summaryrefslogtreecommitdiff
path: root/spec/ruby/library/stringscanner/scan_until_spec.rb
AgeCommit message (Expand)Author
2018-03-04Update to ruby/spec@c1b568beregon
2017-09-20Move spec/rubyspec to spec/ruby for consistencyeregon
ccb8396b59a5de09ba9510031feef'>.dir-locals.el39
-rw-r--r--.document23
-rw-r--r--.editorconfig14
-rw-r--r--.gdbinit154
-rw-r--r--.gitattributes2
-rw-r--r--.github/SECURITY.md9
-rw-r--r--.github/codeql/codeql-config.yml4
-rw-r--r--.github/workflows/baseruby.yml47
-rw-r--r--.github/workflows/check_dependencies.yml45
-rw-r--r--.github/workflows/check_misc.yml17
-rw-r--r--.github/workflows/codeql-analysis.yml43
-rw-r--r--.github/workflows/compilers.yml245
-rw-r--r--.github/workflows/macos.yml66
-rw-r--r--.github/workflows/mingw.yml141
-rw-r--r--.github/workflows/mjit.yml77
-rw-r--r--.github/workflows/spec_guards.yml41
-rw-r--r--.github/workflows/ubuntu.yml87
-rw-r--r--.github/workflows/windows.yml80
-rw-r--r--.gitignore49
-rw-r--r--.indent.pro21
-rw-r--r--.rspec_parallel2
-rw-r--r--.travis.yml299
-rw-r--r--BSDL6
-rw-r--r--COPYING76
-rw-r--r--COPYING.ja66
-rw-r--r--LEGAL1215
-rw-r--r--Makefile.in538
-rw-r--r--NEWS220
-rw-r--r--NEWS.md820
-rw-r--r--README.ja.md73
-rw-r--r--README.md94
-rw-r--r--acinclude.m446
-rw-r--r--aclocal.m415
-rw-r--r--addr2line.c1916
-rw-r--r--addr2line.h7
-rw-r--r--appveyor.yml147
-rw-r--r--array.c5498
-rw-r--r--array.rb61
-rw-r--r--ast.c699
-rw-r--r--ast.rb146
-rwxr-xr-xautogen.sh9
-rwxr-xr-xbasictest/test.rb27
-rw-r--r--benchmark/README.md72
-rw-r--r--benchmark/app_answer.rb (renamed from benchmark/bm_app_answer.rb)0
-rw-r--r--benchmark/app_aobench.rb297
-rw-r--r--benchmark/app_erb.yml23
-rw-r--r--benchmark/app_factorial.rb (renamed from benchmark/bm_app_factorial.rb)0
-rw-r--r--benchmark/app_fib.rb (renamed from benchmark/bm_app_fib.rb)0
-rw-r--r--benchmark/app_lc_fizzbuzz.rb (renamed from benchmark/bm_app_lc_fizzbuzz.rb)0
-rw-r--r--benchmark/app_mandelbrot.rb (renamed from benchmark/bm_app_mandelbrot.rb)0
-rw-r--r--benchmark/app_pentomino.rb130
-rw-r--r--benchmark/app_raise.rb (renamed from benchmark/bm_app_raise.rb)0
-rw-r--r--benchmark/app_strconcat.rb (renamed from benchmark/bm_app_strconcat.rb)0
-rw-r--r--benchmark/app_tak.rb (renamed from benchmark/bm_app_tak.rb)0
-rw-r--r--benchmark/app_tarai.rb (renamed from benchmark/bm_app_tarai.rb)0
-rw-r--r--benchmark/app_uri.rb (renamed from benchmark/bm_app_uri.rb)0
-rw-r--r--benchmark/array_flatten.yml19
-rw-r--r--benchmark/array_intersection.yml14
-rw-r--r--benchmark/array_max_float.yml30
-rw-r--r--benchmark/array_max_int.yml31
-rw-r--r--benchmark/array_max_str.yml30
-rw-r--r--benchmark/array_min.yml31
-rw-r--r--benchmark/array_sample_100k_10.rb (renamed from benchmark/bm_array_sample_100k_10.rb)0
-rw-r--r--benchmark/array_sample_100k_11.rb (renamed from benchmark/bm_array_sample_100k_11.rb)0
-rw-r--r--benchmark/array_sample_100k__100.rb (renamed from benchmark/bm_array_sample_100k__100.rb)0
-rw-r--r--benchmark/array_sample_100k__1k.rb (renamed from benchmark/bm_array_sample_100k__1k.rb)0
-rw-r--r--benchmark/array_sample_100k__6k.rb (renamed from benchmark/bm_array_sample_100k__6k.rb)0
-rw-r--r--benchmark/array_sample_100k___10k.rb (renamed from benchmark/bm_array_sample_100k___10k.rb)0
-rw-r--r--benchmark/array_sample_100k___50k.rb (renamed from benchmark/bm_array_sample_100k___50k.rb)0
-rw-r--r--benchmark/array_shift.rb (renamed from benchmark/bm_array_shift.rb)0
-rw-r--r--benchmark/array_small_and.rb (renamed from benchmark/bm_array_small_and.rb)0
-rw-r--r--benchmark/array_small_diff.rb (renamed from benchmark/bm_array_small_diff.rb)0
-rw-r--r--benchmark/array_small_or.rb (renamed from benchmark/bm_array_small_or.rb)0
-rw-r--r--benchmark/array_sort_block.rb (renamed from benchmark/bm_array_sort_block.rb)0
-rw-r--r--benchmark/array_sort_float.rb (renamed from benchmark/bm_array_sort_float.rb)0
-rw-r--r--benchmark/array_values_at_int.rb2
-rw-r--r--benchmark/array_values_at_range.rb2
-rw-r--r--benchmark/bighash.rb (renamed from benchmark/bm_bighash.rb)0
-rw-r--r--benchmark/bm_app_aobench.rb291
-rw-r--r--benchmark/bm_app_erb.rb26
-rw-r--r--benchmark/bm_app_pentomino.rb259
-rw-r--r--benchmark/bm_erb_render.rb26
-rw-r--r--benchmark/bm_file_rename.rb11
-rw-r--r--benchmark/bm_require.rb7
-rw-r--r--benchmark/bm_require_thread.rb15
-rw-r--r--benchmark/bm_so_ackermann.rb19
-rw-r--r--benchmark/bm_so_array.rb23
-rw-r--r--benchmark/bm_so_concatenate.rb18
-rw-r--r--benchmark/bm_so_count_words.rb19
-rw-r--r--benchmark/bm_so_exception.rb61
-rw-r--r--benchmark/bm_so_k_nucleotide.rb48
-rw-r--r--benchmark/bm_so_matrix.rb48
-rw-r--r--benchmark/bm_so_nested_loop.rb24
-rw-r--r--benchmark/bm_so_object.rb56
-rw-r--r--benchmark/bm_so_reverse_complement.rb30
-rw-r--r--benchmark/bm_vm1_attr_ivar.rb14
-rw-r--r--benchmark/bm_vm1_attr_ivar_set.rb14
-rw-r--r--benchmark/bm_vm1_block.rb10
-rw-r--r--benchmark/bm_vm1_const.rb8
-rw-r--r--benchmark/bm_vm1_ensure.rb11
-rw-r--r--benchmark/bm_vm1_float_simple.rb7
-rw-r--r--benchmark/bm_vm1_gc_short_lived.rb10
-rw-r--r--benchmark/bm_vm1_gc_short_with_complex_long.rb27
-rw-r--r--benchmark/bm_vm1_gc_short_with_long.rb13
-rw-r--r--benchmark/bm_vm1_gc_short_with_symbol.rb15
-rw-r--r--benchmark/bm_vm1_gc_wb_ary.rb12
-rw-r--r--benchmark/bm_vm1_gc_wb_ary_promoted.rb14
-rw-r--r--benchmark/bm_vm1_gc_wb_obj.rb15
-rw-r--r--benchmark/bm_vm1_gc_wb_obj_promoted.rb17
-rw-r--r--benchmark/bm_vm1_ivar.rb8
-rw-r--r--benchmark/bm_vm1_ivar_set.rb6
-rw-r--r--benchmark/bm_vm1_length.rb9
-rw-r--r--benchmark/bm_vm1_lvar_init.rb18
-rw-r--r--benchmark/bm_vm1_lvar_set.rb5
-rw-r--r--benchmark/bm_vm1_neq.rb8
-rw-r--r--benchmark/bm_vm1_not.rb7
-rw-r--r--benchmark/bm_vm1_rescue.rb7
-rw-r--r--benchmark/bm_vm1_simplereturn.rb9
-rw-r--r--benchmark/bm_vm1_swap.rb8
-rw-r--r--benchmark/bm_vm1_yield.rb10
-rw-r--r--benchmark/bm_vm2_array.rb5
-rw-r--r--benchmark/bm_vm2_bigarray.rb106
-rw-r--r--benchmark/bm_vm2_bighash.rb5
-rw-r--r--benchmark/bm_vm2_case.rb14
-rw-r--r--benchmark/bm_vm2_case_lit.rb19
-rw-r--r--benchmark/bm_vm2_defined_method.rb9
-rw-r--r--benchmark/bm_vm2_dstr.rb6
-rw-r--r--benchmark/bm_vm2_eval.rb6
-rw-r--r--benchmark/bm_vm2_fiber_switch.rb9
-rw-r--r--benchmark/bm_vm2_method.rb9
-rw-r--r--benchmark/bm_vm2_method_missing.rb12
-rw-r--r--benchmark/bm_vm2_method_with_block.rb9
-rw-r--r--benchmark/bm_vm2_module_ann_const_set.rb5
-rw-r--r--benchmark/bm_vm2_module_const_set.rb8
-rw-r--r--benchmark/bm_vm2_mutex.rb9
-rw-r--r--benchmark/bm_vm2_newlambda.rb5
-rw-r--r--benchmark/bm_vm2_poly_method.rb20
-rw-r--r--benchmark/bm_vm2_poly_method_ov.rb20
-rw-r--r--benchmark/bm_vm2_poly_singleton.rb14
-rw-r--r--benchmark/bm_vm2_proc.rb14
-rw-r--r--benchmark/bm_vm2_raise1.rb18
-rw-r--r--benchmark/bm_vm2_raise2.rb18
-rw-r--r--benchmark/bm_vm2_regexp.rb6
-rw-r--r--benchmark/bm_vm2_send.rb12
-rw-r--r--benchmark/bm_vm2_string_literal.rb5
-rw-r--r--benchmark/bm_vm2_struct_big_aref_hi.rb7
-rw-r--r--benchmark/bm_vm2_struct_big_aref_lo.rb7
-rw-r--r--benchmark/bm_vm2_struct_big_aset.rb7
-rw-r--r--benchmark/bm_vm2_struct_big_href_hi.rb7
-rw-r--r--benchmark/bm_vm2_struct_big_href_lo.rb7
-rw-r--r--benchmark/bm_vm2_struct_big_hset.rb7
-rw-r--r--benchmark/bm_vm2_struct_small_aref.rb7
-rw-r--r--benchmark/bm_vm2_struct_small_aset.rb7
-rw-r--r--benchmark/bm_vm2_struct_small_href.rb7
-rw-r--r--benchmark/bm_vm2_struct_small_hset.rb7
-rw-r--r--benchmark/bm_vm2_super.rb20
-rw-r--r--benchmark/bm_vm2_unif1.rb8
-rw-r--r--benchmark/bm_vm2_zsuper.rb20
-rw-r--r--benchmark/bm_vm_thread_alive_check1.rb6
-rw-r--r--benchmark/bm_vm_thread_pass.rb15
-rw-r--r--benchmark/bm_vm_thread_pass_flood.rb10
-rw-r--r--benchmark/bm_vm_thread_queue.rb18
-rw-r--r--benchmark/cgi_escape_html.yml40
-rw-r--r--benchmark/complex_float_add.yml7
-rw-r--r--benchmark/complex_float_div.yml7
-rw-r--r--benchmark/complex_float_mul.yml7
-rw-r--r--benchmark/complex_float_new.yml7
-rw-r--r--benchmark/complex_float_power.yml7
-rw-r--r--benchmark/complex_float_sub.yml7
-rw-r--r--benchmark/dir_empty_p.rb (renamed from benchmark/bm_dir_empty_p.rb)0
-rw-r--r--benchmark/driver.rb435
-rw-r--r--benchmark/enum_lazy_flat_map.yml16
-rw-r--r--benchmark/enum_lazy_grep_v_100.rb4
-rw-r--r--benchmark/enum_lazy_grep_v_20.rb4
-rw-r--r--benchmark/enum_lazy_grep_v_50.rb4
-rw-r--r--benchmark/enum_lazy_uniq_100.rb4
-rw-r--r--benchmark/enum_lazy_uniq_20.rb4
-rw-r--r--benchmark/enum_lazy_uniq_50.rb4
-rw-r--r--benchmark/enum_lazy_zip.yml22
-rw-r--r--benchmark/erb_render.yml24
-rw-r--r--benchmark/fiber_chain.yml36
-rw-r--r--benchmark/fiber_locals.yml8
-rw-r--r--benchmark/file_chmod.rb9
-rw-r--r--benchmark/file_rename.rb11
-rw-r--r--benchmark/gc/aobench.rb2
-rw-r--r--benchmark/gc/binary_trees.rb2
-rw-r--r--benchmark/gc/gcbench.rb3
-rw-r--r--benchmark/gc/pentomino.rb2
-rw-r--r--benchmark/hash_aref_dsym.rb (renamed from benchmark/bm_hash_aref_dsym.rb)0
-rw-r--r--benchmark/hash_aref_dsym_long.rb (renamed from benchmark/bm_hash_aref_dsym_long.rb)0
-rw-r--r--benchmark/hash_aref_fix.rb (renamed from benchmark/bm_hash_aref_fix.rb)0
-rw-r--r--benchmark/hash_aref_flo.rb (renamed from benchmark/bm_hash_aref_flo.rb)0
-rw-r--r--benchmark/hash_aref_miss.rb (renamed from benchmark/bm_hash_aref_miss.rb)0
-rw-r--r--benchmark/hash_aref_str.rb (renamed from benchmark/bm_hash_aref_str.rb)0
-rw-r--r--benchmark/hash_aref_sym.rb (renamed from benchmark/bm_hash_aref_sym.rb)0
-rw-r--r--benchmark/hash_aref_sym_long.rb (renamed from benchmark/bm_hash_aref_sym_long.rb)0
-rw-r--r--benchmark/hash_defaults.yml6
-rw-r--r--benchmark/hash_dup.yml8
-rw-r--r--benchmark/hash_flatten.rb (renamed from benchmark/bm_hash_flatten.rb)0
-rw-r--r--benchmark/hash_ident_flo.rb (renamed from benchmark/bm_hash_ident_flo.rb)0
-rw-r--r--benchmark/hash_ident_num.rb (renamed from benchmark/bm_hash_ident_num.rb)0
-rw-r--r--benchmark/hash_ident_obj.rb (renamed from benchmark/bm_hash_ident_obj.rb)0
-rw-r--r--benchmark/hash_ident_str.rb (renamed from benchmark/bm_hash_ident_str.rb)0
-rw-r--r--benchmark/hash_ident_sym.rb (renamed from benchmark/bm_hash_ident_sym.rb)0
-rw-r--r--benchmark/hash_keys.rb (renamed from benchmark/bm_hash_keys.rb)0
-rw-r--r--benchmark/hash_literal_small2.rb3
-rw-r--r--benchmark/hash_literal_small4.rb3
-rw-r--r--benchmark/hash_literal_small8.rb3
-rw-r--r--benchmark/hash_long.rb (renamed from benchmark/bm_hash_long.rb)0
-rw-r--r--benchmark/hash_shift.rb (renamed from benchmark/bm_hash_shift.rb)0
-rw-r--r--benchmark/hash_shift_u16.rb (renamed from benchmark/bm_hash_shift_u16.rb)0
-rw-r--r--benchmark/hash_shift_u24.rb (renamed from benchmark/bm_hash_shift_u24.rb)0
-rw-r--r--benchmark/hash_shift_u32.rb (renamed from benchmark/bm_hash_shift_u32.rb)0
-rw-r--r--benchmark/hash_small2.rb (renamed from benchmark/bm_hash_small2.rb)0
-rw-r--r--benchmark/hash_small4.rb (renamed from benchmark/bm_hash_small4.rb)0
-rw-r--r--benchmark/hash_small8.rb (renamed from benchmark/bm_hash_small8.rb)0
-rw-r--r--benchmark/hash_to_proc.rb (renamed from benchmark/bm_hash_to_proc.rb)0
-rw-r--r--benchmark/hash_values.rb (renamed from benchmark/bm_hash_values.rb)0
-rw-r--r--benchmark/int_quo.rb (renamed from benchmark/bm_int_quo.rb)0
-rw-r--r--benchmark/io_copy_stream_write.rb (renamed from benchmark/bm_io_copy_stream_write.rb)0
-rw-r--r--benchmark/io_copy_stream_write_socket.rb (renamed from benchmark/bm_io_copy_stream_write_socket.rb)0
-rw-r--r--benchmark/io_file_create.rb (renamed from benchmark/bm_io_file_create.rb)0
-rw-r--r--benchmark/io_file_read.rb (renamed from benchmark/bm_io_file_read.rb)0
-rw-r--r--benchmark/io_file_write.rb (renamed from benchmark/bm_io_file_write.rb)0
-rw-r--r--benchmark/io_nonblock_noex.rb (renamed from benchmark/bm_io_nonblock_noex.rb)0
-rw-r--r--benchmark/io_nonblock_noex2.rb (renamed from benchmark/bm_io_nonblock_noex2.rb)0
-rw-r--r--benchmark/io_pipe_rw.rb (renamed from benchmark/bm_io_pipe_rw.rb)0
-rw-r--r--benchmark/io_select.rb (renamed from benchmark/bm_io_select.rb)0
-rw-r--r--benchmark/io_select2.rb (renamed from benchmark/bm_io_select2.rb)0
-rw-r--r--benchmark/io_select3.rb (renamed from benchmark/bm_io_select3.rb)0
-rw-r--r--benchmark/irb_color.yml13
-rw-r--r--benchmark/irb_exec.yml10
-rw-r--r--benchmark/kernel_clone.yml6
-rw-r--r--benchmark/kernel_float.yml5
-rw-r--r--benchmark/kernel_tap.yml6
-rw-r--r--benchmark/kernel_then.yml6
-rw-r--r--benchmark/keyword_arguments.yml13
-rw-r--r--benchmark/lib/benchmark_driver/output/driver.rb36
-rw-r--r--benchmark/lib/benchmark_driver/runner/cstime.rb22
-rw-r--r--benchmark/lib/benchmark_driver/runner/cutime.rb22
-rw-r--r--benchmark/lib/benchmark_driver/runner/mjit.rb34
-rw-r--r--benchmark/lib/benchmark_driver/runner/mjit_exec.rb237
-rw-r--r--benchmark/lib/benchmark_driver/runner/peak.rb151
-rw-r--r--benchmark/lib/benchmark_driver/runner/size.rb25
-rw-r--r--benchmark/lib/benchmark_driver/runner/stime.rb22
-rw-r--r--benchmark/lib/benchmark_driver/runner/total.rb137
-rw-r--r--benchmark/lib/benchmark_driver/runner/utime.rb22
-rw-r--r--benchmark/lib/load.rb18
-rw-r--r--benchmark/loop_for.rb (renamed from benchmark/bm_loop_for.rb)0
-rw-r--r--benchmark/loop_generator.rb (renamed from benchmark/bm_loop_generator.rb)0
-rw-r--r--benchmark/loop_times.rb (renamed from benchmark/bm_loop_times.rb)0
-rw-r--r--benchmark/loop_whileloop.rb (renamed from benchmark/bm_loop_whileloop.rb)0
-rw-r--r--benchmark/loop_whileloop2.rb (renamed from benchmark/bm_loop_whileloop2.rb)0
-rw-r--r--benchmark/make_fasta_output.rb19
-rw-r--r--benchmark/marshal_dump_flo.rb (renamed from benchmark/bm_marshal_dump_flo.rb)0
-rw-r--r--benchmark/marshal_dump_load_geniv.rb (renamed from benchmark/bm_marshal_dump_load_geniv.rb)0
-rw-r--r--benchmark/marshal_dump_load_time.rb (renamed from benchmark/bm_marshal_dump_load_time.rb)0
-rw-r--r--benchmark/match_gt4.rb1
-rw-r--r--benchmark/match_small.rb1
-rw-r--r--benchmark/memory_wrapper.rb16
-rw-r--r--benchmark/mjit_exec_jt2jt.yml6
-rw-r--r--benchmark/mjit_exec_vm2jt.yml6
-rw-r--r--benchmark/mjit_exec_vm2vm.yml6
-rw-r--r--benchmark/mjit_exivar.yml18
-rw-r--r--benchmark/mjit_integer.yml30
-rw-r--r--benchmark/mjit_kernel.yml20
-rw-r--r--benchmark/mjit_leave.yml8
-rw-r--r--benchmark/mjit_opt_cc_insns.yml27
-rw-r--r--benchmark/mjit_struct_aref.yml10
-rw-r--r--benchmark/nil_p.yml9
-rw-r--r--benchmark/num_zero_p.yml8
-rw-r--r--benchmark/object_allocate.yml21
-rw-r--r--benchmark/objspace_dump_all.yml13
-rw-r--r--benchmark/other-lang/fact.py2
-rw-r--r--benchmark/pm_array.yml19
-rw-r--r--benchmark/prepare_require.rb25
-rw-r--r--benchmark/prepare_require_thread.rb2
-rw-r--r--benchmark/prepare_so_count_words.rb15
-rw-r--r--benchmark/prepare_so_k_nucleotide.rb2
-rw-r--r--benchmark/prepare_so_reverse_complement.rb2
-rw-r--r--benchmark/range_last.yml4
-rw-r--r--benchmark/realpath.yml30
-rw-r--r--benchmark/report.rb79
-rw-r--r--benchmark/require.yml32
-rw-r--r--benchmark/require_thread.yml40
-rw-r--r--benchmark/run.rb127
-rw-r--r--benchmark/runc.rb27
-rw-r--r--benchmark/securerandom.rb (renamed from benchmark/bm_securerandom.rb)0
-rw-r--r--benchmark/so_ackermann.rb19
-rw-r--r--benchmark/so_array.rb23
-rw-r--r--benchmark/so_binary_trees.rb (renamed from benchmark/bm_so_binary_trees.rb)0
-rw-r--r--benchmark/so_concatenate.rb18
-rw-r--r--benchmark/so_count_words.yml65
-rw-r--r--benchmark/so_exception.rb61
-rw-r--r--benchmark/so_fannkuch.rb (renamed from benchmark/bm_so_fannkuch.rb)0
-rw-r--r--benchmark/so_fasta.rb (renamed from benchmark/bm_so_fasta.rb)0
-rw-r--r--benchmark/so_k_nucleotide.yml155
-rw-r--r--benchmark/so_lists.rb (renamed from benchmark/bm_so_lists.rb)0
-rw-r--r--benchmark/so_mandelbrot.rb (renamed from benchmark/bm_so_mandelbrot.rb)0
-rw-r--r--benchmark/so_matrix.rb48
-rw-r--r--[-rwxr-xr-x]benchmark/so_meteor_contest.rb (renamed from benchmark/bm_so_meteor_contest.rb)0
-rw-r--r--benchmark/so_nbody.rb (renamed from benchmark/bm_so_nbody.rb)0
-rw-r--r--benchmark/so_nested_loop.rb24
-rw-r--r--benchmark/so_nsieve.rb (renamed from benchmark/bm_so_nsieve.rb)0
-rw-r--r--benchmark/so_nsieve_bits.rb (renamed from benchmark/bm_so_nsieve_bits.rb)0
-rw-r--r--benchmark/so_object.rb56
-rw-r--r--benchmark/so_partial_sums.rb (renamed from benchmark/bm_so_partial_sums.rb)0
-rw-r--r--benchmark/so_pidigits.rb (renamed from benchmark/bm_so_pidigits.rb)0
-rw-r--r--benchmark/so_random.rb (renamed from benchmark/bm_so_random.rb)0
-rw-r--r--benchmark/so_reverse_complement.yml137
-rw-r--r--benchmark/so_sieve.rb (renamed from benchmark/bm_so_sieve.rb)0
-rw-r--r--benchmark/so_spectralnorm.rb (renamed from benchmark/bm_so_spectralnorm.rb)0
-rw-r--r--benchmark/string_capitalize.yml10
-rw-r--r--benchmark/string_casecmp.yml26
-rw-r--r--benchmark/string_casecmp_p.yml26
-rw-r--r--benchmark/string_downcase.yml18
-rw-r--r--benchmark/string_index.rb (renamed from benchmark/bm_string_index.rb)0
-rw-r--r--benchmark/string_scan_re.rb (renamed from benchmark/bm_string_scan_re.rb)0
-rw-r--r--benchmark/string_scan_str.rb (renamed from benchmark/bm_string_scan_str.rb)0
-rw-r--r--benchmark/string_slice.yml11
-rw-r--r--benchmark/string_split.yml22
-rw-r--r--benchmark/string_swapcase.yml18
-rw-r--r--benchmark/string_upcase.yml18
-rw-r--r--benchmark/time_strptime.yml13
-rw-r--r--benchmark/time_subsec.rb (renamed from benchmark/bm_time_subsec.rb)0
-rw-r--r--benchmark/vm_array.yml4
-rw-r--r--benchmark/vm_attr_ivar.yml14
-rw-r--r--benchmark/vm_attr_ivar_set.yml14
-rw-r--r--benchmark/vm_backtrace.rb (renamed from benchmark/bm_vm3_backtrace.rb)0
-rw-r--r--benchmark/vm_bigarray.yml105
-rw-r--r--benchmark/vm_bighash.yml4
-rw-r--r--benchmark/vm_block.yml9
-rw-r--r--benchmark/vm_block_handler.yml27
-rw-r--r--benchmark/vm_blockparam.yml7
-rw-r--r--benchmark/vm_blockparam_call.yml8
-rw-r--r--benchmark/vm_blockparam_pass.yml12
-rw-r--r--benchmark/vm_blockparam_yield.yml8
-rw-r--r--benchmark/vm_case.yml13
-rw-r--r--benchmark/vm_case_lit.yml23
-rw-r--r--benchmark/vm_clearmethodcache.rb (renamed from benchmark/bm_vm3_clearmethodcache.rb)0
-rw-r--r--benchmark/vm_const.yml7
-rw-r--r--benchmark/vm_defined_method.yml8
-rw-r--r--benchmark/vm_dstr.yml6
-rw-r--r--benchmark/vm_ensure.yml14
-rw-r--r--benchmark/vm_eval.yml4
-rw-r--r--benchmark/vm_fiber_allocate.yml8
-rw-r--r--benchmark/vm_fiber_count.yml10
-rw-r--r--benchmark/vm_fiber_reuse.yml14
-rw-r--r--benchmark/vm_fiber_reuse_gc.yml12
-rw-r--r--benchmark/vm_fiber_switch.yml9
-rw-r--r--benchmark/vm_float_simple.yml8
-rw-r--r--benchmark/vm_freezestring.yml10
-rw-r--r--benchmark/vm_gc.rb (renamed from benchmark/bm_vm3_gc.rb)0
-rw-r--r--benchmark/vm_gc_old_full.rb (renamed from benchmark/bm_vm3_gc_old_full.rb)0
-rw-r--r--benchmark/vm_gc_old_immediate.rb (renamed from benchmark/bm_vm3_gc_old_immediate.rb)0
-rw-r--r--benchmark/vm_gc_old_lazy.rb (renamed from benchmark/bm_vm3_gc_old_lazy.rb)0
-rw-r--r--benchmark/vm_gc_short_lived.yml9
-rw-r--r--benchmark/vm_gc_short_with_complex_long.yml25
-rw-r--r--benchmark/vm_gc_short_with_long.yml13
-rw-r--r--benchmark/vm_gc_short_with_symbol.yml13
-rw-r--r--benchmark/vm_gc_wb_ary.yml12
-rw-r--r--benchmark/vm_gc_wb_ary_promoted.yml15
-rw-r--r--benchmark/vm_gc_wb_obj.yml15
-rw-r--r--benchmark/vm_gc_wb_obj_promoted.yml17
-rw-r--r--benchmark/vm_iclass_super.yml20
-rw-r--r--benchmark/vm_ivar.yml6
-rw-r--r--benchmark/vm_ivar_init.yml14
-rw-r--r--benchmark/vm_ivar_set.yml5
-rw-r--r--benchmark/vm_ivar_set_subclass.yml17
-rw-r--r--benchmark/vm_length.yml8
-rw-r--r--benchmark/vm_lvar_init.yml21
-rw-r--r--benchmark/vm_lvar_set.yml4
-rw-r--r--benchmark/vm_method.yml8
-rw-r--r--benchmark/vm_method_missing.yml11
-rw-r--r--benchmark/vm_method_with_block.yml8
-rw-r--r--benchmark/vm_module_ann_const_set.yml4
-rw-r--r--benchmark/vm_module_const_set.yml8
-rw-r--r--benchmark/vm_mutex.yml8
-rw-r--r--benchmark/vm_neq.yml7
-rw-r--r--benchmark/vm_newlambda.yml4
-rw-r--r--benchmark/vm_not.yml6
-rw-r--r--benchmark/vm_poly_method.yml24
-rw-r--r--benchmark/vm_poly_method_ov.yml24
-rw-r--r--benchmark/vm_poly_same_method.yml25
-rw-r--r--benchmark/vm_poly_singleton.yml18
-rw-r--r--benchmark/vm_proc.yml12
-rw-r--r--benchmark/vm_raise1.yml16
-rw-r--r--benchmark/vm_raise2.yml16
-rw-r--r--benchmark/vm_regexp.yml8
-rw-r--r--benchmark/vm_rescue.yml6
-rw-r--r--benchmark/vm_send.yml14
-rw-r--r--benchmark/vm_send_cfunc.yml3
-rw-r--r--benchmark/vm_simplereturn.yml7
-rw-r--r--benchmark/vm_string_literal.yml4
-rw-r--r--benchmark/vm_struct_big_aref_hi.yml7
-rw-r--r--benchmark/vm_struct_big_aref_lo.yml7
-rw-r--r--benchmark/vm_struct_big_aset.yml11
-rw-r--r--benchmark/vm_struct_big_href_hi.yml7
-rw-r--r--benchmark/vm_struct_big_href_lo.yml7
-rw-r--r--benchmark/vm_struct_big_hset.yml11
-rw-r--r--benchmark/vm_struct_small_aref.yml7
-rw-r--r--benchmark/vm_struct_small_aset.yml11
-rw-r--r--benchmark/vm_struct_small_href.yml7
-rw-r--r--benchmark/vm_struct_small_hset.yml7
-rw-r--r--benchmark/vm_super.yml17
-rw-r--r--benchmark/vm_swap.yml7
-rw-r--r--benchmark/vm_symbol_block_pass.rb (renamed from benchmark/bm_vm_symbol_block_pass.rb)0
-rw-r--r--benchmark/vm_thread_alive_check.yml8
-rw-r--r--benchmark/vm_thread_close.rb (renamed from benchmark/bm_vm_thread_close.rb)0
-rw-r--r--benchmark/vm_thread_condvar1.rb (renamed from benchmark/bm_vm_thread_condvar1.rb)0
-rw-r--r--benchmark/vm_thread_condvar2.rb (renamed from benchmark/bm_vm_thread_condvar2.rb)0
-rw-r--r--benchmark/vm_thread_create_join.rb (renamed from benchmark/bm_vm_thread_create_join.rb)0
-rw-r--r--benchmark/vm_thread_mutex1.rb (renamed from benchmark/bm_vm_thread_mutex1.rb)0
-rw-r--r--benchmark/vm_thread_mutex2.rb (renamed from benchmark/bm_vm_thread_mutex2.rb)0
-rw-r--r--benchmark/vm_thread_mutex3.rb (renamed from benchmark/bm_vm_thread_mutex3.rb)0
-rw-r--r--benchmark/vm_thread_pass.rb15
-rw-r--r--benchmark/vm_thread_pass_flood.rb10
-rw-r--r--benchmark/vm_thread_pipe.rb (renamed from benchmark/bm_vm_thread_pipe.rb)0
-rw-r--r--benchmark/vm_thread_queue.rb18
-rw-r--r--benchmark/vm_thread_sized_queue.rb (renamed from benchmark/bm_vm_thread_sized_queue.rb)0
-rw-r--r--benchmark/vm_thread_sized_queue2.rb (renamed from benchmark/bm_vm_thread_sized_queue2.rb)0
-rw-r--r--benchmark/vm_thread_sized_queue3.rb (renamed from benchmark/bm_vm_thread_sized_queue3.rb)0
-rw-r--r--benchmark/vm_thread_sized_queue4.rb (renamed from benchmark/bm_vm_thread_sized_queue4.rb)0
-rw-r--r--benchmark/vm_thread_sleep.yml4
-rw-r--r--benchmark/vm_unif1.yml7
-rw-r--r--benchmark/vm_yield.yml13
-rw-r--r--benchmark/vm_zsuper.yml18
-rw-r--r--benchmark/wc.input.base25
-rw-r--r--bignum.c607
-rwxr-xr-xbin/bundle46
-rwxr-xr-xbin/bundler27
-rwxr-xr-xbin/erb188
-rwxr-xr-xbin/irb28
-rwxr-xr-xbin/racc27
-rwxr-xr-xbin/rdoc53
-rwxr-xr-xbin/ri31
-rw-r--r--bootstraptest/pending.rb24
-rwxr-xr-xbootstraptest/runner.rb76
-rw-r--r--bootstraptest/test_env.rb12
-rw-r--r--bootstraptest/test_eval.rb11
-rw-r--r--bootstraptest/test_exception.rb2
-rw-r--r--bootstraptest/test_fiber.rb39
-rw-r--r--bootstraptest/test_flow.rb18
-rw-r--r--bootstraptest/test_fork.rb4
-rw-r--r--bootstraptest/test_insns.rb120
-rw-r--r--bootstraptest/test_io.rb4
-rw-r--r--bootstraptest/test_jump.rb30
-rw-r--r--bootstraptest/test_literal.rb24
-rw-r--r--bootstraptest/test_literal_suffix.rb6
-rw-r--r--bootstraptest/test_objectspace.rb9
-rw-r--r--bootstraptest/test_proc.rb17
-rw-r--r--bootstraptest/test_ractor.rb1444
-rw-r--r--bootstraptest/test_syntax.rb6
-rw-r--r--bootstraptest/test_thread.rb38
-rw-r--r--builtin.c69
-rw-r--r--builtin.h83
-rw-r--r--ccan/list/list.h33
-rw-r--r--class.c771
-rw-r--r--common.mk14430
-rw-r--r--compar.c111
-rw-r--r--compile.c8161
-rw-r--r--complex.c879
-rw-r--r--configure.ac2572
-rw-r--r--constant.h21
-rw-r--r--cont.c3131
-rw-r--r--coroutine/Stack.h16
-rw-r--r--coroutine/amd64/Context.S46
-rw-r--r--coroutine/amd64/Context.h54
-rw-r--r--coroutine/arm32/Context.S33
-rw-r--r--coroutine/arm32/Context.h53
-rw-r--r--coroutine/arm64/Context.S62
-rw-r--r--coroutine/arm64/Context.h52
-rw-r--r--coroutine/copy/Context.c162
-rw-r--r--coroutine/copy/Context.h90
-rw-r--r--coroutine/ppc64le/Context.S75
-rw-r--r--coroutine/ppc64le/Context.h51
-rw-r--r--coroutine/ucontext/Context.c22
-rw-r--r--coroutine/ucontext/Context.h70
-rw-r--r--coroutine/win32/Context.S47
-rw-r--r--coroutine/win32/Context.asm55
-rw-r--r--coroutine/win32/Context.h59
-rw-r--r--coroutine/win64/Context.S77
-rw-r--r--coroutine/win64/Context.asm79
-rw-r--r--coroutine/win64/Context.h69
-rw-r--r--coroutine/x86/Context.S42
-rw-r--r--coroutine/x86/Context.h55
-rw-r--r--coverage/README2
-rw-r--r--cygwin/GNUmakefile.in15
-rw-r--r--debug.c301
-rw-r--r--debug_counter.c127
-rw-r--r--debug_counter.h406
-rw-r--r--defs/gmake.mk292
-rw-r--r--defs/id.def29
-rw-r--r--defs/keywords4
-rw-r--r--defs/known_errors.def251
-rw-r--r--defs/lex.c.src4
-rw-r--r--defs/separated_version.mk2
-rw-r--r--defs/universal.mk5
-rw-r--r--dir.c1192
-rw-r--r--dir.rb136
-rw-r--r--dln.c31
-rw-r--r--dln.h21
-rw-r--r--dln_find.c34
-rw-r--r--dmydln.c2
-rw-r--r--doc/.document1
-rw-r--r--doc/ChangeLog-0.60_to_1.14
-rw-r--r--doc/ChangeLog-1.8.02
-rw-r--r--doc/ChangeLog-1.9.32
-rw-r--r--doc/ChangeLog-2.0.06
-rw-r--r--doc/ChangeLog-2.1.04
-rw-r--r--doc/ChangeLog-2.4.02
-rw-r--r--doc/ChangeLog-20165
-rw-r--r--doc/NEWS-1.9.22
-rw-r--r--doc/NEWS-2.0.08
-rw-r--r--doc/NEWS-2.2.08
-rw-r--r--doc/NEWS-2.3.070
-rw-r--r--doc/NEWS-2.4.064
-rw-r--r--doc/NEWS-2.5.0565
-rw-r--r--doc/NEWS-2.6.0662
-rw-r--r--doc/NEWS-2.7.0826
-rw-r--r--doc/bug_triaging.rdoc79
-rw-r--r--doc/contributing.rdoc176
-rw-r--r--doc/contributors.rdoc793
-rw-r--r--doc/csv/arguments/io.rdoc5
-rw-r--r--doc/csv/options/common/col_sep.rdoc63
-rw-r--r--doc/csv/options/common/quote_char.rdoc42
-rw-r--r--doc/csv/options/common/row_sep.rdoc100
-rw-r--r--doc/csv/options/generating/force_quotes.rdoc17
-rw-r--r--doc/csv/options/generating/quote_empty.rdoc12
-rw-r--r--doc/csv/options/generating/write_converters.rdoc33
-rw-r--r--doc/csv/options/generating/write_empty_value.rdoc15
-rw-r--r--doc/csv/options/generating/write_headers.rdoc29
-rw-r--r--doc/csv/options/generating/write_nil_value.rdoc14
-rw-r--r--doc/csv/options/parsing/converters.rdoc46
-rw-r--r--doc/csv/options/parsing/empty_value.rdoc13
-rw-r--r--doc/csv/options/parsing/field_size_limit.rdoc39
-rw-r--r--doc/csv/options/parsing/header_converters.rdoc43
-rw-r--r--doc/csv/options/parsing/headers.rdoc63
-rw-r--r--doc/csv/options/parsing/liberal_parsing.rdoc19
-rw-r--r--doc/csv/options/parsing/nil_value.rdoc12
-rw-r--r--doc/csv/options/parsing/return_headers.rdoc22
-rw-r--r--doc/csv/options/parsing/skip_blanks.rdoc31
-rw-r--r--doc/csv/options/parsing/skip_lines.rdoc37
-rw-r--r--doc/csv/options/parsing/strip.rdoc15
-rw-r--r--doc/csv/options/parsing/unconverted_fields.rdoc27
-rw-r--r--doc/csv/recipes/filtering.rdoc156
-rw-r--r--doc/csv/recipes/generating.rdoc244
-rw-r--r--doc/csv/recipes/parsing.rdoc543
-rw-r--r--doc/csv/recipes/recipes.rdoc6
-rw-r--r--doc/dig_methods.rdoc82
-rw-r--r--doc/dtrace_probes.rdoc78
-rw-r--r--doc/etc.rd.ja75
-rw-r--r--doc/extension.ja.rdoc40
-rw-r--r--doc/extension.rdoc293
-rw-r--r--doc/fiber.md191
-rw-r--r--doc/globals.rdoc87
-rw-r--r--doc/implicit_conversion.rdoc198
-rw-r--r--doc/irb/irb.rd.ja75
-rw-r--r--doc/keywords.rdoc10
-rw-r--r--doc/maintainers.rdoc392
-rw-r--r--doc/make_cheatsheet.md124
-rw-r--r--doc/marshal.rdoc2
-rw-r--r--doc/memory_view.md167
-rw-r--r--doc/method_documentation.rdoc183
-rw-r--r--doc/ractor.md931
-rw-r--r--doc/regexp.rdoc47
-rw-r--r--doc/security.rdoc13
-rw-r--r--doc/shell.rd.ja335
-rw-r--r--doc/signals.rdoc106
-rw-r--r--doc/standard_library.rdoc90
-rw-r--r--doc/syntax.rdoc7
-rw-r--r--doc/syntax/assignment.rdoc27
-rw-r--r--doc/syntax/calling_methods.rdoc97
-rw-r--r--doc/syntax/comments.rdoc253
-rw-r--r--doc/syntax/control_expressions.rdoc78
-rw-r--r--doc/syntax/exceptions.rdoc9
-rw-r--r--doc/syntax/literals.rdoc43
-rw-r--r--doc/syntax/methods.rdoc204
-rw-r--r--doc/syntax/miscellaneous.rdoc32
-rw-r--r--doc/syntax/modules_and_classes.rdoc38
-rw-r--r--doc/syntax/pattern_matching.rdoc503
-rw-r--r--doc/syntax/precedence.rdoc6
-rw-r--r--doc/syntax/refinements.rdoc46
-rw-r--r--doc/yarvarch.en (renamed from template/yarvarch.en)0
-rw-r--r--doc/yarvarch.ja (renamed from template/yarvarch.ja)0
-rw-r--r--enc/Makefile.in3
-rw-r--r--enc/ascii.c2
-rw-r--r--enc/cesu_8.c454
-rw-r--r--enc/cp949.c2
-rw-r--r--enc/depend6104
-rw-r--r--enc/encdb.c2
-rw-r--r--enc/euc_jp.c4
-rw-r--r--enc/gb2312.c4
-rw-r--r--enc/iso_8859_11.c2
-rw-r--r--enc/iso_8859_6.c2
-rw-r--r--enc/iso_8859_8.c2
-rw-r--r--enc/jis/props.h.blt56
-rw-r--r--enc/jis/props.kwd6
-rw-r--r--enc/jis/props.src6
-rwxr-xr-xenc/make_encmake.rb12
-rw-r--r--enc/shift_jis.c529
-rw-r--r--enc/shift_jis.h546
-rw-r--r--enc/trans/JIS/JISX0212%UCS.src2
-rw-r--r--enc/trans/JIS/UCS%JISX0212.src2
-rw-r--r--enc/trans/cesu_8.trans85
-rw-r--r--enc/trans/escape.trans3
-rw-r--r--enc/trans/ibm720-tbl.rb122
-rw-r--r--enc/trans/newline.trans10
-rw-r--r--enc/trans/single_byte.trans3
-rw-r--r--enc/unicode.c29
-rw-r--r--enc/unicode/10.0.0/casefold.h7068
-rw-r--r--enc/unicode/10.0.0/name2ctype.h38087
-rw-r--r--enc/unicode/12.1.0/casefold.h7428
-rw-r--r--enc/unicode/12.1.0/name2ctype.h41810
-rw-r--r--[-rwxr-xr-x]enc/unicode/case-folding.rb9
-rw-r--r--enc/windows_1250.c2
-rw-r--r--enc/windows_1251.c2
-rw-r--r--enc/windows_1252.c2
-rw-r--r--enc/windows_1253.c2
-rw-r--r--enc/windows_1254.c2
-rw-r--r--enc/windows_1257.c2
-rw-r--r--enc/windows_31j.c6
-rw-r--r--enc/x_emoji.h4
-rw-r--r--encindex.h7
-rw-r--r--encoding.c768
-rw-r--r--enum.c790
-rw-r--r--enumerator.c2370
-rw-r--r--error.c1182
-rw-r--r--eval.c768
-rw-r--r--eval_error.c346
-rw-r--r--eval_intern.h137
-rw-r--r--eval_jump.c35
-rw-r--r--ext/-test-/RUBY_ALIGNOF/c.c15
-rw-r--r--ext/-test-/RUBY_ALIGNOF/cpp.cpp9
-rw-r--r--ext/-test-/RUBY_ALIGNOF/depend163
-rw-r--r--ext/-test-/RUBY_ALIGNOF/extconf.rb6
-rw-r--r--ext/-test-/arith_seq/extract/depend162
-rw-r--r--ext/-test-/arith_seq/extract/extconf.rb2
-rw-r--r--ext/-test-/arith_seq/extract/extract.c27
-rw-r--r--ext/-test-/array/concat/depend322
-rw-r--r--ext/-test-/array/concat/extconf.rb2
-rw-r--r--ext/-test-/array/concat/to_ary_conact.c34
-rw-r--r--ext/-test-/array/resize/depend150
-rw-r--r--ext/-test-/bignum/big2str.c2
-rw-r--r--ext/-test-/bignum/bigzero.c2
-rw-r--r--ext/-test-/bignum/depend1100
-rw-r--r--ext/-test-/bignum/div.c2
-rw-r--r--ext/-test-/bignum/intpack.c2
-rw-r--r--ext/-test-/bignum/mul.c2
-rw-r--r--ext/-test-/bignum/str2big.c2
-rw-r--r--ext/-test-/bug-14834/bug-14384.c39
-rw-r--r--ext/-test-/bug-14834/depend163
-rw-r--r--ext/-test-/bug-14834/extconf.rb2
-rw-r--r--ext/-test-/bug-3571/bug.c2
-rw-r--r--ext/-test-/bug-3571/depend163
-rw-r--r--ext/-test-/bug-5832/depend163
-rw-r--r--ext/-test-/bug_reporter/depend163
-rw-r--r--ext/-test-/class/depend302
-rw-r--r--ext/-test-/cxxanyargs/cxxanyargs.cpp961
-rw-r--r--ext/-test-/cxxanyargs/depend25
-rw-r--r--ext/-test-/cxxanyargs/extconf.rb42
-rw-r--r--ext/-test-/cxxanyargs/failure.cpp13
-rw-r--r--ext/-test-/cxxanyargs/failurem1.cpp13
-rw-r--r--ext/-test-/debug/depend452
-rw-r--r--ext/-test-/enumerator_kw/depend163
-rw-r--r--ext/-test-/enumerator_kw/enumerator_kw.c21
-rw-r--r--ext/-test-/enumerator_kw/extconf.rb1
-rw-r--r--ext/-test-/exception/depend606
-rw-r--r--ext/-test-/exception/enc_raise.c2
-rw-r--r--ext/-test-/fatal/depend163
-rw-r--r--ext/-test-/file/depend452
-rw-r--r--ext/-test-/file/fs.c3
-rw-r--r--ext/-test-/float/depend329
-rw-r--r--ext/-test-/funcall/depend163
-rw-r--r--ext/-test-/funcall/funcall.c72
-rw-r--r--ext/-test-/funcall/passing_block.c30
-rw-r--r--ext/-test-/gvl/call_without_gvl/call_without_gvl.c42
-rw-r--r--ext/-test-/gvl/call_without_gvl/depend150
-rw-r--r--ext/-test-/hash/depend324
-rw-r--r--ext/-test-/integer/core_ext.c9
-rw-r--r--ext/-test-/integer/depend468
-rw-r--r--ext/-test-/iseq_load/depend163
-rw-r--r--ext/-test-/iter/break.c4
-rw-r--r--ext/-test-/iter/depend485
-rw-r--r--ext/-test-/iter/yield.c2
-rw-r--r--ext/-test-/load/protect/depend163
-rw-r--r--ext/-test-/marshal/compat/depend163
-rw-r--r--ext/-test-/marshal/internal_ivar/depend163
-rw-r--r--ext/-test-/marshal/internal_ivar/internal_ivar.c15
-rw-r--r--ext/-test-/marshal/usr/depend163
-rw-r--r--ext/-test-/memory_status/depend163
-rw-r--r--ext/-test-/memory_status/memory_status.c4
-rw-r--r--ext/-test-/memory_view/depend164
-rw-r--r--ext/-test-/memory_view/extconf.rb3
-rw-r--r--ext/-test-/memory_view/memory_view.c446
-rw-r--r--ext/-test-/method/depend324
-rw-r--r--ext/-test-/notimplement/bug.c2
-rw-r--r--ext/-test-/notimplement/depend163
-rw-r--r--ext/-test-/num2int/depend163
-rw-r--r--ext/-test-/path_to_class/depend163
-rw-r--r--ext/-test-/popen_deadlock/depend163
-rw-r--r--ext/-test-/popen_deadlock/extconf.rb1
-rw-r--r--ext/-test-/postponed_job/depend165
-rw-r--r--ext/-test-/postponed_job/postponed_job.c49
-rw-r--r--ext/-test-/printf/depend169
-rw-r--r--ext/-test-/proc/depend485
-rw-r--r--ext/-test-/random/depend328
-rw-r--r--ext/-test-/random/extconf.rb3
-rw-r--r--ext/-test-/random/init.c11
-rw-r--r--ext/-test-/random/loop.c110
-rw-r--r--ext/-test-/rational/depend168
-rw-r--r--ext/-test-/rational/rat.c10
-rw-r--r--ext/-test-/rb_call_super_kw/depend163
-rw-r--r--ext/-test-/rb_call_super_kw/extconf.rb1
-rw-r--r--ext/-test-/rb_call_super_kw/rb_call_super_kw.c14
-rw-r--r--ext/-test-/recursion/depend163
-rw-r--r--ext/-test-/regexp/depend325
-rw-r--r--ext/-test-/scan_args/depend163
-rw-r--r--[-rwxr-xr-x]ext/-test-/scan_args/extconf.rb0
-rw-r--r--ext/-test-/scan_args/scan_args.c21
-rw-r--r--ext/-test-/st/foreach/depend163
-rw-r--r--ext/-test-/st/foreach/foreach.c2
-rw-r--r--ext/-test-/st/numhash/depend163
-rw-r--r--ext/-test-/st/numhash/numhash.c5
-rw-r--r--ext/-test-/st/update/depend163
-rw-r--r--ext/-test-/string/capacity.c4
-rw-r--r--ext/-test-/string/coderange.c12
-rw-r--r--ext/-test-/string/cstr.c4
-rw-r--r--ext/-test-/string/depend2470
-rw-r--r--ext/-test-/string/ellipsize.c2
-rw-r--r--ext/-test-/string/enc_associate.c2
-rw-r--r--ext/-test-/string/enc_str_buf_cat.c16
-rw-r--r--ext/-test-/string/fstring.c17
-rw-r--r--ext/-test-/string/init.c2
-rw-r--r--ext/-test-/string/modify.c2
-rw-r--r--ext/-test-/string/new.c21
-rw-r--r--ext/-test-/string/nofree.c2
-rw-r--r--ext/-test-/string/normalize.c4
-rw-r--r--ext/-test-/string/qsort.c2
-rw-r--r--ext/-test-/string/rb_interned_str.c14
-rw-r--r--ext/-test-/string/rb_str_dup.c35
-rw-r--r--ext/-test-/string/set_len.c2
-rw-r--r--ext/-test-/struct/depend608
-rw-r--r--ext/-test-/symbol/depend324
-rw-r--r--ext/-test-/symbol/init.c8
-rw-r--r--ext/-test-/thread_fd_close/depend154
-rw-r--r--ext/-test-/time/depend489
-rw-r--r--ext/-test-/time/init.c2
-rw-r--r--ext/-test-/time/leap_second.c14
-rw-r--r--ext/-test-/time/new.c2
-rw-r--r--ext/-test-/tracepoint/depend300
-rw-r--r--ext/-test-/tracepoint/gc_hook.c13
-rw-r--r--ext/-test-/typeddata/depend163
-rw-r--r--ext/-test-/typeddata/typeddata.c4
-rw-r--r--ext/-test-/vm/depend150
-rw-r--r--ext/-test-/wait_for_single_fd/depend150
-rw-r--r--ext/-test-/wait_for_single_fd/extconf.rb6
-rw-r--r--ext/-test-/wait_for_single_fd/wait_for_single_fd.c64
-rw-r--r--ext/-test-/win32/console/attribute.c5
-rw-r--r--ext/.document17
-rw-r--r--ext/Setup1
-rw-r--r--ext/Setup.atheos1
-rw-r--r--ext/Setup.nacl42
-rw-r--r--ext/Setup.nt1
-rw-r--r--ext/bigdecimal/bigdecimal.c873
-rw-r--r--ext/bigdecimal/bigdecimal.gemspec18
-rw-r--r--ext/bigdecimal/bigdecimal.h16
-rw-r--r--ext/bigdecimal/depend153
-rw-r--r--ext/bigdecimal/extconf.rb44
-rw-r--r--ext/bigdecimal/lib/bigdecimal.rb1
-rw-r--r--ext/bigdecimal/lib/bigdecimal/jacobian.rb4
-rw-r--r--ext/bigdecimal/lib/bigdecimal/math.rb4
-rw-r--r--ext/bigdecimal/lib/bigdecimal/util.rb65
-rw-r--r--ext/bigdecimal/sample/linear.rb21
-rw-r--r--ext/bigdecimal/sample/nlsolve.rb10
-rw-r--r--ext/cgi/escape/depend152
-rw-r--r--ext/cgi/escape/escape.c94
-rw-r--r--ext/continuation/depend150
-rw-r--r--ext/coverage/coverage.c363
-rw-r--r--ext/coverage/depend182
-rw-r--r--ext/coverage/lib/coverage.rb14
-rw-r--r--ext/date/date.gemspec14
-rw-r--r--ext/date/date_core.c1142
-rw-r--r--ext/date/date_parse.c258
-rw-r--r--ext/date/date_strptime.c84
-rw-r--r--ext/date/depend608
-rw-r--r--ext/date/lib/date.rb7
-rw-r--r--ext/date/prereq.mk8
-rw-r--r--ext/date/update-abbr52
-rw-r--r--ext/date/zonetab.h2094
-rw-r--r--ext/date/zonetab.list160
-rw-r--r--ext/dbm/dbm.c78
-rw-r--r--ext/dbm/dbm.gemspec8
-rw-r--r--ext/dbm/depend152
-rw-r--r--ext/dbm/extconf.rb6
-rw-r--r--ext/digest/bubblebabble/bubblebabble.c1
-rw-r--r--ext/digest/bubblebabble/depend154
-rw-r--r--ext/digest/depend152
-rw-r--r--ext/digest/digest.c51
-rw-r--r--ext/digest/digest.gemspec33
-rw-r--r--ext/digest/digest.h21
-rw-r--r--ext/digest/digest_conf.rb69
-rw-r--r--ext/digest/md5/depend320
-rw-r--r--ext/digest/md5/md5cc.h7
-rw-r--r--ext/digest/md5/md5init.c13
-rw-r--r--ext/digest/md5/md5ossl.h15
-rw-r--r--ext/digest/rmd160/depend320
-rw-r--r--ext/digest/rmd160/extconf.rb2
-rw-r--r--ext/digest/rmd160/rmd160init.c13
-rw-r--r--ext/digest/rmd160/rmd160ossl.h20
-rw-r--r--ext/digest/sha1/depend320
-rw-r--r--ext/digest/sha1/extconf.rb2
-rw-r--r--ext/digest/sha1/sha1init.c13
-rw-r--r--ext/digest/sha1/sha1ossl.h22
-rw-r--r--ext/digest/sha2/depend319
-rw-r--r--ext/digest/sha2/extconf.rb2
-rw-r--r--ext/digest/sha2/sha2init.c16
-rw-r--r--ext/digest/sha2/sha2ossl.h27
-rw-r--r--ext/etc/depend153
-rw-r--r--ext/etc/etc.c101
-rw-r--r--ext/etc/etc.gemspec30
-rw-r--r--ext/etc/extconf.rb14
-rw-r--r--ext/etc/mkconstants.rb16
-rwxr-xr-xext/extmk.rb36
-rw-r--r--ext/fcntl/depend152
-rw-r--r--ext/fcntl/fcntl.c16
-rw-r--r--ext/fcntl/fcntl.gemspec11
-rw-r--r--ext/fiber/depend2
-rw-r--r--ext/fiddle/closure.c35
-rw-r--r--ext/fiddle/conversions.c221
-rw-r--r--ext/fiddle/conversions.h17
-rw-r--r--ext/fiddle/depend1249
-rw-r--r--ext/fiddle/extconf.rb141
-rw-r--r--ext/fiddle/extlibs12
-rw-r--r--ext/fiddle/fiddle.c167
-rw-r--r--ext/fiddle/fiddle.gemspec55
-rw-r--r--ext/fiddle/fiddle.h128
-rw-r--r--ext/fiddle/function.c365
-rw-r--r--ext/fiddle/handle.c22
-rw-r--r--ext/fiddle/lib/fiddle.rb16
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb124
-rw-r--r--ext/fiddle/lib/fiddle/function.rb5
-rw-r--r--ext/fiddle/lib/fiddle/import.rb20
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb21
-rw-r--r--ext/fiddle/lib/fiddle/struct.rb310
-rw-r--r--ext/fiddle/lib/fiddle/types.rb35
-rw-r--r--ext/fiddle/lib/fiddle/value.rb27
-rw-r--r--ext/fiddle/lib/fiddle/version.rb3
-rw-r--r--ext/fiddle/memory_view.c254
-rw-r--r--ext/fiddle/pinned.c123
-rw-r--r--ext/fiddle/pointer.c171
-rw-r--r--[-rwxr-xr-x]ext/fiddle/win32/fficonfig.h0
-rwxr-xr-xext/fiddle/win32/libffi-config.rb2
-rw-r--r--[-rwxr-xr-x]ext/fiddle/win32/libffi.mk.tmpl0
-rw-r--r--ext/gdbm/depend152
-rw-r--r--ext/gdbm/gdbm.c35
-rw-r--r--ext/gdbm/gdbm.gemspec12
-rw-r--r--ext/io/console/console.c822
-rw-r--r--ext/io/console/depend155
-rw-r--r--ext/io/console/extconf.rb17
-rw-r--r--ext/io/console/io-console.gemspec23
-rw-r--r--ext/io/console/win32_vk.inc361
-rw-r--r--ext/io/console/win32_vk.list2
-rw-r--r--ext/io/nonblock/depend152
-rw-r--r--ext/io/nonblock/io-nonblock.gemspec25
-rw-r--r--ext/io/wait/depend152
-rw-r--r--ext/io/wait/io-wait.gemspec27
-rw-r--r--ext/io/wait/wait.c212
-rw-r--r--ext/json/VERSION1
-rw-r--r--ext/json/depend2
-rw-r--r--ext/json/extconf.rb1
-rw-r--r--ext/json/generator/depend155
-rw-r--r--ext/json/generator/generator.c271
-rw-r--r--ext/json/generator/generator.h7
-rw-r--r--ext/json/json.gemspecbin5474 -> 2464 bytes-rw-r--r--ext/json/lib/json.rb578
-rw-r--r--ext/json/lib/json/add/bigdecimal.rb4
-rw-r--r--ext/json/lib/json/add/complex.rb5
-rw-r--r--ext/json/lib/json/add/ostruct.rb2
-rw-r--r--ext/json/lib/json/add/rational.rb5
-rw-r--r--ext/json/lib/json/add/regexp.rb4
-rw-r--r--ext/json/lib/json/add/set.rb29
-rw-r--r--ext/json/lib/json/common.rb497
-rw-r--r--ext/json/lib/json/version.rb2
-rw-r--r--ext/json/parser/depend154
-rw-r--r--ext/json/parser/extconf.rb25
-rw-r--r--ext/json/parser/parser.c242
-rw-r--r--ext/json/parser/parser.h1
-rw-r--r--ext/json/parser/parser.rl90
-rw-r--r--ext/json/parser/prereq.mk4
-rw-r--r--ext/monitor/depend162
-rw-r--r--ext/monitor/extconf.rb2
-rw-r--r--ext/monitor/lib/monitor.rb284
-rw-r--r--ext/monitor/monitor.c225
-rw-r--r--ext/nkf/depend150
-rw-r--r--ext/nkf/nkf-utf8/nkf.c51
-rw-r--r--ext/nkf/nkf-utf8/utf8tbl.c158
-rw-r--r--ext/nkf/nkf.c1
-rw-r--r--ext/nkf/nkf.gemspec24
-rw-r--r--ext/objspace/depend492
-rw-r--r--ext/objspace/lib/objspace.rb91
-rw-r--r--ext/objspace/object_tracing.c125
-rw-r--r--ext/objspace/objspace.c311
-rw-r--r--ext/objspace/objspace_dump.c643
-rw-r--r--ext/openssl/History.md250
-rw-r--r--ext/openssl/depend4962
-rw-r--r--ext/openssl/deprecation.rb23
-rw-r--r--ext/openssl/extconf.rb85
-rw-r--r--ext/openssl/lib/openssl.rb34
-rw-r--r--ext/openssl/lib/openssl/bn.rb2
-rw-r--r--ext/openssl/lib/openssl/buffering.rb58
-rw-r--r--ext/openssl/lib/openssl/cipher.rb2
-rw-r--r--ext/openssl/lib/openssl/config.rb79
-rw-r--r--ext/openssl/lib/openssl/digest.rb22
-rw-r--r--ext/openssl/lib/openssl/hmac.rb13
-rw-r--r--ext/openssl/lib/openssl/marshal.rb30
-rw-r--r--ext/openssl/lib/openssl/pkcs5.rb2
-rw-r--r--ext/openssl/lib/openssl/pkey.rb43
-rw-r--r--ext/openssl/lib/openssl/ssl.rb56
-rw-r--r--ext/openssl/lib/openssl/version.rb5
-rw-r--r--ext/openssl/lib/openssl/x509.rb189
-rw-r--r--ext/openssl/openssl.gemspec63
-rw-r--r--ext/openssl/openssl_missing.h47
-rw-r--r--ext/openssl/ossl.c111
-rw-r--r--ext/openssl/ossl.h18
-rw-r--r--ext/openssl/ossl_asn1.c32
-rw-r--r--ext/openssl/ossl_bn.c126
-rw-r--r--ext/openssl/ossl_bn.h3
-rw-r--r--ext/openssl/ossl_cipher.c75
-rw-r--r--ext/openssl/ossl_digest.c75
-rw-r--r--ext/openssl/ossl_engine.c64
-rw-r--r--ext/openssl/ossl_hmac.c16
-rw-r--r--ext/openssl/ossl_kdf.c120
-rw-r--r--ext/openssl/ossl_ns_spki.c26
-rw-r--r--ext/openssl/ossl_ocsp.c17
-rw-r--r--ext/openssl/ossl_ocsp.h6
-rw-r--r--ext/openssl/ossl_pkcs12.c1
-rw-r--r--ext/openssl/ossl_pkcs7.c23
-rw-r--r--ext/openssl/ossl_pkcs7.h16
-rw-r--r--ext/openssl/ossl_pkey.c232
-rw-r--r--ext/openssl/ossl_pkey.h13
-rw-r--r--ext/openssl/ossl_pkey_dh.c2
-rw-r--r--ext/openssl/ossl_pkey_dsa.c4
-rw-r--r--ext/openssl/ossl_pkey_ec.c181
-rw-r--r--ext/openssl/ossl_pkey_rsa.c218
-rw-r--r--ext/openssl/ossl_rand.c42
-rw-r--r--ext/openssl/ossl_ssl.c449
-rw-r--r--ext/openssl/ossl_ts.c1524
-rw-r--r--ext/openssl/ossl_ts.h16
-rw-r--r--ext/openssl/ossl_version.h15
-rw-r--r--ext/openssl/ossl_x509.c91
-rw-r--r--ext/openssl/ossl_x509cert.c44
-rw-r--r--ext/openssl/ossl_x509crl.c9
-rw-r--r--ext/openssl/ossl_x509ext.c15
-rw-r--r--ext/openssl/ossl_x509name.c25
-rw-r--r--ext/openssl/ossl_x509req.c12
-rw-r--r--ext/openssl/ossl_x509revoked.c21
-rw-r--r--ext/openssl/ossl_x509store.c62
-rw-r--r--ext/pathname/depend152
-rw-r--r--ext/pathname/extconf.rb2
-rw-r--r--ext/pathname/lib/pathname.rb34
-rw-r--r--ext/pathname/pathname.c222
-rw-r--r--ext/pathname/pathname.gemspec25
-rw-r--r--ext/psych/.gitignore11
-rw-r--r--ext/psych/depend762
-rw-r--r--ext/psych/extconf.rb8
-rw-r--r--ext/psych/lib/psych.rb300
-rw-r--r--ext/psych/lib/psych/class_loader.rb10
-rw-r--r--ext/psych/lib/psych/handler.rb9
-rw-r--r--ext/psych/lib/psych/nodes/alias.rb2
-rw-r--r--ext/psych/lib/psych/nodes/document.rb2
-rw-r--r--ext/psych/lib/psych/nodes/mapping.rb2
-rw-r--r--ext/psych/lib/psych/nodes/node.rb23
-rw-r--r--ext/psych/lib/psych/nodes/scalar.rb4
-rw-r--r--ext/psych/lib/psych/nodes/sequence.rb2
-rw-r--r--ext/psych/lib/psych/nodes/stream.rb2
-rw-r--r--ext/psych/lib/psych/scalar_scanner.rb59
-rw-r--r--ext/psych/lib/psych/tree_builder.rb48
-rw-r--r--ext/psych/lib/psych/versions.rb7
-rw-r--r--ext/psych/lib/psych/visitors/to_ruby.rb67
-rw-r--r--ext/psych/lib/psych/visitors/visitor.rb20
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb76
-rw-r--r--ext/psych/psych.c9
-rw-r--r--ext/psych/psych.gemspec35
-rw-r--r--ext/psych/psych_emitter.c15
-rw-r--r--ext/psych/psych_parser.c95
-rw-r--r--ext/psych/psych_yaml_tree.c12
-rw-r--r--ext/psych/yaml/api.c95
-rw-r--r--ext/psych/yaml/config.h84
-rw-r--r--ext/psych/yaml/dumper.c6
-rw-r--r--ext/psych/yaml/emitter.c77
-rw-r--r--ext/psych/yaml/loader.c320
-rw-r--r--ext/psych/yaml/parser.c29
-rw-r--r--ext/psych/yaml/reader.c6
-rw-r--r--ext/psych/yaml/scanner.c86
-rw-r--r--ext/psych/yaml/yaml.h72
-rw-r--r--ext/psych/yaml/yaml_private.h68
-rw-r--r--ext/pty/depend160
-rw-r--r--ext/pty/extconf.rb6
-rw-r--r--ext/pty/lib/expect.rb6
-rw-r--r--ext/pty/pty.c126
-rw-r--r--ext/racc/cparse/README2
-rw-r--r--ext/racc/cparse/cparse.c48
-rw-r--r--ext/racc/cparse/depend151
-rw-r--r--ext/racc/cparse/extconf.rb6
-rw-r--r--ext/rbconfig/sizeof/depend300
-rw-r--r--ext/readline/.gitignore1
-rw-r--r--ext/readline/depend151
-rw-r--r--ext/readline/depend-gem4
-rw-r--r--ext/readline/extconf.rb8
-rw-r--r--ext/readline/readline-ext.gemspec26
-rw-r--r--ext/readline/readline.c62
-rw-r--r--ext/ripper/depend190
-rw-r--r--ext/ripper/eventids2.c359
-rw-r--r--ext/ripper/extconf.rb8
-rw-r--r--ext/ripper/lib/ripper/core.rb2
-rw-r--r--ext/ripper/lib/ripper/lexer.rb168
-rw-r--r--ext/ripper/lib/ripper/sexp.rb39
-rw-r--r--ext/ripper/tools/dsl.rb88
-rw-r--r--[-rwxr-xr-x]ext/ripper/tools/generate-param-macros.rb0
-rw-r--r--[-rwxr-xr-x]ext/ripper/tools/generate.rb9
-rw-r--r--[-rwxr-xr-x]ext/ripper/tools/preproc.rb51
-rw-r--r--[-rwxr-xr-x]ext/ripper/tools/strip.rb0
-rw-r--r--ext/rubyvm/depend2
-rw-r--r--ext/rubyvm/lib/forwardable/impl.rb5
-rw-r--r--ext/sdbm/_sdbm.c952
-rw-r--r--ext/sdbm/depend25
-rw-r--r--ext/sdbm/extconf.rb5
-rw-r--r--ext/sdbm/init.c1067
-rw-r--r--ext/sdbm/sdbm.gemspec21
-rw-r--r--ext/sdbm/sdbm.h86
-rw-r--r--ext/socket/ancdata.c22
-rw-r--r--ext/socket/basicsocket.c21
-rw-r--r--ext/socket/constants.c1
-rw-r--r--ext/socket/depend2445
-rw-r--r--ext/socket/extconf.rb3
-rw-r--r--ext/socket/getaddrinfo.c2
-rw-r--r--ext/socket/ifaddr.c51
-rw-r--r--ext/socket/init.c320
-rw-r--r--ext/socket/ipsocket.c30
-rw-r--r--ext/socket/lib/socket.rb25
-rw-r--r--ext/socket/mkconstants.rb31
-rw-r--r--ext/socket/option.c8
-rw-r--r--ext/socket/raddrinfo.c147
-rw-r--r--ext/socket/rubysocket.h72
-rw-r--r--ext/socket/socket.c154
-rw-r--r--ext/socket/sockssocket.c14
-rw-r--r--ext/socket/tcpserver.c2
-rw-r--r--ext/socket/tcpsocket.c39
-rw-r--r--ext/socket/udpsocket.c11
-rw-r--r--ext/socket/unixsocket.c59
-rw-r--r--ext/stringio/depend152
-rw-r--r--ext/stringio/extconf.rb1
-rw-r--r--ext/stringio/stringio.c462
-rw-r--r--ext/stringio/stringio.gemspec44
-rw-r--r--ext/strscan/depend153
-rw-r--r--ext/strscan/extconf.rb3
-rw-r--r--ext/strscan/strscan.c458
-rw-r--r--ext/strscan/strscan.gemspec28
-rw-r--r--ext/syslog/depend150
-rw-r--r--ext/syslog/extconf.rb2
-rw-r--r--ext/syslog/lib/syslog/logger.rb4
-rw-r--r--ext/syslog/syslog.c6
-rw-r--r--ext/syslog/syslog.gemspec23
-rw-r--r--ext/win32/depend2
-rw-r--r--ext/win32/lib/Win32API.rb47
-rw-r--r--ext/win32/lib/win32/importer.rb9
-rw-r--r--ext/win32/lib/win32/registry.rb16
-rw-r--r--ext/win32/lib/win32/resolv.rb14
-rw-r--r--ext/win32/lib/win32/resolv9x.rb253
-rw-r--r--ext/win32/lib/win32/sspi.rb627
-rw-r--r--ext/win32/resolv/depend17
-rw-r--r--ext/win32ole/lib/win32ole.rb33
-rw-r--r--ext/win32ole/win32ole.c91
-rw-r--r--ext/win32ole/win32ole.gemspec21
-rw-r--r--ext/win32ole/win32ole.h4
-rw-r--r--ext/win32ole/win32ole_error.c4
-rw-r--r--ext/win32ole/win32ole_error.h3
-rw-r--r--ext/win32ole/win32ole_event.c11
-rw-r--r--ext/win32ole/win32ole_method.c14
-rw-r--r--ext/win32ole/win32ole_method.h2
-rw-r--r--ext/win32ole/win32ole_record.c2
-rw-r--r--ext/win32ole/win32ole_record.h2
-rw-r--r--ext/win32ole/win32ole_type.c2
-rw-r--r--ext/win32ole/win32ole_type.h2
-rw-r--r--ext/win32ole/win32ole_typelib.c2
-rw-r--r--ext/win32ole/win32ole_typelib.h2
-rw-r--r--ext/win32ole/win32ole_variable.c2
-rw-r--r--ext/win32ole/win32ole_variable.h2
-rw-r--r--ext/win32ole/win32ole_variant.c3
-rw-r--r--ext/win32ole/win32ole_variant.h2
-rw-r--r--ext/win32ole/win32ole_variant_m.c2
-rw-r--r--ext/win32ole/win32ole_variant_m.h2
-rw-r--r--ext/zlib/.gitignore1
-rw-r--r--ext/zlib/depend152
-rw-r--r--ext/zlib/extconf.rb6
-rw-r--r--ext/zlib/extlibs6
-rw-r--r--ext/zlib/zlib.c631
-rw-r--r--ext/zlib/zlib.gemspec20
-rw-r--r--file.c1563
-rw-r--r--gc.c6632
-rw-r--r--gc.h33
-rw-r--r--gc.rb241
-rw-r--r--gem_prelude.rb19
-rw-r--r--gems/bundled_gems16
-rw-r--r--golf_prelude.rb7
-rw-r--r--goruby.c6
-rw-r--r--hash.c5207
-rw-r--r--hrtime.h168
-rw-r--r--ia64.s42
-rw-r--r--id_table.c24
-rw-r--r--id_table.h5
-rw-r--r--include/ruby.h31
-rw-r--r--include/ruby/assert.h234
-rw-r--r--include/ruby/atomic.h236
-rw-r--r--include/ruby/backward.h46
-rw-r--r--include/ruby/backward/2/assume.h43
-rw-r--r--include/ruby/backward/2/attributes.h170
-rw-r--r--include/ruby/backward/2/bool.h37
-rw-r--r--include/ruby/backward/2/gcc_version_since.h38
-rw-r--r--include/ruby/backward/2/inttypes.h132
-rw-r--r--include/ruby/backward/2/limits.h100
-rw-r--r--include/ruby/backward/2/long_long.h65
-rw-r--r--include/ruby/backward/2/r_cast.h33
-rw-r--r--include/ruby/backward/2/rmodule.h37
-rw-r--r--include/ruby/backward/2/stdalign.h30
-rw-r--r--include/ruby/backward/2/stdarg.h47
-rw-r--r--include/ruby/backward/classext.h18
-rw-r--r--include/ruby/backward/cxxanyargs.hpp683
-rw-r--r--include/ruby/backward/rubyio.h6
-rw-r--r--include/ruby/backward/rubysig.h47
-rw-r--r--include/ruby/backward/st.h6
-rw-r--r--include/ruby/backward/util.h6
-rw-r--r--include/ruby/debug.h53
-rw-r--r--include/ruby/defines.h359
-rw-r--r--include/ruby/encoding.h48
-rw-r--r--include/ruby/intern.h998
-rw-r--r--include/ruby/internal/anyargs.h375
-rw-r--r--include/ruby/internal/arithmetic.h38
-rw-r--r--include/ruby/internal/arithmetic/char.h58
-rw-r--r--include/ruby/internal/arithmetic/double.h39
-rw-r--r--include/ruby/internal/arithmetic/fixnum.h44
-rw-r--r--include/ruby/internal/arithmetic/gid_t.h34
-rw-r--r--include/ruby/internal/arithmetic/int.h163
-rw-r--r--include/ruby/internal/arithmetic/intptr_t.h42
-rw-r--r--include/ruby/internal/arithmetic/long.h244
-rw-r--r--include/ruby/internal/arithmetic/long_long.h53
-rw-r--r--include/ruby/internal/arithmetic/mode_t.h34
-rw-r--r--include/ruby/internal/arithmetic/off_t.h49
-rw-r--r--include/ruby/internal/arithmetic/pid_t.h34
-rw-r--r--include/ruby/internal/arithmetic/short.h54
-rw-r--r--include/ruby/internal/arithmetic/size_t.h56
-rw-r--r--include/ruby/internal/arithmetic/st_data_t.h59
-rw-r--r--include/ruby/internal/arithmetic/uid_t.h34
-rw-r--r--include/ruby/internal/assume.h90
-rw-r--r--include/ruby/internal/attr/alloc_size.h32
-rw-r--r--include/ruby/internal/attr/artificial.h46
-rw-r--r--include/ruby/internal/attr/cold.h37
-rw-r--r--include/ruby/internal/attr/const.h46
-rw-r--r--include/ruby/internal/attr/constexpr.h85
-rw-r--r--include/ruby/internal/attr/deprecated.h63
-rw-r--r--include/ruby/internal/attr/diagnose_if.h42
-rw-r--r--include/ruby/internal/attr/enum_extensibility.h32
-rw-r--r--include/ruby/internal/attr/error.h32
-rw-r--r--include/ruby/internal/attr/flag_enum.h33
-rw-r--r--include/ruby/internal/attr/forceinline.h40
-rw-r--r--include/ruby/internal/attr/format.h38
-rw-r--r--include/ruby/internal/attr/maybe_unused.h38
-rw-r--r--include/ruby/internal/attr/noalias.h58
-rw-r--r--include/ruby/internal/attr/nodiscard.h45
-rw-r--r--include/ruby/internal/attr/noexcept.h91
-rw-r--r--include/ruby/internal/attr/noinline.h35
-rw-r--r--include/ruby/internal/attr/nonnull.h32
-rw-r--r--include/ruby/internal/attr/noreturn.h48
-rw-r--r--include/ruby/internal/attr/pure.h43
-rw-r--r--include/ruby/internal/attr/restrict.h45
-rw-r--r--include/ruby/internal/attr/returns_nonnull.h37
-rw-r--r--include/ruby/internal/attr/warning.h32
-rw-r--r--include/ruby/internal/attr/weakref.h32
-rw-r--r--include/ruby/internal/cast.h53
-rw-r--r--include/ruby/internal/compiler_is.h45
-rw-r--r--include/ruby/internal/compiler_is/apple.h41
-rw-r--r--include/ruby/internal/compiler_is/clang.h38
-rw-r--r--include/ruby/internal/compiler_is/gcc.h46
-rw-r--r--include/ruby/internal/compiler_is/intel.h41
-rw-r--r--include/ruby/internal/compiler_is/msvc.h57
-rw-r--r--include/ruby/internal/compiler_is/sunpro.h55
-rw-r--r--include/ruby/internal/compiler_since.h61
-rw-r--r--include/ruby/internal/config.h144
-rw-r--r--include/ruby/internal/constant_p.h37
-rw-r--r--include/ruby/internal/core.h35
-rw-r--r--include/ruby/internal/core/rarray.h270
-rw-r--r--include/ruby/internal/core/rbasic.h85
-rw-r--r--include/ruby/internal/core/rbignum.h51
-rw-r--r--include/ruby/internal/core/rclass.h47
-rw-r--r--include/ruby/internal/core/rdata.h184
-rw-r--r--include/ruby/internal/core/rfile.h36
-rw-r--r--include/ruby/internal/core/rhash.h62
-rw-r--r--include/ruby/internal/core/rmatch.h73
-rw-r--r--include/ruby/internal/core/robject.h96
-rw-r--r--include/ruby/internal/core/rregexp.h84
-rw-r--r--include/ruby/internal/core/rstring.h215
-rw-r--r--include/ruby/internal/core/rstruct.h73
-rw-r--r--include/ruby/internal/core/rtypeddata.h186
-rw-r--r--include/ruby/internal/ctype.h203
-rw-r--r--include/ruby/internal/dllexport.h92
-rw-r--r--include/ruby/internal/dosish.h63
-rw-r--r--include/ruby/internal/error.h84
-rw-r--r--include/ruby/internal/eval.h50
-rw-r--r--include/ruby/internal/event.h75
-rw-r--r--include/ruby/internal/fl_type.h471
-rw-r--r--include/ruby/internal/gc.h57
-rw-r--r--include/ruby/internal/glob.h35
-rw-r--r--include/ruby/internal/globals.h157
-rw-r--r--include/ruby/internal/has/attribute.h164
-rw-r--r--include/ruby/internal/has/builtin.h105
-rw-r--r--include/ruby/internal/has/c_attribute.h38
-rw-r--r--include/ruby/internal/has/cpp_attribute.h87
-rw-r--r--include/ruby/internal/has/declspec_attribute.h48
-rw-r--r--include/ruby/internal/has/extension.h33
-rw-r--r--include/ruby/internal/has/feature.h31
-rw-r--r--include/ruby/internal/has/warning.h31
-rw-r--r--include/ruby/internal/intern/array.h78
-rw-r--r--include/ruby/internal/intern/bignum.h105
-rw-r--r--include/ruby/internal/intern/class.h57
-rw-r--r--include/ruby/internal/intern/compar.h34
-rw-r--r--include/ruby/internal/intern/complex.h60
-rw-r--r--include/ruby/internal/intern/cont.h41
-rw-r--r--include/ruby/internal/intern/dir.h33
-rw-r--r--include/ruby/internal/intern/enum.h33
-rw-r--r--include/ruby/internal/intern/enumerator.h80
-rw-r--r--include/ruby/internal/intern/error.h82
-rw-r--r--include/ruby/internal/intern/eval.h59
-rw-r--r--include/ruby/internal/intern/file.h42
-rw-r--r--include/ruby/internal/intern/gc.h57
-rw-r--r--include/ruby/internal/intern/hash.h59
-rw-r--r--include/ruby/internal/intern/io.h70
-rw-r--r--include/ruby/internal/intern/load.h44
-rw-r--r--include/ruby/internal/intern/marshal.h35
-rw-r--r--include/ruby/internal/intern/numeric.h42
-rw-r--r--include/ruby/internal/intern/object.h90
-rw-r--r--include/ruby/internal/intern/parse.h64
-rw-r--r--include/ruby/internal/intern/proc.h53
-rw-r--r--include/ruby/internal/intern/process.h46
-rw-r--r--include/ruby/internal/intern/random.h45
-rw-r--r--include/ruby/internal/intern/range.h35
-rw-r--r--include/ruby/internal/intern/rational.h46
-rw-r--r--include/ruby/internal/intern/re.h50
-rw-r--r--include/ruby/internal/intern/ruby.h37
-rw-r--r--include/ruby/internal/intern/select.h52
-rw-r--r--include/ruby/internal/intern/select/largesize.h103
-rw-r--r--include/ruby/internal/intern/select/posix.h82
-rw-r--r--include/ruby/internal/intern/select/win32.h124
-rw-r--r--include/ruby/internal/intern/signal.h39
-rw-r--r--include/ruby/internal/intern/sprintf.h43
-rw-r--r--include/ruby/internal/intern/string.h298
-rw-r--r--include/ruby/internal/intern/struct.h47
-rw-r--r--include/ruby/internal/intern/thread.h76
-rw-r--r--include/ruby/internal/intern/time.h51
-rw-r--r--include/ruby/internal/intern/variable.h83
-rw-r--r--include/ruby/internal/intern/vm.h77
-rw-r--r--include/ruby/internal/interpreter.h93
-rw-r--r--include/ruby/internal/iterator.h65
-rw-r--r--include/ruby/internal/memory.h281
-rw-r--r--include/ruby/internal/method.h39
-rw-r--r--include/ruby/internal/module.h39
-rw-r--r--include/ruby/internal/newobj.h73
-rw-r--r--include/ruby/internal/rgengc.h199
-rw-r--r--include/ruby/internal/scan_args.h401
-rw-r--r--include/ruby/internal/special_consts.h204
-rw-r--r--include/ruby/internal/static_assert.h77
-rw-r--r--include/ruby/internal/stdalign.h133
-rw-r--r--include/ruby/internal/stdbool.h51
-rw-r--r--include/ruby/internal/symbol.h114
-rw-r--r--include/ruby/internal/token_paste.h75
-rw-r--r--include/ruby/internal/value.h66
-rw-r--r--include/ruby/internal/value_type.h354
-rw-r--r--include/ruby/internal/variable.h62
-rw-r--r--include/ruby/internal/warning_push.h91
-rw-r--r--include/ruby/internal/xmalloc.h362
-rw-r--r--include/ruby/io.h73
-rw-r--r--include/ruby/memory_view.h165
-rw-r--r--include/ruby/missing.h140
-rw-r--r--include/ruby/onigmo.h10
-rw-r--r--include/ruby/ractor.h68
-rw-r--r--include/ruby/random.h92
-rw-r--r--include/ruby/re.h70
-rw-r--r--include/ruby/regex.h22
-rw-r--r--include/ruby/ruby.h2518
-rw-r--r--include/ruby/st.h130
-rw-r--r--include/ruby/subst.h10
-rw-r--r--include/ruby/thread.h55
-rw-r--r--include/ruby/thread_native.h42
-rw-r--r--include/ruby/util.h69
-rw-r--r--include/ruby/version.h56
-rw-r--r--include/ruby/vm.h45
-rw-r--r--include/ruby/win32.h136
-rw-r--r--inits.c40
-rw-r--r--insns.def1392
-rw-r--r--integer.rb150
-rw-r--r--internal.h1980
-rw-r--r--internal/array.h119
-rw-r--r--internal/bignum.h246
-rw-r--r--internal/bits.h566
-rw-r--r--internal/class.h174
-rw-r--r--internal/compar.h50
-rw-r--r--internal/compile.h32
-rw-r--r--internal/compilers.h108
-rw-r--r--internal/complex.h30
-rw-r--r--internal/cont.h26
-rw-r--r--internal/dir.h17
-rw-r--r--internal/enc.h20
-rw-r--r--internal/encoding.h31
-rw-r--r--internal/enum.h19
-rw-r--r--internal/enumerator.h22
-rw-r--r--internal/error.h124
-rw-r--r--internal/eval.h33
-rw-r--r--internal/file.h39
-rw-r--r--internal/fixnum.h185
-rw-r--r--internal/gc.h167
-rw-r--r--internal/hash.h241
-rw-r--r--internal/imemo.h244
-rw-r--r--internal/inits.h51
-rw-r--r--internal/io.h35
-rw-r--r--internal/load.h19
-rw-r--r--internal/loadpath.h17
-rw-r--r--internal/math.h24
-rw-r--r--internal/missing.h19
-rw-r--r--internal/numeric.h255
-rw-r--r--internal/object.h83
-rw-r--r--internal/parse.h23
-rw-r--r--internal/proc.h33
-rw-r--r--internal/process.h136
-rw-r--r--internal/random.h17
-rw-r--r--internal/range.h41
-rw-r--r--internal/rational.h72
-rw-r--r--internal/re.h29
-rw-r--r--internal/sanitizers.h191
-rw-r--r--internal/scheduler.h44
-rw-r--r--internal/serial.h24
-rw-r--r--internal/signal.h22
-rw-r--r--internal/static_assert.h17
-rw-r--r--internal/string.h141
-rw-r--r--internal/struct.h154
-rw-r--r--internal/symbol.h41
-rw-r--r--internal/thread.h54
-rw-r--r--internal/time.h35
-rw-r--r--internal/transcode.h21
-rw-r--r--internal/util.h31
-rw-r--r--internal/variable.h84
-rw-r--r--internal/vm.h131
-rw-r--r--internal/warnings.h17
-rw-r--r--io.c2881
-rw-r--r--io.rb123
-rw-r--r--iseq.c2315
-rw-r--r--iseq.h243
-rw-r--r--kernel.rb174
-rw-r--r--lex.c.blt121
-rw-r--r--lib/.document26
-rw-r--r--lib/English.gemspec24
-rw-r--r--lib/English.rb48
-rw-r--r--lib/abbrev.gemspec22
-rw-r--r--lib/base64.gemspec22
-rw-r--r--lib/base64.rb5
-rw-r--r--lib/benchmark.rb13
-rw-r--r--lib/benchmark/benchmark.gemspec29
-rw-r--r--lib/benchmark/version.rb3
-rw-r--r--lib/bundler.gemspec251
-rw-r--r--lib/bundler.rb450
-rw-r--r--lib/bundler/build_metadata.rb43
-rw-r--r--lib/bundler/bundler.gemspec45
-rw-r--r--lib/bundler/capistrano.rb9
-rw-r--r--lib/bundler/cli.rb481
-rw-r--r--lib/bundler/cli/add.rb45
-rw-r--r--lib/bundler/cli/binstubs.rb30
-rw-r--r--lib/bundler/cli/cache.rb42
-rw-r--r--lib/bundler/cli/check.rb14
-rw-r--r--lib/bundler/cli/clean.rb13
-rw-r--r--lib/bundler/cli/common.rb65
-rw-r--r--lib/bundler/cli/config.rb248
-rw-r--r--lib/bundler/cli/console.rb5
-rw-r--r--lib/bundler/cli/doctor.rb72
-rw-r--r--lib/bundler/cli/exec.rb42
-rw-r--r--lib/bundler/cli/fund.rb36
-rw-r--r--lib/bundler/cli/gem.rb257
-rw-r--r--lib/bundler/cli/info.rb50
-rw-r--r--lib/bundler/cli/init.rb24
-rw-r--r--lib/bundler/cli/inject.rb3
-rw-r--r--lib/bundler/cli/install.rb175
-rw-r--r--lib/bundler/cli/issue.rb17
-rw-r--r--lib/bundler/cli/list.rb66
-rw-r--r--lib/bundler/cli/lock.rb7
-rw-r--r--lib/bundler/cli/open.rb19
-rw-r--r--lib/bundler/cli/outdated.rb275
-rw-r--r--lib/bundler/cli/package.rb46
-rw-r--r--lib/bundler/cli/platform.rb1
-rw-r--r--lib/bundler/cli/plugin.rb22
-rw-r--r--lib/bundler/cli/pristine.rb20
-rw-r--r--lib/bundler/cli/remove.rb17
-rw-r--r--lib/bundler/cli/show.rb5
-rw-r--r--lib/bundler/cli/update.rb79
-rw-r--r--lib/bundler/cli/viz.rb1
-rw-r--r--lib/bundler/compact_index_client.rb41
-rw-r--r--lib/bundler/compact_index_client/cache.rb23
-rw-r--r--lib/bundler/compact_index_client/gem_parser.rb28
-rw-r--r--lib/bundler/compact_index_client/updater.rb45
-rw-r--r--lib/bundler/constants.rb1
-rw-r--r--lib/bundler/current_ruby.rb37
-rw-r--r--lib/bundler/definition.rb656
-rw-r--r--lib/bundler/dep_proxy.rb25
-rw-r--r--lib/bundler/dependency.rb45
-rw-r--r--lib/bundler/deployment.rb4
-rw-r--r--lib/bundler/deprecate.rb18
-rw-r--r--lib/bundler/digest.rb71
-rw-r--r--lib/bundler/dsl.rb263
-rw-r--r--lib/bundler/endpoint_specification.rb13
-rw-r--r--lib/bundler/env.rb132
-rw-r--r--lib/bundler/environment_preserver.rb63
-rw-r--r--lib/bundler/errors.rb24
-rw-r--r--lib/bundler/feature_flag.rb37
-rw-r--r--lib/bundler/fetcher.rb64
-rw-r--r--lib/bundler/fetcher/base.rb3
-rw-r--r--lib/bundler/fetcher/compact_index.rb55
-rw-r--r--lib/bundler/fetcher/dependency.rb5
-rw-r--r--lib/bundler/fetcher/downloader.rb38
-rw-r--r--lib/bundler/fetcher/index.rb19
-rw-r--r--lib/bundler/friendly_errors.rb80
-rw-r--r--lib/bundler/gem_helper.rb145
-rw-r--r--lib/bundler/gem_helpers.rb68
-rw-r--r--lib/bundler/gem_remote_fetcher.rb42
-rw-r--r--lib/bundler/gem_tasks.rb3
-rw-r--r--lib/bundler/gem_version_promoter.rb27
-rw-r--r--lib/bundler/gemdeps.rb1
-rw-r--r--lib/bundler/graph.rb7
-rw-r--r--lib/bundler/index.rb32
-rw-r--r--lib/bundler/injector.rb246
-rw-r--r--lib/bundler/inline.rb73
-rw-r--r--lib/bundler/installer.rb202
-rw-r--r--lib/bundler/installer/gem_installer.rb22
-rw-r--r--lib/bundler/installer/parallel_installer.rb169
-rw-r--r--lib/bundler/installer/standalone.rb42
-rw-r--r--lib/bundler/lazy_specification.rb94
-rw-r--r--lib/bundler/lockfile_generator.rb95
-rw-r--r--lib/bundler/lockfile_parser.rb65
-rw-r--r--lib/bundler/man/.document (renamed from lib/bundler/ssl_certs/.document)0
-rw-r--r--lib/bundler/man/bundle-add.166
-rw-r--r--lib/bundler/man/bundle-add.1.ronn46
-rw-r--r--lib/bundler/man/bundle-binstubs.142
-rw-r--r--lib/bundler/man/bundle-binstubs.1.ronn41
-rw-r--r--lib/bundler/man/bundle-cache.155
-rw-r--r--lib/bundler/man/bundle-cache.1.ronn72
-rw-r--r--lib/bundler/man/bundle-check.131
-rw-r--r--lib/bundler/man/bundle-check.1.ronn26
-rw-r--r--lib/bundler/man/bundle-clean.124
-rw-r--r--lib/bundler/man/bundle-clean.1.ronn18
-rw-r--r--lib/bundler/man/bundle-config.1496
-rw-r--r--lib/bundler/man/bundle-config.1.ronn396
-rw-r--r--lib/bundler/man/bundle-doctor.144
-rw-r--r--lib/bundler/man/bundle-doctor.1.ronn33
-rw-r--r--lib/bundler/man/bundle-exec.1165
-rw-r--r--lib/bundler/man/bundle-exec.1.ronn152
-rw-r--r--lib/bundler/man/bundle-gem.1115
-rw-r--r--lib/bundler/man/bundle-gem.1.ronn117
-rw-r--r--lib/bundler/man/bundle-info.120
-rw-r--r--lib/bundler/man/bundle-info.1.ronn17
-rw-r--r--lib/bundler/man/bundle-init.125
-rw-r--r--lib/bundler/man/bundle-init.1.ronn29
-rw-r--r--lib/bundler/man/bundle-inject.133
-rw-r--r--lib/bundler/man/bundle-inject.1.ronn22
-rw-r--r--lib/bundler/man/bundle-install.1338
-rw-r--r--lib/bundler/man/bundle-install.1.ronn405
-rw-r--r--lib/bundler/man/bundle-list.150
-rw-r--r--lib/bundler/man/bundle-list.1.ronn33
-rw-r--r--lib/bundler/man/bundle-lock.184
-rw-r--r--lib/bundler/man/bundle-lock.1.ronn94
-rw-r--r--lib/bundler/man/bundle-open.132
-rw-r--r--lib/bundler/man/bundle-open.1.ronn19
-rw-r--r--lib/bundler/man/bundle-outdated.1155
-rw-r--r--lib/bundler/man/bundle-outdated.1.ronn111
-rw-r--r--lib/bundler/man/bundle-platform.161
-rw-r--r--lib/bundler/man/bundle-platform.1.ronn42
-rw-r--r--lib/bundler/man/bundle-pristine.134
-rw-r--r--lib/bundler/man/bundle-pristine.1.ronn34
-rw-r--r--lib/bundler/man/bundle-remove.131
-rw-r--r--lib/bundler/man/bundle-remove.1.ronn23
-rw-r--r--lib/bundler/man/bundle-show.123
-rw-r--r--lib/bundler/man/bundle-show.1.ronn21
-rw-r--r--lib/bundler/man/bundle-update.1394
-rw-r--r--lib/bundler/man/bundle-update.1.ronn350
-rw-r--r--lib/bundler/man/bundle-viz.139
-rw-r--r--lib/bundler/man/bundle-viz.1.ronn30
-rw-r--r--lib/bundler/man/bundle.1136
-rw-r--r--lib/bundler/man/bundle.1.ronn111
-rw-r--r--lib/bundler/man/gemfile.5712
-rw-r--r--lib/bundler/man/gemfile.5.ronn525
-rw-r--r--lib/bundler/man/index.txt25
-rw-r--r--lib/bundler/match_platform.rb3
-rw-r--r--lib/bundler/mirror.rb21
-rw-r--r--lib/bundler/plugin.rb158
-rw-r--r--lib/bundler/plugin/api.rb2
-rw-r--r--lib/bundler/plugin/api/source.rb43
-rw-r--r--lib/bundler/plugin/dsl.rb2
-rw-r--r--lib/bundler/plugin/events.rb61
-rw-r--r--lib/bundler/plugin/index.rb40
-rw-r--r--lib/bundler/plugin/installer.rb44
-rw-r--r--lib/bundler/plugin/installer/rubygems.rb2
-rw-r--r--lib/bundler/plugin/source_list.rb19
-rw-r--r--lib/bundler/process_lock.rb24
-rw-r--r--lib/bundler/psyched_yaml.rb5
-rw-r--r--lib/bundler/remote_specification.rb8
-rw-r--r--lib/bundler/resolver.rb429
-rw-r--r--lib/bundler/resolver/spec_group.rb110
-rw-r--r--lib/bundler/retry.rb9
-rw-r--r--lib/bundler/ruby_dsl.rb1
-rw-r--r--lib/bundler/ruby_version.rb26
-rw-r--r--lib/bundler/rubygems_ext.rb179
-rw-r--r--lib/bundler/rubygems_gem_installer.rb100
-rw-r--r--lib/bundler/rubygems_integration.rb643
-rw-r--r--lib/bundler/runtime.rb76
-rw-r--r--lib/bundler/settings.rb452
-rw-r--r--lib/bundler/settings/validator.rb102
-rw-r--r--lib/bundler/setup.rb24
-rw-r--r--lib/bundler/shared_helpers.rb213
-rw-r--r--lib/bundler/similarity_detector.rb7
-rw-r--r--lib/bundler/source.rb67
-rw-r--r--lib/bundler/source/gemspec.rb1
-rw-r--r--lib/bundler/source/git.rb142
-rw-r--r--lib/bundler/source/git/git_proxy.rb223
-rw-r--r--lib/bundler/source/metadata.rb63
-rw-r--r--lib/bundler/source/path.rb49
-rw-r--r--lib/bundler/source/path/installer.rb22
-rw-r--r--lib/bundler/source/rubygems.rb381
-rw-r--r--lib/bundler/source/rubygems/remote.rb13
-rw-r--r--lib/bundler/source/rubygems_aggregate.rb68
-rw-r--r--lib/bundler/source_list.rb159
-rw-r--r--lib/bundler/source_map.rb58
-rw-r--r--lib/bundler/spec_set.rb107
-rw-r--r--lib/bundler/ssl_certs/certificate_manager.rb65
-rw-r--r--lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem23
-rw-r--r--lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem25
-rw-r--r--lib/bundler/stub_specification.rb73
-rw-r--r--lib/bundler/templates/.document1
-rw-r--r--[-rwxr-xr-x]lib/bundler/templates/Executable12
-rw-r--r--lib/bundler/templates/Executable.bundler114
-rw-r--r--lib/bundler/templates/Gemfile3
-rw-r--r--lib/bundler/templates/gems.rb8
-rw-r--r--lib/bundler/templates/newgem/CHANGELOG.md.tt5
-rw-r--r--lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt104
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt21
-rw-r--r--lib/bundler/templates/newgem/README.md.tt14
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt28
-rw-r--r--lib/bundler/templates/newgem/bin/console.tt1
-rw-r--r--lib/bundler/templates/newgem/circleci/config.yml.tt13
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt2
-rw-r--r--lib/bundler/templates/newgem/github/workflows/main.yml.tt27
-rw-r--r--lib/bundler/templates/newgem/gitignore.tt1
-rw-r--r--lib/bundler/templates/newgem/gitlab-ci.yml.tt9
-rw-r--r--lib/bundler/templates/newgem/lib/newgem.rb.tt7
-rw-r--r--lib/bundler/templates/newgem/lib/newgem/version.rb.tt2
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt66
-rw-r--r--lib/bundler/templates/newgem/rspec.tt1
-rw-r--r--lib/bundler/templates/newgem/rubocop.yml.tt13
-rw-r--r--lib/bundler/templates/newgem/sig/newgem.rbs.tt8
-rw-r--r--lib/bundler/templates/newgem/spec/newgem_spec.rb.tt2
-rw-r--r--lib/bundler/templates/newgem/spec/spec_helper.rb.tt3
-rw-r--r--lib/bundler/templates/newgem/standard.yml.tt2
-rw-r--r--lib/bundler/templates/newgem/test/minitest/newgem_test.rb.tt13
-rw-r--r--lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt6
-rw-r--r--lib/bundler/templates/newgem/test/newgem_test.rb.tt11
-rw-r--r--lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt15
-rw-r--r--lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt6
-rw-r--r--lib/bundler/templates/newgem/test/test_helper.rb.tt4
-rw-r--r--lib/bundler/templates/newgem/travis.yml.tt3
-rw-r--r--lib/bundler/ui.rb7
-rw-r--r--lib/bundler/ui/rg_proxy.rb3
-rw-r--r--lib/bundler/ui/shell.rb29
-rw-r--r--lib/bundler/ui/silent.rb1
-rw-r--r--lib/bundler/uri_credentials_filter.rb15
-rw-r--r--lib/bundler/vendor/.document1
-rw-r--r--lib/bundler/vendor/connection_pool/LICENSE20
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool.rb126
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb174
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb3
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb57
-rw-r--r--lib/bundler/vendor/fileutils/LICENSE.txt22
-rw-r--r--lib/bundler/vendor/fileutils/lib/fileutils.rb1764
-rw-r--r--lib/bundler/vendor/molinillo/LICENSE9
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo.rb11
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb7
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb8
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb49
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb1
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb3
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb3
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb3
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb3
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb13
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb3
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb7
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb63
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/errors.rb84
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb3
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb14
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb4
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb675
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb5
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/state.rb12
-rw-r--r--lib/bundler/vendor/net-http-persistent/README.rdoc82
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb27
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb764
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb40
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb53
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb129
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb79
-rw-r--r--lib/bundler/vendor/thor/LICENSE.md20
-rw-r--r--lib/bundler/vendor/thor/lib/thor.rb25
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions.rb41
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/create_file.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/create_link.rb5
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/directory.rb24
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb29
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb27
-rw-r--r--lib/bundler/vendor/thor/lib/thor/base.rb106
-rw-r--r--lib/bundler/vendor/thor/lib/thor/command.rb35
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb12
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb129
-rw-r--r--lib/bundler/vendor/thor/lib/thor/error.rb78
-rw-r--r--lib/bundler/vendor/thor/lib/thor/group.rb6
-rw-r--r--lib/bundler/vendor/thor/lib/thor/invocation.rb1
-rw-r--r--lib/bundler/vendor/thor/lib/thor/line_editor.rb4
-rw-r--r--lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb12
-rw-r--r--lib/bundler/vendor/thor/lib/thor/nested_context.rb29
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser.rb8
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/arguments.rb10
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/option.rb27
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/options.rb26
-rw-r--r--lib/bundler/vendor/thor/lib/thor/rake_compat.rb1
-rw-r--r--lib/bundler/vendor/thor/lib/thor/runner.rb25
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell.rb8
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/basic.rb73
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/color.rb12
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/html.rb6
-rw-r--r--lib/bundler/vendor/thor/lib/thor/util.rb20
-rw-r--r--lib/bundler/vendor/thor/lib/thor/version.rb2
-rw-r--r--lib/bundler/vendor/tmpdir/lib/tmpdir.rb154
-rw-r--r--lib/bundler/vendor/tsort/LICENSE.txt22
-rw-r--r--lib/bundler/vendor/tsort/lib/tsort.rb453
-rw-r--r--lib/bundler/vendor/uri/LICENSE.txt22
-rw-r--r--lib/bundler/vendor/uri/lib/uri.rb104
-rw-r--r--lib/bundler/vendor/uri/lib/uri/common.rb744
-rw-r--r--lib/bundler/vendor/uri/lib/uri/file.rb94
-rw-r--r--lib/bundler/vendor/uri/lib/uri/ftp.rb267
-rw-r--r--lib/bundler/vendor/uri/lib/uri/generic.rb1568
-rw-r--r--lib/bundler/vendor/uri/lib/uri/http.rb88
-rw-r--r--lib/bundler/vendor/uri/lib/uri/https.rb23
-rw-r--r--lib/bundler/vendor/uri/lib/uri/ldap.rb261
-rw-r--r--lib/bundler/vendor/uri/lib/uri/ldaps.rb21
-rw-r--r--lib/bundler/vendor/uri/lib/uri/mailto.rb294
-rw-r--r--lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb546
-rw-r--r--lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb125
-rw-r--r--lib/bundler/vendor/uri/lib/uri/version.rb6
-rw-r--r--lib/bundler/vendored_fileutils.rb4
-rw-r--r--lib/bundler/vendored_molinillo.rb3
-rw-r--r--lib/bundler/vendored_persistent.rb46
-rw-r--r--lib/bundler/vendored_thor.rb5
-rw-r--r--lib/bundler/vendored_tmpdir.rb4
-rw-r--r--lib/bundler/vendored_tsort.rb4
-rw-r--r--lib/bundler/vendored_uri.rb4
-rw-r--r--lib/bundler/version.rb23
-rw-r--r--lib/bundler/version_ranges.rb57
-rw-r--r--lib/bundler/vlad.rb7
-rw-r--r--lib/bundler/worker.rb28
-rw-r--r--lib/bundler/yaml_serializer.rb13
-rw-r--r--lib/cgi.rb3
-rw-r--r--lib/cgi/cgi.gemspec31
-rw-r--r--lib/cgi/cookie.rb57
-rw-r--r--lib/cgi/core.rb80
-rw-r--r--lib/cgi/html.rb6
-rw-r--r--lib/cgi/session.rb12
-rw-r--r--lib/cgi/session/pstore.rb3
-rw-r--r--lib/cgi/util.rb38
-rw-r--r--lib/cmath.gemspec24
-rw-r--r--lib/cmath.rb435
-rw-r--r--lib/csv.gemspec21
-rw-r--r--lib/csv.rb4124
-rw-r--r--lib/csv/core_ext/array.rb9
-rw-r--r--lib/csv/core_ext/string.rb9
-rw-r--r--lib/csv/csv.gemspec64
-rw-r--r--lib/csv/delete_suffix.rb18
-rw-r--r--lib/csv/fields_converter.rb84
-rw-r--r--lib/csv/match_p.rb20
-rw-r--r--lib/csv/parser.rb1142
-rw-r--r--lib/csv/row.rb624
-rw-r--r--lib/csv/table.rb621
-rw-r--r--lib/csv/version.rb6
-rw-r--r--lib/csv/writer.rb209
-rw-r--r--lib/debug.gemspec22
-rw-r--r--lib/debug.rb35
-rw-r--r--lib/delegate.rb120
-rw-r--r--lib/delegate/delegate.gemspec31
-rw-r--r--lib/did_you_mean.rb112
-rw-r--r--lib/did_you_mean/core_ext/name_error.rb25
-rw-r--r--lib/did_you_mean/did_you_mean.gemspec27
-rw-r--r--lib/did_you_mean/experimental.rb2
-rw-r--r--lib/did_you_mean/formatters/plain_formatter.rb33
-rw-r--r--lib/did_you_mean/formatters/verbose_formatter.rb49
-rw-r--r--lib/did_you_mean/jaro_winkler.rb87
-rw-r--r--lib/did_you_mean/levenshtein.rb57
-rw-r--r--lib/did_you_mean/spell_checker.rb46
-rw-r--r--lib/did_you_mean/spell_checkers/key_error_checker.rb20
-rw-r--r--lib/did_you_mean/spell_checkers/method_name_checker.rb69
-rw-r--r--lib/did_you_mean/spell_checkers/name_error_checkers.rb20
-rw-r--r--lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb49
-rw-r--r--lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb82
-rw-r--r--lib/did_you_mean/spell_checkers/null_checker.rb6
-rw-r--r--lib/did_you_mean/spell_checkers/require_path_checker.rb35
-rw-r--r--lib/did_you_mean/tree_spell_checker.rb109
-rw-r--r--lib/did_you_mean/verbose.rb4
-rw-r--r--lib/did_you_mean/version.rb3
-rw-r--r--lib/drb/acl.rb7
-rw-r--r--lib/drb/drb.gemspec30
-rw-r--r--lib/drb/drb.rb310
-rw-r--r--lib/drb/extserv.rb2
-rw-r--r--lib/drb/extservm.rb7
-rw-r--r--lib/drb/gw.rb2
-rw-r--r--lib/drb/observer.rb2
-rw-r--r--lib/drb/ssl.rb14
-rw-r--r--lib/drb/timeridconv.rb2
-rw-r--r--lib/drb/unix.rb8
-rw-r--r--lib/drb/version.rb3
-rw-r--r--lib/drb/weakidconv.rb59
-rw-r--r--lib/e2mmap.rb177
-rw-r--r--lib/erb.gemspec24
-rw-r--r--lib/erb.rb132
-rw-r--r--lib/fileutils.gemspec24
-rw-r--r--lib/fileutils.rb443
-rw-r--r--lib/find.gemspec24
-rw-r--r--lib/find.rb6
-rw-r--r--lib/forwardable.rb45
-rw-r--r--lib/forwardable/forwardable.gemspec26
-rw-r--r--lib/forwardable/impl.rb8
-rw-r--r--lib/getoptlong.rb3
-rw-r--r--lib/getoptlong/getoptlong.gemspec32
-rw-r--r--lib/ipaddr.gemspec12
-rw-r--r--lib/ipaddr.rb100
-rw-r--r--lib/irb.rb426
-rw-r--r--lib/irb/.document1
-rw-r--r--lib/irb/cmd/chws.rb4
-rw-r--r--lib/irb/cmd/fork.rb6
-rw-r--r--lib/irb/cmd/help.rb16
-rw-r--r--lib/irb/cmd/info.rb25
-rw-r--r--lib/irb/cmd/load.rb4
-rw-r--r--lib/irb/cmd/ls.rb83
-rw-r--r--lib/irb/cmd/measure.rb40
-rw-r--r--lib/irb/cmd/nop.rb14
-rw-r--r--lib/irb/cmd/pushws.rb5
-rw-r--r--lib/irb/cmd/show_source.rb86
-rw-r--r--lib/irb/cmd/subirb.rb4
-rw-r--r--lib/irb/cmd/whereami.rb20
-rw-r--r--lib/irb/color.rb251
-rw-r--r--lib/irb/color_printer.rb47
-rw-r--r--lib/irb/completion.rb301
-rw-r--r--lib/irb/context.rb210
-rw-r--r--lib/irb/easter-egg.rb138
-rw-r--r--lib/irb/ext/change-ws.rb1
-rw-r--r--lib/irb/ext/history.rb58
-rw-r--r--lib/irb/ext/loader.rb66
-rw-r--r--lib/irb/ext/multi-irb.rb14
-rw-r--r--lib/irb/ext/save-history.rb47
-rw-r--r--lib/irb/ext/tracer.rb16
-rw-r--r--lib/irb/ext/use-loader.rb11
-rw-r--r--lib/irb/ext/workspaces.rb1
-rw-r--r--lib/irb/extend-command.rb176
-rw-r--r--lib/irb/frame.rb19
-rw-r--r--lib/irb/help.rb3
-rw-r--r--lib/irb/init.rb181
-rw-r--r--lib/irb/input-method.rb201
-rw-r--r--lib/irb/inspector.rb26
-rw-r--r--lib/irb/irb.gemspec42
-rw-r--r--lib/irb/lc/.document4
-rw-r--r--lib/irb/lc/error.rb71
-rw-r--r--lib/irb/lc/help-message27
-rw-r--r--lib/irb/lc/ja/error.rb69
-rw-r--r--lib/irb/lc/ja/help-message15
-rw-r--r--lib/irb/locale.rb19
-rw-r--r--lib/irb/notifier.rb22
-rw-r--r--lib/irb/output-method.rb12
-rw-r--r--lib/irb/ruby-lex.rb1618
-rw-r--r--lib/irb/ruby-token.rb267
-rw-r--r--lib/irb/ruby_logo.aa37
-rw-r--r--lib/irb/slex.rb282
-rw-r--r--lib/irb/version.rb5
-rw-r--r--lib/irb/workspace.rb105
-rw-r--r--lib/irb/xmp.rb4
-rw-r--r--lib/logger.rb365
-rw-r--r--lib/logger/errors.rb9
-rw-r--r--lib/logger/formatter.rb36
-rw-r--r--lib/logger/log_device.rb205
-rw-r--r--lib/logger/logger.gemspec29
-rw-r--r--lib/logger/period.rb47
-rw-r--r--lib/logger/severity.rb19
-rw-r--r--lib/logger/version.rb5
-rw-r--r--lib/matrix.rb924
-rw-r--r--lib/matrix/eigenvalue_decomposition.rb23
-rw-r--r--lib/matrix/lup_decomposition.rb8
-rw-r--r--lib/matrix/matrix.gemspec29
-rw-r--r--lib/matrix/version.rb5
-rw-r--r--lib/mkmf.rb161
-rw-r--r--lib/monitor.rb315
-rw-r--r--lib/mutex_m.gemspec27
-rw-r--r--lib/mutex_m.rb10
-rw-r--r--lib/net/ftp.rb203
-rw-r--r--lib/net/http.rb204
-rw-r--r--lib/net/http/exceptions.rb7
-rw-r--r--lib/net/http/generic_request.rb17
-rw-r--r--lib/net/http/header.rb104
-rw-r--r--lib/net/http/net-http.gemspec36
-rw-r--r--lib/net/http/response.rb24
-rw-r--r--lib/net/http/responses.rb34
-rw-r--r--lib/net/http/status.rb4
-rw-r--r--lib/net/https.rb2
-rw-r--r--lib/net/imap.rb64
-rw-r--r--lib/net/net-ftp.gemspec36
-rw-r--r--lib/net/net-imap.gemspec37
-rw-r--r--lib/net/net-pop.gemspec34
-rw-r--r--lib/net/net-protocol.gemspec36
-rw-r--r--lib/net/net-smtp.gemspec35
-rw-r--r--lib/net/pop.rb20
-rw-r--r--lib/net/protocol.rb104
-rw-r--r--lib/net/smtp.rb124
-rw-r--r--lib/observer.rb27
-rw-r--r--lib/observer/observer.gemspec32
-rw-r--r--lib/open-uri.gemspec26
-rw-r--r--lib/open-uri.rb46
-rw-r--r--lib/open3.gemspec33
-rw-r--r--lib/open3.rb131
-rw-r--r--lib/optparse.rb213
-rw-r--r--lib/optparse/ac.rb7
-rw-r--r--lib/optparse/kwargs.rb3
-rw-r--r--lib/optparse/optparse.gemspec33
-rw-r--r--lib/ostruct.rb254
-rw-r--r--lib/ostruct/ostruct.gemspec29
-rw-r--r--lib/pp.gemspec27
-rw-r--r--lib/pp.rb139
-rw-r--r--lib/prettyprint.gemspec22
-rw-r--r--lib/prettyprint.rb6
-rw-r--r--lib/prime.gemspec28
-rw-r--r--lib/prime.rb152
-rw-r--r--lib/profile.rb11
-rw-r--r--lib/profiler.rb149
-rw-r--r--lib/pstore.rb8
-rw-r--r--lib/pstore/pstore.gemspec32
-rw-r--r--lib/racc.rb6
-rw-r--r--lib/racc/compat.rb33
-rw-r--r--lib/racc/debugflags.rb60
-rw-r--r--lib/racc/exception.rb16
-rw-r--r--lib/racc/grammar.rb1118
-rw-r--r--lib/racc/grammarfileparser.rb561
-rw-r--r--lib/racc/info.rb17
-rw-r--r--lib/racc/iset.rb92
-rw-r--r--lib/racc/logfilegenerator.rb212
-rw-r--r--lib/racc/parser-text.rb637
-rw-r--r--lib/racc/parser.rb81
-rw-r--r--lib/racc/parserfilegenerator.rb512
-rw-r--r--lib/racc/pre-setup13
-rw-r--r--lib/racc/racc.gemspec107
-rw-r--r--lib/racc/rdoc/grammar.en.rdoc2
-rw-r--r--lib/racc/sourcetext.rb35
-rw-r--r--lib/racc/state.rb972
-rw-r--r--lib/racc/statetransitiontable.rb317
-rw-r--r--lib/racc/static.rb5
-rw-r--r--lib/rdoc.rb33
-rw-r--r--lib/rdoc/.document1
-rw-r--r--lib/rdoc/alias.rb2
-rw-r--r--lib/rdoc/anon_class.rb2
-rw-r--r--lib/rdoc/any_method.rb73
-rw-r--r--lib/rdoc/attr.rb2
-rw-r--r--lib/rdoc/class_module.rb8
-rw-r--r--lib/rdoc/code_object.rb4
-rw-r--r--lib/rdoc/code_objects.rb2
-rw-r--r--lib/rdoc/comment.rb43
-rw-r--r--lib/rdoc/constant.rb2
-rw-r--r--lib/rdoc/context.rb69
-rw-r--r--lib/rdoc/context/section.rb15
-rw-r--r--lib/rdoc/cross_reference.rb48
-rw-r--r--lib/rdoc/encoding.rb88
-rw-r--r--lib/rdoc/erb_partial.rb4
-rw-r--r--lib/rdoc/erbio.rb12
-rw-r--r--lib/rdoc/extend.rb2
-rw-r--r--lib/rdoc/generator.rb2
-rw-r--r--lib/rdoc/generator/darkfish.rb89
-rw-r--r--lib/rdoc/generator/json_index.rb9
-rw-r--r--lib/rdoc/generator/markup.rb16
-rw-r--r--lib/rdoc/generator/pot.rb8
-rw-r--r--lib/rdoc/generator/pot/message_extractor.rb2
-rw-r--r--lib/rdoc/generator/pot/po.rb6
-rw-r--r--lib/rdoc/generator/pot/po_entry.rb22
-rw-r--r--lib/rdoc/generator/ri.rb2
-rw-r--r--lib/rdoc/generator/template/darkfish/_head.rhtml16
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml4
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml4
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml14
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml4
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml14
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml12
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml10
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml10
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml10
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml8
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml8
-rw-r--r--lib/rdoc/generator/template/darkfish/class.rhtml88
-rw-r--r--lib/rdoc/generator/template/darkfish/css/rdoc.css61
-rw-r--r--lib/rdoc/generator/template/darkfish/index.rhtml7
-rw-r--r--lib/rdoc/generator/template/darkfish/js/darkfish.js121
-rw-r--r--lib/rdoc/generator/template/darkfish/js/jquery.js4
-rw-r--r--lib/rdoc/generator/template/darkfish/js/search.js63
-rw-r--r--lib/rdoc/generator/template/darkfish/servlet_root.rhtml31
-rw-r--r--lib/rdoc/generator/template/darkfish/table_of_contents.rhtml32
-rw-r--r--lib/rdoc/generator/template/json_index/js/navigation.js45
-rw-r--r--lib/rdoc/generator/template/json_index/js/searcher.js12
-rw-r--r--lib/rdoc/ghost_method.rb2
-rw-r--r--lib/rdoc/i18n.rb4
-rw-r--r--lib/rdoc/i18n/locale.rb2
-rw-r--r--lib/rdoc/i18n/text.rb10
-rw-r--r--lib/rdoc/include.rb2
-rw-r--r--lib/rdoc/known_classes.rb2
-rw-r--r--lib/rdoc/markdown.rb1824
-rw-r--r--lib/rdoc/markdown/entities.rb2
-rw-r--r--lib/rdoc/markdown/literals.rb41
-rw-r--r--lib/rdoc/markup.rb27
-rw-r--r--lib/rdoc/markup/attr_changer.rb2
-rw-r--r--lib/rdoc/markup/attr_span.rb12
-rw-r--r--lib/rdoc/markup/attribute_manager.rb165
-rw-r--r--lib/rdoc/markup/attributes.rb14
-rw-r--r--lib/rdoc/markup/blank_line.rb2
-rw-r--r--lib/rdoc/markup/block_quote.rb2
-rw-r--r--lib/rdoc/markup/document.rb2
-rw-r--r--lib/rdoc/markup/formatter.rb49
-rw-r--r--lib/rdoc/markup/formatter_test_case.rb764
-rw-r--r--lib/rdoc/markup/hard_break.rb2
-rw-r--r--lib/rdoc/markup/heading.rb8
-rw-r--r--lib/rdoc/markup/include.rb2
-rw-r--r--lib/rdoc/markup/indented_paragraph.rb2
-rw-r--r--lib/rdoc/markup/inline.rb2
-rw-r--r--lib/rdoc/markup/list.rb2
-rw-r--r--lib/rdoc/markup/list_item.rb2
-rw-r--r--lib/rdoc/markup/paragraph.rb2
-rw-r--r--lib/rdoc/markup/parser.rb126
-rw-r--r--lib/rdoc/markup/pre_process.rb17
-rw-r--r--lib/rdoc/markup/raw.rb2
-rw-r--r--lib/rdoc/markup/regexp_handling.rb41
-rw-r--r--lib/rdoc/markup/rule.rb2
-rw-r--r--lib/rdoc/markup/special.rb41
-rw-r--r--lib/rdoc/markup/table.rb47
-rw-r--r--lib/rdoc/markup/text_formatter_test_case.rb115
-rw-r--r--lib/rdoc/markup/to_ansi.rb2
-rw-r--r--lib/rdoc/markup/to_bs.rb8
-rw-r--r--lib/rdoc/markup/to_html.rb86
-rw-r--r--lib/rdoc/markup/to_html_crossref.rb67
-rw-r--r--lib/rdoc/markup/to_html_snippet.rb20
-rw-r--r--lib/rdoc/markup/to_joined_paragraph.rb39
-rw-r--r--lib/rdoc/markup/to_label.rb20
-rw-r--r--lib/rdoc/markup/to_markdown.rb18
-rw-r--r--lib/rdoc/markup/to_rdoc.rb42
-rw-r--r--lib/rdoc/markup/to_table_of_contents.rb3
-rw-r--r--lib/rdoc/markup/to_test.rb2
-rw-r--r--lib/rdoc/markup/to_tt_only.rb6
-rw-r--r--lib/rdoc/markup/verbatim.rb2
-rw-r--r--lib/rdoc/meta_method.rb2
-rw-r--r--lib/rdoc/method_attr.rb4
-rw-r--r--lib/rdoc/mixin.rb2
-rw-r--r--lib/rdoc/normal_class.rb6
-rw-r--r--lib/rdoc/normal_module.rb2
-rw-r--r--lib/rdoc/options.rb100
-rw-r--r--lib/rdoc/parser.rb18
-rw-r--r--lib/rdoc/parser/c.rb333
-rw-r--r--lib/rdoc/parser/changelog.rb169
-rw-r--r--lib/rdoc/parser/markdown.rb2
-rw-r--r--lib/rdoc/parser/rd.rb2
-rw-r--r--lib/rdoc/parser/ripper_state_lex.rb177
-rw-r--r--lib/rdoc/parser/ruby.rb356
-rw-r--r--lib/rdoc/parser/ruby_tools.rb27
-rw-r--r--lib/rdoc/parser/simple.rb6
-rw-r--r--lib/rdoc/parser/text.rb2
-rw-r--r--lib/rdoc/rd.rb2
-rw-r--r--lib/rdoc/rd/block_parser.rb95
-rw-r--r--lib/rdoc/rd/inline.rb10
-rw-r--r--lib/rdoc/rd/inline_parser.rb275
-rw-r--r--lib/rdoc/rdoc.gemspec212
-rw-r--r--lib/rdoc/rdoc.rb98
-rw-r--r--lib/rdoc/require.rb2
-rw-r--r--lib/rdoc/ri.rb2
-rw-r--r--lib/rdoc/ri/driver.rb51
-rw-r--r--lib/rdoc/ri/formatter.rb2
-rw-r--r--lib/rdoc/ri/paths.rb22
-rw-r--r--lib/rdoc/ri/store.rb2
-rw-r--r--lib/rdoc/ri/task.rb4
-rw-r--r--lib/rdoc/rubygems_hook.rb6
-rw-r--r--lib/rdoc/servlet.rb31
-rw-r--r--lib/rdoc/single_class.rb2
-rw-r--r--lib/rdoc/stats.rb2
-rw-r--r--lib/rdoc/stats/normal.rb36
-rw-r--r--lib/rdoc/stats/quiet.rb2
-rw-r--r--lib/rdoc/stats/verbose.rb2
-rw-r--r--lib/rdoc/store.rb102
-rw-r--r--lib/rdoc/task.rb4
-rw-r--r--lib/rdoc/test_case.rb204
-rw-r--r--lib/rdoc/text.rb26
-rw-r--r--lib/rdoc/token_stream.rb35
-rw-r--r--lib/rdoc/tom_doc.rb29
-rw-r--r--lib/rdoc/top_level.rb12
-rw-r--r--lib/rdoc/version.rb8
-rw-r--r--lib/readline.gemspec35
-rw-r--r--lib/readline.rb6
-rw-r--r--lib/reline.rb471
-rw-r--r--lib/reline/ansi.rb259
-rw-r--r--lib/reline/config.rb347
-rw-r--r--lib/reline/general_io.rb93
-rw-r--r--lib/reline/history.rb76
-rw-r--r--lib/reline/key_actor.rb7
-rw-r--r--lib/reline/key_actor/base.rb7
-rw-r--r--lib/reline/key_actor/emacs.rb517
-rw-r--r--lib/reline/key_actor/vi_command.rb518
-rw-r--r--lib/reline/key_actor/vi_insert.rb517
-rw-r--r--lib/reline/key_stroke.rb55
-rw-r--r--lib/reline/kill_ring.rb125
-rw-r--r--lib/reline/line_editor.rb2781
-rw-r--r--lib/reline/reline.gemspec27
-rw-r--r--lib/reline/unicode.rb626
-rw-r--r--lib/reline/unicode/east_asian_width.rb1164
-rw-r--r--lib/reline/version.rb3
-rw-r--r--lib/reline/windows.rb328
-rw-r--r--lib/resolv-replace.gemspec24
-rw-r--r--lib/resolv.gemspec22
-rw-r--r--lib/resolv.rb188
-rw-r--r--lib/rexml/attlistdecl.rb63
-rw-r--r--lib/rexml/attribute.rb192
-rw-r--r--lib/rexml/cdata.rb68
-rw-r--r--lib/rexml/child.rb97
-rw-r--r--lib/rexml/comment.rb80
-rw-r--r--lib/rexml/doctype.rb270
-rw-r--r--lib/rexml/document.rb291
-rw-r--r--lib/rexml/dtd/attlistdecl.rb11
-rw-r--r--lib/rexml/dtd/dtd.rb47
-rw-r--r--lib/rexml/dtd/elementdecl.rb18
-rw-r--r--lib/rexml/dtd/entitydecl.rb57
-rw-r--r--lib/rexml/dtd/notationdecl.rb40
-rw-r--r--lib/rexml/element.rb1265
-rw-r--r--lib/rexml/encoding.rb51
-rw-r--r--lib/rexml/entity.rb172
-rw-r--r--lib/rexml/formatters/default.rb112
-rw-r--r--lib/rexml/formatters/pretty.rb142
-rw-r--r--lib/rexml/formatters/transitive.rb58
-rw-r--r--lib/rexml/functions.rb421
-rw-r--r--lib/rexml/instruction.rb71
-rw-r--r--lib/rexml/light/node.rb196
-rw-r--r--lib/rexml/namespace.rb48
-rw-r--r--lib/rexml/node.rb76
-rw-r--r--lib/rexml/output.rb30
-rw-r--r--lib/rexml/parent.rb166
-rw-r--r--lib/rexml/parseexception.rb52
-rw-r--r--lib/rexml/parsers/baseparser.rb533
-rw-r--r--lib/rexml/parsers/lightparser.rb59
-rw-r--r--lib/rexml/parsers/pullparser.rb197
-rw-r--r--lib/rexml/parsers/sax2parser.rb273
-rw-r--r--lib/rexml/parsers/streamparser.rb61
-rw-r--r--lib/rexml/parsers/treeparser.rb101
-rw-r--r--lib/rexml/parsers/ultralightparser.rb57
-rw-r--r--lib/rexml/parsers/xpathparser.rb657
-rw-r--r--lib/rexml/quickpath.rb266
-rw-r--r--lib/rexml/rexml.rb32
-rw-r--r--lib/rexml/sax2listener.rb98
-rw-r--r--lib/rexml/security.rb28
-rw-r--r--lib/rexml/source.rb297
-rw-r--r--lib/rexml/streamlistener.rb93
-rw-r--r--lib/rexml/syncenumerator.rb33
-rw-r--r--lib/rexml/text.rb426
-rw-r--r--lib/rexml/undefinednamespaceexception.rb9
-rw-r--r--lib/rexml/validation/relaxng.rb539
-rw-r--r--lib/rexml/validation/validation.rb144
-rw-r--r--lib/rexml/validation/validationexception.rb10
-rw-r--r--lib/rexml/xmldecl.rb116
-rw-r--r--lib/rexml/xmltokens.rb85
-rw-r--r--lib/rexml/xpath.rb81
-rw-r--r--lib/rexml/xpath_parser.rb704
-rw-r--r--lib/rinda/rinda.gemspec28
-rw-r--r--lib/rinda/ring.rb2
-rw-r--r--lib/rinda/tuplespace.rb2
-rw-r--r--lib/rss.rb92
-rw-r--r--lib/rss/0.9.rb462
-rw-r--r--lib/rss/1.0.rb485
-rw-r--r--lib/rss/2.0.rb143
-rw-r--r--lib/rss/atom.rb1025
-rw-r--r--lib/rss/content.rb34
-rw-r--r--lib/rss/content/1.0.rb10
-rw-r--r--lib/rss/content/2.0.rb12
-rw-r--r--lib/rss/converter.rb171
-rw-r--r--lib/rss/dublincore.rb164
-rw-r--r--lib/rss/dublincore/1.0.rb13
-rw-r--r--lib/rss/dublincore/2.0.rb13
-rw-r--r--lib/rss/dublincore/atom.rb17
-rw-r--r--lib/rss/image.rb198
-rw-r--r--lib/rss/itunes.rb413
-rw-r--r--lib/rss/maker.rb79
-rw-r--r--lib/rss/maker/0.9.rb509
-rw-r--r--lib/rss/maker/1.0.rb436
-rw-r--r--lib/rss/maker/2.0.rb224
-rw-r--r--lib/rss/maker/atom.rb173
-rw-r--r--lib/rss/maker/base.rb945
-rw-r--r--lib/rss/maker/content.rb22
-rw-r--r--lib/rss/maker/dublincore.rb122
-rw-r--r--lib/rss/maker/entry.rb164
-rw-r--r--lib/rss/maker/feed.rb427
-rw-r--r--lib/rss/maker/image.rb112
-rw-r--r--lib/rss/maker/itunes.rb243
-rw-r--r--lib/rss/maker/slash.rb34
-rw-r--r--lib/rss/maker/syndication.rb19
-rw-r--r--lib/rss/maker/taxonomy.rb119
-rw-r--r--lib/rss/maker/trackback.rb62
-rw-r--r--lib/rss/parser.rb571
-rw-r--r--lib/rss/rexmlparser.rb50
-rw-r--r--lib/rss/rss.rb1347
-rw-r--r--lib/rss/slash.rb52
-rw-r--r--lib/rss/syndication.rb69
-rw-r--r--lib/rss/taxonomy.rb148
-rw-r--r--lib/rss/trackback.rb291
-rw-r--r--lib/rss/utils.rb200
-rw-r--r--lib/rss/xml-stylesheet.rb106
-rw-r--r--lib/rss/xml.rb72
-rw-r--r--lib/rss/xmlparser.rb95
-rw-r--r--lib/rss/xmlscanner.rb122
-rw-r--r--lib/rubygems.rb628
-rw-r--r--lib/rubygems/available_set.rb11
-rw-r--r--lib/rubygems/basic_specification.rb81
-rw-r--r--lib/rubygems/bundler_version_finder.rb57
-rw-r--r--lib/rubygems/command.rb141
-rw-r--r--lib/rubygems/command_manager.rb46
-rw-r--r--lib/rubygems/commands/build_command.rb97
-rw-r--r--lib/rubygems/commands/cert_command.rb165
-rw-r--r--lib/rubygems/commands/check_command.rb12
-rw-r--r--lib/rubygems/commands/cleanup_command.rb68
-rw-r--r--lib/rubygems/commands/contents_command.rb49
-rw-r--r--lib/rubygems/commands/dependency_command.rb57
-rw-r--r--lib/rubygems/commands/environment_command.rb28
-rw-r--r--lib/rubygems/commands/fetch_command.rb17
-rw-r--r--lib/rubygems/commands/generate_index_command.rb16
-rw-r--r--lib/rubygems/commands/help_command.rb35
-rw-r--r--lib/rubygems/commands/info_command.rb38
-rw-r--r--lib/rubygems/commands/install_command.rb124
-rw-r--r--lib/rubygems/commands/list_command.rb18
-rw-r--r--lib/rubygems/commands/lock_command.rb17
-rw-r--r--lib/rubygems/commands/mirror_command.rb3
-rw-r--r--lib/rubygems/commands/open_command.rb35
-rw-r--r--lib/rubygems/commands/outdated_command.rb9
-rw-r--r--lib/rubygems/commands/owner_command.rb45
-rw-r--r--lib/rubygems/commands/pristine_command.rb73
-rw-r--r--lib/rubygems/commands/push_command.rb93
-rw-r--r--lib/rubygems/commands/query_command.rb346
-rw-r--r--lib/rubygems/commands/rdoc_command.rb14
-rw-r--r--lib/rubygems/commands/search_command.rb17
-rw-r--r--lib/rubygems/commands/server_command.rb17
-rw-r--r--lib/rubygems/commands/setup_command.rb442
-rw-r--r--lib/rubygems/commands/signin_command.rb8
-rw-r--r--lib/rubygems/commands/signout_command.rb8
-rw-r--r--lib/rubygems/commands/sources_command.rb59
-rw-r--r--lib/rubygems/commands/specification_command.rb33
-rw-r--r--lib/rubygems/commands/stale_command.rb4
-rw-r--r--lib/rubygems/commands/uninstall_command.rb83
-rw-r--r--lib/rubygems/commands/unpack_command.rb64
-rw-r--r--lib/rubygems/commands/update_command.rb178
-rw-r--r--lib/rubygems/commands/which_command.rb16
-rw-r--r--lib/rubygems/commands/yank_command.rb30
-rw-r--r--lib/rubygems/compatibility.rb30
-rw-r--r--lib/rubygems/config_file.rb147
-rw-r--r--lib/rubygems/core_ext/kernel_gem.rb13
-rw-r--r--[-rwxr-xr-x]lib/rubygems/core_ext/kernel_require.rb69
-rw-r--r--lib/rubygems/core_ext/kernel_warn.rb54
-rw-r--r--lib/rubygems/core_ext/tcpsocket_init.rb52
-rw-r--r--lib/rubygems/defaults.rb175
-rw-r--r--lib/rubygems/dependency.rb69
-rw-r--r--lib/rubygems/dependency_installer.rb232
-rw-r--r--lib/rubygems/dependency_list.rb58
-rw-r--r--lib/rubygems/deprecate.rb64
-rw-r--r--lib/rubygems/doctor.rb23
-rw-r--r--lib/rubygems/errors.rb19
-rw-r--r--lib/rubygems/exceptions.rb46
-rw-r--r--lib/rubygems/ext.rb13
-rw-r--r--lib/rubygems/ext/build_error.rb3
-rw-r--r--lib/rubygems/ext/builder.rb124
-rw-r--r--lib/rubygems/ext/cmake_builder.rb13
-rw-r--r--lib/rubygems/ext/configure_builder.rb14
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb62
-rw-r--r--lib/rubygems/ext/rake_builder.rb35
-rw-r--r--lib/rubygems/gem_runner.rb23
-rw-r--r--lib/rubygems/gemcutter_utilities.rb183
-rw-r--r--lib/rubygems/indexer.rb61
-rw-r--r--lib/rubygems/install_default_message.rb5
-rw-r--r--lib/rubygems/install_message.rb5
-rw-r--r--lib/rubygems/install_update_options.rb52
-rw-r--r--lib/rubygems/installer.rb411
-rw-r--r--lib/rubygems/installer_test_case.rb199
-rw-r--r--lib/rubygems/installer_uninstaller_utils.rb29
-rw-r--r--lib/rubygems/local_remote_options.rb17
-rw-r--r--lib/rubygems/mock_gem_ui.rb14
-rw-r--r--lib/rubygems/name_tuple.rb19
-rw-r--r--lib/rubygems/openssl.rb7
-rw-r--r--lib/rubygems/optparse.rb3
-rw-r--r--lib/rubygems/optparse/.document1
-rw-r--r--lib/rubygems/optparse/COPYING56
-rw-r--r--lib/rubygems/optparse/lib/optionparser.rb2
-rw-r--r--lib/rubygems/optparse/lib/optparse.rb2230
-rw-r--r--lib/rubygems/optparse/lib/optparse/ac.rb54
-rw-r--r--lib/rubygems/optparse/lib/optparse/date.rb18
-rw-r--r--lib/rubygems/optparse/lib/optparse/kwargs.rb22
-rw-r--r--lib/rubygems/optparse/lib/optparse/shellwords.rb7
-rw-r--r--lib/rubygems/optparse/lib/optparse/time.rb11
-rw-r--r--lib/rubygems/optparse/lib/optparse/uri.rb7
-rw-r--r--lib/rubygems/optparse/lib/optparse/version.rb71
-rw-r--r--lib/rubygems/package.rb264
-rw-r--r--lib/rubygems/package/digest_io.rb9
-rw-r--r--lib/rubygems/package/file_source.rb13
-rw-r--r--lib/rubygems/package/io_source.rb9
-rw-r--r--lib/rubygems/package/old.rb28
-rw-r--r--lib/rubygems/package/source.rb1
-rw-r--r--lib/rubygems/package/tar_header.rb48
-rw-r--r--lib/rubygems/package/tar_reader.rb35
-rw-r--r--lib/rubygems/package/tar_reader/entry.rb27
-rw-r--r--lib/rubygems/package/tar_test_case.rb147
-rw-r--r--lib/rubygems/package/tar_writer.rb49
-rw-r--r--lib/rubygems/package_task.rb13
-rw-r--r--lib/rubygems/path_support.rb24
-rw-r--r--lib/rubygems/platform.rb46
-rw-r--r--lib/rubygems/psych_tree.rb2
-rw-r--r--lib/rubygems/query_utils.rb353
-rw-r--r--lib/rubygems/rdoc.rb329
-rw-r--r--lib/rubygems/remote_fetcher.rb202
-rw-r--r--lib/rubygems/request.rb70
-rw-r--r--lib/rubygems/request/connection_pools.rb49
-rw-r--r--lib/rubygems/request/http_pool.rb10
-rw-r--r--lib/rubygems/request/https_pool.rb4
-rw-r--r--lib/rubygems/request_set.rb153
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb113
-rw-r--r--lib/rubygems/request_set/lockfile.rb53
-rw-r--r--lib/rubygems/request_set/lockfile/parser.rb47
-rw-r--r--lib/rubygems/request_set/lockfile/tokenizer.rb22
-rw-r--r--lib/rubygems/requirement.rb122
-rw-r--r--lib/rubygems/resolver.rb123
-rw-r--r--lib/rubygems/resolver/activation_request.rb84
-rw-r--r--lib/rubygems/resolver/api_set.rb64
-rw-r--r--lib/rubygems/resolver/api_set/gem_parser.rb20
-rw-r--r--lib/rubygems/resolver/api_specification.rb42
-rw-r--r--lib/rubygems/resolver/best_set.rb21
-rw-r--r--lib/rubygems/resolver/composed_set.rb19
-rw-r--r--lib/rubygems/resolver/conflict.rb21
-rw-r--r--lib/rubygems/resolver/current_set.rb5
-rw-r--r--lib/rubygems/resolver/dependency_request.rb12
-rw-r--r--lib/rubygems/resolver/git_set.rb13
-rw-r--r--lib/rubygems/resolver/git_specification.rb13
-rw-r--r--lib/rubygems/resolver/index_set.rb15
-rw-r--r--lib/rubygems/resolver/index_specification.rb41
-rw-r--r--lib/rubygems/resolver/installed_specification.rb9
-rw-r--r--lib/rubygems/resolver/installer_set.rb101
-rw-r--r--lib/rubygems/resolver/local_specification.rb5
-rw-r--r--lib/rubygems/resolver/lock_set.rb19
-rw-r--r--lib/rubygems/resolver/lock_specification.rb21
-rw-r--r--lib/rubygems/resolver/molinillo.rb2
-rw-r--r--lib/rubygems/resolver/molinillo/LICENSE9
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo.rb11
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb8
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb49
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb1
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb13
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb63
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb84
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb14
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb4
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb675
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb5
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/state.rb12
-rw-r--r--lib/rubygems/resolver/requirement_list.rb3
-rw-r--r--lib/rubygems/resolver/set.rb7
-rw-r--r--lib/rubygems/resolver/source_set.rb11
-rw-r--r--lib/rubygems/resolver/spec_specification.rb19
-rw-r--r--lib/rubygems/resolver/specification.rb34
-rw-r--r--lib/rubygems/resolver/stats.rb2
-rw-r--r--lib/rubygems/resolver/vendor_set.rb11
-rw-r--r--lib/rubygems/resolver/vendor_specification.rb7
-rw-r--r--lib/rubygems/s3_uri_signer.rb175
-rw-r--r--lib/rubygems/safe_yaml.rb35
-rw-r--r--lib/rubygems/security.rb157
-rw-r--r--lib/rubygems/security/policies.rb3
-rw-r--r--lib/rubygems/security/policy.rb70
-rw-r--r--lib/rubygems/security/signer.rb104
-rw-r--r--lib/rubygems/security/trust_dir.rb25
-rw-r--r--lib/rubygems/security_option.rb11
-rw-r--r--lib/rubygems/server.rb102
-rw-r--r--lib/rubygems/source.rb92
-rw-r--r--lib/rubygems/source/git.rb36
-rw-r--r--lib/rubygems/source/installed.rb9
-rw-r--r--lib/rubygems/source/local.rb20
-rw-r--r--lib/rubygems/source/lock.rb10
-rw-r--r--lib/rubygems/source/specific_file.rb12
-rw-r--r--lib/rubygems/source/vendor.rb7
-rw-r--r--lib/rubygems/source_list.rb16
-rw-r--r--lib/rubygems/source_local.rb8
-rw-r--r--lib/rubygems/source_specific_file.rb6
-rw-r--r--lib/rubygems/spec_fetcher.rb75
-rw-r--r--lib/rubygems/specification.rb1242
-rw-r--r--lib/rubygems/specification_policy.rb486
-rw-r--r--lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem21
-rw-r--r--lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem23
-rw-r--r--lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem25
-rw-r--r--lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem (renamed from lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem)0
-rw-r--r--lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem21
-rw-r--r--lib/rubygems/stub_specification.rb38
-rw-r--r--lib/rubygems/syck_hack.rb77
-rw-r--r--lib/rubygems/test_case.rb1529
-rw-r--r--lib/rubygems/test_utilities.rb384
-rw-r--r--lib/rubygems/text.rb17
-rw-r--r--lib/rubygems/tsort.rb3
-rw-r--r--lib/rubygems/tsort/.document1
-rw-r--r--lib/rubygems/tsort/LICENSE.txt22
-rw-r--r--lib/rubygems/tsort/lib/tsort.rb454
-rw-r--r--lib/rubygems/uninstaller.rb187
-rw-r--r--lib/rubygems/uri.rb111
-rw-r--r--lib/rubygems/uri_formatter.rb9
-rw-r--r--lib/rubygems/user_interaction.rb150
-rw-r--r--lib/rubygems/util.rb105
-rw-r--r--lib/rubygems/util/licenses.rb827
-rw-r--r--lib/rubygems/util/list.rb2
-rw-r--r--lib/rubygems/validator.rb57
-rw-r--r--lib/rubygems/version.rb86
-rw-r--r--lib/rubygems/version_option.rb17
-rw-r--r--lib/scanf.gemspec25
-rw-r--r--lib/scanf.rb776
-rw-r--r--lib/securerandom.gemspec22
-rw-r--r--lib/securerandom.rb194
-rw-r--r--lib/set.rb517
-rw-r--r--lib/set/set.gemspec25
-rw-r--r--lib/set/sorted_set.rb6
-rw-r--r--lib/shell.rb461
-rw-r--r--lib/shell/builtin-command.rb147
-rw-r--r--lib/shell/command-processor.rb668
-rw-r--r--lib/shell/error.rb26
-rw-r--r--lib/shell/filter.rb138
-rw-r--r--lib/shell/process-controller.rb309
-rw-r--r--lib/shell/system-command.rb159
-rw-r--r--lib/shell/version.rb16
-rw-r--r--lib/shellwords.gemspec22
-rw-r--r--lib/shellwords.rb41
-rw-r--r--lib/singleton.rb33
-rw-r--r--lib/singleton/singleton.gemspec30
-rw-r--r--lib/sync.rb329
-rw-r--r--lib/tempfile.gemspec24
-rw-r--r--lib/tempfile.rb95
-rw-r--r--lib/thwait.rb140
-rw-r--r--lib/time.gemspec22
-rw-r--r--lib/time.rb261
-rw-r--r--lib/timeout.rb12
-rw-r--r--lib/timeout/timeout.gemspec30
-rw-r--r--lib/tmpdir.gemspec26
-rw-r--r--lib/tmpdir.rb88
-rw-r--r--lib/tracer.rb16
-rw-r--r--lib/tracer/tracer.gemspec25
-rw-r--r--lib/tsort.gemspec22
-rw-r--r--lib/un.gemspec23
-rw-r--r--lib/un.rb33
-rw-r--r--lib/unicode_normalize/normalize.rb4
-rw-r--r--lib/unicode_normalize/tables.rb10113
-rw-r--r--lib/uri.rb69
-rw-r--r--lib/uri/common.rb221
-rw-r--r--lib/uri/file.rb94
-rw-r--r--lib/uri/ftp.rb65
-rw-r--r--lib/uri/generic.rb382
-rw-r--r--lib/uri/http.rb23
-rw-r--r--lib/uri/https.rb3
-rw-r--r--lib/uri/ldap.rb82
-rw-r--r--lib/uri/ldaps.rb2
-rw-r--r--lib/uri/mailto.rb41
-rw-r--r--lib/uri/rfc2396_parser.rb71
-rw-r--r--lib/uri/rfc3986_parser.rb25
-rw-r--r--lib/uri/uri.gemspec29
-rw-r--r--lib/uri/version.rb6
-rw-r--r--lib/uri/ws.rb84
-rw-r--r--lib/uri/wss.rb22
-rw-r--r--lib/weakref.rb48
-rw-r--r--lib/weakref/weakref.gemspec34
-rw-r--r--lib/webrick.rb227
-rw-r--r--lib/webrick/accesslog.rb159
-rw-r--r--lib/webrick/cgi.rb309
-rw-r--r--lib/webrick/config.rb158
-rw-r--r--lib/webrick/cookie.rb172
-rw-r--r--lib/webrick/httpauth.rb96
-rw-r--r--lib/webrick/httpauth/authenticator.rb117
-rw-r--r--lib/webrick/httpauth/basicauth.rb108
-rw-r--r--lib/webrick/httpauth/digestauth.rb408
-rw-r--r--lib/webrick/httpauth/htdigest.rb132
-rw-r--r--lib/webrick/httpauth/htgroup.rb94
-rw-r--r--lib/webrick/httpauth/htpasswd.rb125
-rw-r--r--lib/webrick/httpproxy.rb338
-rw-r--r--lib/webrick/httprequest.rb587
-rw-r--r--lib/webrick/httpresponse.rb471
-rw-r--r--lib/webrick/https.rb152
-rw-r--r--lib/webrick/httpserver.rb280
-rw-r--r--lib/webrick/httpservlet.rb23
-rw-r--r--lib/webrick/httpservlet/abstract.rb152
-rw-r--r--lib/webrick/httpservlet/cgi_runner.rb47
-rw-r--r--lib/webrick/httpservlet/cgihandler.rb122
-rw-r--r--lib/webrick/httpservlet/erbhandler.rb88
-rw-r--r--lib/webrick/httpservlet/filehandler.rb522
-rw-r--r--lib/webrick/httpservlet/prochandler.rb47
-rw-r--r--lib/webrick/httpstatus.rb194
-rw-r--r--lib/webrick/httputils.rb511
-rw-r--r--lib/webrick/log.rb156
-rw-r--r--lib/webrick/server.rb359
-rw-r--r--lib/webrick/ssl.rb215
-rw-r--r--lib/webrick/utils.rb270
-rw-r--r--lib/webrick/version.rb18
-rw-r--r--lib/webrick/webrick.gemspec30
-rw-r--r--lib/yaml.rb19
-rw-r--r--lib/yaml/yaml.gemspec23
-rwxr-xr-xlibexec/bundle50
-rwxr-xr-xlibexec/bundler4
-rwxr-xr-xlibexec/erb174
-rwxr-xr-xlibexec/irb11
-rwxr-xr-xlibexec/racc320
-rwxr-xr-xlibexec/rdoc44
-rwxr-xr-xlibexec/ri12
-rw-r--r--load.c532
-rw-r--r--loadpath.c1
-rw-r--r--localeinit.c6
-rw-r--r--main.c8
-rw-r--r--man/erb.19
-rw-r--r--man/goruby.12
-rw-r--r--man/index.txt25
-rw-r--r--man/irb.163
-rw-r--r--man/ruby.119
-rw-r--r--marshal.c441
-rw-r--r--math.c60
-rw-r--r--memory_view.c869
-rw-r--r--method.h114
-rw-r--r--mini_builtin.c84
-rw-r--r--miniinit.c2
-rw-r--r--misc/README18
-rwxr-xr-xmisc/expand_tabs.rb167
-rw-r--r--misc/inf-ruby.el418
-rwxr-xr-xmisc/lldb_cruby.py449
-rw-r--r--misc/lldb_disasm.py239
-rwxr-xr-xmisc/rb_optparse.zsh2
-rw-r--r--misc/rdoc-mode.el166
-rw-r--r--misc/ruby-additional.el181
-rw-r--r--misc/ruby-electric.el583
-rw-r--r--misc/ruby-mode.el1584
-rw-r--r--misc/ruby-style.el17
-rw-r--r--misc/rubydb2x.el104
-rw-r--r--misc/rubydb3x.el115
-rw-r--r--misc/test_lldb_cruby.rb8
-rw-r--r--missing/alloca.c2
-rw-r--r--missing/crypt.h7
-rw-r--r--missing/dtoa.c3470
-rw-r--r--missing/dup2.c2
-rw-r--r--missing/explicit_bzero.c12
-rw-r--r--missing/file.h3
-rw-r--r--missing/fileblocks.c1
-rw-r--r--missing/flock.c4
-rw-r--r--missing/isinf.c2
-rw-r--r--missing/memcmp.c3
-rw-r--r--missing/mt19937.c158
-rw-r--r--missing/nan.c28
-rw-r--r--missing/procstat_vm.c85
-rw-r--r--missing/setproctitle.c5
-rw-r--r--missing/tgamma.c2
-rw-r--r--missing/x86_64-chkstk.S (renamed from missing/x86_64-chkstk.s)0
-rw-r--r--mjit.c1023
-rw-r--r--mjit.h216
-rw-r--r--mjit_compile.c606
-rw-r--r--mjit_worker.c1528
-rw-r--r--nacl/GNUmakefile.in100
-rw-r--r--nacl/README.nacl51
-rw-r--r--nacl/create_nmf.rb70
-rw-r--r--nacl/dirent.h15
-rw-r--r--nacl/example.html150
-rwxr-xr-xnacl/nacl-config.rb61
-rw-r--r--nacl/package.rb113
-rw-r--r--nacl/pepper_main.c732
-rw-r--r--nacl/resource.h8
-rw-r--r--nacl/select.h7
-rw-r--r--nacl/signal.h6
-rw-r--r--nacl/stat.h10
-rw-r--r--nacl/unistd.h9
-rw-r--r--nacl/utime.h11
-rw-r--r--node.c1003
-rw-r--r--node.h513
-rw-r--r--numeric.c1042
-rw-r--r--object.c1827
-rw-r--r--pack.c437
-rw-r--r--pack.rb283
-rw-r--r--parse.y11142
-rw-r--r--prelude.rb151
-rw-r--r--probes.d11
-rw-r--r--probes_helper.h25
-rw-r--r--proc.c1791
-rw-r--r--process.c2171
-rw-r--r--ractor.c3257
-rw-r--r--ractor.rb838
-rw-r--r--ractor_core.h341
-rw-r--r--random.c905
-rw-r--r--range.c984
-rw-r--r--rational.c896
-rw-r--r--re.c516
-rw-r--r--regcomp.c56
-rw-r--r--regenc.h2
-rw-r--r--regerror.c7
-rw-r--r--regexec.c64
-rw-r--r--regint.h2
-rw-r--r--regparse.c1082
-rw-r--r--regparse.h2
-rw-r--r--ruby-runner.c21
-rw-r--r--ruby.c912
-rw-r--r--ruby_assert.h65
-rw-r--r--ruby_atomic.h256
-rw-r--r--safe.c128
-rw-r--r--sample/README2
-rw-r--r--sample/biorhythm.rb9
-rw-r--r--sample/dir.rb2
-rw-r--r--sample/drb/http0serv.rb8
-rw-r--r--sample/drb/name.rb3
-rw-r--r--sample/drb/old_tuplespace.rb2
-rw-r--r--sample/fact.rb4
-rw-r--r--sample/fib.py2
-rw-r--r--sample/freq.rb12
-rw-r--r--sample/iseq_loader.rb6
-rw-r--r--sample/list.rb5
-rw-r--r--sample/list3.rb2
-rw-r--r--sample/observ.rb2
-rw-r--r--sample/occur.rb2
-rw-r--r--sample/occur2.rb13
-rw-r--r--sample/openssl/c_rehash.rb2
-rw-r--r--sample/openssl/echo_svr.rb2
-rw-r--r--sample/openssl/gen_csr.rb2
-rw-r--r--sample/ripper/ruby2html.rb6
-rw-r--r--[-rwxr-xr-x]sample/test.rb0
-rw-r--r--sample/timeout.rb18
-rw-r--r--sample/trick2013/kinaba/remarks.markdown4
-rw-r--r--sample/trick2013/mame/music-box.mp4bin580724 -> 0 bytes-rw-r--r--sample/trick2013/mame/remarks.markdown4
-rw-r--r--sample/trick2013/yhara/entry.rb2
-rw-r--r--sample/trick2015/kinaba/entry.rb2
-rw-r--r--sample/trick2015/ksk_1/remarks.markdown2
-rw-r--r--sample/trick2015/ksk_2/remarks.markdown4
-rw-r--r--sample/trick2018/01-kinaba/authors.markdown3
-rw-r--r--sample/trick2018/01-kinaba/entry.rb8
-rw-r--r--sample/trick2018/01-kinaba/remarks.markdown55
-rw-r--r--sample/trick2018/02-mame/authors.markdown3
-rw-r--r--sample/trick2018/02-mame/entry.rb15
-rw-r--r--sample/trick2018/02-mame/remarks.markdown16
-rw-r--r--sample/trick2018/03-tompng/Gemfile2
-rw-r--r--sample/trick2018/03-tompng/Gemfile.lock13
-rw-r--r--sample/trick2018/03-tompng/authors.markdown3
-rw-r--r--sample/trick2018/03-tompng/entry.rb31
-rw-r--r--sample/trick2018/03-tompng/output.txt44
-rw-r--r--sample/trick2018/03-tompng/remarks.markdown19
-rw-r--r--sample/trick2018/03-tompng/trick.pngbin0 -> 5661 bytes-rw-r--r--sample/trick2018/04-colin/authors.markdown3
-rw-r--r--sample/trick2018/04-colin/entry.rb2
-rw-r--r--sample/trick2018/04-colin/remarks.markdown62
-rw-r--r--sample/trick2018/05-tompng/authors.markdown3
-rw-r--r--sample/trick2018/05-tompng/entry.rb41
-rw-r--r--sample/trick2018/05-tompng/preview_of_output.pngbin0 -> 66800 bytes-rw-r--r--sample/trick2018/05-tompng/remarks.markdown31
-rw-r--r--sample/trick2018/README.md16
-rw-r--r--sample/webrick/demo-app.rb66
-rw-r--r--sample/webrick/demo-multipart.cgi12
-rw-r--r--sample/webrick/demo-servlet.rb6
-rw-r--r--sample/webrick/demo-urlencoded.cgi12
-rw-r--r--sample/webrick/hello.cgi11
-rw-r--r--sample/webrick/hello.rb8
-rw-r--r--sample/webrick/httpd.rb23
-rw-r--r--sample/webrick/httpproxy.rb25
-rw-r--r--sample/webrick/httpsd.rb33
-rw-r--r--scheduler.c212
-rw-r--r--signal.c654
-rw-r--r--siphash.c2
-rw-r--r--siphash.h2
-rw-r--r--spec/README.md48
-rw-r--r--spec/bundler/bundler/build_metadata_spec.rb49
-rw-r--r--spec/bundler/bundler/bundler_spec.rb311
-rw-r--r--spec/bundler/bundler/cli_spec.rb163
-rw-r--r--spec/bundler/bundler/compact_index_client/updater_spec.rb53
-rw-r--r--spec/bundler/bundler/definition_spec.rb122
-rw-r--r--spec/bundler/bundler/dep_proxy_spec.rb32
-rw-r--r--spec/bundler/bundler/digest_spec.rb17
-rw-r--r--spec/bundler/bundler/dsl_spec.rb152
-rw-r--r--spec/bundler/bundler/endpoint_specification_spec.rb9
-rw-r--r--spec/bundler/bundler/env_spec.rb167
-rw-r--r--spec/bundler/bundler/environment_preserver_spec.rb5
-rw-r--r--spec/bundler/bundler/fetcher/base_spec.rb7
-rw-r--r--spec/bundler/bundler/fetcher/compact_index_spec.rb31
-rw-r--r--spec/bundler/bundler/fetcher/dependency_spec.rb19
-rw-r--r--spec/bundler/bundler/fetcher/downloader_spec.rb62
-rw-r--r--spec/bundler/bundler/fetcher/index_spec.rb103
-rw-r--r--spec/bundler/bundler/fetcher_spec.rb60
-rw-r--r--spec/bundler/bundler/friendly_errors_spec.rb58
-rw-r--r--spec/bundler/bundler/gem_helper_spec.rb267
-rw-r--r--spec/bundler/bundler/gem_version_promoter_spec.rb56
-rw-r--r--spec/bundler/bundler/index_spec.rb1
-rw-r--r--spec/bundler/bundler/installer/gem_installer_spec.rb18
-rw-r--r--spec/bundler/bundler/installer/parallel_installer_spec.rb35
-rw-r--r--spec/bundler/bundler/installer/spec_installation_spec.rb6
-rw-r--r--spec/bundler/bundler/lockfile_parser_spec.rb61
-rw-r--r--spec/bundler/bundler/mirror_spec.rb24
-rw-r--r--spec/bundler/bundler/plugin/api/source_spec.rb9
-rw-r--r--spec/bundler/bundler/plugin/api_spec.rb9
-rw-r--r--spec/bundler/bundler/plugin/dsl_spec.rb3
-rw-r--r--spec/bundler/bundler/plugin/events_spec.rb22
-rw-r--r--spec/bundler/bundler/plugin/index_spec.rb43
-rw-r--r--spec/bundler/bundler/plugin/installer_spec.rb45
-rw-r--r--spec/bundler/bundler/plugin/source_list_spec.rb1
-rw-r--r--spec/bundler/bundler/plugin_spec.rb83
-rw-r--r--spec/bundler/bundler/psyched_yaml_spec.rb2
-rw-r--r--spec/bundler/bundler/remote_specification_spec.rb1
-rw-r--r--spec/bundler/bundler/retry_spec.rb1
-rw-r--r--spec/bundler/bundler/ruby_dsl_spec.rb2
-rw-r--r--spec/bundler/bundler/ruby_version_spec.rb66
-rw-r--r--spec/bundler/bundler/rubygems_integration_spec.rb49
-rw-r--r--spec/bundler/bundler/settings/validator_spec.rb111
-rw-r--r--spec/bundler/bundler/settings_spec.rb117
-rw-r--r--spec/bundler/bundler/shared_helpers_spec.rb124
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb88
-rw-r--r--spec/bundler/bundler/source/git_spec.rb73
-rw-r--r--spec/bundler/bundler/source/rubygems/remote_spec.rb58
-rw-r--r--spec/bundler/bundler/source/rubygems_spec.rb15
-rw-r--r--spec/bundler/bundler/source_list_spec.rb92
-rw-r--r--spec/bundler/bundler/source_spec.rb59
-rw-r--r--spec/bundler/bundler/spec_set_spec.rb40
-rw-r--r--spec/bundler/bundler/ssl_certs/certificate_manager_spec.rb141
-rw-r--r--spec/bundler/bundler/stub_specification_spec.rb44
-rw-r--r--spec/bundler/bundler/ui/shell_spec.rb53
-rw-r--r--spec/bundler/bundler/ui_spec.rb5
-rw-r--r--spec/bundler/bundler/uri_credentials_filter_spec.rb11
-rw-r--r--spec/bundler/bundler/vendored_persistent_spec.rb77
-rw-r--r--spec/bundler/bundler/version_ranges_spec.rb5
-rw-r--r--spec/bundler/bundler/worker_spec.rb49
-rw-r--r--spec/bundler/bundler/yaml_serializer_spec.rb3
-rw-r--r--spec/bundler/cache/cache_path_spec.rb18
-rw-r--r--spec/bundler/cache/gems_spec.rb101
-rw-r--r--spec/bundler/cache/git_spec.rb307
-rw-r--r--spec/bundler/cache/path_spec.rb227
-rw-r--r--spec/bundler/cache/platform_spec.rb11
-rw-r--r--spec/bundler/commands/add_spec.rb194
-rw-r--r--spec/bundler/commands/binstubs_spec.rb324
-rw-r--r--spec/bundler/commands/cache_spec.rb432
-rw-r--r--spec/bundler/commands/check_spec.rb375
-rw-r--r--spec/bundler/commands/clean_spec.rb443
-rw-r--r--spec/bundler/commands/config_spec.rb319
-rw-r--r--spec/bundler/commands/console_spec.rb58
-rw-r--r--spec/bundler/commands/doctor_spec.rb158
-rw-r--r--spec/bundler/commands/exec_spec.rb856
-rw-r--r--spec/bundler/commands/fund_spec.rb82
-rw-r--r--spec/bundler/commands/help_spec.rb51
-rw-r--r--spec/bundler/commands/info_spec.rb200
-rw-r--r--spec/bundler/commands/init_spec.rb119
-rw-r--r--spec/bundler/commands/inject_spec.rb59
-rw-r--r--spec/bundler/commands/install_spec.rb650
-rw-r--r--spec/bundler/commands/issue_spec.rb3
-rw-r--r--spec/bundler/commands/licenses_spec.rb15
-rw-r--r--spec/bundler/commands/list_spec.rb195
-rw-r--r--spec/bundler/commands/lock_spec.rb345
-rw-r--r--spec/bundler/commands/newgem_spec.rb1468
-rw-r--r--spec/bundler/commands/open_spec.rb161
-rw-r--r--spec/bundler/commands/outdated_spec.rb1023
-rw-r--r--spec/bundler/commands/package_spec.rb306
-rw-r--r--spec/bundler/commands/post_bundle_message_spec.rb205
-rw-r--r--spec/bundler/commands/pristine_spec.rb150
-rw-r--r--spec/bundler/commands/remove_spec.rb702
-rw-r--r--spec/bundler/commands/show_spec.rb101
-rw-r--r--spec/bundler/commands/update_spec.rb992
-rw-r--r--spec/bundler/commands/version_spec.rb47
-rw-r--r--spec/bundler/commands/viz_spec.rb38
-rw-r--r--spec/bundler/install/allow_offline_install_spec.rb32
-rw-r--r--spec/bundler/install/binstubs_spec.rb27
-rw-r--r--spec/bundler/install/bundler_spec.rb162
-rw-r--r--spec/bundler/install/deploy_spec.rb395
-rw-r--r--spec/bundler/install/failure_spec.rb30
-rw-r--r--spec/bundler/install/force_spec.rb67
-rw-r--r--spec/bundler/install/gemfile/eval_gemfile_spec.rb73
-rw-r--r--spec/bundler/install/gemfile/gemspec_spec.rb288
-rw-r--r--spec/bundler/install/gemfile/git_spec.rb676
-rw-r--r--spec/bundler/install/gemfile/groups_spec.rb213
-rw-r--r--spec/bundler/install/gemfile/install_if.rb45
-rw-r--r--spec/bundler/install/gemfile/install_if_spec.rb44
-rw-r--r--spec/bundler/install/gemfile/lockfile_spec.rb48
-rw-r--r--spec/bundler/install/gemfile/path_spec.rb460
-rw-r--r--spec/bundler/install/gemfile/platform_spec.rb378
-rw-r--r--spec/bundler/install/gemfile/ruby_spec.rb34
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb1340
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb348
-rw-r--r--spec/bundler/install/gemfile_spec.rb100
-rw-r--r--spec/bundler/install/gems/compact_index_spec.rb430
-rw-r--r--spec/bundler/install/gems/dependency_api_spec.rb241
-rw-r--r--spec/bundler/install/gems/env_spec.rb9
-rw-r--r--spec/bundler/install/gems/flex_spec.rb126
-rw-r--r--spec/bundler/install/gems/fund_spec.rb137
-rw-r--r--spec/bundler/install/gems/mirror_spec.rb15
-rw-r--r--spec/bundler/install/gems/native_extensions_spec.rb110
-rw-r--r--spec/bundler/install/gems/post_install_spec.rb27
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb224
-rw-r--r--spec/bundler/install/gems/standalone_spec.rb279
-rw-r--r--spec/bundler/install/gems/sudo_spec.rb90
-rw-r--r--spec/bundler/install/gems/win32_spec.rb8
-rw-r--r--spec/bundler/install/gemspecs_spec.rb82
-rw-r--r--spec/bundler/install/git_spec.rb70
-rw-r--r--spec/bundler/install/global_cache_spec.rb254
-rw-r--r--spec/bundler/install/path_spec.rb150
-rw-r--r--spec/bundler/install/post_bundle_message_spec.rb190
-rw-r--r--spec/bundler/install/prereleases_spec.rb24
-rw-r--r--spec/bundler/install/process_lock_spec.rb35
-rw-r--r--spec/bundler/install/redownload_spec.rb91
-rw-r--r--spec/bundler/install/security_policy_spec.rb35
-rw-r--r--spec/bundler/install/yanked_spec.rb84
-rw-r--r--spec/bundler/lock/git_spec.rb4
-rw-r--r--spec/bundler/lock/lockfile_spec.rb714
-rw-r--r--spec/bundler/other/bundle_ruby_spec.rb143
-rw-r--r--spec/bundler/other/cli_dispatch_spec.rb18
-rw-r--r--spec/bundler/other/ext_spec.rb14
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb711
-rw-r--r--spec/bundler/other/platform_spec.rb830
-rw-r--r--spec/bundler/other/ssl_cert_spec.rb18
-rw-r--r--spec/bundler/plugins/command_spec.rb13
-rw-r--r--spec/bundler/plugins/hook_spec.rb115
-rw-r--r--spec/bundler/plugins/install_spec.rb149
-rw-r--r--spec/bundler/plugins/list_spec.rb60
-rw-r--r--spec/bundler/plugins/source/example_spec.rb90
-rw-r--r--spec/bundler/plugins/source_spec.rb20
-rw-r--r--spec/bundler/plugins/uninstall_spec.rb49
-rw-r--r--spec/bundler/quality_es_spec.rb61
-rw-r--r--spec/bundler/quality_spec.rb274
-rw-r--r--spec/bundler/realworld/dependency_api_spec.rb15
-rw-r--r--spec/bundler/realworld/double_check_spec.rb40
-rw-r--r--spec/bundler/realworld/edgecases_spec.rb539
-rw-r--r--spec/bundler/realworld/ffi_spec.rb57
-rw-r--r--spec/bundler/realworld/fixtures/warbler/.gitignore1
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile7
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile.lock30
-rw-r--r--spec/bundler/realworld/fixtures/warbler/bin/warbler-example.rb3
-rw-r--r--spec/bundler/realworld/fixtures/warbler/demo/demo.gemspec10
-rw-r--r--spec/bundler/realworld/gemfile_source_header_spec.rb12
-rw-r--r--spec/bundler/realworld/mirror_probe_spec.rb44
-rw-r--r--spec/bundler/realworld/parallel_spec.rb33
-rw-r--r--spec/bundler/realworld/slow_perf_spec.rb22
-rw-r--r--spec/bundler/resolver/basic_spec.rb132
-rw-r--r--spec/bundler/resolver/platform_spec.rb283
-rw-r--r--spec/bundler/runtime/executable_spec.rb92
-rw-r--r--spec/bundler/runtime/gem_tasks_spec.rb79
-rw-r--r--spec/bundler/runtime/inline_spec.rb260
-rw-r--r--spec/bundler/runtime/load_spec.rb28
-rw-r--r--spec/bundler/runtime/platform_spec.rb240
-rw-r--r--spec/bundler/runtime/require_spec.rb157
-rw-r--r--spec/bundler/runtime/setup_spec.rb873
-rw-r--r--spec/bundler/runtime/with_clean_env_spec.rb135
-rw-r--r--spec/bundler/runtime/with_unbundled_env_spec.rb302
-rw-r--r--spec/bundler/spec_helper.rb160
-rw-r--r--spec/bundler/support/api_request_limit_hax.rb16
-rw-r--r--spec/bundler/support/artifice/compact_index.rb31
-rw-r--r--spec/bundler/support/artifice/compact_index_api_missing.rb7
-rw-r--r--spec/bundler/support/artifice/compact_index_basic_authentication.rb3
-rw-r--r--spec/bundler/support/artifice/compact_index_checksum_mismatch.rb3
-rw-r--r--spec/bundler/support/artifice/compact_index_concurrent_download.rb7
-rw-r--r--spec/bundler/support/artifice/compact_index_creds_diff_host.rb7
-rw-r--r--spec/bundler/support/artifice/compact_index_extra.rb11
-rw-r--r--spec/bundler/support/artifice/compact_index_extra_api.rb13
-rw-r--r--spec/bundler/support/artifice/compact_index_extra_api_missing.rb17
-rw-r--r--spec/bundler/support/artifice/compact_index_extra_missing.rb5
-rw-r--r--spec/bundler/support/artifice/compact_index_forbidden.rb3
-rw-r--r--spec/bundler/support/artifice/compact_index_host_redirect.rb3
-rw-r--r--spec/bundler/support/artifice/compact_index_no_gem.rb13
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update.rb9
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb40
-rw-r--r--spec/bundler/support/artifice/compact_index_range_not_satisfiable.rb34
-rw-r--r--spec/bundler/support/artifice/compact_index_rate_limited.rb48
-rw-r--r--spec/bundler/support/artifice/compact_index_redirects.rb3
-rw-r--r--spec/bundler/support/artifice/compact_index_strict_basic_authentication.rb3
-rw-r--r--spec/bundler/support/artifice/compact_index_wrong_dependencies.rb3
-rw-r--r--spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb3
-rw-r--r--spec/bundler/support/artifice/endopint_marshal_fail_basic_authentication.rb14
-rw-r--r--spec/bundler/support/artifice/endpoint.rb104
-rw-r--r--spec/bundler/support/artifice/endpoint_500.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_api_forbidden.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_api_missing.rb7
-rw-r--r--spec/bundler/support/artifice/endpoint_basic_authentication.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_creds_diff_host.rb7
-rw-r--r--spec/bundler/support/artifice/endpoint_extra.rb11
-rw-r--r--spec/bundler/support/artifice/endpoint_extra_api.rb11
-rw-r--r--spec/bundler/support/artifice/endpoint_extra_missing.rb5
-rw-r--r--spec/bundler/support/artifice/endpoint_fallback.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_host_redirect.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_marshal_fail.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_marshal_fail_basic_authentication.rb15
-rw-r--r--spec/bundler/support/artifice/endpoint_mirror_source.rb5
-rw-r--r--spec/bundler/support/artifice/endpoint_redirect.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_strict_basic_authentication.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_timeout.rb5
-rw-r--r--spec/bundler/support/artifice/fail.rb5
-rw-r--r--spec/bundler/support/artifice/vcr.rb165
-rw-r--r--spec/bundler/support/artifice/windows.rb14
-rw-r--r--spec/bundler/support/build_metadata.rb49
-rw-r--r--spec/bundler/support/builders.rb377
-rw-r--r--spec/bundler/support/bundle.rb8
-rw-r--r--spec/bundler/support/code_climate.rb25
-rw-r--r--spec/bundler/support/command_execution.rb33
-rw-r--r--spec/bundler/support/filters.rb40
-rw-r--r--spec/bundler/support/hax.rb59
-rw-r--r--spec/bundler/support/helpers.rb498
-rw-r--r--spec/bundler/support/indexes.rb93
-rw-r--r--spec/bundler/support/less_than_proc.rb19
-rw-r--r--spec/bundler/support/matchers.rb159
-rw-r--r--spec/bundler/support/path.rb223
-rw-r--r--spec/bundler/support/permissions.rb1
-rw-r--r--spec/bundler/support/platforms.rb32
-rw-r--r--spec/bundler/support/rubygems_ext.rb170
-rw-r--r--spec/bundler/support/rubygems_version_manager.rb120
-rw-r--r--spec/bundler/support/silent_logger.rb1
-rw-r--r--spec/bundler/support/sometimes.rb56
-rw-r--r--spec/bundler/support/streams.rb13
-rw-r--r--spec/bundler/support/sudo.rb1
-rw-r--r--spec/bundler/support/switch_rubygems.rb4
-rw-r--r--spec/bundler/support/the_bundle.rb5
-rw-r--r--spec/bundler/update/gemfile_spec.rb47
-rw-r--r--spec/bundler/update/gems/fund_spec.rb50
-rw-r--r--spec/bundler/update/gems/post_install_spec.rb15
-rw-r--r--spec/bundler/update/git_spec.rb112
-rw-r--r--spec/bundler/update/path_spec.rb2
-rw-r--r--spec/bundler/update/redownload_spec.rb34
-rw-r--r--spec/mspec/.gitignore26
-rw-r--r--spec/mspec/.travis.yml18
-rw-r--r--spec/mspec/Gemfile2
-rw-r--r--spec/mspec/Gemfile.lock9
-rw-r--r--spec/mspec/README.md35
-rw-r--r--spec/mspec/Rakefile1
-rw-r--r--spec/mspec/lib/mspec.rb14
-rwxr-xr-xspec/mspec/lib/mspec/commands/mkspec.rb4
-rw-r--r--spec/mspec/lib/mspec/commands/mspec-ci.rb3
-rw-r--r--spec/mspec/lib/mspec/commands/mspec-run.rb3
-rw-r--r--spec/mspec/lib/mspec/commands/mspec-tag.rb3
-rwxr-xr-xspec/mspec/lib/mspec/commands/mspec.rb71
-rw-r--r--spec/mspec/lib/mspec/expectations/expectations.rb18
-rw-r--r--spec/mspec/lib/mspec/expectations/should.rb22
-rw-r--r--spec/mspec/lib/mspec/guards/bug.rb19
-rw-r--r--spec/mspec/lib/mspec/guards/conflict.rb6
-rw-r--r--spec/mspec/lib/mspec/guards/feature.rb4
-rw-r--r--spec/mspec/lib/mspec/guards/guard.rb2
-rw-r--r--spec/mspec/lib/mspec/guards/platform.rb46
-rw-r--r--spec/mspec/lib/mspec/guards/version.rb37
-rw-r--r--spec/mspec/lib/mspec/helpers/datetime.rb2
-rw-r--r--spec/mspec/lib/mspec/helpers/flunk.rb2
-rw-r--r--spec/mspec/lib/mspec/helpers/fs.rb10
-rw-r--r--spec/mspec/lib/mspec/helpers/io.rb36
-rw-r--r--spec/mspec/lib/mspec/helpers/numeric.rb10
-rw-r--r--spec/mspec/lib/mspec/helpers/ruby_exe.rb63
-rw-r--r--spec/mspec/lib/mspec/helpers/scratch.rb4
-rw-r--r--spec/mspec/lib/mspec/helpers/tmp.rb15
-rw-r--r--spec/mspec/lib/mspec/helpers/warning.rb12
-rw-r--r--spec/mspec/lib/mspec/matchers.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/base.rb86
-rw-r--r--spec/mspec/lib/mspec/matchers/be_close.rb8
-rw-r--r--spec/mspec/lib/mspec/matchers/block_caller.rb30
-rw-r--r--spec/mspec/lib/mspec/matchers/complain.rb51
-rw-r--r--spec/mspec/lib/mspec/matchers/eql.rb8
-rw-r--r--spec/mspec/lib/mspec/matchers/equal.rb8
-rw-r--r--spec/mspec/lib/mspec/matchers/equal_element.rb4
-rw-r--r--spec/mspec/lib/mspec/matchers/have_instance_method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/have_method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/have_private_instance_method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/have_private_method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/have_protected_instance_method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/have_public_instance_method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/have_singleton_method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/include.rb4
-rw-r--r--spec/mspec/lib/mspec/matchers/include_any_of.rb29
-rw-r--r--spec/mspec/lib/mspec/matchers/method.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/output.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/raise_error.rb46
-rw-r--r--spec/mspec/lib/mspec/matchers/skip.rb5
-rw-r--r--spec/mspec/lib/mspec/mocks/mock.rb24
-rw-r--r--spec/mspec/lib/mspec/mocks/object.rb4
-rw-r--r--spec/mspec/lib/mspec/mocks/proxy.rb6
-rw-r--r--spec/mspec/lib/mspec/runner/actions/constants_leak_checker.rb84
-rw-r--r--spec/mspec/lib/mspec/runner/actions/filter.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/actions/leakchecker.rb137
-rw-r--r--spec/mspec/lib/mspec/runner/actions/profile.rb60
-rw-r--r--spec/mspec/lib/mspec/runner/actions/tag.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/actions/taglist.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/actions/tally.rb14
-rw-r--r--spec/mspec/lib/mspec/runner/actions/timeout.rb60
-rw-r--r--spec/mspec/lib/mspec/runner/context.rb39
-rw-r--r--spec/mspec/lib/mspec/runner/evaluate.rb4
-rw-r--r--spec/mspec/lib/mspec/runner/example.rb14
-rw-r--r--spec/mspec/lib/mspec/runner/exception.rb31
-rw-r--r--spec/mspec/lib/mspec/runner/filters/regexp.rb24
-rw-r--r--spec/mspec/lib/mspec/runner/formatters.rb1
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/base.rb128
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/describe.rb1
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/dotted.rb110
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/file.rb9
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/html.rb10
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/junit.rb9
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/method.rb28
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/multi.rb42
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/profile.rb60
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/specdoc.rb14
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/spinner.rb20
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/stats.rb57
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/summary.rb11
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/unit.rb1
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/yaml.rb10
-rw-r--r--spec/mspec/lib/mspec/runner/mspec.rb94
-rw-r--r--spec/mspec/lib/mspec/runner/object.rb12
-rw-r--r--spec/mspec/lib/mspec/runner/parallel.rb98
-rw-r--r--spec/mspec/lib/mspec/runner/shared.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/tag.rb2
-rw-r--r--spec/mspec/lib/mspec/utils/format.rb24
-rw-r--r--spec/mspec/lib/mspec/utils/name_map.rb51
-rw-r--r--spec/mspec/lib/mspec/utils/options.rb34
-rw-r--r--spec/mspec/lib/mspec/utils/script.rb63
-rw-r--r--spec/mspec/lib/mspec/utils/version.rb2
-rw-r--r--spec/mspec/lib/mspec/utils/warnings.rb42
-rw-r--r--spec/mspec/spec/commands/mkspec_spec.rb4
-rw-r--r--spec/mspec/spec/commands/mspec_run_spec.rb11
-rw-r--r--spec/mspec/spec/expectations/should.rb2
-rw-r--r--spec/mspec/spec/expectations/should_spec.rb10
-rw-r--r--spec/mspec/spec/fixtures/chatty_spec.rb8
-rw-r--r--spec/mspec/spec/fixtures/config.mspec2
-rw-r--r--spec/mspec/spec/fixtures/die_spec.rb7
-rwxr-xr-xspec/mspec/spec/fixtures/my_ruby2
-rw-r--r--spec/mspec/spec/guards/conflict_spec.rb2
-rw-r--r--spec/mspec/spec/guards/feature_spec.rb40
-rw-r--r--spec/mspec/spec/guards/guard_spec.rb4
-rw-r--r--spec/mspec/spec/guards/platform_spec.rb47
-rw-r--r--spec/mspec/spec/guards/version_spec.rb58
-rw-r--r--spec/mspec/spec/helpers/io_spec.rb48
-rw-r--r--spec/mspec/spec/helpers/tmp_spec.rb2
-rw-r--r--spec/mspec/spec/integration/run_spec.rb37
-rw-r--r--spec/mspec/spec/integration/tag_spec.rb12
-rw-r--r--spec/mspec/spec/matchers/base_spec.rb219
-rw-r--r--spec/mspec/spec/matchers/be_close_spec.rb18
-rw-r--r--spec/mspec/spec/matchers/complain_spec.rb47
-rw-r--r--spec/mspec/spec/matchers/eql_spec.rb4
-rw-r--r--spec/mspec/spec/matchers/equal_element_spec.rb12
-rw-r--r--spec/mspec/spec/matchers/equal_spec.rb4
-rw-r--r--spec/mspec/spec/matchers/include_any_of_spec.rb42
-rw-r--r--spec/mspec/spec/matchers/raise_error_spec.rb65
-rw-r--r--spec/mspec/spec/mocks/mock_spec.rb71
-rw-r--r--spec/mspec/spec/runner/context_spec.rb29
-rw-r--r--spec/mspec/spec/runner/example_spec.rb10
-rw-r--r--spec/mspec/spec/runner/exception_spec.rb2
-rw-r--r--spec/mspec/spec/runner/filters/profile_spec.rb8
-rw-r--r--spec/mspec/spec/runner/filters/regexp_spec.rb20
-rw-r--r--spec/mspec/spec/runner/formatters/dotted_spec.rb2
-rw-r--r--spec/mspec/spec/runner/formatters/multi_spec.rb8
-rw-r--r--spec/mspec/spec/runner/mspec_spec.rb19
-rw-r--r--spec/mspec/spec/spec_helper.rb2
-rw-r--r--spec/mspec/spec/utils/name_map_spec.rb4
-rw-r--r--spec/mspec/spec/utils/options_spec.rb21
-rw-r--r--spec/mspec/spec/utils/script_spec.rb23
-rwxr-xr-xspec/mspec/tool/pull-latest-mspec-spec26
-rw-r--r--spec/mspec/tool/remove_old_guards.rb39
-rw-r--r--spec/mspec/tool/sync/sync-rubyspec.rb90
-rwxr-xr-xspec/mspec/tool/tag_from_output.rb44
-rwxr-xr-xspec/mspec/tool/wrap_with_guard.rb28
-rw-r--r--spec/ruby/.mspec.constants231
-rw-r--r--spec/ruby/.rubocop.yml99
-rw-r--r--spec/ruby/.rubocop_todo.yml153
-rw-r--r--spec/ruby/.travis.yml34
-rw-r--r--spec/ruby/CHANGES.before-2008-05-1017796
-rw-r--r--spec/ruby/CONTRIBUTING.md232
-rw-r--r--spec/ruby/README.md81
-rw-r--r--spec/ruby/appveyor.yml30
-rw-r--r--spec/ruby/command_line/dash_a_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_c_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_d_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_e_spec.rb4
-rw-r--r--spec/ruby/command_line/dash_encoding_spec.rb30
-rw-r--r--spec/ruby/command_line/dash_external_encoding_spec.rb15
-rw-r--r--spec/ruby/command_line/dash_internal_encoding_spec.rb15
-rw-r--r--spec/ruby/command_line/dash_l_spec.rb31
-rw-r--r--spec/ruby/command_line/dash_n_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_p_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_r_spec.rb21
-rw-r--r--spec/ruby/command_line/dash_s_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_upper_c_spec.rb20
-rw-r--r--spec/ruby/command_line/dash_upper_e_spec.rb29
-rw-r--r--spec/ruby/command_line/dash_upper_f_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_upper_i_spec.rb42
-rw-r--r--spec/ruby/command_line/dash_upper_k_spec.rb76
-rw-r--r--spec/ruby/command_line/dash_upper_s_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_upper_u_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_upper_w_spec.rb36
-rw-r--r--spec/ruby/command_line/dash_upper_x_spec.rb6
-rw-r--r--spec/ruby/command_line/dash_v_spec.rb6
-rw-r--r--spec/ruby/command_line/dash_w_spec.rb4
-rw-r--r--spec/ruby/command_line/dash_x_spec.rb4
-rw-r--r--spec/ruby/command_line/error_message_spec.rb6
-rw-r--r--spec/ruby/command_line/feature_spec.rb63
-rw-r--r--spec/ruby/command_line/fixtures/bin/hybrid_launcher.sh2
-rwxr-xr-x[-rw-r--r--]spec/ruby/command_line/fixtures/bin/launcher.rb0
-rw-r--r--spec/ruby/command_line/fixtures/change_directory_script.rb (renamed from spec/ruby/command_line/fixtures/dash_upper_c_script.rb)0
-rw-r--r--spec/ruby/command_line/fixtures/test_file.rb2
-rw-r--r--spec/ruby/command_line/frozen_strings_spec.rb41
-rw-r--r--spec/ruby/command_line/rubylib_spec.rb69
-rw-r--r--spec/ruby/command_line/rubyopt_spec.rb39
-rw-r--r--spec/ruby/command_line/shared/change_directory.rb21
-rw-r--r--spec/ruby/command_line/shared/verbose.rb2
-rw-r--r--spec/ruby/command_line/syntax_error_spec.rb2
-rw-r--r--spec/ruby/core/argf/argf_spec.rb2
-rw-r--r--spec/ruby/core/argf/argv_spec.rb2
-rw-r--r--spec/ruby/core/argf/binmode_spec.rb12
-rw-r--r--spec/ruby/core/argf/bytes_spec.rb10
-rw-r--r--spec/ruby/core/argf/chars_spec.rb10
-rw-r--r--spec/ruby/core/argf/close_spec.rb21
-rw-r--r--spec/ruby/core/argf/closed_spec.rb2
-rw-r--r--spec/ruby/core/argf/codepoints_spec.rb10
-rw-r--r--spec/ruby/core/argf/each_byte_spec.rb4
-rw-r--r--spec/ruby/core/argf/each_char_spec.rb4
-rw-r--r--spec/ruby/core/argf/each_codepoint_spec.rb4
-rw-r--r--spec/ruby/core/argf/each_line_spec.rb4
-rw-r--r--spec/ruby/core/argf/each_spec.rb4
-rw-r--r--spec/ruby/core/argf/eof_spec.rb4
-rw-r--r--spec/ruby/core/argf/file_spec.rb2
-rw-r--r--spec/ruby/core/argf/filename_spec.rb4
-rw-r--r--spec/ruby/core/argf/fileno_spec.rb4
-rw-r--r--spec/ruby/core/argf/getc_spec.rb4
-rw-r--r--spec/ruby/core/argf/gets_spec.rb34
-rw-r--r--spec/ruby/core/argf/lineno_spec.rb2
-rw-r--r--spec/ruby/core/argf/lines_spec.rb10
-rw-r--r--spec/ruby/core/argf/path_spec.rb4
-rw-r--r--spec/ruby/core/argf/pos_spec.rb4
-rw-r--r--spec/ruby/core/argf/read_nonblock_spec.rb14
-rw-r--r--spec/ruby/core/argf/read_spec.rb34
-rw-r--r--spec/ruby/core/argf/readchar_spec.rb6
-rw-r--r--spec/ruby/core/argf/readline_spec.rb6
-rw-r--r--spec/ruby/core/argf/readlines_spec.rb4
-rw-r--r--spec/ruby/core/argf/readpartial_spec.rb22
-rw-r--r--spec/ruby/core/argf/rewind_spec.rb4
-rw-r--r--spec/ruby/core/argf/seek_spec.rb4
-rw-r--r--spec/ruby/core/argf/set_encoding_spec.rb2
-rw-r--r--spec/ruby/core/argf/shared/eof.rb2
-rw-r--r--spec/ruby/core/argf/shared/fileno.rb4
-rw-r--r--spec/ruby/core/argf/shared/pos.rb2
-rw-r--r--spec/ruby/core/argf/skip_spec.rb4
-rw-r--r--spec/ruby/core/argf/tell_spec.rb4
-rw-r--r--spec/ruby/core/argf/to_a_spec.rb4
-rw-r--r--spec/ruby/core/argf/to_i_spec.rb4
-rw-r--r--spec/ruby/core/argf/to_io_spec.rb2
-rw-r--r--spec/ruby/core/argf/to_s_spec.rb2
-rw-r--r--spec/ruby/core/array/allocate_spec.rb4
-rw-r--r--spec/ruby/core/array/any_spec.rb8
-rw-r--r--spec/ruby/core/array/append_spec.rb13
-rw-r--r--spec/ruby/core/array/array_spec.rb2
-rw-r--r--spec/ruby/core/array/assoc_spec.rb4
-rw-r--r--spec/ruby/core/array/at_spec.rb12
-rw-r--r--spec/ruby/core/array/bsearch_index_spec.rb124
-rw-r--r--spec/ruby/core/array/bsearch_spec.rb8
-rw-r--r--spec/ruby/core/array/clear_spec.rb43
-rw-r--r--spec/ruby/core/array/clone_spec.rb10
-rw-r--r--spec/ruby/core/array/collect_spec.rb10
-rw-r--r--spec/ruby/core/array/combination_spec.rb4
-rw-r--r--spec/ruby/core/array/compact_spec.rb54
-rw-r--r--spec/ruby/core/array/comparison_spec.rb4
-rw-r--r--spec/ruby/core/array/concat_spec.rb138
-rw-r--r--spec/ruby/core/array/constructor_spec.rb4
-rw-r--r--spec/ruby/core/array/count_spec.rb2
-rw-r--r--spec/ruby/core/array/cycle_spec.rb20
-rw-r--r--spec/ruby/core/array/deconstruct_spec.rb11
-rw-r--r--spec/ruby/core/array/delete_at_spec.rb50
-rw-r--r--spec/ruby/core/array/delete_if_spec.rb42
-rw-r--r--spec/ruby/core/array/delete_spec.rb44
-rw-r--r--spec/ruby/core/array/difference_spec.rb24
-rw-r--r--spec/ruby/core/array/dig_spec.rb100
-rw-r--r--spec/ruby/core/array/drop_spec.rb22
-rw-r--r--spec/ruby/core/array/drop_while_spec.rb2
-rw-r--r--spec/ruby/core/array/dup_spec.rb6
-rw-r--r--spec/ruby/core/array/each_index_spec.rb8
-rw-r--r--spec/ruby/core/array/each_spec.rb24
-rw-r--r--spec/ruby/core/array/element_reference_spec.rb8
-rw-r--r--spec/ruby/core/array/element_set_spec.rb140
-rw-r--r--spec/ruby/core/array/empty_spec.rb10
-rw-r--r--spec/ruby/core/array/eql_spec.rb12
-rw-r--r--spec/ruby/core/array/equal_value_spec.rb12
-rw-r--r--spec/ruby/core/array/fetch_spec.rb14
-rw-r--r--spec/ruby/core/array/fill_spec.rb90
-rw-r--r--spec/ruby/core/array/filter_spec.rb16
-rw-r--r--spec/ruby/core/array/find_index_spec.rb4
-rw-r--r--spec/ruby/core/array/first_spec.rb16
-rw-r--r--spec/ruby/core/array/fixtures/classes.rb23
-rw-r--r--spec/ruby/core/array/fixtures/encoded_strings.rb16
-rw-r--r--spec/ruby/core/array/flatten_spec.rb92
-rw-r--r--spec/ruby/core/array/frozen_spec.rb10
-rw-r--r--spec/ruby/core/array/hash_spec.rb10
-rw-r--r--spec/ruby/core/array/include_spec.rb4
-rw-r--r--spec/ruby/core/array/index_spec.rb6
-rw-r--r--spec/ruby/core/array/initialize_spec.rb34
-rw-r--r--spec/ruby/core/array/insert_spec.rb18
-rw-r--r--spec/ruby/core/array/inspect_spec.rb6
-rw-r--r--spec/ruby/core/array/intersection_spec.rb92
-rw-r--r--spec/ruby/core/array/join_spec.rb18
-rw-r--r--spec/ruby/core/array/keep_if_spec.rb2
-rw-r--r--spec/ruby/core/array/last_spec.rb14
-rw-r--r--spec/ruby/core/array/length_spec.rb8
-rw-r--r--spec/ruby/core/array/map_spec.rb10
-rw-r--r--spec/ruby/core/array/max_spec.rb12
-rw-r--r--spec/ruby/core/array/min_spec.rb12
-rw-r--r--spec/ruby/core/array/minmax_spec.rb14
-rw-r--r--spec/ruby/core/array/minus_spec.rb88
-rw-r--r--spec/ruby/core/array/multiply_spec.rb100
-rw-r--r--spec/ruby/core/array/new_spec.rb24
-rw-r--r--spec/ruby/core/array/pack/a_spec.rb13
-rw-r--r--spec/ruby/core/array/pack/at_spec.rb8
-rw-r--r--spec/ruby/core/array/pack/b_spec.rb21
-rw-r--r--spec/ruby/core/array/pack/buffer_spec.rb50
-rw-r--r--spec/ruby/core/array/pack/c_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/comment_spec.rb6
-rw-r--r--spec/ruby/core/array/pack/d_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/e_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/empty_spec.rb2
-rw-r--r--spec/ruby/core/array/pack/f_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/g_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/h_spec.rb21
-rw-r--r--spec/ruby/core/array/pack/i_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/j_spec.rb319
-rw-r--r--spec/ruby/core/array/pack/l_spec.rb26
-rw-r--r--spec/ruby/core/array/pack/m_spec.rb19
-rw-r--r--spec/ruby/core/array/pack/n_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/p_spec.rb57
-rw-r--r--spec/ruby/core/array/pack/percent_spec.rb4
-rw-r--r--spec/ruby/core/array/pack/q_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/s_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/shared/basic.rb22
-rw-r--r--spec/ruby/core/array/pack/shared/encodings.rb4
-rw-r--r--spec/ruby/core/array/pack/shared/float.rb70
-rw-r--r--spec/ruby/core/array/pack/shared/integer.rb2
-rw-r--r--spec/ruby/core/array/pack/shared/numeric_basic.rb20
-rw-r--r--spec/ruby/core/array/pack/shared/string.rb46
-rw-r--r--spec/ruby/core/array/pack/shared/taint.rb35
-rw-r--r--spec/ruby/core/array/pack/shared/unicode.rb6
-rw-r--r--spec/ruby/core/array/pack/u_spec.rb20
-rw-r--r--spec/ruby/core/array/pack/v_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/w_spec.rb16
-rw-r--r--spec/ruby/core/array/pack/x_spec.rb12
-rw-r--r--spec/ruby/core/array/pack/z_spec.rb12
-rw-r--r--spec/ruby/core/array/partition_spec.rb4
-rw-r--r--spec/ruby/core/array/permutation_spec.rb6
-rw-r--r--spec/ruby/core/array/plus_spec.rb30
-rw-r--r--spec/ruby/core/array/pop_spec.rb108
-rw-r--r--spec/ruby/core/array/prepend_spec.rb7
-rw-r--r--spec/ruby/core/array/product_spec.rb12
-rw-r--r--spec/ruby/core/array/push_spec.rb37
-rw-r--r--spec/ruby/core/array/rassoc_spec.rb6
-rw-r--r--spec/ruby/core/array/reject_spec.rb48
-rw-r--r--spec/ruby/core/array/repeated_combination_spec.rb4
-rw-r--r--spec/ruby/core/array/repeated_permutation_spec.rb2
-rw-r--r--spec/ruby/core/array/replace_spec.rb8
-rw-r--r--spec/ruby/core/array/reverse_each_spec.rb8
-rw-r--r--spec/ruby/core/array/reverse_spec.rb8
-rw-r--r--spec/ruby/core/array/rindex_spec.rb6
-rw-r--r--spec/ruby/core/array/rotate_spec.rb22
-rw-r--r--spec/ruby/core/array/sample_spec.rb41
-rw-r--r--spec/ruby/core/array/select_spec.rb28
-rw-r--r--spec/ruby/core/array/shared/clone.rb40
-rw-r--r--spec/ruby/core/array/shared/collect.rb70
-rw-r--r--spec/ruby/core/array/shared/delete_if.rb24
-rw-r--r--spec/ruby/core/array/shared/difference.rb78
-rw-r--r--spec/ruby/core/array/shared/inspect.rb61
-rw-r--r--spec/ruby/core/array/shared/intersection.rb84
-rw-r--r--spec/ruby/core/array/shared/join.rb136
-rw-r--r--spec/ruby/core/array/shared/keep_if.rb14
-rw-r--r--spec/ruby/core/array/shared/push.rb33
-rw-r--r--spec/ruby/core/array/shared/replace.rb6
-rw-r--r--spec/ruby/core/array/shared/select.rb32
-rw-r--r--spec/ruby/core/array/shared/slice.rb120
-rw-r--r--spec/ruby/core/array/shared/union.rb79
-rw-r--r--spec/ruby/core/array/shared/unshift.rb46
-rw-r--r--spec/ruby/core/array/shift_spec.rb48
-rw-r--r--spec/ruby/core/array/shuffle_spec.rb22
-rw-r--r--spec/ruby/core/array/size_spec.rb8
-rw-r--r--spec/ruby/core/array/slice_spec.rb28
-rw-r--r--spec/ruby/core/array/sort_by_spec.rb14
-rw-r--r--spec/ruby/core/array/sort_spec.rb36
-rw-r--r--spec/ruby/core/array/sum_spec.rb42
-rw-r--r--spec/ruby/core/array/take_spec.rb4
-rw-r--r--spec/ruby/core/array/take_while_spec.rb2
-rw-r--r--spec/ruby/core/array/to_a_spec.rb4
-rw-r--r--spec/ruby/core/array/to_ary_spec.rb4
-rw-r--r--spec/ruby/core/array/to_h_spec.rb54
-rw-r--r--spec/ruby/core/array/to_s_spec.rb8
-rw-r--r--spec/ruby/core/array/transpose_spec.rb8
-rw-r--r--spec/ruby/core/array/try_convert_spec.rb8
-rw-r--r--spec/ruby/core/array/union_spec.rb91
-rw-r--r--spec/ruby/core/array/uniq_spec.rb116
-rw-r--r--spec/ruby/core/array/unshift_spec.rb51
-rw-r--r--spec/ruby/core/array/values_at_spec.rb11
-rw-r--r--spec/ruby/core/array/zip_spec.rb6
-rw-r--r--spec/ruby/core/basicobject/__id__spec.rb4
-rw-r--r--spec/ruby/core/basicobject/__send___spec.rb6
-rw-r--r--spec/ruby/core/basicobject/basicobject_spec.rb14
-rw-r--r--spec/ruby/core/basicobject/equal_spec.rb4
-rw-r--r--spec/ruby/core/basicobject/equal_value_spec.rb4
-rw-r--r--spec/ruby/core/basicobject/initialize_spec.rb4
-rw-r--r--spec/ruby/core/basicobject/instance_eval_spec.rb34
-rw-r--r--spec/ruby/core/basicobject/instance_exec_spec.rb26
-rw-r--r--spec/ruby/core/basicobject/method_missing_spec.rb2
-rw-r--r--spec/ruby/core/basicobject/not_equal_spec.rb2
-rw-r--r--spec/ruby/core/basicobject/not_spec.rb2
-rw-r--r--spec/ruby/core/basicobject/singleton_method_added_spec.rb4
-rw-r--r--spec/ruby/core/basicobject/singleton_method_removed_spec.rb2
-rw-r--r--spec/ruby/core/basicobject/singleton_method_undefined_spec.rb2
-rw-r--r--spec/ruby/core/bignum/abs_spec.rb7
-rw-r--r--spec/ruby/core/bignum/bignum_spec.rb19
-rw-r--r--spec/ruby/core/bignum/bit_and_spec.rb50
-rw-r--r--spec/ruby/core/bignum/bit_length_spec.rb33
-rw-r--r--spec/ruby/core/bignum/bit_or_spec.rb41
-rw-r--r--spec/ruby/core/bignum/bit_xor_spec.rb47
-rw-r--r--spec/ruby/core/bignum/case_compare_spec.rb6
-rw-r--r--spec/ruby/core/bignum/coerce_spec.rb65
-rw-r--r--spec/ruby/core/bignum/comparison_spec.rb162
-rw-r--r--spec/ruby/core/bignum/complement_spec.rb9
-rw-r--r--spec/ruby/core/bignum/div_spec.rb21
-rw-r--r--spec/ruby/core/bignum/divide_spec.rb18
-rw-r--r--spec/ruby/core/bignum/divmod_spec.rb81
-rw-r--r--spec/ruby/core/bignum/element_reference_spec.rb30
-rw-r--r--spec/ruby/core/bignum/eql_spec.rb22
-rw-r--r--spec/ruby/core/bignum/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/bignum/even_spec.rb19
-rw-r--r--spec/ruby/core/bignum/exponent_spec.rb29
-rw-r--r--spec/ruby/core/bignum/fdiv_spec.rb5
-rw-r--r--spec/ruby/core/bignum/gt_spec.rb20
-rw-r--r--spec/ruby/core/bignum/gte_spec.rb19
-rw-r--r--spec/ruby/core/bignum/hash_spec.rb12
-rw-r--r--spec/ruby/core/bignum/left_shift_spec.rb73
-rw-r--r--spec/ruby/core/bignum/lt_spec.rb22
-rw-r--r--spec/ruby/core/bignum/lte_spec.rb24
-rw-r--r--spec/ruby/core/bignum/magnitude_spec.rb6
-rw-r--r--spec/ruby/core/bignum/minus_spec.rb19
-rw-r--r--spec/ruby/core/bignum/modulo_spec.rb10
-rw-r--r--spec/ruby/core/bignum/multiply_spec.rb20
-rw-r--r--spec/ruby/core/bignum/odd_spec.rb19
-rw-r--r--spec/ruby/core/bignum/plus_spec.rb19
-rw-r--r--spec/ruby/core/bignum/remainder_spec.rb21
-rw-r--r--spec/ruby/core/bignum/right_shift_spec.rb99
-rw-r--r--spec/ruby/core/bignum/shared/abs.rb6
-rw-r--r--spec/ruby/core/bignum/shared/divide.rb27
-rw-r--r--spec/ruby/core/bignum/shared/equal.rb31
-rw-r--r--spec/ruby/core/bignum/shared/modulo.rb29
-rw-r--r--spec/ruby/core/bignum/size_spec.rb16
-rw-r--r--spec/ruby/core/bignum/to_f_spec.rb13
-rw-r--r--spec/ruby/core/bignum/to_s_spec.rb48
-rw-r--r--spec/ruby/core/bignum/uminus_spec.rb11
-rw-r--r--spec/ruby/core/binding/clone_spec.rb8
-rw-r--r--spec/ruby/core/binding/dup_spec.rb8
-rw-r--r--spec/ruby/core/binding/eval_spec.rb111
-rw-r--r--spec/ruby/core/binding/fixtures/classes.rb26
-rw-r--r--spec/ruby/core/binding/fixtures/irb.rb3
-rw-r--r--spec/ruby/core/binding/fixtures/irbrc1
-rw-r--r--spec/ruby/core/binding/fixtures/location.rb6
-rw-r--r--spec/ruby/core/binding/irb_spec.rb16
-rw-r--r--spec/ruby/core/binding/local_variable_defined_spec.rb4
-rw-r--r--spec/ruby/core/binding/local_variable_get_spec.rb16
-rw-r--r--spec/ruby/core/binding/local_variable_set_spec.rb12
-rw-r--r--spec/ruby/core/binding/local_variables_spec.rb2
-rw-r--r--spec/ruby/core/binding/location_spec.rb46
-rw-r--r--spec/ruby/core/binding/receiver_spec.rb4
-rw-r--r--spec/ruby/core/binding/source_location_spec.rb11
-rw-r--r--spec/ruby/core/builtin_constants/builtin_constants_spec.rb24
-rw-r--r--spec/ruby/core/class/allocate_spec.rb8
-rw-r--r--spec/ruby/core/class/dup_spec.rb4
-rw-r--r--spec/ruby/core/class/inherited_spec.rb9
-rw-r--r--spec/ruby/core/class/initialize_spec.rb12
-rw-r--r--spec/ruby/core/class/new_spec.rb21
-rw-r--r--spec/ruby/core/class/superclass_spec.rb6
-rw-r--r--spec/ruby/core/class/to_s_spec.rb23
-rw-r--r--spec/ruby/core/comparable/between_spec.rb4
-rw-r--r--spec/ruby/core/comparable/clamp_spec.rb84
-rw-r--r--spec/ruby/core/comparable/equal_value_spec.rb43
-rw-r--r--spec/ruby/core/comparable/gt_spec.rb6
-rw-r--r--spec/ruby/core/comparable/gte_spec.rb6
-rw-r--r--spec/ruby/core/comparable/lt_spec.rb12
-rw-r--r--spec/ruby/core/comparable/lte_spec.rb6
-rw-r--r--spec/ruby/core/complex/abs2_spec.rb8
-rw-r--r--spec/ruby/core/complex/abs_spec.rb5
-rw-r--r--spec/ruby/core/complex/angle_spec.rb7
-rw-r--r--spec/ruby/core/complex/arg_spec.rb7
-rw-r--r--spec/ruby/core/complex/coerce_spec.rb69
-rw-r--r--spec/ruby/core/complex/comparision_spec.rb27
-rw-r--r--spec/ruby/core/complex/conj_spec.rb6
-rw-r--r--spec/ruby/core/complex/conjugate_spec.rb6
-rw-r--r--spec/ruby/core/complex/constants_spec.rb6
-rw-r--r--spec/ruby/core/complex/denominator_spec.rb12
-rw-r--r--spec/ruby/core/complex/divide_spec.rb3
-rw-r--r--spec/ruby/core/complex/eql_spec.rb2
-rw-r--r--spec/ruby/core/complex/equal_value_spec.rb92
-rw-r--r--spec/ruby/core/complex/exponent_spec.rb60
-rw-r--r--spec/ruby/core/complex/fdiv_spec.rb20
-rw-r--r--spec/ruby/core/complex/finite_spec.rb32
-rw-r--r--spec/ruby/core/complex/hash_spec.rb16
-rw-r--r--spec/ruby/core/complex/imag_spec.rb5
-rw-r--r--spec/ruby/core/complex/imaginary_spec.rb3
-rw-r--r--spec/ruby/core/complex/infinite_spec.rb32
-rw-r--r--spec/ruby/core/complex/inspect_spec.rb15
-rw-r--r--spec/ruby/core/complex/integer_spec.rb2
-rw-r--r--spec/ruby/core/complex/magnitude_spec.rb5
-rw-r--r--spec/ruby/core/complex/marshal_dump_spec.rb2
-rw-r--r--spec/ruby/core/complex/minus_spec.rb44
-rw-r--r--spec/ruby/core/complex/multiply_spec.rb48
-rw-r--r--spec/ruby/core/complex/negative_spec.rb4
-rw-r--r--spec/ruby/core/complex/numerator_spec.rb18
-rw-r--r--spec/ruby/core/complex/phase_spec.rb4
-rw-r--r--spec/ruby/core/complex/plus_spec.rb44
-rw-r--r--spec/ruby/core/complex/polar_spec.rb23
-rw-r--r--spec/ruby/core/complex/positive_spec.rb4
-rw-r--r--spec/ruby/core/complex/quo_spec.rb3
-rw-r--r--spec/ruby/core/complex/rationalize_spec.rb10
-rw-r--r--spec/ruby/core/complex/real_spec.rb9
-rw-r--r--spec/ruby/core/complex/rect_spec.rb7
-rw-r--r--spec/ruby/core/complex/rectangular_spec.rb7
-rw-r--r--spec/ruby/core/complex/shared/abs.rb10
-rw-r--r--spec/ruby/core/complex/shared/arg.rb (renamed from spec/ruby/shared/complex/arg.rb)0
-rw-r--r--spec/ruby/core/complex/shared/conjugate.rb (renamed from spec/ruby/shared/complex/conjugate.rb)0
-rw-r--r--spec/ruby/core/complex/shared/divide.rb82
-rw-r--r--spec/ruby/core/complex/shared/image.rb8
-rw-r--r--spec/ruby/core/complex/shared/rect.rb94
-rw-r--r--spec/ruby/core/complex/to_c_spec.rb12
-rw-r--r--spec/ruby/core/complex/to_f_spec.rb8
-rw-r--r--spec/ruby/core/complex/to_i_spec.rb8
-rw-r--r--spec/ruby/core/complex/to_r_spec.rb8
-rw-r--r--spec/ruby/core/complex/to_s_spec.rb43
-rw-r--r--spec/ruby/core/complex/uminus_spec.rb2
-rw-r--r--spec/ruby/core/data/constants_spec.rb15
-rw-r--r--spec/ruby/core/dir/chdir_spec.rb14
-rw-r--r--spec/ruby/core/dir/children_spec.rb136
-rw-r--r--spec/ruby/core/dir/chroot_spec.rb14
-rw-r--r--spec/ruby/core/dir/close_spec.rb24
-rw-r--r--spec/ruby/core/dir/delete_spec.rb6
-rw-r--r--spec/ruby/core/dir/dir_spec.rb2
-rw-r--r--spec/ruby/core/dir/each_child_spec.rb103
-rw-r--r--spec/ruby/core/dir/each_spec.rb6
-rw-r--r--spec/ruby/core/dir/element_reference_spec.rb6
-rw-r--r--spec/ruby/core/dir/empty_spec.rb31
-rw-r--r--spec/ruby/core/dir/entries_spec.rb12
-rw-r--r--spec/ruby/core/dir/exist_spec.rb8
-rw-r--r--spec/ruby/core/dir/exists_spec.rb15
-rw-r--r--spec/ruby/core/dir/fileno_spec.rb8
-rw-r--r--spec/ruby/core/dir/fixtures/common.rb5
-rw-r--r--spec/ruby/core/dir/foreach_spec.rb6
-rw-r--r--spec/ruby/core/dir/getwd_spec.rb6
-rw-r--r--spec/ruby/core/dir/glob_spec.rb38
-rw-r--r--spec/ruby/core/dir/home_spec.rb47
-rw-r--r--spec/ruby/core/dir/initialize_spec.rb4
-rw-r--r--spec/ruby/core/dir/inspect_spec.rb4
-rw-r--r--spec/ruby/core/dir/mkdir_spec.rb68
-rw-r--r--spec/ruby/core/dir/open_spec.rb6
-rw-r--r--spec/ruby/core/dir/path_spec.rb8
-rw-r--r--spec/ruby/core/dir/pos_spec.rb8
-rw-r--r--spec/ruby/core/dir/pwd_spec.rb6
-rw-r--r--spec/ruby/core/dir/read_spec.rb6
-rw-r--r--spec/ruby/core/dir/rewind_spec.rb6
-rw-r--r--spec/ruby/core/dir/rmdir_spec.rb6
-rw-r--r--spec/ruby/core/dir/seek_spec.rb6
-rw-r--r--spec/ruby/core/dir/shared/chroot.rb10
-rw-r--r--spec/ruby/core/dir/shared/closed.rb2
-rw-r--r--spec/ruby/core/dir/shared/delete.rb24
-rw-r--r--spec/ruby/core/dir/shared/exist.rb2
-rw-r--r--spec/ruby/core/dir/shared/glob.rb108
-rw-r--r--spec/ruby/core/dir/shared/open.rb24
-rw-r--r--spec/ruby/core/dir/shared/path.rb22
-rw-r--r--spec/ruby/core/dir/shared/pwd.rb20
-rw-r--r--spec/ruby/core/dir/tell_spec.rb8
-rw-r--r--spec/ruby/core/dir/to_path_spec.rb8
-rw-r--r--spec/ruby/core/dir/unlink_spec.rb6
-rw-r--r--spec/ruby/core/encoding/_dump_spec.rb2
-rw-r--r--spec/ruby/core/encoding/_load_spec.rb2
-rw-r--r--spec/ruby/core/encoding/aliases_spec.rb62
-rw-r--r--spec/ruby/core/encoding/ascii_compatible_spec.rb16
-rw-r--r--spec/ruby/core/encoding/compatible_spec.rb574
-rw-r--r--spec/ruby/core/encoding/converter/asciicompat_encoding_spec.rb60
-rw-r--r--spec/ruby/core/encoding/converter/constants_spec.rb184
-rw-r--r--spec/ruby/core/encoding/converter/convert_spec.rb72
-rw-r--r--spec/ruby/core/encoding/converter/convpath_spec.rb77
-rw-r--r--spec/ruby/core/encoding/converter/destination_encoding_spec.rb16
-rw-r--r--spec/ruby/core/encoding/converter/finish_spec.rb56
-rw-r--r--spec/ruby/core/encoding/converter/insert_output_spec.rb2
-rw-r--r--spec/ruby/core/encoding/converter/inspect_spec.rb2
-rw-r--r--spec/ruby/core/encoding/converter/last_error_spec.rb150
-rw-r--r--spec/ruby/core/encoding/converter/new_spec.rb200
-rw-r--r--spec/ruby/core/encoding/converter/primitive_convert_spec.rb418
-rw-r--r--spec/ruby/core/encoding/converter/primitive_errinfo_spec.rb114
-rw-r--r--spec/ruby/core/encoding/converter/putback_spec.rb77
-rw-r--r--spec/ruby/core/encoding/converter/replacement_spec.rb118
-rw-r--r--spec/ruby/core/encoding/converter/search_convpath_spec.rb89
-rw-r--r--spec/ruby/core/encoding/converter/source_encoding_spec.rb16
-rw-r--r--spec/ruby/core/encoding/default_external_spec.rb105
-rw-r--r--spec/ruby/core/encoding/default_internal_spec.rb141
-rw-r--r--spec/ruby/core/encoding/dummy_spec.rb22
-rw-r--r--spec/ruby/core/encoding/find_spec.rb120
-rw-r--r--spec/ruby/core/encoding/inspect_spec.rb26
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb28
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb28
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb44
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb43
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb44
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb46
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb54
-rw-r--r--spec/ruby/core/encoding/list_spec.rb68
-rw-r--r--spec/ruby/core/encoding/locale_charmap_spec.rb69
-rw-r--r--spec/ruby/core/encoding/name_list_spec.rb32
-rw-r--r--spec/ruby/core/encoding/name_spec.rb8
-rw-r--r--spec/ruby/core/encoding/names_spec.rb50
-rw-r--r--spec/ruby/core/encoding/replicate_spec.rb76
-rw-r--r--spec/ruby/core/encoding/shared/name.rb2
-rw-r--r--spec/ruby/core/encoding/to_s_spec.rb8
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb22
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb22
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb40
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb46
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb48
-rw-r--r--spec/ruby/core/enumerable/all_spec.rb123
-rw-r--r--spec/ruby/core/enumerable/any_spec.rb142
-rw-r--r--spec/ruby/core/enumerable/chain_spec.rb25
-rw-r--r--spec/ruby/core/enumerable/chunk_spec.rb59
-rw-r--r--spec/ruby/core/enumerable/chunk_while_spec.rb64
-rw-r--r--spec/ruby/core/enumerable/collect_concat_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/collect_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/count_spec.rb4
-rw-r--r--spec/ruby/core/enumerable/cycle_spec.rb12
-rw-r--r--spec/ruby/core/enumerable/detect_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/drop_spec.rb16
-rw-r--r--spec/ruby/core/enumerable/drop_while_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/each_cons_spec.rb22
-rw-r--r--spec/ruby/core/enumerable/each_entry_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/each_slice_spec.rb22
-rw-r--r--spec/ruby/core/enumerable/each_with_index_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/each_with_object_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/entries_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/filter_map_spec.rb26
-rw-r--r--spec/ruby/core/enumerable/filter_spec.rb9
-rw-r--r--spec/ruby/core/enumerable/find_all_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/find_index_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/find_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/first_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/fixtures/classes.rb20
-rw-r--r--spec/ruby/core/enumerable/flat_map_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/grep_spec.rb36
-rw-r--r--spec/ruby/core/enumerable/grep_v_spec.rb110
-rw-r--r--spec/ruby/core/enumerable/group_by_spec.rb18
-rw-r--r--spec/ruby/core/enumerable/include_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/inject_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/lazy_spec.rb4
-rw-r--r--spec/ruby/core/enumerable/map_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/max_by_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/max_spec.rb12
-rw-r--r--spec/ruby/core/enumerable/member_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/min_by_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/min_spec.rb12
-rw-r--r--spec/ruby/core/enumerable/minmax_by_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/minmax_spec.rb38
-rw-r--r--spec/ruby/core/enumerable/none_spec.rb175
-rw-r--r--spec/ruby/core/enumerable/one_spec.rb141
-rw-r--r--spec/ruby/core/enumerable/partition_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/reduce_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/reject_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/reverse_each_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/select_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/shared/collect.rb38
-rw-r--r--spec/ruby/core/enumerable/shared/collect_concat.rb4
-rw-r--r--spec/ruby/core/enumerable/shared/entries.rb12
-rw-r--r--spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb2
-rw-r--r--spec/ruby/core/enumerable/shared/find.rb16
-rw-r--r--spec/ruby/core/enumerable/shared/find_all.rb2
-rw-r--r--spec/ruby/core/enumerable/shared/take.rb8
-rw-r--r--spec/ruby/core/enumerable/slice_after_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/slice_before_spec.rb41
-rw-r--r--spec/ruby/core/enumerable/slice_when_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/sort_by_spec.rb13
-rw-r--r--spec/ruby/core/enumerable/sort_spec.rb12
-rw-r--r--spec/ruby/core/enumerable/sum_spec.rb42
-rw-r--r--spec/ruby/core/enumerable/take_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/take_while_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/tally_spec.rb35
-rw-r--r--spec/ruby/core/enumerable/to_a_spec.rb8
-rw-r--r--spec/ruby/core/enumerable/to_h_spec.rb52
-rw-r--r--spec/ruby/core/enumerable/uniq_spec.rb129
-rw-r--r--spec/ruby/core/enumerable/zip_spec.rb19
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb11
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb19
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb11
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb20
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb19
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb11
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb22
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb22
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb11
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb19
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb19
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb13
-rw-r--r--spec/ruby/core/enumerator/chain/each_spec.rb17
-rw-r--r--spec/ruby/core/enumerator/chain/initialize_spec.rb33
-rw-r--r--spec/ruby/core/enumerator/chain/inspect_spec.rb16
-rw-r--r--spec/ruby/core/enumerator/chain/rewind_spec.rb53
-rw-r--r--spec/ruby/core/enumerator/chain/size_spec.rb24
-rw-r--r--spec/ruby/core/enumerator/each_spec.rb88
-rw-r--r--spec/ruby/core/enumerator/each_with_index_spec.rb16
-rw-r--r--spec/ruby/core/enumerator/each_with_object_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/enum_for_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/enumerator_spec.rb2
-rw-r--r--spec/ruby/core/enumerator/feed_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/first_spec.rb2
-rw-r--r--spec/ruby/core/enumerator/generator/each_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/generator/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/initialize_spec.rb14
-rw-r--r--spec/ruby/core/enumerator/inject_spec.rb15
-rw-r--r--spec/ruby/core/enumerator/inspect_spec.rb2
-rw-r--r--spec/ruby/core/enumerator/lazy/chunk_spec.rb67
-rw-r--r--spec/ruby/core/enumerator/lazy/chunk_while_spec.rb9
-rw-r--r--spec/ruby/core/enumerator/lazy/collect_concat_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/collect_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/drop_spec.rb10
-rw-r--r--spec/ruby/core/enumerator/lazy/drop_while_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/lazy/eager_spec.rb29
-rw-r--r--spec/ruby/core/enumerator/lazy/enum_for_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/filter_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/find_all_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/flat_map_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/lazy/force_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/lazy/grep_spec.rb43
-rw-r--r--spec/ruby/core/enumerator/lazy/grep_v_spec.rb161
-rw-r--r--spec/ruby/core/enumerator/lazy/initialize_spec.rb10
-rw-r--r--spec/ruby/core/enumerator/lazy/lazy_spec.rb14
-rw-r--r--spec/ruby/core/enumerator/lazy/map_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/reject_spec.rb24
-rw-r--r--spec/ruby/core/enumerator/lazy/select_spec.rb43
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/collect.rb10
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/collect_concat.rb12
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/select.rb12
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/to_enum.rb9
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_after_spec.rb9
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_before_spec.rb9
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_when_spec.rb9
-rw-r--r--spec/ruby/core/enumerator/lazy/take_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/take_while_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/lazy/to_enum_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/uniq_spec.rb93
-rw-r--r--spec/ruby/core/enumerator/lazy/zip_spec.rb18
-rw-r--r--spec/ruby/core/enumerator/new_spec.rb120
-rw-r--r--spec/ruby/core/enumerator/next_spec.rb38
-rw-r--r--spec/ruby/core/enumerator/next_values_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/peek_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/peek_values_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/plus_spec.rb35
-rw-r--r--spec/ruby/core/enumerator/produce_spec.rb36
-rw-r--r--spec/ruby/core/enumerator/rewind_spec.rb42
-rw-r--r--spec/ruby/core/enumerator/size_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/to_enum_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/with_index_spec.rb16
-rw-r--r--spec/ruby/core/enumerator/with_object_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/yielder/append_spec.rb30
-rw-r--r--spec/ruby/core/enumerator/yielder/initialize_spec.rb2
-rw-r--r--spec/ruby/core/enumerator/yielder/to_proc_spec.rb18
-rw-r--r--spec/ruby/core/enumerator/yielder/yield_spec.rb19
-rw-r--r--spec/ruby/core/env/assoc_spec.rb12
-rw-r--r--spec/ruby/core/env/clear_spec.rb4
-rw-r--r--spec/ruby/core/env/delete_if_spec.rb41
-rw-r--r--spec/ruby/core/env/delete_spec.rb29
-rw-r--r--spec/ruby/core/env/each_key_spec.rb10
-rw-r--r--spec/ruby/core/env/each_pair_spec.rb6
-rw-r--r--spec/ruby/core/env/each_spec.rb6
-rw-r--r--spec/ruby/core/env/each_value_spec.rb12
-rw-r--r--spec/ruby/core/env/element_reference_spec.rb70
-rw-r--r--spec/ruby/core/env/element_set_spec.rb6
-rw-r--r--spec/ruby/core/env/empty_spec.rb8
-rw-r--r--spec/ruby/core/env/fetch_spec.rb48
-rw-r--r--spec/ruby/core/env/filter_spec.rb15
-rw-r--r--spec/ruby/core/env/has_key_spec.rb6
-rw-r--r--spec/ruby/core/env/has_value_spec.rb6
-rw-r--r--spec/ruby/core/env/include_spec.rb6
-rw-r--r--spec/ruby/core/env/index_spec.rb16
-rw-r--r--spec/ruby/core/env/indexes_spec.rb2
-rw-r--r--spec/ruby/core/env/indices_spec.rb2
-rw-r--r--spec/ruby/core/env/inspect_spec.rb2
-rw-r--r--spec/ruby/core/env/invert_spec.rb2
-rw-r--r--spec/ruby/core/env/keep_if_spec.rb35
-rw-r--r--spec/ruby/core/env/key_spec.rb10
-rw-r--r--spec/ruby/core/env/keys_spec.rb6
-rw-r--r--spec/ruby/core/env/length_spec.rb6
-rw-r--r--spec/ruby/core/env/member_spec.rb6
-rw-r--r--spec/ruby/core/env/merge_spec.rb8
-rw-r--r--spec/ruby/core/env/rassoc_spec.rb23
-rw-r--r--spec/ruby/core/env/rehash_spec.rb8
-rw-r--r--spec/ruby/core/env/reject_spec.rb38
-rw-r--r--spec/ruby/core/env/replace_spec.rb52
-rw-r--r--spec/ruby/core/env/select_spec.rb36
-rw-r--r--spec/ruby/core/env/shared/each.rb58
-rw-r--r--spec/ruby/core/env/shared/include.rb16
-rw-r--r--spec/ruby/core/env/shared/key.rb28
-rw-r--r--spec/ruby/core/env/shared/select.rb61
-rw-r--r--spec/ruby/core/env/shared/store.rb14
-rw-r--r--spec/ruby/core/env/shared/to_hash.rb19
-rw-r--r--spec/ruby/core/env/shared/update.rb100
-rw-r--r--spec/ruby/core/env/shared/value.rb15
-rw-r--r--spec/ruby/core/env/shift_spec.rb53
-rw-r--r--spec/ruby/core/env/size_spec.rb6
-rw-r--r--spec/ruby/core/env/slice_spec.rb29
-rw-r--r--spec/ruby/core/env/spec_helper.rb26
-rw-r--r--spec/ruby/core/env/store_spec.rb6
-rw-r--r--spec/ruby/core/env/to_a_spec.rb11
-rw-r--r--spec/ruby/core/env/to_h_spec.rb62
-rw-r--r--spec/ruby/core/env/to_hash_spec.rb6
-rw-r--r--spec/ruby/core/env/to_s_spec.rb2
-rw-r--r--spec/ruby/core/env/update_spec.rb25
-rw-r--r--spec/ruby/core/env/value_spec.rb6
-rw-r--r--spec/ruby/core/env/values_at_spec.rb33
-rw-r--r--spec/ruby/core/env/values_spec.rb13
-rw-r--r--spec/ruby/core/exception/args_spec.rb5
-rw-r--r--spec/ruby/core/exception/arguments_spec.rb11
-rw-r--r--spec/ruby/core/exception/backtrace_locations_spec.rb39
-rw-r--r--spec/ruby/core/exception/backtrace_spec.rb33
-rw-r--r--spec/ruby/core/exception/case_compare_spec.rb38
-rw-r--r--spec/ruby/core/exception/cause_spec.rb39
-rw-r--r--spec/ruby/core/exception/destination_encoding_name_spec.rb9
-rw-r--r--spec/ruby/core/exception/destination_encoding_spec.rb9
-rw-r--r--spec/ruby/core/exception/dup_spec.rb74
-rw-r--r--spec/ruby/core/exception/equal_value_spec.rb4
-rw-r--r--spec/ruby/core/exception/errno_spec.rb22
-rw-r--r--spec/ruby/core/exception/error_bytes_spec.rb5
-rw-r--r--spec/ruby/core/exception/error_char_spec.rb5
-rw-r--r--spec/ruby/core/exception/exception_spec.rb78
-rw-r--r--spec/ruby/core/exception/exit_value_spec.rb12
-rw-r--r--spec/ruby/core/exception/fixtures/common.rb33
-rw-r--r--spec/ruby/core/exception/frozen_error_spec.rb26
-rw-r--r--spec/ruby/core/exception/full_message_spec.rb92
-rw-r--r--spec/ruby/core/exception/hierarchy_spec.rb62
-rw-r--r--spec/ruby/core/exception/incomplete_input_spec.rb5
-rw-r--r--spec/ruby/core/exception/initialize_spec.rb1
-rw-r--r--spec/ruby/core/exception/inspect_spec.rb8
-rw-r--r--spec/ruby/core/exception/interrupt_spec.rb10
-rw-r--r--spec/ruby/core/exception/io_error_spec.rb8
-rw-r--r--spec/ruby/core/exception/key_error_spec.rb21
-rw-r--r--spec/ruby/core/exception/load_error_spec.rb2
-rw-r--r--spec/ruby/core/exception/message_spec.rb4
-rw-r--r--spec/ruby/core/exception/name_error_spec.rb31
-rw-r--r--spec/ruby/core/exception/name_spec.rb44
-rw-r--r--spec/ruby/core/exception/new_spec.rb8
-rw-r--r--spec/ruby/core/exception/no_method_error_spec.rb89
-rw-r--r--spec/ruby/core/exception/range_error_spec.rb7
-rw-r--r--spec/ruby/core/exception/readagain_bytes_spec.rb5
-rw-r--r--spec/ruby/core/exception/reason_spec.rb12
-rw-r--r--spec/ruby/core/exception/receiver_spec.rb116
-rw-r--r--spec/ruby/core/exception/result_spec.rb10
-rw-r--r--spec/ruby/core/exception/script_error_spec.rb15
-rw-r--r--spec/ruby/core/exception/set_backtrace_spec.rb12
-rw-r--r--spec/ruby/core/exception/signal_exception_spec.rb63
-rw-r--r--spec/ruby/core/exception/signm_spec.rb8
-rw-r--r--spec/ruby/core/exception/signo_spec.rb8
-rw-r--r--spec/ruby/core/exception/source_encoding_name_spec.rb9
-rw-r--r--spec/ruby/core/exception/source_encoding_spec.rb9
-rw-r--r--spec/ruby/core/exception/standard_error_spec.rb57
-rw-r--r--spec/ruby/core/exception/status_spec.rb8
-rw-r--r--spec/ruby/core/exception/success_spec.rb14
-rw-r--r--spec/ruby/core/exception/system_call_error_spec.rb90
-rw-r--r--spec/ruby/core/exception/system_exit_spec.rb17
-rw-r--r--spec/ruby/core/exception/system_stack_error_spec.rb7
-rw-r--r--spec/ruby/core/exception/to_s_spec.rb20
-rw-r--r--spec/ruby/core/exception/top_level_spec.rb47
-rw-r--r--spec/ruby/core/exception/uncaught_throw_error_spec.rb9
-rw-r--r--spec/ruby/core/false/and_spec.rb2
-rw-r--r--spec/ruby/core/false/dup_spec.rb7
-rw-r--r--spec/ruby/core/false/falseclass_spec.rb6
-rw-r--r--spec/ruby/core/false/inspect_spec.rb2
-rw-r--r--spec/ruby/core/false/or_spec.rb2
-rw-r--r--spec/ruby/core/false/to_s_spec.rb12
-rw-r--r--spec/ruby/core/false/xor_spec.rb2
-rw-r--r--spec/ruby/core/fiber/fixtures/classes.rb12
-rw-r--r--spec/ruby/core/fiber/new_spec.rb62
-rw-r--r--spec/ruby/core/fiber/raise_spec.rb101
-rw-r--r--spec/ruby/core/fiber/resume_spec.rb113
-rw-r--r--spec/ruby/core/fiber/yield_spec.rb80
-rw-r--r--spec/ruby/core/file/absolute_path_spec.rb61
-rw-r--r--spec/ruby/core/file/atime_spec.rb6
-rw-r--r--spec/ruby/core/file/basename_spec.rb30
-rw-r--r--spec/ruby/core/file/birthtime_spec.rb16
-rw-r--r--spec/ruby/core/file/blockdev_spec.rb4
-rw-r--r--spec/ruby/core/file/chardev_spec.rb4
-rw-r--r--spec/ruby/core/file/chmod_spec.rb182
-rw-r--r--spec/ruby/core/file/chown_spec.rb28
-rw-r--r--spec/ruby/core/file/constants/constants_spec.rb2
-rw-r--r--spec/ruby/core/file/constants_spec.rb2
-rw-r--r--spec/ruby/core/file/ctime_spec.rb6
-rw-r--r--spec/ruby/core/file/delete_spec.rb6
-rw-r--r--spec/ruby/core/file/directory_spec.rb4
-rw-r--r--spec/ruby/core/file/dirname_spec.rb10
-rw-r--r--spec/ruby/core/file/empty_spec.rb13
-rw-r--r--spec/ruby/core/file/executable_real_spec.rb4
-rw-r--r--spec/ruby/core/file/executable_spec.rb4
-rw-r--r--spec/ruby/core/file/exist_spec.rb6
-rw-r--r--spec/ruby/core/file/exists_spec.rb6
-rw-r--r--spec/ruby/core/file/expand_path_spec.rb183
-rw-r--r--spec/ruby/core/file/extname_spec.rb54
-rw-r--r--spec/ruby/core/file/file_spec.rb4
-rw-r--r--spec/ruby/core/file/fixtures/file_types.rb36
-rw-r--r--spec/ruby/core/file/flock_spec.rb6
-rw-r--r--spec/ruby/core/file/fnmatch_spec.rb8
-rw-r--r--spec/ruby/core/file/ftype_spec.rb21
-rw-r--r--spec/ruby/core/file/grpowned_spec.rb4
-rw-r--r--spec/ruby/core/file/identical_spec.rb4
-rw-r--r--spec/ruby/core/file/initialize_spec.rb6
-rw-r--r--spec/ruby/core/file/inspect_spec.rb2
-rw-r--r--spec/ruby/core/file/join_spec.rb19
-rw-r--r--spec/ruby/core/file/lchmod_spec.rb24
-rw-r--r--spec/ruby/core/file/lchown_spec.rb6
-rw-r--r--spec/ruby/core/file/link_spec.rb18
-rw-r--r--spec/ruby/core/file/lstat_spec.rb8
-rw-r--r--spec/ruby/core/file/lutime_spec.rb38
-rw-r--r--spec/ruby/core/file/mkfifo_spec.rb74
-rw-r--r--spec/ruby/core/file/mtime_spec.rb8
-rw-r--r--spec/ruby/core/file/new_spec.rb46
-rw-r--r--spec/ruby/core/file/null_spec.rb2
-rw-r--r--spec/ruby/core/file/open_spec.rb276
-rw-r--r--spec/ruby/core/file/owned_spec.rb12
-rw-r--r--spec/ruby/core/file/path_spec.rb33
-rw-r--r--spec/ruby/core/file/pipe_spec.rb6
-rw-r--r--spec/ruby/core/file/printf_spec.rb18
-rw-r--r--spec/ruby/core/file/read_spec.rb4
-rw-r--r--spec/ruby/core/file/readable_real_spec.rb4
-rw-r--r--spec/ruby/core/file/readable_spec.rb4
-rw-r--r--spec/ruby/core/file/readlink_spec.rb29
-rw-r--r--spec/ruby/core/file/realdirpath_spec.rb8
-rw-r--r--spec/ruby/core/file/realpath_spec.rb14
-rw-r--r--spec/ruby/core/file/rename_spec.rb18
-rw-r--r--spec/ruby/core/file/reopen_spec.rb4
-rw-r--r--spec/ruby/core/file/setgid_spec.rb4
-rw-r--r--spec/ruby/core/file/setuid_spec.rb4
-rw-r--r--spec/ruby/core/file/shared/fnmatch.rb26
-rw-r--r--spec/ruby/core/file/shared/open.rb2
-rw-r--r--spec/ruby/core/file/shared/path.rb92
-rw-r--r--spec/ruby/core/file/shared/read.rb10
-rw-r--r--spec/ruby/core/file/shared/stat.rb2
-rw-r--r--spec/ruby/core/file/shared/unlink.rb26
-rw-r--r--spec/ruby/core/file/size_spec.rb10
-rw-r--r--spec/ruby/core/file/socket_spec.rb4
-rw-r--r--spec/ruby/core/file/split_spec.rb13
-rw-r--r--spec/ruby/core/file/stat/atime_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/birthtime_spec.rb4
-rw-r--r--spec/ruby/core/file/stat/blksize_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/blockdev_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/blocks_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/chardev_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/comparison_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/ctime_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/dev_major_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/dev_minor_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/dev_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/directory_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/executable_real_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/executable_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/file_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/ftype_spec.rb8
-rw-r--r--spec/ruby/core/file/stat/gid_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/grpowned_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/ino_spec.rb20
-rw-r--r--spec/ruby/core/file/stat/inspect_spec.rb8
-rw-r--r--spec/ruby/core/file/stat/mode_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/mtime_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/new_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/nlink_spec.rb4
-rw-r--r--spec/ruby/core/file/stat/owned_spec.rb20
-rw-r--r--spec/ruby/core/file/stat/pipe_spec.rb12
-rw-r--r--spec/ruby/core/file/stat/rdev_major_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/rdev_minor_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/rdev_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/readable_real_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/readable_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/setgid_spec.rb10
-rw-r--r--spec/ruby/core/file/stat/setuid_spec.rb10
-rw-r--r--spec/ruby/core/file/stat/size_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/socket_spec.rb10
-rw-r--r--spec/ruby/core/file/stat/sticky_spec.rb10
-rw-r--r--spec/ruby/core/file/stat/symlink_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/uid_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/world_readable_spec.rb8
-rw-r--r--spec/ruby/core/file/stat/world_writable_spec.rb8
-rw-r--r--spec/ruby/core/file/stat/writable_real_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/writable_spec.rb6
-rw-r--r--spec/ruby/core/file/stat/zero_spec.rb6
-rw-r--r--spec/ruby/core/file/stat_spec.rb22
-rw-r--r--spec/ruby/core/file/sticky_spec.rb6
-rw-r--r--spec/ruby/core/file/symlink_spec.rb16
-rw-r--r--spec/ruby/core/file/to_path_spec.rb49
-rw-r--r--spec/ruby/core/file/truncate_spec.rb32
-rw-r--r--spec/ruby/core/file/umask_spec.rb27
-rw-r--r--spec/ruby/core/file/unlink_spec.rb6
-rw-r--r--spec/ruby/core/file/utime_spec.rb71
-rw-r--r--spec/ruby/core/file/world_readable_spec.rb8
-rw-r--r--spec/ruby/core/file/world_writable_spec.rb8
-rw-r--r--spec/ruby/core/file/writable_real_spec.rb4
-rw-r--r--spec/ruby/core/file/writable_spec.rb4
-rw-r--r--spec/ruby/core/file/zero_spec.rb4
-rw-r--r--spec/ruby/core/filetest/blockdev_spec.rb4
-rw-r--r--spec/ruby/core/filetest/chardev_spec.rb4
-rw-r--r--spec/ruby/core/filetest/directory_spec.rb4
-rw-r--r--spec/ruby/core/filetest/executable_real_spec.rb4
-rw-r--r--spec/ruby/core/filetest/executable_spec.rb4
-rw-r--r--spec/ruby/core/filetest/exist_spec.rb4
-rw-r--r--spec/ruby/core/filetest/exists_spec.rb6
-rw-r--r--spec/ruby/core/filetest/file_spec.rb4
-rw-r--r--spec/ruby/core/filetest/grpowned_spec.rb4
-rw-r--r--spec/ruby/core/filetest/identical_spec.rb4
-rw-r--r--spec/ruby/core/filetest/owned_spec.rb8
-rw-r--r--spec/ruby/core/filetest/pipe_spec.rb8
-rw-r--r--spec/ruby/core/filetest/readable_real_spec.rb4
-rw-r--r--spec/ruby/core/filetest/readable_spec.rb4
-rw-r--r--spec/ruby/core/filetest/setgid_spec.rb8
-rw-r--r--spec/ruby/core/filetest/setuid_spec.rb8
-rw-r--r--spec/ruby/core/filetest/size_spec.rb4
-rw-r--r--spec/ruby/core/filetest/socket_spec.rb8
-rw-r--r--spec/ruby/core/filetest/sticky_spec.rb4
-rw-r--r--spec/ruby/core/filetest/symlink_spec.rb4
-rw-r--r--spec/ruby/core/filetest/world_readable_spec.rb2
-rw-r--r--spec/ruby/core/filetest/world_writable_spec.rb2
-rw-r--r--spec/ruby/core/filetest/writable_real_spec.rb4
-rw-r--r--spec/ruby/core/filetest/writable_spec.rb4
-rw-r--r--spec/ruby/core/filetest/zero_spec.rb4
-rw-r--r--spec/ruby/core/fixnum/abs_spec.rb7
-rw-r--r--spec/ruby/core/fixnum/bit_and_spec.rb46
-rw-r--r--spec/ruby/core/fixnum/bit_length_spec.rb42
-rw-r--r--spec/ruby/core/fixnum/bit_or_spec.rb26
-rw-r--r--spec/ruby/core/fixnum/bit_xor_spec.rb24
-rw-r--r--spec/ruby/core/fixnum/case_compare_spec.rb6
-rw-r--r--spec/ruby/core/fixnum/coerce_spec.rb39
-rw-r--r--spec/ruby/core/fixnum/comparison_spec.rb26
-rw-r--r--spec/ruby/core/fixnum/complement_spec.rb10
-rw-r--r--spec/ruby/core/fixnum/div_spec.rb44
-rw-r--r--spec/ruby/core/fixnum/divide_spec.rb35
-rw-r--r--spec/ruby/core/fixnum/divmod_spec.rb35
-rw-r--r--spec/ruby/core/fixnum/element_reference_spec.rb80
-rw-r--r--spec/ruby/core/fixnum/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/fixnum/even_spec.rb23
-rw-r--r--spec/ruby/core/fixnum/exponent_spec.rb76
-rw-r--r--spec/ruby/core/fixnum/fdiv_spec.rb49
-rw-r--r--spec/ruby/core/fixnum/fixnum_spec.rb19
-rw-r--r--spec/ruby/core/fixnum/gt_spec.rb19
-rw-r--r--spec/ruby/core/fixnum/gte_spec.rb20
-rw-r--r--spec/ruby/core/fixnum/hash_spec.rb11
-rw-r--r--spec/ruby/core/fixnum/left_shift_spec.rb91
-rw-r--r--spec/ruby/core/fixnum/lt_spec.rb19
-rw-r--r--spec/ruby/core/fixnum/lte_spec.rb20
-rw-r--r--spec/ruby/core/fixnum/magnitude_spec.rb6
-rw-r--r--spec/ruby/core/fixnum/minus_spec.rb29
-rw-r--r--spec/ruby/core/fixnum/modulo_spec.rb10
-rw-r--r--spec/ruby/core/fixnum/multiply_spec.rb27
-rw-r--r--spec/ruby/core/fixnum/odd_spec.rb23
-rw-r--r--spec/ruby/core/fixnum/plus_spec.rb29
-rw-r--r--spec/ruby/core/fixnum/right_shift_spec.rb91
-rw-r--r--spec/ruby/core/fixnum/shared/abs.rb9
-rw-r--r--spec/ruby/core/fixnum/shared/equal.rb24
-rw-r--r--spec/ruby/core/fixnum/shared/modulo.rb42
-rw-r--r--spec/ruby/core/fixnum/size_spec.rb19
-rw-r--r--spec/ruby/core/fixnum/succ_spec.rb15
-rw-r--r--spec/ruby/core/fixnum/to_f_spec.rb9
-rw-r--r--spec/ruby/core/fixnum/to_s_spec.rb50
-rw-r--r--spec/ruby/core/fixnum/uminus_spec.rb16
-rw-r--r--spec/ruby/core/fixnum/zero_spec.rb9
-rw-r--r--spec/ruby/core/float/abs_spec.rb5
-rw-r--r--spec/ruby/core/float/angle_spec.rb3
-rw-r--r--spec/ruby/core/float/arg_spec.rb3
-rw-r--r--spec/ruby/core/float/case_compare_spec.rb4
-rw-r--r--spec/ruby/core/float/ceil_spec.rb10
-rw-r--r--spec/ruby/core/float/coerce_spec.rb2
-rw-r--r--spec/ruby/core/float/comparison_spec.rb36
-rw-r--r--spec/ruby/core/float/constants_spec.rb2
-rw-r--r--spec/ruby/core/float/denominator_spec.rb2
-rw-r--r--spec/ruby/core/float/divide_spec.rb11
-rw-r--r--spec/ruby/core/float/divmod_spec.rb12
-rw-r--r--spec/ruby/core/float/dup_spec.rb8
-rw-r--r--spec/ruby/core/float/eql_spec.rb2
-rw-r--r--spec/ruby/core/float/equal_value_spec.rb4
-rw-r--r--spec/ruby/core/float/exponent_spec.rb2
-rw-r--r--spec/ruby/core/float/fdiv_spec.rb4
-rw-r--r--spec/ruby/core/float/finite_spec.rb10
-rw-r--r--spec/ruby/core/float/fixtures/classes.rb4
-rw-r--r--spec/ruby/core/float/float_spec.rb6
-rw-r--r--spec/ruby/core/float/floor_spec.rb10
-rw-r--r--spec/ruby/core/float/gt_spec.rb9
-rw-r--r--spec/ruby/core/float/gte_spec.rb9
-rw-r--r--spec/ruby/core/float/hash_spec.rb2
-rw-r--r--spec/ruby/core/float/infinite_spec.rb2
-rw-r--r--spec/ruby/core/float/inspect_spec.rb6
-rw-r--r--spec/ruby/core/float/lt_spec.rb9
-rw-r--r--spec/ruby/core/float/lte_spec.rb9
-rw-r--r--spec/ruby/core/float/magnitude_spec.rb4
-rw-r--r--spec/ruby/core/float/minus_spec.rb5
-rw-r--r--spec/ruby/core/float/modulo_spec.rb8
-rw-r--r--spec/ruby/core/float/multiply_spec.rb9
-rw-r--r--spec/ruby/core/float/nan_spec.rb8
-rw-r--r--spec/ruby/core/float/negative_spec.rb33
-rw-r--r--spec/ruby/core/float/next_float_spec.rb4
-rw-r--r--spec/ruby/core/float/numerator_spec.rb2
-rw-r--r--spec/ruby/core/float/phase_spec.rb3
-rw-r--r--spec/ruby/core/float/plus_spec.rb5
-rw-r--r--spec/ruby/core/float/positive_spec.rb33
-rw-r--r--spec/ruby/core/float/prev_float_spec.rb4
-rw-r--r--spec/ruby/core/float/quo_spec.rb4
-rw-r--r--spec/ruby/core/float/rationalize_spec.rb10
-rw-r--r--spec/ruby/core/float/round_spec.rb79
-rw-r--r--spec/ruby/core/float/shared/abs.rb2
-rw-r--r--spec/ruby/core/float/shared/arg.rb36
-rw-r--r--spec/ruby/core/float/shared/arithmetic_exception_in_coerce.rb11
-rw-r--r--spec/ruby/core/float/shared/comparison_exception_in_coerce.rb11
-rw-r--r--spec/ruby/core/float/shared/modulo.rb4
-rw-r--r--spec/ruby/core/float/shared/quo.rb8
-rw-r--r--spec/ruby/core/float/shared/to_s.rb308
-rw-r--r--spec/ruby/core/float/to_f_spec.rb2
-rw-r--r--spec/ruby/core/float/to_i_spec.rb6
-rw-r--r--spec/ruby/core/float/to_int_spec.rb6
-rw-r--r--spec/ruby/core/float/to_r_spec.rb2
-rw-r--r--spec/ruby/core/float/to_s_spec.rb120
-rw-r--r--spec/ruby/core/float/truncate_spec.rb14
-rw-r--r--spec/ruby/core/float/uminus_spec.rb4
-rw-r--r--spec/ruby/core/float/uplus_spec.rb2
-rw-r--r--spec/ruby/core/float/zero_spec.rb8
-rw-r--r--spec/ruby/core/gc/count_spec.rb12
-rw-r--r--spec/ruby/core/gc/disable_spec.rb2
-rw-r--r--spec/ruby/core/gc/enable_spec.rb2
-rw-r--r--spec/ruby/core/gc/garbage_collect_spec.rb2
-rw-r--r--spec/ruby/core/gc/profiler/clear_spec.rb2
-rw-r--r--spec/ruby/core/gc/profiler/disable_spec.rb4
-rw-r--r--spec/ruby/core/gc/profiler/enable_spec.rb4
-rw-r--r--spec/ruby/core/gc/profiler/enabled_spec.rb2
-rw-r--r--spec/ruby/core/gc/profiler/report_spec.rb2
-rw-r--r--spec/ruby/core/gc/profiler/result_spec.rb2
-rw-r--r--spec/ruby/core/gc/profiler/total_time_spec.rb2
-rw-r--r--spec/ruby/core/gc/start_spec.rb6
-rw-r--r--spec/ruby/core/gc/stat_spec.rb16
-rw-r--r--spec/ruby/core/gc/stress_spec.rb2
-rw-r--r--spec/ruby/core/hash/allocate_spec.rb2
-rw-r--r--spec/ruby/core/hash/any_spec.rb6
-rw-r--r--spec/ruby/core/hash/assoc_spec.rb2
-rw-r--r--spec/ruby/core/hash/clear_spec.rb10
-rw-r--r--spec/ruby/core/hash/clone_spec.rb5
-rw-r--r--spec/ruby/core/hash/compact_spec.rb88
-rw-r--r--spec/ruby/core/hash/compare_by_identity_spec.rb24
-rw-r--r--spec/ruby/core/hash/constructor_spec.rb37
-rw-r--r--spec/ruby/core/hash/deconstruct_keys_spec.rb25
-rw-r--r--spec/ruby/core/hash/default_proc_spec.rb24
-rw-r--r--spec/ruby/core/hash/default_spec.rb12
-rw-r--r--spec/ruby/core/hash/delete_if_spec.rb18
-rw-r--r--spec/ruby/core/hash/delete_spec.rb14
-rw-r--r--spec/ruby/core/hash/dig_spec.rb108
-rw-r--r--spec/ruby/core/hash/each_key_spec.rb12
-rw-r--r--spec/ruby/core/hash/each_pair_spec.rb16
-rw-r--r--spec/ruby/core/hash/each_spec.rb16
-rw-r--r--spec/ruby/core/hash/each_value_spec.rb12
-rw-r--r--spec/ruby/core/hash/element_reference_spec.rb18
-rw-r--r--spec/ruby/core/hash/element_set_spec.rb8
-rw-r--r--spec/ruby/core/hash/empty_spec.rb14
-rw-r--r--spec/ruby/core/hash/eql_spec.rb6
-rw-r--r--spec/ruby/core/hash/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/hash/except_spec.rb34
-rw-r--r--spec/ruby/core/hash/fetch_spec.rb30
-rw-r--r--spec/ruby/core/hash/fetch_values_spec.rb48
-rw-r--r--spec/ruby/core/hash/filter_spec.rb12
-rw-r--r--spec/ruby/core/hash/fixtures/classes.rb7
-rw-r--r--spec/ruby/core/hash/fixtures/name.rb30
-rw-r--r--spec/ruby/core/hash/flatten_spec.rb4
-rw-r--r--spec/ruby/core/hash/gt_spec.rb66
-rw-r--r--spec/ruby/core/hash/gte_spec.rb66
-rw-r--r--spec/ruby/core/hash/has_key_spec.rb9
-rw-r--r--spec/ruby/core/hash/has_value_spec.rb9
-rw-r--r--spec/ruby/core/hash/hash_spec.rb10
-rw-r--r--spec/ruby/core/hash/include_spec.rb8
-rw-r--r--spec/ruby/core/hash/index_spec.rb12
-rw-r--r--spec/ruby/core/hash/initialize_spec.rb45
-rw-r--r--spec/ruby/core/hash/inspect_spec.rb6
-rw-r--r--spec/ruby/core/hash/invert_spec.rb4
-rw-r--r--spec/ruby/core/hash/keep_if_spec.rb18
-rw-r--r--spec/ruby/core/hash/key_spec.rb12
-rw-r--r--spec/ruby/core/hash/keys_spec.rb4
-rw-r--r--spec/ruby/core/hash/length_spec.rb8
-rw-r--r--spec/ruby/core/hash/lt_spec.rb66
-rw-r--r--spec/ruby/core/hash/lte_spec.rb66
-rw-r--r--spec/ruby/core/hash/member_spec.rb8
-rw-r--r--spec/ruby/core/hash/merge_spec.rb51
-rw-r--r--spec/ruby/core/hash/new_spec.rb10
-rw-r--r--spec/ruby/core/hash/rassoc_spec.rb2
-rw-r--r--spec/ruby/core/hash/rehash_spec.rb48
-rw-r--r--spec/ruby/core/hash/reject_spec.rb32
-rw-r--r--spec/ruby/core/hash/replace_spec.rb8
-rw-r--r--spec/ruby/core/hash/ruby2_keywords_hash_spec.rb47
-rw-r--r--spec/ruby/core/hash/select_spec.rb81
-rw-r--r--spec/ruby/core/hash/shared/comparison.rb6
-rw-r--r--spec/ruby/core/hash/shared/each.rb35
-rw-r--r--spec/ruby/core/hash/shared/eql.rb96
-rw-r--r--spec/ruby/core/hash/shared/index.rb4
-rw-r--r--spec/ruby/core/hash/shared/replace.rb14
-rw-r--r--spec/ruby/core/hash/shared/select.rb91
-rw-r--r--spec/ruby/core/hash/shared/store.rb27
-rw-r--r--spec/ruby/core/hash/shared/to_s.rb41
-rw-r--r--spec/ruby/core/hash/shared/update.rb33
-rw-r--r--spec/ruby/core/hash/shift_spec.rb25
-rw-r--r--spec/ruby/core/hash/size_spec.rb8
-rw-r--r--spec/ruby/core/hash/slice_spec.rb53
-rw-r--r--spec/ruby/core/hash/sort_spec.rb4
-rw-r--r--spec/ruby/core/hash/store_spec.rb8
-rw-r--r--spec/ruby/core/hash/to_a_spec.rb16
-rw-r--r--spec/ruby/core/hash/to_h_spec.rb44
-rw-r--r--spec/ruby/core/hash/to_hash_spec.rb4
-rw-r--r--spec/ruby/core/hash/to_proc_spec.rb128
-rw-r--r--spec/ruby/core/hash/to_s_spec.rb6
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb140
-rw-r--r--spec/ruby/core/hash/transform_values_spec.rb126
-rw-r--r--spec/ruby/core/hash/try_convert_spec.rb8
-rw-r--r--spec/ruby/core/hash/update_spec.rb8
-rw-r--r--spec/ruby/core/hash/value_spec.rb9
-rw-r--r--spec/ruby/core/hash/values_at_spec.rb8
-rw-r--r--spec/ruby/core/hash/values_spec.rb4
-rw-r--r--spec/ruby/core/integer/abs_spec.rb6
-rw-r--r--spec/ruby/core/integer/allbits_spec.rb37
-rw-r--r--spec/ruby/core/integer/anybits_spec.rb36
-rw-r--r--spec/ruby/core/integer/bit_and_spec.rb97
-rw-r--r--spec/ruby/core/integer/bit_length_spec.rb76
-rw-r--r--spec/ruby/core/integer/bit_or_spec.rb68
-rw-r--r--spec/ruby/core/integer/bit_xor_spec.rb72
-rw-r--r--spec/ruby/core/integer/case_compare_spec.rb6
-rw-r--r--spec/ruby/core/integer/ceil_spec.rb19
-rw-r--r--spec/ruby/core/integer/chr_spec.rb67
-rw-r--r--spec/ruby/core/integer/coerce_spec.rb104
-rw-r--r--spec/ruby/core/integer/comparison_spec.rb177
-rw-r--r--spec/ruby/core/integer/complement_spec.rb20
-rw-r--r--spec/ruby/core/integer/constants_spec.rb27
-rw-r--r--spec/ruby/core/integer/denominator_spec.rb4
-rw-r--r--spec/ruby/core/integer/digits_spec.rb32
-rw-r--r--spec/ruby/core/integer/div_spec.rb146
-rw-r--r--spec/ruby/core/integer/divide_spec.rb89
-rw-r--r--spec/ruby/core/integer/divmod_spec.rb117
-rw-r--r--spec/ruby/core/integer/downto_spec.rb12
-rw-r--r--spec/ruby/core/integer/dup_spec.rb13
-rw-r--r--spec/ruby/core/integer/element_reference_spec.rb196
-rw-r--r--spec/ruby/core/integer/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/integer/even_spec.rb44
-rw-r--r--spec/ruby/core/integer/exponent_spec.rb7
-rw-r--r--spec/ruby/core/integer/fdiv_spec.rb49
-rw-r--r--spec/ruby/core/integer/fixtures/classes.rb4
-rw-r--r--spec/ruby/core/integer/floor_spec.rb19
-rw-r--r--spec/ruby/core/integer/gcd_spec.rb29
-rw-r--r--spec/ruby/core/integer/gcdlcm_spec.rb18
-rw-r--r--spec/ruby/core/integer/gt_spec.rb43
-rw-r--r--spec/ruby/core/integer/gte_spec.rb43
-rw-r--r--spec/ruby/core/integer/integer_spec.rb13
-rw-r--r--spec/ruby/core/integer/lcm_spec.rb18
-rw-r--r--spec/ruby/core/integer/left_shift_spec.rb168
-rw-r--r--spec/ruby/core/integer/lt_spec.rb45
-rw-r--r--spec/ruby/core/integer/lte_spec.rb53
-rw-r--r--spec/ruby/core/integer/magnitude_spec.rb6
-rw-r--r--spec/ruby/core/integer/minus_spec.rb43
-rw-r--r--spec/ruby/core/integer/modulo_spec.rb10
-rw-r--r--spec/ruby/core/integer/multiply_spec.rb45
-rw-r--r--spec/ruby/core/integer/next_spec.rb6
-rw-r--r--spec/ruby/core/integer/nobits_spec.rb36
-rw-r--r--spec/ruby/core/integer/numerator_spec.rb2
-rw-r--r--spec/ruby/core/integer/odd_spec.rb42
-rw-r--r--spec/ruby/core/integer/ord_spec.rb2
-rw-r--r--spec/ruby/core/integer/plus_spec.rb43
-rw-r--r--spec/ruby/core/integer/pow_spec.rb51
-rw-r--r--spec/ruby/core/integer/pred_spec.rb2
-rw-r--r--spec/ruby/core/integer/rationalize_spec.rb6
-rw-r--r--spec/ruby/core/integer/remainder_spec.rb51
-rw-r--r--spec/ruby/core/integer/right_shift_spec.rb194
-rw-r--r--spec/ruby/core/integer/round_spec.rb68
-rw-r--r--spec/ruby/core/integer/shared/abs.rb18
-rw-r--r--spec/ruby/core/integer/shared/arithmetic_coerce.rb31
-rw-r--r--spec/ruby/core/integer/shared/comparison_coerce.rb11
-rw-r--r--spec/ruby/core/integer/shared/equal.rb58
-rw-r--r--spec/ruby/core/integer/shared/exponent.rb118
-rw-r--r--spec/ruby/core/integer/shared/integer_rounding.rb19
-rw-r--r--spec/ruby/core/integer/shared/modulo.rb74
-rw-r--r--spec/ruby/core/integer/shared/next.rb12
-rw-r--r--spec/ruby/core/integer/size_spec.rb34
-rw-r--r--spec/ruby/core/integer/sqrt_spec.rb31
-rw-r--r--spec/ruby/core/integer/succ_spec.rb6
-rw-r--r--spec/ruby/core/integer/times_spec.rb2
-rw-r--r--spec/ruby/core/integer/to_f_spec.rb23
-rw-r--r--spec/ruby/core/integer/to_i_spec.rb6
-rw-r--r--spec/ruby/core/integer/to_int_spec.rb6
-rw-r--r--spec/ruby/core/integer/to_r_spec.rb10
-rw-r--r--spec/ruby/core/integer/to_s_spec.rb95
-rw-r--r--spec/ruby/core/integer/truncate_spec.rb19
-rw-r--r--spec/ruby/core/integer/uminus_spec.rb30
-rw-r--r--spec/ruby/core/integer/upto_spec.rb12
-rw-r--r--spec/ruby/core/io/advise_spec.rb23
-rw-r--r--spec/ruby/core/io/binmode_spec.rb6
-rw-r--r--spec/ruby/core/io/binread_spec.rb20
-rw-r--r--spec/ruby/core/io/binwrite_spec.rb6
-rw-r--r--spec/ruby/core/io/bytes_spec.rb68
-rw-r--r--spec/ruby/core/io/chars_spec.rb18
-rw-r--r--spec/ruby/core/io/close_on_exec_spec.rb42
-rw-r--r--spec/ruby/core/io/close_read_spec.rb44
-rw-r--r--spec/ruby/core/io/close_spec.rb45
-rw-r--r--spec/ruby/core/io/close_write_spec.rb44
-rw-r--r--spec/ruby/core/io/closed_spec.rb4
-rw-r--r--spec/ruby/core/io/codepoints_spec.rb39
-rw-r--r--spec/ruby/core/io/constants_spec.rb2
-rw-r--r--spec/ruby/core/io/copy_stream_spec.rb54
-rw-r--r--spec/ruby/core/io/dup_spec.rb38
-rw-r--r--spec/ruby/core/io/each_byte_spec.rb6
-rw-r--r--spec/ruby/core/io/each_char_spec.rb6
-rw-r--r--spec/ruby/core/io/each_codepoint_spec.rb14
-rw-r--r--spec/ruby/core/io/each_line_spec.rb6
-rw-r--r--spec/ruby/core/io/each_spec.rb6
-rw-r--r--spec/ruby/core/io/eof_spec.rb36
-rw-r--r--spec/ruby/core/io/external_encoding_spec.rb304
-rw-r--r--spec/ruby/core/io/fcntl_spec.rb6
-rw-r--r--spec/ruby/core/io/fdatasync_spec.rb2
-rw-r--r--spec/ruby/core/io/fileno_spec.rb6
-rw-r--r--spec/ruby/core/io/fixtures/classes.rb20
-rw-r--r--spec/ruby/core/io/fixtures/copy_in_out.rb2
-rw-r--r--spec/ruby/core/io/flush_spec.rb35
-rw-r--r--spec/ruby/core/io/for_fd_spec.rb4
-rw-r--r--spec/ruby/core/io/foreach_spec.rb8
-rw-r--r--spec/ruby/core/io/fsync_spec.rb6
-rw-r--r--spec/ruby/core/io/getbyte_spec.rb6
-rw-r--r--spec/ruby/core/io/getc_spec.rb6
-rw-r--r--spec/ruby/core/io/gets_spec.rb70
-rw-r--r--spec/ruby/core/io/initialize_spec.rb22
-rw-r--r--spec/ruby/core/io/inspect_spec.rb2
-rw-r--r--spec/ruby/core/io/internal_encoding_spec.rb232
-rw-r--r--spec/ruby/core/io/io_spec.rb2
-rw-r--r--spec/ruby/core/io/ioctl_spec.rb14
-rw-r--r--spec/ruby/core/io/isatty_spec.rb4
-rw-r--r--spec/ruby/core/io/lineno_spec.rb10
-rw-r--r--spec/ruby/core/io/lines_spec.rb56
-rw-r--r--spec/ruby/core/io/new_spec.rb4
-rw-r--r--spec/ruby/core/io/open_spec.rb10
-rw-r--r--spec/ruby/core/io/output_spec.rb12
-rw-r--r--spec/ruby/core/io/pid_spec.rb6
-rw-r--r--spec/ruby/core/io/pipe_spec.rb20
-rw-r--r--spec/ruby/core/io/popen_spec.rb82
-rw-r--r--spec/ruby/core/io/pos_spec.rb7
-rw-r--r--spec/ruby/core/io/pread_spec.rb50
-rw-r--r--spec/ruby/core/io/print_spec.rb13
-rw-r--r--spec/ruby/core/io/printf_spec.rb6
-rw-r--r--spec/ruby/core/io/putc_spec.rb4
-rw-r--r--spec/ruby/core/io/puts_spec.rb53
-rw-r--r--spec/ruby/core/io/pwrite_spec.rb43
-rw-r--r--spec/ruby/core/io/read_nonblock_spec.rb50
-rw-r--r--spec/ruby/core/io/read_spec.rb270
-rw-r--r--spec/ruby/core/io/readbyte_spec.rb6
-rw-r--r--spec/ruby/core/io/readchar_spec.rb10
-rw-r--r--spec/ruby/core/io/readline_spec.rb14
-rw-r--r--spec/ruby/core/io/readlines_spec.rb84
-rw-r--r--spec/ruby/core/io/readpartial_spec.rb18
-rw-r--r--spec/ruby/core/io/reopen_spec.rb47
-rw-r--r--spec/ruby/core/io/rewind_spec.rb8
-rw-r--r--spec/ruby/core/io/seek_spec.rb14
-rw-r--r--spec/ruby/core/io/select_spec.rb36
-rw-r--r--spec/ruby/core/io/set_encoding_by_bom_spec.rb57
-rw-r--r--spec/ruby/core/io/set_encoding_spec.rb288
-rw-r--r--spec/ruby/core/io/shared/binwrite.rb16
-rw-r--r--spec/ruby/core/io/shared/chars.rb4
-rw-r--r--spec/ruby/core/io/shared/codepoints.rb6
-rw-r--r--spec/ruby/core/io/shared/each.rb58
-rw-r--r--spec/ruby/core/io/shared/new.rb190
-rw-r--r--spec/ruby/core/io/shared/pos.rb10
-rw-r--r--spec/ruby/core/io/shared/readlines.rb47
-rw-r--r--spec/ruby/core/io/shared/tty.rb7
-rw-r--r--spec/ruby/core/io/shared/write.rb45
-rw-r--r--spec/ruby/core/io/stat_spec.rb6
-rw-r--r--spec/ruby/core/io/sync_spec.rb8
-rw-r--r--spec/ruby/core/io/sysopen_spec.rb8
-rw-r--r--spec/ruby/core/io/sysread_spec.rb26
-rw-r--r--spec/ruby/core/io/sysseek_spec.rb10
-rw-r--r--spec/ruby/core/io/syswrite_spec.rb27
-rw-r--r--spec/ruby/core/io/tell_spec.rb8
-rw-r--r--spec/ruby/core/io/to_i_spec.rb6
-rw-r--r--spec/ruby/core/io/to_io_spec.rb4
-rw-r--r--spec/ruby/core/io/try_convert_spec.rb8
-rw-r--r--spec/ruby/core/io/tty_spec.rb4
-rw-r--r--spec/ruby/core/io/ungetbyte_spec.rb39
-rw-r--r--spec/ruby/core/io/ungetc_spec.rb49
-rw-r--r--spec/ruby/core/io/write_nonblock_spec.rb31
-rw-r--r--spec/ruby/core/io/write_spec.rb91
-rw-r--r--spec/ruby/core/kernel/Array_spec.rb8
-rw-r--r--spec/ruby/core/kernel/Complex_spec.rb187
-rw-r--r--spec/ruby/core/kernel/Float_spec.rb123
-rw-r--r--spec/ruby/core/kernel/Hash_spec.rb16
-rw-r--r--spec/ruby/core/kernel/Integer_spec.rb351
-rw-r--r--spec/ruby/core/kernel/Rational_spec.rb4
-rw-r--r--spec/ruby/core/kernel/String_spec.rb12
-rw-r--r--spec/ruby/core/kernel/__callee___spec.rb4
-rw-r--r--spec/ruby/core/kernel/__dir___spec.rb32
-rw-r--r--spec/ruby/core/kernel/__method___spec.rb4
-rw-r--r--spec/ruby/core/kernel/abort_spec.rb6
-rw-r--r--spec/ruby/core/kernel/at_exit_spec.rb35
-rw-r--r--spec/ruby/core/kernel/autoload_spec.rb57
-rw-r--r--spec/ruby/core/kernel/backtick_spec.rb36
-rw-r--r--spec/ruby/core/kernel/binding_spec.rb6
-rw-r--r--spec/ruby/core/kernel/block_given_spec.rb4
-rw-r--r--spec/ruby/core/kernel/caller_locations_spec.rb56
-rw-r--r--spec/ruby/core/kernel/caller_spec.rb35
-rw-r--r--spec/ruby/core/kernel/case_compare_spec.rb4
-rw-r--r--spec/ruby/core/kernel/catch_spec.rb10
-rw-r--r--spec/ruby/core/kernel/chomp_spec.rb40
-rw-r--r--spec/ruby/core/kernel/chop_spec.rb40
-rw-r--r--spec/ruby/core/kernel/class_spec.rb6
-rw-r--r--spec/ruby/core/kernel/clone_spec.rb38
-rw-r--r--spec/ruby/core/kernel/comparison_spec.rb2
-rw-r--r--spec/ruby/core/kernel/define_singleton_method_spec.rb36
-rw-r--r--spec/ruby/core/kernel/display_spec.rb4
-rw-r--r--spec/ruby/core/kernel/dup_spec.rb14
-rw-r--r--spec/ruby/core/kernel/enum_for_spec.rb2
-rw-r--r--spec/ruby/core/kernel/eql_spec.rb5
-rw-r--r--spec/ruby/core/kernel/equal_value_spec.rb10
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb232
-rw-r--r--spec/ruby/core/kernel/exec_spec.rb4
-rw-r--r--spec/ruby/core/kernel/exit_spec.rb6
-rw-r--r--spec/ruby/core/kernel/extend_spec.rb18
-rw-r--r--spec/ruby/core/kernel/fail_spec.rb25
-rw-r--r--spec/ruby/core/kernel/fixtures/__dir__.rb2
-rw-r--r--spec/ruby/core/kernel/fixtures/at_exit.rb3
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_c.rb5
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_from_included_module.rb9
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_from_included_module2.rb9
-rw-r--r--spec/ruby/core/kernel/fixtures/caller_at_exit.rb7
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb95
-rw-r--r--spec/ruby/core/kernel/fixtures/eval_return_with_lambda.rb2
-rw-r--r--spec/ruby/core/kernel/fixtures/singleton_methods.rb13
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_core_method.rb14
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_require.rb1
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_require_caller.rb2
-rw-r--r--spec/ruby/core/kernel/fork_spec.rb6
-rw-r--r--spec/ruby/core/kernel/format_spec.rb4
-rw-r--r--spec/ruby/core/kernel/freeze_spec.rb32
-rw-r--r--spec/ruby/core/kernel/frozen_spec.rb32
-rw-r--r--spec/ruby/core/kernel/gets_spec.rb4
-rw-r--r--spec/ruby/core/kernel/global_variables_spec.rb4
-rw-r--r--spec/ruby/core/kernel/gsub_spec.rb6
-rw-r--r--spec/ruby/core/kernel/initialize_copy_spec.rb29
-rw-r--r--spec/ruby/core/kernel/inspect_spec.rb16
-rw-r--r--spec/ruby/core/kernel/instance_of_spec.rb12
-rw-r--r--spec/ruby/core/kernel/instance_variable_defined_spec.rb6
-rw-r--r--spec/ruby/core/kernel/instance_variable_get_spec.rb30
-rw-r--r--spec/ruby/core/kernel/instance_variable_set_spec.rb44
-rw-r--r--spec/ruby/core/kernel/instance_variables_spec.rb10
-rw-r--r--spec/ruby/core/kernel/is_a_spec.rb6
-rw-r--r--spec/ruby/core/kernel/iterator_spec.rb18
-rw-r--r--spec/ruby/core/kernel/itself_spec.rb4
-rw-r--r--spec/ruby/core/kernel/kind_of_spec.rb6
-rw-r--r--spec/ruby/core/kernel/lambda_spec.rb54
-rw-r--r--spec/ruby/core/kernel/load_spec.rb8
-rw-r--r--spec/ruby/core/kernel/local_variables_spec.rb15
-rw-r--r--spec/ruby/core/kernel/loop_spec.rb22
-rw-r--r--spec/ruby/core/kernel/match_spec.rb24
-rw-r--r--spec/ruby/core/kernel/method_spec.rb8
-rw-r--r--spec/ruby/core/kernel/methods_spec.rb6
-rw-r--r--spec/ruby/core/kernel/nil_spec.rb4
-rw-r--r--spec/ruby/core/kernel/not_match_spec.rb4
-rw-r--r--spec/ruby/core/kernel/object_id_spec.rb4
-rw-r--r--spec/ruby/core/kernel/open_spec.rb23
-rw-r--r--spec/ruby/core/kernel/p_spec.rb38
-rw-r--r--spec/ruby/core/kernel/pp_spec.rb9
-rw-r--r--spec/ruby/core/kernel/print_spec.rb4
-rw-r--r--spec/ruby/core/kernel/printf_spec.rb35
-rw-r--r--spec/ruby/core/kernel/private_methods_spec.rb6
-rw-r--r--spec/ruby/core/kernel/proc_spec.rb40
-rw-r--r--spec/ruby/core/kernel/protected_methods_spec.rb6
-rw-r--r--spec/ruby/core/kernel/public_method_spec.rb14
-rw-r--r--spec/ruby/core/kernel/public_methods_spec.rb6
-rw-r--r--spec/ruby/core/kernel/public_send_spec.rb20
-rw-r--r--spec/ruby/core/kernel/putc_spec.rb6
-rw-r--r--spec/ruby/core/kernel/puts_spec.rb4
-rw-r--r--spec/ruby/core/kernel/raise_spec.rb27
-rw-r--r--spec/ruby/core/kernel/rand_spec.rb20
-rw-r--r--spec/ruby/core/kernel/readline_spec.rb4
-rw-r--r--spec/ruby/core/kernel/readlines_spec.rb4
-rw-r--r--spec/ruby/core/kernel/remove_instance_variable_spec.rb10
-rw-r--r--spec/ruby/core/kernel/require_relative_spec.rb136
-rw-r--r--spec/ruby/core/kernel/require_spec.rb8
-rw-r--r--spec/ruby/core/kernel/respond_to_missing_spec.rb4
-rw-r--r--spec/ruby/core/kernel/respond_to_spec.rb9
-rw-r--r--spec/ruby/core/kernel/select_spec.rb6
-rw-r--r--spec/ruby/core/kernel/send_spec.rb8
-rw-r--r--spec/ruby/core/kernel/set_trace_func_spec.rb4
-rw-r--r--spec/ruby/core/kernel/shared/dup_clone.rb90
-rw-r--r--spec/ruby/core/kernel/shared/kind_of.rb23
-rw-r--r--spec/ruby/core/kernel/shared/lambda.rb4
-rw-r--r--spec/ruby/core/kernel/shared/load.rb43
-rw-r--r--spec/ruby/core/kernel/shared/method.rb6
-rw-r--r--spec/ruby/core/kernel/shared/require.rb221
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb887
-rw-r--r--spec/ruby/core/kernel/shared/sprintf_encoding.rb36
-rw-r--r--spec/ruby/core/kernel/shared/then.rb20
-rw-r--r--spec/ruby/core/kernel/singleton_class_spec.rb6
-rw-r--r--spec/ruby/core/kernel/singleton_method_spec.rb2
-rw-r--r--spec/ruby/core/kernel/singleton_methods_spec.rb32
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb24
-rw-r--r--spec/ruby/core/kernel/spawn_spec.rb8
-rw-r--r--spec/ruby/core/kernel/sprintf_spec.rb320
-rw-r--r--spec/ruby/core/kernel/srand_spec.rb16
-rw-r--r--spec/ruby/core/kernel/sub_spec.rb4
-rw-r--r--spec/ruby/core/kernel/syscall_spec.rb4
-rw-r--r--spec/ruby/core/kernel/system_spec.rb36
-rw-r--r--spec/ruby/core/kernel/taint_spec.rb81
-rw-r--r--spec/ruby/core/kernel/tainted_spec.rb35
-rw-r--r--spec/ruby/core/kernel/tap_spec.rb6
-rw-r--r--spec/ruby/core/kernel/test_spec.rb4
-rw-r--r--spec/ruby/core/kernel/then_spec.rb8
-rw-r--r--spec/ruby/core/kernel/throw_spec.rb16
-rw-r--r--spec/ruby/core/kernel/to_enum_spec.rb2
-rw-r--r--spec/ruby/core/kernel/to_s_spec.rb16
-rw-r--r--spec/ruby/core/kernel/trace_var_spec.rb6
-rw-r--r--spec/ruby/core/kernel/trap_spec.rb4
-rw-r--r--spec/ruby/core/kernel/trust_spec.rb52
-rw-r--r--spec/ruby/core/kernel/untaint_spec.rb52
-rw-r--r--spec/ruby/core/kernel/untrace_var_spec.rb4
-rw-r--r--spec/ruby/core/kernel/untrust_spec.rb51
-rw-r--r--spec/ruby/core/kernel/untrusted_spec.rb60
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb192
-rw-r--r--spec/ruby/core/kernel/yield_self_spec.rb28
-rw-r--r--spec/ruby/core/main/define_method_spec.rb4
-rw-r--r--spec/ruby/core/main/fixtures/classes.rb11
-rw-r--r--spec/ruby/core/main/fixtures/string_refinement.rb7
-rw-r--r--spec/ruby/core/main/fixtures/string_refinement_user.rb11
-rw-r--r--spec/ruby/core/main/include_spec.rb4
-rw-r--r--spec/ruby/core/main/private_spec.rb37
-rw-r--r--spec/ruby/core/main/public_spec.rb33
-rw-r--r--spec/ruby/core/main/to_s_spec.rb2
-rw-r--r--spec/ruby/core/main/using_spec.rb132
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb222
-rw-r--r--spec/ruby/core/marshal/fixtures/marshal_data.rb60
-rw-r--r--spec/ruby/core/marshal/float_spec.rb2
-rw-r--r--spec/ruby/core/marshal/load_spec.rb4
-rw-r--r--spec/ruby/core/marshal/major_version_spec.rb2
-rw-r--r--spec/ruby/core/marshal/minor_version_spec.rb2
-rw-r--r--spec/ruby/core/marshal/restore_spec.rb4
-rw-r--r--spec/ruby/core/marshal/shared/load.rb501
-rw-r--r--spec/ruby/core/matchdata/allocate_spec.rb10
-rw-r--r--spec/ruby/core/matchdata/begin_spec.rb110
-rw-r--r--spec/ruby/core/matchdata/captures_spec.rb2
-rw-r--r--spec/ruby/core/matchdata/dup_spec.rb14
-rw-r--r--spec/ruby/core/matchdata/element_reference_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/end_spec.rb110
-rw-r--r--spec/ruby/core/matchdata/eql_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/hash_spec.rb2
-rw-r--r--spec/ruby/core/matchdata/inspect_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/length_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/named_captures_spec.rb20
-rw-r--r--spec/ruby/core/matchdata/names_spec.rb2
-rw-r--r--spec/ruby/core/matchdata/offset_spec.rb2
-rw-r--r--spec/ruby/core/matchdata/post_match_spec.rb46
-rw-r--r--spec/ruby/core/matchdata/pre_match_spec.rb46
-rw-r--r--spec/ruby/core/matchdata/regexp_spec.rb13
-rw-r--r--spec/ruby/core/matchdata/shared/eql.rb2
-rw-r--r--spec/ruby/core/matchdata/size_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/string_spec.rb15
-rw-r--r--spec/ruby/core/matchdata/to_a_spec.rb2
-rw-r--r--spec/ruby/core/matchdata/to_s_spec.rb2
-rw-r--r--spec/ruby/core/matchdata/values_at_spec.rb14
-rw-r--r--spec/ruby/core/math/acos_spec.rb22
-rw-r--r--spec/ruby/core/math/acosh_spec.rb18
-rw-r--r--spec/ruby/core/math/asin_spec.rb20
-rw-r--r--spec/ruby/core/math/asinh_spec.rb8
-rw-r--r--spec/ruby/core/math/atan2_spec.rb16
-rw-r--r--spec/ruby/core/math/atan_spec.rb8
-rw-r--r--spec/ruby/core/math/atanh_spec.rb6
-rw-r--r--spec/ruby/core/math/cbrt_spec.rb8
-rw-r--r--spec/ruby/core/math/constants_spec.rb4
-rw-r--r--spec/ruby/core/math/cos_spec.rb8
-rw-r--r--spec/ruby/core/math/cosh_spec.rb8
-rw-r--r--spec/ruby/core/math/erf_spec.rb8
-rw-r--r--spec/ruby/core/math/erfc_spec.rb8
-rw-r--r--spec/ruby/core/math/exp_spec.rb8
-rw-r--r--spec/ruby/core/math/frexp_spec.rb8
-rw-r--r--spec/ruby/core/math/gamma_spec.rb6
-rw-r--r--spec/ruby/core/math/hypot_spec.rb8
-rw-r--r--spec/ruby/core/math/ldexp_spec.rb14
-rw-r--r--spec/ruby/core/math/lgamma_spec.rb10
-rw-r--r--spec/ruby/core/math/log10_spec.rb14
-rw-r--r--spec/ruby/core/math/log2_spec.rb12
-rw-r--r--spec/ruby/core/math/log_spec.rb20
-rw-r--r--spec/ruby/core/math/sin_spec.rb8
-rw-r--r--spec/ruby/core/math/sinh_spec.rb8
-rw-r--r--spec/ruby/core/math/sqrt_spec.rb8
-rw-r--r--spec/ruby/core/math/tan_spec.rb14
-rw-r--r--spec/ruby/core/math/tanh_spec.rb8
-rw-r--r--spec/ruby/core/method/arity_spec.rb4
-rw-r--r--spec/ruby/core/method/call_spec.rb8
-rw-r--r--spec/ruby/core/method/case_compare_spec.rb7
-rw-r--r--spec/ruby/core/method/clone_spec.rb4
-rw-r--r--spec/ruby/core/method/compose_spec.rb102
-rw-r--r--spec/ruby/core/method/curry_spec.rb14
-rw-r--r--spec/ruby/core/method/element_reference_spec.rb8
-rw-r--r--spec/ruby/core/method/eql_spec.rb6
-rw-r--r--spec/ruby/core/method/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/method/fixtures/classes.rb32
-rw-r--r--spec/ruby/core/method/hash_spec.rb6
-rw-r--r--spec/ruby/core/method/inspect_spec.rb6
-rw-r--r--spec/ruby/core/method/name_spec.rb4
-rw-r--r--spec/ruby/core/method/original_name_spec.rb22
-rw-r--r--spec/ruby/core/method/owner_spec.rb4
-rw-r--r--spec/ruby/core/method/parameters_spec.rb23
-rw-r--r--spec/ruby/core/method/receiver_spec.rb4
-rw-r--r--spec/ruby/core/method/shared/call.rb4
-rw-r--r--spec/ruby/core/method/shared/eql.rb4
-rw-r--r--spec/ruby/core/method/shared/to_s.rb53
-rw-r--r--spec/ruby/core/method/source_location_spec.rb28
-rw-r--r--spec/ruby/core/method/super_method_spec.rb4
-rw-r--r--spec/ruby/core/method/to_proc_spec.rb19
-rw-r--r--spec/ruby/core/method/to_s_spec.rb6
-rw-r--r--spec/ruby/core/method/unbind_spec.rb4
-rw-r--r--spec/ruby/core/module/alias_method_spec.rb53
-rw-r--r--spec/ruby/core/module/allocate_spec.rb2
-rw-r--r--spec/ruby/core/module/ancestors_spec.rb4
-rw-r--r--spec/ruby/core/module/append_features_spec.rb34
-rw-r--r--spec/ruby/core/module/attr_accessor_spec.rb46
-rw-r--r--spec/ruby/core/module/attr_reader_spec.rb34
-rw-r--r--spec/ruby/core/module/attr_spec.rb49
-rw-r--r--spec/ruby/core/module/attr_writer_spec.rb34
-rw-r--r--spec/ruby/core/module/autoload_spec.rb686
-rw-r--r--spec/ruby/core/module/case_compare_spec.rb4
-rw-r--r--spec/ruby/core/module/class_eval_spec.rb6
-rw-r--r--spec/ruby/core/module/class_exec_spec.rb6
-rw-r--r--spec/ruby/core/module/class_variable_defined_spec.rb14
-rw-r--r--spec/ruby/core/module/class_variable_get_spec.rb22
-rw-r--r--spec/ruby/core/module/class_variable_set_spec.rb24
-rw-r--r--spec/ruby/core/module/class_variables_spec.rb4
-rw-r--r--spec/ruby/core/module/comparison_spec.rb6
-rw-r--r--spec/ruby/core/module/const_defined_spec.rb26
-rw-r--r--spec/ruby/core/module/const_get_spec.rb69
-rw-r--r--spec/ruby/core/module/const_missing_spec.rb15
-rw-r--r--spec/ruby/core/module/const_set_spec.rb91
-rw-r--r--spec/ruby/core/module/const_source_location_spec.rb220
-rw-r--r--spec/ruby/core/module/constants_spec.rb20
-rw-r--r--spec/ruby/core/module/define_method_spec.rb147
-rw-r--r--spec/ruby/core/module/define_singleton_method_spec.rb6
-rw-r--r--spec/ruby/core/module/deprecate_constant_spec.rb78
-rw-r--r--spec/ruby/core/module/eql_spec.rb8
-rw-r--r--spec/ruby/core/module/equal_spec.rb8
-rw-r--r--spec/ruby/core/module/equal_value_spec.rb8
-rw-r--r--spec/ruby/core/module/extend_object_spec.rb28
-rw-r--r--spec/ruby/core/module/extended_spec.rb4
-rw-r--r--spec/ruby/core/module/fixtures/autoload_callback.rb2
-rw-r--r--spec/ruby/core/module/fixtures/autoload_during_autoload.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_during_require.rb4
-rw-r--r--spec/ruby/core/module/fixtures/autoload_during_require_current_file.rb5
-rw-r--r--spec/ruby/core/module/fixtures/autoload_exception.rb3
-rw-r--r--spec/ruby/core/module/fixtures/autoload_location.rb3
-rw-r--r--spec/ruby/core/module/fixtures/autoload_nested.rb8
-rw-r--r--spec/ruby/core/module/fixtures/autoload_never_set.rb1
-rw-r--r--spec/ruby/core/module/fixtures/autoload_o.rb1
-rw-r--r--spec/ruby/core/module/fixtures/autoload_overridden.rb3
-rw-r--r--spec/ruby/core/module/fixtures/autoload_raise.rb2
-rw-r--r--spec/ruby/core/module/fixtures/autoload_required_directly.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_required_directly_nested.rb1
-rw-r--r--spec/ruby/core/module/fixtures/autoload_required_directly_no_constant.rb2
-rw-r--r--spec/ruby/core/module/fixtures/autoload_scope.rb8
-rw-r--r--spec/ruby/core/module/fixtures/autoload_self_during_require.rb5
-rw-r--r--spec/ruby/core/module/fixtures/autoload_subclass.rb4
-rw-r--r--spec/ruby/core/module/fixtures/classes.rb9
-rw-r--r--spec/ruby/core/module/fixtures/constants_autoload.rb6
-rw-r--r--spec/ruby/core/module/fixtures/constants_autoload_a.rb2
-rw-r--r--spec/ruby/core/module/fixtures/constants_autoload_b.rb2
-rw-r--r--spec/ruby/core/module/fixtures/constants_autoload_c.rb3
-rw-r--r--spec/ruby/core/module/fixtures/constants_autoload_d.rb4
-rw-r--r--spec/ruby/core/module/fixtures/multi/foo.rb6
-rw-r--r--spec/ruby/core/module/fixtures/multi/foo/bar_baz.rb11
-rw-r--r--spec/ruby/core/module/fixtures/refine.rb25
-rw-r--r--spec/ruby/core/module/freeze_spec.rb4
-rw-r--r--spec/ruby/core/module/gt_spec.rb6
-rw-r--r--spec/ruby/core/module/gte_spec.rb6
-rw-r--r--spec/ruby/core/module/include_spec.rb38
-rw-r--r--spec/ruby/core/module/included_modules_spec.rb8
-rw-r--r--spec/ruby/core/module/included_spec.rb6
-rw-r--r--spec/ruby/core/module/initialize_copy_spec.rb10
-rw-r--r--spec/ruby/core/module/initialize_spec.rb4
-rw-r--r--spec/ruby/core/module/instance_method_spec.rb16
-rw-r--r--spec/ruby/core/module/instance_methods_spec.rb4
-rw-r--r--spec/ruby/core/module/lt_spec.rb6
-rw-r--r--spec/ruby/core/module/lte_spec.rb6
-rw-r--r--spec/ruby/core/module/method_added_spec.rb25
-rw-r--r--spec/ruby/core/module/method_defined_spec.rb61
-rw-r--r--spec/ruby/core/module/method_removed_spec.rb4
-rw-r--r--spec/ruby/core/module/method_undefined_spec.rb4
-rw-r--r--spec/ruby/core/module/module_eval_spec.rb6
-rw-r--r--spec/ruby/core/module/module_exec_spec.rb6
-rw-r--r--spec/ruby/core/module/module_function_spec.rb14
-rw-r--r--spec/ruby/core/module/name_spec.rb90
-rw-r--r--spec/ruby/core/module/nesting_spec.rb4
-rw-r--r--spec/ruby/core/module/new_spec.rb4
-rw-r--r--spec/ruby/core/module/prepend_features_spec.rb28
-rw-r--r--spec/ruby/core/module/prepend_spec.rb87
-rw-r--r--spec/ruby/core/module/prepended_spec.rb2
-rw-r--r--spec/ruby/core/module/private_class_method_spec.rb24
-rw-r--r--spec/ruby/core/module/private_constant_spec.rb10
-rw-r--r--spec/ruby/core/module/private_instance_methods_spec.rb6
-rw-r--r--spec/ruby/core/module/private_method_defined_spec.rb66
-rw-r--r--spec/ruby/core/module/private_spec.rb49
-rw-r--r--spec/ruby/core/module/protected_instance_methods_spec.rb6
-rw-r--r--spec/ruby/core/module/protected_method_defined_spec.rb66
-rw-r--r--spec/ruby/core/module/protected_spec.rb11
-rw-r--r--spec/ruby/core/module/public_class_method_spec.rb18
-rw-r--r--spec/ruby/core/module/public_constant_spec.rb4
-rw-r--r--spec/ruby/core/module/public_instance_method_spec.rb14
-rw-r--r--spec/ruby/core/module/public_instance_methods_spec.rb6
-rw-r--r--spec/ruby/core/module/public_method_defined_spec.rb16
-rw-r--r--spec/ruby/core/module/public_spec.rb8
-rw-r--r--spec/ruby/core/module/refine_spec.rb1128
-rw-r--r--spec/ruby/core/module/remove_class_variable_spec.rb12
-rw-r--r--spec/ruby/core/module/remove_const_spec.rb30
-rw-r--r--spec/ruby/core/module/remove_method_spec.rb34
-rw-r--r--spec/ruby/core/module/shared/class_eval.rb58
-rw-r--r--spec/ruby/core/module/shared/class_exec.rb4
-rw-r--r--spec/ruby/core/module/shared/set_visibility.rb51
-rw-r--r--spec/ruby/core/module/singleton_class_spec.rb12
-rw-r--r--spec/ruby/core/module/to_s_spec.rb35
-rw-r--r--spec/ruby/core/module/undef_method_spec.rb63
-rw-r--r--spec/ruby/core/module/using_spec.rb377
-rw-r--r--spec/ruby/core/mutex/lock_spec.rb32
-rw-r--r--spec/ruby/core/mutex/locked_spec.rb2
-rw-r--r--spec/ruby/core/mutex/owned_spec.rb14
-rw-r--r--spec/ruby/core/mutex/sleep_spec.rb55
-rw-r--r--spec/ruby/core/mutex/synchronize_spec.rb43
-rw-r--r--spec/ruby/core/mutex/try_lock_spec.rb2
-rw-r--r--spec/ruby/core/mutex/unlock_spec.rb10
-rw-r--r--spec/ruby/core/nil/and_spec.rb2
-rw-r--r--spec/ruby/core/nil/case_compare_spec.rb13
-rw-r--r--spec/ruby/core/nil/dup_spec.rb7
-rw-r--r--spec/ruby/core/nil/inspect_spec.rb2
-rw-r--r--spec/ruby/core/nil/match_spec.rb23
-rw-r--r--spec/ruby/core/nil/nil_spec.rb4
-rw-r--r--spec/ruby/core/nil/nilclass_spec.rb6
-rw-r--r--spec/ruby/core/nil/or_spec.rb2
-rw-r--r--spec/ruby/core/nil/rationalize_spec.rb6
-rw-r--r--spec/ruby/core/nil/to_a_spec.rb2
-rw-r--r--spec/ruby/core/nil/to_c_spec.rb2
-rw-r--r--spec/ruby/core/nil/to_f_spec.rb2
-rw-r--r--spec/ruby/core/nil/to_h_spec.rb2
-rw-r--r--spec/ruby/core/nil/to_i_spec.rb4
-rw-r--r--spec/ruby/core/nil/to_r_spec.rb2
-rw-r--r--spec/ruby/core/nil/to_s_spec.rb12
-rw-r--r--spec/ruby/core/nil/xor_spec.rb2
-rw-r--r--spec/ruby/core/numeric/abs2_spec.rb2
-rw-r--r--spec/ruby/core/numeric/abs_spec.rb5
-rw-r--r--spec/ruby/core/numeric/angle_spec.rb6
-rw-r--r--spec/ruby/core/numeric/arg_spec.rb6
-rw-r--r--spec/ruby/core/numeric/ceil_spec.rb4
-rw-r--r--spec/ruby/core/numeric/clone_spec.rb25
-rw-r--r--spec/ruby/core/numeric/coerce_spec.rb51
-rw-r--r--spec/ruby/core/numeric/comparison_spec.rb4
-rw-r--r--spec/ruby/core/numeric/conj_spec.rb6
-rw-r--r--spec/ruby/core/numeric/conjugate_spec.rb6
-rw-r--r--spec/ruby/core/numeric/denominator_spec.rb4
-rw-r--r--spec/ruby/core/numeric/div_spec.rb10
-rw-r--r--spec/ruby/core/numeric/divmod_spec.rb4
-rw-r--r--spec/ruby/core/numeric/dup_spec.rb16
-rw-r--r--spec/ruby/core/numeric/eql_spec.rb4
-rw-r--r--spec/ruby/core/numeric/fdiv_spec.rb4
-rw-r--r--spec/ruby/core/numeric/finite_spec.rb8
-rw-r--r--spec/ruby/core/numeric/floor_spec.rb4
-rw-r--r--spec/ruby/core/numeric/i_spec.rb2
-rw-r--r--spec/ruby/core/numeric/imag_spec.rb6
-rw-r--r--spec/ruby/core/numeric/imaginary_spec.rb6
-rw-r--r--spec/ruby/core/numeric/infinite_spec.rb8
-rw-r--r--spec/ruby/core/numeric/integer_spec.rb6
-rw-r--r--spec/ruby/core/numeric/magnitude_spec.rb4
-rw-r--r--spec/ruby/core/numeric/modulo_spec.rb4
-rw-r--r--spec/ruby/core/numeric/negative_spec.rb60
-rw-r--r--spec/ruby/core/numeric/nonzero_spec.rb4
-rw-r--r--spec/ruby/core/numeric/numerator_spec.rb2
-rw-r--r--spec/ruby/core/numeric/numeric_spec.rb2
-rw-r--r--spec/ruby/core/numeric/phase_spec.rb6
-rw-r--r--spec/ruby/core/numeric/polar_spec.rb50
-rw-r--r--spec/ruby/core/numeric/positive_spec.rb60
-rw-r--r--spec/ruby/core/numeric/quo_spec.rb26
-rw-r--r--spec/ruby/core/numeric/real_spec.rb34
-rw-r--r--spec/ruby/core/numeric/rect_spec.rb6
-rw-r--r--spec/ruby/core/numeric/rectangular_spec.rb6
-rw-r--r--spec/ruby/core/numeric/remainder_spec.rb4
-rw-r--r--spec/ruby/core/numeric/round_spec.rb4
-rw-r--r--spec/ruby/core/numeric/shared/abs.rb4
-rw-r--r--spec/ruby/core/numeric/shared/arg.rb38
-rw-r--r--spec/ruby/core/numeric/shared/conj.rb20
-rw-r--r--spec/ruby/core/numeric/shared/imag.rb26
-rw-r--r--spec/ruby/core/numeric/shared/rect.rb6
-rw-r--r--spec/ruby/core/numeric/shared/step.rb294
-rw-r--r--spec/ruby/core/numeric/singleton_method_added_spec.rb12
-rw-r--r--spec/ruby/core/numeric/step_spec.rb175
-rw-r--r--spec/ruby/core/numeric/to_c_spec.rb2
-rw-r--r--spec/ruby/core/numeric/to_int_spec.rb4
-rw-r--r--spec/ruby/core/numeric/truncate_spec.rb4
-rw-r--r--spec/ruby/core/numeric/uminus_spec.rb2
-rw-r--r--spec/ruby/core/numeric/uplus_spec.rb4
-rw-r--r--spec/ruby/core/numeric/zero_spec.rb8
-rw-r--r--spec/ruby/core/objectspace/_id2ref_spec.rb4
-rw-r--r--spec/ruby/core/objectspace/add_finalizer_spec.rb2
-rw-r--r--spec/ruby/core/objectspace/call_finalizer_spec.rb2
-rw-r--r--spec/ruby/core/objectspace/count_objects_spec.rb2
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb199
-rw-r--r--spec/ruby/core/objectspace/each_object_spec.rb26
-rw-r--r--spec/ruby/core/objectspace/finalizers_spec.rb2
-rw-r--r--spec/ruby/core/objectspace/fixtures/classes.rb2
-rw-r--r--spec/ruby/core/objectspace/garbage_collect_spec.rb8
-rw-r--r--spec/ruby/core/objectspace/remove_finalizer_spec.rb2
-rw-r--r--spec/ruby/core/objectspace/undefine_finalizer_spec.rb2
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_key_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_pair_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_value_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/element_reference_spec.rb24
-rw-r--r--spec/ruby/core/objectspace/weakmap/element_set_spec.rb61
-rw-r--r--spec/ruby/core/objectspace/weakmap/include_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/inspect_spec.rb25
-rw-r--r--spec/ruby/core/objectspace/weakmap/key_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/keys_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/length_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/member_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/each.rb10
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/include.rb34
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/members.rb14
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/size.rb14
-rw-r--r--spec/ruby/core/objectspace/weakmap/size_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/values_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap_spec.rb12
-rw-r--r--spec/ruby/core/proc/allocate_spec.rb4
-rw-r--r--spec/ruby/core/proc/arity_spec.rb2
-rw-r--r--spec/ruby/core/proc/binding_spec.rb6
-rw-r--r--spec/ruby/core/proc/block_pass_spec.rb38
-rw-r--r--spec/ruby/core/proc/call_spec.rb6
-rw-r--r--spec/ruby/core/proc/case_compare_spec.rb6
-rw-r--r--spec/ruby/core/proc/clone_spec.rb6
-rw-r--r--spec/ruby/core/proc/compose_spec.rb156
-rw-r--r--spec/ruby/core/proc/curry_spec.rb62
-rw-r--r--spec/ruby/core/proc/dup_spec.rb6
-rw-r--r--spec/ruby/core/proc/element_reference_spec.rb17
-rw-r--r--spec/ruby/core/proc/eql_spec.rb12
-rw-r--r--spec/ruby/core/proc/equal_value_spec.rb12
-rw-r--r--spec/ruby/core/proc/fixtures/proc_aref.rb9
-rw-r--r--spec/ruby/core/proc/fixtures/proc_aref_frozen.rb10
-rw-r--r--spec/ruby/core/proc/fixtures/source_location.rb8
-rw-r--r--spec/ruby/core/proc/hash_spec.rb6
-rw-r--r--spec/ruby/core/proc/inspect_spec.rb4
-rw-r--r--spec/ruby/core/proc/lambda_spec.rb20
-rw-r--r--spec/ruby/core/proc/new_spec.rb88
-rw-r--r--spec/ruby/core/proc/parameters_spec.rb38
-rw-r--r--spec/ruby/core/proc/shared/call.rb30
-rw-r--r--spec/ruby/core/proc/shared/call_arguments.rb24
-rw-r--r--spec/ruby/core/proc/shared/compose.rb47
-rw-r--r--spec/ruby/core/proc/shared/dup.rb2
-rw-r--r--spec/ruby/core/proc/shared/equal.rb38
-rw-r--r--spec/ruby/core/proc/shared/to_s.rb49
-rw-r--r--spec/ruby/core/proc/source_location_spec.rb38
-rw-r--r--spec/ruby/core/proc/to_proc_spec.rb4
-rw-r--r--spec/ruby/core/proc/to_s_spec.rb4
-rw-r--r--spec/ruby/core/proc/yield_spec.rb6
-rw-r--r--spec/ruby/core/process/abort_spec.rb4
-rw-r--r--spec/ruby/core/process/clock_getres_spec.rb33
-rw-r--r--spec/ruby/core/process/clock_gettime_spec.rb137
-rw-r--r--spec/ruby/core/process/daemon_spec.rb14
-rw-r--r--spec/ruby/core/process/detach_spec.rb4
-rw-r--r--spec/ruby/core/process/egid_spec.rb2
-rw-r--r--spec/ruby/core/process/euid_spec.rb35
-rw-r--r--spec/ruby/core/process/exec_spec.rb69
-rw-r--r--spec/ruby/core/process/exit_spec.rb4
-rw-r--r--spec/ruby/core/process/fixtures/clocks.rb18
-rw-r--r--spec/ruby/core/process/fixtures/common.rb8
-rw-r--r--spec/ruby/core/process/fixtures/in.txt1
-rw-r--r--spec/ruby/core/process/fixtures/map_fd.rb3
-rw-r--r--spec/ruby/core/process/fork_spec.rb4
-rw-r--r--spec/ruby/core/process/getpgid_spec.rb2
-rw-r--r--spec/ruby/core/process/getpgrp_spec.rb2
-rw-r--r--spec/ruby/core/process/getpriority_spec.rb10
-rw-r--r--spec/ruby/core/process/getrlimit_spec.rb22
-rw-r--r--spec/ruby/core/process/gid/change_privilege_spec.rb2
-rw-r--r--spec/ruby/core/process/gid/eid_spec.rb2
-rw-r--r--spec/ruby/core/process/gid/grant_privilege_spec.rb2
-rw-r--r--spec/ruby/core/process/gid/re_exchange_spec.rb2
-rw-r--r--spec/ruby/core/process/gid/re_exchangeable_spec.rb2
-rw-r--r--spec/ruby/core/process/gid/rid_spec.rb2
-rw-r--r--spec/ruby/core/process/gid/sid_available_spec.rb2
-rw-r--r--spec/ruby/core/process/gid/switch_spec.rb2
-rw-r--r--spec/ruby/core/process/gid_spec.rb2
-rw-r--r--spec/ruby/core/process/groups_spec.rb45
-rw-r--r--spec/ruby/core/process/initgroups_spec.rb30
-rw-r--r--spec/ruby/core/process/kill_spec.rb20
-rw-r--r--spec/ruby/core/process/last_status_spec.rb18
-rw-r--r--spec/ruby/core/process/maxgroups_spec.rb4
-rw-r--r--spec/ruby/core/process/pid_spec.rb4
-rw-r--r--spec/ruby/core/process/ppid_spec.rb20
-rw-r--r--spec/ruby/core/process/set_proctitle_spec.rb2
-rw-r--r--spec/ruby/core/process/setpgid_spec.rb5
-rw-r--r--spec/ruby/core/process/setpgrp_spec.rb2
-rw-r--r--spec/ruby/core/process/setpriority_spec.rb33
-rw-r--r--spec/ruby/core/process/setrlimit_spec.rb16
-rw-r--r--spec/ruby/core/process/setsid_spec.rb39
-rw-r--r--spec/ruby/core/process/spawn_spec.rb383
-rw-r--r--spec/ruby/core/process/status/bit_and_spec.rb2
-rw-r--r--spec/ruby/core/process/status/coredump_spec.rb2
-rw-r--r--spec/ruby/core/process/status/equal_value_spec.rb14
-rw-r--r--spec/ruby/core/process/status/exited_spec.rb2
-rw-r--r--spec/ruby/core/process/status/exitstatus_spec.rb16
-rw-r--r--spec/ruby/core/process/status/inspect_spec.rb2
-rw-r--r--spec/ruby/core/process/status/pid_spec.rb2
-rw-r--r--spec/ruby/core/process/status/right_shift_spec.rb2
-rw-r--r--spec/ruby/core/process/status/signaled_spec.rb2
-rw-r--r--spec/ruby/core/process/status/stopped_spec.rb2
-rw-r--r--spec/ruby/core/process/status/stopsig_spec.rb2
-rw-r--r--spec/ruby/core/process/status/success_spec.rb2
-rw-r--r--spec/ruby/core/process/status/termsig_spec.rb22
-rw-r--r--spec/ruby/core/process/status/to_i_spec.rb12
-rw-r--r--spec/ruby/core/process/status/to_int_spec.rb2
-rw-r--r--spec/ruby/core/process/status/to_s_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/getegid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/geteuid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/getgid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/getuid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/issetugid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setegid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/seteuid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setgid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setregid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setresgid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setresuid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setreuid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setrgid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setruid_spec.rb2
-rw-r--r--spec/ruby/core/process/sys/setuid_spec.rb2
-rw-r--r--spec/ruby/core/process/times_spec.rb42
-rw-r--r--spec/ruby/core/process/uid/change_privilege_spec.rb2
-rw-r--r--spec/ruby/core/process/uid/eid_spec.rb2
-rw-r--r--spec/ruby/core/process/uid/grant_privilege_spec.rb2
-rw-r--r--spec/ruby/core/process/uid/re_exchange_spec.rb2
-rw-r--r--spec/ruby/core/process/uid/re_exchangeable_spec.rb2
-rw-r--r--spec/ruby/core/process/uid/rid_spec.rb2
-rw-r--r--spec/ruby/core/process/uid/sid_available_spec.rb2
-rw-r--r--spec/ruby/core/process/uid/switch_spec.rb2
-rw-r--r--spec/ruby/core/process/uid_spec.rb63
-rw-r--r--spec/ruby/core/process/wait2_spec.rb15
-rw-r--r--spec/ruby/core/process/wait_spec.rb21
-rw-r--r--spec/ruby/core/process/waitall_spec.rb6
-rw-r--r--spec/ruby/core/process/waitpid2_spec.rb2
-rw-r--r--spec/ruby/core/process/waitpid_spec.rb4
-rw-r--r--spec/ruby/core/queue/append_spec.rb6
-rw-r--r--spec/ruby/core/queue/clear_spec.rb6
-rw-r--r--spec/ruby/core/queue/close_spec.rb6
-rw-r--r--spec/ruby/core/queue/closed_spec.rb6
-rw-r--r--spec/ruby/core/queue/deq_spec.rb6
-rw-r--r--spec/ruby/core/queue/empty_spec.rb6
-rw-r--r--spec/ruby/core/queue/enq_spec.rb6
-rw-r--r--spec/ruby/core/queue/length_spec.rb6
-rw-r--r--spec/ruby/core/queue/num_waiting_spec.rb6
-rw-r--r--spec/ruby/core/queue/pop_spec.rb6
-rw-r--r--spec/ruby/core/queue/push_spec.rb6
-rw-r--r--spec/ruby/core/queue/shift_spec.rb6
-rw-r--r--spec/ruby/core/queue/size_spec.rb6
-rw-r--r--spec/ruby/core/random/bytes_spec.rb25
-rw-r--r--spec/ruby/core/random/default_spec.rb37
-rw-r--r--spec/ruby/core/random/equal_value_spec.rb2
-rw-r--r--spec/ruby/core/random/fixtures/classes.rb15
-rw-r--r--spec/ruby/core/random/new_seed_spec.rb6
-rw-r--r--spec/ruby/core/random/new_spec.rb4
-rw-r--r--spec/ruby/core/random/rand_spec.rb51
-rw-r--r--spec/ruby/core/random/random_number_spec.rb10
-rw-r--r--spec/ruby/core/random/raw_seed_spec.rb11
-rw-r--r--spec/ruby/core/random/seed_spec.rb2
-rw-r--r--spec/ruby/core/random/shared/bytes.rb17
-rw-r--r--spec/ruby/core/random/shared/rand.rb9
-rw-r--r--spec/ruby/core/random/shared/urandom.rb6
-rw-r--r--spec/ruby/core/random/srand_spec.rb2
-rw-r--r--spec/ruby/core/random/urandom_spec.rb9
-rw-r--r--spec/ruby/core/range/begin_spec.rb6
-rw-r--r--spec/ruby/core/range/bsearch_spec.rb212
-rw-r--r--spec/ruby/core/range/case_compare_spec.rb36
-rw-r--r--spec/ruby/core/range/cover_spec.rb9
-rw-r--r--spec/ruby/core/range/dup_spec.rb6
-rw-r--r--spec/ruby/core/range/each_spec.rb32
-rw-r--r--spec/ruby/core/range/end_spec.rb6
-rw-r--r--spec/ruby/core/range/eql_spec.rb8
-rw-r--r--spec/ruby/core/range/equal_value_spec.rb14
-rw-r--r--spec/ruby/core/range/exclude_end_spec.rb22
-rw-r--r--spec/ruby/core/range/first_spec.rb14
-rw-r--r--spec/ruby/core/range/fixtures/classes.rb25
-rw-r--r--spec/ruby/core/range/hash_spec.rb12
-rw-r--r--spec/ruby/core/range/include_spec.rb10
-rw-r--r--spec/ruby/core/range/initialize_spec.rb31
-rw-r--r--spec/ruby/core/range/inspect_spec.rb27
-rw-r--r--spec/ruby/core/range/last_spec.rb20
-rw-r--r--spec/ruby/core/range/max_spec.rb12
-rw-r--r--spec/ruby/core/range/member_spec.rb10
-rw-r--r--spec/ruby/core/range/min_spec.rb9
-rw-r--r--spec/ruby/core/range/minmax_spec.rb170
-rw-r--r--spec/ruby/core/range/new_spec.rb59
-rw-r--r--spec/ruby/core/range/percent_spec.rb18
-rw-r--r--spec/ruby/core/range/range_spec.rb2
-rw-r--r--spec/ruby/core/range/shared/cover.rb68
-rw-r--r--spec/ruby/core/range/shared/cover_and_include.rb15
-rw-r--r--spec/ruby/core/range/shared/equal_value.rb10
-rw-r--r--spec/ruby/core/range/shared/include.rb6
-rw-r--r--spec/ruby/core/range/size_spec.rb9
-rw-r--r--spec/ruby/core/range/step_spec.rb243
-rw-r--r--spec/ruby/core/range/to_a_spec.rb10
-rw-r--r--spec/ruby/core/range/to_s_spec.rb27
-rw-r--r--spec/ruby/core/rational/abs_spec.rb4
-rw-r--r--spec/ruby/core/rational/ceil_spec.rb4
-rw-r--r--spec/ruby/core/rational/coerce_spec.rb4
-rw-r--r--spec/ruby/core/rational/comparison_spec.rb15
-rw-r--r--spec/ruby/core/rational/denominator_spec.rb4
-rw-r--r--spec/ruby/core/rational/div_spec.rb10
-rw-r--r--spec/ruby/core/rational/divide_spec.rb12
-rw-r--r--spec/ruby/core/rational/divmod_spec.rb8
-rw-r--r--spec/ruby/core/rational/equal_value_spec.rb10
-rw-r--r--spec/ruby/core/rational/exponent_spec.rb4
-rw-r--r--spec/ruby/core/rational/fdiv_spec.rb4
-rw-r--r--spec/ruby/core/rational/floor_spec.rb4
-rw-r--r--spec/ruby/core/rational/hash_spec.rb4
-rw-r--r--spec/ruby/core/rational/inspect_spec.rb4
-rw-r--r--spec/ruby/core/rational/integer_spec.rb7
-rw-r--r--spec/ruby/core/rational/magnitude_spec.rb4
-rw-r--r--spec/ruby/core/rational/marshal_dump_spec.rb2
-rw-r--r--spec/ruby/core/rational/minus_spec.rb6
-rw-r--r--spec/ruby/core/rational/modulo_spec.rb4
-rw-r--r--spec/ruby/core/rational/multiply_spec.rb12
-rw-r--r--spec/ruby/core/rational/numerator_spec.rb4
-rw-r--r--spec/ruby/core/rational/plus_spec.rb12
-rw-r--r--spec/ruby/core/rational/quo_spec.rb4
-rw-r--r--spec/ruby/core/rational/rational_spec.rb2
-rw-r--r--spec/ruby/core/rational/rationalize_spec.rb6
-rw-r--r--spec/ruby/core/rational/remainder_spec.rb4
-rw-r--r--spec/ruby/core/rational/round_spec.rb5
-rw-r--r--spec/ruby/core/rational/to_f_spec.rb4
-rw-r--r--spec/ruby/core/rational/to_i_spec.rb4
-rw-r--r--spec/ruby/core/rational/to_r_spec.rb8
-rw-r--r--spec/ruby/core/rational/to_s_spec.rb4
-rw-r--r--spec/ruby/core/rational/truncate_spec.rb4
-rw-r--r--spec/ruby/core/regexp/case_compare_spec.rb4
-rw-r--r--spec/ruby/core/regexp/casefold_spec.rb6
-rw-r--r--spec/ruby/core/regexp/compile_spec.rb15
-rw-r--r--spec/ruby/core/regexp/encoding_spec.rb10
-rw-r--r--spec/ruby/core/regexp/eql_spec.rb4
-rw-r--r--spec/ruby/core/regexp/equal_value_spec.rb4
-rw-r--r--spec/ruby/core/regexp/escape_spec.rb4
-rw-r--r--spec/ruby/core/regexp/fixed_encoding_spec.rb2
-rw-r--r--spec/ruby/core/regexp/hash_spec.rb2
-rw-r--r--spec/ruby/core/regexp/initialize_spec.rb16
-rw-r--r--spec/ruby/core/regexp/inspect_spec.rb2
-rw-r--r--spec/ruby/core/regexp/last_match_spec.rb4
-rw-r--r--spec/ruby/core/regexp/match_spec.rb86
-rw-r--r--spec/ruby/core/regexp/named_captures_spec.rb2
-rw-r--r--spec/ruby/core/regexp/names_spec.rb2
-rw-r--r--spec/ruby/core/regexp/new_spec.rb21
-rw-r--r--spec/ruby/core/regexp/options_spec.rb10
-rw-r--r--spec/ruby/core/regexp/quote_spec.rb4
-rw-r--r--spec/ruby/core/regexp/shared/new.rb505
-rw-r--r--spec/ruby/core/regexp/shared/new_ascii.rb464
-rw-r--r--spec/ruby/core/regexp/shared/new_ascii_8bit.rb553
-rw-r--r--spec/ruby/core/regexp/shared/quote.rb6
-rw-r--r--spec/ruby/core/regexp/source_spec.rb2
-rw-r--r--spec/ruby/core/regexp/to_s_spec.rb2
-rw-r--r--spec/ruby/core/regexp/try_convert_spec.rb2
-rw-r--r--spec/ruby/core/regexp/union_spec.rb40
-rw-r--r--spec/ruby/core/signal/fixtures/trap_all.rb15
-rw-r--r--spec/ruby/core/signal/list_spec.rb6
-rw-r--r--spec/ruby/core/signal/signame_spec.rb21
-rw-r--r--spec/ruby/core/signal/trap_spec.rb95
-rw-r--r--spec/ruby/core/sizedqueue/append_spec.rb11
-rw-r--r--spec/ruby/core/sizedqueue/clear_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/close_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/closed_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/deq_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/empty_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/enq_spec.rb11
-rw-r--r--spec/ruby/core/sizedqueue/length_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/max_spec.rb10
-rw-r--r--spec/ruby/core/sizedqueue/new_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/num_waiting_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/pop_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/push_spec.rb11
-rw-r--r--spec/ruby/core/sizedqueue/shift_spec.rb6
-rw-r--r--spec/ruby/core/sizedqueue/size_spec.rb6
-rw-r--r--spec/ruby/core/string/allocate_spec.rb2
-rw-r--r--spec/ruby/core/string/append_spec.rb6
-rw-r--r--spec/ruby/core/string/ascii_only_spec.rb130
-rw-r--r--spec/ruby/core/string/b_spec.rb22
-rw-r--r--spec/ruby/core/string/bytes_spec.rb34
-rw-r--r--spec/ruby/core/string/bytesize_spec.rb52
-rw-r--r--spec/ruby/core/string/byteslice_spec.rb20
-rw-r--r--spec/ruby/core/string/capitalize_spec.rb188
-rw-r--r--spec/ruby/core/string/case_compare_spec.rb10
-rw-r--r--spec/ruby/core/string/casecmp_spec.rb104
-rw-r--r--spec/ruby/core/string/center_spec.rb113
-rw-r--r--spec/ruby/core/string/chars_spec.rb9
-rw-r--r--spec/ruby/core/string/chomp_spec.rb213
-rw-r--r--spec/ruby/core/string/chop_spec.rb82
-rw-r--r--spec/ruby/core/string/chr_spec.rb82
-rw-r--r--spec/ruby/core/string/clear_spec.rb60
-rw-r--r--spec/ruby/core/string/clone_spec.rb5
-rw-r--r--spec/ruby/core/string/codepoints_spec.rb26
-rw-r--r--spec/ruby/core/string/comparison_spec.rb4
-rw-r--r--spec/ruby/core/string/concat_spec.rb36
-rw-r--r--spec/ruby/core/string/count_spec.rb16
-rw-r--r--spec/ruby/core/string/crypt_spec.rb163
-rw-r--r--spec/ruby/core/string/delete_prefix_spec.rb90
-rw-r--r--spec/ruby/core/string/delete_spec.rb46
-rw-r--r--spec/ruby/core/string/delete_suffix_spec.rb90
-rw-r--r--spec/ruby/core/string/downcase_spec.rb191
-rw-r--r--spec/ruby/core/string/dump_spec.rb160
-rw-r--r--spec/ruby/core/string/dup_spec.rb10
-rw-r--r--spec/ruby/core/string/each_byte_spec.rb4
-rw-r--r--spec/ruby/core/string/each_char_spec.rb8
-rw-r--r--spec/ruby/core/string/each_codepoint_spec.rb14
-rw-r--r--spec/ruby/core/string/each_grapheme_cluster_spec.rb9
-rw-r--r--spec/ruby/core/string/each_line_spec.rb12
-rw-r--r--spec/ruby/core/string/element_reference_spec.rb6
-rw-r--r--spec/ruby/core/string/element_set_spec.rb464
-rw-r--r--spec/ruby/core/string/empty_spec.rb14
-rw-r--r--spec/ruby/core/string/encode_spec.rb259
-rw-r--r--spec/ruby/core/string/encoding_spec.rb370
-rw-r--r--spec/ruby/core/string/end_with_spec.rb50
-rw-r--r--spec/ruby/core/string/eql_spec.rb6
-rw-r--r--spec/ruby/core/string/equal_value_spec.rb10
-rw-r--r--spec/ruby/core/string/fixtures/classes.rb13
-rw-r--r--spec/ruby/core/string/force_encoding_spec.rb92
-rw-r--r--spec/ruby/core/string/freeze_spec.rb7
-rw-r--r--spec/ruby/core/string/getbyte_spec.rb8
-rw-r--r--spec/ruby/core/string/grapheme_clusters_spec.rb13
-rw-r--r--spec/ruby/core/string/gsub_spec.rb278
-rw-r--r--spec/ruby/core/string/hash_spec.rb4
-rw-r--r--spec/ruby/core/string/hex_spec.rb4
-rw-r--r--spec/ruby/core/string/include_spec.rb12
-rw-r--r--spec/ruby/core/string/index_spec.rb75
-rw-r--r--spec/ruby/core/string/initialize_spec.rb6
-rw-r--r--spec/ruby/core/string/insert_spec.rb64
-rw-r--r--spec/ruby/core/string/inspect_spec.rb32
-rw-r--r--spec/ruby/core/string/intern_spec.rb8
-rw-r--r--spec/ruby/core/string/length_spec.rb8
-rw-r--r--spec/ruby/core/string/lines_spec.rb19
-rw-r--r--spec/ruby/core/string/ljust_spec.rb111
-rw-r--r--spec/ruby/core/string/lstrip_spec.rb42
-rw-r--r--spec/ruby/core/string/match_spec.rb66
-rw-r--r--spec/ruby/core/string/modulo_spec.rb243
-rw-r--r--spec/ruby/core/string/multiply_spec.rb8
-rw-r--r--spec/ruby/core/string/new_spec.rb23
-rw-r--r--spec/ruby/core/string/next_spec.rb10
-rw-r--r--spec/ruby/core/string/oct_spec.rb4
-rw-r--r--spec/ruby/core/string/ord_spec.rb40
-rw-r--r--spec/ruby/core/string/partition_spec.rb8
-rw-r--r--spec/ruby/core/string/plus_spec.rb24
-rw-r--r--spec/ruby/core/string/prepend_spec.rb56
-rw-r--r--spec/ruby/core/string/replace_spec.rb6
-rw-r--r--spec/ruby/core/string/reverse_spec.rb38
-rw-r--r--spec/ruby/core/string/rindex_spec.rb46
-rw-r--r--spec/ruby/core/string/rjust_spec.rb111
-rw-r--r--spec/ruby/core/string/rpartition_spec.rb8
-rw-r--r--spec/ruby/core/string/rstrip_spec.rb24
-rw-r--r--spec/ruby/core/string/scan_spec.rb69
-rw-r--r--spec/ruby/core/string/scrub_spec.rb6
-rw-r--r--spec/ruby/core/string/setbyte_spec.rb14
-rw-r--r--spec/ruby/core/string/shared/chars.rb88
-rw-r--r--spec/ruby/core/string/shared/codepoints.rb20
-rw-r--r--spec/ruby/core/string/shared/concat.rb62
-rw-r--r--spec/ruby/core/string/shared/each_char_without_block.rb4
-rw-r--r--spec/ruby/core/string/shared/each_line.rb110
-rw-r--r--spec/ruby/core/string/shared/encode.rb48
-rw-r--r--spec/ruby/core/string/shared/eql.rb4
-rw-r--r--spec/ruby/core/string/shared/equal_value.rb6
-rw-r--r--spec/ruby/core/string/shared/grapheme_clusters.rb16
-rw-r--r--spec/ruby/core/string/shared/length.rb35
-rw-r--r--spec/ruby/core/string/shared/replace.rb62
-rw-r--r--spec/ruby/core/string/shared/slice.rb328
-rw-r--r--spec/ruby/core/string/shared/succ.rb32
-rw-r--r--spec/ruby/core/string/shared/to_s.rb8
-rw-r--r--spec/ruby/core/string/shared/to_sym.rb67
-rw-r--r--spec/ruby/core/string/size_spec.rb8
-rw-r--r--spec/ruby/core/string/slice_spec.rb338
-rw-r--r--spec/ruby/core/string/split_spec.rb342
-rw-r--r--spec/ruby/core/string/squeeze_spec.rb48
-rw-r--r--spec/ruby/core/string/start_with_spec.rb45
-rw-r--r--spec/ruby/core/string/string_spec.rb2
-rw-r--r--spec/ruby/core/string/strip_spec.rb46
-rw-r--r--spec/ruby/core/string/sub_spec.rb205
-rw-r--r--spec/ruby/core/string/succ_spec.rb10
-rw-r--r--spec/ruby/core/string/sum_spec.rb4
-rw-r--r--spec/ruby/core/string/swapcase_spec.rb178
-rw-r--r--spec/ruby/core/string/to_c_spec.rb2
-rw-r--r--spec/ruby/core/string/to_f_spec.rb5
-rw-r--r--spec/ruby/core/string/to_i_spec.rb28
-rw-r--r--spec/ruby/core/string/to_r_spec.rb4
-rw-r--r--spec/ruby/core/string/to_s_spec.rb8
-rw-r--r--spec/ruby/core/string/to_str_spec.rb8
-rw-r--r--spec/ruby/core/string/to_sym_spec.rb8
-rw-r--r--spec/ruby/core/string/tr_s_spec.rb110
-rw-r--r--spec/ruby/core/string/tr_spec.rb86
-rw-r--r--spec/ruby/core/string/try_convert_spec.rb8
-rw-r--r--spec/ruby/core/string/uminus_spec.rb84
-rw-r--r--spec/ruby/core/string/undump_spec.rb451
-rw-r--r--spec/ruby/core/string/unicode_normalize_spec.rb10
-rw-r--r--spec/ruby/core/string/unicode_normalized_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack/a_spec.rb17
-rw-r--r--spec/ruby/core/string/unpack/at_spec.rb10
-rw-r--r--spec/ruby/core/string/unpack/b_spec.rb11
-rw-r--r--spec/ruby/core/string/unpack/c_spec.rb10
-rw-r--r--spec/ruby/core/string/unpack/comment_spec.rb6
-rw-r--r--spec/ruby/core/string/unpack/d_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/e_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/f_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/g_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/h_spec.rb19
-rw-r--r--spec/ruby/core/string/unpack/i_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/j_spec.rb427
-rw-r--r--spec/ruby/core/string/unpack/l_spec.rb24
-rw-r--r--spec/ruby/core/string/unpack/m_spec.rb25
-rw-r--r--spec/ruby/core/string/unpack/n_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/p_spec.rb53
-rw-r--r--spec/ruby/core/string/unpack/percent_spec.rb4
-rw-r--r--spec/ruby/core/string/unpack/q_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/s_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/shared/basic.rb8
-rw-r--r--spec/ruby/core/string/unpack/shared/float.rb2
-rw-r--r--spec/ruby/core/string/unpack/shared/integer.rb2
-rw-r--r--spec/ruby/core/string/unpack/shared/taint.rb83
-rw-r--r--spec/ruby/core/string/unpack/u_spec.rb21
-rw-r--r--spec/ruby/core/string/unpack/v_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/w_spec.rb18
-rw-r--r--spec/ruby/core/string/unpack/x_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack/z_spec.rb12
-rw-r--r--spec/ruby/core/string/unpack1_spec.rb10
-rw-r--r--spec/ruby/core/string/upcase_spec.rb181
-rw-r--r--spec/ruby/core/string/uplus_spec.rb32
-rw-r--r--spec/ruby/core/string/upto_spec.rb12
-rw-r--r--spec/ruby/core/string/valid_encoding_spec.rb244
-rw-r--r--spec/ruby/core/struct/clone_spec.rb7
-rw-r--r--spec/ruby/core/struct/deconstruct_keys_spec.rb70
-rw-r--r--spec/ruby/core/struct/deconstruct_spec.rb12
-rw-r--r--spec/ruby/core/struct/dig_spec.rb64
-rw-r--r--spec/ruby/core/struct/dup_spec.rb7
-rw-r--r--spec/ruby/core/struct/each_pair_spec.rb8
-rw-r--r--spec/ruby/core/struct/each_spec.rb8
-rw-r--r--spec/ruby/core/struct/element_reference_spec.rb16
-rw-r--r--spec/ruby/core/struct/element_set_spec.rb12
-rw-r--r--spec/ruby/core/struct/eql_spec.rb10
-rw-r--r--spec/ruby/core/struct/equal_value_spec.rb8
-rw-r--r--spec/ruby/core/struct/filter_spec.rb12
-rw-r--r--spec/ruby/core/struct/hash_spec.rb24
-rw-r--r--spec/ruby/core/struct/initialize_spec.rb6
-rw-r--r--spec/ruby/core/struct/inspect_spec.rb13
-rw-r--r--spec/ruby/core/struct/instance_variable_get_spec.rb16
-rw-r--r--spec/ruby/core/struct/instance_variables_spec.rb4
-rw-r--r--spec/ruby/core/struct/length_spec.rb6
-rw-r--r--spec/ruby/core/struct/members_spec.rb6
-rw-r--r--spec/ruby/core/struct/new_spec.rb114
-rw-r--r--spec/ruby/core/struct/select_spec.rb30
-rw-r--r--spec/ruby/core/struct/shared/dup.rb9
-rw-r--r--spec/ruby/core/struct/shared/equal_value.rb7
-rw-r--r--spec/ruby/core/struct/shared/select.rb26
-rw-r--r--spec/ruby/core/struct/size_spec.rb6
-rw-r--r--spec/ruby/core/struct/struct_spec.rb6
-rw-r--r--spec/ruby/core/struct/tms/cstime_spec.rb9
-rw-r--r--spec/ruby/core/struct/tms/cutime_spec.rb9
-rw-r--r--spec/ruby/core/struct/tms/element_reference_spec.rb5
-rw-r--r--spec/ruby/core/struct/tms/members_spec.rb5
-rw-r--r--spec/ruby/core/struct/tms/new_spec.rb5
-rw-r--r--spec/ruby/core/struct/tms/stime_spec.rb9
-rw-r--r--spec/ruby/core/struct/tms/utime_spec.rb9
-rw-r--r--spec/ruby/core/struct/to_a_spec.rb6
-rw-r--r--spec/ruby/core/struct/to_h_spec.rb47
-rw-r--r--spec/ruby/core/struct/to_s_spec.rb8
-rw-r--r--spec/ruby/core/struct/values_at_spec.rb6
-rw-r--r--spec/ruby/core/struct/values_spec.rb4
-rw-r--r--spec/ruby/core/symbol/all_symbols_spec.rb13
-rw-r--r--spec/ruby/core/symbol/capitalize_spec.rb16
-rw-r--r--spec/ruby/core/symbol/case_compare_spec.rb2
-rw-r--r--spec/ruby/core/symbol/casecmp_spec.rb108
-rw-r--r--spec/ruby/core/symbol/comparison_spec.rb4
-rw-r--r--spec/ruby/core/symbol/downcase_spec.rb9
-rw-r--r--spec/ruby/core/symbol/dup_spec.rb7
-rw-r--r--spec/ruby/core/symbol/element_reference_spec.rb6
-rw-r--r--spec/ruby/core/symbol/empty_spec.rb2
-rw-r--r--spec/ruby/core/symbol/encoding_spec.rb2
-rw-r--r--spec/ruby/core/symbol/end_with_spec.rb10
-rw-r--r--spec/ruby/core/symbol/equal_value_spec.rb2
-rw-r--r--spec/ruby/core/symbol/id2name_spec.rb6
-rw-r--r--spec/ruby/core/symbol/inspect_spec.rb2
-rw-r--r--spec/ruby/core/symbol/intern_spec.rb2
-rw-r--r--spec/ruby/core/symbol/length_spec.rb4
-rw-r--r--spec/ruby/core/symbol/match_spec.rb75
-rw-r--r--spec/ruby/core/symbol/next_spec.rb4
-rw-r--r--spec/ruby/core/symbol/shared/slice.rb50
-rw-r--r--spec/ruby/core/symbol/shared/succ.rb2
-rw-r--r--spec/ruby/core/symbol/size_spec.rb4
-rw-r--r--spec/ruby/core/symbol/slice_spec.rb6
-rw-r--r--spec/ruby/core/symbol/start_with_spec.rb10
-rw-r--r--spec/ruby/core/symbol/succ_spec.rb4
-rw-r--r--spec/ruby/core/symbol/swapcase_spec.rb13
-rw-r--r--spec/ruby/core/symbol/symbol_spec.rb6
-rw-r--r--spec/ruby/core/symbol/to_proc_spec.rb53
-rw-r--r--spec/ruby/core/symbol/to_s_spec.rb6
-rw-r--r--spec/ruby/core/symbol/to_sym_spec.rb2
-rw-r--r--spec/ruby/core/symbol/upcase_spec.rb9
-rw-r--r--spec/ruby/core/systemexit/initialize_spec.rb3
-rw-r--r--spec/ruby/core/systemexit/success_spec.rb6
-rw-r--r--spec/ruby/core/thread/abort_on_exception_spec.rb6
-rw-r--r--spec/ruby/core/thread/add_trace_func_spec.rb2
-rw-r--r--spec/ruby/core/thread/alive_spec.rb24
-rw-r--r--spec/ruby/core/thread/allocate_spec.rb4
-rw-r--r--spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb75
-rw-r--r--spec/ruby/core/thread/backtrace/location/base_label_spec.rb41
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/absolute_path.rb4
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/absolute_path_main.rb2
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/absolute_path_method_added.rb10
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/classes.rb18
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/locations_in_main.rb5
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/locations_in_required.rb3
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/main.rb4
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/path.rb2
-rw-r--r--spec/ruby/core/thread/backtrace/location/inspect_spec.rb4
-rw-r--r--spec/ruby/core/thread/backtrace/location/label_spec.rb21
-rw-r--r--spec/ruby/core/thread/backtrace/location/lineno_spec.rb14
-rw-r--r--spec/ruby/core/thread/backtrace/location/path_spec.rb45
-rw-r--r--spec/ruby/core/thread/backtrace/location/to_s_spec.rb4
-rw-r--r--spec/ruby/core/thread/backtrace_locations_spec.rb75
-rw-r--r--spec/ruby/core/thread/backtrace_spec.rb44
-rw-r--r--spec/ruby/core/thread/current_spec.rb20
-rw-r--r--spec/ruby/core/thread/element_reference_spec.rb8
-rw-r--r--spec/ruby/core/thread/element_set_spec.rb25
-rw-r--r--spec/ruby/core/thread/exclusive_spec.rb57
-rw-r--r--spec/ruby/core/thread/exit_spec.rb6
-rw-r--r--spec/ruby/core/thread/fetch_spec.rb36
-rw-r--r--spec/ruby/core/thread/fixtures/classes.rb19
-rw-r--r--spec/ruby/core/thread/fork_spec.rb6
-rw-r--r--spec/ruby/core/thread/group_spec.rb4
-rw-r--r--spec/ruby/core/thread/initialize_spec.rb6
-rw-r--r--spec/ruby/core/thread/inspect_spec.rb44
-rw-r--r--spec/ruby/core/thread/join_spec.rb34
-rw-r--r--spec/ruby/core/thread/key_spec.rb10
-rw-r--r--spec/ruby/core/thread/keys_spec.rb4
-rw-r--r--spec/ruby/core/thread/kill_spec.rb36
-rw-r--r--spec/ruby/core/thread/list_spec.rb29
-rw-r--r--spec/ruby/core/thread/main_spec.rb4
-rw-r--r--spec/ruby/core/thread/name_spec.rb106
-rw-r--r--spec/ruby/core/thread/new_spec.rb43
-rw-r--r--spec/ruby/core/thread/pass_spec.rb4
-rw-r--r--spec/ruby/core/thread/priority_spec.rb26
-rw-r--r--spec/ruby/core/thread/raise_spec.rb59
-rw-r--r--spec/ruby/core/thread/report_on_exception_spec.rb106
-rw-r--r--spec/ruby/core/thread/run_spec.rb7
-rw-r--r--spec/ruby/core/thread/set_trace_func_spec.rb2
-rw-r--r--spec/ruby/core/thread/shared/exit.rb32
-rw-r--r--spec/ruby/core/thread/shared/start.rb2
-rw-r--r--spec/ruby/core/thread/shared/to_s.rb55
-rw-r--r--spec/ruby/core/thread/shared/wakeup.rb2
-rw-r--r--spec/ruby/core/thread/start_spec.rb6
-rw-r--r--spec/ruby/core/thread/status_spec.rb4
-rw-r--r--spec/ruby/core/thread/stop_spec.rb24
-rw-r--r--spec/ruby/core/thread/terminate_spec.rb6
-rw-r--r--spec/ruby/core/thread/thread_variable_get_spec.rb2
-rw-r--r--spec/ruby/core/thread/thread_variable_set_spec.rb2
-rw-r--r--spec/ruby/core/thread/thread_variable_spec.rb2
-rw-r--r--spec/ruby/core/thread/thread_variables_spec.rb11
-rw-r--r--spec/ruby/core/thread/to_s_spec.rb6
-rw-r--r--spec/ruby/core/thread/value_spec.rb21
-rw-r--r--spec/ruby/core/thread/wakeup_spec.rb6
-rw-r--r--spec/ruby/core/threadgroup/add_spec.rb47
-rw-r--r--spec/ruby/core/threadgroup/default_spec.rb2
-rw-r--r--spec/ruby/core/threadgroup/enclose_spec.rb13
-rw-r--r--spec/ruby/core/threadgroup/enclosed_spec.rb2
-rw-r--r--spec/ruby/core/threadgroup/fixtures/classes.rb6
-rw-r--r--spec/ruby/core/threadgroup/list_spec.rb13
-rw-r--r--spec/ruby/core/time/_dump_spec.rb7
-rw-r--r--spec/ruby/core/time/_load_spec.rb14
-rw-r--r--spec/ruby/core/time/asctime_spec.rb6
-rw-r--r--spec/ruby/core/time/at_spec.rb135
-rw-r--r--spec/ruby/core/time/ceil_spec.rb46
-rw-r--r--spec/ruby/core/time/comparison_spec.rb12
-rw-r--r--spec/ruby/core/time/ctime_spec.rb6
-rw-r--r--spec/ruby/core/time/day_spec.rb6
-rw-r--r--spec/ruby/core/time/dst_spec.rb6
-rw-r--r--spec/ruby/core/time/dup_spec.rb6
-rw-r--r--spec/ruby/core/time/eql_spec.rb2
-rw-r--r--spec/ruby/core/time/fixtures/classes.rb94
-rw-r--r--spec/ruby/core/time/floor_spec.rb38
-rw-r--r--spec/ruby/core/time/friday_spec.rb6
-rw-r--r--spec/ruby/core/time/getgm_spec.rb6
-rw-r--r--spec/ruby/core/time/getlocal_spec.rb81
-rw-r--r--spec/ruby/core/time/getutc_spec.rb6
-rw-r--r--spec/ruby/core/time/gm_spec.rb14
-rw-r--r--spec/ruby/core/time/gmt_offset_spec.rb6
-rw-r--r--spec/ruby/core/time/gmt_spec.rb6
-rw-r--r--spec/ruby/core/time/gmtime_spec.rb6
-rw-r--r--spec/ruby/core/time/gmtoff_spec.rb6
-rw-r--r--spec/ruby/core/time/hash_spec.rb6
-rw-r--r--spec/ruby/core/time/hour_spec.rb2
-rw-r--r--spec/ruby/core/time/inspect_spec.rb19
-rw-r--r--spec/ruby/core/time/isdst_spec.rb6
-rw-r--r--spec/ruby/core/time/local_spec.rb16
-rw-r--r--spec/ruby/core/time/localtime_spec.rb25
-rw-r--r--spec/ruby/core/time/mday_spec.rb6
-rw-r--r--spec/ruby/core/time/min_spec.rb2
-rw-r--r--spec/ruby/core/time/minus_spec.rb38
-rw-r--r--spec/ruby/core/time/mktime_spec.rb16
-rw-r--r--spec/ruby/core/time/mon_spec.rb6
-rw-r--r--spec/ruby/core/time/monday_spec.rb6
-rw-r--r--spec/ruby/core/time/month_spec.rb6
-rw-r--r--spec/ruby/core/time/new_spec.rb268
-rw-r--r--spec/ruby/core/time/now_spec.rb6
-rw-r--r--spec/ruby/core/time/nsec_spec.rb6
-rw-r--r--spec/ruby/core/time/plus_spec.rb40
-rw-r--r--spec/ruby/core/time/round_spec.rb8
-rw-r--r--spec/ruby/core/time/saturday_spec.rb6
-rw-r--r--spec/ruby/core/time/sec_spec.rb2
-rw-r--r--spec/ruby/core/time/shared/gm.rb48
-rw-r--r--spec/ruby/core/time/shared/gmt_offset.rb6
-rw-r--r--spec/ruby/core/time/shared/gmtime.rb2
-rw-r--r--spec/ruby/core/time/shared/inspect.rb6
-rw-r--r--spec/ruby/core/time/shared/local.rb2
-rw-r--r--spec/ruby/core/time/shared/now.rb27
-rw-r--r--spec/ruby/core/time/shared/time_params.rb36
-rw-r--r--spec/ruby/core/time/shared/to_i.rb7
-rw-r--r--spec/ruby/core/time/strftime_spec.rb16
-rw-r--r--spec/ruby/core/time/subsec_spec.rb4
-rw-r--r--spec/ruby/core/time/succ_spec.rb54
-rw-r--r--spec/ruby/core/time/sunday_spec.rb6
-rw-r--r--spec/ruby/core/time/thursday_spec.rb6
-rw-r--r--spec/ruby/core/time/time_spec.rb2
-rw-r--r--spec/ruby/core/time/to_a_spec.rb2
-rw-r--r--spec/ruby/core/time/to_f_spec.rb2
-rw-r--r--spec/ruby/core/time/to_i_spec.rb6
-rw-r--r--spec/ruby/core/time/to_r_spec.rb2
-rw-r--r--spec/ruby/core/time/to_s_spec.rb4
-rw-r--r--spec/ruby/core/time/tuesday_spec.rb6
-rw-r--r--spec/ruby/core/time/tv_nsec_spec.rb2
-rw-r--r--spec/ruby/core/time/tv_sec_spec.rb6
-rw-r--r--spec/ruby/core/time/tv_usec_spec.rb2
-rw-r--r--spec/ruby/core/time/usec_spec.rb6
-rw-r--r--spec/ruby/core/time/utc_offset_spec.rb6
-rw-r--r--spec/ruby/core/time/utc_spec.rb20
-rw-r--r--spec/ruby/core/time/wday_spec.rb2
-rw-r--r--spec/ruby/core/time/wednesday_spec.rb6
-rw-r--r--spec/ruby/core/time/yday_spec.rb2
-rw-r--r--spec/ruby/core/time/year_spec.rb2
-rw-r--r--spec/ruby/core/time/zone_spec.rb4
-rw-r--r--spec/ruby/core/tracepoint/binding_spec.rb21
-rw-r--r--spec/ruby/core/tracepoint/callee_id_spec.rb18
-rw-r--r--spec/ruby/core/tracepoint/defined_class_spec.rb27
-rw-r--r--spec/ruby/core/tracepoint/disable_spec.rb76
-rw-r--r--spec/ruby/core/tracepoint/enable_spec.rb551
-rw-r--r--spec/ruby/core/tracepoint/enabled_spec.rb15
-rw-r--r--spec/ruby/core/tracepoint/eval_script_spec.rb25
-rw-r--r--spec/ruby/core/tracepoint/event_spec.rb22
-rw-r--r--spec/ruby/core/tracepoint/fixtures/classes.rb40
-rw-r--r--spec/ruby/core/tracepoint/inspect_spec.rb125
-rw-r--r--spec/ruby/core/tracepoint/lineno_spec.rb20
-rw-r--r--spec/ruby/core/tracepoint/method_id_spec.rb15
-rw-r--r--spec/ruby/core/tracepoint/new_spec.rb72
-rw-r--r--spec/ruby/core/tracepoint/parameters_spec.rb30
-rw-r--r--spec/ruby/core/tracepoint/path_spec.rb26
-rw-r--r--spec/ruby/core/tracepoint/raised_exception_spec.rb20
-rw-r--r--spec/ruby/core/tracepoint/return_value_spec.rb17
-rw-r--r--spec/ruby/core/tracepoint/self_spec.rb26
-rw-r--r--spec/ruby/core/tracepoint/trace_spec.rb10
-rw-r--r--spec/ruby/core/true/and_spec.rb2
-rw-r--r--spec/ruby/core/true/case_compare_spec.rb13
-rw-r--r--spec/ruby/core/true/dup_spec.rb7
-rw-r--r--spec/ruby/core/true/inspect_spec.rb2
-rw-r--r--spec/ruby/core/true/or_spec.rb2
-rw-r--r--spec/ruby/core/true/to_s_spec.rb12
-rw-r--r--spec/ruby/core/true/trueclass_spec.rb6
-rw-r--r--spec/ruby/core/true/xor_spec.rb2
-rw-r--r--spec/ruby/core/unboundmethod/arity_spec.rb2
-rw-r--r--spec/ruby/core/unboundmethod/bind_call_spec.rb52
-rw-r--r--spec/ruby/core/unboundmethod/bind_spec.rb20
-rw-r--r--spec/ruby/core/unboundmethod/clone_spec.rb4
-rw-r--r--spec/ruby/core/unboundmethod/eql_spec.rb2
-rw-r--r--spec/ruby/core/unboundmethod/equal_value_spec.rb4
-rw-r--r--spec/ruby/core/unboundmethod/fixtures/classes.rb1
-rw-r--r--spec/ruby/core/unboundmethod/hash_spec.rb6
-rw-r--r--spec/ruby/core/unboundmethod/inspect_spec.rb8
-rw-r--r--spec/ruby/core/unboundmethod/name_spec.rb4
-rw-r--r--spec/ruby/core/unboundmethod/original_name_spec.rb22
-rw-r--r--spec/ruby/core/unboundmethod/owner_spec.rb4
-rw-r--r--spec/ruby/core/unboundmethod/parameters_spec.rb2
-rw-r--r--spec/ruby/core/unboundmethod/shared/to_s.rb13
-rw-r--r--spec/ruby/core/unboundmethod/source_location_spec.rb10
-rw-r--r--spec/ruby/core/unboundmethod/super_method_spec.rb4
-rw-r--r--spec/ruby/core/unboundmethod/to_s_spec.rb8
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb14
-rw-r--r--spec/ruby/core/warning/element_set_spec.rb31
-rw-r--r--spec/ruby/core/warning/warn_spec.rb91
-rw-r--r--spec/ruby/default.mspec24
-rw-r--r--spec/ruby/fixtures/class.rb4
-rw-r--r--spec/ruby/fixtures/code/load_fixture_and__FILE__.rb1
-rw-r--r--spec/ruby/fixtures/code/recursive_require_fixture.rb2
-rw-r--r--spec/ruby/fixtures/code/wrap_fixture.rb8
-rw-r--r--spec/ruby/fixtures/code_loading.rb15
-rw-r--r--spec/ruby/fixtures/constants.rb18
-rw-r--r--spec/ruby/fixtures/rational.rb3
-rw-r--r--spec/ruby/language/BEGIN_spec.rb13
-rw-r--r--spec/ruby/language/END_spec.rb15
-rw-r--r--spec/ruby/language/README4
-rw-r--r--spec/ruby/language/alias_spec.rb45
-rw-r--r--spec/ruby/language/and_spec.rb2
-rw-r--r--spec/ruby/language/array_spec.rb11
-rw-r--r--spec/ruby/language/block_spec.rb315
-rw-r--r--spec/ruby/language/break_spec.rb69
-rw-r--r--spec/ruby/language/case_spec.rb274
-rw-r--r--spec/ruby/language/class_spec.rb92
-rw-r--r--spec/ruby/language/class_variable_spec.rb8
-rw-r--r--spec/ruby/language/comment_spec.rb15
-rw-r--r--spec/ruby/language/constants_spec.rb240
-rw-r--r--spec/ruby/language/def_spec.rb189
-rw-r--r--spec/ruby/language/defined_spec.rb88
-rw-r--r--spec/ruby/language/delegation_spec.rb41
-rw-r--r--spec/ruby/language/encoding_spec.rb16
-rw-r--r--spec/ruby/language/ensure_spec.rb271
-rw-r--r--spec/ruby/language/execution_spec.rb2
-rw-r--r--spec/ruby/language/file_spec.rb8
-rw-r--r--spec/ruby/language/fixtures/array.rb21
-rw-r--r--spec/ruby/language/fixtures/begin_file.rb3
-rw-r--r--spec/ruby/language/fixtures/binary_symbol.rb4
-rw-r--r--spec/ruby/language/fixtures/block.rb4
-rw-r--r--spec/ruby/language/fixtures/break.rb38
-rw-r--r--spec/ruby/language/fixtures/break_lambda_toplevel.rb2
-rw-r--r--spec/ruby/language/fixtures/break_lambda_toplevel_block.rb2
-rw-r--r--spec/ruby/language/fixtures/break_lambda_toplevel_method.rb2
-rw-r--r--spec/ruby/language/fixtures/bytes_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/case_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/def.rb6
-rw-r--r--spec/ruby/language/fixtures/defined.rb5
-rw-r--r--spec/ruby/language/fixtures/delegation.rb11
-rw-r--r--spec/ruby/language/fixtures/emacs_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/ensure.rb51
-rw-r--r--spec/ruby/language/fixtures/for_scope.rb15
-rw-r--r--spec/ruby/language/fixtures/hash_strings_ascii8bit.rb7
-rw-r--r--spec/ruby/language/fixtures/hash_strings_binary.rb7
-rw-r--r--spec/ruby/language/fixtures/magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/metaclass.rb1
-rw-r--r--spec/ruby/language/fixtures/no_magic_comment.rb1
-rw-r--r--spec/ruby/language/fixtures/print_magic_comment_result_at_exit.rb3
-rw-r--r--spec/ruby/language/fixtures/rescue.rb4
-rw-r--r--spec/ruby/language/fixtures/rescue_captures.rb107
-rw-r--r--spec/ruby/language/fixtures/second_line_magic_comment.rb3
-rw-r--r--spec/ruby/language/fixtures/second_token_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/send.rb3
-rwxr-xr-xspec/ruby/language/fixtures/shebang_magic_comment.rb3
-rw-r--r--spec/ruby/language/fixtures/squiggly_heredoc.rb24
-rw-r--r--spec/ruby/language/fixtures/super.rb219
-rw-r--r--spec/ruby/language/fixtures/utf16-be-nobom.rbbin0 -> 68 bytes-rw-r--r--spec/ruby/language/fixtures/utf16-le-nobom.rbbin0 -> 69 bytes-rw-r--r--spec/ruby/language/fixtures/utf8-bom.rb2
-rw-r--r--spec/ruby/language/fixtures/utf8-nobom.rb2
-rw-r--r--spec/ruby/language/fixtures/vim_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/yield.rb4
-rw-r--r--spec/ruby/language/for_spec.rb17
-rw-r--r--spec/ruby/language/hash_spec.rb41
-rw-r--r--spec/ruby/language/heredoc_spec.rb75
-rw-r--r--spec/ruby/language/if_spec.rb19
-rw-r--r--spec/ruby/language/lambda_spec.rb175
-rw-r--r--spec/ruby/language/line_spec.rb8
-rw-r--r--spec/ruby/language/loop_spec.rb4
-rw-r--r--spec/ruby/language/magic_comment_spec.rb110
-rw-r--r--spec/ruby/language/match_spec.rb11
-rw-r--r--spec/ruby/language/metaclass_spec.rb18
-rw-r--r--spec/ruby/language/method_spec.rb964
-rw-r--r--spec/ruby/language/module_spec.rb36
-rw-r--r--spec/ruby/language/next_spec.rb16
-rw-r--r--spec/ruby/language/not_spec.rb2
-rw-r--r--spec/ruby/language/numbered_parameters_spec.rb106
-rw-r--r--spec/ruby/language/numbers_spec.rb12
-rw-r--r--spec/ruby/language/optional_assignments_spec.rb141
-rw-r--r--spec/ruby/language/or_spec.rb14
-rw-r--r--spec/ruby/language/order_spec.rb2
-rw-r--r--spec/ruby/language/pattern_matching_spec.rb1035
-rw-r--r--spec/ruby/language/precedence_spec.rb39
-rw-r--r--spec/ruby/language/predefined/data_spec.rb21
-rw-r--r--spec/ruby/language/predefined/fixtures/data2.rb3
-rw-r--r--spec/ruby/language/predefined/fixtures/data3.rb3
-rw-r--r--spec/ruby/language/predefined/fixtures/data_offset.rb12
-rw-r--r--spec/ruby/language/predefined/fixtures/empty_data.rb3
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_dynamic.rb4
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_dynamic_required.rb2
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_id.rb4
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_id_required.rb1
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_required_before.rb2
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_values.rb9
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_variables.rb4
-rw-r--r--spec/ruby/language/predefined/fixtures/toplevel_binding_variables_required.rb2
-rw-r--r--spec/ruby/language/predefined/toplevel_binding_spec.rb34
-rw-r--r--spec/ruby/language/predefined_spec.rb453
-rw-r--r--spec/ruby/language/private_spec.rb18
-rw-r--r--spec/ruby/language/proc_spec.rb4
-rw-r--r--spec/ruby/language/range_spec.rb26
-rw-r--r--spec/ruby/language/redo_spec.rb6
-rw-r--r--spec/ruby/language/regexp/anchors_spec.rb4
-rw-r--r--spec/ruby/language/regexp/back-references_spec.rb11
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb33
-rw-r--r--spec/ruby/language/regexp/encoding_spec.rb40
-rw-r--r--spec/ruby/language/regexp/escapes_spec.rb12
-rw-r--r--spec/ruby/language/regexp/grouping_spec.rb6
-rw-r--r--spec/ruby/language/regexp/interpolation_spec.rb8
-rw-r--r--spec/ruby/language/regexp/modifiers_spec.rb19
-rw-r--r--spec/ruby/language/regexp/repetition_spec.rb21
-rw-r--r--spec/ruby/language/regexp_spec.rb53
-rw-r--r--spec/ruby/language/rescue_spec.rb274
-rw-r--r--spec/ruby/language/retry_spec.rb4
-rw-r--r--spec/ruby/language/return_spec.rb258
-rw-r--r--spec/ruby/language/safe_navigator_spec.rb144
-rw-r--r--spec/ruby/language/safe_spec.rb152
-rw-r--r--spec/ruby/language/send_spec.rb93
-rw-r--r--spec/ruby/language/singleton_class_spec.rb41
-rw-r--r--spec/ruby/language/source_encoding_spec.rb61
-rw-r--r--spec/ruby/language/string_spec.rb137
-rw-r--r--spec/ruby/language/super_spec.rb324
-rw-r--r--spec/ruby/language/symbol_spec.rb15
-rw-r--r--spec/ruby/language/throw_spec.rb25
-rw-r--r--spec/ruby/language/undef_spec.rb14
-rw-r--r--spec/ruby/language/unless_spec.rb2
-rw-r--r--spec/ruby/language/until_spec.rb4
-rw-r--r--spec/ruby/language/variables_spec.rb95
-rw-r--r--spec/ruby/language/while_spec.rb4
-rw-r--r--spec/ruby/language/yield_spec.rb56
-rw-r--r--spec/ruby/library/English/English_spec.rb26
-rw-r--r--spec/ruby/library/English/alias_spec.rb14
-rw-r--r--spec/ruby/library/abbrev/abbrev_spec.rb6
-rw-r--r--spec/ruby/library/base64/decode64_spec.rb18
-rw-r--r--spec/ruby/library/base64/encode64_spec.rb11
-rw-r--r--spec/ruby/library/base64/strict_decode64_spec.rb41
-rw-r--r--spec/ruby/library/base64/strict_encode64_spec.rb19
-rw-r--r--spec/ruby/library/base64/urlsafe_decode64_spec.rb14
-rw-r--r--spec/ruby/library/base64/urlsafe_encode64_spec.rb10
-rw-r--r--spec/ruby/library/bigdecimal/BigDecimal_spec.rb298
-rw-r--r--spec/ruby/library/bigdecimal/abs_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/add_spec.rb38
-rw-r--r--spec/ruby/library/bigdecimal/case_compare_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/ceil_spec.rb8
-rw-r--r--spec/ruby/library/bigdecimal/clone_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/coerce_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/comparison_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/constants_spec.rb70
-rw-r--r--spec/ruby/library/bigdecimal/div_spec.rb56
-rw-r--r--spec/ruby/library/bigdecimal/divide_spec.rb14
-rw-r--r--spec/ruby/library/bigdecimal/divmod_spec.rb28
-rw-r--r--spec/ruby/library/bigdecimal/double_fig_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/dup_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/eql_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/equal_value_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/exponent_spec.rb8
-rw-r--r--spec/ruby/library/bigdecimal/finite_spec.rb11
-rw-r--r--spec/ruby/library/bigdecimal/fix_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/floor_spec.rb8
-rw-r--r--spec/ruby/library/bigdecimal/frac_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/gt_spec.rb32
-rw-r--r--spec/ruby/library/bigdecimal/gte_spec.rb32
-rw-r--r--spec/ruby/library/bigdecimal/hash_spec.rb30
-rw-r--r--spec/ruby/library/bigdecimal/infinite_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/inspect_spec.rb45
-rw-r--r--spec/ruby/library/bigdecimal/limit_spec.rb31
-rw-r--r--spec/ruby/library/bigdecimal/lt_spec.rb32
-rw-r--r--spec/ruby/library/bigdecimal/lte_spec.rb32
-rw-r--r--spec/ruby/library/bigdecimal/minus_spec.rb28
-rw-r--r--spec/ruby/library/bigdecimal/mode_spec.rb14
-rw-r--r--spec/ruby/library/bigdecimal/modulo_spec.rb12
-rw-r--r--spec/ruby/library/bigdecimal/mult_spec.rb14
-rw-r--r--spec/ruby/library/bigdecimal/multiply_spec.rb19
-rw-r--r--spec/ruby/library/bigdecimal/nan_spec.rb24
-rw-r--r--spec/ruby/library/bigdecimal/new_spec.rb109
-rw-r--r--spec/ruby/library/bigdecimal/nonzero_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/plus_spec.rb15
-rw-r--r--spec/ruby/library/bigdecimal/power_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/precs_spec.rb71
-rw-r--r--spec/ruby/library/bigdecimal/quo_spec.rb9
-rw-r--r--spec/ruby/library/bigdecimal/remainder_spec.rb54
-rw-r--r--spec/ruby/library/bigdecimal/round_spec.rb256
-rw-r--r--spec/ruby/library/bigdecimal/shared/clone.rb13
-rw-r--r--spec/ruby/library/bigdecimal/shared/eql.rb4
-rw-r--r--spec/ruby/library/bigdecimal/shared/modulo.rb51
-rw-r--r--spec/ruby/library/bigdecimal/shared/mult.rb20
-rw-r--r--spec/ruby/library/bigdecimal/shared/power.rb4
-rw-r--r--spec/ruby/library/bigdecimal/shared/quo.rb18
-rw-r--r--spec/ruby/library/bigdecimal/shared/to_int.rb6
-rw-r--r--spec/ruby/library/bigdecimal/sign_spec.rb5
-rw-r--r--spec/ruby/library/bigdecimal/split_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/sqrt_spec.rb24
-rw-r--r--spec/ruby/library/bigdecimal/sub_spec.rb27
-rw-r--r--spec/ruby/library/bigdecimal/to_d_spec.rb10
-rw-r--r--spec/ruby/library/bigdecimal/to_f_spec.rb5
-rw-r--r--spec/ruby/library/bigdecimal/to_i_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/to_int_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/to_r_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/to_s_spec.rb66
-rw-r--r--spec/ruby/library/bigdecimal/truncate_spec.rb14
-rw-r--r--spec/ruby/library/bigdecimal/uminus_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/uplus_spec.rb5
-rw-r--r--spec/ruby/library/bigdecimal/util_spec.rb42
-rw-r--r--spec/ruby/library/bigdecimal/ver_spec.rb11
-rw-r--r--spec/ruby/library/bigdecimal/zero_spec.rb29
-rw-r--r--spec/ruby/library/bigmath/log_spec.rb2
-rw-r--r--spec/ruby/library/cgi/cookie/domain_spec.rb2
-rw-r--r--spec/ruby/library/cgi/cookie/expires_spec.rb2
-rw-r--r--spec/ruby/library/cgi/cookie/initialize_spec.rb6
-rw-r--r--spec/ruby/library/cgi/cookie/name_spec.rb14
-rw-r--r--spec/ruby/library/cgi/cookie/parse_spec.rb14
-rw-r--r--spec/ruby/library/cgi/cookie/path_spec.rb2
-rw-r--r--spec/ruby/library/cgi/cookie/secure_spec.rb2
-rw-r--r--spec/ruby/library/cgi/cookie/to_s_spec.rb15
-rw-r--r--spec/ruby/library/cgi/cookie/value_spec.rb2
-rw-r--r--spec/ruby/library/cgi/escapeElement_spec.rb2
-rw-r--r--spec/ruby/library/cgi/escapeHTML_spec.rb6
-rw-r--r--spec/ruby/library/cgi/escape_spec.rb18
-rw-r--r--spec/ruby/library/cgi/htmlextension/a_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/base_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/blockquote_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/br_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/caption_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/checkbox_group_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/checkbox_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/doctype_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/file_field_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/form_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/frame_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/frameset_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/hidden_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/html_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/image_button_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/img_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/multipart_form_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/password_field_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/popup_menu_spec.rb6
-rw-r--r--spec/ruby/library/cgi/htmlextension/radio_button_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/radio_group_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/reset_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/scrolling_list_spec.rb6
-rw-r--r--spec/ruby/library/cgi/htmlextension/submit_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/text_field_spec.rb4
-rw-r--r--spec/ruby/library/cgi/htmlextension/textarea_spec.rb4
-rw-r--r--spec/ruby/library/cgi/http_header_spec.rb6
-rw-r--r--spec/ruby/library/cgi/initialize_spec.rb2
-rw-r--r--spec/ruby/library/cgi/out_spec.rb4
-rw-r--r--spec/ruby/library/cgi/parse_spec.rb2
-rw-r--r--spec/ruby/library/cgi/pretty_spec.rb2
-rw-r--r--spec/ruby/library/cgi/print_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_charset_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_encoding_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_language_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/auth_type_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/cache_control_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/content_length_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/content_type_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/cookies_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/element_reference_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/from_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/gateway_interface_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/has_key_spec.rb4
-rw-r--r--spec/ruby/library/cgi/queryextension/host_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/include_spec.rb4
-rw-r--r--spec/ruby/library/cgi/queryextension/key_spec.rb4
-rw-r--r--spec/ruby/library/cgi/queryextension/keys_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/multipart_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/negotiate_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/params_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/path_info_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/path_translated_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/pragma_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/query_string_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/raw_cookie2_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/raw_cookie_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/referer_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_addr_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_host_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_ident_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_user_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/request_method_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/script_name_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/server_name_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/server_port_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/server_protocol_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/server_software_spec.rb2
-rw-r--r--spec/ruby/library/cgi/queryextension/user_agent_spec.rb2
-rw-r--r--spec/ruby/library/cgi/rfc1123_date_spec.rb4
-rw-r--r--spec/ruby/library/cgi/shared/http_header.rb8
-rw-r--r--spec/ruby/library/cgi/unescapeElement_spec.rb2
-rw-r--r--spec/ruby/library/cgi/unescapeHTML_spec.rb7
-rw-r--r--spec/ruby/library/cgi/unescape_spec.rb6
-rw-r--r--spec/ruby/library/cmath/math/acos_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/acosh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/asin_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/asinh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/atan2_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/atan_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/atanh_spec.rb20
-rw-r--r--spec/ruby/library/cmath/math/cos_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/cosh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/exp_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/fixtures/classes.rb (renamed from spec/ruby/library/complex/math/fixtures/classes.rb)0
-rw-r--r--spec/ruby/library/cmath/math/log10_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/log_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/shared/acos.rb41
-rw-r--r--spec/ruby/library/cmath/math/shared/acosh.rb37
-rw-r--r--spec/ruby/library/cmath/math/shared/asin.rb47
-rw-r--r--spec/ruby/library/cmath/math/shared/asinh.rb32
-rw-r--r--spec/ruby/library/cmath/math/shared/atan.rb32
-rw-r--r--spec/ruby/library/cmath/math/shared/atan2.rb34
-rw-r--r--spec/ruby/library/cmath/math/shared/atanh.rb30
-rw-r--r--spec/ruby/library/cmath/math/shared/cos.rb30
-rw-r--r--spec/ruby/library/cmath/math/shared/cosh.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/exp.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/log.rb39
-rw-r--r--spec/ruby/library/cmath/math/shared/log10.rb41
-rw-r--r--spec/ruby/library/cmath/math/shared/sin.rb30
-rw-r--r--spec/ruby/library/cmath/math/shared/sinh.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/sqrt.rb34
-rw-r--r--spec/ruby/library/cmath/math/shared/tan.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/tanh.rb32
-rw-r--r--spec/ruby/library/cmath/math/sin_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/sinh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/sqrt_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/tan_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/tanh_spec.rb18
-rw-r--r--spec/ruby/library/complex/math/acos_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/acosh_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/asin_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/asinh_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/atan2_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/atan_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/atanh_spec.rb17
-rw-r--r--spec/ruby/library/complex/math/cos_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/cosh_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/exp_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/log10_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/log_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/shared/acos.rb41
-rw-r--r--spec/ruby/library/complex/math/shared/acosh.rb37
-rw-r--r--spec/ruby/library/complex/math/shared/asin.rb47
-rw-r--r--spec/ruby/library/complex/math/shared/asinh.rb32
-rw-r--r--spec/ruby/library/complex/math/shared/atan.rb32
-rw-r--r--spec/ruby/library/complex/math/shared/atan2.rb34
-rw-r--r--spec/ruby/library/complex/math/shared/atanh.rb30
-rw-r--r--spec/ruby/library/complex/math/shared/cos.rb30
-rw-r--r--spec/ruby/library/complex/math/shared/cosh.rb28
-rw-r--r--spec/ruby/library/complex/math/shared/exp.rb28
-rw-r--r--spec/ruby/library/complex/math/shared/log.rb39
-rw-r--r--spec/ruby/library/complex/math/shared/log10.rb41
-rw-r--r--spec/ruby/library/complex/math/shared/sin.rb30
-rw-r--r--spec/ruby/library/complex/math/shared/sinh.rb28
-rw-r--r--spec/ruby/library/complex/math/shared/sqrt.rb34
-rw-r--r--spec/ruby/library/complex/math/shared/tan.rb28
-rw-r--r--spec/ruby/library/complex/math/shared/tanh.rb32
-rw-r--r--spec/ruby/library/complex/math/sin_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/sinh_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/sqrt_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/tan_spec.rb15
-rw-r--r--spec/ruby/library/complex/math/tanh_spec.rb15
-rw-r--r--spec/ruby/library/complex/numeric/im_spec.rb3
-rw-r--r--spec/ruby/library/conditionvariable/broadcast_spec.rb31
-rw-r--r--spec/ruby/library/conditionvariable/marshal_dump_spec.rb9
-rw-r--r--spec/ruby/library/conditionvariable/signal_spec.rb66
-rw-r--r--spec/ruby/library/conditionvariable/wait_spec.rb158
-rw-r--r--spec/ruby/library/coverage/fixtures/eval_code.rb11
-rw-r--r--spec/ruby/library/coverage/fixtures/spec_helper.rb11
-rw-r--r--spec/ruby/library/coverage/peek_result_spec.rb105
-rw-r--r--spec/ruby/library/coverage/result_spec.rb36
-rw-r--r--spec/ruby/library/coverage/start_spec.rb2
-rw-r--r--spec/ruby/library/csv/basicwriter/close_on_terminate_spec.rb2
-rw-r--r--spec/ruby/library/csv/basicwriter/initialize_spec.rb2
-rw-r--r--spec/ruby/library/csv/basicwriter/terminate_spec.rb2
-rw-r--r--spec/ruby/library/csv/cell/data_spec.rb2
-rw-r--r--spec/ruby/library/csv/cell/initialize_spec.rb2
-rw-r--r--spec/ruby/library/csv/foreach_spec.rb2
-rw-r--r--spec/ruby/library/csv/generate_line_spec.rb2
-rw-r--r--spec/ruby/library/csv/generate_row_spec.rb2
-rw-r--r--spec/ruby/library/csv/generate_spec.rb4
-rw-r--r--spec/ruby/library/csv/iobuf/close_spec.rb2
-rw-r--r--spec/ruby/library/csv/iobuf/initialize_spec.rb2
-rw-r--r--spec/ruby/library/csv/iobuf/read_spec.rb2
-rw-r--r--spec/ruby/library/csv/iobuf/terminate_spec.rb2
-rw-r--r--spec/ruby/library/csv/ioreader/close_on_terminate_spec.rb2
-rw-r--r--spec/ruby/library/csv/ioreader/get_row_spec.rb2
-rw-r--r--spec/ruby/library/csv/ioreader/initialize_spec.rb2
-rw-r--r--spec/ruby/library/csv/ioreader/terminate_spec.rb2
-rw-r--r--spec/ruby/library/csv/liberal_parsing_spec.rb19
-rw-r--r--spec/ruby/library/csv/open_spec.rb2
-rw-r--r--spec/ruby/library/csv/parse_spec.rb14
-rw-r--r--spec/ruby/library/csv/read_spec.rb2
-rw-r--r--spec/ruby/library/csv/readlines_spec.rb14
-rw-r--r--spec/ruby/library/csv/streambuf/add_buf_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/buf_size_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/drop_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/element_reference_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/get_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/idx_is_eos_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/initialize_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/is_eos_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/read_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/rel_buf_spec.rb2
-rw-r--r--spec/ruby/library/csv/streambuf/terminate_spec.rb2
-rw-r--r--spec/ruby/library/csv/stringreader/get_row_spec.rb2
-rw-r--r--spec/ruby/library/csv/stringreader/initialize_spec.rb2
-rw-r--r--spec/ruby/library/csv/writer/add_row_spec.rb2
-rw-r--r--spec/ruby/library/csv/writer/append_spec.rb2
-rw-r--r--spec/ruby/library/csv/writer/close_spec.rb2
-rw-r--r--spec/ruby/library/csv/writer/create_spec.rb2
-rw-r--r--spec/ruby/library/csv/writer/generate_spec.rb2
-rw-r--r--spec/ruby/library/csv/writer/initialize_spec.rb2
-rw-r--r--spec/ruby/library/csv/writer/terminate_spec.rb2
-rw-r--r--spec/ruby/library/date/accessor_spec.rb2
-rw-r--r--spec/ruby/library/date/add_month_spec.rb10
-rw-r--r--spec/ruby/library/date/add_spec.rb10
-rw-r--r--spec/ruby/library/date/ajd_spec.rb2
-rw-r--r--spec/ruby/library/date/ajd_to_amjd_spec.rb2
-rw-r--r--spec/ruby/library/date/ajd_to_jd_spec.rb2
-rw-r--r--spec/ruby/library/date/amjd_spec.rb2
-rw-r--r--spec/ruby/library/date/amjd_to_ajd_spec.rb2
-rw-r--r--spec/ruby/library/date/append_spec.rb2
-rw-r--r--spec/ruby/library/date/asctime_spec.rb2
-rw-r--r--spec/ruby/library/date/boat_spec.rb2
-rw-r--r--spec/ruby/library/date/case_compare_spec.rb2
-rw-r--r--spec/ruby/library/date/civil_spec.rb6
-rw-r--r--spec/ruby/library/date/commercial_spec.rb7
-rw-r--r--spec/ruby/library/date/commercial_to_jd_spec.rb2
-rw-r--r--spec/ruby/library/date/comparison_spec.rb2
-rw-r--r--spec/ruby/library/date/constants_spec.rb10
-rw-r--r--spec/ruby/library/date/conversions_spec.rb2
-rw-r--r--spec/ruby/library/date/ctime_spec.rb2
-rw-r--r--spec/ruby/library/date/cwday_spec.rb2
-rw-r--r--spec/ruby/library/date/cweek_spec.rb2
-rw-r--r--spec/ruby/library/date/cwyear_spec.rb2
-rw-r--r--spec/ruby/library/date/day_fraction_spec.rb2
-rw-r--r--spec/ruby/library/date/day_fraction_to_time_spec.rb2
-rw-r--r--spec/ruby/library/date/day_spec.rb2
-rw-r--r--spec/ruby/library/date/downto_spec.rb2
-rw-r--r--spec/ruby/library/date/england_spec.rb2
-rw-r--r--spec/ruby/library/date/eql_spec.rb2
-rw-r--r--spec/ruby/library/date/format/bag/method_missing_spec.rb2
-rw-r--r--spec/ruby/library/date/format/bag/to_hash_spec.rb2
-rw-r--r--spec/ruby/library/date/friday_spec.rb12
-rw-r--r--spec/ruby/library/date/gregorian_leap_spec.rb3
-rw-r--r--spec/ruby/library/date/gregorian_spec.rb4
-rw-r--r--spec/ruby/library/date/hash_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/abs_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/coerce_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/comparison_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/d_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/finite_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/infinite_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/nan_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/uminus_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/uplus_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity/zero_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity_spec.rb16
-rw-r--r--spec/ruby/library/date/inspect_spec.rb2
-rw-r--r--spec/ruby/library/date/iso8601_spec.rb44
-rw-r--r--spec/ruby/library/date/italy_spec.rb2
-rw-r--r--spec/ruby/library/date/jd_spec.rb4
-rw-r--r--spec/ruby/library/date/jd_to_ajd_spec.rb2
-rw-r--r--spec/ruby/library/date/jd_to_civil_spec.rb2
-rw-r--r--spec/ruby/library/date/jd_to_commercial_spec.rb2
-rw-r--r--spec/ruby/library/date/jd_to_ld_spec.rb2
-rw-r--r--spec/ruby/library/date/jd_to_mjd_spec.rb2
-rw-r--r--spec/ruby/library/date/jd_to_ordinal_spec.rb2
-rw-r--r--spec/ruby/library/date/jd_to_wday_spec.rb2
-rw-r--r--spec/ruby/library/date/julian_leap_spec.rb2
-rw-r--r--spec/ruby/library/date/julian_spec.rb6
-rw-r--r--spec/ruby/library/date/ld_spec.rb2
-rw-r--r--spec/ruby/library/date/ld_to_jd_spec.rb2
-rw-r--r--spec/ruby/library/date/leap_spec.rb2
-rw-r--r--spec/ruby/library/date/mday_spec.rb2
-rw-r--r--spec/ruby/library/date/minus_month_spec.rb25
-rw-r--r--spec/ruby/library/date/minus_spec.rb12
-rw-r--r--spec/ruby/library/date/mjd_spec.rb2
-rw-r--r--spec/ruby/library/date/mjd_to_jd_spec.rb2
-rw-r--r--spec/ruby/library/date/mon_spec.rb2
-rw-r--r--spec/ruby/library/date/monday_spec.rb8
-rw-r--r--spec/ruby/library/date/month_spec.rb2
-rw-r--r--spec/ruby/library/date/new_spec.rb8
-rw-r--r--spec/ruby/library/date/new_start_spec.rb2
-rw-r--r--spec/ruby/library/date/next_day_spec.rb12
-rw-r--r--spec/ruby/library/date/next_month_spec.rb17
-rw-r--r--spec/ruby/library/date/next_spec.rb2
-rw-r--r--spec/ruby/library/date/next_year_spec.rb2
-rw-r--r--spec/ruby/library/date/ordinal_spec.rb5
-rw-r--r--spec/ruby/library/date/ordinal_to_jd_spec.rb2
-rw-r--r--spec/ruby/library/date/parse_spec.rb32
-rw-r--r--spec/ruby/library/date/plus_spec.rb4
-rw-r--r--spec/ruby/library/date/prev_day_spec.rb8
-rw-r--r--spec/ruby/library/date/prev_month_spec.rb17
-rw-r--r--spec/ruby/library/date/prev_year_spec.rb2
-rw-r--r--spec/ruby/library/date/relationship_spec.rb2
-rw-r--r--spec/ruby/library/date/rfc3339_spec.rb13
-rw-r--r--spec/ruby/library/date/right_shift_spec.rb2
-rw-r--r--spec/ruby/library/date/saturday_spec.rb8
-rw-r--r--spec/ruby/library/date/shared/civil.rb24
-rw-r--r--spec/ruby/library/date/shared/commercial.rb18
-rw-r--r--spec/ruby/library/date/shared/valid_jd.rb27
-rw-r--r--spec/ruby/library/date/start_spec.rb2
-rw-r--r--spec/ruby/library/date/step_spec.rb2
-rw-r--r--spec/ruby/library/date/strftime_spec.rb4
-rw-r--r--spec/ruby/library/date/strptime_spec.rb2
-rw-r--r--spec/ruby/library/date/succ_spec.rb2
-rw-r--r--spec/ruby/library/date/sunday_spec.rb8
-rw-r--r--spec/ruby/library/date/thursday_spec.rb8
-rw-r--r--spec/ruby/library/date/time_to_day_fraction_spec.rb2
-rw-r--r--spec/ruby/library/date/to_s_spec.rb2
-rw-r--r--spec/ruby/library/date/today_spec.rb12
-rw-r--r--spec/ruby/library/date/tuesday_spec.rb8
-rw-r--r--spec/ruby/library/date/upto_spec.rb2
-rw-r--r--spec/ruby/library/date/valid_civil_spec.rb5
-rw-r--r--spec/ruby/library/date/valid_commercial_spec.rb6
-rw-r--r--spec/ruby/library/date/valid_date_spec.rb4
-rw-r--r--spec/ruby/library/date/valid_jd_spec.rb5
-rw-r--r--spec/ruby/library/date/valid_ordinal_spec.rb5
-rw-r--r--spec/ruby/library/date/valid_time_spec.rb2
-rw-r--r--spec/ruby/library/date/wday_spec.rb7
-rw-r--r--spec/ruby/library/date/wednesday_spec.rb8
-rw-r--r--spec/ruby/library/date/yday_spec.rb2
-rw-r--r--spec/ruby/library/date/year_spec.rb2
-rw-r--r--spec/ruby/library/date/zone_to_diff_spec.rb2
-rw-r--r--spec/ruby/library/datetime/_strptime_spec.rb2
-rw-r--r--spec/ruby/library/datetime/add_spec.rb9
-rw-r--r--spec/ruby/library/datetime/civil_spec.rb2
-rw-r--r--spec/ruby/library/datetime/commercial_spec.rb2
-rw-r--r--spec/ruby/library/datetime/hour_spec.rb14
-rw-r--r--spec/ruby/library/datetime/httpdate_spec.rb2
-rw-r--r--spec/ruby/library/datetime/iso8601_spec.rb2
-rw-r--r--spec/ruby/library/datetime/jd_spec.rb2
-rw-r--r--spec/ruby/library/datetime/jisx0301_spec.rb2
-rw-r--r--spec/ruby/library/datetime/min_spec.rb4
-rw-r--r--spec/ruby/library/datetime/minute_spec.rb4
-rw-r--r--spec/ruby/library/datetime/new_offset_spec.rb2
-rw-r--r--spec/ruby/library/datetime/new_spec.rb6
-rw-r--r--spec/ruby/library/datetime/now_spec.rb19
-rw-r--r--spec/ruby/library/datetime/offset_spec.rb2
-rw-r--r--spec/ruby/library/datetime/ordinal_spec.rb2
-rw-r--r--spec/ruby/library/datetime/parse_spec.rb14
-rw-r--r--spec/ruby/library/datetime/rfc2822_spec.rb2
-rw-r--r--spec/ruby/library/datetime/rfc3339_spec.rb2
-rw-r--r--spec/ruby/library/datetime/rfc822_spec.rb2
-rw-r--r--spec/ruby/library/datetime/sec_fraction_spec.rb2
-rw-r--r--spec/ruby/library/datetime/sec_spec.rb4
-rw-r--r--spec/ruby/library/datetime/second_fraction_spec.rb2
-rw-r--r--spec/ruby/library/datetime/second_spec.rb4
-rw-r--r--spec/ruby/library/datetime/shared/min.rb12
-rw-r--r--spec/ruby/library/datetime/shared/sec.rb8
-rw-r--r--spec/ruby/library/datetime/strftime_spec.rb12
-rw-r--r--spec/ruby/library/datetime/strptime_spec.rb2
-rw-r--r--spec/ruby/library/datetime/subtract_spec.rb19
-rw-r--r--spec/ruby/library/datetime/to_date_spec.rb35
-rw-r--r--spec/ruby/library/datetime/to_datetime_spec.rb7
-rw-r--r--spec/ruby/library/datetime/to_s_spec.rb15
-rw-r--r--spec/ruby/library/datetime/to_time_spec.rb34
-rw-r--r--spec/ruby/library/datetime/xmlschema_spec.rb2
-rw-r--r--spec/ruby/library/datetime/zone_spec.rb2
-rw-r--r--spec/ruby/library/delegate/delegate_class/instance_method_spec.rb8
-rw-r--r--spec/ruby/library/delegate/delegate_class/instance_methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegate_class/private_instance_methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegate_class/protected_instance_methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegate_class/public_instance_methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/case_compare_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/compare_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/complement_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/eql_spec.rb59
-rw-r--r--spec/ruby/library/delegate/delegator/equal_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/equal_value_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/frozen_spec.rb10
-rw-r--r--spec/ruby/library/delegate/delegator/hash_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/marshal_spec.rb2
-rw-r--r--spec/ruby/library/delegate/delegator/method_spec.rb12
-rw-r--r--spec/ruby/library/delegate/delegator/methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/not_equal_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/not_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/private_methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/protected_methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/public_methods_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/send_spec.rb12
-rw-r--r--spec/ruby/library/delegate/delegator/taint_spec.rb28
-rw-r--r--spec/ruby/library/delegate/delegator/tap_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegator/trust_spec.rb26
-rw-r--r--spec/ruby/library/delegate/delegator/untaint_spec.rb32
-rw-r--r--spec/ruby/library/delegate/delegator/untrust_spec.rb28
-rw-r--r--spec/ruby/library/digest/bubblebabble_spec.rb10
-rw-r--r--spec/ruby/library/digest/hexencode_spec.rb8
-rw-r--r--spec/ruby/library/digest/instance/append_spec.rb7
-rw-r--r--spec/ruby/library/digest/instance/new_spec.rb19
-rw-r--r--spec/ruby/library/digest/instance/shared/update.rb8
-rw-r--r--spec/ruby/library/digest/instance/update_spec.rb7
-rw-r--r--spec/ruby/library/digest/md5/append_spec.rb8
-rw-r--r--spec/ruby/library/digest/md5/block_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/md5/digest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/md5/digest_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/md5/digest_spec.rb4
-rw-r--r--spec/ruby/library/digest/md5/equal_spec.rb5
-rw-r--r--spec/ruby/library/digest/md5/file_spec.rb10
-rw-r--r--spec/ruby/library/digest/md5/hexdigest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/md5/hexdigest_spec.rb4
-rw-r--r--spec/ruby/library/digest/md5/inspect_spec.rb5
-rw-r--r--spec/ruby/library/digest/md5/length_spec.rb7
-rw-r--r--spec/ruby/library/digest/md5/reset_spec.rb5
-rw-r--r--spec/ruby/library/digest/md5/shared/constants.rb1
-rw-r--r--spec/ruby/library/digest/md5/size_spec.rb7
-rw-r--r--spec/ruby/library/digest/md5/to_s_spec.rb4
-rw-r--r--spec/ruby/library/digest/md5/update_spec.rb6
-rw-r--r--spec/ruby/library/digest/sha1/digest_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha1/file_spec.rb10
-rw-r--r--spec/ruby/library/digest/sha1/shared/constants.rb3
-rw-r--r--spec/ruby/library/digest/sha2/hexdigest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha256/append_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha256/block_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha256/digest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha256/digest_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha256/digest_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha256/equal_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha256/file_spec.rb14
-rw-r--r--spec/ruby/library/digest/sha256/hexdigest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha256/hexdigest_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha256/inspect_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha256/length_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha256/reset_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha256/shared/constants.rb1
-rw-r--r--spec/ruby/library/digest/sha256/size_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha256/to_s_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha256/update_spec.rb6
-rw-r--r--spec/ruby/library/digest/sha384/append_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha384/block_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha384/digest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha384/digest_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha384/digest_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha384/equal_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha384/file_spec.rb10
-rw-r--r--spec/ruby/library/digest/sha384/hexdigest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha384/hexdigest_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha384/inspect_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha384/length_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha384/reset_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha384/shared/constants.rb1
-rw-r--r--spec/ruby/library/digest/sha384/size_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha384/to_s_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha384/update_spec.rb6
-rw-r--r--spec/ruby/library/digest/sha512/append_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha512/block_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha512/digest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha512/digest_length_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha512/digest_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha512/equal_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha512/file_spec.rb10
-rw-r--r--spec/ruby/library/digest/sha512/hexdigest_bang_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha512/hexdigest_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha512/inspect_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha512/length_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha512/reset_spec.rb5
-rw-r--r--spec/ruby/library/digest/sha512/shared/constants.rb1
-rw-r--r--spec/ruby/library/digest/sha512/size_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha512/to_s_spec.rb4
-rw-r--r--spec/ruby/library/digest/sha512/update_spec.rb6
-rw-r--r--spec/ruby/library/drb/start_service_spec.rb4
-rw-r--r--spec/ruby/library/erb/def_class_spec.rb2
-rw-r--r--spec/ruby/library/erb/def_method_spec.rb2
-rw-r--r--spec/ruby/library/erb/def_module_spec.rb2
-rw-r--r--spec/ruby/library/erb/defmethod/def_erb_method_spec.rb5
-rw-r--r--spec/ruby/library/erb/filename_spec.rb6
-rw-r--r--spec/ruby/library/erb/fixtures/classes.rb9
-rw-r--r--spec/ruby/library/erb/new_spec.rb50
-rw-r--r--spec/ruby/library/erb/result_spec.rb6
-rw-r--r--spec/ruby/library/erb/run_spec.rb7
-rw-r--r--spec/ruby/library/erb/src_spec.rb2
-rw-r--r--spec/ruby/library/erb/util/h_spec.rb4
-rw-r--r--spec/ruby/library/erb/util/html_escape_spec.rb5
-rw-r--r--spec/ruby/library/erb/util/shared/url_encode.rb16
-rw-r--r--spec/ruby/library/erb/util/u_spec.rb5
-rw-r--r--spec/ruby/library/erb/util/url_encode_spec.rb4
-rw-r--r--spec/ruby/library/etc/confstr_spec.rb14
-rw-r--r--spec/ruby/library/etc/endgrent_spec.rb6
-rw-r--r--spec/ruby/library/etc/endpwent_spec.rb6
-rw-r--r--spec/ruby/library/etc/getgrent_spec.rb6
-rw-r--r--spec/ruby/library/etc/getgrgid_spec.rb87
-rw-r--r--spec/ruby/library/etc/getgrnam_spec.rb6
-rw-r--r--spec/ruby/library/etc/getlogin_spec.rb19
-rw-r--r--spec/ruby/library/etc/getpwent_spec.rb6
-rw-r--r--spec/ruby/library/etc/getpwnam_spec.rb4
-rw-r--r--spec/ruby/library/etc/getpwuid_spec.rb4
-rw-r--r--spec/ruby/library/etc/group_spec.rb17
-rw-r--r--spec/ruby/library/etc/nprocessors_spec.rb12
-rw-r--r--spec/ruby/library/etc/passwd_spec.rb15
-rw-r--r--spec/ruby/library/etc/struct_group_spec.rb10
-rw-r--r--spec/ruby/library/etc/struct_passwd_spec.rb4
-rw-r--r--spec/ruby/library/etc/sysconf_spec.rb22
-rw-r--r--spec/ruby/library/etc/sysconfdir_spec.rb8
-rw-r--r--spec/ruby/library/etc/systmpdir_spec.rb8
-rw-r--r--spec/ruby/library/expect/expect_spec.rb4
-rw-r--r--spec/ruby/library/fiber/alive_spec.rb76
-rw-r--r--spec/ruby/library/fiber/current_spec.rb90
-rw-r--r--spec/ruby/library/fiber/resume_spec.rb21
-rw-r--r--spec/ruby/library/fiber/transfer_spec.rb139
-rw-r--r--spec/ruby/library/find/find_spec.rb4
-rw-r--r--spec/ruby/library/find/prune_spec.rb2
-rw-r--r--spec/ruby/library/getoptlong/each_option_spec.rb6
-rw-r--r--spec/ruby/library/getoptlong/each_spec.rb6
-rw-r--r--spec/ruby/library/getoptlong/error_message_spec.rb2
-rw-r--r--spec/ruby/library/getoptlong/get_option_spec.rb6
-rw-r--r--spec/ruby/library/getoptlong/get_spec.rb6
-rw-r--r--spec/ruby/library/getoptlong/initialize_spec.rb2
-rw-r--r--spec/ruby/library/getoptlong/ordering_spec.rb6
-rw-r--r--spec/ruby/library/getoptlong/set_options_spec.rb16
-rw-r--r--spec/ruby/library/getoptlong/shared/get.rb12
-rw-r--r--spec/ruby/library/getoptlong/terminate_spec.rb6
-rw-r--r--spec/ruby/library/getoptlong/terminated_spec.rb8
-rw-r--r--spec/ruby/library/ipaddr/hton_spec.rb2
-rw-r--r--spec/ruby/library/ipaddr/ipv4_conversion_spec.rb12
-rw-r--r--spec/ruby/library/ipaddr/new_spec.rb18
-rw-r--r--spec/ruby/library/ipaddr/operator_spec.rb16
-rw-r--r--spec/ruby/library/ipaddr/reverse_spec.rb6
-rw-r--r--spec/ruby/library/ipaddr/to_s_spec.rb2
-rw-r--r--spec/ruby/library/logger/device/close_spec.rb19
-rw-r--r--spec/ruby/library/logger/device/new_spec.rb12
-rw-r--r--spec/ruby/library/logger/device/write_spec.rb19
-rw-r--r--spec/ruby/library/logger/logger/add_spec.rb10
-rw-r--r--spec/ruby/library/logger/logger/close_spec.rb6
-rw-r--r--spec/ruby/library/logger/logger/datetime_format_spec.rb6
-rw-r--r--spec/ruby/library/logger/logger/debug_spec.rb8
-rw-r--r--spec/ruby/library/logger/logger/error_spec.rb8
-rw-r--r--spec/ruby/library/logger/logger/fatal_spec.rb8
-rw-r--r--spec/ruby/library/logger/logger/info_spec.rb8
-rw-r--r--spec/ruby/library/logger/logger/new_spec.rb75
-rw-r--r--spec/ruby/library/logger/logger/unknown_spec.rb6
-rw-r--r--spec/ruby/library/logger/logger/warn_spec.rb8
-rw-r--r--spec/ruby/library/logger/severity_spec.rb2
-rw-r--r--spec/ruby/library/mathn/bignum/exponent_spec.rb21
-rw-r--r--spec/ruby/library/mathn/complex/Complex_spec.rb14
-rw-r--r--spec/ruby/library/mathn/fixnum/exponent_spec.rb17
-rw-r--r--spec/ruby/library/mathn/float/exponent_spec.rb17
-rw-r--r--spec/ruby/library/mathn/integer/from_prime_division_spec.rb11
-rw-r--r--spec/ruby/library/mathn/integer/prime_division_spec.rb21
-rw-r--r--spec/ruby/library/mathn/math/fixtures/classes.rb3
-rw-r--r--spec/ruby/library/mathn/math/rsqrt_spec.rb17
-rw-r--r--spec/ruby/library/mathn/math/shared/rsqrt.rb21
-rw-r--r--spec/ruby/library/mathn/math/shared/sqrt.rb25
-rw-r--r--spec/ruby/library/mathn/math/sqrt_spec.rb17
-rw-r--r--spec/ruby/library/mathn/rational/Rational_spec.rb14
-rw-r--r--spec/ruby/library/mathn/rational/inspect_spec.rb15
-rw-r--r--spec/ruby/library/matrix/I_spec.rb6
-rw-r--r--spec/ruby/library/matrix/antisymmetric_spec.rb37
-rw-r--r--spec/ruby/library/matrix/build_spec.rb16
-rw-r--r--spec/ruby/library/matrix/clone_spec.rb4
-rw-r--r--spec/ruby/library/matrix/coerce_spec.rb6
-rw-r--r--spec/ruby/library/matrix/collect_spec.rb6
-rw-r--r--spec/ruby/library/matrix/column_size_spec.rb2
-rw-r--r--spec/ruby/library/matrix/column_spec.rb6
-rw-r--r--spec/ruby/library/matrix/column_vector_spec.rb4
-rw-r--r--spec/ruby/library/matrix/column_vectors_spec.rb2
-rw-r--r--spec/ruby/library/matrix/columns_spec.rb4
-rw-r--r--spec/ruby/library/matrix/conj_spec.rb6
-rw-r--r--spec/ruby/library/matrix/conjugate_spec.rb6
-rw-r--r--spec/ruby/library/matrix/constructor_spec.rb16
-rw-r--r--spec/ruby/library/matrix/det_spec.rb6
-rw-r--r--spec/ruby/library/matrix/determinant_spec.rb6
-rw-r--r--spec/ruby/library/matrix/diagonal_spec.rb10
-rw-r--r--spec/ruby/library/matrix/divide_spec.rb25
-rw-r--r--spec/ruby/library/matrix/each_spec.rb8
-rw-r--r--spec/ruby/library/matrix/each_with_index_spec.rb8
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvalue_matrix_spec.rb2
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvalues_spec.rb4
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvector_matrix_spec.rb4
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvectors_spec.rb4
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/initialize_spec.rb8
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/to_a_spec.rb2
-rw-r--r--spec/ruby/library/matrix/element_reference_spec.rb2
-rw-r--r--spec/ruby/library/matrix/empty_spec.rb14
-rw-r--r--spec/ruby/library/matrix/eql_spec.rb6
-rw-r--r--spec/ruby/library/matrix/equal_value_spec.rb6
-rw-r--r--spec/ruby/library/matrix/exponent_spec.rb12
-rw-r--r--spec/ruby/library/matrix/find_index_spec.rb10
-rw-r--r--spec/ruby/library/matrix/hash_spec.rb6
-rw-r--r--spec/ruby/library/matrix/hermitian_spec.rb10
-rw-r--r--spec/ruby/library/matrix/identity_spec.rb6
-rw-r--r--spec/ruby/library/matrix/imag_spec.rb6
-rw-r--r--spec/ruby/library/matrix/imaginary_spec.rb6
-rw-r--r--spec/ruby/library/matrix/inspect_spec.rb4
-rw-r--r--spec/ruby/library/matrix/inv_spec.rb8
-rw-r--r--spec/ruby/library/matrix/inverse_from_spec.rb2
-rw-r--r--spec/ruby/library/matrix/inverse_spec.rb8
-rw-r--r--spec/ruby/library/matrix/lower_triangular_spec.rb2
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/determinant_spec.rb4
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/initialize_spec.rb6
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/l_spec.rb2
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/p_spec.rb2
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/solve_spec.rb8
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/to_a_spec.rb2
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/u_spec.rb2
-rw-r--r--spec/ruby/library/matrix/map_spec.rb6
-rw-r--r--spec/ruby/library/matrix/minor_spec.rb4
-rw-r--r--spec/ruby/library/matrix/minus_spec.rb20
-rw-r--r--spec/ruby/library/matrix/multiply_spec.rb18
-rw-r--r--spec/ruby/library/matrix/new_spec.rb2
-rw-r--r--spec/ruby/library/matrix/normal_spec.rb14
-rw-r--r--spec/ruby/library/matrix/orthogonal_spec.rb14
-rw-r--r--spec/ruby/library/matrix/permutation_spec.rb8
-rw-r--r--spec/ruby/library/matrix/plus_spec.rb20
-rw-r--r--spec/ruby/library/matrix/rank_spec.rb2
-rw-r--r--spec/ruby/library/matrix/real_spec.rb7
-rw-r--r--spec/ruby/library/matrix/rect_spec.rb6
-rw-r--r--spec/ruby/library/matrix/rectangular_spec.rb6
-rw-r--r--spec/ruby/library/matrix/regular_spec.rb6
-rw-r--r--spec/ruby/library/matrix/round_spec.rb4
-rw-r--r--spec/ruby/library/matrix/row_size_spec.rb2
-rw-r--r--spec/ruby/library/matrix/row_spec.rb6
-rw-r--r--spec/ruby/library/matrix/row_vector_spec.rb4
-rw-r--r--spec/ruby/library/matrix/row_vectors_spec.rb2
-rw-r--r--spec/ruby/library/matrix/rows_spec.rb4
-rw-r--r--spec/ruby/library/matrix/scalar/Fail_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/Raise_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/divide_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/exponent_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/included_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/initialize_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/minus_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/multiply_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar/plus_spec.rb2
-rw-r--r--spec/ruby/library/matrix/scalar_spec.rb2
-rw-r--r--spec/ruby/library/matrix/shared/collect.rb2
-rw-r--r--spec/ruby/library/matrix/shared/conjugate.rb2
-rw-r--r--spec/ruby/library/matrix/shared/determinant.rb4
-rw-r--r--spec/ruby/library/matrix/shared/equal_value.rb2
-rw-r--r--spec/ruby/library/matrix/shared/identity.rb2
-rw-r--r--spec/ruby/library/matrix/shared/imaginary.rb2
-rw-r--r--spec/ruby/library/matrix/shared/inverse.rb4
-rw-r--r--spec/ruby/library/matrix/shared/rectangular.rb2
-rw-r--r--spec/ruby/library/matrix/shared/trace.rb2
-rw-r--r--spec/ruby/library/matrix/shared/transpose.rb2
-rw-r--r--spec/ruby/library/matrix/singular_spec.rb6
-rw-r--r--spec/ruby/library/matrix/square_spec.rb2
-rw-r--r--spec/ruby/library/matrix/symmetric_spec.rb10
-rw-r--r--spec/ruby/library/matrix/t_spec.rb6
-rw-r--r--spec/ruby/library/matrix/to_a_spec.rb2
-rw-r--r--spec/ruby/library/matrix/to_s_spec.rb2
-rw-r--r--spec/ruby/library/matrix/tr_spec.rb6
-rw-r--r--spec/ruby/library/matrix/trace_spec.rb6
-rw-r--r--spec/ruby/library/matrix/transpose_spec.rb6
-rw-r--r--spec/ruby/library/matrix/unit_spec.rb6
-rw-r--r--spec/ruby/library/matrix/unitary_spec.rb23
-rw-r--r--spec/ruby/library/matrix/upper_triangular_spec.rb2
-rw-r--r--spec/ruby/library/matrix/vector/cross_product_spec.rb4
-rw-r--r--spec/ruby/library/matrix/vector/each2_spec.rb10
-rw-r--r--spec/ruby/library/matrix/vector/eql_spec.rb2
-rw-r--r--spec/ruby/library/matrix/vector/inner_product_spec.rb4
-rw-r--r--spec/ruby/library/matrix/vector/normalize_spec.rb6
-rw-r--r--spec/ruby/library/matrix/zero_spec.rb14
-rw-r--r--spec/ruby/library/mkmf/mkmf_spec.rb7
-rw-r--r--spec/ruby/library/monitor/mon_initialize_spec.rb31
-rw-r--r--spec/ruby/library/net/FTPError_spec.rb2
-rw-r--r--spec/ruby/library/net/FTPPermError_spec.rb2
-rw-r--r--spec/ruby/library/net/FTPProtoError_spec.rb2
-rw-r--r--spec/ruby/library/net/FTPReplyError_spec.rb2
-rw-r--r--spec/ruby/library/net/FTPTempError_spec.rb2
-rw-r--r--spec/ruby/library/net/ftp/abort_spec.rb20
-rw-r--r--spec/ruby/library/net/ftp/acct_spec.rb18
-rw-r--r--spec/ruby/library/net/ftp/binary_spec.rb4
-rw-r--r--spec/ruby/library/net/ftp/chdir_spec.rb30
-rw-r--r--spec/ruby/library/net/ftp/close_spec.rb4
-rw-r--r--spec/ruby/library/net/ftp/closed_spec.rb4
-rw-r--r--spec/ruby/library/net/ftp/connect_spec.rb16
-rw-r--r--spec/ruby/library/net/ftp/debug_mode_spec.rb4
-rw-r--r--spec/ruby/library/net/ftp/default_passive_spec.rb12
-rw-r--r--spec/ruby/library/net/ftp/delete_spec.rb20
-rw-r--r--spec/ruby/library/net/ftp/dir_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/fixtures/server.rb14
-rw-r--r--spec/ruby/library/net/ftp/get_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/getbinaryfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/getdir_spec.rb6
-rw-r--r--spec/ruby/library/net/ftp/gettextfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/help_spec.rb18
-rw-r--r--spec/ruby/library/net/ftp/initialize_spec.rb324
-rw-r--r--spec/ruby/library/net/ftp/last_response_code_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/last_response_spec.rb6
-rw-r--r--spec/ruby/library/net/ftp/lastresp_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/list_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/login_spec.rb48
-rw-r--r--spec/ruby/library/net/ftp/ls_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/mdtm_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/mkdir_spec.rb18
-rw-r--r--spec/ruby/library/net/ftp/mtime_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/nlst_spec.rb26
-rw-r--r--spec/ruby/library/net/ftp/noop_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/open_spec.rb4
-rw-r--r--spec/ruby/library/net/ftp/passive_spec.rb16
-rw-r--r--spec/ruby/library/net/ftp/put_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/putbinaryfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/puttextfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/pwd_spec.rb16
-rw-r--r--spec/ruby/library/net/ftp/quit_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/rename_spec.rb30
-rw-r--r--spec/ruby/library/net/ftp/resume_spec.rb4
-rw-r--r--spec/ruby/library/net/ftp/retrbinary_spec.rb6
-rw-r--r--spec/ruby/library/net/ftp/retrlines_spec.rb6
-rw-r--r--spec/ruby/library/net/ftp/return_code_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/rmdir_spec.rb18
-rw-r--r--spec/ruby/library/net/ftp/sendcmd_spec.rb18
-rw-r--r--spec/ruby/library/net/ftp/set_socket_spec.rb6
-rw-r--r--spec/ruby/library/net/ftp/shared/getbinaryfile.rb32
-rw-r--r--spec/ruby/library/net/ftp/shared/gettextfile.rb20
-rw-r--r--spec/ruby/library/net/ftp/shared/list.rb20
-rw-r--r--spec/ruby/library/net/ftp/shared/putbinaryfile.rb36
-rw-r--r--spec/ruby/library/net/ftp/shared/puttextfile.rb24
-rw-r--r--spec/ruby/library/net/ftp/site_spec.rb16
-rw-r--r--spec/ruby/library/net/ftp/size_spec.rb14
-rw-r--r--spec/ruby/library/net/ftp/status_spec.rb24
-rw-r--r--spec/ruby/library/net/ftp/storbinary_spec.rb6
-rw-r--r--spec/ruby/library/net/ftp/storlines_spec.rb6
-rw-r--r--spec/ruby/library/net/ftp/system_spec.rb14
-rw-r--r--spec/ruby/library/net/ftp/voidcmd_spec.rb18
-rw-r--r--spec/ruby/library/net/ftp/welcome_spec.rb6
-rw-r--r--spec/ruby/library/net/http/HTTPBadResponse_spec.rb2
-rw-r--r--spec/ruby/library/net/http/HTTPClientExcepton_spec.rb14
-rw-r--r--spec/ruby/library/net/http/HTTPError_spec.rb2
-rw-r--r--spec/ruby/library/net/http/HTTPFatalError_spec.rb2
-rw-r--r--spec/ruby/library/net/http/HTTPHeaderSyntaxError_spec.rb2
-rw-r--r--spec/ruby/library/net/http/HTTPRetriableError_spec.rb2
-rw-r--r--spec/ruby/library/net/http/HTTPServerException_spec.rb26
-rw-r--r--spec/ruby/library/net/http/http/Proxy_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/active_spec.rb6
-rw-r--r--spec/ruby/library/net/http/http/address_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/close_on_empty_response_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/copy_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/default_port_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/delete_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/finish_spec.rb6
-rw-r--r--spec/ruby/library/net/http/http/fixtures/http_server.rb26
-rw-r--r--spec/ruby/library/net/http/http/get2_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/get_print_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/get_response_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/get_spec.rb75
-rw-r--r--spec/ruby/library/net/http/http/head2_spec.rb9
-rw-r--r--spec/ruby/library/net/http/http/head_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/http_default_port_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/https_default_port_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/initialize_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/inspect_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/is_version_1_1_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/is_version_1_2_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/lock_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/mkcol_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/move_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/new_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/newobj_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/open_timeout_spec.rb23
-rw-r--r--spec/ruby/library/net/http/http/options_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/port_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/post2_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/post_form_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/post_spec.rb40
-rw-r--r--spec/ruby/library/net/http/http/propfind_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/proppatch_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/proxy_address_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/proxy_class_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/proxy_pass_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/proxy_port_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/proxy_user_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/put2_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/put_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/read_timeout_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_get_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/request_head_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/request_post_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/request_put_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/request_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/request_types_spec.rb30
-rw-r--r--spec/ruby/library/net/http/http/send_request_spec.rb6
-rw-r--r--spec/ruby/library/net/http/http/set_debug_output_spec.rb6
-rw-r--r--spec/ruby/library/net/http/http/shared/request_get.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_head.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_post.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_put.rb2
-rw-r--r--spec/ruby/library/net/http/http/socket_type_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/start_spec.rb6
-rw-r--r--spec/ruby/library/net/http/http/started_spec.rb6
-rw-r--r--spec/ruby/library/net/http/http/trace_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/unlock_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/use_ssl_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/version_1_1_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/version_1_2_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpexceptions/initialize_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpexceptions/response_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/body_exist_spec.rb7
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/body_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/body_stream_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/exec_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/inspect_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/method_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/path_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/request_body_permitted_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/response_body_permitted_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/set_body_internal_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/add_field_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/basic_auth_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/canonical_each_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/chunked_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/content_length_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/content_range_spec.rb10
-rw-r--r--spec/ruby/library/net/http/httpheader/content_type_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/delete_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/each_capitalized_name_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/each_capitalized_spec.rb7
-rw-r--r--spec/ruby/library/net/http/httpheader/each_header_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/each_key_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/each_name_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/each_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/each_value_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/element_reference_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/element_set_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/fetch_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/form_data_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/get_fields_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/initialize_http_header_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpheader/key_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/length_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/main_type_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/proxy_basic_auth_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/range_length_spec.rb10
-rw-r--r--spec/ruby/library/net/http/httpheader/range_spec.rb14
-rw-r--r--spec/ruby/library/net/http/httpheader/set_content_type_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/set_form_data_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/set_range_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/set_range.rb12
-rw-r--r--spec/ruby/library/net/http/httpheader/size_spec.rb6
-rw-r--r--spec/ruby/library/net/http/httpheader/sub_type_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/to_hash_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpheader/type_params_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httprequest/initialize_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/body_permitted_spec.rb14
-rw-r--r--spec/ruby/library/net/http/httpresponse/body_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpresponse/code_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/code_type_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/entity_spec.rb4
-rw-r--r--spec/ruby/library/net/http/httpresponse/error_spec.rb19
-rw-r--r--spec/ruby/library/net/http/httpresponse/error_type_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpresponse/exception_type_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpresponse/header_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/http_version_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/initialize_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/inspect_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/message_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/msg_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_body_spec.rb11
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_header_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_new_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/reading_body_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/response_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/value_spec.rb19
-rw-r--r--spec/ruby/library/objectspace/memsize_of_spec.rb34
-rw-r--r--spec/ruby/library/objectspace/reachable_objects_from_spec.rb61
-rw-r--r--spec/ruby/library/observer/add_observer_spec.rb4
-rw-r--r--spec/ruby/library/observer/count_observers_spec.rb4
-rw-r--r--spec/ruby/library/observer/delete_observer_spec.rb4
-rw-r--r--spec/ruby/library/observer/delete_observers_spec.rb4
-rw-r--r--spec/ruby/library/observer/notify_observers_spec.rb6
-rw-r--r--spec/ruby/library/open3/capture2_spec.rb2
-rw-r--r--spec/ruby/library/open3/capture2e_spec.rb2
-rw-r--r--spec/ruby/library/open3/capture3_spec.rb2
-rw-r--r--spec/ruby/library/open3/pipeline_r_spec.rb2
-rw-r--r--spec/ruby/library/open3/pipeline_rw_spec.rb2
-rw-r--r--spec/ruby/library/open3/pipeline_spec.rb2
-rw-r--r--spec/ruby/library/open3/pipeline_start_spec.rb2
-rw-r--r--spec/ruby/library/open3/pipeline_w_spec.rb2
-rw-r--r--spec/ruby/library/open3/popen2_spec.rb2
-rw-r--r--spec/ruby/library/open3/popen2e_spec.rb2
-rw-r--r--spec/ruby/library/open3/popen3_spec.rb4
-rw-r--r--spec/ruby/library/openssl/cipher_spec.rb4
-rw-r--r--spec/ruby/library/openssl/config/freeze_spec.rb26
-rw-r--r--spec/ruby/library/openssl/digest_spec.rb63
-rw-r--r--spec/ruby/library/openssl/hmac/digest_spec.rb6
-rw-r--r--spec/ruby/library/openssl/hmac/hexdigest_spec.rb6
-rw-r--r--spec/ruby/library/openssl/random/pseudo_bytes_spec.rb4
-rw-r--r--spec/ruby/library/openssl/random/random_bytes_spec.rb4
-rw-r--r--spec/ruby/library/openssl/random/shared/random_bytes.rb4
-rw-r--r--spec/ruby/library/openssl/x509/name/parse_spec.rb6
-rw-r--r--spec/ruby/library/openstruct/delete_field_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/element_reference_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/element_set_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/equal_value_spec.rb4
-rw-r--r--spec/ruby/library/openstruct/frozen_spec.rb14
-rw-r--r--spec/ruby/library/openstruct/initialize_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/inspect_spec.rb6
-rw-r--r--spec/ruby/library/openstruct/marshal_dump_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/marshal_load_spec.rb4
-rw-r--r--spec/ruby/library/openstruct/method_missing_spec.rb39
-rw-r--r--spec/ruby/library/openstruct/new_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/to_h_spec.rb43
-rw-r--r--spec/ruby/library/openstruct/to_s_spec.rb6
-rw-r--r--spec/ruby/library/optionparser/order_spec.rb28
-rw-r--r--spec/ruby/library/optionparser/parse_spec.rb28
-rw-r--r--spec/ruby/library/pathname/absolute_spec.rb11
-rw-r--r--spec/ruby/library/pathname/empty_spec.rb32
-rw-r--r--spec/ruby/library/pathname/equal_value_spec.rb3
-rw-r--r--spec/ruby/library/pathname/glob_spec.rb57
-rw-r--r--spec/ruby/library/pathname/hash_spec.rb3
-rw-r--r--spec/ruby/library/pathname/join_spec.rb2
-rw-r--r--spec/ruby/library/pathname/new_spec.rb20
-rw-r--r--spec/ruby/library/pathname/parent_spec.rb3
-rw-r--r--spec/ruby/library/pathname/pathname_spec.rb30
-rw-r--r--spec/ruby/library/pathname/realdirpath_spec.rb2
-rw-r--r--spec/ruby/library/pathname/realpath_spec.rb2
-rw-r--r--spec/ruby/library/pathname/relative_path_from_spec.rb8
-rw-r--r--spec/ruby/library/pathname/relative_spec.rb11
-rw-r--r--spec/ruby/library/pathname/root_spec.rb13
-rw-r--r--spec/ruby/library/pathname/sub_spec.rb3
-rw-r--r--spec/ruby/library/pp/pp_spec.rb8
-rw-r--r--spec/ruby/library/prime/each_spec.rb2
-rw-r--r--spec/ruby/library/prime/instance_spec.rb6
-rw-r--r--spec/ruby/library/prime/int_from_prime_division_spec.rb2
-rw-r--r--spec/ruby/library/prime/integer/each_prime_spec.rb2
-rw-r--r--spec/ruby/library/prime/integer/from_prime_division_spec.rb2
-rw-r--r--spec/ruby/library/prime/integer/prime_division_spec.rb4
-rw-r--r--spec/ruby/library/prime/integer/prime_spec.rb2
-rw-r--r--spec/ruby/library/prime/next_spec.rb4
-rw-r--r--spec/ruby/library/prime/prime_division_spec.rb4
-rw-r--r--spec/ruby/library/prime/prime_spec.rb2
-rw-r--r--spec/ruby/library/prime/succ_spec.rb4
-rw-r--r--spec/ruby/library/rbconfig/rbconfig_spec.rb84
-rw-r--r--spec/ruby/library/rbconfig/sizeof/limits_spec.rb40
-rw-r--r--spec/ruby/library/rbconfig/sizeof/sizeof_spec.rb30
-rw-r--r--spec/ruby/library/rbconfig/unicode_emoji_version_spec.rb22
-rw-r--r--spec/ruby/library/rbconfig/unicode_version_spec.rb28
-rw-r--r--spec/ruby/library/readline/basic_quote_characters_spec.rb2
-rw-r--r--spec/ruby/library/readline/basic_word_break_characters_spec.rb2
-rw-r--r--spec/ruby/library/readline/completer_quote_characters_spec.rb2
-rw-r--r--spec/ruby/library/readline/completer_word_break_characters_spec.rb2
-rw-r--r--spec/ruby/library/readline/completion_append_character_spec.rb2
-rw-r--r--spec/ruby/library/readline/completion_case_fold_spec.rb2
-rw-r--r--spec/ruby/library/readline/completion_proc_spec.rb4
-rw-r--r--spec/ruby/library/readline/constants_spec.rb2
-rw-r--r--spec/ruby/library/readline/emacs_editing_mode_spec.rb2
-rw-r--r--spec/ruby/library/readline/filename_quote_characters_spec.rb2
-rw-r--r--spec/ruby/library/readline/history/append_spec.rb4
-rw-r--r--spec/ruby/library/readline/history/delete_at_spec.rb18
-rw-r--r--spec/ruby/library/readline/history/each_spec.rb10
-rw-r--r--spec/ruby/library/readline/history/element_reference_spec.rb22
-rw-r--r--spec/ruby/library/readline/history/element_set_spec.rb6
-rw-r--r--spec/ruby/library/readline/history/empty_spec.rb2
-rw-r--r--spec/ruby/library/readline/history/history_spec.rb2
-rw-r--r--spec/ruby/library/readline/history/length_spec.rb4
-rw-r--r--spec/ruby/library/readline/history/pop_spec.rb14
-rw-r--r--spec/ruby/library/readline/history/push_spec.rb4
-rw-r--r--spec/ruby/library/readline/history/shift_spec.rb14
-rw-r--r--spec/ruby/library/readline/history/size_spec.rb4
-rw-r--r--spec/ruby/library/readline/history/to_s_spec.rb2
-rw-r--r--spec/ruby/library/readline/readline_spec.rb10
-rw-r--r--spec/ruby/library/readline/spec_helper.rb6
-rw-r--r--spec/ruby/library/readline/vi_editing_mode_spec.rb2
-rw-r--r--spec/ruby/library/resolv/fixtures/hosts1
-rw-r--r--spec/ruby/library/resolv/get_address_spec.rb16
-rw-r--r--spec/ruby/library/resolv/get_addresses_spec.rb14
-rw-r--r--spec/ruby/library/resolv/get_name_spec.rb15
-rw-r--r--spec/ruby/library/resolv/get_names_spec.rb13
-rw-r--r--spec/ruby/library/rexml/attribute/clone_spec.rb19
-rw-r--r--spec/ruby/library/rexml/attribute/element_spec.rb35
-rw-r--r--spec/ruby/library/rexml/attribute/equal_value_spec.rb27
-rw-r--r--spec/ruby/library/rexml/attribute/hash_spec.rb23
-rw-r--r--spec/ruby/library/rexml/attribute/initialize_spec.rb47
-rw-r--r--spec/ruby/library/rexml/attribute/inspect_spec.rb32
-rw-r--r--spec/ruby/library/rexml/attribute/namespace_spec.rb41
-rw-r--r--spec/ruby/library/rexml/attribute/node_type_spec.rb17
-rw-r--r--spec/ruby/library/rexml/attribute/prefix_spec.rb27
-rw-r--r--spec/ruby/library/rexml/attribute/remove_spec.rb33
-rw-r--r--spec/ruby/library/rexml/attribute/to_s_spec.rb23
-rw-r--r--spec/ruby/library/rexml/attribute/to_string_spec.rb24
-rw-r--r--spec/ruby/library/rexml/attribute/value_spec.rb24
-rw-r--r--spec/ruby/library/rexml/attribute/write_spec.rb37
-rw-r--r--spec/ruby/library/rexml/attribute/xpath_spec.rb30
-rw-r--r--spec/ruby/library/rexml/attributes/add_spec.rb13
-rw-r--r--spec/ruby/library/rexml/attributes/append_spec.rb13
-rw-r--r--spec/ruby/library/rexml/attributes/delete_all_spec.rb53
-rw-r--r--spec/ruby/library/rexml/attributes/delete_spec.rb45
-rw-r--r--spec/ruby/library/rexml/attributes/each_attribute_spec.rb38
-rw-r--r--spec/ruby/library/rexml/attributes/each_spec.rb41
-rw-r--r--spec/ruby/library/rexml/attributes/element_reference_spec.rb30
-rw-r--r--spec/ruby/library/rexml/attributes/element_set_spec.rb42
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_ns_spec.rb25
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_spec.rb47
-rw-r--r--spec/ruby/library/rexml/attributes/initialize_spec.rb29
-rw-r--r--spec/ruby/library/rexml/attributes/length_spec.rb13
-rw-r--r--spec/ruby/library/rexml/attributes/namespaces_spec.rb11
-rw-r--r--spec/ruby/library/rexml/attributes/prefixes_spec.rb39
-rw-r--r--spec/ruby/library/rexml/attributes/shared/length.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/size_spec.rb13
-rw-r--r--spec/ruby/library/rexml/attributes/to_a_spec.rb30
-rw-r--r--spec/ruby/library/rexml/cdata/clone_spec.rb17
-rw-r--r--spec/ruby/library/rexml/cdata/initialize_spec.rb39
-rw-r--r--spec/ruby/library/rexml/cdata/to_s_spec.rb13
-rw-r--r--spec/ruby/library/rexml/cdata/value_spec.rb13
-rw-r--r--spec/ruby/library/rexml/document/add_element_spec.rb53
-rw-r--r--spec/ruby/library/rexml/document/add_spec.rb91
-rw-r--r--spec/ruby/library/rexml/document/clone_spec.rb35
-rw-r--r--spec/ruby/library/rexml/document/doctype_spec.rb25
-rw-r--r--spec/ruby/library/rexml/document/encoding_spec.rb35
-rw-r--r--spec/ruby/library/rexml/document/expanded_name_spec.rb25
-rw-r--r--spec/ruby/library/rexml/document/new_spec.rb57
-rw-r--r--spec/ruby/library/rexml/document/node_type_spec.rb13
-rw-r--r--spec/ruby/library/rexml/document/root_spec.rb19
-rw-r--r--spec/ruby/library/rexml/document/stand_alone_spec.rb33
-rw-r--r--spec/ruby/library/rexml/document/version_spec.rb23
-rw-r--r--spec/ruby/library/rexml/document/write_spec.rb59
-rw-r--r--spec/ruby/library/rexml/document/xml_decl_spec.rb25
-rw-r--r--spec/ruby/library/rexml/element/add_attribute_spec.rb67
-rw-r--r--spec/ruby/library/rexml/element/add_attributes_spec.rb37
-rw-r--r--spec/ruby/library/rexml/element/add_element_spec.rb64
-rw-r--r--spec/ruby/library/rexml/element/add_namespace_spec.rb38
-rw-r--r--spec/ruby/library/rexml/element/add_text_spec.rb39
-rw-r--r--spec/ruby/library/rexml/element/attribute_spec.rb29
-rw-r--r--spec/ruby/library/rexml/element/attributes_spec.rb29
-rw-r--r--spec/ruby/library/rexml/element/cdatas_spec.rb39
-rw-r--r--spec/ruby/library/rexml/element/clone_spec.rb49
-rw-r--r--spec/ruby/library/rexml/element/comments_spec.rb33
-rw-r--r--spec/ruby/library/rexml/element/delete_attribute_spec.rb63
-rw-r--r--spec/ruby/library/rexml/element/delete_element_spec.rb83
-rw-r--r--spec/ruby/library/rexml/element/delete_namespace_spec.rb39
-rw-r--r--spec/ruby/library/rexml/element/document_spec.rb27
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb59
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_text_spec.rb51
-rw-r--r--spec/ruby/library/rexml/element/element_reference_spec.rb23
-rw-r--r--spec/ruby/library/rexml/element/get_text_spec.rb29
-rw-r--r--spec/ruby/library/rexml/element/has_attributes_spec.rb27
-rw-r--r--spec/ruby/library/rexml/element/has_elements_spec.rb29
-rw-r--r--spec/ruby/library/rexml/element/has_text_spec.rb25
-rw-r--r--spec/ruby/library/rexml/element/inspect_spec.rb43
-rw-r--r--spec/ruby/library/rexml/element/instructions_spec.rb35
-rw-r--r--spec/ruby/library/rexml/element/namespace_spec.rb43
-rw-r--r--spec/ruby/library/rexml/element/namespaces_spec.rb53
-rw-r--r--spec/ruby/library/rexml/element/new_spec.rb57
-rw-r--r--spec/ruby/library/rexml/element/next_element_spec.rb33
-rw-r--r--spec/ruby/library/rexml/element/node_type_spec.rb13
-rw-r--r--spec/ruby/library/rexml/element/prefixes_spec.rb37
-rw-r--r--spec/ruby/library/rexml/element/previous_element_spec.rb33
-rw-r--r--spec/ruby/library/rexml/element/raw_spec.rb37
-rw-r--r--spec/ruby/library/rexml/element/root_spec.rb45
-rw-r--r--spec/ruby/library/rexml/element/text_spec.rb91
-rw-r--r--spec/ruby/library/rexml/element/texts_spec.rb25
-rw-r--r--spec/ruby/library/rexml/element/whitespace_spec.rb35
-rw-r--r--spec/ruby/library/rexml/node/each_recursive_spec.rb37
-rw-r--r--spec/ruby/library/rexml/node/find_first_recursive_spec.rb43
-rw-r--r--spec/ruby/library/rexml/node/index_in_parent_spec.rb25
-rw-r--r--spec/ruby/library/rexml/node/next_sibling_node_spec.rb35
-rw-r--r--spec/ruby/library/rexml/node/parent_spec.rb34
-rw-r--r--spec/ruby/library/rexml/node/previous_sibling_node_spec.rb35
-rw-r--r--spec/ruby/library/rexml/shared/each_element.rb2
-rw-r--r--spec/ruby/library/rexml/shared/elements_to_a.rb2
-rw-r--r--spec/ruby/library/rexml/text/append_spec.rb17
-rw-r--r--spec/ruby/library/rexml/text/clone_spec.rb17
-rw-r--r--spec/ruby/library/rexml/text/comparison_spec.rb41
-rw-r--r--spec/ruby/library/rexml/text/empty_spec.rb19
-rw-r--r--spec/ruby/library/rexml/text/indent_text_spec.rb38
-rw-r--r--spec/ruby/library/rexml/text/inspect_spec.rb13
-rw-r--r--spec/ruby/library/rexml/text/new_spec.rb96
-rw-r--r--spec/ruby/library/rexml/text/node_type_spec.rb13
-rw-r--r--spec/ruby/library/rexml/text/normalize_spec.rb13
-rw-r--r--spec/ruby/library/rexml/text/read_with_substitution_spec.rb20
-rw-r--r--spec/ruby/library/rexml/text/to_s_spec.rb28
-rw-r--r--spec/ruby/library/rexml/text/unnormalize_spec.rb13
-rw-r--r--spec/ruby/library/rexml/text/value_spec.rb57
-rw-r--r--spec/ruby/library/rexml/text/wrap_spec.rb32
-rw-r--r--spec/ruby/library/rexml/text/write_with_substitution_spec.rb55
-rw-r--r--spec/ruby/library/ripper/lex_spec.rb23
-rw-r--r--spec/ruby/library/ripper/sexp_spec.rb13
-rw-r--r--spec/ruby/library/rubygems/gem/bin_path_spec.rb34
-rw-r--r--spec/ruby/library/scanf/io/block_scanf_spec.rb13
-rw-r--r--spec/ruby/library/scanf/io/scanf_spec.rb57
-rw-r--r--spec/ruby/library/scanf/io/shared/block_scanf.rb2
-rw-r--r--spec/ruby/library/scanf/string/block_scanf_spec.rb13
-rw-r--r--spec/ruby/library/scanf/string/scanf_spec.rb97
-rw-r--r--spec/ruby/library/securerandom/base64_spec.rb6
-rw-r--r--spec/ruby/library/securerandom/bytes_spec.rb8
-rw-r--r--spec/ruby/library/securerandom/hex_spec.rb8
-rw-r--r--spec/ruby/library/securerandom/random_bytes_spec.rb7
-rw-r--r--spec/ruby/library/securerandom/random_number_spec.rb56
-rw-r--r--spec/ruby/library/set/add_spec.rb4
-rw-r--r--spec/ruby/library/set/append_spec.rb4
-rw-r--r--spec/ruby/library/set/case_compare_spec.rb12
-rw-r--r--spec/ruby/library/set/case_equality_spec.rb10
-rw-r--r--spec/ruby/library/set/classify_spec.rb2
-rw-r--r--spec/ruby/library/set/clear_spec.rb2
-rw-r--r--spec/ruby/library/set/collect_spec.rb4
-rw-r--r--spec/ruby/library/set/compare_by_identity_spec.rb143
-rw-r--r--spec/ruby/library/set/constructor_spec.rb2
-rw-r--r--spec/ruby/library/set/delete_if_spec.rb2
-rw-r--r--spec/ruby/library/set/delete_spec.rb2
-rw-r--r--spec/ruby/library/set/difference_spec.rb4
-rw-r--r--spec/ruby/library/set/disjoint_spec.rb23
-rw-r--r--spec/ruby/library/set/divide_spec.rb2
-rw-r--r--spec/ruby/library/set/each_spec.rb2
-rw-r--r--spec/ruby/library/set/empty_spec.rb2
-rw-r--r--spec/ruby/library/set/enumerable/to_set_spec.rb14
-rw-r--r--spec/ruby/library/set/eql_spec.rb2
-rw-r--r--spec/ruby/library/set/equal_value_spec.rb9
-rw-r--r--spec/ruby/library/set/exclusion_spec.rb8
-rw-r--r--spec/ruby/library/set/filter_spec.rb8
-rw-r--r--spec/ruby/library/set/fixtures/set_like.rb31
-rw-r--r--spec/ruby/library/set/flatten_merge_spec.rb4
-rw-r--r--spec/ruby/library/set/flatten_spec.rb19
-rw-r--r--spec/ruby/library/set/hash_spec.rb2
-rw-r--r--spec/ruby/library/set/include_spec.rb4
-rw-r--r--spec/ruby/library/set/initialize_spec.rb26
-rw-r--r--spec/ruby/library/set/inspect_spec.rb17
-rw-r--r--spec/ruby/library/set/intersect_spec.rb23
-rw-r--r--spec/ruby/library/set/intersection_spec.rb4
-rw-r--r--spec/ruby/library/set/keep_if_spec.rb2
-rw-r--r--spec/ruby/library/set/length_spec.rb4
-rw-r--r--spec/ruby/library/set/map_spec.rb4
-rw-r--r--spec/ruby/library/set/member_spec.rb4
-rw-r--r--spec/ruby/library/set/merge_spec.rb6
-rw-r--r--spec/ruby/library/set/minus_spec.rb4
-rw-r--r--spec/ruby/library/set/plus_spec.rb4
-rw-r--r--spec/ruby/library/set/pretty_print_cycle_spec.rb2
-rw-r--r--spec/ruby/library/set/pretty_print_spec.rb2
-rw-r--r--spec/ruby/library/set/proper_subset_spec.rb17
-rw-r--r--spec/ruby/library/set/proper_superset_spec.rb17
-rw-r--r--spec/ruby/library/set/reject_spec.rb2
-rw-r--r--spec/ruby/library/set/replace_spec.rb2
-rw-r--r--spec/ruby/library/set/select_spec.rb42
-rw-r--r--spec/ruby/library/set/shared/difference.rb6
-rw-r--r--spec/ruby/library/set/shared/include.rb22
-rw-r--r--spec/ruby/library/set/shared/inspect.rb15
-rw-r--r--spec/ruby/library/set/shared/intersection.rb4
-rw-r--r--spec/ruby/library/set/shared/select.rb42
-rw-r--r--spec/ruby/library/set/shared/union.rb4
-rw-r--r--spec/ruby/library/set/size_spec.rb4
-rw-r--r--spec/ruby/library/set/sortedset/add_spec.rb61
-rw-r--r--spec/ruby/library/set/sortedset/append_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/case_equality_spec.rb9
-rw-r--r--spec/ruby/library/set/sortedset/classify_spec.rb43
-rw-r--r--spec/ruby/library/set/sortedset/clear_spec.rb27
-rw-r--r--spec/ruby/library/set/sortedset/collect_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/constructor_spec.rb23
-rw-r--r--spec/ruby/library/set/sortedset/delete_if_spec.rb59
-rw-r--r--spec/ruby/library/set/sortedset/delete_spec.rb57
-rw-r--r--spec/ruby/library/set/sortedset/difference_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/divide_spec.rb55
-rw-r--r--spec/ruby/library/set/sortedset/each_spec.rb41
-rw-r--r--spec/ruby/library/set/sortedset/empty_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/eql_spec.rb25
-rw-r--r--spec/ruby/library/set/sortedset/equal_value_spec.rb21
-rw-r--r--spec/ruby/library/set/sortedset/exclusion_spec.rb29
-rw-r--r--spec/ruby/library/set/sortedset/filter_spec.rb12
-rw-r--r--spec/ruby/library/set/sortedset/flatten_merge_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/flatten_spec.rb69
-rw-r--r--spec/ruby/library/set/sortedset/hash_spec.rb21
-rw-r--r--spec/ruby/library/set/sortedset/include_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/initialize_spec.rb51
-rw-r--r--spec/ruby/library/set/sortedset/inspect_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/intersection_spec.rb19
-rw-r--r--spec/ruby/library/set/sortedset/keep_if_spec.rb49
-rw-r--r--spec/ruby/library/set/sortedset/length_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/map_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/member_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/merge_spec.rb31
-rw-r--r--spec/ruby/library/set/sortedset/minus_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/plus_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_cycle_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_spec.rb25
-rw-r--r--spec/ruby/library/set/sortedset/proper_subset_spec.rb53
-rw-r--r--spec/ruby/library/set/sortedset/proper_superset_spec.rb53
-rw-r--r--spec/ruby/library/set/sortedset/reject_spec.rb65
-rw-r--r--spec/ruby/library/set/sortedset/replace_spec.rb27
-rw-r--r--spec/ruby/library/set/sortedset/select_spec.rb37
-rw-r--r--spec/ruby/library/set/sortedset/shared/difference.rb6
-rw-r--r--spec/ruby/library/set/sortedset/shared/intersection.rb4
-rw-r--r--spec/ruby/library/set/sortedset/shared/select.rb35
-rw-r--r--spec/ruby/library/set/sortedset/shared/union.rb4
-rw-r--r--spec/ruby/library/set/sortedset/size_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/subset_spec.rb53
-rw-r--r--spec/ruby/library/set/sortedset/subtract_spec.rb27
-rw-r--r--spec/ruby/library/set/sortedset/superset_spec.rb53
-rw-r--r--spec/ruby/library/set/sortedset/to_a_spec.rb27
-rw-r--r--spec/ruby/library/set/sortedset/union_spec.rb19
-rw-r--r--spec/ruby/library/set/subset_spec.rb17
-rw-r--r--spec/ruby/library/set/subtract_spec.rb2
-rw-r--r--spec/ruby/library/set/superset_spec.rb17
-rw-r--r--spec/ruby/library/set/to_a_spec.rb2
-rw-r--r--spec/ruby/library/set/to_s_spec.rb11
-rw-r--r--spec/ruby/library/set/union_spec.rb4
-rw-r--r--spec/ruby/library/shellwords/shellwords_spec.rb11
-rw-r--r--spec/ruby/library/singleton/allocate_spec.rb6
-rw-r--r--spec/ruby/library/singleton/clone_spec.rb6
-rw-r--r--spec/ruby/library/singleton/dump_spec.rb4
-rw-r--r--spec/ruby/library/singleton/dup_spec.rb6
-rw-r--r--spec/ruby/library/singleton/instance_spec.rb4
-rw-r--r--spec/ruby/library/singleton/load_spec.rb4
-rw-r--r--spec/ruby/library/singleton/new_spec.rb6
-rw-r--r--spec/ruby/library/socket/addrinfo/afamily_spec.rb5
-rw-r--r--spec/ruby/library/socket/addrinfo/bind_spec.rb5
-rw-r--r--spec/ruby/library/socket/addrinfo/canonname_spec.rb14
-rw-r--r--spec/ruby/library/socket/addrinfo/connect_from_spec.rb75
-rw-r--r--spec/ruby/library/socket/addrinfo/connect_spec.rb35
-rw-r--r--spec/ruby/library/socket/addrinfo/connect_to_spec.rb75
-rw-r--r--spec/ruby/library/socket/addrinfo/family_addrinfo_spec.rb115
-rw-r--r--spec/ruby/library/socket/addrinfo/foreach_spec.rb9
-rw-r--r--spec/ruby/library/socket/addrinfo/getaddrinfo_spec.rb91
-rw-r--r--spec/ruby/library/socket/addrinfo/getnameinfo_spec.rb42
-rw-r--r--spec/ruby/library/socket/addrinfo/initialize_spec.rb344
-rw-r--r--spec/ruby/library/socket/addrinfo/inspect_sockaddr_spec.rb55
-rw-r--r--spec/ruby/library/socket/addrinfo/inspect_spec.rb65
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_address_spec.rb38
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_port_spec.rb7
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_spec.rb36
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_unpack_spec.rb7
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_loopback_spec.rb17
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_multicast_spec.rb39
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_private_spec.rb14
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_spec.rb5
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_linklocal_spec.rb23
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_loopback_spec.rb9
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_global_spec.rb20
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_linklocal_spec.rb19
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_nodelocal_spec.rb18
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_orglocal_spec.rb18
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_sitelocal_spec.rb18
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_multicast_spec.rb26
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_sitelocal_spec.rb23
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_spec.rb5
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_to_ipv4_spec.rb71
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_unique_local_spec.rb18
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_unspecified_spec.rb15
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_v4compat_spec.rb20
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_v4mapped_spec.rb20
-rw-r--r--spec/ruby/library/socket/addrinfo/listen_spec.rb34
-rw-r--r--spec/ruby/library/socket/addrinfo/marshal_dump_spec.rb84
-rw-r--r--spec/ruby/library/socket/addrinfo/marshal_load_spec.rb35
-rw-r--r--spec/ruby/library/socket/addrinfo/pfamily_spec.rb11
-rw-r--r--spec/ruby/library/socket/addrinfo/protocol_spec.rb28
-rw-r--r--spec/ruby/library/socket/addrinfo/shared/to_sockaddr.rb24
-rw-r--r--spec/ruby/library/socket/addrinfo/socktype_spec.rb27
-rw-r--r--spec/ruby/library/socket/addrinfo/tcp_spec.rb42
-rw-r--r--spec/ruby/library/socket/addrinfo/to_s_spec.rb7
-rw-r--r--spec/ruby/library/socket/addrinfo/to_sockaddr_spec.rb7
-rw-r--r--spec/ruby/library/socket/addrinfo/udp_spec.rb42
-rw-r--r--spec/ruby/library/socket/addrinfo/unix_path_spec.rb23
-rw-r--r--spec/ruby/library/socket/addrinfo/unix_spec.rb39
-rw-r--r--spec/ruby/library/socket/ancillarydata/cmsg_is_spec.rb33
-rw-r--r--spec/ruby/library/socket/ancillarydata/data_spec.rb9
-rw-r--r--spec/ruby/library/socket/ancillarydata/family_spec.rb9
-rw-r--r--spec/ruby/library/socket/ancillarydata/initialize_spec.rb284
-rw-r--r--spec/ruby/library/socket/ancillarydata/int_spec.rb43
-rw-r--r--spec/ruby/library/socket/ancillarydata/ip_pktinfo_spec.rb145
-rw-r--r--spec/ruby/library/socket/ancillarydata/ipv6_pktinfo_addr_spec.rb11
-rw-r--r--spec/ruby/library/socket/ancillarydata/ipv6_pktinfo_ifindex_spec.rb11
-rw-r--r--spec/ruby/library/socket/ancillarydata/ipv6_pktinfo_spec.rb89
-rw-r--r--spec/ruby/library/socket/ancillarydata/level_spec.rb9
-rw-r--r--spec/ruby/library/socket/ancillarydata/type_spec.rb9
-rw-r--r--spec/ruby/library/socket/ancillarydata/unix_rights_spec.rb61
-rw-r--r--spec/ruby/library/socket/basicsocket/close_read_spec.rb18
-rw-r--r--spec/ruby/library/socket/basicsocket/close_write_spec.rb18
-rw-r--r--spec/ruby/library/socket/basicsocket/connect_address_spec.rb154
-rw-r--r--spec/ruby/library/socket/basicsocket/do_not_reverse_lookup_spec.rb68
-rw-r--r--spec/ruby/library/socket/basicsocket/for_fd_spec.rb25
-rw-r--r--spec/ruby/library/socket/basicsocket/getpeereid_spec.rb36
-rw-r--r--spec/ruby/library/socket/basicsocket/getpeername_spec.rb9
-rw-r--r--spec/ruby/library/socket/basicsocket/getsockname_spec.rb8
-rw-r--r--spec/ruby/library/socket/basicsocket/getsockopt_spec.rb148
-rw-r--r--spec/ruby/library/socket/basicsocket/ioctl_spec.rb3
-rw-r--r--spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb44
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb71
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_spec.rb91
-rw-r--r--spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb209
-rw-r--r--spec/ruby/library/socket/basicsocket/recvmsg_spec.rb197
-rw-r--r--spec/ruby/library/socket/basicsocket/send_spec.rb131
-rw-r--r--spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb113
-rw-r--r--spec/ruby/library/socket/basicsocket/sendmsg_spec.rb111
-rw-r--r--spec/ruby/library/socket/basicsocket/setsockopt_spec.rb149
-rw-r--r--spec/ruby/library/socket/basicsocket/shutdown_spec.rb155
-rw-r--r--spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb43
-rw-r--r--spec/ruby/library/socket/constants/constants_spec.rb26
-rw-r--r--spec/ruby/library/socket/fixtures/classes.rb85
-rw-r--r--spec/ruby/library/socket/ipsocket/addr_spec.rb67
-rw-r--r--spec/ruby/library/socket/ipsocket/getaddress_spec.rb16
-rw-r--r--spec/ruby/library/socket/ipsocket/peeraddr_spec.rb74
-rw-r--r--spec/ruby/library/socket/ipsocket/recvfrom_spec.rb59
-rw-r--r--spec/ruby/library/socket/option/bool_spec.rb12
-rw-r--r--spec/ruby/library/socket/option/initialize_spec.rb83
-rw-r--r--spec/ruby/library/socket/option/inspect_spec.rb5
-rw-r--r--spec/ruby/library/socket/option/int_spec.rb25
-rw-r--r--spec/ruby/library/socket/option/linger_spec.rb22
-rw-r--r--spec/ruby/library/socket/option/new_spec.rb10
-rw-r--r--spec/ruby/library/socket/shared/pack_sockaddr.rb57
-rw-r--r--spec/ruby/library/socket/shared/recv_nonblock.rb54
-rw-r--r--spec/ruby/library/socket/shared/socketpair.rb115
-rw-r--r--spec/ruby/library/socket/socket/accept_loop_spec.rb84
-rw-r--r--spec/ruby/library/socket/socket/accept_nonblock_spec.rb117
-rw-r--r--spec/ruby/library/socket/socket/accept_spec.rb123
-rw-r--r--spec/ruby/library/socket/socket/bind_spec.rb103
-rw-r--r--spec/ruby/library/socket/socket/connect_nonblock_spec.rb146
-rw-r--r--spec/ruby/library/socket/socket/connect_spec.rb58
-rw-r--r--spec/ruby/library/socket/socket/for_fd_spec.rb5
-rw-r--r--spec/ruby/library/socket/socket/getaddrinfo_spec.rb279
-rw-r--r--spec/ruby/library/socket/socket/gethostbyaddr_spec.rb126
-rw-r--r--spec/ruby/library/socket/socket/gethostbyname_spec.rb136
-rw-r--r--spec/ruby/library/socket/socket/gethostname_spec.rb4
-rw-r--r--spec/ruby/library/socket/socket/getifaddrs_spec.rb117
-rw-r--r--spec/ruby/library/socket/socket/getnameinfo_spec.rb89
-rw-r--r--spec/ruby/library/socket/socket/getservbyname_spec.rb14
-rw-r--r--spec/ruby/library/socket/socket/getservbyport_spec.rb23
-rw-r--r--spec/ruby/library/socket/socket/initialize_spec.rb87
-rw-r--r--spec/ruby/library/socket/socket/ip_address_list_spec.rb50
-rw-r--r--spec/ruby/library/socket/socket/ipv6only_bang_spec.rb20
-rw-r--r--spec/ruby/library/socket/socket/listen_spec.rb54
-rw-r--r--spec/ruby/library/socket/socket/local_address_spec.rb43
-rw-r--r--spec/ruby/library/socket/socket/new_spec.rb4
-rw-r--r--spec/ruby/library/socket/socket/pack_sockaddr_in_spec.rb6
-rw-r--r--spec/ruby/library/socket/socket/pack_sockaddr_un_spec.rb6
-rw-r--r--spec/ruby/library/socket/socket/pair_spec.rb6
-rw-r--r--spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb120
-rw-r--r--spec/ruby/library/socket/socket/recvfrom_spec.rb94
-rw-r--r--spec/ruby/library/socket/socket/remote_address_spec.rb54
-rw-r--r--spec/ruby/library/socket/socket/sockaddr_in_spec.rb6
-rw-r--r--spec/ruby/library/socket/socket/sockaddr_un_spec.rb6
-rw-r--r--spec/ruby/library/socket/socket/socket_spec.rb4
-rw-r--r--spec/ruby/library/socket/socket/socketpair_spec.rb6
-rw-r--r--spec/ruby/library/socket/socket/sysaccept_spec.rb93
-rw-r--r--spec/ruby/library/socket/socket/tcp_server_loop_spec.rb54
-rw-r--r--spec/ruby/library/socket/socket/tcp_server_sockets_spec.rb39
-rw-r--r--spec/ruby/library/socket/socket/tcp_spec.rb70
-rw-r--r--spec/ruby/library/socket/socket/udp_server_loop_on_spec.rb47
-rw-r--r--spec/ruby/library/socket/socket/udp_server_loop_spec.rb57
-rw-r--r--spec/ruby/library/socket/socket/udp_server_recv_spec.rb35
-rw-r--r--spec/ruby/library/socket/socket/udp_server_sockets_spec.rb39
-rw-r--r--spec/ruby/library/socket/socket/unix_server_loop_spec.rb58
-rw-r--r--spec/ruby/library/socket/socket/unix_server_socket_spec.rb48
-rw-r--r--spec/ruby/library/socket/socket/unix_spec.rb45
-rw-r--r--spec/ruby/library/socket/socket/unpack_sockaddr_in_spec.rb33
-rw-r--r--spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb14
-rw-r--r--spec/ruby/library/socket/spec_helper.rb13
-rw-r--r--spec/ruby/library/socket/tcpserver/accept_nonblock_spec.rb53
-rw-r--r--spec/ruby/library/socket/tcpserver/accept_spec.rb72
-rw-r--r--spec/ruby/library/socket/tcpserver/gets_spec.rb6
-rw-r--r--spec/ruby/library/socket/tcpserver/initialize_spec.rb101
-rw-r--r--spec/ruby/library/socket/tcpserver/listen_spec.rb28
-rw-r--r--spec/ruby/library/socket/tcpserver/new_spec.rb63
-rw-r--r--spec/ruby/library/socket/tcpserver/sysaccept_spec.rb46
-rw-r--r--spec/ruby/library/socket/tcpsocket/gethostbyname_spec.rb74
-rw-r--r--spec/ruby/library/socket/tcpsocket/initialize_spec.rb61
-rw-r--r--spec/ruby/library/socket/tcpsocket/local_address_spec.rb73
-rw-r--r--spec/ruby/library/socket/tcpsocket/new_spec.rb2
-rw-r--r--spec/ruby/library/socket/tcpsocket/open_spec.rb2
-rw-r--r--spec/ruby/library/socket/tcpsocket/partially_closable_spec.rb6
-rw-r--r--spec/ruby/library/socket/tcpsocket/recv_nonblock_spec.rb12
-rw-r--r--spec/ruby/library/socket/tcpsocket/recv_spec.rb28
-rw-r--r--spec/ruby/library/socket/tcpsocket/remote_address_spec.rb72
-rw-r--r--spec/ruby/library/socket/tcpsocket/setsockopt_spec.rb4
-rw-r--r--spec/ruby/library/socket/tcpsocket/shared/new.rb10
-rw-r--r--spec/ruby/library/socket/udpsocket/bind_spec.rb53
-rw-r--r--spec/ruby/library/socket/udpsocket/connect_spec.rb35
-rw-r--r--spec/ruby/library/socket/udpsocket/initialize_spec.rb40
-rw-r--r--spec/ruby/library/socket/udpsocket/inspect_spec.rb17
-rw-r--r--spec/ruby/library/socket/udpsocket/local_address_spec.rb80
-rw-r--r--spec/ruby/library/socket/udpsocket/new_spec.rb12
-rw-r--r--spec/ruby/library/socket/udpsocket/open_spec.rb4
-rw-r--r--spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb95
-rw-r--r--spec/ruby/library/socket/udpsocket/remote_address_spec.rb79
-rw-r--r--spec/ruby/library/socket/udpsocket/send_spec.rb90
-rw-r--r--spec/ruby/library/socket/udpsocket/write_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixserver/accept_nonblock_spec.rb64
-rw-r--r--spec/ruby/library/socket/unixserver/accept_spec.rb70
-rw-r--r--spec/ruby/library/socket/unixserver/for_fd_spec.rb4
-rw-r--r--spec/ruby/library/socket/unixserver/initialize_spec.rb28
-rw-r--r--spec/ruby/library/socket/unixserver/listen_spec.rb21
-rw-r--r--spec/ruby/library/socket/unixserver/new_spec.rb4
-rw-r--r--spec/ruby/library/socket/unixserver/open_spec.rb5
-rw-r--r--spec/ruby/library/socket/unixserver/shared/new.rb5
-rw-r--r--spec/ruby/library/socket/unixserver/sysaccept_spec.rb52
-rw-r--r--spec/ruby/library/socket/unixsocket/addr_spec.rb14
-rw-r--r--spec/ruby/library/socket/unixsocket/initialize_spec.rb38
-rw-r--r--spec/ruby/library/socket/unixsocket/inspect_spec.rb4
-rw-r--r--spec/ruby/library/socket/unixsocket/local_address_spec.rb96
-rw-r--r--spec/ruby/library/socket/unixsocket/new_spec.rb4
-rw-r--r--spec/ruby/library/socket/unixsocket/open_spec.rb9
-rw-r--r--spec/ruby/library/socket/unixsocket/pair_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixsocket/partially_closable_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixsocket/path_spec.rb4
-rw-r--r--spec/ruby/library/socket/unixsocket/peeraddr_spec.rb10
-rw-r--r--spec/ruby/library/socket/unixsocket/recv_io_spec.rb49
-rw-r--r--spec/ruby/library/socket/unixsocket/recvfrom_spec.rb57
-rw-r--r--spec/ruby/library/socket/unixsocket/remote_address_spec.rb45
-rw-r--r--spec/ruby/library/socket/unixsocket/send_io_spec.rb27
-rw-r--r--spec/ruby/library/socket/unixsocket/shared/new.rb6
-rw-r--r--spec/ruby/library/socket/unixsocket/socketpair_spec.rb40
-rw-r--r--spec/ruby/library/stringio/append_spec.rb24
-rw-r--r--spec/ruby/library/stringio/binmode_spec.rb18
-rw-r--r--spec/ruby/library/stringio/bytes_spec.rb16
-rw-r--r--spec/ruby/library/stringio/chars_spec.rb16
-rw-r--r--spec/ruby/library/stringio/close_read_spec.rb15
-rw-r--r--spec/ruby/library/stringio/close_spec.rb23
-rw-r--r--spec/ruby/library/stringio/close_write_spec.rb15
-rw-r--r--spec/ruby/library/stringio/closed_read_spec.rb4
-rw-r--r--spec/ruby/library/stringio/closed_spec.rb4
-rw-r--r--spec/ruby/library/stringio/closed_write_spec.rb4
-rw-r--r--spec/ruby/library/stringio/codepoints_spec.rb15
-rw-r--r--spec/ruby/library/stringio/each_byte_spec.rb4
-rw-r--r--spec/ruby/library/stringio/each_char_spec.rb6
-rw-r--r--spec/ruby/library/stringio/each_codepoint_spec.rb9
-rw-r--r--spec/ruby/library/stringio/each_line_spec.rb10
-rw-r--r--spec/ruby/library/stringio/each_spec.rb10
-rw-r--r--spec/ruby/library/stringio/eof_spec.rb6
-rw-r--r--spec/ruby/library/stringio/external_encoding_spec.rb24
-rw-r--r--spec/ruby/library/stringio/fcntl_spec.rb6
-rw-r--r--spec/ruby/library/stringio/fileno_spec.rb6
-rw-r--r--spec/ruby/library/stringio/flush_spec.rb4
-rw-r--r--spec/ruby/library/stringio/fsync_spec.rb4
-rw-r--r--spec/ruby/library/stringio/getbyte_spec.rb10
-rw-r--r--spec/ruby/library/stringio/getc_spec.rb12
-rw-r--r--spec/ruby/library/stringio/getch_spec.rb34
-rw-r--r--spec/ruby/library/stringio/getpass_spec.rb11
-rw-r--r--spec/ruby/library/stringio/gets_spec.rb22
-rw-r--r--spec/ruby/library/stringio/initialize_spec.rb49
-rw-r--r--spec/ruby/library/stringio/inspect_spec.rb19
-rw-r--r--spec/ruby/library/stringio/internal_encoding_spec.rb2
-rw-r--r--spec/ruby/library/stringio/isatty_spec.rb6
-rw-r--r--spec/ruby/library/stringio/length_spec.rb6
-rw-r--r--spec/ruby/library/stringio/lineno_spec.rb2
-rw-r--r--spec/ruby/library/stringio/lines_spec.rb26
-rw-r--r--spec/ruby/library/stringio/open_spec.rb13
-rw-r--r--spec/ruby/library/stringio/path_spec.rb6
-rw-r--r--spec/ruby/library/stringio/pid_spec.rb4
-rw-r--r--spec/ruby/library/stringio/pos_spec.rb8
-rw-r--r--spec/ruby/library/stringio/print_spec.rb18
-rw-r--r--spec/ruby/library/stringio/printf_spec.rb17
-rw-r--r--spec/ruby/library/stringio/putc_spec.rb10
-rw-r--r--spec/ruby/library/stringio/puts_spec.rb31
-rw-r--r--spec/ruby/library/stringio/read_nonblock_spec.rb28
-rw-r--r--spec/ruby/library/stringio/read_spec.rb4
-rw-r--r--spec/ruby/library/stringio/readbyte_spec.rb8
-rw-r--r--spec/ruby/library/stringio/readchar_spec.rb8
-rw-r--r--spec/ruby/library/stringio/readline_spec.rb26
-rw-r--r--spec/ruby/library/stringio/readlines_spec.rb20
-rw-r--r--spec/ruby/library/stringio/readpartial_spec.rb14
-rw-r--r--spec/ruby/library/stringio/reopen_spec.rb86
-rw-r--r--spec/ruby/library/stringio/rewind_spec.rb4
-rw-r--r--spec/ruby/library/stringio/seek_spec.rb18
-rw-r--r--spec/ruby/library/stringio/set_encoding_spec.rb16
-rw-r--r--spec/ruby/library/stringio/shared/codepoints.rb6
-rw-r--r--spec/ruby/library/stringio/shared/each.rb18
-rw-r--r--spec/ruby/library/stringio/shared/each_byte.rb4
-rw-r--r--spec/ruby/library/stringio/shared/each_char.rb4
-rw-r--r--spec/ruby/library/stringio/shared/getc.rb4
-rw-r--r--spec/ruby/library/stringio/shared/read.rb16
-rw-r--r--spec/ruby/library/stringio/shared/readchar.rb6
-rw-r--r--spec/ruby/library/stringio/shared/sysread.rb2
-rw-r--r--spec/ruby/library/stringio/shared/write.rb20
-rw-r--r--spec/ruby/library/stringio/size_spec.rb6
-rw-r--r--spec/ruby/library/stringio/string_spec.rb6
-rw-r--r--spec/ruby/library/stringio/stringio_spec.rb3
-rw-r--r--spec/ruby/library/stringio/sync_spec.rb4
-rw-r--r--spec/ruby/library/stringio/sysread_spec.rb6
-rw-r--r--spec/ruby/library/stringio/syswrite_spec.rb6
-rw-r--r--spec/ruby/library/stringio/tell_spec.rb6
-rw-r--r--spec/ruby/library/stringio/truncate_spec.rb12
-rw-r--r--spec/ruby/library/stringio/tty_spec.rb6
-rw-r--r--spec/ruby/library/stringio/ungetbyte_spec.rb2
-rw-r--r--spec/ruby/library/stringio/ungetc_spec.rb10
-rw-r--r--spec/ruby/library/stringio/write_nonblock_spec.rb6
-rw-r--r--spec/ruby/library/stringio/write_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/append_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/beginning_of_line_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/bol_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/check_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/check_until_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/clear_spec.rb16
-rw-r--r--spec/ruby/library/stringscanner/concat_spec.rb10
-rw-r--r--spec/ruby/library/stringscanner/dup_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/element_reference_spec.rb11
-rw-r--r--spec/ruby/library/stringscanner/empty_spec.rb16
-rw-r--r--spec/ruby/library/stringscanner/eos_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/exist_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/get_byte_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/getbyte_spec.rb16
-rw-r--r--spec/ruby/library/stringscanner/getch_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/initialize_spec.rb3
-rw-r--r--spec/ruby/library/stringscanner/inspect_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/match_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/matched_size_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/matched_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/must_C_version_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/peek_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/peep_spec.rb16
-rw-r--r--spec/ruby/library/stringscanner/pointer_spec.rb8
-rw-r--r--spec/ruby/library/stringscanner/pos_spec.rb8
-rw-r--r--spec/ruby/library/stringscanner/post_match_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/pre_match_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/reset_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/rest_size_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/rest_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/restsize_spec.rb16
-rw-r--r--spec/ruby/library/stringscanner/scan_full_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/scan_spec.rb66
-rw-r--r--spec/ruby/library/stringscanner/scan_until_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/search_full_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/shared/concat.rb12
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range.rb16
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range_matched.rb14
-rw-r--r--spec/ruby/library/stringscanner/shared/peek.rb18
-rw-r--r--spec/ruby/library/stringscanner/shared/pos.rb4
-rw-r--r--spec/ruby/library/stringscanner/skip_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/skip_until_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/string_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/terminate_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/unscan_spec.rb6
-rw-r--r--spec/ruby/library/syslog/alert_spec.rb5
-rw-r--r--spec/ruby/library/syslog/close_spec.rb9
-rw-r--r--spec/ruby/library/syslog/constants_spec.rb3
-rw-r--r--spec/ruby/library/syslog/crit_spec.rb5
-rw-r--r--spec/ruby/library/syslog/debug_spec.rb5
-rw-r--r--spec/ruby/library/syslog/emerg_spec.rb5
-rw-r--r--spec/ruby/library/syslog/err_spec.rb5
-rw-r--r--spec/ruby/library/syslog/facility_spec.rb3
-rw-r--r--spec/ruby/library/syslog/ident_spec.rb5
-rw-r--r--spec/ruby/library/syslog/info_spec.rb5
-rw-r--r--spec/ruby/library/syslog/inspect_spec.rb3
-rw-r--r--spec/ruby/library/syslog/instance_spec.rb3
-rw-r--r--spec/ruby/library/syslog/log_spec.rb23
-rw-r--r--spec/ruby/library/syslog/mask_spec.rb11
-rw-r--r--spec/ruby/library/syslog/notice_spec.rb5
-rw-r--r--spec/ruby/library/syslog/open_spec.rb14
-rw-r--r--spec/ruby/library/syslog/opened_spec.rb3
-rw-r--r--spec/ruby/library/syslog/options_spec.rb3
-rw-r--r--spec/ruby/library/syslog/reopen_spec.rb5
-rw-r--r--spec/ruby/library/syslog/shared/log.rb15
-rw-r--r--spec/ruby/library/syslog/shared/reopen.rb4
-rw-r--r--spec/ruby/library/syslog/warning_spec.rb5
-rw-r--r--spec/ruby/library/tempfile/_close_spec.rb2
-rw-r--r--spec/ruby/library/tempfile/callback_spec.rb2
-rw-r--r--spec/ruby/library/tempfile/close_spec.rb8
-rw-r--r--spec/ruby/library/tempfile/delete_spec.rb4
-rw-r--r--spec/ruby/library/tempfile/initialize_spec.rb11
-rw-r--r--spec/ruby/library/tempfile/length_spec.rb4
-rw-r--r--spec/ruby/library/tempfile/open_spec.rb19
-rw-r--r--spec/ruby/library/tempfile/path_spec.rb2
-rw-r--r--spec/ruby/library/tempfile/shared/unlink.rb2
-rw-r--r--spec/ruby/library/tempfile/size_spec.rb4
-rw-r--r--spec/ruby/library/tempfile/unlink_spec.rb4
-rw-r--r--spec/ruby/library/thread/exclusive_spec.rb12
-rw-r--r--spec/ruby/library/thread/queue/append_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/clear_spec.rb9
-rw-r--r--spec/ruby/library/thread/queue/close_spec.rb9
-rw-r--r--spec/ruby/library/thread/queue/closed_spec.rb9
-rw-r--r--spec/ruby/library/thread/queue/deq_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/empty_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/enq_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/length_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/num_waiting_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/pop_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/push_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/shift_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue/size_spec.rb7
-rw-r--r--spec/ruby/library/thread/queue_spec.rb8
-rw-r--r--spec/ruby/library/thread/shared/queue/clear.rb10
-rw-r--r--spec/ruby/library/thread/shared/queue/close.rb26
-rw-r--r--spec/ruby/library/thread/shared/queue/deque.rb37
-rw-r--r--spec/ruby/library/thread/shared/queue/enque.rb10
-rw-r--r--spec/ruby/library/thread/sizedqueue/append_spec.rb12
-rw-r--r--spec/ruby/library/thread/sizedqueue/clear_spec.rb9
-rw-r--r--spec/ruby/library/thread/sizedqueue/close_spec.rb9
-rw-r--r--spec/ruby/library/thread/sizedqueue/closed_spec.rb9
-rw-r--r--spec/ruby/library/thread/sizedqueue/deq_spec.rb7
-rw-r--r--spec/ruby/library/thread/sizedqueue/empty_spec.rb7
-rw-r--r--spec/ruby/library/thread/sizedqueue/enq_spec.rb12
-rw-r--r--spec/ruby/library/thread/sizedqueue/length_spec.rb7
-rw-r--r--spec/ruby/library/thread/sizedqueue/max_spec.rb52
-rw-r--r--spec/ruby/library/thread/sizedqueue/new_spec.rb25
-rw-r--r--spec/ruby/library/thread/sizedqueue/num_waiting_spec.rb18
-rw-r--r--spec/ruby/library/thread/sizedqueue/pop_spec.rb7
-rw-r--r--spec/ruby/library/thread/sizedqueue/push_spec.rb12
-rw-r--r--spec/ruby/library/thread/sizedqueue/shared/enque.rb34
-rw-r--r--spec/ruby/library/thread/sizedqueue/shift_spec.rb7
-rw-r--r--spec/ruby/library/thread/sizedqueue/size_spec.rb7
-rw-r--r--spec/ruby/library/thread/sizedqueue_spec.rb8
-rw-r--r--spec/ruby/library/time/httpdate_spec.rb2
-rw-r--r--spec/ruby/library/time/iso8601_spec.rb4
-rw-r--r--spec/ruby/library/time/rfc2822_spec.rb4
-rw-r--r--spec/ruby/library/time/rfc822_spec.rb4
-rw-r--r--spec/ruby/library/time/shared/rfc2822.rb2
-rw-r--r--spec/ruby/library/time/to_date_spec.rb2
-rw-r--r--spec/ruby/library/time/to_datetime_spec.rb27
-rw-r--r--spec/ruby/library/time/to_time_spec.rb15
-rw-r--r--spec/ruby/library/time/xmlschema_spec.rb4
-rw-r--r--spec/ruby/library/timeout/error_spec.rb2
-rw-r--r--spec/ruby/library/timeout/timeout_spec.rb29
-rw-r--r--spec/ruby/library/tmpdir/dir/mktmpdir_spec.rb12
-rw-r--r--spec/ruby/library/tmpdir/dir/tmpdir_spec.rb2
-rw-r--r--spec/ruby/library/uri/decode_www_form_component_spec.rb2
-rw-r--r--spec/ruby/library/uri/decode_www_form_spec.rb2
-rw-r--r--spec/ruby/library/uri/encode_www_form_component_spec.rb2
-rw-r--r--spec/ruby/library/uri/encode_www_form_spec.rb2
-rw-r--r--spec/ruby/library/uri/eql_spec.rb6
-rw-r--r--spec/ruby/library/uri/equality_spec.rb6
-rw-r--r--spec/ruby/library/uri/escape/decode_spec.rb2
-rw-r--r--spec/ruby/library/uri/escape/encode_spec.rb2
-rw-r--r--spec/ruby/library/uri/escape/escape_spec.rb2
-rw-r--r--spec/ruby/library/uri/escape/unescape_spec.rb2
-rw-r--r--spec/ruby/library/uri/extract_spec.rb2
-rw-r--r--spec/ruby/library/uri/ftp/build_spec.rb2
-rw-r--r--spec/ruby/library/uri/ftp/merge_spec.rb2
-rw-r--r--spec/ruby/library/uri/ftp/new2_spec.rb2
-rw-r--r--spec/ruby/library/uri/ftp/path_spec.rb2
-rw-r--r--spec/ruby/library/uri/ftp/set_typecode_spec.rb2
-rw-r--r--spec/ruby/library/uri/ftp/to_s_spec.rb2
-rw-r--r--spec/ruby/library/uri/ftp/typecode_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/absolute_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/build2_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/build_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/coerce_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/component_ary_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/component_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/default_port_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/eql_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/equal_value_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/fragment_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/hash_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/hierarchical_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/host_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/inspect_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/merge_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/minus_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/normalize_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/opaque_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/password_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/path_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/plus_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/port_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/query_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/registry_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/relative_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/route_from_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/route_to_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/scheme_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/select_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_fragment_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_host_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_opaque_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_password_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_path_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_port_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_query_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_registry_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_scheme_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_user_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/set_userinfo_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/to_s_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/use_registry_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/user_spec.rb2
-rw-r--r--spec/ruby/library/uri/generic/userinfo_spec.rb2
-rw-r--r--spec/ruby/library/uri/http/build_spec.rb2
-rw-r--r--spec/ruby/library/uri/http/request_uri_spec.rb2
-rw-r--r--spec/ruby/library/uri/join_spec.rb6
-rw-r--r--spec/ruby/library/uri/ldap/attributes_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/build_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/dn_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/extensions_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/filter_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/hierarchical_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/scope_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/set_attributes_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/set_dn_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/set_extensions_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/set_filter_spec.rb2
-rw-r--r--spec/ruby/library/uri/ldap/set_scope_spec.rb2
-rw-r--r--spec/ruby/library/uri/mailto/build_spec.rb10
-rw-r--r--spec/ruby/library/uri/mailto/headers_spec.rb2
-rw-r--r--spec/ruby/library/uri/mailto/set_headers_spec.rb2
-rw-r--r--spec/ruby/library/uri/mailto/set_to_spec.rb2
-rw-r--r--spec/ruby/library/uri/mailto/to_mailtext_spec.rb2
-rw-r--r--spec/ruby/library/uri/mailto/to_rfc822text_spec.rb2
-rw-r--r--spec/ruby/library/uri/mailto/to_s_spec.rb2
-rw-r--r--spec/ruby/library/uri/mailto/to_spec.rb2
-rw-r--r--spec/ruby/library/uri/merge_spec.rb2
-rw-r--r--spec/ruby/library/uri/normalize_spec.rb4
-rw-r--r--spec/ruby/library/uri/parse_spec.rb4
-rw-r--r--spec/ruby/library/uri/parser/escape_spec.rb2
-rw-r--r--spec/ruby/library/uri/parser/extract_spec.rb4
-rw-r--r--spec/ruby/library/uri/parser/inspect_spec.rb2
-rw-r--r--spec/ruby/library/uri/parser/join_spec.rb4
-rw-r--r--spec/ruby/library/uri/parser/make_regexp_spec.rb2
-rw-r--r--spec/ruby/library/uri/parser/parse_spec.rb6
-rw-r--r--spec/ruby/library/uri/parser/split_spec.rb2
-rw-r--r--spec/ruby/library/uri/parser/unescape_spec.rb2
-rw-r--r--spec/ruby/library/uri/plus_spec.rb6
-rw-r--r--spec/ruby/library/uri/regexp_spec.rb2
-rw-r--r--spec/ruby/library/uri/route_from_spec.rb2
-rw-r--r--spec/ruby/library/uri/route_to_spec.rb2
-rw-r--r--spec/ruby/library/uri/select_spec.rb12
-rw-r--r--spec/ruby/library/uri/set_component_spec.rb24
-rw-r--r--spec/ruby/library/uri/shared/join.rb4
-rw-r--r--spec/ruby/library/uri/shared/parse.rb4
-rw-r--r--spec/ruby/library/uri/split_spec.rb2
-rw-r--r--spec/ruby/library/uri/uri_spec.rb4
-rw-r--r--spec/ruby/library/uri/util/make_components_hash_spec.rb2
-rw-r--r--spec/ruby/library/weakref/__getobj___spec.rb6
-rw-r--r--spec/ruby/library/weakref/allocate_spec.rb8
-rw-r--r--spec/ruby/library/weakref/new_spec.rb13
-rw-r--r--spec/ruby/library/weakref/send_spec.rb6
-rw-r--r--spec/ruby/library/weakref/weakref_alive_spec.rb8
-rw-r--r--spec/ruby/library/win32ole/fixtures/classes.rb16
-rw-r--r--spec/ruby/library/win32ole/fixtures/event.xml4
-rw-r--r--spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb15
-rw-r--r--spec/ruby/library/win32ole/win32ole/_invoke_spec.rb10
-rw-r--r--spec/ruby/library/win32ole/win32ole/codepage_spec.rb4
-rw-r--r--spec/ruby/library/win32ole/win32ole/connect_spec.rb6
-rw-r--r--spec/ruby/library/win32ole/win32ole/const_load_spec.rb4
-rw-r--r--spec/ruby/library/win32ole/win32ole/constants_spec.rb4
-rw-r--r--spec/ruby/library/win32ole/win32ole/create_guid_spec.rb4
-rw-r--r--spec/ruby/library/win32ole/win32ole/invoke_spec.rb15
-rw-r--r--spec/ruby/library/win32ole/win32ole/locale_spec.rb6
-rw-r--r--spec/ruby/library/win32ole/win32ole/new_spec.rb8
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb4
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb6
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_method_spec.rb6
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb13
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole/setproperty_spec.rb6
-rw-r--r--spec/ruby/library/win32ole/win32ole/shared/ole_method.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole/shared/setproperty.rb22
-rw-r--r--spec/ruby/library/win32ole/win32ole_event/new_spec.rb46
-rw-r--r--spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb104
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb36
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/event_spec.rb26
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb10
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/name_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/new_spec.rb12
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb4
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/params_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/shared/name.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/visible_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/default_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/input_spec.rb4
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/name_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/optional_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/retval_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/shared/name.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/name_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/new_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/progids_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/shared/name.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/name_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/value_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_builtin_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_domain_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_private_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_ruby_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/detect_implicit_spec.rb2
-rw-r--r--spec/ruby/library/yaml/dump_spec.rb11
-rw-r--r--spec/ruby/library/yaml/dump_stream_spec.rb4
-rw-r--r--spec/ruby/library/yaml/each_node_spec.rb2
-rw-r--r--spec/ruby/library/yaml/emitter_spec.rb2
-rw-r--r--spec/ruby/library/yaml/fixtures/example_class.rb8
-rw-r--r--spec/ruby/library/yaml/generic_parser_spec.rb2
-rw-r--r--spec/ruby/library/yaml/load_documents_spec.rb10
-rw-r--r--spec/ruby/library/yaml/load_file_spec.rb4
-rw-r--r--spec/ruby/library/yaml/load_spec.rb31
-rw-r--r--spec/ruby/library/yaml/load_stream_spec.rb8
-rw-r--r--spec/ruby/library/yaml/object_maker_spec.rb2
-rw-r--r--spec/ruby/library/yaml/parse_documents_spec.rb2
-rw-r--r--spec/ruby/library/yaml/parse_file_spec.rb10
-rw-r--r--spec/ruby/library/yaml/parse_spec.rb4
-rw-r--r--spec/ruby/library/yaml/parser_spec.rb2
-rw-r--r--spec/ruby/library/yaml/quick_emit_spec.rb2
-rw-r--r--spec/ruby/library/yaml/read_type_class_spec.rb2
-rw-r--r--spec/ruby/library/yaml/shared/each_document.rb2
-rw-r--r--spec/ruby/library/yaml/tagurize_spec.rb11
-rw-r--r--spec/ruby/library/yaml/to_yaml_spec.rb23
-rw-r--r--spec/ruby/library/yaml/transfer_spec.rb2
-rw-r--r--spec/ruby/library/yaml/try_implicit_spec.rb2
-rw-r--r--spec/ruby/library/zlib/adler32_spec.rb6
-rw-r--r--spec/ruby/library/zlib/crc32_spec.rb8
-rw-r--r--spec/ruby/library/zlib/crc_table_spec.rb2
-rw-r--r--spec/ruby/library/zlib/deflate/append_spec.rb1
-rw-r--r--spec/ruby/library/zlib/deflate/deflate_spec.rb4
-rw-r--r--spec/ruby/library/zlib/deflate/flush_spec.rb1
-rw-r--r--spec/ruby/library/zlib/deflate/new_spec.rb2
-rw-r--r--spec/ruby/library/zlib/deflate/params_spec.rb2
-rw-r--r--spec/ruby/library/zlib/deflate/set_dictionary_spec.rb3
-rw-r--r--spec/ruby/library/zlib/deflate_spec.rb8
-rw-r--r--spec/ruby/library/zlib/gunzip_spec.rb14
-rw-r--r--spec/ruby/library/zlib/gzip_spec.rb15
-rw-r--r--spec/ruby/library/zlib/gzipfile/close_spec.rb9
-rw-r--r--spec/ruby/library/zlib/gzipfile/closed_spec.rb7
-rw-r--r--spec/ruby/library/zlib/gzipfile/comment_spec.rb5
-rw-r--r--spec/ruby/library/zlib/gzipfile/crc_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipfile/finish_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipfile/level_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipfile/mtime_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipfile/orig_name_spec.rb5
-rw-r--r--spec/ruby/library/zlib/gzipfile/os_code_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipfile/sync_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipfile/to_io_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipfile/wrap_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/each_byte_spec.rb4
-rw-r--r--spec/ruby/library/zlib/gzipreader/each_line_spec.rb4
-rw-r--r--spec/ruby/library/zlib/gzipreader/each_spec.rb4
-rw-r--r--spec/ruby/library/zlib/gzipreader/eof_spec.rb8
-rw-r--r--spec/ruby/library/zlib/gzipreader/getc_spec.rb6
-rw-r--r--spec/ruby/library/zlib/gzipreader/gets_spec.rb4
-rw-r--r--spec/ruby/library/zlib/gzipreader/lineno_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/new_spec.rb2
-rw-r--r--spec/ruby/library/zlib/gzipreader/open_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/pos_spec.rb7
-rw-r--r--spec/ruby/library/zlib/gzipreader/read_spec.rb12
-rw-r--r--spec/ruby/library/zlib/gzipreader/readchar_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/readline_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/readlines_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/readpartial_spec.rb4
-rw-r--r--spec/ruby/library/zlib/gzipreader/rewind_spec.rb5
-rw-r--r--spec/ruby/library/zlib/gzipreader/shared/each.rb4
-rw-r--r--spec/ruby/library/zlib/gzipreader/tell_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/ungetbyte_spec.rb12
-rw-r--r--spec/ruby/library/zlib/gzipreader/ungetc_spec.rb36
-rw-r--r--spec/ruby/library/zlib/gzipreader/unused_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/append_spec.rb4
-rw-r--r--spec/ruby/library/zlib/gzipwriter/comment_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/flush_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/mtime_spec.rb4
-rw-r--r--spec/ruby/library/zlib/gzipwriter/new_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/open_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/orig_name_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/pos_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/print_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/printf_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/putc_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/puts_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/tell_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/write_spec.rb4
-rw-r--r--spec/ruby/library/zlib/inflate/append_spec.rb4
-rw-r--r--spec/ruby/library/zlib/inflate/inflate_spec.rb4
-rw-r--r--spec/ruby/library/zlib/inflate/new_spec.rb2
-rw-r--r--spec/ruby/library/zlib/inflate/set_dictionary_spec.rb3
-rw-r--r--spec/ruby/library/zlib/inflate/sync_point_spec.rb1
-rw-r--r--spec/ruby/library/zlib/inflate/sync_spec.rb1
-rw-r--r--spec/ruby/library/zlib/inflate_spec.rb8
-rw-r--r--spec/ruby/library/zlib/zlib_version_spec.rb9
-rw-r--r--spec/ruby/library/zlib/zstream/adler_spec.rb2
-rw-r--r--spec/ruby/library/zlib/zstream/avail_in_spec.rb2
-rw-r--r--spec/ruby/library/zlib/zstream/avail_out_spec.rb2
-rw-r--r--spec/ruby/library/zlib/zstream/close_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/closed_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/data_type_spec.rb2
-rw-r--r--spec/ruby/library/zlib/zstream/end_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/ended_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/finish_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/finished_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/flush_next_in_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/flush_next_out_spec.rb6
-rw-r--r--spec/ruby/library/zlib/zstream/reset_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/stream_end_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/total_in_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/total_out_spec.rb1
-rw-r--r--spec/ruby/optional/capi/README9
-rw-r--r--spec/ruby/optional/capi/array_spec.rb52
-rw-r--r--spec/ruby/optional/capi/basic_object_spec.rb24
-rw-r--r--spec/ruby/optional/capi/bignum_spec.rb28
-rw-r--r--spec/ruby/optional/capi/boolean_spec.rb2
-rw-r--r--spec/ruby/optional/capi/class_spec.rb166
-rw-r--r--spec/ruby/optional/capi/complex_spec.rb2
-rw-r--r--spec/ruby/optional/capi/constants_spec.rb109
-rw-r--r--spec/ruby/optional/capi/data_spec.rb11
-rw-r--r--spec/ruby/optional/capi/encoding_spec.rb278
-rw-r--r--spec/ruby/optional/capi/enumerator_spec.rb29
-rw-r--r--spec/ruby/optional/capi/exception_spec.rb53
-rw-r--r--spec/ruby/optional/capi/ext/array_spec.c219
-rw-r--r--spec/ruby/optional/capi/ext/basic_object_spec.c19
-rw-r--r--spec/ruby/optional/capi/ext/bignum_spec.c59
-rw-r--r--spec/ruby/optional/capi/ext/boolean_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c149
-rw-r--r--spec/ruby/optional/capi/ext/class_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/complex_spec.c33
-rw-r--r--spec/ruby/optional/capi/ext/constants_spec.c694
-rw-r--r--spec/ruby/optional/capi/ext/data_spec.c24
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c304
-rw-r--r--spec/ruby/optional/capi/ext/enumerator_spec.c19
-rw-r--r--spec/ruby/optional/capi/ext/exception_spec.c36
-rw-r--r--spec/ruby/optional/capi/ext/file_spec.c15
-rw-r--r--spec/ruby/optional/capi/ext/fixnum_spec.c28
-rw-r--r--spec/ruby/optional/capi/ext/float_spec.c27
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c46
-rw-r--r--spec/ruby/optional/capi/ext/globals_spec.c96
-rw-r--r--spec/ruby/optional/capi/ext/hash_spec.c106
-rw-r--r--spec/ruby/optional/capi/ext/integer_spec.c17
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c149
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c231
-rw-r--r--spec/ruby/optional/capi/ext/language_spec.c42
-rw-r--r--spec/ruby/optional/capi/ext/marshal_spec.c14
-rw-r--r--spec/ruby/optional/capi/ext/module_spec.c109
-rw-r--r--spec/ruby/optional/capi/ext/module_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/mutex_spec.c38
-rw-r--r--spec/ruby/optional/capi/ext/numeric_spec.c154
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c318
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c26
-rw-r--r--spec/ruby/optional/capi/ext/range_spec.c18
-rw-r--r--spec/ruby/optional/capi/ext/rational_spec.c43
-rw-r--r--spec/ruby/optional/capi/ext/rbasic_spec.c94
-rw-r--r--spec/ruby/optional/capi/ext/regexp_spec.c45
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h606
-rw-r--r--spec/ruby/optional/capi/ext/st_spec.c12
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c462
-rw-r--r--spec/ruby/optional/capi/ext/struct_spec.c48
-rw-r--r--spec/ruby/optional/capi/ext/symbol_spec.c65
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c62
-rw-r--r--spec/ruby/optional/capi/ext/time_spec.c48
-rw-r--r--spec/ruby/optional/capi/ext/tracepoint_spec.c49
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c88
-rw-r--r--spec/ruby/optional/capi/ext/util_spec.c80
-rw-r--r--spec/ruby/optional/capi/file_spec.rb4
-rw-r--r--spec/ruby/optional/capi/fixnum_spec.rb113
-rw-r--r--spec/ruby/optional/capi/fixtures/class.rb11
-rw-r--r--spec/ruby/optional/capi/float_spec.rb15
-rw-r--r--spec/ruby/optional/capi/gc_spec.rb41
-rw-r--r--spec/ruby/optional/capi/globals_spec.rb37
-rw-r--r--spec/ruby/optional/capi/hash_spec.rb41
-rw-r--r--spec/ruby/optional/capi/integer_spec.rb17
-rw-r--r--spec/ruby/optional/capi/io_spec.rb71
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb276
-rw-r--r--spec/ruby/optional/capi/language_spec.rb37
-rw-r--r--spec/ruby/optional/capi/marshal_spec.rb2
-rw-r--r--spec/ruby/optional/capi/module_spec.rb58
-rw-r--r--spec/ruby/optional/capi/mutex_spec.rb17
-rw-r--r--spec/ruby/optional/capi/numeric_spec.rb330
-rw-r--r--spec/ruby/optional/capi/object_spec.rb315
-rw-r--r--spec/ruby/optional/capi/proc_spec.rb69
-rw-r--r--spec/ruby/optional/capi/rake_helper.rb1
-rw-r--r--spec/ruby/optional/capi/range_spec.rb8
-rw-r--r--spec/ruby/optional/capi/rational_spec.rb2
-rw-r--r--spec/ruby/optional/capi/rbasic_spec.rb22
-rw-r--r--spec/ruby/optional/capi/regexp_spec.rb16
-rw-r--r--spec/ruby/optional/capi/shared/rbasic.rb83
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb77
-rw-r--r--spec/ruby/optional/capi/st_spec.rb2
-rw-r--r--spec/ruby/optional/capi/string_spec.rb496
-rw-r--r--spec/ruby/optional/capi/struct_spec.rb44
-rw-r--r--spec/ruby/optional/capi/symbol_spec.rb41
-rw-r--r--spec/ruby/optional/capi/thread_spec.rb47
-rw-r--r--spec/ruby/optional/capi/time_spec.rb160
-rw-r--r--spec/ruby/optional/capi/tracepoint_spec.rb56
-rw-r--r--spec/ruby/optional/capi/typed_data_spec.rb35
-rw-r--r--spec/ruby/optional/capi/util_spec.rb183
-rw-r--r--spec/ruby/security/cve_2010_1330_spec.rb21
-rw-r--r--spec/ruby/security/cve_2011_4815_spec.rb14
-rw-r--r--spec/ruby/security/cve_2013_4164_spec.rb2
-rw-r--r--spec/ruby/security/cve_2014_8080_spec.rb53
-rw-r--r--spec/ruby/security/cve_2017_17742_spec.rb34
-rw-r--r--spec/ruby/security/cve_2018_16396_spec.rb25
-rw-r--r--spec/ruby/security/cve_2018_6914_spec.rb55
-rw-r--r--spec/ruby/security/cve_2018_8778_spec.rb12
-rw-r--r--spec/ruby/security/cve_2018_8779_spec.rb30
-rw-r--r--spec/ruby/security/cve_2018_8780_spec.rb43
-rw-r--r--spec/ruby/security/cve_2019_8321_spec.rb22
-rw-r--r--spec/ruby/security/cve_2019_8322_spec.rb23
-rw-r--r--spec/ruby/security/cve_2019_8323_spec.rb38
-rw-r--r--spec/ruby/security/cve_2019_8325_spec.rb38
-rw-r--r--spec/ruby/security/cve_2020_10663_spec.rb41
-rw-r--r--spec/ruby/shared/basicobject/method_missing.rb36
-rw-r--r--spec/ruby/shared/basicobject/send.rb28
-rw-r--r--spec/ruby/shared/complex/Complex.rb133
-rw-r--r--spec/ruby/shared/complex/abs.rb12
-rw-r--r--spec/ruby/shared/complex/abs2.rb12
-rw-r--r--spec/ruby/shared/complex/coerce.rb70
-rw-r--r--spec/ruby/shared/complex/constants.rb7
-rw-r--r--spec/ruby/shared/complex/denominator.rb13
-rw-r--r--spec/ruby/shared/complex/divide.rb84
-rw-r--r--spec/ruby/shared/complex/equal_value.rb93
-rw-r--r--spec/ruby/shared/complex/exponent.rb61
-rw-r--r--spec/ruby/shared/complex/float/arg.rb38
-rw-r--r--spec/ruby/shared/complex/hash.rb16
-rw-r--r--spec/ruby/shared/complex/image.rb10
-rw-r--r--spec/ruby/shared/complex/inspect.rb14
-rw-r--r--spec/ruby/shared/complex/minus.rb45
-rw-r--r--spec/ruby/shared/complex/multiply.rb49
-rw-r--r--spec/ruby/shared/complex/numerator.rb19
-rw-r--r--spec/ruby/shared/complex/numeric/arg.rb38
-rw-r--r--spec/ruby/shared/complex/numeric/conj.rb20
-rw-r--r--spec/ruby/shared/complex/numeric/imag.rb26
-rw-r--r--spec/ruby/shared/complex/numeric/polar.rb50
-rw-r--r--spec/ruby/shared/complex/numeric/real.rb30
-rw-r--r--spec/ruby/shared/complex/plus.rb45
-rw-r--r--spec/ruby/shared/complex/polar.rb22
-rw-r--r--spec/ruby/shared/complex/real.rb8
-rw-r--r--spec/ruby/shared/complex/rect.rb96
-rw-r--r--spec/ruby/shared/complex/to_s.rb44
-rw-r--r--spec/ruby/shared/enumerable/minmax.rb24
-rw-r--r--spec/ruby/shared/enumerator/each.rb89
-rw-r--r--spec/ruby/shared/enumerator/enum_cons.rb12
-rw-r--r--spec/ruby/shared/enumerator/enum_for.rb7
-rw-r--r--spec/ruby/shared/enumerator/new.rb42
-rw-r--r--spec/ruby/shared/enumerator/next.rb28
-rw-r--r--spec/ruby/shared/enumerator/rewind.rb39
-rw-r--r--spec/ruby/shared/enumerator/with_index.rb15
-rw-r--r--spec/ruby/shared/enumerator/with_object.rb2
-rw-r--r--spec/ruby/shared/fiber/resume.rb50
-rw-r--r--spec/ruby/shared/file/directory.rb6
-rw-r--r--spec/ruby/shared/file/executable.rb10
-rw-r--r--spec/ruby/shared/file/executable_real.rb8
-rw-r--r--spec/ruby/shared/file/exist.rb6
-rw-r--r--spec/ruby/shared/file/file.rb8
-rw-r--r--spec/ruby/shared/file/grpowned.rb3
-rw-r--r--spec/ruby/shared/file/identical.rb12
-rw-r--r--spec/ruby/shared/file/readable.rb5
-rw-r--r--spec/ruby/shared/file/size.rb2
-rw-r--r--spec/ruby/shared/file/world_readable.rb16
-rw-r--r--spec/ruby/shared/file/world_writable.rb16
-rw-r--r--spec/ruby/shared/file/writable.rb6
-rw-r--r--spec/ruby/shared/file/writable_real.rb8
-rw-r--r--spec/ruby/shared/file/zero.rb22
-rw-r--r--spec/ruby/shared/hash/key_error.rb23
-rw-r--r--spec/ruby/shared/io/putc.rb12
-rw-r--r--spec/ruby/shared/kernel/object_id.rb8
-rw-r--r--spec/ruby/shared/kernel/raise.rb71
-rw-r--r--spec/ruby/shared/math/atanh.rb8
-rw-r--r--spec/ruby/shared/process/abort.rb12
-rw-r--r--spec/ruby/shared/process/exit.rb40
-rw-r--r--spec/ruby/shared/process/fork.rb6
-rw-r--r--spec/ruby/shared/queue/clear.rb12
-rw-r--r--spec/ruby/shared/queue/close.rb14
-rw-r--r--spec/ruby/shared/queue/closed.rb (renamed from spec/ruby/library/thread/shared/queue/closed.rb)0
-rw-r--r--spec/ruby/shared/queue/deque.rb85
-rw-r--r--spec/ruby/shared/queue/empty.rb (renamed from spec/ruby/library/thread/shared/queue/empty.rb)0
-rw-r--r--spec/ruby/shared/queue/enque.rb18
-rw-r--r--spec/ruby/shared/queue/length.rb (renamed from spec/ruby/library/thread/shared/queue/length.rb)0
-rw-r--r--spec/ruby/shared/queue/num_waiting.rb (renamed from spec/ruby/library/thread/shared/queue/num_waiting.rb)0
-rw-r--r--spec/ruby/shared/rational/Rational.rb56
-rw-r--r--spec/ruby/shared/rational/abs.rb2
-rw-r--r--spec/ruby/shared/rational/arithmetic_exception_in_coerce.rb11
-rw-r--r--spec/ruby/shared/rational/ceil.rb2
-rw-r--r--spec/ruby/shared/rational/coerce.rb15
-rw-r--r--spec/ruby/shared/rational/comparison.rb12
-rw-r--r--spec/ruby/shared/rational/denominator.rb2
-rw-r--r--spec/ruby/shared/rational/div.rb14
-rw-r--r--spec/ruby/shared/rational/divide.rb6
-rw-r--r--spec/ruby/shared/rational/divmod.rb8
-rw-r--r--spec/ruby/shared/rational/equal_value.rb2
-rw-r--r--spec/ruby/shared/rational/exponent.rb24
-rw-r--r--spec/ruby/shared/rational/fdiv.rb2
-rw-r--r--spec/ruby/shared/rational/floor.rb2
-rw-r--r--spec/ruby/shared/rational/hash.rb2
-rw-r--r--spec/ruby/shared/rational/inspect.rb14
-rw-r--r--spec/ruby/shared/rational/marshal_dump.rb2
-rw-r--r--spec/ruby/shared/rational/marshal_load.rb2
-rw-r--r--spec/ruby/shared/rational/minus.rb8
-rw-r--r--spec/ruby/shared/rational/modulo.rb10
-rw-r--r--spec/ruby/shared/rational/multiply.rb2
-rw-r--r--spec/ruby/shared/rational/numerator.rb2
-rw-r--r--spec/ruby/shared/rational/plus.rb8
-rw-r--r--spec/ruby/shared/rational/quo.rb2
-rw-r--r--spec/ruby/shared/rational/remainder.rb2
-rw-r--r--spec/ruby/shared/rational/round.rb41
-rw-r--r--spec/ruby/shared/rational/to_f.rb2
-rw-r--r--spec/ruby/shared/rational/to_i.rb2
-rw-r--r--spec/ruby/shared/rational/to_r.rb14
-rw-r--r--spec/ruby/shared/rational/to_s.rb9
-rw-r--r--spec/ruby/shared/rational/truncate.rb2
-rw-r--r--spec/ruby/shared/sizedqueue/enque.rb50
-rw-r--r--spec/ruby/shared/sizedqueue/max.rb47
-rw-r--r--spec/ruby/shared/sizedqueue/new.rb18
-rw-r--r--spec/ruby/shared/sizedqueue/num_waiting.rb12
-rw-r--r--spec/ruby/shared/string/end_with.rb54
-rw-r--r--spec/ruby/shared/string/start_with.rb72
-rw-r--r--spec/ruby/shared/string/times.rb58
-rw-r--r--spec/ruby/shared/time/strftime_for_date.rb10
-rw-r--r--spec/ruby/spec_helper.rb16
-rw-r--r--sprintf.c307
-rw-r--r--st.c632
-rw-r--r--strftime.c55
-rw-r--r--string.c3605
-rw-r--r--struct.c328
-rw-r--r--symbol.c687
-rw-r--r--symbol.h21
-rw-r--r--template/Doxyfile.tmpl51
-rw-r--r--template/GNUmakefile.in8
-rw-r--r--template/Makefile.in687
-rw-r--r--template/builtin_binary.inc.tmpl30
-rw-r--r--template/call_iseq_optimized.inc.tmpl68
-rw-r--r--template/configure-ext.mk.tmpl7
-rw-r--r--template/depend.tmpl2
-rw-r--r--template/encdb.h.tmpl38
-rw-r--r--template/exts.mk.tmpl35
-rw-r--r--template/fake.rb.in20
-rw-r--r--template/id.c.tmpl2
-rw-r--r--template/insns.inc.tmpl24
-rw-r--r--template/insns_info.inc.tmpl109
-rw-r--r--template/minsns.inc.tmpl14
-rw-r--r--template/opt_sc.inc.tmpl35
-rw-r--r--template/optinsn.inc.tmpl54
-rw-r--r--template/optunifs.inc.tmpl67
-rw-r--r--template/prelude.c.tmpl168
-rwxr-xr-xtemplate/ruby-gdb.in6
-rwxr-xr-xtemplate/ruby-lldb.in6
-rw-r--r--template/ruby-runner.h.in2
-rw-r--r--template/ruby.pc.in3
-rw-r--r--template/transdb.h.tmpl21
-rw-r--r--template/unicode_norm_gen.tmpl24
-rw-r--r--template/verconf.h.tmpl2
-rw-r--r--template/vm.inc.tmpl33
-rw-r--r--template/vmtc.inc.tmpl21
-rw-r--r--template/yasmdata.rb.tmpl20
-rw-r--r--test/-ext-/arith_seq/test_arith_seq_extract.rb40
-rw-r--r--test/-ext-/array/test_resize.rb2
-rw-r--r--test/-ext-/array/test_to_ary_concat.rb20
-rw-r--r--test/-ext-/bignum/test_big2str.rb2
-rw-r--r--test/-ext-/bignum/test_bigzero.rb2
-rw-r--r--test/-ext-/bignum/test_div.rb2
-rw-r--r--test/-ext-/bignum/test_mul.rb2
-rw-r--r--test/-ext-/bignum/test_pack.rb2
-rw-r--r--test/-ext-/bignum/test_str2big.rb2
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb6
-rw-r--r--test/-ext-/debug/test_debug.rb16
-rw-r--r--test/-ext-/debug/test_profile_frames.rb50
-rw-r--r--test/-ext-/exception/test_data_error.rb2
-rw-r--r--test/-ext-/exception/test_enc_raise.rb2
-rw-r--r--test/-ext-/exception/test_ensured.rb2
-rw-r--r--test/-ext-/exception/test_exception_at_throwing.rb2
-rw-r--r--test/-ext-/funcall/test_funcall.rb11
-rw-r--r--test/-ext-/funcall/test_passing_block.rb41
-rw-r--r--test/-ext-/gvl/test_last_thread.rb1
-rw-r--r--test/-ext-/gvl/test_ubf_async_safe.rb20
-rw-r--r--test/-ext-/hash/test_delete.rb2
-rw-r--r--test/-ext-/integer/test_integer.rb13
-rw-r--r--test/-ext-/integer/test_my_integer.rb2
-rw-r--r--test/-ext-/iseq_load/test_iseq_load.rb67
-rw-r--r--test/-ext-/iter/test_yield_block.rb2
-rw-r--r--test/-ext-/marshal/test_internal_ivar.rb8
-rw-r--r--test/-ext-/method/test_arity.rb2
-rw-r--r--test/-ext-/popen_deadlock/test_popen_deadlock.rb2
-rw-r--r--test/-ext-/postponed_job/test_postponed_job.rb11
-rw-r--r--test/-ext-/proc/test_bmethod.rb4
-rw-r--r--test/-ext-/rational/test_rat.rb38
-rw-r--r--test/-ext-/string/test_capacity.rb21
-rw-r--r--test/-ext-/string/test_cstr.rb8
-rw-r--r--test/-ext-/string/test_ellipsize.rb2
-rw-r--r--test/-ext-/string/test_enc_associate.rb4
-rw-r--r--test/-ext-/string/test_enc_str_buf_cat.rb9
-rw-r--r--test/-ext-/string/test_external_new.rb17
-rw-r--r--test/-ext-/string/test_fstring.rb54
-rw-r--r--test/-ext-/string/test_interned_str.rb12
-rw-r--r--test/-ext-/string/test_modify_expand.rb3
-rw-r--r--test/-ext-/string/test_normalize.rb8
-rw-r--r--test/-ext-/string/test_rb_str_dup.rb16
-rw-r--r--test/-ext-/struct/test_duplicate.rb4
-rw-r--r--test/-ext-/symbol/noninterned_name.rb2
-rw-r--r--test/-ext-/symbol/test_inadvertent_creation.rb21
-rw-r--r--test/-ext-/test_bug-14834.rb12
-rw-r--r--test/-ext-/test_enumerator_kw.rb11
-rw-r--r--test/-ext-/test_notimplement.rb31
-rw-r--r--test/-ext-/test_printf.rb11
-rw-r--r--test/-ext-/test_random.rb27
-rw-r--r--test/-ext-/test_scan_args.rb72
-rw-r--r--test/-ext-/thread_fd_close/test_thread_fd_close.rb6
-rw-r--r--test/-ext-/tracepoint/test_tracepoint.rb24
-rw-r--r--test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb26
-rw-r--r--test/-ext-/win32/test_console_attr.rb17
-rw-r--r--test/benchmark/test_benchmark.rb8
-rw-r--r--test/bigdecimal/test_bigdecimal.rb842
-rw-r--r--test/bigdecimal/test_bigdecimal_util.rb69
-rw-r--r--test/bigdecimal/test_ractor.rb23
-rw-r--r--test/cgi/test_cgi_cookie.rb87
-rw-r--r--test/cgi/test_cgi_core.rb4
-rw-r--r--test/cgi/test_cgi_header.rb8
-rw-r--r--test/cgi/test_cgi_multipart.rb3
-rw-r--r--test/cgi/test_cgi_util.rb61
-rw-r--r--test/coverage/test_coverage.rb502
-rw-r--r--test/csv/base.rb9
-rw-r--r--test/csv/helper.rb42
-rw-r--r--test/csv/interface/test_delegation.rb47
-rw-r--r--test/csv/interface/test_read.rb339
-rw-r--r--test/csv/interface/test_read_write.rb115
-rw-r--r--test/csv/interface/test_write.rb174
-rw-r--r--test/csv/parse/test_column_separator.rb40
-rw-r--r--test/csv/parse/test_convert.rb110
-rw-r--r--test/csv/parse/test_each.rb23
-rw-r--r--test/csv/parse/test_general.rb259
-rw-r--r--test/csv/parse/test_header.rb335
-rw-r--r--test/csv/parse/test_invalid.rb39
-rw-r--r--test/csv/parse/test_liberal_parsing.rb160
-rw-r--r--test/csv/parse/test_quote_char_nil.rb93
-rw-r--r--test/csv/parse/test_rewind.rb40
-rw-r--r--test/csv/parse/test_row_separator.rb16
-rw-r--r--test/csv/parse/test_skip_lines.rb118
-rw-r--r--test/csv/parse/test_strip.rb83
-rw-r--r--test/csv/parse/test_unconverted_fields.rb117
-rwxr-xr-xtest/csv/test_csv_parsing.rb244
-rwxr-xr-xtest/csv/test_csv_writing.rb98
-rw-r--r--[-rwxr-xr-x]test/csv/test_data_converters.rb243
-rw-r--r--[-rwxr-xr-x]test/csv/test_encodings.rb78
-rw-r--r--[-rwxr-xr-x]test/csv/test_features.rb203
-rwxr-xr-xtest/csv/test_headers.rb305
-rwxr-xr-xtest/csv/test_interface.rb393
-rw-r--r--[-rwxr-xr-x]test/csv/test_row.rb89
-rw-r--r--[-rwxr-xr-x]test/csv/test_table.rb243
-rw-r--r--test/csv/ts_all.rb21
-rw-r--r--test/csv/write/test_converters.rb53
-rw-r--r--test/csv/write/test_force_quotes.rb78
-rw-r--r--test/csv/write/test_general.rb246
-rw-r--r--test/csv/write/test_quote_empty.rb70
-rw-r--r--test/date/test_date.rb13
-rw-r--r--test/date/test_date_arith.rb31
-rw-r--r--test/date/test_date_attr.rb23
-rw-r--r--test/date/test_date_base.rb443
-rw-r--r--test/date/test_date_conv.rb18
-rw-r--r--test/date/test_date_marshal.rb21
-rw-r--r--test/date/test_date_new.rb116
-rw-r--r--test/date/test_date_parse.rb195
-rw-r--r--test/date/test_date_ractor.rb27
-rw-r--r--test/date/test_date_strftime.rb16
-rw-r--r--test/date/test_date_strptime.rb19
-rw-r--r--test/date/test_switch_hitter.rb60
-rw-r--r--test/dbm/test_dbm.rb6
-rw-r--r--test/did_you_mean/core_ext/test_name_error_extension.rb48
-rw-r--r--test/did_you_mean/edit_distance/test_jaro_winkler.rb36
-rw-r--r--test/did_you_mean/fixtures/book.rb4
-rw-r--r--test/did_you_mean/fixtures/mini_dir.yml15
-rw-r--r--test/did_you_mean/fixtures/rspec_dir.yml112
-rw-r--r--test/did_you_mean/helper.rb29
-rw-r--r--test/did_you_mean/spell_checking/test_class_name_check.rb81
-rw-r--r--test/did_you_mean/spell_checking/test_key_name_check.rb54
-rw-r--r--test/did_you_mean/spell_checking/test_method_name_check.rb147
-rw-r--r--test/did_you_mean/spell_checking/test_require_path_check.rb32
-rw-r--r--test/did_you_mean/spell_checking/test_uncorrectable_name_check.rb15
-rw-r--r--test/did_you_mean/spell_checking/test_variable_name_check.rb140
-rw-r--r--test/did_you_mean/test_spell_checker.rb77
-rw-r--r--test/did_you_mean/test_tree_spell_checker.rb170
-rw-r--r--test/did_you_mean/test_verbose_formatter.rb23
-rw-r--r--test/did_you_mean/tree_spell/change_word.rb61
-rw-r--r--test/did_you_mean/tree_spell/human_typo.rb69
-rw-r--r--test/did_you_mean/tree_spell/test_change_word.rb38
-rw-r--r--test/did_you_mean/tree_spell/test_human_typo.rb24
-rw-r--r--test/digest/test_digest.rb9
-rw-r--r--test/digest/test_digest_extend.rb2
-rw-r--r--test/digest/test_ractor.rb101
-rw-r--r--test/drb/drbtest.rb106
-rw-r--r--test/drb/test_acl.rb21
-rw-r--r--test/drb/test_drb.rb133
-rw-r--r--test/drb/test_drbobject.rb69
-rw-r--r--test/drb/test_drbssl.rb55
-rw-r--r--test/drb/test_drbunix.rb26
-rw-r--r--test/drb/ut_drb.rb21
-rw-r--r--test/dtrace/helper.rb100
-rw-r--r--test/dtrace/test_array_create.rb8
-rw-r--r--test/dtrace/test_function_entry.rb9
-rw-r--r--test/dtrace/test_hash_create.rb6
-rw-r--r--test/dtrace/test_method_cache.rb2
-rw-r--r--test/dtrace/test_require.rb6
-rw-r--r--test/dtrace/test_singleton_function.rb9
-rw-r--r--test/dtrace/test_string.rb6
-rw-r--r--test/erb/test_erb.rb139
-rw-r--r--test/erb/test_erb_command.rb20
-rw-r--r--test/erb/test_erb_m17n.rb2
-rw-r--r--test/etc/test_etc.rb28
-rw-r--r--test/excludes/_appveyor/TestArray.rb7
-rw-r--r--test/fiber/http.rb53
-rw-r--r--test/fiber/scheduler.rb210
-rw-r--r--test/fiber/test_backtrace.rb22
-rw-r--r--test/fiber/test_enumerator.rb51
-rw-r--r--test/fiber/test_io.rb100
-rw-r--r--test/fiber/test_mutex.rb220
-rw-r--r--test/fiber/test_process.rb51
-rw-r--r--test/fiber/test_ractor.rb23
-rw-r--r--test/fiber/test_scheduler.rb90
-rw-r--r--test/fiber/test_sleep.rb71
-rw-r--r--test/fiber/test_thread.rb108
-rw-r--r--test/fiddle/helper.rb65
-rw-r--r--test/fiddle/test_c_struct_entry.rb130
-rw-r--r--test/fiddle/test_c_union_entity.rb15
-rw-r--r--test/fiddle/test_closure.rb25
-rw-r--r--test/fiddle/test_cparser.rb179
-rw-r--r--test/fiddle/test_func.rb65
-rw-r--r--test/fiddle/test_function.rb55
-rw-r--r--test/fiddle/test_handle.rb17
-rw-r--r--test/fiddle/test_import.rb370
-rw-r--r--test/fiddle/test_memory_view.rb115
-rw-r--r--test/fiddle/test_pinned.rb27
-rw-r--r--test/fiddle/test_pointer.rb100
-rw-r--r--test/fileutils/test_dryrun.rb2
-rw-r--r--test/fileutils/test_fileutils.rb231
-rw-r--r--test/fileutils/test_nowrite.rb2
-rw-r--r--test/fileutils/test_verbose.rb2
-rw-r--r--test/fileutils/visibility_tests.rb4
-rw-r--r--test/fixtures/fake_sorted_set_gem/sorted_set.rb9
-rw-r--r--test/gdbm/test_gdbm.rb11
-rw-r--r--test/io/console/test_io_console.rb182
-rw-r--r--test/io/nonblock/test_flush.rb1
-rw-r--r--test/io/wait/test_io_wait.rb22
-rw-r--r--test/io/wait/test_io_wait_uncommon.rb78
-rw-r--r--test/io/wait/test_ractor.rb22
-rw-r--r--test/irb/test_cmd.rb429
-rw-r--r--test/irb/test_color.rb218
-rw-r--r--test/irb/test_color_printer.rb68
-rw-r--r--test/irb/test_completion.rb69
-rw-r--r--test/irb/test_context.rb597
-rw-r--r--test/irb/test_history.rb211
-rw-r--r--test/irb/test_init.rb83
-rw-r--r--test/irb/test_option.rb3
-rw-r--r--test/irb/test_raise_no_backtrace_exception.rb13
-rw-r--r--test/irb/test_ruby-lex.rb108
-rw-r--r--test/irb/test_ruby_lex.rb586
-rw-r--r--test/irb/test_workspace.rb111
-rw-r--r--test/irb/yamatanooroti/test_rendering.rb165
-rw-r--r--test/json/fixtures/fail29.json1
-rw-r--r--test/json/fixtures/fail30.json1
-rw-r--r--test/json/fixtures/fail31.json1
-rw-r--r--test/json/fixtures/fail32.json1
-rw-r--r--test/json/json_addition_test.rb6
-rw-r--r--test/json/json_common_interface_test.rb51
-rw-r--r--test/json/json_fixtures_test.rb10
-rw-r--r--test/json/json_generator_test.rb38
-rw-r--r--test/json/json_parser_test.rb53
-rw-r--r--test/json/ractor_test.rb30
-rw-r--r--test/json/test_helper.rb10
-rw-r--r--test/lib/envutil.rb288
-rw-r--r--test/lib/iseq_loader_checker.rb75
-rw-r--r--test/lib/jit_support.rb93
-rw-r--r--test/lib/leakchecker.rb203
-rw-r--r--test/lib/minitest/benchmark.rb418
-rw-r--r--test/lib/minitest/unit.rb1414
-rw-r--r--test/lib/profile_test_all.rb91
-rw-r--r--test/lib/test/unit.rb1176
-rw-r--r--test/lib/test/unit/assertions.rb941
-rw-r--r--test/lib/test/unit/parallel.rb208
-rw-r--r--test/lib/test/unit/testcase.rb36
-rw-r--r--test/lib/tracepointchecker.rb119
-rw-r--r--test/lib/with_different_ofs.rb4
-rw-r--r--test/lib/zombie_hunter.rb9
-rw-r--r--test/logger/helper.rb13
-rw-r--r--test/logger/test_logdevice.rb38
-rw-r--r--test/logger/test_logger.rb57
-rw-r--r--test/logger/test_logperiod.rb80
-rw-r--r--test/logger/test_severity.rb14
-rw-r--r--test/matrix/test_matrix.rb222
-rw-r--r--test/matrix/test_vector.rb108
-rw-r--r--test/minitest/test_minitest_mock.rb404
-rw-r--r--test/minitest/test_minitest_unit.rb1779
-rw-r--r--test/misc/test_ruby_mode.rb183
-rw-r--r--test/mkmf/base.rb20
-rw-r--r--test/mkmf/test_flags.rb2
-rw-r--r--test/mkmf/test_framework.rb2
-rw-r--r--test/mkmf/test_install.rb30
-rw-r--r--test/mkmf/test_mkmf.rb15
-rw-r--r--test/monitor/test_monitor.rb83
-rw-r--r--test/net/fixtures/Makefile (renamed from test/net/imap/Makefile)0
-rw-r--r--test/net/fixtures/cacert.pem86
-rw-r--r--test/net/fixtures/server.crt110
-rw-r--r--test/net/fixtures/server.key43
-rw-r--r--test/net/ftp/test_buffered_socket.rb6
-rw-r--r--test/net/ftp/test_ftp.rb602
-rw-r--r--test/net/http/test_http.rb147
-rw-r--r--test/net/http/test_http_request.rb13
-rw-r--r--test/net/http/test_httpheader.rb34
-rw-r--r--test/net/http/test_httpresponse.rb34
-rw-r--r--test/net/http/test_https.rb185
-rw-r--r--test/net/http/utils.rb25
-rw-r--r--test/net/imap/test_imap.rb181
-rw-r--r--test/net/imap/test_imap_response_parser.rb51
-rw-r--r--test/net/pop/test_pop.rb29
-rw-r--r--test/net/protocol/test_protocol.rb93
-rw-r--r--test/net/smtp/test_smtp.rb104
-rw-r--r--test/net/smtp/test_ssl_socket.rb4
-rw-r--r--test/net/smtp/test_sslcontext.rb129
-rw-r--r--test/net/smtp/test_starttls.rb122
-rw-r--r--test/objspace/test_objspace.rb203
-rw-r--r--test/open-uri/test_open-uri.rb122
-rw-r--r--test/open-uri/test_ssl.rb353
-rw-r--r--test/openssl/fixtures/pkey/dh-1.pem13
-rw-r--r--test/openssl/fixtures/pkey/rsa-1.pem51
-rw-r--r--test/openssl/fixtures/pkey/rsa-2.pem51
-rw-r--r--test/openssl/fixtures/pkey/rsa-3.pem51
-rw-r--r--test/openssl/test_asn1.rb41
-rw-r--r--test/openssl/test_bn.rb11
-rw-r--r--test/openssl/test_buffering.rb11
-rw-r--r--test/openssl/test_cipher.rb85
-rw-r--r--test/openssl/test_config.rb178
-rw-r--r--test/openssl/test_digest.rb64
-rw-r--r--test/openssl/test_engine.rb4
-rw-r--r--test/openssl/test_fips.rb2
-rw-r--r--test/openssl/test_hmac.rb12
-rw-r--r--test/openssl/test_kdf.rb44
-rw-r--r--test/openssl/test_ns_spki.rb6
-rw-r--r--test/openssl/test_ocsp.rb46
-rw-r--r--test/openssl/test_ossl.rb65
-rw-r--r--test/openssl/test_pair.rb96
-rw-r--r--test/openssl/test_pkcs12.rb2
-rw-r--r--test/openssl/test_pkcs7.rb26
-rw-r--r--test/openssl/test_pkey.rb28
-rw-r--r--test/openssl/test_pkey_dh.rb17
-rw-r--r--test/openssl/test_pkey_dsa.rb15
-rw-r--r--test/openssl/test_pkey_ec.rb105
-rw-r--r--test/openssl/test_pkey_rsa.rb199
-rw-r--r--test/openssl/test_random.rb2
-rw-r--r--test/openssl/test_ssl.rb463
-rw-r--r--test/openssl/test_ssl_session.rb76
-rw-r--r--test/openssl/test_ts.rb680
-rw-r--r--test/openssl/test_x509attr.rb29
-rw-r--r--test/openssl/test_x509cert.rb115
-rw-r--r--test/openssl/test_x509crl.rb97
-rw-r--r--test/openssl/test_x509ext.rb26
-rw-r--r--test/openssl/test_x509name.rb44
-rw-r--r--test/openssl/test_x509req.rb43
-rw-r--r--test/openssl/test_x509store.rb14
-rw-r--r--test/openssl/ut_eof.rb10
-rw-r--r--test/openssl/utils.rb131
-rw-r--r--test/optparse/test_acceptable.rb1
-rw-r--r--test/optparse/test_autoconf.rb9
-rw-r--r--test/optparse/test_did_you_mean.rb52
-rw-r--r--test/optparse/test_kwargs.rb2
-rw-r--r--test/optparse/test_optparse.rb32
-rw-r--r--test/optparse/test_summary.rb11
-rw-r--r--test/optparse/test_zsh_completion.rb2
-rw-r--r--test/ostruct/test_ostruct.rb134
-rw-r--r--test/pathname/test_pathname.rb243
-rw-r--r--test/pathname/test_ractor.rb22
-rw-r--r--test/psych/helper.rb40
-rw-r--r--test/psych/test_alias_and_anchor.rb12
-rw-r--r--test/psych/test_array.rb6
-rw-r--r--test/psych/test_class.rb4
-rw-r--r--test/psych/test_coder.rb135
-rw-r--r--test/psych/test_date_time.rb4
-rw-r--r--test/psych/test_deprecated.rb4
-rw-r--r--test/psych/test_document.rb2
-rw-r--r--test/psych/test_emitter.rb10
-rw-r--r--test/psych/test_encoding.rb16
-rw-r--r--test/psych/test_exception.rb87
-rw-r--r--test/psych/test_hash.rb48
-rw-r--r--test/psych/test_marshalable.rb12
-rw-r--r--test/psych/test_merge_keys.rb34
-rw-r--r--test/psych/test_nil.rb4
-rw-r--r--test/psych/test_object.rb4
-rw-r--r--test/psych/test_object_references.rb12
-rw-r--r--test/psych/test_omap.rb4
-rw-r--r--test/psych/test_parser.rb78
-rw-r--r--test/psych/test_psych.rb239
-rw-r--r--test/psych/test_ractor.rb50
-rw-r--r--test/psych/test_safe_load.rb109
-rw-r--r--test/psych/test_scalar_scanner.rb20
-rw-r--r--test/psych/test_serialize_subclasses.rb4
-rw-r--r--test/psych/test_set.rb6
-rw-r--r--test/psych/test_stream.rb16
-rw-r--r--test/psych/test_string.rb14
-rw-r--r--test/psych/test_struct.rb6
-rw-r--r--test/psych/test_tainted.rb131
-rw-r--r--test/psych/test_tree_builder.rb14
-rw-r--r--test/psych/test_yaml.rb39
-rw-r--r--test/psych/test_yaml_special_cases.rb130
-rw-r--r--test/psych/test_yamlstore.rb47
-rw-r--r--test/psych/visitors/test_to_ruby.rb5
-rw-r--r--test/psych/visitors/test_yaml_tree.rb14
-rw-r--r--test/racc/assets/cadenza.y170
-rw-r--r--test/racc/assets/cast.y926
-rw-r--r--test/racc/assets/chk.y126
-rw-r--r--test/racc/assets/conf.y16
-rw-r--r--test/racc/assets/csspool.y729
-rw-r--r--test/racc/assets/digraph.y29
-rw-r--r--test/racc/assets/echk.y118
-rw-r--r--test/racc/assets/edtf.y583
-rw-r--r--test/racc/assets/err.y60
-rw-r--r--test/racc/assets/error_recovery.y35
-rw-r--r--test/racc/assets/expect.y7
-rw-r--r--test/racc/assets/firstline.y4
-rw-r--r--test/racc/assets/huia.y318
-rw-r--r--test/racc/assets/ichk.y102
-rw-r--r--test/racc/assets/ifelse.y14
-rw-r--r--test/racc/assets/intp.y546
-rw-r--r--test/racc/assets/journey.y47
-rw-r--r--test/racc/assets/liquor.y313
-rw-r--r--test/racc/assets/machete.y423
-rw-r--r--test/racc/assets/macruby.y2197
-rw-r--r--test/racc/assets/mailp.y437
-rw-r--r--test/racc/assets/mediacloth.y599
-rw-r--r--test/racc/assets/mof.y649
-rw-r--r--test/racc/assets/namae.y302
-rw-r--r--test/racc/assets/nasl.y626
-rw-r--r--test/racc/assets/newsyn.y25
-rw-r--r--test/racc/assets/noend.y4
-rw-r--r--test/racc/assets/nokogiri-css.y255
-rw-r--r--test/racc/assets/nonass.y41
-rw-r--r--test/racc/assets/normal.y27
-rw-r--r--test/racc/assets/norule.y4
-rw-r--r--test/racc/assets/nullbug1.y25
-rw-r--r--test/racc/assets/nullbug2.y15
-rw-r--r--test/racc/assets/opal.y1807
-rw-r--r--test/racc/assets/opt.y123
-rw-r--r--test/racc/assets/percent.y35
-rw-r--r--test/racc/assets/php_serialization.y98
-rw-r--r--test/racc/assets/recv.y97
-rw-r--r--test/racc/assets/riml.y665
-rw-r--r--test/racc/assets/rrconf.y14
-rw-r--r--test/racc/assets/ruby18.y1943
-rw-r--r--test/racc/assets/ruby19.y2174
-rw-r--r--test/racc/assets/ruby20.y2350
-rw-r--r--test/racc/assets/ruby21.y2359
-rw-r--r--test/racc/assets/ruby22.y2381
-rw-r--r--test/racc/assets/scan.y72
-rw-r--r--test/racc/assets/syntax.y50
-rw-r--r--test/racc/assets/tp_plus.y622
-rw-r--r--test/racc/assets/twowaysql.y278
-rw-r--r--test/racc/assets/unterm.y5
-rw-r--r--test/racc/assets/useless.y12
-rw-r--r--test/racc/assets/yyerr.y46
-rw-r--r--test/racc/bench.y36
-rw-r--r--test/racc/helper.rb115
-rw-r--r--test/racc/infini.y8
-rw-r--r--test/racc/regress/README.txt7
-rw-r--r--test/racc/regress/cadenza796
-rw-r--r--test/racc/regress/cast3428
-rw-r--r--test/racc/regress/csspool2314
-rw-r--r--test/racc/regress/edtf1794
-rw-r--r--test/racc/regress/huia1392
-rw-r--r--test/racc/regress/journey222
-rw-r--r--test/racc/regress/liquor885
-rw-r--r--test/racc/regress/machete833
-rw-r--r--test/racc/regress/mediacloth1463
-rw-r--r--test/racc/regress/mof1368
-rw-r--r--test/racc/regress/namae634
-rw-r--r--test/racc/regress/nasl2058
-rw-r--r--test/racc/regress/nokogiri-css836
-rw-r--r--test/racc/regress/opal6431
-rw-r--r--test/racc/regress/php_serialization336
-rw-r--r--test/racc/regress/riml3283
-rw-r--r--test/racc/regress/ruby186344
-rw-r--r--test/racc/regress/ruby227460
-rw-r--r--test/racc/regress/tp_plus1933
-rw-r--r--test/racc/regress/twowaysql556
-rw-r--r--test/racc/scandata/brace7
-rw-r--r--test/racc/scandata/gvar1
-rw-r--r--test/racc/scandata/normal4
-rw-r--r--test/racc/scandata/percent18
-rw-r--r--test/racc/scandata/slash10
-rw-r--r--test/racc/src.intp34
-rw-r--r--test/racc/start.y20
-rw-r--r--test/racc/test_chk_y.rb52
-rw-r--r--test/racc/test_grammar_file_parser.rb15
-rw-r--r--test/racc/test_racc_command.rb339
-rw-r--r--test/racc/test_scan_y.rb52
-rw-r--r--test/racc/testscanner.rb51
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Basics.text4
-rw-r--r--test/rdoc/helper.rb5
-rw-r--r--test/rdoc/support/formatter_test_case.rb764
-rw-r--r--test/rdoc/support/test_case.rb228
-rw-r--r--test/rdoc/support/text_formatter_test_case.rb115
-rw-r--r--test/rdoc/test_rdoc_alias.rb2
-rw-r--r--test/rdoc/test_rdoc_any_method.rb57
-rw-r--r--test/rdoc/test_rdoc_attr.rb7
-rw-r--r--test/rdoc/test_rdoc_class_module.rb57
-rw-r--r--test/rdoc/test_rdoc_code_object.rb8
-rw-r--r--test/rdoc/test_rdoc_comment.rb17
-rw-r--r--test/rdoc/test_rdoc_constant.rb4
-rw-r--r--test/rdoc/test_rdoc_context.rb38
-rw-r--r--test/rdoc/test_rdoc_context_section.rb14
-rw-r--r--test/rdoc/test_rdoc_cross_reference.rb34
-rw-r--r--test/rdoc/test_rdoc_encoding.rb110
-rw-r--r--test/rdoc/test_rdoc_extend.rb2
-rw-r--r--test/rdoc/test_rdoc_generator_darkfish.rb9
-rw-r--r--test/rdoc/test_rdoc_generator_json_index.rb39
-rw-r--r--test/rdoc/test_rdoc_generator_markup.rb4
-rw-r--r--test/rdoc/test_rdoc_generator_pot.rb4
-rw-r--r--test/rdoc/test_rdoc_generator_pot_po.rb4
-rw-r--r--test/rdoc/test_rdoc_generator_pot_po_entry.rb4
-rw-r--r--test/rdoc/test_rdoc_generator_ri.rb4
-rw-r--r--test/rdoc/test_rdoc_i18n_locale.rb12
-rw-r--r--test/rdoc/test_rdoc_i18n_text.rb4
-rw-r--r--test/rdoc/test_rdoc_include.rb2
-rw-r--r--test/rdoc/test_rdoc_markdown.rb96
-rw-r--r--test/rdoc/test_rdoc_markdown_test.rb8
-rw-r--r--test/rdoc/test_rdoc_markup.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_attribute_manager.rb77
-rw-r--r--test/rdoc/test_rdoc_markup_attributes.rb12
-rw-r--r--test/rdoc/test_rdoc_markup_document.rb6
-rw-r--r--test/rdoc/test_rdoc_markup_formatter.rb61
-rw-r--r--test/rdoc/test_rdoc_markup_hard_break.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_heading.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_include.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_indented_paragraph.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_paragraph.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_parser.rb64
-rw-r--r--test/rdoc/test_rdoc_markup_pre_process.rb21
-rw-r--r--test/rdoc/test_rdoc_markup_raw.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_to_ansi.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_to_bs.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_to_html.rb63
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_crossref.rb121
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_snippet.rb18
-rw-r--r--test/rdoc/test_rdoc_markup_to_joined_paragraph.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_to_label.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_to_markdown.rb8
-rw-r--r--test/rdoc/test_rdoc_markup_to_rdoc.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_to_table_of_contents.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_to_tt_only.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_verbatim.rb4
-rw-r--r--test/rdoc/test_rdoc_method_attr.rb2
-rw-r--r--test/rdoc/test_rdoc_normal_class.rb2
-rw-r--r--test/rdoc/test_rdoc_normal_module.rb2
-rw-r--r--test/rdoc/test_rdoc_options.rb115
-rw-r--r--test/rdoc/test_rdoc_parser.rb26
-rw-r--r--test/rdoc/test_rdoc_parser_c.rb87
-rw-r--r--test/rdoc/test_rdoc_parser_changelog.rb177
-rw-r--r--test/rdoc/test_rdoc_parser_markdown.rb4
-rw-r--r--test/rdoc/test_rdoc_parser_rd.rb4
-rw-r--r--test/rdoc/test_rdoc_parser_ruby.rb708
-rw-r--r--test/rdoc/test_rdoc_parser_simple.rb4
-rw-r--r--test/rdoc/test_rdoc_rd.rb4
-rw-r--r--test/rdoc/test_rdoc_rd_block_parser.rb4
-rw-r--r--test/rdoc/test_rdoc_rd_inline.rb4
-rw-r--r--test/rdoc/test_rdoc_rd_inline_parser.rb4
-rw-r--r--test/rdoc/test_rdoc_rdoc.rb214
-rw-r--r--test/rdoc/test_rdoc_require.rb8
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb197
-rw-r--r--test/rdoc/test_rdoc_ri_paths.rb18
-rw-r--r--test/rdoc/test_rdoc_rubygems_hook.rb101
-rw-r--r--test/rdoc/test_rdoc_servlet.rb43
-rw-r--r--test/rdoc/test_rdoc_single_class.rb4
-rw-r--r--test/rdoc/test_rdoc_stats.rb4
-rw-r--r--test/rdoc/test_rdoc_store.rb62
-rw-r--r--test/rdoc/test_rdoc_task.rb14
-rw-r--r--test/rdoc/test_rdoc_text.rb57
-rw-r--r--test/rdoc/test_rdoc_token_stream.rb19
-rw-r--r--test/rdoc/test_rdoc_tom_doc.rb68
-rw-r--r--test/rdoc/test_rdoc_top_level.rb7
-rw-r--r--test/rdoc/xref_data.rb23
-rw-r--r--test/rdoc/xref_test_case.rb26
-rw-r--r--test/readline/helper.rb24
-rw-r--r--test/readline/test_readline.rb538
-rw-r--r--test/readline/test_readline_history.rb192
-rw-r--r--test/reline/helper.rb113
-rw-r--r--test/reline/test_config.rb325
-rw-r--r--test/reline/test_history.rb301
-rw-r--r--test/reline/test_key_actor_emacs.rb2315
-rw-r--r--test/reline/test_key_actor_vi.rb1455
-rw-r--r--test/reline/test_key_stroke.rb49
-rw-r--r--test/reline/test_kill_ring.rb268
-rw-r--r--test/reline/test_macro.rb39
-rw-r--r--test/reline/test_reline.rb319
-rw-r--r--test/reline/test_string_processing.rb77
-rw-r--r--test/reline/test_unicode.rb16
-rw-r--r--test/reline/test_within_pipe.rb75
-rwxr-xr-xtest/reline/yamatanooroti/multiline_repl74
-rw-r--r--test/reline/yamatanooroti/termination_checker.rb30
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb742
-rw-r--r--test/resolv/test_addr.rb33
-rw-r--r--test/resolv/test_dns.rb205
-rw-r--r--test/resolv/test_mdns.rb27
-rw-r--r--test/rexml/data/LostineRiver.kml.gzbin50154 -> 0 bytes-rw-r--r--test/rexml/data/ProductionSupport.xml29
-rw-r--r--test/rexml/data/axis.xml25
-rw-r--r--test/rexml/data/bad.xml5
-rw-r--r--test/rexml/data/basic.xml11
-rw-r--r--test/rexml/data/basicupdate.xml47
-rw-r--r--test/rexml/data/broken.rss20
-rw-r--r--test/rexml/data/contents.xml70
-rw-r--r--test/rexml/data/dash.xml12
-rw-r--r--test/rexml/data/defaultNamespace.xml6
-rw-r--r--test/rexml/data/doctype_test.xml34
-rw-r--r--test/rexml/data/documentation.xml542
-rw-r--r--test/rexml/data/euc.xml296
-rw-r--r--test/rexml/data/evaluate.xml28
-rw-r--r--test/rexml/data/fibo.xml29
-rw-r--r--test/rexml/data/foo.xml10
-rw-r--r--test/rexml/data/google.2.xml156
-rw-r--r--test/rexml/data/id.xml21
-rw-r--r--test/rexml/data/iso8859-1.xml4
-rw-r--r--test/rexml/data/jaxen24.xml2
-rw-r--r--test/rexml/data/jaxen3.xml15
-rw-r--r--test/rexml/data/lang.xml11
-rw-r--r--test/rexml/data/lang0.xml18
-rw-r--r--test/rexml/data/message.xml27
-rw-r--r--test/rexml/data/moreover.xml244
-rw-r--r--test/rexml/data/much_ado.xml6850
-rw-r--r--test/rexml/data/namespaces.xml18
-rw-r--r--test/rexml/data/nitf.xml67
-rw-r--r--test/rexml/data/numbers.xml18
-rw-r--r--test/rexml/data/ofbiz-issues-full-177.xml13971
-rw-r--r--test/rexml/data/pi.xml13
-rw-r--r--test/rexml/data/pi2.xml6
-rw-r--r--test/rexml/data/project.xml1
-rw-r--r--test/rexml/data/simple.xml2
-rw-r--r--test/rexml/data/stream_accents.xml4
-rw-r--r--test/rexml/data/t63-1.xmlbin161690 -> 0 bytes-rw-r--r--test/rexml/data/t63-2.svg2828
-rw-r--r--test/rexml/data/t75.xml31
-rw-r--r--test/rexml/data/test/tests.xml683
-rw-r--r--test/rexml/data/test/tests.xsl369
-rw-r--r--test/rexml/data/testNamespaces.xml22
-rw-r--r--test/rexml/data/testsrc.xml64
-rw-r--r--test/rexml/data/text.xml10
-rw-r--r--test/rexml/data/ticket_61.xml4
-rw-r--r--test/rexml/data/ticket_68.xml590
-rw-r--r--test/rexml/data/tutorial.xml678
-rw-r--r--test/rexml/data/underscore.xml6
-rw-r--r--test/rexml/data/utf16.xmlbin207464 -> 0 bytes-rw-r--r--test/rexml/data/web.xml42
-rw-r--r--test/rexml/data/web2.xml7
-rw-r--r--test/rexml/data/working.rss202
-rw-r--r--test/rexml/data/xmlfile-bug.xml15
-rw-r--r--test/rexml/data/xp.tst27
-rw-r--r--test/rexml/data/yahoo.xml80
-rw-r--r--test/rexml/listener.rb51
-rw-r--r--test/rexml/parse/test_document_type_declaration.rb50
-rw-r--r--test/rexml/parse/test_notation_declaration.rb100
-rw-r--r--test/rexml/parser/test_sax2.rb203
-rw-r--r--test/rexml/parser/test_stream.rb32
-rw-r--r--test/rexml/parser/test_tree.rb43
-rw-r--r--test/rexml/parser/test_ultra_light.rb70
-rw-r--r--test/rexml/rexml_test_utils.rb7
-rw-r--r--test/rexml/test_attributes.rb223
-rw-r--r--test/rexml/test_attributes_mixin.rb32
-rw-r--r--test/rexml/test_changing_encoding.rb45
-rw-r--r--test/rexml/test_comment.rb26
-rw-r--r--test/rexml/test_contrib.rb585
-rw-r--r--test/rexml/test_core.rb1468
-rw-r--r--test/rexml/test_doctype.rb107
-rw-r--r--test/rexml/test_document.rb416
-rw-r--r--test/rexml/test_element.rb18
-rw-r--r--test/rexml/test_elements.rb119
-rw-r--r--test/rexml/test_encoding.rb108
-rw-r--r--test/rexml/test_entity.rb206
-rw-r--r--test/rexml/test_functions.rb238
-rw-r--r--test/rexml/test_functions_number.rb35
-rw-r--r--test/rexml/test_jaxen.rb130
-rw-r--r--test/rexml/test_light.rb107
-rw-r--r--test/rexml/test_lightparser.rb16
-rw-r--r--test/rexml/test_listener.rb131
-rw-r--r--test/rexml/test_martin_fowler.rb40
-rw-r--r--test/rexml/test_namespace.rb41
-rw-r--r--test/rexml/test_order.rb110
-rw-r--r--test/rexml/test_preceding_sibling.rb41
-rw-r--r--test/rexml/test_pullparser.rb103
-rw-r--r--test/rexml/test_rexml_issuezilla.rb19
-rw-r--r--test/rexml/test_sax.rb287
-rw-r--r--test/rexml/test_stream.rb130
-rw-r--r--test/rexml/test_text.rb22
-rw-r--r--test/rexml/test_ticket_80.rb59
-rw-r--r--test/rexml/test_validation_rng.rb793
-rw-r--r--test/rexml/test_xml_declaration.rb36
-rw-r--r--test/rexml/xpath/test_attribute.rb30
-rw-r--r--test/rexml/xpath/test_axis_preceding_sibling.rb40
-rw-r--r--test/rexml/xpath/test_base.rb1090
-rw-r--r--test/rexml/xpath/test_node.rb43
-rw-r--r--test/rexml/xpath/test_predicate.rb83
-rw-r--r--test/rexml/xpath/test_text.rb77
-rw-r--r--test/rinda/test_rinda.rb117
-rw-r--r--test/ripper/assert_parse_files.rb32
-rw-r--r--test/ripper/dummyparser.rb32
-rw-r--r--test/ripper/test_files.rb50
-rw-r--r--test/ripper/test_files_ext.rb8
-rw-r--r--test/ripper/test_files_lib.rb14
-rw-r--r--test/ripper/test_files_sample.rb8
-rw-r--r--test/ripper/test_files_test.rb8
-rw-r--r--test/ripper/test_files_test_1.rb9
-rw-r--r--test/ripper/test_files_test_2.rb9
-rw-r--r--test/ripper/test_lexer.rb178
-rw-r--r--test/ripper/test_parser_events.rb199
-rw-r--r--test/ripper/test_ripper.rb10
-rw-r--r--test/ripper/test_scanner_events.rb111
-rw-r--r--test/ripper/test_sexp.rb380
-rw-r--r--test/rss/dot.pngbin111 -> 0 bytes-rw-r--r--test/rss/rss-assertions.rb2091
-rw-r--r--test/rss/rss-testcase.rb479
-rw-r--r--test/rss/test_1.0.rb308
-rw-r--r--test/rss/test_2.0.rb412
-rw-r--r--test/rss/test_accessor.rb104
-rw-r--r--test/rss/test_atom.rb684
-rw-r--r--test/rss/test_content.rb105
-rw-r--r--test/rss/test_dublincore.rb270
-rw-r--r--test/rss/test_image.rb215
-rw-r--r--test/rss/test_inherit.rb41
-rw-r--r--test/rss/test_itunes.rb348
-rw-r--r--test/rss/test_maker_0.9.rb477
-rw-r--r--test/rss/test_maker_1.0.rb519
-rw-r--r--test/rss/test_maker_2.0.rb758
-rw-r--r--test/rss/test_maker_atom_entry.rb394
-rw-r--r--test/rss/test_maker_atom_feed.rb455
-rw-r--r--test/rss/test_maker_content.rb48
-rw-r--r--test/rss/test_maker_dc.rb150
-rw-r--r--test/rss/test_maker_image.rb63
-rw-r--r--test/rss/test_maker_itunes.rb470
-rw-r--r--test/rss/test_maker_slash.rb38
-rw-r--r--test/rss/test_maker_sy.rb45
-rw-r--r--test/rss/test_maker_taxo.rb82
-rw-r--r--test/rss/test_maker_trackback.rb42
-rw-r--r--test/rss/test_maker_xml-stylesheet.rb84
-rw-r--r--test/rss/test_parser.rb65
-rw-r--r--test/rss/test_parser_1.0.rb529
-rw-r--r--test/rss/test_parser_2.0.rb123
-rw-r--r--test/rss/test_parser_atom_entry.rb164
-rw-r--r--test/rss/test_parser_atom_feed.rb277
-rw-r--r--test/rss/test_setup_maker_0.9.rb247
-rw-r--r--test/rss/test_setup_maker_1.0.rb551
-rw-r--r--test/rss/test_setup_maker_2.0.rb309
-rw-r--r--test/rss/test_setup_maker_atom_entry.rb410
-rw-r--r--test/rss/test_setup_maker_atom_feed.rb446
-rw-r--r--test/rss/test_setup_maker_itunes.rb144
-rw-r--r--test/rss/test_setup_maker_slash.rb39
-rw-r--r--test/rss/test_slash.rb65
-rw-r--r--test/rss/test_syndication.rb126
-rw-r--r--test/rss/test_taxonomy.rb173
-rw-r--r--test/rss/test_to_s.rb701
-rw-r--r--test/rss/test_trackback.rb136
-rw-r--r--test/rss/test_version.rb10
-rw-r--r--test/rss/test_xml-stylesheet.rb109
-rw-r--r--test/ruby/bug-13526.rb8
-rw-r--r--test/ruby/enc/test_case_comprehensive.rb9
-rw-r--r--test/ruby/enc/test_case_mapping.rb33
-rw-r--r--test/ruby/enc/test_cesu8.rb109
-rw-r--r--test/ruby/enc/test_emoji_breaks.rb122
-rw-r--r--test/ruby/enc/test_grapheme_breaks.rb95
-rw-r--r--test/ruby/enc/test_regex_casefold.rb6
-rw-r--r--test/ruby/marshaltestlib.rb4
-rw-r--r--test/ruby/sentence.rb2
-rw-r--r--test/ruby/test_alias.rb57
-rw-r--r--test/ruby/test_argf.rb138
-rw-r--r--test/ruby/test_arithmetic_sequence.rb491
-rw-r--r--test/ruby/test_array.rb831
-rw-r--r--test/ruby/test_assignment.rb40
-rw-r--r--test/ruby/test_ast.rb348
-rw-r--r--test/ruby/test_autoload.rb216
-rw-r--r--test/ruby/test_backtrace.rb102
-rw-r--r--test/ruby/test_basicinstructions.rb6
-rw-r--r--test/ruby/test_beginendblock.rb22
-rw-r--r--test/ruby/test_bignum.rb66
-rw-r--r--test/ruby/test_call.rb9
-rw-r--r--test/ruby/test_class.rb166
-rw-r--r--test/ruby/test_clone.rb35
-rw-r--r--test/ruby/test_comparable.rb32
-rw-r--r--test/ruby/test_complex.rb215
-rw-r--r--test/ruby/test_complexrational.rb8
-rw-r--r--test/ruby/test_const.rb39
-rw-r--r--test/ruby/test_continuation.rb26
-rw-r--r--test/ruby/test_default_gems.rb16
-rw-r--r--test/ruby/test_defined.rb116
-rw-r--r--test/ruby/test_dir.rb267
-rw-r--r--test/ruby/test_dir_m17n.rb75
-rw-r--r--test/ruby/test_econv.rb27
-rw-r--r--test/ruby/test_encoding.rb48
-rw-r--r--test/ruby/test_enum.rb300
-rw-r--r--test/ruby/test_enumerator.rb259
-rw-r--r--test/ruby/test_env.rb118
-rw-r--r--test/ruby/test_eval.rb70
-rw-r--r--test/ruby/test_exception.rb552
-rw-r--r--test/ruby/test_fiber.rb273
-rw-r--r--test/ruby/test_file.rb89
-rw-r--r--test/ruby/test_file_exhaustive.rb202
-rw-r--r--test/ruby/test_fixnum.rb1
-rw-r--r--test/ruby/test_flip.rb3
-rw-r--r--test/ruby/test_float.rb84
-rw-r--r--test/ruby/test_fnmatch.rb37
-rw-r--r--test/ruby/test_frozen_error.rb57
-rw-r--r--test/ruby/test_gc.rb85
-rw-r--r--test/ruby/test_gc_compact.rb155
-rw-r--r--test/ruby/test_hash.rb486
-rw-r--r--test/ruby/test_ifunless.rb2
-rw-r--r--test/ruby/test_inlinecache.rb110
-rw-r--r--test/ruby/test_integer.rb135
-rw-r--r--test/ruby/test_integer_comb.rb24
-rw-r--r--test/ruby/test_io.rb729
-rw-r--r--test/ruby/test_io_m17n.rb103
-rw-r--r--test/ruby/test_iseq.rb358
-rw-r--r--test/ruby/test_iterator.rb30
-rw-r--r--test/ruby/test_jit.rb1224
-rw-r--r--test/ruby/test_jit_debug.rb17
-rw-r--r--test/ruby/test_key_error.rb42
-rw-r--r--test/ruby/test_keyword.rb3683
-rw-r--r--test/ruby/test_lambda.rb68
-rw-r--r--test/ruby/test_lazy_enumerator.rb132
-rw-r--r--test/ruby/test_literal.rb63
-rw-r--r--test/ruby/test_m17n.rb64
-rw-r--r--test/ruby/test_m17n_comb.rb27
-rw-r--r--test/ruby/test_marshal.rb248
-rw-r--r--test/ruby/test_math.rb1
-rw-r--r--test/ruby/test_memory_view.rb341
-rw-r--r--test/ruby/test_method.rb478
-rw-r--r--test/ruby/test_method_cache.rb65
-rw-r--r--test/ruby/test_mixed_unicode_escapes.rb8
-rw-r--r--test/ruby/test_module.rb993
-rw-r--r--test/ruby/test_name_error.rb156
-rw-r--r--test/ruby/test_nomethod_error.rb109
-rw-r--r--test/ruby/test_not.rb2
-rw-r--r--test/ruby/test_notimp.rb85
-rw-r--r--test/ruby/test_numeric.rb119
-rw-r--r--test/ruby/test_object.rb150
-rw-r--r--test/ruby/test_objectspace.rb30
-rw-r--r--test/ruby/test_optimization.rb294
-rw-r--r--test/ruby/test_pack.rb16
-rw-r--r--test/ruby/test_parse.rb686
-rw-r--r--test/ruby/test_path.rb8
-rw-r--r--test/ruby/test_pattern_matching.rb1505
-rw-r--r--test/ruby/test_pipe.rb19
-rw-r--r--test/ruby/test_primitive.rb78
-rw-r--r--test/ruby/test_proc.rb432
-rw-r--r--test/ruby/test_process.rb298
-rw-r--r--test/ruby/test_rand.rb360
-rw-r--r--test/ruby/test_range.rb355
-rw-r--r--test/ruby/test_rational.rb114
-rw-r--r--test/ruby/test_refinement.rb565
-rw-r--r--test/ruby/test_regexp.rb221
-rw-r--r--test/ruby/test_require.rb202
-rw-r--r--test/ruby/test_require_lib.rb28
-rw-r--r--test/ruby/test_rubyoptions.rb353
-rw-r--r--test/ruby/test_rubyvm.rb4
-rw-r--r--test/ruby/test_rubyvm_mjit.rb91
-rw-r--r--test/ruby/test_settracefunc.rb717
-rw-r--r--test/ruby/test_signal.rb107
-rw-r--r--test/ruby/test_sprintf.rb11
-rw-r--r--test/ruby/test_stack.rb82
-rw-r--r--test/ruby/test_string.rb565
-rw-r--r--test/ruby/test_struct.rb98
-rw-r--r--test/ruby/test_super.rb151
-rw-r--r--test/ruby/test_symbol.rb106
-rw-r--r--test/ruby/test_syntax.rb806
-rw-r--r--test/ruby/test_system.rb41
-rw-r--r--test/ruby/test_thread.rb385
-rw-r--r--test/ruby/test_thread_cv.rb245
-rw-r--r--test/ruby/test_thread_queue.rb631
-rw-r--r--test/ruby/test_time.rb164
-rw-r--r--test/ruby/test_time_tz.rb433
-rw-r--r--test/ruby/test_trace.rb11
-rw-r--r--test/ruby/test_transcode.rb90
-rw-r--r--test/ruby/test_undef.rb2
-rw-r--r--test/ruby/test_variable.rb92
-rw-r--r--test/ruby/test_vm_dump.rb4
-rw-r--r--test/ruby/test_weakmap.rb64
-rw-r--r--test/rubygems/ca_cert.pem139
-rw-r--r--test/rubygems/client.pem148
-rw-r--r--test/rubygems/data/null-required-ruby-version.gemspec.rzbin0 -> 403 bytes-rw-r--r--test/rubygems/data/null-required-rubygems-version.gemspec.rzbin0 -> 421 bytes-rw-r--r--test/rubygems/data/null-type.gemspec.rzbin554 -> 504 bytes-rw-r--r--test/rubygems/encrypted_private_key.pem52
-rw-r--r--test/rubygems/fix_openssl_warnings.rb13
-rw-r--r--test/rubygems/helper.rb1595
-rw-r--r--test/rubygems/installer_test_case.rb247
-rw-r--r--test/rubygems/package/tar_test_case.rb139
-rw-r--r--test/rubygems/packages/ascii_binder-0.1.10.1.gembin0 -> 244736 bytes-rw-r--r--test/rubygems/packages/ill-formatted-platform-1.0.0.10.gembin0 -> 10240 bytes-rw-r--r--test/rubygems/private_ec_key.pem9
-rw-r--r--test/rubygems/rubygems/commands/crash_command.rb2
-rw-r--r--test/rubygems/rubygems_plugin.rb3
-rw-r--r--test/rubygems/simple_gem.rb2
-rw-r--r--test/rubygems/specifications/bar-0.0.2.gemspec2
-rw-r--r--test/rubygems/specifications/rubyforge-0.0.1.gemspec12
-rw-r--r--test/rubygems/ssl_cert.pem95
-rw-r--r--test/rubygems/ssl_key.pem38
-rw-r--r--test/rubygems/test_bundled_ca.rb89
-rw-r--r--test/rubygems/test_config.rb13
-rw-r--r--test/rubygems/test_deprecate.rb98
-rw-r--r--test/rubygems/test_gem.rb1314
-rw-r--r--test/rubygems/test_gem_available_set.rb13
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb45
-rw-r--r--test/rubygems/test_gem_command.rb176
-rw-r--r--test/rubygems/test_gem_command_manager.rb86
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb624
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb240
-rw-r--r--test/rubygems/test_gem_commands_check_command.rb16
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb148
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb78
-rw-r--r--test/rubygems/test_gem_commands_dependency_command.rb77
-rw-r--r--test/rubygems/test_gem_commands_environment_command.rb57
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb59
-rw-r--r--test/rubygems/test_gem_commands_generate_index_command.rb35
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb34
-rw-r--r--test/rubygems/test_gem_commands_info_command.rb43
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb616
-rw-r--r--test/rubygems/test_gem_commands_list_command.rb6
-rw-r--r--test/rubygems/test_gem_commands_lock_command.rb7
-rw-r--r--test/rubygems/test_gem_commands_mirror.rb5
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb50
-rw-r--r--test/rubygems/test_gem_commands_outdated_command.rb22
-rw-r--r--test/rubygems/test_gem_commands_owner_command.rb236
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb271
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb204
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb253
-rw-r--r--test/rubygems/test_gem_commands_search_command.rb5
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb17
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb428
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb79
-rw-r--r--test/rubygems/test_gem_commands_signout_command.rb9
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb211
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb85
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb9
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb325
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb26
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb294
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb17
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb96
-rw-r--r--test/rubygems/test_gem_config_file.rb64
-rw-r--r--test/rubygems/test_gem_dependency.rb29
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb444
-rw-r--r--test/rubygems/test_gem_dependency_list.rb68
-rw-r--r--test/rubygems/test_gem_dependency_resolution_error.rb7
-rw-r--r--test/rubygems/test_gem_doctor.rb95
-rw-r--r--test/rubygems/test_gem_ext_builder.rb165
-rw-r--r--test/rubygems/test_gem_ext_cmake_builder.rb46
-rw-r--r--test/rubygems/test_gem_ext_configure_builder.rb32
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb88
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb76
-rw-r--r--test/rubygems/test_gem_gem_runner.rb84
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb103
-rw-r--r--test/rubygems/test_gem_impossible_dependencies_error.rb5
-rw-r--r--test/rubygems/test_gem_indexer.rb110
-rw-r--r--test/rubygems/test_gem_install_update_options.rb101
-rw-r--r--test/rubygems/test_gem_installer.rb1548
-rw-r--r--test/rubygems/test_gem_local_remote_options.rb10
-rw-r--r--test/rubygems/test_gem_name_tuple.rb5
-rw-r--r--test/rubygems/test_gem_package.rb492
-rw-r--r--test/rubygems/test_gem_package_old.rb114
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb92
-rw-r--r--test/rubygems/test_gem_package_tar_reader.rb5
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb28
-rw-r--r--test/rubygems/test_gem_package_tar_writer.rb114
-rw-r--r--test/rubygems/test_gem_package_task.rb63
-rw-r--r--test/rubygems/test_gem_path_support.rb63
-rw-r--r--test/rubygems/test_gem_platform.rb93
-rw-r--r--test/rubygems/test_gem_rdoc.rb156
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb827
-rw-r--r--test/rubygems/test_gem_request.rb128
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb42
-rw-r--r--test/rubygems/test_gem_request_set.rb186
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb190
-rw-r--r--test/rubygems/test_gem_request_set_lockfile.rb28
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb40
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_tokenizer.rb250
-rw-r--r--test/rubygems/test_gem_requirement.rb148
-rw-r--r--test/rubygems/test_gem_resolver.rb160
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb40
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb122
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb31
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb38
-rw-r--r--test/rubygems/test_gem_resolver_composed_set.rb5
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb11
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb5
-rw-r--r--test/rubygems/test_gem_resolver_git_set.rb7
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb11
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb9
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb16
-rw-r--r--test/rubygems/test_gem_resolver_installed_specification.rb6
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb55
-rw-r--r--test/rubygems/test_gem_resolver_local_specification.rb7
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb11
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb5
-rw-r--r--test/rubygems/test_gem_resolver_requirement_list.rb5
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb9
-rw-r--r--test/rubygems/test_gem_resolver_vendor_set.rb11
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb5
-rw-r--r--test/rubygems/test_gem_security.rb102
-rw-r--r--test/rubygems/test_gem_security_policy.rb90
-rw-r--r--test/rubygems/test_gem_security_signer.rb40
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb21
-rw-r--r--test/rubygems/test_gem_server.rb218
-rw-r--r--test/rubygems/test_gem_silent_ui.rb21
-rw-r--r--test/rubygems/test_gem_source.rb74
-rw-r--r--test/rubygems/test_gem_source_fetch_problem.rb16
-rw-r--r--test/rubygems/test_gem_source_git.rb62
-rw-r--r--test/rubygems/test_gem_source_installed.rb27
-rw-r--r--test/rubygems/test_gem_source_list.rb4
-rw-r--r--test/rubygems/test_gem_source_local.rb19
-rw-r--r--test/rubygems/test_gem_source_lock.rb39
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb23
-rw-r--r--test/rubygems/test_gem_source_subpath_problem.rb49
-rw-r--r--test/rubygems/test_gem_source_vendor.rb19
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb20
-rw-r--r--test/rubygems/test_gem_specification.rb1561
-rw-r--r--test/rubygems/test_gem_stream_ui.rb57
-rw-r--r--test/rubygems/test_gem_stub_specification.rb45
-rw-r--r--test/rubygems/test_gem_text.rb10
-rw-r--r--test/rubygems/test_gem_uninstaller.rb269
-rw-r--r--test/rubygems/test_gem_unsatisfiable_dependency_error.rb5
-rw-r--r--test/rubygems/test_gem_uri.rb39
-rw-r--r--test/rubygems/test_gem_uri_formatter.rb5
-rw-r--r--test/rubygems/test_gem_util.rb71
-rw-r--r--test/rubygems/test_gem_validator.rb12
-rw-r--r--test/rubygems/test_gem_version.rb88
-rw-r--r--test/rubygems/test_gem_version_option.rb7
-rw-r--r--test/rubygems/test_kernel.rb46
-rw-r--r--test/rubygems/test_project_sanity.rb20
-rw-r--r--test/rubygems/test_remote_fetch_error.rb6
-rw-r--r--test/rubygems/test_require.rb581
-rw-r--r--test/rubygems/test_rubygems.rb44
-rw-r--r--test/rubygems/utilities.rb371
-rw-r--r--test/runner.rb37
-rw-r--r--test/scanf/data.txt6
-rw-r--r--test/scanf/test_scanf.rb304
-rw-r--r--test/scanf/test_scanfblocks.rb82
-rw-r--r--test/scanf/test_scanfio.rb21
-rw-r--r--test/sdbm/test_sdbm.rb542
-rw-r--r--test/shell/test_command_processor.rb82
-rw-r--r--test/socket/test_addrinfo.rb17
-rw-r--r--test/socket/test_basicsocket.rb24
-rw-r--r--test/socket/test_nonblock.rb4
-rw-r--r--test/socket/test_socket.rb74
-rw-r--r--test/socket/test_tcp.rb45
-rw-r--r--test/socket/test_udp.rb10
-rw-r--r--test/socket/test_unix.rb30
-rw-r--r--test/stringio/test_ractor.rb23
-rw-r--r--test/stringio/test_stringio.rb173
-rw-r--r--test/strscan/test_ractor.rb28
-rw-r--r--test/strscan/test_stringscanner.rb334
-rw-r--r--test/syslog/test_syslog_logger.rb15
-rw-r--r--test/test_cmath.rb76
-rw-r--r--test/test_delegate.rb145
-rw-r--r--test/test_extlibs.rb2
-rw-r--r--test/test_find.rb4
-rw-r--r--test/test_forwardable.rb67
-rw-r--r--test/test_ipaddr.rb120
-rw-r--r--test/test_mutex_m.rb32
-rw-r--r--test/test_open3.rb65
-rw-r--r--test/test_pp.rb28
-rw-r--r--test/test_prime.rb103
-rw-r--r--test/test_pstore.rb2
-rw-r--r--test/test_pty.rb7
-rw-r--r--test/test_rbconfig.rb9
-rw-r--r--test/test_securerandom.rb22
-rw-r--r--test/test_set.rb144
-rw-r--r--test/test_shellwords.rb5
-rw-r--r--test/test_sorted_set.rb45
-rw-r--r--test/test_syslog.rb9
-rw-r--r--test/test_tempfile.rb56
-rw-r--r--test/test_time.rb81
-rw-r--r--test/test_tmpdir.rb85
-rw-r--r--test/test_tracer.rb178
-rw-r--r--test/test_unicode_normalize.rb20
-rw-r--r--test/test_win32api.rb24
-rw-r--r--test/testunit/test4test_hideskip.rb10
-rw-r--r--test/testunit/test4test_redefinition.rb14
-rw-r--r--test/testunit/test4test_sorting.rb18
-rw-r--r--test/testunit/test_assertion.rb17
-rw-r--r--test/testunit/test_hideskip.rb17
-rw-r--r--test/testunit/test_parallel.rb196
-rw-r--r--test/testunit/tests_for_parallel/runner.rb14
-rw-r--r--test/thread/test_cv.rb222
-rw-r--r--test/thread/test_queue.rb565
-rw-r--r--test/thread/test_sync.rb64
-rw-r--r--test/uri/test_common.rb14
-rw-r--r--test/uri/test_file.rb67
-rw-r--r--test/uri/test_generic.rb88
-rw-r--r--test/uri/test_ldap.rb4
-rw-r--r--test/uri/test_parser.rb42
-rw-r--r--test/uri/test_ws.rb71
-rw-r--r--test/webrick/test_cgi.rb170
-rw-r--r--test/webrick/test_filehandler.rb324
-rw-r--r--test/webrick/test_httpauth.rb240
-rw-r--r--test/webrick/test_httpproxy.rb328
-rw-r--r--test/webrick/test_httprequest.rb417
-rw-r--r--test/webrick/test_httpresponse.rb160
-rw-r--r--test/webrick/test_httpserver.rb418
-rw-r--r--test/webrick/test_server.rb162
-rw-r--r--test/webrick/test_ssl_server.rb40
-rw-r--r--test/webrick/test_utils.rb110
-rw-r--r--test/webrick/utils.rb74
-rw-r--r--test/win32ole/available_ole.rb41
-rw-r--r--test/win32ole/test_ole_methods.rb2
-rw-r--r--test/win32ole/test_thread.rb2
-rw-r--r--test/win32ole/test_win32ole.rb56
-rw-r--r--test/win32ole/test_win32ole_event.rb87
-rw-r--r--test/win32ole/test_win32ole_method.rb13
-rw-r--r--test/win32ole/test_win32ole_method_event.rb36
-rw-r--r--test/win32ole/test_win32ole_param.rb53
-rw-r--r--test/win32ole/test_win32ole_param_event.rb30
-rw-r--r--test/win32ole/test_win32ole_record.rb18
-rw-r--r--test/win32ole/test_win32ole_type.rb52
-rw-r--r--test/win32ole/test_win32ole_type_event.rb44
-rw-r--r--test/zlib/test_zlib.rb248
-rw-r--r--thread.c2977
-rw-r--r--thread_pthread.c2044
-rw-r--r--thread_pthread.h97
-rw-r--r--thread_sync.c682
-rw-r--r--thread_win32.c256
-rw-r--r--thread_win32.h31
-rw-r--r--time.c2137
-rw-r--r--timev.h33
-rwxr-xr-xtool/bisect.sh31
-rw-r--r--tool/bundler/rubocop_gems.rb11
-rw-r--r--tool/bundler/rubocop_gems.rb.lock63
-rw-r--r--tool/bundler/standard_gems.rb11
-rw-r--r--tool/bundler/standard_gems.rb.lock69
-rw-r--r--tool/bundler/test_gems.rb12
-rw-r--r--tool/bundler/test_gems.rb.lock44
-rwxr-xr-xtool/change_maker.rb47
-rwxr-xr-xtool/checksum.rb4
-rw-r--r--tool/colorize.rb41
-rw-r--r--tool/colors (renamed from test/colors)0
-rwxr-xr-xtool/darwin-cc6
-rw-r--r--tool/downloader.rb90
-rw-r--r--tool/enc-emoji-citrus-gen.rb4
-rwxr-xr-xtool/enc-unicode.rb88
-rw-r--r--tool/eval.rb4
-rwxr-xr-xtool/expand-config.rb2
-rwxr-xr-xtool/extlibs.rb103
-rw-r--r--tool/fake.rb36
-rwxr-xr-xtool/fetch-bundled_gems.rb27
-rwxr-xr-xtool/file2lastrev.rb75
-rwxr-xr-xtool/format-release245
-rw-r--r--[-rwxr-xr-x]tool/gem-unpack.rb3
-rwxr-xr-xtool/gen-mailmap.rb47
-rwxr-xr-xtool/gen_ruby_tapset.rb11
-rw-r--r--tool/generate-backport-changelog.rb99
-rw-r--r--tool/generic_erb.rb15
-rwxr-xr-xtool/git-refresh3
-rw-r--r--tool/gperf.sed22
-rwxr-xr-xtool/id2token.rb3
-rwxr-xr-xtool/ifchange5
-rwxr-xr-xtool/insns2vm.rb17
-rwxr-xr-xtool/instruction.rb1226
-rwxr-xr-xtool/leaked-globals66
-rw-r--r--tool/lib/-test-/integer.rb (renamed from test/lib/-test-/integer.rb)0
-rw-r--r--tool/lib/colorize.rb55
-rw-r--r--tool/lib/envutil.rb365
-rw-r--r--tool/lib/find_executable.rb (renamed from test/lib/find_executable.rb)0
-rw-r--r--tool/lib/gc_compact_checker.rb10
-rw-r--r--tool/lib/iseq_loader_checker.rb81
-rw-r--r--tool/lib/jisx0208.rb (renamed from tool/jisx0208.rb)0
-rw-r--r--tool/lib/leakchecker.rb299
-rw-r--r--tool/lib/memory_status.rb (renamed from test/lib/memory_status.rb)0
-rw-r--r--tool/lib/minitest/README.txt (renamed from test/lib/minitest/README.txt)0
-rw-r--r--tool/lib/minitest/autorun.rb (renamed from test/lib/minitest/autorun.rb)0
-rw-r--r--tool/lib/minitest/benchmark.rb418
-rw-r--r--tool/lib/minitest/mock.rb (renamed from test/lib/minitest/mock.rb)0
-rw-r--r--tool/lib/minitest/unit.rb1479
-rw-r--r--tool/lib/profile_test_all.rb91
-rw-r--r--tool/lib/test/unit.rb1293
-rw-r--r--tool/lib/test/unit/assertions.rb317
-rw-r--r--tool/lib/test/unit/core_assertions.rb796
-rw-r--r--tool/lib/test/unit/parallel.rb209
-rw-r--r--tool/lib/test/unit/testcase.rb32
-rw-r--r--tool/lib/tracepointchecker.rb126
-rw-r--r--tool/lib/vcs.rb696
-rw-r--r--tool/lib/vpath.rb (renamed from tool/vpath.rb)0
-rw-r--r--tool/lib/webrick.rb232
-rw-r--r--tool/lib/webrick/.document6
-rw-r--r--tool/lib/webrick/accesslog.rb157
-rw-r--r--tool/lib/webrick/cgi.rb313
-rw-r--r--tool/lib/webrick/compat.rb (renamed from lib/webrick/compat.rb)0
-rw-r--r--tool/lib/webrick/config.rb158
-rw-r--r--tool/lib/webrick/cookie.rb172
-rw-r--r--tool/lib/webrick/htmlutils.rb (renamed from lib/webrick/htmlutils.rb)0
-rw-r--r--tool/lib/webrick/httpauth.rb96
-rw-r--r--tool/lib/webrick/httpauth/authenticator.rb117
-rw-r--r--tool/lib/webrick/httpauth/basicauth.rb116
-rw-r--r--tool/lib/webrick/httpauth/digestauth.rb395
-rw-r--r--tool/lib/webrick/httpauth/htdigest.rb132
-rw-r--r--tool/lib/webrick/httpauth/htgroup.rb97
-rw-r--r--tool/lib/webrick/httpauth/htpasswd.rb158
-rw-r--r--tool/lib/webrick/httpauth/userdb.rb (renamed from lib/webrick/httpauth/userdb.rb)0
-rw-r--r--tool/lib/webrick/httpproxy.rb354
-rw-r--r--tool/lib/webrick/httprequest.rb636
-rw-r--r--tool/lib/webrick/httpresponse.rb564
-rw-r--r--tool/lib/webrick/https.rb152
-rw-r--r--tool/lib/webrick/httpserver.rb294
-rw-r--r--tool/lib/webrick/httpservlet.rb23
-rw-r--r--tool/lib/webrick/httpservlet/abstract.rb152
-rw-r--r--tool/lib/webrick/httpservlet/cgi_runner.rb47
-rw-r--r--tool/lib/webrick/httpservlet/cgihandler.rb126
-rw-r--r--tool/lib/webrick/httpservlet/erbhandler.rb88
-rw-r--r--tool/lib/webrick/httpservlet/filehandler.rb552
-rw-r--r--tool/lib/webrick/httpservlet/prochandler.rb47
-rw-r--r--tool/lib/webrick/httpstatus.rb194
-rw-r--r--tool/lib/webrick/httputils.rb512
-rw-r--r--tool/lib/webrick/httpversion.rb (renamed from lib/webrick/httpversion.rb)0
-rw-r--r--tool/lib/webrick/log.rb156
-rw-r--r--tool/lib/webrick/server.rb381
-rw-r--r--tool/lib/webrick/ssl.rb215
-rw-r--r--tool/lib/webrick/utils.rb265
-rw-r--r--tool/lib/webrick/version.rb18
-rw-r--r--tool/lib/zombie_hunter.rb10
-rw-r--r--tool/m4/_colorize_result_prepare.m433
-rw-r--r--tool/m4/ac_msg_result.m45
-rw-r--r--tool/m4/colorize_result.m49
-rw-r--r--tool/m4/ruby_append_option.m45
-rw-r--r--tool/m4/ruby_append_options.m47
-rw-r--r--tool/m4/ruby_check_builtin_func.m410
-rw-r--r--tool/m4/ruby_check_builtin_setjmp.m427
-rw-r--r--tool/m4/ruby_check_printf_prefix.m429
-rw-r--r--tool/m4/ruby_check_setjmp.m417
-rw-r--r--tool/m4/ruby_check_signedness.m45
-rw-r--r--tool/m4/ruby_check_sizeof.m4108
-rw-r--r--tool/m4/ruby_check_sysconf.m413
-rw-r--r--tool/m4/ruby_cppoutfile.m418
-rw-r--r--tool/m4/ruby_decl_attribute.m445
-rw-r--r--tool/m4/ruby_default_arch.m411
-rw-r--r--tool/m4/ruby_define_if.m412
-rw-r--r--tool/m4/ruby_defint.m440
-rw-r--r--tool/m4/ruby_dtrace_available.m420
-rw-r--r--tool/m4/ruby_dtrace_postprocess.m430
-rw-r--r--tool/m4/ruby_func_attribute.m47
-rw-r--r--tool/m4/ruby_mingw32.m424
-rw-r--r--tool/m4/ruby_prepend_option.m45
-rw-r--r--tool/m4/ruby_prog_gnu_ld.m410
-rw-r--r--tool/m4/ruby_replace_funcs.m413
-rw-r--r--tool/m4/ruby_replace_type.m458
-rw-r--r--tool/m4/ruby_rm_recursive.m418
-rw-r--r--tool/m4/ruby_setjmp_type.m452
-rw-r--r--tool/m4/ruby_stack_grow_direction.m430
-rw-r--r--tool/m4/ruby_try_cflags.m412
-rw-r--r--tool/m4/ruby_try_cxxflags.m417
-rw-r--r--tool/m4/ruby_try_ldflags.m415
-rw-r--r--tool/m4/ruby_type_attribute.m48
-rw-r--r--tool/m4/ruby_universal_arch.m490
-rw-r--r--tool/m4/ruby_werror_flag.m418
-rwxr-xr-xtool/make-snapshot422
-rwxr-xr-xtool/merger.rb426
-rw-r--r--tool/mjit_archflag.sh40
-rw-r--r--tool/mjit_tabs.rb65
-rw-r--r--tool/mk_builtin_loader.rb361
-rw-r--r--tool/mk_call_iseq_optimized.rb72
-rwxr-xr-xtool/mkconfig.rb77
-rwxr-xr-xtool/mkrunnable.rb10
-rwxr-xr-xtool/node_name.rb8
-rw-r--r--tool/prereq.status3
-rwxr-xr-xtool/pull-latest-mspec-spec18
-rwxr-xr-xtool/pure_parser.rb24
-rwxr-xr-xtool/rbinstall.rb452
-rwxr-xr-xtool/rbuninstall.rb18
-rwxr-xr-xtool/redmine-backporter.rb103
-rwxr-xr-xtool/release.sh47
-rwxr-xr-xtool/releng/gen-mail.rb50
-rwxr-xr-xtool/releng/gen-release-note.rb36
-rwxr-xr-xtool/releng/update-www-meta.rb213
-rw-r--r--tool/ruby_vm/controllers/application_controller.rb25
-rw-r--r--tool/ruby_vm/helpers/c_escape.rb128
-rw-r--r--tool/ruby_vm/helpers/dumper.rb113
-rw-r--r--tool/ruby_vm/helpers/scanner.rb53
-rw-r--r--tool/ruby_vm/loaders/insns_def.rb100
-rw-r--r--tool/ruby_vm/loaders/opt_insn_unif_def.rb34
-rw-r--r--tool/ruby_vm/loaders/opt_operand_def.rb56
-rw-r--r--tool/ruby_vm/loaders/vm_opts_h.rb37
-rw-r--r--tool/ruby_vm/models/attribute.rb59
-rwxr-xr-xtool/ruby_vm/models/bare_instructions.rb240
-rw-r--r--tool/ruby_vm/models/c_expr.rb41
-rw-r--r--tool/ruby_vm/models/instructions.rb22
-rw-r--r--tool/ruby_vm/models/instructions_unifications.rb43
-rw-r--r--tool/ruby_vm/models/operands_unifications.rb142
-rw-r--r--tool/ruby_vm/models/trace_instructions.rb71
-rw-r--r--tool/ruby_vm/models/typemap.rb62
-rw-r--r--tool/ruby_vm/scripts/converter.rb29
-rw-r--r--tool/ruby_vm/scripts/insns2vm.rb93
-rw-r--r--tool/ruby_vm/tests/.gitkeep0
-rw-r--r--tool/ruby_vm/views/_attributes.erb35
-rw-r--r--tool/ruby_vm/views/_c_expr.erb17
-rw-r--r--tool/ruby_vm/views/_comptime_insn_stack_increase.erb62
-rw-r--r--tool/ruby_vm/views/_copyright.erb31
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb76
-rw-r--r--tool/ruby_vm/views/_insn_len_info.erb21
-rw-r--r--tool/ruby_vm/views/_insn_name_info.erb38
-rw-r--r--tool/ruby_vm/views/_insn_operand_info.erb46
-rw-r--r--tool/ruby_vm/views/_insn_sp_pc_dependency.erb27
-rw-r--r--tool/ruby_vm/views/_insn_type_chars.erb13
-rw-r--r--tool/ruby_vm/views/_leaf_helpers.erb55
-rw-r--r--tool/ruby_vm/views/_mjit_compile_getinlinecache.erb31
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn.erb92
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn_body.erb129
-rw-r--r--tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb29
-rw-r--r--tool/ruby_vm/views/_mjit_compile_ivar.erb101
-rw-r--r--tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb38
-rw-r--r--tool/ruby_vm/views/_mjit_compile_send.erb117
-rw-r--r--tool/ruby_vm/views/_notice.erb22
-rw-r--r--tool/ruby_vm/views/_sp_inc_helpers.erb37
-rw-r--r--tool/ruby_vm/views/_trace_instruction.erb16
-rw-r--r--tool/ruby_vm/views/insns.inc.erb26
-rw-r--r--tool/ruby_vm/views/insns_info.inc.erb22
-rw-r--r--tool/ruby_vm/views/mjit_compile.inc.erb110
-rw-r--r--tool/ruby_vm/views/opt_sc.inc.erb40
-rw-r--r--tool/ruby_vm/views/optinsn.inc.erb71
-rw-r--r--tool/ruby_vm/views/optunifs.inc.erb21
-rw-r--r--tool/ruby_vm/views/vm.inc.erb30
-rw-r--r--tool/ruby_vm/views/vmtc.inc.erb21
-rw-r--r--tool/run-lcov.rb8
-rwxr-xr-xtool/runruby.rb81
-rw-r--r--tool/search-cgvars.rb55
-rw-r--r--tool/sync_default_gems.rb636
-rw-r--r--tool/test-bundled-gems.rb57
-rw-r--r--tool/test-coverage.rb27
-rw-r--r--tool/test/minitest/metametameta.rb (renamed from test/minitest/metametameta.rb)0
-rw-r--r--tool/test/minitest/test_minitest_benchmark.rb (renamed from test/minitest/test_minitest_benchmark.rb)0
-rw-r--r--tool/test/minitest/test_minitest_mock.rb404
-rw-r--r--tool/test/minitest/test_minitest_unit.rb1793
-rw-r--r--tool/test/runner.rb23
-rw-r--r--tool/test/test_jisx0208.rb2
-rw-r--r--tool/test/testunit/test4test_hideskip.rb10
-rw-r--r--tool/test/testunit/test4test_redefinition.rb14
-rw-r--r--tool/test/testunit/test4test_sorting.rb18
-rw-r--r--tool/test/testunit/test_assertion.rb29
-rw-r--r--tool/test/testunit/test_hideskip.rb21
-rw-r--r--tool/test/testunit/test_parallel.rb204
-rw-r--r--tool/test/testunit/test_redefinition.rb (renamed from test/testunit/test_redefinition.rb)0
-rw-r--r--tool/test/testunit/test_sorting.rb (renamed from test/testunit/test_sorting.rb)0
-rw-r--r--tool/test/testunit/tests_for_parallel/ptest_first.rb (renamed from test/testunit/tests_for_parallel/ptest_first.rb)0
-rw-r--r--tool/test/testunit/tests_for_parallel/ptest_forth.rb (renamed from test/testunit/tests_for_parallel/ptest_forth.rb)0
-rw-r--r--tool/test/testunit/tests_for_parallel/ptest_second.rb (renamed from test/testunit/tests_for_parallel/ptest_second.rb)0
-rw-r--r--tool/test/testunit/tests_for_parallel/ptest_third.rb (renamed from test/testunit/tests_for_parallel/ptest_third.rb)0
-rw-r--r--tool/test/testunit/tests_for_parallel/runner.rb14
-rw-r--r--tool/test/webrick/.htaccess (renamed from test/webrick/.htaccess)0
-rw-r--r--tool/test/webrick/test_cgi.rb170
-rw-r--r--tool/test/webrick/test_config.rb (renamed from test/webrick/test_config.rb)0
-rw-r--r--tool/test/webrick/test_cookie.rb (renamed from test/webrick/test_cookie.rb)0
-rw-r--r--tool/test/webrick/test_do_not_reverse_lookup.rb (renamed from test/webrick/test_do_not_reverse_lookup.rb)0
-rw-r--r--tool/test/webrick/test_filehandler.rb402
-rw-r--r--tool/test/webrick/test_htgroup.rb19
-rw-r--r--tool/test/webrick/test_htmlutils.rb (renamed from test/webrick/test_htmlutils.rb)0
-rw-r--r--tool/test/webrick/test_httpauth.rb366
-rw-r--r--tool/test/webrick/test_httpproxy.rb466
-rw-r--r--tool/test/webrick/test_httprequest.rb488
-rw-r--r--tool/test/webrick/test_httpresponse.rb282
-rw-r--r--tool/test/webrick/test_https.rb (renamed from test/webrick/test_https.rb)0
-rw-r--r--tool/test/webrick/test_httpserver.rb543
-rw-r--r--tool/test/webrick/test_httpstatus.rb35
-rw-r--r--tool/test/webrick/test_httputils.rb (renamed from test/webrick/test_httputils.rb)0
-rw-r--r--tool/test/webrick/test_httpversion.rb (renamed from test/webrick/test_httpversion.rb)0
-rw-r--r--tool/test/webrick/test_server.rb191
-rw-r--r--tool/test/webrick/test_ssl_server.rb67
-rw-r--r--tool/test/webrick/test_utils.rb110
-rw-r--r--tool/test/webrick/utils.rb82
-rw-r--r--tool/test/webrick/webrick.cgi (renamed from test/webrick/webrick.cgi)0
-rw-r--r--tool/test/webrick/webrick.rhtml4
-rw-r--r--tool/test/webrick/webrick_long_filename.cgi (renamed from test/webrick/webrick_long_filename.cgi)0
-rw-r--r--tool/transcode-tblgen.rb30
-rw-r--r--tool/transform_mjit_header.rb326
-rwxr-xr-xtool/travis_retry.sh13
-rw-r--r--tool/update-bundled_gems.rb14
-rwxr-xr-xtool/update-deps38
-rw-r--r--tool/vcs.rb479
-rwxr-xr-xtool/ytab.sed64
-rw-r--r--trace_point.rb348
-rw-r--r--transcode.c136
-rw-r--r--transcode_data.h5
-rw-r--r--transient_heap.c989
-rw-r--r--transient_heap.h65
-rw-r--r--util.c3480
-rw-r--r--util/remove_openssl.rb55
-rw-r--r--variable.c2143
-rw-r--r--variable.h22
-rw-r--r--version.c55
-rw-r--r--version.h46
-rw-r--r--vm.c2206
-rw-r--r--vm_args.c532
-rw-r--r--vm_backtrace.c597
-rw-r--r--vm_callinfo.h455
-rw-r--r--vm_core.h1061
-rw-r--r--vm_debug.h91
-rw-r--r--vm_dump.c502
-rw-r--r--vm_eval.c1542
-rw-r--r--vm_exec.c76
-rw-r--r--vm_exec.h88
-rw-r--r--vm_insnhelper.c4102
-rw-r--r--vm_insnhelper.h145
-rw-r--r--vm_method.c1498
-rw-r--r--vm_opts.h36
-rw-r--r--vm_sync.c299
-rw-r--r--vm_sync.h138
-rw-r--r--vm_trace.c1266
-rw-r--r--vsnprintf.c7
-rw-r--r--warning.rb53
-rw-r--r--win32/.document1
-rw-r--r--win32/Makefile.sub324
-rw-r--r--win32/README.win32100
-rwxr-xr-xwin32/configure.bat22
-rw-r--r--win32/dir.h9
-rw-r--r--win32/file.c40
-rwxr-xr-xwin32/ifchange.bat13
-rwxr-xr-xwin32/mkexports.rb10
-rwxr-xr-xwin32/rm.bat2
-rwxr-xr-x[-rw-r--r--]win32/rtname.cmd0
-rw-r--r--win32/setup.mak69
-rw-r--r--win32/win32.c1059
8985 files changed, 596439 insertions, 317208 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000000..8f4b96445c
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1,39 @@
+;; Copyright (c) 2018 Urabe, Shyouhei. All rights reserved.
+;;
+;; This file is a part of the programming language Ruby. Permission is hereby
+;; granted, to either redistribute and/or modify this file, provided that the
+;; conditions mentioned in the file COPYING are met. Consult the file for
+;; details.
+
+((nil .
+ ((indent-tabs-mode . nil)
+ (require-final-newline . t)
+ (tab-width . 8)
+ (show-trailing-whitespace . t)
+ (whitespace-line-column . 80))) ;; See also [Misc #12277]
+
+ ;; (bat-mode . ((buffer-file-coding-system . utf-8-dos)))
+
+ (ruby-mode . ((ruby-indent-level . 2)))
+
+ (rdoc-mode . ((fill-column . 74)))
+
+ (yaml-mode . ((yaml-indent-offset . 2)))
+
+ (makefile-mode . ((indent-tabs-mode . t)))
+
+ (c-mode . ((c-file-style . "ruby")))
+
+ (c++-mode . ((c-file-style . "ruby")))
+
+ (change-log-mode .
+ ((buffer-file-coding-system . us-ascii)
+ (indent-tabs-mode . t)
+ (change-log-indent-text . 2)
+ (add-log-time-format . (lambda (&optional x y)
+ (let* ((time (or x (current-time)))
+ (system-time-locale "C")
+ (diff (+ (cadr time) 32400))
+ (lo (% diff 65536))
+ (hi (+ (car time) (/ diff 65536))))
+ (format-time-string "%a %b %e %H:%M:%S %Y" (list hi lo) t)))))))
diff --git a/.document b/.document
index eeb565b08b..8616203552 100644
--- a/.document
+++ b/.document
@@ -9,8 +9,18 @@
# prelude
prelude.rb
-
rbconfig.rb
+array.rb
+ast.rb
+dir.rb
+gc.rb
+integer.rb
+io.rb
+kernel.rb
+pack.rb
+trace_point.rb
+warning.rb
+ractor.rb
# the lib/ directory (which has its own .document file)
lib
@@ -19,9 +29,18 @@ lib
ext
# rdoc files
-NEWS
+NEWS.md
README.md
README.ja.md
+COPYING
+COPYING.ja
+CONTRIBUTING.md
+
+LEGAL
+
+# win32/README.win32 linked from README.md
+win32
+
doc
diff --git a/.editorconfig b/.editorconfig
index 49cc692091..4633a7acae 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -3,7 +3,7 @@ root = true
[*]
end_of_line = lf
indent_size = 4
-indent_style = tab
+indent_style = space
insert_final_newline = true
tab_width = 8
trim_trailing_whitespace = true
@@ -13,12 +13,18 @@ end_of_line = crlf
[*.gemspec]
indent_size = 2
-indent_style = space
[*.rb]
indent_size = 2
-indent_style = space
[*.yml]
indent_size = 2
-indent_style = space
+
+[{*[Mm]akefile*,*.mak,*.mk,depend}]
+indent_style = tab
+
+[enc/*]
+indent_size = 2
+
+[reg*.[ch]]
+indent_size = 2
diff --git a/.gdbinit b/.gdbinit
index b789cc257b..49380951b8 100644
--- a/.gdbinit
+++ b/.gdbinit
@@ -1,3 +1,5 @@
+set startup-with-shell off
+
define hook-run
set $color_type = 0
set $color_highlite = 0
@@ -134,7 +136,7 @@ define rp
printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
if ($flags & RUBY_FL_USER2)
printf "(shared) shared="
- output/x ((struct RArray*)($arg0))->as.heap.aux.shared
+ output/x ((struct RArray*)($arg0))->as.heap.aux.shared_root
printf " "
else
printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa
@@ -154,8 +156,12 @@ define rp
else
if ($flags & RUBY_T_MASK) == RUBY_T_HASH
printf "%sT_HASH%s: ", $color_type, $color_end,
- if ((struct RHash *)($arg0))->ntbl
- printf "len=%ld ", ((struct RHash *)($arg0))->ntbl->num_entries
+ if (((struct RHash *)($arg0))->basic.flags & RHASH_ST_TABLE_FLAG)
+ printf "st len=%ld ", ((struct RHash *)($arg0))->as.st->num_entries
+ else
+ printf "li len=%ld bound=%ld ", \
+ ((((struct RHash *)($arg0))->basic.flags & RHASH_AR_TABLE_SIZE_MASK) >> RHASH_AR_TABLE_SIZE_SHIFT), \
+ ((((struct RHash *)($arg0))->basic.flags & RHASH_AR_TABLE_BOUND_MASK) >> RHASH_AR_TABLE_BOUND_SHIFT)
end
print (struct RHash *)($arg0)
else
@@ -245,7 +251,7 @@ define rp
else
if ($flags & RUBY_T_MASK) == RUBY_T_IMEMO
printf "%sT_IMEMO%s(", $color_type, $color_end
- output (enum imemo_type)(($flags>>RUBY_FL_USHIFT)&imemo_mask)
+ output (enum imemo_type)(($flags>>RUBY_FL_USHIFT)&RUBY_IMEMO_MASK)
printf "): "
rp_imemo $arg0
else
@@ -259,6 +265,10 @@ define rp
printf "%sT_ZOMBIE%s: ", $color_type, $color_end
print (struct RData *)($arg0)
else
+ if ($flags & RUBY_T_MASK) == RUBY_T_MOVED
+ printf "%sT_MOVED%s: ", $color_type, $color_end
+ print *(struct RMoved *)$arg0
+ else
printf "%sunknown%s: ", $color_type, $color_end
print (struct RBasic *)($arg0)
end
@@ -294,6 +304,7 @@ define rp
end
end
end
+ end
end
document rp
Print a Ruby's VALUE.
@@ -546,7 +557,7 @@ document rp_class
end
define rp_imemo
- set $flags = (enum imemo_type)((((struct RBasic *)($arg0))->flags >> RUBY_FL_USHIFT) & imemo_mask)
+ set $flags = (enum imemo_type)((((struct RBasic *)($arg0))->flags >> RUBY_FL_USHIFT) & RUBY_IMEMO_MASK)
if $flags == imemo_cref
printf "(rb_cref_t *) %p\n", (void*)$arg0
print *(rb_cref_t *)$arg0
@@ -698,12 +709,6 @@ define nd_cval
rp ($arg0).u3.value
end
-
-define nd_cnt
- printf "%su3.cnt%s: ", $color_highlite, $color_end
- p ($arg0).u3.cnt
-end
-
define nd_tbl
printf "%su1.tbl%s: ", $color_highlite, $color_end
p ($arg0).u1.tbl
@@ -742,12 +747,6 @@ define nd_lit
rp ($arg0).u1.value
end
-
-define nd_frml
- printf "%su1.node%s: ", $color_highlite, $color_end
- rp ($arg0).u1.node
-end
-
define nd_rest
printf "%su2.argc%s: ", $color_highlite, $color_end
p ($arg0).u2.argc
@@ -774,12 +773,6 @@ define nd_args
rp ($arg0).u3.node
end
-
-define nd_noex
- printf "%su1.id%s: ", $color_highlite, $color_end
- p ($arg0).u1.id
-end
-
define nd_defn
printf "%su3.node%s: ", $color_highlite, $color_end
rp ($arg0).u3.node
@@ -797,17 +790,6 @@ define nd_new
end
-define nd_cfnc
- printf "%su1.cfunc%s: ", $color_highlite, $color_end
- p ($arg0).u1.cfunc
-end
-
-define nd_argc
- printf "%su2.argc%s: ", $color_highlite, $color_end
- p ($arg0).u2.argc
-end
-
-
define nd_cname
printf "%su1.id%s: ", $color_highlite, $color_end
p ($arg0).u1.id
@@ -989,7 +971,7 @@ define iseq
end
define rb_ps
- rb_ps_vm ruby_current_vm
+ rb_ps_vm ruby_current_vm_ptr
end
document rb_ps
Dump all threads and their callstacks
@@ -1021,24 +1003,55 @@ define print_lineno
set $pos = $pos - 1
end
- set $i = 0
- set $size = $iseq->body->line_info_size
- set $table = $iseq->body->line_info_table
+ set $index = 0
+ set $size = $iseq->body->insns_info.size
+ set $table = $iseq->body->insns_info.body
+ set $positions = $iseq->body->insns_info.positions
#printf "size: %d\n", $size
if $size == 0
else
- set $i = 1
- while $i < $size
- #printf "table[%d]: position: %d, line: %d, pos: %d\n", $i, $table[$i].position, $table[$i].line_no, $pos
- if $table[$i].position > $pos
- loop_break
+ if $size == 1
+ printf "%d", $table[0].line_no
+ else
+ if $positions
+ # get_insn_info_linear_search
+ set $index = 1
+ while $index < $size
+ #printf "table[%d]: position: %d, line: %d, pos: %d\n", $i, $positions[$i], $table[$i].line_no, $pos
+ if $positions[$index] > $pos
+ loop_break
+ end
+ set $index = $index + 1
+ if $positions[$index] == $pos
+ loop_break
+ end
end
- set $i = $i + 1
- if $table[$i].position == $pos
- loop_break
+ else
+ # get_insn_info_succinct_bitvector
+ set $sd = $iseq->body->insns_info.succ_index_table
+ set $immediate_table_size = sizeof($sd->imm_part) / sizeof(uint64_t) * 9
+ if $pos < $immediate_table_size
+ set $i = $pos / 9
+ set $j = $pos % 9
+ set $index = ((int)($sd->imm_part[$i] >> ($j * 7))) & 0x7f
+ else
+ set $block_index = ($pos - $immediate_table_size) / 512
+ set $block = &$sd->succ_part[$block_index]
+ set $block_bit_index = ($pos - $immediate_table_size) % 512
+ set $small_block_index = $block_bit_index / 64
+ set $small_block_popcount = $small_block_index == 0 ? 0 : (((int)($block->small_block_ranks >> (($small_block_index - 1) * 9))) & 0x1ff)
+ set $x = $block->bits[$small_block_index] << (63 - $block_bit_index % 64)
+ set $x = ($x & 0x5555555555555555) + ($x >> 1 & 0x5555555555555555)
+ set $x = ($x & 0x3333333333333333) + ($x >> 2 & 0x3333333333333333)
+ set $x = ($x & 0x0707070707070707) + ($x >> 4 & 0x0707070707070707)
+ set $x = ($x & 0x001f001f001f001f) + ($x >> 8 & 0x001f001f001f001f)
+ set $x = ($x & 0x0000003f0000003f) + ($x >>16 & 0x0000003f0000003f)
+ set $popcnt = ($x & 0x7f) + ($x >>32 & 0x7f)
+ set $index = $block->rank + $small_block_popcount + $popcnt
end
end
- printf "%d", $table[$i-1].line_no
+ printf "%d", $table[$index-1].line_no
+ end
end
end
@@ -1065,9 +1078,9 @@ define print_id
else
set $serial = (rb_id_serial_t)$id
end
- if $serial && $serial <= global_symbols.last_id
+ if $serial && $serial <= ruby_global_symbols.last_id
set $idx = $serial / ID_ENTRY_UNIT
- set $ids = (struct RArray *)global_symbols.ids
+ set $ids = (struct RArray *)ruby_global_symbols.ids
set $flags = $ids->basic.flags
if ($flags & RUBY_FL_USER1)
set $idsptr = $ids->as.ary
@@ -1110,7 +1123,7 @@ define print_pathobj
else
set $str = ((struct RArray*)($arg0))->as.heap.ptr[0]
end
- printf "%s", $str
+ print_string $str
end
end
@@ -1119,11 +1132,11 @@ define rb_ps_thread
set $ps_thread_th = (rb_thread_t*)$ps_thread->data
printf "* #<Thread:%p rb_thread_t:%p native_thread:%p>\n", \
$ps_thread, $ps_thread_th, $ps_thread_th->thread_id
- set $cfp = $ps_thread_th->ec.cfp
- set $cfpend = (rb_control_frame_t *)($ps_thread_th->ec.vm_stack + $ps_thread_th->ec.vm_stack_size)-1
+ set $cfp = $ps_thread_th->ec->cfp
+ set $cfpend = (rb_control_frame_t *)($ps_thread_th->ec->vm_stack + $ps_thread_th->ec->vm_stack_size)-1
while $cfp < $cfpend
if $cfp->iseq
- if !((VALUE)$cfp->iseq & RUBY_IMMEDIATE_MASK) && (((imemo_ifunc << RUBY_FL_USHIFT) | RUBY_T_IMEMO)==$cfp->iseq->flags & ((imemo_mask << RUBY_FL_USHIFT) | RUBY_T_MASK))
+ if !((VALUE)$cfp->iseq & RUBY_IMMEDIATE_MASK) && (((imemo_ifunc << RUBY_FL_USHIFT) | RUBY_T_IMEMO)==$cfp->iseq->flags & ((RUBY_IMEMO_MASK << RUBY_FL_USHIFT) | RUBY_T_MASK))
printf "%d:ifunc ", $cfpend-$cfp
set print symbol-filename on
output/a $cfp->iseq.body
@@ -1181,7 +1194,7 @@ define rb_ps_thread
end
define rb_count_objects
- set $objspace = ruby_current_vm->objspace
+ set $objspace = ruby_current_vm_ptr->objspace
set $counts_00 = 0
set $counts_01 = 0
set $counts_02 = 0
@@ -1266,7 +1279,7 @@ document rb_count_objects
Counts all objects grouped by type.
end
-# Details: https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/MachineInstructionsTraceWithGDB
+# Details: https://bugs.ruby-lang.org/projects/ruby-master/wiki/MachineInstructionsTraceWithGDB
define trace_machine_instructions
set logging on
set height 0
@@ -1305,3 +1318,34 @@ define dump_node
((struct RString*)$str)->as.heap.ptr : \
((struct RString*)$str)->as.ary)
end
+
+define print_flags
+ printf "RUBY_FL_WB_PROTECTED: %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_WB_PROTECTED ? "1" : "0"
+ printf "RUBY_FL_PROMOTED0 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_PROMOTED0 ? "1" : "0"
+ printf "RUBY_FL_PROMOTED1 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_PROMOTED1 ? "1" : "0"
+ printf "RUBY_FL_FINALIZE : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_FINALIZE ? "1" : "0"
+ printf "RUBY_FL_TAINT : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_TAINT ? "1" : "0"
+ printf "RUBY_FL_UNTRUSTED : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_UNTRUSTED ? "1" : "0"
+ printf "RUBY_FL_EXIVAR : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_EXIVAR ? "1" : "0"
+ printf "RUBY_FL_FREEZE : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_FREEZE ? "1" : "0"
+
+ printf "RUBY_FL_USER0 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER0 ? "1" : "0"
+ printf "RUBY_FL_USER1 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER1 ? "1" : "0"
+ printf "RUBY_FL_USER2 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER2 ? "1" : "0"
+ printf "RUBY_FL_USER3 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER3 ? "1" : "0"
+ printf "RUBY_FL_USER4 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER4 ? "1" : "0"
+ printf "RUBY_FL_USER5 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER5 ? "1" : "0"
+ printf "RUBY_FL_USER6 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER6 ? "1" : "0"
+ printf "RUBY_FL_USER7 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER7 ? "1" : "0"
+ printf "RUBY_FL_USER8 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER8 ? "1" : "0"
+ printf "RUBY_FL_USER9 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER9 ? "1" : "0"
+ printf "RUBY_FL_USER10 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER10 ? "1" : "0"
+ printf "RUBY_FL_USER11 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER11 ? "1" : "0"
+ printf "RUBY_FL_USER12 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER12 ? "1" : "0"
+ printf "RUBY_FL_USER13 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER13 ? "1" : "0"
+ printf "RUBY_FL_USER14 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER14 ? "1" : "0"
+ printf "RUBY_FL_USER15 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER15 ? "1" : "0"
+ printf "RUBY_FL_USER16 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER16 ? "1" : "0"
+ printf "RUBY_FL_USER17 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER17 ? "1" : "0"
+ printf "RUBY_FL_USER18 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER18 ? "1" : "0"
+end
diff --git a/.gitattributes b/.gitattributes
index 6ca2f89462..d0c2d266b4 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,3 +4,5 @@ bin svn-properties=svn:ignore=ruby
bin/* diff=ruby
tool/update-deps diff=ruby
tool/make-snapshot diff=ruby
+tool/format-release diff=ruby
+tool/leaked-globals diff=ruby
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
new file mode 100644
index 0000000000..56baa29942
--- /dev/null
+++ b/.github/SECURITY.md
@@ -0,0 +1,9 @@
+# Security Policy
+
+## Supported Versions
+
+See <https://www.ruby-lang.org/en/downloads/branches/>.
+
+## Reporting a Vulnerability
+
+See <https://www.ruby-lang.org/en/security/>.
diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml
new file mode 100644
index 0000000000..7196708b21
--- /dev/null
+++ b/.github/codeql/codeql-config.yml
@@ -0,0 +1,4 @@
+name: "CodeQL config for the Ruby language"
+
+paths-ignore:
+ - '/ext/**/*/conftest.c'
diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml
new file mode 100644
index 0000000000..16d1e4a85a
--- /dev/null
+++ b/.github/workflows/baseruby.yml
@@ -0,0 +1,47 @@
+name: BASERUBY Check
+
+on: [push, pull_request]
+
+jobs:
+ baseruby:
+ name: BASERUBY
+ runs-on: ubuntu-20.04
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ strategy:
+ matrix:
+ ruby:
+ - ruby-2.2
+# - ruby-2.3
+# - ruby-2.4
+# - ruby-2.5
+# - ruby-2.6
+ - ruby-2.7
+
+ steps:
+ - uses: actions/checkout@v2
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby }}
+ bundler: none
+ - run: echo "make=make -sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: sudo apt-get install build-essential autoconf bison
+ - run: ./autogen.sh
+ - run: ./configure --disable-install-doc
+ - run: $make update-unicode
+ - run: $make common-srcs
+ - run: $make incs
+ - run: $make all
+ - run: $make test
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / BASERUBY @ ${{ matrix.ruby }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml
new file mode 100644
index 0000000000..26d2ca473d
--- /dev/null
+++ b/.github/workflows/check_dependencies.yml
@@ -0,0 +1,45 @@
+name: Check Dependencies
+on: [push, pull_request]
+jobs:
+ update-deps:
+ strategy:
+ matrix:
+ os: [ubuntu-20.04, macos-latest]
+ fail-fast: true
+ runs-on: ${{ matrix.os }}
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ steps:
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
+ if: "contains(matrix.os, 'ubuntu')"
+ - name: Install libraries
+ run: |
+ brew update
+ brew install gdbm gmp libffi openssl@1.1 zlib autoconf automake libtool readline
+ if: "contains(matrix.os, 'macos')"
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ - uses: actions/checkout@v2
+ - run: ./autogen.sh
+ - name: Run configure
+ run: ./configure -C --disable-install-doc --disable-rubygems --with-gcc 'optflags=-O0' 'debugflags=-save-temps=obj -g'
+ - run: make all golf
+ - run: ruby tool/update-deps --fix
+ - run: git diff --no-ext-diff --ignore-submodules --exit-code
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / Dependencies need to update",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml
new file mode 100644
index 0000000000..576341bf88
--- /dev/null
+++ b/.github/workflows/check_misc.yml
@@ -0,0 +1,17 @@
+name: Miscellaneous checks
+on: [push, pull_request]
+
+jobs:
+ checks:
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v2
+ - name: Check if C-sources are US-ASCII
+ run: |
+ ! grep -r -n '[^ -~]' *.[chy] include internal win32/*.[ch]
+ - name: Check for header macros
+ run: |
+ ! for header in ruby/*.h; do \
+ git grep -l -F -e $header -e HAVE_`echo $header | tr a-z./ A-Z__` -- . > /dev/null || echo $header
+ done | grep -F .
+ working-directory: include
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000000..2dc47c0683
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,43 @@
+name: "Code scanning - action"
+
+on:
+ push:
+ pull_request:
+ schedule:
+ - cron: '0 12 * * 4'
+
+jobs:
+ CodeQL-Build:
+
+ # CodeQL runs on ubuntu-20.04 and windows-latest
+ runs-on: ubuntu-20.04
+
+ steps:
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
+
+ - name: Checkout repository
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 2
+
+ - run: git checkout HEAD^2
+ if: ${{ github.event_name == 'pull_request' }}
+
+ - name: Remove an obsolete rubygems vendored file
+ run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: cpp
+ config-file: ./.github/codeql/codeql-config.yml
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml
new file mode 100644
index 0000000000..47b73fb907
--- /dev/null
+++ b/.github/workflows/compilers.yml
@@ -0,0 +1,245 @@
+name: Compilations
+
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**.md'
+ - '**.rdoc'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**.md'
+ - '**.rdoc'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+# Github actions does not support YAML anchors. This creative use of
+# environment variables (plus the "echo $GITHUB_ENV" hack) is to reroute that
+# restriction.
+env:
+ default_cc: clang-14
+ append_cc: ''
+ crosshost: ''
+
+ # -O1 is faster than -O3 in our tests... Majority of time are consumed trying
+ # to optimize binaries. Also Github Actions run on relatively modern CPUs
+ # compared to, say, GCC 4 or Clang 3. We don't specify `-march=native`
+ # because compilers tend not understand what the CPU is.
+ optflags: '-O1'
+
+ # -g0 disables backtraces when SEGV. Do not set that.
+ debugflags: '-ggdb3'
+
+ default_configure: >-
+ --enable-debug-env
+ --disable-install-doc
+ --with-ext=-test-/cxxanyargs,+
+ append_configure: >-
+ --without-valgrind
+ --without-jemalloc
+ --without-gmp
+
+ UPDATE_UNICODE: >-
+ UNICODE_FILES=.
+ UNICODE_PROPERTY_FILES=.
+ UNICODE_AUXILIARY_FILES=.
+ UNICODE_EMOJI_FILES=.
+ CONFIGURE_TTY: never
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ RUBY_DEBUG: ci rgengc
+ RUBY_TESTOPTS: >-
+ -q
+ --color=always
+ --tty=no
+
+jobs:
+ compile:
+ strategy:
+ fail-fast: false
+ matrix:
+ entry:
+ - { key: default_cc, name: gcc-11, value: gcc-11, container: gcc-11 }
+ - { key: default_cc, name: gcc-10, value: gcc-10, container: gcc-10 }
+ - { key: default_cc, name: gcc-9, value: gcc-9, container: gcc-9 }
+ - { key: default_cc, name: gcc-8, value: gcc-8, container: gcc-8 }
+ - { key: default_cc, name: gcc-7, value: gcc-7, container: gcc-7 }
+ - { key: default_cc, name: gcc-6, value: gcc-6, container: gcc-6 }
+ - { key: default_cc, name: gcc-5, value: gcc-5, container: gcc-5 }
+ - { key: default_cc, name: gcc-4.8, value: gcc-4.8, container: gcc-4.8 }
+ - key: default_cc
+ name: 'gcc-11 LTO'
+ value: 'gcc-11 -O2 -flto=auto -ffat-lto-objects'
+ container: gcc-11
+ shared: '--disable-shared'
+ # check: true
+ - { key: default_cc, name: clang-14, value: clang-14, container: clang-14 }
+ - { key: default_cc, name: clang-13, value: clang-13, container: clang-13 }
+ - { key: default_cc, name: clang-12, value: clang-12, container: clang-12 }
+ - { key: default_cc, name: clang-11, value: clang-11, container: clang-11 }
+ - { key: default_cc, name: clang-10, value: clang-10, container: clang-10 }
+ - { key: default_cc, name: clang-9, value: clang-9, container: clang-9 }
+ - { key: default_cc, name: clang-8, value: clang-8, container: clang-8 }
+ - { key: default_cc, name: clang-7, value: clang-7, container: clang-7 }
+ - { key: default_cc, name: clang-6.0, value: clang-6.0, container: clang-6.0 }
+ - { key: default_cc, name: clang-5.0, value: clang-5.0, container: clang-5.0 }
+ - { key: default_cc, name: clang-4.0, value: clang-4.0, container: clang-4.0 }
+ - { key: default_cc, name: clang-3.9, value: clang-3.9, container: clang-3.9 }
+ - key: default_cc
+ name: 'clang-14 LTO'
+ value: 'clang-14 -O2 -flto=auto'
+ container: clang-14
+ shared: '--disable-shared'
+ # check: true
+
+ - { key: crosshost, name: aarch64-linux-gnu, value: aarch64-linux-gnu, container: crossbuild-essential-arm64 }
+# - { key: crosshost, name: arm-linux-gnueabi, value: arm-linux-gnueabi }
+# - { key: crosshost, name: arm-linux-gnueabihf, value: arm-linux-gnueabihf }
+# - { key: crosshost, name: i686-w64-mingw32, value: i686-w64-mingw32 }
+# - { key: crosshost, name: powerpc-linux-gnu, value: powerpc-linux-gnu }
+ - { key: crosshost, name: powerpc64le-linux-gnu, value: powerpc64le-linux-gnu, container: crossbuild-essential-ppc64el }
+ - { key: crosshost, name: s390x-linux-gnu, value: s390x-linux-gnu, container: crossbuild-essential-s390x }
+ - { key: crosshost, name: x86_64-w64-mingw32, value: x86_64-w64-mingw32, container: mingw-w64 }
+
+ - { key: append_cc, name: c99, value: '-std=c99 -Werror=pedantic -pedantic-errors' }
+# - { key: append_cc, name: c11, value: '-std=c11 -Werror=pedantic -pedantic-errors' }
+# - { key: append_cc, name: c17, value: '-std=c17 -Werror=pedantic -pedantic-errors' }
+# - { key: append_cc, name: c2x, value: '-std=c2x -Werror=pedantic -pedantic-errors' }
+ - { key: CXXFLAGS, name: c++98, value: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
+# - { key: CXXFLAGS, name: c++11, value: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
+# - { key: CXXFLAGS, name: c++14, value: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
+# - { key: CXXFLAGS, name: c++17, value: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
+ - { key: CXXFLAGS, name: c++2a, value: '-std=c++2a -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
+
+ - { key: optflags, name: '-O0', value: '-O0 -march=x86-64 -mtune=generic' }
+# - { key: optflags, name: '-O3', value: '-O3 -march=x86-64 -mtune=generic', check: true }
+
+ - { key: append_configure, name: gmp, value: '--with-gmp' }
+ - { key: append_configure, name: jemalloc, value: '--with-jemalloc' }
+ - { key: append_configure, name: valgrind, value: '--with-valgrind' }
+ - { key: append_configure, name: 'coroutine=ucontext', value: '--with-coroutine=ucontext' }
+ - { key: append_configure, name: 'coroutine=copy', value: '--with-coroutine=copy' }
+ - { key: append_configure, name: disable-jit-support, value: '--disable-jit-support' }
+ - { key: append_configure, name: disable-dln, value: '--disable-dln' }
+ - { key: append_configure, name: disable-rubygems, value: '--disable-rubygems' }
+
+ - { key: cppflags, name: OPT_THREADED_CODE=1, value: '-DOPT_THREADED_CODE=1' }
+ - { key: cppflags, name: OPT_THREADED_CODE=2, value: '-DOPT_THREADED_CODE=2' }
+ - { key: cppflags, name: OPT_THREADED_CODE=3, value: '-DOPT_THREADED_CODE=3' }
+
+ - { key: cppflags, name: NDEBUG, value: '-DNDEBUG' }
+ - { key: cppflags, name: RUBY_DEBUG, value: '-DRUBY_DEBUG' }
+# - { key: cppflags, name: ARRAY_DEBUG, value: '-DARRAY_DEBUG' }
+# - { key: cppflags, name: BIGNUM_DEBUG, value: '-DBIGNUM_DEBUG' }
+# - { key: cppflags, name: CCAN_LIST_DEBUG, value: '-DCCAN_LIST_DEBUG' }
+# - { key: cppflags, name: CPDEBUG=-1, value: '-DCPDEBUG=-1' }
+# - { key: cppflags, name: ENC_DEBUG, value: '-DENC_DEBUG' }
+# - { key: cppflags, name: GC_DEBUG, value: '-DGC_DEBUG' }
+# - { key: cppflags, name: HASH_DEBUG, value: '-DHASH_DEBUG' }
+# - { key: cppflags, name: ID_TABLE_DEBUG, value: '-DID_TABLE_DEBUG' }
+# - { key: cppflags, name: RGENGC_DEBUG=-1, value: '-DRGENGC_DEBUG=-1' }
+# - { key: cppflags, name: SYMBOL_DEBUG, value: '-DSYMBOL_DEBUG' }
+# - { key: cppflags, name: THREAD_DEBUG=-1, value: '-DTHREAD_DEBUG=-1' }
+
+# - { key: cppflags, name: RGENGC_CHECK_MODE, value: '-DRGENGC_CHECK_MODE' }
+# - { key: cppflags, name: TRANSIENT_HEAP_CHECK_MODE, value: '-DTRANSIENT_HEAP_CHECK_MODE' }
+# - { key: cppflags, name: VM_CHECK_MODE, value: '-DVM_CHECK_MODE' }
+
+ - { key: cppflags, name: USE_EMBED_CI=0, value: '-DUSE_EMBED_CI=0' }
+ - { key: cppflags, name: USE_FLONUM=0, value: '-DUSE_FLONUM=0' }
+# - { key: cppflags, name: USE_GC_MALLOC_OBJ_INFO_DETAILS, value: '-DUSE_GC_MALLOC_OBJ_INFO_DETAILS' }
+ - { key: cppflags, name: USE_LAZY_LOAD, value: '-DUSE_LAZY_LOAD' }
+# - { key: cppflags, name: USE_RINCGC=0, value: '-DUSE_RINCGC=0' }
+# - { key: cppflags, name: USE_SYMBOL_GC=0, value: '-DUSE_SYMBOL_GC=0' }
+# - { key: cppflags, name: USE_THREAD_CACHE=0, value: '-DUSE_THREAD_CACHE=0' }
+# - { key: cppflags, name: USE_TRANSIENT_HEAP=0, value: '-DUSE_TRANSIENT_HEAP=0' }
+# - { key: cppflags, name: USE_RUBY_DEBUG_LOG=1, value: '-DUSE_RUBY_DEBUG_LOG=1' }
+
+ - { key: cppflags, name: DEBUG_FIND_TIME_NUMGUESS, value: '-DDEBUG_FIND_TIME_NUMGUESS' }
+ - { key: cppflags, name: DEBUG_INTEGER_PACK, value: '-DDEBUG_INTEGER_PACK' }
+# - { key: cppflags, name: ENABLE_PATH_CHECK, value: '-DENABLE_PATH_CHECK' }
+
+ - { key: cppflags, name: GC_DEBUG_STRESS_TO_CLASS, value: '-DGC_DEBUG_STRESS_TO_CLASS' }
+# - { key: cppflags, name: GC_ENABLE_LAZY_SWEEP=0, value: '-DGC_ENABLE_LAZY_SWEEP=0' }
+# - { key: cppflags, name: GC_PROFILE_DETAIL_MEMOTY, value: '-DGC_PROFILE_DETAIL_MEMOTY' }
+# - { key: cppflags, name: GC_PROFILE_MORE_DETAIL, value: '-DGC_PROFILE_MORE_DETAIL' }
+
+# - { key: cppflags, name: CALC_EXACT_MALLOC_SIZE, value: '-DCALC_EXACT_MALLOC_SIZE' }
+# - { key: cppflags, name: MALLOC_ALLOCATED_SIZE_CHECK, value: '-DMALLOC_ALLOCATED_SIZE_CHECK' }
+
+# - { key: cppflags, name: IBF_ISEQ_ENABLE_LOCAL_BUFFER, value: '-DIBF_ISEQ_ENABLE_LOCAL_BUFFER' }
+
+# - { key: cppflags, name: RGENGC_ESTIMATE_OLDMALLOC, value: '-DRGENGC_ESTIMATE_OLDMALLOC' }
+# - { key: cppflags, name: RGENGC_FORCE_MAJOR_GC, value: '-DRGENGC_FORCE_MAJOR_GC' }
+# - { key: cppflags, name: RGENGC_OBJ_INFO, value: '-DRGENGC_OBJ_INFO' }
+# - { key: cppflags, name: RGENGC_OLD_NEWOBJ_CHECK, value: '-DRGENGC_OLD_NEWOBJ_CHECK' }
+# - { key: cppflags, name: RGENGC_PROFILE, value: '-DRGENGC_PROFILE' }
+
+# - { key: cppflags, name: VM_DEBUG_BP_CHECK, value: '-DVM_DEBUG_BP_CHECK' }
+# - { key: cppflags, name: VM_DEBUG_VERIFY_METHOD_CACHE, value: '-DVM_DEBUG_VERIFY_METHOD_CACHE' }
+
+ - { key: cppflags, name: MJIT_FORCE_ENABLE, value: '-DMJIT_FORCE_ENABLE' }
+ - { key: cppflags, name: YJIT_FORCE_ENABLE, value: '-DYJIT_FORCE_ENABLE' }
+
+ name: ${{ matrix.entry.name }}
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/ruby/ruby-ci-image:${{ matrix.entry.container || 'clang-14' }}
+ options: --user root
+ if: ${{ !startsWith(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ steps:
+ - run: id
+ working-directory:
+ - run: mkdir build
+ working-directory:
+ - name: setenv
+ run: |
+ echo "${{ matrix.entry.key }}=${{ matrix.entry.value }}" >> $GITHUB_ENV
+ echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - uses: actions/checkout@v3
+ with:
+ path: src
+ - uses: actions/cache@v3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: >
+ ../src/configure -C ${default_configure} ${append_configure}
+ ${{ matrix.entry.key == 'crosshost' && '--host="${crosshost}"' || '--with-gcc="${default_cc} ${append_cc}"' }}
+ ${{ matrix.entry.shared || '--enable-shared' }}
+ - run: make extract-extlibs
+ - run: make incs
+ - run: make
+# - run: make leaked-globals
+ - run: make test
+ - run: make install
+ if: ${{ matrix.entry.check }}
+ - run: make test-tool
+ if: ${{ matrix.entry.check }}
+ - run: make test-all TESTS='-- ruby -ext-'
+ if: ${{ matrix.entry.check }}
+ - run: make test-spec
+ if: ${{ matrix.entry.check }}
+
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.entry.name }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: ${{ failure() && github.event_name == 'push' }}
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
new file mode 100644
index 0000000000..1da94630fe
--- /dev/null
+++ b/.github/workflows/macos.yml
@@ -0,0 +1,66 @@
+name: macOS
+on: [push, pull_request]
+jobs:
+ make:
+ runs-on: macos-latest
+ strategy:
+ matrix:
+ test_task: [ "check" ] #, "test-bundler-parallel", "test-bundled-gems" ] matrix tests has unknown issues
+ fail-fast: false
+ env:
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: Disable Firewall
+ run: |
+ sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+ sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ - uses: actions/checkout@v2
+ with:
+ path: src
+ - name: Install libraries
+ run: |
+ export WAITS='5 60'
+ tool/travis_retry.sh brew update
+ tool/travis_retry.sh brew install gdbm gmp libffi openssl@1.1 zlib autoconf automake libtool readline
+ working-directory: src
+ - name: Set ENV
+ run: |
+ echo "JOBS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: ../src/configure -C --disable-install-doc --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline)
+ - run: make $JOBS incs
+ - run: make $JOBS
+ - run: make leaked-globals
+ if: matrix.test_task == 'check'
+ - run: make prepare-gems
+ if: matrix.test_task == 'check'
+ - run: make $JOBS -s ${{ matrix.test_task }}
+ timeout-minutes: 60
+ env:
+ RUBY_TESTOPTS: "-q --tty=no"
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: "rexml"
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml
new file mode 100644
index 0000000000..a5d64c7b2d
--- /dev/null
+++ b/.github/workflows/mingw.yml
@@ -0,0 +1,141 @@
+name: MinGW
+on: [push, pull_request]
+
+# Notes:
+# Actions console encoding causes issues, see test-all & test-spec steps
+#
+jobs:
+ make:
+ runs-on: windows-2022
+ name: ${{ github.workflow }} (${{ matrix.msystem }})
+ env:
+ MSYSTEM: MINGW64
+ MSYSTEM_PREFIX: /mingw64
+ MSYS2_ARCH: x86_64
+ CHOST: "x86_64-w64-mingw32"
+ CFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong"
+ CXXFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe"
+ CPPFLAGS: "-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048"
+ LDFLAGS: "-pipe -fstack-protector-strong"
+ UPDATE_UNICODE: "UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=."
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ strategy:
+ matrix:
+ test_task: [ "check" ] # to make job names consistent
+ fail-fast: false
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: git config
+ run: |
+ git config --system core.autocrlf false
+ git config --system core.eol lf
+ git config --system advice.detachedHead 0
+ - uses: actions/checkout@v2
+ with:
+ path: src
+ - name: Set up Ruby & MSYS2
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: 2.6
+ mingw: _upgrade_ gdbm gmp libffi libyaml openssl ragel readline
+ msys2: automake1.16 bison
+ - name: where check
+ run: |
+ # show where
+ Write-Host
+ $where = 'gcc.exe', 'ragel.exe', 'make.exe', 'bison.exe', 'libcrypto-1_1-x64.dll', 'libssl-1_1-x64.dll'
+ foreach ($e in $where) {
+ $rslt = where.exe $e 2>&1 | Out-String
+ if ($rslt.contains($e)) { Write-Host $rslt }
+ else { Write-Host "`nCan't find $e" }
+ }
+
+ - name: autogen
+ run: |
+ ./autogen.sh
+ working-directory: src
+ shell: sh
+
+ - name: configure
+ run: |
+ # Actions uses UTF8, causes test failures, similar to normal OS setup
+ $PSDefaultParameterValues['*:Encoding'] = 'utf8'
+ [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ $config_args = "--build=$env:CHOST --host=$env:CHOST --target=$env:CHOST"
+ Write-Host $config_args
+ sh -c "../src/configure --disable-install-doc --prefix=/. $config_args"
+ # Write-Host "-------------------------------------- config.log"
+ # Get-Content ./config.log | foreach {Write-Output $_}
+
+ - name: update
+ run: |
+ $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS)
+ make -j $jobs incs
+
+ - name: download gems
+ run: |
+ $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS)
+ make -j $jobs update-gems
+
+ - name: make all
+ timeout-minutes: 40
+ run: |
+ $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS)
+ make -j $jobs
+
+ - name: make install
+ run: |
+ # Actions uses UTF8, causes test failures, similar to normal OS setup
+ $PSDefaultParameterValues['*:Encoding'] = 'utf8'
+ [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ make DESTDIR=../install install-nodoc
+
+ - name: test
+ timeout-minutes: 5
+ run: |
+ make test
+
+ - name: test-all
+ timeout-minutes: 60
+ run: |
+ # Actions uses UTF8, causes test failures, similar to normal OS setup
+ $PSDefaultParameterValues['*:Encoding'] = 'utf8'
+ [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ $jobs = [int](1.5 * $env:NUMBER_OF_PROCESSORS)
+ if ($env:BUNDLER_VERSION) { Remove-Item env:\BUNDLER_VERSION }
+ make test-all TESTOPTS="-j $jobs --retry --job-status=normal --show-skip --timeout-scale=1.5"
+
+ - name: test-spec
+ timeout-minutes: 10
+ working-directory: src/spec/ruby
+ run: |
+ $env:Path = "$pwd/../../../install/bin;$env:Path"
+ # Actions uses UTF8, causes test failures, similar to normal OS setup
+ $PSDefaultParameterValues['*:Encoding'] = 'utf8'
+ [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
+ ruby -v
+ ruby ../mspec/bin/mspec -I../../tool/lib -j
+
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} ${{ matrix.msystem }} / ${{ matrix.test_task }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/mjit.yml b/.github/workflows/mjit.yml
new file mode 100644
index 0000000000..8dcbcf7760
--- /dev/null
+++ b/.github/workflows/mjit.yml
@@ -0,0 +1,77 @@
+name: MJIT
+on: [push, pull_request]
+jobs:
+ make:
+ strategy:
+ matrix:
+ test_task: [check] # to make job names consistent
+ jit_opts: [--jit-wait]
+ fail-fast: false
+ runs-on: ubuntu-20.04
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ env:
+ TESTOPTS: '-q --tty=no'
+ RUN_OPTS: '--disable-gems ${{ matrix.jit_opts }} --jit-debug=-ggdb3'
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ - uses: actions/checkout@v2
+ with:
+ path: src
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: ../src/configure -C --disable-install-doc cppflags=-DVM_CHECK_MODE
+ - run: make incs
+ - run: make
+ - run: sudo make -s install
+ - run: sudo apt-get install gdb # used by test / test-all failure
+ - name: Run test
+ run: |
+ ulimit -c unlimited
+ make -s test RUN_OPTS="$RUN_OPTS"
+ timeout-minutes: 60
+ # - name: Run test-all
+ # run: |
+ # ulimit -c unlimited
+ # make -s test-all RUN_OPTS="$RUN_OPTS"
+ # timeout-minutes: 60
+ - name: Run test-spec
+ run: |
+ ulimit -c unlimited
+ make -s test-spec RUN_OPTS="$RUN_OPTS"
+ timeout-minutes: 60
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.jit_opts }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml
new file mode 100644
index 0000000000..bf053cdd05
--- /dev/null
+++ b/.github/workflows/spec_guards.yml
@@ -0,0 +1,41 @@
+name: Rubyspec Version Guards Check
+
+on: [push, pull_request]
+
+jobs:
+ rubyspec:
+ name: Rubyspec
+ runs-on: ubuntu-20.04
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ strategy:
+ matrix:
+ # Specs from ruby/spec should still run on all supported Ruby versions.
+ # This also ensures the needed ruby_version_is guards are there, see spec/README.md.
+ ruby:
+ - ruby-2.5
+# - ruby-2.6
+ - ruby-2.7
+ - ruby-3.0
+
+ steps:
+ - uses: actions/checkout@v2
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby }}
+ bundler: none
+ - run: gem install webrick
+ - run: ruby ../mspec/bin/mspec
+ working-directory: spec/ruby
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / rubyspec @ ${{ matrix.ruby }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
new file mode 100644
index 0000000000..93187699be
--- /dev/null
+++ b/.github/workflows/ubuntu.yml
@@ -0,0 +1,87 @@
+name: Ubuntu
+on: [push, pull_request]
+jobs:
+ make:
+ strategy:
+ matrix:
+ test_task: [ "check", "test-bundler-parallel", "test-bundled-gems", "test-all TESTS=--repeat-count=2" ]
+ os:
+ - ubuntu-20.04
+# - ubuntu-18.04
+# - ubuntu-16.04
+ debug: ["", "-DRUBY_DEBUG"]
+ exclude:
+ - test_task: test-bundler-parallel
+ os: ubuntu-16.04
+ - test_task: test-bundled-gems
+ os: ubuntu-16.04
+ - test_task: "test-all TESTS=--repeat-count=2"
+ os: ubuntu-16.04
+ - os: ubuntu-16.04
+ debug: -DRUBY_DEBUG
+ - test_task: "test-all TESTS=--repeat-count=2"
+ debug: -DRUBY_DEBUG
+ fail-fast: false
+ env:
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ RUBY_DEBUG: ci
+ runs-on: ${{ matrix.os }}
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ - uses: actions/checkout@v2
+ with:
+ path: src
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - name: Set ENV
+ run: |
+ echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: ../src/configure -C --disable-install-doc cppflags=${{ matrix.debug }}
+ - run: make $JOBS incs
+ - run: make $JOBS
+ - run: make leaked-globals
+ if: matrix.test_task == 'check'
+ - run: make prepare-gems
+ if: matrix.test_task == 'check'
+ - name: Create dummy files in build dir
+ run: |
+ ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}'
+ if: matrix.test_task == 'check'
+ - run: make $JOBS -s ${{ matrix.test_task }}
+ timeout-minutes: 30
+ env:
+ RUBY_TESTOPTS: "-q --tty=no"
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.debug }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
new file mode 100644
index 0000000000..98e59ae188
--- /dev/null
+++ b/.github/workflows/windows.yml
@@ -0,0 +1,80 @@
+name: Windows
+on: [push, pull_request]
+jobs:
+ make:
+ strategy:
+ matrix:
+ test_task: [test]
+ os: [windows-2019]
+ vs: [2019]
+ fail-fast: false
+ runs-on: ${{ matrix.os }}
+ env:
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ VCVARS: C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ steps:
+ - run: md build
+ working-directory:
+ - uses: actions/cache@v2
+ with:
+ path: C:\vcpkg\downloads
+ key: ${{ runner.os }}-vcpkg-download-${{ matrix.os }}-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-vcpkg-download-${{ matrix.os }}-
+ ${{ runner.os }}-vcpkg-download-
+ - name: Install libraries with vcpkg
+ run: |
+ vcpkg --triplet x64-windows install readline zlib
+ - uses: actions/cache@v2
+ with:
+ path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
+ key: ${{ runner.os }}-chocolatey-${{ matrix.os }}-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-chocolatey-${{ matrix.os }}-
+ ${{ runner.os }}-chocolatey-
+ - name: Install libraries with chocolatey
+ run: |
+ choco install --no-progress openssl
+ choco install --no-progress winflexbison3 --version=2.5.18.20190508
+ - name: git config
+ run: |
+ git config --system advice.detachedHead 0
+ - uses: actions/checkout@v2
+ with:
+ path: src
+ - name: Configure
+ run: |
+ call "%VCVARS%"
+ ../src/win32/configure.bat --disable-install-doc --without-ext=+,dbm,gdbm --enable-bundled-libffi --with-opt-dir=C:/vcpkg/installed/x64-windows --with-openssl-dir="C:/Program Files/OpenSSL-Win64"
+ - name: nmake
+ run: |
+ call "%VCVARS%"
+ set YACC=win_bison
+ echo on
+ nmake incs
+ nmake extract-extlibs
+ nmake
+ - name: nmake test
+ timeout-minutes: 30
+ run: |
+ call "%VCVARS%"
+ nmake ${{ matrix.test_task }}
+ - uses: k0kubun/action-slack@v2.0.0
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / ${{ matrix.test_task }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref }}".split('/').reverse()[0]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: failure() && github.event_name == 'push'
+
+defaults:
+ run:
+ working-directory: build
+ shell: cmd
diff --git a/.gitignore b/.gitignore
index ad98717668..8d11d7278a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
*.a
*.bak
*.bc
+*.bundle
*.dSYM
*.dmyh
*.dylib
@@ -15,22 +16,28 @@
*.obj
*.old
*.orig
+*.pch
*.pdb
+*.rbinc
*.rej
*.s
*.sav
+*.sl
+*.so
*.swp
*.yarb
*~
-.*-*
.*.list
.*.time
.DS_Store
+.bundle
.ccmalloc
.ext
.pc
.ppack
.svn
+.time
+.ruby-version
Makefile
cygruby*.def
extconf.h
@@ -39,6 +46,7 @@ y.tab.c
*.gcda
*.gcno
*.gcov
+*.vscode
lcov*.info
# /
@@ -49,7 +57,11 @@ lcov*.info
/*.pc
/*.rc
/*_prelude.c
+/.downloaded-cache
+/.top-enc.mk
+/build*/
/COPYING.LIB
+/ChangeLog
/Doxyfile
/GNUmakefile
/README.atheos
@@ -59,6 +71,7 @@ lcov*.info
/archive
/autom4te*.cache
/automake
+/benchmark/benchmark-driver
/beos
/bmlog-*
/breakpoints.gdb
@@ -106,6 +119,7 @@ lcov*.info
/rename2.h
/repack
/revision.h
+/revision.tmp
/riscos
/rubicon
/ruby
@@ -114,6 +128,7 @@ lcov*.info
/ruby-man.rd.gz
/run.gdb
/sizes.c
+/static-ruby
/test.rb
/test-coverage.dat
/tmp
@@ -124,33 +139,46 @@ lcov*.info
/web
/yasmdata.rb
+# /bin/
+
+/bin/*.exe
+/bin/*.dll
+
# /benchmark/
/benchmark/bm_require.data
/benchmark/bmx_*.rb
/benchmark/fasta.output.*
/benchmark/wc.input
-/bin/ruby
-
/enc/*.def
/enc/*.exp
/enc/*.lib
/enc/jis/props.h
/enc/unicode/data
+# /coroutine/
+!/coroutine/**/*.s
+
# /enc/trans/
/enc/trans/*.c
/enc/trans/*.def
/enc/trans/*.exp
/enc/trans/*.lib
-/enc/trans/.time
+
+# /exe/
+/exe/goruby
+/exe/ruby
# /ext/
/ext/extinit.c
/ext/configure-ext.mk
/ext/*/exts.mk
+# /ext/-test-/cxxanyargs
+/ext/-test-/cxxanyargs/failure*.failed
+
# /ext/-test-/win32/dln/
+/ext/-test-/win32/dln/dlntest.dll
/ext/-test-/win32/dln/dlntest.exp
/ext/-test-/win32/dln/dlntest.lib
@@ -166,6 +194,7 @@ lcov*.info
# /ext/ripper/
/ext/ripper/eventids1.c
+/ext/ripper/.eventids2-check
/ext/ripper/eventids2table.c
/ext/ripper/ripper.*
/ext/ripper/ids1
@@ -178,11 +207,15 @@ lcov*.info
# /gems
/gems/*.gem
+/gems/src
/gems/*-*
+# /lib/
+/lib/ruby/[1-9]*.*
+/lib/ruby/vendor_ruby
+
# /spec/bundler
/.rspec_status
-/spec/rspec
# /tool/
/tool/config.guess
@@ -190,4 +223,8 @@ lcov*.info
# /win32/
/win32/*.ico
-/win32/.time
+
+# MJIT
+/rb_mjit_header.h
+/mjit_config.h
+/include/ruby-*/*/rb_mjit_min_header-*.h
diff --git a/.indent.pro b/.indent.pro
deleted file mode 100644
index 6a207a0554..0000000000
--- a/.indent.pro
+++ /dev/null
@@ -1,21 +0,0 @@
--bap
--nbbb
--nbc
--br
--nbs
--ncdb
--ce
--cli0.5
--ndj
--ei
--nfc1
--i4
--l120
--lp
--npcs
--psl
--sc
--sob
-
--TID
--TVALUE
diff --git a/.rspec_parallel b/.rspec_parallel
new file mode 100644
index 0000000000..aaff198a32
--- /dev/null
+++ b/.rspec_parallel
@@ -0,0 +1,2 @@
+--format progress
+--format ParallelTests::RSpec::RuntimeLogger --out tmp/parallel_runtime_rspec.log
diff --git a/.travis.yml b/.travis.yml
index 3e81083c8f..d480307dd6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,4 @@
+# -*- YAML -*-
# Copyright (C) 2011 Urabe, Shyouhei. All rights reserved.
#
# This file is a part of the programming language Ruby. Permission is hereby
@@ -17,88 +18,274 @@
# is also a good place to look at.
language: c
-dist: trusty
-sudo: false
+os: linux
-compiler:
- - gcc
+dist: xenial
-os:
- - linux
+git:
+ quiet: true
-before_install:
- - "CONFIG_FLAG="
- - "JOBS=-j`nproc`"
+cache:
+ ccache: true
+ directories:
+ - $HOME/config_2nd
+ - $HOME/.downloaded-cache
+
+env:
+ global:
+ # Reset timestamps early
+ - _=$(touch NEWS && find . -type f -exec touch -r NEWS {} +)
+ - CONFIGURE_TTY=no
+ - CCACHE_COMPILERCHECK=none
+ - CCACHE_NOCOMPRESS=1
+ - CCACHE_MAXSIZE=512Mi
+ - NPROC="`nproc`"
+ # JOBS and SETARCH are overridden when necessary; see below.
+ - JOBS=-j$((1+${NPROC}))
+ - SETARCH=
+ - RUBY_PREFIX=/tmp/ruby-prefix
+ - GEMS_FOR_TEST='timezone tzinfo'
+ - UPDATE_UNICODE="UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=."
+ - BEFORE_INSTALL=true
+ # https://github.com/travis-ci/travis-build/blob/e411371dda21430a60f61b8f3f57943d2fe4d344/lib/travis/build/bash/travis_apt_get_options.bash#L7
+ - travis_apt_get_options='--allow-downgrades --allow-remove-essential --allow-change-held-packages'
+ - travis_apt_get_options="-yq --no-install-suggests --no-install-recommends $travis_apt_get_options"
+
+.org.ruby-lang.ci.matrix-definitions:
+
+ - &make-test-only
+ script:
+ - $SETARCH make -s test TESTOPTS="${TESTOPTS=$JOBS -q --tty=no}"
+
+ - &gcc-8
+ compiler: gcc-8
+ # # Not using addon to control retries
+ # addons:
+ # apt:
+ # sources:
+ # - ubuntu-toolchain-r-test
+ before_install:
+ - bash -cx "${BEFORE_INSTALL}"
+ - tool/travis_retry.sh sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
+ - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
+ - >-
+ tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
+ ccache
+ gcc-8
+ g++-8
+ libffi-dev
+ libgdbm-dev
+ libncurses5-dev
+ libncursesw5-dev
+ libreadline6-dev
+ libssl-dev
+ libyaml-dev
+ openssl
+ zlib1g-dev
+
+ - &clang-8
+ compiler: clang-8
+ addons:
+ apt:
+ # Not doing this manually unlike other sources, because it has been stable.
+ sources:
+ - llvm-toolchain-xenial-8
+ config:
+ retries: true
+ before_install:
+ - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
+ - >-
+ tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
+ clang-8
+ llvm-8-tools
+ libffi-dev
+ libgdbm-dev
+ libncurses5-dev
+ libncursesw5-dev
+ libreadline6-dev
+ libssl-dev
+ libyaml-dev
+ openssl
+ zlib1g-dev
+
+ # --------
+
+ - &x86_64-linux
+ name: x86_64-linux
+ <<: *gcc-8
+
+ - &arm64-linux
+ name: arm64-linux
+ arch: arm64
+ <<: *gcc-8
+
+ - &s390x-linux
+ name: s390x-linux
+ arch: s390x
+ <<: *gcc-8
+
+ - &i686-linux
+ name: i686-linux
+ compiler: gcc-8
+ env:
+ - GCC_FLAGS=-m32
+ - CXX='g++-8 -m32'
+ - debugflags=-g0
+ - SETARCH='setarch i686 --verbose --3gb'
+ # # Not using addon to control retries
+ # addons:
+ # apt:
+ # sources:
+ # - ubuntu-toolchain-r-test
+ before_install:
+ - tool/travis_retry.sh sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
+ - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
+ - >-
+ tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
+ gcc-8-multilib
+ g++-8
+ g++-8-multilib
+ libstdc++-8-dev:i386
+ libffi-dev:i386
+ libffi6:i386
+ libgdbm-dev:i386
+ libgdbm3:i386
+ libncurses5-dev:i386
+ libncurses5:i386
+ libncursesw5-dev:i386
+ libreadline6-dev:i386
+ libreadline6:i386
+ libssl-dev:i386
+ libssl1.0.0:i386
+ linux-libc-dev:i386
+ zlib1g-dev:i386
+ zlib1g:i386
+
+ - &arm32-linux
+ name: arm32-linux
+ arch: arm64
+ # https://packages.ubuntu.com/xenial/crossbuild-essential-armhf
+ compiler: arm-linux-gnueabihf-gcc
+ env:
+ - debugflags=-g0
+ - SETARCH='setarch linux32 --verbose --32bit'
+ before_install:
+ - sudo dpkg --add-architecture armhf
+ - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
+ - >-
+ tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
+ ccache
+ crossbuild-essential-armhf
+ libc6:armhf
+ libstdc++-5-dev:armhf
+ libffi-dev:armhf
+ libffi6:armhf
+ libgdbm-dev:armhf
+ libgdbm3:armhf
+ libncurses5-dev:armhf
+ libncurses5:armhf
+ libncursesw5-dev:armhf
+ libreadline6-dev:armhf
+ libreadline6:armhf
+ libssl-dev:armhf
+ libssl1.0.0:armhf
+ linux-libc-dev:armhf
+ zlib1g-dev:armhf
+ zlib1g:armhf
+
+matrix:
+ include:
+ # Build every commit:
+ - <<: *i686-linux
+ # Build every commit (Allowed Failures):
+ - <<: *arm32-linux
+ - <<: *arm64-linux
+ - <<: *s390x-linux
+ allow_failures:
+ - name: arm32-linux
+ - name: arm64-linux
+ - name: s390x-linux
+ fast_finish: true
before_script:
- - "echo JOBS=$JOBS"
- - "uname -a"
- - "uname -r"
- - "rm -fr .ext autom4te.cache"
- - "echo $TERM"
+ - rm -fr .ext autom4te.cache
+ - |-
+ [ -d ~/.downloaded-cache ] ||
+ mkdir ~/.downloaded-cache
+ - ln -s ~/.downloaded-cache
- "> config.status"
- - "sed -f tool/prereq.status Makefile.in common.mk > Makefile"
- - "make update-config_files"
- - "make touch-unicode-files"
- - "make -s $JOBS srcs UNICODE_FILES=."
- - "requests=; for req in ${RUBYSPEC_PULL_REQUEST//,/ }; do
- requests=\"$requests +refs/pull/$req/merge:\";
- done"
- - "${requests:+git -C spec/ruby -c user.email=none -c user.name=none pull --no-edit origin $requests}"
- - "${requests:+git -C spec/ruby log --oneline origin/master..@}"
- - "rm config.status Makefile rbconfig.rb .rbconfig.time"
- - "mkdir build config_1st config_2nd"
- - "chmod -R a-w ."
- - "chmod u+w build config_1st config_2nd"
- - "cd build"
- - "../configure -C --disable-install-doc --with-gcc=$CC $CONFIG_FLAG"
- - "cp -pr config.cache config.status .ext/include ../config_1st"
- - "make reconfig"
- - "cp -pr config.cache config.status .ext/include ../config_2nd"
- - "(cd .. && exec diff -ru config_1st config_2nd)"
- - "make -s $JOBS"
+ - "> .rbconfig.time"
+ - sed -f tool/prereq.status template/Makefile.in common.mk > Makefile
+ - make touch-unicode-files
+ - make -s $JOBS $UPDATE_UNICODE up
+ - make -s $JOBS srcs
+ - rm -f config.status Makefile rbconfig.rb .rbconfig.time
+ - |-
+ if [ -d ~/config_2nd ]; then
+ cp -pr ~/config_2nd build
+ else
+ mkdir build
+ fi
+ - mkdir config_1st config_2nd
+ - chmod -R a-w .
+ - chmod -R u+w build config_1st config_2nd
+ - cd build
+ - |-
+ case "$CC" in
+ gcc*) CC="ccache $CC${GCC_FLAGS:+ }$GCC_FLAGS -fno-diagnostics-color";;
+ clang*) CC="ccache $CC${GCC_FLAGS:+ }$GCC_FLAGS -fno-color-diagnostics";;
+ esac
+ - |-
+ [ ! -f config.cache ] ||
+ [ "$CC" = "`sed -n s/^ac_cv_prog_CC=//p config.cache`" ] ||
+ (set -x; exec rm config.cache)
+ - $SETARCH ../configure -C --disable-install-doc --prefix=$RUBY_PREFIX $CONFIG_FLAG
+ - cp -pr config.cache config.status .ext/include ../config_1st
+ - $SETARCH make reconfig
+ - cp -pr config.cache config.status .ext/include ../config_2nd
+ - (cd .. && exec diff -ru config_1st config_2nd)
+ - chmod u+w ..
+ - rm -rf ~/config_2nd
+ - mv ../config_2nd ~
+ - chmod u-w ..
+ - $SETARCH make -s $JOBS
+ - make -s install
+ - |-
+ [ -z "${GEMS_FOR_TEST}" ] ||
+ $RUBY_PREFIX/bin/gem install --no-document $GEMS_FOR_TEST
+ - echo "raise 'do not load ~/.irbrc in test'" > ~/.irbrc
script:
- - "make -s test TESTOPTS=--color=never"
- - "make -s $JOBS test-all -o exts TESTOPTS='-q --color=never --job-status=normal'"
- - "make -s $JOBS test-spec MSPECOPT=-j"
+ - $SETARCH make -s test -o showflags TESTOPTS="${TESTOPTS=$JOBS -q --tty=no}"
+ - travis_wait 50 $SETARCH make -s test-all -o exts TESTOPTS="${TESTOPTS} ${TEST_ALL_OPTS}" RUBYOPT="-w"
+ - $SETARCH make -s test-spec MSPECOPT=-ff # not using `-j` because sometimes `mspec -j` silently dies
+ - $SETARCH make -s -o showflags leaked-globals
# Branch matrix. Not all branches are Travis-ready so we limit branches here.
branches:
only:
- - trunk
- - ruby_2_2
- - ruby_2_3
+ - master
- ruby_2_4
- - /^feature\//
- - /^bug\//
+ - ruby_2_5
+ - ruby_2_6
+ - ruby_2_7
# We want to be notified when something happens.
notifications:
irc:
channels:
- "chat.freenode.net#ruby-core"
- - "chat.freenode.net#ruby-ja"
on_success: change # [always|never|change] # default: always
on_failure: always # [always|never|change] # default: always
template:
- "%{message} by @%{author}: See %{build_url}"
- slack:
- secure: crR7xx7uiv0dEE2tM14umgn0THOknlXoAU1S7W9efKkKUf7bmg87dE7Tii+VKIVvxZGOiIPa6DEbtXsia/yLjC6nsAWQzwRKeeVTcGOvyA5nyPBArLsYjkczxWASHCttqckA20PH75YRZsQErwd/bzvKP/nWGBTbk3sHBLDyEZI=
- on_pull_requests: false
- on_success: change
+ webhooks:
+ urls:
+ - secure: mRsoS/UbqDkKkW5p3AEqM27d4SZnV6Gsylo3bm8T/deltQzTsGzZwrm7OIBXZv0UFZdE68XmPlyHfZFLSP2V9QZ7apXMf9/vw0GtcSe1gchtnjpAPF6lYBn7nMCbVPPx9cS0dwL927fjdRM1vj7IKZ2bk4F0lAJ25R25S6teqdk= # ruby-lang slack: ruby/simpler-alerts-bot (travis)
+ on_success: never
on_failure: always
email:
- ko1c-failure@atdot.net
-
-# Local Variables:
-# mode: YAML
-# coding: utf-8-unix
-# indent-tabs-mode: nil
-# tab-width: 4
-# fill-column: 79
-# default-justification: full
-# End:
diff --git a/BSDL b/BSDL
index a009caefea..66d93598aa 100644
--- a/BSDL
+++ b/BSDL
@@ -4,10 +4,10 @@ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
+ notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/COPYING b/COPYING
index f06056fb45..48e5a96de7 100644
--- a/COPYING
+++ b/COPYING
@@ -2,55 +2,55 @@ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
You can redistribute it and/or modify it under either the terms of the
2-clause BSDL (see the file BSDL), or the conditions below:
- 1. You may make and give away verbatim copies of the source form of the
- software without restriction, provided that you duplicate all of the
- original copyright notices and associated disclaimers.
+1. You may make and give away verbatim copies of the source form of the
+ software without restriction, provided that you duplicate all of the
+ original copyright notices and associated disclaimers.
- 2. You may modify your copy of the software in any way, provided that
- you do at least ONE of the following:
+2. You may modify your copy of the software in any way, provided that
+ you do at least ONE of the following:
- a) place your modifications in the Public Domain or otherwise
- make them Freely Available, such as by posting said
- modifications to Usenet or an equivalent medium, or by allowing
- the author to include your modifications in the software.
+ a. place your modifications in the Public Domain or otherwise
+ make them Freely Available, such as by posting said
+ modifications to Usenet or an equivalent medium, or by allowing
+ the author to include your modifications in the software.
- b) use the modified software only within your corporation or
- organization.
+ b. use the modified software only within your corporation or
+ organization.
- c) give non-standard binaries non-standard names, with
- instructions on where to get the original software distribution.
+ c. give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
- d) make other distribution arrangements with the author.
+ d. make other distribution arrangements with the author.
- 3. You may distribute the software in object code or binary form,
- provided that you do at least ONE of the following:
+3. You may distribute the software in object code or binary form,
+ provided that you do at least ONE of the following:
- a) distribute the binaries and library files of the software,
- together with instructions (in the manual page or equivalent)
- on where to get the original distribution.
+ a. distribute the binaries and library files of the software,
+ together with instructions (in the manual page or equivalent)
+ on where to get the original distribution.
- b) accompany the distribution with the machine-readable source of
- the software.
+ b. accompany the distribution with the machine-readable source of
+ the software.
- c) give non-standard binaries non-standard names, with
- instructions on where to get the original software distribution.
+ c. give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
- d) make other distribution arrangements with the author.
+ d. make other distribution arrangements with the author.
- 4. You may modify and include the part of the software into any other
- software (possibly commercial). But some files in the distribution
- are not written by the author, so that they are not under these terms.
+4. You may modify and include the part of the software into any other
+ software (possibly commercial). But some files in the distribution
+ are not written by the author, so that they are not under these terms.
- For the list of those files and their copying conditions, see the
- file LEGAL.
+ For the list of those files and their copying conditions, see the
+ file LEGAL.
- 5. The scripts and library files supplied as input to or produced as
- output from the software do not automatically fall under the
- copyright of the software, but belong to whomever generated them,
- and may be sold commercially, and may be aggregated with this
- software.
+5. The scripts and library files supplied as input to or produced as
+ output from the software do not automatically fall under the
+ copyright of the software, but belong to whomever generated them,
+ and may be sold commercially, and may be aggregated with this
+ software.
- 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE.
+6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE.
diff --git a/COPYING.ja b/COPYING.ja
index e50d01c8d1..230376bc60 100644
--- a/COPYING.ja
+++ b/COPYING.ja
@@ -2,50 +2,50 @@
ã¾ãŸã¯ä»¥ä¸‹ã«ç¤ºã™æ¡ä»¶ã§æœ¬ãƒ—ログラムをå†é…布ã§ãã¾ã™
2-clause BSDLã«ã¤ã„ã¦ã¯BSDLファイルをå‚ç…§ã—ã¦ä¸‹ã•ã„.
- 1. 複製ã¯åˆ¶é™ãªã自由ã§ã™ï¼Ž
+1. 複製ã¯åˆ¶é™ãªã自由ã§ã™ï¼Ž
- 2. ä»¥ä¸‹ã®æ¡ä»¶ã®ã„ãšã‚Œã‹ã‚’満ãŸã™æ™‚ã«æœ¬ãƒ—ログラムã®ã‚½ãƒ¼ã‚¹ã‚’
- 自由ã«å¤‰æ›´ã§ãã¾ã™ï¼Ž
+2. ä»¥ä¸‹ã®æ¡ä»¶ã®ã„ãšã‚Œã‹ã‚’満ãŸã™æ™‚ã«æœ¬ãƒ—ログラムã®ã‚½ãƒ¼ã‚¹ã‚’
+ 自由ã«å¤‰æ›´ã§ãã¾ã™ï¼Ž
- (a) ãƒãƒƒãƒˆãƒ‹ãƒ¥ãƒ¼ã‚ºã«ãƒã‚¹ãƒˆã—ãŸã‚Šï¼Œä½œè€…ã«å¤‰æ›´ã‚’é€ä»˜ã™ã‚‹
- ãªã©ã®æ–¹æ³•ã§ï¼Œå¤‰æ›´ã‚’公開ã™ã‚‹ï¼Ž
+ a. ãƒãƒƒãƒˆãƒ‹ãƒ¥ãƒ¼ã‚ºã«ãƒã‚¹ãƒˆã—ãŸã‚Šï¼Œä½œè€…ã«å¤‰æ›´ã‚’é€ä»˜ã™ã‚‹
+ ãªã©ã®æ–¹æ³•ã§ï¼Œå¤‰æ›´ã‚’公開ã™ã‚‹ï¼Ž
- (b) 変更ã—ãŸæœ¬ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã‚’è‡ªåˆ†ã®æ‰€å±žã™ã‚‹çµ„織内部ã ã‘ã§
- 使ã†ï¼Ž
+ b. 変更ã—ãŸæœ¬ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã‚’è‡ªåˆ†ã®æ‰€å±žã™ã‚‹çµ„織内部ã ã‘ã§
+ 使ã†ï¼Ž
- (c) 変更点を明示ã—ãŸã†ãˆï¼Œã‚½ãƒ•トウェアã®åå‰ã‚’変更ã™ã‚‹ï¼Ž
- ãã®ã‚½ãƒ•トウェアをé…布ã™ã‚‹æ™‚ã«ã¯å¤‰æ›´å‰ã®æœ¬ãƒ—ログラ
- ãƒ ã‚‚åŒæ™‚ã«é…布ã™ã‚‹ï¼Žã¾ãŸã¯å¤‰æ›´å‰ã®æœ¬ãƒ—ログラムã®ã‚½ãƒ¼
- スã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
+ c. 変更点を明示ã—ãŸã†ãˆï¼Œã‚½ãƒ•トウェアã®åå‰ã‚’変更ã™ã‚‹ï¼Ž
+ ãã®ã‚½ãƒ•トウェアをé…布ã™ã‚‹æ™‚ã«ã¯å¤‰æ›´å‰ã®æœ¬ãƒ—ログラ
+ ãƒ ã‚‚åŒæ™‚ã«é…布ã™ã‚‹ï¼Žã¾ãŸã¯å¤‰æ›´å‰ã®æœ¬ãƒ—ログラムã®ã‚½ãƒ¼
+ スã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
- (d) ãã®ä»–ã®å¤‰æ›´æ¡ä»¶ã‚’作者ã¨åˆæ„ã™ã‚‹ï¼Ž
+ d. ãã®ä»–ã®å¤‰æ›´æ¡ä»¶ã‚’作者ã¨åˆæ„ã™ã‚‹ï¼Ž
- 3. ä»¥ä¸‹ã®æ¡ä»¶ã®ã„ãšã‚Œã‹ã‚’満ãŸã™æ™‚ã«æœ¬ãƒ—ログラムをコンパイ
- ルã—ãŸã‚ªãƒ–ジェクトコードや実行形å¼ã§ã‚‚é…布ã§ãã¾ã™ï¼Ž
+3. ä»¥ä¸‹ã®æ¡ä»¶ã®ã„ãšã‚Œã‹ã‚’満ãŸã™æ™‚ã«æœ¬ãƒ—ログラムをコンパイ
+ ルã—ãŸã‚ªãƒ–ジェクトコードや実行形å¼ã§ã‚‚é…布ã§ãã¾ã™ï¼Ž
- (a) ãƒã‚¤ãƒŠãƒªã‚’å—ã‘å–ã£ãŸäººãŒã‚½ãƒ¼ã‚¹ã‚’入手ã§ãるよã†ã«ï¼Œ
- ソースã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
+ a. ãƒã‚¤ãƒŠãƒªã‚’å—ã‘å–ã£ãŸäººãŒã‚½ãƒ¼ã‚¹ã‚’入手ã§ãるよã†ã«ï¼Œ
+ ソースã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
- (b) 機械å¯èª­ãªã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’添付ã™ã‚‹ï¼Ž
+ b. 機械å¯èª­ãªã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’添付ã™ã‚‹ï¼Ž
- (c) 変更を行ã£ãŸãƒã‚¤ãƒŠãƒªã¯åå‰ã‚’変更ã—ãŸã†ãˆï¼Œã‚ªãƒªã‚¸ãƒŠ
- ルã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
+ c. 変更を行ã£ãŸãƒã‚¤ãƒŠãƒªã¯åå‰ã‚’変更ã—ãŸã†ãˆï¼Œã‚ªãƒªã‚¸ãƒŠ
+ ルã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
- (d) ãã®ä»–ã®é…布æ¡ä»¶ã‚’作者ã¨åˆæ„ã™ã‚‹ï¼Ž
+ d. ãã®ä»–ã®é…布æ¡ä»¶ã‚’作者ã¨åˆæ„ã™ã‚‹ï¼Ž
- 4. ä»–ã®ãƒ—ログラムã¸ã®å¼•用ã¯ã„ã‹ãªã‚‹ç›®çš„ã§ã‚れ自由ã§ã™ï¼ŽãŸ
- ã ã—,本プログラムã«å«ã¾ã‚Œã‚‹ä»–ã®ä½œè€…ã«ã‚ˆã‚‹ã‚³ãƒ¼ãƒ‰ã¯ï¼Œã
- れãžã‚Œã®ä½œè€…ã®æ„å‘ã«ã‚ˆã‚‹åˆ¶é™ãŒåŠ ãˆã‚‰ã‚Œã‚‹å ´åˆãŒã‚りã¾ã™ï¼Ž
+4. ä»–ã®ãƒ—ログラムã¸ã®å¼•用ã¯ã„ã‹ãªã‚‹ç›®çš„ã§ã‚れ自由ã§ã™ï¼ŽãŸ
+ ã ã—,本プログラムã«å«ã¾ã‚Œã‚‹ä»–ã®ä½œè€…ã«ã‚ˆã‚‹ã‚³ãƒ¼ãƒ‰ã¯ï¼Œã
+ れãžã‚Œã®ä½œè€…ã®æ„å‘ã«ã‚ˆã‚‹åˆ¶é™ãŒåŠ ãˆã‚‰ã‚Œã‚‹å ´åˆãŒã‚りã¾ã™ï¼Ž
- ãれらファイルã®ä¸€è¦§ã¨ãれãžã‚Œã®é…布æ¡ä»¶ãªã©ã«ä»˜ã„ã¦ã¯
- LEGALファイルをå‚ç…§ã—ã¦ãã ã•ã„.
+ ãれらファイルã®ä¸€è¦§ã¨ãれãžã‚Œã®é…布æ¡ä»¶ãªã©ã«ä»˜ã„ã¦ã¯
+ LEGALファイルをå‚ç…§ã—ã¦ãã ã•ã„.
- 5. 本プログラムã¸ã®å…¥åŠ›ã¨ãªã‚‹ã‚¹ã‚¯ãƒªãƒ—トãŠã‚ˆã³ï¼Œæœ¬ãƒ—ログラ
- ムã‹ã‚‰ã®å‡ºåŠ›ã®æ¨©åˆ©ã¯æœ¬ãƒ—ログラムã®ä½œè€…ã§ã¯ãªã,ãれãž
- れã®å…¥å‡ºåŠ›ã‚’ç”Ÿæˆã—ãŸäººã«å±žã—ã¾ã™ï¼Žã¾ãŸï¼Œæœ¬ãƒ—ログラムã«
- 組ã¿è¾¼ã¾ã‚Œã‚‹ãŸã‚ã®æ‹¡å¼µãƒ©ã‚¤ãƒ–ラリã«ã¤ã„ã¦ã‚‚åŒæ§˜ã§ã™ï¼Ž
+5. 本プログラムã¸ã®å…¥åŠ›ã¨ãªã‚‹ã‚¹ã‚¯ãƒªãƒ—トãŠã‚ˆã³ï¼Œæœ¬ãƒ—ログラ
+ ムã‹ã‚‰ã®å‡ºåŠ›ã®æ¨©åˆ©ã¯æœ¬ãƒ—ログラムã®ä½œè€…ã§ã¯ãªã,ãれãž
+ れã®å…¥å‡ºåŠ›ã‚’ç”Ÿæˆã—ãŸäººã«å±žã—ã¾ã™ï¼Žã¾ãŸï¼Œæœ¬ãƒ—ログラムã«
+ 組ã¿è¾¼ã¾ã‚Œã‚‹ãŸã‚ã®æ‹¡å¼µãƒ©ã‚¤ãƒ–ラリã«ã¤ã„ã¦ã‚‚åŒæ§˜ã§ã™ï¼Ž
- 6. 本プログラムã¯ç„¡ä¿è¨¼ã§ã™ï¼Žä½œè€…ã¯æœ¬ãƒ—ログラムをサãƒãƒ¼ãƒˆ
- ã™ã‚‹æ„å¿—ã¯ã‚りã¾ã™ãŒï¼Œãƒ—ログラム自身ã®ãƒã‚°ã‚ã‚‹ã„ã¯æœ¬ãƒ—
- ログラムã®å®Ÿè¡Œãªã©ã‹ã‚‰ç™ºç”Ÿã™ã‚‹ã„ã‹ãªã‚‹æå®³ã«å¯¾ã—ã¦ã‚‚責
- 任をæŒã¡ã¾ã›ã‚“.
+6. 本プログラムã¯ç„¡ä¿è¨¼ã§ã™ï¼Žä½œè€…ã¯æœ¬ãƒ—ログラムをサãƒãƒ¼ãƒˆ
+ ã™ã‚‹æ„å¿—ã¯ã‚りã¾ã™ãŒï¼Œãƒ—ログラム自身ã®ãƒã‚°ã‚ã‚‹ã„ã¯æœ¬ãƒ—
+ ログラムã®å®Ÿè¡Œãªã©ã‹ã‚‰ç™ºç”Ÿã™ã‚‹ã„ã‹ãªã‚‹æå®³ã«å¯¾ã—ã¦ã‚‚責
+ 任をæŒã¡ã¾ã›ã‚“.
diff --git a/LEGAL b/LEGAL
index 4a9858f36e..2a7964e771 100644
--- a/LEGAL
+++ b/LEGAL
@@ -1,100 +1,248 @@
-LEGAL NOTICE INFORMATION
-------------------------
+# -*- rdoc -*-
+
+= LEGAL NOTICE INFORMATION
+--------------------------
All the files in this distribution are covered under either the Ruby's
license (see the file COPYING) or public-domain except some files
mentioned below.
-ccan/build_assert/build_assert.h
-ccan/check_type/check_type.h
-ccan/container_of/container_of.h
-ccan/str/str.h
+[addr2line.c]
- These files are licensed under the CC0.
+ A part of this file is from FreeBSD.
- https://creativecommons.org/choose/zero/
+ >>>
+ Copyright (c) 1986, 1988, 1991, 1993::
+ The Regents of the University of California. All rights reserved.
-ccan/list/list.h
+ (c) UNIX System Laboratories, Inc.
- This file is licensed under the MIT License.
+ All or some portions of this file are derived from material licensed
+ to the University of California by American Telephone and Telegraph
+ Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ the permission of UNIX System Laboratories, Inc.
- 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:
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
- 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/ruby/oniguruma.h:
-regcomp.c:
-regenc.[ch]:
-regerror.c:
-regexec.c:
-regint.h:
-regparse.[ch]:
-enc/ascii.c
-enc/big5.c
-enc/cp949.c
-enc/emacs_mule.c
-enc/encdb.c
-enc/euc_jp.c
-enc/euc_kr.c
-enc/euc_tw.c
-enc/gb18030.c
-enc/gb2312.c
-enc/gbk.c
-enc/iso_8859_1.c
-enc/iso_8859_10.c
-enc/iso_8859_11.c
-enc/iso_8859_13.c
-enc/iso_8859_14.c
-enc/iso_8859_15.c
-enc/iso_8859_16.c
-enc/iso_8859_2.c
-enc/iso_8859_3.c
-enc/iso_8859_4.c
-enc/iso_8859_5.c
-enc/iso_8859_6.c
-enc/iso_8859_7.c
-enc/iso_8859_8.c
-enc/iso_8859_9.c
-enc/koi8_r.c
-enc/koi8_u.c
-enc/shift_jis.c
-enc/unicode.c
-enc/us_ascii.c
-enc/utf_16be.c
-enc/utf_16le.c
-enc/utf_32be.c
-enc/utf_32le.c
-enc/utf_8.c
-enc/windows_1251.c
-
-Oniguruma ---- (C) K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
-
-http://www.geocities.jp/kosako3/oniguruma/
-http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/oniguruma/
-http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
-
- When this software is partly used or it is distributed with Ruby,
- this of Ruby follows the license of Ruby.
-
-enc/trans/GB/GB12345%UCS.src:
-enc/trans/GB/UCS%GB12345.src:
-enc/trans/GB/GB2312%UCS.src:
-enc/trans/GB/UCS%GB2312.src:
+ @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+
+
+[ccan/build_assert/build_assert.h]
+[ccan/check_type/check_type.h]
+[ccan/container_of/container_of.h]
+[ccan/str/str.h]
+
+ These files are licensed under the {CC0}[https://creativecommons.org/choose/zero/].
+
+[ccan/list/list.h]
+
+ This file is licensed under the {MIT License}[rdoc-label:label-MIT+License].
+
+[coroutine]
+
+ Unless otherwise specified, these files are licensed under the
+ {MIT License}[rdoc-label:label-MIT+License].
+
+[include/ruby/onigmo.h]
+[include/ruby/oniguruma.h]
+[regcomp.c]
+[regenc.c]
+[regenc.h]
+[regerror.c]
+[regexec.c]
+[regint.h]
+[regparse.c]
+[regparse.h]
+[enc/ascii.c]
+[enc/big5.c]
+[enc/cp949.c]
+[enc/emacs_mule.c]
+[enc/encdb.c]
+[enc/euc_jp.c]
+[enc/euc_kr.c]
+[enc/euc_tw.c]
+[enc/gb18030.c]
+[enc/gb2312.c]
+[enc/gbk.c]
+[enc/iso_8859_1.c]
+[enc/iso_8859_10.c]
+[enc/iso_8859_11.c]
+[enc/iso_8859_13.c]
+[enc/iso_8859_14.c]
+[enc/iso_8859_15.c]
+[enc/iso_8859_16.c]
+[enc/iso_8859_2.c]
+[enc/iso_8859_3.c]
+[enc/iso_8859_4.c]
+[enc/iso_8859_5.c]
+[enc/iso_8859_6.c]
+[enc/iso_8859_7.c]
+[enc/iso_8859_8.c]
+[enc/iso_8859_9.c]
+[enc/koi8_r.c]
+[enc/koi8_u.c]
+[enc/shift_jis.c]
+[enc/unicode.c]
+[enc/us_ascii.c]
+[enc/utf_16be.c]
+[enc/utf_16le.c]
+[enc/utf_32be.c]
+[enc/utf_32le.c]
+[enc/utf_8.c]
+[enc/windows_1251.c]
+[enc/windows_31j.c]
+
+ Onigmo (Oniguruma-mod) LICENSE
+
+ >>>
+ Copyright (c) 2002-2009:: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ Copyright (c) 2011-2014:: K.Takata <kentkt AT csc DOT jp>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ Oniguruma LICENSE
+
+ >>>
+ Copyright (c) 2002-2009:: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ * https://github.com/k-takata/Onigmo/
+ * https://github.com/kkos/oniguruma
+ * https://svnweb.freebsd.org/ports/head/devel/oniguruma/
+ When this software is partly used or it is distributed with Ruby,
+ this of Ruby follows the license of Ruby.
+
+[enc/windows_1250.c]
+[enc/windows_1252.c]
+
+ >>>
+ Copyright (c) 2006-2007:: Byte <byte AT mail DOT kna DOT ru>
+ K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+[enc/cesu_8.c]
+[enc/windows_1253.c]
+[enc/windows_1254.c]
+[enc/windows_1257.c]
+
+ >>>
+ Copyright (c) 2002-2007:: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+[enc/trans/GB/GB12345%UCS.src]
+[enc/trans/GB/UCS%GB12345.src]
+[enc/trans/GB/GB2312%UCS.src]
+[enc/trans/GB/UCS%GB2312.src]
+
+ These files have this explanatory texts.
+
+ >>>
This mapping data was created from files provided by Unicode, Inc.
(The Unicode Consortium). The files were used to create a product supporting
Unicode, as explicitly permitted in the files' copyright notices.
@@ -102,56 +250,93 @@ enc/trans/GB/UCS%GB2312.src:
files for any particular purpose, and has ceased to publish the files many
years ago.
-enc/trans/JIS/JISX0201-KANA%UCS.src:
-enc/trans/JIS/JISX0208@1990%UCS.src:
-enc/trans/JIS/JISX0212%UCS.src:
-enc/trans/JIS/UCS%JISX0201-KANA.src:
-enc/trans/JIS/UCS%JISX0208@1990.src:
-enc/trans/JIS/UCS%JISX0212.src:
+[enc/trans/JIS/JISX0201-KANA%UCS.src]
+[enc/trans/JIS/JISX0208\@1990%UCS.src]
+[enc/trans/JIS/JISX0212%UCS.src]
+[enc/trans/JIS/UCS%JISX0201-KANA.src]
+[enc/trans/JIS/UCS%JISX0208@1990.src]
+[enc/trans/JIS/UCS%JISX0212.src]
+ These files are copyrighted as the following.
+
+ >>>
© 2015 Unicode®, Inc.
+
For terms of use, see http://www.unicode.org/terms_of_use.html
-enc/trans/JIS/JISX0213-1%UCS@BMP.src:
-enc/trans/JIS/JISX0213-1%UCS@SIP.src:
-enc/trans/JIS/JISX0213-2%UCS@BMP.src:
-enc/trans/JIS/JISX0213-2%UCS@SIP.src:
+[enc/trans/JIS/JISX0213-1%UCS@BMP.src]
+[enc/trans/JIS/JISX0213-1%UCS@SIP.src]
+[enc/trans/JIS/JISX0213-2%UCS@BMP.src]
+[enc/trans/JIS/JISX0213-2%UCS@SIP.src]
+
+ These files are copyrighted as the following.
+
+ >>>
+ Copyright (C) 2001:: earthian@tama.or.jp, All Rights Reserved.
+ Copyright (C) 2001:: I'O, All Rights Reserved.
+ Copyright (C) 2006:: Project X0213, All Rights Reserved.
+ You can use, modify, distribute this table freely.
- Copyright (C) 2001 earthian@tama.or.jp, All Rights Reserved.
- Copyright (C) 2001 I'O, All Rights Reserved.
- Copyright (C) 2006 Project X0213, All Rights Reserved.
- You can use, modify, distribute this table freely.
+[enc/trans/JIS/UCS@BMP%JISX0213-1.src]
+[enc/trans/JIS/UCS@BMP%JISX0213-2.src]
+[enc/trans/JIS/UCS@SIP%JISX0213-1.src]
+[enc/trans/JIS/UCS@SIP%JISX0213-2.src]
-enc/trans/JIS/UCS@BMP%JISX0213-1.src:
-enc/trans/JIS/UCS@BMP%JISX0213-2.src:
-enc/trans/JIS/UCS@SIP%JISX0213-1.src:
-enc/trans/JIS/UCS@SIP%JISX0213-2.src:
+ These files are copyrighted as the following.
- Copyright (C) 2001 earthian@tama.or.jp, All Rights Reserved.
- Copyright (C) 2001 I'O, All Rights Reserved.
- You can use, modify, distribute this table freely.
+ >>>
+ Copyright (C) 2001:: earthian@tama.or.jp, All Rights Reserved.
+ Copyright (C) 2001:: I'O, All Rights Reserved.
+ You can use, modify, distribute this table freely.
-configure:
+[enc/trans/ucm/glibc-BIG5-2.3.3.ucm]
+[enc/trans/ucm/glibc-BIG5HKSCS-2.3.3.ucm]
+
+ >>>
+ Copyright (C) 2001-2005:: International Business Machines
+ Corporation and others. All Rights Reserved.
+
+[enc/trans/ucm/windows-950-2000.ucm]
+[enc/trans/ucm/windows-950_hkscs-2001.ucm]
+
+ >>>
+ Copyright (C) 2001-2002:: International Business Machines
+ Corporation and others. All Rights Reserved.
+
+
+[configure]
This file is free software.
- Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+ >>>
+ Copyright (C) 1992-1996, 1998-2012:: Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
-tool/config.guess:
-tool/config.sub:
+[aclocal.m4]
+
+ This file is free software.
+
+ >>>
+ Copyright (C) 1996-2020:: Free Software Foundation, Inc.
+
+ This file 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.
+
+[tool/config.guess]
+[tool/config.sub]
As long as you distribute these files with the file configure, they
are covered under the Ruby's license.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
- Free Software Foundation, Inc.
+ >>>
+ Copyright 1992-2018:: Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ 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
@@ -160,54 +345,57 @@ tool/config.sub:
General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
As a special exception to the GNU General Public License, if you
distribute this file as part of a program that contains a
configuration script generated by Autoconf, you may include it under
- the same distribution terms that you use for the rest of that program.
+ the same distribution terms that you use for the rest of that
+ program. This Exception is an additional permission under section 7
+ of the GNU General Public License, version 3 ("GPLv3").
-parse.c:
+[parse.c]
+[parse.h]
- This file is licensed under the GPL, but is incorporated into Ruby and
+ These files are licensed under the GPL, but are incorporated into Ruby and
redistributed under the terms of the Ruby license, as permitted by the
exception to the GPL below.
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
+ >>>
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018:: 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 2, or (at your option)
- any later version.
+ 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.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ 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.
+ 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. */
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison.
-util.c (partly):
+[missing/dtoa.c]
- Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ This file is under these licenses.
+
+ >>>
+ Copyright (c) 1991, 2000, 2001:: by Lucent Technologies.
Permission to use, copy, modify, and distribute this software for any
purpose without fee is hereby granted, provided that this entire notice
@@ -220,71 +408,73 @@ util.c (partly):
REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
-win32/win32.[ch]:
+ >>>
+ Copyright (c) 2004-2008:: David Schultz <das@FreeBSD.ORG>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+[win32/win32.c]
+[include/ruby/win32.h]
You can apply the Artistic License to these files. (or GPL,
alternatively)
- Copyright (c) 1993, Intergraph Corporation
+ >>>
+ Copyright (c) 1993:: Intergraph Corporation
You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the perl README file.
-util.c (partly):
-
- Copyright (c) 2004-2008 David Schultz <das@FreeBSD.ORG>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-random.c
+[missing/mt19937.c]
This file is under the new-style BSD license.
- A C-program for MT19937, with initialization improved 2002/2/10.
- Coded by Takuji Nishimura and Makoto Matsumoto.
+ >>>
+ A C-program for MT19937, with initialization improved 2002/2/10.::
+ Coded by Takuji Nishimura and Makoto Matsumoto.
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
+ Copyright (C) 1997 - 2002:: Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
- 3. The names of its contributors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -303,12 +493,15 @@ random.c
http://www.math.keio.ac.jp/matumoto/emt.html
email: matumoto@math.keio.ac.jp
-vm_dump.c:procstat_vm
+ The Wayback Machine url: http://web.archive.org/web/19990429082237/http://www.math.keio.ac.jp/matumoto/emt.html
+
+[missing/procstat_vm.c]
This file is under the new-style BSD license.
- Copyright (c) 2007 Robert N. M. Watson
- All rights reserved.
+ >>>
+ Copyright (c) 2007:: Robert N. M. Watson
+ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -333,146 +526,69 @@ vm_dump.c:procstat_vm
$FreeBSD: head/usr.bin/procstat/procstat_vm.c 261780 2014-02-11 21:57:37Z jhb $
-vsnprintf.c:
+[vsnprintf.c]
- This file is under the old-style BSD license. Note that the
- paragraph 3 below is now null and void.
+ This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license].
- Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
+ >>>
+ Copyright (c) 1990, 1993::
+ The Regents of the University of California. All rights reserved.
This code is derived from software contributed to Berkeley by
Chris Torek.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
- IMPORTANT NOTE:
- --------------
- From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
- paragraph 3 above is now null and void.
-
-st.c:
-strftime.c:
-include/ruby/st.h:
-missing/acosh.c:
-missing/alloca.c:
-missing/dup2.c:
-missing/erf.c:
-missing/finite.c:
-missing/hypot.c:
-missing/isinf.c:
-missing/isnan.c:
-missing/lgamma_r.c:
-missing/memcmp.c:
-missing/memmove.c:
-missing/strchr.c:
-missing/strerror.c:
-missing/strstr.c:
-missing/tgamma.c:
-ext/date/date_strftime.c:
-ext/digest/sha1/sha1.[ch]:
-ext/sdbm/_sdbm.c:
-ext/sdbm/sdbm.h:
+[st.c]
+[strftime.c]
+[include/ruby/st.h]
+[missing/acosh.c]
+[missing/alloca.c]
+[missing/dup2.c]
+[missing/erf.c]
+[missing/finite.c]
+[missing/hypot.c]
+[missing/isinf.c]
+[missing/isnan.c]
+[missing/lgamma_r.c]
+[missing/memcmp.c]
+[missing/memmove.c]
+[missing/strchr.c]
+[missing/strerror.c]
+[missing/strstr.c]
+[missing/tgamma.c]
+[ext/date/date_strftime.c]
+[ext/digest/sha1/sha1.c]
+[ext/digest/sha1/sha1.h]
These files are all under public domain.
-missing/crypt.c:
+[missing/crypt.c]
- This file is under the old-style BSD license. Note that the
- paragraph 3 below is now null and void.
+ This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license].
- Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
+ >>>
+ Copyright (c) 1989, 1993::
+ The Regents of the University of California. All rights reserved.
This code is derived from software contributed to Berkeley by
Tom Truscott.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-missing/setproctitle.c
+[missing/setproctitle.c]
- This file is under the old-style BSD license. Note that the
- paragraph 3 below is now null and void.
+ This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license].
- Copyright 2003 Damien Miller
- Copyright (c) 1983, 1995-1997 Eric P. Allman
- Copyright (c) 1988, 1993
- The Regents of the University of California. All rights reserved.
+ >>>
+ Copyright 2003:: Damien Miller
+ Copyright (c) 1983, 1995-1997:: Eric P. Allman
+ Copyright (c) 1988, 1993::
+ The Regents of the University of California. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-missing/strlcat.c
-missing/strlcpy.c
+[missing/strlcat.c]
+[missing/strlcpy.c]
These files are under an ISC-style license.
- Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ >>>
+ Copyright (c) 1998, 2015:: Todd C. Miller <Todd.Miller@courtesan.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -486,23 +602,26 @@ missing/strlcpy.c
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-missing/langinfo.c
+[missing/langinfo.c]
This file is from http://www.cl.cam.ac.uk/~mgk25/ucs/langinfo.c.
Ruby uses a modified version. The file contains the following
author/copyright notice:
- Markus.Kuhn@cl.cam.ac.uk -- 2002-03-11
- Permission to use, copy, modify, and distribute this software
- for any purpose and without fee is hereby granted. The author
- disclaims all warranties with regard to this software.
+ >>>
+ Markus.Kuhn@cl.cam.ac.uk -- 2002-03-11::
+ Permission to use, copy, modify, and distribute this software
+ for any purpose and without fee is hereby granted. The author
+ disclaims all warranties with regard to this software.
-ext/digest/md5/md5.[ch]:
+[ext/digest/md5/md5.c]
+[ext/digest/md5/md5.h]
These files are under the following license. Ruby uses modified
versions of them.
- Copyright (C) 1999, 2000 Aladdin Enterprises. All rights reserved.
+ >>>
+ Copyright (C) 1999, 2000:: Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -523,23 +642,27 @@ ext/digest/md5/md5.[ch]:
L. Peter Deutsch
ghost@aladdin.com
-ext/digest/rmd160/rmd160.[ch]:
+[ext/digest/rmd160/rmd160.c]
+[ext/digest/rmd160/rmd160.h]
These files have the following copyright information, and by the
author we are allowed to use it under the new-style BSD license.
- AUTHOR: Antoon Bosselaers, ESAT-COSIC
+ >>>
+ AUTHOR:: Antoon Bosselaers, ESAT-COSIC
(Arranged for libc by Todd C. Miller)
- DATE: 1 March 1996
+ DATE:: 1 March 1996
- Copyright (c) Katholieke Universiteit Leuven
+ Copyright (c):: Katholieke Universiteit Leuven
1996, All Rights Reserved
-ext/digest/sha2/sha2.[ch]:
+[ext/digest/sha2/sha2.c]
+[ext/digest/sha2/sha2.h]
These files are under the new-style BSD license.
- Copyright 2000 Aaron D. Gifford. All rights reserved.
+ >>>
+ Copyright 2000:: Aaron D. Gifford. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -565,96 +688,123 @@ ext/digest/sha2/sha2.[ch]:
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-ext/json/generator/generator.c:
+[ext/json/generator/generator.c]
+
+ The file contains the following copyright notice.
- Copyright 2001-2004 Unicode, Inc.
+ >>>
+ Copyright 2001-2004:: Unicode, Inc.
- Disclaimer
+ Disclaimer::
- This source code is provided as is by Unicode, Inc. No claims are
- made as to fitness for any particular purpose. No warranties of any
- kind are expressed or implied. The recipient agrees to determine
- applicability of information provided. If this file has been
- purchased on magnetic or optical media from Unicode, Inc., the
- sole remedy for any claim will be exchange of defective media
- within 90 days of receipt.
+ This source code is provided as is by Unicode, Inc. No claims are
+ made as to fitness for any particular purpose. No warranties of any
+ kind are expressed or implied. The recipient agrees to determine
+ applicability of information provided. If this file has been
+ purchased on magnetic or optical media from Unicode, Inc., the
+ sole remedy for any claim will be exchange of defective media
+ within 90 days of receipt.
- Limitations on Rights to Redistribute This Code
+ Limitations on Rights to Redistribute This Code::
- Unicode, Inc. hereby grants the right to freely use the information
- supplied in this file in the creation of products supporting the
- Unicode Standard, and to make copies of this file in any form
- for internal or external distribution as long as this notice
- remains attached.
+ Unicode, Inc. hereby grants the right to freely use the information
+ supplied in this file in the creation of products supporting the
+ Unicode Standard, and to make copies of this file in any form
+ for internal or external distribution as long as this notice
+ remains attached.
-ext/nkf/nkf-utf8/config.h:
-ext/nkf/nkf-utf8/nkf.c:
-ext/nkf/nkf-utf8/utf8tbl.c:
+[ext/nkf/nkf-utf8/config.h]
+[ext/nkf/nkf-utf8/nkf.c]
+[ext/nkf/nkf-utf8/utf8tbl.c]
These files are under the following license. So to speak, it is
copyrighted semi-public-domain software.
- Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
- Everyone is permitted to do anything on this program
- including copying, modifying, improving,
- as long as you don't try to pretend that you wrote it.
- i.e., the above copyright notice has to appear in all copies.
- Binary distribution requires original version messages.
- You don't have to ask before copying, redistribution or publishing.
- THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
-
-ext/psych:
-test/psych:
-
- Copyright 2009 Aaron Patterson, et al.
-
- 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.
-
-ext/psych/yaml:
-
- Copyright (c) 2006 Kirill Simonov
-
- 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.
-
-ext/socket/addrinfo.h:
-ext/socket/getaddrinfo.c:
-ext/socket/getnameinfo.c:
+ >>>
+ Copyright (C) 1987:: Fujitsu LTD. (Itaru ICHIKAWA)
+
+ Everyone is permitted to do anything on this program
+ including copying, modifying, improving,
+ as long as you don't try to pretend that you wrote it.
+ i.e., the above copyright notice has to appear in all copies.
+ Binary distribution requires original version messages.
+ You don't have to ask before copying, redistribution or publishing.
+ THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+
+[ext/psych]
+[test/psych]
+
+ The files under these directories are under the following license, except for
+ ext/psych/yaml.
+
+ >>>
+ Copyright 2009:: Aaron Patterson, et al.
+
+ 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.
+
+[ext/psych/yaml]
+
+ The files under this directory are under the following license.
+
+ >>>
+ Copyright (c) 2006:: Kirill Simonov
+
+ 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.
+
+[ext/pty/pty.c]
+
+ >>>
+ C) Copyright 1998:: by Akinori Ito.
+
+ This software may be redistributed freely for this purpose, in full
+ or in part, provided that this entire copyright notice is included
+ on any copies of this software and applications and derivations thereof.
+
+ This software is provided on an "as is" basis, without warranty of any
+ kind, either expressed or implied, as to any matter including, but not
+ limited to warranty of fitness of purpose, or merchantability, or
+ results obtained from use of this software.
+
+[ext/socket/addrinfo.h]
+[ext/socket/getaddrinfo.c]
+[ext/socket/getnameinfo.c]
These files are under the new-style BSD license.
- Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ >>>
+ Copyright (C) 1995, 1996, 1997, 1998, and 1999:: WIDE Project.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -681,31 +831,35 @@ ext/socket/getnameinfo.c:
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-ext/win32ole/win32ole.c:
+[ext/win32ole/win32ole.c]
You can apply the Artistic License to this file. (or GPL,
alternatively)
- (c) 1995 Microsoft Corporation. All rights reserved.
+ >>>
+ (c) 1995:: Microsoft Corporation. All rights reserved.
Developed by ActiveWare Internet Corp., http://www.ActiveWare.com
- Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy
+ Other modifications Copyright (c) 1997, 1998:: by Gurusamy Sarathy
<gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>
You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the README file
of the Perl distribution.
-lib/rdoc/generator/template/darkfish/css/fonts.css:
+ The Wayback Machine url: http://web.archive.org/web/19970607104352/http://www.activeware.com:80/
- This file is licensed under the SIL Open Font License.
+[lib/rdoc/generator/template/darkfish/css/fonts.css]
- http://scripts.sil.org/OFL
+ This file is licensed under the {SIL Open Font License}[http://scripts.sil.org/OFL].
-spec/mspec:
-spec/ruby:
+[spec/mspec]
+[spec/ruby]
- Copyright (c) 2008 Engine Yard, Inc. All rights reserved.
+ The files under these directories are under the following license.
+
+ >>>
+ Copyright (c) 2008:: Engine Yard, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -728,89 +882,170 @@ spec/ruby:
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
-lib/rubygems.rb:
-lib/rubygems:
-test/rubygems:
-
- RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim
- Weirich and others. You can redistribute it and/or modify it under
- either the terms of the MIT license (see the file MIT.txt), or the
- conditions below:
-
- 1. You may make and give away verbatim copies of the source form of the
- software without restriction, provided that you duplicate all of the
- original copyright notices and associated disclaimers.
-
- 2. You may modify your copy of the software in any way, provided that
- you do at least ONE of the following:
+[lib/rubygems.rb]
+[lib/rubygems]
+[test/rubygems]
- a. place your modifications in the Public Domain or otherwise
- make them Freely Available, such as by posting said
- modifications to Usenet or an equivalent medium, or by allowing
- the author to include your modifications in the software.
+ RubyGems is under the following license.
- b. use the modified software only within your corporation or
- organization.
-
- c. give non-standard executables non-standard names, with
- instructions on where to get the original software distribution.
-
- d. make other distribution arrangements with the author.
-
- 3. You may distribute the software in object code or executable
- form, provided that you do at least ONE of the following:
-
- a. distribute the executables and library files of the software,
- together with instructions (in the manual page or equivalent)
- on where to get the original distribution.
-
- b. accompany the distribution with the machine-readable source of
- the software.
-
- c. give non-standard executables non-standard names, with
- instructions on where to get the original software distribution.
-
- d . make other distribution arrangements with the author.
-
- 4. You may modify and include the part of the software into any other
- software (possibly commercial).
-
- 5. The scripts and library files supplied as input to or produced as
- output from the software do not automatically fall under the
- copyright of the software, but belong to whomever generated them,
- and may be sold commercially, and may be aggregated with this
- software.
-
- 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE.
-
-lib/bundler:
-lib/bundler.rb:
-lib/bundler.gemspec:
-spec/bundler:
-
- Portions copyright (c) 2010 Andre Arko
- Portions copyright (c) 2009 Engine Yard
-
- MIT License
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ >>>
+ RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim
+ Weirich and others. You can redistribute it and/or modify it under
+ either the terms of the {MIT license}[rdoc-label:label-MIT+License], or the conditions
+ below:
+
+ 1. You may make and give away verbatim copies of the source form of the
+ software without restriction, provided that you duplicate all of the
+ original copyright notices and associated disclaimers.
+
+ 2. You may modify your copy of the software in any way, provided that
+ you do at least ONE of the following:
+
+ a. place your modifications in the Public Domain or otherwise
+ make them Freely Available, such as by posting said
+ modifications to Usenet or an equivalent medium, or by allowing
+ the author to include your modifications in the software.
+
+ b. use the modified software only within your corporation or
+ organization.
+
+ c. give non-standard executables non-standard names, with
+ instructions on where to get the original software distribution.
+
+ d. make other distribution arrangements with the author.
+
+ 3. You may distribute the software in object code or executable
+ form, provided that you do at least ONE of the following:
+
+ a. distribute the executables and library files of the software,
+ together with instructions (in the manual page or equivalent)
+ on where to get the original distribution.
+
+ b. accompany the distribution with the machine-readable source of
+ the software.
+
+ c. give non-standard executables non-standard names, with
+ instructions on where to get the original software distribution.
+
+ d. make other distribution arrangements with the author.
+
+ 4. You may modify and include the part of the software into any other
+ software (possibly commercial).
+
+ 5. The scripts and library files supplied as input to or produced as
+ output from the software do not automatically fall under the
+ copyright of the software, but belong to whomever generated them,
+ and may be sold commercially, and may be aggregated with this
+ software.
+
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+[lib/bundler]
+[lib/bundler.rb]
+[lib/bundler.gemspec]
+[spec/bundler]
+[man/bundle-*,gemfile.*]
+
+ Bundler is under the following license.
+
+ >>>
+ Portions copyright (c) 2010:: Andre Arko
+ Portions copyright (c) 2009:: Engine Yard
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
+[lib/did_you_mean]
+[lib/did_you_mean.rb]
+[test/did_you_mean]
+
+ did_you_mean is under the following license.
+
+ >>>
+ Copyright (c) 2014-2016 Yuki Nishijima
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
+[benchmark/so_ackermann.rb]
+[benchmark/so_array.rb]
+[benchmark/so_binary_trees.rb]
+[benchmark/so_concatenate.rb]
+[benchmark/so_count_words.yml]
+[benchmark/so_exception.rb]
+[benchmark/so_fannkuch.rb]
+[benchmark/so_fasta.rb]
+[benchmark/so_k_nucleotide.yml]
+[benchmark/so_lists.rb]
+[benchmark/so_mandelbrot.rb]
+[benchmark/so_matrix.rb]
+[benchmark/so_meteor_contest.rb]
+[benchmark/so_nbody.rb]
+[benchmark/so_nested_loop.rb]
+[benchmark/so_nsieve.rb]
+[benchmark/so_nsieve_bits.rb]
+[benchmark/so_object.rb]
+[benchmark/so_partial_sums.rb]
+[benchmark/so_pidigits.rb]
+[benchmark/so_random.rb]
+[benchmark/so_reverse_complement.yml]
+[benchmark/so_sieve.rb]
+[benchmark/so_spectralnorm.rb]
+
+ These files are very old copy of then-called "The Great Computer Language
+ Shootout". LEGAL SITUATION OF THESE FILES ARE UNCLEAR because the original
+ site has been lost. Upstream diverged to delete several benchmarks listed
+ above.
+
+== MIT License
+>>>
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+== Old-style BSD license
+>>>
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ IMPORTANT NOTE::
+
+ From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
+ paragraph 3 above is now null and void.
diff --git a/Makefile.in b/Makefile.in
deleted file mode 100644
index 7880fee798..0000000000
--- a/Makefile.in
+++ /dev/null
@@ -1,538 +0,0 @@
-SHELL = /bin/sh
-NULLCMD = @NULLCMD@
-n=$(NULLCMD)
-ECHO1 = $(V:1=$n)
-RUNCMD = $(SHELL)
-CDPATH = .
-CHDIR = @CHDIR@
-exec = exec
-NULL = /dev/null
-PATH_SEPARATOR = @PATH_SEPARATOR@
-
-#### Start of system configuration section. ####
-
-srcdir = @srcdir@
-top_srcdir = $(srcdir)
-hdrdir = $(srcdir)/include
-PLATFORM_DIR = @PLATFORM_DIR@
-
-CC = @CC@
-CPP = @CPP@
-LD = @LD@
-YACC = bison
-PURIFY =
-AUTOCONF = autoconf
-ACLOCAL = aclocal
-CONFIGURE = @CONFIGURE@
-@SET_MAKE@
-MKFILES = @MAKEFILES@
-BASERUBY = @BASERUBY@
-HAVE_BASERUBY = @HAVE_BASERUBY@
-TEST_RUNNABLE = @TEST_RUNNABLE@
-CROSS_COMPILING = @CROSS_COMPILING@
-DOXYGEN = @DOXYGEN@
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-sbindir = @sbindir@
-libdir = @libdir@
-libexecdir = @libexecdir@
-datarootdir = @datarootdir@
-datadir = @datadir@
-arch = @arch@
-sitearch = @sitearch@
-sitedir = @sitedir@
-archlibdir = @archlibdir@
-ruby_version = @ruby_version@
-
-TESTUI = console
-TESTS =
-INSTALLDOC = @INSTALLDOC@
-DOCTARGETS = @RDOCTARGET@ @CAPITARGET@
-
-EXTOUT = @EXTOUT@
-arch_hdrdir = $(EXTOUT)/include/$(arch)
-VPATH = $(arch_hdrdir)/ruby:$(hdrdir)/ruby:$(srcdir):$(srcdir)/missing
-
-empty =
-CC_VERSION = @CC_VERSION@
-OUTFLAG = @OUTFLAG@$(empty)
-COUTFLAG = @COUTFLAG@$(empty)
-ARCH_FLAG = @ARCH_FLAG@
-CFLAGS_NO_ARCH = @CFLAGS@
-CFLAGS = $(CFLAGS_NO_ARCH) $(ARCH_FLAG)
-cflags = @cflags@
-optflags = @optflags@
-debugflags = @debugflags@
-warnflags = @warnflags@ @strict_warnflags@
-cppflags = @cppflags@
-XCFLAGS = @XCFLAGS@
-CPPFLAGS = @CPPFLAGS@ $(INCFLAGS)
-LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
-EXTLDFLAGS = @EXTLDFLAGS@
-XLDFLAGS = @XLDFLAGS@ $(EXTLDFLAGS)
-EXTLIBS =
-LIBS = @LIBS@ $(EXTLIBS)
-MISSING = @LIBOBJS@ @ALLOCA@
-ENABLE_SHARED = @ENABLE_SHARED@
-LDSHARED = @LIBRUBY_LDSHARED@
-DLDFLAGS = @LIBRUBY_DLDFLAGS@ $(XLDFLAGS) $(ARCH_FLAG)
-SOLIBS = @SOLIBS@
-ENABLE_DEBUG_ENV = @ENABLE_DEBUG_ENV@
-MAINLIBS = @MAINLIBS@
-ARCHMINIOBJS = @MINIOBJS@
-DLNOBJ = @DLNOBJ@
-ENCOBJS = @ENCOBJS@
-EXTOBJS = @EXTOBJS@
-BUILTIN_ENCOBJS = @BUILTIN_ENCOBJS@
-BUILTIN_TRANSSRCS = @BUILTIN_TRANSSRCS@
-BUILTIN_TRANSOBJS = @BUILTIN_TRANSOBJS@
-POSTLINK = @POSTLINK@
-
-RUBY_BASE_NAME=@RUBY_BASE_NAME@
-RUBY_PROGRAM_VERSION=@RUBY_PROGRAM_VERSION@
-RUBY_API_VERSION=@RUBY_API_VERSION@
-RUBY_INSTALL_NAME=@RUBY_INSTALL_NAME@
-RUBY_SO_NAME=@RUBY_SO_NAME@
-EXEEXT = @EXEEXT@
-LIBEXT = @LIBEXT@
-PROGRAM=$(RUBY_INSTALL_NAME)$(EXEEXT)
-RUBY = $(RUBY_INSTALL_NAME)
-MINIRUBY = @MINIRUBY@\
- $(MINIRUBYOPT)
-# RUNRUBY_COMMAND:: runruby.rb or baseruby. do not append options directly
-RUNRUBY_COMMAND = @RUNRUBY_COMMAND@
-# RUNRUBY:: run ruby with RUN_OPTS which is passed to ruby
-RUNRUBY = @RUNRUBY@ $(RUN_OPTS)
-# RUNRUBY_DEBUGGER:: debugging option for runruby.rb
-RUNRUBY_DEBUGGER = --debugger='gdb -x run.gdb --quiet --args'
-XRUBY = @XRUBY@
-BTESTRUBY = @BTESTRUBY@\
- $(MINIRUBYOPT)
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-XRUBY_LIBDIR = @XRUBY_LIBDIR@
-XRUBY_RUBYLIBDIR = @XRUBY_RUBYLIBDIR@
-XRUBY_RUBYHDRDIR = @XRUBY_RUBYHDRDIR@
-BOOTSTRAPRUBY = @BOOTSTRAPRUBY@
-
-#### End of system configuration section. ####
-
-MAJOR= @MAJOR@
-MINOR= @MINOR@
-TEENY= @TEENY@
-RUBY_PROGRAM_VERSION = @RUBY_PROGRAM_VERSION@
-
-LIBRUBY_A = @LIBRUBY_A@
-LIBRUBY_SO = @LIBRUBY_SO@
-LIBRUBY_ALIASES= @LIBRUBY_ALIASES@
-LIBRUBY = @LIBRUBY@
-LIBRUBYARG = @LIBRUBYARG@
-LIBRUBYARG_STATIC = @LIBRUBYARG_STATIC@
-LIBRUBYARG_SHARED = @LIBRUBYARG_SHARED@
-LIBRUBY_RELATIVE = @LIBRUBY_RELATIVE@
-LIBRUBY_A_OBJS = @LIBRUBY_A_OBJS@
-
-DTRACE_REBUILD_OBJS = $(DTRACE_REBUILD:yes=$(DTRACE_DEPENDENT_OBJS))
-
-DTRACE_DEPENDENT_OBJS = array.$(OBJEXT) \
- eval.$(OBJEXT) \
- gc.$(OBJEXT) \
- hash.$(OBJEXT) \
- load.$(OBJEXT) \
- object.$(OBJEXT) \
- parse.$(OBJEXT) \
- string.$(OBJEXT) \
- symbol.$(OBJEXT) \
- vm.$(OBJEXT)
-
-THREAD_MODEL = @THREAD_MODEL@
-
-PREP = @PREP@
-ARCHFILE = @ARCHFILE@
-SETUP =
-EXTSTATIC = @EXTSTATIC@
-ENCSTATIC = @ENCSTATIC@
-SET_LC_MESSAGES = env LC_MESSAGES=C
-
-MAKEDIRS = @MKDIR_P@
-CP = cp
-MV = mv
-RM = rm -f
-RMDIR = @RMDIR@
-RMDIRS = @RMDIRS@
-RMALL = @RMALL@
-NM = @NM@
-AR = @AR@
-ARFLAGS = @ARFLAGS@$(empty)
-RANLIB = @RANLIB@
-AS = @AS@
-ASFLAGS = @ASFLAGS@ $(INCFLAGS)
-IFCHANGE = $(srcdir)/tool/ifchange
-SET_LC_MESSAGES = env LC_MESSAGES=C
-OBJDUMP = @OBJDUMP@
-OBJCOPY = @OBJCOPY@
-HAVE_GIT = @HAVE_GIT@
-GIT = @GIT@
-VCS = @VCS@
-VCSUP = @VCSUP@
-DTRACE = @DTRACE@ @DTRACE_OPT@
-DTRACE_EXT = @DTRACE_EXT@
-DTRACE_OBJ = @DTRACE_OBJ@
-DTRACE_REBUILD= @DTRACE_REBUILD@
-DTRACE_GLOMMED_OBJ = $(DTRACE_REBUILD:yes=ruby-glommed.$(OBJEXT))
-
-OBJEXT = @OBJEXT@
-ASMEXT = S
-DLEXT = @DLEXT@
-MANTYPE = @MANTYPE@
-SYMBOL_PREFIX = @SYMBOL_PREFIX@
-
-INSTALLED_LIST= .installed.list
-
-NEWLINE_C = enc/trans/newline.c
-MINIPRELUDE_C = miniprelude.c
-PRELUDE_C = prelude.c
-RBCONFIG = .rbconfig.time
-
-MAINSRC = $(MAINOBJ:@OBJEXT@=c)
-
-SRC_FILE = $<
-OS_SRC_FILE = $<
-DEST_FILE = $@
-OS_DEST_FILE = $@
-
-MESSAGE_BEGIN = @for line in
-MESSAGE_END = ; do echo "$$line"; done
-ECHO_BEGIN = @sep=''; for word in
-ECHO_END = ; do echo @ECHO_N@ "$$sep'$$word'@ECHO_C@"; sep=' '; done; echo
-
-DESTDIR = @DESTDIR@
-
-configure_args = @configure_args@
-#### End of variables
-
-.SUFFIXES: .inc .h .c .y .i .$(DTRACE_EXT)
-
-all:
-
-# Prevent GNU make v3 from overflowing arg limit on SysV.
-.NOEXPORT:
-
-miniruby$(EXEEXT):
- @-if test -f $@; then $(MV) -f $@ $@.old; $(RM) $@.old; fi
- $(ECHO) linking $@
- $(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(MAINLIBS) $(LIBS) $(OUTFLAG)$@
- $(Q) $(POSTLINK)
-
-$(PROGRAM):
- @$(RM) $@
- $(ECHO) linking $@
- $(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) $(LIBS) $(EXTLIBS) $(OUTFLAG)$@
- $(Q) $(POSTLINK)
-
-# We must `rm' the library each time this rule is invoked because "updating" a
-# MAB library on Apple/NeXT (see --enable-fat-binary in configure) is not
-# supported.
-$(LIBRUBY_A):
- @$(RM) $@
- $(ECHO) linking static-library $@
- $(Q) $(AR) $(ARFLAGS) $@ $(LIBRUBY_A_OBJS) $(INITOBJS)
- @-$(RANLIB) $@ 2> /dev/null || true
-
-verify-static-library: $(LIBRUBY_A)
- $(ECHO) verifying static-library $@
- @$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)conftest$(EXEEXT)
- @$(RMALL) conftest$(EXEEXT) conftest.c conftest.dSYM
-
-$(LIBRUBY_SO):
- @-$(PRE_LIBRUBY_UPDATE)
- $(ECHO) linking shared-library $@
- $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(SOLIBS) $(EXTSOLIBS) $(OUTFLAG)$@
- -$(Q) $(OBJCOPY) -w -L '$(SYMBOL_PREFIX)Init_*' -L '$(SYMBOL_PREFIX)ruby_static_id_*' \
- -L '$(SYMBOL_PREFIX)*_threadptr_*' $@
- $(Q) $(POSTLINK)
- @-$(MINIRUBY) -e 'ARGV.each{|link| File.delete link rescue nil; \
- File.symlink "$(LIBRUBY_SO)", link}' \
- $(LIBRUBY_ALIASES) || true
-
-ruby_pc = @ruby_pc@
-$(ruby_pc):
- @./config.status --file=$@:$(srcdir)/template/ruby.pc.in
-
-ruby-runner.h: template/ruby-runner.h.in
- @./config.status --file=$@:$(srcdir)/template/$(@F).in
-
-$(RBCONFIG): $(PREP)
-
-rbconfig.rb: $(RBCONFIG)
-
-install-cross: $(arch)-fake.rb $(RBCONFIG) rbconfig.rb $(arch_hdrdir)/ruby/config.h \
- $(LIBRUBY_A) $(LIBRUBY_SO) $(ARCHFILE)
- $(ECHO) installing cross-compiling stuff
- $(Q) $(MAKEDIRS) $(XRUBY_RUBYLIBDIR)/$(arch) $(XRUBY_RUBYHDRDIR)/$(arch)/ruby
- $(Q) sed '/^\$$:\.unshift/q' $(arch)-fake.rb > fake.rb
- $(Q) $(BASERUBY) -p \
- -e '~/^\s*CONFIG\["LDFLAGS"\]/ and' \
- -e '$$_[/(?=\s*"$$)/] = %q[ #{(CONFIG["LIBPATHFLAG"]%File.dirname(__FILE__)).strip}]' \
- rbconfig.rb > fake-rbconfig.rb
- $(INSTALL_SCRIPT) fake.rb $(XRUBY_RUBYLIBDIR)/$(arch)/fake.rb
- $(INSTALL_SCRIPT) fake-rbconfig.rb $(XRUBY_RUBYLIBDIR)/$(arch)/rbconfig.rb
- @$(RM) fake.rb fake-rbconfig.rb
- $(INSTALL_DATA) $(arch_hdrdir)/ruby/config.h $(XRUBY_RUBYHDRDIR)/$(arch)/ruby
- $(INSTALL_DATA) $(top_srcdir)/include/ruby/win32.h $(XRUBY_RUBYHDRDIR)/ruby
- $(INSTALL_DATA) $(LIBRUBY) $(LIBRUBY_A) $(XRUBY_RUBYLIBDIR)/$(arch)
- $(INSTALL_PROGRAM) $(LIBRUBY_SO) $(XRUBY_RUBYLIBDIR)/$(arch)
-
-Makefile: $(srcdir)/Makefile.in $(srcdir)/enc/Makefile.in
-
-$(MKFILES): config.status $(srcdir)/version.h
- @[ -f $@ ] && mv $@ $@.old
- MAKE=$(MAKE) $(SHELL) ./config.status $@
- @cmp $@ $@.old > /dev/null 2>&1 && echo $@ unchanged && exit 0; \
- { \
- echo "all:; -@rm -f conftest.mk"; \
- echo "conftest.mk: .force; @echo AUTO_REMAKE"; \
- echo ".force:"; \
- } > conftest.mk || exit 1; \
- $(MAKE) -f conftest.mk | grep '^AUTO_REMAKE$$' >/dev/null 2>&1 || \
- { echo "$@ updated, restart."; exit 1; }
-
-uncommon.mk: $(srcdir)/common.mk
- sed 's/{\$$([^(){}]*)[^{}]*}//g' $< > $@
-
-.PHONY: reconfig
-reconfig-args = $(srcdir)/$(CONFIGURE) $(configure_args)
-config.status-args = ./config.status --recheck
-reconfig-exec-0 = test -t 1 && { CONFIGURE_TTY=yes; export CONFIGURE_TTY; }; exec 3>&1; exit `exec 4>&1; { "$$@" 3>&- 4>&-; echo $$? 1>&4; } | fgrep -v '(cached)' 1>&3 3>&- 4>&-`
-reconfig-exec-1 = set -x; "$$@"
-
-reconfig config.status: $(srcdir)/$(CONFIGURE) $(srcdir)/enc/Makefile.in \
- $(srcdir)/include/ruby/version.h
- @PWD= MINIRUBY="$(MINIRUBY)"; export MINIRUBY; \
- set $(SHELL) $($@-args); $(reconfig-exec-$(V))
-
-$(srcdir)/$(CONFIGURE): $(srcdir)/configure.ac $(srcdir)/aclocal.m4
- $(CHDIR) $(srcdir) && exec $(AUTOCONF) -o $(@F)
-
-$(srcdir)/aclocal.m4:
- $(CHDIR) $(srcdir) && \
- type $(ACLOCAL) >/dev/null 2>&1 && exec $(ACLOCAL); \
- touch $(@F)
-
-prereq: $(srcdir)/$(CONFIGURE)
-
-incs: id.h
-all-incs: probes.h
-
-# Things which should be considered:
-# * with gperf v.s. without gperf
-# * committers may have various versions of gperf
-# * ./configure v.s. ../ruby/configure
-# * GNU make v.s. HP-UX make # HP-UX make invokes the action if lex.c and keywords has same mtime.
-# * svn checkout generate a file with mtime as current time
-# * ext4 and XFS has a mtime with fractional part
-lex.c: defs/keywords
- @\
- if cmp -s $(srcdir)/defs/lex.c.src $?; then \
- [ $(Q) ] && echo copying $@ || set -x; \
- $(CP) $(srcdir)/lex.c.blt $@; \
- else \
- [ $(Q) ] && echo generating $@ || set -x; \
- gperf -C -P -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ $? \
- | sed 's/(long)&((\(struct stringpool_t\) *\*)0)->\(stringpool_[a-z0-9]*\)/offsetof(\1, \2)/g' \
- > $@.tmp && \
- $(MV) $@.tmp $@ && \
- $(CP) $? $(srcdir)/defs/lex.c.src && \
- $(CP) $@ $(srcdir)/lex.c.blt; \
- fi
-
-JIS_PROPS_OPTIONS = -k1,3 -7 -c -j1 -i1 -t -C -P -t --ignore-case -H onig_jis_property_hash -Q onig_jis_property_pool -N onig_jis_property
-
-$(srcdir)/enc/jis/props.h: enc/jis/props.kwd
- $(MAKEDIRS) $(@D)
- @set +e; \
- if cmp -s $(?:.kwd=.src) $?; then \
- set -x; \
- $(CP) $(?:.kwd=.h.blt) $@; \
- else \
- set -x; \
- gperf $(JIS_PROPS_OPTIONS) $? | \
- sed 's/(int)(long)&((\([a-zA-Z_0-9 ]*[a-zA-Z_0-9]\) *\*)0)->\([a-zA-Z0-9_]*\),/(char)offsetof(\1, \2),/g' > $@ && \
- $(CP) $? $(?:.kwd=.src) && \
- $(CP) $@ $(?:.kwd=.h.blt); \
- fi
-
-.c.@OBJEXT@:
- @$(ECHO) compiling $<
- $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $<
-
-.s.@OBJEXT@:
- @$(ECHO) assembling $<
- $(Q) $(AS) $(ASFLAGS) -o $@ $<
-
-.c.S:
- @$(ECHO) translating $<
- $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -S $<
-
-.c.i:
- @$(ECHO) preprocessing $<
- $(Q) $(CPP) $(warnflags) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -E $< > $@
-
-.d.h:
- @$(ECHO) translating probes $<
- $(Q) $(DTRACE) -o $@.tmp -h -C $(INCFLAGS) -s $<
- $(Q) sed -e 's/RUBY_/RUBY_DTRACE_/g' -e 's/PROBES_H_TMP/RUBY_PROBES_H/' -e 's/(char \*/(const char */g' -e 's/, char \*/, const char */g' $@.tmp > $@
- $(Q) $(RM) $@.tmp
-
-.dmyh.h:
- @$(ECHO) making dummy $(DEST_FILE)
- $(Q)echo '#include "$(*F).dmyh"' > $@
-
-probes.stamp: $(DTRACE_REBUILD_OBJS)
- $(Q) if test -f $@ -o -f probes.$(OBJEXT); then \
- $(RM) $(DTRACE_REBUILD_OBJS) $@; \
- $(ECHO0) "rebuilding objects which were modified by \"dtrace -G\""; \
- $(MAKE) $(DTRACE_REBUILD_OBJS); \
- fi
- $(Q) touch $@
-
-probes.@OBJEXT@: $(srcdir)/probes.d $(DTRACE_REBUILD:yes=probes.stamp)
- @$(ECHO) processing probes in object files
- $(Q) $(RM) $@
- $(Q) $(DTRACE) -G -C $(INCFLAGS) -s $(srcdir)/probes.d -o $@ $(DTRACE_REBUILD_OBJS)
-
-# DTrace static library hacks described here:
-# http://mail.opensolaris.org/pipermail/dtrace-discuss/2005-August/000207.html
-ruby-glommed.$(OBJEXT):
- @$(ECHO) generating a glommed object with DTrace probes for static library
- $(Q) $(LD) -r -o $@ $(OBJS)
-
-clean-local::
- $(Q)$(RM) ext/extinit.c ext/extinit.$(OBJEXT) ext/ripper/y.output \
- enc/encinit.c enc/encinit.$(OBJEXT)
- -$(Q)$(RM) $(pkgconfig_DATA)
- -$(Q)$(RMALL) exe/ ruby-runner.h *.dSYM
-
-distclean-local::
- $(Q)$(RM) ext/config.cache $(RBCONFIG) Doxyfile
- -$(Q)$(RM) run.gdb
- -$(Q)$(RM) $(INSTALLED_LIST) $(arch_hdrdir)/ruby/config.h verconf.h
- -$(Q)$(RMDIRS) $(arch_hdrdir)/ruby 2> /dev/null || true
-
-ext/clean.sub gems/clean.sub:: ext/clean.mk
-ext/distclean.sub gems/distclean.sub:: ext/distclean.mk
-ext/realclean.sub gems/realclean.sub:: ext/realclean.mk
-
-ext/clean.mk ext/distclean.mk ext/realclean.mk::
- -$(Q) if [ -f $(EXTS_MK) ]; then exec $(MAKE) -f $(EXTS_MK) $(@F:.mk=); fi
-
-ext/clean:: ext/clean.sub
-ext/distclean:: ext/distclean.sub
-ext/realclean:: ext/realclean.sub
-gems/clean:: gems/clean.sub
-gems/distclean:: gems/distclean.sub
-gems/realclean:: gems/realclean.sub
-
-ext/clean.sub ext/distclean.sub ext/realclean.sub \
-gems/clean.sub gems/distclean.sub gems/realclean.sub::
- $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \
- test "$$#" = 0 && set .; \
- set dummy `\
- cd $(@D) 2>/dev/null && \
- find "$$@" \( -name Makefile -o -name exts.mk \) -print | \
- sed -n 's:^\./::;s:^:$(@D)/:;s:/[^/][^/]*$$::p' | sort -u; \
- `; shift; \
- for dir do \
- $(RM) "$$dir/exts.mk"; \
- if [ -f "$$dir/Makefile" ]; then \
- echo $(@F:.sub=)ing "$$dir"; \
- (cd "$$dir" && exec $(MAKE) $(mflags) $(@F:.sub=)); \
- fi; \
- done || true
-
-ext/distclean ext/realclean gems/distclean gems/realclean::
- $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \
- test "$$#" = 0 && set .; \
- cd $(@D) 2>/dev/null && \
- find "$$@" -type d -empty -exec $(RMDIRS) {} + 2> /dev/null || true
- $(Q) $(RMDIRS) $(@D) 2> /dev/null || true
-
-clean-enc distclean-enc realclean-enc:
- @test -f "$(ENC_MK)" || exit 0; \
- echo $(@:-enc=ing) encodings; \
- exec $(MAKE) $(MAKE_ENC) $(@:-enc=)
-
-ext/extinit.$(OBJEXT): ext/extinit.c $(SETUP)
- $(ECHO) compiling $@
- $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c ext/extinit.c
-
-enc/encinit.$(OBJEXT): enc/encinit.c $(SETUP)
-
-test-bundler-precheck: $(arch)-fake.rb programs
-
-yes-test-bundler-prepare: test-bundler-precheck
- $(XRUBY) -C "$(srcdir)" bin/gem install --no-ri --no-rdoc \
- --install-dir spec/rspec --conservative 'rspec:~> 3.5'
-
-RSPECOPTS = --format progress
-BUNDLER_SPECS =
-test-bundler: $(TEST_RUNNABLE)-test-bundler
-yes-test-bundler: yes-test-bundler-prepare
- $(gnumake_recursive)$(Q) \
- $(XRUBY) -C $(srcdir) -Ispec/bundler spec/rspec/bin/rspec \
- $(RSPECOPTS) spec/bundler/$(BUNDLER_SPECS)
-no-test-bundler:
-
-update-src::
- @$(CHDIR) "$(srcdir)" && LC_TIME=C exec $(VCSUP)
-
-update-download:: update-config_files
-
-after-update:: prereq
-
-gcov:
- $(Q) $(BASERUBY) $(srcdir)/tool/run-gcov.rb
-
-lcov:
- $(Q) $(BASERUBY) $(srcdir)/tool/run-lcov.rb
-
-update-doclie:
- $(Q) $(srcdir)/tool/git-refresh -C $(srcdir)/coverage $(Q1:0=-q) \
- --branch $(DOCLIE_GIT_REF) \
- $(DOCLIE_GIT_URL) doclie $(GIT_OPTS)
-
-update-simplecov-html:
- $(Q) $(srcdir)/tool/git-refresh -C $(srcdir)/coverage $(Q1:0=-q) \
- --branch $(SIMPLECOV_HTML_GIT_REF) \
- $(SIMPLECOV_HTML_GIT_URL) simplecov-html $(GIT_OPTS)
-
-update-simplecov:
- $(Q) $(srcdir)/tool/git-refresh -C $(srcdir)/coverage $(Q1:0=-q) \
- --branch $(SIMPLECOV_GIT_REF) \
- $(SIMPLECOV_GIT_URL) simplecov $(GIT_OPTS)
-
-update-coverage: update-simplecov update-simplecov-html update-doclie
-
-INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc \
- vmtc.inc vm.inc
-
-$(INSNS): $(srcdir)/insns.def vm_opts.h \
- $(srcdir)/defs/opt_operand.def $(srcdir)/defs/opt_insn_unif.def \
- $(srcdir)/tool/instruction.rb $(srcdir)/tool/insns2vm.rb
- $(ECHO) generating $@
- $(Q) $(BASERUBY) -Ku $(srcdir)/tool/insns2vm.rb $(INSNS2VMOPT) $@
-
-verconf.h: $(RBCONFIG)
-
-loadpath: verconf.h
- @$(CPP) $(XCFLAGS) $(CPPFLAGS) $(srcdir)/loadpath.c | \
- sed -e '1,/^const char ruby_initial_load_paths/d;/;/,$$d' \
- -e '/^ /!d;s/ *"\\0"$$//;s/" *"//g'
-
-un-runnable:
- $(ECHO) cannot make runnable, configure with --enable-load-relative.
- $(Q) exit 1
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 9f9e162238..0000000000
--- a/NEWS
+++ /dev/null
@@ -1,220 +0,0 @@
-# -*- rdoc -*-
-
-= NEWS for Ruby 2.5.0
-
-This document is a list of user visible feature changes made between
-releases except for bug fixes.
-
-Note that each entry is kept so brief that no reason behind or
-reference information is supplied with. For a full list of changes
-with all sufficient information, see the ChangeLog file or Redmine
-(e.g. <tt>https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER</tt>)
-
-== Changes since the 2.4.0 release
-
-=== Language changes
-
-* Top-level constant look-up is removed. [Feature #11547]
-
-* rescue/else/ensure are allowed inside do/end blocks. [Feature #12906]
-
-* refinements take place in string interpolations. [Feature #13812]
-
-=== Core classes updates (outstanding ones only)
-
-* Array
-
- * Array#append [Feature #12746]
- * Array#prepend [Feature #12746]
-
-* Dir
-
- * Dir.glob provides new optional keyword argument, :base.
- [Feature #13056]
- * Dir.children [Feature #11302]
- * Dir.each_child [Feature #11302]
-
-* File
-
- * :newline option to File.open implies text mode now. [Bug #13350]
- * File#path now raises an IOError for files opened with
- File::Constants::TMPFILE option. [Feature #13568]
- * File.stat, File.exist?, and other rb_stat()-using methods release GVL
- [Bug #13941]
- * File.rename releases GVL [Feature #13951]
-
-* Hash
-
- * Hash#transform_keys [Feature #13583]
- * Hash#transform_keys! [Feature #13583]
-
-* IO
-
- * IO#pread [Feature #4532]
- * IO#pwrite [Feature #4532]
-
-* IOError
-
- * exception message "stream closed" is changed [Bug #13405]
-
-* Integer
-
- * Integer.sqrt [Feature #13219]
- * Integer#step does no longer rescue exceptions when given
- a step value which cannot be compared with #> to 0. [Feature #7688]
- * Integer#{round,floor,ceil,truncate} now always return an Integer.
- [Bug #13420]
-
-* Kernel
-
- * Kernel#yield_self [Feature #6721]
-
-* Net::HTTP
-
- * Net::HTTP.new supports no_proxy parameter [Feature #11195]
-
-* Numeric
-
- * Numerical comparison operators (<,<=,>=,>) no longer rescue exceptions
- of #coerce. Return nil in #coerce if the coercion is impossible.
- [Feature #7688]
-
-* Process
-
- * Precision of Process.times is improved if getrusage(2) exists. [Feature #11952]
-
-* Range
- * Range#initialize no longer rescue exceptions when comparing begin and
- end with #<=> and raise a "bad value for range" ArgumentError
- but instead let the exception from the #<=> call go through.
- [Feature #7688]
-
-* Regexp
- * Update to Onigmo 6.1.1.
- * Support absent operator https://github.com/k-takata/Onigmo/issues/82
-
-* String
-
- * String#-@ deduplicates unfrozen strings. Already-frozen
- strings remain unchanged for compatibility. [Feature #13077]
- * -"literal" (String#-@) optimized to return the same object
- (same as "literal".freeze in Ruby 2.1+) [Feature #13295]
- * String#{casecmp,casecmp?} now return nil for non-string arguments
- instead of raising a TypeError. [Bug #13312]
- * String#delete_prefix is added to remove prefix [Feature #12694]
- * String#delete_prefix! is added to remove prefix destructively [Feature #12694]
- * String#delete_suffix is added to remove suffix [Feature #13665]
- * String#delete_suffix! is added to remove suffix destructively [Feature #13665]
- * String#each_grapheme_cluster and String#grapheme_clusters is added to
- enumerate grapheme clusters [Feature #13780]
-
-* Regexp/String: Updated Unicode version from 9.0.0 to 10.0.0 [Feature #13685]
-
-* Thread
-
- * Thread#fetch [Feature #13009]
-
- * Description set by Thread#name= is now visible on Windows 10.
-
-* Time
-
- * Time#at receives 3rd argument which specifies the unit of 2nd argument.
- [Feature #13919]
-
-* KeyError
-
- * KeyError#receiver [Feature #12063]
- * KeyError#key [Feature #12063]
-
-=== Stdlib updates (outstanding ones only)
-
-* Bundler
-
- * Add Bundler to Standard Library. [Feature #12733]
-
-* ERB
- * Add ERB#result_with_hash to render a template with local variables passed
- with a Hash object. [Feature #8631]
-
- * Carriage returns are changed to be trimmed properly if trim_mode is specified
- and used. Duplicated newlines will be removed on Windows. [Bug #5339] [Bug #11464]
-
-* Net::HTTP
- * Add more HTTP status classes
-
- * Net::HTTP::STATUS_CODES is added as HTTP Status Code Repository [Misc #12935]
-
- * Net::HTTP#proxy_user and Net::HTTP#proxy_pass now reflects http_proxy
- environment variable if the system's environment variable is multiuser
- safe. [Bug #12921]
-
-* RbConfig
- * New constants:
- * RbConfig::LIMITS is added to provide the limits of C types.
-
-* Ripper
- * New method:
- * Ripper#state is added to tell the state of scanner. [Feature #13686]
-
- * New constants:
- * Ripper::EXPR_BEG and so on for Ripper#state.
-
-* Set
- * Add Set#to_s as alias to #inspect [Feature #13676]
- * Add Set#=== as alias to #include? [Feature #13801]
-
-* WEBrick
-
- * Add Server Name Indication (SNI) support [Feature #13729]
-
-=== Compatibility issues (excluding feature bug fixes)
-
-* BasicSocket#read_nonblock and BasicSocket#write_nonblock no
- longer sets the O_NONBLOCK file description flag as side effect
- (on Linux only) [Feature #13362]
-
-* Net::HTTP
- * Net::HTTP#start now pass :ENV to p_addr by default. [Bug #13351]
- To avoid this, pass nil explicitly.
-
-* Random.raw_seed renamed to become Random.urandom. It is now
- applicable to non-seeding purposes due to [Bug #9569].
-
-* Socket::Ifaddr#vhid is added [Feature #13803]
-
-* ConditionVariable, Queue and SizedQueue reimplemented for speed.
- They no longer subclass Struct. [Feature #13552]
-
-=== Stdlib compatibility issues (excluding feature bug fixes)
-
-* mathn.rb
- Removed from stdlib. [Feature #10169]
-
-* Rubygems
- * Removed "ubygems.rb" file from stdlib. It's needless after the Ruby 1.9.
-
-=== C API updates
-
-=== Supported platform changes
-
-=== Implementation improvements
-
-* (This might not be a "user visible feature change" but) Hash class's
- hash function is now SipHash13. [Feature #13017]
-
-* SecureRandom now prefers OS-provided sources than OpenSSL. [Bug #9569]
-
-* Mutex rewritten to be smaller and faster [Feature #13517]
-
-=== Miscellaneous changes
-
-* Print backtrace and error message in reverse order if STDERR is unchanged and a tty.
- [Feature #8661] [experimental]
-
-* configure option --with-ext now mandates its arguments. So for
- instance if you run ./configure --with-ext=openssl,+ then the
- openssl library is guaranteed compiled, otherwise the build fails
- abnormally.
-
- Note however to always add the ",+" at the end of the argument.
- Otherwise nothing but openssl are built. [Feature #13302]
diff --git a/NEWS.md b/NEWS.md
new file mode 100644
index 0000000000..2dcfacb6e2
--- /dev/null
+++ b/NEWS.md
@@ -0,0 +1,820 @@
+# NEWS for Ruby 3.0.0
+
+This document is a list of user visible feature changes
+since the **2.7.0** release, except for bug fixes.
+
+Note that each entry is kept so brief that no reason behind or reference
+information is supplied with. For a full list of changes with all
+sufficient information, see the ChangeLog file or Redmine
+(e.g. `https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER`).
+
+## Language changes
+
+* Keyword arguments are now separated from positional arguments.
+ Code that resulted in deprecation warnings in Ruby 2.7 will now
+ result in ArgumentError or different behavior. [[Feature #14183]]
+
+* Procs accepting a single rest argument and keywords are no longer
+ subject to autosplatting. This now matches the behavior of Procs
+ accepting a single rest argument and no keywords.
+ [[Feature #16166]]
+
+ ```ruby
+ pr = proc{|*a, **kw| [a, kw]}
+
+ pr.call([1])
+ # 2.7 => [[1], {}]
+ # 3.0 => [[[1]], {}]
+
+ pr.call([1, {a: 1}])
+ # 2.7 => [[1], {:a=>1}] # and deprecation warning
+ # 3.0 => [[[1, {:a=>1}]], {}]
+ ```
+
+* Arguments forwarding (`...`) now supports leading arguments.
+ [[Feature #16378]]
+
+ ```ruby
+ def method_missing(meth, ...)
+ send(:"do_#{meth}", ...)
+ end
+ ```
+
+* Pattern matching (`case/in`) is no longer experimental. [[Feature #17260]]
+
+* One-line pattern matching is redesigned. [EXPERIMENTAL]
+
+ * `=>` is added. It can be used like a rightward assignment.
+ [[Feature #17260]]
+
+ ```ruby
+ 0 => a
+ p a #=> 0
+
+ {b: 0, c: 1} => {b:}
+ p b #=> 0
+ ```
+
+ * `in` is changed to return `true` or `false`. [[Feature #17371]]
+
+ ```ruby
+ # version 3.0
+ 0 in 1 #=> false
+
+ # version 2.7
+ 0 in 1 #=> raise NoMatchingPatternError
+ ```
+
+* Find-pattern is added. [EXPERIMENTAL]
+ [[Feature #16828]]
+
+ ```ruby
+ case ["a", 1, "b", "c", 2, "d", "e", "f", 3]
+ in [*pre, String => x, String => y, *post]
+ p pre #=> ["a", 1]
+ p x #=> "b"
+ p y #=> "c"
+ p post #=> [2, "d", "e", "f", 3]
+ end
+ ```
+
+* Endless method definition is added. [EXPERIMENTAL]
+ [[Feature #16746]]
+
+ ```ruby
+ def square(x) = x * x
+ ```
+
+* Interpolated String literals are no longer frozen when
+ `# frozen-string-literal: true` is used. [[Feature #17104]]
+
+* Magic comment `shareable_constant_value` added to freeze constants.
+ See {Magic Comments}[rdoc-ref:doc/syntax/comments.rdoc@Magic+Comments] for more details.
+ [[Feature #17273]]
+
+* A {static analysis}[rdoc-label:label-Static+analysis] foundation is
+ introduced.
+ * {RBS}[rdoc-label:label-RBS] is introduced. It is a type definition
+ language for Ruby programs.
+ * {TypeProf}[rdoc-label:label-TypeProf] is experimentally bundled. It is a
+ type analysis tool for Ruby programs.
+
+* Deprecation warnings are no longer shown by default (since Ruby 2.7.2).
+ Turn them on with `-W:deprecated` (or with `-w` to show other warnings too).
+ [[Feature #16345]]
+
+* $SAFE and $KCODE are now normal global variables with no special behavior.
+ C-API methods related to $SAFE have been removed.
+ [[Feature #16131]] [[Feature #17136]]
+
+* yield in singleton class definitions in methods is now a SyntaxError
+ instead of a warning. yield in a class definition outside of a method
+ is now a SyntaxError instead of a LocalJumpError. [[Feature #15575]]
+
+* When a class variable is overtaken by the same definition in an
+ ancestor class/module, a RuntimeError is now raised (previously,
+ it only issued a warning in verbose mode). Additionally, accessing a
+ class variable from the toplevel scope is now a RuntimeError.
+ [[Bug #14541]]
+
+* Assigning to a numbered parameter is now a SyntaxError instead of
+ a warning.
+
+## Command line options
+
+### `--help` option
+
+When the environment variable `RUBY_PAGER` or `PAGER` is present and has
+a non-empty value, and the standard input and output are tty, the `--help`
+option shows the help message via the pager designated by the value.
+[[Feature #16754]]
+
+### `--backtrace-limit` option
+
+The `--backtrace-limit` option limits the maximum length of a backtrace.
+[[Feature #8661]]
+
+## Core classes updates
+
+Outstanding ones only.
+
+* Array
+
+ * The following methods now return Array instances instead of
+ subclass instances when called on subclass instances:
+ [[Bug #6087]]
+
+ * Array#drop
+ * Array#drop_while
+ * Array#flatten
+ * Array#slice!
+ * Array#slice / Array#[]
+ * Array#take
+ * Array#take_while
+ * Array#uniq
+ * Array#*
+
+ * Can be sliced with Enumerator::ArithmeticSequence
+
+ ```ruby
+ dirty_data = ['--', 'data1', '--', 'data2', '--', 'data3']
+ dirty_data[(1..).step(2)] # take each second element
+ # => ["data1", "data2", "data3"]
+ ```
+
+* Binding
+
+ * Binding#eval when called with one argument will use "(eval)"
+ for `__FILE__` and 1 for `__LINE__` in the evaluated code.
+ [[Bug #4352]] [[Bug #17419]]
+
+* ConditionVariable
+
+ * ConditionVariable#wait may now invoke the `block`/`unblock` scheduler
+ hooks in a non-blocking context. [[Feature #16786]]
+
+* Dir
+
+ * Dir.glob and Dir.[] now sort the results by default, and
+ accept the `sort:` keyword option. [[Feature #8709]]
+
+* ENV
+
+ * ENV.except has been added, which returns a hash excluding the
+ given keys and their values. [[Feature #15822]]
+
+ * Windows: Read ENV names and values as UTF-8 encoded Strings
+ [[Feature #12650]]
+
+* Encoding
+
+ * Added new encoding IBM720. [[Feature #16233]]
+
+ * Changed default for Encoding.default_external to UTF-8 on Windows
+ [[Feature #16604]]
+
+* Fiber
+
+ * Fiber.new(blocking: true/false) allows you to create non-blocking
+ execution contexts. [[Feature #16786]]
+
+ * Fiber#blocking? tells whether the fiber is non-blocking. [[Feature #16786]]
+
+ * Fiber#backtrace and Fiber#backtrace_locations provide per-fiber backtrace.
+ [[Feature #16815]]
+
+ * The limitation of Fiber#transfer is relaxed. [[Bug #17221]]
+
+* GC
+
+ * GC.auto_compact= and GC.auto_compact have been added to control
+ when compaction runs. Setting `auto_compact=` to true will cause
+ compaction to occur during major collections. At the moment,
+ compaction adds significant overhead to major collections, so please
+ test first! [[Feature #17176]]
+
+* Hash
+
+ * Hash#transform_keys and Hash#transform_keys! now accept a hash that maps
+ keys to new keys. [[Feature #16274]]
+
+ * Hash#except has been added, which returns a hash excluding the
+ given keys and their values. [[Feature #15822]]
+
+* IO
+
+ * IO#nonblock? now defaults to `true`. [[Feature #16786]]
+
+ * IO#wait_readable, IO#wait_writable, IO#read, IO#write and other
+ related methods (e.g. IO#puts, IO#gets) may invoke the scheduler hook
+ `#io_wait(io, events, timeout)` in a non-blocking execution context.
+ [[Feature #16786]]
+
+* Kernel
+
+ * Kernel#clone when called with the `freeze: false` keyword will call
+ `#initialize_clone` with the `freeze: false` keyword.
+ [[Bug #14266]]
+
+ * Kernel#clone when called with the `freeze: true` keyword will call
+ `#initialize_clone` with the `freeze: true` keyword, and will
+ return a frozen copy even if the receiver is unfrozen.
+ [[Feature #16175]]
+
+ * Kernel#eval when called with two arguments will use "(eval)"
+ for `__FILE__` and 1 for `__LINE__` in the evaluated code.
+ [[Bug #4352]]
+
+ * Kernel#lambda now warns if called without a literal block.
+ [[Feature #15973]]
+
+ * Kernel.sleep invokes the scheduler hook `#kernel_sleep(...)` in a
+ non-blocking execution context. [[Feature #16786]]
+
+* Module
+
+ * Module#include and Module#prepend now affect classes and modules
+ that have already included or prepended the receiver, mirroring the
+ behavior if the arguments were included in the receiver before
+ the other modules and classes included or prepended the receiver.
+ [[Feature #9573]]
+
+ ```ruby
+ class C; end
+ module M1; end
+ module M2; end
+ C.include M1
+ M1.include M2
+ p C.ancestors #=> [C, M1, M2, Object, Kernel, BasicObject]
+ ```
+
+ * Module#public, Module#protected, Module#private, Module#public_class_method,
+ Module#private_class_method, toplevel "private" and "public" methods
+ now accept single array argument with a list of method names. [[Feature #17314]]
+
+ * Module#attr_accessor, Module#attr_reader, Module#attr_writer and Module#attr
+ methods now return an array of defined method names as symbols.
+ [[Feature #17314]]
+
+ * Module#alias_method now returns the defined alias as a symbol.
+ [[Feature #17314]]
+
+* Mutex
+
+ * `Mutex` is now acquired per-`Fiber` instead of per-`Thread`. This change
+ should be compatible for essentially all usages and avoids blocking when
+ using a scheduler. [[Feature #16792]]
+
+* Proc
+
+ * Proc#== and Proc#eql? are now defined and will return true for
+ separate Proc instances if the procs were created from the same block.
+ [[Feature #14267]]
+
+* Queue / SizedQueue
+
+ * Queue#pop, SizedQueue#push and related methods may now invoke the
+ `block`/`unblock` scheduler hooks in a non-blocking context.
+ [[Feature #16786]]
+
+* Ractor
+
+ * New class added to enable parallel execution. See rdoc-ref:ractor.md for
+ more details.
+
+* Random
+
+ * `Random::DEFAULT` now refers to the `Random` class instead of being a `Random` instance,
+ so it can work with `Ractor`.
+ [[Feature #17322]]
+
+ * `Random::DEFAULT` is deprecated since its value is now confusing and it is no longer global,
+ use `Kernel.rand`/`Random.rand` directly, or create a `Random` instance with `Random.new` instead.
+ [[Feature #17351]]
+
+
+* String
+
+ * The following methods now return or yield String instances
+ instead of subclass instances when called on subclass instances:
+ [[Bug #10845]]
+
+ * String#*
+ * String#capitalize
+ * String#center
+ * String#chomp
+ * String#chop
+ * String#delete
+ * String#delete_prefix
+ * String#delete_suffix
+ * String#downcase
+ * String#dump
+ * String#each_char
+ * String#each_grapheme_cluster
+ * String#each_line
+ * String#gsub
+ * String#ljust
+ * String#lstrip
+ * String#partition
+ * String#reverse
+ * String#rjust
+ * String#rpartition
+ * String#rstrip
+ * String#scrub
+ * String#slice!
+ * String#slice / String#[]
+ * String#split
+ * String#squeeze
+ * String#strip
+ * String#sub
+ * String#succ / String#next
+ * String#swapcase
+ * String#tr
+ * String#tr_s
+ * String#upcase
+
+* Symbol
+
+ * Symbol#to_proc now returns a lambda Proc. [[Feature #16260]]
+
+ * Symbol#name has been added, which returns the name of the symbol
+ if it is named. The returned string is frozen. [[Feature #16150]]
+
+* Fiber
+
+ * Introduce Fiber.set_scheduler for intercepting blocking operations and
+ Fiber.scheduler for accessing the current scheduler. See
+ rdoc-ref:fiber.md for more details about what operations are supported and
+ how to implement the scheduler hooks. [[Feature #16786]]
+
+ * Fiber.blocking? tells whether the current execution context is
+ blocking. [[Feature #16786]]
+
+ * Thread#join invokes the scheduler hooks `block`/`unblock` in a
+ non-blocking execution context. [[Feature #16786]]
+
+* Thread
+
+ * Thread.ignore_deadlock accessor has been added for disabling the
+ default deadlock detection, allowing the use of signal handlers to
+ break deadlock. [[Bug #13768]]
+
+* Warning
+
+ * Warning#warn now supports a category keyword argument.
+ [[Feature #17122]]
+
+## Stdlib updates
+
+Outstanding ones only.
+
+* BigDecimal
+
+ * Update to BigDecimal 3.0.0
+
+ * This version is Ractor compatible.
+
+* Bundler
+
+ * Update to Bundler 2.2.3
+
+* CGI
+
+ * Update to 0.2.0
+
+ * This version is Ractor compatible.
+
+* CSV
+
+ * Update to CSV 3.1.9
+
+* Date
+
+ * Update to Date 3.1.1
+
+ * This version is Ractor compatible.
+
+* Digest
+
+ * Update to Digest 3.0.0
+
+ * This version is Ractor compatible.
+
+* Etc
+
+ * Update to Etc 1.2.0
+
+ * This version is Ractor compatible.
+
+* Fiddle
+
+ * Update to Fiddle 1.0.5
+
+* IRB
+
+ * Update to IRB 1.2.6
+
+* JSON
+
+ * Update to JSON 2.5.0
+
+ * This version is Ractor compatible.
+
+* Set
+
+ * Update to set 1.0.0
+
+ * SortedSet has been removed for dependency and performance reasons.
+
+ * Set#join is added as a shorthand for `.to_a.join`.
+
+ * Set#<=> is added.
+
+* Socket
+
+ * Add :connect_timeout to TCPSocket.new [[Feature #17187]]
+
+* Net::HTTP
+
+ * Net::HTTP#verify_hostname= and Net::HTTP#verify_hostname have been
+ added to skip hostname verification. [[Feature #16555]]
+
+ * Net::HTTP.get, Net::HTTP.get_response, and Net::HTTP.get_print
+ can take the request headers as a Hash in the second argument when the
+ first argument is a URI. [[Feature #16686]]
+
+* Net::SMTP
+
+ * Add SNI support.
+
+ * Net::SMTP.start arguments are keyword arguments.
+
+ * TLS should not check the host name by default.
+
+* OpenStruct
+
+ * Initialization is no longer lazy. [[Bug #12136]]
+
+ * Builtin methods can now be overridden safely. [[Bug #15409]]
+
+ * Implementation uses only methods ending with `!`.
+
+ * Ractor compatible.
+
+ * Improved support for YAML. [[Bug #8382]]
+
+ * Use officially discouraged. Read OpenStruct@Caveats section.
+
+* Pathname
+
+ * Ractor compatible.
+
+* Psych
+
+ * Update to Psych 3.3.0
+
+ * This version is Ractor compatible.
+
+* Reline
+
+ * Update to Reline 0.1.5
+
+* RubyGems
+
+ * Update to RubyGems 3.2.3
+
+* StringIO
+
+ * Update to StringIO 3.0.0
+
+ * This version is Ractor compatible.
+
+* StringScanner
+
+ * Update to StringScanner 3.0.0
+
+ * This version is Ractor compatible.
+
+## Compatibility issues
+
+Excluding feature bug fixes.
+
+* Regexp literals and all Range objects are frozen. [[Feature #8948]] [[Feature #16377]] [[Feature #15504]]
+
+ ```ruby
+ /foo/.frozen? #=> true
+ (42...).frozen? # => true
+ ```
+
+* EXPERIMENTAL: Hash#each consistently yields a 2-element array. [[Bug #12706]]
+
+ * Now `{ a: 1 }.each(&->(k, v) { })` raises an ArgumentError
+ due to lambda's arity check.
+
+* When writing to STDOUT redirected to a closed pipe, no broken pipe
+ error message will be shown now. [[Feature #14413]]
+
+* `TRUE`/`FALSE`/`NIL` constants are no longer defined.
+
+* Integer#zero? overrides Numeric#zero? for optimization. [[Misc #16961]]
+
+* Enumerable#grep and Enumerable#grep_v when passed a Regexp and no block no longer modify
+ Regexp.last_match. [[Bug #17030]]
+
+* Requiring 'open-uri' no longer redefines `Kernel#open`.
+ Call `URI.open` directly or `use URI#open` instead. [[Misc #15893]]
+
+* SortedSet has been removed for dependency and performance reasons.
+
+## Stdlib compatibility issues
+
+* Default gems
+
+ * The following libraries are promoted to default gems from stdlib.
+
+ * English
+ * abbrev
+ * base64
+ * drb
+ * debug
+ * erb
+ * find
+ * net-ftp
+ * net-http
+ * net-imap
+ * net-protocol
+ * open-uri
+ * optparse
+ * pp
+ * prettyprint
+ * resolv-replace
+ * resolv
+ * rinda
+ * set
+ * securerandom
+ * shellwords
+ * tempfile
+ * tmpdir
+ * time
+ * tsort
+ * un
+ * weakref
+
+ * The following extensions are promoted to default gems from stdlib.
+
+ * digest
+ * io-nonblock
+ * io-wait
+ * nkf
+ * pathname
+ * syslog
+ * win32ole
+
+* Bundled gems
+
+ * net-telnet and xmlrpc have been removed from the bundled gems.
+ If you are interested in maintaining them, please comment on
+ your plan to https://github.com/ruby/xmlrpc
+ or https://github.com/ruby/net-telnet.
+
+* SDBM has been removed from the Ruby standard library. [[Bug #8446]]
+
+ * The issues of sdbm will be handled at https://github.com/ruby/sdbm
+
+* WEBrick has been removed from the Ruby standard library. [[Feature #17303]]
+
+ * The issues of WEBrick will be handled at https://github.com/ruby/webrick
+
+## C API updates
+
+* C API functions related to $SAFE have been removed.
+ [[Feature #16131]]
+
+* C API header file `ruby/ruby.h` was split. [[GH-2991]]
+
+ This should have no impact on extension libraries,
+ but users might experience slow compilations.
+
+* Memory view interface [EXPERIMENTAL]
+
+ * The memory view interface is a C-API set to exchange a raw memory area,
+ such as a numeric array or a bitmap image, between extension libraries.
+ The extension libraries can share also the metadata of the memory area
+ that consists of the shape, the element format, and so on.
+ Using these kinds of metadata, the extension libraries can share even
+ a multidimensional array appropriately.
+ This feature is designed by referring to Python's buffer protocol.
+ [[Feature #13767]] [[Feature #14722]]
+
+* Ractor related C APIs are introduced (experimental) in "include/ruby/ractor.h".
+
+## Implementation improvements
+
+* New method cache mechanism for Ractor. [[Feature #16614]]
+
+ * Inline method caches pointed from ISeq can be accessed by multiple Ractors
+ in parallel and synchronization is needed even for method caches. However,
+ such synchronization can be overhead so introducing new inline method cache
+ mechanisms, (1) Disposable inline method cache (2) per-Class method cache
+ and (3) new invalidation mechanism. (1) can avoid per-method call
+ synchronization because it only uses atomic operations.
+ See the ticket for more details.
+
+* The number of hashes allocated when using a keyword splat in
+ a method call has been reduced to a maximum of 1, and passing
+ a keyword splat to a method that accepts specific keywords
+ does not allocate a hash.
+
+* `super` is optimized when the same type of method is called in the previous call
+ if it's not refinements or an attr reader or writer.
+
+### JIT
+
+* Performance improvements of JIT-ed code
+
+ * Microarchitectural optimizations
+
+ * Native functions shared by multiple methods are deduplicated on JIT compaction.
+
+ * Decrease code size of hot paths by some optimizations and partitioning cold paths.
+
+ * Instance variables
+
+ * Eliminate some redundant checks.
+
+ * Skip checking a class and a object multiple times in a method when possible.
+
+ * Optimize accesses in some core classes like Hash and their subclasses.
+
+ * Method inlining support for some C methods
+
+ * `Kernel`: `#class`, `#frozen?`
+
+ * `Integer`: `#-@`, `#~`, `#abs`, `#bit_length`, `#even?`, `#integer?`, `#magnitude`,
+ `#odd?`, `#ord`, `#to_i`, `#to_int`, `#zero?`
+
+ * `Struct`: reader methods for 10th or later members
+
+ * Constant references are inlined.
+
+ * Always generate appropriate code for `==`, `nil?`, and `!` calls depending on
+ a receiver class.
+
+ * Reduce the number of PC accesses on branches and method returns.
+
+ * Optimize C method calls a little.
+
+* Compilation process improvements
+
+ * It does not keep temporary files in /tmp anymore.
+
+ * Throttle GC and compaction of JIT-ed code.
+
+ * Avoid GC-ing JIT-ed code when not necessary.
+
+ * GC-ing JIT-ed code is executed in a background thread.
+
+ * Reduce the number of locks between Ruby and JIT threads.
+
+## Static analysis
+
+### RBS
+
+* RBS is a new language for type definition of Ruby programs.
+ It allows writing types of classes and modules with advanced
+ types including union types, overloading, generics, and
+ _interface types_ for duck typing.
+
+* Ruby ships with type definitions for core/stdlib classes.
+
+* `rbs` gem is bundled to load and process RBS files.
+
+### TypeProf
+
+* TypeProf is a type analysis tool for Ruby code based on abstract interpretation.
+
+ * It reads non-annotated Ruby code, tries inferring its type signature, and prints
+ the analysis result in RBS format.
+
+ * Though it supports only a subset of the Ruby language yet, we will continuously
+ improve the coverage of language features, analysis performance, and usability.
+
+```ruby
+# test.rb
+def foo(x)
+ if x > 10
+ x.to_s
+ else
+ nil
+ end
+end
+
+foo(42)
+```
+
+```
+$ typeprof test.rb
+# Classes
+class Object
+ def foo : (Integer) -> String?
+end
+```
+
+## Miscellaneous changes
+
+* Methods using `ruby2_keywords` will no longer keep empty keyword
+ splats, those are now removed just as they are for methods not
+ using `ruby2_keywords`.
+
+* When an exception is caught in the default handler, the error
+ message and backtrace are printed in order from the innermost.
+ [[Feature #8661]]
+
+* Accessing an uninitialized instance variable no longer emits a
+ warning in verbose mode. [[Feature #17055]]
+
+[Bug #4352]: https://bugs.ruby-lang.org/issues/4352
+[Bug #6087]: https://bugs.ruby-lang.org/issues/6087
+[Bug #8382]: https://bugs.ruby-lang.org/issues/8382
+[Bug #8446]: https://bugs.ruby-lang.org/issues/8446
+[Feature #8661]: https://bugs.ruby-lang.org/issues/8661
+[Feature #8709]: https://bugs.ruby-lang.org/issues/8709
+[Feature #8948]: https://bugs.ruby-lang.org/issues/8948
+[Feature #9573]: https://bugs.ruby-lang.org/issues/9573
+[Bug #10845]: https://bugs.ruby-lang.org/issues/10845
+[Bug #12136]: https://bugs.ruby-lang.org/issues/12136
+[Feature #12650]: https://bugs.ruby-lang.org/issues/12650
+[Bug #12706]: https://bugs.ruby-lang.org/issues/12706
+[Feature #13767]: https://bugs.ruby-lang.org/issues/13767
+[Bug #13768]: https://bugs.ruby-lang.org/issues/13768
+[Feature #14183]: https://bugs.ruby-lang.org/issues/14183
+[Bug #14266]: https://bugs.ruby-lang.org/issues/14266
+[Feature #14267]: https://bugs.ruby-lang.org/issues/14267
+[Feature #14413]: https://bugs.ruby-lang.org/issues/14413
+[Bug #14541]: https://bugs.ruby-lang.org/issues/14541
+[Feature #14722]: https://bugs.ruby-lang.org/issues/14722
+[Bug #15409]: https://bugs.ruby-lang.org/issues/15409
+[Feature #15504]: https://bugs.ruby-lang.org/issues/15504
+[Feature #15575]: https://bugs.ruby-lang.org/issues/15575
+[Feature #15822]: https://bugs.ruby-lang.org/issues/15822
+[Misc #15893]: https://bugs.ruby-lang.org/issues/15893
+[Feature #15921]: https://bugs.ruby-lang.org/issues/15921
+[Feature #15973]: https://bugs.ruby-lang.org/issues/15973
+[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
+[Feature #16150]: https://bugs.ruby-lang.org/issues/16150
+[Feature #16166]: https://bugs.ruby-lang.org/issues/16166
+[Feature #16175]: https://bugs.ruby-lang.org/issues/16175
+[Feature #16233]: https://bugs.ruby-lang.org/issues/16233
+[Feature #16260]: https://bugs.ruby-lang.org/issues/16260
+[Feature #16274]: https://bugs.ruby-lang.org/issues/16274
+[Feature #16345]: https://bugs.ruby-lang.org/issues/16345
+[Feature #16377]: https://bugs.ruby-lang.org/issues/16377
+[Feature #16378]: https://bugs.ruby-lang.org/issues/16378
+[Feature #16555]: https://bugs.ruby-lang.org/issues/16555
+[Feature #16604]: https://bugs.ruby-lang.org/issues/16604
+[Feature #16614]: https://bugs.ruby-lang.org/issues/16614
+[Feature #16686]: https://bugs.ruby-lang.org/issues/16686
+[Feature #16746]: https://bugs.ruby-lang.org/issues/16746
+[Feature #16754]: https://bugs.ruby-lang.org/issues/16754
+[Feature #16786]: https://bugs.ruby-lang.org/issues/16786
+[Feature #16792]: https://bugs.ruby-lang.org/issues/16792
+[Feature #16815]: https://bugs.ruby-lang.org/issues/16815
+[Feature #16828]: https://bugs.ruby-lang.org/issues/16828
+[Misc #16961]: https://bugs.ruby-lang.org/issues/16961
+[Bug #17030]: https://bugs.ruby-lang.org/issues/17030
+[Feature #17055]: https://bugs.ruby-lang.org/issues/17055
+[Feature #17104]: https://bugs.ruby-lang.org/issues/17104
+[Feature #17122]: https://bugs.ruby-lang.org/issues/17122
+[Feature #17136]: https://bugs.ruby-lang.org/issues/17136
+[Feature #17176]: https://bugs.ruby-lang.org/issues/17176
+[Feature #17187]: https://bugs.ruby-lang.org/issues/17187
+[Bug #17221]: https://bugs.ruby-lang.org/issues/17221
+[Feature #17260]: https://bugs.ruby-lang.org/issues/17260
+[Feature #17273]: https://bugs.ruby-lang.org/issues/17273
+[Feature #17303]: https://bugs.ruby-lang.org/issues/17303
+[Feature #17314]: https://bugs.ruby-lang.org/issues/17314
+[Feature #17322]: https://bugs.ruby-lang.org/issues/17322
+[Feature #17351]: https://bugs.ruby-lang.org/issues/17351
+[Feature #17371]: https://bugs.ruby-lang.org/issues/17371
+[Bug #17419]: https://bugs.ruby-lang.org/issues/17419
+[GH-2991]: https://github.com/ruby/ruby/pull/2991
diff --git a/README.ja.md b/README.ja.md
index 2902216f99..6663b94680 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -1,3 +1,11 @@
+[![Build Status](https://travis-ci.org/ruby/ruby.svg?branch=master)](https://travis-ci.org/ruby/ruby)
+[![Build status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
+[![Actions Status](https://github.com/ruby/ruby/workflows/macOS/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"macOS")
+[![Actions Status](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
+[![Actions Status](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
+[![Actions Status](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
+[![Actions Status](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
+
# Rubyã¨ã¯
Rubyã¯ã‚·ãƒ³ãƒ—ルã‹ã¤å¼·åŠ›ãªã‚ªãƒ–ジェクト指å‘スクリプト言語ã§ã™ï¼Ž Rubyã¯ç´”粋ãªã‚ªãƒ–ジェクト指å‘言語ã¨ã—ã¦è¨­è¨ˆã•れã¦ã„ã‚‹ã®ã§ï¼Œ
@@ -10,40 +18,48 @@ Rubyã¯ãƒ†ã‚­ã‚¹ãƒˆå‡¦ç†é–¢ä¿‚ã®èƒ½åŠ›ãªã©ã«å„ªã‚Œï¼ŒPerlã¨åŒã˜ãらã„
* ã‚·ãƒ³ãƒ—ãƒ«ãªæ–‡æ³•
* 普通ã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæŒ‡å‘æ©Ÿèƒ½(クラス,メソッドコールãªã©)
-* 特殊ãªã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæŒ‡å‘æ©Ÿèƒ½(Mixin, 特異メソッドãªã©)
+* 特殊ãªã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæŒ‡å‘æ©Ÿèƒ½(Mixin,特異メソッドãªã©)
* 演算å­ã‚ªãƒ¼ãƒãƒ¼ãƒ­ãƒ¼ãƒ‰
* ä¾‹å¤–å‡¦ç†æ©Ÿèƒ½
* イテレータã¨ã‚¯ãƒ­ãƒ¼ã‚¸ãƒ£
* ガーベージコレクタ
* ダイナミックローディング (アーキテクãƒãƒ£ã«ã‚ˆã‚‹)
-* ç§»æ¤æ€§ãŒé«˜ã„.多ãã®Unix-like/POSIX互æ›ãƒ—ラットフォーム上ã§å‹•ãã ã‘ã§ãªã,Windows, Mac OS
- X,Haikuãªã©ã®ä¸Šã§ã‚‚å‹•ã cf.
- https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/SupportedPlatformsJa
+* ç§»æ¤æ€§ãŒé«˜ã„.多ãã®Unix-like/POSIX互æ›ãƒ—ラットフォーム上ã§å‹•ãã ã‘ã§ãªã,Windows, macOS,
+ Haikuãªã©ã®ä¸Šã§ã‚‚å‹•ã cf.
+ https://github.com/ruby/ruby/blob/master/doc/contributing.rdoc#platform-maintainers
## 入手法
-### FTPã§
+サードパーティーツールを使ã£ãŸæ–¹æ³•ã‚’å«ã‚€Rubyã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«æ–¹æ³•ã®ä¸€è¦§ã¯
-以下ã®å ´æ‰€ã«ãŠã„ã¦ã‚りã¾ã™ï¼Ž
+https://www.ruby-lang.org/ja/downloads/
-ftp://ftp.ruby-lang.org/pub/ruby/
+ã‚’å‚ç…§ã—ã¦ãã ã•ã„.
-### Subversionã§
+### Git
-開発先端ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§å–å¾—ã§ãã¾ã™ï¼Ž
+ミラーをGitHubã«å…¬é–‹ã—ã¦ã„ã¾ã™ï¼Ž 以下ã®ã‚³ãƒžãƒ³ãƒ‰ã§ãƒªãƒã‚¸ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã™ï¼Ž
- $ svn co https://svn.ruby-lang.org/repos/ruby/trunk/ ruby
+ $ git clone https://github.com/ruby/ruby.git
-ä»–ã«é–‹ç™ºä¸­ã®ãƒ–ランãƒã®ä¸€è¦§ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§è¦‹ã‚‰ã‚Œã¾ã™ï¼Ž
+ä»–ã®ãƒ–ランãƒã®ä¸€è¦§ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§è¦‹ã‚‰ã‚Œã¾ã™ï¼Ž
- $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
+ $ git ls-remote https://github.com/ruby/ruby.git
+
+Rubyリãƒã‚¸ãƒˆãƒªã®æœ¬æ¥ã®master㯠https://git.ruby-lang.org/ruby.git ã«ã‚りã¾ã™ï¼Ž
+コミッタã¯ã“ã¡ã‚‰ã‚’使ã„ã¾ã™ï¼Ž
+
+### Subversion
-### Gitã§
+å¤ã„Rubyã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§ã‚‚å–å¾—ã§ãã¾ã™ï¼Ž
-Subversionã®ãƒŸãƒ©ãƒ¼ã‚’GitHubã«å…¬é–‹ã—ã¦ã„ã¾ã™ï¼Ž 以下ã®ã‚³ãƒžãƒ³ãƒ‰ã§ãƒªãƒã‚¸ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã™ï¼Ž
+ $ svn co https://svn.ruby-lang.org/repos/ruby/branches/ruby_2_6/ ruby
+
+ä»–ã®ãƒ–ランãƒã®ä¸€è¦§ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§è¦‹ã‚‰ã‚Œã¾ã™ï¼Ž
+
+ $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
- $ git clone git://github.com/ruby/ruby.git
## ホームページ
@@ -55,38 +71,33 @@ https://www.ruby-lang.org/
## メーリングリスト
-Rubyã®ãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆãŒã‚りã¾ã™ï¼Žå‚åŠ å¸Œæœ›ã®æ–¹ã¯
-
-mailto:ruby-list-request@ruby-lang.org
-
-ã¾ã§æœ¬æ–‡ã«
+Rubyã®ãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆãŒã‚りã¾ã™ï¼Žå‚åŠ å¸Œæœ›ã®æ–¹ã¯ [ruby-list-request@ruby-lang.org] ã¾ã§æœ¬æ–‡ã«
subscribe
ã¨æ›¸ã„ã¦é€ã£ã¦ä¸‹ã•ã„.
-Ruby開発者å‘ã‘メーリングリストもã‚りã¾ã™ï¼Žã“ã¡ã‚‰ã§ã¯rubyã®ãƒã‚°ï¼Œå°†æ¥ã®ä»•様拡張ãªã©å®Ÿè£…上ã®å•題ã«ã¤ã„ã¦è­°è«–ã•れã¦ã„ã¾ã™ï¼Ž å‚åŠ å¸Œæœ›ã®æ–¹ã¯
-
-mailto:ruby-dev-request@ruby-lang.org
-
-ã¾ã§ruby-listã¨åŒæ§˜ã®æ–¹æ³•ã§ãƒ¡ãƒ¼ãƒ«ã—ã¦ãã ã•ã„.
+Ruby開発者å‘ã‘メーリングリストもã‚りã¾ã™ï¼Žã“ã¡ã‚‰ã§ã¯rubyã®ãƒã‚°ï¼Œå°†æ¥ã®ä»•様拡張ãªã©å®Ÿè£…上ã®å•題ã«ã¤ã„ã¦è­°è«–ã•れã¦ã„ã¾ã™ï¼Ž
+å‚åŠ å¸Œæœ›ã®æ–¹ã¯ [ruby-dev-request@ruby-lang.org] ã¾ã§ruby-listã¨åŒæ§˜ã®æ–¹æ³•ã§ãƒ¡ãƒ¼ãƒ«ã—ã¦ãã ã•ã„.
Ruby拡張モジュールã«ã¤ã„ã¦è©±ã—åˆã†ruby-extãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆã¨æ•°å­¦é–¢ä¿‚ã®è©±é¡Œã«ã¤ã„ã¦è©±ã—åˆã†ruby-mathメーリングリストã¨
英語ã§rubyã«ã¤ã„ã¦è©±ã—åˆã†ruby-talkメーリングリストもã‚りã¾ã™ï¼Žå‚加方法ã¯ã©ã‚Œã‚‚åŒã˜ã§ã™ï¼Ž
+[ruby-list-request@ruby-lang.org]: mailto:ruby-list-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
+[ruby-dev-request@ruby-lang.org]: mailto:ruby-dev-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
+
## コンパイル・インストール
ä»¥ä¸‹ã®æ‰‹é †ã§è¡Œã£ã¦ãã ã•ã„.
-1. ã‚‚ã— `configure` ファイルãŒè¦‹ã¤ã‹ã‚‰ãªã„,もã—ã㯠`configure.ac` よりå¤ã„よã†ãªã‚‰ï¼Œ `autoconf` を実行ã—ã¦
- æ–°ã—ã `configure` を生æˆã™ã‚‹
+1. (Gitリãƒã‚¸ãƒˆãƒªã‹ã‚‰å–å¾—ã—ãŸã‚½ãƒ¼ã‚¹ã‚’ビルドã™ã‚‹å ´åˆ) `./autogen.sh` を実行ã—ã¦æ–°ã—ã `configure` を生æˆã™ã‚‹
2. `configure` を実行ã—㦠`Makefile` ãªã©ã‚’生æˆã™ã‚‹
環境ã«ã‚ˆã£ã¦ã¯ãƒ‡ãƒ•ォルトã®Cコンパイラ用オプションãŒä»˜ãã¾ã™ï¼Ž `configure` オプション㧠`optflags=..`
`warnflags=..` ç­‰ã§ä¸Šæ›¸ãã§ãã¾ã™ï¼Ž
-3. (å¿…è¦ãªã‚‰ã°)`defines.h` を編集ã™ã‚‹
+3. (å¿…è¦ãªã‚‰ã°)`include/ruby/defines.h` を編集ã™ã‚‹
多分,必è¦ç„¡ã„ã¨æ€ã„ã¾ã™ï¼Ž
@@ -95,7 +106,8 @@ Ruby拡張モジュールã«ã¤ã„ã¦è©±ã—åˆã†ruby-extメーリングリスãƒ
`ext/Setup` ã«è¨˜è¿°ã—ãŸãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯é™çš„ã«ãƒªãƒ³ã‚¯ã•れã¾ã™ï¼Ž
ダイナミックローディングをサãƒãƒ¼ãƒˆã—ã¦ã„ãªã„アーキテクãƒãƒ£ã§ã¯ `Setup` ã®1行目ã®ã€Œ`option nodynamic`ã€ã¨ã„ã†è¡Œã®ã‚³
- メントを外ã™å¿…è¦ãŒã‚りã¾ã™ï¼Žã¾ãŸï¼Œã“ã®ã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ã§æ‹¡å¼µãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’利用ã™ã‚‹ãŸã‚ã«ã¯ï¼Œã‚らã‹ã˜ã‚é™çš„ã«ãƒªãƒ³ã‚¯ã‚’ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ï¼Ž
+ メントを外ã™å¿…è¦ãŒã‚りã¾ã™ï¼Ž
+ ã¾ãŸï¼Œã“ã®ã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ã§æ‹¡å¼µãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’利用ã™ã‚‹ãŸã‚ã«ã¯ï¼Œã‚らã‹ã˜ã‚é™çš„ã«ãƒªãƒ³ã‚¯ã‚’ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ï¼Ž
5. `make` を実行ã—ã¦ã‚³ãƒ³ãƒ‘イルã™ã‚‹
@@ -166,6 +178,3 @@ stackoverflow (https://ja.stackoverflow.com/) ãªã©ã®Webã‚µã‚¤ãƒˆã«æŠ•ç¨¿ã—ã
Rubyã®ã‚ªãƒªã‚¸ãƒŠãƒ«ç‰ˆã¯ï¼Œ1995å¹´ã«ã¾ã¤ã‚‚ã¨ã‚†ãã²ã‚æ°ã«ã‚ˆã£ã¦è¨­è¨ˆãƒ»é–‹ç™ºã•れã¾ã—ãŸï¼Ž
<mailto:matz@ruby-lang.org>
-
----
-created at: Thu Aug 3 11:57:36 JST 1995
diff --git a/README.md b/README.md
index 5667c811f0..bd7c7813a7 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,31 @@
-[![Build Status](https://travis-ci.org/ruby/ruby.svg)](https://travis-ci.org/ruby/ruby)
-[![Build status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/trunk?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/trunk)
+[![Build Status](https://travis-ci.org/ruby/ruby.svg?branch=master)](https://travis-ci.org/ruby/ruby)
+[![Build status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
+[![Actions Status](https://github.com/ruby/ruby/workflows/macOS/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"macOS")
+[![Actions Status](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
+[![Actions Status](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
+[![Actions Status](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
+[![Actions Status](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
# What's Ruby
-Ruby is the interpreted scripting language for quick and easy object-oriented
-programming. It has many features to process text files and to do system
-management tasks (as in Perl). It is simple, straight-forward, and
-extensible.
+Ruby is an interpreted object-oriented programming language often
+used for web development. It also offers many scripting features
+to process plain text and serialized files, or manage system tasks.
+It is simple, straightforward, and extensible.
## Features of Ruby
* Simple Syntax
* **Normal** Object-oriented Features (e.g. class, method calls)
-* **Advanced** Object-oriented Features (e.g. Mix-in, Singleton-method)
+* **Advanced** Object-oriented Features (e.g. mix-in, singleton-method)
* Operator Overloading
* Exception Handling
* Iterators and Closures
* Garbage Collection
* Dynamic Loading of Object Files (on some architectures)
* Highly Portable (works on many Unix-like/POSIX compatible platforms as
- well as Windows, Mac OS X, Haiku, etc.) cf.
- https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/SupportedPlatforms
+ well as Windows, macOS, etc.) cf.
+ https://github.com/ruby/ruby/blob/master/doc/contributing.rdoc#label-Platform+Maintainers
## How to get Ruby
@@ -30,61 +35,62 @@ like rvm, see:
https://www.ruby-lang.org/en/downloads/
-The Ruby distribution files can be found on the following FTP site:
+### Git
-ftp://ftp.ruby-lang.org/pub/ruby/
+The mirror of the Ruby source tree can be checked out with the following command:
-The trunk of the Ruby source tree can be checked out with the following
-command:
+ $ git clone https://github.com/ruby/ruby.git
- $ svn co https://svn.ruby-lang.org/repos/ruby/trunk/ ruby
+There are some other branches under development. Try the following command
+to see the list of branches:
-Or if you are using git then use the following command:
+ $ git ls-remote https://github.com/ruby/ruby.git
- $ git clone git://github.com/ruby/ruby.git
+You may also want to use https://git.ruby-lang.org/ruby.git (actual master of Ruby source)
+if you are a committer.
-There are some other branches under development. Try the following command
-to see the list of branches:
+### Subversion
- $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
+Stable branches for older Ruby versions can be checked out with also the
+following command:
-Or if you are using git then use the following command:
+ $ svn co https://svn.ruby-lang.org/repos/ruby/branches/ruby_2_6/ ruby
- $ git ls-remote git://github.com/ruby/ruby.git
+Try the following command to see the list of branches:
+
+ $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
-## Ruby home page
-The URL of the Ruby home page is:
+## Ruby home page
https://www.ruby-lang.org/
## Mailing list
-There is a mailing list to talk about Ruby. To subscribe to this list, please
+There is a mailing list to discuss Ruby. To subscribe to this list, please
send the following phrase:
subscribe
-in the mail body (not subject) to the address
-<mailto:ruby-talk-request@ruby-lang.org>.
+in the mail body (not subject) to the address [ruby-talk-request@ruby-lang.org].
-## How to compile and install
+[ruby-talk-request@ruby-lang.org]: mailto:ruby-talk-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
-This is what you need to do to compile and install Ruby:
+## How to compile and install
-1. If you want to use Microsoft Visual C++ to compile ruby, read
+1. If you want to use Microsoft Visual C++ to compile Ruby, read
[win32/README.win32](win32/README.win32) instead of this document.
-2. If `./configure` does not exist or is older than `configure.ac`, run
- `autoconf` to (re)generate configure.
+2. Run `./autogen.sh` to generate configure, when you build the source checked
+ out from the Git repository.
3. Run `./configure`, which will generate `config.h` and `Makefile`.
Some C compiler flags may be added by default depending on your
- environment. Specify `optflags=..` and `warnflags=..` as necessary to
+ environment. Specify `optflags=..` and `warnflags=..` as necessary to
override them.
-4. Edit `defines.h` if you need. Usually this step will not be needed.
+4. Edit `include/ruby/defines.h` if you need. Usually this step will not be needed.
5. Remove comment mark(`#`) before the module names from `ext/Setup` (or add
module names if not present), if you want to link modules statically.
@@ -102,14 +108,9 @@ This is what you need to do to compile and install Ruby:
7. Optionally, run '`make check`' to check whether the compiled Ruby
interpreter works well. If you see the message "`check succeeded`", your
- ruby works as it should (hopefully).
-
-8. Optionally, Run `make update-gems` and `make extract-gems`
+ Ruby works as it should (hopefully).
- If you want to install bundled gems, run `make update-gems` and
- `extract-gems` before run `make install`.
-
-9. Run '`make install`'
+8. Run '`make install`'.
This command will create the following directories and install files into
them.
@@ -138,10 +139,9 @@ This is what you need to do to compile and install Ruby:
**NOTE**: teeny of the API version may be different from one of Ruby's
program version
- You may have to be a super user to install ruby.
-
+ You may have to be a super user to install Ruby.
-If you fail to compile ruby, please send the detailed error report with the
+If you fail to compile Ruby, please send the detailed error report with the
error log and machine/OS type, to help others.
Some extension libraries may not get compiled because of lack of necessary
@@ -158,7 +158,7 @@ Questions about the Ruby language can be asked on the Ruby-Talk mailing list
(https://www.ruby-lang.org/en/community/mailing-lists) or on websites like
(https://stackoverflow.com).
-Bug reports should be filed at https://bugs.ruby-lang.org. Read [HowToReport] for more information.
+Bugs should be reported at https://bugs.ruby-lang.org. Read [HowToReport] for more information.
[HowToReport]: https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport
@@ -166,10 +166,8 @@ Bug reports should be filed at https://bugs.ruby-lang.org. Read [HowToReport] fo
See the file [CONTRIBUTING.md](CONTRIBUTING.md)
-
## The Author
-Ruby was originally designed and developed by Yukihiro Matsumoto (Matz) in
-1995.
+Ruby was originally designed and developed by Yukihiro Matsumoto (Matz) in 1995.
-<mailto:matz@ruby-lang.org>
+<matz@ruby-lang.org>
diff --git a/acinclude.m4 b/acinclude.m4
deleted file mode 100644
index 99b24e6d93..0000000000
--- a/acinclude.m4
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- autoconf -*-
-
-AC_DEFUN([_COLORIZE_RESULT_PREPARE], [
- msg_checking= msg_result_yes= msg_result_no= msg_result_other= msg_reset=
- AS_IF([test "x${CONFIGURE_TTY}" = xyes -o -t 1], [
- msg_begin="`tput smso 2>/dev/null`"
- AS_CASE(["$msg_begin"], ['@<:@'*m],
- [msg_begin="`echo "$msg_begin" | sed ['s/[0-9]*m$//']`"
- msg_checking="${msg_begin}33m"
- AS_IF([test ${TEST_COLORS:+set}], [
- msg_result_yes=[`expr ":$TEST_COLORS:" : ".*:pass=\([^:]*\):"`]
- msg_result_no=[`expr ":$TEST_COLORS:" : ".*:fail=\([^:]*\):"`]
- msg_result_other=[`expr ":$TEST_COLORS:" : ".*:skip=\([^:]*\):"`]
- ])
- msg_result_yes="${msg_begin}${msg_result_yes:-32;1}m"
- msg_result_no="${msg_begin}${msg_result_no:-31;1}m"
- msg_result_other="${msg_begin}${msg_result_other:-33;1}m"
- msg_reset="${msg_begin}m"
- ])
- AS_UNSET(msg_begin)
- ])
- AS_REQUIRE_SHELL_FN([colorize_result],
- [AS_FUNCTION_DESCRIBE([colorize_result], [MSG], [Colorize result])],
- [AS_CASE(["$[]1"],
- [yes], [AS_ECHO(["${msg_result_yes}$[]1${msg_reset}]")],
- [no], [AS_ECHO(["${msg_result_no}$[]1${msg_reset}]")],
- [AS_ECHO(["${msg_result_other}$[]1${msg_reset}]")])])
-])
-
-AC_DEFUN([COLORIZE_RESULT], [AC_REQUIRE([_COLORIZE_RESULT_PREPARE])dnl
- AS_LITERAL_IF([$1],
- [m4_case([$1],
- [yes], [AS_ECHO(["${msg_result_yes}$1${msg_reset}"])],
- [no], [AS_ECHO(["${msg_result_no}$1${msg_reset}"])],
- [AS_ECHO(["${msg_result_other}$1${msg_reset}"])])],
- [colorize_result "$1"]) dnl
-])
-
-AC_DEFUN([AC_CHECKING],[dnl
-AC_REQUIRE([_COLORIZE_RESULT_PREPARE])dnl
-AS_MESSAGE([checking ${msg_checking}$1${msg_reset}...])])
-
-AC_DEFUN([AC_MSG_RESULT], [dnl
-{ _AS_ECHO_LOG([result: $1])
-COLORIZE_RESULT([$1]); dnl
-}])
diff --git a/aclocal.m4 b/aclocal.m4
index 18ba297b05..e69de29bb2 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,15 +0,0 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
-
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
-
-# This file 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.
-
-m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
-m4_include([acinclude.m4])
diff --git a/addr2line.c b/addr2line.c
index 55cc997f77..0029cffbca 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -8,14 +8,26 @@
**********************************************************************/
-#include "ruby/config.h"
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wgnu-empty-initializer"
+#pragma clang diagnostic ignored "-Wgcc-compat"
+#endif
+
+#include "ruby/internal/config.h"
+#include "ruby/defines.h"
#include "ruby/missing.h"
#include "addr2line.h"
#include <stdio.h>
#include <errno.h>
-#ifdef USE_ELF
+#ifdef HAVE_LIBPROC_H
+#include <libproc.h>
+#endif
+
+#include "ruby/internal/stdbool.h"
+
+#if defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H)
#include <fcntl.h>
#include <limits.h>
@@ -28,12 +40,6 @@
#include <sys/stat.h>
#include <unistd.h>
-#ifdef __OpenBSD__
-#include <elf_abi.h>
-#else
-#include <elf.h>
-#endif
-
/* Make alloca work the best possible way. */
#ifdef __GNUC__
# ifndef alloca
@@ -57,24 +63,20 @@ void *alloca();
# include <dlfcn.h>
#endif
-#define DW_LNS_copy 0x01
-#define DW_LNS_advance_pc 0x02
-#define DW_LNS_advance_line 0x03
-#define DW_LNS_set_file 0x04
-#define DW_LNS_set_column 0x05
-#define DW_LNS_negate_stmt 0x06
-#define DW_LNS_set_basic_block 0x07
-#define DW_LNS_const_add_pc 0x08
-#define DW_LNS_fixed_advance_pc 0x09
-#define DW_LNS_set_prologue_end 0x0a /* DWARF3 */
-#define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */
-#define DW_LNS_set_isa 0x0c /* DWARF3 */
+#ifdef HAVE_MACH_O_LOADER_H
+# include <crt_externs.h>
+# include <mach-o/fat.h>
+# include <mach-o/loader.h>
+# include <mach-o/nlist.h>
+# include <mach-o/stab.h>
+#endif
-/* Line number extended opcode name. */
-#define DW_LNE_end_sequence 0x01
-#define DW_LNE_set_address 0x02
-#define DW_LNE_define_file 0x03
-#define DW_LNE_set_discriminator 0x04 /* DWARF4 */
+#ifdef USE_ELF
+# ifdef __OpenBSD__
+# include <elf_abi.h>
+# else
+# include <elf.h>
+# endif
#ifndef ElfW
# if SIZEOF_VOIDP == 8
@@ -90,13 +92,44 @@ void *alloca();
# define ELF_ST_TYPE ELF32_ST_TYPE
# endif
#endif
+#endif
+
+#ifdef SHF_COMPRESSED
+# if defined(ELFCOMPRESS_ZLIB) && defined(HAVE_LIBZ)
+ /* FreeBSD 11.0 lacks ELFCOMPRESS_ZLIB */
+# include <zlib.h>
+# define SUPPORT_COMPRESSED_DEBUG_LINE
+# endif
+#else /* compatibility with glibc < 2.22 */
+# define SHF_COMPRESSED 0
+#endif
+
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
-int kprintf(const char *fmt, ...);
+#define DW_LNS_copy 0x01
+#define DW_LNS_advance_pc 0x02
+#define DW_LNS_advance_line 0x03
+#define DW_LNS_set_file 0x04
+#define DW_LNS_set_column 0x05
+#define DW_LNS_negate_stmt 0x06
+#define DW_LNS_set_basic_block 0x07
+#define DW_LNS_const_add_pc 0x08
+#define DW_LNS_fixed_advance_pc 0x09
+#define DW_LNS_set_prologue_end 0x0a /* DWARF3 */
+#define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */
+#define DW_LNS_set_isa 0x0c /* DWARF3 */
-typedef struct {
+/* Line number extended opcode name. */
+#define DW_LNE_end_sequence 0x01
+#define DW_LNE_set_address 0x02
+#define DW_LNE_define_file 0x03
+#define DW_LNE_set_discriminator 0x04 /* DWARF4 */
+
+PRINTF_ARGS(static int kprintf(const char *fmt, ...), 1, 2);
+
+typedef struct line_info {
const char *dirname;
const char *filename;
const char *path; /* object path */
@@ -105,19 +138,56 @@ typedef struct {
uintptr_t base_addr;
uintptr_t saddr;
const char *sname; /* function name */
+
+ struct line_info *next;
} line_info_t;
-typedef struct obj_info obj_info_t;
-struct obj_info {
+
+struct dwarf_section {
+ char *ptr;
+ size_t size;
+ uint64_t flags;
+};
+
+typedef struct obj_info {
const char *path; /* object path */
- int fd;
- void *mapped;
+ char *mapped;
size_t mapped_size;
+ void *uncompressed;
uintptr_t base_addr;
- obj_info_t *next;
+ uintptr_t vmaddr;
+ struct dwarf_section debug_abbrev;
+ struct dwarf_section debug_info;
+ struct dwarf_section debug_line;
+ struct dwarf_section debug_ranges;
+ struct dwarf_section debug_str;
+ struct obj_info *next;
+} obj_info_t;
+
+#define DWARF_SECTION_COUNT 5
+
+static struct dwarf_section *
+obj_dwarf_section_at(obj_info_t *obj, int n)
+{
+ struct dwarf_section *ary[] = {
+ &obj->debug_abbrev,
+ &obj->debug_info,
+ &obj->debug_line,
+ &obj->debug_ranges,
+ &obj->debug_str
+ };
+ if (n < 0 || DWARF_SECTION_COUNT <= n) {
+ abort();
+ }
+ return ary[n];
+}
+
+struct debug_section_definition {
+ const char *name;
+ struct dwarf_section *dwarf;
};
/* Avoid consuming stack as this module may be used from signal handler */
-static char binary_filename[PATH_MAX];
+static char binary_filename[PATH_MAX + 1];
static unsigned long
uleb128(char **p)
@@ -177,8 +247,7 @@ get_nth_dirname(unsigned long dir, char *p)
}
static void
-fill_filename(int file, char *include_directories, char *filenames,
- line_info_t *line)
+fill_filename(int file, char *include_directories, char *filenames, line_info_t *line, obj_info_t *obj)
{
int i;
char *p = filenames;
@@ -188,8 +257,8 @@ fill_filename(int file, char *include_directories, char *filenames,
filename = p;
if (!*p) {
/* Need to output binary file name? */
- kprintf("Unexpected file number %d in %s\n",
- file, binary_filename);
+ kprintf("Unexpected file number %d in %s at %tx\n",
+ file, binary_filename, filenames - obj->mapped);
return;
}
while (*p) p++;
@@ -213,104 +282,128 @@ fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
obj_info_t *obj, line_info_t *lines, int offset)
{
int i;
- addr += obj->base_addr;
+ addr += obj->base_addr - obj->vmaddr;
for (i = offset; i < num_traces; i++) {
uintptr_t a = (uintptr_t)traces[i];
/* We assume one line code doesn't result >100 bytes of native code.
We may want more reliable way eventually... */
if (addr < a && a < addr + 100) {
- fill_filename(file, include_directories, filenames, &lines[i]);
+ fill_filename(file, include_directories, filenames, &lines[i], obj);
lines[i].line = line;
}
}
}
+struct LineNumberProgramHeader {
+ uint64_t unit_length;
+ uint16_t version;
+ uint8_t format; /* 4 or 8 */
+ uint64_t header_length;
+ uint8_t minimum_instruction_length;
+ uint8_t maximum_operations_per_instruction;
+ uint8_t default_is_stmt;
+ int8_t line_base;
+ uint8_t line_range;
+ uint8_t opcode_base;
+ /* uint8_t standard_opcode_lengths[opcode_base-1]; */
+ const char *include_directories;
+ const char *filenames;
+ const char *cu_start;
+ const char *cu_end;
+};
+
static int
-parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
- obj_info_t *obj, line_info_t *lines, int offset)
+parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
{
- char *p, *cu_end, *cu_start, *include_directories, *filenames;
- unsigned long unit_length;
- int default_is_stmt, line_base;
- unsigned int header_length, minimum_instruction_length, line_range,
- opcode_base;
- /* unsigned char *standard_opcode_lengths; */
-
- /* The registers. */
- unsigned long addr = 0;
- unsigned int file = 1;
- unsigned int line = 1;
- /* unsigned int column = 0; */
- int is_stmt;
- /* int basic_block = 0; */
- /* int end_sequence = 0; */
- /* int prologue_end = 0; */
- /* int epilogue_begin = 0; */
- /* unsigned int isa = 0; */
-
- p = *debug_line;
-
- unit_length = *(unsigned int *)p;
- p += sizeof(unsigned int);
- if (unit_length == 0xffffffff) {
- unit_length = *(unsigned long *)p;
- p += sizeof(unsigned long);
+ const char *p = *pp;
+ header->unit_length = *(uint32_t *)p;
+ p += sizeof(uint32_t);
+
+ header->format = 4;
+ if (header->unit_length == 0xffffffff) {
+ header->unit_length = *(uint64_t *)p;
+ p += sizeof(uint64_t);
+ header->format = 8;
}
- cu_end = p + unit_length;
-
- /*dwarf_version = *(unsigned short *)p;*/
- p += 2;
-
- header_length = *(unsigned int *)p;
- p += sizeof(unsigned int);
-
- cu_start = p + header_length;
+ header->cu_end = p + header->unit_length;
- minimum_instruction_length = *(unsigned char *)p;
- p++;
-
- is_stmt = default_is_stmt = *(unsigned char *)p;
- p++;
+ header->version = *(uint16_t *)p;
+ p += sizeof(uint16_t);
+ if (header->version > 4) return -1;
- line_base = *(signed char *)p;
- p++;
+ header->header_length = header->format == 4 ? *(uint32_t *)p : *(uint64_t *)p;
+ p += header->format;
+ header->cu_start = p + header->header_length;
- line_range = *(unsigned char *)p;
- p++;
+ header->minimum_instruction_length = *(uint8_t *)p++;
- opcode_base = *(unsigned char *)p;
- p++;
+ if (header->version >= 4) {
+ /* maximum_operations_per_instruction = *(uint8_t *)p; */
+ if (*p != 1) return -1; /* For non-VLIW architectures, this field is 1 */
+ p++;
+ }
- /* standard_opcode_lengths = (unsigned char *)p - 1; */
- p += opcode_base - 1;
+ header->default_is_stmt = *(uint8_t *)p++;
+ header->line_base = *(int8_t *)p++;
+ header->line_range = *(uint8_t *)p++;
+ header->opcode_base = *(uint8_t *)p++;
+ /* header->standard_opcode_lengths = (uint8_t *)p - 1; */
+ p += header->opcode_base - 1;
- include_directories = p;
+ header->include_directories = p;
/* temporary measure for compress-debug-sections */
- if (p >= cu_end) return -1;
+ if (p >= header->cu_end) return -1;
/* skip include directories */
while (*p) {
- p = memchr(p, '\0', cu_end - p);
+ p = memchr(p, '\0', header->cu_end - p);
if (!p) return -1;
p++;
}
p++;
- filenames = p;
+ header->filenames = p;
- p = cu_start;
+ *pp = header->cu_start;
+
+ return 0;
+}
+
+static int
+parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
+ obj_info_t *obj, line_info_t *lines, int offset)
+{
+ const char *p = (const char *)*debug_line;
+ struct LineNumberProgramHeader header;
+
+ /* The registers. */
+ unsigned long addr = 0;
+ unsigned int file = 1;
+ unsigned int line = 1;
+ /* unsigned int column = 0; */
+ int is_stmt;
+ /* int basic_block = 0; */
+ /* int end_sequence = 0; */
+ /* int prologue_end = 0; */
+ /* int epilogue_begin = 0; */
+ /* unsigned int isa = 0; */
+
+ if (parse_debug_line_header(&p, &header))
+ return -1;
+ is_stmt = header.default_is_stmt;
#define FILL_LINE() \
do { \
fill_line(num_traces, traces, addr, file, line, \
- include_directories, filenames, \
+ (char *)header.include_directories, \
+ (char *)header.filenames, \
obj, lines, offset); \
/*basic_block = prologue_end = epilogue_begin = 0;*/ \
} while (0)
- while (p < cu_end) {
+ while (p < header.cu_end) {
unsigned long a;
unsigned char op = *p++;
switch (op) {
@@ -318,19 +411,19 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
FILL_LINE();
break;
case DW_LNS_advance_pc:
- a = uleb128(&p);
+ a = uleb128((char **)&p);
addr += a;
break;
case DW_LNS_advance_line: {
- long a = sleb128(&p);
+ long a = sleb128((char **)&p);
line += a;
break;
}
case DW_LNS_set_file:
- file = (unsigned int)uleb128(&p);
+ file = (unsigned int)uleb128((char **)&p);
break;
case DW_LNS_set_column:
- /*column = (unsigned int)*/(void)uleb128(&p);
+ /*column = (unsigned int)*/(void)uleb128((char **)&p);
break;
case DW_LNS_negate_stmt:
is_stmt = !is_stmt;
@@ -339,12 +432,13 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
/*basic_block = 1; */
break;
case DW_LNS_const_add_pc:
- a = ((255 - opcode_base) / line_range) *
- minimum_instruction_length;
+ a = ((255UL - header.opcode_base) / header.line_range) *
+ header.minimum_instruction_length;
addr += a;
break;
case DW_LNS_fixed_advance_pc:
- a = *(unsigned char *)p++;
+ a = *(uint16_t *)p;
+ p += sizeof(uint16_t);
addr += a;
break;
case DW_LNS_set_prologue_end:
@@ -354,7 +448,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
/* epilogue_begin = 1; */
break;
case DW_LNS_set_isa:
- /* isa = (unsigned int)*/(void)uleb128(&p);
+ /* isa = (unsigned int)*/(void)uleb128((char **)&p);
break;
case 0:
a = *(unsigned char *)p++;
@@ -367,7 +461,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
file = 1;
line = 1;
/* column = 0; */
- is_stmt = default_is_stmt;
+ is_stmt = header.default_is_stmt;
/* end_sequence = 0; */
/* isa = 0; */
break;
@@ -381,7 +475,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
break;
case DW_LNE_set_discriminator:
/* TODO:currently ignore */
- uleb128(&p);
+ uleb128((char **)&p);
break;
default:
kprintf("Unknown extended opcode: %d in %s\n",
@@ -389,18 +483,16 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
}
break;
default: {
- unsigned long addr_incr;
- unsigned long line_incr;
- a = op - opcode_base;
- addr_incr = (a / line_range) * minimum_instruction_length;
- line_incr = line_base + (a % line_range);
- addr += (unsigned int)addr_incr;
- line += (unsigned int)line_incr;
+ uint8_t adjusted_opcode = op - header.opcode_base;
+ uint8_t operation_advance = adjusted_opcode / header.line_range;
+ /* NOTE: this code doesn't support VLIW */
+ addr += operation_advance * header.minimum_instruction_length;
+ line += header.line_base + (adjusted_opcode % header.line_range);
FILL_LINE();
}
}
}
- *debug_line = p;
+ *debug_line = (char *)p;
return 0;
}
@@ -434,13 +526,26 @@ append_obj(obj_info_t **objp)
*objp = newobj;
}
+#ifdef USE_ELF
+/* Ideally we should check 4 paths to follow gnu_debuglink:
+ *
+ * - /usr/lib/debug/.build-id/ab/cdef1234.debug
+ * - /usr/bin/ruby.debug
+ * - /usr/bin/.debug/ruby.debug
+ * - /usr/lib/debug/usr/bin/ruby.debug.
+ *
+ * but we handle only two cases for now as the two formats are
+ * used by some linux distributions.
+ *
+ * See GDB's info for detail.
+ * https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
+ */
+
+// check the path pattern of "/usr/lib/debug/usr/bin/ruby.debug"
static void
follow_debuglink(const char *debuglink, int num_traces, void **traces,
obj_info_t **objp, line_info_t *lines, int offset)
{
- /* Ideally we should check 4 paths to follow gnu_debuglink,
- but we handle only one case for now as this format is used
- by some linux distributions. See GDB's info for detail. */
static const char global_debug_dir[] = "/usr/lib/debug";
const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
char *p;
@@ -468,6 +573,1085 @@ follow_debuglink(const char *debuglink, int num_traces, void **traces,
fill_lines(num_traces, traces, 0, objp, lines, offset);
}
+// check the path pattern of "/usr/lib/debug/.build-id/ab/cdef1234.debug"
+static void
+follow_debuglink_build_id(const char *build_id, size_t build_id_size, int num_traces, void **traces,
+ obj_info_t **objp, line_info_t *lines, int offset)
+{
+ static const char global_debug_dir[] = "/usr/lib/debug/.build-id/";
+ const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
+ char *p;
+ obj_info_t *o1 = *objp, *o2;
+ size_t i;
+
+ if (PATH_MAX < global_debug_dir_len + 1 + build_id_size * 2 + 6) return;
+
+ memcpy(binary_filename, global_debug_dir, global_debug_dir_len);
+ p = binary_filename + global_debug_dir_len;
+ for (i = 0; i < build_id_size; i++) {
+ static const char tbl[] = "0123456789abcdef";
+ unsigned char n = build_id[i];
+ *p++ = tbl[n / 16];
+ *p++ = tbl[n % 16];
+ if (i == 0) *p++ = '/';
+ }
+ strcpy(p, ".debug");
+
+ append_obj(objp);
+ o2 = *objp;
+ o2->base_addr = o1->base_addr;
+ o2->path = o1->path;
+ fill_lines(num_traces, traces, 0, objp, lines, offset);
+}
+#endif
+
+enum
+{
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_subprogram = 0x2e,
+};
+
+/* Attributes encodings */
+enum
+{
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ /* Reserved 0x04 */
+ /* Reserved 0x05 */
+ /* Reserved 0x06 */
+ /* Reserved 0x07 */
+ /* Reserved 0x08 */
+ DW_AT_ordering = 0x09,
+ /* Reserved 0x0a */
+ DW_AT_byte_size = 0x0b,
+ /* Reserved 0x0c */
+ DW_AT_bit_size = 0x0d,
+ /* Reserved 0x0e */
+ /* Reserved 0x0f */
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ /* Reserved 0x14 */
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ /* Reserved 0x1f */
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ /* Reserved 0x23 */
+ /* Reserved 0x24 */
+ DW_AT_producer = 0x25,
+ /* Reserved 0x26 */
+ DW_AT_prototyped = 0x27,
+ /* Reserved 0x28 */
+ /* Reserved 0x29 */
+ DW_AT_return_addr = 0x2a,
+ /* Reserved 0x2b */
+ DW_AT_start_scope = 0x2c,
+ /* Reserved 0x2d */
+ DW_AT_bit_stride = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ /* Reserved 0x30 */
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ /* Reserved 0x43 */
+ DW_AT_namelist_item = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ DW_AT_allocated = 0x4e,
+ DW_AT_associated = 0x4f,
+ DW_AT_data_location = 0x50,
+ DW_AT_byte_stride = 0x51,
+ DW_AT_entry_pc = 0x52,
+ DW_AT_use_UTF8 = 0x53,
+ DW_AT_extension = 0x54,
+ DW_AT_ranges = 0x55,
+ DW_AT_trampoline = 0x56,
+ DW_AT_call_column = 0x57,
+ DW_AT_call_file = 0x58,
+ DW_AT_call_line = 0x59,
+ DW_AT_description = 0x5a,
+ DW_AT_binary_scale = 0x5b,
+ DW_AT_decimal_scale = 0x5c,
+ DW_AT_small = 0x5d,
+ DW_AT_decimal_sign = 0x5e,
+ DW_AT_digit_count = 0x5f,
+ DW_AT_picture_string = 0x60,
+ DW_AT_mutable = 0x61,
+ DW_AT_threads_scaled = 0x62,
+ DW_AT_explicit = 0x63,
+ DW_AT_object_pointer = 0x64,
+ DW_AT_endianity = 0x65,
+ DW_AT_elemental = 0x66,
+ DW_AT_pure = 0x67,
+ DW_AT_recursive = 0x68,
+ DW_AT_signature = 0x69,
+ DW_AT_main_subprogram = 0x6a,
+ DW_AT_data_bit_offset = 0x6b,
+ DW_AT_const_expr = 0x6c,
+ DW_AT_enum_class = 0x6d,
+ DW_AT_linkage_name = 0x6e,
+ DW_AT_string_length_bit_size = 0x6f,
+ DW_AT_string_length_byte_size = 0x70,
+ DW_AT_rank = 0x71,
+ DW_AT_str_offsets_base = 0x72,
+ DW_AT_addr_base = 0x73,
+ DW_AT_rnglists_base = 0x74,
+ /* Reserved 0x75 */
+ DW_AT_dwo_name = 0x76,
+ DW_AT_reference = 0x77,
+ DW_AT_rvalue_reference = 0x78,
+ DW_AT_macros = 0x79,
+ DW_AT_call_all_calls = 0x7a,
+ DW_AT_call_all_source_calls = 0x7b,
+ DW_AT_call_all_tail_calls = 0x7c,
+ DW_AT_call_return_pc = 0x7d,
+ DW_AT_call_value = 0x7e,
+ DW_AT_call_origin = 0x7f,
+ DW_AT_call_parameter = 0x80,
+ DW_AT_call_pc = 0x81,
+ DW_AT_call_tail_call = 0x82,
+ DW_AT_call_target = 0x83,
+ DW_AT_call_target_clobbered = 0x84,
+ DW_AT_call_data_location = 0x85,
+ DW_AT_call_data_value = 0x86,
+ DW_AT_noreturn = 0x87,
+ DW_AT_alignment = 0x88,
+ DW_AT_export_symbols = 0x89,
+ DW_AT_deleted = 0x8a,
+ DW_AT_defaulted = 0x8b,
+ DW_AT_loclists_base = 0x8c,
+ DW_AT_lo_user = 0x2000,
+ DW_AT_hi_user = 0x3fff
+};
+
+/* Attribute form encodings */
+enum
+{
+ DW_FORM_addr = 0x01,
+ /* Reserved 0x02 */
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16,
+ DW_FORM_sec_offset = 0x17,
+ DW_FORM_exprloc = 0x18,
+ DW_FORM_flag_present = 0x19,
+ DW_FORM_strx = 0x1a,
+ DW_FORM_addrx = 0x1b,
+ DW_FORM_ref_sup4 = 0x1c,
+ DW_FORM_strp_sup = 0x1d,
+ DW_FORM_data16 = 0x1e,
+ DW_FORM_line_strp = 0x1f,
+ DW_FORM_ref_sig8 = 0x20,
+ DW_FORM_implicit_const = 0x21,
+ DW_FORM_loclistx = 0x22,
+ DW_FORM_rnglistx = 0x23,
+ DW_FORM_ref_sup8 = 0x24,
+ DW_FORM_strx1 = 0x25,
+ DW_FORM_strx2 = 0x26,
+ DW_FORM_strx3 = 0x27,
+ DW_FORM_strx4 = 0x28,
+ DW_FORM_addrx1 = 0x29,
+ DW_FORM_addrx2 = 0x2a,
+ DW_FORM_addrx3 = 0x2b,
+ DW_FORM_addrx4 = 0x2c
+};
+
+enum {
+ VAL_none = 0,
+ VAL_cstr = 1,
+ VAL_data = 2,
+ VAL_uint = 3,
+ VAL_int = 4
+};
+
+# define ABBREV_TABLE_SIZE 256
+typedef struct {
+ obj_info_t *obj;
+ char *file;
+ char *current_cu;
+ uint64_t current_low_pc;
+ char *debug_line_cu_end;
+ char *debug_line_files;
+ char *debug_line_directories;
+ char *p;
+ char *cu_end;
+ char *pend;
+ char *q0;
+ char *q;
+ int format; // 4 or 8
+ uint8_t address_size;
+ int level;
+ char *abbrev_table[ABBREV_TABLE_SIZE];
+} DebugInfoReader;
+
+typedef struct {
+ ptrdiff_t pos;
+ int tag;
+ int has_children;
+} DIE;
+
+typedef struct {
+ union {
+ char *ptr;
+ uint64_t uint64;
+ int64_t int64;
+ } as;
+ uint64_t off;
+ uint64_t at;
+ uint64_t form;
+ size_t size;
+ int type;
+} DebugInfoValue;
+
+/* TODO: Big Endian */
+#define MERGE_2INTS(a,b,sz) (((uint64_t)(b)<<sz)|(a))
+
+static uint16_t
+get_uint16(const uint8_t *p)
+{
+ return (uint16_t)MERGE_2INTS(p[0],p[1],8);
+}
+
+static uint32_t
+get_uint32(const uint8_t *p)
+{
+ return (uint32_t)MERGE_2INTS(get_uint16(p),get_uint16(p+2),16);
+}
+
+static uint64_t
+get_uint64(const uint8_t *p)
+{
+ return MERGE_2INTS(get_uint32(p),get_uint32(p+4),32);
+}
+
+static uint8_t
+read_uint8(char **ptr)
+{
+ const unsigned char *p = (const unsigned char *)*ptr;
+ *ptr = (char *)(p + 1);
+ return *p;
+}
+
+static uint16_t
+read_uint16(char **ptr)
+{
+ const unsigned char *p = (const unsigned char *)*ptr;
+ *ptr = (char *)(p + 2);
+ return get_uint16(p);
+}
+
+static uint32_t
+read_uint24(char **ptr)
+{
+ const unsigned char *p = (const unsigned char *)*ptr;
+ *ptr = (char *)(p + 3);
+ return (*p << 16) | get_uint16(p+1);
+}
+
+static uint32_t
+read_uint32(char **ptr)
+{
+ const unsigned char *p = (const unsigned char *)*ptr;
+ *ptr = (char *)(p + 4);
+ return get_uint32(p);
+}
+
+static uint64_t
+read_uint64(char **ptr)
+{
+ const unsigned char *p = (const unsigned char *)*ptr;
+ *ptr = (char *)(p + 8);
+ return get_uint64(p);
+}
+
+static uintptr_t
+read_uintptr(char **ptr)
+{
+ const unsigned char *p = (const unsigned char *)*ptr;
+ *ptr = (char *)(p + SIZEOF_VOIDP);
+#if SIZEOF_VOIDP == 8
+ return get_uint64(p);
+#else
+ return get_uint32(p);
+#endif
+}
+
+static uint64_t
+read_uint(DebugInfoReader *reader)
+{
+ if (reader->format == 4) {
+ return read_uint32(&reader->p);
+ } else { /* 64 bit */
+ return read_uint64(&reader->p);
+ }
+}
+
+static uint64_t
+read_uleb128(DebugInfoReader *reader)
+{
+ return uleb128(&reader->p);
+}
+
+static int64_t
+read_sleb128(DebugInfoReader *reader)
+{
+ return sleb128(&reader->p);
+}
+
+static void
+debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
+{
+ reader->file = obj->mapped;
+ reader->obj = obj;
+ reader->p = obj->debug_info.ptr;
+ reader->pend = obj->debug_info.ptr + obj->debug_info.size;
+ reader->debug_line_cu_end = obj->debug_line.ptr;
+ reader->current_low_pc = 0;
+}
+
+static void
+di_read_debug_abbrev_cu(DebugInfoReader *reader)
+{
+ uint64_t prev = 0;
+ char *p = reader->q0;
+ for (;;) {
+ uint64_t abbrev_number = uleb128(&p);
+ if (abbrev_number <= prev) break;
+ if (abbrev_number < ABBREV_TABLE_SIZE) {
+ reader->abbrev_table[abbrev_number] = p;
+ }
+ prev = abbrev_number;
+ uleb128(&p); /* tag */
+ p++; /* has_children */
+ /* skip content */
+ for (;;) {
+ uint64_t at = uleb128(&p);
+ uint64_t form = uleb128(&p);
+ if (!at && !form) break;
+ }
+ }
+}
+
+static int
+di_read_debug_line_cu(DebugInfoReader *reader)
+{
+ const char *p;
+ struct LineNumberProgramHeader header;
+
+ p = (const char *)reader->debug_line_cu_end;
+ if (parse_debug_line_header(&p, &header))
+ return -1;
+
+ reader->debug_line_cu_end = (char *)header.cu_end;
+ reader->debug_line_directories = (char *)header.include_directories;
+ reader->debug_line_files = (char *)header.filenames;
+
+ return 0;
+}
+
+static void
+set_uint_value(DebugInfoValue *v, uint64_t n)
+{
+ v->as.uint64 = n;
+ v->type = VAL_uint;
+}
+
+static void
+set_int_value(DebugInfoValue *v, int64_t n)
+{
+ v->as.int64 = n;
+ v->type = VAL_int;
+}
+
+static void
+set_cstr_value(DebugInfoValue *v, char *s)
+{
+ v->as.ptr = s;
+ v->off = 0;
+ v->type = VAL_cstr;
+}
+
+static void
+set_cstrp_value(DebugInfoValue *v, char *s, uint64_t off)
+{
+ v->as.ptr = s;
+ v->off = off;
+ v->type = VAL_cstr;
+}
+
+static void
+set_data_value(DebugInfoValue *v, char *s)
+{
+ v->as.ptr = s;
+ v->type = VAL_data;
+}
+
+static const char *
+get_cstr_value(DebugInfoValue *v)
+{
+ if (v->as.ptr) {
+ return v->as.ptr + v->off;
+ } else {
+ return NULL;
+ }
+}
+
+static void
+debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v)
+{
+ switch (form) {
+ case DW_FORM_addr:
+ if (reader->address_size == 4) {
+ set_uint_value(v, read_uint32(&reader->p));
+ } else if (reader->address_size == 8) {
+ set_uint_value(v, read_uint64(&reader->p));
+ } else {
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
+ }
+ break;
+ case DW_FORM_block2:
+ v->size = read_uint16(&reader->p);
+ set_data_value(v, reader->p);
+ reader->p += v->size;
+ break;
+ case DW_FORM_block4:
+ v->size = read_uint32(&reader->p);
+ set_data_value(v, reader->p);
+ reader->p += v->size;
+ break;
+ case DW_FORM_data2:
+ set_uint_value(v, read_uint16(&reader->p));
+ break;
+ case DW_FORM_data4:
+ set_uint_value(v, read_uint32(&reader->p));
+ break;
+ case DW_FORM_data8:
+ set_uint_value(v, read_uint64(&reader->p));
+ break;
+ case DW_FORM_string:
+ v->size = strlen(reader->p);
+ set_cstr_value(v, reader->p);
+ reader->p += v->size + 1;
+ break;
+ case DW_FORM_block:
+ v->size = uleb128(&reader->p);
+ set_data_value(v, reader->p);
+ reader->p += v->size;
+ break;
+ case DW_FORM_block1:
+ v->size = read_uint8(&reader->p);
+ set_data_value(v, reader->p);
+ reader->p += v->size;
+ break;
+ case DW_FORM_data1:
+ set_uint_value(v, read_uint8(&reader->p));
+ break;
+ case DW_FORM_flag:
+ set_uint_value(v, read_uint8(&reader->p));
+ break;
+ case DW_FORM_sdata:
+ set_int_value(v, read_sleb128(reader));
+ break;
+ case DW_FORM_strp:
+ set_cstrp_value(v, reader->obj->debug_str.ptr, read_uint(reader));
+ break;
+ case DW_FORM_udata:
+ set_uint_value(v, read_uleb128(reader));
+ break;
+ case DW_FORM_ref_addr:
+ if (reader->address_size == 4) {
+ set_uint_value(v, read_uint32(&reader->p));
+ } else if (reader->address_size == 8) {
+ set_uint_value(v, read_uint64(&reader->p));
+ } else {
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
+ }
+ break;
+ case DW_FORM_ref1:
+ set_uint_value(v, read_uint8(&reader->p));
+ break;
+ case DW_FORM_ref2:
+ set_uint_value(v, read_uint16(&reader->p));
+ break;
+ case DW_FORM_ref4:
+ set_uint_value(v, read_uint32(&reader->p));
+ break;
+ case DW_FORM_ref8:
+ set_uint_value(v, read_uint64(&reader->p));
+ break;
+ case DW_FORM_ref_udata:
+ set_uint_value(v, uleb128(&reader->p));
+ break;
+ case DW_FORM_indirect:
+ /* TODO: read the referred value */
+ set_uint_value(v, uleb128(&reader->p));
+ break;
+ case DW_FORM_sec_offset:
+ set_uint_value(v, read_uint(reader)); /* offset */
+ /* addrptr: debug_addr */
+ /* lineptr: debug_line */
+ /* loclist: debug_loclists */
+ /* loclistptr: debug_loclists */
+ /* macptr: debug_macro */
+ /* rnglist: debug_rnglists */
+ /* rnglistptr: debug_rnglists */
+ /* stroffsetsptr: debug_str_offsets */
+ break;
+ case DW_FORM_exprloc:
+ v->size = (size_t)read_uleb128(reader);
+ set_data_value(v, reader->p);
+ reader->p += v->size;
+ break;
+ case DW_FORM_flag_present:
+ set_uint_value(v, 1);
+ break;
+ case DW_FORM_strx:
+ set_uint_value(v, uleb128(&reader->p));
+ break;
+ case DW_FORM_addrx:
+ /* TODO: read .debug_addr */
+ set_uint_value(v, uleb128(&reader->p));
+ break;
+ case DW_FORM_ref_sup4:
+ set_uint_value(v, read_uint32(&reader->p));
+ break;
+ case DW_FORM_strp_sup:
+ set_uint_value(v, read_uint(reader));
+ /* *p = reader->sup_file + reader->sup_str->sh_offset + ret; */
+ break;
+ case DW_FORM_data16:
+ v->size = 16;
+ set_data_value(v, reader->p);
+ reader->p += v->size;
+ break;
+ case DW_FORM_line_strp:
+ set_uint_value(v, read_uint(reader));
+ /* *p = reader->file + reader->line->sh_offset + ret; */
+ break;
+ case DW_FORM_ref_sig8:
+ set_uint_value(v, read_uint64(&reader->p));
+ break;
+ case DW_FORM_implicit_const:
+ set_int_value(v, sleb128(&reader->q));
+ break;
+ case DW_FORM_loclistx:
+ set_uint_value(v, read_uleb128(reader));
+ break;
+ case DW_FORM_rnglistx:
+ set_uint_value(v, read_uleb128(reader));
+ break;
+ case DW_FORM_ref_sup8:
+ set_uint_value(v, read_uint64(&reader->p));
+ break;
+ case DW_FORM_strx1:
+ set_uint_value(v, read_uint8(&reader->p));
+ break;
+ case DW_FORM_strx2:
+ set_uint_value(v, read_uint16(&reader->p));
+ break;
+ case DW_FORM_strx3:
+ set_uint_value(v, read_uint24(&reader->p));
+ break;
+ case DW_FORM_strx4:
+ set_uint_value(v, read_uint32(&reader->p));
+ break;
+ case DW_FORM_addrx1:
+ set_uint_value(v, read_uint8(&reader->p));
+ break;
+ case DW_FORM_addrx2:
+ set_uint_value(v, read_uint16(&reader->p));
+ break;
+ case DW_FORM_addrx3:
+ set_uint_value(v, read_uint24(&reader->p));
+ break;
+ case DW_FORM_addrx4:
+ set_uint_value(v, read_uint32(&reader->p));
+ break;
+ case 0:
+ goto fail;
+ break;
+ }
+ return;
+
+ fail:
+ fprintf(stderr, "%d: unsupported form: %#"PRIx64"\n", __LINE__, form);
+ exit(1);
+}
+
+/* find abbrev in current compilation unit */
+static char *
+di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
+{
+ char *p;
+ if (abbrev_number < ABBREV_TABLE_SIZE) {
+ return reader->abbrev_table[abbrev_number];
+ }
+ p = reader->abbrev_table[ABBREV_TABLE_SIZE-1];
+ /* skip 255th record */
+ uleb128(&p); /* tag */
+ p++; /* has_children */
+ /* skip content */
+ for (;;) {
+ uint64_t at = uleb128(&p);
+ uint64_t form = uleb128(&p);
+ if (!at && !form) break;
+ }
+ for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
+ if (n == 0) {
+ fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
+ exit(1);
+ }
+ uleb128(&p); /* tag */
+ p++; /* has_children */
+ /* skip content */
+ for (;;) {
+ uint64_t at = uleb128(&p);
+ uint64_t form = uleb128(&p);
+ if (!at && !form) break;
+ }
+ }
+ return p;
+}
+
+#if 0
+static void
+hexdump0(const unsigned char *p, size_t n)
+{
+ size_t i;
+ fprintf(stderr, " 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
+ for (i=0; i < n; i++){
+ switch (i & 15) {
+ case 0:
+ fprintf(stderr, "%02zd: %02X ", i/16, p[i]);
+ break;
+ case 15:
+ fprintf(stderr, "%02X\n", p[i]);
+ break;
+ default:
+ fprintf(stderr, "%02X ", p[i]);
+ break;
+ }
+ }
+ if ((i & 15) != 15) {
+ fprintf(stderr, "\n");
+ }
+}
+#define hexdump(p,n) hexdump0((const unsigned char *)p, n)
+
+static void
+div_inspect(DebugInfoValue *v)
+{
+ switch (v->type) {
+ case VAL_uint:
+ fprintf(stderr,"%d: type:%d size:%zx v:%lx\n",__LINE__,v->type,v->size,v->as.uint64);
+ break;
+ case VAL_int:
+ fprintf(stderr,"%d: type:%d size:%zx v:%ld\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64);
+ break;
+ case VAL_cstr:
+ fprintf(stderr,"%d: type:%d size:%zx v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr);
+ break;
+ case VAL_data:
+ fprintf(stderr,"%d: type:%d size:%zx v:\n",__LINE__,v->type,v->size);
+ hexdump(v->as.ptr, 16);
+ break;
+ }
+}
+#endif
+
+static DIE *
+di_read_die(DebugInfoReader *reader, DIE *die)
+{
+ uint64_t abbrev_number = uleb128(&reader->p);
+ if (abbrev_number == 0) {
+ reader->level--;
+ return NULL;
+ }
+
+ reader->q = di_find_abbrev(reader, abbrev_number);
+
+ die->pos = reader->p - reader->obj->debug_info.ptr - 1;
+ die->tag = (int)uleb128(&reader->q); /* tag */
+ die->has_children = *reader->q++; /* has_children */
+ if (die->has_children) {
+ reader->level++;
+ }
+ return die;
+}
+
+static DebugInfoValue *
+di_read_record(DebugInfoReader *reader, DebugInfoValue *vp)
+{
+ uint64_t at = uleb128(&reader->q);
+ uint64_t form = uleb128(&reader->q);
+ if (!at || !form) return NULL;
+ vp->at = at;
+ vp->form = form;
+ debug_info_reader_read_value(reader, form, vp);
+ return vp;
+}
+
+static void
+di_skip_records(DebugInfoReader *reader)
+{
+ for (;;) {
+ DebugInfoValue v = {{}};
+ uint64_t at = uleb128(&reader->q);
+ uint64_t form = uleb128(&reader->q);
+ if (!at || !form) return;
+ debug_info_reader_read_value(reader, form, &v);
+ }
+}
+
+typedef struct {
+ uint64_t low_pc;
+ uint64_t high_pc;
+ uint64_t ranges;
+ bool low_pc_set;
+ bool high_pc_set;
+ bool ranges_set;
+} ranges_t;
+
+static void
+ranges_set(ranges_t *ptr, DebugInfoValue *v)
+{
+ switch (v->at) {
+ case DW_AT_low_pc:
+ ptr->low_pc = v->as.uint64;
+ ptr->low_pc_set = true;
+ break;
+ case DW_AT_high_pc:
+ if (v->form == DW_FORM_addr) {
+ ptr->high_pc = v->as.uint64;
+ }
+ else {
+ ptr->high_pc = ptr->low_pc + v->as.uint64;
+ }
+ ptr->high_pc_set = true;
+ break;
+ case DW_AT_ranges:
+ ptr->ranges = v->as.uint64;
+ ptr->ranges_set = true;
+ break;
+ }
+}
+
+static uintptr_t
+ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
+{
+ if (ptr->high_pc_set) {
+ if (ptr->ranges_set || !ptr->low_pc_set) {
+ exit(1);
+ }
+ if (ptr->low_pc <= addr && addr <= ptr->high_pc) {
+ return (uintptr_t)ptr->low_pc;
+ }
+ }
+ else if (ptr->ranges_set) {
+ /* TODO: support base address selection entry */
+ char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
+ uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
+ for (;;) {
+ uintptr_t from = read_uintptr(&p);
+ uintptr_t to = read_uintptr(&p);
+ if (!from && !to) break;
+ if (from == UINTPTR_MAX) {
+ /* base address selection entry */
+ base = to;
+ }
+ else if (base + from <= addr && addr < base + to) {
+ return from;
+ }
+ }
+ }
+ else if (ptr->low_pc_set) {
+ if (ptr->low_pc == addr) {
+ return (uintptr_t)ptr->low_pc;
+ }
+ }
+ return false;
+}
+
+#if 0
+static void
+ranges_inspect(DebugInfoReader *reader, ranges_t *ptr)
+{
+ if (ptr->high_pc_set) {
+ if (ptr->ranges_set || !ptr->low_pc_set) {
+ fprintf(stderr,"low_pc_set:%d high_pc_set:%d ranges_set:%d\n",ptr->low_pc_set,ptr->high_pc_set,ptr->ranges_set);
+ exit(1);
+ }
+ fprintf(stderr,"low_pc:%"PRIx64" high_pc:%"PRIx64"\n",ptr->low_pc,ptr->high_pc);
+ }
+ else if (ptr->ranges_set) {
+ char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
+ fprintf(stderr,"low_pc:%"PRIx64" ranges:%"PRIx64" %lx ",ptr->low_pc,ptr->ranges, p-reader->obj->mapped);
+ for (;;) {
+ uintptr_t from = read_uintptr(&p);
+ uintptr_t to = read_uintptr(&p);
+ if (!from && !to) break;
+ fprintf(stderr,"%"PRIx64"-%"PRIx64" ",ptr->low_pc+from,ptr->low_pc+to);
+ }
+ fprintf(stderr,"\n");
+ }
+ else if (ptr->low_pc_set) {
+ fprintf(stderr,"low_pc:%"PRIx64"\n",ptr->low_pc);
+ }
+ else {
+ fprintf(stderr,"empty\n");
+ }
+}
+#endif
+
+static int
+di_read_cu(DebugInfoReader *reader)
+{
+ uint64_t unit_length;
+ uint16_t version;
+ uint64_t debug_abbrev_offset;
+ reader->format = 4;
+ reader->current_cu = reader->p;
+ unit_length = read_uint32(&reader->p);
+ if (unit_length == 0xffffffff) {
+ unit_length = read_uint64(&reader->p);
+ reader->format = 8;
+ }
+ reader->cu_end = reader->p + unit_length;
+ version = read_uint16(&reader->p);
+ if (version > 5) {
+ return -1;
+ }
+ else if (version == 5) {
+ /* unit_type = */ read_uint8(&reader->p);
+ reader->address_size = read_uint8(&reader->p);
+ debug_abbrev_offset = read_uint(reader);
+ }
+ else {
+ debug_abbrev_offset = read_uint(reader);
+ reader->address_size = read_uint8(&reader->p);
+ }
+ reader->q0 = reader->obj->debug_abbrev.ptr + debug_abbrev_offset;
+
+ reader->level = 0;
+ di_read_debug_abbrev_cu(reader);
+ if (di_read_debug_line_cu(reader)) return -1;
+
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER_BUILD_DATE)
+ /* Though DWARF specifies "the applicable base address defaults to the base
+ address of the compilation unit", but GCC seems to use zero as default */
+#else
+ do {
+ DIE die;
+
+ if (!di_read_die(reader, &die)) continue;
+
+ if (die.tag != DW_TAG_compile_unit) {
+ di_skip_records(reader);
+ break;
+ }
+
+ /* enumerate abbrev */
+ for (;;) {
+ DebugInfoValue v = {{}};
+ if (!di_read_record(reader, &v)) break;
+ switch (v.at) {
+ case DW_AT_low_pc:
+ reader->current_low_pc = v.as.uint64;
+ break;
+ }
+ }
+ } while (0);
+#endif
+ return 0;
+}
+
+static void
+read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_info_t *line)
+{
+ char *p = reader->p;
+ char *q = reader->q;
+ int level = reader->level;
+ DIE die;
+
+ reader->p = reader->current_cu + abstract_origin;
+ if (!di_read_die(reader, &die)) goto finish;
+
+ /* enumerate abbrev */
+ for (;;) {
+ DebugInfoValue v = {{}};
+ if (!di_read_record(reader, &v)) break;
+ switch (v.at) {
+ case DW_AT_name:
+ line->sname = get_cstr_value(&v);
+ break;
+ }
+ }
+
+ finish:
+ reader->p = p;
+ reader->q = q;
+ reader->level = level;
+}
+
+static void
+debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
+ line_info_t *lines, int offset) {
+ while (reader->p < reader->cu_end) {
+ DIE die;
+ ranges_t ranges = {};
+ line_info_t line = {};
+
+ if (!di_read_die(reader, &die)) continue;
+ /* fprintf(stderr,"%d:%tx: <%d>\n",__LINE__,die.pos,reader->level,die.tag); */
+
+ if (die.tag != DW_TAG_subprogram && die.tag != DW_TAG_inlined_subroutine) {
+ skip_die:
+ di_skip_records(reader);
+ continue;
+ }
+
+ /* enumerate abbrev */
+ for (;;) {
+ DebugInfoValue v = {{}};
+ /* ptrdiff_t pos = reader->p - reader->p0; */
+ if (!di_read_record(reader, &v)) break;
+ /* fprintf(stderr,"\n%d:%tx: AT:%lx FORM:%lx\n",__LINE__,pos,v.at,v.form); */
+ /* div_inspect(&v); */
+ switch (v.at) {
+ case DW_AT_name:
+ line.sname = get_cstr_value(&v);
+ break;
+ case DW_AT_call_file:
+ fill_filename((int)v.as.uint64, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
+ break;
+ case DW_AT_call_line:
+ line.line = (int)v.as.uint64;
+ break;
+ case DW_AT_low_pc:
+ case DW_AT_high_pc:
+ case DW_AT_ranges:
+ ranges_set(&ranges, &v);
+ break;
+ case DW_AT_declaration:
+ goto skip_die;
+ case DW_AT_inline:
+ /* 1 or 3 */
+ break; /* goto skip_die; */
+ case DW_AT_abstract_origin:
+ read_abstract_origin(reader, v.as.uint64, &line);
+ break; /* goto skip_die; */
+ }
+ }
+ /* ranges_inspect(reader, &ranges); */
+ /* fprintf(stderr,"%d:%tx: %x ",__LINE__,diepos,die.tag); */
+ for (int i=offset; i < num_traces; i++) {
+ uintptr_t addr = (uintptr_t)traces[i];
+ uintptr_t offset = addr - reader->obj->base_addr + reader->obj->vmaddr;
+ uintptr_t saddr = ranges_include(reader, &ranges, offset);
+ if (saddr) {
+ /* fprintf(stderr, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
+ if (lines[i].sname) {
+ line_info_t *lp = malloc(sizeof(line_info_t));
+ memcpy(lp, &lines[i], sizeof(line_info_t));
+ lines[i].next = lp;
+ lp->dirname = line.dirname;
+ lp->filename = line.filename;
+ lp->line = line.line;
+ lp->saddr = 0;
+ }
+ lines[i].path = reader->obj->path;
+ lines[i].base_addr = line.base_addr;
+ lines[i].sname = line.sname;
+ lines[i].saddr = saddr + reader->obj->base_addr - reader->obj->vmaddr;
+ }
+ }
+ }
+}
+
+#ifdef USE_ELF
+static unsigned long
+uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr)
+{
+ *ptr = NULL;
+#ifdef SUPPORT_COMPRESSED_DEBUG_LINE
+ ElfW(Chdr) *chdr = (ElfW(Chdr) *)(file + shdr->sh_offset);
+ unsigned long destsize = chdr->ch_size;
+ int ret = 0;
+
+ if (chdr->ch_type != ELFCOMPRESS_ZLIB) {
+ /* unsupported compression type */
+ return 0;
+ }
+
+ *ptr = malloc(destsize);
+ if (!*ptr) return 0;
+ ret = uncompress((Bytef *)*ptr, &destsize,
+ (const Bytef*)chdr + sizeof(ElfW(Chdr)),
+ shdr->sh_size - sizeof(ElfW(Chdr)));
+ if (ret != Z_OK) goto fail;
+ return destsize;
+
+fail:
+ free(*ptr);
+ *ptr = NULL;
+#endif
+ return 0;
+}
+
/* read file and fill lines */
static uintptr_t
fill_lines(int num_traces, void **traces, int check_debuglink,
@@ -475,10 +1659,10 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
{
int i, j;
char *shstr;
- char *section_name;
ElfW(Ehdr) *ehdr;
ElfW(Shdr) *shdr, *shstr_shdr;
- ElfW(Shdr) *debug_line_shdr = NULL, *gnu_debuglink_shdr = NULL;
+ ElfW(Shdr) *gnu_debuglink_shdr = NULL;
+ ElfW(Shdr) *note_gnu_build_id = NULL;
int fd;
off_t filesize;
char *file;
@@ -514,6 +1698,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
kprintf("mmap: %s\n", strerror(e));
goto fail;
}
+ close(fd);
ehdr = (ElfW(Ehdr) *)file;
if (memcmp(ehdr->e_ident, "\177ELF", 4) != 0) {
@@ -521,11 +1706,8 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
* Huh? Maybe filename was overridden by setproctitle() and
* it match non-elf file.
*/
- close(fd);
goto fail;
}
-
- obj->fd = fd;
obj->mapped = file;
obj->mapped_size = (size_t)filesize;
@@ -535,7 +1717,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
shstr = file + shstr_shdr->sh_offset;
for (i = 0; i < ehdr->e_shnum; i++) {
- section_name = shstr + shdr[i].sh_name;
+ char *section_name = shstr + shdr[i].sh_name;
switch (shdr[i].sh_type) {
case SHT_STRTAB:
if (!strcmp(section_name, ".strtab")) {
@@ -553,13 +1735,40 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
/* if (!strcmp(section_name, ".dynsym")) */
dynsym_shdr = shdr + i;
break;
+ case SHT_NOTE:
+ if (!strcmp(section_name, ".note.gnu.build-id")) {
+ note_gnu_build_id = shdr + i;
+ }
+ break;
case SHT_PROGBITS:
- if (!strcmp(section_name, ".debug_line")) {
- debug_line_shdr = shdr + i;
- }
- else if (!strcmp(section_name, ".gnu_debuglink")) {
+ if (!strcmp(section_name, ".gnu_debuglink")) {
gnu_debuglink_shdr = shdr + i;
}
+ else {
+ const char *debug_section_names[] = {
+ ".debug_abbrev",
+ ".debug_info",
+ ".debug_line",
+ ".debug_ranges",
+ ".debug_str"
+ };
+
+ for (j=0; j < DWARF_SECTION_COUNT; j++) {
+ struct dwarf_section *s = obj_dwarf_section_at(obj, j);
+
+ if (strcmp(section_name, debug_section_names[j]) != 0)
+ continue;
+
+ s->ptr = file + shdr[i].sh_offset;
+ s->size = shdr[i].sh_size;
+ s->flags = shdr[i].sh_flags;
+ if (s->flags & SHF_COMPRESSED) {
+ s->size = uncompress_debug_section(&shdr[i], file, &s->ptr);
+ if (!s->size) goto fail;
+ }
+ break;
+ }
+ }
break;
}
}
@@ -571,20 +1780,22 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
char *strtab = file + dynstr_shdr->sh_offset;
ElfW(Sym) *symtab = (ElfW(Sym) *)(file + dynsym_shdr->sh_offset);
int symtab_count = (int)(dynsym_shdr->sh_size / sizeof(ElfW(Sym)));
- for (j = 0; j < symtab_count; j++) {
- ElfW(Sym) *sym = &symtab[j];
- Dl_info info;
- void *h, *s;
- if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue;
- h = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
- if (!h) continue;
- s = dlsym(h, strtab + sym->st_name);
- if (!s) continue;
- if (dladdr(s, &info)) {
- dladdr_fbase = (uintptr_t)info.dli_fbase;
- break;
- }
- }
+ void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
+ if (handle) {
+ for (j = 0; j < symtab_count; j++) {
+ ElfW(Sym) *sym = &symtab[j];
+ Dl_info info;
+ void *s;
+ if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size == 0) continue;
+ s = dlsym(handle, strtab + sym->st_name);
+ if (s && dladdr(s, &info)) {
+ obj->base_addr = dladdr_fbase;
+ dladdr_fbase = (uintptr_t)info.dli_fbase;
+ break;
+ }
+ }
+ dlclose(handle);
+ }
if (ehdr->e_type == ET_EXEC) {
obj->base_addr = 0;
}
@@ -595,33 +1806,48 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
}
}
- if (!symtab_shdr) {
- symtab_shdr = dynsym_shdr;
- strtab_shdr = dynstr_shdr;
- }
-
- if (symtab_shdr && strtab_shdr) {
- char *strtab = file + strtab_shdr->sh_offset;
- ElfW(Sym) *symtab = (ElfW(Sym) *)(file + symtab_shdr->sh_offset);
- int symtab_count = (int)(symtab_shdr->sh_size / sizeof(ElfW(Sym)));
- for (j = 0; j < symtab_count; j++) {
- ElfW(Sym) *sym = &symtab[j];
- uintptr_t saddr = (uintptr_t)sym->st_value + obj->base_addr;
- if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue;
- for (i = offset; i < num_traces; i++) {
- uintptr_t d = (uintptr_t)traces[i] - saddr;
- if (lines[i].line > 0 || d <= 0 || d > (uintptr_t)sym->st_size)
- continue;
- /* fill symbol name and addr from .symtab */
- lines[i].sname = strtab + sym->st_name;
- lines[i].saddr = saddr;
- lines[i].path = obj->path;
- lines[i].base_addr = obj->base_addr;
- }
- }
+ if (obj->debug_info.ptr && obj->debug_abbrev.ptr) {
+ DebugInfoReader reader;
+ debug_info_reader_init(&reader, obj);
+ i = 0;
+ while (reader.p < reader.pend) {
+ /* fprintf(stderr, "%d:%tx: CU[%d]\n", __LINE__, reader.p - reader.obj->debug_info.ptr, i++); */
+ if (di_read_cu(&reader)) goto use_symtab;
+ debug_info_read(&reader, num_traces, traces, lines, offset);
+ }
+ }
+ else {
+ /* This file doesn't have dwarf, use symtab or dynsym */
+use_symtab:
+ if (!symtab_shdr) {
+ /* This file doesn't have symtab, use dynsym instead */
+ symtab_shdr = dynsym_shdr;
+ strtab_shdr = dynstr_shdr;
+ }
+
+ if (symtab_shdr && strtab_shdr) {
+ char *strtab = file + strtab_shdr->sh_offset;
+ ElfW(Sym) *symtab = (ElfW(Sym) *)(file + symtab_shdr->sh_offset);
+ int symtab_count = (int)(symtab_shdr->sh_size / sizeof(ElfW(Sym)));
+ for (j = 0; j < symtab_count; j++) {
+ ElfW(Sym) *sym = &symtab[j];
+ uintptr_t saddr = (uintptr_t)sym->st_value + obj->base_addr;
+ if (ELF_ST_TYPE(sym->st_info) != STT_FUNC) continue;
+ for (i = offset; i < num_traces; i++) {
+ uintptr_t d = (uintptr_t)traces[i] - saddr;
+ if (lines[i].line > 0 || d > (uintptr_t)sym->st_size)
+ continue;
+ /* fill symbol name and addr from .symtab */
+ if (!lines[i].sname) lines[i].sname = strtab + sym->st_name;
+ lines[i].saddr = saddr;
+ lines[i].path = obj->path;
+ lines[i].base_addr = obj->base_addr;
+ }
+ }
+ }
}
- if (!debug_line_shdr) {
+ if (!obj->debug_line.ptr) {
/* This file doesn't have .debug_line section,
let's check .gnu_debuglink section instead. */
if (gnu_debuglink_shdr && check_debuglink) {
@@ -629,19 +1855,244 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
num_traces, traces,
objp, lines, offset);
}
+ if (note_gnu_build_id && check_debuglink) {
+ ElfW(Nhdr) *nhdr = (ElfW(Nhdr)*) (file + note_gnu_build_id->sh_offset);
+ const char *build_id = (char *)(nhdr + 1) + nhdr->n_namesz;
+ follow_debuglink_build_id(build_id, nhdr->n_descsz,
+ num_traces, traces,
+ objp, lines, offset);
+ }
goto finish;
}
if (parse_debug_line(num_traces, traces,
- file + debug_line_shdr->sh_offset,
- debug_line_shdr->sh_size,
- obj, lines, offset))
- goto fail;
+ obj->debug_line.ptr,
+ obj->debug_line.size,
+ obj, lines, offset) == -1)
+ goto fail;
+
finish:
return dladdr_fbase;
fail:
return (uintptr_t)-1;
}
+#else /* Mach-O */
+/* read file and fill lines */
+static uintptr_t
+fill_lines(int num_traces, void **traces, int check_debuglink,
+ obj_info_t **objp, line_info_t *lines, int offset)
+{
+# ifdef __LP64__
+# define LP(x) x##_64
+# else
+# define LP(x) x
+# endif
+ int fd;
+ off_t filesize;
+ char *file, *p = NULL;
+ obj_info_t *obj = *objp;
+ struct LP(mach_header) *header;
+ uintptr_t dladdr_fbase = 0;
+
+ {
+ char *s = binary_filename;
+ char *base = strrchr(binary_filename, '/')+1;
+ size_t max = PATH_MAX;
+ size_t size = strlen(binary_filename);
+ size_t basesize = size - (base - binary_filename);
+ s += size;
+ max -= size;
+ p = s;
+ size = strlcpy(s, ".dSYM/Contents/Resources/DWARF/", max);
+ if (size == 0) goto fail;
+ s += size;
+ max -= size;
+ if (max <= basesize) goto fail;
+ memcpy(s, base, basesize);
+ s[basesize] = 0;
+
+ fd = open(binary_filename, O_RDONLY);
+ if (fd < 0) {
+ *p = 0; /* binary_filename becomes original file name */
+ fd = open(binary_filename, O_RDONLY);
+ if (fd < 0) {
+ goto fail;
+ }
+ }
+ }
+
+ filesize = lseek(fd, 0, SEEK_END);
+ if (filesize < 0) {
+ int e = errno;
+ close(fd);
+ kprintf("lseek: %s\n", strerror(e));
+ goto fail;
+ }
+#if SIZEOF_OFF_T > SIZEOF_SIZE_T
+ if (filesize > (off_t)SIZE_MAX) {
+ close(fd);
+ kprintf("Too large file %s\n", binary_filename);
+ goto fail;
+ }
+#endif
+ lseek(fd, 0, SEEK_SET);
+ /* async-signal unsafe */
+ file = (char *)mmap(NULL, (size_t)filesize, PROT_READ, MAP_SHARED, fd, 0);
+ if (file == MAP_FAILED) {
+ int e = errno;
+ close(fd);
+ kprintf("mmap: %s\n", strerror(e));
+ goto fail;
+ }
+ close(fd);
+
+ obj->mapped = file;
+ obj->mapped_size = (size_t)filesize;
+
+ header = (struct LP(mach_header) *)file;
+ if (header->magic == LP(MH_MAGIC)) {
+ /* non universal binary */
+ p = file;
+ }
+ else if (header->magic == FAT_CIGAM) {
+ struct LP(mach_header) *mhp = _NSGetMachExecuteHeader();
+ struct fat_header *fat = (struct fat_header *)file;
+ char *q = file + sizeof(*fat);
+ uint32_t nfat_arch = __builtin_bswap32(fat->nfat_arch);
+ /* fprintf(stderr,"%d: fat:%s %d\n",__LINE__, binary_filename,nfat_arch); */
+ for (uint32_t i = 0; i < nfat_arch; i++) {
+ struct fat_arch *arch = (struct fat_arch *)q;
+ cpu_type_t cputype = __builtin_bswap32(arch->cputype);
+ cpu_subtype_t cpusubtype = __builtin_bswap32(arch->cpusubtype);
+ uint32_t offset = __builtin_bswap32(arch->offset);
+ /* fprintf(stderr,"%d: fat %d %x/%x %x/%x\n",__LINE__, i, mhp->cputype,mhp->cpusubtype, cputype,cpusubtype); */
+ if (mhp->cputype == cputype &&
+ (cpu_subtype_t)(mhp->cpusubtype & ~CPU_SUBTYPE_MASK) == cpusubtype) {
+ p = file + offset;
+ file = p;
+ header = (struct LP(mach_header) *)p;
+ if (header->magic == LP(MH_MAGIC)) {
+ goto found_mach_header;
+ }
+ break;
+ }
+ q += sizeof(*arch);
+ }
+ kprintf("'%s' is not a Mach-O universal binary file!\n",binary_filename);
+ close(fd);
+ goto fail;
+ }
+ else {
+ kprintf("'%s' is not a "
+# ifdef __LP64__
+ "64"
+# else
+ "32"
+# endif
+ "-bit Mach-O file!\n",binary_filename);
+ close(fd);
+ goto fail;
+ }
+found_mach_header:
+ p += sizeof(*header);
+
+ for (uint32_t i = 0; i < (uint32_t)header->ncmds; i++) {
+ struct load_command *lcmd = (struct load_command *)p;
+ switch (lcmd->cmd) {
+ case LP(LC_SEGMENT):
+ {
+ static const char *debug_section_names[] = {
+ "__debug_abbrev",
+ "__debug_info",
+ "__debug_line",
+ "__debug_ranges",
+ "__debug_str"
+ };
+ struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;
+ if (strcmp(scmd->segname, "__TEXT") == 0) {
+ obj->vmaddr = scmd->vmaddr;
+ }
+ else if (strcmp(scmd->segname, "__DWARF") == 0) {
+ p += sizeof(struct LP(segment_command));
+ for (uint64_t i = 0; i < scmd->nsects; i++) {
+ struct LP(section) *sect = (struct LP(section) *)p;
+ p += sizeof(struct LP(section));
+ for (int j=0; j < DWARF_SECTION_COUNT; j++) {
+ struct dwarf_section *s = obj_dwarf_section_at(obj, j);
+
+ if (strcmp(sect->sectname, debug_section_names[j]) != 0)
+ continue;
+
+ s->ptr = file + sect->offset;
+ s->size = sect->size;
+ s->flags = sect->flags;
+ if (s->flags & SHF_COMPRESSED) {
+ goto fail;
+ }
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case LC_SYMTAB:
+ {
+ struct symtab_command *cmd = (struct symtab_command *)lcmd;
+ struct LP(nlist) *nl = (struct LP(nlist) *)(file + cmd->symoff);
+ char *strtab = file + cmd->stroff, *sname = 0;
+ uint32_t j;
+ uintptr_t saddr = 0;
+ /* kprintf("[%2d]: %x/symtab %p\n", i, cmd->cmd, p); */
+ for (j = 0; j < cmd->nsyms; j++) {
+ uintptr_t symsize, d;
+ struct LP(nlist) *e = &nl[j];
+ /* kprintf("[%2d][%4d]: %02x/%x/%x: %s %llx\n", i, j, e->n_type,e->n_sect,e->n_desc,strtab+e->n_un.n_strx,e->n_value); */
+ if (e->n_type != N_FUN) continue;
+ if (e->n_sect) {
+ saddr = (uintptr_t)e->n_value + obj->base_addr - obj->vmaddr;
+ sname = strtab + e->n_un.n_strx;
+ /* kprintf("[%2d][%4d]: %02x/%x/%x: %s %llx\n", i, j, e->n_type,e->n_sect,e->n_desc,strtab+e->n_un.n_strx,e->n_value); */
+ continue;
+ }
+ for (int k = offset; k < num_traces; k++) {
+ d = (uintptr_t)traces[k] - saddr;
+ symsize = e->n_value;
+ /* kprintf("%lx %lx %lx\n",saddr,symsize,traces[k]); */
+ if (lines[k].line > 0 || d > (uintptr_t)symsize)
+ continue;
+ /* fill symbol name and addr from .symtab */
+ if (!lines[k].sname) lines[k].sname = sname;
+ lines[k].saddr = saddr;
+ lines[k].path = obj->path;
+ lines[k].base_addr = obj->base_addr;
+ }
+ }
+ }
+ }
+ p += lcmd->cmdsize;
+ }
+
+ if (obj->debug_info.ptr && obj->debug_abbrev.ptr) {
+ DebugInfoReader reader;
+ debug_info_reader_init(&reader, obj);
+ while (reader.p < reader.pend) {
+ if (di_read_cu(&reader)) goto fail;
+ debug_info_read(&reader, num_traces, traces, lines, offset);
+ }
+ }
+
+ if (parse_debug_line(num_traces, traces,
+ obj->debug_line.ptr,
+ obj->debug_line.size,
+ obj, lines, offset) == -1)
+ goto fail;
+
+ return dladdr_fbase;
+fail:
+ return (uintptr_t)-1;
+}
+#endif
#define HAVE_MAIN_EXE_PATH
#if defined(__FreeBSD__)
@@ -653,17 +2104,22 @@ fail:
* and returns strlen(binary_filename).
* it is NUL terminated.
*/
-#if defined(__linux__)
-ssize_t
+#if defined(__linux__) || defined(__NetBSD__)
+static ssize_t
main_exe_path(void)
{
-# define PROC_SELF_EXE "/proc/self/exe"
+# if defined(__linux__)
+# define PROC_SELF_EXE "/proc/self/exe"
+# elif defined(__NetBSD__)
+# define PROC_SELF_EXE "/proc/curproc/exe"
+# endif
ssize_t len = readlink(PROC_SELF_EXE, binary_filename, PATH_MAX);
+ if (len < 0) return 0;
binary_filename[len] = 0;
return len;
}
#elif defined(__FreeBSD__)
-ssize_t
+static ssize_t
main_exe_path(void)
{
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
@@ -676,10 +2132,66 @@ main_exe_path(void)
len--; /* sysctl sets strlen+1 */
return len;
}
+#elif defined(HAVE_LIBPROC_H)
+static ssize_t
+main_exe_path(void)
+{
+ int len = proc_pidpath(getpid(), binary_filename, PATH_MAX);
+ if (len == 0) return 0;
+ binary_filename[len] = 0;
+ return len;
+}
#else
#undef HAVE_MAIN_EXE_PATH
#endif
+static void
+print_line0(line_info_t *line, void *address)
+{
+ uintptr_t addr = (uintptr_t)address;
+ uintptr_t d = addr - line->saddr;
+ if (!address) {
+ /* inlined */
+ if (line->dirname && line->dirname[0]) {
+ kprintf("%s(%s) %s/%s:%d\n", line->path, line->sname, line->dirname, line->filename, line->line);
+ }
+ else {
+ kprintf("%s(%s) %s:%d\n", line->path, line->sname, line->filename, line->line);
+ }
+ }
+ else if (!line->path) {
+ kprintf("[0x%"PRIxPTR"]\n", addr);
+ }
+ else if (!line->saddr || !line->sname) {
+ kprintf("%s(0x%"PRIxPTR") [0x%"PRIxPTR"]\n", line->path, addr-line->base_addr, addr);
+ }
+ else if (line->line <= 0) {
+ kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"]\n", line->path, line->sname,
+ d, addr);
+ }
+ else if (!line->filename) {
+ kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"] ???:%d\n", line->path, line->sname,
+ d, addr, line->line);
+ }
+ else if (line->dirname && line->dirname[0]) {
+ kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"] %s/%s:%d\n", line->path, line->sname,
+ d, addr, line->dirname, line->filename, line->line);
+ }
+ else {
+ kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"] %s:%d\n", line->path, line->sname,
+ d, addr, line->filename, line->line);
+ }
+}
+
+static void
+print_line(line_info_t *line, void *address)
+{
+ print_line0(line, address);
+ if (line->next) {
+ print_line(line->next, NULL);
+ }
+}
+
void
rb_dump_backtrace_with_lines(int num_traces, void **traces)
{
@@ -731,6 +2243,8 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces)
path = info.dli_fname;
obj->path = path;
lines[i].path = path;
+ lines[i].sname = info.dli_sname;
+ lines[i].saddr = (uintptr_t)info.dli_saddr;
strlcpy(binary_filename, path, PATH_MAX);
if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
break;
@@ -741,46 +2255,36 @@ next_line:
/* output */
for (i = 0; i < num_traces; i++) {
- line_info_t *line = &lines[i];
- uintptr_t addr = (uintptr_t)traces[i];
- uintptr_t d = addr - line->saddr;
- if (!line->path) {
- kprintf("[0x%lx]\n", addr);
- }
- else if (!line->saddr || !line->sname) {
- kprintf("%s [0x%lx]\n", line->path, addr);
- }
- else if (line->line <= 0) {
- kprintf("%s(%s+0x%lx) [0x%lx]\n", line->path, line->sname,
- d, addr);
- }
- else if (!line->filename) {
- kprintf("%s(%s+0x%lx) [0x%lx] ???:%d\n", line->path, line->sname,
- d, addr, line->line);
- }
- else if (line->dirname && line->dirname[0]) {
- kprintf("%s(%s+0x%lx) [0x%lx] %s/%s:%d\n", line->path, line->sname,
- d, addr, line->dirname, line->filename, line->line);
- }
- else {
- kprintf("%s(%s+0x%lx) [0x%lx] %s:%d\n", line->path, line->sname,
- d, addr, line->filename, line->line);
- }
+ print_line(&lines[i], traces[i]);
+
/* FreeBSD's backtrace may show _start and so on */
- if (line->sname && strcmp("main", line->sname) == 0)
+ if (lines[i].sname && strcmp("main", lines[i].sname) == 0)
break;
}
/* free */
while (obj) {
obj_info_t *o = obj;
- obj = o->next;
- if (o->fd) {
- munmap(o->mapped, o->mapped_size);
- close(o->fd);
+ for (i=0; i < DWARF_SECTION_COUNT; i++) {
+ struct dwarf_section *s = obj_dwarf_section_at(obj, i);
+ if (s->flags & SHF_COMPRESSED) {
+ free(s->ptr);
+ }
+ }
+ if (obj->mapped_size) {
+ munmap(obj->mapped, obj->mapped_size);
}
+ obj = o->next;
free(o);
}
+ for (i = 0; i < num_traces; i++) {
+ line_info_t *line = lines[i].next;
+ while (line) {
+ line_info_t *l = line;
+ line = line->next;
+ free(l);
+ }
+ }
free(lines);
free(dladdr_fbases);
}
@@ -826,7 +2330,7 @@ next_line:
#define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
static inline int toupper(int c) { return ('A' <= c && c <= 'Z') ? (c&0x5f) : c; }
#define hex2ascii(hex) (hex2ascii_data[hex])
-char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+static const char hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static inline int imax(int a, int b) { return (a > b ? a : b); }
static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
@@ -840,7 +2344,7 @@ static void putce(int c)
(void)ret;
}
-int
+static int
kprintf(const char *fmt, ...)
{
va_list ap;
diff --git a/addr2line.h b/addr2line.h
index d99f010934..f09b665800 100644
--- a/addr2line.h
+++ b/addr2line.h
@@ -1,3 +1,5 @@
+#ifndef RUBY_ADDR2LINE_H
+#define RUBY_ADDR2LINE_H
/**********************************************************************
addr2line.h -
@@ -8,10 +10,7 @@
**********************************************************************/
-#ifndef RUBY_ADDR2LINE_H
-#define RUBY_ADDR2LINE_H
-
-#ifdef USE_ELF
+#if (defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H))
void
rb_dump_backtrace_with_lines(int num_traces, void **traces);
diff --git a/appveyor.yml b/appveyor.yml
index 22c7bdce6a..78e3102008 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,55 +1,104 @@
---
-shallow_clone: true
+version: '{build}'
+init:
+ - git config --global user.name git
+ - git config --global user.email svn-admin@ruby-lang.org
+clone_depth: 10
platform:
- x64
environment:
ruby_version: "24-%Platform%"
- zlib_version: "1.2.11"
matrix:
- - vs: "120"
-install:
- - chcp
- - SET BITS=%Platform:x86=32%
- - SET BITS=%BITS:x=%
- - SET OPENSSL_DIR=c:\OpenSSL-Win%BITS%
- - CALL SET vcvars=%%^VS%VS%COMNTOOLS^%%..\..\VC\vcvarsall.bat
- - SET vcvars
- - '"%vcvars%" %Platform:x64=amd64%'
- - SET ruby_path=C:\Ruby%ruby_version:-x86=%
- - SET PATH=\usr\local\bin;%ruby_path%\bin;%PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin
- - ruby --version
- - 'cl'
- - SET
- - echo> Makefile srcdir=.
- - echo>> Makefile MSC_VER=0
- - echo>> Makefile RT=none
- - echo>> Makefile RT_VER=0
- - echo>> Makefile BUILTIN_ENCOBJS=nul
- - type win32\Makefile.sub >> Makefile
- - nmake %mflags% touch-unicode-files
- - nmake %mflags% up incs UNICODE_FILES=.
- - del Makefile
- - mkdir \usr\local\bin
- - mkdir \usr\local\include
- - mkdir \usr\local\lib
- - appveyor DownloadFile https://zlib.net/zlib%zlib_version:.=%.zip
- - 7z x -o%APPVEYOR_BUILD_FOLDER%\ext\zlib zlib%zlib_version:.=%.zip
- - for %%I in (%OPENSSL_DIR%\*.dll) do mklink /h \usr\local\bin\%%~nxI %%I
- - mkdir %Platform%-mswin_%vs%
- - ps: Get-ChildItem "win32" -Recurse | foreach {$_.Attributes = 'Readonly'}
- - ps: Get-Item $env:Platform"-mswin_"$env:vs | foreach {$_.Attributes = 'Normal'}
-build_script:
- - cd %APPVEYOR_BUILD_FOLDER%
- - cd %Platform%-mswin_%vs%
- - ..\win32\configure.bat --without-ext=+,dbm,gdbm,readline --with-opt-dir=/usr/local --with-openssl-dir=%OPENSSL_DIR:\=/%
- - nmake -l
- - nmake install-nodoc
- - \usr\bin\ruby -v -e "p :locale => Encoding.find('locale'), :filesystem => Encoding.find('filesystem')"
-test_script:
- - set /a JOBS=%NUMBER_OF_PROCESSORS%
- - nmake -l "TESTOPTS=-v -q" btest
- - nmake -l "TESTOPTS=-v -q" test-basic
- - nmake -l "TESTOPTS=-q -j%JOBS%" test-all
- - nmake -l test-spec
-matrix:
- fast_finish: true
+ - build: vs
+ vs: 120
+ ssl: OpenSSL
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ GEMS_FOR_TEST: ""
+ - build: vs
+ vs: 140
+ ssl: OpenSSL-v111
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ GEMS_FOR_TEST: ""
+ RELINE_TEST_ENCODING: "Windows-31J"
+ UPDATE_UNICODE: "UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=."
+cache:
+ - c:\Tools\vcpkg\installed\
+for:
+-
+ matrix:
+ only:
+ - build: vs
+ install:
+ - ver
+ - chcp
+ - SET BITS=%Platform:x86=32%
+ - SET BITS=%BITS:x=%
+ - SET OPENSSL_DIR=C:\%ssl%-Win%BITS%
+ - cd C:\Tools\vcpkg
+ - git pull -q
+ - .\bootstrap-vcpkg.bat
+ - cd %APPVEYOR_BUILD_FOLDER%
+ - vcpkg --triplet %Platform%-windows install libffi libyaml zlib
+ - set PATH=c:\Tools\vcpkg\installed\%Platform%-windows\bin;%PATH%
+ - CALL SET vcvars=%%^VS%VS%COMNTOOLS^%%..\..\VC\vcvarsall.bat
+ - SET vcvars
+ - '"%vcvars%" %Platform:x64=amd64%'
+ - SET ruby_path=C:\Ruby%ruby_version:-x86=%
+ - SET PATH=\usr\local\bin;%ruby_path%\bin;%PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin
+ - ruby --version
+ - 'cl'
+ - echo> Makefile srcdir=.
+ - echo>> Makefile MSC_VER=0
+ - echo>> Makefile RT=none
+ - echo>> Makefile RT_VER=0
+ - echo>> Makefile BUILTIN_ENCOBJS=nul
+ - type win32\Makefile.sub >> Makefile
+ - nmake %mflags% touch-unicode-files
+ - nmake %mflags% %UPDATE_UNICODE% incs
+ - nmake %mflags% extract-extlibs
+ - del Makefile
+ - mkdir \usr\local\bin
+ - mkdir \usr\local\include
+ - mkdir \usr\local\lib
+ - for %%I in (%OPENSSL_DIR%\*.dll) do mklink /h \usr\local\bin\%%~nxI %%I
+ - attrib +r /s /d
+ - mkdir %Platform%-mswin_%vs%
+ build_script:
+ - cd %APPVEYOR_BUILD_FOLDER%
+ - cd %Platform%-mswin_%vs%
+ - >-
+ ..\win32\configure.bat
+ --without-ext=+,dbm,gdbm,readline
+ --with-opt-dir="/usr/local;c:/Tools/vcpkg/installed/%Platform%-windows"
+ --with-openssl-dir=%OPENSSL_DIR:\=/%
+ - nmake -l
+ - nmake install-nodoc
+ - \usr\bin\ruby -v -e "p :locale => Encoding.find('locale'), :filesystem => Encoding.find('filesystem')"
+ - if not "%GEMS_FOR_TEST%" == "" \usr\bin\gem install --no-document %GEMS_FOR_TEST%
+ - \usr\bin\ruby -ropenssl -e "puts 'Build ' + OpenSSL::OPENSSL_VERSION, 'Runtime ' + OpenSSL::OPENSSL_LIBRARY_VERSION"
+ test_script:
+ - set /a JOBS=%NUMBER_OF_PROCESSORS%
+ - nmake -l "TESTOPTS=-v -q" btest
+ - nmake -l "TESTOPTS=-v -q" test-basic
+ - nmake -l "TESTOPTS=-v --timeout-scale=3.0 --excludes=../test/excludes/_appveyor -j%JOBS% --exclude readline --exclude win32ole --exclude test_bignum --exclude test_syntax --exclude test_open-uri --exclude test_bundled_ca" test-all
+ # separately execute tests without -j which may crash worker with -j.
+ - nmake -l "TESTOPTS=-v --timeout-scale=3.0 --excludes=../test/excludes/_appveyor" test-all TESTS="../test/win32ole ../test/ruby/test_bignum.rb ../test/ruby/test_syntax.rb ../test/open-uri/test_open-uri.rb ../test/rubygems/test_bundled_ca.rb"
+ - nmake -l test-spec MSPECOPT=-fs # not using `-j` because sometimes `mspec -j` silently dies on Windows
+notifications:
+ - provider: Webhook
+ method: POST
+ url:
+ secure: CcFlJNDJ/a6to7u3Z4Fnz6dScEPNx7hTha2GkSRlV+1U6dqmxY/7uBcLXYb9gR3jfQk6w+2o/HrjNAyXMNGU/JOka3s2WRI4VKitzM+lQ08owvJIh0R7LxrGH0J2e81U # ruby-lang slack: ruby/simpler-alerts-bot
+ body: >-
+ {{^isPullRequest}}
+ {
+ "ci": "AppVeyor CI",
+ "env": "Visual Studio 2013 / 2015",
+ "url": "{{buildUrl}}",
+ "commit": "{{commitId}}",
+ "branch": "{{branch}}"
+ }
+ {{/isPullRequest}}
+ on_build_success: false
+ on_build_failure: true
+ on_build_status_changed: false
diff --git a/array.c b/array.c
index c5d7274272..b48a6431e7 100644
--- a/array.c
+++ b/array.c
@@ -11,14 +11,28 @@
**********************************************************************/
+#include "debug_counter.h"
+#include "id.h"
#include "internal.h"
-#include "ruby/util.h"
-#include "ruby/st.h"
+#include "internal/array.h"
+#include "internal/compar.h"
+#include "internal/enum.h"
+#include "internal/gc.h"
+#include "internal/hash.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/proc.h"
+#include "internal/rational.h"
+#include "internal/vm.h"
#include "probes.h"
-#include "id.h"
-#include "debug_counter.h"
+#include "ruby/encoding.h"
+#include "ruby/st.h"
+#include "ruby/util.h"
+#include "transient_heap.h"
+#include "builtin.h"
-#ifndef ARRAY_DEBUG
+#if !ARRAY_DEBUG
+# undef NDEBUG
# define NDEBUG
#endif
#include "ruby_assert.h"
@@ -32,27 +46,52 @@ VALUE rb_cArray;
#define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
#define SMALL_ARRAY_LEN 16
-# define ARY_SHARED_P(ary) \
- (assert(!FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG)), \
- FL_TEST((ary),ELTS_SHARED)!=0)
-# define ARY_EMBED_P(ary) \
- (assert(!FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG)), \
- FL_TEST((ary), RARRAY_EMBED_FLAG)!=0)
+RBIMPL_ATTR_MAYBE_UNUSED()
+static int
+should_be_T_ARRAY(VALUE ary)
+{
+ return RB_TYPE_P(ary, T_ARRAY);
+}
+
+RBIMPL_ATTR_MAYBE_UNUSED()
+static int
+should_not_be_shared_and_embedded(VALUE ary)
+{
+ return !FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG);
+}
+
+#define ARY_SHARED_P(ary) \
+ (assert(should_be_T_ARRAY((VALUE)(ary))), \
+ assert(should_not_be_shared_and_embedded((VALUE)ary)), \
+ FL_TEST_RAW((ary),ELTS_SHARED)!=0)
+
+#define ARY_EMBED_P(ary) \
+ (assert(should_be_T_ARRAY((VALUE)(ary))), \
+ assert(should_not_be_shared_and_embedded((VALUE)ary)), \
+ FL_TEST_RAW((ary), RARRAY_EMBED_FLAG) != 0)
#define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
#define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
+#define ARY_HEAP_CAPA(a) (assert(!ARY_EMBED_P(a)), assert(!ARY_SHARED_ROOT_P(a)), \
+ RARRAY(a)->as.heap.aux.capa)
+
#define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
#define ARY_EMBED_LEN(a) \
(assert(ARY_EMBED_P(a)), \
(long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
(RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
-#define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), RARRAY(a)->as.heap.aux.capa * sizeof(VALUE))
+#define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
+
+#define ARY_OWNS_HEAP_P(a) (assert(should_be_T_ARRAY((VALUE)(a))), \
+ !FL_TEST_RAW((a), ELTS_SHARED|RARRAY_EMBED_FLAG))
-#define ARY_OWNS_HEAP_P(a) (!FL_TEST((a), ELTS_SHARED|RARRAY_EMBED_FLAG))
#define FL_SET_EMBED(a) do { \
assert(!ARY_SHARED_P(a)); \
FL_SET((a), RARRAY_EMBED_FLAG); \
+ RARY_TRANSIENT_UNSET(a); \
+ ary_verify(a); \
} while (0)
+
#define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
#define FL_SET_SHARED(ary) do { \
assert(!ARY_EMBED_P(ary)); \
@@ -101,7 +140,7 @@ VALUE rb_cArray;
} while (0)
#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : \
- ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : RARRAY(ary)->as.heap.aux.capa)
+ ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
#define ARY_SET_CAPA(ary, n) do { \
assert(!ARY_EMBED_P(ary)); \
assert(!ARY_SHARED_P(ary)); \
@@ -109,33 +148,116 @@ VALUE rb_cArray;
RARRAY(ary)->as.heap.aux.capa = (n); \
} while (0)
-#define ARY_SHARED(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared)
+#define ARY_SHARED_ROOT(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared_root)
#define ARY_SET_SHARED(ary, value) do { \
const VALUE _ary_ = (ary); \
const VALUE _value_ = (value); \
assert(!ARY_EMBED_P(_ary_)); \
assert(ARY_SHARED_P(_ary_)); \
assert(ARY_SHARED_ROOT_P(_value_)); \
- RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared, _value_); \
+ RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \
} while (0)
#define RARRAY_SHARED_ROOT_FLAG FL_USER5
-#define ARY_SHARED_ROOT_P(ary) (FL_TEST((ary), RARRAY_SHARED_ROOT_FLAG))
-#define ARY_SHARED_NUM(ary) \
+#define ARY_SHARED_ROOT_P(ary) (assert(should_be_T_ARRAY((VALUE)(ary))), \
+ FL_TEST_RAW((ary), RARRAY_SHARED_ROOT_FLAG))
+#define ARY_SHARED_ROOT_REFCNT(ary) \
(assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa)
-#define ARY_SHARED_OCCUPIED(ary) (ARY_SHARED_NUM(ary) == 1)
-#define ARY_SET_SHARED_NUM(ary, value) do { \
+#define ARY_SHARED_ROOT_OCCUPIED(ary) (ARY_SHARED_ROOT_REFCNT(ary) == 1)
+#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
assert(ARY_SHARED_ROOT_P(ary)); \
RARRAY(ary)->as.heap.aux.capa = (value); \
} while (0)
#define FL_SET_SHARED_ROOT(ary) do { \
assert(!ARY_EMBED_P(ary)); \
+ assert(!RARRAY_TRANSIENT_P(ary)); \
FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
} while (0)
-#define ARY_SET(a, i, v) RARRAY_ASET((assert(!ARY_SHARED_P(a)), (a)), (i), (v))
+static inline void
+ARY_SET(VALUE a, long i, VALUE v)
+{
+ assert(!ARY_SHARED_P(a));
+ assert(!OBJ_FROZEN(a));
+
+ RARRAY_ASET(a, i, v);
+}
+#undef RARRAY_ASET
+
+
+#if ARRAY_DEBUG
+#define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
+
+static VALUE
+ary_verify_(VALUE ary, const char *file, int line)
+{
+ assert(RB_TYPE_P(ary, T_ARRAY));
+
+ if (FL_TEST(ary, ELTS_SHARED)) {
+ VALUE root = RARRAY(ary)->as.heap.aux.shared_root;
+ const VALUE *ptr = ARY_HEAP_PTR(ary);
+ const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root);
+ long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(root);
+ assert(FL_TEST(root, RARRAY_SHARED_ROOT_FLAG));
+ assert(root_ptr <= ptr && ptr + len <= root_ptr + root_len);
+ ary_verify(root);
+ }
+ else if (ARY_EMBED_P(ary)) {
+ assert(!RARRAY_TRANSIENT_P(ary));
+ assert(!ARY_SHARED_P(ary));
+ assert(RARRAY_LEN(ary) <= RARRAY_EMBED_LEN_MAX);
+ }
+ else {
+#if 1
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
+ long i, len = RARRAY_LEN(ary);
+ volatile VALUE v;
+ if (len > 1) len = 1; /* check only HEAD */
+ for (i=0; i<len; i++) {
+ v = ptr[i]; /* access check */
+ }
+ v = v;
+#endif
+ }
+
+#if USE_TRANSIENT_HEAP
+ if (RARRAY_TRANSIENT_P(ary)) {
+ assert(rb_transient_heap_managed_ptr_p(RARRAY_CONST_PTR_TRANSIENT(ary)));
+ }
+#endif
+
+ rb_transient_heap_verify();
+
+ return ary;
+}
+
+void
+rb_ary_verify(VALUE ary)
+{
+ ary_verify(ary);
+}
+#else
+#define ary_verify(ary) ((void)0)
+#endif
+
+VALUE *
+rb_ary_ptr_use_start(VALUE ary)
+{
+#if ARRAY_DEBUG
+ FL_SET_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
+#endif
+ return (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary);
+}
void
-rb_mem_clear(register VALUE *mem, register long size)
+rb_ary_ptr_use_end(VALUE ary)
+{
+#if ARRAY_DEBUG
+ FL_UNSET_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
+#endif
+}
+
+void
+rb_mem_clear(VALUE *mem, long size)
{
while (size--) {
*mem++ = Qnil;
@@ -145,7 +267,7 @@ rb_mem_clear(register VALUE *mem, register long size)
static void
ary_mem_clear(VALUE ary, long beg, long size)
{
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
rb_mem_clear(ptr + beg, size);
});
}
@@ -161,7 +283,7 @@ memfill(register VALUE *mem, register long size, register VALUE val)
static void
ary_memfill(VALUE ary, long beg, long size, VALUE val)
{
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
memfill(ptr + beg, size, val);
RB_OBJ_WRITTEN(ary, Qundef, val);
});
@@ -170,28 +292,22 @@ ary_memfill(VALUE ary, long beg, long size, VALUE val)
static void
ary_memcpy0(VALUE ary, long beg, long argc, const VALUE *argv, VALUE buff_owner_ary)
{
-#if 1
assert(!ARY_SHARED_P(buff_owner_ary));
if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) {
- rb_gc_writebarrier_remember(buff_owner_ary);
- RARRAY_PTR_USE(ary, ptr, {
- MEMCPY(ptr+beg, argv, VALUE, argc);
- });
+ rb_gc_writebarrier_remember(buff_owner_ary);
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+ MEMCPY(ptr+beg, argv, VALUE, argc);
+ });
}
else {
- int i;
- RARRAY_PTR_USE(ary, ptr, {
- for (i=0; i<argc; i++) {
- RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
- }
- });
+ int i;
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+ for (i=0; i<argc; i++) {
+ RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
+ }
+ });
}
-#else
- /* giveup write barrier (traditional way) */
- RARRAY_PTR(buff_owner_ary);
- MEMCPY(RARRAY_PTR(ary)+beg, argv, VALUE, argc);
-#endif
}
static void
@@ -200,49 +316,175 @@ ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv)
ary_memcpy0(ary, beg, argc, argv, ary);
}
+static VALUE *
+ary_heap_alloc(VALUE ary, size_t capa)
+{
+ VALUE *ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * capa);
+
+ if (ptr != NULL) {
+ RARY_TRANSIENT_SET(ary);
+ }
+ else {
+ RARY_TRANSIENT_UNSET(ary);
+ ptr = ALLOC_N(VALUE, capa);
+ }
+
+ return ptr;
+}
+
+static void
+ary_heap_free_ptr(VALUE ary, const VALUE *ptr, long size)
+{
+ if (RARRAY_TRANSIENT_P(ary)) {
+ /* ignore it */
+ }
+ else {
+ ruby_sized_xfree((void *)ptr, size);
+ }
+}
+
+static void
+ary_heap_free(VALUE ary)
+{
+ if (RARRAY_TRANSIENT_P(ary)) {
+ RARY_TRANSIENT_UNSET(ary);
+ }
+ else {
+ ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
+ }
+}
+
+static void
+ary_heap_realloc(VALUE ary, size_t new_capa)
+{
+ size_t old_capa = ARY_HEAP_CAPA(ary);
+
+ if (RARRAY_TRANSIENT_P(ary)) {
+ if (new_capa <= old_capa) {
+ /* do nothing */
+ }
+ else {
+ VALUE *new_ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * new_capa);
+
+ if (new_ptr == NULL) {
+ new_ptr = ALLOC_N(VALUE, new_capa);
+ RARY_TRANSIENT_UNSET(ary);
+ }
+
+ MEMCPY(new_ptr, ARY_HEAP_PTR(ary), VALUE, old_capa);
+ ARY_SET_PTR(ary, new_ptr);
+ }
+ }
+ else {
+ SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, old_capa);
+ }
+ ary_verify(ary);
+}
+
+#if USE_TRANSIENT_HEAP
+static inline void
+rb_ary_transient_heap_evacuate_(VALUE ary, int transient, int promote)
+{
+ if (transient) {
+ VALUE *new_ptr;
+ const VALUE *old_ptr = ARY_HEAP_PTR(ary);
+ long capa = ARY_HEAP_CAPA(ary);
+ long len = ARY_HEAP_LEN(ary);
+
+ if (ARY_SHARED_ROOT_P(ary)) {
+ capa = len;
+ }
+
+ assert(ARY_OWNS_HEAP_P(ary));
+ assert(RARRAY_TRANSIENT_P(ary));
+ assert(!ARY_PTR_USING_P(ary));
+
+ if (promote) {
+ new_ptr = ALLOC_N(VALUE, capa);
+ RARY_TRANSIENT_UNSET(ary);
+ }
+ else {
+ new_ptr = ary_heap_alloc(ary, capa);
+ }
+
+ MEMCPY(new_ptr, old_ptr, VALUE, capa);
+ /* do not use ARY_SET_PTR() because they assert !frozen */
+ RARRAY(ary)->as.heap.ptr = new_ptr;
+ }
+
+ ary_verify(ary);
+}
+
+void
+rb_ary_transient_heap_evacuate(VALUE ary, int promote)
+{
+ rb_ary_transient_heap_evacuate_(ary, RARRAY_TRANSIENT_P(ary), promote);
+}
+
+void
+rb_ary_detransient(VALUE ary)
+{
+ assert(RARRAY_TRANSIENT_P(ary));
+ rb_ary_transient_heap_evacuate_(ary, TRUE, TRUE);
+}
+#else
+void
+rb_ary_detransient(VALUE ary)
+{
+ /* do nothing */
+}
+#endif
+
static void
ary_resize_capa(VALUE ary, long capacity)
{
assert(RARRAY_LEN(ary) <= capacity);
assert(!OBJ_FROZEN(ary));
assert(!ARY_SHARED_P(ary));
+
if (capacity > RARRAY_EMBED_LEN_MAX) {
if (ARY_EMBED_P(ary)) {
long len = ARY_EMBED_LEN(ary);
- VALUE *ptr = ALLOC_N(VALUE, (capacity));
+ VALUE *ptr = ary_heap_alloc(ary, capacity);
+
MEMCPY(ptr, ARY_EMBED_PTR(ary), VALUE, len);
FL_UNSET_EMBED(ary);
ARY_SET_PTR(ary, ptr);
ARY_SET_HEAP_LEN(ary, len);
}
else {
- SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, capacity, RARRAY(ary)->as.heap.aux.capa);
+ ary_heap_realloc(ary, capacity);
}
- ARY_SET_CAPA(ary, (capacity));
+ ARY_SET_CAPA(ary, capacity);
}
else {
if (!ARY_EMBED_P(ary)) {
- long len = RARRAY_LEN(ary);
- const VALUE *ptr = RARRAY_CONST_PTR(ary);
+ long len = ARY_HEAP_LEN(ary);
+ long old_capa = ARY_HEAP_CAPA(ary);
+ const VALUE *ptr = ARY_HEAP_PTR(ary);
- if (len > capacity) len = capacity;
+ if (len > capacity) len = capacity;
MEMCPY((VALUE *)RARRAY(ary)->as.ary, ptr, VALUE, len);
+ ary_heap_free_ptr(ary, ptr, old_capa);
+
FL_SET_EMBED(ary);
ARY_SET_LEN(ary, len);
- ruby_xfree((VALUE *)ptr);
}
}
+
+ ary_verify(ary);
}
static inline void
ary_shrink_capa(VALUE ary)
{
long capacity = ARY_HEAP_LEN(ary);
- long old_capa = RARRAY(ary)->as.heap.aux.capa;
+ long old_capa = ARY_HEAP_CAPA(ary);
assert(!ARY_SHARED_P(ary));
assert(old_capa >= capacity);
- if (old_capa > capacity)
- REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, capacity);
+ if (old_capa > capacity) ary_heap_realloc(ary, capacity);
+
+ ary_verify(ary);
}
static void
@@ -258,19 +500,21 @@ ary_double_capa(VALUE ary, long min)
}
new_capa += min;
ary_resize_capa(ary, new_capa);
+
+ ary_verify(ary);
}
static void
-rb_ary_decrement_share(VALUE shared)
+rb_ary_decrement_share(VALUE shared_root)
{
- if (shared) {
- long num = ARY_SHARED_NUM(shared) - 1;
+ if (shared_root) {
+ long num = ARY_SHARED_ROOT_REFCNT(shared_root) - 1;
if (num == 0) {
- rb_ary_free(shared);
- rb_gc_force_recycle(shared);
+ rb_ary_free(shared_root);
+ rb_gc_force_recycle(shared_root);
}
else if (num > 0) {
- ARY_SET_SHARED_NUM(shared, num);
+ ARY_SET_SHARED_ROOT_REFCNT(shared_root, num);
}
}
}
@@ -278,8 +522,8 @@ rb_ary_decrement_share(VALUE shared)
static void
rb_ary_unshare(VALUE ary)
{
- VALUE shared = RARRAY(ary)->as.heap.aux.shared;
- rb_ary_decrement_share(shared);
+ VALUE shared_root = RARRAY(ary)->as.heap.aux.shared_root;
+ rb_ary_decrement_share(shared_root);
FL_UNSET_SHARED(ary);
}
@@ -292,65 +536,77 @@ rb_ary_unshare_safe(VALUE ary)
}
static VALUE
-rb_ary_increment_share(VALUE shared)
+rb_ary_increment_share(VALUE shared_root)
{
- long num = ARY_SHARED_NUM(shared);
+ long num = ARY_SHARED_ROOT_REFCNT(shared_root);
if (num >= 0) {
- ARY_SET_SHARED_NUM(shared, num + 1);
+ ARY_SET_SHARED_ROOT_REFCNT(shared_root, num + 1);
}
- return shared;
+ return shared_root;
}
static void
-rb_ary_set_shared(VALUE ary, VALUE shared)
+rb_ary_set_shared(VALUE ary, VALUE shared_root)
{
- rb_ary_increment_share(shared);
+ rb_ary_increment_share(shared_root);
FL_SET_SHARED(ary);
- ARY_SET_SHARED(ary, shared);
+ RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
+ ARY_SET_SHARED(ary, shared_root);
}
static inline void
rb_ary_modify_check(VALUE ary)
{
rb_check_frozen(ary);
+ ary_verify(ary);
}
void
-rb_ary_modify(VALUE ary)
+rb_ary_cancel_sharing(VALUE ary)
{
- rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
- long shared_len, len = RARRAY_LEN(ary);
- VALUE shared = ARY_SHARED(ary);
+ long shared_len, len = RARRAY_LEN(ary);
+ VALUE shared_root = ARY_SHARED_ROOT(ary);
+
+ ary_verify(shared_root);
+
if (len <= RARRAY_EMBED_LEN_MAX) {
- const VALUE *ptr = ARY_HEAP_PTR(ary);
+ const VALUE *ptr = ARY_HEAP_PTR(ary);
FL_UNSET_SHARED(ary);
FL_SET_EMBED(ary);
- MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len);
- rb_ary_decrement_share(shared);
+ MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len);
+ rb_ary_decrement_share(shared_root);
ARY_SET_EMBED_LEN(ary, len);
}
- else if (ARY_SHARED_OCCUPIED(shared) && len > ((shared_len = RARRAY_LEN(shared))>>1)) {
- long shift = RARRAY_CONST_PTR(ary) - RARRAY_CONST_PTR(shared);
- FL_UNSET_SHARED(ary);
- ARY_SET_PTR(ary, RARRAY_CONST_PTR(shared));
- ARY_SET_CAPA(ary, shared_len);
- RARRAY_PTR_USE(ary, ptr, {
- MEMMOVE(ptr, ptr+shift, VALUE, len);
- });
- FL_SET_EMBED(shared);
- rb_ary_decrement_share(shared);
- }
+ else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && len > ((shared_len = RARRAY_LEN(shared_root))>>1)) {
+ long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root);
+ FL_UNSET_SHARED(ary);
+ ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared_root));
+ ARY_SET_CAPA(ary, shared_len);
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+ MEMMOVE(ptr, ptr+shift, VALUE, len);
+ });
+ FL_SET_EMBED(shared_root);
+ rb_ary_decrement_share(shared_root);
+ }
else {
- VALUE *ptr = ALLOC_N(VALUE, len);
- MEMCPY(ptr, RARRAY_CONST_PTR(ary), VALUE, len);
+ VALUE *ptr = ary_heap_alloc(ary, len);
+ MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len);
rb_ary_unshare(ary);
ARY_SET_CAPA(ary, len);
ARY_SET_PTR(ary, ptr);
}
- rb_gc_writebarrier_remember(ary);
+ rb_gc_writebarrier_remember(ary);
}
+ ary_verify(ary);
+}
+
+void
+rb_ary_modify(VALUE ary)
+{
+ rb_ary_modify_check(ary);
+ rb_ary_cancel_sharing(ary);
}
static VALUE
@@ -365,11 +621,14 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
}
if (ARY_SHARED_P(ary)) {
if (new_len > RARRAY_EMBED_LEN_MAX) {
- VALUE shared = ARY_SHARED(ary);
- if (ARY_SHARED_OCCUPIED(shared)) {
- if (RARRAY_CONST_PTR(ary) - RARRAY_CONST_PTR(shared) + new_len <= RARRAY_LEN(shared)) {
+ VALUE shared_root = ARY_SHARED_ROOT(ary);
+ if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
+ if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root) + new_len <= RARRAY_LEN(shared_root)) {
rb_ary_modify_check(ary);
- return shared;
+
+ ary_verify(ary);
+ ary_verify(shared_root);
+ return shared_root;
}
else {
/* if array is shared, then it is likely it participate in push/shift pattern */
@@ -378,11 +637,13 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
if (new_len > capa - (capa >> 6)) {
ary_double_capa(ary, new_len);
}
+ ary_verify(ary);
return ary;
}
}
}
- rb_ary_modify(ary);
+ ary_verify(ary);
+ rb_ary_modify(ary);
}
else {
rb_ary_modify_check(ary);
@@ -392,17 +653,21 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
ary_double_capa(ary, new_len);
}
+ ary_verify(ary);
return ary;
}
/*
* call-seq:
- * ary.freeze -> ary
+ * array.freeze -> self
*
- * Calls Object#freeze on +ary+ to prevent any further
- * modification. A RuntimeError will be raised if a modification
- * attempt is made.
+ * Freezes +self+; returns +self+:
+ * a = []
+ * a.frozen? # => false
+ * a.freeze
+ * a.frozen? # => true
*
+ * An attempt to modify a frozen \Array raises FrozenError.
*/
VALUE
@@ -411,21 +676,6 @@ rb_ary_freeze(VALUE ary)
return rb_obj_freeze(ary);
}
-/*
- * call-seq:
- * ary.frozen? -> true or false
- *
- * Return +true+ if this array is frozen (or temporarily frozen
- * while being sorted). See also Object#frozen?
- */
-
-static VALUE
-rb_ary_frozen_p(VALUE ary)
-{
- if (OBJ_FROZEN(ary)) return Qtrue;
- return Qfalse;
-}
-
/* This can be used to take a snapshot of an array (with
e.g. rb_ary_replace) and check later whether the array has been
modified from the snapshot. The snapshot is cheap, though if
@@ -438,7 +688,7 @@ rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
{
if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
!ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
- RARRAY(ary1)->as.heap.aux.shared == RARRAY(ary2)->as.heap.aux.shared &&
+ RARRAY(ary1)->as.heap.aux.shared_root == RARRAY(ary2)->as.heap.aux.shared_root &&
RARRAY(ary1)->as.heap.len == RARRAY(ary2)->as.heap.len) {
return Qtrue;
}
@@ -479,7 +729,7 @@ ary_new(VALUE klass, long capa)
ary = ary_alloc(klass);
if (capa > RARRAY_EMBED_LEN_MAX) {
- ptr = ALLOC_N(VALUE, capa);
+ ptr = ary_heap_alloc(ary, capa);
FL_UNSET_EMBED(ary);
ARY_SET_PTR(ary, ptr);
ARY_SET_CAPA(ary, capa);
@@ -520,7 +770,7 @@ VALUE
return ary;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
{
VALUE ary;
@@ -540,10 +790,64 @@ rb_ary_new_from_values(long n, const VALUE *elts)
return rb_ary_tmp_new_from_values(rb_cArray, n, elts);
}
+static VALUE
+ec_ary_alloc(rb_execution_context_t *ec, VALUE klass)
+{
+ RB_EC_NEWOBJ_OF(ec, ary, struct RArray, klass, T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
+ /* Created array is:
+ * FL_SET_EMBED((VALUE)ary);
+ * ARY_SET_EMBED_LEN((VALUE)ary, 0);
+ */
+ return (VALUE)ary;
+}
+
+static VALUE
+ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa)
+{
+ VALUE ary,*ptr;
+
+ if (capa < 0) {
+ rb_raise(rb_eArgError, "negative array size (or size too big)");
+ }
+ if (capa > ARY_MAX_SIZE) {
+ rb_raise(rb_eArgError, "array size too big");
+ }
+
+ RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
+
+ ary = ec_ary_alloc(ec, klass);
+
+ if (capa > RARRAY_EMBED_LEN_MAX) {
+ ptr = ary_heap_alloc(ary, capa);
+ FL_UNSET_EMBED(ary);
+ ARY_SET_PTR(ary, ptr);
+ ARY_SET_CAPA(ary, capa);
+ ARY_SET_HEAP_LEN(ary, 0);
+ }
+
+ return ary;
+}
+
+VALUE
+rb_ec_ary_new_from_values(rb_execution_context_t *ec, long n, const VALUE *elts)
+{
+ VALUE ary;
+
+ ary = ec_ary_new(ec, rb_cArray, n);
+ if (n > 0 && elts) {
+ ary_memcpy(ary, 0, n, elts);
+ ARY_SET_LEN(ary, n);
+ }
+
+ return ary;
+}
+
VALUE
rb_ary_tmp_new(long capa)
{
- return ary_new(0, capa);
+ VALUE ary = ary_new(0, capa);
+ rb_ary_transient_heap_evacuate(ary, TRUE);
+ return ary;
}
VALUE
@@ -552,6 +856,7 @@ rb_ary_tmp_new_fill(long capa)
VALUE ary = ary_new(0, capa);
ary_memfill(ary, 0, capa, Qnil);
ARY_SET_LEN(ary, capa);
+ rb_ary_transient_heap_evacuate(ary, TRUE);
return ary;
}
@@ -559,11 +864,29 @@ void
rb_ary_free(VALUE ary)
{
if (ARY_OWNS_HEAP_P(ary)) {
- RB_DEBUG_COUNTER_INC(obj_ary_ptr);
- ruby_sized_xfree((void *)ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
+ if (USE_DEBUG_COUNTER &&
+ !ARY_SHARED_ROOT_P(ary) &&
+ ARY_HEAP_CAPA(ary) > RARRAY_LEN(ary)) {
+ RB_DEBUG_COUNTER_INC(obj_ary_extracapa);
+ }
+
+ if (RARRAY_TRANSIENT_P(ary)) {
+ RB_DEBUG_COUNTER_INC(obj_ary_transient);
+ }
+ else {
+ RB_DEBUG_COUNTER_INC(obj_ary_ptr);
+ ary_heap_free(ary);
+ }
}
else {
- RB_DEBUG_COUNTER_INC(obj_ary_embed);
+ RB_DEBUG_COUNTER_INC(obj_ary_embed);
+ }
+
+ if (ARY_SHARED_P(ary)) {
+ RB_DEBUG_COUNTER_INC(obj_ary_shared);
+ }
+ if (ARY_SHARED_ROOT_P(ary) && ARY_SHARED_ROOT_OCCUPIED(ary)) {
+ RB_DEBUG_COUNTER_INC(obj_ary_shared_root_occupied);
}
}
@@ -583,39 +906,52 @@ ary_discard(VALUE ary)
{
rb_ary_free(ary);
RBASIC(ary)->flags |= RARRAY_EMBED_FLAG;
- RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK;
+ RBASIC(ary)->flags &= ~(RARRAY_EMBED_LEN_MASK | RARRAY_TRANSIENT_FLAG);
}
static VALUE
ary_make_shared(VALUE ary)
{
assert(!ARY_EMBED_P(ary));
+ ary_verify(ary);
+
if (ARY_SHARED_P(ary)) {
- return ARY_SHARED(ary);
+ return ARY_SHARED_ROOT(ary);
}
else if (ARY_SHARED_ROOT_P(ary)) {
return ary;
}
else if (OBJ_FROZEN(ary)) {
+ rb_ary_transient_heap_evacuate(ary, TRUE);
ary_shrink_capa(ary);
FL_SET_SHARED_ROOT(ary);
- ARY_SET_SHARED_NUM(ary, 1);
+ ARY_SET_SHARED_ROOT_REFCNT(ary, 1);
return ary;
}
else {
long capa = ARY_CAPA(ary), len = RARRAY_LEN(ary);
+ const VALUE *ptr;
NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
- FL_UNSET_EMBED(shared);
+ VALUE vshared = (VALUE)shared;
- ARY_SET_LEN((VALUE)shared, capa);
- ARY_SET_PTR((VALUE)shared, RARRAY_CONST_PTR(ary));
- ary_mem_clear((VALUE)shared, len, capa - len);
- FL_SET_SHARED_ROOT(shared);
- ARY_SET_SHARED_NUM((VALUE)shared, 1);
+ rb_ary_transient_heap_evacuate(ary, TRUE);
+ ptr = ARY_HEAP_PTR(ary);
+
+ FL_UNSET_EMBED(vshared);
+ ARY_SET_LEN(vshared, capa);
+ ARY_SET_PTR(vshared, ptr);
+ ary_mem_clear(vshared, len, capa - len);
+ FL_SET_SHARED_ROOT(vshared);
+ ARY_SET_SHARED_ROOT_REFCNT(vshared, 1);
FL_SET_SHARED(ary);
- ARY_SET_SHARED(ary, (VALUE)shared);
- OBJ_FREEZE(shared);
- return (VALUE)shared;
+ RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
+ ARY_SET_SHARED(ary, vshared);
+ OBJ_FREEZE(vshared);
+
+ ary_verify(vshared);
+ ary_verify(ary);
+
+ return vshared;
}
}
@@ -626,7 +962,7 @@ ary_make_substitution(VALUE ary)
if (len <= RARRAY_EMBED_LEN_MAX) {
VALUE subst = rb_ary_new2(len);
- ary_memcpy(subst, 0, len, RARRAY_CONST_PTR(ary));
+ ary_memcpy(subst, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_EMBED_LEN(subst, len);
return subst;
}
@@ -641,11 +977,12 @@ rb_assoc_new(VALUE car, VALUE cdr)
return rb_ary_new3(2, car, cdr);
}
-static VALUE
-to_ary(VALUE ary)
+VALUE
+rb_to_array_type(VALUE ary)
{
return rb_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
}
+#define to_ary rb_to_array_type
VALUE
rb_check_array_type(VALUE ary)
@@ -653,23 +990,24 @@ rb_check_array_type(VALUE ary)
return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
}
+MJIT_FUNC_EXPORTED VALUE
+rb_check_to_array(VALUE ary)
+{
+ return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
+}
+
/*
* call-seq:
- * Array.try_convert(obj) -> array or nil
+ * Array.try_convert(object) -> object, new_array, or nil
*
- * Tries to convert +obj+ into an array, using +to_ary+ method. Returns the
- * converted array or +nil+ if +obj+ cannot be converted for any reason.
- * This method can be used to check if an argument is an array.
+ * If +object+ is an \Array object, returns +object+.
*
- * Array.try_convert([1]) #=> [1]
- * Array.try_convert("1") #=> nil
+ * Otherwise if +object+ responds to <tt>:to_ary</tt>,
+ * calls <tt>object.to_ary</tt> and returns the result.
*
- * if tmp = Array.try_convert(arg)
- * # the argument is an array
- * elsif tmp = String.try_convert(arg)
- * # the argument is a string
- * end
+ * Returns +nil+ if +object+ does not respond to <tt>:to_ary</tt>
*
+ * Raises an exception unless <tt>object.to_ary</tt> returns an \Array object.
*/
static VALUE
@@ -680,58 +1018,46 @@ rb_ary_s_try_convert(VALUE dummy, VALUE ary)
/*
* call-seq:
- * Array.new(size=0, default=nil)
- * Array.new(array)
- * Array.new(size) {|index| block }
- *
- * Returns a new array.
- *
- * In the first form, if no arguments are sent, the new array will be empty.
- * When a +size+ and an optional +default+ are sent, an array is created with
- * +size+ copies of +default+. Take notice that all elements will reference the
- * same object +default+.
- *
- * The second form creates a copy of the array passed as a parameter (the
- * array is generated by calling to_ary on the parameter).
- *
- * first_array = ["Matz", "Guido"]
- *
- * second_array = Array.new(first_array) #=> ["Matz", "Guido"]
- *
- * first_array.equal? second_array #=> false
- *
- * In the last form, an array of the given size is created. Each element in
- * this array is created by passing the element's index to the given block
- * and storing the return value.
- *
- * Array.new(3){ |index| index ** 2 }
- * # => [0, 1, 4]
- *
- * == Common gotchas
- *
- * When sending the second parameter, the same object will be used as the
- * value for all the array elements:
- *
- * a = Array.new(2, Hash.new)
- * # => [{}, {}]
- *
- * a[0]['cat'] = 'feline'
- * a # => [{"cat"=>"feline"}, {"cat"=>"feline"}]
- *
- * a[1]['cat'] = 'Felix'
- * a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
- *
- * Since all the Array elements store the same hash, changes to one of them
- * will affect them all.
- *
- * If multiple copies are what you want, you should use the block
- * version which uses the result of that block each time an element
- * of the array needs to be initialized:
- *
- * a = Array.new(2) { Hash.new }
- * a[0]['cat'] = 'feline'
- * a # => [{"cat"=>"feline"}, {}]
- *
+ * Array.new -> new_empty_array
+ * Array.new(array) -> new_array
+ * Array.new(size) -> new_array
+ * Array.new(size, default_value) -> new_array
+ * Array.new(size) {|index| ... } -> new_array
+ *
+ * Returns a new \Array.
+ *
+ * With no block and no arguments, returns a new empty \Array object.
+ *
+ * With no block and a single \Array argument +array+,
+ * returns a new \Array formed from +array+:
+ * a = Array.new([:foo, 'bar', 2])
+ * a.class # => Array
+ * a # => [:foo, "bar", 2]
+ *
+ * With no block and a single \Integer argument +size+,
+ * returns a new \Array of the given size
+ * whose elements are all +nil+:
+ * a = Array.new(3)
+ * a # => [nil, nil, nil]
+ *
+ * With no block and arguments +size+ and +default_value+,
+ * returns an \Array of the given size;
+ * each element is that same +default_value+:
+ * a = Array.new(3, 'x')
+ * a # => ['x', 'x', 'x']
+ *
+ * With a block and argument +size+,
+ * returns an \Array of the given size;
+ * the block is called with each successive integer +index+;
+ * the element for that +index+ is the return value from the block:
+ * a = Array.new(3) {|index| "Element #{index}" }
+ * a # => ["Element 0", "Element 1", "Element 2"]
+ *
+ * Raises ArgumentError if +size+ is negative.
+ *
+ * With a block and no argument,
+ * or a single argument +0+,
+ * ignores the block and returns a new empty \Array.
*/
static VALUE
@@ -742,8 +1068,8 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
rb_ary_modify(ary);
if (argc == 0) {
- if (ARY_OWNS_HEAP_P(ary) && RARRAY_CONST_PTR(ary) != 0) {
- ruby_sized_xfree((void *)RARRAY_CONST_PTR(ary), ARY_HEAP_SIZE(ary));
+ if (ARY_OWNS_HEAP_P(ary) && ARY_HEAP_PTR(ary) != NULL) {
+ ary_heap_free(ary);
}
rb_ary_unshare_safe(ary);
FL_SET_EMBED(ary);
@@ -794,7 +1120,7 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
/*
* Returns a new array populated with the given objects.
*
- * Array.[]( 1, 'a', /^A/ ) # => [1, "a", /^A/]
+ * Array.[]( 1, 'a', /^A/) # => [1, "a", /^A/]
* Array[ 1, 'a', /^A/ ] # => [1, "a", /^A/]
* [ 1, 'a', /^A/ ] # => [1, "a", /^A/]
*/
@@ -850,7 +1176,7 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
if (len <= RARRAY_EMBED_LEN_MAX) {
VALUE result = ary_alloc(klass);
- ary_memcpy(result, 0, len, RARRAY_CONST_PTR(ary) + offset);
+ ary_memcpy(result, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary) + offset);
ARY_SET_EMBED_LEN(result, len);
return result;
}
@@ -859,20 +1185,69 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
FL_UNSET_EMBED(result);
shared = ary_make_shared(ary);
- ARY_SET_PTR(result, RARRAY_CONST_PTR(ary));
+ ARY_SET_PTR(result, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_LEN(result, RARRAY_LEN(ary));
rb_ary_set_shared(result, shared);
ARY_INCREASE_PTR(result, offset);
ARY_SET_LEN(result, len);
+
+ ary_verify(shared);
+ ary_verify(result);
+ return result;
+ }
+}
+
+static VALUE
+ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
+{
+ assert(offset >= 0);
+ assert(len >= 0);
+ assert(offset+len <= RARRAY_LEN(ary));
+ assert(step != 0);
+
+ const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary);
+ const long orig_len = len;
+
+ if ((step > 0 && step >= len) || (step < 0 && (step < -len))) {
+ VALUE result = ary_new(klass, 1);
+ VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
+ RB_OBJ_WRITE(result, ptr, values[offset]);
+ ARY_SET_EMBED_LEN(result, 1);
return result;
}
+
+ long ustep = (step < 0) ? -step : step;
+ len = (len + ustep - 1) / ustep;
+
+ long i;
+ long j = offset + ((step > 0) ? 0 : (orig_len - 1));
+ VALUE result = ary_new(klass, len);
+ if (len <= RARRAY_EMBED_LEN_MAX) {
+ VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
+ for (i = 0; i < len; ++i) {
+ RB_OBJ_WRITE(result, ptr+i, values[j]);
+ j += step;
+ }
+ ARY_SET_EMBED_LEN(result, len);
+ }
+ else {
+ RARRAY_PTR_USE_TRANSIENT(result, ptr, {
+ for (i = 0; i < len; ++i) {
+ RB_OBJ_WRITE(result, ptr+i, values[j]);
+ j += step;
+ }
+ });
+ ARY_SET_LEN(result, len);
+ }
+
+ return result;
}
static VALUE
ary_make_shared_copy(VALUE ary)
{
- return ary_make_partial(ary, rb_obj_class(ary), 0, RARRAY_LEN(ary));
+ return ary_make_partial(ary, rb_cArray, 0, RARRAY_LEN(ary));
}
enum ary_take_pos_flags
@@ -884,13 +1259,17 @@ enum ary_take_pos_flags
static VALUE
ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last)
{
- VALUE nv;
long n;
long len;
long offset = 0;
- rb_scan_args(argc, argv, "1", &nv);
- n = NUM2LONG(nv);
+ argc = rb_check_arity(argc, 0, 1);
+ /* the case optional argument is omitted should be handled in
+ * callers of this function. if another arity case is added,
+ * this arity check needs to rewrite. */
+ RUBY_ASSERT_ALWAYS(argc == 1);
+
+ n = NUM2LONG(argv[0]);
len = RARRAY_LEN(ary);
if (n > len) {
n = len;
@@ -906,29 +1285,28 @@ ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos
/*
* call-seq:
- * ary << obj -> ary
- *
- * Append---Pushes the given object on to the end of this array. This
- * expression returns the array itself, so several appends
- * may be chained together.
+ * array << object -> self
*
- * a = [ 1, 2 ]
- * a << "c" << "d" << [ 3, 4 ]
- * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
- * a
- * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
+ * Appends +object+ to +self+; returns +self+:
+ * a = [:foo, 'bar', 2]
+ * a << :baz # => [:foo, "bar", 2, :baz]
*
+ * Appends +object+ as one element, even if it is another \Array:
+ * a = [:foo, 'bar', 2]
+ * a1 = a << [3, 4]
+ * a1 # => [:foo, "bar", 2, [3, 4]]
*/
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
- long idx = RARRAY_LEN(ary);
+ long idx = RARRAY_LEN((ary_verify(ary), ary));
VALUE target_ary = ary_ensure_room_for_push(ary, 1);
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
RB_OBJ_WRITE(target_ary, &ptr[idx], item);
});
ARY_SET_LEN(ary, idx + 1);
+ ary_verify(ary);
return ary;
}
@@ -944,18 +1322,22 @@ rb_ary_cat(VALUE ary, const VALUE *argv, long len)
/*
* call-seq:
- * ary.push(obj, ... ) -> ary
- *
- * Append --- Pushes the given object(s) on to the end of this array. This
- * expression returns the array itself, so several appends
- * may be chained together. See also Array#pop for the opposite
- * effect.
- *
- * a = [ "a", "b", "c" ]
- * a.push("d", "e", "f")
- * #=> ["a", "b", "c", "d", "e", "f"]
- * [1, 2, 3].push(4).push(5)
- * #=> [1, 2, 3, 4, 5]
+ * array.push(*objects) -> self
+ *
+ * Appends trailing elements.
+ *
+ * Appends each argument in +objects+ to +self+; returns +self+:
+ * a = [:foo, 'bar', 2]
+ * a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat]
+ *
+ * Appends each argument as one element, even if it is another \Array:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.push([:baz, :bat], [:bam, :bad])
+ * a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]
+ *
+ * Array#append is an alias for \Array#push.
+ *
+ * Related: #pop, #shift, #unshift.
*/
static VALUE
@@ -979,25 +1361,36 @@ rb_ary_pop(VALUE ary)
}
--n;
ARY_SET_LEN(ary, n);
+ ary_verify(ary);
return RARRAY_AREF(ary, n);
}
/*
* call-seq:
- * ary.pop -> obj or nil
- * ary.pop(n) -> new_ary
+ * array.pop -> object or nil
+ * array.pop(n) -> new_array
+ *
+ * Removes and returns trailing elements.
+ *
+ * When no argument is given and +self+ is not empty,
+ * removes and returns the last element:
+ * a = [:foo, 'bar', 2]
+ * a.pop # => 2
+ * a # => [:foo, "bar"]
+ *
+ * Returns +nil+ if the array is empty.
*
- * Removes the last element from +self+ and returns it, or
- * +nil+ if the array is empty.
+ * When a non-negative \Integer argument +n+ is given and is in range,
+ * removes and returns the last +n+ elements in a new \Array:
+ * a = [:foo, 'bar', 2]
+ * a.pop(2) # => ["bar", 2]
*
- * If a number +n+ is given, returns an array of the last +n+ elements
- * (or less) just like <code>array.slice!(-n, n)</code> does. See also
- * Array#push for the opposite effect.
+ * If +n+ is positive and out of range,
+ * removes and returns all elements:
+ * a = [:foo, 'bar', 2]
+ * a.pop(50) # => [:foo, "bar", 2]
*
- * a = [ "a", "b", "c", "d" ]
- * a.pop #=> "d"
- * a.pop(2) #=> ["b", "c"]
- * a #=> ["a"]
+ * Related: #push, #shift, #unshift.
*/
static VALUE
@@ -1012,6 +1405,7 @@ rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
rb_ary_modify_check(ary);
result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
+ ary_verify(ary);
return result;
}
@@ -1026,10 +1420,11 @@ rb_ary_shift(VALUE ary)
top = RARRAY_AREF(ary, 0);
if (!ARY_SHARED_P(ary)) {
if (len < ARY_DEFAULT_SIZE) {
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr, ptr+1, VALUE, len-1);
}); /* WB: no new reference */
ARY_INCREASE_LEN(ary, -1);
+ ary_verify(ary);
return top;
}
assert(!ARY_EMBED_P(ary)); /* ARY_EMBED_LEN_MAX < ARY_DEFAULT_SIZE */
@@ -1037,36 +1432,45 @@ rb_ary_shift(VALUE ary)
ARY_SET(ary, 0, Qnil);
ary_make_shared(ary);
}
- else if (ARY_SHARED_OCCUPIED(ARY_SHARED(ary))) {
- RARRAY_PTR_USE(ary, ptr, ptr[0] = Qnil);
+ else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, ptr[0] = Qnil);
}
ARY_INCREASE_PTR(ary, 1); /* shift ptr */
ARY_INCREASE_LEN(ary, -1);
+ ary_verify(ary);
+
return top;
}
/*
* call-seq:
- * ary.shift -> obj or nil
- * ary.shift(n) -> new_ary
+ * array.shift -> object or nil
+ * array.shift(n) -> new_array
+ *
+ * Removes and returns leading elements.
+ *
+ * When no argument is given, removes and returns the first element:
+ * a = [:foo, 'bar', 2]
+ * a.shift # => :foo
+ * a # => ['bar', 2]
*
- * Removes the first element of +self+ and returns it (shifting all
- * other elements down by one). Returns +nil+ if the array
- * is empty.
+ * Returns +nil+ if +self+ is empty.
*
- * If a number +n+ is given, returns an array of the first +n+ elements
- * (or less) just like <code>array.slice!(0, n)</code> does. With +ary+
- * containing only the remainder elements, not including what was shifted to
- * +new_ary+. See also Array#unshift for the opposite effect.
+ * When positive \Integer argument +n+ is given, removes the first +n+ elements;
+ * returns those elements in a new \Array:
+ * a = [:foo, 'bar', 2]
+ * a.shift(2) # => [:foo, 'bar']
+ * a # => [2]
*
- * args = [ "-m", "-q", "filename" ]
- * args.shift #=> "-m"
- * args #=> ["-q", "filename"]
+ * If +n+ is as large as or larger than <tt>self.length</tt>,
+ * removes all elements; returns those elements in a new \Array:
+ * a = [:foo, 'bar', 2]
+ * a.shift(3) # => [:foo, 'bar', 2]
*
- * args = [ "-m", "-q", "filename" ]
- * args.shift(2) #=> ["-m", "-q"]
- * args #=> ["filename"]
+ * If +n+ is zero, returns a new empty \Array; +self+ is unmodified.
+ *
+ * Related: #push, #pop, #unshift.
*/
static VALUE
@@ -1082,51 +1486,80 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
rb_ary_modify_check(ary);
result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
n = RARRAY_LEN(result);
- if (ARY_SHARED_P(ary)) {
- if (ARY_SHARED_OCCUPIED(ARY_SHARED(ary))) {
- setup_occupied_shared:
- ary_mem_clear(ary, 0, n);
- }
- ARY_INCREASE_PTR(ary, n);
+ rb_ary_behead(ary,n);
+
+ return result;
+}
+
+static VALUE
+behead_shared(VALUE ary, long n)
+{
+ assert(ARY_SHARED_P(ary));
+ rb_ary_modify_check(ary);
+ if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
+ ary_mem_clear(ary, 0, n);
+ }
+ ARY_INCREASE_PTR(ary, n);
+ ARY_INCREASE_LEN(ary, -n);
+ ary_verify(ary);
+ return ary;
+}
+
+static VALUE
+behead_transient(VALUE ary, long n)
+{
+ rb_ary_modify_check(ary);
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+ MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
+ }); /* WB: no new reference */
+ ARY_INCREASE_LEN(ary, -n);
+ ary_verify(ary);
+ return ary;
+}
+
+MJIT_FUNC_EXPORTED VALUE
+rb_ary_behead(VALUE ary, long n)
+{
+ if (n <= 0) {
+ return ary;
+ }
+ else if (ARY_SHARED_P(ary)) {
+ return behead_shared(ary, n);
+ }
+ else if (RARRAY_LEN(ary) >= ARY_DEFAULT_SIZE) {
+ ary_make_shared(ary);
+ return behead_shared(ary, n);
}
else {
- if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
- RARRAY_PTR_USE(ary, ptr, {
- MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
- }); /* WB: no new reference */
- }
- else {
- ary_make_shared(ary);
- goto setup_occupied_shared;
- }
+ return behead_transient(ary, n);
}
- ARY_INCREASE_LEN(ary, -n);
+}
- return result;
+static VALUE
+make_room_for_unshift(VALUE ary, const VALUE *head, VALUE *sharedp, int argc, long capa, long len)
+{
+ if (head - sharedp < argc) {
+ long room = capa - len - argc;
+
+ room -= room >> 4;
+ MEMMOVE((VALUE *)sharedp + argc + room, head, VALUE, len);
+ head = sharedp + argc + room;
+ }
+ ARY_SET_PTR(ary, head - argc);
+ assert(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary)));
+
+ ary_verify(ary);
+ return ARY_SHARED_ROOT(ary);
}
static VALUE
-ary_ensure_room_for_unshift(VALUE ary, int argc)
+ary_modify_for_unshift(VALUE ary, int argc)
{
long len = RARRAY_LEN(ary);
long new_len = len + argc;
long capa;
const VALUE *head, *sharedp;
- if (len > ARY_MAX_SIZE - argc) {
- rb_raise(rb_eIndexError, "index %ld too big", new_len);
- }
-
- if (ARY_SHARED_P(ary)) {
- VALUE shared = ARY_SHARED(ary);
- capa = RARRAY_LEN(shared);
- if (ARY_SHARED_OCCUPIED(shared) && capa > new_len) {
- head = RARRAY_CONST_PTR(ary);
- sharedp = RARRAY_CONST_PTR(shared);
- goto makeroom_if_need;
- }
- }
-
rb_ary_modify(ary);
capa = ARY_CAPA(ary);
if (capa - (capa >> 6) <= new_len) {
@@ -1135,45 +1568,69 @@ ary_ensure_room_for_unshift(VALUE ary, int argc)
/* use shared array for big "queues" */
if (new_len > ARY_DEFAULT_SIZE * 4) {
- /* make a room for unshifted items */
+ ary_verify(ary);
+
+ /* make a room for unshifted items */
capa = ARY_CAPA(ary);
ary_make_shared(ary);
- head = sharedp = RARRAY_CONST_PTR(ary);
- goto makeroom;
- makeroom_if_need:
- if (head - sharedp < argc) {
- long room;
- makeroom:
- room = capa - new_len;
- room -= room >> 4;
- MEMMOVE((VALUE *)sharedp + argc + room, head, VALUE, len);
- head = sharedp + argc + room;
- }
- ARY_SET_PTR(ary, head - argc);
- assert(ARY_SHARED_OCCUPIED(ARY_SHARED(ary)));
- return ARY_SHARED(ary);
+ head = sharedp = RARRAY_CONST_PTR_TRANSIENT(ary);
+ return make_room_for_unshift(ary, head, (void *)sharedp, argc, capa, len);
}
else {
/* sliding items */
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr + argc, ptr, VALUE, len);
});
+ ary_verify(ary);
return ary;
}
}
+static VALUE
+ary_ensure_room_for_unshift(VALUE ary, int argc)
+{
+ long len = RARRAY_LEN(ary);
+ long new_len = len + argc;
+
+ if (len > ARY_MAX_SIZE - argc) {
+ rb_raise(rb_eIndexError, "index %ld too big", new_len);
+ }
+ else if (! ARY_SHARED_P(ary)) {
+ return ary_modify_for_unshift(ary, argc);
+ }
+ else {
+ VALUE shared_root = ARY_SHARED_ROOT(ary);
+ long capa = RARRAY_LEN(shared_root);
+
+ if (! ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
+ return ary_modify_for_unshift(ary, argc);
+ }
+ else if (new_len > capa) {
+ return ary_modify_for_unshift(ary, argc);
+ }
+ else {
+ const VALUE * head = RARRAY_CONST_PTR_TRANSIENT(ary);
+ void *sharedp = (void *)RARRAY_CONST_PTR_TRANSIENT(shared_root);
+
+ rb_ary_modify_check(ary);
+ return make_room_for_unshift(ary, head, sharedp, argc, capa, len);
+ }
+ }
+}
+
/*
* call-seq:
- * ary.unshift(obj, ...) -> ary
+ * array.unshift(*objects) -> self
+ *
+ * Prepends the given +objects+ to +self+:
+ * a = [:foo, 'bar', 2]
+ * a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]
*
- * Prepends objects to the front of +self+, moving other elements upwards.
- * See also Array#shift for the opposite effect.
+ * Array#prepend is an alias for Array#unshift.
*
- * a = [ "b", "c", "d" ]
- * a.unshift("a") #=> ["a", "b", "c", "d"]
- * a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"]
+ * Related: #push, #pop, #shift.
*/
static VALUE
@@ -1214,21 +1671,11 @@ rb_ary_elt(VALUE ary, long offset)
VALUE
rb_ary_entry(VALUE ary, long offset)
{
- long len = RARRAY_LEN(ary);
- const VALUE *ptr = RARRAY_CONST_PTR(ary);
- if (len == 0) return Qnil;
- if (offset < 0) {
- offset += len;
- if (offset < 0) return Qnil;
- }
- else if (len <= offset) {
- return Qnil;
- }
- return ptr[offset];
+ return rb_ary_entry_internal(ary, offset);
}
VALUE
-rb_ary_subseq(VALUE ary, long beg, long len)
+rb_ary_subseq_step(VALUE ary, long beg, long len, long step)
{
VALUE klass;
long alen = RARRAY_LEN(ary);
@@ -1239,93 +1686,169 @@ rb_ary_subseq(VALUE ary, long beg, long len)
if (alen < len || alen < beg + len) {
len = alen - beg;
}
- klass = rb_obj_class(ary);
+ klass = rb_cArray;
if (len == 0) return ary_new(klass, 0);
+ if (step == 0)
+ rb_raise(rb_eArgError, "slice step cannot be zero");
+ if (step == 1)
+ return ary_make_partial(ary, klass, beg, len);
+ else
+ return ary_make_partial_step(ary, klass, beg, len, step);
+}
- return ary_make_partial(ary, klass, beg, len);
+VALUE
+rb_ary_subseq(VALUE ary, long beg, long len)
+{
+ return rb_ary_subseq_step(ary, beg, len, 1);
}
+static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
+
/*
* call-seq:
- * ary[index] -> obj or nil
- * ary[start, length] -> new_ary or nil
- * ary[range] -> new_ary or nil
- * ary.slice(index) -> obj or nil
- * ary.slice(start, length) -> new_ary or nil
- * ary.slice(range) -> new_ary or nil
- *
- * Element Reference --- Returns the element at +index+, or returns a
- * subarray starting at the +start+ index and continuing for +length+
- * elements, or returns a subarray specified by +range+ of indices.
- *
- * Negative indices count backward from the end of the array (-1 is the last
- * element). For +start+ and +range+ cases the starting index is just before
- * an element. Additionally, an empty array is returned when the starting
- * index for an element range is at the end of the array.
- *
- * Returns +nil+ if the index (or starting index) are out of range.
- *
- * a = [ "a", "b", "c", "d", "e" ]
- * a[2] + a[0] + a[1] #=> "cab"
- * a[6] #=> nil
- * a[1, 2] #=> [ "b", "c" ]
- * a[1..3] #=> [ "b", "c", "d" ]
- * a[4..7] #=> [ "e" ]
- * a[6..10] #=> nil
- * a[-3, 3] #=> [ "c", "d", "e" ]
- * # special cases
- * a[5] #=> nil
- * a[6, 1] #=> nil
- * a[5, 1] #=> []
- * a[5..10] #=> []
- *
+ * array[index] -> object or nil
+ * array[start, length] -> object or nil
+ * array[range] -> object or nil
+ * array[aseq] -> object or nil
+ * array.slice(index) -> object or nil
+ * array.slice(start, length) -> object or nil
+ * array.slice(range) -> object or nil
+ * array.slice(aseq) -> object or nil
+ *
+ * Returns elements from +self+; does not modify +self+.
+ *
+ * When a single \Integer argument +index+ is given, returns the element at offset +index+:
+ * a = [:foo, 'bar', 2]
+ * a[0] # => :foo
+ * a[2] # => 2
+ * a # => [:foo, "bar", 2]
+ *
+ * If +index+ is negative, counts relative to the end of +self+:
+ * a = [:foo, 'bar', 2]
+ * a[-1] # => 2
+ * a[-2] # => "bar"
+ *
+ * If +index+ is out of range, returns +nil+.
+ *
+ * When two \Integer arguments +start+ and +length+ are given,
+ * returns a new \Array of size +length+ containing successive elements beginning at offset +start+:
+ * a = [:foo, 'bar', 2]
+ * a[0, 2] # => [:foo, "bar"]
+ * a[1, 2] # => ["bar", 2]
+ *
+ * If <tt>start + length</tt> is greater than <tt>self.length</tt>,
+ * returns all elements from offset +start+ to the end:
+ * a = [:foo, 'bar', 2]
+ * a[0, 4] # => [:foo, "bar", 2]
+ * a[1, 3] # => ["bar", 2]
+ * a[2, 2] # => [2]
+ *
+ * If <tt>start == self.size</tt> and <tt>length >= 0</tt>,
+ * returns a new empty \Array.
+ *
+ * If +length+ is negative, returns +nil+.
+ *
+ * When a single \Range argument +range+ is given,
+ * treats <tt>range.min</tt> as +start+ above
+ * and <tt>range.size</tt> as +length+ above:
+ * a = [:foo, 'bar', 2]
+ * a[0..1] # => [:foo, "bar"]
+ * a[1..2] # => ["bar", 2]
+ *
+ * Special case: If <tt>range.start == a.size</tt>, returns a new empty \Array.
+ *
+ * If <tt>range.end</tt> is negative, calculates the end index from the end:
+ * a = [:foo, 'bar', 2]
+ * a[0..-1] # => [:foo, "bar", 2]
+ * a[0..-2] # => [:foo, "bar"]
+ * a[0..-3] # => [:foo]
+ *
+ * If <tt>range.start</tt> is negative, calculates the start index from the end:
+ * a = [:foo, 'bar', 2]
+ * a[-1..2] # => [2]
+ * a[-2..2] # => ["bar", 2]
+ * a[-3..2] # => [:foo, "bar", 2]
+ *
+ * If <tt>range.start</tt> is larger than the array size, returns +nil+.
+ * a = [:foo, 'bar', 2]
+ * a[4..1] # => nil
+ * a[4..0] # => nil
+ * a[4..-1] # => nil
+ *
+ * When a single Enumerator::ArithmeticSequence argument +aseq+ is given,
+ * returns an Array of elements corresponding to the indexes produced by
+ * the sequence.
+ * a = ['--', 'data1', '--', 'data2', '--', 'data3']
+ * a[(1..).step(2)] # => ["data1", "data2", "data3"]
+ *
+ * Unlike slicing with range, if the start or the end of the arithmetic sequence
+ * is larger than array size, throws RangeError.
+ * a = ['--', 'data1', '--', 'data2', '--', 'data3']
+ * a[(1..11).step(2)]
+ * # RangeError (((1..11).step(2)) out of range)
+ * a[(7..).step(2)]
+ * # RangeError (((7..).step(2)) out of range)
+ *
+ * If given a single argument, and its type is not one of the listed, tries to
+ * convert it to Integer, and raises if it is impossible:
+ * a = [:foo, 'bar', 2]
+ * # Raises TypeError (no implicit conversion of Symbol into Integer):
+ * a[:foo]
+ *
+ * Array#slice is an alias for Array#[].
*/
VALUE
rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
{
- VALUE arg;
- long beg, len;
-
+ rb_check_arity(argc, 1, 2);
if (argc == 2) {
- beg = NUM2LONG(argv[0]);
- len = NUM2LONG(argv[1]);
- if (beg < 0) {
- beg += RARRAY_LEN(ary);
- }
- return rb_ary_subseq(ary, beg, len);
+ return rb_ary_aref2(ary, argv[0], argv[1]);
}
- if (argc != 1) {
- rb_scan_args(argc, argv, "11", NULL, NULL);
+ return rb_ary_aref1(ary, argv[0]);
+}
+
+static VALUE
+rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
+{
+ long beg = NUM2LONG(b);
+ long len = NUM2LONG(e);
+ if (beg < 0) {
+ beg += RARRAY_LEN(ary);
}
- arg = argv[0];
+ return rb_ary_subseq(ary, beg, len);
+}
+
+MJIT_FUNC_EXPORTED VALUE
+rb_ary_aref1(VALUE ary, VALUE arg)
+{
+ long beg, len, step;
+
/* special case - speeding up */
if (FIXNUM_P(arg)) {
return rb_ary_entry(ary, FIX2LONG(arg));
}
- /* check if idx is Range */
- switch (rb_range_beg_len(arg, &beg, &len, RARRAY_LEN(ary), 0)) {
+ /* check if idx is Range or ArithmeticSequence */
+ switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &len, &step, RARRAY_LEN(ary), 0)) {
case Qfalse:
- break;
+ break;
case Qnil:
- return Qnil;
+ return Qnil;
default:
- return rb_ary_subseq(ary, beg, len);
+ return rb_ary_subseq_step(ary, beg, len, step);
}
+
return rb_ary_entry(ary, NUM2LONG(arg));
}
/*
* call-seq:
- * ary.at(index) -> obj or nil
- *
- * Returns the element at +index+. A negative index counts from the end of
- * +self+. Returns +nil+ if the index is out of range. See also
- * Array#[].
+ * array.at(index) -> object
*
- * a = [ "a", "b", "c", "d", "e" ]
- * a.at(0) #=> "a"
- * a.at(-1) #=> "e"
+ * Returns the element at \Integer offset +index+; does not modify +self+.
+ * a = [:foo, 'bar', 2]
+ * a.at(0) # => :foo
+ * a.at(2) # => 2
*/
VALUE
@@ -1336,19 +1859,33 @@ rb_ary_at(VALUE ary, VALUE pos)
/*
* call-seq:
- * ary.first -> obj or nil
- * ary.first(n) -> new_ary
+ * array.first -> object or nil
+ * array.first(n) -> new_array
+ *
+ * Returns elements from +self+; does not modify +self+.
+ *
+ * When no argument is given, returns the first element:
+ * a = [:foo, 'bar', 2]
+ * a.first # => :foo
+ * a # => [:foo, "bar", 2]
+ *
+ * If +self+ is empty, returns +nil+.
+ *
+ * When non-negative \Integer argument +n+ is given,
+ * returns the first +n+ elements in a new \Array:
+ * a = [:foo, 'bar', 2]
+ * a.first(2) # => [:foo, "bar"]
*
- * Returns the first element, or the first +n+ elements, of the array.
- * If the array is empty, the first form returns +nil+, and the
- * second form returns an empty array. See also Array#last for
- * the opposite effect.
+ * If <tt>n >= array.size</tt>, returns all elements:
+ * a = [:foo, 'bar', 2]
+ * a.first(50) # => [:foo, "bar", 2]
*
- * a = [ "q", "r", "s", "t" ]
- * a.first #=> "q"
- * a.first(2) #=> ["q", "r"]
+ * If <tt>n == 0</tt> returns an new empty \Array:
+ * a = [:foo, 'bar', 2]
+ * a.first(0) # []
+ *
+ * Related: #last.
*/
-
static VALUE
rb_ary_first(int argc, VALUE *argv, VALUE ary)
{
@@ -1363,17 +1900,32 @@ rb_ary_first(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.last -> obj or nil
- * ary.last(n) -> new_ary
+ * array.last -> object or nil
+ * array.last(n) -> new_array
+ *
+ * Returns elements from +self+; +self+ is not modified.
+ *
+ * When no argument is given, returns the last element:
+ * a = [:foo, 'bar', 2]
+ * a.last # => 2
+ * a # => [:foo, "bar", 2]
+ *
+ * If +self+ is empty, returns +nil+.
*
- * Returns the last element(s) of +self+. If the array is empty,
- * the first form returns +nil+.
+ * When non-negative \Innteger argument +n+ is given,
+ * returns the last +n+ elements in a new \Array:
+ * a = [:foo, 'bar', 2]
+ * a.last(2) # => ["bar", 2]
*
- * See also Array#first for the opposite effect.
+ * If <tt>n >= array.size</tt>, returns all elements:
+ * a = [:foo, 'bar', 2]
+ * a.last(50) # => [:foo, "bar", 2]
*
- * a = [ "w", "x", "y", "z" ]
- * a.last #=> "z"
- * a.last(2) #=> ["y", "z"]
+ * If <tt>n == 0</tt>, returns an new empty \Array:
+ * a = [:foo, 'bar', 2]
+ * a.last(0) # []
+ *
+ * Related: #first.
*/
VALUE
@@ -1391,26 +1943,35 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.fetch(index) -> obj
- * ary.fetch(index, default) -> obj
- * ary.fetch(index) { |index| block } -> obj
- *
- * Tries to return the element at position +index+, but throws an IndexError
- * exception if the referenced +index+ lies outside of the array bounds. This
- * error can be prevented by supplying a second argument, which will act as a
- * +default+ value.
- *
- * Alternatively, if a block is given it will only be executed when an
- * invalid +index+ is referenced.
- *
- * Negative values of +index+ count from the end of the array.
- *
- * a = [ 11, 22, 33, 44 ]
- * a.fetch(1) #=> 22
- * a.fetch(-1) #=> 44
- * a.fetch(4, 'cat') #=> "cat"
- * a.fetch(100) { |i| puts "#{i} is out of bounds" }
- * #=> "100 is out of bounds"
+ * array.fetch(index) -> element
+ * array.fetch(index, default_value) -> element
+ * array.fetch(index) {|index| ... } -> element
+ *
+ * Returns the element at offset +index+.
+ *
+ * With the single \Integer argument +index+,
+ * returns the element at offset +index+:
+ * a = [:foo, 'bar', 2]
+ * a.fetch(1) # => "bar"
+ *
+ * If +index+ is negative, counts from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a.fetch(-1) # => 2
+ * a.fetch(-2) # => "bar"
+ *
+ * With arguments +index+ and +default_value+,
+ * returns the element at offset +index+ if index is in range,
+ * otherwise returns +default_value+:
+ * a = [:foo, 'bar', 2]
+ * a.fetch(1, nil) # => "bar"
+ *
+ * With argument +index+ and a block,
+ * returns the element at offset +index+ if index is in range
+ * (and the block is not called); otherwise calls the block with index and returns its return value:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.fetch(1) {|index| raise 'Cannot happen' } # => "bar"
+ * a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50"
*/
static VALUE
@@ -1443,28 +2004,37 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.find_index(obj) -> int or nil
- * ary.find_index { |item| block } -> int or nil
- * ary.find_index -> Enumerator
- * ary.index(obj) -> int or nil
- * ary.index { |item| block } -> int or nil
- * ary.index -> Enumerator
+ * array.index(object) -> integer or nil
+ * array.index {|element| ... } -> integer or nil
+ * array.index -> new_enumerator
+ *
+ * Returns the index of a specified element.
+ *
+ * When argument +object+ is given but no block,
+ * returns the index of the first element +element+
+ * for which <tt>object == element</tt>:
+ * a = [:foo, 'bar', 2, 'bar']
+ * a.index('bar') # => 1
+ *
+ * Returns +nil+ if no such element found.
*
- * Returns the _index_ of the first object in +ary+ such that the object is
- * <code>==</code> to +obj+.
+ * When both argument +object+ and a block are given,
+ * calls the block with each successive element;
+ * returns the index of the first element for which the block returns a truthy value:
+ * a = [:foo, 'bar', 2, 'bar']
+ * a.index {|element| element == 'bar' } # => 1
*
- * If a block is given instead of an argument, returns the _index_ of the
- * first object for which the block returns +true+. Returns +nil+ if no
- * match is found.
+ * Returns +nil+ if the block never returns a truthy value.
*
- * See also Array#rindex.
+ * When neither an argument nor a block is given, returns a new Enumerator:
+ * a = [:foo, 'bar', 2]
+ * e = a.index
+ * e # => #<Enumerator: [:foo, "bar", 2]:index>
+ * e.each {|element| element == 'bar' } # => 1
*
- * An Enumerator is returned if neither a block nor argument is given.
+ * Array#find_index is an alias for Array#index.
*
- * a = [ "a", "b", "c" ]
- * a.index("b") #=> 1
- * a.index("z") #=> nil
- * a.index { |x| x == "b" } #=> 1
+ * Related: #rindex.
*/
static VALUE
@@ -1497,26 +2067,33 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.rindex(obj) -> int or nil
- * ary.rindex { |item| block } -> int or nil
- * ary.rindex -> Enumerator
+ * array.rindex(object) -> integer or nil
+ * array.rindex {|element| ... } -> integer or nil
+ * array.rindex -> new_enumerator
*
- * Returns the _index_ of the last object in +self+ <code>==</code> to +obj+.
+ * Returns the index of the last element for which <tt>object == element</tt>.
*
- * If a block is given instead of an argument, returns the _index_ of the
- * first object for which the block returns +true+, starting from the last
- * object.
+ * When argument +object+ is given but no block, returns the index of the last such element found:
+ * a = [:foo, 'bar', 2, 'bar']
+ * a.rindex('bar') # => 3
*
- * Returns +nil+ if no match is found.
+ * Returns +nil+ if no such object found.
*
- * See also Array#index.
+ * When a block is given but no argument, calls the block with each successive element;
+ * returns the index of the last element for which the block returns a truthy value:
+ * a = [:foo, 'bar', 2, 'bar']
+ * a.rindex {|element| element == 'bar' } # => 3
*
- * If neither block nor argument is given, an Enumerator is returned instead.
+ * Returns +nil+ if the block never returns a truthy value.
*
- * a = [ "a", "b", "b", "b", "c" ]
- * a.rindex("b") #=> 3
- * a.rindex("z") #=> nil
- * a.rindex { |x| x == "b" } #=> 3
+ * When neither an argument nor a block is given, returns a new \Enumerator:
+ *
+ * a = [:foo, 'bar', 2, 'bar']
+ * e = a.rindex
+ * e # => #<Enumerator: [:foo, "bar", 2, "bar"]:rindex>
+ * e.each {|element| element == 'bar' } # => 3
+ *
+ * Related: #index.
*/
static VALUE
@@ -1545,6 +2122,9 @@ rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
if (rb_equal(e, val)) {
return LONG2NUM(i);
}
+ if (i > RARRAY_LEN(ary)) {
+ break;
+ }
}
return Qnil;
}
@@ -1578,7 +2158,7 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
}
{
- const VALUE *optr = RARRAY_CONST_PTR(ary);
+ const VALUE *optr = RARRAY_CONST_PTR_TRANSIENT(ary);
rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
}
@@ -1591,7 +2171,7 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
len = beg + rlen;
ary_mem_clear(ary, olen, beg - olen);
if (rlen > 0) {
- if (rofs != -1) rptr = RARRAY_CONST_PTR(ary) + rofs;
+ if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
ary_memcpy0(ary, beg, rlen, rptr, target_ary);
}
ARY_SET_LEN(ary, len);
@@ -1609,14 +2189,21 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
}
if (len != rlen) {
- RARRAY_PTR_USE(ary, ptr,
- MEMMOVE(ptr + beg + rlen, ptr + beg + len,
- VALUE, olen - (beg + len)));
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr,
+ MEMMOVE(ptr + beg + rlen, ptr + beg + len,
+ VALUE, olen - (beg + len)));
ARY_SET_LEN(ary, alen);
}
if (rlen > 0) {
- if (rofs != -1) rptr = RARRAY_CONST_PTR(ary) + rofs;
- MEMMOVE(RARRAY_PTR(ary) + beg, rptr, VALUE, rlen);
+ if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
+ /* give up wb-protected ary */
+ RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
+
+ /* do not use RARRAY_PTR() because it can causes GC.
+ * ary can contain T_NONE object because it is not cleared.
+ */
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr,
+ MEMMOVE(ptr + beg, rptr, VALUE, rlen));
}
}
}
@@ -1674,96 +2261,184 @@ rb_ary_resize(VALUE ary, long len)
}
else {
if (olen > len + ARY_DEFAULT_SIZE) {
- SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, len, RARRAY(ary)->as.heap.aux.capa);
+ ary_heap_realloc(ary, len);
ARY_SET_CAPA(ary, len);
}
ARY_SET_HEAP_LEN(ary, len);
}
+ ary_verify(ary);
return ary;
}
+static VALUE
+ary_aset_by_rb_ary_store(VALUE ary, long key, VALUE val)
+{
+ rb_ary_store(ary, key, val);
+ return val;
+}
+
+static VALUE
+ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
+{
+ VALUE rpl = rb_ary_to_ary(val);
+ rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR_TRANSIENT(rpl), RARRAY_LEN(rpl));
+ RB_GC_GUARD(rpl);
+ return val;
+}
+
/*
* call-seq:
- * ary[index] = obj -> obj
- * ary[start, length] = obj or other_ary or nil -> obj or other_ary or nil
- * ary[range] = obj or other_ary or nil -> obj or other_ary or nil
- *
- * Element Assignment --- Sets the element at +index+, or replaces a subarray
- * from the +start+ index for +length+ elements, or replaces a subarray
- * specified by the +range+ of indices.
- *
- * If indices are greater than the current capacity of the array, the array
- * grows automatically. Elements are inserted into the array at +start+ if
- * +length+ is zero.
- *
- * Negative indices will count backward from the end of the array. For
- * +start+ and +range+ cases the starting index is just before an element.
- *
- * An IndexError is raised if a negative index points past the beginning of
- * the array.
- *
- * See also Array#push, and Array#unshift.
- *
- * a = Array.new
- * a[4] = "4"; #=> [nil, nil, nil, nil, "4"]
- * a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
- * a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"]
- * a[0, 2] = "?" #=> ["?", 2, nil, "4"]
- * a[0..2] = "A" #=> ["A", "4"]
- * a[-1] = "Z" #=> ["A", "Z"]
- * a[1..-1] = nil #=> ["A", nil]
- * a[1..-1] = [] #=> ["A"]
- * a[0, 0] = [ 1, 2 ] #=> [1, 2, "A"]
- * a[3, 0] = "B" #=> [1, 2, "A", "B"]
+ * array[index] = object -> object
+ * array[start, length] = object -> object
+ * array[range] = object -> object
+ *
+ * Assigns elements in +self+; returns the given +object+.
+ *
+ * When \Integer argument +index+ is given, assigns +object+ to an element in +self+.
+ *
+ * If +index+ is non-negative, assigns +object+ the element at offset +index+:
+ * a = [:foo, 'bar', 2]
+ * a[0] = 'foo' # => "foo"
+ * a # => ["foo", "bar", 2]
+ *
+ * If +index+ is greater than <tt>self.length</tt>, extends the array:
+ * a = [:foo, 'bar', 2]
+ * a[7] = 'foo' # => "foo"
+ * a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]
+ *
+ * If +index+ is negative, counts backwards from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a[-1] = 'two' # => "two"
+ * a # => [:foo, "bar", "two"]
+ *
+ * When \Integer arguments +start+ and +length+ are given and +object+ is not an \Array,
+ * removes <tt>length - 1</tt> elements beginning at offset +start+,
+ * and assigns +object+ at offset +start+:
+ * a = [:foo, 'bar', 2]
+ * a[0, 2] = 'foo' # => "foo"
+ * a # => ["foo", 2]
+ *
+ * If +start+ is negative, counts backwards from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a[-2, 2] = 'foo' # => "foo"
+ * a # => [:foo, "foo"]
+ *
+ * If +start+ is non-negative and outside the array (<tt> >= self.size</tt>),
+ * extends the array with +nil+, assigns +object+ at offset +start+,
+ * and ignores +length+:
+ * a = [:foo, 'bar', 2]
+ * a[6, 50] = 'foo' # => "foo"
+ * a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
+ *
+ * If +length+ is zero, shifts elements at and following offset +start+
+ * and assigns +object+ at offset +start+:
+ * a = [:foo, 'bar', 2]
+ * a[1, 0] = 'foo' # => "foo"
+ * a # => [:foo, "foo", "bar", 2]
+ *
+ * If +length+ is too large for the existing array, does not extend the array:
+ * a = [:foo, 'bar', 2]
+ * a[1, 5] = 'foo' # => "foo"
+ * a # => [:foo, "foo"]
+ *
+ * When \Range argument +range+ is given and +object+ is an \Array,
+ * removes <tt>length - 1</tt> elements beginning at offset +start+,
+ * and assigns +object+ at offset +start+:
+ * a = [:foo, 'bar', 2]
+ * a[0..1] = 'foo' # => "foo"
+ * a # => ["foo", 2]
+ *
+ * if <tt>range.begin</tt> is negative, counts backwards from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a[-2..2] = 'foo' # => "foo"
+ * a # => [:foo, "foo"]
+ *
+ * If the array length is less than <tt>range.begin</tt>,
+ * assigns +object+ at offset <tt>range.begin</tt>, and ignores +length+:
+ * a = [:foo, 'bar', 2]
+ * a[6..50] = 'foo' # => "foo"
+ * a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
+ *
+ * If <tt>range.end</tt> is zero, shifts elements at and following offset +start+
+ * and assigns +object+ at offset +start+:
+ * a = [:foo, 'bar', 2]
+ * a[1..0] = 'foo' # => "foo"
+ * a # => [:foo, "foo", "bar", 2]
+ *
+ * If <tt>range.end</tt> is negative, assigns +object+ at offset +start+,
+ * retains <tt>range.end.abs -1</tt> elements past that, and removes those beyond:
+ * a = [:foo, 'bar', 2]
+ * a[1..-1] = 'foo' # => "foo"
+ * a # => [:foo, "foo"]
+ * a = [:foo, 'bar', 2]
+ * a[1..-2] = 'foo' # => "foo"
+ * a # => [:foo, "foo", 2]
+ * a = [:foo, 'bar', 2]
+ * a[1..-3] = 'foo' # => "foo"
+ * a # => [:foo, "foo", "bar", 2]
+ * a = [:foo, 'bar', 2]
+ *
+ * If <tt>range.end</tt> is too large for the existing array,
+ * replaces array elements, but does not extend the array with +nil+ values:
+ * a = [:foo, 'bar', 2]
+ * a[1..5] = 'foo' # => "foo"
+ * a # => [:foo, "foo"]
*/
static VALUE
rb_ary_aset(int argc, VALUE *argv, VALUE ary)
{
long offset, beg, len;
- VALUE rpl;
+ rb_check_arity(argc, 2, 3);
+ rb_ary_modify_check(ary);
if (argc == 3) {
- rb_ary_modify_check(ary);
beg = NUM2LONG(argv[0]);
len = NUM2LONG(argv[1]);
- goto range;
+ return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);
}
- rb_check_arity(argc, 2, 2);
- rb_ary_modify_check(ary);
if (FIXNUM_P(argv[0])) {
offset = FIX2LONG(argv[0]);
- goto fixnum;
+ return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}
if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
/* check if idx is Range */
- range:
- rpl = rb_ary_to_ary(argv[argc-1]);
- rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR(rpl), RARRAY_LEN(rpl));
- RB_GC_GUARD(rpl);
- return argv[argc-1];
+ return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);
}
offset = NUM2LONG(argv[0]);
-fixnum:
- rb_ary_store(ary, offset, argv[1]);
- return argv[1];
+ return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}
/*
* call-seq:
- * ary.insert(index, obj...) -> ary
- *
- * Inserts the given values before the element with the given +index+.
+ * array.insert(index, *objects) -> self
*
- * Negative indices count backwards from the end of the array, where +-1+ is
- * the last element. If a negative index is used, the given values will be
- * inserted after that element, so using an index of +-1+ will insert the
- * values at the end of the array.
+ * Inserts given +objects+ before or after the element at \Integer index +offset+;
+ * returns +self+.
*
- * a = %w{ a b c d }
- * a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]
- * a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
+ * When +index+ is non-negative, inserts all given +objects+
+ * before the element at offset +index+:
+ * a = [:foo, 'bar', 2]
+ * a.insert(1, :bat, :bam) # => [:foo, :bat, :bam, "bar", 2]
+ *
+ * Extends the array if +index+ is beyond the array (<tt>index >= self.size</tt>):
+ * a = [:foo, 'bar', 2]
+ * a.insert(5, :bat, :bam)
+ * a # => [:foo, "bar", 2, nil, nil, :bat, :bam]
+ *
+ * Does nothing if no objects given:
+ * a = [:foo, 'bar', 2]
+ * a.insert(1)
+ * a.insert(50)
+ * a.insert(-50)
+ * a # => [:foo, "bar", 2]
+ *
+ * When +index+ is negative, inserts all given +objects+
+ * _after_ the element at offset <tt>index+self.size</tt>:
+ * a = [:foo, 'bar', 2]
+ * a.insert(-2, :bat, :bam)
+ * a # => [:foo, "bar", :bat, :bam, 2]
*/
static VALUE
@@ -1801,27 +2476,48 @@ ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.each { |item| block } -> ary
- * ary.each -> Enumerator
+ * array.each {|element| ... } -> self
+ * array.each -> Enumerator
+ *
+ * Iterates over array elements.
*
- * Calls the given block once for each element in +self+, passing that element
- * as a parameter. Returns the array itself.
+ * When a block given, passes each successive array element to the block;
+ * returns +self+:
+ * a = [:foo, 'bar', 2]
+ * a.each {|element| puts "#{element.class} #{element}" }
*
- * If no block is given, an Enumerator is returned.
+ * Output:
+ * Symbol foo
+ * String bar
+ * Integer 2
*
- * a = [ "a", "b", "c" ]
- * a.each {|x| print x, " -- " }
+ * Allows the array to be modified during iteration:
+ * a = [:foo, 'bar', 2]
+ * a.each {|element| puts element; a.clear if element.to_s.start_with?('b') }
*
- * produces:
+ * Output:
+ * foo
+ * bar
*
- * a -- b -- c --
+ * When no block given, returns a new \Enumerator:
+ * a = [:foo, 'bar', 2]
+ * e = a.each
+ * e # => #<Enumerator: [:foo, "bar", 2]:each>
+ * a1 = e.each {|element| puts "#{element.class} #{element}" }
+ *
+ * Output:
+ * Symbol foo
+ * String bar
+ * Integer 2
+ *
+ * Related: #each_index, #reverse_each.
*/
VALUE
rb_ary_each(VALUE ary)
{
long i;
-
+ ary_verify(ary);
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
@@ -1831,20 +2527,41 @@ rb_ary_each(VALUE ary)
/*
* call-seq:
- * ary.each_index { |index| block } -> ary
- * ary.each_index -> Enumerator
+ * array.each_index {|index| ... } -> self
+ * array.each_index -> Enumerator
+ *
+ * Iterates over array indexes.
+ *
+ * When a block given, passes each successive array index to the block;
+ * returns +self+:
+ * a = [:foo, 'bar', 2]
+ * a.each_index {|index| puts "#{index} #{a[index]}" }
*
- * Same as Array#each, but passes the +index+ of the element instead of the
- * element itself.
+ * Output:
+ * 0 foo
+ * 1 bar
+ * 2 2
*
- * An Enumerator is returned if no block is given.
+ * Allows the array to be modified during iteration:
+ * a = [:foo, 'bar', 2]
+ * a.each_index {|index| puts index; a.clear if index > 0 }
*
- * a = [ "a", "b", "c" ]
- * a.each_index {|x| print x, " -- " }
+ * Output:
+ * 0
+ * 1
*
- * produces:
+ * When no block given, returns a new \Enumerator:
+ * a = [:foo, 'bar', 2]
+ * e = a.each_index
+ * e # => #<Enumerator: [:foo, "bar", 2]:each_index>
+ * a1 = e.each {|index| puts "#{index} #{a[index]}"}
*
- * 0 -- 1 -- 2 --
+ * Output:
+ * 0 foo
+ * 1 bar
+ * 2 2
+ *
+ * Related: #each, #reverse_each.
*/
static VALUE
@@ -1861,17 +2578,40 @@ rb_ary_each_index(VALUE ary)
/*
* call-seq:
- * ary.reverse_each { |item| block } -> ary
- * ary.reverse_each -> Enumerator
- *
- * Same as Array#each, but traverses +self+ in reverse order.
- *
- * a = [ "a", "b", "c" ]
- * a.reverse_each {|x| print x, " " }
- *
- * produces:
- *
- * c b a
+ * array.reverse_each {|element| ... } -> self
+ * array.reverse_each -> Enumerator
+ *
+ * Iterates backwards over array elements.
+ *
+ * When a block given, passes, in reverse order, each element to the block;
+ * returns +self+:
+ * a = [:foo, 'bar', 2]
+ * a.reverse_each {|element| puts "#{element.class} #{element}" }
+ *
+ * Output:
+ * Integer 2
+ * String bar
+ * Symbol foo
+ *
+ * Allows the array to be modified during iteration:
+ * a = [:foo, 'bar', 2]
+ * a.reverse_each {|element| puts element; a.clear if element.to_s.start_with?('b') }
+ *
+ * Output:
+ * 2
+ * bar
+ *
+ * When no block given, returns a new \Enumerator:
+ * a = [:foo, 'bar', 2]
+ * e = a.reverse_each
+ * e # => #<Enumerator: [:foo, "bar", 2]:reverse_each>
+ * a1 = e.each {|element| puts "#{element.class} #{element}" }
+ * Output:
+ * Integer 2
+ * String bar
+ * Symbol foo
+ *
+ * Related: #each, #each_index.
*/
static VALUE
@@ -1894,12 +2634,9 @@ rb_ary_reverse_each(VALUE ary)
/*
* call-seq:
- * ary.length -> int
- *
- * Returns the number of elements in +self+. May be zero.
+ * array.length -> an_integer
*
- * [ 1, 2, 3, 4, 5 ].length #=> 5
- * [].length #=> 0
+ * Returns the count of elements in +self+.
*/
static VALUE
@@ -1911,11 +2648,10 @@ rb_ary_length(VALUE ary)
/*
* call-seq:
- * ary.empty? -> true or false
- *
- * Returns +true+ if +self+ contains no elements.
+ * array.empty? -> true or false
*
- * [].empty? #=> true
+ * Returns +true+ if the count of elements in +self+ is zero,
+ * +false+ otherwise.
*/
static VALUE
@@ -1931,15 +2667,18 @@ rb_ary_dup(VALUE ary)
{
long len = RARRAY_LEN(ary);
VALUE dup = rb_ary_new2(len);
- ary_memcpy(dup, 0, len, RARRAY_CONST_PTR(ary));
+ ary_memcpy(dup, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_LEN(dup, len);
+
+ ary_verify(ary);
+ ary_verify(dup);
return dup;
}
VALUE
rb_ary_resurrect(VALUE ary)
{
- return rb_ary_new4(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
+ return ary_make_partial(ary, rb_cArray, 0, RARRAY_LEN(ary));
}
extern VALUE rb_output_fs;
@@ -1964,7 +2703,7 @@ recursive_join(VALUE obj, VALUE argp, int recur)
return Qnil;
}
-static void
+static long
ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
{
long i;
@@ -1973,10 +2712,39 @@ ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
if (max > 0) rb_enc_copy(result, RARRAY_AREF(ary, 0));
for (i=0; i<max; i++) {
val = RARRAY_AREF(ary, i);
+ if (!RB_TYPE_P(val, T_STRING)) break;
if (i > 0 && !NIL_P(sep))
rb_str_buf_append(result, sep);
rb_str_buf_append(result, val);
- if (OBJ_TAINTED(val)) OBJ_TAINT(result);
+ }
+ return i;
+}
+
+static void
+ary_join_1_str(VALUE dst, VALUE src, int *first)
+{
+ rb_str_buf_append(dst, src);
+ if (*first) {
+ rb_enc_copy(dst, src);
+ *first = FALSE;
+ }
+}
+
+static void
+ary_join_1_ary(VALUE obj, VALUE ary, VALUE sep, VALUE result, VALUE val, int *first)
+{
+ if (val == ary) {
+ rb_raise(rb_eArgError, "recursive array join");
+ }
+ else {
+ VALUE args[4];
+
+ *first = FALSE;
+ args[0] = val;
+ args[1] = sep;
+ args[2] = result;
+ args[3] = (VALUE)first;
+ rb_exec_recursive(recursive_join, obj, (VALUE)args);
}
}
@@ -1991,44 +2759,19 @@ ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
val = RARRAY_AREF(ary, i);
if (RB_TYPE_P(val, T_STRING)) {
- str_join:
- rb_str_buf_append(result, val);
- if (*first) {
- rb_enc_copy(result, val);
- *first = FALSE;
- }
+ ary_join_1_str(result, val, first);
}
else if (RB_TYPE_P(val, T_ARRAY)) {
- obj = val;
- ary_join:
- if (val == ary) {
- rb_raise(rb_eArgError, "recursive array join");
- }
- else {
- VALUE args[4];
-
- *first = FALSE;
- args[0] = val;
- args[1] = sep;
- args[2] = result;
- args[3] = (VALUE)first;
- rb_exec_recursive(recursive_join, obj, (VALUE)args);
- }
+ ary_join_1_ary(val, ary, sep, result, val, first);
}
- else {
- tmp = rb_check_string_type(val);
- if (!NIL_P(tmp)) {
- val = tmp;
- goto str_join;
- }
- tmp = rb_check_array_type(val);
- if (!NIL_P(tmp)) {
- obj = val;
- val = tmp;
- goto ary_join;
- }
- val = rb_obj_as_string(val);
- goto str_join;
+ else if (!NIL_P(tmp = rb_check_string_type(val))) {
+ ary_join_1_str(result, tmp, first);
+ }
+ else if (!NIL_P(tmp = rb_check_array_type(val))) {
+ ary_join_1_ary(val, ary, sep, result, tmp, first);
+ }
+ else {
+ ary_join_1_str(result, rb_obj_as_string(val), first);
}
}
}
@@ -2037,11 +2780,9 @@ VALUE
rb_ary_join(VALUE ary, VALUE sep)
{
long len = 1, i;
- int taint = FALSE;
VALUE val, tmp, result;
if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0);
- if (OBJ_TAINTED(ary)) taint = TRUE;
if (!NIL_P(sep)) {
StringValue(sep);
@@ -2053,10 +2794,11 @@ rb_ary_join(VALUE ary, VALUE sep)
if (NIL_P(tmp) || tmp != val) {
int first;
- result = rb_str_buf_new(len + (RARRAY_LEN(ary)-i)*10);
+ long n = RARRAY_LEN(ary);
+ if (i > n) i = n;
+ result = rb_str_buf_new(len + (n-i)*10);
rb_enc_associate(result, rb_usascii_encoding());
- if (taint) OBJ_TAINT(result);
- ary_join_0(ary, sep, i, result);
+ i = ary_join_0(ary, sep, i, result);
first = i == 0;
ary_join_1(ary, ary, sep, i, result, &first);
return result;
@@ -2065,8 +2807,9 @@ rb_ary_join(VALUE ary, VALUE sep)
len += RSTRING_LEN(tmp);
}
- result = rb_str_buf_new(len);
- if (taint) OBJ_TAINT(result);
+ result = rb_str_new(0, len);
+ rb_str_set_len(result, 0);
+
ary_join_0(ary, sep, RARRAY_LEN(ary), result);
return result;
@@ -2074,29 +2817,38 @@ rb_ary_join(VALUE ary, VALUE sep)
/*
* call-seq:
- * ary.join(separator=$,) -> str
- *
- * Returns a string created by converting each element of the array to
- * a string, separated by the given +separator+.
- * If the +separator+ is +nil+, it uses current <code>$,</code>.
- * If both the +separator+ and <code>$,</code> are +nil+,
- * it uses an empty string.
- *
- * [ "a", "b", "c" ].join #=> "abc"
- * [ "a", "b", "c" ].join("-") #=> "a-b-c"
- *
- * For nested arrays, join is applied recursively:
- *
- * [ "a", [1, 2, [:x, :y]], "b" ].join("-") #=> "a-1-2-x-y-b"
+ * array.join ->new_string
+ * array.join(separator = $,) -> new_string
+ *
+ * Returns the new \String formed by joining the array elements after conversion.
+ * For each element +element+
+ * - Uses <tt>element.to_s</tt> if +element+ is not a <tt>kind_of?(Array)</tt>.
+ * - Uses recursive <tt>element.join(separator)</tt> if +element+ is a <tt>kind_of?(Array)</tt>.
+ *
+ * With no argument, joins using the output field separator, <tt>$,</tt>:
+ * a = [:foo, 'bar', 2]
+ * $, # => nil
+ * a.join # => "foobar2"
+ *
+ * With \string argument +separator+, joins using that separator:
+ * a = [:foo, 'bar', 2]
+ * a.join("\n") # => "foo\nbar\n2"
+ *
+ * Joins recursively for nested Arrays:
+ * a = [:foo, [:bar, [:baz, :bat]]]
+ * a.join # => "foobarbazbat"
*/
-
static VALUE
rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
{
VALUE sep;
- rb_scan_args(argc, argv, "01", &sep);
- if (NIL_P(sep)) sep = rb_output_fs;
+ if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {
+ sep = rb_output_fs;
+ if (!NIL_P(sep)) {
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
+ }
+ }
return rb_ary_join(ary, sep);
}
@@ -2104,7 +2856,6 @@ rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
static VALUE
inspect_ary(VALUE ary, VALUE dummy, int recur)
{
- int tainted = OBJ_TAINTED(ary);
long i;
VALUE s, str;
@@ -2112,24 +2863,24 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
str = rb_str_buf_new2("[");
for (i=0; i<RARRAY_LEN(ary); i++) {
s = rb_inspect(RARRAY_AREF(ary, i));
- if (OBJ_TAINTED(s)) tainted = TRUE;
if (i > 0) rb_str_buf_cat2(str, ", ");
else rb_enc_copy(str, s);
rb_str_buf_append(str, s);
}
rb_str_buf_cat2(str, "]");
- if (tainted) OBJ_TAINT(str);
return str;
}
/*
* call-seq:
- * ary.inspect -> string
- * ary.to_s -> string
+ * array.inspect -> new_string
*
- * Creates a string representation of +self+.
+ * Returns the new \String formed by calling method <tt>#inspect</tt>
+ * on each array element:
+ * a = [:foo, 'bar', 2]
+ * a.inspect # => "[:foo, \"bar\", 2]"
*
- * [ "a", "b", "c" ].to_s #=> "[\"a\", \"b\", \"c\"]"
+ * Array#to_s is an alias for Array#inspect.
*/
static VALUE
@@ -2147,11 +2898,20 @@ rb_ary_to_s(VALUE ary)
/*
* call-seq:
- * ary.to_a -> ary
- *
- * Returns +self+.
- *
- * If called on a subclass of Array, converts the receiver to an Array object.
+ * to_a -> self or new_array
+ *
+ * When +self+ is an instance of \Array, returns +self+:
+ * a = [:foo, 'bar', 2]
+ * a.to_a # => [:foo, "bar", 2]
+ *
+ * Otherwise, returns a new \Array containing the elements of +self+:
+ * class MyArray < Array; end
+ * a = MyArray.new(['foo', 'bar', 'two'])
+ * a.instance_of?(Array) # => false
+ * a.kind_of?(Array) # => true
+ * a1 = a.to_a
+ * a1 # => ["foo", "bar", "two"]
+ * a1.class # => Array # Not MyArray
*/
static VALUE
@@ -2167,13 +2927,24 @@ rb_ary_to_a(VALUE ary)
/*
* call-seq:
- * ary.to_h -> hash
- *
- * Returns the result of interpreting <i>ary</i> as an array of
- * <tt>[key, value]</tt> pairs.
- *
- * [[:foo, :bar], [1, 2]].to_h
- * # => {:foo => :bar, 1 => 2}
+ * array.to_h -> new_hash
+ * array.to_h {|item| ... } -> new_hash
+ *
+ * Returns a new \Hash formed from +self+.
+ *
+ * When a block is given, calls the block with each array element;
+ * the block must return a 2-element \Array whose two elements
+ * form a key-value pair in the returned \Hash:
+ * a = ['foo', :bar, 1, [2, 3], {baz: 4}]
+ * h = a.to_h {|item| [item, item] }
+ * h # => {"foo"=>"foo", :bar=>:bar, 1=>1, [2, 3]=>[2, 3], {:baz=>4}=>{:baz=>4}}
+ *
+ * When no block is given, +self+ must be an \Array of 2-element sub-arrays,
+ * each sub-array is formed into a key-value pair in the new \Hash:
+ * [].to_h # => {}
+ * a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']]
+ * h = a.to_h
+ * h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}
*/
static VALUE
@@ -2181,8 +2952,11 @@ rb_ary_to_h(VALUE ary)
{
long i;
VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary));
+ int block_given = rb_block_given_p();
+
for (i=0; i<RARRAY_LEN(ary); i++) {
- const VALUE elt = rb_ary_elt(ary, i);
+ const VALUE e = rb_ary_elt(ary, i);
+ const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
const VALUE key_value_pair = rb_check_array_type(elt);
if (NIL_P(key_value_pair)) {
rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",
@@ -2199,7 +2973,7 @@ rb_ary_to_h(VALUE ary)
/*
* call-seq:
- * ary.to_ary -> ary
+ * array.to_ary -> self
*
* Returns +self+.
*/
@@ -2228,9 +3002,9 @@ rb_ary_reverse(VALUE ary)
rb_ary_modify(ary);
if (len > 1) {
- RARRAY_PTR_USE(ary, p1, {
- p2 = p1 + len - 1; /* points last item */
- ary_reverse(p1, p2);
+ RARRAY_PTR_USE_TRANSIENT(ary, p1, {
+ p2 = p1 + len - 1; /* points last item */
+ ary_reverse(p1, p2);
}); /* WB: no new reference */
}
return ary;
@@ -2238,13 +3012,11 @@ rb_ary_reverse(VALUE ary)
/*
* call-seq:
- * ary.reverse! -> ary
- *
- * Reverses +self+ in place.
+ * array.reverse! -> self
*
- * a = [ "a", "b", "c" ]
- * a.reverse! #=> ["c", "b", "a"]
- * a #=> ["c", "b", "a"]
+ * Reverses +self+ in place:
+ * a = ['foo', 'bar', 'two']
+ * a.reverse! # => ["two", "bar", "foo"]
*/
static VALUE
@@ -2255,12 +3027,12 @@ rb_ary_reverse_bang(VALUE ary)
/*
* call-seq:
- * ary.reverse -> new_ary
+ * array.reverse -> new_array
*
- * Returns a new array containing +self+'s elements in reverse order.
- *
- * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"]
- * [ 1 ].reverse #=> [1]
+ * Returns a new \Array with the elements of +self+ in reverse order.
+ * a = ['foo', 'bar', 'two']
+ * a1 = a.reverse
+ * a1 # => ["two", "bar", "foo"]
*/
static VALUE
@@ -2270,8 +3042,8 @@ rb_ary_reverse_m(VALUE ary)
VALUE dup = rb_ary_new2(len);
if (len > 0) {
- const VALUE *p1 = RARRAY_CONST_PTR(ary);
- VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
+ const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
+ VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
@@ -2284,73 +3056,127 @@ rotate_count(long cnt, long len)
return (cnt < 0) ? (len - (~cnt % len) - 1) : (cnt % len);
}
+static void
+ary_rotate_ptr(VALUE *ptr, long len, long cnt)
+{
+ if (cnt == 1) {
+ VALUE tmp = *ptr;
+ memmove(ptr, ptr + 1, sizeof(VALUE)*(len - 1));
+ *(ptr + len - 1) = tmp;
+ } else if (cnt == len - 1) {
+ VALUE tmp = *(ptr + len - 1);
+ memmove(ptr + 1, ptr, sizeof(VALUE)*(len - 1));
+ *ptr = tmp;
+ } else {
+ --len;
+ if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
+ if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
+ if (len > 0) ary_reverse(ptr, ptr + len);
+ }
+}
+
VALUE
rb_ary_rotate(VALUE ary, long cnt)
{
rb_ary_modify(ary);
if (cnt != 0) {
- VALUE *ptr = RARRAY_PTR(ary);
- long len = RARRAY_LEN(ary);
-
- if (len > 0 && (cnt = rotate_count(cnt, len)) > 0) {
- --len;
- if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
- if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
- if (len > 0) ary_reverse(ptr, ptr + len);
- return ary;
- }
+ long len = RARRAY_LEN(ary);
+ if (len > 1 && (cnt = rotate_count(cnt, len)) > 0) {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
+ return ary;
+ }
}
-
return Qnil;
}
/*
* call-seq:
- * ary.rotate!(count=1) -> ary
- *
- * Rotates +self+ in place so that the element at +count+ comes first, and
- * returns +self+.
- *
- * If +count+ is negative then it rotates in the opposite direction, starting
- * from the end of the array where +-1+ is the last element.
- *
- * a = [ "a", "b", "c", "d" ]
- * a.rotate! #=> ["b", "c", "d", "a"]
- * a #=> ["b", "c", "d", "a"]
- * a.rotate!(2) #=> ["d", "a", "b", "c"]
- * a.rotate!(-3) #=> ["a", "b", "c", "d"]
+ * array.rotate! -> self
+ * array.rotate!(count) -> self
+ *
+ * Rotates +self+ in place by moving elements from one end to the other; returns +self+.
+ *
+ * When no argument given, rotates the first element to the last position:
+ * a = [:foo, 'bar', 2, 'bar']
+ * a.rotate! # => ["bar", 2, "bar", :foo]
+ *
+ * When given a non-negative \Integer +count+,
+ * rotates +count+ elements from the beginning to the end:
+ * a = [:foo, 'bar', 2]
+ * a.rotate!(2)
+ * a # => [2, :foo, "bar"]
+ *
+ * If +count+ is large, uses <tt>count % array.size</tt> as the count:
+ * a = [:foo, 'bar', 2]
+ * a.rotate!(20)
+ * a # => [2, :foo, "bar"]
+ *
+ * If +count+ is zero, returns +self+ unmodified:
+ * a = [:foo, 'bar', 2]
+ * a.rotate!(0)
+ * a # => [:foo, "bar", 2]
+ *
+ * When given a negative Integer +count+, rotates in the opposite direction,
+ * from end to beginning:
+ * a = [:foo, 'bar', 2]
+ * a.rotate!(-2)
+ * a # => ["bar", 2, :foo]
+ *
+ * If +count+ is small (far from zero), uses <tt>count % array.size</tt> as the count:
+ * a = [:foo, 'bar', 2]
+ * a.rotate!(-5)
+ * a # => ["bar", 2, :foo]
*/
static VALUE
rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
{
- long n = 1;
-
- switch (argc) {
- case 1: n = NUM2LONG(argv[0]);
- case 0: break;
- default: rb_scan_args(argc, argv, "01", NULL);
- }
+ long n = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
rb_ary_rotate(ary, n);
return ary;
}
/*
* call-seq:
- * ary.rotate(count=1) -> new_ary
- *
- * Returns a new array by rotating +self+ so that the element at +count+ is
- * the first element of the new array.
- *
- * If +count+ is negative then it rotates in the opposite direction, starting
- * from the end of +self+ where +-1+ is the last element.
- *
- * a = [ "a", "b", "c", "d" ]
- * a.rotate #=> ["b", "c", "d", "a"]
- * a #=> ["a", "b", "c", "d"]
- * a.rotate(2) #=> ["c", "d", "a", "b"]
- * a.rotate(-3) #=> ["b", "c", "d", "a"]
+ * array.rotate -> new_array
+ * array.rotate(count) -> new_array
+ *
+ * Returns a new \Array formed from +self+ with elements
+ * rotated from one end to the other.
+ *
+ * When no argument given, returns a new \Array that is like +self+,
+ * except that the first element has been rotated to the last position:
+ * a = [:foo, 'bar', 2, 'bar']
+ * a1 = a.rotate
+ * a1 # => ["bar", 2, "bar", :foo]
+ *
+ * When given a non-negative \Integer +count+,
+ * returns a new \Array with +count+ elements rotated from the beginning to the end:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.rotate(2)
+ * a1 # => [2, :foo, "bar"]
+ *
+ * If +count+ is large, uses <tt>count % array.size</tt> as the count:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.rotate(20)
+ * a1 # => [2, :foo, "bar"]
+ *
+ * If +count+ is zero, returns a copy of +self+, unmodified:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.rotate(0)
+ * a1 # => [:foo, "bar", 2]
+ *
+ * When given a negative \Integer +count+, rotates in the opposite direction,
+ * from end to beginning:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.rotate(-2)
+ * a1 # => ["bar", 2, :foo]
+ *
+ * If +count+ is small (far from zero), uses <tt>count % array.size</tt> as the count:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.rotate(-5)
+ * a1 # => ["bar", 2, :foo]
*/
static VALUE
@@ -2358,19 +3184,14 @@ rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
{
VALUE rotated;
const VALUE *ptr;
- long len, cnt = 1;
-
- switch (argc) {
- case 1: cnt = NUM2LONG(argv[0]);
- case 0: break;
- default: rb_scan_args(argc, argv, "01", NULL);
- }
+ long len;
+ long cnt = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
len = RARRAY_LEN(ary);
rotated = rb_ary_new2(len);
if (len > 0) {
cnt = rotate_count(cnt, len);
- ptr = RARRAY_CONST_PTR(ary);
+ ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
len -= cnt;
ary_memcpy(rotated, 0, len, ptr + cnt);
ary_memcpy(rotated, len, cnt, ptr);
@@ -2418,7 +3239,7 @@ sort_2(const void *ap, const void *bp, void *dummy)
VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
int n;
- if (FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, Fixnum)) {
+ if (FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, Integer)) {
if ((long)a > (long)b) return 1;
if ((long)a < (long)b) return -1;
return 0;
@@ -2439,26 +3260,38 @@ sort_2(const void *ap, const void *bp, void *dummy)
/*
* call-seq:
- * ary.sort! -> ary
- * ary.sort! { |a, b| block } -> ary
- *
- * Sorts +self+ in place.
- *
- * Comparisons for the sort will be done using the <code><=></code> operator
- * or using an optional code block.
- *
- * The block must implement a comparison between +a+ and +b+ and return
- * an integer less than 0 when +b+ follows +a+, +0+ when +a+ and +b+
- * are equivalent, or an integer greater than 0 when +a+ follows +b+.
- *
- * The result is not guaranteed to be stable. When the comparison of two
- * elements returns +0+, the order of the elements is unpredictable.
- *
- * ary = [ "d", "a", "e", "c", "b" ]
- * ary.sort! #=> ["a", "b", "c", "d", "e"]
- * ary.sort! { |a, b| b <=> a } #=> ["e", "d", "c", "b", "a"]
- *
- * See also Enumerable#sort_by.
+ * array.sort! -> self
+ * array.sort! {|a, b| ... } -> self
+ *
+ * Returns +self+ with its elements sorted in place.
+ *
+ * With no block, compares elements using operator <tt><=></tt>
+ * (see Comparable):
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a.sort!
+ * a # => ["a", "b", "c", "d", "e"]
+ *
+ * With a block, calls the block with each element pair;
+ * for each element pair +a+ and +b+, the block should return an integer:
+ * - Negative when +b+ is to follow +a+.
+ * - Zero when +a+ and +b+ are equivalent.
+ * - Positive when +a+ is to follow +b+.
+ *
+ * Example:
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a.sort! {|a, b| a <=> b }
+ * a # => ["a", "b", "c", "d", "e"]
+ * a.sort! {|a, b| b <=> a }
+ * a # => ["e", "d", "c", "b", "a"]
+ *
+ * When the block returns zero, the order for +a+ and +b+ is indeterminate,
+ * and may be unstable:
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a.sort! {|a, b| 0 }
+ * a # => ["d", "e", "c", "a", "b"]
*/
VALUE
@@ -2470,14 +3303,13 @@ rb_ary_sort_bang(VALUE ary)
VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
struct ary_sort_data data;
long len = RARRAY_LEN(ary);
-
RBASIC_CLEAR_CLASS(tmp);
data.ary = tmp;
data.cmp_opt.opt_methods = 0;
data.cmp_opt.opt_inited = 0;
RARRAY_PTR_USE(tmp, ptr, {
- ruby_qsort(ptr, len, sizeof(VALUE),
- rb_block_given_p()?sort_1:sort_2, &data);
+ ruby_qsort(ptr, len, sizeof(VALUE),
+ rb_block_given_p()?sort_1:sort_2, &data);
}); /* WB: no new reference */
rb_ary_modify(ary);
if (ARY_EMBED_P(tmp)) {
@@ -2503,46 +3335,61 @@ rb_ary_sort_bang(VALUE ary)
rb_ary_unshare(ary);
}
else {
- ruby_sized_xfree((void *)ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
+ ary_heap_free(ary);
}
- ARY_SET_PTR(ary, RARRAY_CONST_PTR(tmp));
+ ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
ARY_SET_HEAP_LEN(ary, len);
- ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
+ ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
}
/* tmp was lost ownership for the ptr */
FL_UNSET(tmp, FL_FREEZE);
FL_SET_EMBED(tmp);
ARY_SET_EMBED_LEN(tmp, 0);
FL_SET(tmp, FL_FREEZE);
- }
+ }
/* tmp will be GC'ed. */
RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
}
+ ary_verify(ary);
return ary;
}
/*
* call-seq:
- * ary.sort -> new_ary
- * ary.sort { |a, b| block } -> new_ary
- *
- * Returns a new array created by sorting +self+.
- *
- * Comparisons for the sort will be done using the <code><=></code> operator
- * or using an optional code block.
- *
- * The block must implement a comparison between +a+ and +b+ and return
- * an integer less than 0 when +b+ follows +a+, +0+ when +a+ and +b+
- * are equivalent, or an integer greater than 0 when +a+ follows +b+.
- *
- * The result is not guaranteed to be stable. When the comparison of two
- * elements returns +0+, the order of the elements is unpredictable.
- *
- * ary = [ "d", "a", "e", "c", "b" ]
- * ary.sort #=> ["a", "b", "c", "d", "e"]
- * ary.sort { |a, b| b <=> a } #=> ["e", "d", "c", "b", "a"]
- *
- * See also Enumerable#sort_by.
+ * array.sort -> new_array
+ * array.sort {|a, b| ... } -> new_array
+ *
+ * Returns a new \Array whose elements are those from +self+, sorted.
+ *
+ * With no block, compares elements using operator <tt><=></tt>
+ * (see Comparable):
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a1 = a.sort
+ * a1 # => ["a", "b", "c", "d", "e"]
+ *
+ * With a block, calls the block with each element pair;
+ * for each element pair +a+ and +b+, the block should return an integer:
+ * - Negative when +b+ is to follow +a+.
+ * - Zero when +a+ and +b+ are equivalent.
+ * - Positive when +a+ is to follow +b+.
+ *
+ * Example:
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a1 = a.sort {|a, b| a <=> b }
+ * a1 # => ["a", "b", "c", "d", "e"]
+ * a2 = a.sort {|a, b| b <=> a }
+ * a2 # => ["e", "d", "c", "b", "a"]
+ *
+ * When the block returns zero, the order for +a+ and +b+ is indeterminate,
+ * and may be unstable:
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a1 = a.sort {|a, b| 0 }
+ * a1 # => ["c", "e", "b", "d", "a"]
+ *
+ * Related: Enumerable#sort_by.
*/
VALUE
@@ -2557,55 +3404,93 @@ static VALUE rb_ary_bsearch_index(VALUE ary);
/*
* call-seq:
- * ary.bsearch {|x| block } -> elem
+ * array.bsearch {|element| ... } -> object
+ * array.bsearch -> new_enumerator
+ *
+ * Returns an element from +self+ selected by a binary search.
+ * +self+ should be sorted, but this is not checked.
*
* By using binary search, finds a value from this array which meets
- * the given condition in O(log n) where n is the size of the array.
- *
- * You can use this method in two modes: a find-minimum mode and
- * a find-any mode. In either case, the elements of the array must be
- * monotone (or sorted) with respect to the block.
- *
- * In find-minimum mode (this is a good choice for typical use cases),
- * the block must always return true or false, and there must be an index i
- * (0 <= i <= ary.size) so that:
- *
- * - the block returns false for any element whose index is less than
- * i, and
- * - the block returns true for any element whose index is greater
- * than or equal to i.
- *
- * This method returns the i-th element. If i is equal to ary.size,
- * it returns nil.
- *
- * ary = [0, 4, 7, 10, 12]
- * ary.bsearch {|x| x >= 4 } #=> 4
- * ary.bsearch {|x| x >= 6 } #=> 7
- * ary.bsearch {|x| x >= -1 } #=> 0
- * ary.bsearch {|x| x >= 100 } #=> nil
- *
- * In find-any mode (this behaves like libc's bsearch(3)), the block
- * must always return a number, and there must be two indices i and j
- * (0 <= i <= j <= ary.size) so that:
- *
- * - the block returns a positive number for ary[k] if 0 <= k < i,
- * - the block returns zero for ary[k] if i <= k < j, and
- * - the block returns a negative number for ary[k] if
- * j <= k < ary.size.
- *
- * Under this condition, this method returns any element whose index
- * is within i...j. If i is equal to j (i.e., there is no element
- * that satisfies the block), this method returns nil.
- *
- * ary = [0, 4, 7, 10, 12]
- * # try to find v such that 4 <= v < 8
- * ary.bsearch {|x| 1 - x / 4 } #=> 4 or 7
- * # try to find v such that 8 <= v < 10
- * ary.bsearch {|x| 4 - x / 2 } #=> nil
- *
- * You must not mix the two modes at a time; the block must always
- * return either true/false, or always return a number. It is
- * undefined which value is actually picked up at each iteration.
+ * the given condition in <tt>O(log n)</tt> where +n+ is the size of the array.
+ *
+ * There are two search modes:
+ * - <b>Find-minimum mode</b>: the block should return +true+ or +false+.
+ * - <b>Find-any mode</b>: the block should return a numeric value.
+ *
+ * The block should not mix the modes by and sometimes returning +true+ or +false+
+ * and sometimes returning a numeric value, but this is not checked.
+ *
+ * <b>Find-Minimum Mode</b>
+ *
+ * In find-minimum mode, the block always returns +true+ or +false+.
+ * The further requirement (though not checked) is that
+ * there are no indexes +i+ and +j+ such that:
+ * - <tt>0 <= i < j <= self.size</tt>.
+ * - The block returns +true+ for <tt>self[i]</tt> and +false+ for <tt>self[j]</tt>.
+ *
+ * In find-minimum mode, method bsearch returns the first element for which the block returns true.
+ *
+ * Examples:
+ * a = [0, 4, 7, 10, 12]
+ * a.bsearch {|x| x >= 4 } # => 4
+ * a.bsearch {|x| x >= 6 } # => 7
+ * a.bsearch {|x| x >= -1 } # => 0
+ * a.bsearch {|x| x >= 100 } # => nil
+ *
+ * Less formally: the block is such that all +false+-evaluating elements
+ * precede all +true+-evaluating elements.
+ *
+ * These make sense as blocks in find-minimum mode:
+ * a = [0, 4, 7, 10, 12]
+ * a.map {|x| x >= 4 } # => [false, true, true, true, true]
+ * a.map {|x| x >= 6 } # => [false, false, true, true, true]
+ * a.map {|x| x >= -1 } # => [true, true, true, true, true]
+ * a.map {|x| x >= 100 } # => [false, false, false, false, false]
+ *
+ * This would not make sense:
+ * a = [0, 4, 7, 10, 12]
+ * a.map {|x| x == 7 } # => [false, false, true, false, false]
+ *
+ * <b>Find-Any Mode</b>
+ *
+ * In find-any mode, the block always returns a numeric value.
+ * The further requirement (though not checked) is that
+ * there are no indexes +i+ and +j+ such that:
+ * - <tt>0 <= i < j <= self.size</tt>.
+ * - The block returns a negative value for <tt>self[i]</tt>
+ * and a positive value for <tt>self[j]</tt>.
+ * - The block returns a negative value for <tt>self[i]</tt> and zero <tt>self[j]</tt>.
+ * - The block returns zero for <tt>self[i]</tt> and a positive value for <tt>self[j]</tt>.
+ *
+ * In find-any mode, method bsearch returns some element
+ * for which the block returns zero, or +nil+ if no such element is found.
+ *
+ * Examples:
+ * a = [0, 4, 7, 10, 12]
+ * a.bsearch {|element| 7 <=> element } # => 7
+ * a.bsearch {|element| -1 <=> element } # => nil
+ * a.bsearch {|element| 5 <=> element } # => nil
+ * a.bsearch {|element| 15 <=> element } # => nil
+ *
+ * Less formally: the block is such that:
+ * - All positive-evaluating elements precede all zero-evaluating elements.
+ * - All positive-evaluating elements precede all negative-evaluating elements.
+ * - All zero-evaluating elements precede all negative-evaluating elements.
+ *
+ * These make sense as blocks in find-any mode:
+ * a = [0, 4, 7, 10, 12]
+ * a.map {|element| 7 <=> element } # => [1, 1, 0, -1, -1]
+ * a.map {|element| -1 <=> element } # => [-1, -1, -1, -1, -1]
+ * a.map {|element| 5 <=> element } # => [1, 1, -1, -1, -1]
+ * a.map {|element| 15 <=> element } # => [1, 1, 1, 1, 1]
+ *
+ * This would not make sense:
+ * a = [0, 4, 7, 10, 12]
+ * a.map {|element| element <=> 7 } # => [-1, -1, 0, 1, 1]
+ *
+ * Returns an enumerator if no block given:
+ * a = [0, 4, 7, 10, 12]
+ * a.bsearch # => #<Enumerator: [0, 4, 7, 10, 12]:bsearch>
*/
static VALUE
@@ -2621,15 +3506,11 @@ rb_ary_bsearch(VALUE ary)
/*
* call-seq:
- * ary.bsearch_index {|x| block } -> int or nil
- *
- * By using binary search, finds an index of a value from this array which
- * meets the given condition in O(log n) where n is the size of the array.
+ * array.bsearch_index {|element| ... } -> integer or nil
+ * array.bsearch_index -> new_enumerator
*
- * It supports two modes, depending on the nature of the block. They are
- * exactly the same as in the case of the #bsearch method, with the only difference
- * being that this method returns the index of the element instead of the
- * element itself. For more details consult the documentation for #bsearch.
+ * Searches +self+ as described at method #bsearch,
+ * but returns the _index_ of the found element instead of the element itself.
*/
static VALUE
@@ -2688,18 +3569,26 @@ sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
/*
* call-seq:
- * ary.sort_by! { |obj| block } -> ary
- * ary.sort_by! -> Enumerator
+ * array.sort_by! {|element| ... } -> self
+ * array.sort_by! -> new_enumerator
+ *
+ * Sorts the elements of +self+ in place,
+ * using an ordering determined by the block; returns self.
*
- * Sorts +self+ in place using a set of keys generated by mapping the
- * values in +self+ through the given block.
+ * Calls the block with each successive element;
+ * sorts elements based on the values returned from the block.
*
- * The result is not guaranteed to be stable. When two keys are equal,
- * the order of the corresponding elements is unpredictable.
+ * For duplicates returned by the block, the ordering is indeterminate, and may be unstable.
*
- * If no block is given, an Enumerator is returned instead.
+ * This example sorts strings based on their sizes:
+ * a = ['aaaa', 'bbb', 'cc', 'd']
+ * a.sort_by! {|element| element.size }
+ * a # => ["d", "cc", "bbb", "aaaa"]
*
- * See also Enumerable#sort_by.
+ * Returns a new \Enumerator if no block given:
+ *
+ * a = ['aaaa', 'bbb', 'cc', 'd']
+ * a.sort_by! # => #<Enumerator: ["aaaa", "bbb", "cc", "d"]:sort_by!>
*/
static VALUE
@@ -2717,23 +3606,21 @@ rb_ary_sort_by_bang(VALUE ary)
/*
* call-seq:
- * ary.collect { |item| block } -> new_ary
- * ary.map { |item| block } -> new_ary
- * ary.collect -> Enumerator
- * ary.map -> Enumerator
- *
- * Invokes the given block once for each element of +self+.
+ * array.map {|element| ... } -> new_array
+ * array.map -> new_enumerator
*
- * Creates a new array containing the values returned by the block.
+ * Calls the block, if given, with each element of +self+;
+ * returns a new \Array whose elements are the return values from the block:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.map {|element| element.class }
+ * a1 # => [Symbol, String, Integer]
*
- * See also Enumerable#collect.
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.map
+ * a1 # => #<Enumerator: [:foo, "bar", 2]:map>
*
- * If no block is given, an Enumerator is returned instead.
- *
- * a = [ "a", "b", "c", "d" ]
- * a.collect { |x| x + "!" } #=> ["a!", "b!", "c!", "d!"]
- * a.map.with_index { |x, i| x * i } #=> ["", "b", "cc", "ddd"]
- * a #=> ["a", "b", "c", "d"]
+ * Array#collect is an alias for Array#map.
*/
static VALUE
@@ -2745,7 +3632,7 @@ rb_ary_collect(VALUE ary)
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
collect = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
- rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
+ rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
}
return collect;
}
@@ -2753,23 +3640,20 @@ rb_ary_collect(VALUE ary)
/*
* call-seq:
- * ary.collect! {|item| block } -> ary
- * ary.map! {|item| block } -> ary
- * ary.collect! -> Enumerator
- * ary.map! -> Enumerator
- *
- * Invokes the given block once for each element of +self+, replacing the
- * element with the value returned by the block.
+ * array.map! {|element| ... } -> self
+ * array.map! -> new_enumerator
*
- * See also Enumerable#collect.
+ * Calls the block, if given, with each element;
+ * replaces the element with the block's return value:
+ * a = [:foo, 'bar', 2]
+ * a.map! { |element| element.class } # => [Symbol, String, Integer]
*
- * If no block is given, an Enumerator is returned instead.
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.map!
+ * a1 # => #<Enumerator: [:foo, "bar", 2]:map!>
*
- * a = [ "a", "b", "c", "d" ]
- * a.map! {|x| x + "!" }
- * a #=> [ "a!", "b!", "c!", "d!" ]
- * a.collect!.with_index {|x, i| x[0...i] }
- * a #=> ["", "b", "c!", "d!"]
+ * Array#collect! is an alias for Array#map!.
*/
static VALUE
@@ -2811,47 +3695,98 @@ rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func
return result;
}
+static VALUE
+append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
+{
+ long beg, len;
+ if (FIXNUM_P(idx)) {
+ beg = FIX2LONG(idx);
+ }
+ /* check if idx is Range */
+ else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) {
+ if (len > 0) {
+ const VALUE *const src = RARRAY_CONST_PTR_TRANSIENT(ary);
+ const long end = beg + len;
+ const long prevlen = RARRAY_LEN(result);
+ if (beg < olen) {
+ rb_ary_cat(result, src + beg, end > olen ? olen-beg : len);
+ }
+ if (end > olen) {
+ rb_ary_store(result, prevlen + len - 1, Qnil);
+ }
+ }
+ return result;
+ }
+ else {
+ beg = NUM2LONG(idx);
+ }
+ return rb_ary_push(result, rb_ary_entry(ary, beg));
+}
+
/*
* call-seq:
- * ary.values_at(selector, ...) -> new_ary
+ * array.values_at(*indexes) -> new_array
+ *
+ * Returns a new \Array whose elements are the elements
+ * of +self+ at the given \Integer +indexes+.
+ *
+ * For each positive +index+, returns the element at offset +index+:
+ * a = [:foo, 'bar', 2]
+ * a.values_at(0, 2) # => [:foo, 2]
*
- * Returns an array containing the elements in +self+ corresponding to the
- * given +selector+(s).
+ * The given +indexes+ may be in any order, and may repeat:
+ * a = [:foo, 'bar', 2]
+ * a.values_at(2, 0, 1, 0, 2) # => [2, :foo, "bar", :foo, 2]
*
- * The selectors may be either integer indices or ranges.
+ * Assigns +nil+ for an +index+ that is too large:
+ * a = [:foo, 'bar', 2]
+ * a.values_at(0, 3, 1, 3) # => [:foo, nil, "bar", nil]
*
- * See also Array#select.
+ * Returns a new empty \Array if no arguments given.
*
- * a = %w{ a b c d e f }
- * a.values_at(1, 3, 5) # => ["b", "d", "f"]
- * a.values_at(1, 3, 5, 7) # => ["b", "d", "f", nil]
- * a.values_at(-1, -2, -2, -7) # => ["f", "e", "e", nil]
- * a.values_at(4..6, 3...6) # => ["e", "f", nil, "d", "e", "f"]
+ * For each negative +index+, counts backward from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a.values_at(-1, -3) # => [2, :foo]
+ *
+ * Assigns +nil+ for an +index+ that is too small:
+ * a = [:foo, 'bar', 2]
+ * a.values_at(0, -5, 1, -6, 2) # => [:foo, nil, "bar", nil, 2]
+ *
+ * The given +indexes+ may have a mixture of signs:
+ * a = [:foo, 'bar', 2]
+ * a.values_at(0, -2, 1, -1) # => [:foo, "bar", "bar", 2]
*/
static VALUE
rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
{
- return rb_get_values_at(ary, RARRAY_LEN(ary), argc, argv, rb_ary_entry);
+ long i, olen = RARRAY_LEN(ary);
+ VALUE result = rb_ary_new_capa(argc);
+ for (i = 0; i < argc; ++i) {
+ append_values_at_single(result, ary, olen, argv[i]);
+ }
+ RB_GC_GUARD(ary);
+ return result;
}
/*
* call-seq:
- * ary.select { |item| block } -> new_ary
- * ary.select -> Enumerator
+ * array.select {|element| ... } -> new_array
+ * array.select -> new_enumerator
*
- * Returns a new array containing all elements of +ary+
- * for which the given +block+ returns a true value.
+ * Calls the block, if given, with each element of +self+;
+ * returns a new \Array containing those elements of +self+
+ * for which the block returns a truthy value:
+ * a = [:foo, 'bar', 2, :bam]
+ * a1 = a.select {|element| element.to_s.start_with?('b') }
+ * a1 # => ["bar", :bam]
*
- * If no block is given, an Enumerator is returned instead.
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2, :bam]
+ * a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>
*
- * [1,2,3,4,5].select { |num| num.even? } #=> [2, 4]
- *
- * a = %w{ a b c d e f }
- * a.select { |v| v =~ /[aeiou]/ } #=> ["a", "e"]
- *
- * See also Enumerable#select.
+ * Array#filter is an alias for Array#select.
*/
static VALUE
@@ -2903,9 +3838,10 @@ select_bang_ensure(VALUE a)
if (i2 < len && i2 < i1) {
long tail = 0;
+ rb_ary_modify(ary);
if (i1 < len) {
tail = len - i1;
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
});
}
@@ -2916,20 +3852,23 @@ select_bang_ensure(VALUE a)
/*
* call-seq:
- * ary.select! {|item| block } -> ary or nil
- * ary.select! -> Enumerator
+ * array.select! {|element| ... } -> self or nil
+ * array.select! -> new_enumerator
*
- * Invokes the given block passing in successive elements from +self+,
- * deleting elements for which the block returns a +false+ value.
+ * Calls the block, if given with each element of +self+;
+ * removes from +self+ those elements for which the block returns +false+ or +nil+.
*
- * The array may not be changed instantly every time the block is called.
+ * Returns +self+ if any elements were removed:
+ * a = [:foo, 'bar', 2, :bam]
+ * a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
*
- * If changes were made, it will return +self+, otherwise it returns +nil+.
+ * Returns +nil+ if no elements were removed.
*
- * See also Array#keep_if
- *
- * If no block is given, an Enumerator is returned instead.
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2, :bam]
+ * a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>
*
+ * Array#filter! is an alias for Array#select!.
*/
static VALUE
@@ -2947,18 +3886,17 @@ rb_ary_select_bang(VALUE ary)
/*
* call-seq:
- * ary.keep_if { |item| block } -> ary
- * ary.keep_if -> Enumerator
- *
- * Deletes every element of +self+ for which the given block evaluates to
- * +false+.
+ * array.keep_if {|element| ... } -> self
+ * array.keep_if -> new_enumeration
*
- * See also Array#select!
+ * Retains those elements for which the block returns a truthy value;
+ * deletes all other elements; returns +self+:
+ * a = [:foo, 'bar', 2, :bam]
+ * a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
*
- * If no block is given, an Enumerator is returned instead.
- *
- * a = %w{ a b c d e f }
- * a.keep_if { |v| v =~ /[aeiou]/ } #=> ["a", "e"]
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2, :bam]
+ * a.keep_if # => #<Enumerator: [:foo, "bar", 2, :bam]:keep_if>
*/
static VALUE
@@ -2984,22 +3922,34 @@ ary_resize_smaller(VALUE ary, long len)
/*
* call-seq:
- * ary.delete(obj) -> item or nil
- * ary.delete(obj) { block } -> item or result of block
- *
- * Deletes all items from +self+ that are equal to +obj+.
- *
- * Returns the last deleted item, or +nil+ if no matching item is found.
- *
- * If the optional code block is given, the result of the block is returned if
- * the item is not found. (To remove +nil+ elements and get an informative
- * return value, use Array#compact!)
- *
- * a = [ "a", "b", "b", "b", "c" ]
- * a.delete("b") #=> "b"
- * a #=> ["a", "c"]
- * a.delete("z") #=> nil
- * a.delete("z") { "not found" } #=> "not found"
+ * array.delete(obj) -> deleted_object
+ * array.delete(obj) {|nosuch| ... } -> deleted_object or block_return
+ *
+ * Removes zero or more elements from +self+; returns +self+.
+ *
+ * When no block is given,
+ * removes from +self+ each element +ele+ such that <tt>ele == obj</tt>;
+ * returns the last deleted element:
+ * s1 = 'bar'; s2 = 'bar'
+ * a = [:foo, s1, 2, s2]
+ * a.delete('bar') # => "bar"
+ * a # => [:foo, 2]
+ *
+ * Returns +nil+ if no elements removed.
+ *
+ * When a block is given,
+ * removes from +self+ each element +ele+ such that <tt>ele == obj</tt>.
+ *
+ * If any such elements are found, ignores the block
+ * and returns the last deleted element:
+ * s1 = 'bar'; s2 = 'bar'
+ * a = [:foo, s1, 2, s2]
+ * deleted_obj = a.delete('bar') {|obj| fail 'Cannot happen' }
+ * a # => [:foo, 2]
+ *
+ * If no such elements are found, returns the block's return value:
+ * a = [:foo, 'bar', 2]
+ * a.delete(:nosuch) {|obj| "#{obj} not found" } # => "nosuch not found"
*/
VALUE
@@ -3029,6 +3979,7 @@ rb_ary_delete(VALUE ary, VALUE item)
ary_resize_smaller(ary, i2);
+ ary_verify(ary);
return v;
}
@@ -3069,27 +4020,33 @@ rb_ary_delete_at(VALUE ary, long pos)
rb_ary_modify(ary);
del = RARRAY_AREF(ary, pos);
- RARRAY_PTR_USE(ary, ptr, {
- MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+ MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
});
ARY_INCREASE_LEN(ary, -1);
-
+ ary_verify(ary);
return del;
}
/*
* call-seq:
- * ary.delete_at(index) -> obj or nil
+ * array.delete_at(index) -> deleted_object or nil
+ *
+ * Deletes an element from +self+, per the given \Integer +index+.
+ *
+ * When +index+ is non-negative, deletes the element at offset +index+:
+ * a = [:foo, 'bar', 2]
+ * a.delete_at(1) # => "bar"
+ * a # => [:foo, 2]
*
- * Deletes the element at the specified +index+, returning that element, or
- * +nil+ if the +index+ is out of range.
+ * If index is too large, returns +nil+.
*
- * See also Array#slice!
+ * When +index+ is negative, counts backward from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a.delete_at(-2) # => "bar"
+ * a # => [:foo, 2]
*
- * a = ["ant", "bat", "cat", "dog"]
- * a.delete_at(2) #=> "cat"
- * a #=> ["ant", "bat", "dog"]
- * a.delete_at(99) #=> nil
+ * If +index+ is too small (far from zero), returns nil.
*/
static VALUE
@@ -3098,66 +4055,118 @@ rb_ary_delete_at_m(VALUE ary, VALUE pos)
return rb_ary_delete_at(ary, NUM2LONG(pos));
}
+static VALUE
+ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
+{
+ const long orig_len = RARRAY_LEN(ary);
+
+ if (len < 0) {
+ return Qnil;
+ }
+ else if (pos < -orig_len) {
+ return Qnil;
+ }
+ else if (pos < 0) {
+ pos += orig_len;
+ }
+ else if (orig_len < pos) {
+ return Qnil;
+ }
+ if (orig_len < pos + len) {
+ len = orig_len - pos;
+ }
+ if (len == 0) {
+ return rb_ary_new2(0);
+ }
+ else {
+ VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
+ rb_ary_splice(ary, pos, len, 0, 0);
+ return arg2;
+ }
+}
+
/*
* call-seq:
- * ary.slice!(index) -> obj or nil
- * ary.slice!(start, length) -> new_ary or nil
- * ary.slice!(range) -> new_ary or nil
- *
- * Deletes the element(s) given by an +index+ (optionally up to +length+
- * elements) or by a +range+.
- *
- * Returns the deleted object (or objects), or +nil+ if the +index+ is out of
- * range.
- *
- * a = [ "a", "b", "c" ]
- * a.slice!(1) #=> "b"
- * a #=> ["a", "c"]
- * a.slice!(-1) #=> "c"
- * a #=> ["a"]
- * a.slice!(100) #=> nil
- * a #=> ["a"]
+ * array.slice!(n) -> object or nil
+ * array.slice!(start, length) -> new_array or nil
+ * array.slice!(range) -> new_array or nil
+ *
+ * Removes and returns elements from +self+.
+ *
+ * When the only argument is an \Integer +n+,
+ * removes and returns the _nth_ element in +self+:
+ * a = [:foo, 'bar', 2]
+ * a.slice!(1) # => "bar"
+ * a # => [:foo, 2]
+ *
+ * If +n+ is negative, counts backwards from the end of +self+:
+ * a = [:foo, 'bar', 2]
+ * a.slice!(-1) # => 2
+ * a # => [:foo, "bar"]
+ *
+ * If +n+ is out of range, returns +nil+.
+ *
+ * When the only arguments are Integers +start+ and +length+,
+ * removes +length+ elements from +self+ beginning at offset +start+;
+ * returns the deleted objects in a new Array:
+ * a = [:foo, 'bar', 2]
+ * a.slice!(0, 2) # => [:foo, "bar"]
+ * a # => [2]
+ *
+ * If <tt>start + length</tt> exceeds the array size,
+ * removes and returns all elements from offset +start+ to the end:
+ * a = [:foo, 'bar', 2]
+ * a.slice!(1, 50) # => ["bar", 2]
+ * a # => [:foo]
+ *
+ * If <tt>start == a.size</tt> and +length+ is non-negative,
+ * returns a new empty \Array.
+ *
+ * If +length+ is negative, returns +nil+.
+ *
+ * When the only argument is a \Range object +range+,
+ * treats <tt>range.min</tt> as +start+ above and <tt>range.size</tt> as +length+ above:
+ * a = [:foo, 'bar', 2]
+ * a.slice!(1..2) # => ["bar", 2]
+ * a # => [:foo]
+ *
+ * If <tt>range.start == a.size</tt>, returns a new empty \Array.
+ *
+ * If <tt>range.start</tt> is larger than the array size, returns +nil+.
+ *
+ * If <tt>range.end</tt> is negative, counts backwards from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a.slice!(0..-2) # => [:foo, "bar"]
+ * a # => [2]
+ *
+ * If <tt>range.start</tt> is negative,
+ * calculates the start index backwards from the end of the array:
+ * a = [:foo, 'bar', 2]
+ * a.slice!(-2..2) # => ["bar", 2]
+ * a # => [:foo]
*/
static VALUE
rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
{
- VALUE arg1, arg2;
- long pos, len, orig_len;
+ VALUE arg1;
+ long pos, len;
rb_ary_modify_check(ary);
+ rb_check_arity(argc, 1, 2);
+ arg1 = argv[0];
+
if (argc == 2) {
pos = NUM2LONG(argv[0]);
len = NUM2LONG(argv[1]);
- delete_pos_len:
- if (len < 0) return Qnil;
- orig_len = RARRAY_LEN(ary);
- if (pos < 0) {
- pos += orig_len;
- if (pos < 0) return Qnil;
- }
- else if (orig_len < pos) return Qnil;
- if (orig_len < pos + len) {
- len = orig_len - pos;
- }
- if (len == 0) return rb_ary_new2(0);
- arg2 = rb_ary_new4(len, RARRAY_CONST_PTR(ary)+pos);
- RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
- rb_ary_splice(ary, pos, len, 0, 0);
- return arg2;
- }
-
- if (argc != 1) {
- /* error report */
- rb_scan_args(argc, argv, "11", NULL, NULL);
+ return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
}
- arg1 = argv[0];
if (!FIXNUM_P(arg1)) {
switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
case Qtrue:
/* valid range */
- goto delete_pos_len;
+ return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
case Qnil:
/* invalid range */
return Qnil;
@@ -3177,7 +4186,8 @@ ary_reject(VALUE orig, VALUE result)
for (i = 0; i < RARRAY_LEN(orig); i++) {
VALUE v = RARRAY_AREF(orig, i);
- if (!RTEST(rb_yield(v))) {
+
+ if (!RTEST(rb_yield(v))) {
rb_ary_push(result, v);
}
}
@@ -3206,7 +4216,6 @@ static VALUE
ary_reject_bang(VALUE ary)
{
struct select_bang_arg args;
-
rb_ary_modify_check(ary);
args.ary = ary;
args.len[0] = args.len[1] = 0;
@@ -3215,37 +4224,44 @@ ary_reject_bang(VALUE ary)
/*
* call-seq:
- * ary.reject! { |item| block } -> ary or nil
- * ary.reject! -> Enumerator
+ * array.reject! {|element| ... } -> self or nil
+ * array.reject! -> new_enumerator
*
- * Deletes every element of +self+ for which the block evaluates to +true+,
- * if no changes were made returns +nil+.
+ * Removes each element for which the block returns a truthy value.
*
- * The array may not be changed instantly every time the block is called.
+ * Returns +self+ if any elements removed:
+ * a = [:foo, 'bar', 2, 'bat']
+ * a.reject! {|element| element.to_s.start_with?('b') } # => [:foo, 2]
*
- * See also Enumerable#reject and Array#delete_if.
+ * Returns +nil+ if no elements removed.
*
- * If no block is given, an Enumerator is returned instead.
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2]
+ * a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!>
*/
static VALUE
rb_ary_reject_bang(VALUE ary)
{
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ rb_ary_modify(ary);
return ary_reject_bang(ary);
}
/*
* call-seq:
- * ary.reject {|item| block } -> new_ary
- * ary.reject -> Enumerator
- *
- * Returns a new array containing the items in +self+ for which the given
- * block is not +true+. The ordering of non-rejected elements is maintained.
- *
- * See also Array#delete_if
- *
- * If no block is given, an Enumerator is returned instead.
+ * array.reject {|element| ... } -> new_array
+ * array.reject -> new_enumerator
+ *
+ * Returns a new \Array whose elements are all those from +self+
+ * for which the block returns +false+ or +nil+:
+ * a = [:foo, 'bar', 2, 'bat']
+ * a1 = a.reject {|element| element.to_s.start_with?('b') }
+ * a1 # => [:foo, 2]
+ *
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2]
+ * a.reject # => #<Enumerator: [:foo, "bar", 2]:reject>
*/
static VALUE
@@ -3261,25 +4277,23 @@ rb_ary_reject(VALUE ary)
/*
* 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!
+ * array.delete_if {|element| ... } -> self
+ * array.delete_if -> Enumerator
*
- * If no block is given, an Enumerator is returned instead.
+ * Removes each element in +self+ for which the block returns a truthy value;
+ * returns +self+:
+ * a = [:foo, 'bar', 2, 'bat']
+ * a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2]
*
- * scores = [ 97, 42, 75 ]
- * scores.delete_if {|score| score < 80 } #=> [97]
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2]
+ * a.delete_if # => #<Enumerator: [:foo, "bar", 2]:delete_if>
*/
static VALUE
rb_ary_delete_if(VALUE ary)
{
+ ary_verify(ary);
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
ary_reject_bang(ary);
return ary;
@@ -3289,7 +4303,8 @@ static VALUE
take_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, cbarg))
{
VALUE *args = (VALUE *)cbarg;
- if (args[1]-- == 0) rb_iter_break();
+ if (args[1] == 0) rb_iter_break();
+ else args[1]--;
if (argc > 1) val = rb_ary_new4(argc, argv);
rb_ary_push(args[0], val);
return Qnil;
@@ -3313,26 +4328,51 @@ take_items(VALUE obj, long n)
/*
* call-seq:
- * ary.zip(arg, ...) -> new_ary
- * ary.zip(arg, ...) { |arr| block } -> nil
- *
- * Converts any arguments to arrays, then merges elements of +self+ with
- * corresponding elements from each argument.
- *
- * This generates a sequence of <code>ary.size</code> _n_-element arrays,
- * where _n_ is one more than the count of arguments.
- *
- * If the size of any argument is less than the size of the initial array,
- * +nil+ values are supplied.
- *
- * If a block is given, it is invoked for each output +array+, otherwise an
- * array of arrays is returned.
- *
- * a = [ 4, 5, 6 ]
- * b = [ 7, 8, 9 ]
- * [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
- * [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]]
- * a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
+ * array.zip(*other_arrays) -> new_array
+ * array.zip(*other_arrays) {|other_array| ... } -> nil
+ *
+ * When no block given, returns a new \Array +new_array+ of size <tt>self.size</tt>
+ * whose elements are Arrays.
+ *
+ * Each nested array <tt>new_array[n]</tt> is of size <tt>other_arrays.size+1</tt>,
+ * and contains:
+ * - The _nth_ element of +self+.
+ * - The _nth_ element of each of the +other_arrays+.
+ *
+ * If all +other_arrays+ and +self+ are the same size:
+ * a = [:a0, :a1, :a2, :a3]
+ * b = [:b0, :b1, :b2, :b3]
+ * c = [:c0, :c1, :c2, :c3]
+ * d = a.zip(b, c)
+ * d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
+ *
+ * If any array in +other_arrays+ is smaller than +self+,
+ * fills to <tt>self.size</tt> with +nil+:
+ * a = [:a0, :a1, :a2, :a3]
+ * b = [:b0, :b1, :b2]
+ * c = [:c0, :c1]
+ * d = a.zip(b, c)
+ * d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]
+ *
+ * If any array in +other_arrays+ is larger than +self+,
+ * its trailing elements are ignored:
+ * a = [:a0, :a1, :a2, :a3]
+ * b = [:b0, :b1, :b2, :b3, :b4]
+ * c = [:c0, :c1, :c2, :c3, :c4, :c5]
+ * d = a.zip(b, c)
+ * d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
+ *
+ * When a block is given, calls the block with each of the sub-arrays (formed as above); returns nil
+ * a = [:a0, :a1, :a2, :a3]
+ * b = [:b0, :b1, :b2, :b3]
+ * c = [:c0, :c1, :c2, :c3]
+ * a.zip(b, c) {|sub_array| p sub_array} # => nil
+ *
+ * Output:
+ * [:a0, :b0, :c0]
+ * [:a1, :b1, :c1]
+ * [:a2, :b2, :c2]
+ * [:a3, :b3, :c3]
*/
static VALUE
@@ -3395,15 +4435,12 @@ rb_ary_zip(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.transpose -> new_ary
- *
- * Assumes that +self+ is an array of arrays and transposes the rows and
- * columns.
+ * array.transpose -> new_array
*
- * a = [[1,2], [3,4], [5,6]]
- * a.transpose #=> [[1, 3, 5], [2, 4, 6]]
- *
- * If the length of the subarrays don't match, an IndexError is raised.
+ * Transposes the rows and columns in an \Array of Arrays;
+ * the nested Arrays must all be the same size:
+ * a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
+ * a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
*/
static VALUE
@@ -3436,15 +4473,11 @@ rb_ary_transpose(VALUE ary)
/*
* call-seq:
- * ary.replace(other_ary) -> ary
- * ary.initialize_copy(other_ary) -> ary
- *
- * Replaces the contents of +self+ with the contents of +other_ary+,
- * truncating or expanding if necessary.
+ * array.replace(other_array) -> self
*
- * a = [ "a", "b", "c", "d", "e" ]
- * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"]
- * a #=> ["x", "y", "z"]
+ * Replaces the content of +self+ with the content of +other_array+; returns +self+:
+ * a = [:foo, 'bar', 2]
+ * a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3]
*/
VALUE
@@ -3455,93 +4488,236 @@ rb_ary_replace(VALUE copy, VALUE orig)
if (copy == orig) return copy;
if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
- VALUE shared = 0;
+ VALUE shared_root = 0;
if (ARY_OWNS_HEAP_P(copy)) {
- RARRAY_PTR_USE(copy, ptr, ruby_sized_xfree(ptr, ARY_HEAP_SIZE(copy)));
+ ary_heap_free(copy);
}
else if (ARY_SHARED_P(copy)) {
- shared = ARY_SHARED(copy);
+ shared_root = ARY_SHARED_ROOT(copy);
FL_UNSET_SHARED(copy);
}
FL_SET_EMBED(copy);
- ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
- if (shared) {
- rb_ary_decrement_share(shared);
+ ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
+ if (shared_root) {
+ rb_ary_decrement_share(shared_root);
}
ARY_SET_LEN(copy, RARRAY_LEN(orig));
}
else {
- VALUE shared = ary_make_shared(orig);
+ VALUE shared_root = ary_make_shared(orig);
if (ARY_OWNS_HEAP_P(copy)) {
- RARRAY_PTR_USE(copy, ptr, ruby_sized_xfree(ptr, ARY_HEAP_SIZE(copy)));
+ ary_heap_free(copy);
}
else {
rb_ary_unshare_safe(copy);
}
FL_UNSET_EMBED(copy);
- ARY_SET_PTR(copy, RARRAY_CONST_PTR(orig));
- ARY_SET_LEN(copy, RARRAY_LEN(orig));
- rb_ary_set_shared(copy, shared);
+ ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
+ ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
+ rb_ary_set_shared(copy, shared_root);
}
+ ary_verify(copy);
return copy;
}
/*
* call-seq:
- * ary.clear -> ary
- *
- * Removes all elements from +self+.
+ * array.clear -> self
*
- * a = [ "a", "b", "c", "d", "e" ]
- * a.clear #=> [ ]
+ * Removes all elements from +self+:
+ * a = [:foo, 'bar', 2]
+ * a.clear # => []
*/
VALUE
rb_ary_clear(VALUE ary)
{
rb_ary_modify_check(ary);
- ARY_SET_LEN(ary, 0);
if (ARY_SHARED_P(ary)) {
if (!ARY_EMBED_P(ary)) {
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
+ ARY_SET_EMBED_LEN(ary, 0);
}
}
- else if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
- ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
+ else {
+ ARY_SET_LEN(ary, 0);
+ if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
+ ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
+ }
}
+ ary_verify(ary);
return ary;
}
/*
* call-seq:
- * ary.fill(obj) -> ary
- * ary.fill(obj, start [, length]) -> ary
- * ary.fill(obj, range ) -> ary
- * ary.fill { |index| block } -> ary
- * ary.fill(start [, length] ) { |index| block } -> ary
- * ary.fill(range) { |index| block } -> ary
- *
- * The first three forms set the selected elements of +self+ (which
- * may be the entire array) to +obj+.
- *
- * A +start+ of +nil+ is equivalent to zero.
- *
- * A +length+ of +nil+ is equivalent to the length of the array.
- *
- * The last three forms fill the array with the value of the given block,
- * which is passed the absolute index of each element to be filled.
- *
- * Negative values of +start+ count from the end of the array, where +-1+ is
- * the last element.
- *
- * a = [ "a", "b", "c", "d" ]
- * a.fill("x") #=> ["x", "x", "x", "x"]
- * a.fill("z", 2, 2) #=> ["x", "x", "z", "z"]
- * a.fill("y", 0..1) #=> ["y", "y", "z", "z"]
- * a.fill { |i| i*i } #=> [0, 1, 4, 9]
- * a.fill(-2) { |i| i*i*i } #=> [0, 1, 8, 27]
+ * array.fill(obj) -> self
+ * array.fill(obj, start) -> self
+ * array.fill(obj, start, length) -> self
+ * array.fill(obj, range) -> self
+ * array.fill {|index| ... } -> self
+ * array.fill(start) {|index| ... } -> self
+ * array.fill(start, length) {|index| ... } -> self
+ * array.fill(range) {|index| ... } -> self
+ *
+ * Replaces specified elements in +self+ with specified objects; returns +self+.
+ *
+ * With argument +obj+ and no block given, replaces all elements with that one object:
+ * a = ['a', 'b', 'c', 'd']
+ * a # => ["a", "b", "c", "d"]
+ * a.fill(:X) # => [:X, :X, :X, :X]
+ *
+ * With arguments +obj+ and \Integer +start+, and no block given,
+ * replaces elements based on the given start.
+ *
+ * If +start+ is in range (<tt>0 <= start < array.size</tt>),
+ * replaces all elements from offset +start+ through the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, 2) # => ["a", "b", :X, :X]
+ *
+ * If +start+ is too large (<tt>start >= array.size</tt>), does nothing:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, 4) # => ["a", "b", "c", "d"]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, 5) # => ["a", "b", "c", "d"]
+ *
+ * If +start+ is negative, counts from the end (starting index is <tt>start + array.size</tt>):
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, -2) # => ["a", "b", :X, :X]
+ *
+ * If +start+ is too small (less than and far from zero), replaces all elements:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, -6) # => [:X, :X, :X, :X]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, -50) # => [:X, :X, :X, :X]
+ *
+ * With arguments +obj+, \Integer +start+, and \Integer +length+, and no block given,
+ * replaces elements based on the given +start+ and +length+.
+ *
+ * If +start+ is in range, replaces +length+ elements beginning at offset +start+:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, 1, 1) # => ["a", :X, "c", "d"]
+ *
+ * If +start+ is negative, counts from the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, -2, 1) # => ["a", "b", :X, "d"]
+ *
+ * If +start+ is large (<tt>start >= array.size</tt>), extends +self+ with +nil+:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, 5, 0) # => ["a", "b", "c", "d", nil]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, 5, 2) # => ["a", "b", "c", "d", nil, :X, :X]
+ *
+ * If +length+ is zero or negative, replaces no elements:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, 1, 0) # => ["a", "b", "c", "d"]
+ * a.fill(:X, 1, -1) # => ["a", "b", "c", "d"]
+ *
+ * With arguments +obj+ and \Range +range+, and no block given,
+ * replaces elements based on the given range.
+ *
+ * If the range is positive and ascending (<tt>0 < range.begin <= range.end</tt>),
+ * replaces elements from <tt>range.begin</tt> to <tt>range.end</tt>:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (1..1)) # => ["a", :X, "c", "d"]
+ *
+ * If <tt>range.first</tt> is negative, replaces no elements:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (-1..1)) # => ["a", "b", "c", "d"]
+ *
+ * If <tt>range.last</tt> is negative, counts from the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (0..-2)) # => [:X, :X, :X, "d"]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (1..-2)) # => ["a", :X, :X, "d"]
+ *
+ * If <tt>range.last</tt> and <tt>range.last</tt> are both negative,
+ * both count from the end of the array:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (-1..-1)) # => ["a", "b", "c", :X]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (-2..-2)) # => ["a", "b", :X, "d"]
+ *
+ * With no arguments and a block given, calls the block with each index;
+ * replaces the corresponding element with the block's return value:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
+ *
+ * With argument +start+ and a block given, calls the block with each index
+ * from offset +start+ to the end; replaces the corresponding element
+ * with the block's return value:
+ *
+ * If start is in range (<tt>0 <= start < array.size</tt>),
+ * replaces from offset +start+ to the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(1) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "new_3"]
+ *
+ * If +start+ is too large(<tt>start >= array.size</tt>), does nothing:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
+ *
+ * If +start+ is negative, counts from the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "new_3"]
+ *
+ * If start is too small (<tt>start <= -array.size</tt>, replaces all elements:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(-6) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(-50) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
+ *
+ * With arguments +start+ and +length+, and a block given,
+ * calls the block for each index specified by start length;
+ * replaces the corresponding element with the block's return value.
+ *
+ * If +start+ is in range, replaces +length+ elements beginning at offset +start+:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(1, 1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]
+ *
+ * If start is negative, counts from the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(-2, 1) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]
+ *
+ * If +start+ is large (<tt>start >= array.size</tt>), extends +self+ with +nil+:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(5, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(5, 2) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil, "new_5", "new_6"]
+ *
+ * If +length+ is zero or less, replaces no elements:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(1, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]
+ * a.fill(1, -1) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]
+ *
+ * With arguments +obj+ and +range+, and a block given,
+ * calls the block with each index in the given range;
+ * replaces the corresponding element with the block's return value.
+ *
+ * If the range is positive and ascending (<tt>range 0 < range.begin <= range.end</tt>,
+ * replaces elements from <tt>range.begin</tt> to <tt>range.end</tt>:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(1..1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]
+ *
+ * If +range.first+ is negative, does nothing:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(-1..1) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
+ *
+ * If <tt>range.last</tt> is negative, counts from the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(0..-2) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "d"]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(1..-2) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "d"]
+ *
+ * If <tt>range.first</tt> and <tt>range.last</tt> are both negative,
+ * both count from the end:
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(-1..-1) { |index| "new_#{index}" } # => ["a", "b", "c", "new_3"]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(-2..-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]
*/
static VALUE
@@ -3610,25 +4786,14 @@ rb_ary_fill(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary + other_ary -> new_ary
- *
- * Concatenation --- Returns a new array built by concatenating the
- * two arrays together to produce a third array.
- *
- * [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
- * a = [ "a", "b", "c" ]
- * c = a + [ "d", "e", "f" ]
- * c #=> [ "a", "b", "c", "d", "e", "f" ]
- * a #=> [ "a", "b", "c" ]
+ * array + other_array -> new_array
*
- * Note that
- * x += y
- * is the same as
- * x = x + y
- * This means that it produces a new array. As a consequence,
- * repeated use of <code>+=</code> on arrays can be quite inefficient.
+ * Returns a new \Array containing all elements of +array+
+ * followed by all elements of +other_array+:
+ * a = [0, 1] + [2, 3]
+ * a # => [0, 1, 2, 3]
*
- * See also Array#concat.
+ * Related: #concat.
*/
VALUE
@@ -3643,8 +4808,8 @@ rb_ary_plus(VALUE x, VALUE y)
len = xlen + ylen;
z = rb_ary_new2(len);
- ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));
- ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
+ ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR_TRANSIENT(x));
+ ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y));
ARY_SET_LEN(z, len);
return z;
}
@@ -3654,29 +4819,19 @@ ary_append(VALUE x, VALUE y)
{
long n = RARRAY_LEN(y);
if (n > 0) {
- rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR(y), n);
+ rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR_TRANSIENT(y), n);
}
+ RB_GC_GUARD(y);
return x;
}
/*
* call-seq:
- * ary.concat(other_ary1, other_ary2,...) -> ary
+ * array.concat(*other_arrays) -> self
*
- * Appends the elements of +other_ary+s to +self+.
- *
- * [ "a", "b" ].concat( ["c", "d"] ) #=> [ "a", "b", "c", "d" ]
- * [ "a" ].concat( ["b"], ["c", "d"] ) #=> [ "a", "b", "c", "d" ]
- * [ "a" ].concat #=> [ "a" ]
- *
- * a = [ 1, 2, 3 ]
- * a.concat( [ 4, 5 ] )
- * a #=> [ 1, 2, 3, 4, 5 ]
- *
- * a = [ 1, 2 ]
- * a.concat(a, a) #=> [1, 2, 1, 2, 1, 2]
- *
- * See also Array#+.
+ * Adds to +array+ all elements from each \Array in +other_arrays+; returns +self+:
+ * a = [0, 1]
+ * a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5]
*/
static VALUE
@@ -3696,6 +4851,7 @@ rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
ary_append(ary, args);
}
+ ary_verify(ary);
return ary;
}
@@ -3707,19 +4863,17 @@ rb_ary_concat(VALUE x, VALUE y)
/*
* call-seq:
- * ary * int -> new_ary
- * ary * str -> new_string
+ * array * n -> new_array
+ * array * string_separator -> new_string
*
- * Repetition --- With a String argument, equivalent to
- * <code>ary.join(str)</code>.
- *
- * Otherwise, returns a new array built by concatenating the +int+ copies of
- * +self+.
- *
- *
- * [ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ]
- * [ 1, 2, 3 ] * "," #=> "1,2,3"
+ * When non-negative argument \Integer +n+ is given,
+ * returns a new \Array built by concatenating the +n+ copies of +self+:
+ * a = ['x', 'y']
+ * a * 3 # => ["x", "y", "x", "y", "x", "y"]
*
+ * When \String argument +string_separator+ is given,
+ * equivalent to <tt>array.join(string_separator)</tt>:
+ * [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}"
*/
static VALUE
@@ -3736,7 +4890,7 @@ rb_ary_times(VALUE ary, VALUE times)
len = NUM2LONG(times);
if (len == 0) {
- ary2 = ary_new(rb_obj_class(ary), 0);
+ ary2 = ary_new(rb_cArray, 0);
goto out;
}
if (len < 0) {
@@ -3747,45 +4901,37 @@ rb_ary_times(VALUE ary, VALUE times)
}
len *= RARRAY_LEN(ary);
- ary2 = ary_new(rb_obj_class(ary), len);
+ ary2 = ary_new(rb_cArray, len);
ARY_SET_LEN(ary2, len);
- ptr = RARRAY_CONST_PTR(ary);
+ ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
t = RARRAY_LEN(ary);
if (0 < t) {
ary_memcpy(ary2, 0, t, ptr);
while (t <= len/2) {
- ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
+ ary_memcpy(ary2, t, t, RARRAY_CONST_PTR_TRANSIENT(ary2));
t *= 2;
}
if (t < len) {
- ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
+ ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR_TRANSIENT(ary2));
}
}
out:
- OBJ_INFECT(ary2, ary);
-
return ary2;
}
/*
* call-seq:
- * ary.assoc(obj) -> element_ary or nil
+ * array.assoc(obj) -> found_array or nil
*
- * Searches through an array whose elements are also arrays comparing +obj+
- * with the first element of each contained array using <code>obj.==</code>.
+ * Returns the first element in +self+ that is an \Array
+ * whose first element <tt>==</tt> +obj+:
+ * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
+ * a.assoc(4) # => [4, 5, 6]
*
- * Returns the first contained array that matches (that is, the first
- * associated array), or +nil+ if no match is found.
+ * Returns +nil+ if no such element is found.
*
- * See also Array#rassoc
- *
- * s1 = [ "colors", "red", "blue", "green" ]
- * s2 = [ "letters", "a", "b", "c" ]
- * s3 = "foo"
- * a = [ s1, s2, s3 ]
- * a.assoc("letters") #=> [ "letters", "a", "b", "c" ]
- * a.assoc("foo") #=> nil
+ * Related: #rassoc.
*/
VALUE
@@ -3805,20 +4951,16 @@ rb_ary_assoc(VALUE ary, VALUE key)
/*
* call-seq:
- * ary.rassoc(obj) -> element_ary or nil
- *
- * Searches through the array whose elements are also arrays.
- *
- * Compares +obj+ with the second element of each contained array using
- * <code>obj.==</code>.
+ * array.rassoc(obj) -> found_array or nil
*
- * Returns the first contained array that matches +obj+.
+ * Returns the first element in +self+ that is an \Array
+ * whose second element <tt>==</tt> +obj+:
+ * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
+ * a.rassoc(4) # => [2, 4]
*
- * See also Array#assoc.
+ * Returns +nil+ if no such element is found.
*
- * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
- * a.rassoc("two") #=> [2, "two"]
- * a.rassoc("four") #=> nil
+ * Related: #assoc.
*/
VALUE
@@ -3845,6 +4987,7 @@ recursive_equal(VALUE ary1, VALUE ary2, int recur)
if (recur) return Qtrue; /* Subtle! */
+ /* rb_equal() can evacuate ptrs */
p1 = RARRAY_CONST_PTR(ary1);
p2 = RARRAY_CONST_PTR(ary2);
len1 = RARRAY_LEN(ary1);
@@ -3857,8 +5000,8 @@ recursive_equal(VALUE ary1, VALUE ary2, int recur)
return Qfalse;
if (len1 < i)
return Qtrue;
- p1 = RARRAY_CONST_PTR(ary1) + i;
- p2 = RARRAY_CONST_PTR(ary2) + i;
+ p1 = RARRAY_CONST_PTR(ary1) + i;
+ p2 = RARRAY_CONST_PTR(ary2) + i;
}
else {
return Qfalse;
@@ -3872,16 +5015,19 @@ recursive_equal(VALUE ary1, VALUE ary2, int recur)
/*
* call-seq:
- * ary == other_ary -> bool
+ * array == other_array -> true or false
*
- * Equality --- Two arrays are equal if they contain the same number of
- * elements and if each element is equal to (according to Object#==) the
- * corresponding element in +other_ary+.
+ * Returns +true+ if both <tt>array.size == other_array.size</tt>
+ * and for each index +i+ in +array+, <tt>array[i] == other_array[i]</tt>:
+ * a0 = [:foo, 'bar', 2]
+ * a1 = [:foo, 'bar', 2.0]
+ * a1 == a0 # => true
+ * [] == [] # => true
*
- * [ "a", "c" ] == [ "a", "c", 7 ] #=> false
- * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
- * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
+ * Otherwise, returns +false+.
*
+ * This method is different from method Array#eql?,
+ * which compares elements using <tt>Object#eql?</tt>.
*/
static VALUE
@@ -3895,7 +5041,7 @@ rb_ary_equal(VALUE ary1, VALUE ary2)
return rb_equal(ary2, ary1);
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
- if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
+ if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
}
@@ -3914,10 +5060,18 @@ recursive_eql(VALUE ary1, VALUE ary2, int recur)
/*
* call-seq:
- * ary.eql?(other) -> true or false
+ * array.eql? other_array -> true or false
+ *
+ * Returns +true+ if +self+ and +other_array+ are the same size,
+ * and if, for each index +i+ in +self+, <tt>self[i].eql? other_array[i]</tt>:
+ * a0 = [:foo, 'bar', 2]
+ * a1 = [:foo, 'bar', 2]
+ * a1.eql?(a0) # => true
+ *
+ * Otherwise, returns +false+.
*
- * Returns +true+ if +self+ and +other+ are the same object,
- * or are both arrays with the same content (according to Object#eql?).
+ * This method is different from method {Array#==}[#method-i-3D-3D],
+ * which compares using method <tt>Object#==</tt>.
*/
static VALUE
@@ -3926,20 +5080,19 @@ rb_ary_eql(VALUE ary1, VALUE ary2)
if (ary1 == ary2) return Qtrue;
if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
- if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
+ if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
}
/*
* call-seq:
- * ary.hash -> integer
+ * array.hash -> integer
*
- * Compute a hash-code for this array.
+ * Returns the integer hash value for +self+.
*
- * Two arrays with the same content will have the same hash code (and will
- * compare using #eql?).
- *
- * See also Object#hash.
+ * Two arrays with the same content will have the same hash code (and will compare using eql?):
+ * [0, 1, 2].hash == [0, 1, 2].hash # => true
+ * [0, 1, 2].hash == [0, 1, 3].hash # => false
*/
static VALUE
@@ -3961,14 +5114,12 @@ rb_ary_hash(VALUE ary)
/*
* call-seq:
- * ary.include?(object) -> true or false
- *
- * Returns +true+ if the given +object+ is present in +self+ (that is, if any
- * element <code>==</code> +object+), otherwise returns +false+.
+ * array.include?(obj) -> true or false
*
- * a = [ "a", "b", "c" ]
- * a.include?("b") #=> true
- * a.include?("z") #=> false
+ * Returns +true+ if for some index +i+ in +self+, <tt>obj == self[i]</tt>;
+ * otherwise +false+:
+ * [0, 1, 2].include?(2) # => true
+ * [0, 1, 2].include?(3) # => false
*/
VALUE
@@ -4023,32 +5174,24 @@ recursive_cmp(VALUE ary1, VALUE ary2, int recur)
/*
* call-seq:
- * ary <=> other_ary -> -1, 0, +1 or nil
- *
- * Comparison --- Returns an integer (+-1+, +0+, or <code>+1</code>) if this
- * array is less than, equal to, or greater than +other_ary+.
- *
- * Each object in each array is compared (using the <=> operator).
+ * array <=> other_array -> -1, 0, or 1
*
- * Arrays are compared in an "element-wise" manner; the first element of +ary+
- * is compared with the first one of +other_ary+ using the <=> operator, then
- * each of the second elements, etc...
- * As soon as the result of any such comparison is non zero (i.e. the two
- * corresponding elements are not equal), that result is returned for the
- * whole array comparison.
+ * Returns -1, 0, or 1 as +self+ is less than, equal to, or greater than +other_array+.
+ * For each index +i+ in +self+, evaluates <tt>result = self[i] <=> other_array[i]</tt>.
*
- * If all the elements are equal, then the result is based on a comparison of
- * the array lengths. Thus, two arrays are "equal" according to Array#<=> if,
- * and only if, they have the same length and the value of each element is
- * equal to the value of the corresponding element in the other array.
+ * Returns -1 if any result is -1:
+ * [0, 1, 2] <=> [0, 1, 3] # => -1
*
- * +nil+ is returned if the +other_ary+ is not an array or if the comparison
- * of two elements returned +nil+.
- *
- * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1
- * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1
- * [ 1, 2 ] <=> [ 1, :two ] #=> nil
+ * Returns 1 if any result is 1:
+ * [0, 1, 2] <=> [0, 1, 1] # => 1
*
+ * When all results are zero:
+ * - Returns -1 if +array+ is smaller than +other_array+:
+ * [0, 1, 2] <=> [0, 1, 2, 3] # => -1
+ * - Returns 1 if +array+ is larger than +other_array+:
+ * [0, 1, 2] <=> [0, 1] # => 1
+ * - Returns 0 if +array+ and +other_array+ are the same size:
+ * [0, 1, 2] <=> [0, 1, 2] # => 0
*/
VALUE
@@ -4120,28 +5263,26 @@ static inline void
ary_recycle_hash(VALUE hash)
{
assert(RBASIC_CLASS(hash) == 0);
- if (RHASH(hash)->ntbl) {
- st_table *tbl = RHASH(hash)->ntbl;
+ if (RHASH_ST_TABLE_P(hash)) {
+ st_table *tbl = RHASH_ST_TABLE(hash);
st_free_table(tbl);
+ RHASH_ST_CLEAR(hash);
}
- rb_gc_force_recycle(hash);
}
/*
* call-seq:
- * ary - other_ary -> new_ary
- *
- * Array Difference
- *
- * Returns a new array that is a copy of the original array, removing any
- * items that also appear in +other_ary+. The order is preserved from the
- * original array.
+ * array - other_array -> new_array
*
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * Returns a new \Array containing only those elements from +array+
+ * that are not found in \Array +other_array+;
+ * items are compared using <tt>eql?</tt>;
+ * the order from +array+ is preserved:
+ * [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3]
+ * [0, 1, 2, 3] - [3, 0] # => [1, 2]
+ * [0, 1, 2] - [4] # => [0, 1, 2]
*
- * [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
- *
- * If you need set-like behavior, see the library class Set.
+ * Related: Array#difference.
*/
static VALUE
@@ -4154,7 +5295,7 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
ary2 = to_ary(ary2);
ary3 = rb_ary_new();
- if (RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
+ if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (i=0; i<RARRAY_LEN(ary1); i++) {
VALUE elt = rb_ary_elt(ary1, i);
if (rb_ary_includes_by_eql(ary2, elt)) continue;
@@ -4165,7 +5306,7 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
hash = ary_make_hash(ary2);
for (i=0; i<RARRAY_LEN(ary1); i++) {
- if (st_lookup(rb_hash_tbl_raw(hash), RARRAY_AREF(ary1, i), 0)) continue;
+ if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
rb_ary_push(ary3, rb_ary_elt(ary1, i));
}
ary_recycle_hash(hash);
@@ -4174,17 +5315,70 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
/*
* call-seq:
- * ary & other_ary -> new_ary
+ * array.difference(*other_arrays) -> new_array
+ *
+ * Returns a new \Array containing only those elements from +self+
+ * that are not found in any of the Arrays +other_arrays+;
+ * items are compared using <tt>eql?</tt>; order from +self+ is preserved:
+ * [0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1]) # => [0, 2, 3]
+ * [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2]
+ * [0, 1, 2].difference([4]) # => [0, 1, 2]
*
- * Set Intersection --- Returns a new array containing unique elements common to the
- * two arrays. The order is preserved from the original array.
+ * Returns a copy of +self+ if no arguments given.
+ *
+ * Related: Array#-.
+ */
+
+static VALUE
+rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
+{
+ VALUE ary_diff;
+ long i, length;
+ volatile VALUE t0;
+ bool *is_hash = ALLOCV_N(bool, t0, argc);
+ ary_diff = rb_ary_new();
+ length = RARRAY_LEN(ary);
+
+ for (i = 0; i < argc; i++) {
+ argv[i] = to_ary(argv[i]);
+ is_hash[i] = (length > SMALL_ARRAY_LEN && RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
+ if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
+ }
+
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ int j;
+ VALUE elt = rb_ary_elt(ary, i);
+ for (j = 0; j < argc; j++) {
+ if (is_hash[j]) {
+ if (rb_hash_stlike_lookup(argv[j], RARRAY_AREF(ary, i), NULL))
+ break;
+ }
+ else {
+ if (rb_ary_includes_by_eql(argv[j], elt)) break;
+ }
+ }
+ if (j == argc) rb_ary_push(ary_diff, elt);
+ }
+
+ ALLOCV_END(t0);
+
+ return ary_diff;
+}
+
+
+/*
+ * call-seq:
+ * array & other_array -> new_array
*
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * Returns a new \Array containing each element found in both +array+ and \Array +other_array+;
+ * duplicates are omitted; items are compared using <tt>eql?</tt>:
+ * [0, 1, 2, 3] & [1, 2] # => [1, 2]
+ * [0, 1, 0, 1] & [0, 1] # => [0, 1]
*
- * [ 1, 1, 3, 5 ] & [ 3, 2, 1 ] #=> [ 1, 3 ]
- * [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
+ * Preserves order from +array+:
+ * [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2]
*
- * See also Array#uniq.
+ * Related: Array#intersection.
*/
@@ -4192,13 +5386,12 @@ static VALUE
rb_ary_and(VALUE ary1, VALUE ary2)
{
VALUE hash, ary3, v;
- st_table *table;
st_data_t vv;
long i;
ary2 = to_ary(ary2);
ary3 = rb_ary_new();
- if (RARRAY_LEN(ary2) == 0) return ary3;
+ if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (i=0; i<RARRAY_LEN(ary1); i++) {
@@ -4211,12 +5404,11 @@ rb_ary_and(VALUE ary1, VALUE ary2)
}
hash = ary_make_hash(ary2);
- table = rb_hash_tbl_raw(hash);
for (i=0; i<RARRAY_LEN(ary1); i++) {
v = RARRAY_AREF(ary1, i);
vv = (st_data_t)v;
- if (st_delete(table, &vv, 0)) {
+ if (rb_hash_stlike_delete(hash, &vv, 0)) {
rb_ary_push(ary3, v);
}
}
@@ -4225,6 +5417,37 @@ rb_ary_and(VALUE ary1, VALUE ary2)
return ary3;
}
+/*
+ * call-seq:
+ * array.intersection(*other_arrays) -> new_array
+ *
+ * Returns a new \Array containing each element found both in +self+
+ * and in all of the given Arrays +other_arrays+;
+ * duplicates are omitted; items are compared using <tt>eql?</tt>:
+ * [0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
+ * [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
+ *
+ * Preserves order from +self+:
+ * [0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2]
+ *
+ * Returns a copy of +self+ if no arguments given.
+ *
+ * Related: Array#&.
+ */
+
+static VALUE
+rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary)
+{
+ VALUE result = rb_ary_dup(ary);
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ result = rb_ary_and(result, argv[i]);
+ }
+
+ return result;
+}
+
static int
ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
{
@@ -4233,50 +5456,59 @@ ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
return ST_CONTINUE;
}
+static void
+rb_ary_union(VALUE ary_union, VALUE ary)
+{
+ long i;
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE elt = rb_ary_elt(ary, i);
+ if (rb_ary_includes_by_eql(ary_union, elt)) continue;
+ rb_ary_push(ary_union, elt);
+ }
+}
+
+static void
+rb_ary_union_hash(VALUE hash, VALUE ary2)
+{
+ long i;
+ for (i = 0; i < RARRAY_LEN(ary2); i++) {
+ VALUE elt = RARRAY_AREF(ary2, i);
+ if (!rb_hash_stlike_update(hash, (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
+ RB_OBJ_WRITTEN(hash, Qundef, elt);
+ }
+ }
+}
+
/*
* call-seq:
- * ary | other_ary -> new_ary
+ * array | other_array -> new_array
*
- * Set Union --- Returns a new array by joining +ary+ with +other_ary+,
- * excluding any duplicates and preserving the order from the given arrays.
+ * Returns the union of +array+ and \Array +other_array+;
+ * duplicates are removed; order is preserved;
+ * items are compared using <tt>eql?</tt>:
+ * [0, 1] | [2, 3] # => [0, 1, 2, 3]
+ * [0, 1, 1] | [2, 2, 3] # => [0, 1, 2, 3]
+ * [0, 1, 2] | [3, 2, 1, 0] # => [0, 1, 2, 3]
*
- * It compares elements using their #hash and #eql? methods for efficiency.
- *
- * [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
- * [ "c", "d", "a" ] | [ "a", "b", "c" ] #=> [ "c", "d", "a", "b" ]
- *
- * See also Array#uniq.
+ * Related: Array#union.
*/
static VALUE
rb_ary_or(VALUE ary1, VALUE ary2)
{
VALUE hash, ary3;
- long i;
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
ary3 = rb_ary_new();
- for (i=0; i<RARRAY_LEN(ary1); i++) {
- VALUE elt = rb_ary_elt(ary1, i);
- if (rb_ary_includes_by_eql(ary3, elt)) continue;
- rb_ary_push(ary3, elt);
- }
- for (i=0; i<RARRAY_LEN(ary2); i++) {
- VALUE elt = rb_ary_elt(ary2, i);
- if (rb_ary_includes_by_eql(ary3, elt)) continue;
- rb_ary_push(ary3, elt);
- }
+ rb_ary_union(ary3, ary1);
+ rb_ary_union(ary3, ary2);
return ary3;
}
hash = ary_make_hash(ary1);
- for (i=0; i<RARRAY_LEN(ary2); i++) {
- VALUE elt = RARRAY_AREF(ary2, i);
- if (!st_update(RHASH_TBL_RAW(hash), (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
- RB_OBJ_WRITTEN(hash, Qundef, elt);
- }
- }
+ rb_ary_union_hash(hash, ary2);
+
ary3 = rb_hash_values(hash);
ary_recycle_hash(hash);
return ary3;
@@ -4284,25 +5516,170 @@ rb_ary_or(VALUE ary1, VALUE ary2)
/*
* call-seq:
- * ary.max -> obj
- * ary.max { |a, b| block } -> obj
- * ary.max(n) -> array
- * ary.max(n) { |a, b| block } -> array
+ * array.union(*other_arrays) -> new_array
+ *
+ * Returns a new \Array that is the union of +self+ and all given Arrays +other_arrays+;
+ * duplicates are removed; order is preserved; items are compared using <tt>eql?</tt>:
+ * [0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7]
+ * [0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3]
+ * [0, 1, 2, 3].union([3, 2], [1, 0]) # => [0, 1, 2, 3]
+ *
+ * Returns a copy of +self+ if no arguments given.
+ *
+ * Related: Array#|.
+ */
+
+static VALUE
+rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
+{
+ int i;
+ long sum;
+ VALUE hash, ary_union;
+
+ sum = RARRAY_LEN(ary);
+ for (i = 0; i < argc; i++) {
+ argv[i] = to_ary(argv[i]);
+ sum += RARRAY_LEN(argv[i]);
+ }
+
+ if (sum <= SMALL_ARRAY_LEN) {
+ ary_union = rb_ary_new();
+
+ rb_ary_union(ary_union, ary);
+ for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
+
+ return ary_union;
+ }
+
+ hash = ary_make_hash(ary);
+ for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
+
+ ary_union = rb_hash_values(hash);
+ ary_recycle_hash(hash);
+ return ary_union;
+}
+
+static VALUE
+ary_max_generic(VALUE ary, long i, VALUE vmax)
+{
+ RUBY_ASSERT(i > 0 && i < RARRAY_LEN(ary));
+
+ VALUE v;
+ for (; i < RARRAY_LEN(ary); ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (rb_cmpint(rb_funcallv(vmax, id_cmp, 1, &v), vmax, v) < 0) {
+ vmax = v;
+ }
+ }
+
+ return vmax;
+}
+
+static VALUE
+ary_max_opt_fixnum(VALUE ary, long i, VALUE vmax)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(FIXNUM_P(vmax));
+
+ VALUE v;
+ for (; i < n; ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (FIXNUM_P(v)) {
+ if ((long)vmax < (long)v) {
+ vmax = v;
+ }
+ }
+ else {
+ return ary_max_generic(ary, i, vmax);
+ }
+ }
+
+ return vmax;
+}
+
+static VALUE
+ary_max_opt_float(VALUE ary, long i, VALUE vmax)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(RB_FLOAT_TYPE_P(vmax));
+
+ VALUE v;
+ for (; i < n; ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (RB_FLOAT_TYPE_P(v)) {
+ if (rb_float_cmp(vmax, v) < 0) {
+ vmax = v;
+ }
+ }
+ else {
+ return ary_max_generic(ary, i, vmax);
+ }
+ }
+
+ return vmax;
+}
+
+static VALUE
+ary_max_opt_string(VALUE ary, long i, VALUE vmax)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(STRING_P(vmax));
+
+ VALUE v;
+ for (; i < n; ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (STRING_P(v)) {
+ if (rb_str_cmp(vmax, v) < 0) {
+ vmax = v;
+ }
+ }
+ else {
+ return ary_max_generic(ary, i, vmax);
+ }
+ }
+
+ return vmax;
+}
+
+/*
+ * call-seq:
+ * array.max -> element
+ * array.max {|a, b| ... } -> element
+ * array.max(n) -> new_array
+ * array.max(n) {|a, b| ... } -> new_array
+ *
+ * Returns one of the following:
+ * - The maximum-valued element from +self+.
+ * - A new \Array of maximum-valued elements selected from +self+.
*
- * Returns the object in _ary_ with the maximum value. The
- * first form assumes all objects implement <code>Comparable</code>;
- * the second uses the block to return <em>a <=> b</em>.
+ * When no block is given, each element in +self+ must respond to method <tt><=></tt>
+ * with an \Integer.
*
- * a = %w(albatross dog horse)
- * a.max #=> "horse"
- * a.max { |a, b| a.length <=> b.length } #=> "albatross"
+ * With no argument and no block, returns the element in +self+
+ * having the maximum value per method <tt><=></tt>:
+ * [0, 1, 2].max # => 2
*
- * If the +n+ argument is given, maximum +n+ elements are returned
- * as an array.
+ * With an argument \Integer +n+ and no block, returns a new \Array with at most +n+ elements,
+ * in descending order per method <tt><=></tt>:
+ * [0, 1, 2, 3].max(3) # => [3, 2, 1]
+ * [0, 1, 2, 3].max(6) # => [3, 2, 1]
*
- * a = %w[albatross dog horse]
- * a.max(2) #=> ["horse", "dog"]
- * a.max(2) {|a, b| a.length <=> b.length } #=> ["albatross", "horse"]
+ * When a block is given, the block must return an \Integer.
+ *
+ * With a block and no argument, calls the block <tt>self.size-1</tt> times to compare elements;
+ * returns the element having the maximum value per the block:
+ * ['0', '00', '000'].max {|a, b| a.size <=> b.size } # => "000"
+ *
+ * With an argument +n+ and a block, returns a new \Array with at most +n+ elements,
+ * in descending order per the block:
+ * ['0', '00', '000'].max(2) {|a, b| a.size <=> b.size } # => ["000", "00"]
*/
static VALUE
rb_ary_max(int argc, VALUE *argv, VALUE ary)
@@ -4312,11 +5689,10 @@ rb_ary_max(int argc, VALUE *argv, VALUE ary)
VALUE num;
long i;
- rb_scan_args(argc, argv, "01", &num);
-
- if (!NIL_P(num))
+ if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 1, 1);
+ const long n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
v = RARRAY_AREF(ary, i);
@@ -4325,39 +5701,149 @@ rb_ary_max(int argc, VALUE *argv, VALUE ary)
}
}
}
- else {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- v = RARRAY_AREF(ary, i);
- if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) > 0) {
- result = v;
- }
- }
+ else if (n > 0) {
+ result = RARRAY_AREF(ary, 0);
+ if (n > 1) {
+ if (FIXNUM_P(result) && CMP_OPTIMIZABLE(cmp_opt, Integer)) {
+ return ary_max_opt_fixnum(ary, 1, result);
+ }
+ else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
+ return ary_max_opt_string(ary, 1, result);
+ }
+ else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
+ return ary_max_opt_float(ary, 1, result);
+ }
+ else {
+ return ary_max_generic(ary, 1, result);
+ }
+ }
}
if (result == Qundef) return Qnil;
return result;
}
+static VALUE
+ary_min_generic(VALUE ary, long i, VALUE vmin)
+{
+ RUBY_ASSERT(i > 0 && i < RARRAY_LEN(ary));
+
+ VALUE v;
+ for (; i < RARRAY_LEN(ary); ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (rb_cmpint(rb_funcallv(vmin, id_cmp, 1, &v), vmin, v) > 0) {
+ vmin = v;
+ }
+ }
+
+ return vmin;
+}
+
+static VALUE
+ary_min_opt_fixnum(VALUE ary, long i, VALUE vmin)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(FIXNUM_P(vmin));
+
+ VALUE a;
+ for (; i < n; ++i) {
+ a = RARRAY_AREF(ary, i);
+
+ if (FIXNUM_P(a)) {
+ if ((long)vmin > (long)a) {
+ vmin = a;
+ }
+ }
+ else {
+ return ary_min_generic(ary, i, vmin);
+ }
+ }
+
+ return vmin;
+}
+
+static VALUE
+ary_min_opt_float(VALUE ary, long i, VALUE vmin)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(RB_FLOAT_TYPE_P(vmin));
+
+ VALUE a;
+ for (; i < n; ++i) {
+ a = RARRAY_AREF(ary, i);
+
+ if (RB_FLOAT_TYPE_P(a)) {
+ if (rb_float_cmp(vmin, a) > 0) {
+ vmin = a;
+ }
+ }
+ else {
+ return ary_min_generic(ary, i, vmin);
+ }
+ }
+
+ return vmin;
+}
+
+static VALUE
+ary_min_opt_string(VALUE ary, long i, VALUE vmin)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(STRING_P(vmin));
+
+ VALUE a;
+ for (; i < n; ++i) {
+ a = RARRAY_AREF(ary, i);
+
+ if (STRING_P(a)) {
+ if (rb_str_cmp(vmin, a) > 0) {
+ vmin = a;
+ }
+ }
+ else {
+ return ary_min_generic(ary, i, vmin);
+ }
+ }
+
+ return vmin;
+}
+
/*
* call-seq:
- * ary.min -> obj
- * ary.min {| a,b | block } -> obj
- * ary.min(n) -> array
- * ary.min(n) {| a,b | block } -> array
+ * array.min -> element
+ * array.min { |a, b| ... } -> element
+ * array.min(n) -> new_array
+ * array.min(n) { |a, b| ... } -> new_array
+ *
+ * Returns one of the following:
+ * - The minimum-valued element from +self+.
+ * - A new \Array of minimum-valued elements selected from +self+.
+ *
+ * When no block is given, each element in +self+ must respond to method <tt><=></tt>
+ * with an \Integer.
*
- * Returns the object in _ary_ with the minimum value. The
- * first form assumes all objects implement <code>Comparable</code>;
- * the second uses the block to return <em>a <=> b</em>.
+ * With no argument and no block, returns the element in +self+
+ * having the minimum value per method <tt><=></tt>:
+ * [0, 1, 2].min # => 0
*
- * a = %w(albatross dog horse)
- * a.min #=> "albatross"
- * a.min { |a, b| a.length <=> b.length } #=> "dog"
+ * With \Integer argument +n+ and no block, returns a new \Array with at most +n+ elements,
+ * in ascending order per method <tt><=></tt>:
+ * [0, 1, 2, 3].min(3) # => [0, 1, 2]
+ * [0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
*
- * If the +n+ argument is given, minimum +n+ elements are returned
- * as an array.
+ * When a block is given, the block must return an Integer.
*
- * a = %w[albatross dog horse]
- * a.min(2) #=> ["albatross", "dog"]
- * a.min(2) {|a, b| a.length <=> b.length } #=> ["dog", "horse"]
+ * With a block and no argument, calls the block <tt>self.size-1</tt> times to compare elements;
+ * returns the element having the minimum value per the block:
+ * ['0', '00', '000'].min { |a, b| a.size <=> b.size } # => "0"
+ *
+ * With an argument +n+ and a block, returns a new \Array with at most +n+ elements,
+ * in ascending order per the block:
+ * [0, 1, 2, 3].min(3) # => [0, 1, 2]
+ * [0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
*/
static VALUE
rb_ary_min(int argc, VALUE *argv, VALUE ary)
@@ -4367,11 +5853,10 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
VALUE num;
long i;
- rb_scan_args(argc, argv, "01", &num);
-
- if (!NIL_P(num))
+ if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 0, 1);
+ const long n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
v = RARRAY_AREF(ary, i);
@@ -4380,18 +5865,56 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
}
}
}
- else {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- v = RARRAY_AREF(ary, i);
- if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) < 0) {
- result = v;
- }
- }
+ else if (n > 0) {
+ result = RARRAY_AREF(ary, 0);
+ if (n > 1) {
+ if (FIXNUM_P(result) && CMP_OPTIMIZABLE(cmp_opt, Integer)) {
+ return ary_min_opt_fixnum(ary, 1, result);
+ }
+ else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
+ return ary_min_opt_string(ary, 1, result);
+ }
+ else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
+ return ary_min_opt_float(ary, 1, result);
+ }
+ else {
+ return ary_min_generic(ary, 1, result);
+ }
+ }
}
if (result == Qundef) return Qnil;
return result;
}
+/*
+ * call-seq:
+ * array.minmax -> [min_val, max_val]
+ * array.minmax {|a, b| ... } -> [min_val, max_val]
+ *
+ * Returns a new 2-element \Array containing the minimum and maximum values
+ * from +self+, either per method <tt><=></tt> or per a given block:.
+ *
+ * When no block is given, each element in +self+ must respond to method <tt><=></tt>
+ * with an \Integer;
+ * returns a new 2-element \Array containing the minimum and maximum values
+ * from +self+, per method <tt><=></tt>:
+ * [0, 1, 2].minmax # => [0, 2]
+ *
+ * When a block is given, the block must return an \Integer;
+ * the block is called <tt>self.size-1</tt> times to compare elements;
+ * returns a new 2-element \Array containing the minimum and maximum values
+ * from +self+, per the block:
+ * ['0', '00', '000'].minmax {|a, b| a.size <=> b.size } # => ["0", "000"]
+ */
+static VALUE
+rb_ary_minmax(VALUE ary)
+{
+ if (rb_block_given_p()) {
+ return rb_call_super(0, NULL);
+ }
+ return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
+}
+
static int
push_value(st_data_t key, st_data_t val, st_data_t ary)
{
@@ -4401,31 +5924,31 @@ push_value(st_data_t key, st_data_t val, st_data_t ary)
/*
* call-seq:
- * ary.uniq! -> ary or nil
- * ary.uniq! { |item| ... } -> ary or nil
- *
- * Removes duplicate elements from +self+.
+ * array.uniq! -> self or nil
+ * array.uniq! {|element| ... } -> self or nil
*
- * If a block is given, it will use the return value of the block for
- * comparison.
+ * Removes duplicate elements from +self+, the first occurrence always being retained;
+ * returns +self+ if any elements removed, +nil+ otherwise.
*
- * It compares values using their #hash and #eql? methods for efficiency.
+ * With no block given, identifies and removes elements using method <tt>eql?</tt>
+ * to compare.
*
- * +self+ is traversed in order, and the first occurrence is kept.
+ * Returns +self+ if any elements removed:
+ * a = [0, 0, 1, 1, 2, 2]
+ * a.uniq! # => [0, 1, 2]
*
- * Returns +nil+ if no changes are made (that is, no duplicates are found).
+ * Returns +nil+ if no elements removed.
*
- * a = [ "a", "a", "b", "b", "c" ]
- * a.uniq! # => ["a", "b", "c"]
+ * With a block given, calls the block for each element;
+ * identifies (using method <tt>eql?</tt>) and removes
+ * elements for which the block returns duplicate values.
*
- * b = [ "a", "b", "c" ]
- * b.uniq! # => nil
- *
- * c = [["student","sam"], ["student","george"], ["teacher","matz"]]
- * c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
+ * Returns +self+ if any elements removed:
+ * a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
+ * a.uniq! {|element| element.size } # => ['a', 'aa', 'aaa']
*
+ * Returns +nil+ if no elements removed.
*/
-
static VALUE
rb_ary_uniq_bang(VALUE ary)
{
@@ -4451,7 +5974,7 @@ rb_ary_uniq_bang(VALUE ary)
FL_SET_EMBED(ary);
}
ary_resize_capa(ary, hash_size);
- st_foreach(rb_hash_tbl_raw(hash), push_value, ary);
+ rb_hash_foreach(hash, push_value, ary);
ary_recycle_hash(hash);
return ary;
@@ -4459,23 +5982,22 @@ rb_ary_uniq_bang(VALUE ary)
/*
* call-seq:
- * ary.uniq -> new_ary
- * ary.uniq { |item| ... } -> new_ary
- *
- * Returns a new array by removing duplicate values in +self+.
- *
- * If a block is given, it will use the return value of the block for comparison.
- *
- * It compares values using their #hash and #eql? methods for efficiency.
- *
- * +self+ is traversed in order, and the first occurrence is kept.
- *
- * a = [ "a", "a", "b", "b", "c" ]
- * a.uniq # => ["a", "b", "c"]
- *
- * b = [["student","sam"], ["student","george"], ["teacher","matz"]]
- * b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
- *
+ * array.uniq -> new_array
+ * array.uniq {|element| ... } -> new_array
+ *
+ * Returns a new \Array containing those elements from +self+ that are not duplicates,
+ * the first occurrence always being retained.
+ *
+ * With no block given, identifies and omits duplicates using method <tt>eql?</tt>
+ * to compare.
+ * a = [0, 0, 1, 1, 2, 2]
+ * a.uniq # => [0, 1, 2]
+ *
+ * With a block given, calls the block for each element;
+ * identifies (using method <tt>eql?</tt>) and omits duplicate values,
+ * that is, those elements for which the block returns the same value:
+ * a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
+ * a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
*/
static VALUE
@@ -4483,9 +6005,11 @@ rb_ary_uniq(VALUE ary)
{
VALUE hash, uniq;
- if (RARRAY_LEN(ary) <= 1)
- return rb_ary_dup(ary);
- if (rb_block_given_p()) {
+ if (RARRAY_LEN(ary) <= 1) {
+ hash = 0;
+ uniq = rb_ary_dup(ary);
+ }
+ else if (rb_block_given_p()) {
hash = ary_make_hash_by(ary);
uniq = rb_hash_values(hash);
}
@@ -4493,22 +6017,20 @@ rb_ary_uniq(VALUE ary)
hash = ary_make_hash(ary);
uniq = rb_hash_values(hash);
}
- RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
- ary_recycle_hash(hash);
+ if (hash) {
+ ary_recycle_hash(hash);
+ }
return uniq;
}
/*
* call-seq:
- * ary.compact! -> ary or nil
- *
- * Removes +nil+ elements from the array.
+ * array.compact! -> self or nil
*
- * Returns +nil+ if no changes were made, otherwise returns the array.
+ * Removes all +nil+ elements from +self+.
*
- * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
- * [ "a", "b", "c" ].compact! #=> nil
+ * Returns +self+ if any elements removed, otherwise +nil+.
*/
static VALUE
@@ -4518,14 +6040,14 @@ rb_ary_compact_bang(VALUE ary)
long n;
rb_ary_modify(ary);
- p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
+ p = t = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary); /* WB: no new reference */
end = p + RARRAY_LEN(ary);
while (t < end) {
if (NIL_P(*t)) t++;
else *p++ = *t++;
}
- n = p - RARRAY_CONST_PTR(ary);
+ n = p - RARRAY_CONST_PTR_TRANSIENT(ary);
if (RARRAY_LEN(ary) == n) {
return Qnil;
}
@@ -4536,12 +6058,11 @@ rb_ary_compact_bang(VALUE ary)
/*
* call-seq:
- * ary.compact -> new_ary
+ * array.compact -> new_array
*
- * Returns a copy of +self+ with all +nil+ elements removed.
- *
- * [ "a", nil, "b", nil, "c", nil ].compact
- * #=> [ "a", "b", "c" ]
+ * Returns a new \Array containing all non-+nil+ elements from +self+:
+ * a = [nil, 0, nil, 1, nil, 2, nil]
+ * a.compact # => [0, 1, 2]
*/
static VALUE
@@ -4554,23 +6075,26 @@ rb_ary_compact(VALUE ary)
/*
* call-seq:
- * ary.count -> int
- * ary.count(obj) -> int
- * ary.count { |item| block } -> int
+ * array.count -> an_integer
+ * array.count(obj) -> an_integer
+ * array.count {|element| ... } -> an_integer
*
- * Returns the number of elements.
+ * Returns a count of specified elements.
*
- * If an argument is given, counts the number of elements which equal +obj+
- * using <code>==</code>.
+ * With no argument and no block, returns the count of all elements:
+ * [0, 1, 2].count # => 3
+ * [].count # => 0
*
- * If a block is given, counts the number of elements for which the block
- * returns a true value.
+ * With argument +obj+, returns the count of elements <tt>eql?</tt> to +obj+:
+ * [0, 1, 2, 0].count(0) # => 2
+ * [0, 1, 2].count(3) # => 0
*
- * ary = [1, 2, 4, 2]
- * ary.count #=> 4
- * ary.count(2) #=> 2
- * ary.count { |x| x%2 == 0 } #=> 3
+ * With no argument and a block given, calls the block with each element;
+ * returns the count of elements for which the block returns a truthy value:
+ * [0, 1, 2, 3].count {|element| element > 1} # => 2
*
+ * With argument +obj+ and a block given, issues a warning, ignores the block,
+ * and returns the count of elements <tt>eql?</tt> to +obj+:
*/
static VALUE
@@ -4578,7 +6102,7 @@ rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
long i, n = 0;
- if (argc == 0) {
+ if (rb_check_arity(argc, 0, 1) == 0) {
VALUE v;
if (!rb_block_given_p())
@@ -4590,9 +6114,8 @@ rb_ary_count(int argc, VALUE *argv, VALUE ary)
}
}
else {
- VALUE obj;
+ VALUE obj = argv[0];
- rb_scan_args(argc, argv, "1", &obj);
if (rb_block_given_p()) {
rb_warn("given block not used");
}
@@ -4605,18 +6128,43 @@ rb_ary_count(int argc, VALUE *argv, VALUE ary)
}
static VALUE
-flatten(VALUE ary, int level, int *modified)
+flatten(VALUE ary, int level)
{
- long i = 0;
- VALUE stack, result, tmp, elt;
- st_table *memo;
+ long i;
+ VALUE stack, result, tmp = 0, elt, vmemo;
+ st_table *memo = 0;
st_data_t id;
- stack = ary_new(0, ARY_DEFAULT_SIZE);
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ elt = RARRAY_AREF(ary, i);
+ tmp = rb_check_array_type(elt);
+ if (!NIL_P(tmp)) {
+ break;
+ }
+ }
+ if (i == RARRAY_LEN(ary)) {
+ return ary;
+ }
+
result = ary_new(0, RARRAY_LEN(ary));
- memo = st_init_numtable();
- st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
- *modified = 0;
+ ary_memcpy(result, 0, i, RARRAY_CONST_PTR_TRANSIENT(ary));
+ ARY_SET_LEN(result, i);
+
+ stack = ary_new(0, ARY_DEFAULT_SIZE);
+ rb_ary_push(stack, ary);
+ rb_ary_push(stack, LONG2NUM(i + 1));
+
+ if (level < 0) {
+ vmemo = rb_hash_new();
+ RBASIC_CLEAR_CLASS(vmemo);
+ memo = st_init_numtable();
+ rb_hash_st_table_set(vmemo, memo);
+ st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
+ st_insert(memo, (st_data_t)tmp, (st_data_t)Qtrue);
+ }
+
+ ary = tmp;
+ i = 0;
while (1) {
while (i < RARRAY_LEN(ary)) {
@@ -4627,19 +6175,24 @@ flatten(VALUE ary, int level, int *modified)
}
tmp = rb_check_array_type(elt);
if (RBASIC(result)->klass) {
+ if (memo) {
+ RB_GC_GUARD(vmemo);
+ st_clear(memo);
+ }
rb_raise(rb_eRuntimeError, "flatten reentered");
}
if (NIL_P(tmp)) {
rb_ary_push(result, elt);
}
else {
- *modified = 1;
- id = (st_data_t)tmp;
- if (st_lookup(memo, id, 0)) {
- st_free_table(memo);
- rb_raise(rb_eArgError, "tried to flatten recursive array");
+ if (memo) {
+ id = (st_data_t)tmp;
+ if (st_is_member(memo, id)) {
+ st_clear(memo);
+ rb_raise(rb_eArgError, "tried to flatten recursive array");
+ }
+ st_insert(memo, id, (st_data_t)Qtrue);
}
- st_insert(memo, id, (st_data_t)Qtrue);
rb_ary_push(stack, ary);
rb_ary_push(stack, LONG2NUM(i));
ary = tmp;
@@ -4649,37 +6202,49 @@ flatten(VALUE ary, int level, int *modified)
if (RARRAY_LEN(stack) == 0) {
break;
}
- id = (st_data_t)ary;
- st_delete(memo, &id, 0);
+ if (memo) {
+ id = (st_data_t)ary;
+ st_delete(memo, &id, 0);
+ }
tmp = rb_ary_pop(stack);
i = NUM2LONG(tmp);
ary = rb_ary_pop(stack);
}
- st_free_table(memo);
+ if (memo) {
+ st_clear(memo);
+ }
- RBASIC_SET_CLASS(result, rb_obj_class(ary));
+ RBASIC_SET_CLASS(result, rb_cArray);
return result;
}
/*
* call-seq:
- * ary.flatten! -> ary or nil
- * ary.flatten!(level) -> ary or nil
- *
- * Flattens +self+ in place.
- *
- * Returns +nil+ if no modifications were made (i.e., the array contains no
- * subarrays.)
- *
- * The optional +level+ argument determines the level of recursion to flatten.
- *
- * a = [ 1, 2, [3, [4, 5] ] ]
- * a.flatten! #=> [1, 2, 3, 4, 5]
- * a.flatten! #=> nil
- * a #=> [1, 2, 3, 4, 5]
- * a = [ 1, 2, [3, [4, 5] ] ]
- * a.flatten!(1) #=> [1, 2, 3, [4, 5]]
+ * array.flatten! -> self or nil
+ * array.flatten!(level) -> self or nil
+ *
+ * Replaces each nested \Array in +self+ with the elements from that \Array;
+ * returns +self+ if any changes, +nil+ otherwise.
+ *
+ * With non-negative \Integer argument +level+, flattens recursively through +level+ levels:
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(1) # => [0, 1, [2, 3], 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(2) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(3) # => [0, 1, 2, 3, 4, 5]
+ * [0, 1, 2].flatten!(1) # => nil
+ *
+ * With no argument, a +nil+ argument, or with negative argument +level+, flattens all levels:
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten! # => [0, 1, 2, 3, 4, 5]
+ * [0, 1, 2].flatten! # => nil
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(-1) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(-2) # => [0, 1, 2, 3, 4, 5]
+ * [0, 1, 2].flatten!(-1) # => nil
*/
static VALUE
@@ -4688,14 +6253,13 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
int mod = 0, level = -1;
VALUE result, lv;
- rb_scan_args(argc, argv, "01", &lv);
+ lv = (rb_check_arity(argc, 0, 1) ? argv[0] : Qnil);
rb_ary_modify_check(ary);
if (!NIL_P(lv)) level = NUM2INT(lv);
if (level == 0) return Qnil;
- result = flatten(ary, level, &mod);
- if (mod == 0) {
- ary_discard(result);
+ result = flatten(ary, level);
+ if (result == ary) {
return Qnil;
}
if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
@@ -4707,89 +6271,68 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.flatten -> new_ary
- * ary.flatten(level) -> new_ary
- *
- * Returns a new array that is a one-dimensional flattening of +self+
- * (recursively).
- *
- * That is, for every element that is an array, extract its elements into
- * the new array.
- *
- * The optional +level+ argument determines the level of recursion to
- * flatten.
- *
- * s = [ 1, 2, 3 ] #=> [1, 2, 3]
- * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
- * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
- * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- * a = [ 1, 2, [3, [4, 5] ] ]
- * a.flatten(1) #=> [1, 2, 3, [4, 5]]
+ * array.flatten -> new_array
+ * array.flatten(level) -> new_array
+ *
+ * Returns a new \Array that is a recursive flattening of +self+:
+ * - Each non-Array element is unchanged.
+ * - Each \Array is replaced by its individual elements.
+ *
+ * With non-negative \Integer argument +level+, flattens recursively through +level+ levels:
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(0) # => [0, [1, [2, 3], 4], 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(1) # => [0, 1, [2, 3], 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(2) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(3) # => [0, 1, 2, 3, 4, 5]
+ *
+ * With no argument, a +nil+ argument, or with negative argument +level+, flattens all levels:
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten # => [0, 1, 2, 3, 4, 5]
+ * [0, 1, 2].flatten # => [0, 1, 2]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(-1) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(-2) # => [0, 1, 2, 3, 4, 5]
+ * [0, 1, 2].flatten(-1) # => [0, 1, 2]
*/
static VALUE
rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
{
- int mod = 0, level = -1;
- VALUE result, lv;
+ int level = -1;
+ VALUE result;
- rb_scan_args(argc, argv, "01", &lv);
- if (!NIL_P(lv)) level = NUM2INT(lv);
- if (level == 0) return ary_make_shared_copy(ary);
+ if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
+ level = NUM2INT(argv[0]);
+ if (level == 0) return ary_make_shared_copy(ary);
+ }
- result = flatten(ary, level, &mod);
- OBJ_INFECT(result, ary);
+ result = flatten(ary, level);
+ if (result == ary) {
+ result = ary_make_shared_copy(ary);
+ }
return result;
}
-#define OPTHASH_GIVEN_P(opts) \
- (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
-static ID id_random;
-
#define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
-/*
- * call-seq:
- * ary.shuffle! -> ary
- * ary.shuffle!(random: rng) -> ary
- *
- * Shuffles elements in +self+ in place.
- *
- * a = [ 1, 2, 3 ] #=> [1, 2, 3]
- * a.shuffle! #=> [2, 3, 1]
- * a #=> [2, 3, 1]
- *
- * The optional +rng+ argument will be used as the random number generator.
- *
- * a.shuffle!(random: Random.new(1)) #=> [1, 3, 2]
- */
-
static VALUE
-rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary)
+rb_ary_shuffle_bang(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
{
- VALUE opts, randgen = rb_cRandom;
long i, len;
- if (OPTHASH_GIVEN_P(opts)) {
- VALUE rnd;
- ID keyword_ids[1];
-
- keyword_ids[0] = id_random;
- rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
- if (rnd != Qundef) {
- randgen = rnd;
- }
- }
- rb_check_arity(argc, 0, 0);
rb_ary_modify(ary);
i = len = RARRAY_LEN(ary);
RARRAY_PTR_USE(ary, ptr, {
while (i) {
long j = RAND_UPTO(i);
VALUE tmp;
- if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR(ary)) {
- rb_raise(rb_eRuntimeError, "modified during shuffle");
+ if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR_TRANSIENT(ary)) {
+ rb_raise(rb_eRuntimeError, "modified during shuffle");
}
tmp = ptr[--i];
ptr[i] = ptr[j];
@@ -4799,77 +6342,24 @@ rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary)
return ary;
}
-
-/*
- * call-seq:
- * ary.shuffle -> new_ary
- * ary.shuffle(random: rng) -> new_ary
- *
- * Returns a new array with elements of +self+ shuffled.
- *
- * a = [ 1, 2, 3 ] #=> [1, 2, 3]
- * a.shuffle #=> [2, 3, 1]
- * a #=> [1, 2, 3]
- *
- * The optional +rng+ argument will be used as the random number generator.
- *
- * a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
- */
-
static VALUE
-rb_ary_shuffle(int argc, VALUE *argv, VALUE ary)
+rb_ary_shuffle(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
{
ary = rb_ary_dup(ary);
- rb_ary_shuffle_bang(argc, argv, ary);
+ rb_ary_shuffle_bang(ec, ary, randgen);
return ary;
}
-
-/*
- * call-seq:
- * ary.sample -> obj
- * ary.sample(random: rng) -> obj
- * ary.sample(n) -> new_ary
- * ary.sample(n, random: rng) -> new_ary
- *
- * Choose a random element or +n+ random elements from the array.
- *
- * The elements are chosen by using random and unique indices into the array
- * in order to ensure that an element doesn't repeat itself unless the array
- * already contained duplicate elements.
- *
- * If the array is empty the first form returns +nil+ and the second form
- * returns an empty array.
- *
- * The optional +rng+ argument will be used as the random number generator.
- *
- * a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
- * a.sample #=> 7
- * a.sample(4) #=> [6, 4, 2, 5]
- */
-
-
static VALUE
-rb_ary_sample(int argc, VALUE *argv, VALUE ary)
+rb_ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE to_array)
{
- VALUE nv, result;
- VALUE opts, randgen = rb_cRandom;
+ VALUE result;
long n, len, i, j, k, idx[10];
long rnds[numberof(idx)];
long memo_threshold;
- if (OPTHASH_GIVEN_P(opts)) {
- VALUE rnd;
- ID keyword_ids[1];
-
- keyword_ids[0] = id_random;
- rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
- if (rnd != Qundef) {
- randgen = rnd;
- }
- }
len = RARRAY_LEN(ary);
- if (argc == 0) {
+ if (!to_array) {
if (len < 2)
i = 0;
else
@@ -4877,7 +6367,6 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
return rb_ary_elt(ary, i);
}
- rb_scan_args(argc, argv, "1", &nv);
n = NUM2LONG(nv);
if (n < 0) rb_raise(rb_eArgError, "negative sample number");
if (n > len) n = len;
@@ -4899,7 +6388,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
return rb_ary_new_capa(0);
case 1:
i = rnds[0];
- return rb_ary_new_from_values(1, &RARRAY_AREF(ary, i));
+ return rb_ary_new_from_args(1, RARRAY_AREF(ary, i));
case 2:
i = rnds[0];
j = rnds[1];
@@ -4934,7 +6423,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
sorted[j] = idx[i] = k;
}
result = rb_ary_new_capa(n);
- RARRAY_PTR_USE(result, ptr_result, {
+ RARRAY_PTR_USE_TRANSIENT(result, ptr_result, {
for (i=0; i<n; i++) {
ptr_result[i] = RARRAY_AREF(ary, idx[i]);
}
@@ -4944,7 +6433,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
long max_idx = 0;
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
- VALUE vmemo = Data_Wrap_Struct(0, 0, 0, st_free_table);
+ VALUE vmemo = Data_Wrap_Struct(0, 0, st_free_table, 0);
st_table *memo = st_init_numtable_with_size(n);
DATA_PTR(vmemo) = memo;
result = rb_ary_new_capa(n);
@@ -4957,7 +6446,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
len = RARRAY_LEN(ary);
if (len <= max_idx) n = 0;
else if (n > len) n = len;
- RARRAY_PTR_USE(ary, ptr_ary, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr_ary, {
for (i=0; i<n; i++) {
long j2 = j = ptr_result[i];
long i2 = i;
@@ -5000,7 +6489,7 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
n = RARRAY_AREF(args, 0);
}
if (RARRAY_LEN(self) == 0) return INT2FIX(0);
- if (n == Qnil) return DBL2NUM(INFINITY);
+ if (n == Qnil) return DBL2NUM(HUGE_VAL);
mul = NUM2LONG(n);
if (mul <= 0) return INT2FIX(0);
n = LONG2FIX(mul);
@@ -5009,38 +6498,46 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.cycle(n=nil) { |obj| block } -> nil
- * ary.cycle(n=nil) -> Enumerator
- *
- * Calls the given block for each element +n+ times or forever if +nil+ is
- * given.
- *
- * Does nothing if a non-positive number is given or the array is empty.
- *
- * Returns +nil+ if the loop has finished without getting interrupted.
- *
- * If no block is given, an Enumerator is returned instead.
- *
- * a = ["a", "b", "c"]
- * a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever.
- * a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
- *
+ * array.cycle {|element| ... } -> nil
+ * array.cycle(count) {|element| ... } -> nil
+ * array.cycle -> new_enumerator
+ * array.cycle(count) -> new_enumerator
+ *
+ * When called with positive \Integer argument +count+ and a block,
+ * calls the block with each element, then does so again,
+ * until it has done so +count+ times; returns +nil+:
+ * output = []
+ * [0, 1].cycle(2) {|element| output.push(element) } # => nil
+ * output # => [0, 1, 0, 1]
+ *
+ * If +count+ is zero or negative, does not call the block:
+ * [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil
+ * [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil
+ *
+ * When a block is given, and argument is omitted or +nil+, cycles forever:
+ * # Prints 0 and 1 forever.
+ * [0, 1].cycle {|element| puts element }
+ * [0, 1].cycle(nil) {|element| puts element }
+ *
+ * When no block is given, returns a new \Enumerator:
+ *
+ * [0, 1].cycle(2) # => #<Enumerator: [0, 1]:cycle(2)>
+ * [0, 1].cycle # => # => #<Enumerator: [0, 1]:cycle>
+ * [0, 1].cycle.first(5) # => [0, 1, 0, 1, 0]
*/
-
static VALUE
rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
{
long n, i;
- VALUE nv = Qnil;
- rb_scan_args(argc, argv, "01", &nv);
+ rb_check_arity(argc, 0, 1);
RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
- if (NIL_P(nv)) {
+ if (argc == 0 || NIL_P(argv[0])) {
n = -1;
}
else {
- n = NUM2LONG(nv);
+ n = NUM2LONG(argv[0]);
if (n <= 0) return Qnil;
}
@@ -5052,8 +6549,6 @@ rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
return Qnil;
}
-#define tmpbuf(n, size) rb_str_tmp_new((n)*(size))
-#define tmpbuf_discard(s) (rb_str_resize((s), 0L), RBASIC_SET_CLASS_RAW(s, rb_cString))
#define tmpary(n) rb_ary_tmp_new(n)
#define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray))
@@ -5066,11 +6561,9 @@ static int
yield_indexed_values(const VALUE values, const long r, const long *const p)
{
const VALUE result = rb_ary_new2(r);
- VALUE *const result_array = RARRAY_PTR(result);
- const VALUE *const values_array = RARRAY_CONST_PTR(values);
long i;
- for (i = 0; i < r; i++) result_array[i] = values_array[p[i]];
+ for (i = 0; i < r; i++) ARY_SET(result, i, RARRAY_AREF(values, p[i]));
ARY_SET_LEN(result, r);
rb_yield(result);
return !RBASIC(values)->klass;
@@ -5125,7 +6618,7 @@ permute0(const long n, const long r, long *const p, char *const used, const VALU
/*
* Returns the product of from, from-1, ..., from - how_many + 1.
- * http://en.wikipedia.org/wiki/Pochhammer_symbol
+ * https://en.wikipedia.org/wiki/Pochhammer_symbol
*/
static VALUE
descending_factorial(long from, long how_many)
@@ -5177,42 +6670,78 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.permutation { |p| block } -> ary
- * ary.permutation -> Enumerator
- * ary.permutation(n) { |p| block } -> ary
- * ary.permutation(n) -> Enumerator
- *
- * When invoked with a block, yield all permutations of length +n+ of the
- * elements of the array, then return the array itself.
- *
- * If +n+ is not specified, yield all permutations of all elements.
- *
- * The implementation makes no guarantees about the order in which the
- * permutations are yielded.
- *
- * If no block is given, an Enumerator is returned instead.
- *
- * Examples:
- *
- * a = [1, 2, 3]
- * a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
- * a.permutation(1).to_a #=> [[1],[2],[3]]
- * a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
- * a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
- * a.permutation(0).to_a #=> [[]] # one permutation of length 0
- * a.permutation(4).to_a #=> [] # no permutations of length 4
+ * array.permutation {|element| ... } -> self
+ * array.permutation(n) {|element| ... } -> self
+ * array.permutation -> new_enumerator
+ * array.permutation(n) -> new_enumerator
+ *
+ * When invoked with a block, yield all permutations of elements of +self+; returns +self+.
+ * The order of permutations is indeterminate.
+ *
+ * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>)
+ * are given, calls the block with all +n+-tuple permutations of +self+.
+ *
+ * Example:
+ * a = [0, 1, 2]
+ * a.permutation(2) {|permutation| p permutation }
+ * Output:
+ * [0, 1]
+ * [0, 2]
+ * [1, 0]
+ * [1, 2]
+ * [2, 0]
+ * [2, 1]
+ * Another example:
+ * a = [0, 1, 2]
+ * a.permutation(3) {|permutation| p permutation }
+ * Output:
+ * [0, 1, 2]
+ * [0, 2, 1]
+ * [1, 0, 2]
+ * [1, 2, 0]
+ * [2, 0, 1]
+ * [2, 1, 0]
+ *
+ * When +n+ is zero, calls the block once with a new empty \Array:
+ * a = [0, 1, 2]
+ * a.permutation(0) {|permutation| p permutation }
+ * Output:
+ * []
+ *
+ * When +n+ is out of range (negative or larger than <tt>self.size</tt>),
+ * does not call the block:
+ * a = [0, 1, 2]
+ * a.permutation(-1) {|permutation| fail 'Cannot happen' }
+ * a.permutation(4) {|permutation| fail 'Cannot happen' }
+ *
+ * When a block given but no argument,
+ * behaves the same as <tt>a.permutation(a.size)</tt>:
+ * a = [0, 1, 2]
+ * a.permutation {|permutation| p permutation }
+ * Output:
+ * [0, 1, 2]
+ * [0, 2, 1]
+ * [1, 0, 2]
+ * [1, 2, 0]
+ * [2, 0, 1]
+ * [2, 1, 0]
+ *
+ * Returns a new \Enumerator if no block given:
+ * a = [0, 1, 2]
+ * a.permutation # => #<Enumerator: [0, 1, 2]:permutation>
+ * a.permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
*/
static VALUE
rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
{
- VALUE num;
long r, n, i;
n = RARRAY_LEN(ary); /* Array length */
RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size); /* Return enumerator if no block */
- rb_scan_args(argc, argv, "01", &num);
- r = NIL_P(num) ? n : NUM2LONG(num); /* Permutation size from argument */
+ r = n;
+ if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))
+ r = NUM2LONG(argv[0]); /* Permutation size from argument */
if (r < 0 || n < r) {
/* no permutations: yield nothing */
@@ -5273,27 +6802,44 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.combination(n) { |c| block } -> ary
- * ary.combination(n) -> Enumerator
- *
- * When invoked with a block, yields all combinations of length +n+ of elements
- * from the array and then returns the array itself.
- *
- * The implementation makes no guarantees about the order in which the
- * combinations are yielded.
- *
- * If no block is given, an Enumerator is returned instead.
- *
- * Examples:
- *
- * a = [1, 2, 3, 4]
- * a.combination(1).to_a #=> [[1],[2],[3],[4]]
- * a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
- * a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
- * a.combination(4).to_a #=> [[1,2,3,4]]
- * a.combination(0).to_a #=> [[]] # one combination of length 0
- * a.combination(5).to_a #=> [] # no combinations of length 5
- *
+ * array.combination(n) {|element| ... } -> self
+ * array.combination(n) -> new_enumerator
+ *
+ * Calls the block, if given, with combinations of elements of +self+;
+ * returns +self+. The order of combinations is indeterminate.
+ *
+ * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>)
+ * are given, calls the block with all +n+-tuple combinations of +self+.
+ *
+ * Example:
+ * a = [0, 1, 2]
+ * a.combination(2) {|combination| p combination }
+ * Output:
+ * [0, 1]
+ * [0, 2]
+ * [1, 2]
+ *
+ * Another example:
+ * a = [0, 1, 2]
+ * a.combination(3) {|combination| p combination }
+ * Output:
+ * [0, 1, 2]
+ *
+ * When +n+ is zero, calls the block once with a new empty \Array:
+ * a = [0, 1, 2]
+ * a1 = a.combination(0) {|combination| p combination }
+ * Output:
+ * []
+ *
+ * When +n+ is out of range (negative or larger than <tt>self.size</tt>),
+ * does not call the block:
+ * a = [0, 1, 2]
+ * a.combination(-1) {|combination| fail 'Cannot happen' }
+ * a.combination(4) {|combination| fail 'Cannot happen' }
+ *
+ * Returns a new \Enumerator if no block given:
+ * a = [0, 1, 2]
+ * a.combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
*/
static VALUE
@@ -5380,27 +6926,59 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.repeated_permutation(n) { |p| block } -> ary
- * ary.repeated_permutation(n) -> Enumerator
- *
- * When invoked with a block, yield all repeated permutations of length +n+ of
- * the elements of the array, then return the array itself.
- *
- * The implementation makes no guarantees about the order in which the repeated
- * permutations are yielded.
- *
- * If no block is given, an Enumerator is returned instead.
- *
- * Examples:
- *
- * a = [1, 2]
- * a.repeated_permutation(1).to_a #=> [[1], [2]]
- * a.repeated_permutation(2).to_a #=> [[1,1],[1,2],[2,1],[2,2]]
- * a.repeated_permutation(3).to_a #=> [[1,1,1],[1,1,2],[1,2,1],[1,2,2],
- * # [2,1,1],[2,1,2],[2,2,1],[2,2,2]]
- * a.repeated_permutation(0).to_a #=> [[]] # one permutation of length 0
+ * array.repeated_permutation(n) {|permutation| ... } -> self
+ * array.repeated_permutation(n) -> new_enumerator
+ *
+ * Calls the block with each repeated permutation of length +n+ of the elements of +self+;
+ * each permutation is an \Array;
+ * returns +self+. The order of the permutations is indeterminate.
+ *
+ * When a block and a positive \Integer argument +n+ are given, calls the block with each
+ * +n+-tuple repeated permutation of the elements of +self+.
+ * The number of permutations is <tt>self.size**n</tt>.
+ *
+ * +n+ = 1:
+ * a = [0, 1, 2]
+ * a.repeated_permutation(1) {|permutation| p permutation }
+ * Output:
+ * [0]
+ * [1]
+ * [2]
+ *
+ * +n+ = 2:
+ * a.repeated_permutation(2) {|permutation| p permutation }
+ * Output:
+ * [0, 0]
+ * [0, 1]
+ * [0, 2]
+ * [1, 0]
+ * [1, 1]
+ * [1, 2]
+ * [2, 0]
+ * [2, 1]
+ * [2, 2]
+ *
+ * If +n+ is zero, calls the block once with an empty \Array.
+ *
+ * If +n+ is negative, does not call the block:
+ * a.repeated_permutation(-1) {|permutation| fail 'Cannot happen' }
+ *
+ * Returns a new \Enumerator if no block given:
+ * a = [0, 1, 2]
+ * a.repeated_permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
+ *
+ * Using Enumerators, it's convenient to show the permutations and counts
+ * for some values of +n+:
+ * e = a.repeated_permutation(0)
+ * e.size # => 1
+ * e.to_a # => [[]]
+ * e = a.repeated_permutation(1)
+ * e.size # => 3
+ * e.to_a # => [[0], [1], [2]]
+ * e = a.repeated_permutation(2)
+ * e.size # => 9
+ * e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
*/
-
static VALUE
rb_ary_repeated_permutation(VALUE ary, VALUE num)
{
@@ -5470,29 +7048,55 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.repeated_combination(n) { |c| block } -> ary
- * ary.repeated_combination(n) -> Enumerator
- *
- * When invoked with a block, yields all repeated combinations of length +n+ of
- * elements from the array and then returns the array itself.
- *
- * The implementation makes no guarantees about the order in which the repeated
- * combinations are yielded.
- *
- * If no block is given, an Enumerator is returned instead.
- *
- * Examples:
- *
- * a = [1, 2, 3]
- * a.repeated_combination(1).to_a #=> [[1], [2], [3]]
- * a.repeated_combination(2).to_a #=> [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]]
- * a.repeated_combination(3).to_a #=> [[1,1,1],[1,1,2],[1,1,3],[1,2,2],[1,2,3],
- * # [1,3,3],[2,2,2],[2,2,3],[2,3,3],[3,3,3]]
- * a.repeated_combination(4).to_a #=> [[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,2,2],[1,1,2,3],
- * # [1,1,3,3],[1,2,2,2],[1,2,2,3],[1,2,3,3],[1,3,3,3],
- * # [2,2,2,2],[2,2,2,3],[2,2,3,3],[2,3,3,3],[3,3,3,3]]
- * a.repeated_combination(0).to_a #=> [[]] # one combination of length 0
- *
+ * array.repeated_combination(n) {|combination| ... } -> self
+ * array.repeated_combination(n) -> new_enumerator
+ *
+ * Calls the block with each repeated combination of length +n+ of the elements of +self+;
+ * each combination is an \Array;
+ * returns +self+. The order of the combinations is indeterminate.
+ *
+ * When a block and a positive \Integer argument +n+ are given, calls the block with each
+ * +n+-tuple repeated combination of the elements of +self+.
+ * The number of combinations is <tt>(n+1)(n+2)/2</tt>.
+ *
+ * +n+ = 1:
+ * a = [0, 1, 2]
+ * a.repeated_combination(1) {|combination| p combination }
+ * Output:
+ * [0]
+ * [1]
+ * [2]
+ *
+ * +n+ = 2:
+ * a.repeated_combination(2) {|combination| p combination }
+ * Output:
+ * [0, 0]
+ * [0, 1]
+ * [0, 2]
+ * [1, 1]
+ * [1, 2]
+ * [2, 2]
+ *
+ * If +n+ is zero, calls the block once with an empty \Array.
+ *
+ * If +n+ is negative, does not call the block:
+ * a.repeated_combination(-1) {|combination| fail 'Cannot happen' }
+ *
+ * Returns a new \Enumerator if no block given:
+ * a = [0, 1, 2]
+ * a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
+ *
+ * Using Enumerators, it's convenient to show the combinations and counts
+ * for some values of +n+:
+ * e = a.repeated_combination(0)
+ * e.size # => 1
+ * e.to_a # => [[]]
+ * e = a.repeated_combination(1)
+ * e.size # => 3
+ * e.to_a # => [[0], [1], [2]]
+ * e = a.repeated_combination(2)
+ * e.size # => 6
+ * e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
*/
static VALUE
@@ -5532,23 +7136,51 @@ rb_ary_repeated_combination(VALUE ary, VALUE num)
/*
* call-seq:
- * ary.product(other_ary, ...) -> new_ary
- * ary.product(other_ary, ...) { |p| block } -> ary
- *
- * Returns an array of all combinations of elements from all arrays.
- *
- * The length of the returned array is the product of the length of +self+ and
- * the argument arrays.
- *
- * If given a block, #product will yield all combinations and return +self+
- * instead.
- *
- * [1,2,3].product([4,5]) #=> [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
- * [1,2].product([1,2]) #=> [[1,1],[1,2],[2,1],[2,2]]
- * [1,2].product([3,4],[5,6]) #=> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
- * # [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
- * [1,2].product() #=> [[1],[2]]
- * [1,2].product([]) #=> []
+ * array.product(*other_arrays) -> new_array
+ * array.product(*other_arrays) {|combination| ... } -> self
+ *
+ * Computes and returns or yields all combinations of elements from all the Arrays,
+ * including both +self+ and +other_arrays+.
+ * - The number of combinations is the product of the sizes of all the arrays,
+ * including both +self+ and +other_arrays+.
+ * - The order of the returned combinations is indeterminate.
+ *
+ * When no block is given, returns the combinations as an \Array of Arrays:
+ * a = [0, 1, 2]
+ * a1 = [3, 4]
+ * a2 = [5, 6]
+ * p = a.product(a1)
+ * p.size # => 6 # a.size * a1.size
+ * p # => [[0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4]]
+ * p = a.product(a1, a2)
+ * p.size # => 12 # a.size * a1.size * a2.size
+ * p # => [[0, 3, 5], [0, 3, 6], [0, 4, 5], [0, 4, 6], [1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]
+ *
+ * If any argument is an empty \Array, returns an empty \Array.
+ *
+ * If no argument is given, returns an \Array of 1-element Arrays,
+ * each containing an element of +self+:
+ * a.product # => [[0], [1], [2]]
+ *
+ * When a block is given, yields each combination as an \Array; returns +self+:
+ * a.product(a1) {|combination| p combination }
+ * Output:
+ * [0, 3]
+ * [0, 4]
+ * [1, 3]
+ * [1, 4]
+ * [2, 3]
+ * [2, 4]
+ *
+ * If any argument is an empty \Array, does not call the block:
+ * a.product(a1, a2, []) {|combination| fail 'Cannot happen' }
+ *
+ * If no argument is given, yields each element of +self+ as a 1-element \Array:
+ * a.product {|combination| p combination }
+ * Output:
+ * [0]
+ * [1]
+ * [2]
*/
static VALUE
@@ -5556,15 +7188,14 @@ rb_ary_product(int argc, VALUE *argv, VALUE ary)
{
int n = argc+1; /* How many arrays we're operating on */
volatile VALUE t0 = tmpary(n);
- volatile VALUE t1 = tmpbuf(n, sizeof(int));
+ volatile VALUE t1 = Qundef;
VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
- int *counters = (int*)RSTRING_PTR(t1); /* The current position in each one */
+ int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */
VALUE result = Qnil; /* The array we'll be returning, when no block given */
long i,j;
long resultlen = 1;
RBASIC_CLEAR_CLASS(t0);
- RBASIC_CLEAR_CLASS(t1);
/* initialize the arrays of arrays */
ARY_SET_LEN(t0, n);
@@ -5635,24 +7266,25 @@ rb_ary_product(int argc, VALUE *argv, VALUE ary)
}
done:
tmpary_discard(t0);
- tmpbuf_discard(t1);
+ ALLOCV_END(t1);
return NIL_P(result) ? ary : result;
}
/*
* call-seq:
- * ary.take(n) -> new_ary
- *
- * Returns first +n+ elements from the array.
- *
- * If a negative number is given, raises an ArgumentError.
- *
- * See also Array#drop
- *
- * a = [1, 2, 3, 4, 5, 0]
- * a.take(3) #=> [1, 2, 3]
- *
+ * array.take(n) -> new_array
+ *
+ * Returns a new \Array containing the first +n+ element of +self+,
+ * where +n+ is a non-negative \Integer;
+ * does not modify +self+.
+ *
+ * Examples:
+ * a = [0, 1, 2, 3, 4, 5]
+ * a.take(1) # => [0]
+ * a.take(2) # => [0, 1]
+ * a.take(50) # => [0, 1, 2, 3, 4, 5]
+ * a # => [0, 1, 2, 3, 4, 5]
*/
static VALUE
@@ -5667,19 +7299,22 @@ rb_ary_take(VALUE obj, VALUE n)
/*
* call-seq:
- * ary.take_while { |obj| block } -> new_ary
- * ary.take_while -> Enumerator
- *
- * Passes elements to the block until the block returns +nil+ or +false+, then
- * stops iterating and returns an array of all prior elements.
- *
- * If no block is given, an Enumerator is returned instead.
- *
- * See also Array#drop_while
- *
- * a = [1, 2, 3, 4, 5, 0]
- * a.take_while { |i| i < 3 } #=> [1, 2]
- *
+ * array.take_while {|element| ... } -> new_array
+ * array.take_while -> new_enumerator
+ *
+ * Returns a new \Array containing zero or more leading elements of +self+;
+ * does not modify +self+.
+ *
+ * With a block given, calls the block with each successive element of +self+;
+ * stops if the block returns +false+ or +nil+;
+ * returns a new Array containing those elements for which the block returned a truthy value:
+ * a = [0, 1, 2, 3, 4, 5]
+ * a.take_while {|element| element < 3 } # => [0, 1, 2]
+ * a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5]
+ * a # => [0, 1, 2, 3, 4, 5]
+ *
+ * With no block given, returns a new \Enumerator:
+ * [0, 1].take_while # => #<Enumerator: [0, 1]:take_while>
*/
static VALUE
@@ -5696,18 +7331,17 @@ rb_ary_take_while(VALUE ary)
/*
* call-seq:
- * ary.drop(n) -> new_ary
- *
- * Drops first +n+ elements from +ary+ and returns the rest of the elements in
- * an array.
+ * array.drop(n) -> new_array
*
- * If a negative number is given, raises an ArgumentError.
- *
- * See also Array#take
- *
- * a = [1, 2, 3, 4, 5, 0]
- * a.drop(3) #=> [4, 5, 0]
+ * Returns a new \Array containing all but the first +n+ element of +self+,
+ * where +n+ is a non-negative \Integer;
+ * does not modify +self+.
*
+ * Examples:
+ * a = [0, 1, 2, 3, 4, 5]
+ * a.drop(0) # => [0, 1, 2, 3, 4, 5]
+ * a.drop(1) # => [1, 2, 3, 4, 5]
+ * a.drop(2) # => [2, 3, 4, 5]
*/
static VALUE
@@ -5726,20 +7360,20 @@ rb_ary_drop(VALUE ary, VALUE n)
/*
* call-seq:
- * ary.drop_while { |obj| block } -> new_ary
- * ary.drop_while -> Enumerator
- *
- * Drops elements up to, but not including, the first element for which the
- * block returns +nil+ or +false+ and returns an array containing the
- * remaining elements.
- *
- * If no block is given, an Enumerator is returned instead.
- *
- * See also Array#take_while
+ * array.drop_while {|element| ... } -> new_array
+ * array.drop_while -> new_enumerator
+
+ * Returns a new \Array containing zero or more trailing elements of +self+;
+ * does not modify +self+.
*
- * a = [1, 2, 3, 4, 5, 0]
- * a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
+ * With a block given, calls the block with each successive element of +self+;
+ * stops if the block returns +false+ or +nil+;
+ * returns a new Array _omitting_ those elements for which the block returned a truthy value:
+ * a = [0, 1, 2, 3, 4, 5]
+ * a.drop_while {|element| element < 3 } # => [3, 4, 5]
*
+ * With no block given, returns a new \Enumerator:
+ * [0, 1].drop_while # => # => #<Enumerator: [0, 1]:drop_while>
*/
static VALUE
@@ -5756,20 +7390,53 @@ rb_ary_drop_while(VALUE ary)
/*
* call-seq:
- * ary.any? [{ |obj| block }] -> true or false
- *
- * See also Enumerable#any?
+ * array.any? -> true or false
+ * array.any? {|element| ... } -> true or false
+ * array.any?(obj) -> true or false
+ *
+ * Returns +true+ if any element of +self+ meets a given criterion.
+ *
+ * With no block given and no argument, returns +true+ if +self+ has any truthy element,
+ * +false+ otherwise:
+ * [nil, 0, false].any? # => true
+ * [nil, false].any? # => false
+ * [].any? # => false
+ *
+ * With a block given and no argument, calls the block with each element in +self+;
+ * returns +true+ if the block returns any truthy value, +false+ otherwise:
+ * [0, 1, 2].any? {|element| element > 1 } # => true
+ * [0, 1, 2].any? {|element| element > 2 } # => false
+ *
+ * If argument +obj+ is given, returns +true+ if +obj+.<tt>===</tt> any element,
+ * +false+ otherwise:
+ * ['food', 'drink'].any?(/foo/) # => true
+ * ['food', 'drink'].any?(/bar/) # => false
+ * [].any?(/foo/) # => false
+ * [0, 1, 2].any?(1) # => true
+ * [0, 1, 2].any?(3) # => false
+ *
+ * Related: Enumerable#any?
*/
static VALUE
-rb_ary_any_p(VALUE ary)
+rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
{
long i, len = RARRAY_LEN(ary);
- const VALUE *ptr = RARRAY_CONST_PTR(ary);
+ rb_check_arity(argc, 0, 1);
if (!len) return Qfalse;
- if (!rb_block_given_p()) {
- for (i = 0; i < len; ++i) if (RTEST(ptr[i])) return Qtrue;
+ if (argc) {
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
+ }
+ }
+ else if (!rb_block_given_p()) {
+ for (i = 0; i < len; ++i) {
+ if (RTEST(RARRAY_AREF(ary, i))) return Qtrue;
+ }
}
else {
for (i = 0; i < RARRAY_LEN(ary); ++i) {
@@ -5780,22 +7447,208 @@ rb_ary_any_p(VALUE ary)
}
/*
- * call-seq:
- * ary.dig(idx, ...) -> object
- *
- * Extracts the nested value specified by the sequence of <i>idx</i>
- * objects by calling +dig+ at each step, returning +nil+ if any
- * intermediate step is +nil+.
- *
- * a = [[1, [2, 3]]]
- *
- * a.dig(0, 1, 1) #=> 3
- * a.dig(1, 2, 3) #=> nil
- * a.dig(0, 0, 0) #=> TypeError: Integer does not have #dig method
- * [42, {foo: :bar}].dig(1, :foo) #=> :bar
+ * call-seq:
+ * array.all? -> true or false
+ * array.all? {|element| ... } -> true or false
+ * array.all?(obj) -> true or false
+ *
+ * Returns +true+ if all elements of +self+ meet a given criterion.
+ *
+ * With no block given and no argument, returns +true+ if +self+ contains only truthy elements,
+ * +false+ otherwise:
+ * [0, 1, :foo].all? # => true
+ * [0, nil, 2].all? # => false
+ * [].all? # => true
+ *
+ * With a block given and no argument, calls the block with each element in +self+;
+ * returns +true+ if the block returns only truthy values, +false+ otherwise:
+ * [0, 1, 2].all? { |element| element < 3 } # => true
+ * [0, 1, 2].all? { |element| element < 2 } # => false
+ *
+ * If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> every element, +false+ otherwise:
+ * ['food', 'fool', 'foot'].all?(/foo/) # => true
+ * ['food', 'drink'].all?(/bar/) # => false
+ * [].all?(/foo/) # => true
+ * [0, 0, 0].all?(0) # => true
+ * [0, 1, 2].all?(1) # => false
+ *
+ * Related: Enumerable#all?
*/
-VALUE
+static VALUE
+rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
+{
+ long i, len = RARRAY_LEN(ary);
+
+ rb_check_arity(argc, 0, 1);
+ if (!len) return Qtrue;
+ if (argc) {
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
+ }
+ }
+ else if (!rb_block_given_p()) {
+ for (i = 0; i < len; ++i) {
+ if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;
+ }
+ }
+ else {
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
+ }
+ }
+ return Qtrue;
+}
+
+/*
+ * call-seq:
+ * array.none? -> true or false
+ * array.none? {|element| ... } -> true or false
+ * array.none?(obj) -> true or false
+ *
+ * Returns +true+ if no element of +self+ meet a given criterion.
+ *
+ * With no block given and no argument, returns +true+ if +self+ has no truthy elements,
+ * +false+ otherwise:
+ * [nil, false].none? # => true
+ * [nil, 0, false].none? # => false
+ * [].none? # => true
+ *
+ * With a block given and no argument, calls the block with each element in +self+;
+ * returns +true+ if the block returns no truthy value, +false+ otherwise:
+ * [0, 1, 2].none? {|element| element > 3 } # => true
+ * [0, 1, 2].none? {|element| element > 1 } # => false
+ *
+ * If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> no element, +false+ otherwise:
+ * ['food', 'drink'].none?(/bar/) # => true
+ * ['food', 'drink'].none?(/foo/) # => false
+ * [].none?(/foo/) # => true
+ * [0, 1, 2].none?(3) # => true
+ * [0, 1, 2].none?(1) # => false
+ *
+ * Related: Enumerable#none?
+ */
+
+static VALUE
+rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
+{
+ long i, len = RARRAY_LEN(ary);
+
+ rb_check_arity(argc, 0, 1);
+ if (!len) return Qtrue;
+ if (argc) {
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
+ }
+ }
+ else if (!rb_block_given_p()) {
+ for (i = 0; i < len; ++i) {
+ if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;
+ }
+ }
+ else {
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
+ }
+ }
+ return Qtrue;
+}
+
+/*
+ * call-seq:
+ * array.one? -> true or false
+ * array.one? {|element| ... } -> true or false
+ * array.one?(obj) -> true or false
+ *
+ * Returns +true+ if exactly one element of +self+ meets a given criterion.
+ *
+ * With no block given and no argument, returns +true+ if +self+ has exactly one truthy element,
+ * +false+ otherwise:
+ * [nil, 0].one? # => true
+ * [0, 0].one? # => false
+ * [nil, nil].one? # => false
+ * [].one? # => false
+ *
+ * With a block given and no argument, calls the block with each element in +self+;
+ * returns +true+ if the block a truthy value for exactly one element, +false+ otherwise:
+ * [0, 1, 2].one? {|element| element > 0 } # => false
+ * [0, 1, 2].one? {|element| element > 1 } # => true
+ * [0, 1, 2].one? {|element| element > 2 } # => false
+ *
+ * If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> exactly one element,
+ * +false+ otherwise:
+ * [0, 1, 2].one?(0) # => true
+ * [0, 0, 1].one?(0) # => false
+ * [1, 1, 2].one?(0) # => false
+ * ['food', 'drink'].one?(/bar/) # => false
+ * ['food', 'drink'].one?(/foo/) # => true
+ * [].one?(/foo/) # => false
+ *
+ * Related: Enumerable#one?
+ */
+
+static VALUE
+rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
+{
+ long i, len = RARRAY_LEN(ary);
+ VALUE result = Qfalse;
+
+ rb_check_arity(argc, 0, 1);
+ if (!len) return Qfalse;
+ if (argc) {
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {
+ if (result) return Qfalse;
+ result = Qtrue;
+ }
+ }
+ }
+ else if (!rb_block_given_p()) {
+ for (i = 0; i < len; ++i) {
+ if (RTEST(RARRAY_AREF(ary, i))) {
+ if (result) return Qfalse;
+ result = Qtrue;
+ }
+ }
+ }
+ else {
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
+ if (result) return Qfalse;
+ result = Qtrue;
+ }
+ }
+ }
+ return result;
+}
+
+/*
+ * call-seq:
+ * array.dig(index, *identifiers) -> object
+ *
+ * Finds and returns the object in nested objects
+ * that is specified by +index+ and +identifiers+.
+ * The nested objects may be instances of various classes.
+ * See {Dig Methods}[rdoc-ref:doc/dig_methods.rdoc].
+ *
+ * Examples:
+ * a = [:foo, [:bar, :baz, [:bat, :bam]]]
+ * a.dig(1) # => [:bar, :baz, [:bat, :bam]]
+ * a.dig(1, 2) # => [:bat, :bam]
+ * a.dig(1, 2, 0) # => :bat
+ * a.dig(1, 2, 3) # => nil
+ */
+
+static VALUE
rb_ary_dig(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
@@ -5811,13 +7664,7 @@ finish_exact_sum(long n, VALUE r, VALUE v, int z)
if (n != 0)
v = rb_fix_plus(LONG2FIX(n), v);
if (r != Qundef) {
- /* r can be an Integer when mathn is loaded */
- if (FIXNUM_P(r))
- v = rb_fix_plus(r, v);
- else if (RB_TYPE_P(r, T_BIGNUM))
- v = rb_big_plus(r, v);
- else
- v = rb_rational_plus(r, v);
+ v = rb_rational_plus(r, v);
}
else if (!n && z) {
v = rb_fix_plus(LONG2FIX(0), v);
@@ -5827,44 +7674,35 @@ finish_exact_sum(long n, VALUE r, VALUE v, int z)
/*
* call-seq:
- * ary.sum(init=0) -> number
- * ary.sum(init=0) {|e| expr } -> number
- *
- * Returns the sum of elements.
- * For example, [e1, e2, e3].sum returns init + e1 + e2 + e3.
- *
- * If a block is given, the block is applied to each element
- * before addition.
- *
- * If <i>ary</i> is empty, it returns <i>init</i>.
- *
- * [].sum #=> 0
- * [].sum(0.0) #=> 0.0
- * [1, 2, 3].sum #=> 6
- * [3, 5.5].sum #=> 8.5
- * [2.5, 3.0].sum(0.0) {|e| e * e } #=> 15.25
- * [Object.new].sum #=> TypeError
- *
- * The (arithmetic) mean value of an array can be obtained as follows.
- *
- * mean = ary.sum(0.0) / ary.length
- *
- * This method can be used for non-numeric objects by
- * explicit <i>init</i> argument.
- *
- * ["a", "b", "c"].sum("") #=> "abc"
- * [[1], [[2]], [3]].sum([]) #=> [1, [2], 3]
- *
- * However, Array#join and Array#flatten is faster than Array#sum for
- * array of strings and array of arrays.
- *
- * ["a", "b", "c"].join #=> "abc"
- * [[1], [[2]], [3]].flatten(1) #=> [1, [2], 3]
- *
- *
- * Array#sum method may not respect method redefinition of "+" methods
- * such as Integer#+.
- *
+ * array.sum(init = 0) -> object
+ * array.sum(init = 0) {|element| ... } -> object
+ *
+ * When no block is given, returns the object equivalent to:
+ * sum = init
+ * array.each {|element| sum += element }
+ * sum
+ * For example, <tt>[e1, e2, e3].sum</tt> returns </tt>init + e1 + e2 + e3</tt>.
+ *
+ * Examples:
+ * a = [0, 1, 2, 3]
+ * a.sum # => 6
+ * a.sum(100) # => 106
+ *
+ * The elements need not be numeric, but must be <tt>+</tt>-compatible
+ * with each other and with +init+:
+ * a = ['abc', 'def', 'ghi']
+ * a.sum('jkl') # => "jklabcdefghi"
+ *
+ * When a block is given, it is called with each element
+ * and the block's return value (instead of the element itself) is used as the addend:
+ * a = ['zero', 1, :two]
+ * s = a.sum('Coerced and concatenated: ') {|element| element.to_s }
+ * s # => "Coerced and concatenated: zero1two"
+ *
+ * Notes:
+ * - Array#join and Array#flatten may be faster than Array#sum
+ * for an \Array of Strings or an \Array of Arrays.
+ * - Array#sum method may not respect method redefinition of "+" methods such as Integer#+.
*/
static VALUE
@@ -5874,8 +7712,7 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
long i, n;
int block_given;
- if (rb_scan_args(argc, argv, "01", &v) == 0)
- v = LONG2FIX(0);
+ v = (rb_check_arity(argc, 0, 1) ? argv[0] : LONG2FIX(0));
block_given = rb_block_given_p();
@@ -5915,15 +7752,15 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
if (RB_FLOAT_TYPE_P(e)) {
/*
* Kahan-Babuska balancing compensated summation algorithm
- * See http://link.springer.com/article/10.1007/s00607-005-0139-x
+ * See https://link.springer.com/article/10.1007/s00607-005-0139-x
*/
double f, c;
+ double x, t;
f = NUM2DBL(v);
c = 0.0;
goto has_float_value;
for (; i < RARRAY_LEN(ary); i++) {
- double x, t;
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
@@ -5939,6 +7776,20 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
else
goto not_float;
+ if (isnan(f)) continue;
+ if (isnan(x)) {
+ f = x;
+ continue;
+ }
+ if (isinf(x)) {
+ if (isinf(f) && signbit(x) != signbit(f))
+ f = NAN;
+ else
+ f = x;
+ continue;
+ }
+ if (isinf(f)) continue;
+
t = f + x;
if (fabs(f) >= fabs(x))
c += ((f - t) + x);
@@ -5964,13 +7815,39 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
return v;
}
+static VALUE
+rb_ary_deconstruct(VALUE ary)
+{
+ return ary;
+}
+
/*
- * Arrays are ordered, integer-indexed collections of any object.
+ * An \Array is an ordered, integer-indexed collection of objects,
+ * called _elements_. Any object may be an \Array element.
*
- * Array indexing starts at 0, as in C or Java. A negative index is assumed
- * to be relative to the end of the array---that is, an index of -1 indicates
- * the last element of the array, -2 is the next to last element in the
- * array, and so on.
+ * == \Array Indexes
+ *
+ * \Array indexing starts at 0, as in C or Java.
+ *
+ * A positive index is an offset from the first element:
+ * - Index 0 indicates the first element.
+ * - Index 1 indicates the second element.
+ * - ...
+ *
+ * A negative index is an offset, backwards, from the end of the array:
+ * - Index -1 indicates the last element.
+ * - Index -2 indicates the next-to-last element.
+ * - ...
+ *
+ * A non-negative index is <i>in range</i> if it is smaller than
+ * the size of the array. For a 3-element array:
+ * - Indexes 0 through 2 are in range.
+ * - Index 3 is out of range.
+ *
+ * A negative index is <i>in range</i> if its absolute value is
+ * not larger than the size of the array. For a 3-element array:
+ * - Indexes -1 through -3 are in range.
+ * - Index -4 is out of range.
*
* == Creating Arrays
*
@@ -5997,12 +7874,12 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
* This method is safe to use with mutable objects such as hashes, strings or
* other arrays:
*
- * Array.new(4) { Hash.new } #=> [{}, {}, {}, {}]
+ * Array.new(4) {Hash.new} #=> [{}, {}, {}, {}]
* Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
*
* This is also a quick way to build up multi-dimensional arrays:
*
- * empty_table = Array.new(3) { Array.new(3) }
+ * empty_table = Array.new(3) {Array.new(3)}
* #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
*
* An array can also be created by using the Array() method, provided by
@@ -6149,7 +8026,7 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
* Note that this operation leaves the array unchanged.
*
* arr = [1, 2, 3, 4, 5]
- * arr.each { |a| print a -= 10, " " }
+ * arr.each {|a| print a -= 10, " "}
* # prints: -9 -8 -7 -6 -5
* #=> [1, 2, 3, 4, 5]
*
@@ -6158,15 +8035,15 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
*
* words = %w[first second third fourth fifth sixth]
* str = ""
- * words.reverse_each { |word| str += "#{word} " }
+ * words.reverse_each {|word| str += "#{word} "}
* p str #=> "sixth fifth fourth third second first "
*
* The #map method can be used to create a new array based on the original
* array, but with the values modified by the supplied block:
*
- * arr.map { |a| 2*a } #=> [2, 4, 6, 8, 10]
+ * arr.map {|a| 2*a} #=> [2, 4, 6, 8, 10]
* arr #=> [1, 2, 3, 4, 5]
- * arr.map! { |a| a**2 } #=> [1, 4, 9, 16, 25]
+ * arr.map! {|a| a**2} #=> [1, 4, 9, 16, 25]
* arr #=> [1, 4, 9, 16, 25]
*
* == Selecting Items from an Array
@@ -6180,9 +8057,9 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
* === Non-destructive Selection
*
* arr = [1, 2, 3, 4, 5, 6]
- * arr.select { |a| a > 3 } #=> [4, 5, 6]
- * arr.reject { |a| a < 3 } #=> [3, 4, 5, 6]
- * arr.drop_while { |a| a < 4 } #=> [4, 5, 6]
+ * arr.select {|a| a > 3} #=> [4, 5, 6]
+ * arr.reject {|a| a < 3} #=> [3, 4, 5, 6]
+ * arr.drop_while {|a| a < 4} #=> [4, 5, 6]
* arr #=> [1, 2, 3, 4, 5, 6]
*
* === Destructive Selection
@@ -6193,21 +8070,17 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
* Similar to #select vs. #reject, #delete_if and #keep_if have the exact
* opposite result when supplied with the same block:
*
- * arr.delete_if { |a| a < 4 } #=> [4, 5, 6]
+ * arr.delete_if {|a| a < 4} #=> [4, 5, 6]
* arr #=> [4, 5, 6]
*
* arr = [1, 2, 3, 4, 5, 6]
- * arr.keep_if { |a| a < 4 } #=> [1, 2, 3]
+ * arr.keep_if {|a| a < 4} #=> [1, 2, 3]
* arr #=> [1, 2, 3]
- *
*/
void
Init_Array(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
rb_cArray = rb_define_class("Array", rb_cObject);
rb_include_module(rb_cArray, rb_mEnumerable);
@@ -6222,7 +8095,6 @@ Init_Array(void)
rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
rb_define_method(rb_cArray, "to_h", rb_ary_to_h, 0);
rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
- rb_define_method(rb_cArray, "frozen?", rb_ary_frozen_p, 0);
rb_define_method(rb_cArray, "==", rb_ary_equal, 1);
rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1);
@@ -6235,6 +8107,9 @@ Init_Array(void)
rb_define_method(rb_cArray, "first", rb_ary_first, -1);
rb_define_method(rb_cArray, "last", rb_ary_last, -1);
rb_define_method(rb_cArray, "concat", rb_ary_concat_multi, -1);
+ rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1);
+ rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1);
+ rb_define_method(rb_cArray, "intersection", rb_ary_intersection_multi, -1);
rb_define_method(rb_cArray, "<<", rb_ary_push, 1);
rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
rb_define_alias(rb_cArray, "append", "push");
@@ -6247,7 +8122,7 @@ Init_Array(void)
rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
rb_define_method(rb_cArray, "length", rb_ary_length, 0);
- rb_define_alias(rb_cArray, "size", "length");
+ rb_define_method(rb_cArray, "size", rb_ary_length, 0);
rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
rb_define_method(rb_cArray, "find_index", rb_ary_index, -1);
rb_define_method(rb_cArray, "index", rb_ary_index, -1);
@@ -6266,6 +8141,8 @@ Init_Array(void)
rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0);
rb_define_method(rb_cArray, "select", rb_ary_select, 0);
rb_define_method(rb_cArray, "select!", rb_ary_select_bang, 0);
+ rb_define_method(rb_cArray, "filter", rb_ary_select, 0);
+ rb_define_method(rb_cArray, "filter!", rb_ary_select_bang, 0);
rb_define_method(rb_cArray, "keep_if", rb_ary_keep_if, 0);
rb_define_method(rb_cArray, "values_at", rb_ary_values_at, -1);
rb_define_method(rb_cArray, "delete", rb_ary_delete, 1);
@@ -6296,6 +8173,7 @@ Init_Array(void)
rb_define_method(rb_cArray, "max", rb_ary_max, -1);
rb_define_method(rb_cArray, "min", rb_ary_min, -1);
+ rb_define_method(rb_cArray, "minmax", rb_ary_minmax, 0);
rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
@@ -6304,9 +8182,6 @@ Init_Array(void)
rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
rb_define_method(rb_cArray, "count", rb_ary_count, -1);
- rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, -1);
- rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, -1);
- rb_define_method(rb_cArray, "sample", rb_ary_sample, -1);
rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
@@ -6320,9 +8195,14 @@ Init_Array(void)
rb_define_method(rb_cArray, "drop_while", rb_ary_drop_while, 0);
rb_define_method(rb_cArray, "bsearch", rb_ary_bsearch, 0);
rb_define_method(rb_cArray, "bsearch_index", rb_ary_bsearch_index, 0);
- rb_define_method(rb_cArray, "any?", rb_ary_any_p, 0);
+ rb_define_method(rb_cArray, "any?", rb_ary_any_p, -1);
+ rb_define_method(rb_cArray, "all?", rb_ary_all_p, -1);
+ rb_define_method(rb_cArray, "none?", rb_ary_none_p, -1);
+ rb_define_method(rb_cArray, "one?", rb_ary_one_p, -1);
rb_define_method(rb_cArray, "dig", rb_ary_dig, -1);
rb_define_method(rb_cArray, "sum", rb_ary_sum, -1);
- id_random = rb_intern("random");
+ rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
}
+
+#include "array.rbinc"
diff --git a/array.rb b/array.rb
new file mode 100644
index 0000000000..a43a3b27b1
--- /dev/null
+++ b/array.rb
@@ -0,0 +1,61 @@
+class Array
+ # call-seq:
+ # array.shuffle!(random: Random) -> array
+ #
+ # Shuffles the elements of +self+ in place.
+ # a = [1, 2, 3] #=> [1, 2, 3]
+ # a.shuffle! #=> [2, 3, 1]
+ # a #=> [2, 3, 1]
+ #
+ # The optional +random+ argument will be used as the random number generator:
+ # a.shuffle!(random: Random.new(1)) #=> [1, 3, 2]
+ def shuffle!(random: Random)
+ Primitive.rb_ary_shuffle_bang(random)
+ end
+
+ # call-seq:
+ # array.shuffle(random: Random) -> new_ary
+ #
+ # Returns a new array with elements of +self+ shuffled.
+ # a = [1, 2, 3] #=> [1, 2, 3]
+ # a.shuffle #=> [2, 3, 1]
+ # a #=> [1, 2, 3]
+ #
+ # The optional +random+ argument will be used as the random number generator:
+ # a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
+ def shuffle(random: Random)
+ Primitive.rb_ary_shuffle(random)
+ end
+
+ # call-seq:
+ # array.sample(random: Random) -> object
+ # array.sample(n, random: Random) -> new_ary
+ #
+ # Returns random elements from +self+.
+ #
+ # When no arguments are given, returns a random element from +self+:
+ # a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ # a.sample # => 3
+ # a.sample # => 8
+ # If +self+ is empty, returns +nil+.
+ #
+ # When argument +n+ is given, returns a new \Array containing +n+ random
+ # elements from +self+:
+ # a.sample(3) # => [8, 9, 2]
+ # a.sample(6) # => [9, 6, 10, 3, 1, 4]
+ # Returns no more than <tt>a.size</tt> elements
+ # (because no new duplicates are introduced):
+ # a.sample(a.size * 2) # => [6, 4, 1, 8, 5, 9, 10, 2, 3, 7]
+ # But +self+ may contain duplicates:
+ # a = [1, 1, 1, 2, 2, 3]
+ # a.sample(a.size * 2) # => [1, 1, 3, 2, 1, 2]
+ # Returns a new empty \Array if +self+ is empty.
+ #
+ # The optional +random+ argument will be used as the random number generator:
+ # a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ # a.sample(random: Random.new(1)) #=> 6
+ # a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2]
+ def sample(n = (ary = false), random: Random)
+ Primitive.rb_ary_sample(random, n, ary)
+ end
+end
diff --git a/ast.c b/ast.c
new file mode 100644
index 0000000000..2af0b3e530
--- /dev/null
+++ b/ast.c
@@ -0,0 +1,699 @@
+/* indent-tabs-mode: nil */
+#include "internal.h"
+#include "internal/parse.h"
+#include "internal/symbol.h"
+#include "internal/warnings.h"
+#include "iseq.h"
+#include "node.h"
+#include "ruby.h"
+#include "ruby/encoding.h"
+#include "ruby/util.h"
+#include "vm_core.h"
+
+#include "builtin.h"
+
+static VALUE rb_mAST;
+static VALUE rb_cNode;
+
+struct ASTNodeData {
+ rb_ast_t *ast;
+ const NODE *node;
+};
+
+static void
+node_gc_mark(void *ptr)
+{
+ struct ASTNodeData *data = (struct ASTNodeData *)ptr;
+ rb_gc_mark((VALUE)data->ast);
+}
+
+static size_t
+node_memsize(const void *ptr)
+{
+ struct ASTNodeData *data = (struct ASTNodeData *)ptr;
+ return rb_ast_memsize(data->ast);
+}
+
+static const rb_data_type_t rb_node_type = {
+ "AST/node",
+ {node_gc_mark, RUBY_TYPED_DEFAULT_FREE, node_memsize,},
+ 0, 0,
+ RUBY_TYPED_FREE_IMMEDIATELY,
+};
+
+static VALUE rb_ast_node_alloc(VALUE klass);
+
+static void
+setup_node(VALUE obj, rb_ast_t *ast, const NODE *node)
+{
+ struct ASTNodeData *data;
+
+ TypedData_Get_Struct(obj, struct ASTNodeData, &rb_node_type, data);
+ data->ast = ast;
+ data->node = node;
+}
+
+static VALUE
+ast_new_internal(rb_ast_t *ast, const NODE *node)
+{
+ VALUE obj;
+
+ obj = rb_ast_node_alloc(rb_cNode);
+ setup_node(obj, ast, node);
+
+ return obj;
+}
+
+static VALUE rb_ast_parse_str(VALUE str);
+static VALUE rb_ast_parse_file(VALUE path);
+static VALUE rb_ast_parse_array(VALUE array);
+
+static VALUE
+ast_parse_new(void)
+{
+ return rb_parser_set_context(rb_parser_new(), NULL, 0);
+}
+
+static VALUE
+ast_parse_done(rb_ast_t *ast)
+{
+ if (!ast->body.root) {
+ rb_ast_dispose(ast);
+ rb_exc_raise(GET_EC()->errinfo);
+ }
+
+ return ast_new_internal(ast, (NODE *)ast->body.root);
+}
+
+static VALUE
+ast_s_parse(rb_execution_context_t *ec, VALUE module, VALUE str)
+{
+ return rb_ast_parse_str(str);
+}
+
+static VALUE
+rb_ast_parse_str(VALUE str)
+{
+ rb_ast_t *ast = 0;
+
+ StringValue(str);
+ ast = rb_parser_compile_string_path(ast_parse_new(), Qnil, str, 1);
+ return ast_parse_done(ast);
+}
+
+static VALUE
+ast_s_parse_file(rb_execution_context_t *ec, VALUE module, VALUE path)
+{
+ return rb_ast_parse_file(path);
+}
+
+static VALUE
+rb_ast_parse_file(VALUE path)
+{
+ VALUE f;
+ rb_ast_t *ast = 0;
+ rb_encoding *enc = rb_utf8_encoding();
+
+ FilePathValue(path);
+ f = rb_file_open_str(path, "r");
+ rb_funcall(f, rb_intern("set_encoding"), 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
+ ast = rb_parser_compile_file_path(ast_parse_new(), Qnil, f, 1);
+ rb_io_close(f);
+ return ast_parse_done(ast);
+}
+
+static VALUE
+lex_array(VALUE array, int index)
+{
+ VALUE str = rb_ary_entry(array, index);
+ if (!NIL_P(str)) {
+ StringValue(str);
+ if (!rb_enc_asciicompat(rb_enc_get(str))) {
+ rb_raise(rb_eArgError, "invalid source encoding");
+ }
+ }
+ return str;
+}
+
+static VALUE
+rb_ast_parse_array(VALUE array)
+{
+ rb_ast_t *ast = 0;
+
+ array = rb_check_array_type(array);
+ ast = rb_parser_compile_generic(ast_parse_new(), lex_array, Qnil, array, 1);
+ return ast_parse_done(ast);
+}
+
+static VALUE node_children(rb_ast_t*, const NODE*);
+
+static VALUE
+node_find(VALUE self, const int node_id)
+{
+ VALUE ary;
+ long i;
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ if (nd_node_id(data->node) == node_id) return self;
+
+ ary = node_children(data->ast, data->node);
+
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE child = RARRAY_AREF(ary, i);
+
+ if (CLASS_OF(child) == rb_cNode) {
+ VALUE result = node_find(child, node_id);
+ if (RTEST(result)) return result;
+ }
+ }
+
+ return Qnil;
+}
+
+extern VALUE rb_e_script;
+
+static VALUE
+script_lines(VALUE path)
+{
+ VALUE hash, lines;
+ ID script_lines;
+ CONST_ID(script_lines, "SCRIPT_LINES__");
+ if (!rb_const_defined_at(rb_cObject, script_lines)) return Qnil;
+ hash = rb_const_get_at(rb_cObject, script_lines);
+ if (!RB_TYPE_P(hash, T_HASH)) return Qnil;
+ lines = rb_hash_lookup(hash, path);
+ if (!RB_TYPE_P(lines, T_ARRAY)) return Qnil;
+ return lines;
+}
+
+static VALUE
+ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body)
+{
+ VALUE path, node, lines;
+ int node_id;
+ const rb_iseq_t *iseq = NULL;
+
+ if (rb_obj_is_proc(body)) {
+ iseq = vm_proc_iseq(body);
+
+ if (!rb_obj_is_iseq((VALUE)iseq)) {
+ iseq = NULL;
+ }
+ }
+ else {
+ iseq = rb_method_iseq(body);
+ }
+
+ if (!iseq) return Qnil;
+
+ path = rb_iseq_path(iseq);
+ node_id = iseq->body->location.node_id;
+ if (!NIL_P(lines = script_lines(path))) {
+ node = rb_ast_parse_array(lines);
+ }
+ else if (RSTRING_LEN(path) == 2 && memcmp(RSTRING_PTR(path), "-e", 2) == 0) {
+ node = rb_ast_parse_str(rb_e_script);
+ }
+ else {
+ node = rb_ast_parse_file(path);
+ }
+
+ return node_find(node, node_id);
+}
+
+static VALUE
+rb_ast_node_alloc(VALUE klass)
+{
+ struct ASTNodeData *data;
+ VALUE obj = TypedData_Make_Struct(klass, struct ASTNodeData, &rb_node_type, data);
+
+ return obj;
+}
+
+static const char*
+node_type_to_str(const NODE *node)
+{
+ return (ruby_node_name(nd_type(node)) + rb_strlen_lit("NODE_"));
+}
+
+static VALUE
+ast_node_type(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return rb_sym_intern_ascii_cstr(node_type_to_str(data->node));
+}
+
+#define NEW_CHILD(ast, node) node ? ast_new_internal(ast, node) : Qnil
+
+static VALUE
+rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...)
+{
+ va_list ar;
+ VALUE ary;
+ long i;
+
+ ary = rb_ary_new2(n);
+
+ va_start(ar, n);
+ for (i=0; i<n; i++) {
+ NODE *node;
+ node = va_arg(ar, NODE *);
+ rb_ary_push(ary, NEW_CHILD(ast, node));
+ }
+ va_end(ar);
+ return ary;
+}
+
+static VALUE
+dump_block(rb_ast_t *ast, const NODE *node)
+{
+ VALUE ary = rb_ary_new();
+ do {
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
+ } while (node->nd_next &&
+ nd_type(node->nd_next) == NODE_BLOCK &&
+ (node = node->nd_next, 1));
+ if (node->nd_next) {
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
+ }
+
+ return ary;
+}
+
+static VALUE
+dump_array(rb_ast_t *ast, const NODE *node)
+{
+ VALUE ary = rb_ary_new();
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
+
+ while (node->nd_next && nd_type(node->nd_next) == NODE_LIST) {
+ node = node->nd_next;
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
+ }
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
+
+ return ary;
+}
+
+static VALUE
+var_name(ID id)
+{
+ if (!id) return Qnil;
+ if (!rb_id2str(id)) return Qnil;
+ return ID2SYM(id);
+}
+
+static VALUE
+no_name_rest(void)
+{
+ ID rest;
+ CONST_ID(rest, "NODE_SPECIAL_NO_NAME_REST");
+ return ID2SYM(rest);
+}
+
+static VALUE
+rest_arg(rb_ast_t *ast, const NODE *rest_arg)
+{
+ return NODE_NAMED_REST_P(rest_arg) ? NEW_CHILD(ast, rest_arg) : no_name_rest();
+}
+
+static VALUE
+node_children(rb_ast_t *ast, const NODE *node)
+{
+ char name[DECIMAL_SIZE_OF_BITS(sizeof(long) * CHAR_BIT) + 2]; /* including '$' */
+
+ enum node_type type = nd_type(node);
+ switch (type) {
+ case NODE_BLOCK:
+ return dump_block(ast, node);
+ case NODE_IF:
+ return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else);
+ case NODE_UNLESS:
+ return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else);
+ case NODE_CASE:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
+ case NODE_CASE2:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
+ case NODE_CASE3:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
+ case NODE_WHEN:
+ return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next);
+ case NODE_IN:
+ return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next);
+ case NODE_WHILE:
+ case NODE_UNTIL:
+ return rb_ary_push(rb_ary_new_from_node_args(ast, 2, node->nd_cond, node->nd_body),
+ (node->nd_state ? Qtrue : Qfalse));
+ case NODE_ITER:
+ case NODE_FOR:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_iter, node->nd_body);
+ case NODE_FOR_MASGN:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_var);
+ case NODE_BREAK:
+ case NODE_NEXT:
+ case NODE_RETURN:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_stts);
+ case NODE_REDO:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_RETRY:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_BEGIN:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
+ case NODE_RESCUE:
+ return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_resq, node->nd_else);
+ case NODE_RESBODY:
+ return rb_ary_new_from_node_args(ast, 3, node->nd_args, node->nd_body, node->nd_head);
+ case NODE_ENSURE:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_ensr);
+ case NODE_AND:
+ case NODE_OR:
+ {
+ VALUE ary = rb_ary_new();
+
+ while (1) {
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_1st));
+ if (!node->nd_2nd || nd_type(node->nd_2nd) != (int)type)
+ break;
+ node = node->nd_2nd;
+ }
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_2nd));
+ return ary;
+ }
+ case NODE_MASGN:
+ if (NODE_NAMED_REST_P(node->nd_args)) {
+ return rb_ary_new_from_node_args(ast, 3, node->nd_value, node->nd_head, node->nd_args);
+ }
+ else {
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_value),
+ NEW_CHILD(ast, node->nd_head),
+ no_name_rest());
+ }
+ case NODE_LASGN:
+ case NODE_DASGN:
+ case NODE_DASGN_CURR:
+ case NODE_IASGN:
+ case NODE_CVASGN:
+ case NODE_GASGN:
+ if (NODE_REQUIRED_KEYWORD_P(node)) {
+ return rb_ary_new_from_args(2, var_name(node->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
+ }
+ return rb_ary_new_from_args(2, var_name(node->nd_vid), NEW_CHILD(ast, node->nd_value));
+ case NODE_CDECL:
+ if (node->nd_vid) {
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_vid), NEW_CHILD(ast, node->nd_value));
+ }
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_else), ID2SYM(node->nd_else->nd_mid), NEW_CHILD(ast, node->nd_value));
+ case NODE_OP_ASGN1:
+ return rb_ary_new_from_args(4, NEW_CHILD(ast, node->nd_recv),
+ ID2SYM(node->nd_mid),
+ NEW_CHILD(ast, node->nd_args->nd_head),
+ NEW_CHILD(ast, node->nd_args->nd_body));
+ case NODE_OP_ASGN2:
+ return rb_ary_new_from_args(5, NEW_CHILD(ast, node->nd_recv),
+ node->nd_next->nd_aid ? Qtrue : Qfalse,
+ ID2SYM(node->nd_next->nd_vid),
+ ID2SYM(node->nd_next->nd_mid),
+ NEW_CHILD(ast, node->nd_value));
+ case NODE_OP_ASGN_AND:
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idANDOP),
+ NEW_CHILD(ast, node->nd_value));
+ case NODE_OP_ASGN_OR:
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idOROP),
+ NEW_CHILD(ast, node->nd_value));
+ case NODE_OP_CDECL:
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head),
+ ID2SYM(node->nd_aid),
+ NEW_CHILD(ast, node->nd_value));
+ case NODE_CALL:
+ case NODE_OPCALL:
+ case NODE_QCALL:
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv),
+ ID2SYM(node->nd_mid),
+ NEW_CHILD(ast, node->nd_args));
+ case NODE_FCALL:
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_mid),
+ NEW_CHILD(ast, node->nd_args));
+ case NODE_VCALL:
+ return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
+ case NODE_SUPER:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_args);
+ case NODE_ZSUPER:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_LIST:
+ case NODE_VALUES:
+ return dump_array(ast, node);
+ case NODE_ZLIST:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_HASH:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
+ case NODE_YIELD:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
+ case NODE_LVAR:
+ case NODE_DVAR:
+ return rb_ary_new_from_args(1, var_name(node->nd_vid));
+ case NODE_IVAR:
+ case NODE_CONST:
+ case NODE_CVAR:
+ case NODE_GVAR:
+ return rb_ary_new_from_args(1, ID2SYM(node->nd_vid));
+ case NODE_NTH_REF:
+ snprintf(name, sizeof(name), "$%ld", node->nd_nth);
+ return rb_ary_new_from_args(1, ID2SYM(rb_intern(name)));
+ case NODE_BACK_REF:
+ name[0] = '$';
+ name[1] = (char)node->nd_nth;
+ name[2] = '\0';
+ return rb_ary_new_from_args(1, ID2SYM(rb_intern(name)));
+ case NODE_MATCH2:
+ if (node->nd_args) {
+ return rb_ary_new_from_node_args(ast, 3, node->nd_recv, node->nd_value, node->nd_args);
+ }
+ return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
+ case NODE_MATCH3:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
+ case NODE_MATCH:
+ case NODE_LIT:
+ case NODE_STR:
+ case NODE_XSTR:
+ return rb_ary_new_from_args(1, node->nd_lit);
+ case NODE_ONCE:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
+ case NODE_DSTR:
+ case NODE_DXSTR:
+ case NODE_DREGX:
+ case NODE_DSYM:
+ {
+ NODE *n = node->nd_next;
+ VALUE head = Qnil, next = Qnil;
+ if (n) {
+ head = NEW_CHILD(ast, n->nd_head);
+ next = NEW_CHILD(ast, n->nd_next);
+ }
+ return rb_ary_new_from_args(3, node->nd_lit, head, next);
+ }
+ case NODE_EVSTR:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
+ case NODE_ARGSCAT:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
+ case NODE_ARGSPUSH:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
+ case NODE_SPLAT:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
+ case NODE_BLOCK_PASS:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
+ case NODE_DEFN:
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn));
+ case NODE_DEFS:
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn));
+ case NODE_ALIAS:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd);
+ case NODE_VALIAS:
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_alias), ID2SYM(node->nd_orig));
+ case NODE_UNDEF:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_undef);
+ case NODE_CLASS:
+ return rb_ary_new_from_node_args(ast, 3, node->nd_cpath, node->nd_super, node->nd_body);
+ case NODE_MODULE:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_cpath, node->nd_body);
+ case NODE_SCLASS:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_body);
+ case NODE_COLON2:
+ return rb_ary_new_from_args(2, NEW_CHILD(ast, node->nd_head), ID2SYM(node->nd_mid));
+ case NODE_COLON3:
+ return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
+ case NODE_DOT2:
+ case NODE_DOT3:
+ case NODE_FLIP2:
+ case NODE_FLIP3:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_beg, node->nd_end);
+ case NODE_SELF:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_NIL:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_TRUE:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_FALSE:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_ERRINFO:
+ return rb_ary_new_from_node_args(ast, 0);
+ case NODE_DEFINED:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
+ case NODE_POSTEXE:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
+ case NODE_ATTRASGN:
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_args));
+ case NODE_LAMBDA:
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
+ case NODE_OPT_ARG:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next);
+ case NODE_KW_ARG:
+ return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next);
+ case NODE_POSTARG:
+ if (NODE_NAMED_REST_P(node->nd_1st)) {
+ return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd);
+ }
+ return rb_ary_new_from_args(2, no_name_rest(),
+ NEW_CHILD(ast, node->nd_2nd));
+ case NODE_ARGS:
+ {
+ struct rb_args_info *ainfo = node->nd_ainfo;
+ return rb_ary_new_from_args(10,
+ INT2NUM(ainfo->pre_args_num),
+ NEW_CHILD(ast, ainfo->pre_init),
+ NEW_CHILD(ast, ainfo->opt_args),
+ var_name(ainfo->first_post_arg),
+ INT2NUM(ainfo->post_args_num),
+ NEW_CHILD(ast, ainfo->post_init),
+ (ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA
+ ? ID2SYM(rb_intern("NODE_SPECIAL_EXCESSIVE_COMMA"))
+ : var_name(ainfo->rest_arg)),
+ (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_args)),
+ (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_rest_arg)),
+ var_name(ainfo->block_arg));
+ }
+ case NODE_SCOPE:
+ {
+ ID *tbl = node->nd_tbl;
+ int i, size = tbl ? (int)*tbl++ : 0;
+ VALUE locals = rb_ary_new_capa(size);
+ for (i = 0; i < size; i++) {
+ rb_ary_push(locals, var_name(tbl[i]));
+ }
+ return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, node->nd_args), NEW_CHILD(ast, node->nd_body));
+ }
+ case NODE_ARYPTN:
+ {
+ struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
+ VALUE rest = rest_arg(ast, apinfo->rest_arg);
+ return rb_ary_new_from_args(4,
+ NEW_CHILD(ast, node->nd_pconst),
+ NEW_CHILD(ast, apinfo->pre_args),
+ rest,
+ NEW_CHILD(ast, apinfo->post_args));
+ }
+ case NODE_FNDPTN:
+ {
+ struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo;
+ VALUE pre_rest = rest_arg(ast, fpinfo->pre_rest_arg);
+ VALUE post_rest = rest_arg(ast, fpinfo->post_rest_arg);
+ return rb_ary_new_from_args(4,
+ NEW_CHILD(ast, node->nd_pconst),
+ pre_rest,
+ NEW_CHILD(ast, fpinfo->args),
+ post_rest);
+ }
+ case NODE_HSHPTN:
+ {
+ VALUE kwrest = node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
+ NEW_CHILD(ast, node->nd_pkwrestarg);
+
+ return rb_ary_new_from_args(3,
+ NEW_CHILD(ast, node->nd_pconst),
+ NEW_CHILD(ast, node->nd_pkwargs),
+ kwrest);
+ }
+ case NODE_ARGS_AUX:
+ case NODE_LAST:
+ break;
+ }
+
+ rb_bug("node_children: unknown node: %s", ruby_node_name(type));
+}
+
+static VALUE
+ast_node_children(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return node_children(data->ast, data->node);
+}
+
+static VALUE
+ast_node_first_lineno(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return INT2NUM(nd_first_lineno(data->node));
+}
+
+static VALUE
+ast_node_first_column(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return INT2NUM(nd_first_column(data->node));
+}
+
+static VALUE
+ast_node_last_lineno(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return INT2NUM(nd_last_lineno(data->node));
+}
+
+static VALUE
+ast_node_last_column(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return INT2NUM(nd_last_column(data->node));
+}
+
+static VALUE
+ast_node_inspect(rb_execution_context_t *ec, VALUE self)
+{
+ VALUE str;
+ VALUE cname;
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ cname = rb_class_path(rb_obj_class(self));
+ str = rb_str_new2("#<");
+
+ rb_str_append(str, cname);
+ rb_str_catf(str, ":%s@%d:%d-%d:%d>",
+ node_type_to_str(data->node),
+ nd_first_lineno(data->node), nd_first_column(data->node),
+ nd_last_lineno(data->node), nd_last_column(data->node));
+
+ return str;
+}
+
+#include "ast.rbinc"
+
+void
+Init_ast(void)
+{
+ rb_mAST = rb_define_module_under(rb_cRubyVM, "AbstractSyntaxTree");
+ rb_cNode = rb_define_class_under(rb_mAST, "Node", rb_cObject);
+ rb_undef_alloc_func(rb_cNode);
+}
diff --git a/ast.rb b/ast.rb
new file mode 100644
index 0000000000..34fa645671
--- /dev/null
+++ b/ast.rb
@@ -0,0 +1,146 @@
+# for ast.c
+
+class RubyVM
+
+ # AbstractSyntaxTree provides methods to parse Ruby code into
+ # abstract syntax trees. The nodes in the tree
+ # are instances of RubyVM::AbstractSyntaxTree::Node.
+ #
+ # This module is MRI specific as it exposes implementation details
+ # of the MRI abstract syntax tree.
+ #
+ # This module is experimental and its API is not stable, therefore it might
+ # change without notice. As examples, the order of children nodes is not
+ # guaranteed, the number of children nodes might change, there is no way to
+ # access children nodes by name, etc.
+ #
+ # If you are looking for a stable API or an API working under multiple Ruby
+ # implementations, consider using the _parser_ gem or Ripper. If you would
+ # like to make RubyVM::AbstractSyntaxTree stable, please join the discussion
+ # at https://bugs.ruby-lang.org/issues/14844.
+ #
+ module AbstractSyntaxTree
+
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.parse(string) -> RubyVM::AbstractSyntaxTree::Node
+ #
+ # Parses the given _string_ into an abstract syntax tree,
+ # returning the root node of that tree.
+ #
+ # SyntaxError is raised if the given _string_ is invalid syntax.
+ #
+ # RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:9>
+ def self.parse string
+ Primitive.ast_s_parse string
+ end
+
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.parse_file(pathname) -> RubyVM::AbstractSyntaxTree::Node
+ #
+ # Reads the file from _pathname_, then parses it like ::parse,
+ # returning the root node of the abstract syntax tree.
+ #
+ # SyntaxError is raised if _pathname_'s contents are not
+ # valid Ruby syntax.
+ #
+ # RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
+ def self.parse_file pathname
+ Primitive.ast_s_parse_file pathname
+ end
+
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.of(proc) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.of(method) -> RubyVM::AbstractSyntaxTree::Node
+ #
+ # Returns AST nodes of the given _proc_ or _method_.
+ #
+ # RubyVM::AbstractSyntaxTree.of(proc {1 + 2})
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:35-1:42>
+ #
+ # def hello
+ # puts "hello, world"
+ # end
+ #
+ # RubyVM::AbstractSyntaxTree.of(method(:hello))
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
+ def self.of body
+ Primitive.ast_s_of body
+ end
+
+ # RubyVM::AbstractSyntaxTree::Node instances are created by parse methods in
+ # RubyVM::AbstractSyntaxTree.
+ #
+ # This class is MRI specific.
+ #
+ class Node
+
+ # call-seq:
+ # node.type -> symbol
+ #
+ # Returns the type of this node as a symbol.
+ #
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
+ # root.type # => :SCOPE
+ # lasgn = root.children[2]
+ # lasgn.type # => :LASGN
+ # call = lasgn.children[1]
+ # call.type # => :OPCALL
+ def type
+ Primitive.ast_node_type
+ end
+
+ # call-seq:
+ # node.first_lineno -> integer
+ #
+ # The line number in the source code where this AST's text began.
+ def first_lineno
+ Primitive.ast_node_first_lineno
+ end
+
+ # call-seq:
+ # node.first_column -> integer
+ #
+ # The column number in the source code where this AST's text began.
+ def first_column
+ Primitive.ast_node_first_column
+ end
+
+ # call-seq:
+ # node.last_lineno -> integer
+ #
+ # The line number in the source code where this AST's text ended.
+ def last_lineno
+ Primitive.ast_node_last_lineno
+ end
+
+ # call-seq:
+ # node.last_column -> integer
+ #
+ # The column number in the source code where this AST's text ended.
+ def last_column
+ Primitive.ast_node_last_column
+ end
+
+ # call-seq:
+ # node.children -> array
+ #
+ # Returns AST nodes under this one. Each kind of node
+ # has different children, depending on what kind of node it is.
+ #
+ # The returned array may contain other nodes or <code>nil</code>.
+ def children
+ Primitive.ast_node_children
+ end
+
+ # call-seq:
+ # node.inspect -> string
+ #
+ # Returns debugging information about this node as a string.
+ def inspect
+ Primitive.ast_node_inspect
+ end
+ end
+ end
+end
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000000..44a1922cb0
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+PWD=
+case "$0" in
+*/*) srcdir=`dirname $0`;;
+*) srcdir="";;
+esac
+
+exec ${AUTORECONF:-autoreconf} --install --symlink "$@" ${srcdir:+"$srcdir"}
diff --git a/basictest/test.rb b/basictest/test.rb
index 25d52ca1ef..52008b78db 100755
--- a/basictest/test.rb
+++ b/basictest/test.rb
@@ -35,7 +35,7 @@ class Progress
# dircolors-like style
colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(/(\w+)=([^:\n]*)/)] : {}
begin
- File.read(File.join(__dir__, "../test/colors")).scan(/(\w+)=([^:\n]*)/) do |n, c|
+ File.read(File.join(__dir__, "../tool/colors")).scan(/(\w+)=([^:\n]*)/) do |n, c|
colors[n] ||= c
end
rescue
@@ -984,13 +984,6 @@ test_ok($z == 0)
test_check "iterator"
-test_ok(!iterator?)
-
-def ttt
- test_ok(iterator?)
-end
-ttt{}
-
# yield at top level
test_ok(!defined?(yield))
@@ -1432,9 +1425,6 @@ marity_test(:test_ok)
marity_test(:marity_test)
marity_test(:p)
-lambda(&method(:test_ok)).call(true)
-lambda(&block_get{|a,n| test_ok(a,n)}).call(true, 2)
-
class ITER_TEST1
def a
block_given?
@@ -1739,7 +1729,7 @@ a = nil
test_ok(defined?(a))
test_ok(a == nil)
-# multiple asignment
+# multiple assignment
a, b = 1, 2
test_ok(a == 1 && b == 2)
@@ -2147,7 +2137,7 @@ $_ = foobar
test_ok($_ == foobar)
class Gods
- @@rule = "Uranus" # private to Gods
+ @@rule = "Uranus"
def ruler0
@@rule
end
@@ -2170,7 +2160,7 @@ module Olympians
end
class Titans < Gods
- @@rule = "Cronus" # do not affect @@rule in Gods
+ @@rule = "Cronus" # modifies @@rule in Gods
include Olympians
def ruler4
@@rule
@@ -2185,7 +2175,14 @@ test_ok(Titans.ruler2 == "Cronus")
atlas = Titans.new
test_ok(atlas.ruler0 == "Cronus")
test_ok(atlas.ruler3 == "Zeus")
-test_ok(atlas.ruler4 == "Cronus")
+begin
+ atlas.ruler4
+rescue RuntimeError => e
+ test_ok(e.message.include?("class variable @@rule of Olympians is overtaken by Gods"))
+else
+ test_ok(false)
+end
+test_ok(atlas.ruler3 == "Zeus")
test_check "trace"
$x = 1234
diff --git a/benchmark/README.md b/benchmark/README.md
new file mode 100644
index 0000000000..39a5aa139b
--- /dev/null
+++ b/benchmark/README.md
@@ -0,0 +1,72 @@
+# ruby/benchmark
+
+This directory has benchmark definitions to be run with
+[benchmark\_driver.gem](https://github.com/benchmark-driver/benchmark-driver).
+
+## Normal usage
+
+Execute `gem install benchmark_driver` and run a command like:
+
+```bash
+# Run a benchmark script with the ruby in the $PATH
+benchmark-driver benchmark/app_fib.rb
+
+# Run benchmark scripts with multiple Ruby executables or options
+benchmark-driver benchmark/*.rb -e /path/to/ruby -e '/path/to/ruby --jit'
+
+# Or compare Ruby versions managed by rbenv
+benchmark-driver benchmark/*.rb --rbenv '2.5.1;2.6.0-preview2 --jit'
+
+# You can collect many metrics in many ways
+benchmark-driver benchmark/*.rb --runner memory --output markdown
+
+# Some are defined with YAML for complex setup or accurate measurement
+benchmark-driver benchmark/*.yml
+```
+
+See also:
+
+```console
+Usage: benchmark-driver [options] RUBY|YAML...
+ -r, --runner TYPE Specify runner type: ips, time, memory, once (default: ips)
+ -o, --output TYPE Specify output type: compare, simple, markdown, record (default: compare)
+ -e, --executables EXECS Ruby executables (e1::path1 arg1; e2::path2 arg2;...)
+ --rbenv VERSIONS Ruby executables in rbenv (x.x.x arg1;y.y.y arg2;...)
+ --repeat-count NUM Try benchmark NUM times and use the fastest result or the worst memory usage
+ --repeat-result TYPE Yield "best", "average" or "worst" result with --repeat-count (default: best)
+ --bundler Install and use gems specified in Gemfile
+ --filter REGEXP Filter out benchmarks with given regexp
+ --run-duration SECONDS Warmup estimates loop_count to run for this duration (default: 3)
+ -v, --verbose Verbose mode. Multiple -v options increase visilibity (max: 2)
+```
+
+## make benchmark
+
+Using `make benchmark`, `make update-benchmark-driver` automatically downloads
+the supported version of benchmark\_driver, and it runs benchmarks with the downloaded
+benchmark\_driver.
+
+```bash
+# Run all benchmarks with the ruby in the $PATH and the built ruby
+make benchmark
+
+# Or compare with specific ruby binary
+make benchmark COMPARE_RUBY="/path/to/ruby --jit"
+
+# Run vm benchmarks
+make benchmark ITEM=vm
+
+# Run some limited benchmarks in ITEM-matched files
+make benchmark ITEM=vm OPTS=--filter=block
+
+# You can specify the benchmark by an exact filename instead of using the default argument:
+# ARGS = $$(find $(srcdir)/benchmark -maxdepth 1 -name '*$(ITEM)*.yml' -o -name '*$(ITEM)*.rb')
+make benchmark ARGS=benchmark/erb_render.yml
+
+# You can specify any option via $OPTS
+make benchmark OPTS="--help"
+
+# With `make benchmark`, some special runner plugins are available:
+# -r peak, -r size, -r total, -r utime, -r stime, -r cutime, -r cstime
+make benchmark ITEM=vm_bigarray OPTS="-r peak"
+```
diff --git a/benchmark/bm_app_answer.rb b/benchmark/app_answer.rb
index 3cd8a8fd37..3cd8a8fd37 100644
--- a/benchmark/bm_app_answer.rb
+++ b/benchmark/app_answer.rb
diff --git a/benchmark/app_aobench.rb b/benchmark/app_aobench.rb
new file mode 100644
index 0000000000..16296af12b
--- /dev/null
+++ b/benchmark/app_aobench.rb
@@ -0,0 +1,297 @@
+# coding: US-ASCII
+
+# AO render benchmark
+# Original program (C) Syoyo Fujita in Javascript (and other languages)
+# https://code.google.com/p/aobench/
+# Ruby(yarv2llvm) version by Hideki Miura
+#
+
+IMAGE_WIDTH = 256
+IMAGE_HEIGHT = 256
+NSUBSAMPLES = 2
+NAO_SAMPLES = 8
+
+srand(0)
+
+class Vec
+ def initialize(x, y, z)
+ @x = x
+ @y = y
+ @z = z
+ end
+
+ attr_accessor :x, :y, :z
+
+ def vadd(b)
+ Vec.new(@x + b.x, @y + b.y, @z + b.z)
+ end
+
+ def vsub(b)
+ Vec.new(@x - b.x, @y - b.y, @z - b.z)
+ end
+
+ def vcross(b)
+ Vec.new(@y * b.z - @z * b.y,
+ @z * b.x - @x * b.z,
+ @x * b.y - @y * b.x)
+ end
+
+ def vdot(b)
+ @x * b.x + @y * b.y + @z * b.z
+ end
+
+ def vlength
+ Math.sqrt(@x * @x + @y * @y + @z * @z)
+ end
+
+ def vnormalize
+ len = vlength
+ v = Vec.new(@x, @y, @z)
+ if len > 1.0e-17 then
+ v.x = v.x / len
+ v.y = v.y / len
+ v.z = v.z / len
+ end
+ v
+ end
+end
+
+
+class Sphere
+ def initialize(center, radius)
+ @center = center
+ @radius = radius
+ end
+
+ attr_reader :center, :radius
+
+ def intersect(ray, isect)
+ rs = ray.org.vsub(@center)
+ b = rs.vdot(ray.dir)
+ c = rs.vdot(rs) - (@radius * @radius)
+ d = b * b - c
+ if d > 0.0 then
+ t = - b - Math.sqrt(d)
+
+ if t > 0.0 and t < isect.t then
+ isect.t = t
+ isect.hit = true
+ isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
+ ray.org.y + ray.dir.y * t,
+ ray.org.z + ray.dir.z * t)
+ n = isect.pl.vsub(@center)
+ isect.n = n.vnormalize
+ else
+ 0.0
+ end
+ end
+ nil
+ end
+end
+
+class Plane
+ def initialize(p, n)
+ @p = p
+ @n = n
+ end
+
+ def intersect(ray, isect)
+ d = -@p.vdot(@n)
+ v = ray.dir.vdot(@n)
+ v0 = v
+ if v < 0.0 then
+ v0 = -v
+ end
+ if v0 < 1.0e-17 then
+ return
+ end
+
+ t = -(ray.org.vdot(@n) + d) / v
+
+ if t > 0.0 and t < isect.t then
+ isect.hit = true
+ isect.t = t
+ isect.n = @n
+ isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
+ ray.org.y + t * ray.dir.y,
+ ray.org.z + t * ray.dir.z)
+ end
+ nil
+ end
+end
+
+class Ray
+ def initialize(org, dir)
+ @org = org
+ @dir = dir
+ end
+
+ attr_accessor :org, :dir
+end
+
+class Isect
+ def initialize
+ @t = 10000000.0
+ @hit = false
+ @pl = Vec.new(0.0, 0.0, 0.0)
+ @n = Vec.new(0.0, 0.0, 0.0)
+ end
+
+ attr_accessor :t, :hit, :pl, :n
+end
+
+def clamp(f)
+ i = f * 255.5
+ if i > 255.0 then
+ i = 255.0
+ end
+ if i < 0.0 then
+ i = 0.0
+ end
+ i.to_i
+end
+
+def otherBasis(basis, n)
+ basis[2] = Vec.new(n.x, n.y, n.z)
+ basis[1] = Vec.new(0.0, 0.0, 0.0)
+
+ if n.x < 0.6 and n.x > -0.6 then
+ basis[1].x = 1.0
+ elsif n.y < 0.6 and n.y > -0.6 then
+ basis[1].y = 1.0
+ elsif n.z < 0.6 and n.z > -0.6 then
+ basis[1].z = 1.0
+ else
+ basis[1].x = 1.0
+ end
+
+ basis[0] = basis[1].vcross(basis[2])
+ basis[0] = basis[0].vnormalize
+
+ basis[1] = basis[2].vcross(basis[0])
+ basis[1] = basis[1].vnormalize
+end
+
+class Scene
+ def initialize
+ @spheres = Array.new
+ @spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
+ @spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
+ @spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
+ @plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
+ end
+
+ def ambient_occlusion(isect)
+ basis = Array.new
+ otherBasis(basis, isect.n)
+
+ ntheta = NAO_SAMPLES
+ nphi = NAO_SAMPLES
+ eps = 0.0001
+ occlusion = 0.0
+
+ p0 = Vec.new(isect.pl.x + eps * isect.n.x,
+ isect.pl.y + eps * isect.n.y,
+ isect.pl.z + eps * isect.n.z)
+ nphi.times do |j|
+ ntheta.times do |i|
+ r = rand
+ phi = 2.0 * 3.14159265 * rand
+ x = Math.cos(phi) * Math.sqrt(1.0 - r)
+ y = Math.sin(phi) * Math.sqrt(1.0 - r)
+ z = Math.sqrt(r)
+
+ rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
+ ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
+ rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
+
+ raydir = Vec.new(rx, ry, rz)
+ ray = Ray.new(p0, raydir)
+
+ occisect = Isect.new
+ @spheres[0].intersect(ray, occisect)
+ @spheres[1].intersect(ray, occisect)
+ @spheres[2].intersect(ray, occisect)
+ @plane.intersect(ray, occisect)
+ if occisect.hit then
+ occlusion = occlusion + 1.0
+ else
+ 0.0
+ end
+ end
+ end
+
+ occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
+
+ Vec.new(occlusion, occlusion, occlusion)
+ end
+
+ def render(w, h, nsubsamples)
+ cnt = 0
+ nsf = nsubsamples.to_f
+ h.times do |y|
+ w.times do |x|
+ rad = Vec.new(0.0, 0.0, 0.0)
+
+ # Subsampling
+ nsubsamples.times do |v|
+ nsubsamples.times do |u|
+
+ cnt = cnt + 1
+ wf = w.to_f
+ hf = h.to_f
+ xf = x.to_f
+ yf = y.to_f
+ uf = u.to_f
+ vf = v.to_f
+
+ px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
+ py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
+
+ eye = Vec.new(px, py, -1.0).vnormalize
+
+ ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
+
+ isect = Isect.new
+ @spheres[0].intersect(ray, isect)
+ @spheres[1].intersect(ray, isect)
+ @spheres[2].intersect(ray, isect)
+ @plane.intersect(ray, isect)
+ if isect.hit then
+ col = ambient_occlusion(isect)
+ rad.x = rad.x + col.x
+ rad.y = rad.y + col.y
+ rad.z = rad.z + col.z
+ end
+ end
+ end
+
+ r = rad.x / (nsf * nsf)
+ g = rad.y / (nsf * nsf)
+ b = rad.z / (nsf * nsf)
+ printf("%c", clamp(r))
+ printf("%c", clamp(g))
+ printf("%c", clamp(b))
+ end
+ nil
+ end
+
+ nil
+ end
+end
+
+alias printf_orig printf
+def printf *args
+ # $fp.printf(*args)
+end
+
+# File.open("ao.ppm", "w") do |fp|
+ # $fp = fp
+ printf("P6\n")
+ printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
+ printf("255\n")
+ Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
+# end
+
+undef printf
+alias printf printf_orig
diff --git a/benchmark/app_erb.yml b/benchmark/app_erb.yml
new file mode 100644
index 0000000000..31e29b7644
--- /dev/null
+++ b/benchmark/app_erb.yml
@@ -0,0 +1,23 @@
+#
+# Create many HTML strings with ERB.
+#
+prelude: |
+ require 'erb'
+
+ data = <<erb
+ <html>
+ <head> <%= title %> </head>
+ <body>
+ <h1> <%= title %> </h1>
+ <p>
+ <%= content %>
+ </p>
+ </body>
+ </html>
+ erb
+
+ title = "hello world!"
+ content = "hello world!\n" * 10
+benchmark:
+ app_erb: ERB.new(data).result(binding)
+loop_count: 15000
diff --git a/benchmark/bm_app_factorial.rb b/benchmark/app_factorial.rb
index 45f471dfdb..45f471dfdb 100644
--- a/benchmark/bm_app_factorial.rb
+++ b/benchmark/app_factorial.rb
diff --git a/benchmark/bm_app_fib.rb b/benchmark/app_fib.rb
index 34a7b2e725..34a7b2e725 100644
--- a/benchmark/bm_app_fib.rb
+++ b/benchmark/app_fib.rb
diff --git a/benchmark/bm_app_lc_fizzbuzz.rb b/benchmark/app_lc_fizzbuzz.rb
index f09574bbeb..f09574bbeb 100644
--- a/benchmark/bm_app_lc_fizzbuzz.rb
+++ b/benchmark/app_lc_fizzbuzz.rb
diff --git a/benchmark/bm_app_mandelbrot.rb b/benchmark/app_mandelbrot.rb
index 801b75e8e2..801b75e8e2 100644
--- a/benchmark/bm_app_mandelbrot.rb
+++ b/benchmark/app_mandelbrot.rb
diff --git a/benchmark/app_pentomino.rb b/benchmark/app_pentomino.rb
new file mode 100644
index 0000000000..47be7b203f
--- /dev/null
+++ b/benchmark/app_pentomino.rb
@@ -0,0 +1,130 @@
+#!/usr/local/bin/ruby
+# This program is contributed by Shin Nishiyama
+
+
+# modified by K.Sasada
+
+NP = 5
+ROW = 8 + NP
+COL = 8
+
+$p = []
+$b = []
+$no = 0
+
+def piece(n, a, nb)
+ nb.each{|x|
+ a[n] = x
+ if n == NP-1
+ $p << [a.sort]
+ else
+ nbc=nb.dup
+ [-ROW, -1, 1, ROW].each{|d|
+ if x+d > 0 and not a.include?(x+d) and not nbc.include?(x+d)
+ nbc << x+d
+ end
+ }
+ nbc.delete x
+ piece(n+1,a[0..n],nbc)
+ end
+ }
+end
+
+def kikaku(a)
+ a.collect {|x| x - a[0]}
+end
+def ud(a)
+ kikaku(a.collect {|x| ((x+NP)%ROW)-ROW*((x+NP)/ROW) }.sort)
+end
+def rl(a)
+ kikaku(a.collect {|x| ROW*((x+NP)/ROW)+ROW-((x+NP)%ROW)}.sort)
+end
+def xy(a)
+ kikaku(a.collect {|x| ROW*((x+NP)%ROW) + (x+NP)/ROW }.sort)
+end
+
+def mkpieces
+ piece(0,[],[0])
+ $p.each do |a|
+ a0 = a[0]
+ a[1] = ud(a0)
+ a[2] = rl(a0)
+ a[3] = ud(rl(a0))
+ a[4] = xy(a0)
+ a[5] = ud(xy(a0))
+ a[6] = rl(xy(a0))
+ a[7] = ud(rl(xy(a0)))
+ a.sort!
+ a.uniq!
+ end
+ $p.uniq!.sort! {|x,y| x[0] <=> y[0] }
+end
+
+def mkboard
+ (0...ROW*COL).each{|i|
+ if i % ROW >= ROW-NP
+ $b[i] = -2
+ else
+ $b[i] = -1
+ end
+ $b[3*ROW+3]=$b[3*ROW+4]=$b[4*ROW+3]=$b[4*ROW+4]=-2
+ }
+end
+
+def pboard
+ return # skip print
+ print "No. #$no\n"
+ (0...COL).each{|i|
+ print "|"
+ (0...ROW-NP).each{|j|
+ x = $b[i*ROW+j]
+ if x < 0
+ print "..|"
+ else
+ printf "%2d|",x+1
+ end
+ }
+ print "\n"
+ }
+ print "\n"
+end
+
+$pnum=[]
+def setpiece(a,pos)
+ if a.length == $p.length then
+ $no += 1
+ pboard
+ return
+ end
+ while $b[pos] != -1
+ pos += 1
+ end
+ ($pnum - a).each do |i|
+ $p[i].each do |x|
+ f = 0
+ x.each{|s|
+ if $b[pos+s] != -1
+ f=1
+ break
+ end
+ }
+ if f == 0 then
+ x.each{|s|
+ $b[pos+s] = i
+ }
+ a << i
+ setpiece(a.dup, pos)
+ a.pop
+ x.each{|s|
+ $b[pos+s] = -1
+ }
+ end
+ end
+ end
+end
+
+mkpieces
+mkboard
+$p[4] = [$p[4][0]]
+$pnum = (0...$p.length).to_a
+setpiece([],0)
diff --git a/benchmark/bm_app_raise.rb b/benchmark/app_raise.rb
index 5db8f95d50..5db8f95d50 100644
--- a/benchmark/bm_app_raise.rb
+++ b/benchmark/app_raise.rb
diff --git a/benchmark/bm_app_strconcat.rb b/benchmark/app_strconcat.rb
index 7eed7c1aed..7eed7c1aed 100644
--- a/benchmark/bm_app_strconcat.rb
+++ b/benchmark/app_strconcat.rb
diff --git a/benchmark/bm_app_tak.rb b/benchmark/app_tak.rb
index efe5380f4e..efe5380f4e 100644
--- a/benchmark/bm_app_tak.rb
+++ b/benchmark/app_tak.rb
diff --git a/benchmark/bm_app_tarai.rb b/benchmark/app_tarai.rb
index 4c146f5ccf..4c146f5ccf 100644
--- a/benchmark/bm_app_tarai.rb
+++ b/benchmark/app_tarai.rb
diff --git a/benchmark/bm_app_uri.rb b/benchmark/app_uri.rb
index 586edfd5dc..586edfd5dc 100644
--- a/benchmark/bm_app_uri.rb
+++ b/benchmark/app_uri.rb
diff --git a/benchmark/array_flatten.yml b/benchmark/array_flatten.yml
new file mode 100644
index 0000000000..88ef544ba0
--- /dev/null
+++ b/benchmark/array_flatten.yml
@@ -0,0 +1,19 @@
+prelude: |
+ small_flat_ary = 5.times.to_a
+ large_flat_ary = 100.times.to_a
+ small_pairs_ary = [[1, 2]] * 5
+ large_pairs_ary = [[1, 2]] * 100
+ mostly_flat_ary = 100.times.to_a.push([101, 102])
+
+benchmark:
+ small_flat_ary.flatten: small_flat_ary.flatten
+ small_flat_ary.flatten!: small_flat_ary.flatten!
+ large_flat_ary.flatten: large_flat_ary.flatten
+ large_flat_ary.flatten!: large_flat_ary.flatten!
+ small_pairs_ary.flatten: small_pairs_ary.flatten
+ small_pairs_ary.flatten!: small_pairs_ary.dup.flatten!
+ large_pairs_ary.flatten: large_pairs_ary.flatten
+ large_pairs_ary.flatten!: large_pairs_ary.dup.flatten!
+ mostly_flat_ary.flatten: mostly_flat_ary.flatten
+ mostly_flat_ary.flatten!: mostly_flat_ary.dup.flatten!
+loop_count: 10000
diff --git a/benchmark/array_intersection.yml b/benchmark/array_intersection.yml
new file mode 100644
index 0000000000..26705323fd
--- /dev/null
+++ b/benchmark/array_intersection.yml
@@ -0,0 +1,14 @@
+prelude: |
+ small1 = [1, 2, 3]
+ small2 = [1, 2, 3, 4, 5]
+ small3 = [2, 3, 4, 5]
+ small4 = [2]
+ big1 = [1, 2, 3, 4] * 64
+ big2 = [1, 2, 3] * 64
+ big3 = [1, 2] * 64
+
+benchmark:
+ small-&: small1 & small2 & small3 & small4
+ small-intersection: small1.intersection(small2, small3, small4)
+ big-&: big1 & big2 & big3
+ big-intersection: big1.intersection(big2, big3)
diff --git a/benchmark/array_max_float.yml b/benchmark/array_max_float.yml
new file mode 100644
index 0000000000..ace1ae2e14
--- /dev/null
+++ b/benchmark/array_max_float.yml
@@ -0,0 +1,30 @@
+prelude: |
+ ary2 = 2.times.map(&:to_f).shuffle
+ ary10 = 10.times.map(&:to_f).shuffle
+ ary100 = 100.times.map(&:to_f).shuffle
+ ary500 = 500.times.map(&:to_f).shuffle
+ ary1000 = 1000.times.map(&:to_f).shuffle
+ ary2000 = 2500.times.map(&:to_f).shuffle
+ ary3000 = 2500.times.map(&:to_f).shuffle
+ ary5000 = 5000.times.map(&:to_f).shuffle
+ ary10000 = 10000.times.map(&:to_f).shuffle
+ ary20000 = 20000.times.map(&:to_f).shuffle
+ ary50000 = 50000.times.map(&:to_f).shuffle
+ ary100000 = 100000.times.map(&:to_f).shuffle
+
+benchmark:
+ ary2.max: ary2.max
+ ary10.max: ary10.max
+ ary100.max: ary100.max
+ ary500.max: ary500.max
+ ary1000.max: ary1000.max
+ ary2000.max: ary2000.max
+ ary3000.max: ary3000.max
+ ary5000.max: ary5000.max
+ ary10000.max: ary10000.max
+ ary20000.max: ary20000.max
+ ary50000.max: ary50000.max
+ ary100000.max: ary100000.max
+
+loop_count: 10000
+
diff --git a/benchmark/array_max_int.yml b/benchmark/array_max_int.yml
new file mode 100644
index 0000000000..acd83684d0
--- /dev/null
+++ b/benchmark/array_max_int.yml
@@ -0,0 +1,31 @@
+prelude: |
+ ary2 = 2.times.to_a.shuffle
+ ary10 = 10.times.to_a.shuffle
+ ary100 = 100.times.to_a.shuffle
+ ary500 = 500.times.to_a.shuffle
+ ary1000 = 1000.times.to_a.shuffle
+ ary2000 = 2500.times.to_a.shuffle
+ ary3000 = 2500.times.to_a.shuffle
+ ary5000 = 5000.times.to_a.shuffle
+ ary10000 = 10000.times.to_a.shuffle
+ ary20000 = 20000.times.to_a.shuffle
+ ary50000 = 50000.times.to_a.shuffle
+ ary100000 = 100000.times.to_a.shuffle
+ ary1000000 = 1000000.times.to_a.shuffle
+
+benchmark:
+ ary2.max: ary2.max
+ ary10.max: ary10.max
+ ary100.max: ary100.max
+ ary500.max: ary500.max
+ ary1000.max: ary1000.max
+ ary2000.max: ary2000.max
+ ary3000.max: ary3000.max
+ ary5000.max: ary5000.max
+ ary10000.max: ary10000.max
+ ary20000.max: ary20000.max
+ ary50000.max: ary50000.max
+ ary100000.max: ary100000.max
+ ary1000000.max: ary1000000.max
+
+loop_count: 10000
diff --git a/benchmark/array_max_str.yml b/benchmark/array_max_str.yml
new file mode 100644
index 0000000000..2aeed010f2
--- /dev/null
+++ b/benchmark/array_max_str.yml
@@ -0,0 +1,30 @@
+prelude: |
+ ary2 = 2.times.map(&:to_s).shuffle
+ ary10 = 10.times.map(&:to_s).shuffle
+ ary100 = 100.times.map(&:to_s).shuffle
+ ary500 = 500.times.map(&:to_s).shuffle
+ ary1000 = 1000.times.map(&:to_s).shuffle
+ ary2000 = 2500.times.map(&:to_s).shuffle
+ ary3000 = 2500.times.map(&:to_s).shuffle
+ ary5000 = 5000.times.map(&:to_s).shuffle
+ ary10000 = 10000.times.map(&:to_s).shuffle
+ ary20000 = 20000.times.map(&:to_s).shuffle
+ ary50000 = 50000.times.map(&:to_s).shuffle
+ ary100000 = 100000.times.map(&:to_s).shuffle
+
+benchmark:
+ ary2.max: ary2.max
+ ary10.max: ary10.max
+ ary100.max: ary100.max
+ ary500.max: ary500.max
+ ary1000.max: ary1000.max
+ ary2000.max: ary2000.max
+ ary3000.max: ary3000.max
+ ary5000.max: ary5000.max
+ ary10000.max: ary10000.max
+ ary20000.max: ary20000.max
+ ary50000.max: ary50000.max
+ ary100000.max: ary100000.max
+
+loop_count: 10000
+
diff --git a/benchmark/array_min.yml b/benchmark/array_min.yml
new file mode 100644
index 0000000000..53e5072b14
--- /dev/null
+++ b/benchmark/array_min.yml
@@ -0,0 +1,31 @@
+prelude: |
+ ary2 = 2.times.to_a.shuffle
+ ary10 = 10.times.to_a.shuffle
+ ary100 = 100.times.to_a.shuffle
+ ary500 = 500.times.to_a.shuffle
+ ary1000 = 1000.times.to_a.shuffle
+ ary2000 = 2500.times.to_a.shuffle
+ ary3000 = 2500.times.to_a.shuffle
+ ary5000 = 5000.times.to_a.shuffle
+ ary10000 = 10000.times.to_a.shuffle
+ ary20000 = 20000.times.to_a.shuffle
+ ary50000 = 50000.times.to_a.shuffle
+ ary100000 = 100000.times.to_a.shuffle
+ ary1000000 = 1000000.times.to_a.shuffle
+
+benchmark:
+ ary2.min: ary2.min
+ ary10.min: ary10.min
+ ary100.min: ary100.min
+ ary500.min: ary500.min
+ ary1000.min: ary1000.min
+ ary2000.min: ary2000.min
+ ary3000.min: ary3000.min
+ ary5000.min: ary5000.min
+ ary10000.min: ary10000.min
+ ary20000.min: ary20000.min
+ ary50000.min: ary50000.min
+ ary100000.min: ary100000.min
+ ary1000000.min: ary1000000.min
+
+loop_count: 10000
diff --git a/benchmark/bm_array_sample_100k_10.rb b/benchmark/array_sample_100k_10.rb
index 5f41ecc32b..5f41ecc32b 100644
--- a/benchmark/bm_array_sample_100k_10.rb
+++ b/benchmark/array_sample_100k_10.rb
diff --git a/benchmark/bm_array_sample_100k_11.rb b/benchmark/array_sample_100k_11.rb
index 18b1715319..18b1715319 100644
--- a/benchmark/bm_array_sample_100k_11.rb
+++ b/benchmark/array_sample_100k_11.rb
diff --git a/benchmark/bm_array_sample_100k__100.rb b/benchmark/array_sample_100k__100.rb
index 22863afe89..22863afe89 100644
--- a/benchmark/bm_array_sample_100k__100.rb
+++ b/benchmark/array_sample_100k__100.rb
diff --git a/benchmark/bm_array_sample_100k__1k.rb b/benchmark/array_sample_100k__1k.rb
index 4cd79e6c67..4cd79e6c67 100644
--- a/benchmark/bm_array_sample_100k__1k.rb
+++ b/benchmark/array_sample_100k__1k.rb
diff --git a/benchmark/bm_array_sample_100k__6k.rb b/benchmark/array_sample_100k__6k.rb
index b3d264249e..b3d264249e 100644
--- a/benchmark/bm_array_sample_100k__6k.rb
+++ b/benchmark/array_sample_100k__6k.rb
diff --git a/benchmark/bm_array_sample_100k___10k.rb b/benchmark/array_sample_100k___10k.rb
index 5dd55ec058..5dd55ec058 100644
--- a/benchmark/bm_array_sample_100k___10k.rb
+++ b/benchmark/array_sample_100k___10k.rb
diff --git a/benchmark/bm_array_sample_100k___50k.rb b/benchmark/array_sample_100k___50k.rb
index 1506732c3c..1506732c3c 100644
--- a/benchmark/bm_array_sample_100k___50k.rb
+++ b/benchmark/array_sample_100k___50k.rb
diff --git a/benchmark/bm_array_shift.rb b/benchmark/array_shift.rb
index 798bb9e3f4..798bb9e3f4 100644
--- a/benchmark/bm_array_shift.rb
+++ b/benchmark/array_shift.rb
diff --git a/benchmark/bm_array_small_and.rb b/benchmark/array_small_and.rb
index e53a6edae6..e53a6edae6 100644
--- a/benchmark/bm_array_small_and.rb
+++ b/benchmark/array_small_and.rb
diff --git a/benchmark/bm_array_small_diff.rb b/benchmark/array_small_diff.rb
index 9661ee48db..9661ee48db 100644
--- a/benchmark/bm_array_small_diff.rb
+++ b/benchmark/array_small_diff.rb
diff --git a/benchmark/bm_array_small_or.rb b/benchmark/array_small_or.rb
index c58b5fd1ff..c58b5fd1ff 100644
--- a/benchmark/bm_array_small_or.rb
+++ b/benchmark/array_small_or.rb
diff --git a/benchmark/bm_array_sort_block.rb b/benchmark/array_sort_block.rb
index 3579786056..3579786056 100644
--- a/benchmark/bm_array_sort_block.rb
+++ b/benchmark/array_sort_block.rb
diff --git a/benchmark/bm_array_sort_float.rb b/benchmark/array_sort_float.rb
index 9a6e2f8bd2..9a6e2f8bd2 100644
--- a/benchmark/bm_array_sort_float.rb
+++ b/benchmark/array_sort_float.rb
diff --git a/benchmark/array_values_at_int.rb b/benchmark/array_values_at_int.rb
new file mode 100644
index 0000000000..6cb394cb9f
--- /dev/null
+++ b/benchmark/array_values_at_int.rb
@@ -0,0 +1,2 @@
+ary = Array.new(10000) {|i| i}
+100000.times { ary.values_at(500) }
diff --git a/benchmark/array_values_at_range.rb b/benchmark/array_values_at_range.rb
new file mode 100644
index 0000000000..5b53806d1c
--- /dev/null
+++ b/benchmark/array_values_at_range.rb
@@ -0,0 +1,2 @@
+ary = Array.new(10000) {|i| i}
+100000.times { ary.values_at(1..2000) }
diff --git a/benchmark/bm_bighash.rb b/benchmark/bighash.rb
index e2ad5a5c94..e2ad5a5c94 100644
--- a/benchmark/bm_bighash.rb
+++ b/benchmark/bighash.rb
diff --git a/benchmark/bm_app_aobench.rb b/benchmark/bm_app_aobench.rb
deleted file mode 100644
index 2bd6acfaf8..0000000000
--- a/benchmark/bm_app_aobench.rb
+++ /dev/null
@@ -1,291 +0,0 @@
-# AO render benchmark
-# Original program (C) Syoyo Fujita in Javascript (and other languages)
-# https://code.google.com/p/aobench/
-# Ruby(yarv2llvm) version by Hideki Miura
-#
-
-IMAGE_WIDTH = 256
-IMAGE_HEIGHT = 256
-NSUBSAMPLES = 2
-NAO_SAMPLES = 8
-
-class Vec
- def initialize(x, y, z)
- @x = x
- @y = y
- @z = z
- end
-
- attr_accessor :x, :y, :z
-
- def vadd(b)
- Vec.new(@x + b.x, @y + b.y, @z + b.z)
- end
-
- def vsub(b)
- Vec.new(@x - b.x, @y - b.y, @z - b.z)
- end
-
- def vcross(b)
- Vec.new(@y * b.z - @z * b.y,
- @z * b.x - @x * b.z,
- @x * b.y - @y * b.x)
- end
-
- def vdot(b)
- @x * b.x + @y * b.y + @z * b.z
- end
-
- def vlength
- Math.sqrt(@x * @x + @y * @y + @z * @z)
- end
-
- def vnormalize
- len = vlength
- v = Vec.new(@x, @y, @z)
- if len > 1.0e-17 then
- v.x = v.x / len
- v.y = v.y / len
- v.z = v.z / len
- end
- v
- end
-end
-
-
-class Sphere
- def initialize(center, radius)
- @center = center
- @radius = radius
- end
-
- attr_reader :center, :radius
-
- def intersect(ray, isect)
- rs = ray.org.vsub(@center)
- b = rs.vdot(ray.dir)
- c = rs.vdot(rs) - (@radius * @radius)
- d = b * b - c
- if d > 0.0 then
- t = - b - Math.sqrt(d)
-
- if t > 0.0 and t < isect.t then
- isect.t = t
- isect.hit = true
- isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
- ray.org.y + ray.dir.y * t,
- ray.org.z + ray.dir.z * t)
- n = isect.pl.vsub(@center)
- isect.n = n.vnormalize
- else
- 0.0
- end
- end
- nil
- end
-end
-
-class Plane
- def initialize(p, n)
- @p = p
- @n = n
- end
-
- def intersect(ray, isect)
- d = -@p.vdot(@n)
- v = ray.dir.vdot(@n)
- v0 = v
- if v < 0.0 then
- v0 = -v
- end
- if v0 < 1.0e-17 then
- return
- end
-
- t = -(ray.org.vdot(@n) + d) / v
-
- if t > 0.0 and t < isect.t then
- isect.hit = true
- isect.t = t
- isect.n = @n
- isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
- ray.org.y + t * ray.dir.y,
- ray.org.z + t * ray.dir.z)
- end
- nil
- end
-end
-
-class Ray
- def initialize(org, dir)
- @org = org
- @dir = dir
- end
-
- attr_accessor :org, :dir
-end
-
-class Isect
- def initialize
- @t = 10000000.0
- @hit = false
- @pl = Vec.new(0.0, 0.0, 0.0)
- @n = Vec.new(0.0, 0.0, 0.0)
- end
-
- attr_accessor :t, :hit, :pl, :n
-end
-
-def clamp(f)
- i = f * 255.5
- if i > 255.0 then
- i = 255.0
- end
- if i < 0.0 then
- i = 0.0
- end
- i.to_i
-end
-
-def otherBasis(basis, n)
- basis[2] = Vec.new(n.x, n.y, n.z)
- basis[1] = Vec.new(0.0, 0.0, 0.0)
-
- if n.x < 0.6 and n.x > -0.6 then
- basis[1].x = 1.0
- elsif n.y < 0.6 and n.y > -0.6 then
- basis[1].y = 1.0
- elsif n.z < 0.6 and n.z > -0.6 then
- basis[1].z = 1.0
- else
- basis[1].x = 1.0
- end
-
- basis[0] = basis[1].vcross(basis[2])
- basis[0] = basis[0].vnormalize
-
- basis[1] = basis[2].vcross(basis[0])
- basis[1] = basis[1].vnormalize
-end
-
-class Scene
- def initialize
- @spheres = Array.new
- @spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
- @spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
- @spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
- @plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
- end
-
- def ambient_occlusion(isect)
- basis = Array.new
- otherBasis(basis, isect.n)
-
- ntheta = NAO_SAMPLES
- nphi = NAO_SAMPLES
- eps = 0.0001
- occlusion = 0.0
-
- p0 = Vec.new(isect.pl.x + eps * isect.n.x,
- isect.pl.y + eps * isect.n.y,
- isect.pl.z + eps * isect.n.z)
- nphi.times do |j|
- ntheta.times do |i|
- r = rand
- phi = 2.0 * 3.14159265 * rand
- x = Math.cos(phi) * Math.sqrt(1.0 - r)
- y = Math.sin(phi) * Math.sqrt(1.0 - r)
- z = Math.sqrt(r)
-
- rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
- ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
- rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
-
- raydir = Vec.new(rx, ry, rz)
- ray = Ray.new(p0, raydir)
-
- occisect = Isect.new
- @spheres[0].intersect(ray, occisect)
- @spheres[1].intersect(ray, occisect)
- @spheres[2].intersect(ray, occisect)
- @plane.intersect(ray, occisect)
- if occisect.hit then
- occlusion = occlusion + 1.0
- else
- 0.0
- end
- end
- end
-
- occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
-
- Vec.new(occlusion, occlusion, occlusion)
- end
-
- def render(w, h, nsubsamples)
- cnt = 0
- nsf = nsubsamples.to_f
- h.times do |y|
- w.times do |x|
- rad = Vec.new(0.0, 0.0, 0.0)
-
- # Subsampling
- nsubsamples.times do |v|
- nsubsamples.times do |u|
-
- cnt = cnt + 1
- wf = w.to_f
- hf = h.to_f
- xf = x.to_f
- yf = y.to_f
- uf = u.to_f
- vf = v.to_f
-
- px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
- py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
-
- eye = Vec.new(px, py, -1.0).vnormalize
-
- ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
-
- isect = Isect.new
- @spheres[0].intersect(ray, isect)
- @spheres[1].intersect(ray, isect)
- @spheres[2].intersect(ray, isect)
- @plane.intersect(ray, isect)
- if isect.hit then
- col = ambient_occlusion(isect)
- rad.x = rad.x + col.x
- rad.y = rad.y + col.y
- rad.z = rad.z + col.z
- end
- end
- end
-
- r = rad.x / (nsf * nsf)
- g = rad.y / (nsf * nsf)
- b = rad.z / (nsf * nsf)
- printf("%c", clamp(r))
- printf("%c", clamp(g))
- printf("%c", clamp(b))
- end
- nil
- end
-
- nil
- end
-end
-
-alias printf_orig printf
-def printf *args
-end
-
-# File.open("ao.ppm", "w") do |fp|
- printf("P6\n")
- printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
- printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT)
- Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
-# end
-
-undef printf
-alias printf printf_orig
diff --git a/benchmark/bm_app_erb.rb b/benchmark/bm_app_erb.rb
deleted file mode 100644
index 77c66a7949..0000000000
--- a/benchmark/bm_app_erb.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Create many HTML strings with ERB.
-#
-
-require 'erb'
-
-data = DATA.read
-max = 15_000
-title = "hello world!"
-content = "hello world!\n" * 10
-
-max.times{
- ERB.new(data).result(binding)
-}
-
-__END__
-
-<html>
- <head> <%= title %> </head>
- <body>
- <h1> <%= title %> </h1>
- <p>
- <%= content %>
- </p>
- </body>
-</html>
diff --git a/benchmark/bm_app_pentomino.rb b/benchmark/bm_app_pentomino.rb
deleted file mode 100644
index 59c63f358e..0000000000
--- a/benchmark/bm_app_pentomino.rb
+++ /dev/null
@@ -1,259 +0,0 @@
-#!/usr/local/bin/ruby
-# This program is contributed by Shin Nishiyama
-
-
-# modified by K.Sasada
-
-NP = 5
-ROW = 8 + NP
-COL = 8
-
-$p = []
-$b = []
-$no = 0
-
-def piece(n, a, nb)
- nb.each{|x|
- a[n] = x
- if n == NP-1
- $p << [a.sort]
- else
- nbc=nb.dup
- [-ROW, -1, 1, ROW].each{|d|
- if x+d > 0 and not a.include?(x+d) and not nbc.include?(x+d)
- nbc << x+d
- end
- }
- nbc.delete x
- piece(n+1,a[0..n],nbc)
- end
- }
-end
-
-def kikaku(a)
- a.collect {|x| x - a[0]}
-end
-def ud(a)
- kikaku(a.collect {|x| ((x+NP)%ROW)-ROW*((x+NP)/ROW) }.sort)
-end
-def rl(a)
- kikaku(a.collect {|x| ROW*((x+NP)/ROW)+ROW-((x+NP)%ROW)}.sort)
-end
-def xy(a)
- kikaku(a.collect {|x| ROW*((x+NP)%ROW) + (x+NP)/ROW }.sort)
-end
-
-def mkpieces
- piece(0,[],[0])
- $p.each do |a|
- a0 = a[0]
- a[1] = ud(a0)
- a[2] = rl(a0)
- a[3] = ud(rl(a0))
- a[4] = xy(a0)
- a[5] = ud(xy(a0))
- a[6] = rl(xy(a0))
- a[7] = ud(rl(xy(a0)))
- a.sort!
- a.uniq!
- end
- $p.uniq!.sort! {|x,y| x[0] <=> y[0] }
-end
-
-def mkboard
- (0...ROW*COL).each{|i|
- if i % ROW >= ROW-NP
- $b[i] = -2
- else
- $b[i] = -1
- end
- $b[3*ROW+3]=$b[3*ROW+4]=$b[4*ROW+3]=$b[4*ROW+4]=-2
- }
-end
-
-def pboard
- return # skip print
- print "No. #$no\n"
- (0...COL).each{|i|
- print "|"
- (0...ROW-NP).each{|j|
- x = $b[i*ROW+j]
- if x < 0
- print "..|"
- else
- printf "%2d|",x+1
- end
- }
- print "\n"
- }
- print "\n"
-end
-
-$pnum=[]
-def setpiece(a,pos)
- if a.length == $p.length then
- $no += 1
- pboard
- return
- end
- while $b[pos] != -1
- pos += 1
- end
- ($pnum - a).each do |i|
- $p[i].each do |x|
- f = 0
- x.each{|s|
- if $b[pos+s] != -1
- f=1
- break
- end
- }
- if f == 0 then
- x.each{|s|
- $b[pos+s] = i
- }
- a << i
- setpiece(a.dup, pos)
- a.pop
- x.each{|s|
- $b[pos+s] = -1
- }
- end
- end
- end
-end
-
-mkpieces
-mkboard
-$p[4] = [$p[4][0]]
-$pnum = (0...$p.length).to_a
-setpiece([],0)
-
-
-__END__
-
-# original
-
-NP = 5
-ROW = 8 + NP
-COL = 8
-
-$p = []
-$b = []
-$no = 0
-
-def piece(n,a,nb)
- for x in nb
- a[n] = x
- if n == NP-1
- $p << [a.sort]
- else
- nbc=nb.dup
- for d in [-ROW, -1, 1, ROW]
- if x+d > 0 and not a.include?(x+d) and not nbc.include?(x+d)
- nbc << x+d
- end
- end
- nbc.delete x
- piece(n+1,a[0..n],nbc)
- end
- end
-end
-
-def kikaku(a)
- a.collect {|x| x - a[0]}
-end
-def ud(a)
- kikaku(a.collect {|x| ((x+NP)%ROW)-ROW*((x+NP)/ROW) }.sort)
-end
-def rl(a)
- kikaku(a.collect {|x| ROW*((x+NP)/ROW)+ROW-((x+NP)%ROW)}.sort)
-end
-def xy(a)
- kikaku(a.collect {|x| ROW*((x+NP)%ROW) + (x+NP)/ROW }.sort)
-end
-
-def mkpieces
- piece(0,[],[0])
- $p.each do |a|
- a0 = a[0]
- a[1] = ud(a0)
- a[2] = rl(a0)
- a[3] = ud(rl(a0))
- a[4] = xy(a0)
- a[5] = ud(xy(a0))
- a[6] = rl(xy(a0))
- a[7] = ud(rl(xy(a0)))
- a.sort!
- a.uniq!
- end
- $p.uniq!.sort! {|x,y| x[0] <=> y[0] }
-end
-
-def mkboard
- for i in 0...ROW*COL
- if i % ROW >= ROW-NP
- $b[i] = -2
- else
- $b[i] = -1
- end
- $b[3*ROW+3]=$b[3*ROW+4]=$b[4*ROW+3]=$b[4*ROW+4]=-2
- end
-end
-
-def pboard
- print "No. #$no\n"
- for i in 0...COL
- print "|"
- for j in 0...ROW-NP
- x = $b[i*ROW+j]
- if x < 0
- print "..|"
- else
- printf "%2d|",x+1
- end
- end
- print "\n"
- end
- print "\n"
-end
-
-$pnum=[]
-def setpiece(a,pos)
- if a.length == $p.length then
- $no += 1
- pboard
- return
- end
- while $b[pos] != -1
- pos += 1
- end
- ($pnum - a).each do |i|
- $p[i].each do |x|
- f = 0
- for s in x do
- if $b[pos+s] != -1
- f=1
- break
- end
- end
- if f == 0 then
- for s in x do
- $b[pos+s] = i
- end
- a << i
- setpiece(a.dup, pos)
- a.pop
- for s in x do
- $b[pos+s] = -1
- end
- end
- end
- end
-end
-
-mkpieces
-mkboard
-$p[4] = [$p[4][0]]
-$pnum = (0...$p.length).to_a
-setpiece([],0)
diff --git a/benchmark/bm_erb_render.rb b/benchmark/bm_erb_render.rb
deleted file mode 100644
index d2929b0553..0000000000
--- a/benchmark/bm_erb_render.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-require 'erb'
-
-data = DATA.read
-max = 1_500_000
-title = "hello world!"
-content = "hello world!\n" * 10
-
-src = "def self.render(title, content); #{ERB.new(data).src}; end"
-mod = Module.new
-mod.instance_eval(src, "(ERB)")
-
-max.times do
- mod.render(title, content)
-end
-
-__END__
-
-<html>
- <head> <%= title %> </head>
- <body>
- <h1> <%= title %> </h1>
- <p>
- <%= content %>
- </p>
- </body>
-</html>
diff --git a/benchmark/bm_file_rename.rb b/benchmark/bm_file_rename.rb
deleted file mode 100644
index 3bf6a5ef35..0000000000
--- a/benchmark/bm_file_rename.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# rename file
-require 'tempfile'
-
-max = 100_000
-tmp = [ Tempfile.new('rename-a'), Tempfile.new('rename-b') ]
-a, b = tmp.map { |x| x.path }
-max.times do
- File.rename(a, b)
- File.rename(b, a)
-end
-tmp.each { |t| t.close! }
diff --git a/benchmark/bm_require.rb b/benchmark/bm_require.rb
deleted file mode 100644
index b8abc88f41..0000000000
--- a/benchmark/bm_require.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-$:.push File.join(File.dirname(__FILE__), "bm_require.data")
-
-1.upto(10000) do |i|
- require "c#{i}"
-end
-
-$:.pop
diff --git a/benchmark/bm_require_thread.rb b/benchmark/bm_require_thread.rb
deleted file mode 100644
index e54db6c6e5..0000000000
--- a/benchmark/bm_require_thread.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-$:.push File.join(File.dirname(__FILE__), "bm_require.data")
-
-i=0
-t = Thread.new do
- while true
- i = i+1 # dummy loop
- end
-end
-
-1.upto(100) do |i|
- require "c#{i}"
-end
-
-$:.pop
-t.kill
diff --git a/benchmark/bm_so_ackermann.rb b/benchmark/bm_so_ackermann.rb
deleted file mode 100644
index 7db5be9050..0000000000
--- a/benchmark/bm_so_ackermann.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: ackermann-ruby.code,v 1.4 2004/11/13 07:40:41 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-
-def ack(m, n)
- if m == 0 then
- n + 1
- elsif n == 0 then
- ack(m - 1, 1)
- else
- ack(m - 1, ack(m, n - 1))
- end
-end
-
-NUM = 9
-ack(3, NUM)
-
-
diff --git a/benchmark/bm_so_array.rb b/benchmark/bm_so_array.rb
deleted file mode 100644
index 2b8fce8f99..0000000000
--- a/benchmark/bm_so_array.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: ary-ruby.code,v 1.4 2004/11/13 07:41:27 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-# with help from Paul Brannan and Mark Hubbart
-
-n = 9000 # Integer(ARGV.shift || 1)
-
-x = Array.new(n)
-y = Array.new(n, 0)
-
-n.times{|bi|
- x[bi] = bi + 1
-}
-
-(0 .. 999).each do |e|
- (n-1).step(0,-1) do |bi|
- y[bi] += x.at(bi)
- end
-end
-# puts "#{y.first} #{y.last}"
-
-
diff --git a/benchmark/bm_so_concatenate.rb b/benchmark/bm_so_concatenate.rb
deleted file mode 100644
index 873214de7c..0000000000
--- a/benchmark/bm_so_concatenate.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: strcat-ruby.code,v 1.4 2004/11/13 07:43:28 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-# based on code from Aristarkh A Zagorodnikov and Dat Nguyen
-
-STUFF = "hello\n"
-i = 0
-while i<10
- i += 1
- hello = ''
- 4_000_000.times do |e|
- hello << STUFF
- end
-end
-# puts hello.length
-
-
diff --git a/benchmark/bm_so_count_words.rb b/benchmark/bm_so_count_words.rb
deleted file mode 100644
index 65f6337a4a..0000000000
--- a/benchmark/bm_so_count_words.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: wc-ruby.code,v 1.4 2004/11/13 07:43:32 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-# with help from Paul Brannan
-
-input = open(File.join(File.dirname($0), 'wc.input'), 'rb')
-
-nl = nw = nc = 0
-while true
- tmp = input.read(4096) or break
- data = tmp << (input.gets || "")
- nc += data.length
- nl += data.count("\n")
- ((data.strip! || data).tr!("\n", " ") || data).squeeze!
- nw += data.count(" ") + 1
-end
-# STDERR.puts "#{nl} #{nw} #{nc}"
-
diff --git a/benchmark/bm_so_exception.rb b/benchmark/bm_so_exception.rb
deleted file mode 100644
index deb003a594..0000000000
--- a/benchmark/bm_so_exception.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: except-ruby.code,v 1.4 2004/11/13 07:41:33 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-
-$HI = 0
-$LO = 0
-NUM = 250000 # Integer(ARGV[0] || 1)
-
-
-class Lo_Exception < Exception
- def initialize(num)
- @value = num
- end
-end
-
-class Hi_Exception < Exception
- def initialize(num)
- @value = num
- end
-end
-
-def some_function(num)
- begin
- hi_function(num)
- rescue
- print "We shouldn't get here, exception is: #{$!.type}\n"
- end
-end
-
-def hi_function(num)
- begin
- lo_function(num)
- rescue Hi_Exception
- $HI = $HI + 1
- end
-end
-
-def lo_function(num)
- begin
- blowup(num)
- rescue Lo_Exception
- $LO = $LO + 1
- end
-end
-
-def blowup(num)
- if num % 2 == 0
- raise Lo_Exception.new(num)
- else
- raise Hi_Exception.new(num)
- end
-end
-
-
-i = 1
-max = NUM+1
-while i < max
- i += 1
- some_function(i+1)
-end
diff --git a/benchmark/bm_so_k_nucleotide.rb b/benchmark/bm_so_k_nucleotide.rb
deleted file mode 100644
index dadab3e79c..0000000000
--- a/benchmark/bm_so_k_nucleotide.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# The Computer Language Shootout
-# http://shootout.alioth.debian.org
-#
-# contributed by jose fco. gonzalez
-# modified by Sokolov Yura
-
-seq = String.new
-
-def frecuency( seq,length )
- n, table = seq.length - length + 1, Hash.new(0)
- f, i = nil, nil
- (0 ... length).each do |f|
- (f ... n).step(length) do |i|
- table[seq[i,length]] += 1
- end
- end
- [n,table]
-
-end
-
-def sort_by_freq( seq,length )
- n,table = frecuency( seq,length )
- a, b, v = nil, nil, nil
- table.sort{|a,b| b[1] <=> a[1]}.each do |v|
- puts "%s %.3f" % [v[0].upcase,((v[1]*100).to_f/n)]
- end
- puts
-end
-
-def find_seq( seq,s )
- n,table = frecuency( seq,s.length )
- puts "#{table[s].to_s}\t#{s.upcase}"
-end
-
-input = open(File.join(File.dirname($0), 'fasta.output.100000'), 'rb')
-
-line = input.gets while line !~ /^>THREE/
-line = input.gets
-
-while (line !~ /^>/) & line do
- seq << line.chomp
- line = input.gets
-end
-
-[1,2].each {|i| sort_by_freq( seq,i ) }
-
-%w(ggt ggta ggtatt ggtattttaatt ggtattttaatttatagt).each{|s| find_seq( seq,s) }
-
diff --git a/benchmark/bm_so_matrix.rb b/benchmark/bm_so_matrix.rb
deleted file mode 100644
index e2c5c8e559..0000000000
--- a/benchmark/bm_so_matrix.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: matrix-ruby.code,v 1.4 2004/11/13 07:42:14 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-
-n = 60 #Integer(ARGV.shift || 1)
-
-size = 40
-
-def mkmatrix(rows, cols)
- count = 1
- mx = Array.new(rows)
- (0 .. (rows - 1)).each do |bi|
- row = Array.new(cols, 0)
- (0 .. (cols - 1)).each do |j|
- row[j] = count
- count += 1
- end
- mx[bi] = row
- end
- mx
-end
-
-def mmult(rows, cols, m1, m2)
- m3 = Array.new(rows)
- (0 .. (rows - 1)).each do |bi|
- row = Array.new(cols, 0)
- (0 .. (cols - 1)).each do |j|
- val = 0
- (0 .. (cols - 1)).each do |k|
- val += m1.at(bi).at(k) * m2.at(k).at(j)
- end
- row[j] = val
- end
- m3[bi] = row
- end
- m3
-end
-
-m1 = mkmatrix(size, size)
-m2 = mkmatrix(size, size)
-mm = Array.new
-n.times do
- mm = mmult(size, size, m1, m2)
-end
-# puts "#{mm[0][0]} #{mm[2][3]} #{mm[3][2]} #{mm[4][4]}"
-
-
diff --git a/benchmark/bm_so_nested_loop.rb b/benchmark/bm_so_nested_loop.rb
deleted file mode 100644
index a0513f8c47..0000000000
--- a/benchmark/bm_so_nested_loop.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: nestedloop-ruby.code,v 1.4 2004/11/13 07:42:22 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-# from Avi Bryant
-
-n = 16 # Integer(ARGV.shift || 1)
-x = 0
-n.times do
- n.times do
- n.times do
- n.times do
- n.times do
- n.times do
- x += 1
- end
- end
- end
- end
- end
-end
-# puts x
-
-
diff --git a/benchmark/bm_so_object.rb b/benchmark/bm_so_object.rb
deleted file mode 100644
index e8607c7199..0000000000
--- a/benchmark/bm_so_object.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/ruby
-# -*- mode: ruby -*-
-# $Id: objinst-ruby.code,v 1.4 2004/11/13 07:42:25 bfulgham Exp $
-# http://www.bagley.org/~doug/shootout/
-# with help from Aristarkh Zagorodnikov
-
-class Toggle
- def initialize(start_state)
- @bool = start_state
- end
-
- def value
- @bool
- end
-
- def activate
- @bool = !@bool
- self
- end
-end
-
-class NthToggle < Toggle
- def initialize(start_state, max_counter)
- super start_state
- @count_max = max_counter
- @counter = 0
- end
-
- def activate
- @counter += 1
- if @counter >= @count_max
- @bool = !@bool
- @counter = 0
- end
- self
- end
-end
-
-n = 1500000 # (ARGV.shift || 1).to_i
-
-toggle = Toggle.new 1
-5.times do
- toggle.activate.value ? 'true' : 'false'
-end
-n.times do
- toggle = Toggle.new 1
-end
-
-ntoggle = NthToggle.new 1, 3
-8.times do
- ntoggle.activate.value ? 'true' : 'false'
-end
-n.times do
- ntoggle = NthToggle.new 1, 3
-end
-
diff --git a/benchmark/bm_so_reverse_complement.rb b/benchmark/bm_so_reverse_complement.rb
deleted file mode 100644
index 82ea666994..0000000000
--- a/benchmark/bm_so_reverse_complement.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/ruby
-# The Great Computer Language Shootout
-# http://shootout.alioth.debian.org/
-#
-# Contributed by Peter Bjarke Olsen
-# Modified by Doug King
-
-seq=Array.new
-
-def revcomp(seq)
- seq.reverse!.tr!('wsatugcyrkmbdhvnATUGCYRKMBDHVN','WSTAACGRYMKVHDBNTAACGRYMKVHDBN')
- stringlen=seq.length
- 0.step(stringlen-1,60) {|x| print seq.slice(x,60) , "\n"}
-end
-
-input = open(File.join(File.dirname($0), 'fasta.output.2500000'), 'rb')
-
-while input.gets
- if $_ =~ />/
- if seq.length != 0
- revcomp(seq.join)
- seq=Array.new
- end
- puts $_
- else
- $_.sub(/\n/,'')
- seq.push $_
- end
-end
-revcomp(seq.join)
diff --git a/benchmark/bm_vm1_attr_ivar.rb b/benchmark/bm_vm1_attr_ivar.rb
deleted file mode 100644
index 16906f3605..0000000000
--- a/benchmark/bm_vm1_attr_ivar.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class C
- attr_reader :a, :b
- def initialize
- @a = nil
- @b = nil
- end
-end
-obj = C.new
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- j = obj.a
- k = obj.b
-end
diff --git a/benchmark/bm_vm1_attr_ivar_set.rb b/benchmark/bm_vm1_attr_ivar_set.rb
deleted file mode 100644
index 7e7a6b48c0..0000000000
--- a/benchmark/bm_vm1_attr_ivar_set.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class C
- attr_accessor :a, :b
- def initialize
- @a = nil
- @b = nil
- end
-end
-obj = C.new
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- obj.a = 1
- obj.b = 2
-end
diff --git a/benchmark/bm_vm1_block.rb b/benchmark/bm_vm1_block.rb
deleted file mode 100644
index a9f56b15ea..0000000000
--- a/benchmark/bm_vm1_block.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-def m
- yield
-end
-
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- m{
- }
-end
diff --git a/benchmark/bm_vm1_const.rb b/benchmark/bm_vm1_const.rb
deleted file mode 100644
index ac59ebccf1..0000000000
--- a/benchmark/bm_vm1_const.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-Const = 1
-
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- j = Const
- k = Const
-end
diff --git a/benchmark/bm_vm1_ensure.rb b/benchmark/bm_vm1_ensure.rb
deleted file mode 100644
index a1596145f2..0000000000
--- a/benchmark/bm_vm1_ensure.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-i = 0
-while i<30_000_000 # benchmark loop 1
- i += 1
- begin
- begin
- ensure
- end
- ensure
- end
-end
-
diff --git a/benchmark/bm_vm1_float_simple.rb b/benchmark/bm_vm1_float_simple.rb
deleted file mode 100644
index d4581439ff..0000000000
--- a/benchmark/bm_vm1_float_simple.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-i = 0.0; f = 0.0
-while i<30_000_000
- i += 1
- f += 0.1; f -= 0.1
- f += 0.1; f -= 0.1
- f += 0.1; f -= 0.1
-end
diff --git a/benchmark/bm_vm1_gc_short_lived.rb b/benchmark/bm_vm1_gc_short_lived.rb
deleted file mode 100644
index e78bca5668..0000000000
--- a/benchmark/bm_vm1_gc_short_lived.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-i = 0
-while i<30_000_000 # while loop 1
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
- i+=1
-end
diff --git a/benchmark/bm_vm1_gc_short_with_complex_long.rb b/benchmark/bm_vm1_gc_short_with_complex_long.rb
deleted file mode 100644
index b66052dee0..0000000000
--- a/benchmark/bm_vm1_gc_short_with_complex_long.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-def nested_hash h, n
- if n == 0
- ''
- else
- 10.times{
- h[Object.new] = nested_hash(h, n-1)
- }
- end
-end
-
-long_lived = Hash.new
-nested_hash long_lived, 6
-
-GC.start
-GC.start
-
-i = 0
-while i<30_000_000 # while loop 1
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
- i+=1
-end
-
diff --git a/benchmark/bm_vm1_gc_short_with_long.rb b/benchmark/bm_vm1_gc_short_with_long.rb
deleted file mode 100644
index 298dbc845b..0000000000
--- a/benchmark/bm_vm1_gc_short_with_long.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-long_lived = Array.new(1_000_000){|i| "#{i}"}
-GC.start
-GC.start
-i = 0
-while i<30_000_000 # while loop 1
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
- i+=1
-end
diff --git a/benchmark/bm_vm1_gc_short_with_symbol.rb b/benchmark/bm_vm1_gc_short_with_symbol.rb
deleted file mode 100644
index 6b15c1b7bf..0000000000
--- a/benchmark/bm_vm1_gc_short_with_symbol.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# make many symbols
-50_000.times{|i| sym = "sym#{i}".to_sym}
-GC.start
-GC.start
-
-i = 0
-while i<30_000_000 # while loop 1
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
- i+=1
-end
diff --git a/benchmark/bm_vm1_gc_wb_ary.rb b/benchmark/bm_vm1_gc_wb_ary.rb
deleted file mode 100644
index 1b030386cf..0000000000
--- a/benchmark/bm_vm1_gc_wb_ary.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-short_lived_ary = []
-
-if RUBY_VERSION >= "2.2.0"
- GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
-end
-
-i = 0
-short_lived = ''
-while i<30_000_000 # while loop 1
- short_lived_ary[0] = short_lived # write barrier
- i+=1
-end
diff --git a/benchmark/bm_vm1_gc_wb_ary_promoted.rb b/benchmark/bm_vm1_gc_wb_ary_promoted.rb
deleted file mode 100644
index ebc369a60f..0000000000
--- a/benchmark/bm_vm1_gc_wb_ary_promoted.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-long_lived = []
-
-if RUBY_VERSION > "2.2.0"
- 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
-elsif
- GC.start
-end
-
-i = 0
-short_lived = ''
-while i<30_000_000 # while loop 1
- long_lived[0] = short_lived # write barrier
- i+=1
-end
diff --git a/benchmark/bm_vm1_gc_wb_obj.rb b/benchmark/bm_vm1_gc_wb_obj.rb
deleted file mode 100644
index 96f4261915..0000000000
--- a/benchmark/bm_vm1_gc_wb_obj.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class C
- attr_accessor :foo
-end
-short_lived_obj = C.new
-
-if RUBY_VERSION >= "2.2.0"
- GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
-end
-
-i = 0
-short_lived = ''
-while i<30_000_000 # while loop 1
- short_lived_obj.foo = short_lived # write barrier
- i+=1
-end
diff --git a/benchmark/bm_vm1_gc_wb_obj_promoted.rb b/benchmark/bm_vm1_gc_wb_obj_promoted.rb
deleted file mode 100644
index 674c413992..0000000000
--- a/benchmark/bm_vm1_gc_wb_obj_promoted.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class C
- attr_accessor :foo
-end
-long_lived = C.new
-
-if RUBY_VERSION >= "2.2.0"
- 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
-elsif
- GC.start
-end
-
-i = 0
-short_lived = ''
-while i<30_000_000 # while loop 1
- long_lived.foo = short_lived # write barrier
- i+=1
-end
diff --git a/benchmark/bm_vm1_ivar.rb b/benchmark/bm_vm1_ivar.rb
deleted file mode 100644
index 68a73cf92f..0000000000
--- a/benchmark/bm_vm1_ivar.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-@a = 1
-
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- j = @a
- k = @a
-end
diff --git a/benchmark/bm_vm1_ivar_set.rb b/benchmark/bm_vm1_ivar_set.rb
deleted file mode 100644
index bd81b06c34..0000000000
--- a/benchmark/bm_vm1_ivar_set.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- @a = 1
- @b = 2
-end
diff --git a/benchmark/bm_vm1_length.rb b/benchmark/bm_vm1_length.rb
deleted file mode 100644
index 353de3ab0e..0000000000
--- a/benchmark/bm_vm1_length.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-a = 'abc'
-b = [1, 2, 3]
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- a.length
- b.length
-end
-
diff --git a/benchmark/bm_vm1_lvar_init.rb b/benchmark/bm_vm1_lvar_init.rb
deleted file mode 100644
index 36f2068811..0000000000
--- a/benchmark/bm_vm1_lvar_init.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-def m v
- unless v
- # unreachable code
- v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = v10 =
- v11 = v12 = v13 = v14 = v15 = v16 = v17 = v18 = v19 = v20 =
- v21 = v22 = v23 = v24 = v25 = v26 = v27 = v28 = v29 = v30 =
- v31 = v32 = v33 = v34 = v35 = v36 = v37 = v38 = v39 = v40 =
- v41 = v42 = v43 = v44 = v45 = v46 = v47 = v48 = v49 = v50 = 1
- end
-end
-
-i = 0
-
-while i<30_000_000 # while loop 1
- i += 1
- m i
-end
-
diff --git a/benchmark/bm_vm1_lvar_set.rb b/benchmark/bm_vm1_lvar_set.rb
deleted file mode 100644
index 222e864134..0000000000
--- a/benchmark/bm_vm1_lvar_set.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- a = b = c = d = e = f = g = h = j = k = l = m = n = o = p = q = r = 1
-end
diff --git a/benchmark/bm_vm1_neq.rb b/benchmark/bm_vm1_neq.rb
deleted file mode 100644
index bbb4ae07a4..0000000000
--- a/benchmark/bm_vm1_neq.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-i = 0
-obj1 = Object.new
-obj2 = Object.new
-
-while i<30_000_000 # while loop 1
- i += 1
- obj1 != obj2
-end
diff --git a/benchmark/bm_vm1_not.rb b/benchmark/bm_vm1_not.rb
deleted file mode 100644
index b09ecdcc21..0000000000
--- a/benchmark/bm_vm1_not.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-i = 0
-obj = Object.new
-
-while i<30_000_000 # while loop 1
- i += 1
- !obj
-end
diff --git a/benchmark/bm_vm1_rescue.rb b/benchmark/bm_vm1_rescue.rb
deleted file mode 100644
index b0d3e2bdfa..0000000000
--- a/benchmark/bm_vm1_rescue.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- begin
- rescue
- end
-end
diff --git a/benchmark/bm_vm1_simplereturn.rb b/benchmark/bm_vm1_simplereturn.rb
deleted file mode 100644
index 63f9f21675..0000000000
--- a/benchmark/bm_vm1_simplereturn.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-def m
- return 1
-end
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- m
-end
-
diff --git a/benchmark/bm_vm1_swap.rb b/benchmark/bm_vm1_swap.rb
deleted file mode 100644
index 918f8b2112..0000000000
--- a/benchmark/bm_vm1_swap.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-a = 1
-b = 2
-i = 0
-while i<30_000_000 # while loop 1
- i += 1
- a, b = b, a
-end
-
diff --git a/benchmark/bm_vm1_yield.rb b/benchmark/bm_vm1_yield.rb
deleted file mode 100644
index 775597cea6..0000000000
--- a/benchmark/bm_vm1_yield.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-def m
- i = 0
- while i<30_000_000 # while loop 1
- i += 1
- yield
- end
-end
-
-m{}
-
diff --git a/benchmark/bm_vm2_array.rb b/benchmark/bm_vm2_array.rb
deleted file mode 100644
index df9037c83c..0000000000
--- a/benchmark/bm_vm2_array.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- a = [1,2,3,4,5,6,7,8,9,10]
-end
diff --git a/benchmark/bm_vm2_bigarray.rb b/benchmark/bm_vm2_bigarray.rb
deleted file mode 100644
index b02509d6a2..0000000000
--- a/benchmark/bm_vm2_bigarray.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- a = [
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- ]
-end
diff --git a/benchmark/bm_vm2_bighash.rb b/benchmark/bm_vm2_bighash.rb
deleted file mode 100644
index 5e3f437bb8..0000000000
--- a/benchmark/bm_vm2_bighash.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-i = 0
-while i<60_000 # benchmark loop 2
- i += 1
- a = {0=>0, 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, 18=>18, 19=>19, 20=>20, 21=>21, 22=>22, 23=>23, 24=>24, 25=>25, 26=>26, 27=>27, 28=>28, 29=>29, 30=>30, 31=>31, 32=>32, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 38=>38, 39=>39, 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, 60=>60, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67, 68=>68, 69=>69, 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79, 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, 90=>90, 91=>91, 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, 100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, 110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, 120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126, 127=>127, 128=>128, 129=>129, 130=>130, 131=>131, 132=>132, 133=>133, 134=>134, 135=>135, 136=>136, 137=>137, 138=>138, 139=>139, 140=>140, 141=>141, 142=>142, 143=>143, 144=>144, 145=>145, 146=>146, 147=>147, 148=>148, 149=>149, 150=>150, 151=>151, 152=>152, 153=>153, 154=>154, 155=>155, 156=>156, 157=>157, 158=>158, 159=>159, 160=>160, 161=>161, 162=>162, 163=>163, 164=>164, 165=>165, 166=>166, 167=>167, 168=>168, 169=>169, 170=>170, 171=>171, 172=>172, 173=>173, 174=>174, 175=>175, 176=>176, 177=>177, 178=>178, 179=>179, 180=>180, 181=>181, 182=>182, 183=>183, 184=>184, 185=>185, 186=>186, 187=>187, 188=>188, 189=>189, 190=>190, 191=>191, 192=>192, 193=>193, 194=>194, 195=>195, 196=>196, 197=>197, 198=>198, 199=>199, 200=>200, 201=>201, 202=>202, 203=>203, 204=>204, 205=>205, 206=>206, 207=>207, 208=>208, 209=>209, 210=>210, 211=>211, 212=>212, 213=>213, 214=>214, 215=>215, 216=>216, 217=>217, 218=>218, 219=>219, 220=>220, 221=>221, 222=>222, 223=>223, 224=>224, 225=>225, 226=>226, 227=>227, 228=>228, 229=>229, 230=>230, 231=>231, 232=>232, 233=>233, 234=>234, 235=>235, 236=>236, 237=>237, 238=>238, 239=>239, 240=>240, 241=>241, 242=>242, 243=>243, 244=>244, 245=>245, 246=>246, 247=>247, 248=>248, 249=>249, 250=>250, 251=>251, 252=>252, 253=>253, 254=>254, 255=>255, 256=>256, 257=>257, 258=>258, 259=>259, 260=>260, 261=>261, 262=>262, 263=>263, 264=>264, 265=>265, 266=>266, 267=>267, 268=>268, 269=>269, 270=>270, 271=>271, 272=>272, 273=>273, 274=>274, 275=>275, 276=>276, 277=>277, 278=>278, 279=>279, 280=>280, 281=>281, 282=>282, 283=>283, 284=>284, 285=>285, 286=>286, 287=>287, 288=>288, 289=>289, 290=>290, 291=>291, 292=>292, 293=>293, 294=>294, 295=>295, 296=>296, 297=>297, 298=>298, 299=>299, 300=>300, 301=>301, 302=>302, 303=>303, 304=>304, 305=>305, 306=>306, 307=>307, 308=>308, 309=>309, 310=>310, 311=>311, 312=>312, 313=>313, 314=>314, 315=>315, 316=>316, 317=>317, 318=>318, 319=>319, 320=>320, 321=>321, 322=>322, 323=>323, 324=>324, 325=>325, 326=>326, 327=>327, 328=>328, 329=>329, 330=>330, 331=>331, 332=>332, 333=>333, 334=>334, 335=>335, 336=>336, 337=>337, 338=>338, 339=>339, 340=>340, 341=>341, 342=>342, 343=>343, 344=>344, 345=>345, 346=>346, 347=>347, 348=>348, 349=>349, 350=>350, 351=>351, 352=>352, 353=>353, 354=>354, 355=>355, 356=>356, 357=>357, 358=>358, 359=>359, 360=>360, 361=>361, 362=>362, 363=>363, 364=>364, 365=>365, 366=>366, 367=>367, 368=>368, 369=>369, 370=>370, 371=>371, 372=>372, 373=>373, 374=>374, 375=>375, 376=>376, 377=>377, 378=>378, 379=>379, 380=>380, 381=>381, 382=>382, 383=>383, 384=>384, 385=>385, 386=>386, 387=>387, 388=>388, 389=>389, 390=>390, 391=>391, 392=>392, 393=>393, 394=>394, 395=>395, 396=>396, 397=>397, 398=>398, 399=>399, 400=>400, 401=>401, 402=>402, 403=>403, 404=>404, 405=>405, 406=>406, 407=>407, 408=>408, 409=>409, 410=>410, 411=>411, 412=>412, 413=>413, 414=>414, 415=>415, 416=>416, 417=>417, 418=>418, 419=>419, 420=>420, 421=>421, 422=>422, 423=>423, 424=>424, 425=>425, 426=>426, 427=>427, 428=>428, 429=>429, 430=>430, 431=>431, 432=>432, 433=>433, 434=>434, 435=>435, 436=>436, 437=>437, 438=>438, 439=>439, 440=>440, 441=>441, 442=>442, 443=>443, 444=>444, 445=>445, 446=>446, 447=>447, 448=>448, 449=>449, 450=>450, 451=>451, 452=>452, 453=>453, 454=>454, 455=>455, 456=>456, 457=>457, 458=>458, 459=>459, 460=>460, 461=>461, 462=>462, 463=>463, 464=>464, 465=>465, 466=>466, 467=>467, 468=>468, 469=>469, 470=>470, 471=>471, 472=>472, 473=>473, 474=>474, 475=>475, 476=>476, 477=>477, 478=>478, 479=>479, 480=>480, 481=>481, 482=>482, 483=>483, 484=>484, 485=>485, 486=>486, 487=>487, 488=>488, 489=>489, 490=>490, 491=>491, 492=>492, 493=>493, 494=>494, 495=>495, 496=>496, 497=>497, 498=>498, 499=>499, 500=>500,}
-end
diff --git a/benchmark/bm_vm2_case.rb b/benchmark/bm_vm2_case.rb
deleted file mode 100644
index adc6e4df0a..0000000000
--- a/benchmark/bm_vm2_case.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-i = 0
-while i<6_000_000 # while loop 2
- case :foo
- when :bar
- raise
- when :baz
- raise
- when :boo
- raise
- when :foo
- i += 1
- end
-end
-
diff --git a/benchmark/bm_vm2_case_lit.rb b/benchmark/bm_vm2_case_lit.rb
deleted file mode 100644
index c62b294e0e..0000000000
--- a/benchmark/bm_vm2_case_lit.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-i = 0
-@ret = [ "foo", true, false, :sym, 6, nil, 0.1, 0xffffffffffffffff ]
-def foo(i)
- @ret[i % @ret.size]
-end
-
-while i<6_000_000 # while loop 2
- case foo(i)
- when "foo" then :foo
- when true then true
- when false then false
- when :sym then :sym
- when 6 then :fix
- when nil then nil
- when 0.1 then :float
- when 0xffffffffffffffff then :big
- end
- i += 1
-end
diff --git a/benchmark/bm_vm2_defined_method.rb b/benchmark/bm_vm2_defined_method.rb
deleted file mode 100644
index 053ed6c912..0000000000
--- a/benchmark/bm_vm2_defined_method.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class Object
- define_method(:m){}
-end
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- m; m; m; m; m; m; m; m;
-end
diff --git a/benchmark/bm_vm2_dstr.rb b/benchmark/bm_vm2_dstr.rb
deleted file mode 100644
index 58c0f7bbc3..0000000000
--- a/benchmark/bm_vm2_dstr.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-i = 0
-x = y = 'z'
-while i<6_000_000 # benchmark loop 2
- i += 1
- str = "foo#{x}bar#{y}baz"
-end
diff --git a/benchmark/bm_vm2_eval.rb b/benchmark/bm_vm2_eval.rb
deleted file mode 100644
index 307cfc28ef..0000000000
--- a/benchmark/bm_vm2_eval.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- eval("1")
-end
-
diff --git a/benchmark/bm_vm2_fiber_switch.rb b/benchmark/bm_vm2_fiber_switch.rb
deleted file mode 100644
index c6f615d71d..0000000000
--- a/benchmark/bm_vm2_fiber_switch.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# based on benchmark for [ruby-core:65518] [Feature #10341] by Knut Franke
-fib = Fiber.new do
- loop { Fiber.yield }
-end
-i = 0
-while i< 6_000_000 # benchmark loop 2
- i += 1
- fib.resume
-end
diff --git a/benchmark/bm_vm2_method.rb b/benchmark/bm_vm2_method.rb
deleted file mode 100644
index a8ccff7138..0000000000
--- a/benchmark/bm_vm2_method.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-def m
- nil
-end
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- m; m; m; m; m; m; m; m;
-end
diff --git a/benchmark/bm_vm2_method_missing.rb b/benchmark/bm_vm2_method_missing.rb
deleted file mode 100644
index 2badc73101..0000000000
--- a/benchmark/bm_vm2_method_missing.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class C
- def method_missing mid
- end
-end
-
-obj = C.new
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m;
-end
diff --git a/benchmark/bm_vm2_method_with_block.rb b/benchmark/bm_vm2_method_with_block.rb
deleted file mode 100644
index b4efb4f520..0000000000
--- a/benchmark/bm_vm2_method_with_block.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-def m
- nil
-end
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- m{}; m{}; m{}; m{}; m{}; m{}; m{}; m{};
-end
diff --git a/benchmark/bm_vm2_module_ann_const_set.rb b/benchmark/bm_vm2_module_ann_const_set.rb
deleted file mode 100644
index 12ccfd2ff3..0000000000
--- a/benchmark/bm_vm2_module_ann_const_set.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- Module.new.const_set(:X, Module.new)
-end
diff --git a/benchmark/bm_vm2_module_const_set.rb b/benchmark/bm_vm2_module_const_set.rb
deleted file mode 100644
index f4d4c1b2e7..0000000000
--- a/benchmark/bm_vm2_module_const_set.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-i = 0
-module M
-end
-$VERBOSE = nil
-while i<6_000_000 # benchmark loop 2
- i += 1
- M.const_set(:X, Module.new)
-end
diff --git a/benchmark/bm_vm2_mutex.rb b/benchmark/bm_vm2_mutex.rb
deleted file mode 100644
index 5d16480c6b..0000000000
--- a/benchmark/bm_vm2_mutex.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'thread'
-
-m = Thread::Mutex.new
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- m.synchronize{}
-end
diff --git a/benchmark/bm_vm2_newlambda.rb b/benchmark/bm_vm2_newlambda.rb
deleted file mode 100644
index 6422c9b0d0..0000000000
--- a/benchmark/bm_vm2_newlambda.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- lambda {}
-end
diff --git a/benchmark/bm_vm2_poly_method.rb b/benchmark/bm_vm2_poly_method.rb
deleted file mode 100644
index c82c0e4bce..0000000000
--- a/benchmark/bm_vm2_poly_method.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class C1
- def m
- 1
- end
-end
-class C2
- def m
- 2
- end
-end
-
-o1 = C1.new
-o2 = C2.new
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- o = (i % 2 == 0) ? o1 : o2
- o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
- i += 1
-end
diff --git a/benchmark/bm_vm2_poly_method_ov.rb b/benchmark/bm_vm2_poly_method_ov.rb
deleted file mode 100644
index aa5fd1dd38..0000000000
--- a/benchmark/bm_vm2_poly_method_ov.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class C1
- def m
- 1
- end
-end
-class C2
- def m
- 2
- end
-end
-
-o1 = C1.new
-o2 = C2.new
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- o = (i % 2 == 0) ? o1 : o2
-# o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
- i += 1
-end
diff --git a/benchmark/bm_vm2_poly_singleton.rb b/benchmark/bm_vm2_poly_singleton.rb
deleted file mode 100644
index 0dba4320c4..0000000000
--- a/benchmark/bm_vm2_poly_singleton.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class C1
- def m; 1; end
-end
-
-o1 = C1.new
-o2 = C1.new
-o2.singleton_class
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- o = (i % 2 == 0) ? o1 : o2
- o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
- i += 1
-end
diff --git a/benchmark/bm_vm2_proc.rb b/benchmark/bm_vm2_proc.rb
deleted file mode 100644
index 65e5217371..0000000000
--- a/benchmark/bm_vm2_proc.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-def m &b
- b
-end
-
-pr = m{
- a = 1
-}
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- pr.call
-end
-
diff --git a/benchmark/bm_vm2_raise1.rb b/benchmark/bm_vm2_raise1.rb
deleted file mode 100644
index aa5387987f..0000000000
--- a/benchmark/bm_vm2_raise1.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-def rec n
- if n > 0
- rec n-1
- else
- raise
- end
-end
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
-
- begin
- rec 1
- rescue
- # ignore
- end
-end
diff --git a/benchmark/bm_vm2_raise2.rb b/benchmark/bm_vm2_raise2.rb
deleted file mode 100644
index 1f61c63157..0000000000
--- a/benchmark/bm_vm2_raise2.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-def rec n
- if n > 0
- rec n-1
- else
- raise
- end
-end
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
-
- begin
- rec 10
- rescue
- # ignore
- end
-end
diff --git a/benchmark/bm_vm2_regexp.rb b/benchmark/bm_vm2_regexp.rb
deleted file mode 100644
index 55f9e957a3..0000000000
--- a/benchmark/bm_vm2_regexp.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-i = 0
-str = 'xxxhogexxx'
-while i<6_000_000 # benchmark loop 2
- /hoge/ =~ str
- i += 1
-end
diff --git a/benchmark/bm_vm2_send.rb b/benchmark/bm_vm2_send.rb
deleted file mode 100644
index 6a3ab6fdab..0000000000
--- a/benchmark/bm_vm2_send.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class C
- def m
- end
-end
-
-o = C.new
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- o.__send__ :m
-end
diff --git a/benchmark/bm_vm2_string_literal.rb b/benchmark/bm_vm2_string_literal.rb
deleted file mode 100644
index 1d73036849..0000000000
--- a/benchmark/bm_vm2_string_literal.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-end
diff --git a/benchmark/bm_vm2_struct_big_aref_hi.rb b/benchmark/bm_vm2_struct_big_aref_hi.rb
deleted file mode 100644
index 22cb26b0a5..0000000000
--- a/benchmark/bm_vm2_struct_big_aref_hi.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(*('a'..'z').map { |x| x.to_sym })
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x.z # x[25]
-end
diff --git a/benchmark/bm_vm2_struct_big_aref_lo.rb b/benchmark/bm_vm2_struct_big_aref_lo.rb
deleted file mode 100644
index 5e61a7087e..0000000000
--- a/benchmark/bm_vm2_struct_big_aref_lo.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(*('a'..'z').map { |x| x.to_sym })
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x.k # x[10]
-end
diff --git a/benchmark/bm_vm2_struct_big_aset.rb b/benchmark/bm_vm2_struct_big_aset.rb
deleted file mode 100644
index 5a1c3d16f3..0000000000
--- a/benchmark/bm_vm2_struct_big_aset.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(*('a'..'z').map { |x| x.to_sym })
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x.k = i # x[10] = i
-end
diff --git a/benchmark/bm_vm2_struct_big_href_hi.rb b/benchmark/bm_vm2_struct_big_href_hi.rb
deleted file mode 100644
index fff940a80a..0000000000
--- a/benchmark/bm_vm2_struct_big_href_hi.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(*('a'..'z').map { |x| x.to_sym })
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x[:z]
-end
diff --git a/benchmark/bm_vm2_struct_big_href_lo.rb b/benchmark/bm_vm2_struct_big_href_lo.rb
deleted file mode 100644
index 5e4085d59d..0000000000
--- a/benchmark/bm_vm2_struct_big_href_lo.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(*('a'..'z').map { |x| x.to_sym })
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x[:k]
-end
diff --git a/benchmark/bm_vm2_struct_big_hset.rb b/benchmark/bm_vm2_struct_big_hset.rb
deleted file mode 100644
index 9c0cee4141..0000000000
--- a/benchmark/bm_vm2_struct_big_hset.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(*('a'..'z').map { |x| x.to_sym })
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x[:k] = i
-end
diff --git a/benchmark/bm_vm2_struct_small_aref.rb b/benchmark/bm_vm2_struct_small_aref.rb
deleted file mode 100644
index 8eaa555b41..0000000000
--- a/benchmark/bm_vm2_struct_small_aref.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(:a, :b, :c)
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x.a
-end
diff --git a/benchmark/bm_vm2_struct_small_aset.rb b/benchmark/bm_vm2_struct_small_aset.rb
deleted file mode 100644
index ecd0f95669..0000000000
--- a/benchmark/bm_vm2_struct_small_aset.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(:a, :b, :c)
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x.a = i
-end
diff --git a/benchmark/bm_vm2_struct_small_href.rb b/benchmark/bm_vm2_struct_small_href.rb
deleted file mode 100644
index 2c88fee6bf..0000000000
--- a/benchmark/bm_vm2_struct_small_href.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(:a, :b, :c)
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x[:a]
-end
diff --git a/benchmark/bm_vm2_struct_small_hset.rb b/benchmark/bm_vm2_struct_small_hset.rb
deleted file mode 100644
index 33c36d20f1..0000000000
--- a/benchmark/bm_vm2_struct_small_hset.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-s = Struct.new(:a, :b, :c)
-x = s.new
-i = 0
-while i<6_000_000 # benchmark loop 2
- i += 1
- x[:a] = 1
-end
diff --git a/benchmark/bm_vm2_super.rb b/benchmark/bm_vm2_super.rb
deleted file mode 100644
index afd8579e7b..0000000000
--- a/benchmark/bm_vm2_super.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-
-class C
- def m
- 1
- end
-end
-
-class CC < C
- def m
- super()
- end
-end
-
-obj = CC.new
-
-i = 0
-while i<6_000_000 # benchmark loop 2
- obj.m
- i += 1
-end
diff --git a/benchmark/bm_vm2_unif1.rb b/benchmark/bm_vm2_unif1.rb
deleted file mode 100644
index 1774625942..0000000000
--- a/benchmark/bm_vm2_unif1.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-i = 0
-def m a, b
-end
-
-while i<6_000_000 # benchmark loop 2
- i += 1
- m 100, 200
-end
diff --git a/benchmark/bm_vm2_zsuper.rb b/benchmark/bm_vm2_zsuper.rb
deleted file mode 100644
index 2a43e62217..0000000000
--- a/benchmark/bm_vm2_zsuper.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-i = 0
-
-class C
- def m a
- 1
- end
-end
-
-class CC < C
- def m a
- super
- end
-end
-
-obj = CC.new
-
-while i<6_000_000 # benchmark loop 2
- obj.m 10
- i += 1
-end
diff --git a/benchmark/bm_vm_thread_alive_check1.rb b/benchmark/bm_vm_thread_alive_check1.rb
deleted file mode 100644
index c993accdda..0000000000
--- a/benchmark/bm_vm_thread_alive_check1.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-5_000.times{
- t = Thread.new{}
- while t.alive?
- Thread.pass
- end
-}
diff --git a/benchmark/bm_vm_thread_pass.rb b/benchmark/bm_vm_thread_pass.rb
deleted file mode 100644
index b5b3c0bc85..0000000000
--- a/benchmark/bm_vm_thread_pass.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# Plenty Thtread.pass
-# A performance may depend on GVL implementation.
-
-tmax = (ARGV.shift || 2).to_i
-lmax = 200_000 / tmax
-
-(1..tmax).map{
- Thread.new{
- lmax.times{
- Thread.pass
- }
- }
-}.each{|t| t.join}
-
-
diff --git a/benchmark/bm_vm_thread_pass_flood.rb b/benchmark/bm_vm_thread_pass_flood.rb
deleted file mode 100644
index a660aafc18..0000000000
--- a/benchmark/bm_vm_thread_pass_flood.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# n.b. this is a good test for GVL when pinned to a single CPU
-
-1000.times{
- Thread.new{loop{Thread.pass}}
-}
-
-i = 0
-while i<10000
- i += 1
-end
diff --git a/benchmark/bm_vm_thread_queue.rb b/benchmark/bm_vm_thread_queue.rb
deleted file mode 100644
index 274ceda366..0000000000
--- a/benchmark/bm_vm_thread_queue.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'thread'
-
-n = 1_000_000
-q = Thread::Queue.new
-consumer = Thread.new{
- while q.pop
- # consuming
- end
-}
-
-producer = Thread.new{
- n.times{
- q.push true
- }
- q.push nil
-}
-
-consumer.join
diff --git a/benchmark/cgi_escape_html.yml b/benchmark/cgi_escape_html.yml
new file mode 100644
index 0000000000..af6abd08ac
--- /dev/null
+++ b/benchmark/cgi_escape_html.yml
@@ -0,0 +1,40 @@
+prelude: require 'cgi/escape'
+benchmark:
+ - name: escape_html_blank
+ prelude: str = ""
+ script: CGI.escapeHTML(str)
+ loop_count: 20000000
+ - name: escape_html_short_none
+ prelude: str = "abcde"
+ script: CGI.escapeHTML(str)
+ loop_count: 20000000
+ - name: escape_html_short_one
+ prelude: str = "abcd<"
+ script: CGI.escapeHTML(str)
+ loop_count: 20000000
+ - name: escape_html_short_all
+ prelude: str = "'&\"<>"
+ script: CGI.escapeHTML(str)
+ loop_count: 5000000
+ - name: escape_html_long_none
+ prelude: str = "abcde" * 300
+ script: CGI.escapeHTML(str)
+ loop_count: 1000000
+ - name: escape_html_long_all
+ prelude: str = "'&\"<>" * 10
+ script: CGI.escapeHTML(str)
+ loop_count: 1000000
+ - name: escape_html_real
+ prelude: | # http://example.com/
+ str = <<~HTML
+ <body>
+ <div>
+ <h1>Example Domain</h1>
+ <p>This domain is established to be used for illustrative examples in documents. You may use this
+ domain in examples without prior coordination or asking for permission.</p>
+ <p><a href="http://www.iana.org/domains/example">More information...</a></p>
+ </div>
+ </body>
+ HTML
+ script: CGI.escapeHTML(str)
+ loop_count: 1000000
diff --git a/benchmark/complex_float_add.yml b/benchmark/complex_float_add.yml
new file mode 100644
index 0000000000..d0150c5e5b
--- /dev/null
+++ b/benchmark/complex_float_add.yml
@@ -0,0 +1,7 @@
+prelude: |
+ max, min = 1000.0, -1000.0
+ a = Complex(rand(max)+min, rand(max)+min)
+ b = Complex(rand(max)+min, rand(max)+min)
+benchmark:
+ complex_float_add: c = a + b
+loop_count: 1000000
diff --git a/benchmark/complex_float_div.yml b/benchmark/complex_float_div.yml
new file mode 100644
index 0000000000..b9f5e1d51c
--- /dev/null
+++ b/benchmark/complex_float_div.yml
@@ -0,0 +1,7 @@
+prelude: |
+ max, min = 1000.0, -1000.0
+ a = Complex(rand(max)+min, rand(max)+min)
+ b = Complex(rand(max)+min, rand(max)+min)
+benchmark:
+ complex_float_div: c = a / b
+loop_count: 1000000
diff --git a/benchmark/complex_float_mul.yml b/benchmark/complex_float_mul.yml
new file mode 100644
index 0000000000..59b096a6dc
--- /dev/null
+++ b/benchmark/complex_float_mul.yml
@@ -0,0 +1,7 @@
+prelude: |
+ max, min = 1000.0, -1000.0
+ a = Complex(rand(max)+min, rand(max)+min)
+ b = Complex(rand(max)+min, rand(max)+min)
+benchmark:
+ complex_float_mul: c = a * b
+loop_count: 1000000
diff --git a/benchmark/complex_float_new.yml b/benchmark/complex_float_new.yml
new file mode 100644
index 0000000000..6fcde3125b
--- /dev/null
+++ b/benchmark/complex_float_new.yml
@@ -0,0 +1,7 @@
+prelude: |
+ max, min = 1000.0, -1000.0
+ a = Complex(rand(max)+min, rand(max)+min)
+ b = Complex(rand(max)+min, rand(max)+min)
+benchmark:
+ complex_float_new: c = Complex(a, b)
+loop_count: 1000000
diff --git a/benchmark/complex_float_power.yml b/benchmark/complex_float_power.yml
new file mode 100644
index 0000000000..c40a31ab55
--- /dev/null
+++ b/benchmark/complex_float_power.yml
@@ -0,0 +1,7 @@
+prelude: |
+ max, min = 1000.0, -1000.0
+ a = Complex(rand(max)+min, rand(max)+min)
+ b = Complex(rand(max)+min, rand(max)+min)
+benchmark:
+ complex_float_power: c = a ** b
+loop_count: 1000000
diff --git a/benchmark/complex_float_sub.yml b/benchmark/complex_float_sub.yml
new file mode 100644
index 0000000000..3fafe7cdbe
--- /dev/null
+++ b/benchmark/complex_float_sub.yml
@@ -0,0 +1,7 @@
+prelude: |
+ max, min = 1000.0, -1000.0
+ a = Complex(rand(max)+min, rand(max)+min)
+ b = Complex(rand(max)+min, rand(max)+min)
+benchmark:
+ complex_float_sub: c = a - b
+loop_count: 1000000
diff --git a/benchmark/bm_dir_empty_p.rb b/benchmark/dir_empty_p.rb
index 8329c757cf..8329c757cf 100644
--- a/benchmark/bm_dir_empty_p.rb
+++ b/benchmark/dir_empty_p.rb
diff --git a/benchmark/driver.rb b/benchmark/driver.rb
deleted file mode 100644
index 36365af209..0000000000
--- a/benchmark/driver.rb
+++ /dev/null
@@ -1,435 +0,0 @@
-#
-# Ruby Benchmark driver
-#
-
-first = true
-
-begin
- require 'optparse'
-rescue LoadError
- if first
- first = false
- $:.unshift File.join(File.dirname(__FILE__), '../lib')
- retry
- else
- raise
- end
-end
-
-require 'benchmark'
-require 'pp'
-require 'tempfile'
-
-class BenchmarkDriver
- def self.benchmark(opt)
- driver = self.new(opt[:execs], opt[:dir], opt)
- begin
- driver.run
- ensure
- driver.show_results
- end
- end
-
- def self.load(input, type, opt)
- case type
- when 'yaml'
- require 'yaml'
- h = YAML.load(input)
- when 'json'
- require 'json'
- h = JSON.load(input)
- else
- h = eval(input.read)
- end
- results = h[:results] || h["results"]
- obj = allocate
- obj.instance_variable_set("@execs", h[:executables] || h["executables"])
- obj.instance_variable_set("@results", results)
- obj.instance_variable_set("@opt", opt)
- [1, 2].each do |i|
- loop = results.assoc((n = "loop_whileloop#{i}").intern) || results.assoc(n)
- obj.instance_variable_set("@loop_wl#{i}", loop ? loop[1].map {|t,*|t} : nil)
- end
- obj.instance_variable_set("@measure_target", opt[:measure_target] || opt["measure_target"])
- obj
- end
-
- def output *args
- puts(*args)
- @output and @output.puts(*args)
- end
-
- def message *args
- output(*args) if @verbose
- end
-
- def message_print *args
- if @verbose
- print(*args)
- STDOUT.flush
- @output and @output.print(*args)
- end
- end
-
- def progress_message *args
- unless STDOUT.tty?
- STDERR.print(*args)
- STDERR.flush
- end
- end
-
- def initialize execs, dir, opt = {}
- @execs = execs.map{|e|
- e.strip!
- next if e.empty?
-
- if /(.+)::(.+)/ =~ e
- # ex) ruby-a::/path/to/ruby-a
- label = $1.strip
- path = $2
- version = `#{path} -v`.chomp
- else
- path = e
- version = label = `#{path} -v`.chomp
- end
- [path, label, version]
- }.compact
-
- @dir = dir
- @repeat = opt[:repeat] || 1
- @repeat = 1 if @repeat < 1
- @pattern = opt[:pattern] || nil
- @exclude = opt[:exclude] || nil
- @verbose = opt[:quiet] ? false : (opt[:verbose] || false)
- @output = opt[:output] ? open(opt[:output], 'w') : nil
- @loop_wl1 = @loop_wl2 = nil
- @ruby_arg = opt[:ruby_arg] || nil
- @measure_target = opt[:measure_target]
- @opt = opt
-
- # [[name, [[r-1-1, r-1-2, ...], [r-2-1, r-2-2, ...]]], ...]
- @results = []
-
- if @verbose
- @start_time = Time.now
- message @start_time
- @execs.each_with_index{|(path, label, version), i|
- message "target #{i}: " + (label == version ? "#{label}" : "#{label} (#{version})") + " at \"#{path}\""
- }
- message "measure target: #{@measure_target}"
- end
- end
-
- def adjusted_results name, results
- s = nil
- results.each_with_index{|e, i|
- r = e.min
- case name
- when /^vm1_/
- if @loop_wl1
- r -= @loop_wl1[i]
- r = 0 if r < 0
- s = '*'
- end
- when /^vm2_/
- if @loop_wl2
- r -= @loop_wl2[i]
- r = 0 if r < 0
- s = '*'
- end
- end
- yield r
- }
- s
- end
-
- def show_results
- case @opt[:format]
- when :tsv
- strformat = "\t%1$s"
- numformat = "\t%1$*2$.3f"
- minwidth = 0
- name_width = 0
- when :markdown
- markdown = true
- strformat = "|%1$-*2$s"
- numformat = "|%1$*2$.3f"
- when :plain
- strformat = " %1$-*2$s"
- numformat = " %1$*2$.3f"
- end
-
- name_width ||= @results.map {|v, result|
- v.size + (case v; when /^vm1_/; @loop_wl1; when /^vm2_/; @loop_wl2; end ? 1 : 0)
- }.max
- minwidth ||= 7
- width = @execs.map{|(_, v)| [v.size, minwidth].max}
-
- output
-
- if @verbose
- message '-----------------------------------------------------------'
- message 'raw data:'
- message
- message PP.pp(@results, "", 79)
- message
- message "Elapsed time: #{Time.now - @start_time} (sec)"
- end
-
- if rawdata_output = @opt[:rawdata_output]
- h = {}
- h[:cpuinfo] = File.read('/proc/cpuinfo') if File.exist?('/proc/cpuinfo')
- h[:executables] = @execs
- h[:results] = @results
- if (type = File.extname(rawdata_output)).empty?
- type = rawdata_output
- rawdata_output = @output.path.sub(/\.[^.\/]+\z/, '') << '.' << rawdata_output
- end
- case type
- when 'yaml'
- require 'yaml'
- h = YAML.dump(h)
- when 'json'
- require 'json'
- h = JSON.pretty_generate(h)
- else
- require 'pp'
- h = h.pretty_inspect
- end
- open(rawdata_output, 'w') {|f| f.puts h}
- end
-
- output '-----------------------------------------------------------'
- output 'benchmark results:'
-
- if @verbose and @repeat > 1
- output "minimum results in each #{@repeat} measurements."
- end
-
- output({
- real: "Execution time (sec)",
- peak: "Memory usage (peak) (B)",
- size: "Memory usage (last size) (B)",
- }[@measure_target])
- output if markdown
- output ["name".ljust(name_width), @execs.map.with_index{|(_, v), i| sprintf(strformat, v, width[i])}].join("").rstrip
- output ["-"*name_width, width.map{|n|":".rjust(n, "-")}].join("|") if markdown
- @results.each{|v, result|
- rets = []
- s = adjusted_results(v, result){|r|
- rets << sprintf(numformat, r, width[rets.size])
- }
- v += s if s
- output [v.ljust(name_width), rets].join("")
- }
-
- if @execs.size > 1
- output
- output({
- real: "Speedup ratio: compare with the result of `#{@execs[0][1]}' (greater is better)",
- peak: "Memory consuming ratio (peak) with the result of `#{@execs[0][1]}' (greater is better)",
- size: "Memory consuming ratio (size) with the result of `#{@execs[0][1]}' (greater is better)",
- }[@measure_target])
- output if markdown
- output ["name".ljust(name_width), @execs[1..-1].map.with_index{|(_, v), i| sprintf(strformat, v, width[i])}].join("").rstrip
- output ["-"*name_width, width[1..-1].map{|n|":".rjust(n, "-")}].join("|") if markdown
- @results.each{|v, result|
- rets = []
- first_value = nil
- s = adjusted_results(v, result){|r|
- if first_value
- if r == 0
- rets << "Error"
- else
- rets << sprintf(numformat, first_value/Float(r), width[rets.size+1])
- end
- else
- first_value = r
- end
- }
- v += s if s
- output [v.ljust(name_width), rets].join("")
- }
- end
-
- if @opt[:output]
- output
- output "Log file: #{@opt[:output]}"
- end
- end
-
- def files
- flag = {}
- @files = Dir.glob(File.join(@dir, 'bm*.rb')).map{|file|
- next if @pattern && /#{@pattern}/ !~ File.basename(file)
- next if @exclude && /#{@exclude}/ =~ File.basename(file)
- case file
- when /bm_(vm[12])_/, /bm_loop_(whileloop2?).rb/
- flag[$1] = true
- end
- file
- }.compact
-
- if flag['vm1'] && !flag['whileloop']
- @files << File.join(@dir, 'bm_loop_whileloop.rb')
- elsif flag['vm2'] && !flag['whileloop2']
- @files << File.join(@dir, 'bm_loop_whileloop2.rb')
- end
-
- @files.sort!
- progress_message "total: #{@files.size * @repeat} trial(s) (#{@repeat} trial(s) for #{@files.size} benchmark(s))\n"
- @files
- end
-
- def run
- files.each_with_index{|file, i|
- @i = i
- r = measure_file(file)
-
- if /bm_loop_whileloop.rb/ =~ file
- @loop_wl1 = r[1].map{|e| e.min}
- elsif /bm_loop_whileloop2.rb/ =~ file
- @loop_wl2 = r[1].map{|e| e.min}
- end
- }
- end
-
- def measure_file file
- name = File.basename(file, '.rb').sub(/^bm_/, '')
- prepare_file = File.join(File.dirname(file), "prepare_#{name}.rb")
- load prepare_file if FileTest.exist?(prepare_file)
-
- if @verbose
- output
- output '-----------------------------------------------------------'
- output name
- output
- output File.read(file)
- output
- end
-
- result = [name]
- result << @execs.map{|(e, v)|
- (0...@repeat).map{
- message_print "#{v}\t"
- progress_message '.'
-
- m = measure(e, file)
- message "#{m}"
- m
- }
- }
- @results << result
- result
- end
-
- unless defined?(File::NULL)
- if File.exist?('/dev/null')
- File::NULL = '/dev/null'
- end
- end
-
- def measure executable, file
- case @measure_target
- when :real
- cmd = "#{executable} #{@ruby_arg} #{file}"
- m = Benchmark.measure{
- system(cmd, out: File::NULL)
- }
- result = m.real
- when :peak, :size
- tmp = Tempfile.new("benchmark-memory-wrapper-data")
- wrapper = "#{File.join(__dir__, 'memory_wrapper.rb')} #{tmp.path} #{@measure_target}"
- cmd = "#{executable} #{@ruby_arg} #{wrapper} #{file}"
- system(cmd, out: File::NULL)
- result = tmp.read.to_i
- tmp.close
- else
- raise "unknown measure target"
- end
-
- if $? != 0
- raise $?.inspect if $? && $?.signaled?
- output "\`#{cmd}\' exited with abnormal status (#{$?})"
- 0
- else
- result
- end
- end
-end
-
-if __FILE__ == $0
- opt = {
- :execs => [],
- :dir => File.dirname(__FILE__),
- :repeat => 1,
- :measure_target => :real,
- :output => nil,
- :raw_output => nil,
- :format => :tsv,
- }
- formats = {
- :tsv => ".tsv",
- :markdown => ".md",
- :plain => ".txt",
- }
-
- parser = OptionParser.new{|o|
- o.on('-e', '--executables [EXECS]',
- "Specify benchmark one or more targets (e1::path1; e2::path2; e3::path3;...)"){|e|
- e.split(/;/).each{|path|
- opt[:execs] << path
- }
- }
- o.on('-d', '--directory [DIRECTORY]', "Benchmark suites directory"){|d|
- opt[:dir] = d
- }
- o.on('-p', '--pattern [PATTERN]', "Benchmark name pattern"){|p|
- opt[:pattern] = p
- }
- o.on('-x', '--exclude [PATTERN]', "Benchmark exclude pattern"){|e|
- opt[:exclude] = e
- }
- o.on('-r', '--repeat-count [NUM]', "Repeat count"){|n|
- opt[:repeat] = n.to_i
- }
- o.on('-o', '--output-file [FILE]', "Output file"){|f|
- opt[:output] = f
- }
- o.on('--ruby-arg [ARG]', "Optional argument for ruby"){|a|
- opt[:ruby_arg] = a
- }
- o.on('--measure-target [TARGET]', 'real (execution time), peak, size (memory)'){|mt|
- opt[:measure_target] = mt.to_sym
- }
- o.on('--rawdata-output [FILE]', 'output rawdata'){|r|
- opt[:rawdata_output] = r
- }
- o.on('--load-rawdata=FILE', 'input rawdata'){|r|
- opt[:rawdata_input] = r
- }
- o.on('-f', "--format=FORMAT", "output format (#{formats.keys.join(",")})", formats.keys){|r|
- opt[:format] = r
- }
- o.on('-v', '--verbose'){|v|
- opt[:verbose] = v
- }
- o.on('-q', '--quiet', "Run without notify information except result table."){|q|
- opt[:quiet] = q
- opt[:verbose] = false
- }
- }
-
- parser.parse!(ARGV)
-
- if input = opt[:rawdata_input]
- b = open(input) {|f|
- BenchmarkDriver.load(f, File.extname(input)[1..-1], opt)
- }
- b.show_results
- else
- opt[:output] ||= "bmlog-#{Time.now.strftime('%Y%m%d-%H%M%S')}.#{$$}#{formats[opt[:format]]}"
- BenchmarkDriver.benchmark(opt)
- end
-end
-
diff --git a/benchmark/enum_lazy_flat_map.yml b/benchmark/enum_lazy_flat_map.yml
new file mode 100644
index 0000000000..0ee390a441
--- /dev/null
+++ b/benchmark/enum_lazy_flat_map.yml
@@ -0,0 +1,16 @@
+prelude: |
+ num = (1..).lazy.take(100)
+ ary2 = [[1,2]].cycle.lazy.take(10)
+ ary10 = [[*1..10]].cycle.lazy.take(10)
+ ary20 = [[*1..20]].cycle.lazy.take(10)
+ ary50 = [[*1..50]].cycle.lazy.take(10)
+ ary100 = [[*1..100]].cycle.lazy.take(10)
+
+benchmark:
+ num3: num.flat_map {|x| x}.take(3).to_a
+ num10: num.flat_map {|x| x}.take(3).to_a
+ ary2: ary2.flat_map {|x| x}.take(3).to_a
+ ary10: ary10.flat_map {|x| x}.take(3).to_a
+ ary20: ary20.flat_map {|x| x}.take(3).to_a
+ ary50: ary50.flat_map {|x| x}.take(3).to_a
+ ary100: ary100.flat_map {|x| x}.take(3).to_a
diff --git a/benchmark/enum_lazy_grep_v_100.rb b/benchmark/enum_lazy_grep_v_100.rb
new file mode 100644
index 0000000000..8832392e65
--- /dev/null
+++ b/benchmark/enum_lazy_grep_v_100.rb
@@ -0,0 +1,4 @@
+grep_data = (1..10).to_a * 1000
+N = 100
+enum = grep_data.lazy.grep_v(->(i){i == 0}).grep_v(->(i){i == 0})
+N.times {enum.each {}}
diff --git a/benchmark/enum_lazy_grep_v_20.rb b/benchmark/enum_lazy_grep_v_20.rb
new file mode 100644
index 0000000000..329509fa8f
--- /dev/null
+++ b/benchmark/enum_lazy_grep_v_20.rb
@@ -0,0 +1,4 @@
+grep_data = (1..10).to_a * 1000
+N = 100
+enum = grep_data.lazy.grep_v(->(i){i > 2}).grep_v(->(i){i > 2})
+N.times {enum.each {}}
diff --git a/benchmark/enum_lazy_grep_v_50.rb b/benchmark/enum_lazy_grep_v_50.rb
new file mode 100644
index 0000000000..02ea4d4e71
--- /dev/null
+++ b/benchmark/enum_lazy_grep_v_50.rb
@@ -0,0 +1,4 @@
+grep_data = (1..10).to_a * 1000
+N = 100
+enum = grep_data.lazy.grep_v(->(i){i > 5}).grep_v(->(i){i > 5})
+N.times {enum.each {}}
diff --git a/benchmark/enum_lazy_uniq_100.rb b/benchmark/enum_lazy_uniq_100.rb
new file mode 100644
index 0000000000..2e6434d9c4
--- /dev/null
+++ b/benchmark/enum_lazy_uniq_100.rb
@@ -0,0 +1,4 @@
+uniq_data = (1..10_000).to_a
+N = 100
+enum = uniq_data.lazy.uniq {|i| i % 10000}.uniq {|i| i % 10000}
+N.times {enum.each {}}
diff --git a/benchmark/enum_lazy_uniq_20.rb b/benchmark/enum_lazy_uniq_20.rb
new file mode 100644
index 0000000000..75e6398fee
--- /dev/null
+++ b/benchmark/enum_lazy_uniq_20.rb
@@ -0,0 +1,4 @@
+uniq_data = (1..10_000).to_a
+N = 100
+enum = uniq_data.lazy.uniq {|i| i % 2000}.uniq {|i| i % 2000}
+N.times {enum.each {}}
diff --git a/benchmark/enum_lazy_uniq_50.rb b/benchmark/enum_lazy_uniq_50.rb
new file mode 100644
index 0000000000..59a39b78ff
--- /dev/null
+++ b/benchmark/enum_lazy_uniq_50.rb
@@ -0,0 +1,4 @@
+uniq_data = (1..10_000).to_a
+N = 100
+enum = uniq_data.lazy.uniq {|i| i % 5000}.uniq {|i| i % 5000}
+N.times {enum.each {}}
diff --git a/benchmark/enum_lazy_zip.yml b/benchmark/enum_lazy_zip.yml
new file mode 100644
index 0000000000..4566ff0261
--- /dev/null
+++ b/benchmark/enum_lazy_zip.yml
@@ -0,0 +1,22 @@
+prelude: |
+ a = (1..3).lazy
+ b = a.map {|x| x}
+
+benchmark:
+ first_ary: a.zip(["a", "b", "c"]).first
+ first_nonary: a.zip("a".."c").first
+ first_noarg: a.zip.first
+
+ take3_ary: a.zip(["a", "b", "c"]).take(3).force
+ take3_nonary: a.zip("a".."c").take(3).force
+ take3_noarg: a.zip.take(3).force
+
+ chain-first_ary: b.zip(["a", "b", "c"]).first
+ chain-first_nonary: b.zip("a".."c").first
+ chain-first_noarg: b.zip.first
+
+ chain-take3_ary: b.zip(["a", "b", "c"]).take(3).force
+ chain-take3_nonary: b.zip("a".."c").take(3).force
+ chain-take3_noarg: b.zip.take(3).force
+
+ block: a.zip("a".."c") {|x, y| [x, y]}
diff --git a/benchmark/erb_render.yml b/benchmark/erb_render.yml
new file mode 100644
index 0000000000..15f6c3880b
--- /dev/null
+++ b/benchmark/erb_render.yml
@@ -0,0 +1,24 @@
+prelude: |
+ require 'erb'
+
+ data = <<erb
+ <html>
+ <head> <%= title %> </head>
+ <body>
+ <h1> <%= title %> </h1>
+ <p>
+ <%= content %>
+ </p>
+ </body>
+ </html>
+ erb
+
+ title = "hello world!"
+ content = "hello world!\n" * 10
+
+ src = "def self.render(title, content); #{ERB.new(data).src}; end"
+ mod = Module.new
+ mod.instance_eval(src, "(ERB)")
+benchmark:
+ erb_render: mod.render(title, content)
+loop_count: 1500000
diff --git a/benchmark/fiber_chain.yml b/benchmark/fiber_chain.yml
new file mode 100644
index 0000000000..a36c759f8e
--- /dev/null
+++ b/benchmark/fiber_chain.yml
@@ -0,0 +1,36 @@
+prelude: |
+ def make_link(previous)
+ Fiber.new do
+ while message = previous.resume
+ Fiber.yield(message)
+ end
+ end
+ end
+
+ def make_chain(length = 1000, &block)
+ chain = Fiber.new(&block)
+
+ (length - 1).times do
+ chain = make_link(chain)
+ end
+
+ return chain
+ end
+
+ message = "Hello World!"
+
+ chain = make_chain do
+ while true
+ Fiber.yield(message)
+ end
+ end
+benchmark:
+ make_chain: |
+ make_chain(100) do
+ while true
+ Fiber.yield(message)
+ end
+ end
+ resume_chain: |
+ chain.resume
+loop_count: 5000
diff --git a/benchmark/fiber_locals.yml b/benchmark/fiber_locals.yml
new file mode 100644
index 0000000000..8588686477
--- /dev/null
+++ b/benchmark/fiber_locals.yml
@@ -0,0 +1,8 @@
+prelude: |
+ th = Thread.current
+ th[:key] = :val
+benchmark:
+ key?: th.key?(:key)
+ []: th[:key]
+ keys: th.keys
+loop_count: 1_000_000
diff --git a/benchmark/file_chmod.rb b/benchmark/file_chmod.rb
new file mode 100644
index 0000000000..1cd4760c9d
--- /dev/null
+++ b/benchmark/file_chmod.rb
@@ -0,0 +1,9 @@
+# chmod file
+require 'tempfile'
+max = 200_000
+tmp = Tempfile.new('chmod')
+path = tmp.path
+max.times do
+ File.chmod(0777, path)
+end
+tmp.close!
diff --git a/benchmark/file_rename.rb b/benchmark/file_rename.rb
new file mode 100644
index 0000000000..bbb44aebac
--- /dev/null
+++ b/benchmark/file_rename.rb
@@ -0,0 +1,11 @@
+# rename file
+require 'tempfile'
+
+max = 100_000
+tmp = [ Tempfile.new('rename-a'), Tempfile.new('rename-b') ]
+a, b = tmp.map { |x| x.path }
+tmp.each { |t| t.close } # Windows can't rename files without closing them
+max.times do
+ File.rename(a, b)
+ File.rename(b, a)
+end
diff --git a/benchmark/gc/aobench.rb b/benchmark/gc/aobench.rb
index 2eed7abc83..275f58b924 100644
--- a/benchmark/gc/aobench.rb
+++ b/benchmark/gc/aobench.rb
@@ -1 +1 @@
-require_relative '../bm_app_aobench.rb'
+require_relative '../app_aobench'
diff --git a/benchmark/gc/binary_trees.rb b/benchmark/gc/binary_trees.rb
index af8ea722aa..83347cdd20 100644
--- a/benchmark/gc/binary_trees.rb
+++ b/benchmark/gc/binary_trees.rb
@@ -1 +1 @@
-require_relative '../bm_so_binary_trees.rb'
+require_relative '../so_binary_trees'
diff --git a/benchmark/gc/gcbench.rb b/benchmark/gc/gcbench.rb
index 09a404466a..23d0b91c6c 100644
--- a/benchmark/gc/gcbench.rb
+++ b/benchmark/gc/gcbench.rb
@@ -3,11 +3,12 @@ require 'pp'
require 'optparse'
$list = true
-$gcprof = true
+$gcprof = false
opt = OptionParser.new
opt.on('-q'){$list = false}
opt.on('-d'){$gcprof = false}
+opt.on('-p'){$gcprof = true}
opt.parse!(ARGV)
script = File.join(File.dirname(__FILE__), ARGV.shift)
diff --git a/benchmark/gc/pentomino.rb b/benchmark/gc/pentomino.rb
index 94ba74be89..8ebdff7d1d 100644
--- a/benchmark/gc/pentomino.rb
+++ b/benchmark/gc/pentomino.rb
@@ -1 +1 @@
-require_relative '../bm_app_pentomino.rb'
+require_relative '../app_pentomino'
diff --git a/benchmark/bm_hash_aref_dsym.rb b/benchmark/hash_aref_dsym.rb
index af4f8c36d4..af4f8c36d4 100644
--- a/benchmark/bm_hash_aref_dsym.rb
+++ b/benchmark/hash_aref_dsym.rb
diff --git a/benchmark/bm_hash_aref_dsym_long.rb b/benchmark/hash_aref_dsym_long.rb
index 9d7759379e..9d7759379e 100644
--- a/benchmark/bm_hash_aref_dsym_long.rb
+++ b/benchmark/hash_aref_dsym_long.rb
diff --git a/benchmark/bm_hash_aref_fix.rb b/benchmark/hash_aref_fix.rb
index 1346890582..1346890582 100644
--- a/benchmark/bm_hash_aref_fix.rb
+++ b/benchmark/hash_aref_fix.rb
diff --git a/benchmark/bm_hash_aref_flo.rb b/benchmark/hash_aref_flo.rb
index 2217274c82..2217274c82 100644
--- a/benchmark/bm_hash_aref_flo.rb
+++ b/benchmark/hash_aref_flo.rb
diff --git a/benchmark/bm_hash_aref_miss.rb b/benchmark/hash_aref_miss.rb
index b0913dd4bb..b0913dd4bb 100644
--- a/benchmark/bm_hash_aref_miss.rb
+++ b/benchmark/hash_aref_miss.rb
diff --git a/benchmark/bm_hash_aref_str.rb b/benchmark/hash_aref_str.rb
index 19439b061b..19439b061b 100644
--- a/benchmark/bm_hash_aref_str.rb
+++ b/benchmark/hash_aref_str.rb
diff --git a/benchmark/bm_hash_aref_sym.rb b/benchmark/hash_aref_sym.rb
index f75d163fe6..f75d163fe6 100644
--- a/benchmark/bm_hash_aref_sym.rb
+++ b/benchmark/hash_aref_sym.rb
diff --git a/benchmark/bm_hash_aref_sym_long.rb b/benchmark/hash_aref_sym_long.rb
index 9dab8df7be..9dab8df7be 100644
--- a/benchmark/bm_hash_aref_sym_long.rb
+++ b/benchmark/hash_aref_sym_long.rb
diff --git a/benchmark/hash_defaults.yml b/benchmark/hash_defaults.yml
new file mode 100644
index 0000000000..833f10e1c7
--- /dev/null
+++ b/benchmark/hash_defaults.yml
@@ -0,0 +1,6 @@
+prelude: |
+ h = Hash.new { :foo }
+benchmark:
+ default_aref: h[1]
+ default_method: h.default(1)
+loop_count: 1000000
diff --git a/benchmark/hash_dup.yml b/benchmark/hash_dup.yml
new file mode 100644
index 0000000000..65f521ec94
--- /dev/null
+++ b/benchmark/hash_dup.yml
@@ -0,0 +1,8 @@
+prelude: |
+ small_hash = { a: 1 }
+ larger_hash = 20.times.map { |i| [('a'.ord + i).chr.to_sym, i] }.to_h
+
+benchmark:
+ dup_small: small_hash.dup
+ dup_larger: larger_hash.dup
+loop_count: 10000
diff --git a/benchmark/bm_hash_flatten.rb b/benchmark/hash_flatten.rb
index e944aae9f2..e944aae9f2 100644
--- a/benchmark/bm_hash_flatten.rb
+++ b/benchmark/hash_flatten.rb
diff --git a/benchmark/bm_hash_ident_flo.rb b/benchmark/hash_ident_flo.rb
index 0c7edfed3e..0c7edfed3e 100644
--- a/benchmark/bm_hash_ident_flo.rb
+++ b/benchmark/hash_ident_flo.rb
diff --git a/benchmark/bm_hash_ident_num.rb b/benchmark/hash_ident_num.rb
index b226736c6f..b226736c6f 100644
--- a/benchmark/bm_hash_ident_num.rb
+++ b/benchmark/hash_ident_num.rb
diff --git a/benchmark/bm_hash_ident_obj.rb b/benchmark/hash_ident_obj.rb
index 4b3b58edec..4b3b58edec 100644
--- a/benchmark/bm_hash_ident_obj.rb
+++ b/benchmark/hash_ident_obj.rb
diff --git a/benchmark/bm_hash_ident_str.rb b/benchmark/hash_ident_str.rb
index 8582b38e31..8582b38e31 100644
--- a/benchmark/bm_hash_ident_str.rb
+++ b/benchmark/hash_ident_str.rb
diff --git a/benchmark/bm_hash_ident_sym.rb b/benchmark/hash_ident_sym.rb
index 4c81e3d28e..4c81e3d28e 100644
--- a/benchmark/bm_hash_ident_sym.rb
+++ b/benchmark/hash_ident_sym.rb
diff --git a/benchmark/bm_hash_keys.rb b/benchmark/hash_keys.rb
index 6863cd01f9..6863cd01f9 100644
--- a/benchmark/bm_hash_keys.rb
+++ b/benchmark/hash_keys.rb
diff --git a/benchmark/hash_literal_small2.rb b/benchmark/hash_literal_small2.rb
new file mode 100644
index 0000000000..c188529260
--- /dev/null
+++ b/benchmark/hash_literal_small2.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+1_000_000.times.map { { "foo" => "bar", "bar" => "baz" } }
diff --git a/benchmark/hash_literal_small4.rb b/benchmark/hash_literal_small4.rb
new file mode 100644
index 0000000000..739f71b5b0
--- /dev/null
+++ b/benchmark/hash_literal_small4.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+1_000_000.times.map { { "foo" => "bar", "bar" => "baz", "baz" => "lol", "lol" => "lgtm" } }
diff --git a/benchmark/hash_literal_small8.rb b/benchmark/hash_literal_small8.rb
new file mode 100644
index 0000000000..53d80af535
--- /dev/null
+++ b/benchmark/hash_literal_small8.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+1_000_000.times.map { { "foo" => "bar", "bar" => "baz", "baz" => "lol", "lol" => "lgtm", "lgtm" => "nope", "nope" => "ok", "ok" => "again", "again" => "wait" } }
diff --git a/benchmark/bm_hash_long.rb b/benchmark/hash_long.rb
index 03d9109602..03d9109602 100644
--- a/benchmark/bm_hash_long.rb
+++ b/benchmark/hash_long.rb
diff --git a/benchmark/bm_hash_shift.rb b/benchmark/hash_shift.rb
index a645671a5b..a645671a5b 100644
--- a/benchmark/bm_hash_shift.rb
+++ b/benchmark/hash_shift.rb
diff --git a/benchmark/bm_hash_shift_u16.rb b/benchmark/hash_shift_u16.rb
index ec800d0342..ec800d0342 100644
--- a/benchmark/bm_hash_shift_u16.rb
+++ b/benchmark/hash_shift_u16.rb
diff --git a/benchmark/bm_hash_shift_u24.rb b/benchmark/hash_shift_u24.rb
index de4e0fa696..de4e0fa696 100644
--- a/benchmark/bm_hash_shift_u24.rb
+++ b/benchmark/hash_shift_u24.rb
diff --git a/benchmark/bm_hash_shift_u32.rb b/benchmark/hash_shift_u32.rb
index 656aa55583..656aa55583 100644
--- a/benchmark/bm_hash_shift_u32.rb
+++ b/benchmark/hash_shift_u32.rb
diff --git a/benchmark/bm_hash_small2.rb b/benchmark/hash_small2.rb
index 45485d9c71..45485d9c71 100644
--- a/benchmark/bm_hash_small2.rb
+++ b/benchmark/hash_small2.rb
diff --git a/benchmark/bm_hash_small4.rb b/benchmark/hash_small4.rb
index acd4084334..acd4084334 100644
--- a/benchmark/bm_hash_small4.rb
+++ b/benchmark/hash_small4.rb
diff --git a/benchmark/bm_hash_small8.rb b/benchmark/hash_small8.rb
index 9cffcc91b6..9cffcc91b6 100644
--- a/benchmark/bm_hash_small8.rb
+++ b/benchmark/hash_small8.rb
diff --git a/benchmark/bm_hash_to_proc.rb b/benchmark/hash_to_proc.rb
index 2b675bf509..2b675bf509 100644
--- a/benchmark/bm_hash_to_proc.rb
+++ b/benchmark/hash_to_proc.rb
diff --git a/benchmark/bm_hash_values.rb b/benchmark/hash_values.rb
index 069441302f..069441302f 100644
--- a/benchmark/bm_hash_values.rb
+++ b/benchmark/hash_values.rb
diff --git a/benchmark/bm_int_quo.rb b/benchmark/int_quo.rb
index e22a3f8c30..e22a3f8c30 100644
--- a/benchmark/bm_int_quo.rb
+++ b/benchmark/int_quo.rb
diff --git a/benchmark/bm_io_copy_stream_write.rb b/benchmark/io_copy_stream_write.rb
index 3fd87250a4..3fd87250a4 100644
--- a/benchmark/bm_io_copy_stream_write.rb
+++ b/benchmark/io_copy_stream_write.rb
diff --git a/benchmark/bm_io_copy_stream_write_socket.rb b/benchmark/io_copy_stream_write_socket.rb
index 11f369bd0d..11f369bd0d 100644
--- a/benchmark/bm_io_copy_stream_write_socket.rb
+++ b/benchmark/io_copy_stream_write_socket.rb
diff --git a/benchmark/bm_io_file_create.rb b/benchmark/io_file_create.rb
index 2f205c1333..2f205c1333 100644
--- a/benchmark/bm_io_file_create.rb
+++ b/benchmark/io_file_create.rb
diff --git a/benchmark/bm_io_file_read.rb b/benchmark/io_file_read.rb
index b9e796ed30..b9e796ed30 100644
--- a/benchmark/bm_io_file_read.rb
+++ b/benchmark/io_file_read.rb
diff --git a/benchmark/bm_io_file_write.rb b/benchmark/io_file_write.rb
index aa1be0e5fe..aa1be0e5fe 100644
--- a/benchmark/bm_io_file_write.rb
+++ b/benchmark/io_file_write.rb
diff --git a/benchmark/bm_io_nonblock_noex.rb b/benchmark/io_nonblock_noex.rb
index da9357fdc6..da9357fdc6 100644
--- a/benchmark/bm_io_nonblock_noex.rb
+++ b/benchmark/io_nonblock_noex.rb
diff --git a/benchmark/bm_io_nonblock_noex2.rb b/benchmark/io_nonblock_noex2.rb
index 56819d049b..56819d049b 100644
--- a/benchmark/bm_io_nonblock_noex2.rb
+++ b/benchmark/io_nonblock_noex2.rb
diff --git a/benchmark/bm_io_pipe_rw.rb b/benchmark/io_pipe_rw.rb
index 6862a8ae61..6862a8ae61 100644
--- a/benchmark/bm_io_pipe_rw.rb
+++ b/benchmark/io_pipe_rw.rb
diff --git a/benchmark/bm_io_select.rb b/benchmark/io_select.rb
index 19248daeb1..19248daeb1 100644
--- a/benchmark/bm_io_select.rb
+++ b/benchmark/io_select.rb
diff --git a/benchmark/bm_io_select2.rb b/benchmark/io_select2.rb
index 10e37d71b2..10e37d71b2 100644
--- a/benchmark/bm_io_select2.rb
+++ b/benchmark/io_select2.rb
diff --git a/benchmark/bm_io_select3.rb b/benchmark/io_select3.rb
index 7d0ba1f092..7d0ba1f092 100644
--- a/benchmark/bm_io_select3.rb
+++ b/benchmark/io_select3.rb
diff --git a/benchmark/irb_color.yml b/benchmark/irb_color.yml
new file mode 100644
index 0000000000..ebdc8d7e8b
--- /dev/null
+++ b/benchmark/irb_color.yml
@@ -0,0 +1,13 @@
+prelude: |
+ require 'irb/color'
+ code = <<~'CODE'
+ def self.foo # bar
+ :"erb #{ERB.new("<%= self %>", trim_mode: ?-).result}"
+ end
+ CODE
+benchmark:
+ irb_color_complete: |
+ IRB::Color.colorize_code(code, complete: true)
+ irb_color_incomplete: |
+ IRB::Color.colorize_code(code, complete: false)
+loop_count: 2000000
diff --git a/benchmark/irb_exec.yml b/benchmark/irb_exec.yml
new file mode 100644
index 0000000000..28933f8b38
--- /dev/null
+++ b/benchmark/irb_exec.yml
@@ -0,0 +1,10 @@
+prelude: |
+ # frozen_string_literal: true
+ require 'rbconfig'
+ irb_f = [File.join(File.dirname(RbConfig.ruby), 'irb'), '-f']
+benchmark:
+ irb_exec: |
+ IO.popen(irb_f, 'w') do |io|
+ io.write('exit')
+ end
+loop_count: 30
diff --git a/benchmark/kernel_clone.yml b/benchmark/kernel_clone.yml
new file mode 100644
index 0000000000..069b23abcd
--- /dev/null
+++ b/benchmark/kernel_clone.yml
@@ -0,0 +1,6 @@
+prelude: "object = Object.new"
+benchmark:
+ clone: "object.clone"
+ clone_true: "object.clone(freeze: true)"
+ clone_false: "object.clone(freeze: false)"
+loop_count: 10000
diff --git a/benchmark/kernel_float.yml b/benchmark/kernel_float.yml
new file mode 100644
index 0000000000..215f6750fc
--- /dev/null
+++ b/benchmark/kernel_float.yml
@@ -0,0 +1,5 @@
+benchmark:
+ float: "Float(42)"
+ float_true: "Float(42, exception: true)"
+ float_false: "Float(42, exception: false)"
+loop_count: 10000
diff --git a/benchmark/kernel_tap.yml b/benchmark/kernel_tap.yml
new file mode 100644
index 0000000000..4dcbb31b4d
--- /dev/null
+++ b/benchmark/kernel_tap.yml
@@ -0,0 +1,6 @@
+prelude: |
+ obj = Object.new
+ x = nil
+benchmark:
+ kernel_tap: obj.tap { |o| x = o }
+loop_count: 20000000
diff --git a/benchmark/kernel_then.yml b/benchmark/kernel_then.yml
new file mode 100644
index 0000000000..85f7341e33
--- /dev/null
+++ b/benchmark/kernel_then.yml
@@ -0,0 +1,6 @@
+benchmark:
+ kernel_then: 1.then { |i| i + 1 }
+ kernel_then_enum: 1.then
+ kernel_yield_self: 1.yield_self { |i| i + 1 }
+ kernel_yield_self_enum: 1.yield_self
+loop_count: 20000000
diff --git a/benchmark/keyword_arguments.yml b/benchmark/keyword_arguments.yml
new file mode 100644
index 0000000000..fce6bce0b8
--- /dev/null
+++ b/benchmark/keyword_arguments.yml
@@ -0,0 +1,13 @@
+prelude: |
+ h = {a: 1}
+ def kw(a: 1) a end
+ def kws(**kw) kw end
+benchmark:
+ kw_to_kw: "kw(a: 1)"
+ kw_splat_to_kw: "kw(**h)"
+ kw_to_kw_splat: "kws(a: 1)"
+ kw_splat_to_kw_splat: "kws(**h)"
+ kw_and_splat_to_kw: "kw(a: 1, **h)"
+ kw_splats_to_kw: "kw(**h, **h)"
+ kw_and_splat_to_kw_splat: "kws(a: 1, **h)"
+ kw_splats_to_kw_splat: "kws(**h, **h)"
diff --git a/benchmark/lib/benchmark_driver/output/driver.rb b/benchmark/lib/benchmark_driver/output/driver.rb
new file mode 100644
index 0000000000..d22236e9fb
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/output/driver.rb
@@ -0,0 +1,36 @@
+require 'benchmark_driver/output/simple'
+
+# This replicates the legacy benchmark/driver.rb behavior.
+class BenchmarkDriver::Output::Driver < BenchmarkDriver::Output::Simple
+ def initialize(*)
+ super
+ @stdout = $stdout
+ @strio = StringIO.new
+ $stdout = IOMultiplexer.new(@stdout, @strio)
+ end
+
+ def with_benchmark(*)
+ super
+ ensure
+ logfile = "bmlog-#{Time.now.strftime('%Y%m%d-%H%M%S')}.#{$$}.log"
+ puts "\nLog file: #{logfile}"
+
+ $stdout = @stdout
+ File.write(logfile, @strio.tap(&:rewind).read)
+ end
+
+ class IOMultiplexer
+ def initialize(io1, io2)
+ @io1 = io1
+ @io2 = io2
+ end
+
+ [:write, :sync, :sync=, :puts, :print, :flush].each do |method|
+ define_method(method) do |*args|
+ @io1.send(method, *args)
+ @io2.send(method, *args)
+ end
+ end
+ end
+ private_constant :IOMultiplexer
+end
diff --git a/benchmark/lib/benchmark_driver/runner/cstime.rb b/benchmark/lib/benchmark_driver/runner/cstime.rb
new file mode 100644
index 0000000000..3c3453e527
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/cstime.rb
@@ -0,0 +1,22 @@
+require 'benchmark_driver/runner/total'
+
+class BenchmarkDriver::Runner::Cstime < BenchmarkDriver::Runner::Total
+ METRIC = BenchmarkDriver::Metric.new(name: 'cstime', unit: 's', larger_better: false)
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC])
+
+ private
+
+ # Overriding BenchmarkDriver::Runner::Total#metric
+ def metric
+ METRIC
+ end
+
+ # Overriding BenchmarkDriver::Runner::Total#target
+ def target
+ :cstime
+ end
+end
diff --git a/benchmark/lib/benchmark_driver/runner/cutime.rb b/benchmark/lib/benchmark_driver/runner/cutime.rb
new file mode 100644
index 0000000000..e139962ef2
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/cutime.rb
@@ -0,0 +1,22 @@
+require 'benchmark_driver/runner/total'
+
+class BenchmarkDriver::Runner::Cutime < BenchmarkDriver::Runner::Total
+ METRIC = BenchmarkDriver::Metric.new(name: 'cutime', unit: 's', larger_better: false)
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC])
+
+ private
+
+ # Overriding BenchmarkDriver::Runner::Total#metric
+ def metric
+ METRIC
+ end
+
+ # Overriding BenchmarkDriver::Runner::Total#target
+ def target
+ :cutime
+ end
+end
diff --git a/benchmark/lib/benchmark_driver/runner/mjit.rb b/benchmark/lib/benchmark_driver/runner/mjit.rb
new file mode 100644
index 0000000000..1d4693e8be
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/mjit.rb
@@ -0,0 +1,34 @@
+require 'benchmark_driver/struct'
+require 'benchmark_driver/metric'
+require 'erb'
+
+# A runner to measure after-JIT performance easily
+class BenchmarkDriver::Runner::Mjit < BenchmarkDriver::Runner::Ips
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]).extend(Module.new{
+ def parse(**)
+ jobs = super
+ jobs.map do |job|
+ job = job.dup
+ job.prelude = "#{job.prelude}\n#{<<~EOS}"
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ __bmdv_ruby_i = 0
+ while __bmdv_ruby_i < 10000 # jit_min_calls
+ #{job.script}
+ __bmdv_ruby_i += 1
+ end
+ RubyVM::MJIT.pause # compile
+ #{job.script}
+ RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile
+ #{job.script}
+ RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile 2
+ end
+ EOS
+ job
+ end
+ end
+ })
+end
diff --git a/benchmark/lib/benchmark_driver/runner/mjit_exec.rb b/benchmark/lib/benchmark_driver/runner/mjit_exec.rb
new file mode 100644
index 0000000000..eac3dfba84
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/mjit_exec.rb
@@ -0,0 +1,237 @@
+require 'benchmark_driver/struct'
+require 'benchmark_driver/metric'
+require 'erb'
+
+# A special runner dedicated for measuring mjit_exec overhead.
+class BenchmarkDriver::Runner::MjitExec
+ METRIC = BenchmarkDriver::Metric.new(name: 'Iteration per second', unit: 'i/s')
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = ::BenchmarkDriver::Struct.new(
+ :name, # @param [String] name - This is mandatory for all runner
+ :metrics, # @param [Array<BenchmarkDriver::Metric>]
+ :num_methods, # @param [Integer] num_methods - The number of methods to be defined
+ :loop_count, # @param [Integer] loop_count
+ :from_jit, # @param [TrueClass,FalseClass] from_jit - Whether the mjit_exec() is from JIT or not
+ :to_jit, # @param [TrueClass,FalseClass] to_jit - Whether the mjit_exec() is to JIT or not
+ )
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ class << JobParser = Module.new
+ # @param [Array,String] num_methods
+ # @param [Integer] loop_count
+ # @param [TrueClass,FalseClass] from_jit
+ # @param [TrueClass,FalseClass] to_jit
+ def parse(num_methods:, loop_count:, from_jit:, to_jit:)
+ if num_methods.is_a?(String)
+ num_methods = eval(num_methods)
+ end
+
+ num_methods.map do |num|
+ if num_methods.size > 1
+ suffix = "[#{'%4d' % num}]"
+ else
+ suffix = "_#{num}"
+ end
+ Job.new(
+ name: "mjit_exec_#{from_jit ? 'JT' : 'VM'}2#{to_jit ? 'JT' : 'VM'}#{suffix}",
+ metrics: [METRIC],
+ num_methods: num,
+ loop_count: loop_count,
+ from_jit: from_jit,
+ to_jit: to_jit,
+ )
+ end
+ end
+ end
+
+ # @param [BenchmarkDriver::Config::RunnerConfig] config
+ # @param [BenchmarkDriver::Output] output
+ # @param [BenchmarkDriver::Context] contexts
+ def initialize(config:, output:, contexts:)
+ @config = config
+ @output = output
+ @contexts = contexts
+ end
+
+ # This method is dynamically called by `BenchmarkDriver::JobRunner.run`
+ # @param [Array<BenchmarkDriver::Runner::Peak::Job>] jobs
+ def run(jobs)
+ @output.with_benchmark do
+ jobs.each do |job|
+ @output.with_job(name: job.name) do
+ @contexts.each do |context|
+ result = BenchmarkDriver::Repeater.with_repeat(config: @config, larger_better: true, rest_on_average: :average) do
+ run_benchmark(job, context: context)
+ end
+ value, duration = result.value
+ @output.with_context(name: context.name, executable: context.executable, gems: context.gems, prelude: context.prelude) do
+ @output.report(values: { METRIC => value }, duration: duration, loop_count: job.loop_count)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ private
+
+ # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil
+ # @param [BenchmarkDriver::Context] context
+ # @return [BenchmarkDriver::Metrics]
+ def run_benchmark(job, context:)
+ if job.from_jit
+ if job.to_jit
+ benchmark = BenchmarkJT2JT.new(num_methods: job.num_methods, loop_count: job.loop_count)
+ else
+ raise NotImplementedError, "JT2VM is not implemented yet"
+ end
+ else
+ if job.to_jit
+ benchmark = BenchmarkVM2JT.new(num_methods: job.num_methods, loop_count: job.loop_count)
+ else
+ benchmark = BenchmarkVM2VM.new(num_methods: job.num_methods, loop_count: job.loop_count)
+ end
+ end
+
+ duration = Tempfile.open(['benchmark_driver-result', '.txt']) do |f|
+ with_script(benchmark.render(result: f.path)) do |path|
+ opt = []
+ if context.executable.command.any? { |c| c.start_with?('--jit') }
+ opt << '--jit-min-calls=2'
+ end
+ IO.popen([*context.executable.command, '--disable-gems', *opt, path], &:read)
+ if $?.success?
+ Float(f.read)
+ else
+ BenchmarkDriver::Result::ERROR
+ end
+ end
+ end
+
+ [job.loop_count.to_f / duration, duration]
+ end
+
+ def with_script(script)
+ if @config.verbose >= 2
+ sep = '-' * 30
+ $stdout.puts "\n\n#{sep}[Script begin]#{sep}\n#{script}#{sep}[Script end]#{sep}\n\n"
+ end
+
+ Tempfile.open(['benchmark_driver-', '.rb']) do |f|
+ f.puts script
+ f.close
+ return yield(f.path)
+ end
+ end
+
+ # @param [Integer] num_methods
+ # @param [Integer] loop_count
+ BenchmarkVM2VM = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do
+ # @param [String] result - A file to write result
+ def render(result:)
+ ERB.new(<<~EOS, trim_mode: '%').result(binding)
+ % num_methods.times do |i|
+ def a<%= i %>
+ nil
+ end
+ % end
+ RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+
+ def vm
+ t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ i = 0
+ while i < <%= loop_count / 1000 %>
+ % 1000.times do |i|
+ a<%= i % num_methods %>
+ % end
+ i += 1
+ end
+ % (loop_count % 1000).times do |i|
+ a<%= i % num_methods %>
+ % end
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
+ end
+
+ vm # warmup call cache
+ File.write(<%= result.dump %>, vm)
+ EOS
+ end
+ end
+ private_constant :BenchmarkVM2VM
+
+ # @param [Integer] num_methods
+ # @param [Integer] loop_count
+ BenchmarkVM2JT = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do
+ # @param [String] result - A file to write result
+ def render(result:)
+ ERB.new(<<~EOS, trim_mode: '%').result(binding)
+ % num_methods.times do |i|
+ def a<%= i %>
+ nil
+ end
+ a<%= i %>
+ a<%= i %> # --jit-min-calls=2
+ % end
+ RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+
+ def vm
+ t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ i = 0
+ while i < <%= loop_count / 1000 %>
+ % 1000.times do |i|
+ a<%= i % num_methods %>
+ % end
+ i += 1
+ end
+ % (loop_count % 1000).times do |i|
+ a<%= i % num_methods %>
+ % end
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
+ end
+
+ vm # warmup call cache
+ File.write(<%= result.dump %>, vm)
+ EOS
+ end
+ end
+ private_constant :BenchmarkVM2JT
+
+ # @param [Integer] num_methods
+ # @param [Integer] loop_count
+ BenchmarkJT2JT = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do
+ # @param [String] result - A file to write result
+ def render(result:)
+ ERB.new(<<~EOS, trim_mode: '%').result(binding)
+ % num_methods.times do |i|
+ def a<%= i %>
+ nil
+ end
+ % end
+
+ # You may need to:
+ # * Increase `JIT_ISEQ_SIZE_THRESHOLD` to 10000000 in mjit.h
+ # * Always return false in `inlinable_iseq_p()` of mjit_compile.c
+ def jit
+ t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ i = 0
+ while i < <%= loop_count / 1000 %>
+ % 1000.times do |i|
+ a<%= i % num_methods %>
+ % end
+ i += 1
+ end
+ % (loop_count % 1000).times do |i|
+ a<%= i % num_methods %>
+ % end
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
+ end
+
+ jit
+ jit
+ RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ File.write(<%= result.dump %>, jit)
+ EOS
+ end
+ end
+ private_constant :BenchmarkJT2JT
+end
diff --git a/benchmark/lib/benchmark_driver/runner/peak.rb b/benchmark/lib/benchmark_driver/runner/peak.rb
new file mode 100644
index 0000000000..d04f2e51ff
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/peak.rb
@@ -0,0 +1,151 @@
+require 'benchmark_driver/struct'
+require 'benchmark_driver/metric'
+require 'benchmark_driver/default_job'
+require 'benchmark_driver/default_job_parser'
+require 'tempfile'
+
+class BenchmarkDriver::Runner::Peak
+ METRIC = BenchmarkDriver::Metric.new(
+ name: 'Peak memory usage', unit: 'bytes', larger_better: false, worse_word: 'larger',
+ )
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC])
+
+ # @param [BenchmarkDriver::Config::RunnerConfig] config
+ # @param [BenchmarkDriver::Output] output
+ # @param [BenchmarkDriver::Context] contexts
+ def initialize(config:, output:, contexts:)
+ @config = config
+ @output = output
+ @contexts = contexts
+ end
+
+ # This method is dynamically called by `BenchmarkDriver::JobRunner.run`
+ # @param [Array<BenchmarkDriver::Runner::Peak::Job>] jobs
+ def run(jobs)
+ if jobs.any? { |job| job.loop_count.nil? }
+ jobs = jobs.map do |job|
+ job.loop_count ? job : Job.new(job.to_h.merge(loop_count: 1))
+ end
+ end
+
+ @output.with_benchmark do
+ jobs.each do |job|
+ @output.with_job(name: job.name) do
+ job.runnable_contexts(@contexts).each do |context|
+ value = BenchmarkDriver::Repeater.with_repeat(config: @config, larger_better: false) do
+ run_benchmark(job, context: context)
+ end
+ @output.with_context(name: context.name, executable: context.executable, gems: context.gems, prelude: context.prelude) do
+ @output.report(values: { metric => value }, loop_count: job.loop_count)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ private
+
+ # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil
+ # @param [BenchmarkDriver::Context] context
+ # @return [BenchmarkDriver::Metrics]
+ def run_benchmark(job, context:)
+ benchmark = BenchmarkScript.new(
+ preludes: [context.prelude, job.prelude],
+ script: job.script,
+ teardown: job.teardown,
+ loop_count: job.loop_count,
+ )
+
+ memory_status = File.expand_path('../../../../tool/lib/memory_status', __dir__)
+ Tempfile.open(['benchmark_driver-', '.rb']) do |f|
+ with_script(benchmark.render) do |path|
+ output = IO.popen([*context.executable.command, path, f.path, target, memory_status], &:read)
+ if $?.success?
+ Integer(f.read)
+ else
+ $stdout.print(output)
+ BenchmarkDriver::Result::ERROR
+ end
+ end
+ end
+ end
+
+ # Overridden by BenchmarkDriver::Runner::Size
+ def target
+ 'peak'
+ end
+
+ # Overridden by BenchmarkDriver::Runner::Size
+ def metric
+ METRIC
+ end
+
+ def with_script(script)
+ if @config.verbose >= 2
+ sep = '-' * 30
+ $stdout.puts "\n\n#{sep}[Script begin]#{sep}\n#{script}#{sep}[Script end]#{sep}\n\n"
+ end
+
+ Tempfile.open(['benchmark_driver-', '.rb']) do |f|
+ f.puts script
+ f.close
+ return yield(f.path)
+ end
+ end
+
+ # @param [String] prelude
+ # @param [String] script
+ # @param [String] teardown
+ # @param [Integer] loop_count
+ BenchmarkScript = ::BenchmarkDriver::Struct.new(:preludes, :script, :teardown, :loop_count) do
+ def render
+ prelude = preludes.reject(&:nil?).reject(&:empty?).join("\n")
+ <<-RUBY
+#{prelude}
+#{while_loop(script, loop_count)}
+#{teardown}
+
+result_file, target, memory_status = ARGV
+require_relative memory_status
+
+ms = Memory::Status.new
+case target.to_sym
+when :peak
+ key = ms.respond_to?(:hwm) ? :hwm : :peak
+when :size
+ key = ms.respond_to?(:rss) ? :rss : :size
+else
+ raise('unexpected target: ' + target)
+end
+
+File.write(result_file, ms[key])
+ RUBY
+ end
+
+ private
+
+ def while_loop(content, times)
+ if !times.is_a?(Integer) || times <= 0
+ raise ArgumentError.new("Unexpected times: #{times.inspect}")
+ end
+
+ if times > 1
+ <<-RUBY
+__bmdv_i = 0
+while __bmdv_i < #{times}
+ #{content}
+ __bmdv_i += 1
+end
+ RUBY
+ else
+ content
+ end
+ end
+ end
+ private_constant :BenchmarkScript
+end
diff --git a/benchmark/lib/benchmark_driver/runner/size.rb b/benchmark/lib/benchmark_driver/runner/size.rb
new file mode 100644
index 0000000000..1b31f901c7
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/size.rb
@@ -0,0 +1,25 @@
+require 'benchmark_driver/runner/peak'
+
+# Actually the same as BenchmarkDriver::Runner::Memory
+class BenchmarkDriver::Runner::Size < BenchmarkDriver::Runner::Peak
+ METRIC = BenchmarkDriver::Metric.new(
+ name: 'Max resident set size', unit: 'bytes', larger_better: false, worse_word: 'larger',
+ )
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC])
+
+ private
+
+ # Overriding BenchmarkDriver::Runner::Peak#metric
+ def metric
+ METRIC
+ end
+
+ # Overriding BenchmarkDriver::Runner::Peak#target
+ def target
+ 'size'
+ end
+end
diff --git a/benchmark/lib/benchmark_driver/runner/stime.rb b/benchmark/lib/benchmark_driver/runner/stime.rb
new file mode 100644
index 0000000000..4577fb0bf8
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/stime.rb
@@ -0,0 +1,22 @@
+require 'benchmark_driver/runner/total'
+
+class BenchmarkDriver::Runner::Stime < BenchmarkDriver::Runner::Total
+ METRIC = BenchmarkDriver::Metric.new(name: 'stime', unit: 's', larger_better: false)
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC])
+
+ private
+
+ # Overriding BenchmarkDriver::Runner::Total#metric
+ def metric
+ METRIC
+ end
+
+ # Overriding BenchmarkDriver::Runner::Total#target
+ def target
+ :stime
+ end
+end
diff --git a/benchmark/lib/benchmark_driver/runner/total.rb b/benchmark/lib/benchmark_driver/runner/total.rb
new file mode 100644
index 0000000000..64dc14f84e
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/total.rb
@@ -0,0 +1,137 @@
+require 'benchmark_driver/struct'
+require 'benchmark_driver/metric'
+require 'benchmark_driver/default_job'
+require 'benchmark_driver/default_job_parser'
+require 'tempfile'
+
+class BenchmarkDriver::Runner::Total
+ METRIC = BenchmarkDriver::Metric.new(name: 'Total time', unit: 's', larger_better: false)
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC])
+
+ # @param [BenchmarkDriver::Config::RunnerConfig] config
+ # @param [BenchmarkDriver::Output] output
+ # @param [BenchmarkDriver::Context] contexts
+ def initialize(config:, output:, contexts:)
+ @config = config
+ @output = output
+ @contexts = contexts
+ end
+
+ # This method is dynamically called by `BenchmarkDriver::JobRunner.run`
+ # @param [Array<BenchmarkDriver::Runner::Total::Job>] jobs
+ def run(jobs)
+ if jobs.any? { |job| job.loop_count.nil? }
+ raise 'missing loop_count is not supported in Ruby repository'
+ end
+
+ @output.with_benchmark do
+ jobs.each do |job|
+ @output.with_job(name: job.name) do
+ job.runnable_contexts(@contexts).each do |context|
+ duration = BenchmarkDriver::Repeater.with_repeat(config: @config, larger_better: false) do
+ run_benchmark(job, context: context)
+ end
+ @output.with_context(name: context.name, executable: context.executable, gems: context.gems, prelude: context.prelude) do
+ @output.report(values: { metric => duration }, duration: duration, loop_count: job.loop_count)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ private
+
+ # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil
+ # @param [BenchmarkDriver::Context] context
+ # @return [BenchmarkDriver::Metrics]
+ def run_benchmark(job, context:)
+ benchmark = BenchmarkScript.new(
+ preludes: [context.prelude, job.prelude],
+ script: job.script,
+ teardown: job.teardown,
+ loop_count: job.loop_count,
+ )
+
+ Tempfile.open(['benchmark_driver-', '.rb']) do |f|
+ with_script(benchmark.render(result: f.path, target: target)) do |path|
+ IO.popen([*context.executable.command, path], &:read) # TODO: print stdout if verbose=2
+ if $?.success?
+ Float(f.read)
+ else
+ BenchmarkDriver::Result::ERROR
+ end
+ end
+ end
+ end
+
+ # This method is overridden by some subclasses
+ def metric
+ METRIC
+ end
+
+ # This method is overridden by some subclasses
+ def target
+ :total
+ end
+
+ def with_script(script)
+ if @config.verbose >= 2
+ sep = '-' * 30
+ $stdout.puts "\n\n#{sep}[Script begin]#{sep}\n#{script}#{sep}[Script end]#{sep}\n\n"
+ end
+
+ Tempfile.open(['benchmark_driver-', '.rb']) do |f|
+ f.puts script
+ f.close
+ return yield(f.path)
+ end
+ end
+
+ # @param [String] prelude
+ # @param [String] script
+ # @param [String] teardown
+ # @param [Integer] loop_count
+ BenchmarkScript = ::BenchmarkDriver::Struct.new(:preludes, :script, :teardown, :loop_count) do
+ # @param [String] result - A file to write result
+ def render(result:, target:)
+ prelude = preludes.reject(&:nil?).reject(&:empty?).join("\n")
+ <<-RUBY
+#{prelude}
+
+require 'benchmark'
+__bmdv_result = Benchmark.measure {
+ #{while_loop(script, loop_count)}
+}
+
+#{teardown}
+
+File.write(#{result.dump}, __bmdv_result.#{target})
+ RUBY
+ end
+
+ private
+
+ def while_loop(content, times)
+ if !times.is_a?(Integer) || times <= 0
+ raise ArgumentError.new("Unexpected times: #{times.inspect}")
+ elsif times == 1
+ return content
+ end
+
+ # TODO: execute in batch
+ <<-RUBY
+__bmdv_i = 0
+while __bmdv_i < #{times}
+ #{content}
+ __bmdv_i += 1
+end
+ RUBY
+ end
+ end
+ private_constant :BenchmarkScript
+end
diff --git a/benchmark/lib/benchmark_driver/runner/utime.rb b/benchmark/lib/benchmark_driver/runner/utime.rb
new file mode 100644
index 0000000000..b61d83a188
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/utime.rb
@@ -0,0 +1,22 @@
+require 'benchmark_driver/runner/total'
+
+class BenchmarkDriver::Runner::Utime < BenchmarkDriver::Runner::Total
+ METRIC = BenchmarkDriver::Metric.new(name: 'utime', unit: 's', larger_better: false)
+
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC])
+
+ private
+
+ # Overriding BenchmarkDriver::Runner::Total#metric
+ def metric
+ METRIC
+ end
+
+ # Overriding BenchmarkDriver::Runner::Total#target
+ def target
+ :utime
+ end
+end
diff --git a/benchmark/lib/load.rb b/benchmark/lib/load.rb
new file mode 100644
index 0000000000..31b770c484
--- /dev/null
+++ b/benchmark/lib/load.rb
@@ -0,0 +1,18 @@
+# How to use this file:
+# 1. write a `$(srcdir)/test.rb` like:
+=begin
+require_relative 'benchmark/lib/load'
+
+Benchmark.driver(repeat_count: 5){|x|
+ x.executable name: 'clean-miniruby', command: %w'../clean-trunk/miniruby'
+ x.executable name: 'modif-miniruby', command: %w'./miniruby'
+
+ x.report %q{
+ h = {a: 1, b: 2, c: 3, d: 4}
+ }
+}
+=end
+#
+# 2. `make run`
+$:.unshift(File.join(__dir__, '../benchmark-driver/lib'))
+require 'benchmark_driver'
diff --git a/benchmark/bm_loop_for.rb b/benchmark/loop_for.rb
index 0fc4cc1511..0fc4cc1511 100644
--- a/benchmark/bm_loop_for.rb
+++ b/benchmark/loop_for.rb
diff --git a/benchmark/bm_loop_generator.rb b/benchmark/loop_generator.rb
index d3375c744c..d3375c744c 100644
--- a/benchmark/bm_loop_generator.rb
+++ b/benchmark/loop_generator.rb
diff --git a/benchmark/bm_loop_times.rb b/benchmark/loop_times.rb
index 521f72ad1a..521f72ad1a 100644
--- a/benchmark/bm_loop_times.rb
+++ b/benchmark/loop_times.rb
diff --git a/benchmark/bm_loop_whileloop.rb b/benchmark/loop_whileloop.rb
index 0072822c06..0072822c06 100644
--- a/benchmark/bm_loop_whileloop.rb
+++ b/benchmark/loop_whileloop.rb
diff --git a/benchmark/bm_loop_whileloop2.rb b/benchmark/loop_whileloop2.rb
index 47d02dffc4..47d02dffc4 100644
--- a/benchmark/bm_loop_whileloop2.rb
+++ b/benchmark/loop_whileloop2.rb
diff --git a/benchmark/make_fasta_output.rb b/benchmark/make_fasta_output.rb
deleted file mode 100644
index b6d787ae27..0000000000
--- a/benchmark/make_fasta_output.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# prepare 'fasta.output'
-
-def prepare_fasta_output n
- filebase = File.join(File.dirname($0), 'fasta.output')
- script = File.join(File.dirname($0), 'bm_so_fasta.rb')
- file = "#{filebase}.#{n}"
-
- unless FileTest.exist?(file)
- STDERR.puts "preparing #{file}"
-
- open(file, 'w'){|f|
- ARGV[0] = n
- $stdout = f
- load script
- $stdout = STDOUT
- }
- end
-end
-
diff --git a/benchmark/bm_marshal_dump_flo.rb b/benchmark/marshal_dump_flo.rb
index 9b8d0c6afb..9b8d0c6afb 100644
--- a/benchmark/bm_marshal_dump_flo.rb
+++ b/benchmark/marshal_dump_flo.rb
diff --git a/benchmark/bm_marshal_dump_load_geniv.rb b/benchmark/marshal_dump_load_geniv.rb
index 8252ad90fa..8252ad90fa 100644
--- a/benchmark/bm_marshal_dump_load_geniv.rb
+++ b/benchmark/marshal_dump_load_geniv.rb
diff --git a/benchmark/bm_marshal_dump_load_time.rb b/benchmark/marshal_dump_load_time.rb
index e29743b791..e29743b791 100644
--- a/benchmark/bm_marshal_dump_load_time.rb
+++ b/benchmark/marshal_dump_load_time.rb
diff --git a/benchmark/match_gt4.rb b/benchmark/match_gt4.rb
new file mode 100644
index 0000000000..ffda109912
--- /dev/null
+++ b/benchmark/match_gt4.rb
@@ -0,0 +1 @@
+1000000.times { /(.)(.)(\d+)(\d)/.match("THX1138.") }
diff --git a/benchmark/match_small.rb b/benchmark/match_small.rb
new file mode 100644
index 0000000000..3b743d484a
--- /dev/null
+++ b/benchmark/match_small.rb
@@ -0,0 +1 @@
+1000000.times { 'haystack'.match(/hay/) }
diff --git a/benchmark/memory_wrapper.rb b/benchmark/memory_wrapper.rb
deleted file mode 100644
index 3f4451a037..0000000000
--- a/benchmark/memory_wrapper.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-
-write_file, target, script_file = ARGV
-
-load(script_file)
-require_relative '../test/lib/memory_status'
-open(write_file, 'wb'){|f|
- ms = Memory::Status.new
- case target.to_sym
- when :peak
- key = ms.respond_to?(:hwm) ? :hwm : :peak
- when :size
- key = ms.respond_to?(:rss) ? :rss : :size
- end
-
- f.puts ms[key]
-}
diff --git a/benchmark/mjit_exec_jt2jt.yml b/benchmark/mjit_exec_jt2jt.yml
new file mode 100644
index 0000000000..6c303c7a44
--- /dev/null
+++ b/benchmark/mjit_exec_jt2jt.yml
@@ -0,0 +1,6 @@
+type: lib/benchmark_driver/runner/mjit_exec
+num_methods: [1]
+#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000]
+loop_count: 50000000
+from_jit: true
+to_jit: true
diff --git a/benchmark/mjit_exec_vm2jt.yml b/benchmark/mjit_exec_vm2jt.yml
new file mode 100644
index 0000000000..764883f070
--- /dev/null
+++ b/benchmark/mjit_exec_vm2jt.yml
@@ -0,0 +1,6 @@
+type: lib/benchmark_driver/runner/mjit_exec
+num_methods: [1]
+#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000]
+loop_count: 50000000
+from_jit: false
+to_jit: true
diff --git a/benchmark/mjit_exec_vm2vm.yml b/benchmark/mjit_exec_vm2vm.yml
new file mode 100644
index 0000000000..030aa76c1c
--- /dev/null
+++ b/benchmark/mjit_exec_vm2vm.yml
@@ -0,0 +1,6 @@
+type: lib/benchmark_driver/runner/mjit_exec
+num_methods: [1]
+#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000]
+loop_count: 50000000
+from_jit: false
+to_jit: false
diff --git a/benchmark/mjit_exivar.yml b/benchmark/mjit_exivar.yml
new file mode 100644
index 0000000000..2584fa6410
--- /dev/null
+++ b/benchmark/mjit_exivar.yml
@@ -0,0 +1,18 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ class Bench < Hash
+ def initialize
+ @exivar = nil
+ end
+
+ def exivar
+ @exivar
+ end
+ end
+
+ bench = Bench.new
+
+benchmark:
+ mjit_exivar: bench.exivar
+
+loop_count: 200000000
diff --git a/benchmark/mjit_integer.yml b/benchmark/mjit_integer.yml
new file mode 100644
index 0000000000..edc3556479
--- /dev/null
+++ b/benchmark/mjit_integer.yml
@@ -0,0 +1,30 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_abs(int) int.abs end
+ def mjit_bit_length(int) int.bit_length end
+ def mjit_comp(int) ~int end
+ def mjit_even?(int) int.even? end
+ def mjit_integer?(int) int.integer? end
+ def mjit_magnitude(int) int.magnitude end
+ def mjit_odd?(int) int.odd? end
+ def mjit_ord(int) int.ord end
+ def mjit_to_i(int) int.to_i end
+ def mjit_to_int(int) int.to_int end
+ def mjit_uminus(int) -int end
+ def mjit_zero?(int) int.zero? end
+
+benchmark:
+ - mjit_abs(-1)
+ - mjit_bit_length(100)
+ - mjit_comp(1)
+ - mjit_even?(2)
+ - mjit_integer?(0)
+ - mjit_magnitude(-1)
+ - mjit_odd?(1)
+ - mjit_ord(1)
+ - mjit_to_i(1)
+ - mjit_to_int(1)
+ - mjit_uminus(1)
+ - mjit_zero?(0)
+
+loop_count: 40000000
diff --git a/benchmark/mjit_kernel.yml b/benchmark/mjit_kernel.yml
new file mode 100644
index 0000000000..7720e65c2c
--- /dev/null
+++ b/benchmark/mjit_kernel.yml
@@ -0,0 +1,20 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_class(obj)
+ obj.class
+ end
+
+ def mjit_frozen?(obj)
+ obj.frozen?
+ end
+
+ str = ""
+ fstr = "".freeze
+
+benchmark:
+ - mjit_class(self)
+ - mjit_class(1)
+ - mjit_frozen?(str)
+ - mjit_frozen?(fstr)
+
+loop_count: 40000000
diff --git a/benchmark/mjit_leave.yml b/benchmark/mjit_leave.yml
new file mode 100644
index 0000000000..9ac68b164b
--- /dev/null
+++ b/benchmark/mjit_leave.yml
@@ -0,0 +1,8 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def leave
+ nil
+ end
+benchmark:
+ mjit_leave: leave
+loop_count: 200000000
diff --git a/benchmark/mjit_opt_cc_insns.yml b/benchmark/mjit_opt_cc_insns.yml
new file mode 100644
index 0000000000..fed6d34bd5
--- /dev/null
+++ b/benchmark/mjit_opt_cc_insns.yml
@@ -0,0 +1,27 @@
+# opt_* insns using vm_method_cfunc_is with send-compatible operands:
+# * opt_nil_p
+# * opt_not
+# * opt_eq
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_nil?(obj)
+ obj.nil?
+ end
+
+ def mjit_not(obj)
+ !obj
+ end
+
+ def mjit_eq(a, b)
+ a == b
+ end
+
+benchmark:
+ - script: mjit_nil?(1)
+ loop_count: 40000000
+ - script: mjit_not(1)
+ loop_count: 40000000
+ - script: mjit_eq(1, nil)
+ loop_count: 8000000
+ - script: mjit_eq(nil, 1)
+ loop_count: 8000000
diff --git a/benchmark/mjit_struct_aref.yml b/benchmark/mjit_struct_aref.yml
new file mode 100644
index 0000000000..bfba1323f2
--- /dev/null
+++ b/benchmark/mjit_struct_aref.yml
@@ -0,0 +1,10 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_struct_aref(struct)
+ struct.aa
+ end
+ struct = Struct.new(:a0, :a1, :a2, :a3, :a4, :a5, :a6, :a7, :a8, :a9, :aa).new
+
+benchmark: mjit_struct_aref(struct)
+
+loop_count: 40000000
diff --git a/benchmark/nil_p.yml b/benchmark/nil_p.yml
new file mode 100644
index 0000000000..79ba4f2177
--- /dev/null
+++ b/benchmark/nil_p.yml
@@ -0,0 +1,9 @@
+prelude: |
+ class Niller; def nil?; true; end; end
+ xnil, notnil = nil, Object.new
+ niller = Niller.new
+benchmark:
+ - xnil.nil?
+ - notnil.nil?
+ - niller.nil?
+loop_count: 10000000
diff --git a/benchmark/num_zero_p.yml b/benchmark/num_zero_p.yml
new file mode 100644
index 0000000000..2195963433
--- /dev/null
+++ b/benchmark/num_zero_p.yml
@@ -0,0 +1,8 @@
+benchmark:
+ - 0.zero?
+ - 1.zero?
+ - 0r.zero?
+ - 1r.zero?
+ - 0i.zero?
+ - 1i.zero?
+loop_count: 50000000
diff --git a/benchmark/object_allocate.yml b/benchmark/object_allocate.yml
new file mode 100644
index 0000000000..93ff463e41
--- /dev/null
+++ b/benchmark/object_allocate.yml
@@ -0,0 +1,21 @@
+prelude: |
+ class Eight
+ 8.times { include(Module.new) }
+ end
+ class ThirtyTwo
+ 32.times { include(Module.new) }
+ end
+ class SixtyFour
+ 64.times { include(Module.new) }
+ end
+ class OneTwentyEight
+ 128.times { include(Module.new) }
+ end
+ # Disable GC to see raw throughput:
+ GC.disable
+benchmark:
+ allocate_8_deep: Eight.new
+ allocate_32_deep: ThirtyTwo.new
+ allocate_64_deep: SixtyFour.new
+ allocate_128_deep: OneTwentyEight.new
+loop_count: 100000
diff --git a/benchmark/objspace_dump_all.yml b/benchmark/objspace_dump_all.yml
new file mode 100644
index 0000000000..ebab562d2e
--- /dev/null
+++ b/benchmark/objspace_dump_all.yml
@@ -0,0 +1,13 @@
+prelude: |
+ require 'objspace'
+ require 'tempfile'
+ $objs = 1_000.times.map { Object.new }
+ $strings = 1_000.times.map { |i| "string #{i}" }
+ $file = Tempfile.new('heap')
+ $dev_null = File.open(File::NULL, 'w+')
+
+benchmark:
+ dump_all_string: "ObjectSpace.dump_all(output: :string)"
+ dump_all_file: "ObjectSpace.dump_all(output: $file)"
+ dump_all_dev_null: "ObjectSpace.dump_all(output: $dev_null)"
+loop_count: 1
diff --git a/benchmark/other-lang/fact.py b/benchmark/other-lang/fact.py
index 01593965d9..1ce9f76275 100644
--- a/benchmark/other-lang/fact.py
+++ b/benchmark/other-lang/fact.py
@@ -3,7 +3,7 @@
def factL(n):
r = 1
- for x in range(2, n):
+ for x in range(2, n+1):
r *= x
return r
diff --git a/benchmark/pm_array.yml b/benchmark/pm_array.yml
new file mode 100644
index 0000000000..babb65a289
--- /dev/null
+++ b/benchmark/pm_array.yml
@@ -0,0 +1,19 @@
+prelude: |
+ def call(*val)
+ case val
+ in [String => body]
+ [200, {}, [body]]
+ in [Integer => status]
+ [status, {}, [""]]
+ in [Integer, String] => response
+ [response[0], {}, [response[1]]]
+ in [Integer, Hash, String] => response
+ [response[0], response[1], [response[2]]]
+ end
+ end
+
+benchmark:
+ first_match: call("ok")
+ second_match: call(401)
+ third_match: call(200, "ok")
+ fourth_match: call(201, {}, "created")
diff --git a/benchmark/prepare_require.rb b/benchmark/prepare_require.rb
deleted file mode 100644
index c4786f04ad..0000000000
--- a/benchmark/prepare_require.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require "fileutils"
-
-def prepare
- num_files = 10000
-
- basename = File.dirname($0)
- data_dir = File.join(basename, "bm_require.data")
-
- # skip if all of files exists
- if File.exist?(File.join(data_dir, "c#{num_files}.rb"))
- return
- end
-
- FileUtils.mkdir_p(data_dir)
-
- 1.upto(num_files) do |i|
- f = File.open("#{data_dir}/c#{i}.rb", "w")
- f.puts <<-END
- class C#{i}
- end
- END
- end
-end
-
-prepare
diff --git a/benchmark/prepare_require_thread.rb b/benchmark/prepare_require_thread.rb
deleted file mode 100644
index 339ecb8b39..0000000000
--- a/benchmark/prepare_require_thread.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-load File.join(File.dirname(__FILE__), "prepare_require.rb")
-
diff --git a/benchmark/prepare_so_count_words.rb b/benchmark/prepare_so_count_words.rb
deleted file mode 100644
index ee2138cdb2..0000000000
--- a/benchmark/prepare_so_count_words.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# prepare 'wc.input'
-
-def prepare_wc_input
- wcinput = File.join(File.dirname($0), 'wc.input')
- wcbase = File.join(File.dirname($0), 'wc.input.base')
- unless FileTest.exist?(wcinput)
- data = File.read(wcbase)
- 13.times{
- data << data
- }
- open(wcinput, 'w'){|f| f.write data}
- end
-end
-
-prepare_wc_input
diff --git a/benchmark/prepare_so_k_nucleotide.rb b/benchmark/prepare_so_k_nucleotide.rb
deleted file mode 100644
index d83aeb7a7e..0000000000
--- a/benchmark/prepare_so_k_nucleotide.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-require_relative 'make_fasta_output'
-prepare_fasta_output(100_000)
diff --git a/benchmark/prepare_so_reverse_complement.rb b/benchmark/prepare_so_reverse_complement.rb
deleted file mode 100644
index da3ec2df14..0000000000
--- a/benchmark/prepare_so_reverse_complement.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-require_relative 'make_fasta_output'
-prepare_fasta_output(2_500_000)
diff --git a/benchmark/range_last.yml b/benchmark/range_last.yml
new file mode 100644
index 0000000000..a6674f82ee
--- /dev/null
+++ b/benchmark/range_last.yml
@@ -0,0 +1,4 @@
+benchmark:
+ - (1..1_000_000).last(100)
+ - (1..1_000_000).last(1000)
+ - (1..1_000_000).last(10000)
diff --git a/benchmark/realpath.yml b/benchmark/realpath.yml
new file mode 100644
index 0000000000..90a029d5b9
--- /dev/null
+++ b/benchmark/realpath.yml
@@ -0,0 +1,30 @@
+prelude: |
+ f = File
+ pwd = Dir.pwd
+ Dir.mkdir('b') unless f.directory?('b')
+ f.write('b/a', '') unless f.file?('b/a')
+
+ relative = 'b/a'
+ absolute = File.join(pwd, relative)
+ dir = 'b'
+ file = 'a'
+
+ relative_dir = 'b/c'
+ absolute_dir = File.join(pwd, relative_dir)
+ file_dir = 'c'
+benchmark:
+ relative_nil: "f.realpath(relative, nil)"
+ absolute_nil: "f.realpath(absolute, nil)"
+ relative_relative: "f.realpath(file, dir)"
+ absolute_relative: "f.realpath(absolute, dir)"
+ relative_absolute: "f.realpath(relative, pwd)"
+ relative_nil_dir: "f.realdirpath(relative_dir, nil)"
+ absolute_nil_dir: "f.realdirpath(absolute_dir, nil)"
+ relative_relative_dir: "f.realdirpath(file_dir, dir)"
+ absolute_relative_dir: "f.realdirpath(absolute_dir, dir)"
+ relative_absolute_dir: "f.realdirpath(relative_dir, pwd)"
+ relative_nil_notexist: "f.realpath(relative_dir, nil) rescue nil"
+ absolute_nil_notexist: "f.realpath(absolute_dir, nil) rescue nil"
+ relative_relative_notexist: "f.realpath(file_dir, dir) rescue nil"
+ absolute_relative_notexist: "f.realpath(absolute_dir, dir) rescue nil"
+ relative_absolute_notexist: "f.realpath(relative_dir, pwd) rescue nil"
diff --git a/benchmark/report.rb b/benchmark/report.rb
deleted file mode 100644
index d2dc56b1e1..0000000000
--- a/benchmark/report.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-#
-# YARV benchmark driver
-#
-
-require 'yarvutil'
-require 'benchmark'
-require 'rbconfig'
-
-def exec_command type, file, w
- <<-EOP
- $DRIVER_PATH = '#{File.dirname($0)}'
- $LOAD_PATH.replace $LOAD_PATH | #{$LOAD_PATH.inspect}
- require 'benchmark'
- require 'yarvutil'
-# print '#{type}'
- begin
- puts Benchmark.measure{
- #{w}('#{file}')
- }.utime
- rescue Exception => exec_command_error_variable
- puts "\t" + exec_command_error_variable.message
- end
- EOP
-end
-
-def benchmark cmd
- rubybin = ENV['RUBY'] || RbConfig.ruby
-
- IO.popen(rubybin, 'r+'){|io|
- io.write cmd
- io.close_write
- return io.gets
- }
-end
-
-def ruby_exec file
- prog = exec_command 'ruby', file, 'load'
- benchmark prog
-end
-
-def yarv_exec file
- prog = exec_command 'yarv', file, 'YARVUtil.load_bm'
- benchmark prog
-end
-
-$wr = $wy = nil
-
-def measure bench
- file = File.dirname($0) + "/bm_#{bench}.rb"
- r = ruby_exec(file).to_f
- y = yarv_exec(file).to_f
- puts "#{bench}\t#{r}\t#{y}"
-end
-
-def measure2
- r = ruby_exec.to_f
- y = yarv_exec.to_f
- puts r/y
-end
-
-if $0 == __FILE__
- %w{
- whileloop
- whileloop2
- times
- const
- method
- poly_method
- block
- rescue
- rescue2
- }.each{|bench|
- measure bench
- }
-end
-
-
-
-
diff --git a/benchmark/require.yml b/benchmark/require.yml
new file mode 100644
index 0000000000..09f218cf08
--- /dev/null
+++ b/benchmark/require.yml
@@ -0,0 +1,32 @@
+prelude: |
+ require "fileutils"
+
+ def prepare
+ num_files = 10000
+
+ basename = File.dirname($0)
+ data_dir = File.join(basename, "bm_require.data")
+
+ # skip if all of files exists
+ if File.exist?(File.join(data_dir, "c#{num_files}.rb"))
+ return
+ end
+
+ FileUtils.mkdir_p(data_dir)
+
+ 1.upto(num_files) do |i|
+ File.write("#{data_dir}/c#{i}.rb", "class C#{i}\n""end\n")
+ end
+ end
+
+ prepare
+benchmark:
+ require: |
+ $:.push File.join(File.dirname(__FILE__), "bm_require.data")
+
+ 1.upto(10000) do |i|
+ require "c#{i}"
+ end
+
+ $:.pop
+loop_count: 1
diff --git a/benchmark/require_thread.yml b/benchmark/require_thread.yml
new file mode 100644
index 0000000000..0c63257106
--- /dev/null
+++ b/benchmark/require_thread.yml
@@ -0,0 +1,40 @@
+prelude: |
+ require "fileutils"
+
+ def prepare
+ num_files = 10000
+
+ basename = File.dirname($0)
+ data_dir = File.join(basename, "bm_require.data")
+
+ # skip if all of files exists
+ if File.exist?(File.join(data_dir, "c#{num_files}.rb"))
+ return
+ end
+
+ FileUtils.mkdir_p(data_dir)
+
+ 1.upto(num_files) do |i|
+ File.write("#{data_dir}/c#{i}.rb", "class C#{i}\n""end\n")
+ end
+ end
+
+ prepare
+benchmark:
+ require_thread: |
+ $:.push File.join(File.dirname(__FILE__), "bm_require.data")
+
+ i=0
+ t = Thread.new do
+ while true
+ i = i+1 # dummy loop
+ end
+ end
+
+ 1.upto(100) do |i|
+ require "c#{i}"
+ end
+
+ $:.pop
+ t.kill
+loop_count: 1
diff --git a/benchmark/run.rb b/benchmark/run.rb
deleted file mode 100644
index 0cd2363849..0000000000
--- a/benchmark/run.rb
+++ /dev/null
@@ -1,127 +0,0 @@
-#
-# Ruby benchmark driver
-#
-
-require 'benchmark'
-require 'rbconfig'
-
-$matzrubyonly = false
-$rubyonly = false
-
-$results = []
-
-# prepare 'wc.input'
-def prepare_wc_input
- wcinput = File.join(File.dirname($0), 'wc.input')
- wcbase = File.join(File.dirname($0), 'wc.input.base')
- unless FileTest.exist?(wcinput)
- data = File.read(wcbase)
- 13.times{
- data << data
- }
- open(wcinput, 'w'){|f| f.write data}
- end
-end
-
-prepare_wc_input
-
-def bm file
- prog = File.readlines(file).map{|e| e.rstrip}.join("\n")
- return if prog.empty?
-
- /[a-z]+_(.+)\.rb/ =~ file
- bm_name = $1
- puts '-----------------------------------------------------------' unless $rubyonly || $matzrubyonly
- puts "#{bm_name}: "
-
-
-puts <<EOS unless $matzrubyonly || $rubyonly
-#{prog}
---
-EOS
- begin
- result = [bm_name]
- result << matzruby_exec(file) unless $rubyonly
- result << ruby_exec(file) unless $matzrubyonly
- $results << result
-
- rescue Exception => e
- puts
- puts "** benchmark failure: #{e}"
- puts e.backtrace
- end
-end
-
-def benchmark file, bin
- m = Benchmark.measure{
- `#{bin} #{$opts} #{file}`
- }
- sec = '%.3f' % m.real
- puts " #{sec}"
- sec
-end
-
-def ruby_exec file
- print 'ruby'
- benchmark file, $ruby_program
-end
-
-def matzruby_exec file
- print 'matz'
- rubylib = ENV['RUBYLIB']
- ENV['RUBYLIB'] = ''
- r = benchmark file, $matzruby_program
- ENV['RUBYLIB'] = rubylib
- r
-end
-
-if $0 == __FILE__
- ARGV.each{|arg|
- case arg
- when /\A--ruby=(.+)/
- $ruby_program = $1
- when /\A--matzruby=(.+)/
- $matzruby_program = $1
- when /\A--opts=(.+)/
- $opts = $1
- when /\A(-r|--only-ruby)\z/
- $rubyonly = true
- when /\A(-m|--only-matzruby)\z/
- $matzrubyonly = true
- end
- }
- ARGV.delete_if{|arg|
- /\A-/ =~ arg
- }
-
- puts "MatzRuby:"
- system("#{$matzruby_program} -v")
- puts "Ruby:"
- system("#{$ruby_program} -v")
- puts
-
- if ARGV.empty?
- Dir.glob(File.dirname(__FILE__) + '/bm_*.rb').sort.each{|file|
- bm file
- }
- else
- ARGV.each{|file|
- Dir.glob(File.join(File.dirname(__FILE__), file + '*')){|ef|
- # file = "#{File.dirname(__FILE__)}/#{file}.rb"
- bm ef
- }
- }
- end
-
- puts
- puts "-- benchmark summary ---------------------------"
- $results.each{|res|
- print res.shift, "\t"
- (res||[]).each{|result|
- /([\d\.]+)/ =~ result
- print $1 + "\t" if $1
- }
- puts
- }
-end
-
diff --git a/benchmark/runc.rb b/benchmark/runc.rb
deleted file mode 100644
index 97c5cef045..0000000000
--- a/benchmark/runc.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-#
-#
-
-require 'benchmark'
-require 'rbconfig'
-
-$rubybin = ENV['RUBY'] || RbConfig.ruby
-
-def runfile file
- puts file
- file = File.join(File.dirname($0), 'contrib', file)
- Benchmark.bm{|x|
- x.report('ruby'){
- system("#{$rubybin} #{file}")
- }
- x.report('yarv'){
- system("#{$rubybin} -rite -I.. #{file}")
- }
- }
-end
-
-ARGV.each{|file|
- runfile file
-}
-
-
diff --git a/benchmark/bm_securerandom.rb b/benchmark/securerandom.rb
index a082ea6d5b..a082ea6d5b 100644
--- a/benchmark/bm_securerandom.rb
+++ b/benchmark/securerandom.rb
diff --git a/benchmark/so_ackermann.rb b/benchmark/so_ackermann.rb
new file mode 100644
index 0000000000..4effa1ecaf
--- /dev/null
+++ b/benchmark/so_ackermann.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/ruby
+# -*- Ruby -*-
+# $Id: ackermann-ruby.code,v 1.4 2004/11/13 07:40:41 bfulgham Exp $
+# http://www.bagley.org/~doug/shootout/
+
+def ack(m, n)
+ if m == 0 then
+ n + 1
+ elsif n == 0 then
+ ack(m - 1, 1)
+ else
+ ack(m - 1, ack(m, n - 1))
+ end
+end
+
+NUM = 9
+ack(3, NUM)
+
+
diff --git a/benchmark/so_array.rb b/benchmark/so_array.rb
new file mode 100644
index 0000000000..767e03db5f
--- /dev/null
+++ b/benchmark/so_array.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/ruby
+# -*- Ruby -*-
+# $Id: ary-ruby.code,v 1.4 2004/11/13 07:41:27 bfulgham Exp $
+# http://www.bagley.org/~doug/shootout/
+# with help from Paul Brannan and Mark Hubbart
+
+n = 9000 # Integer(ARGV.shift || 1)
+
+x = Array.new(n)
+y = Array.new(n, 0)
+
+n.times{|bi|
+ x[bi] = bi + 1
+}
+
+(0 .. 999).each do |e|
+ (n-1).step(0,-1) do |bi|
+ y[bi] += x.at(bi)
+ end
+end
+# puts "#{y.first} #{y.last}"
+
+
diff --git a/benchmark/bm_so_binary_trees.rb b/benchmark/so_binary_trees.rb
index b1693e4109..b1693e4109 100644
--- a/benchmark/bm_so_binary_trees.rb
+++ b/benchmark/so_binary_trees.rb
diff --git a/benchmark/so_concatenate.rb b/benchmark/so_concatenate.rb
new file mode 100644
index 0000000000..4468e20ac8
--- /dev/null
+++ b/benchmark/so_concatenate.rb
@@ -0,0 +1,18 @@
+#!/usr/bin/ruby
+# -*- Ruby -*-
+# $Id: strcat-ruby.code,v 1.4 2004/11/13 07:43:28 bfulgham Exp $
+# http://www.bagley.org/~doug/shootout/
+# based on code from Aristarkh A Zagorodnikov and Dat Nguyen
+
+STUFF = "hello\n"
+i = 0
+while i<10
+ i += 1
+ hello = ''
+ 4_000_000.times do |e|
+ hello << STUFF
+ end
+end
+# puts hello.length
+
+
diff --git a/benchmark/so_count_words.yml b/benchmark/so_count_words.yml
new file mode 100644
index 0000000000..99683505f9
--- /dev/null
+++ b/benchmark/so_count_words.yml
@@ -0,0 +1,65 @@
+prelude: |
+ #!/usr/bin/ruby
+
+ wc_input_base = <<EOS
+ Subject: Re: Who was Izchak Miller?
+ From: "Jane D. Anonymous" <nobody@yale.edu>
+ Date: 1996/04/28
+ Message-Id: <4lv7bc$oh@news.ycc.yale.edu>
+ References: <317C405E.5DFA@panix.com> <4lk6vl$gde@ns.oar.net>
+ To: 75176.2330@compuserve.com
+ Content-Type: text/plain; charset=us-ascii
+ Organization: Yale University
+ X-Url: news:4lk6vl$gde@ns.oar.net
+ Mime-Version: 1.0
+ Newsgroups: rec.games.roguelike.nethack
+ X-Mailer: Mozilla 1.1N (Macintosh; I; 68K)
+
+ Hello there, Izchak Miller was my father. When I was younger I spent
+ many a night, hunched over the keyboard with a cup of tea, playing
+ nethack with him and my brother. my dad was a philosopher with a strong
+ weakness for fantasy/sci fi. I remember when he started to get involved
+ with the Nethack team- my brother's Dungeons and Dragons monster book
+ found a regular place beside my dad's desk. it's nice to see him living
+ on in the game he loved so much :-).
+ Tamar Miller
+
+ The following is a really long word of 5000 characters:
+
+ wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
+ EOS
+
+ # prepare 'wc.input'
+
+ def prepare_wc_input(wcbase)
+ wcinput = File.join(File.dirname($0), 'wc.input')
+ unless FileTest.exist?(wcinput)
+ data = wcbase.dup
+ 13.times{
+ data << data
+ }
+ open(wcinput, 'w'){|f| f.write data}
+ end
+ end
+
+ prepare_wc_input(wc_input_base)
+
+benchmark:
+ so_count_words: |
+ # $Id: wc-ruby.code,v 1.4 2004/11/13 07:43:32 bfulgham Exp $
+ # http://www.bagley.org/~doug/shootout/
+ # with help from Paul Brannan
+ input = open(File.join(File.dirname($0), 'wc.input'), 'rb')
+
+ nl = nw = nc = 0
+ while true
+ tmp = input.read(4096) or break
+ data = tmp << (input.gets || "")
+ nc += data.length
+ nl += data.count("\n")
+ ((data.strip! || data).tr!("\n", " ") || data).squeeze!
+ nw += data.count(" ") + 1
+ end
+ # STDERR.puts "#{nl} #{nw} #{nc}"
+
+loop_count: 1
diff --git a/benchmark/so_exception.rb b/benchmark/so_exception.rb
new file mode 100644
index 0000000000..eb205b4df1
--- /dev/null
+++ b/benchmark/so_exception.rb
@@ -0,0 +1,61 @@
+#!/usr/bin/ruby
+# -*- Ruby -*-
+# $Id: except-ruby.code,v 1.4 2004/11/13 07:41:33 bfulgham Exp $
+# http://www.bagley.org/~doug/shootout/
+
+$HI = 0
+$LO = 0
+NUM = 250000 # Integer(ARGV[0] || 1)
+
+
+class Lo_Exception < Exception
+ def initialize(num)
+ @value = num
+ end
+end
+
+class Hi_Exception < Exception
+ def initialize(num)
+ @value = num
+ end
+end
+
+def some_function(num)
+ begin
+ hi_function(num)
+ rescue
+ print "We shouldn't get here, exception is: #{$!.type}\n"
+ end
+end
+
+def hi_function(num)
+ begin
+ lo_function(num)
+ rescue Hi_Exception
+ $HI = $HI + 1
+ end
+end
+
+def lo_function(num)
+ begin
+ blowup(num)
+ rescue Lo_Exception
+ $LO = $LO + 1
+ end
+end
+
+def blowup(num)
+ if num % 2 == 0
+ raise Lo_Exception.new(num)
+ else
+ raise Hi_Exception.new(num)
+ end
+end
+
+
+i = 1
+max = NUM+1
+while i < max
+ i += 1
+ some_function(i+1)
+end
diff --git a/benchmark/bm_so_fannkuch.rb b/benchmark/so_fannkuch.rb
index bac5ecd44c..bac5ecd44c 100644
--- a/benchmark/bm_so_fannkuch.rb
+++ b/benchmark/so_fannkuch.rb
diff --git a/benchmark/bm_so_fasta.rb b/benchmark/so_fasta.rb
index dcc6b39507..dcc6b39507 100644
--- a/benchmark/bm_so_fasta.rb
+++ b/benchmark/so_fasta.rb
diff --git a/benchmark/so_k_nucleotide.yml b/benchmark/so_k_nucleotide.yml
new file mode 100644
index 0000000000..d7df086c39
--- /dev/null
+++ b/benchmark/so_k_nucleotide.yml
@@ -0,0 +1,155 @@
+prelude: |
+ bm_so_fasta = <<'EOS'
+ # The Computer Language Shootout
+ # http://shootout.alioth.debian.org/
+ # Contributed by Sokolov Yura
+
+ $last = 42.0
+ def gen_random(max, im=139968, ia=3877, ic=29573)
+ (max * ($last = ($last * ia + ic) % im)) / im
+ end
+
+ alu =
+ "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"+
+ "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"+
+ "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"+
+ "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"+
+ "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"+
+ "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"+
+ "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"
+
+ iub = [
+ ["a", 0.27],
+ ["c", 0.12],
+ ["g", 0.12],
+ ["t", 0.27],
+
+ ["B", 0.02],
+ ["D", 0.02],
+ ["H", 0.02],
+ ["K", 0.02],
+ ["M", 0.02],
+ ["N", 0.02],
+ ["R", 0.02],
+ ["S", 0.02],
+ ["V", 0.02],
+ ["W", 0.02],
+ ["Y", 0.02],
+ ]
+ homosapiens = [
+ ["a", 0.3029549426680],
+ ["c", 0.1979883004921],
+ ["g", 0.1975473066391],
+ ["t", 0.3015094502008],
+ ]
+
+ def make_repeat_fasta(id, desc, src, n)
+ puts ">#{id} #{desc}"
+ v = nil
+ width = 60
+ l = src.length
+ s = src * ((n / l) + 1)
+ s.slice!(n, l)
+ puts(s.scan(/.{1,#{width}}/).join("\n"))
+ end
+
+ def make_random_fasta(id, desc, table, n)
+ puts ">#{id} #{desc}"
+ rand, v = nil,nil
+ width = 60
+ chunk = 1 * width
+ prob = 0.0
+ table.each{|v| v[1]= (prob += v[1])}
+ for i in 1..(n/width)
+ puts((1..width).collect{
+ rand = gen_random(1.0)
+ table.find{|v| v[1]>rand}[0]
+ }.join)
+ end
+ if n%width != 0
+ puts((1..(n%width)).collect{
+ rand = gen_random(1.0)
+ table.find{|v| v[1]>rand}[0]
+ }.join)
+ end
+ end
+
+
+ n = (ARGV[0] or 250_000).to_i
+
+ make_repeat_fasta('ONE', 'Homo sapiens alu', alu, n*2)
+ make_random_fasta('TWO', 'IUB ambiguity codes', iub, n*3)
+ make_random_fasta('THREE', 'Homo sapiens frequency', homosapiens, n*5)
+ EOS
+benchmark:
+ - name: so_k_nucleotide
+ prelude: |
+ script = File.join(File.dirname($0), 'bm_so_fasta.rb')
+ File.write(script, bm_so_fasta)
+
+ def prepare_fasta_output n
+ filebase = File.join(File.dirname($0), 'fasta.output')
+ script = File.join(File.dirname($0), 'bm_so_fasta.rb')
+ file = "#{filebase}.#{n}"
+
+ unless FileTest.exist?(file)
+ STDERR.puts "preparing #{file}"
+
+ open(file, 'w'){|f|
+ ARGV[0] = n
+ $stdout = f
+ load script
+ $stdout = STDOUT
+ }
+ end
+ end
+ prepare_fasta_output(100_000)
+ script: |
+ # The Computer Language Shootout
+ # http://shootout.alioth.debian.org
+ #
+ # contributed by jose fco. gonzalez
+ # modified by Sokolov Yura
+
+ seq = String.new
+
+ def frecuency( seq,length )
+ n, table = seq.length - length + 1, Hash.new(0)
+ f, i = nil, nil
+ (0 ... length).each do |f|
+ (f ... n).step(length) do |i|
+ table[seq[i,length]] += 1
+ end
+ end
+ [n,table]
+
+ end
+
+ def sort_by_freq( seq,length )
+ n,table = frecuency( seq,length )
+ a, b, v = nil, nil, nil
+ table.sort{|a,b| b[1] <=> a[1]}.each do |v|
+ puts "%s %.3f" % [v[0].upcase,((v[1]*100).to_f/n)]
+ end
+ puts
+ end
+
+ def find_seq( seq,s )
+ n,table = frecuency( seq,s.length )
+ puts "#{table[s].to_s}\t#{s.upcase}"
+ end
+
+ input = open(File.join(File.dirname($0), 'fasta.output.100000'), 'rb')
+
+ line = input.gets while line !~ /^>THREE/
+ line = input.gets
+
+ while (line !~ /^>/) & line do
+ seq << line.chomp
+ line = input.gets
+ end
+
+ [1,2].each {|i| sort_by_freq( seq,i ) }
+
+ %w(ggt ggta ggtatt ggtattttaatt ggtattttaatttatagt).each{|s| find_seq( seq,s) }
+ loop_count: 1
diff --git a/benchmark/bm_so_lists.rb b/benchmark/so_lists.rb
index e8f4a2a5f7..e8f4a2a5f7 100644
--- a/benchmark/bm_so_lists.rb
+++ b/benchmark/so_lists.rb
diff --git a/benchmark/bm_so_mandelbrot.rb b/benchmark/so_mandelbrot.rb
index 76331c64b8..76331c64b8 100644
--- a/benchmark/bm_so_mandelbrot.rb
+++ b/benchmark/so_mandelbrot.rb
diff --git a/benchmark/so_matrix.rb b/benchmark/so_matrix.rb
new file mode 100644
index 0000000000..2d1e72bda9
--- /dev/null
+++ b/benchmark/so_matrix.rb
@@ -0,0 +1,48 @@
+#!/usr/bin/ruby
+# -*- Ruby -*-
+# $Id: matrix-ruby.code,v 1.4 2004/11/13 07:42:14 bfulgham Exp $
+# http://www.bagley.org/~doug/shootout/
+
+n = 60 #Integer(ARGV.shift || 1)
+
+size = 40
+
+def mkmatrix(rows, cols)
+ count = 1
+ mx = Array.new(rows)
+ (0 .. (rows - 1)).each do |bi|
+ row = Array.new(cols, 0)
+ (0 .. (cols - 1)).each do |j|
+ row[j] = count
+ count += 1
+ end
+ mx[bi] = row
+ end
+ mx
+end
+
+def mmult(rows, cols, m1, m2)
+ m3 = Array.new(rows)
+ (0 .. (rows - 1)).each do |bi|
+ row = Array.new(cols, 0)
+ (0 .. (cols - 1)).each do |j|
+ val = 0
+ (0 .. (cols - 1)).each do |k|
+ val += m1.at(bi).at(k) * m2.at(k).at(j)
+ end
+ row[j] = val
+ end
+ m3[bi] = row
+ end
+ m3
+end
+
+m1 = mkmatrix(size, size)
+m2 = mkmatrix(size, size)
+mm = Array.new
+n.times do
+ mm = mmult(size, size, m1, m2)
+end
+# puts "#{mm[0][0]} #{mm[2][3]} #{mm[3][2]} #{mm[4][4]}"
+
+
diff --git a/benchmark/bm_so_meteor_contest.rb b/benchmark/so_meteor_contest.rb
index 8c136baa6c..8c136baa6c 100755..100644
--- a/benchmark/bm_so_meteor_contest.rb
+++ b/benchmark/so_meteor_contest.rb
diff --git a/benchmark/bm_so_nbody.rb b/benchmark/so_nbody.rb
index d6c5bb9e61..d6c5bb9e61 100644
--- a/benchmark/bm_so_nbody.rb
+++ b/benchmark/so_nbody.rb
diff --git a/benchmark/so_nested_loop.rb b/benchmark/so_nested_loop.rb
new file mode 100644
index 0000000000..766fcf7b84
--- /dev/null
+++ b/benchmark/so_nested_loop.rb
@@ -0,0 +1,24 @@
+#!/usr/bin/ruby
+# -*- Ruby -*-
+# $Id: nestedloop-ruby.code,v 1.4 2004/11/13 07:42:22 bfulgham Exp $
+# http://www.bagley.org/~doug/shootout/
+# from Avi Bryant
+
+n = 16 # Integer(ARGV.shift || 1)
+x = 0
+n.times do
+ n.times do
+ n.times do
+ n.times do
+ n.times do
+ n.times do
+ x += 1
+ end
+ end
+ end
+ end
+ end
+end
+# puts x
+
+
diff --git a/benchmark/bm_so_nsieve.rb b/benchmark/so_nsieve.rb
index a65cc78233..a65cc78233 100644
--- a/benchmark/bm_so_nsieve.rb
+++ b/benchmark/so_nsieve.rb
diff --git a/benchmark/bm_so_nsieve_bits.rb b/benchmark/so_nsieve_bits.rb
index 6f958ee44e..6f958ee44e 100644
--- a/benchmark/bm_so_nsieve_bits.rb
+++ b/benchmark/so_nsieve_bits.rb
diff --git a/benchmark/so_object.rb b/benchmark/so_object.rb
new file mode 100644
index 0000000000..131f44624c
--- /dev/null
+++ b/benchmark/so_object.rb
@@ -0,0 +1,56 @@
+#!/usr/bin/ruby
+# -*- Ruby -*-
+# $Id: objinst-ruby.code,v 1.4 2004/11/13 07:42:25 bfulgham Exp $
+# http://www.bagley.org/~doug/shootout/
+# with help from Aristarkh Zagorodnikov
+
+class Toggle
+ def initialize(start_state)
+ @bool = start_state
+ end
+
+ def value
+ @bool
+ end
+
+ def activate
+ @bool = !@bool
+ self
+ end
+end
+
+class NthToggle < Toggle
+ def initialize(start_state, max_counter)
+ super start_state
+ @count_max = max_counter
+ @counter = 0
+ end
+
+ def activate
+ @counter += 1
+ if @counter >= @count_max
+ @bool = !@bool
+ @counter = 0
+ end
+ self
+ end
+end
+
+n = 1500000 # (ARGV.shift || 1).to_i
+
+toggle = Toggle.new 1
+5.times do
+ toggle.activate.value ? 'true' : 'false'
+end
+n.times do
+ toggle = Toggle.new 1
+end
+
+ntoggle = NthToggle.new 1, 3
+8.times do
+ ntoggle.activate.value ? 'true' : 'false'
+end
+n.times do
+ ntoggle = NthToggle.new 1, 3
+end
+
diff --git a/benchmark/bm_so_partial_sums.rb b/benchmark/so_partial_sums.rb
index 630b45cb8d..630b45cb8d 100644
--- a/benchmark/bm_so_partial_sums.rb
+++ b/benchmark/so_partial_sums.rb
diff --git a/benchmark/bm_so_pidigits.rb b/benchmark/so_pidigits.rb
index 9a537b2d1c..9a537b2d1c 100644
--- a/benchmark/bm_so_pidigits.rb
+++ b/benchmark/so_pidigits.rb
diff --git a/benchmark/bm_so_random.rb b/benchmark/so_random.rb
index a66b9e8e63..a66b9e8e63 100644
--- a/benchmark/bm_so_random.rb
+++ b/benchmark/so_random.rb
diff --git a/benchmark/so_reverse_complement.yml b/benchmark/so_reverse_complement.yml
new file mode 100644
index 0000000000..de05eedfc4
--- /dev/null
+++ b/benchmark/so_reverse_complement.yml
@@ -0,0 +1,137 @@
+prelude: |
+ bm_so_fasta = <<'EOS'
+ # The Computer Language Shootout
+ # http://shootout.alioth.debian.org/
+ # Contributed by Sokolov Yura
+
+ $last = 42.0
+ def gen_random(max, im=139968, ia=3877, ic=29573)
+ (max * ($last = ($last * ia + ic) % im)) / im
+ end
+
+ alu =
+ "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"+
+ "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"+
+ "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"+
+ "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"+
+ "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"+
+ "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"+
+ "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"
+
+ iub = [
+ ["a", 0.27],
+ ["c", 0.12],
+ ["g", 0.12],
+ ["t", 0.27],
+
+ ["B", 0.02],
+ ["D", 0.02],
+ ["H", 0.02],
+ ["K", 0.02],
+ ["M", 0.02],
+ ["N", 0.02],
+ ["R", 0.02],
+ ["S", 0.02],
+ ["V", 0.02],
+ ["W", 0.02],
+ ["Y", 0.02],
+ ]
+ homosapiens = [
+ ["a", 0.3029549426680],
+ ["c", 0.1979883004921],
+ ["g", 0.1975473066391],
+ ["t", 0.3015094502008],
+ ]
+
+ def make_repeat_fasta(id, desc, src, n)
+ puts ">#{id} #{desc}"
+ v = nil
+ width = 60
+ l = src.length
+ s = src * ((n / l) + 1)
+ s.slice!(n, l)
+ puts(s.scan(/.{1,#{width}}/).join("\n"))
+ end
+
+ def make_random_fasta(id, desc, table, n)
+ puts ">#{id} #{desc}"
+ rand, v = nil,nil
+ width = 60
+ chunk = 1 * width
+ prob = 0.0
+ table.each{|v| v[1]= (prob += v[1])}
+ for i in 1..(n/width)
+ puts((1..width).collect{
+ rand = gen_random(1.0)
+ table.find{|v| v[1]>rand}[0]
+ }.join)
+ end
+ if n%width != 0
+ puts((1..(n%width)).collect{
+ rand = gen_random(1.0)
+ table.find{|v| v[1]>rand}[0]
+ }.join)
+ end
+ end
+
+
+ n = (ARGV[0] or 250_000).to_i
+
+ make_repeat_fasta('ONE', 'Homo sapiens alu', alu, n*2)
+ make_random_fasta('TWO', 'IUB ambiguity codes', iub, n*3)
+ make_random_fasta('THREE', 'Homo sapiens frequency', homosapiens, n*5)
+ EOS
+benchmark:
+ - name: so_reverse_complement
+ prelude: |
+ script = File.join(File.dirname($0), 'bm_so_fasta.rb')
+ File.write(script, bm_so_fasta)
+
+ def prepare_fasta_output n
+ filebase = File.join(File.dirname($0), 'fasta.output')
+ script = File.join(File.dirname($0), 'bm_so_fasta.rb')
+ file = "#{filebase}.#{n}"
+
+ unless FileTest.exist?(file)
+ STDERR.puts "preparing #{file}"
+
+ open(file, 'w'){|f|
+ ARGV[0] = n
+ $stdout = f
+ load script
+ $stdout = STDOUT
+ }
+ end
+ end
+ prepare_fasta_output(2_500_000)
+ script: |
+ # The Great Computer Language Shootout
+ # http://shootout.alioth.debian.org/
+ #
+ # Contributed by Peter Bjarke Olsen
+ # Modified by Doug King
+
+ seq=Array.new
+
+ def revcomp(seq)
+ seq.reverse!.tr!('wsatugcyrkmbdhvnATUGCYRKMBDHVN','WSTAACGRYMKVHDBNTAACGRYMKVHDBN')
+ stringlen=seq.length
+ 0.step(stringlen-1,60) {|x| print seq.slice(x,60) , "\n"}
+ end
+
+ input = open(File.join(File.dirname($0), 'fasta.output.2500000'), 'rb')
+
+ while input.gets
+ if $_ =~ />/
+ if seq.length != 0
+ revcomp(seq.join)
+ seq=Array.new
+ end
+ puts $_
+ else
+ $_.sub(/\n/,'')
+ seq.push $_
+ end
+ end
+ revcomp(seq.join)
+ loop_count: 1
diff --git a/benchmark/bm_so_sieve.rb b/benchmark/so_sieve.rb
index 43dc302648..43dc302648 100644
--- a/benchmark/bm_so_sieve.rb
+++ b/benchmark/so_sieve.rb
diff --git a/benchmark/bm_so_spectralnorm.rb b/benchmark/so_spectralnorm.rb
index 6b97206689..6b97206689 100644
--- a/benchmark/bm_so_spectralnorm.rb
+++ b/benchmark/so_spectralnorm.rb
diff --git a/benchmark/string_capitalize.yml b/benchmark/string_capitalize.yml
new file mode 100644
index 0000000000..7d23fd3d35
--- /dev/null
+++ b/benchmark/string_capitalize.yml
@@ -0,0 +1,10 @@
+prelude: |
+ str1 = [*"a".."m",*"N".."Z",*"0".."9"].join("")
+ str10 = str1 * 10
+ str100 = str10 * 10
+ str1000 = str100 * 10
+benchmark:
+ capitalize-1: str1.capitalize
+ capitalize-10: str10.capitalize
+ capitalize-100: str100.capitalize
+ capitalize-1000: str1000.capitalize
diff --git a/benchmark/string_casecmp.yml b/benchmark/string_casecmp.yml
new file mode 100644
index 0000000000..2354040a04
--- /dev/null
+++ b/benchmark/string_casecmp.yml
@@ -0,0 +1,26 @@
+prelude: |
+ lstr1 = [*"a".."z",*"0".."9"].join("")
+ lstr10 = lstr1 * 10
+ lstr100 = lstr10 * 10
+ lstr1000 = lstr100 * 10
+ lnonascii1 = [*"\u{e0}".."\u{ff}"].join("")
+ lnonascii10 = lnonascii1 * 10
+ lnonascii100 = lnonascii10 * 10
+ lnonascii1000 = lnonascii100 * 10
+ ustr1 = [*"A".."Z",*"0".."9"].join("")
+ ustr10 = ustr1 * 10
+ ustr100 = ustr10 * 10
+ ustr1000 = ustr100 * 10
+ unonascii1 = [*"\u{c0}".."\u{df}"].join("")
+ unonascii10 = unonascii1 * 10
+ unonascii100 = unonascii10 * 10
+ unonascii1000 = unonascii100 * 10
+benchmark:
+ casecmp-1: lstr1.casecmp(ustr1)
+ casecmp-10: lstr10.casecmp(ustr10)
+ casecmp-100: lstr100.casecmp(ustr100)
+ casecmp-1000: lstr1000.casecmp(ustr1000)
+ casecmp-nonascii1: lnonascii1.casecmp(unonascii1)
+ casecmp-nonascii10: lnonascii10.casecmp(unonascii10)
+ casecmp-nonascii100: lnonascii100.casecmp(unonascii100)
+ casecmp-nonascii1000: lnonascii1000.casecmp(unonascii1000)
diff --git a/benchmark/string_casecmp_p.yml b/benchmark/string_casecmp_p.yml
new file mode 100644
index 0000000000..a790ce7d55
--- /dev/null
+++ b/benchmark/string_casecmp_p.yml
@@ -0,0 +1,26 @@
+prelude: |
+ lstr1 = [*"a".."z",*"0".."9"].join("")
+ lstr10 = lstr1 * 10
+ lstr100 = lstr10 * 10
+ lstr1000 = lstr100 * 10
+ lnonascii1 = [*"\u{e0}".."\u{ff}"].join("")
+ lnonascii10 = lnonascii1 * 10
+ lnonascii100 = lnonascii10 * 10
+ lnonascii1000 = lnonascii100 * 10
+ ustr1 = [*"A".."Z",*"0".."9"].join("")
+ ustr10 = ustr1 * 10
+ ustr100 = ustr10 * 10
+ ustr1000 = ustr100 * 10
+ unonascii1 = [*"\u{c0}".."\u{df}"].join("")
+ unonascii10 = unonascii1 * 10
+ unonascii100 = unonascii10 * 10
+ unonascii1000 = unonascii100 * 10
+benchmark:
+ casecmp_p-1: lstr1.casecmp?(ustr1)
+ casecmp_p-10: lstr10.casecmp?(ustr10)
+ casecmp_p-100: lstr100.casecmp?(ustr100)
+ casecmp_p-1000: lstr1000.casecmp?(ustr1000)
+ casecmp_p-nonascii1: lnonascii1.casecmp?(unonascii1)
+ casecmp_p-nonascii10: lnonascii10.casecmp?(unonascii10)
+ casecmp_p-nonascii100: lnonascii100.casecmp?(unonascii100)
+ casecmp_p-nonascii1000: lnonascii1000.casecmp?(unonascii1000)
diff --git a/benchmark/string_downcase.yml b/benchmark/string_downcase.yml
new file mode 100644
index 0000000000..1fea6afbec
--- /dev/null
+++ b/benchmark/string_downcase.yml
@@ -0,0 +1,18 @@
+prelude: |
+ str1 = [*"A".."Z",*"0".."9"].join("")
+ str10 = str1 * 10
+ str100 = str10 * 10
+ str1000 = str100 * 10
+ nonascii1 = [*"\u{c0}".."\u{df}"].join("")
+ nonascii10 = nonascii1 * 10
+ nonascii100 = nonascii10 * 10
+ nonascii1000 = nonascii100 * 10
+benchmark:
+ downcase-1: str1.upcase
+ downcase-10: str10.upcase
+ downcase-100: str100.upcase
+ downcase-1000: str1000.upcase
+ downcase-nonascii1: nonascii1.downcase
+ downcase-nonascii10: nonascii10.downcase
+ downcase-nonascii100: nonascii100.downcase
+ downcase-nonascii1000: nonascii1000.downcase
diff --git a/benchmark/bm_string_index.rb b/benchmark/string_index.rb
index 7783111082..7783111082 100644
--- a/benchmark/bm_string_index.rb
+++ b/benchmark/string_index.rb
diff --git a/benchmark/bm_string_scan_re.rb b/benchmark/string_scan_re.rb
index b0d60201a9..b0d60201a9 100644
--- a/benchmark/bm_string_scan_re.rb
+++ b/benchmark/string_scan_re.rb
diff --git a/benchmark/bm_string_scan_str.rb b/benchmark/string_scan_str.rb
index 42440bd948..42440bd948 100644
--- a/benchmark/bm_string_scan_str.rb
+++ b/benchmark/string_scan_str.rb
diff --git a/benchmark/string_slice.yml b/benchmark/string_slice.yml
new file mode 100644
index 0000000000..fc2393c5d1
--- /dev/null
+++ b/benchmark/string_slice.yml
@@ -0,0 +1,11 @@
+prelude: |
+ long_string = "x"*1000+"-hår"
+benchmark:
+ regexp-short: |
+ "x-hår".slice!(/-(.)(.)(.)/, 3)
+ regexp-long: |
+ long_string.dup.slice!(/-(.)(.)(.)/, 3)
+ string-short: |
+ "x-hår".slice!("r")
+ string-long: |
+ long_string.dup.slice!("r")
diff --git a/benchmark/string_split.yml b/benchmark/string_split.yml
new file mode 100644
index 0000000000..cc2c7d7855
--- /dev/null
+++ b/benchmark/string_split.yml
@@ -0,0 +1,22 @@
+prelude: |
+ str1 = [*0..5].join(" ") + " "
+ str10 = str1 * 10
+ str100 = str10 * 10
+ str1000 = str100 * 10
+benchmark:
+ to_chars-1: str1.split('')
+ to_chars-10: str10.split('')
+ to_chars-100: str100.split('')
+ to_chars-1000: str1000.split('')
+ to_words-1: str1.split(' ')
+ to_words-10: str10.split(' ')
+ to_words-100: str100.split(' ')
+ to_words-1000: str1000.split(' ')
+ re_chars-1: str1.split(//)
+ re_chars-10: str10.split(//)
+ re_chars-100: str100.split(//)
+ re_chars-1000: str1000.split(//)
+ re_space-1: str1.split(/ /)
+ re_space-10: str10.split(/ /)
+ re_space-100: str100.split(/ /)
+ re_space-1000: str1000.split(/ /)
diff --git a/benchmark/string_swapcase.yml b/benchmark/string_swapcase.yml
new file mode 100644
index 0000000000..eeb5928907
--- /dev/null
+++ b/benchmark/string_swapcase.yml
@@ -0,0 +1,18 @@
+prelude: |
+ str1 = [*"A".."M",*"n".."z",*"0".."9"].join("")
+ str10 = str1 * 10
+ str100 = str10 * 10
+ str1000 = str100 * 10
+ nonascii1 = [*"\u{c0}".."\u{cf}",*"\u{f0}".."\u{ff}"].join("")
+ nonascii10 = nonascii1 * 10
+ nonascii100 = nonascii10 * 10
+ nonascii1000 = nonascii100 * 10
+benchmark:
+ swapcase-1: str1.swapcase
+ swapcase-10: str10.swapcase
+ swapcase-100: str100.swapcase
+ swapcase-1000: str1000.swapcase
+ swapcase-nonascii1: nonascii1.swapcase
+ swapcase-nonascii10: nonascii10.swapcase
+ swapcase-nonascii100: nonascii100.swapcase
+ swapcase-nonascii1000: nonascii1000.swapcase
diff --git a/benchmark/string_upcase.yml b/benchmark/string_upcase.yml
new file mode 100644
index 0000000000..dab84bbde2
--- /dev/null
+++ b/benchmark/string_upcase.yml
@@ -0,0 +1,18 @@
+prelude: |
+ str1 = [*"a".."z",*"0".."9"].join("")
+ str10 = str1 * 10
+ str100 = str10 * 10
+ str1000 = str100 * 10
+ nonascii1 = [*"\u{e0}".."\u{ff}"].join("")
+ nonascii10 = nonascii1 * 10
+ nonascii100 = nonascii10 * 10
+ nonascii1000 = nonascii100 * 10
+benchmark:
+ upcase-1: str1.upcase
+ upcase-10: str10.upcase
+ upcase-100: str100.upcase
+ upcase-1000: str1000.upcase
+ upcase-nonascii1: nonascii1.upcase
+ upcase-nonascii10: nonascii10.upcase
+ upcase-nonascii100: nonascii100.upcase
+ upcase-nonascii1000: nonascii1000.upcase
diff --git a/benchmark/time_strptime.yml b/benchmark/time_strptime.yml
new file mode 100644
index 0000000000..8d89ebb7a7
--- /dev/null
+++ b/benchmark/time_strptime.yml
@@ -0,0 +1,13 @@
+prelude: |
+ require 'time'
+benchmark:
+ - Time.strptime("28/Aug/2005:06:54:20 +0000", "%d/%b/%Y:%T %z")
+ - Time.strptime("1", "%s")
+ - Time.strptime("0 +0100", "%s %z")
+ - Time.strptime("0 UTC", "%s %z")
+ - Time.strptime("1.5", "%s.%N")
+ - Time.strptime("1.000000000001", "%s.%N")
+ - Time.strptime("20010203 -0200", "%Y%m%d %z")
+ - Time.strptime("20010203 UTC", "%Y%m%d %z")
+ - Time.strptime("2018-365", "%Y-%j")
+ - Time.strptime("2018-091", "%Y-%j")
diff --git a/benchmark/bm_time_subsec.rb b/benchmark/time_subsec.rb
index 505021c701..505021c701 100644
--- a/benchmark/bm_time_subsec.rb
+++ b/benchmark/time_subsec.rb
diff --git a/benchmark/vm_array.yml b/benchmark/vm_array.yml
new file mode 100644
index 0000000000..2a177237ef
--- /dev/null
+++ b/benchmark/vm_array.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_array: |
+ a = [1,2,3,4,5,6,7,8,9,10]
+loop_count: 6000000
diff --git a/benchmark/vm_attr_ivar.yml b/benchmark/vm_attr_ivar.yml
new file mode 100644
index 0000000000..75b803478e
--- /dev/null
+++ b/benchmark/vm_attr_ivar.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ attr_reader :a, :b
+ def initialize
+ @a = nil
+ @b = nil
+ end
+ end
+ obj = C.new
+benchmark:
+ vm_attr_ivar: |
+ j = obj.a
+ k = obj.b
+loop_count: 30000000
diff --git a/benchmark/vm_attr_ivar_set.yml b/benchmark/vm_attr_ivar_set.yml
new file mode 100644
index 0000000000..a0d379b18a
--- /dev/null
+++ b/benchmark/vm_attr_ivar_set.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ attr_accessor :a, :b
+ def initialize
+ @a = nil
+ @b = nil
+ end
+ end
+ obj = C.new
+benchmark:
+ vm_attr_ivar_set: |
+ obj.a = 1
+ obj.b = 2
+loop_count: 30000000
diff --git a/benchmark/bm_vm3_backtrace.rb b/benchmark/vm_backtrace.rb
index 0fbf73e1ca..0fbf73e1ca 100644
--- a/benchmark/bm_vm3_backtrace.rb
+++ b/benchmark/vm_backtrace.rb
diff --git a/benchmark/vm_bigarray.yml b/benchmark/vm_bigarray.yml
new file mode 100644
index 0000000000..8b2d3f3443
--- /dev/null
+++ b/benchmark/vm_bigarray.yml
@@ -0,0 +1,105 @@
+benchmark:
+ vm_bigarray: |
+ a = [
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ ]
+loop_count: 6000000
diff --git a/benchmark/vm_bighash.yml b/benchmark/vm_bighash.yml
new file mode 100644
index 0000000000..4dacfde793
--- /dev/null
+++ b/benchmark/vm_bighash.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_bighash: |
+ a = {0=>0, 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, 18=>18, 19=>19, 20=>20, 21=>21, 22=>22, 23=>23, 24=>24, 25=>25, 26=>26, 27=>27, 28=>28, 29=>29, 30=>30, 31=>31, 32=>32, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 38=>38, 39=>39, 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, 60=>60, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67, 68=>68, 69=>69, 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79, 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, 90=>90, 91=>91, 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, 100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, 110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, 120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126, 127=>127, 128=>128, 129=>129, 130=>130, 131=>131, 132=>132, 133=>133, 134=>134, 135=>135, 136=>136, 137=>137, 138=>138, 139=>139, 140=>140, 141=>141, 142=>142, 143=>143, 144=>144, 145=>145, 146=>146, 147=>147, 148=>148, 149=>149, 150=>150, 151=>151, 152=>152, 153=>153, 154=>154, 155=>155, 156=>156, 157=>157, 158=>158, 159=>159, 160=>160, 161=>161, 162=>162, 163=>163, 164=>164, 165=>165, 166=>166, 167=>167, 168=>168, 169=>169, 170=>170, 171=>171, 172=>172, 173=>173, 174=>174, 175=>175, 176=>176, 177=>177, 178=>178, 179=>179, 180=>180, 181=>181, 182=>182, 183=>183, 184=>184, 185=>185, 186=>186, 187=>187, 188=>188, 189=>189, 190=>190, 191=>191, 192=>192, 193=>193, 194=>194, 195=>195, 196=>196, 197=>197, 198=>198, 199=>199, 200=>200, 201=>201, 202=>202, 203=>203, 204=>204, 205=>205, 206=>206, 207=>207, 208=>208, 209=>209, 210=>210, 211=>211, 212=>212, 213=>213, 214=>214, 215=>215, 216=>216, 217=>217, 218=>218, 219=>219, 220=>220, 221=>221, 222=>222, 223=>223, 224=>224, 225=>225, 226=>226, 227=>227, 228=>228, 229=>229, 230=>230, 231=>231, 232=>232, 233=>233, 234=>234, 235=>235, 236=>236, 237=>237, 238=>238, 239=>239, 240=>240, 241=>241, 242=>242, 243=>243, 244=>244, 245=>245, 246=>246, 247=>247, 248=>248, 249=>249, 250=>250, 251=>251, 252=>252, 253=>253, 254=>254, 255=>255, 256=>256, 257=>257, 258=>258, 259=>259, 260=>260, 261=>261, 262=>262, 263=>263, 264=>264, 265=>265, 266=>266, 267=>267, 268=>268, 269=>269, 270=>270, 271=>271, 272=>272, 273=>273, 274=>274, 275=>275, 276=>276, 277=>277, 278=>278, 279=>279, 280=>280, 281=>281, 282=>282, 283=>283, 284=>284, 285=>285, 286=>286, 287=>287, 288=>288, 289=>289, 290=>290, 291=>291, 292=>292, 293=>293, 294=>294, 295=>295, 296=>296, 297=>297, 298=>298, 299=>299, 300=>300, 301=>301, 302=>302, 303=>303, 304=>304, 305=>305, 306=>306, 307=>307, 308=>308, 309=>309, 310=>310, 311=>311, 312=>312, 313=>313, 314=>314, 315=>315, 316=>316, 317=>317, 318=>318, 319=>319, 320=>320, 321=>321, 322=>322, 323=>323, 324=>324, 325=>325, 326=>326, 327=>327, 328=>328, 329=>329, 330=>330, 331=>331, 332=>332, 333=>333, 334=>334, 335=>335, 336=>336, 337=>337, 338=>338, 339=>339, 340=>340, 341=>341, 342=>342, 343=>343, 344=>344, 345=>345, 346=>346, 347=>347, 348=>348, 349=>349, 350=>350, 351=>351, 352=>352, 353=>353, 354=>354, 355=>355, 356=>356, 357=>357, 358=>358, 359=>359, 360=>360, 361=>361, 362=>362, 363=>363, 364=>364, 365=>365, 366=>366, 367=>367, 368=>368, 369=>369, 370=>370, 371=>371, 372=>372, 373=>373, 374=>374, 375=>375, 376=>376, 377=>377, 378=>378, 379=>379, 380=>380, 381=>381, 382=>382, 383=>383, 384=>384, 385=>385, 386=>386, 387=>387, 388=>388, 389=>389, 390=>390, 391=>391, 392=>392, 393=>393, 394=>394, 395=>395, 396=>396, 397=>397, 398=>398, 399=>399, 400=>400, 401=>401, 402=>402, 403=>403, 404=>404, 405=>405, 406=>406, 407=>407, 408=>408, 409=>409, 410=>410, 411=>411, 412=>412, 413=>413, 414=>414, 415=>415, 416=>416, 417=>417, 418=>418, 419=>419, 420=>420, 421=>421, 422=>422, 423=>423, 424=>424, 425=>425, 426=>426, 427=>427, 428=>428, 429=>429, 430=>430, 431=>431, 432=>432, 433=>433, 434=>434, 435=>435, 436=>436, 437=>437, 438=>438, 439=>439, 440=>440, 441=>441, 442=>442, 443=>443, 444=>444, 445=>445, 446=>446, 447=>447, 448=>448, 449=>449, 450=>450, 451=>451, 452=>452, 453=>453, 454=>454, 455=>455, 456=>456, 457=>457, 458=>458, 459=>459, 460=>460, 461=>461, 462=>462, 463=>463, 464=>464, 465=>465, 466=>466, 467=>467, 468=>468, 469=>469, 470=>470, 471=>471, 472=>472, 473=>473, 474=>474, 475=>475, 476=>476, 477=>477, 478=>478, 479=>479, 480=>480, 481=>481, 482=>482, 483=>483, 484=>484, 485=>485, 486=>486, 487=>487, 488=>488, 489=>489, 490=>490, 491=>491, 492=>492, 493=>493, 494=>494, 495=>495, 496=>496, 497=>497, 498=>498, 499=>499, 500=>500,}
+loop_count: 60000
diff --git a/benchmark/vm_block.yml b/benchmark/vm_block.yml
new file mode 100644
index 0000000000..68b3e40bf5
--- /dev/null
+++ b/benchmark/vm_block.yml
@@ -0,0 +1,9 @@
+prelude: |
+ def m
+ yield
+ end
+benchmark:
+ vm_block: |
+ m{
+ }
+loop_count: 30000000
diff --git a/benchmark/vm_block_handler.yml b/benchmark/vm_block_handler.yml
new file mode 100644
index 0000000000..461d7953ad
--- /dev/null
+++ b/benchmark/vm_block_handler.yml
@@ -0,0 +1,27 @@
+# :FIXME: is there a way to benchmark block_handler_type_ifunc?
+
+prelude: |
+ p = proc{_1}
+ o = Object.new
+ def o.each
+ i = 0
+ while i < 3_000_000 do
+ yield i
+ i += 1
+ end
+ end
+
+benchmark:
+ - name: block_handler_type_iseq
+ script: |
+ o.each{_1}
+
+ - name: block_handler_type_symbol
+ script: |
+ o.each(&:itself)
+
+ - name: block_handler_type_proc
+ script: |
+ o.each(&p)
+
+loop_count: 1
diff --git a/benchmark/vm_blockparam.yml b/benchmark/vm_blockparam.yml
new file mode 100644
index 0000000000..5e5a0170a2
--- /dev/null
+++ b/benchmark/vm_blockparam.yml
@@ -0,0 +1,7 @@
+prelude: |
+ def m &b
+ end
+benchmark:
+ vm_blockparam: |
+ m{}
+loop_count: 30000000
diff --git a/benchmark/vm_blockparam_call.yml b/benchmark/vm_blockparam_call.yml
new file mode 100644
index 0000000000..a7d8d366ea
--- /dev/null
+++ b/benchmark/vm_blockparam_call.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def m &b
+ b.call
+ end
+benchmark:
+ vm_blockparam_call: |
+ m{}
+loop_count: 30000000
diff --git a/benchmark/vm_blockparam_pass.yml b/benchmark/vm_blockparam_pass.yml
new file mode 100644
index 0000000000..841f5e7a63
--- /dev/null
+++ b/benchmark/vm_blockparam_pass.yml
@@ -0,0 +1,12 @@
+prelude: |
+ def bp_yield
+ yield
+ end
+
+ def bp_pass &b
+ bp_yield &b
+ end
+benchmark:
+ vm_blockparam_pass: |
+ bp_pass{}
+loop_count: 30000000
diff --git a/benchmark/vm_blockparam_yield.yml b/benchmark/vm_blockparam_yield.yml
new file mode 100644
index 0000000000..8ea9b46ed2
--- /dev/null
+++ b/benchmark/vm_blockparam_yield.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def bp_yield &b
+ yield
+ end
+benchmark:
+ vm_blockparam_yield: |
+ bp_yield{}
+loop_count: 30000000
diff --git a/benchmark/vm_case.yml b/benchmark/vm_case.yml
new file mode 100644
index 0000000000..b26a491a15
--- /dev/null
+++ b/benchmark/vm_case.yml
@@ -0,0 +1,13 @@
+benchmark:
+ vm_case: |
+ case :foo
+ when :bar
+ raise
+ when :baz
+ raise
+ when :boo
+ raise
+ when :foo
+ # noop
+ end
+loop_count: 6000000
diff --git a/benchmark/vm_case_lit.yml b/benchmark/vm_case_lit.yml
new file mode 100644
index 0000000000..9f91801544
--- /dev/null
+++ b/benchmark/vm_case_lit.yml
@@ -0,0 +1,23 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_case_lit: |
+ i = 0
+ @ret = [ "foo", true, false, :sym, 6, nil, 0.1, 0xffffffffffffffff ]
+ def foo(i)
+ @ret[i % @ret.size]
+ end
+
+ while i<6_000_000
+ case foo(i)
+ when "foo" then :foo
+ when true then true
+ when false then false
+ when :sym then :sym
+ when 6 then :fix
+ when nil then nil
+ when 0.1 then :float
+ when 0xffffffffffffffff then :big
+ end
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/bm_vm3_clearmethodcache.rb b/benchmark/vm_clearmethodcache.rb
index 9661323cd2..9661323cd2 100644
--- a/benchmark/bm_vm3_clearmethodcache.rb
+++ b/benchmark/vm_clearmethodcache.rb
diff --git a/benchmark/vm_const.yml b/benchmark/vm_const.yml
new file mode 100644
index 0000000000..6064d4eed0
--- /dev/null
+++ b/benchmark/vm_const.yml
@@ -0,0 +1,7 @@
+prelude: |
+ Const = 1
+benchmark:
+ vm_const: |
+ j = Const
+ k = Const
+loop_count: 30000000
diff --git a/benchmark/vm_defined_method.yml b/benchmark/vm_defined_method.yml
new file mode 100644
index 0000000000..347e0cfd33
--- /dev/null
+++ b/benchmark/vm_defined_method.yml
@@ -0,0 +1,8 @@
+prelude: |
+ class Object
+ define_method(:m){}
+ end
+benchmark:
+ vm_defined_method: |
+ m; m; m; m; m; m; m; m;
+loop_count: 6000000
diff --git a/benchmark/vm_dstr.yml b/benchmark/vm_dstr.yml
new file mode 100644
index 0000000000..30c7a3193c
--- /dev/null
+++ b/benchmark/vm_dstr.yml
@@ -0,0 +1,6 @@
+prelude: |
+ x = y = 'z'
+benchmark:
+ vm_dstr: |
+ str = "foo#{x}bar#{y}baz"
+loop_count: 6000000
diff --git a/benchmark/vm_ensure.yml b/benchmark/vm_ensure.yml
new file mode 100644
index 0000000000..4ea62f30de
--- /dev/null
+++ b/benchmark/vm_ensure.yml
@@ -0,0 +1,14 @@
+# Not utilizing loop_count since using it for this is too unstable for now
+benchmark:
+ vm_ensure: |
+ i = 0
+ while i<30_000_000
+ i += 1
+ begin
+ begin
+ ensure
+ end
+ ensure
+ end
+ end
+loop_count: 1
diff --git a/benchmark/vm_eval.yml b/benchmark/vm_eval.yml
new file mode 100644
index 0000000000..7ba1a8d1de
--- /dev/null
+++ b/benchmark/vm_eval.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_eval: |
+ eval("1")
+loop_count: 6000000
diff --git a/benchmark/vm_fiber_allocate.yml b/benchmark/vm_fiber_allocate.yml
new file mode 100644
index 0000000000..b5a54e1ddf
--- /dev/null
+++ b/benchmark/vm_fiber_allocate.yml
@@ -0,0 +1,8 @@
+prelude: |
+ # Disable GC to see raw throughput:
+ GC.disable
+benchmark:
+ vm_fiber_allocate: |
+ fiber = Fiber.new{Fiber.yield}
+ fiber.resume
+loop_count: 100000
diff --git a/benchmark/vm_fiber_count.yml b/benchmark/vm_fiber_count.yml
new file mode 100644
index 0000000000..b83d3152d4
--- /dev/null
+++ b/benchmark/vm_fiber_count.yml
@@ -0,0 +1,10 @@
+# On Linux, you will need to increase the maximum number of memory maps:
+# sudo sysctl -w vm.max_map_count=200000
+prelude: |
+ fibers = []
+benchmark:
+ vm_fiber_count: |
+ fiber = Fiber.new{Fiber.yield}
+ fibers << fiber
+ fiber.resume
+loop_count: 100000
diff --git a/benchmark/vm_fiber_reuse.yml b/benchmark/vm_fiber_reuse.yml
new file mode 100644
index 0000000000..4ca41085b1
--- /dev/null
+++ b/benchmark/vm_fiber_reuse.yml
@@ -0,0 +1,14 @@
+prelude: |
+ GC.disable
+ fibers = []
+benchmark:
+ vm_fiber_reuse: |
+ 1024.times do
+ fiber = Fiber.new{Fiber.yield}
+ fibers << fiber
+ fiber.resume
+ end
+
+ fibers.clear
+ GC.start
+loop_count: 200
diff --git a/benchmark/vm_fiber_reuse_gc.yml b/benchmark/vm_fiber_reuse_gc.yml
new file mode 100644
index 0000000000..892622f121
--- /dev/null
+++ b/benchmark/vm_fiber_reuse_gc.yml
@@ -0,0 +1,12 @@
+# https://bugs.ruby-lang.org/issues/16009
+prelude: |
+ fibers = []
+benchmark:
+ vm_fiber_reuse_gc: |
+ 2000.times do
+ fiber = Fiber.new{Fiber.yield}
+ fibers << fiber
+ fiber.resume
+ end
+ fibers.clear
+loop_count: 100
diff --git a/benchmark/vm_fiber_switch.yml b/benchmark/vm_fiber_switch.yml
new file mode 100644
index 0000000000..3de36b66eb
--- /dev/null
+++ b/benchmark/vm_fiber_switch.yml
@@ -0,0 +1,9 @@
+prelude: |
+ # based on benchmark for [ruby-core:65518] [Feature #10341] by Knut Franke
+ fib = Fiber.new do
+ loop { Fiber.yield }
+ end
+benchmark:
+ vm_fiber_switch: |
+ fib.resume
+loop_count: 20000000
diff --git a/benchmark/vm_float_simple.yml b/benchmark/vm_float_simple.yml
new file mode 100644
index 0000000000..92f5fd52ab
--- /dev/null
+++ b/benchmark/vm_float_simple.yml
@@ -0,0 +1,8 @@
+prelude: |
+ f = 0.0
+benchmark:
+ vm_float_simple: |
+ f += 0.1; f -= 0.1
+ f += 0.1; f -= 0.1
+ f += 0.1; f -= 0.1
+loop_count: 30000000
diff --git a/benchmark/vm_freezestring.yml b/benchmark/vm_freezestring.yml
new file mode 100644
index 0000000000..facc9aa043
--- /dev/null
+++ b/benchmark/vm_freezestring.yml
@@ -0,0 +1,10 @@
+prelude: |
+ class String
+ def freeze
+ -self
+ end
+ end
+benchmark:
+ vm_freezestring: |
+ "tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze
+loop_count: 6000000
diff --git a/benchmark/bm_vm3_gc.rb b/benchmark/vm_gc.rb
index e668026915..e668026915 100644
--- a/benchmark/bm_vm3_gc.rb
+++ b/benchmark/vm_gc.rb
diff --git a/benchmark/bm_vm3_gc_old_full.rb b/benchmark/vm_gc_old_full.rb
index cfdfc8c5a5..cfdfc8c5a5 100644
--- a/benchmark/bm_vm3_gc_old_full.rb
+++ b/benchmark/vm_gc_old_full.rb
diff --git a/benchmark/bm_vm3_gc_old_immediate.rb b/benchmark/vm_gc_old_immediate.rb
index ad22feb655..ad22feb655 100644
--- a/benchmark/bm_vm3_gc_old_immediate.rb
+++ b/benchmark/vm_gc_old_immediate.rb
diff --git a/benchmark/bm_vm3_gc_old_lazy.rb b/benchmark/vm_gc_old_lazy.rb
index b74d44baf1..b74d44baf1 100644
--- a/benchmark/bm_vm3_gc_old_lazy.rb
+++ b/benchmark/vm_gc_old_lazy.rb
diff --git a/benchmark/vm_gc_short_lived.yml b/benchmark/vm_gc_short_lived.yml
new file mode 100644
index 0000000000..29c803fee3
--- /dev/null
+++ b/benchmark/vm_gc_short_lived.yml
@@ -0,0 +1,9 @@
+benchmark:
+ vm_gc_short_lived: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_short_with_complex_long.yml b/benchmark/vm_gc_short_with_complex_long.yml
new file mode 100644
index 0000000000..4b6c3ed7b9
--- /dev/null
+++ b/benchmark/vm_gc_short_with_complex_long.yml
@@ -0,0 +1,25 @@
+prelude: |
+ def nested_hash h, n
+ if n == 0
+ ''
+ else
+ 10.times{
+ h[Object.new] = nested_hash(h, n-1)
+ }
+ end
+ end
+
+ long_lived = Hash.new
+ nested_hash long_lived, 6
+
+ GC.start
+ GC.start
+benchmark:
+ vm_gc_short_with_complex_long: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_short_with_long.yml b/benchmark/vm_gc_short_with_long.yml
new file mode 100644
index 0000000000..03ba0f95a9
--- /dev/null
+++ b/benchmark/vm_gc_short_with_long.yml
@@ -0,0 +1,13 @@
+prelude: |
+ long_lived = Array.new(1_000_000){|i| "#{i}"}
+ GC.start
+ GC.start
+benchmark:
+ vm_gc_short_with_long: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_short_with_symbol.yml b/benchmark/vm_gc_short_with_symbol.yml
new file mode 100644
index 0000000000..129b8bf4ed
--- /dev/null
+++ b/benchmark/vm_gc_short_with_symbol.yml
@@ -0,0 +1,13 @@
+prelude: |
+ 50_000.times{|i| sym = "sym#{i}".to_sym}
+ GC.start
+ GC.start
+benchmark:
+ vm_gc_short_with_symbol: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_ary.yml b/benchmark/vm_gc_wb_ary.yml
new file mode 100644
index 0000000000..e3293e72d0
--- /dev/null
+++ b/benchmark/vm_gc_wb_ary.yml
@@ -0,0 +1,12 @@
+prelude: |
+ short_lived_ary = []
+
+ if RUBY_VERSION >= "2.2.0"
+ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
+ end
+
+ short_lived = ''
+benchmark:
+ vm_gc_wb_ary: |
+ short_lived_ary[0] = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_ary_promoted.yml b/benchmark/vm_gc_wb_ary_promoted.yml
new file mode 100644
index 0000000000..003995945b
--- /dev/null
+++ b/benchmark/vm_gc_wb_ary_promoted.yml
@@ -0,0 +1,15 @@
+prelude: |
+ long_lived = []
+
+ if RUBY_VERSION > "2.2.0"
+ 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
+ elsif
+ GC.start
+ end
+
+ short_lived = ''
+
+benchmark:
+ vm_gc_wb_ary_promoted: |
+ long_lived[0] = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_obj.yml b/benchmark/vm_gc_wb_obj.yml
new file mode 100644
index 0000000000..a2a2ce2d18
--- /dev/null
+++ b/benchmark/vm_gc_wb_obj.yml
@@ -0,0 +1,15 @@
+prelude: |
+ class C
+ attr_accessor :foo
+ end
+ short_lived_obj = C.new
+
+ if RUBY_VERSION >= "2.2.0"
+ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
+ end
+
+ short_lived = ''
+benchmark:
+ vm_gc_wb_obj: |
+ short_lived_obj.foo = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_obj_promoted.yml b/benchmark/vm_gc_wb_obj_promoted.yml
new file mode 100644
index 0000000000..00a454ba72
--- /dev/null
+++ b/benchmark/vm_gc_wb_obj_promoted.yml
@@ -0,0 +1,17 @@
+prelude: |
+ class C
+ attr_accessor :foo
+ end
+ long_lived = C.new
+
+ if RUBY_VERSION >= "2.2.0"
+ 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
+ elsif
+ GC.start
+ end
+
+ short_lived = ''
+benchmark:
+ vm_gc_wb_obj_promoted: |
+ long_lived.foo = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_iclass_super.yml b/benchmark/vm_iclass_super.yml
new file mode 100644
index 0000000000..21bb7db247
--- /dev/null
+++ b/benchmark/vm_iclass_super.yml
@@ -0,0 +1,20 @@
+prelude: |
+ class C
+ def m
+ 1
+ end
+
+ ("A".."M").each do |module_name|
+ eval <<-EOM
+ module #{module_name}
+ def m; super; end
+ end
+ prepend #{module_name}
+ EOM
+ end
+ end
+
+ obj = C.new
+benchmark:
+ vm_iclass_super: obj.m
+loop_count: 6000000
diff --git a/benchmark/vm_ivar.yml b/benchmark/vm_ivar.yml
new file mode 100644
index 0000000000..119531d5ef
--- /dev/null
+++ b/benchmark/vm_ivar.yml
@@ -0,0 +1,6 @@
+prelude: "@a = 1\n"
+benchmark:
+ vm_ivar: |
+ j = @a
+ k = @a
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_init.yml b/benchmark/vm_ivar_init.yml
new file mode 100644
index 0000000000..c6f1633907
--- /dev/null
+++ b/benchmark/vm_ivar_init.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ def initialize
+ @a = nil
+ @b = nil
+ @c = nil
+ @d = nil
+ @e = nil
+ end
+ end
+benchmark:
+ vm_ivar_init: |
+ C.new
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_set.yml b/benchmark/vm_ivar_set.yml
new file mode 100644
index 0000000000..8bbb60043b
--- /dev/null
+++ b/benchmark/vm_ivar_set.yml
@@ -0,0 +1,5 @@
+benchmark:
+ vm_ivar_set: |
+ @a = 1
+ @b = 2
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_set_subclass.yml b/benchmark/vm_ivar_set_subclass.yml
new file mode 100644
index 0000000000..2653d36ded
--- /dev/null
+++ b/benchmark/vm_ivar_set_subclass.yml
@@ -0,0 +1,17 @@
+prelude: |
+ class A
+ def initialize
+ @a = nil
+ @b = nil
+ @c = nil
+ @d = nil
+ @e = nil
+ end
+ end
+ class B < A; end
+ class C < A; end
+benchmark:
+ vm_ivar_init_subclass: |
+ B.new
+ C.new
+loop_count: 3000000
diff --git a/benchmark/vm_length.yml b/benchmark/vm_length.yml
new file mode 100644
index 0000000000..5fd94e7d86
--- /dev/null
+++ b/benchmark/vm_length.yml
@@ -0,0 +1,8 @@
+prelude: |
+ a = 'abc'
+ b = [1, 2, 3]
+benchmark:
+ vm_length: |
+ a.length
+ b.length
+loop_count: 30000000
diff --git a/benchmark/vm_lvar_init.yml b/benchmark/vm_lvar_init.yml
new file mode 100644
index 0000000000..70a9b1c0ca
--- /dev/null
+++ b/benchmark/vm_lvar_init.yml
@@ -0,0 +1,21 @@
+# while loop cost is not removed because `i` is used in the script
+benchmark:
+ vm_lvar_init: |
+ def m v
+ unless v
+ # unreachable code
+ v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = v10 =
+ v11 = v12 = v13 = v14 = v15 = v16 = v17 = v18 = v19 = v20 =
+ v21 = v22 = v23 = v24 = v25 = v26 = v27 = v28 = v29 = v30 =
+ v31 = v32 = v33 = v34 = v35 = v36 = v37 = v38 = v39 = v40 =
+ v41 = v42 = v43 = v44 = v45 = v46 = v47 = v48 = v49 = v50 = 1
+ end
+ end
+
+ i = 0
+
+ while i<30_000_000
+ i += 1
+ m i
+ end
+loop_count: 1
diff --git a/benchmark/vm_lvar_set.yml b/benchmark/vm_lvar_set.yml
new file mode 100644
index 0000000000..f29f763d81
--- /dev/null
+++ b/benchmark/vm_lvar_set.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_lvar_set: |
+ a = b = c = d = e = f = g = h = j = k = l = m = n = o = p = q = r = 1
+loop_count: 30000000
diff --git a/benchmark/vm_method.yml b/benchmark/vm_method.yml
new file mode 100644
index 0000000000..d45e4ec572
--- /dev/null
+++ b/benchmark/vm_method.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def m
+ nil
+ end
+benchmark:
+ vm_method: |
+ m; m; m; m; m; m; m; m;
+loop_count: 6000000
diff --git a/benchmark/vm_method_missing.yml b/benchmark/vm_method_missing.yml
new file mode 100644
index 0000000000..3da456c0bb
--- /dev/null
+++ b/benchmark/vm_method_missing.yml
@@ -0,0 +1,11 @@
+prelude: |
+ class C
+ def method_missing mid
+ end
+ end
+
+ obj = C.new
+benchmark:
+ vm_method_missing: |
+ obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m;
+loop_count: 6000000
diff --git a/benchmark/vm_method_with_block.yml b/benchmark/vm_method_with_block.yml
new file mode 100644
index 0000000000..281a481394
--- /dev/null
+++ b/benchmark/vm_method_with_block.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def m
+ nil
+ end
+benchmark:
+ vm_method_with_block: |
+ m{}; m{}; m{}; m{}; m{}; m{}; m{}; m{};
+loop_count: 6000000
diff --git a/benchmark/vm_module_ann_const_set.yml b/benchmark/vm_module_ann_const_set.yml
new file mode 100644
index 0000000000..243229ba4a
--- /dev/null
+++ b/benchmark/vm_module_ann_const_set.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_module_ann_const_set: |
+ Module.new.const_set(:X, Module.new)
+loop_count: 6000000
diff --git a/benchmark/vm_module_const_set.yml b/benchmark/vm_module_const_set.yml
new file mode 100644
index 0000000000..e5a24181a9
--- /dev/null
+++ b/benchmark/vm_module_const_set.yml
@@ -0,0 +1,8 @@
+prelude: |
+ module M
+ end
+ $VERBOSE = nil
+benchmark:
+ vm_module_const_set: |
+ M.const_set(:X, Module.new)
+loop_count: 6000000
diff --git a/benchmark/vm_mutex.yml b/benchmark/vm_mutex.yml
new file mode 100644
index 0000000000..abcf1e28ce
--- /dev/null
+++ b/benchmark/vm_mutex.yml
@@ -0,0 +1,8 @@
+prelude: |
+ require 'thread'
+
+ m = Thread::Mutex.new
+benchmark:
+ vm_mutex: |
+ m.synchronize{}
+loop_count: 6000000
diff --git a/benchmark/vm_neq.yml b/benchmark/vm_neq.yml
new file mode 100644
index 0000000000..fb04d15ae8
--- /dev/null
+++ b/benchmark/vm_neq.yml
@@ -0,0 +1,7 @@
+prelude: |
+ obj1 = Object.new
+ obj2 = Object.new
+benchmark:
+ vm_neq: |
+ obj1 != obj2
+loop_count: 30000000
diff --git a/benchmark/vm_newlambda.yml b/benchmark/vm_newlambda.yml
new file mode 100644
index 0000000000..0b9787d91a
--- /dev/null
+++ b/benchmark/vm_newlambda.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_newlambda: |
+ lambda {}
+loop_count: 6000000
diff --git a/benchmark/vm_not.yml b/benchmark/vm_not.yml
new file mode 100644
index 0000000000..c68dde3c50
--- /dev/null
+++ b/benchmark/vm_not.yml
@@ -0,0 +1,6 @@
+prelude: |
+ obj = Object.new
+benchmark:
+ vm_not: |
+ !obj
+loop_count: 30000000
diff --git a/benchmark/vm_poly_method.yml b/benchmark/vm_poly_method.yml
new file mode 100644
index 0000000000..dd2f4e71de
--- /dev/null
+++ b/benchmark/vm_poly_method.yml
@@ -0,0 +1,24 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_poly_method: |
+ class C1
+ def m
+ 1
+ end
+ end
+ class C2
+ def m
+ 2
+ end
+ end
+
+ o1 = C1.new
+ o2 = C2.new
+
+ i = 0
+ while i<6_000_000
+ o = (i % 2 == 0) ? o1 : o2
+ o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/vm_poly_method_ov.yml b/benchmark/vm_poly_method_ov.yml
new file mode 100644
index 0000000000..bca1b62729
--- /dev/null
+++ b/benchmark/vm_poly_method_ov.yml
@@ -0,0 +1,24 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_poly_method_ov: |
+ class C1
+ def m
+ 1
+ end
+ end
+ class C2
+ def m
+ 2
+ end
+ end
+
+ o1 = C1.new
+ o2 = C2.new
+
+ i = 0
+ while i<6_000_000
+ o = (i % 2 == 0) ? o1 : o2
+ # o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/vm_poly_same_method.yml b/benchmark/vm_poly_same_method.yml
new file mode 100644
index 0000000000..6c5404ac84
--- /dev/null
+++ b/benchmark/vm_poly_same_method.yml
@@ -0,0 +1,25 @@
+prelude: |
+ module AR; end
+ class AR::Base
+ def create_or_update
+ nil
+ end
+ def save
+ create_or_update
+ end
+ end
+ class Foo < AR::Base; end
+ class Bar < AR::Base; end
+ o1 = Foo.new
+ o2 = Bar.new
+benchmark:
+ vm_poly_same_method: |
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+loop_count: 6000000
diff --git a/benchmark/vm_poly_singleton.yml b/benchmark/vm_poly_singleton.yml
new file mode 100644
index 0000000000..c7923160fb
--- /dev/null
+++ b/benchmark/vm_poly_singleton.yml
@@ -0,0 +1,18 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_poly_singleton: |
+ class C1
+ def m; 1; end
+ end
+
+ o1 = C1.new
+ o2 = C1.new
+ o2.singleton_class
+
+ i = 0
+ while i<6_000_000 # benchmark loop 2
+ o = (i % 2 == 0) ? o1 : o2
+ o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/vm_proc.yml b/benchmark/vm_proc.yml
new file mode 100644
index 0000000000..2f8de6c272
--- /dev/null
+++ b/benchmark/vm_proc.yml
@@ -0,0 +1,12 @@
+prelude: |
+ def m &b
+ b
+ end
+
+ pr = m{
+ a = 1
+ }
+benchmark:
+ vm_proc: |
+ pr.call
+loop_count: 6000000
diff --git a/benchmark/vm_raise1.yml b/benchmark/vm_raise1.yml
new file mode 100644
index 0000000000..247d9f70ee
--- /dev/null
+++ b/benchmark/vm_raise1.yml
@@ -0,0 +1,16 @@
+prelude: |
+ def rec n
+ if n > 0
+ rec n-1
+ else
+ raise
+ end
+ end
+benchmark:
+ vm_raise1: |
+ begin
+ rec 1
+ rescue
+ # ignore
+ end
+loop_count: 6000000
diff --git a/benchmark/vm_raise2.yml b/benchmark/vm_raise2.yml
new file mode 100644
index 0000000000..f0fa047b3c
--- /dev/null
+++ b/benchmark/vm_raise2.yml
@@ -0,0 +1,16 @@
+prelude: |
+ def rec n
+ if n > 0
+ rec n-1
+ else
+ raise
+ end
+ end
+benchmark:
+ vm_raise2: |
+ begin
+ rec 10
+ rescue
+ # ignore
+ end
+loop_count: 6000000
diff --git a/benchmark/vm_regexp.yml b/benchmark/vm_regexp.yml
new file mode 100644
index 0000000000..2aa3d94dbd
--- /dev/null
+++ b/benchmark/vm_regexp.yml
@@ -0,0 +1,8 @@
+prelude: |
+ str = 'xxxhogexxx'
+benchmark:
+ vm_regexp: |
+ /hoge/ =~ str
+ vm_regexp_invert: |
+ str =~ /hoge/
+loop_count: 6000000
diff --git a/benchmark/vm_rescue.yml b/benchmark/vm_rescue.yml
new file mode 100644
index 0000000000..b4a0af521f
--- /dev/null
+++ b/benchmark/vm_rescue.yml
@@ -0,0 +1,6 @@
+benchmark:
+ vm_rescue: |
+ begin
+ rescue
+ end
+loop_count: 30000000
diff --git a/benchmark/vm_send.yml b/benchmark/vm_send.yml
new file mode 100644
index 0000000000..f31bc7ac89
--- /dev/null
+++ b/benchmark/vm_send.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ def m
+ end
+ end
+
+ o = C.new
+ m = :m
+benchmark:
+ vm_send: |
+ o.__send__ :m
+ vm_send_var: |
+ o.__send__ m
+loop_count: 6000000
diff --git a/benchmark/vm_send_cfunc.yml b/benchmark/vm_send_cfunc.yml
new file mode 100644
index 0000000000..b114ac317d
--- /dev/null
+++ b/benchmark/vm_send_cfunc.yml
@@ -0,0 +1,3 @@
+benchmark:
+ vm_send_cfunc: self.class
+loop_count: 100000000
diff --git a/benchmark/vm_simplereturn.yml b/benchmark/vm_simplereturn.yml
new file mode 100644
index 0000000000..c9829cff0b
--- /dev/null
+++ b/benchmark/vm_simplereturn.yml
@@ -0,0 +1,7 @@
+prelude: |
+ def m
+ return 1
+ end
+benchmark:
+ vm_simplereturn: m
+loop_count: 30000000
diff --git a/benchmark/vm_string_literal.yml b/benchmark/vm_string_literal.yml
new file mode 100644
index 0000000000..64439c7980
--- /dev/null
+++ b/benchmark/vm_string_literal.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_string_literal: |
+ x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_aref_hi.yml b/benchmark/vm_struct_big_aref_hi.yml
new file mode 100644
index 0000000000..4cf78970cb
--- /dev/null
+++ b/benchmark/vm_struct_big_aref_hi.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_aref_hi: |
+ x.z # x[25]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_aref_lo.yml b/benchmark/vm_struct_big_aref_lo.yml
new file mode 100644
index 0000000000..c91af27fa5
--- /dev/null
+++ b/benchmark/vm_struct_big_aref_lo.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_aref_lo: |
+ x.k # x[10]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_aset.yml b/benchmark/vm_struct_big_aset.yml
new file mode 100644
index 0000000000..69550d14ea
--- /dev/null
+++ b/benchmark/vm_struct_big_aset.yml
@@ -0,0 +1,11 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_struct_big_aset: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+ i = 0
+ while i<6_000_000
+ i += 1
+ x.k = i # x[10] = i
+ end
+loop_count: 1
diff --git a/benchmark/vm_struct_big_href_hi.yml b/benchmark/vm_struct_big_href_hi.yml
new file mode 100644
index 0000000000..09b764dd13
--- /dev/null
+++ b/benchmark/vm_struct_big_href_hi.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_href_hi: |
+ x[:z]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_href_lo.yml b/benchmark/vm_struct_big_href_lo.yml
new file mode 100644
index 0000000000..d2f00b220f
--- /dev/null
+++ b/benchmark/vm_struct_big_href_lo.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_href_lo: |
+ x[:k]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_hset.yml b/benchmark/vm_struct_big_hset.yml
new file mode 100644
index 0000000000..fc45cbee9c
--- /dev/null
+++ b/benchmark/vm_struct_big_hset.yml
@@ -0,0 +1,11 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_struct_big_hset: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+ i = 0
+ while i<6_000_000
+ i += 1
+ x[:k] = i
+ end
+loop_count: 1
diff --git a/benchmark/vm_struct_small_aref.yml b/benchmark/vm_struct_small_aref.yml
new file mode 100644
index 0000000000..5a83251d1e
--- /dev/null
+++ b/benchmark/vm_struct_small_aref.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+benchmark:
+ vm_struct_small_aref: |
+ x.a
+loop_count: 6000000
diff --git a/benchmark/vm_struct_small_aset.yml b/benchmark/vm_struct_small_aset.yml
new file mode 100644
index 0000000000..74f435f126
--- /dev/null
+++ b/benchmark/vm_struct_small_aset.yml
@@ -0,0 +1,11 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_struct_small_aset: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+ i = 0
+ while i<6_000_000
+ i += 1
+ x.a = i
+ end
+loop_count: 1
diff --git a/benchmark/vm_struct_small_href.yml b/benchmark/vm_struct_small_href.yml
new file mode 100644
index 0000000000..6b7d7f39e7
--- /dev/null
+++ b/benchmark/vm_struct_small_href.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+benchmark:
+ vm_struct_small_href: |
+ x[:a]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_small_hset.yml b/benchmark/vm_struct_small_hset.yml
new file mode 100644
index 0000000000..5d43b150de
--- /dev/null
+++ b/benchmark/vm_struct_small_hset.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+benchmark:
+ vm_struct_small_hset: |
+ x[:a] = 1
+loop_count: 6000000
diff --git a/benchmark/vm_super.yml b/benchmark/vm_super.yml
new file mode 100644
index 0000000000..0d1e965c6e
--- /dev/null
+++ b/benchmark/vm_super.yml
@@ -0,0 +1,17 @@
+prelude: |
+ class C
+ def m
+ 1
+ end
+ end
+
+ class CC < C
+ def m
+ super()
+ end
+ end
+
+ obj = CC.new
+benchmark:
+ vm_super: obj.m
+loop_count: 6000000
diff --git a/benchmark/vm_swap.yml b/benchmark/vm_swap.yml
new file mode 100644
index 0000000000..e824a65e0a
--- /dev/null
+++ b/benchmark/vm_swap.yml
@@ -0,0 +1,7 @@
+prelude: |
+ a = 1
+ b = 2
+benchmark:
+ vm_swap: |
+ a, b = b, a
+loop_count: 30000000
diff --git a/benchmark/bm_vm_symbol_block_pass.rb b/benchmark/vm_symbol_block_pass.rb
index 1d433353e1..1d433353e1 100644
--- a/benchmark/bm_vm_symbol_block_pass.rb
+++ b/benchmark/vm_symbol_block_pass.rb
diff --git a/benchmark/vm_thread_alive_check.yml b/benchmark/vm_thread_alive_check.yml
new file mode 100644
index 0000000000..d21737d3e8
--- /dev/null
+++ b/benchmark/vm_thread_alive_check.yml
@@ -0,0 +1,8 @@
+benchmark:
+ vm_thread_alive_check: |
+ t = Thread.new{}
+ while t.alive?
+ Thread.pass
+ end
+loop_count: 50_000
+
diff --git a/benchmark/bm_vm_thread_close.rb b/benchmark/vm_thread_close.rb
index 3e9a265ce8..3e9a265ce8 100644
--- a/benchmark/bm_vm_thread_close.rb
+++ b/benchmark/vm_thread_close.rb
diff --git a/benchmark/bm_vm_thread_condvar1.rb b/benchmark/vm_thread_condvar1.rb
index cf5706b23e..cf5706b23e 100644
--- a/benchmark/bm_vm_thread_condvar1.rb
+++ b/benchmark/vm_thread_condvar1.rb
diff --git a/benchmark/bm_vm_thread_condvar2.rb b/benchmark/vm_thread_condvar2.rb
index 7c8dc19481..7c8dc19481 100644
--- a/benchmark/bm_vm_thread_condvar2.rb
+++ b/benchmark/vm_thread_condvar2.rb
diff --git a/benchmark/bm_vm_thread_create_join.rb b/benchmark/vm_thread_create_join.rb
index 393cd45df9..393cd45df9 100644
--- a/benchmark/bm_vm_thread_create_join.rb
+++ b/benchmark/vm_thread_create_join.rb
diff --git a/benchmark/bm_vm_thread_mutex1.rb b/benchmark/vm_thread_mutex1.rb
index 66e42c85e1..66e42c85e1 100644
--- a/benchmark/bm_vm_thread_mutex1.rb
+++ b/benchmark/vm_thread_mutex1.rb
diff --git a/benchmark/bm_vm_thread_mutex2.rb b/benchmark/vm_thread_mutex2.rb
index 6e6c804c31..6e6c804c31 100644
--- a/benchmark/bm_vm_thread_mutex2.rb
+++ b/benchmark/vm_thread_mutex2.rb
diff --git a/benchmark/bm_vm_thread_mutex3.rb b/benchmark/vm_thread_mutex3.rb
index c750dc542a..c750dc542a 100644
--- a/benchmark/bm_vm_thread_mutex3.rb
+++ b/benchmark/vm_thread_mutex3.rb
diff --git a/benchmark/vm_thread_pass.rb b/benchmark/vm_thread_pass.rb
new file mode 100644
index 0000000000..438bd08d45
--- /dev/null
+++ b/benchmark/vm_thread_pass.rb
@@ -0,0 +1,15 @@
+# Plenty Thread.pass
+# A performance may depend on GVL implementation.
+
+tmax = (ARGV.shift || 8).to_i
+lmax = 400_000 / tmax
+
+(1..tmax).map{
+ Thread.new{
+ lmax.times{
+ Thread.pass
+ }
+ }
+}.each{|t| t.join}
+
+
diff --git a/benchmark/vm_thread_pass_flood.rb b/benchmark/vm_thread_pass_flood.rb
new file mode 100644
index 0000000000..65df8e6154
--- /dev/null
+++ b/benchmark/vm_thread_pass_flood.rb
@@ -0,0 +1,10 @@
+# n.b. this is a good test for GVL when pinned to a single CPU
+
+5_000.times{
+ Thread.new{loop{Thread.pass}}
+}
+
+i = 0
+while i<10_000
+ i += 1
+end
diff --git a/benchmark/bm_vm_thread_pipe.rb b/benchmark/vm_thread_pipe.rb
index 112a621905..112a621905 100644
--- a/benchmark/bm_vm_thread_pipe.rb
+++ b/benchmark/vm_thread_pipe.rb
diff --git a/benchmark/vm_thread_queue.rb b/benchmark/vm_thread_queue.rb
new file mode 100644
index 0000000000..1dd3696a3c
--- /dev/null
+++ b/benchmark/vm_thread_queue.rb
@@ -0,0 +1,18 @@
+require 'thread'
+
+n = 10_000_000
+q = Thread::Queue.new
+consumer = Thread.new{
+ while q.pop
+ # consuming
+ end
+}
+
+producer = Thread.new{
+ n.times{
+ q.push true
+ }
+ q.push nil
+}
+
+consumer.join
diff --git a/benchmark/bm_vm_thread_sized_queue.rb b/benchmark/vm_thread_sized_queue.rb
index 7b9af5482b..7b9af5482b 100644
--- a/benchmark/bm_vm_thread_sized_queue.rb
+++ b/benchmark/vm_thread_sized_queue.rb
diff --git a/benchmark/bm_vm_thread_sized_queue2.rb b/benchmark/vm_thread_sized_queue2.rb
index de9f55e978..de9f55e978 100644
--- a/benchmark/bm_vm_thread_sized_queue2.rb
+++ b/benchmark/vm_thread_sized_queue2.rb
diff --git a/benchmark/bm_vm_thread_sized_queue3.rb b/benchmark/vm_thread_sized_queue3.rb
index ce5f1796d8..ce5f1796d8 100644
--- a/benchmark/bm_vm_thread_sized_queue3.rb
+++ b/benchmark/vm_thread_sized_queue3.rb
diff --git a/benchmark/bm_vm_thread_sized_queue4.rb b/benchmark/vm_thread_sized_queue4.rb
index a9b7d80ec0..a9b7d80ec0 100644
--- a/benchmark/bm_vm_thread_sized_queue4.rb
+++ b/benchmark/vm_thread_sized_queue4.rb
diff --git a/benchmark/vm_thread_sleep.yml b/benchmark/vm_thread_sleep.yml
new file mode 100644
index 0000000000..96901d8466
--- /dev/null
+++ b/benchmark/vm_thread_sleep.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_thread_sleep: |
+ Thread.new { sleep }
+loop_count: 10_000
diff --git a/benchmark/vm_unif1.yml b/benchmark/vm_unif1.yml
new file mode 100644
index 0000000000..04187bb0e2
--- /dev/null
+++ b/benchmark/vm_unif1.yml
@@ -0,0 +1,7 @@
+prelude: |
+ def m a, b
+ end
+benchmark:
+ vm_unif1: |
+ m 100, 200
+loop_count: 6000000
diff --git a/benchmark/vm_yield.yml b/benchmark/vm_yield.yml
new file mode 100644
index 0000000000..230be3d84f
--- /dev/null
+++ b/benchmark/vm_yield.yml
@@ -0,0 +1,13 @@
+# while loop cost is not removed due to benchmark_driver.gem's limitation
+benchmark:
+ vm_yield: |
+ def m
+ i = 0
+ while i<30_000_000
+ i += 1
+ yield
+ end
+ end
+
+ m{}
+loop_count: 1
diff --git a/benchmark/vm_zsuper.yml b/benchmark/vm_zsuper.yml
new file mode 100644
index 0000000000..bfb5837578
--- /dev/null
+++ b/benchmark/vm_zsuper.yml
@@ -0,0 +1,18 @@
+prelude: |
+ class C
+ def m a
+ 1
+ end
+ end
+
+ class CC < C
+ def m a
+ super
+ end
+ end
+
+ obj = CC.new
+benchmark:
+ vm_zsuper: |
+ obj.m 10
+loop_count: 6000000
diff --git a/benchmark/wc.input.base b/benchmark/wc.input.base
deleted file mode 100644
index 41143fbac0..0000000000
--- a/benchmark/wc.input.base
+++ /dev/null
@@ -1,25 +0,0 @@
-Subject: Re: Who was Izchak Miller?
-From: "Jane D. Anonymous" <nobody@yale.edu>
-Date: 1996/04/28
-Message-Id: <4lv7bc$oh@news.ycc.yale.edu>
-References: <317C405E.5DFA@panix.com> <4lk6vl$gde@ns.oar.net>
-To: 75176.2330@compuserve.com
-Content-Type: text/plain; charset=us-ascii
-Organization: Yale University
-X-Url: news:4lk6vl$gde@ns.oar.net
-Mime-Version: 1.0
-Newsgroups: rec.games.roguelike.nethack
-X-Mailer: Mozilla 1.1N (Macintosh; I; 68K)
-
-Hello there, Izchak Miller was my father. When I was younger I spent
-many a night, hunched over the keyboard with a cup of tea, playing
-nethack with him and my brother. my dad was a philosopher with a strong
-weakness for fantasy/sci fi. I remember when he started to get involved
-with the Nethack team- my brother's Dungeons and Dragons monster book
-found a regular place beside my dad's desk. it's nice to see him living
-on in the game he loved so much :-).
- Tamar Miller
-
-The following is a really long word of 5000 characters:
-
-wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
diff --git a/bignum.c b/bignum.c
index b650d83936..7c55366ecb 100644
--- a/bignum.c
+++ b/bignum.c
@@ -9,32 +9,42 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/thread.h"
-#include "ruby/util.h"
-#include "id.h"
+#include "ruby/internal/config.h"
+
+#include <ctype.h>
+#include <float.h>
+#include <math.h>
#ifdef HAVE_STRINGS_H
-#include <strings.h>
+# include <strings.h>
#endif
-#include <math.h>
-#include <float.h>
-#include <ctype.h>
+
#ifdef HAVE_IEEEFP_H
-#include <ieeefp.h>
+# include <ieeefp.h>
#endif
-#include "ruby_assert.h"
#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
-#define USE_GMP
-#include <gmp.h>
+# define USE_GMP
+# include <gmp.h>
#endif
+#include "id.h"
+#include "internal.h"
+#include "internal/bignum.h"
+#include "internal/complex.h"
+#include "internal/gc.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/sanitizers.h"
+#include "internal/util.h"
+#include "internal/variable.h"
+#include "internal/warnings.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+#include "ruby_assert.h"
+
#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
-#ifndef RUBY_INTEGER_UNIFICATION
-VALUE rb_cBignum;
-#endif
const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
#ifndef SIZEOF_BDIGIT_DBL
@@ -65,7 +75,6 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
#else
# define HOST_BIGENDIAN_P 0
#endif
-#define ALIGNOF(type) ((int)offsetof(struct { char f1; type f2; }, f2))
/* (!LSHIFTABLE(d, n) ? 0 : (n)) is same as n but suppress a warning, C4293, by Visual Studio. */
#define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
#define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
@@ -386,6 +395,7 @@ bdigitdbl2bary(BDIGIT *ds, size_t n, BDIGIT_DBL num)
static int
bary_cmp(const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
{
+ size_t i;
BARY_TRUNC(xds, xn);
BARY_TRUNC(yds, yn);
@@ -394,11 +404,12 @@ bary_cmp(const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
if (xn > yn)
return 1;
- while (xn-- && xds[xn] == yds[xn])
- ;
- if (xn == (size_t)-1)
+ for (i = 0; i < xn; i++)
+ if (xds[xn - i - 1] != yds[yn - i - 1])
+ break;
+ if (i == xn)
return 0;
- return xds[xn] < yds[xn] ? -1 : 1;
+ return xds[xn - i - 1] < yds[yn - i - 1] ? -1 : 1;
}
static BDIGIT
@@ -419,15 +430,16 @@ bary_small_lshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift)
static void
bary_small_rshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift, BDIGIT higher_bdigit)
{
+ size_t i;
BDIGIT_DBL num = 0;
assert(0 <= shift && shift < BITSPERDIG);
num = BIGUP(higher_bdigit);
- while (n--) {
- BDIGIT x = xds[n];
+ for (i = 0; i < n; i++) {
+ BDIGIT x = xds[n - i - 1];
num = (num | x) >> shift;
- zds[n] = BIGLO(num);
+ zds[n - i - 1] = BIGLO(num);
num = BIGUP(x);
}
}
@@ -446,8 +458,9 @@ bary_zero_p(const BDIGIT *xds, size_t xn)
static void
bary_neg(BDIGIT *ds, size_t n)
{
- while (n--)
- ds[n] = BIGLO(~ds[n]);
+ size_t i;
+ for (i = 0; i < n; i++)
+ ds[n - i - 1] = BIGLO(~ds[n - i - 1]);
}
static int
@@ -617,8 +630,12 @@ static int
bytes_2comp(unsigned char *buf, size_t len)
{
size_t i;
- for (i = 0; i < len; i++)
- buf[i] = ~buf[i];
+ for (i = 0; i < len; i++) {
+ signed char c = buf[i];
+ signed int d = ~c;
+ unsigned int e = d & 0xFF;
+ buf[i] = e;
+ }
for (i = 0; i < len; i++) {
buf[i]++;
if (buf[i] != 0)
@@ -668,7 +685,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
return ((1 < de - dp || CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
}
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
- if (wordsize == 2 && (uintptr_t)words % ALIGNOF(uint16_t) == 0) {
+ if (wordsize == 2 && (uintptr_t)words % RUBY_ALIGNOF(uint16_t) == 0) {
uint16_t u = (uint16_t)(d = dp[0]);
if (need_swap) u = swap16(u);
*((uint16_t *)words) = u;
@@ -676,7 +693,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
#endif
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
- if (wordsize == 4 && (uintptr_t)words % ALIGNOF(uint32_t) == 0) {
+ if (wordsize == 4 && (uintptr_t)words % RUBY_ALIGNOF(uint32_t) == 0) {
uint32_t u = (uint32_t)(d = dp[0]);
if (need_swap) u = swap32(u);
*((uint32_t *)words) = u;
@@ -684,7 +701,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
#endif
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
- if (wordsize == 8 && (uintptr_t)words % ALIGNOF(uint64_t) == 0) {
+ if (wordsize == 8 && (uintptr_t)words % RUBY_ALIGNOF(uint64_t) == 0) {
uint64_t u = (uint64_t)(d = dp[0]);
if (need_swap) u = swap64(u);
*((uint64_t *)words) = u;
@@ -699,7 +716,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
return (1 < de - dp || FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
}
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
- if (wordsize == 2 && (uintptr_t)words % ALIGNOF(uint16_t) == 0) {
+ if (wordsize == 2 && (uintptr_t)words % RUBY_ALIGNOF(uint16_t) == 0) {
uint16_t u = (uint16_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
if (need_swap) u = swap16(u);
*((uint16_t *)words) = u;
@@ -708,7 +725,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
#endif
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
- if (wordsize == 4 && (uintptr_t)words % ALIGNOF(uint32_t) == 0) {
+ if (wordsize == 4 && (uintptr_t)words % RUBY_ALIGNOF(uint32_t) == 0) {
uint32_t u = (uint32_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
if (need_swap) u = swap32(u);
*((uint32_t *)words) = u;
@@ -717,7 +734,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
#endif
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
- if (wordsize == 8 && (uintptr_t)words % ALIGNOF(uint64_t) == 0) {
+ if (wordsize == 8 && (uintptr_t)words % RUBY_ALIGNOF(uint64_t) == 0) {
uint64_t u = (uint64_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
if (need_swap) u = swap64(u);
*((uint64_t *)words) = u;
@@ -760,7 +777,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
#endif
if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
- wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words % ALIGNOF(BDIGIT) == 0) {
+ wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words % RUBY_ALIGNOF(BDIGIT) == 0) {
size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
size_t src_num_bdigits = de - dp;
size_t dst_num_bdigits = numwords * bdigits_per_word;
@@ -903,8 +920,6 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
if ((flags & INTEGER_PACK_2COMP) && (sign < 0 && numwords != 0)) {
- unsigned char *buf;
-
int word_num_partialbits;
size_t word_num_fullbytes;
@@ -1082,6 +1097,13 @@ integer_unpack_single_bdigit(BDIGIT u, size_t size, int flags, BDIGIT *dp)
return sign;
}
+#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
+#define reinterpret_cast(type, value) (type) \
+ __builtin_assume_aligned((value), sizeof(*(type)NULL));
+#else
+#define reinterpret_cast(type, value) (type)value
+#endif
+
static int
bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags, int nlp_bits)
{
@@ -1102,23 +1124,24 @@ bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, siz
return integer_unpack_single_bdigit(*(uint8_t *)buf, sizeof(uint8_t), flags, dp);
}
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
- if (wordsize == 2 && (uintptr_t)words % ALIGNOF(uint16_t) == 0) {
- uint16_t u = *(uint16_t *)buf;
+ if (wordsize == 2 && (uintptr_t)words % RUBY_ALIGNOF(uint16_t) == 0) {
+ uint16_t u = *reinterpret_cast(const uint16_t *, buf);
return integer_unpack_single_bdigit(need_swap ? swap16(u) : u, sizeof(uint16_t), flags, dp);
}
#endif
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
- if (wordsize == 4 && (uintptr_t)words % ALIGNOF(uint32_t) == 0) {
- uint32_t u = *(uint32_t *)buf;
+ if (wordsize == 4 && (uintptr_t)words % RUBY_ALIGNOF(uint32_t) == 0) {
+ uint32_t u = *reinterpret_cast(const uint32_t *, buf);
return integer_unpack_single_bdigit(need_swap ? swap32(u) : u, sizeof(uint32_t), flags, dp);
}
#endif
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
- if (wordsize == 8 && (uintptr_t)words % ALIGNOF(uint64_t) == 0) {
- uint64_t u = *(uint64_t *)buf;
+ if (wordsize == 8 && (uintptr_t)words % RUBY_ALIGNOF(uint64_t) == 0) {
+ uint64_t u = *reinterpret_cast(const uint64_t *, buf);
return integer_unpack_single_bdigit(need_swap ? swap64(u) : u, sizeof(uint64_t), flags, dp);
}
#endif
+#undef reinterpret_cast
}
#if !defined(WORDS_BIGENDIAN)
if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
@@ -1434,7 +1457,9 @@ bary_add_one(BDIGIT *ds, size_t n)
{
size_t i;
for (i = 0; i < n; i++) {
- ds[i] = BIGLO(ds[i]+1);
+ BDIGIT_DBL n = ds[i];
+ n += 1;
+ ds[i] = BIGLO(n);
if (ds[i] != 0)
return 0;
}
@@ -1502,15 +1527,16 @@ bigdivrem_mulsub(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
i = 0;
do {
- BDIGIT_DBL ee;
+ BDIGIT_DBL_SIGNED ee;
t2 += (BDIGIT_DBL)yds[i] * x;
ee = num - BIGLO(t2);
- num = (BDIGIT_DBL)zds[i] + ee;
+ num = (BDIGIT_DBL_SIGNED)zds[i] + ee;
if (ee) zds[i] = BIGLO(num);
num = BIGDN(num);
t2 = BIGDN(t2);
} while (++i < yn);
- num += zds[i] - t2; /* borrow from high digit; don't update */
+ num -= (BDIGIT_DBL_SIGNED)t2;
+ num += (BDIGIT_DBL_SIGNED)zds[yn]; /* borrow from high digit; don't update */
return num;
}
@@ -1980,7 +2006,7 @@ bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGI
}
/*
- * ref. http://en.wikipedia.org/wiki/Toom%E2%80%93Cook_multiplication
+ * ref. https://en.wikipedia.org/wiki/Toom%E2%80%93Cook_multiplication
*
* x(b) = x0 * b^0 + x1 * b^1 + x2 * b^2
* y(b) = y0 * b^0 + y1 * b^1 + y2 * b^2
@@ -2261,10 +2287,23 @@ rb_big_mul_toom3(VALUE x, VALUE y)
}
#ifdef USE_GMP
+static inline void
+bdigits_to_mpz(mpz_t mp, const BDIGIT *digits, size_t len)
+{
+ const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
+ mpz_import(mp, len, -1, sizeof(BDIGIT), 0, nails, digits);
+}
+
+static inline void
+bdigits_from_mpz(mpz_t mp, BDIGIT *digits, size_t *len)
+{
+ const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
+ mpz_export(digits, len, -1, sizeof(BDIGIT), 0, nails, mp);
+}
+
static void
bary_mul_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
{
- const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
mpz_t x, y, z;
size_t count;
@@ -2273,15 +2312,15 @@ bary_mul_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT
mpz_init(x);
mpz_init(y);
mpz_init(z);
- mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
+ bdigits_to_mpz(x, xds, xn);
if (xds == yds && xn == yn) {
mpz_mul(z, x, x);
}
else {
- mpz_import(y, yn, -1, sizeof(BDIGIT), 0, nails, yds);
+ bdigits_to_mpz(y, yds, yn);
mpz_mul(z, x, y);
}
- mpz_export(zds, &count, -1, sizeof(BDIGIT), 0, nails, z);
+ bdigits_from_mpz(z, zds, &count);
BDIGITS_ZERO(zds+count, zn-count);
mpz_clear(x);
mpz_clear(y);
@@ -2320,9 +2359,9 @@ bary_sparse_p(const BDIGIT *ds, size_t n)
{
long c = 0;
- if ( ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
- if (c <= 1 && ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
- if (c <= 1 && ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
+ if ( ds[2 * n / 5]) c++;
+ if (c <= 1 && ds[ n / 2]) c++;
+ if (c <= 1 && ds[3 * n / 5]) c++;
return (c <= 1) ? 1 : 0;
}
@@ -2430,12 +2469,7 @@ bary_mul_karatsuba_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn,
{
/* normal multiplication when x is small */
if (xn < KARATSUBA_MUL_DIGITS) {
- normal:
- if (xds == yds && xn == yn)
- bary_sq_fast(zds, zn, xds, xn);
- else
- bary_short_mul(zds, zn, xds, xn, yds, yn);
- return;
+ goto normal;
}
/* normal multiplication when x or y is a sparse bignum */
@@ -2453,6 +2487,15 @@ bary_mul_karatsuba_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn,
/* multiplication by karatsuba method */
bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
+ return;
+
+ normal:
+ if (xds == yds && xn == yn) {
+ bary_sq_fast(zds, zn, xds, xn);
+ }
+ else {
+ bary_short_mul(zds, zn, xds, xn, yds, yn);
+ }
}
static void
@@ -2556,6 +2599,7 @@ bigdivrem1(void *ptr)
return 0;
}
+/* async-signal-safe */
static void
rb_big_stop(void *ptr)
{
@@ -2578,10 +2622,9 @@ bigdivrem_single1(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT x_higher_bdi
size_t i;
BDIGIT_DBL t2;
t2 = x_higher_bdigit;
- i = xn;
- while (i--) {
- t2 = BIGUP(t2) + xds[i];
- qds[i] = (BDIGIT)(t2 / y);
+ for (i = 0; i < xn; i++) {
+ t2 = BIGUP(t2) + xds[xn - i - 1];
+ qds[xn - i - 1] = (BDIGIT)(t2 / y);
t2 %= y;
}
return (BDIGIT)t2;
@@ -2621,7 +2664,7 @@ bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn)
if (bds.zn > 10000 || bds.yn > 10000) {
retry:
bds.stop = Qfalse;
- rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds);
+ rb_nogvl(bigdivrem1, &bds, rb_big_stop, &bds, RB_NOGVL_UBF_ASYNC_SAFE);
if (bds.stop == Qtrue) {
/* execute trap handler, but exception was not raised. */
@@ -2732,7 +2775,6 @@ rb_big_divrem_normal(VALUE x, VALUE y)
static void
bary_divmod_gmp(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
{
- const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
mpz_t x, y, q, r;
size_t count;
@@ -2746,8 +2788,8 @@ bary_divmod_gmp(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xd
if (qds) mpz_init(q);
if (rds) mpz_init(r);
- mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
- mpz_import(y, yn, -1, sizeof(BDIGIT), 0, nails, yds);
+ bdigits_to_mpz(x, xds, xn);
+ bdigits_to_mpz(y, yds, yn);
if (!rds) {
mpz_fdiv_q(q, x, y);
@@ -2763,13 +2805,13 @@ bary_divmod_gmp(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xd
mpz_clear(y);
if (qds) {
- mpz_export(qds, &count, -1, sizeof(BDIGIT), 0, nails, q);
+ bdigits_from_mpz(q, qds, &count);
BDIGITS_ZERO(qds+count, qn-count);
mpz_clear(q);
}
if (rds) {
- mpz_export(rds, &count, -1, sizeof(BDIGIT), 0, nails, r);
+ bdigits_from_mpz(r, rds, &count);
BDIGITS_ZERO(rds+count, rn-count);
mpz_clear(r);
}
@@ -2868,29 +2910,8 @@ bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, s
}
-#define BIGNUM_DEBUG 0
-#if BIGNUM_DEBUG
-#define ON_DEBUG(x) do { x; } while (0)
-static void
-dump_bignum(VALUE x)
-{
- long i;
- printf("%c0x0", BIGNUM_SIGN(x) ? '+' : '-');
- for (i = BIGNUM_LEN(x); i--; ) {
- printf("_%0*"PRIxBDIGIT, SIZEOF_BDIGIT*2, BDIGITS(x)[i]);
- }
- printf(", len=%"PRIuSIZE, BIGNUM_LEN(x));
- puts("");
-}
-
-static VALUE
-rb_big_dump(VALUE x)
-{
- dump_bignum(x);
- return x;
-}
-#else
-#define ON_DEBUG(x)
+#ifndef BIGNUM_DEBUG
+# define BIGNUM_DEBUG (0+RUBY_DEBUG)
#endif
static int
@@ -2928,7 +2949,7 @@ rb_cmpint(VALUE val, VALUE a, VALUE b)
}
#define BIGNUM_SET_LEN(b,l) \
- ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
+ (BIGNUM_EMBED_P(b) ? \
(void)(RBASIC(b)->flags = \
(RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
@@ -2938,19 +2959,19 @@ static void
rb_big_realloc(VALUE big, size_t len)
{
BDIGIT *ds;
- if (RBASIC(big)->flags & BIGNUM_EMBED_FLAG) {
+ if (BIGNUM_EMBED_P(big)) {
if (BIGNUM_EMBED_LEN_MAX < len) {
ds = ALLOC_N(BDIGIT, len);
MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, BIGNUM_EMBED_LEN_MAX);
RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
RBIGNUM(big)->as.heap.digits = ds;
- RBASIC(big)->flags &= ~BIGNUM_EMBED_FLAG;
+ FL_UNSET_RAW(big, BIGNUM_EMBED_FLAG);
}
}
else {
if (len <= BIGNUM_EMBED_LEN_MAX) {
ds = RBIGNUM(big)->as.heap.digits;
- RBASIC(big)->flags |= BIGNUM_EMBED_FLAG;
+ FL_SET_RAW(big, BIGNUM_EMBED_FLAG);
BIGNUM_SET_LEN(big, len);
(void)VALGRIND_MAKE_MEM_UNDEFINED((void*)RBIGNUM(big)->as.ary, sizeof(RBIGNUM(big)->as.ary));
if (ds) {
@@ -2980,18 +3001,19 @@ static VALUE
bignew_1(VALUE klass, size_t len, int sign)
{
NEWOBJ_OF(big, struct RBignum, klass, T_BIGNUM | (RGENGC_WB_PROTECTED_BIGNUM ? FL_WB_PROTECTED : 0));
- BIGNUM_SET_SIGN(big, sign);
+ VALUE bigv = (VALUE)big;
+ BIGNUM_SET_SIGN(bigv, sign);
if (len <= BIGNUM_EMBED_LEN_MAX) {
- RBASIC(big)->flags |= BIGNUM_EMBED_FLAG;
- BIGNUM_SET_LEN(big, len);
- (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)RBIGNUM(big)->as.ary, sizeof(RBIGNUM(big)->as.ary));
+ FL_SET_RAW(bigv, BIGNUM_EMBED_FLAG);
+ BIGNUM_SET_LEN(bigv, len);
+ (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)big->as.ary, sizeof(big->as.ary));
}
else {
- RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
- RBIGNUM(big)->as.heap.len = len;
+ big->as.heap.digits = ALLOC_N(BDIGIT, len);
+ big->as.heap.len = len;
}
- OBJ_FREEZE(big);
- return (VALUE)big;
+ OBJ_FREEZE(bigv);
+ return bigv;
}
VALUE
@@ -3139,7 +3161,7 @@ rb_big_norm(VALUE x)
}
VALUE
-rb_uint2big(VALUE n)
+rb_uint2big(uintptr_t n)
{
long i;
VALUE big = bignew(bdigit_roomof(SIZEOF_VALUE), 1);
@@ -3161,7 +3183,7 @@ rb_uint2big(VALUE n)
}
VALUE
-rb_int2big(SIGNED_VALUE n)
+rb_int2big(intptr_t n)
{
long neg = 0;
VALUE u;
@@ -3182,14 +3204,14 @@ rb_int2big(SIGNED_VALUE n)
}
VALUE
-rb_uint2inum(VALUE n)
+rb_uint2inum(uintptr_t n)
{
if (POSFIXABLE(n)) return LONG2FIX(n);
return rb_uint2big(n);
}
VALUE
-rb_int2inum(SIGNED_VALUE n)
+rb_int2inum(intptr_t n)
{
if (FIXABLE(n)) return LONG2FIX(n);
return rb_int2big(n);
@@ -3368,7 +3390,7 @@ rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
size_t numbytes;
int nlz_bits_in_msbyte;
size_t numwords;
- size_t nlz_bits;
+ size_t nlz_bits = 0;
if (word_numbits == 0)
return (size_t)-1;
@@ -3570,7 +3592,7 @@ rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t
}
/*
- * Import an integer into a buffer.
+ * Import an integer from a buffer.
*
* [words] buffer to import.
* [numwords] the size of given buffer as number of words.
@@ -3725,12 +3747,12 @@ str2big_scan_digits(const char *s, const char *str, int base, int badcheck, size
return TRUE;
}
- if (badcheck && *str == '_') goto bad;
+ if (badcheck && *str == '_') return FALSE;
while ((c = *str++) != 0) {
if (c == '_') {
if (nondigit) {
- if (badcheck) goto bad;
+ if (badcheck) return FALSE;
break;
}
nondigit = (char) c;
@@ -3745,7 +3767,7 @@ str2big_scan_digits(const char *s, const char *str, int base, int badcheck, size
}
if (len > 0 && !--len) break;
}
- if (badcheck && nondigit) goto bad;
+ if (badcheck && nondigit) return FALSE;
if (badcheck && len) {
str--;
while (*str && ISSPACE(*str)) {
@@ -3753,7 +3775,6 @@ str2big_scan_digits(const char *s, const char *str, int base, int badcheck, size
if (len > 0 && !--len) break;
}
if (len && *str) {
- bad:
return FALSE;
}
}
@@ -3940,7 +3961,6 @@ str2big_gmp(
size_t num_bdigits,
int base)
{
- const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
char *buf, *p;
const char *q;
VALUE tmps;
@@ -3963,7 +3983,7 @@ str2big_gmp(
zn = num_bdigits;
z = bignew(zn, sign);
zds = BDIGITS(z);
- mpz_export(BDIGITS(z), &count, -1, sizeof(BDIGIT), 0, nails, mz);
+ bdigits_from_mpz(mz, BDIGITS(z), &count);
BDIGITS_ZERO(zds+count, zn-count);
mpz_clear(mz);
@@ -3974,6 +3994,8 @@ str2big_gmp(
}
#endif
+static VALUE rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base);
+
/*
* Parse +str+ as Ruby Integer, i.e., underscores, 0d and 0b prefixes.
*
@@ -4048,10 +4070,7 @@ rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
} while (0)
if (!str) {
- bad:
- if (endp) *endp = (char *)str;
- if (ndigits) *ndigits = num_digits;
- return z;
+ goto bad;
}
if (len && (flags & RB_INT_PARSE_SIGN)) {
while (ISSPACE(*str)) ADV(1);
@@ -4215,9 +4234,14 @@ rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
}
return bignorm(z);
+
+ bad:
+ if (endp) *endp = (char *)str;
+ if (ndigits) *ndigits = num_digits;
+ return z;
}
-VALUE
+static VALUE
rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base)
{
return rb_int_parse_cstr(str, len, endp, NULL, base,
@@ -4225,7 +4249,7 @@ rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base)
}
VALUE
-rb_str_to_inum(VALUE str, int base, int badcheck)
+rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception)
{
VALUE ret;
const char *s;
@@ -4237,13 +4261,22 @@ rb_str_to_inum(VALUE str, int base, int badcheck)
RSTRING_GETMEM(str, s, len);
ret = rb_cstr_parse_inum(s, len, (badcheck ? NULL : &end), base);
if (NIL_P(ret)) {
- if (badcheck) invalid_integer(str);
- ret = INT2FIX(0);
+ if (badcheck) {
+ if (!raise_exception) return Qnil;
+ invalid_integer(str);
+ }
+ ret = INT2FIX(0);
}
return ret;
}
VALUE
+rb_str_to_inum(VALUE str, int base, int badcheck)
+{
+ return rb_str_convert_to_inum(str, base, badcheck, TRUE);
+}
+
+VALUE
rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
{
int positive_p = 1;
@@ -4485,7 +4518,7 @@ rb_uint128t2big(uint128_t n)
return big;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_int128t2big(int128_t n)
{
int neg = 0;
@@ -4625,12 +4658,6 @@ static size_t base36_numdigits_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
static void
power_cache_init(void)
{
- int i, j;
- for (i = 0; i < 35; ++i) {
- for (j = 0; j < MAX_BASE36_POWER_TABLE_ENTRIES; ++j) {
- base36_power_cache[i][j] = Qnil;
- }
- }
}
static inline VALUE
@@ -4653,8 +4680,8 @@ power_cache_get_power(int base, int power_level, size_t *numdigits_ret)
if (MAX_BASE36_POWER_TABLE_ENTRIES <= power_level)
rb_bug("too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
- if (NIL_P(base36_power_cache[base - 2][power_level])) {
- VALUE power;
+ VALUE power = base36_power_cache[base - 2][power_level];
+ if (!power) {
size_t numdigits;
if (power_level == 0) {
int numdigits0;
@@ -4674,7 +4701,7 @@ power_cache_get_power(int base, int power_level, size_t *numdigits_ret)
}
if (numdigits_ret)
*numdigits_ret = base36_numdigits_cache[base - 2][power_level];
- return base36_power_cache[base - 2][power_level];
+ return power;
}
struct big2str_struct {
@@ -4983,7 +5010,6 @@ rb_big2str_generic(VALUE x, int base)
static VALUE
big2str_gmp(VALUE x, int base)
{
- const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
mpz_t mx;
size_t size;
VALUE str;
@@ -4991,7 +5017,7 @@ big2str_gmp(VALUE x, int base)
size_t xn = BIGNUM_LEN(x);
mpz_init(mx);
- mpz_import(mx, xn, -1, sizeof(BDIGIT), 0, nails, xds);
+ bdigits_to_mpz(mx, xds, xn);
size = mpz_sizeinbase(mx, base);
@@ -5069,6 +5095,9 @@ rb_big2str(VALUE x, int base)
static unsigned long
big2ulong(VALUE x, const char *type)
{
+#if SIZEOF_LONG > SIZEOF_BDIGIT
+ size_t i;
+#endif
size_t len = BIGNUM_LEN(x);
unsigned long num;
BDIGIT *ds;
@@ -5083,9 +5112,9 @@ big2ulong(VALUE x, const char *type)
num = (unsigned long)ds[0];
#else
num = 0;
- while (len--) {
+ for (i = 0; i < len; i++) {
num <<= BITSPERDIG;
- num += (unsigned long)ds[len]; /* overflow is already checked */
+ num += (unsigned long)ds[len - i - 1]; /* overflow is already checked */
}
#endif
return num;
@@ -5127,6 +5156,9 @@ rb_big2long(VALUE x)
static unsigned LONG_LONG
big2ull(VALUE x, const char *type)
{
+#if SIZEOF_LONG_LONG > SIZEOF_BDIGIT
+ size_t i;
+#endif
size_t len = BIGNUM_LEN(x);
unsigned LONG_LONG num;
BDIGIT *ds = BDIGITS(x);
@@ -5139,9 +5171,9 @@ big2ull(VALUE x, const char *type)
num = (unsigned LONG_LONG)ds[0];
#else
num = 0;
- while (len--) {
+ for (i = 0; i < len; i++) {
num = BIGUP(num);
- num += ds[len];
+ num += ds[len - i - 1];
}
#endif
return num;
@@ -5248,8 +5280,13 @@ big2dbl(VALUE x)
}
}
if (carry) {
- dl &= BDIGMAX << bits;
- dl = BIGLO(dl + ((BDIGIT)1 << bits));
+ BDIGIT mask = BDIGMAX;
+ BDIGIT bit = 1;
+ mask <<= bits;
+ bit <<= bits;
+ dl &= mask;
+ dl += bit;
+ dl = BIGLO(dl);
if (!dl) d += 1;
}
}
@@ -5333,6 +5370,15 @@ rb_integer_float_cmp(VALUE x, VALUE y)
return INT2FIX(-1);
}
+#if SIZEOF_LONG * CHAR_BIT >= DBL_MANT_DIG /* assume FLT_RADIX == 2 */
+COMPILER_WARNING_PUSH
+#if __has_warning("-Wimplicit-int-float-conversion")
+COMPILER_WARNING_IGNORED(-Wimplicit-int-float-conversion)
+#endif
+static const double LONG_MAX_as_double = LONG_MAX;
+COMPILER_WARNING_POP
+#endif
+
VALUE
rb_integer_float_eq(VALUE x, VALUE y)
{
@@ -5352,7 +5398,7 @@ rb_integer_float_eq(VALUE x, VALUE y)
return Qtrue;
#else
long xn, yn;
- if (yi < LONG_MIN || LONG_MAX < yi)
+ if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
return Qfalse;
xn = FIX2LONG(x);
yn = (long)yi;
@@ -5365,6 +5411,7 @@ rb_integer_float_eq(VALUE x, VALUE y)
return rb_big_eq(x, y);
}
+
VALUE
rb_big_cmp(VALUE x, VALUE y)
{
@@ -5464,8 +5511,8 @@ rb_big_le(VALUE x, VALUE y)
* big == obj -> true or false
*
* Returns <code>true</code> only if <i>obj</i> has the same value
- * as <i>big</i>. Contrast this with <code>Integer#eql?</code>, which
- * requires <i>obj</i> to be a <code>Integer</code>.
+ * as <i>big</i>. Contrast this with Integer#eql?, which requires
+ * <i>obj</i> to be an Integer.
*
* 68719476736 == 68719476736.0 #=> true
*/
@@ -5928,7 +5975,7 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
zds = BDIGITS(z);
dd = bigdivrem_single(zds, xds, xn, dd);
if (modp) {
- *modp = rb_uint2big((VALUE)dd);
+ *modp = rb_uint2big((uintptr_t)dd);
BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
}
if (divp) *divp = z;
@@ -6018,12 +6065,15 @@ rb_big_divide(VALUE x, VALUE y, ID op)
}
else if (RB_FLOAT_TYPE_P(y)) {
if (op == '/') {
- return DBL2NUM(rb_big2dbl(x) / RFLOAT_VALUE(y));
+ double dx = rb_big2dbl(x);
+ return rb_flo_div_flo(DBL2NUM(dx), y);
}
else {
+ VALUE v;
double dy = RFLOAT_VALUE(y);
if (dy == 0.0) rb_num_zerodiv();
- return rb_dbl2big(rb_big2dbl(x) / dy);
+ v = rb_big_divide(x, y, '/');
+ return rb_dbl2big(RFLOAT_VALUE(v));
}
}
else {
@@ -6043,7 +6093,7 @@ rb_big_div(VALUE x, VALUE y)
VALUE
rb_big_idiv(VALUE x, VALUE y)
{
- return rb_big_divide(x, y, rb_intern("div"));
+ return rb_big_divide(x, y, idDiv);
}
VALUE
@@ -6087,7 +6137,7 @@ rb_big_divmod(VALUE x, VALUE y)
y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
- return rb_num_coerce_bin(x, y, rb_intern("divmod"));
+ return rb_num_coerce_bin(x, y, idDivmod);
}
bigdivmod(x, y, &div, &mod);
@@ -6125,7 +6175,7 @@ big_fdiv(VALUE x, VALUE y, long ey)
#if SIZEOF_LONG > SIZEOF_INT
{
/* Visual C++ can't be here */
- if (l > INT_MAX) return INFINITY;
+ if (l > INT_MAX) return HUGE_VAL;
if (l < INT_MIN) return 0.0;
}
#endif
@@ -6156,6 +6206,7 @@ double
rb_big_fdiv_double(VALUE x, VALUE y)
{
double dx, dy;
+ VALUE v;
dx = big2dbl(x);
if (FIXNUM_P(y)) {
@@ -6164,9 +6215,7 @@ rb_big_fdiv_double(VALUE x, VALUE y)
return big_fdiv_int(x, rb_int2big(FIX2LONG(y)));
}
else if (RB_BIGNUM_TYPE_P(y)) {
- dy = rb_big2dbl(y);
- if (isinf(dx) || isinf(dy))
- return big_fdiv_int(x, y);
+ return big_fdiv_int(x, y);
}
else if (RB_FLOAT_TYPE_P(y)) {
dy = RFLOAT_VALUE(y);
@@ -6176,9 +6225,10 @@ rb_big_fdiv_double(VALUE x, VALUE y)
return big_fdiv_float(x, y);
}
else {
- return NUM2DBL(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
+ return NUM2DBL(rb_num_coerce_bin(x, y, idFdiv));
}
- return dx / dy;
+ v = rb_flo_div_flo(DBL2NUM(dx), DBL2NUM(dy));
+ return NUM2DBL(v);
}
VALUE
@@ -6195,10 +6245,12 @@ rb_big_pow(VALUE x, VALUE y)
again:
if (y == INT2FIX(0)) return INT2FIX(1);
+ if (y == INT2FIX(1)) return x;
if (RB_FLOAT_TYPE_P(y)) {
d = RFLOAT_VALUE(y);
- if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x)) && d != round(d))
- return rb_funcall(rb_complex_raw1(x), idPow, 1, y);
+ if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x))) {
+ return rb_dbl_complex_new_polar_pi(pow(-rb_big2dbl(x), d), d);
+ }
}
else if (RB_BIGNUM_TYPE_P(y)) {
y = bignorm(y);
@@ -6210,8 +6262,13 @@ rb_big_pow(VALUE x, VALUE y)
else if (FIXNUM_P(y)) {
yy = FIX2LONG(y);
- if (yy < 0)
- return rb_funcall(rb_rational_raw1(x), idPow, 1, y);
+ if (yy < 0) {
+ x = rb_big_pow(x, LONG2NUM(-yy));
+ if (RB_INTEGER_TYPE_P(x))
+ return rb_rational_raw(INT2FIX(1), x);
+ else
+ return DBL2NUM(1.0 / NUM2DBL(x));
+ }
else {
VALUE z = 0;
SIGNED_VALUE mask;
@@ -6631,7 +6688,6 @@ rb_big_aref(VALUE x, VALUE y)
return INT2FIX(0);
bigtrunc(y);
if (BIGSIZE(y) > sizeof(size_t)) {
- out_of_range:
return BIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
}
#if SIZEOF_SIZE_T <= SIZEOF_LONG
@@ -6649,7 +6705,8 @@ rb_big_aref(VALUE x, VALUE y)
s2 = shift%BITSPERDIG;
bit = (BDIGIT)1 << s2;
- if (s1 >= BIGNUM_LEN(x)) goto out_of_range;
+ if (s1 >= BIGNUM_LEN(x))
+ return BIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
xds = BDIGITS(x);
if (BIGNUM_POSITIVE_P(x))
@@ -6830,8 +6887,17 @@ estimate_initial_sqrt(VALUE *xp, const size_t xn, const BDIGIT *nds, size_t len)
rshift /= 2;
rshift += (2-(len&1))*BITSPERDIG/2;
if (rshift >= 0) {
- d <<= rshift;
+ if (nlz((BDIGIT)d) + rshift >= BITSPERDIG) {
+ /* (d << rshift) does cause overflow.
+ * example: Integer.sqrt(0xffff_ffff_ffff_ffff ** 2)
+ */
+ d = ~(BDIGIT_DBL)0;
+ }
+ else {
+ d <<= rshift;
+ }
}
+ BDIGITS_ZERO(xds, xn-2);
bdigitdbl2bary(&xds[xn-2], 2, d);
if (!lowbits) return NULL; /* special case, exact result */
@@ -6878,6 +6944,215 @@ rb_big_isqrt(VALUE n)
return x;
}
+#ifdef USE_GMP
+static void
+bary_powm_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, const BDIGIT *mds, size_t mn)
+{
+ mpz_t z, x, y, m;
+ size_t count;
+ mpz_init(x);
+ mpz_init(y);
+ mpz_init(m);
+ mpz_init(z);
+ bdigits_to_mpz(x, xds, xn);
+ bdigits_to_mpz(y, yds, yn);
+ bdigits_to_mpz(m, mds, mn);
+ mpz_powm(z, x, y, m);
+ bdigits_from_mpz(z, zds, &count);
+ BDIGITS_ZERO(zds+count, zn-count);
+ mpz_clear(x);
+ mpz_clear(y);
+ mpz_clear(m);
+ mpz_clear(z);
+}
+#endif
+
+static VALUE
+int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
+{
+#ifdef USE_GMP
+ VALUE z;
+ size_t xn, yn, mn, zn;
+
+ if (FIXNUM_P(x)) {
+ x = rb_int2big(FIX2LONG(x));
+ }
+ if (FIXNUM_P(y)) {
+ y = rb_int2big(FIX2LONG(y));
+ }
+ assert(RB_BIGNUM_TYPE_P(m));
+ xn = BIGNUM_LEN(x);
+ yn = BIGNUM_LEN(y);
+ mn = BIGNUM_LEN(m);
+ zn = mn;
+ z = bignew(zn, 1);
+ bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
+ if (nega_flg & BIGNUM_POSITIVE_P(z)) {
+ z = rb_big_minus(z, m);
+ }
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+ RB_GC_GUARD(m);
+ return rb_big_norm(z);
+#else
+ VALUE tmp = LONG2FIX(1L);
+ long yy;
+
+ for (/*NOP*/; ! FIXNUM_P(y); y = rb_big_rshift(y, LONG2FIX(1L))) {
+ if (RTEST(rb_int_odd_p(y))) {
+ tmp = rb_int_mul(tmp, x);
+ tmp = rb_int_modulo(tmp, m);
+ }
+ x = rb_int_mul(x, x);
+ x = rb_int_modulo(x, m);
+ }
+ for (yy = FIX2LONG(y); yy; yy >>= 1L) {
+ if (yy & 1L) {
+ tmp = rb_int_mul(tmp, x);
+ tmp = rb_int_modulo(tmp, m);
+ }
+ x = rb_int_mul(x, x);
+ x = rb_int_modulo(x, m);
+ }
+
+ if (nega_flg && rb_int_positive_p(tmp)) {
+ tmp = rb_int_minus(tmp, m);
+ }
+ return tmp;
+#endif
+}
+
+/*
+ * Integer#pow
+ */
+
+static VALUE
+int_pow_tmp1(VALUE x, VALUE y, long mm, int nega_flg)
+{
+ long xx = FIX2LONG(x);
+ long tmp = 1L;
+ long yy;
+
+ for (/*NOP*/; ! FIXNUM_P(y); y = rb_big_rshift(y, LONG2FIX(1L))) {
+ if (RTEST(rb_int_odd_p(y))) {
+ tmp = (tmp * xx) % mm;
+ }
+ xx = (xx * xx) % mm;
+ }
+ for (yy = FIX2LONG(y); yy; yy >>= 1L) {
+ if (yy & 1L) {
+ tmp = (tmp * xx) % mm;
+ }
+ xx = (xx * xx) % mm;
+ }
+
+ if (nega_flg && tmp) {
+ tmp -= mm;
+ }
+ return LONG2FIX(tmp);
+}
+
+static VALUE
+int_pow_tmp2(VALUE x, VALUE y, long mm, int nega_flg)
+{
+ long tmp = 1L;
+ long yy;
+#ifdef DLONG
+ const DLONG m = mm;
+ long tmp2 = tmp;
+ long xx = FIX2LONG(x);
+# define MUL_MODULO(a, b, c) (long)(((DLONG)(a) * (DLONG)(b)) % (c))
+#else
+ const VALUE m = LONG2FIX(mm);
+ VALUE tmp2 = LONG2FIX(tmp);
+ VALUE xx = x;
+# define MUL_MODULO(a, b, c) rb_int_modulo(rb_fix_mul_fix((a), (b)), (c))
+#endif
+
+ for (/*NOP*/; ! FIXNUM_P(y); y = rb_big_rshift(y, LONG2FIX(1L))) {
+ if (RTEST(rb_int_odd_p(y))) {
+ tmp2 = MUL_MODULO(tmp2, xx, m);
+ }
+ xx = MUL_MODULO(xx, xx, m);
+ }
+ for (yy = FIX2LONG(y); yy; yy >>= 1L) {
+ if (yy & 1L) {
+ tmp2 = MUL_MODULO(tmp2, xx, m);
+ }
+ xx = MUL_MODULO(xx, xx, m);
+ }
+
+#ifdef DLONG
+ tmp = tmp2;
+#else
+ tmp = FIX2LONG(tmp2);
+#endif
+ if (nega_flg && tmp) {
+ tmp -= mm;
+ }
+ return LONG2FIX(tmp);
+}
+
+/*
+ * Document-method: Integer#pow
+ * call-seq:
+ * integer.pow(numeric) -> numeric
+ * integer.pow(integer, integer) -> integer
+ *
+ * Returns (modular) exponentiation as:
+ *
+ * a.pow(b) #=> same as a**b
+ * a.pow(b, m) #=> same as (a**b) % m, but avoids huge temporary values
+ */
+VALUE
+rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
+{
+ rb_check_arity(argc, 1, 2);
+
+ if (argc == 1) {
+ return rb_int_pow(num, argv[0]);
+ }
+ else {
+ VALUE const a = num;
+ VALUE const b = argv[0];
+ VALUE m = argv[1];
+ int nega_flg = 0;
+ if ( ! RB_INTEGER_TYPE_P(b)) {
+ rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless a 1st argument is integer");
+ }
+ if (rb_int_negative_p(b)) {
+ rb_raise(rb_eRangeError, "Integer#pow() 1st argument cannot be negative when 2nd argument specified");
+ }
+ if (!RB_INTEGER_TYPE_P(m)) {
+ rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless all arguments are integers");
+ }
+
+ if (rb_int_negative_p(m)) {
+ m = rb_int_uminus(m);
+ nega_flg = 1;
+ }
+
+ if (FIXNUM_P(m)) {
+ long const half_val = (long)HALF_LONG_MSB;
+ long const mm = FIX2LONG(m);
+ if (!mm) rb_num_zerodiv();
+ if (mm == 1) return INT2FIX(0);
+ if (mm <= half_val) {
+ return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg);
+ }
+ else {
+ return int_pow_tmp2(rb_int_modulo(a, m), b, mm, nega_flg);
+ }
+ }
+ else {
+ if (rb_bigzero_p(m)) rb_num_zerodiv();
+ if (bignorm(m) == INT2FIX(1)) return INT2FIX(0);
+ return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
+ }
+ }
+ UNREACHABLE_RETURN(Qnil);
+}
+
/*
* Bignum objects hold integers outside the range of
* Fixnum. Bignum objects are created
@@ -6899,9 +7174,7 @@ rb_big_isqrt(VALUE n)
void
Init_Bignum(void)
{
-#ifndef RUBY_INTEGER_UNIFICATION
- rb_cBignum = rb_cInteger;
-#endif
+ /* An obsolete class, use Integer */
rb_define_const(rb_cObject, "Bignum", rb_cInteger);
rb_deprecate_constant(rb_cObject, "Bignum");
diff --git a/bin/bundle b/bin/bundle
index cf03a523ab..1a0b06b005 100755
--- a/bin/bundle
+++ b/bin/bundle
@@ -1,31 +1,27 @@
#!/usr/bin/env ruby
-# frozen_string_literal: true
+#
+# This file was generated by RubyGems.
+#
+# The application 'bundler' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
-# Exit cleanly from an early interrupt
-Signal.trap("INT") do
- Bundler.ui.debug("\n#{caller.join("\n")}") if defined?(Bundler)
- exit 1
-end
-
-require "bundler"
-# Check if an older version of bundler is installed
-$LOAD_PATH.each do |path|
- next unless path =~ %r{/bundler-0\.(\d+)} && $1.to_i < 9
- err = String.new
- err << "Looks like you have a version of bundler that's older than 0.9.\n"
- err << "Please remove your old versions.\n"
- err << "An easy way to do this is by running `gem cleanup bundler`."
- abort(err)
-end
+require 'rubygems'
-require "bundler/friendly_errors"
-Bundler.with_friendly_errors do
- require "bundler/cli"
+version = ">= 0.a"
- # Allow any command to use --help flag to show help for that command
- help_flags = %w(--help -h)
- help_flag_used = ARGV.any? {|a| help_flags.include? a }
- args = help_flag_used ? Bundler::CLI.reformatted_help_args(ARGV) : ARGV
+str = ARGV.first
+if str
+ str = str.b[/\A_(.*)_\z/, 1]
+ if str and Gem::Version.correct?(str)
+ version = str
+ ARGV.shift
+ end
+end
- Bundler::CLI.start(args, :debug => true)
+if Gem.respond_to?(:activate_bin_path)
+load Gem.activate_bin_path('bundler', 'bundle', version)
+else
+gem "bundler", version
+load Gem.bin_path("bundler", "bundle", version)
end
diff --git a/bin/bundler b/bin/bundler
index d9131fe834..e15eb39ed7 100755
--- a/bin/bundler
+++ b/bin/bundler
@@ -1,4 +1,27 @@
#!/usr/bin/env ruby
-# frozen_string_literal: true
+#
+# This file was generated by RubyGems.
+#
+# The application 'bundler' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
-load File.expand_path("../bundle", __FILE__)
+require 'rubygems'
+
+version = ">= 0.a"
+
+str = ARGV.first
+if str
+ str = str.b[/\A_(.*)_\z/, 1]
+ if str and Gem::Version.correct?(str)
+ version = str
+ ARGV.shift
+ end
+end
+
+if Gem.respond_to?(:activate_bin_path)
+load Gem.activate_bin_path('bundler', 'bundler', version)
+else
+gem "bundler", version
+load Gem.bin_path("bundler", "bundler", version)
+end
diff --git a/bin/erb b/bin/erb
index 6a88c3b26a..89d74fc525 100755
--- a/bin/erb
+++ b/bin/erb
@@ -1,171 +1,27 @@
#!/usr/bin/env ruby
-# Tiny eRuby --- ERB2
-# Copyright (c) 1999-2000,2002 Masatoshi SEKI
-# You can redistribute it and/or modify it under the same terms as Ruby.
-
-require 'erb'
-
-class ERB
- module Main
- def ARGV.switch
- return nil if self.empty?
- arg = self.shift
- return nil if arg == '--'
- case arg
- when /\A-(.)(.*)/
- if $1 == '-'
- arg, @maybe_arg = arg.split(/=/, 2)
- return arg
- end
- raise 'unknown switch "-"' if $2[0] == ?- and $1 != 'T'
- if $2.size > 0
- self.unshift "-#{$2}"
- @maybe_arg = $2
- else
- @maybe_arg = nil
- end
- "-#{$1}"
- when /\A(\w+)=/
- arg
- else
- self.unshift arg
- nil
- end
- end
-
- def ARGV.req_arg
- (@maybe_arg || self.shift || raise('missing argument')).tap {
- @maybe_arg = nil
- }
- end
-
- def trim_mode_opt(trim_mode, disable_percent)
- return trim_mode if disable_percent
- case trim_mode
- when 0
- return '%'
- when 1
- return '%>'
- when 2
- return '%<>'
- when '-'
- return '%-'
- end
- end
- module_function :trim_mode_opt
-
- def run(factory=ERB)
- trim_mode = 0
- disable_percent = false
- variables = {}
- begin
- while switch = ARGV.switch
- case switch
- when '-x' # ruby source
- output = true
- when '-n' # line number
- number = true
- when '-v' # verbose
- $VERBOSE = true
- when '--version' # version
- STDERR.puts factory.version
- exit
- when '-d', '--debug' # debug
- $DEBUG = true
- when '-r' # require
- require ARGV.req_arg
- when '-S' # security level
- arg = ARGV.req_arg
- raise "invalid safe_level #{arg.dump}" unless arg =~ /\A[0-1]\z/
- safe_level = arg.to_i
- when '-T' # trim mode
- arg = ARGV.req_arg
- if arg == '-'
- trim_mode = arg
- next
- end
- raise "invalid trim mode #{arg.dump}" unless arg =~ /\A[0-2]\z/
- trim_mode = arg.to_i
- when '-E', '--encoding'
- arg = ARGV.req_arg
- set_encoding(*arg.split(/:/, 2))
- when '-U'
- set_encoding(Encoding::UTF_8, Encoding::UTF_8)
- when '-P'
- disable_percent = true
- when '--help'
- raise "print this help"
- when /\A-/
- raise "unknown switch #{switch.dump}"
- else
- var, val = *switch.split('=', 2)
- (variables ||= {})[var] = val
- end
- end
- rescue # usage
- STDERR.puts $!.to_s
- STDERR.puts File.basename($0) +
- " [switches] [var=value...] [inputfile]"
- STDERR.puts <<EOU
- -x print ruby script
- -n print ruby script with line number
- -v enable verbose mode
- -d set $DEBUG to true
- -r library load a library
- -S safe_level set $SAFE (0..1)
- -E ex[:in] set default external/internal encodings
- -U set default encoding to UTF-8.
- -T trim_mode specify trim_mode (0..2, -)
- -P ignore lines which start with "%"
- var=value set variable
-EOU
- exit 1
- end
-
- $<.set_encoding(Encoding::ASCII_8BIT, nil)
- src = $<.read
- filename = $FILENAME
- exit 2 unless src
- trim = trim_mode_opt(trim_mode, disable_percent)
- erb = factory.new(src.untaint, safe_level, trim)
- erb.filename = filename
- if output
- if number
- erb.src.each_line.with_index do |line, l|
- puts "%3d %s"%[l+1, line]
- end
- else
- puts erb.src
- end
- else
- bind = TOPLEVEL_BINDING.taint
- if variables
- enc = erb.encoding
- for var, val in variables do
- val = val.encode(enc) if val
- bind.local_variable_set(var, val)
- end
- end
- erb.run(bind)
- end
- end
- module_function :run
-
- def set_encoding(extern, intern = nil)
- verbose, $VERBOSE = $VERBOSE, nil
- Encoding.default_external = extern unless extern.nil? || extern == ""
- Encoding.default_internal = intern unless intern.nil? || intern == ""
- [$stdin, $stdout, $stderr].each do |io|
- io.set_encoding(extern, intern)
- end
- ensure
- $VERBOSE = verbose
- end
- module_function :set_encoding
- class << self; private :set_encoding; end
+#
+# This file was generated by RubyGems.
+#
+# The application 'erb' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0.a"
+
+str = ARGV.first
+if str
+ str = str.b[/\A_(.*)_\z/, 1]
+ if str and Gem::Version.correct?(str)
+ version = str
+ ARGV.shift
end
end
-if __FILE__ == $0
- ERB::Main.run
+if Gem.respond_to?(:activate_bin_path)
+load Gem.activate_bin_path('erb', 'erb', version)
+else
+gem "erb", version
+load Gem.bin_path("erb", "erb", version)
end
diff --git a/bin/irb b/bin/irb
index c64ee85fbd..ae6d358c9d 100755
--- a/bin/irb
+++ b/bin/irb
@@ -1,11 +1,27 @@
#!/usr/bin/env ruby
#
-# irb.rb - interactive ruby
-# $Release Version: 0.9.6 $
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+# This file was generated by RubyGems.
#
+# The application 'irb' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0.a"
-require "irb"
+str = ARGV.first
+if str
+ str = str.b[/\A_(.*)_\z/, 1]
+ if str and Gem::Version.correct?(str)
+ version = str
+ ARGV.shift
+ end
+end
-IRB.start(__FILE__)
+if Gem.respond_to?(:activate_bin_path)
+load Gem.activate_bin_path('irb', 'irb', version)
+else
+gem "irb", version
+load Gem.bin_path("irb", "irb", version)
+end
diff --git a/bin/racc b/bin/racc
new file mode 100755
index 0000000000..3ddac532b4
--- /dev/null
+++ b/bin/racc
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'racc' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0.a"
+
+if ARGV.first
+ str = ARGV.first
+ str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+ if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+ version = $1
+ ARGV.shift
+ end
+end
+
+if Gem.respond_to?(:activate_bin_path)
+load Gem.activate_bin_path('racc', 'racc', version)
+else
+gem "racc", version
+load Gem.bin_path("racc", "racc", version)
+end
diff --git a/bin/rdoc b/bin/rdoc
index aaa23292df..8fa948cddb 100755
--- a/bin/rdoc
+++ b/bin/rdoc
@@ -1,44 +1,27 @@
#!/usr/bin/env ruby
#
-# RDoc: Documentation tool for source code
-# (see lib/rdoc/rdoc.rb for more information)
+# This file was generated by RubyGems.
+#
+# The application 'rdoc' is installed as part of a gem, and
+# this file is here to facilitate running it.
#
-# Copyright (c) 2003 Dave Thomas
-# Released under the same terms as Ruby
-begin
- gem 'rdoc'
-rescue NameError => e # --disable-gems
- raise unless e.name == :gem
-rescue Gem::LoadError
-end
+require 'rubygems'
-require 'rdoc/rdoc'
+version = ">= 0.a"
-begin
- r = RDoc::RDoc.new
- r.document ARGV
-rescue Errno::ENOSPC
- $stderr.puts 'Ran out of space creating documentation'
- $stderr.puts
- $stderr.puts 'Please free up some space and try again'
-rescue SystemExit
- raise
-rescue Exception => e
- if $DEBUG_RDOC then
- $stderr.puts e.message
- $stderr.puts "#{e.backtrace.join "\n\t"}"
- $stderr.puts
- elsif Interrupt === e then
- $stderr.puts
- $stderr.puts 'Interrupted'
- else
- $stderr.puts "uh-oh! RDoc had a problem:"
- $stderr.puts e.message
- $stderr.puts
- $stderr.puts "run with --debug for full backtrace"
+str = ARGV.first
+if str
+ str = str.b[/\A_(.*)_\z/, 1]
+ if str and Gem::Version.correct?(str)
+ version = str
+ ARGV.shift
end
-
- exit 1
end
+if Gem.respond_to?(:activate_bin_path)
+load Gem.activate_bin_path('rdoc', 'rdoc', version)
+else
+gem "rdoc", version
+load Gem.bin_path("rdoc", "rdoc", version)
+end
diff --git a/bin/ri b/bin/ri
index 7fbed0c099..0cc2f73bb6 100755
--- a/bin/ri
+++ b/bin/ri
@@ -1,12 +1,27 @@
#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'rdoc' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
-begin
- gem 'rdoc'
-rescue NameError => e # --disable-gems
- raise unless e.name == :gem
-rescue Gem::LoadError
-end
+require 'rubygems'
+
+version = ">= 0.a"
-require 'rdoc/ri/driver'
+str = ARGV.first
+if str
+ str = str.b[/\A_(.*)_\z/, 1]
+ if str and Gem::Version.correct?(str)
+ version = str
+ ARGV.shift
+ end
+end
-RDoc::RI::Driver.run ARGV
+if Gem.respond_to?(:activate_bin_path)
+load Gem.activate_bin_path('rdoc', 'ri', version)
+else
+gem "rdoc", version
+load Gem.bin_path("rdoc", "ri", version)
+end
diff --git a/bootstraptest/pending.rb b/bootstraptest/pending.rb
index 744c0adac1..2c4b85a419 100644
--- a/bootstraptest/pending.rb
+++ b/bootstraptest/pending.rb
@@ -1,19 +1,3 @@
-assert_equal 'A', %q{
- class A
- @@a = 'A'
- def a=(x)
- @@a = x
- end
- def a
- @@a
- end
- end
-
- B = A.dup
- B.new.a = 'B'
- A.new.a
-}, '[ruby-core:17019]'
-
assert_equal 'ok', %q{
def m
lambda{
@@ -31,9 +15,7 @@ assert_equal 'ok', %q{
end
}
-assert_normal_exit %q{
- r = Range.allocate
- def r.<=>(o) true end
- r.instance_eval { initialize r, r }
- r.inspect
+# This randomly fails on mswin.
+assert_equal %q{[]}, %q{
+ Thread.new{sleep}.backtrace
}
diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb
index a2b6fadaf4..2cd91ffd07 100755
--- a/bootstraptest/runner.rb
+++ b/bootstraptest/runner.rb
@@ -1,4 +1,4 @@
-"exec" "${RUBY-ruby}" "-x" "$0" "$@" || true # -*- mode: ruby; coding: utf-8 -*-
+"exec" "${RUBY-ruby}" "-x" "$0" "$@" || true # -*- Ruby -*-
#!./ruby
# $Id$
@@ -6,6 +6,7 @@
# Never use optparse in this file.
# Never use test/unit in this file.
# Never use Ruby extensions in this file.
+# Maintain Ruby 1.8 compatibility for now
begin
require 'fileutils'
@@ -139,7 +140,7 @@ End
# dircolors-like style
colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(/(\w+)=([^:\n]*)/)] : {}
begin
- File.read(File.join(__dir__, "../test/colors")).scan(/(\w+)=([^:\n]*)/) do |n, c|
+ File.read(File.join(__dir__, "../tool/colors")).scan(/(\w+)=([^:\n]*)/) do |n, c|
colors[n] ||= c
end
rescue
@@ -170,8 +171,8 @@ End
end
def erase(e = true)
- if e and @columns > 0 and !@verbose
- "\r#{" "*@columns}\r"
+ if e and @columns > 0 and @tty and !@verbose
+ "\e[1K\r"
else
""
end
@@ -207,6 +208,9 @@ def exec_test(pathes)
$stderr.puts unless @quiet and @tty and @error == error
end
$stderr.print(erase) if @quiet
+ @errbuf.each do |msg|
+ $stderr.puts msg
+ end
if @error == 0
if @count == 0
$stderr.puts "No tests, no problem"
@@ -215,9 +219,6 @@ def exec_test(pathes)
end
exit true
else
- @errbuf.each do |msg|
- $stderr.puts msg
- end
$stderr.puts "#{@failed}FAIL#{@reset} #{@error}/#{@count} tests failed"
exit false
end
@@ -243,7 +244,7 @@ def show_progress(message = '')
else
$stderr.print "#{@failed}F"
$stderr.printf(" %.3f", t) if @verbose
- $stderr.print "#{@reset}"
+ $stderr.print @reset
$stderr.puts if @verbose
error faildesc, message
unless errout.empty?
@@ -254,23 +255,34 @@ def show_progress(message = '')
end
end
rescue Interrupt
- raise Interrupt
+ $stderr.puts "\##{@count} #{@location}"
+ raise
rescue Exception => err
$stderr.print 'E'
$stderr.puts if @verbose
error err.message, message
+ensure
+ begin
+ check_coredump
+ rescue CoreDumpError => err
+ $stderr.print 'E'
+ $stderr.puts if @verbose
+ error err.message, message
+ end
end
-# NativeClient is special. The binary is cross-compiled. But runs on the build environment.
-# So RUBY_PLATFORM in this process is not useful to detect it.
-def nacl?
- @ruby and File.basename(@ruby.split(/\s/).first)['sel_ldr']
+def show_limit(testsrc, opt = '', **argh)
+ result = get_result_string(testsrc, opt, **argh)
+ if @tty and @verbose
+ $stderr.puts ".{#@reset}\n#{erase}#{result}"
+ else
+ @errbuf.push result
+ end
end
def assert_check(testsrc, message = '', opt = '', **argh)
show_progress(message) {
result = get_result_string(testsrc, opt, **argh)
- check_coredump
yield(result)
}
end
@@ -371,6 +383,9 @@ def assert_normal_exit(testsrc, *rest, timeout: nil, **opt)
end
def assert_finish(timeout_seconds, testsrc, message = '')
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
+ timeout_seconds *= 3
+ end
newtest
show_progress(message) {
faildesc = nil
@@ -379,12 +394,24 @@ def assert_finish(timeout_seconds, testsrc, message = '')
pid = io.pid
waited = false
tlimit = Time.now + timeout_seconds
- while Time.now < tlimit
+ diff = timeout_seconds
+ while diff > 0
if Process.waitpid pid, Process::WNOHANG
waited = true
break
end
- sleep 0.1
+ if io.respond_to?(:read_nonblock)
+ if IO.select([io], nil, nil, diff)
+ begin
+ io.read_nonblock(1024)
+ rescue Errno::EAGAIN, IO::WaitReadable, EOFError
+ break
+ end while true
+ end
+ else
+ sleep 0.1
+ end
+ diff = tlimit - Time.now
end
if !waited
Process.kill(:KILL, pid)
@@ -433,7 +460,6 @@ def get_result_string(src, opt = '', **argh)
`#{@ruby} -W0 #{opt} #{filename}`
ensure
raise Interrupt if $? and $?.signaled? && $?.termsig == Signal.list["INT"]
- raise CoreDumpError, "core dumped" if $? and $?.coredump?
end
else
eval(src).to_s
@@ -493,7 +519,21 @@ def in_temporary_working_directory(dir)
end
def cleanup_coredump
- FileUtils.rm_f 'core'
+ if File.file?('core')
+ require 'time'
+ Dir.glob('/tmp/bootstraptest-core.*').each do |f|
+ if Time.now - File.mtime(f) > 7 * 24 * 60 * 60 # 7 days
+ warn "Deleting an old core file: #{f}"
+ FileUtils.rm(f)
+ end
+ end
+ core_path = "/tmp/bootstraptest-core.#{Time.now.utc.iso8601}"
+ warn "A core file is found. Saving it at: #{core_path.dump}"
+ FileUtils.mv('core', core_path)
+ cmd = ['gdb', @ruby, '-c', core_path, '-ex', 'bt', '-batch']
+ p cmd # debugging why it's not working
+ system(*cmd)
+ end
FileUtils.rm_f Dir.glob('core.*')
FileUtils.rm_f @ruby+'.stackdump' if @ruby
end
diff --git a/bootstraptest/test_env.rb b/bootstraptest/test_env.rb
new file mode 100644
index 0000000000..7d1b45b75e
--- /dev/null
+++ b/bootstraptest/test_env.rb
@@ -0,0 +1,12 @@
+assert_equal "true", %q{
+ ENV["ENVTEST"] = "\u{e9 3042 d76c}"
+ env = ENV["ENVTEST"]
+ env.valid_encoding?
+}
+
+# different encoding is used for PATH
+assert_equal "true", %q{
+ ENV["PATH"] = "\u{e9 3042 d76c}"
+ env = ENV["PATH"]
+ env.valid_encoding?
+}
diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb
index 8e90ac2728..5d2593c306 100644
--- a/bootstraptest/test_eval.rb
+++ b/bootstraptest/test_eval.rb
@@ -190,7 +190,8 @@ assert_equal %q{[10, main]}, %q{
}
%w[break next redo].each do |keyword|
- assert_match %r"Can't escape from eval with #{keyword}\z", %{
+ assert_match %r"Can't escape from eval with #{keyword}\b", %{
+ STDERR.reopen(STDOUT)
begin
eval "0 rescue #{keyword}"
rescue SyntaxError => e
@@ -249,7 +250,9 @@ assert_equal 'ok', %q{
assert_equal 'ok', %q{
begin
- 12.instance_eval { @@a }
+ class A
+ 12.instance_eval { @@a }
+ end
rescue NameError
:ok
end
@@ -257,7 +260,9 @@ assert_equal 'ok', %q{
assert_equal 'ok', %q{
begin
- 12.instance_exec { @@a }
+ class A
+ 12.instance_exec { @@a }
+ end
rescue NameError
:ok
end
diff --git a/bootstraptest/test_exception.rb b/bootstraptest/test_exception.rb
index 35c8d25e37..0fb6f552b8 100644
--- a/bootstraptest/test_exception.rb
+++ b/bootstraptest/test_exception.rb
@@ -402,7 +402,7 @@ assert_equal 'nil', %q{
exc.inspect
}, '[ruby-dev:32608]'
-assert_equal 'exception class/object expected', %q{
+assert_equal 'divided by 0', %q{
class ZeroDivisionError
def self.new(message)
42
diff --git a/bootstraptest/test_fiber.rb b/bootstraptest/test_fiber.rb
new file mode 100644
index 0000000000..35e1bf6851
--- /dev/null
+++ b/bootstraptest/test_fiber.rb
@@ -0,0 +1,39 @@
+show_limit %q{
+ fibers = []
+ begin
+ fiber = Fiber.new{Fiber.yield}
+ fiber.resume
+ fibers << fiber
+
+ raise Exception, "skipping" if fibers.count >= 10_000
+ rescue Exception => error
+ puts "Fiber count: #{fibers.count} (#{error})"
+ break
+ end while true
+}
+
+assert_equal %q{ok}, %q{
+ Fiber.new{
+ }.resume
+ :ok
+}
+
+assert_equal %q{ok}, %q{
+ 10_000.times.collect{Fiber.new{}}
+ :ok
+}
+
+assert_equal %q{ok}, %q{
+ fibers = 100.times.collect{Fiber.new{Fiber.yield}}
+ fibers.each(&:resume)
+ fibers.each(&:resume)
+ :ok
+}
+
+assert_normal_exit %q{
+ at_exit { Fiber.new{}.resume }
+}
+
+assert_normal_exit %q{
+ Fiber.new(&Object.method(:class_eval)).resume("foo")
+}, '[ruby-dev:34128]'
diff --git a/bootstraptest/test_flow.rb b/bootstraptest/test_flow.rb
index 0390062a24..35f19db588 100644
--- a/bootstraptest/test_flow.rb
+++ b/bootstraptest/test_flow.rb
@@ -534,11 +534,11 @@ assert_equal %Q{ENSURE\n}, %q{
['[ruby-core:39125]', %q{
class Bug5234
include Enumerable
- def each
+ def each(&block)
begin
yield :foo
ensure
- proc
+ proc(&block)
end
end
end
@@ -547,11 +547,11 @@ assert_equal %Q{ENSURE\n}, %q{
['[ruby-dev:45656]', %q{
class Bug6460
include Enumerable
- def each
+ def each(&block)
begin
yield :foo
ensure
- 1.times { Proc.new }
+ 1.times { Proc.new(&block) }
end
end
end
@@ -589,3 +589,13 @@ assert_equal "foo", %q{
end
Bug6460.new.m1
}, '[ruby-dev:46372]'
+
+assert_equal "foo", %q{
+ obj = "foo"
+ if obj || any1
+ any2 = any2
+ else
+ raise obj.inspect
+ end
+ obj
+}, '[ruby-core:87830]'
diff --git a/bootstraptest/test_fork.rb b/bootstraptest/test_fork.rb
index 1cd9f7ac6c..83923dad97 100644
--- a/bootstraptest/test_fork.rb
+++ b/bootstraptest/test_fork.rb
@@ -21,7 +21,9 @@ assert_finish 10, %q{
end
}, '[ruby-core:22158]'
-assert_normal_exit(<<'End', '[ruby-dev:37934]')
+# temporarily stop this test to enable explicit failure when
+# timer thread couldn't be created (r61706 and r61717).
+assert_normal_exit(<<'End', '[ruby-dev:37934]') if false
main = Thread.current
Thread.new { sleep 0.01 until main.stop?; Thread.kill main }
Process.setrlimit(:NPROC, 1) if defined?(Process::RLIMIT_NPROC)
diff --git a/bootstraptest/test_insns.rb b/bootstraptest/test_insns.rb
index 4dd888897a..9052cad7bd 100644
--- a/bootstraptest/test_insns.rb
+++ b/bootstraptest/test_insns.rb
@@ -10,15 +10,16 @@ begin
rescue LoadError
# OK, just skip
else
- $FIXNUM_MAX = RbConfig::LIMITS["FIXNUM_MAX"]
- $FIXNUM_MIN = RbConfig::LIMITS["FIXNUM_MIN"]
+ if defined? RbConfig::LIMITS
+ $FIXNUM_MAX = RbConfig::LIMITS["FIXNUM_MAX"]
+ $FIXNUM_MIN = RbConfig::LIMITS["FIXNUM_MIN"]
+ end
end
fsl = { frozen_string_literal: true } # used later
tests = [
# insn , expression to generate such insn
[ 'nop', %q{ raise rescue true }, ],
- [ 'trace', %q{ true }, ],
[ 'setlocal *, 0', %q{ x = true }, ],
[ 'setlocal *, 1', %q{ x = nil; -> { x = true }.call }, ],
@@ -27,6 +28,27 @@ tests = [
[ 'getlocal *, 1', %q{ x = true; -> { x }.call }, ],
[ 'getlocal', %q{ x = true; -> { -> { x }.() }.() }, ],
+ [ 'setblockparam', <<-'},', ], # {
+ def m&b
+ b = # here
+ proc { true }
+ end
+ m { false }.call
+ },
+ [ 'getblockparam', <<-'},', ], # {
+ def m&b
+ b # here
+ end
+ m { true }.call
+ },
+ [ 'getblockparamproxy', <<-'},', ], # {
+ def m&b
+ b # here
+ .call
+ end
+ m { true }
+ },
+
[ 'setspecial', %q{ true if true..true }, ],
[ 'getspecial', %q{ $&.nil? }, ],
[ 'getspecial', %q{ $`.nil? }, ],
@@ -42,8 +64,8 @@ tests = [
[ 'setinstancevariable', %q{ @x = true }, ],
[ 'getinstancevariable', %q{ @x = true; @x }, ],
- [ 'setclassvariable', %q{ @@x = true }, ],
- [ 'getclassvariable', %q{ @@x = true; @@x }, ],
+ [ 'setclassvariable', %q{ class A; @@x = true; end }, ],
+ [ 'getclassvariable', %q{ class A; @@x = true; @@x end }, ],
[ 'setconstant', %q{ X = true }, ],
[ 'setconstant', %q{ Object::X = true }, ],
@@ -64,25 +86,24 @@ tests = [
[ 'putobject', %q{ /(?<x>x)/ =~ "x"; x == "x" }, ],
[ 'putspecialobject', %q{ {//=>true}[//] }, ],
- [ 'putiseq', %q{ -> { true }.() }, ],
[ 'putstring', %q{ "true" }, ],
[ 'tostring / concatstrings', %q{ "#{true}" }, ],
- [ 'freezestring', %q{ "#{true}"}, fsl, ],
- [ 'freezestring', %q{ "#{true}"}, '-d', fsl, ],
[ 'toregexp', %q{ /#{true}/ =~ "true" && $~ }, ],
+ [ 'intern', %q{ :"#{true}" }, ],
[ 'newarray', %q{ ["true"][0] }, ],
+ [ 'newarraykwsplat', %q{ [**{x:'true'}][0][:x] }, ],
[ 'duparray', %q{ [ true ][0] }, ],
[ 'expandarray', %q{ y = [ true, false, nil ]; x, = y; x }, ],
[ 'expandarray', %q{ y = [ true, false, nil ]; x, *z = y; x }, ],
[ 'expandarray', %q{ y = [ true, false, nil ]; x, *z, w = y; x }, ],
[ 'splatarray', %q{ x, = *(y = true), false; x }, ],
[ 'concatarray', %q{ ["t", "r", *x = "u", "e"].join }, ],
- [ 'concatarray', <<~'},', ], # {
+ [ 'concatarray', <<-'},', ], # {
class X; def to_a; ['u']; end; end
['t', 'r', *X.new, 'e'].join
},
- [ 'concatarray', <<~'},', ], # {
+ [ 'concatarray', <<-'},', ], # {
r = false
t = [true, nil]
q, w, e = r, *t # here
@@ -91,15 +112,15 @@ tests = [
[ 'newhash', %q{ x = {}; x[x] = true }, ],
[ 'newhash', %q{ x = true; { x => x }[x] }, ],
+ [ 'newhashfromarray', %q{ { a: true }[:a] }, ],
[ 'newrange', %q{ x = 1; [*(0..x)][0] == 0 }, ],
[ 'newrange', %q{ x = 1; [*(0...x)][0] == 0 }, ],
[ 'pop', %q{ def x; true; end; x }, ],
[ 'dup', %q{ x = y = true; x }, ],
[ 'dupn', %q{ Object::X ||= true }, ],
- [ 'dupn', %q{ Object::X ||= true }, ],
[ 'reverse', %q{ q, (w, e), r = 1, [2, 3], 4; e == 3 }, ],
- [ 'swap', <<~'},', ], # {
+ [ 'swap', <<-'},', ], # {
x = [[false, true]]
for i, j in x # here
;
@@ -113,7 +134,8 @@ tests = [
[ 'defined', %q{ !defined?(x) }, ],
[ 'checkkeyword', %q{ def x x:rand;x end; x x: true }, ],
- [ 'checkmatch', <<~'},', ], # {
+ [ 'checktype', %q{ x = true; "#{x}" }, ],
+ [ 'checkmatch', <<-'},', ], # {
x = y = true
case x
when false
@@ -123,7 +145,7 @@ tests = [
end
y == nil
},
- [ 'checkmatch', <<~'},', ], # {
+ [ 'checkmatch', <<-'},', ], # {
x, y = true, [false]
case x
when *y # here
@@ -133,7 +155,7 @@ tests = [
end
z
},
- [ 'checkmatch', <<~'},', ], # {
+ [ 'checkmatch', <<-'},', ], # {
x = false
begin
raise
@@ -149,7 +171,7 @@ tests = [
[ 'defineclass', %q{ X = Class.new; class X; true end }, ],
[ 'defineclass', %q{ X = Class.new; class Y < X; true end }, ],
[ 'defineclass', %q{ X = Class.new; class << X; true end }, ],
- [ 'defineclass', <<~'},', ], # {
+ [ 'defineclass', <<-'},', ], # {
X = Class.new
Y = Class.new(X)
class Y < X
@@ -160,7 +182,7 @@ tests = [
[ 'opt_send_without_block', %q{ true.to_s }, ],
[ 'send', %q{ true.tap {|i| i.to_s } }, ],
[ 'leave', %q{ def x; true; end; x }, ],
- [ 'invokesuper', <<~'},', ], # {
+ [ 'invokesuper', <<-'},', ], # {
class X < String
def empty?
super # here
@@ -168,7 +190,7 @@ tests = [
end
X.new.empty?
},
- [ 'invokeblock', <<~'},', ], # {
+ [ 'invokeblock', <<-'},', ], # {
def x
return yield self # here
end
@@ -178,8 +200,11 @@ tests = [
},
[ 'opt_str_freeze', %q{ 'true'.freeze }, ],
+ [ 'opt_nil_p', %q{ nil.nil? }, ],
+ [ 'opt_nil_p', %q{ !Object.nil? }, ],
+ [ 'opt_nil_p', %q{ Class.new{def nil?; true end}.new.nil? }, ],
[ 'opt_str_uminus', %q{ -'true' }, ],
- [ 'opt_str_freeze', <<~'},', ], # {
+ [ 'opt_str_freeze', <<-'},', ], # {
class String
def freeze
true
@@ -190,7 +215,7 @@ tests = [
[ 'opt_newarray_max', %q{ [ ].max.nil? }, ],
[ 'opt_newarray_max', %q{ [1, x = 2, 3].max == 3 }, ],
- [ 'opt_newarray_max', <<~'},', ], # {
+ [ 'opt_newarray_max', <<-'},', ], # {
class Array
def max
true
@@ -200,7 +225,7 @@ tests = [
},
[ 'opt_newarray_min', %q{ [ ].min.nil? }, ],
[ 'opt_newarray_min', %q{ [3, x = 2, 1].min == 1 }, ],
- [ 'opt_newarray_min', <<~'},', ], # {
+ [ 'opt_newarray_min', <<-'},', ], # {
class Array
def min
true
@@ -216,12 +241,12 @@ tests = [
[ 'branchunless', %q{ x = nil; x &&= true; x.nil? }, ],
[ 'branchnil', %q{ x = true; x&.to_s }, ],
[ 'branchnil', %q{ x = nil; (x&.to_s).nil? }, ],
- [ 'jump', <<~'},', ], # {
+ [ 'jump', <<-'},', ], # {
y = 1
x = if y == 0 then nil elsif y == 1 then true else nil end
x
},
- [ 'jump', <<~'},', ], # {
+ [ 'jump', <<-'},', ], # {
# ultra complicated situation: this ||= assignment only generates
# 15 instructions, not including the class definition.
class X; attr_accessor :x; end
@@ -230,14 +255,14 @@ tests = [
},
[ 'once', %q{ /#{true}/o =~ "true" && $~ }, ],
- [ 'once', <<~'},', ], # {
+ [ 'once', <<-'},', ], # {
def once expr
return /#{expr}/o # here
end
x = once(true); x = once(false); x = once(nil);
x =~ "true" && $~
},
- [ 'once', <<~'},', ], # {
+ [ 'once', <<-'},', ], # {
# recursive once
def once n
return %r/#{
@@ -251,7 +276,7 @@ tests = [
x = once(128); x = once(7); x = once(16);
x =~ "true" && $~
},
- [ 'once', <<~'},', ], # {
+ [ 'once', <<-'},', ], # {
# inter-thread lockup situation
def once n
return Thread.start n do |m|
@@ -299,12 +324,12 @@ tests = [
[ 'opt_mod', %q{ '%s' % [ true ] }, ],
[ 'opt_eq', %q{ 1 == 1 }, ],
- [ 'opt_eq', <<~'},', ], # {
+ [ 'opt_eq', <<-'},', ], # {
class X; def == other; true; end; end
X.new == true
},
[ 'opt_neq', %q{ 1 != 0 }, ],
- [ 'opt_neq', <<~'},', ], # {
+ [ 'opt_neq', <<-'},', ], # {
class X; def != other; true; end; end
X.new != true
},
@@ -336,7 +361,7 @@ tests = [
[ 'opt_aset', %q{ [][0] = true }, ],
[ 'opt_aset', %q{ {}[0] = true }, ],
[ 'opt_aset', %q{ x = 'frue'; x[0] = 't'; x }, ],
- [ 'opt_aset', <<~'},', ], # {
+ [ 'opt_aset', <<-'},', ], # {
# opt_aref / opt_aset mixup situation
class X; def x; {}; end; end
x = X.new
@@ -366,24 +391,49 @@ tests = [
[ 'opt_succ',%Q{ #{ $FIXNUM_MAX }.succ == #{ $FIXNUM_MAX + 1 } }, ]
end,
[ 'opt_succ', %q{ '1'.succ == '2' }, ],
- [ 'opt_succ', %q{ x = Time.at(0); x.succ == Time.at(1) }, ],
[ 'opt_not', %q{ ! false }, ],
- [ 'opt_neq', <<~'},', ], # {
+ [ 'opt_neq', <<-'},', ], # {
class X; def !; true; end; end
! X.new
},
- [ 'opt_regexpmatch1', %q{ /true/ =~ 'true' && $~ }, ],
- [ 'opt_regexpmatch1', <<~'},', ], # {
+ [ 'opt_regexpmatch2', %q{ /true/ =~ 'true' && $~ }, ],
+ [ 'opt_regexpmatch2', <<-'},', ], # {
class Regexp; def =~ other; true; end; end
/true/ =~ 'true'
},
[ 'opt_regexpmatch2', %q{ 'true' =~ /true/ && $~ }, ],
- [ 'opt_regexpmatch2', <<~'},', ], # {
+ [ 'opt_regexpmatch2', <<-'},', ], # {
class String; def =~ other; true; end; end
'true' =~ /true/
},
]
-tests.compact.each {|(insn, expr, *a)| assert_equal 'true', expr, insn, *a }
+# normal path
+tests.compact.each do |(insn, expr, *a)|
+ if a.last.is_a?(Hash)
+ a = a.dup
+ kw = a.pop
+ assert_equal 'true', expr, insn, *a, **kw
+ else
+ assert_equal 'true', expr, insn, *a
+ end
+end
+
+# with trace
+tests.compact.each {|(insn, expr, *a)|
+ progn = "set_trace_func(proc{})\n" + expr
+ if a.last.is_a?(Hash)
+ a = a.dup
+ kw = a.pop
+ assert_equal 'true', progn, 'trace_' + insn, *a, **kw
+ else
+ assert_equal 'true', progn, 'trace_' + insn, *a
+ end
+}
+
+assert_normal_exit("#{<<-"begin;"}\n#{<<-'end;'}")
+begin;
+ RubyVM::InstructionSequence.compile("", debug_level: 5)
+end;
diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb
index 1d2b19368a..89c00d0b88 100644
--- a/bootstraptest/test_io.rb
+++ b/bootstraptest/test_io.rb
@@ -52,7 +52,7 @@ assert_equal 'ok', %q{
STDIN.reopen(rw)
STDIN.reopen(save)
rw.close
- File.unlink(tmpname) unless RUBY_PLATFORM['nacl']
+ File.unlink(tmpname)
:ok
}
@@ -69,7 +69,7 @@ assert_equal 'ok', %q{
STDIN.print "a"
STDIN.reopen(save)
rw.close
- File.unlink(tmpname) unless RUBY_PLATFORM['nacl']
+ File.unlink(tmpname)
:ok
}
diff --git a/bootstraptest/test_jump.rb b/bootstraptest/test_jump.rb
index 595aaa7c4b..18a2737ea3 100644
--- a/bootstraptest/test_jump.rb
+++ b/bootstraptest/test_jump.rb
@@ -146,15 +146,16 @@ assert_equal %q{131}, %q{
end
}
}
-assert_equal %q{ok}, %q{
+assert_match %r{Invalid retry}, %q{
+STDERR.reopen(STDOUT)
begin
eval %q{
1.times{
retry
}
}
-rescue SyntaxError
- :ok
+rescue SyntaxError => e
+ e.message
end
}
assert_equal %q{3}, %q{
@@ -295,14 +296,19 @@ assert_equal "true", %q{
s.return_eigenclass == class << s; self; end
}, '[ruby-core:21379]'
-assert_equal "true", %q{
- class Object
- def yield_eigenclass
- class << self
- yield self
+assert_match %r{Invalid yield}, %q{
+STDERR.reopen(STDOUT)
+begin
+ eval %q{
+ class Object
+ def yield_eigenclass
+ class << self
+ yield self
+ end
end
end
- end
- s = "foo"
- s.yield_eigenclass {|c| c == class << s; self; end }
-}, '[ruby-dev:40975]'
+ }
+rescue SyntaxError => e
+ e.message
+end
+}
diff --git a/bootstraptest/test_literal.rb b/bootstraptest/test_literal.rb
index e79092e411..9b3c10d519 100644
--- a/bootstraptest/test_literal.rb
+++ b/bootstraptest/test_literal.rb
@@ -65,10 +65,8 @@ assert_equal ':a3c', ':"a#{1+2}c".inspect'
assert_equal 'Symbol', ':"a#{1+2}c".class'
# xstring
-unless nacl?
- assert_equal "foo\n", %q(`echo foo`)
- assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
-end
+assert_equal "foo\n", %q(`echo foo`)
+assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
# regexp
assert_equal '', '//.source'
@@ -225,6 +223,24 @@ assert_equal 'ok', %q{ # long hash literal (optimized)
:ok
}
+assert_equal 'ok', %q{ # Bug #15536
+ eval <<-END
+ {
+ **{
+ a0: nil, a1: nil, a2: nil, a3: nil, a4: nil, a5: nil, a6: nil, a7: nil, a8: nil,
+ },
+ a0: nil, a1: nil, a2: nil, a3: nil, a4: nil, a5: nil, a6: nil, a7: nil, a8: nil,
+ **{
+ c: nil
+ },
+ b0: nil, b1: nil, b2: nil, b3: nil, b4: nil, b5: nil, b6: nil, b7: nil, b8: nil,
+ b9: nil, b10: nil, b11: nil, b12: nil, b13: nil, b14: nil, b15: nil, b16: nil,
+ b17: nil, b18: nil, b19: nil, b20: nil, b21: nil,
+ }
+ END
+ :ok
+}
+
assert_equal 'ok', %q{
[print(:ok), exit] # void literal with side-effect
:dummy
diff --git a/bootstraptest/test_literal_suffix.rb b/bootstraptest/test_literal_suffix.rb
index 4316c9e040..c36fa7078f 100644
--- a/bootstraptest/test_literal_suffix.rb
+++ b/bootstraptest/test_literal_suffix.rb
@@ -46,9 +46,9 @@ assert_equal '1', '1rescue nil'
assert_equal '10000000000000000001/10000000000000000000',
'1.0000000000000000001r'
-assert_equal 'syntax error, unexpected tIDENTIFIER, expecting end-of-input',
+assert_equal 'syntax error, unexpected local variable or method, expecting end-of-input',
%q{begin eval('1ir', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end}
-assert_equal 'syntax error, unexpected tIDENTIFIER, expecting end-of-input',
+assert_equal 'syntax error, unexpected local variable or method, expecting end-of-input',
%q{begin eval('1.2ir', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end}
-assert_equal 'syntax error, unexpected tIDENTIFIER, expecting end-of-input',
+assert_equal 'syntax error, unexpected local variable or method, expecting end-of-input',
%q{begin eval('1e1r', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end}
diff --git a/bootstraptest/test_objectspace.rb b/bootstraptest/test_objectspace.rb
index 24a1a0ce2c..63a8d99322 100644
--- a/bootstraptest/test_objectspace.rb
+++ b/bootstraptest/test_objectspace.rb
@@ -44,3 +44,12 @@ assert_normal_exit %q{
Thread.new {}
end
}, '[ruby-core:37858]'
+
+assert_equal 'ok', %q{
+ objects_and_ids = 1000.times.map { o = Object.new; [o, o.object_id] }
+ objects_and_ids.each { |expected, id|
+ actual = ObjectSpace._id2ref(id)
+ raise "expected #{expected.inspect}, got #{actual.inspect}" unless actual.equal?(expected)
+ }
+ 'ok'
+}
diff --git a/bootstraptest/test_proc.rb b/bootstraptest/test_proc.rb
index c23394e8d2..637603243d 100644
--- a/bootstraptest/test_proc.rb
+++ b/bootstraptest/test_proc.rb
@@ -224,19 +224,6 @@ assert_equal %q{[[nil, []], [1, []], [1, [2]], [1, [2, 3]]]}, %q{
Proc.new{|a, *b| [a, b]}.call(1, 2, 3),
]
}
-assert_equal %q{0}, %q{
- pr = proc{
- $SAFE
- }
- $SAFE = 1
- pr.call
-}
-assert_equal %q{[1, 0]}, %q{
- pr = proc{
- $SAFE += 1
- }
- [pr.call, $SAFE]
-}
assert_equal %q{1}, %q{
def m(&b)
b
@@ -380,8 +367,8 @@ assert_equal 'ok', %q{
assert_equal 'ok', %q{
class Foo
- def call_it
- p = Proc.new
+ def call_it(&block)
+ p = Proc.new(&block)
p.call
end
end
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
new file mode 100644
index 0000000000..7d920c31b5
--- /dev/null
+++ b/bootstraptest/test_ractor.rb
@@ -0,0 +1,1444 @@
+# Ractor.current returns a current ractor
+assert_equal 'Ractor', %q{
+ Ractor.current.class
+}
+
+# Ractor.new returns new Ractor
+assert_equal 'Ractor', %q{
+ Ractor.new{}.class
+}
+
+# Ractor.allocate is not supported
+assert_equal "[:ok, :ok]", %q{
+ rs = []
+ begin
+ Ractor.allocate
+ rescue => e
+ rs << :ok if e.message == 'allocator undefined for Ractor'
+ end
+
+ begin
+ Ractor.new{}.dup
+ rescue
+ rs << :ok if e.message == 'allocator undefined for Ractor'
+ end
+
+ rs
+}
+
+# A Ractor can have a name
+assert_equal 'test-name', %q{
+ r = Ractor.new name: 'test-name' do
+ end
+ r.name
+}
+
+# If Ractor doesn't have a name, Ractor#name returns nil.
+assert_equal 'nil', %q{
+ r = Ractor.new do
+ end
+ r.name.inspect
+}
+
+# Raises exceptions if initialize with an invalid name
+assert_equal 'ok', %q{
+ begin
+ r = Ractor.new(name: [{}]) {}
+ rescue TypeError => e
+ 'ok'
+ end
+}
+
+# Ractor.new must call with a block
+assert_equal "must be called with a block", %q{
+ begin
+ Ractor.new
+ rescue ArgumentError => e
+ e.message
+ end
+}
+
+# Ractor#inspect
+# Return only id and status for main ractor
+assert_equal "#<Ractor:#1 running>", %q{
+ Ractor.current.inspect
+}
+
+# Return id, loc, and status for no-name ractor
+assert_match /^#<Ractor:#([^ ]*?) .+:[0-9]+ terminated>$/, %q{
+ r = Ractor.new { '' }
+ r.take
+ sleep 0.1 until r.inspect =~ /terminated/
+ r.inspect
+}
+
+# Return id, name, loc, and status for named ractor
+assert_match /^#<Ractor:#([^ ]*?) Test Ractor .+:[0-9]+ terminated>$/, %q{
+ r = Ractor.new(name: 'Test Ractor') { '' }
+ r.take
+ sleep 0.1 until r.inspect =~ /terminated/
+ r.inspect
+}
+
+# A return value of a Ractor block will be a message from the Ractor.
+assert_equal 'ok', %q{
+ # join
+ r = Ractor.new do
+ 'ok'
+ end
+ r.take
+}
+
+# Passed arguments to Ractor.new will be a block parameter
+# The values are passed with Ractor-communication pass.
+assert_equal 'ok', %q{
+ # ping-pong with arg
+ r = Ractor.new 'ok' do |msg|
+ msg
+ end
+ r.take
+}
+
+# Pass multiple arguments to Ractor.new
+assert_equal 'ok', %q{
+ # ping-pong with two args
+ r = Ractor.new 'ping', 'pong' do |msg, msg2|
+ [msg, msg2]
+ end
+ 'ok' if r.take == ['ping', 'pong']
+}
+
+# Ractor#send passes an object with copy to a Ractor
+# and Ractor.receive in the Ractor block can receive the passed value.
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ msg = Ractor.receive
+ end
+ r.send 'ok'
+ r.take
+}
+
+# Ractor#receive_if can filter the message
+assert_equal '[2, 3, 1]', %q{
+ r = Ractor.new Ractor.current do |main|
+ main << 1
+ main << 2
+ main << 3
+ end
+ a = []
+ a << Ractor.receive_if{|msg| msg == 2}
+ a << Ractor.receive_if{|msg| msg == 3}
+ a << Ractor.receive
+}
+
+# Ractor#receive_if with break
+assert_equal '[2, [1, :break], 3]', %q{
+ r = Ractor.new Ractor.current do |main|
+ main << 1
+ main << 2
+ main << 3
+ end
+
+ a = []
+ a << Ractor.receive_if{|msg| msg == 2}
+ a << Ractor.receive_if{|msg| break [msg, :break]}
+ a << Ractor.receive
+}
+
+# Ractor#receive_if can't be called recursively
+assert_equal '[[:e1, 1], [:e2, 2]]', %q{
+ r = Ractor.new Ractor.current do |main|
+ main << 1
+ main << 2
+ main << 3
+ end
+
+ a = []
+
+ Ractor.receive_if do |msg|
+ begin
+ Ractor.receive
+ rescue Ractor::Error
+ a << [:e1, msg]
+ end
+ true # delete 1 from queue
+ end
+
+ Ractor.receive_if do |msg|
+ begin
+ Ractor.receive_if{}
+ rescue Ractor::Error
+ a << [:e2, msg]
+ end
+ true # delete 2 from queue
+ end
+
+ a #
+}
+
+# dtoa race condition
+assert_equal '[:ok, :ok, :ok]', %q{
+ n = 3
+ n.times.map{
+ Ractor.new{
+ 10_000.times{ rand.to_s }
+ :ok
+ }
+ }.map(&:take)
+}
+
+# Ractor.make_shareable issue for locals in proc [Bug #18023]
+assert_equal '[:a, :b, :c, :d, :e]', %q{
+ v1, v2, v3, v4, v5 = :a, :b, :c, :d, :e
+ closure = Proc.new { [v1, v2, v3, v4, v5] }
+
+ Ractor.make_shareable(closure).call
+}
+
+# Ractor.make_shareable issue for locals in proc [Bug #18023]
+assert_equal '[:a, :b, :c, :d, :e, :f, :g]', %q{
+ a = :a
+ closure = -> {
+ b, c, d = :b, :c, :d
+ -> {
+ e, f, g = :e, :f, :g
+ -> { [a, b, c, d, e, f, g] }
+ }.call
+ }.call
+
+ Ractor.make_shareable(closure).call
+}
+
+###
+###
+# Ractor still has several memory corruption so skip huge number of tests
+if ENV['GITHUB_WORKFLOW'] &&
+ ENV['GITHUB_WORKFLOW'] == 'Compilations'
+ # ignore the follow
+else
+
+# Ractor.select(*ractors) receives a values from a ractors.
+# It is similar to select(2) and Go's select syntax.
+# The return value is [ch, received_value]
+assert_equal 'ok', %q{
+ # select 1
+ r1 = Ractor.new{'r1'}
+ r, obj = Ractor.select(r1)
+ 'ok' if r == r1 and obj == 'r1'
+}
+
+# Ractor.select from two ractors.
+assert_equal '["r1", "r2"]', %q{
+ # select 2
+ r1 = Ractor.new{'r1'}
+ r2 = Ractor.new{'r2'}
+ rs = [r1, r2]
+ as = []
+ r, obj = Ractor.select(*rs)
+ rs.delete(r)
+ as << obj
+ r, obj = Ractor.select(*rs)
+ as << obj
+ as.sort #=> ["r1", "r2"]
+}
+
+# Ractor.select from multiple ractors.
+assert_equal 30.times.map { 'ok' }.to_s, %q{
+ def test n
+ rs = (1..n).map do |i|
+ Ractor.new(i) do |i|
+ "r#{i}"
+ end
+ end
+ as = []
+ all_rs = rs.dup
+
+ n.times{
+ r, obj = Ractor.select(*rs)
+ as << [r, obj]
+ rs.delete(r)
+ }
+
+ if as.map{|r, o| r.object_id}.sort == all_rs.map{|r| r.object_id}.sort &&
+ as.map{|r, o| o}.sort == (1..n).map{|i| "r#{i}"}.sort
+ 'ok'
+ else
+ 'ng'
+ end
+ end
+
+ 30.times.map{|i|
+ test i
+ }
+} unless ENV['RUN_OPTS'] =~ /--jit-min-calls=5/ # This always fails with --jit-wait --jit-min-calls=5
+
+# Exception for empty select
+assert_match /specify at least one ractor/, %q{
+ begin
+ Ractor.select
+ rescue ArgumentError => e
+ e.message
+ end
+}
+
+# Outgoing port of a ractor will be closed when the Ractor is terminated.
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ 'finish'
+ end
+
+ r.take
+ sleep 0.1 until r.inspect =~ /terminated/
+
+ begin
+ o = r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ "ng: #{o}"
+ end
+}
+
+# Raise Ractor::ClosedError when try to send into a terminated ractor
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ end
+
+ r.take # closed
+ sleep 0.1 until r.inspect =~ /terminated/
+
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Raise Ractor::ClosedError when try to send into a closed actor
+assert_equal 'ok', %q{
+ r = Ractor.new { Ractor.receive }
+ r.close_incoming
+
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Raise Ractor::ClosedError when try to take from closed actor
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ Ractor.yield 1
+ Ractor.receive
+ end
+
+ r.close_outgoing
+ begin
+ r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Can mix with Thread#interrupt and Ractor#take [Bug #17366]
+assert_equal 'err', %q{
+ Ractor.new{
+ t = Thread.current
+ begin
+ Thread.new{ t.raise "err" }.join
+ rescue => e
+ e.message
+ end
+ }.take
+}
+
+# Killed Ractor's thread yields nil
+assert_equal 'nil', %q{
+ Ractor.new{
+ t = Thread.current
+ Thread.new{ t.kill }.join
+ }.take.inspect #=> nil
+}
+
+# Ractor.yield raises Ractor::ClosedError when outgoing port is closed.
+assert_equal 'ok', %q{
+ r = Ractor.new Ractor.current do |main|
+ Ractor.receive
+ main << true
+ Ractor.yield 1
+ end
+
+ r.close_outgoing
+ r << true
+ Ractor.receive
+
+ begin
+ r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Raise Ractor::ClosedError when try to send into a ractor with closed incoming port
+assert_equal 'ok', %q{
+ r = Ractor.new { Ractor.receive }
+ r.close_incoming
+
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# A ractor with closed incoming port still can send messages out
+assert_equal '[1, 2]', %q{
+ r = Ractor.new do
+ Ractor.yield 1
+ 2
+ end
+ r.close_incoming
+
+ [r.take, r.take]
+}
+
+# Raise Ractor::ClosedError when try to take from a ractor with closed outgoing port
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ Ractor.yield 1
+ Ractor.receive
+ end
+
+ sleep 0.01 # wait for Ractor.yield in r
+ r.close_outgoing
+ begin
+ r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# A ractor with closed outgoing port still can receive messages from incoming port
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ Ractor.receive
+ end
+
+ r.close_outgoing
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ng'
+ else
+ 'ok'
+ end
+}
+
+# Ractor.main returns main ractor
+assert_equal 'true', %q{
+ Ractor.new{
+ Ractor.main
+ }.take == Ractor.current
+}
+
+# a ractor with closed outgoing port should terminate
+assert_equal 'ok', %q{
+ Ractor.new do
+ close_outgoing
+ end
+
+ true until Ractor.count == 1
+ :ok
+}
+
+# multiple Ractors can receive (wait) from one Ractor
+assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{
+ pipe = Ractor.new do
+ loop do
+ Ractor.yield Ractor.receive
+ end
+ end
+
+ RN = 10
+ rs = RN.times.map{|i|
+ Ractor.new pipe, i do |pipe, i|
+ msg = pipe.take
+ msg # ping-pong
+ end
+ }
+ RN.times{|i|
+ pipe << i
+ }
+ RN.times.map{
+ r, n = Ractor.select(*rs)
+ rs.delete r
+ n
+ }.sort
+}
+
+# Ractor.select also support multiple take, receive and yield
+assert_equal '[true, true, true]', %q{
+ RN = 10
+ CR = Ractor.current
+
+ rs = (1..RN).map{
+ Ractor.new do
+ CR.send 'send' + CR.take #=> 'sendyield'
+ 'take'
+ end
+ }
+ received = []
+ take = []
+ yielded = []
+ until rs.empty?
+ r, v = Ractor.select(CR, *rs, yield_value: 'yield')
+ case r
+ when :receive
+ received << v
+ when :yield
+ yielded << v
+ else
+ take << v
+ rs.delete r
+ end
+ end
+ [received.all?('sendyield'), yielded.all?(nil), take.all?('take')]
+}
+
+# multiple Ractors can send to one Ractor
+assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{
+ pipe = Ractor.new do
+ loop do
+ Ractor.yield Ractor.receive
+ end
+ end
+
+ RN = 10
+ RN.times.map{|i|
+ Ractor.new pipe, i do |pipe, i|
+ pipe << i
+ end
+ }
+ RN.times.map{
+ pipe.take
+ }.sort
+}
+
+# an exception in a Ractor will be re-raised at Ractor#receive
+assert_equal '[RuntimeError, "ok", true]', %q{
+ r = Ractor.new do
+ raise 'ok' # exception will be transferred receiver
+ end
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ [e.cause.class, #=> RuntimeError
+ e.cause.message, #=> 'ok'
+ e.ractor == r] #=> true
+ end
+}
+
+# threads in a ractor will killed
+assert_equal '{:ok=>3}', %q{
+ Ractor.new Ractor.current do |main|
+ q = Queue.new
+ Thread.new do
+ q << true
+ loop{}
+ ensure
+ main << :ok
+ end
+
+ Thread.new do
+ q << true
+ while true
+ end
+ ensure
+ main << :ok
+ end
+
+ Thread.new do
+ q << true
+ sleep 1
+ ensure
+ main << :ok
+ end
+
+ # wait for the start of all threads
+ 3.times{q.pop}
+ end
+
+ 3.times.map{Ractor.receive}.tally
+}
+
+# unshareable object are copied
+assert_equal 'false', %q{
+ obj = 'str'.dup
+ r = Ractor.new obj do |msg|
+ msg.object_id
+ end
+
+ obj.object_id == r.take
+}
+
+# To copy the object, now Marshal#dump is used
+assert_equal "allocator undefined for Thread", %q{
+ obj = Thread.new{}
+ begin
+ r = Ractor.new obj do |msg|
+ msg
+ end
+ rescue TypeError => e
+ e.message #=> no _dump_data is defined for class Thread
+ else
+ 'ng'
+ end
+}
+
+# send shareable and unshareable objects
+assert_equal "ok", %q{
+ echo_ractor = Ractor.new do
+ loop do
+ v = Ractor.receive
+ Ractor.yield v
+ end
+ end
+
+ class C; end
+ module M; end
+ S = Struct.new(:a, :b, :c, :d)
+
+ shareable_objects = [
+ true,
+ false,
+ nil,
+ 1,
+ 1.1, # Float
+ 1+2r, # Rational
+ 3+4i, # Complex
+ 2**128, # Bignum
+ :sym, # Symbol
+ 'xyzzy'.to_sym, # dynamic symbol
+ 'frozen'.freeze, # frozen String
+ /regexp/, # regexp literal
+ /reg{true}exp/.freeze, # frozen dregexp
+ [1, 2].freeze, # frozen Array which only refers to shareable
+ {a: 1}.freeze, # frozen Hash which only refers to shareable
+ [{a: 1}.freeze, 'str'.freeze].freeze, # nested frozen container
+ S.new(1, 2).freeze, # frozen Struct
+ S.new(1, 2, 3, 4).freeze, # frozen Struct
+ (1..2), # Range on Struct
+ (1..), # Range on Struct
+ (..1), # Range on Struct
+ C, # class
+ M, # module
+ Ractor.current, # Ractor
+ ]
+
+ unshareable_objects = [
+ 'mutable str'.dup,
+ [:array],
+ {hash: true},
+ S.new(1, 2),
+ S.new(1, 2, 3, 4),
+ S.new("a", 2).freeze, # frozen, but refers to an unshareable object
+ ]
+
+ results = []
+
+ shareable_objects.map{|o|
+ echo_ractor << o
+ o2 = echo_ractor.take
+ results << "#{o} is copied" unless o.object_id == o2.object_id
+ }
+
+ unshareable_objects.map{|o|
+ echo_ractor << o
+ o2 = echo_ractor.take
+ results << "#{o.inspect} is not copied" if o.object_id == o2.object_id
+ }
+
+ if results.empty?
+ :ok
+ else
+ results.inspect
+ end
+}
+
+# frozen Objects are shareable
+assert_equal [false, true, false].inspect, %q{
+ class C
+ def initialize freeze
+ @a = 1
+ @b = :sym
+ @c = 'frozen_str'
+ @c.freeze if freeze
+ @d = true
+ end
+ end
+
+ def check obj1
+ obj2 = Ractor.new obj1 do |obj|
+ obj
+ end.take
+
+ obj1.object_id == obj2.object_id
+ end
+
+ results = []
+ results << check(C.new(true)) # false
+ results << check(C.new(true).freeze) # true
+ results << check(C.new(false).freeze) # false
+}
+
+# move example2: String
+# touching moved object causes an error
+assert_equal 'hello world', %q{
+ # move
+ r = Ractor.new do
+ obj = Ractor.receive
+ obj << ' world'
+ end
+
+ str = 'hello'
+ r.send str, move: true
+ modified = r.take
+
+ begin
+ str << ' exception' # raise Ractor::MovedError
+ rescue Ractor::MovedError
+ modified #=> 'hello world'
+ else
+ raise 'unreachable'
+ end
+}
+
+# move example2: Array
+assert_equal '[0, 1]', %q{
+ r = Ractor.new do
+ ary = Ractor.receive
+ ary << 1
+ end
+
+ a1 = [0]
+ r.send a1, move: true
+ a2 = r.take
+ begin
+ a1 << 2 # raise Ractor::MovedError
+ rescue Ractor::MovedError
+ a2.inspect
+ end
+}
+
+# move with yield
+assert_equal 'hello', %q{
+ r = Ractor.new do
+ Thread.current.report_on_exception = false
+ obj = 'hello'
+ Ractor.yield obj, move: true
+ obj << 'world'
+ end
+
+ str = r.take
+ begin
+ r.take
+ rescue Ractor::RemoteError
+ str #=> "hello"
+ end
+}
+
+# yield/move should not make moved object when the yield is not succeeded
+assert_equal '"str"', %q{
+ R = Ractor.new{}
+ M = Ractor.current
+ r = Ractor.new do
+ s = 'str'
+ selected_r, v = Ractor.select R, yield_value: s, move: true
+ raise if selected_r != R # taken from R
+ M.send s.inspect # s should not be a moved object
+ end
+
+ Ractor.receive
+}
+
+# yield/move can fail
+assert_equal "allocator undefined for Thread", %q{
+ r = Ractor.new do
+ obj = Thread.new{}
+ Ractor.yield obj
+ rescue => e
+ e.message
+ end
+ r.take
+}
+
+# Access to global-variables are prohibited
+assert_equal 'can not access global variables $gv from non-main Ractors', %q{
+ $gv = 1
+ r = Ractor.new do
+ $gv
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Access to global-variables are prohibited
+assert_equal 'can not access global variables $gv from non-main Ractors', %q{
+ r = Ractor.new do
+ $gv = 1
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# $stdin,out,err is Ractor local, but shared fds
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ [$stdin, $stdout, $stderr].map{|io|
+ [io.object_id, io.fileno]
+ }
+ end
+
+ [$stdin, $stdout, $stderr].zip(r.take){|io, (oid, fno)|
+ raise "should not be different object" if io.object_id == oid
+ raise "fd should be same" unless io.fileno == fno
+ }
+ 'ok'
+}
+
+# $stdin,out,err belong to Ractor
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ $stdin.itself
+ $stdout.itself
+ $stderr.itself
+ 'ok'
+ end
+
+ r.take
+}
+
+# $DEBUG, $VERBOSE are Ractor local
+assert_equal 'true', %q{
+ $DEBUG = true
+ $VERBOSE = true
+
+ def ractor_local_globals
+ /a(b)(c)d/ =~ 'abcd' # for $~
+ `echo foo` unless /solaris/ =~ RUBY_PLATFORM
+
+ {
+ # ractor-local (derived from created ractor): debug
+ '$DEBUG' => $DEBUG,
+ '$-d' => $-d,
+
+ # ractor-local (derived from created ractor): verbose
+ '$VERBOSE' => $VERBOSE,
+ '$-w' => $-w,
+ '$-W' => $-W,
+ '$-v' => $-v,
+
+ # process-local (readonly): other commandline parameters
+ '$-p' => $-p,
+ '$-l' => $-l,
+ '$-a' => $-a,
+
+ # process-local (readonly): getpid
+ '$$' => $$,
+
+ # thread local: process result
+ '$?' => $?,
+
+ # scope local: match
+ '$~' => $~.inspect,
+ '$&' => $&,
+ '$`' => $`,
+ '$\'' => $',
+ '$+' => $+,
+ '$1' => $1,
+
+ # scope local: last line
+ '$_' => $_,
+
+ # scope local: last backtrace
+ '$@' => $@,
+ '$!' => $!,
+
+ # ractor local: stdin, out, err
+ '$stdin' => $stdin.inspect,
+ '$stdout' => $stdout.inspect,
+ '$stderr' => $stderr.inspect,
+ }
+ end
+
+ h = Ractor.new do
+ ractor_local_globals
+ end.take
+ ractor_local_globals == h #=> true
+}
+
+# selfs are different objects
+assert_equal 'false', %q{
+ r = Ractor.new do
+ self.object_id
+ end
+ r.take == self.object_id #=> false
+}
+
+# self is a Ractor instance
+assert_equal 'true', %q{
+ r = Ractor.new do
+ self.object_id
+ end
+ r.object_id == r.take #=> true
+}
+
+# given block Proc will be isolated, so can not access outer variables.
+assert_equal 'ArgumentError', %q{
+ begin
+ a = true
+ r = Ractor.new do
+ a
+ end
+ rescue => e
+ e.class
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor
+assert_equal 'can not access instance variables of classes/modules from non-main Ractors', %q{
+ class C
+ @iv = 'str'
+ end
+
+ r = Ractor.new do
+ class C
+ p @iv
+ end
+ end
+
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor
+assert_equal 'can not access instance variables of shareable objects from non-main Ractors', %q{
+ shared = Ractor.new{}
+ shared.instance_variable_set(:@iv, 'str')
+
+ r = Ractor.new shared do |shared|
+ p shared.instance_variable_get(:@iv)
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor, by @iv (get)
+assert_equal 'can not access instance variables of shareable objects from non-main Ractors', %q{
+ class Ractor
+ def setup
+ @foo = ''
+ end
+
+ def foo
+ @foo
+ end
+ end
+
+ shared = Ractor.new{}
+ shared.setup
+
+ r = Ractor.new shared do |shared|
+ p shared.foo
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor, by @iv (set)
+assert_equal 'can not access instance variables of shareable objects from non-main Ractors', %q{
+ class Ractor
+ def setup
+ @foo = ''
+ end
+ end
+
+ shared = Ractor.new{}
+
+ r = Ractor.new shared do |shared|
+ p shared.setup
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# But a shareable object is frozen, it is allowed to access ivars from non-main Ractor
+assert_equal '11', %q{
+ [Object.new, [], ].map{|obj|
+ obj.instance_variable_set('@a', 1)
+ Ractor.make_shareable obj = obj.freeze
+
+ Ractor.new obj do |obj|
+ obj.instance_variable_get('@a')
+ end.take.to_s
+ }.join
+}
+
+# cvar in shareable-objects are not allowed to access from non-main Ractor
+assert_equal 'can not access class variables from non-main Ractors', %q{
+ class C
+ @@cv = 'str'
+ end
+
+ r = Ractor.new do
+ class C
+ p @@cv
+ end
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Getting non-shareable objects via constants by other Ractors is not allowed
+assert_equal 'can not access non-shareable objects in constant C::CONST by non-main Ractor.', %q{
+ class C
+ CONST = 'str'
+ end
+ r = Ractor.new do
+ C::CONST
+ end
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Constant cache should care about non-sharable constants
+assert_equal "can not access non-shareable objects in constant Object::STR by non-main Ractor.", %q{
+ STR = "hello"
+ def str; STR; end
+ s = str() # fill const cache
+ begin
+ Ractor.new{ str() }.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Setting non-shareable objects into constants by other Ractors is not allowed
+assert_equal 'can not set constants with non-shareable objects by non-main Ractors', %q{
+ class C
+ end
+ r = Ractor.new do
+ C::CONST = 'str'
+ end
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# define_method is not allowed
+assert_equal "defined in a different Ractor", %q{
+ str = "foo"
+ define_method(:buggy){|i| str << "#{i}"}
+ begin
+ Ractor.new{buggy(10)}.take
+ rescue => e
+ e.cause.message
+ end
+}
+
+# Immutable Array and Hash are shareable, so it can be shared with constants
+assert_equal '[1000, 3]', %q{
+ A = Array.new(1000).freeze # [nil, ...]
+ H = {a: 1, b: 2, c: 3}.freeze
+
+ Ractor.new{ [A.size, H.size] }.take
+}
+
+# Ractor.count
+assert_equal '[1, 4, 3, 2, 1]', %q{
+ counts = []
+ counts << Ractor.count
+ ractors = (1..3).map { Ractor.new { Ractor.receive } }
+ counts << Ractor.count
+
+ ractors[0].send('End 0').take
+ sleep 0.1 until ractors[0].inspect =~ /terminated/
+ counts << Ractor.count
+
+ ractors[1].send('End 1').take
+ sleep 0.1 until ractors[1].inspect =~ /terminated/
+ counts << Ractor.count
+
+ ractors[2].send('End 2').take
+ sleep 0.1 until ractors[2].inspect =~ /terminated/
+ counts << Ractor.count
+
+ counts.inspect
+}
+
+# ObjectSpace.each_object can not handle unshareable objects with Ractors
+assert_equal '0', %q{
+ Ractor.new{
+ n = 0
+ ObjectSpace.each_object{|o| n += 1 unless Ractor.shareable?(o)}
+ n
+ }.take
+}
+
+# ObjectSpace._id2ref can not handle unshareable objects with Ractors
+assert_equal 'ok', %q{
+ s = 'hello'
+
+ Ractor.new s.object_id do |id ;s|
+ begin
+ s = ObjectSpace._id2ref(id)
+ rescue => e
+ :ok
+ end
+ end.take
+}
+
+# Ractor.make_shareable(obj)
+assert_equal 'true', %q{
+ class C
+ def initialize
+ @a = 'foo'
+ @b = 'bar'
+ end
+
+ def freeze
+ @c = [:freeze_called]
+ super
+ end
+
+ attr_reader :a, :b, :c
+ end
+ S = Struct.new(:s1, :s2)
+ str = "hello"
+ str.instance_variable_set("@iv", "hello")
+ /a/ =~ 'a'
+ m = $~
+ class N < Numeric
+ def /(other)
+ 1
+ end
+ end
+ ary = []; ary << ary
+
+ a = [[1, ['2', '3']],
+ {Object.new => "hello"},
+ C.new,
+ S.new("x", "y"),
+ ("a".."b"),
+ str,
+ ary, # cycle
+ /regexp/,
+ /#{'r'.upcase}/,
+ m,
+ Complex(N.new,0),
+ Rational(N.new,0),
+ true,
+ false,
+ nil,
+ 1, 1.2, 1+3r, 1+4i, # Numeric
+ ]
+ Ractor.make_shareable(a)
+
+ # check all frozen
+ a.each{|o|
+ raise o.inspect unless o.frozen?
+
+ case o
+ when C
+ raise o.a.inspect unless o.a.frozen?
+ raise o.b.inspect unless o.b.frozen?
+ raise o.c.inspect unless o.c.frozen? && o.c == [:freeze_called]
+ when Rational
+ raise o.numerator.inspect unless o.numerator.frozen?
+ when Complex
+ raise o.real.inspect unless o.real.frozen?
+ when Array
+ if o[0] == 1
+ raise o[1][1].inspect unless o[1][1].frozen?
+ end
+ when Hash
+ o.each{|k, v|
+ raise k.inspect unless k.frozen?
+ raise v.inspect unless v.frozen?
+ }
+ end
+ }
+
+ Ractor.shareable?(a)
+}
+
+# Ractor.make_shareable(obj) doesn't freeze shareable objects
+assert_equal 'true', %q{
+ r = Ractor.new{}
+ Ractor.make_shareable(a = [r])
+ [a.frozen?, a[0].frozen?] == [true, false]
+}
+
+# Ractor.make_shareable(a_proc) makes a proc shareable.
+assert_equal 'true', %q{
+ a = [1, [2, 3], {a: "4"}]
+ pr = Proc.new do
+ a
+ end
+ Ractor.make_shareable(a) # referred value should be shareable
+ Ractor.make_shareable(pr)
+ Ractor.shareable?(pr)
+}
+
+# Ractor.shareable?(recursive_objects)
+assert_equal '[false, false]', %q{
+ y = []
+ x = [y, {}].freeze
+ y << x
+ y.freeze
+ [Ractor.shareable?(x), Ractor.shareable?(y)]
+}
+
+# Ractor.make_shareable(recursive_objects)
+assert_equal '[:ok, false, false]', %q{
+ o = Object.new
+ def o.freeze; raise; end
+ y = []
+ x = [y, o].freeze
+ y << x
+ y.freeze
+ [(Ractor.make_shareable(x) rescue :ok), Ractor.shareable?(x), Ractor.shareable?(y)]
+}
+
+# Ractor.make_shareable with Class/Module
+assert_equal '[C, M]', %q{
+ class C; end
+ module M; end
+
+ Ractor.make_shareable(ary = [C, M])
+}
+
+# define_method() can invoke different Ractor's proc if the proc is shareable.
+assert_equal '1', %q{
+ class C
+ a = 1
+ define_method "foo", Ractor.make_shareable(Proc.new{ a })
+ a = 2
+ end
+
+ Ractor.new{ C.new.foo }.take
+}
+
+# Ractor.make_shareable(a_proc) makes a proc shareable.
+assert_equal 'can not make a Proc shareable because it accesses outer variables (a).', %q{
+ a = b = nil
+ pr = Proc.new do
+ c = b # assign to a is okay because c is block local variable
+ # reading b is okay
+ a = b # assign to a is not allowed #=> Ractor::Error
+ end
+
+ begin
+ Ractor.make_shareable(pr)
+ rescue => e
+ e.message
+ end
+}
+
+# Ractor.make_shareable(obj, copy: true) makes copied shareable object.
+assert_equal '[false, false, true, true]', %q{
+ r = []
+ o1 = [1, 2, ["3"]]
+
+ o2 = Ractor.make_shareable(o1, copy: true)
+ r << Ractor.shareable?(o1) # false
+ r << (o1.object_id == o2.object_id) # false
+
+ o3 = Ractor.make_shareable(o1)
+ r << Ractor.shareable?(o1) # true
+ r << (o1.object_id == o3.object_id) # false
+ r
+}
+
+# TracePoint with normal Proc should be Ractor local
+assert_equal '[4, 8]', %q{
+ rs = []
+ TracePoint.new(:line){|tp| rs << tp.lineno if tp.path == __FILE__}.enable do
+ Ractor.new{ # line 4
+ a = 1
+ b = 2
+ }.take
+ c = 3 # line 8
+ end
+ rs
+}
+
+# Ractor deep copies frozen objects (ary)
+assert_equal '[true, false]', %q{
+ Ractor.new([[]].freeze) { |ary|
+ [ary.frozen?, ary.first.frozen? ]
+ }.take
+}
+
+# Ractor deep copies frozen objects (str)
+assert_equal '[true, false]', %q{
+ s = String.new.instance_eval { @x = []; freeze}
+ Ractor.new(s) { |s|
+ [s.frozen?, s.instance_variable_get(:@x).frozen?]
+ }.take
+}
+
+# Can not trap with not isolated Proc on non-main ractor
+assert_equal '[:ok, :ok]', %q{
+ a = []
+ Ractor.new{
+ trap(:INT){p :ok}
+ }.take
+ a << :ok
+
+ begin
+ Ractor.new{
+ s = 'str'
+ trap(:INT){p s}
+ }.take
+ rescue => Ractor::RemoteError
+ a << :ok
+ end
+}
+
+# Ractor-local storage
+assert_equal '[nil, "b", "a"]', %q{
+ ans = []
+ Ractor.current[:key] = 'a'
+ r = Ractor.new{
+ Ractor.yield self[:key]
+ self[:key] = 'b'
+ self[:key]
+ }
+ ans << r.take
+ ans << r.take
+ ans << Ractor.current[:key]
+}
+
+###
+### Synchronization tests
+###
+
+N = 100_000
+
+# fstring pool
+assert_equal "#{N}#{N}", %Q{
+ N = #{N}
+ 2.times.map{
+ Ractor.new{
+ N.times{|i| -(i.to_s)}
+ }
+ }.map{|r| r.take}.join
+}
+
+# enc_table
+assert_equal "#{N/10}", %Q{
+ Ractor.new do
+ loop do
+ Encoding.find("test-enc-#{rand(5_000)}").inspect
+ rescue ArgumentError => e
+ end
+ end
+
+ src = Encoding.find("UTF-8")
+ #{N/10}.times{|i|
+ src.replicate("test-enc-\#{i}")
+ }
+}
+
+# Generic ivtbl
+n = N/2
+assert_equal "#{n}#{n}", %Q{
+ 2.times.map{
+ Ractor.new do
+ #{n}.times do
+ obj = ''
+ obj.instance_variable_set("@a", 1)
+ obj.instance_variable_set("@b", 1)
+ obj.instance_variable_set("@c", 1)
+ obj.instance_variable_defined?("@a")
+ end
+ end
+ }.map{|r| r.take}.join
+}
+
+# NameError
+assert_equal "ok", %q{
+ begin
+ bar
+ rescue => err
+ end
+ begin
+ Ractor.new{} << err
+ rescue TypeError
+ 'ok'
+ end
+}
+
+# Can yield back values while GC is sweeping [Bug #18117]
+assert_equal "ok", %q{
+ workers = (0...8).map do
+ Ractor.new do
+ loop do
+ 10_000.times.map { Object.new }
+ Ractor.yield Time.now
+ end
+ end
+ end
+
+ 1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) }
+ "ok"
+}
+
+end # if !ENV['GITHUB_WORKFLOW']
diff --git a/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb
index a111990a1f..fa27bf2aeb 100644
--- a/bootstraptest/test_syntax.rb
+++ b/bootstraptest/test_syntax.rb
@@ -268,8 +268,10 @@ assert_equal %q{}, %q{
defined?(@@a)
}
assert_equal %q{class variable}, %q{
- @@a = 1
- defined?(@@a)
+ class A
+ @@a = 1
+ defined?(@@a)
+ end
}
assert_equal %q{}, %q{
defined?($a)
diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb
index d16295de8b..38a55ff229 100644
--- a/bootstraptest/test_thread.rb
+++ b/bootstraptest/test_thread.rb
@@ -1,4 +1,14 @@
-# Thread and Fiber
+show_limit %q{
+ threads = []
+ begin
+ threads << Thread.new{sleep}
+
+ raise Exception, "skipping" if threads.count >= 10_000
+ rescue Exception => error
+ puts "Thread count: #{threads.count} (#{error})"
+ break
+ end while true
+} if false # disable to pass CI
assert_equal %q{ok}, %q{
Thread.new{
@@ -36,7 +46,7 @@ begin
}
}
rescue ThreadError => e
- :ok if /can't create Thread/ =~ e.message
+ /can't create Thread/ =~ e.message ? :ok : e.message
end
}
assert_equal %q{ok}, %q{
@@ -50,7 +60,7 @@ begin
}
}
rescue ThreadError => e
- :ok if /can't create Thread/ =~ e.message
+ /can't create Thread/ =~ e.message ? :ok : e.message
end
}
assert_equal %q{ok}, %q{
@@ -299,10 +309,6 @@ assert_equal 'ok', %q{
}, '[ruby-dev:34492]'
assert_normal_exit %q{
- at_exit { Fiber.new{}.resume }
-}
-
-assert_normal_exit %q{
g = enum_for(:local_variables)
loop { g.next }
}, '[ruby-dev:34128]'
@@ -328,10 +334,6 @@ assert_normal_exit %q{
}, '[ruby-dev:34128]'
assert_normal_exit %q{
- Fiber.new(&Object.method(:class_eval)).resume("foo")
-}, '[ruby-dev:34128]'
-
-assert_normal_exit %q{
Thread.new("foo", &Object.method(:class_eval)).join
}, '[ruby-dev:34128]'
@@ -482,3 +484,17 @@ assert_equal 'foo', %q{
GC.start
f.call.source
}
+assert_normal_exit %q{
+ class C
+ def inspect
+ sleep 0.5
+ 'C!!'
+ end
+ end
+ Thread.new{
+ loop{
+ p C.new
+ }
+ }
+ sleep 0.1
+}, timeout: 5
diff --git a/builtin.c b/builtin.c
new file mode 100644
index 0000000000..7c3653dab7
--- /dev/null
+++ b/builtin.c
@@ -0,0 +1,69 @@
+#include "internal.h"
+#include "vm_core.h"
+#include "iseq.h"
+#include "builtin.h"
+
+#if CROSS_COMPILING
+
+#define INCLUDED_BY_BUILTIN_C 1
+#include "mini_builtin.c"
+
+#else
+
+#include "builtin_binary.inc"
+
+static const unsigned char *
+bin4feature(const struct builtin_binary *bb, const char *feature, size_t *psize)
+{
+ *psize = bb->bin_size;
+ return strcmp(bb->feature, feature) ? NULL : bb->bin;
+}
+
+static const unsigned char*
+builtin_lookup(const char *feature, size_t *psize)
+{
+ static int index = 0;
+ const unsigned char *bin = bin4feature(&builtin_binary[index++], feature, psize);
+
+ // usually, `builtin_binary` order is loading order at miniruby.
+ for (const struct builtin_binary *bb = &builtin_binary[0]; bb->feature &&! bin; bb++) {
+ bin = bin4feature(bb++, feature, psize);
+ }
+ return bin;
+}
+
+void
+rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
+{
+ // search binary
+ size_t size;
+ const unsigned char *bin = builtin_lookup(feature_name, &size);
+ if (! bin) {
+ rb_bug("builtin_lookup: can not find %s\n", feature_name);
+ }
+
+ // load binary
+ rb_vm_t *vm = GET_VM();
+ if (vm->builtin_function_table != NULL) rb_bug("vm->builtin_function_table should be NULL.");
+ vm->builtin_function_table = table;
+ vm->builtin_inline_index = 0;
+ const rb_iseq_t *iseq = rb_iseq_ibf_load_bytes((const char *)bin, size);
+ vm->builtin_function_table = NULL;
+
+ // exec
+ rb_iseq_eval(rb_iseq_check(iseq));
+}
+
+#endif
+
+void
+Init_builtin(void)
+{
+ // nothing
+}
+
+void
+Init_builtin_features(void)
+{
+ rb_load_with_builtin_functions("gem_prelude", NULL);
+}
diff --git a/builtin.h b/builtin.h
new file mode 100644
index 0000000000..3b2f477654
--- /dev/null
+++ b/builtin.h
@@ -0,0 +1,83 @@
+#ifndef BUILTIN_H_INCLUDED
+#define BUILTIN_H_INCLUDED
+
+// invoke
+
+struct rb_builtin_function {
+ // for invocation
+ const void * const func_ptr;
+ const int argc;
+
+ // for load
+ const int index;
+ const char * const name;
+
+ // for jit
+ void (*compiler)(FILE *, long, unsigned, bool);
+};
+
+#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity, _compiler) {\
+ .name = #_name, \
+ .func_ptr = (void *)_fname, \
+ .argc = _arity, \
+ .index = _i, \
+ .compiler = _compiler, \
+}
+
+void rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table);
+
+#ifndef rb_execution_context_t
+typedef struct rb_execution_context_struct rb_execution_context_t;
+#define rb_execution_context_t rb_execution_context_t
+#endif
+
+/* The following code is generated by the following Ruby script:
+
+16.times{|i|
+ args = (i > 0 ? ', ' : '') + (0...i).map{"VALUE"}.join(', ')
+ puts "static inline void rb_builtin_function_check_arity#{i}(VALUE (*f)(rb_execution_context_t *ec, VALUE self#{args})){}"
+}
+*/
+
+static inline void rb_builtin_function_check_arity0(VALUE (*f)(rb_execution_context_t *ec, VALUE self)){}
+static inline void rb_builtin_function_check_arity1(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE)){}
+static inline void rb_builtin_function_check_arity2(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity3(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity4(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity5(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity6(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity7(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity8(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity9(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity10(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity11(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity12(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity13(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity14(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+static inline void rb_builtin_function_check_arity15(VALUE (*f)(rb_execution_context_t *ec, VALUE self, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)){}
+
+VALUE rb_vm_lvar_exposed(rb_execution_context_t *ec, int index);
+
+// __builtin_inline!
+
+PUREFUNC(static inline VALUE rb_vm_lvar(rb_execution_context_t *ec, int index));
+
+static inline VALUE
+rb_vm_lvar(rb_execution_context_t *ec, int index)
+{
+#if VM_CORE_H_EC_DEFINED
+ return ec->cfp->ep[index];
+#else
+ return rb_vm_lvar_exposed(ec, index);
+#endif
+}
+
+// dump/load
+
+struct builtin_binary {
+ const char *feature; // feature name
+ const unsigned char *bin; // binary by ISeq#to_binary
+ size_t bin_size;
+};
+
+#endif // BUILTIN_H_INCLUDED
diff --git a/ccan/list/list.h b/ccan/list/list.h
index ca9f9f1f7f..7d219307bc 100644
--- a/ccan/list/list.h
+++ b/ccan/list/list.h
@@ -57,7 +57,7 @@ struct list_head
* Example:
* static struct list_head my_list = LIST_HEAD_INIT(my_list);
*/
-#define LIST_HEAD_INIT(name) { { &name.n, &name.n } }
+#define LIST_HEAD_INIT(name) { { &(name).n, &(name).n } }
/**
* LIST_HEAD - define and initialize an empty list_head
@@ -238,6 +238,21 @@ static inline int list_empty_nodebug(const struct list_head *h)
#endif
/**
+ * list_empty_nocheck - is a list empty?
+ * @h: the list_head
+ *
+ * If the list is empty, returns true. This doesn't perform any
+ * debug check for list consistency, so it can be called without
+ * locks, racing with the list being modified. This is ok for
+ * checks where an incorrect result is not an issue (optimized
+ * bail out path for example).
+ */
+static inline bool list_empty_nocheck(const struct list_head *h)
+{
+ return h->n.next == &h->n;
+}
+
+/**
* list_del - delete an entry from an (unknown) linked list.
* @n: the list_node to delete from the list.
*
@@ -639,7 +654,7 @@ static inline void list_prepend_list_(struct list_head *to,
/**
* list_for_each_off - iterate through a list of memory regions.
* @h: the list_head
- * @i: the pointer to a memory region wich contains list node data.
+ * @i: the pointer to a memory region which contains list node data.
* @off: offset(relative to @i) at which list node data resides.
*
* This is a low-level wrapper to iterate @i over the entire list, used to
@@ -647,12 +662,12 @@ static inline void list_prepend_list_(struct list_head *to,
* so you can break and continue as normal.
*
* WARNING! Being the low-level macro that it is, this wrapper doesn't know
- * nor care about the type of @i. The only assumtion made is that @i points
+ * nor care about the type of @i. The only assumption made is that @i points
* to a chunk of memory that at some @offset, relative to @i, contains a
- * properly filled `struct node_list' which in turn contains pointers to
- * memory chunks and it's turtles all the way down. Whith all that in mind
+ * properly filled `struct list_node' which in turn contains pointers to
+ * memory chunks and it's turtles all the way down. With all that in mind
* remember that given the wrong pointer/offset couple this macro will
- * happilly churn all you memory untill SEGFAULT stops it, in other words
+ * happily churn all you memory until SEGFAULT stops it, in other words
* caveat emptor.
*
* It is worth mentioning that one of legitimate use-cases for that wrapper
@@ -671,7 +686,7 @@ static inline void list_prepend_list_(struct list_head *to,
/**
* list_for_each_rev_off - iterate through a list of memory regions backwards
* @h: the list_head
- * @i: the pointer to a memory region wich contains list node data.
+ * @i: the pointer to a memory region which contains list node data.
* @off: offset(relative to @i) at which list node data resides.
*
* See list_for_each_off for details
@@ -683,7 +698,7 @@ static inline void list_prepend_list_(struct list_head *to,
* list_for_each_safe_off - iterate through a list of memory regions, maybe
* during deletion
* @h: the list_head
- * @i: the pointer to a memory region wich contains list node data.
+ * @i: the pointer to a memory region which contains list node data.
* @nxt: the structure containing the list_node
* @off: offset(relative to @i) at which list node data resides.
*
@@ -702,7 +717,7 @@ static inline void list_prepend_list_(struct list_head *to,
* list_for_each_rev_safe_off - iterate backwards through a list of
* memory regions, maybe during deletion
* @h: the list_head
- * @i: the pointer to a memory region wich contains list node data.
+ * @i: the pointer to a memory region which contains list node data.
* @nxt: the structure containing the list_node
* @off: offset(relative to @i) at which list node data resides.
*
diff --git a/class.c b/class.c
index 364f258333..682a21d488 100644
--- a/class.c
+++ b/class.c
@@ -23,15 +23,27 @@
* \{
*/
+#include "ruby/internal/config.h"
+#include <ctype.h>
+
+#include "gc.h"
+#include "constant.h"
+#include "id_table.h"
#include "internal.h"
+#include "internal/class.h"
+#include "internal/eval.h"
+#include "internal/hash.h"
+#include "internal/object.h"
+#include "internal/string.h"
+#include "internal/variable.h"
#include "ruby/st.h"
-#include "constant.h"
#include "vm_core.h"
-#include "id_table.h"
-#include <ctype.h>
#define id_attached id__attached__
+#define METACLASS_OF(k) RBASIC(k)->klass
+#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
+
void
rb_class_subclass_add(VALUE super, VALUE klass)
{
@@ -176,7 +188,7 @@ class_alloc(VALUE flags, VALUE klass)
*/
RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
RCLASS_SERIAL(obj) = rb_next_class_serial();
- RCLASS_REFINED_CLASS(obj) = Qnil;
+ RB_OBJ_WRITE(obj, &RCLASS_REFINED_CLASS(obj), Qnil);
RCLASS_EXT(obj)->allocator = 0;
return (VALUE)obj;
@@ -205,7 +217,6 @@ rb_class_boot(VALUE super)
RCLASS_SET_SUPER(klass, super);
RCLASS_M_TBL_INIT(klass);
- OBJ_INFECT(klass, super);
return (VALUE)klass;
}
@@ -220,7 +231,7 @@ void
rb_check_inheritable(VALUE super)
{
if (!RB_TYPE_P(super, T_CLASS)) {
- rb_raise(rb_eTypeError, "superclass must be a Class (%"PRIsVALUE" given)",
+ rb_raise(rb_eTypeError, "superclass must be an instance of Class (given an instance of %"PRIsVALUE")",
rb_obj_class(super));
}
if (RBASIC(super)->flags & FL_SINGLETON) {
@@ -309,20 +320,9 @@ class_init_copy_check(VALUE clone, VALUE orig)
}
}
-/* :nodoc: */
-VALUE
-rb_mod_init_copy(VALUE clone, VALUE orig)
+static void
+copy_tables(VALUE clone, VALUE orig)
{
- if (RB_TYPE_P(clone, T_CLASS)) {
- class_init_copy_check(clone, orig);
- }
- if (!OBJ_INIT_COPY(clone, orig)) return clone;
- if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
- RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
- rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
- }
- RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
- RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
if (RCLASS_IV_TBL(clone)) {
st_free_table(RCLASS_IV_TBL(clone));
RCLASS_IV_TBL(clone) = 0;
@@ -335,7 +335,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
if (RCLASS_IV_TBL(orig)) {
st_data_t id;
- RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(orig));
+ rb_iv_tbl_copy(clone, orig);
CONST_ID(id, "__tmp_classpath__");
st_delete(RCLASS_IV_TBL(clone), &id, 0);
CONST_ID(id, "__classpath__");
@@ -350,6 +350,31 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
arg.klass = clone;
rb_id_table_foreach(RCLASS_CONST_TBL(orig), clone_const_i, &arg);
}
+}
+
+static void ensure_origin(VALUE klass);
+
+/* :nodoc: */
+VALUE
+rb_mod_init_copy(VALUE clone, VALUE orig)
+{
+ if (RB_TYPE_P(clone, T_CLASS)) {
+ class_init_copy_check(clone, orig);
+ }
+ if (!OBJ_INIT_COPY(clone, orig)) return clone;
+
+ /* cloned flag is refer at constant inline cache
+ * see vm_get_const_key_cref() in vm_insnhelper.c
+ */
+ FL_SET(clone, RCLASS_CLONED);
+ FL_SET(orig , RCLASS_CLONED);
+
+ if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
+ RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
+ rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
+ }
+ RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
+ copy_tables(clone, orig);
if (RCLASS_M_TBL(orig)) {
struct clone_method_arg arg;
arg.old_klass = orig;
@@ -358,6 +383,75 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
rb_id_table_foreach(RCLASS_M_TBL(orig), clone_method_i, &arg);
}
+ if (RCLASS_ORIGIN(orig) == orig) {
+ RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
+ }
+ else {
+ VALUE p = RCLASS_SUPER(orig);
+ VALUE orig_origin = RCLASS_ORIGIN(orig);
+ VALUE prev_clone_p = clone;
+ VALUE origin_stack = rb_ary_tmp_new(2);
+ VALUE origin[2];
+ VALUE clone_p = 0;
+ long origin_len;
+ int add_subclass;
+ VALUE clone_origin;
+
+ ensure_origin(clone);
+ clone_origin = RCLASS_ORIGIN(clone);
+
+ while (p && p != orig_origin) {
+ if (BUILTIN_TYPE(p) != T_ICLASS) {
+ rb_bug("non iclass between module/class and origin");
+ }
+ clone_p = class_alloc(RBASIC(p)->flags, RBASIC(p)->klass);
+ RCLASS_SET_SUPER(prev_clone_p, clone_p);
+ prev_clone_p = clone_p;
+ RCLASS_M_TBL(clone_p) = RCLASS_M_TBL(p);
+ RCLASS_CONST_TBL(clone_p) = RCLASS_CONST_TBL(p);
+ RCLASS_IV_TBL(clone_p) = RCLASS_IV_TBL(p);
+ RCLASS_EXT(clone_p)->allocator = RCLASS_EXT(p)->allocator;
+ if (RB_TYPE_P(clone, T_CLASS)) {
+ RCLASS_SET_INCLUDER(clone_p, clone);
+ }
+ add_subclass = TRUE;
+ if (p != RCLASS_ORIGIN(p)) {
+ origin[0] = clone_p;
+ origin[1] = RCLASS_ORIGIN(p);
+ rb_ary_cat(origin_stack, origin, 2);
+ }
+ else if ((origin_len = RARRAY_LEN(origin_stack)) > 1 &&
+ RARRAY_AREF(origin_stack, origin_len - 1) == p) {
+ RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), clone_p);
+ RICLASS_SET_ORIGIN_SHARED_MTBL(clone_p);
+ rb_ary_resize(origin_stack, origin_len);
+ add_subclass = FALSE;
+ }
+ if (add_subclass) {
+ rb_module_add_to_subclasses_list(RBASIC(p)->klass, clone_p);
+ }
+ p = RCLASS_SUPER(p);
+ }
+
+ if (p == orig_origin) {
+ if (clone_p) {
+ RCLASS_SET_SUPER(clone_p, clone_origin);
+ RCLASS_SET_SUPER(clone_origin, RCLASS_SUPER(orig_origin));
+ }
+ copy_tables(clone_origin, orig_origin);
+ if (RCLASS_M_TBL(orig_origin)) {
+ struct clone_method_arg arg;
+ arg.old_klass = orig;
+ arg.new_klass = clone;
+ RCLASS_M_TBL_INIT(clone_origin);
+ rb_id_table_foreach(RCLASS_M_TBL(orig_origin), clone_method_i, &arg);
+ }
+ }
+ else {
+ rb_bug("no origin for class that has origin");
+ }
+ }
+
return clone;
}
@@ -367,28 +461,41 @@ rb_singleton_class_clone(VALUE obj)
return rb_singleton_class_clone_and_attach(obj, Qundef);
}
+// Clone and return the singleton class of `obj` if it has been created and is attached to `obj`.
VALUE
rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
{
const VALUE klass = RBASIC(obj)->klass;
- if (!FL_TEST(klass, FL_SINGLETON))
- return klass;
+ // Note that `rb_singleton_class()` can create situations where `klass` is
+ // attached to an object other than `obj`. In which case `obj` does not have
+ // a material singleton class attached yet and there is no singleton class
+ // to clone.
+ if (!(FL_TEST(klass, FL_SINGLETON) && rb_attr_get(klass, id_attached) == obj)) {
+ // nothing to clone
+ return klass;
+ }
else {
/* copy singleton(unnamed) class */
+ bool klass_of_clone_is_new;
VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
if (BUILTIN_TYPE(obj) == T_CLASS) {
+ klass_of_clone_is_new = true;
RBASIC_SET_CLASS(clone, clone);
}
else {
- RBASIC_SET_CLASS(clone, rb_singleton_class_clone(klass));
+ VALUE klass_metaclass_clone = rb_singleton_class_clone(klass);
+ // When `METACLASS_OF(klass) == klass_metaclass_clone`, it means the
+ // recursive call did not clone `METACLASS_OF(klass)`.
+ klass_of_clone_is_new = (METACLASS_OF(klass) != klass_metaclass_clone);
+ RBASIC_SET_CLASS(clone, klass_metaclass_clone);
}
RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
if (RCLASS_IV_TBL(klass)) {
- RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(klass));
+ rb_iv_tbl_copy(clone, klass);
}
if (RCLASS_CONST_TBL(klass)) {
struct clone_const_arg arg;
@@ -406,7 +513,9 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
arg.new_klass = clone;
rb_id_table_foreach(RCLASS_M_TBL(klass), clone_method_i, &arg);
}
- rb_singleton_class_attached(RBASIC(clone)->klass, clone);
+ if (klass_of_clone_is_new) {
+ rb_singleton_class_attached(RBASIC(clone)->klass, clone);
+ }
FL_SET(clone, FL_SINGLETON);
return clone;
@@ -428,11 +537,6 @@ rb_singleton_class_attached(VALUE klass, VALUE obj)
}
}
-
-
-#define METACLASS_OF(k) RBASIC(k)->klass
-#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
-
/*!
* whether k is a meta^(n)-class of Class class
* @retval 1 if \a k is a meta^(n)-class of Class class (n >= 0)
@@ -505,8 +609,6 @@ make_metaclass(VALUE klass)
while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass);
- OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
-
return metaclass;
}
@@ -537,8 +639,8 @@ boot_defclass(const char *name, VALUE super)
VALUE obj = rb_class_boot(super);
ID id = rb_intern(name);
- rb_name_class(obj, id);
rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
+ rb_vm_add_root_module(obj);
return obj;
}
@@ -550,7 +652,7 @@ Init_class_hierarchy(void)
rb_gc_register_mark_object(rb_cObject);
/* resolve class name ASAP for order-independence */
- rb_class_name(rb_cObject);
+ rb_set_class_path_string(rb_cObject, rb_cObject, rb_fstring_lit("Object"));
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
@@ -616,7 +718,7 @@ rb_define_class_id(ID id, VALUE super)
* \return the value \c Class#inherited's returns
* \pre Each of \a super and \a klass must be a \c Class object.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_class_inherited(VALUE super, VALUE klass)
{
ID inherited;
@@ -658,14 +760,16 @@ rb_define_class(const char *name, VALUE super)
if (rb_class_real(RCLASS_SUPER(klass)) != super) {
rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
}
+
+ /* Class may have been defined in Ruby and not pin-rooted */
+ rb_vm_add_root_module(klass);
return klass;
}
if (!super) {
rb_raise(rb_eArgError, "no super class for `%s'", name);
}
klass = rb_define_class_id(id, super);
- rb_vm_add_root_module(id, klass);
- rb_name_class(klass, id);
+ rb_vm_add_root_module(klass);
rb_const_set(rb_cObject, id, klass);
rb_class_inherited(super, klass);
@@ -730,6 +834,9 @@ rb_define_class_id_under(VALUE outer, ID id, VALUE super)
" (%"PRIsVALUE" is given but was %"PRIsVALUE")",
outer, rb_id2str(id), RCLASS_SUPER(klass), super);
}
+ /* Class may have been defined in Ruby and not pin-rooted */
+ rb_vm_add_root_module(klass);
+
return klass;
}
if (!super) {
@@ -740,7 +847,7 @@ rb_define_class_id_under(VALUE outer, ID id, VALUE super)
rb_set_class_path_string(klass, outer, rb_id2str(id));
rb_const_set(outer, id, klass);
rb_class_inherited(super, klass);
- rb_gc_register_mark_object(klass);
+ rb_vm_add_root_module(klass);
return klass;
}
@@ -753,15 +860,11 @@ rb_module_new(void)
return (VALUE)mdl;
}
+// Kept for compatibility. Use rb_module_new() instead.
VALUE
rb_define_module_id(ID id)
{
- VALUE mdl;
-
- mdl = rb_module_new();
- rb_name_class(mdl, id);
-
- return mdl;
+ return rb_module_new();
}
VALUE
@@ -777,10 +880,12 @@ rb_define_module(const char *name)
rb_raise(rb_eTypeError, "%s is not a module (%"PRIsVALUE")",
name, rb_obj_class(module));
}
+ /* Module may have been defined in Ruby and not pin-rooted */
+ rb_vm_add_root_module(module);
return module;
}
- module = rb_define_module_id(id);
- rb_vm_add_root_module(id, module);
+ module = rb_module_new();
+ rb_vm_add_root_module(module);
rb_const_set(rb_cObject, id, module);
return module;
@@ -806,7 +911,7 @@ rb_define_module_id_under(VALUE outer, ID id)
}
return module;
}
- module = rb_define_module_id(id);
+ module = rb_module_new();
rb_const_set(outer, id, module);
rb_set_class_path_string(module, outer, rb_id2str(id));
rb_gc_register_mark_object(module);
@@ -819,9 +924,13 @@ rb_include_class_new(VALUE module, VALUE super)
{
VALUE klass = class_alloc(T_ICLASS, rb_cClass);
+ RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
+
+ RCLASS_SET_ORIGIN(klass, klass);
if (BUILTIN_TYPE(module) == T_ICLASS) {
module = RBASIC(module)->klass;
}
+ RUBY_ASSERT(!RB_TYPE_P(module, T_ICLASS));
if (!RCLASS_IV_TBL(module)) {
RCLASS_IV_TBL(module) = st_init_numtable();
}
@@ -831,18 +940,8 @@ rb_include_class_new(VALUE module, VALUE super)
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
- RCLASS_M_TBL(OBJ_WB_UNPROTECT(klass)) =
- RCLASS_M_TBL(OBJ_WB_UNPROTECT(RCLASS_ORIGIN(module))); /* TODO: unprotected? */
-
RCLASS_SET_SUPER(klass, super);
- if (RB_TYPE_P(module, T_ICLASS)) {
- RBASIC_SET_CLASS(klass, RBASIC(module)->klass);
- }
- else {
- RBASIC_SET_CLASS(klass, module);
- }
- OBJ_INFECT(klass, module);
- OBJ_INFECT(klass, super);
+ RBASIC_SET_CLASS(klass, module);
return (VALUE)klass;
}
@@ -852,12 +951,11 @@ static int include_modules_at(const VALUE klass, VALUE c, VALUE module, int sear
static void
ensure_includable(VALUE klass, VALUE module)
{
- rb_frozen_class_p(klass);
+ rb_class_modify_check(klass);
Check_Type(module, T_MODULE);
if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
rb_raise(rb_eArgError, "refinement module is not allowed");
}
- OBJ_INFECT(klass, module);
}
void
@@ -870,6 +968,31 @@ rb_include_module(VALUE klass, VALUE module)
changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
if (changed < 0)
rb_raise(rb_eArgError, "cyclic include detected");
+
+ if (RB_TYPE_P(klass, T_MODULE)) {
+ rb_subclass_entry_t *iclass = RCLASS_EXT(klass)->subclasses;
+ int do_include = 1;
+ while (iclass) {
+ VALUE check_class = iclass->klass;
+ /* During lazy sweeping, iclass->klass could be a dead object that
+ * has not yet been swept. */
+ if (!rb_objspace_garbage_object_p(check_class)) {
+ while (check_class) {
+ if (RB_TYPE_P(check_class, T_ICLASS) &&
+ (RBASIC(check_class)->klass == module)) {
+ do_include = 0;
+ }
+ check_class = RCLASS_SUPER(check_class);
+ }
+
+ if (do_include) {
+ include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE);
+ }
+ }
+
+ iclass = iclass->next;
+ }
+ }
}
static enum rb_id_table_iterator_result
@@ -879,27 +1002,40 @@ add_refined_method_entry_i(ID key, VALUE value, void *data)
return ID_TABLE_CONTINUE;
}
+static enum rb_id_table_iterator_result
+clear_module_cache_i(ID id, VALUE val, void *data)
+{
+ VALUE klass = (VALUE)data;
+ rb_clear_method_cache(klass, id);
+ return ID_TABLE_CONTINUE;
+}
+
static int
include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super)
{
- VALUE p, iclass;
- int method_changed = 0, constant_changed = 0;
+ VALUE p, iclass, origin_stack = 0;
+ int method_changed = 0, constant_changed = 0, add_subclass;
+ long origin_len;
struct rb_id_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
+ VALUE original_klass = klass;
while (module) {
+ int origin_seen = FALSE;
int superclass_seen = FALSE;
struct rb_id_table *tbl;
- if (RCLASS_ORIGIN(module) != module)
- goto skip;
+ if (klass == c)
+ origin_seen = TRUE;
if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module))
return -1;
/* ignore if the module included already in superclasses */
- for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
+ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
int type = BUILTIN_TYPE(p);
+ if (c == p)
+ origin_seen = TRUE;
if (type == T_ICLASS) {
if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
- if (!superclass_seen) {
+ if (!superclass_seen && origin_seen) {
c = p; /* move insertion point */
}
goto skip;
@@ -907,36 +1043,66 @@ include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super)
}
else if (type == T_CLASS) {
if (!search_super) break;
- superclass_seen = TRUE;
+ superclass_seen = TRUE;
}
}
- iclass = rb_include_class_new(module, RCLASS_SUPER(c));
+
+ VALUE super_class = RCLASS_SUPER(c);
+
+ // invalidate inline method cache
+ tbl = RCLASS_M_TBL(module);
+ if (tbl && rb_id_table_size(tbl)) {
+ if (search_super) { // include
+ if (super_class && !RB_TYPE_P(super_class, T_MODULE)) {
+ rb_id_table_foreach(tbl, clear_module_cache_i, (void *)super_class);
+ }
+ }
+ else { // prepend
+ if (!RB_TYPE_P(original_klass, T_MODULE)) {
+ rb_id_table_foreach(tbl, clear_module_cache_i, (void *)original_klass);
+ }
+ }
+ method_changed = 1;
+ }
+
+ // setup T_ICLASS for the include/prepend module
+ iclass = rb_include_class_new(module, super_class);
c = RCLASS_SET_SUPER(c, iclass);
+ RCLASS_SET_INCLUDER(iclass, klass);
+ add_subclass = TRUE;
+ if (module != RCLASS_ORIGIN(module)) {
+ if (!origin_stack) origin_stack = rb_ary_tmp_new(2);
+ VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)};
+ rb_ary_cat(origin_stack, origin, 2);
+ }
+ else if (origin_stack && (origin_len = RARRAY_LEN(origin_stack)) > 1 &&
+ RARRAY_AREF(origin_stack, origin_len - 1) == module) {
+ RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
+ RICLASS_SET_ORIGIN_SHARED_MTBL(iclass);
+ rb_ary_resize(origin_stack, origin_len);
+ add_subclass = FALSE;
+ }
{
VALUE m = module;
- if (BUILTIN_TYPE(m) == T_ICLASS) m = RBASIC(m)->klass;
- rb_module_add_to_subclasses_list(m, iclass);
+ if (BUILTIN_TYPE(m) == T_ICLASS) m = RBASIC(m)->klass;
+ if (add_subclass) rb_module_add_to_subclasses_list(m, iclass);
}
if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
VALUE refined_class =
rb_refinement_module_get_refined_class(klass);
- rb_id_table_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i, (void *)refined_class);
+ rb_id_table_foreach(RCLASS_M_TBL(module), add_refined_method_entry_i, (void *)refined_class);
FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT);
}
- tbl = RMODULE_M_TBL(module);
- if (tbl && rb_id_table_size(tbl)) method_changed = 1;
-
- tbl = RMODULE_CONST_TBL(module);
+ tbl = RCLASS_CONST_TBL(module);
if (tbl && rb_id_table_size(tbl)) constant_changed = 1;
skip:
module = RCLASS_SUPER(module);
}
- if (method_changed) rb_clear_method_cache_by_class(klass);
if (constant_changed) rb_clear_constant_cache();
return method_changed;
@@ -945,22 +1111,22 @@ include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super)
static enum rb_id_table_iterator_result
move_refined_method(ID key, VALUE value, void *data)
{
- rb_method_entry_t *me = (rb_method_entry_t *) value;
- VALUE klass = (VALUE)data;
- struct rb_id_table *tbl = RCLASS_M_TBL(klass);
+ rb_method_entry_t *me = (rb_method_entry_t *)value;
if (me->def->type == VM_METHOD_TYPE_REFINED) {
- if (me->def->body.refined.orig_me) {
+ VALUE klass = (VALUE)data;
+ struct rb_id_table *tbl = RCLASS_M_TBL(klass);
+
+ if (me->def->body.refined.orig_me) {
const rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me;
RB_OBJ_WRITE(me, &me->def->body.refined.orig_me, NULL);
new_me = rb_method_entry_clone(me);
- rb_id_table_insert(tbl, key, (VALUE)new_me);
- RB_OBJ_WRITTEN(klass, Qundef, new_me);
+ rb_method_table_insert(klass, tbl, key, new_me);
rb_method_entry_copy(me, orig_me);
return ID_TABLE_CONTINUE;
}
else {
- rb_id_table_insert(tbl, key, (VALUE)me);
+ rb_method_table_insert(klass, tbl, key, me);
return ID_TABLE_DELETE;
}
}
@@ -969,48 +1135,98 @@ move_refined_method(ID key, VALUE value, void *data)
}
}
-void
-rb_prepend_module(VALUE klass, VALUE module)
+static enum rb_id_table_iterator_result
+cache_clear_refined_method(ID key, VALUE value, void *data)
{
- VALUE origin;
- int changed = 0;
+ rb_method_entry_t *me = (rb_method_entry_t *) value;
- ensure_includable(klass, module);
+ if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
+ VALUE klass = (VALUE)data;
+ rb_clear_method_cache(klass, me->called_id);
+ }
+ // Refined method entries without an orig_me is going to stay in the method
+ // table of klass, like before the move, so no need to clear the cache.
- origin = RCLASS_ORIGIN(klass);
+ return ID_TABLE_CONTINUE;
+}
+
+static void
+ensure_origin(VALUE klass)
+{
+ VALUE origin = RCLASS_ORIGIN(klass);
if (origin == klass) {
origin = class_alloc(T_ICLASS, klass);
- OBJ_WB_UNPROTECT(origin); /* TODO: conservative shading. Need more survey. */
RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass));
RCLASS_SET_SUPER(klass, origin);
RCLASS_SET_ORIGIN(klass, origin);
RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
RCLASS_M_TBL_INIT(klass);
+ rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass);
rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);
}
+}
+
+void
+rb_prepend_module(VALUE klass, VALUE module)
+{
+ int changed = 0;
+ bool klass_had_no_origin = RCLASS_ORIGIN(klass) == klass;
+
+ ensure_includable(klass, module);
+ ensure_origin(klass);
changed = include_modules_at(klass, klass, module, FALSE);
if (changed < 0)
rb_raise(rb_eArgError, "cyclic prepend detected");
if (changed) {
rb_vm_check_redefinition_by_prepend(klass);
}
+ if (RB_TYPE_P(klass, T_MODULE)) {
+ rb_subclass_entry_t *iclass = RCLASS_EXT(klass)->subclasses;
+ VALUE klass_origin = RCLASS_ORIGIN(klass);
+ struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass);
+ struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin);
+ while (iclass) {
+ /* During lazy sweeping, iclass->klass could be a dead object that
+ * has not yet been swept. */
+ if (!rb_objspace_garbage_object_p(iclass->klass)) {
+ if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(iclass->klass)) {
+ // backfill an origin iclass to handle refinements and future prepends
+ rb_id_table_foreach(RCLASS_M_TBL(iclass->klass), clear_module_cache_i, (void *)iclass->klass);
+ RCLASS_M_TBL(iclass->klass) = klass_m_tbl;
+ VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(iclass->klass));
+ RCLASS_SET_SUPER(iclass->klass, origin);
+ RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(iclass->klass));
+ RCLASS_SET_ORIGIN(iclass->klass, origin);
+ RICLASS_SET_ORIGIN_SHARED_MTBL(origin);
+ }
+ include_modules_at(iclass->klass, iclass->klass, module, FALSE);
+ }
+
+ iclass = iclass->next;
+ }
+ }
}
/*
* call-seq:
* mod.included_modules -> array
*
- * Returns the list of modules included in <i>mod</i>.
+ * Returns the list of modules included or prepended in <i>mod</i>
+ * or one of <i>mod</i>'s ancestors.
+ *
+ * module Sub
+ * end
*
* module Mixin
+ * prepend Sub
* end
*
* module Outer
* include Mixin
* end
*
- * Mixin.included_modules #=> []
- * Outer.included_modules #=> [Mixin]
+ * Mixin.included_modules #=> [Sub]
+ * Outer.included_modules #=> [Sub, Mixin]
*/
VALUE
@@ -1021,7 +1237,7 @@ rb_mod_included_modules(VALUE mod)
VALUE origin = RCLASS_ORIGIN(mod);
for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
- if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) {
+ if (p != origin && RCLASS_ORIGIN(p) == p && BUILTIN_TYPE(p) == T_ICLASS) {
VALUE m = RBASIC(p)->klass;
if (RB_TYPE_P(m, T_MODULE))
rb_ary_push(ary, m);
@@ -1034,8 +1250,8 @@ rb_mod_included_modules(VALUE mod)
* call-seq:
* mod.include?(module) -> true or false
*
- * Returns <code>true</code> if <i>module</i> is included in
- * <i>mod</i> or one of <i>mod</i>'s ancestors.
+ * Returns <code>true</code> if <i>module</i> is included
+ * or prepended in <i>mod</i> or one of <i>mod</i>'s ancestors.
*
* module A
* end
@@ -1056,7 +1272,7 @@ rb_mod_include_p(VALUE mod, VALUE mod2)
Check_Type(mod2, T_MODULE);
for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
- if (BUILTIN_TYPE(p) == T_ICLASS) {
+ if (BUILTIN_TYPE(p) == T_ICLASS && !FL_TEST(p, RICLASS_IS_ORIGIN)) {
if (RBASIC(p)->klass == mod2) return Qtrue;
}
}
@@ -1087,10 +1303,11 @@ rb_mod_ancestors(VALUE mod)
VALUE p, ary = rb_ary_new();
for (p = mod; p; p = RCLASS_SUPER(p)) {
+ if (p != RCLASS_ORIGIN(p)) continue;
if (BUILTIN_TYPE(p) == T_ICLASS) {
rb_ary_push(ary, RBASIC(p)->klass);
}
- else if (p == RCLASS_ORIGIN(p)) {
+ else {
rb_ary_push(ary, p);
}
}
@@ -1162,7 +1379,7 @@ method_entry_i(ID key, VALUE value, void *data)
if (!me) return ID_TABLE_CONTINUE;
if (!arg->recur && me->owner != owner) return ID_TABLE_CONTINUE;
}
- if (!st_lookup(arg->list, key, 0)) {
+ if (!st_is_member(arg->list, key)) {
if (UNDEFINED_METHOD_ENTRY_P(me)) {
type = METHOD_VISI_UNDEF; /* none */
}
@@ -1174,20 +1391,39 @@ method_entry_i(ID key, VALUE value, void *data)
return ID_TABLE_CONTINUE;
}
+static void
+add_instance_method_list(VALUE mod, struct method_entry_arg *me_arg)
+{
+ struct rb_id_table *m_tbl = RCLASS_M_TBL(mod);
+ if (!m_tbl) return;
+ rb_id_table_foreach(m_tbl, method_entry_i, me_arg);
+}
+
+static bool
+particular_class_p(VALUE mod)
+{
+ if (!mod) return false;
+ if (FL_TEST(mod, FL_SINGLETON)) return true;
+ if (BUILTIN_TYPE(mod) == T_ICLASS) return true;
+ return false;
+}
+
static VALUE
class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
{
VALUE ary;
- int recur, prepended = 0;
+ int recur = TRUE, prepended = 0;
struct method_entry_arg me_arg;
- if (argc == 0) {
- recur = TRUE;
- }
- else {
- VALUE r;
- rb_scan_args(argc, argv, "01", &r);
- recur = RTEST(r);
+ if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
+
+ me_arg.list = st_init_numtable();
+ me_arg.recur = recur;
+
+ if (obj) {
+ for (; particular_class_p(mod); mod = RCLASS_SUPER(mod)) {
+ add_instance_method_list(mod, &me_arg);
+ }
}
if (!recur && RCLASS_ORIGIN(mod) != mod) {
@@ -1195,15 +1431,12 @@ class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int
prepended = 1;
}
- me_arg.list = st_init_numtable();
- me_arg.recur = recur;
for (; mod; mod = RCLASS_SUPER(mod)) {
- if (RCLASS_M_TBL(mod)) rb_id_table_foreach(RCLASS_M_TBL(mod), method_entry_i, &me_arg);
+ add_instance_method_list(mod, &me_arg);
if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
- if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
if (!recur) break;
}
- ary = rb_ary_new();
+ ary = rb_ary_new2(me_arg.list->num_entries);
st_foreach(me_arg.list, func, ary);
st_free_table(me_arg.list);
@@ -1304,7 +1537,7 @@ rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod)
* <i>obj</i>. This will include all the methods accessible in
* <i>obj</i>'s ancestors.
* If the optional parameter is <code>false</code>, it
- * returns an array of <i>obj<i>'s public and protected singleton methods,
+ * returns an array of <i>obj</i>'s public and protected singleton methods,
* the array will not include methods in modules included in <i>obj</i>.
*
* class Klass
@@ -1417,31 +1650,30 @@ rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj)
VALUE
rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
{
- VALUE recur, ary, klass, origin;
+ VALUE ary, klass, origin;
struct method_entry_arg me_arg;
struct rb_id_table *mtbl;
+ int recur = TRUE;
- if (argc == 0) {
- recur = Qtrue;
- }
- else {
- rb_scan_args(argc, argv, "01", &recur);
+ if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
+ if (RB_TYPE_P(obj, T_CLASS) && FL_TEST(obj, FL_SINGLETON)) {
+ rb_singleton_class(obj);
}
klass = CLASS_OF(obj);
origin = RCLASS_ORIGIN(klass);
me_arg.list = st_init_numtable();
- me_arg.recur = RTEST(recur);
+ me_arg.recur = recur;
if (klass && FL_TEST(klass, FL_SINGLETON)) {
if ((mtbl = RCLASS_M_TBL(origin)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
klass = RCLASS_SUPER(klass);
}
- if (RTEST(recur)) {
+ if (recur) {
while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
klass = RCLASS_SUPER(klass);
}
}
- ary = rb_ary_new();
+ ary = rb_ary_new2(me_arg.list->num_entries);
st_foreach(me_arg.list, ins_methods_i, ary);
st_free_table(me_arg.list);
@@ -1505,24 +1737,36 @@ rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
* \{
*/
+#ifdef rb_define_method_id
+#undef rb_define_method_id
+#endif
void
rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
{
rb_add_method_cfunc(klass, mid, func, argc, METHOD_VISI_PUBLIC);
}
+#ifdef rb_define_method
+#undef rb_define_method
+#endif
void
rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PUBLIC);
}
+#ifdef rb_define_protected_method
+#undef rb_define_protected_method
+#endif
void
rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PROTECTED);
}
+#ifdef rb_define_private_method
+#undef rb_define_private_method
+#endif
void
rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
@@ -1560,19 +1804,15 @@ rb_undef_methods_from(VALUE klass, VALUE super)
* \{
*/
-#define SPECIAL_SINGLETON(x,c) do {\
- if (obj == (x)) {\
- return (c);\
- }\
-} while (0)
-
static inline VALUE
special_singleton_class_of(VALUE obj)
{
- SPECIAL_SINGLETON(Qnil, rb_cNilClass);
- SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
- SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
- return Qnil;
+ switch (obj) {
+ case Qnil: return rb_cNilClass;
+ case Qfalse: return rb_cFalseClass;
+ case Qtrue: return rb_cTrueClass;
+ default: return Qnil;
+ }
}
VALUE
@@ -1595,40 +1835,35 @@ singleton_class_of(VALUE obj)
{
VALUE klass;
- if (FIXNUM_P(obj) || FLONUM_P(obj) || STATIC_SYM_P(obj)) {
- no_singleton:
+ switch (TYPE(obj)) {
+ case T_FIXNUM:
+ case T_BIGNUM:
+ case T_FLOAT:
+ case T_SYMBOL:
rb_raise(rb_eTypeError, "can't define singleton");
- }
- if (SPECIAL_CONST_P(obj)) {
+
+ case T_FALSE:
+ case T_TRUE:
+ case T_NIL:
klass = special_singleton_class_of(obj);
if (NIL_P(klass))
rb_bug("unknown immediate %p", (void *)obj);
return klass;
- }
- else {
- switch (BUILTIN_TYPE(obj)) {
- case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
- goto no_singleton;
- case T_STRING:
- if (FL_TEST_RAW(obj, RSTRING_FSTR)) goto no_singleton;
- break;
- }
+
+ case T_STRING:
+ if (FL_TEST_RAW(obj, RSTRING_FSTR)) {
+ rb_raise(rb_eTypeError, "can't define singleton");
+ }
}
klass = RBASIC(obj)->klass;
if (!(FL_TEST(klass, FL_SINGLETON) &&
- rb_ivar_get(klass, id_attached) == obj)) {
+ rb_attr_get(klass, id_attached) == obj)) {
rb_serial_t serial = RCLASS_SERIAL(klass);
klass = rb_make_metaclass(obj, klass);
RCLASS_SERIAL(klass) = serial;
}
- if (OBJ_TAINTED(obj)) {
- OBJ_TAINT(klass);
- }
- else {
- FL_UNSET(klass, FL_TAINT);
- }
RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj));
return klass;
@@ -1664,7 +1899,7 @@ rb_singleton_class_get(VALUE obj)
}
klass = RBASIC(obj)->klass;
if (!FL_TEST(klass, FL_SINGLETON)) return Qnil;
- if (rb_ivar_get(klass, id_attached) != obj) return Qnil;
+ if (rb_attr_get(klass, id_attached) != obj) return Qnil;
return klass;
}
@@ -1672,7 +1907,7 @@ rb_singleton_class_get(VALUE obj)
* Returns the singleton class of \a obj. Creates it if necessary.
*
* \param obj an arbitrary object.
- * \throw TypeError if \a obj is a Integer or a Symbol.
+ * \throw TypeError if \a obj is an Integer or a Symbol.
* \return the singleton class.
*
* \post \a obj has its own singleton class.
@@ -1705,6 +1940,9 @@ rb_singleton_class(VALUE obj)
* \{
*/
+#ifdef rb_define_singleton_method
+#undef rb_define_singleton_method
+#endif
/*!
* Defines a singleton method for \a obj.
* \param obj an arbitrary object
@@ -1718,8 +1956,9 @@ rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS),
rb_define_method(singleton_class_of(obj), name, func, argc);
}
-
-
+#ifdef rb_define_module_function
+#undef rb_define_module_function
+#endif
/*!
* Defines a module function for \a module.
* \param module an module or a class.
@@ -1734,7 +1973,9 @@ rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS)
rb_define_singleton_method(module, name, func, argc);
}
-
+#ifdef rb_define_global_function
+#undef rb_define_global_function
+#endif
/*!
* Defines a global function
* \param name name of the function
@@ -1773,19 +2014,17 @@ rb_define_attr(VALUE klass, const char *name, int read, int write)
rb_attr(klass, rb_intern(name), read, write, FALSE);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_keyword_error_new(const char *error, VALUE keys)
{
- const VALUE *ptr = RARRAY_CONST_PTR(keys);
long i = 0, len = RARRAY_LEN(keys);
VALUE error_message = rb_sprintf("%s keyword%.*s", error, len > 1, "s");
if (len > 0) {
rb_str_cat_cstr(error_message, ": ");
while (1) {
- const VALUE k = ptr[i];
- Check_Type(k, T_SYMBOL); /* wrong hash is given to rb_get_kwargs */
- rb_str_append(error_message, rb_sym2str(k));
+ const VALUE k = RARRAY_AREF(keys, i);
+ rb_str_append(error_message, rb_inspect(k));
if (++i >= len) break;
rb_str_cat_cstr(error_message, ", ");
}
@@ -1805,20 +2044,19 @@ NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keyw
static void
unknown_keyword_error(VALUE hash, const ID *table, int keywords)
{
- st_table *tbl = rb_hash_tbl_raw(hash);
int i;
for (i = 0; i < keywords; i++) {
st_data_t key = ID2SYM(table[i]);
- st_delete(tbl, &key, NULL);
+ rb_hash_stlike_delete(hash, &key, NULL);
}
rb_keyword_error("unknown", rb_hash_keys(hash));
}
+
static int
separate_symbol(st_data_t key, st_data_t value, st_data_t arg)
{
VALUE *kwdhash = (VALUE *)arg;
-
if (!SYMBOL_P(key)) kwdhash++;
if (!*kwdhash) *kwdhash = rb_hash_new();
rb_hash_aset(*kwdhash, (VALUE)key, (VALUE)value);
@@ -1835,10 +2073,10 @@ rb_extract_keywords(VALUE *orighash)
*orighash = 0;
return hash;
}
- st_foreach(rb_hash_tbl_raw(hash), separate_symbol, (st_data_t)&parthash);
+ rb_hash_foreach(hash, separate_symbol, (st_data_t)&parthash);
*orighash = parthash[1];
if (parthash[1] && RBASIC_CLASS(hash) != rb_cHash) {
- RBASIC_SET_CLASS(parthash[1], RBASIC_CLASS(hash));
+ RBASIC_SET_CLASS(parthash[1], RBASIC_CLASS(hash));
}
return parthash[0];
}
@@ -1853,8 +2091,8 @@ rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, V
#define extract_kwarg(keyword, val) \
(key = (st_data_t)(keyword), values ? \
- st_delete(rb_hash_tbl_raw(keyword_hash), &key, (val)) : \
- st_lookup(rb_hash_tbl_raw(keyword_hash), key, (val)))
+ (rb_hash_stlike_delete(keyword_hash, &key, &(val)) || ((val) = Qundef, 0)) : \
+ rb_hash_stlike_lookup(keyword_hash, key, NULL))
if (NIL_P(keyword_hash)) keyword_hash = 0;
@@ -1862,18 +2100,11 @@ rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, V
rest = 1;
optional = -1-optional;
}
- if (values) {
- for (j = 0; j < required + optional; j++) {
- values[j] = Qundef;
- }
- }
if (required) {
for (; i < required; i++) {
VALUE keyword = ID2SYM(table[i]);
if (keyword_hash) {
- st_data_t val;
- if (extract_kwarg(keyword, &val)) {
- if (values) values[i] = (VALUE)val;
+ if (extract_kwarg(keyword, values[i])) {
continue;
}
}
@@ -1887,9 +2118,7 @@ rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, V
j = i;
if (optional && keyword_hash) {
for (i = 0; i < optional; i++) {
- st_data_t val;
- if (extract_kwarg(ID2SYM(table[required+i]), &val)) {
- if (values) values[required+i] = (VALUE)val;
+ if (extract_kwarg(ID2SYM(table[required+i]), values[required+i])) {
j++;
}
}
@@ -1899,89 +2128,101 @@ rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, V
unknown_keyword_error(keyword_hash, table, required+optional);
}
}
+ if (values && !keyword_hash) {
+ for (i = 0; i < required + optional; i++) {
+ values[i] = Qundef;
+ }
+ }
return j;
#undef extract_kwarg
}
-#undef rb_scan_args
-int
-rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
+struct rb_scan_args_t {
+ int kw_flag;
+ int n_lead;
+ int n_opt;
+ int n_trail;
+ bool f_var;
+ bool f_hash;
+ bool f_block;
+};
+
+static void
+rb_scan_args_parse(int kw_flag, const char *fmt, struct rb_scan_args_t *arg)
{
- int i;
const char *p = fmt;
- VALUE *var;
- va_list vargs;
- int f_var = 0, f_hash = 0, f_block = 0;
- int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
- int argi = 0, last_idx = -1;
- VALUE hash = Qnil, last_hash = 0;
+
+ memset(arg, 0, sizeof(*arg));
+ arg->kw_flag = kw_flag;
if (ISDIGIT(*p)) {
- n_lead = *p - '0';
+ arg->n_lead = *p - '0';
p++;
if (ISDIGIT(*p)) {
- n_opt = *p - '0';
+ arg->n_opt = *p - '0';
p++;
}
}
if (*p == '*') {
- f_var = 1;
+ arg->f_var = 1;
p++;
}
if (ISDIGIT(*p)) {
- n_trail = *p - '0';
+ arg->n_trail = *p - '0';
p++;
}
if (*p == ':') {
- f_hash = 1;
+ arg->f_hash = 1;
p++;
}
if (*p == '&') {
- f_block = 1;
+ arg->f_block = 1;
p++;
}
if (*p != '\0') {
rb_fatal("bad scan arg format: %s", fmt);
}
- n_mand = n_lead + n_trail;
-
- if (argc < n_mand)
- goto argc_error;
+}
- va_start(vargs, fmt);
+static int
+rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *const argv, va_list vargs)
+{
+ int i, argi = 0;
+ VALUE *var, hash = Qnil;
+#define rb_scan_args_next_param() va_arg(vargs, VALUE *)
+ const int kw_flag = arg->kw_flag;
+ const int n_lead = arg->n_lead;
+ const int n_opt = arg->n_opt;
+ const int n_trail = arg->n_trail;
+ const int n_mand = n_lead + n_trail;
+ const bool f_var = arg->f_var;
+ const bool f_hash = arg->f_hash;
+ const bool f_block = arg->f_block;
- /* capture an option hash - phase 1: pop */
- if (f_hash && n_mand < argc) {
- VALUE last = argv[argc - 1];
+ /* capture an option hash - phase 1: pop from the argv */
+ if (f_hash && argc > 0) {
+ VALUE last = argv[argc - 1];
+ if (rb_scan_args_keyword_p(kw_flag, last)) {
+ hash = rb_hash_dup(last);
+ argc--;
+ }
+ }
- if (NIL_P(last)) {
- /* nil is taken as an empty option hash only if it is not
- ambiguous; i.e. '*' is not specified and arguments are
- given more than sufficient */
- if (!f_var && n_mand + n_opt < argc)
- argc--;
- }
- else {
- hash = rb_check_hash_type(last);
- if (!NIL_P(hash)) {
- VALUE opts = rb_extract_keywords(&hash);
- if (!(last_hash = hash)) argc--;
- else last_idx = argc - 1;
- hash = opts ? opts : Qnil;
- }
- }
+ if (argc < n_mand) {
+ goto argc_error;
}
+
/* capture leading mandatory arguments */
- for (i = n_lead; i-- > 0; ) {
- var = va_arg(vargs, VALUE *);
- if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
+ for (i = 0; i < n_lead; i++) {
+ var = rb_scan_args_next_param();
+ if (var) *var = argv[argi];
argi++;
}
/* capture optional arguments */
- for (i = n_opt; i-- > 0; ) {
- var = va_arg(vargs, VALUE *);
- if (argi < argc - n_trail) {
- if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
+ for (i = 0; i < n_opt; i++) {
+ var = rb_scan_args_next_param();
+ if (argi < argc - n_trail) {
+ if (var) *var = argv[argi];
argi++;
}
else {
@@ -1990,15 +2231,11 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
}
/* capture variable length arguments */
if (f_var) {
- int n_var = argc - argi - n_trail;
+ int n_var = argc - argi - n_trail;
- var = va_arg(vargs, VALUE *);
+ var = rb_scan_args_next_param();
if (0 < n_var) {
- if (var) {
- int f_last = (last_idx + 1 == argc - n_trail);
- *var = rb_ary_new4(n_var-f_last, &argv[argi]);
- if (f_last) rb_ary_push(*var, last_hash);
- }
+ if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
argi += n_var;
}
else {
@@ -2006,19 +2243,19 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
}
}
/* capture trailing mandatory arguments */
- for (i = n_trail; i-- > 0; ) {
- var = va_arg(vargs, VALUE *);
- if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
+ for (i = 0; i < n_trail; i++) {
+ var = rb_scan_args_next_param();
+ if (var) *var = argv[argi];
argi++;
}
/* capture an option hash - phase 2: assignment */
if (f_hash) {
- var = va_arg(vargs, VALUE *);
- if (var) *var = hash;
+ var = rb_scan_args_next_param();
+ if (var) *var = hash;
}
/* capture iterator block */
if (f_block) {
- var = va_arg(vargs, VALUE *);
+ var = rb_scan_args_next_param();
if (rb_block_given_p()) {
*var = rb_block_proc();
}
@@ -2026,14 +2263,58 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
*var = Qnil;
}
}
- va_end(vargs);
- if (argi < argc) {
- argc_error:
- rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
+ if (argi == argc) {
+ return argc;
}
- return argc;
+ argc_error:
+ return -(argc + 1);
+#undef rb_scan_args_next_param
+}
+
+static int
+rb_scan_args_result(const struct rb_scan_args_t *const arg, int argc)
+{
+ const int n_lead = arg->n_lead;
+ const int n_opt = arg->n_opt;
+ const int n_trail = arg->n_trail;
+ const int n_mand = n_lead + n_trail;
+ const bool f_var = arg->f_var;
+
+ if (argc >= 0) {
+ return argc;
+ }
+
+ argc = -argc - 1;
+ rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
+ UNREACHABLE_RETURN(-1);
+}
+
+#undef rb_scan_args
+int
+rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
+{
+ va_list vargs;
+ struct rb_scan_args_t arg;
+ rb_scan_args_parse(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, fmt, &arg);
+ va_start(vargs,fmt);
+ argc = rb_scan_args_assign(&arg, argc, argv, vargs);
+ va_end(vargs);
+ return rb_scan_args_result(&arg, argc);
+}
+
+#undef rb_scan_args_kw
+int
+rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt, ...)
+{
+ va_list vargs;
+ struct rb_scan_args_t arg;
+ rb_scan_args_parse(kw_flag, fmt, &arg);
+ va_start(vargs,fmt);
+ argc = rb_scan_args_assign(&arg, argc, argv, vargs);
+ va_end(vargs);
+ return rb_scan_args_result(&arg, argc);
}
int
diff --git a/common.mk b/common.mk
index 2eddfa53f6..6372cbf92c 100644
--- a/common.mk
+++ b/common.mk
@@ -1,8 +1,10 @@
+# -*- mode: makefile-gmake; indent-tabs-mode: t -*-
+
bin: $(PROGRAM) $(WPROGRAM)
lib: $(LIBRUBY)
dll: $(LIBRUBY_SO)
-.SUFFIXES: .inc .h .c .y .i .$(DTRACE_EXT)
+.SUFFIXES: .rbinc .rb .inc .h .c .y .i .$(ASMEXT) .$(DTRACE_EXT)
# V=0 quiet, V=1 verbose. other values don't work.
V = 0
@@ -15,13 +17,16 @@ mflags = $(MFLAGS)
gnumake_recursive =
enable_shared = $(ENABLE_SHARED:no=)
-UNICODE_VERSION = 10.0.0
+UNICODE_VERSION = 12.1.0
+UNICODE_EMOJI_VERSION = 12.1
+UNICODE_BETA = NO
### set the following environment variable or uncomment the line if
### the Unicode data files should be updated completely on every update ('make up',...).
# ALWAYS_UPDATE_UNICODE = yes
-UNICODE_DATA_DIR = enc/unicode/data/$(UNICODE_VERSION)
+UNICODE_DATA_DIR = enc/unicode/data/$(UNICODE_VERSION)/ucd
UNICODE_SRC_DATA_DIR = $(srcdir)/$(UNICODE_DATA_DIR)
+UNICODE_SRC_EMOJI_DATA_DIR = $(srcdir)/enc/unicode/data/emoji/$(UNICODE_EMOJI_VERSION)
UNICODE_HDR_DIR = $(srcdir)/enc/unicode/$(UNICODE_VERSION)
UNICODE_DATA_HEADERS = \
$(UNICODE_HDR_DIR)/casefold.h \
@@ -33,42 +38,51 @@ RUBYLIB = $(PATH_SEPARATOR)
RUBYOPT = -
RUN_OPTS = --disable-gems
+# GITPULLOPTIONS = --no-tags
+
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(UNICODE_HDR_DIR)
GEM_HOME =
GEM_PATH =
GEM_VENDOR =
-SIMPLECOV_GIT_URL = git://github.com/colszowka/simplecov.git
-SIMPLECOV_GIT_REF = v0.15.0
-SIMPLECOV_HTML_GIT_URL = git://github.com/colszowka/simplecov-html.git
+BENCHMARK_DRIVER_GIT_URL = https://github.com/benchmark-driver/benchmark-driver
+BENCHMARK_DRIVER_GIT_REF = v0.15.15
+SIMPLECOV_GIT_URL = https://github.com/colszowka/simplecov.git
+SIMPLECOV_GIT_REF = v0.17.0
+SIMPLECOV_HTML_GIT_URL = https://github.com/colszowka/simplecov-html.git
SIMPLECOV_HTML_GIT_REF = v0.10.2
-DOCLIE_GIT_URL = git://github.com/ms-ati/docile.git
-DOCLIE_GIT_REF = v1.1.5
+DOCLIE_GIT_URL = https://github.com/ms-ati/docile.git
+DOCLIE_GIT_REF = v1.3.2
STATIC_RUBY = static-ruby
TIMESTAMPDIR = $(EXTOUT)/.timestamp
+RUBYCOMMONDIR = $(EXTOUT)/common
EXTCONF = extconf.rb
LIBRUBY_EXTS = ./.libruby-with-ext.time
REVISION_H = ./.revision.time
PLATFORM_D = $(TIMESTAMPDIR)/.$(PLATFORM_DIR).time
ENC_TRANS_D = $(TIMESTAMPDIR)/.enc-trans.time
+RDOC = $(XRUBY) "$(srcdir)/libexec/rdoc" --root "$(srcdir)" --encoding=UTF-8 --all
RDOCOUT = $(EXTOUT)/rdoc
HTMLOUT = $(EXTOUT)/html
CAPIOUT = doc/capi
+INSTALL_DOC_OPTS = --rdoc-output="$(RDOCOUT)" --html-output="$(HTMLOUT)"
+RDOC_GEN_OPTS = --page-dir "$(srcdir)/doc" --no-force-update
INITOBJS = dmyext.$(OBJEXT) dmyenc.$(OBJEXT)
NORMALMAINOBJ = main.$(OBJEXT)
MAINOBJ = $(NORMALMAINOBJ)
DLDOBJS = $(INITOBJS)
EXTSOLIBS =
-MINIOBJS = $(ARCHMINIOBJS) miniinit.$(OBJEXT) dmyext.$(OBJEXT) miniprelude.$(OBJEXT)
+MINIOBJS = $(ARCHMINIOBJS) miniinit.$(OBJEXT) dmyext.$(OBJEXT)
ENC_MK = enc.mk
MAKE_ENC = -f $(ENC_MK) V="$(V)" UNICODE_HDR_DIR="$(UNICODE_HDR_DIR)" \
RUBY="$(MINIRUBY)" MINIRUBY="$(MINIRUBY)" $(mflags)
COMMONOBJS = array.$(OBJEXT) \
+ ast.$(OBJEXT) \
bignum.$(OBJEXT) \
class.$(OBJEXT) \
compar.$(OBJEXT) \
@@ -93,6 +107,9 @@ COMMONOBJS = array.$(OBJEXT) \
load.$(OBJEXT) \
marshal.$(OBJEXT) \
math.$(OBJEXT) \
+ memory_view.$(OBJEXT) \
+ mjit.$(OBJEXT) \
+ mjit_compile.$(OBJEXT) \
node.$(OBJEXT) \
numeric.$(OBJEXT) \
object.$(OBJEXT) \
@@ -100,6 +117,7 @@ COMMONOBJS = array.$(OBJEXT) \
parse.$(OBJEXT) \
proc.$(OBJEXT) \
process.$(OBJEXT) \
+ ractor.$(OBJEXT) \
random.$(OBJEXT) \
range.$(OBJEXT) \
rational.$(OBJEXT) \
@@ -111,7 +129,7 @@ COMMONOBJS = array.$(OBJEXT) \
regparse.$(OBJEXT) \
regsyntax.$(OBJEXT) \
ruby.$(OBJEXT) \
- safe.$(OBJEXT) \
+ scheduler.$(OBJEXT) \
signal.$(OBJEXT) \
sprintf.$(OBJEXT) \
st.$(OBJEXT) \
@@ -122,13 +140,16 @@ COMMONOBJS = array.$(OBJEXT) \
thread.$(OBJEXT) \
time.$(OBJEXT) \
transcode.$(OBJEXT) \
+ transient_heap.$(OBJEXT) \
util.$(OBJEXT) \
variable.$(OBJEXT) \
version.$(OBJEXT) \
vm.$(OBJEXT) \
vm_backtrace.$(OBJEXT) \
vm_dump.$(OBJEXT) \
+ vm_sync.$(OBJEXT) \
vm_trace.$(OBJEXT) \
+ $(COROUTINE_OBJ) \
$(DTRACE_OBJ) \
$(BUILTIN_ENCOBJS) \
$(BUILTIN_TRANSOBJS) \
@@ -139,15 +160,15 @@ EXPORTOBJS = $(DLNOBJ) \
loadpath.$(OBJEXT) \
$(COMMONOBJS)
-OBJS = $(EXPORTOBJS) prelude.$(OBJEXT)
+OBJS = $(EXPORTOBJS) builtin.$(OBJEXT)
ALLOBJS = $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(INITOBJS)
GOLFOBJS = goruby.$(OBJEXT) golf_prelude.$(OBJEXT)
DEFAULT_PRELUDES = $(GEM_PRELUDE)
-PRELUDE_SCRIPTS = $(srcdir)/prelude.rb $(DEFAULT_PRELUDES)
-GEM_PRELUDE = $(srcdir)/gem_prelude.rb
-PRELUDES = {$(srcdir)}prelude.c {$(srcdir)}miniprelude.c
+PRELUDE_SCRIPTS = $(DEFAULT_PRELUDES)
+GEM_PRELUDE =
+PRELUDES = {$(srcdir)}miniprelude.c
GOLFPRELUDES = {$(srcdir)}golf_prelude.c
SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \
@@ -158,7 +179,7 @@ EXTMK_ARGS = $(SCRIPT_ARGS) --extension $(EXTS) --extstatic $(EXTSTATIC) \
--make-flags="V=$(V) MINIRUBY='$(MINIRUBY)'" \
--gnumake=$(gnumake) --extflags="$(EXTLDFLAGS)" \
--
-INSTRUBY = $(SUDO) $(RUNRUBY) -r./$(arch)-fake $(srcdir)/tool/rbinstall.rb
+INSTRUBY = $(SUDO) $(RUNRUBY) -r./$(arch)-fake $(tooldir)/rbinstall.rb
INSTRUBY_ARGS = $(SCRIPT_ARGS) \
--data-mode=$(INSTALL_DATA_MODE) \
--prog-mode=$(INSTALL_PROG_MODE) \
@@ -167,30 +188,69 @@ INSTRUBY_ARGS = $(SCRIPT_ARGS) \
INSTALL_PROG_MODE = 0755
INSTALL_DATA_MODE = 0644
-PRE_LIBRUBY_UPDATE = $(MINIRUBY) -e 'ARGV[1] or File.unlink(ARGV[0]) rescue nil' -- \
- $(LIBRUBY_EXTS) $(LIBRUBY_SO_UPDATE)
-
TESTSDIR = $(srcdir)/test
+TOOL_TESTSDIR = $(tooldir)/test
TEST_EXCLUDES = --excludes-dir=$(TESTSDIR)/excludes --name=!/memory_leak/
-EXCLUDE_TESTFRAMEWORK = --exclude=/testunit/ --exclude=/minitest/
TESTWORKDIR = testwork
TESTOPTS = $(RUBY_TESTOPTS)
TESTRUN_SCRIPT = $(srcdir)/test.rb
-COMPILE_PRELUDE = $(srcdir)/tool/generic_erb.rb $(srcdir)/template/prelude.c.tmpl
+COMPILE_PRELUDE = $(tooldir)/generic_erb.rb $(srcdir)/template/prelude.c.tmpl \
+ $(tooldir)/ruby_vm/helpers/c_escape.rb
SHOWFLAGS = showflags
+MAKE_LINK = $(MINIRUBY) -rfileutils -e "include FileUtils::Verbose" \
+ -e "src, dest = ARGV" \
+ -e "exit if File.identical?(src, dest) or cmp(src, dest) rescue nil" \
+ -e "def noraise; yield; rescue; rescue NotImplementedError; end" \
+ -e "noraise {ln_sf('../'*dest.count('/')+src, dest)} or" \
+ -e "noraise {ln(src, dest)} or" \
+ -e "cp(src, dest)"
+
+
all: $(SHOWFLAGS) main docs
-main: $(SHOWFLAGS) exts $(ENCSTATIC:static=lib)encs
+main: $(SHOWFLAGS) exts $(ENCSTATIC:static=lib)encs programs
@$(NULLCMD)
+mjit-headers: $(MJIT_SUPPORT)-mjit-headers
+no-mjit-headers: PHONY
+yes-mjit-headers: mjit_config.h PHONY
+
+mjit.$(OBJEXT): mjit_config.h
+mjit_config.h: Makefile
+
+
+# These rules using MJIT_HEADER_SUFFIX must be in common.mk, not
+# Makefile.in, in order to override the macro in defs/universal.mk.
+
+# Other `-Dxxx`s preceding `-DMJIT_HEADER` will be removed in transform_mjit_header.rb.
+# So `-DMJIT_HEADER` should be passed first when rb_mjit_header.h is generated.
+$(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time: probes.h vm.$(OBJEXT) \
+ $(TIMESTAMPDIR)/$(arch)/.time $(tooldir)/mjit_tabs.rb $(PREP) $(RBCONFIG)
+ $(ECHO) building $(@F:.time=.h)
+ $(MINIRUBY) $(tooldir)/mjit_tabs.rb "$(MJIT_TABS)" \
+ $(CPP) -DMJIT_HEADER $(MJIT_HEADER_FLAGS) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(srcdir)/vm.c $(CPPOUTFLAG)$(@F:.time=.h).new
+ $(Q) $(IFCHANGE) "--timestamp=$@" $(@F:.time=.h) $(@F:.time=.h).new
+
+$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time
+
+$(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: \
+ $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time \
+ $(tooldir)/transform_mjit_header.rb $(PREP) \
+ $(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h
+ $(ECHO) building $@
+ $(MINIRUBY) $(tooldir)/transform_mjit_header.rb "$(CC) $(ARCH_FLAG) $(CFLAGS)" $(MJIT_HEADER:.h=)$(MJIT_HEADER_ARCH).h $@
+ $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR)
+ $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F)
+
.PHONY: showflags
exts enc trans: $(SHOWFLAGS)
showflags:
$(MESSAGE_BEGIN) \
+ " BASERUBY = $(BASERUBY)" \
" CC = $(CC)" \
" LD = $(LD)" \
" LDSHARED = $(LDSHARED)" \
@@ -202,6 +262,7 @@ showflags:
" LANG = $(LANG)" \
" LC_ALL = $(LC_ALL)" \
" LC_CTYPE = $(LC_CTYPE)" \
+ " MFLAGS = $(MFLAGS)" \
$(MESSAGE_END)
-@$(CC_VERSION)
@@ -211,22 +272,25 @@ showconfig:
$(configure_args) \
$(ECHO_END)
+EXTS_NOTE = -f $(EXTS_MK) $(mflags) RUBY="$(MINIRUBY)" top_srcdir="$(srcdir)" note
+
exts: build-ext
EXTS_MK = exts.mk
-$(EXTS_MK): ext/configure-ext.mk $(TIMESTAMPDIR)/$(arch)/.time $(srcdir)/template/exts.mk.tmpl
+$(EXTS_MK): ext/configure-ext.mk $(srcdir)/template/exts.mk.tmpl \
+ $(TIMESTAMPDIR)/$(arch)/.time $(TIMESTAMPDIR)/.RUBYCOMMONDIR.time
$(Q)$(MAKE) -f ext/configure-ext.mk $(mflags) V=$(V) EXTSTATIC=$(EXTSTATIC) \
gnumake=$(gnumake) MINIRUBY="$(MINIRUBY)" \
EXTLDFLAGS="$(EXTLDFLAGS)" srcdir="$(srcdir)"
$(ECHO) generating makefile $@
- $(Q)$(MINIRUBY) $(srcdir)/tool/generic_erb.rb -o $@ -c \
- $(srcdir)/template/exts.mk.tmpl --gnumake=$(gnumake)
+ $(Q)$(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ -c \
+ $(srcdir)/template/exts.mk.tmpl --gnumake=$(gnumake) --configure-exts=ext/configure-ext.mk
ext/configure-ext.mk: $(PREP) all-incs $(MKFILES) $(RBCONFIG) $(LIBRUBY) \
$(srcdir)/template/configure-ext.mk.tmpl
$(ECHO) generating makefiles $@
$(Q)$(MAKEDIRS) $(@D)
- $(Q)$(MINIRUBY) $(srcdir)/tool/generic_erb.rb -o $@ -c \
+ $(Q)$(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ -c \
$(srcdir)/template/$(@F).tmpl --srcdir="$(srcdir)" \
--miniruby="$(MINIRUBY)" --script-args='$(SCRIPT_ARGS)'
@@ -235,14 +299,17 @@ configure-ext: $(EXTS_MK)
build-ext: $(EXTS_MK)
$(Q)$(MAKE) -f $(EXTS_MK) $(mflags) libdir="$(libdir)" LIBRUBY_EXTS=$(LIBRUBY_EXTS) \
EXTENCS="$(ENCOBJS)" UPDATE_LIBRARIES=no $(EXTSTATIC)
- $(Q)$(MAKE) -f $(EXTS_MK) $(mflags) RUBY="$(MINIRUBY)" top_srcdir="$(srcdir)" note
+ $(Q)$(MAKE) $(EXTS_NOTE)
+
+exts-note: $(EXTS_MK)
+ $(Q)$(MAKE) $(EXTS_NOTE)
-ext/extinit.c: $(srcdir)/template/extinit.c.tmpl
- $(Q)$(MINIRUBY) $(srcdir)/tool/generic_erb.rb -o $@ -c \
+ext/extinit.c: $(srcdir)/template/extinit.c.tmpl $(PREP)
+ $(Q)$(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ -c \
$(srcdir)/template/extinit.c.tmpl $(EXTINITS)
prog: program wprogram
-programs: $(PROGRAM) $(WPROGRAM)
+programs: $(PROGRAM) $(WPROGRAM) $(arch)-fake.rb
$(PREP): $(MKFILES)
@@ -251,11 +318,15 @@ miniruby$(EXEEXT): config.status $(ALLOBJS) $(ARCHFILE)
objs: $(ALLOBJS)
GORUBY = go$(RUBY_INSTALL_NAME)
-golf: $(LIBRUBY) $(GOLFOBJS) PHONY
+GOLF = $(GORUBY)
+golf: $(GOLF)
+$(GOLF): $(LIBRUBY) $(GOLFOBJS) PHONY
$(Q) $(MAKE) $(mflags) \
+ GOLF=_dummy_golf_target_to_avoid_conflict_just_in_case_ \
MAINOBJ=goruby.$(OBJEXT) \
EXTOBJS="golf_prelude.$(OBJEXT) $(EXTOBJS)" \
PROGRAM=$(GORUBY)$(EXEEXT) \
+ V=$(V) \
program
capi: $(CAPIOUT)/.timestamp PHONY
@@ -263,11 +334,11 @@ $(CAPIOUT)/.timestamp: Doxyfile $(PREP)
$(Q) $(MAKEDIRS) "$(@D)"
$(ECHO) generating capi
-$(Q) $(DOXYGEN) -b
- $(Q) $(MINIRUBY) -e 'File.open(ARGV[0], "w"){|f| f.puts(Time.now)}' "$@"
+ $(Q) $(MINIRUBY) -e 'File.open(ARGV[0], "w"){'"|f|"' f.puts(Time.now)}' "$@"
-Doxyfile: $(srcdir)/template/Doxyfile.tmpl $(PREP) $(srcdir)/tool/generic_erb.rb $(RBCONFIG)
+Doxyfile: $(srcdir)/template/Doxyfile.tmpl $(PREP) $(tooldir)/generic_erb.rb $(RBCONFIG)
$(ECHO) generating $@
- $(Q) $(MINIRUBY) $(srcdir)/tool/generic_erb.rb -o $@ $(srcdir)/template/Doxyfile.tmpl \
+ $(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ $(srcdir)/template/Doxyfile.tmpl \
--srcdir="$(srcdir)" --miniruby="$(MINIRUBY)"
program: $(SHOWFLAGS) $(PROGRAM)
@@ -278,18 +349,22 @@ $(PROGRAM) $(WPROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP
$(LIBRUBY_A): $(LIBRUBY_A_OBJS) $(MAINOBJ) $(INITOBJS) $(ARCHFILE)
-$(LIBRUBY_SO): $(OBJS) $(DLDOBJS) $(LIBRUBY_A) $(PREP) $(LIBRUBY_SO_UPDATE) $(BUILTIN_ENCOBJS)
+$(LIBRUBY_SO): $(OBJS) $(DLDOBJS) $(LIBRUBY_A) $(PREP) $(BUILTIN_ENCOBJS)
$(LIBRUBY_EXTS):
- @exit > $@
+ @$(NULLCMD) > $@
$(STATIC_RUBY)$(EXEEXT): $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(LIBRUBY_A)
$(Q)$(RM) $@
- $(PURIFY) $(CC) $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)$@ $(LDFLAGS) $(XLDFLAGS)
+ $(PURIFY) $(CC) $(MAINOBJ) $(DLDOBJS) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)$@ $(LDFLAGS) $(XLDFLAGS)
ruby.imp: $(COMMONOBJS)
- $(Q)$(NM) -Pgp $(COMMONOBJS) | \
- awk 'BEGIN{print "#!"}; $$2~/^[BDT]$$/&&$$1!~/^(Init_|ruby_static_id_|.*_threadptr_|\.)/{print $$1}' | \
+ $(Q){ \
+ $(NM) -Pgp $(COMMONOBJS) | \
+ awk 'BEGIN{print "#!"}; $$2~/^[A-TV-Z]$$/&&$$1!~/^$(SYMBOL_PREFIX)(Init_|InitVM_|ruby_static_id_|.*_threadptr_|rb_ec_)|^\./{print $$1}'; \
+ ($(CHDIR) $(srcdir) && \
+ exec sed -n '/^MJIT_FUNC_EXPORTED/!d;N;s/.*\n\(rb_[a-zA-Z_0-9]*\).*/$(SYMBOL_PREFIX)\1/p' cont.c gc.c thread*c vm*.c) \
+ } | \
sort -u -o $@
install: install-$(INSTALLDOC)
@@ -298,17 +373,17 @@ pkgconfig-data: $(ruby_pc)
$(ruby_pc): $(srcdir)/template/ruby.pc.in config.status
install-all: docs pre-install-all do-install-all post-install-all
-pre-install-all:: all pre-install-local pre-install-ext pre-install-doc
+pre-install-all:: all pre-install-local pre-install-ext pre-install-gem pre-install-doc
do-install-all: pre-install-all
- $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=all --rdoc-output="$(RDOCOUT)"
-post-install-all:: post-install-local post-install-ext post-install-doc
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) $(INSTALL_DOC_OPTS)
+post-install-all:: post-install-local post-install-ext post-install-gem post-install-doc
@$(NULLCMD)
install-nodoc: pre-install-nodoc do-install-nodoc post-install-nodoc
-pre-install-nodoc:: pre-install-local pre-install-ext
+pre-install-nodoc:: pre-install-local pre-install-ext pre-install-gem
do-install-nodoc: main pre-install-nodoc
- $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS)
-post-install-nodoc:: post-install-local post-install-ext
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --exclude=doc
+post-install-nodoc:: post-install-local post-install-ext post-install-gem
install-local: pre-install-local do-install-local post-install-local
pre-install-local:: pre-install-bin pre-install-lib pre-install-man
@@ -382,12 +457,12 @@ what-where-all: no-install-all
no-install-all: pre-no-install-all dont-install-all post-no-install-all
pre-no-install-all:: pre-no-install-local pre-no-install-ext pre-no-install-doc
dont-install-all: $(PROGRAM)
- $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=all --rdoc-output="$(RDOCOUT)"
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=all $(INSTALL_DOC_OPTS)
post-no-install-all:: post-no-install-local post-no-install-ext post-no-install-doc
@$(NULLCMD)
uninstall: $(INSTALLED_LIST) sudo-precheck
- $(Q)$(SUDO) $(MINIRUBY) $(srcdir)/tool/rbuninstall.rb --destdir=$(DESTDIR) $(INSTALLED_LIST)
+ $(Q)$(SUDO) $(MINIRUBY) $(tooldir)/rbuninstall.rb --destdir=$(DESTDIR) $(INSTALLED_LIST)
reinstall: all uninstall install
@@ -469,28 +544,35 @@ post-no-install-man::
install-doc: rdoc pre-install-doc do-install-doc post-install-doc
pre-install-doc:: install-prereq
do-install-doc: $(PROGRAM) pre-install-doc
- $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=rdoc --rdoc-output="$(RDOCOUT)"
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=rdoc $(INSTALL_DOC_OPTS)
post-install-doc::
@$(NULLCMD)
install-gem: pre-install-gem do-install-gem post-install-gem
-pre-install-gem:: pre-install-bin pre-install-lib pre-install-man
+pre-install-gem:: prepare-gems pre-install-bin pre-install-lib pre-install-man
do-install-gem: $(PROGRAM) pre-install-gem
$(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=gem
post-install-gem::
@$(NULLCMD)
+install-dbg: pre-install-dbg do-install-dbg post-install-dbg
+pre-install-dbg::
+do-install-dbg: $(PROGRAM) pre-install-dbg
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=dbg
+post-install-dbg::
+ @$(NULLCMD)
+
rdoc: PHONY main
@echo Generating RDoc documentation
- $(Q) $(XRUBY) "$(srcdir)/bin/rdoc" --root "$(srcdir)" --page-dir "$(srcdir)/doc" --encoding=UTF-8 --no-force-update --all --ri --op "$(RDOCOUT)" $(RDOCFLAGS) "$(srcdir)"
+ $(Q) $(RDOC) --ri --op "$(RDOCOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) "$(srcdir)"
html: PHONY main
@echo Generating RDoc HTML files
- $(Q) $(XRUBY) "$(srcdir)/bin/rdoc" --root "$(srcdir)" --page-dir "$(srcdir)/doc" --encoding=UTF-8 --no-force-update --all --op "$(HTMLOUT)" $(RDOCFLAGS) "$(srcdir)"
+ $(Q) $(RDOC) --op "$(HTMLOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) "$(srcdir)"
rdoc-coverage: PHONY main
@echo Generating RDoc coverage report
- $(Q) $(XRUBY) "$(srcdir)/bin/rdoc" --root "$(srcdir)" --encoding=UTF-8 --all --quiet -C $(RDOCFLAGS) "$(srcdir)"
+ $(Q) $(RDOC) --quiet -C $(RDOCFLAGS) "$(srcdir)"
RDOCBENCHOUT=/tmp/rdocbench
@@ -508,7 +590,7 @@ what-where-doc: no-install-doc
no-install-doc: pre-no-install-doc dont-install-doc post-no-install-doc
pre-no-install-doc:: install-prereq
dont-install-doc:: $(PREP)
- $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=rdoc --rdoc-output="$(RDOCOUT)"
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=rdoc $(INSTALL_DOC_OPTS)
post-no-install-doc::
@$(NULLCMD)
@@ -523,13 +605,17 @@ clean: clean-ext clean-enc clean-golf clean-docs clean-extout clean-local clean-
clean-local:: clean-runnable
$(Q)$(RM) $(OBJS) $(MINIOBJS) $(MAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES)
$(Q)$(RM) $(PROGRAM) $(WPROGRAM) miniruby$(EXEEXT) dmyext.$(OBJEXT) dmyenc.$(OBJEXT) $(ARCHFILE) .*.time
- $(Q)$(RM) y.tab.c y.output encdb.h transdb.h config.log rbconfig.rb $(ruby_pc) probes.h probes.$(OBJEXT) probes.stamp ruby-glommed.$(OBJEXT)
- $(Q)$(RM) GNUmakefile.old Makefile.old $(arch)-fake.rb bisect.sh $(ENC_TRANS_D)
- -$(Q) $(RMDIR) enc/jis enc/trans enc 2> $(NULL) || exit 0
-clean-runnable:: PHONY
- $(Q)$(CHDIR) bin 2>$(NULL) && $(RM) $(PROGRAM) $(WPROGRAM) $(GORUBY)$(EXEEXT) bin/*.$(DLEXT) 2>$(NULL) || exit 0
- $(Q)$(CHDIR) lib 2>$(NULL) && $(RM) $(LIBRUBY_A) $(LIBRUBY) $(LIBRUBY_ALIASES) $(RUBY_BASE_NAME)/$(RUBY_PROGRAM_VERSION) $(RUBY_BASE_NAME)/vendor_ruby 2>$(NULL) || exit 0
- $(Q)$(RMDIR) lib/$(RUBY_BASE_NAME) lib bin 2>$(NULL) || exit 0
+ $(Q)$(RM) y.tab.c y.output encdb.h transdb.h config.log rbconfig.rb $(ruby_pc) $(COROUTINE_H:/Context.h=/.time)
+ $(Q)$(RM) probes.h probes.$(OBJEXT) probes.stamp ruby-glommed.$(OBJEXT) ruby.imp ChangeLog $(STATIC_RUBY)$(EXEEXT)
+ $(Q)$(RM) GNUmakefile.old Makefile.old $(arch)-fake.rb bisect.sh $(ENC_TRANS_D) builtin_binary.inc
+ -$(Q) $(RMDIR) enc/jis enc/trans enc $(COROUTINE_H:/Context.h=) coroutine 2> $(NULL) || $(NULLCMD)
+
+bin/clean-runnable:: PHONY
+ $(Q)$(CHDIR) bin 2>$(NULL) && $(RM) $(PROGRAM) $(WPROGRAM) $(GORUBY)$(EXEEXT) bin/*.$(DLEXT) 2>$(NULL) || $(NULLCMD)
+lib/clean-runnable:: PHONY
+ $(Q)$(CHDIR) lib 2>$(NULL) && $(RM) $(LIBRUBY_A) $(LIBRUBY) $(LIBRUBY_ALIASES) $(RUBY_BASE_NAME)/$(RUBY_PROGRAM_VERSION) $(RUBY_BASE_NAME)/vendor_ruby 2>$(NULL) || $(NULLCMD)
+clean-runnable:: bin/clean-runnable lib/clean-runnable PHONY
+ $(Q)$(RMDIR) lib/$(RUBY_BASE_NAME) lib bin 2>$(NULL) || $(NULLCMD)
clean-ext:: PHONY
clean-golf: PHONY
$(Q)$(RM) $(GORUBY)$(EXEEXT) $(GOLFOBJS)
@@ -538,14 +624,14 @@ clean-html: PHONY
clean-capi: PHONY
clean-platform: PHONY
clean-extout: PHONY
- -$(Q)$(RMDIR) $(EXTOUT)/$(arch) $(EXTOUT) 2> $(NULL) || exit 0
+ -$(Q)$(RMDIR) $(EXTOUT)/$(arch) $(EXTOUT) 2> $(NULL) || $(NULLCMD)
clean-docs: clean-rdoc clean-html clean-capi
clean-spec: PHONY
clean-rubyspec: clean-spec
distclean: distclean-ext distclean-enc distclean-golf distclean-docs distclean-extout distclean-local distclean-platform distclean-spec
distclean-local:: clean-local
- $(Q)$(RM) $(MKFILES) yasmdata.rb *.inc $(PRELUDES)
+ $(Q)$(RM) $(MKFILES) yasmdata.rb *.inc $(PRELUDES) *.rbinc
$(Q)$(RM) config.cache config.status config.status.lineno
$(Q)$(RM) *~ *.bak *.stackdump core *.core gmon.out $(PREP)
-$(Q)$(RMALL) $(srcdir)/autom4te.cache
@@ -561,12 +647,27 @@ distclean-spec: clean-spec
distclean-rubyspec: distclean-spec
realclean:: realclean-ext realclean-local realclean-enc realclean-golf realclean-extout
-realclean-local:: distclean-local
+realclean-local:: distclean-local realclean-srcs-local
+
+clean-srcs:: clean-srcs-local clean-srcs-ext
+realclean-srcs:: realclean-srcs-local realclean-srcs-ext
+
+clean-srcs-local::
$(Q)$(RM) parse.c parse.h lex.c enc/trans/newline.c revision.h
- $(Q)$(RM) id.c id.h probes.dmyh
- $(Q)$(CHDIR) $(srcdir) && $(exec) $(RM) parse.c parse.h lex.c enc/trans/newline.c $(PRELUDES) revision.h
- $(Q)$(CHDIR) $(srcdir) && $(exec) $(RM) id.c id.h probes.dmyh
- $(Q)$(CHDIR) $(srcdir) && $(exec) $(RM) configure aclocal.m4 tool/config.guess tool/config.sub gems/*.gem
+ $(Q)$(RM) id.c id.h probes.dmyh probes.h
+ $(Q)$(RM) encdb.h transdb.h verconf.h ruby-runner.h
+ $(Q)$(RM) mjit_config.h rb_mjit_header.h
+ $(Q)$(RM) $(MJIT_MIN_HEADER) $(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h
+
+realclean-srcs-local:: clean-srcs-local
+ $(Q)$(CHDIR) $(srcdir) && $(RM) \
+ parse.c parse.h lex.c enc/trans/newline.c $(PRELUDES) revision.h \
+ id.c id.h probes.dmyh configure aclocal.m4 tool/config.guess tool/config.sub gems/*.gem \
+ || $(NULLCMD)
+
+clean-srcs-ext::
+realclean-srcs-ext:: clean-srcs-ext
+
realclean-ext:: PHONY
realclean-golf: distclean-golf
$(Q)$(RM) $(GOLFPRELUDES)
@@ -584,9 +685,9 @@ distclean-ext:: ext/distclean gems/distclean timestamp/distclean
realclean-ext:: ext/realclean gems/realclean timestamp/realclean
ext/clean.mk ext/distclean.mk ext/realclean.mk::
-ext/clean gems/clean:: ext/clean.mk
-ext/distclean gems/distclean:: ext/distclean.mk
-ext/realclean gems/realclean:: ext/realclean.mk
+ext/clean:: ext/clean.mk
+ext/distclean:: ext/distclean.mk
+ext/realclean:: ext/realclean.mk
timestamp/clean:: ext/clean gems/clean
timestamp/distclean:: ext/distclean gems/distclean
@@ -594,14 +695,14 @@ timestamp/realclean:: ext/realclean gems/realclean
timestamp/clean timestamp/distclean timestamp/realclean::
$(Q)$(RM) $(TIMESTAMPDIR)/.*.time $(TIMESTAMPDIR)/$(arch)/.time
- $(Q)$(RMDIRS) $(TIMESTAMPDIR)/$(arch) 2> $(NULL) || exit 0
+ $(Q)$(RMDIRS) $(TIMESTAMPDIR)/$(arch) $(TIMESTAMPDIR) 2> $(NULL) || $(NULLCMD)
clean-ext::
-$(Q)$(RM) ext/extinit.$(OBJEXT)
distclean-ext realclean-ext::
-$(Q)$(RM) $(EXTS_MK) ext/extinit.* ext/configure-ext.mk
- -$(Q)$(RMDIR) ext 2> $(NULL) || exit 0
+ -$(Q)$(RMDIR) ext 2> $(NULL) || $(NULLCMD)
clean-enc distclean-enc realclean-enc: PHONY
@@ -609,7 +710,7 @@ clean-enc: clean-enc.d
clean-enc.d: PHONY
$(Q)$(RM) $(ENC_TRANS_D)
- -$(Q) $(RMDIR) enc/jis enc/trans enc 2> $(NULL) || exit 0
+ -$(Q) $(RMDIR) enc/jis enc/trans enc 2> $(NULL) || $(NULLCMD)
clean-rdoc distclean-rdoc realclean-rdoc:
@echo $(@:-rdoc=ing) rdoc
@@ -623,17 +724,23 @@ clean-capi distclean-capi realclean-capi:
@echo $(@:-capi=ing) capi
$(Q)$(RMALL) $(CAPIOUT)
-clean-platform:
+clean-platform distclean-platform realclean-platform:
$(Q) $(RM) $(PLATFORM_D)
- -$(Q) $(RMDIR) $(PLATFORM_DIR) 2> $(NULL) || exit 0
+ -$(Q) $(RMDIR) $(PLATFORM_DIR) 2> $(NULL) || $(NULLCMD)
RUBYSPEC_CAPIEXT = spec/ruby/optional/capi/ext
clean-spec: PHONY
-$(Q) $(RM) $(RUBYSPEC_CAPIEXT)/*.$(OBJEXT) $(RUBYSPEC_CAPIEXT)/*.$(DLEXT)
- -$(Q) $(RMDIRS) $(RUBYSPEC_CAPIEXT) 2> $(NULL) || exit 0
+ -$(Q) $(RMDIRS) $(RUBYSPEC_CAPIEXT) 2> $(NULL) || $(NULLCMD)
+ -$(Q) $(RMALL) rubyspec_temp
-check: main test test-testframework test-almost
+check: main test test-tool test-all test-spec
$(ECHO) check succeeded
+ -$(Q) if [ x"$(GIT)" != x ] && $(CHDIR) "$(srcdir)" && \
+ b=`$(GIT) symbolic-ref --short HEAD 2>&1` && \
+ u=`$(GIT) branch --list --format='%(upstream:short)' $$b`; then \
+ set -x; $(GIT) --no-pager log --format=oneline -G "^ *# *include" $$u..HEAD --; \
+ fi
check-ruby: test test-ruby
fake: $(CROSS_COMPILING)-fake
@@ -642,21 +749,24 @@ no-fake -fake: PHONY
# really doesn't depend on .o, just ensure newer than headers which
# version.o depends on.
-$(arch)-fake.rb: $(srcdir)/template/fake.rb.in $(srcdir)/tool/generic_erb.rb version.$(OBJEXT) miniruby$(EXEEXT)
+$(arch)-fake.rb: $(srcdir)/template/fake.rb.in $(tooldir)/generic_erb.rb version.$(OBJEXT) miniruby$(EXEEXT)
$(ECHO) generating $@
- $(Q) $(CPP) $(warnflags) $(XCFLAGS) $(CPPFLAGS) "$(srcdir)/version.c" | \
- $(BOOTSTRAPRUBY) "$(srcdir)/tool/generic_erb.rb" -o $@ "$(srcdir)/template/fake.rb.in" \
+ $(Q) $(CPP) -DRUBY_EXPORT $(INCFLAGS) $(CPPFLAGS) "$(srcdir)/version.c" | \
+ $(BOOTSTRAPRUBY) "$(tooldir)/generic_erb.rb" -o $@ "$(srcdir)/template/fake.rb.in" \
i=- srcdir="$(srcdir)" BASERUBY="$(BASERUBY)"
btest: $(TEST_RUNNABLE)-btest
no-btest: PHONY
yes-btest: fake miniruby$(EXEEXT) PHONY
- $(Q)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" $(OPTS) $(TESTOPTS)
+ $(Q)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(BTESTS)
btest-ruby: $(TEST_RUNNABLE)-btest-ruby
no-btest-ruby: PHONY
yes-btest-ruby: prog PHONY
- $(Q)$(exec) $(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib $(RUN_OPTS)" -q $(OPTS) $(TESTOPTS)
+ $(Q)$(exec) $(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib $(RUN_OPTS)" -q $(OPTS) $(TESTOPTS) $(BTESTS)
+
+rtest: fake miniruby$(EXEEXT) PHONY
+ $(Q)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" --sets=ractor -v
test-basic: $(TEST_RUNNABLE)-test-basic
no-test-basic: PHONY
@@ -671,63 +781,69 @@ yes-test-knownbug: prog PHONY
test-testframework: $(TEST_RUNNABLE)-test-testframework
yes-test-testframework: prog PHONY
- $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(srcdir)/test/runner.rb" --ruby="$(RUNRUBY)" $(TESTOPTS) testunit minitest
+ $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(TOOL_TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" $(TESTOPTS) testunit minitest
no-test-testframework: PHONY
+test-tool: $(TEST_RUNNABLE)-test-tool
+yes-test-tool: prog PHONY
+ $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(TOOL_TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" $(TESTOPTS)
+no-test-tool: PHONY
+
test-sample: test-basic # backward compatibility for mswin-build
-test: btest-ruby test-knownbug test-basic
+test-short: btest-ruby test-knownbug test-basic
+test: test-short
# $ make test-all TESTOPTS="--help" displays more detail
# for example, make test-all TESTOPTS="-j2 -v -n test-name -- test-file-name"
test-all: $(TEST_RUNNABLE)-test-all
yes-test-all: programs PHONY
- $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(srcdir)/test/runner.rb" --ruby="$(RUNRUBY)" $(TEST_EXCLUDES) $(TESTOPTS) $(TESTS)
+ $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" $(TEST_EXCLUDES) $(TESTOPTS) $(TESTS)
TESTS_BUILD = mkmf
no-test-all: PHONY
- $(gnumake_recursive)$(MINIRUBY) -I"$(srcdir)/lib" "$(srcdir)/test/runner.rb" $(TESTOPTS) $(TESTS_BUILD)
+ $(gnumake_recursive)$(MINIRUBY) -I"$(srcdir)/lib" "$(TESTSDIR)/runner.rb" $(TESTOPTS) $(TESTS_BUILD)
-test-almost: $(TEST_RUNNABLE)-test-almost
-yes-test-almost: prog PHONY
- $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(srcdir)/test/runner.rb" --ruby="$(RUNRUBY)" $(TEST_EXCLUDES) $(TESTOPTS) $(EXCLUDE_TESTFRAMEWORK) $(TESTS)
-no-test-almost: PHONY
+test-almost: test-all
+yes-test-almost: yes-test-all
+no-test-almost: no-test-all
test-ruby: $(TEST_RUNNABLE)-test-ruby
no-test-ruby: PHONY
yes-test-ruby: prog encs PHONY
- $(gnumake_recursive)$(RUNRUBY) "$(srcdir)/test/runner.rb" $(TEST_EXCLUDES) $(TESTOPTS) -- ruby -ext-
+ $(gnumake_recursive)$(RUNRUBY) "$(TESTSDIR)/runner.rb" $(TEST_EXCLUDES) $(TESTOPTS) -- ruby -ext-
extconf: $(PREP)
$(Q) $(MAKEDIRS) "$(EXTCONFDIR)"
$(RUNRUBY) -C "$(EXTCONFDIR)" $(EXTCONF) $(EXTCONFARGS)
-$(RBCONFIG): $(srcdir)/tool/mkconfig.rb config.status $(srcdir)/version.h
+$(RBCONFIG): $(tooldir)/mkconfig.rb config.status $(srcdir)/version.h
$(Q)$(BOOTSTRAPRUBY) -n \
-e 'BEGIN{version=ARGV.shift;mis=ARGV.dup}' \
-e 'END{abort "UNICODE version mismatch: #{mis}" unless mis.empty?}' \
-e '(mis.delete(ARGF.path); ARGF.close) if /ONIG_UNICODE_VERSION_STRING +"#{Regexp.quote(version)}"/o' \
$(UNICODE_VERSION) $(UNICODE_DATA_HEADERS)
- $(Q)$(BOOTSTRAPRUBY) $(srcdir)/tool/mkconfig.rb \
+ $(Q)$(BOOTSTRAPRUBY) $(tooldir)/mkconfig.rb \
-arch=$(arch) -version=$(RUBY_PROGRAM_VERSION) \
-install_name=$(RUBY_INSTALL_NAME) \
-so_name=$(RUBY_SO_NAME) \
-unicode_version=$(UNICODE_VERSION) \
+ -unicode_emoji_version=$(UNICODE_EMOJI_VERSION) \
> rbconfig.tmp
$(IFCHANGE) "--timestamp=$@" rbconfig.rb rbconfig.tmp
test-rubyspec: test-spec
yes-test-rubyspec: yes-test-spec
-test-spec-precheck: $(arch)-fake.rb programs
+test-spec-precheck: main
test-spec: $(TEST_RUNNABLE)-test-spec
yes-test-spec: test-spec-precheck
$(gnumake_recursive)$(Q) \
- $(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec run -B $(srcdir)/spec/default.mspec $(MSPECOPT) $(SPECOPTS)
+ $(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec run -B $(srcdir)/spec/default.mspec -I$(srcdir)/tool/lib $(MSPECOPT) $(SPECOPTS)
no-test-spec:
RUNNABLE = $(LIBRUBY_RELATIVE:no=un)-runnable
-runnable: $(RUNNABLE) prog $(srcdir)/tool/mkrunnable.rb PHONY
- $(Q) $(MINIRUBY) $(srcdir)/tool/mkrunnable.rb -v $(EXTOUT)
+runnable: $(RUNNABLE) prog $(tooldir)/mkrunnable.rb PHONY
+ $(Q) $(MINIRUBY) $(tooldir)/mkrunnable.rb -v $(EXTOUT)
yes-runnable: PHONY
encs: enc trans
@@ -740,10 +856,11 @@ encs enc trans libencs libenc libtrans: $(SHOWFLAGS) $(ENC_MK) $(LIBRUBY) $(PREP
libenc enc: {$(VPATH)}encdb.h
libtrans trans: {$(VPATH)}transdb.h
+# Use MINIRUBY which loads fake.rb for cross compiling
$(ENC_MK): $(srcdir)/enc/make_encmake.rb $(srcdir)/enc/Makefile.in $(srcdir)/enc/depend \
$(srcdir)/enc/encinit.c.erb $(srcdir)/lib/mkmf.rb $(RBCONFIG) fake
$(ECHO) generating $@
- $(Q) $(BOOTSTRAPRUBY) $(srcdir)/enc/make_encmake.rb --builtin-encs="$(BUILTIN_ENCOBJS)" --builtin-transes="$(BUILTIN_TRANSOBJS)" --module$(ENCSTATIC) $(ENCS) $@
+ $(Q) $(MINIRUBY) $(srcdir)/enc/make_encmake.rb --builtin-encs="$(BUILTIN_ENCOBJS)" --builtin-transes="$(BUILTIN_TRANSOBJS)" --module$(ENCSTATIC) $(ENCS) $@
.PRECIOUS: $(MKFILES)
@@ -753,60 +870,69 @@ $(ENC_MK): $(srcdir)/enc/make_encmake.rb $(srcdir)/enc/Makefile.in $(srcdir)/enc
.PHONY: clean clean-ext clean-local clean-enc clean-golf clean-rdoc clean-html clean-extout
.PHONY: distclean distclean-ext distclean-local distclean-enc distclean-golf distclean-extout
.PHONY: realclean realclean-ext realclean-local realclean-enc realclean-golf realclean-extout
-.PHONY: check test test-all btest btest-ruby test-basic test-knownbug
-.PHONY: run runruby parse benchmark benchmark-each tbench gdb gdb-ruby
+.PHONY: exam check test test-short test-all btest btest-ruby test-basic test-knownbug
+.PHONY: run runruby parse benchmark gdb gdb-ruby
.PHONY: update-mspec update-rubyspec test-rubyspec test-spec
.PHONY: touch-unicode-files
PHONY:
-{$(VPATH)}parse.c: {$(VPATH)}parse.y $(srcdir)/tool/ytab.sed {$(VPATH)}id.h
+{$(VPATH)}parse.c: {$(VPATH)}parse.y $(tooldir)/ytab.sed {$(VPATH)}id.h
{$(VPATH)}parse.h: {$(VPATH)}parse.c
{$(srcdir)}.y.c:
$(ECHO) generating $@
- $(Q)$(BASERUBY) $(srcdir)/tool/id2token.rb --path-separator=.$(PATH_SEPARATOR)./ --vpath=$(VPATH) id.h $(SRC_FILE) > parse.tmp.y
+ $(Q)$(BASERUBY) $(tooldir)/id2token.rb --path-separator=.$(PATH_SEPARATOR)./ --vpath=$(VPATH) id.h $(SRC_FILE) > parse.tmp.y
+ $(Q)$(BASERUBY) $(tooldir)/pure_parser.rb parse.tmp.y $(YACC)
+ $(Q)$(RM) parse.tmp.y.bak
$(Q)$(YACC) -d $(YFLAGS) -o y.tab.c parse.tmp.y
$(Q)$(RM) parse.tmp.y
- $(Q)sed -f $(srcdir)/tool/ytab.sed -e "/^#/s|parse\.tmp\.[iy]|$(SRC_FILE)|" -e "/^#/s!y\.tab\.c!$@!" y.tab.c > $@.new
+ $(Q)sed -f $(tooldir)/ytab.sed -e "/^#/s|parse\.tmp\.[iy]|$(SRC_FILE)|" -e "/^#/s!y\.tab\.c!$@!" y.tab.c > $@.new
$(Q)$(MV) $@.new $@
$(Q)sed -e "/^#line.*y\.tab\.h/d;/^#line.*parse.*\.y/d" y.tab.h > $(@:.c=.h)
$(Q)$(RM) y.tab.c y.tab.h
$(PLATFORM_D):
$(Q) $(MAKEDIRS) $(PLATFORM_DIR) $(@D)
- @exit > $@
+ @$(NULLCMD) > $@
-exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time miniruby$(EXEEXT)
- $(Q) $(PURIFY) $(CC) $(CFLAGS) $(CPPFLAGS) -DRUBY_INSTALL_NAME=$(@F) $(LDFLAGS) $(LIBS) $(OUTFLAG)$@ $<
+exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time miniruby$(EXEEXT) {$(VPATH)}config.h
+ $(Q) $(CC) $(CFLAGS) $(INCFLAGS) $(CPPFLAGS) -DRUBY_INSTALL_NAME=$(@F) $(COUTFLAG)ruby-runner.$(OBJEXT) -c $(CSRCFLAG)$(srcdir)/ruby-runner.c
+ $(Q) $(PURIFY) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTFLAG)$@ ruby-runner.$(OBJEXT) $(LIBS)
+ $(Q) $(POSTLINK)
$(Q) ./miniruby$(EXEEXT) \
- -e 'prog, dest = ARGV; dest += "/ruby"' \
+ -e 'prog, dest, inst = ARGV; dest += "/ruby"' \
+ -e 'exit unless prog==inst' \
-e 'unless prog=="ruby"' \
-e ' begin File.unlink(dest); rescue Errno::ENOENT; end' \
-e ' File.symlink(prog, dest)' \
-e 'end' \
- $(@F) $(@D)
+ $(@F) $(@D) $(RUBY_INSTALL_NAME)$(EXEEXT)
exe/.time:
- $(Q) $(MAKEDIRS) exe $(@D)
- @exit > $@
+ $(Q) $(MAKEDIRS) $(@D)
+ @$(NULLCMD) > $@
$(BUILTIN_ENCOBJS) $(BUILTIN_TRANSOBJS): $(ENC_TRANS_D)
$(ENC_TRANS_D):
$(Q) $(MAKEDIRS) enc/trans $(@D)
- @exit > $@
+ @$(NULLCMD) > $@
$(TIMESTAMPDIR)/$(arch)/.time:
$(Q)$(MAKEDIRS) $(@D) $(EXTOUT)/$(arch)
- @exit > $@
+ @$(NULLCMD) > $@
+
+$(TIMESTAMPDIR)/.RUBYCOMMONDIR.time:
+ $(Q)$(MAKEDIRS) $(@D) $(RUBYCOMMONDIR)
+ @$(NULLCMD) > $@
###
CCAN_DIR = {$(VPATH)}ccan
RUBY_H_INCLUDES = {$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}defines.h \
{$(VPATH)}intern.h {$(VPATH)}missing.h {$(VPATH)}st.h \
- {$(VPATH)}subst.h
+ {$(VPATH)}assert.h {$(VPATH)}subst.h
###
@@ -829,33 +955,38 @@ strlcat.$(OBJEXT): {$(VPATH)}strlcat.c
strlcpy.$(OBJEXT): {$(VPATH)}strlcpy.c
strstr.$(OBJEXT): {$(VPATH)}strstr.c
nt.$(OBJEXT): {$(VPATH)}nt.c
-ia64.$(OBJEXT): {$(VPATH)}ia64.s
- $(CC) $(CFLAGS) -c $<
+
+.coroutine_obj $(COROUTINE_OBJ): \
+ {$(VPATH)}$(COROUTINE_SRC) \
+ $(COROUTINE_H:/Context.h=/.time)
+$(COROUTINE_H:/Context.h=/.time):
+ $(Q) $(MAKEDIRS) $(@D)
+ @$(NULLCMD) > $@
###
# dependencies for generated C sources.
parse.$(OBJEXT): {$(VPATH)}parse.c
miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c
-prelude.$(OBJEXT): {$(VPATH)}prelude.c
# dependencies for optional sources.
compile.$(OBJEXT): {$(VPATH)}opt_sc.inc {$(VPATH)}optunifs.inc
win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c {$(VPATH)}win32/file.h \
{$(VPATH)}dln.h {$(VPATH)}dln_find.c {$(VPATH)}encindex.h \
- {$(VPATH)}internal.h {$(VPATH)}util.h $(RUBY_H_INCLUDES) $(PLATFORM_D)
+ {$(VPATH)}internal.h {$(VPATH)}util.h $(RUBY_H_INCLUDES) \
+ {$(VPATH)}vm.h $(PLATFORM_D)
win32/file.$(OBJEXT): {$(VPATH)}win32/file.c {$(VPATH)}win32/file.h \
$(RUBY_H_INCLUDES) $(PLATFORM_D)
-$(NEWLINE_C): $(srcdir)/enc/trans/newline.trans $(srcdir)/tool/transcode-tblgen.rb
+$(NEWLINE_C): $(srcdir)/enc/trans/newline.trans $(tooldir)/transcode-tblgen.rb
$(Q) $(MAKEDIRS) $(@D)
- $(Q) $(BASERUBY) "$(srcdir)/tool/transcode-tblgen.rb" -vo $@ $(srcdir)/enc/trans/newline.trans
+ $(Q) $(BASERUBY) "$(tooldir)/transcode-tblgen.rb" -vo $@ $(srcdir)/enc/trans/newline.trans
enc/trans/newline.$(OBJEXT): $(NEWLINE_C)
-verconf.h: $(srcdir)/template/verconf.h.tmpl $(srcdir)/tool/generic_erb.rb
+verconf.h: $(srcdir)/template/verconf.h.tmpl $(tooldir)/generic_erb.rb
$(ECHO) creating $@
- $(Q) $(BOOTSTRAPRUBY) "$(srcdir)/tool/generic_erb.rb" -o $@ $(srcdir)/template/verconf.h.tmpl
+ $(Q) $(BOOTSTRAPRUBY) "$(tooldir)/generic_erb.rb" -o $@ $(srcdir)/template/verconf.h.tmpl
ruby-glommed.$(OBJEXT): $(OBJS)
@@ -863,23 +994,46 @@ $(OBJS): {$(VPATH)}config.h {$(VPATH)}missing.h
INSNS2VMOPT = --srcdir="$(srcdir)"
-{$(VPATH)}minsns.inc: $(srcdir)/template/minsns.inc.tmpl
-
-{$(VPATH)}opt_sc.inc: $(srcdir)/template/opt_sc.inc.tmpl
-
-{$(VPATH)}optinsn.inc: $(srcdir)/template/optinsn.inc.tmpl
-
-{$(VPATH)}optunifs.inc: $(srcdir)/template/optunifs.inc.tmpl
-
-{$(VPATH)}insns.inc: $(srcdir)/template/insns.inc.tmpl
-
-{$(VPATH)}insns_info.inc: $(srcdir)/template/insns_info.inc.tmpl
-
-{$(VPATH)}vmtc.inc: $(srcdir)/template/vmtc.inc.tmpl
-
-{$(VPATH)}vm.inc: $(srcdir)/template/vm.inc.tmpl
+srcs_vpath = {$(VPATH)}
+
+inc_common_headers = $(tooldir)/ruby_vm/views/_copyright.erb $(tooldir)/ruby_vm/views/_notice.erb
+$(srcs_vpath)opt_sc.inc: $(tooldir)/ruby_vm/views/opt_sc.inc.erb $(inc_common_headers)
+$(srcs_vpath)optinsn.inc: $(tooldir)/ruby_vm/views/optinsn.inc.erb $(inc_common_headers)
+$(srcs_vpath)optunifs.inc: $(tooldir)/ruby_vm/views/optunifs.inc.erb $(inc_common_headers)
+$(srcs_vpath)insns.inc: $(tooldir)/ruby_vm/views/insns.inc.erb $(inc_common_headers)
+$(srcs_vpath)insns_info.inc: $(tooldir)/ruby_vm/views/insns_info.inc.erb $(inc_common_headers) \
+ $(tooldir)/ruby_vm/views/_insn_type_chars.erb $(tooldir)/ruby_vm/views/_insn_name_info.erb \
+ $(tooldir)/ruby_vm/views/_insn_len_info.erb $(tooldir)/ruby_vm/views/_insn_operand_info.erb \
+ $(tooldir)/ruby_vm/views/_attributes.erb $(tooldir)/ruby_vm/views/_comptime_insn_stack_increase.erb \
+ $(tooldir)/ruby_vm/views/_insn_sp_pc_dependency.erb
+$(srcs_vpath)vmtc.inc: $(tooldir)/ruby_vm/views/vmtc.inc.erb $(inc_common_headers)
+$(srcs_vpath)vm.inc: $(tooldir)/ruby_vm/views/vm.inc.erb $(inc_common_headers) \
+ $(tooldir)/ruby_vm/views/_insn_entry.erb $(tooldir)/ruby_vm/views/_trace_instruction.erb
+$(srcs_vpath)mjit_compile.inc: $(tooldir)/ruby_vm/views/mjit_compile.inc.erb $(inc_common_headers) \
+ $(tooldir)/ruby_vm/views/_mjit_compile_insn.erb $(tooldir)/ruby_vm/views/_mjit_compile_send.erb \
+ $(tooldir)/ruby_vm/views/_mjit_compile_ivar.erb \
+ $(tooldir)/ruby_vm/views/_mjit_compile_insn_body.erb $(tooldir)/ruby_vm/views/_mjit_compile_pc_and_sp.erb \
+ $(tooldir)/ruby_vm/views/_mjit_compile_invokebuiltin.erb
+
+BUILTIN_RB_SRCS = \
+ $(srcdir)/ast.rb \
+ $(srcdir)/dir.rb \
+ $(srcdir)/gc.rb \
+ $(srcdir)/integer.rb \
+ $(srcdir)/io.rb \
+ $(srcdir)/pack.rb \
+ $(srcdir)/trace_point.rb \
+ $(srcdir)/warning.rb \
+ $(srcdir)/array.rb \
+ $(srcdir)/kernel.rb \
+ $(srcdir)/ractor.rb \
+ $(srcdir)/prelude.rb \
+ $(srcdir)/gem_prelude.rb \
+ $(empty)
+BUILTIN_RB_INCS = $(BUILTIN_RB_SRCS:.rb=.rbinc)
-common-srcs: {$(VPATH)}parse.c {$(VPATH)}lex.c {$(VPATH)}enc/trans/newline.c {$(VPATH)}id.c \
+common-srcs: $(srcs_vpath)parse.c $(srcs_vpath)lex.c $(srcs_vpath)enc/trans/newline.c $(srcs_vpath)id.c \
+ $(BUILTIN_RB_INCS) \
srcs-lib srcs-ext incs
missing-srcs: $(srcdir)/missing/des_tables.c
@@ -890,13 +1044,20 @@ EXT_SRCS = $(srcdir)/ext/ripper/ripper.c \
$(srcdir)/ext/rbconfig/sizeof/sizes.c \
$(srcdir)/ext/rbconfig/sizeof/limits.c \
$(srcdir)/ext/socket/constdefs.c \
+ $(srcdir)/ext/etc/constdefs.h \
# EXT_SRCS
srcs-ext: $(EXT_SRCS)
+realclean-srcs-ext::
+ $(Q)$(RM) $(EXT_SRCS)
+
+EXTRA_SRCS = $(srcdir)/ext/json/parser/parser.c \
+ $(srcdir)/ext/date/zonetab.h \
+ $(empty)
-srcs-extra: $(srcdir)/ext/json/parser/parser.c \
- $(srcdir)/ext/date/zonetab.h \
- $(empty)
+srcs-extra: $(EXTRA_SRCS)
+realclean-srcs-extra::
+ $(Q)$(RM) $(EXTRA_SRCS)
LIB_SRCS = $(srcdir)/lib/unicode_normalize/tables.rb
@@ -915,52 +1076,46 @@ incs: $(INSNS) {$(VPATH)}node_name.inc {$(VPATH)}known_errors.inc \
insns: $(INSNS)
-id.h: $(srcdir)/tool/generic_erb.rb $(srcdir)/template/id.h.tmpl $(srcdir)/defs/id.def
+id.h: $(tooldir)/generic_erb.rb $(srcdir)/template/id.h.tmpl $(srcdir)/defs/id.def
$(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb --output=$@ \
+ $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb --output=$@ \
$(srcdir)/template/id.h.tmpl
-id.c: $(srcdir)/tool/generic_erb.rb $(srcdir)/template/id.c.tmpl $(srcdir)/defs/id.def
+id.c: $(tooldir)/generic_erb.rb $(srcdir)/template/id.c.tmpl $(srcdir)/defs/id.def
$(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb --output=$@ \
+ $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb --output=$@ \
$(srcdir)/template/id.c.tmpl
-node_name.inc: {$(VPATH)}node.h
+node_name.inc: $(tooldir)/node_name.rb $(srcdir)/node.h
$(ECHO) generating $@
- $(Q) $(BASERUBY) -n $(srcdir)/tool/node_name.rb < $? > $@
+ $(Q) $(BASERUBY) -n $(tooldir)/node_name.rb < $(srcdir)/node.h > $@
-encdb.h: $(PREP) $(srcdir)/tool/generic_erb.rb $(srcdir)/template/encdb.h.tmpl
+encdb.h: $(PREP) $(tooldir)/generic_erb.rb $(srcdir)/template/encdb.h.tmpl
$(ECHO) generating $@
- $(Q) $(MINIRUBY) $(srcdir)/tool/generic_erb.rb -c -o $@ $(srcdir)/template/encdb.h.tmpl $(srcdir)/enc enc
+ $(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -c -o $@ $(srcdir)/template/encdb.h.tmpl $(srcdir)/enc enc
-transdb.h: $(PREP) srcs-enc $(srcdir)/tool/generic_erb.rb $(srcdir)/template/transdb.h.tmpl
+transdb.h: $(PREP) srcs-enc $(tooldir)/generic_erb.rb $(srcdir)/template/transdb.h.tmpl
$(ECHO) generating $@
- $(Q) $(MINIRUBY) $(srcdir)/tool/generic_erb.rb -c -o $@ $(srcdir)/template/transdb.h.tmpl $(srcdir)/enc/trans enc/trans
+ $(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -c -o $@ $(srcdir)/template/transdb.h.tmpl $(srcdir)/enc/trans enc/trans
enc/encinit.c: $(ENC_MK) $(srcdir)/enc/encinit.c.erb
known_errors.inc: $(srcdir)/template/known_errors.inc.tmpl $(srcdir)/defs/known_errors.def
$(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -c -o $@ $(srcdir)/template/known_errors.inc.tmpl $(srcdir)/defs/known_errors.def
+ $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -c -o $@ $(srcdir)/template/known_errors.inc.tmpl $(srcdir)/defs/known_errors.def
-vm_call_iseq_optimized.inc: $(srcdir)/tool/mk_call_iseq_optimized.rb
+vm_call_iseq_optimized.inc: $(srcdir)/template/call_iseq_optimized.inc.tmpl
$(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/mk_call_iseq_optimized.rb > $@
+ $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -c -o $@ $(srcdir)/template/call_iseq_optimized.inc.tmpl
-$(MINIPRELUDE_C): $(COMPILE_PRELUDE)
+$(MINIPRELUDE_C): $(COMPILE_PRELUDE) $(BUILTIN_RB_SRCS)
$(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -o $@ \
- $(srcdir)/template/prelude.c.tmpl
+ $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -I$(srcdir) -o $@ \
+ $(srcdir)/template/prelude.c.tmpl $(BUILTIN_RB_SRCS)
-$(PRELUDE_C): $(COMPILE_PRELUDE) \
- $(PRELUDE_SCRIPTS)
+$(GOLF_PRELUDE_C): $(COMPILE_PRELUDE) {$(srcdir)}golf_prelude.rb
$(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -c -o $@ \
- $(srcdir)/template/prelude.c.tmpl $(PRELUDE_SCRIPTS)
-
-{$(VPATH)}golf_prelude.c: $(COMPILE_PRELUDE) {$(srcdir)}golf_prelude.rb
- $(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -c -o $@ \
+ $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -I$(srcdir) -c -o $@ \
$(srcdir)/template/prelude.c.tmpl golf_prelude.rb
MAINCPPFLAGS = $(ENABLE_DEBUG_ENV:yes=-DRUBY_DEBUG_ENV=1)
@@ -969,46 +1124,60 @@ $(MAINOBJ): $(srcdir)/$(MAINSRC)
$(ECHO) compiling $(srcdir)/$(MAINSRC)
$(Q) $(CC) $(MAINCPPFLAGS) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(srcdir)/$(MAINSRC)
-{$(VPATH)}probes.dmyh: {$(srcdir)}probes.d $(srcdir)/tool/gen_dummy_probes.rb
+{$(VPATH)}probes.dmyh: {$(srcdir)}probes.d $(tooldir)/gen_dummy_probes.rb
probes.dmyh:
- $(BASERUBY) $(srcdir)/tool/gen_dummy_probes.rb $(srcdir)/probes.d > $@
+ $(BASERUBY) $(tooldir)/gen_dummy_probes.rb $(srcdir)/probes.d > $@
probes.h: {$(VPATH)}probes.$(DTRACE_EXT)
prereq: incs srcs preludes PHONY
-preludes: {$(VPATH)}prelude.c
preludes: {$(VPATH)}miniprelude.c
preludes: {$(srcdir)}golf_prelude.c
+{$(srcdir)}.rb.rbinc:
+ $(ECHO) making $@
+ $(Q) $(BASERUBY) $(tooldir)/mk_builtin_loader.rb $<
+
+builtin_binary.inc: $(PREP) $(BUILTIN_RB_SRCS) $(srcdir)/template/builtin_binary.inc.tmpl
+ $(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ \
+ $(srcdir)/template/builtin_binary.inc.tmpl -- --cross=$(CROSS_COMPILING)
+
+$(BUILTIN_RB_INCS): $(top_srcdir)/tool/mk_builtin_loader.rb
+
$(srcdir)/revision.h:
- @exit > $@
+ $(Q)$(gnumake:yes=#) $(RM) $(@F)
+ $(Q)$(gnumake:yes=#) $(NULLCMD) > $@ || $(NULLCMD) > $(@F)
+
+revision.tmp::
+ $(Q) $(NULLCMD) > $@
+revision.$(HAVE_BASERUBY:yes=tmp):: $(srcdir)/version.h $(tooldir)/file2lastrev.rb $(REVISION_FORCE)
+ $(Q) $(BASERUBY) $(tooldir)/file2lastrev.rb -q --revision.h --srcdir="$(srcdir)" > $@
-$(REVISION_H): $(srcdir)/version.h $(srcdir)/tool/file2lastrev.rb $(REVISION_FORCE)
- -$(Q) $(BASERUBY) $(srcdir)/tool/file2lastrev.rb --revision.h "$(srcdir)" > revision.tmp
+$(REVISION_H): revision.tmp
$(Q)$(IFCHANGE) "--timestamp=$@" "$(srcdir)/revision.h" revision.tmp
-$(srcdir)/ext/ripper/ripper.c: $(srcdir)/parse.y id.h
+$(srcdir)/ext/ripper/ripper.c: $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/parse.y id.h $(srcdir)/ext/ripper/depend
$(ECHO) generating $@
$(Q) VPATH=$${PWD-`pwd`} && $(CHDIR) $(@D) && \
- sed /AUTOGENERATED/q depend | \
+ sed -e 's/{\$$([^(){}]*)[^{}]*}//g' -e /AUTOGENERATED/q depend | \
$(exec) $(MAKE) -f - $(mflags) \
- Q=$(Q) ECHO=$(ECHO) RM="$(RM)" top_srcdir=../.. srcdir=. VPATH="$${VPATH}" \
- RUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)"
+ Q=$(Q) ECHO=$(ECHO) RM="$(RM)" BISON=$(YACC) top_srcdir=../.. srcdir=. VPATH="$${VPATH}" \
+ RUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)" LANG=C
-$(srcdir)/ext/json/parser/parser.c: $(srcdir)/ext/json/parser/parser.rl
+$(srcdir)/ext/json/parser/parser.c: $(srcdir)/ext/json/parser/parser.rl $(srcdir)/ext/json/parser/prereq.mk
$(ECHO) generating $@
$(Q) $(CHDIR) $(@D) && $(exec) $(MAKE) -f prereq.mk $(mflags) \
Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=. VPATH=../../.. BASERUBY="$(BASERUBY)"
-$(srcdir)/ext/date/zonetab.h: $(srcdir)/ext/date/zonetab.list
+$(srcdir)/ext/date/zonetab.h: $(srcdir)/ext/date/zonetab.list $(srcdir)/ext/date/prereq.mk
$(ECHO) generating $@
$(Q) $(CHDIR) $(@D) && $(exec) $(MAKE) -f prereq.mk $(mflags) \
Q=$(Q) ECHO=$(ECHO) top_srcdir=../.. srcdir=. VPATH=../.. BASERUBY="$(BASERUBY)"
$(srcdir)/ext/rbconfig/sizeof/sizes.c: $(srcdir)/ext/rbconfig/sizeof/depend \
- $(srcdir)/tool/generic_erb.rb $(srcdir)/template/sizes.c.tmpl $(srcdir)/configure.ac
+ $(tooldir)/generic_erb.rb $(srcdir)/template/sizes.c.tmpl $(srcdir)/configure.ac
$(ECHO) generating $@
$(Q) $(CHDIR) $(@D) && \
sed '/AUTOGENERATED/q' depend | \
@@ -1016,7 +1185,7 @@ $(srcdir)/ext/rbconfig/sizeof/sizes.c: $(srcdir)/ext/rbconfig/sizeof/depend \
Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=. VPATH=../../.. RUBY="$(BASERUBY)" $(@F)
$(srcdir)/ext/rbconfig/sizeof/limits.c: $(srcdir)/ext/rbconfig/sizeof/depend \
- $(srcdir)/tool/generic_erb.rb $(srcdir)/template/limits.c.tmpl
+ $(tooldir)/generic_erb.rb $(srcdir)/template/limits.c.tmpl
$(ECHO) generating $@
$(Q) $(CHDIR) $(@D) && \
sed '/AUTOGENERATED/q' depend | \
@@ -1029,49 +1198,47 @@ $(srcdir)/ext/socket/constdefs.c: $(srcdir)/ext/socket/depend
$(exec) $(MAKE) -f - $(mflags) \
Q=$(Q) ECHO=$(ECHO) top_srcdir=../.. srcdir=. VPATH=../.. RUBY="$(BASERUBY)"
+$(srcdir)/ext/etc/constdefs.h: $(srcdir)/ext/etc/depend
+ $(Q) $(CHDIR) $(@D) && \
+ sed '/AUTOGENERATED/q' depend | \
+ $(exec) $(MAKE) -f - $(mflags) \
+ Q=$(Q) ECHO=$(ECHO) top_srcdir=../.. srcdir=. VPATH=../.. RUBY="$(BASERUBY)"
+
##
run: fake miniruby$(EXEEXT) PHONY
- $(BTESTRUBY) $(TESTRUN_SCRIPT) $(RUNOPT)
+ $(BTESTRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
runruby: $(PROGRAM) PHONY
- $(RUNRUBY) $(TESTRUN_SCRIPT)
+ $(RUNRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
parse: fake miniruby$(EXEEXT) PHONY
$(BTESTRUBY) --dump=parsetree_with_comment,insns $(TESTRUN_SCRIPT)
bisect: PHONY
- $(srcdir)/tool/bisect.sh miniruby $(srcdir)
+ $(tooldir)/bisect.sh miniruby $(srcdir)
bisect-ruby: PHONY
- $(srcdir)/tool/bisect.sh ruby $(srcdir)
+ $(tooldir)/bisect.sh ruby $(srcdir)
COMPARE_RUBY = $(BASERUBY)
+BENCH_RUBY = $(RUNRUBY)
+BENCH_OPTS = --output=markdown --output-compare
ITEM =
+ARGS = $$(find $(srcdir)/benchmark -maxdepth 1 -name '$(ITEM)' -o -name '*$(ITEM)*.yml' -o -name '*$(ITEM)*.rb' | sort)
OPTS =
-# You can pass several options through OPTS environment variable.
-# $ make benchmark OPTS="--help" displays more detail.
-# for example,
-# $ make benchmark COMPARE_RUBY="ruby-trunk" OPTS="-e ruby-2.2.2"
-# This command compares trunk and built-ruby and 2.2.2
-benchmark: miniruby$(EXEEXT) PHONY
- $(BASERUBY) $(srcdir)/benchmark/driver.rb -v \
- --executables="$(COMPARE_RUBY) -I$(srcdir)/lib -I. -I$(EXTOUT)/common --disable-gem; built-ruby::$(MINIRUBY) --disable-gem" \
- --pattern='bm_' --directory=$(srcdir)/benchmark $(OPTS)
-
-benchmark-each: miniruby$(EXEEXT) PHONY
- $(BASERUBY) $(srcdir)/benchmark/driver.rb -v \
- --executables="$(COMPARE_RUBY) -I$(srcdir)/lib -I. -I$(EXTOUT)/common --disable-gem; built-ruby::$(MINIRUBY) --disable-gem" \
- --pattern=$(ITEM) --directory=$(srcdir)/benchmark $(OPTS)
-
-tbench: miniruby$(EXEEXT) PHONY
- $(BASERUBY) $(srcdir)/benchmark/driver.rb -v \
- --executables="$(COMPARE_RUBY) -I$(srcdir)/lib -I. -I$(EXTOUT)/common --disable-gem; built-ruby::$(MINIRUBY) --disable-gem" \
- --pattern='bmx_' --directory=$(srcdir)/benchmark $(OPTS)
+# See benchmark/README.md for details.
+benchmark: miniruby$(EXEEXT) update-benchmark-driver PHONY
+ $(BASERUBY) -rrubygems -I$(srcdir)/benchmark/lib $(srcdir)/benchmark/benchmark-driver/exe/benchmark-driver \
+ --executables="compare-ruby::$(COMPARE_RUBY) -I$(EXTOUT)/common --disable-gem" \
+ --executables="built-ruby::$(BENCH_RUBY) --disable-gem" \
+ $(BENCH_OPTS) $(ARGS) $(OPTS)
run.gdb:
echo set breakpoint pending on > run.gdb
+ echo b rb_assert_failure >> run.gdb
+ echo b rb_bug >> run.gdb
echo b ruby_debug_breakpoint >> run.gdb
echo '# handle SIGINT nostop' >> run.gdb
echo '# handle SIGPIPE nostop' >> run.gdb
@@ -1086,74 +1253,144 @@ run.gdb:
gdb: miniruby$(EXEEXT) run.gdb PHONY
- gdb -x run.gdb --quiet --args $(MINIRUBY) $(TESTRUN_SCRIPT)
+ gdb -x run.gdb --quiet --args $(MINIRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
gdb-ruby: $(PROGRAM) run.gdb PHONY
- $(Q) $(RUNRUBY_COMMAND) $(RUNRUBY_DEBUGGER) -- $(TESTRUN_SCRIPT)
+ $(Q) $(RUNRUBY_COMMAND) $(RUNRUBY_DEBUGGER) -- $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
LLDB_INIT = command script import -r $(srcdir)/misc/lldb_cruby.py
lldb: miniruby$(EXEEXT) PHONY
- lldb -o '$(LLDB_INIT)' miniruby$(EXEEXT) -- $(TESTRUN_SCRIPT)
+ lldb -o '$(LLDB_INIT)' miniruby$(EXEEXT) -- $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
lldb-ruby: $(PROGRAM) PHONY
- lldb $(enable_shared:yes=-o 'target modules add ${LIBRUBY_SO}') -o '$(LLDB_INIT)' $(PROGRAM) -- $(TESTRUN_SCRIPT)
+ lldb $(enable_shared:yes=-o 'target modules add ${LIBRUBY_SO}') -o '$(LLDB_INIT)' $(PROGRAM) -- $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
DISTPKGS = gzip,zip,all
+PKGSDIR = tmp
dist:
- $(BASERUBY) $(srcdir)/tool/make-snapshot \
+ $(BASERUBY) $(tooldir)/make-snapshot \
-srcdir=$(srcdir) -packages=$(DISTPKGS) \
-unicode-version=$(UNICODE_VERSION) \
- tmp $(RELNAME)
+ $(DISTOPTS) $(PKGSDIR) $(RELNAME)
up:: update-remote
up::
- -$(Q)$(MAKE) $(mflags) Q=$(Q) REVISION_FORCE=PHONY "$(REVISION_H)"
+ -$(Q)$(MAKE) $(mflags) Q=$(Q) REVISION_FORCE=PHONY after-update
-up::
- -$(Q)$(MAKE) $(mflags) Q=$(Q) after-update
+yes::
+no::
+after-update:: $(REVISION_H)
after-update:: extract-extlibs
+after-update:: extract-gems
update-remote:: update-src update-download
-update-download:: update-unicode update-gems download-extlibs
+update-download:: $(ALWAYS_UPDATE_UNICODE:yes=update-unicode)
+update-download:: update-gems
+update-download:: download-extlibs
update-mspec:
update-rubyspec:
update-config_files: PHONY
- $(Q) $(BASERUBY) -C "$(srcdir)" tool/downloader.rb -d tool -e gnu \
+ $(Q) $(BASERUBY) -C "$(srcdir)" tool/downloader.rb -d tool --cache-dir=$(CACHE_DIR) -e gnu \
config.guess config.sub
-update-gems: PHONY
+refresh-gems: update-bundled_gems prepare-gems
+prepare-gems: $(HAVE_BASERUBY:yes=update-gems) $(HAVE_BASERUBY:yes=extract-gems)
+
+update-gems$(gnumake:yes=-nongnumake): PHONY
$(ECHO) Downloading bundled gem files...
$(Q) $(BASERUBY) -C "$(srcdir)" \
-I./tool -rdownloader -answ \
-e 'gem, ver = *$$F' \
- -e 'old = Dir.glob("#{gem}-*.gem")' \
+ -e 'next if !ver or /^#/=~gem' \
+ -e 'old = Dir.glob("gems/#{gem}-*.gem")' \
-e 'gem = "#{gem}-#{ver}.gem"' \
-e 'Downloader::RubyGems.download(gem, "gems", nil) and' \
- -e 'File.unlink(*(old-[gem]))' \
+ -e '(old.delete("gems/#{gem}"); !old.empty?) and' \
+ -e 'File.unlink(*old) and' \
+ -e 'FileUtils.rm_rf(old.map{'"|n|"'n.chomp(".gem")})' \
gems/bundled_gems
-extract-gems: PHONY
+extract-gems$(gnumake:yes=-nongnumake): PHONY
$(ECHO) Extracting bundled gem files...
- $(Q) $(RUNRUBY) -C "$(srcdir)/gems" \
- -I../tool -rgem-unpack -answ \
+ $(Q) $(RUNRUBY) -C "$(srcdir)" \
+ -Itool -rgem-unpack -answ \
+ -e 'BEGIN {FileUtils.mkdir_p(d = ".bundle/gems")}' \
-e 'gem, ver = *$$F' \
- -e 'Gem.unpack("#{gem}-#{ver}.gem")' \
- bundled_gems
+ -e 'next if !ver or /^#/=~gem' \
+ -e 'g = "#{gem}-#{ver}"' \
+ -e 'File.directory?("#{d}/#{g}") or Gem.unpack("gems/#{g}.gem", d)' \
+ gems/bundled_gems
update-bundled_gems: PHONY
$(Q) $(RUNRUBY) -rrubygems \
- -pla \
- -e '$$_=Gem::SpecFetcher.fetcher.detect(:latest) {|s|' \
- -e 'break "#{s.name} #{s.version}" if s.platform=="ruby"&&s.name==$$F[0]' \
- -e '}' \
+ $(tooldir)/update-bundled_gems.rb \
"$(srcdir)/gems/bundled_gems" | \
"$(IFCHANGE)" "$(srcdir)/gems/bundled_gems" -
+test-bundled-gems-precheck: $(TEST_RUNNABLE)-test-bundled-gems-precheck
+yes-test-bundled-gems-precheck: main
+no-test-bundled-gems-precheck:
+
+test-bundled-gems-fetch: $(PREP)
+ $(Q) $(BASERUBY) -C $(srcdir)/gems ../tool/fetch-bundled_gems.rb src bundled_gems
+
+test-bundled-gems-prepare: test-bundled-gems-precheck test-bundled-gems-fetch
+test-bundled-gems-prepare: $(TEST_RUNNABLE)-test-bundled-gems-prepare
+no-test-bundled-gems-prepare: no-test-bundled-gems-precheck
+yes-test-bundled-gems-prepare: yes-test-bundled-gems-precheck
+ $(XRUBY) -C "$(srcdir)" bin/gem install --no-document \
+ --install-dir .bundle --conservative "bundler" "minitest:~> 5" "test-unit" "rake" "hoe" "rexml" "json-schema" "rbs:~> 1.6.2"
+
+PREPARE_BUNDLED_GEMS = test-bundled-gems-prepare
+test-bundled-gems: $(TEST_RUNNABLE)-test-bundled-gems
+yes-test-bundled-gems: test-bundled-gems-run
+no-test-bundled-gems:
+
+# Override this to allow failure of specific gems on CI
+# TEST_BUNDLED_GEMS_ALLOW_FAILURES =
+
+BUNDLED_GEMS =
+test-bundled-gems-run: $(PREPARE_BUNDLED_GEMS)
+ $(Q) $(XRUBY) $(tooldir)/test-bundled-gems.rb $(BUNDLED_GEMS)
+
+test-bundler-precheck: $(TEST_RUNNABLE)-test-bundler-precheck
+no-test-bundler-precheck:
+yes-test-bundler-precheck: main
+
+no-test-bundler-prepare: no-test-bundler-precheck
+yes-test-bundler-prepare: yes-test-bundler-precheck
+ $(XRUBY) -C "$(srcdir)" bin/gem install --no-document \
+ --install-dir .bundle --conservative "rspec:~> 3.8" "rake:~> 13.0" "parallel_tests:~> 2.29"
+
+RSPECOPTS =
+BUNDLER_SPECS =
+test-bundler: $(TEST_RUNNABLE)-test-bundler
+yes-test-bundler: yes-test-bundler-prepare
+ $(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec \
+ --require spec_helper $(RSPECOPTS) spec/bundler/$(BUNDLER_SPECS)
+no-test-bundler:
+
+PARALLELRSPECOPTS = --runtime-log $(srcdir)/tmp/parallel_runtime_rspec.log
+test-bundler-parallel: $(TEST_RUNNABLE)-test-bundler-parallel
+yes-test-bundler-parallel: yes-test-bundler-prepare
+ $(XRUBY) -I$(srcdir)/spec/bundler \
+ -e "ENV['PARALLEL_TESTS_EXECUTABLE'] = ARGV.shift" \
+ -e "load ARGV.shift" \
+ "$(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec" \
+ $(srcdir)/.bundle/bin/parallel_rspec \
+ -o "--require spec_helper" \
+ $(PARALLELRSPECOPTS) $(srcdir)/spec/bundler/$(BUNDLER_SPECS)
+no-test-bundler-parallel:
+
+GEM = up
+sync-default-gems:
+ $(Q) $(XRUBY) -C "$(srcdir)" tool/sync_default_gems.rb $(GEM)
+
UNICODE_FILES = $(UNICODE_SRC_DATA_DIR)/UnicodeData.txt \
$(UNICODE_SRC_DATA_DIR)/CompositionExclusions.txt \
$(UNICODE_SRC_DATA_DIR)/NormalizationTest.txt \
@@ -1169,62 +1406,102 @@ UNICODE_PROPERTY_FILES = \
$(UNICODE_SRC_DATA_DIR)/PropertyAliases.txt \
$(UNICODE_SRC_DATA_DIR)/PropertyValueAliases.txt \
$(UNICODE_SRC_DATA_DIR)/Scripts.txt \
+ $(empty)
+
+UNICODE_AUXILIARY_FILES = \
$(UNICODE_SRC_DATA_DIR)/auxiliary/GraphemeBreakProperty.txt \
+ $(UNICODE_SRC_DATA_DIR)/auxiliary/GraphemeBreakTest.txt \
$(empty)
-update-unicode: $(UNICODE_FILES)
+UNICODE_EMOJI_FILES = \
+ $(UNICODE_SRC_EMOJI_DATA_DIR)/emoji-data.txt \
+ $(UNICODE_SRC_EMOJI_DATA_DIR)/emoji-sequences.txt \
+ $(UNICODE_SRC_EMOJI_DATA_DIR)/emoji-test.txt \
+ $(UNICODE_SRC_EMOJI_DATA_DIR)/emoji-variation-sequences.txt \
+ $(UNICODE_SRC_EMOJI_DATA_DIR)/emoji-zwj-sequences.txt \
+ $(empty)
+
+update-unicode: $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES) \
+ $(UNICODE_AUXILIARY_FILES) $(UNICODE_EMOJI_FILES)
CACHE_DIR = $(srcdir)/.downloaded-cache
UNICODE_DOWNLOAD = \
- $(BASERUBY) $(srcdir)/tool/downloader.rb \
+ $(BASERUBY) $(tooldir)/downloader.rb \
--cache-dir=$(CACHE_DIR) \
- -d $(srcdir)/$(UNICODE_DATA_DIR) \
+ --unicode-beta $(UNICODE_BETA) \
+ -d $(UNICODE_SRC_DATA_DIR) \
-p $(UNICODE_VERSION)/ucd \
-e $(ALWAYS_UPDATE_UNICODE:yes=-a) unicode
+UNICODE_AUXILIARY_DOWNLOAD = \
+ $(BASERUBY) $(tooldir)/downloader.rb \
+ --cache-dir=$(CACHE_DIR) \
+ --unicode-beta $(UNICODE_BETA) \
+ -d $(UNICODE_SRC_DATA_DIR)/auxiliary \
+ -p $(UNICODE_VERSION)/ucd/auxiliary \
+ -e $(ALWAYS_UPDATE_UNICODE:yes=-a) unicode
+UNICODE_EMOJI_DOWNLOAD = \
+ $(BASERUBY) $(tooldir)/downloader.rb \
+ --cache-dir=$(CACHE_DIR) \
+ --unicode-beta $(UNICODE_BETA) \
+ -d $(UNICODE_SRC_EMOJI_DATA_DIR) \
+ -p emoji/$(UNICODE_EMOJI_VERSION) \
+ -e $(ALWAYS_UPDATE_UNICODE:yes=-a) unicode
-$(UNICODE_PROPERTY_FILES): update-unicode-property-files
-update-unicode-property-files:
- $(ECHO) Downloading Unicode $(UNICODE_VERSION) property files...
- $(Q) $(MAKEDIRS) "$(UNICODE_SRC_DATA_DIR)/auxiliary"
- $(Q) $(UNICODE_DOWNLOAD) $(UNICODE_PROPERTY_FILES)
-
-$(UNICODE_FILES): update-unicode-files
+$(UNICODE_FILES) $(UNICODE_PROPERTY_FILES): update-unicode-files
update-unicode-files:
- $(ECHO) Downloading Unicode $(UNICODE_VERSION) data files...
+ $(ECHO) Downloading Unicode $(UNICODE_VERSION) data and property files...
$(Q) $(MAKEDIRS) "$(UNICODE_SRC_DATA_DIR)"
- $(Q) $(UNICODE_DOWNLOAD) $(UNICODE_FILES)
+ $(Q) $(UNICODE_DOWNLOAD) $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES)
+
+$(UNICODE_AUXILIARY_FILES): update-unicode-auxiliary-files
+update-unicode-auxiliary-files:
+ $(ECHO) Downloading Unicode $(UNICODE_VERSION) auxiliary files...
+ $(Q) $(MAKEDIRS) "$(UNICODE_SRC_DATA_DIR)/auxiliary"
+ $(Q) $(UNICODE_AUXILIARY_DOWNLOAD) $(UNICODE_AUXILIARY_FILES)
+
+$(UNICODE_EMOJI_FILES): update-unicode-emoji-files
+update-unicode-emoji-files:
+ $(ECHO) Downloading Unicode emoji $(UNICODE_EMOJI_VERSION) files...
+ $(Q) $(MAKEDIRS) "$(UNICODE_SRC_EMOJI_DATA_DIR)"
+ $(Q) $(UNICODE_EMOJI_DOWNLOAD) $(UNICODE_EMOJI_FILES)
-$(srcdir)/$(HAVE_BASERUBY:yes=lib/unicode_normalize/tables.rb): \
+$(srcdir)/lib/unicode_normalize/$(HAVE_BASERUBY:yes=tables.rb): \
$(UNICODE_SRC_DATA_DIR)/.unicode-tables.time
$(UNICODE_SRC_DATA_DIR)/$(ALWAYS_UPDATE_UNICODE:yes=.unicode-tables.time): \
- $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES)
+ $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES) \
+ $(UNICODE_AUXILIARY_FILES) $(UNICODE_EMOJI_FILES)
touch-unicode-files:
$(MAKEDIRS) $(UNICODE_SRC_DATA_DIR)
touch $(UNICODE_SRC_DATA_DIR)/.unicode-tables.time $(UNICODE_DATA_HEADERS)
-$(UNICODE_SRC_DATA_DIR)/.unicode-tables.time: $(srcdir)/tool/generic_erb.rb \
+UNICODE_TABLES_TIMESTAMP = yes
+$(UNICODE_SRC_DATA_DIR)/.unicode-tables.time: $(tooldir)/generic_erb.rb \
$(srcdir)/template/unicode_norm_gen.tmpl \
$(ALWAYS_UPDATE_UNICODE:yes=update-unicode)
$(Q) $(MAKE) $(@D)
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb \
- -c -t$@ -o $(srcdir)/lib/unicode_normalize/tables.rb \
+ $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb \
+ -c $(UNICODE_TABLES_TIMESTAMP:yes=-t$@) \
+ -o $(srcdir)/lib/unicode_normalize/tables.rb \
-I $(srcdir) \
$(srcdir)/template/unicode_norm_gen.tmpl \
$(UNICODE_DATA_DIR) lib/unicode_normalize
$(UNICODE_SRC_DATA_DIR):
- $(Q) $(exec) $(MAKEDIRS) $@ || exit && echo $(MAKE)
+ $(gnumake_recursive)$(Q) $(MAKEDIRS) $@
$(UNICODE_HDR_DIR)/$(ALWAYS_UPDATE_UNICODE:yes=name2ctype.h): \
- $(srcdir)/tool/enc-unicode.rb \
+ $(tooldir)/enc-unicode.rb \
$(UNICODE_SRC_DATA_DIR)/UnicodeData.txt \
- $(UNICODE_PROPERTY_FILES)
+ $(UNICODE_PROPERTY_FILES) \
+ $(UNICODE_EMOJI_FILES)
$(UNICODE_HDR_DIR)/name2ctype.h:
$(MAKEDIRS) $(@D)
- $(BOOTSTRAPRUBY) $(srcdir)/tool/enc-unicode.rb --header $(UNICODE_SRC_DATA_DIR) > $@
+ $(BOOTSTRAPRUBY) $(tooldir)/enc-unicode.rb --header \
+ $(UNICODE_SRC_DATA_DIR) $(UNICODE_SRC_EMOJI_DATA_DIR) > $@.new
+ $(MV) $@.new $@
# the next non-comment line was:
# $(UNICODE_HDR_DIR)/casefold.h: $(srcdir)/enc/unicode/case-folding.rb \
@@ -1267,12 +1544,9 @@ info-libruby_so: PHONY
info-arch: PHONY
@echo arch=$(arch)
-change: PHONY
- $(BASERUBY) -C "$(srcdir)" ./tool/change_maker.rb $(CHANGES) > change.log
+exam: check
-exam: check test-spec
-
-love: sudo-precheck up all test install exam
+love: sudo-precheck up all test exam install
@echo love is all you need
great: exam
@@ -1283,44 +1557,56 @@ sudo-precheck: PHONY
@$(SUDO) echo > $(NULL)
update-man-date: PHONY
- -$(Q) $(BASERUBY) -I"$(srcdir)/tool" -rvcs -i -p \
+ -$(Q) $(BASERUBY) -I"$(tooldir)/lib" -rvcs -i -p \
-e 'BEGIN{@vcs=VCS.detect(ARGV.shift)}' \
-e '$$_.sub!(/^(\.Dd ).*/){$$1+@vcs.modified(ARGF.path).strftime("%B %d, %Y")}' \
"$(srcdir)" "$(srcdir)"/man/*.1
+.PHONY: ChangeLog
+ChangeLog:
+ $(ECHO) Generating $@
+ -$(Q) $(BASERUBY) -I"$(tooldir)/lib" -rvcs \
+ -e 'VCS.detect(ARGV[0]).export_changelog("@", nil, nil, ARGV[1])' \
+ "$(srcdir)" $@
+
+HELP_EXTRA_TASKS = ""
+
help: PHONY
$(MESSAGE_BEGIN) \
" Makefile of Ruby" \
"" \
"targets:" \
- " all (default): builds all of below" \
- " miniruby: builds only miniruby" \
- " encs: builds encodings" \
- " exts: builds extensions" \
- " main: builds encodings, extensions and ruby" \
- " docs: builds documents" \
- " run: runs test.rb by miniruby" \
- " runruby: runs test.rb by ruby you just built" \
- " gdb: runs test.rb by miniruby under gdb" \
- " gdb-ruby: runs test.rb by ruby under gdb" \
- " check: equals make test test-all" \
- " exam: equals make check test-spec" \
- " test: ruby core tests" \
- " test-all: all ruby tests [TESTOPTS=-j4 TESTS=<test files>]" \
- " test-spec: run the Ruby spec suite" \
- " test-rubyspec: same as test-spec" \
- " up: update local copy and autogenerated files" \
- " benchmark: benchmark this ruby and COMPARE_RUBY." \
- " gcbench: gc benchmark [GCBENCH_ITEM=<item_name>]" \
- " gcbench-rdoc: gc benchmark with GCBENCH_ITEM=rdoc" \
- " install: install all ruby distributions" \
- " install-nodoc: install without rdoc" \
- " install-cross: install cross compiling stuff" \
- " clean: clean for tarball" \
- " distclean: clean for repository" \
- " change: make change log template" \
- " golf: for golfers" \
- "" \
+ " all (default): builds all of below" \
+ " miniruby: builds only miniruby" \
+ " encs: builds encodings" \
+ " exts: builds extensions" \
+ " main: builds encodings, extensions and ruby" \
+ " docs: builds documents" \
+ " install-capi: builds C API documents" \
+ " run: runs test.rb by miniruby" \
+ " runruby: runs test.rb by ruby you just built" \
+ " gdb: runs test.rb by miniruby under gdb" \
+ " gdb-ruby: runs test.rb by ruby under gdb" \
+ " check: equals make test test-tool test-all test-spec" \
+ " test: ruby core tests [BTESTS=<bootstraptest files>]" \
+ " test-all: all ruby tests [TESTOPTS=-j4 TESTS=<test files>]" \
+ " test-spec: run the Ruby spec suite [SPECOPTS=<specs, opts>]" \
+ " test-bundler: run the Bundler spec" \
+ " test-bundled-gems: run the test suite of bundled gems" \
+ " test-tool: tests under the tool/test" \
+ " update-gems: download files of the bundled gems" \
+ " update-bundled_gems: update the latest version of bundled gems" \
+ " sync-default-gems: sync default gems from upstream [GEM=<gem_name>]" \
+ " up: update local copy and autogenerated files" \
+ " benchmark: benchmark this ruby and COMPARE_RUBY." \
+ " gcbench: gc benchmark [GCBENCH_ITEM=<item_name>]" \
+ " install: install all ruby distributions" \
+ " install-nodoc: install without rdoc" \
+ " install-cross: install cross compiling stuff" \
+ " clean: clean for tarball" \
+ " distclean: clean for repository" \
+ " golf: build goruby for golfers" \
+ $(HELP_EXTRA_TASKS) \
"see DeveloperHowto for more detail: " \
" https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto" \
$(MESSAGE_END)
@@ -1328,19 +1614,241 @@ help: PHONY
# AUTOGENERATED DEPENDENCIES START
addr2line.$(OBJEXT): {$(VPATH)}addr2line.c
addr2line.$(OBJEXT): {$(VPATH)}addr2line.h
+addr2line.$(OBJEXT): {$(VPATH)}assert.h
+addr2line.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+addr2line.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+addr2line.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+addr2line.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+addr2line.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+addr2line.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+addr2line.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
addr2line.$(OBJEXT): {$(VPATH)}config.h
+addr2line.$(OBJEXT): {$(VPATH)}defines.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/assume.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/cast.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/config.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/dosish.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+addr2line.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
addr2line.$(OBJEXT): {$(VPATH)}missing.h
+array.$(OBJEXT): $(hdrdir)/ruby.h
array.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-array.$(OBJEXT): $(top_srcdir)/include/ruby.h
+array.$(OBJEXT): $(top_srcdir)/internal/array.h
+array.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+array.$(OBJEXT): $(top_srcdir)/internal/bits.h
+array.$(OBJEXT): $(top_srcdir)/internal/class.h
+array.$(OBJEXT): $(top_srcdir)/internal/compar.h
+array.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+array.$(OBJEXT): $(top_srcdir)/internal/enum.h
+array.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+array.$(OBJEXT): $(top_srcdir)/internal/gc.h
+array.$(OBJEXT): $(top_srcdir)/internal/hash.h
+array.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+array.$(OBJEXT): $(top_srcdir)/internal/object.h
+array.$(OBJEXT): $(top_srcdir)/internal/proc.h
+array.$(OBJEXT): $(top_srcdir)/internal/rational.h
+array.$(OBJEXT): $(top_srcdir)/internal/serial.h
+array.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+array.$(OBJEXT): $(top_srcdir)/internal/vm.h
+array.$(OBJEXT): $(top_srcdir)/internal/warnings.h
array.$(OBJEXT): {$(VPATH)}array.c
+array.$(OBJEXT): {$(VPATH)}array.rbinc
+array.$(OBJEXT): {$(VPATH)}assert.h
+array.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+array.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+array.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+array.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+array.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+array.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+array.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+array.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+array.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+array.$(OBJEXT): {$(VPATH)}builtin.h
array.$(OBJEXT): {$(VPATH)}config.h
array.$(OBJEXT): {$(VPATH)}debug_counter.h
array.$(OBJEXT): {$(VPATH)}defines.h
array.$(OBJEXT): {$(VPATH)}encoding.h
array.$(OBJEXT): {$(VPATH)}id.h
+array.$(OBJEXT): {$(VPATH)}id_table.h
array.$(OBJEXT): {$(VPATH)}intern.h
array.$(OBJEXT): {$(VPATH)}internal.h
-array.$(OBJEXT): {$(VPATH)}io.h
+array.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+array.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+array.$(OBJEXT): {$(VPATH)}internal/assume.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+array.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+array.$(OBJEXT): {$(VPATH)}internal/cast.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+array.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+array.$(OBJEXT): {$(VPATH)}internal/config.h
+array.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+array.$(OBJEXT): {$(VPATH)}internal/core.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+array.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+array.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+array.$(OBJEXT): {$(VPATH)}internal/ctype.h
+array.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+array.$(OBJEXT): {$(VPATH)}internal/dosish.h
+array.$(OBJEXT): {$(VPATH)}internal/error.h
+array.$(OBJEXT): {$(VPATH)}internal/eval.h
+array.$(OBJEXT): {$(VPATH)}internal/event.h
+array.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+array.$(OBJEXT): {$(VPATH)}internal/gc.h
+array.$(OBJEXT): {$(VPATH)}internal/glob.h
+array.$(OBJEXT): {$(VPATH)}internal/globals.h
+array.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+array.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+array.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+array.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+array.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+array.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+array.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+array.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+array.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+array.$(OBJEXT): {$(VPATH)}internal/iterator.h
+array.$(OBJEXT): {$(VPATH)}internal/memory.h
+array.$(OBJEXT): {$(VPATH)}internal/method.h
+array.$(OBJEXT): {$(VPATH)}internal/module.h
+array.$(OBJEXT): {$(VPATH)}internal/newobj.h
+array.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+array.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+array.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+array.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+array.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+array.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+array.$(OBJEXT): {$(VPATH)}internal/symbol.h
+array.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+array.$(OBJEXT): {$(VPATH)}internal/value.h
+array.$(OBJEXT): {$(VPATH)}internal/value_type.h
+array.$(OBJEXT): {$(VPATH)}internal/variable.h
+array.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+array.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
array.$(OBJEXT): {$(VPATH)}missing.h
array.$(OBJEXT): {$(VPATH)}onigmo.h
array.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -1349,41 +1857,748 @@ array.$(OBJEXT): {$(VPATH)}probes.h
array.$(OBJEXT): {$(VPATH)}ruby_assert.h
array.$(OBJEXT): {$(VPATH)}st.h
array.$(OBJEXT): {$(VPATH)}subst.h
+array.$(OBJEXT): {$(VPATH)}transient_heap.h
array.$(OBJEXT): {$(VPATH)}util.h
+ast.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+ast.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+ast.$(OBJEXT): $(CCAN_DIR)/list/list.h
+ast.$(OBJEXT): $(CCAN_DIR)/str/str.h
+ast.$(OBJEXT): $(hdrdir)/ruby.h
+ast.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+ast.$(OBJEXT): $(top_srcdir)/internal/array.h
+ast.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+ast.$(OBJEXT): $(top_srcdir)/internal/gc.h
+ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+ast.$(OBJEXT): $(top_srcdir)/internal/parse.h
+ast.$(OBJEXT): $(top_srcdir)/internal/serial.h
+ast.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+ast.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+ast.$(OBJEXT): $(top_srcdir)/internal/vm.h
+ast.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+ast.$(OBJEXT): {$(VPATH)}assert.h
+ast.$(OBJEXT): {$(VPATH)}ast.c
+ast.$(OBJEXT): {$(VPATH)}ast.rbinc
+ast.$(OBJEXT): {$(VPATH)}atomic.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+ast.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+ast.$(OBJEXT): {$(VPATH)}builtin.h
+ast.$(OBJEXT): {$(VPATH)}config.h
+ast.$(OBJEXT): {$(VPATH)}defines.h
+ast.$(OBJEXT): {$(VPATH)}encoding.h
+ast.$(OBJEXT): {$(VPATH)}id.h
+ast.$(OBJEXT): {$(VPATH)}intern.h
+ast.$(OBJEXT): {$(VPATH)}internal.h
+ast.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+ast.$(OBJEXT): {$(VPATH)}internal/assume.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+ast.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+ast.$(OBJEXT): {$(VPATH)}internal/cast.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+ast.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+ast.$(OBJEXT): {$(VPATH)}internal/config.h
+ast.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+ast.$(OBJEXT): {$(VPATH)}internal/core.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+ast.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+ast.$(OBJEXT): {$(VPATH)}internal/ctype.h
+ast.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+ast.$(OBJEXT): {$(VPATH)}internal/dosish.h
+ast.$(OBJEXT): {$(VPATH)}internal/error.h
+ast.$(OBJEXT): {$(VPATH)}internal/eval.h
+ast.$(OBJEXT): {$(VPATH)}internal/event.h
+ast.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+ast.$(OBJEXT): {$(VPATH)}internal/gc.h
+ast.$(OBJEXT): {$(VPATH)}internal/glob.h
+ast.$(OBJEXT): {$(VPATH)}internal/globals.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+ast.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+ast.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+ast.$(OBJEXT): {$(VPATH)}internal/iterator.h
+ast.$(OBJEXT): {$(VPATH)}internal/memory.h
+ast.$(OBJEXT): {$(VPATH)}internal/method.h
+ast.$(OBJEXT): {$(VPATH)}internal/module.h
+ast.$(OBJEXT): {$(VPATH)}internal/newobj.h
+ast.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+ast.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+ast.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+ast.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+ast.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+ast.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+ast.$(OBJEXT): {$(VPATH)}internal/symbol.h
+ast.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+ast.$(OBJEXT): {$(VPATH)}internal/value.h
+ast.$(OBJEXT): {$(VPATH)}internal/value_type.h
+ast.$(OBJEXT): {$(VPATH)}internal/variable.h
+ast.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+ast.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+ast.$(OBJEXT): {$(VPATH)}iseq.h
+ast.$(OBJEXT): {$(VPATH)}method.h
+ast.$(OBJEXT): {$(VPATH)}missing.h
+ast.$(OBJEXT): {$(VPATH)}node.h
+ast.$(OBJEXT): {$(VPATH)}onigmo.h
+ast.$(OBJEXT): {$(VPATH)}oniguruma.h
+ast.$(OBJEXT): {$(VPATH)}ruby_assert.h
+ast.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+ast.$(OBJEXT): {$(VPATH)}st.h
+ast.$(OBJEXT): {$(VPATH)}subst.h
+ast.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+ast.$(OBJEXT): {$(VPATH)}thread_native.h
+ast.$(OBJEXT): {$(VPATH)}util.h
+ast.$(OBJEXT): {$(VPATH)}vm_core.h
+ast.$(OBJEXT): {$(VPATH)}vm_opts.h
+bignum.$(OBJEXT): $(hdrdir)/ruby.h
bignum.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-bignum.$(OBJEXT): $(top_srcdir)/include/ruby.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/bits.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/class.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/complex.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/gc.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/object.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/serial.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/util.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/variable.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/vm.h
+bignum.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+bignum.$(OBJEXT): {$(VPATH)}assert.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+bignum.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
bignum.$(OBJEXT): {$(VPATH)}bignum.c
bignum.$(OBJEXT): {$(VPATH)}config.h
+bignum.$(OBJEXT): {$(VPATH)}constant.h
bignum.$(OBJEXT): {$(VPATH)}defines.h
-bignum.$(OBJEXT): {$(VPATH)}encoding.h
bignum.$(OBJEXT): {$(VPATH)}id.h
+bignum.$(OBJEXT): {$(VPATH)}id_table.h
bignum.$(OBJEXT): {$(VPATH)}intern.h
bignum.$(OBJEXT): {$(VPATH)}internal.h
-bignum.$(OBJEXT): {$(VPATH)}io.h
+bignum.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+bignum.$(OBJEXT): {$(VPATH)}internal/assume.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+bignum.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+bignum.$(OBJEXT): {$(VPATH)}internal/cast.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+bignum.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+bignum.$(OBJEXT): {$(VPATH)}internal/config.h
+bignum.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+bignum.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+bignum.$(OBJEXT): {$(VPATH)}internal/ctype.h
+bignum.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+bignum.$(OBJEXT): {$(VPATH)}internal/dosish.h
+bignum.$(OBJEXT): {$(VPATH)}internal/error.h
+bignum.$(OBJEXT): {$(VPATH)}internal/eval.h
+bignum.$(OBJEXT): {$(VPATH)}internal/event.h
+bignum.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+bignum.$(OBJEXT): {$(VPATH)}internal/gc.h
+bignum.$(OBJEXT): {$(VPATH)}internal/glob.h
+bignum.$(OBJEXT): {$(VPATH)}internal/globals.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+bignum.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+bignum.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+bignum.$(OBJEXT): {$(VPATH)}internal/iterator.h
+bignum.$(OBJEXT): {$(VPATH)}internal/memory.h
+bignum.$(OBJEXT): {$(VPATH)}internal/method.h
+bignum.$(OBJEXT): {$(VPATH)}internal/module.h
+bignum.$(OBJEXT): {$(VPATH)}internal/newobj.h
+bignum.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+bignum.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+bignum.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+bignum.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+bignum.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+bignum.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+bignum.$(OBJEXT): {$(VPATH)}internal/symbol.h
+bignum.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+bignum.$(OBJEXT): {$(VPATH)}internal/value.h
+bignum.$(OBJEXT): {$(VPATH)}internal/value_type.h
+bignum.$(OBJEXT): {$(VPATH)}internal/variable.h
+bignum.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+bignum.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
bignum.$(OBJEXT): {$(VPATH)}missing.h
-bignum.$(OBJEXT): {$(VPATH)}onigmo.h
-bignum.$(OBJEXT): {$(VPATH)}oniguruma.h
bignum.$(OBJEXT): {$(VPATH)}ruby_assert.h
bignum.$(OBJEXT): {$(VPATH)}st.h
bignum.$(OBJEXT): {$(VPATH)}subst.h
bignum.$(OBJEXT): {$(VPATH)}thread.h
bignum.$(OBJEXT): {$(VPATH)}util.h
+builtin.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+builtin.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+builtin.$(OBJEXT): $(CCAN_DIR)/list/list.h
+builtin.$(OBJEXT): $(CCAN_DIR)/str/str.h
+builtin.$(OBJEXT): $(hdrdir)/ruby.h
+builtin.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/array.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/gc.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/serial.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/vm.h
+builtin.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+builtin.$(OBJEXT): {$(VPATH)}assert.h
+builtin.$(OBJEXT): {$(VPATH)}atomic.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+builtin.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+builtin.$(OBJEXT): {$(VPATH)}builtin.c
+builtin.$(OBJEXT): {$(VPATH)}builtin.h
+builtin.$(OBJEXT): {$(VPATH)}builtin_binary.inc
+builtin.$(OBJEXT): {$(VPATH)}config.h
+builtin.$(OBJEXT): {$(VPATH)}defines.h
+builtin.$(OBJEXT): {$(VPATH)}id.h
+builtin.$(OBJEXT): {$(VPATH)}intern.h
+builtin.$(OBJEXT): {$(VPATH)}internal.h
+builtin.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+builtin.$(OBJEXT): {$(VPATH)}internal/assume.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+builtin.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+builtin.$(OBJEXT): {$(VPATH)}internal/cast.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+builtin.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+builtin.$(OBJEXT): {$(VPATH)}internal/config.h
+builtin.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+builtin.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+builtin.$(OBJEXT): {$(VPATH)}internal/ctype.h
+builtin.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+builtin.$(OBJEXT): {$(VPATH)}internal/dosish.h
+builtin.$(OBJEXT): {$(VPATH)}internal/error.h
+builtin.$(OBJEXT): {$(VPATH)}internal/eval.h
+builtin.$(OBJEXT): {$(VPATH)}internal/event.h
+builtin.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+builtin.$(OBJEXT): {$(VPATH)}internal/gc.h
+builtin.$(OBJEXT): {$(VPATH)}internal/glob.h
+builtin.$(OBJEXT): {$(VPATH)}internal/globals.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+builtin.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+builtin.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+builtin.$(OBJEXT): {$(VPATH)}internal/iterator.h
+builtin.$(OBJEXT): {$(VPATH)}internal/memory.h
+builtin.$(OBJEXT): {$(VPATH)}internal/method.h
+builtin.$(OBJEXT): {$(VPATH)}internal/module.h
+builtin.$(OBJEXT): {$(VPATH)}internal/newobj.h
+builtin.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+builtin.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+builtin.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+builtin.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+builtin.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+builtin.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+builtin.$(OBJEXT): {$(VPATH)}internal/symbol.h
+builtin.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+builtin.$(OBJEXT): {$(VPATH)}internal/value.h
+builtin.$(OBJEXT): {$(VPATH)}internal/value_type.h
+builtin.$(OBJEXT): {$(VPATH)}internal/variable.h
+builtin.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+builtin.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+builtin.$(OBJEXT): {$(VPATH)}iseq.h
+builtin.$(OBJEXT): {$(VPATH)}method.h
+builtin.$(OBJEXT): {$(VPATH)}missing.h
+builtin.$(OBJEXT): {$(VPATH)}node.h
+builtin.$(OBJEXT): {$(VPATH)}ruby_assert.h
+builtin.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+builtin.$(OBJEXT): {$(VPATH)}st.h
+builtin.$(OBJEXT): {$(VPATH)}subst.h
+builtin.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+builtin.$(OBJEXT): {$(VPATH)}thread_native.h
+builtin.$(OBJEXT): {$(VPATH)}vm_core.h
+builtin.$(OBJEXT): {$(VPATH)}vm_opts.h
class.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
class.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
class.$(OBJEXT): $(CCAN_DIR)/list/list.h
class.$(OBJEXT): $(CCAN_DIR)/str/str.h
+class.$(OBJEXT): $(hdrdir)/ruby.h
class.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-class.$(OBJEXT): $(top_srcdir)/include/ruby.h
+class.$(OBJEXT): $(top_srcdir)/internal/array.h
+class.$(OBJEXT): $(top_srcdir)/internal/class.h
+class.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+class.$(OBJEXT): $(top_srcdir)/internal/error.h
+class.$(OBJEXT): $(top_srcdir)/internal/eval.h
+class.$(OBJEXT): $(top_srcdir)/internal/gc.h
+class.$(OBJEXT): $(top_srcdir)/internal/hash.h
+class.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+class.$(OBJEXT): $(top_srcdir)/internal/object.h
+class.$(OBJEXT): $(top_srcdir)/internal/serial.h
+class.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+class.$(OBJEXT): $(top_srcdir)/internal/string.h
+class.$(OBJEXT): $(top_srcdir)/internal/variable.h
+class.$(OBJEXT): $(top_srcdir)/internal/vm.h
+class.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+class.$(OBJEXT): {$(VPATH)}assert.h
+class.$(OBJEXT): {$(VPATH)}atomic.h
+class.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+class.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+class.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+class.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+class.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+class.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+class.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+class.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+class.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
class.$(OBJEXT): {$(VPATH)}class.c
class.$(OBJEXT): {$(VPATH)}config.h
class.$(OBJEXT): {$(VPATH)}constant.h
class.$(OBJEXT): {$(VPATH)}defines.h
class.$(OBJEXT): {$(VPATH)}encoding.h
+class.$(OBJEXT): {$(VPATH)}gc.h
class.$(OBJEXT): {$(VPATH)}id.h
class.$(OBJEXT): {$(VPATH)}id_table.h
class.$(OBJEXT): {$(VPATH)}intern.h
class.$(OBJEXT): {$(VPATH)}internal.h
-class.$(OBJEXT): {$(VPATH)}io.h
+class.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+class.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+class.$(OBJEXT): {$(VPATH)}internal/assume.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+class.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+class.$(OBJEXT): {$(VPATH)}internal/cast.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+class.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+class.$(OBJEXT): {$(VPATH)}internal/config.h
+class.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+class.$(OBJEXT): {$(VPATH)}internal/core.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+class.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+class.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+class.$(OBJEXT): {$(VPATH)}internal/ctype.h
+class.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+class.$(OBJEXT): {$(VPATH)}internal/dosish.h
+class.$(OBJEXT): {$(VPATH)}internal/error.h
+class.$(OBJEXT): {$(VPATH)}internal/eval.h
+class.$(OBJEXT): {$(VPATH)}internal/event.h
+class.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+class.$(OBJEXT): {$(VPATH)}internal/gc.h
+class.$(OBJEXT): {$(VPATH)}internal/glob.h
+class.$(OBJEXT): {$(VPATH)}internal/globals.h
+class.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+class.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+class.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+class.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+class.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+class.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+class.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+class.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+class.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+class.$(OBJEXT): {$(VPATH)}internal/iterator.h
+class.$(OBJEXT): {$(VPATH)}internal/memory.h
+class.$(OBJEXT): {$(VPATH)}internal/method.h
+class.$(OBJEXT): {$(VPATH)}internal/module.h
+class.$(OBJEXT): {$(VPATH)}internal/newobj.h
+class.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+class.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+class.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+class.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+class.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+class.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+class.$(OBJEXT): {$(VPATH)}internal/symbol.h
+class.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+class.$(OBJEXT): {$(VPATH)}internal/value.h
+class.$(OBJEXT): {$(VPATH)}internal/value_type.h
+class.$(OBJEXT): {$(VPATH)}internal/variable.h
+class.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+class.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
class.$(OBJEXT): {$(VPATH)}method.h
class.$(OBJEXT): {$(VPATH)}missing.h
class.$(OBJEXT): {$(VPATH)}node.h
@@ -1396,36 +2611,377 @@ class.$(OBJEXT): {$(VPATH)}subst.h
class.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
class.$(OBJEXT): {$(VPATH)}thread_native.h
class.$(OBJEXT): {$(VPATH)}vm_core.h
-class.$(OBJEXT): {$(VPATH)}vm_debug.h
class.$(OBJEXT): {$(VPATH)}vm_opts.h
+compar.$(OBJEXT): $(hdrdir)/ruby.h
compar.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+compar.$(OBJEXT): $(top_srcdir)/internal/compar.h
+compar.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+compar.$(OBJEXT): $(top_srcdir)/internal/error.h
+compar.$(OBJEXT): $(top_srcdir)/internal/serial.h
+compar.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+compar.$(OBJEXT): $(top_srcdir)/internal/string.h
+compar.$(OBJEXT): $(top_srcdir)/internal/vm.h
+compar.$(OBJEXT): {$(VPATH)}assert.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+compar.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
compar.$(OBJEXT): {$(VPATH)}compar.c
compar.$(OBJEXT): {$(VPATH)}config.h
compar.$(OBJEXT): {$(VPATH)}defines.h
+compar.$(OBJEXT): {$(VPATH)}encoding.h
compar.$(OBJEXT): {$(VPATH)}id.h
compar.$(OBJEXT): {$(VPATH)}intern.h
+compar.$(OBJEXT): {$(VPATH)}internal.h
+compar.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+compar.$(OBJEXT): {$(VPATH)}internal/assume.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+compar.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+compar.$(OBJEXT): {$(VPATH)}internal/cast.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+compar.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+compar.$(OBJEXT): {$(VPATH)}internal/config.h
+compar.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+compar.$(OBJEXT): {$(VPATH)}internal/core.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+compar.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+compar.$(OBJEXT): {$(VPATH)}internal/ctype.h
+compar.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+compar.$(OBJEXT): {$(VPATH)}internal/dosish.h
+compar.$(OBJEXT): {$(VPATH)}internal/error.h
+compar.$(OBJEXT): {$(VPATH)}internal/eval.h
+compar.$(OBJEXT): {$(VPATH)}internal/event.h
+compar.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+compar.$(OBJEXT): {$(VPATH)}internal/gc.h
+compar.$(OBJEXT): {$(VPATH)}internal/glob.h
+compar.$(OBJEXT): {$(VPATH)}internal/globals.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+compar.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+compar.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+compar.$(OBJEXT): {$(VPATH)}internal/iterator.h
+compar.$(OBJEXT): {$(VPATH)}internal/memory.h
+compar.$(OBJEXT): {$(VPATH)}internal/method.h
+compar.$(OBJEXT): {$(VPATH)}internal/module.h
+compar.$(OBJEXT): {$(VPATH)}internal/newobj.h
+compar.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+compar.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+compar.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+compar.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+compar.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+compar.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+compar.$(OBJEXT): {$(VPATH)}internal/symbol.h
+compar.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+compar.$(OBJEXT): {$(VPATH)}internal/value.h
+compar.$(OBJEXT): {$(VPATH)}internal/value_type.h
+compar.$(OBJEXT): {$(VPATH)}internal/variable.h
+compar.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+compar.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
compar.$(OBJEXT): {$(VPATH)}missing.h
+compar.$(OBJEXT): {$(VPATH)}onigmo.h
+compar.$(OBJEXT): {$(VPATH)}oniguruma.h
compar.$(OBJEXT): {$(VPATH)}st.h
compar.$(OBJEXT): {$(VPATH)}subst.h
compile.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
compile.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
compile.$(OBJEXT): $(CCAN_DIR)/list/list.h
compile.$(OBJEXT): $(CCAN_DIR)/str/str.h
+compile.$(OBJEXT): $(hdrdir)/ruby.h
compile.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-compile.$(OBJEXT): $(top_srcdir)/include/ruby.h
+compile.$(OBJEXT): $(top_srcdir)/internal/array.h
+compile.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+compile.$(OBJEXT): $(top_srcdir)/internal/bits.h
+compile.$(OBJEXT): $(top_srcdir)/internal/class.h
+compile.$(OBJEXT): $(top_srcdir)/internal/compile.h
+compile.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+compile.$(OBJEXT): $(top_srcdir)/internal/complex.h
+compile.$(OBJEXT): $(top_srcdir)/internal/encoding.h
+compile.$(OBJEXT): $(top_srcdir)/internal/error.h
+compile.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+compile.$(OBJEXT): $(top_srcdir)/internal/gc.h
+compile.$(OBJEXT): $(top_srcdir)/internal/hash.h
+compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+compile.$(OBJEXT): $(top_srcdir)/internal/object.h
+compile.$(OBJEXT): $(top_srcdir)/internal/rational.h
+compile.$(OBJEXT): $(top_srcdir)/internal/re.h
+compile.$(OBJEXT): $(top_srcdir)/internal/serial.h
+compile.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+compile.$(OBJEXT): $(top_srcdir)/internal/string.h
+compile.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+compile.$(OBJEXT): $(top_srcdir)/internal/thread.h
+compile.$(OBJEXT): $(top_srcdir)/internal/variable.h
+compile.$(OBJEXT): $(top_srcdir)/internal/vm.h
+compile.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+compile.$(OBJEXT): {$(VPATH)}assert.h
+compile.$(OBJEXT): {$(VPATH)}atomic.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+compile.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+compile.$(OBJEXT): {$(VPATH)}builtin.h
compile.$(OBJEXT): {$(VPATH)}compile.c
compile.$(OBJEXT): {$(VPATH)}config.h
+compile.$(OBJEXT): {$(VPATH)}constant.h
+compile.$(OBJEXT): {$(VPATH)}debug_counter.h
compile.$(OBJEXT): {$(VPATH)}defines.h
compile.$(OBJEXT): {$(VPATH)}encindex.h
compile.$(OBJEXT): {$(VPATH)}encoding.h
compile.$(OBJEXT): {$(VPATH)}gc.h
compile.$(OBJEXT): {$(VPATH)}id.h
compile.$(OBJEXT): {$(VPATH)}id_table.h
+compile.$(OBJEXT): {$(VPATH)}insns.def
compile.$(OBJEXT): {$(VPATH)}insns.inc
compile.$(OBJEXT): {$(VPATH)}insns_info.inc
compile.$(OBJEXT): {$(VPATH)}intern.h
compile.$(OBJEXT): {$(VPATH)}internal.h
-compile.$(OBJEXT): {$(VPATH)}io.h
+compile.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+compile.$(OBJEXT): {$(VPATH)}internal/assume.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+compile.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+compile.$(OBJEXT): {$(VPATH)}internal/cast.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+compile.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+compile.$(OBJEXT): {$(VPATH)}internal/config.h
+compile.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+compile.$(OBJEXT): {$(VPATH)}internal/core.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rmatch.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+compile.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+compile.$(OBJEXT): {$(VPATH)}internal/ctype.h
+compile.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+compile.$(OBJEXT): {$(VPATH)}internal/dosish.h
+compile.$(OBJEXT): {$(VPATH)}internal/error.h
+compile.$(OBJEXT): {$(VPATH)}internal/eval.h
+compile.$(OBJEXT): {$(VPATH)}internal/event.h
+compile.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+compile.$(OBJEXT): {$(VPATH)}internal/gc.h
+compile.$(OBJEXT): {$(VPATH)}internal/glob.h
+compile.$(OBJEXT): {$(VPATH)}internal/globals.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+compile.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+compile.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+compile.$(OBJEXT): {$(VPATH)}internal/iterator.h
+compile.$(OBJEXT): {$(VPATH)}internal/memory.h
+compile.$(OBJEXT): {$(VPATH)}internal/method.h
+compile.$(OBJEXT): {$(VPATH)}internal/module.h
+compile.$(OBJEXT): {$(VPATH)}internal/newobj.h
+compile.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+compile.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+compile.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+compile.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+compile.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+compile.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+compile.$(OBJEXT): {$(VPATH)}internal/symbol.h
+compile.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+compile.$(OBJEXT): {$(VPATH)}internal/value.h
+compile.$(OBJEXT): {$(VPATH)}internal/value_type.h
+compile.$(OBJEXT): {$(VPATH)}internal/variable.h
+compile.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+compile.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
compile.$(OBJEXT): {$(VPATH)}iseq.h
compile.$(OBJEXT): {$(VPATH)}method.h
compile.$(OBJEXT): {$(VPATH)}missing.h
@@ -1443,18 +2999,189 @@ compile.$(OBJEXT): {$(VPATH)}st.h
compile.$(OBJEXT): {$(VPATH)}subst.h
compile.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
compile.$(OBJEXT): {$(VPATH)}thread_native.h
+compile.$(OBJEXT): {$(VPATH)}util.h
+compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h
compile.$(OBJEXT): {$(VPATH)}vm_core.h
compile.$(OBJEXT): {$(VPATH)}vm_debug.h
compile.$(OBJEXT): {$(VPATH)}vm_opts.h
+complex.$(OBJEXT): $(hdrdir)/ruby.h
complex.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-complex.$(OBJEXT): $(top_srcdir)/include/ruby.h
+complex.$(OBJEXT): $(top_srcdir)/internal/array.h
+complex.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+complex.$(OBJEXT): $(top_srcdir)/internal/bits.h
+complex.$(OBJEXT): $(top_srcdir)/internal/class.h
+complex.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+complex.$(OBJEXT): $(top_srcdir)/internal/complex.h
+complex.$(OBJEXT): $(top_srcdir)/internal/error.h
+complex.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+complex.$(OBJEXT): $(top_srcdir)/internal/gc.h
+complex.$(OBJEXT): $(top_srcdir)/internal/math.h
+complex.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+complex.$(OBJEXT): $(top_srcdir)/internal/object.h
+complex.$(OBJEXT): $(top_srcdir)/internal/rational.h
+complex.$(OBJEXT): $(top_srcdir)/internal/serial.h
+complex.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+complex.$(OBJEXT): $(top_srcdir)/internal/string.h
+complex.$(OBJEXT): $(top_srcdir)/internal/vm.h
+complex.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+complex.$(OBJEXT): {$(VPATH)}assert.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+complex.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
complex.$(OBJEXT): {$(VPATH)}complex.c
complex.$(OBJEXT): {$(VPATH)}config.h
complex.$(OBJEXT): {$(VPATH)}defines.h
complex.$(OBJEXT): {$(VPATH)}encoding.h
+complex.$(OBJEXT): {$(VPATH)}id.h
+complex.$(OBJEXT): {$(VPATH)}id_table.h
complex.$(OBJEXT): {$(VPATH)}intern.h
complex.$(OBJEXT): {$(VPATH)}internal.h
-complex.$(OBJEXT): {$(VPATH)}io.h
+complex.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+complex.$(OBJEXT): {$(VPATH)}internal/assume.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+complex.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+complex.$(OBJEXT): {$(VPATH)}internal/cast.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+complex.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+complex.$(OBJEXT): {$(VPATH)}internal/config.h
+complex.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+complex.$(OBJEXT): {$(VPATH)}internal/core.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+complex.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+complex.$(OBJEXT): {$(VPATH)}internal/ctype.h
+complex.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+complex.$(OBJEXT): {$(VPATH)}internal/dosish.h
+complex.$(OBJEXT): {$(VPATH)}internal/error.h
+complex.$(OBJEXT): {$(VPATH)}internal/eval.h
+complex.$(OBJEXT): {$(VPATH)}internal/event.h
+complex.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+complex.$(OBJEXT): {$(VPATH)}internal/gc.h
+complex.$(OBJEXT): {$(VPATH)}internal/glob.h
+complex.$(OBJEXT): {$(VPATH)}internal/globals.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+complex.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+complex.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+complex.$(OBJEXT): {$(VPATH)}internal/iterator.h
+complex.$(OBJEXT): {$(VPATH)}internal/memory.h
+complex.$(OBJEXT): {$(VPATH)}internal/method.h
+complex.$(OBJEXT): {$(VPATH)}internal/module.h
+complex.$(OBJEXT): {$(VPATH)}internal/newobj.h
+complex.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+complex.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+complex.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+complex.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+complex.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+complex.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+complex.$(OBJEXT): {$(VPATH)}internal/symbol.h
+complex.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+complex.$(OBJEXT): {$(VPATH)}internal/value.h
+complex.$(OBJEXT): {$(VPATH)}internal/value_type.h
+complex.$(OBJEXT): {$(VPATH)}internal/variable.h
+complex.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+complex.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
complex.$(OBJEXT): {$(VPATH)}missing.h
complex.$(OBJEXT): {$(VPATH)}onigmo.h
complex.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -1465,23 +3192,187 @@ cont.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
cont.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
cont.$(OBJEXT): $(CCAN_DIR)/list/list.h
cont.$(OBJEXT): $(CCAN_DIR)/str/str.h
+cont.$(OBJEXT): $(hdrdir)/ruby.h
cont.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-cont.$(OBJEXT): $(top_srcdir)/include/ruby.h
+cont.$(OBJEXT): $(top_srcdir)/internal/array.h
+cont.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+cont.$(OBJEXT): $(top_srcdir)/internal/cont.h
+cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
+cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+cont.$(OBJEXT): $(top_srcdir)/internal/proc.h
+cont.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
+cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
+cont.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+cont.$(OBJEXT): $(top_srcdir)/internal/vm.h
+cont.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+cont.$(OBJEXT): {$(VPATH)}$(COROUTINE_H)
+cont.$(OBJEXT): {$(VPATH)}assert.h
+cont.$(OBJEXT): {$(VPATH)}atomic.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+cont.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
cont.$(OBJEXT): {$(VPATH)}config.h
cont.$(OBJEXT): {$(VPATH)}cont.c
+cont.$(OBJEXT): {$(VPATH)}debug_counter.h
cont.$(OBJEXT): {$(VPATH)}defines.h
-cont.$(OBJEXT): {$(VPATH)}encoding.h
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
cont.$(OBJEXT): {$(VPATH)}gc.h
cont.$(OBJEXT): {$(VPATH)}id.h
+cont.$(OBJEXT): {$(VPATH)}id_table.h
cont.$(OBJEXT): {$(VPATH)}intern.h
cont.$(OBJEXT): {$(VPATH)}internal.h
-cont.$(OBJEXT): {$(VPATH)}io.h
+cont.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+cont.$(OBJEXT): {$(VPATH)}internal/assume.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+cont.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+cont.$(OBJEXT): {$(VPATH)}internal/cast.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+cont.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+cont.$(OBJEXT): {$(VPATH)}internal/config.h
+cont.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+cont.$(OBJEXT): {$(VPATH)}internal/core.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+cont.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+cont.$(OBJEXT): {$(VPATH)}internal/ctype.h
+cont.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+cont.$(OBJEXT): {$(VPATH)}internal/dosish.h
+cont.$(OBJEXT): {$(VPATH)}internal/error.h
+cont.$(OBJEXT): {$(VPATH)}internal/eval.h
+cont.$(OBJEXT): {$(VPATH)}internal/event.h
+cont.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+cont.$(OBJEXT): {$(VPATH)}internal/gc.h
+cont.$(OBJEXT): {$(VPATH)}internal/glob.h
+cont.$(OBJEXT): {$(VPATH)}internal/globals.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+cont.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+cont.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+cont.$(OBJEXT): {$(VPATH)}internal/iterator.h
+cont.$(OBJEXT): {$(VPATH)}internal/memory.h
+cont.$(OBJEXT): {$(VPATH)}internal/method.h
+cont.$(OBJEXT): {$(VPATH)}internal/module.h
+cont.$(OBJEXT): {$(VPATH)}internal/newobj.h
+cont.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+cont.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+cont.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+cont.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+cont.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+cont.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+cont.$(OBJEXT): {$(VPATH)}internal/symbol.h
+cont.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+cont.$(OBJEXT): {$(VPATH)}internal/value.h
+cont.$(OBJEXT): {$(VPATH)}internal/value_type.h
+cont.$(OBJEXT): {$(VPATH)}internal/variable.h
+cont.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+cont.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
cont.$(OBJEXT): {$(VPATH)}method.h
cont.$(OBJEXT): {$(VPATH)}missing.h
+cont.$(OBJEXT): {$(VPATH)}mjit.h
cont.$(OBJEXT): {$(VPATH)}node.h
-cont.$(OBJEXT): {$(VPATH)}onigmo.h
-cont.$(OBJEXT): {$(VPATH)}oniguruma.h
+cont.$(OBJEXT): {$(VPATH)}ractor.h
+cont.$(OBJEXT): {$(VPATH)}ractor_core.h
cont.$(OBJEXT): {$(VPATH)}ruby_assert.h
cont.$(OBJEXT): {$(VPATH)}ruby_atomic.h
cont.$(OBJEXT): {$(VPATH)}st.h
@@ -1495,87 +3386,1022 @@ debug.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
debug.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
debug.$(OBJEXT): $(CCAN_DIR)/list/list.h
debug.$(OBJEXT): $(CCAN_DIR)/str/str.h
+debug.$(OBJEXT): $(hdrdir)/ruby.h
debug.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-debug.$(OBJEXT): $(top_srcdir)/include/ruby.h
+debug.$(OBJEXT): $(top_srcdir)/internal/array.h
+debug.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+debug.$(OBJEXT): $(top_srcdir)/internal/gc.h
+debug.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+debug.$(OBJEXT): $(top_srcdir)/internal/serial.h
+debug.$(OBJEXT): $(top_srcdir)/internal/signal.h
+debug.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+debug.$(OBJEXT): $(top_srcdir)/internal/util.h
+debug.$(OBJEXT): $(top_srcdir)/internal/vm.h
+debug.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+debug.$(OBJEXT): {$(VPATH)}assert.h
+debug.$(OBJEXT): {$(VPATH)}atomic.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+debug.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
debug.$(OBJEXT): {$(VPATH)}config.h
debug.$(OBJEXT): {$(VPATH)}debug.c
+debug.$(OBJEXT): {$(VPATH)}debug_counter.h
debug.$(OBJEXT): {$(VPATH)}defines.h
debug.$(OBJEXT): {$(VPATH)}encoding.h
debug.$(OBJEXT): {$(VPATH)}eval_intern.h
debug.$(OBJEXT): {$(VPATH)}gc.h
debug.$(OBJEXT): {$(VPATH)}id.h
+debug.$(OBJEXT): {$(VPATH)}id_table.h
debug.$(OBJEXT): {$(VPATH)}intern.h
debug.$(OBJEXT): {$(VPATH)}internal.h
+debug.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+debug.$(OBJEXT): {$(VPATH)}internal/assume.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+debug.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+debug.$(OBJEXT): {$(VPATH)}internal/cast.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+debug.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+debug.$(OBJEXT): {$(VPATH)}internal/config.h
+debug.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+debug.$(OBJEXT): {$(VPATH)}internal/core.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+debug.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+debug.$(OBJEXT): {$(VPATH)}internal/ctype.h
+debug.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+debug.$(OBJEXT): {$(VPATH)}internal/dosish.h
+debug.$(OBJEXT): {$(VPATH)}internal/error.h
+debug.$(OBJEXT): {$(VPATH)}internal/eval.h
+debug.$(OBJEXT): {$(VPATH)}internal/event.h
+debug.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+debug.$(OBJEXT): {$(VPATH)}internal/gc.h
+debug.$(OBJEXT): {$(VPATH)}internal/glob.h
+debug.$(OBJEXT): {$(VPATH)}internal/globals.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+debug.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+debug.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+debug.$(OBJEXT): {$(VPATH)}internal/iterator.h
+debug.$(OBJEXT): {$(VPATH)}internal/memory.h
+debug.$(OBJEXT): {$(VPATH)}internal/method.h
+debug.$(OBJEXT): {$(VPATH)}internal/module.h
+debug.$(OBJEXT): {$(VPATH)}internal/newobj.h
+debug.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+debug.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+debug.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+debug.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+debug.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+debug.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+debug.$(OBJEXT): {$(VPATH)}internal/symbol.h
+debug.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+debug.$(OBJEXT): {$(VPATH)}internal/value.h
+debug.$(OBJEXT): {$(VPATH)}internal/value_type.h
+debug.$(OBJEXT): {$(VPATH)}internal/variable.h
+debug.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+debug.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
debug.$(OBJEXT): {$(VPATH)}io.h
debug.$(OBJEXT): {$(VPATH)}method.h
debug.$(OBJEXT): {$(VPATH)}missing.h
debug.$(OBJEXT): {$(VPATH)}node.h
debug.$(OBJEXT): {$(VPATH)}onigmo.h
debug.$(OBJEXT): {$(VPATH)}oniguruma.h
+debug.$(OBJEXT): {$(VPATH)}ractor.h
+debug.$(OBJEXT): {$(VPATH)}ractor_core.h
debug.$(OBJEXT): {$(VPATH)}ruby_assert.h
debug.$(OBJEXT): {$(VPATH)}ruby_atomic.h
debug.$(OBJEXT): {$(VPATH)}st.h
debug.$(OBJEXT): {$(VPATH)}subst.h
+debug.$(OBJEXT): {$(VPATH)}symbol.h
debug.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
debug.$(OBJEXT): {$(VPATH)}thread_native.h
debug.$(OBJEXT): {$(VPATH)}util.h
+debug.$(OBJEXT): {$(VPATH)}vm_callinfo.h
debug.$(OBJEXT): {$(VPATH)}vm_core.h
debug.$(OBJEXT): {$(VPATH)}vm_debug.h
debug.$(OBJEXT): {$(VPATH)}vm_opts.h
+debug_counter.$(OBJEXT): $(hdrdir)/ruby.h
debug_counter.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-debug_counter.$(OBJEXT): $(top_srcdir)/include/ruby.h
+debug_counter.$(OBJEXT): {$(VPATH)}assert.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+debug_counter.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
debug_counter.$(OBJEXT): {$(VPATH)}config.h
debug_counter.$(OBJEXT): {$(VPATH)}debug_counter.c
debug_counter.$(OBJEXT): {$(VPATH)}debug_counter.h
debug_counter.$(OBJEXT): {$(VPATH)}defines.h
-debug_counter.$(OBJEXT): {$(VPATH)}encoding.h
debug_counter.$(OBJEXT): {$(VPATH)}intern.h
debug_counter.$(OBJEXT): {$(VPATH)}internal.h
-debug_counter.$(OBJEXT): {$(VPATH)}io.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/assume.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/cast.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/config.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/ctype.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/dosish.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/error.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/eval.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/event.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/gc.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/glob.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/globals.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/iterator.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/memory.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/method.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/module.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/newobj.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/symbol.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/value.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/value_type.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/variable.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
debug_counter.$(OBJEXT): {$(VPATH)}missing.h
-debug_counter.$(OBJEXT): {$(VPATH)}onigmo.h
-debug_counter.$(OBJEXT): {$(VPATH)}oniguruma.h
debug_counter.$(OBJEXT): {$(VPATH)}st.h
debug_counter.$(OBJEXT): {$(VPATH)}subst.h
+debug_counter.$(OBJEXT): {$(VPATH)}thread_native.h
+dir.$(OBJEXT): $(hdrdir)/ruby.h
dir.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-dir.$(OBJEXT): $(top_srcdir)/include/ruby.h
+dir.$(OBJEXT): $(top_srcdir)/internal/array.h
+dir.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+dir.$(OBJEXT): $(top_srcdir)/internal/dir.h
+dir.$(OBJEXT): $(top_srcdir)/internal/encoding.h
+dir.$(OBJEXT): $(top_srcdir)/internal/error.h
+dir.$(OBJEXT): $(top_srcdir)/internal/file.h
+dir.$(OBJEXT): $(top_srcdir)/internal/gc.h
+dir.$(OBJEXT): $(top_srcdir)/internal/io.h
+dir.$(OBJEXT): $(top_srcdir)/internal/serial.h
+dir.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+dir.$(OBJEXT): $(top_srcdir)/internal/string.h
+dir.$(OBJEXT): $(top_srcdir)/internal/vm.h
+dir.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+dir.$(OBJEXT): {$(VPATH)}assert.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+dir.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+dir.$(OBJEXT): {$(VPATH)}builtin.h
dir.$(OBJEXT): {$(VPATH)}config.h
dir.$(OBJEXT): {$(VPATH)}defines.h
dir.$(OBJEXT): {$(VPATH)}dir.c
+dir.$(OBJEXT): {$(VPATH)}dir.rbinc
dir.$(OBJEXT): {$(VPATH)}encindex.h
dir.$(OBJEXT): {$(VPATH)}encoding.h
+dir.$(OBJEXT): {$(VPATH)}id.h
dir.$(OBJEXT): {$(VPATH)}intern.h
dir.$(OBJEXT): {$(VPATH)}internal.h
+dir.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+dir.$(OBJEXT): {$(VPATH)}internal/assume.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+dir.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+dir.$(OBJEXT): {$(VPATH)}internal/cast.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+dir.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+dir.$(OBJEXT): {$(VPATH)}internal/config.h
+dir.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+dir.$(OBJEXT): {$(VPATH)}internal/core.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+dir.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+dir.$(OBJEXT): {$(VPATH)}internal/ctype.h
+dir.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+dir.$(OBJEXT): {$(VPATH)}internal/dosish.h
+dir.$(OBJEXT): {$(VPATH)}internal/error.h
+dir.$(OBJEXT): {$(VPATH)}internal/eval.h
+dir.$(OBJEXT): {$(VPATH)}internal/event.h
+dir.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+dir.$(OBJEXT): {$(VPATH)}internal/gc.h
+dir.$(OBJEXT): {$(VPATH)}internal/glob.h
+dir.$(OBJEXT): {$(VPATH)}internal/globals.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+dir.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+dir.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+dir.$(OBJEXT): {$(VPATH)}internal/iterator.h
+dir.$(OBJEXT): {$(VPATH)}internal/memory.h
+dir.$(OBJEXT): {$(VPATH)}internal/method.h
+dir.$(OBJEXT): {$(VPATH)}internal/module.h
+dir.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dir.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+dir.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+dir.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+dir.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+dir.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+dir.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+dir.$(OBJEXT): {$(VPATH)}internal/symbol.h
+dir.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+dir.$(OBJEXT): {$(VPATH)}internal/value.h
+dir.$(OBJEXT): {$(VPATH)}internal/value_type.h
+dir.$(OBJEXT): {$(VPATH)}internal/variable.h
+dir.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+dir.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
dir.$(OBJEXT): {$(VPATH)}io.h
dir.$(OBJEXT): {$(VPATH)}missing.h
dir.$(OBJEXT): {$(VPATH)}onigmo.h
dir.$(OBJEXT): {$(VPATH)}oniguruma.h
dir.$(OBJEXT): {$(VPATH)}st.h
dir.$(OBJEXT): {$(VPATH)}subst.h
+dir.$(OBJEXT): {$(VPATH)}thread.h
dir.$(OBJEXT): {$(VPATH)}util.h
+dln.$(OBJEXT): $(hdrdir)/ruby.h
dln.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+dln.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+dln.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+dln.$(OBJEXT): {$(VPATH)}assert.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+dln.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
dln.$(OBJEXT): {$(VPATH)}config.h
dln.$(OBJEXT): {$(VPATH)}defines.h
dln.$(OBJEXT): {$(VPATH)}dln.c
dln.$(OBJEXT): {$(VPATH)}dln.h
dln.$(OBJEXT): {$(VPATH)}intern.h
+dln.$(OBJEXT): {$(VPATH)}internal.h
+dln.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+dln.$(OBJEXT): {$(VPATH)}internal/assume.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+dln.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+dln.$(OBJEXT): {$(VPATH)}internal/cast.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+dln.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+dln.$(OBJEXT): {$(VPATH)}internal/config.h
+dln.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+dln.$(OBJEXT): {$(VPATH)}internal/core.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+dln.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+dln.$(OBJEXT): {$(VPATH)}internal/ctype.h
+dln.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+dln.$(OBJEXT): {$(VPATH)}internal/dosish.h
+dln.$(OBJEXT): {$(VPATH)}internal/error.h
+dln.$(OBJEXT): {$(VPATH)}internal/eval.h
+dln.$(OBJEXT): {$(VPATH)}internal/event.h
+dln.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+dln.$(OBJEXT): {$(VPATH)}internal/gc.h
+dln.$(OBJEXT): {$(VPATH)}internal/glob.h
+dln.$(OBJEXT): {$(VPATH)}internal/globals.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+dln.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+dln.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+dln.$(OBJEXT): {$(VPATH)}internal/iterator.h
+dln.$(OBJEXT): {$(VPATH)}internal/memory.h
+dln.$(OBJEXT): {$(VPATH)}internal/method.h
+dln.$(OBJEXT): {$(VPATH)}internal/module.h
+dln.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dln.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+dln.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+dln.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+dln.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+dln.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+dln.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+dln.$(OBJEXT): {$(VPATH)}internal/symbol.h
+dln.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+dln.$(OBJEXT): {$(VPATH)}internal/value.h
+dln.$(OBJEXT): {$(VPATH)}internal/value_type.h
+dln.$(OBJEXT): {$(VPATH)}internal/variable.h
+dln.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+dln.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
dln.$(OBJEXT): {$(VPATH)}missing.h
dln.$(OBJEXT): {$(VPATH)}st.h
dln.$(OBJEXT): {$(VPATH)}subst.h
dln_find.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+dln_find.$(OBJEXT): {$(VPATH)}assert.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+dln_find.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
dln_find.$(OBJEXT): {$(VPATH)}config.h
dln_find.$(OBJEXT): {$(VPATH)}defines.h
dln_find.$(OBJEXT): {$(VPATH)}dln.h
dln_find.$(OBJEXT): {$(VPATH)}dln_find.c
dln_find.$(OBJEXT): {$(VPATH)}intern.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/assume.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/cast.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/config.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/ctype.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/dosish.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/error.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/eval.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/event.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/gc.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/glob.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/globals.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/iterator.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/memory.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/method.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/module.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/symbol.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/value.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/value_type.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/variable.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
dln_find.$(OBJEXT): {$(VPATH)}missing.h
dln_find.$(OBJEXT): {$(VPATH)}st.h
dln_find.$(OBJEXT): {$(VPATH)}subst.h
dmydln.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+dmydln.$(OBJEXT): {$(VPATH)}assert.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+dmydln.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
dmydln.$(OBJEXT): {$(VPATH)}config.h
dmydln.$(OBJEXT): {$(VPATH)}defines.h
dmydln.$(OBJEXT): {$(VPATH)}dmydln.c
dmydln.$(OBJEXT): {$(VPATH)}intern.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/assume.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/cast.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/config.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/ctype.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/dosish.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/error.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/eval.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/event.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/gc.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/glob.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/globals.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/iterator.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/memory.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/method.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/module.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/symbol.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/value.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/value_type.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/variable.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
dmydln.$(OBJEXT): {$(VPATH)}missing.h
dmydln.$(OBJEXT): {$(VPATH)}st.h
dmydln.$(OBJEXT): {$(VPATH)}subst.h
@@ -1586,7 +4412,6 @@ enc/ascii.$(OBJEXT): {$(VPATH)}defines.h
enc/ascii.$(OBJEXT): {$(VPATH)}enc/ascii.c
enc/ascii.$(OBJEXT): {$(VPATH)}encindex.h
enc/ascii.$(OBJEXT): {$(VPATH)}missing.h
-enc/ascii.$(OBJEXT): {$(VPATH)}oniguruma.h
enc/ascii.$(OBJEXT): {$(VPATH)}regenc.h
enc/trans/newline.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}config.h
@@ -1605,7 +4430,7 @@ enc/unicode.$(OBJEXT): {$(VPATH)}defines.h
enc/unicode.$(OBJEXT): {$(VPATH)}enc/unicode.c
enc/unicode.$(OBJEXT): {$(VPATH)}intern.h
enc/unicode.$(OBJEXT): {$(VPATH)}missing.h
-enc/unicode.$(OBJEXT): {$(VPATH)}oniguruma.h
+enc/unicode.$(OBJEXT): {$(VPATH)}onigmo.h
enc/unicode.$(OBJEXT): {$(VPATH)}regenc.h
enc/unicode.$(OBJEXT): {$(VPATH)}regint.h
enc/unicode.$(OBJEXT): {$(VPATH)}st.h
@@ -1615,26 +4440,189 @@ enc/us_ascii.$(OBJEXT): {$(VPATH)}defines.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}enc/us_ascii.c
enc/us_ascii.$(OBJEXT): {$(VPATH)}encindex.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}missing.h
-enc/us_ascii.$(OBJEXT): {$(VPATH)}oniguruma.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}regenc.h
enc/utf_8.$(OBJEXT): {$(VPATH)}config.h
enc/utf_8.$(OBJEXT): {$(VPATH)}defines.h
enc/utf_8.$(OBJEXT): {$(VPATH)}enc/utf_8.c
enc/utf_8.$(OBJEXT): {$(VPATH)}encindex.h
enc/utf_8.$(OBJEXT): {$(VPATH)}missing.h
-enc/utf_8.$(OBJEXT): {$(VPATH)}oniguruma.h
enc/utf_8.$(OBJEXT): {$(VPATH)}regenc.h
+encoding.$(OBJEXT): $(hdrdir)/ruby.h
encoding.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-encoding.$(OBJEXT): $(top_srcdir)/include/ruby.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/class.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/enc.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/encoding.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/gc.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/inits.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/load.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/object.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/serial.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/string.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/vm.h
+encoding.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+encoding.$(OBJEXT): {$(VPATH)}assert.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+encoding.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
encoding.$(OBJEXT): {$(VPATH)}config.h
+encoding.$(OBJEXT): {$(VPATH)}debug_counter.h
encoding.$(OBJEXT): {$(VPATH)}defines.h
encoding.$(OBJEXT): {$(VPATH)}encindex.h
encoding.$(OBJEXT): {$(VPATH)}encoding.c
encoding.$(OBJEXT): {$(VPATH)}encoding.h
+encoding.$(OBJEXT): {$(VPATH)}id_table.h
encoding.$(OBJEXT): {$(VPATH)}intern.h
encoding.$(OBJEXT): {$(VPATH)}internal.h
-encoding.$(OBJEXT): {$(VPATH)}io.h
+encoding.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+encoding.$(OBJEXT): {$(VPATH)}internal/assume.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+encoding.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+encoding.$(OBJEXT): {$(VPATH)}internal/cast.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+encoding.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+encoding.$(OBJEXT): {$(VPATH)}internal/config.h
+encoding.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+encoding.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+encoding.$(OBJEXT): {$(VPATH)}internal/ctype.h
+encoding.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+encoding.$(OBJEXT): {$(VPATH)}internal/dosish.h
+encoding.$(OBJEXT): {$(VPATH)}internal/error.h
+encoding.$(OBJEXT): {$(VPATH)}internal/eval.h
+encoding.$(OBJEXT): {$(VPATH)}internal/event.h
+encoding.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+encoding.$(OBJEXT): {$(VPATH)}internal/gc.h
+encoding.$(OBJEXT): {$(VPATH)}internal/glob.h
+encoding.$(OBJEXT): {$(VPATH)}internal/globals.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+encoding.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+encoding.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+encoding.$(OBJEXT): {$(VPATH)}internal/iterator.h
+encoding.$(OBJEXT): {$(VPATH)}internal/memory.h
+encoding.$(OBJEXT): {$(VPATH)}internal/method.h
+encoding.$(OBJEXT): {$(VPATH)}internal/module.h
+encoding.$(OBJEXT): {$(VPATH)}internal/newobj.h
+encoding.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+encoding.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+encoding.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+encoding.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+encoding.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+encoding.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+encoding.$(OBJEXT): {$(VPATH)}internal/symbol.h
+encoding.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+encoding.$(OBJEXT): {$(VPATH)}internal/value.h
+encoding.$(OBJEXT): {$(VPATH)}internal/value_type.h
+encoding.$(OBJEXT): {$(VPATH)}internal/variable.h
+encoding.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+encoding.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
encoding.$(OBJEXT): {$(VPATH)}missing.h
+encoding.$(OBJEXT): {$(VPATH)}node.h
encoding.$(OBJEXT): {$(VPATH)}onigmo.h
encoding.$(OBJEXT): {$(VPATH)}oniguruma.h
encoding.$(OBJEXT): {$(VPATH)}regenc.h
@@ -1642,50 +4630,566 @@ encoding.$(OBJEXT): {$(VPATH)}ruby_assert.h
encoding.$(OBJEXT): {$(VPATH)}st.h
encoding.$(OBJEXT): {$(VPATH)}subst.h
encoding.$(OBJEXT): {$(VPATH)}util.h
+encoding.$(OBJEXT): {$(VPATH)}vm_debug.h
+encoding.$(OBJEXT): {$(VPATH)}vm_sync.h
+enum.$(OBJEXT): $(hdrdir)/ruby.h
enum.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-enum.$(OBJEXT): $(top_srcdir)/include/ruby.h
+enum.$(OBJEXT): $(top_srcdir)/internal/array.h
+enum.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+enum.$(OBJEXT): $(top_srcdir)/internal/bits.h
+enum.$(OBJEXT): $(top_srcdir)/internal/class.h
+enum.$(OBJEXT): $(top_srcdir)/internal/compar.h
+enum.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+enum.$(OBJEXT): $(top_srcdir)/internal/enum.h
+enum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+enum.$(OBJEXT): $(top_srcdir)/internal/gc.h
+enum.$(OBJEXT): $(top_srcdir)/internal/hash.h
+enum.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+enum.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+enum.$(OBJEXT): $(top_srcdir)/internal/object.h
+enum.$(OBJEXT): $(top_srcdir)/internal/proc.h
+enum.$(OBJEXT): $(top_srcdir)/internal/rational.h
+enum.$(OBJEXT): $(top_srcdir)/internal/re.h
+enum.$(OBJEXT): $(top_srcdir)/internal/serial.h
+enum.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+enum.$(OBJEXT): $(top_srcdir)/internal/vm.h
+enum.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+enum.$(OBJEXT): {$(VPATH)}assert.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+enum.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
enum.$(OBJEXT): {$(VPATH)}config.h
enum.$(OBJEXT): {$(VPATH)}defines.h
enum.$(OBJEXT): {$(VPATH)}encoding.h
enum.$(OBJEXT): {$(VPATH)}enum.c
enum.$(OBJEXT): {$(VPATH)}id.h
+enum.$(OBJEXT): {$(VPATH)}id_table.h
enum.$(OBJEXT): {$(VPATH)}intern.h
enum.$(OBJEXT): {$(VPATH)}internal.h
-enum.$(OBJEXT): {$(VPATH)}io.h
+enum.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+enum.$(OBJEXT): {$(VPATH)}internal/assume.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+enum.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+enum.$(OBJEXT): {$(VPATH)}internal/cast.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+enum.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+enum.$(OBJEXT): {$(VPATH)}internal/config.h
+enum.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+enum.$(OBJEXT): {$(VPATH)}internal/core.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+enum.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+enum.$(OBJEXT): {$(VPATH)}internal/ctype.h
+enum.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+enum.$(OBJEXT): {$(VPATH)}internal/dosish.h
+enum.$(OBJEXT): {$(VPATH)}internal/error.h
+enum.$(OBJEXT): {$(VPATH)}internal/eval.h
+enum.$(OBJEXT): {$(VPATH)}internal/event.h
+enum.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+enum.$(OBJEXT): {$(VPATH)}internal/gc.h
+enum.$(OBJEXT): {$(VPATH)}internal/glob.h
+enum.$(OBJEXT): {$(VPATH)}internal/globals.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+enum.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+enum.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+enum.$(OBJEXT): {$(VPATH)}internal/iterator.h
+enum.$(OBJEXT): {$(VPATH)}internal/memory.h
+enum.$(OBJEXT): {$(VPATH)}internal/method.h
+enum.$(OBJEXT): {$(VPATH)}internal/module.h
+enum.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enum.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+enum.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+enum.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+enum.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+enum.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+enum.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+enum.$(OBJEXT): {$(VPATH)}internal/symbol.h
+enum.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+enum.$(OBJEXT): {$(VPATH)}internal/value.h
+enum.$(OBJEXT): {$(VPATH)}internal/value_type.h
+enum.$(OBJEXT): {$(VPATH)}internal/variable.h
+enum.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+enum.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
enum.$(OBJEXT): {$(VPATH)}missing.h
enum.$(OBJEXT): {$(VPATH)}onigmo.h
enum.$(OBJEXT): {$(VPATH)}oniguruma.h
+enum.$(OBJEXT): {$(VPATH)}ruby_assert.h
enum.$(OBJEXT): {$(VPATH)}st.h
enum.$(OBJEXT): {$(VPATH)}subst.h
enum.$(OBJEXT): {$(VPATH)}symbol.h
enum.$(OBJEXT): {$(VPATH)}util.h
+enumerator.$(OBJEXT): $(hdrdir)/ruby.h
enumerator.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-enumerator.$(OBJEXT): $(top_srcdir)/include/ruby.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/array.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/bits.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/enumerator.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/error.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/gc.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/hash.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/rational.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/serial.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/string.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/struct.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/vm.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+enumerator.$(OBJEXT): {$(VPATH)}assert.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+enumerator.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
enumerator.$(OBJEXT): {$(VPATH)}config.h
enumerator.$(OBJEXT): {$(VPATH)}defines.h
enumerator.$(OBJEXT): {$(VPATH)}encoding.h
enumerator.$(OBJEXT): {$(VPATH)}enumerator.c
+enumerator.$(OBJEXT): {$(VPATH)}id.h
enumerator.$(OBJEXT): {$(VPATH)}intern.h
enumerator.$(OBJEXT): {$(VPATH)}internal.h
-enumerator.$(OBJEXT): {$(VPATH)}io.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/assume.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/cast.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/config.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/ctype.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/dosish.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/error.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/eval.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/event.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/gc.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/glob.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/globals.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/iterator.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/memory.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/method.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/module.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/symbol.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/value.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/value_type.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/variable.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
enumerator.$(OBJEXT): {$(VPATH)}missing.h
enumerator.$(OBJEXT): {$(VPATH)}onigmo.h
enumerator.$(OBJEXT): {$(VPATH)}oniguruma.h
+enumerator.$(OBJEXT): {$(VPATH)}ruby_assert.h
enumerator.$(OBJEXT): {$(VPATH)}st.h
enumerator.$(OBJEXT): {$(VPATH)}subst.h
error.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
error.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
error.$(OBJEXT): $(CCAN_DIR)/list/list.h
error.$(OBJEXT): $(CCAN_DIR)/str/str.h
+error.$(OBJEXT): $(hdrdir)/ruby.h
error.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-error.$(OBJEXT): $(top_srcdir)/include/ruby.h
+error.$(OBJEXT): $(top_srcdir)/internal/array.h
+error.$(OBJEXT): $(top_srcdir)/internal/class.h
+error.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+error.$(OBJEXT): $(top_srcdir)/internal/error.h
+error.$(OBJEXT): $(top_srcdir)/internal/eval.h
+error.$(OBJEXT): $(top_srcdir)/internal/gc.h
+error.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+error.$(OBJEXT): $(top_srcdir)/internal/io.h
+error.$(OBJEXT): $(top_srcdir)/internal/load.h
+error.$(OBJEXT): $(top_srcdir)/internal/object.h
+error.$(OBJEXT): $(top_srcdir)/internal/serial.h
+error.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+error.$(OBJEXT): $(top_srcdir)/internal/string.h
+error.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+error.$(OBJEXT): $(top_srcdir)/internal/thread.h
+error.$(OBJEXT): $(top_srcdir)/internal/variable.h
+error.$(OBJEXT): $(top_srcdir)/internal/vm.h
+error.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+error.$(OBJEXT): {$(VPATH)}assert.h
+error.$(OBJEXT): {$(VPATH)}atomic.h
+error.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+error.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+error.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+error.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+error.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+error.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+error.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+error.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+error.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+error.$(OBJEXT): {$(VPATH)}builtin.h
error.$(OBJEXT): {$(VPATH)}config.h
+error.$(OBJEXT): {$(VPATH)}constant.h
error.$(OBJEXT): {$(VPATH)}defines.h
error.$(OBJEXT): {$(VPATH)}encoding.h
error.$(OBJEXT): {$(VPATH)}error.c
+error.$(OBJEXT): {$(VPATH)}eval_intern.h
error.$(OBJEXT): {$(VPATH)}id.h
+error.$(OBJEXT): {$(VPATH)}id_table.h
error.$(OBJEXT): {$(VPATH)}intern.h
error.$(OBJEXT): {$(VPATH)}internal.h
+error.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+error.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+error.$(OBJEXT): {$(VPATH)}internal/assume.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+error.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+error.$(OBJEXT): {$(VPATH)}internal/cast.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+error.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+error.$(OBJEXT): {$(VPATH)}internal/config.h
+error.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+error.$(OBJEXT): {$(VPATH)}internal/core.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+error.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+error.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+error.$(OBJEXT): {$(VPATH)}internal/ctype.h
+error.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+error.$(OBJEXT): {$(VPATH)}internal/dosish.h
+error.$(OBJEXT): {$(VPATH)}internal/error.h
+error.$(OBJEXT): {$(VPATH)}internal/eval.h
+error.$(OBJEXT): {$(VPATH)}internal/event.h
+error.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+error.$(OBJEXT): {$(VPATH)}internal/gc.h
+error.$(OBJEXT): {$(VPATH)}internal/glob.h
+error.$(OBJEXT): {$(VPATH)}internal/globals.h
+error.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+error.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+error.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+error.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+error.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+error.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+error.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+error.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+error.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+error.$(OBJEXT): {$(VPATH)}internal/iterator.h
+error.$(OBJEXT): {$(VPATH)}internal/memory.h
+error.$(OBJEXT): {$(VPATH)}internal/method.h
+error.$(OBJEXT): {$(VPATH)}internal/module.h
+error.$(OBJEXT): {$(VPATH)}internal/newobj.h
+error.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+error.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+error.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+error.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+error.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+error.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+error.$(OBJEXT): {$(VPATH)}internal/symbol.h
+error.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+error.$(OBJEXT): {$(VPATH)}internal/value.h
+error.$(OBJEXT): {$(VPATH)}internal/value_type.h
+error.$(OBJEXT): {$(VPATH)}internal/variable.h
+error.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+error.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
error.$(OBJEXT): {$(VPATH)}io.h
error.$(OBJEXT): {$(VPATH)}known_errors.inc
error.$(OBJEXT): {$(VPATH)}method.h
@@ -1700,15 +5204,47 @@ error.$(OBJEXT): {$(VPATH)}subst.h
error.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
error.$(OBJEXT): {$(VPATH)}thread_native.h
error.$(OBJEXT): {$(VPATH)}vm_core.h
-error.$(OBJEXT): {$(VPATH)}vm_debug.h
error.$(OBJEXT): {$(VPATH)}vm_opts.h
+error.$(OBJEXT): {$(VPATH)}warning.rbinc
eval.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
eval.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
eval.$(OBJEXT): $(CCAN_DIR)/list/list.h
eval.$(OBJEXT): $(CCAN_DIR)/str/str.h
+eval.$(OBJEXT): $(hdrdir)/ruby.h
eval.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-eval.$(OBJEXT): $(top_srcdir)/include/ruby.h
+eval.$(OBJEXT): $(top_srcdir)/internal/array.h
+eval.$(OBJEXT): $(top_srcdir)/internal/class.h
+eval.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+eval.$(OBJEXT): $(top_srcdir)/internal/error.h
+eval.$(OBJEXT): $(top_srcdir)/internal/eval.h
+eval.$(OBJEXT): $(top_srcdir)/internal/gc.h
+eval.$(OBJEXT): $(top_srcdir)/internal/hash.h
+eval.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+eval.$(OBJEXT): $(top_srcdir)/internal/inits.h
+eval.$(OBJEXT): $(top_srcdir)/internal/io.h
+eval.$(OBJEXT): $(top_srcdir)/internal/object.h
+eval.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
+eval.$(OBJEXT): $(top_srcdir)/internal/serial.h
+eval.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+eval.$(OBJEXT): $(top_srcdir)/internal/string.h
+eval.$(OBJEXT): $(top_srcdir)/internal/thread.h
+eval.$(OBJEXT): $(top_srcdir)/internal/variable.h
+eval.$(OBJEXT): $(top_srcdir)/internal/vm.h
+eval.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+eval.$(OBJEXT): {$(VPATH)}assert.h
+eval.$(OBJEXT): {$(VPATH)}atomic.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+eval.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
eval.$(OBJEXT): {$(VPATH)}config.h
+eval.$(OBJEXT): {$(VPATH)}constant.h
+eval.$(OBJEXT): {$(VPATH)}debug_counter.h
eval.$(OBJEXT): {$(VPATH)}defines.h
eval.$(OBJEXT): {$(VPATH)}encoding.h
eval.$(OBJEXT): {$(VPATH)}eval.c
@@ -1717,18 +5253,162 @@ eval.$(OBJEXT): {$(VPATH)}eval_intern.h
eval.$(OBJEXT): {$(VPATH)}eval_jump.c
eval.$(OBJEXT): {$(VPATH)}gc.h
eval.$(OBJEXT): {$(VPATH)}id.h
+eval.$(OBJEXT): {$(VPATH)}id_table.h
eval.$(OBJEXT): {$(VPATH)}intern.h
eval.$(OBJEXT): {$(VPATH)}internal.h
+eval.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+eval.$(OBJEXT): {$(VPATH)}internal/assume.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+eval.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+eval.$(OBJEXT): {$(VPATH)}internal/cast.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+eval.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+eval.$(OBJEXT): {$(VPATH)}internal/config.h
+eval.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+eval.$(OBJEXT): {$(VPATH)}internal/core.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+eval.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+eval.$(OBJEXT): {$(VPATH)}internal/ctype.h
+eval.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+eval.$(OBJEXT): {$(VPATH)}internal/dosish.h
+eval.$(OBJEXT): {$(VPATH)}internal/error.h
+eval.$(OBJEXT): {$(VPATH)}internal/eval.h
+eval.$(OBJEXT): {$(VPATH)}internal/event.h
+eval.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+eval.$(OBJEXT): {$(VPATH)}internal/gc.h
+eval.$(OBJEXT): {$(VPATH)}internal/glob.h
+eval.$(OBJEXT): {$(VPATH)}internal/globals.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+eval.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+eval.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+eval.$(OBJEXT): {$(VPATH)}internal/iterator.h
+eval.$(OBJEXT): {$(VPATH)}internal/memory.h
+eval.$(OBJEXT): {$(VPATH)}internal/method.h
+eval.$(OBJEXT): {$(VPATH)}internal/module.h
+eval.$(OBJEXT): {$(VPATH)}internal/newobj.h
+eval.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+eval.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+eval.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+eval.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+eval.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+eval.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+eval.$(OBJEXT): {$(VPATH)}internal/symbol.h
+eval.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+eval.$(OBJEXT): {$(VPATH)}internal/value.h
+eval.$(OBJEXT): {$(VPATH)}internal/value_type.h
+eval.$(OBJEXT): {$(VPATH)}internal/variable.h
+eval.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+eval.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
eval.$(OBJEXT): {$(VPATH)}io.h
eval.$(OBJEXT): {$(VPATH)}iseq.h
eval.$(OBJEXT): {$(VPATH)}method.h
eval.$(OBJEXT): {$(VPATH)}missing.h
+eval.$(OBJEXT): {$(VPATH)}mjit.h
eval.$(OBJEXT): {$(VPATH)}node.h
eval.$(OBJEXT): {$(VPATH)}onigmo.h
eval.$(OBJEXT): {$(VPATH)}oniguruma.h
eval.$(OBJEXT): {$(VPATH)}probes.dmyh
eval.$(OBJEXT): {$(VPATH)}probes.h
eval.$(OBJEXT): {$(VPATH)}probes_helper.h
+eval.$(OBJEXT): {$(VPATH)}ractor.h
+eval.$(OBJEXT): {$(VPATH)}ractor_core.h
eval.$(OBJEXT): {$(VPATH)}ruby_assert.h
eval.$(OBJEXT): {$(VPATH)}ruby_atomic.h
eval.$(OBJEXT): {$(VPATH)}st.h
@@ -1741,9 +5421,47 @@ eval.$(OBJEXT): {$(VPATH)}vm_debug.h
eval.$(OBJEXT): {$(VPATH)}vm_opts.h
explicit_bzero.$(OBJEXT): {$(VPATH)}config.h
explicit_bzero.$(OBJEXT): {$(VPATH)}explicit_bzero.c
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/config.h
+explicit_bzero.$(OBJEXT): {$(VPATH)}internal/dllexport.h
explicit_bzero.$(OBJEXT): {$(VPATH)}missing.h
+file.$(OBJEXT): $(hdrdir)/ruby.h
file.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-file.$(OBJEXT): $(top_srcdir)/include/ruby.h
+file.$(OBJEXT): $(top_srcdir)/internal/array.h
+file.$(OBJEXT): $(top_srcdir)/internal/class.h
+file.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+file.$(OBJEXT): $(top_srcdir)/internal/dir.h
+file.$(OBJEXT): $(top_srcdir)/internal/error.h
+file.$(OBJEXT): $(top_srcdir)/internal/file.h
+file.$(OBJEXT): $(top_srcdir)/internal/gc.h
+file.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+file.$(OBJEXT): $(top_srcdir)/internal/io.h
+file.$(OBJEXT): $(top_srcdir)/internal/load.h
+file.$(OBJEXT): $(top_srcdir)/internal/object.h
+file.$(OBJEXT): $(top_srcdir)/internal/process.h
+file.$(OBJEXT): $(top_srcdir)/internal/serial.h
+file.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+file.$(OBJEXT): $(top_srcdir)/internal/string.h
+file.$(OBJEXT): $(top_srcdir)/internal/thread.h
+file.$(OBJEXT): $(top_srcdir)/internal/vm.h
+file.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+file.$(OBJEXT): {$(VPATH)}assert.h
+file.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+file.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+file.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+file.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+file.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+file.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+file.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+file.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+file.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
file.$(OBJEXT): {$(VPATH)}config.h
file.$(OBJEXT): {$(VPATH)}defines.h
file.$(OBJEXT): {$(VPATH)}dln.h
@@ -1751,8 +5469,149 @@ file.$(OBJEXT): {$(VPATH)}encindex.h
file.$(OBJEXT): {$(VPATH)}encoding.h
file.$(OBJEXT): {$(VPATH)}file.c
file.$(OBJEXT): {$(VPATH)}id.h
+file.$(OBJEXT): {$(VPATH)}id_table.h
file.$(OBJEXT): {$(VPATH)}intern.h
file.$(OBJEXT): {$(VPATH)}internal.h
+file.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+file.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+file.$(OBJEXT): {$(VPATH)}internal/assume.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+file.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+file.$(OBJEXT): {$(VPATH)}internal/cast.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+file.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+file.$(OBJEXT): {$(VPATH)}internal/config.h
+file.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+file.$(OBJEXT): {$(VPATH)}internal/core.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+file.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+file.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+file.$(OBJEXT): {$(VPATH)}internal/ctype.h
+file.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+file.$(OBJEXT): {$(VPATH)}internal/dosish.h
+file.$(OBJEXT): {$(VPATH)}internal/error.h
+file.$(OBJEXT): {$(VPATH)}internal/eval.h
+file.$(OBJEXT): {$(VPATH)}internal/event.h
+file.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+file.$(OBJEXT): {$(VPATH)}internal/gc.h
+file.$(OBJEXT): {$(VPATH)}internal/glob.h
+file.$(OBJEXT): {$(VPATH)}internal/globals.h
+file.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+file.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+file.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+file.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+file.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+file.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+file.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+file.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+file.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+file.$(OBJEXT): {$(VPATH)}internal/iterator.h
+file.$(OBJEXT): {$(VPATH)}internal/memory.h
+file.$(OBJEXT): {$(VPATH)}internal/method.h
+file.$(OBJEXT): {$(VPATH)}internal/module.h
+file.$(OBJEXT): {$(VPATH)}internal/newobj.h
+file.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+file.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+file.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+file.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+file.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+file.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+file.$(OBJEXT): {$(VPATH)}internal/symbol.h
+file.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+file.$(OBJEXT): {$(VPATH)}internal/value.h
+file.$(OBJEXT): {$(VPATH)}internal/value_type.h
+file.$(OBJEXT): {$(VPATH)}internal/variable.h
+file.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+file.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
file.$(OBJEXT): {$(VPATH)}io.h
file.$(OBJEXT): {$(VPATH)}missing.h
file.$(OBJEXT): {$(VPATH)}onigmo.h
@@ -1765,8 +5624,48 @@ gc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
gc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
gc.$(OBJEXT): $(CCAN_DIR)/list/list.h
gc.$(OBJEXT): $(CCAN_DIR)/str/str.h
+gc.$(OBJEXT): $(hdrdir)/ruby.h
gc.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-gc.$(OBJEXT): $(top_srcdir)/include/ruby.h
+gc.$(OBJEXT): $(top_srcdir)/internal/array.h
+gc.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+gc.$(OBJEXT): $(top_srcdir)/internal/bits.h
+gc.$(OBJEXT): $(top_srcdir)/internal/class.h
+gc.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+gc.$(OBJEXT): $(top_srcdir)/internal/complex.h
+gc.$(OBJEXT): $(top_srcdir)/internal/cont.h
+gc.$(OBJEXT): $(top_srcdir)/internal/error.h
+gc.$(OBJEXT): $(top_srcdir)/internal/eval.h
+gc.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+gc.$(OBJEXT): $(top_srcdir)/internal/gc.h
+gc.$(OBJEXT): $(top_srcdir)/internal/hash.h
+gc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+gc.$(OBJEXT): $(top_srcdir)/internal/io.h
+gc.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+gc.$(OBJEXT): $(top_srcdir)/internal/object.h
+gc.$(OBJEXT): $(top_srcdir)/internal/proc.h
+gc.$(OBJEXT): $(top_srcdir)/internal/rational.h
+gc.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+gc.$(OBJEXT): $(top_srcdir)/internal/serial.h
+gc.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+gc.$(OBJEXT): $(top_srcdir)/internal/string.h
+gc.$(OBJEXT): $(top_srcdir)/internal/struct.h
+gc.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+gc.$(OBJEXT): $(top_srcdir)/internal/thread.h
+gc.$(OBJEXT): $(top_srcdir)/internal/variable.h
+gc.$(OBJEXT): $(top_srcdir)/internal/vm.h
+gc.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+gc.$(OBJEXT): {$(VPATH)}assert.h
+gc.$(OBJEXT): {$(VPATH)}atomic.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+gc.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+gc.$(OBJEXT): {$(VPATH)}builtin.h
gc.$(OBJEXT): {$(VPATH)}config.h
gc.$(OBJEXT): {$(VPATH)}constant.h
gc.$(OBJEXT): {$(VPATH)}debug.h
@@ -1776,18 +5675,163 @@ gc.$(OBJEXT): {$(VPATH)}encoding.h
gc.$(OBJEXT): {$(VPATH)}eval_intern.h
gc.$(OBJEXT): {$(VPATH)}gc.c
gc.$(OBJEXT): {$(VPATH)}gc.h
+gc.$(OBJEXT): {$(VPATH)}gc.rbinc
gc.$(OBJEXT): {$(VPATH)}id.h
gc.$(OBJEXT): {$(VPATH)}id_table.h
gc.$(OBJEXT): {$(VPATH)}intern.h
gc.$(OBJEXT): {$(VPATH)}internal.h
+gc.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+gc.$(OBJEXT): {$(VPATH)}internal/assume.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+gc.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+gc.$(OBJEXT): {$(VPATH)}internal/cast.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+gc.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+gc.$(OBJEXT): {$(VPATH)}internal/config.h
+gc.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+gc.$(OBJEXT): {$(VPATH)}internal/core.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rmatch.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+gc.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+gc.$(OBJEXT): {$(VPATH)}internal/ctype.h
+gc.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+gc.$(OBJEXT): {$(VPATH)}internal/dosish.h
+gc.$(OBJEXT): {$(VPATH)}internal/error.h
+gc.$(OBJEXT): {$(VPATH)}internal/eval.h
+gc.$(OBJEXT): {$(VPATH)}internal/event.h
+gc.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+gc.$(OBJEXT): {$(VPATH)}internal/gc.h
+gc.$(OBJEXT): {$(VPATH)}internal/glob.h
+gc.$(OBJEXT): {$(VPATH)}internal/globals.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+gc.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+gc.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+gc.$(OBJEXT): {$(VPATH)}internal/iterator.h
+gc.$(OBJEXT): {$(VPATH)}internal/memory.h
+gc.$(OBJEXT): {$(VPATH)}internal/method.h
+gc.$(OBJEXT): {$(VPATH)}internal/module.h
+gc.$(OBJEXT): {$(VPATH)}internal/newobj.h
+gc.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+gc.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+gc.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+gc.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+gc.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+gc.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+gc.$(OBJEXT): {$(VPATH)}internal/symbol.h
+gc.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+gc.$(OBJEXT): {$(VPATH)}internal/value.h
+gc.$(OBJEXT): {$(VPATH)}internal/value_type.h
+gc.$(OBJEXT): {$(VPATH)}internal/variable.h
+gc.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+gc.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
gc.$(OBJEXT): {$(VPATH)}io.h
gc.$(OBJEXT): {$(VPATH)}method.h
gc.$(OBJEXT): {$(VPATH)}missing.h
+gc.$(OBJEXT): {$(VPATH)}mjit.h
gc.$(OBJEXT): {$(VPATH)}node.h
gc.$(OBJEXT): {$(VPATH)}onigmo.h
gc.$(OBJEXT): {$(VPATH)}oniguruma.h
gc.$(OBJEXT): {$(VPATH)}probes.dmyh
gc.$(OBJEXT): {$(VPATH)}probes.h
+gc.$(OBJEXT): {$(VPATH)}ractor.h
+gc.$(OBJEXT): {$(VPATH)}ractor_core.h
gc.$(OBJEXT): {$(VPATH)}re.h
gc.$(OBJEXT): {$(VPATH)}regenc.h
gc.$(OBJEXT): {$(VPATH)}regex.h
@@ -1796,33 +5840,193 @@ gc.$(OBJEXT): {$(VPATH)}ruby_assert.h
gc.$(OBJEXT): {$(VPATH)}ruby_atomic.h
gc.$(OBJEXT): {$(VPATH)}st.h
gc.$(OBJEXT): {$(VPATH)}subst.h
+gc.$(OBJEXT): {$(VPATH)}symbol.h
gc.$(OBJEXT): {$(VPATH)}thread.h
gc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
gc.$(OBJEXT): {$(VPATH)}thread_native.h
+gc.$(OBJEXT): {$(VPATH)}transient_heap.h
gc.$(OBJEXT): {$(VPATH)}util.h
+gc.$(OBJEXT): {$(VPATH)}vm_callinfo.h
gc.$(OBJEXT): {$(VPATH)}vm_core.h
gc.$(OBJEXT): {$(VPATH)}vm_debug.h
gc.$(OBJEXT): {$(VPATH)}vm_opts.h
+gc.$(OBJEXT): {$(VPATH)}vm_sync.h
golf_prelude.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
golf_prelude.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
golf_prelude.$(OBJEXT): $(CCAN_DIR)/list/list.h
golf_prelude.$(OBJEXT): $(CCAN_DIR)/str/str.h
+golf_prelude.$(OBJEXT): $(hdrdir)/ruby.h
golf_prelude.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-golf_prelude.$(OBJEXT): $(top_srcdir)/include/ruby.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/array.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/gc.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/serial.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/vm.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+golf_prelude.$(OBJEXT): {$(VPATH)}assert.h
+golf_prelude.$(OBJEXT): {$(VPATH)}atomic.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+golf_prelude.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
golf_prelude.$(OBJEXT): {$(VPATH)}config.h
golf_prelude.$(OBJEXT): {$(VPATH)}defines.h
-golf_prelude.$(OBJEXT): {$(VPATH)}encoding.h
golf_prelude.$(OBJEXT): {$(VPATH)}golf_prelude.c
+golf_prelude.$(OBJEXT): {$(VPATH)}golf_prelude.rb
golf_prelude.$(OBJEXT): {$(VPATH)}id.h
golf_prelude.$(OBJEXT): {$(VPATH)}intern.h
golf_prelude.$(OBJEXT): {$(VPATH)}internal.h
-golf_prelude.$(OBJEXT): {$(VPATH)}io.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/assume.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/cast.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/config.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/ctype.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/dosish.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/error.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/eval.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/event.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/gc.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/glob.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/globals.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/iterator.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/memory.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/method.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/module.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/newobj.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/symbol.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/value.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/value_type.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/variable.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
golf_prelude.$(OBJEXT): {$(VPATH)}iseq.h
golf_prelude.$(OBJEXT): {$(VPATH)}method.h
golf_prelude.$(OBJEXT): {$(VPATH)}missing.h
golf_prelude.$(OBJEXT): {$(VPATH)}node.h
-golf_prelude.$(OBJEXT): {$(VPATH)}onigmo.h
-golf_prelude.$(OBJEXT): {$(VPATH)}oniguruma.h
golf_prelude.$(OBJEXT): {$(VPATH)}ruby_assert.h
golf_prelude.$(OBJEXT): {$(VPATH)}ruby_atomic.h
golf_prelude.$(OBJEXT): {$(VPATH)}st.h
@@ -1830,96 +6034,933 @@ golf_prelude.$(OBJEXT): {$(VPATH)}subst.h
golf_prelude.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
golf_prelude.$(OBJEXT): {$(VPATH)}thread_native.h
golf_prelude.$(OBJEXT): {$(VPATH)}vm_core.h
-golf_prelude.$(OBJEXT): {$(VPATH)}vm_debug.h
golf_prelude.$(OBJEXT): {$(VPATH)}vm_opts.h
+goruby.$(OBJEXT): $(hdrdir)/ruby.h
goruby.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-goruby.$(OBJEXT): $(top_srcdir)/include/ruby.h
+goruby.$(OBJEXT): {$(VPATH)}assert.h
goruby.$(OBJEXT): {$(VPATH)}backward.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+goruby.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
goruby.$(OBJEXT): {$(VPATH)}config.h
goruby.$(OBJEXT): {$(VPATH)}defines.h
goruby.$(OBJEXT): {$(VPATH)}goruby.c
goruby.$(OBJEXT): {$(VPATH)}intern.h
+goruby.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+goruby.$(OBJEXT): {$(VPATH)}internal/assume.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+goruby.$(OBJEXT): {$(VPATH)}internal/cast.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+goruby.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+goruby.$(OBJEXT): {$(VPATH)}internal/config.h
+goruby.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+goruby.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+goruby.$(OBJEXT): {$(VPATH)}internal/ctype.h
+goruby.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+goruby.$(OBJEXT): {$(VPATH)}internal/dosish.h
+goruby.$(OBJEXT): {$(VPATH)}internal/error.h
+goruby.$(OBJEXT): {$(VPATH)}internal/eval.h
+goruby.$(OBJEXT): {$(VPATH)}internal/event.h
+goruby.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+goruby.$(OBJEXT): {$(VPATH)}internal/gc.h
+goruby.$(OBJEXT): {$(VPATH)}internal/glob.h
+goruby.$(OBJEXT): {$(VPATH)}internal/globals.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+goruby.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+goruby.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+goruby.$(OBJEXT): {$(VPATH)}internal/iterator.h
+goruby.$(OBJEXT): {$(VPATH)}internal/memory.h
+goruby.$(OBJEXT): {$(VPATH)}internal/method.h
+goruby.$(OBJEXT): {$(VPATH)}internal/module.h
+goruby.$(OBJEXT): {$(VPATH)}internal/newobj.h
+goruby.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+goruby.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+goruby.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+goruby.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+goruby.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+goruby.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+goruby.$(OBJEXT): {$(VPATH)}internal/symbol.h
+goruby.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+goruby.$(OBJEXT): {$(VPATH)}internal/value.h
+goruby.$(OBJEXT): {$(VPATH)}internal/value_type.h
+goruby.$(OBJEXT): {$(VPATH)}internal/variable.h
+goruby.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+goruby.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
goruby.$(OBJEXT): {$(VPATH)}main.c
goruby.$(OBJEXT): {$(VPATH)}missing.h
goruby.$(OBJEXT): {$(VPATH)}node.h
goruby.$(OBJEXT): {$(VPATH)}st.h
goruby.$(OBJEXT): {$(VPATH)}subst.h
goruby.$(OBJEXT): {$(VPATH)}vm_debug.h
+hash.$(OBJEXT): $(hdrdir)/ruby.h
hash.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-hash.$(OBJEXT): $(top_srcdir)/include/ruby.h
+hash.$(OBJEXT): $(top_srcdir)/internal/array.h
+hash.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+hash.$(OBJEXT): $(top_srcdir)/internal/bits.h
+hash.$(OBJEXT): $(top_srcdir)/internal/class.h
+hash.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+hash.$(OBJEXT): $(top_srcdir)/internal/cont.h
+hash.$(OBJEXT): $(top_srcdir)/internal/error.h
+hash.$(OBJEXT): $(top_srcdir)/internal/gc.h
+hash.$(OBJEXT): $(top_srcdir)/internal/hash.h
+hash.$(OBJEXT): $(top_srcdir)/internal/object.h
+hash.$(OBJEXT): $(top_srcdir)/internal/proc.h
+hash.$(OBJEXT): $(top_srcdir)/internal/serial.h
+hash.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+hash.$(OBJEXT): $(top_srcdir)/internal/string.h
+hash.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+hash.$(OBJEXT): $(top_srcdir)/internal/time.h
+hash.$(OBJEXT): $(top_srcdir)/internal/vm.h
+hash.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+hash.$(OBJEXT): {$(VPATH)}assert.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+hash.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
hash.$(OBJEXT): {$(VPATH)}config.h
+hash.$(OBJEXT): {$(VPATH)}debug_counter.h
hash.$(OBJEXT): {$(VPATH)}defines.h
hash.$(OBJEXT): {$(VPATH)}encoding.h
hash.$(OBJEXT): {$(VPATH)}hash.c
hash.$(OBJEXT): {$(VPATH)}id.h
+hash.$(OBJEXT): {$(VPATH)}id_table.h
hash.$(OBJEXT): {$(VPATH)}intern.h
hash.$(OBJEXT): {$(VPATH)}internal.h
-hash.$(OBJEXT): {$(VPATH)}io.h
+hash.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+hash.$(OBJEXT): {$(VPATH)}internal/assume.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+hash.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+hash.$(OBJEXT): {$(VPATH)}internal/cast.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+hash.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+hash.$(OBJEXT): {$(VPATH)}internal/config.h
+hash.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+hash.$(OBJEXT): {$(VPATH)}internal/core.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+hash.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+hash.$(OBJEXT): {$(VPATH)}internal/ctype.h
+hash.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+hash.$(OBJEXT): {$(VPATH)}internal/dosish.h
+hash.$(OBJEXT): {$(VPATH)}internal/error.h
+hash.$(OBJEXT): {$(VPATH)}internal/eval.h
+hash.$(OBJEXT): {$(VPATH)}internal/event.h
+hash.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+hash.$(OBJEXT): {$(VPATH)}internal/gc.h
+hash.$(OBJEXT): {$(VPATH)}internal/glob.h
+hash.$(OBJEXT): {$(VPATH)}internal/globals.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+hash.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+hash.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+hash.$(OBJEXT): {$(VPATH)}internal/iterator.h
+hash.$(OBJEXT): {$(VPATH)}internal/memory.h
+hash.$(OBJEXT): {$(VPATH)}internal/method.h
+hash.$(OBJEXT): {$(VPATH)}internal/module.h
+hash.$(OBJEXT): {$(VPATH)}internal/newobj.h
+hash.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+hash.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+hash.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+hash.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+hash.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+hash.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+hash.$(OBJEXT): {$(VPATH)}internal/symbol.h
+hash.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+hash.$(OBJEXT): {$(VPATH)}internal/value.h
+hash.$(OBJEXT): {$(VPATH)}internal/value_type.h
+hash.$(OBJEXT): {$(VPATH)}internal/variable.h
+hash.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+hash.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
hash.$(OBJEXT): {$(VPATH)}missing.h
hash.$(OBJEXT): {$(VPATH)}onigmo.h
hash.$(OBJEXT): {$(VPATH)}oniguruma.h
hash.$(OBJEXT): {$(VPATH)}probes.dmyh
hash.$(OBJEXT): {$(VPATH)}probes.h
+hash.$(OBJEXT): {$(VPATH)}ruby_assert.h
hash.$(OBJEXT): {$(VPATH)}st.h
hash.$(OBJEXT): {$(VPATH)}subst.h
hash.$(OBJEXT): {$(VPATH)}symbol.h
+hash.$(OBJEXT): {$(VPATH)}transient_heap.h
hash.$(OBJEXT): {$(VPATH)}util.h
+inits.$(OBJEXT): $(hdrdir)/ruby.h
inits.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-inits.$(OBJEXT): $(top_srcdir)/include/ruby.h
+inits.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+inits.$(OBJEXT): $(top_srcdir)/internal/inits.h
+inits.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+inits.$(OBJEXT): {$(VPATH)}assert.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+inits.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+inits.$(OBJEXT): {$(VPATH)}builtin.h
inits.$(OBJEXT): {$(VPATH)}config.h
inits.$(OBJEXT): {$(VPATH)}defines.h
-inits.$(OBJEXT): {$(VPATH)}encoding.h
inits.$(OBJEXT): {$(VPATH)}inits.c
inits.$(OBJEXT): {$(VPATH)}intern.h
inits.$(OBJEXT): {$(VPATH)}internal.h
-inits.$(OBJEXT): {$(VPATH)}io.h
+inits.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+inits.$(OBJEXT): {$(VPATH)}internal/assume.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+inits.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+inits.$(OBJEXT): {$(VPATH)}internal/cast.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+inits.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+inits.$(OBJEXT): {$(VPATH)}internal/config.h
+inits.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+inits.$(OBJEXT): {$(VPATH)}internal/core.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+inits.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+inits.$(OBJEXT): {$(VPATH)}internal/ctype.h
+inits.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+inits.$(OBJEXT): {$(VPATH)}internal/dosish.h
+inits.$(OBJEXT): {$(VPATH)}internal/error.h
+inits.$(OBJEXT): {$(VPATH)}internal/eval.h
+inits.$(OBJEXT): {$(VPATH)}internal/event.h
+inits.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+inits.$(OBJEXT): {$(VPATH)}internal/gc.h
+inits.$(OBJEXT): {$(VPATH)}internal/glob.h
+inits.$(OBJEXT): {$(VPATH)}internal/globals.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+inits.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+inits.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+inits.$(OBJEXT): {$(VPATH)}internal/iterator.h
+inits.$(OBJEXT): {$(VPATH)}internal/memory.h
+inits.$(OBJEXT): {$(VPATH)}internal/method.h
+inits.$(OBJEXT): {$(VPATH)}internal/module.h
+inits.$(OBJEXT): {$(VPATH)}internal/newobj.h
+inits.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+inits.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+inits.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+inits.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+inits.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+inits.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+inits.$(OBJEXT): {$(VPATH)}internal/symbol.h
+inits.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+inits.$(OBJEXT): {$(VPATH)}internal/value.h
+inits.$(OBJEXT): {$(VPATH)}internal/value_type.h
+inits.$(OBJEXT): {$(VPATH)}internal/variable.h
+inits.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+inits.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
inits.$(OBJEXT): {$(VPATH)}missing.h
-inits.$(OBJEXT): {$(VPATH)}onigmo.h
-inits.$(OBJEXT): {$(VPATH)}oniguruma.h
+inits.$(OBJEXT): {$(VPATH)}prelude.rbinc
inits.$(OBJEXT): {$(VPATH)}st.h
inits.$(OBJEXT): {$(VPATH)}subst.h
+io.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+io.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+io.$(OBJEXT): $(CCAN_DIR)/list/list.h
+io.$(OBJEXT): $(CCAN_DIR)/str/str.h
+io.$(OBJEXT): $(hdrdir)/ruby.h
io.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-io.$(OBJEXT): $(top_srcdir)/include/ruby.h
+io.$(OBJEXT): $(top_srcdir)/internal/array.h
+io.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+io.$(OBJEXT): $(top_srcdir)/internal/bits.h
+io.$(OBJEXT): $(top_srcdir)/internal/class.h
+io.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+io.$(OBJEXT): $(top_srcdir)/internal/encoding.h
+io.$(OBJEXT): $(top_srcdir)/internal/error.h
+io.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+io.$(OBJEXT): $(top_srcdir)/internal/gc.h
+io.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+io.$(OBJEXT): $(top_srcdir)/internal/inits.h
+io.$(OBJEXT): $(top_srcdir)/internal/io.h
+io.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+io.$(OBJEXT): $(top_srcdir)/internal/object.h
+io.$(OBJEXT): $(top_srcdir)/internal/process.h
+io.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
+io.$(OBJEXT): $(top_srcdir)/internal/serial.h
+io.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+io.$(OBJEXT): $(top_srcdir)/internal/string.h
+io.$(OBJEXT): $(top_srcdir)/internal/thread.h
+io.$(OBJEXT): $(top_srcdir)/internal/transcode.h
+io.$(OBJEXT): $(top_srcdir)/internal/variable.h
+io.$(OBJEXT): $(top_srcdir)/internal/vm.h
+io.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+io.$(OBJEXT): {$(VPATH)}assert.h
+io.$(OBJEXT): {$(VPATH)}atomic.h
+io.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+io.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+io.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+io.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+io.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+io.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+io.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+io.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+io.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+io.$(OBJEXT): {$(VPATH)}builtin.h
io.$(OBJEXT): {$(VPATH)}config.h
+io.$(OBJEXT): {$(VPATH)}constant.h
io.$(OBJEXT): {$(VPATH)}defines.h
io.$(OBJEXT): {$(VPATH)}dln.h
io.$(OBJEXT): {$(VPATH)}encindex.h
io.$(OBJEXT): {$(VPATH)}encoding.h
io.$(OBJEXT): {$(VPATH)}id.h
+io.$(OBJEXT): {$(VPATH)}id_table.h
io.$(OBJEXT): {$(VPATH)}intern.h
io.$(OBJEXT): {$(VPATH)}internal.h
+io.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+io.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+io.$(OBJEXT): {$(VPATH)}internal/assume.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+io.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+io.$(OBJEXT): {$(VPATH)}internal/cast.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+io.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+io.$(OBJEXT): {$(VPATH)}internal/config.h
+io.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+io.$(OBJEXT): {$(VPATH)}internal/core.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+io.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+io.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+io.$(OBJEXT): {$(VPATH)}internal/ctype.h
+io.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+io.$(OBJEXT): {$(VPATH)}internal/dosish.h
+io.$(OBJEXT): {$(VPATH)}internal/error.h
+io.$(OBJEXT): {$(VPATH)}internal/eval.h
+io.$(OBJEXT): {$(VPATH)}internal/event.h
+io.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+io.$(OBJEXT): {$(VPATH)}internal/gc.h
+io.$(OBJEXT): {$(VPATH)}internal/glob.h
+io.$(OBJEXT): {$(VPATH)}internal/globals.h
+io.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+io.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+io.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+io.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+io.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+io.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+io.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+io.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+io.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+io.$(OBJEXT): {$(VPATH)}internal/iterator.h
+io.$(OBJEXT): {$(VPATH)}internal/memory.h
+io.$(OBJEXT): {$(VPATH)}internal/method.h
+io.$(OBJEXT): {$(VPATH)}internal/module.h
+io.$(OBJEXT): {$(VPATH)}internal/newobj.h
+io.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+io.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+io.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+io.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+io.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+io.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+io.$(OBJEXT): {$(VPATH)}internal/symbol.h
+io.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+io.$(OBJEXT): {$(VPATH)}internal/value.h
+io.$(OBJEXT): {$(VPATH)}internal/value_type.h
+io.$(OBJEXT): {$(VPATH)}internal/variable.h
+io.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+io.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
io.$(OBJEXT): {$(VPATH)}io.c
io.$(OBJEXT): {$(VPATH)}io.h
+io.$(OBJEXT): {$(VPATH)}io.rbinc
+io.$(OBJEXT): {$(VPATH)}method.h
io.$(OBJEXT): {$(VPATH)}missing.h
+io.$(OBJEXT): {$(VPATH)}node.h
io.$(OBJEXT): {$(VPATH)}onigmo.h
io.$(OBJEXT): {$(VPATH)}oniguruma.h
+io.$(OBJEXT): {$(VPATH)}ractor.h
+io.$(OBJEXT): {$(VPATH)}ruby_assert.h
io.$(OBJEXT): {$(VPATH)}ruby_atomic.h
io.$(OBJEXT): {$(VPATH)}st.h
io.$(OBJEXT): {$(VPATH)}subst.h
io.$(OBJEXT): {$(VPATH)}thread.h
+io.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+io.$(OBJEXT): {$(VPATH)}thread_native.h
io.$(OBJEXT): {$(VPATH)}util.h
+io.$(OBJEXT): {$(VPATH)}vm_core.h
+io.$(OBJEXT): {$(VPATH)}vm_opts.h
iseq.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
iseq.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
iseq.$(OBJEXT): $(CCAN_DIR)/list/list.h
iseq.$(OBJEXT): $(CCAN_DIR)/str/str.h
+iseq.$(OBJEXT): $(hdrdir)/ruby.h
iseq.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-iseq.$(OBJEXT): $(top_srcdir)/include/ruby.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/array.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/bits.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/class.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/compile.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/error.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/file.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/serial.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/string.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/thread.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/variable.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/vm.h
+iseq.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+iseq.$(OBJEXT): {$(VPATH)}assert.h
+iseq.$(OBJEXT): {$(VPATH)}atomic.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+iseq.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+iseq.$(OBJEXT): {$(VPATH)}builtin.h
iseq.$(OBJEXT): {$(VPATH)}config.h
+iseq.$(OBJEXT): {$(VPATH)}constant.h
+iseq.$(OBJEXT): {$(VPATH)}debug_counter.h
iseq.$(OBJEXT): {$(VPATH)}defines.h
iseq.$(OBJEXT): {$(VPATH)}encoding.h
iseq.$(OBJEXT): {$(VPATH)}eval_intern.h
iseq.$(OBJEXT): {$(VPATH)}gc.h
iseq.$(OBJEXT): {$(VPATH)}id.h
iseq.$(OBJEXT): {$(VPATH)}id_table.h
+iseq.$(OBJEXT): {$(VPATH)}insns.def
iseq.$(OBJEXT): {$(VPATH)}insns.inc
iseq.$(OBJEXT): {$(VPATH)}insns_info.inc
iseq.$(OBJEXT): {$(VPATH)}intern.h
iseq.$(OBJEXT): {$(VPATH)}internal.h
-iseq.$(OBJEXT): {$(VPATH)}io.h
+iseq.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+iseq.$(OBJEXT): {$(VPATH)}internal/assume.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+iseq.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+iseq.$(OBJEXT): {$(VPATH)}internal/cast.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+iseq.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+iseq.$(OBJEXT): {$(VPATH)}internal/config.h
+iseq.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+iseq.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+iseq.$(OBJEXT): {$(VPATH)}internal/ctype.h
+iseq.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+iseq.$(OBJEXT): {$(VPATH)}internal/dosish.h
+iseq.$(OBJEXT): {$(VPATH)}internal/error.h
+iseq.$(OBJEXT): {$(VPATH)}internal/eval.h
+iseq.$(OBJEXT): {$(VPATH)}internal/event.h
+iseq.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+iseq.$(OBJEXT): {$(VPATH)}internal/gc.h
+iseq.$(OBJEXT): {$(VPATH)}internal/glob.h
+iseq.$(OBJEXT): {$(VPATH)}internal/globals.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+iseq.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+iseq.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+iseq.$(OBJEXT): {$(VPATH)}internal/iterator.h
+iseq.$(OBJEXT): {$(VPATH)}internal/memory.h
+iseq.$(OBJEXT): {$(VPATH)}internal/method.h
+iseq.$(OBJEXT): {$(VPATH)}internal/module.h
+iseq.$(OBJEXT): {$(VPATH)}internal/newobj.h
+iseq.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+iseq.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+iseq.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+iseq.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+iseq.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+iseq.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+iseq.$(OBJEXT): {$(VPATH)}internal/symbol.h
+iseq.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+iseq.$(OBJEXT): {$(VPATH)}internal/value.h
+iseq.$(OBJEXT): {$(VPATH)}internal/value_type.h
+iseq.$(OBJEXT): {$(VPATH)}internal/variable.h
+iseq.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+iseq.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
iseq.$(OBJEXT): {$(VPATH)}iseq.c
iseq.$(OBJEXT): {$(VPATH)}iseq.h
iseq.$(OBJEXT): {$(VPATH)}method.h
iseq.$(OBJEXT): {$(VPATH)}missing.h
+iseq.$(OBJEXT): {$(VPATH)}mjit.h
iseq.$(OBJEXT): {$(VPATH)}node.h
iseq.$(OBJEXT): {$(VPATH)}node_name.inc
iseq.$(OBJEXT): {$(VPATH)}onigmo.h
@@ -1931,24 +6972,193 @@ iseq.$(OBJEXT): {$(VPATH)}subst.h
iseq.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
iseq.$(OBJEXT): {$(VPATH)}thread_native.h
iseq.$(OBJEXT): {$(VPATH)}util.h
+iseq.$(OBJEXT): {$(VPATH)}vm_callinfo.h
iseq.$(OBJEXT): {$(VPATH)}vm_core.h
-iseq.$(OBJEXT): {$(VPATH)}vm_debug.h
iseq.$(OBJEXT): {$(VPATH)}vm_opts.h
load.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
load.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
load.$(OBJEXT): $(CCAN_DIR)/list/list.h
load.$(OBJEXT): $(CCAN_DIR)/str/str.h
+load.$(OBJEXT): $(hdrdir)/ruby.h
load.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-load.$(OBJEXT): $(top_srcdir)/include/ruby.h
+load.$(OBJEXT): $(top_srcdir)/internal/array.h
+load.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+load.$(OBJEXT): $(top_srcdir)/internal/dir.h
+load.$(OBJEXT): $(top_srcdir)/internal/error.h
+load.$(OBJEXT): $(top_srcdir)/internal/file.h
+load.$(OBJEXT): $(top_srcdir)/internal/gc.h
+load.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+load.$(OBJEXT): $(top_srcdir)/internal/load.h
+load.$(OBJEXT): $(top_srcdir)/internal/parse.h
+load.$(OBJEXT): $(top_srcdir)/internal/serial.h
+load.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+load.$(OBJEXT): $(top_srcdir)/internal/string.h
+load.$(OBJEXT): $(top_srcdir)/internal/thread.h
+load.$(OBJEXT): $(top_srcdir)/internal/variable.h
+load.$(OBJEXT): $(top_srcdir)/internal/vm.h
+load.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+load.$(OBJEXT): {$(VPATH)}assert.h
+load.$(OBJEXT): {$(VPATH)}atomic.h
+load.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+load.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+load.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+load.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+load.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+load.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+load.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+load.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+load.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
load.$(OBJEXT): {$(VPATH)}config.h
+load.$(OBJEXT): {$(VPATH)}constant.h
load.$(OBJEXT): {$(VPATH)}defines.h
load.$(OBJEXT): {$(VPATH)}dln.h
load.$(OBJEXT): {$(VPATH)}encoding.h
load.$(OBJEXT): {$(VPATH)}eval_intern.h
load.$(OBJEXT): {$(VPATH)}id.h
+load.$(OBJEXT): {$(VPATH)}id_table.h
load.$(OBJEXT): {$(VPATH)}intern.h
load.$(OBJEXT): {$(VPATH)}internal.h
-load.$(OBJEXT): {$(VPATH)}io.h
+load.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+load.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+load.$(OBJEXT): {$(VPATH)}internal/assume.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+load.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+load.$(OBJEXT): {$(VPATH)}internal/cast.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+load.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+load.$(OBJEXT): {$(VPATH)}internal/config.h
+load.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+load.$(OBJEXT): {$(VPATH)}internal/core.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+load.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+load.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+load.$(OBJEXT): {$(VPATH)}internal/ctype.h
+load.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+load.$(OBJEXT): {$(VPATH)}internal/dosish.h
+load.$(OBJEXT): {$(VPATH)}internal/error.h
+load.$(OBJEXT): {$(VPATH)}internal/eval.h
+load.$(OBJEXT): {$(VPATH)}internal/event.h
+load.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+load.$(OBJEXT): {$(VPATH)}internal/gc.h
+load.$(OBJEXT): {$(VPATH)}internal/glob.h
+load.$(OBJEXT): {$(VPATH)}internal/globals.h
+load.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+load.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+load.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+load.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+load.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+load.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+load.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+load.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+load.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+load.$(OBJEXT): {$(VPATH)}internal/iterator.h
+load.$(OBJEXT): {$(VPATH)}internal/memory.h
+load.$(OBJEXT): {$(VPATH)}internal/method.h
+load.$(OBJEXT): {$(VPATH)}internal/module.h
+load.$(OBJEXT): {$(VPATH)}internal/newobj.h
+load.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+load.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+load.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+load.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+load.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+load.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+load.$(OBJEXT): {$(VPATH)}internal/symbol.h
+load.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+load.$(OBJEXT): {$(VPATH)}internal/value.h
+load.$(OBJEXT): {$(VPATH)}internal/value_type.h
+load.$(OBJEXT): {$(VPATH)}internal/variable.h
+load.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+load.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+load.$(OBJEXT): {$(VPATH)}iseq.h
load.$(OBJEXT): {$(VPATH)}load.c
load.$(OBJEXT): {$(VPATH)}method.h
load.$(OBJEXT): {$(VPATH)}missing.h
@@ -1965,48 +7175,522 @@ load.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
load.$(OBJEXT): {$(VPATH)}thread_native.h
load.$(OBJEXT): {$(VPATH)}util.h
load.$(OBJEXT): {$(VPATH)}vm_core.h
-load.$(OBJEXT): {$(VPATH)}vm_debug.h
load.$(OBJEXT): {$(VPATH)}vm_opts.h
loadpath.$(OBJEXT): $(hdrdir)/ruby/ruby.h
loadpath.$(OBJEXT): $(hdrdir)/ruby/version.h
loadpath.$(OBJEXT): $(top_srcdir)/version.h
+loadpath.$(OBJEXT): {$(VPATH)}assert.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+loadpath.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
loadpath.$(OBJEXT): {$(VPATH)}config.h
loadpath.$(OBJEXT): {$(VPATH)}defines.h
loadpath.$(OBJEXT): {$(VPATH)}intern.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/assume.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/cast.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/config.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/ctype.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/dosish.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/error.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/eval.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/event.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/gc.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/glob.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/globals.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/iterator.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/memory.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/method.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/module.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/newobj.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/symbol.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/value.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/value_type.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/variable.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
loadpath.$(OBJEXT): {$(VPATH)}loadpath.c
loadpath.$(OBJEXT): {$(VPATH)}missing.h
loadpath.$(OBJEXT): {$(VPATH)}st.h
loadpath.$(OBJEXT): {$(VPATH)}subst.h
loadpath.$(OBJEXT): {$(VPATH)}verconf.h
+localeinit.$(OBJEXT): $(hdrdir)/ruby.h
localeinit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-localeinit.$(OBJEXT): $(top_srcdir)/include/ruby.h
+localeinit.$(OBJEXT): {$(VPATH)}assert.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+localeinit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
localeinit.$(OBJEXT): {$(VPATH)}config.h
localeinit.$(OBJEXT): {$(VPATH)}defines.h
localeinit.$(OBJEXT): {$(VPATH)}encindex.h
localeinit.$(OBJEXT): {$(VPATH)}encoding.h
localeinit.$(OBJEXT): {$(VPATH)}intern.h
localeinit.$(OBJEXT): {$(VPATH)}internal.h
-localeinit.$(OBJEXT): {$(VPATH)}io.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/assume.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/cast.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/config.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/ctype.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/dosish.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/error.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/eval.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/event.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/gc.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/glob.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/globals.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/iterator.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/memory.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/method.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/module.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/newobj.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/symbol.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/value.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/value_type.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/variable.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
localeinit.$(OBJEXT): {$(VPATH)}localeinit.c
localeinit.$(OBJEXT): {$(VPATH)}missing.h
localeinit.$(OBJEXT): {$(VPATH)}onigmo.h
localeinit.$(OBJEXT): {$(VPATH)}oniguruma.h
localeinit.$(OBJEXT): {$(VPATH)}st.h
localeinit.$(OBJEXT): {$(VPATH)}subst.h
+main.$(OBJEXT): $(hdrdir)/ruby.h
main.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-main.$(OBJEXT): $(top_srcdir)/include/ruby.h
+main.$(OBJEXT): {$(VPATH)}assert.h
main.$(OBJEXT): {$(VPATH)}backward.h
+main.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+main.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+main.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+main.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+main.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+main.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+main.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+main.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+main.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
main.$(OBJEXT): {$(VPATH)}config.h
main.$(OBJEXT): {$(VPATH)}defines.h
main.$(OBJEXT): {$(VPATH)}intern.h
+main.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+main.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+main.$(OBJEXT): {$(VPATH)}internal/assume.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+main.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+main.$(OBJEXT): {$(VPATH)}internal/cast.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+main.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+main.$(OBJEXT): {$(VPATH)}internal/config.h
+main.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+main.$(OBJEXT): {$(VPATH)}internal/core.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+main.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+main.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+main.$(OBJEXT): {$(VPATH)}internal/ctype.h
+main.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+main.$(OBJEXT): {$(VPATH)}internal/dosish.h
+main.$(OBJEXT): {$(VPATH)}internal/error.h
+main.$(OBJEXT): {$(VPATH)}internal/eval.h
+main.$(OBJEXT): {$(VPATH)}internal/event.h
+main.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+main.$(OBJEXT): {$(VPATH)}internal/gc.h
+main.$(OBJEXT): {$(VPATH)}internal/glob.h
+main.$(OBJEXT): {$(VPATH)}internal/globals.h
+main.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+main.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+main.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+main.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+main.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+main.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+main.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+main.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+main.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+main.$(OBJEXT): {$(VPATH)}internal/iterator.h
+main.$(OBJEXT): {$(VPATH)}internal/memory.h
+main.$(OBJEXT): {$(VPATH)}internal/method.h
+main.$(OBJEXT): {$(VPATH)}internal/module.h
+main.$(OBJEXT): {$(VPATH)}internal/newobj.h
+main.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+main.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+main.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+main.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+main.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+main.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+main.$(OBJEXT): {$(VPATH)}internal/symbol.h
+main.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+main.$(OBJEXT): {$(VPATH)}internal/value.h
+main.$(OBJEXT): {$(VPATH)}internal/value_type.h
+main.$(OBJEXT): {$(VPATH)}internal/variable.h
+main.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+main.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
main.$(OBJEXT): {$(VPATH)}main.c
main.$(OBJEXT): {$(VPATH)}missing.h
main.$(OBJEXT): {$(VPATH)}node.h
main.$(OBJEXT): {$(VPATH)}st.h
main.$(OBJEXT): {$(VPATH)}subst.h
main.$(OBJEXT): {$(VPATH)}vm_debug.h
+marshal.$(OBJEXT): $(hdrdir)/ruby.h
marshal.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-marshal.$(OBJEXT): $(top_srcdir)/include/ruby.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/array.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/class.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/encoding.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/error.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/gc.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/hash.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/object.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/serial.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/string.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/struct.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/util.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/vm.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+marshal.$(OBJEXT): {$(VPATH)}assert.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+marshal.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
marshal.$(OBJEXT): {$(VPATH)}config.h
marshal.$(OBJEXT): {$(VPATH)}defines.h
marshal.$(OBJEXT): {$(VPATH)}encindex.h
@@ -2014,6 +7698,146 @@ marshal.$(OBJEXT): {$(VPATH)}encoding.h
marshal.$(OBJEXT): {$(VPATH)}id_table.h
marshal.$(OBJEXT): {$(VPATH)}intern.h
marshal.$(OBJEXT): {$(VPATH)}internal.h
+marshal.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+marshal.$(OBJEXT): {$(VPATH)}internal/assume.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+marshal.$(OBJEXT): {$(VPATH)}internal/cast.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+marshal.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+marshal.$(OBJEXT): {$(VPATH)}internal/config.h
+marshal.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+marshal.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+marshal.$(OBJEXT): {$(VPATH)}internal/ctype.h
+marshal.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+marshal.$(OBJEXT): {$(VPATH)}internal/dosish.h
+marshal.$(OBJEXT): {$(VPATH)}internal/error.h
+marshal.$(OBJEXT): {$(VPATH)}internal/eval.h
+marshal.$(OBJEXT): {$(VPATH)}internal/event.h
+marshal.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+marshal.$(OBJEXT): {$(VPATH)}internal/gc.h
+marshal.$(OBJEXT): {$(VPATH)}internal/glob.h
+marshal.$(OBJEXT): {$(VPATH)}internal/globals.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+marshal.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+marshal.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+marshal.$(OBJEXT): {$(VPATH)}internal/iterator.h
+marshal.$(OBJEXT): {$(VPATH)}internal/memory.h
+marshal.$(OBJEXT): {$(VPATH)}internal/method.h
+marshal.$(OBJEXT): {$(VPATH)}internal/module.h
+marshal.$(OBJEXT): {$(VPATH)}internal/newobj.h
+marshal.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+marshal.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+marshal.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+marshal.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+marshal.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+marshal.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+marshal.$(OBJEXT): {$(VPATH)}internal/symbol.h
+marshal.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+marshal.$(OBJEXT): {$(VPATH)}internal/value.h
+marshal.$(OBJEXT): {$(VPATH)}internal/value_type.h
+marshal.$(OBJEXT): {$(VPATH)}internal/variable.h
+marshal.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+marshal.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
marshal.$(OBJEXT): {$(VPATH)}io.h
marshal.$(OBJEXT): {$(VPATH)}marshal.c
marshal.$(OBJEXT): {$(VPATH)}missing.h
@@ -2022,52 +7846,1179 @@ marshal.$(OBJEXT): {$(VPATH)}oniguruma.h
marshal.$(OBJEXT): {$(VPATH)}st.h
marshal.$(OBJEXT): {$(VPATH)}subst.h
marshal.$(OBJEXT): {$(VPATH)}util.h
+math.$(OBJEXT): $(hdrdir)/ruby.h
math.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-math.$(OBJEXT): $(top_srcdir)/include/ruby.h
+math.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+math.$(OBJEXT): $(top_srcdir)/internal/class.h
+math.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+math.$(OBJEXT): $(top_srcdir)/internal/complex.h
+math.$(OBJEXT): $(top_srcdir)/internal/gc.h
+math.$(OBJEXT): $(top_srcdir)/internal/math.h
+math.$(OBJEXT): $(top_srcdir)/internal/object.h
+math.$(OBJEXT): $(top_srcdir)/internal/serial.h
+math.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+math.$(OBJEXT): $(top_srcdir)/internal/vm.h
+math.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+math.$(OBJEXT): {$(VPATH)}assert.h
+math.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+math.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+math.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+math.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+math.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+math.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+math.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+math.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+math.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
math.$(OBJEXT): {$(VPATH)}config.h
math.$(OBJEXT): {$(VPATH)}defines.h
-math.$(OBJEXT): {$(VPATH)}encoding.h
+math.$(OBJEXT): {$(VPATH)}id_table.h
math.$(OBJEXT): {$(VPATH)}intern.h
math.$(OBJEXT): {$(VPATH)}internal.h
-math.$(OBJEXT): {$(VPATH)}io.h
+math.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+math.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+math.$(OBJEXT): {$(VPATH)}internal/assume.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+math.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+math.$(OBJEXT): {$(VPATH)}internal/cast.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+math.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+math.$(OBJEXT): {$(VPATH)}internal/config.h
+math.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+math.$(OBJEXT): {$(VPATH)}internal/core.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+math.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+math.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+math.$(OBJEXT): {$(VPATH)}internal/ctype.h
+math.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+math.$(OBJEXT): {$(VPATH)}internal/dosish.h
+math.$(OBJEXT): {$(VPATH)}internal/error.h
+math.$(OBJEXT): {$(VPATH)}internal/eval.h
+math.$(OBJEXT): {$(VPATH)}internal/event.h
+math.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+math.$(OBJEXT): {$(VPATH)}internal/gc.h
+math.$(OBJEXT): {$(VPATH)}internal/glob.h
+math.$(OBJEXT): {$(VPATH)}internal/globals.h
+math.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+math.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+math.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+math.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+math.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+math.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+math.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+math.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+math.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+math.$(OBJEXT): {$(VPATH)}internal/iterator.h
+math.$(OBJEXT): {$(VPATH)}internal/memory.h
+math.$(OBJEXT): {$(VPATH)}internal/method.h
+math.$(OBJEXT): {$(VPATH)}internal/module.h
+math.$(OBJEXT): {$(VPATH)}internal/newobj.h
+math.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+math.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+math.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+math.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+math.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+math.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+math.$(OBJEXT): {$(VPATH)}internal/symbol.h
+math.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+math.$(OBJEXT): {$(VPATH)}internal/value.h
+math.$(OBJEXT): {$(VPATH)}internal/value_type.h
+math.$(OBJEXT): {$(VPATH)}internal/variable.h
+math.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+math.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
math.$(OBJEXT): {$(VPATH)}math.c
math.$(OBJEXT): {$(VPATH)}missing.h
-math.$(OBJEXT): {$(VPATH)}onigmo.h
-math.$(OBJEXT): {$(VPATH)}oniguruma.h
math.$(OBJEXT): {$(VPATH)}st.h
math.$(OBJEXT): {$(VPATH)}subst.h
+memory_view.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h
+memory_view.$(OBJEXT): $(top_srcdir)/internal/util.h
+memory_view.$(OBJEXT): $(top_srcdir)/internal/variable.h
+memory_view.$(OBJEXT): {$(VPATH)}assert.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+memory_view.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+memory_view.$(OBJEXT): {$(VPATH)}config.h
+memory_view.$(OBJEXT): {$(VPATH)}constant.h
+memory_view.$(OBJEXT): {$(VPATH)}debug_counter.h
+memory_view.$(OBJEXT): {$(VPATH)}defines.h
+memory_view.$(OBJEXT): {$(VPATH)}id_table.h
+memory_view.$(OBJEXT): {$(VPATH)}intern.h
+memory_view.$(OBJEXT): {$(VPATH)}internal.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/assume.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/cast.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/config.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/ctype.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/dosish.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/error.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/eval.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/event.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/gc.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/glob.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/globals.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/iterator.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/memory.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/method.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/module.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/newobj.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/symbol.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/value.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/value_type.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/variable.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+memory_view.$(OBJEXT): {$(VPATH)}memory_view.c
+memory_view.$(OBJEXT): {$(VPATH)}memory_view.h
+memory_view.$(OBJEXT): {$(VPATH)}missing.h
+memory_view.$(OBJEXT): {$(VPATH)}node.h
+memory_view.$(OBJEXT): {$(VPATH)}st.h
+memory_view.$(OBJEXT): {$(VPATH)}subst.h
+memory_view.$(OBJEXT): {$(VPATH)}vm_debug.h
+memory_view.$(OBJEXT): {$(VPATH)}vm_sync.h
+miniinit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+miniinit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+miniinit.$(OBJEXT): $(CCAN_DIR)/list/list.h
+miniinit.$(OBJEXT): $(CCAN_DIR)/str/str.h
+miniinit.$(OBJEXT): $(hdrdir)/ruby.h
miniinit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/array.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/serial.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/vm.h
+miniinit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+miniinit.$(OBJEXT): {$(VPATH)}array.rb
+miniinit.$(OBJEXT): {$(VPATH)}assert.h
+miniinit.$(OBJEXT): {$(VPATH)}ast.rb
+miniinit.$(OBJEXT): {$(VPATH)}atomic.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+miniinit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+miniinit.$(OBJEXT): {$(VPATH)}builtin.h
miniinit.$(OBJEXT): {$(VPATH)}config.h
miniinit.$(OBJEXT): {$(VPATH)}defines.h
+miniinit.$(OBJEXT): {$(VPATH)}dir.rb
miniinit.$(OBJEXT): {$(VPATH)}encoding.h
+miniinit.$(OBJEXT): {$(VPATH)}gc.rb
+miniinit.$(OBJEXT): {$(VPATH)}gem_prelude.rb
+miniinit.$(OBJEXT): {$(VPATH)}id.h
+miniinit.$(OBJEXT): {$(VPATH)}integer.rb
miniinit.$(OBJEXT): {$(VPATH)}intern.h
+miniinit.$(OBJEXT): {$(VPATH)}internal.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/assume.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/cast.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/config.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/ctype.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/dosish.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/error.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/eval.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/event.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/gc.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/glob.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/globals.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/iterator.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/memory.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/method.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/module.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/newobj.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/symbol.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/value.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/value_type.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/variable.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+miniinit.$(OBJEXT): {$(VPATH)}io.rb
+miniinit.$(OBJEXT): {$(VPATH)}iseq.h
+miniinit.$(OBJEXT): {$(VPATH)}kernel.rb
+miniinit.$(OBJEXT): {$(VPATH)}method.h
+miniinit.$(OBJEXT): {$(VPATH)}mini_builtin.c
miniinit.$(OBJEXT): {$(VPATH)}miniinit.c
+miniinit.$(OBJEXT): {$(VPATH)}miniprelude.c
miniinit.$(OBJEXT): {$(VPATH)}missing.h
+miniinit.$(OBJEXT): {$(VPATH)}node.h
miniinit.$(OBJEXT): {$(VPATH)}onigmo.h
miniinit.$(OBJEXT): {$(VPATH)}oniguruma.h
+miniinit.$(OBJEXT): {$(VPATH)}pack.rb
+miniinit.$(OBJEXT): {$(VPATH)}prelude.rb
+miniinit.$(OBJEXT): {$(VPATH)}ractor.rb
+miniinit.$(OBJEXT): {$(VPATH)}ruby_assert.h
+miniinit.$(OBJEXT): {$(VPATH)}ruby_atomic.h
miniinit.$(OBJEXT): {$(VPATH)}st.h
miniinit.$(OBJEXT): {$(VPATH)}subst.h
+miniinit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+miniinit.$(OBJEXT): {$(VPATH)}thread_native.h
+miniinit.$(OBJEXT): {$(VPATH)}trace_point.rb
+miniinit.$(OBJEXT): {$(VPATH)}vm_core.h
+miniinit.$(OBJEXT): {$(VPATH)}vm_opts.h
+miniinit.$(OBJEXT): {$(VPATH)}warning.rb
+miniprelude.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+miniprelude.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+miniprelude.$(OBJEXT): $(CCAN_DIR)/list/list.h
+miniprelude.$(OBJEXT): $(CCAN_DIR)/str/str.h
+miniprelude.$(OBJEXT): $(hdrdir)/ruby.h
+miniprelude.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+miniprelude.$(OBJEXT): {$(VPATH)}assert.h
+miniprelude.$(OBJEXT): {$(VPATH)}ast.rb
+miniprelude.$(OBJEXT): {$(VPATH)}atomic.h
+miniprelude.$(OBJEXT): {$(VPATH)}config.h
+miniprelude.$(OBJEXT): {$(VPATH)}defines.h
+miniprelude.$(OBJEXT): {$(VPATH)}gc.rb
+miniprelude.$(OBJEXT): {$(VPATH)}id.h
+miniprelude.$(OBJEXT): {$(VPATH)}intern.h
+miniprelude.$(OBJEXT): {$(VPATH)}internal.h
+miniprelude.$(OBJEXT): {$(VPATH)}io.rb
miniprelude.$(OBJEXT): {$(VPATH)}iseq.h
+miniprelude.$(OBJEXT): {$(VPATH)}method.h
miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c
+miniprelude.$(OBJEXT): {$(VPATH)}missing.h
+miniprelude.$(OBJEXT): {$(VPATH)}node.h
+miniprelude.$(OBJEXT): {$(VPATH)}pack.rb
+miniprelude.$(OBJEXT): {$(VPATH)}prelude.rb
+miniprelude.$(OBJEXT): {$(VPATH)}ruby_assert.h
+miniprelude.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+miniprelude.$(OBJEXT): {$(VPATH)}st.h
+miniprelude.$(OBJEXT): {$(VPATH)}subst.h
+miniprelude.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+miniprelude.$(OBJEXT): {$(VPATH)}thread_native.h
+miniprelude.$(OBJEXT): {$(VPATH)}trace_point.rb
+miniprelude.$(OBJEXT): {$(VPATH)}vm_core.h
+miniprelude.$(OBJEXT): {$(VPATH)}vm_opts.h
+mjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+mjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+mjit.$(OBJEXT): $(CCAN_DIR)/list/list.h
+mjit.$(OBJEXT): $(CCAN_DIR)/str/str.h
+mjit.$(OBJEXT): $(hdrdir)/ruby.h
+mjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+mjit.$(OBJEXT): $(hdrdir)/ruby/version.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/array.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/class.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/compile.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/cont.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/file.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/vm.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+mjit.$(OBJEXT): {$(VPATH)}assert.h
+mjit.$(OBJEXT): {$(VPATH)}atomic.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+mjit.$(OBJEXT): {$(VPATH)}builtin.h
+mjit.$(OBJEXT): {$(VPATH)}config.h
+mjit.$(OBJEXT): {$(VPATH)}constant.h
+mjit.$(OBJEXT): {$(VPATH)}debug.h
+mjit.$(OBJEXT): {$(VPATH)}debug_counter.h
+mjit.$(OBJEXT): {$(VPATH)}defines.h
+mjit.$(OBJEXT): {$(VPATH)}dln.h
+mjit.$(OBJEXT): {$(VPATH)}encoding.h
+mjit.$(OBJEXT): {$(VPATH)}gc.h
+mjit.$(OBJEXT): {$(VPATH)}id.h
+mjit.$(OBJEXT): {$(VPATH)}id_table.h
+mjit.$(OBJEXT): {$(VPATH)}insns.def
+mjit.$(OBJEXT): {$(VPATH)}insns.inc
+mjit.$(OBJEXT): {$(VPATH)}insns_info.inc
+mjit.$(OBJEXT): {$(VPATH)}intern.h
+mjit.$(OBJEXT): {$(VPATH)}internal.h
+mjit.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/assume.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+mjit.$(OBJEXT): {$(VPATH)}internal/cast.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+mjit.$(OBJEXT): {$(VPATH)}internal/config.h
+mjit.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+mjit.$(OBJEXT): {$(VPATH)}internal/ctype.h
+mjit.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+mjit.$(OBJEXT): {$(VPATH)}internal/dosish.h
+mjit.$(OBJEXT): {$(VPATH)}internal/error.h
+mjit.$(OBJEXT): {$(VPATH)}internal/eval.h
+mjit.$(OBJEXT): {$(VPATH)}internal/event.h
+mjit.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+mjit.$(OBJEXT): {$(VPATH)}internal/gc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/glob.h
+mjit.$(OBJEXT): {$(VPATH)}internal/globals.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+mjit.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+mjit.$(OBJEXT): {$(VPATH)}internal/iterator.h
+mjit.$(OBJEXT): {$(VPATH)}internal/memory.h
+mjit.$(OBJEXT): {$(VPATH)}internal/method.h
+mjit.$(OBJEXT): {$(VPATH)}internal/module.h
+mjit.$(OBJEXT): {$(VPATH)}internal/newobj.h
+mjit.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+mjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+mjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+mjit.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+mjit.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+mjit.$(OBJEXT): {$(VPATH)}internal/symbol.h
+mjit.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+mjit.$(OBJEXT): {$(VPATH)}internal/value.h
+mjit.$(OBJEXT): {$(VPATH)}internal/value_type.h
+mjit.$(OBJEXT): {$(VPATH)}internal/variable.h
+mjit.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+mjit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+mjit.$(OBJEXT): {$(VPATH)}iseq.h
+mjit.$(OBJEXT): {$(VPATH)}method.h
+mjit.$(OBJEXT): {$(VPATH)}missing.h
+mjit.$(OBJEXT): {$(VPATH)}mjit.c
+mjit.$(OBJEXT): {$(VPATH)}mjit.h
+mjit.$(OBJEXT): {$(VPATH)}mjit_config.h
+mjit.$(OBJEXT): {$(VPATH)}mjit_worker.c
+mjit.$(OBJEXT): {$(VPATH)}node.h
+mjit.$(OBJEXT): {$(VPATH)}onigmo.h
+mjit.$(OBJEXT): {$(VPATH)}oniguruma.h
+mjit.$(OBJEXT): {$(VPATH)}ruby_assert.h
+mjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+mjit.$(OBJEXT): {$(VPATH)}st.h
+mjit.$(OBJEXT): {$(VPATH)}subst.h
+mjit.$(OBJEXT): {$(VPATH)}thread.h
+mjit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+mjit.$(OBJEXT): {$(VPATH)}thread_native.h
+mjit.$(OBJEXT): {$(VPATH)}util.h
+mjit.$(OBJEXT): {$(VPATH)}vm_callinfo.h
+mjit.$(OBJEXT): {$(VPATH)}vm_core.h
+mjit.$(OBJEXT): {$(VPATH)}vm_opts.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}config.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}internal/config.h
+mjit_build_dir.$(OBJEXT): {$(VPATH)}ruby-runner.c
+mjit_build_dir.$(OBJEXT): {$(VPATH)}ruby-runner.h
+mjit_compile.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+mjit_compile.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+mjit_compile.$(OBJEXT): $(CCAN_DIR)/list/list.h
+mjit_compile.$(OBJEXT): $(CCAN_DIR)/str/str.h
+mjit_compile.$(OBJEXT): $(hdrdir)/ruby.h
+mjit_compile.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/array.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/class.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/compile.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/gc.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/hash.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/object.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/serial.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/variable.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/vm.h
+mjit_compile.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+mjit_compile.$(OBJEXT): {$(VPATH)}assert.h
+mjit_compile.$(OBJEXT): {$(VPATH)}atomic.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+mjit_compile.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+mjit_compile.$(OBJEXT): {$(VPATH)}builtin.h
+mjit_compile.$(OBJEXT): {$(VPATH)}config.h
+mjit_compile.$(OBJEXT): {$(VPATH)}constant.h
+mjit_compile.$(OBJEXT): {$(VPATH)}debug_counter.h
+mjit_compile.$(OBJEXT): {$(VPATH)}defines.h
+mjit_compile.$(OBJEXT): {$(VPATH)}id.h
+mjit_compile.$(OBJEXT): {$(VPATH)}id_table.h
+mjit_compile.$(OBJEXT): {$(VPATH)}insns.def
+mjit_compile.$(OBJEXT): {$(VPATH)}insns.inc
+mjit_compile.$(OBJEXT): {$(VPATH)}insns_info.inc
+mjit_compile.$(OBJEXT): {$(VPATH)}intern.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/assume.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/cast.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/config.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/ctype.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/dosish.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/error.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/eval.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/event.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/gc.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/glob.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/globals.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/iterator.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/memory.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/method.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/module.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/newobj.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/symbol.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/value.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/value_type.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/variable.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+mjit_compile.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+mjit_compile.$(OBJEXT): {$(VPATH)}iseq.h
+mjit_compile.$(OBJEXT): {$(VPATH)}method.h
+mjit_compile.$(OBJEXT): {$(VPATH)}missing.h
+mjit_compile.$(OBJEXT): {$(VPATH)}mjit.h
+mjit_compile.$(OBJEXT): {$(VPATH)}mjit_compile.c
+mjit_compile.$(OBJEXT): {$(VPATH)}mjit_compile.inc
+mjit_compile.$(OBJEXT): {$(VPATH)}node.h
+mjit_compile.$(OBJEXT): {$(VPATH)}ruby_assert.h
+mjit_compile.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+mjit_compile.$(OBJEXT): {$(VPATH)}st.h
+mjit_compile.$(OBJEXT): {$(VPATH)}subst.h
+mjit_compile.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+mjit_compile.$(OBJEXT): {$(VPATH)}thread_native.h
+mjit_compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h
+mjit_compile.$(OBJEXT): {$(VPATH)}vm_core.h
+mjit_compile.$(OBJEXT): {$(VPATH)}vm_exec.h
+mjit_compile.$(OBJEXT): {$(VPATH)}vm_insnhelper.h
+mjit_compile.$(OBJEXT): {$(VPATH)}vm_opts.h
node.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
node.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
node.$(OBJEXT): $(CCAN_DIR)/list/list.h
node.$(OBJEXT): $(CCAN_DIR)/str/str.h
+node.$(OBJEXT): $(hdrdir)/ruby.h
node.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-node.$(OBJEXT): $(top_srcdir)/include/ruby.h
+node.$(OBJEXT): $(top_srcdir)/internal/array.h
+node.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+node.$(OBJEXT): $(top_srcdir)/internal/gc.h
+node.$(OBJEXT): $(top_srcdir)/internal/hash.h
+node.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+node.$(OBJEXT): $(top_srcdir)/internal/serial.h
+node.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+node.$(OBJEXT): $(top_srcdir)/internal/variable.h
+node.$(OBJEXT): $(top_srcdir)/internal/vm.h
+node.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+node.$(OBJEXT): {$(VPATH)}assert.h
+node.$(OBJEXT): {$(VPATH)}atomic.h
+node.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+node.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+node.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+node.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+node.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+node.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+node.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+node.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+node.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
node.$(OBJEXT): {$(VPATH)}config.h
+node.$(OBJEXT): {$(VPATH)}constant.h
node.$(OBJEXT): {$(VPATH)}defines.h
-node.$(OBJEXT): {$(VPATH)}encoding.h
node.$(OBJEXT): {$(VPATH)}id.h
+node.$(OBJEXT): {$(VPATH)}id_table.h
node.$(OBJEXT): {$(VPATH)}intern.h
node.$(OBJEXT): {$(VPATH)}internal.h
-node.$(OBJEXT): {$(VPATH)}io.h
+node.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+node.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+node.$(OBJEXT): {$(VPATH)}internal/assume.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+node.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+node.$(OBJEXT): {$(VPATH)}internal/cast.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+node.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+node.$(OBJEXT): {$(VPATH)}internal/config.h
+node.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+node.$(OBJEXT): {$(VPATH)}internal/core.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+node.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+node.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+node.$(OBJEXT): {$(VPATH)}internal/ctype.h
+node.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+node.$(OBJEXT): {$(VPATH)}internal/dosish.h
+node.$(OBJEXT): {$(VPATH)}internal/error.h
+node.$(OBJEXT): {$(VPATH)}internal/eval.h
+node.$(OBJEXT): {$(VPATH)}internal/event.h
+node.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+node.$(OBJEXT): {$(VPATH)}internal/gc.h
+node.$(OBJEXT): {$(VPATH)}internal/glob.h
+node.$(OBJEXT): {$(VPATH)}internal/globals.h
+node.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+node.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+node.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+node.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+node.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+node.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+node.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+node.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+node.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+node.$(OBJEXT): {$(VPATH)}internal/iterator.h
+node.$(OBJEXT): {$(VPATH)}internal/memory.h
+node.$(OBJEXT): {$(VPATH)}internal/method.h
+node.$(OBJEXT): {$(VPATH)}internal/module.h
+node.$(OBJEXT): {$(VPATH)}internal/newobj.h
+node.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+node.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+node.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+node.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+node.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+node.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+node.$(OBJEXT): {$(VPATH)}internal/symbol.h
+node.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+node.$(OBJEXT): {$(VPATH)}internal/value.h
+node.$(OBJEXT): {$(VPATH)}internal/value_type.h
+node.$(OBJEXT): {$(VPATH)}internal/variable.h
+node.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+node.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
node.$(OBJEXT): {$(VPATH)}method.h
node.$(OBJEXT): {$(VPATH)}missing.h
node.$(OBJEXT): {$(VPATH)}node.c
node.$(OBJEXT): {$(VPATH)}node.h
-node.$(OBJEXT): {$(VPATH)}onigmo.h
-node.$(OBJEXT): {$(VPATH)}oniguruma.h
node.$(OBJEXT): {$(VPATH)}ruby_assert.h
node.$(OBJEXT): {$(VPATH)}ruby_atomic.h
node.$(OBJEXT): {$(VPATH)}st.h
@@ -2075,34 +9026,380 @@ node.$(OBJEXT): {$(VPATH)}subst.h
node.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
node.$(OBJEXT): {$(VPATH)}thread_native.h
node.$(OBJEXT): {$(VPATH)}vm_core.h
-node.$(OBJEXT): {$(VPATH)}vm_debug.h
node.$(OBJEXT): {$(VPATH)}vm_opts.h
+numeric.$(OBJEXT): $(hdrdir)/ruby.h
numeric.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-numeric.$(OBJEXT): $(top_srcdir)/include/ruby.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/array.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/bits.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/class.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/complex.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/enumerator.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/gc.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/hash.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/object.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/rational.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/serial.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/util.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/variable.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/vm.h
+numeric.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+numeric.$(OBJEXT): {$(VPATH)}assert.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+numeric.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+numeric.$(OBJEXT): {$(VPATH)}builtin.h
numeric.$(OBJEXT): {$(VPATH)}config.h
+numeric.$(OBJEXT): {$(VPATH)}constant.h
numeric.$(OBJEXT): {$(VPATH)}defines.h
numeric.$(OBJEXT): {$(VPATH)}encoding.h
numeric.$(OBJEXT): {$(VPATH)}id.h
+numeric.$(OBJEXT): {$(VPATH)}id_table.h
+numeric.$(OBJEXT): {$(VPATH)}integer.rb
+numeric.$(OBJEXT): {$(VPATH)}integer.rbinc
numeric.$(OBJEXT): {$(VPATH)}intern.h
numeric.$(OBJEXT): {$(VPATH)}internal.h
-numeric.$(OBJEXT): {$(VPATH)}io.h
+numeric.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+numeric.$(OBJEXT): {$(VPATH)}internal/assume.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+numeric.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+numeric.$(OBJEXT): {$(VPATH)}internal/cast.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+numeric.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+numeric.$(OBJEXT): {$(VPATH)}internal/config.h
+numeric.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+numeric.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+numeric.$(OBJEXT): {$(VPATH)}internal/ctype.h
+numeric.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+numeric.$(OBJEXT): {$(VPATH)}internal/dosish.h
+numeric.$(OBJEXT): {$(VPATH)}internal/error.h
+numeric.$(OBJEXT): {$(VPATH)}internal/eval.h
+numeric.$(OBJEXT): {$(VPATH)}internal/event.h
+numeric.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+numeric.$(OBJEXT): {$(VPATH)}internal/gc.h
+numeric.$(OBJEXT): {$(VPATH)}internal/glob.h
+numeric.$(OBJEXT): {$(VPATH)}internal/globals.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+numeric.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+numeric.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+numeric.$(OBJEXT): {$(VPATH)}internal/iterator.h
+numeric.$(OBJEXT): {$(VPATH)}internal/memory.h
+numeric.$(OBJEXT): {$(VPATH)}internal/method.h
+numeric.$(OBJEXT): {$(VPATH)}internal/module.h
+numeric.$(OBJEXT): {$(VPATH)}internal/newobj.h
+numeric.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+numeric.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+numeric.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+numeric.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+numeric.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+numeric.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+numeric.$(OBJEXT): {$(VPATH)}internal/symbol.h
+numeric.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+numeric.$(OBJEXT): {$(VPATH)}internal/value.h
+numeric.$(OBJEXT): {$(VPATH)}internal/value_type.h
+numeric.$(OBJEXT): {$(VPATH)}internal/variable.h
+numeric.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+numeric.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
numeric.$(OBJEXT): {$(VPATH)}missing.h
numeric.$(OBJEXT): {$(VPATH)}numeric.c
numeric.$(OBJEXT): {$(VPATH)}onigmo.h
numeric.$(OBJEXT): {$(VPATH)}oniguruma.h
+numeric.$(OBJEXT): {$(VPATH)}ruby_assert.h
numeric.$(OBJEXT): {$(VPATH)}st.h
numeric.$(OBJEXT): {$(VPATH)}subst.h
numeric.$(OBJEXT): {$(VPATH)}util.h
+object.$(OBJEXT): $(hdrdir)/ruby.h
object.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-object.$(OBJEXT): $(top_srcdir)/include/ruby.h
+object.$(OBJEXT): $(top_srcdir)/internal/array.h
+object.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+object.$(OBJEXT): $(top_srcdir)/internal/bits.h
+object.$(OBJEXT): $(top_srcdir)/internal/class.h
+object.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+object.$(OBJEXT): $(top_srcdir)/internal/error.h
+object.$(OBJEXT): $(top_srcdir)/internal/eval.h
+object.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+object.$(OBJEXT): $(top_srcdir)/internal/gc.h
+object.$(OBJEXT): $(top_srcdir)/internal/inits.h
+object.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+object.$(OBJEXT): $(top_srcdir)/internal/object.h
+object.$(OBJEXT): $(top_srcdir)/internal/serial.h
+object.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+object.$(OBJEXT): $(top_srcdir)/internal/string.h
+object.$(OBJEXT): $(top_srcdir)/internal/struct.h
+object.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+object.$(OBJEXT): $(top_srcdir)/internal/variable.h
+object.$(OBJEXT): $(top_srcdir)/internal/vm.h
+object.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+object.$(OBJEXT): {$(VPATH)}assert.h
+object.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+object.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+object.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+object.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+object.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+object.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+object.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+object.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+object.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+object.$(OBJEXT): {$(VPATH)}builtin.h
object.$(OBJEXT): {$(VPATH)}config.h
object.$(OBJEXT): {$(VPATH)}constant.h
object.$(OBJEXT): {$(VPATH)}defines.h
object.$(OBJEXT): {$(VPATH)}encoding.h
object.$(OBJEXT): {$(VPATH)}id.h
+object.$(OBJEXT): {$(VPATH)}id_table.h
object.$(OBJEXT): {$(VPATH)}intern.h
object.$(OBJEXT): {$(VPATH)}internal.h
-object.$(OBJEXT): {$(VPATH)}io.h
+object.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+object.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+object.$(OBJEXT): {$(VPATH)}internal/assume.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+object.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+object.$(OBJEXT): {$(VPATH)}internal/cast.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+object.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+object.$(OBJEXT): {$(VPATH)}internal/config.h
+object.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+object.$(OBJEXT): {$(VPATH)}internal/core.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+object.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+object.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+object.$(OBJEXT): {$(VPATH)}internal/ctype.h
+object.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+object.$(OBJEXT): {$(VPATH)}internal/dosish.h
+object.$(OBJEXT): {$(VPATH)}internal/error.h
+object.$(OBJEXT): {$(VPATH)}internal/eval.h
+object.$(OBJEXT): {$(VPATH)}internal/event.h
+object.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+object.$(OBJEXT): {$(VPATH)}internal/gc.h
+object.$(OBJEXT): {$(VPATH)}internal/glob.h
+object.$(OBJEXT): {$(VPATH)}internal/globals.h
+object.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+object.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+object.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+object.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+object.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+object.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+object.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+object.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+object.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+object.$(OBJEXT): {$(VPATH)}internal/iterator.h
+object.$(OBJEXT): {$(VPATH)}internal/memory.h
+object.$(OBJEXT): {$(VPATH)}internal/method.h
+object.$(OBJEXT): {$(VPATH)}internal/module.h
+object.$(OBJEXT): {$(VPATH)}internal/newobj.h
+object.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+object.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+object.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+object.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+object.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+object.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+object.$(OBJEXT): {$(VPATH)}internal/symbol.h
+object.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+object.$(OBJEXT): {$(VPATH)}internal/value.h
+object.$(OBJEXT): {$(VPATH)}internal/value_type.h
+object.$(OBJEXT): {$(VPATH)}internal/variable.h
+object.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+object.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+object.$(OBJEXT): {$(VPATH)}kernel.rb
+object.$(OBJEXT): {$(VPATH)}kernel.rbinc
object.$(OBJEXT): {$(VPATH)}missing.h
object.$(OBJEXT): {$(VPATH)}object.c
object.$(OBJEXT): {$(VPATH)}onigmo.h
@@ -2112,29 +9409,368 @@ object.$(OBJEXT): {$(VPATH)}probes.h
object.$(OBJEXT): {$(VPATH)}st.h
object.$(OBJEXT): {$(VPATH)}subst.h
object.$(OBJEXT): {$(VPATH)}util.h
+pack.$(OBJEXT): $(hdrdir)/ruby.h
pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-pack.$(OBJEXT): $(top_srcdir)/include/ruby.h
+pack.$(OBJEXT): $(top_srcdir)/internal/array.h
+pack.$(OBJEXT): $(top_srcdir)/internal/bits.h
+pack.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+pack.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+pack.$(OBJEXT): $(top_srcdir)/internal/string.h
+pack.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+pack.$(OBJEXT): $(top_srcdir)/internal/util.h
+pack.$(OBJEXT): $(top_srcdir)/internal/variable.h
+pack.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+pack.$(OBJEXT): {$(VPATH)}assert.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+pack.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+pack.$(OBJEXT): {$(VPATH)}builtin.h
pack.$(OBJEXT): {$(VPATH)}config.h
+pack.$(OBJEXT): {$(VPATH)}constant.h
pack.$(OBJEXT): {$(VPATH)}defines.h
pack.$(OBJEXT): {$(VPATH)}encoding.h
+pack.$(OBJEXT): {$(VPATH)}id_table.h
pack.$(OBJEXT): {$(VPATH)}intern.h
pack.$(OBJEXT): {$(VPATH)}internal.h
-pack.$(OBJEXT): {$(VPATH)}io.h
+pack.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+pack.$(OBJEXT): {$(VPATH)}internal/assume.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+pack.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+pack.$(OBJEXT): {$(VPATH)}internal/cast.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+pack.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+pack.$(OBJEXT): {$(VPATH)}internal/config.h
+pack.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+pack.$(OBJEXT): {$(VPATH)}internal/core.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+pack.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+pack.$(OBJEXT): {$(VPATH)}internal/ctype.h
+pack.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+pack.$(OBJEXT): {$(VPATH)}internal/dosish.h
+pack.$(OBJEXT): {$(VPATH)}internal/error.h
+pack.$(OBJEXT): {$(VPATH)}internal/eval.h
+pack.$(OBJEXT): {$(VPATH)}internal/event.h
+pack.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+pack.$(OBJEXT): {$(VPATH)}internal/gc.h
+pack.$(OBJEXT): {$(VPATH)}internal/glob.h
+pack.$(OBJEXT): {$(VPATH)}internal/globals.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+pack.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+pack.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+pack.$(OBJEXT): {$(VPATH)}internal/iterator.h
+pack.$(OBJEXT): {$(VPATH)}internal/memory.h
+pack.$(OBJEXT): {$(VPATH)}internal/method.h
+pack.$(OBJEXT): {$(VPATH)}internal/module.h
+pack.$(OBJEXT): {$(VPATH)}internal/newobj.h
+pack.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+pack.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+pack.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+pack.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+pack.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+pack.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+pack.$(OBJEXT): {$(VPATH)}internal/symbol.h
+pack.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+pack.$(OBJEXT): {$(VPATH)}internal/value.h
+pack.$(OBJEXT): {$(VPATH)}internal/value_type.h
+pack.$(OBJEXT): {$(VPATH)}internal/variable.h
+pack.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+pack.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
pack.$(OBJEXT): {$(VPATH)}missing.h
pack.$(OBJEXT): {$(VPATH)}onigmo.h
pack.$(OBJEXT): {$(VPATH)}oniguruma.h
pack.$(OBJEXT): {$(VPATH)}pack.c
+pack.$(OBJEXT): {$(VPATH)}pack.rbinc
pack.$(OBJEXT): {$(VPATH)}st.h
pack.$(OBJEXT): {$(VPATH)}subst.h
+parse.$(OBJEXT): $(hdrdir)/ruby.h
parse.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-parse.$(OBJEXT): $(top_srcdir)/include/ruby.h
+parse.$(OBJEXT): $(top_srcdir)/internal/array.h
+parse.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+parse.$(OBJEXT): $(top_srcdir)/internal/bits.h
+parse.$(OBJEXT): $(top_srcdir)/internal/compile.h
+parse.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+parse.$(OBJEXT): $(top_srcdir)/internal/complex.h
+parse.$(OBJEXT): $(top_srcdir)/internal/error.h
+parse.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+parse.$(OBJEXT): $(top_srcdir)/internal/gc.h
+parse.$(OBJEXT): $(top_srcdir)/internal/hash.h
+parse.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+parse.$(OBJEXT): $(top_srcdir)/internal/io.h
+parse.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+parse.$(OBJEXT): $(top_srcdir)/internal/parse.h
+parse.$(OBJEXT): $(top_srcdir)/internal/rational.h
+parse.$(OBJEXT): $(top_srcdir)/internal/re.h
+parse.$(OBJEXT): $(top_srcdir)/internal/serial.h
+parse.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+parse.$(OBJEXT): $(top_srcdir)/internal/string.h
+parse.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+parse.$(OBJEXT): $(top_srcdir)/internal/thread.h
+parse.$(OBJEXT): $(top_srcdir)/internal/util.h
+parse.$(OBJEXT): $(top_srcdir)/internal/variable.h
+parse.$(OBJEXT): $(top_srcdir)/internal/vm.h
+parse.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+parse.$(OBJEXT): {$(VPATH)}assert.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+parse.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
parse.$(OBJEXT): {$(VPATH)}config.h
+parse.$(OBJEXT): {$(VPATH)}constant.h
parse.$(OBJEXT): {$(VPATH)}defines.h
parse.$(OBJEXT): {$(VPATH)}defs/keywords
parse.$(OBJEXT): {$(VPATH)}encoding.h
parse.$(OBJEXT): {$(VPATH)}id.h
+parse.$(OBJEXT): {$(VPATH)}id_table.h
parse.$(OBJEXT): {$(VPATH)}intern.h
parse.$(OBJEXT): {$(VPATH)}internal.h
+parse.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+parse.$(OBJEXT): {$(VPATH)}internal/assume.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+parse.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+parse.$(OBJEXT): {$(VPATH)}internal/cast.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+parse.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+parse.$(OBJEXT): {$(VPATH)}internal/config.h
+parse.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+parse.$(OBJEXT): {$(VPATH)}internal/core.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+parse.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+parse.$(OBJEXT): {$(VPATH)}internal/ctype.h
+parse.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+parse.$(OBJEXT): {$(VPATH)}internal/dosish.h
+parse.$(OBJEXT): {$(VPATH)}internal/error.h
+parse.$(OBJEXT): {$(VPATH)}internal/eval.h
+parse.$(OBJEXT): {$(VPATH)}internal/event.h
+parse.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+parse.$(OBJEXT): {$(VPATH)}internal/gc.h
+parse.$(OBJEXT): {$(VPATH)}internal/glob.h
+parse.$(OBJEXT): {$(VPATH)}internal/globals.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+parse.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+parse.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+parse.$(OBJEXT): {$(VPATH)}internal/iterator.h
+parse.$(OBJEXT): {$(VPATH)}internal/memory.h
+parse.$(OBJEXT): {$(VPATH)}internal/method.h
+parse.$(OBJEXT): {$(VPATH)}internal/module.h
+parse.$(OBJEXT): {$(VPATH)}internal/newobj.h
+parse.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+parse.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+parse.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+parse.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+parse.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+parse.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+parse.$(OBJEXT): {$(VPATH)}internal/symbol.h
+parse.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+parse.$(OBJEXT): {$(VPATH)}internal/value.h
+parse.$(OBJEXT): {$(VPATH)}internal/value_type.h
+parse.$(OBJEXT): {$(VPATH)}internal/variable.h
+parse.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+parse.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
parse.$(OBJEXT): {$(VPATH)}io.h
parse.$(OBJEXT): {$(VPATH)}lex.c
parse.$(OBJEXT): {$(VPATH)}missing.h
@@ -2146,8 +9782,10 @@ parse.$(OBJEXT): {$(VPATH)}parse.h
parse.$(OBJEXT): {$(VPATH)}parse.y
parse.$(OBJEXT): {$(VPATH)}probes.dmyh
parse.$(OBJEXT): {$(VPATH)}probes.h
+parse.$(OBJEXT): {$(VPATH)}ractor.h
parse.$(OBJEXT): {$(VPATH)}regenc.h
parse.$(OBJEXT): {$(VPATH)}regex.h
+parse.$(OBJEXT): {$(VPATH)}ruby_assert.h
parse.$(OBJEXT): {$(VPATH)}st.h
parse.$(OBJEXT): {$(VPATH)}subst.h
parse.$(OBJEXT): {$(VPATH)}symbol.h
@@ -2156,21 +9794,20 @@ prelude.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
prelude.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
prelude.$(OBJEXT): $(CCAN_DIR)/list/list.h
prelude.$(OBJEXT): $(CCAN_DIR)/str/str.h
+prelude.$(OBJEXT): $(hdrdir)/ruby.h
prelude.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-prelude.$(OBJEXT): $(top_srcdir)/include/ruby.h
+prelude.$(OBJEXT): {$(VPATH)}assert.h
+prelude.$(OBJEXT): {$(VPATH)}atomic.h
prelude.$(OBJEXT): {$(VPATH)}config.h
prelude.$(OBJEXT): {$(VPATH)}defines.h
-prelude.$(OBJEXT): {$(VPATH)}encoding.h
+prelude.$(OBJEXT): {$(VPATH)}gem_prelude.rb
prelude.$(OBJEXT): {$(VPATH)}id.h
prelude.$(OBJEXT): {$(VPATH)}intern.h
prelude.$(OBJEXT): {$(VPATH)}internal.h
-prelude.$(OBJEXT): {$(VPATH)}io.h
prelude.$(OBJEXT): {$(VPATH)}iseq.h
prelude.$(OBJEXT): {$(VPATH)}method.h
prelude.$(OBJEXT): {$(VPATH)}missing.h
prelude.$(OBJEXT): {$(VPATH)}node.h
-prelude.$(OBJEXT): {$(VPATH)}onigmo.h
-prelude.$(OBJEXT): {$(VPATH)}oniguruma.h
prelude.$(OBJEXT): {$(VPATH)}prelude.c
prelude.$(OBJEXT): {$(VPATH)}ruby_assert.h
prelude.$(OBJEXT): {$(VPATH)}ruby_atomic.h
@@ -2179,23 +9816,188 @@ prelude.$(OBJEXT): {$(VPATH)}subst.h
prelude.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
prelude.$(OBJEXT): {$(VPATH)}thread_native.h
prelude.$(OBJEXT): {$(VPATH)}vm_core.h
-prelude.$(OBJEXT): {$(VPATH)}vm_debug.h
prelude.$(OBJEXT): {$(VPATH)}vm_opts.h
proc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
proc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
proc.$(OBJEXT): $(CCAN_DIR)/list/list.h
proc.$(OBJEXT): $(CCAN_DIR)/str/str.h
+proc.$(OBJEXT): $(hdrdir)/ruby.h
proc.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-proc.$(OBJEXT): $(top_srcdir)/include/ruby.h
+proc.$(OBJEXT): $(top_srcdir)/internal/array.h
+proc.$(OBJEXT): $(top_srcdir)/internal/class.h
+proc.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+proc.$(OBJEXT): $(top_srcdir)/internal/error.h
+proc.$(OBJEXT): $(top_srcdir)/internal/eval.h
+proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
+proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+proc.$(OBJEXT): $(top_srcdir)/internal/object.h
+proc.$(OBJEXT): $(top_srcdir)/internal/proc.h
+proc.$(OBJEXT): $(top_srcdir)/internal/serial.h
+proc.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+proc.$(OBJEXT): $(top_srcdir)/internal/string.h
+proc.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+proc.$(OBJEXT): $(top_srcdir)/internal/vm.h
+proc.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+proc.$(OBJEXT): {$(VPATH)}assert.h
+proc.$(OBJEXT): {$(VPATH)}atomic.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+proc.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
proc.$(OBJEXT): {$(VPATH)}config.h
proc.$(OBJEXT): {$(VPATH)}defines.h
proc.$(OBJEXT): {$(VPATH)}encoding.h
proc.$(OBJEXT): {$(VPATH)}eval_intern.h
proc.$(OBJEXT): {$(VPATH)}gc.h
proc.$(OBJEXT): {$(VPATH)}id.h
+proc.$(OBJEXT): {$(VPATH)}id_table.h
proc.$(OBJEXT): {$(VPATH)}intern.h
proc.$(OBJEXT): {$(VPATH)}internal.h
-proc.$(OBJEXT): {$(VPATH)}io.h
+proc.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+proc.$(OBJEXT): {$(VPATH)}internal/assume.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+proc.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+proc.$(OBJEXT): {$(VPATH)}internal/cast.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+proc.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+proc.$(OBJEXT): {$(VPATH)}internal/config.h
+proc.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+proc.$(OBJEXT): {$(VPATH)}internal/core.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+proc.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+proc.$(OBJEXT): {$(VPATH)}internal/ctype.h
+proc.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+proc.$(OBJEXT): {$(VPATH)}internal/dosish.h
+proc.$(OBJEXT): {$(VPATH)}internal/error.h
+proc.$(OBJEXT): {$(VPATH)}internal/eval.h
+proc.$(OBJEXT): {$(VPATH)}internal/event.h
+proc.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+proc.$(OBJEXT): {$(VPATH)}internal/gc.h
+proc.$(OBJEXT): {$(VPATH)}internal/glob.h
+proc.$(OBJEXT): {$(VPATH)}internal/globals.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+proc.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+proc.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+proc.$(OBJEXT): {$(VPATH)}internal/iterator.h
+proc.$(OBJEXT): {$(VPATH)}internal/memory.h
+proc.$(OBJEXT): {$(VPATH)}internal/method.h
+proc.$(OBJEXT): {$(VPATH)}internal/module.h
+proc.$(OBJEXT): {$(VPATH)}internal/newobj.h
+proc.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+proc.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+proc.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+proc.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+proc.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+proc.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+proc.$(OBJEXT): {$(VPATH)}internal/symbol.h
+proc.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+proc.$(OBJEXT): {$(VPATH)}internal/value.h
+proc.$(OBJEXT): {$(VPATH)}internal/value_type.h
+proc.$(OBJEXT): {$(VPATH)}internal/variable.h
+proc.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+proc.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
proc.$(OBJEXT): {$(VPATH)}iseq.h
proc.$(OBJEXT): {$(VPATH)}method.h
proc.$(OBJEXT): {$(VPATH)}missing.h
@@ -2210,28 +10012,205 @@ proc.$(OBJEXT): {$(VPATH)}subst.h
proc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
proc.$(OBJEXT): {$(VPATH)}thread_native.h
proc.$(OBJEXT): {$(VPATH)}vm_core.h
-proc.$(OBJEXT): {$(VPATH)}vm_debug.h
proc.$(OBJEXT): {$(VPATH)}vm_opts.h
process.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
process.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
process.$(OBJEXT): $(CCAN_DIR)/list/list.h
process.$(OBJEXT): $(CCAN_DIR)/str/str.h
+process.$(OBJEXT): $(hdrdir)/ruby.h
process.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-process.$(OBJEXT): $(top_srcdir)/include/ruby.h
+process.$(OBJEXT): $(top_srcdir)/internal/array.h
+process.$(OBJEXT): $(top_srcdir)/internal/bits.h
+process.$(OBJEXT): $(top_srcdir)/internal/class.h
+process.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+process.$(OBJEXT): $(top_srcdir)/internal/dir.h
+process.$(OBJEXT): $(top_srcdir)/internal/error.h
+process.$(OBJEXT): $(top_srcdir)/internal/eval.h
+process.$(OBJEXT): $(top_srcdir)/internal/gc.h
+process.$(OBJEXT): $(top_srcdir)/internal/hash.h
+process.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+process.$(OBJEXT): $(top_srcdir)/internal/object.h
+process.$(OBJEXT): $(top_srcdir)/internal/process.h
+process.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
+process.$(OBJEXT): $(top_srcdir)/internal/serial.h
+process.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+process.$(OBJEXT): $(top_srcdir)/internal/string.h
+process.$(OBJEXT): $(top_srcdir)/internal/thread.h
+process.$(OBJEXT): $(top_srcdir)/internal/variable.h
+process.$(OBJEXT): $(top_srcdir)/internal/vm.h
+process.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+process.$(OBJEXT): {$(VPATH)}$(COROUTINE_H)
+process.$(OBJEXT): {$(VPATH)}assert.h
+process.$(OBJEXT): {$(VPATH)}atomic.h
+process.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+process.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+process.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+process.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+process.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+process.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+process.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+process.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+process.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
process.$(OBJEXT): {$(VPATH)}config.h
+process.$(OBJEXT): {$(VPATH)}constant.h
+process.$(OBJEXT): {$(VPATH)}debug_counter.h
process.$(OBJEXT): {$(VPATH)}defines.h
process.$(OBJEXT): {$(VPATH)}dln.h
process.$(OBJEXT): {$(VPATH)}encoding.h
+process.$(OBJEXT): {$(VPATH)}hrtime.h
process.$(OBJEXT): {$(VPATH)}id.h
+process.$(OBJEXT): {$(VPATH)}id_table.h
process.$(OBJEXT): {$(VPATH)}intern.h
process.$(OBJEXT): {$(VPATH)}internal.h
+process.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+process.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+process.$(OBJEXT): {$(VPATH)}internal/assume.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+process.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+process.$(OBJEXT): {$(VPATH)}internal/cast.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+process.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+process.$(OBJEXT): {$(VPATH)}internal/config.h
+process.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+process.$(OBJEXT): {$(VPATH)}internal/core.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+process.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+process.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+process.$(OBJEXT): {$(VPATH)}internal/ctype.h
+process.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+process.$(OBJEXT): {$(VPATH)}internal/dosish.h
+process.$(OBJEXT): {$(VPATH)}internal/error.h
+process.$(OBJEXT): {$(VPATH)}internal/eval.h
+process.$(OBJEXT): {$(VPATH)}internal/event.h
+process.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+process.$(OBJEXT): {$(VPATH)}internal/gc.h
+process.$(OBJEXT): {$(VPATH)}internal/glob.h
+process.$(OBJEXT): {$(VPATH)}internal/globals.h
+process.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+process.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+process.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+process.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+process.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+process.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+process.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+process.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+process.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+process.$(OBJEXT): {$(VPATH)}internal/iterator.h
+process.$(OBJEXT): {$(VPATH)}internal/memory.h
+process.$(OBJEXT): {$(VPATH)}internal/method.h
+process.$(OBJEXT): {$(VPATH)}internal/module.h
+process.$(OBJEXT): {$(VPATH)}internal/newobj.h
+process.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+process.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+process.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+process.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+process.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+process.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+process.$(OBJEXT): {$(VPATH)}internal/symbol.h
+process.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+process.$(OBJEXT): {$(VPATH)}internal/value.h
+process.$(OBJEXT): {$(VPATH)}internal/value_type.h
+process.$(OBJEXT): {$(VPATH)}internal/variable.h
+process.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+process.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
process.$(OBJEXT): {$(VPATH)}io.h
process.$(OBJEXT): {$(VPATH)}method.h
process.$(OBJEXT): {$(VPATH)}missing.h
+process.$(OBJEXT): {$(VPATH)}mjit.h
process.$(OBJEXT): {$(VPATH)}node.h
process.$(OBJEXT): {$(VPATH)}onigmo.h
process.$(OBJEXT): {$(VPATH)}oniguruma.h
process.$(OBJEXT): {$(VPATH)}process.c
+process.$(OBJEXT): {$(VPATH)}ractor.h
process.$(OBJEXT): {$(VPATH)}ruby_assert.h
process.$(OBJEXT): {$(VPATH)}ruby_atomic.h
process.$(OBJEXT): {$(VPATH)}st.h
@@ -2241,49 +10220,762 @@ process.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
process.$(OBJEXT): {$(VPATH)}thread_native.h
process.$(OBJEXT): {$(VPATH)}util.h
process.$(OBJEXT): {$(VPATH)}vm_core.h
-process.$(OBJEXT): {$(VPATH)}vm_debug.h
process.$(OBJEXT): {$(VPATH)}vm_opts.h
+ractor.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+ractor.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+ractor.$(OBJEXT): $(CCAN_DIR)/list/list.h
+ractor.$(OBJEXT): $(CCAN_DIR)/str/str.h
+ractor.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/array.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/bits.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/complex.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/error.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/gc.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/hash.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/rational.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/serial.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/string.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/struct.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/thread.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/vm.h
+ractor.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+ractor.$(OBJEXT): {$(VPATH)}assert.h
+ractor.$(OBJEXT): {$(VPATH)}atomic.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+ractor.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+ractor.$(OBJEXT): {$(VPATH)}builtin.h
+ractor.$(OBJEXT): {$(VPATH)}config.h
+ractor.$(OBJEXT): {$(VPATH)}constant.h
+ractor.$(OBJEXT): {$(VPATH)}debug.h
+ractor.$(OBJEXT): {$(VPATH)}debug_counter.h
+ractor.$(OBJEXT): {$(VPATH)}defines.h
+ractor.$(OBJEXT): {$(VPATH)}encoding.h
+ractor.$(OBJEXT): {$(VPATH)}gc.h
+ractor.$(OBJEXT): {$(VPATH)}id.h
+ractor.$(OBJEXT): {$(VPATH)}id_table.h
+ractor.$(OBJEXT): {$(VPATH)}intern.h
+ractor.$(OBJEXT): {$(VPATH)}internal.h
+ractor.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+ractor.$(OBJEXT): {$(VPATH)}internal/assume.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+ractor.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+ractor.$(OBJEXT): {$(VPATH)}internal/cast.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+ractor.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+ractor.$(OBJEXT): {$(VPATH)}internal/config.h
+ractor.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+ractor.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+ractor.$(OBJEXT): {$(VPATH)}internal/ctype.h
+ractor.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+ractor.$(OBJEXT): {$(VPATH)}internal/dosish.h
+ractor.$(OBJEXT): {$(VPATH)}internal/error.h
+ractor.$(OBJEXT): {$(VPATH)}internal/eval.h
+ractor.$(OBJEXT): {$(VPATH)}internal/event.h
+ractor.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+ractor.$(OBJEXT): {$(VPATH)}internal/gc.h
+ractor.$(OBJEXT): {$(VPATH)}internal/glob.h
+ractor.$(OBJEXT): {$(VPATH)}internal/globals.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+ractor.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+ractor.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+ractor.$(OBJEXT): {$(VPATH)}internal/iterator.h
+ractor.$(OBJEXT): {$(VPATH)}internal/memory.h
+ractor.$(OBJEXT): {$(VPATH)}internal/method.h
+ractor.$(OBJEXT): {$(VPATH)}internal/module.h
+ractor.$(OBJEXT): {$(VPATH)}internal/newobj.h
+ractor.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+ractor.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+ractor.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+ractor.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+ractor.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+ractor.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+ractor.$(OBJEXT): {$(VPATH)}internal/symbol.h
+ractor.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+ractor.$(OBJEXT): {$(VPATH)}internal/value.h
+ractor.$(OBJEXT): {$(VPATH)}internal/value_type.h
+ractor.$(OBJEXT): {$(VPATH)}internal/variable.h
+ractor.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+ractor.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+ractor.$(OBJEXT): {$(VPATH)}method.h
+ractor.$(OBJEXT): {$(VPATH)}missing.h
+ractor.$(OBJEXT): {$(VPATH)}node.h
+ractor.$(OBJEXT): {$(VPATH)}onigmo.h
+ractor.$(OBJEXT): {$(VPATH)}oniguruma.h
+ractor.$(OBJEXT): {$(VPATH)}ractor.c
+ractor.$(OBJEXT): {$(VPATH)}ractor.h
+ractor.$(OBJEXT): {$(VPATH)}ractor.rb
+ractor.$(OBJEXT): {$(VPATH)}ractor.rbinc
+ractor.$(OBJEXT): {$(VPATH)}ractor_core.h
+ractor.$(OBJEXT): {$(VPATH)}ruby_assert.h
+ractor.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+ractor.$(OBJEXT): {$(VPATH)}st.h
+ractor.$(OBJEXT): {$(VPATH)}subst.h
+ractor.$(OBJEXT): {$(VPATH)}thread.h
+ractor.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+ractor.$(OBJEXT): {$(VPATH)}thread_native.h
+ractor.$(OBJEXT): {$(VPATH)}transient_heap.h
+ractor.$(OBJEXT): {$(VPATH)}variable.h
+ractor.$(OBJEXT): {$(VPATH)}vm_core.h
+ractor.$(OBJEXT): {$(VPATH)}vm_debug.h
+ractor.$(OBJEXT): {$(VPATH)}vm_opts.h
+ractor.$(OBJEXT): {$(VPATH)}vm_sync.h
+random.$(OBJEXT): $(hdrdir)/ruby.h
random.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-random.$(OBJEXT): $(top_srcdir)/include/ruby.h
+random.$(OBJEXT): $(top_srcdir)/internal/array.h
+random.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+random.$(OBJEXT): $(top_srcdir)/internal/bits.h
+random.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+random.$(OBJEXT): $(top_srcdir)/internal/error.h
+random.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+random.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+random.$(OBJEXT): $(top_srcdir)/internal/random.h
+random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+random.$(OBJEXT): $(top_srcdir)/internal/serial.h
+random.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+random.$(OBJEXT): $(top_srcdir)/internal/string.h
+random.$(OBJEXT): $(top_srcdir)/internal/variable.h
+random.$(OBJEXT): $(top_srcdir)/internal/vm.h
+random.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+random.$(OBJEXT): {$(VPATH)}assert.h
+random.$(OBJEXT): {$(VPATH)}atomic.h
+random.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+random.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+random.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+random.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+random.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+random.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+random.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+random.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+random.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
random.$(OBJEXT): {$(VPATH)}config.h
+random.$(OBJEXT): {$(VPATH)}constant.h
random.$(OBJEXT): {$(VPATH)}defines.h
random.$(OBJEXT): {$(VPATH)}encoding.h
+random.$(OBJEXT): {$(VPATH)}id_table.h
random.$(OBJEXT): {$(VPATH)}intern.h
random.$(OBJEXT): {$(VPATH)}internal.h
-random.$(OBJEXT): {$(VPATH)}io.h
+random.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+random.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+random.$(OBJEXT): {$(VPATH)}internal/assume.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+random.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+random.$(OBJEXT): {$(VPATH)}internal/cast.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+random.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+random.$(OBJEXT): {$(VPATH)}internal/config.h
+random.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+random.$(OBJEXT): {$(VPATH)}internal/core.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+random.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+random.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+random.$(OBJEXT): {$(VPATH)}internal/ctype.h
+random.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+random.$(OBJEXT): {$(VPATH)}internal/dosish.h
+random.$(OBJEXT): {$(VPATH)}internal/error.h
+random.$(OBJEXT): {$(VPATH)}internal/eval.h
+random.$(OBJEXT): {$(VPATH)}internal/event.h
+random.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+random.$(OBJEXT): {$(VPATH)}internal/gc.h
+random.$(OBJEXT): {$(VPATH)}internal/glob.h
+random.$(OBJEXT): {$(VPATH)}internal/globals.h
+random.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+random.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+random.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+random.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+random.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+random.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+random.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+random.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+random.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+random.$(OBJEXT): {$(VPATH)}internal/iterator.h
+random.$(OBJEXT): {$(VPATH)}internal/memory.h
+random.$(OBJEXT): {$(VPATH)}internal/method.h
+random.$(OBJEXT): {$(VPATH)}internal/module.h
+random.$(OBJEXT): {$(VPATH)}internal/newobj.h
+random.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+random.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+random.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+random.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+random.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+random.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+random.$(OBJEXT): {$(VPATH)}internal/symbol.h
+random.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+random.$(OBJEXT): {$(VPATH)}internal/value.h
+random.$(OBJEXT): {$(VPATH)}internal/value_type.h
+random.$(OBJEXT): {$(VPATH)}internal/variable.h
+random.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+random.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
random.$(OBJEXT): {$(VPATH)}missing.h
+random.$(OBJEXT): {$(VPATH)}mt19937.c
random.$(OBJEXT): {$(VPATH)}onigmo.h
random.$(OBJEXT): {$(VPATH)}oniguruma.h
+random.$(OBJEXT): {$(VPATH)}ractor.h
random.$(OBJEXT): {$(VPATH)}random.c
+random.$(OBJEXT): {$(VPATH)}random.h
random.$(OBJEXT): {$(VPATH)}ruby_atomic.h
random.$(OBJEXT): {$(VPATH)}siphash.c
random.$(OBJEXT): {$(VPATH)}siphash.h
random.$(OBJEXT): {$(VPATH)}st.h
random.$(OBJEXT): {$(VPATH)}subst.h
+range.$(OBJEXT): $(hdrdir)/ruby.h
range.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-range.$(OBJEXT): $(top_srcdir)/include/ruby.h
+range.$(OBJEXT): $(top_srcdir)/internal/array.h
+range.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+range.$(OBJEXT): $(top_srcdir)/internal/bits.h
+range.$(OBJEXT): $(top_srcdir)/internal/compar.h
+range.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+range.$(OBJEXT): $(top_srcdir)/internal/enum.h
+range.$(OBJEXT): $(top_srcdir)/internal/enumerator.h
+range.$(OBJEXT): $(top_srcdir)/internal/error.h
+range.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+range.$(OBJEXT): $(top_srcdir)/internal/gc.h
+range.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+range.$(OBJEXT): $(top_srcdir)/internal/range.h
+range.$(OBJEXT): $(top_srcdir)/internal/serial.h
+range.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+range.$(OBJEXT): $(top_srcdir)/internal/string.h
+range.$(OBJEXT): $(top_srcdir)/internal/struct.h
+range.$(OBJEXT): $(top_srcdir)/internal/vm.h
+range.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+range.$(OBJEXT): {$(VPATH)}assert.h
+range.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+range.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+range.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+range.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+range.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+range.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+range.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+range.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+range.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
range.$(OBJEXT): {$(VPATH)}config.h
range.$(OBJEXT): {$(VPATH)}defines.h
range.$(OBJEXT): {$(VPATH)}encoding.h
range.$(OBJEXT): {$(VPATH)}id.h
range.$(OBJEXT): {$(VPATH)}intern.h
range.$(OBJEXT): {$(VPATH)}internal.h
-range.$(OBJEXT): {$(VPATH)}io.h
+range.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+range.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+range.$(OBJEXT): {$(VPATH)}internal/assume.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+range.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+range.$(OBJEXT): {$(VPATH)}internal/cast.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+range.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+range.$(OBJEXT): {$(VPATH)}internal/config.h
+range.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+range.$(OBJEXT): {$(VPATH)}internal/core.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+range.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+range.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+range.$(OBJEXT): {$(VPATH)}internal/ctype.h
+range.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+range.$(OBJEXT): {$(VPATH)}internal/dosish.h
+range.$(OBJEXT): {$(VPATH)}internal/error.h
+range.$(OBJEXT): {$(VPATH)}internal/eval.h
+range.$(OBJEXT): {$(VPATH)}internal/event.h
+range.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+range.$(OBJEXT): {$(VPATH)}internal/gc.h
+range.$(OBJEXT): {$(VPATH)}internal/glob.h
+range.$(OBJEXT): {$(VPATH)}internal/globals.h
+range.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+range.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+range.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+range.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+range.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+range.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+range.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+range.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+range.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+range.$(OBJEXT): {$(VPATH)}internal/iterator.h
+range.$(OBJEXT): {$(VPATH)}internal/memory.h
+range.$(OBJEXT): {$(VPATH)}internal/method.h
+range.$(OBJEXT): {$(VPATH)}internal/module.h
+range.$(OBJEXT): {$(VPATH)}internal/newobj.h
+range.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+range.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+range.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+range.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+range.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+range.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+range.$(OBJEXT): {$(VPATH)}internal/symbol.h
+range.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+range.$(OBJEXT): {$(VPATH)}internal/value.h
+range.$(OBJEXT): {$(VPATH)}internal/value_type.h
+range.$(OBJEXT): {$(VPATH)}internal/variable.h
+range.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+range.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
range.$(OBJEXT): {$(VPATH)}missing.h
range.$(OBJEXT): {$(VPATH)}onigmo.h
range.$(OBJEXT): {$(VPATH)}oniguruma.h
range.$(OBJEXT): {$(VPATH)}range.c
range.$(OBJEXT): {$(VPATH)}st.h
range.$(OBJEXT): {$(VPATH)}subst.h
+rational.$(OBJEXT): $(hdrdir)/ruby.h
rational.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-rational.$(OBJEXT): $(top_srcdir)/include/ruby.h
+rational.$(OBJEXT): $(top_srcdir)/internal/array.h
+rational.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+rational.$(OBJEXT): $(top_srcdir)/internal/bits.h
+rational.$(OBJEXT): $(top_srcdir)/internal/class.h
+rational.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+rational.$(OBJEXT): $(top_srcdir)/internal/complex.h
+rational.$(OBJEXT): $(top_srcdir)/internal/error.h
+rational.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+rational.$(OBJEXT): $(top_srcdir)/internal/gc.h
+rational.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+rational.$(OBJEXT): $(top_srcdir)/internal/object.h
+rational.$(OBJEXT): $(top_srcdir)/internal/rational.h
+rational.$(OBJEXT): $(top_srcdir)/internal/serial.h
+rational.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+rational.$(OBJEXT): $(top_srcdir)/internal/string.h
+rational.$(OBJEXT): $(top_srcdir)/internal/vm.h
+rational.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+rational.$(OBJEXT): {$(VPATH)}assert.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+rational.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
rational.$(OBJEXT): {$(VPATH)}config.h
rational.$(OBJEXT): {$(VPATH)}defines.h
rational.$(OBJEXT): {$(VPATH)}encoding.h
rational.$(OBJEXT): {$(VPATH)}id.h
+rational.$(OBJEXT): {$(VPATH)}id_table.h
rational.$(OBJEXT): {$(VPATH)}intern.h
rational.$(OBJEXT): {$(VPATH)}internal.h
-rational.$(OBJEXT): {$(VPATH)}io.h
+rational.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+rational.$(OBJEXT): {$(VPATH)}internal/assume.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+rational.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+rational.$(OBJEXT): {$(VPATH)}internal/cast.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+rational.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+rational.$(OBJEXT): {$(VPATH)}internal/config.h
+rational.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+rational.$(OBJEXT): {$(VPATH)}internal/core.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+rational.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+rational.$(OBJEXT): {$(VPATH)}internal/ctype.h
+rational.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+rational.$(OBJEXT): {$(VPATH)}internal/dosish.h
+rational.$(OBJEXT): {$(VPATH)}internal/error.h
+rational.$(OBJEXT): {$(VPATH)}internal/eval.h
+rational.$(OBJEXT): {$(VPATH)}internal/event.h
+rational.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+rational.$(OBJEXT): {$(VPATH)}internal/gc.h
+rational.$(OBJEXT): {$(VPATH)}internal/glob.h
+rational.$(OBJEXT): {$(VPATH)}internal/globals.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+rational.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+rational.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+rational.$(OBJEXT): {$(VPATH)}internal/iterator.h
+rational.$(OBJEXT): {$(VPATH)}internal/memory.h
+rational.$(OBJEXT): {$(VPATH)}internal/method.h
+rational.$(OBJEXT): {$(VPATH)}internal/module.h
+rational.$(OBJEXT): {$(VPATH)}internal/newobj.h
+rational.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+rational.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+rational.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+rational.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+rational.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+rational.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+rational.$(OBJEXT): {$(VPATH)}internal/symbol.h
+rational.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+rational.$(OBJEXT): {$(VPATH)}internal/value.h
+rational.$(OBJEXT): {$(VPATH)}internal/value_type.h
+rational.$(OBJEXT): {$(VPATH)}internal/variable.h
+rational.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+rational.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
rational.$(OBJEXT): {$(VPATH)}missing.h
rational.$(OBJEXT): {$(VPATH)}onigmo.h
rational.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -2291,15 +10983,178 @@ rational.$(OBJEXT): {$(VPATH)}rational.c
rational.$(OBJEXT): {$(VPATH)}ruby_assert.h
rational.$(OBJEXT): {$(VPATH)}st.h
rational.$(OBJEXT): {$(VPATH)}subst.h
+re.$(OBJEXT): $(hdrdir)/ruby.h
re.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-re.$(OBJEXT): $(top_srcdir)/include/ruby.h
+re.$(OBJEXT): $(top_srcdir)/internal/array.h
+re.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+re.$(OBJEXT): $(top_srcdir)/internal/error.h
+re.$(OBJEXT): $(top_srcdir)/internal/gc.h
+re.$(OBJEXT): $(top_srcdir)/internal/hash.h
+re.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+re.$(OBJEXT): $(top_srcdir)/internal/re.h
+re.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+re.$(OBJEXT): $(top_srcdir)/internal/string.h
+re.$(OBJEXT): $(top_srcdir)/internal/variable.h
+re.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+re.$(OBJEXT): {$(VPATH)}assert.h
+re.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+re.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+re.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+re.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+re.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+re.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+re.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+re.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+re.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
re.$(OBJEXT): {$(VPATH)}config.h
+re.$(OBJEXT): {$(VPATH)}constant.h
re.$(OBJEXT): {$(VPATH)}defines.h
re.$(OBJEXT): {$(VPATH)}encindex.h
re.$(OBJEXT): {$(VPATH)}encoding.h
+re.$(OBJEXT): {$(VPATH)}id_table.h
re.$(OBJEXT): {$(VPATH)}intern.h
re.$(OBJEXT): {$(VPATH)}internal.h
-re.$(OBJEXT): {$(VPATH)}io.h
+re.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+re.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+re.$(OBJEXT): {$(VPATH)}internal/assume.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+re.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+re.$(OBJEXT): {$(VPATH)}internal/cast.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+re.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+re.$(OBJEXT): {$(VPATH)}internal/config.h
+re.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+re.$(OBJEXT): {$(VPATH)}internal/core.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rmatch.h
+re.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+re.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+re.$(OBJEXT): {$(VPATH)}internal/ctype.h
+re.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+re.$(OBJEXT): {$(VPATH)}internal/dosish.h
+re.$(OBJEXT): {$(VPATH)}internal/error.h
+re.$(OBJEXT): {$(VPATH)}internal/eval.h
+re.$(OBJEXT): {$(VPATH)}internal/event.h
+re.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+re.$(OBJEXT): {$(VPATH)}internal/gc.h
+re.$(OBJEXT): {$(VPATH)}internal/glob.h
+re.$(OBJEXT): {$(VPATH)}internal/globals.h
+re.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+re.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+re.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+re.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+re.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+re.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+re.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+re.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+re.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+re.$(OBJEXT): {$(VPATH)}internal/iterator.h
+re.$(OBJEXT): {$(VPATH)}internal/memory.h
+re.$(OBJEXT): {$(VPATH)}internal/method.h
+re.$(OBJEXT): {$(VPATH)}internal/module.h
+re.$(OBJEXT): {$(VPATH)}internal/newobj.h
+re.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+re.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+re.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+re.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+re.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+re.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+re.$(OBJEXT): {$(VPATH)}internal/symbol.h
+re.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+re.$(OBJEXT): {$(VPATH)}internal/value.h
+re.$(OBJEXT): {$(VPATH)}internal/value_type.h
+re.$(OBJEXT): {$(VPATH)}internal/variable.h
+re.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+re.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
re.$(OBJEXT): {$(VPATH)}missing.h
re.$(OBJEXT): {$(VPATH)}onigmo.h
re.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -2312,12 +11167,161 @@ re.$(OBJEXT): {$(VPATH)}st.h
re.$(OBJEXT): {$(VPATH)}subst.h
re.$(OBJEXT): {$(VPATH)}util.h
regcomp.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regcomp.$(OBJEXT): {$(VPATH)}assert.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+regcomp.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
regcomp.$(OBJEXT): {$(VPATH)}config.h
regcomp.$(OBJEXT): {$(VPATH)}defines.h
regcomp.$(OBJEXT): {$(VPATH)}intern.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/assume.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/cast.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/config.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/ctype.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/dosish.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/error.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/eval.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/event.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/gc.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/glob.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/globals.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/iterator.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/memory.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/method.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/module.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/symbol.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/value.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/value_type.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/variable.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
regcomp.$(OBJEXT): {$(VPATH)}missing.h
regcomp.$(OBJEXT): {$(VPATH)}onigmo.h
-regcomp.$(OBJEXT): {$(VPATH)}oniguruma.h
regcomp.$(OBJEXT): {$(VPATH)}regcomp.c
regcomp.$(OBJEXT): {$(VPATH)}regenc.h
regcomp.$(OBJEXT): {$(VPATH)}regint.h
@@ -2325,48 +11329,644 @@ regcomp.$(OBJEXT): {$(VPATH)}regparse.h
regcomp.$(OBJEXT): {$(VPATH)}st.h
regcomp.$(OBJEXT): {$(VPATH)}subst.h
regenc.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regenc.$(OBJEXT): {$(VPATH)}assert.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+regenc.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
regenc.$(OBJEXT): {$(VPATH)}config.h
regenc.$(OBJEXT): {$(VPATH)}defines.h
regenc.$(OBJEXT): {$(VPATH)}intern.h
+regenc.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+regenc.$(OBJEXT): {$(VPATH)}internal/assume.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+regenc.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+regenc.$(OBJEXT): {$(VPATH)}internal/cast.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+regenc.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+regenc.$(OBJEXT): {$(VPATH)}internal/config.h
+regenc.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+regenc.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+regenc.$(OBJEXT): {$(VPATH)}internal/ctype.h
+regenc.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+regenc.$(OBJEXT): {$(VPATH)}internal/dosish.h
+regenc.$(OBJEXT): {$(VPATH)}internal/error.h
+regenc.$(OBJEXT): {$(VPATH)}internal/eval.h
+regenc.$(OBJEXT): {$(VPATH)}internal/event.h
+regenc.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+regenc.$(OBJEXT): {$(VPATH)}internal/gc.h
+regenc.$(OBJEXT): {$(VPATH)}internal/glob.h
+regenc.$(OBJEXT): {$(VPATH)}internal/globals.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+regenc.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+regenc.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+regenc.$(OBJEXT): {$(VPATH)}internal/iterator.h
+regenc.$(OBJEXT): {$(VPATH)}internal/memory.h
+regenc.$(OBJEXT): {$(VPATH)}internal/method.h
+regenc.$(OBJEXT): {$(VPATH)}internal/module.h
+regenc.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regenc.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+regenc.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+regenc.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+regenc.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+regenc.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+regenc.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+regenc.$(OBJEXT): {$(VPATH)}internal/symbol.h
+regenc.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+regenc.$(OBJEXT): {$(VPATH)}internal/value.h
+regenc.$(OBJEXT): {$(VPATH)}internal/value_type.h
+regenc.$(OBJEXT): {$(VPATH)}internal/variable.h
+regenc.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+regenc.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
regenc.$(OBJEXT): {$(VPATH)}missing.h
regenc.$(OBJEXT): {$(VPATH)}onigmo.h
-regenc.$(OBJEXT): {$(VPATH)}oniguruma.h
regenc.$(OBJEXT): {$(VPATH)}regenc.c
regenc.$(OBJEXT): {$(VPATH)}regenc.h
regenc.$(OBJEXT): {$(VPATH)}regint.h
regenc.$(OBJEXT): {$(VPATH)}st.h
regenc.$(OBJEXT): {$(VPATH)}subst.h
regerror.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regerror.$(OBJEXT): {$(VPATH)}assert.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+regerror.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
regerror.$(OBJEXT): {$(VPATH)}config.h
regerror.$(OBJEXT): {$(VPATH)}defines.h
regerror.$(OBJEXT): {$(VPATH)}intern.h
+regerror.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+regerror.$(OBJEXT): {$(VPATH)}internal/assume.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+regerror.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+regerror.$(OBJEXT): {$(VPATH)}internal/cast.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+regerror.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+regerror.$(OBJEXT): {$(VPATH)}internal/config.h
+regerror.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+regerror.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+regerror.$(OBJEXT): {$(VPATH)}internal/ctype.h
+regerror.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+regerror.$(OBJEXT): {$(VPATH)}internal/dosish.h
+regerror.$(OBJEXT): {$(VPATH)}internal/error.h
+regerror.$(OBJEXT): {$(VPATH)}internal/eval.h
+regerror.$(OBJEXT): {$(VPATH)}internal/event.h
+regerror.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+regerror.$(OBJEXT): {$(VPATH)}internal/gc.h
+regerror.$(OBJEXT): {$(VPATH)}internal/glob.h
+regerror.$(OBJEXT): {$(VPATH)}internal/globals.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+regerror.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+regerror.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+regerror.$(OBJEXT): {$(VPATH)}internal/iterator.h
+regerror.$(OBJEXT): {$(VPATH)}internal/memory.h
+regerror.$(OBJEXT): {$(VPATH)}internal/method.h
+regerror.$(OBJEXT): {$(VPATH)}internal/module.h
+regerror.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regerror.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+regerror.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+regerror.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+regerror.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+regerror.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+regerror.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+regerror.$(OBJEXT): {$(VPATH)}internal/symbol.h
+regerror.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+regerror.$(OBJEXT): {$(VPATH)}internal/value.h
+regerror.$(OBJEXT): {$(VPATH)}internal/value_type.h
+regerror.$(OBJEXT): {$(VPATH)}internal/variable.h
+regerror.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+regerror.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
regerror.$(OBJEXT): {$(VPATH)}missing.h
regerror.$(OBJEXT): {$(VPATH)}onigmo.h
-regerror.$(OBJEXT): {$(VPATH)}oniguruma.h
regerror.$(OBJEXT): {$(VPATH)}regenc.h
regerror.$(OBJEXT): {$(VPATH)}regerror.c
regerror.$(OBJEXT): {$(VPATH)}regint.h
regerror.$(OBJEXT): {$(VPATH)}st.h
regerror.$(OBJEXT): {$(VPATH)}subst.h
regexec.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regexec.$(OBJEXT): {$(VPATH)}assert.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+regexec.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
regexec.$(OBJEXT): {$(VPATH)}config.h
regexec.$(OBJEXT): {$(VPATH)}defines.h
regexec.$(OBJEXT): {$(VPATH)}intern.h
+regexec.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+regexec.$(OBJEXT): {$(VPATH)}internal/assume.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+regexec.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+regexec.$(OBJEXT): {$(VPATH)}internal/cast.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+regexec.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+regexec.$(OBJEXT): {$(VPATH)}internal/config.h
+regexec.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+regexec.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+regexec.$(OBJEXT): {$(VPATH)}internal/ctype.h
+regexec.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+regexec.$(OBJEXT): {$(VPATH)}internal/dosish.h
+regexec.$(OBJEXT): {$(VPATH)}internal/error.h
+regexec.$(OBJEXT): {$(VPATH)}internal/eval.h
+regexec.$(OBJEXT): {$(VPATH)}internal/event.h
+regexec.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+regexec.$(OBJEXT): {$(VPATH)}internal/gc.h
+regexec.$(OBJEXT): {$(VPATH)}internal/glob.h
+regexec.$(OBJEXT): {$(VPATH)}internal/globals.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+regexec.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+regexec.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+regexec.$(OBJEXT): {$(VPATH)}internal/iterator.h
+regexec.$(OBJEXT): {$(VPATH)}internal/memory.h
+regexec.$(OBJEXT): {$(VPATH)}internal/method.h
+regexec.$(OBJEXT): {$(VPATH)}internal/module.h
+regexec.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regexec.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+regexec.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+regexec.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+regexec.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+regexec.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+regexec.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+regexec.$(OBJEXT): {$(VPATH)}internal/symbol.h
+regexec.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+regexec.$(OBJEXT): {$(VPATH)}internal/value.h
+regexec.$(OBJEXT): {$(VPATH)}internal/value_type.h
+regexec.$(OBJEXT): {$(VPATH)}internal/variable.h
+regexec.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+regexec.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
regexec.$(OBJEXT): {$(VPATH)}missing.h
regexec.$(OBJEXT): {$(VPATH)}onigmo.h
-regexec.$(OBJEXT): {$(VPATH)}oniguruma.h
regexec.$(OBJEXT): {$(VPATH)}regenc.h
regexec.$(OBJEXT): {$(VPATH)}regexec.c
regexec.$(OBJEXT): {$(VPATH)}regint.h
regexec.$(OBJEXT): {$(VPATH)}st.h
regexec.$(OBJEXT): {$(VPATH)}subst.h
regparse.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regparse.$(OBJEXT): {$(VPATH)}assert.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+regparse.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
regparse.$(OBJEXT): {$(VPATH)}config.h
regparse.$(OBJEXT): {$(VPATH)}defines.h
regparse.$(OBJEXT): {$(VPATH)}intern.h
+regparse.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+regparse.$(OBJEXT): {$(VPATH)}internal/assume.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+regparse.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+regparse.$(OBJEXT): {$(VPATH)}internal/cast.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+regparse.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+regparse.$(OBJEXT): {$(VPATH)}internal/config.h
+regparse.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+regparse.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+regparse.$(OBJEXT): {$(VPATH)}internal/ctype.h
+regparse.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+regparse.$(OBJEXT): {$(VPATH)}internal/dosish.h
+regparse.$(OBJEXT): {$(VPATH)}internal/error.h
+regparse.$(OBJEXT): {$(VPATH)}internal/eval.h
+regparse.$(OBJEXT): {$(VPATH)}internal/event.h
+regparse.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+regparse.$(OBJEXT): {$(VPATH)}internal/gc.h
+regparse.$(OBJEXT): {$(VPATH)}internal/glob.h
+regparse.$(OBJEXT): {$(VPATH)}internal/globals.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+regparse.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+regparse.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+regparse.$(OBJEXT): {$(VPATH)}internal/iterator.h
+regparse.$(OBJEXT): {$(VPATH)}internal/memory.h
+regparse.$(OBJEXT): {$(VPATH)}internal/method.h
+regparse.$(OBJEXT): {$(VPATH)}internal/module.h
+regparse.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regparse.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+regparse.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+regparse.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+regparse.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+regparse.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+regparse.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+regparse.$(OBJEXT): {$(VPATH)}internal/symbol.h
+regparse.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+regparse.$(OBJEXT): {$(VPATH)}internal/value.h
+regparse.$(OBJEXT): {$(VPATH)}internal/value_type.h
+regparse.$(OBJEXT): {$(VPATH)}internal/variable.h
+regparse.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+regparse.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
regparse.$(OBJEXT): {$(VPATH)}missing.h
regparse.$(OBJEXT): {$(VPATH)}onigmo.h
-regparse.$(OBJEXT): {$(VPATH)}oniguruma.h
regparse.$(OBJEXT): {$(VPATH)}regenc.h
regparse.$(OBJEXT): {$(VPATH)}regint.h
regparse.$(OBJEXT): {$(VPATH)}regparse.c
@@ -2374,36 +11974,372 @@ regparse.$(OBJEXT): {$(VPATH)}regparse.h
regparse.$(OBJEXT): {$(VPATH)}st.h
regparse.$(OBJEXT): {$(VPATH)}subst.h
regsyntax.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regsyntax.$(OBJEXT): {$(VPATH)}assert.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+regsyntax.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
regsyntax.$(OBJEXT): {$(VPATH)}config.h
regsyntax.$(OBJEXT): {$(VPATH)}defines.h
regsyntax.$(OBJEXT): {$(VPATH)}intern.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/assume.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/cast.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/config.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/ctype.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/dosish.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/error.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/eval.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/event.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/gc.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/glob.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/globals.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/iterator.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/memory.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/method.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/module.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/symbol.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/value.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/value_type.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/variable.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
regsyntax.$(OBJEXT): {$(VPATH)}missing.h
regsyntax.$(OBJEXT): {$(VPATH)}onigmo.h
-regsyntax.$(OBJEXT): {$(VPATH)}oniguruma.h
regsyntax.$(OBJEXT): {$(VPATH)}regenc.h
regsyntax.$(OBJEXT): {$(VPATH)}regint.h
regsyntax.$(OBJEXT): {$(VPATH)}regsyntax.c
regsyntax.$(OBJEXT): {$(VPATH)}st.h
regsyntax.$(OBJEXT): {$(VPATH)}subst.h
+ruby-runner.$(OBJEXT): {$(VPATH)}config.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+ruby-runner.$(OBJEXT): {$(VPATH)}internal/config.h
ruby-runner.$(OBJEXT): {$(VPATH)}ruby-runner.c
ruby-runner.$(OBJEXT): {$(VPATH)}ruby-runner.h
ruby.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
ruby.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
ruby.$(OBJEXT): $(CCAN_DIR)/list/list.h
ruby.$(OBJEXT): $(CCAN_DIR)/str/str.h
+ruby.$(OBJEXT): $(hdrdir)/ruby.h
ruby.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-ruby.$(OBJEXT): $(top_srcdir)/include/ruby.h
+ruby.$(OBJEXT): $(hdrdir)/ruby/version.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/array.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/class.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/error.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/file.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/gc.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/inits.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/io.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/load.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/object.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/process.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/serial.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/string.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/variable.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/vm.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+ruby.$(OBJEXT): {$(VPATH)}assert.h
+ruby.$(OBJEXT): {$(VPATH)}atomic.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+ruby.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
ruby.$(OBJEXT): {$(VPATH)}config.h
+ruby.$(OBJEXT): {$(VPATH)}constant.h
+ruby.$(OBJEXT): {$(VPATH)}debug_counter.h
ruby.$(OBJEXT): {$(VPATH)}defines.h
ruby.$(OBJEXT): {$(VPATH)}dln.h
ruby.$(OBJEXT): {$(VPATH)}encoding.h
ruby.$(OBJEXT): {$(VPATH)}eval_intern.h
ruby.$(OBJEXT): {$(VPATH)}id.h
+ruby.$(OBJEXT): {$(VPATH)}id_table.h
ruby.$(OBJEXT): {$(VPATH)}intern.h
ruby.$(OBJEXT): {$(VPATH)}internal.h
+ruby.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+ruby.$(OBJEXT): {$(VPATH)}internal/assume.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+ruby.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+ruby.$(OBJEXT): {$(VPATH)}internal/cast.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+ruby.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+ruby.$(OBJEXT): {$(VPATH)}internal/config.h
+ruby.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+ruby.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+ruby.$(OBJEXT): {$(VPATH)}internal/ctype.h
+ruby.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+ruby.$(OBJEXT): {$(VPATH)}internal/dosish.h
+ruby.$(OBJEXT): {$(VPATH)}internal/error.h
+ruby.$(OBJEXT): {$(VPATH)}internal/eval.h
+ruby.$(OBJEXT): {$(VPATH)}internal/event.h
+ruby.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+ruby.$(OBJEXT): {$(VPATH)}internal/gc.h
+ruby.$(OBJEXT): {$(VPATH)}internal/glob.h
+ruby.$(OBJEXT): {$(VPATH)}internal/globals.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+ruby.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+ruby.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+ruby.$(OBJEXT): {$(VPATH)}internal/iterator.h
+ruby.$(OBJEXT): {$(VPATH)}internal/memory.h
+ruby.$(OBJEXT): {$(VPATH)}internal/method.h
+ruby.$(OBJEXT): {$(VPATH)}internal/module.h
+ruby.$(OBJEXT): {$(VPATH)}internal/newobj.h
+ruby.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+ruby.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+ruby.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+ruby.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+ruby.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+ruby.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+ruby.$(OBJEXT): {$(VPATH)}internal/symbol.h
+ruby.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+ruby.$(OBJEXT): {$(VPATH)}internal/value.h
+ruby.$(OBJEXT): {$(VPATH)}internal/value_type.h
+ruby.$(OBJEXT): {$(VPATH)}internal/variable.h
+ruby.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+ruby.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
ruby.$(OBJEXT): {$(VPATH)}io.h
ruby.$(OBJEXT): {$(VPATH)}method.h
ruby.$(OBJEXT): {$(VPATH)}missing.h
+ruby.$(OBJEXT): {$(VPATH)}mjit.h
ruby.$(OBJEXT): {$(VPATH)}node.h
ruby.$(OBJEXT): {$(VPATH)}onigmo.h
ruby.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -2417,41 +12353,349 @@ ruby.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
ruby.$(OBJEXT): {$(VPATH)}thread_native.h
ruby.$(OBJEXT): {$(VPATH)}util.h
ruby.$(OBJEXT): {$(VPATH)}vm_core.h
-ruby.$(OBJEXT): {$(VPATH)}vm_debug.h
ruby.$(OBJEXT): {$(VPATH)}vm_opts.h
-safe.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-safe.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-safe.$(OBJEXT): $(CCAN_DIR)/list/list.h
-safe.$(OBJEXT): $(CCAN_DIR)/str/str.h
-safe.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-safe.$(OBJEXT): $(top_srcdir)/include/ruby.h
-safe.$(OBJEXT): {$(VPATH)}config.h
-safe.$(OBJEXT): {$(VPATH)}defines.h
-safe.$(OBJEXT): {$(VPATH)}encoding.h
-safe.$(OBJEXT): {$(VPATH)}id.h
-safe.$(OBJEXT): {$(VPATH)}intern.h
-safe.$(OBJEXT): {$(VPATH)}internal.h
-safe.$(OBJEXT): {$(VPATH)}io.h
-safe.$(OBJEXT): {$(VPATH)}method.h
-safe.$(OBJEXT): {$(VPATH)}missing.h
-safe.$(OBJEXT): {$(VPATH)}node.h
-safe.$(OBJEXT): {$(VPATH)}onigmo.h
-safe.$(OBJEXT): {$(VPATH)}oniguruma.h
-safe.$(OBJEXT): {$(VPATH)}ruby_assert.h
-safe.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-safe.$(OBJEXT): {$(VPATH)}safe.c
-safe.$(OBJEXT): {$(VPATH)}st.h
-safe.$(OBJEXT): {$(VPATH)}subst.h
-safe.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-safe.$(OBJEXT): {$(VPATH)}thread_native.h
-safe.$(OBJEXT): {$(VPATH)}vm_core.h
-safe.$(OBJEXT): {$(VPATH)}vm_debug.h
-safe.$(OBJEXT): {$(VPATH)}vm_opts.h
+scheduler.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+scheduler.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+scheduler.$(OBJEXT): $(CCAN_DIR)/list/list.h
+scheduler.$(OBJEXT): $(CCAN_DIR)/str/str.h
+scheduler.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/array.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/vm.h
+scheduler.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+scheduler.$(OBJEXT): {$(VPATH)}assert.h
+scheduler.$(OBJEXT): {$(VPATH)}atomic.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+scheduler.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+scheduler.$(OBJEXT): {$(VPATH)}config.h
+scheduler.$(OBJEXT): {$(VPATH)}defines.h
+scheduler.$(OBJEXT): {$(VPATH)}encoding.h
+scheduler.$(OBJEXT): {$(VPATH)}id.h
+scheduler.$(OBJEXT): {$(VPATH)}intern.h
+scheduler.$(OBJEXT): {$(VPATH)}internal.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/assume.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/cast.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/config.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/ctype.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/dosish.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/error.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/eval.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/event.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/gc.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/glob.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/globals.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/iterator.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/memory.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/method.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/module.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/newobj.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/scheduler.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/symbol.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/value.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/value_type.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/variable.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+scheduler.$(OBJEXT): {$(VPATH)}io.h
+scheduler.$(OBJEXT): {$(VPATH)}method.h
+scheduler.$(OBJEXT): {$(VPATH)}missing.h
+scheduler.$(OBJEXT): {$(VPATH)}node.h
+scheduler.$(OBJEXT): {$(VPATH)}onigmo.h
+scheduler.$(OBJEXT): {$(VPATH)}oniguruma.h
+scheduler.$(OBJEXT): {$(VPATH)}ruby_assert.h
+scheduler.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+scheduler.$(OBJEXT): {$(VPATH)}scheduler.c
+scheduler.$(OBJEXT): {$(VPATH)}st.h
+scheduler.$(OBJEXT): {$(VPATH)}subst.h
+scheduler.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+scheduler.$(OBJEXT): {$(VPATH)}thread_native.h
+scheduler.$(OBJEXT): {$(VPATH)}vm_core.h
+scheduler.$(OBJEXT): {$(VPATH)}vm_opts.h
+setproctitle.$(OBJEXT): $(hdrdir)/ruby.h
setproctitle.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-setproctitle.$(OBJEXT): $(top_srcdir)/include/ruby.h
+setproctitle.$(OBJEXT): {$(VPATH)}assert.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+setproctitle.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
setproctitle.$(OBJEXT): {$(VPATH)}config.h
setproctitle.$(OBJEXT): {$(VPATH)}defines.h
setproctitle.$(OBJEXT): {$(VPATH)}intern.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/assume.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/cast.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/config.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/ctype.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/dosish.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/error.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/eval.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/event.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/gc.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/glob.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/globals.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/iterator.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/memory.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/method.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/module.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/newobj.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/symbol.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/value.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/value_type.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/variable.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
setproctitle.$(OBJEXT): {$(VPATH)}missing.h
setproctitle.$(OBJEXT): {$(VPATH)}setproctitle.c
setproctitle.$(OBJEXT): {$(VPATH)}st.h
@@ -2461,21 +12705,188 @@ signal.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
signal.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
signal.$(OBJEXT): $(CCAN_DIR)/list/list.h
signal.$(OBJEXT): $(CCAN_DIR)/str/str.h
+signal.$(OBJEXT): $(hdrdir)/ruby.h
signal.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-signal.$(OBJEXT): $(top_srcdir)/include/ruby.h
+signal.$(OBJEXT): $(top_srcdir)/internal/array.h
+signal.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+signal.$(OBJEXT): $(top_srcdir)/internal/eval.h
+signal.$(OBJEXT): $(top_srcdir)/internal/gc.h
+signal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+signal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+signal.$(OBJEXT): $(top_srcdir)/internal/serial.h
+signal.$(OBJEXT): $(top_srcdir)/internal/signal.h
+signal.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+signal.$(OBJEXT): $(top_srcdir)/internal/string.h
+signal.$(OBJEXT): $(top_srcdir)/internal/thread.h
+signal.$(OBJEXT): $(top_srcdir)/internal/vm.h
+signal.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+signal.$(OBJEXT): {$(VPATH)}assert.h
+signal.$(OBJEXT): {$(VPATH)}atomic.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+signal.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
signal.$(OBJEXT): {$(VPATH)}config.h
+signal.$(OBJEXT): {$(VPATH)}debug_counter.h
signal.$(OBJEXT): {$(VPATH)}defines.h
signal.$(OBJEXT): {$(VPATH)}encoding.h
signal.$(OBJEXT): {$(VPATH)}eval_intern.h
signal.$(OBJEXT): {$(VPATH)}id.h
+signal.$(OBJEXT): {$(VPATH)}id_table.h
signal.$(OBJEXT): {$(VPATH)}intern.h
signal.$(OBJEXT): {$(VPATH)}internal.h
-signal.$(OBJEXT): {$(VPATH)}io.h
+signal.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+signal.$(OBJEXT): {$(VPATH)}internal/assume.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+signal.$(OBJEXT): {$(VPATH)}internal/cast.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+signal.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+signal.$(OBJEXT): {$(VPATH)}internal/config.h
+signal.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+signal.$(OBJEXT): {$(VPATH)}internal/core.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+signal.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+signal.$(OBJEXT): {$(VPATH)}internal/ctype.h
+signal.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+signal.$(OBJEXT): {$(VPATH)}internal/dosish.h
+signal.$(OBJEXT): {$(VPATH)}internal/error.h
+signal.$(OBJEXT): {$(VPATH)}internal/eval.h
+signal.$(OBJEXT): {$(VPATH)}internal/event.h
+signal.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+signal.$(OBJEXT): {$(VPATH)}internal/gc.h
+signal.$(OBJEXT): {$(VPATH)}internal/glob.h
+signal.$(OBJEXT): {$(VPATH)}internal/globals.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+signal.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+signal.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+signal.$(OBJEXT): {$(VPATH)}internal/iterator.h
+signal.$(OBJEXT): {$(VPATH)}internal/memory.h
+signal.$(OBJEXT): {$(VPATH)}internal/method.h
+signal.$(OBJEXT): {$(VPATH)}internal/module.h
+signal.$(OBJEXT): {$(VPATH)}internal/newobj.h
+signal.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+signal.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+signal.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+signal.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+signal.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+signal.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+signal.$(OBJEXT): {$(VPATH)}internal/symbol.h
+signal.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+signal.$(OBJEXT): {$(VPATH)}internal/value.h
+signal.$(OBJEXT): {$(VPATH)}internal/value_type.h
+signal.$(OBJEXT): {$(VPATH)}internal/variable.h
+signal.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+signal.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
signal.$(OBJEXT): {$(VPATH)}method.h
signal.$(OBJEXT): {$(VPATH)}missing.h
signal.$(OBJEXT): {$(VPATH)}node.h
signal.$(OBJEXT): {$(VPATH)}onigmo.h
signal.$(OBJEXT): {$(VPATH)}oniguruma.h
+signal.$(OBJEXT): {$(VPATH)}ractor.h
+signal.$(OBJEXT): {$(VPATH)}ractor_core.h
signal.$(OBJEXT): {$(VPATH)}ruby_assert.h
signal.$(OBJEXT): {$(VPATH)}ruby_atomic.h
signal.$(OBJEXT): {$(VPATH)}signal.c
@@ -2486,15 +12897,184 @@ signal.$(OBJEXT): {$(VPATH)}thread_native.h
signal.$(OBJEXT): {$(VPATH)}vm_core.h
signal.$(OBJEXT): {$(VPATH)}vm_debug.h
signal.$(OBJEXT): {$(VPATH)}vm_opts.h
+sprintf.$(OBJEXT): $(hdrdir)/ruby.h
sprintf.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-sprintf.$(OBJEXT): $(top_srcdir)/include/ruby.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/bits.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/class.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/error.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/gc.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/hash.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/object.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/serial.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/string.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/util.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/vm.h
+sprintf.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+sprintf.$(OBJEXT): {$(VPATH)}assert.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+sprintf.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
sprintf.$(OBJEXT): {$(VPATH)}config.h
sprintf.$(OBJEXT): {$(VPATH)}defines.h
sprintf.$(OBJEXT): {$(VPATH)}encoding.h
sprintf.$(OBJEXT): {$(VPATH)}id.h
+sprintf.$(OBJEXT): {$(VPATH)}id_table.h
sprintf.$(OBJEXT): {$(VPATH)}intern.h
sprintf.$(OBJEXT): {$(VPATH)}internal.h
-sprintf.$(OBJEXT): {$(VPATH)}io.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/assume.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/cast.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/config.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rmatch.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/ctype.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/dosish.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/error.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/eval.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/event.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/gc.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/glob.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/globals.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/iterator.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/memory.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/method.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/module.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/newobj.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/symbol.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/value.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/value_type.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/variable.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
sprintf.$(OBJEXT): {$(VPATH)}missing.h
sprintf.$(OBJEXT): {$(VPATH)}onigmo.h
sprintf.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -2504,32 +13084,335 @@ sprintf.$(OBJEXT): {$(VPATH)}sprintf.c
sprintf.$(OBJEXT): {$(VPATH)}st.h
sprintf.$(OBJEXT): {$(VPATH)}subst.h
sprintf.$(OBJEXT): {$(VPATH)}vsnprintf.c
-st.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-st.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-st.$(OBJEXT): $(CCAN_DIR)/list/list.h
-st.$(OBJEXT): $(CCAN_DIR)/str/str.h
+st.$(OBJEXT): $(hdrdir)/ruby.h
st.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-st.$(OBJEXT): $(top_srcdir)/include/ruby.h
+st.$(OBJEXT): $(top_srcdir)/internal/bits.h
+st.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+st.$(OBJEXT): $(top_srcdir)/internal/hash.h
+st.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+st.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+st.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+st.$(OBJEXT): {$(VPATH)}assert.h
+st.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+st.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+st.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+st.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+st.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+st.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+st.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+st.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+st.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
st.$(OBJEXT): {$(VPATH)}config.h
st.$(OBJEXT): {$(VPATH)}defines.h
-st.$(OBJEXT): {$(VPATH)}encoding.h
st.$(OBJEXT): {$(VPATH)}intern.h
st.$(OBJEXT): {$(VPATH)}internal.h
-st.$(OBJEXT): {$(VPATH)}io.h
+st.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+st.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+st.$(OBJEXT): {$(VPATH)}internal/assume.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+st.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+st.$(OBJEXT): {$(VPATH)}internal/cast.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+st.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+st.$(OBJEXT): {$(VPATH)}internal/config.h
+st.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+st.$(OBJEXT): {$(VPATH)}internal/core.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+st.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+st.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+st.$(OBJEXT): {$(VPATH)}internal/ctype.h
+st.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+st.$(OBJEXT): {$(VPATH)}internal/dosish.h
+st.$(OBJEXT): {$(VPATH)}internal/error.h
+st.$(OBJEXT): {$(VPATH)}internal/eval.h
+st.$(OBJEXT): {$(VPATH)}internal/event.h
+st.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+st.$(OBJEXT): {$(VPATH)}internal/gc.h
+st.$(OBJEXT): {$(VPATH)}internal/glob.h
+st.$(OBJEXT): {$(VPATH)}internal/globals.h
+st.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+st.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+st.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+st.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+st.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+st.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+st.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+st.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+st.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+st.$(OBJEXT): {$(VPATH)}internal/iterator.h
+st.$(OBJEXT): {$(VPATH)}internal/memory.h
+st.$(OBJEXT): {$(VPATH)}internal/method.h
+st.$(OBJEXT): {$(VPATH)}internal/module.h
+st.$(OBJEXT): {$(VPATH)}internal/newobj.h
+st.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+st.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+st.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+st.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+st.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+st.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+st.$(OBJEXT): {$(VPATH)}internal/symbol.h
+st.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+st.$(OBJEXT): {$(VPATH)}internal/value.h
+st.$(OBJEXT): {$(VPATH)}internal/value_type.h
+st.$(OBJEXT): {$(VPATH)}internal/variable.h
+st.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+st.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
st.$(OBJEXT): {$(VPATH)}missing.h
-st.$(OBJEXT): {$(VPATH)}onigmo.h
-st.$(OBJEXT): {$(VPATH)}oniguruma.h
st.$(OBJEXT): {$(VPATH)}st.c
st.$(OBJEXT): {$(VPATH)}st.h
st.$(OBJEXT): {$(VPATH)}subst.h
+strftime.$(OBJEXT): $(hdrdir)/ruby.h
strftime.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-strftime.$(OBJEXT): $(top_srcdir)/include/ruby.h
+strftime.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+strftime.$(OBJEXT): $(top_srcdir)/internal/serial.h
+strftime.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+strftime.$(OBJEXT): $(top_srcdir)/internal/string.h
+strftime.$(OBJEXT): $(top_srcdir)/internal/util.h
+strftime.$(OBJEXT): $(top_srcdir)/internal/vm.h
+strftime.$(OBJEXT): {$(VPATH)}assert.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+strftime.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
strftime.$(OBJEXT): {$(VPATH)}config.h
strftime.$(OBJEXT): {$(VPATH)}defines.h
strftime.$(OBJEXT): {$(VPATH)}encoding.h
strftime.$(OBJEXT): {$(VPATH)}intern.h
strftime.$(OBJEXT): {$(VPATH)}internal.h
-strftime.$(OBJEXT): {$(VPATH)}io.h
+strftime.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+strftime.$(OBJEXT): {$(VPATH)}internal/assume.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+strftime.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+strftime.$(OBJEXT): {$(VPATH)}internal/cast.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+strftime.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+strftime.$(OBJEXT): {$(VPATH)}internal/config.h
+strftime.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+strftime.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+strftime.$(OBJEXT): {$(VPATH)}internal/ctype.h
+strftime.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+strftime.$(OBJEXT): {$(VPATH)}internal/dosish.h
+strftime.$(OBJEXT): {$(VPATH)}internal/error.h
+strftime.$(OBJEXT): {$(VPATH)}internal/eval.h
+strftime.$(OBJEXT): {$(VPATH)}internal/event.h
+strftime.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+strftime.$(OBJEXT): {$(VPATH)}internal/gc.h
+strftime.$(OBJEXT): {$(VPATH)}internal/glob.h
+strftime.$(OBJEXT): {$(VPATH)}internal/globals.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+strftime.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+strftime.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+strftime.$(OBJEXT): {$(VPATH)}internal/iterator.h
+strftime.$(OBJEXT): {$(VPATH)}internal/memory.h
+strftime.$(OBJEXT): {$(VPATH)}internal/method.h
+strftime.$(OBJEXT): {$(VPATH)}internal/module.h
+strftime.$(OBJEXT): {$(VPATH)}internal/newobj.h
+strftime.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+strftime.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+strftime.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+strftime.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+strftime.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+strftime.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+strftime.$(OBJEXT): {$(VPATH)}internal/symbol.h
+strftime.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+strftime.$(OBJEXT): {$(VPATH)}internal/value.h
+strftime.$(OBJEXT): {$(VPATH)}internal/value_type.h
+strftime.$(OBJEXT): {$(VPATH)}internal/variable.h
+strftime.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+strftime.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
strftime.$(OBJEXT): {$(VPATH)}missing.h
strftime.$(OBJEXT): {$(VPATH)}onigmo.h
strftime.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -2537,8 +13420,39 @@ strftime.$(OBJEXT): {$(VPATH)}st.h
strftime.$(OBJEXT): {$(VPATH)}strftime.c
strftime.$(OBJEXT): {$(VPATH)}subst.h
strftime.$(OBJEXT): {$(VPATH)}timev.h
+string.$(OBJEXT): $(hdrdir)/ruby.h
string.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-string.$(OBJEXT): $(top_srcdir)/include/ruby.h
+string.$(OBJEXT): $(top_srcdir)/internal/array.h
+string.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+string.$(OBJEXT): $(top_srcdir)/internal/bits.h
+string.$(OBJEXT): $(top_srcdir)/internal/class.h
+string.$(OBJEXT): $(top_srcdir)/internal/compar.h
+string.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+string.$(OBJEXT): $(top_srcdir)/internal/encoding.h
+string.$(OBJEXT): $(top_srcdir)/internal/error.h
+string.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+string.$(OBJEXT): $(top_srcdir)/internal/gc.h
+string.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+string.$(OBJEXT): $(top_srcdir)/internal/object.h
+string.$(OBJEXT): $(top_srcdir)/internal/proc.h
+string.$(OBJEXT): $(top_srcdir)/internal/re.h
+string.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+string.$(OBJEXT): $(top_srcdir)/internal/serial.h
+string.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+string.$(OBJEXT): $(top_srcdir)/internal/string.h
+string.$(OBJEXT): $(top_srcdir)/internal/transcode.h
+string.$(OBJEXT): $(top_srcdir)/internal/vm.h
+string.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+string.$(OBJEXT): {$(VPATH)}assert.h
+string.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+string.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+string.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+string.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+string.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+string.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+string.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+string.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+string.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
string.$(OBJEXT): {$(VPATH)}config.h
string.$(OBJEXT): {$(VPATH)}crypt.h
string.$(OBJEXT): {$(VPATH)}debug_counter.h
@@ -2547,10 +13461,152 @@ string.$(OBJEXT): {$(VPATH)}encindex.h
string.$(OBJEXT): {$(VPATH)}encoding.h
string.$(OBJEXT): {$(VPATH)}gc.h
string.$(OBJEXT): {$(VPATH)}id.h
+string.$(OBJEXT): {$(VPATH)}id_table.h
string.$(OBJEXT): {$(VPATH)}intern.h
string.$(OBJEXT): {$(VPATH)}internal.h
-string.$(OBJEXT): {$(VPATH)}io.h
+string.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+string.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+string.$(OBJEXT): {$(VPATH)}internal/assume.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+string.$(OBJEXT): {$(VPATH)}internal/cast.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+string.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+string.$(OBJEXT): {$(VPATH)}internal/config.h
+string.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+string.$(OBJEXT): {$(VPATH)}internal/core.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rmatch.h
+string.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+string.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+string.$(OBJEXT): {$(VPATH)}internal/ctype.h
+string.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+string.$(OBJEXT): {$(VPATH)}internal/dosish.h
+string.$(OBJEXT): {$(VPATH)}internal/error.h
+string.$(OBJEXT): {$(VPATH)}internal/eval.h
+string.$(OBJEXT): {$(VPATH)}internal/event.h
+string.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+string.$(OBJEXT): {$(VPATH)}internal/gc.h
+string.$(OBJEXT): {$(VPATH)}internal/glob.h
+string.$(OBJEXT): {$(VPATH)}internal/globals.h
+string.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+string.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+string.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+string.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+string.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+string.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+string.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+string.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+string.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+string.$(OBJEXT): {$(VPATH)}internal/iterator.h
+string.$(OBJEXT): {$(VPATH)}internal/memory.h
+string.$(OBJEXT): {$(VPATH)}internal/method.h
+string.$(OBJEXT): {$(VPATH)}internal/module.h
+string.$(OBJEXT): {$(VPATH)}internal/newobj.h
+string.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+string.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+string.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+string.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+string.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+string.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+string.$(OBJEXT): {$(VPATH)}internal/symbol.h
+string.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+string.$(OBJEXT): {$(VPATH)}internal/value.h
+string.$(OBJEXT): {$(VPATH)}internal/value_type.h
+string.$(OBJEXT): {$(VPATH)}internal/variable.h
+string.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+string.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
string.$(OBJEXT): {$(VPATH)}missing.h
+string.$(OBJEXT): {$(VPATH)}node.h
string.$(OBJEXT): {$(VPATH)}onigmo.h
string.$(OBJEXT): {$(VPATH)}oniguruma.h
string.$(OBJEXT): {$(VPATH)}probes.dmyh
@@ -2561,25 +13617,216 @@ string.$(OBJEXT): {$(VPATH)}ruby_assert.h
string.$(OBJEXT): {$(VPATH)}st.h
string.$(OBJEXT): {$(VPATH)}string.c
string.$(OBJEXT): {$(VPATH)}subst.h
+string.$(OBJEXT): {$(VPATH)}util.h
+string.$(OBJEXT): {$(VPATH)}vm_debug.h
+string.$(OBJEXT): {$(VPATH)}vm_sync.h
strlcat.$(OBJEXT): {$(VPATH)}config.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/config.h
+strlcat.$(OBJEXT): {$(VPATH)}internal/dllexport.h
strlcat.$(OBJEXT): {$(VPATH)}missing.h
strlcat.$(OBJEXT): {$(VPATH)}strlcat.c
strlcpy.$(OBJEXT): {$(VPATH)}config.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/config.h
+strlcpy.$(OBJEXT): {$(VPATH)}internal/dllexport.h
strlcpy.$(OBJEXT): {$(VPATH)}missing.h
strlcpy.$(OBJEXT): {$(VPATH)}strlcpy.c
struct.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
struct.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
struct.$(OBJEXT): $(CCAN_DIR)/list/list.h
struct.$(OBJEXT): $(CCAN_DIR)/str/str.h
+struct.$(OBJEXT): $(hdrdir)/ruby.h
struct.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-struct.$(OBJEXT): $(top_srcdir)/include/ruby.h
+struct.$(OBJEXT): $(top_srcdir)/internal/array.h
+struct.$(OBJEXT): $(top_srcdir)/internal/class.h
+struct.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+struct.$(OBJEXT): $(top_srcdir)/internal/error.h
+struct.$(OBJEXT): $(top_srcdir)/internal/gc.h
+struct.$(OBJEXT): $(top_srcdir)/internal/hash.h
+struct.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+struct.$(OBJEXT): $(top_srcdir)/internal/object.h
+struct.$(OBJEXT): $(top_srcdir)/internal/proc.h
+struct.$(OBJEXT): $(top_srcdir)/internal/serial.h
+struct.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+struct.$(OBJEXT): $(top_srcdir)/internal/string.h
+struct.$(OBJEXT): $(top_srcdir)/internal/struct.h
+struct.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+struct.$(OBJEXT): $(top_srcdir)/internal/vm.h
+struct.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+struct.$(OBJEXT): {$(VPATH)}assert.h
+struct.$(OBJEXT): {$(VPATH)}atomic.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+struct.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+struct.$(OBJEXT): {$(VPATH)}builtin.h
struct.$(OBJEXT): {$(VPATH)}config.h
struct.$(OBJEXT): {$(VPATH)}defines.h
struct.$(OBJEXT): {$(VPATH)}encoding.h
struct.$(OBJEXT): {$(VPATH)}id.h
+struct.$(OBJEXT): {$(VPATH)}id_table.h
struct.$(OBJEXT): {$(VPATH)}intern.h
struct.$(OBJEXT): {$(VPATH)}internal.h
-struct.$(OBJEXT): {$(VPATH)}io.h
+struct.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+struct.$(OBJEXT): {$(VPATH)}internal/assume.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+struct.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+struct.$(OBJEXT): {$(VPATH)}internal/cast.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+struct.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+struct.$(OBJEXT): {$(VPATH)}internal/config.h
+struct.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+struct.$(OBJEXT): {$(VPATH)}internal/core.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+struct.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+struct.$(OBJEXT): {$(VPATH)}internal/ctype.h
+struct.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+struct.$(OBJEXT): {$(VPATH)}internal/dosish.h
+struct.$(OBJEXT): {$(VPATH)}internal/error.h
+struct.$(OBJEXT): {$(VPATH)}internal/eval.h
+struct.$(OBJEXT): {$(VPATH)}internal/event.h
+struct.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+struct.$(OBJEXT): {$(VPATH)}internal/gc.h
+struct.$(OBJEXT): {$(VPATH)}internal/glob.h
+struct.$(OBJEXT): {$(VPATH)}internal/globals.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+struct.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+struct.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+struct.$(OBJEXT): {$(VPATH)}internal/iterator.h
+struct.$(OBJEXT): {$(VPATH)}internal/memory.h
+struct.$(OBJEXT): {$(VPATH)}internal/method.h
+struct.$(OBJEXT): {$(VPATH)}internal/module.h
+struct.$(OBJEXT): {$(VPATH)}internal/newobj.h
+struct.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+struct.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+struct.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+struct.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+struct.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+struct.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+struct.$(OBJEXT): {$(VPATH)}internal/symbol.h
+struct.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+struct.$(OBJEXT): {$(VPATH)}internal/value.h
+struct.$(OBJEXT): {$(VPATH)}internal/value_type.h
+struct.$(OBJEXT): {$(VPATH)}internal/variable.h
+struct.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+struct.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
struct.$(OBJEXT): {$(VPATH)}method.h
struct.$(OBJEXT): {$(VPATH)}missing.h
struct.$(OBJEXT): {$(VPATH)}node.h
@@ -2592,12 +13839,35 @@ struct.$(OBJEXT): {$(VPATH)}struct.c
struct.$(OBJEXT): {$(VPATH)}subst.h
struct.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
struct.$(OBJEXT): {$(VPATH)}thread_native.h
+struct.$(OBJEXT): {$(VPATH)}transient_heap.h
struct.$(OBJEXT): {$(VPATH)}vm_core.h
-struct.$(OBJEXT): {$(VPATH)}vm_debug.h
struct.$(OBJEXT): {$(VPATH)}vm_opts.h
+symbol.$(OBJEXT): $(hdrdir)/ruby.h
symbol.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-symbol.$(OBJEXT): $(top_srcdir)/include/ruby.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/class.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/error.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/gc.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/hash.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/object.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/serial.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/string.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/vm.h
+symbol.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+symbol.$(OBJEXT): {$(VPATH)}assert.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+symbol.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
symbol.$(OBJEXT): {$(VPATH)}config.h
+symbol.$(OBJEXT): {$(VPATH)}debug_counter.h
symbol.$(OBJEXT): {$(VPATH)}defines.h
symbol.$(OBJEXT): {$(VPATH)}encoding.h
symbol.$(OBJEXT): {$(VPATH)}gc.h
@@ -2607,8 +13877,148 @@ symbol.$(OBJEXT): {$(VPATH)}id_table.c
symbol.$(OBJEXT): {$(VPATH)}id_table.h
symbol.$(OBJEXT): {$(VPATH)}intern.h
symbol.$(OBJEXT): {$(VPATH)}internal.h
-symbol.$(OBJEXT): {$(VPATH)}io.h
+symbol.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+symbol.$(OBJEXT): {$(VPATH)}internal/assume.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+symbol.$(OBJEXT): {$(VPATH)}internal/cast.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+symbol.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+symbol.$(OBJEXT): {$(VPATH)}internal/config.h
+symbol.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+symbol.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+symbol.$(OBJEXT): {$(VPATH)}internal/ctype.h
+symbol.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+symbol.$(OBJEXT): {$(VPATH)}internal/dosish.h
+symbol.$(OBJEXT): {$(VPATH)}internal/error.h
+symbol.$(OBJEXT): {$(VPATH)}internal/eval.h
+symbol.$(OBJEXT): {$(VPATH)}internal/event.h
+symbol.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+symbol.$(OBJEXT): {$(VPATH)}internal/gc.h
+symbol.$(OBJEXT): {$(VPATH)}internal/glob.h
+symbol.$(OBJEXT): {$(VPATH)}internal/globals.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+symbol.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+symbol.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+symbol.$(OBJEXT): {$(VPATH)}internal/iterator.h
+symbol.$(OBJEXT): {$(VPATH)}internal/memory.h
+symbol.$(OBJEXT): {$(VPATH)}internal/method.h
+symbol.$(OBJEXT): {$(VPATH)}internal/module.h
+symbol.$(OBJEXT): {$(VPATH)}internal/newobj.h
+symbol.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+symbol.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+symbol.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+symbol.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+symbol.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+symbol.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+symbol.$(OBJEXT): {$(VPATH)}internal/symbol.h
+symbol.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+symbol.$(OBJEXT): {$(VPATH)}internal/value.h
+symbol.$(OBJEXT): {$(VPATH)}internal/value_type.h
+symbol.$(OBJEXT): {$(VPATH)}internal/variable.h
+symbol.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+symbol.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
symbol.$(OBJEXT): {$(VPATH)}missing.h
+symbol.$(OBJEXT): {$(VPATH)}node.h
symbol.$(OBJEXT): {$(VPATH)}onigmo.h
symbol.$(OBJEXT): {$(VPATH)}oniguruma.h
symbol.$(OBJEXT): {$(VPATH)}probes.dmyh
@@ -2618,26 +14028,209 @@ symbol.$(OBJEXT): {$(VPATH)}st.h
symbol.$(OBJEXT): {$(VPATH)}subst.h
symbol.$(OBJEXT): {$(VPATH)}symbol.c
symbol.$(OBJEXT): {$(VPATH)}symbol.h
+symbol.$(OBJEXT): {$(VPATH)}vm_debug.h
+symbol.$(OBJEXT): {$(VPATH)}vm_sync.h
thread.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
thread.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
thread.$(OBJEXT): $(CCAN_DIR)/list/list.h
thread.$(OBJEXT): $(CCAN_DIR)/str/str.h
+thread.$(OBJEXT): $(hdrdir)/ruby.h
thread.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-thread.$(OBJEXT): $(top_srcdir)/include/ruby.h
+thread.$(OBJEXT): $(top_srcdir)/internal/array.h
+thread.$(OBJEXT): $(top_srcdir)/internal/bits.h
+thread.$(OBJEXT): $(top_srcdir)/internal/class.h
+thread.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+thread.$(OBJEXT): $(top_srcdir)/internal/cont.h
+thread.$(OBJEXT): $(top_srcdir)/internal/error.h
+thread.$(OBJEXT): $(top_srcdir)/internal/gc.h
+thread.$(OBJEXT): $(top_srcdir)/internal/hash.h
+thread.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+thread.$(OBJEXT): $(top_srcdir)/internal/io.h
+thread.$(OBJEXT): $(top_srcdir)/internal/object.h
+thread.$(OBJEXT): $(top_srcdir)/internal/proc.h
+thread.$(OBJEXT): $(top_srcdir)/internal/scheduler.h
+thread.$(OBJEXT): $(top_srcdir)/internal/serial.h
+thread.$(OBJEXT): $(top_srcdir)/internal/signal.h
+thread.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+thread.$(OBJEXT): $(top_srcdir)/internal/string.h
+thread.$(OBJEXT): $(top_srcdir)/internal/thread.h
+thread.$(OBJEXT): $(top_srcdir)/internal/time.h
+thread.$(OBJEXT): $(top_srcdir)/internal/vm.h
+thread.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+thread.$(OBJEXT): {$(VPATH)}$(COROUTINE_H)
+thread.$(OBJEXT): {$(VPATH)}assert.h
+thread.$(OBJEXT): {$(VPATH)}atomic.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+thread.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
thread.$(OBJEXT): {$(VPATH)}config.h
+thread.$(OBJEXT): {$(VPATH)}debug.h
+thread.$(OBJEXT): {$(VPATH)}debug_counter.h
thread.$(OBJEXT): {$(VPATH)}defines.h
thread.$(OBJEXT): {$(VPATH)}encoding.h
thread.$(OBJEXT): {$(VPATH)}eval_intern.h
thread.$(OBJEXT): {$(VPATH)}gc.h
+thread.$(OBJEXT): {$(VPATH)}hrtime.h
thread.$(OBJEXT): {$(VPATH)}id.h
+thread.$(OBJEXT): {$(VPATH)}id_table.h
thread.$(OBJEXT): {$(VPATH)}intern.h
thread.$(OBJEXT): {$(VPATH)}internal.h
+thread.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+thread.$(OBJEXT): {$(VPATH)}internal/assume.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+thread.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+thread.$(OBJEXT): {$(VPATH)}internal/cast.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+thread.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+thread.$(OBJEXT): {$(VPATH)}internal/config.h
+thread.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+thread.$(OBJEXT): {$(VPATH)}internal/core.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+thread.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+thread.$(OBJEXT): {$(VPATH)}internal/ctype.h
+thread.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+thread.$(OBJEXT): {$(VPATH)}internal/dosish.h
+thread.$(OBJEXT): {$(VPATH)}internal/error.h
+thread.$(OBJEXT): {$(VPATH)}internal/eval.h
+thread.$(OBJEXT): {$(VPATH)}internal/event.h
+thread.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+thread.$(OBJEXT): {$(VPATH)}internal/gc.h
+thread.$(OBJEXT): {$(VPATH)}internal/glob.h
+thread.$(OBJEXT): {$(VPATH)}internal/globals.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+thread.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+thread.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+thread.$(OBJEXT): {$(VPATH)}internal/iterator.h
+thread.$(OBJEXT): {$(VPATH)}internal/memory.h
+thread.$(OBJEXT): {$(VPATH)}internal/method.h
+thread.$(OBJEXT): {$(VPATH)}internal/module.h
+thread.$(OBJEXT): {$(VPATH)}internal/newobj.h
+thread.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+thread.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+thread.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+thread.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+thread.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+thread.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+thread.$(OBJEXT): {$(VPATH)}internal/symbol.h
+thread.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+thread.$(OBJEXT): {$(VPATH)}internal/value.h
+thread.$(OBJEXT): {$(VPATH)}internal/value_type.h
+thread.$(OBJEXT): {$(VPATH)}internal/variable.h
+thread.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+thread.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
thread.$(OBJEXT): {$(VPATH)}io.h
+thread.$(OBJEXT): {$(VPATH)}iseq.h
thread.$(OBJEXT): {$(VPATH)}method.h
thread.$(OBJEXT): {$(VPATH)}missing.h
+thread.$(OBJEXT): {$(VPATH)}mjit.h
thread.$(OBJEXT): {$(VPATH)}node.h
thread.$(OBJEXT): {$(VPATH)}onigmo.h
thread.$(OBJEXT): {$(VPATH)}oniguruma.h
+thread.$(OBJEXT): {$(VPATH)}ractor.h
+thread.$(OBJEXT): {$(VPATH)}ractor_core.h
thread.$(OBJEXT): {$(VPATH)}ruby_assert.h
thread.$(OBJEXT): {$(VPATH)}ruby_atomic.h
thread.$(OBJEXT): {$(VPATH)}st.h
@@ -2652,30 +14245,361 @@ thread.$(OBJEXT): {$(VPATH)}timev.h
thread.$(OBJEXT): {$(VPATH)}vm_core.h
thread.$(OBJEXT): {$(VPATH)}vm_debug.h
thread.$(OBJEXT): {$(VPATH)}vm_opts.h
+thread.$(OBJEXT): {$(VPATH)}vm_sync.h
+time.$(OBJEXT): $(hdrdir)/ruby.h
time.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-time.$(OBJEXT): $(top_srcdir)/include/ruby.h
+time.$(OBJEXT): $(top_srcdir)/internal/array.h
+time.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+time.$(OBJEXT): $(top_srcdir)/internal/bits.h
+time.$(OBJEXT): $(top_srcdir)/internal/compar.h
+time.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+time.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+time.$(OBJEXT): $(top_srcdir)/internal/gc.h
+time.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+time.$(OBJEXT): $(top_srcdir)/internal/rational.h
+time.$(OBJEXT): $(top_srcdir)/internal/serial.h
+time.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+time.$(OBJEXT): $(top_srcdir)/internal/string.h
+time.$(OBJEXT): $(top_srcdir)/internal/time.h
+time.$(OBJEXT): $(top_srcdir)/internal/variable.h
+time.$(OBJEXT): $(top_srcdir)/internal/vm.h
+time.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+time.$(OBJEXT): {$(VPATH)}assert.h
+time.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+time.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+time.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+time.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+time.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+time.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+time.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+time.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+time.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
time.$(OBJEXT): {$(VPATH)}config.h
+time.$(OBJEXT): {$(VPATH)}constant.h
time.$(OBJEXT): {$(VPATH)}defines.h
time.$(OBJEXT): {$(VPATH)}encoding.h
time.$(OBJEXT): {$(VPATH)}id.h
+time.$(OBJEXT): {$(VPATH)}id_table.h
time.$(OBJEXT): {$(VPATH)}intern.h
time.$(OBJEXT): {$(VPATH)}internal.h
-time.$(OBJEXT): {$(VPATH)}io.h
+time.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+time.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+time.$(OBJEXT): {$(VPATH)}internal/assume.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+time.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+time.$(OBJEXT): {$(VPATH)}internal/cast.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+time.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+time.$(OBJEXT): {$(VPATH)}internal/config.h
+time.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+time.$(OBJEXT): {$(VPATH)}internal/core.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+time.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+time.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+time.$(OBJEXT): {$(VPATH)}internal/ctype.h
+time.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+time.$(OBJEXT): {$(VPATH)}internal/dosish.h
+time.$(OBJEXT): {$(VPATH)}internal/error.h
+time.$(OBJEXT): {$(VPATH)}internal/eval.h
+time.$(OBJEXT): {$(VPATH)}internal/event.h
+time.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+time.$(OBJEXT): {$(VPATH)}internal/gc.h
+time.$(OBJEXT): {$(VPATH)}internal/glob.h
+time.$(OBJEXT): {$(VPATH)}internal/globals.h
+time.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+time.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+time.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+time.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+time.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+time.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+time.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+time.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+time.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+time.$(OBJEXT): {$(VPATH)}internal/iterator.h
+time.$(OBJEXT): {$(VPATH)}internal/memory.h
+time.$(OBJEXT): {$(VPATH)}internal/method.h
+time.$(OBJEXT): {$(VPATH)}internal/module.h
+time.$(OBJEXT): {$(VPATH)}internal/newobj.h
+time.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+time.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+time.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+time.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+time.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+time.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+time.$(OBJEXT): {$(VPATH)}internal/symbol.h
+time.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+time.$(OBJEXT): {$(VPATH)}internal/value.h
+time.$(OBJEXT): {$(VPATH)}internal/value_type.h
+time.$(OBJEXT): {$(VPATH)}internal/variable.h
+time.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+time.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
time.$(OBJEXT): {$(VPATH)}missing.h
time.$(OBJEXT): {$(VPATH)}onigmo.h
time.$(OBJEXT): {$(VPATH)}oniguruma.h
+time.$(OBJEXT): {$(VPATH)}ruby_assert.h
time.$(OBJEXT): {$(VPATH)}st.h
time.$(OBJEXT): {$(VPATH)}subst.h
time.$(OBJEXT): {$(VPATH)}time.c
time.$(OBJEXT): {$(VPATH)}timev.h
+transcode.$(OBJEXT): $(hdrdir)/ruby.h
transcode.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-transcode.$(OBJEXT): $(top_srcdir)/include/ruby.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/array.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/class.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/gc.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/inits.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/object.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/serial.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/string.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/transcode.h
+transcode.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+transcode.$(OBJEXT): {$(VPATH)}assert.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+transcode.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
transcode.$(OBJEXT): {$(VPATH)}config.h
transcode.$(OBJEXT): {$(VPATH)}defines.h
transcode.$(OBJEXT): {$(VPATH)}encoding.h
+transcode.$(OBJEXT): {$(VPATH)}id.h
+transcode.$(OBJEXT): {$(VPATH)}id_table.h
transcode.$(OBJEXT): {$(VPATH)}intern.h
transcode.$(OBJEXT): {$(VPATH)}internal.h
-transcode.$(OBJEXT): {$(VPATH)}io.h
+transcode.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+transcode.$(OBJEXT): {$(VPATH)}internal/assume.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+transcode.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+transcode.$(OBJEXT): {$(VPATH)}internal/cast.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+transcode.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+transcode.$(OBJEXT): {$(VPATH)}internal/config.h
+transcode.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+transcode.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+transcode.$(OBJEXT): {$(VPATH)}internal/ctype.h
+transcode.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+transcode.$(OBJEXT): {$(VPATH)}internal/dosish.h
+transcode.$(OBJEXT): {$(VPATH)}internal/error.h
+transcode.$(OBJEXT): {$(VPATH)}internal/eval.h
+transcode.$(OBJEXT): {$(VPATH)}internal/event.h
+transcode.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+transcode.$(OBJEXT): {$(VPATH)}internal/gc.h
+transcode.$(OBJEXT): {$(VPATH)}internal/glob.h
+transcode.$(OBJEXT): {$(VPATH)}internal/globals.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+transcode.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+transcode.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+transcode.$(OBJEXT): {$(VPATH)}internal/iterator.h
+transcode.$(OBJEXT): {$(VPATH)}internal/memory.h
+transcode.$(OBJEXT): {$(VPATH)}internal/method.h
+transcode.$(OBJEXT): {$(VPATH)}internal/module.h
+transcode.$(OBJEXT): {$(VPATH)}internal/newobj.h
+transcode.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+transcode.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+transcode.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+transcode.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+transcode.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+transcode.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+transcode.$(OBJEXT): {$(VPATH)}internal/symbol.h
+transcode.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+transcode.$(OBJEXT): {$(VPATH)}internal/value.h
+transcode.$(OBJEXT): {$(VPATH)}internal/value_type.h
+transcode.$(OBJEXT): {$(VPATH)}internal/variable.h
+transcode.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+transcode.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
transcode.$(OBJEXT): {$(VPATH)}missing.h
transcode.$(OBJEXT): {$(VPATH)}onigmo.h
transcode.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -2683,17 +14607,364 @@ transcode.$(OBJEXT): {$(VPATH)}st.h
transcode.$(OBJEXT): {$(VPATH)}subst.h
transcode.$(OBJEXT): {$(VPATH)}transcode.c
transcode.$(OBJEXT): {$(VPATH)}transcode_data.h
+transient_heap.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+transient_heap.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+transient_heap.$(OBJEXT): $(CCAN_DIR)/list/list.h
+transient_heap.$(OBJEXT): $(CCAN_DIR)/str/str.h
+transient_heap.$(OBJEXT): $(hdrdir)/ruby.h
+transient_heap.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/array.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/gc.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/hash.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/serial.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/struct.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/variable.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/vm.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+transient_heap.$(OBJEXT): {$(VPATH)}assert.h
+transient_heap.$(OBJEXT): {$(VPATH)}atomic.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+transient_heap.$(OBJEXT): {$(VPATH)}config.h
+transient_heap.$(OBJEXT): {$(VPATH)}constant.h
+transient_heap.$(OBJEXT): {$(VPATH)}debug.h
+transient_heap.$(OBJEXT): {$(VPATH)}debug_counter.h
+transient_heap.$(OBJEXT): {$(VPATH)}defines.h
+transient_heap.$(OBJEXT): {$(VPATH)}gc.h
+transient_heap.$(OBJEXT): {$(VPATH)}id.h
+transient_heap.$(OBJEXT): {$(VPATH)}id_table.h
+transient_heap.$(OBJEXT): {$(VPATH)}intern.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/assume.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/cast.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/config.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/ctype.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/dosish.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/error.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/eval.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/event.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/gc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/glob.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/globals.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/iterator.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/memory.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/method.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/module.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/newobj.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/symbol.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/value.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/value_type.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/variable.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+transient_heap.$(OBJEXT): {$(VPATH)}method.h
+transient_heap.$(OBJEXT): {$(VPATH)}missing.h
+transient_heap.$(OBJEXT): {$(VPATH)}node.h
+transient_heap.$(OBJEXT): {$(VPATH)}ruby_assert.h
+transient_heap.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+transient_heap.$(OBJEXT): {$(VPATH)}st.h
+transient_heap.$(OBJEXT): {$(VPATH)}subst.h
+transient_heap.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+transient_heap.$(OBJEXT): {$(VPATH)}thread_native.h
+transient_heap.$(OBJEXT): {$(VPATH)}transient_heap.c
+transient_heap.$(OBJEXT): {$(VPATH)}transient_heap.h
+transient_heap.$(OBJEXT): {$(VPATH)}vm_core.h
+transient_heap.$(OBJEXT): {$(VPATH)}vm_debug.h
+transient_heap.$(OBJEXT): {$(VPATH)}vm_opts.h
+transient_heap.$(OBJEXT): {$(VPATH)}vm_sync.h
+util.$(OBJEXT): $(hdrdir)/ruby.h
util.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-util.$(OBJEXT): $(top_srcdir)/include/ruby.h
+util.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+util.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+util.$(OBJEXT): $(top_srcdir)/internal/util.h
+util.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+util.$(OBJEXT): {$(VPATH)}assert.h
+util.$(OBJEXT): {$(VPATH)}atomic.h
+util.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+util.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+util.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+util.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+util.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+util.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+util.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+util.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+util.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
util.$(OBJEXT): {$(VPATH)}config.h
util.$(OBJEXT): {$(VPATH)}defines.h
-util.$(OBJEXT): {$(VPATH)}encoding.h
+util.$(OBJEXT): {$(VPATH)}dtoa.c
util.$(OBJEXT): {$(VPATH)}intern.h
util.$(OBJEXT): {$(VPATH)}internal.h
-util.$(OBJEXT): {$(VPATH)}io.h
+util.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+util.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+util.$(OBJEXT): {$(VPATH)}internal/assume.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+util.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+util.$(OBJEXT): {$(VPATH)}internal/cast.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+util.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+util.$(OBJEXT): {$(VPATH)}internal/config.h
+util.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+util.$(OBJEXT): {$(VPATH)}internal/core.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+util.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+util.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+util.$(OBJEXT): {$(VPATH)}internal/ctype.h
+util.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+util.$(OBJEXT): {$(VPATH)}internal/dosish.h
+util.$(OBJEXT): {$(VPATH)}internal/error.h
+util.$(OBJEXT): {$(VPATH)}internal/eval.h
+util.$(OBJEXT): {$(VPATH)}internal/event.h
+util.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+util.$(OBJEXT): {$(VPATH)}internal/gc.h
+util.$(OBJEXT): {$(VPATH)}internal/glob.h
+util.$(OBJEXT): {$(VPATH)}internal/globals.h
+util.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+util.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+util.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+util.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+util.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+util.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+util.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+util.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+util.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+util.$(OBJEXT): {$(VPATH)}internal/iterator.h
+util.$(OBJEXT): {$(VPATH)}internal/memory.h
+util.$(OBJEXT): {$(VPATH)}internal/method.h
+util.$(OBJEXT): {$(VPATH)}internal/module.h
+util.$(OBJEXT): {$(VPATH)}internal/newobj.h
+util.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+util.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+util.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+util.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+util.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+util.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+util.$(OBJEXT): {$(VPATH)}internal/symbol.h
+util.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+util.$(OBJEXT): {$(VPATH)}internal/value.h
+util.$(OBJEXT): {$(VPATH)}internal/value_type.h
+util.$(OBJEXT): {$(VPATH)}internal/variable.h
+util.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+util.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
util.$(OBJEXT): {$(VPATH)}missing.h
-util.$(OBJEXT): {$(VPATH)}onigmo.h
-util.$(OBJEXT): {$(VPATH)}oniguruma.h
+util.$(OBJEXT): {$(VPATH)}ruby_atomic.h
util.$(OBJEXT): {$(VPATH)}st.h
util.$(OBJEXT): {$(VPATH)}subst.h
util.$(OBJEXT): {$(VPATH)}util.c
@@ -2702,8 +14973,37 @@ variable.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
variable.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
variable.$(OBJEXT): $(CCAN_DIR)/list/list.h
variable.$(OBJEXT): $(CCAN_DIR)/str/str.h
+variable.$(OBJEXT): $(hdrdir)/ruby.h
variable.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-variable.$(OBJEXT): $(top_srcdir)/include/ruby.h
+variable.$(OBJEXT): $(top_srcdir)/internal/array.h
+variable.$(OBJEXT): $(top_srcdir)/internal/class.h
+variable.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+variable.$(OBJEXT): $(top_srcdir)/internal/error.h
+variable.$(OBJEXT): $(top_srcdir)/internal/eval.h
+variable.$(OBJEXT): $(top_srcdir)/internal/gc.h
+variable.$(OBJEXT): $(top_srcdir)/internal/hash.h
+variable.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+variable.$(OBJEXT): $(top_srcdir)/internal/object.h
+variable.$(OBJEXT): $(top_srcdir)/internal/re.h
+variable.$(OBJEXT): $(top_srcdir)/internal/serial.h
+variable.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+variable.$(OBJEXT): $(top_srcdir)/internal/string.h
+variable.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+variable.$(OBJEXT): $(top_srcdir)/internal/thread.h
+variable.$(OBJEXT): $(top_srcdir)/internal/variable.h
+variable.$(OBJEXT): $(top_srcdir)/internal/vm.h
+variable.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+variable.$(OBJEXT): {$(VPATH)}assert.h
+variable.$(OBJEXT): {$(VPATH)}atomic.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+variable.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
variable.$(OBJEXT): {$(VPATH)}config.h
variable.$(OBJEXT): {$(VPATH)}constant.h
variable.$(OBJEXT): {$(VPATH)}debug_counter.h
@@ -2713,35 +15013,406 @@ variable.$(OBJEXT): {$(VPATH)}id.h
variable.$(OBJEXT): {$(VPATH)}id_table.h
variable.$(OBJEXT): {$(VPATH)}intern.h
variable.$(OBJEXT): {$(VPATH)}internal.h
-variable.$(OBJEXT): {$(VPATH)}io.h
+variable.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+variable.$(OBJEXT): {$(VPATH)}internal/assume.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+variable.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+variable.$(OBJEXT): {$(VPATH)}internal/cast.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+variable.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+variable.$(OBJEXT): {$(VPATH)}internal/config.h
+variable.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+variable.$(OBJEXT): {$(VPATH)}internal/core.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+variable.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+variable.$(OBJEXT): {$(VPATH)}internal/ctype.h
+variable.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+variable.$(OBJEXT): {$(VPATH)}internal/dosish.h
+variable.$(OBJEXT): {$(VPATH)}internal/error.h
+variable.$(OBJEXT): {$(VPATH)}internal/eval.h
+variable.$(OBJEXT): {$(VPATH)}internal/event.h
+variable.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+variable.$(OBJEXT): {$(VPATH)}internal/gc.h
+variable.$(OBJEXT): {$(VPATH)}internal/glob.h
+variable.$(OBJEXT): {$(VPATH)}internal/globals.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+variable.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+variable.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+variable.$(OBJEXT): {$(VPATH)}internal/iterator.h
+variable.$(OBJEXT): {$(VPATH)}internal/memory.h
+variable.$(OBJEXT): {$(VPATH)}internal/method.h
+variable.$(OBJEXT): {$(VPATH)}internal/module.h
+variable.$(OBJEXT): {$(VPATH)}internal/newobj.h
+variable.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+variable.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+variable.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+variable.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+variable.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+variable.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+variable.$(OBJEXT): {$(VPATH)}internal/symbol.h
+variable.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+variable.$(OBJEXT): {$(VPATH)}internal/value.h
+variable.$(OBJEXT): {$(VPATH)}internal/value_type.h
+variable.$(OBJEXT): {$(VPATH)}internal/variable.h
+variable.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+variable.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+variable.$(OBJEXT): {$(VPATH)}method.h
variable.$(OBJEXT): {$(VPATH)}missing.h
+variable.$(OBJEXT): {$(VPATH)}node.h
variable.$(OBJEXT): {$(VPATH)}onigmo.h
variable.$(OBJEXT): {$(VPATH)}oniguruma.h
+variable.$(OBJEXT): {$(VPATH)}ractor.h
+variable.$(OBJEXT): {$(VPATH)}ractor_core.h
+variable.$(OBJEXT): {$(VPATH)}ruby_assert.h
+variable.$(OBJEXT): {$(VPATH)}ruby_atomic.h
variable.$(OBJEXT): {$(VPATH)}st.h
variable.$(OBJEXT): {$(VPATH)}subst.h
+variable.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+variable.$(OBJEXT): {$(VPATH)}thread_native.h
+variable.$(OBJEXT): {$(VPATH)}transient_heap.h
variable.$(OBJEXT): {$(VPATH)}util.h
variable.$(OBJEXT): {$(VPATH)}variable.c
+variable.$(OBJEXT): {$(VPATH)}variable.h
+variable.$(OBJEXT): {$(VPATH)}vm_core.h
+variable.$(OBJEXT): {$(VPATH)}vm_debug.h
+variable.$(OBJEXT): {$(VPATH)}vm_opts.h
+variable.$(OBJEXT): {$(VPATH)}vm_sync.h
+version.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+version.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+version.$(OBJEXT): $(CCAN_DIR)/list/list.h
+version.$(OBJEXT): $(CCAN_DIR)/str/str.h
+version.$(OBJEXT): $(hdrdir)/ruby.h
version.$(OBJEXT): $(hdrdir)/ruby/ruby.h
version.$(OBJEXT): $(hdrdir)/ruby/version.h
+version.$(OBJEXT): $(top_srcdir)/internal/array.h
+version.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+version.$(OBJEXT): $(top_srcdir)/internal/gc.h
+version.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+version.$(OBJEXT): $(top_srcdir)/internal/serial.h
+version.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+version.$(OBJEXT): $(top_srcdir)/internal/vm.h
+version.$(OBJEXT): $(top_srcdir)/internal/warnings.h
version.$(OBJEXT): $(top_srcdir)/revision.h
version.$(OBJEXT): $(top_srcdir)/version.h
+version.$(OBJEXT): {$(VPATH)}assert.h
+version.$(OBJEXT): {$(VPATH)}atomic.h
+version.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+version.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+version.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+version.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+version.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+version.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+version.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+version.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+version.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
version.$(OBJEXT): {$(VPATH)}config.h
+version.$(OBJEXT): {$(VPATH)}debug_counter.h
version.$(OBJEXT): {$(VPATH)}defines.h
+version.$(OBJEXT): {$(VPATH)}id.h
version.$(OBJEXT): {$(VPATH)}intern.h
+version.$(OBJEXT): {$(VPATH)}internal.h
+version.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+version.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+version.$(OBJEXT): {$(VPATH)}internal/assume.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+version.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+version.$(OBJEXT): {$(VPATH)}internal/cast.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+version.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+version.$(OBJEXT): {$(VPATH)}internal/config.h
+version.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+version.$(OBJEXT): {$(VPATH)}internal/core.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+version.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+version.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+version.$(OBJEXT): {$(VPATH)}internal/ctype.h
+version.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+version.$(OBJEXT): {$(VPATH)}internal/dosish.h
+version.$(OBJEXT): {$(VPATH)}internal/error.h
+version.$(OBJEXT): {$(VPATH)}internal/eval.h
+version.$(OBJEXT): {$(VPATH)}internal/event.h
+version.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+version.$(OBJEXT): {$(VPATH)}internal/gc.h
+version.$(OBJEXT): {$(VPATH)}internal/glob.h
+version.$(OBJEXT): {$(VPATH)}internal/globals.h
+version.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+version.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+version.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+version.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+version.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+version.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+version.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+version.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+version.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+version.$(OBJEXT): {$(VPATH)}internal/iterator.h
+version.$(OBJEXT): {$(VPATH)}internal/memory.h
+version.$(OBJEXT): {$(VPATH)}internal/method.h
+version.$(OBJEXT): {$(VPATH)}internal/module.h
+version.$(OBJEXT): {$(VPATH)}internal/newobj.h
+version.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+version.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+version.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+version.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+version.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+version.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+version.$(OBJEXT): {$(VPATH)}internal/symbol.h
+version.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+version.$(OBJEXT): {$(VPATH)}internal/value.h
+version.$(OBJEXT): {$(VPATH)}internal/value_type.h
+version.$(OBJEXT): {$(VPATH)}internal/variable.h
+version.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+version.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+version.$(OBJEXT): {$(VPATH)}method.h
version.$(OBJEXT): {$(VPATH)}missing.h
+version.$(OBJEXT): {$(VPATH)}mjit.h
+version.$(OBJEXT): {$(VPATH)}node.h
+version.$(OBJEXT): {$(VPATH)}ruby_assert.h
+version.$(OBJEXT): {$(VPATH)}ruby_atomic.h
version.$(OBJEXT): {$(VPATH)}st.h
version.$(OBJEXT): {$(VPATH)}subst.h
+version.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+version.$(OBJEXT): {$(VPATH)}thread_native.h
version.$(OBJEXT): {$(VPATH)}version.c
+version.$(OBJEXT): {$(VPATH)}vm_core.h
+version.$(OBJEXT): {$(VPATH)}vm_opts.h
vm.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
vm.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
vm.$(OBJEXT): $(CCAN_DIR)/list/list.h
vm.$(OBJEXT): $(CCAN_DIR)/str/str.h
+vm.$(OBJEXT): $(hdrdir)/ruby.h
vm.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-vm.$(OBJEXT): $(top_srcdir)/include/ruby.h
+vm.$(OBJEXT): $(top_srcdir)/internal/array.h
+vm.$(OBJEXT): $(top_srcdir)/internal/bignum.h
+vm.$(OBJEXT): $(top_srcdir)/internal/bits.h
+vm.$(OBJEXT): $(top_srcdir)/internal/class.h
+vm.$(OBJEXT): $(top_srcdir)/internal/compar.h
+vm.$(OBJEXT): $(top_srcdir)/internal/compile.h
+vm.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+vm.$(OBJEXT): $(top_srcdir)/internal/cont.h
+vm.$(OBJEXT): $(top_srcdir)/internal/error.h
+vm.$(OBJEXT): $(top_srcdir)/internal/eval.h
+vm.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
+vm.$(OBJEXT): $(top_srcdir)/internal/gc.h
+vm.$(OBJEXT): $(top_srcdir)/internal/hash.h
+vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+vm.$(OBJEXT): $(top_srcdir)/internal/inits.h
+vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h
+vm.$(OBJEXT): $(top_srcdir)/internal/object.h
+vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
+vm.$(OBJEXT): $(top_srcdir)/internal/proc.h
+vm.$(OBJEXT): $(top_srcdir)/internal/random.h
+vm.$(OBJEXT): $(top_srcdir)/internal/re.h
+vm.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+vm.$(OBJEXT): $(top_srcdir)/internal/serial.h
+vm.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+vm.$(OBJEXT): $(top_srcdir)/internal/string.h
+vm.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+vm.$(OBJEXT): $(top_srcdir)/internal/variable.h
+vm.$(OBJEXT): $(top_srcdir)/internal/vm.h
+vm.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+vm.$(OBJEXT): {$(VPATH)}assert.h
+vm.$(OBJEXT): {$(VPATH)}atomic.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+vm.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+vm.$(OBJEXT): {$(VPATH)}builtin.h
vm.$(OBJEXT): {$(VPATH)}config.h
vm.$(OBJEXT): {$(VPATH)}constant.h
vm.$(OBJEXT): {$(VPATH)}debug_counter.h
vm.$(OBJEXT): {$(VPATH)}defines.h
+vm.$(OBJEXT): {$(VPATH)}defs/opt_operand.def
vm.$(OBJEXT): {$(VPATH)}encoding.h
vm.$(OBJEXT): {$(VPATH)}eval_intern.h
vm.$(OBJEXT): {$(VPATH)}gc.h
@@ -2749,29 +15420,174 @@ vm.$(OBJEXT): {$(VPATH)}id.h
vm.$(OBJEXT): {$(VPATH)}id_table.h
vm.$(OBJEXT): {$(VPATH)}insns.def
vm.$(OBJEXT): {$(VPATH)}insns.inc
+vm.$(OBJEXT): {$(VPATH)}insns_info.inc
vm.$(OBJEXT): {$(VPATH)}intern.h
vm.$(OBJEXT): {$(VPATH)}internal.h
-vm.$(OBJEXT): {$(VPATH)}io.h
+vm.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+vm.$(OBJEXT): {$(VPATH)}internal/assume.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+vm.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+vm.$(OBJEXT): {$(VPATH)}internal/cast.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+vm.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+vm.$(OBJEXT): {$(VPATH)}internal/config.h
+vm.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+vm.$(OBJEXT): {$(VPATH)}internal/core.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+vm.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+vm.$(OBJEXT): {$(VPATH)}internal/ctype.h
+vm.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+vm.$(OBJEXT): {$(VPATH)}internal/dosish.h
+vm.$(OBJEXT): {$(VPATH)}internal/error.h
+vm.$(OBJEXT): {$(VPATH)}internal/eval.h
+vm.$(OBJEXT): {$(VPATH)}internal/event.h
+vm.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+vm.$(OBJEXT): {$(VPATH)}internal/gc.h
+vm.$(OBJEXT): {$(VPATH)}internal/glob.h
+vm.$(OBJEXT): {$(VPATH)}internal/globals.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+vm.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+vm.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+vm.$(OBJEXT): {$(VPATH)}internal/iterator.h
+vm.$(OBJEXT): {$(VPATH)}internal/memory.h
+vm.$(OBJEXT): {$(VPATH)}internal/method.h
+vm.$(OBJEXT): {$(VPATH)}internal/module.h
+vm.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+vm.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+vm.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+vm.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+vm.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+vm.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+vm.$(OBJEXT): {$(VPATH)}internal/symbol.h
+vm.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+vm.$(OBJEXT): {$(VPATH)}internal/value.h
+vm.$(OBJEXT): {$(VPATH)}internal/value_type.h
+vm.$(OBJEXT): {$(VPATH)}internal/variable.h
+vm.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+vm.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
vm.$(OBJEXT): {$(VPATH)}iseq.h
vm.$(OBJEXT): {$(VPATH)}method.h
vm.$(OBJEXT): {$(VPATH)}missing.h
+vm.$(OBJEXT): {$(VPATH)}mjit.h
vm.$(OBJEXT): {$(VPATH)}node.h
vm.$(OBJEXT): {$(VPATH)}onigmo.h
vm.$(OBJEXT): {$(VPATH)}oniguruma.h
vm.$(OBJEXT): {$(VPATH)}probes.dmyh
vm.$(OBJEXT): {$(VPATH)}probes.h
vm.$(OBJEXT): {$(VPATH)}probes_helper.h
+vm.$(OBJEXT): {$(VPATH)}ractor.h
+vm.$(OBJEXT): {$(VPATH)}ractor_core.h
vm.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm.$(OBJEXT): {$(VPATH)}ruby_atomic.h
vm.$(OBJEXT): {$(VPATH)}st.h
vm.$(OBJEXT): {$(VPATH)}subst.h
vm.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
vm.$(OBJEXT): {$(VPATH)}thread_native.h
+vm.$(OBJEXT): {$(VPATH)}variable.h
vm.$(OBJEXT): {$(VPATH)}vm.c
vm.$(OBJEXT): {$(VPATH)}vm.h
vm.$(OBJEXT): {$(VPATH)}vm.inc
vm.$(OBJEXT): {$(VPATH)}vm_args.c
vm.$(OBJEXT): {$(VPATH)}vm_call_iseq_optimized.inc
+vm.$(OBJEXT): {$(VPATH)}vm_callinfo.h
vm.$(OBJEXT): {$(VPATH)}vm_core.h
vm.$(OBJEXT): {$(VPATH)}vm_debug.h
vm.$(OBJEXT): {$(VPATH)}vm_eval.c
@@ -2781,13 +15597,33 @@ vm.$(OBJEXT): {$(VPATH)}vm_insnhelper.c
vm.$(OBJEXT): {$(VPATH)}vm_insnhelper.h
vm.$(OBJEXT): {$(VPATH)}vm_method.c
vm.$(OBJEXT): {$(VPATH)}vm_opts.h
+vm.$(OBJEXT): {$(VPATH)}vm_sync.h
vm.$(OBJEXT): {$(VPATH)}vmtc.inc
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/list/list.h
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/str/str.h
+vm_backtrace.$(OBJEXT): $(hdrdir)/ruby.h
vm_backtrace.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/include/ruby.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/array.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/vm.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}assert.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}atomic.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
vm_backtrace.$(OBJEXT): {$(VPATH)}config.h
vm_backtrace.$(OBJEXT): {$(VPATH)}debug.h
vm_backtrace.$(OBJEXT): {$(VPATH)}defines.h
@@ -2796,7 +15632,146 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}eval_intern.h
vm_backtrace.$(OBJEXT): {$(VPATH)}id.h
vm_backtrace.$(OBJEXT): {$(VPATH)}intern.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}io.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/assume.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/cast.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/config.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/ctype.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/dosish.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/error.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/eval.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/event.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/gc.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/glob.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/globals.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/iterator.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/memory.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/method.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/module.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/symbol.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/value.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/value_type.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/variable.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
vm_backtrace.$(OBJEXT): {$(VPATH)}iseq.h
vm_backtrace.$(OBJEXT): {$(VPATH)}method.h
vm_backtrace.$(OBJEXT): {$(VPATH)}missing.h
@@ -2811,28 +15786,189 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
vm_backtrace.$(OBJEXT): {$(VPATH)}thread_native.h
vm_backtrace.$(OBJEXT): {$(VPATH)}vm_backtrace.c
vm_backtrace.$(OBJEXT): {$(VPATH)}vm_core.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}vm_debug.h
vm_backtrace.$(OBJEXT): {$(VPATH)}vm_opts.h
vm_dump.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
vm_dump.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
vm_dump.$(OBJEXT): $(CCAN_DIR)/list/list.h
vm_dump.$(OBJEXT): $(CCAN_DIR)/str/str.h
+vm_dump.$(OBJEXT): $(hdrdir)/ruby.h
vm_dump.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-vm_dump.$(OBJEXT): $(top_srcdir)/include/ruby.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/array.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/vm.h
+vm_dump.$(OBJEXT): $(top_srcdir)/internal/warnings.h
vm_dump.$(OBJEXT): {$(VPATH)}addr2line.h
+vm_dump.$(OBJEXT): {$(VPATH)}assert.h
+vm_dump.$(OBJEXT): {$(VPATH)}atomic.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+vm_dump.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
vm_dump.$(OBJEXT): {$(VPATH)}config.h
+vm_dump.$(OBJEXT): {$(VPATH)}constant.h
vm_dump.$(OBJEXT): {$(VPATH)}defines.h
-vm_dump.$(OBJEXT): {$(VPATH)}encoding.h
+vm_dump.$(OBJEXT): {$(VPATH)}gc.h
vm_dump.$(OBJEXT): {$(VPATH)}id.h
+vm_dump.$(OBJEXT): {$(VPATH)}id_table.h
vm_dump.$(OBJEXT): {$(VPATH)}intern.h
vm_dump.$(OBJEXT): {$(VPATH)}internal.h
-vm_dump.$(OBJEXT): {$(VPATH)}io.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/assume.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/cast.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/config.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/ctype.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/dosish.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/error.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/eval.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/event.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/gc.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/glob.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/globals.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/iterator.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/memory.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/method.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/module.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/symbol.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/value.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/value_type.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/variable.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
vm_dump.$(OBJEXT): {$(VPATH)}iseq.h
vm_dump.$(OBJEXT): {$(VPATH)}method.h
vm_dump.$(OBJEXT): {$(VPATH)}missing.h
vm_dump.$(OBJEXT): {$(VPATH)}node.h
-vm_dump.$(OBJEXT): {$(VPATH)}onigmo.h
-vm_dump.$(OBJEXT): {$(VPATH)}oniguruma.h
+vm_dump.$(OBJEXT): {$(VPATH)}procstat_vm.c
+vm_dump.$(OBJEXT): {$(VPATH)}ractor.h
+vm_dump.$(OBJEXT): {$(VPATH)}ractor_core.h
vm_dump.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm_dump.$(OBJEXT): {$(VPATH)}ruby_atomic.h
vm_dump.$(OBJEXT): {$(VPATH)}st.h
@@ -2843,34 +15979,398 @@ vm_dump.$(OBJEXT): {$(VPATH)}vm_core.h
vm_dump.$(OBJEXT): {$(VPATH)}vm_debug.h
vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c
vm_dump.$(OBJEXT): {$(VPATH)}vm_opts.h
+vm_sync.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+vm_sync.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+vm_sync.$(OBJEXT): $(CCAN_DIR)/list/list.h
+vm_sync.$(OBJEXT): $(CCAN_DIR)/str/str.h
+vm_sync.$(OBJEXT): $(hdrdir)/ruby.h
+vm_sync.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/array.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/gc.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/serial.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/vm.h
+vm_sync.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+vm_sync.$(OBJEXT): {$(VPATH)}addr2line.h
+vm_sync.$(OBJEXT): {$(VPATH)}assert.h
+vm_sync.$(OBJEXT): {$(VPATH)}atomic.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+vm_sync.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+vm_sync.$(OBJEXT): {$(VPATH)}config.h
+vm_sync.$(OBJEXT): {$(VPATH)}constant.h
+vm_sync.$(OBJEXT): {$(VPATH)}debug_counter.h
+vm_sync.$(OBJEXT): {$(VPATH)}defines.h
+vm_sync.$(OBJEXT): {$(VPATH)}gc.h
+vm_sync.$(OBJEXT): {$(VPATH)}id.h
+vm_sync.$(OBJEXT): {$(VPATH)}id_table.h
+vm_sync.$(OBJEXT): {$(VPATH)}intern.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/array.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/assume.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/cast.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/compilers.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/config.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/ctype.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/dosish.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/error.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/eval.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/event.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/gc.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/glob.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/globals.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/imemo.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/iterator.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/memory.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/method.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/module.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/serial.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/symbol.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/value.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/value_type.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/variable.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/vm.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/warnings.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+vm_sync.$(OBJEXT): {$(VPATH)}iseq.h
+vm_sync.$(OBJEXT): {$(VPATH)}method.h
+vm_sync.$(OBJEXT): {$(VPATH)}missing.h
+vm_sync.$(OBJEXT): {$(VPATH)}node.h
+vm_sync.$(OBJEXT): {$(VPATH)}procstat_vm.c
+vm_sync.$(OBJEXT): {$(VPATH)}ractor.h
+vm_sync.$(OBJEXT): {$(VPATH)}ractor_core.h
+vm_sync.$(OBJEXT): {$(VPATH)}ruby_assert.h
+vm_sync.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+vm_sync.$(OBJEXT): {$(VPATH)}st.h
+vm_sync.$(OBJEXT): {$(VPATH)}subst.h
+vm_sync.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+vm_sync.$(OBJEXT): {$(VPATH)}thread_native.h
+vm_sync.$(OBJEXT): {$(VPATH)}vm_core.h
+vm_sync.$(OBJEXT): {$(VPATH)}vm_debug.h
+vm_sync.$(OBJEXT): {$(VPATH)}vm_opts.h
+vm_sync.$(OBJEXT): {$(VPATH)}vm_sync.c
+vm_sync.$(OBJEXT): {$(VPATH)}vm_sync.h
vm_trace.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
vm_trace.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
vm_trace.$(OBJEXT): $(CCAN_DIR)/list/list.h
vm_trace.$(OBJEXT): $(CCAN_DIR)/str/str.h
+vm_trace.$(OBJEXT): $(hdrdir)/ruby.h
vm_trace.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-vm_trace.$(OBJEXT): $(top_srcdir)/include/ruby.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/array.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/gc.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/hash.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/symbol.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/vm.h
+vm_trace.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+vm_trace.$(OBJEXT): {$(VPATH)}assert.h
+vm_trace.$(OBJEXT): {$(VPATH)}atomic.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+vm_trace.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+vm_trace.$(OBJEXT): {$(VPATH)}builtin.h
vm_trace.$(OBJEXT): {$(VPATH)}config.h
vm_trace.$(OBJEXT): {$(VPATH)}debug.h
+vm_trace.$(OBJEXT): {$(VPATH)}debug_counter.h
vm_trace.$(OBJEXT): {$(VPATH)}defines.h
vm_trace.$(OBJEXT): {$(VPATH)}encoding.h
vm_trace.$(OBJEXT): {$(VPATH)}eval_intern.h
vm_trace.$(OBJEXT): {$(VPATH)}id.h
vm_trace.$(OBJEXT): {$(VPATH)}intern.h
vm_trace.$(OBJEXT): {$(VPATH)}internal.h
-vm_trace.$(OBJEXT): {$(VPATH)}io.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/assume.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/cast.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/config.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/ctype.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/dosish.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/error.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/eval.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/event.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/gc.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/glob.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/globals.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/iterator.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/memory.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/method.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/module.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/symbol.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/token_paste.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/value.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/value_type.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/variable.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+vm_trace.$(OBJEXT): {$(VPATH)}iseq.h
vm_trace.$(OBJEXT): {$(VPATH)}method.h
vm_trace.$(OBJEXT): {$(VPATH)}missing.h
+vm_trace.$(OBJEXT): {$(VPATH)}mjit.h
vm_trace.$(OBJEXT): {$(VPATH)}node.h
vm_trace.$(OBJEXT): {$(VPATH)}onigmo.h
vm_trace.$(OBJEXT): {$(VPATH)}oniguruma.h
+vm_trace.$(OBJEXT): {$(VPATH)}ractor.h
vm_trace.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm_trace.$(OBJEXT): {$(VPATH)}ruby_atomic.h
vm_trace.$(OBJEXT): {$(VPATH)}st.h
vm_trace.$(OBJEXT): {$(VPATH)}subst.h
vm_trace.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
vm_trace.$(OBJEXT): {$(VPATH)}thread_native.h
+vm_trace.$(OBJEXT): {$(VPATH)}trace_point.rbinc
vm_trace.$(OBJEXT): {$(VPATH)}vm_core.h
-vm_trace.$(OBJEXT): {$(VPATH)}vm_debug.h
vm_trace.$(OBJEXT): {$(VPATH)}vm_opts.h
vm_trace.$(OBJEXT): {$(VPATH)}vm_trace.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/compar.c b/compar.c
index 02529c9960..04d4ff8c70 100644
--- a/compar.c
+++ b/compar.c
@@ -9,8 +9,12 @@
**********************************************************************/
-#include "ruby/ruby.h"
#include "id.h"
+#include "internal.h"
+#include "internal/compar.h"
+#include "internal/error.h"
+#include "internal/vm.h"
+#include "ruby/ruby.h"
VALUE rb_mComparable;
@@ -95,7 +99,7 @@ cmpint(VALUE x, VALUE y)
* obj > other -> true or false
*
* Compares two objects based on the receiver's <code><=></code>
- * method, returning true if it returns 1.
+ * method, returning true if it returns a value greater than 0.
*/
static VALUE
@@ -110,7 +114,7 @@ cmp_gt(VALUE x, VALUE y)
* obj >= other -> true or false
*
* Compares two objects based on the receiver's <code><=></code>
- * method, returning true if it returns 0 or 1.
+ * method, returning true if it returns a value greater than or equal to 0.
*/
static VALUE
@@ -125,7 +129,7 @@ cmp_ge(VALUE x, VALUE y)
* obj < other -> true or false
*
* Compares two objects based on the receiver's <code><=></code>
- * method, returning true if it returns -1.
+ * method, returning true if it returns a value less than 0.
*/
static VALUE
@@ -140,7 +144,7 @@ cmp_lt(VALUE x, VALUE y)
* obj <= other -> true or false
*
* Compares two objects based on the receiver's <code><=></code>
- * method, returning true if it returns -1 or 0.
+ * method, returning true if it returns a value less than or equal to 0.
*/
static VALUE
@@ -154,9 +158,9 @@ cmp_le(VALUE x, VALUE y)
* call-seq:
* obj.between?(min, max) -> true or false
*
- * Returns <code>false</code> if <i>obj</i> <code><=></code>
- * <i>min</i> is less than zero or if <i>anObject</i> <code><=></code>
- * <i>max</i> is greater than zero, <code>true</code> otherwise.
+ * Returns <code>false</code> if _obj_ <code><=></code> _min_ is less
+ * than zero or if _obj_ <code><=></code> _max_ is greater than zero,
+ * <code>true</code> otherwise.
*
* 3.between?(1, 5) #=> true
* 6.between?(1, 5) #=> false
@@ -176,10 +180,12 @@ cmp_between(VALUE x, VALUE min, VALUE max)
/*
* call-seq:
* obj.clamp(min, max) -> obj
+ * obj.clamp(range) -> obj
*
- * Returns <i>min</i> if <i>obj</i> <code><=></code> <i>min</i> is less
- * than zero, <i>max</i> if <i>obj</i> <code><=></code> <i>max</i> is
- * greater than zero and <i>obj</i> otherwise.
+ * In <code>(min, max)</code> form, returns _min_ if _obj_
+ * <code><=></code> _min_ is less than zero, _max_ if _obj_
+ * <code><=></code> _max_ is greater than zero, and _obj_
+ * otherwise.
*
* 12.clamp(0, 100) #=> 12
* 523.clamp(0, 100) #=> 100
@@ -187,36 +193,76 @@ cmp_between(VALUE x, VALUE min, VALUE max)
*
* 'd'.clamp('a', 'f') #=> 'd'
* 'z'.clamp('a', 'f') #=> 'f'
+ *
+ * In <code>(range)</code> form, returns _range.begin_ if _obj_
+ * <code><=></code> _range.begin_ is less than zero, _range.end_
+ * if _obj_ <code><=></code> _range.end_ is greater than zero, and
+ * _obj_ otherwise.
+ *
+ * 12.clamp(0..100) #=> 12
+ * 523.clamp(0..100) #=> 100
+ * -3.123.clamp(0..100) #=> 0
+ *
+ * 'd'.clamp('a'..'f') #=> 'd'
+ * 'z'.clamp('a'..'f') #=> 'f'
+ *
+ * If _range.begin_ is +nil+, it is considered smaller than _obj_,
+ * and if _range.end_ is +nil+, it is considered greater than
+ * _obj_.
+ *
+ * -20.clamp(0..) #=> 0
+ * 523.clamp(..100) #=> 100
+ *
+ * When _range.end_ is excluded and not +nil+, an exception is
+ * raised.
+ *
+ * 100.clamp(0...100) # ArgumentError
*/
static VALUE
-cmp_clamp(VALUE x, VALUE min, VALUE max)
+cmp_clamp(int argc, VALUE *argv, VALUE x)
{
- int c;
-
- if (cmpint(min, max) > 0) {
+ VALUE min, max;
+ int c, excl = 0;
+
+ if (rb_scan_args(argc, argv, "11", &min, &max) == 1) {
+ VALUE range = min;
+ if (!rb_range_values(range, &min, &max, &excl)) {
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Range)",
+ rb_builtin_class_name(range));
+ }
+ if (!NIL_P(max)) {
+ if (excl) rb_raise(rb_eArgError, "cannot clamp with an exclusive range");
+ }
+ }
+ if (!NIL_P(min) && !NIL_P(max) && cmpint(min, max) > 0) {
rb_raise(rb_eArgError, "min argument must be smaller than max argument");
}
- c = cmpint(x, min);
- if (c == 0) return x;
- if (c < 0) return min;
- c = cmpint(x, max);
- if (c > 0) return max;
+ if (!NIL_P(min)) {
+ c = cmpint(x, min);
+ if (c == 0) return x;
+ if (c < 0) return min;
+ }
+ if (!NIL_P(max)) {
+ c = cmpint(x, max);
+ if (c > 0) return max;
+ }
return x;
}
/*
- * The <code>Comparable</code> mixin is used by classes whose objects
- * may be ordered. The class must define the <code><=></code> operator,
- * which compares the receiver against another object, returning -1, 0,
- * or +1 depending on whether the receiver is less than, equal to, or
- * greater than the other object. If the other object is not comparable
- * then the <code><=></code> operator should return nil.
- * <code>Comparable</code> uses
- * <code><=></code> to implement the conventional comparison operators
- * (<code><</code>, <code><=</code>, <code>==</code>, <code>>=</code>,
- * and <code>></code>) and the method <code>between?</code>.
+ * The Comparable mixin is used by classes whose objects may be
+ * ordered. The class must define the <code><=></code> operator,
+ * which compares the receiver against another object, returning a
+ * value less than 0, returning 0, or returning a value greater than 0,
+ * depending on whether the receiver is less than, equal to,
+ * or greater than the other object. If the other object is not
+ * comparable then the <code><=></code> operator should return +nil+.
+ * Comparable uses <code><=></code> to implement the conventional
+ * comparison operators (<code><</code>, <code><=</code>,
+ * <code>==</code>, <code>>=</code>, and <code>></code>) and the
+ * method <code>between?</code>.
*
* class SizeMatters
* include Comparable
@@ -248,9 +294,6 @@ cmp_clamp(VALUE x, VALUE min, VALUE max)
void
Init_Comparable(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
rb_mComparable = rb_define_module("Comparable");
rb_define_method(rb_mComparable, "==", cmp_equal, 1);
rb_define_method(rb_mComparable, ">", cmp_gt, 1);
@@ -258,5 +301,5 @@ Init_Comparable(void)
rb_define_method(rb_mComparable, "<", cmp_lt, 1);
rb_define_method(rb_mComparable, "<=", cmp_le, 1);
rb_define_method(rb_mComparable, "between?", cmp_between, 2);
- rb_define_method(rb_mComparable, "clamp", cmp_clamp, 2);
+ rb_define_method(rb_mComparable, "clamp", cmp_clamp, -1);
}
diff --git a/compile.c b/compile.c
index f92eabaa13..9844c145bc 100644
--- a/compile.c
+++ b/compile.c
@@ -9,37 +9,54 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/re.h"
-#include "encindex.h"
+#include "ruby/internal/config.h"
#include <math.h>
-#define USE_INSN_STACK_INCREASE 1
-#include "vm_core.h"
-#include "iseq.h"
-#include "insns.inc"
-#include "insns_info.inc"
-#include "id_table.h"
-#include "gc.h"
-
#ifdef HAVE_DLADDR
# include <dlfcn.h>
#endif
+#include "encindex.h"
+#include "gc.h"
+#include "id_table.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/compile.h"
+#include "internal/complex.h"
+#include "internal/encoding.h"
+#include "internal/error.h"
+#include "internal/hash.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/rational.h"
+#include "internal/re.h"
+#include "internal/symbol.h"
+#include "internal/thread.h"
+#include "internal/variable.h"
+#include "iseq.h"
+#include "ruby/re.h"
+#include "ruby/util.h"
+#include "vm_core.h"
+#include "vm_callinfo.h"
+#include "vm_debug.h"
+
+#include "builtin.h"
+#include "insns.inc"
+#include "insns_info.inc"
+
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
-#define ISEQ_TYPE_ONCE_GUARD ISEQ_TYPE_DEFINED_GUARD
-
#define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG))
#define FIXNUM_OR(n, i) ((n)|INT2FIX(i))
typedef struct iseq_link_element {
enum {
- ISEQ_ELEMENT_NONE,
+ ISEQ_ELEMENT_ANCHOR,
ISEQ_ELEMENT_LABEL,
ISEQ_ELEMENT_INSN,
- ISEQ_ELEMENT_ADJUST
+ ISEQ_ELEMENT_ADJUST,
+ ISEQ_ELEMENT_TRACE,
} type;
struct iseq_link_element *next;
struct iseq_link_element *prev;
@@ -72,10 +89,13 @@ typedef struct iseq_label_data {
typedef struct iseq_insn_data {
LINK_ELEMENT link;
enum ruby_vminsn_type insn_id;
- unsigned int line_no;
int operand_size;
int sc_state;
VALUE *operands;
+ struct {
+ int line_no;
+ rb_event_flag_t events;
+ } insn_info;
} INSN;
typedef struct iseq_adjust_data {
@@ -84,6 +104,12 @@ typedef struct iseq_adjust_data {
int line_no;
} ADJUST;
+typedef struct iseq_trace_data {
+ LINK_ELEMENT link;
+ rb_event_flag_t event;
+ long data;
+} TRACE;
+
struct ensure_range {
LABEL *begin;
LABEL *end;
@@ -91,11 +117,13 @@ struct ensure_range {
};
struct iseq_compile_data_ensure_node_stack {
- NODE *ensure_node;
+ const NODE *ensure_node;
struct iseq_compile_data_ensure_node_stack *prev;
struct ensure_range *erange;
};
+const ID rb_iseq_shared_exc_local_tbl[] = {idERROR_INFO};
+
/**
* debug function(macro) interface depend on CPDEBUG
* if it is less than 0, runtime option is in effect.
@@ -146,7 +174,7 @@ struct iseq_compile_data_ensure_node_stack {
#define debug_node_start(node) ((void) \
(compile_debug_print_indent(1) && \
- (ruby_debug_print_node(1, CPDEBUG, "", (NODE *)(node)), gl_node_level)), \
+ (ruby_debug_print_node(1, CPDEBUG, "", (const NODE *)(node)), gl_node_level)), \
gl_node_level++)
#define debug_node_end() gl_node_level --
@@ -163,6 +191,7 @@ struct iseq_compile_data_ensure_node_stack {
#endif
#if CPDEBUG > 1 || CPDEBUG < 0
+#undef printf
#define printf ruby_debug_printf
#define debugs if (compile_debug_print_indent(1)) ruby_debug_printf
#define debug_compile(msg, v) ((void)(compile_debug_print_indent(1) && fputs((msg), stderr)), (v))
@@ -191,18 +220,27 @@ struct iseq_compile_data_ensure_node_stack {
#define ADD_INSN(seq, line, insn) \
ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
-/* insert an instruction before prev */
-#define INSERT_BEFORE_INSN(prev, line, insn) \
- INSERT_ELEM_PREV(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
+/* insert an instruction before next */
+#define INSERT_BEFORE_INSN(next, line, insn) \
+ ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
+
+/* insert an instruction after prev */
+#define INSERT_AFTER_INSN(prev, line, insn) \
+ ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
/* add an instruction with some operands (1, 2, 3, 5) */
#define ADD_INSN1(seq, line, insn, op1) \
ADD_ELEM((seq), (LINK_ELEMENT *) \
new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
-/* insert an instruction with some operands (1, 2, 3, 5) before prev */
-#define INSERT_BEFORE_INSN1(prev, line, insn, op1) \
- INSERT_ELEM_PREV(&(prev)->link, (LINK_ELEMENT *) \
+/* insert an instruction with some operands (1, 2, 3, 5) before next */
+#define INSERT_BEFORE_INSN1(next, line, insn, op1) \
+ ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) \
+ new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
+
+/* insert an instruction with some operands (1, 2, 3, 5) after prev */
+#define INSERT_AFTER_INSN1(prev, line, insn, op1) \
+ ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) \
new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
#define LABEL_REF(label) ((label)->refcnt++)
@@ -240,73 +278,16 @@ struct iseq_compile_data_ensure_node_stack {
#define ADD_SEND_R(seq, line, id, argc, block, flag, keywords) \
ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords)))
-#define ADD_TRACE_LINE_COVERAGE(seq, line) \
- do { \
- if (ISEQ_COVERAGE(iseq) && \
- ISEQ_LINE_COVERAGE(iseq) && \
- (line) > 0 && \
- (line) != ISEQ_COMPILE_DATA(iseq)->last_coverable_line) { \
- RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), (line) - 1, INT2FIX(0)); \
- ISEQ_COMPILE_DATA(iseq)->last_coverable_line = (line); \
- ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(COVERAGE_INDEX_LINES)); \
- } \
- } while (0)
-#define DECL_BRANCH_BASE(branches, line, type) \
- do { \
- if (ISEQ_COVERAGE(iseq) && \
- ISEQ_BRANCH_COVERAGE(iseq) && \
- (line) > 0) { \
- VALUE structure = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 0); \
- branches = rb_ary_tmp_new(0); \
- rb_ary_push(structure, branches); \
- rb_ary_push(branches, ID2SYM(rb_intern(type))); \
- rb_ary_push(branches, INT2FIX(line)); \
- } \
- } while (0)
-#define ADD_TRACE_BRANCH_COVERAGE(seq, line, type, branches) \
- do { \
- if (ISEQ_COVERAGE(iseq) && \
- ISEQ_BRANCH_COVERAGE(iseq) && \
- (line) > 0) { \
- VALUE counters = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 1); \
- long counter_idx = RARRAY_LEN(counters); \
- rb_ary_push(counters, INT2FIX(0)); \
- rb_ary_push(branches, ID2SYM(rb_intern(type))); \
- rb_ary_push(branches, INT2FIX(line)); \
- rb_ary_push(branches, INT2FIX(counter_idx)); \
- ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(counter_idx * 16 + COVERAGE_INDEX_BRANCHES)); \
- } \
- } while (0)
-#define ADD_TRACE_METHOD_COVERAGE(seq, line, method_name) \
- do { \
- if (ISEQ_COVERAGE(iseq) && \
- ISEQ_METHOD_COVERAGE(iseq) && \
- (line) > 0) { \
- VALUE methods = ISEQ_METHOD_COVERAGE(iseq); \
- long counter_idx = RARRAY_LEN(methods) / 3; \
- rb_ary_push(methods, ID2SYM(method_name)); \
- rb_ary_push(methods, INT2FIX(line)); \
- rb_ary_push(methods, INT2FIX(0)); \
- ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(counter_idx * 16 + COVERAGE_INDEX_METHODS)); \
- } \
- } while (0)
-
-#define ADD_TRACE(seq, line, event) \
- do { \
- if (ISEQ_COMPILE_DATA(iseq)->option->trace_instruction) { \
- ADD_INSN1((seq), (line), trace, INT2FIX(event)); \
- } \
- } while (0)
-
-#define ADD_GETLOCAL(seq, line, idx, level) \
- do { \
- ADD_INSN2((seq), (line), getlocal, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(level)); \
- } while (0)
-
-#define ADD_SETLOCAL(seq, line, idx, level) \
- do { \
- ADD_INSN2((seq), (line), setlocal, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(level)); \
- } while (0)
+#define ADD_TRACE(seq, event) \
+ ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event), 0))
+#define ADD_TRACE_WITH_DATA(seq, event, data) \
+ ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event), (data)))
+
+static void iseq_add_getlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int idx, int level);
+static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int idx, int level);
+
+#define ADD_GETLOCAL(seq, line, idx, level) iseq_add_getlocal(iseq, (seq), (line), (idx), (level))
+#define ADD_SETLOCAL(seq, line, idx, level) iseq_add_setlocal(iseq, (seq), (line), (idx), (level))
/* add label */
#define ADD_LABEL(seq, label) \
@@ -328,8 +309,10 @@ struct iseq_compile_data_ensure_node_stack {
(VALUE)(ls) | 1, (VALUE)(le) | 1, \
(VALUE)(iseqv), (VALUE)(lc) | 1); \
LABEL_UNREMOVABLE(ls); \
- LABEL_UNREMOVABLE(le); \
- LABEL_UNREMOVABLE(lc); \
+ LABEL_REF(le); \
+ LABEL_REF(lc); \
+ if (NIL_P(ISEQ_COMPILE_DATA(iseq)->catch_table_ary)) \
+ RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, rb_ary_tmp_new(3)); \
rb_ary_push(ISEQ_COMPILE_DATA(iseq)->catch_table_ary, freeze_hide_obj(_e)); \
} while (0)
@@ -351,7 +334,7 @@ struct iseq_compile_data_ensure_node_stack {
#define COMPILE_RECV(anchor, desc, node) \
(private_recv_p(node) ? \
(ADD_INSN(anchor, nd_line(node), putself), VM_CALL_FCALL) : \
- (COMPILE(anchor, desc, node->nd_recv), 0))
+ COMPILE(anchor, desc, node->nd_recv) ? 0 : -1)
#define OPERAND_AT(insn, idx) \
(((INSN*)(insn))->operands[(idx)])
@@ -362,15 +345,18 @@ struct iseq_compile_data_ensure_node_stack {
#define IS_INSN(link) ((link)->type == ISEQ_ELEMENT_INSN)
#define IS_LABEL(link) ((link)->type == ISEQ_ELEMENT_LABEL)
#define IS_ADJUST(link) ((link)->type == ISEQ_ELEMENT_ADJUST)
+#define IS_TRACE(link) ((link)->type == ISEQ_ELEMENT_TRACE)
#define IS_INSN_ID(iobj, insn) (INSN_OF(iobj) == BIN(insn))
+#define IS_NEXT_INSN_ID(link, insn) \
+ ((link)->next && IS_INSN((link)->next) && IS_INSN_ID((link)->next, insn))
/* error */
#if CPDEBUG > 0
-NORETURN(static void append_compile_error(rb_iseq_t *iseq, int line, const char *fmt, ...));
+NORETURN(static void append_compile_error(const rb_iseq_t *iseq, int line, const char *fmt, ...));
#endif
static void
-append_compile_error(rb_iseq_t *iseq, int line, const char *fmt, ...)
+append_compile_error(const rb_iseq_t *iseq, int line, const char *fmt, ...)
{
VALUE err_info = ISEQ_COMPILE_DATA(iseq)->err_info;
VALUE file = rb_iseq_path(iseq);
@@ -387,7 +373,10 @@ append_compile_error(rb_iseq_t *iseq, int line, const char *fmt, ...)
else if (!err_info) {
RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->err_info, Qtrue);
}
- if (compile_debug) rb_exc_fatal(err);
+ if (compile_debug) {
+ if (SPECIAL_CONST_P(err)) err = rb_eSyntaxError;
+ rb_exc_fatal(err);
+ }
}
#if 0
@@ -409,7 +398,7 @@ compile_bug(rb_iseq_t *iseq, int line, const char *fmt, ...)
#define EXPECT_NODE(prefix, node, ndtype, errval) \
do { \
- NODE *error_node = (node); \
+ const NODE *error_node = (node); \
enum node_type error_type = nd_type(error_node); \
if (error_type != (ndtype)) { \
COMPILE_ERROR(ERROR_ARGS_AT(error_node) \
@@ -428,7 +417,7 @@ do { \
#define UNKNOWN_NODE(prefix, node, errval) \
do { \
- NODE *error_node = (node); \
+ const NODE *error_node = (node); \
COMPILE_ERROR(ERROR_ARGS_AT(error_node) prefix ": unknown node (%s)", \
ruby_node_name(nd_type(error_node))); \
return errval; \
@@ -438,12 +427,13 @@ do { \
#define COMPILE_NG 0
#define CHECK(sub) if (!(sub)) {BEFORE_RETURN;return COMPILE_NG;}
+#define NO_CHECK(sub) (void)(sub)
#define BEFORE_RETURN
/* leave name uninitialized so that compiler warn if INIT_ANCHOR is
* missing */
#define DECL_ANCHOR(name) \
- LINK_ANCHOR name[1] = {{{0,},}}
+ LINK_ANCHOR name[1] = {{{ISEQ_ELEMENT_ANCHOR,},}}
#define INIT_ANCHOR(name) \
(name->last = &name->anchor)
@@ -482,22 +472,26 @@ static int calc_sp_depth(int depth, INSN *iobj);
static INSN *new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int argc, ...);
static LABEL *new_label_body(rb_iseq_t *iseq, long line);
static ADJUST *new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line);
+static TRACE *new_trace_body(rb_iseq_t *iseq, rb_event_flag_t event, long data);
-static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, NODE *n, int);
+
+static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor, const NODE *n, int);
static int iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
+static int iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
static int iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl);
static int iseq_set_exception_local_table(rb_iseq_t *iseq);
-static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, NODE *node);
+static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, const NODE *const node);
static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
static int iseq_set_exception_table(rb_iseq_t *iseq);
static int iseq_set_optargs_table(rb_iseq_t *iseq);
-static int compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, VALUE needstr);
+static int compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, VALUE needstr);
+static int compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int method_call_keywords, int popped);
/*
* To make Array to LinkedList, use link_anchor
@@ -535,6 +529,44 @@ verify_list(ISEQ_ARG_DECLARE const char *info, LINK_ANCHOR *const anchor)
#define verify_list(info, anchor) verify_list(iseq, (info), (anchor))
#endif
+static void
+verify_call_cache(rb_iseq_t *iseq)
+{
+#if CPDEBUG
+ // fprintf(stderr, "ci_size:%d\t", iseq->body->ci_size); rp(iseq);
+
+ VALUE *original = rb_iseq_original_iseq(iseq);
+ size_t i = 0;
+ while (i < iseq->body->iseq_size) {
+ VALUE insn = original[i];
+ const char *types = insn_op_types(insn);
+
+ for (int j=0; types[j]; j++) {
+ if (types[j] == TS_CALLDATA) {
+ struct rb_call_data *cd = (struct rb_call_data *)original[i+j+1];
+ const struct rb_callinfo *ci = cd->ci;
+ const struct rb_callcache *cc = cd->cc;
+ if (cc != vm_cc_empty()) {
+ vm_ci_dump(ci);
+ rb_bug("call cache is not initialized by vm_cc_empty()");
+ }
+ }
+ }
+ i += insn_len(insn);
+ }
+
+ for (unsigned int i=0; i<iseq->body->ci_size; i++) {
+ struct rb_call_data *cd = &iseq->body->call_data[i];
+ const struct rb_callinfo *ci = cd->ci;
+ const struct rb_callcache *cc = cd->cc;
+ if (cc != NULL && cc != vm_cc_empty()) {
+ vm_ci_dump(ci);
+ rb_bug("call cache is not initialized by vm_cc_empty()");
+ }
+ }
+#endif
+}
+
/*
* elem1, elem2 => elem1, elem2, elem
*/
@@ -566,23 +598,97 @@ APPEND_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor, LINK_ELEMENT *before, LI
#endif
static int
-iseq_add_mark_object(const rb_iseq_t *iseq, VALUE v)
+branch_coverage_valid_p(rb_iseq_t *iseq, int first_line)
{
- if (!SPECIAL_CONST_P(v)) {
- rb_iseq_add_mark_object(iseq, v);
+ if (!ISEQ_COVERAGE(iseq)) return 0;
+ if (!ISEQ_BRANCH_COVERAGE(iseq)) return 0;
+ if (first_line <= 0) return 0;
+ return 1;
+}
+
+static VALUE
+decl_branch_base(rb_iseq_t *iseq, const NODE *node, const char *type)
+{
+ const int first_lineno = nd_first_lineno(node), first_column = nd_first_column(node);
+ const int last_lineno = nd_last_lineno(node), last_column = nd_last_column(node);
+
+ if (!branch_coverage_valid_p(iseq, first_lineno)) return Qundef;
+
+ /*
+ * if !structure[node]
+ * structure[node] = [type, first_lineno, first_column, last_lineno, last_column, branches = {}]
+ * else
+ * branches = structure[node][5]
+ * end
+ */
+
+ VALUE structure = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 0);
+ VALUE key = (VALUE)node | 1; // FIXNUM for hash key
+ VALUE branch_base = rb_hash_aref(structure, key);
+ VALUE branches;
+
+ if (NIL_P(branch_base)) {
+ branch_base = rb_ary_tmp_new(6);
+ rb_hash_aset(structure, key, branch_base);
+ rb_ary_push(branch_base, ID2SYM(rb_intern(type)));
+ rb_ary_push(branch_base, INT2FIX(first_lineno));
+ rb_ary_push(branch_base, INT2FIX(first_column));
+ rb_ary_push(branch_base, INT2FIX(last_lineno));
+ rb_ary_push(branch_base, INT2FIX(last_column));
+ branches = rb_hash_new();
+ rb_obj_hide(branches);
+ rb_ary_push(branch_base, branches);
}
- return COMPILE_OK;
+ else {
+ branches = RARRAY_AREF(branch_base, 5);
+ }
+
+ return branches;
}
-static int
-iseq_add_mark_object_compile_time(const rb_iseq_t *iseq, VALUE v)
+static void
+add_trace_branch_coverage(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NODE *node, int branch_id, const char *type, VALUE branches)
{
- if (!SPECIAL_CONST_P(v)) {
- rb_ary_push(ISEQ_COMPILE_DATA(iseq)->mark_ary, v);
+ const int first_lineno = nd_first_lineno(node), first_column = nd_first_column(node);
+ const int last_lineno = nd_last_lineno(node), last_column = nd_last_column(node);
+
+ if (!branch_coverage_valid_p(iseq, first_lineno)) return;
+
+ /*
+ * if !branches[branch_id]
+ * branches[branch_id] = [type, first_lineno, first_column, last_lineno, last_column, counter_idx]
+ * else
+ * counter_idx= branches[branch_id][5]
+ * end
+ */
+
+ VALUE key = INT2FIX(branch_id);
+ VALUE branch = rb_hash_aref(branches, key);
+ long counter_idx;
+
+ if (NIL_P(branch)) {
+ branch = rb_ary_tmp_new(6);
+ rb_hash_aset(branches, key, branch);
+ rb_ary_push(branch, ID2SYM(rb_intern(type)));
+ rb_ary_push(branch, INT2FIX(first_lineno));
+ rb_ary_push(branch, INT2FIX(first_column));
+ rb_ary_push(branch, INT2FIX(last_lineno));
+ rb_ary_push(branch, INT2FIX(last_column));
+ VALUE counters = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 1);
+ counter_idx = RARRAY_LEN(counters);
+ rb_ary_push(branch, LONG2FIX(counter_idx));
+ rb_ary_push(counters, INT2FIX(0));
}
- return COMPILE_OK;
+ else {
+ counter_idx = FIX2LONG(RARRAY_AREF(branch, 5));
+ }
+
+ ADD_TRACE_WITH_DATA(seq, RUBY_EVENT_COVERAGE_BRANCH, counter_idx);
+ ADD_INSN(seq, last_lineno, nop);
}
+#define ISEQ_LAST_LINE(iseq) (ISEQ_COMPILE_DATA(iseq)->last_line)
+
static int
validate_label(st_data_t name, st_data_t label, st_data_t arg)
{
@@ -606,15 +712,34 @@ validate_labels(rb_iseq_t *iseq, st_table *labels_table)
}
VALUE
-rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
+rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc)
{
DECL_ANCHOR(ret);
INIT_ANCHOR(ret);
+ (*ifunc->func)(iseq, ret, ifunc->data);
+
+ ADD_INSN(ret, ISEQ_COMPILE_DATA(iseq)->last_line, leave);
+
+ CHECK(iseq_setup_insn(iseq, ret));
+ return iseq_setup(iseq, ret);
+}
+
+VALUE
+rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
+{
+ DECL_ANCHOR(ret);
+ INIT_ANCHOR(ret);
+
+ if (IMEMO_TYPE_P(node, imemo_ifunc)) {
+ rb_raise(rb_eArgError, "unexpected imemo_ifunc");
+ }
+
if (node == 0) {
- COMPILE(ret, "nil", node);
+ NO_CHECK(COMPILE(ret, "nil", node));
iseq_set_local_table(iseq, 0);
}
+ /* assume node is T_NODE */
else if (nd_type(node) == NODE_SCOPE) {
/* iseq type of top, method, class, block */
iseq_set_local_table(iseq, node->nd_tbl);
@@ -629,11 +754,13 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
start->rescued = LABEL_RESCUE_BEG;
end->rescued = LABEL_RESCUE_END;
- ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_B_CALL);
+ ADD_TRACE(ret, RUBY_EVENT_B_CALL);
+ ADD_INSN (ret, FIX2INT(iseq->body->location.first_lineno), nop);
ADD_LABEL(ret, start);
CHECK(COMPILE(ret, "block body", node->nd_body));
ADD_LABEL(ret, end);
- ADD_TRACE(ret, nd_line(node), RUBY_EVENT_B_RETURN);
+ ADD_TRACE(ret, RUBY_EVENT_B_RETURN);
+ ISEQ_COMPILE_DATA(iseq)->last_line = iseq->body->location.code_location.end_pos.lineno;
/* wide range catch handler must put at last */
ADD_CATCH_ENTRY(CATCH_TYPE_REDO, start, end, NULL, start);
@@ -642,17 +769,18 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
}
case ISEQ_TYPE_CLASS:
{
- ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_CLASS);
+ ADD_TRACE(ret, RUBY_EVENT_CLASS);
CHECK(COMPILE(ret, "scoped node", node->nd_body));
- ADD_TRACE(ret, nd_line(node), RUBY_EVENT_END);
+ ADD_TRACE(ret, RUBY_EVENT_END);
+ ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node);
break;
}
case ISEQ_TYPE_METHOD:
{
- ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_CALL);
- ADD_TRACE_METHOD_COVERAGE(ret, FIX2INT(iseq->body->location.first_lineno), rb_intern_str(iseq->body->location.label));
+ ADD_TRACE(ret, RUBY_EVENT_CALL);
CHECK(COMPILE(ret, "scoped node", node->nd_body));
- ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
+ ADD_TRACE(ret, RUBY_EVENT_RETURN);
+ ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node);
break;
}
default: {
@@ -661,22 +789,18 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
}
}
}
- else if (imemo_type_p((VALUE)node, imemo_ifunc)) {
- const struct vm_ifunc *ifunc = (struct vm_ifunc *)node;
- /* user callback */
- (*ifunc->func)(iseq, ret, ifunc->data);
- }
else {
+ const char *m;
+#define INVALID_ISEQ_TYPE(type) \
+ ISEQ_TYPE_##type: m = #type; goto invalid_iseq_type
switch (iseq->body->type) {
- case ISEQ_TYPE_METHOD:
- case ISEQ_TYPE_CLASS:
- case ISEQ_TYPE_BLOCK:
- case ISEQ_TYPE_EVAL:
- case ISEQ_TYPE_MAIN:
- case ISEQ_TYPE_TOP:
- COMPILE_ERROR(ERROR_ARGS "compile/should not be reached: %s:%d",
- __FILE__, __LINE__);
- return COMPILE_NG;
+ case INVALID_ISEQ_TYPE(METHOD);
+ case INVALID_ISEQ_TYPE(CLASS);
+ case INVALID_ISEQ_TYPE(BLOCK);
+ case INVALID_ISEQ_TYPE(EVAL);
+ case INVALID_ISEQ_TYPE(MAIN);
+ case INVALID_ISEQ_TYPE(TOP);
+#undef INVALID_ISEQ_TYPE /* invalid iseq types end */
case ISEQ_TYPE_RESCUE:
iseq_set_exception_local_table(iseq);
CHECK(COMPILE(ret, "rescue", node));
@@ -685,12 +809,14 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
iseq_set_exception_local_table(iseq);
CHECK(COMPILE_POPPED(ret, "ensure", node));
break;
- case ISEQ_TYPE_DEFINED_GUARD:
- iseq_set_exception_local_table(iseq);
- CHECK(COMPILE(ret, "defined guard", node));
+ case ISEQ_TYPE_PLAIN:
+ CHECK(COMPILE(ret, "ensure", node));
break;
default:
- COMPILE_ERROR(ERROR_ARGS "unknown scope");
+ COMPILE_ERROR(ERROR_ARGS "unknown scope: %d", iseq->body->type);
+ return COMPILE_NG;
+ invalid_iseq_type:
+ COMPILE_ERROR(ERROR_ARGS "compile/ISEQ_TYPE_%s should not be reached", m);
return COMPILE_NG;
}
}
@@ -703,17 +829,18 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
ADD_INSN(ret, ISEQ_COMPILE_DATA(iseq)->last_line, leave);
}
-#if SUPPORT_JOKE
+#if OPT_SUPPORT_JOKE
if (ISEQ_COMPILE_DATA(iseq)->labels_table) {
st_table *labels_table = ISEQ_COMPILE_DATA(iseq)->labels_table;
ISEQ_COMPILE_DATA(iseq)->labels_table = 0;
validate_labels(iseq, labels_table);
}
#endif
+ CHECK(iseq_setup_insn(iseq, ret));
return iseq_setup(iseq, ret);
}
-int
+static int
rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
{
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
@@ -727,26 +854,11 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
encoded[i] = (VALUE)table[insn];
i += len;
}
+ FL_SET((VALUE)iseq, ISEQ_TRANSLATED);
#endif
return COMPILE_OK;
}
-#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
-static int
-rb_vm_insn_addr2insn(const void *addr) /* cold path */
-{
- int insn;
- const void * const *table = rb_vm_get_insns_address_table();
-
- for (insn = 0; insn < VM_INSTRUCTION_SIZE; insn++) {
- if (table[insn] == addr) {
- return insn;
- }
- }
- rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr);
-}
-#endif
-
VALUE *
rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
{
@@ -786,6 +898,16 @@ rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
#define STRICT_ALIGNMENT
#endif
+/*
+ * Some OpenBSD platforms (including sparc64) require strict alignment.
+ */
+#if defined(__OpenBSD__)
+ #include <sys/endian.h>
+ #ifdef __STRICT_ALIGNMENT
+ #define STRICT_ALIGNMENT
+ #endif
+#endif
+
#ifdef STRICT_ALIGNMENT
#if defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG > SIZEOF_VALUE
#define ALIGNMENT_SIZE SIZEOF_LONG_LONG
@@ -826,11 +948,10 @@ calc_padding(void *ptr, size_t size)
#endif /* STRICT_ALIGNMENT */
static void *
-compile_data_alloc(rb_iseq_t *iseq, size_t size)
+compile_data_alloc_with_arena(struct iseq_compile_data_storage **arena, size_t size)
{
void *ptr = 0;
- struct iseq_compile_data_storage *storage =
- ISEQ_COMPILE_DATA(iseq)->storage_current;
+ struct iseq_compile_data_storage *storage = *arena;
#ifdef STRICT_ALIGNMENT
size_t padding = calc_padding((void *)&storage->buff[storage->pos], size);
#else
@@ -846,8 +967,8 @@ compile_data_alloc(rb_iseq_t *iseq, size_t size)
alloc_size *= 2;
}
storage->next = (void *)ALLOC_N(char, alloc_size +
- SIZEOF_ISEQ_COMPILE_DATA_STORAGE);
- storage = ISEQ_COMPILE_DATA(iseq)->storage_current = storage->next;
+ offsetof(struct iseq_compile_data_storage, buff));
+ storage = *arena = storage->next;
storage->next = 0;
storage->pos = 0;
storage->size = alloc_size;
@@ -865,10 +986,34 @@ compile_data_alloc(rb_iseq_t *iseq, size_t size)
return ptr;
}
+static void *
+compile_data_alloc(rb_iseq_t *iseq, size_t size)
+{
+ struct iseq_compile_data_storage ** arena = &ISEQ_COMPILE_DATA(iseq)->node.storage_current;
+ return compile_data_alloc_with_arena(arena, size);
+}
+
+static inline void *
+compile_data_alloc2(rb_iseq_t *iseq, size_t x, size_t y)
+{
+ size_t size = rb_size_mul_or_raise(x, y, rb_eRuntimeError);
+ return compile_data_alloc(iseq, size);
+}
+
+static inline void *
+compile_data_calloc2(rb_iseq_t *iseq, size_t x, size_t y)
+{
+ size_t size = rb_size_mul_or_raise(x, y, rb_eRuntimeError);
+ void *p = compile_data_alloc(iseq, size);
+ memset(p, 0, size);
+ return p;
+}
+
static INSN *
compile_data_alloc_insn(rb_iseq_t *iseq)
{
- return (INSN *)compile_data_alloc(iseq, sizeof(INSN));
+ struct iseq_compile_data_storage ** arena = &ISEQ_COMPILE_DATA(iseq)->insn.storage_current;
+ return (INSN *)compile_data_alloc_with_arena(arena, sizeof(INSN));
}
static LABEL *
@@ -883,11 +1028,17 @@ compile_data_alloc_adjust(rb_iseq_t *iseq)
return (ADJUST *)compile_data_alloc(iseq, sizeof(ADJUST));
}
+static TRACE *
+compile_data_alloc_trace(rb_iseq_t *iseq)
+{
+ return (TRACE *)compile_data_alloc(iseq, sizeof(TRACE));
+}
+
/*
* elem1, elemX => elem1, elem2, elemX
*/
static void
-INSERT_ELEM_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
+ELEM_INSERT_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
{
elem2->next = elem1->next;
elem2->prev = elem1;
@@ -901,7 +1052,7 @@ INSERT_ELEM_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
* elem1, elemX => elemX, elem2, elem1
*/
static void
-INSERT_ELEM_PREV(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
+ELEM_INSERT_PREV(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
{
elem2->prev = elem1->prev;
elem2->next = elem1;
@@ -915,7 +1066,7 @@ INSERT_ELEM_PREV(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
* elemX, elem1, elemY => elemX, elem2, elemY
*/
static void
-REPLACE_ELEM(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
+ELEM_REPLACE(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
{
elem2->prev = elem1->prev;
elem2->next = elem1->next;
@@ -928,7 +1079,7 @@ REPLACE_ELEM(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
}
static void
-REMOVE_ELEM(LINK_ELEMENT *elem)
+ELEM_REMOVE(LINK_ELEMENT *elem)
{
elem->prev->next = elem->next;
if (elem->next) {
@@ -937,7 +1088,7 @@ REMOVE_ELEM(LINK_ELEMENT *elem)
}
static LINK_ELEMENT *
-FIRST_ELEMENT(LINK_ANCHOR *const anchor)
+FIRST_ELEMENT(const LINK_ANCHOR *const anchor)
{
return anchor->anchor.next;
}
@@ -961,14 +1112,42 @@ POP_ELEMENT(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor)
#define POP_ELEMENT(anchor) POP_ELEMENT(iseq, (anchor))
#endif
+static LINK_ELEMENT *
+ELEM_FIRST_INSN(LINK_ELEMENT *elem)
+{
+ while (elem) {
+ switch (elem->type) {
+ case ISEQ_ELEMENT_INSN:
+ case ISEQ_ELEMENT_ADJUST:
+ return elem;
+ default:
+ elem = elem->next;
+ }
+ }
+ return NULL;
+}
+
static int
-LIST_SIZE_ZERO(LINK_ANCHOR *const anchor)
+LIST_INSN_SIZE_ONE(const LINK_ANCHOR *const anchor)
{
- if (anchor->anchor.next == 0) {
- return 1;
+ LINK_ELEMENT *first_insn = ELEM_FIRST_INSN(FIRST_ELEMENT(anchor));
+ if (first_insn != NULL &&
+ ELEM_FIRST_INSN(first_insn->next) == NULL) {
+ return TRUE;
}
else {
- return 0;
+ return FALSE;
+ }
+}
+
+static int
+LIST_INSN_SIZE_ZERO(const LINK_ANCHOR *const anchor)
+{
+ if (ELEM_FIRST_INSN(FIRST_ELEMENT(anchor)) == NULL) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
}
}
@@ -993,38 +1172,9 @@ APPEND_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *const anc1, LINK_ANCHOR *const anc2)
#define APPEND_LIST(anc1, anc2) APPEND_LIST(iseq, (anc1), (anc2))
#endif
-/*
- * anc1: e1, e2, e3
- * anc2: e4, e5
- *#=>
- * anc1: e4, e5, e1, e2, e3
- * anc2: e4, e5 (broken)
- */
-static void
-INSERT_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *const anc1, LINK_ANCHOR *const anc2)
-{
- if (anc2->anchor.next) {
- LINK_ELEMENT *first = anc1->anchor.next;
- anc1->anchor.next = anc2->anchor.next;
- anc1->anchor.next->prev = &anc1->anchor;
- anc2->last->next = first;
- if (first) {
- first->prev = anc2->last;
- }
- else {
- anc1->last = anc2->last;
- }
- }
-
- verify_list("append", anc1);
-}
-#if CPDEBUG < 0
-#define INSERT_LIST(anc1, anc2) INSERT_LIST(iseq, (anc1), (anc2))
-#endif
-
#if CPDEBUG && 0
static void
-debug_list(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor)
+debug_list(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor, LINK_ELEMENT *cur)
{
LINK_ELEMENT *list = FIRST_ELEMENT(anchor);
printf("----\n");
@@ -1032,21 +1182,34 @@ debug_list(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor)
anchor->anchor.next, anchor->last);
while (list) {
printf("curr: %p, next: %p, prev: %p, type: %d\n", list, list->next,
- list->prev, FIX2INT(list->type));
+ list->prev, (int)list->type);
list = list->next;
}
printf("----\n");
- dump_disasm_list(anchor->anchor.next);
+ dump_disasm_list_with_cursor(anchor->anchor.next, cur, 0);
verify_list("debug list", anchor);
}
#if CPDEBUG < 0
-#define debug_list(anc) debug_list(iseq, (anc))
+#define debug_list(anc, cur) debug_list(iseq, (anc), (cur))
#endif
#else
-#define debug_list(anc) ((void)0)
+#define debug_list(anc, cur) ((void)0)
#endif
+static TRACE *
+new_trace_body(rb_iseq_t *iseq, rb_event_flag_t event, long data)
+{
+ TRACE *trace = compile_data_alloc_trace(iseq);
+
+ trace->link.type = ISEQ_ELEMENT_TRACE;
+ trace->link.next = NULL;
+ trace->event = event;
+ trace->data = data;
+
+ return trace;
+}
+
static LABEL *
new_label_body(rb_iseq_t *iseq, long line)
{
@@ -1082,12 +1245,14 @@ new_insn_core(rb_iseq_t *iseq, int line_no,
int insn_id, int argc, VALUE *argv)
{
INSN *iobj = compile_data_alloc_insn(iseq);
+
/* printf("insn_id: %d, line: %d\n", insn_id, line_no); */
iobj->link.type = ISEQ_ELEMENT_INSN;
iobj->link.next = 0;
iobj->insn_id = insn_id;
- iobj->line_no = line_no;
+ iobj->insn_info.line_no = line_no;
+ iobj->insn_info.events = 0;
iobj->operands = argv;
iobj->operand_size = argc;
iobj->sc_state = 0;
@@ -1101,8 +1266,8 @@ new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int a
va_list argv;
if (argc > 0) {
int i;
- va_init_list(argv, argc);
- operands = (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * argc);
+ va_start(argv, argc);
+ operands = compile_data_alloc2(iseq, sizeof(VALUE), argc);
for (i = 0; i < argc; i++) {
VALUE v = va_arg(argv, VALUE);
operands[i] = v;
@@ -1112,61 +1277,159 @@ new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int a
return new_insn_core(iseq, line_no, insn_id, argc, operands);
}
-static struct rb_call_info *
-new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, struct rb_call_info_kw_arg *kw_arg, int has_blockiseq)
+static const struct rb_callinfo *
+new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, struct rb_callinfo_kwarg *kw_arg, int has_blockiseq)
{
- size_t size = kw_arg != NULL ? sizeof(struct rb_call_info_with_kwarg) : sizeof(struct rb_call_info);
- struct rb_call_info *ci = (struct rb_call_info *)compile_data_alloc(iseq, size);
- struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci;
+ VM_ASSERT(argc >= 0);
- ci->mid = mid;
- ci->flag = flag;
- ci->orig_argc = argc;
+ if (!(flag & (VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG | VM_CALL_KW_SPLAT)) &&
+ kw_arg == NULL && !has_blockiseq) {
+ flag |= VM_CALL_ARGS_SIMPLE;
+ }
if (kw_arg) {
- ci->flag |= VM_CALL_KWARG;
- ci_kw->kw_arg = kw_arg;
- ci->orig_argc += kw_arg->keyword_len;
- iseq->body->ci_kw_size++;
- }
- else {
- iseq->body->ci_size++;
+ flag |= VM_CALL_KWARG;
+ argc += kw_arg->keyword_len;
}
- if (!(ci->flag & (VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG | VM_CALL_KW_SPLAT)) &&
- kw_arg == NULL && !has_blockiseq) {
- ci->flag |= VM_CALL_ARGS_SIMPLE;
- }
+ // fprintf(stderr, "[%d] id:%s\t", (int)iseq->body->ci_size, rb_id2name(mid)); rp(iseq);
+ iseq->body->ci_size++;
+ const struct rb_callinfo *ci = vm_ci_new(mid, flag, argc, kw_arg);
+ RB_OBJ_WRITTEN(iseq, Qundef, ci);
return ci;
}
static INSN *
-new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_call_info_kw_arg *keywords)
+new_insn_send(rb_iseq_t *iseq, int line_no, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_callinfo_kwarg *keywords)
{
- VALUE *operands = (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 3);
- operands[0] = (VALUE)new_callinfo(iseq, id, FIX2INT(argc), FIX2INT(flag), keywords, blockiseq != NULL);
- operands[1] = Qfalse; /* cache */
- operands[2] = (VALUE)blockiseq;
- return new_insn_core(iseq, line_no, BIN(send), 3, operands);
+ VALUE *operands = compile_data_calloc2(iseq, sizeof(VALUE), 2);
+ VALUE ci = (VALUE)new_callinfo(iseq, id, FIX2INT(argc), FIX2INT(flag), keywords, blockiseq != NULL);
+ operands[0] = ci;
+ operands[1] = (VALUE)blockiseq;
+ if (blockiseq) {
+ RB_OBJ_WRITTEN(iseq, Qundef, blockiseq);
+ }
+ INSN *insn = new_insn_core(iseq, line_no, BIN(send), 2, operands);
+ RB_OBJ_WRITTEN(iseq, Qundef, ci);
+ RB_GC_GUARD(ci);
+ return insn;
}
static rb_iseq_t *
-new_child_iseq(rb_iseq_t *iseq, NODE *node,
+new_child_iseq(rb_iseq_t *iseq, const NODE *const node,
VALUE name, const rb_iseq_t *parent, enum iseq_type type, int line_no)
{
rb_iseq_t *ret_iseq;
+ rb_ast_body_t ast;
+
+ ast.root = node;
+ ast.compile_option = 0;
+ ast.line_count = -1;
debugs("[new_child_iseq]> ---------------------------------------\n");
- ret_iseq = rb_iseq_new_with_opt(node, name,
+ int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
+ ret_iseq = rb_iseq_new_with_opt(&ast, name,
rb_iseq_path(iseq), rb_iseq_realpath(iseq),
- INT2FIX(line_no), parent, type, ISEQ_COMPILE_DATA(iseq)->option);
+ INT2FIX(line_no), parent,
+ isolated_depth ? isolated_depth + 1 : 0,
+ type, ISEQ_COMPILE_DATA(iseq)->option);
debugs("[new_child_iseq]< ---------------------------------------\n");
- iseq_add_mark_object(iseq, (VALUE)ret_iseq);
return ret_iseq;
}
+static rb_iseq_t *
+new_child_iseq_with_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func *ifunc,
+ VALUE name, const rb_iseq_t *parent, enum iseq_type type, int line_no)
+{
+ rb_iseq_t *ret_iseq;
+
+ debugs("[new_child_iseq_with_callback]> ---------------------------------------\n");
+ ret_iseq = rb_iseq_new_with_callback(ifunc, name,
+ rb_iseq_path(iseq), rb_iseq_realpath(iseq),
+ INT2FIX(line_no), parent, type, ISEQ_COMPILE_DATA(iseq)->option);
+ debugs("[new_child_iseq_with_callback]< ---------------------------------------\n");
+ return ret_iseq;
+}
+
+static void
+set_catch_except_p(struct rb_iseq_constant_body *body)
+{
+ body->catch_except_p = TRUE;
+ if (body->parent_iseq != NULL) {
+ set_catch_except_p(body->parent_iseq->body);
+ }
+}
+
+/* Set body->catch_except_p to TRUE if the ISeq may catch an exception. If it is FALSE,
+ JIT-ed code may be optimized. If we are extremely conservative, we should set TRUE
+ if catch table exists. But we want to optimize while loop, which always has catch
+ table entries for break/next/redo.
+
+ So this function sets TRUE for limited ISeqs with break/next/redo catch table entries
+ whose child ISeq would really raise an exception. */
+static void
+update_catch_except_flags(struct rb_iseq_constant_body *body)
+{
+ unsigned int pos;
+ size_t i;
+ int insn;
+ const struct iseq_catch_table *ct = body->catch_table;
+
+ /* This assumes that a block has parent_iseq which may catch an exception from the block, and that
+ BREAK/NEXT/REDO catch table entries are used only when `throw` insn is used in the block. */
+ pos = 0;
+ while (pos < body->iseq_size) {
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ insn = rb_vm_insn_addr2insn((void *)body->iseq_encoded[pos]);
+#else
+ insn = (int)body->iseq_encoded[pos];
+#endif
+ if (insn == BIN(throw)) {
+ set_catch_except_p(body);
+ break;
+ }
+ pos += insn_len(insn);
+ }
+
+ if (ct == NULL)
+ return;
+
+ for (i = 0; i < ct->size; i++) {
+ const struct iseq_catch_table_entry *entry =
+ UNALIGNED_MEMBER_PTR(ct, entries[i]);
+ if (entry->type != CATCH_TYPE_BREAK
+ && entry->type != CATCH_TYPE_NEXT
+ && entry->type != CATCH_TYPE_REDO) {
+ body->catch_except_p = TRUE;
+ break;
+ }
+ }
+}
+
+static void
+iseq_insert_nop_between_end_and_cont(rb_iseq_t *iseq)
+{
+ VALUE catch_table_ary = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ if (NIL_P(catch_table_ary)) return;
+ unsigned int i, tlen = (unsigned int)RARRAY_LEN(catch_table_ary);
+ const VALUE *tptr = RARRAY_CONST_PTR_TRANSIENT(catch_table_ary);
+ for (i = 0; i < tlen; i++) {
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(tptr[i]);
+ LINK_ELEMENT *end = (LINK_ELEMENT *)(ptr[2] & ~1);
+ LINK_ELEMENT *cont = (LINK_ELEMENT *)(ptr[4] & ~1);
+ LINK_ELEMENT *e;
+ for (e = end; e && (IS_LABEL(e) || IS_TRACE(e)); e = e->next) {
+ if (e == cont) {
+ INSN *nop = new_insn_core(iseq, 0, BIN(nop), 0, 0);
+ ELEM_INSERT_NEXT(end, &nop->link);
+ break;
+ }
+ }
+ }
+}
+
static int
-iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
{
if (RTEST(ISEQ_COMPILE_DATA(iseq)->err_info))
return COMPILE_NG;
@@ -1196,6 +1459,20 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
dump_disasm_list(FIRST_ELEMENT(anchor));
}
+ debugs("[compile step 3.4 (iseq_insert_nop_between_end_and_cont)]\n");
+ iseq_insert_nop_between_end_and_cont(iseq);
+ if (compile_debug > 5)
+ dump_disasm_list(FIRST_ELEMENT(anchor));
+
+ return COMPILE_OK;
+}
+
+static int
+iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+ if (RTEST(ISEQ_COMPILE_DATA(iseq)->err_info))
+ return COMPILE_NG;
+
debugs("[compile step 4.1 (iseq_set_sequence)]\n");
if (!iseq_set_sequence(iseq, anchor)) return COMPILE_NG;
if (compile_debug > 5)
@@ -1210,10 +1487,21 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
debugs("[compile step 5 (iseq_translate_threaded_code)] \n");
if (!rb_iseq_translate_threaded_code(iseq)) return COMPILE_NG;
+ debugs("[compile step 6 (update_catch_except_flags)] \n");
+ update_catch_except_flags(iseq->body);
+
+#if VM_INSN_INFO_TABLE_IMPL == 2
+ if (iseq->body->insns_info.succ_index_table == NULL) {
+ debugs("[compile step 7 (rb_iseq_insns_info_encode_positions)] \n");
+ rb_iseq_insns_info_encode_positions(iseq);
+ }
+#endif
+
if (compile_debug > 1) {
VALUE str = rb_iseq_disasm(iseq);
printf("%s\n", StringValueCStr(str));
}
+ verify_call_cache(iseq);
debugs("[compile step: finish]\n");
return COMPILE_OK;
@@ -1222,16 +1510,8 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
static int
iseq_set_exception_local_table(rb_iseq_t *iseq)
{
- /* TODO: every id table is same -> share it.
- * Current problem is iseq_free().
- */
- ID id_dollar_bang;
- ID *ids = (ID *)ALLOC_N(ID, 1);
-
- CONST_ID(id_dollar_bang, "#$!");
- iseq->body->local_table_size = 1;
- ids[0] = id_dollar_bang;
- iseq->body->local_table = ids;
+ iseq->body->local_table_size = numberof(rb_iseq_shared_exc_local_tbl);
+ iseq->body->local_table = rb_iseq_shared_exc_local_tbl;
return COMPILE_OK;
}
@@ -1265,7 +1545,8 @@ get_local_var_idx(const rb_iseq_t *iseq, ID id)
int idx = get_dyna_var_idx_at_raw(iseq->body->local_iseq, id);
if (idx < 0) {
- rb_bug("get_local_var_idx: %d", idx);
+ COMPILE_ERROR(iseq, ISEQ_LAST_LINE(iseq),
+ "get_local_var_idx: %d", idx);
}
return idx;
@@ -1275,6 +1556,7 @@ static int
get_dyna_var_idx(const rb_iseq_t *iseq, ID id, int *level, int *ls)
{
int lv = 0, idx = -1;
+ const rb_iseq_t *const topmost_iseq = iseq;
while (iseq) {
idx = get_dyna_var_idx_at_raw(iseq, id);
@@ -1286,7 +1568,8 @@ get_dyna_var_idx(const rb_iseq_t *iseq, ID id, int *level, int *ls)
}
if (idx < 0) {
- rb_bug("get_dyna_var_idx: -1");
+ COMPILE_ERROR(topmost_iseq, ISEQ_LAST_LINE(topmost_iseq),
+ "get_dyna_var_idx: -1");
}
*level = lv;
@@ -1294,69 +1577,184 @@ get_dyna_var_idx(const rb_iseq_t *iseq, ID id, int *level, int *ls)
return idx;
}
+static int
+iseq_local_block_param_p(const rb_iseq_t *iseq, unsigned int idx, unsigned int level)
+{
+ const struct rb_iseq_constant_body *body;
+ while (level > 0) {
+ iseq = iseq->body->parent_iseq;
+ level--;
+ }
+ body = iseq->body;
+ if (body->local_iseq == iseq && /* local variables */
+ body->param.flags.has_block &&
+ body->local_table_size - body->param.block_start == idx) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static int
+iseq_block_param_id_p(const rb_iseq_t *iseq, ID id, int *pidx, int *plevel)
+{
+ int level, ls;
+ int idx = get_dyna_var_idx(iseq, id, &level, &ls);
+ if (iseq_local_block_param_p(iseq, ls - idx, level)) {
+ *pidx = ls - idx;
+ *plevel = level;
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static void
+access_outer_variables(const rb_iseq_t *iseq, int level, ID id, bool write)
+{
+ int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
+
+ if (isolated_depth && level >= isolated_depth) {
+ if (id == rb_intern("yield")) {
+ COMPILE_ERROR(iseq, ISEQ_LAST_LINE(iseq), "can not yield from isolated Proc", rb_id2name(id));
+ }
+ else {
+ COMPILE_ERROR(iseq, ISEQ_LAST_LINE(iseq), "can not access variable `%s' from isolated Proc", rb_id2name(id));
+ }
+ }
+
+ for (int i=0; i<level; i++) {
+ VALUE val;
+ struct rb_id_table *ovs = iseq->body->outer_variables;
+
+ if (!ovs) {
+ ovs = iseq->body->outer_variables = rb_id_table_create(8);
+ }
+
+ if (rb_id_table_lookup(iseq->body->outer_variables, id, &val)) {
+ if (write && !val) {
+ rb_id_table_insert(iseq->body->outer_variables, id, Qtrue);
+ }
+ }
+ else {
+ rb_id_table_insert(iseq->body->outer_variables, id, write ? Qtrue : Qfalse);
+ }
+
+ iseq = iseq->body->parent_iseq;
+ }
+}
+
+static ID
+iseq_lvar_id(const rb_iseq_t *iseq, int idx, int level)
+{
+ for (int i=0; i<level; i++) {
+ iseq = iseq->body->parent_iseq;
+ }
+
+ ID id = iseq->body->local_table[iseq->body->local_table_size - idx];
+ // fprintf(stderr, "idx:%d level:%d ID:%s\n", idx, level, rb_id2name(id));
+ return id;
+}
+
+static void
+iseq_add_getlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int idx, int level)
+{
+ if (iseq_local_block_param_p(iseq, idx, level)) {
+ ADD_INSN2(seq, line, getblockparam, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
+ }
+ else {
+ ADD_INSN2(seq, line, getlocal, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
+ }
+ if (level > 0) access_outer_variables(iseq, level, iseq_lvar_id(iseq, idx, level), Qfalse);
+}
+
+static void
+iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int idx, int level)
+{
+ if (iseq_local_block_param_p(iseq, idx, level)) {
+ ADD_INSN2(seq, line, setblockparam, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
+ }
+ else {
+ ADD_INSN2(seq, line, setlocal, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
+ }
+ if (level > 0) access_outer_variables(iseq, level, iseq_lvar_id(iseq, idx, level), Qtrue);
+}
+
+
+
static void
iseq_calc_param_size(rb_iseq_t *iseq)
{
- if (iseq->body->param.flags.has_opt ||
- iseq->body->param.flags.has_post ||
- iseq->body->param.flags.has_rest ||
- iseq->body->param.flags.has_block ||
- iseq->body->param.flags.has_kw ||
- iseq->body->param.flags.has_kwrest) {
+ struct rb_iseq_constant_body *const body = iseq->body;
+ if (body->param.flags.has_opt ||
+ body->param.flags.has_post ||
+ body->param.flags.has_rest ||
+ body->param.flags.has_block ||
+ body->param.flags.has_kw ||
+ body->param.flags.has_kwrest) {
- if (iseq->body->param.flags.has_block) {
- iseq->body->param.size = iseq->body->param.block_start + 1;
+ if (body->param.flags.has_block) {
+ body->param.size = body->param.block_start + 1;
}
- else if (iseq->body->param.flags.has_kwrest) {
- iseq->body->param.size = iseq->body->param.keyword->rest_start + 1;
+ else if (body->param.flags.has_kwrest) {
+ body->param.size = body->param.keyword->rest_start + 1;
}
- else if (iseq->body->param.flags.has_kw) {
- iseq->body->param.size = iseq->body->param.keyword->bits_start + 1;
+ else if (body->param.flags.has_kw) {
+ body->param.size = body->param.keyword->bits_start + 1;
}
- else if (iseq->body->param.flags.has_post) {
- iseq->body->param.size = iseq->body->param.post_start + iseq->body->param.post_num;
+ else if (body->param.flags.has_post) {
+ body->param.size = body->param.post_start + body->param.post_num;
}
- else if (iseq->body->param.flags.has_rest) {
- iseq->body->param.size = iseq->body->param.rest_start + 1;
+ else if (body->param.flags.has_rest) {
+ body->param.size = body->param.rest_start + 1;
}
- else if (iseq->body->param.flags.has_opt) {
- iseq->body->param.size = iseq->body->param.lead_num + iseq->body->param.opt_num;
+ else if (body->param.flags.has_opt) {
+ body->param.size = body->param.lead_num + body->param.opt_num;
}
else {
- rb_bug("unreachable");
+ UNREACHABLE;
}
}
else {
- iseq->body->param.size = iseq->body->param.lead_num;
+ body->param.size = body->param.lead_num;
}
}
-static void
+static int
iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
- const struct rb_args_info *args)
+ const struct rb_args_info *args, int arg_size)
{
- NODE *node = args->kw_args;
+ const NODE *node = args->kw_args;
+ struct rb_iseq_constant_body *const body = iseq->body;
struct rb_iseq_param_keyword *keyword;
const VALUE default_values = rb_ary_tmp_new(1);
const VALUE complex_mark = rb_str_tmp_new(0);
int kw = 0, rkw = 0, di = 0, i;
- iseq->body->param.flags.has_kw = TRUE;
- iseq->body->param.keyword = keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
- keyword->bits_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_cflag);
+ body->param.flags.has_kw = TRUE;
+ body->param.keyword = keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
while (node) {
- NODE *val_node = node->nd_body->nd_value;
+ kw++;
+ node = node->nd_next;
+ }
+ arg_size += kw;
+ keyword->bits_start = arg_size++;
+
+ node = args->kw_args;
+ while (node) {
+ const NODE *val_node = node->nd_body->nd_value;
VALUE dv;
- if (val_node == (NODE *)-1) {
+ if (val_node == NODE_SPECIAL_REQUIRED_KEYWORD) {
++rkw;
}
else {
switch (nd_type(val_node)) {
case NODE_LIT:
dv = val_node->nd_lit;
- iseq_add_mark_object(iseq, dv);
break;
case NODE_NIL:
dv = Qnil;
@@ -1368,7 +1766,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
dv = Qfalse;
break;
default:
- COMPILE_POPPED(optargs, "kwarg", node); /* nd_type(node) == NODE_KW_ARG */
+ NO_CHECK(COMPILE_POPPED(optargs, "kwarg", node)); /* nd_type(node) == NODE_KW_ARG */
dv = complex_mark;
}
@@ -1376,18 +1774,17 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
rb_ary_push(default_values, dv);
}
- kw++;
node = node->nd_next;
}
keyword->num = kw;
if (args->kw_rest_arg->nd_vid != 0) {
- keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_vid);
- iseq->body->param.flags.has_kwrest = TRUE;
+ keyword->rest_start = arg_size++;
+ body->param.flags.has_kwrest = TRUE;
}
keyword->required_num = rkw;
- keyword->table = &iseq->body->local_table[keyword->bits_start - keyword->num];
+ keyword->table = &body->local_table[keyword->bits_start - keyword->num];
{
VALUE *dvs = ALLOC_N(VALUE, RARRAY_LEN(default_values));
@@ -1395,45 +1792,46 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
for (i = 0; i < RARRAY_LEN(default_values); i++) {
VALUE dv = RARRAY_AREF(default_values, i);
if (dv == complex_mark) dv = Qundef;
+ if (!SPECIAL_CONST_P(dv)) {
+ RB_OBJ_WRITTEN(iseq, Qundef, dv);
+ }
dvs[i] = dv;
}
keyword->default_values = dvs;
}
+ return arg_size;
}
static int
-iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, NODE *node_args)
+iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *const node_args)
{
debugs("iseq_set_arguments: %s\n", node_args ? "" : "0");
if (node_args) {
+ struct rb_iseq_constant_body *const body = iseq->body;
struct rb_args_info *args = node_args->nd_ainfo;
ID rest_id = 0;
int last_comma = 0;
ID block_id = 0;
+ int arg_size;
EXPECT_NODE("iseq_set_arguments", node_args, NODE_ARGS, COMPILE_NG);
- iseq->body->param.lead_num = (int)args->pre_args_num;
- if (iseq->body->param.lead_num > 0) iseq->body->param.flags.has_lead = TRUE;
- debugs(" - argc: %d\n", iseq->body->param.lead_num);
+ body->param.flags.ruby2_keywords = args->ruby2_keywords;
+ body->param.lead_num = arg_size = (int)args->pre_args_num;
+ if (body->param.lead_num > 0) body->param.flags.has_lead = TRUE;
+ debugs(" - argc: %d\n", body->param.lead_num);
rest_id = args->rest_arg;
- if (rest_id == 1) {
+ if (rest_id == NODE_SPECIAL_EXCESSIVE_COMMA) {
last_comma = 1;
rest_id = 0;
}
block_id = args->block_arg;
- if (args->first_post_arg) {
- iseq->body->param.post_start = get_dyna_var_idx_at_raw(iseq, args->first_post_arg);
- iseq->body->param.post_num = args->post_args_num;
- iseq->body->param.flags.has_post = TRUE;
- }
-
if (args->opt_args) {
- NODE *node = args->opt_args;
+ const NODE *node = args->opt_args;
LABEL *label;
VALUE labels = rb_ary_tmp_new(1);
VALUE *opt_table;
@@ -1443,7 +1841,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, NODE *node_args)
label = NEW_LABEL(nd_line(node));
rb_ary_push(labels, (VALUE)label | 1);
ADD_LABEL(optargs, label);
- COMPILE_POPPED(optargs, "optarg", node->nd_body);
+ NO_CHECK(COMPILE_POPPED(optargs, "optarg", node->nd_body));
node = node->nd_next;
i += 1;
}
@@ -1455,61 +1853,73 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, NODE *node_args)
opt_table = ALLOC_N(VALUE, i+1);
- MEMCPY(opt_table, RARRAY_CONST_PTR(labels), VALUE, i+1);
+ MEMCPY(opt_table, RARRAY_CONST_PTR_TRANSIENT(labels), VALUE, i+1);
for (j = 0; j < i+1; j++) {
opt_table[j] &= ~1;
}
rb_ary_clear(labels);
- iseq->body->param.flags.has_opt = TRUE;
- iseq->body->param.opt_num = i;
- iseq->body->param.opt_table = opt_table;
+ body->param.flags.has_opt = TRUE;
+ body->param.opt_num = i;
+ body->param.opt_table = opt_table;
+ arg_size += i;
}
- if (args->kw_args) {
- iseq_set_arguments_keywords(iseq, optargs, args);
+ if (rest_id) {
+ body->param.rest_start = arg_size++;
+ body->param.flags.has_rest = TRUE;
+ assert(body->param.rest_start != -1);
}
- else if (args->kw_rest_arg) {
- struct rb_iseq_param_keyword *keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
- keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_vid);
- iseq->body->param.keyword = keyword;
- iseq->body->param.flags.has_kwrest = TRUE;
+
+ if (args->first_post_arg) {
+ body->param.post_start = arg_size;
+ body->param.post_num = args->post_args_num;
+ body->param.flags.has_post = TRUE;
+ arg_size += args->post_args_num;
+
+ if (body->param.flags.has_rest) { /* TODO: why that? */
+ body->param.post_start = body->param.rest_start + 1;
+ }
}
- if (args->pre_init) { /* m_init */
- COMPILE_POPPED(optargs, "init arguments (m)", args->pre_init);
+ if (args->kw_args) {
+ arg_size = iseq_set_arguments_keywords(iseq, optargs, args, arg_size);
}
- if (args->post_init) { /* p_init */
- COMPILE_POPPED(optargs, "init arguments (p)", args->post_init);
+ else if (args->kw_rest_arg) {
+ struct rb_iseq_param_keyword *keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
+ keyword->rest_start = arg_size++;
+ body->param.keyword = keyword;
+ body->param.flags.has_kwrest = TRUE;
}
-
- if (rest_id) {
- iseq->body->param.rest_start = get_dyna_var_idx_at_raw(iseq, rest_id);
- iseq->body->param.flags.has_rest = TRUE;
- assert(iseq->body->param.rest_start != -1);
-
- if (iseq->body->param.post_start == 0) { /* TODO: why that? */
- iseq->body->param.post_start = iseq->body->param.rest_start + 1;
- }
+ else if (args->no_kwarg) {
+ body->param.flags.accepts_no_kwarg = TRUE;
}
if (block_id) {
- iseq->body->param.block_start = get_dyna_var_idx_at_raw(iseq, block_id);
- iseq->body->param.flags.has_block = TRUE;
+ body->param.block_start = arg_size++;
+ body->param.flags.has_block = TRUE;
}
iseq_calc_param_size(iseq);
+ body->param.size = arg_size;
+
+ if (args->pre_init) { /* m_init */
+ NO_CHECK(COMPILE_POPPED(optargs, "init arguments (m)", args->pre_init));
+ }
+ if (args->post_init) { /* p_init */
+ NO_CHECK(COMPILE_POPPED(optargs, "init arguments (p)", args->post_init));
+ }
- if (iseq->body->type == ISEQ_TYPE_BLOCK) {
- if (iseq->body->param.flags.has_opt == FALSE &&
- iseq->body->param.flags.has_post == FALSE &&
- iseq->body->param.flags.has_rest == FALSE &&
- iseq->body->param.flags.has_kw == FALSE &&
- iseq->body->param.flags.has_kwrest == FALSE) {
+ if (body->type == ISEQ_TYPE_BLOCK) {
+ if (body->param.flags.has_opt == FALSE &&
+ body->param.flags.has_post == FALSE &&
+ body->param.flags.has_rest == FALSE &&
+ body->param.flags.has_kw == FALSE &&
+ body->param.flags.has_kwrest == FALSE) {
- if (iseq->body->param.lead_num == 1 && last_comma == 0) {
+ if (body->param.lead_num == 1 && last_comma == 0) {
/* {|a|} */
- iseq->body->param.flags.ambiguous_param0 = TRUE;
+ body->param.flags.ambiguous_param0 = TRUE;
}
}
}
@@ -1545,27 +1955,71 @@ iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl)
static int
cdhash_cmp(VALUE val, VALUE lit)
{
- if (val == lit) return 0;
- if (SPECIAL_CONST_P(lit)) {
- return val != lit;
+ int tval, tlit;
+
+ if (val == lit) {
+ return 0;
+ }
+ else if ((tlit = OBJ_BUILTIN_TYPE(lit)) == -1) {
+ return val != lit;
+ }
+ else if ((tval = OBJ_BUILTIN_TYPE(val)) == -1) {
+ return -1;
+ }
+ else if (tlit != tval) {
+ return -1;
+ }
+ else if (tlit == T_SYMBOL) {
+ return val != lit;
}
- if (SPECIAL_CONST_P(val) || BUILTIN_TYPE(val) != BUILTIN_TYPE(lit)) {
- return -1;
+ else if (tlit == T_STRING) {
+ return rb_str_hash_cmp(lit, val);
}
- if (BUILTIN_TYPE(lit) == T_STRING) {
- return rb_str_hash_cmp(lit, val);
+ else if (tlit == T_BIGNUM) {
+ long x = FIX2LONG(rb_big_cmp(lit, val));
+
+ /* Given lit and val are both Bignum, x must be -1, 0, 1.
+ * There is no need to call rb_fix2int here. */
+ RUBY_ASSERT((x == 1) || (x == 0) || (x == -1));
+ return (int)x;
+ }
+ else if (tlit == T_FLOAT) {
+ return rb_float_cmp(lit, val);
+ }
+ else if (tlit == T_RATIONAL) {
+ const struct RRational *rat1 = RRATIONAL(val);
+ const struct RRational *rat2 = RRATIONAL(lit);
+ return cdhash_cmp(rat1->num, rat2->num) || cdhash_cmp(rat1->den, rat2->den);
+ }
+ else if (tlit == T_COMPLEX) {
+ const struct RComplex *comp1 = RCOMPLEX(val);
+ const struct RComplex *comp2 = RCOMPLEX(lit);
+ return cdhash_cmp(comp1->real, comp2->real) || cdhash_cmp(comp1->imag, comp2->imag);
+ }
+ else {
+ UNREACHABLE_RETURN(-1);
}
- return !rb_eql(lit, val);
}
static st_index_t
cdhash_hash(VALUE a)
{
- if (SPECIAL_CONST_P(a)) return (st_index_t)a;
- if (RB_TYPE_P(a, T_STRING)) return rb_str_hash(a);
- {
- VALUE hval = rb_hash(a);
- return (st_index_t)FIX2LONG(hval);
+ switch (OBJ_BUILTIN_TYPE(a)) {
+ case -1:
+ case T_SYMBOL:
+ return (st_index_t)a;
+ case T_STRING:
+ return rb_str_hash(a);
+ case T_BIGNUM:
+ return FIX2LONG(rb_big_hash(a));
+ case T_FLOAT:
+ return rb_dbl_long_hash(RFLOAT_VALUE(a));
+ case T_RATIONAL:
+ return rb_rational_hash(a);
+ case T_COMPLEX:
+ return rb_complex_hash(a);
+ default:
+ UNREACHABLE_RETURN(0);
}
}
@@ -1581,7 +2035,7 @@ struct cdhash_set_label_struct {
};
static int
-cdhash_set_label_i(VALUE key, VALUE val, void *ptr)
+cdhash_set_label_i(VALUE key, VALUE val, VALUE ptr)
{
struct cdhash_set_label_struct *data = (struct cdhash_set_label_struct *)ptr;
LABEL *lobj = (LABEL *)(val & ~1);
@@ -1610,11 +2064,11 @@ get_ivar_ic_value(rb_iseq_t *iseq,ID id)
}
#define BADINSN_DUMP(anchor, list, dest) \
- dump_disasm_list_with_cursor(&anchor->anchor, list, dest)
+ dump_disasm_list_with_cursor(FIRST_ELEMENT(anchor), list, dest)
#define BADINSN_ERROR \
(xfree(generated_iseq), \
- xfree(line_info_table), \
+ xfree(insns_info), \
BADINSN_DUMP(anchor, list, NULL), \
COMPILE_ERROR)
@@ -1644,7 +2098,7 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
sp = calc_sp_depth(sp, iobj);
if (sp < 0) {
BADINSN_DUMP(anchor, list, NULL);
- COMPILE_ERROR(iseq, iobj->line_no,
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
"argument stack underflow (%d)", sp);
return -1;
}
@@ -1652,7 +2106,7 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
stack_max = sp;
}
- line = iobj->line_no;
+ line = iobj->insn_info.line_no;
/* fprintf(stderr, "insn: %-16s, sp: %d\n", insn_name(iobj->insn_id), sp); */
operands = iobj->operands;
insn = iobj->insn_id;
@@ -1663,7 +2117,7 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
if (iobj->operand_size != len - 1) {
/* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */
BADINSN_DUMP(anchor, list, NULL);
- COMPILE_ERROR(iseq, iobj->line_no,
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
"operand size miss! (%d for %d)",
iobj->operand_size, len - 1);
return -1;
@@ -1675,13 +2129,17 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
LABEL *lobj = (LABEL *)operands[j];
if (!lobj->set) {
BADINSN_DUMP(anchor, list, NULL);
- COMPILE_ERROR(iseq, iobj->line_no,
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
"unknown label: "LABEL_FORMAT, lobj->label_no);
return -1;
}
if (lobj->sp == -1) {
lobj->sp = sp;
- }
+ } else if (lobj->sp != sp) {
+ debugs("%s:%d: sp inconsistency found but ignored (" LABEL_FORMAT " sp: %d, calculated sp: %d)\n",
+ RSTRING_PTR(rb_iseq_path(iseq)), line,
+ lobj->label_no, lobj->sp, sp);
+ }
}
}
break;
@@ -1693,11 +2151,16 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
lobj->sp = sp;
}
else {
+ if (lobj->sp != sp) {
+ debugs("%s:%d: sp inconsistency found but ignored (" LABEL_FORMAT " sp: %d, calculated sp: %d)\n",
+ RSTRING_PTR(rb_iseq_path(iseq)), line,
+ lobj->label_no, lobj->sp, sp);
+ }
sp = lobj->sp;
}
break;
}
- case ISEQ_ELEMENT_NONE:
+ case ISEQ_ELEMENT_TRACE:
{
/* ignore */
break;
@@ -1726,46 +2189,103 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
return stack_max;
}
+static int
+add_insn_info(struct iseq_insn_info_entry *insns_info, unsigned int *positions,
+ int insns_info_index, int code_index, const INSN *iobj)
+{
+ if (insns_info_index == 0 ||
+ insns_info[insns_info_index-1].line_no != iobj->insn_info.line_no ||
+ insns_info[insns_info_index-1].events != iobj->insn_info.events) {
+ insns_info[insns_info_index].line_no = iobj->insn_info.line_no;
+ insns_info[insns_info_index].events = iobj->insn_info.events;
+ positions[insns_info_index] = code_index;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int
+add_adjust_info(struct iseq_insn_info_entry *insns_info, unsigned int *positions,
+ int insns_info_index, int code_index, const ADJUST *adjust)
+{
+ if (insns_info_index > 0 ||
+ insns_info[insns_info_index-1].line_no != adjust->line_no) {
+ insns_info[insns_info_index].line_no = adjust->line_no;
+ insns_info[insns_info_index].events = 0;
+ positions[insns_info_index] = code_index;
+ return TRUE;
+ }
+ return FALSE;
+}
+
/**
ruby insn object list -> raw instruction sequence
*/
static int
iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
{
- struct iseq_line_info_entry *line_info_table;
- unsigned int last_line = 0;
+ VALUE iseqv = (VALUE)iseq;
+ struct iseq_insn_info_entry *insns_info;
+ struct rb_iseq_constant_body *const body = iseq->body;
+ unsigned int *positions;
LINK_ELEMENT *list;
VALUE *generated_iseq;
+ rb_event_flag_t events = 0;
+ long data = 0;
- int insn_num, code_index, line_info_index, sp = 0;
+ int insn_num, code_index, insns_info_index, sp = 0;
int stack_max = fix_sp_depth(iseq, anchor);
if (stack_max < 0) return COMPILE_NG;
/* fix label position */
- list = FIRST_ELEMENT(anchor);
insn_num = code_index = 0;
- while (list) {
+ for (list = FIRST_ELEMENT(anchor); list; list = list->next) {
switch (list->type) {
case ISEQ_ELEMENT_INSN:
{
INSN *iobj = (INSN *)list;
/* update sp */
sp = calc_sp_depth(sp, iobj);
- code_index += insn_data_length(iobj);
insn_num++;
+ events = iobj->insn_info.events |= events;
+ if (ISEQ_COVERAGE(iseq)) {
+ if (ISEQ_LINE_COVERAGE(iseq) && (events & RUBY_EVENT_COVERAGE_LINE) &&
+ !(rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES)) {
+ int line = iobj->insn_info.line_no;
+ if (line >= 1) {
+ RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), line - 1, INT2FIX(0));
+ }
+ }
+ if (ISEQ_BRANCH_COVERAGE(iseq) && (events & RUBY_EVENT_COVERAGE_BRANCH)) {
+ while (RARRAY_LEN(ISEQ_PC2BRANCHINDEX(iseq)) <= code_index) {
+ rb_ary_push(ISEQ_PC2BRANCHINDEX(iseq), Qnil);
+ }
+ RARRAY_ASET(ISEQ_PC2BRANCHINDEX(iseq), code_index, INT2FIX(data));
+ }
+ }
+ code_index += insn_data_length(iobj);
+ events = 0;
+ data = 0;
break;
}
case ISEQ_ELEMENT_LABEL:
{
LABEL *lobj = (LABEL *)list;
lobj->position = code_index;
+ if (lobj->sp != sp) {
+ debugs("%s: sp inconsistency found but ignored (" LABEL_FORMAT " sp: %d, calculated sp: %d)\n",
+ RSTRING_PTR(rb_iseq_path(iseq)),
+ lobj->label_no, lobj->sp, sp);
+ }
sp = lobj->sp;
break;
}
- case ISEQ_ELEMENT_NONE:
+ case ISEQ_ELEMENT_TRACE:
{
- /* ignore */
+ TRACE *trace = (TRACE *)list;
+ events |= trace->event;
+ if (trace->event & RUBY_EVENT_COVERAGE_BRANCH) data = trace->data;
break;
}
case ISEQ_ELEMENT_ADJUST:
@@ -1782,22 +2302,20 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
}
break;
}
+ default: break;
}
- list = list->next;
}
/* make instruction sequence */
generated_iseq = ALLOC_N(VALUE, code_index);
- line_info_table = ALLOC_N(struct iseq_line_info_entry, insn_num);
- iseq->body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, iseq->body->is_size);
- iseq->body->ci_entries = (struct rb_call_info *)ruby_xmalloc(sizeof(struct rb_call_info) * iseq->body->ci_size +
- sizeof(struct rb_call_info_with_kwarg) * iseq->body->ci_kw_size);
- iseq->body->cc_entries = ZALLOC_N(struct rb_call_cache, iseq->body->ci_size + iseq->body->ci_kw_size);
-
- ISEQ_COMPILE_DATA(iseq)->ci_index = ISEQ_COMPILE_DATA(iseq)->ci_kw_index = 0;
+ insns_info = ALLOC_N(struct iseq_insn_info_entry, insn_num);
+ positions = ALLOC_N(unsigned int, insn_num);
+ body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, body->is_size);
+ body->call_data = ZALLOC_N(struct rb_call_data, body->ci_size);
+ ISEQ_COMPILE_DATA(iseq)->ci_index = 0;
list = FIRST_ELEMENT(anchor);
- line_info_index = code_index = sp = 0;
+ insns_info_index = code_index = sp = 0;
while (list) {
switch (list->type) {
@@ -1840,93 +2358,79 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
rb_hash_rehash(map);
freeze_hide_obj(map);
generated_iseq[code_index + 1 + j] = map;
+ RB_OBJ_WRITTEN(iseq, Qundef, map);
+ FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
break;
}
case TS_LINDEX:
case TS_NUM: /* ulong */
generated_iseq[code_index + 1 + j] = FIX2INT(operands[j]);
break;
- case TS_ISEQ: /* iseq */
- {
- VALUE v = operands[j];
- generated_iseq[code_index + 1 + j] = v;
- break;
- }
case TS_VALUE: /* VALUE */
+ case TS_ISEQ: /* iseq */
{
VALUE v = operands[j];
generated_iseq[code_index + 1 + j] = v;
/* to mark ruby object */
- iseq_add_mark_object(iseq, v);
+ if (!SPECIAL_CONST_P(v)) {
+ RB_OBJ_WRITTEN(iseq, Qundef, v);
+ FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ }
break;
}
case TS_IC: /* inline cache */
+ case TS_ISE: /* inline storage entry */
+ case TS_IVC: /* inline ivar cache */
{
unsigned int ic_index = FIX2UINT(operands[j]);
- IC ic = (IC)&iseq->body->is_entries[ic_index];
- if (UNLIKELY(ic_index >= iseq->body->is_size)) {
- rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->body->is_size);
+ IC ic = (IC)&body->is_entries[ic_index];
+ if (UNLIKELY(ic_index >= body->is_size)) {
+ BADINSN_DUMP(anchor, &iobj->link, 0);
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
+ "iseq_set_sequence: ic_index overflow: index: %d, size: %d",
+ ic_index, body->is_size);
}
generated_iseq[code_index + 1 + j] = (VALUE)ic;
+ FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
break;
}
- case TS_CALLINFO: /* call info */
- {
- struct rb_call_info *base_ci = (struct rb_call_info *)operands[j];
- struct rb_call_info *ci;
-
- if (base_ci->flag & VM_CALL_KWARG) {
- struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&iseq->body->ci_entries[iseq->body->ci_size];
- struct rb_call_info_with_kwarg *ci_kw = &ci_kw_entries[ISEQ_COMPILE_DATA(iseq)->ci_kw_index++];
- *ci_kw = *((struct rb_call_info_with_kwarg *)base_ci);
- ci = (struct rb_call_info *)ci_kw;
- assert(ISEQ_COMPILE_DATA(iseq)->ci_kw_index <= iseq->body->ci_kw_size);
- }
- else {
- ci = &iseq->body->ci_entries[ISEQ_COMPILE_DATA(iseq)->ci_index++];
- *ci = *base_ci;
- assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= iseq->body->ci_size);
- }
-
- generated_iseq[code_index + 1 + j] = (VALUE)ci;
- break;
- }
- case TS_CALLCACHE:
- {
- struct rb_call_cache *cc = &iseq->body->cc_entries[ISEQ_COMPILE_DATA(iseq)->ci_index + ISEQ_COMPILE_DATA(iseq)->ci_kw_index - 1];
- generated_iseq[code_index + 1 + j] = (VALUE)cc;
- break;
- }
+ case TS_CALLDATA:
+ {
+ const struct rb_callinfo *source_ci = (const struct rb_callinfo *)operands[j];
+ struct rb_call_data *cd = &body->call_data[ISEQ_COMPILE_DATA(iseq)->ci_index++];
+ assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size);
+ cd->ci = source_ci;
+ cd->cc = vm_cc_empty();
+ generated_iseq[code_index + 1 + j] = (VALUE)cd;
+ break;
+ }
case TS_ID: /* ID */
generated_iseq[code_index + 1 + j] = SYM2ID(operands[j]);
break;
- case TS_GENTRY:
- {
- struct rb_global_entry *entry =
- (struct rb_global_entry *)(operands[j] & (~1));
- generated_iseq[code_index + 1 + j] = (VALUE)entry;
- }
- break;
case TS_FUNCPTR:
generated_iseq[code_index + 1 + j] = operands[j];
break;
+ case TS_BUILTIN:
+ generated_iseq[code_index + 1 + j] = operands[j];
+ break;
default:
- BADINSN_ERROR(iseq, iobj->line_no,
+ BADINSN_ERROR(iseq, iobj->insn_info.line_no,
"unknown operand type: %c", type);
return COMPILE_NG;
}
}
- if (last_line != iobj->line_no) {
- line_info_table[line_info_index].line_no = last_line = iobj->line_no;
- line_info_table[line_info_index].position = code_index;
- line_info_index++;
- }
+ if (add_insn_info(insns_info, positions, insns_info_index, code_index, iobj)) insns_info_index++;
code_index += len;
break;
}
case ISEQ_ELEMENT_LABEL:
{
LABEL *lobj = (LABEL *)list;
+ if (lobj->sp != sp) {
+ debugs("%s: sp inconsistency found but ignored (" LABEL_FORMAT " sp: %d, calculated sp: %d)\n",
+ RSTRING_PTR(rb_iseq_path(iseq)),
+ lobj->label_no, lobj->sp, sp);
+ }
sp = lobj->sp;
break;
}
@@ -1945,11 +2449,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
if (adjust->line_no != -1) {
const int diff = orig_sp - sp;
if (diff > 0) {
- if (last_line != (unsigned int)adjust->line_no) {
- line_info_table[line_info_index].line_no = last_line = adjust->line_no;
- line_info_table[line_info_index].position = code_index;
- line_info_index++;
- }
+ if (add_adjust_info(insns_info, positions, insns_info_index, code_index, adjust)) insns_info_index++;
}
if (diff > 1) {
generated_iseq[code_index++] = BIN(adjuststack);
@@ -1961,8 +2461,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
else if (diff < 0) {
int label_no = adjust->label ? adjust->label->label_no : -1;
xfree(generated_iseq);
- xfree(line_info_table);
- debug_list(anchor);
+ xfree(insns_info);
+ xfree(positions);
+ debug_list(anchor, list);
COMPILE_ERROR(iseq, adjust->line_no,
"iseq_set_sequence: adjust bug to %d %d < %d",
label_no, orig_sp, sp);
@@ -1978,16 +2479,19 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
list = list->next;
}
- iseq->body->iseq_encoded = (void *)generated_iseq;
- iseq->body->iseq_size = code_index;
- iseq->body->stack_max = stack_max;
+ body->iseq_encoded = (void *)generated_iseq;
+ body->iseq_size = code_index;
+ body->stack_max = stack_max;
/* get rid of memory leak when REALLOC failed */
- iseq->body->line_info_table = line_info_table;
+ body->insns_info.body = insns_info;
+ body->insns_info.positions = positions;
- REALLOC_N(line_info_table, struct iseq_line_info_entry, line_info_index);
- iseq->body->line_info_table = line_info_table;
- iseq->body->line_info_size = line_info_index;
+ REALLOC_N(insns_info, struct iseq_insn_info_entry, insns_info_index);
+ body->insns_info.body = insns_info;
+ REALLOC_N(positions, unsigned int, insns_info_index);
+ body->insns_info.positions = positions;
+ body->insns_info.size = insns_info_index;
return COMPILE_OK;
}
@@ -2011,25 +2515,23 @@ iseq_set_exception_table(rb_iseq_t *iseq)
unsigned int tlen, i;
struct iseq_catch_table_entry *entry;
+ iseq->body->catch_table = NULL;
+ if (NIL_P(ISEQ_COMPILE_DATA(iseq)->catch_table_ary)) return COMPILE_OK;
tlen = (int)RARRAY_LEN(ISEQ_COMPILE_DATA(iseq)->catch_table_ary);
- tptr = RARRAY_CONST_PTR(ISEQ_COMPILE_DATA(iseq)->catch_table_ary);
+ tptr = RARRAY_CONST_PTR_TRANSIENT(ISEQ_COMPILE_DATA(iseq)->catch_table_ary);
if (tlen > 0) {
struct iseq_catch_table *table = xmalloc(iseq_catch_table_bytes(tlen));
table->size = tlen;
for (i = 0; i < table->size; i++) {
- ptr = RARRAY_CONST_PTR(tptr[i]);
- entry = &table->entries[i];
+ ptr = RARRAY_CONST_PTR_TRANSIENT(tptr[i]);
+ entry = UNALIGNED_MEMBER_PTR(table, entries[i]);
entry->type = (enum catch_type)(ptr[0] & 0xffff);
entry->start = label_get_position((LABEL *)(ptr[1] & ~1));
entry->end = label_get_position((LABEL *)(ptr[2] & ~1));
entry->iseq = (rb_iseq_t *)ptr[3];
-
- /* register iseq as mark object */
- if (entry->iseq != 0) {
- iseq_add_mark_object(iseq, (VALUE)entry->iseq);
- }
+ RB_OBJ_WRITTEN(iseq, Qundef, entry->iseq);
/* stack depth */
if (ptr[4]) {
@@ -2051,9 +2553,6 @@ iseq_set_exception_table(rb_iseq_t *iseq)
iseq->body->catch_table = table;
RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, 0); /* free */
}
- else {
- iseq->body->catch_table = NULL;
- }
return COMPILE_OK;
}
@@ -2086,14 +2585,32 @@ get_destination_insn(INSN *iobj)
{
LABEL *lobj = (LABEL *)OPERAND_AT(iobj, 0);
LINK_ELEMENT *list;
+ rb_event_flag_t events = 0;
list = lobj->link.next;
while (list) {
- if (IS_INSN(list) || IS_ADJUST(list)) {
+ switch (list->type) {
+ case ISEQ_ELEMENT_INSN:
+ case ISEQ_ELEMENT_ADJUST:
+ goto found;
+ case ISEQ_ELEMENT_LABEL:
+ /* ignore */
break;
+ case ISEQ_ELEMENT_TRACE:
+ {
+ TRACE *trace = (TRACE *)list;
+ events |= trace->event;
+ }
+ break;
+ default: break;
}
list = list->next;
}
+ found:
+ if (list && IS_INSN(list)) {
+ INSN *iobj = (INSN *)list;
+ iobj->insn_info.events |= events;
+ }
return list;
}
@@ -2130,7 +2647,7 @@ unref_destination(INSN *iobj, int pos)
{
LABEL *lobj = (LABEL *)OPERAND_AT(iobj, pos);
--lobj->refcnt;
- if (!lobj->refcnt) REMOVE_ELEM(&lobj->link);
+ if (!lobj->refcnt) ELEM_REMOVE(&lobj->link);
}
static void
@@ -2142,33 +2659,61 @@ replace_destination(INSN *dobj, INSN *nobj)
--dl->refcnt;
++nl->refcnt;
OPERAND_AT(dobj, 0) = n;
- if (!dl->refcnt) REMOVE_ELEM(&dl->link);
+ if (!dl->refcnt) ELEM_REMOVE(&dl->link);
+}
+
+static LABEL*
+find_destination(INSN *i)
+{
+ int pos, len = insn_len(i->insn_id);
+ for (pos = 0; pos < len; ++pos) {
+ if (insn_op_types(i->insn_id)[pos] == TS_OFFSET) {
+ return (LABEL *)OPERAND_AT(i, pos);
+ }
+ }
+ return 0;
}
static int
remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
{
LINK_ELEMENT *first = i, *end;
+ int *unref_counts = 0, nlabels = ISEQ_COMPILE_DATA(iseq)->label_no;
if (!i) return 0;
- while (i) {
+ unref_counts = ALLOCA_N(int, nlabels);
+ MEMZERO(unref_counts, int, nlabels);
+ end = i;
+ do {
+ LABEL *lab;
if (IS_INSN(i)) {
- if (IS_INSN_ID(i, jump) || IS_INSN_ID(i, leave)) {
+ if (IS_INSN_ID(i, leave)) {
+ end = i;
break;
}
+ else if ((lab = find_destination((INSN *)i)) != 0) {
+ if (lab->unremovable) break;
+ unref_counts[lab->label_no]++;
+ }
}
else if (IS_LABEL(i)) {
- if (((LABEL *)i)->unremovable) return 0;
- if (((LABEL *)i)->refcnt > 0) {
+ lab = (LABEL *)i;
+ if (lab->unremovable) return 0;
+ if (lab->refcnt > unref_counts[lab->label_no]) {
if (i == first) return 0;
- i = i->prev;
break;
}
+ continue;
}
- else return 0;
- i = i->next;
- }
- end = i;
+ else if (IS_TRACE(i)) {
+ /* do nothing */
+ }
+ else if (IS_ADJUST(i)) {
+ LABEL *dest = ((ADJUST *)i)->label;
+ if (dest && dest->unremovable) return 0;
+ }
+ end = i;
+ } while ((i = i->next) != 0);
i = first;
do {
if (IS_INSN(i)) {
@@ -2180,16 +2725,13 @@ remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
case TS_OFFSET:
unref_destination((INSN *)i, pos);
break;
- case TS_CALLINFO:
- if (((struct rb_call_info *)OPERAND_AT(i, pos))->flag & VM_CALL_KWARG)
- --(body->ci_kw_size);
- else
- --(body->ci_size);
+ case TS_CALLDATA:
+ --(body->ci_size);
break;
}
}
}
- REMOVE_ELEM(i);
+ ELEM_REMOVE(i);
} while ((i != end) && (i = i->next) != 0);
return 1;
}
@@ -2199,10 +2741,10 @@ iseq_pop_newarray(rb_iseq_t *iseq, INSN *iobj)
{
switch (OPERAND_AT(iobj, 0)) {
case INT2FIX(0): /* empty array */
- REMOVE_ELEM(&iobj->link);
+ ELEM_REMOVE(&iobj->link);
return TRUE;
case INT2FIX(1): /* single element array */
- REMOVE_ELEM(&iobj->link);
+ ELEM_REMOVE(&iobj->link);
return FALSE;
default:
iobj->insn_id = BIN(adjuststack);
@@ -2211,12 +2753,136 @@ iseq_pop_newarray(rb_iseq_t *iseq, INSN *iobj)
}
static int
+is_frozen_putstring(INSN *insn, VALUE *op)
+{
+ if (IS_INSN_ID(insn, putstring)) {
+ *op = OPERAND_AT(insn, 0);
+ return 1;
+ }
+ else if (IS_INSN_ID(insn, putobject)) { /* frozen_string_literal */
+ *op = OPERAND_AT(insn, 0);
+ return RB_TYPE_P(*op, T_STRING);
+ }
+ return 0;
+}
+
+static int
+optimize_checktype(rb_iseq_t *iseq, INSN *iobj)
+{
+ /*
+ * putobject obj
+ * dup
+ * checktype T_XXX
+ * branchif l1
+ * l2:
+ * ...
+ * l1:
+ *
+ * => obj is a T_XXX
+ *
+ * putobject obj (T_XXX)
+ * jump L1
+ * L1:
+ *
+ * => obj is not a T_XXX
+ *
+ * putobject obj (T_XXX)
+ * jump L2
+ * L2:
+ */
+ int line;
+ INSN *niobj, *ciobj, *dup = 0;
+ LABEL *dest = 0;
+ VALUE type;
+
+ switch (INSN_OF(iobj)) {
+ case BIN(putstring):
+ type = INT2FIX(T_STRING);
+ break;
+ case BIN(putnil):
+ type = INT2FIX(T_NIL);
+ break;
+ case BIN(putobject):
+ type = INT2FIX(TYPE(OPERAND_AT(iobj, 0)));
+ break;
+ default: return FALSE;
+ }
+
+ ciobj = (INSN *)get_next_insn(iobj);
+ if (IS_INSN_ID(ciobj, jump)) {
+ ciobj = (INSN *)get_next_insn((INSN*)OPERAND_AT(ciobj, 0));
+ }
+ if (IS_INSN_ID(ciobj, dup)) {
+ ciobj = (INSN *)get_next_insn(dup = ciobj);
+ }
+ if (!ciobj || !IS_INSN_ID(ciobj, checktype)) return FALSE;
+ niobj = (INSN *)get_next_insn(ciobj);
+ if (!niobj) {
+ /* TODO: putobject true/false */
+ return FALSE;
+ }
+ switch (INSN_OF(niobj)) {
+ case BIN(branchif):
+ if (OPERAND_AT(ciobj, 0) == type) {
+ dest = (LABEL *)OPERAND_AT(niobj, 0);
+ }
+ break;
+ case BIN(branchunless):
+ if (OPERAND_AT(ciobj, 0) != type) {
+ dest = (LABEL *)OPERAND_AT(niobj, 0);
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ line = ciobj->insn_info.line_no;
+ if (!dest) {
+ if (niobj->link.next && IS_LABEL(niobj->link.next)) {
+ dest = (LABEL *)niobj->link.next; /* reuse label */
+ }
+ else {
+ dest = NEW_LABEL(line);
+ ELEM_INSERT_NEXT(&niobj->link, &dest->link);
+ }
+ }
+ INSERT_AFTER_INSN1(iobj, line, jump, dest);
+ LABEL_REF(dest);
+ if (!dup) INSERT_AFTER_INSN(iobj, line, pop);
+ return TRUE;
+}
+
+static const struct rb_callinfo *
+ci_flag_set(const rb_iseq_t *iseq, const struct rb_callinfo *ci, unsigned int add)
+{
+ const struct rb_callinfo *nci = vm_ci_new(vm_ci_mid(ci),
+ vm_ci_flag(ci) | add,
+ vm_ci_argc(ci),
+ vm_ci_kwarg(ci));
+ RB_OBJ_WRITTEN(iseq, ci, nci);
+ return nci;
+}
+
+static const struct rb_callinfo *
+ci_argc_set(const rb_iseq_t *iseq, const struct rb_callinfo *ci, int argc)
+{
+ const struct rb_callinfo *nci = vm_ci_new(vm_ci_mid(ci),
+ vm_ci_flag(ci),
+ argc,
+ vm_ci_kwarg(ci));
+ RB_OBJ_WRITTEN(iseq, ci, nci);
+ return nci;
+}
+
+static int
iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt)
{
- INSN *iobj = (INSN *)list;
+ INSN *const iobj = (INSN *)list;
+
again:
+ optimize_checktype(iseq, iobj);
+
if (IS_INSN_ID(iobj, jump)) {
- INSN *niobj, *diobj, *piobj;
+ INSN *niobj, *diobj, *piobj;
diobj = (INSN *)get_destination_insn(iobj);
niobj = (INSN *)get_next_insn(iobj);
@@ -2228,11 +2894,13 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
* LABEL:
*/
unref_destination(iobj, 0);
- REMOVE_ELEM(&iobj->link);
+ ELEM_REMOVE(&iobj->link);
return COMPILE_OK;
}
- else if (iobj != diobj && IS_INSN_ID(diobj, jump) &&
- OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0)) {
+ else if (iobj != diobj && IS_INSN(&diobj->link) &&
+ IS_INSN_ID(diobj, jump) &&
+ OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0) &&
+ diobj->insn_info.events == 0) {
/*
* useless jump elimination:
* jump LABEL1
@@ -2247,7 +2915,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
remove_unreachable_chunk(iseq, iobj->link.next);
goto again;
}
- else if (IS_INSN_ID(diobj, leave)) {
+ else if (IS_INSN_ID(diobj, leave)) {
/*
* jump LABEL
* ...
@@ -2259,20 +2927,21 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
* LABEL:
* leave
*/
- INSN *popiobj = new_insn_core(iseq, iobj->line_no,
- BIN(pop), 0, 0);
/* replace */
unref_destination(iobj, 0);
- iobj->insn_id = BIN(leave);
+ iobj->insn_id = BIN(leave);
iobj->operand_size = 0;
- INSERT_ELEM_NEXT(&iobj->link, &popiobj->link);
+ iobj->insn_info = diobj->insn_info;
goto again;
}
- else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 &&
+ else if (IS_INSN(iobj->link.prev) &&
+ (piobj = (INSN *)iobj->link.prev) &&
(IS_INSN_ID(piobj, branchif) ||
IS_INSN_ID(piobj, branchunless))) {
INSN *pdiobj = (INSN *)get_destination_insn(piobj);
if (niobj == pdiobj) {
+ int refcnt = IS_LABEL(piobj->link.next) ?
+ ((LABEL *)piobj->link.next)->refcnt : 0;
/*
* useless jump elimination (if/unless destination):
* if L1
@@ -2290,7 +2959,12 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
piobj->insn_id = (IS_INSN_ID(piobj, branchif))
? BIN(branchunless) : BIN(branchif);
replace_destination(piobj, iobj);
- REMOVE_ELEM(&iobj->link);
+ if (refcnt <= 1) {
+ ELEM_REMOVE(&iobj->link);
+ }
+ else {
+ /* TODO: replace other branch destinations too */
+ }
return COMPILE_OK;
}
else if (diobj == pdiobj) {
@@ -2307,9 +2981,9 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
* pop
* jump L1
*/
- INSN *popiobj = new_insn_core(iseq, iobj->line_no,
+ INSN *popiobj = new_insn_core(iseq, iobj->insn_info.line_no,
BIN(pop), 0, 0);
- REPLACE_ELEM(&piobj->link, &popiobj->link);
+ ELEM_REPLACE(&piobj->link, &popiobj->link);
}
}
if (remove_unreachable_chunk(iseq, iobj->link.next)) {
@@ -2327,24 +3001,23 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
* putobject "beg".."end"
*/
if (IS_INSN_ID(iobj, checkmatch)) {
- INSN *range = (INSN *)get_prev_insn(iobj);
- INSN *beg, *end;
+ INSN *range = (INSN *)get_prev_insn(iobj);
+ INSN *beg, *end;
+ VALUE str_beg, str_end;
if (range && IS_INSN_ID(range, newrange) &&
- (end = (INSN *)get_prev_insn(range)) != 0 &&
- IS_INSN_ID(end, putstring) &&
- (beg = (INSN *)get_prev_insn(end)) != 0 &&
- IS_INSN_ID(beg, putstring)) {
- VALUE str_beg = OPERAND_AT(beg, 0);
- VALUE str_end = OPERAND_AT(end, 0);
+ (end = (INSN *)get_prev_insn(range)) != 0 &&
+ is_frozen_putstring(end, &str_end) &&
+ (beg = (INSN *)get_prev_insn(end)) != 0 &&
+ is_frozen_putstring(beg, &str_beg)) {
int excl = FIX2INT(OPERAND_AT(range, 0));
VALUE lit_range = rb_range_new(str_beg, str_end, excl);
- iseq_add_mark_object_compile_time(iseq, lit_range);
- REMOVE_ELEM(&beg->link);
- REMOVE_ELEM(&end->link);
+ ELEM_REMOVE(&beg->link);
+ ELEM_REMOVE(&end->link);
range->insn_id = BIN(putobject);
OPERAND_AT(range, 0) = lit_range;
+ RB_OBJ_WRITTEN(iseq, Qundef, lit_range);
}
}
@@ -2364,105 +3037,135 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
* if L2
*/
INSN *nobj = (INSN *)get_destination_insn(iobj);
- INSN *pobj = (INSN *)iobj->link.prev;
- int prev_dup = 0;
- if (pobj) {
- if (!IS_INSN(&pobj->link))
- pobj = 0;
- else if (IS_INSN_ID(pobj, dup))
- prev_dup = 1;
- }
-
- for (;;) {
- if (IS_INSN_ID(nobj, jump)) {
- replace_destination(iobj, nobj);
- }
- else if (prev_dup && IS_INSN_ID(nobj, dup) &&
- !!(nobj = (INSN *)nobj->link.next) &&
- /* basic blocks, with no labels in the middle */
- nobj->insn_id == iobj->insn_id) {
- /*
- * dup
- * if L1
- * ...
- * L1:
- * dup
- * if L2
- * =>
- * dup
- * if L2
- * ...
- * L1:
- * dup
- * if L2
- */
- replace_destination(iobj, nobj);
- }
- else if (pobj) {
- /*
- * putnil
- * if L1
- * =>
- * # nothing
- *
- * putobject true
- * if L1
- * =>
- * jump L1
- *
- * putstring ".."
- * if L1
- * =>
- * jump L1
- *
- * putstring ".."
- * dup
- * if L1
- * =>
- * putstring ".."
- * jump L1
- *
- */
- int cond;
- if (prev_dup && IS_INSN(pobj->link.prev)) {
- pobj = (INSN *)pobj->link.prev;
- }
- if (IS_INSN_ID(pobj, putobject)) {
- cond = (IS_INSN_ID(iobj, branchif) ?
- OPERAND_AT(pobj, 0) != Qfalse :
- IS_INSN_ID(iobj, branchunless) ?
- OPERAND_AT(pobj, 0) == Qfalse :
- FALSE);
- }
- else if (IS_INSN_ID(pobj, putstring) ||
- IS_INSN_ID(pobj, duparray) ||
- IS_INSN_ID(pobj, newarray)) {
- cond = IS_INSN_ID(iobj, branchif);
- }
- else if (IS_INSN_ID(pobj, putnil)) {
- cond = !IS_INSN_ID(iobj, branchif);
- }
- else break;
- if (prev_dup || !IS_INSN_ID(pobj, newarray)) {
- REMOVE_ELEM(iobj->link.prev);
- }
- else if (!iseq_pop_newarray(iseq, pobj)) {
- pobj = new_insn_core(iseq, pobj->line_no, BIN(pop), 0, NULL);
- INSERT_ELEM_NEXT(&iobj->link, &pobj->link);
- }
- if (cond) {
- iobj->insn_id = BIN(jump);
- goto again;
- }
- else {
- unref_destination(iobj, 0);
- REMOVE_ELEM(&iobj->link);
- }
- break;
- }
- else break;
- nobj = (INSN *)get_destination_insn(nobj);
- }
+
+ /* This is super nasty hack!!!
+ *
+ * This jump-jump optimization may ignore event flags of the jump
+ * instruction being skipped. Actually, Line 2 TracePoint event
+ * is never fired in the following code:
+ *
+ * 1: raise if 1 == 2
+ * 2: while true
+ * 3: break
+ * 4: end
+ *
+ * This is critical for coverage measurement. [Bug #15980]
+ *
+ * This is a stopgap measure: stop the jump-jump optimization if
+ * coverage measurement is enabled and if the skipped instruction
+ * has any event flag.
+ *
+ * Note that, still, TracePoint Line event does not occur on Line 2.
+ * This should be fixed in future.
+ */
+ int stop_optimization =
+ ISEQ_COVERAGE(iseq) && ISEQ_LINE_COVERAGE(iseq) &&
+ nobj->insn_info.events;
+ if (!stop_optimization) {
+ INSN *pobj = (INSN *)iobj->link.prev;
+ int prev_dup = 0;
+ if (pobj) {
+ if (!IS_INSN(&pobj->link))
+ pobj = 0;
+ else if (IS_INSN_ID(pobj, dup))
+ prev_dup = 1;
+ }
+
+ for (;;) {
+ if (IS_INSN(&nobj->link) && IS_INSN_ID(nobj, jump)) {
+ replace_destination(iobj, nobj);
+ }
+ else if (prev_dup && IS_INSN_ID(nobj, dup) &&
+ !!(nobj = (INSN *)nobj->link.next) &&
+ /* basic blocks, with no labels in the middle */
+ nobj->insn_id == iobj->insn_id) {
+ /*
+ * dup
+ * if L1
+ * ...
+ * L1:
+ * dup
+ * if L2
+ * =>
+ * dup
+ * if L2
+ * ...
+ * L1:
+ * dup
+ * if L2
+ */
+ replace_destination(iobj, nobj);
+ }
+ else if (pobj) {
+ /*
+ * putnil
+ * if L1
+ * =>
+ * # nothing
+ *
+ * putobject true
+ * if L1
+ * =>
+ * jump L1
+ *
+ * putstring ".."
+ * if L1
+ * =>
+ * jump L1
+ *
+ * putstring ".."
+ * dup
+ * if L1
+ * =>
+ * putstring ".."
+ * jump L1
+ *
+ */
+ int cond;
+ if (prev_dup && IS_INSN(pobj->link.prev)) {
+ pobj = (INSN *)pobj->link.prev;
+ }
+ if (IS_INSN_ID(pobj, putobject)) {
+ cond = (IS_INSN_ID(iobj, branchif) ?
+ OPERAND_AT(pobj, 0) != Qfalse :
+ IS_INSN_ID(iobj, branchunless) ?
+ OPERAND_AT(pobj, 0) == Qfalse :
+ FALSE);
+ }
+ else if (IS_INSN_ID(pobj, putstring) ||
+ IS_INSN_ID(pobj, duparray) ||
+ IS_INSN_ID(pobj, newarray)) {
+ cond = IS_INSN_ID(iobj, branchif);
+ }
+ else if (IS_INSN_ID(pobj, putnil)) {
+ cond = !IS_INSN_ID(iobj, branchif);
+ }
+ else break;
+ if (prev_dup || !IS_INSN_ID(pobj, newarray)) {
+ ELEM_REMOVE(iobj->link.prev);
+ }
+ else if (!iseq_pop_newarray(iseq, pobj)) {
+ pobj = new_insn_core(iseq, pobj->insn_info.line_no, BIN(pop), 0, NULL);
+ ELEM_INSERT_PREV(&iobj->link, &pobj->link);
+ }
+ if (cond) {
+ if (prev_dup) {
+ pobj = new_insn_core(iseq, pobj->insn_info.line_no, BIN(putnil), 0, NULL);
+ ELEM_INSERT_NEXT(&iobj->link, &pobj->link);
+ }
+ iobj->insn_id = BIN(jump);
+ goto again;
+ }
+ else {
+ unref_destination(iobj, 0);
+ ELEM_REMOVE(&iobj->link);
+ }
+ break;
+ }
+ else break;
+ nobj = (INSN *)get_destination_insn(nobj);
+ }
+ }
}
if (IS_INSN_ID(iobj, pop)) {
@@ -2477,14 +3180,33 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
enum ruby_vminsn_type previ = ((INSN *)prev)->insn_id;
if (previ == BIN(putobject) || previ == BIN(putnil) ||
previ == BIN(putself) || previ == BIN(putstring) ||
+ previ == BIN(dup) ||
+ previ == BIN(getlocal) ||
+ previ == BIN(getblockparam) ||
+ previ == BIN(getblockparamproxy) ||
+ /* getinstancevariable may issue a warning */
previ == BIN(duparray)) {
/* just push operand or static value and pop soon, no
* side effects */
- REMOVE_ELEM(prev);
- REMOVE_ELEM(&iobj->link);
+ ELEM_REMOVE(prev);
+ ELEM_REMOVE(&iobj->link);
}
else if (previ == BIN(newarray) && iseq_pop_newarray(iseq, (INSN*)prev)) {
- REMOVE_ELEM(&iobj->link);
+ ELEM_REMOVE(&iobj->link);
+ }
+ else if (previ == BIN(concatarray)) {
+ INSN *piobj = (INSN *)prev;
+ INSERT_BEFORE_INSN1(piobj, piobj->insn_info.line_no, splatarray, Qfalse);
+ INSN_OF(piobj) = BIN(pop);
+ }
+ else if (previ == BIN(concatstrings)) {
+ if (OPERAND_AT(prev, 0) == INT2FIX(1)) {
+ ELEM_REMOVE(prev);
+ }
+ else {
+ ELEM_REMOVE(&iobj->link);
+ INSN_OF(prev) = BIN(adjuststack);
+ }
}
}
}
@@ -2505,15 +3227,72 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
LINK_ELEMENT *next = iobj->link.next;
if (IS_INSN(next) && IS_INSN_ID(next, splatarray)) {
/* remove splatarray following always-array insn */
- REMOVE_ELEM(next);
+ ELEM_REMOVE(next);
}
}
if (IS_INSN_ID(iobj, tostring)) {
LINK_ELEMENT *next = iobj->link.next;
+ /*
+ * tostring
+ * concatstrings 1
+ * =>
+ * tostring
+ */
if (IS_INSN(next) && IS_INSN_ID(next, concatstrings) &&
OPERAND_AT(next, 0) == INT2FIX(1)) {
- REMOVE_ELEM(next);
+ ELEM_REMOVE(next);
+ }
+ }
+
+ if (IS_INSN_ID(iobj, putstring) ||
+ (IS_INSN_ID(iobj, putobject) && RB_TYPE_P(OPERAND_AT(iobj, 0), T_STRING))) {
+ /*
+ * putstring ""
+ * concatstrings N
+ * =>
+ * concatstrings N-1
+ */
+ if (IS_NEXT_INSN_ID(&iobj->link, concatstrings) &&
+ RSTRING_LEN(OPERAND_AT(iobj, 0)) == 0) {
+ INSN *next = (INSN *)iobj->link.next;
+ if ((OPERAND_AT(next, 0) = FIXNUM_INC(OPERAND_AT(next, 0), -1)) == INT2FIX(1)) {
+ ELEM_REMOVE(&next->link);
+ }
+ ELEM_REMOVE(&iobj->link);
+ }
+ }
+
+ if (IS_INSN_ID(iobj, concatstrings)) {
+ /*
+ * concatstrings N
+ * concatstrings M
+ * =>
+ * concatstrings N+M-1
+ */
+ LINK_ELEMENT *next = iobj->link.next;
+ INSN *jump = 0;
+ if (IS_INSN(next) && IS_INSN_ID(next, jump))
+ next = get_destination_insn(jump = (INSN *)next);
+ if (IS_INSN(next) && IS_INSN_ID(next, concatstrings)) {
+ int n = FIX2INT(OPERAND_AT(iobj, 0)) + FIX2INT(OPERAND_AT(next, 0)) - 1;
+ OPERAND_AT(iobj, 0) = INT2FIX(n);
+ if (jump) {
+ LABEL *label = ((LABEL *)OPERAND_AT(jump, 0));
+ if (!--label->refcnt) {
+ ELEM_REMOVE(&label->link);
+ }
+ else {
+ label = NEW_LABEL(0);
+ OPERAND_AT(jump, 0) = (VALUE)label;
+ }
+ label->refcnt++;
+ ELEM_INSERT_NEXT(next, &label->link);
+ CHECK(iseq_peephole_optimize(iseq, get_next_insn(jump), do_tailcallopt));
+ }
+ else {
+ ELEM_REMOVE(next);
+ }
}
}
@@ -2539,7 +3318,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
switch (INSN_OF(next)) {
case BIN(nop):
- /*case BIN(trace):*/
next = next->next;
break;
case BIN(jump):
@@ -2551,6 +3329,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
break;
case BIN(leave):
piobj = iobj;
+ /* fall through */
default:
next = NULL;
break;
@@ -2559,28 +3338,69 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
if (piobj) {
- struct rb_call_info *ci = (struct rb_call_info *)piobj->operands[0];
- if (IS_INSN_ID(piobj, send) || IS_INSN_ID(piobj, invokesuper)) {
- if (piobj->operands[2] == 0) { /* no blockiseq */
- ci->flag |= VM_CALL_TAILCALL;
+ const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(piobj, 0);
+ if (IS_INSN_ID(piobj, send) ||
+ IS_INSN_ID(piobj, invokesuper)) {
+ if (OPERAND_AT(piobj, 1) == 0) { /* no blockiseq */
+ ci = ci_flag_set(iseq, ci, VM_CALL_TAILCALL);
+ OPERAND_AT(piobj, 0) = (VALUE)ci;
+ RB_OBJ_WRITTEN(iseq, Qundef, ci);
}
}
else {
- ci->flag |= VM_CALL_TAILCALL;
+ ci = ci_flag_set(iseq, ci, VM_CALL_TAILCALL);
+ OPERAND_AT(piobj, 0) = (VALUE)ci;
+ RB_OBJ_WRITTEN(iseq, Qundef, ci);
}
}
}
- #define IS_TRACE_LINE(insn) \
- (IS_INSN_ID(insn, trace) && \
- OPERAND_AT(insn, 0) == INT2FIX(RUBY_EVENT_LINE))
- if (IS_TRACE_LINE(iobj) && iobj->link.prev && IS_INSN(iobj->link.prev)) {
- INSN *piobj = (INSN *)iobj->link.prev;
- if (IS_TRACE_LINE(piobj)) {
- REMOVE_ELEM(iobj->link.prev);
+ if (IS_INSN_ID(iobj, dup)) {
+ if (IS_NEXT_INSN_ID(&iobj->link, setlocal)) {
+ LINK_ELEMENT *set1 = iobj->link.next, *set2 = NULL;
+ if (IS_NEXT_INSN_ID(set1, setlocal)) {
+ set2 = set1->next;
+ if (OPERAND_AT(set1, 0) == OPERAND_AT(set2, 0) &&
+ OPERAND_AT(set1, 1) == OPERAND_AT(set2, 1)) {
+ ELEM_REMOVE(set1);
+ ELEM_REMOVE(&iobj->link);
+ }
+ }
+ else if (IS_NEXT_INSN_ID(set1, dup) &&
+ IS_NEXT_INSN_ID(set1->next, setlocal)) {
+ set2 = set1->next->next;
+ if (OPERAND_AT(set1, 0) == OPERAND_AT(set2, 0) &&
+ OPERAND_AT(set1, 1) == OPERAND_AT(set2, 1)) {
+ ELEM_REMOVE(set1->next);
+ ELEM_REMOVE(set2);
+ }
+ }
+ }
+ }
+
+ if (IS_INSN_ID(iobj, getlocal)) {
+ LINK_ELEMENT *niobj = &iobj->link;
+ if (IS_NEXT_INSN_ID(niobj, dup)) {
+ niobj = niobj->next;
+ }
+ if (IS_NEXT_INSN_ID(niobj, setlocal)) {
+ LINK_ELEMENT *set1 = niobj->next;
+ if (OPERAND_AT(iobj, 0) == OPERAND_AT(set1, 0) &&
+ OPERAND_AT(iobj, 1) == OPERAND_AT(set1, 1)) {
+ ELEM_REMOVE(set1);
+ ELEM_REMOVE(niobj);
+ }
}
}
+ if (IS_INSN_ID(iobj, opt_invokebuiltin_delegate)) {
+ if (IS_TRACE(iobj->link.next)) {
+ if (IS_NEXT_INSN_ID(iobj->link.next, leave)) {
+ iobj->insn_id = BIN(opt_invokebuiltin_delegate_leave);
+ }
+ }
+ }
+
return COMPILE_OK;
}
@@ -2592,12 +3412,10 @@ insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
if (insn_id == BIN(opt_neq)) {
VALUE *old_operands = iobj->operands;
- iobj->operand_size = 4;
- iobj->operands = (VALUE *)compile_data_alloc(iseq, iobj->operand_size * sizeof(VALUE));
- iobj->operands[0] = old_operands[0];
- iobj->operands[1] = Qfalse; /* CALL_CACHE */
- iobj->operands[2] = (VALUE)new_callinfo(iseq, idEq, 1, 0, NULL, FALSE);
- iobj->operands[3] = Qfalse; /* CALL_CACHE */
+ iobj->operand_size = 2;
+ iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE));
+ iobj->operands[0] = (VALUE)new_callinfo(iseq, idEq, 1, 0, NULL, FALSE);
+ iobj->operands[1] = old_operands[0];
}
return COMPILE_OK;
@@ -2613,16 +3431,16 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
*/
INSN *niobj = (INSN *)iobj->link.next;
if (IS_INSN_ID(niobj, send)) {
- struct rb_call_info *ci = (struct rb_call_info *)OPERAND_AT(niobj, 0);
- if ((ci->flag & VM_CALL_ARGS_SIMPLE) && ci->orig_argc == 0) {
- switch (ci->mid) {
+ const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(niobj, 0);
+ if ((vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) && vm_ci_argc(ci) == 0) {
+ switch (vm_ci_mid(ci)) {
case idMax:
iobj->insn_id = BIN(opt_newarray_max);
- REMOVE_ELEM(&niobj->link);
+ ELEM_REMOVE(&niobj->link);
return COMPILE_OK;
case idMin:
iobj->insn_id = BIN(opt_newarray_min);
- REMOVE_ELEM(&niobj->link);
+ ELEM_REMOVE(&niobj->link);
return COMPILE_OK;
}
}
@@ -2630,23 +3448,24 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
}
if (IS_INSN_ID(iobj, send)) {
- struct rb_call_info *ci = (struct rb_call_info *)OPERAND_AT(iobj, 0);
- const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(iobj, 2);
+ const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(iobj, 0);
+ const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(iobj, 1);
#define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt))
- if (ci->flag & VM_CALL_ARGS_SIMPLE) {
- switch (ci->orig_argc) {
+ if (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) {
+ switch (vm_ci_argc(ci)) {
case 0:
- switch (ci->mid) {
+ switch (vm_ci_mid(ci)) {
case idLength: SP_INSN(length); return COMPILE_OK;
case idSize: SP_INSN(size); return COMPILE_OK;
case idEmptyP: SP_INSN(empty_p);return COMPILE_OK;
+ case idNilP: SP_INSN(nil_p); return COMPILE_OK;
case idSucc: SP_INSN(succ); return COMPILE_OK;
case idNot: SP_INSN(not); return COMPILE_OK;
}
break;
case 1:
- switch (ci->mid) {
+ switch (vm_ci_mid(ci)) {
case idPLUS: SP_INSN(plus); return COMPILE_OK;
case idMINUS: SP_INSN(minus); return COMPILE_OK;
case idMULT: SP_INSN(mult); return COMPILE_OK;
@@ -2654,23 +3473,26 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
case idMOD: SP_INSN(mod); return COMPILE_OK;
case idEq: SP_INSN(eq); return COMPILE_OK;
case idNeq: SP_INSN(neq); return COMPILE_OK;
+ case idEqTilde:SP_INSN(regexpmatch2);return COMPILE_OK;
case idLT: SP_INSN(lt); return COMPILE_OK;
case idLE: SP_INSN(le); return COMPILE_OK;
case idGT: SP_INSN(gt); return COMPILE_OK;
case idGE: SP_INSN(ge); return COMPILE_OK;
case idLTLT: SP_INSN(ltlt); return COMPILE_OK;
case idAREF: SP_INSN(aref); return COMPILE_OK;
+ case idAnd: SP_INSN(and); return COMPILE_OK;
+ case idOr: SP_INSN(or); return COMPILE_OK;
}
break;
case 2:
- switch (ci->mid) {
+ switch (vm_ci_mid(ci)) {
case idASET: SP_INSN(aset); return COMPILE_OK;
}
break;
}
}
- if ((ci->flag & VM_CALL_ARGS_BLOCKARG) == 0 && blockiseq == NULL) {
+ if ((vm_ci_flag(ci) & VM_CALL_ARGS_BLOCKARG) == 0 && blockiseq == NULL) {
iobj->insn_id = BIN(opt_send_without_block);
iobj->operand_size = insn_len(iobj->insn_id) - 1;
}
@@ -2758,8 +3580,7 @@ new_unified_insn(rb_iseq_t *iseq,
}
if (argc > 0) {
- ptr = operands =
- (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * argc);
+ ptr = operands = compile_data_alloc2(iseq, sizeof(VALUE), argc);
}
/* copy operands */
@@ -2771,7 +3592,7 @@ new_unified_insn(rb_iseq_t *iseq,
list = list->next;
}
- return new_insn_core(iseq, iobj->line_no, insn_id, argc, operands);
+ return new_insn_core(iseq, iobj->insn_info.line_no, insn_id, argc, operands);
}
#endif
@@ -2855,7 +3676,7 @@ insn_set_sc_state(rb_iseq_t *iseq, const LINK_ELEMENT *anchor, INSN *iobj, int s
if (lobj->sc_state != 0) {
if (lobj->sc_state != nstate) {
BADINSN_DUMP(anchor, iobj, lobj);
- COMPILE_ERROR(iseq, iobj->line_no,
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
"insn_set_sc_state error: %d at "LABEL_FORMAT
", %d expected\n",
lobj->sc_state, lobj->label_no, nstate);
@@ -2926,7 +3747,7 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
new_insn_body(iseq, 0, BIN(reput), 0);
/* replace this insn */
- REPLACE_ELEM(list, (LINK_ELEMENT *)rpobj);
+ ELEM_REPLACE(list, (LINK_ELEMENT *)rpobj);
list = (LINK_ELEMENT *)rpobj;
goto redo_point;
}
@@ -2937,7 +3758,7 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
if (state == SCS_AB || state == SCS_BA) {
state = (state == SCS_AB ? SCS_BA : SCS_AB);
- REMOVE_ELEM(list);
+ ELEM_REMOVE(list);
list = list->next;
goto redo_point;
}
@@ -2959,12 +3780,12 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
case SCS_XX:
goto normal_insn;
default:
- COMPILE_ERROR(iseq, iobj->line_no,
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
"unreachable");
return COMPILE_NG;
}
/* remove useless pop */
- REMOVE_ELEM(list);
+ ELEM_REMOVE(list);
list = list->next;
goto redo_point;
}
@@ -2992,9 +3813,32 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
}
static int
-compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int *cntp)
+all_string_result_p(const NODE *node)
{
- NODE *list = node->nd_next;
+ if (!node) return FALSE;
+ switch (nd_type(node)) {
+ case NODE_STR: case NODE_DSTR:
+ return TRUE;
+ case NODE_IF: case NODE_UNLESS:
+ if (!node->nd_body || !node->nd_else) return FALSE;
+ if (all_string_result_p(node->nd_body))
+ return all_string_result_p(node->nd_else);
+ return FALSE;
+ case NODE_AND: case NODE_OR:
+ if (!node->nd_2nd)
+ return all_string_result_p(node->nd_1st);
+ if (!all_string_result_p(node->nd_1st))
+ return FALSE;
+ return all_string_result_p(node->nd_2nd);
+ default:
+ return FALSE;
+ }
+}
+
+static int
+compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int *cntp)
+{
+ const NODE *list = node->nd_next;
VALUE lit = node->nd_lit;
LINK_ELEMENT *first_lit = 0;
int cnt = 0;
@@ -3007,26 +3851,28 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int
rb_builtin_type_name(TYPE(lit)));
return COMPILE_NG;
}
- lit = node->nd_lit = rb_fstring(lit);
+ lit = rb_fstring(lit);
ADD_INSN1(ret, nd_line(node), putobject, lit);
+ RB_OBJ_WRITTEN(iseq, Qundef, lit);
if (RSTRING_LEN(lit) == 0) first_lit = LAST_ELEMENT(ret);
}
while (list) {
- node = list->nd_head;
- if (nd_type(node) == NODE_STR) {
- node->nd_lit = rb_fstring(node->nd_lit);
- ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
+ const NODE *const head = list->nd_head;
+ if (nd_type(head) == NODE_STR) {
+ lit = rb_fstring(head->nd_lit);
+ ADD_INSN1(ret, nd_line(head), putobject, lit);
+ RB_OBJ_WRITTEN(iseq, Qundef, lit);
lit = Qnil;
}
else {
- CHECK(COMPILE(ret, "each string", node));
+ CHECK(COMPILE(ret, "each string", head));
}
cnt++;
list = list->nd_next;
}
if (NIL_P(lit) && first_lit) {
- REMOVE_ELEM(first_lit);
+ ELEM_REMOVE(first_lit);
--cnt;
}
*cntp = cnt;
@@ -3035,16 +3881,24 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int
}
static int
-compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
+compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
{
int cnt;
- CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
- ADD_INSN1(ret, nd_line(node), concatstrings, INT2FIX(cnt));
+ if (!node->nd_next) {
+ VALUE lit = rb_fstring(node->nd_lit);
+ const int line = (int)nd_line(node);
+ ADD_INSN1(ret, line, putstring, lit);
+ RB_OBJ_WRITTEN(iseq, Qundef, lit);
+ }
+ else {
+ CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
+ ADD_INSN1(ret, nd_line(node), concatstrings, INT2FIX(cnt));
+ }
return COMPILE_OK;
}
static int
-compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
+compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
{
int cnt;
CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
@@ -3053,7 +3907,7 @@ compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
}
static int
-compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int again,
+compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int again,
LABEL *then_label, LABEL *else_label)
{
const int line = nd_line(node);
@@ -3086,7 +3940,7 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int again
}
static int
-compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *cond,
+compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
LABEL *then_label, LABEL *else_label)
{
again:
@@ -3096,7 +3950,10 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *cond,
LABEL *label = NEW_LABEL(nd_line(cond));
CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, label,
else_label));
- if (!label->refcnt) break;
+ if (!label->refcnt) {
+ ADD_INSN(ret, nd_line(cond), putnil);
+ break;
+ }
ADD_LABEL(ret, label);
cond = cond->nd_2nd;
goto again;
@@ -3106,7 +3963,10 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *cond,
LABEL *label = NEW_LABEL(nd_line(cond));
CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, then_label,
label));
- if (!label->refcnt) break;
+ if (!label->refcnt) {
+ ADD_INSN(ret, nd_line(cond), putnil);
+ break;
+ }
ADD_LABEL(ret, label);
cond = cond->nd_2nd;
goto again;
@@ -3114,58 +3974,81 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *cond,
case NODE_LIT: /* NODE_LIT is always true */
case NODE_TRUE:
case NODE_STR:
- case NODE_ZARRAY:
+ case NODE_ZLIST:
case NODE_LAMBDA:
/* printf("useless condition eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
ADD_INSNL(ret, nd_line(cond), jump, then_label);
- break;
+ return COMPILE_OK;
case NODE_FALSE:
case NODE_NIL:
/* printf("useless condition eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
ADD_INSNL(ret, nd_line(cond), jump, else_label);
- break;
+ return COMPILE_OK;
+ case NODE_LIST:
+ case NODE_ARGSCAT:
+ case NODE_DREGX:
+ case NODE_DSTR:
+ CHECK(COMPILE_POPPED(ret, "branch condition", cond));
+ ADD_INSNL(ret, nd_line(cond), jump, then_label);
+ return COMPILE_OK;
case NODE_FLIP2:
CHECK(compile_flip_flop(iseq, ret, cond, TRUE, then_label, else_label));
- break;
+ return COMPILE_OK;
case NODE_FLIP3:
CHECK(compile_flip_flop(iseq, ret, cond, FALSE, then_label, else_label));
- break;
+ return COMPILE_OK;
case NODE_DEFINED:
CHECK(compile_defined_expr(iseq, ret, cond, Qfalse));
- goto branch;
+ break;
default:
CHECK(COMPILE(ret, "branch condition", cond));
- branch:
- ADD_INSNL(ret, nd_line(cond), branchunless, else_label);
- ADD_INSNL(ret, nd_line(cond), jump, then_label);
- break;
+ break;
}
+
+ ADD_INSNL(ret, nd_line(cond), branchunless, else_label);
+ ADD_INSNL(ret, nd_line(cond), jump, then_label);
return COMPILE_OK;
}
+#define HASH_BRACE 1
+
+static int
+keyword_node_p(const NODE *const node)
+{
+ return nd_type(node) == NODE_HASH && (node->nd_brace & HASH_BRACE) != HASH_BRACE;
+}
+
static int
-compile_array_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
+compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
const NODE *const root_node,
- struct rb_call_info_kw_arg **const kw_arg_ptr,
+ struct rb_callinfo_kwarg **const kw_arg_ptr,
unsigned int *flag)
{
if (kw_arg_ptr == NULL) return FALSE;
- if (nd_type(root_node) == NODE_HASH && root_node->nd_head && nd_type(root_node->nd_head) == NODE_ARRAY) {
- NODE *node = root_node->nd_head;
+ if (root_node->nd_head && nd_type(root_node->nd_head) == NODE_LIST) {
+ const NODE *node = root_node->nd_head;
+ int seen_nodes = 0;
while (node) {
- NODE *key_node = node->nd_head;
+ const NODE *key_node = node->nd_head;
+ seen_nodes++;
- assert(nd_type(node) == NODE_ARRAY);
- if (!key_node) {
- if (flag && !root_node->nd_alen) *flag |= VM_CALL_KW_SPLAT;
- return FALSE;
- }
- else if (nd_type(key_node) == NODE_LIT && RB_TYPE_P(key_node->nd_lit, T_SYMBOL)) {
+ assert(nd_type(node) == NODE_LIST);
+ if (key_node && nd_type(key_node) == NODE_LIT && RB_TYPE_P(key_node->nd_lit, T_SYMBOL)) {
/* can be keywords */
}
else {
+ if (flag) {
+ *flag |= VM_CALL_KW_SPLAT;
+ if (seen_nodes > 1 || node->nd_next->nd_next) {
+ /* A new hash will be created for the keyword arguments
+ * in this case, so mark the method as passing mutable
+ * keyword splat.
+ */
+ *flag |= VM_CALL_KW_SPLAT_MUT;
+ }
+ }
return FALSE;
}
node = node->nd_next; /* skip value node */
@@ -3176,7 +4059,8 @@ compile_array_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
node = root_node->nd_head;
{
int len = (int)node->nd_alen / 2;
- struct rb_call_info_kw_arg *kw_arg = (struct rb_call_info_kw_arg *)ruby_xmalloc(sizeof(struct rb_call_info_kw_arg) + sizeof(VALUE) * (len - 1));
+ struct rb_callinfo_kwarg *kw_arg =
+ rb_xmalloc_mul_add(len, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
VALUE *keywords = kw_arg->keywords;
int i = 0;
kw_arg->keyword_len = len;
@@ -3184,10 +4068,10 @@ compile_array_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
*kw_arg_ptr = kw_arg;
for (i=0; node != NULL; i++, node = node->nd_next->nd_next) {
- NODE *key_node = node->nd_head;
- NODE *val_node = node->nd_next->nd_head;
+ const NODE *key_node = node->nd_head;
+ const NODE *val_node = node->nd_next->nd_head;
keywords[i] = key_node->nd_lit;
- COMPILE(ret, "keyword values", val_node);
+ NO_CHECK(COMPILE(ret, "keyword values", val_node));
}
assert(i == len);
return TRUE;
@@ -3196,14 +4080,35 @@ compile_array_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
return FALSE;
}
-enum compile_array_type_t {
- COMPILE_ARRAY_TYPE_ARRAY,
- COMPILE_ARRAY_TYPE_HASH,
- COMPILE_ARRAY_TYPE_ARGS
-};
+static int
+compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node,
+ struct rb_callinfo_kwarg **keywords_ptr, unsigned int *flag)
+{
+ int len = 0;
+
+ for (; node; len++, node = node->nd_next) {
+ if (CPDEBUG > 0) {
+ EXPECT_NODE("compile_args", node, NODE_LIST, -1);
+ }
+
+ if (node->nd_next == NULL && keyword_node_p(node->nd_head)) { /* last node */
+ if (compile_keyword_arg(iseq, ret, node->nd_head, keywords_ptr, flag)) {
+ len--;
+ }
+ else {
+ compile_hash(iseq, ret, node->nd_head, TRUE, FALSE);
+ }
+ }
+ else {
+ NO_CHECK(COMPILE_(ret, "array element", node->nd_head, FALSE));
+ }
+ }
+
+ return len;
+}
static inline int
-static_literal_node_p(NODE *node)
+static_literal_node_p(const NODE *node, const rb_iseq_t *iseq)
{
node = node->nd_head;
switch (nd_type(node)) {
@@ -3212,13 +4117,15 @@ static_literal_node_p(NODE *node)
case NODE_TRUE:
case NODE_FALSE:
return TRUE;
+ case NODE_STR:
+ return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal;
default:
return FALSE;
}
}
static inline VALUE
-static_literal_value(NODE *node)
+static_literal_value(const NODE *node, rb_iseq_t *iseq)
{
node = node->nd_head;
switch (nd_type(node)) {
@@ -3228,180 +4135,349 @@ static_literal_value(NODE *node)
return Qtrue;
case NODE_FALSE:
return Qfalse;
+ case NODE_STR:
+ if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
+ VALUE lit;
+ VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX((int)nd_line(node)));
+ lit = rb_str_dup(node->nd_lit);
+ rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
+ return rb_str_freeze(lit);
+ }
+ else {
+ return rb_fstring(node->nd_lit);
+ }
default:
return node->nd_lit;
}
}
static int
-compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE* node_root,
- enum compile_array_type_t type, struct rb_call_info_kw_arg **keywords_ptr,
- unsigned int *flag, int popped)
+compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped)
{
- NODE *node = node_root;
int line = (int)nd_line(node);
- int len = 0;
- if (nd_type(node) == NODE_ZARRAY) {
+ if (nd_type(node) == NODE_ZLIST) {
if (!popped) {
- switch (type) {
- case COMPILE_ARRAY_TYPE_ARRAY: ADD_INSN1(ret, line, newarray, INT2FIX(0)); break;
- case COMPILE_ARRAY_TYPE_HASH: ADD_INSN1(ret, line, newhash, INT2FIX(0)); break;
- case COMPILE_ARRAY_TYPE_ARGS: /* do nothing */ break;
- }
+ ADD_INSN1(ret, line, newarray, INT2FIX(0));
}
+ return 0;
}
- else {
- int opt_p = 1;
- int first = 1, i;
-
- while (node) {
- NODE *start_node = node, *end_node;
- NODE *kw = 0;
- const int max = 0x100;
- DECL_ANCHOR(anchor);
- INIT_ANCHOR(anchor);
-
- for (i=0; i<max && node; i++, len++, node = node->nd_next) {
- if (CPDEBUG > 0) {
- EXPECT_NODE("compile_array", node, NODE_ARRAY, -1);
- }
- if (type != COMPILE_ARRAY_TYPE_ARRAY && !node->nd_head) {
- kw = node->nd_next;
- node = 0;
- if (kw) {
- opt_p = 0;
- node = kw->nd_next;
- kw = kw->nd_head;
- }
- break;
- }
- if (opt_p && !static_literal_node_p(node)) {
- opt_p = 0;
- }
+ EXPECT_NODE("compile_array", node, NODE_LIST, -1);
- if (type == COMPILE_ARRAY_TYPE_ARGS &&
- node->nd_next == NULL /* last node */ &&
- compile_array_keyword_arg(iseq, anchor, node->nd_head, keywords_ptr, flag)) {
- len--;
- }
- else {
- COMPILE_(anchor, "array element", node->nd_head, popped);
- }
- }
+ if (popped) {
+ for (; node; node = node->nd_next) {
+ NO_CHECK(COMPILE_(ret, "array element", node->nd_head, popped));
+ }
+ return 1;
+ }
- if (opt_p && type != COMPILE_ARRAY_TYPE_ARGS) {
- if (!popped) {
- VALUE ary = rb_ary_tmp_new(i);
+ /* Compilation of an array literal.
+ * The following code is essentially the same as:
+ *
+ * for (int count = 0; node; count++; node->nd_next) {
+ * compile(node->nd_head);
+ * }
+ * ADD_INSN(newarray, count);
+ *
+ * However, there are three points.
+ *
+ * - The code above causes stack overflow for a big string literal.
+ * The following limits the stack length up to max_stack_len.
+ *
+ * [x1,x2,...,x10000] =>
+ * push x1 ; push x2 ; ...; push x256; newarray 256;
+ * push x257; push x258; ...; push x512; newarray 256; concatarray;
+ * push x513; push x514; ...; push x768; newarray 256; concatarray;
+ * ...
+ *
+ * - Long subarray can be optimized by pre-allocating a hidden array.
+ *
+ * [1,2,3,...,100] =>
+ * duparray [1,2,3,...,100]
+ *
+ * [x, 1,2,3,...,100, z] =>
+ * push x; newarray 1;
+ * putobject [1,2,3,...,100] (<- hidden array); concatarray;
+ * push z; newarray 1; concatarray
+ *
+ * - If the last element is a keyword, newarraykwsplat should be emitted
+ * to check and remove empty keyword arguments hash from array.
+ * (Note: a keyword is NODE_HASH which is not static_literal_node_p.)
+ *
+ * [1,2,3,**kw] =>
+ * putobject 1; putobject 2; putobject 3; push kw; newarraykwsplat
+ */
- end_node = node;
- node = start_node;
+ const int max_stack_len = 0x100;
+ const int min_tmp_ary_len = 0x40;
+ int stack_len = 0;
+ int first_chunk = 1;
- while (node != end_node) {
- rb_ary_push(ary, static_literal_value(node));
- node = node->nd_next;
- }
- while (node && node->nd_next &&
- static_literal_node_p(node) &&
- static_literal_node_p(node->nd_next)) {
- VALUE elem[2];
- elem[0] = static_literal_value(node);
- elem[1] = static_literal_value(node->nd_next);
- rb_ary_cat(ary, elem, 2);
- node = node->nd_next->nd_next;
- len++;
- }
+ /* Convert pushed elements to an array, and concatarray if needed */
+#define FLUSH_CHUNK(newarrayinsn) \
+ if (stack_len) { \
+ ADD_INSN1(ret, line, newarrayinsn, INT2FIX(stack_len)); \
+ if (!first_chunk) ADD_INSN(ret, line, concatarray); \
+ first_chunk = stack_len = 0; \
+ }
- OBJ_FREEZE(ary);
+ while (node) {
+ int count = 1;
+
+ /* pre-allocation check (this branch can be omittable) */
+ if (static_literal_node_p(node, iseq)) {
+ /* count the elements that are optimizable */
+ const NODE *node_tmp = node->nd_next;
+ for (; node_tmp && static_literal_node_p(node_tmp, iseq); node_tmp = node_tmp->nd_next)
+ count++;
+
+ if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) {
+ /* The literal contains only optimizable elements, or the subarray is long enough */
+ VALUE ary = rb_ary_tmp_new(count);
+
+ /* Create a hidden array */
+ for (; count; count--, node = node->nd_next)
+ rb_ary_push(ary, static_literal_value(node, iseq));
+ OBJ_FREEZE(ary);
+
+ /* Emit optimized code */
+ FLUSH_CHUNK(newarray);
+ if (first_chunk) {
+ ADD_INSN1(ret, line, duparray, ary);
+ first_chunk = 0;
+ }
+ else {
+ ADD_INSN1(ret, line, putobject, ary);
+ ADD_INSN(ret, line, concatarray);
+ }
+ RB_OBJ_WRITTEN(iseq, Qundef, ary);
+ }
+ }
+
+ /* Base case: Compile "count" elements */
+ for (; count; count--, node = node->nd_next) {
+ if (CPDEBUG > 0) {
+ EXPECT_NODE("compile_array", node, NODE_LIST, -1);
+ }
+
+ NO_CHECK(COMPILE_(ret, "array element", node->nd_head, 0));
+ stack_len++;
+
+ if (!node->nd_next && keyword_node_p(node->nd_head)) {
+ /* Reached the end, and the last element is a keyword */
+ FLUSH_CHUNK(newarraykwsplat);
+ return 1;
+ }
+
+ /* If there are many pushed elements, flush them to avoid stack overflow */
+ if (stack_len >= max_stack_len) FLUSH_CHUNK(newarray);
+ }
+ }
+
+ FLUSH_CHUNK(newarray);
+#undef FLUSH_CHUNK
+ return 1;
+}
- iseq_add_mark_object_compile_time(iseq, ary);
+static inline int
+static_literal_node_pair_p(const NODE *node, const rb_iseq_t *iseq)
+{
+ return node->nd_head && static_literal_node_p(node, iseq) && static_literal_node_p(node->nd_next, iseq);
+}
- if (first) {
- first = 0;
- if (type == COMPILE_ARRAY_TYPE_ARRAY) {
- ADD_INSN1(ret, line, duparray, ary);
- }
- else { /* COMPILE_ARRAY_TYPE_HASH */
- ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, line, putobject, ary);
- ADD_SEND(ret, line, id_core_hash_from_ary, INT2FIX(1));
- }
- }
- else {
- if (type == COMPILE_ARRAY_TYPE_ARRAY) {
- ADD_INSN1(ret, line, putobject, ary);
- ADD_INSN(ret, line, concatarray);
- }
- else {
-#if 0
- ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, line, putobject, ary);
- ADD_SEND(ret, line, id_core_hash_merge_ary, INT2FIX(1));
- /* wrong number of arguments -----------------------^ */
-#else
- COMPILE_ERROR(ERROR_ARGS "core#hash_merge_ary");
- return -1;
-#endif
- }
- }
- }
- }
- else {
- if (!popped) {
- switch (type) {
- case COMPILE_ARRAY_TYPE_ARRAY:
- ADD_INSN1(anchor, line, newarray, INT2FIX(i));
+static int
+compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int method_call_keywords, int popped)
+{
+ int line = (int)nd_line(node);
- if (first) {
- first = 0;
- }
- else {
- ADD_INSN(anchor, line, concatarray);
- }
+ node = node->nd_head;
- APPEND_LIST(ret, anchor);
- break;
- case COMPILE_ARRAY_TYPE_HASH:
- if (i > 0) {
- if (first) {
- ADD_INSN1(anchor, line, newhash, INT2FIX(i));
- APPEND_LIST(ret, anchor);
- }
- else {
- ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN(ret, line, swap);
- APPEND_LIST(ret, anchor);
- ADD_SEND(ret, line, id_core_hash_merge_ptr, INT2FIX(i + 1));
- }
- }
- if (kw) {
- VALUE nhash = (i > 0 || !first) ? INT2FIX(2) : INT2FIX(1);
- ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- if (i > 0 || !first) ADD_INSN(ret, line, swap);
- COMPILE(ret, "keyword splat", kw);
- ADD_SEND(ret, line, id_core_hash_merge_kwd, nhash);
- if (nhash == INT2FIX(1)) ADD_SEND(ret, line, rb_intern("dup"), INT2FIX(0));
- }
- first = 0;
- break;
- case COMPILE_ARRAY_TYPE_ARGS:
- APPEND_LIST(ret, anchor);
- break;
- }
- }
- else {
- /* popped */
- APPEND_LIST(ret, anchor);
- }
- }
+ if (!node || nd_type(node) == NODE_ZLIST) {
+ if (!popped) {
+ ADD_INSN1(ret, line, newhash, INT2FIX(0));
}
+ return 0;
}
- return len;
+
+ EXPECT_NODE("compile_hash", node, NODE_LIST, -1);
+
+ if (popped) {
+ for (; node; node = node->nd_next) {
+ NO_CHECK(COMPILE_(ret, "hash element", node->nd_head, popped));
+ }
+ return 1;
+ }
+
+ /* Compilation of a hash literal (or keyword arguments).
+ * This is very similar to compile_array, but there are some differences:
+ *
+ * - It contains key-value pairs. So we need to take every two elements.
+ * We can assume that the length is always even.
+ *
+ * - Merging is done by a method call (id_core_hash_merge_ptr).
+ * Sometimes we need to insert the receiver, so "anchor" is needed.
+ * In addition, a method call is much slower than concatarray.
+ * So it pays only when the subsequence is really long.
+ * (min_tmp_hash_len must be much larger than min_tmp_ary_len.)
+ *
+ * - We need to handle keyword splat: **kw.
+ * For **kw, the key part (node->nd_head) is NULL, and the value part
+ * (node->nd_next->nd_head) is "kw".
+ * The code is a bit difficult to avoid hash allocation for **{}.
+ */
+
+ const int max_stack_len = 0x100;
+ const int min_tmp_hash_len = 0x800;
+ int stack_len = 0;
+ int first_chunk = 1;
+ DECL_ANCHOR(anchor);
+ INIT_ANCHOR(anchor);
+
+ /* Convert pushed elements to a hash, and merge if needed */
+#define FLUSH_CHUNK() \
+ if (stack_len) { \
+ if (first_chunk) { \
+ APPEND_LIST(ret, anchor); \
+ ADD_INSN1(ret, line, newhash, INT2FIX(stack_len)); \
+ } \
+ else { \
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); \
+ ADD_INSN(ret, line, swap); \
+ APPEND_LIST(ret, anchor); \
+ ADD_SEND(ret, line, id_core_hash_merge_ptr, INT2FIX(stack_len + 1)); \
+ } \
+ INIT_ANCHOR(anchor); \
+ first_chunk = stack_len = 0; \
+ }
+
+ while (node) {
+ int count = 1;
+
+ /* pre-allocation check (this branch can be omittable) */
+ if (static_literal_node_pair_p(node, iseq)) {
+ /* count the elements that are optimizable */
+ const NODE *node_tmp = node->nd_next->nd_next;
+ for (; node_tmp && static_literal_node_pair_p(node_tmp, iseq); node_tmp = node_tmp->nd_next->nd_next)
+ count++;
+
+ if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_hash_len) {
+ /* The literal contains only optimizable elements, or the subsequence is long enough */
+ VALUE ary = rb_ary_tmp_new(count);
+
+ /* Create a hidden hash */
+ for (; count; count--, node = node->nd_next->nd_next) {
+ VALUE elem[2];
+ elem[0] = static_literal_value(node, iseq);
+ elem[1] = static_literal_value(node->nd_next, iseq);
+ rb_ary_cat(ary, elem, 2);
+ }
+ VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
+ rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR_TRANSIENT(ary), hash);
+ hash = rb_obj_hide(hash);
+ OBJ_FREEZE(hash);
+
+ /* Emit optimized code */
+ FLUSH_CHUNK();
+ if (first_chunk) {
+ ADD_INSN1(ret, line, duphash, hash);
+ first_chunk = 0;
+ }
+ else {
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_INSN(ret, line, swap);
+
+ ADD_INSN1(ret, line, putobject, hash);
+
+ ADD_SEND(ret, line, id_core_hash_merge_kwd, INT2FIX(2));
+ }
+ RB_OBJ_WRITTEN(iseq, Qundef, hash);
+ }
+ }
+
+ /* Base case: Compile "count" elements */
+ for (; count; count--, node = node->nd_next->nd_next) {
+
+ if (CPDEBUG > 0) {
+ EXPECT_NODE("compile_hash", node, NODE_LIST, -1);
+ }
+
+ if (node->nd_head) {
+ /* Normal key-value pair */
+ NO_CHECK(COMPILE_(anchor, "hash key element", node->nd_head, 0));
+ NO_CHECK(COMPILE_(anchor, "hash value element", node->nd_next->nd_head, 0));
+ stack_len += 2;
+
+ /* If there are many pushed elements, flush them to avoid stack overflow */
+ if (stack_len >= max_stack_len) FLUSH_CHUNK();
+ }
+ else {
+ /* kwsplat case: foo(..., **kw, ...) */
+ FLUSH_CHUNK();
+
+ const NODE *kw = node->nd_next->nd_head;
+ int empty_kw = nd_type(kw) == NODE_LIT && RB_TYPE_P(kw->nd_lit, T_HASH); /* foo( ..., **{}, ...) */
+ int first_kw = first_chunk && stack_len == 0; /* foo(1,2,3, **kw, ...) */
+ int last_kw = !node->nd_next->nd_next; /* foo( ..., **kw) */
+ int only_kw = last_kw && first_kw; /* foo(1,2,3, **kw) */
+
+ if (empty_kw) {
+ if (only_kw && method_call_keywords) {
+ /* **{} appears at the only keyword argument in method call,
+ * so it won't be modified.
+ * kw is a special NODE_LIT that contains a special empty hash,
+ * so this emits: putobject {}.
+ * This is only done for method calls and not for literal hashes,
+ * because literal hashes should always result in a new hash.
+ */
+ NO_CHECK(COMPILE(ret, "keyword splat", kw));
+ }
+ else if (first_kw) {
+ /* **{} appears as the first keyword argument, so it may be modified.
+ * We need to create a fresh hash object.
+ */
+ ADD_INSN1(ret, line, newhash, INT2FIX(0));
+ }
+ /* Any empty keyword splats that are not the first can be ignored.
+ * since merging an empty hash into the existing hash is the same
+ * as not merging it. */
+ }
+ else {
+ if (only_kw && method_call_keywords) {
+ /* **kw is only keyword argument in method call.
+ * Use directly. This will be not be flagged as mutable.
+ * This is only done for method calls and not for literal hashes,
+ * because literal hashes should always result in a new hash.
+ */
+ NO_CHECK(COMPILE(ret, "keyword splat", kw));
+ }
+ else {
+ /* There is more than one keyword argument, or this is not a method
+ * call. In that case, we need to add an empty hash (if first keyword),
+ * or merge the hash to the accumulated hash (if not the first keyword).
+ */
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ if (first_kw) ADD_INSN1(ret, line, newhash, INT2FIX(0));
+ else ADD_INSN(ret, line, swap);
+
+ NO_CHECK(COMPILE(ret, "keyword splat", kw));
+
+ ADD_SEND(ret, line, id_core_hash_merge_kwd, INT2FIX(2));
+ }
+ }
+
+ first_chunk = 0;
+ }
+ }
+ }
+
+ FLUSH_CHUNK();
+#undef FLUSH_CHUNK
+ return 1;
}
-static VALUE
-case_when_optimizable_literal(NODE *node)
+VALUE
+rb_node_case_when_optimizable_literal(const NODE *const node)
{
switch (nd_type(node)) {
case NODE_LIT: {
@@ -3423,42 +4499,36 @@ case_when_optimizable_literal(NODE *node)
case NODE_FALSE:
return Qfalse;
case NODE_STR:
- return node->nd_lit = rb_fstring(node->nd_lit);
+ return rb_fstring(node->nd_lit);
}
return Qundef;
}
static int
-when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, NODE *vals,
+when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
LABEL *l1, int only_special_literals, VALUE literals)
{
while (vals) {
- NODE* val = vals->nd_head;
- VALUE lit = case_when_optimizable_literal(val);
+ const NODE *val = vals->nd_head;
+ VALUE lit = rb_node_case_when_optimizable_literal(val);
if (lit == Qundef) {
only_special_literals = 0;
}
- else {
- if (rb_hash_lookup(literals, lit) != Qnil) {
- VALUE file = rb_iseq_path(iseq);
- rb_compile_warning(RSTRING_PTR(file), nd_line(val),
- "duplicated when clause is ignored");
- }
- else {
- rb_hash_aset(literals, lit, (VALUE)(l1) | 1);
- }
+ else if (NIL_P(rb_hash_lookup(literals, lit))) {
+ rb_hash_aset(literals, lit, (VALUE)(l1) | 1);
}
ADD_INSN(cond_seq, nd_line(val), dup); /* dup target */
if (nd_type(val) == NODE_STR) {
- val->nd_lit = rb_fstring(val->nd_lit);
debugp_param("nd_lit", val->nd_lit);
- ADD_INSN1(cond_seq, nd_line(val), putobject, val->nd_lit);
+ lit = rb_fstring(val->nd_lit);
+ ADD_INSN1(cond_seq, nd_line(val), putobject, lit);
+ RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
else {
- COMPILE(cond_seq, "when cond", val);
+ if (!COMPILE(cond_seq, "when cond", val)) return -1;
}
ADD_INSN1(cond_seq, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
@@ -3469,26 +4539,72 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, NODE *vals,
}
static int
-compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
+when_splat_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
+ LABEL *l1, int only_special_literals, VALUE literals)
+{
+ const int line = nd_line(vals);
+
+ switch (nd_type(vals)) {
+ case NODE_LIST:
+ if (when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals) < 0)
+ return COMPILE_NG;
+ break;
+ case NODE_SPLAT:
+ ADD_INSN (cond_seq, line, dup);
+ CHECK(COMPILE(cond_seq, "when splat", vals->nd_head));
+ ADD_INSN1(cond_seq, line, splatarray, Qfalse);
+ ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
+ ADD_INSNL(cond_seq, line, branchif, l1);
+ break;
+ case NODE_ARGSCAT:
+ CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
+ CHECK(when_splat_vals(iseq, cond_seq, vals->nd_body, l1, only_special_literals, literals));
+ break;
+ case NODE_ARGSPUSH:
+ CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
+ ADD_INSN (cond_seq, line, dup);
+ CHECK(COMPILE(cond_seq, "when argspush body", vals->nd_body));
+ ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
+ ADD_INSNL(cond_seq, line, branchif, l1);
+ break;
+ default:
+ ADD_INSN (cond_seq, line, dup);
+ CHECK(COMPILE(cond_seq, "when val", vals));
+ ADD_INSN1(cond_seq, line, splatarray, Qfalse);
+ ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
+ ADD_INSNL(cond_seq, line, branchif, l1);
+ break;
+ }
+ return COMPILE_OK;
+}
+
+
+static int
+compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
{
switch (nd_type(node)) {
case NODE_ATTRASGN: {
INSN *iobj;
- struct rb_call_info *ci;
VALUE dupidx;
int line = nd_line(node);
CHECK(COMPILE_POPPED(ret, "masgn lhs (NODE_ATTRASGN)", node));
iobj = (INSN *)get_prev_insn((INSN *)LAST_ELEMENT(ret)); /* send insn */
- ci = (struct rb_call_info *)iobj->operands[0];
- ci->orig_argc += 1;
- dupidx = INT2FIX(ci->orig_argc);
+ const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(iobj, 0);
+ int argc = vm_ci_argc(ci) + 1;
+ ci = ci_argc_set(iseq, ci, argc);
+ OPERAND_AT(iobj, 0) = (VALUE)ci;
+ RB_OBJ_WRITTEN(iseq, Qundef, ci);
+ dupidx = INT2FIX(argc);
INSERT_BEFORE_INSN1(iobj, line, topn, dupidx);
- if (ci->flag & VM_CALL_ARGS_SPLAT) {
- --ci->orig_argc;
- INSERT_BEFORE_INSN1(iobj, line, newarray, INT2FIX(1));
+ if (vm_ci_flag(ci) & VM_CALL_ARGS_SPLAT) {
+ int argc = vm_ci_argc(ci);
+ ci = ci_argc_set(iseq, ci, argc - 1);
+ OPERAND_AT(iobj, 0) = (VALUE)ci;
+ RB_OBJ_WRITTEN(iseq, Qundef, iobj);
+ INSERT_BEFORE_INSN1(iobj, line, newarray, INT2FIX(1));
INSERT_BEFORE_INSN(iobj, line, concatarray);
}
ADD_INSN(ret, line, pop); /* result */
@@ -3498,7 +4614,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
CHECK(COMPILE_POPPED(anchor, "nest masgn lhs", node));
- REMOVE_ELEM(FIRST_ELEMENT(anchor));
+ ELEM_REMOVE(FIRST_ELEMENT(anchor));
ADD_SEQ(ret, anchor);
break;
}
@@ -3506,7 +4622,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
CHECK(COMPILE_POPPED(anchor, "masgn lhs", node));
- REMOVE_ELEM(FIRST_ELEMENT(anchor));
+ ELEM_REMOVE(FIRST_ELEMENT(anchor));
ADD_SEQ(ret, anchor);
}
}
@@ -3515,7 +4631,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
}
static int
-compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *lhsn)
+compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *lhsn)
{
if (lhsn) {
CHECK(compile_massign_opt_lhs(iseq, ret, lhsn->nd_next));
@@ -3526,14 +4642,14 @@ compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *lhsn)
static int
compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
- NODE *rhsn, NODE *orig_lhsn)
+ const NODE *rhsn, const NODE *orig_lhsn)
{
VALUE mem[64];
const int memsize = numberof(mem);
int memindex = 0;
int llen = 0, rlen = 0;
int i;
- NODE *lhsn = orig_lhsn;
+ const NODE *lhsn = orig_lhsn;
#define MEMORY(v) { \
int i; \
@@ -3544,12 +4660,12 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
mem[memindex++] = (v); \
}
- if (rhsn == 0 || nd_type(rhsn) != NODE_ARRAY) {
+ if (rhsn == 0 || nd_type(rhsn) != NODE_LIST) {
return 0;
}
while (lhsn) {
- NODE *ln = lhsn->nd_head;
+ const NODE *ln = lhsn->nd_head;
switch (nd_type(ln)) {
case NODE_LASGN:
MEMORY(ln->nd_vid);
@@ -3557,7 +4673,6 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
case NODE_DASGN:
case NODE_DASGN_CURR:
case NODE_IASGN:
- case NODE_IASGN2:
case NODE_CVASGN:
MEMORY(ln->nd_vid);
break;
@@ -3570,10 +4685,10 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
while (rhsn) {
if (llen <= rlen) {
- COMPILE_POPPED(ret, "masgn val (popped)", rhsn->nd_head);
+ NO_CHECK(COMPILE_POPPED(ret, "masgn val (popped)", rhsn->nd_head));
}
else {
- COMPILE(ret, "masgn val", rhsn->nd_head);
+ NO_CHECK(COMPILE(ret, "masgn val", rhsn->nd_head));
}
rhsn = rhsn->nd_next;
rlen++;
@@ -3601,12 +4716,12 @@ adjust_stack(rb_iseq_t *iseq, LINK_ANCHOR *const ret, int line, int rlen, int ll
}
static int
-compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
- NODE *rhsn = node->nd_value;
- NODE *splatn = node->nd_args;
- NODE *lhsn = node->nd_head;
- int lhs_splat = (splatn && (VALUE)splatn != (VALUE)-1) ? 1 : 0;
+ const NODE *rhsn = node->nd_value;
+ const NODE *splatn = node->nd_args;
+ const NODE *lhsn = node->nd_head;
+ int lhs_splat = (splatn && NODE_NAMED_REST_P(splatn)) ? 1 : 0;
if (!popped || splatn || !compile_massign_opt(iseq, ret, rhsn, lhsn)) {
int llen = 0;
@@ -3621,7 +4736,7 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
lhsn = lhsn->nd_next;
}
- COMPILE(ret, "normal masgn rhs", rhsn);
+ NO_CHECK(COMPILE(ret, "normal masgn rhs", rhsn));
if (!popped) {
ADD_INSN(ret, nd_line(node), dup);
@@ -3660,15 +4775,15 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
if (lhs_splat) {
if (nd_type(splatn) == NODE_POSTARG) {
/*a, b, *r, p1, p2 */
- NODE *postn = splatn->nd_2nd;
- NODE *restn = splatn->nd_1st;
+ const NODE *postn = splatn->nd_2nd;
+ const NODE *restn = splatn->nd_1st;
int num = (int)postn->nd_alen;
- int flag = 0x02 | (((VALUE)restn == (VALUE)-1) ? 0x00 : 0x01);
+ int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00);
ADD_INSN2(ret, nd_line(splatn), expandarray,
INT2FIX(num), INT2FIX(flag));
- if ((VALUE)restn != (VALUE)-1) {
+ if (NODE_NAMED_REST_P(restn)) {
CHECK(compile_massign_lhs(iseq, ret, restn));
}
while (postn) {
@@ -3686,24 +4801,27 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_const_prefix(rb_iseq_t *iseq, NODE *node,
+compile_const_prefix(rb_iseq_t *iseq, const NODE *const node,
LINK_ANCHOR *const pref, LINK_ANCHOR *const body)
{
switch (nd_type(node)) {
case NODE_CONST:
debugi("compile_const_prefix - colon", node->nd_vid);
- ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_vid));
+ ADD_INSN1(body, nd_line(node), putobject, Qtrue);
+ ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_vid));
break;
case NODE_COLON3:
debugi("compile_const_prefix - colon3", node->nd_mid);
ADD_INSN(body, nd_line(node), pop);
ADD_INSN1(body, nd_line(node), putobject, rb_cObject);
- ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid));
+ ADD_INSN1(body, nd_line(node), putobject, Qtrue);
+ ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid));
break;
case NODE_COLON2:
CHECK(compile_const_prefix(iseq, node->nd_head, pref, body));
debugi("compile_const_prefix - colon2", node->nd_mid);
- ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid));
+ ADD_INSN1(body, nd_line(node), putobject, Qfalse);
+ ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid));
break;
default:
CHECK(COMPILE(pref, "const colon2 prefix", node));
@@ -3713,7 +4831,7 @@ compile_const_prefix(rb_iseq_t *iseq, NODE *node,
}
static int
-compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE *cpath)
+compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath)
{
if (nd_type(cpath) == NODE_COLON3) {
/* toplevel class ::Foo */
@@ -3722,7 +4840,7 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE *cpath)
}
else if (cpath->nd_head) {
/* Bar::Foo */
- COMPILE(ret, "nd_else->nd_head", cpath->nd_head);
+ NO_CHECK(COMPILE(ret, "nd_else->nd_head", cpath->nd_head));
return VM_DEFINECLASS_FLAG_SCOPED;
}
else {
@@ -3733,17 +4851,27 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE *cpath)
}
}
-#define private_recv_p(node) (nd_type((node)->nd_recv) == NODE_SELF)
-static int
+static inline int
+private_recv_p(const NODE *node)
+{
+ if (nd_type(node->nd_recv) == NODE_SELF) {
+ NODE *self = node->nd_recv;
+ return self->nd_state != 0;
+ }
+ return 0;
+}
+
+static void
defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
- NODE *node, LABEL **lfinish, VALUE needstr);
+ const NODE *const node, LABEL **lfinish, VALUE needstr);
-static int
+static void
defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
- NODE *node, LABEL **lfinish, VALUE needstr)
+ const NODE *const node, LABEL **lfinish, VALUE needstr)
{
- enum defined_type expr_type = 0;
+ enum defined_type expr_type = DEFINED_NOT_DEFINED;
enum node_type type;
+ const int line = nd_line(node);
switch (type = nd_type(node)) {
@@ -3761,21 +4889,22 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
expr_type = DEFINED_FALSE;
break;
- case NODE_ARRAY:{
- NODE *vals = node;
+ case NODE_LIST:{
+ const NODE *vals = node;
do {
defined_expr0(iseq, ret, vals->nd_head, lfinish, Qfalse);
if (!lfinish[1]) {
- lfinish[1] = NEW_LABEL(nd_line(node));
+ lfinish[1] = NEW_LABEL(line);
}
- ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
+ ADD_INSNL(ret, line, branchunless, lfinish[1]);
} while ((vals = vals->nd_next) != NULL);
}
+ /* fall through */
case NODE_STR:
case NODE_LIT:
- case NODE_ZARRAY:
+ case NODE_ZLIST:
case NODE_AND:
case NODE_OR:
default:
@@ -3789,46 +4918,46 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
break;
case NODE_IVAR:
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_IVAR),
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_IVAR),
ID2SYM(node->nd_vid), needstr);
- return 1;
+ return;
case NODE_GVAR:
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_GVAR),
- ID2SYM(node->nd_entry->id), needstr);
- return 1;
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_GVAR),
+ ID2SYM(node->nd_entry), needstr);
+ return;
case NODE_CVAR:
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CVAR),
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_CVAR),
ID2SYM(node->nd_vid), needstr);
- return 1;
+ return;
case NODE_CONST:
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CONST),
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_CONST),
ID2SYM(node->nd_vid), needstr);
- return 1;
+ return;
case NODE_COLON2:
if (!lfinish[1]) {
- lfinish[1] = NEW_LABEL(nd_line(node));
+ lfinish[1] = NEW_LABEL(line);
}
defined_expr0(iseq, ret, node->nd_head, lfinish, Qfalse);
- ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
- COMPILE(ret, "defined/colon2#nd_head", node->nd_head);
+ ADD_INSNL(ret, line, branchunless, lfinish[1]);
+ NO_CHECK(COMPILE(ret, "defined/colon2#nd_head", node->nd_head));
- ADD_INSN3(ret, nd_line(node), defined,
+ ADD_INSN3(ret, line, defined,
(rb_is_const_id(node->nd_mid) ?
- INT2FIX(DEFINED_CONST) : INT2FIX(DEFINED_METHOD)),
+ INT2FIX(DEFINED_CONST_FROM) : INT2FIX(DEFINED_METHOD)),
ID2SYM(node->nd_mid), needstr);
- return 1;
+ return;
case NODE_COLON3:
- ADD_INSN1(ret, nd_line(node), putobject, rb_cObject);
- ADD_INSN3(ret, nd_line(node), defined,
- INT2FIX(DEFINED_CONST), ID2SYM(node->nd_mid), needstr);
- return 1;
+ ADD_INSN1(ret, line, putobject, rb_cObject);
+ ADD_INSN3(ret, line, defined,
+ INT2FIX(DEFINED_CONST_FROM), ID2SYM(node->nd_mid), needstr);
+ return;
/* method dispatch */
case NODE_CALL:
@@ -3841,47 +4970,47 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
(type == NODE_ATTRASGN && !private_recv_p(node)));
if (!lfinish[1] && (node->nd_args || explicit_receiver)) {
- lfinish[1] = NEW_LABEL(nd_line(node));
+ lfinish[1] = NEW_LABEL(line);
}
if (node->nd_args) {
defined_expr0(iseq, ret, node->nd_args, lfinish, Qfalse);
- ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
+ ADD_INSNL(ret, line, branchunless, lfinish[1]);
}
if (explicit_receiver) {
defined_expr0(iseq, ret, node->nd_recv, lfinish, Qfalse);
- ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
- COMPILE(ret, "defined/recv", node->nd_recv);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_METHOD),
+ ADD_INSNL(ret, line, branchunless, lfinish[1]);
+ NO_CHECK(COMPILE(ret, "defined/recv", node->nd_recv));
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_METHOD),
ID2SYM(node->nd_mid), needstr);
}
else {
- ADD_INSN(ret, nd_line(node), putself);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_FUNC),
+ ADD_INSN(ret, line, putself);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_FUNC),
ID2SYM(node->nd_mid), needstr);
}
- return 1;
+ return;
}
case NODE_YIELD:
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_YIELD), 0,
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_YIELD), 0,
needstr);
- return 1;
+ return;
case NODE_BACK_REF:
case NODE_NTH_REF:
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_REF),
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_REF),
INT2FIX((node->nd_nth << 1) | (type == NODE_BACK_REF)),
needstr);
- return 1;
+ return;
case NODE_SUPER:
case NODE_ZSUPER:
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_ZSUPER), 0,
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_ZSUPER), 0,
needstr);
- return 1;
+ return;
case NODE_OP_ASGN1:
case NODE_OP_ASGN2:
@@ -3894,51 +5023,56 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
case NODE_GASGN:
case NODE_IASGN:
case NODE_CDECL:
- case NODE_CVDECL:
case NODE_CVASGN:
expr_type = DEFINED_ASGN;
break;
}
- if (expr_type) {
- if (needstr != Qfalse) {
- VALUE str = rb_iseq_defined_string(expr_type);
- ADD_INSN1(ret, nd_line(node), putobject, str);
- }
- else {
- ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
- }
- return 1;
+ assert(expr_type != DEFINED_NOT_DEFINED);
+
+ if (needstr != Qfalse) {
+ VALUE str = rb_iseq_defined_string(expr_type);
+ ADD_INSN1(ret, line, putobject, str);
+ }
+ else {
+ ADD_INSN1(ret, line, putobject, Qtrue);
}
- return 0;
}
-static int
+static void
+build_defined_rescue_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const void *unused)
+{
+ ADD_INSN(ret, 0, putnil);
+ iseq_set_exception_local_table(iseq);
+}
+
+static void
defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
- NODE *node, LABEL **lfinish, VALUE needstr)
+ const NODE *const node, LABEL **lfinish, VALUE needstr)
{
LINK_ELEMENT *lcur = ret->last;
- int done = defined_expr0(iseq, ret, node, lfinish, needstr);
+ defined_expr0(iseq, ret, node, lfinish, needstr);
if (lfinish[1]) {
int line = nd_line(node);
LABEL *lstart = NEW_LABEL(line);
LABEL *lend = NEW_LABEL(line);
- const rb_iseq_t *rescue = NEW_CHILD_ISEQ(NEW_NIL(),
- rb_str_concat(rb_str_new2
- ("defined guard in "),
- iseq->body->location.label),
- ISEQ_TYPE_DEFINED_GUARD, 0);
+ const rb_iseq_t *rescue;
+ struct rb_iseq_new_with_callback_callback_func *ifunc =
+ rb_iseq_new_with_callback_new_callback(build_defined_rescue_iseq, NULL);
+ rescue = new_child_iseq_with_callback(iseq, ifunc,
+ rb_str_concat(rb_str_new2("defined guard in "),
+ iseq->body->location.label),
+ iseq, ISEQ_TYPE_RESCUE, 0);
lstart->rescued = LABEL_RESCUE_BEG;
lend->rescued = LABEL_RESCUE_END;
APPEND_LABEL(ret, lcur, lstart);
ADD_LABEL(ret, lend);
ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lfinish[1]);
}
- return done;
}
static int
-compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, VALUE needstr)
+compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, VALUE needstr)
{
const int line = nd_line(node);
if (!node->nd_head) {
@@ -3952,7 +5086,7 @@ compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, VALUE
lfinish[1] = 0;
defined_expr(iseq, ret, node->nd_head, lfinish, needstr);
if (lfinish[1]) {
- INSERT_ELEM_NEXT(last, &new_insn_body(iseq, line, BIN(putnil), 0)->link);
+ ELEM_INSERT_NEXT(last, &new_insn_body(iseq, line, BIN(putnil), 0)->link);
ADD_INSN(ret, line, swap);
ADD_INSN(ret, line, pop);
ADD_LABEL(ret, lfinish[1]);
@@ -3988,7 +5122,7 @@ make_name_for_block(const rb_iseq_t *orig_iseq)
static void
push_ensure_entry(rb_iseq_t *iseq,
struct iseq_compile_data_ensure_node_stack *enl,
- struct ensure_range *er, NODE *node)
+ struct ensure_range *er, const NODE *const node)
{
enl->ensure_node = node;
enl->prev = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack; /* prev */
@@ -4034,7 +5168,7 @@ add_ensure_iseq(LINK_ANCHOR *const ret, rb_iseq_t *iseq, int is_return)
ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enlp->prev;
ADD_LABEL(ensure_part, lstart);
- COMPILE_POPPED(ensure_part, "ensure part", enlp->ensure_node);
+ NO_CHECK(COMPILE_POPPED(ensure_part, "ensure part", enlp->ensure_node));
ADD_LABEL(ensure_part, lend);
ADD_SEQ(ensure, ensure_part);
}
@@ -4049,115 +5183,137 @@ add_ensure_iseq(LINK_ANCHOR *const ret, rb_iseq_t *iseq, int is_return)
ADD_SEQ(ret, ensure);
}
-static VALUE
-setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, NODE *argn,
- unsigned int *flag, struct rb_call_info_kw_arg **keywords)
+static int
+check_keyword(const NODE *node)
{
- VALUE argc = INT2FIX(0);
- int nsplat = 0;
- DECL_ANCHOR(arg_block);
- DECL_ANCHOR(args_splat);
+ /* This check is essentially a code clone of compile_keyword_arg. */
- INIT_ANCHOR(arg_block);
- INIT_ANCHOR(args_splat);
- if (argn && nd_type(argn) == NODE_BLOCK_PASS) {
- COMPILE(arg_block, "block", argn->nd_body);
- *flag |= VM_CALL_ARGS_BLOCKARG;
- argn = argn->nd_head;
+ if (nd_type(node) == NODE_LIST) {
+ while (node->nd_next) {
+ node = node->nd_next;
+ }
+ node = node->nd_head;
}
- setup_argn:
- if (argn) {
- switch (nd_type(argn)) {
- case NODE_SPLAT: {
- COMPILE(args, "args (splat)", argn->nd_head);
- ADD_INSN1(args, nd_line(argn), splatarray, nsplat ? Qtrue : Qfalse);
- argc = INT2FIX(1);
- nsplat++;
- *flag |= VM_CALL_ARGS_SPLAT;
- break;
- }
- case NODE_ARGSCAT:
- case NODE_ARGSPUSH: {
- int next_is_array = (nd_type(argn->nd_head) == NODE_ARRAY);
- DECL_ANCHOR(tmp);
-
- INIT_ANCHOR(tmp);
- COMPILE(tmp, "args (cat: splat)", argn->nd_body);
- if (nd_type(argn) == NODE_ARGSCAT) {
- ADD_INSN1(tmp, nd_line(argn), splatarray, nsplat ? Qtrue : Qfalse);
- }
- else {
- ADD_INSN1(tmp, nd_line(argn), newarray, INT2FIX(1));
- }
- INSERT_LIST(args_splat, tmp);
- nsplat++;
- *flag |= VM_CALL_ARGS_SPLAT;
-
- if (next_is_array) {
- int len = compile_array(iseq, args, argn->nd_head, COMPILE_ARRAY_TYPE_ARGS, NULL, flag, FALSE);
- if (len < 0) return Qnil;
- argc = INT2FIX(len + 1);
- }
- else {
- argn = argn->nd_head;
- goto setup_argn;
- }
- break;
- }
- case NODE_ARRAY:
- {
- int len = compile_array(iseq, args, argn, COMPILE_ARRAY_TYPE_ARGS, keywords, flag, FALSE);
- if (len < 0) return Qnil;
- argc = INT2FIX(len);
- break;
- }
- default: {
- UNKNOWN_NODE("setup_arg", argn, Qnil);
- }
- }
- }
+ return keyword_node_p(node);
+}
- if (nsplat > 1) {
- int i;
- for (i=1; i<nsplat; i++) {
- ADD_INSN(args_splat, nd_line(args), concatarray);
- }
- }
+static VALUE
+setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
+ int dup_rest, unsigned int *flag, struct rb_callinfo_kwarg **keywords)
+{
+ if (argn) {
+ switch (nd_type(argn)) {
+ case NODE_SPLAT: {
+ NO_CHECK(COMPILE(args, "args (splat)", argn->nd_head));
+ ADD_INSN1(args, nd_line(argn), splatarray, dup_rest ? Qtrue : Qfalse);
+ if (flag) *flag |= VM_CALL_ARGS_SPLAT;
+ return INT2FIX(1);
+ }
+ case NODE_ARGSCAT:
+ case NODE_ARGSPUSH: {
+ int next_is_list = (nd_type(argn->nd_head) == NODE_LIST);
+ VALUE argc = setup_args_core(iseq, args, argn->nd_head, 1, NULL, NULL);
+ if (nd_type(argn->nd_body) == NODE_LIST) {
+ /* This branch is needed to avoid "newarraykwsplat" [Bug #16442] */
+ int rest_len = compile_args(iseq, args, argn->nd_body, NULL, NULL);
+ ADD_INSN1(args, nd_line(argn), newarray, INT2FIX(rest_len));
+ }
+ else {
+ NO_CHECK(COMPILE(args, "args (cat: splat)", argn->nd_body));
+ }
+ if (flag) {
+ *flag |= VM_CALL_ARGS_SPLAT;
+ /* This is a dirty hack. It traverses the AST twice.
+ * In a long term, it should be fixed by a redesign of keyword arguments */
+ if (check_keyword(argn->nd_body))
+ *flag |= VM_CALL_KW_SPLAT;
+ }
+ if (nd_type(argn) == NODE_ARGSCAT) {
+ if (next_is_list) {
+ ADD_INSN1(args, nd_line(argn), splatarray, Qtrue);
+ return INT2FIX(FIX2INT(argc) + 1);
+ }
+ else {
+ ADD_INSN1(args, nd_line(argn), splatarray, Qfalse);
+ ADD_INSN(args, nd_line(argn), concatarray);
+ return argc;
+ }
+ }
+ else {
+ ADD_INSN1(args, nd_line(argn), newarray, INT2FIX(1));
+ ADD_INSN(args, nd_line(argn), concatarray);
+ return argc;
+ }
+ }
+ case NODE_LIST: {
+ int len = compile_args(iseq, args, argn, keywords, flag);
+ return INT2FIX(len);
+ }
+ default: {
+ UNKNOWN_NODE("setup_arg", argn, Qnil);
+ }
+ }
+ }
+ return INT2FIX(0);
+}
- if (!LIST_SIZE_ZERO(args_splat)) {
- ADD_SEQ(args, args_splat);
+static VALUE
+setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
+ unsigned int *flag, struct rb_callinfo_kwarg **keywords)
+{
+ VALUE ret;
+ if (argn && nd_type(argn) == NODE_BLOCK_PASS) {
+ unsigned int dup_rest = 1;
+ DECL_ANCHOR(arg_block);
+ INIT_ANCHOR(arg_block);
+ NO_CHECK(COMPILE(arg_block, "block", argn->nd_body));
+
+ *flag |= VM_CALL_ARGS_BLOCKARG;
+
+ if (LIST_INSN_SIZE_ONE(arg_block)) {
+ LINK_ELEMENT *elem = FIRST_ELEMENT(arg_block);
+ if (elem->type == ISEQ_ELEMENT_INSN) {
+ INSN *iobj = (INSN *)elem;
+ if (iobj->insn_id == BIN(getblockparam)) {
+ iobj->insn_id = BIN(getblockparamproxy);
+ }
+ dup_rest = 0;
+ }
+ }
+ ret = setup_args_core(iseq, args, argn->nd_head, dup_rest, flag, keywords);
+ ADD_SEQ(args, arg_block);
}
-
- if (*flag & VM_CALL_ARGS_BLOCKARG) {
- ADD_SEQ(args, arg_block);
+ else {
+ ret = setup_args_core(iseq, args, argn, 0, flag, keywords);
}
- return argc;
+ return ret;
}
-static VALUE
-build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *body)
+static void
+build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *ret, const void *ptr)
{
+ const NODE *body = ptr;
int line = nd_line(body);
VALUE argc = INT2FIX(0);
const rb_iseq_t *block = NEW_CHILD_ISEQ(body, make_name_for_block(iseq->body->parent_iseq), ISEQ_TYPE_BLOCK, line);
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_CALL_WITH_BLOCK(ret, line, id_core_set_postexe, argc, block);
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block);
iseq_set_local_table(iseq, 0);
- return Qnil;
}
static void
-compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node)
+compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
{
- NODE *vars;
+ const NODE *vars;
LINK_ELEMENT *last;
int line = nd_line(node);
LABEL *fail_label = NEW_LABEL(line), *end_label = NEW_LABEL(line);
#if !(defined(NAMED_CAPTURE_BY_SVAR) && NAMED_CAPTURE_BY_SVAR-0)
- ADD_INSN1(ret, line, getglobal, ((VALUE)rb_global_entry(idBACKREF) | 1));
+ ADD_INSN1(ret, line, getglobal, ID2SYM(idBACKREF));
#else
ADD_INSN2(ret, line, getspecial, INT2FIX(1) /* '~' */, INT2FIX(0));
#endif
@@ -4170,11 +5326,11 @@ compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node
ADD_INSN(ret, line, dup);
}
last = ret->last;
- COMPILE_POPPED(ret, "capture", vars->nd_head);
+ NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head));
last = last->next; /* putobject :var */
cap = new_insn_send(iseq, line, idAREF, INT2FIX(1),
NULL, INT2FIX(0), NULL);
- INSERT_ELEM_PREV(last->next, (LINK_ELEMENT *)cap);
+ ELEM_INSERT_PREV(last->next, (LINK_ELEMENT *)cap);
#if !defined(NAMED_CAPTURE_SINGLE_OPT) || NAMED_CAPTURE_SINGLE_OPT-0
if (!vars->nd_next && vars == node) {
/* only one name */
@@ -4199,7 +5355,7 @@ compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node
ADD_INSN(ret, line, pop);
for (vars = node; vars; vars = vars->nd_next) {
last = ret->last;
- COMPILE_POPPED(ret, "capture", vars->nd_head);
+ NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head));
last = last->next; /* putobject :var */
((INSN*)last)->insn_id = BIN(putnil);
((INSN*)last)->operand_size = 0;
@@ -4208,23 +5364,35 @@ compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node
}
static int
-number_literal_p(NODE *n)
+optimizable_range_item_p(const NODE *n)
{
- return (n && nd_type(n) == NODE_LIT && RB_INTEGER_TYPE_P(n->nd_lit));
+ if (!n) return FALSE;
+ switch (nd_type(n)) {
+ case NODE_LIT:
+ return RB_INTEGER_TYPE_P(n->nd_lit);
+ case NODE_NIL:
+ return TRUE;
+ default:
+ return FALSE;
+ }
}
static int
-compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, const enum node_type type)
+compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const enum node_type type)
{
- NODE *node_body = type == NODE_IF ? node->nd_body : node->nd_else;
- NODE *node_else = type == NODE_IF ? node->nd_else : node->nd_body;
+ struct rb_iseq_constant_body *const body = iseq->body;
+ const NODE *const node_body = type == NODE_IF ? node->nd_body : node->nd_else;
+ const NODE *const node_else = type == NODE_IF ? node->nd_else : node->nd_body;
const int line = nd_line(node);
DECL_ANCHOR(cond_seq);
DECL_ANCHOR(then_seq);
DECL_ANCHOR(else_seq);
LABEL *then_label, *else_label, *end_label;
- VALUE branches = 0;
+ VALUE branches = Qfalse;
+ int ci_size;
+ VALUE catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ long catch_table_size = NIL_P(catch_table) ? 0 : RARRAY_LEN(catch_table);
INIT_ANCHOR(cond_seq);
INIT_ANCHOR(then_seq);
@@ -4235,29 +5403,64 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, cons
compile_branch_condition(iseq, cond_seq, node->nd_cond,
then_label, else_label);
+
+ ci_size = body->ci_size;
CHECK(COMPILE_(then_seq, "then", node_body, popped));
+ catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ if (!then_label->refcnt) {
+ body->ci_size = ci_size;
+ if (!NIL_P(catch_table)) rb_ary_set_len(catch_table, catch_table_size);
+ }
+ else {
+ if (!NIL_P(catch_table)) catch_table_size = RARRAY_LEN(catch_table);
+ }
+
+ ci_size = body->ci_size;
CHECK(COMPILE_(else_seq, "else", node_else, popped));
+ catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ if (!else_label->refcnt) {
+ body->ci_size = ci_size;
+ if (!NIL_P(catch_table)) rb_ary_set_len(catch_table, catch_table_size);
+ }
+ else {
+ if (!NIL_P(catch_table)) catch_table_size = RARRAY_LEN(catch_table);
+ }
ADD_SEQ(ret, cond_seq);
if (then_label->refcnt && else_label->refcnt) {
- DECL_BRANCH_BASE(branches, line, type == NODE_IF ? "if" : "unless");
+ branches = decl_branch_base(iseq, node, type == NODE_IF ? "if" : "unless");
}
if (then_label->refcnt) {
ADD_LABEL(ret, then_label);
if (else_label->refcnt) {
- ADD_TRACE_BRANCH_COVERAGE(ret, node_body ? nd_line(node_body) : line, type == NODE_IF ? "then" : "else", branches);
+ add_trace_branch_coverage(
+ iseq,
+ ret,
+ node_body ? node_body : node,
+ 0,
+ type == NODE_IF ? "then" : "else",
+ branches);
+ end_label = NEW_LABEL(line);
+ ADD_INSNL(then_seq, line, jump, end_label);
+ if (!popped) {
+ ADD_INSN(then_seq, line, pop);
+ }
}
ADD_SEQ(ret, then_seq);
- end_label = NEW_LABEL(line);
- ADD_INSNL(ret, line, jump, end_label);
}
if (else_label->refcnt) {
ADD_LABEL(ret, else_label);
if (then_label->refcnt) {
- ADD_TRACE_BRANCH_COVERAGE(ret, node_else ? nd_line(node_else) : line, type == NODE_IF ? "else" : "then", branches);
+ add_trace_branch_coverage(
+ iseq,
+ ret,
+ node_else ? node_else : node,
+ 1,
+ type == NODE_IF ? "else" : "then",
+ branches);
}
ADD_SEQ(ret, else_seq);
}
@@ -4270,10 +5473,10 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, cons
}
static int
-compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_node, int popped)
{
- NODE *vals;
- NODE *tempnode = node;
+ const NODE *vals;
+ const NODE *node = orig_node;
LABEL *endlabel, *elselabel;
DECL_ANCHOR(head);
DECL_ANCHOR(body_seq);
@@ -4282,31 +5485,24 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
VALUE literals = rb_hash_new();
int line;
enum node_type type;
- VALUE branches = 0;
+ VALUE branches = Qfalse;
+ int branch_id = 0;
INIT_ANCHOR(head);
INIT_ANCHOR(body_seq);
INIT_ANCHOR(cond_seq);
- rb_hash_tbl_raw(literals)->type = &cdhash_type;
+ RHASH_TBL_RAW(literals)->type = &cdhash_type;
- if (node->nd_head == 0) {
- CHECK(COMPILE_(ret, "when", node->nd_body, popped));
- return COMPILE_OK;
- }
CHECK(COMPILE(head, "case base", node->nd_head));
- DECL_BRANCH_BASE(branches, nd_line(node), "case");
+ branches = decl_branch_base(iseq, node, "case");
node = node->nd_body;
+ EXPECT_NODE("NODE_CASE", node, NODE_WHEN, COMPILE_NG);
type = nd_type(node);
line = nd_line(node);
- if (type != NODE_WHEN) {
- COMPILE_ERROR(ERROR_ARGS "NODE_CASE: unexpected node. must be NODE_WHEN, but %s", ruby_node_name(type));
- return COMPILE_NG;
- }
-
endlabel = NEW_LABEL(line);
elselabel = NEW_LABEL(line);
@@ -4318,31 +5514,35 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
l1 = NEW_LABEL(line);
ADD_LABEL(body_seq, l1);
ADD_INSN(body_seq, line, pop);
- ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_line(node->nd_body) : line, "when", branches);
+ add_trace_branch_coverage(
+ iseq,
+ body_seq,
+ node->nd_body ? node->nd_body : node,
+ branch_id++,
+ "when",
+ branches);
CHECK(COMPILE_(body_seq, "when body", node->nd_body, popped));
ADD_INSNL(body_seq, line, jump, endlabel);
vals = node->nd_head;
if (vals) {
switch (nd_type(vals)) {
- case NODE_ARRAY:
+ case NODE_LIST:
only_special_literals = when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals);
+ if (only_special_literals < 0) return COMPILE_NG;
break;
case NODE_SPLAT:
case NODE_ARGSCAT:
case NODE_ARGSPUSH:
only_special_literals = 0;
- ADD_INSN (cond_seq, nd_line(vals), dup);
- CHECK(COMPILE(cond_seq, "when/cond splat", vals));
- ADD_INSN1(cond_seq, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
- ADD_INSNL(cond_seq, nd_line(vals), branchif, l1);
+ CHECK(when_splat_vals(iseq, cond_seq, vals, l1, only_special_literals, literals));
break;
default:
UNKNOWN_NODE("NODE_CASE", vals, COMPILE_NG);
}
}
else {
- EXPECT_NODE_NONULL("NODE_CASE", node, NODE_ARRAY, COMPILE_NG);
+ EXPECT_NODE_NONULL("NODE_CASE", node, NODE_LIST, COMPILE_NG);
}
node = node->nd_next;
@@ -4356,26 +5556,25 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
if (node) {
ADD_LABEL(cond_seq, elselabel);
ADD_INSN(cond_seq, line, pop);
- ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_line(node), "else", branches);
+ add_trace_branch_coverage(iseq, cond_seq, node, branch_id, "else", branches);
CHECK(COMPILE_(cond_seq, "else", node, popped));
ADD_INSNL(cond_seq, line, jump, endlabel);
}
else {
debugs("== else (implicit)\n");
ADD_LABEL(cond_seq, elselabel);
- ADD_INSN(cond_seq, nd_line(tempnode), pop);
- ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_line(tempnode), "else", branches);
+ ADD_INSN(cond_seq, nd_line(orig_node), pop);
+ add_trace_branch_coverage(iseq, cond_seq, orig_node, branch_id, "else", branches);
if (!popped) {
- ADD_INSN(cond_seq, nd_line(tempnode), putnil);
+ ADD_INSN(cond_seq, nd_line(orig_node), putnil);
}
- ADD_INSNL(cond_seq, nd_line(tempnode), jump, endlabel);
+ ADD_INSNL(cond_seq, nd_line(orig_node), jump, endlabel);
}
- if (only_special_literals) {
- iseq_add_mark_object(iseq, literals);
-
- ADD_INSN(ret, nd_line(tempnode), dup);
- ADD_INSN2(ret, nd_line(tempnode), opt_case_dispatch, literals, elselabel);
+ if (only_special_literals && ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
+ ADD_INSN(ret, nd_line(orig_node), dup);
+ ADD_INSN2(ret, nd_line(orig_node), opt_case_dispatch, literals, elselabel);
+ RB_OBJ_WRITTEN(iseq, Qundef, literals);
LABEL_REF(elselabel);
}
@@ -4386,16 +5585,17 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_when(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_node, int popped)
{
- NODE *vals;
- NODE *val;
- NODE *orig_node = node;
+ const NODE *vals;
+ const NODE *val;
+ const NODE *node = orig_node->nd_body;
LABEL *endlabel;
DECL_ANCHOR(body_seq);
- VALUE branches = 0;
+ VALUE branches = Qfalse;
+ int branch_id = 0;
- DECL_BRANCH_BASE(branches, nd_line(node), "case");
+ branches = decl_branch_base(iseq, orig_node, "case");
INIT_ANCHOR(body_seq);
endlabel = NEW_LABEL(nd_line(node));
@@ -4404,21 +5604,29 @@ compile_when(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
const int line = nd_line(node);
LABEL *l1 = NEW_LABEL(line);
ADD_LABEL(body_seq, l1);
- ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_line(node->nd_body) : line, "when", branches);
+ add_trace_branch_coverage(
+ iseq,
+ body_seq,
+ node->nd_body ? node->nd_body : node,
+ branch_id++,
+ "when",
+ branches);
CHECK(COMPILE_(body_seq, "when", node->nd_body, popped));
ADD_INSNL(body_seq, line, jump, endlabel);
vals = node->nd_head;
if (!vals) {
- COMPILE_ERROR(ERROR_ARGS "NODE_WHEN: must be NODE_ARRAY, but 0");
- return COMPILE_NG;
+ EXPECT_NODE_NONULL("NODE_WHEN", node, NODE_LIST, COMPILE_NG);
}
switch (nd_type(vals)) {
- case NODE_ARRAY:
+ case NODE_LIST:
while (vals) {
+ LABEL *lnext;
val = vals->nd_head;
- CHECK(COMPILE(ret, "when2", val));
- ADD_INSNL(ret, nd_line(val), branchif, l1);
+ lnext = NEW_LABEL(nd_line(val));
+ debug_compile("== when2\n", (void)0);
+ CHECK(compile_branch_condition(iseq, ret, val, l1, lnext));
+ ADD_LABEL(ret, lnext);
vals = vals->nd_next;
}
break;
@@ -4436,7 +5644,13 @@ compile_when(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
node = node->nd_next;
}
/* else */
- ADD_TRACE_BRANCH_COVERAGE(ret, node ? nd_line(node) : nd_line(orig_node), "else", branches);
+ add_trace_branch_coverage(
+ iseq,
+ ret,
+ node ? node : orig_node,
+ branch_id,
+ "else",
+ branches);
CHECK(COMPILE_(ret, "else", node, popped));
ADD_INSNL(ret, nd_line(orig_node), jump, endlabel);
@@ -4445,15 +5659,831 @@ compile_when(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
return COMPILE_OK;
}
+static int iseq_compile_pattern_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, LABEL *unmatched, int in_alt_pattern, int deconstructed_pos);
+
+static int iseq_compile_array_deconstruct(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, LABEL *deconstruct, LABEL *deconstructed, LABEL *match_failed, LABEL *type_error, int deconstructed_pos);
+
+static int
+iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, LABEL *matched, LABEL *unmatched, int in_alt_pattern, int deconstructed_pos)
+{
+ const int line = nd_line(node);
+
+ switch (nd_type(node)) {
+ case NODE_ARYPTN: {
+ /*
+ * if pattern.use_rest_num?
+ * rest_num = 0
+ * end
+ * if pattern.has_constant_node?
+ * unless pattern.constant === obj
+ * goto match_failed
+ * end
+ * end
+ * unless obj.respond_to?(:deconstruct)
+ * goto match_failed
+ * end
+ * d = obj.deconstruct
+ * unless Array === d
+ * goto type_error
+ * end
+ * min_argc = pattern.pre_args_num + pattern.post_args_num
+ * if pattern.has_rest_arg?
+ * unless d.length >= min_argc
+ * goto match_failed
+ * end
+ * else
+ * unless d.length == min_argc
+ * goto match_failed
+ * end
+ * end
+ * pattern.pre_args_num.each do |i|
+ * unless pattern.pre_args[i].match?(d[i])
+ * goto match_failed
+ * end
+ * end
+ * if pattern.use_rest_num?
+ * rest_num = d.length - min_argc
+ * if pattern.has_rest_arg? && pattern.has_rest_arg_id # not `*`, but `*rest`
+ * unless pattern.rest_arg.match?(d[pattern.pre_args_num, rest_num])
+ * goto match_failed
+ * end
+ * end
+ * end
+ * pattern.post_args_num.each do |i|
+ * j = pattern.pre_args_num + i
+ * j += rest_num
+ * unless pattern.post_args[i].match?(d[j])
+ * goto match_failed
+ * end
+ * end
+ * goto matched
+ * type_error:
+ * FrozenCore.raise TypeError
+ * match_failed:
+ * goto unmatched
+ */
+ struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
+ const NODE *args = apinfo->pre_args;
+ const int pre_args_num = apinfo->pre_args ? rb_long2int(apinfo->pre_args->nd_alen) : 0;
+ const int post_args_num = apinfo->post_args ? rb_long2int(apinfo->post_args->nd_alen) : 0;
+
+ const int min_argc = pre_args_num + post_args_num;
+ const int use_rest_num = apinfo->rest_arg && (NODE_NAMED_REST_P(apinfo->rest_arg) ||
+ (!NODE_NAMED_REST_P(apinfo->rest_arg) && post_args_num > 0));
+
+ LABEL *match_failed, *type_error, *deconstruct, *deconstructed;
+ int i;
+ match_failed = NEW_LABEL(line);
+ type_error = NEW_LABEL(line);
+ deconstruct = NEW_LABEL(line);
+ deconstructed = NEW_LABEL(line);
+
+ if (use_rest_num) {
+ ADD_INSN1(ret, line, putobject, INT2FIX(0)); /* allocate stack for rest_num */
+ ADD_INSN(ret, line, swap);
+ if (deconstructed_pos) {
+ deconstructed_pos++;
+ }
+ }
+
+ if (node->nd_pconst) {
+ ADD_INSN(ret, line, dup);
+ CHECK(COMPILE(ret, "constant", node->nd_pconst));
+ ADD_INSN1(ret, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+ }
+
+ CHECK(iseq_compile_array_deconstruct(iseq, ret, node, deconstruct, deconstructed, match_failed, type_error, deconstructed_pos));
+
+ ADD_INSN(ret, line, dup);
+ ADD_SEND(ret, line, idLength, INT2FIX(0));
+ ADD_INSN1(ret, line, putobject, INT2FIX(min_argc));
+ ADD_SEND(ret, line, apinfo->rest_arg ? idGE : idEq, INT2FIX(1));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+
+ for (i = 0; i < pre_args_num; i++) {
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, putobject, INT2FIX(i));
+ ADD_SEND(ret, line, idAREF, INT2FIX(1));
+ CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, match_failed, in_alt_pattern, FALSE));
+ args = args->nd_next;
+ }
+
+ if (apinfo->rest_arg) {
+ if (NODE_NAMED_REST_P(apinfo->rest_arg)) {
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, putobject, INT2FIX(pre_args_num));
+ ADD_INSN1(ret, line, topn, INT2FIX(1));
+ ADD_SEND(ret, line, idLength, INT2FIX(0));
+ ADD_INSN1(ret, line, putobject, INT2FIX(min_argc));
+ ADD_SEND(ret, line, idMINUS, INT2FIX(1));
+ ADD_INSN1(ret, line, setn, INT2FIX(4));
+ ADD_SEND(ret, line, idAREF, INT2FIX(2));
+
+ CHECK(iseq_compile_pattern_match(iseq, ret, apinfo->rest_arg, match_failed, in_alt_pattern, FALSE));
+ }
+ else {
+ if (post_args_num > 0) {
+ ADD_INSN(ret, line, dup);
+ ADD_SEND(ret, line, idLength, INT2FIX(0));
+ ADD_INSN1(ret, line, putobject, INT2FIX(min_argc));
+ ADD_SEND(ret, line, idMINUS, INT2FIX(1));
+ ADD_INSN1(ret, line, setn, INT2FIX(2));
+ ADD_INSN(ret, line, pop);
+ }
+ }
+ }
+
+ args = apinfo->post_args;
+ for (i = 0; i < post_args_num; i++) {
+ ADD_INSN(ret, line, dup);
+
+ ADD_INSN1(ret, line, putobject, INT2FIX(pre_args_num + i));
+ ADD_INSN1(ret, line, topn, INT2FIX(3));
+ ADD_SEND(ret, line, idPLUS, INT2FIX(1));
+
+ ADD_SEND(ret, line, idAREF, INT2FIX(1));
+ CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, match_failed, in_alt_pattern, FALSE));
+ args = args->nd_next;
+ }
+
+ ADD_INSN(ret, line, pop);
+ if (use_rest_num) {
+ ADD_INSN(ret, line, pop);
+ }
+ ADD_INSNL(ret, line, jump, matched);
+ ADD_INSN(ret, line, putnil);
+ if (use_rest_num) {
+ ADD_INSN(ret, line, putnil);
+ }
+
+ ADD_LABEL(ret, type_error);
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_INSN1(ret, line, putobject, rb_eTypeError);
+ ADD_INSN1(ret, line, putobject, rb_fstring_lit("deconstruct must return Array"));
+ ADD_SEND(ret, line, id_core_raise, INT2FIX(2));
+ ADD_INSN(ret, line, pop);
+
+ ADD_LABEL(ret, match_failed);
+ ADD_INSN(ret, line, pop);
+ if (use_rest_num) {
+ ADD_INSN(ret, line, pop);
+ }
+ ADD_INSNL(ret, line, jump, unmatched);
+
+ break;
+ }
+ case NODE_FNDPTN: {
+ /*
+ * if pattern.has_constant_node?
+ * unless pattern.constant === obj
+ * goto match_failed
+ * end
+ * end
+ * unless obj.respond_to?(:deconstruct)
+ * goto match_failed
+ * end
+ * d = obj.deconstruct
+ * unless Array === d
+ * goto type_error
+ * end
+ * unless d.length >= pattern.args_num
+ * goto match_failed
+ * end
+ *
+ * begin
+ * len = d.length
+ * limit = d.length - pattern.args_num
+ * i = 0
+ * while i <= limit
+ * if pattern.args_num.times.all? {|j| pattern.args[j].match?(d[i+j]) }
+ * if pattern.has_pre_rest_arg_id
+ * unless pattern.pre_rest_arg.match?(d[0, i])
+ * goto find_failed
+ * end
+ * end
+ * if pattern.has_post_rest_arg_id
+ * unless pattern.post_rest_arg.match?(d[i+pattern.args_num, len])
+ * goto find_failed
+ * end
+ * end
+ * goto find_succeeded
+ * end
+ * i+=1
+ * end
+ * find_failed:
+ * goto match_failed
+ * find_succeeded:
+ * end
+ *
+ * goto matched
+ * type_error:
+ * FrozenCore.raise TypeError
+ * match_failed:
+ * goto unmatched
+ */
+ struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo;
+ const NODE *args = fpinfo->args;
+ const int args_num = fpinfo->args ? rb_long2int(fpinfo->args->nd_alen) : 0;
+
+ LABEL *match_failed, *type_error, *deconstruct, *deconstructed;
+ match_failed = NEW_LABEL(line);
+ type_error = NEW_LABEL(line);
+ deconstruct = NEW_LABEL(line);
+ deconstructed = NEW_LABEL(line);
+
+ if (node->nd_pconst) {
+ ADD_INSN(ret, line, dup);
+ CHECK(COMPILE(ret, "constant", node->nd_pconst));
+ ADD_INSN1(ret, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+ }
+
+ CHECK(iseq_compile_array_deconstruct(iseq, ret, node, deconstruct, deconstructed, match_failed, type_error, deconstructed_pos));
+
+ ADD_INSN(ret, line, dup);
+ ADD_SEND(ret, line, idLength, INT2FIX(0));
+ ADD_INSN1(ret, line, putobject, INT2FIX(args_num));
+ ADD_SEND(ret, line, idGE, INT2FIX(1));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+
+ {
+ LABEL *while_begin = NEW_LABEL(nd_line(node));
+ LABEL *next_loop = NEW_LABEL(nd_line(node));
+ LABEL *find_succeeded = NEW_LABEL(line);
+ LABEL *find_failed = NEW_LABEL(nd_line(node));
+ int j;
+
+ ADD_INSN(ret, line, dup); /* allocate stack for len */
+ ADD_SEND(ret, line, idLength, INT2FIX(0));
+
+ ADD_INSN(ret, line, dup); /* allocate stack for limit */
+ ADD_INSN1(ret, line, putobject, INT2FIX(args_num));
+ ADD_SEND(ret, line, idMINUS, INT2FIX(1));
+
+ ADD_INSN1(ret, line, putobject, INT2FIX(0)); /* allocate stack for i */
+
+ ADD_LABEL(ret, while_begin);
+
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, topn, INT2FIX(2));
+ ADD_SEND(ret, line, idLE, INT2FIX(1));
+ ADD_INSNL(ret, line, branchunless, find_failed);
+
+ for (j = 0; j < args_num; j++) {
+ ADD_INSN1(ret, line, topn, INT2FIX(3));
+ ADD_INSN1(ret, line, topn, INT2FIX(1));
+ if (j != 0) {
+ ADD_INSN1(ret, line, putobject, INT2FIX(j));
+ ADD_SEND(ret, line, idPLUS, INT2FIX(1));
+ }
+ ADD_SEND(ret, line, idAREF, INT2FIX(1));
+
+ CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, next_loop, in_alt_pattern, FALSE));
+ args = args->nd_next;
+ }
+
+ if (NODE_NAMED_REST_P(fpinfo->pre_rest_arg)) {
+ ADD_INSN1(ret, line, topn, INT2FIX(3));
+ ADD_INSN1(ret, line, putobject, INT2FIX(0));
+ ADD_INSN1(ret, line, topn, INT2FIX(2));
+ ADD_SEND(ret, line, idAREF, INT2FIX(2));
+ CHECK(iseq_compile_pattern_match(iseq, ret, fpinfo->pre_rest_arg, find_failed, in_alt_pattern, FALSE));
+ }
+ if (NODE_NAMED_REST_P(fpinfo->post_rest_arg)) {
+ ADD_INSN1(ret, line, topn, INT2FIX(3));
+ ADD_INSN1(ret, line, topn, INT2FIX(1));
+ ADD_INSN1(ret, line, putobject, INT2FIX(args_num));
+ ADD_SEND(ret, line, idPLUS, INT2FIX(1));
+ ADD_INSN1(ret, line, topn, INT2FIX(3));
+ ADD_SEND(ret, line, idAREF, INT2FIX(2));
+ CHECK(iseq_compile_pattern_match(iseq, ret, fpinfo->post_rest_arg, find_failed, in_alt_pattern, FALSE));
+ }
+ ADD_INSNL(ret, line, jump, find_succeeded);
+
+ ADD_LABEL(ret, next_loop);
+ ADD_INSN1(ret, line, putobject, INT2FIX(1));
+ ADD_SEND(ret, line, idPLUS, INT2FIX(1));
+ ADD_INSNL(ret, line, jump, while_begin);
+
+ ADD_LABEL(ret, find_failed);
+ ADD_INSN(ret, line, pop);
+ ADD_INSN(ret, line, pop);
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, match_failed);
+ ADD_INSN1(ret, line, dupn, INT2FIX(3));
+
+ ADD_LABEL(ret, find_succeeded);
+ ADD_INSN(ret, line, pop);
+ ADD_INSN(ret, line, pop);
+ ADD_INSN(ret, line, pop);
+ }
+
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, matched);
+ ADD_INSN(ret, line, putnil);
+
+ ADD_LABEL(ret, type_error);
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_INSN1(ret, line, putobject, rb_eTypeError);
+ ADD_INSN1(ret, line, putobject, rb_fstring_lit("deconstruct must return Array"));
+ ADD_SEND(ret, line, id_core_raise, INT2FIX(2));
+ ADD_INSN(ret, line, pop);
+
+ ADD_LABEL(ret, match_failed);
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, unmatched);
+
+ break;
+ }
+ case NODE_HSHPTN: {
+ /*
+ * keys = nil
+ * if pattern.has_kw_args_node? && !pattern.has_kw_rest_arg_node?
+ * keys = pattern.kw_args_node.keys
+ * end
+ * if pattern.has_constant_node?
+ * unless pattern.constant === obj
+ * goto match_failed
+ * end
+ * end
+ * unless obj.respond_to?(:deconstruct_keys)
+ * goto match_failed
+ * end
+ * d = obj.deconstruct_keys(keys)
+ * unless Hash === d
+ * goto type_error
+ * end
+ * if pattern.has_kw_rest_arg_node?
+ * d = d.dup
+ * end
+ * if pattern.has_kw_args_node?
+ * pattern.kw_args_node.each |k,|
+ * unless d.key?(k)
+ * goto match_failed
+ * end
+ * end
+ * pattern.kw_args_node.each |k, pat|
+ * if pattern.has_kw_rest_arg_node?
+ * unless pat.match?(d.delete(k))
+ * goto match_failed
+ * end
+ * else
+ * unless pat.match?(d[k])
+ * goto match_failed
+ * end
+ * end
+ * end
+ * else
+ * unless d.empty?
+ * goto match_failed
+ * end
+ * end
+ * if pattern.has_kw_rest_arg_node?
+ * if pattern.no_rest_keyword?
+ * unless d.empty?
+ * goto match_failed
+ * end
+ * else
+ * unless pattern.kw_rest_arg_node.match?(d)
+ * goto match_failed
+ * end
+ * end
+ * end
+ * goto matched
+ * type_error:
+ * FrozenCore.raise TypeError
+ * match_failed:
+ * goto unmatched
+ */
+ LABEL *match_failed, *type_error;
+ VALUE keys = Qnil;
+
+ match_failed = NEW_LABEL(line);
+ type_error = NEW_LABEL(line);
+
+ if (node->nd_pkwargs && !node->nd_pkwrestarg) {
+ const NODE *kw_args = node->nd_pkwargs->nd_head;
+ keys = rb_ary_new_capa(kw_args ? kw_args->nd_alen/2 : 0);
+ while (kw_args) {
+ rb_ary_push(keys, kw_args->nd_head->nd_lit);
+ kw_args = kw_args->nd_next->nd_next;
+ }
+ }
+
+ if (node->nd_pconst) {
+ ADD_INSN(ret, line, dup);
+ CHECK(COMPILE(ret, "constant", node->nd_pconst));
+ ADD_INSN1(ret, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+ }
+
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, putobject, ID2SYM(rb_intern("deconstruct_keys")));
+ ADD_SEND(ret, line, idRespond_to, INT2FIX(1));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+
+ if (NIL_P(keys)) {
+ ADD_INSN(ret, line, putnil);
+ }
+ else {
+ ADD_INSN1(ret, line, duparray, keys);
+ RB_OBJ_WRITTEN(iseq, Qundef, rb_obj_hide(keys));
+ }
+ ADD_SEND(ret, line, rb_intern("deconstruct_keys"), INT2FIX(1));
+
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, checktype, INT2FIX(T_HASH));
+ ADD_INSNL(ret, line, branchunless, type_error);
+
+ if (node->nd_pkwrestarg) {
+ ADD_SEND(ret, line, rb_intern("dup"), INT2FIX(0));
+ }
+
+ if (node->nd_pkwargs) {
+ int i;
+ int keys_num;
+ const NODE *args;
+ args = node->nd_pkwargs->nd_head;
+ if (args) {
+ DECL_ANCHOR(match_values);
+ INIT_ANCHOR(match_values);
+ keys_num = rb_long2int(args->nd_alen) / 2;
+ for (i = 0; i < keys_num; i++) {
+ NODE *key_node = args->nd_head;
+ NODE *value_node = args->nd_next->nd_head;
+ VALUE key;
+
+ if (nd_type(key_node) != NODE_LIT) {
+ UNKNOWN_NODE("NODE_IN", key_node, COMPILE_NG);
+ }
+ key = key_node->nd_lit;
+
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, putobject, key);
+ ADD_SEND(ret, line, rb_intern("key?"), INT2FIX(1));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+
+ ADD_INSN(match_values, line, dup);
+ ADD_INSN1(match_values, line, putobject, key);
+ ADD_SEND(match_values, line, node->nd_pkwrestarg ? rb_intern("delete") : idAREF, INT2FIX(1));
+ CHECK(iseq_compile_pattern_match(iseq, match_values, value_node, match_failed, in_alt_pattern, FALSE));
+ args = args->nd_next->nd_next;
+ }
+ ADD_SEQ(ret, match_values);
+ }
+ }
+ else {
+ ADD_INSN(ret, line, dup);
+ ADD_SEND(ret, line, idEmptyP, INT2FIX(0));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+ }
+
+ if (node->nd_pkwrestarg) {
+ if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
+ ADD_INSN(ret, line, dup);
+ ADD_SEND(ret, line, idEmptyP, INT2FIX(0));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+ }
+ else {
+ ADD_INSN(ret, line, dup);
+ CHECK(iseq_compile_pattern_match(iseq, ret, node->nd_pkwrestarg, match_failed, in_alt_pattern, FALSE));
+ }
+ }
+
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, matched);
+ ADD_INSN(ret, line, putnil);
+
+ ADD_LABEL(ret, type_error);
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_INSN1(ret, line, putobject, rb_eTypeError);
+ ADD_INSN1(ret, line, putobject, rb_fstring_lit("deconstruct_keys must return Hash"));
+ ADD_SEND(ret, line, id_core_raise, INT2FIX(2));
+ ADD_INSN(ret, line, pop);
+
+ ADD_LABEL(ret, match_failed);
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, unmatched);
+ break;
+ }
+ case NODE_LIT:
+ case NODE_STR:
+ case NODE_XSTR:
+ case NODE_DSTR:
+ case NODE_DSYM:
+ case NODE_DREGX:
+ case NODE_LIST:
+ case NODE_ZLIST:
+ case NODE_LAMBDA:
+ case NODE_DOT2:
+ case NODE_DOT3:
+ case NODE_CONST:
+ case NODE_LVAR:
+ case NODE_DVAR:
+ case NODE_TRUE:
+ case NODE_FALSE:
+ case NODE_SELF:
+ case NODE_NIL:
+ case NODE_COLON2:
+ case NODE_COLON3:
+ CHECK(COMPILE(ret, "case in literal", node));
+ ADD_INSN1(ret, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
+ ADD_INSNL(ret, line, branchif, matched);
+ ADD_INSNL(ret, line, jump, unmatched);
+ break;
+ case NODE_LASGN: {
+ struct rb_iseq_constant_body *const body = iseq->body;
+ ID id = node->nd_vid;
+ int idx = body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
+
+ if (in_alt_pattern) {
+ const char *name = rb_id2name(id);
+ if (name && strlen(name) > 0 && name[0] != '_') {
+ COMPILE_ERROR(ERROR_ARGS "illegal variable in alternative pattern (%"PRIsVALUE")",
+ rb_id2str(id));
+ return COMPILE_NG;
+ }
+ }
+
+ ADD_SETLOCAL(ret, line, idx, get_lvar_level(iseq));
+ ADD_INSNL(ret, line, jump, matched);
+ break;
+ }
+ case NODE_DASGN:
+ case NODE_DASGN_CURR: {
+ int idx, lv, ls;
+ ID id = node->nd_vid;
+
+ idx = get_dyna_var_idx(iseq, id, &lv, &ls);
+
+ if (in_alt_pattern) {
+ const char *name = rb_id2name(id);
+ if (name && strlen(name) > 0 && name[0] != '_') {
+ COMPILE_ERROR(ERROR_ARGS "illegal variable in alternative pattern (%"PRIsVALUE")",
+ rb_id2str(id));
+ return COMPILE_NG;
+ }
+ }
+
+ if (idx < 0) {
+ COMPILE_ERROR(ERROR_ARGS "NODE_DASGN(_CURR): unknown id (%"PRIsVALUE")",
+ rb_id2str(id));
+ return COMPILE_NG;
+ }
+ ADD_SETLOCAL(ret, line, ls - idx, lv);
+ ADD_INSNL(ret, line, jump, matched);
+ break;
+ }
+ case NODE_IF:
+ case NODE_UNLESS: {
+ LABEL *match_failed;
+ match_failed = unmatched;
+ CHECK(iseq_compile_pattern_match(iseq, ret, node->nd_body, unmatched, in_alt_pattern, deconstructed_pos));
+ CHECK(COMPILE(ret, "case in if", node->nd_cond));
+ if (nd_type(node) == NODE_IF) {
+ ADD_INSNL(ret, line, branchunless, match_failed);
+ }
+ else {
+ ADD_INSNL(ret, line, branchif, match_failed);
+ }
+ ADD_INSNL(ret, line, jump, matched);
+ break;
+ }
+ case NODE_HASH: {
+ NODE *n;
+ LABEL *match_failed;
+ match_failed = NEW_LABEL(line);
+
+ n = node->nd_head;
+ if (! (nd_type(n) == NODE_LIST && n->nd_alen == 2)) {
+ COMPILE_ERROR(ERROR_ARGS "unexpected node");
+ return COMPILE_NG;
+ }
+
+ ADD_INSN(ret, line, dup);
+ CHECK(iseq_compile_pattern_match(iseq, ret, n->nd_head, match_failed, in_alt_pattern, deconstructed_pos ? deconstructed_pos + 1 : FALSE));
+ CHECK(iseq_compile_pattern_each(iseq, ret, n->nd_next->nd_head, matched, match_failed, in_alt_pattern, FALSE));
+ ADD_INSN(ret, line, putnil);
+
+ ADD_LABEL(ret, match_failed);
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, unmatched);
+ break;
+ }
+ case NODE_OR: {
+ LABEL *match_succeeded, *fin;
+ match_succeeded = NEW_LABEL(line);
+ fin = NEW_LABEL(line);
+
+ ADD_INSN(ret, line, dup);
+ CHECK(iseq_compile_pattern_each(iseq, ret, node->nd_1st, match_succeeded, fin, TRUE, deconstructed_pos ? deconstructed_pos + 1 : FALSE));
+ ADD_LABEL(ret, match_succeeded);
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, matched);
+ ADD_INSN(ret, line, putnil);
+ ADD_LABEL(ret, fin);
+ CHECK(iseq_compile_pattern_each(iseq, ret, node->nd_2nd, matched, unmatched, TRUE, deconstructed_pos));
+ break;
+ }
+ default:
+ UNKNOWN_NODE("NODE_IN", node, COMPILE_NG);
+ }
+ return COMPILE_OK;
+}
+
+static int
+iseq_compile_pattern_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, LABEL *unmatched, int in_alt_pattern, int deconstructed_pos)
+{
+ LABEL *fin = NEW_LABEL(nd_line(node));
+ CHECK(iseq_compile_pattern_each(iseq, ret, node, fin, unmatched, in_alt_pattern, deconstructed_pos));
+ ADD_LABEL(ret, fin);
+ return COMPILE_OK;
+}
+
+static int
+iseq_compile_array_deconstruct(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, LABEL *deconstruct, LABEL *deconstructed, LABEL *match_failed, LABEL *type_error, int deconstructed_pos)
+{
+ const int line = nd_line(node);
+
+ // NOTE: this optimization allows us to re-use the #deconstruct value
+ // (or its absence).
+ // `deconstructed_pos` contains the distance to the stack relative location
+ // where the value is stored.
+ if (deconstructed_pos) {
+ // If value is nil then we haven't tried to deconstruct
+ ADD_INSN1(ret, line, topn, INT2FIX(deconstructed_pos));
+ ADD_INSNL(ret, line, branchnil, deconstruct);
+
+ // If false then the value is not deconstructable
+ ADD_INSN1(ret, line, topn, INT2FIX(deconstructed_pos));
+ ADD_INSNL(ret, line, branchunless, match_failed);
+
+ // Drop value, add deconstructed to the stack and jump
+ ADD_INSN(ret, line, pop);
+ ADD_INSN1(ret, line, topn, INT2FIX(deconstructed_pos - 1));
+ ADD_INSNL(ret, line, jump, deconstructed);
+ }
+ else {
+ ADD_INSNL(ret, line, jump, deconstruct);
+ }
+
+ ADD_LABEL(ret, deconstruct);
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, putobject, ID2SYM(rb_intern("deconstruct")));
+ ADD_SEND(ret, line, idRespond_to, INT2FIX(1));
+
+ // Cache the result of respond_to? (in case it's false is stays there, if true - it's overwritten after #deconstruct)
+ if (deconstructed_pos) {
+ ADD_INSN1(ret, line, setn, INT2FIX(deconstructed_pos + 1));
+ }
+
+ ADD_INSNL(ret, line, branchunless, match_failed);
+
+ ADD_SEND(ret, line, rb_intern("deconstruct"), INT2FIX(0));
+
+ // Cache the result (if it's cacheable - currently, only top-level array patterns)
+ if (deconstructed_pos) {
+ ADD_INSN1(ret, line, setn, INT2FIX(deconstructed_pos));
+ }
+
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, checktype, INT2FIX(T_ARRAY));
+ ADD_INSNL(ret, line, branchunless, type_error);
+ ADD_INSNL(ret, line, jump, deconstructed);
+
+ ADD_LABEL(ret, deconstructed);
+
+ return COMPILE_OK;
+}
+
+static int
+compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_node, int popped)
+{
+ const NODE *pattern;
+ const NODE *node = orig_node;
+ LABEL *endlabel, *elselabel;
+ DECL_ANCHOR(head);
+ DECL_ANCHOR(body_seq);
+ DECL_ANCHOR(cond_seq);
+ int line;
+ enum node_type type;
+ VALUE branches = 0;
+ int branch_id = 0;
+
+ INIT_ANCHOR(head);
+ INIT_ANCHOR(body_seq);
+ INIT_ANCHOR(cond_seq);
+
+ branches = decl_branch_base(iseq, node, "case");
+
+ node = node->nd_body;
+ EXPECT_NODE("NODE_CASE3", node, NODE_IN, COMPILE_NG);
+ type = nd_type(node);
+ line = nd_line(node);
+
+ endlabel = NEW_LABEL(line);
+ elselabel = NEW_LABEL(line);
+
+ ADD_INSN(head, line, putnil); /* allocate stack for cached #deconstruct value */
+
+ CHECK(COMPILE(head, "case base", orig_node->nd_head));
+
+ ADD_SEQ(ret, head); /* case VAL */
+
+ while (type == NODE_IN) {
+ LABEL *l1;
+
+ if (branch_id) {
+ ADD_INSN(body_seq, line, putnil);
+ }
+ l1 = NEW_LABEL(line);
+ ADD_LABEL(body_seq, l1);
+ ADD_INSN(body_seq, line, pop);
+ ADD_INSN(body_seq, line, pop); /* discard cached #deconstruct value */
+ add_trace_branch_coverage(
+ iseq,
+ body_seq,
+ node->nd_body ? node->nd_body : node,
+ branch_id++,
+ "in",
+ branches);
+ CHECK(COMPILE_(body_seq, "in body", node->nd_body, popped));
+ ADD_INSNL(body_seq, line, jump, endlabel);
+
+ pattern = node->nd_head;
+ if (pattern) {
+ int pat_line = nd_line(pattern);
+ LABEL *next_pat = NEW_LABEL(pat_line);
+ ADD_INSN (cond_seq, pat_line, dup);
+ // NOTE: set deconstructed_pos to the current cached value location
+ // (it's "under" the matchee value, so it's position is 2)
+ CHECK(iseq_compile_pattern_each(iseq, cond_seq, pattern, l1, next_pat, FALSE, 2));
+ ADD_LABEL(cond_seq, next_pat);
+ LABEL_UNREMOVABLE(next_pat);
+ }
+ else {
+ COMPILE_ERROR(ERROR_ARGS "unexpected node");
+ return COMPILE_NG;
+ }
+
+ node = node->nd_next;
+ if (!node) {
+ break;
+ }
+ type = nd_type(node);
+ line = nd_line(node);
+ }
+ /* else */
+ if (node) {
+ ADD_LABEL(cond_seq, elselabel);
+ ADD_INSN(cond_seq, line, pop);
+ ADD_INSN(cond_seq, line, pop); /* discard cached #deconstruct value */
+ add_trace_branch_coverage(iseq, cond_seq, node, branch_id, "else", branches);
+ CHECK(COMPILE_(cond_seq, "else", node, popped));
+ ADD_INSNL(cond_seq, line, jump, endlabel);
+ ADD_INSN(cond_seq, line, putnil);
+ if (popped) {
+ ADD_INSN(cond_seq, line, putnil);
+ }
+ }
+ else {
+ debugs("== else (implicit)\n");
+ ADD_LABEL(cond_seq, elselabel);
+ add_trace_branch_coverage(iseq, cond_seq, orig_node, branch_id, "else", branches);
+ ADD_INSN1(cond_seq, nd_line(orig_node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_INSN1(cond_seq, nd_line(orig_node), putobject, rb_eNoMatchingPatternError);
+ ADD_INSN1(cond_seq, nd_line(orig_node), topn, INT2FIX(2));
+ ADD_SEND(cond_seq, nd_line(orig_node), id_core_raise, INT2FIX(2));
+ ADD_INSN(cond_seq, nd_line(orig_node), pop);
+ ADD_INSN(cond_seq, nd_line(orig_node), pop);
+ ADD_INSN(cond_seq, nd_line(orig_node), pop); /* discard cached #deconstruct value */
+ if (!popped) {
+ ADD_INSN(cond_seq, nd_line(orig_node), putnil);
+ }
+ ADD_INSNL(cond_seq, nd_line(orig_node), jump, endlabel);
+ ADD_INSN(cond_seq, line, putnil);
+ if (popped) {
+ ADD_INSN(cond_seq, line, putnil);
+ }
+ }
+
+ ADD_SEQ(ret, cond_seq);
+ ADD_SEQ(ret, body_seq);
+ ADD_LABEL(ret, endlabel);
+ return COMPILE_OK;
+}
+
static int
-compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, const enum node_type type)
+compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const enum node_type type)
{
const int line = (int)nd_line(node);
+
LABEL *prev_start_label = ISEQ_COMPILE_DATA(iseq)->start_label;
LABEL *prev_end_label = ISEQ_COMPILE_DATA(iseq)->end_label;
LABEL *prev_redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label;
int prev_loopval_popped = ISEQ_COMPILE_DATA(iseq)->loopval_popped;
- VALUE branches = 0;
+ VALUE branches = Qfalse;
struct iseq_compile_data_ensure_node_stack enl;
@@ -4469,7 +6499,7 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, co
ISEQ_COMPILE_DATA(iseq)->loopval_popped = 0;
push_ensure_entry(iseq, &enl, NULL, NULL);
- if (type == NODE_OPT_N || node->nd_state == 1) {
+ if (node->nd_state == 1) {
ADD_INSNL(ret, line, jump, next_label);
}
else {
@@ -4484,8 +6514,14 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, co
if (tmp_label) ADD_LABEL(ret, tmp_label);
ADD_LABEL(ret, redo_label);
- DECL_BRANCH_BASE(branches, line, type == NODE_WHILE ? "while" : "until");
- ADD_TRACE_BRANCH_COVERAGE(ret, node->nd_body ? nd_line(node->nd_body) : line, "body", branches);
+ branches = decl_branch_base(iseq, node, type == NODE_WHILE ? "while" : "until");
+ add_trace_branch_coverage(
+ iseq,
+ ret,
+ node->nd_body ? node->nd_body : node,
+ 0,
+ "body",
+ branches);
CHECK(COMPILE_POPPED(ret, "while body", node->nd_body));
ADD_LABEL(ret, next_label); /* next */
@@ -4493,17 +6529,11 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, co
compile_branch_condition(iseq, ret, node->nd_cond,
redo_label, end_label);
}
- else if (type == NODE_UNTIL) {
+ else {
/* until */
compile_branch_condition(iseq, ret, node->nd_cond,
end_label, redo_label);
}
- else {
- ADD_CALL_RECEIVER(ret, line);
- ADD_CALL(ret, line, idGets, INT2FIX(0));
- ADD_INSNL(ret, line, branchif, redo_label);
- /* opt_n */
- }
ADD_LABEL(ret, end_label);
ADD_ADJUST_RESTORE(ret, adjust_label);
@@ -4539,10 +6569,77 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, co
}
static int
-compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_iter(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ const int line = nd_line(node);
+ const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
+ LABEL *retry_label = NEW_LABEL(line);
+ LABEL *retry_end_l = NEW_LABEL(line);
+ const rb_iseq_t *child_iseq;
+
+ ADD_LABEL(ret, retry_label);
+ if (nd_type(node) == NODE_FOR) {
+ CHECK(COMPILE(ret, "iter caller (for)", node->nd_iter));
+
+ ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq =
+ NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
+ ISEQ_TYPE_BLOCK, line);
+ ADD_SEND_WITH_BLOCK(ret, line, idEach, INT2FIX(0), child_iseq);
+ }
+ else {
+ ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq =
+ NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
+ ISEQ_TYPE_BLOCK, line);
+ CHECK(COMPILE(ret, "iter caller", node->nd_iter));
+ }
+ ADD_LABEL(ret, retry_end_l);
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+
+ ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
+
+ ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l);
+ return COMPILE_OK;
+}
+
+static int
+compile_for_masgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ /* massign to var in "for"
+ * (args.length == 1 && Array.try_convert(args[0])) || args
+ */
+ const int line = nd_line(node);
+ const NODE *var = node->nd_var;
+ LABEL *not_single = NEW_LABEL(nd_line(var));
+ LABEL *not_ary = NEW_LABEL(nd_line(var));
+ CHECK(COMPILE(ret, "for var", var));
+ ADD_INSN(ret, line, dup);
+ ADD_CALL(ret, line, idLength, INT2FIX(0));
+ ADD_INSN1(ret, line, putobject, INT2FIX(1));
+ ADD_CALL(ret, line, idEq, INT2FIX(1));
+ ADD_INSNL(ret, line, branchunless, not_single);
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, putobject, INT2FIX(0));
+ ADD_CALL(ret, line, idAREF, INT2FIX(1));
+ ADD_INSN1(ret, line, putobject, rb_cArray);
+ ADD_INSN(ret, line, swap);
+ ADD_CALL(ret, line, rb_intern("try_convert"), INT2FIX(1));
+ ADD_INSN(ret, line, dup);
+ ADD_INSNL(ret, line, branchunless, not_ary);
+ ADD_INSN(ret, line, swap);
+ ADD_LABEL(ret, not_ary);
+ ADD_INSN(ret, line, pop);
+ ADD_LABEL(ret, not_single);
+ return COMPILE_OK;
+}
+
+static int
+compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
- unsigned long level = 0;
+ unsigned long throw_flag = 0;
if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0) {
/* while/until */
@@ -4559,22 +6656,8 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
ADD_INSN(ret, line, putnil);
}
}
- else if (iseq->body->type == ISEQ_TYPE_BLOCK) {
- break_by_insn:
- /* escape from block */
- CHECK(COMPILE(ret, "break val (block)", node->nd_stts));
- ADD_INSN1(ret, line, throw, INT2FIX(level | TAG_BREAK));
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
- }
- else if (iseq->body->type == ISEQ_TYPE_EVAL) {
- break_in_eval:
- COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with break");
- return COMPILE_NG;
- }
else {
- const rb_iseq_t *ip = iseq->body->parent_iseq;
+ const rb_iseq_t *ip = iseq;
while (ip) {
if (!ISEQ_COMPILE_DATA(ip)) {
@@ -4582,20 +6665,28 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
break;
}
- level++;
if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
- level = VM_THROW_NO_ESCAPE_FLAG;
- goto break_by_insn;
+ throw_flag = VM_THROW_NO_ESCAPE_FLAG;
}
else if (ip->body->type == ISEQ_TYPE_BLOCK) {
- level <<= VM_THROW_LEVEL_SHIFT;
- goto break_by_insn;
+ throw_flag = 0;
}
else if (ip->body->type == ISEQ_TYPE_EVAL) {
- goto break_in_eval;
- }
-
- ip = ip->body->parent_iseq;
+ COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with break");
+ return COMPILE_NG;
+ }
+ else {
+ ip = ip->body->parent_iseq;
+ continue;
+ }
+
+ /* escape from block */
+ CHECK(COMPILE(ret, "break val (block)", node->nd_stts));
+ ADD_INSN1(ret, line, throw, INT2FIX(throw_flag | TAG_BREAK));
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ return COMPILE_OK;
}
COMPILE_ERROR(ERROR_ARGS "Invalid break");
return COMPILE_NG;
@@ -4604,10 +6695,10 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
- unsigned long level = 0;
+ unsigned long throw_flag = 0;
if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0) {
LABEL *splabel = NEW_LABEL(0);
@@ -4631,16 +6722,12 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
add_ensure_iseq(ret, iseq, 0);
ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
ADD_ADJUST_RESTORE(ret, splabel);
+ splabel->unremovable = FALSE;
if (!popped) {
ADD_INSN(ret, line, putnil);
}
}
- else if (iseq->body->type == ISEQ_TYPE_EVAL) {
- next_in_eval:
- COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with next");
- return COMPILE_NG;
- }
else {
const rb_iseq_t *ip = iseq;
@@ -4650,7 +6737,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
break;
}
- level = VM_THROW_NO_ESCAPE_FLAG;
+ throw_flag = VM_THROW_NO_ESCAPE_FLAG;
if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
/* while loop */
break;
@@ -4659,14 +6746,15 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
break;
}
else if (ip->body->type == ISEQ_TYPE_EVAL) {
- goto next_in_eval;
+ COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with next");
+ return COMPILE_NG;
}
ip = ip->body->parent_iseq;
}
if (ip != 0) {
CHECK(COMPILE(ret, "next val", node->nd_stts));
- ADD_INSN1(ret, line, throw, INT2FIX(level | TAG_NEXT));
+ ADD_INSN1(ret, line, throw, INT2FIX(throw_flag | TAG_NEXT));
if (popped) {
ADD_INSN(ret, line, pop);
@@ -4681,7 +6769,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
@@ -4697,12 +6785,7 @@ compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
ADD_INSN(ret, line, putnil);
}
}
- else if (iseq->body->type == ISEQ_TYPE_EVAL) {
- redo_in_eval:
- COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with redo");
- return COMPILE_NG;
- }
- else if (ISEQ_COMPILE_DATA(iseq)->start_label) {
+ else if (iseq->body->type != ISEQ_TYPE_EVAL && ISEQ_COMPILE_DATA(iseq)->start_label) {
LABEL *splabel = NEW_LABEL(0);
debugs("redo in block");
@@ -4718,7 +6801,6 @@ compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
else {
const rb_iseq_t *ip = iseq;
- const unsigned long level = VM_THROW_NO_ESCAPE_FLAG;
while (ip) {
if (!ISEQ_COMPILE_DATA(ip)) {
@@ -4733,14 +6815,15 @@ compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
break;
}
else if (ip->body->type == ISEQ_TYPE_EVAL) {
- goto redo_in_eval;
+ COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with redo");
+ return COMPILE_NG;
}
ip = ip->body->parent_iseq;
}
if (ip != 0) {
ADD_INSN(ret, line, putnil);
- ADD_INSN1(ret, line, throw, INT2FIX(level | TAG_REDO));
+ ADD_INSN1(ret, line, throw, INT2FIX(VM_THROW_NO_ESCAPE_FLAG | TAG_REDO));
if (popped) {
ADD_INSN(ret, line, pop);
@@ -4755,7 +6838,7 @@ compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_retry(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_retry(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
@@ -4775,7 +6858,7 @@ compile_retry(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
LABEL *lstart = NEW_LABEL(line);
@@ -4808,11 +6891,11 @@ compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
- NODE *resq = node;
- NODE *narg;
+ const NODE *resq = node;
+ const NODE *narg;
LABEL *label_miss, *label_hit;
while (resq) {
@@ -4822,7 +6905,7 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
narg = resq->nd_args;
if (narg) {
switch (nd_type(narg)) {
- case NODE_ARRAY:
+ case NODE_LIST:
while (narg) {
ADD_GETLOCAL(ret, line, LVAR_ERRINFO, 0);
CHECK(COMPILE(ret, "rescue arg", narg->nd_head));
@@ -4863,7 +6946,7 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
}
static int
-compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
DECL_ANCHOR(ensr);
@@ -4892,15 +6975,8 @@ compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
ADD_LABEL(ret, lstart);
CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave)));
ADD_LABEL(ret, lend);
- if (ensr->anchor.next == NULL) {
- ADD_INSN(ret, line, nop);
- }
- else {
- ADD_SEQ(ret, ensr);
- if (!popped && last_leave) {
- ADD_INSN(ret, line, putnil);
- }
- }
+ ADD_SEQ(ret, ensr);
+ if (!popped && last_leave) ADD_INSN(ret, line, putnil);
ADD_LABEL(ret, lcont);
if (last_leave) ADD_INSN(ret, line, pop);
@@ -4917,7 +6993,513 @@ compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
return COMPILE_OK;
}
-static int iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped);
+static int
+compile_return(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ const int line = nd_line(node);
+
+ if (iseq) {
+ enum iseq_type type = iseq->body->type;
+ const rb_iseq_t *is = iseq;
+ enum iseq_type t = type;
+ const NODE *retval = node->nd_stts;
+ LABEL *splabel = 0;
+
+ while (t == ISEQ_TYPE_RESCUE || t == ISEQ_TYPE_ENSURE) {
+ if (!(is = is->body->parent_iseq)) break;
+ t = is->body->type;
+ }
+ switch (t) {
+ case ISEQ_TYPE_TOP:
+ case ISEQ_TYPE_MAIN:
+ if (retval) {
+ rb_warn("argument of top-level return is ignored");
+ }
+ if (is == iseq) {
+ /* plain top-level, leave directly */
+ type = ISEQ_TYPE_METHOD;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (type == ISEQ_TYPE_METHOD) {
+ splabel = NEW_LABEL(0);
+ ADD_LABEL(ret, splabel);
+ ADD_ADJUST(ret, line, 0);
+ }
+
+ CHECK(COMPILE(ret, "return nd_stts (return val)", retval));
+
+ if (type == ISEQ_TYPE_METHOD) {
+ add_ensure_iseq(ret, iseq, 1);
+ ADD_TRACE(ret, RUBY_EVENT_RETURN);
+ ADD_INSN(ret, line, leave);
+ ADD_ADJUST_RESTORE(ret, splabel);
+
+ if (!popped) {
+ ADD_INSN(ret, line, putnil);
+ }
+ }
+ else {
+ ADD_INSN1(ret, line, throw, INT2FIX(TAG_RETURN));
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ }
+ }
+ return COMPILE_OK;
+}
+
+static int
+compile_evstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ CHECK(COMPILE_(ret, "nd_body", node, popped));
+
+ if (!popped && !all_string_result_p(node)) {
+ const int line = nd_line(node);
+ const unsigned int flag = VM_CALL_FCALL;
+ LABEL *isstr = NEW_LABEL(line);
+ ADD_INSN(ret, line, dup);
+ ADD_INSN1(ret, line, checktype, INT2FIX(T_STRING));
+ ADD_INSNL(ret, line, branchif, isstr);
+ ADD_INSN(ret, line, dup);
+ ADD_SEND_R(ret, line, idTo_s, INT2FIX(0), NULL, INT2FIX(flag), NULL);
+ ADD_INSN(ret, line, tostring);
+ ADD_LABEL(ret, isstr);
+ }
+ return COMPILE_OK;
+}
+
+static LABEL *
+qcall_branch_start(rb_iseq_t *iseq, LINK_ANCHOR *const recv, VALUE *branches, const NODE *node, int line)
+{
+ LABEL *else_label = NEW_LABEL(line);
+ VALUE br = 0;
+
+ br = decl_branch_base(iseq, node, "&.");
+ *branches = br;
+ ADD_INSN(recv, line, dup);
+ ADD_INSNL(recv, line, branchnil, else_label);
+ add_trace_branch_coverage(iseq, recv, node, 0, "then", br);
+ return else_label;
+}
+
+static void
+qcall_branch_end(rb_iseq_t *iseq, LINK_ANCHOR *const ret, LABEL *else_label, VALUE branches, const NODE *node, int line)
+{
+ LABEL *end_label;
+ if (!else_label) return;
+ end_label = NEW_LABEL(line);
+ ADD_INSNL(ret, line, jump, end_label);
+ ADD_LABEL(ret, else_label);
+ add_trace_branch_coverage(iseq, ret, node, 1, "else", branches);
+ ADD_LABEL(ret, end_label);
+}
+
+static int
+compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int line, int popped)
+{
+ /* optimization shortcut
+ * "literal".freeze -> opt_str_freeze("literal")
+ */
+ if (node->nd_recv && nd_type(node->nd_recv) == NODE_STR &&
+ (node->nd_mid == idFreeze || node->nd_mid == idUMinus) &&
+ node->nd_args == NULL &&
+ ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
+ ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
+ VALUE str = rb_fstring(node->nd_recv->nd_lit);
+ if (node->nd_mid == idUMinus) {
+ ADD_INSN2(ret, line, opt_str_uminus, str,
+ new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
+ }
+ else {
+ ADD_INSN2(ret, line, opt_str_freeze, str,
+ new_callinfo(iseq, idFreeze, 0, 0, NULL, FALSE));
+ }
+ RB_OBJ_WRITTEN(iseq, Qundef, str);
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ return TRUE;
+ }
+ /* optimization shortcut
+ * obj["literal"] -> opt_aref_with(obj, "literal")
+ */
+ if (node->nd_mid == idAREF && !private_recv_p(node) && node->nd_args &&
+ nd_type(node->nd_args) == NODE_LIST && node->nd_args->nd_alen == 1 &&
+ nd_type(node->nd_args->nd_head) == NODE_STR &&
+ ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
+ !ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
+ ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
+ VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
+ CHECK(COMPILE(ret, "recv", node->nd_recv));
+ ADD_INSN2(ret, line, opt_aref_with, str,
+ new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
+ RB_OBJ_WRITTEN(iseq, Qundef, str);
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int
+iseq_has_builtin_function_table(const rb_iseq_t *iseq)
+{
+ return ISEQ_COMPILE_DATA(iseq)->builtin_function_table != NULL;
+}
+
+static const struct rb_builtin_function *
+iseq_builtin_function_lookup(const rb_iseq_t *iseq, const char *name)
+{
+ int i;
+ const struct rb_builtin_function *table = ISEQ_COMPILE_DATA(iseq)->builtin_function_table;
+ for (i=0; table[i].index != -1; i++) {
+ if (strcmp(table[i].name, name) == 0) {
+ return &table[i];
+ }
+ }
+ return NULL;
+}
+
+static const char *
+iseq_builtin_function_name(const enum node_type type, const NODE *recv, ID mid)
+{
+ const char *name = rb_id2name(mid);
+ static const char prefix[] = "__builtin_";
+ const size_t prefix_len = sizeof(prefix) - 1;
+
+ switch (type) {
+ case NODE_CALL:
+ if (recv) {
+ switch (nd_type(recv)) {
+ case NODE_VCALL:
+ if (recv->nd_mid == rb_intern("__builtin")) {
+ return name;
+ }
+ break;
+ case NODE_CONST:
+ if (recv->nd_vid == rb_intern("Primitive")) {
+ return name;
+ }
+ break;
+ default: break;
+ }
+ }
+ break;
+ case NODE_VCALL:
+ case NODE_FCALL:
+ if (UNLIKELY(strncmp(prefix, name, prefix_len) == 0)) {
+ return &name[prefix_len];
+ }
+ break;
+ default: break;
+ }
+ return NULL;
+}
+
+static int
+delegate_call_p(const rb_iseq_t *iseq, unsigned int argc, const LINK_ANCHOR *args, unsigned int *pstart_index)
+{
+
+ if (argc == 0) {
+ *pstart_index = 0;
+ return TRUE;
+ }
+ else if (argc <= iseq->body->local_table_size) {
+ unsigned int start=0;
+
+ // local_table: [p1, p2, p3, l1, l2, l3]
+ // arguments: [p3, l1, l2] -> 2
+ for (start = 0;
+ argc + start <= iseq->body->local_table_size;
+ start++) {
+ const LINK_ELEMENT *elem = FIRST_ELEMENT(args);
+
+ for (unsigned int i=start; i-start<argc; i++) {
+ if (elem->type == ISEQ_ELEMENT_INSN &&
+ INSN_OF(elem) == BIN(getlocal)) {
+ int local_index = FIX2INT(OPERAND_AT(elem, 0));
+ int local_level = FIX2INT(OPERAND_AT(elem, 1));
+
+ if (local_level == 0) {
+ unsigned int index = iseq->body->local_table_size - (local_index - VM_ENV_DATA_SIZE + 1);
+ if (0) { // for debug
+ fprintf(stderr, "lvar:%s (%d), id:%s (%d) local_index:%d, local_size:%d\n",
+ rb_id2name(iseq->body->local_table[i]), i,
+ rb_id2name(iseq->body->local_table[index]), index,
+ local_index, (int)iseq->body->local_table_size);
+ }
+ if (i == index) {
+ elem = elem->next;
+ continue; /* for */
+ }
+ else {
+ goto next;
+ }
+ }
+ else {
+ goto fail; // level != 0 is unsupported
+ }
+ }
+ else {
+ goto fail; // insn is not a getlocal
+ }
+ }
+ goto success;
+ next:;
+ }
+ fail:
+ return FALSE;
+ success:
+ *pstart_index = start;
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static int
+compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int line, int popped,
+ const rb_iseq_t *parent_block, LINK_ANCHOR *args, const char *builtin_func)
+{
+ NODE *args_node = node->nd_args;
+
+ if (parent_block != NULL) {
+ COMPILE_ERROR(iseq, line, "should not call builtins here.");
+ return COMPILE_NG;
+ }
+ else {
+# define BUILTIN_INLINE_PREFIX "_bi"
+ char inline_func[DECIMAL_SIZE_OF_BITS(sizeof(int) * CHAR_BIT) + sizeof(BUILTIN_INLINE_PREFIX)];
+ bool cconst = false;
+ retry:;
+ const struct rb_builtin_function *bf = iseq_builtin_function_lookup(iseq, builtin_func);
+
+ if (bf == NULL) {
+ if (strcmp("cstmt!", builtin_func) == 0 ||
+ strcmp("cexpr!", builtin_func) == 0) {
+ // ok
+ }
+ else if (strcmp("cconst!", builtin_func) == 0) {
+ cconst = true;
+ }
+ else if (strcmp("cinit!", builtin_func) == 0) {
+ // ignore
+ GET_VM()->builtin_inline_index++;
+ return COMPILE_OK;
+ }
+ else if (strcmp("attr!", builtin_func) == 0) {
+ // There's only "inline" attribute for now
+ iseq->body->builtin_inline_p = true;
+ return COMPILE_OK;
+ }
+ else if (1) {
+ rb_bug("can't find builtin function:%s", builtin_func);
+ }
+ else {
+ COMPILE_ERROR(ERROR_ARGS "can't find builtin function:%s", builtin_func);
+ return COMPILE_NG;
+ }
+
+ if (GET_VM()->builtin_inline_index == INT_MAX) {
+ rb_bug("builtin inline function index overflow:%s", builtin_func);
+ }
+ int inline_index = GET_VM()->builtin_inline_index++;
+ snprintf(inline_func, sizeof(inline_func), BUILTIN_INLINE_PREFIX "%d", inline_index);
+ builtin_func = inline_func;
+ args_node = NULL;
+ goto retry;
+ }
+
+ if (cconst) {
+ typedef VALUE(*builtin_func0)(void *, VALUE);
+ VALUE const_val = (*(builtin_func0)bf->func_ptr)(NULL, Qnil);
+ ADD_INSN1(ret, line, putobject, const_val);
+ return COMPILE_OK;
+ }
+
+ // fprintf(stderr, "func_name:%s -> %p\n", builtin_func, bf->func_ptr);
+
+ unsigned int flag = 0;
+ struct rb_callinfo_kwarg *keywords = NULL;
+ VALUE argc = setup_args(iseq, args, args_node, &flag, &keywords);
+
+ if (FIX2INT(argc) != bf->argc) {
+ COMPILE_ERROR(ERROR_ARGS "argc is not match for builtin function:%s (expect %d but %d)",
+ builtin_func, bf->argc, FIX2INT(argc));
+ return COMPILE_NG;
+ }
+
+ unsigned int start_index;
+ if (delegate_call_p(iseq, FIX2INT(argc), args, &start_index)) {
+ ADD_INSN2(ret, line, opt_invokebuiltin_delegate, bf, INT2FIX(start_index));
+ }
+ else {
+ ADD_SEQ(ret, args);
+ ADD_INSN1(ret,line, invokebuiltin, bf);
+ }
+
+ if (popped) ADD_INSN(ret, line, pop);
+ return COMPILE_OK;
+ }
+}
+
+static int
+compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, const enum node_type type, int line, int popped)
+{
+ /* call: obj.method(...)
+ * fcall: func(...)
+ * vcall: func
+ */
+ DECL_ANCHOR(recv);
+ DECL_ANCHOR(args);
+ ID mid = node->nd_mid;
+ VALUE argc;
+ unsigned int flag = 0;
+ struct rb_callinfo_kwarg *keywords = NULL;
+ const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
+ LABEL *else_label = NULL;
+ VALUE branches = Qfalse;
+
+ ISEQ_COMPILE_DATA(iseq)->current_block = NULL;
+
+ INIT_ANCHOR(recv);
+ INIT_ANCHOR(args);
+#if OPT_SUPPORT_JOKE
+ if (nd_type(node) == NODE_VCALL) {
+ ID id_bitblt;
+ ID id_answer;
+
+ CONST_ID(id_bitblt, "bitblt");
+ CONST_ID(id_answer, "the_answer_to_life_the_universe_and_everything");
+
+ if (mid == id_bitblt) {
+ ADD_INSN(ret, line, bitblt);
+ return COMPILE_OK;
+ }
+ else if (mid == id_answer) {
+ ADD_INSN(ret, line, answer);
+ return COMPILE_OK;
+ }
+ }
+ /* only joke */
+ {
+ ID goto_id;
+ ID label_id;
+
+ CONST_ID(goto_id, "__goto__");
+ CONST_ID(label_id, "__label__");
+
+ if (nd_type(node) == NODE_FCALL &&
+ (mid == goto_id || mid == label_id)) {
+ LABEL *label;
+ st_data_t data;
+ st_table *labels_table = ISEQ_COMPILE_DATA(iseq)->labels_table;
+ VALUE label_name;
+
+ if (!labels_table) {
+ labels_table = st_init_numtable();
+ ISEQ_COMPILE_DATA(iseq)->labels_table = labels_table;
+ }
+ if (nd_type(node->nd_args->nd_head) == NODE_LIT &&
+ SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
+
+ label_name = node->nd_args->nd_head->nd_lit;
+ if (!st_lookup(labels_table, (st_data_t)label_name, &data)) {
+ label = NEW_LABEL(line);
+ label->position = line;
+ st_insert(labels_table, (st_data_t)label_name, (st_data_t)label);
+ }
+ else {
+ label = (LABEL *)data;
+ }
+ }
+ else {
+ COMPILE_ERROR(ERROR_ARGS "invalid goto/label format");
+ return COMPILE_NG;
+ }
+
+ if (mid == goto_id) {
+ ADD_INSNL(ret, line, jump, label);
+ }
+ else {
+ ADD_LABEL(ret, label);
+ }
+ return COMPILE_OK;
+ }
+ }
+#endif
+
+ const char *builtin_func;
+ if (UNLIKELY(iseq_has_builtin_function_table(iseq)) &&
+ (builtin_func = iseq_builtin_function_name(type, node->nd_recv, mid)) != NULL) {
+ return compile_builtin_function_call(iseq, ret, node, line, popped, parent_block, args, builtin_func);
+ }
+
+ /* receiver */
+ if (type == NODE_CALL || type == NODE_OPCALL || type == NODE_QCALL) {
+ int idx, level;
+
+ if (mid == idCall &&
+ nd_type(node->nd_recv) == NODE_LVAR &&
+ iseq_block_param_id_p(iseq, node->nd_recv->nd_vid, &idx, &level)) {
+ ADD_INSN2(recv, nd_line(node->nd_recv), getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
+ }
+ else if (private_recv_p(node)) {
+ ADD_INSN(recv, nd_line(node), putself);
+ flag |= VM_CALL_FCALL;
+ }
+ else {
+ CHECK(COMPILE(recv, "recv", node->nd_recv));
+ }
+
+ if (type == NODE_QCALL) {
+ else_label = qcall_branch_start(iseq, recv, &branches, node, line);
+ }
+ }
+ else if (type == NODE_FCALL || type == NODE_VCALL) {
+ ADD_CALL_RECEIVER(recv, line);
+ }
+
+ /* args */
+ if (type != NODE_VCALL) {
+ argc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
+ CHECK(!NIL_P(argc));
+ }
+ else {
+ argc = INT2FIX(0);
+ }
+
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, args);
+
+ debugp_param("call args argc", argc);
+ debugp_param("call method", ID2SYM(mid));
+
+ switch ((int)type) {
+ case NODE_VCALL:
+ flag |= VM_CALL_VCALL;
+ /* VCALL is funcall, so fall through */
+ case NODE_FCALL:
+ flag |= VM_CALL_FCALL;
+ }
+
+ ADD_SEND_R(ret, line, mid, argc, parent_block, INT2FIX(flag), keywords);
+
+ qcall_branch_end(iseq, ret, else_label, branches, node, line);
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ return COMPILE_OK;
+}
+
+
+static int iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped);
/**
compile each node
@@ -4926,35 +7508,51 @@ static int iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *nod
popped: This node will be popped
*/
static int
-iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *node, int popped)
{
if (node == 0) {
- if (!popped) {
- debugs("node: NODE_NIL(implicit)\n");
- ADD_INSN(ret, ISEQ_COMPILE_DATA(iseq)->last_line, putnil);
- }
- return COMPILE_OK;
+ if (!popped) {
+ int lineno = ISEQ_COMPILE_DATA(iseq)->last_line;
+ if (lineno == 0) lineno = FIX2INT(rb_iseq_first_lineno(iseq));
+ debugs("node: NODE_NIL(implicit)\n");
+ ADD_INSN(ret, lineno, putnil);
+ }
+ return COMPILE_OK;
}
return iseq_compile_each0(iseq, ret, node, popped);
}
+static int
+check_yield_place(const rb_iseq_t *iseq)
+{
+ switch (iseq->body->local_iseq->body->type) {
+ case ISEQ_TYPE_TOP:
+ case ISEQ_TYPE_MAIN:
+ case ISEQ_TYPE_CLASS:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
static int
-iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped)
+iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped)
{
- LINK_ELEMENT *saved_last_element = 0;
const int line = (int)nd_line(node);
const enum node_type type = nd_type(node);
+ struct rb_iseq_constant_body *const body = iseq->body;
if (ISEQ_COMPILE_DATA(iseq)->last_line == line) {
/* ignore */
}
else {
if (node->flags & NODE_FL_NEWLINE) {
+ int event = RUBY_EVENT_LINE;
ISEQ_COMPILE_DATA(iseq)->last_line = line;
- ADD_TRACE_LINE_COVERAGE(ret, line);
- ADD_TRACE(ret, line, RUBY_EVENT_LINE);
- saved_last_element = ret->last;
+ if (ISEQ_COVERAGE(iseq) && ISEQ_LINE_COVERAGE(iseq)) {
+ event |= RUBY_EVENT_COVERAGE_LINE;
+ }
+ ADD_TRACE(ret, event);
}
}
@@ -4981,74 +7579,23 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
case NODE_CASE:
CHECK(compile_case(iseq, ret, node, popped));
break;
- case NODE_WHEN:
- CHECK(compile_when(iseq, ret, node, popped));
+ case NODE_CASE2:
+ CHECK(compile_case2(iseq, ret, node, popped));
break;
- case NODE_OPT_N:
+ case NODE_CASE3:
+ CHECK(compile_case3(iseq, ret, node, popped));
+ break;
case NODE_WHILE:
case NODE_UNTIL:
CHECK(compile_loop(iseq, ret, node, popped, type));
break;
case NODE_FOR:
- if (node->nd_var) {
- /* massign to var in "for"
- * args.length == 1 && Array === (tmp = args[0]) ? tmp : args
- */
- NODE *var = node->nd_var;
- LABEL *not_single = NEW_LABEL(nd_line(var));
- LABEL *not_ary = NEW_LABEL(nd_line(var));
- CHECK(COMPILE(ret, "for var", var));
- ADD_INSN(ret, line, dup);
- ADD_CALL(ret, line, idLength, INT2FIX(0));
- ADD_INSN1(ret, line, putobject, INT2FIX(1));
- ADD_CALL(ret, line, idEq, INT2FIX(1));
- ADD_INSNL(ret, line, branchunless, not_single);
- ADD_INSN(ret, line, dup);
- ADD_INSN1(ret, line, putobject, INT2FIX(0));
- ADD_CALL(ret, line, idAREF, INT2FIX(1));
- ADD_INSN1(ret, line, putobject, rb_cArray);
- ADD_INSN1(ret, line, topn, INT2FIX(1));
- ADD_CALL(ret, line, idEqq, INT2FIX(1));
- ADD_INSNL(ret, line, branchunless, not_ary);
- ADD_INSN(ret, line, swap);
- ADD_LABEL(ret, not_ary);
- ADD_INSN(ret, line, pop);
- ADD_LABEL(ret, not_single);
- break;
- }
- case NODE_ITER:{
- const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
- LABEL *retry_label = NEW_LABEL(line);
- LABEL *retry_end_l = NEW_LABEL(line);
- const rb_iseq_t *child_iseq;
-
- ADD_LABEL(ret, retry_label);
- if (nd_type(node) == NODE_FOR) {
- CHECK(COMPILE(ret, "iter caller (for)", node->nd_iter));
-
- ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq =
- NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK, line);
- ADD_SEND_WITH_BLOCK(ret, line, idEach, INT2FIX(0), child_iseq);
- }
- else {
- ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq =
- NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK, line);
- CHECK(COMPILE(ret, "iter caller", node->nd_iter));
- }
- ADD_LABEL(ret, retry_end_l);
-
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
-
- ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
-
- ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l);
-
+ case NODE_ITER:
+ CHECK(compile_iter(iseq, ret, node, popped));
+ break;
+ case NODE_FOR_MASGN:
+ CHECK(compile_for_masgn(iseq, ret, node, popped));
break;
- }
case NODE_BREAK:
CHECK(compile_break(iseq, ret, node, popped));
break;
@@ -5103,7 +7650,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
case NODE_LASGN:{
ID id = node->nd_vid;
- int idx = iseq->body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
+ int idx = body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
debugs("lvar: %s idx: %d\n", rb_id2name(id), idx);
CHECK(COMPILE(ret, "rvalue", node->nd_value));
@@ -5117,18 +7664,19 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
case NODE_DASGN:
case NODE_DASGN_CURR:{
int idx, lv, ls;
+ ID id = node->nd_vid;
CHECK(COMPILE(ret, "dvalue", node->nd_value));
- debugi("dassn id", rb_id2str(node->nd_vid) ? node->nd_vid : '*');
+ debugi("dassn id", rb_id2str(id) ? id : '*');
if (!popped) {
ADD_INSN(ret, line, dup);
}
- idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
+ idx = get_dyna_var_idx(iseq, id, &lv, &ls);
if (idx < 0) {
COMPILE_ERROR(ERROR_ARGS "NODE_DASGN(_CURR): unknown id (%"PRIsVALUE")",
- rb_id2str(node->nd_vid));
+ rb_id2str(id));
goto ng;
}
ADD_SETLOCAL(ret, line, ls - idx, lv);
@@ -5140,12 +7688,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
if (!popped) {
ADD_INSN(ret, line, dup);
}
- ADD_INSN1(ret, line, setglobal,
- ((VALUE)node->nd_entry | 1));
+ ADD_INSN1(ret, line, setglobal, ID2SYM(node->nd_entry));
break;
}
- case NODE_IASGN:
- case NODE_IASGN2:{
+ case NODE_IASGN:{
CHECK(COMPILE(ret, "lvalue", node->nd_value));
if (!popped) {
ADD_INSN(ret, line, dup);
@@ -5156,20 +7702,20 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
break;
}
case NODE_CDECL:{
- CHECK(COMPILE(ret, "lvalue", node->nd_value));
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
- if (!popped) {
- ADD_INSN(ret, line, dup);
- }
+ if (!popped) {
+ ADD_INSN(ret, line, dup);
+ }
if (node->nd_vid) {
ADD_INSN1(ret, line, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- ADD_INSN1(ret, line, setconstant, ID2SYM(node->nd_vid));
+ ADD_INSN1(ret, line, setconstant, ID2SYM(node->nd_vid));
}
else {
compile_cpath(ret, iseq, node->nd_else);
- ADD_INSN1(ret, line, setconstant, ID2SYM(node->nd_else->nd_mid));
+ ADD_INSN1(ret, line, setconstant, ID2SYM(node->nd_else->nd_mid));
}
break;
}
@@ -5183,10 +7729,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
break;
}
case NODE_OP_ASGN1: {
- DECL_ANCHOR(args);
VALUE argc;
unsigned int flag = 0;
- unsigned int asgnflag = 0;
+ int asgnflag = 0;
ID id = node->nd_mid;
int boff = 0;
@@ -5217,25 +7762,24 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_INSN(ret, line, putnil);
}
asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN1 recv", node);
+ CHECK(asgnflag != -1);
switch (nd_type(node->nd_args->nd_head)) {
- case NODE_ZARRAY:
+ case NODE_ZLIST:
argc = INT2FIX(0);
break;
case NODE_BLOCK_PASS:
boff = 1;
+ /* fall through */
default:
- INIT_ANCHOR(args);
- argc = setup_args(iseq, args, node->nd_args->nd_head, &flag, NULL);
+ argc = setup_args(iseq, ret, node->nd_args->nd_head, &flag, NULL);
CHECK(!NIL_P(argc));
- ADD_SEQ(ret, args);
}
ADD_INSN1(ret, line, dupn, FIXNUM_INC(argc, 1 + boff));
+ flag |= asgnflag;
ADD_SEND_WITH_FLAG(ret, line, idAREF, argc, INT2FIX(flag));
- flag |= asgnflag;
- if (id == 0 || id == 1) {
- /* 0: or, 1: and
- a[x] ||= y
+ if (id == idOROP || id == idANDOP) {
+ /* a[x] ||= y or a[x] &&= y
unless/if a[x]
a[x]= y
@@ -5247,12 +7791,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
LABEL *lfin = NEW_LABEL(line);
ADD_INSN(ret, line, dup);
- if (id == 0) {
- /* or */
+ if (id == idOROP) {
ADD_INSNL(ret, line, branchif, label);
}
- else {
- /* and */
+ else { /* idANDOP */
ADD_INSNL(ret, line, branchunless, label);
}
ADD_INSN(ret, line, pop);
@@ -5324,7 +7866,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
case NODE_OP_ASGN2:{
ID atype = node->nd_next->nd_mid;
ID vid = node->nd_next->nd_vid, aid = rb_id_attrset(vid);
- VALUE asgnflag;
+ int asgnflag;
LABEL *lfin = NEW_LABEL(line);
LABEL *lcfin = NEW_LABEL(line);
LABEL *lskip = 0;
@@ -5371,20 +7913,21 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
*/
asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN2#recv", node);
+ CHECK(asgnflag != -1);
if (node->nd_next->nd_aid) {
lskip = NEW_LABEL(line);
ADD_INSN(ret, line, dup);
ADD_INSNL(ret, line, branchnil, lskip);
}
ADD_INSN(ret, line, dup);
- ADD_SEND(ret, line, vid, INT2FIX(0));
+ ADD_SEND_WITH_FLAG(ret, line, vid, INT2FIX(0), INT2FIX(asgnflag));
- if (atype == 0 || atype == 1) { /* 0: OR or 1: AND */
+ if (atype == idOROP || atype == idANDOP) {
ADD_INSN(ret, line, dup);
- if (atype == 0) {
+ if (atype == idOROP) {
ADD_INSNL(ret, line, branchif, lcfin);
}
- else {
+ else { /* idANDOP */
ADD_INSNL(ret, line, branchunless, lcfin);
}
ADD_INSN(ret, line, pop);
@@ -5444,22 +7987,23 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
mid = node->nd_head->nd_mid;
/* cref */
- if (node->nd_aid == 0) {
+ if (node->nd_aid == idOROP) {
lassign = NEW_LABEL(line);
ADD_INSN(ret, line, dup); /* cref cref */
- ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_CONST),
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_CONST_FROM),
ID2SYM(mid), Qfalse); /* cref bool */
ADD_INSNL(ret, line, branchunless, lassign); /* cref */
}
ADD_INSN(ret, line, dup); /* cref cref */
- ADD_INSN1(ret, line, getconstant, ID2SYM(mid)); /* cref obj */
+ ADD_INSN1(ret, line, putobject, Qtrue);
+ ADD_INSN1(ret, line, getconstant, ID2SYM(mid)); /* cref obj */
- if (node->nd_aid == 0 || node->nd_aid == 1) {
+ if (node->nd_aid == idOROP || node->nd_aid == idANDOP) {
lfin = NEW_LABEL(line);
if (!popped) ADD_INSN(ret, line, dup); /* cref [obj] obj */
- if (node->nd_aid == 0)
+ if (node->nd_aid == idOROP)
ADD_INSNL(ret, line, branchif, lfin);
- else
+ else /* idANDOP */
ADD_INSNL(ret, line, branchunless, lfin);
/* cref [obj] */
if (!popped) ADD_INSN(ret, line, pop); /* cref */
@@ -5496,7 +8040,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
LABEL *lfin = NEW_LABEL(line);
LABEL *lassign;
- if (nd_type(node) == NODE_OP_ASGN_OR) {
+ if (nd_type(node) == NODE_OP_ASGN_OR && nd_type(node->nd_head) != NODE_IVAR) {
LABEL *lfinish[2];
lfinish[0] = lfin;
lfinish[1] = 0;
@@ -5532,194 +8076,24 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
break;
}
- case NODE_CALL:
- case NODE_OPCALL:
- /* optimization shortcut
- * "literal".freeze -> opt_str_freeze("literal")
- */
- if (node->nd_recv && nd_type(node->nd_recv) == NODE_STR &&
- (node->nd_mid == idFreeze || node->nd_mid == idUMinus) &&
- node->nd_args == NULL &&
- ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
- ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
- VALUE str = rb_fstring(node->nd_recv->nd_lit);
- iseq_add_mark_object(iseq, str);
- if (node->nd_mid == idUMinus) {
- ADD_INSN1(ret, line, opt_str_uminus, str);
- }
- else {
- ADD_INSN1(ret, line, opt_str_freeze, str);
- }
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
- break;
- }
- /* optimization shortcut
- * obj["literal"] -> opt_aref_with(obj, "literal")
- */
- if (node->nd_mid == idAREF && !private_recv_p(node) && node->nd_args &&
- nd_type(node->nd_args) == NODE_ARRAY && node->nd_args->nd_alen == 1 &&
- nd_type(node->nd_args->nd_head) == NODE_STR &&
- ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
- ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
- VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
- node->nd_args->nd_head->nd_lit = str;
- CHECK(COMPILE(ret, "recv", node->nd_recv));
- ADD_INSN3(ret, line, opt_aref_with,
- new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE),
- NULL/* CALL_CACHE */, str);
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
- break;
- }
- case NODE_QCALL:
- case NODE_FCALL:
- case NODE_VCALL:{ /* VCALL: variable or call */
- /*
- call: obj.method(...)
- fcall: func(...)
- vcall: func
- */
- DECL_ANCHOR(recv);
- DECL_ANCHOR(args);
- LABEL *else_label = 0;
- LABEL *end_label = 0;
- VALUE branches = 0;
- ID mid = node->nd_mid;
- VALUE argc;
- unsigned int flag = 0;
- struct rb_call_info_kw_arg *keywords = NULL;
- const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
- ISEQ_COMPILE_DATA(iseq)->current_block = NULL;
-
- INIT_ANCHOR(recv);
- INIT_ANCHOR(args);
-#if SUPPORT_JOKE
- if (nd_type(node) == NODE_VCALL) {
- ID id_bitblt;
- ID id_answer;
-
- CONST_ID(id_bitblt, "bitblt");
- CONST_ID(id_answer, "the_answer_to_life_the_universe_and_everything");
-
- if (mid == id_bitblt) {
- ADD_INSN(ret, line, bitblt);
- break;
- }
- else if (mid == id_answer) {
- ADD_INSN(ret, line, answer);
- break;
- }
- }
- /* only joke */
- {
- ID goto_id;
- ID label_id;
-
- CONST_ID(goto_id, "__goto__");
- CONST_ID(label_id, "__label__");
-
- if (nd_type(node) == NODE_FCALL &&
- (mid == goto_id || mid == label_id)) {
- LABEL *label;
- st_data_t data;
- st_table *labels_table = ISEQ_COMPILE_DATA(iseq)->labels_table;
- VALUE label_name;
-
- if (!labels_table) {
- labels_table = st_init_numtable();
- ISEQ_COMPILE_DATA(iseq)->labels_table = labels_table;
- }
- if (nd_type(node->nd_args->nd_head) == NODE_LIT &&
- SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
-
- label_name = node->nd_args->nd_head->nd_lit;
- if (!st_lookup(labels_table, (st_data_t)label_name, &data)) {
- label = NEW_LABEL(line);
- label->position = line;
- st_insert(labels_table, (st_data_t)label_name, (st_data_t)label);
- }
- else {
- label = (LABEL *)data;
- }
- }
- else {
- COMPILE_ERROR(ERROR_ARGS "invalid goto/label format");
- goto ng;
- }
-
-
- if (mid == goto_id) {
- ADD_INSNL(ret, line, jump, label);
- }
- else {
- ADD_LABEL(ret, label);
- }
- break;
- }
- }
-#endif
- /* receiver */
- if (type == NODE_CALL || type == NODE_OPCALL || type == NODE_QCALL) {
- CHECK(COMPILE(recv, "recv", node->nd_recv));
- if (type == NODE_QCALL) {
- else_label = NEW_LABEL(line);
- end_label = NEW_LABEL(line);
-
- DECL_BRANCH_BASE(branches, nd_line(node), "&.");
- ADD_INSN(recv, line, dup);
- ADD_INSNL(recv, line, branchnil, else_label);
- ADD_TRACE_BRANCH_COVERAGE(recv, nd_line(node), "then", branches);
- }
- }
- else if (type == NODE_FCALL || type == NODE_VCALL) {
- ADD_CALL_RECEIVER(recv, line);
- }
-
- /* args */
- if (type != NODE_VCALL) {
- argc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
- CHECK(!NIL_P(argc));
- }
- else {
- argc = INT2FIX(0);
- }
-
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, args);
-
- debugp_param("call args argc", argc);
- debugp_param("call method", ID2SYM(mid));
-
- switch ((int)type) {
- case NODE_VCALL:
- flag |= VM_CALL_VCALL;
- /* VCALL is funcall, so fall through */
- case NODE_FCALL:
- flag |= VM_CALL_FCALL;
- }
-
- ADD_SEND_R(ret, line, mid, argc, parent_block, INT2FIX(flag), keywords);
-
- if (else_label && end_label) {
- ADD_INSNL(ret, line, jump, end_label);
- ADD_LABEL(ret, else_label);
- ADD_TRACE_BRANCH_COVERAGE(ret, nd_line(node), "else", branches);
- ADD_LABEL(ret, end_label);
- }
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
- break;
- }
+ case NODE_CALL: /* obj.foo */
+ case NODE_OPCALL: /* foo[] */
+ if (compile_call_precheck_freeze(iseq, ret, node, line, popped) == TRUE) {
+ break;
+ }
+ case NODE_QCALL: /* obj&.foo */
+ case NODE_FCALL: /* foo() */
+ case NODE_VCALL: /* foo (variable or call) */
+ if (compile_call(iseq, ret, node, type, line, popped) == COMPILE_NG) {
+ goto ng;
+ }
+ break;
case NODE_SUPER:
case NODE_ZSUPER:{
DECL_ANCHOR(args);
int argc;
unsigned int flag = 0;
- struct rb_call_info_kw_arg *keywords = NULL;
+ struct rb_callinfo_kwarg *keywords = NULL;
const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
INIT_ANCHOR(args);
@@ -5732,44 +8106,48 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
else {
/* NODE_ZSUPER */
int i;
- const rb_iseq_t *liseq = iseq->body->local_iseq;
+ const rb_iseq_t *liseq = body->local_iseq;
+ const struct rb_iseq_constant_body *const local_body = liseq->body;
+ const struct rb_iseq_param_keyword *const local_kwd = local_body->param.keyword;
int lvar_level = get_lvar_level(iseq);
- argc = liseq->body->param.lead_num;
+ argc = local_body->param.lead_num;
/* normal arguments */
- for (i = 0; i < liseq->body->param.lead_num; i++) {
- int idx = liseq->body->local_table_size - i;
+ for (i = 0; i < local_body->param.lead_num; i++) {
+ int idx = local_body->local_table_size - i;
ADD_GETLOCAL(args, line, idx, lvar_level);
}
- if (liseq->body->param.flags.has_opt) {
+ if (local_body->param.flags.has_opt) {
/* optional arguments */
int j;
- for (j = 0; j < liseq->body->param.opt_num; j++) {
- int idx = liseq->body->local_table_size - (i + j);
+ for (j = 0; j < local_body->param.opt_num; j++) {
+ int idx = local_body->local_table_size - (i + j);
ADD_GETLOCAL(args, line, idx, lvar_level);
}
i += j;
argc = i;
}
- if (liseq->body->param.flags.has_rest) {
+ if (local_body->param.flags.has_rest) {
/* rest argument */
- int idx = liseq->body->local_table_size - liseq->body->param.rest_start;
+ int idx = local_body->local_table_size - local_body->param.rest_start;
+
ADD_GETLOCAL(args, line, idx, lvar_level);
+ ADD_INSN1(args, line, splatarray, Qfalse);
- argc = liseq->body->param.rest_start + 1;
+ argc = local_body->param.rest_start + 1;
flag |= VM_CALL_ARGS_SPLAT;
}
- if (liseq->body->param.flags.has_post) {
+ if (local_body->param.flags.has_post) {
/* post arguments */
- int post_len = liseq->body->param.post_num;
- int post_start = liseq->body->param.post_start;
+ int post_len = local_body->param.post_num;
+ int post_start = local_body->param.post_start;
- if (liseq->body->param.flags.has_rest) {
+ if (local_body->param.flags.has_rest) {
int j;
for (j=0; j<post_len; j++) {
- int idx = liseq->body->local_table_size - (post_start + j);
+ int idx = local_body->local_table_size - (post_start + j);
ADD_GETLOCAL(args, line, idx, lvar_level);
}
ADD_INSN1(args, line, newarray, INT2FIX(j));
@@ -5779,61 +8157,60 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
else {
int j;
for (j=0; j<post_len; j++) {
- int idx = liseq->body->local_table_size - (post_start + j);
+ int idx = local_body->local_table_size - (post_start + j);
ADD_GETLOCAL(args, line, idx, lvar_level);
}
argc = post_len + post_start;
}
}
- if (liseq->body->param.flags.has_kw) { /* TODO: support keywords */
- int local_size = liseq->body->local_table_size;
+ if (local_body->param.flags.has_kw) { /* TODO: support keywords */
+ int local_size = local_body->local_table_size;
argc++;
ADD_INSN1(args, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- if (liseq->body->param.flags.has_kwrest) {
- int idx = liseq->body->local_table_size - liseq->body->param.keyword->rest_start;
+ if (local_body->param.flags.has_kwrest) {
+ int idx = local_body->local_table_size - local_kwd->rest_start;
ADD_GETLOCAL(args, line, idx, lvar_level);
- ADD_SEND (args, line, rb_intern("dup"), INT2FIX(0));
}
else {
ADD_INSN1(args, line, newhash, INT2FIX(0));
+ flag |= VM_CALL_KW_SPLAT_MUT;
}
- for (i = 0; i < liseq->body->param.keyword->num; ++i) {
- ID id = liseq->body->param.keyword->table[i];
+ for (i = 0; i < local_kwd->num; ++i) {
+ ID id = local_kwd->table[i];
int idx = local_size - get_local_var_idx(liseq, id);
ADD_INSN1(args, line, putobject, ID2SYM(id));
ADD_GETLOCAL(args, line, idx, lvar_level);
}
ADD_SEND(args, line, id_core_hash_merge_ptr, INT2FIX(i * 2 + 1));
- if (liseq->body->param.flags.has_rest) {
+ if (local_body->param.flags.has_rest) {
ADD_INSN1(args, line, newarray, INT2FIX(1));
ADD_INSN (args, line, concatarray);
--argc;
}
+ flag |= VM_CALL_KW_SPLAT;
}
- else if (liseq->body->param.flags.has_kwrest) {
- int idx = liseq->body->local_table_size - liseq->body->param.keyword->rest_start;
+ else if (local_body->param.flags.has_kwrest) {
+ int idx = local_body->local_table_size - local_kwd->rest_start;
ADD_GETLOCAL(args, line, idx, lvar_level);
- ADD_SEND (args, line, rb_intern("dup"), INT2FIX(0));
- if (liseq->body->param.flags.has_rest) {
+ if (local_body->param.flags.has_rest) {
ADD_INSN1(args, line, newarray, INT2FIX(1));
ADD_INSN (args, line, concatarray);
}
else {
argc++;
}
+ flag |= VM_CALL_KW_SPLAT;
}
}
- /* dummy receiver */
- ADD_INSN1(ret, line, putobject, type == NODE_ZSUPER ? Qfalse : Qtrue);
+ ADD_INSN(ret, line, putself);
ADD_SEQ(ret, args);
- ADD_INSN3(ret, line, invokesuper,
- new_callinfo(iseq, 0, argc, flag | VM_CALL_SUPER | VM_CALL_FCALL, keywords, parent_block != NULL),
- Qnil, /* CALL_CACHE */
+ ADD_INSN2(ret, line, invokesuper,
+ new_callinfo(iseq, 0, argc, flag | VM_CALL_SUPER | (type == NODE_ZSUPER ? VM_CALL_ZSUPER : 0) | VM_CALL_FCALL, keywords, parent_block != NULL),
parent_block);
if (popped) {
@@ -5841,18 +8218,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
break;
}
- case NODE_ARRAY:{
- CHECK(compile_array(iseq, ret, node, COMPILE_ARRAY_TYPE_ARRAY, NULL, NULL, popped) >= 0);
+ case NODE_LIST:{
+ CHECK(compile_array(iseq, ret, node, popped) >= 0);
break;
}
- case NODE_ZARRAY:{
+ case NODE_ZLIST:{
if (!popped) {
ADD_INSN1(ret, line, newarray, INT2FIX(0));
}
break;
}
case NODE_VALUES:{
- NODE *n = node;
+ const NODE *n = node;
if (popped) {
COMPILE_ERROR(ERROR_ARGS "NODE_VALUES: must not be popped");
}
@@ -5863,98 +8240,24 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_INSN1(ret, line, newarray, INT2FIX(node->nd_alen));
break;
}
- case NODE_HASH:{
- DECL_ANCHOR(list);
- int type = node->nd_head ? nd_type(node->nd_head) : NODE_ZARRAY;
-
- INIT_ANCHOR(list);
- switch (type) {
- case NODE_ARRAY:
- CHECK(compile_array(iseq, list, node->nd_head, COMPILE_ARRAY_TYPE_HASH, NULL, NULL, popped) >= 0);
- ADD_SEQ(ret, list);
- break;
-
- case NODE_ZARRAY:
- if (popped) break;
- ADD_INSN1(ret, line, newhash, INT2FIX(0));
- break;
-
- default:
- COMPILE_ERROR(ERROR_ARGS_AT(node->nd_head) "can't make hash with this node: %s",
- ruby_node_name(type));
- goto ng;
- }
- break;
- }
- case NODE_RETURN:{
- rb_iseq_t *is = iseq;
-
- if (is) {
- enum iseq_type type = is->body->type;
- const rb_iseq_t *parent_iseq = is->body->parent_iseq;
- enum iseq_type parent_type;
-
- if (type == ISEQ_TYPE_TOP) {
- LABEL *splabel = NEW_LABEL(line);
- ADD_LABEL(ret, splabel);
- ADD_ADJUST(ret, line, 0);
- ADD_INSN(ret, line, putnil);
- ADD_INSN(ret, line, leave);
- ADD_ADJUST_RESTORE(ret, splabel);
- }
- else if ((type == ISEQ_TYPE_RESCUE || type == ISEQ_TYPE_ENSURE || type == ISEQ_TYPE_MAIN) &&
- parent_iseq &&
- ((parent_type = parent_iseq->body->type) == ISEQ_TYPE_TOP ||
- parent_type == ISEQ_TYPE_MAIN)) {
- ADD_INSN(ret, line, putnil);
- ADD_INSN1(ret, line, throw, INT2FIX(TAG_RETURN));
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
- }
- else {
- LABEL *splabel = 0;
-
- if (type == ISEQ_TYPE_METHOD) {
- splabel = NEW_LABEL(0);
- ADD_LABEL(ret, splabel);
- ADD_ADJUST(ret, line, 0);
- }
-
- CHECK(COMPILE(ret, "return nd_stts (return val)", node->nd_stts));
-
- if (type == ISEQ_TYPE_METHOD) {
- add_ensure_iseq(ret, iseq, 1);
- ADD_TRACE(ret, line, RUBY_EVENT_RETURN);
- ADD_INSN(ret, line, leave);
- ADD_ADJUST_RESTORE(ret, splabel);
-
- if (!popped) {
- ADD_INSN(ret, line, putnil);
- }
- }
- else {
- ADD_INSN1(ret, line, throw, INT2FIX(TAG_RETURN));
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
- }
- }
- }
+ case NODE_HASH:
+ CHECK(compile_hash(iseq, ret, node, FALSE, popped) >= 0);
+ break;
+ case NODE_RETURN:
+ CHECK(compile_return(iseq, ret, node, popped));
break;
- }
case NODE_YIELD:{
DECL_ANCHOR(args);
VALUE argc;
unsigned int flag = 0;
- struct rb_call_info_kw_arg *keywords = NULL;
+ struct rb_callinfo_kwarg *keywords = NULL;
INIT_ANCHOR(args);
- if (iseq->body->type == ISEQ_TYPE_TOP ||
- iseq->body->type == ISEQ_TYPE_MAIN) {
+
+ if (check_yield_place(iseq) == FALSE) {
COMPILE_ERROR(ERROR_ARGS "Invalid yield");
- goto ng;
- }
+ goto ng;
+ }
if (node->nd_head) {
argc = setup_args(iseq, args, node->nd_head, &flag, &keywords);
@@ -5970,12 +8273,19 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
if (popped) {
ADD_INSN(ret, line, pop);
}
+
+ int level = 0;
+ const rb_iseq_t *tmp_iseq = iseq;
+ for (; tmp_iseq != iseq->body->local_iseq; level++ ) {
+ tmp_iseq = tmp_iseq->body->parent_iseq;
+ }
+ if (level > 0) access_outer_variables(iseq, level, rb_intern("yield"), true);
break;
}
case NODE_LVAR:{
if (!popped) {
ID id = node->nd_vid;
- int idx = iseq->body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
+ int idx = body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
debugs("id: %s idx: %d\n", rb_id2name(id), idx);
ADD_GETLOCAL(ret, line, idx, get_lvar_level(iseq));
@@ -5997,8 +8307,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
break;
}
case NODE_GVAR:{
- ADD_INSN1(ret, line, getglobal,
- ((VALUE)node->nd_entry | 1));
+ ADD_INSN1(ret, line, getglobal, ID2SYM(node->nd_entry));
if (popped) {
ADD_INSN(ret, line, pop);
}
@@ -6018,16 +8327,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
LABEL *lend = NEW_LABEL(line);
- int ic_index = iseq->body->is_size++;
+ int ic_index = body->is_size++;
- ADD_INSN2(ret, line, getinlinecache, lend, INT2FIX(ic_index));
- ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_vid));
- ADD_INSN1(ret, line, setinlinecache, INT2FIX(ic_index));
+ ADD_INSN2(ret, line, opt_getinlinecache, lend, INT2FIX(ic_index));
+ ADD_INSN1(ret, line, putobject, Qtrue);
+ ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_vid));
+ ADD_INSN1(ret, line, opt_setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
else {
ADD_INSN(ret, line, putnil);
- ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_vid));
+ ADD_INSN1(ret, line, putobject, Qtrue);
+ ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_vid));
}
if (popped) {
@@ -6084,26 +8395,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
break;
}
- if (ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
- /* TODO: detect by node */
- if (recv->last == recv->anchor.next &&
- INSN_OF(recv->last) == BIN(putobject) &&
- nd_type(node) == NODE_MATCH2) {
- ADD_SEQ(ret, val);
- ADD_INSN1(ret, line, opt_regexpmatch1,
- OPERAND_AT(recv->last, 0));
- }
- else {
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, val);
- ADD_INSN2(ret, line, opt_regexpmatch2, new_callinfo(iseq, idEqTilde, 1, 0, NULL, FALSE), Qnil);
- }
- }
- else {
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, val);
- ADD_SEND(ret, line, idEqTilde, INT2FIX(1));
- }
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, val);
+ ADD_SEND(ret, line, idEqTilde, INT2FIX(1));
if (node->nd_args) {
compile_named_capture_assign(iseq, ret, node->nd_args);
@@ -6118,27 +8412,31 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
debugp_param("lit", node->nd_lit);
if (!popped) {
ADD_INSN1(ret, line, putobject, node->nd_lit);
+ RB_OBJ_WRITTEN(iseq, Qundef, node->nd_lit);
}
break;
}
case NODE_STR:{
debugp_param("nd_lit", node->nd_lit);
if (!popped) {
- node->nd_lit = rb_fstring(node->nd_lit);
+ VALUE lit = node->nd_lit;
if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
- ADD_INSN1(ret, line, putstring, node->nd_lit);
+ lit = rb_fstring(lit);
+ ADD_INSN1(ret, line, putstring, lit);
+ RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
else {
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX(line));
- VALUE str = rb_str_dup(node->nd_lit);
- rb_ivar_set(str, id_debug_created_info, rb_obj_freeze(debug_info));
- ADD_INSN1(ret, line, putobject, rb_obj_freeze(str));
- iseq_add_mark_object_compile_time(iseq, str);
+ lit = rb_str_dup(lit);
+ rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
+ lit = rb_str_freeze(lit);
}
else {
- ADD_INSN1(ret, line, putobject, node->nd_lit);
+ lit = rb_fstring(lit);
}
+ ADD_INSN1(ret, line, putobject, lit);
+ RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
}
break;
@@ -6149,22 +8447,13 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
if (popped) {
ADD_INSN(ret, line, pop);
}
- else {
- if (ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
- VALUE debug_info = Qnil;
- if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
- debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX(line));
- iseq_add_mark_object_compile_time(iseq, rb_obj_freeze(debug_info));
- }
- ADD_INSN1(ret, line, freezestring, debug_info);
- }
- }
break;
}
case NODE_XSTR:{
- node->nd_lit = rb_fstring(node->nd_lit);
ADD_CALL_RECEIVER(ret, line);
- ADD_INSN1(ret, line, putobject, node->nd_lit);
+ VALUE str = rb_fstring(node->nd_lit);
+ ADD_INSN1(ret, line, putobject, str);
+ RB_OBJ_WRITTEN(iseq, Qundef, str);
ADD_CALL(ret, line, idBackquote, INT2FIX(1));
if (popped) {
@@ -6182,25 +8471,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
break;
}
- case NODE_EVSTR:{
- CHECK(COMPILE(ret, "nd_body", node->nd_body));
-
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
- else {
- const unsigned int flag = VM_CALL_FCALL;
- LABEL *isstr = NEW_LABEL(line);
- ADD_INSN(ret, line, dup);
- ADD_INSN2(ret, line, branchiftype, INT2FIX(T_STRING), isstr);
- LABEL_REF(isstr);
- ADD_INSN(ret, line, dup);
- ADD_SEND_R(ret, line, idTo_s, INT2FIX(0), NULL, INT2FIX(flag), NULL);
- ADD_INSN(ret, line, tostring);
- ADD_LABEL(ret, isstr);
- }
+ case NODE_EVSTR:
+ CHECK(compile_evstr(iseq, ret, node->nd_body, popped));
break;
- }
case NODE_DREGX:{
compile_dregx(iseq, ret, node);
@@ -6209,14 +8482,13 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
break;
}
- case NODE_DREGX_ONCE:{
- int ic_index = iseq->body->is_size++;
- NODE *dregx_node = NEW_NODE(NODE_DREGX, node->u1.value, node->u2.value, node->u3.value);
- NODE *block_node = NEW_NODE(NODE_SCOPE, 0, dregx_node, 0);
- const rb_iseq_t *block_iseq = NEW_CHILD_ISEQ(block_node, make_name_for_block(iseq),
- ISEQ_TYPE_ONCE_GUARD, line);
+ case NODE_ONCE:{
+ int ic_index = body->is_size++;
+ const rb_iseq_t *block_iseq;
+ block_iseq = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_PLAIN, line);
ADD_INSN2(ret, line, once, block_iseq, INT2FIX(ic_index));
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block_iseq);
if (popped) {
ADD_INSN(ret, line, pop);
@@ -6264,46 +8536,42 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
break;
}
case NODE_DEFN:{
+ ID mid = node->nd_mid;
const rb_iseq_t *method_iseq = NEW_ISEQ(node->nd_defn,
- rb_id2str(node->nd_mid),
+ rb_id2str(mid),
ISEQ_TYPE_METHOD, line);
debugp_param("defn/iseq", rb_iseqw_new(method_iseq));
+ ADD_INSN2(ret, line, definemethod, ID2SYM(mid), method_iseq);
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)method_iseq);
- ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, line, putobject, ID2SYM(node->nd_mid));
- ADD_INSN1(ret, line, putiseq, method_iseq);
- ADD_SEND (ret, line, id_core_define_method, INT2FIX(2));
-
- if (popped) {
- ADD_INSN(ret, line, pop);
+ if (!popped) {
+ ADD_INSN1(ret, line, putobject, ID2SYM(mid));
}
break;
}
case NODE_DEFS:{
- const rb_iseq_t * singleton_method = NEW_ISEQ(node->nd_defn,
- rb_id2str(node->nd_mid),
- ISEQ_TYPE_METHOD, line);
+ ID mid = node->nd_mid;
+ const rb_iseq_t * singleton_method_iseq = NEW_ISEQ(node->nd_defn,
+ rb_id2str(mid),
+ ISEQ_TYPE_METHOD, line);
- debugp_param("defs/iseq", rb_iseqw_new(singleton_method));
+ debugp_param("defs/iseq", rb_iseqw_new(singleton_method_iseq));
+ CHECK(COMPILE(ret, "defs: recv", node->nd_recv));
+ ADD_INSN2(ret, line, definesmethod, ID2SYM(mid), singleton_method_iseq);
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_method_iseq);
- ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- CHECK(COMPILE(ret, "defs: recv", node->nd_recv));
- ADD_INSN1(ret, line, putobject, ID2SYM(node->nd_mid));
- ADD_INSN1(ret, line, putiseq, singleton_method);
- ADD_SEND (ret, line, id_core_define_singleton_method, INT2FIX(3));
-
- if (popped) {
- ADD_INSN(ret, line, pop);
- }
+ if (!popped) {
+ ADD_INSN1(ret, line, putobject, ID2SYM(mid));
+ }
break;
}
case NODE_ALIAS:{
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
- CHECK(COMPILE(ret, "alias arg1", node->u1.node));
- CHECK(COMPILE(ret, "alias arg2", node->u2.node));
+ CHECK(COMPILE(ret, "alias arg1", node->nd_1st));
+ CHECK(COMPILE(ret, "alias arg2", node->nd_2nd));
ADD_SEND(ret, line, id_core_set_method_alias, INT2FIX(3));
if (popped) {
@@ -6313,8 +8581,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
case NODE_VALIAS:{
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, line, putobject, ID2SYM(node->u1.id));
- ADD_INSN1(ret, line, putobject, ID2SYM(node->u2.id));
+ ADD_INSN1(ret, line, putobject, ID2SYM(node->nd_alias));
+ ADD_INSN1(ret, line, putobject, ID2SYM(node->nd_orig));
ADD_SEND(ret, line, id_core_set_variable_alias, INT2FIX(2));
if (popped) {
@@ -6325,7 +8593,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
case NODE_UNDEF:{
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
- CHECK(COMPILE(ret, "undef arg", node->u2.node));
+ CHECK(COMPILE(ret, "undef arg", node->nd_undef));
ADD_SEND(ret, line, id_core_undef_method, INT2FIX(2));
if (popped) {
@@ -6343,6 +8611,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
CHECK(COMPILE(ret, "super", node->nd_super));
ADD_INSN3(ret, line, defineclass, ID2SYM(node->nd_cpath->nd_mid), class_iseq, INT2FIX(flags));
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)class_iseq);
if (popped) {
ADD_INSN(ret, line, pop);
@@ -6358,6 +8627,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_INSN (ret, line, putnil); /* dummy */
ADD_INSN3(ret, line, defineclass, ID2SYM(node->nd_cpath->nd_mid), module_iseq, INT2FIX(flags));
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)module_iseq);
if (popped) {
ADD_INSN(ret, line, pop);
@@ -6366,7 +8636,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
case NODE_SCLASS:{
ID singletonclass;
- const rb_iseq_t *singleton_class = NEW_ISEQ(node->nd_body, rb_fstring_cstr("singleton class"),
+ const rb_iseq_t *singleton_class = NEW_ISEQ(node->nd_body, rb_fstring_lit("singleton class"),
ISEQ_TYPE_CLASS, line);
CHECK(COMPILE(ret, "sclass#recv", node->nd_recv));
@@ -6375,6 +8645,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_INSN3(ret, line, defineclass,
ID2SYM(singletonclass), singleton_class,
INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS));
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_class);
if (popped) {
ADD_INSN(ret, line, pop);
@@ -6385,7 +8656,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
if (rb_is_const_id(node->nd_mid)) {
/* constant */
LABEL *lend = NEW_LABEL(line);
- int ic_index = iseq->body->is_size++;
+ int ic_index = body->is_size++;
DECL_ANCHOR(pref);
DECL_ANCHOR(body);
@@ -6393,9 +8664,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
INIT_ANCHOR(pref);
INIT_ANCHOR(body);
CHECK(compile_const_prefix(iseq, node, pref, body));
- if (LIST_SIZE_ZERO(pref)) {
+ if (LIST_INSN_SIZE_ZERO(pref)) {
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
- ADD_INSN2(ret, line, getinlinecache, lend, INT2FIX(ic_index));
+ ADD_INSN2(ret, line, opt_getinlinecache, lend, INT2FIX(ic_index));
}
else {
ADD_INSN(ret, line, putnil);
@@ -6404,7 +8675,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_SEQ(ret, body);
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
- ADD_INSN1(ret, line, setinlinecache, INT2FIX(ic_index));
+ ADD_INSN1(ret, line, opt_setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
}
@@ -6426,21 +8697,22 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
case NODE_COLON3:{
LABEL *lend = NEW_LABEL(line);
- int ic_index = iseq->body->is_size++;
+ int ic_index = body->is_size++;
debugi("colon3#nd_mid", node->nd_mid);
/* add cache insn */
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
- ADD_INSN2(ret, line, getinlinecache, lend, INT2FIX(ic_index));
+ ADD_INSN2(ret, line, opt_getinlinecache, lend, INT2FIX(ic_index));
ADD_INSN(ret, line, pop);
}
ADD_INSN1(ret, line, putobject, rb_cObject);
- ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_mid));
+ ADD_INSN1(ret, line, putobject, Qtrue);
+ ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_mid));
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
- ADD_INSN1(ret, line, setinlinecache, INT2FIX(ic_index));
+ ADD_INSN1(ret, line, opt_setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
@@ -6453,13 +8725,16 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
case NODE_DOT3:{
int excl = type == NODE_DOT3;
VALUE flag = INT2FIX(excl);
- NODE *b = node->nd_beg;
- NODE *e = node->nd_end;
- if (number_literal_p(b) && number_literal_p(e)) {
+ const NODE *b = node->nd_beg;
+ const NODE *e = node->nd_end;
+
+ if (optimizable_range_item_p(b) && optimizable_range_item_p(e)) {
if (!popped) {
- VALUE val = rb_range_new(b->nd_lit, e->nd_lit, excl);
- iseq_add_mark_object_compile_time(iseq, val);
- ADD_INSN1(ret, line, putobject, val);
+ VALUE bv = nd_type(b) == NODE_LIT ? b->nd_lit : Qnil;
+ VALUE ev = nd_type(e) == NODE_LIT ? e->nd_lit : Qnil;
+ VALUE val = rb_range_new(bv, ev, excl);
+ ADD_INSN1(ret, line, putobject, val);
+ RB_OBJ_WRITTEN(iseq, Qundef, val);
}
}
else {
@@ -6512,7 +8787,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
}
case NODE_ERRINFO:{
if (!popped) {
- if (iseq->body->type == ISEQ_TYPE_RESCUE) {
+ if (body->type == ISEQ_TYPE_RESCUE) {
ADD_GETLOCAL(ret, line, LVAR_ERRINFO, 0);
}
else {
@@ -6544,11 +8819,15 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
/* compiled to:
* ONCE{ rb_mRubyVMFrozenCore::core#set_postexe{ ... } }
*/
- int is_index = iseq->body->is_size++;
- const rb_iseq_t *once_iseq = NEW_CHILD_ISEQ((NODE *)IFUNC_NEW(build_postexe_iseq, node->nd_body, 0),
- make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
+ int is_index = body->is_size++;
+ struct rb_iseq_new_with_callback_callback_func *ifunc =
+ rb_iseq_new_with_callback_new_callback(build_postexe_iseq, node->nd_body);
+ const rb_iseq_t *once_iseq =
+ new_child_iseq_with_callback(iseq, ifunc,
+ rb_fstring(make_name_for_block(iseq)), iseq, ISEQ_TYPE_BLOCK, line);
ADD_INSN2(ret, line, once, once_iseq, INT2FIX(is_index));
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)once_iseq);
if (popped) {
ADD_INSN(ret, line, pop);
@@ -6558,9 +8837,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
case NODE_KW_ARG:
{
LABEL *end_label = NEW_LABEL(nd_line(node));
- NODE *default_value = node->nd_body->nd_value;
+ const NODE *default_value = node->nd_body->nd_value;
- if (default_value == (NODE *)-1) {
+ if (default_value == NODE_SPECIAL_REQUIRED_KEYWORD) {
/* required argument. do nothing */
COMPILE_ERROR(ERROR_ARGS "unreachable");
goto ng;
@@ -6577,8 +8856,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
* kw = default_value
* end
*/
- int kw_bits_idx = iseq->body->local_table_size - iseq->body->param.keyword->bits_start;
- int keyword_idx = iseq->body->param.keyword->num;
+ int kw_bits_idx = body->local_table_size - body->param.keyword->bits_start;
+ int keyword_idx = body->param.keyword->num;
ADD_INSN2(ret, line, checkkeyword, INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1), INT2FIX(keyword_idx));
ADD_INSNL(ret, line, branchif, end_label);
@@ -6603,30 +8882,30 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
DECL_ANCHOR(args);
unsigned int flag = 0;
ID mid = node->nd_mid;
- LABEL *lskip = 0;
VALUE argc;
+ LABEL *else_label = NULL;
+ VALUE branches = Qfalse;
/* optimization shortcut
* obj["literal"] = value -> opt_aset_with(obj, "literal", value)
*/
if (mid == idASET && !private_recv_p(node) && node->nd_args &&
- nd_type(node->nd_args) == NODE_ARRAY && node->nd_args->nd_alen == 2 &&
+ nd_type(node->nd_args) == NODE_LIST && node->nd_args->nd_alen == 2 &&
nd_type(node->nd_args->nd_head) == NODE_STR &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
+ !ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction)
{
VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
- node->nd_args->nd_head->nd_lit = str;
- iseq_add_mark_object(iseq, str);
CHECK(COMPILE(ret, "recv", node->nd_recv));
CHECK(COMPILE(ret, "value", node->nd_args->nd_next->nd_head));
if (!popped) {
ADD_INSN(ret, line, swap);
ADD_INSN1(ret, line, topn, INT2FIX(1));
}
- ADD_INSN3(ret, line, opt_aset_with,
- new_callinfo(iseq, idASET, 2, 0, NULL, FALSE),
- NULL/* CALL_CACHE */, str);
+ ADD_INSN2(ret, line, opt_aset_with, str,
+ new_callinfo(iseq, idASET, 2, 0, NULL, FALSE));
+ RB_OBJ_WRITTEN(iseq, Qundef, str);
ADD_INSN(ret, line, pop);
break;
}
@@ -6636,7 +8915,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
argc = setup_args(iseq, args, node->nd_args, &flag, NULL);
CHECK(!NIL_P(argc));
- flag |= COMPILE_RECV(recv, "recv", node);
+ int asgnflag = COMPILE_RECV(recv, "recv", node);
+ CHECK(asgnflag != -1);
+ flag |= (unsigned int)asgnflag;
debugp_param("argc", argc);
debugp_param("nd_mid", ID2SYM(mid));
@@ -6644,9 +8925,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
if (!rb_is_attrset_id(mid)) {
/* safe nav attr */
mid = rb_id_attrset(mid);
- ADD_INSN(recv, line, dup);
- lskip = NEW_LABEL(line);
- ADD_INSNL(recv, line, branchnil, lskip);
+ else_label = qcall_branch_start(iseq, recv, &branches, node, line);
}
if (!popped) {
ADD_INSN(ret, line, putnil);
@@ -6657,7 +8936,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_INSN1(ret, line, topn, INT2FIX(1));
if (flag & VM_CALL_ARGS_SPLAT) {
ADD_INSN1(ret, line, putobject, INT2FIX(-1));
- ADD_SEND(ret, line, idAREF, INT2FIX(1));
+ ADD_SEND_WITH_FLAG(ret, line, idAREF, INT2FIX(1), INT2FIX(asgnflag));
}
ADD_INSN1(ret, line, setn, FIXNUM_INC(argc, 3));
ADD_INSN (ret, line, pop);
@@ -6665,7 +8944,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
else if (flag & VM_CALL_ARGS_SPLAT) {
ADD_INSN(ret, line, dup);
ADD_INSN1(ret, line, putobject, INT2FIX(-1));
- ADD_SEND(ret, line, idAREF, INT2FIX(1));
+ ADD_SEND_WITH_FLAG(ret, line, idAREF, INT2FIX(1), INT2FIX(asgnflag));
ADD_INSN1(ret, line, setn, FIXNUM_INC(argc, 2));
ADD_INSN (ret, line, pop);
}
@@ -6678,26 +8957,11 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_SEQ(ret, args);
}
ADD_SEND_WITH_FLAG(ret, line, mid, argc, INT2FIX(flag));
- if (lskip) ADD_LABEL(ret, lskip);
+ qcall_branch_end(iseq, ret, else_label, branches, node, line);
ADD_INSN(ret, line, pop);
break;
}
- case NODE_PRELUDE:{
- const rb_compile_option_t *orig_opt = ISEQ_COMPILE_DATA(iseq)->option;
- VALUE orig_cov = ISEQ_COVERAGE(iseq);
- rb_compile_option_t new_opt = *orig_opt;
- if (node->nd_orig) {
- rb_iseq_make_compile_option(&new_opt, node->nd_orig);
- ISEQ_COMPILE_DATA(iseq)->option = &new_opt;
- }
- if (!new_opt.coverage_enabled) ISEQ_COVERAGE_SET(iseq, Qfalse);
- CHECK(COMPILE_POPPED(ret, "prelude", node->nd_head));
- CHECK(COMPILE_(ret, "body", node->nd_body, popped));
- ISEQ_COMPILE_DATA(iseq)->option = orig_opt;
- ISEQ_COVERAGE_SET(iseq, orig_cov);
- break;
- }
case NODE_LAMBDA:{
/* compile same as lambda{...} */
const rb_iseq_t *block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
@@ -6705,6 +8969,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_CALL_WITH_BLOCK(ret, line, idLambda, argc, block);
+ RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block);
if (popped) {
ADD_INSN(ret, line, pop);
@@ -6718,20 +8983,6 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
return COMPILE_NG;
}
- /* check & remove redundant trace(line) */
- if (saved_last_element &&
- ret->last == saved_last_element &&
- ((INSN *)saved_last_element)->insn_id == BIN(trace)) {
- POP_ELEMENT(ret);
- /* remove trace(coverage) */
- if (IS_INSN_ID(ret->last, trace2) &&
- (FIX2LONG(OPERAND_AT(ret->last, 0)) & RUBY_EVENT_COVERAGE) &&
- (FIX2LONG(OPERAND_AT(ret->last, 1)) == COVERAGE_INDEX_LINES)) {
- POP_ELEMENT(ret);
- RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), line - 1, Qnil);
- }
- }
-
debug_node_end();
return COMPILE_OK;
}
@@ -6749,21 +9000,22 @@ insn_data_length(INSN *iobj)
static int
calc_sp_depth(int depth, INSN *insn)
{
- return insn_stack_increase(depth, insn->insn_id, insn->operands);
+ return comptime_insn_stack_increase(depth, insn->insn_id, insn->operands);
}
static VALUE
opobj_inspect(VALUE obj)
{
- struct RBasic *r = (struct RBasic *) obj;
- if (!SPECIAL_CONST_P(r) && r->klass == 0) {
- switch (BUILTIN_TYPE(r)) {
+ if (!SPECIAL_CONST_P(obj) && !RBASIC_CLASS(obj)) {
+ switch (BUILTIN_TYPE(obj)) {
case T_STRING:
obj = rb_str_new_cstr(RSTRING_PTR(obj));
break;
case T_ARRAY:
obj = rb_ary_dup(obj);
break;
+ default:
+ break;
}
}
return rb_inspect(obj);
@@ -6806,33 +9058,27 @@ insn_data_to_s_detail(INSN *iobj)
case TS_VALUE: /* VALUE */
{
VALUE v = OPERAND_AT(iobj, j);
- rb_str_concat(str, opobj_inspect(v));
+ if (!CLASS_OF(v))
+ rb_str_cat2(str, "<hidden>");
+ else {
+ rb_str_concat(str, opobj_inspect(v));
+ }
break;
}
case TS_ID: /* ID */
rb_str_concat(str, opobj_inspect(OPERAND_AT(iobj, j)));
break;
- case TS_GENTRY:
- {
- struct rb_global_entry *entry = (struct rb_global_entry *)
- (OPERAND_AT(iobj, j) & (~1));
- rb_str_append(str, rb_id2str(entry->id));
- break;
- }
case TS_IC: /* inline cache */
+ case TS_IVC: /* inline ivar cache */
+ case TS_ISE: /* inline storage entry */
rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
break;
- case TS_CALLINFO: /* call info */
+ case TS_CALLDATA: /* we store these as call infos at compile time */
{
- struct rb_call_info *ci = (struct rb_call_info *)OPERAND_AT(iobj, j);
- rb_str_cat2(str, "<callinfo:");
- if (ci->mid) rb_str_catf(str, "%"PRIsVALUE, rb_id2str(ci->mid));
- rb_str_catf(str, ", %d>", ci->orig_argc);
- break;
- }
- case TS_CALLCACHE: /* call cache */
- {
- rb_str_catf(str, "<call cache>");
+ const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(iobj, j);
+ rb_str_cat2(str, "<calldata:");
+ if (vm_ci_mid(ci)) rb_str_catf(str, "%"PRIsVALUE, rb_id2str(vm_ci_mid(ci)));
+ rb_str_catf(str, ", %d>", vm_ci_argc(ci));
break;
}
case TS_CDHASH: /* case/when condition cache */
@@ -6840,7 +9086,7 @@ insn_data_to_s_detail(INSN *iobj)
break;
case TS_FUNCPTR:
{
- rb_insn_func_t func = (rb_insn_func_t)OPERAND_AT(iobj, j);
+ void *func = (void *)OPERAND_AT(iobj, j);
#ifdef HAVE_DLADDR
Dl_info info;
if (dladdr(func, &info) && info.dli_sname) {
@@ -6851,6 +9097,9 @@ insn_data_to_s_detail(INSN *iobj)
rb_str_catf(str, "<%p>", func);
}
break;
+ case TS_BUILTIN:
+ rb_str_cat2(str, "<TS_BUILTIN>");
+ break;
default:{
rb_raise(rb_eSyntaxError, "unknown operand type: %c", type);
}
@@ -6886,25 +9135,27 @@ dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr,
{
iobj = (INSN *)link;
str = insn_data_to_s_detail(iobj);
- printf("%04d %-65s(%4u)\n", pos, StringValueCStr(str), iobj->line_no);
+ printf(" %04d %-65s(%4u)\n", pos, StringValueCStr(str), iobj->insn_info.line_no);
pos += insn_data_length(iobj);
break;
}
case ISEQ_ELEMENT_LABEL:
{
lobj = (LABEL *)link;
- printf(LABEL_FORMAT"%s\n", lobj->label_no, dest == lobj ? " <---" : "");
+ printf(LABEL_FORMAT" [sp: %d]%s\n", lobj->label_no, lobj->sp,
+ dest == lobj ? " <---" : "");
break;
}
- case ISEQ_ELEMENT_NONE:
+ case ISEQ_ELEMENT_TRACE:
{
- printf("[none]\n");
+ TRACE *trace = (TRACE *)link;
+ printf(" trace: %0x\n", trace->event);
break;
}
case ISEQ_ELEMENT_ADJUST:
{
ADJUST *adjust = (ADJUST *)link;
- printf("adjust: [label: %d]\n", adjust->label ? adjust->label->label_no : -1);
+ printf(" adjust: [label: %d]\n", adjust->label ? adjust->label->label_no : -1);
break;
}
default:
@@ -6920,16 +9171,16 @@ dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr,
const char *
rb_insns_name(int i)
{
- return insn_name_info[i];
+ return insn_name(i);
}
VALUE
rb_insns_name_array(void)
{
- VALUE ary = rb_ary_new();
+ VALUE ary = rb_ary_new_capa(VM_INSTRUCTION_SIZE);
int i;
for (i = 0; i < VM_INSTRUCTION_SIZE; i++) {
- rb_ary_push(ary, rb_fstring_cstr(insn_name_info[i]));
+ rb_ary_push(ary, rb_fstring_cstr(insn_name(i)));
}
return rb_obj_freeze(ary);
}
@@ -6939,7 +9190,7 @@ register_label(rb_iseq_t *iseq, struct st_table *labels_table, VALUE obj)
{
LABEL *label = 0;
st_data_t tmp;
- obj = rb_convert_type_with_id(obj, T_SYMBOL, "Symbol", idTo_sym);
+ obj = rb_to_symbol_type(obj);
if (st_lookup(labels_table, obj, &tmp) == 0) {
label = NEW_LABEL(0);
@@ -6955,18 +9206,16 @@ register_label(rb_iseq_t *iseq, struct st_table *labels_table, VALUE obj)
static VALUE
get_exception_sym2type(VALUE sym)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
static VALUE symRescue, symEnsure, symRetry;
static VALUE symBreak, symRedo, symNext;
if (symRescue == 0) {
- symRescue = ID2SYM(rb_intern("rescue"));
- symEnsure = ID2SYM(rb_intern("ensure"));
- symRetry = ID2SYM(rb_intern("retry"));
- symBreak = ID2SYM(rb_intern("break"));
- symRedo = ID2SYM(rb_intern("redo"));
- symNext = ID2SYM(rb_intern("next"));
+ symRescue = ID2SYM(rb_intern_const("rescue"));
+ symEnsure = ID2SYM(rb_intern_const("ensure"));
+ symRetry = ID2SYM(rb_intern_const("retry"));
+ symBreak = ID2SYM(rb_intern_const("break"));
+ symRedo = ID2SYM(rb_intern_const("redo"));
+ symNext = ID2SYM(rb_intern_const("next"));
}
if (sym == symRescue) return CATCH_TYPE_RESCUE;
@@ -6988,28 +9237,25 @@ iseq_build_from_ary_exception(rb_iseq_t *iseq, struct st_table *labels_table,
for (i=0; i<RARRAY_LEN(exception); i++) {
const rb_iseq_t *eiseq;
VALUE v, type;
- const VALUE *ptr;
LABEL *lstart, *lend, *lcont;
unsigned int sp;
- v = rb_convert_type_with_id(RARRAY_AREF(exception, i), T_ARRAY,
- "Array", idTo_ary);
+ v = rb_to_array_type(RARRAY_AREF(exception, i));
if (RARRAY_LEN(v) != 6) {
rb_raise(rb_eSyntaxError, "wrong exception entry");
}
- ptr = RARRAY_CONST_PTR(v);
- type = get_exception_sym2type(ptr[0]);
- if (ptr[1] == Qnil) {
+ type = get_exception_sym2type(RARRAY_AREF(v, 0));
+ if (RARRAY_AREF(v, 1) == Qnil) {
eiseq = NULL;
}
else {
- eiseq = rb_iseqw_to_iseq(rb_iseq_load(ptr[1], (VALUE)iseq, Qnil));
- }
+ eiseq = rb_iseqw_to_iseq(rb_iseq_load(RARRAY_AREF(v, 1), (VALUE)iseq, Qnil));
+ }
- lstart = register_label(iseq, labels_table, ptr[2]);
- lend = register_label(iseq, labels_table, ptr[3]);
- lcont = register_label(iseq, labels_table, ptr[4]);
- sp = NUM2UINT(ptr[5]);
+ lstart = register_label(iseq, labels_table, RARRAY_AREF(v, 2));
+ lend = register_label(iseq, labels_table, RARRAY_AREF(v, 3));
+ lcont = register_label(iseq, labels_table, RARRAY_AREF(v, 4));
+ sp = NUM2UINT(RARRAY_AREF(v, 5));
/* TODO: Dirty Hack! Fix me */
if (type == CATCH_TYPE_RESCUE ||
@@ -7032,10 +9278,10 @@ insn_make_insn_table(void)
{
struct st_table *table;
int i;
- table = st_init_numtable();
+ table = st_init_numtable_with_size(VM_INSTRUCTION_SIZE);
for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
- st_insert(table, ID2SYM(rb_intern(insn_name(i))), i);
+ st_insert(table, ID2SYM(rb_intern_const(insn_name(i))), i);
}
return table;
@@ -7058,7 +9304,6 @@ iseq_build_load_iseq(const rb_iseq_t *iseq, VALUE op)
}
loaded_iseq = rb_iseqw_to_iseq(iseqw);
- iseq_add_mark_object(iseq, (VALUE)loaded_iseq);
return loaded_iseq;
}
@@ -7068,13 +9313,13 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op)
ID mid = 0;
int orig_argc = 0;
unsigned int flag = 0;
- struct rb_call_info_kw_arg *kw_arg = 0;
+ struct rb_callinfo_kwarg *kw_arg = 0;
if (!NIL_P(op)) {
- VALUE vmid = rb_hash_aref(op, ID2SYM(rb_intern("mid")));
- VALUE vflag = rb_hash_aref(op, ID2SYM(rb_intern("flag")));
- VALUE vorig_argc = rb_hash_aref(op, ID2SYM(rb_intern("orig_argc")));
- VALUE vkw_arg = rb_hash_aref(op, ID2SYM(rb_intern("kw_arg")));
+ VALUE vmid = rb_hash_aref(op, ID2SYM(rb_intern_const("mid")));
+ VALUE vflag = rb_hash_aref(op, ID2SYM(rb_intern_const("flag")));
+ VALUE vorig_argc = rb_hash_aref(op, ID2SYM(rb_intern_const("orig_argc")));
+ VALUE vkw_arg = rb_hash_aref(op, ID2SYM(rb_intern_const("kw_arg")));
if (!NIL_P(vmid)) mid = SYM2ID(vmid);
if (!NIL_P(vflag)) flag = NUM2UINT(vflag);
@@ -7083,7 +9328,7 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op)
if (!NIL_P(vkw_arg)) {
int i;
int len = RARRAY_LENINT(vkw_arg);
- size_t n = rb_call_info_kw_arg_bytes(len);
+ size_t n = rb_callinfo_kwarg_bytes(len);
kw_arg = xmalloc(n);
kw_arg->keyword_len = len;
@@ -7095,7 +9340,24 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op)
}
}
- return (VALUE)new_callinfo(iseq, mid, orig_argc, flag, kw_arg, (flag & VM_CALL_ARGS_SIMPLE) == 0);
+ const struct rb_callinfo *ci = new_callinfo(iseq, mid, orig_argc, flag, kw_arg, (flag & VM_CALL_ARGS_SIMPLE) == 0);
+ RB_OBJ_WRITTEN(iseq, Qundef, ci);
+ return (VALUE)ci;
+}
+
+static rb_event_flag_t
+event_name_to_flag(VALUE sym)
+{
+#define CHECK_EVENT(ev) if (sym == ID2SYM(rb_intern_const(#ev))) return ev;
+ CHECK_EVENT(RUBY_EVENT_LINE);
+ CHECK_EVENT(RUBY_EVENT_CLASS);
+ CHECK_EVENT(RUBY_EVENT_END);
+ CHECK_EVENT(RUBY_EVENT_CALL);
+ CHECK_EVENT(RUBY_EVENT_RETURN);
+ CHECK_EVENT(RUBY_EVENT_B_CALL);
+ CHECK_EVENT(RUBY_EVENT_B_RETURN);
+#undef CHECK_EVENT
+ return RUBY_EVENT_NONE;
}
static int
@@ -7103,7 +9365,6 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
VALUE body, VALUE labels_wrapper)
{
/* TODO: body should be frozen */
- const VALUE *ptr = RARRAY_CONST_PTR(body);
long i, len = RARRAY_LEN(body);
struct st_table *labels_table = DATA_PTR(labels_wrapper);
int j;
@@ -7120,11 +9381,17 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
}
for (i=0; i<len; i++) {
- VALUE obj = ptr[i];
+ VALUE obj = RARRAY_AREF(body, i);
if (SYMBOL_P(obj)) {
- LABEL *label = register_label(iseq, labels_table, obj);
- ADD_LABEL(anchor, label);
+ rb_event_flag_t event;
+ if ((event = event_name_to_flag(obj)) != RUBY_EVENT_NONE) {
+ ADD_TRACE(anchor, event);
+ }
+ else {
+ LABEL *label = register_label(iseq, labels_table, obj);
+ ADD_LABEL(anchor, label);
+ }
}
else if (FIXNUM_P(obj)) {
line_no = NUM2INT(obj);
@@ -7152,7 +9419,13 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
}
if (argc > 0) {
- argv = compile_data_alloc(iseq, sizeof(VALUE) * argc);
+ argv = compile_data_calloc2(iseq, sizeof(VALUE), argc);
+
+ // add element before operand setup to make GC root
+ ADD_ELEM(anchor,
+ (LINK_ELEMENT*)new_insn_core(iseq, line_no,
+ (enum ruby_vminsn_type)insn_id, argc, argv));
+
for (j=0; j<argc; j++) {
VALUE op = rb_ary_entry(obj, j+1);
switch (insn_op_type((VALUE)insn_id, j)) {
@@ -7168,45 +9441,42 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
break;
case TS_VALUE:
argv[j] = op;
- iseq_add_mark_object(iseq, op);
+ RB_OBJ_WRITTEN(iseq, Qundef, op);
break;
case TS_ISEQ:
{
if (op != Qnil) {
- argv[j] = (VALUE)iseq_build_load_iseq(iseq, op);
+ VALUE v = (VALUE)iseq_build_load_iseq(iseq, op);
+ argv[j] = v;
+ RB_OBJ_WRITTEN(iseq, Qundef, v);
}
else {
argv[j] = 0;
}
}
break;
- case TS_GENTRY:
- op = rb_convert_type_with_id(op, T_SYMBOL, "Symbol", idTo_sym);
- argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
- break;
+ case TS_ISE:
case TS_IC:
+ case TS_IVC: /* inline ivar cache */
argv[j] = op;
if (NUM2UINT(op) >= iseq->body->is_size) {
iseq->body->is_size = NUM2INT(op) + 1;
}
+ FL_SET((VALUE)iseq, ISEQ_MARKABLE_ISEQ);
break;
- case TS_CALLINFO:
+ case TS_CALLDATA:
argv[j] = iseq_build_callinfo_from_hash(iseq, op);
break;
- case TS_CALLCACHE:
- argv[j] = Qfalse;
- break;
case TS_ID:
- argv[j] = rb_convert_type_with_id(op, T_SYMBOL,
- "Symbol", idTo_sym);
+ argv[j] = rb_to_symbol_type(op);
break;
case TS_CDHASH:
{
int i;
VALUE map = rb_hash_new_with_size(RARRAY_LEN(op)/2);
- rb_hash_tbl_raw(map)->type = &cdhash_type;
- op = rb_convert_type_with_id(op, T_ARRAY, "Array", idTo_ary);
+ RHASH_TBL_RAW(map)->type = &cdhash_type;
+ op = rb_to_array_type(op);
for (i=0; i<RARRAY_LEN(op); i+=2) {
VALUE key = RARRAY_AREF(op, i);
VALUE sym = RARRAY_AREF(op, i+1);
@@ -7216,7 +9486,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
}
RB_GC_GUARD(op);
argv[j] = map;
- rb_iseq_add_mark_object(iseq, map);
+ RB_OBJ_WRITTEN(iseq, Qundef, map);
}
break;
case TS_FUNCPTR:
@@ -7234,9 +9504,11 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
}
}
}
- ADD_ELEM(anchor,
- (LINK_ELEMENT*)new_insn_core(iseq, line_no,
- (enum ruby_vminsn_type)insn_id, argc, argv));
+ else {
+ ADD_ELEM(anchor,
+ (LINK_ELEMENT*)new_insn_core(iseq, line_no,
+ (enum ruby_vminsn_type)insn_id, argc, NULL));
+ }
}
else {
rb_raise(rb_eTypeError, "unexpected object for instruction");
@@ -7248,8 +9520,8 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
return iseq_setup(iseq, anchor);
}
-#define CHECK_ARRAY(v) rb_convert_type_with_id((v), T_ARRAY, "Array", idTo_ary)
-#define CHECK_SYMBOL(v) rb_convert_type_with_id((v), T_SYMBOL, "Symbol", idTo_sym)
+#define CHECK_ARRAY(v) rb_to_array_type(v)
+#define CHECK_SYMBOL(v) rb_to_symbol_type(v)
static int
int_param(int *dst, VALUE param, VALUE sym)
@@ -7280,7 +9552,7 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
iseq->body->param.flags.has_kw = TRUE;
keyword->num = len;
-#define SYM(s) ID2SYM(rb_intern(#s))
+#define SYM(s) ID2SYM(rb_intern_const(#s))
(void)int_param(&keyword->bits_start, params, SYM(kwbits));
i = keyword->bits_start - keyword->num;
ids = (ID *)&iseq->body->local_table[i];
@@ -7303,6 +9575,9 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
keyword->table = ids;
return keyword;
}
+ else if (default_len < 0) {
+ UNREACHABLE;
+ }
dvs = ALLOC_N(VALUE, (unsigned int)default_len);
@@ -7333,18 +9608,72 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
}
void
+rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
+{
+ INSN *iobj = 0;
+ size_t size = sizeof(INSN);
+ unsigned int pos = 0;
+
+ while (storage) {
+#ifdef STRICT_ALIGNMENT
+ size_t padding = calc_padding((void *)&storage->buff[pos], size);
+#else
+ const size_t padding = 0; /* expected to be optimized by compiler */
+#endif /* STRICT_ALIGNMENT */
+ size_t offset = pos + size + padding;
+ if (offset > storage->size || offset > storage->pos) {
+ pos = 0;
+ storage = storage->next;
+ }
+ else {
+#ifdef STRICT_ALIGNMENT
+ pos += (int)padding;
+#endif /* STRICT_ALIGNMENT */
+
+ iobj = (INSN *)&storage->buff[pos];
+
+ if (iobj->operands) {
+ int j;
+ const char *types = insn_op_types(iobj->insn_id);
+
+ for (j = 0; types[j]; j++) {
+ char type = types[j];
+ switch (type) {
+ case TS_CDHASH:
+ case TS_ISEQ:
+ case TS_VALUE:
+ case TS_CALLDATA: // ci is stored.
+ {
+ VALUE op = OPERAND_AT(iobj, j);
+
+ if (!SPECIAL_CONST_P(op)) {
+ rb_gc_mark(op);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ pos += (int)size;
+ }
+ }
+}
+
+void
rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
VALUE exception, VALUE body)
{
-#define SYM(s) ID2SYM(rb_intern(#s))
+#define SYM(s) ID2SYM(rb_intern_const(#s))
int i, len;
unsigned int arg_size, local_size, stack_max;
ID *tbl;
struct st_table *labels_table = st_init_numtable();
- VALUE labels_wrapper = Data_Wrap_Struct(0, 0, st_free_table, labels_table);
+ VALUE labels_wrapper = Data_Wrap_Struct(0, rb_mark_set, st_free_table, labels_table);
VALUE arg_opt_labels = rb_hash_aref(params, SYM(opt));
VALUE keywords = rb_hash_aref(params, SYM(keyword));
- VALUE sym_arg_rest = ID2SYM(rb_intern("#arg_rest"));
+ VALUE sym_arg_rest = ID2SYM(rb_intern_const("#arg_rest"));
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
@@ -7440,41 +9769,39 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
/* for parser */
int
-rb_dvar_defined(ID id, const struct rb_block *base_block)
-{
- const rb_iseq_t *iseq;
-
- if (base_block && (iseq = vm_block_iseq(base_block)) != NULL) {
- while (iseq->body->type == ISEQ_TYPE_BLOCK ||
- iseq->body->type == ISEQ_TYPE_RESCUE ||
- iseq->body->type == ISEQ_TYPE_ENSURE ||
- iseq->body->type == ISEQ_TYPE_EVAL ||
- iseq->body->type == ISEQ_TYPE_MAIN
+rb_dvar_defined(ID id, const rb_iseq_t *iseq)
+{
+ if (iseq) {
+ const struct rb_iseq_constant_body *body = iseq->body;
+ while (body->type == ISEQ_TYPE_BLOCK ||
+ body->type == ISEQ_TYPE_RESCUE ||
+ body->type == ISEQ_TYPE_ENSURE ||
+ body->type == ISEQ_TYPE_EVAL ||
+ body->type == ISEQ_TYPE_MAIN
) {
unsigned int i;
- for (i = 0; i < iseq->body->local_table_size; i++) {
- if (iseq->body->local_table[i] == id) {
+ for (i = 0; i < body->local_table_size; i++) {
+ if (body->local_table[i] == id) {
return 1;
}
}
- iseq = iseq->body->parent_iseq;
+ iseq = body->parent_iseq;
+ body = iseq->body;
}
}
return 0;
}
int
-rb_local_defined(ID id, const struct rb_block *base_block)
+rb_local_defined(ID id, const rb_iseq_t *iseq)
{
- const rb_iseq_t *iseq;
-
- if (base_block && (iseq = vm_block_iseq(base_block)) != NULL) {
+ if (iseq) {
unsigned int i;
- iseq = iseq->body->local_iseq;
+ const struct rb_iseq_constant_body *const body = iseq->body->local_iseq->body;
- for (i=0; i<iseq->body->local_table_size; i++) {
- if (iseq->body->local_table[i] == id) {
+ for (i=0; i<body->local_table_size; i++) {
+ if (body->local_table[i] == id) {
return 1;
}
}
@@ -7485,9 +9812,9 @@ rb_local_defined(ID id, const struct rb_block *base_block)
static int
caller_location(VALUE *path, VALUE *realpath)
{
- const rb_thread_t *const th = GET_THREAD();
+ const rb_execution_context_t *ec = GET_EC();
const rb_control_frame_t *const cfp =
- rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
+ rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
if (cfp) {
int line = rb_vm_get_sourceline(cfp);
@@ -7496,7 +9823,7 @@ caller_location(VALUE *path, VALUE *realpath)
return line;
}
else {
- *path = rb_fstring_cstr("<compiled>");
+ *path = rb_fstring_lit("<compiled>");
*realpath = *path;
return 1;
}
@@ -7504,81 +9831,98 @@ caller_location(VALUE *path, VALUE *realpath)
typedef struct {
VALUE arg;
- rb_insn_func_t func;
+ VALUE func;
int line;
} accessor_args;
static const rb_iseq_t *
-method_for_self(VALUE name, VALUE arg, rb_insn_func_t func,
- VALUE (*build)(rb_iseq_t *, LINK_ANCHOR *const, VALUE))
+method_for_self(VALUE name, VALUE arg, const struct rb_builtin_function *func,
+ void (*build)(rb_iseq_t *, LINK_ANCHOR *, const void *))
{
VALUE path, realpath;
accessor_args acc;
acc.arg = arg;
- acc.func = func;
+ acc.func = (VALUE)func;
acc.line = caller_location(&path, &realpath);
- return rb_iseq_new_with_opt((NODE *)IFUNC_NEW(build, (VALUE)&acc, 0),
- rb_sym2str(name), path, realpath,
- INT2FIX(acc.line), 0, ISEQ_TYPE_METHOD, 0);
+ struct rb_iseq_new_with_callback_callback_func *ifunc =
+ rb_iseq_new_with_callback_new_callback(build, &acc);
+ return rb_iseq_new_with_callback(ifunc,
+ rb_sym2str(name), path, realpath,
+ INT2FIX(acc.line), 0, ISEQ_TYPE_METHOD, 0);
}
-static VALUE
-for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a)
+static void
+for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *ret, const void *a)
{
const accessor_args *const args = (void *)a;
const int line = args->line;
+ struct rb_iseq_constant_body *const body = iseq->body;
iseq_set_local_table(iseq, 0);
- iseq->body->param.lead_num = 0;
- iseq->body->param.size = 0;
+ body->param.lead_num = 0;
+ body->param.size = 0;
ADD_INSN1(ret, line, putobject, args->arg);
- ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func);
- return Qnil;
+ ADD_INSN1(ret, line, invokebuiltin, args->func);
}
-static VALUE
-for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a)
+static void
+for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *ret, const void *a)
{
const accessor_args *const args = (void *)a;
const int line = args->line;
+ struct rb_iseq_constant_body *const body = iseq->body;
static const ID vars[] = {1, idUScore};
iseq_set_local_table(iseq, vars);
- iseq->body->param.lead_num = 1;
- iseq->body->param.size = 1;
+ body->param.lead_num = 1;
+ body->param.size = 1;
ADD_GETLOCAL(ret, line, numberof(vars)-1, 0);
ADD_INSN1(ret, line, putobject, args->arg);
- ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func);
- ADD_INSN(ret, line, pop);
- return Qnil;
+ ADD_INSN1(ret, line, invokebuiltin, args->func);
}
/*
* func (index) -> (value)
*/
const rb_iseq_t *
-rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
+rb_method_for_self_aref(VALUE name, VALUE arg, const struct rb_builtin_function *func)
{
return method_for_self(name, arg, func, for_self_aref);
}
/*
- * func (index, value) -> (index, value)
+ * func (index, value) -> (value)
*/
const rb_iseq_t *
-rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
+rb_method_for_self_aset(VALUE name, VALUE arg, const struct rb_builtin_function *func)
{
return method_for_self(name, arg, func, for_self_aset);
}
/* ISeq binary format */
+#ifndef IBF_ISEQ_DEBUG
+#define IBF_ISEQ_DEBUG 0
+#endif
+
+#ifndef IBF_ISEQ_ENABLE_LOCAL_BUFFER
+#define IBF_ISEQ_ENABLE_LOCAL_BUFFER 0
+#endif
+
typedef unsigned int ibf_offset_t;
#define IBF_OFFSET(ptr) ((ibf_offset_t)(VALUE)(ptr))
+#define IBF_MAJOR_VERSION ISEQ_MAJOR_VERSION
+#if RUBY_DEVEL
+#define IBF_DEVEL_VERSION 3
+#define IBF_MINOR_VERSION (ISEQ_MINOR_VERSION * 10000 + IBF_DEVEL_VERSION)
+#else
+#define IBF_MINOR_VERSION ISEQ_MINOR_VERSION
+#endif
+
struct ibf_header {
char magic[4]; /* YARB */
unsigned int major_version;
@@ -7587,81 +9931,202 @@ struct ibf_header {
unsigned int extra_size;
unsigned int iseq_list_size;
- unsigned int id_list_size;
- unsigned int object_list_size;
-
+ unsigned int global_object_list_size;
ibf_offset_t iseq_list_offset;
- ibf_offset_t id_list_offset;
- ibf_offset_t object_list_offset;
+ ibf_offset_t global_object_list_offset;
};
-struct ibf_id_entry {
- enum {
- ibf_id_enc_ascii,
- ibf_id_enc_utf8,
- ibf_id_enc_other
- } enc : 2;
- char body[1];
+struct ibf_dump_buffer {
+ VALUE str;
+ st_table *obj_table; /* obj -> obj number */
};
struct ibf_dump {
- VALUE str;
- VALUE iseq_list; /* [iseq0 offset, ...] */
- VALUE obj_list; /* [objs] */
st_table *iseq_table; /* iseq -> iseq number */
- st_table *id_table; /* id -> id number */
+ struct ibf_dump_buffer global_buffer;
+ struct ibf_dump_buffer *current_buffer;
};
rb_iseq_t * iseq_alloc(void);
-struct ibf_load {
+struct ibf_load_buffer {
const char *buff;
+ ibf_offset_t size;
+
+ VALUE obj_list; /* [obj0, ...] */
+ unsigned int obj_list_size;
+ ibf_offset_t obj_list_offset;
+};
+
+struct ibf_load {
const struct ibf_header *header;
- ID *id_list; /* [id0, ...] */
- VALUE iseq_list; /* [iseq0, ...] */
- VALUE obj_list; /* [obj0, ...] */
+ VALUE iseq_list; /* [iseq0, ...] */
+ struct ibf_load_buffer global_buffer;
VALUE loader_obj;
- VALUE str;
rb_iseq_t *iseq;
+ VALUE str;
+ struct ibf_load_buffer *current_buffer;
+};
+
+struct pinned_list {
+ long size;
+ VALUE * buffer;
+};
+
+static void
+pinned_list_mark(void *ptr)
+{
+ long i;
+ struct pinned_list *list = (struct pinned_list *)ptr;
+ for (i = 0; i < list->size; i++) {
+ if (list->buffer[i]) {
+ rb_gc_mark(list->buffer[i]);
+ }
+ }
+}
+
+static void
+pinned_list_free(void *ptr)
+{
+ struct pinned_list *list = (struct pinned_list *)ptr;
+ xfree(list->buffer);
+ xfree(ptr);
+}
+
+static size_t
+pinned_list_memsize(const void *ptr)
+{
+ struct pinned_list *list = (struct pinned_list *)ptr;
+ return sizeof(struct pinned_list) + (list->size * sizeof(VALUE *));
+}
+
+static const rb_data_type_t pinned_list_type = {
+ "pinned_list",
+ {pinned_list_mark, pinned_list_free, pinned_list_memsize,},
+ 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
};
+static VALUE
+pinned_list_fetch(VALUE list, long offset)
+{
+ struct pinned_list * ptr;
+
+ TypedData_Get_Struct(list, struct pinned_list, &pinned_list_type, ptr);
+
+ if (offset >= ptr->size) {
+ rb_raise(rb_eIndexError, "object index out of range: %ld", offset);
+ }
+
+ return ptr->buffer[offset];
+}
+
+static void
+pinned_list_store(VALUE list, long offset, VALUE object)
+{
+ struct pinned_list * ptr;
+
+ TypedData_Get_Struct(list, struct pinned_list, &pinned_list_type, ptr);
+
+ if (offset >= ptr->size) {
+ rb_raise(rb_eIndexError, "object index out of range: %ld", offset);
+ }
+
+ RB_OBJ_WRITE(list, &ptr->buffer[offset], object);
+}
+
+static VALUE
+pinned_list_new(long size)
+{
+ struct pinned_list * ptr;
+ VALUE obj_list =
+ TypedData_Make_Struct(0, struct pinned_list, &pinned_list_type, ptr);
+
+ ptr->buffer = xcalloc(size, sizeof(VALUE));
+ ptr->size = size;
+
+ return obj_list;
+}
+
static ibf_offset_t
ibf_dump_pos(struct ibf_dump *dump)
{
- return (unsigned int)rb_str_strlen(dump->str);
+ long pos = RSTRING_LEN(dump->current_buffer->str);
+#if SIZEOF_LONG > SIZEOF_INT
+ if (pos >= UINT_MAX) {
+ rb_raise(rb_eRuntimeError, "dump size exceeds");
+ }
+#endif
+ return (unsigned int)pos;
+}
+
+static void
+ibf_dump_align(struct ibf_dump *dump, size_t align)
+{
+ ibf_offset_t pos = ibf_dump_pos(dump);
+ if (pos % align) {
+ static const char padding[sizeof(VALUE)];
+ size_t size = align - ((size_t)pos % align);
+#if SIZEOF_LONG > SIZEOF_INT
+ if (pos + size >= UINT_MAX) {
+ rb_raise(rb_eRuntimeError, "dump size exceeds");
+ }
+#endif
+ for (; size > sizeof(padding); size -= sizeof(padding)) {
+ rb_str_cat(dump->current_buffer->str, padding, sizeof(padding));
+ }
+ rb_str_cat(dump->current_buffer->str, padding, size);
+ }
}
static ibf_offset_t
ibf_dump_write(struct ibf_dump *dump, const void *buff, unsigned long size)
{
ibf_offset_t pos = ibf_dump_pos(dump);
- rb_str_cat(dump->str, (const char *)buff, size);
+ rb_str_cat(dump->current_buffer->str, (const char *)buff, size);
/* TODO: overflow check */
return pos;
}
+static ibf_offset_t
+ibf_dump_write_byte(struct ibf_dump *dump, unsigned char byte)
+{
+ return ibf_dump_write(dump, &byte, sizeof(unsigned char));
+}
+
static void
ibf_dump_overwrite(struct ibf_dump *dump, void *buff, unsigned int size, long offset)
{
- VALUE str = dump->str;
+ VALUE str = dump->current_buffer->str;
char *ptr = RSTRING_PTR(str);
if ((unsigned long)(size + offset) > (unsigned long)RSTRING_LEN(str))
- rb_bug("ibf_dump_overwrite: overflow");
+ rb_bug("ibf_dump_overwrite: overflow");
memcpy(ptr + offset, buff, size);
}
+static const void *
+ibf_load_ptr(const struct ibf_load *load, ibf_offset_t *offset, int size)
+{
+ ibf_offset_t beg = *offset;
+ *offset += size;
+ return load->current_buffer->buff + beg;
+}
+
static void *
-ibf_load_alloc(const struct ibf_load *load, ibf_offset_t offset, int size)
+ibf_load_alloc(const struct ibf_load *load, ibf_offset_t offset, size_t x, size_t y)
{
- void *buff = ruby_xmalloc(size);
- memcpy(buff, load->buff + offset, size);
+ void *buff = ruby_xmalloc2(x, y);
+ size_t size = x * y;
+ memcpy(buff, load->current_buffer->buff + offset, size);
return buff;
}
-#define IBF_W(b, type, n) (type *)(VALUE)ibf_dump_write(dump, (b), sizeof(type) * (n))
+#define IBF_W_ALIGN(type) (RUBY_ALIGNOF(type) > 1 ? ibf_dump_align(dump, RUBY_ALIGNOF(type)) : (void)0)
+
+#define IBF_W(b, type, n) (IBF_W_ALIGN(type), (type *)(VALUE)IBF_WP(b, type, n))
#define IBF_WV(variable) ibf_dump_write(dump, &(variable), sizeof(variable))
#define IBF_WP(b, type, n) ibf_dump_write(dump, (b), sizeof(type) * (n))
-#define IBF_R(val, type, n) (type *)ibf_load_alloc(load, IBF_OFFSET(val), sizeof(type) * (n))
+#define IBF_R(val, type, n) (type *)ibf_load_alloc(load, IBF_OFFSET(val), sizeof(type), (n))
+#define IBF_ZERO(variable) memset(&(variable), 0, sizeof(variable))
static int
ibf_table_lookup(struct st_table *table, st_data_t key)
@@ -7669,21 +10134,21 @@ ibf_table_lookup(struct st_table *table, st_data_t key)
st_data_t val;
if (st_lookup(table, key, &val)) {
- return (int)val;
+ return (int)val;
}
else {
- return -1;
+ return -1;
}
}
static int
-ibf_table_index(struct st_table *table, st_data_t key)
+ibf_table_find_or_insert(struct st_table *table, st_data_t key)
{
int index = ibf_table_lookup(table, key);
if (index < 0) { /* not found */
- index = (int)table->num_entries;
- st_insert(table, key, (st_data_t)index);
+ index = (int)table->num_entries;
+ st_insert(table, key, (st_data_t)index);
}
return index;
@@ -7691,465 +10156,826 @@ ibf_table_index(struct st_table *table, st_data_t key)
/* dump/load generic */
+static void ibf_dump_object_list(struct ibf_dump *dump, ibf_offset_t *obj_list_offset, unsigned int *obj_list_size);
+
static VALUE ibf_load_object(const struct ibf_load *load, VALUE object_index);
static rb_iseq_t *ibf_load_iseq(const struct ibf_load *load, const rb_iseq_t *index_iseq);
+static st_table *
+ibf_dump_object_table_new(void)
+{
+ st_table *obj_table = st_init_numtable(); /* need free */
+ st_insert(obj_table, (st_data_t)Qnil, (st_data_t)0); /* 0th is nil */
+
+ return obj_table;
+}
+
static VALUE
ibf_dump_object(struct ibf_dump *dump, VALUE obj)
{
- long index = RARRAY_LEN(dump->obj_list);
- long i;
- for (i=0; i<index; i++) {
- if (RARRAY_AREF(dump->obj_list, i) == obj) return (VALUE)i; /* dedup */
- }
- rb_ary_push(dump->obj_list, obj);
- return (VALUE)index;
+ return ibf_table_find_or_insert(dump->current_buffer->obj_table, (st_data_t)obj);
}
static VALUE
ibf_dump_id(struct ibf_dump *dump, ID id)
{
- return (VALUE)ibf_table_index(dump->id_table, (st_data_t)id);
+ if (id == 0 || rb_id2name(id) == NULL) {
+ return 0;
+ }
+ return ibf_dump_object(dump, rb_id2sym(id));
}
static ID
ibf_load_id(const struct ibf_load *load, const ID id_index)
{
- ID id;
-
if (id_index == 0) {
- id = 0;
- }
- else {
- id = load->id_list[(long)id_index];
-
- if (id == 0) {
- long *indices = (long *)(load->buff + load->header->id_list_offset);
- VALUE str = ibf_load_object(load, indices[id_index]);
- id = NIL_P(str) ? 0 : rb_intern_str(str); /* str == nil -> internal junk id */
- load->id_list[(long)id_index] = id;
- }
+ return 0;
}
-
- return id;
+ VALUE sym = ibf_load_object(load, id_index);
+ return rb_sym2id(sym);
}
/* dump/load: code */
-static VALUE
-ibf_dump_callinfo(struct ibf_dump *dump, const struct rb_call_info *ci)
-{
- return (ci->flag & VM_CALL_KWARG) ? Qtrue : Qfalse;
-}
-
static ibf_offset_t ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq);
-static rb_iseq_t *
+static int
ibf_dump_iseq(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
if (iseq == NULL) {
- return (rb_iseq_t *)-1;
+ return -1;
}
else {
- int iseq_index = ibf_table_lookup(dump->iseq_table, (st_data_t)iseq);
- if (iseq_index < 0) {
- iseq_index = ibf_table_index(dump->iseq_table, (st_data_t)iseq);
- rb_ary_store(dump->iseq_list, iseq_index, LONG2NUM(ibf_dump_iseq_each(dump, rb_iseq_check(iseq))));
- }
- return (rb_iseq_t *)(VALUE)iseq_index;
+ return ibf_table_find_or_insert(dump->iseq_table, (st_data_t)iseq);
}
}
-static VALUE
-ibf_dump_gentry(struct ibf_dump *dump, const struct rb_global_entry *entry)
+static unsigned char
+ibf_load_byte(const struct ibf_load *load, ibf_offset_t *offset)
+{
+ if (*offset >= load->current_buffer->size) { rb_raise(rb_eRuntimeError, "invalid bytecode"); }
+ return (unsigned char)load->current_buffer->buff[(*offset)++];
+}
+
+/*
+ * Small uint serialization
+ * 0x00000000_00000000 - 0x00000000_0000007f: 1byte | XXXX XXX1 |
+ * 0x00000000_00000080 - 0x00000000_00003fff: 2byte | XXXX XX10 | XXXX XXXX |
+ * 0x00000000_00004000 - 0x00000000_001fffff: 3byte | XXXX X100 | XXXX XXXX | XXXX XXXX |
+ * 0x00000000_00020000 - 0x00000000_0fffffff: 4byte | XXXX 1000 | XXXX XXXX | XXXX XXXX | XXXX XXXX |
+ * ...
+ * 0x00010000_00000000 - 0x00ffffff_ffffffff: 8byte | 1000 0000 | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX |
+ * 0x01000000_00000000 - 0xffffffff_ffffffff: 9byte | 0000 0000 | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX | XXXX XXXX |
+ */
+static void
+ibf_dump_write_small_value(struct ibf_dump *dump, VALUE x)
{
- return (VALUE)ibf_dump_id(dump, entry->id);
+ if (sizeof(VALUE) > 8 || CHAR_BIT != 8) {
+ ibf_dump_write(dump, &x, sizeof(VALUE));
+ return;
+ }
+
+ enum { max_byte_length = sizeof(VALUE) + 1 };
+
+ unsigned char bytes[max_byte_length];
+ ibf_offset_t n;
+
+ for (n = 0; n < sizeof(VALUE) && (x >> (7 - n)); n++, x >>= 8) {
+ bytes[max_byte_length - 1 - n] = (unsigned char)x;
+ }
+
+ x <<= 1;
+ x |= 1;
+ x <<= n;
+ bytes[max_byte_length - 1 - n] = (unsigned char)x;
+ n++;
+
+ ibf_dump_write(dump, bytes + max_byte_length - n, n);
}
static VALUE
-ibf_load_gentry(const struct ibf_load *load, const struct rb_global_entry *entry)
+ibf_load_small_value(const struct ibf_load *load, ibf_offset_t *offset)
+{
+ if (sizeof(VALUE) > 8 || CHAR_BIT != 8) {
+ union { char s[sizeof(VALUE)]; VALUE v; } x;
+
+ memcpy(x.s, load->current_buffer->buff + *offset, sizeof(VALUE));
+ *offset += sizeof(VALUE);
+
+ return x.v;
+ }
+
+ enum { max_byte_length = sizeof(VALUE) + 1 };
+
+ const unsigned char *buffer = (const unsigned char *)load->current_buffer->buff;
+ const unsigned char c = buffer[*offset];
+
+ ibf_offset_t n =
+ c & 1 ? 1 :
+ c == 0 ? 9 : ntz_int32(c) + 1;
+ VALUE x = (VALUE)c >> n;
+
+ if (*offset + n > load->current_buffer->size) {
+ rb_raise(rb_eRuntimeError, "invalid byte sequence");
+ }
+
+ ibf_offset_t i;
+ for (i = 1; i < n; i++) {
+ x <<= 8;
+ x |= (VALUE)buffer[*offset + i];
+ }
+
+ *offset += n;
+ return x;
+}
+
+static void
+ibf_dump_builtin(struct ibf_dump *dump, const struct rb_builtin_function *bf)
{
- ID gid = ibf_load_id(load, (ID)(VALUE)entry);
- return (VALUE)rb_global_entry(gid);
+ // short: index
+ // short: name.length
+ // bytes: name
+ // // omit argc (only verify with name)
+ ibf_dump_write_small_value(dump, (VALUE)bf->index);
+
+ size_t len = strlen(bf->name);
+ ibf_dump_write_small_value(dump, (VALUE)len);
+ ibf_dump_write(dump, bf->name, len);
}
-static VALUE *
-ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
+static const struct rb_builtin_function *
+ibf_load_builtin(const struct ibf_load *load, ibf_offset_t *offset)
{
- const int iseq_size = iseq->body->iseq_size;
- int code_index;
- VALUE *code;
- const VALUE *orig_code = rb_iseq_original_iseq(iseq);
+ int i = (int)ibf_load_small_value(load, offset);
+ int len = (int)ibf_load_small_value(load, offset);
+ const char *name = (char *)ibf_load_ptr(load, offset, len);
- code = ALLOCA_N(VALUE, iseq_size);
+ if (0) {
+ fprintf(stderr, "%.*s!!\n", len, name);
+ }
- for (code_index=0; code_index<iseq_size;) {
- const VALUE insn = orig_code[code_index];
- const char *types = insn_op_types(insn);
- int op_index;
-
- code[code_index++] = (VALUE)insn;
-
- for (op_index=0; types[op_index]; op_index++, code_index++) {
- VALUE op = orig_code[code_index];
- switch (types[op_index]) {
- case TS_CDHASH:
- case TS_VALUE:
- code[code_index] = ibf_dump_object(dump, op);
- break;
- case TS_ISEQ:
- code[code_index] = (VALUE)ibf_dump_iseq(dump, (const rb_iseq_t *)op);
- break;
- case TS_IC:
- {
- unsigned int i;
- for (i=0; i<iseq->body->is_size; i++) {
- if (op == (VALUE)&iseq->body->is_entries[i]) {
- break;
- }
- }
- code[code_index] = i;
- }
- break;
- case TS_CALLINFO:
- code[code_index] = ibf_dump_callinfo(dump, (const struct rb_call_info *)op);
- break;
- case TS_CALLCACHE:
- code[code_index] = 0;
- break;
- case TS_ID:
- code[code_index] = ibf_dump_id(dump, (ID)op);
- break;
- case TS_GENTRY:
- code[code_index] = ibf_dump_gentry(dump, (const struct rb_global_entry *)op);
- break;
- case TS_FUNCPTR:
- rb_raise(rb_eRuntimeError, "TS_FUNCPTR is not supported");
- break;
- default:
- code[code_index] = op;
- break;
- }
- }
- assert(insn_len(insn) == op_index+1);
+ const struct rb_builtin_function *table = GET_VM()->builtin_function_table;
+ if (table == NULL) rb_raise(rb_eArgError, "builtin function table is not provided");
+ if (strncmp(table[i].name, name, len) != 0) {
+ rb_raise(rb_eArgError, "builtin function index (%d) mismatch (expect %s but %s)", i, name, table[i].name);
}
+ // fprintf(stderr, "load-builtin: name:%s(%d)\n", table[i].name, table[i].argc);
- return IBF_W(code, VALUE, iseq_size);
+ return &table[i];
}
-static VALUE *
-ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct rb_iseq_constant_body *body)
+static ibf_offset_t
+ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
+ const struct rb_iseq_constant_body *const body = iseq->body;
const int iseq_size = body->iseq_size;
int code_index;
- VALUE *code = IBF_R(body->iseq_encoded, VALUE, iseq_size);
+ const VALUE *orig_code = rb_iseq_original_iseq(iseq);
- struct rb_call_info *ci_entries = iseq->body->ci_entries;
- struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&iseq->body->ci_entries[iseq->body->ci_size];
- struct rb_call_cache *cc_entries = iseq->body->cc_entries;
- union iseq_inline_storage_entry *is_entries = iseq->body->is_entries;
+ ibf_offset_t offset = ibf_dump_pos(dump);
for (code_index=0; code_index<iseq_size;) {
- const VALUE insn = code[code_index++];
- const char *types = insn_op_types(insn);
- int op_index;
-
- for (op_index=0; types[op_index]; op_index++, code_index++) {
- VALUE op = code[code_index];
+ const VALUE insn = orig_code[code_index++];
+ const char *types = insn_op_types(insn);
+ int op_index;
+
+ /* opcode */
+ if (insn >= 0x100) { rb_raise(rb_eRuntimeError, "invalid instruction"); }
+ ibf_dump_write_small_value(dump, insn);
+
+ /* operands */
+ for (op_index=0; types[op_index]; op_index++, code_index++) {
+ VALUE op = orig_code[code_index];
+ VALUE wv;
+
+ switch (types[op_index]) {
+ case TS_CDHASH:
+ case TS_VALUE:
+ wv = ibf_dump_object(dump, op);
+ break;
+ case TS_ISEQ:
+ wv = (VALUE)ibf_dump_iseq(dump, (const rb_iseq_t *)op);
+ break;
+ case TS_IC:
+ case TS_IVC:
+ case TS_ISE:
+ {
+ unsigned int i;
+ for (i=0; i<body->is_size; i++) {
+ if (op == (VALUE)&body->is_entries[i]) {
+ break;
+ }
+ }
+ wv = (VALUE)i;
+ }
+ break;
+ case TS_CALLDATA:
+ {
+ goto skip_wv;
+ }
+ case TS_ID:
+ wv = ibf_dump_id(dump, (ID)op);
+ break;
+ case TS_FUNCPTR:
+ rb_raise(rb_eRuntimeError, "TS_FUNCPTR is not supported");
+ goto skip_wv;
+ case TS_BUILTIN:
+ ibf_dump_builtin(dump, (const struct rb_builtin_function *)op);
+ goto skip_wv;
+ default:
+ wv = op;
+ break;
+ }
+ ibf_dump_write_small_value(dump, wv);
+ skip_wv:;
+ }
+ assert(insn_len(insn) == op_index+1);
+ }
+
+ return offset;
+}
- switch (types[op_index]) {
- case TS_CDHASH:
- case TS_VALUE:
- code[code_index] = ibf_load_object(load, op);
- break;
- case TS_ISEQ:
- code[code_index] = (VALUE)ibf_load_iseq(load, (const rb_iseq_t *)op);
- break;
- case TS_IC:
- code[code_index] = (VALUE)&is_entries[(int)op];
- break;
- case TS_CALLINFO:
- code[code_index] = op ? (VALUE)ci_kw_entries++ : (VALUE)ci_entries++; /* op is Qtrue (kw) or Qfalse (!kw) */
- break;
- case TS_CALLCACHE:
- code[code_index] = (VALUE)cc_entries++;
- break;
- case TS_ID:
- code[code_index] = ibf_load_id(load, (ID)op);
- break;
- case TS_GENTRY:
- code[code_index] = ibf_load_gentry(load, (const struct rb_global_entry *)op);
- break;
- case TS_FUNCPTR:
- rb_raise(rb_eRuntimeError, "TS_FUNCPTR is not supported");
- break;
- default:
- /* code[code_index] = op; */
- break;
- }
- }
- if (insn_len(insn) != op_index+1) {
- rb_raise(rb_eRuntimeError, "operand size mismatch");
- }
- }
+static VALUE *
+ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecode_offset, ibf_offset_t bytecode_size, unsigned int iseq_size)
+{
+ VALUE iseqv = (VALUE)iseq;
+ unsigned int code_index;
+ ibf_offset_t reading_pos = bytecode_offset;
+ VALUE *code = ALLOC_N(VALUE, iseq_size);
+ struct rb_iseq_constant_body *load_body = iseq->body;
+ struct rb_call_data *cd_entries = load_body->call_data;
+ union iseq_inline_storage_entry *is_entries = load_body->is_entries;
+ for (code_index=0; code_index<iseq_size;) {
+ /* opcode */
+ const VALUE insn = code[code_index++] = ibf_load_small_value(load, &reading_pos);
+ const char *types = insn_op_types(insn);
+ int op_index;
+
+ /* operands */
+ for (op_index=0; types[op_index]; op_index++, code_index++) {
+ switch (types[op_index]) {
+ case TS_CDHASH:
+ case TS_VALUE:
+ {
+ VALUE op = ibf_load_small_value(load, &reading_pos);
+ VALUE v = ibf_load_object(load, op);
+ code[code_index] = v;
+ if (!SPECIAL_CONST_P(v)) {
+ RB_OBJ_WRITTEN(iseqv, Qundef, v);
+ FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ }
+ break;
+ }
+ case TS_ISEQ:
+ {
+ VALUE op = (VALUE)ibf_load_small_value(load, &reading_pos);
+ VALUE v = (VALUE)ibf_load_iseq(load, (const rb_iseq_t *)op);
+ code[code_index] = v;
+ if (!SPECIAL_CONST_P(v)) {
+ RB_OBJ_WRITTEN(iseqv, Qundef, v);
+ FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ }
+ break;
+ }
+ case TS_ISE:
+ case TS_IC:
+ case TS_IVC:
+ {
+ VALUE op = ibf_load_small_value(load, &reading_pos);
+ code[code_index] = (VALUE)&is_entries[op];
+ }
+ FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ break;
+ case TS_CALLDATA:
+ {
+ code[code_index] = (VALUE)cd_entries++;
+ }
+ break;
+ case TS_ID:
+ {
+ VALUE op = ibf_load_small_value(load, &reading_pos);
+ code[code_index] = ibf_load_id(load, (ID)(VALUE)op);
+ }
+ break;
+ case TS_FUNCPTR:
+ rb_raise(rb_eRuntimeError, "TS_FUNCPTR is not supported");
+ break;
+ case TS_BUILTIN:
+ code[code_index] = (VALUE)ibf_load_builtin(load, &reading_pos);
+ break;
+ default:
+ code[code_index] = ibf_load_small_value(load, &reading_pos);
+ continue;
+ }
+ }
+ if (insn_len(insn) != op_index+1) {
+ rb_raise(rb_eRuntimeError, "operand size mismatch");
+ }
+ }
+ load_body->iseq_encoded = code;
+ load_body->iseq_size = code_index;
+
+ assert(code_index == iseq_size);
+ assert(reading_pos == bytecode_offset + bytecode_size);
return code;
}
-static VALUE *
+static ibf_offset_t
ibf_dump_param_opt_table(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
int opt_num = iseq->body->param.opt_num;
if (opt_num > 0) {
- return IBF_W(iseq->body->param.opt_table, VALUE, opt_num + 1);
+ IBF_W_ALIGN(VALUE);
+ return ibf_dump_write(dump, iseq->body->param.opt_table, sizeof(VALUE) * (opt_num + 1));
}
else {
- return NULL;
+ return ibf_dump_pos(dump);
}
}
static VALUE *
-ibf_load_param_opt_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+ibf_load_param_opt_table(const struct ibf_load *load, ibf_offset_t opt_table_offset, int opt_num)
{
- int opt_num = body->param.opt_num;
-
if (opt_num > 0) {
- ibf_offset_t offset = IBF_OFFSET(body->param.opt_table);
- VALUE *table = ALLOC_N(VALUE, opt_num+1);
- MEMCPY(table, load->buff + offset, VALUE, opt_num+1);
- return table;
+ VALUE *table = ALLOC_N(VALUE, opt_num+1);
+ MEMCPY(table, load->current_buffer->buff + opt_table_offset, VALUE, opt_num+1);
+ return table;
}
else {
- return NULL;
+ return NULL;
}
}
-static struct rb_iseq_param_keyword *
+static ibf_offset_t
ibf_dump_param_keyword(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
const struct rb_iseq_param_keyword *kw = iseq->body->param.keyword;
if (kw) {
- struct rb_iseq_param_keyword dump_kw = *kw;
- int dv_num = kw->num - kw->required_num;
- ID *ids = kw->num > 0 ? ALLOCA_N(ID, kw->num) : NULL;
- VALUE *dvs = dv_num > 0 ? ALLOCA_N(VALUE, dv_num) : NULL;
- int i;
+ struct rb_iseq_param_keyword dump_kw = *kw;
+ int dv_num = kw->num - kw->required_num;
+ ID *ids = kw->num > 0 ? ALLOCA_N(ID, kw->num) : NULL;
+ VALUE *dvs = dv_num > 0 ? ALLOCA_N(VALUE, dv_num) : NULL;
+ int i;
- for (i=0; i<kw->num; i++) ids[i] = (ID)ibf_dump_id(dump, kw->table[i]);
- for (i=0; i<dv_num; i++) dvs[i] = (VALUE)ibf_dump_object(dump, kw->default_values[i]);
+ for (i=0; i<kw->num; i++) ids[i] = (ID)ibf_dump_id(dump, kw->table[i]);
+ for (i=0; i<dv_num; i++) dvs[i] = (VALUE)ibf_dump_object(dump, kw->default_values[i]);
- dump_kw.table = IBF_W(ids, ID, kw->num);
- dump_kw.default_values = IBF_W(dvs, VALUE, dv_num);
- return IBF_W(&dump_kw, struct rb_iseq_param_keyword, 1);
+ dump_kw.table = IBF_W(ids, ID, kw->num);
+ dump_kw.default_values = IBF_W(dvs, VALUE, dv_num);
+ IBF_W_ALIGN(struct rb_iseq_param_keyword);
+ return ibf_dump_write(dump, &dump_kw, sizeof(struct rb_iseq_param_keyword) * 1);
}
else {
- return NULL;
+ return 0;
}
}
static const struct rb_iseq_param_keyword *
-ibf_load_param_keyword(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
-{
- if (body->param.keyword) {
- struct rb_iseq_param_keyword *kw = IBF_R(body->param.keyword, struct rb_iseq_param_keyword, 1);
- ID *ids = IBF_R(kw->table, ID, kw->num);
- int dv_num = kw->num - kw->required_num;
- VALUE *dvs = IBF_R(kw->default_values, VALUE, dv_num);
- int i;
+ibf_load_param_keyword(const struct ibf_load *load, ibf_offset_t param_keyword_offset)
+{
+ if (param_keyword_offset) {
+ struct rb_iseq_param_keyword *kw = IBF_R(param_keyword_offset, struct rb_iseq_param_keyword, 1);
+ ID *ids = IBF_R(kw->table, ID, kw->num);
+ int dv_num = kw->num - kw->required_num;
+ VALUE *dvs = IBF_R(kw->default_values, VALUE, dv_num);
+ int i;
+
+ for (i=0; i<kw->num; i++) {
+ ids[i] = ibf_load_id(load, ids[i]);
+ }
+ for (i=0; i<dv_num; i++) {
+ dvs[i] = ibf_load_object(load, dvs[i]);
+ }
+
+ kw->table = ids;
+ kw->default_values = dvs;
+ return kw;
+ }
+ else {
+ return NULL;
+ }
+}
- for (i=0; i<kw->num; i++) {
- ids[i] = ibf_load_id(load, ids[i]);
- }
- for (i=0; i<dv_num; i++) {
- dvs[i] = ibf_load_object(load, dvs[i]);
- }
+static ibf_offset_t
+ibf_dump_insns_info_body(struct ibf_dump *dump, const rb_iseq_t *iseq)
+{
+ ibf_offset_t offset = ibf_dump_pos(dump);
+ const struct iseq_insn_info_entry *entries = iseq->body->insns_info.body;
- kw->table = ids;
- kw->default_values = dvs;
- return kw;
+ unsigned int i;
+ for (i = 0; i < iseq->body->insns_info.size; i++) {
+ ibf_dump_write_small_value(dump, entries[i].line_no);
+ ibf_dump_write_small_value(dump, entries[i].events);
}
- else {
- return NULL;
+
+ return offset;
+}
+
+static struct iseq_insn_info_entry *
+ibf_load_insns_info_body(const struct ibf_load *load, ibf_offset_t body_offset, unsigned int size)
+{
+ ibf_offset_t reading_pos = body_offset;
+ struct iseq_insn_info_entry *entries = ALLOC_N(struct iseq_insn_info_entry, size);
+
+ unsigned int i;
+ for (i = 0; i < size; i++) {
+ entries[i].line_no = (int)ibf_load_small_value(load, &reading_pos);
+ entries[i].events = (rb_event_flag_t)ibf_load_small_value(load, &reading_pos);
}
+
+ return entries;
}
-static struct iseq_line_info_entry *
-ibf_dump_line_info_table(struct ibf_dump *dump, const rb_iseq_t *iseq)
+static ibf_offset_t
+ibf_dump_insns_info_positions(struct ibf_dump *dump, const unsigned int *positions, unsigned int size)
{
- return IBF_W(iseq->body->line_info_table, struct iseq_line_info_entry, iseq->body->line_info_size);
+ ibf_offset_t offset = ibf_dump_pos(dump);
+
+ unsigned int last = 0;
+ unsigned int i;
+ for (i = 0; i < size; i++) {
+ ibf_dump_write_small_value(dump, positions[i] - last);
+ last = positions[i];
+ }
+
+ return offset;
}
-static struct iseq_line_info_entry *
-ibf_load_line_info_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+static unsigned int *
+ibf_load_insns_info_positions(const struct ibf_load *load, ibf_offset_t positions_offset, unsigned int size)
{
- return IBF_R(body->line_info_table, struct iseq_line_info_entry, body->line_info_size);
+ ibf_offset_t reading_pos = positions_offset;
+ unsigned int *positions = ALLOC_N(unsigned int, size);
+
+ unsigned int last = 0;
+ unsigned int i;
+ for (i = 0; i < size; i++) {
+ positions[i] = last + (unsigned int)ibf_load_small_value(load, &reading_pos);
+ last = positions[i];
+ }
+
+ return positions;
}
-static ID *
+static ibf_offset_t
ibf_dump_local_table(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
- const int size = iseq->body->local_table_size;
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ const int size = body->local_table_size;
ID *table = ALLOCA_N(ID, size);
int i;
for (i=0; i<size; i++) {
- table[i] = ibf_dump_id(dump, iseq->body->local_table[i]);
+ table[i] = ibf_dump_id(dump, body->local_table[i]);
}
- return IBF_W(table, ID, size);
+ IBF_W_ALIGN(ID);
+ return ibf_dump_write(dump, table, sizeof(ID) * size);
}
static ID *
-ibf_load_local_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+ibf_load_local_table(const struct ibf_load *load, ibf_offset_t local_table_offset, int size)
{
- const int size = body->local_table_size;
-
if (size > 0) {
- ID *table = IBF_R(body->local_table, ID, size);
- int i;
+ ID *table = IBF_R(local_table_offset, ID, size);
+ int i;
- for (i=0; i<size; i++) {
- table[i] = ibf_load_id(load, table[i]);
- }
- return table;
+ for (i=0; i<size; i++) {
+ table[i] = ibf_load_id(load, table[i]);
+ }
+ return table;
}
else {
- return NULL;
+ return NULL;
}
}
-static struct iseq_catch_table *
+static ibf_offset_t
ibf_dump_catch_table(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
const struct iseq_catch_table *table = iseq->body->catch_table;
if (table) {
- int byte_size = iseq_catch_table_bytes(iseq->body->catch_table->size);
- struct iseq_catch_table *dump_table = (struct iseq_catch_table *)ALLOCA_N(char, byte_size);
- unsigned int i;
- dump_table->size = table->size;
- for (i=0; i<table->size; i++) {
- dump_table->entries[i] = table->entries[i];
- dump_table->entries[i].iseq = ibf_dump_iseq(dump, table->entries[i].iseq);
- }
- return (struct iseq_catch_table *)(VALUE)ibf_dump_write(dump, dump_table, byte_size);
+ int *iseq_indices = ALLOCA_N(int, table->size);
+ unsigned int i;
+
+ for (i=0; i<table->size; i++) {
+ iseq_indices[i] = ibf_dump_iseq(dump, table->entries[i].iseq);
+ }
+
+ const ibf_offset_t offset = ibf_dump_pos(dump);
+
+ for (i=0; i<table->size; i++) {
+ ibf_dump_write_small_value(dump, iseq_indices[i]);
+ ibf_dump_write_small_value(dump, table->entries[i].type);
+ ibf_dump_write_small_value(dump, table->entries[i].start);
+ ibf_dump_write_small_value(dump, table->entries[i].end);
+ ibf_dump_write_small_value(dump, table->entries[i].cont);
+ ibf_dump_write_small_value(dump, table->entries[i].sp);
+ }
+ return offset;
}
else {
- return NULL;
+ return ibf_dump_pos(dump);
}
}
static struct iseq_catch_table *
-ibf_load_catch_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+ibf_load_catch_table(const struct ibf_load *load, ibf_offset_t catch_table_offset, unsigned int size)
{
- if (body->catch_table) {
- struct iseq_catch_table *table;
- unsigned int i;
- unsigned int size;
- size = *(unsigned int *)(load->buff + IBF_OFFSET(body->catch_table));
- table = ibf_load_alloc(load, IBF_OFFSET(body->catch_table), iseq_catch_table_bytes(size));
- for (i=0; i<size; i++) {
- table->entries[i].iseq = ibf_load_iseq(load, table->entries[i].iseq);
- }
- return table;
+ if (size) {
+ struct iseq_catch_table *table = ruby_xmalloc(iseq_catch_table_bytes(size));
+ table->size = size;
+
+ ibf_offset_t reading_pos = catch_table_offset;
+
+ unsigned int i;
+ for (i=0; i<table->size; i++) {
+ int iseq_index = (int)ibf_load_small_value(load, &reading_pos);
+ table->entries[i].type = (enum catch_type)ibf_load_small_value(load, &reading_pos);
+ table->entries[i].start = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ table->entries[i].end = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ table->entries[i].cont = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ table->entries[i].sp = (unsigned int)ibf_load_small_value(load, &reading_pos);
+
+ table->entries[i].iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)iseq_index);
+ }
+ return table;
}
else {
- return NULL;
+ return NULL;
}
}
-static struct rb_call_info *
+static ibf_offset_t
ibf_dump_ci_entries(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
- const unsigned int ci_size = iseq->body->ci_size;
- const unsigned int ci_kw_size = iseq->body->ci_kw_size;
- const struct rb_call_info *ci_entries = iseq->body->ci_entries;
- struct rb_call_info *dump_ci_entries;
- struct rb_call_info_with_kwarg *dump_ci_kw_entries;
- int byte_size = ci_size * sizeof(struct rb_call_info) +
- ci_kw_size * sizeof(struct rb_call_info_with_kwarg);
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ const unsigned int ci_size = body->ci_size;
+ const struct rb_call_data *cds = body->call_data;
+
+ ibf_offset_t offset = ibf_dump_pos(dump);
+
unsigned int i;
- dump_ci_entries = (struct rb_call_info *)ALLOCA_N(char, byte_size);
- dump_ci_kw_entries = (struct rb_call_info_with_kwarg *)&dump_ci_entries[ci_size];
- memcpy(dump_ci_entries, ci_entries, byte_size);
+ for (i = 0; i < ci_size; i++) {
+ const struct rb_callinfo *ci = cds[i].ci;
+ if (ci != NULL) {
+ ibf_dump_write_small_value(dump, ibf_dump_id(dump, vm_ci_mid(ci)));
+ ibf_dump_write_small_value(dump, vm_ci_flag(ci));
+ ibf_dump_write_small_value(dump, vm_ci_argc(ci));
- for (i=0; i<ci_size; i++) { /* conver ID for each ci */
- dump_ci_entries[i].mid = ibf_dump_id(dump, dump_ci_entries[i].mid);
+ const struct rb_callinfo_kwarg *kwarg = vm_ci_kwarg(ci);
+ if (kwarg) {
+ int len = kwarg->keyword_len;
+ ibf_dump_write_small_value(dump, len);
+ for (int j=0; j<len; j++) {
+ VALUE keyword = ibf_dump_object(dump, kwarg->keywords[j]);
+ ibf_dump_write_small_value(dump, keyword);
+ }
+ }
+ else {
+ ibf_dump_write_small_value(dump, 0);
+ }
+ }
+ else {
+ // TODO: truncate NULL ci from call_data.
+ ibf_dump_write_small_value(dump, (VALUE)-1);
+ }
}
- for (i=0; i<ci_kw_size; i++) {
- const struct rb_call_info_kw_arg *kw_arg = dump_ci_kw_entries[i].kw_arg;
- int j;
- VALUE *keywords = ALLOCA_N(VALUE, kw_arg->keyword_len);
- for (j=0; j<kw_arg->keyword_len; j++) {
- keywords[j] = (VALUE)ibf_dump_object(dump, kw_arg->keywords[j]); /* kw_arg->keywords[n] is Symbol */
- }
- dump_ci_kw_entries[i].kw_arg = (struct rb_call_info_kw_arg *)(VALUE)ibf_dump_write(dump, &kw_arg->keyword_len, sizeof(int));
- ibf_dump_write(dump, keywords, sizeof(VALUE) * kw_arg->keyword_len);
- dump_ci_kw_entries[i].ci.mid = ibf_dump_id(dump, dump_ci_kw_entries[i].ci.mid);
+ return offset;
+}
+
+static enum rb_id_table_iterator_result
+dump_outer_variable(ID id, VALUE val, void *dump)
+{
+ ibf_dump_write_small_value(dump, ibf_dump_id(dump, id));
+ ibf_dump_write_small_value(dump, val);
+
+ return ID_TABLE_CONTINUE;
+}
+
+static ibf_offset_t
+ibf_dump_outer_variables(struct ibf_dump *dump, const rb_iseq_t *iseq)
+{
+ struct rb_id_table * ovs = iseq->body->outer_variables;
+
+ ibf_offset_t offset = ibf_dump_pos(dump);
+
+ if (ovs) {
+ ibf_dump_write_small_value(dump, (VALUE)rb_id_table_size(ovs));
+ rb_id_table_foreach(ovs, dump_outer_variable, (void *)dump);
}
- return (struct rb_call_info *)(VALUE)ibf_dump_write(dump, dump_ci_entries, byte_size);
+ else {
+ ibf_dump_write_small_value(dump, (VALUE)0);
+ }
+
+ return offset;
}
-static struct rb_call_info *
-ibf_load_ci_entries(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+/* note that we dump out rb_call_info but load back rb_call_data */
+static void
+ibf_load_ci_entries(const struct ibf_load *load,
+ ibf_offset_t ci_entries_offset,
+ unsigned int ci_size,
+ struct rb_call_data **cd_ptr)
{
+ ibf_offset_t reading_pos = ci_entries_offset;
+
unsigned int i;
- const unsigned int ci_size = body->ci_size;
- const unsigned int ci_kw_size = body->ci_kw_size;
- struct rb_call_info *ci_entries = ibf_load_alloc(load, IBF_OFFSET(body->ci_entries),
- sizeof(struct rb_call_info) * body->ci_size +
- sizeof(struct rb_call_info_with_kwarg) * body->ci_kw_size);
- struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&ci_entries[ci_size];
- for (i=0; i<ci_size; i++) {
- ci_entries[i].mid = ibf_load_id(load, ci_entries[i].mid);
+ struct rb_call_data *cds = ZALLOC_N(struct rb_call_data, ci_size);
+ *cd_ptr = cds;
+
+ for (i = 0; i < ci_size; i++) {
+ VALUE mid_index = ibf_load_small_value(load, &reading_pos);
+ if (mid_index != (VALUE)-1) {
+ ID mid = ibf_load_id(load, mid_index);
+ unsigned int flag = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ unsigned int argc = (unsigned int)ibf_load_small_value(load, &reading_pos);
+
+ struct rb_callinfo_kwarg *kwarg = NULL;
+ int kwlen = (int)ibf_load_small_value(load, &reading_pos);
+ if (kwlen > 0) {
+ kwarg = rb_xmalloc_mul_add(kwlen, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
+ kwarg->keyword_len = kwlen;
+ for (int j=0; j<kwlen; j++) {
+ VALUE keyword = ibf_load_small_value(load, &reading_pos);
+ kwarg->keywords[j] = ibf_load_object(load, keyword);
+ }
+ }
+
+ cds[i].ci = vm_ci_new(mid, flag, argc, kwarg);
+ RB_OBJ_WRITTEN(load->iseq, Qundef, cds[i].ci);
+ cds[i].cc = vm_cc_empty();
+ }
+ else {
+ // NULL ci
+ cds[i].ci = NULL;
+ cds[i].cc = NULL;
+ }
}
- for (i=0; i<ci_kw_size; i++) {
- int j;
- ibf_offset_t kw_arg_offset = IBF_OFFSET(ci_kw_entries[i].kw_arg);
- const int keyword_len = *(int *)(load->buff + kw_arg_offset);
- const VALUE *keywords = (VALUE *)(load->buff + kw_arg_offset + sizeof(int));
- struct rb_call_info_kw_arg *kw_arg = ruby_xmalloc(sizeof(struct rb_call_info_kw_arg) + sizeof(VALUE) * (keyword_len - 1));
- kw_arg->keyword_len = keyword_len;
- for (j=0; j<kw_arg->keyword_len; j++) {
- kw_arg->keywords[j] = (VALUE)ibf_load_object(load, keywords[j]);
- }
- ci_kw_entries[i].kw_arg = kw_arg;
- ci_kw_entries[i].ci.mid = ibf_load_id(load, ci_kw_entries[i].ci.mid);
+}
+
+static struct rb_id_table *
+ibf_load_outer_variables(const struct ibf_load * load, ibf_offset_t outer_variables_offset)
+{
+ ibf_offset_t reading_pos = outer_variables_offset;
+
+ struct rb_id_table *tbl = NULL;
+
+ size_t table_size = (size_t)ibf_load_small_value(load, &reading_pos);
+
+ if (table_size > 0) {
+ tbl = rb_id_table_create(table_size);
}
- return ci_entries;
+ for (size_t i = 0; i < table_size; i++) {
+ ID key = ibf_load_id(load, (ID)ibf_load_small_value(load, &reading_pos));
+ VALUE value = ibf_load_small_value(load, &reading_pos);
+ rb_id_table_insert(tbl, key, value);
+ }
+
+ return tbl;
}
static ibf_offset_t
ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
- struct rb_iseq_constant_body dump_body;
- dump_body = *iseq->body;
+ assert(dump->current_buffer == &dump->global_buffer);
+
+ unsigned int *positions;
- dump_body.location.pathobj = ibf_dump_object(dump, dump_body.location.pathobj); /* TODO: freeze */
- dump_body.location.base_label = ibf_dump_object(dump, dump_body.location.base_label);
- dump_body.location.label = ibf_dump_object(dump, dump_body.location.label);
+ const struct rb_iseq_constant_body *body = iseq->body;
- dump_body.iseq_encoded = ibf_dump_code(dump, iseq);
- dump_body.param.opt_table = ibf_dump_param_opt_table(dump, iseq);
- dump_body.param.keyword = ibf_dump_param_keyword(dump, iseq);
- dump_body.line_info_table = ibf_dump_line_info_table(dump, iseq);
- dump_body.local_table = ibf_dump_local_table(dump, iseq);
- dump_body.catch_table = ibf_dump_catch_table(dump, iseq);
- dump_body.parent_iseq = ibf_dump_iseq(dump, iseq->body->parent_iseq);
- dump_body.local_iseq = ibf_dump_iseq(dump, iseq->body->local_iseq);
- dump_body.is_entries = NULL;
- dump_body.ci_entries = ibf_dump_ci_entries(dump, iseq);
- dump_body.cc_entries = NULL;
- dump_body.mark_ary = ISEQ_FLIP_CNT(iseq);
+ const VALUE location_pathobj_index = ibf_dump_object(dump, body->location.pathobj); /* TODO: freeze */
+ const VALUE location_base_label_index = ibf_dump_object(dump, body->location.base_label);
+ const VALUE location_label_index = ibf_dump_object(dump, body->location.label);
+
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+ ibf_offset_t iseq_start = ibf_dump_pos(dump);
+
+ struct ibf_dump_buffer *saved_buffer = dump->current_buffer;
+ struct ibf_dump_buffer buffer;
+ buffer.str = rb_str_new(0, 0);
+ buffer.obj_table = ibf_dump_object_table_new();
+ dump->current_buffer = &buffer;
+#endif
- return ibf_dump_write(dump, &dump_body, sizeof(dump_body));
+ const ibf_offset_t bytecode_offset = ibf_dump_code(dump, iseq);
+ const ibf_offset_t bytecode_size = ibf_dump_pos(dump) - bytecode_offset;
+ const ibf_offset_t param_opt_table_offset = ibf_dump_param_opt_table(dump, iseq);
+ const ibf_offset_t param_keyword_offset = ibf_dump_param_keyword(dump, iseq);
+ const ibf_offset_t insns_info_body_offset = ibf_dump_insns_info_body(dump, iseq);
+
+ positions = rb_iseq_insns_info_decode_positions(iseq->body);
+ const ibf_offset_t insns_info_positions_offset = ibf_dump_insns_info_positions(dump, positions, body->insns_info.size);
+ ruby_xfree(positions);
+
+ const ibf_offset_t local_table_offset = ibf_dump_local_table(dump, iseq);
+ const unsigned int catch_table_size = body->catch_table ? body->catch_table->size : 0;
+ const ibf_offset_t catch_table_offset = ibf_dump_catch_table(dump, iseq);
+ const int parent_iseq_index = ibf_dump_iseq(dump, iseq->body->parent_iseq);
+ const int local_iseq_index = ibf_dump_iseq(dump, iseq->body->local_iseq);
+ const ibf_offset_t ci_entries_offset = ibf_dump_ci_entries(dump, iseq);
+ const ibf_offset_t outer_variables_offset = ibf_dump_outer_variables(dump, iseq);
+
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+ ibf_offset_t local_obj_list_offset;
+ unsigned int local_obj_list_size;
+
+ ibf_dump_object_list(dump, &local_obj_list_offset, &local_obj_list_size);
+#endif
+
+ ibf_offset_t body_offset = ibf_dump_pos(dump);
+
+ /* dump the constant body */
+ unsigned int param_flags =
+ (body->param.flags.has_lead << 0) |
+ (body->param.flags.has_opt << 1) |
+ (body->param.flags.has_rest << 2) |
+ (body->param.flags.has_post << 3) |
+ (body->param.flags.has_kw << 4) |
+ (body->param.flags.has_kwrest << 5) |
+ (body->param.flags.has_block << 6) |
+ (body->param.flags.ambiguous_param0 << 7) |
+ (body->param.flags.accepts_no_kwarg << 8) |
+ (body->param.flags.ruby2_keywords << 9);
+
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+# define IBF_BODY_OFFSET(x) (x)
+#else
+# define IBF_BODY_OFFSET(x) (body_offset - (x))
+#endif
+
+ ibf_dump_write_small_value(dump, body->type);
+ ibf_dump_write_small_value(dump, body->iseq_size);
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(bytecode_offset));
+ ibf_dump_write_small_value(dump, bytecode_size);
+ ibf_dump_write_small_value(dump, param_flags);
+ ibf_dump_write_small_value(dump, body->param.size);
+ ibf_dump_write_small_value(dump, body->param.lead_num);
+ ibf_dump_write_small_value(dump, body->param.opt_num);
+ ibf_dump_write_small_value(dump, body->param.rest_start);
+ ibf_dump_write_small_value(dump, body->param.post_start);
+ ibf_dump_write_small_value(dump, body->param.post_num);
+ ibf_dump_write_small_value(dump, body->param.block_start);
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(param_opt_table_offset));
+ ibf_dump_write_small_value(dump, param_keyword_offset);
+ ibf_dump_write_small_value(dump, location_pathobj_index);
+ ibf_dump_write_small_value(dump, location_base_label_index);
+ ibf_dump_write_small_value(dump, location_label_index);
+ ibf_dump_write_small_value(dump, body->location.first_lineno);
+ ibf_dump_write_small_value(dump, body->location.node_id);
+ ibf_dump_write_small_value(dump, body->location.code_location.beg_pos.lineno);
+ ibf_dump_write_small_value(dump, body->location.code_location.beg_pos.column);
+ ibf_dump_write_small_value(dump, body->location.code_location.end_pos.lineno);
+ ibf_dump_write_small_value(dump, body->location.code_location.end_pos.column);
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(insns_info_body_offset));
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(insns_info_positions_offset));
+ ibf_dump_write_small_value(dump, body->insns_info.size);
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(local_table_offset));
+ ibf_dump_write_small_value(dump, catch_table_size);
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(catch_table_offset));
+ ibf_dump_write_small_value(dump, parent_iseq_index);
+ ibf_dump_write_small_value(dump, local_iseq_index);
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(ci_entries_offset));
+ ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(outer_variables_offset));
+ ibf_dump_write_small_value(dump, body->variable.flip_count);
+ ibf_dump_write_small_value(dump, body->local_table_size);
+ ibf_dump_write_small_value(dump, body->is_size);
+ ibf_dump_write_small_value(dump, body->ci_size);
+ ibf_dump_write_small_value(dump, body->stack_max);
+ ibf_dump_write_small_value(dump, body->catch_except_p);
+ ibf_dump_write_small_value(dump, body->builtin_inline_p);
+
+#undef IBF_BODY_OFFSET
+
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+ ibf_offset_t iseq_length_bytes = ibf_dump_pos(dump);
+
+ dump->current_buffer = saved_buffer;
+ ibf_dump_write(dump, RSTRING_PTR(buffer.str), iseq_length_bytes);
+
+ ibf_offset_t offset = ibf_dump_pos(dump);
+ ibf_dump_write_small_value(dump, iseq_start);
+ ibf_dump_write_small_value(dump, iseq_length_bytes);
+ ibf_dump_write_small_value(dump, body_offset);
+
+ ibf_dump_write_small_value(dump, local_obj_list_offset);
+ ibf_dump_write_small_value(dump, local_obj_list_size);
+
+ st_free_table(buffer.obj_table); // TODO: this leaks in case of exception
+
+ return offset;
+#else
+ return body_offset;
+#endif
}
static VALUE
@@ -8157,123 +10983,223 @@ ibf_load_location_str(const struct ibf_load *load, VALUE str_index)
{
VALUE str = ibf_load_object(load, str_index);
if (str != Qnil) {
- str = rb_fstring(str);
+ str = rb_fstring(str);
}
return str;
}
static void
-ibf_load_iseq_each(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
+ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
{
- struct rb_iseq_constant_body *load_body = iseq->body = ZALLOC(struct rb_iseq_constant_body);
- const struct rb_iseq_constant_body *body = (struct rb_iseq_constant_body *)(load->buff + offset);
+ struct rb_iseq_constant_body *load_body = iseq->body = rb_iseq_constant_body_alloc();
- /* memcpy(load_body, load->buff + offset, sizeof(*load_body)); */
- load_body->type = body->type;
- load_body->stack_max = body->stack_max;
- load_body->iseq_size = body->iseq_size;
- load_body->param = body->param;
- load_body->local_table_size = body->local_table_size;
- load_body->is_size = body->is_size;
- load_body->ci_size = body->ci_size;
- load_body->ci_kw_size = body->ci_kw_size;
- load_body->line_info_size = body->line_info_size;
+ ibf_offset_t reading_pos = offset;
- RB_OBJ_WRITE(iseq, &load_body->mark_ary, iseq_mark_ary_create((int)body->mark_ary));
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+ struct ibf_load_buffer *saved_buffer = load->current_buffer;
+ load->current_buffer = &load->global_buffer;
- {
- VALUE realpath = Qnil, path = ibf_load_object(load, body->location.pathobj);
- if (RB_TYPE_P(path, T_STRING)) {
- realpath = path = rb_fstring(path);
- }
- else if (RB_TYPE_P(path, T_ARRAY)) {
- VALUE pathobj = path;
- if (RARRAY_LEN(pathobj) != 2) {
- rb_raise(rb_eRuntimeError, "path object size mismatch");
- }
- path = rb_fstring(RARRAY_AREF(pathobj, 0));
- realpath = rb_fstring(RARRAY_AREF(pathobj, 1));
- }
- else {
- rb_raise(rb_eRuntimeError, "unexpected path object");
- }
- rb_iseq_pathobj_set(iseq, path, realpath);
- }
+ const ibf_offset_t iseq_start = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t iseq_length_bytes = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t body_offset = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
- RB_OBJ_WRITE(iseq, &load_body->location.base_label, ibf_load_location_str(load, body->location.base_label));
- RB_OBJ_WRITE(iseq, &load_body->location.label, ibf_load_location_str(load, body->location.label));
- load_body->location.first_lineno = body->location.first_lineno;
+ struct ibf_load_buffer buffer;
+ buffer.buff = load->global_buffer.buff + iseq_start;
+ buffer.size = iseq_length_bytes;
+ buffer.obj_list_offset = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
+ buffer.obj_list_size = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
+ buffer.obj_list = pinned_list_new(buffer.obj_list_size);
- load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, body->is_size);
- load_body->ci_entries = ibf_load_ci_entries(load, body);
- load_body->cc_entries = ZALLOC_N(struct rb_call_cache, body->ci_size + body->ci_kw_size);
- load_body->param.opt_table = ibf_load_param_opt_table(load, body);
- load_body->param.keyword = ibf_load_param_keyword(load, body);
- load_body->line_info_table = ibf_load_line_info_table(load, body);
- load_body->local_table = ibf_load_local_table(load, body);
- load_body->catch_table = ibf_load_catch_table(load, body);
- load_body->parent_iseq = ibf_load_iseq(load, body->parent_iseq);
- load_body->local_iseq = ibf_load_iseq(load, body->local_iseq);
-
- load_body->iseq_encoded = ibf_load_code(load, iseq, body);
+ load->current_buffer = &buffer;
+ reading_pos = body_offset;
+#endif
- rb_iseq_translate_threaded_code(iseq);
-}
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+# define IBF_BODY_OFFSET(x) (x)
+#else
+# define IBF_BODY_OFFSET(x) (offset - (x))
+#endif
+ const unsigned int type = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const unsigned int iseq_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t bytecode_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const ibf_offset_t bytecode_size = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
+ const unsigned int param_flags = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const unsigned int param_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const int param_lead_num = (int)ibf_load_small_value(load, &reading_pos);
+ const int param_opt_num = (int)ibf_load_small_value(load, &reading_pos);
+ const int param_rest_start = (int)ibf_load_small_value(load, &reading_pos);
+ const int param_post_start = (int)ibf_load_small_value(load, &reading_pos);
+ const int param_post_num = (int)ibf_load_small_value(load, &reading_pos);
+ const int param_block_start = (int)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t param_opt_table_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const ibf_offset_t param_keyword_offset = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
+ const VALUE location_pathobj_index = ibf_load_small_value(load, &reading_pos);
+ const VALUE location_base_label_index = ibf_load_small_value(load, &reading_pos);
+ const VALUE location_label_index = ibf_load_small_value(load, &reading_pos);
+ const VALUE location_first_lineno = ibf_load_small_value(load, &reading_pos);
+ const int location_node_id = (int)ibf_load_small_value(load, &reading_pos);
+ const int location_code_location_beg_pos_lineno = (int)ibf_load_small_value(load, &reading_pos);
+ const int location_code_location_beg_pos_column = (int)ibf_load_small_value(load, &reading_pos);
+ const int location_code_location_end_pos_lineno = (int)ibf_load_small_value(load, &reading_pos);
+ const int location_code_location_end_pos_column = (int)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t insns_info_body_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const ibf_offset_t insns_info_positions_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const unsigned int insns_info_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t local_table_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const unsigned int catch_table_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t catch_table_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const int parent_iseq_index = (int)ibf_load_small_value(load, &reading_pos);
+ const int local_iseq_index = (int)ibf_load_small_value(load, &reading_pos);
+ const ibf_offset_t ci_entries_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const ibf_offset_t outer_variables_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
+ const rb_snum_t variable_flip_count = (rb_snum_t)ibf_load_small_value(load, &reading_pos);
+ const unsigned int local_table_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const unsigned int is_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const unsigned int ci_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const unsigned int stack_max = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const char catch_except_p = (char)ibf_load_small_value(load, &reading_pos);
+ const bool builtin_inline_p = (bool)ibf_load_small_value(load, &reading_pos);
+
+#undef IBF_BODY_OFFSET
+
+ load_body->type = type;
+ load_body->stack_max = stack_max;
+ load_body->param.flags.has_lead = (param_flags >> 0) & 1;
+ load_body->param.flags.has_opt = (param_flags >> 1) & 1;
+ load_body->param.flags.has_rest = (param_flags >> 2) & 1;
+ load_body->param.flags.has_post = (param_flags >> 3) & 1;
+ load_body->param.flags.has_kw = FALSE;
+ load_body->param.flags.has_kwrest = (param_flags >> 5) & 1;
+ load_body->param.flags.has_block = (param_flags >> 6) & 1;
+ load_body->param.flags.ambiguous_param0 = (param_flags >> 7) & 1;
+ load_body->param.flags.accepts_no_kwarg = (param_flags >> 8) & 1;
+ load_body->param.flags.ruby2_keywords = (param_flags >> 9) & 1;
+ load_body->param.size = param_size;
+ load_body->param.lead_num = param_lead_num;
+ load_body->param.opt_num = param_opt_num;
+ load_body->param.rest_start = param_rest_start;
+ load_body->param.post_start = param_post_start;
+ load_body->param.post_num = param_post_num;
+ load_body->param.block_start = param_block_start;
+ load_body->local_table_size = local_table_size;
+ load_body->is_size = is_size;
+ load_body->ci_size = ci_size;
+ load_body->insns_info.size = insns_info_size;
+
+ ISEQ_COVERAGE_SET(iseq, Qnil);
+ ISEQ_ORIGINAL_ISEQ_CLEAR(iseq);
+ iseq->body->variable.flip_count = variable_flip_count;
+
+ load_body->location.first_lineno = location_first_lineno;
+ load_body->location.node_id = location_node_id;
+ load_body->location.code_location.beg_pos.lineno = location_code_location_beg_pos_lineno;
+ load_body->location.code_location.beg_pos.column = location_code_location_beg_pos_column;
+ load_body->location.code_location.end_pos.lineno = location_code_location_end_pos_lineno;
+ load_body->location.code_location.end_pos.column = location_code_location_end_pos_column;
+ load_body->catch_except_p = catch_except_p;
+ load_body->builtin_inline_p = builtin_inline_p;
+
+ load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, is_size);
+ ibf_load_ci_entries(load, ci_entries_offset, ci_size, &load_body->call_data);
+ load_body->outer_variables = ibf_load_outer_variables(load, outer_variables_offset);
+ load_body->param.opt_table = ibf_load_param_opt_table(load, param_opt_table_offset, param_opt_num);
+ load_body->param.keyword = ibf_load_param_keyword(load, param_keyword_offset);
+ load_body->param.flags.has_kw = (param_flags >> 4) & 1;
+ load_body->insns_info.body = ibf_load_insns_info_body(load, insns_info_body_offset, insns_info_size);
+ load_body->insns_info.positions = ibf_load_insns_info_positions(load, insns_info_positions_offset, insns_info_size);
+ load_body->local_table = ibf_load_local_table(load, local_table_offset, local_table_size);
+ load_body->catch_table = ibf_load_catch_table(load, catch_table_offset, catch_table_size);
+ load_body->parent_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)parent_iseq_index);
+ load_body->local_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)local_iseq_index);
+
+ ibf_load_code(load, iseq, bytecode_offset, bytecode_size, iseq_size);
+#if VM_INSN_INFO_TABLE_IMPL == 2
+ rb_iseq_insns_info_encode_positions(iseq);
+#endif
-static void
-ibf_dump_iseq_list(struct ibf_dump *dump, struct ibf_header *header)
-{
- const long size = RARRAY_LEN(dump->iseq_list);
- ibf_offset_t *list = ALLOCA_N(ibf_offset_t, size);
- long i;
+ rb_iseq_translate_threaded_code(iseq);
- for (i=0; i<size; i++) {
- list[i] = (ibf_offset_t)NUM2LONG(rb_ary_entry(dump->iseq_list, i));
- }
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+ load->current_buffer = &load->global_buffer;
+#endif
- header->iseq_list_offset = ibf_dump_write(dump, list, sizeof(ibf_offset_t) * size);
- header->iseq_list_size = (unsigned int)size;
+ {
+ VALUE realpath = Qnil, path = ibf_load_object(load, location_pathobj_index);
+ if (RB_TYPE_P(path, T_STRING)) {
+ realpath = path = rb_fstring(path);
+ }
+ else if (RB_TYPE_P(path, T_ARRAY)) {
+ VALUE pathobj = path;
+ if (RARRAY_LEN(pathobj) != 2) {
+ rb_raise(rb_eRuntimeError, "path object size mismatch");
+ }
+ path = rb_fstring(RARRAY_AREF(pathobj, 0));
+ realpath = RARRAY_AREF(pathobj, 1);
+ if (!NIL_P(realpath)) {
+ if (!RB_TYPE_P(realpath, T_STRING)) {
+ rb_raise(rb_eArgError, "unexpected realpath %"PRIxVALUE
+ "(%x), path=%+"PRIsVALUE,
+ realpath, TYPE(realpath), path);
+ }
+ realpath = rb_fstring(realpath);
+ }
+ }
+ else {
+ rb_raise(rb_eRuntimeError, "unexpected path object");
+ }
+ rb_iseq_pathobj_set(iseq, path, realpath);
+ }
+
+ RB_OBJ_WRITE(iseq, &load_body->location.base_label, ibf_load_location_str(load, location_base_label_index));
+ RB_OBJ_WRITE(iseq, &load_body->location.label, ibf_load_location_str(load, location_label_index));
+
+#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
+ load->current_buffer = saved_buffer;
+#endif
+ verify_call_cache(iseq);
}
-struct ibf_dump_id_list_i_arg {
+struct ibf_dump_iseq_list_arg
+{
struct ibf_dump *dump;
- long *list;
- int current_i;
+ VALUE offset_list;
};
static int
-ibf_dump_id_list_i(st_data_t key, st_data_t val, st_data_t ptr)
+ibf_dump_iseq_list_i(st_data_t key, st_data_t val, st_data_t ptr)
{
- struct ibf_dump_id_list_i_arg *arg = (struct ibf_dump_id_list_i_arg *)ptr;
- int i = (int)val;
- ID id = (ID)key;
- assert(arg->current_i == i);
- arg->current_i++;
+ const rb_iseq_t *iseq = (const rb_iseq_t *)key;
+ struct ibf_dump_iseq_list_arg *args = (struct ibf_dump_iseq_list_arg *)ptr;
- if (rb_id2name(id)) {
- arg->list[i] = (long)ibf_dump_object(arg->dump, rb_id2str(id));
- }
- else {
- arg->list[i] = 0;
- }
+ ibf_offset_t offset = ibf_dump_iseq_each(args->dump, iseq);
+ rb_ary_push(args->offset_list, UINT2NUM(offset));
return ST_CONTINUE;
}
static void
-ibf_dump_id_list(struct ibf_dump *dump, struct ibf_header *header)
+ibf_dump_iseq_list(struct ibf_dump *dump, struct ibf_header *header)
{
- const long size = dump->id_table->num_entries;
- struct ibf_dump_id_list_i_arg arg;
- arg.list = ALLOCA_N(long, size);
- arg.dump = dump;
- arg.current_i = 0;
+ VALUE offset_list = rb_ary_tmp_new(dump->iseq_table->num_entries);
+
+ struct ibf_dump_iseq_list_arg args;
+ args.dump = dump;
+ args.offset_list = offset_list;
+
+ st_foreach(dump->iseq_table, ibf_dump_iseq_list_i, (st_data_t)&args);
+
+ st_index_t i;
+ st_index_t size = dump->iseq_table->num_entries;
+ ibf_offset_t *offsets = ALLOCA_N(ibf_offset_t, size);
- st_foreach(dump->id_table, ibf_dump_id_list_i, (st_data_t)&arg);
+ for (i = 0; i < size; i++) {
+ offsets[i] = NUM2UINT(RARRAY_AREF(offset_list, i));
+ }
- header->id_list_offset = ibf_dump_write(dump, arg.list, sizeof(long) * size);
- header->id_list_size = (unsigned int)size;
+ ibf_dump_align(dump, sizeof(ibf_offset_t));
+ header->iseq_list_offset = ibf_dump_write(dump, offsets, sizeof(ibf_offset_t) * size);
+ header->iseq_list_size = (unsigned int)size;
}
#define IBF_OBJECT_INTERNAL FL_PROMOTED0
@@ -8294,13 +11220,9 @@ struct ibf_object_header {
enum ibf_object_class_index {
IBF_OBJECT_CLASS_OBJECT,
IBF_OBJECT_CLASS_ARRAY,
- IBF_OBJECT_CLASS_STANDARD_ERROR
-};
-
-struct ibf_object_string {
- long encindex;
- long len;
- char ptr[1];
+ IBF_OBJECT_CLASS_STANDARD_ERROR,
+ IBF_OBJECT_CLASS_NO_MATCHING_PATTERN_ERROR,
+ IBF_OBJECT_CLASS_TYPE_ERROR,
};
struct ibf_object_regexp {
@@ -8308,14 +11230,9 @@ struct ibf_object_regexp {
char option;
};
-struct ibf_object_array {
- long len;
- long ary[1];
-};
-
struct ibf_object_hash {
long len;
- long keyval[1];
+ long keyval[FLEX_ARY_LEN];
};
struct ibf_object_struct_range {
@@ -8328,11 +11245,11 @@ struct ibf_object_struct_range {
struct ibf_object_bignum {
ssize_t slen;
- BDIGIT digits[1];
+ BDIGIT digits[FLEX_ARY_LEN];
};
enum ibf_object_data_type {
- IBF_OBJECT_DATA_ENCODING
+ IBF_OBJECT_DATA_ENCODING,
};
struct ibf_object_complex_rational {
@@ -8343,21 +11260,37 @@ struct ibf_object_symbol {
long str;
};
-#define IBF_OBJHEADER(offset) (struct ibf_object_header *)(load->buff + (offset))
-#define IBF_OBJBODY(type, offset) (type *)(load->buff + sizeof(struct ibf_object_header) + (offset))
+#define IBF_ALIGNED_OFFSET(align, offset) /* offset > 0 */ \
+ ((((offset) - 1) / (align) + 1) * (align))
+#define IBF_OBJBODY(type, offset) (const type *)\
+ ibf_load_check_offset(load, IBF_ALIGNED_OFFSET(RUBY_ALIGNOF(type), offset))
+
+static const void *
+ibf_load_check_offset(const struct ibf_load *load, size_t offset)
+{
+ if (offset >= load->current_buffer->size) {
+ rb_raise(rb_eIndexError, "object offset out of range: %"PRIdSIZE, offset);
+ }
+ return load->current_buffer->buff + offset;
+}
+
+NORETURN(static void ibf_dump_object_unsupported(struct ibf_dump *dump, VALUE obj));
static void
ibf_dump_object_unsupported(struct ibf_dump *dump, VALUE obj)
{
- rb_obj_info_dump(obj);
- rb_bug("ibf_dump_object_unsupported: unsupported");
+ char buff[0x100];
+ rb_raw_obj_info(buff, sizeof(buff), obj);
+ rb_raise(rb_eNotImpError, "ibf_dump_object_unsupported: %s", buff);
}
+NORETURN(static VALUE ibf_load_object_unsupported(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset));
+
static VALUE
ibf_load_object_unsupported(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- rb_bug("unsupported");
- return Qnil;
+ rb_raise(rb_eArgError, "unsupported");
+ UNREACHABLE_RETURN(Qnil);
}
static void
@@ -8365,27 +11298,32 @@ ibf_dump_object_class(struct ibf_dump *dump, VALUE obj)
{
enum ibf_object_class_index cindex;
if (obj == rb_cObject) {
- cindex = IBF_OBJECT_CLASS_OBJECT;
+ cindex = IBF_OBJECT_CLASS_OBJECT;
}
else if (obj == rb_cArray) {
- cindex = IBF_OBJECT_CLASS_ARRAY;
+ cindex = IBF_OBJECT_CLASS_ARRAY;
}
else if (obj == rb_eStandardError) {
- cindex = IBF_OBJECT_CLASS_STANDARD_ERROR;
+ cindex = IBF_OBJECT_CLASS_STANDARD_ERROR;
+ }
+ else if (obj == rb_eNoMatchingPatternError) {
+ cindex = IBF_OBJECT_CLASS_NO_MATCHING_PATTERN_ERROR;
+ }
+ else if (obj == rb_eTypeError) {
+ cindex = IBF_OBJECT_CLASS_TYPE_ERROR;
}
else {
- rb_obj_info_dump(obj);
- rb_p(obj);
- rb_bug("unsupported class");
+ rb_obj_info_dump(obj);
+ rb_p(obj);
+ rb_bug("unsupported class");
}
- ibf_dump_write(dump, &cindex, sizeof(cindex));
+ ibf_dump_write_small_value(dump, (VALUE)cindex);
}
static VALUE
ibf_load_object_class(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- enum ibf_object_class_index *cindexp = IBF_OBJBODY(enum ibf_object_class_index, offset);
- enum ibf_object_class_index cindex = *cindexp;
+ enum ibf_object_class_index cindex = (enum ibf_object_class_index)ibf_load_small_value(load, &offset);
switch (cindex) {
case IBF_OBJECT_CLASS_OBJECT:
@@ -8394,9 +11332,13 @@ ibf_load_object_class(const struct ibf_load *load, const struct ibf_object_heade
return rb_cArray;
case IBF_OBJECT_CLASS_STANDARD_ERROR:
return rb_eStandardError;
+ case IBF_OBJECT_CLASS_NO_MATCHING_PATTERN_ERROR:
+ return rb_eNoMatchingPatternError;
+ case IBF_OBJECT_CLASS_TYPE_ERROR:
+ return rb_eTypeError;
}
- rb_bug("ibf_load_object_class: unknown class (%d)", (int)cindex);
+ rb_raise(rb_eArgError, "ibf_load_object_class: unknown class (%d)", (int)cindex);
}
@@ -8404,13 +11346,13 @@ static void
ibf_dump_object_float(struct ibf_dump *dump, VALUE obj)
{
double dbl = RFLOAT_VALUE(obj);
- ibf_dump_write(dump, &dbl, sizeof(dbl));
+ (void)IBF_W(&dbl, double, 1);
}
static VALUE
ibf_load_object_float(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- double *dblp = IBF_OBJBODY(double, offset);
+ const double *dblp = IBF_OBJBODY(double, offset);
return DBL2NUM(*dblp);
}
@@ -8422,26 +11364,30 @@ ibf_dump_object_string(struct ibf_dump *dump, VALUE obj)
const char *ptr = RSTRING_PTR(obj);
if (encindex > RUBY_ENCINDEX_BUILTIN_MAX) {
- rb_encoding *enc = rb_enc_from_index((int)encindex);
- const char *enc_name = rb_enc_name(enc);
- encindex = RUBY_ENCINDEX_BUILTIN_MAX + ibf_dump_object(dump, rb_str_new2(enc_name));
+ rb_encoding *enc = rb_enc_from_index((int)encindex);
+ const char *enc_name = rb_enc_name(enc);
+ encindex = RUBY_ENCINDEX_BUILTIN_MAX + ibf_dump_object(dump, rb_str_new2(enc_name));
}
- IBF_WV(encindex);
- IBF_WV(len);
+ ibf_dump_write_small_value(dump, encindex);
+ ibf_dump_write_small_value(dump, len);
IBF_WP(ptr, char, len);
}
static VALUE
ibf_load_object_string(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- const struct ibf_object_string *string = IBF_OBJBODY(struct ibf_object_string, offset);
- VALUE str = rb_str_new(string->ptr, string->len);
- int encindex = (int)string->encindex;
+ ibf_offset_t reading_pos = offset;
+
+ int encindex = (int)ibf_load_small_value(load, &reading_pos);
+ const long len = (long)ibf_load_small_value(load, &reading_pos);
+ const char *ptr = load->current_buffer->buff + reading_pos;
+
+ VALUE str = rb_str_new(ptr, len);
if (encindex > RUBY_ENCINDEX_BUILTIN_MAX) {
- VALUE enc_name_str = ibf_load_object(load, encindex - RUBY_ENCINDEX_BUILTIN_MAX);
- encindex = rb_enc_find_index(RSTRING_PTR(enc_name_str));
+ VALUE enc_name_str = ibf_load_object(load, encindex - RUBY_ENCINDEX_BUILTIN_MAX);
+ encindex = rb_enc_find_index(RSTRING_PTR(enc_name_str));
}
rb_enc_associate_index(str, encindex);
@@ -8454,19 +11400,24 @@ ibf_load_object_string(const struct ibf_load *load, const struct ibf_object_head
static void
ibf_dump_object_regexp(struct ibf_dump *dump, VALUE obj)
{
+ VALUE srcstr = RREGEXP_SRC(obj);
struct ibf_object_regexp regexp;
- regexp.srcstr = RREGEXP_SRC(obj);
regexp.option = (char)rb_reg_options(obj);
- regexp.srcstr = (long)ibf_dump_object(dump, regexp.srcstr);
- IBF_WV(regexp);
+ regexp.srcstr = (long)ibf_dump_object(dump, srcstr);
+
+ ibf_dump_write_byte(dump, (unsigned char)regexp.option);
+ ibf_dump_write_small_value(dump, regexp.srcstr);
}
static VALUE
ibf_load_object_regexp(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- const struct ibf_object_regexp *regexp = IBF_OBJBODY(struct ibf_object_regexp, offset);
- VALUE srcstr = ibf_load_object(load, regexp->srcstr);
- VALUE reg = rb_reg_compile(srcstr, (int)regexp->option, NULL, 0);
+ struct ibf_object_regexp regexp;
+ regexp.option = ibf_load_byte(load, &offset);
+ regexp.srcstr = ibf_load_small_value(load, &offset);
+
+ VALUE srcstr = ibf_load_object(load, regexp.srcstr);
+ VALUE reg = rb_reg_compile(srcstr, (int)regexp.option, NULL, 0);
if (header->internal) rb_obj_hide(reg);
if (header->frozen) rb_obj_freeze(reg);
@@ -8477,23 +11428,27 @@ ibf_load_object_regexp(const struct ibf_load *load, const struct ibf_object_head
static void
ibf_dump_object_array(struct ibf_dump *dump, VALUE obj)
{
- long i, len = (int)RARRAY_LEN(obj);
- IBF_WV(len);
+ long i, len = RARRAY_LEN(obj);
+ ibf_dump_write_small_value(dump, len);
for (i=0; i<len; i++) {
- long index = (long)ibf_dump_object(dump, RARRAY_AREF(obj, i));
- IBF_WV(index);
+ long index = (long)ibf_dump_object(dump, RARRAY_AREF(obj, i));
+ ibf_dump_write_small_value(dump, index);
}
}
static VALUE
ibf_load_object_array(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- const struct ibf_object_array *array = IBF_OBJBODY(struct ibf_object_array, offset);
- VALUE ary = rb_ary_new_capa(array->len);
+ ibf_offset_t reading_pos = offset;
+
+ const long len = (long)ibf_load_small_value(load, &reading_pos);
+
+ VALUE ary = rb_ary_new_capa(len);
int i;
- for (i=0; i<array->len; i++) {
- rb_ary_push(ary, ibf_load_object(load, array->ary[i]));
+ for (i=0; i<len; i++) {
+ const VALUE index = ibf_load_small_value(load, &reading_pos);
+ rb_ary_push(ary, ibf_load_object(load, index));
}
if (header->internal) rb_obj_hide(ary);
@@ -8506,10 +11461,12 @@ static int
ibf_dump_object_hash_i(st_data_t key, st_data_t val, st_data_t ptr)
{
struct ibf_dump *dump = (struct ibf_dump *)ptr;
- long key_index = (long)ibf_dump_object(dump, (VALUE)key);
- long val_index = (long)ibf_dump_object(dump, (VALUE)val);
- IBF_WV(key_index);
- IBF_WV(val_index);
+
+ VALUE key_index = ibf_dump_object(dump, (VALUE)key);
+ VALUE val_index = ibf_dump_object(dump, (VALUE)val);
+
+ ibf_dump_write_small_value(dump, key_index);
+ ibf_dump_write_small_value(dump, val_index);
return ST_CONTINUE;
}
@@ -8517,21 +11474,25 @@ static void
ibf_dump_object_hash(struct ibf_dump *dump, VALUE obj)
{
long len = RHASH_SIZE(obj);
- IBF_WV(len);
- if (len > 0) st_foreach(RHASH(obj)->ntbl, ibf_dump_object_hash_i, (st_data_t)dump);
+ ibf_dump_write_small_value(dump, (VALUE)len);
+
+ if (len > 0) rb_hash_foreach(obj, ibf_dump_object_hash_i, (VALUE)dump);
}
static VALUE
ibf_load_object_hash(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- const struct ibf_object_hash *hash = IBF_OBJBODY(struct ibf_object_hash, offset);
- VALUE obj = rb_hash_new_with_size(hash->len);
+ long len = (long)ibf_load_small_value(load, &offset);
+ VALUE obj = rb_hash_new_with_size(len);
int i;
- for (i=0; i<hash->len; i++) {
- VALUE key = ibf_load_object(load, hash->keyval[i*2 ]);
- VALUE val = ibf_load_object(load, hash->keyval[i*2+1]);
- rb_hash_aset(obj, key, val);
+ for (i = 0; i < len; i++) {
+ VALUE key_index = ibf_load_small_value(load, &offset);
+ VALUE val_index = ibf_load_small_value(load, &offset);
+
+ VALUE key = ibf_load_object(load, key_index);
+ VALUE val = ibf_load_object(load, val_index);
+ rb_hash_aset(obj, key, val);
}
rb_hash_rehash(obj);
@@ -8545,19 +11506,22 @@ static void
ibf_dump_object_struct(struct ibf_dump *dump, VALUE obj)
{
if (rb_obj_is_kind_of(obj, rb_cRange)) {
- struct ibf_object_struct_range range;
- VALUE beg, end;
- range.len = 3;
- range.class_index = 0;
+ struct ibf_object_struct_range range;
+ VALUE beg, end;
+ IBF_ZERO(range);
+ range.len = 3;
+ range.class_index = 0;
- rb_range_values(obj, &beg, &end, &range.excl);
- range.beg = (long)ibf_dump_object(dump, beg);
- range.end = (long)ibf_dump_object(dump, end);
+ rb_range_values(obj, &beg, &end, &range.excl);
+ range.beg = (long)ibf_dump_object(dump, beg);
+ range.end = (long)ibf_dump_object(dump, end);
- IBF_WV(range);
+ IBF_W_ALIGN(struct ibf_object_struct_range);
+ IBF_WV(range);
}
else {
- rb_bug("ibf_dump_object_struct: unsupported class");
+ rb_raise(rb_eNotImpError, "ibf_dump_object_struct: unsupported class %"PRIsVALUE,
+ rb_class_name(CLASS_OF(obj)));
}
}
@@ -8580,7 +11544,7 @@ ibf_dump_object_bignum(struct ibf_dump *dump, VALUE obj)
ssize_t slen = BIGNUM_SIGN(obj) > 0 ? len : len * -1;
BDIGIT *d = BIGNUM_DIGITS(obj);
- IBF_WV(slen);
+ (void)IBF_W(&slen, ssize_t, 1);
IBF_WP(d, BDIGIT, len);
}
@@ -8601,32 +11565,34 @@ static void
ibf_dump_object_data(struct ibf_dump *dump, VALUE obj)
{
if (rb_data_is_encoding(obj)) {
- rb_encoding *enc = rb_to_encoding(obj);
- const char *name = rb_enc_name(enc);
- enum ibf_object_data_type type = IBF_OBJECT_DATA_ENCODING;
- long len = strlen(name) + 1;
- IBF_WV(type);
- IBF_WV(len);
- IBF_WP(name, char, strlen(name) + 1);
+ rb_encoding *enc = rb_to_encoding(obj);
+ const char *name = rb_enc_name(enc);
+ long len = strlen(name) + 1;
+ long data[2];
+ data[0] = IBF_OBJECT_DATA_ENCODING;
+ data[1] = len;
+ (void)IBF_W(data, long, 2);
+ IBF_WP(name, char, len);
}
else {
- ibf_dump_object_unsupported(dump, obj);
+ ibf_dump_object_unsupported(dump, obj);
}
}
static VALUE
ibf_load_object_data(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- const enum ibf_object_data_type *typep = IBF_OBJBODY(enum ibf_object_data_type, offset);
- /* const long *lenp = IBF_OBJBODY(long, offset + sizeof(enum ibf_object_data_type)); */
- const char *data = IBF_OBJBODY(char, offset + sizeof(enum ibf_object_data_type) + sizeof(long));
+ const long *body = IBF_OBJBODY(long, offset);
+ const enum ibf_object_data_type type = (enum ibf_object_data_type)body[0];
+ /* const long len = body[1]; */
+ const char *data = (const char *)&body[2];
- switch (*typep) {
+ switch (type) {
case IBF_OBJECT_DATA_ENCODING:
- {
- VALUE encobj = rb_enc_from_encoding(rb_enc_find(data));
- return encobj;
- }
+ {
+ VALUE encobj = rb_enc_from_encoding(rb_enc_find(data));
+ return encobj;
+ }
}
return ibf_load_object_unsupported(load, header, offset);
@@ -8635,11 +11601,11 @@ ibf_load_object_data(const struct ibf_load *load, const struct ibf_object_header
static void
ibf_dump_object_complex_rational(struct ibf_dump *dump, VALUE obj)
{
- long real = (long)ibf_dump_object(dump, RCOMPLEX(obj)->real);
- long imag = (long)ibf_dump_object(dump, RCOMPLEX(obj)->imag);
+ long data[2];
+ data[0] = (long)ibf_dump_object(dump, RCOMPLEX(obj)->real);
+ data[1] = (long)ibf_dump_object(dump, RCOMPLEX(obj)->imag);
- IBF_WV(real);
- IBF_WV(imag);
+ (void)IBF_W(data, long, 2);
}
static VALUE
@@ -8660,16 +11626,16 @@ static void
ibf_dump_object_symbol(struct ibf_dump *dump, VALUE obj)
{
VALUE str = rb_sym2str(obj);
- long str_index = (long)ibf_dump_object(dump, str);
- IBF_WV(str_index);
+ VALUE str_index = ibf_dump_object(dump, str);
+
+ ibf_dump_write_small_value(dump, str_index);
}
static VALUE
ibf_load_object_symbol(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
- /* const struct ibf_object_header *header = IBF_OBJHEADER(offset); */
- const struct ibf_object_symbol *symbol = IBF_OBJBODY(struct ibf_object_symbol, offset);
- VALUE str = ibf_load_object(load, symbol->str);
+ VALUE str_index = ibf_load_small_value(load, &offset);
+ VALUE str = ibf_load_object(load, str_index);
ID id = rb_intern_str(str);
return ID2SYM(id);
}
@@ -8707,41 +11673,67 @@ static ibf_dump_object_function dump_object_functions[RUBY_T_MASK+1] = {
ibf_dump_object_unsupported, /* T_ICLASS 0x1c */
ibf_dump_object_unsupported, /* T_ZOMBIE 0x1d */
ibf_dump_object_unsupported, /* 0x1e */
- ibf_dump_object_unsupported /* 0x1f */
+ ibf_dump_object_unsupported, /* 0x1f */
};
+static void
+ibf_dump_object_object_header(struct ibf_dump *dump, const struct ibf_object_header header)
+{
+ unsigned char byte =
+ (header.type << 0) |
+ (header.special_const << 5) |
+ (header.frozen << 6) |
+ (header.internal << 7);
+
+ IBF_WV(byte);
+}
+
+static struct ibf_object_header
+ibf_load_object_object_header(const struct ibf_load *load, ibf_offset_t *offset)
+{
+ unsigned char byte = ibf_load_byte(load, offset);
+
+ struct ibf_object_header header;
+ header.type = (byte >> 0) & 0x1f;
+ header.special_const = (byte >> 5) & 0x01;
+ header.frozen = (byte >> 6) & 0x01;
+ header.internal = (byte >> 7) & 0x01;
+
+ return header;
+}
+
static ibf_offset_t
-lbf_dump_object_object(struct ibf_dump *dump, VALUE obj)
+ibf_dump_object_object(struct ibf_dump *dump, VALUE obj)
{
struct ibf_object_header obj_header;
- ibf_offset_t current_offset = ibf_dump_pos(dump);
+ ibf_offset_t current_offset;
+ IBF_ZERO(obj_header);
obj_header.type = TYPE(obj);
- if (SPECIAL_CONST_P(obj)) {
- if (RB_TYPE_P(obj, T_SYMBOL) ||
- RB_TYPE_P(obj, T_FLOAT)) {
- obj_header.internal = FALSE;
- goto dump_object;
- }
- obj_header.special_const = TRUE;
- obj_header.frozen = TRUE;
- obj_header.internal = TRUE;
- IBF_WV(obj_header);
- IBF_WV(obj);
+ IBF_W_ALIGN(ibf_offset_t);
+ current_offset = ibf_dump_pos(dump);
+
+ if (SPECIAL_CONST_P(obj) &&
+ ! (RB_TYPE_P(obj, T_SYMBOL) ||
+ RB_TYPE_P(obj, T_FLOAT))) {
+ obj_header.special_const = TRUE;
+ obj_header.frozen = TRUE;
+ obj_header.internal = TRUE;
+ ibf_dump_object_object_header(dump, obj_header);
+ ibf_dump_write_small_value(dump, obj);
}
else {
- obj_header.internal = (RBASIC_CLASS(obj) == 0) ? TRUE : FALSE;
- dump_object:
- obj_header.special_const = FALSE;
- obj_header.frozen = FL_TEST(obj, FL_FREEZE) ? TRUE : FALSE;
- IBF_WV(obj_header);
- (*dump_object_functions[obj_header.type])(dump, obj);
+ obj_header.internal = SPECIAL_CONST_P(obj) ? FALSE : (RBASIC_CLASS(obj) == 0) ? TRUE : FALSE;
+ obj_header.special_const = FALSE;
+ obj_header.frozen = FL_TEST(obj, FL_FREEZE) ? TRUE : FALSE;
+ ibf_dump_object_object_header(dump, obj_header);
+ (*dump_object_functions[obj_header.type])(dump, obj);
}
return current_offset;
}
-typedef VALUE (*ibf_load_object_function)(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t);
+typedef VALUE (*ibf_load_object_function)(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset);
static ibf_load_object_function load_object_functions[RUBY_T_MASK+1] = {
ibf_load_object_unsupported, /* T_NONE */
ibf_load_object_unsupported, /* T_OBJECT */
@@ -8774,82 +11766,116 @@ static ibf_load_object_function load_object_functions[RUBY_T_MASK+1] = {
ibf_load_object_unsupported, /* T_ICLASS 0x1c */
ibf_load_object_unsupported, /* T_ZOMBIE 0x1d */
ibf_load_object_unsupported, /* 0x1e */
- ibf_load_object_unsupported /* 0x1f */
+ ibf_load_object_unsupported, /* 0x1f */
};
static VALUE
ibf_load_object(const struct ibf_load *load, VALUE object_index)
{
if (object_index == 0) {
- return Qnil;
- }
- else if (object_index >= load->header->object_list_size) {
- rb_raise(rb_eIndexError, "object index out of range: %"PRIdVALUE, object_index);
+ return Qnil;
}
else {
- VALUE obj = rb_ary_entry(load->obj_list, (long)object_index);
- if (obj == Qnil) { /* TODO: avoid multiple Qnil load */
- ibf_offset_t *offsets = (ibf_offset_t *)(load->header->object_list_offset + load->buff);
- ibf_offset_t offset = offsets[object_index];
- const struct ibf_object_header *header = IBF_OBJHEADER(offset);
+ VALUE obj = pinned_list_fetch(load->current_buffer->obj_list, (long)object_index);
+ if (!obj) {
+ ibf_offset_t *offsets = (ibf_offset_t *)(load->current_buffer->obj_list_offset + load->current_buffer->buff);
+ ibf_offset_t offset = offsets[object_index];
+ const struct ibf_object_header header = ibf_load_object_object_header(load, &offset);
+
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_object: list=%#x offsets=%p offset=%#x\n",
+ load->current_buffer->obj_list_offset, (void *)offsets, offset);
+ fprintf(stderr, "ibf_load_object: type=%#x special=%d frozen=%d internal=%d\n",
+ header.type, header.special_const, header.frozen, header.internal);
+#endif
+ if (offset >= load->current_buffer->size) {
+ rb_raise(rb_eIndexError, "object offset out of range: %u", offset);
+ }
+
+ if (header.special_const) {
+ ibf_offset_t reading_pos = offset;
+
+ obj = ibf_load_small_value(load, &reading_pos);
+ }
+ else {
+ obj = (*load_object_functions[header.type])(load, &header, offset);
+ }
+
+ pinned_list_store(load->current_buffer->obj_list, (long)object_index, obj);
+ }
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_object: index=%#"PRIxVALUE" obj=%#"PRIxVALUE"\n",
+ object_index, obj);
+#endif
+ return obj;
+ }
+}
- if (header->special_const) {
- VALUE *vp = IBF_OBJBODY(VALUE, offset);
- obj = *vp;
- }
- else {
- obj = (*load_object_functions[header->type])(load, header, offset);
- }
+struct ibf_dump_object_list_arg
+{
+ struct ibf_dump *dump;
+ VALUE offset_list;
+};
- rb_ary_store(load->obj_list, (long)object_index, obj);
- }
- iseq_add_mark_object(load->iseq, obj);
- return obj;
- }
+static int
+ibf_dump_object_list_i(st_data_t key, st_data_t val, st_data_t ptr)
+{
+ VALUE obj = (VALUE)key;
+ struct ibf_dump_object_list_arg *args = (struct ibf_dump_object_list_arg *)ptr;
+
+ ibf_offset_t offset = ibf_dump_object_object(args->dump, obj);
+ rb_ary_push(args->offset_list, UINT2NUM(offset));
+
+ return ST_CONTINUE;
}
static void
-ibf_dump_object_list(struct ibf_dump *dump, struct ibf_header *header)
+ibf_dump_object_list(struct ibf_dump *dump, ibf_offset_t *obj_list_offset, unsigned int *obj_list_size)
{
- VALUE list = rb_ary_tmp_new(RARRAY_LEN(dump->obj_list));
- int i, size;
+ st_table *obj_table = dump->current_buffer->obj_table;
+ VALUE offset_list = rb_ary_tmp_new(obj_table->num_entries);
- for (i=0; i<RARRAY_LEN(dump->obj_list); i++) {
- VALUE obj = RARRAY_AREF(dump->obj_list, i);
- ibf_offset_t offset = lbf_dump_object_object(dump, obj);
- rb_ary_push(list, UINT2NUM(offset));
- }
- size = i;
- header->object_list_offset = ibf_dump_pos(dump);
+ struct ibf_dump_object_list_arg args;
+ args.dump = dump;
+ args.offset_list = offset_list;
+
+ st_foreach(obj_table, ibf_dump_object_list_i, (st_data_t)&args);
+
+ IBF_W_ALIGN(ibf_offset_t);
+ *obj_list_offset = ibf_dump_pos(dump);
+
+ st_index_t size = obj_table->num_entries;
+ st_index_t i;
for (i=0; i<size; i++) {
- ibf_offset_t offset = NUM2UINT(RARRAY_AREF(list, i));
- IBF_WV(offset);
+ ibf_offset_t offset = NUM2UINT(RARRAY_AREF(offset_list, i));
+ IBF_WV(offset);
}
- header->object_list_size = size;
+ *obj_list_size = (unsigned int)size;
}
static void
ibf_dump_mark(void *ptr)
{
struct ibf_dump *dump = (struct ibf_dump *)ptr;
- rb_gc_mark(dump->str);
- rb_gc_mark(dump->iseq_list);
- rb_gc_mark(dump->obj_list);
+ rb_gc_mark(dump->global_buffer.str);
+
+ rb_mark_set(dump->global_buffer.obj_table);
+ rb_mark_set(dump->iseq_table);
}
static void
ibf_dump_free(void *ptr)
{
struct ibf_dump *dump = (struct ibf_dump *)ptr;
- if (dump->iseq_table) {
- st_free_table(dump->iseq_table);
- dump->iseq_table = 0;
+ if (dump->global_buffer.obj_table) {
+ st_free_table(dump->global_buffer.obj_table);
+ dump->global_buffer.obj_table = 0;
}
- if (dump->id_table) {
- st_free_table(dump->id_table);
- dump->id_table = 0;
+ if (dump->iseq_table) {
+ st_free_table(dump->iseq_table);
+ dump->iseq_table = 0;
}
ruby_xfree(dump);
}
@@ -8860,7 +11886,7 @@ ibf_dump_memsize(const void *ptr)
struct ibf_dump *dump = (struct ibf_dump *)ptr;
size_t size = sizeof(*dump);
if (dump->iseq_table) size += st_memsize(dump->iseq_table);
- if (dump->id_table) size += st_memsize(dump->id_table);
+ if (dump->global_buffer.obj_table) size += st_memsize(dump->global_buffer.obj_table);
return size;
}
@@ -8873,18 +11899,18 @@ static const rb_data_type_t ibf_dump_type = {
static void
ibf_dump_setup(struct ibf_dump *dump, VALUE dumper_obj)
{
- RB_OBJ_WRITE(dumper_obj, &dump->str, rb_str_new(0, 0));
- RB_OBJ_WRITE(dumper_obj, &dump->iseq_list, rb_ary_tmp_new(0));
- RB_OBJ_WRITE(dumper_obj, &dump->obj_list, rb_ary_tmp_new(1));
- rb_ary_push(dump->obj_list, Qnil); /* 0th is nil */
+ dump->global_buffer.obj_table = NULL; // GC may run before a value is assigned
+ dump->iseq_table = NULL;
+
+ RB_OBJ_WRITE(dumper_obj, &dump->global_buffer.str, rb_str_new(0, 0));
+ dump->global_buffer.obj_table = ibf_dump_object_table_new();
dump->iseq_table = st_init_numtable(); /* need free */
- dump->id_table = st_init_numtable(); /* need free */
- ibf_table_index(dump->id_table, 0); /* id_index:0 is 0 */
+ dump->current_buffer = &dump->global_buffer;
}
VALUE
-iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
+rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
{
struct ibf_dump *dump;
struct ibf_header header = {{0}};
@@ -8892,11 +11918,11 @@ iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
VALUE str;
if (iseq->body->parent_iseq != NULL ||
- iseq->body->local_iseq != iseq) {
- rb_raise(rb_eRuntimeError, "should be top of iseq");
+ iseq->body->local_iseq != iseq) {
+ rb_raise(rb_eRuntimeError, "should be top of iseq");
}
if (RTEST(ISEQ_COVERAGE(iseq))) {
- rb_raise(rb_eRuntimeError, "should not compile with coverage");
+ rb_raise(rb_eRuntimeError, "should not compile with coverage");
}
dump_obj = TypedData_Make_Struct(0, struct ibf_dump, &ibf_dump_type, dump);
@@ -8910,26 +11936,25 @@ iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
header.magic[1] = 'A';
header.magic[2] = 'R';
header.magic[3] = 'B';
- header.major_version = ISEQ_MAJOR_VERSION;
- header.minor_version = ISEQ_MINOR_VERSION;
+ header.major_version = IBF_MAJOR_VERSION;
+ header.minor_version = IBF_MINOR_VERSION;
ibf_dump_iseq_list(dump, &header);
- ibf_dump_id_list(dump, &header);
- ibf_dump_object_list(dump, &header);
+ ibf_dump_object_list(dump, &header.global_object_list_offset, &header.global_object_list_size);
header.size = ibf_dump_pos(dump);
if (RTEST(opt)) {
- VALUE opt_str = opt;
- const char *ptr = StringValuePtr(opt_str);
- header.extra_size = RSTRING_LENINT(opt_str);
- ibf_dump_write(dump, ptr, header.extra_size);
+ VALUE opt_str = opt;
+ const char *ptr = StringValuePtr(opt_str);
+ header.extra_size = RSTRING_LENINT(opt_str);
+ ibf_dump_write(dump, ptr, header.extra_size);
}
else {
- header.extra_size = 0;
+ header.extra_size = 0;
}
ibf_dump_overwrite(dump, &header, sizeof(header), 0);
- str = dump->str;
+ str = dump->global_buffer.str;
ibf_dump_free(dump);
DATA_PTR(dump_obj) = NULL;
RB_GC_GUARD(dump_obj);
@@ -8939,26 +11964,33 @@ iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
static const ibf_offset_t *
ibf_iseq_list(const struct ibf_load *load)
{
- return (ibf_offset_t *)(load->buff + load->header->iseq_list_offset);
+ return (const ibf_offset_t *)(load->global_buffer.buff + load->header->iseq_list_offset);
}
void
-ibf_load_iseq_complete(rb_iseq_t *iseq)
+rb_ibf_load_iseq_complete(rb_iseq_t *iseq)
{
struct ibf_load *load = RTYPEDDATA_DATA(iseq->aux.loader.obj);
rb_iseq_t *prev_src_iseq = load->iseq;
+ ibf_offset_t offset = ibf_iseq_list(load)[iseq->aux.loader.index];
load->iseq = iseq;
- ibf_load_iseq_each(load, iseq, ibf_iseq_list(load)[iseq->aux.loader.index]);
- ISEQ_COMPILE_DATA(iseq) = NULL;
- FL_UNSET(iseq, ISEQ_NOT_LOADED_YET);
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "rb_ibf_load_iseq_complete: index=%#x offset=%#x size=%#x\n",
+ iseq->aux.loader.index, offset,
+ load->header->size);
+#endif
+ ibf_load_iseq_each(load, iseq, offset);
+ ISEQ_COMPILE_DATA_CLEAR(iseq);
+ FL_UNSET((VALUE)iseq, ISEQ_NOT_LOADED_YET);
+ rb_iseq_init_trace(iseq);
load->iseq = prev_src_iseq;
}
#if USE_LAZY_LOAD
-const rb_iseq_t *
+MJIT_FUNC_EXPORTED const rb_iseq_t *
rb_iseq_complete(const rb_iseq_t *iseq)
{
- ibf_load_iseq_complete((rb_iseq_t *)iseq);
+ rb_ibf_load_iseq_complete((rb_iseq_t *)iseq);
return iseq;
}
#endif
@@ -8968,65 +12000,108 @@ ibf_load_iseq(const struct ibf_load *load, const rb_iseq_t *index_iseq)
{
int iseq_index = (int)(VALUE)index_iseq;
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_iseq: index_iseq=%p iseq_list=%p\n",
+ (void *)index_iseq, (void *)load->iseq_list);
+#endif
if (iseq_index == -1) {
return NULL;
}
else {
- VALUE iseqv = rb_ary_entry(load->iseq_list, iseq_index);
+ VALUE iseqv = pinned_list_fetch(load->iseq_list, iseq_index);
- if (iseqv != Qnil) {
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_iseq: iseqv=%p\n", (void *)iseqv);
+#endif
+ if (iseqv) {
return (rb_iseq_t *)iseqv;
}
else {
rb_iseq_t *iseq = iseq_imemo_alloc();
- FL_SET(iseq, ISEQ_NOT_LOADED_YET);
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_iseq: new iseq=%p\n", (void *)iseq);
+#endif
+ FL_SET((VALUE)iseq, ISEQ_NOT_LOADED_YET);
iseq->aux.loader.obj = load->loader_obj;
iseq->aux.loader.index = iseq_index;
- rb_ary_store(load->iseq_list, iseq_index, (VALUE)iseq);
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_iseq: iseq=%p loader_obj=%p index=%d\n",
+ (void *)iseq, (void *)load->loader_obj, iseq_index);
+#endif
+ pinned_list_store(load->iseq_list, iseq_index, (VALUE)iseq);
#if !USE_LAZY_LOAD
- ibf_load_iseq_complete(iseq);
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_iseq: loading iseq=%p\n", (void *)iseq);
+#endif
+ rb_ibf_load_iseq_complete(iseq);
+#else
+ if (GET_VM()->builtin_function_table) {
+ rb_ibf_load_iseq_complete(iseq);
+ }
#endif /* !USE_LAZY_LOAD */
- if (load->iseq) {
- iseq_add_mark_object(load->iseq, (VALUE)iseq);
- }
+#if IBF_ISEQ_DEBUG
+ fprintf(stderr, "ibf_load_iseq: iseq=%p loaded %p\n",
+ (void *)iseq, (void *)load->iseq);
+#endif
return iseq;
}
}
}
static void
-ibf_load_setup(struct ibf_load *load, VALUE loader_obj, VALUE str)
+ibf_load_setup_bytes(struct ibf_load *load, VALUE loader_obj, const char *bytes, size_t size)
{
- rb_check_safe_obj(str);
-
- if (RSTRING_LENINT(str) < (int)sizeof(struct ibf_header)) {
- rb_raise(rb_eRuntimeError, "broken binary format");
- }
- RB_OBJ_WRITE(loader_obj, &load->str, str);
load->loader_obj = loader_obj;
- load->buff = StringValuePtr(str);
- load->header = (struct ibf_header *)load->buff;
- RB_OBJ_WRITE(loader_obj, &load->iseq_list, rb_ary_tmp_new(0));
- RB_OBJ_WRITE(loader_obj, &load->obj_list, rb_ary_tmp_new(0));
- load->id_list = ZALLOC_N(ID, load->header->id_list_size);
+ load->global_buffer.buff = bytes;
+ load->header = (struct ibf_header *)load->global_buffer.buff;
+ load->global_buffer.size = load->header->size;
+ load->global_buffer.obj_list_offset = load->header->global_object_list_offset;
+ load->global_buffer.obj_list_size = load->header->global_object_list_size;
+ RB_OBJ_WRITE(loader_obj, &load->iseq_list, pinned_list_new(load->header->iseq_list_size));
+ RB_OBJ_WRITE(loader_obj, &load->global_buffer.obj_list, pinned_list_new(load->global_buffer.obj_list_size));
load->iseq = NULL;
- if (RSTRING_LENINT(str) < (int)load->header->size) {
+ load->current_buffer = &load->global_buffer;
+
+ if (size < load->header->size) {
rb_raise(rb_eRuntimeError, "broken binary format");
}
if (strncmp(load->header->magic, "YARB", 4) != 0) {
rb_raise(rb_eRuntimeError, "unknown binary format");
}
- if (load->header->major_version != ISEQ_MAJOR_VERSION ||
- load->header->minor_version != ISEQ_MINOR_VERSION) {
+ if (load->header->major_version != IBF_MAJOR_VERSION ||
+ load->header->minor_version != IBF_MINOR_VERSION) {
rb_raise(rb_eRuntimeError, "unmatched version file (%u.%u for %u.%u)",
- load->header->major_version, load->header->minor_version, ISEQ_MAJOR_VERSION, ISEQ_MINOR_VERSION);
+ load->header->major_version, load->header->minor_version, IBF_MAJOR_VERSION, IBF_MINOR_VERSION);
}
- if (strcmp(load->buff + sizeof(struct ibf_header), RUBY_PLATFORM) != 0) {
+ if (strcmp(load->global_buffer.buff + sizeof(struct ibf_header), RUBY_PLATFORM) != 0) {
rb_raise(rb_eRuntimeError, "unmatched platform");
}
+ if (load->header->iseq_list_offset % RUBY_ALIGNOF(ibf_offset_t)) {
+ rb_raise(rb_eArgError, "unaligned iseq list offset: %u",
+ load->header->iseq_list_offset);
+ }
+ if (load->global_buffer.obj_list_offset % RUBY_ALIGNOF(ibf_offset_t)) {
+ rb_raise(rb_eArgError, "unaligned object list offset: %u",
+ load->global_buffer.obj_list_offset);
+ }
+}
+
+static void
+ibf_load_setup(struct ibf_load *load, VALUE loader_obj, VALUE str)
+{
+ if (RSTRING_LENINT(str) < (int)sizeof(struct ibf_header)) {
+ rb_raise(rb_eRuntimeError, "broken binary format");
+ }
+
+#if USE_LAZY_LOAD
+ str = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
+#endif
+
+ ibf_load_setup_bytes(load, loader_obj, StringValuePtr(str), RSTRING_LEN(str));
+ RB_OBJ_WRITE(loader_obj, &load->str, str);
}
static void
@@ -9035,22 +12110,20 @@ ibf_loader_mark(void *ptr)
struct ibf_load *load = (struct ibf_load *)ptr;
rb_gc_mark(load->str);
rb_gc_mark(load->iseq_list);
- rb_gc_mark(load->obj_list);
+ rb_gc_mark(load->global_buffer.obj_list);
}
static void
ibf_loader_free(void *ptr)
{
struct ibf_load *load = (struct ibf_load *)ptr;
- ruby_xfree(load->id_list);
ruby_xfree(load);
}
static size_t
ibf_loader_memsize(const void *ptr)
{
- struct ibf_load *load = (struct ibf_load *)ptr;
- return sizeof(struct ibf_load) + load->header->id_list_size * sizeof(ID);
+ return sizeof(struct ibf_load);
}
static const rb_data_type_t ibf_load_type = {
@@ -9060,10 +12133,10 @@ static const rb_data_type_t ibf_load_type = {
};
const rb_iseq_t *
-iseq_ibf_load(VALUE str)
+rb_iseq_ibf_load(VALUE str)
{
struct ibf_load *load;
- const rb_iseq_t *iseq;
+ rb_iseq_t *iseq;
VALUE loader_obj = TypedData_Make_Struct(0, struct ibf_load, &ibf_load_type, load);
ibf_load_setup(load, loader_obj, str);
@@ -9073,15 +12146,29 @@ iseq_ibf_load(VALUE str)
return iseq;
}
+const rb_iseq_t *
+rb_iseq_ibf_load_bytes(const char *bytes, size_t size)
+{
+ struct ibf_load *load;
+ rb_iseq_t *iseq;
+ VALUE loader_obj = TypedData_Make_Struct(0, struct ibf_load, &ibf_load_type, load);
+
+ ibf_load_setup_bytes(load, loader_obj, bytes, size);
+ iseq = ibf_load_iseq(load, 0);
+
+ RB_GC_GUARD(loader_obj);
+ return iseq;
+}
+
VALUE
-iseq_ibf_load_extra_data(VALUE str)
+rb_iseq_ibf_load_extra_data(VALUE str)
{
struct ibf_load *load;
VALUE loader_obj = TypedData_Make_Struct(0, struct ibf_load, &ibf_load_type, load);
VALUE extra_str;
ibf_load_setup(load, loader_obj, str);
- extra_str = rb_str_new(load->buff + load->header->size, load->header->extra_size);
+ extra_str = rb_str_new(load->global_buffer.buff + load->header->size, load->header->extra_size);
RB_GC_GUARD(loader_obj);
return extra_str;
}
diff --git a/complex.c b/complex.c
index 5d84106441..27c1f131e3 100644
--- a/complex.c
+++ b/complex.c
@@ -5,21 +5,37 @@
which is written in ruby.
*/
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
+
#if defined _MSC_VER
/* Microsoft Visual C does not define M_PI and others by default */
# define _USE_MATH_DEFINES 1
#endif
+
+#include <ctype.h>
#include <math.h>
-#include "internal.h"
+#undef NDEBUG
#define NDEBUG
+#include "id.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/class.h"
+#include "internal/complex.h"
+#include "internal/math.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/rational.h"
#include "ruby_assert.h"
#define ZERO INT2FIX(0)
#define ONE INT2FIX(1)
#define TWO INT2FIX(2)
+#if USE_FLONUM
#define RFLOAT_0 DBL2NUM(0)
+#else
+static VALUE RFLOAT_0;
+#endif
#if defined(HAVE_SIGNBIT) && defined(__GNUC__) && defined(__sun) && \
!defined(signbit)
extern int signbit(double);
@@ -27,26 +43,21 @@ extern int signbit(double);
VALUE rb_cComplex;
-static VALUE nucomp_abs(VALUE self);
-static VALUE nucomp_arg(VALUE self);
-
static ID id_abs, id_arg,
- id_denominator, id_expt, id_fdiv,
- id_negate, id_numerator, id_quo,
- id_real_p, id_to_f, id_to_i, id_to_r,
- id_i_real, id_i_imag,
+ id_denominator, id_numerator,
+ id_real_p, id_i_real, id_i_imag,
id_finite_p, id_infinite_p, id_rationalize,
id_PI;
+#define id_to_i idTo_i
+#define id_to_r idTo_r
+#define id_negate idUMinus
+#define id_expt idPow
+#define id_to_f idTo_f
+#define id_quo idQuo
+#define id_fdiv idFdiv
#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
-#define binop(n,op) \
-inline static VALUE \
-f_##n(VALUE x, VALUE y)\
-{\
- return rb_funcall(x, (op), 1, y);\
-}
-
#define fun1(n) \
inline static VALUE \
f_##n(VALUE x)\
@@ -61,31 +72,32 @@ f_##n(VALUE x, VALUE y)\
return rb_funcall(x, id_##n, 1, y);\
}
-#define math1(n) \
-inline static VALUE \
-m_##n(VALUE x)\
-{\
- return rb_funcall(rb_mMath, id_##n, 1, x);\
-}
-
-#define math2(n) \
-inline static VALUE \
-m_##n(VALUE x, VALUE y)\
-{\
- return rb_funcall(rb_mMath, id_##n, 2, x, y);\
-}
-
#define PRESERVE_SIGNEDZERO
inline static VALUE
f_add(VALUE x, VALUE y)
{
-#ifndef PRESERVE_SIGNEDZERO
- if (FIXNUM_P(y) && FIXNUM_ZERO_P(y))
- return x;
- else if (FIXNUM_P(x) && FIXNUM_ZERO_P(x))
- return y;
-#endif
+ if (RB_INTEGER_TYPE_P(x) &&
+ LIKELY(rb_method_basic_definition_p(rb_cInteger, idPLUS))) {
+ if (FIXNUM_ZERO_P(x))
+ return y;
+ if (FIXNUM_ZERO_P(y))
+ return x;
+ return rb_int_plus(x, y);
+ }
+ else if (RB_FLOAT_TYPE_P(x) &&
+ LIKELY(rb_method_basic_definition_p(rb_cFloat, idPLUS))) {
+ if (FIXNUM_ZERO_P(y))
+ return x;
+ return rb_float_plus(x, y);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL) &&
+ LIKELY(rb_method_basic_definition_p(rb_cRational, idPLUS))) {
+ if (FIXNUM_ZERO_P(y))
+ return x;
+ return rb_rational_plus(x, y);
+ }
+
return rb_funcall(x, '+', 1, y);
}
@@ -117,44 +129,104 @@ f_gt_p(VALUE x, VALUE y)
inline static VALUE
f_mul(VALUE x, VALUE y)
{
-#ifndef PRESERVE_SIGNEDZERO
- if (FIXNUM_P(y)) {
- long iy = FIX2LONG(y);
- if (iy == 0) {
- if (RB_INTEGER_TYPE_P(x))
- return ZERO;
- }
- else if (iy == 1)
- return x;
- }
- else if (FIXNUM_P(x)) {
- long ix = FIX2LONG(x);
- if (ix == 0) {
- if (RB_INTEGER_TYPE_P(y))
- return ZERO;
- }
- else if (ix == 1)
- return y;
+ if (RB_INTEGER_TYPE_P(x) &&
+ LIKELY(rb_method_basic_definition_p(rb_cInteger, idMULT))) {
+ if (FIXNUM_ZERO_P(y))
+ return ZERO;
+ if (FIXNUM_ZERO_P(x) && RB_INTEGER_TYPE_P(y))
+ return ZERO;
+ if (x == ONE) return y;
+ if (y == ONE) return x;
+ return rb_int_mul(x, y);
+ }
+ else if (RB_FLOAT_TYPE_P(x) &&
+ LIKELY(rb_method_basic_definition_p(rb_cFloat, idMULT))) {
+ if (y == ONE) return x;
+ return rb_float_mul(x, y);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL) &&
+ LIKELY(rb_method_basic_definition_p(rb_cRational, idMULT))) {
+ if (y == ONE) return x;
+ return rb_rational_mul(x, y);
+ }
+ else if (LIKELY(rb_method_basic_definition_p(CLASS_OF(x), idMULT))) {
+ if (y == ONE) return x;
}
-#endif
return rb_funcall(x, '*', 1, y);
}
inline static VALUE
f_sub(VALUE x, VALUE y)
{
-#ifndef PRESERVE_SIGNEDZERO
- if (FIXNUM_P(y) && FIXNUM_ZERO_P(y))
+ if (FIXNUM_ZERO_P(y) &&
+ LIKELY(rb_method_basic_definition_p(CLASS_OF(x), idMINUS))) {
return x;
-#endif
+ }
return rb_funcall(x, '-', 1, y);
}
-fun1(abs)
-fun1(arg)
-fun1(denominator)
+inline static VALUE
+f_abs(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ return rb_int_abs(x);
+ }
+ else if (RB_FLOAT_TYPE_P(x)) {
+ return rb_float_abs(x);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ return rb_rational_abs(x);
+ }
+ else if (RB_TYPE_P(x, T_COMPLEX)) {
+ return rb_complex_abs(x);
+ }
+ return rb_funcall(x, id_abs, 0);
+}
+
+static VALUE numeric_arg(VALUE self);
+static VALUE float_arg(VALUE self);
+
+inline static VALUE
+f_arg(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ return numeric_arg(x);
+ }
+ else if (RB_FLOAT_TYPE_P(x)) {
+ return float_arg(x);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ return numeric_arg(x);
+ }
+ else if (RB_TYPE_P(x, T_COMPLEX)) {
+ return rb_complex_arg(x);
+ }
+ return rb_funcall(x, id_arg, 0);
+}
-static VALUE nucomp_negate(VALUE self);
+inline static VALUE
+f_numerator(VALUE x)
+{
+ if (RB_TYPE_P(x, T_RATIONAL)) {
+ return RRATIONAL(x)->num;
+ }
+ if (RB_FLOAT_TYPE_P(x)) {
+ return rb_float_numerator(x);
+ }
+ return x;
+}
+
+inline static VALUE
+f_denominator(VALUE x)
+{
+ if (RB_TYPE_P(x, T_RATIONAL)) {
+ return RRATIONAL(x)->den;
+ }
+ if (RB_FLOAT_TYPE_P(x)) {
+ return rb_float_denominator(x);
+ }
+ return INT2FIX(1);
+}
inline static VALUE
f_negate(VALUE x)
@@ -169,13 +241,30 @@ f_negate(VALUE x)
return rb_rational_uminus(x);
}
else if (RB_TYPE_P(x, T_COMPLEX)) {
- return nucomp_negate(x);
+ return rb_complex_uminus(x);
}
return rb_funcall(x, id_negate, 0);
}
-fun1(numerator)
-fun1(real_p)
+static bool nucomp_real_p(VALUE self);
+
+static inline bool
+f_real_p(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ return true;
+ }
+ else if (RB_FLOAT_TYPE_P(x)) {
+ return true;
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ return true;
+ }
+ else if (RB_TYPE_P(x, T_COMPLEX)) {
+ return nucomp_real_p(x);
+ }
+ return rb_funcall(x, id_real_p, 0);
+}
inline static VALUE
f_to_i(VALUE x)
@@ -184,6 +273,7 @@ f_to_i(VALUE x)
return rb_str_to_inum(x, 10, 0);
return rb_funcall(x, id_to_i, 0);
}
+
inline static VALUE
f_to_f(VALUE x)
{
@@ -206,7 +296,19 @@ f_eqeq_p(VALUE x, VALUE y)
fun2(expt)
fun2(fdiv)
-fun2(quo)
+
+static VALUE
+f_quo(VALUE x, VALUE y)
+{
+ if (RB_INTEGER_TYPE_P(x))
+ return rb_numeric_quo(x, y);
+ if (RB_FLOAT_TYPE_P(x))
+ return rb_float_div(x, y);
+ if (RB_TYPE_P(x, T_RATIONAL))
+ return rb_numeric_quo(x, y);
+
+ return rb_funcallv(x, id_quo, 1, &y);
+}
inline static int
f_negative_p(VALUE x)
@@ -225,7 +327,10 @@ f_negative_p(VALUE x)
inline static int
f_zero_p(VALUE x)
{
- if (RB_INTEGER_TYPE_P(x)) {
+ if (RB_FLOAT_TYPE_P(x)) {
+ return FLOAT_ZERO_P(x);
+ }
+ else if (RB_INTEGER_TYPE_P(x)) {
return FIXNUM_ZERO_P(x);
}
else if (RB_TYPE_P(x, T_RATIONAL)) {
@@ -298,6 +403,7 @@ nucomp_s_new_internal(VALUE klass, VALUE real, VALUE imag)
RCOMPLEX_SET_REAL(obj, real);
RCOMPLEX_SET_IMAG(obj, imag);
+ OBJ_FREEZE_RAW((VALUE)obj);
return (VALUE)obj;
}
@@ -308,30 +414,6 @@ nucomp_s_alloc(VALUE klass)
return nucomp_s_new_internal(klass, ZERO, ZERO);
}
-#if 0
-static VALUE
-nucomp_s_new_bang(int argc, VALUE *argv, VALUE klass)
-{
- VALUE real, imag;
-
- switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
- case 1:
- if (!k_numeric_p(real))
- real = f_to_i(real);
- imag = ZERO;
- break;
- default:
- if (!k_numeric_p(real))
- real = f_to_i(real);
- if (!k_numeric_p(imag))
- imag = f_to_i(imag);
- break;
- }
-
- return nucomp_s_new_internal(klass, real, imag);
-}
-#endif
-
inline static VALUE
f_complex_new_bang1(VALUE klass, VALUE x)
{
@@ -347,22 +429,6 @@ f_complex_new_bang2(VALUE klass, VALUE x, VALUE y)
return nucomp_s_new_internal(klass, x, y);
}
-#ifdef CANONICALIZATION_FOR_MATHN
-#define CANON
-#endif
-
-#ifdef CANON
-static int canonicalization = 0;
-
-RUBY_FUNC_EXPORTED void
-nucomp_canonicalization(int f)
-{
- canonicalization = f;
-}
-#else
-#define canonicalization 0
-#endif
-
inline static void
nucomp_real_check(VALUE num)
{
@@ -377,26 +443,20 @@ nucomp_real_check(VALUE num)
inline static VALUE
nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag)
{
-#ifdef CANON
-#define CL_CANON
-#ifdef CL_CANON
- if (k_exact_zero_p(imag) && canonicalization)
- return real;
-#else
- if (f_zero_p(imag) && canonicalization)
- return real;
-#endif
-#endif
- if (f_real_p(real) && f_real_p(imag))
+ int complex_r, complex_i;
+ complex_r = RB_TYPE_P(real, T_COMPLEX);
+ complex_i = RB_TYPE_P(imag, T_COMPLEX);
+ if (!complex_r && !complex_i) {
return nucomp_s_new_internal(klass, real, imag);
- else if (f_real_p(real)) {
+ }
+ else if (!complex_r) {
get_dat1(imag);
return nucomp_s_new_internal(klass,
f_sub(real, dat->imag),
f_add(ZERO, dat->real));
}
- else if (f_real_p(imag)) {
+ else if (!complex_i) {
get_dat1(real);
return nucomp_s_new_internal(klass,
@@ -447,11 +507,12 @@ f_complex_new2(VALUE klass, VALUE x, VALUE y)
return nucomp_s_canonicalize_internal(klass, x, y);
}
+static VALUE nucomp_convert(VALUE klass, VALUE a1, VALUE a2, int raise);
static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass);
/*
* call-seq:
- * Complex(x[, y]) -> numeric
+ * Complex(x[, y], exception: true) -> numeric or nil
*
* Returns x+i*y;
*
@@ -460,6 +521,9 @@ static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass);
* Complex(nil) #=> TypeError
* Complex(1, nil) #=> TypeError
*
+ * Complex(1, nil, exception: false) #=> nil
+ * Complex('1+2', exception: false) #=> nil
+ *
* Syntax of string form:
*
* string form = extra spaces , complex , extra spaces ;
@@ -485,7 +549,19 @@ static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass);
static VALUE
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
{
- return nucomp_s_convert(argc, argv, rb_cComplex);
+ VALUE a1, a2, opts = Qnil;
+ int raise = TRUE;
+
+ if (rb_scan_args(argc, argv, "11:", &a1, &a2, &opts) == 1) {
+ a2 = Qundef;
+ }
+ if (!NIL_P(opts)) {
+ raise = rb_opts_exception_p(opts, raise);
+ }
+ if (argc > 0 && CLASS_OF(a1) == rb_cComplex && a2 == Qundef) {
+ return a1;
+ }
+ return nucomp_convert(rb_cComplex, a1, a2, raise);
}
#define imp1(n) \
@@ -511,7 +587,7 @@ imp1(sinh)
static VALUE
m_cos(VALUE x)
{
- if (f_real_p(x))
+ if (!RB_TYPE_P(x, T_COMPLEX))
return m_cos_bang(x);
{
get_dat1(x);
@@ -526,7 +602,7 @@ m_cos(VALUE x)
static VALUE
m_sin(VALUE x)
{
- if (f_real_p(x))
+ if (!RB_TYPE_P(x, T_COMPLEX))
return m_sin_bang(x);
{
get_dat1(x);
@@ -538,50 +614,18 @@ m_sin(VALUE x)
}
}
-#if 0
-imp1(sqrt)
-
-VALUE
-rb_complex_sqrt(VALUE x)
-{
- int pos;
- VALUE a, re, im;
- get_dat1(x);
-
- pos = f_positive_p(dat->imag);
- a = f_abs(x);
- re = m_sqrt_bang(f_div(f_add(a, dat->real), TWO));
- im = m_sqrt_bang(f_div(f_sub(a, dat->real), TWO));
- if (!pos) im = f_negate(im);
- return f_complex_new2(rb_cComplex, re, im);
-}
-
-static VALUE
-m_sqrt(VALUE x)
-{
- if (f_real_p(x)) {
- if (f_positive_p(x))
- return m_sqrt_bang(x);
- return f_complex_new2(rb_cComplex, ZERO, m_sqrt_bang(f_negate(x)));
- }
- return rb_complex_sqrt(x);
-}
-#endif
-
static VALUE
f_complex_polar(VALUE klass, VALUE x, VALUE y)
{
assert(!RB_TYPE_P(x, T_COMPLEX));
assert(!RB_TYPE_P(y, T_COMPLEX));
if (f_zero_p(x) || f_zero_p(y)) {
- if (canonicalization) return x;
return nucomp_s_new_internal(klass, x, RFLOAT_0);
}
if (RB_FLOAT_TYPE_P(y)) {
const double arg = RFLOAT_VALUE(y);
if (arg == M_PI) {
x = f_negate(x);
- if (canonicalization) return x;
y = RFLOAT_0;
}
else if (arg == M_PI_2) {
@@ -596,13 +640,12 @@ f_complex_polar(VALUE klass, VALUE x, VALUE y)
const double abs = RFLOAT_VALUE(x);
const double real = abs * cos(arg), imag = abs * sin(arg);
x = DBL2NUM(real);
- if (canonicalization && imag == 0.0) return x;
y = DBL2NUM(imag);
}
else {
- y = f_mul(x, DBL2NUM(sin(arg)));
- x = f_mul(x, DBL2NUM(cos(arg)));
- if (canonicalization && f_zero_p(y)) return x;
+ const double ax = sin(arg), ay = cos(arg);
+ y = f_mul(x, DBL2NUM(ax));
+ x = f_mul(x, DBL2NUM(ay));
}
return nucomp_s_new_internal(klass, x, y);
}
@@ -611,6 +654,38 @@ f_complex_polar(VALUE klass, VALUE x, VALUE y)
f_mul(x, m_sin(y)));
}
+#ifdef HAVE___COSPI
+# define cospi(x) __cospi(x)
+#else
+# define cospi(x) cos((x) * M_PI)
+#endif
+#ifdef HAVE___SINPI
+# define sinpi(x) __sinpi(x)
+#else
+# define sinpi(x) sin((x) * M_PI)
+#endif
+/* returns a Complex or Float of ang*PI-rotated abs */
+VALUE
+rb_dbl_complex_new_polar_pi(double abs, double ang)
+{
+ double fi;
+ const double fr = modf(ang, &fi);
+ int pos = fr == +0.5;
+
+ if (pos || fr == -0.5) {
+ if ((modf(fi / 2.0, &fi) != fr) ^ pos) abs = -abs;
+ return rb_complex_new(RFLOAT_0, DBL2NUM(abs));
+ }
+ else if (fr == 0.0) {
+ if (modf(fi / 2.0, &fi) != 0.0) abs = -abs;
+ return DBL2NUM(abs);
+ }
+ else {
+ const double real = abs * cospi(ang), imag = abs * sinpi(ang);
+ return rb_complex_new(DBL2NUM(real), DBL2NUM(imag));
+ }
+}
+
/*
* call-seq:
* Complex.polar(abs[, arg]) -> complex
@@ -630,13 +705,20 @@ nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
switch (rb_scan_args(argc, argv, "11", &abs, &arg)) {
case 1:
nucomp_real_check(abs);
- if (canonicalization) return abs;
return nucomp_s_new_internal(klass, abs, ZERO);
default:
nucomp_real_check(abs);
nucomp_real_check(arg);
break;
}
+ if (RB_TYPE_P(abs, T_COMPLEX)) {
+ get_dat1(abs);
+ abs = dat->real;
+ }
+ if (RB_TYPE_P(arg, T_COMPLEX)) {
+ get_dat1(arg);
+ arg = dat->real;
+ }
return f_complex_polar(klass, abs, arg);
}
@@ -649,8 +731,8 @@ nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
* Complex(7).real #=> 7
* Complex(9, -4).real #=> 9
*/
-static VALUE
-nucomp_real(VALUE self)
+VALUE
+rb_complex_real(VALUE self)
{
get_dat1(self);
return dat->real;
@@ -666,8 +748,8 @@ nucomp_real(VALUE self)
* Complex(7).imaginary #=> 0
* Complex(9, -4).imaginary #=> -4
*/
-static VALUE
-nucomp_imag(VALUE self)
+VALUE
+rb_complex_imag(VALUE self)
{
get_dat1(self);
return dat->imag;
@@ -681,12 +763,12 @@ nucomp_imag(VALUE self)
*
* -Complex(1, 2) #=> (-1-2i)
*/
-static VALUE
-nucomp_negate(VALUE self)
+VALUE
+rb_complex_uminus(VALUE self)
{
- get_dat1(self);
- return f_complex_new2(CLASS_OF(self),
- f_negate(dat->real), f_negate(dat->imag));
+ get_dat1(self);
+ return f_complex_new2(CLASS_OF(self),
+ f_negate(dat->real), f_negate(dat->imag));
}
/*
@@ -735,8 +817,8 @@ rb_complex_plus(VALUE self, VALUE other)
* Complex(9, 8) - 4 #=> (5+8i)
* Complex(20, 9) - 9.8 #=> (10.2+9i)
*/
-static VALUE
-nucomp_sub(VALUE self, VALUE other)
+VALUE
+rb_complex_minus(VALUE self, VALUE other)
{
if (RB_TYPE_P(other, T_COMPLEX)) {
VALUE real, imag;
@@ -770,6 +852,19 @@ safe_mul(VALUE a, VALUE b, int az, int bz)
return f_mul(a, b);
}
+static void
+comp_mul(VALUE areal, VALUE aimag, VALUE breal, VALUE bimag, VALUE *real, VALUE *imag)
+{
+ int arzero = f_zero_p(areal);
+ int aizero = f_zero_p(aimag);
+ int brzero = f_zero_p(breal);
+ int bizero = f_zero_p(bimag);
+ *real = f_sub(safe_mul(areal, breal, arzero, brzero),
+ safe_mul(aimag, bimag, aizero, bizero));
+ *imag = f_add(safe_mul(areal, bimag, arzero, bizero),
+ safe_mul(aimag, breal, aizero, brzero));
+}
+
/*
* call-seq:
* cmp * numeric -> complex
@@ -787,19 +882,9 @@ rb_complex_mul(VALUE self, VALUE other)
{
if (RB_TYPE_P(other, T_COMPLEX)) {
VALUE real, imag;
- VALUE areal, aimag, breal, bimag;
- int arzero, aizero, brzero, bizero;
-
get_dat2(self, other);
- arzero = f_zero_p(areal = adat->real);
- aizero = f_zero_p(aimag = adat->imag);
- brzero = f_zero_p(breal = bdat->real);
- bizero = f_zero_p(bimag = bdat->imag);
- real = f_sub(safe_mul(areal, breal, arzero, brzero),
- safe_mul(aimag, bimag, aizero, bizero));
- imag = f_add(safe_mul(areal, bimag, arzero, bizero),
- safe_mul(aimag, breal, aizero, brzero));
+ comp_mul(adat->real, adat->imag, bdat->real, bdat->imag, &real, &imag);
return f_complex_new2(CLASS_OF(self), real, imag);
}
@@ -812,13 +897,13 @@ rb_complex_mul(VALUE self, VALUE other)
}
return rb_num_coerce_bin(self, other, '*');
}
-#define nucomp_mul rb_complex_mul
inline static VALUE
f_divide(VALUE self, VALUE other,
VALUE (*func)(VALUE, VALUE), ID id)
{
if (RB_TYPE_P(other, T_COMPLEX)) {
+ VALUE r, n, x, y;
int flo;
get_dat2(self, other);
@@ -826,42 +911,29 @@ f_divide(VALUE self, VALUE other,
RB_FLOAT_TYPE_P(bdat->real) || RB_FLOAT_TYPE_P(bdat->imag));
if (f_gt_p(f_abs(bdat->real), f_abs(bdat->imag))) {
- VALUE r, n;
-
r = (*func)(bdat->imag, bdat->real);
n = f_mul(bdat->real, f_add(ONE, f_mul(r, r)));
- if (flo)
- return f_complex_new2(CLASS_OF(self),
- (*func)(self, n),
- (*func)(f_negate(f_mul(self, r)), n));
- return f_complex_new2(CLASS_OF(self),
- (*func)(f_add(adat->real,
- f_mul(adat->imag, r)), n),
- (*func)(f_sub(adat->imag,
- f_mul(adat->real, r)), n));
+ x = (*func)(f_add(adat->real, f_mul(adat->imag, r)), n);
+ y = (*func)(f_sub(adat->imag, f_mul(adat->real, r)), n);
}
else {
- VALUE r, n;
-
r = (*func)(bdat->real, bdat->imag);
n = f_mul(bdat->imag, f_add(ONE, f_mul(r, r)));
- if (flo)
- return f_complex_new2(CLASS_OF(self),
- (*func)(f_mul(self, r), n),
- (*func)(f_negate(self), n));
- return f_complex_new2(CLASS_OF(self),
- (*func)(f_add(f_mul(adat->real, r),
- adat->imag), n),
- (*func)(f_sub(f_mul(adat->imag, r),
- adat->real), n));
+ x = (*func)(f_add(f_mul(adat->real, r), adat->imag), n);
+ y = (*func)(f_sub(f_mul(adat->imag, r), adat->real), n);
}
+ if (!flo) {
+ x = rb_rational_canonicalize(x);
+ y = rb_rational_canonicalize(y);
+ }
+ return f_complex_new2(CLASS_OF(self), x, y);
}
if (k_numeric_p(other) && f_real_p(other)) {
+ VALUE x, y;
get_dat1(self);
-
- return f_complex_new2(CLASS_OF(self),
- (*func)(dat->real, other),
- (*func)(dat->imag, other));
+ x = rb_rational_canonicalize((*func)(dat->real, other));
+ y = rb_rational_canonicalize((*func)(dat->imag, other));
+ return f_complex_new2(CLASS_OF(self), x, y);
}
return rb_num_coerce_bin(self, other, id);
}
@@ -881,13 +953,13 @@ f_divide(VALUE self, VALUE other,
* Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i)
* Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i)
*/
-static VALUE
-nucomp_div(VALUE self, VALUE other)
+VALUE
+rb_complex_div(VALUE self, VALUE other)
{
return f_divide(self, other, f_quo, id_quo);
}
-#define nucomp_quo nucomp_div
+#define nucomp_quo rb_complex_div
/*
* call-seq:
@@ -918,8 +990,8 @@ f_reciprocal(VALUE x)
* Complex('i') ** 2 #=> (-1+0i)
* Complex(-8) ** Rational(1, 3) #=> (1.0000000000000002+1.7320508075688772i)
*/
-static VALUE
-nucomp_expt(VALUE self, VALUE other)
+VALUE
+rb_complex_pow(VALUE self, VALUE other)
{
if (k_numeric_p(other) && k_exact_zero_p(other))
return f_complex_new_bang1(CLASS_OF(self), ONE);
@@ -949,38 +1021,45 @@ nucomp_expt(VALUE self, VALUE other)
return f_complex_polar(CLASS_OF(self), nr, ntheta);
}
if (FIXNUM_P(other)) {
- if (f_gt_p(other, ZERO)) {
- VALUE x, z;
- long n;
-
- x = self;
- z = x;
- n = FIX2LONG(other) - 1;
-
- while (n) {
- long q, r;
-
- while (1) {
- get_dat1(x);
-
- q = n / 2;
- r = n % 2;
-
- if (r)
- break;
-
- x = nucomp_s_new_internal(CLASS_OF(self),
- f_sub(f_mul(dat->real, dat->real),
- f_mul(dat->imag, dat->imag)),
- f_mul(f_mul(TWO, dat->real), dat->imag));
- n = q;
- }
- z = f_mul(z, x);
- n--;
- }
- return z;
+ long n = FIX2LONG(other);
+ if (n == 0) {
+ return nucomp_s_new_internal(CLASS_OF(self), ONE, ZERO);
+ }
+ if (n < 0) {
+ self = f_reciprocal(self);
+ other = rb_int_uminus(other);
+ n = -n;
+ }
+ {
+ get_dat1(self);
+ VALUE xr = dat->real, xi = dat->imag, zr = xr, zi = xi;
+
+ if (f_zero_p(xi)) {
+ zr = rb_num_pow(zr, other);
+ }
+ else if (f_zero_p(xr)) {
+ zi = rb_num_pow(zi, other);
+ if (n & 2) zi = f_negate(zi);
+ if (!(n & 1)) {
+ VALUE tmp = zr;
+ zr = zi;
+ zi = tmp;
+ }
+ }
+ else {
+ while (--n) {
+ long q, r;
+
+ for (; q = n / 2, r = n % 2, r == 0; n = q) {
+ VALUE tmp = f_sub(f_mul(xr, xr), f_mul(xi, xi));
+ xi = f_mul(f_mul(TWO, xr), xi);
+ xr = tmp;
+ }
+ comp_mul(zr, zi, xr, xi, &zr, &zi);
+ }
+ }
+ return nucomp_s_new_internal(CLASS_OF(self), zr, zi);
}
- return f_expt(f_reciprocal(self), rb_int_uminus(other));
}
if (k_numeric_p(other) && f_real_p(other)) {
VALUE r, theta;
@@ -1026,14 +1105,51 @@ nucomp_eqeq_p(VALUE self, VALUE other)
return f_boolcast(f_eqeq_p(other, self));
}
+static bool
+nucomp_real_p(VALUE self)
+{
+ get_dat1(self);
+ return(f_zero_p(dat->imag) ? true : false);
+}
+
+/*
+ * call-seq:
+ * cmp <=> object -> 0, 1, -1, or nil
+ *
+ * If +cmp+'s imaginary part is zero, and +object+ is also a
+ * real number (or a Complex number where the imaginary part is zero),
+ * compare the real part of +cmp+ to object. Otherwise, return nil.
+ *
+ * Complex(2, 3) <=> Complex(2, 3) #=> nil
+ * Complex(2, 3) <=> 1 #=> nil
+ * Complex(2) <=> 1 #=> 1
+ * Complex(2) <=> 2 #=> 0
+ * Complex(2) <=> 3 #=> -1
+ */
+static VALUE
+nucomp_cmp(VALUE self, VALUE other)
+{
+ if (nucomp_real_p(self) && k_numeric_p(other)) {
+ if (RB_TYPE_P(other, T_COMPLEX) && nucomp_real_p(other)) {
+ get_dat2(self, other);
+ return rb_funcall(adat->real, idCmp, 1, bdat->real);
+ }
+ else if (f_real_p(other)) {
+ get_dat1(self);
+ return rb_funcall(dat->real, idCmp, 1, other);
+ }
+ }
+ return Qnil;
+}
+
/* :nodoc: */
static VALUE
nucomp_coerce(VALUE self, VALUE other)
{
- if (k_numeric_p(other) && f_real_p(other))
- return rb_assoc_new(f_complex_new_bang1(CLASS_OF(self), other), self);
if (RB_TYPE_P(other, T_COMPLEX))
return rb_assoc_new(other, self);
+ if (k_numeric_p(other) && f_real_p(other))
+ return rb_assoc_new(f_complex_new_bang1(CLASS_OF(self), other), self);
rb_raise(rb_eTypeError, "%"PRIsVALUE" can't be coerced into %"PRIsVALUE,
rb_obj_class(other), rb_obj_class(self));
@@ -1050,8 +1166,8 @@ nucomp_coerce(VALUE self, VALUE other)
* Complex(-1).abs #=> 1
* Complex(3.0, -4.0).abs #=> 5.0
*/
-static VALUE
-nucomp_abs(VALUE self)
+VALUE
+rb_complex_abs(VALUE self)
{
get_dat1(self);
@@ -1097,8 +1213,8 @@ nucomp_abs2(VALUE self)
*
* Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
*/
-static VALUE
-nucomp_arg(VALUE self)
+VALUE
+rb_complex_arg(VALUE self)
{
get_dat1(self);
return rb_math_atan2(dat->imag, dat->real);
@@ -1143,27 +1259,19 @@ nucomp_polar(VALUE self)
*
* Complex(1, 2).conjugate #=> (1-2i)
*/
-static VALUE
-nucomp_conj(VALUE self)
+VALUE
+rb_complex_conjugate(VALUE self)
{
get_dat1(self);
return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
}
-#if 0
-/* :nodoc: */
-static VALUE
-nucomp_true(VALUE self)
-{
- return Qtrue;
-}
-#endif
-
/*
* call-seq:
- * cmp.real? -> false
+ * Complex(1).real? -> false
+ * Complex(1, 2).real? -> false
*
- * Returns false.
+ * Returns false, even if the complex number has no imaginary part.
*/
static VALUE
nucomp_false(VALUE self)
@@ -1171,23 +1279,6 @@ nucomp_false(VALUE self)
return Qfalse;
}
-#if 0
-/* :nodoc: */
-static VALUE
-nucomp_exact_p(VALUE self)
-{
- get_dat1(self);
- return f_boolcast(k_exact_p(dat->real) && k_exact_p(dat->imag));
-}
-
-/* :nodoc: */
-static VALUE
-nucomp_inexact_p(VALUE self)
-{
- return f_boolcast(!nucomp_exact_p(self));
-}
-#endif
-
/*
* call-seq:
* cmp.denominator -> integer
@@ -1228,7 +1319,7 @@ nucomp_numerator(VALUE self)
get_dat1(self);
- cd = f_denominator(self);
+ cd = nucomp_denominator(self);
return f_complex_new2(CLASS_OF(self),
f_mul(f_numerator(dat->real),
f_div(cd, f_denominator(dat->real))),
@@ -1237,8 +1328,8 @@ nucomp_numerator(VALUE self)
}
/* :nodoc: */
-static VALUE
-nucomp_hash(VALUE self)
+st_index_t
+rb_complex_hash(VALUE self)
{
st_index_t v, h[2];
VALUE n;
@@ -1249,7 +1340,13 @@ nucomp_hash(VALUE self)
n = rb_hash(dat->imag);
h[1] = NUM2LONG(n);
v = rb_memhash(h, sizeof(h));
- return LONG2FIX(v);
+ return v;
+}
+
+static VALUE
+nucomp_hash(VALUE self)
+{
+ return ST2FIX(rb_complex_hash(self));
}
/* :nodoc: */
@@ -1352,8 +1449,8 @@ nucomp_inspect(VALUE self)
* call-seq:
* cmp.finite? -> true or false
*
- * Returns +true+ if +cmp+'s magnitude is finite number,
- * oterwise returns +false+.
+ * Returns +true+ if +cmp+'s real and imaginary parts are both finite numbers,
+ * otherwise returns +false+.
*/
static VALUE
rb_complex_finite_p(VALUE self)
@@ -1370,10 +1467,8 @@ rb_complex_finite_p(VALUE self)
* call-seq:
* cmp.infinite? -> nil or 1
*
- * Returns values corresponding to the value of +cmp+'s magnitude:
- *
- * +finite+:: +nil+
- * ++Infinity+:: ++1+
+ * Returns +1+ if +cmp+'s real or imaginary part is an infinite number,
+ * otherwise returns +nil+.
*
* For example:
*
@@ -1406,6 +1501,7 @@ nucomp_loader(VALUE self, VALUE a)
RCOMPLEX_SET_REAL(dat, rb_ivar_get(a, id_i_real));
RCOMPLEX_SET_IMAG(dat, rb_ivar_get(a, id_i_imag));
+ OBJ_FREEZE_RAW(self);
return self;
}
@@ -1449,12 +1545,18 @@ rb_complex_new(VALUE x, VALUE y)
}
VALUE
-rb_complex_polar(VALUE x, VALUE y)
+rb_complex_new_polar(VALUE x, VALUE y)
{
return f_complex_polar(rb_cComplex, x, y);
}
VALUE
+rb_complex_polar(VALUE x, VALUE y)
+{
+ return rb_complex_new_polar(x, y);
+}
+
+VALUE
rb_Complex(VALUE x, VALUE y)
{
VALUE a[2];
@@ -1463,10 +1565,17 @@ rb_Complex(VALUE x, VALUE y)
return nucomp_s_convert(2, a, rb_cComplex);
}
+/*!
+ * Creates a Complex object.
+ *
+ * \param real real part value
+ * \param imag imaginary part value
+ * \return a new Complex object
+ */
VALUE
-rb_complex_abs(VALUE cmp)
+rb_dbl_complex_new(double real, double imag)
{
- return nucomp_abs(cmp);
+ return rb_complex_raw(DBL2NUM(real), DBL2NUM(imag));
}
/*
@@ -1558,7 +1667,7 @@ nucomp_rationalize(int argc, VALUE *argv, VALUE self)
{
get_dat1(self);
- rb_scan_args(argc, argv, "01", NULL);
+ rb_check_arity(argc, 0, 1);
if (!k_exact_zero_p(dat->imag)) {
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
@@ -1606,8 +1715,6 @@ numeric_to_c(VALUE self)
return rb_complex_new1(self);
}
-#include <ctype.h>
-
inline static int
issign(int c)
{
@@ -1804,7 +1911,7 @@ read_comp(const char **s, int strict,
return 0; /* e.g. "1@-" */
}
num2 = str2num(bb);
- *ret = rb_complex_polar(num, num2);
+ *ret = rb_complex_new_polar(num, num2);
if (!st)
return 0; /* e.g. "1@2." */
else
@@ -1847,8 +1954,7 @@ skip_ws(const char **s)
}
static int
-parse_comp(const char *s, int strict,
- VALUE *num)
+parse_comp(const char *s, int strict, VALUE *num)
{
char *buf, *b;
VALUE tmp;
@@ -1859,14 +1965,14 @@ parse_comp(const char *s, int strict,
skip_ws(&s);
if (!read_comp(&s, strict, num, &b)) {
- ret = 0;
+ ret = 0;
}
else {
- skip_ws(&s);
+ skip_ws(&s);
- if (strict)
- if (*s != '\0')
- ret = 0;
+ if (strict)
+ if (*s != '\0')
+ ret = 0;
}
ALLOCV_END(tmp);
@@ -1874,7 +1980,7 @@ parse_comp(const char *s, int strict,
}
static VALUE
-string_to_c_strict(VALUE self)
+string_to_c_strict(VALUE self, int raise)
{
char *s;
VALUE num;
@@ -1883,8 +1989,10 @@ string_to_c_strict(VALUE self)
s = RSTRING_PTR(self);
- if (!s || memchr(s, '\0', RSTRING_LEN(self)))
+ if (!s || memchr(s, '\0', RSTRING_LEN(self))) {
+ if (!raise) return Qnil;
rb_raise(rb_eArgError, "string contains null byte");
+ }
if (s && s[RSTRING_LEN(self)]) {
rb_str_modify(self);
@@ -1896,6 +2004,7 @@ string_to_c_strict(VALUE self)
s = (char *)"";
if (!parse_comp(s, 1, &num)) {
+ if (!raise) return Qnil;
rb_raise(rb_eArgError, "invalid value for convert(): %+"PRIsVALUE,
self);
}
@@ -1951,28 +2060,29 @@ string_to_c(VALUE self)
}
static VALUE
-nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
+to_complex(VALUE val)
{
- VALUE a1, a2, backref;
-
- rb_scan_args(argc, argv, "11", &a1, &a2);
+ return rb_convert_type(val, T_COMPLEX, "Complex", "to_c");
+}
- if (NIL_P(a1) || (argc == 2 && NIL_P(a2)))
+static VALUE
+nucomp_convert(VALUE klass, VALUE a1, VALUE a2, int raise)
+{
+ if (NIL_P(a1) || NIL_P(a2)) {
+ if (!raise) return Qnil;
rb_raise(rb_eTypeError, "can't convert nil into Complex");
-
- backref = rb_backref_get();
- rb_match_busy(backref);
+ }
if (RB_TYPE_P(a1, T_STRING)) {
- a1 = string_to_c_strict(a1);
+ a1 = string_to_c_strict(a1, raise);
+ if (NIL_P(a1)) return Qnil;
}
if (RB_TYPE_P(a2, T_STRING)) {
- a2 = string_to_c_strict(a2);
+ a2 = string_to_c_strict(a2, raise);
+ if (NIL_P(a2)) return Qnil;
}
- rb_backref_set(backref);
-
if (RB_TYPE_P(a1, T_COMPLEX)) {
{
get_dat1(a1);
@@ -1992,16 +2102,19 @@ nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
}
if (RB_TYPE_P(a1, T_COMPLEX)) {
- if (argc == 1 || (k_exact_zero_p(a2)))
+ if (a2 == Qundef || (k_exact_zero_p(a2)))
return a1;
}
- if (argc == 1) {
+ if (a2 == Qundef) {
if (k_numeric_p(a1) && !f_real_p(a1))
return a1;
/* should raise exception for consistency */
- if (!k_numeric_p(a1))
- return rb_convert_type(a1, T_COMPLEX, "Complex", "to_c");
+ if (!k_numeric_p(a1)) {
+ if (!raise)
+ return rb_protect(to_complex, a1, NULL);
+ return to_complex(a1);
+ }
}
else {
if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
@@ -2012,13 +2125,35 @@ nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
}
{
+ int argc;
VALUE argv2[2];
argv2[0] = a1;
- argv2[1] = a2;
+ if (a2 == Qundef) {
+ argv2[1] = Qnil;
+ argc = 1;
+ }
+ else {
+ if (!raise && !RB_INTEGER_TYPE_P(a2) && !RB_FLOAT_TYPE_P(a2) && !RB_TYPE_P(a2, T_RATIONAL))
+ return Qnil;
+ argv2[1] = a2;
+ argc = 2;
+ }
return nucomp_s_new(argc, argv2, klass);
}
}
+static VALUE
+nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE a1, a2;
+
+ if (rb_scan_args(argc, argv, "11", &a1, &a2) == 1) {
+ a2 = Qundef;
+ }
+
+ return nucomp_convert(klass, a1, a2, TRUE);
+}
+
/* --- */
/*
@@ -2187,41 +2322,24 @@ void
Init_Complex(void)
{
VALUE compat;
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
- assert(fprintf(stderr, "assert() is now active\n"));
-
- id_abs = rb_intern("abs");
- id_arg = rb_intern("arg");
- id_denominator = rb_intern("denominator");
- id_expt = rb_intern("**");
- id_fdiv = rb_intern("fdiv");
- id_negate = rb_intern("-@");
- id_numerator = rb_intern("numerator");
- id_quo = rb_intern("quo");
- id_real_p = rb_intern("real?");
- id_to_f = rb_intern("to_f");
- id_to_i = rb_intern("to_i");
- id_to_r = rb_intern("to_r");
- id_i_real = rb_intern("@real");
- id_i_imag = rb_intern("@image"); /* @image, not @imag */
- id_finite_p = rb_intern("finite?");
- id_infinite_p = rb_intern("infinite?");
- id_rationalize = rb_intern("rationalize");
- id_PI = rb_intern("PI");
+ id_abs = rb_intern_const("abs");
+ id_arg = rb_intern_const("arg");
+ id_denominator = rb_intern_const("denominator");
+ id_numerator = rb_intern_const("numerator");
+ id_real_p = rb_intern_const("real?");
+ id_i_real = rb_intern_const("@real");
+ id_i_imag = rb_intern_const("@image"); /* @image, not @imag */
+ id_finite_p = rb_intern_const("finite?");
+ id_infinite_p = rb_intern_const("infinite?");
+ id_rationalize = rb_intern_const("rationalize");
+ id_PI = rb_intern_const("PI");
rb_cComplex = rb_define_class("Complex", rb_cNumeric);
rb_define_alloc_func(rb_cComplex, nucomp_s_alloc);
rb_undef_method(CLASS_OF(rb_cComplex), "allocate");
-#if 0
- rb_define_private_method(CLASS_OF(rb_cComplex), "new!", nucomp_s_new_bang, -1);
- rb_define_private_method(CLASS_OF(rb_cComplex), "new", nucomp_s_new, -1);
-#else
rb_undef_method(CLASS_OF(rb_cComplex), "new");
-#endif
rb_define_singleton_method(rb_cComplex, "rectangular", nucomp_s_new, -1);
rb_define_singleton_method(rb_cComplex, "rect", nucomp_s_new, -1);
@@ -2229,9 +2347,8 @@ Init_Complex(void)
rb_define_global_function("Complex", nucomp_f_complex, -1);
- rb_undef_methods_from(rb_cComplex, rb_mComparable);
+ rb_undef_methods_from(rb_cComplex, RCLASS_ORIGIN(rb_mComparable));
rb_undef_method(rb_cComplex, "%");
- rb_undef_method(rb_cComplex, "<=>");
rb_undef_method(rb_cComplex, "div");
rb_undef_method(rb_cComplex, "divmod");
rb_undef_method(rb_cComplex, "floor");
@@ -2243,43 +2360,36 @@ Init_Complex(void)
rb_undef_method(rb_cComplex, "truncate");
rb_undef_method(rb_cComplex, "i");
- rb_define_method(rb_cComplex, "real", nucomp_real, 0);
- rb_define_method(rb_cComplex, "imaginary", nucomp_imag, 0);
- rb_define_method(rb_cComplex, "imag", nucomp_imag, 0);
+ rb_define_method(rb_cComplex, "real", rb_complex_real, 0);
+ rb_define_method(rb_cComplex, "imaginary", rb_complex_imag, 0);
+ rb_define_method(rb_cComplex, "imag", rb_complex_imag, 0);
- rb_define_method(rb_cComplex, "-@", nucomp_negate, 0);
+ rb_define_method(rb_cComplex, "-@", rb_complex_uminus, 0);
rb_define_method(rb_cComplex, "+", rb_complex_plus, 1);
- rb_define_method(rb_cComplex, "-", nucomp_sub, 1);
- rb_define_method(rb_cComplex, "*", nucomp_mul, 1);
- rb_define_method(rb_cComplex, "/", nucomp_div, 1);
+ rb_define_method(rb_cComplex, "-", rb_complex_minus, 1);
+ rb_define_method(rb_cComplex, "*", rb_complex_mul, 1);
+ rb_define_method(rb_cComplex, "/", rb_complex_div, 1);
rb_define_method(rb_cComplex, "quo", nucomp_quo, 1);
rb_define_method(rb_cComplex, "fdiv", nucomp_fdiv, 1);
- rb_define_method(rb_cComplex, "**", nucomp_expt, 1);
+ rb_define_method(rb_cComplex, "**", rb_complex_pow, 1);
rb_define_method(rb_cComplex, "==", nucomp_eqeq_p, 1);
+ rb_define_method(rb_cComplex, "<=>", nucomp_cmp, 1);
rb_define_method(rb_cComplex, "coerce", nucomp_coerce, 1);
- rb_define_method(rb_cComplex, "abs", nucomp_abs, 0);
- rb_define_method(rb_cComplex, "magnitude", nucomp_abs, 0);
+ rb_define_method(rb_cComplex, "abs", rb_complex_abs, 0);
+ rb_define_method(rb_cComplex, "magnitude", rb_complex_abs, 0);
rb_define_method(rb_cComplex, "abs2", nucomp_abs2, 0);
- rb_define_method(rb_cComplex, "arg", nucomp_arg, 0);
- rb_define_method(rb_cComplex, "angle", nucomp_arg, 0);
- rb_define_method(rb_cComplex, "phase", nucomp_arg, 0);
+ rb_define_method(rb_cComplex, "arg", rb_complex_arg, 0);
+ rb_define_method(rb_cComplex, "angle", rb_complex_arg, 0);
+ rb_define_method(rb_cComplex, "phase", rb_complex_arg, 0);
rb_define_method(rb_cComplex, "rectangular", nucomp_rect, 0);
rb_define_method(rb_cComplex, "rect", nucomp_rect, 0);
rb_define_method(rb_cComplex, "polar", nucomp_polar, 0);
- rb_define_method(rb_cComplex, "conjugate", nucomp_conj, 0);
- rb_define_method(rb_cComplex, "conj", nucomp_conj, 0);
-#if 0
- rb_define_method(rb_cComplex, "~", nucomp_conj, 0); /* gcc */
-#endif
+ rb_define_method(rb_cComplex, "conjugate", rb_complex_conjugate, 0);
+ rb_define_method(rb_cComplex, "conj", rb_complex_conjugate, 0);
rb_define_method(rb_cComplex, "real?", nucomp_false, 0);
-#if 0
- rb_define_method(rb_cComplex, "complex?", nucomp_true, 0);
- rb_define_method(rb_cComplex, "exact?", nucomp_exact_p, 0);
- rb_define_method(rb_cComplex, "inexact?", nucomp_inexact_p, 0);
-#endif
rb_define_method(rb_cComplex, "numerator", nucomp_numerator, 0);
rb_define_method(rb_cComplex, "denominator", nucomp_denominator, 0);
@@ -2297,7 +2407,8 @@ Init_Complex(void)
rb_define_method(rb_cComplex, "infinite?", rb_complex_infinite_p, 0);
rb_define_private_method(rb_cComplex, "marshal_dump", nucomp_marshal_dump, 0);
- compat = rb_define_class_under(rb_cComplex, "compatible", rb_cObject); /* :nodoc: */
+ /* :nodoc: */
+ compat = rb_define_class_under(rb_cComplex, "compatible", rb_cObject);
rb_define_private_method(compat, "marshal_load", nucomp_marshal_load, 1);
rb_marshal_define_compat(rb_cComplex, compat, nucomp_dumper, nucomp_loader);
@@ -2340,11 +2451,9 @@ Init_Complex(void)
rb_define_const(rb_cComplex, "I",
f_complex_new_bang2(rb_cComplex, ZERO, ONE));
+#if !USE_FLONUM
+ rb_gc_register_mark_object(RFLOAT_0 = DBL2NUM(0.0));
+#endif
+
rb_provide("complex.so"); /* for backward compatibility */
}
-
-/*
-Local variables:
-c-file-style: "ruby"
-End:
-*/
diff --git a/configure.ac b/configure.ac
index e6cd95cc9d..28fdfefbbc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,37 +1,55 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT()
+AC_INIT
{
AC_CONFIG_AUX_DIR(tool)
AC_PREREQ(2.67)
-AC_DISABLE_OPTION_CHECKING
-
-AC_ARG_VAR([cflags], [additional CFLAGS])
-AC_ARG_VAR([cppflags], [additional CPPFLAGS])
-AC_ARG_VAR([cxxflags], [additional CXXFLAGS])
-
-AC_DEFUN([RUBY_RM_RECURSIVE], [
-m4_version_prereq([2.70], [-1], [
-# suppress error messages, rm: cannot remove 'conftest.dSYM', from
-# AC_EGREP_CPP with CFLAGS=-g on Darwin.
-AS_CASE([$build_os], [darwin*], [
-rm() {
- rm_recursive=''
- for arg do
- AS_CASE("$arg",
- [--*], [],
- [-*r*], [break],
- [conftest.*], [AS_IF([test -d "$arg"], [rm_recursive=-r; break])],
- [])
- done
- command rm $rm_recursive "[$]@"
-}
-])])])
+tooldir="$srcdir/tool"
-{ # environment section
+AC_DISABLE_OPTION_CHECKING
+m4_include([tool/m4/_colorize_result_prepare.m4])
+m4_include([tool/m4/ac_msg_result.m4])
+m4_include([tool/m4/colorize_result.m4])
+m4_include([tool/m4/ruby_append_option.m4])
+m4_include([tool/m4/ruby_append_options.m4])
+m4_include([tool/m4/ruby_check_builtin_func.m4])
+m4_include([tool/m4/ruby_check_builtin_setjmp.m4])
+m4_include([tool/m4/ruby_check_printf_prefix.m4])
+m4_include([tool/m4/ruby_check_setjmp.m4])
+m4_include([tool/m4/ruby_check_signedness.m4])
+m4_include([tool/m4/ruby_check_sizeof.m4])
+m4_include([tool/m4/ruby_check_sysconf.m4])
+m4_include([tool/m4/ruby_cppoutfile.m4])
+m4_include([tool/m4/ruby_decl_attribute.m4])
+m4_include([tool/m4/ruby_default_arch.m4])
+m4_include([tool/m4/ruby_define_if.m4])
+m4_include([tool/m4/ruby_defint.m4])
+m4_include([tool/m4/ruby_dtrace_available.m4])
+m4_include([tool/m4/ruby_dtrace_postprocess.m4])
+m4_include([tool/m4/ruby_func_attribute.m4])
+m4_include([tool/m4/ruby_mingw32.m4])
+m4_include([tool/m4/ruby_prepend_option.m4])
+m4_include([tool/m4/ruby_prog_gnu_ld.m4])
+m4_include([tool/m4/ruby_replace_funcs.m4])
+m4_include([tool/m4/ruby_replace_type.m4])
+m4_include([tool/m4/ruby_rm_recursive.m4])
+m4_include([tool/m4/ruby_setjmp_type.m4])
+m4_include([tool/m4/ruby_stack_grow_direction.m4])
+m4_include([tool/m4/ruby_try_cflags.m4])
+m4_include([tool/m4/ruby_try_cxxflags.m4])
+m4_include([tool/m4/ruby_try_ldflags.m4])
+m4_include([tool/m4/ruby_universal_arch.m4])
+m4_include([tool/m4/ruby_werror_flag.m4])
+
+AC_ARG_VAR([cflags], [additional CFLAGS (ignored when CFLAGS is given)])
+AC_ARG_VAR([cppflags], [additional CPPFLAGS (ignored when CPPFLAGS is given)])
+AC_ARG_VAR([cxxflags], [additional CXXFLAGS (ignored when CXXFLAGS is given)])
+
+: "environment section" && {
HAVE_BASERUBY=yes
+BASERUBY_VERSION=
AC_ARG_WITH(baseruby,
AS_HELP_STRING([--with-baseruby=RUBY], [use RUBY as baseruby; RUBY is the pathname of ruby]),
[AS_CASE(["$withval"],
@@ -42,11 +60,10 @@ AC_ARG_WITH(baseruby,
[
AC_PATH_PROG([BASERUBY], [ruby], [false])
])
-AS_IF([test "$HAVE_BASERUBY" = yes -a "`RUBYOPT=- $BASERUBY -e 'print 42' 2>/dev/null`" = 42], [
- AS_IF([test "`RUBYOPT=- $BASERUBY --disable=gems -e 'print 42' 2>/dev/null`" = 42], [
- BASERUBY="$BASERUBY --disable=gems"
- ])
- $BASERUBY -C "$srcdir" tool/downloader.rb -d tool -e gnu config.guess config.sub
+AS_IF([test "$HAVE_BASERUBY" != no -a "`RUBYOPT=- $BASERUBY --disable=gems -e 'print 42 if RUBY_VERSION > "2.2"' 2>/dev/null`" = 42], [
+ BASERUBY="$BASERUBY --disable=gems"
+ BASERUBY_VERSION=`$BASERUBY -v`
+ $BASERUBY -C "$srcdir" tool/downloader.rb -d tool -e gnu config.guess config.sub >&AS_MESSAGE_FD
], [
BASERUBY="echo executable host ruby is required. use --with-baseruby option.; false"
HAVE_BASERUBY=no
@@ -66,193 +83,37 @@ AS_IF([test x"$HAVE_GIT" = xyes], [command -v "$GIT" > /dev/null || HAVE_GIT=no]
AC_SUBST(GIT)
AC_SUBST(HAVE_GIT)
-AC_DEFUN([RUBY_MINGW32],
-[AS_CASE(["$host_os"],
-[cygwin*], [
-AC_CACHE_CHECK(for mingw32 environment, rb_cv_mingw32,
-[AC_TRY_CPP([
-#ifndef __MINGW32__
-# error
-#endif
-], rb_cv_mingw32=yes,rb_cv_mingw32=no)
-rm -f conftest*])
-AS_IF([test "$rb_cv_mingw32" = yes], [
- target_os="mingw32"
- : ${ac_tool_prefix:="`expr "$CC" : ['\(.*-\)g\?cc[^/]*$']`"}
-])
-])
-AS_CASE(["$target_os"], [mingw*msvc], [
-target_os="`echo ${target_os} | sed 's/msvc$//'`"
-])
-AS_CASE(["$target_cpu-$target_os"], [x86_64-mingw*], [
-target_cpu=x64
-])
-])
-
-AC_DEFUN([RUBY_NACL],
-[
- AS_CASE(["${host_os}"],
-[nacl], [
- ac_cv_exeext=.nexe
- host_vendor=chromium
- ac_cv_host=chromium
- AC_MSG_CHECKING([wheather \$NACL_SDK_ROOT is set])
- AS_IF([test x"${NACL_SDK_ROOT}" = x], [
- AC_MSG_RESULT([no])
- AC_MSG_ERROR([You need to set \$NACL_SDK_ROOT environment variable to build for NativeClient])
- ])
- AC_MSG_RESULT([yes])
-
- nacl_cv_build_variant=glibc
- AC_ARG_WITH(newlib,
- AS_HELP_STRING([--with-newlib], [uses newlib version of NativeClient SDK]),
- [AS_CASE([$withval],
- [no], [nacl_cv_build_variant=glibc],
- [yes], [nacl_cv_build_variant=newlib])])
-
- AS_CASE(["$target_cpu"],
- [x86_64], [nacl_cv_cpu_nick=x86
- nacl_cv_cpu_nick2=x86_64],
- [i?86], [nacl_cv_cpu_nick=x86
- nacl_cv_cpu_nick2=x86_32],
- [le32], [nacl_cv_cpu_nick=pnacl
- nacl_cv_cpu_nick2=pnacl
- ac_cv_exeext=.pexe],
- [nacl_cv_cpu_nick=$target_cpu])
- AS_CASE(["$build_os"],
- [linux*], [nacl_cv_os_nick=linux],
- [darwin*], [nacl_cv_os_nick=mac],
- [cygwin*|mingw*], [nacl_cv_os_nick=win],
- [nacl_cv_os_nick=$build_os])
-
- host="$host_cpu-chromium-$host_os-"
- ac_tool_prefix="$host_cpu-nacl-"
-
- AC_MSG_CHECKING([NativeClient toolchain])
- AS_IF([test x"$nacl_cv_cpu_nick" = xpnacl], [
- NACL_TOOLCHAIN="${nacl_cv_os_nick}_pnacl"
- ac_tool_prefix=pnacl-
- ], [test -d \
- "${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_${nacl_cv_cpu_nick}_${nacl_cv_build_variant}"], [
- NACL_TOOLCHAIN="${nacl_cv_os_nick}_${nacl_cv_cpu_nick}_${nacl_cv_build_variant}"
- ], [test -d \
- "${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_x86_${nacl_cv_cpu_nick}/${nacl_cv_build_variant}"], [
- NACL_TOOLCHAIN="${nacl_cv_os_nick}_x86_${nacl_cv_cpu_nick}/${nacl_cv_build_variant}"
- ], [
- AS_CASE(
- ["${nacl_cv_build_variant}"],
- [glibc], [AS_IF([test \
- -d "${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_${nacl_cv_cpu_nick}_newlib" \
- -a -d "${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_${nacl_cv_cpu_nick}"], [
- NACL_TOOLCHAIN="${nacl_cv_os_nick}_${nacl_cv_cpu_nick}"
- ])],
- [newlib], [ NACL_TOOLCHAIN="${nacl_cv_os_nick}_${nacl_cv_cpu_nick}" ])
- ])
- AS_IF([test ! -e "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/${ac_tool_prefix}gcc"], [
- AS_IF([test "${build_cpu}" = i686 -a -e "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/nacl-gcc"], [
- ac_tool_prefix=nacl-
- ])
- AS_IF([test "${build_cpu}" = x86_64 -a -e "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/nacl-gcc"], [
- ac_tool_prefix=nacl64-
- ])
- ])
- AS_IF([test -z "${NACL_TOOLCHAIN}"], [
- AC_MSG_ERROR([Unrecognized --host and --build combination or NaCl SDK is not installed])
- ])
- AC_MSG_RESULT(${NACL_TOOLCHAIN})
-
- AC_MSG_CHECKING([path to SDK])
- AS_IF([! echo -- "${PATH}" | grep -F "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/bin" > /dev/null], [
- PATH="${PATH}:${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/bin"
- ])
- AC_MSG_RESULT(${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/bin)
-
- RUBY_APPEND_OPTIONS(XCFLAGS, '-I$(NACL_SDK_ROOT)/include')
- AS_IF([test x"${nacl_cv_cpu_nick}" = xpnacl], [
- RUBY_APPEND_OPTIONS(XCFLAGS, '-isystem $(NACL_SDK_ROOT)/include/pnacl')
- ], [test x"${nacl_cv_build_variant}" = xnewlib], [
- RUBY_APPEND_OPTIONS(XCFLAGS, '-isystem $(NACL_SDK_ROOT)/include/newlib')
- ])
-
- AC_MSG_CHECKING([nacl library path])
- AS_IF([test -d "${NACL_SDK_ROOT}/lib/${nacl_cv_build_variant}_${nacl_cv_cpu_nick2}/Release"], [
- nacl_cv_libpath="${nacl_cv_build_variant}_${nacl_cv_cpu_nick2}"
- ], [test -d "${NACL_SDK_ROOT}/lib/${nacl_cv_cpu_nick2}/Release"], [
- nacl_cv_libpath="${nacl_cv_cpu_nick2}"
- ], [
- AC_MSG_ERROR([not found])
- ])
- AC_MSG_RESULT([${nacl_cv_libpath}])
- RUBY_APPEND_OPTIONS(XLDFLAGS, '-L$(NACL_SDK_ROOT)/'"lib/${nacl_cv_libpath}/Release")
-
- AC_SUBST(NACL_TOOLCHAIN)
- AC_SUBST(NACL_SDK_ROOT)
- AC_SUBST(NACL_SDK_VARIANT, "${nacl_cv_build_variant}")
- AC_SUBST(NACL_LIB_PATH, "${nacl_cv_libpath}")
- AC_CHECK_TOOLS(CC, [clang gcc])
- AC_CHECK_TOOLS(CXX, [clang++ g++])
-])])
-
-AC_DEFUN([RUBY_NACL_CHECK_PEPPER_TYPES],
-[AS_CASE(["${host_os}"],
-[nacl], [
- AC_CHECK_TYPES([struct PPB_Core, struct PPB_Messaging, struct PPB_Var,
- struct PPB_URLLoader, struct PPB_URLRequestInfo,
- struct PPB_URLResponseInfo, struct PPB_FileRef,
- struct PPP_Instance])
-])
-])
-
-AC_DEFUN([RUBY_CPPOUTFILE],
-[AC_CACHE_CHECK(whether ${CPP} accepts -o, rb_cv_cppoutfile,
-[save_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS='-o conftest-1.i'
-rb_cv_cppoutfile=no
-AC_TRY_CPP([test-for-cppout],
- [grep test-for-cppout conftest-1.i > /dev/null && rb_cv_cppoutfile=yes])
-CPPFLAGS="$save_CPPFLAGS"
-rm -f conftest*])
-AS_IF([test "$rb_cv_cppoutfile" = yes], [
- CPPOUTFILE='-o conftest.i'
-], [test "$rb_cv_cppoutfile" = no], [
- CPPOUTFILE='> conftest.i'
-], [test -n "$rb_cv_cppoutfile"], [
- CPPOUTFILE="$rb_cv_cppoutfile"
-])
-AC_SUBST(CPPOUTFILE)])
-
-AC_DEFUN([RUBY_PROG_GNU_LD],
-[AC_CACHE_CHECK(whether the linker is GNU ld, rb_cv_prog_gnu_ld,
-[AS_IF([`$CC $CFLAGS $CPPFLAGS $LDFLAGS --print-prog-name=ld 2>&1` -v 2>&1 | grep "GNU ld" > /dev/null], [
- rb_cv_prog_gnu_ld=yes
-], [
- rb_cv_prog_gnu_ld=no
-])])
-GNU_LD=$rb_cv_prog_gnu_ld
-AC_SUBST(GNU_LD)])
-
-eval `sed -n ['s/^@%:@define RUBY_API_VERSION_\([A-Z][A-Z_0-9]*\) \([0-9][0-9]*\)/API_\1=\2/p'] $srcdir/include/ruby/version.h`
-RUBY_PROGRAM_VERSION=`sed -n 's/^@%:@define RUBY_VERSION "\(.*\)"/\1/p' $srcdir/version.h`
-MAJOR=`echo $RUBY_PROGRAM_VERSION | cut -d. -f1`
-MINOR=`echo $RUBY_PROGRAM_VERSION | cut -d. -f2`
-TEENY=`echo $RUBY_PROGRAM_VERSION | cut -d. -f3`
+eval `sed -n -e ['s/^@%:@define RUBY_[A-Z_]*VERSION_\([A-Z][A-Z][A-Z_0-9]*\) \([0-9][0-9]*\)$/\1=\2/p'] \
+ -e ['s/^@%:@define \(RUBY_PATCHLEVEL\) \(.*\)/\1=\2/p'] \
+ $srcdir/include/ruby/version.h $srcdir/version.h`
for v in MAJOR MINOR TEENY; do
AS_IF([eval "test \"\$$v\" = ''"], [
AC_MSG_ERROR(could not determine $v number from version.h)
])
done
-AS_IF([test "$MAJOR.$MINOR" != "$API_MAJOR.$API_MINOR"], [
- AC_MSG_ERROR([API version $API_MAJOR.$API_MINOR differs from program version $MAJOR.$MINOR])
-])
AC_SUBST(MAJOR)
AC_SUBST(MINOR)
AC_SUBST(TEENY)
-AC_SUBST(RUBY_PROGRAM_VERSION)
AC_SUBST(RUBY_API_VERSION, '$(MAJOR).$(MINOR)')
-RUBY_PATCHLEVEL=`sed -n 's/^#define RUBY_PATCHLEVEL //p' $srcdir/version.h`
-AC_DEFINE(CANONICALIZATION_FOR_MATHN)
+AC_SUBST(RUBY_PROGRAM_VERSION, '$(MAJOR).$(MINOR).$(TEENY)')
+
+AS_IF([test "$program_prefix" = NONE], [
+ program_prefix=
+])
+AS_IF([test "$prefix" -ef .], [
+ AC_MSG_ERROR(--prefix cannot be the current working directory.)
+])
+RUBY_BASE_NAME=`echo ruby | sed "$program_transform_name"`
+RUBYW_BASE_NAME=`echo rubyw | sed "$program_transform_name"`
+AC_SUBST(RUBY_BASE_NAME)
+AC_SUBST(RUBYW_BASE_NAME)
+AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version}')
+
dnl checks for alternative programs
AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+AC_ARG_PROGRAM
RUBY_RM_RECURSIVE
AC_ARG_WITH(gcc,
AS_HELP_STRING([--without-gcc], [never use gcc]),
@@ -266,21 +127,105 @@ AS_IF([test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"], [
AC_MSG_ERROR(cached CC is different -- throw away $cache_file
(it is also a good idea to do 'make clean' before compiling))
])
-test -z "$CC" || ac_cv_prog_CC="$CC"
-
-AS_IF([test "$program_prefix" = NONE], [
- program_prefix=
+AS_CASE(["${build_os}"], [linux*|cygwin*], [
+ AC_CHECK_TOOLS([CC], [gcc clang cc])
+], [
+ # OpenBSD wants to prefer cc over gcc.
+ # See https://github.com/ruby/ruby/pull/2443
+ AC_CHECK_TOOLS([CC], [cl.exe clang cc gcc c99 /usr/ucb/cc])
+])
+
+AC_ARG_VAR([AR], [Archiver command])
+AC_ARG_VAR([AS], [Assembler command])
+AC_ARG_VAR([CC], [C compiler command])
+AC_ARG_VAR([CXX], [C++ compiler command])
+AC_ARG_VAR([LD], [Linker command])
+AC_ARG_VAR([NM], [Symbol list command])
+AC_ARG_VAR([OBJCOPY], [Objcopy command])
+AC_ARG_VAR([OBJDUMP], [Objdump command])
+AC_ARG_VAR([RANLIB], [Ranlib command])
+AC_ARG_VAR([STRIP], [Strip command])
+
+# We don't want to bother things like `ccache gcc`, `clang -shared-libgcc`, ...
+set rb_dummy ${CC}
+rb_CC=$2
+AS_CASE(["/${rb_CC} "],
+[*@<:@\ /@:>@"cc "*], [
+ # Don't try g++/clang++ when CC=cc
+ AC_CHECK_TOOLS([CXX], [cl.exe CC c++])
+],
+[*icc*], [
+ # Intel C++ has interprocedural optimizations. It tends to come with its
+ # own linker etc.
+ AC_CHECK_TOOL([AR], [`echo "${rb_CC}" | sed s/icc/xiar/`])
+ AC_CHECK_TOOL([CXX], [`echo "${rb_CC}" | sed s/icc/icpc/`])
+ AC_CHECK_TOOL([LD], [`echo "${rb_CC}" | sed s/icc/xild/`])
+],
+[*gcc*], [
+ # Dito for GCC.
+ AC_CHECK_TOOL([LD], [`echo "${rb_CC}" | sed s/gcc/ld/`])
+ AC_CHECK_TOOL([AR], [`echo "${rb_CC}" | sed s/gcc/gcc-ar/`])
+ AC_CHECK_TOOL([CXX], [`echo "${rb_CC}" | sed s/gcc/g++/`])
+ AC_CHECK_TOOL([NM], [`echo "${rb_CC}" | sed s/gcc/gcc-nm/`])
+ AC_CHECK_TOOL([RANLIB], [`echo "${rb_CC}" | sed s/gcc/gcc-ranlib/`])
+],
+[*clang*], [
+ # Dito for LLVM. Note however that llvm-as is a LLVM-IR to LLVM bitcode
+ # assembler that does not target your machine native binary.
+ : ${LD:="${CC}"} # ... try -fuse-ld=lld ?
+ AC_CHECK_TOOL([AR], [`echo "${rb_CC}" | sed s/clang/llvm-ar/`])
+# AC_CHECK_TOOL([AS], [`echo "${rb_CC}" | sed s/clang/llvm-as/`])
+ AC_CHECK_TOOL([CXX], [`echo "${rb_CC}" | sed s/clang/clang++/`])
+ AC_CHECK_TOOL([NM], [`echo "${rb_CC}" | sed s/clang/llvm-nm/`])
+ AC_CHECK_TOOL([OBJCOPY], [`echo "${rb_CC}" | sed s/clang/llvm-objcopy/`])
+ AC_CHECK_TOOL([OBJDUMP], [`echo "${rb_CC}" | sed s/clang/llvm-objdump/`])
+ AC_CHECK_TOOL([RANLIB], [`echo "${rb_CC}" | sed s/clang/llvm-ranlib/`])
+ AC_CHECK_TOOL([STRIP], [`echo "${rb_CC}" | sed s/clang/llvm-strip/`])
+])
+AS_UNSET(rb_CC)
+AS_UNSET(rb_dummy)
+
+AS_CASE(["${build_os}"],
+[solaris*], [
+ AC_PATH_TOOL([LD], [ld], [/usr/ccs/bin/ld], [/usr/ccs/bin:$PATH])
+],
+[aix*], [
+ AC_PATH_TOOL([NM], [nm], [/usr/ccs/bin/nm], [/usr/ccs/bin:$PATH])
])
-AS_IF([test "$prefix" -ef .], [
- AC_MSG_ERROR(--prefix cannot be the current working directory.)
+AS_CASE(["${target_os}"],
+[cygwin*|mingw*], [
+ ac_cv_prog_ac_ct_OBJCOPY=":"
+])
+
+rb_test_CFLAGS=${CFLAGS+yes}
+rb_test_CXXFLAGS=${CXXFLAGS+yes}
+
+# BSD's ports and MacPorts prefix GNU binutils with 'g'
+
+dnl Seems necessarily in order to add -std=gnu99 option for gcc 4.9.
+m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
+
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_RANLIB
+AC_CHECK_TOOLS([AR], [gar ar])
+AC_CHECK_TOOLS([AS], [gas as])
+AC_CHECK_TOOLS([LD], [gld ld]) # ... try gold ?
+AC_CHECK_TOOLS([NM], [gnm nm])
+AC_CHECK_TOOLS([OBJCOPY], [gobjcopy objcopy])
+AC_CHECK_TOOLS([OBJDUMP], [gobjdump objdump])
+AC_CHECK_TOOLS([STRIP], [gstrip strip], [:])
+
+AS_IF([test ! $rb_test_CFLAGS], [AS_UNSET(CFLAGS)]); AS_UNSET(rb_test_CFLAGS)
+AS_IF([test ! $rb_test_CXXFLAGS], [AS_UNSET(CXXFLAGS)]); AS_UNSET(rb_save_CXXFLAGS)
+
+AS_IF([test "${CXX}" = "g++" -a -z "${GXX}"], [
+ # AC_PROG_CXX sets $CXX to "g++" when it purposefully finds that there is
+ # _no_ g++. This brain-damaged design must be worked around. Thankfully,
+ # similar thing doesn't happen for AC_PROG_CC.
+ rb_there_is_in_fact_no_gplusplus_but_autoconf_is_cheating_us=true
])
-RUBY_BASE_NAME=`echo ruby | sed "$program_transform_name"`
-RUBYW_BASE_NAME=`echo rubyw | sed "$program_transform_name"`
-AC_SUBST(RUBY_BASE_NAME)
-AC_SUBST(RUBYW_BASE_NAME)
-AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version}')
-AC_CANONICAL_TARGET
test x"$target_alias" = x &&
target_os=`echo $target_os | sed 's/linux-gnu$/linux/;s/linux-gnu/linux-/'`
ac_install_sh='' # unusable for extension libraries.
@@ -307,7 +252,7 @@ AS_CASE("${os_version_style}",
[minor], [os_version_style_transform=['s/\([0-9]\.[0-9][0-9]*\)\.[0-9][.0-9]*$/\1/']],
[major+0], [os_version_style_transform=['s/\([0-9]\)\.[0-9][.0-9]*$/\1.0/']],
[major], [os_version_style_transform=['s/\([0-9]\)\.[0-9][.0-9]*$/\1/']],
- [none], [os_version_style_transform=['s/[0-9]\.[0-9][.0-9]*$//']],
+ [none], [os_version_style_transform=['s/[0-9]*\.[0-9][.0-9]*$//']],
[AC_MSG_ERROR(unknown --with-os-version-style: $withval)])
AS_IF([test -z "$target_alias" -a -n "$os_version_style_transform"],
[
@@ -315,28 +260,6 @@ AS_IF([test -z "$target_alias" -a -n "$os_version_style_transform"],
target_os=`echo ${target_os} | sed "$os_version_style_transform"`
])
-AC_DEFUN([RUBY_APPEND_OPTION],
- [# RUBY_APPEND_OPTION($1)
- AS_CASE([" [$]{$1-} "],
- [*" $2 "*], [], [' '], [ $1="$2"], [ $1="[$]$1 $2"])])
-AC_DEFUN([RUBY_APPEND_OPTIONS],
- [# RUBY_APPEND_OPTIONS($1)
- for rb_opt in $2; do
- AS_CASE([" [$]{$1-} "],
- [*" [$]{rb_opt} "*], [], [' '], [ $1="[$]{rb_opt}"], [ $1="[$]$1 [$]{rb_opt}"])
- done])
-AC_DEFUN([RUBY_PREPEND_OPTION],
- [# RUBY_PREPEND_OPTION($1)
- AS_CASE([" [$]{$1-} "],
- [*" $2 "*], [], [' '], [ $1="$2"], [ $1="$2 [$]$1"])])
-AC_DEFUN([RUBY_PREPEND_OPTIONS],
- [# RUBY_PREPEND_OPTIONS($1)
- unset rb_opts; for rb_opt in $2; do
- AS_CASE([" [$]{rb_opts} [$]{$1-} "],
- [*" [$]{rb_opt} "*], [], [' '], [ $1="[$]{rb_opt}"], [ rb_opts="[$]{rb_opts}[$]{rb_opt} "])
- done
- $1="[$]{rb_opts}[$]$1"])
-
AC_ARG_WITH(arch,
AS_HELP_STRING([--with-arch=ARCHS],
[build an Apple/NeXT Multi Architecture Binary (MAB);
@@ -346,111 +269,12 @@ AC_ARG_WITH(arch,
target platform]),
[target_archs="$withval"], [unset target_archs])
-AC_DEFUN([RUBY_DEFAULT_ARCH], [
-AC_MSG_CHECKING([arch option])
-AS_CASE([$1],
- [*64], [ARCH_FLAG=-m64],
- [[i[3-6]86]], [ARCH_FLAG=-m32],
- [AC_MSG_ERROR(unknown target architecture: $target_archs)]
- )
-AC_MSG_RESULT([$ARCH_FLAG])
-])
-
-AC_DEFUN([RUBY_UNIVERSAL_ARCH], [
-# RUBY_UNIVERSAL_ARCH begin
-ARCH_FLAG=`expr " $CXXFLAGS " : ['.* \(-m[0-9][0-9]*\) ']`
-test ${CXXFLAGS+set} && CXXFLAGS=`echo "$CXXFLAGS" | sed [-e 's/ *-arch *[^ ]*//g' -e 's/ *-m32//g' -e 's/ *-m64//g']`
-ARCH_FLAG=`expr " $CFLAGS " : ['.* \(-m[0-9][0-9]*\) ']`
-test ${CFLAGS+set} && CFLAGS=`echo "$CFLAGS" | sed [-e 's/ *-arch *[^ ]*//g' -e 's/ *-m32//g' -e 's/ *-m64//g']`
-test ${LDFLAGS+set} && LDFLAGS=`echo "$LDFLAGS" | sed [-e 's/ *-arch *[^ ]*//g' -e 's/ *-m32//g' -e 's/ *-m64//g']`
-unset universal_binary universal_archnames
-AS_IF([test ${target_archs+set}], [
- AC_MSG_CHECKING([target architectures])
- target_archs=`echo $target_archs | tr , ' '`
- # /usr/lib/arch_tool -archify_list $TARGET_ARCHS
- for archs in $target_archs
- do
- AS_CASE([",$universal_binary,"],[*",$archs,"*], [],[
- cpu=`$SHELL "$ac_aux_dir/config.sub" "${archs}-${target_os}" 2>&1` || {
- AC_MSG_RESULT([failed])
- AC_MSG_ERROR([$cpu])
- }
- cpu=`echo $cpu | sed 's/-.*-.*//'`
- universal_binary="${universal_binary+$universal_binary,}$cpu"
- universal_archnames="${universal_archnames} ${archs}=${cpu}"
- ARCH_FLAG="${ARCH_FLAG+$ARCH_FLAG }-arch $archs"
- ])
- done
- target_archs="$universal_binary"
- unset universal_binary
- AS_CASE(["$target_archs"],
- [*,*], [universal_binary=yes],
- [unset universal_archnames])
- AC_MSG_RESULT([$target_archs])
-
- target=`echo $target | sed "s/^$target_cpu-/-/"`
- target_alias=`echo $target_alias | sed "s/^$target_cpu-/-/"`
- AS_IF([test "${universal_binary-no}" = yes], [
- AC_SUBST(try_header,try_compile)
- target_cpu=universal
- real_cross_compiling=$cross_compiling
- ], [
- AS_IF([test x"$target_cpu" != x"${target_archs}"], [
- echo 'int main(){return 0;}' > conftest.c
- AS_IF([$CC $CFLAGS $ARCH_FLAG -o conftest conftest.c > /dev/null 2>&1], [
- rm -fr conftest.*
- ], [
- RUBY_DEFAULT_ARCH("$target_archs")
- ])
- ])
- target_cpu=${target_archs}
- ])
- AS_CASE(["$target"], [-*], [ target="$target_cpu${target}"])
- AS_CASE(["$target_alias"], [-*], [ target_alias="$target_cpu${target_alias}"])
-], [
- AS_IF([test x"$target_alias" = x], [
- AS_CASE(["$target_os"],
- [darwin*], [
- AC_MSG_CHECKING([for real target cpu])
- target=`echo $target | sed "s/^$target_cpu-/-/"`
- target_cpu=`$CC -E - 2>/dev/null <<EOF |
-#ifdef __x86_64__
-"processor-name=x86_64"
-#endif
-#ifdef __i386__
-"processor-name=i386"
-#endif
-#ifdef __ppc__
-"processor-name=powerpc"
-#endif
-#ifdef __ppc64__
-"processor-name=powerpc64"
-#endif
-EOF
- sed -n 's/^"processor-name=\(.*\)"/\1/p'`
- target="$target_cpu${target}"
- AC_MSG_RESULT([$target_cpu])
- ])
- ])
- target_archs="$target_cpu"
-])
-AS_IF([test "${target_archs}" != "${rb_cv_target_archs-${target_archs}}"], [
- AC_MSG_ERROR([target arch(s) has changed from ${rb_cv_target_archs-nothing} to ${target_archs}])
-], [
- rb_cv_target_archs=${target_archs}
-])
-AS_IF([test "x${ARCH_FLAG}" != x], [
- CFLAGS="${CFLAGS:+$CFLAGS }${ARCH_FLAG}"
- LDFLAGS="${LDFLAGS:+$LDFLAGS }${ARCH_FLAG}"
-])
-# RUBY_UNIVERSAL_ARCH end
-])
-
AC_ARG_ENABLE(load-relative,
AS_HELP_STRING([--enable-load-relative], [resolve load paths at run time]),
[load_relative=$enableval])
-AC_ARG_PROGRAM
+# checks for UNIX variants that set C preprocessor variables
+AC_USE_SYSTEM_EXTENSIONS
dnl Checks for programs.
@@ -459,60 +283,52 @@ test -z "$optflags" ||
cflagspat="$cflagspat;s|"`eval echo '"'"${optflags}"'"' | sed 's/[[][|.*]]/\\&/g;s/^ */ /;s/ *$/ /'`'| |g'
test -z "$debugflags" ||
cflagspat="$cflagspat;s|"`eval echo '"'"${debugflags}"'"' | sed 's/[[][|.*]]/\\&/g;s/^ */ /;s/ *$/ /'`'| |g'
-test -z "warnflags" ||
+test -z "$warnflags" ||
cflagspat="$cflagspat;s|"`eval echo '"'"${warnflags}"'"' | sed 's/[[][|.*]]/\\&/g;s/^ */ /;s/ *$/ /'`'| |g'
AS_IF([test -z "${CFLAGS+set}"], [
cflags=`echo " $cflags " | sed "$cflagspat;s/^ *//;s/ *$//"`
orig_cflags="$cflags"
cflags="$cflags "'${optflags} ${debugflags} ${warnflags}'
])
-AS_IF([test -z "${CXXFLAGS+set}"], [
- cxxflags=`echo " $cxxflags " | sed "$cflagspat;s/^ *//;s/ *$//"`
- orig_cxxflags="$cxxflags"
- cxxflags="$cxxflags "'${optflags} ${debugflags} ${warnflags}'
-])
+dnl AS_IF([test -z "${CXXFLAGS+set}"], [
+dnl cxxflags=`echo " $cxxflags " | sed "$cflagspat;s/^ *//;s/ *$//"`
+dnl orig_cxxflags="$cxxflags"
+dnl cxxflags="$cxxflags "'${optflags} ${debugflags} ${warnflags}'
+dnl ])
-RUBY_NACL
AS_CASE(["$host_os:$build_os"],
[darwin*:darwin*], [
- AC_CHECK_TOOLS(CC, [clang gcc cc])
# Following Apple deployed clang are broken
# clang version 1.0 (http://llvm.org/svn/llvm-project/cfe/tags/Apple/clang-23 exported)
# Apple clang version 2.0 (tags/Apple/clang-137) (based on LLVM 2.9svn)
# Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn)
- AS_IF([! $CC -E -xc - <<SRC >/dev/null], [
- @%:@if defined __APPLE_CC__ && defined __clang_major__ && __clang_major__ < 3
- @%:@error premature clang
- @%:@endif
-SRC
- AC_MSG_ERROR([clang version 3.0 or later is required])
- ])
-])
-AS_IF([test x"${build}" != x"${host}"], [
- AC_CHECK_TOOL(CC, gcc)
+ AC_PREPROC_IFELSE(
+ [AC_LANG_PROGRAM([
+ @%:@if defined __APPLE_CC__ && defined __clang_major__ && __clang_major__ < 3
+ @%:@error premature clang
+ @%:@endif
+ ])],
+ [],
+ [AC_MSG_ERROR([clang version 3.0 or later is required])])
])
-AC_PROG_CC
-
-dnl Select the appropriate C++ compiler in OS X
-AS_CASE(["$build_os"],
- [darwin1*.*], [
- AS_CASE(["x$CC"],
- [xgcc-4.2|x/usr/bin/gcc-4.2], [: ${CXX=g++-4.2}],
- [xgcc|x/usr/bin/gcc], [: ${CXX=g++}],
- [xcc|x/usr/bin/cc], [: ${CXX=c++}],
- [xicc], [: ${CXX=icpc}],
- [xclang|x/usr/bin/clang], [: ${CXX=clang++}])
- ])
-test -z "$CXX" || ac_cv_prog_CXX="$CXX"
+AS_CASE(["$target_os"],
+[darwin*], [
+ AC_MSG_CHECKING(if minimum required OS X version is supported)
+ AC_PREPROC_IFELSE([AC_LANG_SOURCE([[@%:@include <AvailabilityMacros.h>
+ @%:@if MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_5
+ @%:@error pre OS X 10.5
+ [!<===== pre OS X 10.5 =====>]
+ @%:@endif
+ ]])],
+ [macosx_min_required=yes],
+ [AC_MSG_RESULT(no)
+ AC_MSG_ERROR([Unsupported OS X version is required])])
+ AC_MSG_RESULT(${macosx_min_required})
+])
-AC_PROG_CXX
RUBY_MINGW32
-AC_PROG_GCC_TRADITIONAL
AC_SUBST(GCC)
-AS_CASE(["$target_os"],
-[solaris*], [AC_PATH_TOOL([LD], [ld], [/usr/ccs/bin/ld], [/usr/ccs/bin:$PATH])],
-[AC_CHECK_TOOL([LD], [ld], [ld])])
AC_SUBST(LD)
AS_IF([test "$GCC" = yes], [
linker_flag=-Wl,
@@ -521,11 +337,25 @@ AS_IF([test "$GCC" = yes], [
gcc_minor=`echo =__GNUC_MINOR__ | $CC -E -xc - | sed '/^=/!d;s///'`
test -n "$gcc_major" || gcc_major=0
test -n "$gcc_minor" || gcc_minor=0
+ icc_version=`echo =__ICC | $CC -E -xc - | sed '/^=/!d;s///;/^__ICC/d'`
+ test -n "$icc_version" || icc_version=0
# RUBY_APPEND_OPTIONS(XCFLAGS, ["-include ruby/config.h" "-include ruby/missing.h"])
], [
linker_flag=
])
+AS_IF([test "$GCC" = yes -a "$gcc_major" -lt 3 ], [
+ AC_MSG_ERROR([too old GCC])
+])
+
+
+AC_CACHE_CHECK([if thread-local storage is supported], [rb_cv_tls_supported],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[int __thread conftest;]])],
+ [rb_cv_tls_supported=yes],
+ [rb_cv_tls_supported=no])])
+AS_IF([test x"$rb_cv_tls_supported" != xyes],
+ [AC_DEFINE(RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED)])
+
RUBY_PROG_GNU_LD
RUBY_CPPOUTFILE
@@ -536,6 +366,35 @@ AC_SUBST(OUTFLAG)
AC_SUBST(COUTFLAG)
AC_SUBST(CSRCFLAG)
+: ${MJIT_CC=$CC}
+AS_IF([test "x$cross_compiling" = xno], [
+ AC_PATH_PROG([MJIT_CC], ${MJIT_CC})
+
+ # if $CC is in /usr/lib/ccache/$CC, search original $CC (disable ccache)
+ AS_IF([echo $RUBY_DEBUG | grep ci > /dev/null &&
+ echo $MJIT_CC | grep ^/usr/lib/ccache > /dev/null], [
+ PATH=`echo $PATH | sed "s/\/usr\/lib\/ccache://"` MJIT_CC=`which $CC`])
+
+ AS_CASE([$target_os],
+ [*mingw*], [command -v cygpath > /dev/null && MJIT_CC=`cygpath -ma $MJIT_CC`])
+ shift 2
+ MJIT_CC="$MJIT_CC${1+ }$*"
+])
+
+AS_CASE(["$build_os"],
+ [darwin1*.*], [
+ # Xcode linker warns for deprecated architecture and wrongly
+ # installed TBD files.
+ CC_WRAPPER=""
+ echo 'int main(void) {return 0;}' > conftest.c
+ AS_IF([$CC -framework Foundation -o conftest conftest.c 2>&1 |
+ grep '^ld: warning: text-based stub file' >/dev/null], [
+ CC_WRAPPER=`cd -P "${tooldir}" && pwd`/darwin-cc
+ CC="$CC_WRAPPER $CC"
+ ])
+ rm -fr conftest*
+ ])
+
cc_version=
for option in --version -v -V -qversion; do
cc_version_message=`$CC $option 2>&1`
@@ -548,62 +407,25 @@ done
AC_SUBST(CC_VERSION, $cc_version)
AC_SUBST(CC_VERSION_MESSAGE, $cc_version_message)
+: ${DLDFLAGS="$LDFLAGS"}
+
RUBY_UNIVERSAL_ARCH
-AS_IF([test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "$cross_compiling" = no -a "$universal_binary" = no], [
+AS_IF([test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "$cross_compiling" = no -a "${universal_binary:-no}" = no], [
RUBY_DEFAULT_ARCH("$target_cpu")
])
+host_os=$target_os
+host_vendor=$target_vendor
+host_cpu=$target_cpu
+host=$target
+host_alias=$target_alias
-AS_CASE(["$target_cpu-$target_os"], [[i[3-6]86*]], [
- AC_CACHE_CHECK([for __sync_val_compare_and_swap], [rb_cv_gcc_compiler_cas], [
- AC_TRY_LINK([unsigned long atomic_var;],
- [
- __sync_val_compare_and_swap(&atomic_var, 0, 1);
- ],
- [rb_cv_gcc_compiler_cas=yes],
- [rb_cv_gcc_compiler_cas=no])])
- AS_IF([test "$rb_cv_gcc_compiler_cas" = no], [
- unset rb_cv_gcc_compiler_cas
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -march=i486"
- AC_CACHE_CHECK([for __sync_val_compare_and_swap with -march=i486], [rb_cv_gcc_compiler_cas], [
- AC_TRY_LINK([unsigned long atomic_var;],
- [
- __sync_val_compare_and_swap(&atomic_var, 0, 1);
- ],
- [rb_cv_gcc_compiler_cas=yes
- ARCH_FLAG="-march=i486"],
- [rb_cv_gcc_compiler_cas=no])])
- CFLAGS="$save_CFLAGS"
- ])])
-
-AS_CASE(["$target_os"], [darwin*], [
-if libtool 2>&1 | grep no_warning_for_no_symbols > /dev/null; then
- ac_cv_prog_ac_ct_RANLIB=:
- ac_cv_prog_ac_ct_AR='libtool -static'
- rb_cv_arflags='-no_warning_for_no_symbols -o'
-fi
-])
-AC_CHECK_TOOL(RANLIB, ranlib, :)
-AC_CHECK_TOOL(AR, ar)
-AS_IF([test -z "$AR"], [
- AC_CHECK_PROGS(AR, aal, ar)
-])
AC_CACHE_CHECK([for $AR flags], [rb_cv_arflags], [
AS_IF([$AR rcD conftest.a > /dev/null 2>&1 && rm conftest.a],
[rb_cv_arflags=rcD], [rb_cv_arflags=rcu])
])
AC_SUBST(ARFLAGS, ["$rb_cv_arflags "])
-
-AC_CHECK_TOOL(AS, as)
-ASFLAGS=$ASFLAGS
AC_SUBST(ASFLAGS)
-AS_CASE(["$target_os"],[cygwin*|mingw*], [ac_cv_prog_ac_ct_OBJCOPY=":"])
-
-# BSD's ports and MacPorts prefix GNU binutils with 'g'
-AC_CHECK_TOOLS(OBJDUMP, [objdump gobjdump])
-AC_CHECK_TOOLS(OBJCOPY, [objcopy gobjcopy])
-
AS_CASE(["$target_os"],
[cygwin*|mingw*], [
AC_CHECK_TOOL(WINDRES, windres)
@@ -617,8 +439,8 @@ AS_CASE(["$target_os"],
[mingw*], [
test "$rb_cv_msvcrt" = "" && unset rb_cv_msvcrt
AC_CACHE_CHECK(for mingw32 runtime DLL, rb_cv_msvcrt, [
- AC_TRY_LINK([@%:@include <stdio.h>],
- [FILE* volatile f = stdin; return 0;],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <stdio.h>]],
+ [[FILE* volatile f = stdin; return 0;]])],
[rb_cv_msvcrt=`$OBJDUMP -p conftest$ac_exeext |
tr A-Z a-z |
sed -n '/^[[ ]]*dll name: \(msvc.*\)\.dll$/{s//\1/p;q;}'`],
@@ -627,12 +449,11 @@ AS_CASE(["$target_os"],
RT_VER=`echo "$rb_cv_msvcrt" | tr -cd [0-9]`
test "$RT_VER" = "" && RT_VER=60
AC_DEFINE_UNQUOTED(RUBY_MSVCRT_VERSION, $RT_VER)
+ sysconfdir=
])
: ${enable_shared=yes}
],
-[aix*], [AC_CHECK_TOOL(NM, nm, /usr/ccs/bin/nm, /usr/ccs/bin:$PATH)],
[hiuxmpp*], [AC_DEFINE(__HIUX_MPP__)]) # by TOYODA Eizi <toyoda@npd.kishou.go.jp>
-AC_CHECK_TOOL(NM, nm)
AC_PROG_LN_S
AC_PROG_MAKE_SET
@@ -649,56 +470,6 @@ AS_IF([test "x$MKDIR_P" = "x -d"], [
MAKEDIRS="$MKDIR_P"
AC_SUBST(MAKEDIRS)
-AC_DEFUN([RUBY_DTRACE_AVAILABLE],
-[AC_CACHE_CHECK(whether dtrace USDT is available, rb_cv_dtrace_available,
-[
- echo "provider conftest{ probe fire(); };" > conftest_provider.d
- rb_cv_dtrace_available=no
- AS_FOR(opt, rb_dtrace_opt, ["-xnolibs" ""], [dnl
- AS_IF([$DTRACE opt -h -o conftest_provider.h -s conftest_provider.d >/dev/null 2>/dev/null],
- [], [continue])
- AC_TRY_COMPILE([@%:@include "conftest_provider.h"], [CONFTEST_FIRE();],
- [], [continue])
- # DTrace is available on the system
- rb_cv_dtrace_available=yes${rb_dtrace_opt:+"(opt)"}
- break
- ])
- rm -f conftest.[co] conftest_provider.[dho]
-])
-AS_CASE(["$rb_cv_dtrace_available"], ["yes("*")"],
- [DTRACE_OPT=`expr "$rb_cv_dtrace_available" : "yes(\(.*\))"`])
-])
-
-AC_DEFUN([RUBY_DTRACE_POSTPROCESS],
-[AC_CACHE_CHECK(whether $DTRACE needs post processing, rb_cv_prog_dtrace_g,
-[
- rb_cv_prog_dtrace_g=no
- AS_IF([{
- cat >conftest_provider.d <<_PROBES &&
- provider conftest {
- probe fire();
- };
-_PROBES
- $DTRACE ${DTRACE_OPT} -h -o conftest_provider.h -s conftest_provider.d >/dev/null 2>/dev/null &&
- :
- }], [
- AC_TRY_COMPILE([@%:@include "conftest_provider.h"], [CONFTEST_FIRE();], [
- AS_IF([{
- cp -p conftest.${ac_objext} conftest.${ac_objext}.save &&
- $DTRACE ${DTRACE_OPT} -G -s conftest_provider.d conftest.${ac_objext} 2>/dev/null &&
- :
- }], [
- AS_IF([cmp -s conftest.o conftest.${ac_objext}.save], [
- rb_cv_prog_dtrace_g=yes
- ], [
- rb_cv_prog_dtrace_g=rebuild
- ])
- ])])
- ])
- rm -f conftest.[co] conftest_provider.[dho]
-])
-])
-
AC_CHECK_PROG([DTRACE], [${ac_tool_prefix}dtrace], [${ac_tool_prefix}dtrace])
AS_IF([test "$cross_compiling:$ac_cv_prog_DTRACE" = no: -a -n "$ac_tool_prefix"], [
AC_CHECK_PROG([DTRACE], [dtrace], [dtrace])
@@ -706,13 +477,29 @@ AS_IF([test "$cross_compiling:$ac_cv_prog_DTRACE" = no: -a -n "$ac_tool_prefix"]
AC_CHECK_PROGS(DOT, dot)
AC_CHECK_PROGS(DOXYGEN, doxygen)
-AS_CASE(["${host_os}"], [nacl], [AC_PATH_PROG(PYTHON, python)])
-AC_CHECK_PROG(PKG_CONFIG, pkg-config, [pkg-config], [], [],
- [`"$as_dir/$ac_word$ac_exec_ext" --print-errors --version > /dev/null 2>&1 || echo "$as_dir/$ac_word$ac_exec_ext"`])
+for prog in ${ac_tool_prefix:+${ac_tool_prefix}pkg-config} pkg-config; do
+ AC_CHECK_PROG(PKG_CONFIG, $prog, [$prog], [], [],
+ [`"$as_dir/$ac_word$ac_exec_ext" --print-errors --version > /dev/null 2>&1 || echo "$as_dir/$ac_word$ac_exec_ext"`])
+ test -z "${PKG_CONFIG}" || break
+done
-# checks for UNIX variants that set C preprocessor variables
-AC_USE_SYSTEM_EXTENSIONS
+AC_MSG_CHECKING([whether it is Android])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@ifdef __ANDROID__
+ @%:@error android
+ @%:@endif
+]], [[]])],
+[AC_MSG_RESULT(no)],
+[
+ AC_MSG_RESULT(yes)
+ target_os=${target_os}-android
+ AC_MSG_CHECKING([for Android API version])
+ # hacky workaround: https://github.com/termux/termux-packages/issues/6176
+ rb_android_api=`getprop ro.build.version.sdk`
+ AC_MSG_RESULT($rb_android_api)
+ RUBY_APPEND_OPTIONS(CPPFLAGS, -D__ANDROID_API__=$rb_android_api -Wno-macro-redefined)
+])
AC_SUBST(RM, ['rm -f'])
AC_SUBST(CP, ['cp'])
@@ -744,37 +531,19 @@ AS_IF([test -f conf$$.dir/src/cdcmd], [
rm -fr conf$$.dir
AC_MSG_RESULT([$CHDIR])
AC_SUBST(CHDIR)
-
}
-{ # compiler section
-
-AC_DEFUN([RUBY_WERROR_FLAG], [dnl
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $rb_cv_warnflags"
-AS_IF([test "${ac_c_werror_flag+set}"], [
- rb_c_werror_flag="$ac_c_werror_flag"
-], [
- unset rb_c_werror_flag
-])
-ac_c_werror_flag=yes
-$1
-CFLAGS="$save_CFLAGS"
-save_CFLAGS=
-AS_IF([test "${rb_c_werror_flag+set}"], [
- ac_c_werror_flag="$rb_c_werror_flag"
-], [
- unset ac_c_werror_flag
-])])
+: "compiler section" && {
RUBY_WERROR_FLAG([
AC_MSG_CHECKING([whether CFLAGS is valid])
- AC_TRY_COMPILE([], [],
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[AC_MSG_RESULT(yes)],
[
AC_MSG_RESULT(no)
AC_MSG_ERROR([something wrong with CFLAGS="$CFLAGS"])
]
)
+
AC_MSG_CHECKING([whether LDFLAGS is valid])
{
mkdir tmp.$$.try_link &&
@@ -783,7 +552,7 @@ RUBY_WERROR_FLAG([
echo '<?xml?><plist><dict><key>CFBundleIdentifier</key><string></string></dict></plist>' > Info.plist &&
:
} || AC_MSG_ERROR([failed to make temporary directory])
- AC_TRY_LINK([], [],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[AC_MSG_RESULT(yes)],
[
cd .. && rm -fr tmp.$$.try_link
@@ -794,34 +563,6 @@ RUBY_WERROR_FLAG([
cd .. && rm -fr tmp.$$.try_link
])
-AC_DEFUN([RUBY_TRY_CFLAGS], [
- AC_MSG_CHECKING([whether ]$1[ is accepted as CFLAGS])
- RUBY_WERROR_FLAG([
- CFLAGS="[$]CFLAGS $1"
- AC_TRY_COMPILE([$4], [$5],
- [$2
- AC_MSG_RESULT(yes)],
- [$3
- AC_MSG_RESULT(no)])
- ])
-])
-
-AC_DEFUN([RUBY_TRY_LDFLAGS], [
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="[$]LDFLAGS $1"
- AC_MSG_CHECKING([whether $1 is accepted as LDFLAGS])
- RUBY_WERROR_FLAG([
- AC_TRY_LINK([$4], [$5],
- [$2
- AC_MSG_RESULT(yes)],
- [$3
- AC_MSG_RESULT(no)])
- ])
- LDFLAGS="$save_LDFLAGS"
- save_LDFLAGS=
-])
-
-: ${DLDFLAGS="$LDFLAGS"}
: ${RPATHFLAG=''}
rpathflag=''
AS_IF([test x"${RPATHFLAG}" = x], [
@@ -840,6 +581,12 @@ AS_IF([test x"${RPATHFLAG}" = x], [
rpathflag=`echo "$RPATHFLAG" | sed 's/%.*//'`
])
+RUBY_TRY_CFLAGS(-fdeclspec, [
+ RUBY_APPEND_OPTIONS(CC, -fdeclspec)
+ RUBY_APPEND_OPTIONS(MJIT_CC, -fdeclspec)
+])
+RUBY_TRY_CXXFLAGS(-fdeclspec, [RUBY_APPEND_OPTIONS(CXX, -fdeclspec)])
+
AS_CASE([$RUBY_PATCHLEVEL], [-*],
[RUBY_DEVEL=yes], [RUBY_DEVEL=no])
particular_werror_flags=$RUBY_DEVEL
@@ -851,36 +598,46 @@ AC_ARG_ENABLE(werror,
[particular_werror_flags=$enableval])
rb_cv_warnflags="$warnflags"
-AS_IF([test "$GCC:${warnflags+set}:no" = yes::no], [
+AS_CASE(["$GCC:${warnflags+set}:${extra_warnflags:+set}:"],
+[yes::*|yes:*:set:], [# GCC && (!warnflags || extra_warnflags)
AS_IF([test $gcc_major -ge 4], [
- extra_warning=-Werror=extra-tokens
- ], [
- extra_warning=
+ extra_warnflags="$extra_warnflags -Werror=extra-tokens"
])
AS_IF([test $gcc_major -ge 5 -a $gcc_major -le 6], [
- extra_warning="$extra_warning -Wno-maybe-uninitialized"
+ extra_warnflags="$extra_warnflags -Wno-maybe-uninitialized"
])
- for wflag in -Wno-unused-parameter -Wno-parentheses -Wno-long-long \
- -diag-disable=2259 \
- -Wno-missing-field-initializers \
- -Wno-tautological-compare \
- -Wno-parentheses-equality \
- -Wno-constant-logical-operand \
- -Wno-self-assign \
- -Wunused-variable \
+ # ICC doesn't support -Werror=
+ AS_IF([test $icc_version -gt 0], [
+ particular_werror_flags=no
+ ])
+ for wflag in \
+ -Werror=deprecated-declarations \
+ -Werror=division-by-zero \
+ -Werror=duplicated-cond \
+ -Werror=implicit-function-declaration \
-Werror=implicit-int \
+ -Werror=misleading-indentation \
-Werror=pointer-arith \
- -Werror=write-strings \
- -Werror=declaration-after-statement \
-Werror=shorten-64-to-32 \
- -Werror=implicit-function-declaration \
- -Werror=division-by-zero \
- -Werror=deprecated-declarations \
+ -Werror=write-strings \
+ -Wimplicit-fallthrough=0 \
+ -Wmissing-noreturn \
+ -Wno-cast-function-type \
+ -Wno-constant-logical-operand \
+ -Wno-long-long \
+ -Wno-missing-field-initializers \
+ -Wno-overlength-strings \
-Wno-packed-bitfield-compat \
- -Wsuggest-attribute=noreturn \
+ -Wno-parentheses-equality \
+ -Wno-self-assign \
+ -Wno-tautological-compare \
+ -Wno-unused-parameter \
+ -Wno-unused-value \
-Wsuggest-attribute=format \
- -Wimplicit-fallthrough=0 \
- $extra_warning \
+ -Wsuggest-attribute=noreturn \
+ -Wunused-variable \
+ -diag-disable=175,188,1684,2259,2312 \
+ $extra_warnflags \
; do
AS_IF([test "$particular_werror_flags" != yes], [
wflag=`echo x$wflag | sed 's/^x-Werror=/-W/;s/^x//'`
@@ -906,20 +663,22 @@ AS_IF([test "$GCC:${warnflags+set}:no" = yes::no], [
warnflags=
])
RUBY_TRY_CFLAGS(-Qunused-arguments, [RUBY_APPEND_OPTIONS(rb_cv_wsuppress_flags, -Qunused-arguments)])
-
-for n in infinity nan; do
- m=AS_TR_CPP($n)
- AC_CACHE_CHECK([whether $m is available without C99 option], rb_cv_$n,
- [AC_COMPILE_IFELSE(
- [AC_LANG_BOOL_COMPILE_TRY(AC_INCLUDES_DEFAULT([@%:@include <math.h>
-@%:@ifndef $m
-@%:@error no $m
-@%:@endif
-]), [1])], [eval rb_cv_$n=yes], [eval rb_cv_$n=no])])
- AS_IF([eval test '"$rb_cv_'$n'"' = yes], [
- AC_DEFINE_UNQUOTED([HAVE_]$m)
- ])
-done
+AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([
+@%:@if !(defined(__SUNPRO_C)||defined(__SUNPRO_CC))
+@%:@error not sunpro
+@%:@endif],[])], [
+ for e in \
+ E_STATEMENT_NOT_REACHED \
+ E_INIT_SIGN_EXTEND \
+ E_INIT_DOES_NOT_FIT \
+ E_INITIALIZATION_TYPE_MISMATCH
+ do
+ RUBY_TRY_CFLAGS([-erroff=${e}], [
+ RUBY_APPEND_OPTIONS(rb_cv_warnflags, [-erroff=${e}])
+ ])
+ done
+])
AC_ARG_WITH(compress-debug-sections,
AS_HELP_STRING([--with-compress-debug-sections=type],
@@ -927,32 +686,46 @@ AC_ARG_WITH(compress-debug-sections,
[compress_debug_sections=$withval], [compress_debug_sections=])
AS_IF([test "$GCC" = yes], [
- # NaCl's glibc build generates undefined references to __memset_chk.
- # TODO(sbc): Remove this once NaCl's glibc is fixed.
- AS_CASE(["$target_os"], [nacl], [], [
- # -D_FORTIFY_SOURCE
- # When defined _FORTIFY_SOURCE, glibc enables some additional sanity
- # argument check. The performance drop is very little and Ubuntu enables
- # _FORTIFY_SOURCE=2 by default. So, let's support it for protecting us from
- # a mistake of silly C extensions.
- RUBY_TRY_CFLAGS(-D_FORTIFY_SOURCE=2, [RUBY_APPEND_OPTION(XCFLAGS, -D_FORTIFY_SOURCE=2)])
- ])
+ # -D_FORTIFY_SOURCE
+ # When defined _FORTIFY_SOURCE, glibc enables some additional sanity
+ # argument check. The performance drop is very little and Ubuntu enables
+ # _FORTIFY_SOURCE=2 by default. So, let's support it for protecting us from
+ # a mistake of silly C extensions.
+
+ # TODO: check if link succeeds with _FORTIFY_SOURCE=2.
+ AS_CASE(["$target_os"],
+ [mingw*], [
+ fortify_source=no
+ ])
+ AC_ARG_ENABLE(fortify_source,
+ AS_HELP_STRING([--disable-fortify-source],
+ [disable -D_FORTIFY_SOURCE=2 option, which causes link error on mingw]),
+ [fortify_source=$enableval])
+ AS_IF([test "x$fortify_source" != xno], [
+ RUBY_TRY_CFLAGS([$optflags -D_FORTIFY_SOURCE=2], [RUBY_APPEND_OPTION(XCFLAGS, -D_FORTIFY_SOURCE=2)], [],
+ [@%:@include <stdio.h>])
+ ])
+
+ : ${MJIT_HEADER_FLAGS='-P -dD'}
# -fstack-protector
AS_CASE(["$target_os"],
- [mingw*|nacl], [
+ [mingw*|haiku*], [
stack_protector=no
])
AS_IF([test -z "${stack_protector+set}"], [
- RUBY_TRY_CFLAGS(-fstack-protector, [stack_protector=yes], [stack_protector=no])
- AS_IF([test "x$stack_protector" = xyes], [
- RUBY_TRY_LDFLAGS(-fstack-protector, [], [stack_protector=broken])
+ AS_FOR(option, opt, [-fstack-protector-strong -fstack-protector], [
+ RUBY_TRY_CFLAGS(option, [stack_protector=yes])
+ AS_IF([test "x$stack_protector" = xyes], [
+ RUBY_TRY_LDFLAGS(option, [], [stack_protector=])
+ ])
+ AS_IF([test "x$stack_protector" = xyes], [stack_protector=option; break])
])
])
- AS_IF([test "x$stack_protector" = xyes], [
- RUBY_APPEND_OPTION(XCFLAGS, -fstack-protector)
- RUBY_APPEND_OPTION(XLDFLAGS, -fstack-protector)
- RUBY_APPEND_OPTION(LDFLAGS, -fstack-protector)
+ AS_CASE(["$stack_protector"], [-*], [
+ RUBY_APPEND_OPTION(XCFLAGS, $stack_protector)
+ RUBY_APPEND_OPTION(XLDFLAGS, $stack_protector)
+ RUBY_APPEND_OPTION(LDFLAGS, $stack_protector)
])
AS_CASE("${compress_debug_sections:-zlib}",
@@ -972,7 +745,7 @@ AS_IF([test "$GCC" = yes], [
# comments. We bypass ANSI C mode for them. Otherwise
# extension libs cannot include those headers.
- # Since math.h in some mingw64 wrongly delcares frexp and modf
+ # Since math.h in some mingw64 wrongly declares frexp and modf
# to be pure, the variables pointed by the second arguments are
# considered uninitialized unexpectedly.
AC_CACHE_CHECK([whether frexp and modf are broken],
@@ -984,13 +757,13 @@ AS_IF([test "$GCC" = yes], [
], [
CFLAGS="$CFLAGS -Werror -Wuninitialized"
])
- AC_TRY_COMPILE([@%:@include <math.h>
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <math.h>
int foo(double x)
{
int exp;
frexp(x, &exp);
return exp;
- }], [if (foo(0.0)) return 1;],
+ }]], [[if (foo(0.0)) return 1;]])],
[rb_cv_mingw64_broken_frexp_modf=no],
[rb_cv_mingw64_broken_frexp_modf=yes])
CFLAGS="$save_CFLAGS"
@@ -999,11 +772,27 @@ AS_IF([test "$GCC" = yes], [
AC_DEFINE(RUBY_MINGW64_BROKEN_FREXP_MODF)
])
],
- [cygwin*|darwin*|netbsd*|nacl], [
+ [cygwin*|darwin*|netbsd*], [
# need lgamma_r(), finite()
+ ])
+
+ # ANSI (no XCFLAGS because this is C only)
+ AS_CASE(["$target_os"],
+ [solaris*], [
+ # Because "-std=gnu99" affects existence of functions on Solaris,
+ # "-std=gnu99" will be appended to CPPFLAGS.
+ for ansi_options in -std=gnu99; do
+ RUBY_TRY_CFLAGS(${ansi_options}, [
+ RUBY_APPEND_OPTIONS(CPPFLAGS, ${ansi_options})
+ ], [ansi_options=])
+ test "x${ansi_options}" = x || break
+ done
],
[
# ANSI (no XCFLAGS because this is C only)
+ rb_tmp_std_check=`echo $CC $CFLAGS $optflags $warnflags $debugflags | fgrep std= | tr -d '\015'`
+ AS_IF([test "x$rb_tmp_std_check" = "x"],
+ [
for ansi_options in -std=gnu99; do
RUBY_TRY_CFLAGS(${ansi_options}, [
RUBY_APPEND_OPTIONS(warnflags, ${ansi_options})
@@ -1011,6 +800,7 @@ AS_IF([test "$GCC" = yes], [
], [ansi_options=])
test "x${ansi_options}" = x || break
done
+ ])
])
# suppress annoying -Wstrict-overflow warnings
@@ -1038,7 +828,7 @@ AS_IF([test "$GCC" = yes], [
], [
RUBY_TRY_LDFLAGS([-Wl,-unexported_symbol,_Init_*], [visibility_option=ld], [visibility_option=no])
])
- test "$visibility_option" = no -o "$host_os" = nacl || OBJCOPY=:
+ test "$visibility_option" = no || OBJCOPY=:
])
AS_IF([test "$GCC" = yes], [
@@ -1061,6 +851,23 @@ AS_IF([test "$GCC" = yes], [
done
])
+AS_CASE(["$target_cpu"], [[i[3-6]86*]], [
+ AC_CACHE_CHECK([for __sync_val_compare_and_swap], [rb_cv_gcc_compiler_cas], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[unsigned long atomic_var;]],
+ [[__sync_val_compare_and_swap(&atomic_var, 0, 1);]])],
+ [rb_cv_gcc_compiler_cas=yes],
+ [
+ save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -march=i486"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[unsigned long atomic_var;]],
+ [[__sync_val_compare_and_swap(&atomic_var, 0, 1);]])],
+ [rb_cv_gcc_compiler_cas=i486],
+ [rb_cv_gcc_compiler_cas=no])
+ CFLAGS="$save_CFLAGS"
+ ])
+ ])
+ AS_IF([test "$rb_cv_gcc_compiler_cas" = i486], [ARCH_FLAG="-march=i486"])
+])
+
AC_ARG_WITH(opt-dir,
AS_HELP_STRING([--with-opt-dir=DIR-LIST],
[add optional headers and libraries directories separated by $PATH_SEPARATOR]),
@@ -1075,13 +882,21 @@ AC_ARG_WITH(opt-dir,
test -z "${ac_env_CFLAGS_set}" -a -n "${cflags+set}" && eval CFLAGS="\"$cflags $ARCH_FLAG\""
test -z "${ac_env_CXXFLAGS_set}" -a -n "${cxxflags+set}" && eval CXXFLAGS="\"$cxxflags $ARCH_FLAG\""
-
}
-{ # header and library section
+AC_CACHE_CHECK([whether compiler has statement and declarations in expressions],
+ rb_cv_have_stmt_and_decl_in_expr,
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[ __extension__ ({ int a = 0; a; }); ]])],
+ [rb_cv_have_stmt_and_decl_in_expr=yes],
+ [rb_cv_have_stmt_and_decl_in_expr=no])])
+AS_IF([test "$rb_cv_have_stmt_and_decl_in_expr" = yes], [
+ AC_DEFINE(HAVE_STMT_AND_DECL_IN_EXPR)
+])
+
+: "header and library section" && {
AC_ARG_WITH(winnt-ver,
- AS_HELP_STRING([--with-winnt-ver=0xXXXX], [target Windows NT version (default to 0x0501)]),
- [with_winnt_ver="$withval"], [with_winnt_ver="0x0501"])
+ AS_HELP_STRING([--with-winnt-ver=0xXXXX], [target Windows NT version (default to 0x0600)]),
+ [with_winnt_ver="$withval"], [with_winnt_ver="0x0600"])
AS_CASE(["$target_os"],
[mingw*], [
RUBY_APPEND_OPTION(CPPFLAGS, -D_WIN32_WINNT=$with_winnt_ver)
@@ -1092,12 +907,12 @@ AS_CASE(["$target_os"],
[freebsd*], [
AC_CACHE_CHECK([whether pthread should be enabled by default],
rb_cv_enable_pthread_default,
- [AC_TRY_CPP([
+ [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
#include <osreldate.h>
#if __FreeBSD_version < 502102
#error pthread should be disabled on this platform
#endif
- ],
+ ]])],
rb_cv_enable_pthread_default=yes,
rb_cv_enable_pthread_default=no)])
enable_pthread=$rb_cv_enable_pthread_default
@@ -1112,36 +927,31 @@ AS_CASE(["$target_os"],
dnl Checks for libraries.
AS_CASE(["$target_os"],[*bsd*|dragonfly*],[],[ac_cv_func_daemon=no])
+AS_UNSET(ORIG_LIBS)
POSTLINK=:
AC_SUBST(POSTLINK)
AS_CASE(["$target_os"],
[nextstep*], [ ],
[openstep*], [ ],
[rhapsody*], [ ],
-[darwin*], [ RUBY_PREPEND_OPTION(LIBS, -lobjc)
+[darwin*], [
+ ORIG_LIBS="$LIBS"
+ RUBY_PREPEND_OPTION(LIBS, -lobjc)
RUBY_APPEND_OPTIONS(CPPFLAGS, -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT)
- AC_MSG_CHECKING(whether Mac OS X 10.5 or later)
- AC_TRY_CPP([#include <AvailabilityMacros.h>
- #if MAC_OS_X_VERSION_MAX_ALLOWED <= 1040
- #error pre OS X 10.4
- [!<===== pre OS X 10.4 =====>]
- #endif
- ],
- [macosx_10_5=yes], [macosx_10_5=no])
- AC_MSG_RESULT($macosx_10_5)
- AS_IF([test "${target_os@%:@darwin}" -ge 16], [
+ AC_CACHE_CHECK([whether syscall(2) is deprecated], rb_cv_syscall_deprecated,
+ [RUBY_WERROR_FLAG([
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <unistd.h>]],
+ [[if (syscall(0)) return 1;]])],
+ [rb_cv_syscall_deprecated=no],
+ [rb_cv_syscall_deprecated=yes])])])
+ AS_IF([test $rb_cv_syscall_deprecated = yes], [
ac_cv_func___syscall=no
ac_cv_func_syscall=no
ac_cv_header_sys_syscall_h=no
ac_cv_header_syscall_h=no
])
- AS_IF([test $macosx_10_5 = yes], [
- ac_cv_func_getcontext=no
- ac_cv_func_setcontext=no
- ], [
- AC_DEFINE(BROKEN_SETREUID, 1)
- AC_DEFINE(BROKEN_SETREGID, 1)
- ])
+ ac_cv_func_getcontext=no
+ ac_cv_func_setcontext=no
incs=`$CC -v -E -xc - < /dev/null 2>&1 | sed ['1,/^@%:@include </d;s/^ *//;s|[^./][^/]*/\.\./||g;/\/include$/!d;s||/lib|;/\/usr\/lib/d']`
for d in `$CC -print-search-dirs | sed -e '/^libraries: */!d;s///' | tr : '\012' | fgrep -v /../ | sed -n 's|^\(/.*/lib\)/$|\1|p'`; do
incs=`echo "$incs" | fgrep -v "$d"`
@@ -1156,8 +966,9 @@ AS_CASE(["$target_os"],
AS_IF([test $gcc_major -lt 4 -o \( $gcc_major -eq 4 -a $gcc_minor -lt 3 \)], [
ac_cv_func___builtin_setjmp=no
])
+ with_setjmp_type=sigsetjmp # to hijack SIGCHLD handler
AC_CACHE_CHECK(for broken crypt with 8bit chars, rb_cv_broken_crypt,
- [AC_TRY_RUN([
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -1194,7 +1005,7 @@ main()
}
return 0;
}
-],
+]])],
rb_cv_broken_crypt=no,
rb_cv_broken_crypt=yes,
rb_cv_broken_crypt=yes)])
@@ -1223,45 +1034,29 @@ main()
[solaris*], [ LIBS="-lm $LIBS"
ac_cv_func_vfork=no
AC_MSG_CHECKING(whether _XOPEN_SOURCE is already given)
- AC_TRY_COMPILE([#include <unistd.h>
- #ifndef _XOPEN_SOURCE
- #error _XOPEN_SOURCE is not defined
- #endif
- ], [],
- [given_xopen_source=yes], [given_xopen_source=no])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>
+ #ifndef _XOPEN_SOURCE
+ #error _XOPEN_SOURCE is not defined
+ #endif
+ ]], [[]])],
+ [given_xopen_source=yes], [given_xopen_source=no])
AC_MSG_RESULT($given_xopen_source)
AS_IF([test $given_xopen_source = no], [
- # On Solaris, with gcc, -std=iso9899:1999 in $ansi_options
- # is often also needed in CPPFLAGS, because some feature
- # definitions vary depending on such standards options.
- AS_CASE(["${ansi_options}"],
- [*-std=iso9899:1999*], [
- RUBY_APPEND_OPTIONS(CPPFLAGS, ${ansi_options})
- ])
AC_MSG_CHECKING(appropriate _XOPEN_SOURCE value to define)
define_xopen_source=""
for tmp_xpg in 7 6 5; do
AS_IF([test x"$define_xopen_source" != x], [
- break
+ break
])
- # Both AC_TRY_CPP and AC_TRY_COMPILE should pass
- # because some options may not be set to CPPFLAGS.
- AC_TRY_CPP([
- #define _XOPEN_SOURCE ${tmp_xpg}00
- #include <unistd.h>
- #ifndef _XPG${tmp_xpg}
- #error _XPG${tmp_xpg} should be defined by _XOPEN_SOURCE=${tmp_xpg}00
- #endif
- ], [
- AC_TRY_COMPILE([
+ RUBY_WERROR_FLAG([AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#define _XOPEN_SOURCE ${tmp_xpg}00
#include <unistd.h>
#ifndef _XPG${tmp_xpg}
#error _XPG${tmp_xpg} should be defined by _XOPEN_SOURCE=${tmp_xpg}00
#endif
- ], [],
+ ]], [[]])],
[define_xopen_source=${tmp_xpg}00], [])
- ], [])
+ ])
done
AS_IF([test x"$define_xopen_source" = x], [
define_xopen_source=no
@@ -1269,6 +1064,8 @@ main()
AC_MSG_RESULT($define_xopen_source)
AS_IF([test x"$define_xopen_source" != xno], [
RUBY_APPEND_OPTIONS(CPPFLAGS, -D_XOPEN_SOURCE=$define_xopen_source)
+ # _XOPEN_SOURCE should not be defined for C++ on Solaris.
+ RUBY_APPEND_OPTIONS(CXXFLAGS, -U_XOPEN_SOURCE)
])
])
],
@@ -1297,9 +1094,6 @@ main()
ac_cv_func_fsync=yes
ac_cv_func_seekdir=yes
ac_cv_func_telldir=yes
- ac_cv_func_isinf=yes
- ac_cv_func_isnan=yes
- ac_cv_func_finite=yes
ac_cv_func_lchown=yes
ac_cv_func_link=yes
ac_cv_func_readlink=yes
@@ -1318,9 +1112,12 @@ main()
ac_cv_func_clock_gettime=yes
ac_cv_func_clock_getres=yes
ac_cv_func_malloc_usable_size=no
+ ac_cv_type_off_t=yes
+ ac_cv_sizeof_off_t=8
AS_IF([test "$target_cpu" = x64], [
- ac_cv_func___builtin_setjmp=no
+ ac_cv_func___builtin_setjmp=yes
ac_cv_func_round=no
+ rb_cv_coroutine=yes
])
ac_cv_func_tgamma=no
rb_cv_negative_time_t=yes
@@ -1347,22 +1144,44 @@ main()
[netbsd*], [ LIBS="-lm $LIBS"
],
[dragonfly*], [ LIBS="-lm $LIBS"
- # isinf() and isnan() are macros on DragonFly.
- ac_cv_func_isinf=yes
- ac_cv_func_isnan=yes
],
[aix*],[ LIBS="-lm $LIBS"
ac_cv_func_round=no
+ ac_cv_func___builtin_setjmp=no
+ ],
+[linux*],[ LIBS="-lm $LIBS"
+ # __builtin_longjmp in ppc64* Linux does not restore
+ # the TOC register (r2), which is problematic
+ # when a global exit happens from JITted .so code.
+ AS_CASE(["$target_cpu"], [powerpc64*], [
+ ac_cv_func___builtin_setjmp=no
+ ])
+ # With gcc-8's -fcf-protection, MJIT's __builtin_longjmp fails.
+ AS_CASE(["$CC $CFLAGS "], [*" -fcf-protection "*], [cf_protection=yes], [cf_protection=no])
+ AS_IF([test "$cf_protection" = yes], [
+ ac_cv_func___builtin_setjmp=no
+ ])
],
-[nacl], [
- LIBS="-lm $LIBS"
- AS_IF([test "${nacl_cv_build_variant}" = "newlib"], [
- RUBY_APPEND_OPTION(CPPFLAGS, -DNACL_NEWLIB)
- ], [
- RUBY_APPEND_OPTION(XCFLAGS, -fPIC)
- ])
- ],
[ LIBS="-lm $LIBS"])
+: ${ORIG_LIBS=$LIBS}
+
+AS_IF([test -n "${rb_there_is_in_fact_no_gplusplus_but_autoconf_is_cheating_us}"], [
+ AC_MSG_NOTICE([Test skipped due to lack of a C++ compiler.])
+],
+[test -n "${CXX}"], [
+ RUBY_WERROR_FLAG([
+ AC_MSG_CHECKING([whether CXXFLAGS is valid])
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <cstdio>]], [[]])],
+ [AC_MSG_RESULT(yes)],[
+ AC_MSG_RESULT(no)
+ # The message mentions CXXFLAGS, but CPPFLAGS might also affects.
+ AC_MSG_WARN([something wrong with CXXFLAGS="$CXXFLAGS"])
+ CXX=false
+ ])
+ AC_LANG_POP(C++)
+ ])
+])
AC_CHECK_LIB(crypt, crypt) # glibc (GNU/Linux, GNU/Hurd, GNU/kFreeBSD)
AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV
@@ -1377,6 +1196,7 @@ AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(a.out.h)
AC_CHECK_HEADERS(atomic.h)
+AC_CHECK_HEADERS(copyfile.h)
AC_CHECK_HEADERS(direct.h)
AC_CHECK_HEADERS(grp.h)
AC_CHECK_HEADERS(fcntl.h)
@@ -1392,8 +1212,12 @@ AC_CHECK_HEADERS(malloc_np.h)
AC_CHECK_HEADERS(net/socket.h)
AC_CHECK_HEADERS(process.h)
AC_CHECK_HEADERS(pwd.h)
+AC_CHECK_HEADERS(sanitizer/asan_interface.h)
+AC_CHECK_HEADERS(sanitizer/msan_interface.h)
AC_CHECK_HEADERS(setjmpex.h)
+AC_CHECK_HEADERS(stdalign.h)
AC_CHECK_HEADERS(sys/attr.h)
+AC_CHECK_HEADERS(sys/eventfd.h)
AC_CHECK_HEADERS(sys/fcntl.h)
AC_CHECK_HEADERS(sys/file.h)
AC_CHECK_HEADERS(sys/id.h)
@@ -1415,6 +1239,9 @@ AC_CHECK_HEADERS(syscall.h)
AC_CHECK_HEADERS(time.h)
AC_CHECK_HEADERS(ucontext.h)
AC_CHECK_HEADERS(utime.h)
+AS_CASE("$target_cpu", [x64|x86_64|i[3-6]86*], [
+ AC_CHECK_HEADERS(x86intrin.h)
+])
AC_ARG_WITH([gmp],
[AS_HELP_STRING([--without-gmp],
@@ -1430,13 +1257,18 @@ AS_IF([test "x$with_gmp" != xno],
AC_ARG_WITH([jemalloc],
[AS_HELP_STRING([--with-jemalloc],[use jemalloc allocator])],
[with_jemalloc=$withval], [with_jemalloc=no])
-AS_IF([test "x$with_jemalloc" = xyes],[
+AS_IF([test "x$with_jemalloc" != xno],[
AC_SEARCH_LIBS([malloc_conf], [jemalloc],
- [AC_DEFINE(HAVE_LIBJEMALLOC, 1)], [with_jemalloc=no])
+ [
+ AC_DEFINE(HAVE_LIBJEMALLOC, 1)
+ with_jemalloc=yes
+ ],
+ [test x$with_jemalloc = xyes && with_jemalloc=no])
AC_CHECK_HEADER(jemalloc/jemalloc.h, [
AC_DEFINE(RUBY_ALTERNATIVE_MALLOC_HEADER, [<jemalloc/jemalloc.h>])
- ])
- AS_IF([test "x$with_jemalloc" = xno], [
+ ],
+ [test x$with_jemalloc = xyes && with_jemalloc=no])
+ AS_IF([test "x$with_jemalloc" != xyes], [
AC_CACHE_CHECK([for jemalloc with JEMALLOC_MANGLE], rb_cv_jemalloc_demangle,
[AC_LINK_IFELSE([AC_LANG_PROGRAM([@%:@define JEMALLOC_MANGLE 1
@%:@ifdef RUBY_ALTERNATIVE_MALLOC_HEADER
@@ -1452,11 +1284,13 @@ AS_IF([test "x$with_jemalloc" = xyes],[
AC_DEFINE(JEMALLOC_MANGLE)
with_jemalloc=yes
])
- AS_IF([test "x$with_jemalloc" = xyes],
+ AS_CASE(["$with_jemalloc"],
+ [yes],
[
AC_DEFINE(HAVE_MALLOC_CONF)
ac_cv_func_malloc_usable_size=yes
],
+ [no],
[AC_MSG_ERROR([jemalloc requested but not found])
])
])
@@ -1488,7 +1322,6 @@ mv confdefs1.h confdefs.h
cat largefile.h >> confdefs.h
AS_CASE(["$target_os"],
- [mingw*], [ac_cv_type_off_t=yes;ac_cv_sizeof_off_t=8],
[aix*], [
AS_CASE(["$target_cpu:$ac_cv_sys_large_files"],
[ppc64:*|powerpc64:*], [],
@@ -1506,6 +1339,7 @@ AC_C_CHAR_UNSIGNED
AC_C_INLINE
AC_C_VOLATILE
AC_C_TYPEOF
+AC_C_RESTRICT
AS_CASE(":$ac_cv_c_const:$ac_cv_c_volatile:",
[*:no:*], [AC_MSG_ERROR(ANSI C-conforming const and volatile are mandatory)])
@@ -1518,114 +1352,6 @@ AC_CACHE_CHECK([char bit], [rb_cv_char_bit],
[AC_INCLUDES_DEFAULT([@%:@include <limits.h>])], [rb_cv_char_bit=8])
test "$universal_binary" = yes && cross_compiling=$real_cross_compiling])
-dnl RUBY_CHECK_SIZEOF [typename], [maybe same size types], [macros], [include]
-AC_DEFUN([RUBY_CHECK_SIZEOF],
-[dnl
-AS_VAR_PUSHDEF([rbcv_var], [rbcv_sizeof_var])dnl
-AS_VAR_PUSHDEF([cond], [rbcv_sizeof_cond])dnl
-AS_VAR_PUSHDEF([t], [rbcv_sizeof_type])dnl
-AS_VAR_PUSHDEF([s], [rbcv_sizeof_size])dnl
-]
-[m4_bmatch([$1], [\.], [], [if test "$universal_binary" = yes; then])
-AC_CACHE_CHECK([size of $1], [AS_TR_SH([ac_cv_sizeof_$1])], [
- unset AS_TR_SH(ac_cv_sizeof_$1)
- rbcv_var="
-typedef m4_bpatsubst([$1], [\..*]) ac__type_sizeof_;
-static ac__type_sizeof_ *rbcv_ptr;
-@%:@define AS_TR_CPP(SIZEOF_$1) sizeof((*rbcv_ptr)[]m4_bmatch([$1], [\.], .m4_bpatsubst([$1], [^[^.]*\.])))
-"
- m4_ifval([$2], [test -z "${AS_TR_SH(ac_cv_sizeof_$1)+set}" && {
- for t in $2; do
- AC_COMPILE_IFELSE(
- [AC_LANG_BOOL_COMPILE_TRY(AC_INCLUDES_DEFAULT([$4]
- [$rbcv_var]),
- [AS_TR_CPP(SIZEOF_$1) == sizeof($t)])], [
- AS_TR_SH(ac_cv_sizeof_$1)=AS_TR_CPP([SIZEOF_]$t)
- break])
- done
- }], [
- AC_COMPUTE_INT([AS_TR_SH(ac_cv_sizeof_$1)], [AS_TR_CPP(SIZEOF_$1)],
- [AC_INCLUDES_DEFAULT([$4])
-$rbcv_var],
- [AS_TR_SH(ac_cv_sizeof_$1)=])
- ])
- unset cond
- m4_ifval([$3], [test -z "${AS_TR_SH(ac_cv_sizeof_$1)+set}" && {
- for s in 32 64 128; do
- for t in $3; do
- cond="${cond}
-@%:@${cond+el}if defined(__${t}${s}__) || defined(__${t}${s}) || defined(_${t}${s}) || defined(${t}${s})"
- hdr="AC_INCLUDES_DEFAULT([$4
-@%:@if defined(__${t}${s}__) || defined(__${t}${s}) || defined(_${t}${s}) || defined(${t}${s})
-@%:@ define AS_TR_CPP(HAVE_$1) 1
-@%:@else
-@%:@ define AS_TR_CPP(HAVE_$1) 0
-@%:@endif])"
- AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$hdr], [!AS_TR_CPP(HAVE_$1)])], [continue])
- AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$hdr]
- [$rbcv_var],
- [AS_TR_CPP(HAVE_$1) == (AS_TR_CPP(SIZEOF_$1) == ($s / $rb_cv_char_bit))])],
- [AS_TR_SH(ac_cv_sizeof_$1)="${AS_TR_SH(ac_cv_sizeof_$1)+${AS_TR_SH(ac_cv_sizeof_$1)-} }${t}${s}"; continue])
- AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$hdr]
-[
-@%:@if AS_TR_CPP(HAVE_$1)
-$rbcv_var
-@%:@else
-@%:@define AS_TR_CPP(SIZEOF_$1) 0
-@%:@endif
-],
- [AS_TR_CPP(HAVE_$1) == (AS_TR_CPP(SIZEOF_$1) == (m4_bmatch([$2], [^[0-9][0-9]*$], [$2], [($s / $rb_cv_char_bit)])))])],
- [AS_TR_SH(ac_cv_sizeof_$1)="${AS_TR_SH(ac_cv_sizeof_$1)+${AS_TR_SH(ac_cv_sizeof_$1)-} }${t}${s}m4_bmatch([$2], [^[0-9][0-9]*$], [:$2])"])
- done
- done
- }])
- test "${AS_TR_SH(ac_cv_sizeof_$1)@%:@@<:@1-9@:>@}" = "${AS_TR_SH(ac_cv_sizeof_$1)}" &&
- m4_ifval([$2][$3],
- [test "${AS_TR_SH(ac_cv_sizeof_$1)@%:@SIZEOF_}" = "${AS_TR_SH(ac_cv_sizeof_$1)}" && ]){
- test "$universal_binary" = yes && cross_compiling=yes
- AC_COMPUTE_INT([t], AS_TR_CPP(SIZEOF_$1), [AC_INCLUDES_DEFAULT([$4])]
-[${cond+$cond
-@%:@else}
-$rbcv_var
-${cond+@%:@endif}
-@%:@ifndef AS_TR_CPP(SIZEOF_$1)
-@%:@define AS_TR_CPP(SIZEOF_$1) 0
-@%:@endif], [t=0])
- test "$universal_binary" = yes && cross_compiling=$real_cross_compiling
- AS_IF([test ${t-0} != 0], [
- AS_TR_SH(ac_cv_sizeof_$1)="${AS_TR_SH(ac_cv_sizeof_$1)+${AS_TR_SH(ac_cv_sizeof_$1)-} }${t}"
- ])
- }
- : ${AS_TR_SH(ac_cv_sizeof_$1)=0}
-])
-{
- unset cond
- for t in ${AS_TR_SH(ac_cv_sizeof_$1)-}; do
- AS_CASE(["$t"],
- [[[0-9]*|SIZEOF_*]], [
- ${cond+echo "@%:@else"}
- echo "[@%:@define ]AS_TR_CPP(SIZEOF_$1) $t"
- break
- ],
- [
- s=`expr $t : ['.*[^0-9]\([0-9][0-9]*\)$']`
- AS_CASE([$t], [*:*], [t="${t%:*}"], [s=`expr $s / $rb_cv_char_bit`])
- echo "@%:@${cond+el}if defined(__${t}__) || defined(__${t}) || defined(_${t}) || defined($t)"
- echo "@%:@define AS_TR_CPP(SIZEOF_$1) $s"
- cond=1
- ])
- done
- ${cond+echo "@%:@endif"}
-} >> confdefs.h
-m4_bmatch([$1], [\.], [], [else
-AC_CHECK_SIZEOF([$1], 0, [$4])
-fi])
-AS_VAR_POPDEF([rbcv_var])dnl
-AS_VAR_POPDEF([cond])dnl
-AS_VAR_POPDEF([t])dnl
-AS_VAR_POPDEF([s])dnl
-])
-
RUBY_CHECK_SIZEOF(int, [], [ILP])
RUBY_CHECK_SIZEOF(short)
RUBY_CHECK_SIZEOF(long, [int], [ILP LP])
@@ -1645,8 +1371,8 @@ AC_CACHE_CHECK(packed struct attribute, rb_cv_packed_struct,
"__pragma(pack(push, 1)) x __pragma(pack(pop))" \
"x __attribute__((packed))" \
; do
- AC_TRY_COMPILE([@%:@define PACKED_STRUCT(x) $mac
- PACKED_STRUCT(struct { int a; });], [],
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@define PACKED_STRUCT(x) $mac
+ PACKED_STRUCT(struct { int a; });]], [[]])],
[rb_cv_packed_struct=$mac; break])
done])
AS_IF([test "$rb_cv_packed_struct" != no], [
@@ -1656,102 +1382,18 @@ AS_IF([test "$rb_cv_packed_struct" != no], [
AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], x)
])
-AC_DEFUN([RUBY_CHECK_PRINTF_PREFIX], [
-AC_CACHE_CHECK([for printf prefix for $1], [rb_cv_pri_prefix_]AS_TR_SH($1),[
- [rb_cv_pri_prefix_]AS_TR_SH($1)=[NONE]
- RUBY_WERROR_FLAG(RUBY_APPEND_OPTIONS(CFLAGS, $rb_cv_wsuppress_flags)
- for pri in $2; do
- AC_TRY_COMPILE(
- [@%:@include <stdio.h>
- @%:@include <stddef.h>
- @%:@ifdef __GNUC__
- @%:@define PRINTF_ARGS(decl, string_index, first_to_check) \
- decl __attribute__((format(printf, string_index, first_to_check)))
- @%:@else
- @%:@define PRINTF_ARGS(decl, string_index, first_to_check) decl
- @%:@endif
- PRINTF_ARGS(void test_sprintf(const char*, ...), 1, 2);],
- [printf("%]${pri}[d", (]$1[)42);
- test_sprintf("%]${pri}[d", (]$1[)42);],
- [rb_cv_pri_prefix_]AS_TR_SH($1)[=[$pri]; break])
- done)])
-AS_IF([test "[$rb_cv_pri_prefix_]AS_TR_SH($1)" != NONE], [
- AC_DEFINE_UNQUOTED([PRI_]m4_ifval($3,$3,AS_TR_CPP(m4_bpatsubst([$1],[_t$])))[_PREFIX],
- "[$rb_cv_pri_prefix_]AS_TR_SH($1)")
-])
-])
-
AS_IF([test "x$ac_cv_type_long_long" = xyes], [
RUBY_CHECK_PRINTF_PREFIX(long long, ll I64, LL)
], [test "x$ac_cv_type___int64" = xyes], [
RUBY_CHECK_PRINTF_PREFIX(__int64, ll I64, LL)
])
-dnl RUBY_CHECK_SIGNEDNESS [typename] [if-signed] [if-unsigned] [included]
-AC_DEFUN([RUBY_CHECK_SIGNEDNESS], [dnl
- AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT([$4])], [($1)-1 > 0])],
- [$3], [$2])])
-
-dnl RUBY_REPLACE_TYPE [typename] [default type] [macro type] [included]
-AC_DEFUN([RUBY_REPLACE_TYPE], [dnl
- AC_CHECK_TYPE([$1],
- [n="patsubst([$1],["],[\\"])"],
- [n="patsubst([$2],["],[\\"])"],
- [$4])
- AC_CACHE_CHECK([for convertible type of [$1]], rb_cv_[$1]_convertible, [
- u= t=
- AS_CASE(["$n "],
- [*" signed "*], [ ],
- [*" unsigned "*], [
- u=U],
- [RUBY_CHECK_SIGNEDNESS($n, [], [u=U], [$4])])
- AS_IF([test x"$t" = x], [
- for t in "long long" long int short; do
- test -n "$u" && t="unsigned $t"
- AC_COMPILE_IFELSE(
- [AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT([$4])]
- [typedef $n rbcv_conftest_target_type;
- typedef $t rbcv_conftest_replace_type;
- extern rbcv_conftest_target_type rbcv_conftest_var;
- extern rbcv_conftest_replace_type rbcv_conftest_var;
- extern rbcv_conftest_target_type rbcv_conftest_func(void);
- extern rbcv_conftest_replace_type rbcv_conftest_func(void);
- ], [sizeof(rbcv_conftest_target_type) == sizeof(rbcv_conftest_replace_type)])],
- [n="$t"; break])
- done
- ])
- AS_CASE([" $n "],
- [*" long long "*], [
- t=LL],
- [*" long "*], [
- t=LONG],
- [
- t=INT])
- rb_cv_[$1]_convertible=${u}${t}])
- AS_IF([test "${AS_TR_SH(ac_cv_type_[$1])}" = "yes"], [
- n="$1"
- ], [
- AS_CASE(["${rb_cv_[$1]_convertible}"],
- [*LL], [n="long long"],
- [*LONG], [n="long"],
- [n="int"])
- AS_CASE(["${rb_cv_[$1]_convertible}"],
- [U*], [n="unsigned $n"])
- ])
- AS_CASE("${rb_cv_[$1]_convertible}", [U*], [u=+1], [u=-1])
- AC_DEFINE_UNQUOTED(rb_[$1], $n)
- AC_DEFINE_UNQUOTED([SIGNEDNESS_OF_]AS_TR_CPP($1), $u)
- AC_DEFINE_UNQUOTED([$3]2NUM[(v)], [${rb_cv_[$1]_convertible}2NUM(v)])
- AC_DEFINE_UNQUOTED(NUM2[$3][(v)], [NUM2${rb_cv_[$1]_convertible}(v)])
- AC_DEFINE_UNQUOTED(PRI_[$3]_PREFIX,
- [PRI_`echo ${rb_cv_[$1]_convertible} | sed ['s/^U//']`_PREFIX])
-])
RUBY_REPLACE_TYPE(pid_t, int, PIDT)
RUBY_REPLACE_TYPE(uid_t, int, UIDT)
RUBY_REPLACE_TYPE(gid_t, int, GIDT)
RUBY_REPLACE_TYPE(time_t, [], TIMET, [@%:@include <time.h>])
RUBY_REPLACE_TYPE(dev_t, [int long "long long"], DEVT)
-RUBY_REPLACE_TYPE(mode_t, ["unsigned int" long], MODET, [@%:@include <sys/stat.h>])
+RUBY_REPLACE_TYPE(mode_t, ["unsigned short" "unsigned int" long], MODET, [@%:@include <sys/stat.h>])
RUBY_REPLACE_TYPE(rlim_t, [int long "long long"], RLIM, [
@%:@ifdef HAVE_SYS_TYPES_H
@%:@include <sys/types.h>
@@ -1762,160 +1404,65 @@ RUBY_REPLACE_TYPE(rlim_t, [int long "long long"], RLIM, [
@%:@include <sys/resource.h>
])
RUBY_REPLACE_TYPE(off_t, [], OFFT)
-RUBY_REPLACE_TYPE(clockid_t, [], CLOCKID)
-
-AC_CACHE_CHECK(for prototypes, rb_cv_have_prototypes,
- [AC_TRY_COMPILE([int foo(int x) { return 0; }], [return foo(10);],
- rb_cv_have_prototypes=yes,
- rb_cv_have_prototypes=no)])
-AS_IF([test "$rb_cv_have_prototypes" = yes], [
- AC_DEFINE(HAVE_PROTOTYPES)
-])
-
-AC_CACHE_CHECK(token paste string, rb_cv_tokenpaste,
- [AC_TRY_COMPILE([@%:@define paste(a,b) a@%:@@%:@b],
- [int xy = 1; return paste(x,y);],
- rb_cv_tokenpaste=ansi,
- rb_cv_tokenpaste=knr)])
-AS_IF([test "$rb_cv_tokenpaste" = ansi], [
- AC_DEFINE(TOKEN_PASTE(x,y),[x@%:@@%:@y])
-], [
- AC_DEFINE(TOKEN_PASTE(x,y),[x/**/y])
-])
-
-AC_CACHE_CHECK(stringization, rb_cv_stringization, [
- rb_cv_stringization=no
- for string in "#expr" '"expr"'; do
- AC_COMPILE_IFELSE([
- AC_LANG_BOOL_COMPILE_TRY([
-#define STRINGIZE0(expr) $string
-#define STRINGIZE(expr) STRINGIZE0(expr)
-#undef real_test_for_stringization
-#define test_for_stringization -.real_test_for_stringization.-
-const char stringized[[]] = STRINGIZE(test_for_stringization);
-], [sizeof(stringized) == 32])],
- [rb_cv_stringization="$string"; break],
- [rb_cv_stringization=no])
- done]
-)
-AC_DEFINE(STRINGIZE(expr),STRINGIZE0(expr))
-AS_IF([test x"$rb_cv_stringization" != xno -a "$rb_cv_stringization" != "#expr"], [
- AC_DEFINE_UNQUOTED(STRINGIZE0(expr),$rb_cv_stringization)
- AC_DEFINE(OLD_FASHIONED_STRINGIZATION,1)
-])
-
-AC_CACHE_CHECK([string literal concatenation],
- rb_cv_string_literal_concatenation, [
- AC_COMPILE_IFELSE([
- AC_LANG_BOOL_COMPILE_TRY([
-const char concatenated_literal[[]] = "literals" "to"
- "be" "concatenated.";
-], [sizeof(concatenated_literal) == 26])],
- [rb_cv_string_literal_concatenation=yes],
- [rb_cv_string_literal_concatenation=no])]
-)
-AS_IF([test "$rb_cv_string_literal_concatenation" = no], [
- AC_DEFINE(NO_STRING_LITERAL_CONCATENATION,1)
-])
-
-AC_CACHE_CHECK(for variable length prototypes and stdarg.h, rb_cv_stdarg,
- [AC_TRY_COMPILE([
-#include <stdarg.h>
-int foo(int x, ...) {
- va_list va;
- va_start(va, x);
- va_arg(va, int);
- va_arg(va, char *);
- va_arg(va, double);
- return 0;
-}
-], [return foo(10, "", 3.14);],
- rb_cv_stdarg=yes,
- rb_cv_stdarg=no)])
-AS_IF([test "$rb_cv_stdarg" = yes], [
- AC_DEFINE(HAVE_STDARG_PROTOTYPES)
-])
+RUBY_REPLACE_TYPE(clockid_t, [], CLOCKID, [@%:@ifdef HAVE_TIME_H
+@%:@ include <time.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_TIME_H
+@%:@ include <sys/time.h>
+@%:@endif])
+# __VA_ARGS__ is also tested in AC_PROG_CC_C99 since autoconf 2.60a (around
+# 2006). The check below is redundant and should always success. Remain not
+# deleted for backward compat.
AC_CACHE_CHECK(for variable length macro, rb_cv_va_args_macro,
- [AC_TRY_COMPILE([
-int foo(int x, ...);
-@%:@define FOO(a, ...) foo(a, @%:@@%:@__VA_ARGS__)
-], [FOO(1);FOO(1,2);FOO(1,2,3);],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+int foo(const char*);
+@%:@define FOO(...) foo(@%:@__VA_ARGS__)
+]], [[FOO(1);FOO(1,2);FOO(1,2,3);]])],
rb_cv_va_args_macro=yes,
rb_cv_va_args_macro=no)])
AS_IF([test "$rb_cv_va_args_macro" = yes], [
AC_DEFINE(HAVE_VA_ARGS_MACRO)
])
-AC_DEFUN([RUBY_DEFINE_IF], [dnl
- m4_ifval([$1], [AS_LITERAL_IF([$1], [], [test "X$1" = X || ])cat <<EOH >> confdefs.h
-@%:@if $1
-EOH
-])dnl
-AC_DEFINE_UNQUOTED($2, $3)dnl
- m4_ifval([$1], [AS_LITERAL_IF([$1], [], [test "X$1" = X || ])cat <<EOH >> confdefs.h
-@%:@endif /* $1 */
-EOH
-])dnl
-])dnl
-
-dnl RUBY_DECL_ATTRIBUTE(attrib, macroname, cachevar, condition, type, code)
-AC_DEFUN([RUBY_DECL_ATTRIBUTE], [dnl
-m4_ifval([$2], dnl
- [AS_VAR_PUSHDEF([attrib], m4_bpatsubst([$2], [(.*)], []))], dnl
- [AS_VAR_PUSHDEF([attrib], m4_toupper(m4_format(%.4s, [$5]))[_]AS_TR_CPP($1))] dnl
-)dnl
-m4_ifval([$3], dnl
- [AS_VAR_PUSHDEF([rbcv],[$3])], dnl
- [AS_VAR_PUSHDEF([rbcv],[rb_cv_]m4_format(%.4s, [$5])[_][$1])]dnl
-)dnl
-m4_pushdef([attrib_code],[m4_bpatsubst([$1],["],[\\"])])dnl
-m4_pushdef([attrib_params],[m4_bpatsubst([$2(x)],[^[^()]*(\([^()]*\)).*],[\1])])dnl
-m4_ifval([$4], [rbcv_cond=["$4"]; test "$rbcv_cond" || unset rbcv_cond])
-AC_CACHE_CHECK(for m4_ifval([$2],[m4_bpatsubst([$2], [(.*)], [])],[$1]) [$5] attribute, rbcv, dnl
-[rbcv=x
-RUBY_WERROR_FLAG([
-for mac in \
- "__attribute__ ((attrib_code)) x" \
- "x __attribute__ ((attrib_code))" \
- "__declspec(attrib_code) x" \
- x; do
- m4_ifval([$4],mac="$mac"${rbcv_cond+" /* only if $rbcv_cond */"})
- AC_TRY_COMPILE(
- m4_ifval([$4],${rbcv_cond+[@%:@if ]$rbcv_cond})
-[@%:@define ]attrib[](attrib_params)[ $mac]
-m4_ifval([$4],${rbcv_cond+[@%:@else]}
-${rbcv_cond+[@%:@define ]attrib[](attrib_params)[ x]}
-${rbcv_cond+[@%:@endif]})
-$6
-@%:@define mesg ("")
- attrib[](attrib_params)[;], [],
- [rbcv="$mac"; break])
-done
-])])
-AS_IF([test "$rbcv" != x], [
- RUBY_DEFINE_IF(m4_ifval([$4],[${rbcv_cond}]), attrib[](attrib_params)[], $rbcv)
-])
-m4_ifval([$4], [unset rbcv_cond]) dnl
-m4_popdef([attrib_params])dnl
-m4_popdef([attrib_code])dnl
-AS_VAR_POPDEF([attrib])dnl
-AS_VAR_POPDEF([rbcv])dnl
-])
-
-dnl RUBY_FUNC_ATTRIBUTE(attrib, macroname, cachevar, condition)
-AC_DEFUN([RUBY_FUNC_ATTRIBUTE], [dnl
- RUBY_DECL_ATTRIBUTE([$1], [$2], [$3], [$4],
- [function], [@%:@define x int conftest_attribute_check(void)]
- )
-])
-
-dnl RUBY_TYPE_ATTRIBUTE(attrib, macroname, cachevar, condition)
-AC_DEFUN([RUBY_TYPE_ATTRIBUTE], [dnl
- RUBY_DECL_ATTRIBUTE([$1], [$2], [$3], [$4],
- [type], [
-@%:@define x struct conftest_attribute_check {int i;}
+# We want C11's `_Alignof`. GCC (and alike) have `__alignof__`, which behave
+# slightly differently than the C11's. We cannot use `__alignof__` for our
+# purpose. The problem is, however, that old gcc and old clang had both
+# implemented `_Alignof` as a synonym of `__alignof__`. They are not what we
+# want. We have to check sanity.
+#
+# See also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023
+# See also: https://bugs.llvm.org/show_bug.cgi?id=26547
+AC_CACHE_CHECK([if _Alignof() works], rb_cv_have__alignof,[
+ rb_cv_have__alignof=no
+ RUBY_WERROR_FLAG([
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@ifdef HAVE_STDALIGN_H
+ @%:@include <stdalign.h>
+ @%:@endif
+ @%:@ifdef STDC_HEADERS
+ @%:@include <stddef.h>
+ @%:@endif
+ @%:@ifndef __GNUC__
+ @%:@define __extension__
+ @%:@endif
+ ]], [[
+ typedef struct conftest_tag {
+ char _;
+ double d;
+ } T;
+ static int conftest_ary@<:@
+ offsetof(T, d) == __extension__ _Alignof(double)
+ ? 1 : -1
+ @:>@;
+ return conftest_ary@<:@0@:>@;
+ ]])],[
+ rb_cv_have__alignof=yes
+ ],[])
+ ])
])
+AS_IF([test "$rb_cv_have__alignof" != no], [
+ AC_DEFINE(HAVE__ALIGNOF)
])
RUBY_FUNC_ATTRIBUTE(__const__, CONSTFUNC)
@@ -1923,9 +1470,11 @@ RUBY_FUNC_ATTRIBUTE(__pure__, PUREFUNC)
RUBY_FUNC_ATTRIBUTE(__noreturn__, NORETURN)
RUBY_FUNC_ATTRIBUTE(__deprecated__, DEPRECATED)
RUBY_FUNC_ATTRIBUTE(__deprecated__("by "@%:@n), DEPRECATED_BY(n,x), rb_cv_func_deprecated_by)
-RUBY_TYPE_ATTRIBUTE(__deprecated__ mesg, DEPRECATED_TYPE(mesg,x), rb_cv_type_deprecated)
RUBY_FUNC_ATTRIBUTE(__noinline__, NOINLINE)
RUBY_FUNC_ATTRIBUTE(__always_inline__, ALWAYS_INLINE)
+RUBY_FUNC_ATTRIBUTE(__no_sanitize__(san), NO_SANITIZE(san, x), rb_cv_func_no_sanitize)
+RUBY_FUNC_ATTRIBUTE(__no_sanitize_address__, NO_SANITIZE_ADDRESS)
+RUBY_FUNC_ATTRIBUTE(__no_address_safety_analysis__, NO_ADDRESS_SAFETY_ANALYSIS)
RUBY_FUNC_ATTRIBUTE(__warn_unused_result__, WARN_UNUSED_RESULT)
RUBY_FUNC_ATTRIBUTE(__unused__, MAYBE_UNUSED)
RUBY_FUNC_ATTRIBUTE(__error__ mesg, ERRORFUNC(mesg,x), rb_cv_func___error__)
@@ -1935,6 +1484,32 @@ AS_IF([test "$rb_cv_func_weak" != x], [
AC_DEFINE(HAVE_FUNC_WEAK)
])
+AC_CACHE_CHECK([for __attribute__((__depreacted__(msg))) in C++],
+ rb_cv_CentOS6_CXX_workaround,
+ RUBY_WERROR_FLAG([
+ AC_LANG_PUSH([C++])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [],
+ [__attribute__((__deprecated__("message"))) int conftest(...);])],
+ [rb_cv_CentOS6_CXX_workaround=yes],
+ [rb_cv_CentOS6_CXX_workaround=no])
+ AC_LANG_POP()]))
+AS_IF([test "$rb_cv_CentOS6_CXX_workaround" != no],[
+ AC_DEFINE([RUBY_CXX_DEPRECATED(msg)],
+ [__attribute__((__deprecated__(msg)))])])
+
+AC_CACHE_CHECK([for std::nullptr_t], rb_cv_CXX_nullptr, [
+ AC_LANG_PUSH([C++])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [@%:@include <cstddef>],
+ [static std::nullptr_t const *const conftest = nullptr;])],
+ [rb_cv_CXX_nullptr=yes],
+ [rb_cv_CXX_nullptr=no])
+ AC_LANG_POP()])
+AS_IF([test "$rb_cv_CXX_nullptr" != no],[AC_DEFINE(HAVE_NULLPTR)])
+
if_i386=${universal_binary+[defined __i386__]}
RUBY_FUNC_ATTRIBUTE(__stdcall__, FUNC_STDCALL, rb_cv_func_stdcall, ${if_i386})
RUBY_FUNC_ATTRIBUTE(__cdecl__, FUNC_CDECL, rb_cv_func_cdecl, ${if_i386})
@@ -1946,8 +1521,8 @@ AS_IF([test "$GCC" = yes], [
AC_CACHE_CHECK([for function alias], [rb_cv_gcc_function_alias],
[rb_cv_gcc_function_alias=no
for a in alias weak,alias; do
- AC_TRY_LINK([void foo(void) {}
- void bar(void) __attribute__(($a("foo")));], [bar()],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[void foo(void) {}
+ void bar(void) __attribute__(($a("foo")));]], [[bar()]])],
[rb_cv_gcc_function_alias=$a; break])
done])
AS_IF([test "$rb_cv_gcc_function_alias" != no], [
@@ -1959,14 +1534,14 @@ AS_IF([test "$GCC" = yes], [
])
AC_CACHE_CHECK([for __atomic builtins], [rb_cv_gcc_atomic_builtins], [
- AC_TRY_LINK([unsigned char atomic_var;],
- [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[unsigned int atomic_var;]],
+ [[
__atomic_exchange_n(&atomic_var, 0, __ATOMIC_SEQ_CST);
__atomic_exchange_n(&atomic_var, 1, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&atomic_var, 1, __ATOMIC_SEQ_CST);
__atomic_fetch_sub(&atomic_var, 1, __ATOMIC_SEQ_CST);
__atomic_or_fetch(&atomic_var, 1, __ATOMIC_SEQ_CST);
- ],
+ ]])],
[rb_cv_gcc_atomic_builtins=yes],
[rb_cv_gcc_atomic_builtins=no])])
AS_IF([test "$rb_cv_gcc_atomic_builtins" = yes], [
@@ -1974,25 +1549,26 @@ AS_IF([test "$GCC" = yes], [
])
AC_CACHE_CHECK([for __sync builtins], [rb_cv_gcc_sync_builtins], [
- AC_TRY_LINK([unsigned char atomic_var;],
- [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[unsigned int atomic_var;]],
+ [[
__sync_lock_test_and_set(&atomic_var, 0);
__sync_lock_test_and_set(&atomic_var, 1);
__sync_fetch_and_add(&atomic_var, 1);
__sync_fetch_and_sub(&atomic_var, 1);
__sync_or_and_fetch(&atomic_var, 1);
__sync_val_compare_and_swap(&atomic_var, 0, 1);
- ],
+ ]])],
[rb_cv_gcc_sync_builtins=yes],
[rb_cv_gcc_sync_builtins=no])])
AS_IF([test "$rb_cv_gcc_sync_builtins" = yes], [
AC_DEFINE(HAVE_GCC_SYNC_BUILTINS)
])
+])
AC_CACHE_CHECK(for __builtin_unreachable, rb_cv_func___builtin_unreachable,
[RUBY_WERROR_FLAG(
- [AC_TRY_LINK([volatile int zero;],
- [if (zero) __builtin_unreachable();],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[volatile int zero;]],
+ [[if (zero) __builtin_unreachable();]])],
[rb_cv_func___builtin_unreachable=yes],
[rb_cv_func___builtin_unreachable=no])
])
@@ -2000,34 +1576,45 @@ AS_IF([test "$GCC" = yes], [
AS_IF([test "$rb_cv_func___builtin_unreachable" = yes], [
AC_DEFINE_UNQUOTED(UNREACHABLE, [__builtin_unreachable()])
])
-])
AC_CACHE_CHECK(for exported function attribute, rb_cv_func_exported, [
rb_cv_func_exported=no
RUBY_WERROR_FLAG([
for mac in '__attribute__ ((__visibility__("default")))' '__declspec(dllexport)'; do
- AC_TRY_COMPILE([@%:@define RUBY_FUNC_EXPORTED $mac extern
- RUBY_FUNC_EXPORTED void conftest_attribute_check(void);], [],
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@define RUBY_FUNC_EXPORTED $mac extern
+ RUBY_FUNC_EXPORTED void conftest_attribute_check(void);]], [[]])],
[rb_cv_func_exported="$mac"; break])
done
])])
AS_IF([test "$rb_cv_func_exported" != no], [
AC_DEFINE_UNQUOTED(RUBY_FUNC_EXPORTED, [$rb_cv_func_exported extern])
])
+RUBY_DECL_ATTRIBUTE([__nonnull__(n)], [RUBY_FUNC_NONNULL(n,x)], [rb_cv_func_nonnull],
+ [], [function], [
+@%:@define x int conftest_attribute_check(void *p)
+@%:@define n 1
+])
RUBY_APPEND_OPTION(XCFLAGS, -DRUBY_EXPORT)
+AC_ARG_ENABLE(mathn,
+ AS_HELP_STRING([--enable-mathn], [enable canonicalization for mathn]),
+ [AC_MSG_ERROR([mathn support has been dropped])])
+
AC_CACHE_CHECK(for function name string predefined identifier,
rb_cv_function_name_string,
- [rb_cv_function_name_string=no
- RUBY_WERROR_FLAG([
- for func in __func__ __FUNCTION__; do
- AC_TRY_LINK([@%:@include <stdio.h>],
- [puts($func);],
- [rb_cv_function_name_string=$func
- break])
- done
- ])]
+ [AS_CASE(["$target_os"],[openbsd*],[
+ rb_cv_function_name_string=__func__
+ ],[
+ rb_cv_function_name_string=no
+ RUBY_WERROR_FLAG([
+ for func in __func__ __FUNCTION__; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <stdio.h>]],
+ [[puts($func);]])],
+ [rb_cv_function_name_string=$func
+ break])
+ done
+ ])])]
)
AS_IF([test "$rb_cv_function_name_string" != no], [
AC_DEFINE_UNQUOTED(RUBY_FUNCTION_NAME_STRING, [$rb_cv_function_name_string])
@@ -2089,9 +1676,9 @@ RUBY_CHECK_SIZEOF(size_t, [int long void*], [], [@%:@include <sys/types.h>])
RUBY_CHECK_SIZEOF(ptrdiff_t, size_t, [], [@%:@include <stddef.h>])
RUBY_CHECK_PRINTF_PREFIX(size_t, z)
RUBY_CHECK_PRINTF_PREFIX(ptrdiff_t, t)
-AC_STRUCT_ST_BLKSIZE
-AC_STRUCT_ST_BLOCKS
-AC_STRUCT_ST_RDEV
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+AC_CHECK_MEMBERS([struct stat.st_blocks])
+AC_CHECK_MEMBERS([struct stat.st_rdev])
RUBY_CHECK_SIZEOF([struct stat.st_size], [off_t int long "long long"], [], [@%:@include <sys/stat.h>])
AS_IF([test "$ac_cv_member_struct_stat_st_blocks" = yes], [
RUBY_CHECK_SIZEOF([struct stat.st_blocks], [off_t int long "long long"], [], [@%:@include <sys/stat.h>])
@@ -2107,6 +1694,8 @@ AC_CHECK_MEMBERS([struct stat.st_ctim])
AC_CHECK_MEMBERS([struct stat.st_ctimespec])
AC_CHECK_MEMBERS([struct stat.st_ctimensec])
AC_CHECK_MEMBERS([struct stat.st_birthtimespec])
+AS_IF([test "x$ac_cv_member_struct_stat_st_birthtimespec" != xyes],
+ [AC_CHECK_MEMBERS([struct statx.stx_btime])])
AC_CHECK_TYPES([struct timeval], [], [], [@%:@ifdef HAVE_TIME_H
@%:@include <time.h>
@@ -2147,61 +1736,15 @@ AC_CHECK_TYPES([struct timezone], [], [], [@%:@ifdef HAVE_TIME_H
@%:@ include <sys/time.h>
@%:@endif])
-AC_CHECK_TYPES([clockid_t], [], [], [@%:@ifdef HAVE_TIME_H
-@%:@ include <time.h>
-@%:@endif
-@%:@ifdef HAVE_SYS_TIME_H
-@%:@ include <sys/time.h>
-@%:@endif])
-
AC_CACHE_VAL([rb_cv_large_fd_select],
- [AC_CHECK_TYPE(fd_mask, [rb_cv_large_fd_select=yes], [rb_cv_large_fd_select=no], [@%:@ifdef HAVE_SYS_SELECT_H
+ [AC_CHECK_TYPE(fd_mask, [rb_cv_large_fd_select=yes], [rb_cv_large_fd_select=no], [AC_INCLUDES_DEFAULT([])
+@%:@ifdef HAVE_SYS_SELECT_H
@%:@ include <sys/select.h>
@%:@endif])])
AS_IF([test "$rb_cv_large_fd_select" = yes], [
AC_DEFINE(HAVE_RB_FD_INIT, 1)
])
-dnl RUBY_DEFINT TYPENAME, SIZE, [UNSIGNED], [INCLUDES = DEFAULT-INCLUDES]
-AC_DEFUN([RUBY_DEFINT], [dnl
-AS_VAR_PUSHDEF([cond], [rb_defint_cond])dnl
-AS_VAR_PUSHDEF([type], [rb_defint_type])dnl
-AC_CACHE_CHECK([for $1], [rb_cv_type_$1],
-[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT([$4])
-typedef $1 t; int s = sizeof(t) == 42;])],
- [rb_cv_type_$1=yes],
- [AS_CASE([m4_bmatch([$2], [^[1-9][0-9]*$], $2, [$ac_cv_sizeof_]AS_TR_SH($2))],
- ["1"], [ rb_cv_type_$1="m4_if([$3], [], [signed ], [$3 ])char"],
- ["$ac_cv_sizeof_short"], [ rb_cv_type_$1="m4_if([$3], [], [], [$3 ])short"],
- ["$ac_cv_sizeof_int"], [ rb_cv_type_$1="m4_if([$3], [], [], [$3 ])int"],
- ["$ac_cv_sizeof_long"], [ rb_cv_type_$1="m4_if([$3], [], [], [$3 ])long"],
- ["$ac_cv_sizeof_long_long"], [ rb_cv_type_$1="m4_if([$3], [], [], [$3 ])long long"],
- ["${ac_cv_sizeof___int64@%:@*:}"], [ rb_cv_type_$1="m4_if([$3], [], [], [$3 ])__int64"],
- ["${ac_cv_sizeof___int128@%:@*:}"], [ rb_cv_type_$1="m4_if([$3], [], [], [$3 ])__int128"],
- [ rb_cv_type_$1=no])])])
-AS_IF([test "${rb_cv_type_$1}" != no], [
- type="${rb_cv_type_$1@%:@@%:@unsigned }"
- AS_IF([test "$type" != yes && eval 'test -n "${ac_cv_sizeof_'$type'+set}"'], [
- eval cond='"${ac_cv_sizeof_'$type'}"'
- AS_CASE([$cond], [*:*], [
- cond=AS_TR_CPP($type)
- echo "@%:@if defined SIZEOF_"$cond" && SIZEOF_"$cond" > 0" >> confdefs.h
- ], [cond=])
- ], [cond=])
- AC_DEFINE([HAVE_]AS_TR_CPP($1), 1)
- AS_IF([test "${rb_cv_type_$1}" = yes], [
- m4_bmatch([$2], [^[1-9][0-9]*$], [AC_CHECK_SIZEOF([$1], 0, [AC_INCLUDES_DEFAULT([$4])])],
- [RUBY_CHECK_SIZEOF([$1], [$2], [], [AC_INCLUDES_DEFAULT([$4])])])
- ], [
- AC_DEFINE_UNQUOTED($1, [$rb_cv_type_$1])
- AC_DEFINE_UNQUOTED([SIZEOF_]AS_TR_CPP($1), [SIZEOF_]AS_TR_CPP([$type]))
- ])
- test -n "$cond" && echo "@%:@endif /* $cond */" >> confdefs.h
-])
-AS_VAR_POPDEF([cond])dnl
-AS_VAR_POPDEF([type])dnl
-])
-
RUBY_DEFINT(int8_t, 1)
RUBY_DEFINT(uint8_t, 1, unsigned)
RUBY_DEFINT(int16_t, 2)
@@ -2214,52 +1757,27 @@ RUBY_DEFINT(int128_t, 16)
RUBY_DEFINT(uint128_t, 16, unsigned)
RUBY_DEFINT(intptr_t, void*)
RUBY_DEFINT(uintptr_t, void*, unsigned)
+AS_IF([test "x$rb_cv_type_intptr_t" != xno], [
+ RUBY_CHECK_PRINTF_PREFIX(intptr_t, '' ll I64 l, PTR)
+])
RUBY_DEFINT(ssize_t, size_t, [], [@%:@include <sys/types.h>]) dnl may differ from int, so not use AC_TYPE_SSIZE_T.
-
-RUBY_NACL_CHECK_PEPPER_TYPES
+AS_IF([test "x$rb_cv_type_int64_t" != xno], [
+ RUBY_CHECK_PRINTF_PREFIX(int64_t, ll I64 l, 64)
+])
AC_CACHE_CHECK(for stack end address, rb_cv_stack_end_address,
[rb_cv_stack_end_address=no
- AC_TRY_LINK(
- [extern void *__libc_stack_end;],
- [if (!__libc_stack_end) return 1;],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[extern void *__libc_stack_end;]],
+ [[if (!__libc_stack_end) return 1;]])],
[rb_cv_stack_end_address="__libc_stack_end"])
])
AS_IF([test $rb_cv_stack_end_address != no], [
AC_DEFINE_UNQUOTED(STACK_END_ADDRESS, $rb_cv_stack_end_address)
])
-# posix_memalign(memptr, alignment, size) implemented for OpenBSD 4.8 doesn't work if alignment > MALLOC_PAGESIZE.
-# [ruby-core:42158] https://bugs.ruby-lang.org/issues/5901
-# OpenBSD 5.2 fixed the problem. (src/lib/libc/stdlib/malloc.c:1.142)
-# MirOS #10semel has the problem but fixed in the repository. (src/lib/libc/stdlib/malloc.c:1.9)
-AS_CASE(["$target_os"],
-[openbsd*|mirbsd*], [
- AC_CACHE_CHECK(for heap align log on openbsd, rb_cv_page_size_log,
- [rb_cv_page_size_log=no
- for page_log in 12 13; do
- AC_TRY_RUN([
-#include <math.h>
-#include <unistd.h>
-
-int
-main() {
- if ((int)log2((double)sysconf(_SC_PAGESIZE)) != $page_log) return 1;
- return 0;
-}
- ],
- rb_cv_page_size_log="$page_log"; break)
- done])
- AS_IF([test $rb_cv_page_size_log != no], [
- AC_DEFINE_UNQUOTED(HEAP_ALIGN_LOG, $rb_cv_page_size_log)
- ], [
- AC_DEFINE_UNQUOTED(HEAP_ALIGN_LOG, 12)
- ])
-])
-
dnl Checks for library functions.
AC_TYPE_GETGROUPS
-AC_TYPE_SIGNAL
AS_CASE(["${target_cpu}-${target_os}:${target_archs}"],
[powerpc-darwin*], [
AC_LIBSOURCES(alloca.c)
@@ -2279,14 +1797,14 @@ AS_CASE(["${target_cpu}-${target_os}:${target_archs}"],
AS_IF([test "x$ALLOCA" = "x"], [
AC_CACHE_CHECK([for dynamic size alloca], rb_cv_dynamic_alloca, [
for chk in ok __chkstk; do
- AC_TRY_LINK([
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@ifdef HAVE_ALLOCA_H
@%:@include <alloca.h>
@%:@endif
void $chk() {}
int dynamic_alloca_test;
- int dynamic_alloca_result;],
- [dynamic_alloca_result = alloca(dynamic_alloca_test) != 0;],
+ int dynamic_alloca_result;]],
+ [[dynamic_alloca_result = alloca(dynamic_alloca_test) != 0;]])],
[rb_cv_dynamic_alloca=$chk; break])
done])
AS_IF([test "x$rb_cv_dynamic_alloca" = "x__chkstk"], [
@@ -2299,24 +1817,6 @@ AS_IF([test "x$ALLOCA" = "x"], [
])
AC_FUNC_MEMCMP
-# http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html
-# Debian GNU/Linux Etch's libc6.1 2.3.6.ds1-13etch5 has this problem.
-# Debian GNU/Linux Lenny's libc6.1 2.7-10 has no problem.
-AC_CACHE_CHECK(for broken erfc of glibc-2.3.6 on IA64, rb_cv_broken_glibc_ia64_erfc,
- [AC_TRY_RUN([
-#include <math.h>
-int
-main()
-{
- erfc(10000.0);
- return 0;
-}
-],
- rb_cv_broken_glibc_ia64_erfc=no,
- rb_cv_broken_glibc_ia64_erfc=yes,
- rb_cv_broken_glibc_ia64_erfc=no)])
-AS_CASE([$rb_cv_broken_glibc_ia64_erfc],[yes],[ac_cv_func_erf=no])
-
AS_CASE(["$target_os"],[freebsd*],[
AC_DEFINE(BROKEN_CLOSE)
AC_REPLACE_FUNCS(close)
@@ -2329,13 +1829,11 @@ AC_REPLACE_FUNCS(dup2)
AC_REPLACE_FUNCS(erf)
AC_REPLACE_FUNCS(explicit_bzero)
AC_REPLACE_FUNCS(ffs)
-AC_REPLACE_FUNCS(finite)
AC_REPLACE_FUNCS(flock)
AC_REPLACE_FUNCS(hypot)
-AC_REPLACE_FUNCS(isinf)
-AC_REPLACE_FUNCS(isnan)
AC_REPLACE_FUNCS(lgamma_r)
AC_REPLACE_FUNCS(memmove)
+AC_REPLACE_FUNCS(nan)
AC_REPLACE_FUNCS(nextafter)
AC_REPLACE_FUNCS(setproctitle)
AC_REPLACE_FUNCS(strchr)
@@ -2345,6 +1843,10 @@ AC_REPLACE_FUNCS(strlcpy)
AC_REPLACE_FUNCS(strstr)
AC_REPLACE_FUNCS(tgamma)
+RUBY_REPLACE_FUNC([finite], [@%:@include <math.h>])
+RUBY_REPLACE_FUNC([isinf], [@%:@include <math.h>])
+RUBY_REPLACE_FUNC([isnan], [@%:@include <math.h>])
+
# for missing/setproctitle.c
AS_CASE(["$target_os"],
[aix* | k*bsd*-gnu | kopensolaris*-gnu | linux* | darwin*], [AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)],
@@ -2354,9 +1856,9 @@ AC_CHECK_HEADERS(sys/pstat.h)
AC_CACHE_CHECK(for signbit, rb_cv_have_signbit,
- [AC_TRY_LINK([
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <math.h>
-], [int v = signbit(-0.0);],
+]], [[int v = signbit(-0.0);]])],
rb_cv_have_signbit=yes,
rb_cv_have_signbit=no)])
AS_IF([test "$rb_cv_have_signbit" = yes], [
@@ -2365,33 +1867,6 @@ AS_IF([test "$rb_cv_have_signbit" = yes], [
AC_LIBOBJ([signbit])
])
-AC_CACHE_CHECK(for broken memmem, rb_cv_broken_memmem, [
- AC_TRY_RUN([
-@%:@include <string.h>
-
-int
-main(int argc, char **argv)
-{
- const char *str = "hogefugafoobar";
- const char *rs = "foo";
- const char *empty = "";
- char *p;
-
- p = memmem(str, strlen(str), rs, strlen(rs));
- if (p == str+8) {
- p = memmem(str, strlen(str), empty, strlen(empty));
- if (p == str)
- return 0;
- }
- return 1;
-}
- ],
- rb_cv_broken_memmem=no,
- rb_cv_broken_memmem=yes,
- rb_cv_broken_memmem=yes)
-])
-test x"$rb_cv_broken_memmem" = xyes && ac_cv_func_memmem=no
-
AC_FUNC_FORK
AC_CHECK_FUNCS(__syscall)
@@ -2403,6 +1878,7 @@ AC_CHECK_FUNCS(atan2l atan2f)
AC_CHECK_FUNCS(chroot)
AC_CHECK_FUNCS(chsize)
AC_CHECK_FUNCS(clock_gettime)
+AC_CHECK_FUNCS(copy_file_range)
AC_CHECK_FUNCS(cosh)
AC_CHECK_FUNCS(crypt_r)
AC_CHECK_FUNCS(daemon)
@@ -2414,6 +1890,9 @@ AC_CHECK_FUNCS(dup)
AC_CHECK_FUNCS(dup3)
AC_CHECK_FUNCS(eaccess)
AC_CHECK_FUNCS(endgrent)
+AC_CHECK_FUNCS(eventfd)
+AC_CHECK_FUNCS(explicit_memset)
+AC_CHECK_FUNCS(fcopyfile)
AC_CHECK_FUNCS(fchmod)
AC_CHECK_FUNCS(fchown)
AC_CHECK_FUNCS(fcntl)
@@ -2431,10 +1910,16 @@ AC_CHECK_FUNCS(getgidx)
AC_CHECK_FUNCS(getgrnam)
AC_CHECK_FUNCS(getgrnam_r)
AC_CHECK_FUNCS(getgroups)
+AC_CHECK_FUNCS(getlogin)
+AC_CHECK_FUNCS(getlogin_r)
AC_CHECK_FUNCS(getpgid)
AC_CHECK_FUNCS(getpgrp)
AC_CHECK_FUNCS(getpriority)
+AC_CHECK_FUNCS(getpwnam)
AC_CHECK_FUNCS(getpwnam_r)
+AC_CHECK_FUNCS(getpwuid)
+AC_CHECK_FUNCS(getpwuid_r)
+AC_CHECK_FUNCS(getrandom)
AC_CHECK_FUNCS(getresgid)
AC_CHECK_FUNCS(getresuid)
AC_CHECK_FUNCS(getrlimit)
@@ -2442,6 +1927,7 @@ AC_CHECK_FUNCS(getsid)
AC_CHECK_FUNCS(gettimeofday) # for making ac_cv_func_gettimeofday
AC_CHECK_FUNCS(getuidx)
AC_CHECK_FUNCS(gmtime_r)
+AC_CHECK_FUNCS(grantpt)
AC_CHECK_FUNCS(initgroups)
AC_CHECK_FUNCS(ioctl)
AC_CHECK_FUNCS(isfinite)
@@ -2454,6 +1940,7 @@ AC_CHECK_FUNCS(llabs)
AC_CHECK_FUNCS(lockf)
AC_CHECK_FUNCS(log2)
AC_CHECK_FUNCS(lstat)
+AC_CHECK_FUNCS(lutimes)
AC_CHECK_FUNCS(malloc_usable_size)
AC_CHECK_FUNCS(malloc_size)
AC_CHECK_FUNCS(mblen)
@@ -2476,6 +1963,7 @@ AC_CHECK_FUNCS(pwrite)
AC_CHECK_FUNCS(qsort_r)
AC_CHECK_FUNCS(qsort_s)
AC_CHECK_FUNCS(readlink)
+AC_CHECK_FUNCS(realpath)
AC_CHECK_FUNCS(round)
AC_CHECK_FUNCS(sched_getaffinity)
AC_CHECK_FUNCS(seekdir)
@@ -2517,13 +2005,18 @@ AC_CHECK_FUNCS(utimensat)
AC_CHECK_FUNCS(utimes)
AC_CHECK_FUNCS(wait4)
AC_CHECK_FUNCS(waitpid)
+AC_CHECK_FUNCS(__cospi)
+AC_CHECK_FUNCS(__sinpi)
+
+AS_IF([test "x$ac_cv_member_struct_statx_stx_btime" = xyes],
+ [AC_CHECK_FUNCS(statx)])
-AS_IF([test "$ac_cv_func_memset_s" = yes],
+AS_CASE(["$ac_cv_func_memset_s:$ac_cv_func_qsort_s"], [*yes*],
[RUBY_DEFINE_IF([!defined __STDC_WANT_LIB_EXT1__], [__STDC_WANT_LIB_EXT1__], 1)])
AS_IF([test "$ac_cv_func_getcwd" = yes], [
AC_CACHE_CHECK(if getcwd allocates buffer if NULL is given, [rb_cv_getcwd_malloc],
- [AC_TRY_RUN([
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
@%:@include <stddef.h>
@%:@include <stdio.h>
@%:@ifdef HAVE_UNISTD_H
@@ -2542,7 +2035,7 @@ main(int argc, char **argv)
if (!getcwd(NULL, 0)) return EXIT_FAILURE;
return EXIT_SUCCESS;
}
-],
+]])],
rb_cv_getcwd_malloc=yes,
rb_cv_getcwd_malloc=no,
AS_CASE($target_os,
@@ -2558,15 +2051,8 @@ AS_IF([test "$ac_cv_func_crypt_r:$ac_cv_header_crypt_h" = yes:yes],
[AC_CHECK_MEMBERS([struct crypt_data.initialized], [], [],
[AC_INCLUDES_DEFAULT([@%:@include <crypt.h>])])])
-AC_DEFUN([RUBY_CHECK_BUILTIN_FUNC], [dnl
-AC_CACHE_CHECK([for $1], AS_TR_SH(rb_cv_builtin_$1),
- [AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([int foo;], [$2;])],
- [AS_TR_SH(rb_cv_builtin_$1)=yes],
- [AS_TR_SH(rb_cv_builtin_$1)=no])])
-AS_IF([test "${AS_TR_SH(rb_cv_builtin_$1)}" != no], [
- AC_DEFINE(AS_TR_CPP(HAVE_BUILTIN_$1))
-])])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_alloca_with_align, [__builtin_alloca_with_align(1, 4096)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_assume_aligned, [__builtin_assume_aligned((void*)32, 32)])
RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap16, [__builtin_bswap16(0)])
RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap32, [__builtin_bswap32(0)])
RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap64, [__builtin_bswap64(0)])
@@ -2593,24 +2079,25 @@ AS_IF([test x$rb_cv_builtin___builtin_choose_expr = xyes], [
])
])
RUBY_CHECK_BUILTIN_FUNC(__builtin_types_compatible_p, [__builtin_types_compatible_p(int, int)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_trap, [__builtin_trap()])
AS_IF([test "$ac_cv_func_qsort_r" != no], [
AC_CACHE_CHECK(whether qsort_r is GNU version, rb_cv_gnu_qsort_r,
- [AC_TRY_COMPILE([
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <stdlib.h>
-void qsort_r(void *base, size_t nmemb, size_t size,
+void (qsort_r)(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *, void *),
void *arg);
-],[ ],
+]], [[ ]])],
[rb_cv_gnu_qsort_r=yes],
[rb_cv_gnu_qsort_r=no])
])
AC_CACHE_CHECK(whether qsort_r is BSD version, rb_cv_bsd_qsort_r,
- [AC_TRY_COMPILE([
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <stdlib.h>
-void qsort_r(void *base, size_t nmemb, size_t size,
+void (qsort_r)(void *base, size_t nmemb, size_t size,
void *arg, int (*compar)(void *, const void *, const void *));
-],[ ],
+]], [[ ]])],
[rb_cv_bsd_qsort_r=yes],
[rb_cv_bsd_qsort_r=no])
])
@@ -2625,7 +2112,7 @@ void qsort_r(void *base, size_t nmemb, size_t size,
AC_CACHE_CHECK(whether atan2 handles Inf as C99, rb_cv_atan2_inf_c99, [
AS_IF([test $ac_cv_func_atan2f:$ac_cv_func_atan2l = yes:yes], [
- AC_TRY_RUN([
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
@%:@include <math.h>
@%:@ifdef HAVE_UNISTD_H
@%:@include <unistd.h>
@@ -2643,7 +2130,7 @@ main(int argc, char **argv)
if (fabs(atan2(INFINITY, INFINITY) - M_PI_4) <= 0.01) return EXIT_SUCCESS;
return EXIT_FAILURE;
}
-],
+]])],
[rb_cv_atan2_inf_c99=yes],
[rb_cv_atan2_inf_c99=no],
[AS_CASE($target_os, [mingw*|mswin*], [rb_cv_atan2_inf_c99=no], [rb_cv_atan2_inf_c99=yes])]
@@ -2662,112 +2149,25 @@ AS_IF([test x"$ac_cv_func_clock_gettime" != xyes], [
])
])
AC_CHECK_FUNCS(clock_getres) # clock_getres should be tested after clock_gettime test including librt test.
+AC_CHECK_LIB([rt], [timer_create])
+AC_CHECK_LIB([rt], [timer_settime])
+AS_IF([test x"$ac_cv_lib_rt_timer_create" = xyes], [
+ AC_DEFINE(HAVE_TIMER_CREATE, 1)
+])
+AS_IF([test x"$ac_cv_lib_rt_timer_settime" = xyes], [
+ AC_DEFINE(HAVE_TIMER_SETTIME, 1)
+])
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
- [AC_TRY_COMPILE([
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdlib.h>
-], [int v = unsetenv("foo");],
+]], [[int v = unsetenv("foo");]])],
rb_cv_unsetenv_return_value=yes,
rb_cv_unsetenv_return_value=no)])
AS_IF([test "$rb_cv_unsetenv_return_value" = no], [
AC_DEFINE(VOID_UNSETENV)
])
-# used for AC_ARG_WITH(setjmp-type)
-AC_DEFUN([RUBY_CHECK_SETJMP], [
-AC_CACHE_CHECK([for ]$1[ as a macro or function], ac_cv_func_$1,
- [AC_TRY_COMPILE([
-@%:@include <setjmp.h>
-]AC_INCLUDES_DEFAULT([$3])[
-@%:@define JMPARGS_1 env
-@%:@define JMPARGS_2 env,1
-@%:@define JMPARGS JMPARGS_]m4_ifval($2,2,1)[
-],
- m4_ifval($2,$2,jmp_buf)[ env; $1(JMPARGS);],
- ac_cv_func_$1=yes,
- ac_cv_func_$1=no)]
-)
-AS_IF([test "$ac_cv_func_]$1[" = yes], [AC_DEFINE([HAVE_]AS_TR_CPP($1), 1)])
-])
-
-AC_DEFUN([RUBY_CHECK_BUILTIN_SETJMP], [
-AS_IF([test x"${ac_cv_func___builtin_setjmp}" = xyes], [
- unset ac_cv_func___builtin_setjmp
-])
-AC_CACHE_CHECK(for __builtin_setjmp, ac_cv_func___builtin_setjmp,
- [
- ac_cv_func___builtin_setjmp=no
- for cast in "" "(void **)"; do
- RUBY_WERROR_FLAG(
- [AC_TRY_LINK([@%:@include <setjmp.h>
- @%:@include <stdio.h>
- jmp_buf jb;
- @%:@ifdef NORETURN
- NORETURN(void t(void));
- @%:@endif
- void t(void) {__builtin_longjmp($cast jb, 1);}
- int jump(void) {(void)(__builtin_setjmp($cast jb) ? 1 : 0); return 0;}],
- [
- void (*volatile f)(void) = t;
- if (!jump()) printf("%d\n", f != 0);
- ],
- [ac_cv_func___builtin_setjmp="yes with cast ($cast)"])
- ])
- test "$ac_cv_func___builtin_setjmp" = no || break
- done])
-])
-
-AC_DEFUN([RUBY_SETJMP_TYPE], [
-RUBY_CHECK_BUILTIN_SETJMP
-RUBY_CHECK_SETJMP(_setjmpex, [], [@%:@include <setjmpex.h>])
-RUBY_CHECK_SETJMP(_setjmp)
-RUBY_CHECK_SETJMP(sigsetjmp, [sigjmp_buf])
-AC_MSG_CHECKING(for setjmp type)
-setjmp_suffix=
-unset setjmp_sigmask
-AC_ARG_WITH(setjmp-type,
- AS_HELP_STRING([--with-setjmp-type], [select setjmp type]),
- [
- AS_CASE([$withval],
- [__builtin_setjmp], [setjmp=__builtin_setjmp],
- [_setjmp], [ setjmp_prefix=_],
- [sigsetjmp,*], [ setjmp_prefix=sig setjmp_sigmask=`expr "$withval" : 'sigsetjmp\(,.*\)'`],
- [sigsetjmp], [ setjmp_prefix=sig],
- [setjmp], [ setjmp_prefix=],
- [setjmpex], [ setjmp_prefix= setjmp_suffix=ex],
- [''], [ unset setjmp_prefix],
- [ AC_MSG_ERROR(invalid setjmp type: $withval)])], [unset setjmp_prefix])
-setjmp_cast=
-AS_IF([test ${setjmp_prefix+set}], [
- AS_IF([test "${setjmp_prefix}" && eval test '$ac_cv_func_'${setjmp_prefix}setjmp${setjmp_suffix} = no], [
- AC_MSG_ERROR(${setjmp_prefix}setjmp${setjmp_suffix} is not available)
- ])
-], [{ AS_CASE("$ac_cv_func___builtin_setjmp", [yes*], [true], [false]) }], [
- setjmp_cast=`expr "$ac_cv_func___builtin_setjmp" : "yes with cast (\(.*\))"`
- setjmp_prefix=__builtin_
- setjmp_suffix=
-], [test "$ac_cv_header_setjmpex_h:$ac_cv_func__setjmpex" = yes:yes], [
- setjmp_prefix=
- setjmp_suffix=ex
-], [test "$ac_cv_func__setjmp" = yes], [
- setjmp_prefix=_
- setjmp_suffix=
-], [test "$ac_cv_func_sigsetjmp" = yes], [
- AS_CASE([$target_os],[solaris*|cygwin*],[setjmp_prefix=],[setjmp_prefix=sig])
- setjmp_suffix=
-], [
- setjmp_prefix=
- setjmp_suffix=
-])
-AS_IF([test x$setjmp_prefix:$setjmp_sigmask = xsig:], [
- setjmp_sigmask=,0
-])
-AC_MSG_RESULT(${setjmp_prefix}setjmp${setjmp_suffix}${setjmp_cast:+\($setjmp_cast\)}${setjmp_sigmask})
-AC_DEFINE_UNQUOTED([RUBY_SETJMP(env)], [${setjmp_prefix}setjmp${setjmp_suffix}($setjmp_cast(env)${setjmp_sigmask})])
-AC_DEFINE_UNQUOTED([RUBY_LONGJMP(env,val)], [${setjmp_prefix}longjmp($setjmp_cast(env),val)])
-AC_DEFINE_UNQUOTED(RUBY_JMP_BUF, ${setjmp_sigmask+${setjmp_prefix}}jmp_buf)
-AS_IF([test x$setjmp_suffix = xex], [AC_DEFINE_UNQUOTED(RUBY_USE_SETJMPEX, 1)])
-])
# End of setjmp check.
AC_ARG_ENABLE(setreuid,
@@ -2779,21 +2179,21 @@ AS_IF([test "$use_setreuid" = yes], [
])
AC_STRUCT_TIMEZONE
AC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff,
- [AC_TRY_COMPILE([
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@define _BSD_SOURCE
@%:@define _DEFAULT_SOURCE
@%:@include <time.h>
- ],
- [struct tm t; t.tm_gmtoff = 3600;],
+ ]],
+ [[struct tm t; t.tm_gmtoff = 3600;]])],
[rb_cv_member_struct_tm_tm_gmtoff=yes],
[rb_cv_member_struct_tm_tm_gmtoff=no])])
AS_IF([test "$rb_cv_member_struct_tm_tm_gmtoff" = yes], [
AC_DEFINE(HAVE_STRUCT_TM_TM_GMTOFF)
])
AC_CACHE_CHECK(for external int daylight, rb_cv_have_daylight,
- [AC_TRY_LINK([#include <time.h>
- int i;],
- [i = daylight;],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <time.h>
+ int i;]],
+ [[i = daylight;]])],
rb_cv_have_daylight=yes,
rb_cv_have_daylight=no)])
AS_IF([test "$rb_cv_have_daylight" = yes], [
@@ -2801,7 +2201,7 @@ AS_IF([test "$rb_cv_have_daylight" = yes], [
])
AC_CACHE_CHECK(for negative time_t for gmtime(3), rb_cv_negative_time_t,
- [AC_TRY_RUN([
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdlib.h>
#include <time.h>
@@ -2831,7 +2231,7 @@ main()
check(gmtime(&t), 1, 12, 13, 20, 52);
return 0;
}
-],
+]])],
rb_cv_negative_time_t=yes,
rb_cv_negative_time_t=no,
rb_cv_negative_time_t=yes)])
@@ -2842,7 +2242,7 @@ AS_IF([test "$rb_cv_negative_time_t" = yes], [
# [ruby-dev:40910] overflow of time on FreeBSD
# http://www.freebsd.org/cgi/query-pr.cgi?pr=145341
AC_CACHE_CHECK(for localtime(3) overflow correctly, rb_cv_localtime_overflow,
- [AC_TRY_RUN([
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdlib.h>
#include <time.h>
@@ -2874,7 +2274,7 @@ main()
check(t);
return 0;
}
-],
+]])],
rb_cv_localtime_overflow=yes,
rb_cv_localtime_overflow=no,
rb_cv_localtime_overflow=no)])
@@ -2887,7 +2287,7 @@ AS_IF([test "$ac_cv_func_sigprocmask" = yes && test "$ac_cv_func_sigaction" = ye
], [
AC_CHECK_FUNCS(sigsetmask)
AC_CACHE_CHECK(for BSD signal semantics, rb_cv_bsd_signal,
- [AC_TRY_RUN([
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <signal.h>
@@ -2905,7 +2305,7 @@ main()
kill(getpid(), SIGINT);
return 0;
}
-],
+]])],
rb_cv_bsd_signal=yes,
rb_cv_bsd_signal=no,
rb_cv_bsd_signal=$ac_cv_func_sigsetmask)])
@@ -2938,21 +2338,6 @@ AS_IF([test x"$ac_cv_func_dirfd" = xno], [
])])
])
-AS_IF([test x"$target_cpu" = xia64], [
- AC_LIBOBJ([ia64])
- AC_CACHE_CHECK(for __libc_ia64_register_backing_store_base,
- rb_cv___libc_ia64_register_backing_store_base,
- [rb_cv___libc_ia64_register_backing_store_base=no
- AC_TRY_LINK(
- [extern unsigned long __libc_ia64_register_backing_store_base;],
- [unsigned long p = __libc_ia64_register_backing_store_base;
- printf("%ld\n", p);],
- [rb_cv___libc_ia64_register_backing_store_base=yes])])
- AS_IF([test $rb_cv___libc_ia64_register_backing_store_base = yes], [
- AC_DEFINE(HAVE___LIBC_IA64_REGISTER_BACKING_STORE_BASE)
- ])
-])
-
AC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign,
[AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [(-1==(-1>>1))])],
rb_cv_rshift_sign=yes,
@@ -2963,55 +2348,55 @@ AS_IF([test "$rb_cv_rshift_sign" = yes], [
AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>(int)(y)) : (x)>>(int)(y)))
])
-AS_IF([test x"$ac_cv_func_gettimeofday" != xyes], [
- AC_MSG_ERROR(gettimeofday() must exist)
+AS_IF([test "$ac_cv_func_copy_file_range" = no], [
+ AC_CACHE_CHECK([for copy_file_range],
+ rb_cv_use_copy_file_range,
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifndef O_TMPFILE
+ #define O_TMPFILE __O_TMPFILE
+#endif
+
+int
+main()
+{
+#ifdef __NR_copy_file_range
+ int ret, fd_in, fd_out;
+ fd_in = open("/tmp", O_TMPFILE|O_RDWR, S_IRUSR);
+ fd_out = open("/tmp", O_TMPFILE|O_WRONLY, S_IWUSR);
+ ret = syscall(__NR_copy_file_range, fd_in, NULL, fd_out, NULL, 0, 0);
+ close(fd_in);
+ close(fd_out);
+ if (ret == -1) { return 1; }
+ return 0;
+#else
+ return 1;
+#endif
+}
+ ]])],
+ [rb_cv_use_copy_file_range=yes],
+ [rb_cv_use_copy_file_range=no],
+ [rb_cv_use_copy_file_range=no])])
+])
+AS_CASE(["$ac_cv_func_copy_file_range:$rb_cv_use_copy_file_range"], [*yes*], [
+ AC_DEFINE(USE_COPY_FILE_RANGE)
+])
+
+AS_CASE(["$ac_cv_func_gettimeofday:$ac_cv_func_clock_gettime"],
+[*yes*], [],
+[
+ AC_MSG_ERROR(clock_gettime() or gettimeofday() must exist)
])
AS_IF([test "$ac_cv_func_sysconf" = yes], [
- AC_DEFUN([RUBY_CHECK_SYSCONF], [dnl
- AC_CACHE_CHECK([whether _SC_$1 is supported], rb_cv_have_sc_[]m4_tolower($1),
- [AC_TRY_COMPILE([#include <unistd.h>
- ],
- [_SC_$1 >= 0],
- rb_cv_have_sc_[]m4_tolower($1)=yes,
- rb_cv_have_sc_[]m4_tolower($1)=no)
- ])
- AS_IF([test "$rb_cv_have_sc_[]m4_tolower($1)" = yes], [
- AC_DEFINE(HAVE__SC_$1)
- ])
- ])
RUBY_CHECK_SYSCONF(CLK_TCK)
])
-AC_DEFUN([RUBY_STACK_GROW_DIRECTION], [
- AS_VAR_PUSHDEF([stack_grow_dir], [rb_cv_stack_grow_dir_$1])
- AC_CACHE_CHECK(stack growing direction on $1, stack_grow_dir, [
-AS_CASE(["$1"],
-[m68*|x86*|x64|i?86|ia64|ppc*|sparc*|alpha*], [ $2=-1],
-[hppa*], [ $2=+1],
-[
- AC_TRY_RUN([
-/* recurse to get rid of inlining */
-static int
-stack_growup_p(addr, n)
- volatile int *addr, n;
-{
- volatile int end;
- if (n > 0)
- return *addr = stack_growup_p(addr, n - 1);
- else
- return (&end > addr);
-}
-int main()
-{
- int x;
- return stack_growup_p(&x, 10);
-}
-], $2=-1, $2=+1, $2=0)
- ])
-eval stack_grow_dir=\$$2])
-eval $2=\$stack_grow_dir
-AS_VAR_POPDEF([stack_grow_dir])])
AS_IF([test "${universal_binary-no}" = yes ], [
archflagpat=`eval echo '"'"${ARCH_FLAG}"'"' | sed 's/[[][|.*]]/\\&/g'`
save_CFLAGS="$CFLAGS" new_cflags=`echo "$CFLAGS" | sed "s|$archflagpat"'||'`
@@ -3043,35 +2428,104 @@ AS_IF([test "${universal_binary-no}" = yes ], [
AC_DEFINE_UNQUOTED(STACK_GROW_DIRECTION, $dir)
])
+AC_ARG_WITH(coroutine,
+ AS_HELP_STRING([--with-coroutine=IMPLEMENTATION], [specify the coroutine implementation to use]),
+ [rb_cv_coroutine=$withval])
+AS_CASE([$rb_cv_coroutine], [yes|''], [
+ AC_MSG_CHECKING(native coroutine implementation for ${target_cpu}-${target_os})
+ rb_cv_coroutine=
+ AS_CASE(["$target_cpu-$target_os"],
+ [x*64-darwin*], [
+ rb_cv_coroutine=amd64
+ ],
+ [arm64-darwin*], [
+ rb_cv_coroutine=arm64
+ ],
+ [x*64-linux*], [
+ AS_CASE(["$ac_cv_sizeof_voidp"],
+ [8], [ rb_cv_coroutine=amd64 ],
+ [4], [ rb_cv_coroutine=x86 ],
+ dnl unknown pointer size, bail out as no Context.h soon.
+ )
+ ],
+ [*86-linux*], [
+ rb_cv_coroutine=x86
+ ],
+ [x64-mingw32], [
+ rb_cv_coroutine=win64
+ ],
+ [*86-mingw32], [
+ rb_cv_coroutine=win32
+ ],
+ [arm*-linux*], [
+ rb_cv_coroutine=arm32
+ ],
+ [aarch64-linux*], [
+ rb_cv_coroutine=arm64
+ ],
+ [powerpc64le-linux*], [
+ rb_cv_coroutine=ppc64le
+ ],
+ [x86_64-openbsd*], [
+ rb_cv_coroutine=amd64
+ ],
+ [i386-openbsd*], [
+ rb_cv_coroutine=x86
+ ],
+ [*-openbsd*], [
+ rb_cv_coroutine=copy
+ ],
+ [*-haiku*], [
+ rb_cv_coroutine=copy
+ ],
+ [
+ rb_cv_coroutine=ucontext
+ ]
+ )
+ AC_MSG_RESULT(${rb_cv_coroutine})
+])
+COROUTINE_H=coroutine/$rb_cv_coroutine/Context.h
+AS_IF([test ! -f "$srcdir/$COROUTINE_H"],
+ [AC_MSG_ERROR('$rb_cv_coroutine' is not supported as coroutine)])
+AS_CASE([$rb_cv_coroutine],
+ [copy|ucontext], [
+ COROUTINE_SRC=coroutine/$rb_cv_coroutine/Context.c
+ ],
+ [
+ COROUTINE_SRC=coroutine/$rb_cv_coroutine/Context.'$(ASMEXT)'
+ ]
+)
+AC_DEFINE_UNQUOTED(COROUTINE_H, ["$COROUTINE_H"])
+AC_SUBST(X_COROUTINE_H, [$COROUTINE_H])
+AC_SUBST(X_COROUTINE_SRC, [$COROUTINE_SRC])
+
AS_IF([test x"$enable_pthread" = xyes], [
for pthread_lib in thr pthread pthreads c c_r root; do
- AC_CHECK_LIB($pthread_lib, pthread_kill,
+ AC_CHECK_LIB($pthread_lib, pthread_create,
rb_with_pthread=yes, rb_with_pthread=no)
- AS_IF([test "$rb_with_pthread" = "yes"], [ break; fi
+ AS_IF([test "$rb_with_pthread" = "yes"], [break])
done
AS_IF([test x"$rb_with_pthread" = xyes], [
AC_DEFINE(_REENTRANT)
AC_DEFINE(_THREAD_SAFE)
AC_DEFINE(HAVE_LIBPTHREAD)
AC_CHECK_HEADERS(pthread_np.h, [], [], [@%:@include <pthread.h>])
- AS_CASE([$pthread_lib],
- [c], [],
- [root], [],
- [c_r], [MAINLIBS="-pthread $MAINLIBS"],
- [AS_CASE(["$target_os"],
- [openbsd*|mirbsd*], [LIBS="-pthread $LIBS"],
- [LIBS="-l$pthread_lib $LIBS"])])
+ AS_CASE(["$pthread_lib:$target_os"],
+ [c:*], [],
+ [root:*], [],
+ [c_r:*|*:openbsd*|*:mirbsd*], [LIBS="-pthread $LIBS"],
+ [LIBS="-l$pthread_lib $LIBS"])
], [
AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled")
])
AC_CACHE_CHECK([whether pthread_t is scalar type], [rb_cv_scalar_pthread_t], [
- AC_TRY_COMPILE([
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <pthread.h>
- ], [
+ ]], [[
pthread_t thread_id;
thread_id = 0;
if (!thread_id) return 0;
- ], [rb_cv_scalar_pthread_t=yes], [rb_cv_scalar_pthread_t=no])
+ ]])],[rb_cv_scalar_pthread_t=yes],[rb_cv_scalar_pthread_t=no])
])
AS_IF([test x"$rb_cv_scalar_pthread_t" = xyes], [
: # RUBY_CHECK_SIZEOF(pthread_t, [void* int long], [], [@%:@include <pthread.h>])
@@ -3079,37 +2533,32 @@ AS_IF([test x"$enable_pthread" = xyes], [
AC_DEFINE(NON_SCALAR_THREAD_ID)
])
AC_CHECK_FUNCS(sched_yield pthread_attr_setinheritsched \
- pthread_attr_get_np pthread_attr_getstack\
+ pthread_attr_get_np pthread_attr_getstack pthread_attr_getguardsize \
pthread_get_stackaddr_np pthread_get_stacksize_np \
thr_stksegment pthread_stackseg_np pthread_getthrds_np \
- pthread_cond_init pthread_condattr_setclock pthread_condattr_init \
+ pthread_condattr_setclock \
pthread_sigmask pthread_setname_np pthread_set_name_np)
AS_CASE(["$target_os"],[aix*],[ac_cv_func_pthread_getattr_np=no],[AC_CHECK_FUNCS(pthread_getattr_np)])
- AS_IF([test "${host_os}" = "nacl"], [
- ac_cv_func_pthread_attr_init=no
- ], [
- AC_CHECK_FUNCS(pthread_attr_init)
- ])
set_current_thread_name=
AS_IF([test "$ac_cv_func_pthread_setname_np" = yes], [
AC_CACHE_CHECK([arguments of pthread_setname_np], [rb_cv_func_pthread_setname_np_arguments],
[rb_cv_func_pthread_setname_np_arguments=
# Linux,AIX, (pthread_self(), name)
- # NetBSD (pthread_self(), name, \"%s\")
+ # NetBSD (pthread_self(), \"%s\", name)
# Darwin (name)
for mac in \
"(pthread_self(), name)" \
- "(pthread_self(), name, \"%s\")" \
+ "(pthread_self(), \"%s\", name)" \
"(name)" \
; do
- AC_TRY_COMPILE([
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <pthread.h>
@%:@ifdef HAVE_PTHREAD_NP_H
@%:@include <pthread_np.h>
@%:@endif
@%:@define SET_THREAD_NAME(name) pthread_setname_np${mac}
- ],
- [if (SET_THREAD_NAME("conftest")) return 1;],
+ ]],
+ [[if (SET_THREAD_NAME("conftest")) return 1;]])],
[rb_cv_func_pthread_setname_np_arguments="${mac}"
break])
done
@@ -3133,8 +2582,8 @@ AS_IF([test x"$enable_pthread" = xyes], [
AS_IF([test x"$ac_cv_header_ucontext_h" = xno], [
AC_CACHE_CHECK([if signal.h defines ucontext_t], [rb_cv_ucontext_in_signal_h],
- [AC_TRY_COMPILE([@%:@include <signal.h>],
- [size_t size = sizeof(ucontext_t);],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <signal.h>]],
+ [[size_t size = sizeof(ucontext_t);]])],
[rb_cv_ucontext_in_signal_h=yes], [rb_cv_ucontext_in_signal_h=no])])
AS_IF([test x"$rb_cv_ucontext_in_signal_h" = xyes], [
AC_DEFINE_UNQUOTED(UCONTEXT_IN_SIGNAL_H, 1)
@@ -3142,14 +2591,14 @@ AS_IF([test x"$ac_cv_header_ucontext_h" = xno], [
])
AS_IF([test x"$ac_cv_header_ucontext_h" = xyes -o x"$rb_cv_ucontext_in_signal_h" = xyes], [
AC_CACHE_CHECK([if mcontext_t is a pointer], [rb_cv_mcontext_t_ptr],
- [AC_TRY_COMPILE([
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <signal.h>
@%:@ifdef HAVE_UCONTEXT_H
@%:@include <ucontext.h>
@%:@endif
mcontext_t test(mcontext_t mc) {return mc+1;}
- ],
- [test(0);],
+ ]],
+ [[test(0);]])],
[rb_cv_mcontext_t_ptr=yes], [rb_cv_mcontext_t_ptr=no])])
AS_IF([test x"$rb_cv_mcontext_t_ptr" = xyes], [
AC_DEFINE_UNQUOTED(DEFINE_MCONTEXT_PTR(mc, uc), mcontext_t mc = (uc)->uc_mcontext)
@@ -3163,7 +2612,7 @@ AS_IF([test x"$ac_cv_header_ucontext_h" = xyes -o x"$rb_cv_ucontext_in_signal_h"
AS_IF([test "$ac_cv_func_fork_works" = "yes" -a "$rb_with_pthread" = "yes"], [
AC_CACHE_CHECK([if fork works with pthread], rb_cv_fork_with_pthread,
- [AC_TRY_RUN([
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
@@ -3219,17 +2668,15 @@ main(int argc, char *argv[])
}
return EXIT_SUCCESS;
-}],
+}]])],
rb_cv_fork_with_pthread=yes,
rb_cv_fork_with_pthread=no,
rb_cv_fork_with_pthread=yes)])
test x$rb_cv_fork_with_pthread = xyes || AC_DEFINE(CANNOT_FORK_WITH_PTHREAD)
])
-
-
}
-{ # runtime section
+: "runtime section" && {
dnl wheather use dln_a_out or not
AC_ARG_WITH(dln-a-out,
AS_HELP_STRING([--with-dln-a-out], [use dln_a_out if possible]),
@@ -3244,7 +2691,7 @@ AC_ARG_WITH(dln-a-out,
with_dln_a_out=no])], [with_dln_a_out=no])
AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf,
-[AC_TRY_LINK([],[], [
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[
AS_CASE(["`head -1 conftest$EXEEXT | tr -dc '\177ELF' | tr '\177' .`"],
[.ELF*], [rb_cv_binary_elf=yes], [rb_cv_binary_elf=no])],
rb_cv_binary_elf=no)])
@@ -3257,11 +2704,17 @@ AS_IF([test "$rb_cv_binary_elf" = yes], [
AC_CHECK_HEADERS([elf.h elf_abi.h])
AS_IF([test $ac_cv_header_elf_h = yes -o $ac_cv_header_elf_abi_h = yes], [
AC_LIBOBJ([addr2line])
+ AC_CHECK_LIB([z], [uncompress])
])
])
+AC_CHECK_HEADERS([mach-o/loader.h])
+AS_IF([test "$ac_cv_header_mach_o_loader_h" = yes], [
+ AC_LIBOBJ([addr2line])
+])
+
AS_CASE(["$target_os"],
-[linux* | gnu* | k*bsd*-gnu | bsdi* | kopensolaris*-gnu | nacl], [
+[linux* | gnu* | k*bsd*-gnu | bsdi* | kopensolaris*-gnu], [
AS_IF([test "$rb_cv_binary_elf" = no], [
with_dln_a_out=yes
], [
@@ -3269,8 +2722,22 @@ AS_CASE(["$target_os"],
])])
LIBEXT=a
+AC_ARG_WITH(mjit-tabs,
+ AS_HELP_STRING([--without-mjit-tabs], [expand tabs in mjit header]),
+ [AS_IF([test $withval = no], [MJIT_TABS=false])])
+AC_SUBST(MJIT_TABS)dnl
AC_SUBST(DLDFLAGS)dnl
AC_SUBST(ARCH_FLAG)dnl
+AC_SUBST(MJIT_HEADER_FLAGS)dnl
+AC_SUBST(MJIT_HEADER_INSTALL_DIR)dnl
+AC_SUBST(MJIT_CC)dnl
+AS_IF([test "$GCC" = "yes"], [
+ AS_CASE(["$target_os"],[aix*],[mjit_std_cflag="-std=gnu99"])
+])
+AC_SUBST(MJIT_CFLAGS, [${MJIT_CFLAGS-"-w ${mjit_std_cflag} ${orig_cflags}"}])dnl
+AC_SUBST(MJIT_OPTFLAGS, [${MJIT_OPTFLAGS-'$(optflags)'}])dnl
+AC_SUBST(MJIT_DEBUGFLAGS, [${MJIT_DEBUGFLAGS-'$(debugflags)'}])dnl
+AC_SUBST(MJIT_LDSHARED)dnl
AC_SUBST(STATIC)dnl
AC_SUBST(CCDLFLAGS)dnl
@@ -3377,19 +2844,33 @@ AS_IF([test "$with_dln_a_out" != yes], [
])
rb_cv_dlopen=yes],
[darwin*], [ : ${LDSHARED='$(CC) -dynamic -bundle'}
+ : ${DLDSHARED='$(CC) -dynamiclib'}
: ${LDFLAGS=""}
- : ${LIBPATHENV=DYLD_LIBRARY_PATH}
+ : ${LIBPATHENV=DYLD_FALLBACK_LIBRARY_PATH}
: ${PRELOADENV=DYLD_INSERT_LIBRARIES}
+ AS_IF([test x"$enable_shared" = xyes], [
+ # Resolve symbols from libruby.dylib when --enable-shared
+ EXTDLDFLAGS='$(LIBRUBYARG_SHARED)'
+ ], [test "x$EXTSTATIC" = x], [
+ # When building exts as bundles, a mach-o bundle needs to know its loader
+ # program to bind symbols from the ruby executable
+ EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'"
+ ])
rb_cv_dlopen=yes],
[aix*], [ : ${LDSHARED='$(CC)'}
- LDSHARED="$LDSHARED ${linker_flag}-G"
+ AS_IF([test "$GCC" = yes], [
+ LDSHARED="$LDSHARED ${linker_flag}-G -shared"
+ ], [
+ LDSHARED="$LDSHARED ${linker_flag}-G"
+ ])
EXTDLDFLAGS='-e$(TARGET_ENTRY)'
XLDFLAGS="${linker_flag}"'-bE:$(ARCHFILE)'" ${linker_flag}-brtl"
XLDFLAGS="$XLDFLAGS ${linker_flag}-blibpath:${prefix}/lib:${LIBPATH:-/usr/lib:/lib}"
: ${ARCHFILE="ruby.imp"}
- TRY_LINK='$(CC) $(LDFLAGS) -oconftest $(INCFLAGS) -I$(hdrdir) $(CPPFLAGS)'
- TRY_LINK="$TRY_LINK"' $(CFLAGS) $(src) $(LIBPATH) $(LOCAL_LIBS) $(LIBS)'
+ TRY_LINK='$(CC) -oconftest $(INCFLAGS) -I$(hdrdir) $(CPPFLAGS)'
+ TRY_LINK="$TRY_LINK"' $(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(LOCAL_LIBS) $(LIBS)'
: ${LIBPATHENV=LIBPATH}
+ : ${PRELOADENV=LDR_PRELOAD}
rb_cv_dlopen=yes],
[nto-qnx*], [ DLDFLAGS="$DLDFLAGS -L/lib -L/usr/lib -L/usr/local/lib"
: ${LDSHARED='$(LD) -Bshareable -x'}
@@ -3405,22 +2886,32 @@ AS_IF([test "$with_dln_a_out" != yes], [
[hiuxmpp], [ : ${LDSHARED='$(LD) -r'}],
[atheos*], [ : ${LDSHARED='$(CC) -shared'}
rb_cv_dlopen=yes],
- [nacl], [ LDSHARED='$(CC) -shared' ],
[ : ${LDSHARED='$(LD)'}])
AC_MSG_RESULT($rb_cv_dlopen)
AS_IF([test "$rb_cv_dlopen" = yes], [
AS_CASE(["$target_os"],
[darwin*], [
+ AC_SUBST(ADDITIONAL_DLDFLAGS, "")
for flag in \
- "-undefined dynamic_lookup" \
"-multiply_defined suppress" \
+ "-undefined dynamic_lookup" \
; do
- test "x${linker_flag}" = x || flag="${linker_flag}`echo ${flag} | tr ' ' ,`"
- RUBY_TRY_LDFLAGS([$flag], [], [flag=])
- AS_IF([test "x$flag" != x], [
- RUBY_APPEND_OPTIONS(DLDFLAGS, [$flag])
- ])
+ test "x${linker_flag}" = x || flag="${linker_flag}`echo ${flag} | tr ' ' ,`"
+ RUBY_TRY_LDFLAGS([$flag], [], [flag=])
+ AS_IF([test x"$flag" = x], [continue])
+
+ AC_MSG_CHECKING([whether $flag is accepted for bundle])
+ : > conftest.c
+ AS_IF([${LDSHARED/'$(CC)'/$CC} -o conftest.bundle $flag conftest.c >/dev/null 2>conftest.err &&
+ test ! -s conftest.err], [
+ AC_MSG_RESULT([yes])
+ RUBY_APPEND_OPTIONS(DLDFLAGS, [$flag])
+ ], [
+ AC_MSG_RESULT([no])
+ RUBY_APPEND_OPTIONS(ADDITIONAL_DLDFLAGS, [$flag])
+ ])
+ rm -fr conftest.*
done
])
])
@@ -3480,6 +2971,7 @@ AS_CASE(["$target_os"],
])
AS_CASE(["$target_cpu-$target_os"],
[*-darwin*], [
+ AC_CHECK_HEADERS([libproc.h])
AC_CHECK_HEADERS([execinfo.h])
AS_IF([test "x$ac_cv_header_execinfo_h" = xyes], [
AC_CHECK_LIB([execinfo], [backtrace])
@@ -3495,7 +2987,7 @@ AC_CHECK_FUNCS(backtrace)
AS_IF([test "x$ac_cv_func_backtrace" = xyes], [
AC_CACHE_CHECK(for broken backtrace, rb_cv_broken_backtrace,
- [AC_TRY_RUN([
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -3504,6 +2996,7 @@ AS_IF([test "x$ac_cv_func_backtrace" = xyes], [
#include <signal.h>
#include <execinfo.h>
+]`grep '^@%:@ *define *RUBY_SIGALTSTACK_SIZE' ${srcdir}/signal.c`[
#define TRACE_SIZE 256
void sigsegv(int signum, siginfo_t *info, void *ctx){
@@ -3521,18 +3014,19 @@ main(void)
{
volatile int *a = NULL;
stack_t ss;
- ss.ss_sp = malloc(SIGSTKSZ);
+ struct sigaction sa;
+
+ ss.ss_sp = malloc(RUBY_SIGALTSTACK_SIZE);
if (ss.ss_sp == NULL) {
fprintf(stderr, "cannot allocate memory for sigaltstack\n");
return EXIT_FAILURE;
}
- ss.ss_size = SIGSTKSZ;
+ ss.ss_size = RUBY_SIGALTSTACK_SIZE;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) == -1) {
fprintf(stderr, "sigaltstack failed\n");
return EXIT_FAILURE;
}
- struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = sigsegv;
@@ -3542,7 +3036,7 @@ main(void)
a[0] = 1;
return EXIT_SUCCESS;
}
-],
+]])],
rb_cv_broken_backtrace=no,
rb_cv_broken_backtrace=yes,
rb_cv_broken_backtrace=no)])
@@ -3562,11 +3056,10 @@ AS_IF([test "$ac_cv_header_a_out_h" = yes], [
AS_IF([test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown], [
cat confdefs.h > config.h
AC_CACHE_CHECK(whether matz's dln works, rb_cv_dln_a_out,
- [AC_TRY_COMPILE([
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#define USE_DLN_A_OUT
#include "dln.c"
-],
- [],
+]], [[]])],
rb_cv_dln_a_out=yes,
rb_cv_dln_a_out=no)])
AS_IF([test "$rb_cv_dln_a_out" = yes], [
@@ -3589,14 +3082,17 @@ AS_IF([test "$dln_a_out_works" = yes], [
[hpux*], [
DLEXT=sl],
[darwin*], [
- RUBY_APPEND_OPTION(XLDFLAGS, [-Wl,-u,_objc_msgSend])
+ SOEXT=dylib
DLEXT=bundle],
[cygwin*|mingw*|*djgpp*], [
LOAD_RELATIVE=1
+ SOEXT=dll
DLEXT=so],
[
DLEXT=so])
])
+: ${SOEXT="${DLEXT}"}
+AC_SUBST(SOEXT)
AS_IF([test "$rb_cv_dlopen:$load_relative" = yes:yes], [
AS_IF([test "$ac_cv_func_dladdr" = yes], [
LOAD_RELATIVE=1
@@ -3619,20 +3115,27 @@ AC_SUBST(DLEXT)
AS_IF([test "$with_dln_a_out" = yes], [
STRIP=true
], [
- AC_CHECK_TOOL(STRIP, strip, :)dnl
+ AC_MSG_CHECKING([for $STRIP flags])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM], [AS_IF(
+ ["${STRIP}" -A -n conftest$ac_exeext 2>/dev/null], [
+ AC_MSG_RESULT([-A -n])
+ STRIP="${STRIP} -A -n"
+ ],
+ ["${STRIP}" -S -x conftest$ac_exeext 2>/dev/null], [
+ AC_MSG_RESULT([-S -x])
+ STRIP="${STRIP} -S -x"
+ ], [
+ AC_MSG_RESULT([none needed])
+ ])
+ ])
])
-AS_CASE(["$target_os"],
- [linux* | gnu* | k*bsd*-gnu | kopensolaris*-gnu], [
- STRIP="$STRIP -S -x"],
- [darwin*], [
- STRIP="$STRIP -A -n"])
AC_ARG_WITH(ext,
- AC_HELP_STRING([--with-ext=EXTS],
+ AS_HELP_STRING([--with-ext=EXTS],
[pass to --with-ext option of extmk.rb]))
AC_ARG_WITH(out-ext,
- AC_HELP_STRING([--with-out-ext=EXTS],
+ AS_HELP_STRING([--with-out-ext=EXTS],
[pass to --without-ext option of extmk.rb]))
EXTSTATIC=
AC_SUBST(EXTSTATIC)dnl
@@ -3700,6 +3203,7 @@ for var in bindir libdir rubylibprefix; do
done
BTESTRUBY='$(MINIRUBY)'
+BOOTSTRAPRUBY='$(BASERUBY)'
AS_IF([test x"$cross_compiling" = xyes], [
test x"$MINIRUBY" = x && MINIRUBY="${RUBY-$BASERUBY} -I`$CHDIR .; pwd` "-r'$(arch)-fake'
XRUBY_LIBDIR=`${RUBY-$BASERUBY} -rrbconfig -e ['puts RbConfig::CONFIG["libdir"]']`
@@ -3712,31 +3216,17 @@ AS_IF([test x"$cross_compiling" = xyes], [
RUNRUBY_COMMAND='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`'
RUNRUBY='$(RUNRUBY_COMMAND)'
XRUBY='$(MINIRUBY)'
- BOOTSTRAPRUBY='$(BASERUBY)'
TEST_RUNNABLE=no
CROSS_COMPILING=yes
-
- AS_IF([test "$host_os" = "nacl"], [
- AS_IF([test "$build_cpu" = "$host_cpu" || test "${nacl_cv_cpu_nick}" = "x86" -a "$host_cpu" = "i686"], [
- nacl_cv_sel_ldr='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb sel_ldr`'
- nacl_cv_irt_core='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb irt_core`'
- nacl_cv_runnable_ld='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb runnable_ld`'
- nacl_cv_host_lib='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb host_lib`'
- TEST_RUNNABLE=yes
- BTESTRUBY="${nacl_cv_sel_ldr} -a -B ${nacl_cv_irt_core} -w 1:3 -w 2:4"
- BTESTRUBY="$BTESTRUBY -- ${nacl_cv_runnable_ld} --library-path ${nacl_cv_host_lib}"
- BTESTRUBY="$BTESTRUBY `pwd`/"'miniruby$(EXEEXT) -I`cd $(srcdir)/lib; pwd` -I.'
- BTESTRUBY="$BTESTRUBY"' -I$(EXTOUT)/common 3>&1 4>&2 1>/dev/null 2>/dev/null '
- ])
- ])
+ AC_DEFINE(CROSS_COMPILING, 1)
], [
MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib -I.'
MINIRUBY="$MINIRUBY"' -I$(EXTOUT)/common'
PREP='miniruby$(EXEEXT)'
- RUNRUBY_COMMAND='$(MINIRUBY) $(srcdir)/tool/runruby.rb --extout=$(EXTOUT) $(RUNRUBYOPT)'
+ RUNRUBY_COMMAND='$(MINIRUBY) $(tooldir)/runruby.rb --extout=$(EXTOUT) $(RUNRUBYOPT)'
RUNRUBY='$(RUNRUBY_COMMAND) --'
XRUBY='$(RUNRUBY)'
- BOOTSTRAPRUBY='$(MINIRUBY)'
+ AS_CASE(["$HAVE_BASERUBY:$build_os"], [no:*|*:mingw*], [BOOTSTRAPRUBY='$(MINIRUBY)'])
TEST_RUNNABLE=yes
CROSS_COMPILING=no
])
@@ -3751,12 +3241,12 @@ AC_SUBST(XRUBY)
AC_SUBST(BOOTSTRAPRUBY)
AC_SUBST(EXTOUT, [${EXTOUT=.ext}])
-])RSTMAKEFILE=""
+FIRSTMAKEFILE=""
LIBRUBY_A='lib$(RUBY_SO_NAME)-static.a'
LIBRUBY='$(LIBRUBY_A)'
LIBRUBYARG_STATIC='-l$(RUBY_SO_NAME)-static'
LIBRUBYARG='$(LIBRUBYARG_STATIC)'
-SOLIBS=
+SOLIBS='$(MAINLIBS)'
AS_CASE(["$target_os"],
[cygwin*|mingw*|haiku*|darwin*], [
@@ -3771,6 +3261,9 @@ AC_ARG_ENABLE(multiarch,
[multiarch=], [unset multiarch])
AS_IF([test ${multiarch+set}], [
AC_DEFINE(ENABLE_MULTIARCH)
+ MJIT_HEADER_INSTALL_DIR=include/'${arch}/${RUBY_VERSION_NAME}'
+], [
+ MJIT_HEADER_INSTALL_DIR=include/'${RUBY_VERSION_NAME}/${arch}'
])
archlibdir='${libdir}/${arch}'
@@ -3784,7 +3277,7 @@ AC_ARG_WITH(soname,
[
AS_CASE(["$target_os"],
[darwin*], [
- RUBY_SO_NAME='$(RUBY_BASE_NAME).$(RUBY_PROGRAM_VERSION)'
+ RUBY_SO_NAME='$(RUBY_BASE_NAME).$(RUBY_API_VERSION)'
],
[cygwin*], [
RUBY_SO_NAME='$(RUBY_BASE_NAME)$(MAJOR)$(MINOR)0'
@@ -3798,10 +3291,11 @@ AC_ARG_WITH(soname,
[RUBY_SO_NAME='$(RUBY_BASE_NAME)'])
])
-LIBRUBY_LDSHARED=$LDSHARED
+LIBRUBY_LDSHARED=${DLDSHARED=${LDSHARED}}
LIBRUBY_DLDFLAGS=$DLDFLAGS
-LIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(RUBY_PROGRAM_VERSION)'
-LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so'
+LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(RUBY_PROGRAM_VERSION)'
+LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(RUBY_API_VERSION)'
+LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).$(SOEXT)'
ENABLE_SHARED=no
AC_ARG_ENABLE(shared,
@@ -3816,9 +3310,6 @@ AS_CASE("$enable_shared", [yes], [
LIBRUBY_RELATIVE=no
test -z "$CCDLFLAGS" || CFLAGS="$CFLAGS $CCDLFLAGS"
ENABLE_SHARED=yes
- AS_IF([test "$rb_cv_binary_elf" = yes], [
- SOLIBS='$(LIBS)'
- ])
# libdir can be overridden in config.site file (on OpenSUSE at least).
libdir_basename=lib
@@ -3828,6 +3319,11 @@ AS_CASE("$enable_shared", [yes], [
AC_DEFINE_UNQUOTED(LIBDIR_BASENAME, ["${libdir_basename}"])
libdir_basename="${libdir_basename}"${multiarch+'/${arch}'}
+ RUBY_TRY_LDFLAGS([${linker_flag}--no-as-needed], [no_as_needed=yes], [no_as_needed=no])
+ AS_IF([test "$no_as_needed" = yes], [
+ RUBY_APPEND_OPTIONS(LDFLAGS, [${linker_flag}--no-as-needed])
+ ])
+
AS_CASE(["$target_os"],
[freebsd*|dragonfly*], [],
[
@@ -3841,11 +3337,11 @@ AS_CASE("$enable_shared", [yes], [
AS_CASE(["$target_os"],
[sunos4*], [
- LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(RUBY_API_VERSION) lib$(RUBY_SO_NAME).so'
+ LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)'
],
[linux* | gnu* | k*bsd*-gnu | atheos* | kopensolaris*-gnu | haiku*], [
- RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,lib$(RUBY_SO_NAME).so.$(RUBY_API_VERSION)' "$LDFLAGS_OPTDIR"])
- LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(RUBY_API_VERSION) lib$(RUBY_SO_NAME).so'
+ RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,$(LIBRUBY_SONAME)' "$LDFLAGS_OPTDIR"])
+ LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)'
AS_IF([test "$load_relative" = yes], [
libprefix="'\$\${ORIGIN}/../${libdir_basename}'"
LIBRUBY_RPATHFLAGS="-Wl,-rpath,${libprefix}"
@@ -3853,55 +3349,51 @@ AS_CASE("$enable_shared", [yes], [
])
],
[freebsd*|dragonfly*], [
- SOLIBS='$(LIBS)'
- LIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR)'
+ LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)$(MINOR)'
+ LIBRUBY_SONAME='$(LIBRUBY_SO)'
AS_IF([test "$rb_cv_binary_elf" != "yes" ], [
LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)"
LIBRUBY_ALIASES=''
])
],
[netbsd*], [
- SOLIBS='$(LIBS)'
- LIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR).$(TEENY)'
- RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR)' "$LDFLAGS_OPTDIR"])
+ LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)$(MINOR)'
+ LIBRUBY_SO="${LIBRUBY_SONAME}"'.$(TEENY)'
+ RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,$(LIBRUBY_SONAME)' "$LDFLAGS_OPTDIR"])
AS_IF([test "$rb_cv_binary_elf" = yes], [ # ELF platforms
- LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR) lib$(RUBY_SO_NAME).so'
+ LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)'
], [ # a.out platforms
LIBRUBY_ALIASES=""
])
],
[openbsd*|mirbsd*], [
- SOLIBS='$(LIBS)'
- LIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR).'`expr ${MINOR} \* 10 + ${TEENY}`
+ LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR).'`expr ${MINOR} \* 10 + ${TEENY}`
],
[solaris*], [
- SOLIBS='$(LIBS)'
- LIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR)'
- LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(RUBY_PROGRAM_VERSION) lib$(RUBY_SO_NAME).so'
- AS_IF([test "$GCC" = yes], [
- LIBRUBY_DLDFLAGS="$DLDFLAGS "'-Wl,-h,$(@F)'
- ], [
- LIBRUBY_DLDFLAGS="$DLDFLAGS "'-h $(@F)'
- ])
+ LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)'
+ LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(RUBY_PROGRAM_VERSION)'
+ LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)'
+ RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ["${linker_flag}-h${linker_flag:+,}"'$(@F)'])
XLDFLAGS="$XLDFLAGS "'-R${libdir}'
],
[hpux*], [
XLDFLAGS="$XLDFLAGS "'-Wl,+s,+b,$(libdir)'
- LIBRUBY_SO='lib$(RUBY_SO_NAME).sl.$(RUBY_PROGRAM_VERSION)'
- LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).sl.$(RUBY_API_VERSION) lib$(RUBY_SO_NAME).sl'
+ LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)'
],
[aix*], [
RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ["${linker_flag}-bnoentry" "$XLDFLAGS" "$LDFLAGS_OPTDIR"])
LIBRUBYARG_SHARED='-L${libdir} -l${RUBY_SO_NAME}'
- SOLIBS='-lm -lc'
+ LIBS="$LIBS -lm -lc"
],
[darwin*], [
- LIBRUBY_LDSHARED='$(CC) -dynamiclib'
+ LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT)'
+ LIBRUBY_SONAME='$(LIBRUBY_SO)'
+ LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).$(SOEXT)'
AS_IF([test "$load_relative" = yes], [
libprefix="@executable_path/../${libdir_basename}"
LIBRUBY_RELATIVE=yes
])
- LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "'-install_name '${libprefix}'/lib$(RUBY_BASE_NAME).$(RUBY_API_VERSION).dylib'
+ LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS -install_name ${libprefix}"'/$(LIBRUBY_SONAME)'
LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "'-compatibility_version $(RUBY_API_VERSION)'
LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "'-current_version $(RUBY_PROGRAM_VERSION)'
AS_IF([test "$visibility_option" = ld], [
@@ -3910,9 +3402,6 @@ AS_CASE("$enable_shared", [yes], [
LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "'-Wl,-unexported_symbol,*_threadptr_*'
])
LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "' $(XLDFLAGS)'
- LIBRUBY_SO='lib$(RUBY_SO_NAME).dylib'
- LIBRUBY_ALIASES='lib$(RUBY_BASE_NAME).$(RUBY_API_VERSION).dylib lib$(RUBY_INSTALL_NAME).dylib'
- SOLIBS='$(LIBS)'
],
[interix*], [
LIBRUBYARG_SHARED='-L. -L${libdir} -l$(RUBY_SO_NAME)'
@@ -3927,11 +3416,6 @@ AS_CASE("$enable_shared", [yes], [
AC_ARG_ENABLE(pie,
AS_HELP_STRING([--disable-pie], [disable PIE feature]),
[pie=$enableval], [pie=])
- AS_CASE(["$target_os"],
- [nacl], [
- # -pie implies -shared for NaCl.
- pie=no
- ])
AS_IF([test "$GCC" = yes -a -z "$EXTSTATIC" -a "x$pie" != xno], [
RUBY_TRY_CFLAGS(-fPIE, [pie=yes], [pie=no])
AS_IF([test "$pie" = yes], [
@@ -3999,6 +3483,9 @@ AS_CASE(["${enable_dtrace}"],
], [
rb_cv_dtrace_available=no
])
+AS_CASE(["$target_os"],[freebsd*],[
+ rb_cv_dtrace_available=no
+ ])
AS_IF([test "${enable_dtrace}" = yes], [dnl
AS_IF([test -z "$DTRACE"], [dnl
AC_MSG_ERROR([dtrace(1) is missing])
@@ -4043,26 +3530,38 @@ AS_IF([test x"$gcov" = xyes], [
RUBY_SETJMP_TYPE
}
-{ # build section
+: "build section" && {
dnl build rdoc index if requested
RDOCTARGET=""
CAPITARGET=""
AC_ARG_ENABLE(install-doc,
AS_HELP_STRING([--disable-install-doc], [do not install either rdoc indexes or C API documents during install]),
[install_doc=$enableval], [install_doc=yes])
+AC_ARG_WITH(rdoc,
+ AS_HELP_STRING([--with-rdoc=ri,html], [comma/space separated list of RDoc formats to install]),
+ [install_rdoc=`echo ,$withval, | sed 'y/,/ /;s/ ri / rdoc /;s/^ *//;s/ *$//'`], [
AC_ARG_ENABLE(install-rdoc,
AS_HELP_STRING([--disable-install-rdoc], [do not install rdoc indexes during install]),
[install_rdoc=$enableval], [install_rdoc=yes])
+])
AC_ARG_ENABLE(install-capi,
AS_HELP_STRING([--disable-install-capi], [do not install C API documents during install]),
[install_capi=$enableval], [install_capi=no])
AS_IF([test "$install_doc" != no], [
- AS_IF([test "$install_rdoc" != no], [
+ AS_CASE(["$install_rdoc"],
+ [yes], [
RDOCTARGET="rdoc"
- ], [
+ ],
+ [all], [
+ RDOCTARGET="rdoc html"
+ ],
+ [no|''], [
RDOCTARGET="nodoc"
+ ],
+ [
+ RDOCTARGET="$install_rdoc"
])
AS_IF([test "$install_capi" != no -a -n "$DOXYGEN"], [
CAPITARGET="capi"
@@ -4080,6 +3579,17 @@ AC_SUBST(CAPITARGET)
AS_CASE(["$RDOCTARGET:$CAPITARGET"],[nodoc:nodoc],[INSTALLDOC=nodoc],[INSTALLDOC=all])
AC_SUBST(INSTALLDOC)
+AC_ARG_ENABLE(jit-support,
+ AS_HELP_STRING([--disable-jit-support], [disable JIT features]),
+ [MJIT_SUPPORT=$enableval
+ AS_IF([test x"$enable_jit_support" = "xyes"],
+ [AC_DEFINE(USE_MJIT, 1)],
+ [AC_DEFINE(USE_MJIT, 0)])],
+ [MJIT_SUPPORT=yes
+ AC_DEFINE(USE_MJIT, 1)])
+
+AC_SUBST(MJIT_SUPPORT)
+
AC_ARG_ENABLE(install-static-library,
AS_HELP_STRING([--disable-install-static-library], [do not install static ruby library]),
[INSTALL_STATIC_LIBRARY=$enableval],
@@ -4092,7 +3602,7 @@ AS_IF([test "$rb_with_pthread" = "yes"], [
THREAD_MODEL=pthread
])
AC_CACHE_CHECK([for prefix of external symbols], rb_cv_symbol_prefix, [
- AC_TRY_COMPILE([extern void conftest_external(void) {}], [], [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[extern void conftest_external(void) {}]], [[]])],[
rb_cv_symbol_prefix=`$NM conftest.$ac_objext |
sed -n ['/.*T[ ]\([^ ]*\)conftest_external.*/!d;s//\1/p;q']`
],
@@ -4103,7 +3613,7 @@ SYMBOL_PREFIX="$rb_cv_symbol_prefix"
test "x$SYMBOL_PREFIX" = xNONE && SYMBOL_PREFIX=''
DLNOBJ=dln.o
AC_ARG_ENABLE(dln,
- AC_HELP_STRING([--disable-dln], [disable dynamic link feature]),
+ AS_HELP_STRING([--disable-dln], [disable dynamic link feature]),
[test "$enableval" = yes || DLNOBJ=dmydln.o])
AC_SUBST(DLNOBJ)
MINIDLNOBJ=dmydln.o
@@ -4116,8 +3626,16 @@ AS_CASE(["$target_os"],
],
[darwin*], [
RUBY_APPEND_OPTION(CFLAGS, -pipe)
- RUBY_APPEND_OPTION(XLDFLAGS, [-framework CoreFoundation])
- RUBY_APPEND_OPTION(LIBRUBYARG_STATIC, [-framework CoreFoundation])
+ AC_COMPILE_IFELSE([
+ AC_LANG_BOOL_COMPILE_TRY([@%:@include <AvailabilityMacros.h>],
+ [MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7])],
+ [dnl
+ RUBY_APPEND_OPTION(XLDFLAGS, [-framework Security])
+ RUBY_APPEND_OPTION(LIBRUBYARG_STATIC, [-framework Security])
+ ]dnl
+ )
+ RUBY_APPEND_OPTION(XLDFLAGS, [-framework Foundation])
+ RUBY_APPEND_OPTION(LIBRUBYARG_STATIC, [-framework Foundation])
],
[osf*], [
AS_IF([test "$GCC" != "yes" ], [
@@ -4135,7 +3653,7 @@ AS_CASE(["$target_os"],
])
],
[cygwin*|mingw*], [
- LIBRUBY_DLDFLAGS="${DLDFLAGS}"' -Wl,--out-implib=$(LIBRUBY)'
+ LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' -Wl,--out-implib=$(LIBRUBY)'
AS_CASE(["$target_os"],
[cygwin*], [
AS_IF([test x"$enable_shared" = xyes], [
@@ -4160,7 +3678,6 @@ AS_CASE(["$target_os"],
])
LIBRUBY_ALIASES=''
FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
- SOLIBS='$(LIBS)'
AS_IF([test x"$enable_shared" = xyes], [
LIBRUBY='lib$(RUBY_SO_NAME).dll.a'
], [
@@ -4173,10 +3690,8 @@ AS_CASE(["$target_os"],
AS_CASE(["$YACC"],[*yacc*], [
XCFLAGS="$XCFLAGS -DYYMAXDEPTH=300"
YACC="$YACC -Nl40000 -Nm40000"
- ])],
- [nacl], [
- FIRSTMAKEFILE=GNUmakefile:nacl/GNUmakefile.in
])
+])
MINIOBJS="$MINIDLNOBJ"
@@ -4230,13 +3745,12 @@ AS_IF([test "${universal_binary-no}" = yes ], [
AC_CACHE_CHECK([for architecture macros], rb_cv_architecture_macros, [
mv confdefs.h confdefs1.h
: > confdefs.h
- AC_TRY_COMPILE([@%:@if defined __`echo ${universal_archnames} |
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@if defined __`echo ${universal_archnames} |
sed 's/=[^ ]*//g;s/ /__ || defined __/g'`__
@%:@else
@%:@error
>>>>>><<<<<<
-@%:@endif], [],
-[
+@%:@endif]], [[]])],[
rb_cv_architecture_macros=yes
mv -f confdefs1.h confdefs.h
], [
@@ -4249,19 +3763,29 @@ AS_IF([test "${universal_binary-no}" = yes ], [
CFLAGS="$new_cflags -arch $archs"
archs="__${archs}__"
AC_MSG_CHECKING([for macro ${archs} on ${cpu}])
- AC_TRY_COMPILE([@%:@ifndef ${archs}
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@ifndef ${archs}
@%:@error
-@%:@endif], [], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+@%:@endif]], [[]])],
+ [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
done
mv -f confdefs1.h confdefs.h
AC_MSG_ERROR([failed])
])])
AC_CACHE_CHECK(whether __ARCHITECTURE__ is available, rb_cv_architecture_available,
- AC_TRY_COMPILE([@%:@include <stdio.h>
- const char arch[[]] = __ARCHITECTURE__;], [puts(arch);],
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <stdio.h>
+ const char arch[[]] = __ARCHITECTURE__;]], [[puts(arch);]])],
[rb_cv_architecture_available=yes], [rb_cv_architecture_available=no]))
])
+: ${MJIT_LDSHARED=`echo "$LDSHARED" | sed ['s|\$(LD)|'"${LD}"'|g;s|\$(CC)|$(MJIT_CC)|g']`}
+
+MAINLIBS="$LIBS"
+LIBS=$ORIG_LIBS
+AS_IF([test -n "${LIBS}"], [
+ libspat=`echo "${LIBS}" | sed 's/[[][|.*$^]]/\\&/g;s/^ */ /;s/^ *$/ /'`
+ MAINFLAGS=`echo " $MAINLIBS " | sed "s|$libspat"'||;s/^ *//;s/ *$//'`
+])
+LIBRUBYARG_STATIC="${LIBRUBYARG_STATIC} \$(MAINLIBS)"
CPPFLAGS="$CPPFLAGS "'$(DEFS)'
test -z "$CPPFLAGS" || CPPFLAGS="$CPPFLAGS "; CPPFLAGS="$CPPFLAGS"'${cppflags}'
AS_IF([test -n "${cflags+set}"], [
@@ -4278,10 +3802,11 @@ AS_IF([test "${ARCH_FLAG}"], [
CXXFLAGS=`echo "$CXXFLAGS" | sed "s| *$archflagpat"'||'`
LDFLAGS=`echo "$LDFLAGS" | sed "s| *$archflagpat"'||'`
])
+rb_cv_warnflags=`echo "$rb_cv_warnflags" | sed 's/^ *//;s/ *$//'`
warnflags="$rb_cv_warnflags"
AC_SUBST(cppflags)dnl
AC_SUBST(cflags, ["${orig_cflags:+$orig_cflags }"'${optflags} ${debugflags} ${warnflags}'])dnl
-AC_SUBST(cxxflags, ["${orig_cxxflags:+$orig_cxxflags }"'${optflags} ${debugflags} ${warnflags}'])dnl
+AC_SUBST(cxxflags)dnl
AC_SUBST(optflags)dnl
AC_SUBST(debugflags)dnl
AC_SUBST(warnflags)dnl
@@ -4298,6 +3823,7 @@ AC_SUBST(RUBYW_INSTALL_NAME)
AC_SUBST(RUBY_SO_NAME)
AC_SUBST(LIBRUBY_A)
AC_SUBST(LIBRUBY_SO)
+AC_SUBST(LIBRUBY_SONAME)
AC_SUBST(LIBRUBY_ALIASES)
AC_SUBST(LIBRUBY)
AC_SUBST(LIBRUBYARG)
@@ -4305,6 +3831,7 @@ AC_SUBST(LIBRUBYARG_STATIC)
AC_SUBST(LIBRUBYARG_SHARED)
AC_SUBST(SOLIBS)
AC_SUBST(DLDLIBS)
+AC_SUBST(DLDSHARED)
AC_SUBST(ENABLE_SHARED)
AC_SUBST(MAINLIBS)
AC_SUBST(COMMON_LIBS)
@@ -4448,7 +3975,7 @@ AS_IF([test "${universal_binary-no}" = yes ], [
for archs in ${universal_archnames}; do
cpu=`echo $archs | sed 's/.*=//'`
archs=`echo $archs | sed 's/=.*//'`
- RUBY_DEFINE_IF([defined __${archs}__], RUBY_PLATFORM_CPU, ["${cpu}"])
+ RUBY_DEFINE_IF([defined __${archs}__ &&! defined RUBY_PLATFORM_CPU], RUBY_PLATFORM_CPU, ["${cpu}"])
done
])
ints='long int short'
@@ -4456,11 +3983,10 @@ AS_IF([test "${universal_binary-no}" = yes ], [
AC_SUBST(UNIVERSAL_ARCHNAMES, "${universal_archnames}")
AC_SUBST(UNIVERSAL_INTS, "${ints}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM_OS, "${target_os}")
- AC_DEFINE_UNQUOTED(RUBY_ARCH, "universal-"RUBY_PLATFORM_OS)
- AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "universal."RUBY_PLATFORM_CPU"-"RUBY_PLATFORM_OS)
+ AC_DEFINE_UNQUOTED(RUBY_ARCH, "universal-" RUBY_PLATFORM_OS)
+ AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "universal." RUBY_PLATFORM_CPU "-" RUBY_PLATFORM_OS)
], [
arch="${target_cpu}-${target_os}"
- AS_CASE(["$arch"], [le32-nacl], [arch="pnacl"])
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "$arch")
])
@@ -4546,10 +4072,9 @@ AC_ARG_ENABLE(rubygems,
AS_HELP_STRING([--disable-rubygems], [disable rubygems by default]),
[enable_rubygems="$enableval"], [enable_rubygems=yes])
AS_IF([test x"$enable_rubygems" = xno], [
- AC_DEFINE(DISABLE_RUBYGEMS, 1)
- USE_RUBYGEMS=NO
+ USE_RUBYGEMS=no
], [
- USE_RUBYGEMS=YES
+ USE_RUBYGEMS=yes
])
AC_SUBST(USE_RUBYGEMS)
@@ -4565,8 +4090,8 @@ guard=INCLUDE_RUBY_CONFIG_H
} | tr -d '\015' |
(
AS_IF([test "x$CONFIGURE_TTY" = xyes], [color=--color], [color=])
- exec ${srcdir}/tool/ifchange $color "${config_h}" -
-) || AC_MSG_ERROR([failed to create ${config_h}])
+ exec ${tooldir}/ifchange $color "${config_h}" -
+) >&AS_MESSAGE_FD || AC_MSG_ERROR([failed to create ${config_h}])
tr -d '\015' < largefile.h > confdefs.h
rm largefile.h
@@ -4593,31 +4118,32 @@ PACKAGE=$RUBY_BASE_NAME
AC_SUBST(PACKAGE)
AS_MESSAGE([$PACKAGE library version = $ruby_version])
+AS_IF([test x"$CC_WRAPPER" != x], [
+ CC='$(CC_WRAPPER) '"${CC@%:@$CC_WRAPPER }"
+ CPP='$(CC_WRAPPER) '"${CPP@%:@$CC_WRAPPER }"
+ CC_WRAPPER='$(rubyarchdir)/darwin-cc'
+ XCC_WRAPPER='$(top_srcdir)/tool/darwin-cc'
+])
+AC_SUBST(CC_WRAPPER, '')
+AC_SUBST(XCC_WRAPPER)
+
AS_CASE([" $CPP "], [*" $CC "*], [CPP=`echo " $CPP " | sed "s| $CC |"' $(CC) |;s/^ *//;s/ *$//'`])
AS_IF([test x"$firstmf" != x], [
AC_CONFIG_FILES($firstmf:$firsttmpl, [], [firstmf="$firstmf" firsttmpl="$firsttmpl"])
])
-AC_CONFIG_FILES(Makefile, [
+AC_CONFIG_FILES(Makefile:template/Makefile.in, [
tmpmk=confmk$$.tmp
{
AS_IF([test ${VCS+set}], [
:
- ], [svn info "$srcdir" > /dev/null 2>&1], [
- VCS='svn'
], [git_dir=`$GIT --work-tree="$srcdir" --git-dir="$srcdir/.git" rev-parse --git-dir 2>/dev/null`], [
- AS_IF([test -d "$git_dir/svn"], [
- VCS='$(GIT) svn'
- ], [
- VCS='$(GIT)'
- ])
+ VCS='$(GIT)'
], [
VCS='echo cannot'
])
AS_CASE("$VCS",
- [svn], [VCSUP='$(VCS) up $(SVNUPOPTIONS)'],
- ['$(GIT) svn'], [VCSUP='$(VCS) rebase $(GITSVNREBASEOPTIONS)'],
- ['$(GIT)'|git], [VCSUP='$(VCS) pull $(GITPULLOPTIONS)'],
+ ['$(GIT)'|git], [VCSUP='$(VCS) pull --rebase $(GITPULLOPTIONS)'],
[VCSUP='$(VCS)'])
sed -n \
-e '[/^@%:@define \(RUBY_RELEASE_[A-Z]*\) \([0-9][0-9]*\)/]{' \
@@ -4647,10 +4173,10 @@ AC_CONFIG_FILES(Makefile, [
echo 'ruby: $(PROGRAM);' >> $tmpmk
test "$tmpmk" = "$tmpgmk" || rm -f "$tmpgmk"
]) && mv -f $tmpmk Makefile],
-[EXEEXT='$EXEEXT' gnumake='$gnumake' GIT='$GIT'])
+[EXEEXT='$EXEEXT' MAKE='${MAKE-make}' gnumake='$gnumake' GIT='$GIT'])
AC_ARG_WITH([ruby-pc],
- AC_HELP_STRING([--with-ruby-pc=FILENAME], [pc file basename]),
+ AS_HELP_STRING([--with-ruby-pc=FILENAME], [pc file basename]),
[ruby_pc="$withval"],
[ruby_pc="${RUBY_BASE_NAME}-${MAJOR}.${MINOR}.pc"])
AC_SUBST(ruby_pc)
@@ -4680,22 +4206,27 @@ AC_OUTPUT
}
}
+AS_IF([test "$silent" = yes], [], [
AS_IF([${FOLD+:} false], [], [
AS_IF([test "`echo abcdefg hijklmno | fold -s -w10 | sed 1d`" = hijklmno], [FOLD="fold"], [FOLD=])
])
+fold_width=`expr $COLUMNS - 30 2>/dev/null` || fold_width=50
AS_REQUIRE_SHELL_FN([config_summary],
[AS_FUNCTION_DESCRIBE([config_summary], [NAME, VAL], [configuration summary])],
[AS_IF([test -z "$2"], [], [
AS_ECHO_N([" * $1: "]) | dd bs=1 count=26 2>/dev/null
AS_IF([test "$FOLD"], [
- echo "$2" | fold -s -w50 |
+ echo "$2" | fold -s -w$fold_width |
sed '1!s/^/ /;$!s/$/\\/'
], [echo "$2"])
])]
)
+AS_IF([test $install_doc = yes],
+ [DOCTARGETS=`echo " $RDOCTARGET $CAPITARGET " | sed 's/ nodoc //g;s/^ *//;s/ *$//'`],
+ [DOCTARGETS=no])
echo "---"
-echo "Configuration summary for $RUBY_BASE_NAME version $RUBY_PROGRAM_VERSION"
+echo "Configuration summary for $RUBY_BASE_NAME version $MAJOR.$MINOR.$TEENY"
echo ""
config_summary "Installation prefix" "$prefix"
config_summary "exec prefix" "$exec_prefix"
@@ -4709,18 +4240,23 @@ config_summary "vendor path" "$vendordir"
config_summary "target OS" "$target_os"
config_summary "compiler" "$CC"
config_summary "with pthread" "$enable_pthread"
+config_summary "with coroutine" "$rb_cv_coroutine"
config_summary "enable shared libs" "$ENABLE_SHARED"
config_summary "dynamic library ext" "$DLEXT"
config_summary "CFLAGS" "$cflags"
config_summary "CPPFLAGS" "$cppflags"
config_summary "LDFLAGS" "$LDFLAGS"
+config_summary "DLDFLAGS" "$DLDFLAGS"
config_summary "optflags" "$optflags"
config_summary "debugflags" "$debugflags"
config_summary "warnflags" "$warnflags"
config_summary "strip command" "$STRIP"
-config_summary "install doc" "$install_doc"
+config_summary "install doc" "$DOCTARGETS"
+config_summary "JIT support" "$MJIT_SUPPORT"
config_summary "man page type" "$MANTYPE"
config_summary "search path" "$search_path"
config_summary "static-linked-ext" ${EXTSTATIC:+"yes"}
+config_summary "BASERUBY -v" "$BASERUBY_VERSION"
echo ""
echo "---"
+])
diff --git a/constant.h b/constant.h
index 76b59fa047..e0d36909e1 100644
--- a/constant.h
+++ b/constant.h
@@ -1,3 +1,5 @@
+#ifndef CONSTANT_H
+#define CONSTANT_H
/**********************************************************************
constant.h -
@@ -8,8 +10,8 @@
Copyright (C) 2009 Yusuke Endoh
**********************************************************************/
-#ifndef CONSTANT_H
-#define CONSTANT_H
+#include "ruby/ruby.h"
+#include "id_table.h"
typedef enum {
CONST_DEPRECATED = 0x100,
@@ -31,20 +33,23 @@ typedef enum {
typedef struct rb_const_entry_struct {
rb_const_flag_t flag;
int line;
- const VALUE value; /* should be mark */
- const VALUE file; /* should be mark */
+ VALUE value; /* should be mark */
+ VALUE file; /* should be mark */
} rb_const_entry_t;
VALUE rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj);
VALUE rb_mod_public_constant(int argc, const VALUE *argv, VALUE obj);
VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj);
void rb_free_const_table(struct rb_id_table *tbl);
-VALUE rb_public_const_get(VALUE klass, ID id);
+VALUE rb_const_source_location(VALUE, ID);
+
+MJIT_SYMBOL_EXPORT_BEGIN
+int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag);
+rb_const_entry_t *rb_const_lookup(VALUE klass, ID id);
VALUE rb_public_const_get_at(VALUE klass, ID id);
VALUE rb_public_const_get_from(VALUE klass, ID id);
-int rb_public_const_defined(VALUE klass, ID id);
-int rb_public_const_defined_at(VALUE klass, ID id);
int rb_public_const_defined_from(VALUE klass, ID id);
-rb_const_entry_t *rb_const_lookup(VALUE klass, ID id);
+VALUE rb_const_source_location_at(VALUE, ID);
+MJIT_SYMBOL_EXPORT_END
#endif /* CONSTANT_H */
diff --git a/cont.c b/cont.c
index df4ac789bd..a7103a087e 100644
--- a/cont.c
+++ b/cont.c
@@ -9,108 +9,200 @@
**********************************************************************/
-#include "internal.h"
-#include "vm_core.h"
-#include "gc.h"
-#include "eval_intern.h"
-
-/* FIBER_USE_NATIVE enables Fiber performance improvement using system
- * dependent method such as make/setcontext on POSIX system or
- * CreateFiber() API on Windows.
- * This hack make Fiber context switch faster (x2 or more).
- * However, it decrease maximum number of Fiber. For example, on the
- * 32bit POSIX OS, ten or twenty thousands Fiber can be created.
- *
- * Details is reported in the paper "A Fast Fiber Implementation for Ruby 1.9"
- * in Proc. of 51th Programming Symposium, pp.21--28 (2010) (in Japanese).
- */
-
-#if !defined(FIBER_USE_NATIVE)
-# if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
-# if 0
-# elif defined(__NetBSD__)
-/* On our experience, NetBSD doesn't support using setcontext() and pthread
- * simultaneously. This is because pthread_self(), TLS and other information
- * are represented by stack pointer (higher bits of stack pointer).
- * TODO: check such constraint on configure.
- */
-# define FIBER_USE_NATIVE 0
-# elif defined(__sun)
-/* On Solaris because resuming any Fiber caused SEGV, for some reason.
- */
-# define FIBER_USE_NATIVE 0
-# elif defined(__ia64)
-/* At least, Linux/ia64's getcontext(3) doesn't save register window.
- */
-# define FIBER_USE_NATIVE 0
-# elif defined(__GNU__)
-/* GNU/Hurd doesn't fully support getcontext, setcontext, makecontext
- * and swapcontext functions. Disabling their usage till support is
- * implemented. More info at
- * http://darnassus.sceen.net/~hurd-web/open_issues/glibc/#getcontext
- */
-# define FIBER_USE_NATIVE 0
-# else
-# define FIBER_USE_NATIVE 1
-# endif
-# elif defined(_WIN32)
-# define FIBER_USE_NATIVE 1
-# endif
-#endif
-#if !defined(FIBER_USE_NATIVE)
-#define FIBER_USE_NATIVE 0
-#endif
+#include "ruby/internal/config.h"
-#if FIBER_USE_NATIVE
#ifndef _WIN32
#include <unistd.h>
#include <sys/mman.h>
-#include <ucontext.h>
#endif
+
+#include COROUTINE_H
+
+#include "eval_intern.h"
+#include "gc.h"
+#include "internal.h"
+#include "internal/cont.h"
+#include "internal/proc.h"
+#include "internal/warnings.h"
+#include "internal/scheduler.h"
+#include "mjit.h"
+#include "vm_core.h"
+#include "id_table.h"
+#include "ractor_core.h"
+
+static const int DEBUG = 0;
+
#define RB_PAGE_SIZE (pagesize)
#define RB_PAGE_MASK (~(RB_PAGE_SIZE - 1))
static long pagesize;
-#endif /*FIBER_USE_NATIVE*/
+
+static const rb_data_type_t cont_data_type, fiber_data_type;
+static VALUE rb_cContinuation;
+static VALUE rb_cFiber;
+static VALUE rb_eFiberError;
+#ifdef RB_EXPERIMENTAL_FIBER_POOL
+static VALUE rb_cFiberPool;
+#endif
#define CAPTURE_JUST_VALID_VM_STACK 1
+// Defined in `coroutine/$arch/Context.h`:
+#ifdef COROUTINE_LIMITED_ADDRESS_SPACE
+#define FIBER_POOL_ALLOCATION_FREE
+#define FIBER_POOL_INITIAL_SIZE 8
+#define FIBER_POOL_ALLOCATION_MAXIMUM_SIZE 32
+#else
+#define FIBER_POOL_INITIAL_SIZE 32
+#define FIBER_POOL_ALLOCATION_MAXIMUM_SIZE 1024
+#endif
+
enum context_type {
CONTINUATION_CONTEXT = 0,
- FIBER_CONTEXT = 1,
- ROOT_FIBER_CONTEXT = 2
+ FIBER_CONTEXT = 1
};
struct cont_saved_vm_stack {
VALUE *ptr;
#ifdef CAPTURE_JUST_VALID_VM_STACK
- size_t slen; /* length of stack (head of th->ec.vm_stack) */
- size_t clen; /* length of control frames (tail of th->ec.vm_stack) */
+ size_t slen; /* length of stack (head of ec->vm_stack) */
+ size_t clen; /* length of control frames (tail of ec->vm_stack) */
+#endif
+};
+
+struct fiber_pool;
+
+// Represents a single stack.
+struct fiber_pool_stack {
+ // A pointer to the memory allocation (lowest address) for the stack.
+ void * base;
+
+ // The current stack pointer, taking into account the direction of the stack.
+ void * current;
+
+ // The size of the stack excluding any guard pages.
+ size_t size;
+
+ // The available stack capacity w.r.t. the current stack offset.
+ size_t available;
+
+ // The pool this stack should be allocated from.
+ struct fiber_pool * pool;
+
+ // If the stack is allocated, the allocation it came from.
+ struct fiber_pool_allocation * allocation;
+};
+
+// A linked list of vacant (unused) stacks.
+// This structure is stored in the first page of a stack if it is not in use.
+// @sa fiber_pool_vacancy_pointer
+struct fiber_pool_vacancy {
+ // Details about the vacant stack:
+ struct fiber_pool_stack stack;
+
+ // The vacancy linked list.
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ struct fiber_pool_vacancy * previous;
+#endif
+ struct fiber_pool_vacancy * next;
+};
+
+// Manages singly linked list of mapped regions of memory which contains 1 more more stack:
+//
+// base = +-------------------------------+-----------------------+ +
+// |VM Stack |VM Stack | | |
+// | | | | |
+// | | | | |
+// +-------------------------------+ | |
+// |Machine Stack |Machine Stack | | |
+// | | | | |
+// | | | | |
+// | | | . . . . | | size
+// | | | | |
+// | | | | |
+// | | | | |
+// | | | | |
+// | | | | |
+// +-------------------------------+ | |
+// |Guard Page |Guard Page | | |
+// +-------------------------------+-----------------------+ v
+//
+// +------------------------------------------------------->
+//
+// count
+//
+struct fiber_pool_allocation {
+ // A pointer to the memory mapped region.
+ void * base;
+
+ // The size of the individual stacks.
+ size_t size;
+
+ // The stride of individual stacks (including any guard pages or other accounting details).
+ size_t stride;
+
+ // The number of stacks that were allocated.
+ size_t count;
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ // The number of stacks used in this allocation.
+ size_t used;
+#endif
+
+ struct fiber_pool * pool;
+
+ // The allocation linked list.
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ struct fiber_pool_allocation * previous;
#endif
+ struct fiber_pool_allocation * next;
+};
+
+// A fiber pool manages vacant stacks to reduce the overhead of creating fibers.
+struct fiber_pool {
+ // A singly-linked list of allocations which contain 1 or more stacks each.
+ struct fiber_pool_allocation * allocations;
+
+ // Provides O(1) stack "allocation":
+ struct fiber_pool_vacancy * vacancies;
+
+ // The size of the stack allocations (excluding any guard page).
+ size_t size;
+
+ // The total number of stacks that have been allocated in this pool.
+ size_t count;
+
+ // The initial number of stacks to allocate.
+ size_t initial_count;
+
+ // Whether to madvise(free) the stack or not:
+ int free_stacks;
+
+ // The number of stacks that have been used in this pool.
+ size_t used;
+
+ // The amount to allocate for the vm_stack:
+ size_t vm_stack_size;
};
typedef struct rb_context_struct {
enum context_type type;
int argc;
+ int kw_splat;
VALUE self;
VALUE value;
struct cont_saved_vm_stack saved_vm_stack;
struct {
- VALUE *stack;
- VALUE *stack_src;
- size_t stack_size;
-#ifdef __ia64
- VALUE *register_stack;
- VALUE *register_stack_src;
- int register_stack_size;
-#endif
+ VALUE *stack;
+ VALUE *stack_src;
+ size_t stack_size;
} machine;
rb_execution_context_t saved_ec;
rb_jmpbuf_t jmpbuf;
rb_ensure_entry_t *ensure_array;
- rb_ensure_list_t *ensure_list;
- VALUE thread_value;
+ /* Pointer to MJIT info about the continuation. */
+ struct mjit_cont *mjit_cont;
} rb_context_t;
@@ -133,48 +225,536 @@ enum fiber_status {
FIBER_TERMINATED
};
-#define FIBER_CREATED_P(fib) ((fib)->status == FIBER_CREATED)
-#define FIBER_RESUMED_P(fib) ((fib)->status == FIBER_RESUMED)
-#define FIBER_SUSPENDED_P(fib) ((fib)->status == FIBER_SUSPENDED)
-#define FIBER_TERMINATED_P(fib) ((fib)->status == FIBER_TERMINATED)
-#define FIBER_RUNNABLE_P(fib) (FIBER_CREATED_P(fib) || FIBER_SUSPENDED_P(fib))
-
-#if FIBER_USE_NATIVE && !defined(_WIN32)
-#define MAX_MACHINE_STACK_CACHE 10
-static int machine_stack_cache_index = 0;
-typedef struct machine_stack_cache_struct {
- void *ptr;
- size_t size;
-} machine_stack_cache_t;
-static machine_stack_cache_t machine_stack_cache[MAX_MACHINE_STACK_CACHE];
-static machine_stack_cache_t terminated_machine_stack;
-#endif
+#define FIBER_CREATED_P(fiber) ((fiber)->status == FIBER_CREATED)
+#define FIBER_RESUMED_P(fiber) ((fiber)->status == FIBER_RESUMED)
+#define FIBER_SUSPENDED_P(fiber) ((fiber)->status == FIBER_SUSPENDED)
+#define FIBER_TERMINATED_P(fiber) ((fiber)->status == FIBER_TERMINATED)
+#define FIBER_RUNNABLE_P(fiber) (FIBER_CREATED_P(fiber) || FIBER_SUSPENDED_P(fiber))
struct rb_fiber_struct {
rb_context_t cont;
VALUE first_proc;
struct rb_fiber_struct *prev;
- const enum fiber_status status;
- /* If a fiber invokes "transfer",
- * then this fiber can't "resume" any more after that.
- * You shouldn't mix "transfer" and "resume".
- */
- int transferred;
+ VALUE resuming_fiber;
+
+ BITFIELD(enum fiber_status, status, 2);
+ /* Whether the fiber is allowed to implicitly yield. */
+ unsigned int yielding : 1;
+ unsigned int blocking : 1;
+
+ struct coroutine_context context;
+ struct fiber_pool_stack stack;
+};
+
+static struct fiber_pool shared_fiber_pool = {NULL, NULL, 0, 0, 0, 0};
+
+static ID fiber_initialize_keywords[2] = {0};
+
+/*
+ * FreeBSD require a first (i.e. addr) argument of mmap(2) is not NULL
+ * if MAP_STACK is passed.
+ * http://www.FreeBSD.org/cgi/query-pr.cgi?pr=158755
+ */
+#if defined(MAP_STACK) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
+#define FIBER_STACK_FLAGS (MAP_PRIVATE | MAP_ANON | MAP_STACK)
+#else
+#define FIBER_STACK_FLAGS (MAP_PRIVATE | MAP_ANON)
+#endif
+
+#define ERRNOMSG strerror(errno)
+
+// Locates the stack vacancy details for the given stack.
+// Requires that fiber_pool_vacancy fits within one page.
+inline static struct fiber_pool_vacancy *
+fiber_pool_vacancy_pointer(void * base, size_t size)
+{
+ STACK_GROW_DIR_DETECTION;
+
+ return (struct fiber_pool_vacancy *)(
+ (char*)base + STACK_DIR_UPPER(0, size - RB_PAGE_SIZE)
+ );
+}
+
+// Reset the current stack pointer and available size of the given stack.
+inline static void
+fiber_pool_stack_reset(struct fiber_pool_stack * stack)
+{
+ STACK_GROW_DIR_DETECTION;
+
+ stack->current = (char*)stack->base + STACK_DIR_UPPER(0, stack->size);
+ stack->available = stack->size;
+}
+
+// A pointer to the base of the current unused portion of the stack.
+inline static void *
+fiber_pool_stack_base(struct fiber_pool_stack * stack)
+{
+ STACK_GROW_DIR_DETECTION;
+
+ VM_ASSERT(stack->current);
+
+ return STACK_DIR_UPPER(stack->current, (char*)stack->current - stack->available);
+}
+
+// Allocate some memory from the stack. Used to allocate vm_stack inline with machine stack.
+// @sa fiber_initialize_coroutine
+inline static void *
+fiber_pool_stack_alloca(struct fiber_pool_stack * stack, size_t offset)
+{
+ STACK_GROW_DIR_DETECTION;
+
+ if (DEBUG) fprintf(stderr, "fiber_pool_stack_alloca(%p): %"PRIuSIZE"/%"PRIuSIZE"\n", (void*)stack, offset, stack->available);
+ VM_ASSERT(stack->available >= offset);
+
+ // The pointer to the memory being allocated:
+ void * pointer = STACK_DIR_UPPER(stack->current, (char*)stack->current - offset);
+
+ // Move the stack pointer:
+ stack->current = STACK_DIR_UPPER((char*)stack->current + offset, (char*)stack->current - offset);
+ stack->available -= offset;
+
+ return pointer;
+}
+
+// Reset the current stack pointer and available size of the given stack.
+inline static void
+fiber_pool_vacancy_reset(struct fiber_pool_vacancy * vacancy)
+{
+ fiber_pool_stack_reset(&vacancy->stack);
+
+ // Consume one page of the stack because it's used for the vacancy list:
+ fiber_pool_stack_alloca(&vacancy->stack, RB_PAGE_SIZE);
+}
+
+inline static struct fiber_pool_vacancy *
+fiber_pool_vacancy_push(struct fiber_pool_vacancy * vacancy, struct fiber_pool_vacancy * head)
+{
+ vacancy->next = head;
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ if (head) {
+ head->previous = vacancy;
+ vacancy->previous = NULL;
+ }
+#endif
+
+ return vacancy;
+}
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+static void
+fiber_pool_vacancy_remove(struct fiber_pool_vacancy * vacancy)
+{
+ if (vacancy->next) {
+ vacancy->next->previous = vacancy->previous;
+ }
+
+ if (vacancy->previous) {
+ vacancy->previous->next = vacancy->next;
+ }
+ else {
+ // It's the head of the list:
+ vacancy->stack.pool->vacancies = vacancy->next;
+ }
+}
+
+inline static struct fiber_pool_vacancy *
+fiber_pool_vacancy_pop(struct fiber_pool * pool)
+{
+ struct fiber_pool_vacancy * vacancy = pool->vacancies;
+
+ if (vacancy) {
+ fiber_pool_vacancy_remove(vacancy);
+ }
+
+ return vacancy;
+}
+#else
+inline static struct fiber_pool_vacancy *
+fiber_pool_vacancy_pop(struct fiber_pool * pool)
+{
+ struct fiber_pool_vacancy * vacancy = pool->vacancies;
+
+ if (vacancy) {
+ pool->vacancies = vacancy->next;
+ }
+
+ return vacancy;
+}
+#endif
+
+// Initialize the vacant stack. The [base, size] allocation should not include the guard page.
+// @param base The pointer to the lowest address of the allocated memory.
+// @param size The size of the allocated memory.
+inline static struct fiber_pool_vacancy *
+fiber_pool_vacancy_initialize(struct fiber_pool * fiber_pool, struct fiber_pool_vacancy * vacancies, void * base, size_t size)
+{
+ struct fiber_pool_vacancy * vacancy = fiber_pool_vacancy_pointer(base, size);
+
+ vacancy->stack.base = base;
+ vacancy->stack.size = size;
+
+ fiber_pool_vacancy_reset(vacancy);
+
+ vacancy->stack.pool = fiber_pool;
+
+ return fiber_pool_vacancy_push(vacancy, vacancies);
+}
+
+// Allocate a maximum of count stacks, size given by stride.
+// @param count the number of stacks to allocate / were allocated.
+// @param stride the size of the individual stacks.
+// @return [void *] the allocated memory or NULL if allocation failed.
+inline static void *
+fiber_pool_allocate_memory(size_t * count, size_t stride)
+{
+ // We use a divide-by-2 strategy to try and allocate memory. We are trying
+ // to allocate `count` stacks. In normal situation, this won't fail. But
+ // if we ran out of address space, or we are allocating more memory than
+ // the system would allow (e.g. overcommit * physical memory + swap), we
+ // divide count by two and try again. This condition should only be
+ // encountered in edge cases, but we handle it here gracefully.
+ while (*count > 1) {
+#if defined(_WIN32)
+ void * base = VirtualAlloc(0, (*count)*stride, MEM_COMMIT, PAGE_READWRITE);
+
+ if (!base) {
+ *count = (*count) >> 1;
+ }
+ else {
+ return base;
+ }
+#else
+ errno = 0;
+ void * base = mmap(NULL, (*count)*stride, PROT_READ | PROT_WRITE, FIBER_STACK_FLAGS, -1, 0);
+
+ if (base == MAP_FAILED) {
+ // If the allocation fails, count = count / 2, and try again.
+ *count = (*count) >> 1;
+ }
+ else {
+ return base;
+ }
+#endif
+ }
+
+ return NULL;
+}
+
+// Given an existing fiber pool, expand it by the specified number of stacks.
+// @param count the maximum number of stacks to allocate.
+// @return the allocated fiber pool.
+// @sa fiber_pool_allocation_free
+static struct fiber_pool_allocation *
+fiber_pool_expand(struct fiber_pool * fiber_pool, size_t count)
+{
+ STACK_GROW_DIR_DETECTION;
+
+ size_t size = fiber_pool->size;
+ size_t stride = size + RB_PAGE_SIZE;
+
+ // Allocate the memory required for the stacks:
+ void * base = fiber_pool_allocate_memory(&count, stride);
+
+ if (base == NULL) {
+ rb_raise(rb_eFiberError, "can't alloc machine stack to fiber (%"PRIuSIZE" x %"PRIuSIZE" bytes): %s", count, size, ERRNOMSG);
+ }
+
+ struct fiber_pool_vacancy * vacancies = fiber_pool->vacancies;
+ struct fiber_pool_allocation * allocation = RB_ALLOC(struct fiber_pool_allocation);
+
+ // Initialize fiber pool allocation:
+ allocation->base = base;
+ allocation->size = size;
+ allocation->stride = stride;
+ allocation->count = count;
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ allocation->used = 0;
+#endif
+ allocation->pool = fiber_pool;
+
+ if (DEBUG) {
+ fprintf(stderr, "fiber_pool_expand(%"PRIuSIZE"): %p, %"PRIuSIZE"/%"PRIuSIZE" x [%"PRIuSIZE":%"PRIuSIZE"]\n",
+ count, (void*)fiber_pool, fiber_pool->used, fiber_pool->count, size, fiber_pool->vm_stack_size);
+ }
+
+ // Iterate over all stacks, initializing the vacancy list:
+ for (size_t i = 0; i < count; i += 1) {
+ void * base = (char*)allocation->base + (stride * i);
+ void * page = (char*)base + STACK_DIR_UPPER(size, 0);
+
+#if defined(_WIN32)
+ DWORD old_protect;
+
+ if (!VirtualProtect(page, RB_PAGE_SIZE, PAGE_READWRITE | PAGE_GUARD, &old_protect)) {
+ VirtualFree(allocation->base, 0, MEM_RELEASE);
+ rb_raise(rb_eFiberError, "can't set a guard page: %s", ERRNOMSG);
+ }
+#else
+ if (mprotect(page, RB_PAGE_SIZE, PROT_NONE) < 0) {
+ munmap(allocation->base, count*stride);
+ rb_raise(rb_eFiberError, "can't set a guard page: %s", ERRNOMSG);
+ }
+#endif
+
+ vacancies = fiber_pool_vacancy_initialize(
+ fiber_pool, vacancies,
+ (char*)base + STACK_DIR_UPPER(0, RB_PAGE_SIZE),
+ size
+ );
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ vacancies->stack.allocation = allocation;
+#endif
+ }
+
+ // Insert the allocation into the head of the pool:
+ allocation->next = fiber_pool->allocations;
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ if (allocation->next) {
+ allocation->next->previous = allocation;
+ }
+
+ allocation->previous = NULL;
+#endif
+
+ fiber_pool->allocations = allocation;
+ fiber_pool->vacancies = vacancies;
+ fiber_pool->count += count;
+
+ return allocation;
+}
+
+// Initialize the specified fiber pool with the given number of stacks.
+// @param vm_stack_size The size of the vm stack to allocate.
+static void
+fiber_pool_initialize(struct fiber_pool * fiber_pool, size_t size, size_t count, size_t vm_stack_size)
+{
+ VM_ASSERT(vm_stack_size < size);
+
+ fiber_pool->allocations = NULL;
+ fiber_pool->vacancies = NULL;
+ fiber_pool->size = ((size / RB_PAGE_SIZE) + 1) * RB_PAGE_SIZE;
+ fiber_pool->count = 0;
+ fiber_pool->initial_count = count;
+ fiber_pool->free_stacks = 1;
+ fiber_pool->used = 0;
+
+ fiber_pool->vm_stack_size = vm_stack_size;
+
+ fiber_pool_expand(fiber_pool, count);
+}
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+// Free the list of fiber pool allocations.
+static void
+fiber_pool_allocation_free(struct fiber_pool_allocation * allocation)
+{
+ STACK_GROW_DIR_DETECTION;
+
+ VM_ASSERT(allocation->used == 0);
+
+ if (DEBUG) fprintf(stderr, "fiber_pool_allocation_free: %p base=%p count=%"PRIuSIZE"\n", allocation, allocation->base, allocation->count);
+
+ size_t i;
+ for (i = 0; i < allocation->count; i += 1) {
+ void * base = (char*)allocation->base + (allocation->stride * i) + STACK_DIR_UPPER(0, RB_PAGE_SIZE);
+
+ struct fiber_pool_vacancy * vacancy = fiber_pool_vacancy_pointer(base, allocation->size);
+
+ // Pop the vacant stack off the free list:
+ fiber_pool_vacancy_remove(vacancy);
+ }
-#if FIBER_USE_NATIVE
#ifdef _WIN32
- void *fib_handle;
+ VirtualFree(allocation->base, 0, MEM_RELEASE);
#else
- ucontext_t context;
- /* Because context.uc_stack.ss_sp and context.uc_stack.ss_size
- * are not necessarily valid after makecontext() or swapcontext(),
- * they are saved in these variables for later use.
- */
- void *ss_sp;
- size_t ss_size;
+ munmap(allocation->base, allocation->stride * allocation->count);
#endif
+
+ if (allocation->previous) {
+ allocation->previous->next = allocation->next;
+ }
+ else {
+ // We are the head of the list, so update the pool:
+ allocation->pool->allocations = allocation->next;
+ }
+
+ if (allocation->next) {
+ allocation->next->previous = allocation->previous;
+ }
+
+ allocation->pool->count -= allocation->count;
+
+ ruby_xfree(allocation);
+}
#endif
-};
+
+// Acquire a stack from the given fiber pool. If none are available, allocate more.
+static struct fiber_pool_stack
+fiber_pool_stack_acquire(struct fiber_pool * fiber_pool) {
+ struct fiber_pool_vacancy * vacancy = fiber_pool_vacancy_pop(fiber_pool);
+
+ if (DEBUG) fprintf(stderr, "fiber_pool_stack_acquire: %p used=%"PRIuSIZE"\n", (void*)fiber_pool->vacancies, fiber_pool->used);
+
+ if (!vacancy) {
+ const size_t maximum = FIBER_POOL_ALLOCATION_MAXIMUM_SIZE;
+ const size_t minimum = fiber_pool->initial_count;
+
+ size_t count = fiber_pool->count;
+ if (count > maximum) count = maximum;
+ if (count < minimum) count = minimum;
+
+ fiber_pool_expand(fiber_pool, count);
+
+ // The free list should now contain some stacks:
+ VM_ASSERT(fiber_pool->vacancies);
+
+ vacancy = fiber_pool_vacancy_pop(fiber_pool);
+ }
+
+ VM_ASSERT(vacancy);
+ VM_ASSERT(vacancy->stack.base);
+
+ // Take the top item from the free list:
+ fiber_pool->used += 1;
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ vacancy->stack.allocation->used += 1;
+#endif
+
+ fiber_pool_stack_reset(&vacancy->stack);
+
+ return vacancy->stack;
+}
+
+// We advise the operating system that the stack memory pages are no longer being used.
+// This introduce some performance overhead but allows system to relaim memory when there is pressure.
+static inline void
+fiber_pool_stack_free(struct fiber_pool_stack * stack)
+{
+ void * base = fiber_pool_stack_base(stack);
+ size_t size = stack->available;
+
+ // If this is not true, the vacancy information will almost certainly be destroyed:
+ VM_ASSERT(size <= (stack->size - RB_PAGE_SIZE));
+
+ if (DEBUG) fprintf(stderr, "fiber_pool_stack_free: %p+%"PRIuSIZE" [base=%p, size=%"PRIuSIZE"]\n", base, size, stack->base, stack->size);
+
+#if VM_CHECK_MODE > 0 && defined(MADV_DONTNEED)
+ // This immediately discards the pages and the memory is reset to zero.
+ madvise(base, size, MADV_DONTNEED);
+#elif defined(MADV_FREE_REUSABLE)
+ madvise(base, size, MADV_FREE_REUSABLE);
+#elif defined(MADV_FREE)
+ madvise(base, size, MADV_FREE);
+#elif defined(MADV_DONTNEED)
+ madvise(base, size, MADV_DONTNEED);
+#elif defined(_WIN32)
+ VirtualAlloc(base, size, MEM_RESET, PAGE_READWRITE);
+ // Not available in all versions of Windows.
+ //DiscardVirtualMemory(base, size);
+#endif
+}
+
+// Release and return a stack to the vacancy list.
+static void
+fiber_pool_stack_release(struct fiber_pool_stack * stack)
+{
+ struct fiber_pool * pool = stack->pool;
+ struct fiber_pool_vacancy * vacancy = fiber_pool_vacancy_pointer(stack->base, stack->size);
+
+ if (DEBUG) fprintf(stderr, "fiber_pool_stack_release: %p used=%"PRIuSIZE"\n", stack->base, stack->pool->used);
+
+ // Copy the stack details into the vacancy area:
+ vacancy->stack = *stack;
+ // After this point, be careful about updating/using state in stack, since it's copied to the vacancy area.
+
+ // Reset the stack pointers and reserve space for the vacancy data:
+ fiber_pool_vacancy_reset(vacancy);
+
+ // Push the vacancy into the vancancies list:
+ pool->vacancies = fiber_pool_vacancy_push(vacancy, stack->pool->vacancies);
+ pool->used -= 1;
+
+#ifdef FIBER_POOL_ALLOCATION_FREE
+ struct fiber_pool_allocation * allocation = stack->allocation;
+
+ allocation->used -= 1;
+
+ // Release address space and/or dirty memory:
+ if (allocation->used == 0) {
+ fiber_pool_allocation_free(allocation);
+ }
+ else if (stack->pool->free_stacks) {
+ fiber_pool_stack_free(&vacancy->stack);
+ }
+#else
+ // This is entirely optional, but clears the dirty flag from the stack memory, so it won't get swapped to disk when there is memory pressure:
+ if (stack->pool->free_stacks) {
+ fiber_pool_stack_free(&vacancy->stack);
+ }
+#endif
+}
+
+static COROUTINE
+fiber_entry(struct coroutine_context * from, struct coroutine_context * to)
+{
+ rb_fiber_start();
+}
+
+// Initialize a fiber's coroutine's machine stack and vm stack.
+static VALUE *
+fiber_initialize_coroutine(rb_fiber_t *fiber, size_t * vm_stack_size)
+{
+ struct fiber_pool * fiber_pool = fiber->stack.pool;
+ rb_execution_context_t *sec = &fiber->cont.saved_ec;
+ void * vm_stack = NULL;
+
+ VM_ASSERT(fiber_pool != NULL);
+
+ fiber->stack = fiber_pool_stack_acquire(fiber_pool);
+ vm_stack = fiber_pool_stack_alloca(&fiber->stack, fiber_pool->vm_stack_size);
+ *vm_stack_size = fiber_pool->vm_stack_size;
+
+#ifdef COROUTINE_PRIVATE_STACK
+ coroutine_initialize(&fiber->context, fiber_entry, fiber_pool_stack_base(&fiber->stack), fiber->stack.available, sec->machine.stack_start);
+ // The stack for this execution context is still the main machine stack, so don't adjust it.
+ // If this is not managed correctly, you will fail in `rb_ec_stack_check`.
+
+ // We limit the machine stack usage to the fiber stack size.
+ if (sec->machine.stack_maxsize > fiber->stack.available) {
+ sec->machine.stack_maxsize = fiber->stack.available;
+ }
+#else
+ coroutine_initialize(&fiber->context, fiber_entry, fiber_pool_stack_base(&fiber->stack), fiber->stack.available);
+
+ // The stack for this execution context is the one we allocated:
+ sec->machine.stack_start = fiber->stack.current;
+ sec->machine.stack_maxsize = fiber->stack.available;
+#endif
+
+ return vm_stack;
+}
+
+// Release the stack from the fiber, it's execution context, and return it to the fiber pool.
+static void
+fiber_stack_release(rb_fiber_t * fiber)
+{
+ rb_execution_context_t *ec = &fiber->cont.saved_ec;
+
+ if (DEBUG) fprintf(stderr, "fiber_stack_release: %p, stack.base=%p\n", (void*)fiber, fiber->stack.base);
+
+ // Return the stack back to the fiber pool if it wasn't already:
+ if (fiber->stack.base) {
+ fiber_pool_stack_release(&fiber->stack);
+ fiber->stack.base = NULL;
+ }
+
+ // The stack is no longer associated with this execution context:
+ rb_ec_clear_vm_stack(ec);
+}
static const char *
fiber_status_name(enum fiber_status s)
@@ -190,37 +770,106 @@ fiber_status_name(enum fiber_status s)
}
static void
-fiber_status_set(const rb_fiber_t *fib, enum fiber_status s)
+fiber_verify(const rb_fiber_t *fiber)
{
- if (0) fprintf(stderr, "fib: %p, status: %s -> %s\n", fib, fiber_status_name(fib->status), fiber_status_name(s));
- VM_ASSERT(!FIBER_TERMINATED_P(fib));
- VM_ASSERT(fib->status != s);
- *((enum fiber_status *)&fib->status) = s;
+#if VM_CHECK_MODE > 0
+ VM_ASSERT(fiber->cont.saved_ec.fiber_ptr == fiber);
+
+ switch (fiber->status) {
+ case FIBER_RESUMED:
+ VM_ASSERT(fiber->cont.saved_ec.vm_stack != NULL);
+ break;
+ case FIBER_SUSPENDED:
+ VM_ASSERT(fiber->cont.saved_ec.vm_stack != NULL);
+ break;
+ case FIBER_CREATED:
+ case FIBER_TERMINATED:
+ /* TODO */
+ break;
+ default:
+ VM_UNREACHABLE(fiber_verify);
+ }
+#endif
}
-static const rb_data_type_t cont_data_type, fiber_data_type;
-static VALUE rb_cContinuation;
-static VALUE rb_cFiber;
-static VALUE rb_eFiberError;
+inline static void
+fiber_status_set(rb_fiber_t *fiber, enum fiber_status s)
+{
+ // if (DEBUG) fprintf(stderr, "fiber: %p, status: %s -> %s\n", (void *)fiber, fiber_status_name(fiber->status), fiber_status_name(s));
+ VM_ASSERT(!FIBER_TERMINATED_P(fiber));
+ VM_ASSERT(fiber->status != s);
+ fiber_verify(fiber);
+ fiber->status = s;
+}
+
+static inline void
+ec_switch(rb_thread_t *th, rb_fiber_t *fiber)
+{
+ rb_execution_context_t *ec = &fiber->cont.saved_ec;
+ rb_ractor_set_current_ec(th->ractor, th->ec = ec);
+ // ruby_current_execution_context_ptr = th->ec = ec;
+
+ /*
+ * timer-thread may set trap interrupt on previous th->ec at any time;
+ * ensure we do not delay (or lose) the trap interrupt handling.
+ */
+ if (th->vm->ractor.main_thread == th &&
+ rb_signal_buff_size() > 0) {
+ RUBY_VM_SET_TRAP_INTERRUPT(ec);
+ }
+
+ VM_ASSERT(ec->fiber_ptr->cont.self == 0 || ec->vm_stack != NULL);
+}
+
+static rb_context_t *
+cont_ptr(VALUE obj)
+{
+ rb_context_t *cont;
+
+ TypedData_Get_Struct(obj, rb_context_t, &cont_data_type, cont);
+
+ return cont;
+}
+
+static rb_fiber_t *
+fiber_ptr(VALUE obj)
+{
+ rb_fiber_t *fiber;
-#define GetContPtr(obj, ptr) \
- TypedData_Get_Struct((obj), rb_context_t, &cont_data_type, (ptr))
+ TypedData_Get_Struct(obj, rb_fiber_t, &fiber_data_type, fiber);
+ if (!fiber) rb_raise(rb_eFiberError, "uninitialized fiber");
-#define GetFiberPtr(obj, ptr) do {\
- TypedData_Get_Struct((obj), rb_fiber_t, &fiber_data_type, (ptr)); \
- if (!(ptr)) rb_raise(rb_eFiberError, "uninitialized fiber"); \
-} while (0)
+ return fiber;
+}
NOINLINE(static VALUE cont_capture(volatile int *volatile stat));
#define THREAD_MUST_BE_RUNNING(th) do { \
- if (!(th)->ec.tag) rb_raise(rb_eThreadError, "not running thread"); \
+ if (!(th)->ec->tag) rb_raise(rb_eThreadError, "not running thread"); \
} while (0)
+rb_thread_t*
+rb_fiber_threadptr(const rb_fiber_t *fiber)
+{
+ return fiber->cont.saved_ec.thread_ptr;
+}
+
static VALUE
cont_thread_value(const rb_context_t *cont)
{
- return cont->thread_value;
+ return cont->saved_ec.thread_ptr->self;
+}
+
+static void
+cont_compact(void *ptr)
+{
+ rb_context_t *cont = ptr;
+
+ if (cont->self) {
+ cont->self = rb_gc_location(cont->self);
+ }
+ cont->value = rb_gc_location(cont->value);
+ rb_execution_context_update(&cont->saved_ec);
}
static void
@@ -229,97 +878,76 @@ cont_mark(void *ptr)
rb_context_t *cont = ptr;
RUBY_MARK_ENTER("cont");
- rb_gc_mark(cont->value);
+ if (cont->self) {
+ rb_gc_mark_movable(cont->self);
+ }
+ rb_gc_mark_movable(cont->value);
rb_execution_context_mark(&cont->saved_ec);
rb_gc_mark(cont_thread_value(cont));
if (cont->saved_vm_stack.ptr) {
#ifdef CAPTURE_JUST_VALID_VM_STACK
- rb_gc_mark_locations(cont->saved_vm_stack.ptr,
- cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen + cont->saved_vm_stack.clen);
+ rb_gc_mark_locations(cont->saved_vm_stack.ptr,
+ cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen + cont->saved_vm_stack.clen);
#else
- rb_gc_mark_locations(cont->saved_vm_stack.ptr,
- cont->saved_vm_stack.ptr, cont->saved_ec.stack_size);
+ rb_gc_mark_locations(cont->saved_vm_stack.ptr,
+ cont->saved_vm_stack.ptr, cont->saved_ec.stack_size);
#endif
}
if (cont->machine.stack) {
- if (cont->type == CONTINUATION_CONTEXT) {
- /* cont */
- rb_gc_mark_locations(cont->machine.stack,
- cont->machine.stack + cont->machine.stack_size);
- }
- else {
- /* fiber */
- const rb_thread_t *th = rb_thread_ptr(cont_thread_value(cont));
- const rb_fiber_t *fib = (rb_fiber_t*)cont;
-
- if ((th->ec.fiber != fib) && !FIBER_TERMINATED_P(fib)) {
- rb_gc_mark_locations(cont->machine.stack,
- cont->machine.stack + cont->machine.stack_size);
- }
- }
- }
-#ifdef __ia64
- if (cont->machine.register_stack) {
- rb_gc_mark_locations(cont->machine.register_stack,
- cont->machine.register_stack + cont->machine.register_stack_size);
+ if (cont->type == CONTINUATION_CONTEXT) {
+ /* cont */
+ rb_gc_mark_locations(cont->machine.stack,
+ cont->machine.stack + cont->machine.stack_size);
+ }
+ else {
+ /* fiber */
+ const rb_fiber_t *fiber = (rb_fiber_t*)cont;
+
+ if (!FIBER_TERMINATED_P(fiber)) {
+ rb_gc_mark_locations(cont->machine.stack,
+ cont->machine.stack + cont->machine.stack_size);
+ }
+ }
}
-#endif
RUBY_MARK_LEAVE("cont");
}
+#if 0
+static int
+fiber_is_root_p(const rb_fiber_t *fiber)
+{
+ return fiber == fiber->cont.saved_ec.thread_ptr->root_fiber;
+}
+#endif
+
static void
cont_free(void *ptr)
{
rb_context_t *cont = ptr;
RUBY_FREE_ENTER("cont");
- RUBY_FREE_UNLESS_NULL(cont->saved_ec.vm_stack);
-#if FIBER_USE_NATIVE
+
if (cont->type == CONTINUATION_CONTEXT) {
- /* cont */
- ruby_xfree(cont->ensure_array);
- RUBY_FREE_UNLESS_NULL(cont->machine.stack);
+ ruby_xfree(cont->saved_ec.vm_stack);
+ ruby_xfree(cont->ensure_array);
+ RUBY_FREE_UNLESS_NULL(cont->machine.stack);
}
else {
- /* fiber */
- const rb_fiber_t *fib = (rb_fiber_t*)cont;
- const rb_thread_t *const th = GET_THREAD();
-#ifdef _WIN32
- if (th && th->ec.fiber != fib && cont->type != ROOT_FIBER_CONTEXT) {
- /* don't delete root fiber handle */
- if (fib->fib_handle) {
- DeleteFiber(fib->fib_handle);
- }
- }
-#else /* not WIN32 */
- if (th && th->ec.fiber != fib) {
- if (fib->ss_sp) {
- if (cont->type == ROOT_FIBER_CONTEXT) {
- rb_bug("Illegal root fiber parameter");
- }
- munmap((void*)fib->ss_sp, fib->ss_size);
- }
- }
- else {
- /* It may reached here when finalize */
- /* TODO examine whether it is a bug */
- /* rb_bug("cont_free: release self"); */
- }
-#endif
+ rb_fiber_t *fiber = (rb_fiber_t*)cont;
+ coroutine_destroy(&fiber->context);
+ fiber_stack_release(fiber);
}
-#else /* not FIBER_USE_NATIVE */
- ruby_xfree(cont->ensure_array);
- RUBY_FREE_UNLESS_NULL(cont->machine.stack);
-#endif
-#ifdef __ia64
- RUBY_FREE_UNLESS_NULL(cont->machine.register_stack);
-#endif
+
RUBY_FREE_UNLESS_NULL(cont->saved_vm_stack.ptr);
+ if (mjit_enabled) {
+ VM_ASSERT(cont->mjit_cont != NULL);
+ mjit_cont_free(cont->mjit_cont);
+ }
/* free rb_cont_t or rb_fiber_t */
ruby_xfree(ptr);
RUBY_FREE_LEAVE("cont");
@@ -334,90 +962,97 @@ cont_memsize(const void *ptr)
size = sizeof(*cont);
if (cont->saved_vm_stack.ptr) {
#ifdef CAPTURE_JUST_VALID_VM_STACK
- size_t n = (cont->saved_vm_stack.slen + cont->saved_vm_stack.clen);
+ size_t n = (cont->saved_vm_stack.slen + cont->saved_vm_stack.clen);
#else
- size_t n = cont->saved_ec.vm_stack_size;
+ size_t n = cont->saved_ec.vm_stack_size;
#endif
- size += n * sizeof(*cont->saved_vm_stack.ptr);
+ size += n * sizeof(*cont->saved_vm_stack.ptr);
}
if (cont->machine.stack) {
- size += cont->machine.stack_size * sizeof(*cont->machine.stack);
- }
-#ifdef __ia64
- if (cont->machine.register_stack) {
- size += cont->machine.register_stack_size * sizeof(*cont->machine.register_stack);
+ size += cont->machine.stack_size * sizeof(*cont->machine.stack);
}
-#endif
+
return size;
}
-static void
-fiber_verify(const rb_fiber_t *fib)
+void
+rb_fiber_update_self(rb_fiber_t *fiber)
{
-#if VM_CHECK_MODE > 0
- switch (fib->status) {
- case FIBER_RESUMED:
- VM_ASSERT(fib->cont.saved_ec.vm_stack == NULL);
- break;
- case FIBER_SUSPENDED:
- VM_ASSERT(fib->cont.saved_ec.vm_stack != NULL);
- break;
- case FIBER_CREATED:
- case FIBER_TERMINATED:
- /* TODO */
- break;
- default:
- VM_UNREACHABLE(fiber_verify);
+ if (fiber->cont.self) {
+ fiber->cont.self = rb_gc_location(fiber->cont.self);
+ }
+ else {
+ rb_execution_context_update(&fiber->cont.saved_ec);
}
-#endif
}
void
-rb_fiber_mark_self(const rb_fiber_t *fib)
+rb_fiber_mark_self(const rb_fiber_t *fiber)
{
- if (fib)
- rb_gc_mark(fib->cont.self);
+ if (fiber->cont.self) {
+ rb_gc_mark_movable(fiber->cont.self);
+ }
+ else {
+ rb_execution_context_mark(&fiber->cont.saved_ec);
+ }
+}
+
+static void
+fiber_compact(void *ptr)
+{
+ rb_fiber_t *fiber = ptr;
+ fiber->first_proc = rb_gc_location(fiber->first_proc);
+
+ if (fiber->prev) rb_fiber_update_self(fiber->prev);
+
+ cont_compact(&fiber->cont);
+ fiber_verify(fiber);
}
static void
fiber_mark(void *ptr)
{
- rb_fiber_t *fib = ptr;
+ rb_fiber_t *fiber = ptr;
RUBY_MARK_ENTER("cont");
- fiber_verify(fib);
- rb_gc_mark(fib->first_proc);
- rb_fiber_mark_self(fib->prev);
- cont_mark(&fib->cont);
+ fiber_verify(fiber);
+ rb_gc_mark_movable(fiber->first_proc);
+ if (fiber->prev) rb_fiber_mark_self(fiber->prev);
+ cont_mark(&fiber->cont);
RUBY_MARK_LEAVE("cont");
}
static void
fiber_free(void *ptr)
{
- rb_fiber_t *fib = ptr;
+ rb_fiber_t *fiber = ptr;
RUBY_FREE_ENTER("fiber");
- if (fib->cont.type != ROOT_FIBER_CONTEXT &&
- fib->cont.saved_ec.local_storage) {
- st_free_table(fib->cont.saved_ec.local_storage);
+
+ //if (DEBUG) fprintf(stderr, "fiber_free: %p[%p]\n", fiber, fiber->stack.base);
+
+ if (fiber->cont.saved_ec.local_storage) {
+ rb_id_table_free(fiber->cont.saved_ec.local_storage);
}
- cont_free(&fib->cont);
+ cont_free(&fiber->cont);
RUBY_FREE_LEAVE("fiber");
}
static size_t
fiber_memsize(const void *ptr)
{
- const rb_fiber_t *fib = ptr;
- size_t size = 0;
+ const rb_fiber_t *fiber = ptr;
+ size_t size = sizeof(*fiber);
+ const rb_execution_context_t *saved_ec = &fiber->cont.saved_ec;
+ const rb_thread_t *th = rb_ec_thread_ptr(saved_ec);
- size = sizeof(*fib);
- if (fib->cont.type != ROOT_FIBER_CONTEXT &&
- fib->cont.saved_ec.local_storage != NULL) {
- size += st_memsize(fib->cont.saved_ec.local_storage);
+ /*
+ * vm.c::thread_memsize already counts th->ec->local_storage
+ */
+ if (saved_ec->local_storage && fiber != th->root_fiber) {
+ size += rb_id_table_memsize(saved_ec->local_storage);
}
- size += cont_memsize(&fib->cont);
+ size += cont_memsize(&fiber->cont);
return size;
}
@@ -425,10 +1060,10 @@ VALUE
rb_obj_is_fiber(VALUE obj)
{
if (rb_typeddata_is_kind_of(obj, &fiber_data_type)) {
- return Qtrue;
+ return Qtrue;
}
else {
- return Qfalse;
+ return Qfalse;
}
}
@@ -437,48 +1072,31 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
{
size_t size;
- SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
-#ifdef __ia64
- th->machine.register_stack_end = rb_ia64_bsp();
-#endif
+ SET_MACHINE_STACK_END(&th->ec->machine.stack_end);
- if (th->ec.machine.stack_start > th->ec.machine.stack_end) {
- size = cont->machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end;
- cont->machine.stack_src = th->ec.machine.stack_end;
+ if (th->ec->machine.stack_start > th->ec->machine.stack_end) {
+ size = cont->machine.stack_size = th->ec->machine.stack_start - th->ec->machine.stack_end;
+ cont->machine.stack_src = th->ec->machine.stack_end;
}
else {
- size = cont->machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start;
- cont->machine.stack_src = th->ec.machine.stack_start;
+ size = cont->machine.stack_size = th->ec->machine.stack_end - th->ec->machine.stack_start;
+ cont->machine.stack_src = th->ec->machine.stack_start;
}
if (cont->machine.stack) {
- REALLOC_N(cont->machine.stack, VALUE, size);
+ REALLOC_N(cont->machine.stack, VALUE, size);
}
else {
- cont->machine.stack = ALLOC_N(VALUE, size);
+ cont->machine.stack = ALLOC_N(VALUE, size);
}
FLUSH_REGISTER_WINDOWS;
MEMCPY(cont->machine.stack, cont->machine.stack_src, VALUE, size);
-
-#ifdef __ia64
- rb_ia64_flushrs();
- size = cont->machine.register_stack_size = th->machine.register_stack_end - th->machine.register_stack_start;
- cont->machine.register_stack_src = th->machine.register_stack_start;
- if (cont->machine.register_stack) {
- REALLOC_N(cont->machine.register_stack, VALUE, size);
- }
- else {
- cont->machine.register_stack = ALLOC_N(VALUE, size);
- }
-
- MEMCPY(cont->machine.register_stack, cont->machine.register_stack_src, VALUE, size);
-#endif
}
static const rb_data_type_t cont_data_type = {
"continuation",
- {cont_mark, cont_free, cont_memsize,},
+ {cont_mark, cont_free, cont_memsize, cont_compact},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -490,16 +1108,20 @@ cont_save_thread(rb_context_t *cont, rb_thread_t *th)
VM_ASSERT(th->status == THREAD_RUNNABLE);
/* save thread context */
- *sec = th->ec;
+ *sec = *th->ec;
- /* saved_thread->machine.stack_end should be NULL */
+ /* saved_ec->machine.stack_end should be NULL */
/* because it may happen GC afterward */
sec->machine.stack_end = NULL;
+}
-#ifdef __ia64
- sec->machine.register_stack_start = NULL;
- sec->machine.register_stack_end = NULL;
-#endif
+static void
+cont_init_mjit_cont(rb_context_t *cont)
+{
+ VM_ASSERT(cont->mjit_cont == NULL);
+ if (mjit_enabled) {
+ cont->mjit_cont = mjit_cont_new(&(cont->saved_ec));
+ }
}
static void
@@ -507,10 +1129,11 @@ cont_init(rb_context_t *cont, rb_thread_t *th)
{
/* save thread context */
cont_save_thread(cont, th);
- cont->thread_value = th->self;
+ cont->saved_ec.thread_ptr = th;
cont->saved_ec.local_storage = NULL;
cont->saved_ec.local_storage_recursive_hash = Qnil;
cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil;
+ cont_init_mjit_cont(cont);
}
static rb_context_t *
@@ -527,16 +1150,64 @@ cont_new(VALUE klass)
return cont;
}
+VALUE rb_fiberptr_self(struct rb_fiber_struct *fiber)
+{
+ return fiber->cont.self;
+}
+
+unsigned int rb_fiberptr_blocking(struct rb_fiber_struct *fiber)
+{
+ return fiber->blocking;
+}
+
+// This is used for root_fiber because other fibers call cont_init_mjit_cont through cont_new.
+void
+rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber)
+{
+ cont_init_mjit_cont(&fiber->cont);
+}
+
+#if 0
+void
+show_vm_stack(const rb_execution_context_t *ec)
+{
+ VALUE *p = ec->vm_stack;
+ while (p < ec->cfp->sp) {
+ fprintf(stderr, "%3d ", (int)(p - ec->vm_stack));
+ rb_obj_info_dump(*p);
+ p++;
+ }
+}
+
+void
+show_vm_pcs(const rb_control_frame_t *cfp,
+ const rb_control_frame_t *end_of_cfp)
+{
+ int i=0;
+ while (cfp != end_of_cfp) {
+ int pc = 0;
+ if (cfp->iseq) {
+ pc = cfp->pc - cfp->iseq->body->iseq_encoded;
+ }
+ fprintf(stderr, "%2d pc: %d\n", i++, pc);
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+ }
+}
+#endif
+COMPILER_WARNING_PUSH
+#ifdef __clang__
+COMPILER_WARNING_IGNORED(-Wduplicate-decl-specifier)
+#endif
static VALUE
cont_capture(volatile int *volatile stat)
{
rb_context_t *volatile cont;
rb_thread_t *th = GET_THREAD();
volatile VALUE contval;
- rb_execution_context_t *ec = &th->ec;
+ const rb_execution_context_t *ec = th->ec;
THREAD_MUST_BE_RUNNING(th);
- rb_vm_stack_to_heap(th);
+ rb_vm_stack_to_heap(th->ec);
cont = cont_new(rb_cContinuation);
contval = cont->self;
@@ -544,56 +1215,60 @@ cont_capture(volatile int *volatile stat)
cont->saved_vm_stack.slen = ec->cfp->sp - ec->vm_stack;
cont->saved_vm_stack.clen = ec->vm_stack + ec->vm_stack_size - (VALUE*)ec->cfp;
cont->saved_vm_stack.ptr = ALLOC_N(VALUE, cont->saved_vm_stack.slen + cont->saved_vm_stack.clen);
- MEMCPY(cont->saved_vm_stack.ptr, ec->vm_stack, VALUE, cont->saved_vm_stack.slen);
+ MEMCPY(cont->saved_vm_stack.ptr,
+ ec->vm_stack,
+ VALUE, cont->saved_vm_stack.slen);
MEMCPY(cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen,
- (VALUE*)ec->cfp, VALUE, cont->saved_vm_stack.clen);
+ (VALUE*)ec->cfp,
+ VALUE,
+ cont->saved_vm_stack.clen);
#else
cont->saved_vm_stack.ptr = ALLOC_N(VALUE, ec->vm_stack_size);
MEMCPY(cont->saved_vm_stack.ptr, ec->vm_stack, VALUE, ec->vm_stack_size);
#endif
- cont->saved_ec.vm_stack = NULL;
-
+ // At this point, `cfp` is valid but `vm_stack` should be cleared:
+ rb_ec_set_vm_stack(&cont->saved_ec, NULL, 0);
+ VM_ASSERT(cont->saved_ec.cfp != NULL);
cont_save_machine_stack(th, cont);
/* backup ensure_list to array for search in another context */
{
- rb_ensure_list_t *p;
- int size = 0;
- rb_ensure_entry_t *entry;
- for (p=th->ec.ensure_list; p; p=p->next)
- size++;
- entry = cont->ensure_array = ALLOC_N(rb_ensure_entry_t,size+1);
- for (p=th->ec.ensure_list; p; p=p->next) {
- if (!p->entry.marker)
- p->entry.marker = rb_ary_tmp_new(0); /* dummy object */
- *entry++ = p->entry;
- }
- entry->marker = 0;
+ rb_ensure_list_t *p;
+ int size = 0;
+ rb_ensure_entry_t *entry;
+ for (p=th->ec->ensure_list; p; p=p->next)
+ size++;
+ entry = cont->ensure_array = ALLOC_N(rb_ensure_entry_t,size+1);
+ for (p=th->ec->ensure_list; p; p=p->next) {
+ if (!p->entry.marker)
+ p->entry.marker = rb_ary_tmp_new(0); /* dummy object */
+ *entry++ = p->entry;
+ }
+ entry->marker = 0;
}
if (ruby_setjmp(cont->jmpbuf)) {
- VALUE value;
+ VALUE value;
- VAR_INITIALIZED(cont);
- value = cont->value;
- if (cont->argc == -1) rb_exc_raise(value);
- cont->value = Qnil;
- *stat = 1;
- return value;
+ VAR_INITIALIZED(cont);
+ value = cont->value;
+ if (cont->argc == -1) rb_exc_raise(value);
+ cont->value = Qnil;
+ *stat = 1;
+ return value;
}
else {
- *stat = 0;
- return contval;
+ *stat = 0;
+ return contval;
}
}
+COMPILER_WARNING_POP
static inline void
-fiber_restore_thread(rb_thread_t *th, rb_fiber_t *fib)
+fiber_restore_thread(rb_thread_t *th, rb_fiber_t *fiber)
{
- th->ec = fib->cont.saved_ec;
- fib->cont.saved_ec.vm_stack = NULL;
-
- VM_ASSERT(th->ec.vm_stack != NULL);
+ ec_switch(th, fiber);
+ VM_ASSERT(th->ec->fiber_ptr == fiber);
}
static inline void
@@ -603,198 +1278,93 @@ cont_restore_thread(rb_context_t *cont)
/* restore thread context */
if (cont->type == CONTINUATION_CONTEXT) {
- /* continuation */
- rb_execution_context_t *sec = &cont->saved_ec;
- const rb_fiber_t *fib;
-
- fib = th->ec.fiber = sec->fiber;
- if (fib == NULL) fib = th->root_fiber;
-
- if (fib && fib->cont.saved_ec.vm_stack) {
- th->ec.vm_stack_size = fib->cont.saved_ec.vm_stack_size;
- th->ec.vm_stack = fib->cont.saved_ec.vm_stack;
- }
+ /* continuation */
+ rb_execution_context_t *sec = &cont->saved_ec;
+ rb_fiber_t *fiber = NULL;
+
+ if (sec->fiber_ptr != NULL) {
+ fiber = sec->fiber_ptr;
+ }
+ else if (th->root_fiber) {
+ fiber = th->root_fiber;
+ }
+
+ if (fiber && th->ec != &fiber->cont.saved_ec) {
+ ec_switch(th, fiber);
+ }
+
+ if (th->ec->trace_arg != sec->trace_arg) {
+ rb_raise(rb_eRuntimeError, "can't call across trace_func");
+ }
+
+ /* copy vm stack */
#ifdef CAPTURE_JUST_VALID_VM_STACK
- MEMCPY(th->ec.vm_stack, cont->saved_vm_stack.ptr, VALUE, cont->saved_vm_stack.slen);
- MEMCPY(th->ec.vm_stack + sec->vm_stack_size - cont->saved_vm_stack.clen,
- cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen, VALUE, cont->saved_vm_stack.clen);
-#else
- MEMCPY(th->ec.vm_stack, cont->saved_vm_stack.ptr, VALUE, sec->vm_stack_size);
-#endif
-
- /* other members of ec */
- th->ec.cfp = sec->cfp;
- th->ec.safe_level = sec->safe_level;
- th->ec.raised_flag = sec->raised_flag;
- th->ec.tag = sec->tag;
- th->ec.protect_tag = sec->protect_tag;
- th->ec.root_lep = sec->root_lep;
- th->ec.root_svar = sec->root_svar;
- th->ec.ensure_list = sec->ensure_list;
- th->ec.errinfo = sec->errinfo;
- th->ec.trace_arg = sec->trace_arg;
-
- VM_ASSERT(th->ec.vm_stack != NULL);
- }
- else {
- /* fiber */
- fiber_restore_thread(th, (rb_fiber_t*)cont);
- }
-}
-
-#if FIBER_USE_NATIVE
-#ifdef _WIN32
-static void
-fiber_set_stack_location(void)
-{
- rb_thread_t *th = GET_THREAD();
- VALUE *ptr;
-
- SET_MACHINE_STACK_END(&ptr);
- th->ec.machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE));
-}
-
-static VOID CALLBACK
-fiber_entry(void *arg)
-{
- fiber_set_stack_location();
- rb_fiber_start();
-}
-#else /* _WIN32 */
-
-/*
- * FreeBSD require a first (i.e. addr) argument of mmap(2) is not NULL
- * if MAP_STACK is passed.
- * http://www.FreeBSD.org/cgi/query-pr.cgi?pr=158755
- */
-#if defined(MAP_STACK) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
-#define FIBER_STACK_FLAGS (MAP_PRIVATE | MAP_ANON | MAP_STACK)
+ MEMCPY(th->ec->vm_stack,
+ cont->saved_vm_stack.ptr,
+ VALUE, cont->saved_vm_stack.slen);
+ MEMCPY(th->ec->vm_stack + th->ec->vm_stack_size - cont->saved_vm_stack.clen,
+ cont->saved_vm_stack.ptr + cont->saved_vm_stack.slen,
+ VALUE, cont->saved_vm_stack.clen);
#else
-#define FIBER_STACK_FLAGS (MAP_PRIVATE | MAP_ANON)
+ MEMCPY(th->ec->vm_stack, cont->saved_vm_stack.ptr, VALUE, sec->vm_stack_size);
#endif
+ /* other members of ec */
-static char*
-fiber_machine_stack_alloc(size_t size)
-{
- char *ptr;
+ th->ec->cfp = sec->cfp;
+ th->ec->raised_flag = sec->raised_flag;
+ th->ec->tag = sec->tag;
+ th->ec->protect_tag = sec->protect_tag;
+ th->ec->root_lep = sec->root_lep;
+ th->ec->root_svar = sec->root_svar;
+ th->ec->ensure_list = sec->ensure_list;
+ th->ec->errinfo = sec->errinfo;
- if (machine_stack_cache_index > 0) {
- if (machine_stack_cache[machine_stack_cache_index - 1].size == (size / sizeof(VALUE))) {
- ptr = machine_stack_cache[machine_stack_cache_index - 1].ptr;
- machine_stack_cache_index--;
- machine_stack_cache[machine_stack_cache_index].ptr = NULL;
- machine_stack_cache[machine_stack_cache_index].size = 0;
- }
- else{
- /* TODO handle multiple machine stack size */
- rb_bug("machine_stack_cache size is not canonicalized");
- }
+ VM_ASSERT(th->ec->vm_stack != NULL);
}
else {
- void *page;
- STACK_GROW_DIR_DETECTION;
-
- errno = 0;
- ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, FIBER_STACK_FLAGS, -1, 0);
- if (ptr == MAP_FAILED) {
- rb_raise(rb_eFiberError, "can't alloc machine stack to fiber: %s", strerror(errno));
- }
-
- /* guard page setup */
- page = ptr + STACK_DIR_UPPER(size - RB_PAGE_SIZE, 0);
- if (mprotect(page, RB_PAGE_SIZE, PROT_NONE) < 0) {
- rb_raise(rb_eFiberError, "mprotect failed");
- }
+ /* fiber */
+ fiber_restore_thread(th, (rb_fiber_t*)cont);
}
-
- return ptr;
-}
-#endif
-
-static void
-fiber_initialize_machine_stack_context(rb_fiber_t *fib, size_t size)
-{
- rb_execution_context_t *sec = &fib->cont.saved_ec;
-
-#ifdef _WIN32
-# if defined(_MSC_VER) && _MSC_VER <= 1200
-# define CreateFiberEx(cs, stacksize, flags, entry, param) \
- CreateFiber((stacksize), (entry), (param))
-# endif
- fib->fib_handle = CreateFiberEx(size - 1, size, 0, fiber_entry, NULL);
- if (!fib->fib_handle) {
- /* try to release unnecessary fibers & retry to create */
- rb_gc();
- fib->fib_handle = CreateFiberEx(size - 1, size, 0, fiber_entry, NULL);
- if (!fib->fib_handle) {
- rb_raise(rb_eFiberError, "can't create fiber");
- }
- }
- sec->machine.stack_maxsize = size;
-#else /* not WIN32 */
- ucontext_t *context = &fib->context;
- char *ptr;
- STACK_GROW_DIR_DETECTION;
-
- getcontext(context);
- ptr = fiber_machine_stack_alloc(size);
- context->uc_link = NULL;
- context->uc_stack.ss_sp = ptr;
- context->uc_stack.ss_size = size;
- fib->ss_sp = ptr;
- fib->ss_size = size;
- makecontext(context, rb_fiber_start, 0);
- sec->machine.stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size));
- sec->machine.stack_maxsize = size - RB_PAGE_SIZE;
-#endif
-#ifdef __ia64
- sth->machine.register_stack_maxsize = sth->machine.stack_maxsize;
-#endif
}
-NOINLINE(static void fiber_setcontext(rb_fiber_t *newfib, rb_fiber_t *oldfib));
+NOINLINE(static void fiber_setcontext(rb_fiber_t *new_fiber, rb_fiber_t *old_fiber));
static void
-fiber_setcontext(rb_fiber_t *newfib, rb_fiber_t *oldfib)
+fiber_setcontext(rb_fiber_t *new_fiber, rb_fiber_t *old_fiber)
{
rb_thread_t *th = GET_THREAD();
- /* save oldfib's machine stack / TODO: is it needed? */
- if (!FIBER_TERMINATED_P(oldfib)) {
- STACK_GROW_DIR_DETECTION;
- SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
- if (STACK_DIR_UPPER(0, 1)) {
- oldfib->cont.machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end;
- oldfib->cont.machine.stack = th->ec.machine.stack_end;
- }
- else {
- oldfib->cont.machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start;
- oldfib->cont.machine.stack = th->ec.machine.stack_start;
- }
+ /* save old_fiber's machine stack - to ensure efficient garbage collection */
+ if (!FIBER_TERMINATED_P(old_fiber)) {
+ STACK_GROW_DIR_DETECTION;
+ SET_MACHINE_STACK_END(&th->ec->machine.stack_end);
+ if (STACK_DIR_UPPER(0, 1)) {
+ old_fiber->cont.machine.stack_size = th->ec->machine.stack_start - th->ec->machine.stack_end;
+ old_fiber->cont.machine.stack = th->ec->machine.stack_end;
+ }
+ else {
+ old_fiber->cont.machine.stack_size = th->ec->machine.stack_end - th->ec->machine.stack_start;
+ old_fiber->cont.machine.stack = th->ec->machine.stack_start;
+ }
}
- /* exchange machine_stack_start between oldfib and newfib */
- oldfib->cont.saved_ec.machine.stack_start = th->ec.machine.stack_start;
+ /* exchange machine_stack_start between old_fiber and new_fiber */
+ old_fiber->cont.saved_ec.machine.stack_start = th->ec->machine.stack_start;
- /* oldfib->machine.stack_end should be NULL */
- oldfib->cont.saved_ec.machine.stack_end = NULL;
+ /* old_fiber->machine.stack_end should be NULL */
+ old_fiber->cont.saved_ec.machine.stack_end = NULL;
/* restore thread context */
- fiber_restore_thread(th, newfib);
+ fiber_restore_thread(th, new_fiber);
+
+ // if (DEBUG) fprintf(stderr, "fiber_setcontext: %p[%p] -> %p[%p]\n", old_fiber, old_fiber->stack.base, new_fiber, new_fiber->stack.base);
-#ifndef _WIN32
- if (!newfib->context.uc_stack.ss_sp && th->root_fiber != newfib) {
- rb_bug("non_root_fiber->context.uc_stac.ss_sp should not be NULL");
- }
-#endif
/* swap machine context */
-#ifdef _WIN32
- SwitchToFiber(newfib->fib_handle);
-#else
- swapcontext(&oldfib->context, &newfib->context);
-#endif
+ coroutine_transfer(&old_fiber->context, &new_fiber->context);
+
+ // It's possible to get here, and new_fiber is already freed.
+ // if (DEBUG) fprintf(stderr, "fiber_setcontext: %p[%p] <- %p[%p]\n", old_fiber, old_fiber->stack.base, new_fiber, new_fiber->stack.base);
}
-#endif
NOINLINE(NORETURN(static void cont_restore_1(rb_context_t *)));
@@ -806,66 +1376,24 @@ cont_restore_1(rb_context_t *cont)
/* restore machine stack */
#ifdef _M_AMD64
{
- /* workaround for x64 SEH */
- jmp_buf buf;
- setjmp(buf);
- ((_JUMP_BUFFER*)(&cont->jmpbuf))->Frame =
- ((_JUMP_BUFFER*)(&buf))->Frame;
+ /* workaround for x64 SEH */
+ jmp_buf buf;
+ setjmp(buf);
+ _JUMP_BUFFER *bp = (void*)&cont->jmpbuf;
+ bp->Frame = ((_JUMP_BUFFER*)((void*)&buf))->Frame;
}
#endif
if (cont->machine.stack_src) {
- FLUSH_REGISTER_WINDOWS;
- MEMCPY(cont->machine.stack_src, cont->machine.stack,
- VALUE, cont->machine.stack_size);
- }
-
-#ifdef __ia64
- if (cont->machine.register_stack_src) {
- MEMCPY(cont->machine.register_stack_src, cont->machine.register_stack,
- VALUE, cont->machine.register_stack_size);
+ FLUSH_REGISTER_WINDOWS;
+ MEMCPY(cont->machine.stack_src, cont->machine.stack,
+ VALUE, cont->machine.stack_size);
}
-#endif
ruby_longjmp(cont->jmpbuf, 1);
}
NORETURN(NOINLINE(static void cont_restore_0(rb_context_t *, VALUE *)));
-#ifdef __ia64
-#define C(a) rse_##a##0, rse_##a##1, rse_##a##2, rse_##a##3, rse_##a##4
-#define E(a) rse_##a##0= rse_##a##1= rse_##a##2= rse_##a##3= rse_##a##4
-static volatile int C(a), C(b), C(c), C(d), C(e);
-static volatile int C(f), C(g), C(h), C(i), C(j);
-static volatile int C(k), C(l), C(m), C(n), C(o);
-static volatile int C(p), C(q), C(r), C(s), C(t);
-#if 0
-{/* the above lines make cc-mode.el confused so much */}
-#endif
-int rb_dummy_false = 0;
-NORETURN(NOINLINE(static void register_stack_extend(rb_context_t *, VALUE *, VALUE *)));
-static void
-register_stack_extend(rb_context_t *cont, VALUE *vp, VALUE *curr_bsp)
-{
- if (rb_dummy_false) {
- /* use registers as much as possible */
- E(a) = E(b) = E(c) = E(d) = E(e) =
- E(f) = E(g) = E(h) = E(i) = E(j) =
- E(k) = E(l) = E(m) = E(n) = E(o) =
- E(p) = E(q) = E(r) = E(s) = E(t) = 0;
- E(a) = E(b) = E(c) = E(d) = E(e) =
- E(f) = E(g) = E(h) = E(i) = E(j) =
- E(k) = E(l) = E(m) = E(n) = E(o) =
- E(p) = E(q) = E(r) = E(s) = E(t) = 0;
- }
- if (curr_bsp < cont->machine.register_stack_src+cont->machine.register_stack_size) {
- register_stack_extend(cont, vp, (VALUE*)rb_ia64_bsp());
- }
- cont_restore_0(cont, vp);
-}
-#undef C
-#undef E
-#endif
-
static void
cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame)
{
@@ -875,48 +1403,45 @@ cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame)
#else
#define STACK_PAD_SIZE 1024
#endif
- VALUE space[STACK_PAD_SIZE];
+ VALUE space[STACK_PAD_SIZE];
#if !STACK_GROW_DIRECTION
- if (addr_in_prev_frame > &space[0]) {
- /* Stack grows downward */
+ if (addr_in_prev_frame > &space[0]) {
+ /* Stack grows downward */
#endif
#if STACK_GROW_DIRECTION <= 0
- volatile VALUE *const end = cont->machine.stack_src;
- if (&space[0] > end) {
+ volatile VALUE *const end = cont->machine.stack_src;
+ if (&space[0] > end) {
# ifdef HAVE_ALLOCA
- volatile VALUE *sp = ALLOCA_N(VALUE, &space[0] - end);
- space[0] = *sp;
+ volatile VALUE *sp = ALLOCA_N(VALUE, &space[0] - end);
+ space[0] = *sp;
# else
- cont_restore_0(cont, &space[0]);
+ cont_restore_0(cont, &space[0]);
# endif
- }
+ }
#endif
#if !STACK_GROW_DIRECTION
- }
- else {
- /* Stack grows upward */
+ }
+ else {
+ /* Stack grows upward */
#endif
#if STACK_GROW_DIRECTION >= 0
- volatile VALUE *const end = cont->machine.stack_src + cont->machine.stack_size;
- if (&space[STACK_PAD_SIZE] < end) {
+ volatile VALUE *const end = cont->machine.stack_src + cont->machine.stack_size;
+ if (&space[STACK_PAD_SIZE] < end) {
# ifdef HAVE_ALLOCA
- volatile VALUE *sp = ALLOCA_N(VALUE, end - &space[STACK_PAD_SIZE]);
- space[0] = *sp;
+ volatile VALUE *sp = ALLOCA_N(VALUE, end - &space[STACK_PAD_SIZE]);
+ space[0] = *sp;
# else
- cont_restore_0(cont, &space[STACK_PAD_SIZE-1]);
+ cont_restore_0(cont, &space[STACK_PAD_SIZE-1]);
# endif
- }
+ }
#endif
#if !STACK_GROW_DIRECTION
- }
+ }
#endif
}
cont_restore_1(cont);
}
-#ifdef __ia64
-#define cont_restore_0(cont, vp) register_stack_extend((cont), (vp), (VALUE*)rb_ia64_bsp())
-#endif
/*
* Document-class: Continuation
@@ -924,7 +1449,7 @@ cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame)
* Continuation objects are generated by Kernel#callcc,
* after having +require+d <i>continuation</i>. They hold
* a return address and execution context, allowing a nonlocal return
- * to the end of the <code>callcc</code> block from anywhere within a
+ * to the end of the #callcc block from anywhere within a
* program. Continuations are somewhat analogous to a structured
* version of C's <code>setjmp/longjmp</code> (although they contain
* more state, so you might consider them closer to threads).
@@ -968,7 +1493,7 @@ cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame)
* require "continuation"
* callcc {|cont|
* for i in 0..4
- * print "\n#{i}: "
+ * print "#{i}: "
* for j in i*5...(i+1)*5
* cont.call() if j == 17
* printf "%3d", j
@@ -1008,10 +1533,10 @@ rb_callcc(VALUE self)
volatile VALUE val = cont_capture(&called);
if (called) {
- return val;
+ return val;
}
else {
- return rb_yield(val);
+ return rb_yield(val);
}
}
@@ -1019,35 +1544,39 @@ static VALUE
make_passing_arg(int argc, const VALUE *argv)
{
switch (argc) {
+ case -1:
+ return argv[0];
case 0:
- return Qnil;
+ return Qnil;
case 1:
- return argv[0];
+ return argv[0];
default:
- return rb_ary_new4(argc, argv);
+ return rb_ary_new4(argc, argv);
}
}
+typedef VALUE e_proc(VALUE);
+
/* CAUTION!! : Currently, error in rollback_func is not supported */
/* same as rb_protect if set rollback_func to NULL */
void
-ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(ANYARGS), VALUE (*rollback_func)(ANYARGS))
+ruby_register_rollback_func_for_ensure(e_proc *ensure_func, e_proc *rollback_func)
{
st_table **table_p = &GET_VM()->ensure_rollback_table;
if (UNLIKELY(*table_p == NULL)) {
- *table_p = st_init_numtable();
+ *table_p = st_init_numtable();
}
st_insert(*table_p, (st_data_t)ensure_func, (st_data_t)rollback_func);
}
-static inline VALUE
-lookup_rollback_func(VALUE (*ensure_func)(ANYARGS))
+static inline e_proc *
+lookup_rollback_func(e_proc *ensure_func)
{
st_table *table = GET_VM()->ensure_rollback_table;
st_data_t val;
if (table && st_lookup(table, (st_data_t)ensure_func, &val))
- return (VALUE) val;
- return Qundef;
+ return (e_proc *) val;
+ return (e_proc *) Qundef;
}
@@ -1056,62 +1585,63 @@ rollback_ensure_stack(VALUE self,rb_ensure_list_t *current,rb_ensure_entry_t *ta
{
rb_ensure_list_t *p;
rb_ensure_entry_t *entry;
- size_t i;
+ size_t i, j;
size_t cur_size;
size_t target_size;
size_t base_point;
- VALUE (*func)(ANYARGS);
+ e_proc *func;
cur_size = 0;
for (p=current; p; p=p->next)
- cur_size++;
+ cur_size++;
target_size = 0;
for (entry=target; entry->marker; entry++)
- target_size++;
+ target_size++;
/* search common stack point */
p = current;
base_point = cur_size;
while (base_point) {
- if (target_size >= base_point &&
- p->entry.marker == target[target_size - base_point].marker)
- break;
- base_point --;
- p = p->next;
+ if (target_size >= base_point &&
+ p->entry.marker == target[target_size - base_point].marker)
+ break;
+ base_point --;
+ p = p->next;
}
/* rollback function check */
for (i=0; i < target_size - base_point; i++) {
- if (!lookup_rollback_func(target[i].e_proc)) {
- rb_raise(rb_eRuntimeError, "continuation called from out of critical rb_ensure scope");
- }
+ if (!lookup_rollback_func(target[i].e_proc)) {
+ rb_raise(rb_eRuntimeError, "continuation called from out of critical rb_ensure scope");
+ }
}
/* pop ensure stack */
while (cur_size > base_point) {
- /* escape from ensure block */
- (*current->entry.e_proc)(current->entry.data2);
- current = current->next;
- cur_size--;
+ /* escape from ensure block */
+ (*current->entry.e_proc)(current->entry.data2);
+ current = current->next;
+ cur_size--;
}
/* push ensure stack */
- while (i--) {
- func = (VALUE (*)(ANYARGS)) lookup_rollback_func(target[i].e_proc);
- if ((VALUE)func != Qundef) {
- (*func)(target[i].data2);
- }
+ for (j = 0; j < i; j++) {
+ func = lookup_rollback_func(target[i - j - 1].e_proc);
+ if ((VALUE)func != Qundef) {
+ (*func)(target[i - j - 1].data2);
+ }
}
}
+NORETURN(static VALUE rb_cont_call(int argc, VALUE *argv, VALUE contval));
+
/*
* call-seq:
* cont.call(args, ...)
* cont[args, ...]
*
- * Invokes the continuation. The program continues from the end of the
- * <code>callcc</code> block. If no arguments are given, the original
- * <code>callcc</code> returns <code>nil</code>. If one argument is
- * given, <code>callcc</code> returns it. Otherwise, an array
- * containing <i>args</i> is returned.
+ * Invokes the continuation. The program continues from the end of
+ * the #callcc block. If no arguments are given, the original #callcc
+ * returns +nil+. If one argument is given, #callcc returns
+ * it. Otherwise, an array containing <i>args</i> is returned.
*
* callcc {|cont| cont.call } #=> nil
* callcc {|cont| cont.call 1 } #=> 1
@@ -1121,28 +1651,27 @@ rollback_ensure_stack(VALUE self,rb_ensure_list_t *current,rb_ensure_entry_t *ta
static VALUE
rb_cont_call(int argc, VALUE *argv, VALUE contval)
{
- rb_context_t *cont;
+ rb_context_t *cont = cont_ptr(contval);
rb_thread_t *th = GET_THREAD();
- GetContPtr(contval, cont);
if (cont_thread_value(cont) != th->self) {
- rb_raise(rb_eRuntimeError, "continuation called across threads");
+ rb_raise(rb_eRuntimeError, "continuation called across threads");
}
- if (cont->saved_ec.protect_tag != th->ec.protect_tag) {
- rb_raise(rb_eRuntimeError, "continuation called across stack rewinding barrier");
+ if (cont->saved_ec.protect_tag != th->ec->protect_tag) {
+ rb_raise(rb_eRuntimeError, "continuation called across stack rewinding barrier");
}
- if (cont->saved_ec.fiber) {
- if (th->ec.fiber != cont->saved_ec.fiber) {
- rb_raise(rb_eRuntimeError, "continuation called across fiber");
- }
+ if (cont->saved_ec.fiber_ptr) {
+ if (th->ec->fiber_ptr != cont->saved_ec.fiber_ptr) {
+ rb_raise(rb_eRuntimeError, "continuation called across fiber");
+ }
}
- rollback_ensure_stack(contval, th->ec.ensure_list, cont->ensure_array);
+ rollback_ensure_stack(contval, th->ec->ensure_list, cont->ensure_array);
cont->argc = argc;
cont->value = make_passing_arg(argc, argv);
cont_restore_0(cont, &contval);
- return Qnil; /* unreachable */
+ UNREACHABLE_RETURN(Qnil);
}
/*********/
@@ -1164,10 +1693,10 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
* manpage to configure the size of the fiber stack(s).
*
* When a fiber is created it will not run automatically. Rather it must
- * be explicitly asked to run using the <code>Fiber#resume</code> method.
+ * be explicitly asked to run using the Fiber#resume method.
* The code running inside the fiber can give up control by calling
- * <code>Fiber.yield</code> in which case it yields control back to caller
- * (the caller of the <code>Fiber#resume</code>).
+ * Fiber.yield in which case it yields control back to caller (the
+ * caller of the Fiber#resume).
*
* Upon yielding or termination the Fiber returns the value of the last
* executed expression
@@ -1189,10 +1718,10 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
* 2
* FiberError: dead fiber called
*
- * The <code>Fiber#resume</code> method accepts an arbitrary number of
- * parameters, if it is the first call to <code>resume</code> then they
- * will be passed as block arguments. Otherwise they will be the return
- * value of the call to <code>Fiber.yield</code>
+ * The Fiber#resume method accepts an arbitrary number of parameters,
+ * if it is the first call to #resume then they will be passed as
+ * block arguments. Otherwise they will be the return value of the
+ * call to Fiber.yield
*
* Example:
*
@@ -1201,20 +1730,42 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
* end
*
* puts fiber.resume 10
- * puts fiber.resume 14
- * puts fiber.resume 18
+ * puts fiber.resume 1_000_000
+ * puts fiber.resume "The fiber will be dead before I can cause trouble"
*
* <em>produces</em>
*
* 12
- * 14
+ * 1000000
* FiberError: dead fiber called
*
+ * == Non-blocking Fibers
+ *
+ * Since Ruby 3.0, the concept of <em>non-blocking fiber</em> was introduced.
+ * Non-blocking fiber, when reaching any potentially blocking operation (like
+ * sleep, wait for another process, wait for I/O data to be ready), instead
+ * of just freezing itself and all execution in the thread, yields control
+ * to other fibers, and allows the <em>scheduler</em> to handle waiting and waking
+ * (resuming) the fiber when it can proceed.
+ *
+ * For Fiber to behave as non-blocking, it should be created in Fiber.new with
+ * <tt>blocking: false</tt> (which is the default now), and Fiber.scheduler
+ * should be set with Fiber.set_scheduler. If Fiber.scheduler is not set in
+ * the current thread, blocking and non-blocking fiber's behavior is identical.
+ *
+ * Ruby doesn't provide a scheduler class: it is expected to be implemented by
+ * the user and correspond to Fiber::SchedulerInterface.
+ *
+ * There is also Fiber.schedule method, which is expected to immediately perform
+ * passed block in a non-blocking manner (but its actual implementation is up to
+ * the scheduler).
+ *
+ *
*/
static const rb_data_type_t fiber_data_type = {
"fiber",
- {fiber_mark, fiber_free, fiber_memsize,},
+ {fiber_mark, fiber_free, fiber_memsize, fiber_compact,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -1225,193 +1776,405 @@ fiber_alloc(VALUE klass)
}
static rb_fiber_t*
-fiber_t_alloc(VALUE fibval)
+fiber_t_alloc(VALUE fiber_value, unsigned int blocking)
{
- rb_fiber_t *fib;
+ rb_fiber_t *fiber;
rb_thread_t *th = GET_THREAD();
- if (DATA_PTR(fibval) != 0) {
- rb_raise(rb_eRuntimeError, "cannot initialize twice");
+ if (DATA_PTR(fiber_value) != 0) {
+ rb_raise(rb_eRuntimeError, "cannot initialize twice");
}
THREAD_MUST_BE_RUNNING(th);
- fib = ZALLOC(rb_fiber_t);
- fib->cont.self = fibval;
- fib->cont.type = FIBER_CONTEXT;
- cont_init(&fib->cont, th);
- fib->cont.saved_ec.fiber = fib;
- fib->prev = NULL;
-
- /* fib->status == 0 == CREATED
- * So that we don't need to set status: fiber_status_set(fib, FIBER_CREATED); */
- VM_ASSERT(FIBER_CREATED_P(fib));
-
- DATA_PTR(fibval) = fib;
-
- return fib;
-}
-
-rb_control_frame_t *
-rb_vm_push_frame(rb_execution_context_t *sec,
- const rb_iseq_t *iseq,
- VALUE type,
- VALUE self,
- VALUE specval,
- VALUE cref_or_me,
- const VALUE *pc,
- VALUE *sp,
- int local_size,
- int stack_max);
+ fiber = ZALLOC(rb_fiber_t);
+ fiber->cont.self = fiber_value;
+ fiber->cont.type = FIBER_CONTEXT;
+ fiber->blocking = blocking;
+ cont_init(&fiber->cont, th);
+
+ fiber->cont.saved_ec.fiber_ptr = fiber;
+ rb_ec_clear_vm_stack(&fiber->cont.saved_ec);
+
+ fiber->prev = NULL;
+
+ /* fiber->status == 0 == CREATED
+ * So that we don't need to set status: fiber_status_set(fiber, FIBER_CREATED); */
+ VM_ASSERT(FIBER_CREATED_P(fiber));
+
+ DATA_PTR(fiber_value) = fiber;
+
+ return fiber;
+}
static VALUE
-fiber_init(VALUE fibval, VALUE proc)
+fiber_initialize(VALUE self, VALUE proc, struct fiber_pool * fiber_pool, unsigned int blocking)
{
- rb_fiber_t *fib = fiber_t_alloc(fibval);
- rb_context_t *cont = &fib->cont;
- rb_execution_context_t *sec = &cont->saved_ec;
- rb_thread_t *cth = GET_THREAD();
+ rb_fiber_t *fiber = fiber_t_alloc(self, blocking);
- /* initialize cont */
- cont->saved_vm_stack.ptr = NULL;
+ fiber->first_proc = proc;
+ fiber->stack.base = NULL;
+ fiber->stack.pool = fiber_pool;
- sec->vm_stack = NULL;
- sec->vm_stack_size = 0;
+ return self;
+}
- sec->vm_stack_size = cth->vm->default_params.fiber_vm_stack_size / sizeof(VALUE);
- sec->vm_stack = ALLOC_N(VALUE, sec->vm_stack_size);
- sec->cfp = (void *)(sec->vm_stack + sec->vm_stack_size);
+static void
+fiber_prepare_stack(rb_fiber_t *fiber)
+{
+ rb_context_t *cont = &fiber->cont;
+ rb_execution_context_t *sec = &cont->saved_ec;
- rb_vm_push_frame(sec,
- NULL,
- VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_CFRAME,
- Qnil, /* self */
- VM_BLOCK_HANDLER_NONE,
- 0, /* specval */
- NULL, /* pc */
- sec->vm_stack, /* sp */
- 0, /* local_size */
- 0);
+ size_t vm_stack_size = 0;
+ VALUE *vm_stack = fiber_initialize_coroutine(fiber, &vm_stack_size);
+
+ /* initialize cont */
+ cont->saved_vm_stack.ptr = NULL;
+ rb_ec_initialize_vm_stack(sec, vm_stack, vm_stack_size / sizeof(VALUE));
sec->tag = NULL;
sec->local_storage = NULL;
sec->local_storage_recursive_hash = Qnil;
sec->local_storage_recursive_hash_for_trace = Qnil;
+}
- fib->first_proc = proc;
+static struct fiber_pool *
+rb_fiber_pool_default(VALUE pool)
+{
+ return &shared_fiber_pool;
+}
-#if !FIBER_USE_NATIVE
- MEMCPY(&cont->jmpbuf, &cth->root_jmpbuf, rb_jmpbuf_t, 1);
-#endif
+/* :nodoc: */
+static VALUE
+rb_fiber_initialize_kw(int argc, VALUE* argv, VALUE self, int kw_splat)
+{
+ VALUE pool = Qnil;
+ VALUE blocking = Qfalse;
- return fibval;
+ if (kw_splat != RB_NO_KEYWORDS) {
+ VALUE options = Qnil;
+ VALUE arguments[2] = {Qundef};
+
+ argc = rb_scan_args_kw(kw_splat, argc, argv, ":", &options);
+ rb_get_kwargs(options, fiber_initialize_keywords, 0, 2, arguments);
+
+ if (arguments[0] != Qundef) {
+ blocking = arguments[0];
+ }
+
+ if (arguments[1] != Qundef) {
+ pool = arguments[1];
+ }
+ }
+
+ return fiber_initialize(self, rb_block_proc(), rb_fiber_pool_default(pool), RTEST(blocking));
}
-/* :nodoc: */
+/*
+ * call-seq:
+ * Fiber.new(blocking: false) { |*args| ... } -> fiber
+ *
+ * Creates new Fiber. Initially, fiber is not running, but can be resumed with
+ * #resume. Arguments to the first #resume call would be passed to the block:
+ *
+ * f = Fiber.new do |initial|
+ * current = initial
+ * loop do
+ * puts "current: #{current.inspect}"
+ * current = Fiber.yield
+ * end
+ * end
+ * f.resume(100) # prints: current: 100
+ * f.resume(1, 2, 3) # prints: current: [1, 2, 3]
+ * f.resume # prints: current: nil
+ * # ... and so on ...
+ *
+ * if <tt>blocking: false</tt> is passed to the <tt>Fiber.new</tt>, _and_ current thread
+ * has Fiber.scheduler defined, the Fiber becomes non-blocking (see "Non-blocking
+ * fibers" section in class docs).
+ */
static VALUE
-rb_fiber_init(VALUE fibval)
+rb_fiber_initialize(int argc, VALUE* argv, VALUE self)
{
- return fiber_init(fibval, rb_block_proc());
+ return rb_fiber_initialize_kw(argc, argv, self, rb_keyword_given_p());
}
VALUE
-rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj)
+rb_fiber_new(rb_block_call_func_t func, VALUE obj)
{
- return fiber_init(fiber_alloc(rb_cFiber), rb_proc_new(func, obj));
+ return fiber_initialize(fiber_alloc(rb_cFiber), rb_proc_new(func, obj), rb_fiber_pool_default(Qnil), 1);
}
-static void rb_fiber_terminate(rb_fiber_t *fib);
+static VALUE
+rb_f_fiber_kw(int argc, VALUE* argv, int kw_splat)
+{
+ rb_thread_t * th = GET_THREAD();
+ VALUE scheduler = th->scheduler;
+ VALUE fiber = Qnil;
+
+ if (scheduler != Qnil) {
+ fiber = rb_funcall_passing_block_kw(scheduler, rb_intern("fiber"), argc, argv, kw_splat);
+ } else {
+ rb_raise(rb_eRuntimeError, "No scheduler is available!");
+ }
+
+ return fiber;
+}
+
+/*
+ * call-seq:
+ * Fiber.schedule { |*args| ... } -> fiber
+ *
+ * The method is <em>expected</em> to immediately run the provided block of code in a
+ * separate non-blocking fiber.
+ *
+ * puts "Go to sleep!"
+ *
+ * Fiber.set_scheduler(MyScheduler.new)
+ *
+ * Fiber.schedule do
+ * puts "Going to sleep"
+ * sleep(1)
+ * puts "I slept well"
+ * end
+ *
+ * puts "Wakey-wakey, sleepyhead"
+ *
+ * Assuming MyScheduler is properly implemented, this program will produce:
+ *
+ * Go to sleep!
+ * Going to sleep
+ * Wakey-wakey, sleepyhead
+ * ...1 sec pause here...
+ * I slept well
+ *
+ * ...e.g. on the first blocking operation inside the Fiber (<tt>sleep(1)</tt>),
+ * the control is yielded at the outside code (main fiber), and <em>at the end
+ * of the execution</em>, the scheduler takes care of properly resuming all the
+ * blocked fibers.
+ *
+ * Note that the behavior described above is how the method is <em>expected</em>
+ * to behave, actual behavior is up to the current scheduler's implementation of
+ * Fiber::SchedulerInterface#fiber method. Ruby doesn't enforce this method to
+ * behave in any particular way.
+ *
+ * If the scheduler is not set, the method raises
+ * <tt>RuntimeError (No scheduler is available!)</tt>.
+ *
+ */
+static VALUE
+rb_f_fiber(int argc, VALUE *argv, VALUE obj)
+{
+ return rb_f_fiber_kw(argc, argv, rb_keyword_given_p());
+}
+
+/*
+ * call-seq:
+ * Fiber.scheduler -> obj or nil
+ *
+ * Fiber scheduler, set in the current thread with Fiber.set_scheduler. If the scheduler
+ * is +nil+ (which is the default), non-blocking fibers behavior is the same as blocking.
+ * (see "Non-blocking fibers" section in class docs for details about the scheduler concept).
+ *
+ */
+static VALUE
+rb_fiber_scheduler(VALUE klass)
+{
+ return rb_scheduler_get();
+}
+
+/*
+ * call-seq:
+ * Fiber.set_scheduler(scheduler) -> scheduler
+ *
+ * Sets Fiber scheduler for the current thread. If the scheduler is set, non-blocking
+ * fibers (created by Fiber.new with <tt>blocking: false</tt>, or by Fiber.schedule)
+ * call that scheduler's hook methods on potentially blocking operations, and the current
+ * thread will call scheduler's +close+ method on finalization (allowing the scheduler to
+ * properly manage all non-finished fibers).
+ *
+ * +scheduler+ can be an object of any class corresponding to Fiber::SchedulerInterface. Its
+ * implementation is up to the user.
+ *
+ * See also the "Non-blocking fibers" section in class docs.
+ *
+ */
+static VALUE
+rb_fiber_set_scheduler(VALUE klass, VALUE scheduler)
+{
+ // if (rb_scheduler_get() != Qnil) {
+ // rb_raise(rb_eFiberError, "Scheduler is already defined!");
+ // }
+
+ return rb_scheduler_set(scheduler);
+}
+
+NORETURN(static void rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt));
void
rb_fiber_start(void)
{
- rb_thread_t *th = GET_THREAD();
- rb_fiber_t *fib = th->ec.fiber;
+ rb_thread_t * volatile th = GET_THREAD();
+ rb_fiber_t *fiber = th->ec->fiber_ptr;
rb_proc_t *proc;
enum ruby_tag_type state;
+ int need_interrupt = TRUE;
- VM_ASSERT(FIBER_RESUMED_P(fib));
-
- TH_PUSH_TAG(th);
- if ((state = EXEC_TAG()) == TAG_NONE) {
- rb_context_t *cont = &VAR_FROM_MEMORY(fib)->cont;
- int argc;
- const VALUE *argv, args = cont->value;
- GetProcPtr(fib->first_proc, proc);
- argv = (argc = cont->argc) > 1 ? RARRAY_CONST_PTR(args) : &args;
- cont->value = Qnil;
- th->ec.errinfo = Qnil;
- th->ec.root_lep = rb_vm_proc_local_ep(fib->first_proc);
- th->ec.root_svar = Qfalse;
+ VM_ASSERT(th->ec == GET_EC());
+ VM_ASSERT(FIBER_RESUMED_P(fiber));
- EXEC_EVENT_HOOK(th, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, 0, Qnil);
- cont->value = rb_vm_invoke_proc(th, proc, argc, argv, VM_BLOCK_HANDLER_NONE);
+ if (fiber->blocking) {
+ th->blocking += 1;
}
- TH_POP_TAG();
- if (state) {
- VM_ASSERT(FIBER_RESUMED_P(fib));
+ EC_PUSH_TAG(th->ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
+ rb_context_t *cont = &VAR_FROM_MEMORY(fiber)->cont;
+ int argc;
+ const VALUE *argv, args = cont->value;
+ GetProcPtr(fiber->first_proc, proc);
+ argv = (argc = cont->argc) > 1 ? RARRAY_CONST_PTR(args) : &args;
+ cont->value = Qnil;
+ th->ec->errinfo = Qnil;
+ th->ec->root_lep = rb_vm_proc_local_ep(fiber->first_proc);
+ th->ec->root_svar = Qfalse;
- if (state == TAG_RAISE || state == TAG_FATAL) {
- rb_threadptr_pending_interrupt_enque(th, th->ec.errinfo);
- }
- else {
- VALUE err = rb_vm_make_jump_tag_but_local_jump(state, th->ec.errinfo);
- if (!NIL_P(err))
- rb_threadptr_pending_interrupt_enque(th, err);
- }
- RUBY_VM_SET_INTERRUPT(th);
+ EXEC_EVENT_HOOK(th->ec, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, 0, Qnil);
+ cont->value = rb_vm_invoke_proc(th->ec, proc, argc, argv, cont->kw_splat, VM_BLOCK_HANDLER_NONE);
}
+ EC_POP_TAG();
- rb_fiber_terminate(fib);
+ if (state) {
+ VALUE err = th->ec->errinfo;
+ VM_ASSERT(FIBER_RESUMED_P(fiber));
+
+ if (state == TAG_RAISE || state == TAG_FATAL) {
+ rb_threadptr_pending_interrupt_enque(th, err);
+ }
+ else {
+ err = rb_vm_make_jump_tag_but_local_jump(state, err);
+ if (!NIL_P(err)) {
+ rb_threadptr_pending_interrupt_enque(th, err);
+ }
+ }
+ need_interrupt = TRUE;
+ }
+
+ rb_fiber_terminate(fiber, need_interrupt);
VM_UNREACHABLE(rb_fiber_start);
}
static rb_fiber_t *
root_fiber_alloc(rb_thread_t *th)
{
- rb_fiber_t *fib;
- /* no need to allocate vm stack */
- fib = fiber_t_alloc(fiber_alloc(rb_cFiber));
- fib->cont.type = ROOT_FIBER_CONTEXT;
-#if FIBER_USE_NATIVE
-#ifdef _WIN32
- fib->fib_handle = ConvertThreadToFiber(0);
-#endif
+ VALUE fiber_value = fiber_alloc(rb_cFiber);
+ rb_fiber_t *fiber = th->ec->fiber_ptr;
+
+ VM_ASSERT(DATA_PTR(fiber_value) == NULL);
+ VM_ASSERT(fiber->cont.type == FIBER_CONTEXT);
+ VM_ASSERT(fiber->status == FIBER_RESUMED);
+
+ th->root_fiber = fiber;
+ DATA_PTR(fiber_value) = fiber;
+ fiber->cont.self = fiber_value;
+
+#ifdef COROUTINE_PRIVATE_STACK
+ fiber->stack = fiber_pool_stack_acquire(&shared_fiber_pool);
+ coroutine_initialize_main(&fiber->context, fiber_pool_stack_base(&fiber->stack), fiber->stack.available, th->ec->machine.stack_start);
+#else
+ coroutine_initialize_main(&fiber->context);
#endif
- fiber_status_set(fib, FIBER_RESUMED); /* skip CREATED */
- th->root_fiber = th->ec.fiber = fib;
- return fib;
+
+ return fiber;
+}
+
+void
+rb_threadptr_root_fiber_setup(rb_thread_t *th)
+{
+ rb_fiber_t *fiber = ruby_mimmalloc(sizeof(rb_fiber_t));
+ if (!fiber) {
+ rb_bug("%s", strerror(errno)); /* ... is it possible to call rb_bug here? */
+ }
+ MEMZERO(fiber, rb_fiber_t, 1);
+ fiber->cont.type = FIBER_CONTEXT;
+ fiber->cont.saved_ec.fiber_ptr = fiber;
+ fiber->cont.saved_ec.thread_ptr = th;
+ fiber->blocking = 1;
+ fiber_status_set(fiber, FIBER_RESUMED); /* skip CREATED */
+ th->ec = &fiber->cont.saved_ec;
+ // This skips mjit_cont_new for the initial thread because mjit_enabled is always false
+ // at this point. mjit_init calls rb_fiber_init_mjit_cont again for this root_fiber.
+ rb_fiber_init_mjit_cont(fiber);
+}
+
+void
+rb_threadptr_root_fiber_release(rb_thread_t *th)
+{
+ if (th->root_fiber) {
+ /* ignore. A root fiber object will free th->ec */
+ }
+ else {
+ rb_execution_context_t *ec = GET_EC();
+
+ VM_ASSERT(th->ec->fiber_ptr->cont.type == FIBER_CONTEXT);
+ VM_ASSERT(th->ec->fiber_ptr->cont.self == 0);
+
+ if (th->ec == ec) {
+ rb_ractor_set_current_ec(th->ractor, NULL);
+ }
+ fiber_free(th->ec->fiber_ptr);
+ th->ec = NULL;
+ }
+}
+
+void
+rb_threadptr_root_fiber_terminate(rb_thread_t *th)
+{
+ rb_fiber_t *fiber = th->ec->fiber_ptr;
+
+ fiber->status = FIBER_TERMINATED;
+
+ // The vm_stack is `alloca`ed on the thread stack, so it's gone too:
+ rb_ec_clear_vm_stack(th->ec);
}
static inline rb_fiber_t*
fiber_current(void)
{
- rb_thread_t *th = GET_THREAD();
- if (th->ec.fiber == NULL) {
- rb_fiber_t *fib = root_fiber_alloc(th);
- /* Running thread object has stack management responsibility */
- fib->cont.saved_ec.vm_stack = NULL;
+ rb_execution_context_t *ec = GET_EC();
+ if (ec->fiber_ptr->cont.self == 0) {
+ root_fiber_alloc(rb_ec_thread_ptr(ec));
}
- return th->ec.fiber;
+ return ec->fiber_ptr;
}
static inline rb_fiber_t*
-return_fiber(void)
+return_fiber(bool terminate)
{
- rb_fiber_t *fib = fiber_current();
- rb_fiber_t *prev = fib->prev;
-
- if (!prev) {
- rb_fiber_t *root_fiber = GET_THREAD()->root_fiber;
+ rb_fiber_t *fiber = fiber_current();
+ rb_fiber_t *prev = fiber->prev;
- if (root_fiber == fib) {
- rb_raise(rb_eFiberError, "can't yield from root fiber");
- }
- return root_fiber;
+ if (prev) {
+ fiber->prev = NULL;
+ prev->resuming_fiber = Qnil;
+ return prev;
}
else {
- fib->prev = NULL;
- return prev;
+ if (!terminate) {
+ rb_raise(rb_eFiberError, "attempt to yield on a not resumed fiber");
+ }
+
+ rb_thread_t *th = GET_THREAD();
+ rb_fiber_t *root_fiber = th->root_fiber;
+
+ VM_ASSERT(root_fiber != NULL);
+
+ // search resuming fiber
+ for (fiber = root_fiber;
+ RTEST(fiber->resuming_fiber);
+ fiber = fiber_ptr(fiber->resuming_fiber)) {
+ }
+
+ return fiber;
}
}
@@ -1421,200 +2184,261 @@ rb_fiber_current(void)
return fiber_current()->cont.self;
}
+// Prepare to execute next_fiber on the given thread.
static inline VALUE
-fiber_store(rb_fiber_t *next_fib, rb_thread_t *th)
+fiber_store(rb_fiber_t *next_fiber, rb_thread_t *th)
{
- rb_fiber_t *fib;
+ rb_fiber_t *fiber;
- if (th->ec.fiber != NULL) {
- fib = th->ec.fiber;
- cont_save_thread(&fib->cont, th);
+ if (th->ec->fiber_ptr != NULL) {
+ fiber = th->ec->fiber_ptr;
}
else {
- /* create root fiber */
- fib = root_fiber_alloc(th);
+ /* create root fiber */
+ fiber = root_fiber_alloc(th);
}
- VM_ASSERT(FIBER_RESUMED_P(fib) || FIBER_TERMINATED_P(fib));
- VM_ASSERT(FIBER_RUNNABLE_P(next_fib));
-
-#if FIBER_USE_NATIVE
- if (FIBER_CREATED_P(next_fib)) {
- fiber_initialize_machine_stack_context(next_fib, th->vm->default_params.fiber_machine_stack_size);
+ if (FIBER_CREATED_P(next_fiber)) {
+ fiber_prepare_stack(next_fiber);
}
-#endif
- if (FIBER_RESUMED_P(fib)) fiber_status_set(fib, FIBER_SUSPENDED);
+ VM_ASSERT(FIBER_RESUMED_P(fiber) || FIBER_TERMINATED_P(fiber));
+ VM_ASSERT(FIBER_RUNNABLE_P(next_fiber));
-#if FIBER_USE_NATIVE == 0
- /* should (re-)allocate stack are before fib->status change to pass fiber_verify() */
- cont_save_machine_stack(th, &fib->cont);
-#endif
+ if (FIBER_RESUMED_P(fiber)) fiber_status_set(fiber, FIBER_SUSPENDED);
- fiber_status_set(next_fib, FIBER_RESUMED);
+ fiber_status_set(next_fiber, FIBER_RESUMED);
+ fiber_setcontext(next_fiber, fiber);
-#if FIBER_USE_NATIVE
- fiber_setcontext(next_fib, fib);
- /* restored */
-#ifndef _WIN32
- if (terminated_machine_stack.ptr) {
- if (machine_stack_cache_index < MAX_MACHINE_STACK_CACHE) {
- machine_stack_cache[machine_stack_cache_index].ptr = terminated_machine_stack.ptr;
- machine_stack_cache[machine_stack_cache_index].size = terminated_machine_stack.size;
- machine_stack_cache_index++;
- }
- else {
- if (terminated_machine_stack.ptr != fib->cont.machine.stack) {
- munmap((void*)terminated_machine_stack.ptr, terminated_machine_stack.size * sizeof(VALUE));
- }
- else {
- rb_bug("terminated fiber resumed");
- }
- }
- terminated_machine_stack.ptr = NULL;
- terminated_machine_stack.size = 0;
- }
-#endif /* not _WIN32 */
- fib = th->ec.fiber;
- if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value);
- return fib->cont.value;
-
-#else /* FIBER_USE_NATIVE */
- if (ruby_setjmp(fib->cont.jmpbuf)) {
- /* restored */
- fib = th->ec.fiber;
- if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value);
- if (next_fib->cont.value == Qundef) {
- cont_restore_0(&next_fib->cont, &next_fib->cont.value);
- VM_UNREACHABLE(fiber_store);
- }
- return fib->cont.value;
- }
- else {
- VALUE undef = Qundef;
- cont_restore_0(&next_fib->cont, &undef);
- VM_UNREACHABLE(fiber_store);
- }
-#endif /* FIBER_USE_NATIVE */
+ fiber = th->ec->fiber_ptr;
+
+ /* Raise an exception if that was the result of executing the fiber */
+ if (fiber->cont.argc == -1) rb_exc_raise(fiber->cont.value);
+
+ return fiber->cont.value;
}
static inline VALUE
-fiber_switch(rb_fiber_t *fib, int argc, const VALUE *argv, int is_resume)
+fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, VALUE resuming_fiber, bool yielding)
{
VALUE value;
- rb_context_t *cont = &fib->cont;
+ rb_context_t *cont = &fiber->cont;
rb_thread_t *th = GET_THREAD();
- if (th->ec.fiber == fib) {
- /* ignore fiber context switch
+ /* make sure the root_fiber object is available */
+ if (th->root_fiber == NULL) root_fiber_alloc(th);
+
+ if (th->ec->fiber_ptr == fiber) {
+ /* ignore fiber context switch
* because destination fiber is same as current fiber
- */
- return make_passing_arg(argc, argv);
+ */
+ return make_passing_arg(argc, argv);
}
if (cont_thread_value(cont) != th->self) {
- rb_raise(rb_eFiberError, "fiber called across threads");
- }
- else if (cont->saved_ec.protect_tag != th->ec.protect_tag) {
- rb_raise(rb_eFiberError, "fiber called across stack rewinding barrier");
- }
- else if (FIBER_TERMINATED_P(fib)) {
- value = rb_exc_new2(rb_eFiberError, "dead fiber called");
-
- if (!FIBER_TERMINATED_P(th->ec.fiber)) {
- rb_exc_raise(value);
- VM_UNREACHABLE(fiber_switch);
- }
- else {
- /* th->ec.fiber is also dead => switch to root fiber */
- /* (this means we're being called from rb_fiber_terminate, */
- /* and the terminated fiber's return_fiber() is already dead) */
- VM_ASSERT(FIBER_SUSPENDED_P(th->root_fiber));
-
- cont = &th->root_fiber->cont;
- cont->argc = -1;
- cont->value = value;
-#if FIBER_USE_NATIVE
- fiber_setcontext(th->root_fiber, th->ec.fiber);
-#else
- cont_restore_0(cont, &value);
-#endif
- VM_UNREACHABLE(fiber_switch);
- }
+ rb_raise(rb_eFiberError, "fiber called across threads");
+ }
+ else if (cont->saved_ec.protect_tag != th->ec->protect_tag) {
+ rb_raise(rb_eFiberError, "fiber called across stack rewinding barrier");
+ }
+ else if (FIBER_TERMINATED_P(fiber)) {
+ value = rb_exc_new2(rb_eFiberError, "dead fiber called");
+
+ if (!FIBER_TERMINATED_P(th->ec->fiber_ptr)) {
+ rb_exc_raise(value);
+ VM_UNREACHABLE(fiber_switch);
+ }
+ else {
+ /* th->ec->fiber_ptr is also dead => switch to root fiber */
+ /* (this means we're being called from rb_fiber_terminate, */
+ /* and the terminated fiber's return_fiber() is already dead) */
+ VM_ASSERT(FIBER_SUSPENDED_P(th->root_fiber));
+
+ cont = &th->root_fiber->cont;
+ cont->argc = -1;
+ cont->value = value;
+
+ fiber_setcontext(th->root_fiber, th->ec->fiber_ptr);
+
+ VM_UNREACHABLE(fiber_switch);
+ }
}
- if (is_resume) {
- fib->prev = fiber_current();
+ VM_ASSERT(FIBER_RUNNABLE_P(fiber));
+
+ rb_fiber_t *current_fiber = fiber_current();
+
+ VM_ASSERT(!RTEST(current_fiber->resuming_fiber));
+ if (RTEST(resuming_fiber)) {
+ current_fiber->resuming_fiber = resuming_fiber;
+ fiber->prev = fiber_current();
+ fiber->yielding = 0;
}
- VM_ASSERT(FIBER_RUNNABLE_P(fib));
+ VM_ASSERT(!current_fiber->yielding);
+ if (yielding) {
+ current_fiber->yielding = 1;
+ }
+
+ if (current_fiber->blocking) {
+ th->blocking -= 1;
+ }
cont->argc = argc;
+ cont->kw_splat = kw_splat;
cont->value = make_passing_arg(argc, argv);
- value = fiber_store(fib, th);
- RUBY_VM_CHECK_INTS(th);
- EXEC_EVENT_HOOK(th, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, 0, Qnil);
+ value = fiber_store(fiber, th);
+
+ if (RTEST(resuming_fiber) && FIBER_TERMINATED_P(fiber)) {
+ fiber_stack_release(fiber);
+ }
+
+ if (fiber_current()->blocking) {
+ th->blocking += 1;
+ }
+
+ RUBY_VM_CHECK_INTS(th->ec);
+
+ EXEC_EVENT_HOOK(th->ec, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, 0, Qnil);
return value;
}
VALUE
-rb_fiber_transfer(VALUE fibval, int argc, const VALUE *argv)
+rb_fiber_transfer(VALUE fiber_value, int argc, const VALUE *argv)
+{
+ return fiber_switch(fiber_ptr(fiber_value), argc, argv, RB_NO_KEYWORDS, Qfalse, false);
+}
+
+/*
+ * call-seq:
+ * fiber.blocking? -> true or false
+ *
+ * Returns +true+ if +fiber+ is blocking and +false+ otherwise.
+ * Fiber is non-blocking if it was created via passing <tt>blocking: false</tt>
+ * to Fiber.new, or via Fiber.schedule.
+ *
+ * Note, that even if the method returns +false+, Fiber behaves differently
+ * only if Fiber.scheduler is set in the current thread.
+ *
+ * See the "Non-blocking fibers" section in class docs for details.
+ *
+ */
+VALUE
+rb_fiber_blocking_p(VALUE fiber)
{
- rb_fiber_t *fib;
- GetFiberPtr(fibval, fib);
- return fiber_switch(fib, argc, argv, 0);
+ return (fiber_ptr(fiber)->blocking == 0) ? Qfalse : Qtrue;
+}
+
+/*
+ * call-seq:
+ * Fiber.blocking? -> false or number
+ *
+ * Returns +false+ if the current fiber is non-blocking.
+ * Fiber is non-blocking if it was created via passing <tt>blocking: false</tt>
+ * to Fiber.new, or via Fiber.schedule.
+ *
+ * If the current Fiber is blocking, the method, unlike usual
+ * predicate methods, returns a *number* of blocking fibers currently
+ * running (TBD: always 1?).
+ *
+ * Note, that even if the method returns +false+, Fiber behaves differently
+ * only if Fiber.scheduler is set in the current thread.
+ *
+ * See the "Non-blocking fibers" section in class docs for details.
+ *
+ */
+static VALUE
+rb_f_fiber_blocking_p(VALUE klass)
+{
+ rb_thread_t *thread = GET_THREAD();
+ unsigned blocking = thread->blocking;
+
+ if (blocking == 0)
+ return Qfalse;
+
+ return INT2NUM(blocking);
+}
+
+void
+rb_fiber_close(rb_fiber_t *fiber)
+{
+ fiber_status_set(fiber, FIBER_TERMINATED);
}
static void
-rb_fiber_terminate(rb_fiber_t *fib)
-{
- VALUE value = fib->cont.value;
- VM_ASSERT(FIBER_RESUMED_P(fib));
-
- fiber_status_set(fib, FIBER_TERMINATED);
-#if FIBER_USE_NATIVE && !defined(_WIN32)
- /* Ruby must not switch to other thread until storing terminated_machine_stack */
- terminated_machine_stack.ptr = fib->ss_sp;
- terminated_machine_stack.size = fib->ss_size / sizeof(VALUE);
- fib->ss_sp = NULL;
- fib->context.uc_stack.ss_sp = NULL;
- fib->cont.machine.stack = NULL;
- fib->cont.machine.stack_size = 0;
-#endif
- fiber_switch(return_fiber(), 1, &value, 0);
+rb_fiber_terminate(rb_fiber_t *fiber, int need_interrupt)
+{
+ VALUE value = fiber->cont.value;
+ rb_fiber_t *next_fiber;
+
+ VM_ASSERT(FIBER_RESUMED_P(fiber));
+ rb_fiber_close(fiber);
+
+ coroutine_destroy(&fiber->context);
+
+ fiber->cont.machine.stack = NULL;
+ fiber->cont.machine.stack_size = 0;
+
+ next_fiber = return_fiber(true);
+ if (need_interrupt) RUBY_VM_SET_INTERRUPT(&next_fiber->cont.saved_ec);
+ fiber_switch(next_fiber, 1, &value, RB_NO_KEYWORDS, Qfalse, false);
+ ruby_stop(0);
}
VALUE
-rb_fiber_resume(VALUE fibval, int argc, const VALUE *argv)
+rb_fiber_resume_kw(VALUE fiber_value, int argc, const VALUE *argv, int kw_splat)
{
- rb_fiber_t *fib;
- GetFiberPtr(fibval, fib);
+ rb_fiber_t *fiber = fiber_ptr(fiber_value);
+ rb_fiber_t *current_fiber = fiber_current();
- if (fib->prev != 0 || fib->cont.type == ROOT_FIBER_CONTEXT) {
- rb_raise(rb_eFiberError, "double resume");
+ if (argc == -1 && FIBER_CREATED_P(fiber)) {
+ rb_raise(rb_eFiberError, "cannot raise exception on unborn fiber");
+ }
+ else if (FIBER_TERMINATED_P(fiber)) {
+ rb_raise(rb_eFiberError, "attempt to resume a terminated fiber");
+ }
+ else if (fiber == current_fiber) {
+ rb_raise(rb_eFiberError, "attempt to resume the current fiber");
+ }
+ else if (fiber->prev != NULL) {
+ rb_raise(rb_eFiberError, "attempt to resume a resumed fiber (double resume)");
+ }
+ else if (RTEST(fiber->resuming_fiber)) {
+ rb_raise(rb_eFiberError, "attempt to resume a resuming fiber");
}
- if (fib->transferred != 0) {
- rb_raise(rb_eFiberError, "cannot resume transferred Fiber");
+ else if (fiber->prev == NULL &&
+ (!fiber->yielding && fiber->status != FIBER_CREATED)) {
+ rb_raise(rb_eFiberError, "attempt to resume a transferring fiber");
}
- return fiber_switch(fib, argc, argv, 1);
+ return fiber_switch(fiber, argc, argv, kw_splat, fiber_value, false);
+}
+
+VALUE
+rb_fiber_resume(VALUE fiber_value, int argc, const VALUE *argv)
+{
+ return rb_fiber_resume_kw(fiber_value, argc, argv, RB_NO_KEYWORDS);
+}
+
+VALUE
+rb_fiber_yield_kw(int argc, const VALUE *argv, int kw_splat)
+{
+ return fiber_switch(return_fiber(false), argc, argv, kw_splat, Qfalse, true);
}
VALUE
rb_fiber_yield(int argc, const VALUE *argv)
{
- return fiber_switch(return_fiber(), argc, argv, 0);
+ return fiber_switch(return_fiber(false), argc, argv, RB_NO_KEYWORDS, Qfalse, true);
}
void
-rb_fiber_reset_root_local_storage(VALUE thval)
+rb_fiber_reset_root_local_storage(rb_thread_t *th)
{
- rb_thread_t *th = rb_thread_ptr(thval);
-
- if (th->root_fiber && th->root_fiber != th->ec.fiber) {
- th->ec.local_storage = th->root_fiber->cont.saved_ec.local_storage;
+ if (th->root_fiber && th->root_fiber != th->ec->fiber_ptr) {
+ th->ec->local_storage = th->root_fiber->cont.saved_ec.local_storage;
}
}
@@ -1628,32 +2452,146 @@ rb_fiber_reset_root_local_storage(VALUE thval)
* before using this method.
*/
VALUE
-rb_fiber_alive_p(VALUE fibval)
+rb_fiber_alive_p(VALUE fiber_value)
{
- const rb_fiber_t *fib;
- GetFiberPtr(fibval, fib);
- return FIBER_TERMINATED_P(fib) ? Qfalse : Qtrue;
+ return FIBER_TERMINATED_P(fiber_ptr(fiber_value)) ? Qfalse : Qtrue;
}
/*
* call-seq:
* fiber.resume(args, ...) -> obj
*
- * Resumes the fiber from the point at which the last <code>Fiber.yield</code>
- * was called, or starts running it if it is the first call to
- * <code>resume</code>. Arguments passed to resume will be the value of
- * the <code>Fiber.yield</code> expression or will be passed as block
- * parameters to the fiber's block if this is the first <code>resume</code>.
+ * Resumes the fiber from the point at which the last Fiber.yield was
+ * called, or starts running it if it is the first call to
+ * #resume. Arguments passed to resume will be the value of the
+ * Fiber.yield expression or will be passed as block parameters to
+ * the fiber's block if this is the first #resume.
*
* Alternatively, when resume is called it evaluates to the arguments passed
- * to the next <code>Fiber.yield</code> statement inside the fiber's block
+ * to the next Fiber.yield statement inside the fiber's block
* or to the block value if it runs to completion without any
- * <code>Fiber.yield</code>
+ * Fiber.yield
*/
static VALUE
-rb_fiber_m_resume(int argc, VALUE *argv, VALUE fib)
+rb_fiber_m_resume(int argc, VALUE *argv, VALUE fiber)
{
- return rb_fiber_resume(fib, argc, argv);
+ return rb_fiber_resume_kw(fiber, argc, argv, rb_keyword_given_p());
+}
+
+static VALUE rb_fiber_transfer_kw(VALUE fiber_value, int argc, VALUE *argv, int kw_splat);
+
+/*
+ * call-seq:
+ * fiber.raise -> obj
+ * fiber.raise(string) -> obj
+ * fiber.raise(exception [, string [, array]]) -> obj
+ *
+ * Raises an exception in the fiber at the point at which the last
+ * +Fiber.yield+ was called. If the fiber has not been started or has
+ * already run to completion, raises +FiberError+. If the fiber is
+ * yielding, it is resumed. If it is transferring, it is transferred into.
+ * But if it is resuming, raises +FiberError+.
+ *
+ * With no arguments, raises a +RuntimeError+. With a single +String+
+ * argument, raises a +RuntimeError+ with the string as a message. Otherwise,
+ * the first parameter should be the name of an +Exception+ class (or an
+ * object that returns an +Exception+ object when sent an +exception+
+ * message). The optional second parameter sets the message associated with
+ * the exception, and the third parameter is an array of callback information.
+ * Exceptions are caught by the +rescue+ clause of <code>begin...end</code>
+ * blocks.
+ */
+static VALUE
+rb_fiber_raise(int argc, VALUE *argv, VALUE fiber_value)
+{
+ rb_fiber_t *fiber = fiber_ptr(fiber_value);
+ VALUE exc = rb_make_exception(argc, argv);
+ if (RTEST(fiber->resuming_fiber)) {
+ rb_raise(rb_eFiberError, "attempt to raise a resuming fiber");
+ }
+ else if (FIBER_SUSPENDED_P(fiber) && !fiber->yielding) {
+ return rb_fiber_transfer_kw(fiber_value, -1, &exc, RB_NO_KEYWORDS);
+ }
+ else {
+ return rb_fiber_resume_kw(fiber_value, -1, &exc, RB_NO_KEYWORDS);
+ }
+}
+
+/*
+ * call-seq:
+ * fiber.backtrace -> array
+ * fiber.backtrace(start) -> array
+ * fiber.backtrace(start, count) -> array
+ * fiber.backtrace(start..end) -> array
+ *
+ * Returns the current execution stack of the fiber. +start+, +count+ and +end+ allow
+ * to select only parts of the backtrace.
+ *
+ * def level3
+ * Fiber.yield
+ * end
+ *
+ * def level2
+ * level3
+ * end
+ *
+ * def level1
+ * level2
+ * end
+ *
+ * f = Fiber.new { level1 }
+ *
+ * # It is empty before the fiber started
+ * f.backtrace
+ * #=> []
+ *
+ * f.resume
+ *
+ * f.backtrace
+ * #=> ["test.rb:2:in `yield'", "test.rb:2:in `level3'", "test.rb:6:in `level2'", "test.rb:10:in `level1'", "test.rb:13:in `block in <main>'"]
+ * p f.backtrace(1) # start from the item 1
+ * #=> ["test.rb:2:in `level3'", "test.rb:6:in `level2'", "test.rb:10:in `level1'", "test.rb:13:in `block in <main>'"]
+ * p f.backtrace(2, 2) # start from item 2, take 2
+ * #=> ["test.rb:6:in `level2'", "test.rb:10:in `level1'"]
+ * p f.backtrace(1..3) # take items from 1 to 3
+ * #=> ["test.rb:2:in `level3'", "test.rb:6:in `level2'", "test.rb:10:in `level1'"]
+ *
+ * f.resume
+ *
+ * # It is nil after the fiber is finished
+ * f.backtrace
+ * #=> nil
+ *
+ */
+static VALUE
+rb_fiber_backtrace(int argc, VALUE *argv, VALUE fiber)
+{
+ return rb_vm_backtrace(argc, argv, &fiber_ptr(fiber)->cont.saved_ec);
+}
+
+/*
+ * call-seq:
+ * fiber.backtrace_locations -> array
+ * fiber.backtrace_locations(start) -> array
+ * fiber.backtrace_locations(start, count) -> array
+ * fiber.backtrace_locations(start..end) -> array
+ *
+ * Like #backtrace, but returns each line of the execution stack as a
+ * Thread::Backtrace::Location. Accepts the same arguments as #backtrace.
+ *
+ * f = Fiber.new { Fiber.yield }
+ * f.resume
+ * loc = f.backtrace_locations.first
+ * loc.label #=> "yield"
+ * loc.path #=> "test.rb"
+ * loc.lineno #=> 1
+ *
+ *
+ */
+static VALUE
+rb_fiber_backtrace_locations(int argc, VALUE *argv, VALUE fiber)
+{
+ return rb_vm_backtrace_locations(argc, argv, &fiber_ptr(fiber)->cont.saved_ec);
}
/*
@@ -1663,51 +2601,101 @@ rb_fiber_m_resume(int argc, VALUE *argv, VALUE fib)
* Transfer control to another fiber, resuming it from where it last
* stopped or starting it if it was not resumed before. The calling
* fiber will be suspended much like in a call to
- * <code>Fiber.yield</code>. You need to <code>require 'fiber'</code>
+ * Fiber.yield. You need to <code>require 'fiber'</code>
* before using this method.
*
* The fiber which receives the transfer call is treats it much like
* a resume call. Arguments passed to transfer are treated like those
* passed to resume.
*
- * You cannot resume a fiber that transferred control to another one.
- * This will cause a double resume error. You need to transfer control
- * back to this fiber before it can yield and resume.
+ * The two style of control passing to and from fiber (one is #resume and
+ * Fiber::yield, another is #transfer to and from fiber) can't be freely
+ * mixed.
+ *
+ * * If the Fiber's lifecycle had started with transfer, it will never
+ * be able to yield or be resumed control passing, only
+ * finish or transfer back. (It still can resume other fibers that
+ * are allowed to be resumed.)
+ * * If the Fiber's lifecycle had started with resume, it can yield
+ * or transfer to another Fiber, but can receive control back only
+ * the way compatible with the way it was given away: if it had
+ * transferred, it only can be transferred back, and if it had
+ * yielded, it only can be resumed back. After that, it again can
+ * transfer or yield.
+ *
+ * If those rules are broken FiberError is raised.
+ *
+ * For an individual Fiber design, yield/resume is more easy to use
+ * style (the Fiber just gives away control, it doesn't need to think
+ * about who the control is given to), while transfer is more flexible
+ * for complex cases, allowing to build arbitrary graphs of Fibers
+ * dependent on each other.
+ *
*
* Example:
*
- * fiber1 = Fiber.new do
- * puts "In Fiber 1"
- * Fiber.yield
- * end
+ * require 'fiber'
*
- * fiber2 = Fiber.new do
- * puts "In Fiber 2"
- * fiber1.transfer
- * puts "Never see this message"
- * end
+ * manager = nil # For local var to be visible inside worker block
*
- * fiber3 = Fiber.new do
- * puts "In Fiber 3"
- * end
+ * # This fiber would be started with transfer
+ * # It can't yield, and can't be resumed
+ * worker = Fiber.new { |work|
+ * puts "Worker: starts"
+ * puts "Worker: Performed #{work.inspect}, transferring back"
+ * # Fiber.yield # this would raise FiberError: attempt to yield on a not resumed fiber
+ * # manager.resume # this would raise FiberError: attempt to resume a resumed fiber (double resume)
+ * manager.transfer(work.capitalize)
+ * }
+ *
+ * # This fiber would be started with resume
+ * # It can yield or transfer, and can be transferred
+ * # back or resumed
+ * manager = Fiber.new {
+ * puts "Manager: starts"
+ * puts "Manager: transferring 'something' to worker"
+ * result = worker.transfer('something')
+ * puts "Manager: worker returned #{result.inspect}"
+ * # worker.resume # this would raise FiberError: attempt to resume a transferring fiber
+ * Fiber.yield # this is OK, the fiber transferred from and to, now it can yield
+ * puts "Manager: finished"
+ * }
*
- * fiber2.resume
- * fiber3.resume
+ * puts "Starting the manager"
+ * manager.resume
+ * puts "Resuming the manager"
+ * # manager.transfer # this would raise FiberError: attempt to transfer to a yielding fiber
+ * manager.resume
*
* <em>produces</em>
*
- * In fiber 2
- * In fiber 1
- * In fiber 3
+ * Starting the manager
+ * Manager: starts
+ * Manager: transferring 'something' to worker
+ * Worker: starts
+ * Worker: Performed "something", transferring back
+ * Manager: worker returned "Something"
+ * Resuming the manager
+ * Manager: finished
*
*/
static VALUE
-rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fibval)
+rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fiber_value)
{
- rb_fiber_t *fib;
- GetFiberPtr(fibval, fib);
- fib->transferred = 1;
- return fiber_switch(fib, argc, argv, 0);
+ return rb_fiber_transfer_kw(fiber_value, argc, argv, rb_keyword_given_p());
+}
+
+static VALUE
+rb_fiber_transfer_kw(VALUE fiber_value, int argc, VALUE *argv, int kw_splat)
+{
+ rb_fiber_t *fiber = fiber_ptr(fiber_value);
+ if (RTEST(fiber->resuming_fiber)) {
+ rb_raise(rb_eFiberError, "attempt to transfer to a resuming fiber");
+ }
+ if (fiber->yielding) {
+ rb_raise(rb_eFiberError, "attempt to transfer to a yielding fiber");
+ }
+ return fiber_switch(fiber, argc, argv, kw_splat, Qfalse, false);
}
/*
@@ -1716,14 +2704,14 @@ rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fibval)
*
* Yields control back to the context that resumed the fiber, passing
* along any arguments that were passed to it. The fiber will resume
- * processing at this point when <code>resume</code> is called next.
- * Any arguments passed to the next <code>resume</code> will be the
- * value that this <code>Fiber.yield</code> expression evaluates to.
+ * processing at this point when #resume is called next.
+ * Any arguments passed to the next #resume will be the value that
+ * this Fiber.yield expression evaluates to.
*/
static VALUE
rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass)
{
- return rb_fiber_yield(argc, argv);
+ return rb_fiber_yield_kw(argc, argv, rb_keyword_given_p());
}
/*
@@ -1749,24 +2737,110 @@ rb_fiber_s_current(VALUE klass)
*/
static VALUE
-fiber_to_s(VALUE fibval)
+fiber_to_s(VALUE fiber_value)
{
- const rb_fiber_t *fib;
+ const rb_fiber_t *fiber = fiber_ptr(fiber_value);
const rb_proc_t *proc;
- char status_info[0x10];
+ char status_info[0x20];
+
+ if (RTEST(fiber->resuming_fiber)) {
+ snprintf(status_info, 0x20, " (%s by resuming)", fiber_status_name(fiber->status));
+ }
+ else {
+ snprintf(status_info, 0x20, " (%s)", fiber_status_name(fiber->status));
+ }
+
+ if (!rb_obj_is_proc(fiber->first_proc)) {
+ VALUE str = rb_any_to_s(fiber_value);
+ strlcat(status_info, ">", sizeof(status_info));
+ rb_str_set_len(str, RSTRING_LEN(str)-1);
+ rb_str_cat_cstr(str, status_info);
+ return str;
+ }
+ GetProcPtr(fiber->first_proc, proc);
+ return rb_block_to_s(fiber_value, &proc->block, status_info);
+}
+
+#ifdef HAVE_WORKING_FORK
+void
+rb_fiber_atfork(rb_thread_t *th)
+{
+ if (th->root_fiber) {
+ if (&th->root_fiber->cont.saved_ec != th->ec) {
+ th->root_fiber = th->ec->fiber_ptr;
+ }
+ th->root_fiber->prev = 0;
+ }
+}
+#endif
+
+#ifdef RB_EXPERIMENTAL_FIBER_POOL
+static void
+fiber_pool_free(void *ptr)
+{
+ struct fiber_pool * fiber_pool = ptr;
+ RUBY_FREE_ENTER("fiber_pool");
+
+ fiber_pool_free_allocations(fiber_pool->allocations);
+ ruby_xfree(fiber_pool);
+
+ RUBY_FREE_LEAVE("fiber_pool");
+}
+
+static size_t
+fiber_pool_memsize(const void *ptr)
+{
+ const struct fiber_pool * fiber_pool = ptr;
+ size_t size = sizeof(*fiber_pool);
+
+ size += fiber_pool->count * fiber_pool->size;
+
+ return size;
+}
+
+static const rb_data_type_t FiberPoolDataType = {
+ "fiber_pool",
+ {NULL, fiber_pool_free, fiber_pool_memsize,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static VALUE
+fiber_pool_alloc(VALUE klass)
+{
+ struct fiber_pool * fiber_pool = RB_ALLOC(struct fiber_pool);
+
+ return TypedData_Wrap_Struct(klass, &FiberPoolDataType, fiber_pool);
+}
+
+static VALUE
+rb_fiber_pool_initialize(int argc, VALUE* argv, VALUE self)
+{
+ rb_thread_t *th = GET_THREAD();
+ VALUE size = Qnil, count = Qnil, vm_stack_size = Qnil;
+ struct fiber_pool * fiber_pool = NULL;
- GetFiberPtr(fibval, fib);
- snprintf(status_info, 0x10, " (%s)", fiber_status_name(fib->status));
- if (!rb_obj_is_proc(fib->first_proc)) {
- VALUE str = rb_any_to_s(fibval);
- strlcat(status_info, ">", sizeof(status_info));
- rb_str_set_len(str, RSTRING_LEN(str)-1);
- rb_str_cat_cstr(str, status_info);
- return str;
+ // Maybe these should be keyword arguments.
+ rb_scan_args(argc, argv, "03", &size, &count, &vm_stack_size);
+
+ if (NIL_P(size)) {
+ size = INT2NUM(th->vm->default_params.fiber_machine_stack_size);
+ }
+
+ if (NIL_P(count)) {
+ count = INT2NUM(128);
}
- GetProcPtr(fib->first_proc, proc);
- return rb_block_to_s(fibval, &proc->block, status_info);
+
+ if (NIL_P(vm_stack_size)) {
+ vm_stack_size = INT2NUM(th->vm->default_params.fiber_vm_stack_size);
+ }
+
+ TypedData_Get_Struct(self, struct fiber_pool, &FiberPoolDataType, fiber_pool);
+
+ fiber_pool_initialize(fiber_pool, NUM2SIZET(size), NUM2SIZET(count), NUM2SIZET(vm_stack_size));
+
+ return self;
}
+#endif
/*
* Document-class: FiberError
@@ -1781,11 +2855,198 @@ fiber_to_s(VALUE fibval)
* fiber.resume #=> FiberError: dead fiber called
*/
+/*
+ * Document-class: Fiber::SchedulerInterface
+ *
+ * This is not an existing class, but documentation of the interface that Scheduler
+ * object should comply in order to be used as Fiber.scheduler and handle non-blocking
+ * fibers. See also the "Non-blocking fibers" section in Fiber class docs for explanations
+ * of some concepts.
+ *
+ * Scheduler's behavior and usage are expected to be as follows:
+ *
+ * * When the execution in the non-blocking Fiber reaches some blocking operation (like
+ * sleep, wait for a process, or a non-ready I/O), it calls some of the scheduler's
+ * hook methods, listed below.
+ * * Scheduler somehow registers what the current fiber is waited for, and yields control
+ * to other fibers with Fiber.yield (so the fiber would be suspended while expecting its
+ * wait to end, and other fibers in the same thread can perform)
+ * * At the end of the current thread execution, the scheduler's method #close is called
+ * * The scheduler runs into a wait loop, checking all the blocked fibers (which it has
+ * registered on hook calls) and resuming them when the awaited resource is ready (I/O
+ * ready, sleep time passed).
+ *
+ * A typical implementation would probably rely for this closing loop on a gem like
+ * EventMachine[https://github.com/eventmachine/eventmachine] or
+ * Async[https://github.com/socketry/async].
+ *
+ * This way concurrent execution will be achieved in a way that is transparent for every
+ * individual Fiber's code.
+ *
+ * Hook methods are:
+ *
+ * * #io_wait
+ * * #process_wait
+ * * #kernel_sleep
+ * * #block and #unblock
+ * * (the list is expanded as Ruby developers make more methods having non-blocking calls)
+ *
+ * When not specified otherwise, the hook implementations are mandatory: if they are not
+ * implemented, the methods trying to call hook will fail. To provide backward compatibility,
+ * in the future hooks will be optional (if they are not implemented, due to the scheduler
+ * being created for the older Ruby version, the code which needs this hook will not fail,
+ * and will just behave in a blocking fashion).
+ *
+ * It is also strongly suggested that the scheduler implement the #fiber method, which is
+ * delegated to by Fiber.schedule.
+ *
+ * Sample _toy_ implementation of the scheduler can be found in Ruby's code, in
+ * <tt>test/fiber/scheduler.rb</tt>
+ *
+ */
+
+#if 0 /* for RDoc */
+/*
+ *
+ * Document-method: Fiber::SchedulerInterface#close
+ *
+ * Called when the current thread exits. The scheduler is expected to implement this
+ * method in order to allow all waiting fibers to finalize their execution.
+ *
+ * The suggested pattern is to implement the main event loop in the #close method.
+ *
+ */
+static VALUE
+rb_fiber_scheduler_interface_close(VALUE self)
+{
+}
+
+/*
+ * Document-method: SchedulerInterface#process_wait
+ * call-seq: process_wait(pid, flags)
+ *
+ * Invoked by Process::Status.wait in order to wait for a specified process.
+ * See that method description for arguments description.
+ *
+ * Suggested minimal implementation:
+ *
+ * Thread.new do
+ * Process::Status.wait(pid, flags)
+ * end.value
+ *
+ * This hook is optional: if it is not present in the current scheduler,
+ * Process::Status.wait will behave as a blocking method.
+ *
+ * Expected to returns a Process::Status instance.
+ */
+static VALUE
+rb_fiber_scheduler_interface_process_wait(VALUE self)
+{
+}
+
+/*
+ * Document-method: SchedulerInterface#io_wait
+ * call-seq: io_wait(io, events, timeout)
+ *
+ * Invoked by IO#wait, IO#wait_readable, IO#wait_writable to ask whether the
+ * specified descriptor is ready for specified events within
+ * the specified +timeout+.
+ *
+ * +events+ is a bit mask of <tt>IO::READABLE</tt>, <tt>IO::WRITABLE</tt>, and
+ * <tt>IO::PRIORITY</tt>.
+ *
+ * Suggested implementation should register which Fiber is waiting for which
+ * resources and immediately calling Fiber.yield to pass control to other
+ * fibers. Then, in the #close method, the scheduler might dispatch all the
+ * I/O resources to fibers waiting for it.
+ *
+ * Expected to return the subset of events that are ready immediately.
+ *
+ */
+static VALUE
+rb_fiber_scheduler_interface_io_wait(VALUE self)
+{
+}
+
+/*
+ * Document-method: SchedulerInterface#kernel_sleep
+ * call-seq: kernel_sleep(duration = nil)
+ *
+ * Invoked by Kernel#sleep and Mutex#sleep and is expected to provide
+ * an implementation of sleeping in a non-blocking way. Implementation might
+ * register the current fiber in some list of "what fiber waits till what
+ * moment", call Fiber.yield to pass control, and then in #close resume
+ * the fibers whose wait period have ended.
+ *
+ */
+static VALUE
+rb_fiber_scheduler_interface_kernel_sleep(VALUE self)
+{
+}
+
+/*
+ * Document-method: SchedulerInterface#block
+ * call-seq: block(blocker, timeout = nil)
+ *
+ * Invoked by methods like Thread.join, and by Mutex, to signify that current
+ * Fiber is blocked till further notice (e.g. #unblock) or till +timeout+ will
+ * pass.
+ *
+ * +blocker+ is what we are waiting on, informational only (for debugging and
+ * logging). There are no guarantees about its value.
+ *
+ * Expected to return boolean, specifying whether the blocking operation was
+ * successful or not.
+ */
+static VALUE
+rb_fiber_scheduler_interface_block(VALUE self)
+{
+}
+
+/*
+ * Document-method: SchedulerInterface#unblock
+ * call-seq: unblock(blocker, fiber)
+ *
+ * Invoked to wake up Fiber previously blocked with #block (for example, Mutex#lock
+ * calls #block and Mutex#unlock calls #unblock). The scheduler should use
+ * the +fiber+ parameter to understand which fiber is unblocked.
+ *
+ * +blocker+ is what was awaited for, but it is informational only (for debugging
+ * and logging), and it is not guaranteed to be the same value as the +blocker+ for
+ * #block.
+ *
+ */
+static VALUE
+rb_fiber_scheduler_interface_unblock(VALUE self)
+{
+}
+
+/*
+ * Document-method: SchedulerInterface#fiber
+ * call-seq: fiber(&block)
+ *
+ * Implementation of the Fiber.schedule. The method is <em>expected</em> to immediately
+ * run passed block of code in a separate non-blocking fiber, and to return that Fiber.
+ *
+ * Minimal suggested implementation is:
+ *
+ * def fiber(&block)
+ * Fiber.new(blocking: false, &block).tap(&:resume)
+ * end
+ */
+static VALUE
+rb_fiber_scheduler_interface_fiber(VALUE self)
+{
+}
+#endif
+
void
Init_Cont(void)
{
-#if FIBER_USE_NATIVE
rb_thread_t *th = GET_THREAD();
+ size_t vm_stack_size = th->vm->default_params.fiber_vm_stack_size;
+ size_t machine_stack_size = th->vm->default_params.fiber_machine_stack_size;
+ size_t stack_size = machine_stack_size + vm_stack_size;
#ifdef _WIN32
SYSTEM_INFO info;
@@ -1794,17 +3055,54 @@ Init_Cont(void)
#else /* not WIN32 */
pagesize = sysconf(_SC_PAGESIZE);
#endif
- SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
-#endif
+ SET_MACHINE_STACK_END(&th->ec->machine.stack_end);
+
+ fiber_pool_initialize(&shared_fiber_pool, stack_size, FIBER_POOL_INITIAL_SIZE, vm_stack_size);
+
+ fiber_initialize_keywords[0] = rb_intern_const("blocking");
+ fiber_initialize_keywords[1] = rb_intern_const("pool");
+
+ char * fiber_shared_fiber_pool_free_stacks = getenv("RUBY_SHARED_FIBER_POOL_FREE_STACKS");
+ if (fiber_shared_fiber_pool_free_stacks) {
+ shared_fiber_pool.free_stacks = atoi(fiber_shared_fiber_pool_free_stacks);
+ }
rb_cFiber = rb_define_class("Fiber", rb_cObject);
rb_define_alloc_func(rb_cFiber, fiber_alloc);
rb_eFiberError = rb_define_class("FiberError", rb_eStandardError);
rb_define_singleton_method(rb_cFiber, "yield", rb_fiber_s_yield, -1);
- rb_define_method(rb_cFiber, "initialize", rb_fiber_init, 0);
+ rb_define_method(rb_cFiber, "initialize", rb_fiber_initialize, -1);
+ rb_define_method(rb_cFiber, "blocking?", rb_fiber_blocking_p, 0);
rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1);
+ rb_define_method(rb_cFiber, "raise", rb_fiber_raise, -1);
+ rb_define_method(rb_cFiber, "backtrace", rb_fiber_backtrace, -1);
+ rb_define_method(rb_cFiber, "backtrace_locations", rb_fiber_backtrace_locations, -1);
rb_define_method(rb_cFiber, "to_s", fiber_to_s, 0);
rb_define_alias(rb_cFiber, "inspect", "to_s");
+
+ rb_define_singleton_method(rb_cFiber, "blocking?", rb_f_fiber_blocking_p, 0);
+ rb_define_singleton_method(rb_cFiber, "scheduler", rb_fiber_scheduler, 0);
+ rb_define_singleton_method(rb_cFiber, "set_scheduler", rb_fiber_set_scheduler, 1);
+
+ rb_define_singleton_method(rb_cFiber, "schedule", rb_f_fiber, -1);
+ //rb_define_global_function("Fiber", rb_f_fiber, -1);
+
+#if 0 /* for RDoc */
+ rb_cFiberScheduler = rb_define_class_under(rb_cFiber, "SchedulerInterface", rb_cObject);
+ rb_define_method(rb_cFiberScheduler, "close", rb_fiber_scheduler_interface_close, 0);
+ rb_define_method(rb_cFiberScheduler, "process_wait", rb_fiber_scheduler_interface_process_wait, 0);
+ rb_define_method(rb_cFiberScheduler, "io_wait", rb_fiber_scheduler_interface_io_wait, 0);
+ rb_define_method(rb_cFiberScheduler, "kernel_sleep", rb_fiber_scheduler_interface_kernel_sleep, 0);
+ rb_define_method(rb_cFiberScheduler, "block", rb_fiber_scheduler_interface_block, 0);
+ rb_define_method(rb_cFiberScheduler, "unblock", rb_fiber_scheduler_interface_unblock, 0);
+ rb_define_method(rb_cFiberScheduler, "fiber", rb_fiber_scheduler_interface_fiber, 0);
+#endif
+
+#ifdef RB_EXPERIMENTAL_FIBER_POOL
+ rb_cFiberPool = rb_define_class("Pool", rb_cFiber);
+ rb_define_alloc_func(rb_cFiberPool, fiber_pool_alloc);
+ rb_define_method(rb_cFiberPool, "initialize", rb_fiber_pool_initialize, -1);
+#endif
}
RUBY_SYMBOL_EXPORT_BEGIN
@@ -1823,6 +3121,9 @@ ruby_Init_Continuation_body(void)
void
ruby_Init_Fiber_as_Coroutine(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
rb_define_method(rb_cFiber, "transfer", rb_fiber_m_transfer, -1);
rb_define_method(rb_cFiber, "alive?", rb_fiber_alive_p, 0);
rb_define_singleton_method(rb_cFiber, "current", rb_fiber_s_current, 0);
diff --git a/coroutine/Stack.h b/coroutine/Stack.h
new file mode 100644
index 0000000000..f0fc703622
--- /dev/null
+++ b/coroutine/Stack.h
@@ -0,0 +1,16 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 10/11/2020.
+ * Copyright, 2020, by Samuel Williams.
+*/
+
+#include COROUTINE_H
+
+#ifdef COROUTINE_PRIVATE_STACK
+#define COROUTINE_STACK_LOCAL(type, name) type *name = ruby_xmalloc(sizeof(type))
+#define COROUTINE_STACK_FREE(name) ruby_xfree(name)
+#else
+#define COROUTINE_STACK_LOCAL(type, name) type name##_local; type * name = &name##_local
+#define COROUTINE_STACK_FREE(name)
+#endif
diff --git a/coroutine/amd64/Context.S b/coroutine/amd64/Context.S
new file mode 100644
index 0000000000..051db1c5e8
--- /dev/null
+++ b/coroutine/amd64/Context.S
@@ -0,0 +1,46 @@
+##
+## This file is part of the "Coroutine" project and released under the MIT License.
+##
+## Created by Samuel Williams on 10/5/2018.
+## Copyright, 2018, by Samuel Williams.
+##
+
+#define TOKEN_PASTE(x,y) x##y
+#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
+
+.text
+
+.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
+PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
+
+ # Save caller state
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ # Save caller stack pointer
+ movq %rsp, (%rdi)
+
+ # Restore callee stack pointer
+ movq (%rsi), %rsp
+
+ # Restore callee state
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+
+ # Put the first argument into the return value
+ movq %rdi, %rax
+
+ # We pop the return address and jump to it
+ ret
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/coroutine/amd64/Context.h b/coroutine/amd64/Context.h
new file mode 100644
index 0000000000..581525b67e
--- /dev/null
+++ b/coroutine/amd64/Context.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 10/5/2018.
+ * Copyright, 2018, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define COROUTINE __attribute__((noreturn)) void
+
+enum {COROUTINE_REGISTERS = 6};
+
+struct coroutine_context
+{
+ void **stack_pointer;
+};
+
+typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->stack_pointer = NULL;
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ // Stack grows down. Force 16-byte alignment.
+ char * top = (char*)stack + size;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
+
+ *--context->stack_pointer = NULL;
+ *--context->stack_pointer = (void*)start;
+
+ context->stack_pointer -= COROUTINE_REGISTERS;
+ memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
+}
+
+struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+ context->stack_pointer = NULL;
+}
diff --git a/coroutine/arm32/Context.S b/coroutine/arm32/Context.S
new file mode 100644
index 0000000000..1850c4c408
--- /dev/null
+++ b/coroutine/arm32/Context.S
@@ -0,0 +1,33 @@
+##
+## This file is part of the "Coroutine" project and released under the MIT License.
+##
+## Created by Samuel Williams on 10/5/2018.
+## Copyright, 2018, by Samuel Williams.
+##
+
+#define TOKEN_PASTE(x,y) x##y
+#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
+
+.file "Context.S"
+.text
+.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
+.align 2
+.type PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer),%function
+.syntax unified
+
+PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
+ # Save caller state (8 registers + return address)
+ push {r4-r11,lr}
+
+ # Save caller stack pointer
+ str sp, [r0]
+
+ # Restore callee stack pointer
+ ldr sp, [r1]
+
+ # Restore callee state (8 registers program counter)
+ pop {r4-r11,pc}
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/coroutine/arm32/Context.h b/coroutine/arm32/Context.h
new file mode 100644
index 0000000000..e69f4b2eeb
--- /dev/null
+++ b/coroutine/arm32/Context.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 10/5/2018.
+ * Copyright, 2018, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define COROUTINE __attribute__((noreturn)) void
+#define COROUTINE_LIMITED_ADDRESS_SPACE
+
+enum {COROUTINE_REGISTERS = 8};
+
+struct coroutine_context
+{
+ void **stack_pointer;
+};
+
+typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->stack_pointer = NULL;
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ // Stack grows down. Force 16-byte alignment.
+ char * top = (char*)stack + size;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
+
+ *--context->stack_pointer = (void*)start;
+
+ context->stack_pointer -= COROUTINE_REGISTERS;
+ memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
+}
+
+struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+}
diff --git a/coroutine/arm64/Context.S b/coroutine/arm64/Context.S
new file mode 100644
index 0000000000..04e3f6d1ef
--- /dev/null
+++ b/coroutine/arm64/Context.S
@@ -0,0 +1,62 @@
+##
+## This file is part of the "Coroutine" project and released under the MIT License.
+##
+## Created by Samuel Williams on 10/5/2018.
+## Copyright, 2018, by Samuel Williams.
+##
+
+#define TOKEN_PASTE(x,y) x##y
+#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
+
+.text
+.align 2
+
+.global PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
+PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
+
+ # Make space on the stack for caller registers
+ sub sp, sp, 0xb0
+
+ # Save caller registers
+ stp d8, d9, [sp, 0x00]
+ stp d10, d11, [sp, 0x10]
+ stp d12, d13, [sp, 0x20]
+ stp d14, d15, [sp, 0x30]
+ stp x19, x20, [sp, 0x40]
+ stp x21, x22, [sp, 0x50]
+ stp x23, x24, [sp, 0x60]
+ stp x25, x26, [sp, 0x70]
+ stp x27, x28, [sp, 0x80]
+ stp x29, x30, [sp, 0x90]
+
+ # Save return address
+ str x30, [sp, 0xa0]
+
+ # Save stack pointer to x0 (first argument)
+ mov x2, sp
+ str x2, [x0, 0]
+
+ # Load stack pointer from x1 (second argument)
+ ldr x3, [x1, 0]
+ mov sp, x3
+
+ # Restore caller registers
+ ldp d8, d9, [sp, 0x00]
+ ldp d10, d11, [sp, 0x10]
+ ldp d12, d13, [sp, 0x20]
+ ldp d14, d15, [sp, 0x30]
+ ldp x19, x20, [sp, 0x40]
+ ldp x21, x22, [sp, 0x50]
+ ldp x23, x24, [sp, 0x60]
+ ldp x25, x26, [sp, 0x70]
+ ldp x27, x28, [sp, 0x80]
+ ldp x29, x30, [sp, 0x90]
+
+ # Load return address into x4
+ ldr x4, [sp, 0xa0]
+
+ # Pop stack frame
+ add sp, sp, 0xb0
+
+ # Jump to return address (in x4)
+ ret x4
diff --git a/coroutine/arm64/Context.h b/coroutine/arm64/Context.h
new file mode 100644
index 0000000000..34be995a4f
--- /dev/null
+++ b/coroutine/arm64/Context.h
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 10/5/2018.
+ * Copyright, 2018, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define COROUTINE __attribute__((noreturn)) void
+
+enum {COROUTINE_REGISTERS = 0xb0 / 8};
+
+struct coroutine_context
+{
+ void **stack_pointer;
+};
+
+typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->stack_pointer = NULL;
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ // Stack grows down. Force 16-byte alignment.
+ char * top = (char*)stack + size;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
+
+ context->stack_pointer -= COROUTINE_REGISTERS;
+ memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
+
+ context->stack_pointer[0xa0 / 8] = (void*)start;
+}
+
+struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+}
diff --git a/coroutine/copy/Context.c b/coroutine/copy/Context.c
new file mode 100644
index 0000000000..aa8bb2ff05
--- /dev/null
+++ b/coroutine/copy/Context.c
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 24/6/2019.
+ * Copyright, 2019, by Samuel Williams.
+*/
+
+#include "Context.h"
+
+#include <stdint.h>
+
+// http://gcc.gnu.org/onlinedocs/gcc/Alternate-Keywords.html
+#ifndef __GNUC__
+#define __asm__ asm
+#endif
+
+#if defined(__sparc)
+__attribute__((noinline))
+// https://marc.info/?l=linux-sparc&m=131914569320660&w=2
+static void coroutine_flush_register_windows(void) {
+ __asm__
+#ifdef __GNUC__
+ __volatile__
+#endif
+#if defined(__sparcv9) || defined(__sparc_v9__) || defined(__arch64__)
+#ifdef __GNUC__
+ ("flushw" : : : "%o7")
+#else
+ ("flushw")
+#endif
+#else
+ ("ta 0x03")
+#endif
+ ;
+}
+#else
+static void coroutine_flush_register_windows(void) {}
+#endif
+
+__attribute__((noinline))
+void *coroutine_stack_pointer(void) {
+ return (void*)(
+ (char*)__builtin_frame_address(0)
+ );
+}
+
+// Save the current stack to a private area. It is likely that when restoring the stack, this stack frame will be incomplete. But that is acceptable since the previous stack frame which called `setjmp` should be correctly restored.
+__attribute__((noinline))
+int coroutine_save_stack_1(struct coroutine_context * context) {
+ assert(context->stack);
+ assert(context->base);
+
+ void *stack_pointer = coroutine_stack_pointer();
+
+ // At this point, you may need to ensure on architectures that use register windows, that all registers are flushed to the stack, otherwise the copy of the stack will not contain the valid registers:
+ coroutine_flush_register_windows();
+
+ // Save stack to private area:
+ if (stack_pointer < context->base) {
+ size_t size = (char*)context->base - (char*)stack_pointer;
+ assert(size <= context->size);
+
+ memcpy(context->stack, stack_pointer, size);
+ context->used = size;
+ } else {
+ size_t size = (char*)stack_pointer - (char*)context->base;
+ assert(size <= context->size);
+
+ memcpy(context->stack, context->base, size);
+ context->used = size;
+ }
+
+ // Initialized:
+ return 0;
+}
+
+// Copy the current stack to a private memory buffer.
+int coroutine_save_stack(struct coroutine_context * context) {
+ if (_setjmp(context->state)) {
+ // Restored.
+ return 1;
+ }
+
+ // We need to invoke the memory copy from one stack frame deeper than the one that calls setjmp. That is because if you don't do this, the setjmp might be restored into an invalid stack frame (truncated, etc):
+ return coroutine_save_stack_1(context);
+}
+
+__attribute__((noreturn, noinline))
+void coroutine_restore_stack_padded(struct coroutine_context *context, void * buffer) {
+ void *stack_pointer = coroutine_stack_pointer();
+
+ assert(context->base);
+
+ // At this point, you may need to ensure on architectures that use register windows, that all registers are flushed to the stack, otherwise when we copy in the new stack, the registers would not be updated:
+ coroutine_flush_register_windows();
+
+ // Restore stack from private area:
+ if (stack_pointer < context->base) {
+ void * bottom = (char*)context->base - context->used;
+ assert(bottom > stack_pointer);
+
+ memcpy(bottom, context->stack, context->used);
+ } else {
+ void * top = (char*)context->base + context->used;
+ assert(top < stack_pointer);
+
+ memcpy(context->base, context->stack, context->used);
+ }
+
+ // Restore registers. The `buffer` is to force the compiler NOT to elide he buffer and `alloca`:
+ _longjmp(context->state, (int)(1 | (intptr_t)buffer));
+}
+
+// In order to swap between coroutines, we need to swap the stack and registers.
+// `setjmp` and `longjmp` are able to swap registers, but what about swapping stacks? You can use `memcpy` to copy the current stack to a private area and `memcpy` to copy the private stack of the next coroutine to the main stack.
+// But if the stack yop are copying in to the main stack is bigger than the currently executing stack, the `memcpy` will clobber the current stack frame (including the context argument). So we use `alloca` to push the current stack frame *beyond* the stack we are about to copy in. This ensures the current stack frame in `coroutine_restore_stack_padded` remains valid for calling `longjmp`.
+__attribute__((noreturn))
+void coroutine_restore_stack(struct coroutine_context *context) {
+ void *stack_pointer = coroutine_stack_pointer();
+ void *buffer = NULL;
+
+ // We must ensure that the next stack frame is BEYOND the stack we are restoring:
+ if (stack_pointer < context->base) {
+ intptr_t offset = (intptr_t)stack_pointer - ((intptr_t)context->base - context->used);
+ if (offset > 0) buffer = alloca(offset);
+ } else {
+ intptr_t offset = ((intptr_t)context->base + context->used) - (intptr_t)stack_pointer;
+ if (offset > 0) buffer = alloca(offset);
+ }
+
+ assert(context->used > 0);
+
+ coroutine_restore_stack_padded(context, buffer);
+}
+
+struct coroutine_context *coroutine_transfer(struct coroutine_context *current, struct coroutine_context *target)
+{
+ struct coroutine_context *previous = target->from;
+
+ // In theory, either this condition holds true, or we should assign the base address to target:
+ assert(current->base == target->base);
+ // If you are trying to copy the coroutine to a different thread
+ // target->base = current->base
+
+ target->from = current;
+
+ assert(current != target);
+
+ // It's possible to come here, even thought the current fiber has been terminated. We are never going to return so we don't bother saving the stack.
+
+ if (current->stack) {
+ if (coroutine_save_stack(current) == 0) {
+ coroutine_restore_stack(target);
+ }
+ } else {
+ coroutine_restore_stack(target);
+ }
+
+ target->from = previous;
+
+ return target;
+}
diff --git a/coroutine/copy/Context.h b/coroutine/copy/Context.h
new file mode 100644
index 0000000000..6038f00cf6
--- /dev/null
+++ b/coroutine/copy/Context.h
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 27/6/2019.
+ * Copyright, 2019, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* OpenBSD supports alloca, but does not include alloca.h */
+#ifndef __OpenBSD__
+#include <alloca.h>
+#endif
+
+#define COROUTINE __attribute__((noreturn)) void
+
+#if INTPTR_MAX <= INT32_MAX
+#define COROUTINE_LIMITED_ADDRESS_SPACE
+#endif
+
+// This stack copying implementation which uses a private stack for each coroutine, including the main one.
+#define COROUTINE_PRIVATE_STACK
+
+struct coroutine_context
+{
+ // Private stack:
+ void *stack;
+ size_t size, used;
+
+ // The top (or bottom) of the currently executing stack:
+ void *base;
+
+ jmp_buf state;
+
+ struct coroutine_context *from;
+};
+
+typedef COROUTINE(*coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+int coroutine_save_stack(struct coroutine_context * context);
+COROUTINE coroutine_restore_stack(struct coroutine_context *context);
+
+// @param stack The private stack area memory allocation (pointer to lowest address).
+// @param size The size of the private stack area.
+// @param base A stack pointer to the base of the main stack. On x86 hardware, this is the upper extent of the region that will be copied to the private stack.
+static inline void coroutine_initialize_main(struct coroutine_context *context, void *stack, size_t size, void *base) {
+ assert(stack);
+ assert(size >= 1024);
+
+ context->stack = stack;
+ context->size = size;
+ context->used = 0;
+
+ assert(base);
+ context->base = base;
+
+ context->from = NULL;
+}
+
+// @param start The start function to invoke.
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size,
+ void *base
+) {
+ assert(start);
+
+ coroutine_initialize_main(context, stack, size, base);
+
+ if (coroutine_save_stack(context)) {
+ start(context->from, context);
+ }
+}
+
+struct coroutine_context *coroutine_transfer(struct coroutine_context *current, register struct coroutine_context *target);
+
+static inline void coroutine_destroy(struct coroutine_context *context)
+{
+ context->stack = NULL;
+ context->size = 0;
+ context->from = NULL;
+}
diff --git a/coroutine/ppc64le/Context.S b/coroutine/ppc64le/Context.S
new file mode 100644
index 0000000000..61be9efcf0
--- /dev/null
+++ b/coroutine/ppc64le/Context.S
@@ -0,0 +1,75 @@
+#define TOKEN_PASTE(x,y) x##y
+#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
+
+.text
+.align 2
+
+.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
+.type PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer), @function
+PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
+ # Make space on the stack for caller registers
+ addi 1,1,-152
+
+ # Save caller registers
+ std 14,0(1)
+ std 15,8(1)
+ std 16,16(1)
+ std 17,24(1)
+ std 18,32(1)
+ std 19,40(1)
+ std 20,48(1)
+ std 21,56(1)
+ std 22,64(1)
+ std 23,72(1)
+ std 24,80(1)
+ std 25,88(1)
+ std 26,96(1)
+ std 27,104(1)
+ std 28,112(1)
+ std 29,120(1)
+ std 30,128(1)
+ std 31,136(1)
+
+ # Save return address
+ mflr 0
+ std 0,144(1)
+
+ # Save stack pointer to first argument
+ std 1,0(3)
+
+ # Load stack pointer from second argument
+ ld 1,0(4)
+
+ # Restore caller registers
+ ld 14,0(1)
+ ld 15,8(1)
+ ld 16,16(1)
+ ld 17,24(1)
+ ld 18,32(1)
+ ld 19,40(1)
+ ld 20,48(1)
+ ld 21,56(1)
+ ld 22,64(1)
+ ld 23,72(1)
+ ld 24,80(1)
+ ld 25,88(1)
+ ld 26,96(1)
+ ld 27,104(1)
+ ld 28,112(1)
+ ld 29,120(1)
+ ld 30,128(1)
+ ld 31,136(1)
+
+ # Load return address
+ ld 0,144(1)
+ mtlr 0
+
+ # Pop stack frame
+ addi 1,1,152
+
+ # Jump to return address
+ blr
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/coroutine/ppc64le/Context.h b/coroutine/ppc64le/Context.h
new file mode 100644
index 0000000000..e36f9c3583
--- /dev/null
+++ b/coroutine/ppc64le/Context.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define COROUTINE __attribute__((noreturn)) void
+
+enum {
+ COROUTINE_REGISTERS =
+ 19 /* 18 general purpose registers (r14-r31) and 1 return address */
+ + 4 /* space for fiber_entry() to store the link register */
+};
+
+struct coroutine_context
+{
+ void **stack_pointer;
+};
+
+typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->stack_pointer = NULL;
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ // Stack grows down. Force 16-byte alignment.
+ char * top = (char*)stack + size;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
+
+ context->stack_pointer -= COROUTINE_REGISTERS;
+ memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
+
+ /* Skip a global prologue that sets the TOC register */
+ context->stack_pointer[18] = ((char*)start) + 8;
+}
+
+struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+ context->stack_pointer = NULL;
+}
diff --git a/coroutine/ucontext/Context.c b/coroutine/ucontext/Context.c
new file mode 100644
index 0000000000..9ba76ee628
--- /dev/null
+++ b/coroutine/ucontext/Context.c
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 24/6/2019.
+ * Copyright, 2019, by Samuel Williams.
+*/
+
+/* According to Solaris' ucontext.h, makecontext, etc. are removed in SUSv4.
+ * To enable the prototype declarations, we need to define __EXTENSIONS__.
+ */
+#if defined(__sun) && !defined(__EXTENSIONS__)
+#define __EXTENSIONS__
+#endif
+#include "Context.h"
+
+void coroutine_trampoline(void * _start, void * _context)
+{
+ coroutine_start start = (coroutine_start)_start;
+ struct coroutine_context * context = _context;
+
+ start(context->from, context);
+}
diff --git a/coroutine/ucontext/Context.h b/coroutine/ucontext/Context.h
new file mode 100644
index 0000000000..2b2a593793
--- /dev/null
+++ b/coroutine/ucontext/Context.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 24/6/2019.
+ * Copyright, 2019, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <ucontext.h>
+
+#define COROUTINE __attribute__((noreturn)) void
+
+#if INTPTR_MAX <= INT32_MAX
+#define COROUTINE_LIMITED_ADDRESS_SPACE
+#endif
+
+struct coroutine_context
+{
+ ucontext_t state;
+ struct coroutine_context * from;
+};
+
+typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+COROUTINE coroutine_trampoline(void * _start, void * _context);
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->from = NULL;
+ getcontext(&context->state);
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ coroutine_initialize_main(context);
+
+ context->state.uc_stack.ss_size = size;
+ // Despite what it's called, this is not actually a stack pointer. It points to the address of the stack allocation (the lowest address).
+ context->state.uc_stack.ss_sp = (char*)stack;
+ context->state.uc_stack.ss_flags = 0;
+ context->state.uc_link = NULL;
+
+ makecontext(&context->state, (void(*)(void))coroutine_trampoline, 2, (void*)start, (void*)context);
+}
+
+static inline struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target)
+{
+ struct coroutine_context * previous = target->from;
+
+ target->from = current;
+ swapcontext(&current->state, &target->state);
+ target->from = previous;
+
+ return target;
+}
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+ context->state.uc_stack.ss_sp = NULL;
+ context->state.uc_stack.ss_size = 0;
+ context->from = NULL;
+}
diff --git a/coroutine/win32/Context.S b/coroutine/win32/Context.S
new file mode 100644
index 0000000000..d14bf435e8
--- /dev/null
+++ b/coroutine/win32/Context.S
@@ -0,0 +1,47 @@
+##
+## This file is part of the "Coroutine" project and released under the MIT License.
+##
+## Created by Lars Kanis on 06/06/2019.
+##
+
+.text
+
+# Using fastcall is a big win (and it's the same as how x64 works).
+# In coroutine transfer, the arguments are passed in ecx and edx. We don't need
+# to touch these in order to pass them to the destination coroutine.
+
+.globl @coroutine_transfer@8
+@coroutine_transfer@8:
+ # Save the thread information block:
+ pushl %fs:0
+ pushl %fs:4
+ pushl %fs:8
+
+ # Save caller registers:
+ pushl %ebp
+ pushl %ebx
+ pushl %edi
+ pushl %esi
+
+ # Save caller stack pointer:
+ movl %esp, (%ecx)
+
+ # Restore callee stack pointer:
+ movl (%edx), %esp
+
+ # Restore callee stack:
+ popl %esi
+ popl %edi
+ popl %ebx
+ popl %ebp
+
+ # Restore the thread information block:
+ popl %fs:8
+ popl %fs:4
+ popl %fs:0
+
+ # Save the first argument as the return value:
+ movl %ecx, %eax
+
+ # Jump to the address on the stack:
+ ret
diff --git a/coroutine/win32/Context.asm b/coroutine/win32/Context.asm
new file mode 100644
index 0000000000..f8f431239b
--- /dev/null
+++ b/coroutine/win32/Context.asm
@@ -0,0 +1,55 @@
+;;
+;; This file is part of the "Coroutine" project and released under the MIT License.
+;;
+;; Created by Samuel Williams on 10/5/2018.
+;; Copyright, 2018, by Samuel Williams.
+;;
+
+.386
+.model flat
+
+.code
+
+assume fs:nothing
+
+; Using fastcall is a big win (and it's the same has how x64 works).
+; In coroutine transfer, the arguments are passed in ecx and edx. We don't need
+; to touch these in order to pass them to the destination coroutine.
+
+@coroutine_transfer@8 proc
+ ; Save the thread information block:
+ push fs:[0]
+ push fs:[4]
+ push fs:[8]
+
+ ; Save caller registers:
+ push ebp
+ push ebx
+ push edi
+ push esi
+
+ ; Save caller stack pointer:
+ mov dword ptr [ecx], esp
+
+ ; Restore callee stack pointer:
+ mov esp, dword ptr [edx]
+
+ ; Restore callee stack:
+ pop esi
+ pop edi
+ pop ebx
+ pop ebp
+
+ ; Restore the thread information block:
+ pop fs:[8]
+ pop fs:[4]
+ pop fs:[0]
+
+ ; Save the first argument as the return value:
+ mov eax, dword ptr ecx
+
+ ; Jump to the address on the stack:
+ ret
+@coroutine_transfer@8 endp
+
+end
diff --git a/coroutine/win32/Context.h b/coroutine/win32/Context.h
new file mode 100644
index 0000000000..e20342a98d
--- /dev/null
+++ b/coroutine/win32/Context.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 10/5/2018.
+ * Copyright, 2018, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define COROUTINE __declspec(noreturn) void __fastcall
+#define COROUTINE_LIMITED_ADDRESS_SPACE
+
+/* This doesn't include thread information block */
+enum {COROUTINE_REGISTERS = 4};
+
+struct coroutine_context
+{
+ void **stack_pointer;
+};
+
+typedef void(__fastcall * coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->stack_pointer = NULL;
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ // Stack grows down. Force 16-byte alignment.
+ char * top = (char*)stack + size;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
+
+ *--context->stack_pointer = (void*)start;
+
+ /* Windows Thread Information Block */
+ *--context->stack_pointer = (void*)0xFFFFFFFF; /* fs:[0] */
+ *--context->stack_pointer = (void*)top; /* fs:[4] */
+ *--context->stack_pointer = (void*)stack; /* fs:[8] */
+
+ context->stack_pointer -= COROUTINE_REGISTERS;
+ memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
+}
+
+struct coroutine_context * __fastcall coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+}
diff --git a/coroutine/win64/Context.S b/coroutine/win64/Context.S
new file mode 100644
index 0000000000..e0ee38e006
--- /dev/null
+++ b/coroutine/win64/Context.S
@@ -0,0 +1,77 @@
+##
+## This file is part of the "Coroutine" project and released under the MIT License.
+##
+## Created by Samuel Williams on 4/11/2018.
+## Copyright, 2018, by Samuel Williams.
+##
+
+.text
+
+.globl coroutine_transfer
+coroutine_transfer:
+ # Save the thread information block:
+ pushq %gs:8
+ pushq %gs:16
+
+ # Save caller registers:
+ pushq %rbp
+ pushq %rbx
+ pushq %rdi
+ pushq %rsi
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ movaps %xmm15, -168(%rsp)
+ movaps %xmm14, -152(%rsp)
+ movaps %xmm13, -136(%rsp)
+ movaps %xmm12, -120(%rsp)
+ movaps %xmm11, -104(%rsp)
+ movaps %xmm10, -88(%rsp)
+ movaps %xmm9, -72(%rsp)
+ movaps %xmm8, -56(%rsp)
+ movaps %xmm7, -40(%rsp)
+ movaps %xmm6, -24(%rsp)
+
+ # Save caller stack pointer:
+ mov %rsp, (%rcx)
+
+ # Restore callee stack pointer:
+ mov (%rdx), %rsp
+
+ movaps -24(%rsp), %xmm6
+ movaps -40(%rsp), %xmm7
+ movaps -56(%rsp), %xmm8
+ movaps -72(%rsp), %xmm9
+ movaps -88(%rsp), %xmm10
+ movaps -104(%rsp), %xmm11
+ movaps -120(%rsp), %xmm12
+ movaps -136(%rsp), %xmm13
+ movaps -152(%rsp), %xmm14
+ movaps -168(%rsp), %xmm15
+
+ # Restore callee stack:
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rsi
+ popq %rdi
+ popq %rbx
+ popq %rbp
+
+ # Restore the thread information block:
+ popq %gs:16
+ popq %gs:8
+
+ # Put the first argument into the return value:
+ mov %rcx, %rax
+
+ # We pop the return address and jump to it:
+ ret
+
+.globl coroutine_trampoline
+coroutine_trampoline:
+ # Do not remove this. This forces 16-byte alignment when entering the coroutine.
+ ret
diff --git a/coroutine/win64/Context.asm b/coroutine/win64/Context.asm
new file mode 100644
index 0000000000..8c4dea1c93
--- /dev/null
+++ b/coroutine/win64/Context.asm
@@ -0,0 +1,79 @@
+;;
+;; This file is part of the "Coroutine" project and released under the MIT License.
+;;
+;; Created by Samuel Williams on 10/5/2018.
+;; Copyright, 2018, by Samuel Williams.
+;;
+
+.code
+
+coroutine_transfer proc
+ ; Save the thread information block:
+ push qword ptr gs:[8]
+ push qword ptr gs:[16]
+
+ ; Save caller registers:
+ push rbp
+ push rbx
+ push rdi
+ push rsi
+ push r12
+ push r13
+ push r14
+ push r15
+
+ movaps [rsp - 24], xmm6
+ movaps [rsp - 40], xmm7
+ movaps [rsp - 56], xmm8
+ movaps [rsp - 72], xmm9
+ movaps [rsp - 88], xmm10
+ movaps [rsp - 104], xmm11
+ movaps [rsp - 120], xmm12
+ movaps [rsp - 136], xmm13
+ movaps [rsp - 152], xmm14
+ movaps [rsp - 168], xmm15
+
+ ; Save caller stack pointer:
+ mov [rcx], rsp
+
+ ; Restore callee stack pointer:
+ mov rsp, [rdx]
+
+ movaps xmm15, [rsp - 168]
+ movaps xmm14, [rsp - 152]
+ movaps xmm13, [rsp - 136]
+ movaps xmm12, [rsp - 120]
+ movaps xmm11, [rsp - 104]
+ movaps xmm10, [rsp - 88]
+ movaps xmm9, [rsp - 72]
+ movaps xmm8, [rsp - 56]
+ movaps xmm7, [rsp - 40]
+ movaps xmm6, [rsp - 24]
+
+ ; Restore callee stack:
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rsi
+ pop rdi
+ pop rbx
+ pop rbp
+
+ ; Restore the thread information block:
+ pop qword ptr gs:[16]
+ pop qword ptr gs:[8]
+
+ ; Put the first argument into the return value:
+ mov rax, rcx
+
+ ; We pop the return address and jump to it:
+ ret
+coroutine_transfer endp
+
+coroutine_trampoline proc
+ ; Do not remove this. This forces 16-byte alignment when entering the coroutine.
+ ret
+coroutine_trampoline endp
+
+end
diff --git a/coroutine/win64/Context.h b/coroutine/win64/Context.h
new file mode 100644
index 0000000000..e28e6a6ff0
--- /dev/null
+++ b/coroutine/win64/Context.h
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 10/5/2018.
+ * Copyright, 2018, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define COROUTINE __declspec(noreturn) void
+
+enum {
+ COROUTINE_REGISTERS = 8,
+ COROUTINE_XMM_REGISTERS = 1+10*2,
+};
+
+struct coroutine_context
+{
+ void **stack_pointer;
+};
+
+typedef void(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
+
+void coroutine_trampoline();
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->stack_pointer = NULL;
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ // Stack grows down. Force 16-byte alignment.
+ char * top = (char*)stack + size;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
+
+ /* Win64 ABI requires space for arguments */
+ context->stack_pointer -= 4;
+
+ /* Return address */
+ *--context->stack_pointer = 0;
+ *--context->stack_pointer = (void*)start;
+ *--context->stack_pointer = (void*)coroutine_trampoline;
+
+ /* Windows Thread Information Block */
+ /* *--context->stack_pointer = 0; */ /* gs:[0x00] is not used */
+ *--context->stack_pointer = (void*)top; /* gs:[0x08] */
+ *--context->stack_pointer = (void*)stack; /* gs:[0x10] */
+
+ context->stack_pointer -= COROUTINE_REGISTERS;
+ memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
+ memset(context->stack_pointer - COROUTINE_XMM_REGISTERS, 0, sizeof(void*) * COROUTINE_XMM_REGISTERS);
+}
+
+struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+}
diff --git a/coroutine/x86/Context.S b/coroutine/x86/Context.S
new file mode 100644
index 0000000000..6983f21c3b
--- /dev/null
+++ b/coroutine/x86/Context.S
@@ -0,0 +1,42 @@
+##
+## This file is part of the "Coroutine" project and released under the MIT License.
+##
+## Created by Samuel Williams on 3/11/2018.
+## Copyright, 2018, by Samuel Williams.
+##
+
+#define TOKEN_PASTE(x,y) x##y
+#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
+
+.text
+
+.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
+PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
+
+ # Save caller registers
+ pushl %ebp
+ pushl %ebx
+ pushl %edi
+ pushl %esi
+
+ # Save caller stack pointer
+ movl %esp, (%ecx)
+
+ # Restore callee stack pointer
+ movl (%edx), %esp
+
+ # Restore callee stack
+ popl %esi
+ popl %edi
+ popl %ebx
+ popl %ebp
+
+ # Save the first argument as the return value
+ movl %ecx, %eax
+
+ # Jump to the address on the stack
+ ret
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/coroutine/x86/Context.h b/coroutine/x86/Context.h
new file mode 100644
index 0000000000..dfdde24f5d
--- /dev/null
+++ b/coroutine/x86/Context.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the "Coroutine" project and released under the MIT License.
+ *
+ * Created by Samuel Williams on 3/11/2018.
+ * Copyright, 2018, by Samuel Williams.
+*/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define COROUTINE __attribute__((noreturn, fastcall)) void
+#define COROUTINE_LIMITED_ADDRESS_SPACE
+
+enum {COROUTINE_REGISTERS = 4};
+
+struct coroutine_context
+{
+ void **stack_pointer;
+};
+
+typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self) __attribute__((fastcall));
+
+static inline void coroutine_initialize_main(struct coroutine_context * context) {
+ context->stack_pointer = NULL;
+}
+
+static inline void coroutine_initialize(
+ struct coroutine_context *context,
+ coroutine_start start,
+ void *stack,
+ size_t size
+) {
+ assert(start && stack && size >= 1024);
+
+ // Stack grows down. Force 16-byte alignment.
+ char * top = (char*)stack + size;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
+
+ *--context->stack_pointer = NULL;
+ *--context->stack_pointer = (void*)start;
+
+ context->stack_pointer -= COROUTINE_REGISTERS;
+ memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
+}
+
+struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target) __attribute__((fastcall));
+
+static inline void coroutine_destroy(struct coroutine_context * context)
+{
+ context->stack_pointer = NULL;
+}
diff --git a/coverage/README b/coverage/README
index 7e4ff59e2a..78a01826aa 100644
--- a/coverage/README
+++ b/coverage/README
@@ -4,7 +4,7 @@ The make task `update-coverage' retrieves simplecov for coverage report.
COVERAGE=1 make test-all TESTS=test/cgi
-it generate test coverage to coverage directory.
+it generates test coverage to coverage directory.
Limitation
diff --git a/cygwin/GNUmakefile.in b/cygwin/GNUmakefile.in
index 192cf43b37..86098814a1 100644
--- a/cygwin/GNUmakefile.in
+++ b/cygwin/GNUmakefile.in
@@ -1,8 +1,13 @@
+gnumake = yes
+
include Makefile
ENABLE_SHARED=@ENABLE_SHARED@
DLLWRAP = @DLLWRAP@ --target=@target_os@ --driver-name="$(CC)"
-WINDRES = @WINDRES@ --preprocessor="$(CPP) -xc" -DRC_INVOKED
+windres-cpp := $(CPP) -xc
+windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \
+ $(addprefix --preprocessor-arg=,$(wordlist 2,$(words $(windres-cpp)),$(windres-cpp)))
+WINDRES = @WINDRES@ $(windres-cpp) -DRC_INVOKED
STRIP = @STRIP@
ifeq (@target_os@,cygwin)
@@ -94,13 +99,5 @@ $(RUBYDEF): $(LIBRUBY_A) $(PREP) $(RBCONFIG)
clean-local::
@$(RM) $(RUBYDEF)
-
-ifeq (@target_os@,cygwin)
-cygwin-$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR)0.dll: $(LIBRUBY_A) $(RUBYDEF)
- $(ECHO) generating $@
- $(Q) @DLLWRAP@ -s --def=$(RUBYDEF) -o $@
-endif
-
-clean-local::
@$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@)
@$(RM) $(RCFILES)
diff --git a/debug.c b/debug.c
index 60cef508f6..75d4cc6569 100644
--- a/debug.c
+++ b/debug.c
@@ -9,13 +9,33 @@
**********************************************************************/
-#include "ruby/ruby.h"
+#include "ruby/internal/config.h"
+
+#include <stdio.h>
+
+#include "eval_intern.h"
+#include "id.h"
+#include "internal/signal.h"
+#include "internal/util.h"
#include "ruby/encoding.h"
+#include "ruby/io.h"
+#include "ruby/ruby.h"
#include "ruby/util.h"
-#include "vm_debug.h"
-#include "eval_intern.h"
+#include "symbol.h"
#include "vm_core.h"
-#include "id.h"
+#include "vm_debug.h"
+#include "vm_callinfo.h"
+#include "ruby/thread_native.h"
+#include "ractor_core.h"
+
+/* This is the only place struct RIMemo is actually used */
+struct RIMemo {
+ VALUE flags;
+ VALUE v0;
+ VALUE v1;
+ VALUE v2;
+ VALUE v3;
+};
/* for gdb */
const union {
@@ -26,13 +46,18 @@ const union {
enum ruby_method_ids method_ids;
enum ruby_id_types id_types;
enum ruby_fl_type fl_types;
+ enum ruby_fl_ushift fl_ushift;
enum ruby_encoding_consts encoding_consts;
enum ruby_coderange_type enc_coderange_types;
enum ruby_econv_flag_type econv_flag_types;
+ rb_econv_result_t econv_result;
enum ruby_robject_flags robject_flags;
+ enum ruby_robject_consts robject_consts;
enum ruby_rmodule_flags rmodule_flags;
enum ruby_rstring_flags rstring_flags;
+ enum ruby_rstring_consts rstring_consts;
enum ruby_rarray_flags rarray_flags;
+ enum ruby_rarray_consts rarray_consts;
enum {
RUBY_FMODE_READABLE = FMODE_READABLE,
RUBY_FMODE_WRITABLE = FMODE_WRITABLE,
@@ -57,6 +82,13 @@ const union {
RUBY_NODE_LSHIFT = NODE_LSHIFT,
RUBY_NODE_FL_NEWLINE = NODE_FL_NEWLINE
} various;
+ union {
+ enum imemo_type types;
+ enum {RUBY_IMEMO_MASK = IMEMO_MASK} mask;
+ struct RIMemo *ptr;
+ } imemo;
+ struct RSymbol *symbol_ptr;
+ enum vm_call_flag_bits vm_call_flags;
} ruby_dummy_gdb_enums;
const SIGNED_VALUE RUBY_NODE_LMASK = NODE_LMASK;
@@ -138,6 +170,7 @@ extern int ruby_w32_rtc_error;
UINT ruby_w32_codepage[2];
#endif
extern int ruby_rgengc_debug;
+extern int ruby_on_ci;
int
ruby_env_debug_option(const char *str, int len, void *arg)
@@ -183,6 +216,7 @@ ruby_env_debug_option(const char *str, int len, void *arg)
SET_WHEN("gc_stress", *ruby_initial_gc_stress_ptr, Qtrue);
SET_WHEN("core", ruby_enable_coredump, 1);
+ SET_WHEN("ci", ruby_on_ci, 1);
if (NAME_MATCH_VALUE("rgengc")) {
if (!len) ruby_rgengc_debug = 1;
else SET_UINT_LIST("rgengc", &ruby_rgengc_debug, 1);
@@ -211,8 +245,267 @@ set_debug_option(const char *str, int len, void *arg)
}
}
+#ifdef USE_RUBY_DEBUG_LOG
+STATIC_ASSERT(USE_RUBY_DEBUG_LOG, USE_RUBY_DEBUG_LOG ? RUBY_DEVEL : 1);
+#endif
+
+#if RUBY_DEVEL
+static void setup_debug_log(void);
+#else
+#define setup_debug_log()
+#endif
+
void
ruby_set_debug_option(const char *str)
{
ruby_each_words(str, set_debug_option, 0);
+ setup_debug_log();
+}
+
+#if RUBY_DEVEL
+
+// RUBY_DEBUG_LOG features
+// See vm_debug.h comments for details.
+
+#define MAX_DEBUG_LOG 0x1000
+#define MAX_DEBUG_LOG_MESSAGE_LEN 0x0200
+#define MAX_DEBUG_LOG_FILTER 0x0010
+
+enum ruby_debug_log_mode ruby_debug_log_mode;
+
+static struct {
+ char *mem;
+ unsigned int cnt;
+ char filters[MAX_DEBUG_LOG_FILTER][MAX_DEBUG_LOG_FILTER];
+ unsigned int filters_num;
+ rb_nativethread_lock_t lock;
+ FILE *output;
+} debug_log;
+
+static char *
+RUBY_DEBUG_LOG_MEM_ENTRY(unsigned int index)
+{
+ return &debug_log.mem[MAX_DEBUG_LOG_MESSAGE_LEN * index];
+}
+
+static void
+setup_debug_log(void)
+{
+ // check RUBY_DEBUG_LOG
+ const char *log_config = getenv("RUBY_DEBUG_LOG");
+ if (log_config) {
+ fprintf(stderr, "RUBY_DEBUG_LOG=%s\n", log_config);
+
+ if (strcmp(log_config, "mem") == 0) {
+ debug_log.mem = (char *)malloc(MAX_DEBUG_LOG * MAX_DEBUG_LOG_MESSAGE_LEN);
+ if (debug_log.mem == NULL) {
+ fprintf(stderr, "setup_debug_log failed (can't allocate memory)\n");
+ exit(1);
+ }
+ ruby_debug_log_mode |= ruby_debug_log_memory;
+ }
+ else if (strcmp(log_config, "stderr") == 0) {
+ ruby_debug_log_mode |= ruby_debug_log_stderr;
+ }
+ else {
+ ruby_debug_log_mode |= ruby_debug_log_file;
+ if ((debug_log.output = fopen(log_config, "w")) == NULL) {
+ fprintf(stderr, "can not open %s for RUBY_DEBUG_LOG\n", log_config);
+ exit(1);
+ }
+ setvbuf(debug_log.output, NULL, _IONBF, 0);
+ }
+
+ rb_nativethread_lock_initialize(&debug_log.lock);
+ }
+
+ // check RUBY_DEBUG_LOG_FILTER
+ const char *filter_config = getenv("RUBY_DEBUG_LOG_FILTER");
+ if (filter_config && strlen(filter_config) > 0) {
+ unsigned int i;
+ for (i=0; i<MAX_DEBUG_LOG_FILTER; i++) {
+ const char *p;
+ if ((p = strchr(filter_config, ',')) == NULL) {
+ if (strlen(filter_config) >= MAX_DEBUG_LOG_FILTER) {
+ fprintf(stderr, "too long: %s (max:%d)\n", filter_config, MAX_DEBUG_LOG_FILTER);
+ exit(1);
+ }
+ strncpy(debug_log.filters[i], filter_config, MAX_DEBUG_LOG_FILTER - 1);
+ i++;
+ break;
+ }
+ else {
+ size_t n = p - filter_config;
+ if (n >= MAX_DEBUG_LOG_FILTER) {
+ fprintf(stderr, "too long: %s (max:%d)\n", filter_config, MAX_DEBUG_LOG_FILTER);
+ exit(1);
+ }
+ strncpy(debug_log.filters[i], filter_config, n);
+ filter_config = p+1;
+ }
+ }
+ debug_log.filters_num = i;
+ for (i=0; i<debug_log.filters_num; i++) {
+ fprintf(stderr, "RUBY_DEBUG_LOG_FILTER[%d]=%s\n", i, debug_log.filters[i]);
+ }
+ }
+}
+
+bool
+ruby_debug_log_filter(const char *func_name)
+{
+ if (debug_log.filters_num > 0) {
+ for (unsigned int i = 0; i<debug_log.filters_num; i++) {
+ if (strstr(func_name, debug_log.filters[i]) != NULL) {
+ return true;
+ }
+ }
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+static const char *
+pretty_filename(const char *path)
+{
+ // basename is one idea.
+ const char *s;
+ while ((s = strchr(path, '/')) != NULL) {
+ path = s+1;
+ }
+ return path;
+}
+
+void
+ruby_debug_log(const char *file, int line, const char *func_name, const char *fmt, ...)
+{
+ char buff[MAX_DEBUG_LOG_MESSAGE_LEN] = {0};
+ int len = 0;
+ int r = 0;
+
+ // message title
+ if (func_name && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "%s\t", func_name);
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
+ len += r;
+ }
+
+ // message
+ if (fmt && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ va_list args;
+ va_start(args, fmt);
+ r = vsnprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, fmt, args);
+ va_end(args);
+ if (r < 0) rb_bug("ruby_debug_log vsnprintf() returns %d", r);
+ len += r;
+ }
+
+ // optional information
+
+ // C location
+ if (file && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "\t%s:%d", pretty_filename(file), line);
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
+ len += r;
+ }
+
+ // Ruby location
+ int ruby_line;
+ const char *ruby_file = rb_source_location_cstr(&ruby_line);
+ if (len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ if (ruby_file) {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t%s:%d", pretty_filename(ruby_file), ruby_line);
+ }
+ else {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t");
+ }
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
+ len += r;
+ }
+
+ // ractor information
+ if (ruby_single_main_ractor == NULL) {
+ rb_ractor_t *cr = GET_RACTOR();
+ if (r && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tr:#%u/%u",
+ (unsigned int)rb_ractor_id(cr), GET_VM()->ractor.cnt);
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
+ len += r;
+ }
+ }
+
+ // thread information
+ if (!rb_thread_alone()) {
+ const rb_thread_t *th = GET_THREAD();
+ if (r && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tth:%p", (void *)th);
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
+ len += r;
+ }
+ }
+
+ rb_nativethread_lock_lock(&debug_log.lock);
+ {
+ unsigned int cnt = debug_log.cnt++;
+
+ if (ruby_debug_log_mode & ruby_debug_log_memory) {
+ unsigned int index = cnt % MAX_DEBUG_LOG;
+ char *dst = RUBY_DEBUG_LOG_MEM_ENTRY(index);
+ strncpy(dst, buff, MAX_DEBUG_LOG_MESSAGE_LEN);
+ }
+ if (ruby_debug_log_mode & ruby_debug_log_stderr) {
+ fprintf(stderr, "%4u: %s\n", cnt, buff);
+ }
+ if (ruby_debug_log_mode & ruby_debug_log_file) {
+ fprintf(debug_log.output, "%u\t%s\n", cnt, buff);
+ }
+ }
+ rb_nativethread_lock_unlock(&debug_log.lock);
+}
+
+// for debugger
+static void
+debug_log_dump(FILE *out, unsigned int n)
+{
+ if (ruby_debug_log_mode & ruby_debug_log_memory) {
+ unsigned int size = debug_log.cnt > MAX_DEBUG_LOG ? MAX_DEBUG_LOG : debug_log.cnt;
+ unsigned int current_index = debug_log.cnt % MAX_DEBUG_LOG;
+ if (n == 0) n = size;
+ if (n > size) n = size;
+
+ for (unsigned int i=0; i<n; i++) {
+ int index = current_index - size + i;
+ if (index < 0) index += MAX_DEBUG_LOG;
+ VM_ASSERT(index <= MAX_DEBUG_LOG);
+ const char *mesg = RUBY_DEBUG_LOG_MEM_ENTRY(index);;
+ fprintf(out, "%4u: %s\n", debug_log.cnt - size + i, mesg);
+ }
+ }
+ else {
+ fprintf(stderr, "RUBY_DEBUG_LOG=mem is not specified.");
+ }
+}
+
+// for debuggers
+
+void
+ruby_debug_log_print(unsigned int n)
+{
+ debug_log_dump(stderr, n);
+}
+
+void
+ruby_debug_log_dump(const char *fname, unsigned int n)
+{
+ FILE *fp = fopen(fname, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "can't open %s. give up.\n", fname);
+ }
+ else {
+ debug_log_dump(fp, n);
+ fclose(fp);
+ }
}
+#endif // #if RUBY_DEVEL
diff --git a/debug_counter.c b/debug_counter.c
index 6000f98c54..e7b0bb0acd 100644
--- a/debug_counter.c
+++ b/debug_counter.c
@@ -9,10 +9,12 @@
**********************************************************************/
#include "debug_counter.h"
+#include "internal.h"
#include <stdio.h>
+#include <locale.h>
+#include "ruby/thread_native.h"
#if USE_DEBUG_COUNTER
-#include "internal.h"
static const char *const debug_counter_names[] = {
""
@@ -21,21 +23,138 @@ static const char *const debug_counter_names[] = {
#undef RB_DEBUG_COUNTER
};
+MJIT_SYMBOL_EXPORT_BEGIN
size_t rb_debug_counter[numberof(debug_counter_names)];
+void rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add);
+MJIT_SYMBOL_EXPORT_END
-__attribute__((destructor))
+rb_nativethread_lock_t debug_counter_lock;
+
+__attribute__((constructor))
static void
-rb_debug_counter_show_results(void)
+debug_counter_setup(void)
+{
+ rb_nativethread_lock_initialize(&debug_counter_lock);
+}
+
+void
+rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add)
+{
+ rb_nativethread_lock_lock(&debug_counter_lock);
+ {
+ rb_debug_counter[(int)type] += add;
+ }
+ rb_nativethread_lock_unlock(&debug_counter_lock);
+}
+
+int debug_counter_disable_show_at_exit = 0;
+
+// note that this operation is not atomic.
+void
+ruby_debug_counter_reset(void)
+{
+ for (int i = 0; i < RB_DEBUG_COUNTER_MAX; i++) {
+ switch (i) {
+ case RB_DEBUG_COUNTER_mjit_length_unit_queue:
+ case RB_DEBUG_COUNTER_mjit_length_active_units:
+ case RB_DEBUG_COUNTER_mjit_length_compact_units:
+ case RB_DEBUG_COUNTER_mjit_length_stale_units:
+ // These counters may be decreased and should not be reset.
+ break;
+ default:
+ rb_debug_counter[i] = 0;
+ break;
+ }
+ }
+}
+
+// note that this operation is not atomic.
+size_t
+ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
+{
+ int i;
+ if (names_ptr != NULL) {
+ for (i=0; i<RB_DEBUG_COUNTER_MAX; i++) {
+ names_ptr[i] = debug_counter_names[i];
+ }
+ }
+ if (counters_ptr != NULL) {
+ for (i=0; i<RB_DEBUG_COUNTER_MAX; i++) {
+ counters_ptr[i] = rb_debug_counter[i];
+ }
+ }
+
+ return RB_DEBUG_COUNTER_MAX;
+}
+
+void
+ruby_debug_counter_show_at_exit(int enable)
+{
+ debug_counter_disable_show_at_exit = !enable;
+}
+
+void
+rb_debug_counter_show_results(const char *msg)
{
const char *env = getenv("RUBY_DEBUG_COUNTER_DISABLE");
+
+ setlocale(LC_NUMERIC, "");
+
if (env == NULL || strcmp("1", env) != 0) {
int i;
+ fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%d %s\n", getpid(), msg);
for (i=0; i<RB_DEBUG_COUNTER_MAX; i++) {
- fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%s\t%"PRIuSIZE"\n",
+ fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%-30s\t%'14"PRIuSIZE"\n",
debug_counter_names[i],
rb_debug_counter[i]);
}
}
}
+VALUE
+rb_debug_counter_show(RB_UNUSED_VAR(VALUE klass))
+{
+ rb_debug_counter_show_results("show_debug_counters");
+ ruby_debug_counter_show_at_exit(FALSE);
+ return Qnil;
+}
+
+VALUE
+rb_debug_counter_reset(RB_UNUSED_VAR(VALUE klass))
+{
+ ruby_debug_counter_reset();
+ return Qnil;
+}
+
+__attribute__((destructor))
+static void
+debug_counter_show_results_at_exit(void)
+{
+ if (debug_counter_disable_show_at_exit == 0) {
+ rb_debug_counter_show_results("normal exit.");
+ }
+}
+
+#else
+
+void
+rb_debug_counter_show_results(const char *msg)
+{
+}
+
+size_t
+ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
+{
+ return 0;
+}
+void
+ruby_debug_counter_reset(void)
+{
+}
+
+void
+ruby_debug_counter_show_at_exit(int enable)
+{
+}
+
#endif /* USE_DEBUG_COUNTER */
diff --git a/debug_counter.h b/debug_counter.h
index f0f4e5ed0b..3c20821db6 100644
--- a/debug_counter.h
+++ b/debug_counter.h
@@ -14,18 +14,122 @@
#ifdef RB_DEBUG_COUNTER
-/* method search */
-RB_DEBUG_COUNTER(mc_inline_hit)
-RB_DEBUG_COUNTER(mc_inline_miss)
-RB_DEBUG_COUNTER(mc_global_hit)
-RB_DEBUG_COUNTER(mc_global_miss)
-RB_DEBUG_COUNTER(mc_global_state_miss)
-RB_DEBUG_COUNTER(mc_class_serial_miss)
-RB_DEBUG_COUNTER(mc_cme_complement)
-RB_DEBUG_COUNTER(mc_cme_complement_hit)
-RB_DEBUG_COUNTER(mc_search_super)
-
-/* ivar access */
+// method cache (IMC: inline method cache)
+RB_DEBUG_COUNTER(mc_inline_hit) // IMC hit
+RB_DEBUG_COUNTER(mc_inline_miss_klass) // IMC miss by different class
+RB_DEBUG_COUNTER(mc_inline_miss_invalidated) // IMC miss by invalidated ME
+RB_DEBUG_COUNTER(mc_inline_miss_empty) // IMC miss because prev is empty slot
+RB_DEBUG_COUNTER(mc_inline_miss_same_cc) // IMC miss, but same CC
+RB_DEBUG_COUNTER(mc_inline_miss_same_cme) // IMC miss, but same CME
+RB_DEBUG_COUNTER(mc_inline_miss_same_def) // IMC miss, but same definition
+RB_DEBUG_COUNTER(mc_inline_miss_diff) // IMC miss, different methods
+
+RB_DEBUG_COUNTER(mc_cme_complement) // number of acquiring complement CME
+RB_DEBUG_COUNTER(mc_cme_complement_hit) // number of cache hit for complemented CME
+
+RB_DEBUG_COUNTER(mc_search) // count for method lookup in class tree
+RB_DEBUG_COUNTER(mc_search_notfound) // method lookup, but not found
+RB_DEBUG_COUNTER(mc_search_super) // total traversed classes
+
+// callinfo
+RB_DEBUG_COUNTER(ci_packed) // number of packed CI
+RB_DEBUG_COUNTER(ci_kw) // non-packed CI w/ keywords
+RB_DEBUG_COUNTER(ci_nokw) // non-packed CI w/o keywords
+RB_DEBUG_COUNTER(ci_runtime) // creating temporary CI
+
+// callcache
+RB_DEBUG_COUNTER(cc_new) // number of CC
+RB_DEBUG_COUNTER(cc_temp) // dummy CC (stack-allocated)
+RB_DEBUG_COUNTER(cc_found_in_ccs) // count for CC lookup success in CCS
+RB_DEBUG_COUNTER(cc_not_found_in_ccs) // count for CC lookup success in CCS
+
+RB_DEBUG_COUNTER(cc_ent_invalidate) // count for invalidating cc (cc->klass = 0)
+RB_DEBUG_COUNTER(cc_cme_invalidate) // count for invalidating CME
+
+RB_DEBUG_COUNTER(cc_invalidate_leaf) // count for invalidating klass if klass has no-sublcasses
+RB_DEBUG_COUNTER(cc_invalidate_leaf_ccs) // corresponding CCS
+RB_DEBUG_COUNTER(cc_invalidate_leaf_callable) // complimented cache (no-subclasses)
+RB_DEBUG_COUNTER(cc_invalidate_tree) // count for invalidating klass if klass has sublcasses
+RB_DEBUG_COUNTER(cc_invalidate_tree_cme) // cme if cme is found in this class or superclasses
+RB_DEBUG_COUNTER(cc_invalidate_tree_callable) // complimented cache (subclasses)
+RB_DEBUG_COUNTER(cc_invalidate_negative) // count for invalidating negative cache
+
+RB_DEBUG_COUNTER(ccs_free) // count for free'ing ccs
+RB_DEBUG_COUNTER(ccs_maxlen) // maximum length of ccs
+RB_DEBUG_COUNTER(ccs_found) // count for finding corresponding ccs on method lookup
+RB_DEBUG_COUNTER(ccs_not_found) // count for not found corresponding ccs on method lookup
+
+// vm_eval.c
+RB_DEBUG_COUNTER(call0_public)
+RB_DEBUG_COUNTER(call0_other)
+RB_DEBUG_COUNTER(gccct_hit)
+RB_DEBUG_COUNTER(gccct_miss)
+RB_DEBUG_COUNTER(gccct_null)
+
+// iseq
+RB_DEBUG_COUNTER(iseq_num) // number of total created iseq
+RB_DEBUG_COUNTER(iseq_cd_num) // number of total created cd (call_data)
+
+/*
+ * call cache fastpath usage
+ */
+RB_DEBUG_COUNTER(ccf_general)
+RB_DEBUG_COUNTER(ccf_iseq_setup)
+RB_DEBUG_COUNTER(ccf_iseq_setup_0start)
+RB_DEBUG_COUNTER(ccf_iseq_setup_tailcall_0start)
+RB_DEBUG_COUNTER(ccf_iseq_fix) /* several functions created with tool/mk_call_iseq_optimized.rb */
+RB_DEBUG_COUNTER(ccf_iseq_opt) /* has_opt == TRUE (has optional parameters), but other flags are FALSE */
+RB_DEBUG_COUNTER(ccf_iseq_kw1) /* vm_call_iseq_setup_kwparm_kwarg() */
+RB_DEBUG_COUNTER(ccf_iseq_kw2) /* vm_call_iseq_setup_kwparm_nokwarg() */
+RB_DEBUG_COUNTER(ccf_cfunc)
+RB_DEBUG_COUNTER(ccf_cfunc_with_frame)
+RB_DEBUG_COUNTER(ccf_ivar) /* attr_reader */
+RB_DEBUG_COUNTER(ccf_attrset) /* attr_writer */
+RB_DEBUG_COUNTER(ccf_method_missing)
+RB_DEBUG_COUNTER(ccf_zsuper)
+RB_DEBUG_COUNTER(ccf_bmethod)
+RB_DEBUG_COUNTER(ccf_opt_send)
+RB_DEBUG_COUNTER(ccf_opt_call)
+RB_DEBUG_COUNTER(ccf_opt_block_call)
+RB_DEBUG_COUNTER(ccf_super_method)
+
+/*
+ * control frame push counts.
+ *
+ * * frame_push: frame push counts.
+ * * frame_push_*: frame push counts per each type.
+ * * frame_R2R: Ruby frame to Ruby frame
+ * * frame_R2C: Ruby frame to C frame
+ * * frame_C2C: C frame to C frame
+ * * frame_C2R: C frame to Ruby frame
+ */
+RB_DEBUG_COUNTER(frame_push)
+RB_DEBUG_COUNTER(frame_push_method)
+RB_DEBUG_COUNTER(frame_push_block)
+RB_DEBUG_COUNTER(frame_push_class)
+RB_DEBUG_COUNTER(frame_push_top)
+RB_DEBUG_COUNTER(frame_push_cfunc)
+RB_DEBUG_COUNTER(frame_push_ifunc)
+RB_DEBUG_COUNTER(frame_push_eval)
+RB_DEBUG_COUNTER(frame_push_rescue)
+RB_DEBUG_COUNTER(frame_push_dummy)
+
+RB_DEBUG_COUNTER(frame_R2R)
+RB_DEBUG_COUNTER(frame_R2C)
+RB_DEBUG_COUNTER(frame_C2C)
+RB_DEBUG_COUNTER(frame_C2R)
+
+/* instance variable counts
+ *
+ * * ivar_get_ic_hit/miss: ivar_get inline cache (ic) hit/miss counts (VM insn)
+ * * ivar_get_ic_miss_serial: ivar_get ic miss reason by serial (VM insn)
+ * * ivar_get_ic_miss_unset: ... by unset (VM insn)
+ * * ivar_get_ic_miss_noobject: ... by "not T_OBJECT" (VM insn)
+ * * ivar_set_...: same counts with ivar_set (VM insn)
+ * * ivar_get/set_base: call counts of "rb_ivar_get/set()".
+ * because of (1) ic miss.
+ * (2) direct call by C extensions.
+ */
RB_DEBUG_COUNTER(ivar_get_ic_hit)
RB_DEBUG_COUNTER(ivar_get_ic_miss)
RB_DEBUG_COUNTER(ivar_get_ic_miss_serial)
@@ -35,20 +139,103 @@ RB_DEBUG_COUNTER(ivar_set_ic_hit)
RB_DEBUG_COUNTER(ivar_set_ic_miss)
RB_DEBUG_COUNTER(ivar_set_ic_miss_serial)
RB_DEBUG_COUNTER(ivar_set_ic_miss_unset)
-RB_DEBUG_COUNTER(ivar_set_ic_miss_oorange)
+RB_DEBUG_COUNTER(ivar_set_ic_miss_iv_hit)
RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject)
RB_DEBUG_COUNTER(ivar_get_base)
RB_DEBUG_COUNTER(ivar_set_base)
-/* lvar access */
+/* local variable counts
+ *
+ * * lvar_get: total lvar get counts (VM insn)
+ * * lvar_get_dynamic: lvar get counts if accessing upper env (VM insn)
+ * * lvar_set*: same as "get"
+ * * lvar_set_slowpath: counts using vm_env_write_slowpath()
+ */
RB_DEBUG_COUNTER(lvar_get)
RB_DEBUG_COUNTER(lvar_get_dynamic)
RB_DEBUG_COUNTER(lvar_set)
RB_DEBUG_COUNTER(lvar_set_dynamic)
RB_DEBUG_COUNTER(lvar_set_slowpath)
-/* object counts */
+/* GC counts:
+ *
+ * * count: simple count
+ * * _minor: minor gc
+ * * _major: major gc
+ * * other suffix is corresponding to last_gc_info or
+ * gc_profile_record_flag in gc.c.
+ */
+RB_DEBUG_COUNTER(gc_count)
+RB_DEBUG_COUNTER(gc_minor_newobj)
+RB_DEBUG_COUNTER(gc_minor_malloc)
+RB_DEBUG_COUNTER(gc_minor_method)
+RB_DEBUG_COUNTER(gc_minor_capi)
+RB_DEBUG_COUNTER(gc_minor_stress)
+RB_DEBUG_COUNTER(gc_major_nofree)
+RB_DEBUG_COUNTER(gc_major_oldgen)
+RB_DEBUG_COUNTER(gc_major_shady)
+RB_DEBUG_COUNTER(gc_major_force)
+RB_DEBUG_COUNTER(gc_major_oldmalloc)
+
+RB_DEBUG_COUNTER(gc_enter_start)
+RB_DEBUG_COUNTER(gc_enter_mark_continue)
+RB_DEBUG_COUNTER(gc_enter_sweep_continue)
+RB_DEBUG_COUNTER(gc_enter_rest)
+RB_DEBUG_COUNTER(gc_enter_finalizer)
+
+RB_DEBUG_COUNTER(gc_isptr_trial)
+RB_DEBUG_COUNTER(gc_isptr_range)
+RB_DEBUG_COUNTER(gc_isptr_align)
+RB_DEBUG_COUNTER(gc_isptr_maybe)
+
+/* object allocation counts:
+ *
+ * * obj_newobj: newobj counts
+ * * obj_newobj_slowpath: newobj with slowpath counts
+ * * obj_newobj_wb_unprotected: newobj for wb_unprotected.
+ * * obj_free: obj_free() counts
+ * * obj_promote: promoted counts (oldgen)
+ * * obj_wb_unprotect: wb unprotect counts
+ *
+ * * obj_[type]_[attr]: *free'ed counts* for each type.
+ * Note that it is not a allocated counts.
+ * * [type]
+ * * _obj: T_OBJECT
+ * * _str: T_STRING
+ * * _ary: T_ARRAY
+ * * _xxx: T_XXX (hash, struct, ...)
+ *
+ * * [attr]
+ * * _ptr: R?? is not embed.
+ * * _embed: R?? is embed.
+ * * _transient: R?? uses transient heap.
+ * * type specific attr.
+ * * str_shared: str is shared.
+ * * str_nofree: nofree
+ * * str_fstr: fstr
+ * * hash_empty: hash is empty
+ * * hash_1_4: has 1 to 4 entries
+ * * hash_5_8: has 5 to 8 entries
+ * * hash_g8: has n entries (n>8)
+ * * match_under4: has under 4 oniguruma regions allocated
+ * * match_ge4: has n regions allocated (4<=n<8)
+ * * match_ge8: has n regions allocated (8<=n)
+ * * data_empty: T_DATA but no memory free.
+ * * data_xfree: free'ed by xfree().
+ * * data_imm_free: free'ed immediately.
+ * * data_zombie: free'ed with zombie.
+ * * imemo_*: T_IMEMO with each type.
+ */
+RB_DEBUG_COUNTER(obj_newobj)
+RB_DEBUG_COUNTER(obj_newobj_slowpath)
+RB_DEBUG_COUNTER(obj_newobj_wb_unprotected)
RB_DEBUG_COUNTER(obj_free)
+RB_DEBUG_COUNTER(obj_promote)
+RB_DEBUG_COUNTER(obj_wb_unprotect)
+
+RB_DEBUG_COUNTER(obj_obj_embed)
+RB_DEBUG_COUNTER(obj_obj_transient)
+RB_DEBUG_COUNTER(obj_obj_ptr)
RB_DEBUG_COUNTER(obj_str_ptr)
RB_DEBUG_COUNTER(obj_str_embed)
@@ -56,54 +243,219 @@ RB_DEBUG_COUNTER(obj_str_shared)
RB_DEBUG_COUNTER(obj_str_nofree)
RB_DEBUG_COUNTER(obj_str_fstr)
-RB_DEBUG_COUNTER(obj_ary_ptr)
RB_DEBUG_COUNTER(obj_ary_embed)
+RB_DEBUG_COUNTER(obj_ary_transient)
+RB_DEBUG_COUNTER(obj_ary_ptr)
+RB_DEBUG_COUNTER(obj_ary_extracapa)
+/*
+ ary_shared_create: shared ary by Array#dup and so on.
+ ary_shared: finished in shard.
+ ary_shared_root_occupied: shared_root but has only 1 refcnt.
+ The number (ary_shared - ary_shared_root_occupied) is meaningful.
+ */
+RB_DEBUG_COUNTER(obj_ary_shared_create)
+RB_DEBUG_COUNTER(obj_ary_shared)
+RB_DEBUG_COUNTER(obj_ary_shared_root_occupied)
-RB_DEBUG_COUNTER(obj_obj_ptr)
-RB_DEBUG_COUNTER(obj_obj_embed)
+RB_DEBUG_COUNTER(obj_hash_empty)
+RB_DEBUG_COUNTER(obj_hash_1)
+RB_DEBUG_COUNTER(obj_hash_2)
+RB_DEBUG_COUNTER(obj_hash_3)
+RB_DEBUG_COUNTER(obj_hash_4)
+RB_DEBUG_COUNTER(obj_hash_5_8)
+RB_DEBUG_COUNTER(obj_hash_g8)
+
+RB_DEBUG_COUNTER(obj_hash_null)
+RB_DEBUG_COUNTER(obj_hash_ar)
+RB_DEBUG_COUNTER(obj_hash_st)
+RB_DEBUG_COUNTER(obj_hash_transient)
+RB_DEBUG_COUNTER(obj_hash_force_convert)
+
+RB_DEBUG_COUNTER(obj_struct_embed)
+RB_DEBUG_COUNTER(obj_struct_transient)
+RB_DEBUG_COUNTER(obj_struct_ptr)
+
+RB_DEBUG_COUNTER(obj_data_empty)
+RB_DEBUG_COUNTER(obj_data_xfree)
+RB_DEBUG_COUNTER(obj_data_imm_free)
+RB_DEBUG_COUNTER(obj_data_zombie)
+
+RB_DEBUG_COUNTER(obj_match_under4)
+RB_DEBUG_COUNTER(obj_match_ge4)
+RB_DEBUG_COUNTER(obj_match_ge8)
+RB_DEBUG_COUNTER(obj_match_ptr)
+
+RB_DEBUG_COUNTER(obj_iclass_ptr)
+RB_DEBUG_COUNTER(obj_class_ptr)
+RB_DEBUG_COUNTER(obj_module_ptr)
-/* load */
+RB_DEBUG_COUNTER(obj_bignum_ptr)
+RB_DEBUG_COUNTER(obj_bignum_embed)
+RB_DEBUG_COUNTER(obj_float)
+RB_DEBUG_COUNTER(obj_complex)
+RB_DEBUG_COUNTER(obj_rational)
+
+RB_DEBUG_COUNTER(obj_regexp_ptr)
+RB_DEBUG_COUNTER(obj_file_ptr)
+RB_DEBUG_COUNTER(obj_symbol)
+
+RB_DEBUG_COUNTER(obj_imemo_ment)
+RB_DEBUG_COUNTER(obj_imemo_iseq)
+RB_DEBUG_COUNTER(obj_imemo_env)
+RB_DEBUG_COUNTER(obj_imemo_tmpbuf)
+RB_DEBUG_COUNTER(obj_imemo_ast)
+RB_DEBUG_COUNTER(obj_imemo_cref)
+RB_DEBUG_COUNTER(obj_imemo_svar)
+RB_DEBUG_COUNTER(obj_imemo_throw_data)
+RB_DEBUG_COUNTER(obj_imemo_ifunc)
+RB_DEBUG_COUNTER(obj_imemo_memo)
+RB_DEBUG_COUNTER(obj_imemo_parser_strterm)
+RB_DEBUG_COUNTER(obj_imemo_callinfo)
+RB_DEBUG_COUNTER(obj_imemo_callcache)
+RB_DEBUG_COUNTER(obj_imemo_constcache)
+
+/* ar_table */
+RB_DEBUG_COUNTER(artable_hint_hit)
+RB_DEBUG_COUNTER(artable_hint_miss)
+RB_DEBUG_COUNTER(artable_hint_notfound)
+
+/* heap function counts
+ *
+ * * heap_xmalloc/realloc/xfree: call counts
+ */
+RB_DEBUG_COUNTER(heap_xmalloc)
+RB_DEBUG_COUNTER(heap_xrealloc)
+RB_DEBUG_COUNTER(heap_xfree)
+
+/* transient_heap */
+RB_DEBUG_COUNTER(theap_alloc)
+RB_DEBUG_COUNTER(theap_alloc_fail)
+RB_DEBUG_COUNTER(theap_evacuate)
+
+// VM sync
+RB_DEBUG_COUNTER(vm_sync_lock)
+RB_DEBUG_COUNTER(vm_sync_lock_enter)
+RB_DEBUG_COUNTER(vm_sync_lock_enter_nb)
+RB_DEBUG_COUNTER(vm_sync_lock_enter_cr)
+RB_DEBUG_COUNTER(vm_sync_barrier)
+
+/* mjit_exec() counts */
+RB_DEBUG_COUNTER(mjit_exec)
+RB_DEBUG_COUNTER(mjit_exec_not_added)
+RB_DEBUG_COUNTER(mjit_exec_not_ready)
+RB_DEBUG_COUNTER(mjit_exec_not_compiled)
+RB_DEBUG_COUNTER(mjit_exec_call_func)
+
+/* MJIT enqueue / unload */
+RB_DEBUG_COUNTER(mjit_add_iseq_to_process)
+RB_DEBUG_COUNTER(mjit_unload_units)
+
+/* MJIT <-> VM frame push counts */
+RB_DEBUG_COUNTER(mjit_frame_VM2VM)
+RB_DEBUG_COUNTER(mjit_frame_VM2JT)
+RB_DEBUG_COUNTER(mjit_frame_JT2JT)
+RB_DEBUG_COUNTER(mjit_frame_JT2VM)
+
+/* MJIT cancel counters */
+RB_DEBUG_COUNTER(mjit_cancel)
+RB_DEBUG_COUNTER(mjit_cancel_ivar_inline)
+RB_DEBUG_COUNTER(mjit_cancel_exivar_inline)
+RB_DEBUG_COUNTER(mjit_cancel_send_inline)
+RB_DEBUG_COUNTER(mjit_cancel_opt_insn) /* CALL_SIMPLE_METHOD */
+RB_DEBUG_COUNTER(mjit_cancel_invalidate_all)
+RB_DEBUG_COUNTER(mjit_cancel_leave)
+
+/* rb_mjit_unit_list length */
+RB_DEBUG_COUNTER(mjit_length_unit_queue)
+RB_DEBUG_COUNTER(mjit_length_active_units)
+RB_DEBUG_COUNTER(mjit_length_compact_units)
+RB_DEBUG_COUNTER(mjit_length_stale_units)
+
+/* Other MJIT counters */
+RB_DEBUG_COUNTER(mjit_compile_failures)
+
+/* load (not implemented yet) */
+/*
RB_DEBUG_COUNTER(load_files)
RB_DEBUG_COUNTER(load_path_is_not_realpath)
-
+*/
#endif
#ifndef RUBY_DEBUG_COUNTER_H
#define RUBY_DEBUG_COUNTER_H 1
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "ruby/ruby.h" /* for VALUE */
+
#if !defined(__GNUC__) && USE_DEBUG_COUNTER
#error "USE_DEBUG_COUNTER is not supported by other than __GNUC__"
#endif
enum rb_debug_counter_type {
#define RB_DEBUG_COUNTER(name) RB_DEBUG_COUNTER_##name,
-#include "debug_counter.h"
+#include __FILE__
RB_DEBUG_COUNTER_MAX
#undef RB_DEBUG_COUNTER
};
#if USE_DEBUG_COUNTER
-#include "ruby/ruby.h"
-
extern size_t rb_debug_counter[];
+RUBY_EXTERN struct rb_ractor_struct *ruby_single_main_ractor;
+RUBY_EXTERN void rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add);
inline static int
rb_debug_counter_add(enum rb_debug_counter_type type, int add, int cond)
{
if (cond) {
- rb_debug_counter[(int)type] += add;
+ if (ruby_single_main_ractor != NULL) {
+ rb_debug_counter[(int)type] += add;
+ }
+ else {
+ rb_debug_counter_add_atomic(type, add);
+ }
}
return cond;
}
+inline static int
+rb_debug_counter_max(enum rb_debug_counter_type type, unsigned int num)
+{
+ // TODO: sync
+ if (rb_debug_counter[(int)type] < num) {
+ rb_debug_counter[(int)type] = num;
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+VALUE rb_debug_counter_reset(VALUE klass);
+VALUE rb_debug_counter_show(VALUE klass);
+
#define RB_DEBUG_COUNTER_INC(type) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, 1)
#define RB_DEBUG_COUNTER_INC_UNLESS(type, cond) (!rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, !(cond)))
-#define RB_DEBUG_COUNTER_INC_IF(type, cond) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, (cond))
+#define RB_DEBUG_COUNTER_INC_IF(type, cond) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, !!(cond))
+#define RB_DEBUG_COUNTER_ADD(type, num) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, (num), 1)
+#define RB_DEBUG_COUNTER_SETMAX(type, num) rb_debug_counter_max(RB_DEBUG_COUNTER_##type, (unsigned int)(num))
#else
#define RB_DEBUG_COUNTER_INC(type) ((void)0)
-#define RB_DEBUG_COUNTER_INC_UNLESS(type, cond) (cond)
-#define RB_DEBUG_COUNTER_INC_IF(type, cond) (cond)
+#define RB_DEBUG_COUNTER_INC_UNLESS(type, cond) (!!(cond))
+#define RB_DEBUG_COUNTER_INC_IF(type, cond) (!!(cond))
+#define RB_DEBUG_COUNTER_ADD(type, num) ((void)0)
+#define RB_DEBUG_COUNTER_SETMAX(type, num) 0
#endif
+void rb_debug_counter_show_results(const char *msg);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+
+size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr);
+void ruby_debug_counter_reset(void);
+void ruby_debug_counter_show_at_exit(int enable);
+
+RUBY_SYMBOL_EXPORT_END
+
#endif /* RUBY_DEBUG_COUNTER_H */
diff --git a/defs/gmake.mk b/defs/gmake.mk
index 5305790e6f..f093fd4e26 100644
--- a/defs/gmake.mk
+++ b/defs/gmake.mk
@@ -1,8 +1,10 @@
-# -*- makefile-gmake -*-
-gnumake = yes
+# -*- mode: makefile-gmake; indent-tabs-mode: t -*-
+
+reconfig config.status: export MAKE:=$(MAKE)
override gnumake_recursive := $(if $(findstring n,$(firstword $(MFLAGS))),,+)
override mflags := $(filter-out -j%,$(MFLAGS))
MSPECOPT += $(if $(filter -j%,$(MFLAGS)),-j)
+nproc = $(subst -j,,$(filter -j%,$(MFLAGS)))
CHECK_TARGETS := great exam love check test check% test% btest%
# expand test targets, and those dependents
@@ -10,17 +12,22 @@ TEST_TARGETS := $(filter $(CHECK_TARGETS),$(MAKECMDGOALS))
TEST_DEPENDS := $(filter-out commit $(TEST_TARGETS),$(MAKECMDGOALS))
TEST_TARGETS := $(patsubst great,exam,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out great $(TEST_TARGETS),$(TEST_DEPENDS))
-TEST_TARGETS := $(patsubst exam,check test-rubyspec,$(TEST_TARGETS))
+TEST_TARGETS := $(patsubst exam,check,$(TEST_TARGETS))
+TEST_TARGETS := $(patsubst check,test-spec test-all test-tool test-short,$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-rubyspec,test-spec,$(TEST_TARGETS))
-TEST_DEPENDS := $(filter-out exam $(TEST_TARGETS),$(TEST_DEPENDS))
+TEST_DEPENDS := $(filter-out exam check test-spec $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_TARGETS := $(patsubst love,check,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out love $(TEST_TARGETS),$(TEST_DEPENDS))
-TEST_TARGETS := $(patsubst check,test test-testframework test-almost,$(patsubst check-%,test test-%,$(TEST_TARGETS)))
-TEST_DEPENDS := $(filter-out check $(TEST_TARGETS),$(TEST_DEPENDS))
-TEST_TARGETS := $(patsubst test,btest-ruby test-knownbug test-basic,$(TEST_TARGETS))
+TEST_TARGETS := $(patsubst test-almost,test-all,$(patsubst check-%,test test-%,$(TEST_TARGETS)))
+TEST_DEPENDS := $(filter-out test-all $(TEST_TARGETS),$(TEST_DEPENDS))
+TEST_TARGETS := $(patsubst test,test-short,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out test $(TEST_TARGETS),$(TEST_DEPENDS))
+TEST_TARGETS := $(patsubst test-short,btest-ruby test-knownbug test-basic,$(TEST_TARGETS))
+TEST_DEPENDS := $(filter-out test-short $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_DEPENDS += $(if $(filter great exam love check,$(MAKECMDGOALS)),all exts)
+in-srcdir := $(if $(filter-out .,$(srcdir)),$(CHDIR) $(srcdir) &&)
+
ifneq ($(filter -O0 -Od,$(optflags)),)
override XCFLAGS := $(filter-out -D_FORTIFY_SOURCE=%,$(XCFLAGS))
endif
@@ -48,7 +55,7 @@ define archcmd
%.i: %.$(1).i
endef
-$(foreach arch,$(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG))),\
+$(foreach arch,$(arch_flags),\
$(eval $(call archcmd,$(patsubst -arch=%,%,$(value arch)),$(patsubst -arch=%,-arch %,$(value arch)))))
endif
@@ -60,8 +67,8 @@ endif
ORDERED_TEST_TARGETS := $(filter $(TEST_TARGETS), \
btest-ruby test-knownbug test-basic \
- test-testframework test-ruby test-almost test-all \
- test-spec test-bundler-prepare test-bundler \
+ test-testframework test-tool test-ruby test-all \
+ test-spec test-bundler-prepare test-bundler test-bundler-parallel \
)
prev_test := $(if $(filter test-spec,$(ORDERED_TEST_TARGETS)),test-spec-precheck)
$(foreach test,$(ORDERED_TEST_TARGETS), \
@@ -83,18 +90,18 @@ showflags: up
sudo-precheck: test yes-test-testframework no-test-testframework
install-prereq: sudo-precheck
yes-test-all no-test-all: install
-yes-test-almost no-test-almost: install
-endif
-ifneq ($(filter great,$(MAKECMDGOALS)),)
-love: test-rubyspec
endif
+yes-test-bundler-parallel: PARALLELRSPECOPTS += $(if $(nproc),-n$(shell expr $(nproc) + $(nproc) / 2))
+
+# Cross reference needs to parse all files at once
+love install reinstall: RDOCFLAGS = --force-update
$(srcdir)/missing/des_tables.c: $(srcdir)/missing/crypt.c
ifeq ($(if $(filter yes,$(CROSS_COMPILING)),,$(CC)),)
touch $@
else
@$(ECHO) building make_des_table
- $(CC) $(CPPFLAGS) -DDUMP $(LDFLAGS) $(XLDFLAGS) $(LIBS) -omake_des_table $(srcdir)/missing/crypt.c
+ $(CC) $(INCFLAGS) $(CPPFLAGS) -DDUMP $(LDFLAGS) $(XLDFLAGS) $(LIBS) -omake_des_table $(srcdir)/missing/crypt.c
@[ -x ./make_des_table ]
@$(ECHO) generating $@
$(Q) $(MAKEDIRS) $(@D)
@@ -103,10 +110,12 @@ else
$(Q) $(RMALL) make_des_table*
endif
+config.status: $(wildcard config.cache)
+
STUBPROGRAM = rubystub$(EXEEXT)
IGNOREDPATTERNS = %~ .% %.orig %.rej \#%\#
SCRIPTBINDIR := $(if $(EXEEXT),,exec/)
-SCRIPTPROGRAMS = $(addprefix $(SCRIPTBINDIR),$(addsuffix $(EXEEXT),$(filter-out $(IGNOREDPATTERNS),$(notdir $(wildcard $(srcdir)/bin/*)))))
+SCRIPTPROGRAMS = $(addprefix $(SCRIPTBINDIR),$(addsuffix $(EXEEXT),$(filter-out $(IGNOREDPATTERNS),$(notdir $(wildcard $(srcdir)/libexec/*)))))
stub: $(STUBPROGRAM)
scriptbin: $(SCRIPTPROGRAMS)
@@ -137,10 +146,251 @@ $(TIMESTAMPDIR)/.exec.time:
$(Q) exit > $@
.PHONY: commit
-commit: $(if $(filter commit,$(MAKECMDGOALS)),$(filter-out commit,$(MAKECMDGOALS)))
- @$(BASERUBY) -C "$(srcdir)" -I./tool -rvcs -e 'VCS.detect(".").commit'
- $(Q)$(MAKE) $(mflags) Q=$(Q) REVISION_FORCE=PHONY update-src srcs all-incs
+commit: $(if $(filter commit,$(MAKECMDGOALS)),$(filter-out commit,$(MAKECMDGOALS))) up
+ @$(BASERUBY) -C "$(srcdir)" -I./tool/lib -rvcs -e 'VCS.detect(".").commit'
+ +$(Q) \
+ { \
+ $(in-srcdir) \
+ exec sed -f tool/prereq.status defs/gmake.mk template/Makefile.in common.mk; \
+ } | \
+ $(MAKE) $(mflags) Q=$(Q) ECHO=$(ECHO) srcdir="$(srcdir)" srcs_vpath="" CHDIR="$(CHDIR)" \
+ BOOTSTRAPRUBY="$(BOOTSTRAPRUBY)" MINIRUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" \
+ VCSUP="" ENC_MK=.top-enc.mk REVISION_FORCE=PHONY CONFIGURE="$(CONFIGURE)" -f - \
+ update-src srcs all-incs
+
+GITHUB_RUBY_URL = https://github.com/ruby/ruby
+PR =
+
+COMMIT_GPG_SIGN = $(shell git -C "$(srcdir)" config commit.gpgsign)
+REMOTE_GITHUB_URL = $(shell git -C "$(srcdir)" config remote.github.url)
+COMMITS_NOTES = commits
+
+.PHONY: fetch-github
+fetch-github:
+ $(call fetch-github,$(PR))
+
+define fetch-github
+ $(if $(1),,\
+ echo "usage:"; echo " make $@ PR=1234"; \
+ exit 1; \
+ )
+ $(eval REMOTE_GITHUB_URL := $(REMOTE_GITHUB_URL))
+ $(if $(REMOTE_GITHUB_URL),, \
+ echo adding $(GITHUB_RUBY_URL) as remote github; \
+ git -C "$(srcdir)" remote add github $(GITHUB_RUBY_URL); \
+ git -C "$(srcdir)" config --add remote.github.fetch +refs/notes/$(COMMITS_NOTES):refs/notes/$(COMMITS_NOTES)
+ $(eval REMOTE_GITHUB_URL := $(GITHUB_RUBY_URL)) \
+ )
+ $(if $(git -C "$(srcdir)" rev-parse "github/pull/$(1)/head" -- 2> /dev/null), \
+ git -C "$(srcdir)" branch -f "gh-$(1)" "github/pull/$(1)/head", \
+ git -C "$(srcdir)" fetch -f github "pull/$(1)/head:gh-$(1)" \
+ )
+endef
+
+.PHONY: checkout-github
+checkout-github: fetch-github
+ git -C "$(srcdir)" checkout "gh-$(PR)"
+
+.PHONY: update-github
+update-github: fetch-github
+ $(eval PULL_REQUEST_API := https://api.github.com/repos/ruby/ruby/pulls/$(PR))
+ $(eval PULL_REQUEST_FORK_BRANCH := $(shell \
+ curl -s $(if $(GITHUB_TOKEN),-H "Authorization: bearer $(GITHUB_TOKEN)") $(PULL_REQUEST_API) | \
+ $(BASERUBY) -rjson -e 'JSON.parse(STDIN.read)["head"].tap { |h| print "#{h["repo"]["full_name"]} #{h["ref"]}" }' \
+ ))
+ $(eval FORK_REPO := $(word 1,$(PULL_REQUEST_FORK_BRANCH)))
+ $(eval PR_BRANCH := $(word 2,$(PULL_REQUEST_FORK_BRANCH)))
+
+ $(eval GITHUB_UPDATE_WORKTREE := $(shell mktemp -d "$(srcdir)/gh-$(PR)-XXXXXX"))
+ git -C "$(srcdir)" worktree add $(notdir $(GITHUB_UPDATE_WORKTREE)) "gh-$(PR)"
+ git -C "$(GITHUB_UPDATE_WORKTREE)" merge master --no-edit
+ @$(BASERUBY) -e 'print "Are you sure to push this to PR=$(PR)? [Y/n]: "; exit(gets.chomp != "n")'
+ git -C "$(srcdir)" remote add fork-$(PR) git@github.com:$(FORK_REPO).git
+ git -C "$(GITHUB_UPDATE_WORKTREE)" push fork-$(PR) gh-$(PR):$(PR_BRANCH)
+ git -C "$(srcdir)" remote rm fork-$(PR)
+ git -C "$(srcdir)" worktree remove $(notdir $(GITHUB_UPDATE_WORKTREE))
+ git -C "$(srcdir)" branch -D gh-$(PR)
+
+.PHONY: pull-github
+pull-github: fetch-github
+ $(call pull-github,$(PR))
+
+define pull-github
+ $(eval GITHUB_MERGE_BASE := $(shell git -C "$(srcdir)" log -1 --format=format:%H))
+ $(eval GITHUB_MERGE_BRANCH := $(shell git -C "$(srcdir)" symbolic-ref --short HEAD))
+ $(eval GITHUB_MERGE_WORKTREE := $(shell mktemp -d "$(srcdir)/gh-$(1)-XXXXXX"))
+ git -C "$(srcdir)" worktree add $(notdir $(GITHUB_MERGE_WORKTREE)) "gh-$(1)"
+ git -C "$(GITHUB_MERGE_WORKTREE)" rebase $(GITHUB_MERGE_BRANCH)
+ $(eval COMMIT_GPG_SIGN := $(COMMIT_GPG_SIGN))
+ $(if $(filter true,$(COMMIT_GPG_SIGN)), \
+ git -C "$(GITHUB_MERGE_WORKTREE)" rebase --exec "git commit --amend --no-edit -S" "$(GITHUB_MERGE_BASE)"; \
+ )
+ git -C "$(GITHUB_MERGE_WORKTREE)" rebase --exec "git notes add --message 'Merged: $(GITHUB_RUBY_URL)/pull/$(1)'" "$(GITHUB_MERGE_BASE)"
+endef
+
+.PHONY: fetch-github-%
+fetch-github-%:
+ $(call fetch-github,$*)
+
+.PHONY: checkout-github-%
+checkout-github-%: fetch-github-%
+ git -C "$(srcdir)" checkout "gh-$*"
+
+.PHONY: pr-% pull-github-%
+pr-% pull-github-%: fetch-github-%
+ $(call pull-github,$*)
+
+HELP_EXTRA_TASKS = \
+ " checkout-github: checkout GitHub Pull Request [PR=1234]" \
+ " pull-github: rebase GitHub Pull Request to new worktree [PR=1234]" \
+ " update-github: merge master branch and push it to Pull Request [PR=1234]" \
+ ""
+
+extract-gems: $(HAVE_BASERUBY:yes=update-gems)
+
+bundled-gems := $(shell sed '/^[ ]*\#/d;/^[ ]*$$/d;s/[ ][ ]*/-/;s/[ ].*//' $(srcdir)/gems/bundled_gems)
+
+update-gems: | $(patsubst %,gems/%.gem,$(bundled-gems))
+
+test-bundler-precheck: | $(srcdir)/.bundle/cache
-ifeq ($(words $(filter update-gems extract-gems,$(MAKECMDGOALS))),2)
-extract-gems: update-gems
+$(srcdir)/.bundle/cache:
+ $(MAKEDIRS) $(@D) $(CACHE_DIR)
+ $(LN_S) ../.downloaded-cache $@
+
+gems/%.gem:
+ $(ECHO) Downloading bundled gem $*...
+ $(Q) $(BASERUBY) -C "$(srcdir)" \
+ -I./tool -rdownloader \
+ -e 'gem = "$(@F)"' \
+ -e 'old = Dir.glob("gems/"+gem.sub(/-[^-]*$$/, "-*.gem"))' \
+ -e 'Downloader::RubyGems.download(gem, "gems", nil) and' \
+ -e '(old.delete("gems/#{gem}"); !old.empty?) and' \
+ -e 'File.unlink(*old) and' \
+ -e 'FileUtils.rm_rf(old.map{'"|n|"'n.chomp(".gem")})'
+
+extract-gems: | $(patsubst %,.bundle/gems/%,$(bundled-gems))
+
+.bundle/gems/%: gems/%.gem | .bundle/gems
+ $(ECHO) Extracting bundle gem $*...
+ $(Q) $(BASERUBY) -C "$(srcdir)" \
+ -Itool -rgem-unpack \
+ -e 'Gem.unpack("gems/$(@F).gem", ".bundle/gems")'
+
+$(srcdir)/.bundle/gems:
+ $(MAKEDIRS) $@
+
+ifneq ($(filter update-bundled_gems refresh-gems,$(MAKECMDGOALS)),)
+update-gems: update-bundled_gems
+endif
+
+ifeq ($(filter 0 1,$(words $(arch_flags))),)
+$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \
+ $(eval $$(MJIT_HEADER:.h=)-$(value x).h \
+ $$(MJIT_MIN_HEADER:.h=)-$(value x).h \
+ $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time \
+ : ARCH_FLAG := -arch $(value x)))
+
+$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \
+ $(eval $$(MJIT_HEADER:.h=)-$(value x).h: \
+ $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time))
+
+mjit_min_headers := $(patsubst -arch=%,$(MJIT_MIN_HEADER:.h=-%.h),$(arch_flags))
+$(MJIT_MIN_HEADER): $(mjit_min_headers) $(PREP)
+ @ set -e; set $(patsubst -arch=%,%,$(arch_flags)); \
+ cd $(@D); h=$(@F:.h=); \
+ exec > $(@F).new; \
+ echo '#if 0'; \
+ for arch; do\
+ echo "#elif defined __$${arch}__"; \
+ echo "# include \"$$h-$$arch.h\""; \
+ done; \
+ echo "#else"; echo "# error unsupported platform"; echo "#endif"
+ $(IFCHANGE) $@ $@.new
+ $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR)
+ $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F)
+
+endif
+
+ifeq ($(if $(wildcard $(filter-out .,$(UNICODE_FILES) $(UNICODE_PROPERTY_FILES))),,\
+ $(wildcard $(srcdir)/lib/unicode_normalize/tables.rb)),)
+# Needs the dependency when any Unicode data file exists, or
+# normalization tables script doesn't. Otherwise, when the target
+# only exists, use it as-is.
+.PHONY: $(UNICODE_SRC_DATA_DIR)/.unicode-tables.time
+UNICODE_TABLES_TIMESTAMP =
+$(UNICODE_SRC_DATA_DIR)/.unicode-tables.time: \
+ $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES)
+endif
+
+REVISION_IN_HEADER := $(shell sed -n 's/^\#define RUBY_FULL_REVISION "\(.*\)"/\1/p' $(srcdir)/revision.h 2>/dev/null)
+REVISION_LATEST := $(shell $(CHDIR) $(srcdir) && git log -1 --format=%H 2>/dev/null)
+ifneq ($(REVISION_IN_HEADER),$(REVISION_LATEST))
+# GNU make treat the target as unmodified when its dependents get
+# updated but it is not updated, while others may not.
+$(srcdir)/revision.h: $(REVISION_H)
endif
+
+# Query on the generated rdoc
+#
+# $ make rdoc:Integer#+
+rdoc\:%: PHONY
+ $(Q)$(RUNRUBY) $(srcdir)/libexec/ri --no-standard-docs --doc-dir=$(RDOCOUT) $(patsubst rdoc:%,%,$@)
+
+test_%.rb test/%: programs PHONY
+ $(Q)$(exec) $(RUNRUBY) "$(TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" $(TEST_EXCLUDES) $(TESTOPTS) -- $(patsubst test/%,%,$@)
+
+spec/bundler/%: PHONY
+ $(Q)$(exec) $(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec --require spec_helper $(RSPECOPTS) $@
+
+spec/bundler: test-bundler-parallel
+ $(Q)$(NULLCMD)
+
+spec/%: programs exts PHONY
+ $(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec-run -B $(srcdir)/spec/default.mspec $(SPECOPTS) $(patsubst %,$(srcdir)/%,$@)
+
+benchmark/%: miniruby$(EXEEXT) update-benchmark-driver PHONY
+ $(Q)$(BASERUBY) -rrubygems -I$(srcdir)/benchmark/lib $(srcdir)/benchmark/benchmark-driver/exe/benchmark-driver \
+ --executables="compare-ruby::$(COMPARE_RUBY) -I$(EXTOUT)/common --disable-gem" \
+ --executables="built-ruby::$(BENCH_RUBY) --disable-gem" \
+ $(srcdir)/$@ $(BENCH_OPTS) $(OPTS)
+
+clean-srcs-ext::
+ $(Q)$(RM) $(patsubst $(srcdir)/%,%,$(EXT_SRCS))
+
+clean-srcs-extra::
+ $(Q)$(RM) $(patsubst $(srcdir)/%,%,$(EXTRA_SRCS))
+
+ifneq ($(filter $(VCS),git),)
+update-src::
+ @$(BASERUBY) $(tooldir)/lib/colorize.rb pass "Latest commit hash = $(shell $(filter-out svn,$(VCS)) -C $(srcdir) rev-parse --short=10 HEAD)"
+endif
+
+# Update dependencies and commit the updates to the current branch.
+update-deps:
+ $(eval update_deps := $(shell date +update-deps-%Y%m%d))
+ $(eval deps_dir := $(shell mktemp -d)/$(update_deps))
+ $(eval GIT_DIR := $(shell git -C $(srcdir) rev-parse --absolute-git-dir))
+ git --git-dir=$(GIT_DIR) worktree add $(deps_dir)
+ cp $(tooldir)/config.guess $(tooldir)/config.sub $(deps_dir)/tool
+ [ -f config.status ] && cp config.status $(deps_dir)
+ cd $(deps_dir) && autoconf && \
+ exec ./configure -q -C --enable-load-relative --disable-install-doc --disable-rubygems 'optflags=-O0' 'debugflags=-save-temps=obj -g'
+ $(RUNRUBY) -C $(deps_dir) tool/update-deps --fix
+ git -C $(deps_dir) diff --no-ext-diff --ignore-submodules --exit-code || \
+ git -C $(deps_dir) commit --all --message='Update dependencies'
+ git --git-dir=$(GIT_DIR) worktree remove $(deps_dir)
+ $(RMDIR) $(dir $(deps_dir))
+ git --git-dir=$(GIT_DIR) merge --no-edit --ff-only $(update_deps)
+ git --git-dir=$(GIT_DIR) branch --delete $(update_deps)
+
+# order-only-prerequisites doesn't work for $(RUBYSPEC_CAPIEXT)
+# because the same named directory exists in the source tree.
+$(RUBYSPEC_CAPIEXT)/%.$(DLEXT): $(srcdir)/$(RUBYSPEC_CAPIEXT)/%.c $(srcdir)/$(RUBYSPEC_CAPIEXT)/rubyspec.h $(RUBY_H_INCLUDES) $(LIBRUBY_SO)
+ $(ECHO) building $@
+ $(Q) $(MAKEDIRS) $(@D)
+ $(Q) $(DLDSHARED) $(XDLDFLAGS) $(XLDFLAGS) $(ARCH_FLAG) $(ARCH_FLAG) $(CFLAGS) $(INCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ $< $(LIBRUBY_SO)
+ $(Q) $(RMALL) $@.*
+
+rubyspec-capiext: $(patsubst %.c,$(RUBYSPEC_CAPIEXT)/%.$(DLEXT),$(notdir $(wildcard $(srcdir)/$(RUBYSPEC_CAPIEXT)/*.c)))
+ @ $(NULLCMD)
diff --git a/defs/id.def b/defs/id.def
index f30b993bd9..fc7a04ffbc 100644
--- a/defs/id.def
+++ b/defs/id.def
@@ -3,6 +3,7 @@ firstline, predefined = __LINE__+1, %[\
max
min
freeze
+ nil?
inspect
intern
object_id
@@ -38,17 +39,37 @@ firstline, predefined = __LINE__+1, %[\
to_a
to_s
to_i
+ to_f
to_r
bt
bt_locations
call
mesg
exception
+ locals
not NOT
and AND
or OR
+ div
+ divmod
+ fdiv
+ quo
+ name
+ nil
_ UScore
+
+ # MUST be successive
+ _1 NUMPARAM_1
+ _2 NUMPARAM_2
+ _3 NUMPARAM_3
+ _4 NUMPARAM_4
+ _5 NUMPARAM_5
+ _6 NUMPARAM_6
+ _7 NUMPARAM_7
+ _8 NUMPARAM_8
+ _9 NUMPARAM_9
+
"/*NULL*/" NULL
empty?
eql?
@@ -62,21 +83,23 @@ firstline, predefined = __LINE__+1, %[\
core#define_method
core#define_singleton_method
core#set_postexe
- core#hash_from_ary
- core#hash_merge_ary
core#hash_merge_ptr
core#hash_merge_kwd
+ core#raise
- debug#created_info
$_ LASTLINE
$~ BACKREF
+ $! ERROR_INFO
]
# VM ID OP Parser Token
token_ops = %[\
Dot2 .. DOT2
Dot3 ... DOT3
+ BDot2 .. BDOT2
+ BDot3 ... BDOT3
UPlus +@ UPLUS
UMinus -@ UMINUS
Pow ** POW
@@ -96,6 +119,8 @@ token_ops = %[\
Eqq === EQQ
Neq != NEQ
Not !
+ And &
+ Or |
Backquote `
EqTilde =~ MATCH
NeqTilde !~ NMATCH
diff --git a/defs/keywords b/defs/keywords
index e0d931cd1f..fc30ec2d15 100644
--- a/defs/keywords
+++ b/defs/keywords
@@ -1,8 +1,8 @@
%{
-struct kwtable {int name, id[2], state;};
+struct kwtable {short name, id[2], state;};
const struct kwtable *rb_reserved_word(const char *, unsigned int);
#ifndef RIPPER
-static const struct kwtable *reserved_word(const char *, unsigned int);
+static const struct kwtable *reserved_word(/*!ANSI{*/const char *, unsigned int/*}!ANSI*/);
#define rb_reserved_word(str, len) reserved_word(str, len)
%}
diff --git a/defs/known_errors.def b/defs/known_errors.def
index b9c490d3a2..e9694cfbda 100644
--- a/defs/known_errors.def
+++ b/defs/known_errors.def
@@ -1,148 +1,157 @@
-EPERM
-ENOENT
-ESRCH
-EINTR
-EIO
-ENXIO
E2BIG
-ENOEXEC
-EBADF
-ECHILD
-EAGAIN
-ENOMEM
EACCES
-EFAULT
-ENOTBLK
-EBUSY
-EEXIST
-EXDEV
-ENODEV
-ENOTDIR
-EISDIR
-EINVAL
-ENFILE
-EMFILE
-ENOTTY
-ETXTBSY
-EFBIG
-ENOSPC
-ESPIPE
-EROFS
-EMLINK
-EPIPE
-EDOM
-ERANGE
-EDEADLK
-ENAMETOOLONG
-ENOLCK
-ENOSYS
-ENOTEMPTY
-ELOOP
-EWOULDBLOCK
-ENOMSG
-EIDRM
-ECHRNG
-EL2NSYNC
-EL3HLT
-EL3RST
-ELNRNG
-EUNATCH
-ENOCSI
-EL2HLT
+EADDRINUSE
+EADDRNOTAVAIL
+EADV
+EAFNOSUPPORT
+EAGAIN
+EALREADY
+EAUTH
+EBADARCH
EBADE
+EBADEXEC
+EBADF
+EBADFD
+EBADMACHO
+EBADMSG
EBADR
-EXFULL
-ENOANO
+EBADRPC
EBADRQC
EBADSLT
-EDEADLOCK
EBFONT
-ENOSTR
-ENODATA
-ETIME
-ENOSR
-ENONET
-ENOPKG
-EREMOTE
-ENOLINK
-EADV
-ESRMNT
+EBUSY
+ECANCELED
+ECAPMODE
+ECHILD
+ECHRNG
ECOMM
-EPROTO
-EMULTIHOP
-EDOTDOT
-EBADMSG
-EOVERFLOW
-ENOTUNIQ
-EBADFD
-EREMCHG
-ELIBACC
-ELIBBAD
-ELIBSCN
-ELIBMAX
-ELIBEXEC
-EILSEQ
-ERESTART
-ESTRPIPE
-EUSERS
-ENOTSOCK
-EDESTADDRREQ
-EMSGSIZE
-EPROTOTYPE
-ENOPROTOOPT
-EPROTONOSUPPORT
-ESOCKTNOSUPPORT
-EOPNOTSUPP
-EPFNOSUPPORT
-EAFNOSUPPORT
-EADDRINUSE
-EADDRNOTAVAIL
-ENETDOWN
-ENETUNREACH
-ENETRESET
ECONNABORTED
-ECONNRESET
-ENOBUFS
-EISCONN
-ENOTCONN
-ESHUTDOWN
-ETOOMANYREFS
-ETIMEDOUT
ECONNREFUSED
+ECONNRESET
+EDEADLK
+EDEADLOCK
+EDESTADDRREQ
+EDEVERR
+EDOM
+EDOOFUS
+EDOTDOT
+EDQUOT
+EEXIST
+EFAULT
+EFBIG
+EFTYPE
EHOSTDOWN
EHOSTUNREACH
-EALREADY
+EHWPOISON
+EIDRM
+EILSEQ
EINPROGRESS
-ESTALE
-EUCLEAN
-ENOTNAM
-ENAVAIL
+EINTR
+EINVAL
+EIO
+EIPSEC
+EISCONN
+EISDIR
EISNAM
-EREMOTEIO
-EDQUOT
-ECANCELED
EKEYEXPIRED
EKEYREJECTED
EKEYREVOKED
+EL2HLT
+EL2NSYNC
+EL3HLT
+EL3RST
+ELAST
+ELIBACC
+ELIBBAD
+ELIBEXEC
+ELIBMAX
+ELIBSCN
+ELNRNG
+ELOOP
EMEDIUMTYPE
+EMFILE
+EMLINK
+EMSGSIZE
+EMULTIHOP
+ENAMETOOLONG
+ENAVAIL
+ENEEDAUTH
+ENETDOWN
+ENETRESET
+ENETUNREACH
+ENFILE
+ENOANO
+ENOATTR
+ENOBUFS
+ENOCSI
+ENODATA
+ENODEV
+ENOENT
+ENOEXEC
ENOKEY
+ENOLCK
+ENOLINK
ENOMEDIUM
+ENOMEM
+ENOMSG
+ENONET
+ENOPKG
+ENOPOLICY
+ENOPROTOOPT
+ENOSPC
+ENOSR
+ENOSTR
+ENOSYS
+ENOTBLK
+ENOTCAPABLE
+ENOTCONN
+ENOTDIR
+ENOTEMPTY
+ENOTNAM
ENOTRECOVERABLE
-EOWNERDEAD
-ERFKILL
-EAUTH
-EBADRPC
-EDOOFUS
-EFTYPE
-ENEEDAUTH
-ENOATTR
+ENOTSOCK
ENOTSUP
+ENOTTY
+ENOTUNIQ
+ENXIO
+EOPNOTSUPP
+EOVERFLOW
+EOWNERDEAD
+EPERM
+EPFNOSUPPORT
+EPIPE
EPROCLIM
EPROCUNAVAIL
EPROGMISMATCH
EPROGUNAVAIL
+EPROTO
+EPROTONOSUPPORT
+EPROTOTYPE
+EPWROFF
+EQFULL
+ERANGE
+EREMCHG
+EREMOTE
+EREMOTEIO
+ERESTART
+ERFKILL
+EROFS
ERPCMISMATCH
-EIPSEC
-EHWPOISON
-ECAPMODE
-ENOTCAPABLE
+ESHLIBVERS
+ESHUTDOWN
+ESOCKTNOSUPPORT
+ESPIPE
+ESRCH
+ESRMNT
+ESTALE
+ESTRPIPE
+ETIME
+ETIMEDOUT
+ETOOMANYREFS
+ETXTBSY
+EUCLEAN
+EUNATCH
+EUSERS
+EWOULDBLOCK
+EXDEV
+EXFULL
diff --git a/defs/lex.c.src b/defs/lex.c.src
index e0d931cd1f..fc30ec2d15 100644
--- a/defs/lex.c.src
+++ b/defs/lex.c.src
@@ -1,8 +1,8 @@
%{
-struct kwtable {int name, id[2], state;};
+struct kwtable {short name, id[2], state;};
const struct kwtable *rb_reserved_word(const char *, unsigned int);
#ifndef RIPPER
-static const struct kwtable *reserved_word(const char *, unsigned int);
+static const struct kwtable *reserved_word(/*!ANSI{*/const char *, unsigned int/*}!ANSI*/);
#define rb_reserved_word(str, len) reserved_word(str, len)
%}
diff --git a/defs/separated_version.mk b/defs/separated_version.mk
index f086f4b24a..72ee093da7 100644
--- a/defs/separated_version.mk
+++ b/defs/separated_version.mk
@@ -1,6 +1,6 @@
# ******** FOR DEVELEPERS ONLY ********
# Separate version.o into a shared library which varies every
-# revisions, in order to make the rest sharable.
+# revisions, in order to make the rest shareable.
include $(firstword $(wildcard GNUmakefile Makefile))
diff --git a/defs/universal.mk b/defs/universal.mk
new file mode 100644
index 0000000000..c34a31b356
--- /dev/null
+++ b/defs/universal.mk
@@ -0,0 +1,5 @@
+arch_flags := $(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG)))
+ifeq ($(filter 0 1,$(words $(arch_flags))),)
+override MJIT_HEADER_SUFFIX = -%
+override MJIT_HEADER_ARCH = -$(word 2,$(ARCH_FLAG))
+endif
diff --git a/dir.c b/dir.c
index d7e5d82e9f..c19ef637a1 100644
--- a/dir.c
+++ b/dir.c
@@ -11,10 +11,10 @@
**********************************************************************/
-#include "internal.h"
-#include "encindex.h"
-#include "ruby/thread.h"
+#include "ruby/internal/config.h"
+#include <ctype.h>
+#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -22,6 +22,10 @@
#include <unistd.h>
#endif
+#ifndef O_CLOEXEC
+# define O_CLOEXEC 0
+#endif
+
#ifndef USE_OPENDIR_AT
# if defined(HAVE_FDOPENDIR) && defined(HAVE_DIRFD) && \
defined(HAVE_OPENAT) && defined(HAVE_FSTATAT)
@@ -30,12 +34,10 @@
# define USE_OPENDIR_AT 0
# endif
#endif
+
#if USE_OPENDIR_AT
# include <fcntl.h>
#endif
-#ifndef AT_FDCWD
-# define AT_FDCWD -1
-#endif
#undef HAVE_DIRENT_NAMLEN
#if defined HAVE_DIRENT_H && !defined _WIN32
@@ -61,12 +63,6 @@
# include "win32/dir.h"
# endif
#endif
-#if defined(__native_client__) && defined(NACL_NEWLIB)
-# include "nacl/dirent.h"
-# include "nacl/stat.h"
-#endif
-
-#include <errno.h>
#ifndef HAVE_STDLIB_H
char *getenv();
@@ -76,26 +72,6 @@ char *getenv();
char *strchr(char*,char);
#endif
-#include <ctype.h>
-
-#include "ruby/util.h"
-
-/* define system APIs */
-#ifdef _WIN32
-#undef chdir
-#define chdir(p) rb_w32_uchdir(p)
-#undef mkdir
-#define mkdir(p, m) rb_w32_umkdir((p), (m))
-#undef rmdir
-#define rmdir(p) rb_w32_urmdir(p)
-#undef opendir
-#define opendir(p) rb_w32_uopendir(p)
-#define ruby_getcwd() rb_w32_ugetcwd(NULL, 0)
-#define IS_WIN32 1
-#else
-#define IS_WIN32 0
-#endif
-
#ifdef HAVE_SYS_ATTR_H
#include <sys/attr.h>
#endif
@@ -119,15 +95,53 @@ char *strchr(char*,char);
#ifdef __APPLE__
# define NORMALIZE_UTF8PATH 1
+# include <sys/param.h>
+# include <sys/mount.h>
+# include <sys/vnode.h>
#else
# define NORMALIZE_UTF8PATH 0
#endif
-#if NORMALIZE_UTF8PATH
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
+#include "encindex.h"
+#include "id.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/dir.h"
+#include "internal/encoding.h"
+#include "internal/error.h"
+#include "internal/file.h"
+#include "internal/gc.h"
+#include "internal/io.h"
+#include "internal/vm.h"
+#include "ruby/encoding.h"
+#include "ruby/ruby.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+#include "builtin.h"
+
+#ifndef AT_FDCWD
+# define AT_FDCWD -1
+#endif
+
+#define vm_initialized rb_cThread
+
+/* define system APIs */
+#ifdef _WIN32
+# undef chdir
+# define chdir(p) rb_w32_uchdir(p)
+# undef mkdir
+# define mkdir(p, m) rb_w32_umkdir((p), (m))
+# undef rmdir
+# define rmdir(p) rb_w32_urmdir(p)
+# undef opendir
+# define opendir(p) rb_w32_uopendir(p)
+# define ruby_getcwd() rb_w32_ugetcwd(NULL, 0)
+# define IS_WIN32 1
+#else
+# define IS_WIN32 0
+#endif
+#if NORMALIZE_UTF8PATH
# if defined HAVE_FGETATTRLIST || !defined HAVE_GETATTRLIST
# define need_normalization(dirp, path) need_normalization(dirp)
# else
@@ -173,7 +187,7 @@ has_nonascii(const char *ptr, size_t len)
#endif
#ifndef IFTODT
-# define IFTODT(m) (((m) & S_IFMT) / ((~S_IFMT & S_IFMT-1) + 1))
+# define IFTODT(m) (((m) & S_IFMT) / ((~S_IFMT & (S_IFMT-1)) + 1))
#endif
typedef enum {
@@ -207,6 +221,7 @@ typedef enum {
#else
#define FNM_SHORTNAME 0
#endif
+#define FNM_GLOB_NOSORT 0x40
#define FNM_NOMATCH 1
#define FNM_ERROR 2
@@ -472,15 +487,6 @@ static const rb_data_type_t dir_data_type = {
static VALUE dir_close(VALUE);
-#define GlobPathValue(str, safe) \
- /* can contain null bytes as separators */ \
- (!RB_TYPE_P((str), T_STRING) ? \
- (void)FilePathValue(str) : \
- (void)(check_safe_glob((str), (safe)), \
- check_glob_encoding(str), (str)))
-#define check_safe_glob(str, safe) ((safe) ? rb_check_safe_obj(str) : (void)0)
-#define check_glob_encoding(str) rb_enc_check((str), rb_enc_from_encoding(rb_usascii_encoding()))
-
static VALUE
dir_s_alloc(VALUE klass)
{
@@ -494,42 +500,37 @@ dir_s_alloc(VALUE klass)
return obj;
}
-/*
- * call-seq:
- * Dir.new( string ) -> aDir
- * Dir.new( string, encoding: enc ) -> aDir
- *
- * Returns a new directory object for the named directory.
- *
- * The optional <i>encoding</i> keyword argument specifies the encoding of the directory.
- * If not specified, the filesystem encoding is used.
- */
-static VALUE
-dir_initialize(int argc, VALUE *argv, VALUE dir)
+static void *
+nogvl_opendir(void *ptr)
{
- struct dir_data *dp;
- rb_encoding *fsenc;
- VALUE dirname, opt, orig;
- static ID keyword_ids[1];
- const char *path;
+ const char *path = ptr;
- if (!keyword_ids[0]) {
- keyword_ids[0] = rb_id_encoding();
- }
+ return (void *)opendir(path);
+}
- fsenc = rb_filesystem_encoding();
+static DIR *
+opendir_without_gvl(const char *path)
+{
+ if (vm_initialized) {
+ union { const void *in; void *out; } u;
- rb_scan_args(argc, argv, "1:", &dirname, &opt);
+ u.in = path;
- if (!NIL_P(opt)) {
- VALUE enc;
- rb_get_kwargs(opt, keyword_ids, 0, 1, &enc);
- if (enc != Qundef && !NIL_P(enc)) {
- fsenc = rb_to_encoding(enc);
- }
+ return rb_thread_call_without_gvl(nogvl_opendir, u.out, RUBY_UBF_IO, 0);
}
+ else
+ return opendir(path);
+}
+
+static VALUE
+dir_initialize(rb_execution_context_t *ec, VALUE dir, VALUE dirname, VALUE enc)
+{
+ struct dir_data *dp;
+ VALUE orig;
+ const char *path;
+ rb_encoding *fsenc = NIL_P(enc) ? rb_filesystem_encoding() : rb_to_encoding(enc);
- GlobPathValue(dirname, FALSE);
+ FilePathValue(dirname);
orig = rb_str_dup_frozen(dirname);
dirname = rb_str_encode_ospath(dirname);
dirname = rb_str_dup_frozen(dirname);
@@ -540,18 +541,18 @@ dir_initialize(int argc, VALUE *argv, VALUE dir)
RB_OBJ_WRITE(dir, &dp->path, Qnil);
dp->enc = fsenc;
path = RSTRING_PTR(dirname);
- dp->dir = opendir(path);
+ dp->dir = opendir_without_gvl(path);
if (dp->dir == NULL) {
int e = errno;
if (rb_gc_for_fd(e)) {
- dp->dir = opendir(path);
+ dp->dir = opendir_without_gvl(path);
}
#ifdef HAVE_GETATTRLIST
else if (e == EIO) {
u_int32_t attrbuf[1];
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0};
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW) == 0) {
- dp->dir = opendir(path);
+ dp->dir = opendir_without_gvl(path);
}
}
#endif
@@ -565,36 +566,25 @@ dir_initialize(int argc, VALUE *argv, VALUE dir)
return dir;
}
-/*
- * call-seq:
- * Dir.open( string ) -> aDir
- * Dir.open( string, encoding: enc ) -> aDir
- * Dir.open( string ) {| aDir | block } -> anObject
- * Dir.open( string, encoding: enc ) {| aDir | block } -> anObject
- *
- * The optional <i>encoding</i> keyword argument specifies the encoding of the directory.
- * If not specified, the filesystem encoding is used.
- *
- * With no block, <code>open</code> is a synonym for
- * <code>Dir::new</code>. If a block is present, it is passed
- * <i>aDir</i> as a parameter. The directory is closed at the end of
- * the block, and <code>Dir::open</code> returns the value of the
- * block.
- */
static VALUE
-dir_s_open(int argc, VALUE *argv, VALUE klass)
+dir_s_open(rb_execution_context_t *ec, VALUE klass, VALUE dirname, VALUE enc)
{
struct dir_data *dp;
VALUE dir = TypedData_Make_Struct(klass, struct dir_data, &dir_data_type, dp);
- dir_initialize(argc, argv, dir);
- if (rb_block_given_p()) {
- return rb_ensure(rb_yield, dir, dir_close, dir);
- }
+ dir_initialize(ec, dir, dirname, enc);
return dir;
}
+static VALUE
+dir_s_close(rb_execution_context_t *ec, VALUE klass, VALUE dir)
+{
+ return dir_close(dir);
+}
+
+NORETURN(static void dir_closed(void));
+
static void
dir_closed(void)
{
@@ -639,7 +629,7 @@ dir_inspect(VALUE dir)
rb_str_cat2(str, ">");
return str;
}
- return rb_funcallv(dir, rb_intern("to_s"), 0, 0);
+ return rb_funcallv(dir, idTo_s, 0, 0);
}
/* Workaround for Solaris 10 that does not have dirfd.
@@ -840,7 +830,6 @@ dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE), VALUE arg, int children_o
#endif
path = rb_external_str_new_with_enc(name, namlen, dirp->enc);
(*each)(arg, path);
- if (dirp->dir == NULL) dir_closed();
}
return dir;
}
@@ -851,8 +840,7 @@ dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE), VALUE arg, int children_o
* dir.pos -> integer
* dir.tell -> integer
*
- * Returns the current position in <em>dir</em>. See also
- * <code>Dir#seek</code>.
+ * Returns the current position in <em>dir</em>. See also Dir#seek.
*
* d = Dir.new("testdir")
* d.tell #=> 0
@@ -879,7 +867,7 @@ dir_tell(VALUE dir)
* dir.seek( integer ) -> dir
*
* Seeks to a particular location in <em>dir</em>. <i>integer</i>
- * must be a value returned by <code>Dir#tell</code>.
+ * must be a value returned by Dir#tell.
*
* d = Dir.new("testdir") #=> #<Dir:0x401b3c40>
* d.read #=> "."
@@ -907,8 +895,7 @@ dir_seek(VALUE dir, VALUE pos)
* call-seq:
* dir.pos = integer -> integer
*
- * Synonym for <code>Dir#seek</code>, but returns the position
- * parameter.
+ * Synonym for Dir#seek, but returns the position parameter.
*
* d = Dir.new("testdir") #=> #<Dir:0x401b3c40>
* d.read #=> "."
@@ -971,6 +958,14 @@ dir_close(VALUE dir)
return Qnil;
}
+static void *
+nogvl_chdir(void *ptr)
+{
+ const char *path = ptr;
+
+ return (void *)(VALUE)chdir(path);
+}
+
static void
dir_chdir(VALUE path)
{
@@ -987,8 +982,9 @@ struct chdir_data {
};
static VALUE
-chdir_yield(struct chdir_data *args)
+chdir_yield(VALUE v)
{
+ struct chdir_data *args = (void *)v;
dir_chdir(args->new_path);
args->done = TRUE;
chdir_blocking++;
@@ -998,8 +994,9 @@ chdir_yield(struct chdir_data *args)
}
static VALUE
-chdir_restore(struct chdir_data *args)
+chdir_restore(VALUE v)
{
+ struct chdir_data *args = (void *)v;
if (args->done) {
chdir_blocking--;
if (chdir_blocking == 0)
@@ -1017,8 +1014,8 @@ chdir_restore(struct chdir_data *args)
* Changes the current working directory of the process to the given
* string. When called without an argument, changes the directory to
* the value of the environment variable <code>HOME</code>, or
- * <code>LOGDIR</code>. <code>SystemCallError</code> (probably
- * <code>Errno::ENOENT</code>) if the target directory does not exist.
+ * <code>LOGDIR</code>. SystemCallError (probably Errno::ENOENT) if
+ * the target directory does not exist.
*
* If a block is given, it is passed the name of the new current
* directory, and the block is executed with that as the current
@@ -1027,7 +1024,8 @@ chdir_restore(struct chdir_data *args)
* block. <code>chdir</code> blocks can be nested, but in a
* multi-threaded program an error will be raised if a thread attempts
* to open a <code>chdir</code> block while another thread has one
- * open.
+ * open or a call to <code>chdir</code> without a block occurs inside
+ * a block passed to <code>chdir</code> (even in the same thread).
*
* Dir.chdir("/var/spool/mail")
* puts Dir.pwd
@@ -1053,9 +1051,8 @@ dir_s_chdir(int argc, VALUE *argv, VALUE obj)
{
VALUE path = Qnil;
- if (rb_scan_args(argc, argv, "01", &path) == 1) {
- FilePathValue(path);
- path = rb_str_encode_ospath(path);
+ if (rb_check_arity(argc, 0, 1) == 1) {
+ path = rb_str_encode_ospath(rb_get_path(argv[0]));
}
else {
const char *dist = getenv("HOME");
@@ -1067,8 +1064,10 @@ dir_s_chdir(int argc, VALUE *argv, VALUE obj)
}
if (chdir_blocking > 0) {
- if (!rb_block_given_p() || rb_thread_current() != chdir_thread)
- rb_warn("conflicting chdir during another chdir block");
+ if (rb_thread_current() != chdir_thread)
+ rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block");
+ if (!rb_block_given_p())
+ rb_warn("conflicting chdir during another chdir block");
}
if (rb_block_given_p()) {
@@ -1079,7 +1078,13 @@ dir_s_chdir(int argc, VALUE *argv, VALUE obj)
args.done = FALSE;
return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
}
- dir_chdir(path);
+ else {
+ char *p = RSTRING_PTR(path);
+ int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_chdir, p,
+ RUBY_UBF_IO, 0);
+ if (r < 0)
+ rb_sys_fail_path(path);
+ }
return INT2FIX(0);
}
@@ -1095,13 +1100,12 @@ rb_dir_getwd_ospath(void)
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
path_guard = Data_Wrap_Struct((VALUE)0, NULL, RUBY_DEFAULT_FREE, NULL);
- path = my_getcwd();
+ path = ruby_getcwd();
DATA_PTR(path_guard) = path;
#ifdef __APPLE__
cwd = rb_str_normalize_ospath(path, strlen(path));
- OBJ_TAINT(cwd);
#else
- cwd = rb_tainted_str_new2(path);
+ cwd = rb_str_new2(path);
#endif
DATA_PTR(path_guard) = 0;
@@ -1191,17 +1195,29 @@ dir_s_chroot(VALUE dir, VALUE path)
#define dir_s_chroot rb_f_notimplement
#endif
+struct mkdir_arg {
+ const char *path;
+ mode_t mode;
+};
+
+static void *
+nogvl_mkdir(void *ptr)
+{
+ struct mkdir_arg *m = ptr;
+
+ return (void *)(VALUE)mkdir(m->path, m->mode);
+}
+
/*
* call-seq:
* Dir.mkdir( string [, integer] ) -> 0
*
* Makes a new directory named by <i>string</i>, with permissions
* specified by the optional parameter <i>anInteger</i>. The
- * permissions may be modified by the value of
- * <code>File::umask</code>, and are ignored on NT. Raises a
- * <code>SystemCallError</code> if the directory cannot be created. See
- * also the discussion of permissions in the class documentation for
- * <code>File</code>.
+ * permissions may be modified by the value of File::umask, and are
+ * ignored on NT. Raises a SystemCallError if the directory cannot be
+ * created. See also the discussion of permissions in the class
+ * documentation for File.
*
* Dir.mkdir(File.join(Dir.home, ".foo"), 0700) #=> 0
*
@@ -1209,37 +1225,53 @@ dir_s_chroot(VALUE dir, VALUE path)
static VALUE
dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
{
+ struct mkdir_arg m;
VALUE path, vmode;
- int mode;
+ int r;
if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
- mode = NUM2INT(vmode);
+ m.mode = NUM2MODET(vmode);
}
else {
- mode = 0777;
+ m.mode = 0777;
}
path = check_dirname(path);
- if (mkdir(RSTRING_PTR(path), mode) == -1)
+ m.path = RSTRING_PTR(path);
+ r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_mkdir, &m, RUBY_UBF_IO, 0);
+ if (r < 0)
rb_sys_fail_path(path);
return INT2FIX(0);
}
+static void *
+nogvl_rmdir(void *ptr)
+{
+ const char *path = ptr;
+
+ return (void *)(VALUE)rmdir(path);
+}
+
/*
* call-seq:
* Dir.delete( string ) -> 0
* Dir.rmdir( string ) -> 0
* Dir.unlink( string ) -> 0
*
- * Deletes the named directory. Raises a subclass of
- * <code>SystemCallError</code> if the directory isn't empty.
+ * Deletes the named directory. Raises a subclass of SystemCallError
+ * if the directory isn't empty.
*/
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
+ const char *p;
+ int r;
+
dir = check_dirname(dir);
- if (rmdir(RSTRING_PTR(dir)) < 0)
+ p = RSTRING_PTR(dir);
+ r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_rmdir, (void *)p, RUBY_UBF_IO, 0);
+ if (r < 0)
rb_sys_fail_path(dir);
return INT2FIX(0);
@@ -1285,9 +1317,34 @@ sys_enc_warning_in(const char *func, const char *mesg, rb_encoding *enc)
#define sys_warning(val, enc) \
((flags & GLOB_VERBOSE) ? sys_enc_warning_in(RUBY_FUNCTION_NAME_STRING, (val), (enc)) :(void)0)
+static inline size_t
+glob_alloc_size(size_t x, size_t y)
+{
+ size_t z;
+ if (rb_mul_size_overflow(x, y, SSIZE_MAX, &z)) {
+ rb_memerror(); /* or...? */
+ }
+ else {
+ return z;
+ }
+}
+
+static inline void *
+glob_alloc_n(size_t x, size_t y)
+{
+ return malloc(glob_alloc_size(x, y));
+}
+
+static inline void *
+glob_realloc_n(void *p, size_t x, size_t y)
+{
+ return realloc(p, glob_alloc_size(x, y));
+}
+
#define GLOB_ALLOC(type) ((type *)malloc(sizeof(type)))
-#define GLOB_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n)))
+#define GLOB_ALLOC_N(type, n) ((type *)glob_alloc_n(sizeof(type), n))
#define GLOB_REALLOC(ptr, size) realloc((ptr), (size))
+#define GLOB_REALLOC_N(ptr, n) glob_realloc_n(ptr, sizeof(*(ptr)), n)
#define GLOB_FREE(ptr) free(ptr)
#define GLOB_JUMP_TAG(status) (((status) == -1) ? rb_memerror() : rb_jump_tag(status))
@@ -1303,9 +1360,9 @@ to_be_ignored(int e)
}
#ifdef _WIN32
-#define STAT(p, s) rb_w32_ustati64((p), (s))
+#define STAT(p, s) rb_w32_ustati128((p), (s))
#undef lstat
-#define lstat(p, s) rb_w32_ulstati64((p), (s))
+#define lstat(p, s) rb_w32_ulstati128((p), (s))
#else
#define STAT(p, s) stat((p), (s))
#endif
@@ -1316,12 +1373,24 @@ typedef struct {
ruby_glob_errfunc *error;
} ruby_glob_funcs_t;
+static const char *
+at_subpath(int fd, size_t baselen, const char *path)
+{
+#if USE_OPENDIR_AT
+ if (fd != (int)AT_FDCWD && baselen > 0) {
+ path += baselen;
+ if (*path == '/') ++path;
+ }
+#endif
+ return *path ? path : ".";
+}
+
/* System call with warning */
static int
-do_stat(int fd, const char *path, struct stat *pst, int flags, rb_encoding *enc)
+do_stat(int fd, size_t baselen, const char *path, struct stat *pst, int flags, rb_encoding *enc)
{
#if USE_OPENDIR_AT
- int ret = fstatat(fd, path, pst, 0);
+ int ret = fstatat(fd, at_subpath(fd, baselen, path), pst, 0);
#else
int ret = STAT(path, pst);
#endif
@@ -1333,10 +1402,10 @@ do_stat(int fd, const char *path, struct stat *pst, int flags, rb_encoding *enc)
#if defined HAVE_LSTAT || defined lstat || USE_OPENDIR_AT
static int
-do_lstat(int fd, const char *path, struct stat *pst, int flags, rb_encoding *enc)
+do_lstat(int fd, size_t baselen, const char *path, struct stat *pst, int flags, rb_encoding *enc)
{
#if USE_OPENDIR_AT
- int ret = fstatat(fd, path, pst, AT_SYMLINK_NOFOLLOW);
+ int ret = fstatat(fd, at_subpath(fd, baselen, path), pst, AT_SYMLINK_NOFOLLOW);
#else
int ret = lstat(path, pst);
#endif
@@ -1349,18 +1418,86 @@ do_lstat(int fd, const char *path, struct stat *pst, int flags, rb_encoding *enc
#define do_lstat do_stat
#endif
-static DIR *
-do_opendir(const int basefd, const char *path, int flags, rb_encoding *enc,
- ruby_glob_errfunc *errfunc, VALUE arg, int *status)
+struct opendir_at_arg {
+ int basefd;
+ const char *path;
+};
+
+static void *
+with_gvl_gc_for_fd(void *ptr)
{
+ int *e = ptr;
+
+ return (void *)(rb_gc_for_fd(*e) ? Qtrue : Qfalse);
+}
+
+static int
+gc_for_fd_with_gvl(int e)
+{
+ if (vm_initialized)
+ return (int)(VALUE)rb_thread_call_with_gvl(with_gvl_gc_for_fd, &e);
+ else
+ return rb_gc_for_fd(e) ? Qtrue : Qfalse;
+}
+
+static void *
+nogvl_opendir_at(void *ptr)
+{
+ const struct opendir_at_arg *oaa = ptr;
+ DIR *dirp;
+
#if USE_OPENDIR_AT
const int opendir_flags = (O_RDONLY|O_CLOEXEC|
-#ifdef O_DIRECTORY
+# ifdef O_DIRECTORY
O_DIRECTORY|
-#endif
+# endif /* O_DIRECTORY */
0);
- int fd;
-#endif
+ int fd = openat(oaa->basefd, oaa->path, opendir_flags);
+
+ dirp = fd >= 0 ? fdopendir(fd) : 0;
+ if (!dirp) {
+ int e = errno;
+
+ switch (gc_for_fd_with_gvl(e)) {
+ default:
+ if (fd < 0) fd = openat(oaa->basefd, oaa->path, opendir_flags);
+ if (fd >= 0) dirp = fdopendir(fd);
+ if (dirp) return dirp;
+
+ e = errno;
+ /* fallthrough*/
+ case 0:
+ if (fd >= 0) close(fd);
+ errno = e;
+ }
+ }
+#else /* !USE_OPENDIR_AT */
+ dirp = opendir(oaa->path);
+ if (!dirp && gc_for_fd_with_gvl(errno))
+ dirp = opendir(oaa->path);
+#endif /* !USE_OPENDIR_AT */
+
+ return dirp;
+}
+
+static DIR *
+opendir_at(int basefd, const char *path)
+{
+ struct opendir_at_arg oaa;
+
+ oaa.basefd = basefd;
+ oaa.path = path;
+
+ if (vm_initialized)
+ return rb_thread_call_without_gvl(nogvl_opendir_at, &oaa, RUBY_UBF_IO, 0);
+ else
+ return nogvl_opendir_at(&oaa);
+}
+
+static DIR *
+do_opendir(const int basefd, size_t baselen, const char *path, int flags, rb_encoding *enc,
+ ruby_glob_errfunc *errfunc, VALUE arg, int *status)
+{
DIR *dirp;
#ifdef _WIN32
VALUE tmp = 0;
@@ -1370,37 +1507,18 @@ do_opendir(const int basefd, const char *path, int flags, rb_encoding *enc,
path = RSTRING_PTR(tmp);
}
#endif
-#if USE_OPENDIR_AT
- fd = openat(basefd, path, 0, opendir_flags);
- dirp = (fd < 0) ? NULL : fdopendir(fd);
-#else
- dirp = opendir(path);
-#endif
+ dirp = opendir_at(basefd, at_subpath(basefd, baselen, path));
if (!dirp) {
int e = errno;
- switch (rb_gc_for_fd(e)) {
- default:
-#if USE_OPENDIR_AT
- if ((fd >= 0) || (fd = openat(basefd, path, 0, opendir_flags)) >= 0) {
- dirp = fdopendir(fd);
- }
-#else
- dirp = opendir(path);
-#endif
- if (dirp) break;
- e = errno;
- /* fallback */
- case 0:
-#if USE_OPENDIR_AT
- if (fd >= 0) close(fd);
-#endif
- *status = 0;
- if (to_be_ignored(e)) break;
+
+ *status = 0;
+ if (!to_be_ignored(e)) {
if (errfunc) {
*status = (*errfunc)(path, arg, enc, e);
- break;
}
- sys_warning(path, enc);
+ else {
+ sys_warning(path, enc);
+ }
}
}
#ifdef _WIN32
@@ -1411,7 +1529,7 @@ do_opendir(const int basefd, const char *path, int flags, rb_encoding *enc,
}
/* Globing pattern */
-enum glob_pattern_type { PLAIN, ALPHA, MAGICAL, RECURSIVE, MATCH_ALL, MATCH_DIR };
+enum glob_pattern_type { PLAIN, ALPHA, BRACE, MAGICAL, RECURSIVE, MATCH_ALL, MATCH_DIR };
/* Return nonzero if S has any special globbing chars in it. */
static enum glob_pattern_type
@@ -1419,15 +1537,20 @@ has_magic(const char *p, const char *pend, int flags, rb_encoding *enc)
{
const int escape = !(flags & FNM_NOESCAPE);
int hasalpha = 0;
+ int hasmagical = 0;
register char c;
while (p < pend && (c = *p++) != 0) {
switch (c) {
+ case '{':
+ return BRACE;
+
case '*':
case '?':
case '[':
- return MAGICAL;
+ hasmagical = 1;
+ break;
case '\\':
if (escape && p++ >= pend)
@@ -1452,7 +1575,7 @@ has_magic(const char *p, const char *pend, int flags, rb_encoding *enc)
p = Next(p-1, pend, enc);
}
- return hasalpha ? ALPHA : PLAIN;
+ return hasmagical ? MAGICAL : hasalpha ? ALPHA : PLAIN;
}
/* Find separator in globbing pattern. */
@@ -1473,6 +1596,13 @@ find_dirsep(const char *p, const char *pend, int flags, rb_encoding *enc)
open = 0;
continue;
+ case '{':
+ open = 1;
+ continue;
+ case '}':
+ open = 0;
+ continue;
+
case '/':
if (!open)
return (char *)p-1;
@@ -1579,10 +1709,7 @@ glob_make_pattern(const char *p, const char *e, int flags, rb_encoding *enc)
tmp = GLOB_ALLOC(struct glob_pattern);
if (!tmp) {
- error:
- *tail = 0;
- glob_free_pattern(list);
- return 0;
+ goto error;
}
tmp->type = dirsep ? MATCH_DIR : MATCH_ALL;
tmp->str = 0;
@@ -1590,6 +1717,11 @@ glob_make_pattern(const char *p, const char *e, int flags, rb_encoding *enc)
tmp->next = 0;
return list;
+
+ error:
+ *tail = 0;
+ glob_free_pattern(list);
+ return 0;
}
static void
@@ -1840,13 +1972,15 @@ rb_glob_warning(const char *path, VALUE a, const void *enc, int error)
}
#endif
+NORETURN(static VALUE glob_func_error(VALUE val));
+
static VALUE
glob_func_error(VALUE val)
{
struct glob_error_args *arg = (struct glob_error_args *)val;
VALUE path = rb_enc_str_new_cstr(arg->path, arg->enc);
rb_syserr_fail_str(arg->error, path);
- return Qnil;
+ UNREACHABLE_RETURN(Qnil);
}
static int
@@ -1866,8 +2000,17 @@ rb_glob_error(const char *path, VALUE a, const void *enc, int error)
return status;
}
+typedef struct rb_dirent {
+ long d_namlen;
+ const char *d_name;
+#ifdef _WIN32
+ const char *d_altname;
+#endif
+ uint8_t d_type;
+} rb_dirent_t;
+
static inline int
-dirent_match(const char *pat, rb_encoding *enc, const char *name, const struct dirent *dp, int flags)
+dirent_match(const char *pat, rb_encoding *enc, const char *name, const rb_dirent_t *dp, int flags)
{
if (fnmatch(pat, enc, name, flags) == 0) return 1;
#ifdef _WIN32
@@ -1878,6 +2021,236 @@ dirent_match(const char *pat, rb_encoding *enc, const char *name, const struct d
return 0;
}
+struct push_glob_args {
+ int fd;
+ const char *path;
+ size_t baselen;
+ size_t namelen;
+ int dirsep; /* '/' should be placed before appending child entry's name to 'path'. */
+ rb_pathtype_t pathtype; /* type of 'path' */
+ int flags;
+ const ruby_glob_funcs_t *funcs;
+ VALUE arg;
+};
+
+struct dirent_brace_args {
+ const char *name;
+ const rb_dirent_t *dp;
+ int flags;
+};
+
+static int
+dirent_match_brace(const char *pattern, VALUE val, void *enc)
+{
+ struct dirent_brace_args *arg = (struct dirent_brace_args *)val;
+
+ return dirent_match(pattern, enc, arg->name, arg->dp, arg->flags);
+}
+
+/* join paths from pattern list of glob_make_pattern() */
+static char*
+join_path_from_pattern(struct glob_pattern **beg)
+{
+ struct glob_pattern *p;
+ char *path = NULL;
+ size_t path_len = 0;
+
+ for (p = *beg; p; p = p->next) {
+ const char *str;
+ switch (p->type) {
+ case RECURSIVE:
+ str = "**";
+ break;
+ case MATCH_DIR:
+ /* append last slash */
+ str = "";
+ break;
+ default:
+ str = p->str;
+ if (!str) continue;
+ }
+ if (!path) {
+ path_len = strlen(str);
+ path = GLOB_ALLOC_N(char, path_len + 1);
+ if (path) {
+ memcpy(path, str, path_len);
+ path[path_len] = '\0';
+ }
+ }
+ else {
+ size_t len = strlen(str);
+ char *tmp;
+ tmp = GLOB_REALLOC(path, path_len + len + 2);
+ if (tmp) {
+ path = tmp;
+ path[path_len++] = '/';
+ memcpy(path + path_len, str, len);
+ path_len += len;
+ path[path_len] = '\0';
+ }
+ }
+ }
+ return path;
+}
+
+static int push_caller(const char *path, VALUE val, void *enc);
+
+static int ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg,
+ rb_encoding *enc, VALUE var);
+
+static const size_t rb_dirent_name_offset =
+ offsetof(rb_dirent_t, d_type) + sizeof(uint8_t);
+
+static rb_dirent_t *
+dirent_copy(const struct dirent *dp, rb_dirent_t *rdp)
+{
+ if (!dp) return NULL;
+ size_t namlen = NAMLEN(dp);
+ const size_t altlen =
+#ifdef _WIN32
+ dp->d_altlen ? dp->d_altlen + 1 :
+#endif
+ 0;
+ rb_dirent_t *newrdp = rdp;
+ if (!rdp && !(newrdp = malloc(rb_dirent_name_offset + namlen + 1 + altlen)))
+ return NULL;
+ newrdp->d_namlen = namlen;
+ if (!rdp) {
+ char *name = (char *)newrdp + rb_dirent_name_offset;
+ memcpy(name, dp->d_name, namlen);
+ name[namlen] = '\0';
+#ifdef _WIN32
+ newrdp->d_altname = NULL;
+ if (altlen) {
+ char *const altname = name + namlen + 1;
+ memcpy(altname, dp->d_altname, altlen - 1);
+ altname[altlen - 1] = '\0';
+ newrdp->d_altname = altname;
+ }
+#endif
+ newrdp->d_name = name;
+ }
+ else {
+ newrdp->d_name = dp->d_name;
+#ifdef _WIN32
+ newrdp->d_altname = dp->d_altname;
+#endif
+ }
+#ifdef DT_UNKNOWN
+ newrdp->d_type = dp->d_type;
+#else
+ newrdp->d_type = 0;
+#endif
+ return newrdp;
+}
+
+typedef union {
+ struct {
+ DIR *dirp;
+ rb_dirent_t ent;
+ } nosort;
+ struct {
+ size_t count, idx;
+ rb_dirent_t **entries;
+ } sort;
+} ruby_glob_entries_t;
+
+static int
+glob_sort_cmp(const void *a, const void *b, void *e)
+{
+ const rb_dirent_t *ent1 = *(void **)a;
+ const rb_dirent_t *ent2 = *(void **)b;
+ return strcmp(ent1->d_name, ent2->d_name);
+}
+
+static void
+glob_dir_finish(ruby_glob_entries_t *ent, int flags)
+{
+ if (flags & FNM_GLOB_NOSORT) {
+ closedir(ent->nosort.dirp);
+ ent->nosort.dirp = NULL;
+ }
+ else if (ent->sort.entries) {
+ for (size_t i = 0, count = ent->sort.count; i < count;) {
+ GLOB_FREE(ent->sort.entries[i++]);
+ }
+ GLOB_FREE(ent->sort.entries);
+ ent->sort.entries = NULL;
+ ent->sort.count = ent->sort.idx = 0;
+ }
+}
+
+static ruby_glob_entries_t *
+glob_opendir(ruby_glob_entries_t *ent, DIR *dirp, int flags, rb_encoding *enc)
+{
+ MEMZERO(ent, ruby_glob_entries_t, 1);
+ if (flags & FNM_GLOB_NOSORT) {
+ ent->nosort.dirp = dirp;
+ return ent;
+ }
+ else {
+ void *newp;
+ struct dirent *dp;
+ size_t count = 0, capacity = 0;
+ ent->sort.count = 0;
+ ent->sort.idx = 0;
+ ent->sort.entries = 0;
+#ifdef _WIN32
+ if ((capacity = dirp->nfiles) > 0) {
+ if (!(newp = GLOB_ALLOC_N(rb_dirent_t, capacity))) {
+ closedir(dirp);
+ return NULL;
+ }
+ ent->sort.entries = newp;
+ }
+#endif
+ while ((dp = READDIR(dirp, enc)) != NULL) {
+ rb_dirent_t *rdp = dirent_copy(dp, NULL);
+ if (!rdp) {
+ goto nomem;
+ }
+ if (count >= capacity) {
+ capacity += 256;
+ if (!(newp = GLOB_REALLOC_N(ent->sort.entries, capacity)))
+ goto nomem;
+ ent->sort.entries = newp;
+ }
+ ent->sort.entries[count++] = rdp;
+ ent->sort.count = count;
+ }
+ closedir(dirp);
+ if (count < capacity) {
+ if (!(newp = GLOB_REALLOC_N(ent->sort.entries, count))) {
+ glob_dir_finish(ent, 0);
+ return NULL;
+ }
+ ent->sort.entries = newp;
+ }
+ ruby_qsort(ent->sort.entries, ent->sort.count, sizeof(ent->sort.entries[0]),
+ glob_sort_cmp, NULL);
+ return ent;
+ }
+
+ nomem:
+ glob_dir_finish(ent, 0);
+ closedir(dirp);
+ return NULL;
+}
+
+static rb_dirent_t *
+glob_getent(ruby_glob_entries_t *ent, int flags, rb_encoding *enc)
+{
+ if (flags & FNM_GLOB_NOSORT) {
+ return dirent_copy(READDIR(ent->nosort.dirp, enc), &ent->nosort.ent);
+ }
+ else if (ent->sort.idx < ent->sort.count) {
+ return ent->sort.entries[ent->sort.idx++];
+ }
+ else {
+ return NULL;
+ }
+}
+
static int
glob_helper(
int fd,
@@ -1896,12 +2269,11 @@ glob_helper(
struct stat st;
int status = 0;
struct glob_pattern **cur, **new_beg, **new_end;
- int plain = 0, magical = 0, recursive = 0, match_all = 0, match_dir = 0;
+ int plain = 0, brace = 0, magical = 0, recursive = 0, match_all = 0, match_dir = 0;
int escape = !(flags & FNM_NOESCAPE);
size_t pathlen = baselen + namelen;
- const char *base = path;
- if (fd != AT_FDCWD && *(base += baselen) == '/') base++;
+ rb_check_stack_overflow();
for (cur = beg; cur < end; ++cur) {
struct glob_pattern *p = *cur;
@@ -1920,6 +2292,11 @@ glob_helper(
magical = 1;
#endif
break;
+ case BRACE:
+ if (!recursive) {
+ brace = 1;
+ }
+ break;
case MAGICAL:
magical = 2;
break;
@@ -1934,9 +2311,27 @@ glob_helper(
}
}
- if (*base) {
+ if (brace) {
+ struct push_glob_args args;
+ char* brace_path = join_path_from_pattern(beg);
+ if (!brace_path) return -1;
+ args.fd = fd;
+ args.path = path;
+ args.baselen = baselen;
+ args.namelen = namelen;
+ args.dirsep = dirsep;
+ args.pathtype = pathtype;
+ args.flags = flags;
+ args.funcs = funcs;
+ args.arg = arg;
+ status = ruby_brace_expand(brace_path, flags, push_caller, (VALUE)&args, enc, Qfalse);
+ GLOB_FREE(brace_path);
+ return status;
+ }
+
+ if (*path) {
if (match_all && pathtype == path_unknown) {
- if (do_lstat(fd, base, &st, flags, enc) == 0) {
+ if (do_lstat(fd, baselen, path, &st, flags, enc) == 0) {
pathtype = IFTODT(st.st_mode);
}
else {
@@ -1944,7 +2339,7 @@ glob_helper(
}
}
if (match_dir && (pathtype == path_unknown || pathtype == path_symlink)) {
- if (do_stat(fd, base, &st, flags, enc) == 0) {
+ if (do_stat(fd, baselen, path, &st, flags, enc) == 0) {
pathtype = IFTODT(st.st_mode);
}
else {
@@ -1957,10 +2352,11 @@ glob_helper(
if (status) return status;
}
if (match_dir && pathtype == path_directory) {
- const char *subpath = path + baselen + (baselen && path[baselen] == '/');
- char *tmp = join_path(subpath, namelen, dirsep, "", 0);
+ int seplen = (baselen && path[baselen] == '/');
+ const char *subpath = path + baselen + seplen;
+ char *tmp = join_path(subpath, namelen - seplen, dirsep, "", 0);
if (!tmp) return -1;
- status = glob_call_func(funcs->match, tmp + (baselen ? dirsep : 0), arg, enc);
+ status = glob_call_func(funcs->match, tmp, arg, enc);
GLOB_FREE(tmp);
if (status) return status;
}
@@ -1969,7 +2365,7 @@ glob_helper(
if (pathtype == path_noent) return 0;
if (magical || recursive) {
- struct dirent *dp;
+ rb_dirent_t *dp;
DIR *dirp;
# if USE_NAME_ON_FS == USE_NAME_ON_FS_BY_FNMATCH
char *plainname = 0;
@@ -1979,14 +2375,14 @@ glob_helper(
if (cur + 1 == end && (*cur)->type <= ALPHA) {
plainname = join_path(path, pathlen, dirsep, (*cur)->str, strlen((*cur)->str));
if (!plainname) return -1;
- dirp = do_opendir(fd, plainname, flags, enc, funcs->error, arg, &status);
+ dirp = do_opendir(fd, basename, plainname, flags, enc, funcs->error, arg, &status);
GLOB_FREE(plainname);
}
else
# else
;
# endif
- dirp = do_opendir(fd, *base ? base : ".", flags, enc, funcs->error, arg, &status);
+ dirp = do_opendir(fd, baselen, path, flags, enc, funcs->error, arg, &status);
if (dirp == NULL) {
# if FNM_SYSCASE || NORMALIZE_UTF8PATH
if ((magical < 2) && !recursive && (errno == EACCES)) {
@@ -1996,7 +2392,7 @@ glob_helper(
# endif
return status;
}
- IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp, *base ? base : "."));
+ IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp, *path ? path : "."));
# if NORMALIZE_UTF8PATH
if (!(norm_p || magical || recursive)) {
@@ -2008,7 +2404,18 @@ glob_helper(
if (is_case_sensitive(dirp, path) == 0)
flags |= FNM_CASEFOLD;
# endif
- while ((dp = READDIR(dirp, enc)) != NULL) {
+ ruby_glob_entries_t globent;
+ if (!glob_opendir(&globent, dirp, flags, enc)) {
+ status = 0;
+ if (funcs->error) {
+ status = (*funcs->error)(path, arg, enc, ENOMEM);
+ }
+ else {
+ sys_warning(path, enc);
+ }
+ return status;
+ }
+ while ((dp = glob_getent(&globent, flags, enc)) != NULL) {
char *buf;
rb_pathtype_t new_pathtype = path_unknown;
const char *name;
@@ -2017,7 +2424,7 @@ glob_helper(
IF_NORMALIZE_UTF8PATH(VALUE utf8str = Qnil);
name = dp->d_name;
- namlen = NAMLEN(dp);
+ namlen = dp->d_namlen;
if (recursive && name[0] == '.') {
++dotfile;
if (namlen == 1) {
@@ -2055,7 +2462,7 @@ glob_helper(
if (recursive && dotfile < ((flags & FNM_DOTMATCH) ? 2 : 1) &&
new_pathtype == path_unknown) {
/* RECURSIVE never match dot files unless FNM_DOTMATCH is set */
- if (do_lstat(fd, buf, &st, flags, enc) == 0)
+ if (do_lstat(fd, baselen, buf, &st, flags, enc) == 0)
new_pathtype = IFTODT(st.st_mode);
else
new_pathtype = path_noent;
@@ -2070,6 +2477,7 @@ glob_helper(
for (cur = beg; cur < end; ++cur) {
struct glob_pattern *p = *cur;
+ struct dirent_brace_args args;
if (p->type == RECURSIVE) {
if (new_pathtype == path_directory || /* not symlink but real directory */
new_pathtype == path_exist) {
@@ -2079,6 +2487,14 @@ glob_helper(
p = p->next; /* 0 times recursion */
}
switch (p->type) {
+ case BRACE:
+ args.name = name;
+ args.dp = dp;
+ args.flags = flags;
+ if (ruby_brace_expand(p->str, flags, dirent_match_brace,
+ (VALUE)&args, enc, Qfalse) > 0)
+ *new_end++ = p->next;
+ break;
case ALPHA:
# if USE_NAME_ON_FS == USE_NAME_ON_FS_BY_FNMATCH
if (plainname) {
@@ -2103,7 +2519,7 @@ glob_helper(
if (status) break;
}
- closedir(dirp);
+ glob_dir_finish(&globent, flags);
}
else if (plain) {
struct glob_pattern **copy_beg, **copy_end, **cur2;
@@ -2154,8 +2570,8 @@ glob_helper(
}
#if USE_NAME_ON_FS == USE_NAME_ON_FS_REAL_BASENAME
if ((*cur)->type == ALPHA) {
- long base = pathlen + (dirsep != 0);
- buf = replace_real_basename(buf, base, enc, IF_NORMALIZE_UTF8PATH(1)+0,
+ buf = replace_real_basename(buf, pathlen + (dirsep != 0), enc,
+ IF_NORMALIZE_UTF8PATH(1)+0,
flags, &new_pathtype);
if (!buf) break;
}
@@ -2177,6 +2593,42 @@ glob_helper(
}
static int
+push_caller(const char *path, VALUE val, void *enc)
+{
+ struct push_glob_args *arg = (struct push_glob_args *)val;
+ struct glob_pattern *list;
+ int status;
+
+ list = glob_make_pattern(path, path + strlen(path), arg->flags, enc);
+ if (!list) {
+ return -1;
+ }
+ status = glob_helper(arg->fd, arg->path, arg->baselen, arg->namelen, arg->dirsep,
+ arg->pathtype, &list, &list + 1, arg->flags, arg->funcs,
+ arg->arg, enc);
+ glob_free_pattern(list);
+ return status;
+}
+
+static int ruby_glob0(const char *path, int fd, const char *base, int flags,
+ const ruby_glob_funcs_t *funcs, VALUE arg, rb_encoding *enc);
+
+struct push_glob0_args {
+ int fd;
+ const char *base;
+ int flags;
+ const ruby_glob_funcs_t *funcs;
+ VALUE arg;
+};
+
+static int
+push_glob0_caller(const char *path, VALUE val, void *enc)
+{
+ struct push_glob0_args *arg = (struct push_glob0_args *)val;
+ return ruby_glob0(path, arg->fd, arg->base, arg->flags, arg->funcs, arg->arg, enc);
+}
+
+static int
ruby_glob0(const char *path, int fd, const char *base, int flags,
const ruby_glob_funcs_t *funcs, VALUE arg,
rb_encoding *enc)
@@ -2188,6 +2640,17 @@ ruby_glob0(const char *path, int fd, const char *base, int flags,
int status, dirsep = FALSE;
start = root = path;
+
+ if (*root == '{') {
+ struct push_glob0_args args;
+ args.fd = fd;
+ args.base = base;
+ args.flags = flags;
+ args.funcs = funcs;
+ args.arg = arg;
+ return ruby_brace_expand(path, flags, push_glob0_caller, (VALUE)&args, enc, Qfalse);
+ }
+
flags |= FNM_SYSCASE;
#if defined DOSISH
root = rb_enc_path_skip_prefix(root, root + strlen(root), enc);
@@ -2226,7 +2689,7 @@ ruby_glob(const char *path, int flags, ruby_glob_func *func, VALUE arg)
{
ruby_glob_funcs_t funcs;
funcs.match = func;
- funcs.error = NULL;
+ funcs.error = 0;
return ruby_glob0(path, AT_FDCWD, 0, flags & ~GLOB_VERBOSE,
&funcs, arg, rb_ascii8bit_encoding());
}
@@ -2267,7 +2730,6 @@ push_pattern(const char *path, VALUE ary, void *enc)
#if defined _WIN32 || defined __APPLE__
VALUE name = rb_utf8_str_new_cstr(path);
rb_encoding *eenc = rb_default_internal_encoding();
- OBJ_TAINT(name);
name = rb_str_conv_enc(name, NULL, eenc ? eenc : enc);
#else
VALUE name = rb_external_str_new_with_enc(path, strlen(path), enc);
@@ -2356,7 +2818,7 @@ ruby_brace_glob_with_enc(const char *str, int flags, ruby_glob_func *func, VALUE
flags &= ~GLOB_VERBOSE;
args.funcs.match = func;
- args.funcs.error = NULL;
+ args.funcs.error = 0;
args.value = arg;
args.flags = flags;
return ruby_brace_expand(str, flags, glob_brace, (VALUE)&args, enc, Qfalse);
@@ -2368,25 +2830,11 @@ ruby_brace_glob(const char *str, int flags, ruby_glob_func *func, VALUE arg)
return ruby_brace_glob_with_enc(str, flags, func, arg, rb_ascii8bit_encoding());
}
-struct push_glob_args {
- struct glob_args glob;
- int flags;
- int fd;
-};
-
-static int
-push_caller(const char *path, VALUE val, void *enc)
-{
- struct push_glob_args *arg = (struct push_glob_args *)val;
-
- return ruby_glob0(path, arg->fd, arg->glob.base, arg->flags, &rb_glob_funcs,
- (VALUE)&arg->glob, enc);
-}
-
static int
push_glob(VALUE ary, VALUE str, VALUE base, int flags)
{
- struct push_glob_args args;
+ struct glob_args args;
+ int fd;
rb_encoding *enc = rb_enc_get(str);
#if defined _WIN32 || defined __APPLE__
@@ -2397,230 +2845,117 @@ push_glob(VALUE ary, VALUE str, VALUE base, int flags)
if (rb_enc_to_index(enc) == ENCINDEX_US_ASCII)
enc = rb_ascii8bit_encoding();
flags |= GLOB_VERBOSE;
- args.glob.func = push_pattern;
- args.glob.value = ary;
- args.glob.enc = enc;
- args.glob.base = 0;
- args.flags = flags;
- args.fd = AT_FDCWD;
+ args.func = push_pattern;
+ args.value = ary;
+ args.enc = enc;
+ args.base = 0;
+ fd = AT_FDCWD;
if (!NIL_P(base)) {
if (!RB_TYPE_P(base, T_STRING) || !rb_enc_check(str, base)) {
struct dir_data *dirp = DATA_PTR(base);
if (!dirp->dir) dir_closed();
#ifdef HAVE_DIRFD
- if ((args.fd = dirfd(dirp->dir)) == -1)
+ if ((fd = dirfd(dirp->dir)) == -1)
rb_sys_fail_path(dir_inspect(base));
#endif
base = dirp->path;
}
- args.glob.base = RSTRING_PTR(base);
+ args.base = RSTRING_PTR(base);
}
#if defined _WIN32 || defined __APPLE__
enc = rb_utf8_encoding();
#endif
- return ruby_brace_expand(RSTRING_PTR(str), flags,
- push_caller, (VALUE)&args, enc, str);
+ return ruby_glob0(RSTRING_PTR(str), fd, args.base, flags, &rb_glob_funcs,
+ (VALUE)&args, enc);
}
static VALUE
rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */
{
- long offset = 0;
VALUE ary;
+ int status;
- GlobPathValue(str, TRUE);
+ /* can contain null bytes as separators */
+ if (!RB_TYPE_P(str, T_STRING)) {
+ FilePathValue(str);
+ }
+ else if (!rb_str_to_cstr(str)) {
+ rb_raise(rb_eArgError, "nul-separated glob pattern is deprecated");
+ }
+ else {
+ rb_enc_check(str, rb_enc_from_encoding(rb_usascii_encoding()));
+ }
ary = rb_ary_new();
- while (offset < RSTRING_LEN(str)) {
- char *p, *pend;
- int status;
- p = RSTRING_PTR(str) + offset;
- status = push_glob(ary, rb_enc_str_new(p, strlen(p), rb_enc_get(str)),
- base, flags);
- if (status) GLOB_JUMP_TAG(status);
- if (offset >= RSTRING_LEN(str)) break;
- p += strlen(p) + 1;
- pend = RSTRING_PTR(str) + RSTRING_LEN(str);
- while (p < pend && !*p)
- p++;
- offset = p - RSTRING_PTR(str);
- }
+ status = push_glob(ary, str, base, flags);
+ if (status) GLOB_JUMP_TAG(status);
return ary;
}
static VALUE
-dir_globs(long argc, const VALUE *argv, VALUE base, int flags)
+dir_globs(VALUE args, VALUE base, int flags)
{
VALUE ary = rb_ary_new();
long i;
- for (i = 0; i < argc; ++i) {
+ for (i = 0; i < RARRAY_LEN(args); ++i) {
int status;
- VALUE str = argv[i];
- GlobPathValue(str, TRUE);
+ VALUE str = RARRAY_AREF(args, i);
+ FilePathValue(str);
status = push_glob(ary, str, base, flags);
if (status) GLOB_JUMP_TAG(status);
}
+ RB_GC_GUARD(args);
return ary;
}
-static void
-dir_glob_options(VALUE opt, VALUE *base, int *flags)
+static VALUE
+dir_glob_option_base(VALUE base)
{
- ID kw[2];
- VALUE args[2];
- kw[0] = rb_intern("base");
- if (flags) kw[1] = rb_intern("flags");
- rb_get_kwargs(opt, kw, 0, flags ? 2 : 1, args);
- if (args[0] == Qundef || NIL_P(args[0])) {
- *base = Qnil;
+ if (base == Qundef || NIL_P(base)) {
+ return Qnil;
}
#if USE_OPENDIR_AT
- else if (rb_typeddata_is_kind_of(args[0], &dir_data_type)) {
- *base = args[0];
+ if (rb_typeddata_is_kind_of(base, &dir_data_type)) {
+ return base;
}
#endif
- else {
- GlobPathValue(args[0], TRUE);
- if (!RSTRING_LEN(args[0])) args[0] = Qnil;
- *base = args[0];
- }
- if (flags && args[1] != Qundef) {
- *flags = NUM2INT(args[1]);
- }
+ FilePathValue(base);
+ if (!RSTRING_LEN(base)) return Qnil;
+ return base;
+}
+
+static int
+dir_glob_option_sort(VALUE sort)
+{
+ return (sort ? 0 : FNM_GLOB_NOSORT);
}
-/*
- * call-seq:
- * Dir[ string [, string ...] [, base: path] ] -> array
- *
- * Equivalent to calling
- * <code>Dir.glob([</code><i>string,...</i><code>], 0)</code>.
- *
- */
static VALUE
-dir_s_aref(int argc, VALUE *argv, VALUE obj)
+dir_s_aref(rb_execution_context_t *ec, VALUE obj, VALUE args, VALUE base, VALUE sort)
{
- VALUE opts, base;
- argc = rb_scan_args(argc, argv, "*:", NULL, &opts);
- dir_glob_options(opts, &base, NULL);
- if (argc == 1) {
- return rb_push_glob(argv[0], base, 0);
+ const int flags = dir_glob_option_sort(sort);
+ base = dir_glob_option_base(base);
+ if (RARRAY_LEN(args) == 1) {
+ return rb_push_glob(RARRAY_AREF(args, 0), base, flags);
}
- return dir_globs(argc, argv, base, 0);
+ return dir_globs(args, base, flags);
}
-/*
- * call-seq:
- * Dir.glob( pattern, [flags], [base: path] ) -> array
- * Dir.glob( pattern, [flags], [base: path] ) { |filename| block } -> nil
- *
- * Expands +pattern+, which is a pattern string or an Array of pattern
- * strings, and returns an array containing the matching filenames.
- * If a block is given, calls the block once for each matching filename,
- * passing the filename as a parameter to the block.
- *
- * The optional +base+ keyword argument specifies the base directory for
- * interpreting relative pathnames instead of the current working directory.
- * As the results are not prefixed with the base directory name in this
- * case, you will need to prepend the base directory name if you want real
- * paths.
- *
- * Note that the pattern is not a regexp, it's closer to a shell glob.
- * See File::fnmatch for the meaning of the +flags+ parameter.
- * Case sensitivity depends on your system (File::FNM_CASEFOLD is ignored),
- * as does the order in which the results are returned.
- *
- * <code>*</code>::
- * Matches any file. Can be restricted by other values in the glob.
- * Equivalent to <code>/ .* /x</code> in regexp.
- *
- * <code>*</code>:: Matches all files
- * <code>c*</code>:: Matches all files beginning with <code>c</code>
- * <code>*c</code>:: Matches all files ending with <code>c</code>
- * <code>\*c\*</code>:: Match all files that have <code>c</code> in them
- * (including at the beginning or end).
- *
- * Note, this will not match Unix-like hidden files (dotfiles). In order
- * to include those in the match results, you must use the
- * File::FNM_DOTMATCH flag or something like <code>"{*,.*}"</code>.
- *
- * <code>**</code>::
- * Matches directories recursively.
- *
- * <code>?</code>::
- * Matches any one character. Equivalent to <code>/.{1}/</code> in regexp.
- *
- * <code>[set]</code>::
- * Matches any one character in +set+. Behaves exactly like character sets
- * in Regexp, including set negation (<code>[^a-z]</code>).
- *
- * <code>{p,q}</code>::
- * Matches either literal <code>p</code> or literal <code>q</code>.
- * Equivalent to pattern alternation in regexp.
- *
- * Matching literals may be more than one character in length. More than
- * two literals may be specified.
- *
- * <code> \\ </code>::
- * Escapes the next metacharacter.
- *
- * Note that this means you cannot use backslash on windows as part of a
- * glob, i.e. <code>Dir["c:\\foo*"]</code> will not work, use
- * <code>Dir["c:/foo*"]</code> instead.
- *
- * Examples:
- *
- * Dir["config.?"] #=> ["config.h"]
- * Dir.glob("config.?") #=> ["config.h"]
- * Dir.glob("*.[a-z][a-z]") #=> ["main.rb"]
- * Dir.glob("*.[^r]*") #=> ["config.h"]
- * Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"]
- * Dir.glob("*") #=> ["config.h", "main.rb"]
- * Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "config.h", "main.rb"]
- *
- * rbfiles = File.join("**", "*.rb")
- * Dir.glob(rbfiles) #=> ["main.rb",
- * # "lib/song.rb",
- * # "lib/song/karaoke.rb"]
- *
- * Dir.glob(rbfiles, base: "lib") #=> ["song.rb",
- * # "song/karaoke.rb"]
- *
- * libdirs = File.join("**", "lib")
- * Dir.glob(libdirs) #=> ["lib"]
- *
- * librbfiles = File.join("**", "lib", "**", "*.rb")
- * Dir.glob(librbfiles) #=> ["lib/song.rb",
- * # "lib/song/karaoke.rb"]
- *
- * librbfiles = File.join("**", "lib", "*.rb")
- * Dir.glob(librbfiles) #=> ["lib/song.rb"]
- */
static VALUE
-dir_s_glob(int argc, VALUE *argv, VALUE obj)
+dir_s_glob(rb_execution_context_t *ec, VALUE obj, VALUE str, VALUE rflags, VALUE base, VALUE sort)
{
- VALUE str, rflags, ary, opts, base;
- int flags;
-
- argc = rb_scan_args(argc, argv, "11:", &str, &rflags, &opts);
- if (argc == 2)
- flags = NUM2INT(rflags);
- else
- flags = 0;
- dir_glob_options(opts, &base, &flags);
-
- ary = rb_check_array_type(str);
+ VALUE ary = rb_check_array_type(str);
+ const int flags = NUM2INT(rflags) | dir_glob_option_sort(sort);
+ base = dir_glob_option_base(base);
if (NIL_P(ary)) {
ary = rb_push_glob(str, base, flags);
}
else {
- VALUE v = ary;
- ary = dir_globs(RARRAY_LEN(v), RARRAY_CONST_PTR(v), base, flags);
- RB_GC_GUARD(v);
+ ary = dir_globs(ary, base, flags);
}
if (rb_block_given_p()) {
@@ -2633,7 +2968,7 @@ dir_s_glob(int argc, VALUE *argv, VALUE obj)
static VALUE
dir_open_dir(int argc, VALUE *argv)
{
- VALUE dir = rb_funcallv(rb_cDir, rb_intern("open"), argc, argv);
+ VALUE dir = rb_funcallv_kw(rb_cDir, rb_intern("open"), argc, argv, RB_PASS_CALLED_KEYWORDS);
rb_check_typeddata(dir, &dir_data_type);
return dir;
@@ -2687,8 +3022,8 @@ dir_collect(VALUE dir)
* Dir.entries( dirname, encoding: enc ) -> array
*
* Returns an array containing all of the filenames in the given
- * directory. Will raise a <code>SystemCallError</code> if the named
- * directory doesn't exist.
+ * directory. Will raise a SystemCallError if the named directory
+ * doesn't exist.
*
* The optional <i>encoding</i> keyword argument specifies the encoding of the
* directory. If not specified, the filesystem encoding is used.
@@ -2743,6 +3078,44 @@ dir_s_each_child(int argc, VALUE *argv, VALUE io)
return Qnil;
}
+/*
+ * call-seq:
+ * dir.each_child {| filename | block } -> dir
+ * dir.each_child -> an_enumerator
+ *
+ * Calls the block once for each entry except for "." and ".." in
+ * this directory, passing the filename of each entry as a parameter
+ * to the block.
+ *
+ * If no block is given, an enumerator is returned instead.
+ *
+ * d = Dir.new("testdir")
+ * d.each_child {|x| puts "Got #{x}" }
+ *
+ * <em>produces:</em>
+ *
+ * Got config.h
+ * Got main.rb
+ *
+ */
+static VALUE
+dir_each_child_m(VALUE dir)
+{
+ RETURN_ENUMERATOR(dir, 0, 0);
+ return dir_each_entry(dir, dir_yield, Qnil, TRUE);
+}
+
+/*
+ * call-seq:
+ * dir.children -> array
+ *
+ * Returns an array containing all of the filenames except for "."
+ * and ".." in this directory.
+ *
+ * d = Dir.new("testdir")
+ * d.children #=> ["config.h", "main.rb"]
+ *
+ */
static VALUE
dir_collect_children(VALUE dir)
{
@@ -2757,8 +3130,8 @@ dir_collect_children(VALUE dir)
* Dir.children( dirname, encoding: enc ) -> array
*
* Returns an array containing all of the filenames except for "."
- * and ".." in the given directory. Will raise a
- * <code>SystemCallError</code> if the named directory doesn't exist.
+ * and ".." in the given directory. Will raise a SystemCallError if
+ * the named directory doesn't exist.
*
* The optional <i>encoding</i> keyword argument specifies the encoding of the
* directory. If not specified, the filesystem encoding is used.
@@ -2860,6 +3233,7 @@ fnmatch_brace(const char *pattern, VALUE val, void *enc)
*
* File.fnmatch('cat', 'CAT') #=> false # case sensitive
* File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD) #=> true # case insensitive
+ * File.fnmatch('cat', 'CAT', File::FNM_SYSCASE) #=> true or false # depends on the system default
*
* File.fnmatch('?', '/', File::FNM_PATHNAME) #=> false # wildcard doesn't match '/' on FNM_PATHNAME
* File.fnmatch('*', '/', File::FNM_PATHNAME) #=> false # ditto
@@ -2906,7 +3280,7 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
else
flags = 0;
- StringValue(pattern);
+ StringValueCStr(pattern);
FilePathStringValue(path);
if (flags & FNM_EXTGLOB) {
@@ -2972,28 +3346,15 @@ rb_file_directory_p(void)
}
#endif
-/*
- * call-seq:
- * Dir.exists?(file_name) -> true or false
- *
- * Deprecated method. Don't use.
- */
+/* :nodoc: */
static VALUE
rb_dir_exists_p(VALUE obj, VALUE fname)
{
- rb_warning("Dir.exists? is a deprecated name, use Dir.exist? instead");
+ rb_warn_deprecated("Dir.exists?", "Dir.exist?");
return rb_file_directory_p(obj, fname);
}
static void *
-gc_for_fd_with_gvl(void *ptr)
-{
- int *e = ptr;
-
- return (void *)(rb_gc_for_fd(*e) ? Qtrue : Qfalse);
-}
-
-static void *
nogvl_dir_empty_p(void *ptr)
{
const char *path = ptr;
@@ -3003,7 +3364,7 @@ nogvl_dir_empty_p(void *ptr)
if (!dir) {
int e = errno;
- switch ((int)(VALUE)rb_thread_call_with_gvl(gc_for_fd_with_gvl, &e)) {
+ switch (gc_for_fd_with_gvl(e)) {
default:
dir = opendir(path);
if (dir) break;
@@ -3039,7 +3400,7 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname)
const char *path;
enum {false_on_notdir = 1};
- GlobPathValue(dirname, FALSE);
+ FilePathValue(dirname);
orig = rb_str_dup_frozen(dirname);
dirname = rb_str_encode_ospath(dirname);
dirname = rb_str_dup_frozen(dirname);
@@ -3073,10 +3434,9 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname)
}
/*
- * Objects of class <code>Dir</code> are directory streams representing
- * directories in the underlying file system. They provide a variety of
- * ways to list directories and their contents. See also
- * <code>File</code>.
+ * Objects of class Dir are directory streams representing
+ * directories in the underlying file system. They provide a variety
+ * of ways to list directories and their contents. See also File.
*
* The directory used in these examples contains the two regular files
* (<code>config.h</code> and <code>main.rb</code>), the parent
@@ -3091,19 +3451,19 @@ Init_Dir(void)
rb_include_module(rb_cDir, rb_mEnumerable);
rb_define_alloc_func(rb_cDir, dir_s_alloc);
- rb_define_singleton_method(rb_cDir, "open", dir_s_open, -1);
rb_define_singleton_method(rb_cDir, "foreach", dir_foreach, -1);
rb_define_singleton_method(rb_cDir, "entries", dir_entries, -1);
rb_define_singleton_method(rb_cDir, "each_child", dir_s_each_child, -1);
rb_define_singleton_method(rb_cDir, "children", dir_s_children, -1);
- rb_define_method(rb_cDir,"initialize", dir_initialize, -1);
rb_define_method(rb_cDir,"fileno", dir_fileno, 0);
rb_define_method(rb_cDir,"path", dir_path, 0);
rb_define_method(rb_cDir,"to_path", dir_path, 0);
rb_define_method(rb_cDir,"inspect", dir_inspect, 0);
rb_define_method(rb_cDir,"read", dir_read, 0);
rb_define_method(rb_cDir,"each", dir_each, 0);
+ rb_define_method(rb_cDir,"each_child", dir_each_child_m, 0);
+ rb_define_method(rb_cDir,"children", dir_collect_children, 0);
rb_define_method(rb_cDir,"rewind", dir_rewind, 0);
rb_define_method(rb_cDir,"tell", dir_tell, 0);
rb_define_method(rb_cDir,"seek", dir_seek, 1);
@@ -3121,8 +3481,6 @@ Init_Dir(void)
rb_define_singleton_method(rb_cDir,"unlink", dir_s_rmdir, 1);
rb_define_singleton_method(rb_cDir,"home", dir_s_home, -1);
- rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, -1);
- rb_define_singleton_method(rb_cDir,"[]", dir_s_aref, -1);
rb_define_singleton_method(rb_cDir,"exist?", rb_file_directory_p, 1);
rb_define_singleton_method(rb_cDir,"exists?", rb_dir_exists_p, 1);
rb_define_singleton_method(rb_cDir,"empty?", rb_dir_s_empty_p, 1);
@@ -3177,3 +3535,5 @@ Init_Dir(void)
*/
rb_file_const("FNM_SHORTNAME", INT2FIX(FNM_SHORTNAME));
}
+
+#include "dir.rbinc"
diff --git a/dir.rb b/dir.rb
new file mode 100644
index 0000000000..eb46305013
--- /dev/null
+++ b/dir.rb
@@ -0,0 +1,136 @@
+class Dir
+ # Dir.open( string ) -> aDir
+ # Dir.open( string, encoding: enc ) -> aDir
+ # Dir.open( string ) {| aDir | block } -> anObject
+ # Dir.open( string, encoding: enc ) {| aDir | block } -> anObject
+ #
+ # The optional <i>encoding</i> keyword argument specifies the encoding of the directory.
+ # If not specified, the filesystem encoding is used.
+ #
+ # With no block, <code>open</code> is a synonym for Dir::new. If a
+ # block is present, it is passed <i>aDir</i> as a parameter. The
+ # directory is closed at the end of the block, and Dir::open returns
+ # the value of the block.
+ def self.open(name, encoding: nil, &block)
+ dir = Primitive.dir_s_open(name, encoding)
+ if block
+ begin
+ yield dir
+ ensure
+ Primitive.dir_s_close(dir)
+ end
+ else
+ dir
+ end
+ end
+
+ # Dir.new( string ) -> aDir
+ # Dir.new( string, encoding: enc ) -> aDir
+ #
+ # Returns a new directory object for the named directory.
+ #
+ # The optional <i>encoding</i> keyword argument specifies the encoding of the directory.
+ # If not specified, the filesystem encoding is used.
+ def initialize(name, encoding: nil)
+ Primitive.dir_initialize(name, encoding)
+ end
+
+ # Dir[ string [, string ...] [, base: path] [, sort: true] ] -> array
+ #
+ # Equivalent to calling
+ # <code>Dir.glob([</code><i>string,...</i><code>], 0)</code>.
+ def self.[](*args, base: nil, sort: true)
+ Primitive.dir_s_aref(args, base, sort)
+ end
+
+ # Dir.glob( pattern, [flags], [base: path] [, sort: true] ) -> array
+ # Dir.glob( pattern, [flags], [base: path] [, sort: true] ) { |filename| block } -> nil
+ #
+ # Expands +pattern+, which is a pattern string or an Array of pattern
+ # strings, and returns an array containing the matching filenames.
+ # If a block is given, calls the block once for each matching filename,
+ # passing the filename as a parameter to the block.
+ #
+ # The optional +base+ keyword argument specifies the base directory for
+ # interpreting relative pathnames instead of the current working directory.
+ # As the results are not prefixed with the base directory name in this
+ # case, you will need to prepend the base directory name if you want real
+ # paths.
+ #
+ # The results which matched single wildcard or character set are sorted in
+ # binary ascending order, unless false is given as the optional +sort+
+ # keyword argument. The order of an Array of pattern strings and braces
+ # are preserved.
+ #
+ # Note that the pattern is not a regexp, it's closer to a shell glob.
+ # See File::fnmatch for the meaning of the +flags+ parameter.
+ # Case sensitivity depends on your system (File::FNM_CASEFOLD is ignored).
+ #
+ # <code>*</code>::
+ # Matches any file. Can be restricted by other values in the glob.
+ # Equivalent to <code>/ .* /mx</code> in regexp.
+ #
+ # <code>*</code>:: Matches all files
+ # <code>c*</code>:: Matches all files beginning with <code>c</code>
+ # <code>*c</code>:: Matches all files ending with <code>c</code>
+ # <code>\*c\*</code>:: Match all files that have <code>c</code> in them
+ # (including at the beginning or end).
+ #
+ # Note, this will not match Unix-like hidden files (dotfiles). In order
+ # to include those in the match results, you must use the
+ # File::FNM_DOTMATCH flag or something like <code>"{*,.*}"</code>.
+ #
+ # <code>**</code>::
+ # Matches directories recursively if followed by <code>/</code>. If
+ # this path segment contains any other characters, it is the same as the
+ # usual <code>*</code>.
+ #
+ # <code>?</code>::
+ # Matches any one character. Equivalent to <code>/.{1}/</code> in regexp.
+ #
+ # <code>[set]</code>::
+ # Matches any one character in +set+. Behaves exactly like character sets
+ # in Regexp, including set negation (<code>[^a-z]</code>).
+ #
+ # <code>{p,q}</code>::
+ # Matches either literal <code>p</code> or literal <code>q</code>.
+ # Equivalent to pattern alternation in regexp.
+ #
+ # Matching literals may be more than one character in length. More than
+ # two literals may be specified.
+ #
+ # <code> \\ </code>::
+ # Escapes the next metacharacter.
+ #
+ # Note that this means you cannot use backslash on windows as part of a
+ # glob, i.e. <code>Dir["c:\\foo*"]</code> will not work, use
+ # <code>Dir["c:/foo*"]</code> instead.
+ #
+ # Examples:
+ #
+ # Dir["config.?"] #=> ["config.h"]
+ # Dir.glob("config.?") #=> ["config.h"]
+ # Dir.glob("*.[a-z][a-z]") #=> ["main.rb"]
+ # Dir.glob("*.[^r]*") #=> ["config.h"]
+ # Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"]
+ # Dir.glob("*") #=> ["config.h", "main.rb"]
+ # Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "config.h", "main.rb"]
+ # Dir.glob(["*.rb", "*.h"]) #=> ["main.rb", "config.h"]
+ #
+ # Dir.glob("**/*.rb") #=> ["main.rb",
+ # # "lib/song.rb",
+ # # "lib/song/karaoke.rb"]
+ #
+ # Dir.glob("**/*.rb", base: "lib") #=> ["song.rb",
+ # # "song/karaoke.rb"]
+ #
+ # Dir.glob("**/lib") #=> ["lib"]
+ #
+ # Dir.glob("**/lib/**/*.rb") #=> ["lib/song.rb",
+ # # "lib/song/karaoke.rb"]
+ #
+ # Dir.glob("**/lib/*.rb") #=> ["lib/song.rb"]
+ def self.glob(pattern, _flags = 0, flags: _flags, base: nil, sort: true)
+ Primitive.dir_s_glob(pattern, flags, base, sort)
+ end
+end
diff --git a/dln.c b/dln.c
index 55f29fda51..caaa685a6e 100644
--- a/dln.c
+++ b/dln.c
@@ -22,6 +22,7 @@
static void dln_loaderror(const char *format, ...);
#endif
#include "dln.h"
+#include "internal.h"
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
@@ -231,13 +232,13 @@ load_header(int fd, struct exec *hdrp, long disp)
# define R_RIGHTSHIFT(r) (reloc_r_rightshift[(r)->r_type])
# define R_BITSIZE(r) (reloc_r_bitsize[(r)->r_type])
# define R_LENGTH(r) (reloc_r_length[(r)->r_type])
-static int reloc_r_rightshift[] = {
+static const int reloc_r_rightshift[] = {
0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 0, 0, 0,
};
-static int reloc_r_bitsize[] = {
+static const int reloc_r_bitsize[] = {
8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,
};
-static int reloc_r_length[] = {
+static const int reloc_r_length[] = {
0, 1, 2, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
};
# define R_PCREL(r) \
@@ -1170,7 +1171,7 @@ dln_strerror(void)
}
#endif
-#if defined(_AIX) && ! defined(_IA64)
+#if defined(_AIX)
static void
aix_loaderror(const char *pathname)
{
@@ -1242,6 +1243,23 @@ rb_w32_check_imported(HMODULE ext, HMODULE mine)
#define translit_separator(str) (void)(str)
#endif
+#ifdef USE_DLN_DLOPEN
+# include "ruby/internal/stdbool.h"
+# include "internal/warnings.h"
+COMPILER_WARNING_PUSH
+#if defined(__clang__) || GCC_VERSION_SINCE(4, 2, 0)
+COMPILER_WARNING_IGNORED(-Wpedantic)
+#endif
+static bool
+dln_incompatible_library_p(void *handle)
+{
+ void *ex = dlsym(handle, EXTERNAL_PREFIX"ruby_xmalloc");
+ void *const fp = (void *)ruby_xmalloc;
+ return ex && ex != fp;
+}
+COMPILER_WARNING_POP
+#endif
+
void*
dln_load(const char *file)
{
@@ -1329,8 +1347,7 @@ dln_load(const char *file)
}
# if defined RUBY_EXPORT
{
- void *ex = dlsym(handle, EXTERNAL_PREFIX"ruby_xmalloc");
- if (ex && ex != ruby_xmalloc) {
+ if (dln_incompatible_library_p(handle)) {
# if defined __APPLE__ && \
defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
@@ -1386,7 +1403,7 @@ dln_load(const char *file)
}
#endif /* hpux */
-#if defined(_AIX) && ! defined(_IA64)
+#if defined(_AIX)
#define DLN_DEFINED
{
void (*init_fct)();
diff --git a/dln.h b/dln.h
index d98b2607e2..99106fd22b 100644
--- a/dln.h
+++ b/dln.h
@@ -1,3 +1,5 @@
+#ifndef DLN_H
+#define DLN_H
/**********************************************************************
dln.h -
@@ -9,24 +11,7 @@
**********************************************************************/
-#ifndef DLN_H
-#define DLN_H
-
-#ifdef __cplusplus
-# ifndef HAVE_PROTOTYPES
-# define HAVE_PROTOTYPES 1
-# endif
-# ifndef HAVE_STDARG_PROTOTYPES
-# define HAVE_STDARG_PROTOTYPES 1
-# endif
-#endif
-
-#undef _
-#ifdef HAVE_PROTOTYPES
-# define _(args) args
-#else
-# define _(args) ()
-#endif
+#include "ruby/defines.h" /* for RUBY_SYMBOL_EXPORT_BEGIN */
RUBY_SYMBOL_EXPORT_BEGIN
diff --git a/dln_find.c b/dln_find.c
index b08612764e..ca62441631 100644
--- a/dln_find.c
+++ b/dln_find.c
@@ -248,26 +248,14 @@ dln_find_1(const char *fname, const char *path, char *fbuf, size_t size,
/* now append the file name */
i = fnlen;
if (fspace < i) {
- toolong:
- PATHNAME_TOO_LONG();
- goto next;
+ goto toolong;
}
fspace -= i;
memcpy(bp, fname, i + 1);
#if defined(DOSISH)
if (exe_flag && !ext) {
- needs_extension:
- for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) {
- if (fspace < strlen(extension[j])) {
- PATHNAME_TOO_LONG();
- continue;
- }
- strlcpy(bp + i, extension[j], fspace);
- if (stat(fbuf, &st) == 0)
- return fbuf;
- }
- goto next;
+ goto needs_extension;
}
#endif
@@ -284,7 +272,25 @@ dln_find_1(const char *fname, const char *path, char *fbuf, size_t size,
if (*ep == '\0') {
return NULL;
}
+ continue;
+
+ toolong:
+ PATHNAME_TOO_LONG();
+ goto next;
+#if defined(DOSISH)
+ needs_extension:
+ for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) {
+ if (fspace < strlen(extension[j])) {
+ PATHNAME_TOO_LONG();
+ continue;
+ }
+ strlcpy(bp + i, extension[j], fspace);
+ if (stat(fbuf, &st) == 0)
+ return fbuf;
+ }
+ goto next;
+#endif
/* otherwise try the next component in the search path */
}
}
diff --git a/dmydln.c b/dmydln.c
index 0fc0a5325e..d05cda0b8e 100644
--- a/dmydln.c
+++ b/dmydln.c
@@ -6,5 +6,5 @@ dln_load(const char *file)
{
rb_loaderror("this executable file can't load extension libraries");
- UNREACHABLE;
+ UNREACHABLE_RETURN(NULL);
}
diff --git a/doc/.document b/doc/.document
index d739c9f6bc..ad17aada6d 100644
--- a/doc/.document
+++ b/doc/.document
@@ -1,3 +1,4 @@
+*.md
*.rdoc
NEWS-*
syntax
diff --git a/doc/ChangeLog-0.60_to_1.1 b/doc/ChangeLog-0.60_to_1.1
index 33b0326892..bd5f140dc3 100644
--- a/doc/ChangeLog-0.60_to_1.1
+++ b/doc/ChangeLog-0.60_to_1.1
@@ -3166,7 +3166,7 @@ Fri Aug 11 14:37:03 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
* io.c: マクロREAD_DATA_PENDINGã®å®šç¾©ã‚’変更(Linux対応)
- * io.c (io_fptr_finalize): fptrã®é–‹æ”¾æ™‚ã®å‡¦ç†ã‚’指定ã§ãるよã†ã«ï¼Ž
+ * io.c (io_fptr_finalize): fptrã®è§£æ”¾æ™‚ã®å‡¦ç†ã‚’指定ã§ãるよã†ã«ï¼Ž
Wed Aug 9 16:52:41 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
@@ -3448,7 +3448,7 @@ Thu May 18 12:27:23 1995 Yukihiro Matsumoto <matz@ix-02>
ç„¡ããªã£ãŸ(ã¨æ€ã†).
* gc.c (gc): the_scopeをマークã—ã¦ã„ãªã‹ã£ãŸã®ã§ï¼Œãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã®æŒ‡
- ã—ã¦ã„るオブジェクトãŒé–“é•ã£ã¦é–‹æ”¾ã•れる場åˆãŒã‚ã£ãŸï¼Ž
+ ã—ã¦ã„るオブジェクトãŒé–“é•ã£ã¦è§£æ”¾ã•れる場åˆãŒã‚ã£ãŸï¼Ž
* gc.c (mark_locations_array): 若干ã®é«˜é€ŸåŒ–.
diff --git a/doc/ChangeLog-1.8.0 b/doc/ChangeLog-1.8.0
index 3f7d6bfb3c..6d9453d011 100644
--- a/doc/ChangeLog-1.8.0
+++ b/doc/ChangeLog-1.8.0
@@ -13020,7 +13020,7 @@ Tue Jun 12 00:41:18 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
Mon Jun 11 14:29:41 2001 WATANABE Hirofumi <eban@ruby-lang.org>
- * confgure.in: add RUBY_CANONICAL_BUILD.
+ * configure.in: add RUBY_CANONICAL_BUILD.
Sun Jun 10 17:31:47 2001 Guy Decoux <decoux@moulon.inra.fr>
diff --git a/doc/ChangeLog-1.9.3 b/doc/ChangeLog-1.9.3
index eecfc44325..d6aaea7f19 100644
--- a/doc/ChangeLog-1.9.3
+++ b/doc/ChangeLog-1.9.3
@@ -92076,7 +92076,7 @@ Mon Sep 1 16:59:10 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_thread_start_0): should not error_print() within
terminated thread, because $stderr used by it might be
- overriden now. [ruby-dev:21280]
+ overridden now. [ruby-dev:21280]
Sun Aug 31 22:46:55 2003 WATANABE Hirofumi <eban@ruby-lang.org>
diff --git a/doc/ChangeLog-2.0.0 b/doc/ChangeLog-2.0.0
index a1a79b8dca..b51d742203 100644
--- a/doc/ChangeLog-2.0.0
+++ b/doc/ChangeLog-2.0.0
@@ -9758,7 +9758,7 @@ Thu Aug 23 16:20:04 2012 Koichi Sasada <ko1@atdot.net>
are b10.
If flonum is activated, then USE_FLONUM macro is 1.
I'll write detailed in this technique on
- https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/Flonum_tech
+ https://bugs.ruby-lang.org/projects/ruby-master/wiki/Flonum_tech
* benchmark/bmx_temp.rb: add an benchmark for simple
Float calculation.
@@ -13008,7 +13008,7 @@ Thu Jun 7 15:53:03 2012 Koichi Sasada <ko1@atdot.net>
* .gdbinit: add function `trace_machine_instructions' to trace
in native machine assemble.
- See https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/MachineInstructionsTraceWithGDB
+ See https://bugs.ruby-lang.org/projects/ruby-master/wiki/MachineInstructionsTraceWithGDB
for more details.
Wed Jun 6 21:31:21 2012 Tanaka Akira <akr@fsij.org>
@@ -14711,7 +14711,7 @@ Fri Apr 27 01:45:05 2012 NARUSE, Yui <naruse@ruby-lang.org>
(22) main thread waits at gvl_yield:112 (native_cond_wait)
As described above, the main thread can't escape from
rb_threadptr_execute_interrupts_common.
- See extended memo: http://bugs.ruby-lang.org/projects/ruby-trunk/wiki/R35480_ExtendedMemo
+ See extended memo: http://bugs.ruby-lang.org/projects/ruby-master/wiki/R35480_ExtendedMemo
Fri Apr 27 07:15:07 2012 Tanaka Akira <akr@fsij.org>
diff --git a/doc/ChangeLog-2.1.0 b/doc/ChangeLog-2.1.0
index 76edfd3ce7..5b670b31c9 100644
--- a/doc/ChangeLog-2.1.0
+++ b/doc/ChangeLog-2.1.0
@@ -3596,7 +3596,7 @@ Tue Oct 22 19:19:05 2013 Koichi Sasada <ko1@atdot.net>
maintains all pages.
For example, pages are allocated from the heap_pages.
- See https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/GC_design
+ See https://bugs.ruby-lang.org/projects/ruby-master/wiki/GC_design
and https://bugs.ruby-lang.org/attachments/4015/data-heap_structure_with_multiple_heaps.png
for more details.
@@ -8612,7 +8612,7 @@ Wed Jul 17 14:31:13 2013 Koichi Sasada <ko1@atdot.net>
(4) heap::sorted is an array of "slots", sorted by an address of
slot::body.
- See https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/GC_design
+ See https://bugs.ruby-lang.org/projects/ruby-master/wiki/GC_design
for more details (figure).
* gc.c: Avoid "heaps" terminology. It is ambiguous.
diff --git a/doc/ChangeLog-2.4.0 b/doc/ChangeLog-2.4.0
index 1714b7caec..96b5ecb077 100644
--- a/doc/ChangeLog-2.4.0
+++ b/doc/ChangeLog-2.4.0
@@ -4690,7 +4690,7 @@ Thu May 19 13:22:44 2016 Kazuki Yamaguchi <k@rhe.jp>
* ext/openssl/ossl.c (Init_openssl): register an ex_data index for
X509_STORE and X509_STORE_CTX respectively. Since they don't share
the ex_data index registry, we can't use the same index.
- (ossl_verify_cb): use the the correct index.
+ (ossl_verify_cb): use the correct index.
* ext/openssl/ossl_ssl.c (ossl_ssl_verify_callback): ditto.
diff --git a/doc/ChangeLog-2016 b/doc/ChangeLog-2016
deleted file mode 100644
index c708428a93..0000000000
--- a/doc/ChangeLog-2016
+++ /dev/null
@@ -1,5 +0,0 @@
-------------------------------------------------------------------------
-r56645 | naruse | 2016-11-07 00:56:27 +0900 (Mon, 07 Nov 2016) | 1 line
-
-Obsolete ChangeLog [Feature #12283]
-------------------------------------------------------------------------
diff --git a/doc/NEWS-1.9.2 b/doc/NEWS-1.9.2
index fedb1f6633..430c6cc4f5 100644
--- a/doc/NEWS-1.9.2
+++ b/doc/NEWS-1.9.2
@@ -240,7 +240,7 @@ with all sufficient information, see the ChangeLog file.
* new alias of item.guid.isPermaLink=
* DL
- * Now uses libffi as a backend if avaiable.
+ * Now uses libffi as a backend if available.
It means DL works fine on more platforms.
* Fiddle
diff --git a/doc/NEWS-2.0.0 b/doc/NEWS-2.0.0
index 9ad7254317..712d3a693b 100644
--- a/doc/NEWS-2.0.0
+++ b/doc/NEWS-2.0.0
@@ -94,7 +94,7 @@ with all sufficient information, see the ChangeLog file.
required caller size.
* Kernel#to_enum and enum_for accept a block for lazy size evaluation.
* incompatible changes:
- * system() and exec() closes non-standard file descriptors
+ * system() and exec() close non-standard file descriptors
(The default of :close_others option is changed to true by default.)
* respond_to? against a protected method now returns false unless
the second argument is true.
@@ -116,8 +116,7 @@ with all sufficient information, see the ChangeLog file.
corresponding method in the prepending module.
* added Module.prepended and Module.prepend_features, similar
to included and append_features.
- * added Module#refine, which extends a class or module locally.
- [experimental]
+ * added Module#refine, which extends a class or module locally. [experimental]
* extended method:
* Module#define_method accepts a UnboundMethod from a Module.
* Module#const_get accepts a qualified constant string, e.g.
@@ -497,7 +496,7 @@ with all sufficient information, see the ChangeLog file.
* Dir.mktmpdir uses FileUtils.remove_entry instead of
FileUtils.remove_entry_secure. This means that applications should not
change the permission of the created temporary directory to make
- accessible from other users.
+ writable from other users.
* yaml
* Syck has been removed. YAML now completely depends on libyaml being
@@ -528,4 +527,3 @@ with all sufficient information, see the ChangeLog file.
* NUM2SHORT() and NUM2USHORT() added. They are similar to NUM2INT, but short.
* rb_newobj_of() and NEWOBJ_OF() added. They create a new object of a given class.
-
diff --git a/doc/NEWS-2.2.0 b/doc/NEWS-2.2.0
index 5564c606ae..98e252ec77 100644
--- a/doc/NEWS-2.2.0
+++ b/doc/NEWS-2.2.0
@@ -90,7 +90,7 @@ with all sufficient information, see the ChangeLog file.
* Method
* New methods:
- * Method#curry([arity]) returns a curried Proc.
+ * Method#curry([ arity ]) returns a curried Proc.
* Method#super_method returns a Method of superclass, which would be called
when super is used.
@@ -250,8 +250,7 @@ with all sufficient information, see the ChangeLog file.
* Logger::Application is extracted to logger-application gem. It's unmaintain code.
* ObjectSpace (after requiring "objspace")
- * ObjectSpace.memsize_of(obj) returns a size includes sizeof(RVALUE).
- [Bug #8984]
+ * ObjectSpace.memsize_of(obj) returns a size includes sizeof(RVALUE). [Bug #8984]
* Prime
* incompatible changes:
@@ -353,8 +352,7 @@ with all sufficient information, see the ChangeLog file.
* VM
* Use frozen string literals for Hash#[] and Hash#[]=
* Fast keyword arguments passing [Feature #10440]
- * Allow to receive huge splatted array by a rest argument
- [Feature #10440]
+ * Allow to receive huge splatted array by a rest argument [Feature #10440]
* Process
* Process creation methods, such as spawn(), uses vfork() system call.
diff --git a/doc/NEWS-2.3.0 b/doc/NEWS-2.3.0
index 489aba4a89..065515257e 100644
--- a/doc/NEWS-2.3.0
+++ b/doc/NEWS-2.3.0
@@ -16,20 +16,19 @@ with all sufficient information, see the ChangeLog file or Redmine
* frozen-string-literal pragma:
- * new pragma, frozen-string-literal has been experimentally introduced.
- [Feature #8976]
+ * new pragma, frozen-string-literal has been experimentally introduced. [Feature #8976]
* besides, --enable/--disable=frozen-string-literal options also have
been introduced. [Feature #8976]
* command line options --debug or --debug=frozen-string-literal enable
additional debugging mode which shows created location with at frozen
- object error (RuntimeError).
- [Feature #11725]
+ object error (RuntimeError). [Feature #11725]
* safe navigation operator:
* new method call syntax, `object&.foo', method #foo is called on
- `object' if it is not nil.
- this is similar to `try!' in Active Support, except:
+ `object' if it is not nil. [Feature #11537]
+
+ This is similar to `try!' in Active Support, except:
* method name is syntactically required
obj.try! {} # valid
obj&. {} # syntax error
@@ -38,7 +37,6 @@ with all sufficient information, see the ChangeLog file or Redmine
obj&.foo(bar()) # bar() is conditionally evaluated
* attribute assignment is valid
obj&.attr += 1
- [Feature #11537]
* the did_you_mean gem:
@@ -53,15 +51,13 @@ with all sufficient information, see the ChangeLog file or Redmine
* indented here document:
* new string literal, here document starts with `<<~`.
- refer doc/syntax/literals.rdoc for more details.
- [Feature #9098]
+ refer doc/syntax/literals.rdoc for more details. [Feature #9098]
=== Core classes updates (outstanding ones only)
* ARGF
- * ARGF.read_nonblock supports `exception: false' like IO#read_nonblock.
- [Feature #11358]
+ * ARGF.read_nonblock supports `exception: false' like IO#read_nonblock. [Feature #11358]
* Array
@@ -78,8 +74,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* Enumerable
- * Enumerable#grep_v is added as inverse version of Enumerable#grep.
- [Feature #11049]
+ * Enumerable#grep_v is added as inverse version of Enumerable#grep. [Feature #11049]
* Enumerable#chunk_while [Feature #10769]
* Enumerator::Lazy
@@ -105,8 +100,7 @@ with all sufficient information, see the ChangeLog file or Redmine
this affect only files opened as binary. [Feature #11218]
* new option parameter `flags' is added.
- this parameter is bitwise-ORed to oflags generated by normal mode argument.
- [Feature #11253]
+ this parameter is bitwise-ORed to oflags generated by normal mode argument. [Feature #11253]
* IO#advise no longer raises Errno::ENOSYS in cases where it was
detected at build time but not available at runtime. [Feature #11806]
@@ -125,8 +119,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* Numeric
* Numeric#positive? and Numeric#negative? are added, which return
- true when the receiver is positive and negative respectively.
- [Feature #11151]
+ true when the receiver is positive and negative respectively. [Feature #11151]
* Proc
@@ -152,11 +145,9 @@ with all sufficient information, see the ChangeLog file or Redmine
* String
- * String#+@ and String#-@ are added to get mutable/frozen strings.
- [Feature #11782]
+ * String#+@ and String#-@ are added to get mutable/frozen strings. [Feature #11782]
- * String.new now accepts new option parameter `encoding'.
- [Feature #11785]
+ * String.new now accepts new option parameter `encoding'. [Feature #11785]
* Struct
* Struct#dig [Feature #11688]
@@ -233,12 +224,10 @@ with all sufficient information, see the ChangeLog file or Redmine
* OpenSSL
* OpenSSL::SSL::SSLSocket#accept_nonblock and
- OpenSSL::SSL::SSLSocket#connect_nonblock supports `exception: false`.
- [Feature #10532]
+ OpenSSL::SSL::SSLSocket#connect_nonblock supports `exception: false`. [Feature #10532]
* Pathname
- * Pathname#descend and Pathname#ascend supported blockless form.
- [Feature #11052]
+ * Pathname#descend and Pathname#ascend supported blockless form. [Feature #11052]
* Socket
* Socket#connect_nonblock, Socket#accept_nonblock,
@@ -246,8 +235,7 @@ with all sufficient information, see the ChangeLog file or Redmine
BasicSocket#recv_nonblock, BasicSocket#recvmsg_nonblock,
BasicSocket#sendmsg_nonblock all support `exception: false` to return
:wait_readable or :wait_writable symbols instead of raising
- IO::WaitReadable or IO::WaitWritable exceptions
- [Feature #10532] [Feature #11229]
+ IO::WaitReadable or IO::WaitWritable exceptions [Feature #10532] [Feature #11229]
* BasicSocket#recv and BasicSocket#recv_nonblock allow an output
String buffer argument like IO#read and IO#read_nonblock to reduce
GC overhead [Feature #11242]
@@ -255,8 +243,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* StringIO
* In read-only mode, StringIO#set_encoding no longer sets the encoding
of its buffer string. Setting the encoding of the string directly
- without StringIO#set_encoding may cause unpredictable behavior now.
- [Bug #11827]
+ without StringIO#set_encoding may cause unpredictable behavior now. [Bug #11827]
* timeout
* Object#timeout is now warned as deprecated when called.
@@ -297,8 +284,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* default value of Net::HTTP#open_timeout is now 60 (was nil).
* Net::Telnet
- * Net::Telnet is extracted to net-telnet gem. It's unmaintain code.
- [Feature #11083]
+ * Net::Telnet is extracted to net-telnet gem. It's unmaintain code. [Feature #11083]
* Psych
* Updated to Psych 2.0.17
@@ -330,8 +316,7 @@ with all sufficient information, see the ChangeLog file or Redmine
class is already defined but its superclass does not match the given
superclass, as well as definitions in ruby level.
-* rb_timespec_now() is added to fetch current datetime as struct timespec.
- [Feature #11558]
+* rb_timespec_now() is added to fetch current datetime as struct timespec. [Feature #11558]
* rb_time_timespec_new() is added to create a time object with epoch,
nanosecond, and UTC/localtime/time offset arguments. [Feature #11558]
@@ -354,11 +339,9 @@ with all sufficient information, see the ChangeLog file or Redmine
=== Implementation improvements
-* Optimize Proc#call to eliminate method frame construction.
- [Feature #11569]
+* Optimize Proc#call to eliminate method frame construction. [Feature #11569]
-* Reconsidering method entry data structure.
- [Bug #11278]
+* Reconsidering method entry data structure. [Bug #11278]
* Introducing new table data structure for ID keys tables used by
method table and so on. New table structure is simple and fast
@@ -367,13 +350,11 @@ with all sufficient information, see the ChangeLog file or Redmine
* Machine code level tuning for object allocation and method calling
code. r52099, r52254
-* RubyVM::InstructionSequence is extended for future improvement.
- [Feature #11788]
+* RubyVM::InstructionSequence is extended for future improvement. [Feature #11788]
* Case dispatch is now optimized for all special constant literals
including nil, true, and false. Previously, only literal strings,
- symbols, integers and floats compiled to optimized case dispatch.
- [Feature #11769]
+ symbols, integers and floats compiled to optimized case dispatch. [Feature #11769]
* Instance variables on non-pure Ruby classes (T_DATA, T_FILE,
etc..) is less expensive to store than before. [Feature #11170]
@@ -382,8 +363,7 @@ with all sufficient information, see the ChangeLog file or Redmine
constant-time. Previously, Struct elements beyond the first 10
elements used a linear scan. [Feature #10585]
-* The Set class got several speed up.
- [Misc #10754], [r52591]
+* The Set class got several speed up. [Misc #10754], [r52591]
* Socket and I/O-related improvements
@@ -397,8 +377,8 @@ with all sufficient information, see the ChangeLog file or Redmine
addition to reducing expensive exceptions. [Feature #11044]
* (Linux-only) waiting on a single FD anywhere in the stdlib no longer
- uses select(2), making it immune to slowdowns with high-numbered FDs.
- [Feature #11081] [Feature #11377]
+ uses select(2), making it immune to slowdowns with high-numbered
+ FDs. [Feature #11081] [Feature #11377]
* CGI.escapeHTML is optimized with C extension.
https://github.com/ruby/ruby/pull/1164
diff --git a/doc/NEWS-2.4.0 b/doc/NEWS-2.4.0
index 1c0bc904e4..8a02f03809 100644
--- a/doc/NEWS-2.4.0
+++ b/doc/NEWS-2.4.0
@@ -14,16 +14,13 @@ with all sufficient information, see the ChangeLog file or Redmine
=== Language changes
-* Multiple assignment in conditional expression is now allowed.
- [Feature #10617]
+* Multiple assignment in conditional expression is now allowed. [Feature #10617]
* Refinements is enabled at method by Symbol#to_proc. [Feature #9451]
-* Refinements is enabled with Kernel#send and BasicObject#__send__.
- [Feature #11476]
+* Refinements is enabled with Kernel#send and BasicObject#__send__. [Feature #11476]
-* Rescue modifier now applicable to method arguments.
- [Feature #12686]
+* Rescue modifier now applicable to method arguments. [Feature #12686]
* Toplevel return is now allowed. [Feature #4840]
@@ -32,17 +29,21 @@ with all sufficient information, see the ChangeLog file or Redmine
* Array
* Array#concat [Feature #12333]
+
Now takes multiple arguments.
* Array#max and Array#min. [Feature #12172]
+
This may cause a tiny incompatibility: if you redefine
Enumerable#max and call max to an Array, your redefinition will be
now ignored. You should also redefine Array#max.
* Array#pack [Feature #12754]
+
Now takes optional argument `buffer:' to reuse already allocated buffer.
* Array#sum [Feature #12217]
+
This is different from Enumerable#sum in that Array#sum doesn't depend on
the definition of each method.
@@ -56,8 +57,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* Enumerable
- * Enumerable#chunk called without a block now return an Enumerator
- [Feature #2172]
+ * Enumerable#chunk called without a block now return an Enumerator [Feature #2172]
* Enumerable#sum [Feature #12217]
* Enumerable#uniq [Feature #11090]
@@ -95,6 +95,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* Integer#round now takes an optional keyword argument, half option, and the
default behavior is round-up now. [Bug #12548] [Bug #12958]
+
half option can be one of :even, :up, and :down. [Feature #12953]
* IO
@@ -104,8 +105,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* Kernel
- * Kernel#clone now takes an optional keyword argument, freeze flag.
- [Feature #12300]
+ * Kernel#clone now takes an optional keyword argument, freeze flag. [Feature #12300]
* MatchData
@@ -138,11 +138,12 @@ with all sufficient information, see the ChangeLog file or Redmine
for UTR #51 Unicode Emoji, Version 4.0 emoji zwj sequences.
* Regexp#match? [Feature #8110]
+
This returns bool and doesn't save backref.
- * Update Onigmo 6.0.0.
+ * Update to Onigmo 6.0.0.
-* Regexp/String: Updated Unicode version from 8.0.0 to 9.0.0 [Feature #12513]
+* Regexp/String: Update Unicode version from 8.0.0 to 9.0.0 [Feature #12513]
* RubyVM::Env
@@ -153,6 +154,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* String#casecmp? [Feature #12786]
* String#concat, String#prepend [Feature #12333]
+
Now takes multiple arguments.
* String#each_line, String#lines now takes an optional keyword argument,
@@ -189,8 +191,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* Thread
- * Thread#report_on_exception and Thread.report_on_exception
- [Feature #6647]
+ * Thread#report_on_exception and Thread.report_on_exception [Feature #6647]
* TracePoint
@@ -200,8 +201,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* New module named Warning is introduced. By default it has only
one singleton method, named warn. This makes it possible for
- 3rd-party libraries to control the way warnings are handled.
- [Feature #12299]
+ 3rd-party libraries to control the way warnings are handled. [Feature #12299]
=== Stdlib updates (outstanding ones only)
@@ -215,8 +215,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* IPAddr
- * IPAddr#== and IPAddr#<=> no longer raise an exception if coercion fails.
- [Bug #12799]
+ * IPAddr#== and IPAddr#<=> no longer raise an exception if coercion fails. [Bug #12799]
* IRB
@@ -256,8 +255,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* Readline
- * Readline.quoting_detection_proc and Readline.quoting_detection_proc=
- [Feature #12659]
+ * Readline.quoting_detection_proc and Readline.quoting_detection_proc= [Feature #12659]
* REXML
@@ -267,8 +265,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* set
- * New methods: Set#compare_by_identity and Set#compare_by_identity?.
- [Feature #12210]
+ * New methods: Set#compare_by_identity and Set#compare_by_identity?. [Feature #12210]
* WEBrick
@@ -277,6 +274,7 @@ with all sufficient information, see the ChangeLog file or Redmine
=== Compatibility issues (excluding feature bug fixes)
* Array#sum and Enumerable#sum are implemented. [Feature #12217]
+
Ruby itself has no compatibility problem because Ruby didn't have sum method
for arrays before Ruby 2.4.
However many third party gems, activesupport, facets, simple_stats, etc,
@@ -286,6 +284,7 @@ with all sufficient information, see the ChangeLog file or Redmine
be perfectly compatible with all of them.
* Fixnum and Bignum are unified into Integer [Feature #12005]
+
Fixnum class and Bignum class is removed.
Integer class is changed from abstract class to concrete class.
For example, 0 is an instance of Integer: 0.class returns Integer.
@@ -300,6 +299,7 @@ with all sufficient information, see the ChangeLog file or Redmine
* String/Symbol#upcase/downcase/swapcase/capitalize(!) now work for all of
Unicode, not only for ASCII. [Feature #10085]
+
No change is needed if the data is in ASCII anyway or if the limitation
to ASCII was only tolerated while waiting for a more extensive implementation.
A change (using the :ascii option) is needed in cases where Unicode data
@@ -307,6 +307,7 @@ with all sufficient information, see the ChangeLog file or Redmine
A good example of this are internationalized domain names.
* TRUE / FALSE / NIL
+
These constants are now obsoleted. [Feature #12574]
Use true / false / nil resp. instead.
@@ -316,24 +317,23 @@ with all sufficient information, see the ChangeLog file or Redmine
* DateTime#to_time now preserves timezone. [Bug #12189]
-* PSych
+* Psych
- * Update Psych 2.2.2
+ * Update to Psych 2.2.2
* RDoc
- * Update RDoc 5.0.0
+ * Update to RDoc 5.0.0
* RubyGems
- * Update RubyGems 2.6.8
+ * Update to RubyGems 2.6.8
* shellwords
* Shellwords.shellwords (shellsplit) treats the backslash as escape
character only when followed by one of the following characters:
- $ ` " \ <newline>
- [Bug #10055]
+ $ ` " \ <newline> [Bug #10055]
* Time
@@ -348,11 +348,13 @@ with all sufficient information, see the ChangeLog file or Redmine
* Tk
* Tk is removed from stdlib. [Feature #8539]
+
https://github.com/ruby/tk is the new upstream.
* XMLRPC
* XMLRPC is removed from stdlib, and bundled as gem. [Feature #12160][ruby-core:74239]
+
https://github.com/ruby/xmlrpc is the new upstream.
* Zlib
@@ -390,8 +392,8 @@ with all sufficient information, see the ChangeLog file or Redmine
=== Miscellaneous changes
* ChangeLog is removed from the repository.
+
It is generated from commit messages in Subversion by `make dist`.
Also note that now people should follow Git style commit message.
- The template is written at
- [Short (50 chars or less) summary of changes](https://git-scm.com/book/ch5-2.html).
- [Feature #12283]
+ The template is written at {Short (50 chars or less) summary of
+ changes}[https://git-scm.com/book/ch5-2.html]. [Feature #12283]
diff --git a/doc/NEWS-2.5.0 b/doc/NEWS-2.5.0
new file mode 100644
index 0000000000..c891317b61
--- /dev/null
+++ b/doc/NEWS-2.5.0
@@ -0,0 +1,565 @@
+# -*- rdoc -*-
+
+= NEWS for Ruby 2.5.0
+
+This document is a list of user visible feature changes made between
+releases except for bug fixes.
+
+Note that each entry is kept so brief that no reason behind or
+reference information is supplied with. For a full list of changes
+with all sufficient information, see the ChangeLog file or Redmine
+(e.g. <tt>https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER</tt>)
+
+== Changes since the 2.4.0 release
+
+=== Language changes
+
+* Top-level constant look-up is removed. [Feature #11547]
+
+* rescue/else/ensure are allowed inside do/end blocks. [Feature #12906]
+
+* refinements take place in string interpolations. [Feature #13812]
+
+=== Core classes updates (outstanding ones only)
+
+* Array
+
+ * New methods:
+
+ * Array#append [Feature #12746]
+ * Array#prepend [Feature #12746]
+
+* Data
+
+ * Is deprecated. It was a base class for C extensions, and it's not
+ necessary to expose in Ruby level. [Feature #3072]
+
+* Exception
+
+ * New methods:
+
+ * Exception#full_message to retrieve a String expression of an exception,
+ formatted in the same way in which Ruby prints out an uncaught
+ exception. [Feature #14141] [experimental]
+
+* Dir
+
+ * Dir.glob provides new optional keyword argument, +:base+ . [Feature #13056]
+ * Dir.chdir (without block arg), Dir.open, Dir.new, Dir.mkdir, Dir.rmdir,
+ Dir.empty? releases GVL
+
+ * New methods:
+
+ * Dir.children [Feature #11302]
+ * Dir.each_child [Feature #11302]
+
+* Enumerable
+
+ * Enumerable#any?, Enumerable#all?, Enumerable#none? and Enumerable#one?
+ accept a pattern argument. [Feature #11286]
+
+* File
+
+ * File.open accepts +:newline+ option to imply text mode. [Bug #13350]
+ * File#path raises an IOError for files opened with
+ File::Constants::TMPFILE option. [Feature #13568]
+ * File.stat, File.exist? and other <code>rb_stat()</code>-using methods
+ release GVL. [Bug #13941]
+ * File.rename releases GVL. [Feature #13951]
+ * File::Stat#atime, File::Stat#mtime and File::Stat#ctime support fractional
+ second timestamps on Windows 8 and later. [Feature #13726]
+ * File::Stat#ino and File.identical? support ReFS 128bit ino on Windows 8.1
+ and later. [Feature #13731]
+ * File.readable?, File.readable_real?, File.writable?, File.writable_real?,
+ File.executable?, File.executable_real?, File.mkfifo, File.readlink,
+ File.truncate, File#truncate, File.chmod, File.lchmod, File.chown,
+ File.lchown, File.unlink, File.utime, File.lstat release GVL
+
+ * New method:
+
+ * File.lutime [Feature #4052]
+
+* Hash
+
+ * New methods:
+
+ * Hash#transform_keys [Feature #13583]
+ * Hash#transform_keys! [Feature #13583]
+ * Hash#slice [Feature #8499]
+
+* IO
+
+ * IO.copy_stream tries copy offload with copy_file_range(2) [Feature #13867]
+
+ * New methods:
+
+ * IO#pread [Feature #4532]
+ * IO#pwrite [Feature #4532]
+ * IO#write accepts multiple arguments [Feature #9323]
+
+* IOError
+
+ * IO#close might raise an error with message "stream closed",
+ but it is refined to "stream closed in another thread". The new message
+ is more clear for user. [Bug #13405]
+
+* Integer
+
+ * Integer#round, Integer#floor, Integer#ceil and Integer#truncate always
+ return an Integer. [Bug #13420]
+ * Integer#pow accepts modulo argument for calculating modular
+ exponentiation. [Feature #12508] [Feature #11003]
+
+ * New methods:
+
+ * Integer#allbits?, Integer#anybits?, Integer#nobits? [Feature #12753]
+ * Integer.sqrt [Feature #13219]
+
+* Kernel
+
+ * Kernel#yield_self [Feature #6721]
+ * Kernel#pp [Feature #14123]
+ * Kernel#warn(..., uplevel:n) [Feature #12882]
+
+* Method
+
+ * New methods:
+
+ * Method#=== that invokes Method#call, as same as Proc#=== [Feature #14142]
+
+* Module
+
+ * Module#attr, Module#attr_accessor, Module#attr_reader and Module#attr_writer
+ become public. [Feature #14132]
+ * Module#define_method, Module#alias_method, Module#undef_method and
+ Module#remove_method become public. [Feature #14133]
+
+* Numeric
+
+ * Numeric#step no longer hides errors from coerce method when
+ given a step value which cannot be compared with #> to 0. [Feature #7688]
+ * Numerical comparison operators (<,<=,>=,>) no longer hide exceptions
+ from #coerce method internally. Return nil in #coerce if the coercion is
+ impossible. [Feature #7688]
+
+* Process
+
+ * Precision of Process.times is improved if getrusage(2) exists. [Feature #11952]
+
+ * New method:
+
+ * Process.last_status as an alias of $? [Feature #14043]
+
+* Range
+ * Range#initialize no longer hides exceptions when comparing begin and
+ end with #<=> and raise a "bad value for range" ArgumentError
+ but instead lets the exception from the #<=> call go through. [Feature #7688]
+
+* Regexp
+
+ * Update to Onigmo 6.1.3-669ac9997619954c298da971fcfacccf36909d05.
+
+ * Support absence operator https://github.com/k-takata/Onigmo/issues/82
+
+ * Support new 5 emoji-related Unicode character properties
+
+* RubyVM::InstructionSequence
+
+ * New method:
+
+ * RubyVM::InstructionSequence#each_child
+ * RubyVM::InstructionSequence#trace_points
+
+* String
+
+ * <code>String#-@</code> deduplicates unfrozen strings. Already-frozen
+ strings remain unchanged for compatibility. [Feature #13077]
+ * <code>-"literal"</code> (<code>String#-@</code>) optimized to return the same object
+ (same as <code>"literal".freeze</code> in Ruby 2.1+) [Feature #13295]
+ * String#casecmp and String#casecmp? return nil for non-string arguments
+ instead of raising a TypeError. [Bug #13312]
+ * String#start_with? accepts a regexp [Feature #13712]
+
+ * New methods:
+
+ * String#delete_prefix, String#delete_prefix! [Feature #12694]
+ * String#delete_suffix, String#delete_suffix! [Feature #13665]
+ * String#each_grapheme_cluster and String#grapheme_clusters to
+ enumerate grapheme clusters [Feature #13780]
+ * String#undump to unescape String#dump'ed string [Feature #12275]
+
+* Struct
+
+ * Struct.new takes `keyword_init: true` option to initialize members
+ with keyword arguments. [Feature #11925]
+
+* Regexp/String: Update Unicode version from 9.0.0 to 10.0.0 [Feature #13685]
+
+* Thread
+
+ * Description set by Thread#name= is now visible on Windows 10.
+
+ * New method:
+ * Thread#fetch [Feature #13009]
+
+ * The default of Thread.report_on_exception is now true,
+ showing unhandled exceptions terminating threads on $stderr. [Feature #14143]
+
+* Time
+
+ * Time.at receives 3rd argument which specifies the unit of 2nd argument. [Feature #13919]
+
+* KeyError
+
+ * New methods:
+
+ * KeyError#receiver [Feature #12063]
+ * KeyError#key [Feature #12063]
+
+* FrozenError
+
+ * New exception class. [Feature #13224]
+
+=== Stdlib updates (outstanding ones only)
+
+* BigDecimal
+
+ * Update to BigDecimal 1.3.4
+
+ * The following features are added:
+
+ * BigDecimal::VERSION
+
+ * The following features have been deprecated,
+ and are planned to be removed in the version 1.4.0:
+
+ * BigDecimal.new
+
+ * BigDecimal.ver
+
+ * BigDecimal#clone and #dup now do not make a new instance,
+ but returns the receiver itself.
+
+* Coverage
+
+ * Support branch coverage and method coverage measurement. [Feature #13901]
+ Branch coverage tells you which branches are executed, and which not.
+ Method coverage tells you which methods are invoked, and which not.
+ By running a test suite with this new feature, you can know which branches
+ and methods are executed by a test, and evaluate total coverage of a test
+ suite more strictly.
+
+ You can specify the measuring target by an option to `Coverage.start`:
+
+ Coverage.start(lines: true, branches: true, methods: true)
+
+ After some Ruby files are loaded, you can use `Coverage.result` to get
+ the coverage result:
+
+ Coverage.result
+ #=> { "/path/to/file.rb"=>
+ # { :lines => [1, 2, 0, nil, ...],
+ # :branches =>
+ # { [:if, 0, 2, 1, 6, 4] =>
+ # { [:then, 1, 3, 2, 3, 8] => 0,
+ # [:else, 2, 5, 2, 5, 8] => 2
+ # }
+ # },
+ # :methods => {
+ # [Object, :foo, 1, 0, 7, 3] => 2
+ # }
+ # }
+ # }
+
+ The result type of line coverage is not changed; it is just an array that
+ contains numbers, which means the count that each line was executed,
+ or `nil`s, which means that the line is not relevant.
+
+ The result type of branch coverage is:
+
+ { (jump base) => { (jump target) => (counter) } }
+
+ where jump base and targets have the format
+
+ [type, unique-id, start lineno, start column, end lineno, end column]
+
+ For example, `[:if, 0, 2, 1, 6, 4]` reads an `if` statement that ranges from
+ line 2 and column 1, to line 6 and column 4. `[:then, 1, 3, 2, 3, 8]` reads
+ a `then` clause that ranges from line 3 and column 2, to line 3 and column 8.
+ Note that lineno starts from 1, and that columnno starts from 0. So, the
+ above example shows a branch from the `if` to the `then` was never executed,
+ and a branch from the `if` to the `else` was executed twice.
+
+ The result type of method coverage is:
+
+ { (method key) => (counter) }
+
+ where method key has the format
+
+ [class, method-name, start lineno, start column, end lineno, end column]
+
+ For example, `[Object, :foo, 1, 0, 7, 3]` reads `Object#foo` that ranges from
+ line 1 and column 0, to line 7 and column 3. The above example shows this
+ `Object#foo` was invoked twice.
+
+ Note: To keep compatibility, passing no option to `Coverage.start` will measure
+ only line coverage, and `Coverage.result` will return the old format:
+
+ Coverage.result
+ #=> { "/path/to/file.rb"=> [1, 2, 0, nil, ...] }
+
+* DRb
+
+ * ACL::ACLEntry.new no longer suppresses IPAddr::InvalidPrefixError.
+
+* ERB
+
+ * Add ERB#result_with_hash to render a template with local variables passed
+ with a Hash object. [Feature #8631]
+
+ * Default template file encoding is changed from ASCII-8BIT to UTF-8 in erb
+ command. [Bug #14095]
+
+ * Carriage returns are changed to be trimmed properly if trim_mode is specified
+ and used. Duplicated newlines will be removed on Windows. [Bug #5339] [Bug #11464]
+
+* IPAddr
+
+ * IPAddr no longer accepts invalid address mask. [Bug #13399]
+ * IPAddr#ipv4_compat and IPAddr#ipv4_compat? are marked for deprecation. [Bug #13769]
+
+ * New methods:
+
+ * IPAddr#prefix
+ * IPAddr#loopback?
+ * IPAddr#private? [Feature #11666]
+ * IPAddr#link_local? [Feature #10912]
+
+* IRB
+
+ * Print backtrace and error message in reverse order [Feature #8661] [experimental]
+ * `binding.irb` automatically requires irb and runs [Bug #13099] [experimental]
+ * `binding.irb` on its start shows source around the line where it was called [Feature #14124]
+
+* Matrix
+
+ * New methods:
+
+ * Matrix.combine and Matrix#combine [Feature #10903]
+ * Matrix#hadamard_product and Matrix#entrywise_product
+
+* Net::HTTP
+
+ * Net::HTTP.new supports no_proxy parameter [Feature #11195]
+ * Net::HTTP#min_version and Net::HTTP#max_version [Feature #9450]
+ * Add more HTTP status classes
+ * Net::HTTP::STATUS_CODES is added as HTTP Status Code Repository [Misc #12935]
+ * Net::HTTP#proxy_user and Net::HTTP#proxy_pass reflect http_proxy environment
+ variable if the system's environment variable is multiuser safe. [Bug #12921]
+
+* open-uri
+ * URI.open method defined as an alias to open-uri's Kernel.open.
+ open-uri's Kernel.open will be deprecated in future.
+
+* OpenSSL
+
+ * Updated Ruby/OpenSSL from version 2.0 to 2.1. Changes are noted in
+ "Version 2.1.0" section in ext/openssl/History.md.
+
+* Pathname
+
+ * New method:
+
+ * Pathname#glob [Feature #7360]
+
+* Psych
+
+ * Update to Psych 3.0.2.
+
+ * Convert fallback option to a keyword argument
+ https://github.com/ruby/psych/pull/342
+ * Add :symbolize_names option to Psych.load, Psych.safe_load like JSON.parse
+ https://github.com/ruby/psych/pull/333, https://github.com/ruby/psych/pull/337
+ * Add Psych::Handler#event_location
+ https://github.com/ruby/psych/pull/326
+ * Make frozen string literal = true
+ https://github.com/ruby/psych/pull/320
+ * Preserve time zone offset when deserializing times
+ https://github.com/ruby/psych/pull/316
+ * Remove deprecated method aliases for syck gem
+ https://github.com/ruby/psych/pull/312
+
+* RbConfig
+
+ * RbConfig::LIMITS is added to provide the limits of C types.
+ This is available when rbconfig/sizeof is loaded.
+
+* Ripper
+
+ * Ripper::EXPR_BEG and so on for Ripper#state.
+
+ * New method:
+
+ * Ripper#state to tell the state of scanner. [Feature #13686]
+
+* RDoc
+
+ * Update to RDoc 6.0.1.
+
+ * Replace IRB based lexer with Ripper.
+ * https://github.com/ruby/rdoc/pull/512
+ * This much improves the speed of generating documents.
+ * It also facilitates supporting new syntax in the future.
+ * Support many new syntaxes of Ruby from the past few years.
+ * Use "frozen_string_literal: true".
+ Performance survey: https://gist.github.com/aycabta/abdfaa75ea8a6877eeb734e942e73800
+ * Support did_you_mean.
+
+* Rubygems
+
+ * Update to Rubygems 2.7.3.
+ * http://blog.rubygems.org/2017/11/28/2.7.3-released.html
+ * http://blog.rubygems.org/2017/11/08/2.7.2-released.html
+ * http://blog.rubygems.org/2017/11/03/2.7.1-released.html
+ * http://blog.rubygems.org/2017/11/01/2.7.0-released.html
+ * http://blog.rubygems.org/2017/10/09/2.6.14-released.html
+ * http://blog.rubygems.org/2017/08/27/2.6.13-released.html
+
+* SecureRandom
+
+ * New method:
+
+ * SecureRandom.alphanumeric
+
+* Set
+
+ * New methods:
+
+ * Set#to_s as alias to #inspect [Feature #13676]
+ * Set#=== as alias to #include? [Feature #13801]
+ * Set#reset [Feature #6589]
+
+* StringIO
+
+ * StringIO#write accepts multiple arguments
+
+* StringScanner
+
+ * New methods:
+
+ * StringScanner#size, StringScanner#captures, StringScanner#values_at [Feature #836]
+
+* URI
+
+ * Relative path operations no longer collapse consecutive slashes to a single slash. [Bug #8352]
+
+* WEBrick
+
+ * Add Server Name Indication (SNI) support [Feature #13729]
+ * support Proc objects as body responses [Feature #855]
+ * released as a RubyGem [Feature #13173]
+ * avoid unintended behavior from Kernel#open [Misc #14216]
+
+* Zlib
+
+ * Zlib::GzipWriter#write accepts multiple arguments
+
+=== Compatibility issues (excluding feature bug fixes)
+
+* Socket
+
+ * BasicSocket#read_nonblock and BasicSocket#write_nonblock no
+ longer set the O_NONBLOCK file description flag as side effect
+ (on Linux only) [Feature #13362]
+
+* Random
+
+ * Random.raw_seed renamed to become Random.urandom. It is now
+ applicable to non-seeding purposes due to [Bug #9569].
+
+* Socket
+
+ * Socket::Ifaddr#vhid is added [Feature #13803]
+
+* ConditionVariable, Queue and SizedQueue reimplemented for speed.
+ They no longer subclass Struct. [Feature #13552]
+
+=== Stdlib compatibility issues (excluding feature bug fixes)
+
+* Gemification
+
+ * Promote following standard libraries to default gems.
+ * cmath
+ * csv
+ * date
+ * dbm
+ * etc
+ * fcntl
+ * fiddle
+ * fileutils
+ * gdbm
+ * ipaddr
+ * scanf
+ * sdbm
+ * stringio
+ * strscan
+ * webrick
+ * zlib
+
+* Logger
+
+ * Logger.new("| command") had been working to open a command
+ unintentionally. It was prohibited, and now Logger#initialize
+ treats a String argument only as a filename, as its specification. [Bug #14212]
+
+* Net::HTTP
+
+ * Net::HTTP#start now passes :ENV to p_addr by default. [Bug #13351]
+ To avoid this, pass nil explicitly.
+
+* mathn.rb
+
+ * Removed from stdlib. [Feature #10169]
+
+* Rubygems
+
+ * Removed "ubygems.rb" file from stdlib. It's needless since Ruby 1.9.
+
+=== Supported platform changes
+
+* Drop support of NaCl platform
+
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=239656#c160
+
+=== Implementation improvements
+
+* (This might not be a "user visible feature change" but) Hash class's
+ hash function is now SipHash13. [Feature #13017]
+
+* SecureRandom now prefers OS-provided sources than OpenSSL. [Bug #9569]
+
+* Mutex rewritten to be smaller and faster [Feature #13517]
+
+* Performance of block passing using block parameters is improved by
+ lazy Proc allocation [Feature #14045]
+
+* Dynamic instrumentation for TracePoint hooks instead of using "trace"
+ instruction to avoid overhead [Feature #14104]
+
+* ERB now generates code from a template twice as fast as Ruby 2.4
+
+=== Miscellaneous changes
+
+* Print backtrace and error message in reverse order if $stderr is unchanged
+ and a tty. [Feature #8661] [experimental]
+
+* Print error message in bold/underlined text if $stderr is unchanged and a
+ tty. [Feature #14140] [experimental]
+
+* configure option --with-ext now mandates its arguments. So for
+ instance if you run ./configure --with-ext=openssl,+ then the
+ openssl library is guaranteed compiled, otherwise the build fails
+ abnormally.
+
+ Note however to always add the ",+" at the end of the argument.
+ Otherwise nothing but openssl are built. [Feature #13302]
diff --git a/doc/NEWS-2.6.0 b/doc/NEWS-2.6.0
new file mode 100644
index 0000000000..6e70696de2
--- /dev/null
+++ b/doc/NEWS-2.6.0
@@ -0,0 +1,662 @@
+# -*- rdoc -*-
+
+= NEWS for Ruby 2.6.0
+
+This document is a list of user visible feature changes made between
+releases except for bug fixes.
+
+Note that each entry is kept so brief that no reason behind or reference
+information is supplied with. For a full list of changes with all
+sufficient information, see the ChangeLog file or Redmine
+(e.g. <tt>https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER</tt>)
+
+== Changes since the 2.5.0 release
+
+=== Language changes
+
+* <code>$SAFE</code> now is a process global state and can be set to 0 again. [Feature #14250]
+
+* Refinements take place at block passing. [Feature #14223]
+
+* Refinements take place at Kernel#public_send. [Feature #15326]
+
+* Refinements take place at Kernel#respond_to?. [Feature #15327]
+
+* +else+ without +rescue+ now causes a syntax error. [EXPERIMENTAL] [Feature #14606]
+
+* Constant names may start with a non-ASCII capital letter. [Feature #13770]
+
+* Endless ranges are introduced. You can use a Range that has no end,
+ like <code>(0..)</code> (or similarly <code>(0...)</code>). [Feature #12912]
+
+ The following shows typical use cases:
+
+ ary[1..] # identical to ary[1..-1]
+ (1...).each {|index| block } # infinite loop from index 1
+ ary.zip(1..) {|elem, index| block } # ary.each.with_index(1) { }
+
+* Non-Symbol keys in a keyword arguments hash cause an exception.
+
+* The "shadowing outer local variable" warning is removed. [Feature #12490]
+
+ You can now write the following without warning:
+
+ user = users.find {|user| cond(user) }
+
+* Print +cause+ of the exception if the exception is not caught and printed
+ its backtraces and error message. [Feature #8257]
+
+* The flip-flop syntax is deprecated. [Feature #5400]
+
+=== Core classes updates (outstanding ones only)
+
+[Array]
+
+ [New methods]
+
+ * Added Array#union and Array#difference instance methods. [Feature #14097]
+
+ [Modified method]
+
+ * Array#to_h now accepts a block that maps elements to new key/value pairs. [Feature #15143]
+
+ [Aliased methods]
+
+ * Array#filter is a new alias for Array#select. [Feature #13784]
+ * Array#filter! is a new alias for Array#select!. [Feature #13784]
+
+[Binding]
+
+ [New method]
+
+ * Added Binding#source_location. [Feature #14230]
+
+ This method returns the source location of the binding, a 2-element
+ array of <code>__FILE__</code> and <code>__LINE__</code>.
+ Traditionally, the same information could be retrieved by
+ <code>eval("[__FILE__, __LINE__]", binding)</code>, but we are
+ planning to change this behavior so that Kernel#eval ignores
+ binding's source location [Bug #4352]. So, users should use this
+ newly-introduced method instead of Kernel#eval.
+
+[Dir]
+
+ [New methods]
+
+ * Added Dir#each_child and Dir#children instance methods. [Feature #13969]
+
+[Enumerable]
+
+ [New method]
+
+ * Enumerable#chain returns an enumerator object that iterates over the
+ elements of the receiver and then those of each argument
+ in sequence. [Feature #15144]
+
+ [Modified method]
+
+ * Enumerable#to_h now accepts a block that maps elements to new key/value pairs. [Feature #15143]
+
+ [Aliased method]
+
+ * Enumerable#filter is a new alias for Enumerable#select. [Feature #13784]
+
+[Enumerator::ArithmeticSequence]
+
+ * This is a new class to represent a generator of an arithmetic sequence,
+ that is a number sequence defined by a common difference. It can be used
+ for representing what is similar to Python's slice. You can get an
+ instance of this class from Numeric#step and Range#step.
+
+[Enumerator::Chain]
+
+ * This is a new class to represent a chain of enumerables that works as a
+ single enumerator, generated by such methods as Enumerable#chain and
+ Enumerator#+.
+
+[Enumerator::Lazy]
+
+ [Aliased method]
+
+ * Enumerator::Lazy#filter is a new alias for
+ Enumerator::Lazy#select. [Feature #13784]
+
+[Enumerator]
+
+ [New methods]
+
+ * Enumerator#+ returns an enumerator object that iterates over the
+ elements of the receiver and then those of the other operand. [Feature #15144]
+
+[ENV]
+
+ [Modified method]
+
+ * ENV.to_h now accepts a block that maps names and values to new keys and values. [Feature #15143]
+
+[Exception]
+
+ [New options]
+
+ * Exception#full_message takes +:highlight+ and +:order+
+ options. [Bug #14324]
+
+[Hash]
+
+ [Modified methods]
+
+ * Hash#merge, Hash#merge!, and Hash#update now accept multiple
+ arguments. [Feature #15111]
+
+ * Hash#to_h now accepts a block that maps keys and values to new keys and values. [Feature #15143]
+
+ [Aliased methods]
+
+ * Hash#filter is a new alias for Hash#select. [Feature #13784]
+
+ * Hash#filter! is a new alias for Hash#select!. [Feature #13784]
+
+[IO]
+
+ [New option]
+
+ * Added new mode character <code>'x'</code> to open files for exclusive
+ access. [Feature #11258]
+
+[Kernel]
+
+ [Aliased method]
+
+ * Kernel#then is a new alias for Kernel#yield_self. [Feature #14594]
+
+ [New options]
+
+ * Kernel#Complex, Kernel#Float, Kernel#Integer, and
+ Kernel#Rational take an +:exception+ option to specify the way of
+ error handling. [Feature #12732]
+
+ * Kernel#system takes an +:exception+ option to raise an exception
+ on failure. [Feature #14386]
+
+ [Incompatible changes]
+
+ * Kernel#system and Kernel#exec do not close non-standard file descriptors
+ (the default of the +:close_others+ option is changed to +false+,
+ but we still set the +FD_CLOEXEC+ flag on descriptors we
+ create). [Misc #14907]
+
+[KeyError]
+
+ [New options]
+
+ * KeyError.new accepts +:receiver+ and +:key+ options to set receiver and
+ key in Ruby code. [Feature #14313]
+
+[Method]
+
+ [New methods]
+
+ * Added Method#<< and Method#>> for Proc composition. [Feature #6284]
+
+[Module]
+
+ [Modified methods]
+
+ * Module#method_defined?, Module#private_method_defined?, and
+ Module#protected_method_defined? now accept the second
+ parameter as optional. If it is +true+ (the default value), it checks
+ ancestor modules/classes, or checks only the class itself. [Feature #14944]
+
+[NameError]
+
+ [New option]
+
+ * NameError.new accepts a +:receiver+ option to set receiver in Ruby
+ code. [Feature #14313]
+
+[NilClass]
+
+ [New method]
+
+ * NilClass#=~ is added for compatibility. [Feature #15231]
+
+[NoMethodError]
+
+ [New option]
+
+ * NoMethodError.new accepts a +:receiver+ option to set receiver in Ruby
+ code. [Feature #14313]
+
+[Numeric]
+
+ [Incompatible changes]
+
+ * Numeric#step now returns an instance of the Enumerator::ArithmeticSequence
+ class rather than one of the Enumerator class.
+
+[OpenStruct]
+
+ [Modified method]
+
+ * OpenStruct#to_h now accepts a block that maps keys and values to new keys and values. [Feature #15143]
+
+[Proc]
+
+ [New methods]
+
+ * Added Proc#<< and Proc#>> for Proc composition. [Feature #6284]
+
+ [Incompatible changes]
+
+ * Proc#call doesn't change <code>$SAFE</code> any more. [Feature #14250]
+
+[Random]
+
+ [New method]
+
+ * Added Random.bytes. [Feature #4938]
+
+[Range]
+
+ [New method]
+
+ * Added Range#% instance method. [Feature #14697]
+
+ [Incompatible changes]
+
+ * Range#=== now uses the +#cover?+ instead of the +#include?+ method. [Feature #14575]
+ * Range#cover? now accepts a Range object. [Feature #14473]
+ * Range#step now returns an instance of the Enumerator::ArithmeticSequence
+ class rather than one of the Enumerator class.
+
+[Regexp/String]
+
+ * Update Unicode version from 10.0.0 to 11.0.0. [Feature #14802]
+
+ This includes a rewrite of the grapheme cluster (/\X/) algorithm
+ and special-casing for Georgian MTAVRULI on String#downcase.
+
+ * Update Emoji version from 5.0 to 11.0.0 [Feature #14802]
+
+[RubyVM::AbstractSyntaxTree]
+
+ [New methods]
+
+ * RubyVM::AbstractSyntaxTree.parse parses a given string and returns AST
+ nodes. [experimental]
+
+ * RubyVM::AbstractSyntaxTree.parse_file parses a given file and returns AST
+ nodes. [experimental]
+
+ * RubyVM::AbstractSyntaxTree.of returns AST nodes of the given proc or
+ method. [experimental]
+
+[RubyVM]
+
+ [New method]
+
+ * RubyVM.resolve_feature_path identifies the file that will be loaded by
+ "require(feature)". [experimental] [Feature #15230]
+
+[String]
+
+ * String#crypt is now deprecated. [Feature #14915]
+
+ [New features]
+
+ * String#split yields each substring to the block if given. [Feature #4780]
+
+[Struct]
+
+ [Modified method]
+
+ * Struct#to_h now accepts a block that maps keys and values to new keys and values. [Feature #15143]
+
+ [Aliased method]
+
+ * Struct#filter is a new alias for Struct#select. [Feature #13784]
+
+[Time]
+
+ [New features]
+
+ * Time.new and Time#getlocal accept a timezone object as well as
+ a UTC offset string. Time#+, Time#-, and Time#succ also preserve
+ the timezone. [Feature #14850]
+
+[TracePoint]
+
+ [New features]
+
+ * "script_compiled" event is supported. [Feature #15287]
+
+ [New methods]
+
+ * TracePoint#parameters [Feature #14694]
+
+ * TracePoint#instruction_sequence [Feature #15287]
+
+ * TracePoint#eval_script [Feature #15287]
+
+ [Modified method]
+
+ * TracePoint#enable accepts new keywords "target:" and
+ "target_line:". [Feature #15289]
+
+=== Stdlib updates (outstanding ones only)
+
+[BigDecimal]
+
+ Update to version 1.4.0. This version includes several compatibility
+ issues, see Compatibility issues section below for details.
+
+ [Modified method]
+
+ * BigDecimal() accepts the new keyword "exception:" similar to Float().
+
+ [Note for the differences among recent versions]
+
+ You should want to know the differences among recent versions of bigdecimal.
+ Please select the suitable version of bigdecimal according to the following
+ information.
+
+ * 1.3.5 has BigDecimal.new without "exception:" keyword. You can see the
+ deprecation warning of BigDecimal.new when you specify "-w" option.
+ BigDecimal(), BigDecimal.new, and Object#to_d methods are the same.
+
+ * 1.4.0 has BigDecimal.new with "exception:" keyword. You always see the
+ deprecation warning of BigDecimal.new. Object#to_d method is different
+ from BigDecimal() and BigDecimal.new.
+
+ * 2.0.0 will be released soon after releasing Ruby 2.6.0. This version
+ will not have the BigDecimal.new method.
+
+[Bundler]
+
+ * Add Bundler to Standard Library. [Feature #12733]
+
+ * Use 1.17.2, the latest stable version.
+
+[Coverage]
+
+ A oneshot_lines mode is added. [Feature #15022]
+
+ This mode checks "whether each line was executed at least once or not",
+ instead of "how many times each line was executed".
+ A hook for each line is fired at most once, and after it is fired
+ the hook flag is removed, i.e., it runs with zero overhead.
+
+ [New options]
+
+ * Add +:oneshot_lines+ keyword argument to Coverage.start.
+
+ * Add +:stop+ and +:clear+ keyword arguments to Coverage.result.
+ If +clear+ is true, it clears the counters to zero.
+ If +stop+ is true, it disables coverage measurement.
+
+ [New methods]
+
+ * Coverage.line_stub, which is a simple helper function that
+ creates the "stub" of line coverage from a given source code.
+
+[CSV]
+
+ * Upgrade to 3.0.2. This includes performance improvements especially
+ for writing. Writing is about 2 times faster.
+ See https://github.com/ruby/csv/blob/master/NEWS.md.
+
+[ERB]
+
+ [New options]
+
+ * Add +:trim_mode+ and +:eoutvar+ keyword arguments to ERB.new.
+ Now non-keyword arguments other than the first one are softly deprecated
+ and will be removed when Ruby 2.5 becomes EOL. [Feature #14256]
+
+ * erb command's <tt>-S</tt> option is deprecated, and will be removed
+ in the next version.
+
+[FileUtils]
+
+ [New methods]
+
+ * FileUtils#cp_lr. [Feature #4189]
+
+[Matrix]
+
+ [New methods]
+
+ * Matrix#antisymmetric?, Matrix#skew_symmetric?
+
+ * Matrix#map!, Matrix#collect! [Feature #14151]
+
+ * Matrix#[]=
+
+ * Vector#map!, Vector#collect!
+
+ * Vector#[]=
+
+[Net]
+
+ [New options]
+
+ * Add +:write_timeout+ keyword argument to Net::HTTP.new. [Feature #13396]
+
+ [New methods]
+
+ * Add Net::HTTP#write_timeout and Net::HTTP#write_timeout=. [Feature #13396]
+
+ [New constant]
+
+ * Add Net::HTTPClientException to deprecate Net::HTTPServerException,
+ whose name is misleading. [Bug #14688]
+
+[NKF]
+
+ * Upgrade to nkf v2.1.5
+
+[Psych]
+
+ * Upgrade to Psych 3.1.0
+
+[RDoc]
+
+ * Become about 2 times faster.
+
+ * Use SOURCE_DATE_EPOCH to generate files.
+
+ * Fix method line number that slipped off.
+
+ * Enable <code>--width</code>, <code>--exclude</code>,
+ and <code>--line-numbers</code> that were ignored.
+
+ * Add support for blockquote by ">>>" in default markup notation.
+
+ * Add support for "Raises" lines in TomDoc notation.
+
+ * Fix syntax error output.
+
+ * Fix many parsing bugs.
+
+[REXML]
+
+ * Upgrade to REXML 3.1.9.
+ See https://github.com/ruby/rexml/blob/master/NEWS.md.
+
+ [Improved some XPath implementations]
+
+ * <code>concat()</code> function: Stringify all arguments before concatenating.
+
+ * <code>string()</code> function: Support context node.
+
+ * <code>string()</code> function: Support processing instruction node.
+
+ * Support <code>"*:#{ELEMENT_NAME}"</code> syntax in XPath 2.0.
+
+ [Fixed some XPath implementations]
+
+ * <code>"//#{ELEMENT_NAME}[#{POSITION}]"</code> case
+
+ * <code>string()</code> function: Fix <code>function(document)</code>
+ returns nodes that are out of root elements.
+
+ * <code>"/ #{ELEMENT_NAME} "</code> case
+
+ * <code>"/ #{ELEMENT_NAME} [ #{PREDICATE} ]"</code> case
+
+ * <code>"/ #{AXIS}::#{ELEMENT_NAME}"</code> case
+
+ * <code>"#{N}-#{M}"</code> case: One or more white spaces were required
+ before <code>"-"</code>
+
+ * <code>"/child::node()"</code> case
+
+ * <code>"#{FUNCTION}()/#{PATH}"</code> case
+
+ * <code>"@#{ATTRIBUTE}/parent::"</code> case
+
+ * <code>"name(#{NODE_SET})"</code> case
+
+[RSS]
+
+ [New options]
+
+ * RSS::Parser.parse now accepts options as Hash. +:validate+ ,
+ +:ignore_unknown_element+ , +:parser_class+ options are available.
+
+[RubyGems]
+
+ * Upgrade to RubyGems 3.0.1
+
+ * https://blog.rubygems.org/2018/12/19/3.0.0-released.html
+
+ * https://blog.rubygems.org/2018/12/23/3.0.1-released.html
+
+[Set]
+
+ [Aliased method]
+
+ * Set#filter! is a new alias for Set#select!. [Feature #13784]
+
+[URI]
+
+ [New constant]
+
+ * Add URI::File to handle the file URI scheme. [Feature #14035]
+
+=== Compatibility issues (excluding feature bug fixes)
+
+[Dir]
+
+ * Dir.glob with <code>'\0'</code>-separated pattern list will be deprecated,
+ and is now warned. [Feature #14643]
+
+[File]
+
+ * File.read, File.binread, File.write, File.binwrite, File.foreach, and
+ File.readlines do not invoke external commands even if the path starts
+ with the pipe character <code>'|'</code>. [Feature #14245]
+
+[Object]
+
+ * Object#=~ is deprecated. [Feature #15231]
+
+=== Stdlib compatibility issues (excluding feature bug fixes)
+
+* These standard libraries have been promoted to default gems.
+
+ * e2mmap
+ * forwardable
+ * irb
+ * logger
+ * matrix
+ * mutex_m
+ * ostruct
+ * prime
+ * rexml
+ * rss
+ * shell
+ * sync
+ * thwait
+ * tracer
+
+[BigDecimal]
+
+ * The following methods are removed.
+
+ * BigDecimal.allocate
+ * BigDecimal.ver
+
+ * Every BigDecimal object is frozen. [Feature #13984]
+
+ * BigDecimal() parses the given string similar to Float().
+
+ * String#to_d parses the receiver string similar to String#to_f.
+
+ * BigDecimal.new will be removed in version 2.0.
+
+[Pathname]
+
+ * Pathname#read, Pathname#binread, Pathname#write, Pathname#binwrite,
+ Pathname#each_line and Pathname#readlines do not invoke external
+ commands even if the path starts with the pipe character <code>'|'</code>.
+ This follows [Feature #14245].
+
+=== Implementation improvements
+
+* Speedup Proc#call because we don't need to care about <code>$SAFE</code>
+ any more. [Feature #14318]
+
+ With +lc_fizzbuzz+ benchmark which uses Proc#call many times we can
+ measure x1.4 improvements. [Bug #10212]
+
+* Speedup block.call where +block+ is passed block parameter. [Feature #14330]
+
+ Ruby 2.5 improves block passing performance. [Feature #14045]
+
+ Additionally, Ruby 2.6 improves the performance of passed block calling.
+
+* Introduce an initial implementation of a JIT (Just-in-time) compiler. [Feature #14235] [experimental]
+
+ * <tt>--jit</tt> command line option is added to enable JIT. <tt>--jit-verbose=1</tt>
+ is good for inspection. See <tt>ruby --help</tt> for others.
+ * To generate machine code, this JIT compiler uses the C compiler used for building
+ the interpreter. Currently GCC, Clang, and Microsoft Visual C++ are supported for it.
+ * <tt>--disable-mjit-support</tt> option is added to configure. This is added for JIT debugging,
+ but if you get an error on building a header file for JIT, you can use this option to skip
+ building it as a workaround.
+ * rb_waitpid reimplemented on Unix-like platforms to maintain
+ compatibility with processes created for JIT [Bug #14867]
+
+* VM generator script renewal; makes the generated VM more optimized. [GH-1779]
+
+* Thread cache enabled for pthreads platforms (for Thread.new and
+ Thread.start). [Feature #14757]
+
+* timer thread is eliminated for platforms with POSIX timers. [Misc #14937]
+
+* Transient Heap (theap) is supported. [Bug #14858] [Feature #14989]
+
+ theap is a managed heap for short-living memory objects. For example,
+ making a small and short-living Hash object is x2 faster. With rdoc benchmark,
+ we measured 6-7% performance improvement.
+
+* Native implementations (arm32, arm64, ppc64le, win32, win64, x86, amd64) of
+ coroutines to improve performance of Fiber significantly. [Feature #14739]
+
+=== Miscellaneous changes
+
+* On macOS, shared libraries no longer include a full version number of Ruby
+ in their names. This eliminates the burden of each teeny upgrade on the
+ platform that users need to rebuild every extension library.
+
+ [Before]
+ * libruby.2.6.0.dylib
+ * libruby.2.6.dylib -> libruby.2.6.0.dylib
+ * libruby.dylib -> libruby.2.6.0.dylib
+
+ [After]
+ * libruby.2.6.dylib
+ * libruby.dylib -> libruby.2.6.dylib
+
+* Extracted misc/*.el files to https://github.com/ruby/elisp
diff --git a/doc/NEWS-2.7.0 b/doc/NEWS-2.7.0
new file mode 100644
index 0000000000..3e6b98c1fd
--- /dev/null
+++ b/doc/NEWS-2.7.0
@@ -0,0 +1,826 @@
+# -*- rdoc -*-
+
+= NEWS for Ruby 2.7.0
+
+This document is a list of user visible feature changes made between
+releases except for bug fixes.
+
+Note that each entry is kept so brief that no reason behind or reference
+information is supplied with. For a full list of changes with all
+sufficient information, see the ChangeLog file or Redmine
+(e.g. <tt>https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER</tt>).
+
+== Changes since the 2.6.0 release
+
+=== Language changes
+
+==== Pattern matching
+
+* Pattern matching is introduced as an experimental feature. [Feature #14912]
+
+ case [0, [1, 2, 3]]
+ in [a, [b, *c]]
+ p a #=> 0
+ p b #=> 1
+ p c #=> [2, 3]
+ end
+
+ case {a: 0, b: 1}
+ in {a: 0, x: 1}
+ :unreachable
+ in {a: 0, b: var}
+ p var #=> 1
+ end
+
+ case -1
+ in 0 then :unreachable
+ in 1 then :unreachable
+ end #=> NoMatchingPatternError
+
+ json = <<END
+ {
+ "name": "Alice",
+ "age": 30,
+ "children": [{ "name": "Bob", "age": 2 }]
+ }
+ END
+
+ JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: name, age: age}]}
+
+ p name #=> "Bob"
+ p age #=> 2
+
+ JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: "Charlie", age: age}]}
+ #=> NoMatchingPatternError
+
+* See the following slides for more details:
+ * https://speakerdeck.com/k_tsj/pattern-matching-new-feature-in-ruby-2-dot-7
+ * Note that the slides are slightly obsolete.
+
+* The warning against pattern matching can be suppressed with
+ {-W:no-experimental option}[#label-Warning+option].
+
+==== The spec of keyword arguments is changed towards 3.0
+
+* Automatic conversion of keyword arguments and positional arguments is
+ deprecated, and conversion will be removed in Ruby 3. [Feature #14183]
+
+ * When a method call passes a Hash at the last argument, and when it
+ passes no keywords, and when the called method accepts keywords,
+ a warning is emitted. To continue treating the hash as keywords,
+ add a double splat operator to avoid the warning and ensure
+ correct behavior in Ruby 3.
+
+ def foo(key: 42); end; foo({key: 42}) # warned
+ def foo(**kw); end; foo({key: 42}) # warned
+ def foo(key: 42); end; foo(**{key: 42}) # OK
+ def foo(**kw); end; foo(**{key: 42}) # OK
+
+ * When a method call passes keywords to a method that accepts keywords,
+ but it does not pass enough required positional arguments, the
+ keywords are treated as a final required positional argument, and a
+ warning is emitted. Pass the argument as a hash instead of keywords
+ to avoid the warning and ensure correct behavior in Ruby 3.
+
+ def foo(h, **kw); end; foo(key: 42) # warned
+ def foo(h, key: 42); end; foo(key: 42) # warned
+ def foo(h, **kw); end; foo({key: 42}) # OK
+ def foo(h, key: 42); end; foo({key: 42}) # OK
+
+ * When a method accepts specific keywords but not a keyword splat, and
+ a hash or keywords splat is passed to the method that includes both
+ Symbol and non-Symbol keys, the hash will continue to be split, and
+ a warning will be emitted. You will need to update the calling code
+ to pass separate hashes to ensure correct behavior in Ruby 3.
+
+ def foo(h={}, key: 42); end; foo("key" => 43, key: 42) # warned
+ def foo(h={}, key: 42); end; foo({"key" => 43, key: 42}) # warned
+ def foo(h={}, key: 42); end; foo({"key" => 43}, key: 42) # OK
+
+ * If a method does not accept keywords, and is called with keywords,
+ the keywords are still treated as a positional hash, with no warning.
+ This behavior will continue to work in Ruby 3.
+
+ def foo(opt={}); end; foo( key: 42 ) # OK
+
+* Non-symbols are allowed as keyword argument keys if the method accepts
+ arbitrary keywords. [Feature #14183]
+
+ * Non-Symbol keys in a keyword arguments hash were prohibited in 2.6.0,
+ but are now allowed again. [Bug #15658]
+
+ def foo(**kw); p kw; end; foo("str" => 1) #=> {"str"=>1}
+
+* <code>**nil</code> is allowed in method definitions to explicitly mark
+ that the method accepts no keywords. Calling such a method with keywords
+ will result in an ArgumentError. [Feature #14183]
+
+ def foo(h, **nil); end; foo(key: 1) # ArgumentError
+ def foo(h, **nil); end; foo(**{key: 1}) # ArgumentError
+ def foo(h, **nil); end; foo("str" => 1) # ArgumentError
+ def foo(h, **nil); end; foo({key: 1}) # OK
+ def foo(h, **nil); end; foo({"str" => 1}) # OK
+
+* Passing an empty keyword splat to a method that does not accept keywords
+ no longer passes an empty hash, unless the empty hash is necessary for
+ a required parameter, in which case a warning will be emitted. Remove
+ the double splat to continue passing a positional hash. [Feature #14183]
+
+ h = {}; def foo(*a) a end; foo(**h) # []
+ h = {}; def foo(a) a end; foo(**h) # {} and warning
+ h = {}; def foo(*a) a end; foo(h) # [{}]
+ h = {}; def foo(a) a end; foo(h) # {}
+
+* Above warnings can be suppressed also with {-W:no-deprecated option}[#label-Warning+option].
+
+==== Numbered parameters
+
+* Numbered parameters as default block parameters are introduced. [Feature #4475]
+
+ [1, 2, 10].map { _1.to_s(16) } #=> ["1", "2", "a"]
+ [[1, 2], [3, 4]].map { _1 + _2 } #=> [3, 7]
+
+ You can still define a local variable named +_1+ and so on,
+ and that is honored when present, but renders a warning.
+
+ _1 = 0 #=> warning: `_1' is reserved for numbered parameter; consider another name
+ [1].each { p _1 } # prints 0 instead of 1
+
+==== proc/lambda without block is deprecated
+
+* Proc.new and Kernel#proc with no block in a method called with a block will
+ now display a warning.
+
+ def foo
+ proc
+ end
+ foo { puts "Hello" } #=> warning: Capturing the given block using Kernel#proc is deprecated; use `&block` instead
+
+ This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
+
+* Kernel#lambda with no block in a method called with a block raises an exception.
+
+ def bar
+ lambda
+ end
+ bar { puts "Hello" } #=> tried to create Proc object without a block (ArgumentError)
+
+==== Other miscellaneous changes
+
+* A beginless range is experimentally introduced. It might be useful
+ in +case+, new call-sequence of the <code>Comparable#clamp</code>,
+ constants and DSLs. [Feature #14799]
+
+ ary[..3] # identical to ary[0..3]
+
+ case RUBY_VERSION
+ when ..."2.4" then puts "EOL"
+ # ...
+ end
+
+ age.clamp(..100)
+
+ where(sales: ..100)
+
+* Setting <code>$;</code> to a non-nil value will now display a warning. [Feature #14240]
+ This includes the usage in String#split.
+ This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
+
+* Setting <code>$,</code> to a non-nil value will now display a warning. [Feature #14240]
+ This includes the usage in Array#join.
+ This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
+
+* Quoted here-document identifiers must end within the same line.
+
+ <<"EOS
+ " # This had been warned since 2.4; Now it raises a SyntaxError
+ EOS
+
+* The flip-flop syntax deprecation is reverted. [Feature #5400]
+
+* Comment lines can be placed between fluent dot now.
+
+ foo
+ # .bar
+ .baz # => foo.baz
+
+* Calling a private method with a literal +self+ as the receiver
+ is now allowed. [Feature #11297] [Feature #16123]
+
+* Modifier rescue now operates the same for multiple assignment as single
+ assignment. [Bug #8279]
+
+ a, b = raise rescue [1, 2]
+ # Previously parsed as: (a, b = raise) rescue [1, 2]
+ # Now parsed as: a, b = (raise rescue [1, 2])
+
+* +yield+ in singleton class syntax will now display a warning. This behavior
+ will soon be deprecated. [Feature #15575].
+
+ def foo
+ class << Object.new
+ yield #=> warning: `yield' in class syntax will not be supported from Ruby 3.0. [Feature #15575]
+ end
+ end
+ foo { p :ok }
+
+ This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
+
+* Argument forwarding by <code>(...)</code> is introduced. [Feature #16253]
+
+ def foo(...)
+ bar(...)
+ end
+
+ All arguments to +foo+ are forwarded to +bar+, including keyword and
+ block arguments.
+ Note that the parentheses are mandatory. <code>bar ...</code> is parsed
+ as an endless range.
+
+* Access and setting of <code>$SAFE</code> will now always display a warning.
+ <code>$SAFE</code> will become a normal global variable in Ruby 3.0. [Feature #16131]
+
+* <code>Object#{taint,untaint,trust,untrust}</code> and related functions in the C-API
+ no longer have an effect (all objects are always considered untainted), and will now
+ display a warning in verbose mode. This warning will be disabled even in non-verbose mode in
+ Ruby 3.0, and the methods and C functions will be removed in Ruby 3.2. [Feature #16131]
+
+* Refinements take place at Object#method and Module#instance_method. [Feature #15373]
+
+=== Command line options
+
+==== Warning option
+
+The +-W+ option has been extended with a following +:+, to manage categorized
+warnings. [Feature #16345] [Feature #16420]
+
+* To suppress deprecation warnings:
+
+ $ ruby -e '$; = ""'
+ -e:1: warning: `$;' is deprecated
+
+ $ ruby -W:no-deprecated -e '$; = //'
+
+* It works with the +RUBYOPT+ environment variable:
+
+ $ RUBYOPT=-W:no-deprecated ruby -e '$; = //'
+
+* To suppress experimental feature warnings:
+
+ $ ruby -e '0 in a'
+ -e:1: warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!
+
+ $ ruby -W:no-experimental -e '0 in a'
+
+* To suppress both by using +RUBYOPT+, set space separated values:
+
+ $ RUBYOPT='-W:no-deprecated -W:no-experimental' ruby -e '($; = "") in a'
+
+See also Warning in {Core classes updates}[#label-Core+classes+updates+-28outstanding+ones+only-29].
+
+=== Core classes updates (outstanding ones only)
+
+[Array]
+
+ [New methods]
+
+ * Added Array#intersection. [Feature #16155]
+
+ * Added Array#minmax, with a faster implementation than Enumerable#minmax. [Bug #15929]
+
+[Comparable]
+
+ [Modified method]
+
+ * Comparable#clamp now accepts a Range argument. [Feature #14784]
+
+ -1.clamp(0..2) #=> 0
+ 1.clamp(0..2) #=> 1
+ 3.clamp(0..2) #=> 2
+ # With beginless and endless ranges:
+ -1.clamp(0..) #=> 0
+ 3.clamp(..2) #=> 2
+
+
+[Complex]
+
+ [New method]
+
+ * Added Complex#<=>.
+ So <code>0 <=> 0i</code> will not raise NoMethodError. [Bug #15857]
+
+[Dir]
+
+ [Modified methods]
+
+ * Dir.glob and Dir.[] no longer allow NUL-separated glob pattern.
+ Use Array instead. [Feature #14643]
+
+[Encoding]
+
+ [New encoding]
+
+ * Added new encoding CESU-8. [Feature #15931]
+
+[Enumerable]
+
+ [New methods]
+
+ * Added Enumerable#filter_map. [Feature #15323]
+
+ [1, 2, 3].filter_map {|x| x.odd? ? x.to_s : nil } #=> ["1", "3"]
+
+ * Added Enumerable#tally. [Feature #11076]
+
+ ["A", "B", "C", "B", "A"].tally #=> {"A"=>2, "B"=>2, "C"=>1}
+
+[Enumerator]
+
+ [New methods]
+
+ * Added Enumerator.produce to generate an Enumerator from any custom
+ data transformation. [Feature #14781]
+
+ require "date"
+ dates = Enumerator.produce(Date.today, &:succ) #=> infinite sequence of dates
+ dates.detect(&:tuesday?) #=> next Tuesday
+
+ * Added Enumerator::Lazy#eager that generates a non-lazy enumerator
+ from a lazy enumerator. [Feature #15901]
+
+ a = %w(foo bar baz)
+ e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager
+ p e.class #=> Enumerator
+ p e.map {|x| x + "?" } #=> ["FOO!?", "BAR!?", "BAZ!?"]
+
+ * Added Enumerator::Yielder#to_proc so that a Yielder object
+ can be directly passed to another method as a block
+ argument. [Feature #15618]
+
+[Fiber]
+
+ [New method]
+
+ * Added Fiber#raise that behaves like Fiber#resume but raises an
+ exception on the resumed fiber. [Feature #10344]
+
+[File]
+
+ [Modified method]
+
+ * File.extname now returns a dot string for names ending with a dot on
+ non-Windows platforms. [Bug #15267]
+
+ File.extname("foo.") #=> "."
+
+[FrozenError]
+
+ [New method]
+
+ * Added FrozenError#receiver to return the frozen object on which
+ modification was attempted. To set this object when raising
+ FrozenError in Ruby code, FrozenError.new accepts a +:receiver+
+ option. [Feature #15751]
+
+[GC]
+
+ [New method]
+
+ * Added GC.compact method for compacting the heap.
+ This function compacts live objects in the heap so that fewer pages may
+ be used, and the heap may be more CoW (copy-on-write) friendly. [Feature #15626]
+
+ Details on the algorithm and caveats can be found here:
+ https://bugs.ruby-lang.org/issues/15626
+
+[IO]
+
+ [New method]
+
+ * Added IO#set_encoding_by_bom to check the BOM and set the external
+ encoding. [Bug #15210]
+
+[Integer]
+
+ [Modified method]
+
+ * Integer#[] now supports range operations. [Feature #8842]
+
+ 0b01001101[2, 4] #=> 0b0011
+ 0b01001100[2..5] #=> 0b0011
+ 0b01001100[2...6] #=> 0b0011
+ # ^^^^
+
+[Method]
+
+ [Modified method]
+
+ * Method#inspect shows more information. [Feature #14145]
+
+[Module]
+
+ [New methods]
+
+ * Added Module#const_source_location to retrieve the location where a
+ constant is defined. [Feature #10771]
+
+ * Added Module#ruby2_keywords for marking a method as passing keyword
+ arguments through a regular argument splat, useful when delegating
+ all arguments to another method in a way that can be backwards
+ compatible with older Ruby versions. [Bug #16154]
+
+ [Modified methods]
+
+ * Module#autoload? now takes an +inherit+ optional argument, like
+ Module#const_defined?. [Feature #15777]
+
+ * Module#name now always returns a frozen String. The returned String is
+ always the same for a given Module. This change is
+ experimental. [Feature #16150]
+
+[NilClass / TrueClass / FalseClass]
+
+ [Modified methods]
+
+ * NilClass#to_s, TrueClass#to_s, and FalseClass#to_s now always return a
+ frozen String. The returned String is always the same for each of these
+ values. This change is experimental. [Feature #16150]
+
+[ObjectSpace::WeakMap]
+
+ [Modified method]
+
+ * ObjectSpace::WeakMap#[]= now accepts special objects as either key or
+ values. [Feature #16035]
+
+[Proc]
+
+ [New method]
+
+ * Added Proc#ruby2_keywords for marking the proc as passing keyword
+ arguments through a regular argument splat, useful when delegating
+ all arguments to another method or proc in a way that can be backwards
+ compatible with older Ruby versions. [Feature #16404]
+
+[Range]
+
+ [New method]
+
+ * Added Range#minmax, with a faster implementation than Enumerable#minmax.
+ It returns a maximum that now corresponds to Range#max. [Bug #15807]
+
+ [Modified method]
+
+ * Range#=== now uses Range#cover? for String arguments, too (in Ruby 2.6, it was
+ changed from Range#include? for all types except strings). [Bug #15449]
+
+
+[RubyVM]
+
+ [Removed method]
+
+ * +RubyVM.resolve_feature_path+ moved to
+ <code>$LOAD_PATH.resolve_feature_path</code>. [Feature #15903] [Feature #15230]
+
+[String]
+
+ [Unicode]
+
+ * Update Unicode version and Emoji version from 11.0.0 to
+ 12.0.0. [Feature #15321]
+
+ * Update Unicode version to 12.1.0, adding support for
+ U+32FF SQUARE ERA NAME REIWA. [Feature #15195]
+
+ * Update Unicode Emoji version to 12.1. [Feature #16272]
+
+[Symbol]
+
+ [New methods]
+
+ * Added Symbol#start_with? and Symbol#end_with? methods. [Feature #16348]
+
+[Time]
+
+ [New methods]
+
+ * Added Time#ceil method. [Feature #15772]
+
+ * Added Time#floor method. [Feature #15653]
+
+ [Modified method]
+
+ * Time#inspect is separated from Time#to_s and it shows
+ the time's sub second. [Feature #15958]
+
+[UnboundMethod]
+
+ [New method]
+
+ * Added UnboundMethod#bind_call method. [Feature #15955]
+
+ <code>umethod.bind_call(obj, ...)</code> is semantically equivalent
+ to <code>umethod.bind(obj).call(...)</code>. This idiom is used in
+ some libraries to call a method that is overridden. The added
+ method does the same without allocation of an intermediate Method
+ object.
+
+ class Foo
+ def add_1(x)
+ x + 1
+ end
+ end
+ class Bar < Foo
+ def add_1(x) # override
+ x + 2
+ end
+ end
+
+ obj = Bar.new
+ p obj.add_1(1) #=> 3
+ p Foo.instance_method(:add_1).bind(obj).call(1) #=> 2
+ p Foo.instance_method(:add_1).bind_call(obj, 1) #=> 2
+
+[Warning]
+
+ [New methods]
+
+ * Added Warning.[] and Warning.[]= to manage emitting/suppressing
+ some categories of warnings. [Feature #16345] [Feature #16420]
+
+[$LOAD_PATH]
+
+ [New method]
+
+ * Added <code>$LOAD_PATH.resolve_feature_path</code>. [Feature #15903] [Feature #15230]
+
+=== Stdlib updates (outstanding ones only)
+
+[Bundler]
+
+ * Upgrade to Bundler 2.1.2.
+ See https://github.com/bundler/bundler/releases/tag/v2.1.2
+
+[CGI]
+
+ * CGI.escapeHTML becomes 2~5x faster when there is at least one escaped character.
+ See https://github.com/ruby/ruby/pull/2226
+
+[CSV]
+
+ * Upgrade to 3.1.2.
+ See https://github.com/ruby/csv/blob/master/NEWS.md.
+
+[Date]
+
+ * Date.jisx0301, Date#jisx0301, and Date.parse support the new Japanese
+ era. [Feature #15742]
+
+[Delegator]
+
+ * Object#DelegateClass accepts a block and module_evals it in the context
+ of the returned class, similar to Class.new and Struct.new.
+
+[ERB]
+
+ * Prohibit marshaling ERB instance.
+
+[IRB]
+
+ * Introduce syntax highlighting inspired by the Pry gem to Binding#irb
+ source lines, REPL input, and inspect output of some core-class objects.
+
+ * Introduce multiline editing mode provided by Reline.
+
+ * Show documentation when completion.
+
+ * Enable auto indent and save/load history by default.
+
+[JSON]
+
+ * Upgrade to 2.3.0.
+
+[Net::FTP]
+
+ * Add Net::FTP#features to check available features, and Net::FTP#option to
+ enable/disable each of them. [Feature #15964]
+
+[Net::HTTP]
+
+ * Add +ipaddr+ optional parameter to Net::HTTP#start to replace the address for
+ the TCP/IP connection. [Feature #5180]
+
+[Net::IMAP]
+
+ * Add Server Name Indication (SNI) support. [Feature #15594]
+
+[open-uri]
+
+ * Warn open-uri's "open" method at Kernel.
+ Use URI.open instead. [Misc #15893]
+
+ * The default charset of "text/*" media type is UTF-8 instead of
+ ISO-8859-1. [Bug #15933]
+
+[OptionParser]
+
+ * Now show "Did you mean?" for unknown options. [Feature #16256]
+
+ test.rb:
+
+ require "optparse"
+ OptionParser.new do |opts|
+ opts.on("-f", "--foo", "foo") {|v| }
+ opts.on("-b", "--bar", "bar") {|v| }
+ opts.on("-c", "--baz", "baz") {|v| }
+ end.parse!
+
+ example:
+
+ $ ruby test.rb --baa
+ Traceback (most recent call last):
+ test.rb:7:in `<main>': invalid option: --baa (OptionParser::InvalidOption)
+ Did you mean? baz
+ bar
+
+[Pathname]
+
+ * Pathname.glob now delegates 3 arguments to Dir.glob
+ to accept +base+ keyword. [Feature #14405]
+
+[Racc]
+
+ * Merge 1.4.15 from upstream repository and added cli of racc.
+
+[Reline]
+
+ * New stdlib that is compatible with the readline stdlib but is
+ implemented in pure Ruby. It also provides a multiline editing mode.
+
+[REXML]
+
+ * Upgrade to 3.2.3.
+ See https://github.com/ruby/rexml/blob/master/NEWS.md.
+
+[RSS]
+
+ * Upgrade to RSS 0.2.8.
+ See https://github.com/ruby/rss/blob/master/NEWS.md.
+
+[RubyGems]
+
+ * Upgrade to RubyGems 3.1.2.
+ * https://github.com/rubygems/rubygems/releases/tag/v3.1.0
+ * https://github.com/rubygems/rubygems/releases/tag/v3.1.1
+ * https://github.com/rubygems/rubygems/releases/tag/v3.1.2
+
+[StringScanner]
+
+ * Upgrade to 1.0.3.
+ See https://github.com/ruby/strscan/blob/master/NEWS.md.
+
+=== Compatibility issues (excluding feature bug fixes)
+
+* The following libraries are no longer bundled gems.
+ Install corresponding gems to use these features.
+ * CMath (cmath gem)
+ * Scanf (scanf gem)
+ * Shell (shell gem)
+ * Synchronizer (sync gem)
+ * ThreadsWait (thwait gem)
+ * E2MM (e2mmap gem)
+
+[Proc]
+ * The Proc#to_s format was changed. [Feature #16101]
+
+[Range]
+ * Range#minmax used to iterate on the range to determine the maximum.
+ It now uses the same algorithm as Range#max. In rare cases (e.g.
+ ranges of Floats or Strings), this may yield different results. [Bug #15807]
+
+=== Stdlib compatibility issues (excluding feature bug fixes)
+
+* Promote stdlib to default gems
+ * The following default gems were published on rubygems.org
+ * benchmark
+ * cgi
+ * delegate
+ * getoptlong
+ * net-pop
+ * net-smtp
+ * open3
+ * pstore
+ * readline
+ * readline-ext
+ * singleton
+ * The following default gems were only promoted at ruby-core,
+ but not yet published on rubygems.org.
+ * monitor
+ * observer
+ * timeout
+ * tracer
+ * uri
+ * yaml
+* The <tt>did_you_mean</tt> gem has been promoted up to a default gem from a bundled gem
+
+[pathname]
+
+ * Kernel#Pathname when called with a Pathname argument now returns
+ the argument instead of creating a new Pathname. This is more
+ similar to other Kernel methods, but can break code that modifies
+ the return value and expects the argument not to be modified.
+
+[profile.rb, Profiler__]
+
+ * Removed from standard library. It was unmaintained since Ruby 2.0.0.
+
+=== C API updates
+
+* Many <code>*_kw</code> functions have been added for setting whether
+ the final argument being passed should be treated as keywords. You
+ may need to switch to these functions to avoid keyword argument
+ separation warnings, and to ensure correct behavior in Ruby 3.
+
+* The <code>:</code> character in rb_scan_args format string is now
+ treated as keyword arguments. Passing a positional hash instead of
+ keyword arguments will emit a deprecation warning.
+
+* C API declarations with +ANYARGS+ are changed not to use +ANYARGS+.
+ See https://github.com/ruby/ruby/pull/2404
+
+=== Implementation improvements
+
+[Fiber]
+
+ * Allow selecting different coroutine implementations by using
+ +--with-coroutine=+, e.g.
+
+ $ ./configure --with-coroutine=ucontext
+ $ ./configure --with-coroutine=copy
+
+ * Replace previous stack cache with fiber pool cache. The fiber pool
+ allocates many stacks in a single memory region. Stack allocation
+ becomes O(log N) and fiber creation is amortized O(1). Around 10x
+ performance improvement was measured in micro-benchmarks.
+ https://github.com/ruby/ruby/pull/2224
+
+[File]
+ * File.realpath now uses realpath(3) on many platforms, which can
+ significantly improve performance. [Feature #15797]
+
+[Hash]
+ * Change data structure of small Hash objects. [Feature #15602]
+
+[Monitor]
+ * Monitor class is written in C-extension. [Feature #16255]
+
+[Thread]
+
+ * VM stack memory allocation is now combined with native thread stack,
+ improving thread allocation performance and reducing allocation related
+ failures. Around 10x performance improvement was measured in micro-benchmarks.
+
+[JIT]
+
+ * JIT-ed code is recompiled to less-optimized code when an optimization assumption is invalidated.
+
+ * Method inlining is performed when a method is considered as pure.
+ This optimization is still experimental and many methods are NOT considered as pure yet.
+
+ * The default value of +--jit-max-cache+ is changed from 1,000 to 100.
+
+ * The default value of +--jit-min-calls+ is changed from 5 to 10,000.
+
+[RubyVM]
+
+ * Per-call-site method cache, which has been there since around 1.9, was
+ improved: cache hit rate raised from 89% to 94%.
+ See https://github.com/ruby/ruby/pull/2583
+
+[RubyVM::InstructionSequence]
+
+ * RubyVM::InstructionSequence#to_binary method generates compiled binary.
+ The binary size is reduced. [Feature #16163]
+
+=== Miscellaneous changes
+
+* Support for IA64 architecture has been removed. Hardware for testing was
+ difficult to find, native fiber code is difficult to implement, and it added
+ non-trivial complexity to the interpreter. [Feature #15894]
+
+* Require compilers to support C99. [Misc #15347]
+
+ * Details of our dialect: https://bugs.ruby-lang.org/projects/ruby-master/wiki/C99
+
+* Ruby's upstream repository is changed from Subversion to Git.
+
+ * https://git.ruby-lang.org/ruby.git
+
+ * RUBY_REVISION class is changed from Integer to String.
+
+ * RUBY_DESCRIPTION includes Git revision instead of Subversion's one.
+
+* Support built-in methods in Ruby with the <code>_\_builtin_</code> syntax. [Feature #16254]
+
+ Some methods are defined in *.rb (such as trace_point.rb).
+ For example, it is easy to define a method which accepts keyword arguments.
diff --git a/doc/bug_triaging.rdoc b/doc/bug_triaging.rdoc
new file mode 100644
index 0000000000..83fe88cabe
--- /dev/null
+++ b/doc/bug_triaging.rdoc
@@ -0,0 +1,79 @@
+= Bug Triaging Guide
+
+This guide discusses recommendations for triaging bugs in Ruby's bug tracker.
+
+== Bugs with Reproducible Examples
+
+These are the best bug reports. First, consider whether the bug reported is
+actually an issue or if it is expected Ruby behavior. If it is expected Ruby
+behavior, update the issue with why the behavior is expected, and set the
+status to Rejected.
+
+If the bug reported appears to be an actual bug, try reproducing the bug with
+the master branch. If you are not able to reproduce the issue on the master
+branch, try reproducing it on the latest version for the branch the bug was
+reported on. If you cannot reproduce the issue in either case, update
+the issue stating you cannot reproduce the issue, ask the reporter if they
+can reproduce the issue with either the master branch or a later release,
+and set the status to Feedback.
+
+If you can reproduce the example with the master branch, try to figure out
+what is causing the issue. If you feel comfortable, try working on a
+patch for the issue, update the issue, and attach the patch. Try to figure
+out which committer should be assigned to the issue, and set them as the
+assignee, and set the status to Assigned.
+
+If you cannot reproduce the example with the master branch, but can reproduce
+the issue on the latest version for the branch, then it is likely the bug has
+already been fixed, but it has not been backported yet. Try to determine
+which commit fixed it, and update the issue noting that the issue has been
+fixed but not yet backported. If the Ruby version is in the security
+maintenance phase or no longer supported, change the status to Closed. This
+change can be made without adding a note to avoid spamming the mailing list.
+
+For issues that may require backwards incompatible changes or may benefit from
+general committer attention or discussion, consider adding them as agenda
+items for the next committer meeting (https://bugs.ruby-lang.org/issues/14770).
+
+== Crash Bugs Without Reproducers
+
+Many bugs reported have little more than a crash report, often with no way to
+reproduce the issue. These bugs are difficult to triage as they often do not
+contain enough information.
+
+For these bugs, if the Ruby version is the master branch or is the latest
+release for the branch and the branch is in normal maintenance phase, look at
+the backtrace and see if you can determine what could be causing the issue.
+If you can guess what could be causing the issue, see if you can put together
+a reproducible example (this is in general quite difficult). If you cannot
+guess what could be causing the issue, or cannot put together a reproducible
+example yourself, please ask the reporter to provide a reproducible example,
+and change the status to Feedback.
+
+If the Ruby version is no longer current (e.g. 2.5.0 when the latest version
+on the Ruby 2.5 branch is 2.5.5), add a note to the issue asking the reporter
+to try the latest Ruby version for the branch and report back, and change the
+status to Feedback. If the Ruby version is in the security maintenance phase
+or no longer supported, change the status to Closed. This change can be made
+without adding a note.
+
+== Crash Bugs With 3rd Party C Extensions
+
+If the crash happens inside a 3rd party C extension, try to figure out inside
+which C extension it happens, and add a note to the issue to report the
+issue to that C extension, and set the status to Third Party's Issue.
+
+== Non-Bug reports
+
+Any issues in the bug tracker that are not reports of problems should have
+the tracker changed from Bug to either Feature (new features or performance
+improvements) or Misc. This change can be made without adding a note.
+
+== Stale Issues
+
+There are many issues that are stale, with no updates in months or even years.
+For stale issues in Feedback state, where the feedback has not been received,
+you can change the status to Closed without adding a note. For stale issues
+in Assigned state, you can reach out to the assignee and see if they can update
+the issue. If the assignee is no longer an active committer, remove them
+as the assignee and change the status to Open.
diff --git a/doc/contributing.rdoc b/doc/contributing.rdoc
index d0340d4d82..d7395627ca 100644
--- a/doc/contributing.rdoc
+++ b/doc/contributing.rdoc
@@ -27,10 +27,10 @@ on your ticket.
stable release. See
{Downloading Ruby}[https://www.ruby-lang.org/en/downloads/].
* Look to see if anyone already reported your issue, try
- {searching on redmine}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues]
+ {searching on redmine}[https://bugs.ruby-lang.org/projects/ruby-master/issues]
for your problem.
* If you can't find a ticket addressing your issue,
- {create a new one}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues/new].
+ {create a new one}[https://bugs.ruby-lang.org/projects/ruby-master/issues/new].
* Choose the target version, usually current. Bugs will be first fixed in the
current release and then {backported}[rdoc-label:label-Backport+Requests].
* Fill in the Ruby version you're using when experiencing this issue
@@ -53,10 +53,10 @@ on your ticket.
You can report downstream issues for the following distributions via their bug tracker:
-* {debian}[http://bugs.debian.org/cgi-bin/pkgreport.cgi?src=ruby-defaults]
+* {debian}[https://bugs.debian.org/cgi-bin/pkgreport.cgi?src=ruby-defaults]
* {freebsd}[http://www.freebsd.org/cgi/query-pr-summary.cgi?text=ruby]
* {redhat}[https://bugzilla.redhat.com/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=MODIFIED]
-* {macports}[http://trac.macports.org/query?status=assigned&status=new&status=reopened&port=~ruby]
+* {macports}[https://trac.macports.org/query?status=assigned&status=new&status=reopened&port=~ruby]
* etc (add your distribution bug tracker here)
=== Platform Maintainers
@@ -66,14 +66,10 @@ maintainer for a specific platform.
The current active platform maintainers are as follows:
-[mswin32, mswin64 (Microsoft Windows)]
+[mswin64 (Microsoft Windows)]
NAKAMURA Usaku (usa)
[mingw32 (Minimalist GNU for Windows)]
Nobuyoshi Nakada (nobu)
-[IA-64 (Debian GNU/Linux)]
- TAKANO Mitsuhiro (takano32)
-[Symbian OS]
- Alexander Zavorine (azov)
[AIX]
Yutaka Kanemoto (kanemoto)
[FreeBSD]
@@ -81,10 +77,12 @@ The current active platform maintainers are as follows:
[Solaris]
Naohisa Goto (ngoto)
[RHEL, CentOS]
- KOSAKI Motohiro kosaki
-[Mac OS X]
+ KOSAKI Motohiro (kosaki)
+[macOS]
Kenta Murata (mrkn)
-[cygwin, bcc32, djgpp, wince, ...]
+[OpenBSD]
+ Jeremy Evans (jeremyevans0)
+[cygwin, ...]
none. (Maintainer WANTED)
== Reporting Security Issues
@@ -118,7 +116,7 @@ these? Quite a bit, actually:
When a bug report goes for a while without any feedback, it goes to the bug
graveyard which is unfortunate. If you check the {issues
-list}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues] you will find lots
+list}[https://bugs.ruby-lang.org/projects/ruby-master/issues] you will find lots
of delinquent bugs that require attention.
You can help by verifying the existing tickets, try to reproduce the reported
@@ -133,7 +131,7 @@ redmine, if gone without notice. In this case the +patch+ command is your
friend, see <code>man patch</code> for more information. Basically this would
go something like this:
- cd path/to/ruby/trunk
+ cd path/to/ruby
patch -p0 < path/to/patch
You will then be prompted to apply the patch with the associated files. After
@@ -158,8 +156,8 @@ If there's a new feature that you want to see added to Ruby, you will need to
write a convincing proposal and patch to implement the feature.
For new features in CRuby, use the {'Feature'
-tracker}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues?set_filter=1&tracker_id=2]
-on ruby-trunk. For non-CRuby dependent features, features that would apply to
+tracker}[https://bugs.ruby-lang.org/projects/ruby-master/issues?set_filter=1&tracker_id=2]
+on ruby-master. For non-CRuby dependent features, features that would apply to
alternate Ruby implementations such as JRuby and Rubinius, use the {CommonRuby
tracker}[https://bugs.ruby-lang.org/projects/common-ruby].
@@ -197,29 +195,10 @@ A good template for a feature proposal should look something like this:
[See also]
Links to the other related resources
-=== Slideshow
-
-At the Ruby Developer Meeting in Japan, committers discuss Feature Proposals together in Tokyo. We will judge proposals and then accept, reject, or give feedback for them.
-If you have a stalled proposal, making a slide to submit is good way to get feedback.
-
-Slides should be:
-
-* One-page slide
-* Include a corresponding ticket number
-* MUST include a figure and/or short example code
-* SHOULD have less sentence in natural language (try to write less than 140 characters)
-* It is RECOMMENDED to itemize: motivation/use case, proposal, pros/cons, corner case
-* PDF or Image (Web browsers can show it)
-
-Please note:
-
-* Even if the proposal is generally acceptable, it won't be accepted without writing corner cases in the ticket
-* Slide's example: DevelopersMeeting20130727Japan
-
== Backport Requests
When a new version of Ruby is released, it starts at patch level 0 (p0), and
-bugs will be fixed first on the trunk branch. If it's determined that a bug
+bugs will be fixed first on the master branch. If it's determined that a bug
exists in a previous version of Ruby that is still in the bug fix stage of
maintenance, then a patch will be backported. After the maintenance stage of a
particular Ruby version ends, it goes into "security fix only" mode which
@@ -249,34 +228,28 @@ Status and maintainers of branches are listed on the
In order to help resolve existing issues and contributing patches to Ruby you
need to be able to run the test suite.
-CRuby uses subversion for source control, you can find installation
-instructions and lots of great info to learn subversion on the
-{svnbook.red-bean.com}[http://svnbook.red-bean.com/]. For other resources see
-the {ruby-core documentation on
+CRuby uses git for source control, the {git homepage}[https://git-scm.com/]
+has installation instructions with links to documentation for learning more
+about git. There is a mirror of the repository on {github}[https://github.com/ruby/ruby].
+For other resources see the {ruby-core documentation on
ruby-lang.org}[https://www.ruby-lang.org/en/community/ruby-core/].
-This guide will use git for contributing. The {git
-homepage}[http://git-scm.com/] has installation instructions with links to
-documentation for learning more about git. There is a mirror of the subversion
-repository on {github}[https://github.com/ruby/ruby].
-
Install the prerequisite dependencies for building the CRuby interpreter to
run tests.
* C compiler
-* autoconf
-* bison
-* gperf
-* ruby - Ruby itself is prerequisite in order to build Ruby from source. It
- can be 1.8.
+* autoconf - 2.67 or later, preferably 2.69.
+* bison - 2.0 or later, preferably 3.4.
+* gperf - 3.0.3 or later, preferably 3.1.
+* ruby - Ruby itself is prerequisite in order to build Ruby from source.
+ You should use [a maintained version of Ruby](https://www.ruby-lang.org/en/downloads/).
You should also have access to development headers for the following
libraries, but these are not required:
-* Tcl/Tk
* NDBM/QDBM
* GDBM
-* OpenSSL
+* OpenSSL/LibreSSL
* readline/editline(libedit)
* zlib
* libffi
@@ -287,15 +260,15 @@ Now let's build CRuby:
* Checkout the CRuby source code:
- git clone git://github.com/ruby/ruby.git ruby-trunk
+ git clone https://github.com/ruby/ruby.git ruby-master
* Generate the configuration files and build:
- cd ruby-trunk
+ cd ruby-master
autoconf
mkdir build && cd build # its good practice to build outside of source dir
- mkdir ~/.rubies # we will install to .rubies/ruby-trunk in our home dir
- ../configure --prefix="${HOME}/.rubies/ruby-trunk"
+ mkdir ~/.rubies # we will install to .rubies/ruby-master in our home dir
+ ../configure --prefix="${HOME}/.rubies/ruby-master"
make up && make install
After adding Ruby to your PATH, you should be ready to run the test suite:
@@ -319,7 +292,7 @@ For older versions of Ruby you will need to run the build setup again after
checking out the associated branch in git, for example if you wanted to
checkout 1.9.3:
- git clone git://github.com/ruby/ruby.git --branch ruby_1_9_3
+ git clone https://github.com/ruby/ruby.git --branch ruby_1_9_3
Once you checked out the source code, you can update the local copy by:
@@ -332,11 +305,11 @@ Or, update, build, install and check, by just:
== Contributing Documentation
If you're interested in contributing documentation directly to CRuby there is
-a wealth of information available at
-{documenting-ruby.org}[http://documenting-ruby.org/].
+some information available at
+{Contributing}[https://github.com/ruby/ruby#contributing].
There is also the {Ruby Reference
-Manual}[https://bugs.ruby-lang.org/projects/rurema] in Japanese.
+Manual}[https://github.com/rurema/doctree/wiki] in Japanese.
== Contributing A Patch
@@ -352,7 +325,7 @@ Before you submit a patch, there are a few things you should know:
To improve the chance your patch will be accepted please follow these simple rules:
-* Bug fixes should be committed on trunk first
+* Bug fixes should be committed on master first
* Format of the patch file must be a unified diff (ie: diff -pu, svn diff, or git diff)
* Don't introduce cosmetic changes
* Follow the original coding style of the code
@@ -360,23 +333,24 @@ To improve the chance your patch will be accepted please follow these simple rul
First thing you should do is check out the code if you haven't already:
- git clone git://github.com/ruby/ruby.git ruby-trunk
+ git clone https://github.com/ruby/ruby.git ruby-master
Now create a dedicated branch:
- cd ruby-trunk
+ cd ruby-master
git checkout -b my_new_branch
The name of your branch doesn't really matter because it will only exist on
your local computer and won't be part of the official Ruby repository. It will
be used to create patches based on the differences between your branch and
-trunk, or edge Ruby.
+master, or edge Ruby.
=== Coding style
Here are some general rules to follow when writing Ruby and C code for CRuby:
-* Indent 4 spaces for C with tabs for eight-space indentation (emacs default)
+* Indent 4 spaces for C without tabs (old codes might use tabs for eight-space indentation,
+ but newer codes recommend to use spaces only)
* Indent 2 space tabs for Ruby
* Do not use TABs in ruby codes
* ANSI C style for 1.9+ for function declarations
@@ -387,48 +361,25 @@ Here are some general rules to follow when writing Ruby and C code for CRuby:
* ABBRs should be all upper case.
* Do as others do
-=== ChangeLog
-
-Although not required, if you wish to add a ChangeLog entry for your change
-please note:
-
-You can use the following template for the ChangeLog entry on your commit:
-
- Thu Jan 1 00:00:00 2004 Your Name <yourmail@example.com>
-
- * filename (function): short description of this commit.
- This should include your intention of this change.
- [bug:#number] [mailinglist:number]
-
- * filename2 (function2): additional description for this file/function.
+=== Commit messages
-This follows {GNU Coding Standards for Change
-Logs}[http://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs],
-some other requirements and tips:
+When you're ready to commit:
-* Timestamps must be in JST (+09:00) in the style as above.
-* Two spaces between the timestamp and your name. Two spaces between
- your name and your mail address.
-* One blank line between the timestamp and the description.
-* Indent the description with TAB. 2nd line should begin with TAB+2SP.
-* Write a entry (*) for each change.
-* Refer to redmine issue or discussion on the mailing list.
-* For GitHub issues, use [GH-#] (such as [Fixes GH-234]
-* One blank line between entries.
-* Do as other committers do.
+ git commit path/to/files
-You can generate the ChangeLog entry by running <code>make change</code>
+This will open your editor in which you write your commit message.
+Use the following style for commit messages:
-When you're ready to commit, copy your ChangeLog entry into the commit message,
-keeping the same formatting and select your files:
+* Use a succinct subject line.
+* Include reasoning behind the change in the commit message, focusing on why
+ the change is being made.
+* Refer to redmine issue (such as Fixes [Bug #1234] or Implements
+ [Feature #3456]), or discussion on the mailing list
+ (such as [ruby-core:12345]).
+* For GitHub issues, use [GH-#] (such as [Fixes GH-234]).
+* Follow the style used by other committers.
- git commit ChangeLog path/to/files
-
-In the likely event that your branch becomes outdated, you will have to update
-your working branch:
-
- git fetch origin
- git rebase remotes/origin/master
+=== Contributing your code
Now that you've got some code you want to contribute, let's get set up to
generate a patch. Start by forking the github mirror, check the {github docs on
@@ -445,7 +396,7 @@ Next copy the writable url for your fork and add it as a git remote, replace
In order to generate a patch that you can upload to the bug tracker, we can use
the github interface to review our changes just visit
-https://github.com/my_username/ruby/compare/trunk...my_new_branch
+https://github.com/my_username/ruby/compare/master...my_new_branch
Next, you can simply add '.patch' to the end of this URL and it will generate
the patch for you, save the file to your computer and upload it to the bug
@@ -456,7 +407,22 @@ Since git is a distributed system, you are welcome to host your git repository
on any {publicly accessible hosting
site}[https://git.wiki.kernel.org/index.php/GitHosting], including {hosting your
own}[https://www.kernel.org/pub/software/scm/git/docs/user-manual.html#public-repositories]
-You may use the {'git format-patch'}[http://git-scm.com/docs/git-format-patch]
+You may use the {'git format-patch'}[https://git-scm.com/docs/git-format-patch]
command to generate patch files to upload to redmine. You may also use
-the {'git request-pull'}[http://git-scm.com/docs/git-request-pull] command for
+the {'git request-pull'}[https://git-scm.com/docs/git-request-pull] command for
formatting pull request messages to redmine.
+
+=== Updating the official repository
+
+If you are a committer, you can push changes directly into the official
+repository:
+
+ git push origin your-branch-name:master
+
+However, it is likely will have become outdated, and you will have to
+update it. In that case, run:
+
+ git fetch origin
+ git rebase remotes/origin/master
+
+and then try pushing your changes again.
diff --git a/doc/contributors.rdoc b/doc/contributors.rdoc
deleted file mode 100644
index ec567cd35f..0000000000
--- a/doc/contributors.rdoc
+++ /dev/null
@@ -1,793 +0,0 @@
-= Contributors to Ruby
-
-The following list might be incomplete. Feel free to add your name if your
-patch was accepted into Ruby.
-
-== A
-
-Ayumu AIZAWA (ayumin)
-* committer
-
-AKIYOSHI, Masamichi (akiyoshi)
-* committer
-* He had maintained the VMS support on 2003-2004.
-
-Muhammad Ali
-* wrote rdoc for Fiber
-
-Minero Aoki (aamine)
-* committer
-* He is the maintainer of:
- * fileutils
- * net/http, net/https
- * net/pop
- * net/smtp
- * racc
- * ripper
- * strscan
-
-Wakou Aoyama (wakou)
-* committer
-* He was the maintainer of some standard libraries.
-
-Koji Arai
-* committer
-
-arton
-* He is the distributor of ActiveScriptRuby and experimental 1.9.0-x installers for win32.
-* Wrote patches for win32ole, gc.c, tmpdir.rb
-
-Sergey Avseyev
-* Added IO#pread and IO#pwrite.
-
-== B
-
-Daniel Berger
-* a patch for irb
-* documentation
-* He wrote forwardable.rb
-
-David Black (dblack)
-* committer
-* He is the maintainer of scanf
-
-Ken Bloom
-* a patch for REXML.
-
-Oliver M. Bolzer
-* a patch for soap
-
-Alexey Borzenkov
-* a patch for mkmf.rb
-
-Evan Brodie
-* a patch for documentation of Float#round
-
-Richard Brown
-* a patch for configure.in
-
-Dirkjan Bussink
-* a patch for date.rb
-
-Daniel Bovensiepen
-* documentation
-* a patch for irb
-
-== C
-
-Brian Candler
-* a patch for configure.in, net/telnet
-
-keith cascio
-* a patch for optparse.rb
-
-Frederick Cheung
-* a patch for test/ruby/test_symbol.rb
-
-Christoph
-* patches for set.rb
-
-Sean Chittenden
-* pathces for net/http, cgi
-
-William D. Clinger
-* ruby_strtod is based on his paper.
-
-== D
-
-Ryan Davis (ryan)
-* committer
-* He wrote and is the maintainer of miniunit
-
-Guy Decoux (ts)
-* committer
-
-Zach Dennis
-
-Martin Duerst (duerst)
-* committer
-* M17N
-
-Paul Duncan
-* pathces for rdoc
-
-Alexander Dymo
-* a patch for lib/benchmark.rb
-
-== E
-
-Yusuke Endoh (mame)
-* committer
-* He wrote and is the maintainer of base64 library (1.9)
-* did much upon YARV compiler.
-
-erlercw
-* wrote Integer::gcd2
-
-== F
-
-Frank S.Fejes
-* a patch for net/pop
-
-Fundakowski Feldman
-* a patch for process.c
-
-Mauricio Fernandez
-* patches for parse.y
-
-David Flanagan (davidflanagan)
-* committer
-* M17N
-
-Takeyuki Fujioka (xibbar)
-* committer
-* He is the maintainer of cgi/*
-
-FUKUMOTO, Atsushi
-* a patch for tracer.rb
-
-Shota Fukumori (sorah)
-* committer
-* #4415 parallel unit/test
-
-Tadayoshi Funaba (tadf)
-* committer
-* He wrote and is the maintainer of
- * date
- * parsedate (1.8)
-* He ported rational.rb and complex.rb, which 1.8 contains, into rational.c and complex.c of 1.9.
-
-== G
-
-David M. Gay
-* ruby_strtod
-
-Florian Gilcher
-* documentation
-
-GOTOU, Kentaro (gotoken)
-* committer
-* He wrote benchmark.rb
-* He is the maintainer of:
- * benchmark.rb
- * open3
-
-GOTOU, Yuuzou (gotoyuzo)
-* committer
-
-James Edward Gray II (jeg2)
-* committer
-* He wrote the faster implementation of CSV and is the maintainer of csv.
-* Wrote documentation for rdoc
-
-== H
-
-Phil Hagelberg
-* patch for ruby-mode.el's documentation.
-
-Kirk Haines (wyhaines)
-* committer
-* the maintainer of ruby_1_8_6 branch
-
-Shinichiro Hamaji
-* fixed memory leaks (marshal.c, string.c)
-
-Shin-ichiro HARA
-* the developer and the sysop of ruby-{dev,list,core,talk} archive.
-* a patch for numeric.c
-
-Chris Heath (traumdeutung)
-* a patch for proc.c
-
-HIROKAWA Hisashi
-* fixed socket/socket.c
-
-Daniel Hob
-* He wrote:
- * SMTP-TLS support for net/smtp.
- * POP3S support
-
-Eric Hodel (drbrain)
-* committer
-* He is the maintainer of:
- * rdoc
- * ri
- * rubygems
-
-Erik Hollensbe
-* a patch for delegate.rb
-
-Johan Holmberg
-* a patch for dir.c
-* documentation
-
-Erik Huelsmann
-
-Dae San Hwang
-* built a continuous integration environment on OpenSolaris.
-
-== I
-
-Nobuhiro IMAI
-* a patch for logger.rb
-
-"incorporate"
-* a patch for sprintf.c
-
-Keiju Ishitsuka (keiju)
-* committer
-* He wrote and is the maintainer of:
- * cmath.rb (1.9)
- * complex.rb (1.8)
- * e2mmap.rb
- * forwardable.rb
- * irb
- * mathn
- * matrix.rb
- * mutex_m.rb
- * rational.rb (1.8)
- * sync.rb
- * shell/*
- * thwait.rb
- * tracer.rb
-
-== J
-
-Curtis Jackson
-* missing/dup2.c
-
-Alan Johnson
-* a patch for net/ftp
-
-Lyle Johnson
-* patches for nkf, bigdecimal, numeric.c
-
-== K
-
-Yoshihiro Kambayashi
-* a patch for enc/trans/single_byte.trans.
-* He wrote supports for some encodings.
-
-Yutaka Kanemoto
-* patches for common.mk, AIX AF_INET6 support
-
-Motoyuki Kasahara
-* He wrote getoptlong.rb
-
-Masahiro Kawato
-* a patch for shellwords.rb
-
-Wataru Kimura
-* a patch for configure.in
-
-Michael Klishin
-* patch for make help.
-
-Noritada Kobayashi
-* a patch for optparse.rb
-
-Shigeo Kobayashi (shigek)
-* committer
-* He is the maintainer of bigdecimal
-
-KONISHI, Hiromasa (H_Konishi)
-* committer
-* He had maintained the bcc32 support in 2004.
-
-Kornelius "murphy" Kalnbach
-* documentation
-
-K.Kosako (kosako)
-* committer
-* He wrote Oniguruma.
-
-Takehiro Kubo
-* patches for dl 64bit support.
-
-== L
-
-Marc-Andre Lafortune (marcandre)
-* committer
-* patches for hash.c, array.c, thread.c, enumc, string.c, range.c and rdoc documentation.
-
-Hongli Lai
-* improved pstore.rb
-* patch for tool/file2lastrev.rb.
-
-raspberry lemon
-* a patch for webrick/httpproxy.rb.
-
-Christian Loew
-* a patch for fileutils.rb
-
-== M
-
-Shugo Maeda (shugo)
-* committer
-* A system administrator of ruby-lang.org servers.
-* He wrote and is the maintainer of:
- * monitor.rb
- * net/ftp
- * net/imap
-
-Stephan Maka (mathew)
-* documentation
-
-Yukihiro Matsumoto (matz)
-* Matz -- the founder, language designer of Ruby.
-* committer
-* Ruby itself, most of Ruby.
-* He is the maintainer of:
- * singleton
- * timeout
- * gdbm
- * sdbm
-
-Konrad Meyer
-* documentation
-
-Mib Software
-* missing/vsnprintf.c
-
-Todd C. Miller
-* missing/strlcat.c
-* missing/strlcpy.c
-
-MIYASAKA, Masaru
-* a patch for cgi.rb
-
-Stefan Monnier
-* regex.c was fixed with based on his Emacs21 patch.
-
-Marcel Moolenaar
-* patches for eval.c and gc.c.
-
-moonwolf
-* a patch for REXML, xmlrpc
-
-Hiroshi Moriyama
-* a patch for yaml.
-
-Kyosuke Morohashi
-* a patch for gem_prelude.rb
-
-Kenta Murata
-* patches for json, bignum.c
-
-Akinori MUSHA (knu)
-* committer
-* He wrote and is the maintainer of:
- * abbrev.rb
- * generator (1.8)
- * enumerator (1.8)
- * set
- * ipaddr.rb
- * digest/*
- * syslog
-* He is the branch maintainer of ruby_1_8, the release manager of 1.8 series.
-
-== N
-
-Hidetoshi NAGAI (nagai)
-* committer
-* He is the maintainer of tk/*
-
-Nobuyoshi Nakada (nobu)
-* committer
-* a.k.a. the "patch monster"
-* He wrote and is the maintainer of:
- * optparse
- * stringio
- * io/wait
- * iconv
-
-Satoshi Nakagawa
-* patches for util.c
-
-Narihiro Nakamura (nari)
-* committer
-* a.k.a. authorNari
-* working at GC
-
-NAKAMURA, Hiroshi (nahi)
-* committer
-* He is the maintainer of:
- * csv.rb (1.8)
- * logger.rb
- * soap/* (1.8)
- * wsdl/* (1.8)
- * xsd/* (1.8)
-
-NAKAMURA, Usaku (usa)
-* committer
-* a.k.a. unak
-* He is the maintainer of mswin32 and mswin64 support.
-
-NARUSE, Yui (naruse)
-* committer
-* a.k.a. "nurse"
-* Did much upon m17n.
-* He is the maintainer of:
- * json
- * nkf
-
-Christian Neukirchen
-* a patch for webrick/httputils
-
-Michael Neumann (mneumann)
-* committer
-* He is the maintainer of
- * xmlrpc (1.8)
- * gserver (1.8)
-
-NISHIO Hirokazu
-* wrote a patch for CVE-2010-0541
-
-Kazuhiro NISHIYAMA (kazu)
-* committer
-* a.k.a. znz
-
-Go Noguchi
-
-Martin Nordholts
-* misc/rdebug.el
-
-nmu
-* a patch for socket
-
-== O
-
-okkez
-* He is a sysop of the Ruby Reference Manual Renewal Project.
-* fixed ipaddr.rb, ext/etc
-
-Haruhiko Okumura
-* some of missing/* is based on his book:
- * missing/erf.c
- * missing/lgamma_r.c
- * missing/tgamma.c
-
-OMAE, jun
-* a patch for debug.rb
-
-Eugene Ossintsev
-* documentation
-
-== P
-
-Heesob Park
-* a patch for win32/win32.c.
-
-pegacorn
-* a patch for instruby.rb
-
-== Q
-
-== R
-
-Gaston Ramos
-* documentation
-
-The Regents of the University of California
-* missing/crypt.c
-* missing/vsnprintf.c
-
-Sam Roberts
-* patch for socket
-* documentation
-
-Michal Rokos (michal)
-* committer
-* He was the maintainer of DJGPP support.
-
-rubikitch
-* a patch for io.c
-
-Marcus Rueckert
-* a patch for mkconfig.rb.
-
-Run Paint Run Run
-* patch for enc/unicode.c
-* documentation
-
-Sean Russell (ser)
-* committer
-* He wrote and is the maintainer of REXML.
-
-== S
-
-Kazuo Saito (ksaito)
-* committer
-* M17N
-
-Tadashi Saito
-* patches for test/ruby/test_math.rb, thread_*.c, bignum.c
-* working upon BigDecimal.
-* did much upon documentation
-
-Masahiro Sakai
-* a patch for io.c
-
-Laurent Sansonetti
-* a patch for tool/ytab.sed
-
-Jeff Saracco
-* documentation
-
-Koichi Sasada (ko1)
-* committer
-* He wrote YARV.
-
-Hugh Sasse
-* a patch for net/http
-* documentation
-
-Charlie Savage
-* a patch for win32/Makefile.sub
-
-Michael Scholz
-* a patch for ruby-mode.el
-
-Arthur Schreiber
-* patch for net/http and rdoc.
-
-Masatoshi SEKI (seki)
-* committer
-* He wrote and is the maintainer of:
- * drb/*
- * erb
- * rinda
-
-Roman Shterenzon
-* a patch for open-uri.
-
-Kent Sibilev
-
-Gavin Sinclair (gsinclair)
-* committer
-
-John W. Small
-* He wrote gserver.rb
-
-Yuki Sonoda (yugui)
-* committer
-* She is the maintainer of man/* manual pages and is the release manager of 1.9 series.
-* She wrote prime.rb.
-* A developer and a sysop of redmine.ruby-lang.org.
-
-SOUMA, Yutaka
-* a patch for pack.c.
-
-Tatsuki Sugiura
-* WebDAV support for net/http
-
-Masaki Suketa (suke)
-* committer
-* He is the maintainer of win32ole
-
-sheepman
-* patches for ruby.c, thread.c, stringio, enum.c, webrick, net/http
-
-Siena. (siena)
-* committer
-
-Kirill A. Shutemov
-* a patch for parse.y
-
-Darren Smith
-* a patch for golf_prelude.rb
-
-Richard M. Stallman
-* missing/alloca.c
-
-Robin Stocker
-* documentation
-
-Joshua Stowers
-* a patch for array.c
-
-Marcus Stollsteimer (stomar)
-* committer
-* a maintainer of www.ruby-lang.org
-* patches for cgi (HTML5 tag maker), bigdecimal, and others
-* documentation
-
-Adam Strzelecki
-* a patch for compile.c
-
-Masashi Sumi
-* improved net/pop.rb
-
-Eric Sunshine
-* NeXT OpenStep, Rhapsody support
-
-Kouhei Sutou (kou)
-* committer
-* He wrote and is the maintainer of rss/*
-
-David Symonds
-* documentation
-
-== T
-
-TAKANO Mitsuhiro (takano32)
-* committer
-* He is the maintainer of IA-64 support.
-* BigDecimal
-
-TAKAO, Kouji (kouji)
-* committer
-* He is the maintainer of readline.
-
-Nathaniel Talbott (ntalbott)
-* committer
-* He was the maintainer of test/unit, runit, rubyunit.
-
-TANAKA, Akira (akr)
-* committer
-* Did much upon m17n.
-* And he is the maintainer of:
- * open-uri
- * pathname
- * pp
- * resolv-replace
- * resolv
- * time
- * tsort
-
-Takaaki Tateishi (ttate)
-* committer
-* He was the maintainer of dl
-
-Technorama Ltd. (technoroma)
-* committer
-* openssl
-
-Andrew Thompson
-* a patch for socket.c IRIX support.
-
-Dave Thomas (dave)
-* committer
-* a.k.a. the Pragmatic Programmer.
-* He wrote rdoc.
-
-Tietew
-* patches for win32 support
-
-Masahiro Tomita
-* a patch for cgi.rb
-
-Jakub Travnik
-* a patch for eval.c
-
-Tom Truscott
-* missing/crypt.c
-
-== U
-
-UEDA, Satoshi
-* a patch for uri
-
-Takaaki Uematsu (uema2)
-* committer
-* He was the maintainer of WinCE support.
-
-UENO, Katsuhiro (katsu)
-* committer
-* He is the maintainer of zlib
-
-Hajimu UMEMOTO
-* He wrote ipaddr.rb
-
-URABE, Shyouhei (shyouhei)
-* committer
-* a.k.a. mput.
-* He is the branch maintainer of ruby_1_8_6 and ruby_1_8_7
-* and is the release manager of 1.8.x-pXXX.
-
-== V
-
-Joel VanderWerf
-* a patch for numeric.c
-
-Peter Vanbroekhoven
-
-Corinna Vinschen
-
-== W
-
-wanabe (wanabe)
-* committer
-* fixed YARV and Oniguruma.
-
-Chun Wang
-* a patch for time.rb
-
-WATANABE, Hirofumi (eban)
-* committer
-* He is the maintainer of
- * ftools (1.8)
- * tmpdir
- * un
- * Win32API
-
-WATANABE, Tetsuya
-* a patch for ruby.c
-
-William Webber (wew)
-* committer
-
-Jim Weirich (jim)
-* committer
-* He wrote Rake.
-
-Nathan Weizenbaum
-* fixed misc/ruby-mode.el.
-
-why the lukky stiff (why)
-* committer
-* He is the maintainer of syck
-
-Caley Woods
-* documentation
-
-Gary Wright
-* documentation
-
-== X
-
-== Y
-
-Akira Yamada (akira)
-* committer
-* He is the maintainer of ruby related packages at Debian project.
-
-Keita Yamaguchi
-* patches for enum.c, parse.y
-* documentation
-
-Hirokazu Yamamoto (ocean)
-* committer
-
-Hirotaka Yoshioka
-* a patch for improving SEGV handling
-
-== Z
-
-Aristarkh A Zagorodnikov
-* a patch for io.c
-
-Alexander Zavorine
-* committer
-* He is the maintainer for Symbian OS.
-
-Chiyuan Zhang
-* a patch for misc/ruby-mode.el.
-
-Dee Zsombor (zunda)
-* a patch for thread_pthread.c
-
-Dan Zwell
-* a patch for net/pop
-
-
diff --git a/doc/csv/arguments/io.rdoc b/doc/csv/arguments/io.rdoc
new file mode 100644
index 0000000000..f5fe1d1975
--- /dev/null
+++ b/doc/csv/arguments/io.rdoc
@@ -0,0 +1,5 @@
+* Argument +io+ should be an IO object that is:
+ * Open for reading; on return, the IO object will be closed.
+ * Positioned at the beginning.
+ To position at the end, for appending, use method CSV.generate.
+ For any other positioning, pass a preset \StringIO object instead.
diff --git a/doc/csv/options/common/col_sep.rdoc b/doc/csv/options/common/col_sep.rdoc
new file mode 100644
index 0000000000..05769b5773
--- /dev/null
+++ b/doc/csv/options/common/col_sep.rdoc
@@ -0,0 +1,63 @@
+====== Option +col_sep+
+
+Specifies the \String field separator to be used
+for both parsing and generating.
+The \String will be transcoded into the data's \Encoding before use.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:col_sep) # => "," (comma)
+
+Using the default (comma):
+ str = CSV.generate do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo,0\nbar,1\nbaz,2\n"
+ ary = CSV.parse(str)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Using +:+ (colon):
+ col_sep = ':'
+ str = CSV.generate(col_sep: col_sep) do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo:0\nbar:1\nbaz:2\n"
+ ary = CSV.parse(str, col_sep: col_sep)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Using +::+ (two colons):
+ col_sep = '::'
+ str = CSV.generate(col_sep: col_sep) do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo::0\nbar::1\nbaz::2\n"
+ ary = CSV.parse(str, col_sep: col_sep)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Using <tt>''</tt> (empty string):
+ col_sep = ''
+ str = CSV.generate(col_sep: col_sep) do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo0\nbar1\nbaz2\n"
+
+---
+
+Raises an exception if parsing with the empty \String:
+ col_sep = ''
+ # Raises ArgumentError (:col_sep must be 1 or more characters: "")
+ CSV.parse("foo0\nbar1\nbaz2\n", col_sep: col_sep)
+
+Raises an exception if the given value is not String-convertible:
+ col_sep = BasicObject.new
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.generate(line, col_sep: col_sep)
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.parse(str, col_sep: col_sep)
diff --git a/doc/csv/options/common/quote_char.rdoc b/doc/csv/options/common/quote_char.rdoc
new file mode 100644
index 0000000000..67fd3af68b
--- /dev/null
+++ b/doc/csv/options/common/quote_char.rdoc
@@ -0,0 +1,42 @@
+====== Option +quote_char+
+
+Specifies the character (\String of length 1) used used to quote fields
+in both parsing and generating.
+This String will be transcoded into the data's \Encoding before use.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:quote_char) # => "\"" (double quote)
+
+This is useful for an application that incorrectly uses <tt>'</tt> (single-quote)
+to quote fields, instead of the correct <tt>"</tt> (double-quote).
+
+Using the default (double quote):
+ str = CSV.generate do |csv|
+ csv << ['foo', 0]
+ csv << ["'bar'", 1]
+ csv << ['"baz"', 2]
+ end
+ str # => "foo,0\n'bar',1\n\"\"\"baz\"\"\",2\n"
+ ary = CSV.parse(str)
+ ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]]
+
+Using <tt>'</tt> (single-quote):
+ quote_char = "'"
+ str = CSV.generate(quote_char: quote_char) do |csv|
+ csv << ['foo', 0]
+ csv << ["'bar'", 1]
+ csv << ['"baz"', 2]
+ end
+ str # => "foo,0\n'''bar''',1\n\"baz\",2\n"
+ ary = CSV.parse(str, quote_char: quote_char)
+ ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]]
+
+---
+
+Raises an exception if the \String length is greater than 1:
+ # Raises ArgumentError (:quote_char has to be nil or a single character String)
+ CSV.new('', quote_char: 'xx')
+
+Raises an exception if the value is not a \String:
+ # Raises ArgumentError (:quote_char has to be nil or a single character String)
+ CSV.new('', quote_char: :foo)
diff --git a/doc/csv/options/common/row_sep.rdoc b/doc/csv/options/common/row_sep.rdoc
new file mode 100644
index 0000000000..872d9d1f3f
--- /dev/null
+++ b/doc/csv/options/common/row_sep.rdoc
@@ -0,0 +1,100 @@
+====== Option +row_sep+
+
+Specifies the row separator, a \String or the \Symbol <tt>:auto</tt> (see below),
+to be used for both parsing and generating.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:row_sep) # => :auto
+
+---
+
+When +row_sep+ is a \String, that \String becomes the row separator.
+The String will be transcoded into the data's Encoding before use.
+
+Using <tt>"\n"</tt>:
+ row_sep = "\n"
+ str = CSV.generate(row_sep: row_sep) do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo,0\nbar,1\nbaz,2\n"
+ ary = CSV.parse(str)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Using <tt>|</tt> (pipe):
+ row_sep = '|'
+ str = CSV.generate(row_sep: row_sep) do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo,0|bar,1|baz,2|"
+ ary = CSV.parse(str, row_sep: row_sep)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Using <tt>--</tt> (two hyphens):
+ row_sep = '--'
+ str = CSV.generate(row_sep: row_sep) do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo,0--bar,1--baz,2--"
+ ary = CSV.parse(str, row_sep: row_sep)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Using <tt>''</tt> (empty string):
+ row_sep = ''
+ str = CSV.generate(row_sep: row_sep) do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo,0bar,1baz,2"
+ ary = CSV.parse(str, row_sep: row_sep)
+ ary # => [["foo", "0bar", "1baz", "2"]]
+
+---
+
+When +row_sep+ is the \Symbol +:auto+ (the default),
+generating uses <tt>"\n"</tt> as the row separator:
+ str = CSV.generate do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo,0\nbar,1\nbaz,2\n"
+
+Parsing, on the other hand, invokes auto-discovery of the row separator.
+
+Auto-discovery reads ahead in the data looking for the next <tt>\r\n</tt>, +\n+, or +\r+ sequence.
+The sequence will be selected even if it occurs in a quoted field,
+assuming that you would have the same line endings there.
+
+Example:
+ str = CSV.generate do |csv|
+ csv << [:foo, 0]
+ csv << [:bar, 1]
+ csv << [:baz, 2]
+ end
+ str # => "foo,0\nbar,1\nbaz,2\n"
+ ary = CSV.parse(str)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+The default <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>) is used
+if any of the following is true:
+* None of those sequences is found.
+* Data is +ARGF+, +STDIN+, +STDOUT+, or +STDERR+.
+* The stream is only available for output.
+
+Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead.
+
+---
+
+Raises an exception if the given value is not String-convertible:
+ row_sep = BasicObject.new
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.generate(ary, row_sep: row_sep)
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.parse(str, row_sep: row_sep)
diff --git a/doc/csv/options/generating/force_quotes.rdoc b/doc/csv/options/generating/force_quotes.rdoc
new file mode 100644
index 0000000000..11afd1a16c
--- /dev/null
+++ b/doc/csv/options/generating/force_quotes.rdoc
@@ -0,0 +1,17 @@
+====== Option +force_quotes+
+
+Specifies the boolean that determines whether each output field is to be double-quoted.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:force_quotes) # => false
+
+For examples in this section:
+ ary = ['foo', 0, nil]
+
+Using the default, +false+:
+ str = CSV.generate_line(ary)
+ str # => "foo,0,\n"
+
+Using +true+:
+ str = CSV.generate_line(ary, force_quotes: true)
+ str # => "\"foo\",\"0\",\"\"\n"
diff --git a/doc/csv/options/generating/quote_empty.rdoc b/doc/csv/options/generating/quote_empty.rdoc
new file mode 100644
index 0000000000..4c5645c662
--- /dev/null
+++ b/doc/csv/options/generating/quote_empty.rdoc
@@ -0,0 +1,12 @@
+====== Option +quote_empty+
+
+Specifies the boolean that determines whether an empty value is to be double-quoted.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:quote_empty) # => true
+
+With the default +true+:
+ CSV.generate_line(['"', ""]) # => "\"\"\"\",\"\"\n"
+
+With +false+:
+ CSV.generate_line(['"', ""], quote_empty: false) # => "\"\"\"\",\n"
diff --git a/doc/csv/options/generating/write_converters.rdoc b/doc/csv/options/generating/write_converters.rdoc
new file mode 100644
index 0000000000..6e5fae5fda
--- /dev/null
+++ b/doc/csv/options/generating/write_converters.rdoc
@@ -0,0 +1,33 @@
+====== Option +write_converters+
+
+Specifies converters to be used in generating fields.
+See {Write Converters}[#class-CSV-label-Write+Converters]
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:write_converters) # => nil
+
+With no write converter:
+ str = CSV.generate_line(["\na\n", "\tb\t", " c "])
+ str # => "\"\na\n\",\tb\t, c \n"
+
+With a write converter:
+ strip_converter = proc {|field| field.strip }
+ str = CSV.generate_line(["\na\n", "\tb\t", " c "], write_converters: strip_converter)
+ str # => "a,b,c\n"
+
+With two write converters (called in order):
+ upcase_converter = proc {|field| field.upcase }
+ downcase_converter = proc {|field| field.downcase }
+ write_converters = [upcase_converter, downcase_converter]
+ str = CSV.generate_line(['a', 'b', 'c'], write_converters: write_converters)
+ str # => "a,b,c\n"
+
+See also {Write Converters}[#class-CSV-label-Write+Converters]
+
+---
+
+Raises an exception if the converter returns a value that is neither +nil+
+nor \String-convertible:
+ bad_converter = proc {|field| BasicObject.new }
+ # Raises NoMethodError (undefined method `is_a?' for #<BasicObject:>)
+ CSV.generate_line(['a', 'b', 'c'], write_converters: bad_converter) \ No newline at end of file
diff --git a/doc/csv/options/generating/write_empty_value.rdoc b/doc/csv/options/generating/write_empty_value.rdoc
new file mode 100644
index 0000000000..67be5662cb
--- /dev/null
+++ b/doc/csv/options/generating/write_empty_value.rdoc
@@ -0,0 +1,15 @@
+====== Option +write_empty_value+
+
+Specifies the object that is to be substituted for each field
+that has an empty \String.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:write_empty_value) # => ""
+
+Without the option:
+ str = CSV.generate_line(['a', '', 'c', ''])
+ str # => "a,\"\",c,\"\"\n"
+
+With the option:
+ str = CSV.generate_line(['a', '', 'c', ''], write_empty_value: "x")
+ str # => "a,x,c,x\n"
diff --git a/doc/csv/options/generating/write_headers.rdoc b/doc/csv/options/generating/write_headers.rdoc
new file mode 100644
index 0000000000..f9faa9d438
--- /dev/null
+++ b/doc/csv/options/generating/write_headers.rdoc
@@ -0,0 +1,29 @@
+====== Option +write_headers+
+
+Specifies the boolean that determines whether a header row is included in the output;
+ignored if there are no headers.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:write_headers) # => nil
+
+Without +write_headers+:
+ file_path = 't.csv'
+ CSV.open(file_path,'w',
+ :headers => ['Name','Value']
+ ) do |csv|
+ csv << ['foo', '0']
+ end
+ CSV.open(file_path) do |csv|
+ csv.shift
+ end # => ["foo", "0"]
+
+With +write_headers+":
+ CSV.open(file_path,'w',
+ :write_headers=> true,
+ :headers => ['Name','Value']
+ ) do |csv|
+ csv << ['foo', '0']
+ end
+ CSV.open(file_path) do |csv|
+ csv.shift
+ end # => ["Name", "Value"]
diff --git a/doc/csv/options/generating/write_nil_value.rdoc b/doc/csv/options/generating/write_nil_value.rdoc
new file mode 100644
index 0000000000..65d33ff54e
--- /dev/null
+++ b/doc/csv/options/generating/write_nil_value.rdoc
@@ -0,0 +1,14 @@
+====== Option +write_nil_value+
+
+Specifies the object that is to be substituted for each +nil+-valued field.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:write_nil_value) # => nil
+
+Without the option:
+ str = CSV.generate_line(['a', nil, 'c', nil])
+ str # => "a,,c,\n"
+
+With the option:
+ str = CSV.generate_line(['a', nil, 'c', nil], write_nil_value: "x")
+ str # => "a,x,c,x\n"
diff --git a/doc/csv/options/parsing/converters.rdoc b/doc/csv/options/parsing/converters.rdoc
new file mode 100644
index 0000000000..211fa48de6
--- /dev/null
+++ b/doc/csv/options/parsing/converters.rdoc
@@ -0,0 +1,46 @@
+====== Option +converters+
+
+Specifies converters to be used in parsing fields.
+See {Field Converters}[#class-CSV-label-Field+Converters]
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:converters) # => nil
+
+The value may be a field converter name
+(see {Stored Converters}[#class-CSV-label-Stored+Converters]):
+ str = '1,2,3'
+ # Without a converter
+ array = CSV.parse_line(str)
+ array # => ["1", "2", "3"]
+ # With built-in converter :integer
+ array = CSV.parse_line(str, converters: :integer)
+ array # => [1, 2, 3]
+
+The value may be a converter list
+(see {Converter Lists}[#class-CSV-label-Converter+Lists]):
+ str = '1,3.14159'
+ # Without converters
+ array = CSV.parse_line(str)
+ array # => ["1", "3.14159"]
+ # With built-in converters
+ array = CSV.parse_line(str, converters: [:integer, :float])
+ array # => [1, 3.14159]
+
+The value may be a \Proc custom converter:
+(see {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters]):
+ str = ' foo , bar , baz '
+ # Without a converter
+ array = CSV.parse_line(str)
+ array # => [" foo ", " bar ", " baz "]
+ # With a custom converter
+ array = CSV.parse_line(str, converters: proc {|field| field.strip })
+ array # => ["foo", "bar", "baz"]
+
+See also {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters]
+
+---
+
+Raises an exception if the converter is not a converter name or a \Proc:
+ str = 'foo,0'
+ # Raises NoMethodError (undefined method `arity' for nil:NilClass)
+ CSV.parse(str, converters: :foo)
diff --git a/doc/csv/options/parsing/empty_value.rdoc b/doc/csv/options/parsing/empty_value.rdoc
new file mode 100644
index 0000000000..7d3bcc078c
--- /dev/null
+++ b/doc/csv/options/parsing/empty_value.rdoc
@@ -0,0 +1,13 @@
+====== Option +empty_value+
+
+Specifies the object that is to be substituted
+for each field that has an empty \String.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:empty_value) # => "" (empty string)
+
+With the default, <tt>""</tt>:
+ CSV.parse_line('a,"",b,"",c') # => ["a", "", "b", "", "c"]
+
+With a different object:
+ CSV.parse_line('a,"",b,"",c', empty_value: 'x') # => ["a", "x", "b", "x", "c"]
diff --git a/doc/csv/options/parsing/field_size_limit.rdoc b/doc/csv/options/parsing/field_size_limit.rdoc
new file mode 100644
index 0000000000..797c5776fc
--- /dev/null
+++ b/doc/csv/options/parsing/field_size_limit.rdoc
@@ -0,0 +1,39 @@
+====== Option +field_size_limit+
+
+Specifies the \Integer field size limit.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:field_size_limit) # => nil
+
+This is a maximum size CSV will read ahead looking for the closing quote for a field.
+(In truth, it reads to the first line ending beyond this size.)
+If a quote cannot be found within the limit CSV will raise a MalformedCSVError,
+assuming the data is faulty.
+You can use this limit to prevent what are effectively DoS attacks on the parser.
+However, this limit can cause a legitimate parse to fail;
+therefore the default value is +nil+ (no limit).
+
+For the examples in this section:
+ str = <<~EOT
+ "a","b"
+ "
+ 2345
+ ",""
+ EOT
+ str # => "\"a\",\"b\"\n\"\n2345\n\",\"\"\n"
+
+Using the default +nil+:
+ ary = CSV.parse(str)
+ ary # => [["a", "b"], ["\n2345\n", ""]]
+
+Using <tt>50</tt>:
+ field_size_limit = 50
+ ary = CSV.parse(str, field_size_limit: field_size_limit)
+ ary # => [["a", "b"], ["\n2345\n", ""]]
+
+---
+
+Raises an exception if a field is too long:
+ big_str = "123456789\n" * 1024
+ # Raises CSV::MalformedCSVError (Field size exceeded in line 1.)
+ CSV.parse('valid,fields,"' + big_str + '"', field_size_limit: 2048)
diff --git a/doc/csv/options/parsing/header_converters.rdoc b/doc/csv/options/parsing/header_converters.rdoc
new file mode 100644
index 0000000000..309180805f
--- /dev/null
+++ b/doc/csv/options/parsing/header_converters.rdoc
@@ -0,0 +1,43 @@
+====== Option +header_converters+
+
+Specifies converters to be used in parsing headers.
+See {Header Converters}[#class-CSV-label-Header+Converters]
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:header_converters) # => nil
+
+Identical in functionality to option {converters}[#class-CSV-label-Option+converters]
+except that:
+- The converters apply only to the header row.
+- The built-in header converters are +:downcase+ and +:symbol+.
+
+This section assumes prior execution of:
+ str = <<-EOT
+ Name,Value
+ foo,0
+ bar,1
+ baz,2
+ EOT
+ # With no header converter
+ table = CSV.parse(str, headers: true)
+ table.headers # => ["Name", "Value"]
+
+The value may be a header converter name
+(see {Stored Converters}[#class-CSV-label-Stored+Converters]):
+ table = CSV.parse(str, headers: true, header_converters: :downcase)
+ table.headers # => ["name", "value"]
+
+The value may be a converter list
+(see {Converter Lists}[#class-CSV-label-Converter+Lists]):
+ header_converters = [:downcase, :symbol]
+ table = CSV.parse(str, headers: true, header_converters: header_converters)
+ table.headers # => [:name, :value]
+
+The value may be a \Proc custom converter
+(see {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters]):
+ upcase_converter = proc {|field| field.upcase }
+ table = CSV.parse(str, headers: true, header_converters: upcase_converter)
+ table.headers # => ["NAME", "VALUE"]
+
+See also {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters]
+
diff --git a/doc/csv/options/parsing/headers.rdoc b/doc/csv/options/parsing/headers.rdoc
new file mode 100644
index 0000000000..0ea151f24b
--- /dev/null
+++ b/doc/csv/options/parsing/headers.rdoc
@@ -0,0 +1,63 @@
+====== Option +headers+
+
+Specifies a boolean, \Symbol, \Array, or \String to be used
+to define column headers.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:headers) # => false
+
+---
+
+Without +headers+:
+ str = <<-EOT
+ Name,Count
+ foo,0
+ bar,1
+ bax,2
+ EOT
+ csv = CSV.new(str)
+ csv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ csv.headers # => nil
+ csv.shift # => ["Name", "Count"]
+
+---
+
+If set to +true+ or the \Symbol +:first_row+,
+the first row of the data is treated as a row of headers:
+ str = <<-EOT
+ Name,Count
+ foo,0
+ bar,1
+ bax,2
+ EOT
+ csv = CSV.new(str, headers: true)
+ csv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:2 col_sep:"," row_sep:"\n" quote_char:"\"" headers:["Name", "Count"]>
+ csv.headers # => ["Name", "Count"]
+ csv.shift # => #<CSV::Row "Name":"bar" "Count":"1">
+
+---
+
+If set to an \Array, the \Array elements are treated as headers:
+ str = <<-EOT
+ foo,0
+ bar,1
+ bax,2
+ EOT
+ csv = CSV.new(str, headers: ['Name', 'Count'])
+ csv
+ csv.headers # => ["Name", "Count"]
+ csv.shift # => #<CSV::Row "Name":"bar" "Count":"1">
+
+---
+
+If set to a \String +str+, method <tt>CSV::parse_line(str, options)</tt> is called
+with the current +options+, and the returned \Array is treated as headers:
+ str = <<-EOT
+ foo,0
+ bar,1
+ bax,2
+ EOT
+ csv = CSV.new(str, headers: 'Name,Count')
+ csv
+ csv.headers # => ["Name", "Count"]
+ csv.shift # => #<CSV::Row "Name":"bar" "Count":"1">
diff --git a/doc/csv/options/parsing/liberal_parsing.rdoc b/doc/csv/options/parsing/liberal_parsing.rdoc
new file mode 100644
index 0000000000..b8b9b00c98
--- /dev/null
+++ b/doc/csv/options/parsing/liberal_parsing.rdoc
@@ -0,0 +1,19 @@
+====== Option +liberal_parsing+
+
+Specifies the boolean value that determines whether
+CSV will attempt to parse input not conformant with RFC 4180,
+such as double quotes in unquoted fields.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:liberal_parsing) # => false
+
+For examples in this section:
+ str = 'is,this "three, or four",fields'
+
+Without +liberal_parsing+:
+ # Raises CSV::MalformedCSVError (Illegal quoting in str 1.)
+ CSV.parse_line(str)
+
+With +liberal_parsing+:
+ ary = CSV.parse_line(str, liberal_parsing: true)
+ ary # => ["is", "this \"three", " or four\"", "fields"]
diff --git a/doc/csv/options/parsing/nil_value.rdoc b/doc/csv/options/parsing/nil_value.rdoc
new file mode 100644
index 0000000000..412e8795e8
--- /dev/null
+++ b/doc/csv/options/parsing/nil_value.rdoc
@@ -0,0 +1,12 @@
+====== Option +nil_value+
+
+Specifies the object that is to be substituted for each null (no-text) field.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:nil_value) # => nil
+
+With the default, +nil+:
+ CSV.parse_line('a,,b,,c') # => ["a", nil, "b", nil, "c"]
+
+With a different object:
+ CSV.parse_line('a,,b,,c', nil_value: 0) # => ["a", 0, "b", 0, "c"]
diff --git a/doc/csv/options/parsing/return_headers.rdoc b/doc/csv/options/parsing/return_headers.rdoc
new file mode 100644
index 0000000000..45d2e3f3de
--- /dev/null
+++ b/doc/csv/options/parsing/return_headers.rdoc
@@ -0,0 +1,22 @@
+====== Option +return_headers+
+
+Specifies the boolean that determines whether method #shift
+returns or ignores the header row.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:return_headers) # => false
+
+Examples:
+ str = <<-EOT
+ Name,Count
+ foo,0
+ bar,1
+ bax,2
+ EOT
+ # Without return_headers first row is str.
+ csv = CSV.new(str, headers: true)
+ csv.shift # => #<CSV::Row "Name":"foo" "Count":"0">
+ # With return_headers first row is headers.
+ csv = CSV.new(str, headers: true, return_headers: true)
+ csv.shift # => #<CSV::Row "Name":"Name" "Count":"Count">
+
diff --git a/doc/csv/options/parsing/skip_blanks.rdoc b/doc/csv/options/parsing/skip_blanks.rdoc
new file mode 100644
index 0000000000..2c8f7b7bb8
--- /dev/null
+++ b/doc/csv/options/parsing/skip_blanks.rdoc
@@ -0,0 +1,31 @@
+====== Option +skip_blanks+
+
+Specifies a boolean that determines whether blank lines in the input will be ignored;
+a line that contains a column separator is not considered to be blank.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:skip_blanks) # => false
+
+See also option {skiplines}[#class-CSV-label-Option+skip_lines].
+
+For examples in this section:
+ str = <<-EOT
+ foo,0
+
+ bar,1
+ baz,2
+
+ ,
+ EOT
+
+Using the default, +false+:
+ ary = CSV.parse(str)
+ ary # => [["foo", "0"], [], ["bar", "1"], ["baz", "2"], [], [nil, nil]]
+
+Using +true+:
+ ary = CSV.parse(str, skip_blanks: true)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]]
+
+Using a truthy value:
+ ary = CSV.parse(str, skip_blanks: :foo)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]]
diff --git a/doc/csv/options/parsing/skip_lines.rdoc b/doc/csv/options/parsing/skip_lines.rdoc
new file mode 100644
index 0000000000..1481c40a5f
--- /dev/null
+++ b/doc/csv/options/parsing/skip_lines.rdoc
@@ -0,0 +1,37 @@
+====== Option +skip_lines+
+
+Specifies an object to use in identifying comment lines in the input that are to be ignored:
+* If a \Regexp, ignores lines that match it.
+* If a \String, converts it to a \Regexp, ignores lines that match it.
+* If +nil+, no lines are considered to be comments.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:skip_lines) # => nil
+
+For examples in this section:
+ str = <<-EOT
+ # Comment
+ foo,0
+ bar,1
+ baz,2
+ # Another comment
+ EOT
+ str # => "# Comment\nfoo,0\nbar,1\nbaz,2\n# Another comment\n"
+
+Using the default, +nil+:
+ ary = CSV.parse(str)
+ ary # => [["# Comment"], ["foo", "0"], ["bar", "1"], ["baz", "2"], ["# Another comment"]]
+
+Using a \Regexp:
+ ary = CSV.parse(str, skip_lines: /^#/)
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Using a \String:
+ ary = CSV.parse(str, skip_lines: '#')
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+---
+
+Raises an exception if given an object that is not a \Regexp, a \String, or +nil+:
+ # Raises ArgumentError (:skip_lines has to respond to #match: 0)
+ CSV.parse(str, skip_lines: 0)
diff --git a/doc/csv/options/parsing/strip.rdoc b/doc/csv/options/parsing/strip.rdoc
new file mode 100644
index 0000000000..56ae4310c3
--- /dev/null
+++ b/doc/csv/options/parsing/strip.rdoc
@@ -0,0 +1,15 @@
+====== Option +strip+
+
+Specifies the boolean value that determines whether
+whitespace is stripped from each input field.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:strip) # => false
+
+With default value +false+:
+ ary = CSV.parse_line(' a , b ')
+ ary # => [" a ", " b "]
+
+With value +true+:
+ ary = CSV.parse_line(' a , b ', strip: true)
+ ary # => ["a", "b"]
diff --git a/doc/csv/options/parsing/unconverted_fields.rdoc b/doc/csv/options/parsing/unconverted_fields.rdoc
new file mode 100644
index 0000000000..3e7f839d49
--- /dev/null
+++ b/doc/csv/options/parsing/unconverted_fields.rdoc
@@ -0,0 +1,27 @@
+====== Option +unconverted_fields+
+
+Specifies the boolean that determines whether unconverted field values are to be available.
+
+Default value:
+ CSV::DEFAULT_OPTIONS.fetch(:unconverted_fields) # => nil
+
+The unconverted field values are those found in the source data,
+prior to any conversions performed via option +converters+.
+
+When option +unconverted_fields+ is +true+,
+each returned row (\Array or \CSV::Row) has an added method,
++unconverted_fields+, that returns the unconverted field values:
+ str = <<-EOT
+ foo,0
+ bar,1
+ baz,2
+ EOT
+ # Without unconverted_fields
+ csv = CSV.parse(str, converters: :integer)
+ csv # => [["foo", 0], ["bar", 1], ["baz", 2]]
+ csv.first.respond_to?(:unconverted_fields) # => false
+ # With unconverted_fields
+ csv = CSV.parse(str, converters: :integer, unconverted_fields: true)
+ csv # => [["foo", 0], ["bar", 1], ["baz", 2]]
+ csv.first.respond_to?(:unconverted_fields) # => true
+ csv.first.unconverted_fields # => ["foo", "0"]
diff --git a/doc/csv/recipes/filtering.rdoc b/doc/csv/recipes/filtering.rdoc
new file mode 100644
index 0000000000..470649d09a
--- /dev/null
+++ b/doc/csv/recipes/filtering.rdoc
@@ -0,0 +1,156 @@
+== Recipes for Filtering \CSV
+
+For other recipes, see {Recipes for CSV}[./recipes_rdoc.html].
+
+All code snippets on this page assume that the following has been executed:
+ require 'csv'
+
+=== Contents
+
+- {Source and Output Formats}[#label-Source+and+Output+Formats]
+ - {Filtering String to String}[#label-Filtering+String+to+String]
+ - {Recipe: Filter String to String with Headers}[#label-Recipe-3A+Filter+String+to+String+with+Headers]
+ - {Recipe: Filter String to String Without Headers}[#label-Recipe-3A+Filter+String+to+String+Without+Headers]
+ - {Filtering String to IO Stream}[#label-Filtering+String+to+IO+Stream]
+ - {Recipe: Filter String to IO Stream with Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+with+Headers]
+ - {Recipe: Filter String to IO Stream Without Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+Without+Headers]
+ - {Filtering IO Stream to String}[#label-Filtering+IO+Stream+to+String]
+ - {Recipe: Filter IO Stream to String with Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+with+Headers]
+ - {Recipe: Filter IO Stream to String Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+Without+Headers]
+ - {Filtering IO Stream to IO Stream}[#label-Filtering+IO+Stream+to+IO+Stream]
+ - {Recipe: Filter IO Stream to IO Stream with Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+with+Headers]
+ - {Recipe: Filter IO Stream to IO Stream Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+Without+Headers]
+
+=== Source and Output Formats
+
+You can use a Unix-style "filter" for \CSV data.
+The filter reads source \CSV data and writes output \CSV data as modified by the filter.
+The input and output \CSV data may be any mixture of \Strings and \IO streams.
+
+==== Filtering \String to \String
+
+You can filter one \String to another, with or without headers.
+
+===== Recipe: Filter \String to \String with Headers
+
+Use class method CSV.filter with option +headers+ to filter a \String to another \String:
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ out_string = ''
+ CSV.filter(in_string, out_string, headers: true) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"
+
+===== Recipe: Filter \String to \String Without Headers
+
+Use class method CSV.filter without option +headers+ to filter a \String to another \String:
+ in_string = "foo,0\nbar,1\nbaz,2\n"
+ out_string = ''
+ CSV.filter(in_string, out_string) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
+
+==== Filtering \String to \IO Stream
+
+You can filter a \String to an \IO stream, with or without headers.
+
+===== Recipe: Filter \String to \IO Stream with Headers
+
+Use class method CSV.filter with option +headers+ to filter a \String to an \IO stream:
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.open(path, 'w') do |out_io|
+ CSV.filter(in_string, out_io, headers: true) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ end
+ p File.read(path) # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"
+
+===== Recipe: Filter \String to \IO Stream Without Headers
+
+Use class method CSV.filter without option +headers+ to filter a \String to an \IO stream:
+ in_string = "foo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.open(path, 'w') do |out_io|
+ CSV.filter(in_string, out_io) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ end
+ p File.read(path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
+
+==== Filtering \IO Stream to \String
+
+You can filter an \IO stream to a \String, with or without headers.
+
+===== Recipe: Filter \IO Stream to \String with Headers
+
+Use class method CSV.filter with option +headers+ to filter an \IO stream to a \String:
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.write(path, in_string)
+ out_string = ''
+ File.open(path, headers: true) do |in_io|
+ CSV.filter(in_io, out_string, headers: true) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ end
+ out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"
+
+===== Recipe: Filter \IO Stream to \String Without Headers
+
+Use class method CSV.filter without option +headers+ to filter an \IO stream to a \String:
+ in_string = "foo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.write(path, in_string)
+ out_string = ''
+ File.open(path) do |in_io|
+ CSV.filter(in_io, out_string) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ end
+ out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
+
+==== Filtering \IO Stream to \IO Stream
+
+You can filter an \IO stream to another \IO stream, with or without headers.
+
+===== Recipe: Filter \IO Stream to \IO Stream with Headers
+
+Use class method CSV.filter with option +headers+ to filter an \IO stream to another \IO stream:
+ in_path = 't.csv'
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ File.write(in_path, in_string)
+ out_path = 'u.csv'
+ File.open(in_path) do |in_io|
+ File.open(out_path, 'w') do |out_io|
+ CSV.filter(in_io, out_io, headers: true) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ end
+ end
+ p File.read(out_path) # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"
+
+===== Recipe: Filter \IO Stream to \IO Stream Without Headers
+
+Use class method CSV.filter without option +headers+ to filter an \IO stream to another \IO stream:
+ in_path = 't.csv'
+ in_string = "foo,0\nbar,1\nbaz,2\n"
+ File.write(in_path, in_string)
+ out_path = 'u.csv'
+ File.open(in_path) do |in_io|
+ File.open(out_path, 'w') do |out_io|
+ CSV.filter(in_io, out_io) do |row|
+ row[0] = row[0].upcase
+ row[1] *= 4
+ end
+ end
+ end
+ p File.read(out_path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
diff --git a/doc/csv/recipes/generating.rdoc b/doc/csv/recipes/generating.rdoc
new file mode 100644
index 0000000000..3ef6df99b4
--- /dev/null
+++ b/doc/csv/recipes/generating.rdoc
@@ -0,0 +1,244 @@
+== Recipes for Generating \CSV
+
+For other recipes, see {Recipes for CSV}[./recipes_rdoc.html].
+
+All code snippets on this page assume that the following has been executed:
+ require 'csv'
+
+=== Contents
+
+- {Output Formats}[#label-Output+Formats]
+ - {Generating to a String}[#label-Generating+to+a+String]
+ - {Recipe: Generate to String with Headers}[#label-Recipe-3A+Generate+to+String+with+Headers]
+ - {Recipe: Generate to String Without Headers}[#label-Recipe-3A+Generate+to+String+Without+Headers]
+ - {Generating to a File}[#label-Generating+to+a+File]
+ - {Recipe: Generate to File with Headers}[#label-Recipe-3A+Generate+to+File+with+Headers]
+ - {Recipe: Generate to File Without Headers}[#label-Recipe-3A+Generate+to+File+Without+Headers]
+ - {Generating to IO an Stream}[#label-Generating+to+an+IO+Stream]
+ - {Recipe: Generate to IO Stream with Headers}[#label-Recipe-3A+Generate+to+IO+Stream+with+Headers]
+ - {Recipe: Generate to IO Stream Without Headers}[#label-Recipe-3A+Generate+to+IO+Stream+Without+Headers]
+- {Converting Fields}[#label-Converting+Fields]
+ - {Recipe: Filter Generated Field Strings}[#label-Recipe-3A+Filter+Generated+Field+Strings]
+ - {Recipe: Specify Multiple Write Converters}[#label-Recipe-3A+Specify+Multiple+Write+Converters]
+- {RFC 4180 Compliance}[#label-RFC+4180+Compliance]
+ - {Row Separator}[#label-Row+Separator]
+ - {Recipe: Generate Compliant Row Separator}[#label-Recipe-3A+Generate+Compliant+Row+Separator]
+ - {Recipe: Generate Non-Compliant Row Separator}[#label-Recipe-3A+Generate+Non-Compliant+Row+Separator]
+ - {Column Separator}[#label-Column+Separator]
+ - {Recipe: Generate Compliant Column Separator}[#label-Recipe-3A+Generate+Compliant+Column+Separator]
+ - {Recipe: Generate Non-Compliant Column Separator}[#label-Recipe-3A+Generate+Non-Compliant+Column+Separator]
+ - {Quote Character}[#label-Quote+Character]
+ - {Recipe: Generate Compliant Quote Character}[#label-Recipe-3A+Generate+Compliant+Quote+Character]
+ - {Recipe: Generate Non-Compliant Quote Character}[#label-Recipe-3A+Generate+Non-Compliant+Quote+Character]
+
+=== Output Formats
+
+You can generate \CSV output to a \String, to a \File (via its path), or to an \IO stream.
+
+==== Generating to a \String
+
+You can generate \CSV output to a \String, with or without headers.
+
+===== Recipe: Generate to \String with Headers
+
+Use class method CSV.generate with option +headers+ to generate to a \String.
+
+This example uses method CSV#<< to append the rows
+that are to be generated:
+ output_string = CSV.generate('', headers: ['Name', 'Value'], write_headers: true) do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "Name,Value\nFoo,0\nBar,1\nBaz,2\n"
+
+===== Recipe: Generate to \String Without Headers
+
+Use class method CSV.generate without option +headers+ to generate to a \String.
+
+This example uses method CSV#<< to append the rows
+that are to be generated:
+ output_string = CSV.generate do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "Foo,0\nBar,1\nBaz,2\n"
+
+==== Generating to a \File
+
+You can generate /CSV data to a \File, with or without headers.
+
+===== Recipe: Generate to \File with Headers
+
+Use class method CSV.open with option +headers+ generate to a \File.
+
+This example uses method CSV#<< to append the rows
+that are to be generated:
+ path = 't.csv'
+ CSV.open(path, 'w', headers: ['Name', 'Value'], write_headers: true) do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ p File.read(path) # => "Name,Value\nFoo,0\nBar,1\nBaz,2\n"
+
+===== Recipe: Generate to \File Without Headers
+
+Use class method CSV.open without option +headers+ to generate to a \File.
+
+This example uses method CSV#<< to append the rows
+that are to be generated:
+ path = 't.csv'
+ CSV.open(path, 'w') do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ p File.read(path) # => "Foo,0\nBar,1\nBaz,2\n"
+
+==== Generating to an \IO Stream
+
+You can generate \CSV data to an \IO stream, with or without headers.
+
+==== Recipe: Generate to \IO Stream with Headers
+
+Use class method CSV.new with option +headers+ to generate \CSV data to an \IO stream:
+ path = 't.csv'
+ File.open(path, 'w') do |file|
+ csv = CSV.new(file, headers: ['Name', 'Value'], write_headers: true)
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ p File.read(path) # => "Name,Value\nFoo,0\nBar,1\nBaz,2\n"
+
+===== Recipe: Generate to \IO Stream Without Headers
+
+Use class method CSV.new without option +headers+ to generate \CSV data to an \IO stream:
+ path = 't.csv'
+ File.open(path, 'w') do |file|
+ csv = CSV.new(file)
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ p File.read(path) # => "Foo,0\nBar,1\nBaz,2\n"
+
+=== Converting Fields
+
+You can use _write_ _converters_ to convert fields when generating \CSV.
+
+==== Recipe: Filter Generated Field Strings
+
+Use option <tt>:write_converters</tt> and a custom converter to convert field values when generating \CSV.
+
+This example defines and uses a custom write converter to strip whitespace from generated fields:
+ strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field }
+ output_string = CSV.generate(write_converters: strip_converter) do |csv|
+ csv << [' foo ', 0]
+ csv << [' bar ', 1]
+ csv << [' baz ', 2]
+ end
+ output_string # => "foo,0\nbar,1\nbaz,2\n"
+
+==== Recipe: Specify Multiple Write Converters
+
+Use option <tt>:write_converters</tt> and multiple custom coverters
+to convert field values when generating \CSV.
+
+This example defines and uses two custom write converters to strip and upcase generated fields:
+ strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field }
+ upcase_converter = proc {|field| field.respond_to?(:upcase) ? field.upcase : field }
+ converters = [strip_converter, upcase_converter]
+ output_string = CSV.generate(write_converters: converters) do |csv|
+ csv << [' foo ', 0]
+ csv << [' bar ', 1]
+ csv << [' baz ', 2]
+ end
+ output_string # => "FOO,0\nBAR,1\nBAZ,2\n"
+
+=== RFC 4180 Compliance
+
+By default, \CSV generates data that is compliant with
+{RFC 4180}[https://tools.ietf.org/html/rfc4180]
+with respect to:
+- Column separator.
+- Quote character.
+
+==== Row Separator
+
+RFC 4180 specifies the row separator CRLF (Ruby <tt>"\r\n"</tt>).
+
+===== Recipe: Generate Compliant Row Separator
+
+For strict compliance, use option +:row_sep+ to specify row separator <tt>"\r\n"</tt>:
+ output_string = CSV.generate('', row_sep: "\r\n") do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "Foo,0\r\nBar,1\r\nBaz,2\r\n"
+
+===== Recipe: Generate Non-Compliant Row Separator
+
+For data with non-compliant row separators, use option +:row_sep+ with a different value:
+This example source uses semicolon (<tt>";'</tt>) as its row separator:
+ output_string = CSV.generate('', row_sep: ";") do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "Foo,0;Bar,1;Baz,2;"
+
+==== Column Separator
+
+RFC 4180 specifies column separator COMMA (Ruby <tt>","</tt>).
+
+===== Recipe: Generate Compliant Column Separator
+
+Because the \CSV default comma separator is <tt>","</tt>,
+you need not specify option +:col_sep+ for compliant data:
+ output_string = CSV.generate('') do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "Foo,0\nBar,1\nBaz,2\n"
+
+===== Recipe: Generate Non-Compliant Column Separator
+
+For data with non-compliant column separators, use option +:col_sep+.
+This example source uses TAB (<tt>"\t"</tt>) as its column separator:
+ output_string = CSV.generate('', col_sep: "\t") do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "Foo\t0\nBar\t1\nBaz\t2\n"
+
+==== Quote Character
+
+RFC 4180 specifies quote character DQUOTE (Ruby <tt>"\""</tt>).
+
+===== Recipe: Generate Compliant Quote Character
+
+Because the \CSV default quote character is <tt>"\""</tt>,
+you need not specify option +:quote_char+ for compliant data:
+ output_string = CSV.generate('', force_quotes: true) do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "\"Foo\",\"0\"\n\"Bar\",\"1\"\n\"Baz\",\"2\"\n"
+
+===== Recipe: Generate Non-Compliant Quote Character
+
+For data with non-compliant quote characters, use option +:quote_char+.
+This example source uses SQUOTE (<tt>"'"</tt>) as its quote character:
+ output_string = CSV.generate('', quote_char: "'", force_quotes: true) do |csv|
+ csv << ['Foo', 0]
+ csv << ['Bar', 1]
+ csv << ['Baz', 2]
+ end
+ output_string # => "'Foo','0'\n'Bar','1'\n'Baz','2'\n"
diff --git a/doc/csv/recipes/parsing.rdoc b/doc/csv/recipes/parsing.rdoc
new file mode 100644
index 0000000000..6312cea5c4
--- /dev/null
+++ b/doc/csv/recipes/parsing.rdoc
@@ -0,0 +1,543 @@
+== Recipes for Parsing \CSV
+
+For other recipes, see {Recipes for CSV}[./recipes_rdoc.html].
+
+All code snippets on this page assume that the following has been executed:
+ require 'csv'
+
+=== Contents
+
+- {Source Formats}[#label-Source+Formats]
+ - {Parsing from a String}[#label-Parsing+from+a+String]
+ - {Recipe: Parse from String with Headers}[#label-Recipe-3A+Parse+from+String+with+Headers]
+ - {Recipe: Parse from String Without Headers}[#label-Recipe-3A+Parse+from+String+Without+Headers]
+ - {Parsing from a File}[#label-Parsing+from+a+File]
+ - {Recipe: Parse from File with Headers}[#label-Recipe-3A+Parse+from+File+with+Headers]
+ - {Recipe: Parse from File Without Headers}[#label-Recipe-3A+Parse+from+File+Without+Headers]
+ - {Parsing from an IO Stream}[#label-Parsing+from+an+IO+Stream]
+ - {Recipe: Parse from IO Stream with Headers}[#label-Recipe-3A+Parse+from+IO+Stream+with+Headers]
+ - {Recipe: Parse from IO Stream Without Headers}[#label-Recipe-3A+Parse+from+IO+Stream+Without+Headers]
+- {RFC 4180 Compliance}[#label-RFC+4180+Compliance]
+ - {Row Separator}[#label-Row+Separator]
+ - {Recipe: Handle Compliant Row Separator}[#label-Recipe-3A+Handle+Compliant+Row+Separator]
+ - {Recipe: Handle Non-Compliant Row Separator}[#label-Recipe-3A+Handle+Non-Compliant+Row+Separator]
+ - {Column Separator}[#label-Column+Separator]
+ - {Recipe: Handle Compliant Column Separator}[#label-Recipe-3A+Handle+Compliant+Column+Separator]
+ - {Recipe: Handle Non-Compliant Column Separator}[#label-Recipe-3A+Handle+Non-Compliant+Column+Separator]
+ - {Quote Character}[#label-Quote+Character]
+ - {Recipe: Handle Compliant Quote Character}[#label-Recipe-3A+Handle+Compliant+Quote+Character]
+ - {Recipe: Handle Non-Compliant Quote Character}[#label-Recipe-3A+Handle+Non-Compliant+Quote+Character]
+ - {Recipe: Allow Liberal Parsing}[#label-Recipe-3A+Allow+Liberal+Parsing]
+- {Special Handling}[#label-Special+Handling]
+ - {Special Line Handling}[#label-Special+Line+Handling]
+ - {Recipe: Ignore Blank Lines}[#label-Recipe-3A+Ignore+Blank+Lines]
+ - {Recipe: Ignore Selected Lines}[#label-Recipe-3A+Ignore+Selected+Lines]
+ - {Special Field Handling}[#label-Special+Field+Handling]
+ - {Recipe: Strip Fields}[#label-Recipe-3A+Strip+Fields]
+ - {Recipe: Handle Null Fields}[#label-Recipe-3A+Handle+Null+Fields]
+ - {Recipe: Handle Empty Fields}[#label-Recipe-3A+Handle+Empty+Fields]
+- {Converting Fields}[#label-Converting+Fields]
+ - {Converting Fields to Objects}[#label-Converting+Fields+to+Objects]
+ - {Recipe: Convert Fields to Integers}[#label-Recipe-3A+Convert+Fields+to+Integers]
+ - {Recipe: Convert Fields to Floats}[#label-Recipe-3A+Convert+Fields+to+Floats]
+ - {Recipe: Convert Fields to Numerics}[#label-Recipe-3A+Convert+Fields+to+Numerics]
+ - {Recipe: Convert Fields to Dates}[#label-Recipe-3A+Convert+Fields+to+Dates]
+ - {Recipe: Convert Fields to DateTimes}[#label-Recipe-3A+Convert+Fields+to+DateTimes]
+ - {Recipe: Convert Assorted Fields to Objects}[#label-Recipe-3A+Convert+Assorted+Fields+to+Objects]
+ - {Recipe: Convert Fields to Other Objects}[#label-Recipe-3A+Convert+Fields+to+Other+Objects]
+ - {Recipe: Filter Field Strings}[#label-Recipe-3A+Filter+Field+Strings]
+ - {Recipe: Register Field Converters}[#label-Recipe-3A+Register+Field+Converters]
+ - {Using Multiple Field Converters}[#label-Using+Multiple+Field+Converters]
+ - {Recipe: Specify Multiple Field Converters in Option :converters}[#label-Recipe-3A+Specify+Multiple+Field+Converters+in+Option+-3Aconverters]
+ - {Recipe: Specify Multiple Field Converters in a Custom Converter List}[#label-Recipe-3A+Specify+Multiple+Field+Converters+in+a+Custom+Converter+List]
+- {Converting Headers}[#label-Converting+Headers]
+ - {Recipe: Convert Headers to Lowercase}[#label-Recipe-3A+Convert+Headers+to+Lowercase]
+ - {Recipe: Convert Headers to Symbols}[#label-Recipe-3A+Convert+Headers+to+Symbols]
+ - {Recipe: Filter Header Strings}[#label-Recipe-3A+Filter+Header+Strings]
+ - {Recipe: Register Header Converters}[#label-Recipe-3A+Register+Header+Converters]
+ - {Using Multiple Header Converters}[#label-Using+Multiple+Header+Converters]
+ - {Recipe: Specify Multiple Header Converters in Option :header_converters}[#label-Recipe-3A+Specify+Multiple+Header+Converters+in+Option+-3Aheader_converters]
+ - {Recipe: Specify Multiple Header Converters in a Custom Header Converter List}[#label-Recipe-3A+Specify+Multiple+Header+Converters+in+a+Custom+Header+Converter+List]
+- {Diagnostics}[#label-Diagnostics]
+ - {Recipe: Capture Unconverted Fields}[#label-Recipe-3A+Capture+Unconverted+Fields]
+ - {Recipe: Capture Field Info}[#label-Recipe-3A+Capture+Field+Info]
+
+=== Source Formats
+
+You can parse \CSV data from a \String, from a \File (via its path), or from an \IO stream.
+
+==== Parsing from a \String
+
+You can parse \CSV data from a \String, with or without headers.
+
+===== Recipe: Parse from \String with Headers
+
+Use class method CSV.parse with option +headers+ to read a source \String all at once
+(may have memory resource implications):
+ string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ CSV.parse(string, headers: true) # => #<CSV::Table mode:col_or_row row_count:4>
+
+Use instance method CSV#each with option +headers+ to read a source \String one row at a time:
+ CSV.new(string, headers: true).each do |row|
+ p row
+ end
+Output:
+ #<CSV::Row "Name":"foo" "Value":"0">
+ #<CSV::Row "Name":"bar" "Value":"1">
+ #<CSV::Row "Name":"baz" "Value":"2">
+
+===== Recipe: Parse from \String Without Headers
+
+Use class method CSV.parse without option +headers+ to read a source \String all at once
+(may have memory resource implications):
+ string = "foo,0\nbar,1\nbaz,2\n"
+ CSV.parse(string) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Use instance method CSV#each without option +headers+ to read a source \String one row at a time:
+ CSV.new(string).each do |row|
+ p row
+ end
+Output:
+ ["foo", "0"]
+ ["bar", "1"]
+ ["baz", "2"]
+
+==== Parsing from a \File
+
+You can parse \CSV data from a \File, with or without headers.
+
+===== Recipe: Parse from \File with Headers
+
+Use instance method CSV#read with option +headers+ to read a file all at once:
+ string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.write(path, string)
+ CSV.read(path, headers: true) # => #<CSV::Table mode:col_or_row row_count:4>
+
+Use class method CSV.foreach with option +headers+ to read one row at a time:
+ CSV.foreach(path, headers: true) do |row|
+ p row
+ end
+Output:
+ #<CSV::Row "Name":"foo" "Value":"0">
+ #<CSV::Row "Name":"bar" "Value":"1">
+ #<CSV::Row "Name":"baz" "Value":"2">
+
+===== Recipe: Parse from \File Without Headers
+
+Use class method CSV.read without option +headers+ to read a file all at once:
+ string = "foo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.write(path, string)
+ CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Use class method CSV.foreach without option +headers+ to read one row at a time:
+ CSV.foreach(path) do |row|
+ p row
+ end
+Output:
+ ["foo", "0"]
+ ["bar", "1"]
+ ["baz", "2"]
+
+==== Parsing from an \IO Stream
+
+You can parse \CSV data from an \IO stream, with or without headers.
+
+===== Recipe: Parse from \IO Stream with Headers
+
+Use class method CSV.parse with option +headers+ to read an \IO stream all at once:
+ string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.write(path, string)
+ File.open(path) do |file|
+ CSV.parse(file, headers: true)
+ end # => #<CSV::Table mode:col_or_row row_count:4>
+
+Use class method CSV.foreach with option +headers+ to read one row at a time:
+ File.open(path) do |file|
+ CSV.foreach(file, headers: true) do |row|
+ p row
+ end
+ end
+Output:
+ #<CSV::Row "Name":"foo" "Value":"0">
+ #<CSV::Row "Name":"bar" "Value":"1">
+ #<CSV::Row "Name":"baz" "Value":"2">
+
+===== Recipe: Parse from \IO Stream Without Headers
+
+Use class method CSV.parse without option +headers+ to read an \IO stream all at once:
+ string = "foo,0\nbar,1\nbaz,2\n"
+ path = 't.csv'
+ File.write(path, string)
+ File.open(path) do |file|
+ CSV.parse(file)
+ end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+Use class method CSV.foreach without option +headers+ to read one row at a time:
+ File.open(path) do |file|
+ CSV.foreach(file) do |row|
+ p row
+ end
+ end
+Output:
+ ["foo", "0"]
+ ["bar", "1"]
+ ["baz", "2"]
+
+=== RFC 4180 Compliance
+
+By default, \CSV parses data that is compliant with
+{RFC 4180}[https://tools.ietf.org/html/rfc4180]
+with respect to:
+- Row separator.
+- Column separator.
+- Quote character.
+
+==== Row Separator
+
+RFC 4180 specifies the row separator CRLF (Ruby <tt>"\r\n"</tt>).
+
+Although the \CSV default row separator is <tt>"\n"</tt>,
+the parser also by default handles row separator <tt>"\r"</tt> and the RFC-compliant <tt>"\r\n"</tt>.
+
+===== Recipe: Handle Compliant Row Separator
+
+For strict compliance, use option +:row_sep+ to specify row separator <tt>"\r\n"</tt>,
+which allows the compliant row separator:
+ source = "foo,1\r\nbar,1\r\nbaz,2\r\n"
+ CSV.parse(source, row_sep: "\r\n") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]]
+But rejects other row separators:
+ source = "foo,1\nbar,1\nbaz,2\n"
+ CSV.parse(source, row_sep: "\r\n") # Raised MalformedCSVError
+ source = "foo,1\rbar,1\rbaz,2\r"
+ CSV.parse(source, row_sep: "\r\n") # Raised MalformedCSVError
+ source = "foo,1\n\rbar,1\n\rbaz,2\n\r"
+ CSV.parse(source, row_sep: "\r\n") # Raised MalformedCSVError
+
+===== Recipe: Handle Non-Compliant Row Separator
+
+For data with non-compliant row separators, use option +:row_sep+.
+This example source uses semicolon (<tt>";"</tt>) as its row separator:
+ source = "foo,1;bar,1;baz,2;"
+ CSV.parse(source, row_sep: ';') # => [["foo", "1"], ["bar", "1"], ["baz", "2"]]
+
+==== Column Separator
+
+RFC 4180 specifies column separator COMMA (Ruby <tt>","</tt>).
+
+===== Recipe: Handle Compliant Column Separator
+
+Because the \CSV default comma separator is ',',
+you need not specify option +:col_sep+ for compliant data:
+ source = "foo,1\nbar,1\nbaz,2\n"
+ CSV.parse(source) # => [["foo", "1"], ["bar", "1"], ["baz", "2"]]
+
+===== Recipe: Handle Non-Compliant Column Separator
+
+For data with non-compliant column separators, use option +:col_sep+.
+This example source uses TAB (<tt>"\t"</tt>) as its column separator:
+ source = "foo,1\tbar,1\tbaz,2"
+ CSV.parse(source, col_sep: "\t") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]]
+
+==== Quote Character
+
+RFC 4180 specifies quote character DQUOTE (Ruby <tt>"\""</tt>).
+
+===== Recipe: Handle Compliant Quote Character
+
+Because the \CSV default quote character is <tt>"\""</tt>,
+you need not specify option +:quote_char+ for compliant data:
+ source = "\"foo\",\"1\"\n\"bar\",\"1\"\n\"baz\",\"2\"\n"
+ CSV.parse(source) # => [["foo", "1"], ["bar", "1"], ["baz", "2"]]
+
+===== Recipe: Handle Non-Compliant Quote Character
+
+For data with non-compliant quote characters, use option +:quote_char+.
+This example source uses SQUOTE (<tt>"'"</tt>) as its quote character:
+ source = "'foo','1'\n'bar','1'\n'baz','2'\n"
+ CSV.parse(source, quote_char: "'") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]]
+
+==== Recipe: Allow Liberal Parsing
+
+Use option +:liberal_parsing+ to specify that \CSV should
+attempt to parse input not conformant with RFC 4180, such as double quotes in unquoted fields:
+ source = 'is,this "three, or four",fields'
+ CSV.parse(source) # Raises MalformedCSVError
+ CSV.parse(source, liberal_parsing: true) # => [["is", "this \"three", " or four\"", "fields"]]
+
+=== Special Handling
+
+You can use parsing options to specify special handling for certain lines and fields.
+
+==== Special Line Handling
+
+Use parsing options to specify special handling for blank lines, or for other selected lines.
+
+===== Recipe: Ignore Blank Lines
+
+Use option +:skip_blanks+ to ignore blank lines:
+ source = <<-EOT
+ foo,0
+
+ bar,1
+ baz,2
+
+ ,
+ EOT
+ parsed = CSV.parse(source, skip_blanks: true)
+ parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]]
+
+===== Recipe: Ignore Selected Lines
+
+Use option +:skip_lines+ to ignore selected lines.
+ source = <<-EOT
+ # Comment
+ foo,0
+ bar,1
+ baz,2
+ # Another comment
+ EOT
+ parsed = CSV.parse(source, skip_lines: /^#/)
+ parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+
+==== Special Field Handling
+
+Use parsing options to specify special handling for certain field values.
+
+===== Recipe: Strip Fields
+
+Use option +:strip+ to strip parsed field values:
+ CSV.parse_line(' a , b ', strip: true) # => ["a", "b"]
+
+===== Recipe: Handle Null Fields
+
+Use option +:nil_value+ to specify a value that will replace each field
+that is null (no text):
+ CSV.parse_line('a,,b,,c', nil_value: 0) # => ["a", 0, "b", 0, "c"]
+
+===== Recipe: Handle Empty Fields
+
+Use option +:empty_value+ to specify a value that will replace each field
+that is empty (\String of length 0);
+ CSV.parse_line('a,"",b,"",c', empty_value: 'x') # => ["a", "x", "b", "x", "c"]
+
+=== Converting Fields
+
+You can use field converters to change parsed \String fields into other objects,
+or to otherwise modify the \String fields.
+
+==== Converting Fields to Objects
+
+Use field converters to change parsed \String objects into other, more specific, objects.
+
+There are built-in field converters for converting to objects of certain classes:
+- \Float
+- \Integer
+- \Date
+- \DateTime
+
+Other built-in field converters include:
+- +:numeric+: converts to \Integer and \Float.
+- +:all+: converts to \DateTime, \Integer, \Float.
+
+You can also define field converters to convert to objects of other classes.
+
+===== Recipe: Convert Fields to Integers
+
+Convert fields to \Integer objects using built-in converter +:integer+:
+ source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, converters: :integer)
+ parsed.map {|row| row['Value'].class} # => [Integer, Integer, Integer]
+
+===== Recipe: Convert Fields to Floats
+
+Convert fields to \Float objects using built-in converter +:float+:
+ source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, converters: :float)
+ parsed.map {|row| row['Value'].class} # => [Float, Float, Float]
+
+===== Recipe: Convert Fields to Numerics
+
+Convert fields to \Integer and \Float objects using built-in converter +:numeric+:
+ source = "Name,Value\nfoo,0\nbar,1.1\nbaz,2.2\n"
+ parsed = CSV.parse(source, headers: true, converters: :numeric)
+ parsed.map {|row| row['Value'].class} # => [Integer, Float, Float]
+
+===== Recipe: Convert Fields to Dates
+
+Convert fields to \Date objects using built-in converter +:date+:
+ source = "Name,Date\nfoo,2001-02-03\nbar,2001-02-04\nbaz,2001-02-03\n"
+ parsed = CSV.parse(source, headers: true, converters: :date)
+ parsed.map {|row| row['Date'].class} # => [Date, Date, Date]
+
+===== Recipe: Convert Fields to DateTimes
+
+Convert fields to \DateTime objects using built-in converter +:date_time+:
+ source = "Name,DateTime\nfoo,2001-02-03\nbar,2001-02-04\nbaz,2020-05-07T14:59:00-05:00\n"
+ parsed = CSV.parse(source, headers: true, converters: :date_time)
+ parsed.map {|row| row['DateTime'].class} # => [DateTime, DateTime, DateTime]
+
+===== Recipe: Convert Assorted Fields to Objects
+
+Convert assorted fields to objects using built-in converter +:all+:
+ source = "Type,Value\nInteger,0\nFloat,1.0\nDateTime,2001-02-04\n"
+ parsed = CSV.parse(source, headers: true, converters: :all)
+ parsed.map {|row| row['Value'].class} # => [Integer, Float, DateTime]
+
+===== Recipe: Convert Fields to Other Objects
+
+Define a custom field converter to convert \String fields into other objects.
+This example defines and uses a custom field converter
+that converts each column-1 value to a \Rational object:
+ rational_converter = proc do |field, field_context|
+ field_context.index == 1 ? field.to_r : field
+ end
+ source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, converters: rational_converter)
+ parsed.map {|row| row['Value'].class} # => [Rational, Rational, Rational]
+
+==== Recipe: Filter Field Strings
+
+Define a custom field converter to modify \String fields.
+This example defines and uses a custom field converter
+that strips whitespace from each field value:
+ strip_converter = proc {|field| field.strip }
+ source = "Name,Value\n foo , 0 \n bar , 1 \n baz , 2 \n"
+ parsed = CSV.parse(source, headers: true, converters: strip_converter)
+ parsed['Name'] # => ["foo", "bar", "baz"]
+ parsed['Value'] # => ["0", "1", "2"]
+
+==== Recipe: Register Field Converters
+
+Register a custom field converter, assigning it a name;
+then refer to the converter by its name:
+ rational_converter = proc do |field, field_context|
+ field_context.index == 1 ? field.to_r : field
+ end
+ CSV::Converters[:rational] = rational_converter
+ source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, converters: :rational)
+ parsed['Value'] # => [(0/1), (1/1), (2/1)]
+
+==== Using Multiple Field Converters
+
+You can use multiple field converters in either of these ways:
+- Specify converters in option +:converters+.
+- Specify converters in a custom converter list.
+
+===== Recipe: Specify Multiple Field Converters in Option +:converters+
+
+Apply multiple field converters by specifying them in option +:conveters+:
+ source = "Name,Value\nfoo,0\nbar,1.0\nbaz,2.0\n"
+ parsed = CSV.parse(source, headers: true, converters: [:integer, :float])
+ parsed['Value'] # => [0, 1.0, 2.0]
+
+===== Recipe: Specify Multiple Field Converters in a Custom Converter List
+
+Apply multiple field converters by defining and registering a custom converter list:
+ strip_converter = proc {|field| field.strip }
+ CSV::Converters[:strip] = strip_converter
+ CSV::Converters[:my_converters] = [:integer, :float, :strip]
+ source = "Name,Value\n foo , 0 \n bar , 1.0 \n baz , 2.0 \n"
+ parsed = CSV.parse(source, headers: true, converters: :my_converters)
+ parsed['Name'] # => ["foo", "bar", "baz"]
+ parsed['Value'] # => [0, 1.0, 2.0]
+
+=== Converting Headers
+
+You can use header converters to modify parsed \String headers.
+
+Built-in header converters include:
+- +:symbol+: converts \String header to \Symbol.
+- +:downcase+: converts \String header to lowercase.
+
+You can also define header converters to otherwise modify header \Strings.
+
+==== Recipe: Convert Headers to Lowercase
+
+Convert headers to lowercase using built-in converter +:downcase+:
+ source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, header_converters: :downcase)
+ parsed.headers # => ["name", "value"]
+
+==== Recipe: Convert Headers to Symbols
+
+Convert headers to downcased Symbols using built-in converter +:symbol+:
+ source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, header_converters: :symbol)
+ parsed.headers # => [:name, :value]
+ parsed.headers.map {|header| header.class} # => [Symbol, Symbol]
+
+==== Recipe: Filter Header Strings
+
+Define a custom header converter to modify \String fields.
+This example defines and uses a custom header converter
+that capitalizes each header \String:
+ capitalize_converter = proc {|header| header.capitalize }
+ source = "NAME,VALUE\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, header_converters: capitalize_converter)
+ parsed.headers # => ["Name", "Value"]
+
+==== Recipe: Register Header Converters
+
+Register a custom header converter, assigning it a name;
+then refer to the converter by its name:
+ capitalize_converter = proc {|header| header.capitalize }
+ CSV::HeaderConverters[:capitalize] = capitalize_converter
+ source = "NAME,VALUE\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, headers: true, header_converters: :capitalize)
+ parsed.headers # => ["Name", "Value"]
+
+==== Using Multiple Header Converters
+
+You can use multiple header converters in either of these ways:
+- Specify header converters in option +:header_converters+.
+- Specify header converters in a custom header converter list.
+
+===== Recipe: Specify Multiple Header Converters in Option :header_converters
+
+Apply multiple header converters by specifying them in option +:header_conveters+:
+ source = "Name,Value\nfoo,0\nbar,1.0\nbaz,2.0\n"
+ parsed = CSV.parse(source, headers: true, header_converters: [:downcase, :symbol])
+ parsed.headers # => [:name, :value]
+
+===== Recipe: Specify Multiple Header Converters in a Custom Header Converter List
+
+Apply multiple header converters by defining and registering a custom header converter list:
+ CSV::HeaderConverters[:my_header_converters] = [:symbol, :downcase]
+ source = "NAME,VALUE\nfoo,0\nbar,1.0\nbaz,2.0\n"
+ parsed = CSV.parse(source, headers: true, header_converters: :my_header_converters)
+ parsed.headers # => [:name, :value]
+
+=== Diagnostics
+
+==== Recipe: Capture Unconverted Fields
+
+To capture unconverted field values, use option +:unconverted_fields+:
+ source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ parsed = CSV.parse(source, converters: :integer, unconverted_fields: true)
+ parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+ parsed.each {|row| p row.unconverted_fields }
+Output:
+ ["Name", "Value"]
+ ["foo", "0"]
+ ["bar", "1"]
+ ["baz", "2"]
+
+==== Recipe: Capture Field Info
+
+To capture field info in a custom converter, accept two block arguments.
+The first is the field value; the second is a +CSV::FieldInfo+ object:
+ strip_converter = proc {|field, field_info| p field_info; field.strip }
+ source = " foo , 0 \n bar , 1 \n baz , 2 \n"
+ parsed = CSV.parse(source, converters: strip_converter)
+ parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+Output:
+ #<struct CSV::FieldInfo index=0, line=1, header=nil>
+ #<struct CSV::FieldInfo index=1, line=1, header=nil>
+ #<struct CSV::FieldInfo index=0, line=2, header=nil>
+ #<struct CSV::FieldInfo index=1, line=2, header=nil>
+ #<struct CSV::FieldInfo index=0, line=3, header=nil>
+ #<struct CSV::FieldInfo index=1, line=3, header=nil>
diff --git a/doc/csv/recipes/recipes.rdoc b/doc/csv/recipes/recipes.rdoc
new file mode 100644
index 0000000000..9e4eaa1da4
--- /dev/null
+++ b/doc/csv/recipes/recipes.rdoc
@@ -0,0 +1,6 @@
+== Recipes for \CSV
+
+See:
+- {Recipes for Parsing CSV}[./parsing_rdoc.html]
+- {Recipes for Generating CSV}[./generating_rdoc.html]
+- {Recipes for Filtering CSV}[./filtering_rdoc.html]
diff --git a/doc/dig_methods.rdoc b/doc/dig_methods.rdoc
new file mode 100644
index 0000000000..366275d451
--- /dev/null
+++ b/doc/dig_methods.rdoc
@@ -0,0 +1,82 @@
+= Dig Methods
+
+Ruby's +dig+ methods are useful for accessing nested data structures.
+
+Consider this data:
+ item = {
+ id: "0001",
+ type: "donut",
+ name: "Cake",
+ ppu: 0.55,
+ batters: {
+ batter: [
+ {id: "1001", type: "Regular"},
+ {id: "1002", type: "Chocolate"},
+ {id: "1003", type: "Blueberry"},
+ {id: "1004", type: "Devil's Food"}
+ ]
+ },
+ topping: [
+ {id: "5001", type: "None"},
+ {id: "5002", type: "Glazed"},
+ {id: "5005", type: "Sugar"},
+ {id: "5007", type: "Powdered Sugar"},
+ {id: "5006", type: "Chocolate with Sprinkles"},
+ {id: "5003", type: "Chocolate"},
+ {id: "5004", type: "Maple"}
+ ]
+ }
+
+Without a +dig+ method, you can write:
+ item[:batters][:batter][1][:type] # => "Chocolate"
+
+With a +dig+ method, you can write:
+ item.dig(:batters, :batter, 1, :type) # => "Chocolate"
+
+Without a +dig+ method, you can write, erroneously
+(raises <tt>NoMethodError (undefined method `[]' for nil:NilClass)</tt>):
+ item[:batters][:BATTER][1][:type]
+
+With a +dig+ method, you can write (still erroneously, but avoiding the exception):
+ item.dig(:batters, :BATTER, 1, :type) # => nil
+
+== Why Is +dig+ Better?
+
+- It has fewer syntactical elements (to get wrong).
+- It reads better.
+- It does not raise an exception if an item is not found.
+
+== How Does +dig+ Work?
+
+The call sequence is:
+ obj.dig(*identifiers)
+
+The +identifiers+ define a "path" into the nested data structures:
+- For each identifier in +identifiers+, calls method \#dig on a receiver
+ with that identifier.
+- The first receiver is +self+.
+- Each successive receiver is the value returned by the previous call to +dig+.
+- The value finally returned is the value returned by the last call to +dig+.
+
+A +dig+ method raises an exception if any receiver does not respond to \#dig:
+ h = { foo: 1 }
+ # Raises TypeError (Integer does not have #dig method):
+ h.dig(:foo, :bar)
+
+== What Else?
+
+The structure above has \Hash objects and \Array objects,
+both of which have instance method +dig+.
+
+Altogether there are six built-in Ruby classes that have method +dig+,
+three in the core classes and three in the standard library.
+
+In the core:
+- Array#dig: the first argument is an \Integer index.
+- Hash#dig: the first argument is a key.
+- Struct#dig: the first argument is a key.
+
+In the standard library:
+- OpenStruct#dig: the first argument is a \String name.
+- CSV::Table#dig: the first argument is an \Integer index or a \String header.
+- CSV::Row#dig: the first argument is an \Integer index or a \String header.
diff --git a/doc/dtrace_probes.rdoc b/doc/dtrace_probes.rdoc
index d2cdd56902..1b20597ab4 100644
--- a/doc/dtrace_probes.rdoc
+++ b/doc/dtrace_probes.rdoc
@@ -52,15 +52,21 @@ with when they are fired and the arguments they take:
[ruby:::method-entry(classname, methodname, filename, lineno);]
This probe is fired just before a method is entered.
- classname name of the class (a string)
- methodname name of the method about to be executed (a string)
- filename the file name where the method is _being called_ (a string)
- lineno the line number where the method is _being called_ (an int)
+ classname:: name of the class (a string)
+ methodname:: name of the method about to be executed (a string)
+ filename:: the file name where the method is _being called_ (a string)
+ lineno:: the line number where the method is _being called_ (an int)
+
+ *NOTE*: will only be fired if tracing is enabled, e.g. with: <code>TracePoint.new{}.enable</code>.
+ See Feature#14104[https://bugs.ruby-lang.org/issues/14104] for more details.
[ruby:::method-return(classname, methodname, filename, lineno);]
This probe is fired just after a method has returned. The arguments are the
same as "ruby:::method-entry".
+ *NOTE*: will only be fired if tracing is enabled, e.g. with: <code>TracePoint.new{}.enable</code>.
+ See Feature#14104[https://bugs.ruby-lang.org/issues/14104] for more details.
+
[ruby:::cmethod-entry(classname, methodname, filename, lineno);]
This probe is fired just before a C method is entered. The arguments are the
same as "ruby:::method-entry".
@@ -72,9 +78,9 @@ with when they are fired and the arguments they take:
[ruby:::require-entry(requiredfile, filename, lineno);]
This probe is fired on calls to rb_require_safe (when a file is required).
- requiredfile is the name of the file to be required (string).
- filename is the file that called "require" (string).
- lineno is the line number where the call to require was made (int).
+ requiredfile:: the name of the file to be required (string).
+ filename:: the file that called "+require+" (string).
+ lineno:: the line number where the call to require was made (int).
[ruby:::require-return(requiredfile, filename, lineno);]
This probe is fired just before rb_require_safe (when a file is required)
@@ -84,11 +90,11 @@ with when they are fired and the arguments they take:
[ruby:::find-require-entry(requiredfile, filename, lineno);]
This probe is fired right before search_required is called. search_required
determines whether the file has already been required by searching loaded
- features ($"), and if not, figures out which file must be loaded.
+ features (<code>$"</code>), and if not, figures out which file must be loaded.
- requiredfile is the file to be required (string).
- filename is the file that called "require" (string).
- lineno is the line number where the call to require was made (int).
+ requiredfile:: the file to be required (string).
+ filename:: the file that called "require" (string).
+ lineno:: the line number where the call to require was made (int).
[ruby:::find-require-return(requiredfile, filename, lineno);]
This probe is fired right after search_required returns. See the
@@ -106,56 +112,56 @@ with when they are fired and the arguments they take:
[ruby:::raise(classname, filename, lineno);]
This probe is fired when an exception is raised.
- classname is the class name of the raised exception (string)
- filename the name of the file where the exception was raised (string)
- lineno the line number in the file where the exception was raised (int)
+ classname:: the class name of the raised exception (string)
+ filename:: the name of the file where the exception was raised (string)
+ lineno:: the line number in the file where the exception was raised (int)
[ruby:::object-create(classname, filename, lineno);]
This probe is fired when an object is about to be allocated.
- classname the class of the allocated object (string)
- filename the name of the file where the object is allocated (string)
- lineno the line number in the file where the object is allocated (int)
+ classname:: the class of the allocated object (string)
+ filename:: the name of the file where the object is allocated (string)
+ lineno:: the line number in the file where the object is allocated (int)
[ruby:::array-create(length, filename, lineno);]
This probe is fired when an Array is about to be allocated.
- length the size of the array (long)
- filename the name of the file where the array is allocated (string)
- lineno the line number in the file where the array is allocated (int)
+ length:: the size of the array (long)
+ filename:: the name of the file where the array is allocated (string)
+ lineno:: the line number in the file where the array is allocated (int)
[ruby:::hash-create(length, filename, lineno);]
This probe is fired when a Hash is about to be allocated.
- length the size of the hash (long)
- filename the name of the file where the hash is allocated (string)
- lineno the line number in the file where the hash is allocated (int)
+ length:: the size of the hash (long)
+ filename:: the name of the file where the hash is allocated (string)
+ lineno:: the line number in the file where the hash is allocated (int)
[ruby:::string-create(length, filename, lineno);]
This probe is fired when a String is about to be allocated.
- length the size of the string (long)
- filename the name of the file where the string is allocated (string)
- lineno the line number in the file where the string is allocated (int)
+ length:: the size of the string (long)
+ filename:: the name of the file where the string is allocated (string)
+ lineno:: the line number in the file where the string is allocated (int)
[ruby:::symbol-create(str, filename, lineno);]
This probe is fired when a Symbol is about to be allocated.
- str the contents of the symbol (string)
- filename the name of the file where the string is allocated (string)
- lineno the line number in the file where the string is allocated (int)
+ str:: the contents of the symbol (string)
+ filename:: the name of the file where the string is allocated (string)
+ lineno:: the line number in the file where the string is allocated (int)
[ruby:::parse-begin(sourcefile, lineno);]
Fired just before parsing and compiling a source file.
- sourcefile the file being parsed (string)
- lineno the line number where the source starts (int)
+ sourcefile:: the file being parsed (string)
+ lineno:: the line number where the source starts (int)
[ruby:::parse-end(sourcefile, lineno);]
Fired just after parsing and compiling a source file.
- sourcefile the file being parsed (string)
- lineno the line number where the source ended (int)
+ sourcefile:: the file being parsed (string)
+ lineno:: the line number where the source ended (int)
[ruby:::gc-mark-begin();]
Fired at the beginning of a mark phase.
@@ -172,7 +178,7 @@ with when they are fired and the arguments they take:
[ruby:::method-cache-clear(class, sourcefile, lineno);]
Fired when the method cache is cleared.
- class is the classname being cleared, or "global" (string)
- sourcefile the file being parsed (string)
- lineno the line number where the source ended (int)
+ class:: the classname being cleared, or "global" (string)
+ sourcefile:: the file being parsed (string)
+ lineno:: the line number where the source ended (int)
diff --git a/doc/etc.rd.ja b/doc/etc.rd.ja
deleted file mode 100644
index b4ff6ed04e..0000000000
--- a/doc/etc.rd.ja
+++ /dev/null
@@ -1,75 +0,0 @@
-# etc.rd.ja - -*- mode: rd; coding: utf-8; -*- created at: Fri Jul 14 00:47:15 JST 1995
-=begin
-
-= Etc(モジュール)
-
-実行ã—ã¦ã„ã‚‹OSã‹ã‚‰ã®æƒ…報を得るãŸã‚ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ï¼Žã‚¯ãƒ©ã‚¹ã«ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰
-ã—ã¦ä½¿ã†ã“ã¨ã‚‚ã§ãる.
-
-== Module Function
-
---- getlogin
-
- 自分ã®loginåã‚’è¿”ã™ï¼Žã“れãŒå¤±æ•—ã—ãŸå ´åˆã¯getpwuid()を用ã„ã‚‹ã¨
- 良ã„.
-
---- getpwnam(name)
-
- /etc/passwdファイル(ã‚ã‚‹ã„ã¯DBMファイルやNISデータベース)を検
- ç´¢ã—,nameã®åå‰ã‚’æŒã¤passwdエントリを返ã™ï¼Žæˆ»ã‚Šå€¤ã¯passwd構造
- 体ã§ä»¥ä¸‹ã®ãƒ¡ãƒ³ãƒã‚’æŒã¤ï¼Ž
-
- struct passwd
- name # ユーザå(文字列)
- passwd # パスワード(文字列)
- uid # ユーザID(整数)
- gid # グループID(整数)
- gecos # gecosフィールド(文字列)
- dir # ホームディレクトリ(文字列)
- shell # ログインシェル(文字列)
- # 以é™ã®ãƒ¡ãƒ³ãƒã¯ã‚·ã‚¹ãƒ†ãƒ ã«ã‚ˆã£ã¦ã¯æä¾›ã•れãªã„.
- change # パスワード変更時間(整数)
- quota # クォータ(整数)
- age # エージ(整数)
- class # ユーザアクセスクラス(文字列)
- comment # コメント(文字列)
- expire # アカウント有効期é™(æ•´æ•°)
- end
-
- 詳細ã¯getpwnam(3)ã‚’å‚ç…§ã®ã“ã¨ï¼Ž
-
---- getpwuid([uid])
-
- uidをユーザIDã¨ã™ã‚‹passwdエントリを返ã™ï¼Žæˆ»ã‚Šå€¤ã¯getpwnam()ã¨
- åŒæ§˜ã§ã‚る.引数をçœç•¥ã—ãŸå ´åˆã«ã¯getuid()ã®å€¤ã‚’用ã„る.詳細ã¯
- getpwuid(3)ã‚’å‚ç…§ã®ã“ã¨ï¼Ž
-
---- getgrgid(gid)
-
- /etc/groupファイル(ã‚ã‚‹ã„ã¯â€¦getpwnamå‚ç…§)を検索ã—,gidをグルー
- プIDã¨ã™ã‚‹ã‚°ãƒ«ãƒ¼ãƒ—エントリを返ã™ï¼Žæˆ»ã‚Šå€¤ã¯group構造体ã§ä»¥ä¸‹ã®
- メンãƒã‚’æŒã¤ï¼Ž
-
- struct group
- name # グループå(文字列)
- passwd # グループã®ãƒ‘スワード(文字列)
- gid # グループID(整数)
- mem # グループメンãƒåã®é…列
- end
-
- 詳細ã¯getgrgid(3)ã‚’å‚ç…§ã®ã“ã¨ï¼Ž
-
---- getgrnam(name)
-
- nameã¨ã„ã†åå‰ã®ã‚°ãƒ«ãƒ¼ãƒ—エントリを返ã™ï¼Žæˆ»ã‚Šå€¤ã¯getgrgid()ã¨åŒ
- 様ã§ã‚る.詳細ã¯getgrnam(3)ã‚’å‚照.
-
---- group
-
- å…¨ã¦ã®ã‚°ãƒ«ãƒ¼ãƒ—エントリを順ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã®ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ï¼Ž
-
---- passwd
-
- å…¨ã¦ã®passwdエントリを順ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã®ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ï¼Ž
-
-=end
diff --git a/doc/extension.ja.rdoc b/doc/extension.ja.rdoc
index 88f300a562..fe483e50d3 100644
--- a/doc/extension.ja.rdoc
+++ b/doc/extension.ja.rdoc
@@ -215,17 +215,6 @@ rb_str_new_literal(const char *ptr) ::
Cã®ãƒªãƒ†ãƒ©ãƒ«æ–‡å­—列ã‹ã‚‰Rubyã®æ–‡å­—列を生æˆã™ã‚‹ï¼Ž
-rb_tainted_str_new(const char *ptr, long len) ::
-
- 汚染マークãŒä»˜åŠ ã•ã‚ŒãŸæ–°ã—ã„Rubyã®æ–‡å­—列を生æˆã™ã‚‹ï¼Žå¤–部
- ã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿ã«åŸºã¥ã文字列ã«ã¯æ±šæŸ“マークãŒä»˜åŠ ã•れるã¹ã
- ã§ã‚る.
-
-rb_tainted_str_new2(const char *ptr) ::
-rb_tainted_str_new_cstr(const char *ptr) ::
-
- Cã®æ–‡å­—列ã‹ã‚‰æ±šæŸ“マークãŒä»˜åŠ ã•れãŸRubyã®æ–‡å­—列を生æˆã™ã‚‹ï¼Ž
-
rb_str_append(VALUE str1, VALUE str2) ::
Rubyã®æ–‡å­—列str1ã«Rubyã®æ–‡å­—列str2を追加ã™ã‚‹ï¼Ž
@@ -301,6 +290,14 @@ rb_str_set_len(VALUE str, long len) ::
lenãƒã‚¤ãƒˆã¾ã§ã®å†…容ã¯ä¿å­˜ã•れる.lenã¯strã®å®¹é‡ã‚’è¶Šãˆã¦ã„
ã¦ã¯ãªã‚‰ãªã„.
+rb_str_modify(VALUE str) ::
+
+ Rubyã®æ–‡å­—列ã®å¤‰æ›´ã™ã‚‹æº–備をã™ã‚‹ï¼ŽstrãŒå¤‰æ›´å¯èƒ½ã§ãªã‘れã°ä¾‹
+ 外ãŒç™ºç”Ÿã™ã‚‹ï¼Žstrã®ãƒãƒƒãƒ•ã‚¡ãŒå…±æœ‰ã•れã¦ã„ã‚‹å ´åˆã¯ï¼Œæ–°ã—ã„ãƒãƒƒ
+ ファを割り当ã¦ã¦å…±æœ‰ã•れã¦ã„ãªã„状態ã«ã™ã‚‹ï¼ŽRSTRING_PTRを使ã£
+ ã¦ä¸­èº«ã‚’変更ã—ãŸã‚Šï¼Œrb_str_set_lenを呼んã ã‚Šã™ã‚‹å‰ã«ã¯ï¼Œ
+ å¿…ãšã“ã®é–¢æ•°ã‚’呼ã°ãªã‘れãªã‚‰ãªã„.
+
==== é…列ã«å¯¾ã™ã‚‹é–¢æ•°
rb_ary_new() ::
@@ -1243,7 +1240,6 @@ Data_Get_Struct(data, type, sval) ::
RB_INTEGER_TYPE_P(value)
RB_FLOAT_TYPE_P(value)
void Check_Type(VALUE value, int type)
- SafeStringValue(value)
=== 型変æ›
@@ -1325,8 +1321,13 @@ void rb_define_hooked_variable(const char *name, VALUE *var, VALUE (*getter)(),
void rb_global_variable(VALUE *var) ::
- GCã®ãŸã‚,Rubyプログラムã‹ã‚‰ã¯ã‚¢ã‚¯ã‚»ã‚¹ã•れãªã„ãŒ, Rubyオブ
- ジェクトをå«ã‚€å¤§åŸŸå¤‰æ•°ã‚’マークã™ã‚‹ï¼Ž
+ マークã™ã‚‹å¿…è¦ã®ã‚ã‚‹Rubyオブジェクトをå«ã‚€å¤§åŸŸå¤‰æ•°ã‚’,GC
+ ã«ã‚ˆã£ã¦è§£æ”¾ã•れãªã„よã†ã«ä¿è­·ã™ã‚‹ï¼Ž
+
+void rb_gc_register_mark_object(VALUE object) ::
+
+ マークã™ã‚‹å¿…è¦ã®ã‚ã‚‹Rubyオブジェクトを,GCã«ã‚ˆã£ã¦è§£æ”¾ã•
+ れãªã„よã†ã«ç™»éŒ²ã™ã‚‹ï¼Ž
=== 定数
@@ -1828,6 +1829,17 @@ rb_ary_store() ãªã©ã®ï¼Œé©åˆ‡ãª API 関数を利用ã™ã‚‹ã‚ˆã†ã«ã—ã¦ä¸‹
ãã®ã»ã‹ï¼Œå¯¾å¿œã«ã¤ã„ã¦ã®è©³ç´°ã¯ extension.rdoc ã®ã€ŒAppendix D. Generational
GCã€ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„.
+== Appendix E. Ractor サãƒãƒ¼ãƒˆ
+
+Ruby 3.0 ã‹ã‚‰ã€Ruby プログラムを並列ã«å®Ÿè¡Œã™ã‚‹ãŸã‚ã®ä»•組ã¿ã§ã‚ã‚‹ Ractor
+ãŒå°Žå…¥ã•れã¾ã—ãŸã€‚é©åˆ‡ã«ä¸¦åˆ—ã«å®Ÿè¡Œã™ã‚‹ãŸã‚ã«ã¯ã€Ractor サãƒãƒ¼ãƒˆãŒå¿…è¦ã«
+ãªã‚Šã¾ã™ã€‚サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„ライブラリã¯ã€ãƒ¡ã‚¤ãƒ³ Ractor 以外ã§å®Ÿè¡Œã™ã‚‹ã¨
+エラーã«ãªã‚Šã¾ã™ï¼ˆRactor::UnsafeError)。
+
+Ractor をサãƒãƒ¼ãƒˆã™ã‚‹ãŸã‚ã®è©³ç´°ã¯ã€extension.rdoc ã®ã€ŒAppendix F. Ractor
+supportã€ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+
+
:enddoc: Local variables:
:enddoc: fill-column: 60
:enddoc: end:
diff --git a/doc/extension.rdoc b/doc/extension.rdoc
index 271ed67f9c..71a03cbf52 100644
--- a/doc/extension.rdoc
+++ b/doc/extension.rdoc
@@ -190,16 +190,6 @@ rb_str_new_literal(const char *ptr) ::
Creates a new Ruby string from a C string literal.
-rb_tainted_str_new(const char *ptr, long len) ::
-
- Creates a new tainted Ruby string. Strings from external data
- sources should be tainted.
-
-rb_tainted_str_new2(const char *ptr) ::
-rb_tainted_str_new_cstr(const char *ptr) ::
-
- Creates a new tainted Ruby string from a C string.
-
rb_sprintf(const char *format, ...) ::
rb_vsprintf(const char *format, va_list ap) ::
@@ -279,6 +269,14 @@ rb_str_set_len(VALUE str, long len) ::
up to len bytes, regardless RSTRING_LEN(str). len must not exceed
the capacity of str.
+rb_str_modify(VALUE str) ::
+
+ Prepares a Ruby string to modify. If str is not modifiable, this
+ function raises an exception, or if the buffer of str is shared,
+ this function allocates new buffer to make it unshared. Always
+ you MUST call this function before modifying the contents using
+ RSTRING_PTR and/or rb_str_set_len.
+
==== Array Functions
rb_ary_new() ::
@@ -450,6 +448,18 @@ you may rely on:
VALUE rb_call_super(int argc, const VALUE *argv)
+To specify whether keyword arguments are passed when calling super:
+
+ VALUE rb_call_super(int argc, const VALUE *argv, int kw_splat)
+
++kw_splat+ can have these possible values (used by all methods that accept
++kw_splat+ argument):
+
+RB_NO_KEYWORDS :: Do not pass keywords
+RB_PASS_KEYWORDS :: Pass keywords, final argument should be a hash of keywords
+RB_PASS_CALLED_KEYWORDS :: Pass keywords if current method was called with
+ keywords, useful for argument delegation
+
To achieve the receiver of the current scope (if no other way is
available), you can use:
@@ -666,7 +676,8 @@ member of the struct.
void (*dmark)(void*);
void (*dfree)(void*);
size_t (*dsize)(const void *);
- void *reserved[2];
+ void (*dcompact)(void*);
+ void *reserved[1];
} function;
const rb_data_type_t *parent;
void *data;
@@ -698,7 +709,15 @@ Its parameter is a pointer to your struct.
You can pass 0 as dsize if it is hard to implement such a function.
But it is still recommended to avoid 0.
-You have to fill reserved and parent with 0.
+dcompact is invoked when memory compaction took place.
+Referred Ruby objects that were marked by rb_gc_mark_movable()
+can here be updated per rb_gc_location().
+
+You have to fill reserved with 0.
+
+parent can point to another C type definition that the Ruby object
+is inherited from. Then TypedData_Get_Struct() does also accept
+derived objects.
You can fill "data" with an arbitrary value for your use.
Ruby does nothing with the member.
@@ -714,7 +733,7 @@ RUBY_TYPED_FREE_IMMEDIATELY ::
You can specify this flag if the dfree never unlocks Ruby's
internal lock (GVL).
- If this flag is not set, Ruby defers invokation of dfree()
+ If this flag is not set, Ruby defers invocation of dfree()
and invokes dfree() at the same time as finalizers.
RUBY_TYPED_WB_PROTECTED ::
@@ -730,6 +749,14 @@ RUBY_TYPED_WB_PROTECTED ::
More about write barriers can be found in "Generational GC" in
Appendix D.
+RUBY_TYPED_FROZEN_SHAREABLE ::
+
+ This flag indicates that the object is shareable object
+ if the object is frozen. See Appendix F more details.
+
+ If this flag is not set, the object can not become a shareable
+ object by Ractor.make_shareable() method.
+
You can allocate and wrap the structure in one step.
TypedData_Make_Struct(klass, type, data_type, sval)
@@ -746,7 +773,7 @@ be assigned to sval, which should be a pointer of the type specified.
==== Ruby object to C struct
To retrieve the C pointer from the Data object, use the macro
-Data_Get_Struct().
+TypedData_Get_Struct().
TypedData_Get_Struct(obj, type, &data_type, sval)
@@ -895,6 +922,10 @@ but are not exported to the Ruby world. You need to protect them by
void rb_global_variable(VALUE *var)
+or the objects themselves by
+
+ void rb_gc_register_mark_object(VALUE object)
+
=== Prepare extconf.rb
If the file named extconf.rb exists, it will be executed to generate
@@ -1184,10 +1215,6 @@ void Check_Type(VALUE value, int type) ::
Ensures +value+ is of the given internal +type+ or raises a TypeError
-SafeStringValue(value) ::
-
- Checks that +value+ is a String and is not tainted
-
=== Data Type Conversion
FIX2INT(value), INT2FIX(i) ::
@@ -1337,8 +1364,11 @@ void rb_define_hooked_variable(const char *name, VALUE *var, VALUE (*getter)(),
void rb_global_variable(VALUE *var) ::
- GC requires C global variables which hold Ruby values to be marked.
- rb_global_variable tells GC to protect these variables.
+ Tells GC to protect C global variable, which holds Ruby value to be marked.
+
+void rb_gc_register_mark_object(VALUE object) ::
+
+ Tells GC to protect the +object+, which may not be referenced anywhere.
=== Constant Definition
@@ -1383,7 +1413,7 @@ rb_scan_args(int argc, VALUE *argv, const char *fmt, ...) ::
according to the format string. The format can be described in ABNF
as follows:
- scan-arg-spec := param-arg-spec [option-hash-arg-spec] [block-arg-spec]
+ scan-arg-spec := param-arg-spec [keyword-arg-spec] [block-arg-spec]
param-arg-spec := pre-arg-spec [post-arg-spec] / post-arg-spec /
pre-opt-post-arg-spec
@@ -1392,7 +1422,7 @@ rb_scan_args(int argc, VALUE *argv, const char *fmt, ...) ::
[num-of-trailing-mandatory-args]
pre-opt-post-arg-spec := num-of-leading-mandatory-args num-of-optional-args
num-of-trailing-mandatory-args
- option-hash-arg-spec := sym-for-option-hash-arg
+ keyword-arg-spec := sym-for-keyword-arg
block-arg-spec := sym-for-block-arg
num-of-leading-mandatory-args := DIGIT ; The number of leading
@@ -1404,18 +1434,10 @@ rb_scan_args(int argc, VALUE *argv, const char *fmt, ...) ::
; captured as a ruby array
num-of-trailing-mandatory-args := DIGIT ; The number of trailing
; mandatory arguments
- sym-for-option-hash-arg := ":" ; Indicates that an option
- ; hash is captured if the last
- ; argument is a hash or can be
- ; converted to a hash with
- ; #to_hash. When the last
- ; argument is nil, it is
- ; captured if it is not
- ; ambiguous to take it as
- ; empty option hash; i.e. '*'
- ; is not specified and
- ; arguments are given more
- ; than sufficient.
+ sym-for-keyword-arg := ":" ; Indicates that keyword
+ ; argument captured as a hash.
+ ; If keyword arguments are not
+ ; provided, returns nil.
sym-for-block-arg := "&" ; Indicates that an iterator
; block should be captured if
; given
@@ -1430,6 +1452,19 @@ rb_scan_args(int argc, VALUE *argv, const char *fmt, ...) ::
The number of given arguments, excluding an option hash or iterator
block, is returned.
+rb_scan_args_kw(int kw_splat, int argc, VALUE *argv, const char *fmt, ...) ::
+
+ The same as +rb_scan_args+, except the +kw_splat+ argument specifies whether
+ keyword arguments are provided (instead of being determined by the call
+ from Ruby to the C function). +kw_splat+ should be one of the following
+ values:
+
+ RB_SCAN_ARGS_PASS_CALLED_KEYWORDS :: Same behavior as +rb_scan_args+.
+ RB_SCAN_ARGS_KEYWORDS :: The final argument should be a hash treated as
+ keywords.
+ RB_SCAN_ARGS_LAST_HASH_KEYWORDS :: Treat a final argument as keywords if it
+ is a hash, and not as keywords otherwise.
+
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values) ::
Retrieves argument VALUEs bound to keywords, which directed by +table+
@@ -1468,11 +1503,41 @@ VALUE rb_funcallv(VALUE recv, ID mid, int argc, VALUE *argv) ::
Invokes a method, passing arguments as an array of values.
Able to call even private/protected methods.
+VALUE rb_funcallv_kw(VALUE recv, ID mid, int argc, VALUE *argv, int kw_splat) ::
+
+ Same as rb_funcallv, using +kw_splat+ to determine whether keyword
+ arguments are passed.
+
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, VALUE *argv) ::
Invokes a method, passing arguments as an array of values.
Able to call only public methods.
+VALUE rb_funcallv_public_kw(VALUE recv, ID mid, int argc, VALUE *argv, int kw_splat) ::
+
+ Same as rb_funcallv_public, using +kw_splat+ to determine whether keyword
+ arguments are passed.
+
+VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE* argv) ::
+
+ Same as rb_funcallv_public, except is passes the currently active block as
+ the block when calling the method.
+
+VALUE rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE* argv, int kw_splat) ::
+
+ Same as rb_funcall_passing_block, using +kw_splat+ to determine whether
+ keyword arguments are passed.
+
+VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval) ::
+
+ Same as rb_funcallv_public, except +passed_procval+ specifies the block to
+ pass to the method.
+
+VALUE rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat) ::
+
+ Same as rb_funcall_with_block, using +kw_splat+ to determine whether
+ keyword arguments are passed.
+
VALUE rb_eval_string(const char *str) ::
Compiles and executes the string as a Ruby program.
@@ -1517,6 +1582,11 @@ VALUE rb_block_call(VALUE recv, ID mid, int argc, VALUE * argv, VALUE (*func) (A
whereas yielded values can be gotten via argc/argv of the third/fourth
arguments.
+VALUE rb_block_call_kw(VALUE recv, ID mid, int argc, VALUE * argv, VALUE (*func) (ANYARGS), VALUE data2, int kw_splat) ::
+
+ Same as rb_funcall_with_block, using +kw_splat+ to determine whether
+ keyword arguments are passed.
+
\[OBSOLETE] VALUE rb_iterate(VALUE (*func1)(), VALUE arg1, VALUE (*func2)(), VALUE arg2) ::
Calls the function func1, supplying func2 as the block. func1 will be
@@ -1528,7 +1598,32 @@ VALUE rb_block_call(VALUE recv, ID mid, int argc, VALUE * argv, VALUE (*func) (A
VALUE rb_yield(VALUE val) ::
- Evaluates the block with value val.
+ Yields val as a single argument to the block.
+
+VALUE rb_yield_values(int n, ...) ::
+
+ Yields +n+ number of arguments to the block, using one C argument per Ruby
+ argument.
+
+VALUE rb_yield_values2(int n, VALUE *argv) ::
+
+ Yields +n+ number of arguments to the block, with all Ruby arguments in the
+ C argv array.
+
+VALUE rb_yield_values_kw(int n, VALUE *argv, int kw_splat) ::
+
+ Same as rb_yield_values2, using +kw_splat+ to determine whether
+ keyword arguments are passed.
+
+VALUE rb_yield_splat(VALUE args) ::
+
+ Same as rb_yield_values2, except arguments are specified by the Ruby
+ array +args+.
+
+VALUE rb_yield_splat_kw(VALUE args, int kw_splat) ::
+
+ Same as rb_yield_splat, using +kw_splat+ to determine whether
+ keyword arguments are passed.
VALUE rb_rescue(VALUE (*func1)(ANYARGS), VALUE arg1, VALUE (*func2)(ANYARGS), VALUE arg2) ::
@@ -1802,6 +1897,49 @@ RB_EVENT_HOOKS_HAVE_CALLBACK_DATA ::
Means that rb_add_event_hook() takes the third argument `data', to be
passed to the given event hook function.
+=== Defining backward compatible macros for keyword argument functions
+
+Most ruby C extensions are designed to support multiple Ruby versions.
+In order to correctly support Ruby 2.7+ in regards to keyword
+argument separation, C extensions need to use <code>*_kw</code>
+functions. However, these functions do not exist in Ruby 2.6 and
+below, so in those cases macros should be defined to allow you to use
+the same code on multiple Ruby versions. Here are example macros
+you can use in extensions that support Ruby 2.6 (or below) when using
+the <code>*_kw</code> functions introduced in Ruby 2.7.
+
+ #ifndef RB_PASS_KEYWORDS
+ /* Only define macros on Ruby <2.7 */
+ #define rb_funcallv_kw(o, m, c, v, kw) rb_funcallv(o, m, c, v)
+ #define rb_funcallv_public_kw(o, m, c, v, kw) rb_funcallv_public(o, m, c, v)
+ #define rb_funcall_passing_block_kw(o, m, c, v, kw) rb_funcall_passing_block(o, m, c, v)
+ #define rb_funcall_with_block_kw(o, m, c, v, b, kw) rb_funcall_with_block(o, m, c, v, b)
+ #define rb_scan_args_kw(kw, c, v, s, ...) rb_scan_args(c, v, s, __VA_ARGS__)
+ #define rb_call_super_kw(c, v, kw) rb_call_super(c, v)
+ #define rb_yield_values_kw(c, v, kw) rb_yield_values2(c, v)
+ #define rb_yield_splat_kw(a, kw) rb_yield_splat(a)
+ #define rb_block_call_kw(o, m, c, v, f, p, kw) rb_block_call(o, m, c, v, f, p)
+ #define rb_fiber_resume_kw(o, c, v, kw) rb_fiber_resume(o, c, v)
+ #define rb_fiber_yield_kw(c, v, kw) rb_fiber_yield(c, v)
+ #define rb_enumeratorize_with_size_kw(o, m, c, v, f, kw) rb_enumeratorize_with_size(o, m, c, v, f)
+ #define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \
+ rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \
+ (argc), (argv), (size_fn))
+ #define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) do { \
+ if (!rb_block_given_p()) \
+ return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \
+ } while (0)
+ #define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0)
+ #define rb_check_funcall_kw(o, m, c, v, kw) rb_check_funcall(o, m, c, v)
+ #define rb_obj_call_init_kw(o, c, v, kw) rb_obj_call_init(o, c, v)
+ #define rb_class_new_instance_kw(c, v, k, kw) rb_class_new_instance(c, v, k)
+ #define rb_proc_call_kw(p, a, kw) rb_proc_call(p, a)
+ #define rb_proc_call_with_block_kw(p, c, v, b, kw) rb_proc_call_with_block(p, c, v, b)
+ #define rb_method_call_kw(c, v, m, kw) rb_method_call(c, v, m)
+ #define rb_method_call_with_block_kw(c, v, m, b, kw) rb_method_call_with_block(c, v, m, b)
+ #define rb_eval_cmd_kwd(c, a, kw) rb_eval_cmd(c, a, 0)
+ #endif
+
== Appendix C. Functions available for use in extconf.rb
See documentation for {mkmf}[rdoc-ref:MakeMakefile].
@@ -1903,7 +2041,7 @@ Before inserting write barriers, you need to know about RGenGC algorithm
available in include/ruby/ruby.h. An example is available in iseq.c.
For a complete guide for RGenGC and write barriers, please refer to
-<https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/RGenGC>.
+<https://bugs.ruby-lang.org/projects/ruby-master/wiki/RGenGC>.
== Appendix E. RB_GC_GUARD to protect from premature GC
@@ -1954,6 +2092,89 @@ keyword in C. RB_GC_GUARD has the following advantages:
compilers and architectures. RB_GC_GUARD is customizable for broken
systems/compilers without negatively affecting other systems.
+== Appendix F. Ractor support
+
+Ractor is parallel execution mechanism introduced from Ruby 3.0. All
+ractrors can run in parallel by different OS thread (underlying system
+provided thread), so the C extension should be thread-safe. Now we call
+the property that C extension can run in multiple ractors "Ractor-safe".
+
+By default, all C extensions are recognized as Ractor-unsafe. If C
+extension becomes Ractor-safe, the extension should call
+rb_ext_ractor_safe(true) at the Init_ function and all defined method
+marked as Ractor-safe. Ractor-unsafe C-methods only been called from
+main-ractor. If non-main ractor calls it, then Ractor::UnsafeError is
+raised.
+
+BTW non-"Ractor-safe" extensions raises an error on non-main ractors, so
+that it is "safe" because unsafe operations are not allowed.
+"Ractor-safe" property means "multi-Ractor-ready" or "safe on
+multi-ractors execution". "Ractor-safe" term comes from "Thread-safe".
+
+To make "Ractor-safe" C extension, we need to check the following points:
+
+(1) Do not share unshareable objects between ractors
+
+For example, C's global variable can lead sharing an unshareable objects
+betwee ractors.
+
+ VALUE g_var;
+ VALUE set(VALUE self, VALUE v){ return g_var = v; }
+ VALUE get(VALUE self){ return g_var; }
+
+set() and get() pair can share an unshareable objects using g_var, and
+it is Ractor-unsafe.
+
+Not only using global variables directly, some indirect data structure
+such as global st_table can share the objects, so please take care.
+
+Note that class and module objects are shareable objects, so you can
+keep the code "cFoo = rb_define_class(...)" with C's global variables.
+
+(2) Check the thread-safety of the extension
+
+An extension should be thread-safe. For example, the following code is
+not thread-safe:
+
+ bool g_called = false;
+ VALUE call(VALUE self) {
+ if (g_called) rb_raise("recursive call is not allowed.");
+ g_called = true;
+ VALUE ret = do_something();
+ g_called = false;
+ return ret;
+ }
+
+because g_called global variable should be synchronized by other
+ractor's threads. To avoid such data-race, some synchronization should
+be used. Check include/ruby/thread_native.h and include/ruby/atomic.h.
+
+On the Ractor mechanism, most of objects given by the method parameters
+or the receiver are isolated by Ractor's boundary, it is easy to make
+thread-safe code than usual thread-programming in general. For example,
+we don't need to lock an array object to access the element of it.
+
+(3) Check the thread-safety of using library
+
+If an extension relies on the external library libfoo and the function
+foo(), the function foo() should be thread safe.
+
+(4) Make an object shareable
+
+This is not required to make an extension Ractor-safe.
+
+If an extension provides special objects defined by rb_data_type_t,
+consider these objects can become shareable or not.
+
+RUBY_TYPED_FROZEN_SHAREABLE flag indicates that these objects can be
+shareable objects if the object is frozen. This means that if the object
+is frozen, the mutation of wrapped data is not allowed.
+
+(5) Others
+
+Maybe there are more points which should be considered to make
+Ractor-safe extension, so this document will be extended.
+
:enddoc: Local variables:
:enddoc: fill-column: 70
:enddoc: end:
diff --git a/doc/fiber.md b/doc/fiber.md
new file mode 100644
index 0000000000..5abd848677
--- /dev/null
+++ b/doc/fiber.md
@@ -0,0 +1,191 @@
+# Fiber
+
+Fibers provide a mechanism for cooperative concurrency.
+
+## Context Switching
+
+Fibers execute a user-provided block. During the execution, the block may call `Fiber.yield` or `Fiber.transfer` to switch to another fiber. `Fiber#resume` is used to continue execution from the point where `Fiber.yield` was called.
+
+``` ruby
+#!/usr/bin/env ruby
+
+puts "1: Start program."
+
+f = Fiber.new do
+ puts "3: Entered fiber."
+ Fiber.yield
+ puts "5: Resumed fiber."
+end
+
+puts "2: Resume fiber first time."
+f.resume
+
+puts "4: Resume fiber second time."
+f.resume
+
+puts "6: Finished."
+```
+
+This program demonstrates the flow control of fibers.
+
+## Scheduler
+
+The scheduler interface is used to intercept blocking operations. A typical
+implementation would be a wrapper for a gem like `EventMachine` or `Async`. This
+design provides separation of concerns between the event loop implementation
+and application code. It also allows for layered schedulers which can perform
+instrumentation.
+
+To set the scheduler for the current thread:
+
+``` ruby
+Fiber.set_scheduler(MyScheduler.new)
+```
+
+When the thread exits, there is an implicit call to `set_scheduler`:
+
+``` ruby
+Fiber.set_scheduler(nil)
+```
+
+### Interface
+
+This is the interface you need to implement.
+
+``` ruby
+class Scheduler
+ # Wait for the specified process ID to exit.
+ # This hook is optional.
+ # @parameter pid [Integer] The process ID to wait for.
+ # @parameter flags [Integer] A bit-mask of flags suitable for `Process::Status.wait`.
+ # @returns [Process::Status] A process status instance.
+ def process_wait(pid, flags)
+ Thread.new do
+ Process::Status.wait(pid, flags)
+ end.value
+ end
+
+ # Wait for the given file descriptor to match the specified events within
+ # the specified timeout.
+ # @parameter event [Integer] A bit mask of `IO::READABLE`,
+ # `IO::WRITABLE` and `IO::PRIORITY`.
+ # @parameter timeout [Numeric] The amount of time to wait for the event in seconds.
+ # @returns [Integer] The subset of events that are ready.
+ def io_wait(io, events, timeout)
+ end
+
+ # Sleep the current task for the specified duration, or forever if not
+ # specified.
+ # @param duration [Numeric] The amount of time to sleep in seconds.
+ def kernel_sleep(duration = nil)
+ end
+
+ # Block the calling fiber.
+ # @parameter blocker [Object] What we are waiting on, informational only.
+ # @parameter timeout [Numeric | Nil] The amount of time to wait for in seconds.
+ # @returns [Boolean] Whether the blocking operation was successful or not.
+ def block(blocker, timeout = nil)
+ end
+
+ # Unblock the specified fiber.
+ # @parameter blocker [Object] What we are waiting on, informational only.
+ # @parameter fiber [Fiber] The fiber to unblock.
+ # @reentrant Thread safe.
+ def unblock(blocker, fiber)
+ end
+
+ # Intercept the creation of a non-blocking fiber.
+ # @returns [Fiber]
+ def fiber(&block)
+ Fiber.new(blocking: false, &block)
+ end
+
+ # Invoked when the thread exits.
+ def close
+ self.run
+ end
+
+ def run
+ # Implement event loop here.
+ end
+end
+```
+
+Additional hooks may be introduced in the future, we will use feature detection
+in order to enable these hooks.
+
+### Non-blocking Execution
+
+The scheduler hooks will only be used in special non-blocking execution
+contexts. Non-blocking execution contexts introduce non-determinism because the
+execution of scheduler hooks may introduce context switching points into your
+program.
+
+#### Fibers
+
+Fibers can be used to create non-blocking execution contexts.
+
+``` ruby
+Fiber.new do
+ puts Fiber.current.blocking? # false
+
+ # May invoke `Fiber.scheduler&.io_wait`.
+ io.read(...)
+
+ # May invoke `Fiber.scheduler&.io_wait`.
+ io.write(...)
+
+ # Will invoke `Fiber.scheduler&.kernel_sleep`.
+ sleep(n)
+end.resume
+```
+
+We also introduce a new method which simplifies the creation of these
+non-blocking fibers:
+
+``` ruby
+Fiber.schedule do
+ puts Fiber.current.blocking? # false
+end
+```
+
+The purpose of this method is to allow the scheduler to internally decide the
+policy for when to start the fiber, and whether to use symmetric or asymmetric
+fibers.
+
+You can also create blocking execution contexts:
+
+``` ruby
+Fiber.new(blocking: true) do
+ # Won't use the scheduler:
+ sleep(n)
+end
+```
+
+However you should generally avoid this unless you are implementing a scheduler.
+
+#### IO
+
+By default, I/O is non-blocking. Not all operating systems support non-blocking
+I/O. Windows is a notable example where socket I/O can be non-blocking but pipe
+I/O is blocking. Provided that there *is* a scheduler and the current thread *is
+non-blocking*, the operation will invoke the scheduler.
+
+#### Mutex
+
+The `Mutex` class can be used in a non-blocking context and is fiber specific.
+
+#### ConditionVariable
+
+The `ConditionVariable` class can be used in a non-blocking context and is
+fiber-specific.
+
+#### Queue / SizedQueue
+
+The `Queue` and `SizedQueue` classes can be used in a non-blocking context and
+are fiber-specific.
+
+#### Thread
+
+The `Thread#join` operation can be used in a non-blocking context and is
+fiber-specific.
diff --git a/doc/globals.rdoc b/doc/globals.rdoc
index 1e70555988..1d7cda69f9 100644
--- a/doc/globals.rdoc
+++ b/doc/globals.rdoc
@@ -1,70 +1,69 @@
# -*- mode: rdoc; coding: utf-8; fill-column: 74; -*-
-== Pre-defined variables
+== Pre-defined global variables
-$!:: The exception information message set by 'raise'.
-$@:: Array of backtrace of the last exception thrown.
+$!:: The Exception object set by Kernel#raise.
+$@:: The same as <code>$!.backtrace</code>.
+$~:: The information about the last match in the current scope (thread-local and frame-local).
$&:: The string matched by the last successful match.
$`:: The string to the left of the last successful match.
$':: The string to the right of the last successful match.
$+:: The highest group matched by the last successful match.
$1:: The Nth group of the last successful match. May be > 1.
-$~:: The information about the last match in the current scope.
$=:: This variable is no longer effective. Deprecated.
-$/:: The input record separator, newline by default.
-$\:: The output record separator for the print and IO#write. Default is nil.
-$,:: The output field separator for the print and Array#join.
-$;:: The default separator for String#split.
+$/:: The input record separator, newline by default. Aliased to $-0.
+$\:: The output record separator for Kernel#print and IO#write. Default is +nil+.
+$,:: The output field separator for Kernel#print and Array#join. Non-nil $, will be deprecated.
+$;:: The default separator for String#split. Non-nil $; will be deprecated. Aliased to $-F.
$.:: The current input line number of the last file that was read.
-$<:: The virtual concatenation file of the files given on command line (or from $stdin if no files were given).
-$>:: The default output for print, printf. $stdout by default.
+$<:: The same as ARGF.
+$>:: The default output stream for Kernel#print and Kernel#printf. $stdout by default.
$_:: The last input line of string by gets or readline.
$0:: Contains the name of the script being executed. May be assignable.
-$*:: Command line arguments given for the script sans args.
-$$:: The process number of the Ruby running this script.
-$?:: The status of the last executed child process. This value is
- thread-local.
-$::: Load path for scripts and binary modules by load or require.
-$":: The array contains the module names loaded by require.
-$DEBUG:: The debug flag, which is set by the -d switch. Enabling debug
+$*:: The same as ARGV.
+$$:: The process number of the Ruby running this script. Same as Process.pid.
+$?:: The status of the last executed child process (thread-local).
+$LOAD_PATH:: Load path for searching Ruby scripts and extension libraries used
+ by Kernel#load and Kernel#require. Aliased to $: and $-I.
+ Has a singleton method <code>$LOAD_PATH.resolve_feature_path(feature)</code>
+ that returns [+:rb+ or +:so+, path], which resolves the feature to
+ the path the original Kernel#require method would load.
+$LOADED_FEATURES:: The array contains the module names loaded by require.
+ Aliased to $".
+$DEBUG:: The debug flag, which is set by the <tt>-d</tt> switch. Enabling debug
output prints each exception raised to $stderr (but not its
backtrace). Setting this to a true value enables debug output as
- if -d were given on the command line. Setting this to a false
- value disables debug output.
-$LOADED_FEATURES:: The alias to the $".
-$FILENAME:: Current input file from $<. Same as $<.filename.
-$LOAD_PATH:: The alias to the $:.
+ if <tt>-d</tt> were given on the command line. Setting this to a false
+ value disables debug output. Aliased to $-d.
+$FILENAME:: Current input filename from ARGF. Same as ARGF.filename.
$stderr:: The current standard error output.
$stdin:: The current standard input.
$stdout:: The current standard output.
-$VERBOSE:: The verbose flag, which is set by the -w or -v switch. Setting
- this to a true value enables warnings as if -w or -v were given
- on the command line. Setting this to nil disables warnings,
- including from Kernel#warn.
-$-0:: The alias to $/.
-$-a:: True if option -a is set. Read-only variable.
-$-d:: The alias of $DEBUG. See $DEBUG above for further discussion.
-$-F:: The alias to $;.
-$-i:: In in-place-edit mode, this variable holds the extension, otherwise nil.
-$-I:: The alias to $:.
-$-l:: True if option -l is set. Read-only variable.
-$-p:: True if option -p is set. Read-only variable.
-$-v:: An alias of $VERBOSE. See $VERBOSE above for further discussion.
-$-w:: An alias of $VERBOSE. See $VERBOSE above for further discussion.
+$VERBOSE:: The verbose flag, which is set by the <tt>-w</tt> or <tt>-v</tt> switch.
+ Setting this to a true value enables warnings as if <tt>-w</tt> or <tt>-v</tt> were given
+ on the command line. Setting this to +nil+ disables warnings,
+ including from Kernel#warn. Aliased to $-v and $-w.
+$-a:: True if option <tt>-a</tt> is set. Read-only variable.
+$-i:: In in-place-edit mode, this variable holds the extension, otherwise +nil+.
+$-l:: True if option <tt>-l</tt> is set. Read-only variable.
+$-p:: True if option <tt>-p</tt> is set. Read-only variable.
== Pre-defined global constants
-TRUE:: The typical true value.
-FALSE:: The false itself.
-NIL:: The nil itself.
STDIN:: The standard input. The default value for $stdin.
STDOUT:: The standard output. The default value for $stdout.
STDERR:: The standard error output. The default value for $stderr.
ENV:: The hash contains current environment variables.
-ARGF:: The alias to the $<.
-ARGV:: The alias to the $*.
-DATA:: The file object of the script, pointing just after __END__.
-RUBY_VERSION:: The ruby version string (VERSION was deprecated).
+ARGF:: The virtual concatenation of the files given on command line (or from $stdin if no files were given).
+ARGV:: An Array of command line arguments given for the script.
+DATA:: The file object of the script, pointing just after <code>__END__</code>.
+TOPLEVEL_BINDING:: The Binding of the top level scope.
+RUBY_VERSION:: The Ruby language version.
RUBY_RELEASE_DATE:: The release date string.
RUBY_PLATFORM:: The platform identifier.
-
+RUBY_PATCHLEVEL:: The patchlevel for this Ruby. If this is a development build of Ruby the patchlevel will be -1.
+RUBY_REVISION:: The GIT commit hash for this Ruby.
+RUBY_COPYRIGHT:: The copyright string for Ruby.
+RUBY_ENGINE:: The name of the Ruby implementation.
+RUBY_ENGINE_VERSION:: The version of the Ruby implementation.
+RUBY_DESCRIPTION:: The same as <tt>ruby --version</tt>, a String describing various aspects of the Ruby implementation.
diff --git a/doc/implicit_conversion.rdoc b/doc/implicit_conversion.rdoc
new file mode 100644
index 0000000000..0c2a1d4971
--- /dev/null
+++ b/doc/implicit_conversion.rdoc
@@ -0,0 +1,198 @@
+== Implicit Conversions
+
+Some Ruby methods accept one or more objects
+that can be either:
+* <i>Of a given class</i>, and so accepted as is.
+* <i>Implicitly convertible to that class</i>, in which case
+ the called method converts the object.
+
+For each of the relevant classes, the conversion is done by calling
+a specific conversion method:
+
+* Array: +to_ary+
+* Hash: +to_hash+
+* Integer: +to_int+
+* String: +to_str+
+
+=== Array-Convertible Objects
+
+An <i>Array-convertible object</i> is an object that:
+* Has instance method +to_ary+.
+* The method accepts no arguments.
+* The method returns an object +obj+ for which <tt>obj.kind_of?(Array)</tt> returns +true+.
+
+The examples in this section use method <tt>Array#replace</tt>,
+which accepts an Array-convertible argument.
+
+This class is Array-convertible:
+
+ class ArrayConvertible
+ def to_ary
+ [:foo, 'bar', 2]
+ end
+ end
+ a = []
+ a.replace(ArrayConvertible.new) # => [:foo, "bar", 2]
+
+This class is not Array-convertible (no +to_ary+ method):
+
+ class NotArrayConvertible; end
+ a = []
+ # Raises TypeError (no implicit conversion of NotArrayConvertible into Array)
+ a.replace(NotArrayConvertible.new)
+
+This class is not Array-convertible (method +to_ary+ takes arguments):
+
+ class NotArrayConvertible
+ def to_ary(x)
+ [:foo, 'bar', 2]
+ end
+ end
+ a = []
+ # Raises ArgumentError (wrong number of arguments (given 0, expected 1))
+ a.replace(NotArrayConvertible.new)
+
+This class is not Array-convertible (method +to_ary+ returns non-Array):
+
+ class NotArrayConvertible
+ def to_ary
+ :foo
+ end
+ end
+ a = []
+ # Raises TypeError (can't convert NotArrayConvertible to Array (NotArrayConvertible#to_ary gives Symbol))
+ a.replace(NotArrayConvertible.new)
+
+=== Hash-Convertible Objects
+
+A <i>Hash-convertible object</i> is an object that:
+* Has instance method +to_hash+.
+* The method accepts no arguments.
+* The method returns an object +obj+ for which <tt>obj.kind_of?(Hash)</tt> returns +true+.
+
+The examples in this section use method <tt>Hash#merge</tt>,
+which accepts a Hash-convertible argument.
+
+This class is Hash-convertible:
+
+ class HashConvertible
+ def to_hash
+ {foo: 0, bar: 1, baz: 2}
+ end
+ end
+ h = {}
+ h.merge(HashConvertible.new) # => {:foo=>0, :bar=>1, :baz=>2}
+
+This class is not Hash-convertible (no +to_hash+ method):
+
+ class NotHashConvertible; end
+ h = {}
+ # Raises TypeError (no implicit conversion of NotHashConvertible into Hash)
+ h.merge(NotHashConvertible.new)
+
+This class is not Hash-convertible (method +to_hash+ takes arguments):
+
+ class NotHashConvertible
+ def to_hash(x)
+ {foo: 0, bar: 1, baz: 2}
+ end
+ end
+ h = {}
+ # Raises ArgumentError (wrong number of arguments (given 0, expected 1))
+ h.merge(NotHashConvertible.new)
+
+This class is not Hash-convertible (method +to_hash+ returns non-Hash):
+
+ class NotHashConvertible
+ def to_hash
+ :foo
+ end
+ end
+ h = {}
+ # Raises TypeError (can't convert NotHashConvertible to Hash (ToHashReturnsNonHash#to_hash gives Symbol))
+ h.merge(NotHashConvertible.new)
+
+=== Integer-Convertible Objects
+
+An <i>Integer-convertible object</i> is an object that:
+* Has instance method +to_int+.
+* The method accepts no arguments.
+* The method returns an object +obj+ for which <tt>obj.kind_of?(Integer)</tt> returns +true+.
+
+The examples in this section use method <tt>Array.new</tt>,
+which accepts an Integer-convertible argument.
+
+This user-defined class is Integer-convertible:
+
+ class IntegerConvertible
+ def to_int
+ 3
+ end
+ end
+ a = Array.new(IntegerConvertible.new).size
+ a # => 3
+
+This class is not Integer-convertible (method +to_int+ takes arguments):
+
+ class NotIntegerConvertible
+ def to_int(x)
+ 3
+ end
+ end
+ # Raises ArgumentError (wrong number of arguments (given 0, expected 1))
+ Array.new(NotIntegerConvertible.new)
+
+This class is not Integer-convertible (method +to_int+ returns non-Integer):
+
+ class NotIntegerConvertible
+ def to_int
+ :foo
+ end
+ end
+ # Raises TypeError (can't convert NotIntegerConvertible to Integer (NotIntegerConvertible#to_int gives Symbol))
+ Array.new(NotIntegerConvertible.new)
+
+=== String-Convertible Objects
+
+A <i>String-convertible object</i> is an object that:
+* Has instance method +to_str+.
+* The method accepts no arguments.
+* The method returns an object +obj+ for which <tt>obj.kind_of?(String)</tt> returns +true+.
+
+The examples in this section use method <tt>String::new</tt>,
+which accepts a String-convertible argument.
+
+This class is String-convertible:
+
+ class StringConvertible
+ def to_str
+ 'foo'
+ end
+ end
+ String.new(StringConvertible.new) # => "foo"
+
+This class is not String-convertible (no +to_str+ method):
+
+ class NotStringConvertible; end
+ # Raises TypeError (no implicit conversion of NotStringConvertible into String)
+ String.new(NotStringConvertible.new)
+
+This class is not String-convertible (method +to_str+ takes arguments):
+
+ class NotStringConvertible
+ def to_str(x)
+ 'foo'
+ end
+ end
+ # Raises ArgumentError (wrong number of arguments (given 0, expected 1))
+ String.new(NotStringConvertible.new)
+
+This class is not String-convertible (method +to_str+ returns non-String):
+
+ class NotStringConvertible
+ def to_str
+ :foo
+ end
+ end
+ # Raises TypeError (can't convert NotStringConvertible to String (NotStringConvertible#to_str gives Symbol))
+ String.new(NotStringConvertible.new)
diff --git a/doc/irb/irb.rd.ja b/doc/irb/irb.rd.ja
index 85b6536ee4..81247ce4b0 100644
--- a/doc/irb/irb.rd.ja
+++ b/doc/irb/irb.rd.ja
@@ -40,39 +40,46 @@ irbã®ä½¿ã„æ–¹ã¯, Rubyã•ãˆçŸ¥ã£ã¦ã„れã°ã„ãŸã£ã¦ç°¡å˜ã§ã™. 基本
irb.rb [options] file_name opts
options:
-f ~/.irbrc を読ã¿è¾¼ã¾ãªã„.
- -m bcモード(分数, 行列ã®è¨ˆç®—ãŒã§ãã‚‹)
-d $DEBUG ã‚’trueã«ã™ã‚‹(ruby -d ã¨åŒã˜)
- -Kc ruby -Kcã¨åŒã˜
-r load-module ruby -r ã¨åŒã˜.
- --verbose ã“れã‹ã‚‰å®Ÿè¡Œã™ã‚‹è¡Œã‚’表示ã™ã‚‹(デフォルト)
- --noverbose ã“れã‹ã‚‰å®Ÿè¡Œã™ã‚‹è¡Œã‚’表示ã—ãªã„
- --echo å®Ÿè¡Œçµæžœã‚’表示ã™ã‚‹(デフォルト)
- --noecho å®Ÿè¡Œçµæžœã‚’表示ã—ãªã„
- --inspect çµæžœå‡ºåŠ›ã«inspectを用ã„ã‚‹(bcモード以外ã¯ãƒ‡ãƒ•ォルト).
+ -I path $LOAD_PATH ã« path を追加ã™ã‚‹.
+ -U ruby -U ã¨åŒã˜.
+ -E enc ruby -E ã¨åŒã˜.
+ -w ruby -w ã¨åŒã˜.
+ -W[level=2] ruby -W ã¨åŒã˜.
+ --context-mode n æ–°ã—ã„ワークスペースを作æˆã—ãŸæ™‚ã«é–¢é€£ã™ã‚‹ Binding
+ オブジェクトã®ä½œæˆæ–¹æ³•ã‚’ 0 ã‹ã‚‰ 3 ã®ã„ãšã‚Œã‹ã«è¨­å®šã™ã‚‹.
+ --echo å®Ÿè¡Œçµæžœã‚’表示ã™ã‚‹(デフォルト).
+ --noecho å®Ÿè¡Œçµæžœã‚’表示ã—ãªã„.
+ --inspect çµæžœå‡ºåŠ›ã«inspectを用ã„ã‚‹.
--noinspect çµæžœå‡ºåŠ›ã«inspectを用ã„ãªã„.
- --readline readlineライブラリを利用ã™ã‚‹.
- --noreadline readlineライブラリを利用ã—ãªã„. デフォルトã®å‹•作ã¯,
- inf-ruby-mode以外ã§readlineライブラリを利用ã—よã†
- ã¨ã™ã‚‹.
- --prompt prompt-mode
- --prompt-mode prompt-mode
+ --singleline シングルラインエディタを利用ã™ã‚‹.
+ --nosingleline シングルラインエディタを利用ã—ãªã„. デフォルトã®å‹•
+ 作ã¯, inf-ruby-mode以外ã§ã‚·ãƒ³ã‚°ãƒ«ãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’利
+ 用ã—よã†ã¨ã™ã‚‹.
+ --colorize 色付ã‘を利用ã™ã‚‹.
+ --nocolorize 色付ã‘を利用ã—ãªã„.
+ --prompt prompt-mode/--prompt-mode prompt-mode
プロンプトモードを切替ãˆã¾ã™. ç¾åœ¨å®šç¾©ã•れã¦ã„るプ
ロンプトモードã¯, default, simple, xmp, inf-rubyãŒ
- 用æ„ã•れã¦ã„ã¾ã™. デフォルトã¯defaultプロンプトモー
- ドã«ãªã£ã¦ã„ã¾ã™.
-
+ 用æ„ã•れã¦ã„ã¾ã™.
--inf-ruby-mode emacsã®inf-ruby-mode用ã®ãƒ—ロンプト表示を行ãªã†. 特
- ã«æŒ‡å®šãŒãªã„é™ã‚Š, readlineライブラリã¯ä½¿ã‚ãªããªã‚‹.
+ ã«æŒ‡å®šãŒãªã„é™ã‚Š, ラインエディタã¯ä½¿ã‚ãªããªã‚‹.
--simple-prompt
éžå¸¸ã«ã‚·ãƒ³ãƒ—ルãªãƒ—ロンプトを用ã„るモードã§ã™.
--noprompt プロンプト表示を行ãªã‚ãªã„.
+ --single-irb irb 中㧠self を実行ã—ã¦å¾—られるオブジェクトをサ
+ ブ irb ã¨å…±æœ‰ã™ã‚‹.
--tracer コマンド実行時ã«ãƒˆãƒ¬ãƒ¼ã‚¹ã‚’行ãªã†.
--back-trace-limit n
ãƒãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹è¡¨ç¤ºã‚’ãƒãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹ã®é ­ã‹ã‚‰ n, 後ã‚
ã‹ã‚‰nã ã‘行ãªã†. デフォルトã¯16
- --irb_debug n irbã®ãƒ‡ãƒãƒƒã‚°ãƒ‡ãƒãƒƒã‚°ãƒ¬ãƒ™ãƒ«ã‚’nã«è¨­å®šã™ã‚‹(利用ã—ãª
- ã„æ–¹ãŒç„¡é›£ã§ã—ょã†).
- -v, --version irbã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã™ã‚‹
+
+ --verbose 詳細ãªãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’出力ã™ã‚‹.
+ --noverbose 詳細ãªãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’出力ã—ãªã„(デフォルト).
+ -v, --version irbã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã™ã‚‹.
+ -h, --help irb ã®ãƒ˜ãƒ«ãƒ—を表示ã™ã‚‹.
+ -- 以é™ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³å¼•数をオプションã¨ã—ã¦æ‰±ã‚ãªã„.
= コンフィギュレーション
@@ -91,13 +98,12 @@ irb起動時ã«``~/.irbrc''を読ã¿è¾¼ã¿ã¾ã™. ã‚‚ã—存在ã—ãªã„å ´åˆã¯
IRB.conf[:IRB_RC] = nil
IRB.conf[:BACK_TRACE_LIMIT]=16
IRB.conf[:USE_LOADER] = false
- IRB.conf[:USE_READLINE] = nil
+ IRB.conf[:USE_SINGLELINE] = nil
IRB.conf[:USE_TRACER] = false
IRB.conf[:IGNORE_SIGINT] = true
IRB.conf[:IGNORE_EOF] = false
IRB.conf[:PROMPT_MODE] = :DEFAULT
IRB.conf[:PROMPT] = {...}
- IRB.conf[:DEBUG_LEVEL]=0
IRB.conf[:VERBOSE]=true
== プロンプトã®è¨­å®š
@@ -183,9 +189,6 @@ irb拡張コマンドã¯, ç°¡å˜ãªåå‰ã¨é ­ã«`irb_'ã‚’ã¤ã‘ãŸåå‰ã¨ä¸¡
ãƒãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹è¡¨ç¤ºã‚’ãƒãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹ã®é ­ã‹ã‚‰n, 後ã‚ã‹ã‚‰nã ã‘行ãªã†.
デフォルトã¯16
---- conf.debug_level = N
- irb用ã®ãƒ‡ãƒãƒƒã‚°ãƒ¬ãƒ™ãƒ«ã®è¨­å®š
-
--- conf.ignore_eof = true/false
^DãŒå…¥åŠ›ã•ã‚ŒãŸæ™‚ã®å‹•作を設定ã™ã‚‹. trueã®æ™‚ã¯^Dを無視ã™ã‚‹, falseã®
時ã¯irbを終了ã™ã‚‹.
@@ -197,7 +200,8 @@ irb拡張コマンドã¯, ç°¡å˜ãªåå‰ã¨é ­ã«`irb_'ã‚’ã¤ã‘ãŸåå‰ã¨ä¸¡
実行中: 実行を中止ã™ã‚‹.
--- conf.inf_ruby_mode = true/false
- inf-ruby-mode用ã®ãƒ—ロンプト表示を行ãªã†. デフォルトã¯false.
+ inf-ruby-mode用ã®ãƒ—ロンプト表示を行ãªã†. デフォルトã¯false. ç‰¹ã«æŒ‡å®š
+ ãŒãªã„é™ã‚Š, ラインエディタã¯ä½¿ã‚ãªããªã‚‹.
--- conf.inspect_mode = true/false/nil
インスペクトモードを設定ã™ã‚‹.
@@ -225,12 +229,19 @@ irb拡張コマンドã¯, ç°¡å˜ãªåå‰ã¨é ­ã«`irb_'ã‚’ã¤ã‘ãŸåå‰ã¨ä¸¡
--- conf.use_prompt = true/false
プロンプト表示ã™ã‚‹ã‹ã©ã†ã‹? デフォルトã§ã¯ãƒ—ロンプトを表示ã™ã‚‹.
---- conf.use_readline = true/false/nil
- readlineを使ã†ã‹ã©ã†ã‹?
- true: readlineを使ã†.
- false: readlineを使ã‚ãªã„.
- nil: (デフォルト)inf-ruby-mode以外ã§readlineライブラリを利用ã—よ
- ã†ã¨ã™ã‚‹.
+--- conf.use_multiline = true/false/nil
+ マルãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’使ã†ã‹ã©ã†ã‹?
+ true: マルãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’使ã†.
+ false: マルãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’使ã‚ãªã„.
+ nil: (デフォルト)inf-ruby-mode以外ã§ãƒžãƒ«ãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’利用ã—よã†
+ ã¨ã™ã‚‹.
+
+--- conf.use_singleline = true/false/nil
+ シングルラインエディタを使ã†ã‹ã©ã†ã‹?
+ true: シングルラインエディタを使ã†.
+ false: シングルラインエディタを使ã‚ãªã„.
+ nil: (デフォルト)inf-ruby-modeã¨ãƒžãƒ«ãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ä»¥å¤–ã§ã‚·ãƒ³ã‚°ãƒ«ãƒ©
+ インエディタを利用ã—よã†ã¨ã™ã‚‹.
#
#--- conf.verbose=T/F
# irbã‹ã‚‰ã„ã‚ã„ã‚ãªãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’出力ã™ã‚‹ã‹?
diff --git a/doc/keywords.rdoc b/doc/keywords.rdoc
index 98bbd5e864..cb1cff33f0 100644
--- a/doc/keywords.rdoc
+++ b/doc/keywords.rdoc
@@ -76,12 +76,14 @@ for::
expressions}[rdoc-ref:syntax/control_expressions.rdoc]
if::
- Used for +if+ and modifier +if+ expressions. See {control
+ Used for +if+ and modifier +if+ statements. See {control
expressions}[rdoc-ref:syntax/control_expressions.rdoc]
in::
Used to separate the iterable object and iterator variable in a +for+ loop.
See {control expressions}[rdoc-ref:syntax/control_expressions.rdoc]
+ It also serves as a pattern in a +case+ expression.
+ See {pattern matching}[rdoc-ref:syntax/pattern_matching.rdoc]
module::
Creates or opens a module. See {modules and classes
@@ -115,7 +117,9 @@ retry::
handling}[rdoc-ref:syntax/exceptions.rdoc]
return::
- Exits a method. See {methods}[rdoc-ref:syntax/methods.rdoc]
+ Exits a method. See {methods}[rdoc-ref:syntax/methods.rdoc].
+ If met in top-level scope, immediately stops interpretation of
+ the current file.
self::
The object the current method is attached to. See
@@ -137,7 +141,7 @@ undef::
See {modules and classes}[rdoc-ref:syntax/modules_and_classes.rdoc]
unless::
- Used for +unless+ and modifier +unless+ expressions. See {control
+ Used for +unless+ and modifier +unless+ statements. See {control
expressions}[rdoc-ref:syntax/control_expressions.rdoc]
until::
diff --git a/doc/maintainers.rdoc b/doc/maintainers.rdoc
index 66af8b1d50..64510b2559 100644
--- a/doc/maintainers.rdoc
+++ b/doc/maintainers.rdoc
@@ -13,7 +13,7 @@ A module maintainer is responsible for a certain part of Ruby.
* They have "developer" role on the Redmine to modify issues.
* They have authority to decide the feature of their part. But they should always respect discussions on ruby-core/ruby-dev.
-A submaintainer of a module is like a maintainer. But The submaintainer does
+A submaintainer of a module is like a maintainer. But the submaintainer does
not have authority to change/add a feature on his/her part. They need consensus
on ruby-core/ruby-dev before changing/adding. Some of submaintainers have
commit right, others don't.
@@ -30,248 +30,388 @@ Koichi Sasada (ko1)
Yukihiro Matsumoto (matz)
-=== Documentation
-
-Zachary Scott (zzak)
-
== Standard Library Maintainers
=== Libraries
-[lib/English.rb]
+[lib/mkmf.rb]
+ _unmaintained_
+[lib/rubygems.rb, lib/rubygems/*]
+ Eric Hodel (drbrain), Hiroshi SHIBATA (hsbt)
+ https://github.com/rubygems/rubygems
+[lib/unicode_normalize.rb, lib/unicode_normalize/*]
+ Martin J. Dürst
+
+=== Extensions
+
+[ext/continuation]
+ Koichi Sasada (ko1)
+[ext/coverage]
+ Yusuke Endoh (mame)
+[ext/fiber]
+ Koichi Sasada (ko1)
+[ext/monitor]
+ Koichi Sasada (ko1)
+[ext/objspace]
_unmaintained_
+[ext/pty]
+ _unmaintained_
+[ext/ripper]
+ _unmaintained_
+[ext/socket]
+ * Tanaka Akira (akr)
+ * API change needs matz's approval
+[ext/win32]
+ NAKAMURA Usaku (usa)
+
+== Default gems Maintainers
+
+=== Libraries
+
[lib/abbrev.rb]
Akinori MUSHA (knu)
+ https://github.com/ruby/abbrev
+ https://rubygems.org/gems/abbrev
[lib/base64.rb]
Yusuke Endoh (mame)
+ https://github.com/ruby/base64
+ https://rubygems.org/gems/base64
[lib/benchmark.rb]
_unmaintained_
+ https://github.com/ruby/benchmark
+ https://rubygems.org/gems/benchmark
+[lib/bundler.rb, lib/bundler/*]
+ Hiroshi SHIBATA (hsbt)
+ https://github.com/rubygems/rubygems
+ https://rubygems.org/gems/bundler
[lib/cgi.rb, lib/cgi/*]
Takeyuki Fujioka (xibbar)
-[lib/drb.rb, lib/drb/*]
- Masatoshi SEKI (seki)
+ https://github.com/ruby/cgi
+ https://rubygems.org/gems/cgi
+[lib/csv.rb]
+ Kenta Murata (mrkn), Kouhei Sutou (kou)
+ https://github.com/ruby/csv
+ https://rubygems.org/gems/csv
+[lib/English.rb]
+ _unmaintained_
+ https://github.com/ruby/English
+ https://rubygems.org/gems/English
[lib/debug.rb]
_unmaintained_
+ https://github.com/ruby/debug
[lib/delegate.rb]
_unmaintained_
-[lib/e2mmap.rb]
- Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/delegate
+ https://rubygems.org/gems/delegate
+[lib/did_you_mean.rb]
+ Yuki Nishijima (yuki24)
+ https://github.com/ruby/did_you_mean
+ https://rubygems.org/gems/did_you_mean
+[ext/digest, ext/digest/*]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/digest
+ https://rubygems.org/gems/digest
+[lib/drb.rb, lib/drb/*]
+ Masatoshi SEKI (seki)
+ https://github.com/ruby/drb
+ https://rubygems.org/gems/drb
[lib/erb.rb]
Masatoshi SEKI (seki), Takashi Kokubun (k0kubun)
+ https://github.com/ruby/erb
+ https://rubygems.org/gems/erb
+[lib/fileutils.rb]
+ _unmaintained_
+ https://github.com/ruby/fileutils
+ https://rubygems.org/gems/fileutils
[lib/find.rb]
Kazuki Tsujimoto (ktsj)
+ https://github.com/ruby/find
+ https://rubygems.org/gems/find
[lib/forwardable.rb]
Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/forwardable
+ https://rubygems.org/gems/forwardable
[lib/getoptlong.rb]
_unmaintained_
+ https://github.com/ruby/getoptlong
+ https://rubygems.org/gems/getoptlong
[lib/ipaddr.rb]
Akinori MUSHA (knu)
+ https://github.com/ruby/ipaddr
+ https://rubygems.org/gems/ipaddr
[lib/irb.rb, lib/irb/*]
- Keiju ISHITSUKA (keiju)
+ aycabta
+ https://github.com/ruby/irb
+ https://rubygems.org/gems/irb
+[lib/optparse.rb, lib/optparse/*]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/optparse
[lib/logger.rb]
Naotoshi Seo (sonots)
+ https://github.com/ruby/logger
+ https://rubygems.org/gems/logger
[lib/matrix.rb]
- Marc-Andre Lafortune (marcandre)
-[lib/mkmf.rb]
- _unmaintained_
-[lib/monitor.rb]
- Shugo Maeda (shugo)
+ Marc-André Lafortune (marcandre)
+ https://github.com/ruby/matrix
+ https://rubygems.org/gems/matrix
[lib/mutex_m.rb]
Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/mutex_m
+ https://rubygems.org/gems/mutex_m
[lib/net/ftp.rb]
Shugo Maeda (shugo)
-[lib/net/imap.rb]
- Shugo Maeda (shugo)
+ https://github.com/ruby/net-ftp
+ https://rubygems.org/gems/net-ftp
[lib/net/http.rb, lib/net/https.rb]
NARUSE, Yui (naruse)
+ https://github.com/ruby/net-http
+ https://rubygems.org/gems/net-http
+[lib/net/imap.rb]
+ Shugo Maeda (shugo)
+ https://github.com/ruby/net-imap
+ https://rubygems.org/gems/net-imap
[lib/net/pop.rb]
_unmaintained_
-[lib/net/protocol.rb]
- _unmaintained_
+ https://github.com/ruby/net-pop
+ https://rubygems.org/gems/net-pop
[lib/net/smtp.rb]
_unmaintained_
+ https://github.com/ruby/net-smtp
+ https://rubygems.org/gems/net-smtp
+[lib/net/protocol.rb]
+ _unmaintained_
+ https://github.com/ruby/net-protocol
+ https://rubygems.org/gems/net-protocol
[lib/observer.rb]
_unmaintained_
-[lib/open-uri.rb]
- Tanaka Akira (akr)
+ https://github.com/ruby/observer
+ https://rubygems.org/gems/observer
[lib/open3.rb]
_unmaintained_
-[lib/optparse.rb, lib/optparse/*]
- Nobuyuki Nakada (nobu)
+ https://github.com/ruby/open3
+ https://rubygems.org/gems/open3
+[lib/open-uri.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/open-uri
[lib/ostruct.rb]
- Marc-Andre Lafortune (marcandre)
+ Marc-André Lafortune (marcandre)
+ https://github.com/ruby/ostruct
+ https://rubygems.org/gems/ostruct
[lib/pp.rb]
Tanaka Akira (akr)
+ https://github.com/ruby/pp
+ https://rubygems.org/gems/pp
[lib/prettyprint.rb]
Tanaka Akira (akr)
+ https://github.com/ruby/prettyprint
+ https://rubygems.org/gems/prettyprint
[lib/prime.rb]
- Yuki Sonoda (yugui)
-[lib/profile.rb]
- _unmaintained_
-[lib/profiler.rb]
- _unmaintained_
+ Marc-André Lafortune (marcandre)
+ https://github.com/ruby/prime
+ https://rubygems.org/gems/prime
[lib/pstore.rb]
_unmaintained_
-[lib/racc/*]
- Aaron Patterson (tenderlove)
-[lib/resolv-replace.rb]
- Tanaka Akira (akr)
+ https://github.com/ruby/pstore
+ https://rubygems.org/gems/pstore
+[lib/racc.rb, lib/racc/*]
+ Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/racc
+ https://rubygems.org/gems/racc
+[lib/readline.rb]
+ aycabta
+ https://github.com/ruby/readline
+ https://rubygems.org/gems/readline
[lib/resolv.rb]
Tanaka Akira (akr)
-[lib/rexml/*]
- Kouhei Sutou (kou)
+ https://github.com/ruby/resolv
+ https://rubygems.org/gems/resolv
+[lib/resolv-replace.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/resolv-replace
+ https://rubygems.org/gems/resolv-replace
+[lib/rdoc.rb, lib/rdoc/*]
+ Eric Hodel (drbrain), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/rdoc
+ https://rubygems.org/gems/rdoc
+[lib/reline.rb, lib/reline/*]
+ aycabta
+ https://github.com/ruby/reline
+ https://rubygems.org/gems/reline
[lib/rinda/*]
Masatoshi SEKI (seki)
-[lib/rss.rb, lib/rss/*]
- Kouhei Sutou (kou)
-[lib/rubygems.rb, lib/ubygems.rb, lib/rubygems/*]
- Eric Hodel (drbrain), Hiroshi SHIBATA (hsbt)
-[lib/set.rb]
- Akinori MUSHA (knu)
+ https://github.com/ruby/rinda
+ https://rubygems.org/gems/rinda
[lib/securerandom.rb]
Tanaka Akira (akr)
-[lib/shell.rb, lib/shell/*]
- Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/securerandom
+ https://rubygems.org/gems/securerandom
+[lib/set.rb]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/set
+ https://rubygems.org/gems/set
[lib/shellwords.rb]
Akinori MUSHA (knu)
+ https://github.com/ruby/shellwords
+ https://rubygems.org/gems/shellwords
[lib/singleton.rb]
Yukihiro Matsumoto (matz)
-[lib/sync.rb]
- Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/singleton
+ https://rubygems.org/gems/singleton
[lib/tempfile.rb]
_unmaintained_
-[lib/tmpdir.rb]
- _unmaintained_
-[lib/thwait.rb]
- Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/tempfile
+ https://rubygems.org/gems/tempfile
[lib/time.rb]
Tanaka Akira (akr)
+ https://github.com/ruby/time
+ https://rubygems.org/gems/time
[lib/timeout.rb]
Yukihiro Matsumoto (matz)
+ https://github.com/ruby/timeout
+ https://rubygems.org/gems/timeout
+[lib/thwait.rb]
+ Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/thwait
+ https://rubygems.org/gems/thwait
+[lib/tmpdir.rb]
+ _unmaintained_
+ https://github.com/ruby/tmpdir
+ https://rubygems.org/gems/tmpdir
[lib/tracer.rb]
Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/tracer
+ https://rubygems.org/gems/tracer
[lib/tsort.rb]
Tanaka Akira (akr)
+ https://github.com/ruby/tsort
+ https://rubygems.org/gems/tsort
[lib/un.rb]
WATANABE Hirofumi (eban)
-[lib/unicode_normalize.rb, lib/unicode_normalize/*]
- Martin J. Dürst
+ https://github.com/ruby/un
+ https://rubygems.org/gems/un
[lib/uri.rb, lib/uri/*]
YAMADA, Akira (akira)
-[lib/weakref.rb]
- _unmaintained_
+ https://github.com/ruby/uri
+ https://rubygems.org/gems/uri
[lib/yaml.rb, lib/yaml/*]
Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
-
-=== Extensions
-
-[ext/cgi]
- Nobuyoshi Nakada (nobu)
-[ext/continuation]
- Koichi Sasada (ko1)
-[ext/coverage]
- Yusuke Endoh (mame)
-[ext/digest, ext/digest/*]
- Akinori MUSHA (knu)
-[ext/fiber]
- Koichi Sasada (ko1)
-[ext/io/nonblock]
- Nobuyuki Nakada (nobu)
-[ext/io/wait]
- Nobuyuki Nakada (nobu)
-[ext/nkf]
- NARUSE, Yui (narse)
-[ext/objspace]
- _unmaintained_
-[ext/pathname]
- Tanaka Akira (akr)
-[ext/pty]
- _unmaintained_
-[ext/racc]
- Aaron Patterson (tenderlove)
-[ext/readline]
- TAKAO Kouji (kouji)
-[ext/ripper]
- _unmaintained_
-[ext/socket]
- * Tanaka Akira (akr)
- * API change needs matz's approval
-[ext/syslog]
- Akinori MUSHA (knu)
-[ext/win32]
- NAKAMURA Usaku (usa)
-[ext/win32ole]
- Masaki Suketa (suke)
-
-== Default gems Maintainers
-
-=== Libraries
-
-[lib/cmath.rb]
- _unmaintained_
-[lib/csv.rb]
- James Edward Gray II (jeg2)
-[lib/fileutils.rb]
+ https://github.com/ruby/yaml
+ https://rubygems.org/gems/yaml
+[lib/weakref.rb]
_unmaintained_
-[lib/rdoc.rb, lib/rdoc/*]
- Eric Hodel (drbrain), Hiroshi SHIBATA (hsbt)
- https://github.com/rdoc/rdoc
-[lib/scanf.rb]
- David A. Black (dblack)
-[lib/webrick.rb, lib/webrick/*]
- Eric Wong (normalperson)
- https://bugs.ruby-lang.org/
+ https://github.com/ruby/weakref
+ https://rubygems.org/gems/weakref
=== Extensions
[ext/bigdecimal]
Kenta Murata (mrkn)
https://github.com/ruby/bigdecimal
+ https://rubygems.org/gems/bigdecimal
+[ext/cgi]
+ Nobuyoshi Nakada (nobu)
+ https://github.com/ruby/cgi
+ https://rubygems.org/gems/cgi
[ext/date]
_unmaintained_
+ https://github.com/ruby/date
+ https://rubygems.org/gems/date
[ext/dbm]
_unmaintained_
+ https://github.com/ruby/dbm
+ https://rubygems.org/gems/dbm
[ext/etc]
- _unmaintained_
+ Ruby core team
+ https://github.com/ruby/etc
+ https://rubygems.org/gems/etc
[ext/fcntl]
- _unmaintained_
+ Ruby core team
+ https://github.com/ruby/fcntl
+ https://rubygems.org/gems/fcntl
[ext/fiddle]
Aaron Patterson (tenderlove)
+ https://github.com/ruby/fiddle
+ https://rubygems.org/gems/fiddle
[ext/gdbm]
Yukihiro Matsumoto (matz)
+ https://github.com/ruby/gdbm
+ https://rubygems.org/gems/gdbm
[ext/io/console]
Nobuyuki Nakada (nobu)
+ https://github.com/ruby/io-console
+ https://rubygems.org/gems/io-console
+[ext/io/nonblock]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/io-nonblock
+ https://rubygems.org/gems/io-nonblock
+[ext/io/wait]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/io-wait
+ https://rubygems.org/gems/io-wait
[ext/json]
NARUSE, Yui (naruse), Hiroshi SHIBATA (hsbt)
https://github.com/flori/json
+ https://rubygems.org/gems/json
+[ext/nkf]
+ NARUSE, Yui (naruse)
+ https://github.com/ruby/nkf
+ https://rubygems.org/gems/nkf
[ext/openssl]
Kazuki Yamaguchi (rhe)
https://github.com/ruby/openssl
+ https://rubygems.org/gems/openssl
+[ext/pathname]
+ Tanaka Akira (akr)
+ https://github.com/ruby/pathname
+ https://rubygems.org/gems/pathname
[ext/psych]
- Aaron Patterson (tenderlove), Hiroshi SHIBATA(hsbt)
+ Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
https://github.com/ruby/psych
-[ext/sdbm]
- Yukihiro Matsumoto (matz)
+ https://rubygems.org/gems/psych
+[ext/racc]
+ Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/racc
+ https://rubygems.org/gems/racc
+[ext/readline]
+ TAKAO Kouji (kouji)
+ https://github.com/ruby/readline-ext
+ https://rubygems.org/gems/readline-ext
[ext/stringio]
Nobuyuki Nakada (nobu)
+ https://github.com/ruby/stringio
+ https://rubygems.org/gems/stringio
[ext/strscan]
- _unmaintained_
+ Kouhei Sutou (kou)
+ https://github.com/ruby/strscan
+ https://rubygems.org/gems/strscan
+[ext/syslog]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/syslog
+ https://rubygems.org/gems/syslog
+[ext/win32ole]
+ Masaki Suketa (suke)
+ https://github.com/ruby/win32ole
+ https://rubygems.org/gems/win32ole
[ext/zlib]
- _unmaintained_
+ NARUSE, Yui (naruse)
+ https://github.com/ruby/zlib
+ https://rubygems.org/gems/zlib
== Bundled gems upstream repositories
-[did_you_mean]
- https://github.com/yuki24/did_you_mean
[minitest]
https://github.com/seattlerb/minitest
-[net-telnet]
- https://github.com/ruby/net-telnet
[power_assert]
- https://github.com/k-tsj/power_assert
+ https://github.com/ruby/power_assert
[rake]
https://github.com/ruby/rake
[test-unit]
https://github.com/test-unit/test-unit
-[xmlrpc]
- https://github.com/ruby/xmlrpc
+[rexml]
+ https://github.com/ruby/rexml
+[rss]
+ https://github.com/ruby/rss
+[rbs]
+ https://github.com/ruby/rbs
+[typeprof]
+ https://github.com/ruby/typeprof
diff --git a/doc/make_cheatsheet.md b/doc/make_cheatsheet.md
new file mode 100644
index 0000000000..bf245bea03
--- /dev/null
+++ b/doc/make_cheatsheet.md
@@ -0,0 +1,124 @@
+# How to use "configure" and "make" commands for Ruby
+
+This is for developers of Ruby.
+If you are a user of Ruby, please see README.md.
+
+## In-place build
+
+```
+$ autoconf
+$ ./configure --prefix=$PWD/local
+$ make
+$ make install
+$ ./local/bin/ruby -e 'puts "Hello"'
+Hello
+```
+
+## Out-of-place build
+
+```
+$ autoconf
+$ mkdir ../ruby-build
+$ cd ../ruby-build
+$ ../ruby-src/configure --prefix=$PWD/local
+$ make
+$ make install
+$ ./local/bin/ruby -e 'puts "Hello"'
+Hello
+```
+
+## How to run the whole test suite
+
+```
+$ make check
+```
+
+It runs (about) three test suites:
+
+* `make test` (a test suite for the interpreter core)
+* `make test-all` (for all builtin classes and libraries)
+* `make test-spec` (a conformance test suite for Ruby implementations)
+* `make test-bundler` (a test suite for the bundler examples)
+
+## How to run the test suite with log
+
+```
+$ make test OPTS=-v
+
+$ make test-all TESTS=-v
+
+$ make test-spec MSPECOPT=-Vfs
+```
+
+## How to run a part of the test suite
+
+### Runs a directory
+```
+$ make test-all TESTS=test/rubygems
+$ make test-all TESTS=rubygems
+```
+
+### Runs a file
+```
+$ make test-all TESTS=test/ruby/test_foo.rb
+$ make test-all TESTS=ruby/foo
+```
+
+### Runs a test whose name includes test_bar
+```
+$ make test-all TESTS="test/ruby/test_foo.rb -n /test_bar/"
+```
+
+### Runs a file or directory with GNU make
+```
+$ make test/ruby/test_foo.rb
+$ make test/ruby/test_foo.rb TESTOPTS="-n /test_bar/"
+```
+
+### Runs a ruby-spec directory
+```
+$ make test-spec MSPECOPT=spec/ruby/core/foo
+```
+
+### Runs a ruby-spec file
+```
+$ make test-spec MSPECOPT=spec/ruby/core/foo/bar_spec.rb
+```
+
+### Runs a ruby-spec file or directory with GNU make
+```
+$ make spec/ruby/core/foo/bar_spec.rb
+```
+
+### Runs a bundler spec file
+```
+$ make test-bundler BUNDLER_SPECS=commands/exec_spec.rb:58
+```
+
+## How to measure coverage of C and Ruby code
+
+You need to be able to use gcc (gcov) and lcov visualizer.
+
+```
+$ autoconf
+$ ./configure --enable-gcov
+$ make
+$ make update-coverage
+$ rm -f test-coverage.dat
+$ make test-all COVERAGE=true
+$ make lcov
+$ open lcov-out/index.html
+```
+
+If you need only C code coverage, you can remove `COVERAGE=true` from the above process.
+You can also use `gcov` command directly to get per-file coverage.
+
+If you need only Ruby code coverage, you can remove `--enable-gcov`.
+Note that `test-coverage.dat` accumulates all runs of `make test-all`.
+Make sure that you remove the file if you want to measure one test run.
+
+You can see the coverage result of CI: https://rubyci.org/coverage
+
+## How to benchmark
+
+see https://github.com/ruby/ruby/tree/master/benchmark#make-benchmark
diff --git a/doc/marshal.rdoc b/doc/marshal.rdoc
index a51f1bf873..78a3d29d4a 100644
--- a/doc/marshal.rdoc
+++ b/doc/marshal.rdoc
@@ -73,7 +73,7 @@ The first byte has the following special values:
a positive little-endian integer.
"\xfd"::
- The total size of the integer is two bytes. The following three bytes are a
+ The total size of the integer is four bytes. The following three bytes are a
negative little-endian integer.
"\x04"::
diff --git a/doc/memory_view.md b/doc/memory_view.md
new file mode 100644
index 0000000000..646a35423a
--- /dev/null
+++ b/doc/memory_view.md
@@ -0,0 +1,167 @@
+# MemoryView
+
+MemoryView provides the features to share multidimensional homogeneous arrays of
+fixed-size element on memory among extension libraries.
+
+## Disclaimer
+
+* This feature is still experimental. The specification described here can be changed in the future.
+
+* This document is under construction. Please refer the master branch of ruby for the latest version of this document.
+
+## Overview
+
+We sometimes deal with certain kinds of objects that have arrays of the same typed fixed-size elements on a contiguous memory area as its internal representation.
+Numo::NArray in numo-narray and Magick::Image in rmagick are typical examples of such objects.
+MemoryView plays the role of the hub to share the internal data of such objects without copy among such libraries.
+
+Copy-less sharing of data is very important in some field such as data analysis, machine learning, and image processing. In these field, people need to handle large amount of on-memory data with several libraries. If we are forced to copy to exchange large data among libraries, a large amount of the data processing time must be occupied by copying data. You can avoid such wasting time by using MemoryView.
+
+MemoryView has two categories of APIs:
+
+1. Producer API
+
+ Classes can register own MemoryView entry which allows objects of that classes to expose their MemoryView
+
+2. Consumer API
+
+ Consumer API allows us to obtain and manage the MemoryView of an object
+
+## MemoryView structure
+
+A MemoryView structure, `rb_memory_view_t`, is used for exporting objects' MemoryView.
+This structure contains the reference of the object, which is the owner of the MemoryView, the pointer to the head of exported memory, and the metadata that describes the structure of the memory. The metadata can describe multidimensional arrays with strides.
+
+### The member of MemoryView structure
+
+The MemoryView structure consists of the following members.
+
+- `VALUE obj`
+
+ The reference to the original object that has the memory exported via the MemoryView.
+
+ RubyVM manages the reference count of the MemoryView-exported objects to guard them from the garbage collection. The consumers do not have to struggle to guard this object from GC.
+
+- `void *data`
+
+ The pointer to the head of the exported memory.
+
+- `ssize_t byte_size`
+
+ The numbero f bytes in the memory pointed by `data`.
+
+- `bool readonly`
+
+ `true` for readonly memory, `false` for writable memory.
+
+- `const char *format`
+
+ A string to describeth e format of an element, or NULL for unsigned byte.
+
+- `ssize_t item_size`
+
+ The number of bytes in each element.
+
+- `const rb_memory_view_item_component_t *item_desc.components`
+
+ The array of the metadata of the component in an element.
+
+- `size_t item_desc.length`
+
+ The number of items in `item_desc.components`.
+
+- `ssize_t ndim`
+
+ The number of dimensions.
+
+- `const ssize_t *shape`
+
+ A `ndim` size array indicating the number of elements in each dimension.
+ This can be `NULL` when `ndim` is 1.
+
+- `const ssize_t *strides`
+
+ A `ndim` size array indicating the number of bytes to skip to go to the next element in each dimension.
+ This can be `NULL` when `ndim` is 1.
+
+- `const ssize_t *sub_offsets`
+
+ A `ndim` size array consisting of the offsets in each dimension when the MemoryView exposes a nested array.
+ This can be `NULL` when the MemoryView exposes a flat array.
+
+- `void *const private`
+
+ The private data that MemoryView provider uses internally.
+ This can be `NULL` when any private data is unnecessary.
+
+## MemoryView APIs
+
+### For consumers
+
+- `bool rb_memory_view_available_p(VALUE obj)`
+
+ Return `true` if `obj` supports to export a MemoryView. Return `false` otherwise.
+
+ If this function returns `true`, it doesn't mean the function `rb_memory_view_get` will succeed.
+
+- `bool rb_memory_view_get(VALUE obj, rb_memory_view_t *view, int flags)`
+
+ If the given `obj` supports to export a MemoryView that conforms the given `flags`, this function fills `view` by the information of the MemoryView and returns `true`. In this case, the reference count of `obj` is increased.
+
+ If the given combination of `obj` and `flags` cannot export a MemoryView, this function returns `false`. The content of `view` is not touched in this case.
+
+ The exported MemoryView must be released by `rb_memory_view_release` when the MemoryView is no longer needed.
+
+- `bool rb_memory_view_release(rb_memory_view_t *view)`
+
+ Release the given MemoryView `view` and decrement the reference count of `view->obj`.
+
+ Consumers must call this function when the MemoryView is no longer needed. Missing to call this function leads memory leak.
+
+- `ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err)`
+
+ Calculate the number of bytes occupied by an element.
+
+ When the calculation fails, the failed location in `format` is stored into `err`, and returns `-1`.
+
+- `void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices)`
+
+ Calculate the location of the item indicated by the given `indices`.
+ The length of `indices` must equal to `view->ndim`.
+ This function initializes `view->item_desc` if needed.
+
+- `VALUE rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices)`
+
+ Return the Ruby object representation of the item indicated by the given `indices`.
+ The length of `indices` must equal to `view->ndim`.
+ This function uses `rb_memory_view_get_item_pointer`.
+
+- `rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly)`
+
+ Fill the members of `view` as an 1-dimensional byte array.
+
+- `void rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides)`
+
+ Fill the `strides` array with byte-Strides of a contiguous array of the given shape with the given element size.
+
+- `void rb_memory_view_prepare_item_desc(rb_memory_view_t *view)`
+
+ Fill the `item_desc` member of `view`.
+
+- `bool rb_memory_view_is_contiguous(const rb_memory_view_t *view)`
+
+ Return `true` if the data in the MemoryView `view` is row-major or column-major contiguous.
+
+ Return `false` otherwise.
+
+- `bool rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view)`
+
+ Return `true` if the data in the MemoryView `view` is row-major contiguous.
+
+ Return `false` otherwise.
+
+- `bool rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view)`
+
+ Return `true` if the data in the MemoryView `view` is column-major contiguous.
+
+ Return `false` otherwise.
diff --git a/doc/method_documentation.rdoc b/doc/method_documentation.rdoc
new file mode 100644
index 0000000000..0432216868
--- /dev/null
+++ b/doc/method_documentation.rdoc
@@ -0,0 +1,183 @@
+= Method Documentation Guide
+
+This guide discusses recommendations for documenting methods for Ruby core
+classes and classes in the standard library.
+
+== Goal
+
+The goal when documenting a method is to impart the most important
+information about the method in the least amount of time. A reader
+of the method documentation should be able to quickly understand
+the purpose of the method and how to use it. Providing too little
+information about the method is not good, but providing unimportant
+information or unnecessary examples is not good either. Use your
+judgment about what the user of the method needs to know to use the
+method correctly.
+
+== General Structure
+
+The general structure of the method documentation should be:
+
+* call-seq (for methods written in C)
+* Synopsis (Short Description)
+* Details and Examples
+* Argument Description (if necessary)
+* Corner Cases and Exceptions
+* Aliases
+* Related Methods (optional)
+
+== call-seq (for methods written in C)
+
+For methods written in C, RDoc cannot determine what arguments
+the method accepts, so those need to be documented using a
+<tt>call-seq</tt>. Here's an example <tt>call-seq</tt>:
+
+ * call-seq:
+ * array.count -> integer
+ * array.count(obj) -> integer
+ * array.count {|element| ... } -> integer
+
+When creating the <tt>call-seq</tt>, use the form
+
+ receiver_type.method_name(arguments) {|block_arguments|} -> return_type
+
+Omit the parentheses for cases where the method does not accept arguments,
+and omit the block for cases where a block is not accepted.
+
+In the cases where method can return multiple different types, separate the
+types with "or". If the method can return any type, use "object". If the
+method returns the receiver, use "self".
+
+In cases where the method accepts optional arguments, use a <tt>call-seq</tt>
+with an optional argument if the method has the same behavior when an argument
+is omitted as when the argument is passed with the default value. For example,
+use:
+
+ * obj.respond_to?(symbol, include_all=false) -> true or false
+
+Instead of:
+
+ * obj.respond_to?(symbol) -> true or false
+ * obj.respond_to?(symbol, include_all) -> true or false
+
+However, as shown above for <tt>Array#count</tt>, use separate lines if the
+behavior is different if the argument is omitted.
+
+Omit aliases from the call-seq.
+
+== Synopsis
+
+The synopsis comes next, and is a short description of what the
+method does and why you would want to use it. Ideally, this
+is a single sentence, but for more complex methods it may require
+an entire paragraph.
+
+For <tt>Array#count</tt>, the synopsis is:
+
+ Returns a count of specified elements.
+
+This is great as it is short and descriptive. Avoid documenting
+too much in the synopsis, stick to the most important information
+for the benefit of the reader.
+
+== Details and Examples
+
+Most non-trivial methods benefit from examples, as well as details
+beyond what is given in the synopsis. In the details and examples
+section, you can document how the method handles different types
+of arguments, and provides examples on proper usage. In this
+section, focus on how to use the method properly, not on how the
+method handles improper arguments or corner cases.
+
+Not every behavior of a method requires an example. If the method
+is documented to return +self+, you don't need to provide an example
+showing the return value is the same as the receiver. If the method
+is documented to return +nil+, you don't need to provide an example
+showing that it returns +nil+. If the details mention that for a
+certain argument type, an empty array is returned, you don't need
+to provide an example for that.
+
+Only add an example if it provides the user additional information,
+do not add an example if it provides the same information given
+in the synopsis or details. The purpose of examples is not to prove
+what the details are stating.
+
+== Argument Description (if necessary)
+
+For methods that require arguments, if not obvious and not explicitly
+mentioned in the details or implicitly shown in the examples, you can
+provide details about the types of arguments supported. When discussing
+the types of arguments, use simple language even if less-precise, such
+as "level must be an integer", not "level must be an Integer-convertible
+object". The vast majority of use will be with the expected type, not an
+argument that is explicitly convertible to the expected type, and
+documenting the difference is not important.
+
+For methods that take blocks, it can be useful to document the type of
+argument passed if it is not obvious, not explicitly mentioned in the
+details, and not implicitly shown in the examples.
+
+If there is more than one argument or block argument, use an RDoc
+definition list:
+
+argument_name1 :: type and description
+argument_name2 :: type and description
+
+== Corner Cases and Exceptions
+
+For corner cases of methods, such as atypical usage, briefly mention
+the behavior, but do not provide any examples.
+
+Only document exceptions raised if they are not obvious. For example,
+if you have stated earlier than an argument type must be an integer,
+you do not need to document that a TypeError is raised if a non-integer
+is passed. Do not provide examples of exceptions being raised unless
+that is a common case, such as Hash#fetch raising KeyError.
+
+== Aliases
+
+Mention aliases in the form "Array#find_index is an alias for Array#index."
+
+== Related Methods (optional)
+
+In some cases, it is useful to document which methods are related to
+the current method. For example, documentation for Hash#[] might
+mention Hash#fetch as a related method, and Hash#merge might mention
+#merge! as a related method. Consider which methods may be related
+to the current method, and if you think the reader would benefit it,
+at the end of the method documentation, add a line starting with
+"Related: " (e.g. "Related: #fetch"). Don't list more than three
+related methods. If you think more than three methods are related,
+pick the three you think are most important and list those three.
+
+== Methods Accepting Multiple Argument Types
+
+For methods that accept multiple argument types, in some cases it can
+be useful to document the different argument types separately. It's
+best to use a separate paragraph for each case you are discussing.
+
+== Use of English
+
+Readers of this documentation may not be native speakers of English.
+Documentation should be written with this in mind.
+
+Use short sentences and group them into paragraphs that cover a single
+topic. Avoid complex verb tenses, excessive comma-separated phrases,
+and idioms.
+
+When writing documentation, define unusual or critical concepts in
+simple language. Provide links to authoritative sources, or add a
+general description to the top-level documentation for the class or
+module.
+
+== Formatting
+
+Extraneous formatting such as headings and horizontal lines should be
+avoided in general. It is best to keep the formatting as simple as
+possible. Only use headings and other formatting for the most complex
+cases where the method documentation is very long due to the complexity
+of the method.
+
+Methods are documented using RDoc syntax. See the
+{RDoc Markup Reference}[https://docs.ruby-lang.org/en/master/RDoc/Markup.html#class-RDoc::Markup-label-RDoc+Markup+Reference]
+for more information on formatting with RDoc syntax.
diff --git a/doc/ractor.md b/doc/ractor.md
new file mode 100644
index 0000000000..0ca36326ab
--- /dev/null
+++ b/doc/ractor.md
@@ -0,0 +1,931 @@
+# Ractor - Ruby's Actor-like concurrent abstraction
+
+Ractor is designed to provide a parallel execution feature of Ruby without thread-safety concerns.
+
+## Summary
+
+### Multiple Ractors in an interpreter process
+
+You can make multiple Ractors and they run in parallel.
+
+* `Ractor.new{ expr }` creates a new Ractor and `expr` is run in parallel on a parallel computer.
+* Interpreter invokes with the first Ractor (called *main Ractor*).
+* If main Ractor terminated, all Ractors receive terminate request like Threads (if main thread (first invoked Thread), Ruby interpreter sends all running threads to terminate execution).
+* Each Ractor has 1 or more Threads.
+ * Threads in a Ractor shares a Ractor-wide global lock like GIL (GVL in MRI terminology), so they can't run in parallel (without releasing GVL explicitly in C-level). Threads in different ractors run in parallel.
+ * The overhead of creating a Ractor is similar to overhead of one Thread creation.
+
+### Limited sharing between multiple ractors
+
+Ractors don't share everything, unlike threads.
+
+* Most objects are *Unshareable objects*, so you don't need to care about thread-safety problem which is caused by sharing.
+* Some objects are *Shareable objects*.
+ * Immutable objects: frozen objects which don't refer to unshareable-objects.
+ * `i = 123`: `i` is an immutable object.
+ * `s = "str".freeze`: `s` is an immutable object.
+ * `a = [1, [2], 3].freeze`: `a` is not an immutable object because `a` refers unshareable-object `[2]` (which is not frozen).
+ * `h = {c: Object}.freeze`: `h` is an immutable object because `h` refers Symbol `:c` and shareable `Object` class object which is not frozen.
+ * Class/Module objects
+ * Special shareable objects
+ * Ractor object itself.
+ * And more...
+
+### Two-types communication between Ractors
+
+Ractors communicate with each other and synchronize the execution by message exchanging between Ractors. There are two message exchange protocols: push type (message passing) and pull type.
+
+* Push type message passing: `Ractor#send(obj)` and `Ractor.receive()` pair.
+ * Sender ractor passes the `obj` to the ractor `r` by `r.send(obj)` and receiver ractor receives the message with `Ractor.receive`.
+ * Sender knows the destination Ractor `r` and the receiver does not know the sender (accept all message from any ractors).
+ * Receiver has infinite queue and sender enqueues the message. Sender doesn't block to put message into this queue.
+ * This type message exchangin is employed by many other Actor-based language.
+ * `Ractor.receive_if{ filter_expr }` is a variant of `Ractor.receive` to select a message.
+* Pull type communication: `Ractor.yield(obj)` and `Ractor#take()` pair.
+ * Sender ractor declare to yield the `obj` by `Ractor.yield(obj)` and receiver Ractor take it with `r.take`.
+ * Sender doesn't know a destination Ractor and receiver knows the sender Ractor `r`.
+ * Sender or receiver will block if there is no other side.
+
+### Copy & Move semantics to send messages
+
+To send unshareable objects as messages, objects are copied or moved.
+
+* Copy: use deep-copy.
+* Move: move membership.
+ * Sender can not access the moved object after moving the object.
+ * Guarantee that at least only 1 Ractor can access the object.
+
+### Thread-safety
+
+Ractor helps to write a thread-safe concurrent program, but we can make thread-unsafe programs with Ractors.
+
+* GOOD: Sharing limitation
+ * Most objects are unshareable, so we can't make data-racy and race-conditional programs.
+ * Shareable objects are protected by an interpreter or locking mechanism.
+* BAD: Class/Module can violate this assumption
+ * To make it compatible with old behavior, classes and modules can introduce data-race and so on.
+ * Ruby programmers should take care if they modify class/module objects on multi Ractor programs.
+* BAD: Ractor can't solve all thread-safety problems
+ * There are several blocking operations (waiting send, waiting yield and waiting take) so you can make a program which has dead-lock and live-lock issues.
+ * Some kind of shareable objects can introduce transactions (STM, for example). However, misusing transactions will generate inconsistent state.
+
+Without Ractor, we need to trace all of state-mutations to debug thread-safety issues.
+With Ractor, you can concentrate to suspicious code which are shared with Ractors.
+
+## Creation and termination
+
+### `Ractor.new`
+
+* `Ractor.new{ expr }` generates another Ractor.
+
+```ruby
+# Ractor.new with a block creates new Ractor
+r = Ractor.new do
+ # This block will be run in parallel with other ractors
+end
+
+# You can name a Ractor with `name:` argument.
+r = Ractor.new name: 'test-name' do
+end
+
+# and Ractor#name returns its name.
+r.name #=> 'test-name'
+```
+
+### Given block isolation
+
+The Ractor execute given `expr` in a given block.
+Given block will be isolated from outer scope by `Proc#isolate`. To prevent sharing unshareable objects between ractors, block outer-variables, `self` and other information are isolated.
+
+Given block will be isolated by `Proc#isolate` method (not exposed yet for Ruby users). `Proc#isolate` is called at Ractor creation timing (`Ractor.new` is called). If given Proc object is not enable to isolate because of outer variables and so on, an error will be raised.
+
+```ruby
+begin
+ a = true
+ r = Ractor.new do
+ a #=> ArgumentError because this block accesses `a`.
+ end
+ r.take # see later
+rescue ArgumentError
+end
+```
+
+* The `self` of the given block is `Ractor` object itself.
+
+```ruby
+r = Ractor.new do
+ p self.class #=> Ractor
+ self.object_id
+end
+r.take == self.object_id #=> false
+```
+
+Passed arguments to `Ractor.new()` becomes block parameters for the given block. However, an interpreter does not pass the parameter object references, but send them as messages (see below for details).
+
+```ruby
+r = Ractor.new 'ok' do |msg|
+ msg #=> 'ok'
+end
+r.take #=> 'ok'
+```
+
+```ruby
+# almost similar to the last example
+r = Ractor.new do
+ msg = Ractor.receive
+ msg
+end
+r.send 'ok'
+r.take #=> 'ok'
+```
+
+### An execution result of given block
+
+Return value of the given block becomes an outgoing message (see below for details).
+
+```ruby
+r = Ractor.new do
+ 'ok'
+end
+r.take #=> `ok`
+```
+
+```ruby
+# almost similar to the last example
+r = Ractor.new do
+ Ractor.yield 'ok'
+end
+r.take #=> 'ok'
+```
+
+Error in the given block will be propagated to the receiver of an outgoing message.
+
+```ruby
+r = Ractor.new do
+ raise 'ok' # exception will be transferred to the receiver
+end
+
+begin
+ r.take
+rescue Ractor::RemoteError => e
+ e.cause.class #=> RuntimeError
+ e.cause.message #=> 'ok'
+ e.ractor #=> r
+end
+```
+
+## Communication between Ractors
+
+Communication between Ractors is achieved by sending and receiving messages. There is two way to communicate each other.
+
+* (1) Message sending/receiving
+ * (1-1) push type send/receive (sender knows receiver). similar to the Actor model.
+ * (1-2) pull type yield/take (receiver knows sender).
+* (2) Using shareable container objects
+ * Ractor::TVar gem ([ko1/ractor-tvar](https://github.com/ko1/ractor-tvar))
+ * more?
+
+Users can control program execution timing with (1), but should not control with (2) (only manage as critical section).
+
+For message sending and receiving, there are two types APIs: push type and pull type.
+
+* (1-1) send/receive (push type)
+ * `Ractor#send(obj)` (`Ractor#<<(obj)` is an aliases) send a message to the Ractor's incoming port. Incoming port is connected to the infinite size incoming queue so `Ractor#send` will never block.
+ * `Ractor.receive` dequeue a message from its own incoming queue. If the incoming queue is empty, `Ractor.receive` calling will block.
+ * `Ractor.receive_if{|msg| filter_expr }` is variant of `Ractor.receive`. `receive_if` only receives a message which `filter_expr` is true (So `Ractor.receive` is same as `Ractor.receive_if{ true }`.
+* (1-2) yield/take (pull type)
+ * `Ractor.yield(obj)` send an message to a Ractor which are calling `Ractor#take` via outgoing port . If no Ractors are waiting for it, the `Ractor.yield(obj)` will block. If multiple Ractors are waiting for `Ractor.yield(obj)`, only one Ractor can receive the message.
+ * `Ractor#take` receives a message which is waiting by `Ractor.yield(obj)` method from the specified Ractor. If the Ractor does not call `Ractor.yield` yet, the `Ractor#take` call will block.
+* `Ractor.select()` can wait for the success of `take`, `yield` and `receive`.
+* You can close the incoming port or outgoing port.
+ * You can close then with `Ractor#close_incoming` and `Ractor#close_outgoing`.
+ * If the incoming port is closed for a Ractor, you can't `send` to the Ractor. If `Ractor.receive` is blocked for the closed incoming port, then it will raise an exception.
+ * If the outgoing port is closed for a Ractor, you can't call `Ractor#take` and `Ractor.yield` on the Ractor. If ractors are blocking by `Ractor#take` or `Ractor.yield`, closing outgoing port will raise an exception on these blocking ractors.
+ * When a Ractor is terminated, the Ractor's ports are closed.
+* There are 3 way to send an object as a message
+ * (1) Send a reference: Sending a shareable object, send only a reference to the object (fast)
+ * (2) Copy an object: Sending an unshareable object by copying an object deeply (slow). Note that you can not send an object which is not support deep copy. Some `T_DATA` objects are not supported.
+ * (3) Move an object: Sending an unshareable object reference with a membership. Sender Ractor can not access moved objects anymore (raise an exception) after moving it. Current implementation makes new object as a moved object for receiver Ractor and copy references of sending object to moved object.
+ * You can choose "Copy" and "Move" by the `move:` keyword, `Ractor#send(obj, move: true/false)` and `Ractor.yield(obj, move: true/false)` (default is `false` (COPY)).
+
+### Sending/Receiving ports
+
+Each Ractor has _incoming-port_ and _outgoing-port_. Incoming-port is connected to the infinite sized incoming queue.
+
+```
+ Ractor r
+ +-------------------------------------------+
+ | incoming outgoing |
+ | port port |
+ r.send(obj) ->*->[incoming queue] Ractor.yield(obj) ->*-> r.take
+ | | |
+ | v |
+ | Ractor.receive |
+ +-------------------------------------------+
+
+
+Connection example: r2.send obj on r1ã€Ractor.receive on r2
+ +----+ +----+
+ * r1 |---->* r2 *
+ +----+ +----+
+
+
+Connection example: Ractor.yield(obj) on r1, r1.take on r2
+ +----+ +----+
+ * r1 *---->- r2 *
+ +----+ +----+
+
+Connection example: Ractor.yield(obj) on r1 and r2,
+ and waiting for both simultaneously by Ractor.select(r1, r2)
+
+ +----+
+ * r1 *------+
+ +----+ |
+ +----> Ractor.select(r1, r2)
+ +----+ |
+ * r2 *------|
+ +----+
+```
+
+```ruby
+ r = Ractor.new do
+ msg = Ractor.receive # Receive from r's incoming queue
+ msg # send back msg as block return value
+ end
+ r.send 'ok' # Send 'ok' to r's incoming port -> incoming queue
+ r.take # Receive from r's outgoing port
+```
+
+The last example shows the following ractor network.
+
+```
+
+ +------+ +---+
+ * main |------> * r *---+
+ +-----+ +---+ |
+ ^ |
+ +-------------------+
+```
+
+And this code can be rewrite more simple way by using an argument for `Ractor.new`.
+
+```ruby
+ # Actual argument 'ok' for `Ractor.new()` will be send to created Ractor.
+ r = Ractor.new 'ok' do |msg|
+ # Values for formal parameters will be received from incoming queue.
+ # Similar to: msg = Ractor.receive
+
+ msg # Return value of the given block will be sent via outgoing port
+ end
+
+ # receive from the r's outgoing port.
+ r.take #=> `ok`
+```
+
+### Return value of a block for `Ractor.new`
+
+As already explained, the return value of `Ractor.new` (an evaluated value of `expr` in `Ractor.new{ expr }`) can be taken by `Ractor#take`.
+
+```ruby
+Ractor.new{ 42 }.take #=> 42
+```
+
+When the block return value is available, the Ractor is dead so that no ractors except taken Ractor can touch the return value, so any values can be sent with this communication path without any modification.
+
+```ruby
+r = Ractor.new do
+ a = "hello"
+ binding
+end
+
+r.take.eval("p a") #=> "hello" (other communication path can not send a Binding object directly)
+```
+
+### Wait for multiple Ractors with `Ractor.select`
+
+You can wait multiple Ractor's `yield` with `Ractor.select(*ractors)`.
+The return value of `Ractor.select()` is `[r, msg]` where `r` is yielding Ractor and `msg` is yielded message.
+
+Wait for a single ractor (same as `Ractor.take`):
+
+```ruby
+r1 = Ractor.new{'r1'}
+
+r, obj = Ractor.select(r1)
+r == r1 and obj == 'r1' #=> true
+```
+
+Wait for two ractors:
+
+```ruby
+r1 = Ractor.new{'r1'}
+r2 = Ractor.new{'r2'}
+rs = [r1, r2]
+as = []
+
+# Wait for r1 or r2's Ractor.yield
+r, obj = Ractor.select(*rs)
+rs.delete(r)
+as << obj
+
+# Second try (rs only contain not-closed ractors)
+r, obj = Ractor.select(*rs)
+rs.delete(r)
+as << obj
+as.sort == ['r1', 'r2'] #=> true
+```
+
+Complex example:
+
+```ruby
+ pipe = Ractor.new do
+ loop do
+ Ractor.yield Ractor.receive
+ end
+ end
+
+ RN = 10
+ rs = RN.times.map{|i|
+ Ractor.new pipe, i do |pipe, i|
+ msg = pipe.take
+ msg # ping-pong
+ end
+ }
+ RN.times{|i|
+ pipe << i
+ }
+ RN.times.map{
+ r, n = Ractor.select(*rs)
+ rs.delete r
+ n
+ }.sort #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+```
+
+Multiple Ractors can send to one Ractor.
+
+```ruby
+# Create 10 ractors and they send objects to pipe ractor.
+# pipe ractor yield received objects
+
+ pipe = Ractor.new do
+ loop do
+ Ractor.yield Ractor.receive
+ end
+ end
+
+ RN = 10
+ rs = RN.times.map{|i|
+ Ractor.new pipe, i do |pipe, i|
+ pipe << i
+ end
+ }
+
+ RN.times.map{
+ pipe.take
+ }.sort #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+```
+
+TODO: Current `Ractor.select()` has the same issue of `select(2)`, so this interface should be refined.
+
+TODO: `select` syntax of go-language uses round-robin technique to make fair scheduling. Now `Ractor.select()` doesn't use it.
+
+### Closing Ractor's ports
+
+* `Ractor#close_incoming/outgoing` close incoming/outgoing ports (similar to `Queue#close`).
+* `Ractor#close_incoming`
+ * `r.send(obj) ` where `r`'s incoming port is closed, will raise an exception.
+ * When the incoming queue is empty and incoming port is closed, `Ractor.receive` raise an exception. If the incoming queue is not empty, it dequeues an object without exceptions.
+* `Ractor#close_outgoing`
+ * `Ractor.yield` on a Ractor which closed the outgoing port, it will raise an exception.
+ * `Ractor#take` for a Ractor which closed the outgoing port, it will raise an exception. If `Ractor#take` is blocking, it will raise an exception.
+* When a Ractor terminates, the ports are closed automatically.
+ * Return value of the Ractor's block will be yielded as `Ractor.yield(ret_val)`, even if the implementation terminates the based native thread.
+
+Example (try to take from closed Ractor):
+
+```ruby
+ r = Ractor.new do
+ 'finish'
+ end
+ r.take # success (will return 'finish')
+ begin
+ o = r.take # try to take from closed Ractor
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ "ng: #{o}"
+ end
+```
+
+Example (try to send to closed (terminated) Ractor):
+
+```ruby
+ r = Ractor.new do
+ end
+
+ r.take # wait terminate
+
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+```
+
+When multiple Ractors waiting for `Ractor.yield()`, `Ractor#close_outgoing` will cancel all blocking by raise an exception (`ClosedError`).
+
+### Send a message by copying
+
+`Ractor#send(obj)` or `Ractor.yield(obj)` copy `obj` deeply if `obj` is an unshareable object.
+
+```ruby
+obj = 'str'.dup
+r = Ractor.new obj do |msg|
+ # return received msg's object_id
+ msg.object_id
+end
+
+obj.object_id == r.take #=> false
+```
+
+Some objects are not supported to copy the value, and raise an exception.
+
+```ruby
+obj = Thread.new{}
+begin
+ Ractor.new obj do |msg|
+ msg
+ end
+rescue TypeError => e
+ e.message #=> #<TypeError: allocator undefined for Thread>
+else
+ 'ng' # unreachable here
+end
+```
+
+### Send a message by moving
+
+`Ractor#send(obj, move: true)` or `Ractor.yield(obj, move: true)` move `obj` to the destination Ractor.
+If the source Ractor touches the moved object (for example, call the method like `obj.foo()`), it will be an error.
+
+```ruby
+# move with Ractor#send
+r = Ractor.new do
+ obj = Ractor.receive
+ obj << ' world'
+end
+
+str = 'hello'
+r.send str, move: true
+modified = r.take #=> 'hello world'
+
+# str is moved, and accessing str from this Ractor is prohibited
+
+begin
+ # Error because it touches moved str.
+ str << ' exception' # raise Ractor::MovedError
+rescue Ractor::MovedError
+ modified #=> 'hello world'
+else
+ raise 'unreachable'
+end
+```
+
+```ruby
+ # move with Ractor.yield
+ r = Ractor.new do
+ obj = 'hello'
+ Ractor.yield obj, move: true
+ obj << 'world' # raise Ractor::MovedError
+ end
+
+ str = r.take
+ begin
+ r.take
+ rescue Ractor::RemoteError
+ p str #=> "hello"
+ end
+```
+
+Some objects are not supported to move, and an exception will be raise.
+
+```ruby
+r = Ractor.new do
+ Ractor.receive
+end
+
+r.send(Thread.new{}, move: true) #=> allocator undefined for Thread (TypeError)
+```
+
+To achieve the access prohibition for moved objects, _class replacement_ technique is used to implement it.
+
+### Shareable objects
+
+The following objects are shareable.
+
+* Immutable objects
+ * Small integers, some symbols, `true`, `false`, `nil` (a.k.a. `SPECIAL_CONST_P()` objects in internal)
+ * Frozen native objects
+ * Numeric objects: `Float`, `Complex`, `Rational`, big integers (`T_BIGNUM` in internal)
+ * All Symbols.
+ * Frozen `String` and `Regexp` objects (their instance variables should refer only sharble objects)
+* Class, Module objects (`T_CLASS`, `T_MODULE` and `T_ICLASS` in internal)
+* `Ractor` and other special objects which care about synchronization.
+
+Implementation: Now shareable objects (`RVALUE`) have `FL_SHAREABLE` flag. This flag can be added lazily.
+
+To make sharable objects, `Ractor.make_shareable(obj)` method is provided. In this case, try to make sharaeble by freezing `obj` and recursively travasible objects. This method accepts `copy:` keyword (default value is false).`Ractor.make_sharable(obj, copy: true)` tries to make a deep copy of `obj` and make the copied object sharable.
+
+## Language changes to isolate unshareable objects between Ractors
+
+To isolate unshareable objects between Ractors, we introduced additional language semantics on multi-Ractor Ruby programs.
+
+Note that without using Ractors, these additional semantics is not needed (100% compatible with Ruby 2).
+
+### Global variables
+
+Only the main Ractor (a Ractor created at starting of interpreter) can access global variables.
+
+```ruby
+ $gv = 1
+ r = Ractor.new do
+ $gv
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message #=> 'can not access global variables from non-main Ractors'
+ end
+```
+
+Note that some special global variables are ractor-local, like `$stdin`, `$stdout`, `$stderr`. See [[Bug #17268]](https://bugs.ruby-lang.org/issues/17268) for more details.
+
+### Instance variables of shareable objects
+
+Only the main Ractor can access instance variables of shareable objects.
+
+```ruby
+ class C
+ @iv = 'str'
+ end
+
+ r = Ractor.new do
+ class C
+ p @iv
+ end
+ end
+
+
+ begin
+ r.take
+ rescue => e
+ e.class #=> Ractor::IsolationError
+ end
+```
+
+```ruby
+ shared = Ractor.new{}
+ shared.instance_variable_set(:@iv, 'str')
+
+ r = Ractor.new shared do |shared|
+ p shared.instance_variable_get(:@iv)
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message #=> can not access instance variables of shareable objects from non-main Ractors (Ractor::IsolationError)
+ end
+```
+
+Note that instance variables for class/module objects are also prohibited on Ractors.
+
+### Class variables
+
+Only the main Ractor can access class variables.
+
+```ruby
+ class C
+ @@cv = 'str'
+ end
+
+ r = Ractor.new do
+ class C
+ p @@cv
+ end
+ end
+
+
+ begin
+ r.take
+ rescue => e
+ e.class #=> Ractor::IsolationError
+ end
+```
+
+### Constants
+
+Only the main Ractor can read constants which refer to the unshareable object.
+
+```ruby
+ class C
+ CONST = 'str'
+ end
+ r = Ractor.new do
+ C::CONST
+ end
+ begin
+ r.take
+ rescue => e
+ e.class #=> Ractor::IsolationError
+ end
+```
+
+Only the main Ractor can define constants which refer to the unshareable object.
+
+```ruby
+ class C
+ end
+ r = Ractor.new do
+ C::CONST = 'str'
+ end
+ begin
+ r.take
+ rescue => e
+ e.class #=> Ractor::IsolationError
+ end
+```
+
+To make multi-ractor supported library, the constants should only refer sharable objects.
+
+```ruby
+TABLE = {a: 'ko1', b: 'ko2', c: 'ko3'}
+```
+
+In this case, `TABLE` reference an unsharable Hash object. So that other ractors can not refer `TABLE` constant. To make it shareable, we can use `Ractor.make_sharable()` like that.
+
+```ruby
+TABLE = Ractor.make_sharable( {a: 'ko1', b: 'ko2', c: 'ko3'} )
+```
+
+To make it easy, Ruby 3.0 introduced new `shareable_constant_value` Directive.
+
+```ruby
+shareable_constant_value: literal
+
+TABLE = {a: 'ko1', b: 'ko2', c: 'ko3'}
+#=> Same as: TABLE = Ractor.make_sharable( {a: 'ko1', b: 'ko2', c: 'ko3'} )
+```
+
+`shareable_constant_value` directive accepts the following modes (descriptions use the example: `CONST = expr`):
+
+* none: Do nothing. Same as: `CONST = expr`
+* literal:
+ * if `expr` is consites of literals, replaced to `CONST = Ractor.make_sharable(expr)`.
+ * otherwise: replaced to `CONST = expr.tap{|o| raise unless Ractor.shareable?}`.
+* experimental_everything: replaced to `CONST = Ractor.make_sharable(expr)`.
+* experimental_copy: replaced to `CONST = Ractor.make_sharable(expr, copy: true)`.
+
+Except the `none` mode (default), it is guaranteed that the assigned constants refer to only sharable objects.
+
+See [doc/syntax/comment.rdoc](syntax/comment.rdoc) for more details.
+
+## Implementation note
+
+* Each Ractor has its own thread, it means each Ractor has at least 1 native thread.
+* Each Ractor has its own ID (`rb_ractor_t::pub::id`).
+ * On debug mode, all unshareable objects are labeled with current Ractor's id, and it is checked to detect unshareable object leak (access an object from different Ractor) in VM.
+
+## Examples
+
+### Traditional Ring example in Actor-model
+
+```ruby
+RN = 1_000
+CR = Ractor.current
+
+r = Ractor.new do
+ p Ractor.receive
+ CR << :fin
+end
+
+RN.times{
+ r = Ractor.new r do |next_r|
+ next_r << Ractor.receive
+ end
+}
+
+p :setup_ok
+r << 1
+p Ractor.receive
+```
+
+### Fork-join
+
+```ruby
+def fib n
+ if n < 2
+ 1
+ else
+ fib(n-2) + fib(n-1)
+ end
+end
+
+RN = 10
+rs = (1..RN).map do |i|
+ Ractor.new i do |i|
+ [i, fib(i)]
+ end
+end
+
+until rs.empty?
+ r, v = Ractor.select(*rs)
+ rs.delete r
+ p answer: v
+end
+```
+
+### Worker pool
+
+```ruby
+require 'prime'
+
+pipe = Ractor.new do
+ loop do
+ Ractor.yield Ractor.receive
+ end
+end
+
+N = 1000
+RN = 10
+workers = (1..RN).map do
+ Ractor.new pipe do |pipe|
+ while n = pipe.take
+ Ractor.yield [n, n.prime?]
+ end
+ end
+end
+
+(1..N).each{|i|
+ pipe << i
+}
+
+pp (1..N).map{
+ _r, (n, b) = Ractor.select(*workers)
+ [n, b]
+}.sort_by{|(n, b)| n}
+```
+
+### Pipeline
+
+```ruby
+# pipeline with yield/take
+r1 = Ractor.new do
+ 'r1'
+end
+
+r2 = Ractor.new r1 do |r1|
+ r1.take + 'r2'
+end
+
+r3 = Ractor.new r2 do |r2|
+ r2.take + 'r3'
+end
+
+p r3.take #=> 'r1r2r3'
+```
+
+```ruby
+# pipeline with send/receive
+
+r3 = Ractor.new Ractor.current do |cr|
+ cr.send Ractor.receive + 'r3'
+end
+
+r2 = Ractor.new r3 do |r3|
+ r3.send Ractor.receive + 'r2'
+end
+
+r1 = Ractor.new r2 do |r2|
+ r2.send Ractor.receive + 'r1'
+end
+
+r1 << 'r0'
+p Ractor.receive #=> "r0r1r2r3"
+```
+
+### Supervise
+
+```ruby
+# ring example again
+
+r = Ractor.current
+(1..10).map{|i|
+ r = Ractor.new r, i do |r, i|
+ r.send Ractor.receive + "r#{i}"
+ end
+}
+
+r.send "r0"
+p Ractor.receive #=> "r0r10r9r8r7r6r5r4r3r2r1"
+```
+
+```ruby
+# ring example with an error
+
+r = Ractor.current
+rs = (1..10).map{|i|
+ r = Ractor.new r, i do |r, i|
+ loop do
+ msg = Ractor.receive
+ raise if /e/ =~ msg
+ r.send msg + "r#{i}"
+ end
+ end
+}
+
+r.send "r0"
+p Ractor.receive #=> "r0r10r9r8r7r6r5r4r3r2r1"
+r.send "r0"
+p Ractor.select(*rs, Ractor.current) #=> [:receive, "r0r10r9r8r7r6r5r4r3r2r1"]
+r.send "e0"
+p Ractor.select(*rs, Ractor.current)
+#=>
+#<Thread:0x000056262de28bd8 run> terminated with exception (report_on_exception is true):
+Traceback (most recent call last):
+ 2: from /home/ko1/src/ruby/trunk/test.rb:7:in `block (2 levels) in <main>'
+ 1: from /home/ko1/src/ruby/trunk/test.rb:7:in `loop'
+/home/ko1/src/ruby/trunk/test.rb:9:in `block (3 levels) in <main>': unhandled exception
+Traceback (most recent call last):
+ 2: from /home/ko1/src/ruby/trunk/test.rb:7:in `block (2 levels) in <main>'
+ 1: from /home/ko1/src/ruby/trunk/test.rb:7:in `loop'
+/home/ko1/src/ruby/trunk/test.rb:9:in `block (3 levels) in <main>': unhandled exception
+ 1: from /home/ko1/src/ruby/trunk/test.rb:21:in `<main>'
+<internal:ractor>:69:in `select': thrown by remote Ractor. (Ractor::RemoteError)
+```
+
+```ruby
+# resend non-error message
+
+r = Ractor.current
+rs = (1..10).map{|i|
+ r = Ractor.new r, i do |r, i|
+ loop do
+ msg = Ractor.receive
+ raise if /e/ =~ msg
+ r.send msg + "r#{i}"
+ end
+ end
+}
+
+r.send "r0"
+p Ractor.receive #=> "r0r10r9r8r7r6r5r4r3r2r1"
+r.send "r0"
+p Ractor.select(*rs, Ractor.current)
+[:receive, "r0r10r9r8r7r6r5r4r3r2r1"]
+msg = 'e0'
+begin
+ r.send msg
+ p Ractor.select(*rs, Ractor.current)
+rescue Ractor::RemoteError
+ msg = 'r0'
+ retry
+end
+
+#=> <internal:ractor>:100:in `send': The incoming-port is already closed (Ractor::ClosedError)
+# because r == r[-1] is terminated.
+```
+
+```ruby
+# ring example with supervisor and re-start
+
+def make_ractor r, i
+ Ractor.new r, i do |r, i|
+ loop do
+ msg = Ractor.receive
+ raise if /e/ =~ msg
+ r.send msg + "r#{i}"
+ end
+ end
+end
+
+r = Ractor.current
+rs = (1..10).map{|i|
+ r = make_ractor(r, i)
+}
+
+msg = 'e0' # error causing message
+begin
+ r.send msg
+ p Ractor.select(*rs, Ractor.current)
+rescue Ractor::RemoteError
+ r = rs[-1] = make_ractor(rs[-2], rs.size-1)
+ msg = 'x0'
+ retry
+end
+
+#=> [:receive, "x0r9r9r8r7r6r5r4r3r2r1"]
+```
diff --git a/doc/regexp.rdoc b/doc/regexp.rdoc
index 49fce51a8d..d84cae1771 100644
--- a/doc/regexp.rdoc
+++ b/doc/regexp.rdoc
@@ -63,12 +63,14 @@ The following are <i>metacharacters</i> <tt>(</tt>, <tt>)</tt>,
<tt>[</tt>, <tt>]</tt>, <tt>{</tt>, <tt>}</tt>, <tt>.</tt>, <tt>?</tt>,
<tt>+</tt>, <tt>*</tt>. They have a specific meaning when appearing in a
pattern. To match them literally they must be backslash-escaped. To match
-a backslash literally backslash-escape that: <tt>\\\\\\</tt>.
+a backslash literally, backslash-escape it: <tt>\\\\</tt>.
/1 \+ 2 = 3\?/.match('Does 1 + 2 = 3?') #=> #<MatchData "1 + 2 = 3?">
+ /a\\\\b/.match('a\\\\b') #=> #<MatchData "a\\b">
-Patterns behave like double-quoted strings so can contain the same
-backslash escapes.
+Patterns behave like double-quoted strings and can contain the same
+backslash escapes (the meaning of <tt>\s</tt> is different, however,
+see below[#label-Character+Classes]).
/\s\u{6771 4eac 90fd}/.match("Go to æ±äº¬éƒ½")
#=> #<MatchData " æ±äº¬éƒ½">
@@ -130,6 +132,9 @@ The following metacharacters also behave like character classes:
* <tt>/\H/</tt> - A non-hexdigit character (<tt>[^0-9a-fA-F]</tt>)
* <tt>/\s/</tt> - A whitespace character: <tt>/[ \t\r\n\f\v]/</tt>
* <tt>/\S/</tt> - A non-whitespace character: <tt>/[^ \t\r\n\f\v]/</tt>
+* <tt>/\R/</tt> - A linebreak: <tt>\n</tt>, <tt>\v</tt>, <tt>\f</tt>, <tt>\r</tt>
+ <tt>\u0085</tt> (NEXT LINE), <tt>\u2028</tt> (LINE SEPARATOR), <tt>\u2029</tt> (PARAGRAPH SEPARATOR)
+ or <tt>\r\n</tt>.
POSIX <i>bracket expressions</i> are also similar to character classes.
They provide a portable alternative to the above, with the added benefit
@@ -188,8 +193,11 @@ At least one uppercase character ('H'), at least one lowercase character
Repetition is <i>greedy</i> by default: as many occurrences as possible
are matched while still allowing the overall match to succeed. By
contrast, <i>lazy</i> matching makes the minimal amount of matches
-necessary for overall success. A greedy metacharacter can be made lazy by
-following it with <tt>?</tt>.
+necessary for overall success. Most greedy metacharacters can be made lazy
+by following them with <tt>?</tt>. For the <tt>{n}</tt> pattern, because
+it specifies an exact number of characters to match and not a variable
+number of characters, the <tt>?</tt> metacharacter instead makes the
+repeated pattern optional.
Both patterns below match the string. The first uses a greedy quantifier so
'.+' matches '<a><b>'; the second uses a lazy quantifier so '.+?' matches
@@ -227,7 +235,7 @@ Capture groups can be referred to by name when defined with the
constructs.
/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")
- => #<MatchData "$3.67" dollars:"3" cents:"67">
+ #=> #<MatchData "$3.67" dollars:"3" cents:"67">
/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")[:dollars] #=> "3"
Named groups can be backreferenced with <tt>\k<</tt><i>name</i><tt>></tt>,
@@ -237,7 +245,15 @@ where _name_ is the group name.
#=> #<MatchData "ototo" vowel:"o">
*Note*: A regexp can't use named backreferences and numbered
-backreferences simultaneously.
+backreferences simultaneously. Also, if a named capture is used in a
+regexp, then parentheses used for grouping which would otherwise result
+in a unnamed capture are treated as non-capturing.
+
+ /(\w)(\w)/.match("ab").captures # => ["a", "b"]
+ /(\w)(\w)/.match("ab").named_captures # => {}
+
+ /(?<c>\w)(\w)/.match("ab").captures # => ["a"]
+ /(?<c>\w)(\w)/.match("ab").named_captures # => {"c"=>"a"}
When named capture groups are used with a literal regexp on the left-hand
side of an expression and the <tt>=~</tt> operator, the captured text is
@@ -540,10 +556,15 @@ options which control how the pattern can match.
subexpression level with the
<tt>(?</tt><i>on</i><tt>-</tt><i>off</i><tt>)</tt> construct, which
enables options <i>on</i>, and disables options <i>off</i> for the
-expression enclosed by the parentheses.
+expression enclosed by the parentheses:
+
+ /a(?i:b)c/.match('aBc') #=> #<MatchData "aBc">
+ /a(?-i:b)c/i.match('ABC') #=> nil
+
+Additionally, these options can also be toggled for the remainder of the
+pattern:
- /a(?i:b)c/.match('aBc') #=> #<MatchData "aBc">
- /a(?i:b)c/.match('abc') #=> #<MatchData "abc">
+ /a(?i)bc/.match('abC') #=> #<MatchData "abC">
Options may also be used with <tt>Regexp.new</tt>:
@@ -607,9 +628,9 @@ regexp's encoding can be explicitly fixed by supplying
<tt>Regexp.new</tt>:
r = Regexp.new("a".force_encoding("iso-8859-1"),Regexp::FIXEDENCODING)
- r =~"a\u3042"
- #=> Encoding::CompatibilityError: incompatible encoding regexp match
- (ISO-8859-1 regexp with UTF-8 string)
+ r =~ "a\u3042"
+ # raises Encoding::CompatibilityError: incompatible encoding regexp match
+ # (ISO-8859-1 regexp with UTF-8 string)
== Special global variables
diff --git a/doc/security.rdoc b/doc/security.rdoc
index d7d6464ce1..ae20ed30fa 100644
--- a/doc/security.rdoc
+++ b/doc/security.rdoc
@@ -15,19 +15,6 @@ mailto:security@ruby-lang.org ({the PGP public
key}[https://www.ruby-lang.org/security.asc]), which is a private mailing list.
Reported problems will be published after fixes.
-== <code>$SAFE</code>
-
-Ruby provides a mechanism to restrict what operations can be performed by Ruby
-code in the form of the <code>$SAFE</code> variable.
-
-However, <code>$SAFE</code> does not provide a secure environment for executing
-untrusted code.
-
-If you need to execute untrusted code, you should use an operating system level
-sandboxing mechanism. On Linux, ptrace or LXC can be used to sandbox
-potentially malicious code. Other similar mechanisms exist on every major
-operating system.
-
== +Marshal.load+
Ruby's +Marshal+ module provides methods for serializing and deserializing Ruby
diff --git a/doc/shell.rd.ja b/doc/shell.rd.ja
deleted file mode 100644
index a9507fe92a..0000000000
--- a/doc/shell.rd.ja
+++ /dev/null
@@ -1,335 +0,0 @@
- -- shell.rb
- $Release Version: 0.6.0 $
- $Revision$
- by Keiju ISHITSUKA(keiju@ishitsuka.com)
-
-=begin
-
-= 目的
-
-ruby上ã§sh/cshã®ã‚ˆã†ã«ã‚³ãƒžãƒ³ãƒ‰ã®å®Ÿè¡ŒåŠã³ãƒ•ィルタリングを手軽ã«è¡Œã†.
-sh/cshã®åˆ¶å¾¡æ–‡ã¯rubyã®æ©Ÿèƒ½ã‚’用ã„ã¦å®Ÿç¾ã™ã‚‹.
-
-= 主ãªã‚¯ãƒ©ã‚¹ä¸€è¦§
-
-== Shell
-
-Shellオブジェクトã¯ã‚«ãƒ¬ãƒ³ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’æŒã¡, コマンド実行ã¯ãã“ã‹ã‚‰ã®
-相対パスã«ãªã‚Šã¾ã™.
-
---- Shell#cwd
---- Shell#dir
---- Shell#getwd
---- Shell#pwd
-
- カレントディレクトリを返ã™ã€‚
-
---- Shell#system_path
-
- コマンドサーãƒãƒ‘スã®é…列を返ã™ã€‚
-
---- Shell#umask
-
- umaskã‚’è¿”ã™ã€‚
-
-== Filter
-
-コマンドã®å®Ÿè¡Œçµæžœã¯ã™ã¹ã¦Filterã¨ã—ã¦ã‹ãˆã‚Šã¾ã™. Enumerableã‚’includeã—
-ã¦ã„ã¾ã™.
-
-= 主ãªãƒ¡ã‚½ãƒƒãƒ‰ä¸€è¦§
-
-== コマンド定義
-
-OS上ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã™ã‚‹ã«ã¯ã¾ãš, Shellã®ãƒ¡ã‚½ãƒƒãƒ‰ã¨ã—ã¦å®šç¾©ã—ã¾ã™.
-
-注) コマンドを定義ã—ãªãã¨ã‚‚直接実行ã§ãã‚‹Shell#systemコマンドもã‚りã¾ã™.
-
---- Shell.def_system_command(command, path = command)
-
- Shellã®ãƒ¡ã‚½ãƒƒãƒ‰ã¨ã—ã¦commandを登録ã—ã¾ã™.
-
- 例)
- Shell.def_system_command "ls"
- ls を定義
-
- Shell.def_system_command "sys_sort", "sort"
- sortコマンドをsys_sortã¨ã—ã¦å®šç¾©
-
---- Shell.undef_system_command(command)
-
- commandを削除ã—ã¾ã™.
-
---- Shell.alias_command(ali, command, *opts) {...}
-
- commandã®aliasã‚’ã—ã¾ã™.
-
- 例)
- Shell.alias_command "lsC", "ls", "-CBF", "--show-control-chars"
- Shell.alias_command("lsC", "ls"){|*opts| ["-CBF", "--show-control-chars", *opts]}
-
---- Shell.unalias_command(ali)
-
- commandã®aliasを削除ã—ã¾ã™.
-
---- Shell.install_system_commands(pre = "sys_")
-
- system_path上ã«ã‚ã‚‹å…¨ã¦ã®å®Ÿè¡Œå¯èƒ½ãƒ•ァイルをShellã«å®šç¾©ã™ã‚‹. メソッ
- ドåã¯å…ƒã®ãƒ•ァイルåã®é ­ã«preã‚’ã¤ã‘ãŸã‚‚ã®ã¨ãªã‚‹.
-
-== 生æˆ
-
---- Shell.new
-
- プロセスã®ã‚«ãƒ¬ãƒ³ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’カレントディレクトリã¨ã™ã‚‹Shellオ
- ブジェクトを生æˆã—ã¾ã™.
-
---- Shell.cd(path)
-
- pathをカレントディレクトリã¨ã™ã‚‹Shellオブジェクトを生æˆã—ã¾ã™.
-
-== プロセス管ç†
-
---- Shell#jobs
-
- スケジューリングã•れã¦ã„ã‚‹jobã®ä¸€è¦§ã‚’è¿”ã™.
-
---- Shell#kill sig, job
-
- jobã«ã‚·ã‚°ãƒŠãƒ«sigã‚’é€ã‚‹
-
-== カレントディレクトリæ“作
-
---- Shell#cd(path, &block)
---- Shell#chdir
-
- カレントディレクトリをpathã«ã™ã‚‹. イテレータã¨ã—ã¦å‘¼ã°ã‚ŒãŸã¨ãã«ã¯
- ブロック実行中ã®ã¿ã‚«ãƒ¬ãƒ³ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’変更ã™ã‚‹.
-
---- Shell#pushd(path = nil, &block)
---- Shell#pushdir
-
- カレントディレクトリをディレクトリスタックã«ã¤ã¿, カレントディレク
- トリをpathã«ã™ã‚‹. pathãŒçœç•¥ã•れãŸã¨ãã«ã¯, カレントディレクトリã¨
- ディレクトリスタックã®ãƒˆãƒƒãƒ—を交æ›ã™ã‚‹. イテレータã¨ã—ã¦å‘¼ã°ã‚ŒãŸã¨
- ãã«ã¯, ブロック実行中ã®ã¿pushdã™ã‚‹.
-
---- Shell#popd
---- Shell#popdir
-
- ディレクトリスタックã‹ã‚‰ãƒãƒƒãƒ—ã—, ãれをカレントディレクトリã«ã™ã‚‹.
-
-== ファイル/ディレクトリæ“作
-
---- Shell#foreach(path = nil, &block)
-
- pathãŒãƒ•ァイルãªã‚‰, File#foreach
- pathãŒãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãªã‚‰, Dir#foreach
-
---- Shell#open(path, mode)
-
- pathãŒãƒ•ァイルãªã‚‰, File#open
- pathãŒãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãªã‚‰, Dir#open
-
---- Shell#unlink(path)
-
- pathãŒãƒ•ァイルãªã‚‰, File#unlink
- pathãŒãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãªã‚‰, Dir#unlink
-
---- Shell#test(command, file1, file2)
---- Shell#[command, file1, file2]
-
- ファイルテスト関数testã¨åŒã˜.
- 例)
- sh[?e, "foo"]
- sh[:e, "foo"]
- sh["e", "foo"]
- sh[:exists?, "foo"]
- sh["exists?", "foo"]
-
---- Shell#mkdir(*path)
-
- Dir.mkdirã¨åŒã˜(複数å¯)
-
---- Shell#rmdir(*path)
-
- Dir.rmdirã¨åŒã˜(複数å¯)
-
-== コマンド実行
-
---- System#system(command, *opts)
-
- commandを実行ã™ã‚‹.
- 例)
- print sh.system("ls", "-l")
- sh.system("ls", "-l") | sh.head > STDOUT
-
---- System#rehash
-
- リãƒãƒƒã‚·ãƒ¥ã™ã‚‹
-
---- Shell#transact &block
-
- ブロック中ã§ã¯shellã‚’selfã¨ã—ã¦å®Ÿè¡Œã™ã‚‹.
- 例)
- sh.transact{system("ls", "-l") | head > STDOUT}
-
---- Shell#out(dev = STDOUT, &block)
-
- transactを呼ã³å‡ºã—ãã®çµæžœã‚’devã«å‡ºåŠ›ã™ã‚‹.
-
-== 内部コマンド
-
---- Shell#echo(*strings)
---- Shell#cat(*files)
---- Shell#glob(patten)
---- Shell#tee(file)
-
- ã“れらã¯å®Ÿè¡Œã™ã‚‹ã¨, ãれらを内容ã¨ã™ã‚‹Filterオブジェクトを返ã—ã¾ã™.
-
---- Filter#each &block
-
- フィルタã®ä¸€è¡Œãšã¤ã‚’blockã«æ¸¡ã™.
-
---- Filter#<(src)
-
- srcをフィルタã®å…¥åŠ›ã¨ã™ã‚‹. srcãŒ, 文字列ãªã‚‰ã°ãƒ•ァイルを, IOã§ã‚れ
- ã°ãれをãã®ã¾ã¾å…¥åŠ›ã¨ã™ã‚‹.
-
---- Filter#>(to)
-
- srcをフィルタã®å‡ºåŠ›ã¨ã™ã‚‹. toãŒ, 文字列ãªã‚‰ã°ãƒ•ァイルã«, IOã§ã‚れ
- ã°ãれをãã®ã¾ã¾å‡ºåŠ›ã¨ã™ã‚‹.
-
---- Filter#>>(to)
-
- srcをフィルタã«è¿½åŠ ã™ã‚‹. toãŒ, 文字列ãªã‚‰ã°ãƒ•ァイルã«, IOã§ã‚れã°
- ãれをãã®ã¾ã¾å‡ºåŠ›ã¨ã™ã‚‹.
-
---- Filter#|(filter)
-
- パイプçµåˆ
-
---- Filter#+(filter)
-
- filter1 + filter2 㯠filter1ã®å‡ºåŠ›ã®å¾Œ, filter2ã®å‡ºåŠ›ã‚’è¡Œã†.
-
---- Filter#to_a
---- Filter#to_s
-
-== 組込ã¿ã‚³ãƒžãƒ³ãƒ‰
-
---- Shell#atime(file)
---- Shell#basename(file, *opt)
---- Shell#chmod(mode, *files)
---- Shell#chown(owner, group, *file)
---- Shell#ctime(file)
---- Shell#delete(*file)
---- Shell#dirname(file)
---- Shell#ftype(file)
---- Shell#join(*file)
---- Shell#link(file_from, file_to)
---- Shell#lstat(file)
---- Shell#mtime(file)
---- Shell#readlink(file)
---- Shell#rename(file_from, file_to)
---- Shell#split(file)
---- Shell#stat(file)
---- Shell#symlink(file_from, file_to)
---- Shell#truncate(file, length)
---- Shell#utime(atime, mtime, *file)
-
- ã“れらã¯Fileクラスã«ã‚ã‚‹åŒåã®ã‚¯ãƒ©ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã¨åŒã˜ã§ã™.
-
---- Shell#blockdev?(file)
---- Shell#chardev?(file)
---- Shell#directory?(file)
---- Shell#executable?(file)
---- Shell#executable_real?(file)
---- Shell#exist?(file)/Shell#exists?(file)
---- Shell#file?(file)
---- Shell#grpowned?(file)
---- Shell#owned?(file)
---- Shell#pipe?(file)
---- Shell#readable?(file)
---- Shell#readable_real?(file)
---- Shell#setgid?(file)
---- Shell#setuid?(file)
---- Shell#size(file)/Shell#size?(file)
---- Shell#socket?(file)
---- Shell#sticky?(file)
---- Shell#symlink?(file)
---- Shell#writable?(file)
---- Shell#writable_real?(file)
---- Shell#zero?(file)
-
- ã“れらã¯FileTestクラスã«ã‚ã‚‹åŒåã®ã‚¯ãƒ©ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã¨åŒã˜ã§ã™.
-
---- Shell#syscopy(filename_from, filename_to)
---- Shell#copy(filename_from, filename_to)
---- Shell#move(filename_from, filename_to)
---- Shell#compare(filename_from, filename_to)
---- Shell#safe_unlink(*filenames)
---- Shell#makedirs(*filenames)
---- Shell#install(filename_from, filename_to, mode)
-
- ã“れらã¯FileToolsクラスã«ã‚ã‚‹åŒåã®ã‚¯ãƒ©ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã¨åŒã˜ã§ã™.
-
- ãã®ä»–, 以下ã®ã‚‚ã®ãŒã‚¨ã‚¤ãƒªã‚¢ã‚¹ã•れã¦ã„ã¾ã™.
-
---- Shell#cmp <- Shell#compare
---- Shell#mv <- Shell#move
---- Shell#cp <- Shell#copy
---- Shell#rm_f <- Shell#safe_unlink
---- Shell#mkpath <- Shell#makedirs
-
-= サンプル
-
-== ex1
-
- sh = Shell.cd("/tmp")
- sh.mkdir "shell-test-1" unless sh.exists?("shell-test-1")
- sh.cd("shell-test-1")
- for dir in ["dir1", "dir3", "dir5"]
- if !sh.exists?(dir)
- sh.mkdir dir
- sh.cd(dir) do
- f = sh.open("tmpFile", "w")
- f.print "TEST\n"
- f.close
- end
- print sh.pwd
- end
- end
-
-== ex2
-
- sh = Shell.cd("/tmp")
- sh.transact do
- mkdir "shell-test-1" unless exists?("shell-test-1")
- cd("shell-test-1")
- for dir in ["dir1", "dir3", "dir5"]
- if !exists?(dir)
- mkdir dir
- cd(dir) do
- f = open("tmpFile", "w")
- f.print "TEST\n"
- f.close
- end
- print pwd
- end
- end
- end
-
-== ex3
-
- sh.cat("/etc/printcap") | sh.tee("tee1") > "tee2"
- (sh.cat < "/etc/printcap") | sh.tee("tee11") > "tee12"
- sh.cat("/etc/printcap") | sh.tee("tee1") >> "tee2"
- (sh.cat < "/etc/printcap") | sh.tee("tee11") >> "tee12"
-
-== ex4
-
- print sh.cat("/etc/passwd").head.collect{|l| l =~ /keiju/}
-
-=end
diff --git a/doc/signals.rdoc b/doc/signals.rdoc
new file mode 100644
index 0000000000..403eb66549
--- /dev/null
+++ b/doc/signals.rdoc
@@ -0,0 +1,106 @@
+= Caveats for implementing Signal.trap callbacks
+
+As with implementing signal handlers in C or most other languages,
+all code passed to Signal.trap must be reentrant. If you are not
+familiar with reentrancy, you need to read up on it at
+{Wikipedia}[https://en.wikipedia.org/wiki/Reentrancy_(computing)] or
+elsewhere before reading the rest of this document.
+
+Most importantly, "thread-safety" does not guarantee reentrancy;
+and methods such as Mutex#lock and Mutex#synchronize which are
+commonly used for thread-safety even prevent reentrancy.
+
+== An implementation detail of the Ruby VM
+
+The Ruby VM defers Signal.trap callbacks from running until it is safe
+for its internal data structures, but it does not know when it is safe
+for data structures in YOUR code. Ruby implements deferred signal
+handling by registering short C functions with only
+{async-signal-safe functions}[http://man7.org/linux/man-pages/man7/signal-safety.7.html] as
+signal handlers. These short C functions only do enough tell the VM to
+run callbacks registered via Signal.trap later in the main Ruby Thread.
+
+== Unsafe methods to call in Signal.trap blocks
+
+When in doubt, consider anything not listed as safe below as being
+unsafe.
+
+* Mutex#lock, Mutex#synchronize and any code using them are explicitly
+ unsafe. This includes Monitor in the standard library which uses
+ Mutex to provide reentrancy.
+
+* Dir.chdir with block
+
+* any IO write operations when IO#sync is false;
+ including IO#write, IO#write_nonblock, IO#puts.
+ Pipes and sockets default to `IO#sync = true', so it is safe to
+ write to them unless IO#sync was disabled.
+
+* File#flock, as the underlying flock(2) call is not specified by POSIX
+
+== Commonly safe operations inside Signal.trap blocks
+
+* Assignment and retrieval of local, instance, and class variables
+
+* Most object allocations and initializations of common types
+ including Array, Hash, String, Struct, Time.
+
+* Common Array, Hash, String, Struct operations which do not execute a block
+ are generally safe; but beware if iteration is occurring elsewhere.
+
+* Hash#[], Hash#[]= (unless Hash.new was given an unsafe block)
+
+* Thread::Queue#push and Thread::SizedQueue#push (since Ruby 2.1)
+
+* Creating a new Thread via Thread.new/Thread.start can used to get
+ around the unusability of Mutexes inside a signal handler
+
+* Signal.trap is safe to use inside blocks passed to Signal.trap
+
+* arithmetic on Integer and Float (`+', `-', '%', '*', '/')
+
+ Additionally, signal handlers do not run between two successive
+ local variable accesses, so shortcuts such as `+=' and `-=' will
+ not trigger a data race when used on Integer and Float classes in
+ signal handlers.
+
+== System call wrapper methods which are safe inside Signal.trap
+
+Since Ruby has wrappers around many
+{async-signal-safe C functions}[http://man7.org/linux/man-pages/man7/signal-safety.7.html]
+the corresponding wrappers for many IO, File, Dir, and Socket methods
+are safe.
+
+(Incomplete list)
+
+* Dir.chdir (without block arg)
+* Dir.mkdir
+* Dir.open
+* File#truncate
+* File.link
+* File.open
+* File.readlink
+* File.rename
+* File.stat
+* File.symlink
+* File.truncate
+* File.unlink
+* File.utime
+* IO#close
+* IO#dup
+* IO#fsync
+* IO#read
+* IO#read_nonblock
+* IO#stat
+* IO#sysread
+* IO#syswrite
+* IO.select
+* IO.pipe
+* Process.clock_gettime
+* Process.exit!
+* Process.fork
+* Process.kill
+* Process.pid
+* Process.ppid
+* Process.waitpid
+...
diff --git a/doc/standard_library.rdoc b/doc/standard_library.rdoc
index a788080c72..e4418aea81 100644
--- a/doc/standard_library.rdoc
+++ b/doc/standard_library.rdoc
@@ -8,26 +8,44 @@ description.
== Libraries
+MakeMakefile:: Module used to generate a Makefile for C extensions
+RbConfig:: Information of your configure and build of Ruby
+Gem:: Package management framework for Ruby
+
+== Extensions
+
+Coverage:: Provides coverage measurement for Ruby
+Monitor:: Provides an object or module to use safely by more than one thread
+objspace:: Extends ObjectSpace module to add methods for internal statistics
+PTY:: Creates and manages pseudo terminals
+Ripper:: Provides an interface for parsing Ruby programs into S-expressions
+Socket:: Access underlying OS socket implementations
+
+= Default gems
+
+== Libraries
+
Abbrev:: Calculates a set of unique abbreviations for a given set of strings
Base64:: Support for encoding and decoding binary data using a Base64 representation
Benchmark:: Provides methods to measure and report the time used to execute code
+Bundler:: Manage your Ruby application's gem dependencies
CGI:: Support for the Common Gateway Interface protocol
-ConditionVariable:: Augments the Mutex class
+CSV:: Provides an interface to read and write CSV files and data
DEBUGGER__:: Debugging functionality for Ruby
Delegator:: Provides three abilities to delegate method calls to an object
+DidYouMean:: "Did you mean?" experience in Ruby
DRb:: Distributed object system for Ruby
-E2MM:: Module for defining custom exceptions with specific messages
-English.rb:: Require 'English.rb' to reference global variables with less cryptic names
+English:: Provides references to special global variables with less cryptic names
ERB:: An easy to use but powerful templating system for Ruby
+FileUtils:: Several file utility methods for copying, moving, removing, etc
Find:: This module supports top-down traversal of a set of file paths
Forwardable:: Provides delegation of specified methods to a designated object
GetoptLong:: Parse command line options similar to the GNU C getopt_long()
IPAddr:: Provides methods to manipulate IPv4 and IPv6 IP addresses
IRB:: Interactive Ruby command-line tool for REPL (Read Eval Print Loop)
+OptionParser:: Ruby-oriented class for command-line option analysis
Logger:: Provides a simple logging utility for outputting messages
-MakeMakefile:: Module used to generate a Makefile for C extensions
Matrix:: Represents a mathematical matrix.
-Monitor:: Provides an object or module to use safely by more than one thread
Mutex_m:: Mixin to extend objects to be handled like a Mutex
Net::FTP:: Support for the File Transfer Protocol
Net::HTTP:: HTTP client api for Ruby
@@ -35,33 +53,22 @@ Net::IMAP:: Ruby client api for Internet Message Access Protocol
Net::POP3:: Ruby client library for POP3
Net::SMTP:: Simple Mail Transfer Protocol client library for Ruby
Observable:: Provides a mechanism for publish/subscribe pattern in Ruby
-OpenURI:: An easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP
Open3:: Provides access to stdin, stdout and stderr when running other programs
-OptionParser:: Ruby-oriented class for command-line option analysis
OpenStruct:: Class to build custom data structures, similar to a Hash
+OpenURI:: An easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP
PP:: Provides a PrettyPrinter for Ruby objects
PrettyPrinter:: Implements a pretty printing algorithm for readable structure
Prime:: Prime numbers and factorization library
-profile.rb:: Runs the Ruby Profiler__
-Profiler__:: Provides a way to profile your Ruby application
PStore:: Implements a file based persistence mechanism based on a Hash
-Queue:: Synchronized communication between threads
-Racc:: A LALR(1) parser generator written in Ruby.
-RbConfig:: Information of your configure and build of Ruby
-resolv-replace.rb:: Replace Socket DNS with Resolv
Resolv:: Thread-aware DNS resolver library in Ruby
-REXML:: An XML toolkit for Ruby
+resolv-replace.rb:: Replace Socket DNS with Resolv
+RDoc:: Produces HTML and command-line documentation for Ruby
Rinda:: The Linda distributed computing paradigm in Ruby
-RSS:: Family of libraries that support various formats of XML "feeds"
-Gem:: Package management framework for Ruby
SecureRandom:: Interface for secure random number generator
Set:: Provides a class to deal with collections of unordered, unique values
-Shell:: An idiomatic Ruby interface for common UNIX shell commands
Shellwords:: Manipulates strings with word parsing rules of UNIX Bourne shell
Singleton:: Implementation of the Singleton pattern for Ruby
-Synchronizer:: A module that provides a two-phase lock with a counter
Tempfile:: A utility class for managing temporary files
-ThreadsWait:: Watches for termination of multiple threads
Time:: Extends the Time class with methods for parsing and conversion
Timeout:: Auto-terminate potentially long-running operations in Ruby
tmpdir.rb:: Extends the Dir class to manage the OS temporary file path
@@ -69,34 +76,8 @@ Tracer:: Outputs a source level execution trace of a Ruby program
TSort:: Topological sorting using Tarjan's algorithm
un.rb:: Utilities to replace common UNIX commands
URI:: A Ruby module providing support for Uniform Resource Identifiers
-WeakRef:: Allows a referenced object to be garbage-collected
YAML:: Ruby client library for the Psych YAML implementation
-
-== Extensions
-
-Coverage:: Provides coverage measurement for Ruby
-Digest:: Provides a framework for message digest libraries
-IO:: Extensions for Ruby IO class, including #wait and ::console
-NKF:: Ruby extension for Network Kanji Filter
-objspace:: Extends ObjectSpace module to add methods for internal statistics
-Pathname:: Representation of the name of a file or directory on the filesystem
-PTY:: Creates and manages pseudo terminals
-Readline:: Provides an interface for GNU Readline and Edit Line (libedit)
-Ripper:: Provides an interface for parsing Ruby programs into S-expressions
-Socket:: Access underlying OS socket implementations
-Syslog:: Ruby interface for the POSIX system logging facility
-WIN32OLE:: Provides an interface for OLE Automation in Ruby
-
-= Default gems
-
-== Libraries
-
-CMath:: Provides Trigonometric and Transcendental functions for complex numbers
-CSV:: Provides an interface to read and write CSV files and data
-FileUtils:: Several file utility methods for copying, moving, removing, etc
-RDoc:: Produces HTML and command-line documentation for Ruby
-Scanf:: A Ruby implementation of the C function scanf(3)
-WEBrick:: An HTTP server toolkit for Ruby
+WeakRef:: Allows a referenced object to be garbage-collected
== Extensions
@@ -104,27 +85,34 @@ BigDecimal:: Provides arbitrary-precision floating point decimal arithmetic
Date:: A subclass of Object includes Comparable module for handling dates
DateTime:: Subclass of Date to handling dates, hours, minutes, seconds, offsets
DBM:: Provides a wrapper for the UNIX-style Database Manager Library
+Digest:: Provides a framework for message digest libraries
Etc:: Provides access to information typically stored in UNIX /etc directory
Fcntl:: Loads constants defined in the OS fcntl.h C header file
Fiddle:: A libffi wrapper for Ruby
GDBM:: Ruby extension for the GNU dbm (gdbm) library
-IO::console:: Console interface
+IO:: Extensions for Ruby IO class, including #wait, #nonblock and ::console
JSON:: Implements Javascript Object Notation for Ruby
+NKF:: Ruby extension for Network Kanji Filter
OpenSSL:: Provides SSL, TLS and general purpose cryptography for Ruby
+Pathname:: Representation of the name of a file or directory on the filesystem
Psych:: A YAML parser and emitter for Ruby
-SDBM:: Provides a simple file-based key-value store with String keys and values
+Racc:: A LALR(1) parser generator written in Ruby.
+Readline:: Provides an interface for GNU Readline and Edit Line (libedit)
StringIO:: Pseudo I/O on String objects
StringScanner:: Provides lexical scanning operations on a String
+Syslog:: Ruby interface for the POSIX system logging facility
+WIN32OLE:: Provides an interface for OLE Automation in Ruby
Zlib:: Ruby interface for the zlib compression/decompression library
= Bundled gems
== Libraries
-DidYouMean:: "Did you mean?" experience in Ruby
MiniTest:: A test suite with TDD, BDD, mocking and benchmarking
-Net::Telnet:: Telnet client library for Ruby
PowerAssert:: Power Assert for Ruby.
Rake:: Ruby build program with capabilities similar to make
Test::Unit:: A compatibility layer for MiniTest
-XMLRPC:: Remote Procedure Call over HTTP support for Ruby
+REXML:: An XML toolkit for Ruby
+RSS:: Family of libraries that support various formats of XML "feeds"
+RBS:: RBS is a language to describe the structure of Ruby programs
+TypeProf:: A type analysis tool for Ruby code based on abstract interpretation
diff --git a/doc/syntax.rdoc b/doc/syntax.rdoc
index fe0f98ce4c..5895673f36 100644
--- a/doc/syntax.rdoc
+++ b/doc/syntax.rdoc
@@ -11,6 +11,9 @@ Assignment[rdoc-ref:syntax/assignment.rdoc] ::
{Control Expressions}[rdoc-ref:syntax/control_expressions.rdoc] ::
+if+, +unless+, +while+, +until+, +for+, +break+, +next+, +redo+
+{Pattern matching}[rdoc-ref:syntax/pattern_matching.rdoc] ::
+ Experimental structural pattern matching and variable binding syntax
+
Methods[rdoc-ref:syntax/methods.rdoc] ::
Method and method argument syntax
@@ -27,8 +30,10 @@ Precedence[rdoc-ref:syntax/precedence.rdoc] ::
Precedence of ruby operators
Refinements[rdoc-ref:syntax/refinements.rdoc] ::
- Use and behavior of the experimental refinements feature
+ Use and behavior of the refinements feature
Miscellaneous[rdoc-ref:syntax/miscellaneous.rdoc] ::
+alias+, +undef+, +BEGIN+, +END+
+Comments[rdoc-ref:syntax/comments.rdoc] ::
+ Line and block code comments
diff --git a/doc/syntax/assignment.rdoc b/doc/syntax/assignment.rdoc
index 83300cbece..a1806e4c48 100644
--- a/doc/syntax/assignment.rdoc
+++ b/doc/syntax/assignment.rdoc
@@ -92,8 +92,9 @@ Now any reference to +big_calculation+ is considered a local variable and will
be cached. To call the method, use <code>self.big_calculation</code>.
You can force a method call by using empty argument parentheses as shown above
-or by using an explicit receiver like <code>self.</code>. Using an explicit
-receiver may raise a NameError if the method's visibility is not public.
+or by using an explicit receiver like <code>self</code>. Using an explicit
+receiver may raise a NameError if the method's visibility is not public or the
+receiver is the literal <code>self</code>.
Another commonly confusing case is when using a modifier +if+:
@@ -109,6 +110,28 @@ The confusion comes from the out-of-order execution of the expression. First
the local variable is assigned-to then you attempt to call a nonexistent
method.
+== Local Variables and eval
+
+Using +eval+ to evaluate Ruby code will allow access to local variables defined
+in the same scope, even if the local variables are not defined until after the
+call to +eval+. However, local variables defined inside the call to +eval+
+will not be reflected in the surrounding scope. Inside the call to +eval+,
+local variables defined in the surrounding scope and local variables defined
+inside the call to +eval+ will be accessible. However, you will not be able
+to access local variables defined in previous or subsequent calls to +eval+ in
+the same scope. Consider each +eval+ call a separate nested scope. Example:
+
+ def m
+ eval "bar = 1"
+ lvs = eval "baz = 2; ary = [local_variables, foo, baz]; x = 2; ary"
+ eval "quux = 3"
+ foo = 1
+ lvs << local_variables
+ end
+
+ m
+ # => [[:baz, :ary, :x, :lvs, :foo], nil, 2, [:lvs, :foo]]
+
== Instance Variables
Instance variables are shared across all methods for the same object.
diff --git a/doc/syntax/calling_methods.rdoc b/doc/syntax/calling_methods.rdoc
index ec86ef05ee..fc806d5c31 100644
--- a/doc/syntax/calling_methods.rdoc
+++ b/doc/syntax/calling_methods.rdoc
@@ -27,13 +27,66 @@ This sends the +my_method+ message to +my_object+. Any object can be a
receiver but depending on the method's visibility sending a message may raise a
NoMethodError.
-You may use <code>&.</code> to designate a receiver, then +my_method+ is not
-invoked and the result is +nil+ when the receiver is +nil+. In that case, the
-arguments of +my_method+ are not evaluated.
-
You may also use <code>::</code> to designate a receiver, but this is rarely
used due to the potential for confusion with <code>::</code> for namespaces.
+=== Chaining \Method Calls
+
+You can "chain" method calls by immediately following one method call with another.
+
+This example chains methods Array#append and Array#compact:
+
+ a = [:foo, 'bar', 2]
+ a1 = [:baz, nil, :bam, nil]
+ a2 = a.append(*a1).compact
+ a2 # => [:foo, "bar", 2, :baz, :bam]
+
+Details:
+
+- First method <tt>merge</tt> creates a copy of <tt>a</tt>,
+ appends (separately) each element of <tt>a1</tt> to the copy, and returns
+ [:foo, "bar", 2, :baz, nil, :bam, nil]
+- Chained method <tt>compact</tt> creates a copy of that return value,
+ removes its <tt>nil</tt>-valued entries, and returns
+ [:foo, "bar", 2, :baz, :bam]
+
+You can chain methods that are in different classes.
+This example chains methods Hash#to_a and Array#reverse:
+
+ h = {foo: 0, bar: 1, baz: 2}
+ h.to_a.reverse # => [[:baz, 2], [:bar, 1], [:foo, 0]]
+
+Details:
+
+- First method Hash#to_a converts <tt>a</tt> to an \Array, and returns
+ [[:foo, 0], [:bar, 1], [:baz, 2]]
+- Chained method Array#reverse creates copy of that return value,
+ reverses it, and returns
+ [[:baz, 2], [:bar, 1], [:foo, 0]]
+
+=== Safe Navigation Operator
+
+<code>&.</code>, called "safe navigation operator", allows to skip method call
+when receiver is +nil+. It returns +nil+ and doesn't evaluate method's arguments
+if the call is skipped.
+
+ REGEX = /(ruby) is (\w+)/i
+ "Ruby is awesome!".match(REGEX).values_at(1, 2)
+ # => ["Ruby", "awesome"]
+ "Python is fascinating!".match(REGEX).values_at(1, 2)
+ # NoMethodError: undefined method `values_at' for nil:NilClass
+ "Python is fascinating!".match(REGEX)&.values_at(1, 2)
+ # => nil
+
+This allows to easily chain methods which could return empty value. Note that
+<code>&.</code> skips only one next call, so for a longer chain it is necessary
+to add operator on each level:
+
+ "Python is fascinating!".match(REGEX)&.values_at(1, 2).join(' - ')
+ # NoMethodError: undefined method `join' for nil:NilClass
+ "Python is fascinating!".match(REGEX)&.values_at(1, 2)&.join(' - ')
+ # => nil
+
== Arguments
There are three types of arguments when sending a message, the positional
@@ -79,7 +132,7 @@ to:
If the method definition has a <code>*argument</code> extra positional
arguments will be assigned to +argument+ in the method as an Array.
-If the method definition doesn't include keyword arguments the keyword or
+If the method definition doesn't include keyword arguments, the keyword or
hash-type arguments are assigned as a single hash to the last argument:
def my_method(options)
@@ -153,7 +206,8 @@ like positional arguments:
my_method(positional1, keyword1: value1, keyword2: value2)
Any keyword arguments not given will use the default value from the method
-definition. If a keyword argument is given that the method did not list an
+definition. If a keyword argument is given that the method did not list,
+and the method definition does not accept arbitrary keyword arguments, an
ArgumentError will be raised.
=== Block Argument
@@ -259,6 +313,9 @@ hash at the end of the array into keyword arguments:
arguments = [1, 2, { c: 4 }]
my_method(*arguments)
+Note that this behavior is currently deprecated and will emit a warning.
+This behavior will be removed in Ruby 3.0.
+
You may also use the <code>**</code> (described next) to convert a Hash into
keyword arguments.
@@ -266,7 +323,10 @@ If the number of objects in the Array do not match the number of arguments for
the method, an ArgumentError will be raised.
If the splat operator comes first in the call, parentheses must be used to
-avoid a warning.
+avoid a warning:
+
+ my_method *arguments # warning
+ my_method(*arguments) # no warning
=== Hash to Keyword Arguments Conversion
@@ -275,7 +335,8 @@ Given the following method:
def my_method(first: 1, second: 2, third: 3)
end
-You can turn a Hash into keyword arguments with the <code>**</code> operator:
+You can turn a Hash into keyword arguments with the <code>**</code>
+(keyword splat) operator:
arguments = { first: 3, second: 4, third: 5 }
my_method(**arguments)
@@ -289,8 +350,9 @@ Both are equivalent to:
my_method(first: 3, second: 4, third: 5)
-If the method definition uses <code>**</code> to gather arbitrary keyword
-arguments, they will not be gathered by <code>*</code>:
+If the method definition uses the keyword splat operator to
+gather arbitrary keyword arguments, they will not be gathered
+by <code>*</code>:
def my_method(*a, **kw)
p arguments: a, keywords: kw
@@ -300,10 +362,7 @@ arguments, they will not be gathered by <code>*</code>:
Prints:
- {:arguments=>[1, 2, {"3"=>4}], :keywords=>{:five=>6}}
-
-Unlike the splat operator described above, the <code>**</code> operator has no
-commonly recognized name.
+ {:arguments=>[1, 2], :keywords=>{'3'=>4, :five=>6}}
=== Proc to Block Conversion
@@ -314,17 +373,17 @@ Given a method that use a block:
end
You can convert a proc or lambda to a block argument with the <code>&</code>
-operator:
+(block conversion) operator:
argument = proc { |a| puts "#{a.inspect} was yielded" }
my_method(&argument)
-If the splat operator comes first in the call, parenthesis must be used to
-avoid a warning.
+If the block conversion operator comes first in the call, parenthesis must be
+used to avoid a warning:
-Unlike the splat operator described above, the <code>&</code> operator has no
-commonly recognized name.
+ my_method &argument # warning
+ my_method(&argument) # no warning
== Method Lookup
diff --git a/doc/syntax/comments.rdoc b/doc/syntax/comments.rdoc
new file mode 100644
index 0000000000..650d13c2dc
--- /dev/null
+++ b/doc/syntax/comments.rdoc
@@ -0,0 +1,253 @@
+= Code Comments
+
+Ruby has two types of comments: inline and block.
+
+Inline comments start with the <code>#</code> character and continue until the
+end of the line:
+
+ # On a separate line
+ class Foo # or at the end of the line
+ # can be indented
+ def bar
+ end
+ end
+
+Block comments start with <code>=begin</code> and end with <code>=end</code>.
+Each should start on a separate line.
+
+ =begin
+ This is
+ commented out
+ =end
+
+ class Foo
+ end
+
+ =begin some_tag
+ this works, too
+ =end
+
+<code>=begin</code> and <code>=end</code> can not be indented, so this is a
+syntax error:
+
+ class Foo
+ =begin
+ Will not work
+ =end
+ end
+
+== Magic Comments
+
+While comments are typically ignored by Ruby, special "magic comments" contain
+directives that affect how the code is interpreted.
+
+Top-level magic comments must start on the first line, or on the second line if
+the first line looks like <tt>#! shebang line</tt>.
+
+NOTE: Magic comments affect only the file in which they appear;
+other files are unaffected.
+
+ # frozen_string_literal: true
+
+ var = 'hello'
+ var.frozen? # => true
+
+=== Alternative syntax
+
+Magic comments may consist of a single directive (as in the example above).
+Alternatively, multiple directives may appear on the same line if separated by ";"
+and wrapped between "-*-" (see Emacs' {file variables}[https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html]).
+
+ # emacs-compatible; -*- coding: big5; mode: ruby -*-
+
+ p 'hello'.frozen? # => true
+ p 'hello'.encoding # => #<Encoding:Big5>
+
+=== +encoding+ Directive
+
+Indicates which string encoding should be used for string literals,
+regexp literals and <code>__ENCODING__</code>:
+
+ # encoding: big5
+
+ ''.encoding # => #<Encoding:Big5>
+
+Default encoding is UTF-8.
+
+It must appear in the first comment section of a file.
+
+The word "coding" may be used instead of "encoding".
+
+=== +frozen_string_literal+ Directive
+
+Indicates that string literals should be allocated once at parse time and frozen.
+
+ # frozen_string_literal: true
+
+ 3.times do
+ p 'hello'.object_id # => prints same number
+ end
+ p 'world'.frozen? # => true
+
+The default is false; this can be changed with <code>--enable=frozen-string-literal</code>.
+Without the directive, or with <code># frozen_string_literal: false</code>,
+the example above would print 3 different numbers and "false".
+
+Starting in Ruby 3.0, string literals that are dynamic are not frozen nor reused:
+
+ # frozen_string_literal: true
+
+ p "Addition: #{2 + 2}".frozen? # => false
+
+It must appear in the first comment section of a file.
+
+=== +warn_indent+ Directive
+
+This directive can turn on detection of bad indentation for statements that follow it:
+
+ def foo
+ end # => no warning
+
+ # warn_indent: true
+ def bar
+ end # => warning: mismatched indentations at 'end' with 'def' at 6
+
+Another way to get these warnings to show is by running Ruby with warnings (<code>ruby -w</code>). Using a directive to set this false will prevent these warnings to show.
+
+=== +shareable_constant_value+ Directive
+
+Note: This directive is experimental in Ruby 3.0 and may change in future releases.
+
+This special directive helps to create constants that hold only immutable objects, or {Ractor-shareable}[rdoc-ref:Ractor@Shareable+and+unshareable+objects] constants.
+
+The directive can specify special treatment for values assigned to constants:
+
+* +none+: (default)
+* +literal+: literals are implicitly frozen, others must be Ractor-shareable
+* +experimental_everything+: all made shareable
+* +experimental_copy+: copy deeply and make it shareable
+
+==== Mode +none+ (default)
+
+No special treatment in this mode (as in Ruby 2.x): no automatic freezing and no checks.
+
+It has always been a good idea to deep-freeze constants; Ractor makes this
+an even better idea as only the main ractor can access non-shareable constants:
+
+ # shareable_constant_value: none
+ A = {foo: []}
+ A.frozen? # => false
+ Ractor.new { puts A } # => can not access non-shareable objects by non-main Ractor.
+
+==== Mode +literal+
+
+In "literal" mode, constants assigned to literals will be deeply-frozen:
+
+ # shareable_constant_value: literal
+ X = [{foo: []}] # => same as [{foo: [].freeze}.freeze].freeze
+
+Other values must be shareable:
+
+ # shareable_constant_value: literal
+ X = Object.new # => cannot assign unshareable object to X
+
+Note that only literals directly assigned to constants, or recursively held in such literals will be frozen:
+
+ # shareable_constant_value: literal
+ var = [{foo: []}]
+ var.frozen? # => false (assignment was made to local variable)
+ X = var # => cannot assign unshareable object to X
+
+ X = Set[1, 2, {foo: []}].freeze # => cannot assign unshareable object to X
+ # (`Set[...]` is not a literal and
+ # `{foo: []}` is an argument to `Set.[]`)
+
+The method Module#const_set is not affected.
+
+==== Mode +experimental_everything+
+
+In this mode, all values assigned to constants are made shareable.
+
+ # shareable_constant_value: experimental_everything
+ FOO = Set[1, 2, {foo: []}]
+ # same as FOO = Ractor.make_sharable(...)
+ # OR same as `FOO = Set[1, 2, {foo: [].freeze}.freeze].freeze`
+
+ var = [{foo: []}]
+ var.frozen? # => false (assignment was made to local variable)
+ X = var # => calls `Ractor.make_shareable(var)`
+ var.frozen? # => true
+
+This mode is "experimental", because it might be error prone, for
+example by deep-freezing the constants of an external resource which
+could cause errors:
+
+ # shareable_constant_value: experimental_everything
+ FOO = SomeGem::Something::FOO
+ # => deep freezes the gem's constant!
+
+This will be revisited before Ruby 3.1 to either allow `everything`
+or to instead remove this mode.
+
+The method Module#const_set is not affected.
+
+==== Mode +experimental_copy+
+
+In this mode, all values assigned to constants are deeply copied and
+made shareable. It is safer mode than +experimental_everything+.
+
+ # shareable_constant_value: experimental_everything
+ var = [{foo: []}]
+ var.frozen? # => false (assignment was made to local variable)
+ X = var # => calls `Ractor.make_shareable(var, copy: true)`
+ var.frozen? # => false
+ Ractor.shareable?(X) #=> true
+ var.object_id == X.object_id #=> false
+
+This mode is "experimental" and has not been discussed thoroughly.
+This will be revisited before Ruby 3.1 to either allow `copy`
+or to instead remove this mode.
+
+The method Module#const_set is not affected.
+
+==== Scope
+
+This directive can be used multiple times in the same file:
+
+ # shareable_constant_value: none
+ A = {foo: []}
+ A.frozen? # => false
+ Ractor.new { puts A } # => can not access non-shareable objects by non-main Ractor.
+
+ # shareable_constant_value: literal
+ B = {foo: []}
+ B.frozen? # => true
+ B[:foo].frozen? # => true
+
+ C = [Object.new] # => cannot assign unshareable object to C (Ractor::IsolationError)
+
+ D = [Object.new.freeze]
+ D.frozen? # => true
+
+ # shareable_constant_value: experimental_everything
+ E = Set[1, 2, Object.new]
+ E.frozen? # => true
+ E.all(&:frozen?) # => true
+
+The directive affects only subsequent constants and only for the current scope:
+
+ module Mod
+ # shareable_constant_value: literal
+ A = [1, 2, 3]
+ module Sub
+ B = [4, 5]
+ end
+ end
+
+ C = [4, 5]
+
+ module Mod
+ D = [6]
+ end
+ p Mod::A.frozen?, Mod::Sub::B.frozen? # => true, true
+ p C.frozen?, Mod::D.frozen? # => false, false
diff --git a/doc/syntax/control_expressions.rdoc b/doc/syntax/control_expressions.rdoc
index 65f7b431e3..e91b03e72d 100644
--- a/doc/syntax/control_expressions.rdoc
+++ b/doc/syntax/control_expressions.rdoc
@@ -144,7 +144,7 @@ expression.
== Modifier +if+ and +unless+
+if+ and +unless+ can also be used to modify an expression. When used as a
-modifier the left-hand side is the "then" expression and the right-hand side
+modifier the left-hand side is the "then" statement and the right-hand side
is the "test" expression:
a = 0
@@ -164,7 +164,7 @@ This will print 1.
This will print 0.
While the modifier and standard versions have both a "test" expression and a
-"then" expression, they are not exact transformations of each other due to
+"then" statement, they are not exact transformations of each other due to
parse order. Here is an example that shows the difference:
p a if a = 0.zero?
@@ -232,7 +232,7 @@ You may use +then+ after the +when+ condition. This is most frequently used
to place the body of the +when+ on a single line.
case a
- when 1, 2 then puts "a is one or two
+ when 1, 2 then puts "a is one or two"
when 3 then puts "a is three"
else puts "I don't know what a is"
end
@@ -255,6 +255,20 @@ Again, the +then+ and +else+ are optional.
The result value of a +case+ expression is the last value executed in the
expression.
+Since Ruby 2.7, +case+ expressions also provide a more powerful experimental
+pattern matching feature via the +in+ keyword:
+
+ case {a: 1, b: 2, c: 3}
+ in a: Integer => m
+ "matched: #{m}"
+ else
+ "not matched"
+ end
+ # => "matched: 1"
+
+The pattern matching syntax is described on
+{its own page}[rdoc-ref:syntax/pattern_matching.rdoc].
+
== +while+ Loop
The +while+ loop executes while a condition is true:
@@ -439,6 +453,64 @@ longer true, now you will receive a SyntaxError when you use +retry+ outside
of a +rescue+ block. See {Exceptions}[rdoc-ref:syntax/exceptions.rdoc]
for proper usage of +retry+.
+== Modifier Statements
+
+Ruby's grammar differentiates between statements and expressions. All
+expressions are statements (an expression is a type of statement), but
+not all statements are expressions. Some parts of the grammar accept
+expressions and not other types of statements, which causes code that
+looks similar to be parsed differently.
+
+For example, when not used as a modifier, +if+, +else+, +while+, +until+,
+and +begin+ are expressions (and also statements). However, when
+used as a modifier, +if+, +else+, +while+, +until+ and +rescue+
+are statements but not expressions.
+
+ if true; 1 end # expression (and therefore statement)
+ 1 if true # statement (not expression)
+
+Statements that are not expressions cannot be used in contexts where an
+expression is expected, such as method arguments.
+
+ puts( 1 if true ) #=> SyntaxError
+
+You can wrap a statement in parentheses to create an expression.
+
+ puts((1 if true)) #=> 1
+
+If you put a space between the method name and opening parenthesis, you
+do not need two sets of parentheses.
+
+ puts (1 if true) #=> 1, because of optional parentheses for method
+
+This is because this is parsed similar to a method call without
+parentheses. It is equivalent to the following code, without the creation
+of a local variable:
+
+ x = (1 if true)
+ p x
+
+In a modifier statement, the left-hand side must be a statement and the
+right-hand side must be an expression.
+
+So in <code>a if b rescue c</code>, because <code>b rescue c</code> is a
+statement that is not an expression, and therefore is not allowed as the
+right-hand side of the +if+ modifier statement, the code is necessarily
+parsed as <code>(a if b) rescue c</code>.
+
+This interacts with operator precedence in such a way that:
+
+ stmt if v = expr rescue x
+ stmt if v = expr unless x
+
+are parsed as:
+
+ stmt if v = (expr rescue x)
+ (stmt if v = expr) unless x
+
+This is because modifier +rescue+ has higher precedence than <code>=</code>,
+and modifier +if+ has lower precedence than <code>=</code>.
+
== Flip-Flop
The flip-flop is a rarely seen conditional expression. It's primary use is
diff --git a/doc/syntax/exceptions.rdoc b/doc/syntax/exceptions.rdoc
index a2e75616fb..31e2f0175c 100644
--- a/doc/syntax/exceptions.rdoc
+++ b/doc/syntax/exceptions.rdoc
@@ -17,7 +17,14 @@ wish to limit the scope of rescued exceptions:
# ...
end
-The same is true for a +class+ or +module+.
+The same is true for a +class+, +module+, and +block+:
+
+ [0, 1, 2].map do |i|
+ 10 / i
+ rescue ZeroDivisionError
+ nil
+ end
+ #=> [nil, 10, 5]
You can assign the exception to a local variable by using <tt>=>
variable_name</tt> at the end of the +rescue+ line:
diff --git a/doc/syntax/literals.rdoc b/doc/syntax/literals.rdoc
index b8ed7f7c54..d6d677806e 100644
--- a/doc/syntax/literals.rdoc
+++ b/doc/syntax/literals.rdoc
@@ -20,9 +20,6 @@ Literals create objects you can use in your program. Literals include:
+true+ is a true value. All objects except +nil+ and +false+ evaluate to a
true value in conditional expressions.
-(There are also the constants +TRUE+, +FALSE+ and +NIL+, but the lowercase
-literal forms are preferred.)
-
== Numbers
You can write integers of any size as follows:
@@ -71,6 +68,33 @@ Examples:
All these numbers have the same decimal value, 170. Like integers and floats
you may use an underscore for readability.
+=== Rational numbers
+
+Numbers suffixed by +r+ are Rational numbers.
+
+ 12r #=> (12/1)
+ 12.3r #=> (123/10)
+
+Rational numbers are exact, whereas Float numbers are inexact.
+
+ 0.1r + 0.2r #=> (3/10)
+ 0.1 + 0.2 #=> 0.30000000000000004
+
+=== Complex numbers
+
+Numbers suffixed by +i+ are Complex (or imaginary) numbers.
+
+ 1i #=> (0+1i)
+ 1i * 1i #=> (-1+0i)
+
+Also Rational numbers may be imaginary numbers.
+
+ 12.3ri #=> (0+(123/10)*i)
+
++i+ must be placed after +r+, the opposite is not allowed.
+
+ 12.3ir #=> syntax error
+
== Strings
The most common way of writing strings is using <tt>"</tt>:
@@ -119,6 +143,10 @@ Double-quote strings allow interpolation of other values using
Any expression may be placed inside the interpolated section, but it's best to
keep the expression small for readability.
+You can also use <tt>#@foo</tt>, <tt>#@@foo</tt> and <tt>#$foo</tt> as a
+shorthand for, respectively, <tt>#{ @foo }</tt>, <tt>#{ @@foo }</tt> and
+<tt>#{ $foo }</tt>.
+
Interpolation may be disabled by escaping the "#" character or using
single-quote strings:
@@ -166,7 +194,7 @@ a single codepoint in the script encoding:
?\C-\M-a #=> "\x81", same as above
?ã‚ #=> "ã‚"
-=== Here Documents
+=== Here Documents (heredocs)
If you are writing a large block of text you may use a "here document" or
"heredoc":
@@ -228,6 +256,9 @@ behaves like Kernel#`:
cat #{__FILE__}
HEREDOC
+When surrounding with quotes, any character but that quote and newline
+(CR and/or LF) can be used as the identifier.
+
To call a method on a heredoc place it after the opening identifier:
expected_result = <<-EXPECTED.chomp
@@ -306,6 +337,8 @@ its ending value.
(1..2) # includes its ending value
(1...2) # excludes its ending value
+ (1..) # endless range, representing infinite sequence from 1 to Infinity
+ (..1) # beginless range, representing infinite sequence from -Infinity to 1
You may create a range of any object. See the Range documentation for details
on the methods you need to implement.
@@ -330,7 +363,7 @@ See Regexp for a description of the syntax of regular expressions.
== Procs
-A proc can be created with <tt>-></tt>:
+A lambda proc can be created with <tt>-></tt>:
-> { 1 + 1 }
diff --git a/doc/syntax/methods.rdoc b/doc/syntax/methods.rdoc
index bdc555b131..c11bd449bc 100644
--- a/doc/syntax/methods.rdoc
+++ b/doc/syntax/methods.rdoc
@@ -17,8 +17,8 @@ on calling methods}[rdoc-ref:syntax/calling_methods.rdoc].
== Method Names
Method names may be one of the operators or must start a letter or a character
-with the eight bit set. It may contain letters, numbers, an <code>_</code>
-(underscore or low line) or a character with the eight bit set. The convention
+with the eighth bit set. It may contain letters, numbers, an <code>_</code>
+(underscore or low line) or a character with the eighth bit set. The convention
is to use underscores to separate words in a multiword method name:
def method_name
@@ -26,7 +26,7 @@ is to use underscores to separate words in a multiword method name:
end
Ruby programs must be written in a US-ASCII-compatible character set such as
-UTF-8, ISO-8859-1 etc. In such character sets if the eight bit is set it
+UTF-8, ISO-8859-1 etc. In such character sets if the eighth bit is set it
indicates an extended character. Ruby allows method names and other identifiers
to contain such characters. Ruby programs cannot contain some characters like
ASCII NUL (<code>\x00</code>).
@@ -62,9 +62,7 @@ Methods that end with a question mark by convention return boolean, but they
may not always return just +true+ or +false+. Often, they will return an
object to indicate a true value (or "truthy" value).
-Methods that end with an equals sign indicate an assignment method. For
-assignment methods, the return value is ignored and the arguments are returned
-instead.
+Methods that end with an equals sign indicate an assignment method.
These are method names for the various Ruby operators. Each of these
operators accepts only one argument. Following the operator is the typical
@@ -94,8 +92,8 @@ operators.
<code>></code> :: greater-than
<code>>=</code> :: greater-than or equal
-To define unary methods minus, plus, tilde and not (<code>!</code>) follow the
-operator with an <code>@</code> as in <code>+@</code> or <code>!@</code>:
+To define unary methods minus and plus, follow the operator with an
+<code>@</code> as in <code>+@</code>:
class C
def -@
@@ -107,6 +105,13 @@ operator with an <code>@</code> as in <code>+@</code> or <code>!@</code>:
-obj # prints "you inverted this object"
+The <code>@</code> is needed to differentiate unary minus and plus
+operators from binary minus and plus operators.
+
+You can also follow tilde and not (<code>!</code>) unary methods with
+<code>@</code>, but it is not required as there are no binary tilde
+and not operators.
+
Unary methods accept zero arguments.
Additionally, methods for element reference and assignment may be defined:
@@ -147,14 +152,18 @@ evaluated.
1 + 1 # this expression is never evaluated
end
-Note that for assignment methods the return value will always be ignored.
-Instead, the argument will be returned:
+Note that for assignment methods the return value will be ignored when using
+the assignment syntax. Instead, the argument will be returned:
def a=(value)
return 1 + value
end
- p(a = 5) # prints 5
+ p(self.a = 5) # prints 5
+
+The actual return value will be returned when invoking the method directly:
+
+ p send(:a=, 5) # prints 6
== Scope
@@ -279,6 +288,25 @@ This will raise a SyntaxError:
a + b + c
end
+Default argument values can refer to arguments that have already been
+evaluated as local variables, and argument values are always evaluated
+left to right. So this is allowed:
+
+ def add_values(a = 1, b = a)
+ a + b
+ end
+ add_values
+ # => 2
+
+But this will raise a +NameError+ (unless there is a method named
++b+ defined):
+
+ def add_values(a = b, b = 1)
+ a + b
+ end
+ add_values
+ # NameError (undefined local variable or method `b' for main:Object)
+
=== Array Decomposition
You can decompose (unpack or extract values from) an Array using extra
@@ -351,12 +379,23 @@ converted to an Array:
gather_arguments 1, 2, 3 # prints [1, 2, 3]
-The array argument must be the last positional argument, it must appear before
-any keyword arguments.
+The array argument must appear before any keyword arguments.
+
+It is possible to gather arguments at the beginning or in the middle:
+
+ def gather_arguments(first_arg, *middle_arguments, last_arg)
+ p middle_arguments
+ end
+
+ gather_arguments 1, 2, 3, 4 # prints [2, 3]
The array argument will capture a Hash as the last entry if a hash was sent by
the caller after all positional arguments.
+ def gather_arguments(*arguments)
+ p arguments
+ end
+
gather_arguments 1, a: 2 # prints [1, {:a=>2}]
However, this only occurs if the method does not declare any keyword arguments.
@@ -391,12 +430,116 @@ Arbitrary keyword arguments will be accepted with <code>**</code>:
# prints 1 then {:second=>2, :third=>3}
When calling a method with keyword arguments the arguments may appear in any
-order. If an unknown keyword argument is sent by the caller an ArgumentError
-is raised.
+order. If an unknown keyword argument is sent by the caller, and the method
+does not accept arbitrary keyword arguments, an ArgumentError is raised.
+
+To require a specific keyword argument, do not include a default value
+for the keyword argument:
+
+ def add_values(first:, second:)
+ first + second
+ end
+ add_values
+ # ArgumentError (missing keywords: first, second)
+ add_values(first: 1, second: 2)
+ # => 3
When mixing keyword arguments and positional arguments, all positional
arguments must appear before any keyword arguments.
+Also, note that <code>**</code> can be used to ignore keyword arguments:
+
+ def ignore_keywords(**)
+ end
+
+To mark a method as accepting keywords, but not actually accepting
+keywords, you can use the <code>**nil</code>:
+
+ def no_keywords(**nil)
+ end
+
+Calling such a method with keywords or a non-empty keyword splat will
+result in an ArgumentError. This syntax is supported so that keywords
+can be added to the method later without affected backwards compatibility.
+
+=== Keyword and Positional Argument Separation
+
+Between Ruby 2.0 and 2.6, keyword and positional arguments were not
+separated, and a keyword argument could be used as a positional argument
+and vice-versa. In Ruby 3.0, keyword and positional arguments will
+be separated if the method definition includes keyword arguments.
+In Ruby 3.0, if the method definition does not include keyword arguments,
+keyword arguments provided when calling the method will continue to be
+treated as a final positional hash argument.
+
+Currently, the keyword and positional arguments are not separated,
+but cases where behavior will change in Ruby 3.0 will result in a
+warning being emitted.
+
+There are a few different types of keyword argument separation issues.
+
+==== Conversion of Hash to Keywords
+
+If a method is called with the hash, the hash could be treated as
+keywords:
+
+ def my_method(**keywords)
+ keywords
+ end
+ my_method({a: 1}) # {:a => 1}
+
+This occurs even if the hash could be an optional positional argument
+or an element of a rest argument:
+
+ def my_method(hash=nil, **keywords)
+ [hash, keywords]
+ end
+ my_method({a: 1}) # [nil, {:a => 1}]
+
+ def my_method(*args, **keywords)
+ [args, keywords]
+ end
+ my_method({a: 1}) # [[], {:a => 1}]
+
+However, if the hash is needed for a mandatory positional argument,
+it would not be treated as keywords:
+
+ def my_method(hash, **keywords)
+ [hash, keywords]
+ end
+ my_method({a: 1}) # [{:a => 1}, {}]
+
+==== Conversion of Keywords to Positional Arguments
+
+If a method is called with keywords, but it is missing one
+mandatory positional argument, the keywords are converted to
+a hash and the hash used as the mandatory positional argument:
+
+ def my_method(hash, **keywords)
+ [hash, keywords]
+ end
+ my_method(a: 1) # [{:a => 1}, {}]
+
+This is also true for empty keyword splats:
+
+ kw = {}
+ my_method(**kw) # [{}, {}]
+
+==== Splitting of Positional Hashes or Keywords
+
+If a method definition accepts specific keywords and not arbitrary keywords,
+keywords or a positional hash may be split if the hash includes both Symbol
+keys and non-Symbol keys and the keywords or positional hash are not needed
+as a mandatory positional argument. In this case, the non-Symbol keys are
+separated into a positional argument hash, and the Symbol keys are used
+as the keyword arguments:
+
+ def my_method(hash=3, a: 4)
+ [hash, a]
+ end
+ my_method(a: 1, 'a' => 2) # [{"a"=>2}, 1]
+ my_method({a: 1, 'a' => 2}) # [{"a"=>2}, 1]
+
== Block Argument
The block argument is indicated by <code>&</code> and must come last:
@@ -420,15 +563,6 @@ in this section:
yield self
end
-There is also a performance benefit to using yield over a calling a block
-parameter. When a block argument is assigned to a variable a Proc object is
-created which holds the block. When using yield this Proc object is not
-created.
-
-If you only need to use the block sometimes you can use Proc.new to create a
-proc from the block that was passed to your method. See Proc.new for further
-details.
-
== Exception Handling
Methods have an implied exception handling block so you do not need to use
@@ -450,6 +584,28 @@ May be written as:
# handle exception
end
+Similarly, if you wish to always run code even if an exception is raised,
+you can use +ensure+ without +begin+ and +end+:
+
+ def my_method
+ # code that may raise an exception
+ ensure
+ # code that runs even if previous code raised an exception
+ end
+
+You can also combine +rescue+ with +ensure+ and/or +else+, without
++begin+ and +end+:
+
+ def my_method
+ # code that may raise an exception
+ rescue
+ # handle exception
+ else
+ # only run if no exception raised above
+ ensure
+ # code that runs even if previous code raised an exception
+ end
+
If you wish to rescue an exception for only part of your method, use +begin+ and
+end+. For more details see the page on {exception
handling}[rdoc-ref:syntax/exceptions.rdoc].
diff --git a/doc/syntax/miscellaneous.rdoc b/doc/syntax/miscellaneous.rdoc
index d5691f8d60..d5cfd3e474 100644
--- a/doc/syntax/miscellaneous.rdoc
+++ b/doc/syntax/miscellaneous.rdoc
@@ -13,7 +13,7 @@ most frequently used with <code>ruby -e</code>.
Ruby does not require any indentation. Typically, ruby programs are indented
two spaces.
-If you run ruby with warnings enabled and have an indentation mis-match, you
+If you run ruby with warnings enabled and have an indentation mismatch, you
will receive a warning.
== +alias+
@@ -83,6 +83,36 @@ Using the specific reflection methods such as instance_variable_defined? for
instance variables or const_defined? for constants is less error prone than
using +defined?+.
++defined?+ handles some regexp global variables specially based on whether
+there is an active regexp match and how many capture groups there are:
+
+ /b/ =~ 'a'
+ defined?($~) # => "global-variable"
+ defined?($&) # => nil
+ defined?($`) # => nil
+ defined?($') # => nil
+ defined?($+) # => nil
+ defined?($1) # => nil
+ defined?($2) # => nil
+
+ /./ =~ 'a'
+ defined?($~) # => "global-variable"
+ defined?($&) # => "global-variable"
+ defined?($`) # => "global-variable"
+ defined?($') # => "global-variable"
+ defined?($+) # => nil
+ defined?($1) # => nil
+ defined?($2) # => nil
+
+ /(.)/ =~ 'a'
+ defined?($~) # => "global-variable"
+ defined?($&) # => "global-variable"
+ defined?($`) # => "global-variable"
+ defined?($') # => "global-variable"
+ defined?($+) # => "global-variable"
+ defined?($1) # => "global-variable"
+ defined?($2) # => nil
+
== +BEGIN+ and +END+
+BEGIN+ defines a block that is run before any other code in the current file.
diff --git a/doc/syntax/modules_and_classes.rdoc b/doc/syntax/modules_and_classes.rdoc
index dd70d4ac21..6122f6e08e 100644
--- a/doc/syntax/modules_and_classes.rdoc
+++ b/doc/syntax/modules_and_classes.rdoc
@@ -190,9 +190,41 @@ Here is an example:
b.n b #=> 1 -- m called on defining class
a.n b # raises NoMethodError A is not a subclass of B
-The third visibility is +private+. A private method may not be called with a
-receiver, not even +self+. If a private method is called with a receiver a
-NoMethodError will be raised.
+The third visibility is +private+. A private method may only be called from
+inside the owner class without a receiver, or with a literal +self+
+as a receiver. If a private method is called with a
+receiver other than a literal +self+, a NoMethodError will be raised.
+
+ class A
+ def without
+ m
+ end
+
+ def with_self
+ self.m
+ end
+
+ def with_other
+ A.new.m
+ end
+
+ def with_renamed
+ copy = self
+ copy.m
+ end
+
+ def m
+ 1
+ end
+
+ private :m
+ end
+
+ a = A.new
+ a.without #=> 1
+ a.with_self #=> 1
+ a.with_other # NoMethodError (private method `m' called for #<A:0x0000559c287f27d0>)
+ a.with_renamed # NoMethodError (private method `m' called for #<A:0x0000559c285f8330>)
=== +alias+ and +undef+
diff --git a/doc/syntax/pattern_matching.rdoc b/doc/syntax/pattern_matching.rdoc
new file mode 100644
index 0000000000..9f6954f1cb
--- /dev/null
+++ b/doc/syntax/pattern_matching.rdoc
@@ -0,0 +1,503 @@
+= Pattern matching
+
+Pattern matching is a feature allowing deep matching of structured values: checking the structure and binding the matched parts to local variables.
+
+Pattern matching in Ruby is implemented with the +case+/+in+ expression:
+
+ case <expression>
+ in <pattern1>
+ ...
+ in <pattern2>
+ ...
+ in <pattern3>
+ ...
+ else
+ ...
+ end
+
+(Note that +in+ and +when+ branches can NOT be mixed in one +case+ expression.)
+
+Or with the <code>=></code> operator and the +in+ operator, which can be used in a standalone expression:
+
+ <expression> => <pattern>
+
+ <expression> in <pattern>
+
+The +case+/+in+ expression is _exhaustive_: if the value of the expression does not match any branch of the +case+ expression (and the +else+ branch is absent), +NoMatchingPatternError+ is raised.
+
+Therefore, the +case+ expression might be used for conditional matching and unpacking:
+
+ config = {db: {user: 'admin', password: 'abc123'}}
+
+ case config
+ in db: {user:} # matches subhash and puts matched value in variable user
+ puts "Connect with user '#{user}'"
+ in connection: {username: }
+ puts "Connect with user '#{username}'"
+ else
+ puts "Unrecognized structure of config"
+ end
+ # Prints: "Connect with user 'admin'"
+
+whilst the <code>=></code> operator is most useful when the expected data structure is known beforehand, to just unpack parts of it:
+
+ config = {db: {user: 'admin', password: 'abc123'}}
+
+ config => {db: {user:}} # will raise if the config's structure is unexpected
+
+ puts "Connect with user '#{user}'"
+ # Prints: "Connect with user 'admin'"
+
+<code><expression> in <pattern></code> is the same as <code>case <expression>; in <pattern>; true; else false; end</code>.
+You can use it when you only want to know if a pattern has been matched or not:
+
+ users = [{name: "Alice", age: 12}, {name: "Bob", age: 23}]
+ users.any? {|user| user in {name: /B/, age: 20..} } #=> true
+
+See below for more examples and explanations of the syntax.
+
+== Patterns
+
+Patterns can be:
+
+* any Ruby object (matched by the <code>===</code> operator, like in +when+); (<em>Value pattern</em>)
+* array pattern: <code>[<subpattern>, <subpattern>, <subpattern>, ...]</code>; (<em>Array pattern</em>)
+* find pattern: <code>[*variable, <subpattern>, <subpattern>, <subpattern>, ..., *variable]</code>; (<em>Find pattern</em>)
+* hash pattern: <code>{key: <subpattern>, key: <subpattern>, ...}</code>; (<em>Hash pattern</em>)
+* combination of patterns with <code>|</code>; (<em>Alternative pattern</em>)
+* variable capture: <code><pattern> => variable</code> or <code>variable</code>; (<em>As pattern</em>, <em>Variable pattern</em>)
+
+Any pattern can be nested inside array/find/hash patterns where <code><subpattern></code> is specified.
+
+Array patterns and find patterns match arrays, or objects that respond to +deconstruct+ (see below about the latter).
+Hash patterns match hashes, or objects that respond to +deconstruct_keys+ (see below about the latter). Note that only symbol keys are supported for hash patterns.
+
+An important difference between array and hash pattern behavior is that arrays match only a _whole_ array:
+
+ case [1, 2, 3]
+ in [Integer, Integer]
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "not matched"
+
+while the hash matches even if there are other keys besides the specified part:
+
+ case {a: 1, b: 2, c: 3}
+ in {a: Integer}
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+<code>{}</code> is the only exclusion from this rule. It matches only if an empty hash is given:
+
+ case {a: 1, b: 2, c: 3}
+ in {}
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "not matched"
+
+ case {}
+ in {}
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+There is also a way to specify there should be no other keys in the matched hash except those explicitly specified by the pattern, with <code>**nil</code>:
+
+ case {a: 1, b: 2}
+ in {a: Integer, **nil} # this will not match the pattern having keys other than a:
+ "matched a part"
+ in {a: Integer, b: Integer, **nil}
+ "matched a whole"
+ else
+ "not matched"
+ end
+ #=> "matched a whole"
+
+Both array and hash patterns support "rest" specification:
+
+ case [1, 2, 3]
+ in [Integer, *]
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+ case {a: 1, b: 2, c: 3}
+ in {a: Integer, **}
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+In +case+ (but not in <code>=></code> and +in+) expressions, parentheses around both kinds of patterns could be omitted:
+
+ case [1, 2]
+ in Integer, Integer
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+ case {a: 1, b: 2, c: 3}
+ in a: Integer
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+Find pattern is similar to array pattern but it can be used to check if the given object has any elements that match the pattern:
+
+ case ["a", 1, "b", "c", 2]
+ in [*, String, String, *]
+ "matched"
+ else
+ "not matched"
+ end
+
+== Variable binding
+
+Besides deep structural checks, one of the very important features of the pattern matching is the binding of the matched parts to local variables. The basic form of binding is just specifying <code>=> variable_name</code> after the matched (sub)pattern (one might find this similar to storing exceptions in local variables in a <code>rescue ExceptionClass => var</code> clause):
+
+ case [1, 2]
+ in Integer => a, Integer
+ "matched: #{a}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1"
+
+ case {a: 1, b: 2, c: 3}
+ in a: Integer => m
+ "matched: #{m}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1"
+
+If no additional check is required, for only binding some part of the data to a variable, a simpler form could be used:
+
+ case [1, 2]
+ in a, Integer
+ "matched: #{a}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1"
+
+ case {a: 1, b: 2, c: 3}
+ in a: m
+ "matched: #{m}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1"
+
+For hash patterns, even a simpler form exists: key-only specification (without any sub-pattern) binds the local variable with the key's name, too:
+
+ case {a: 1, b: 2, c: 3}
+ in a:
+ "matched: #{a}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1"
+
+Binding works for nested patterns as well:
+
+ case {name: 'John', friends: [{name: 'Jane'}, {name: 'Rajesh'}]}
+ in name:, friends: [{name: first_friend}, *]
+ "matched: #{first_friend}"
+ else
+ "not matched"
+ end
+ #=> "matched: Jane"
+
+The "rest" part of a pattern also can be bound to a variable:
+
+ case [1, 2, 3]
+ in a, *rest
+ "matched: #{a}, #{rest}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1, [2, 3]"
+
+ case {a: 1, b: 2, c: 3}
+ in a:, **rest
+ "matched: #{a}, #{rest}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1, {:b=>2, :c=>3}"
+
+Binding to variables currently does NOT work for alternative patterns joined with <code>|</code>:
+
+ case {a: 1, b: 2}
+ in {a: } | Array
+ "matched: #{a}"
+ else
+ "not matched"
+ end
+ # SyntaxError (illegal variable in alternative pattern (a))
+
+Variables that start with <code>_</code> are the only exclusions from this rule:
+
+ case {a: 1, b: 2}
+ in {a: _, b: _foo} | Array
+ "matched: #{_}, #{_foo}"
+ else
+ "not matched"
+ end
+ # => "matched: 1, 2"
+
+It is, though, not advised to reuse the bound value, as this pattern's goal is to signify a discarded value.
+
+== Variable pinning
+
+Due to the variable binding feature, existing local variable can not be straightforwardly used as a sub-pattern:
+
+ expectation = 18
+
+ case [1, 2]
+ in expectation, *rest
+ "matched. expectation was: #{expectation}"
+ else
+ "not matched. expectation was: #{expectation}"
+ end
+ # expected: "not matched. expectation was: 18"
+ # real: "matched. expectation was: 1" -- local variable just rewritten
+
+For this case, the pin operator <code>^</code> can be used, to tell Ruby "just use this value as part of the pattern":
+
+ expectation = 18
+ case [1, 2]
+ in ^expectation, *rest
+ "matched. expectation was: #{expectation}"
+ else
+ "not matched. expectation was: #{expectation}"
+ end
+ #=> "not matched. expectation was: 18"
+
+One important usage of variable pinning is specifying that the same value should occur in the pattern several times:
+
+ jane = {school: 'high', schools: [{id: 1, level: 'middle'}, {id: 2, level: 'high'}]}
+ john = {school: 'high', schools: [{id: 1, level: 'middle'}]}
+
+ case jane
+ in school:, schools: [*, {id:, level: ^school}] # select the last school, level should match
+ "matched. school: #{id}"
+ else
+ "not matched"
+ end
+ #=> "matched. school: 2"
+
+ case john # the specified school level is "high", but last school does not match
+ in school:, schools: [*, {id:, level: ^school}]
+ "matched. school: #{id}"
+ else
+ "not matched"
+ end
+ #=> "not matched"
+
+== Matching non-primitive objects: +deconstruct+ and +deconstruct_keys+
+
+As already mentioned above, array, find, and hash patterns besides literal arrays and hashes will try to match any object implementing +deconstruct+ (for array/find patterns) or +deconstruct_keys+ (for hash patterns).
+
+ class Point
+ def initialize(x, y)
+ @x, @y = x, y
+ end
+
+ def deconstruct
+ puts "deconstruct called"
+ [@x, @y]
+ end
+
+ def deconstruct_keys(keys)
+ puts "deconstruct_keys called with #{keys.inspect}"
+ {x: @x, y: @y}
+ end
+ end
+
+ case Point.new(1, -2)
+ in px, Integer # sub-patterns and variable binding works
+ "matched: #{px}"
+ else
+ "not matched"
+ end
+ # prints "deconstruct called"
+ "matched: 1"
+
+ case Point.new(1, -2)
+ in x: 0.. => px
+ "matched: #{px}"
+ else
+ "not matched"
+ end
+ # prints: deconstruct_keys called with [:x]
+ #=> "matched: 1"
+
++keys+ are passed to +deconstruct_keys+ to provide a room for optimization in the matched class: if calculating a full hash representation is expensive, one may calculate only the necessary subhash. When the <code>**rest</code> pattern is used, +nil+ is passed as a +keys+ value:
+
+ case Point.new(1, -2)
+ in x: 0.. => px, **rest
+ "matched: #{px}"
+ else
+ "not matched"
+ end
+ # prints: deconstruct_keys called with nil
+ #=> "matched: 1"
+
+Additionally, when matching custom classes, the expected class can be specified as part of the pattern and is checked with <code>===</code>
+
+ class SuperPoint < Point
+ end
+
+ case Point.new(1, -2)
+ in SuperPoint(x: 0.. => px)
+ "matched: #{px}"
+ else
+ "not matched"
+ end
+ #=> "not matched"
+
+ case SuperPoint.new(1, -2)
+ in SuperPoint[x: 0.. => px] # [] or () parentheses are allowed
+ "matched: #{px}"
+ else
+ "not matched"
+ end
+ #=> "matched: 1"
+
+== Guard clauses
+
++if+ can be used to attach an additional condition (guard clause) when the pattern matches. This condition may use bound variables:
+
+ case [1, 2]
+ in a, b if b == a*2
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+ case [1, 1]
+ in a, b if b == a*2
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "not matched"
+
++unless+ works, too:
+
+ case [1, 1]
+ in a, b unless b == a*2
+ "matched"
+ else
+ "not matched"
+ end
+ #=> "matched"
+
+== Current feature status
+
+As of Ruby 3.0, one-line pattern matching and find patterns are considered _experimental_: its syntax can change in the future. Every time you use these features in code, a warning will be printed:
+
+ [0] => [*, 0, *]
+ # warning: Find pattern is experimental, and the behavior may change in future versions of Ruby!
+ # warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
+
+To suppress this warning, one may use the Warning::[]= method:
+
+ Warning[:experimental] = false
+ eval('[0] => [*, 0, *]')
+ # ...no warning printed...
+
+Note that pattern-matching warnings are raised at compile time, so this will not suppress the warning:
+
+ Warning[:experimental] = false # At the time this line is evaluated, the parsing happened and warning emitted
+ [0] => [*, 0, *]
+
+So, only subsequently loaded files or `eval`-ed code is affected by switching the flag.
+
+Alternatively, the command line option <code>-W:no-experimental</code> can be used to turn off "experimental" feature warnings.
+
+== Appendix A. Pattern syntax
+
+Approximate syntax is:
+
+ pattern: value_pattern
+ | variable_pattern
+ | alternative_pattern
+ | as_pattern
+ | array_pattern
+ | find_pattern
+ | hash_pattern
+
+ value_pattern: literal
+ | Constant
+ | ^variable
+
+ variable_pattern: variable
+
+ alternative_pattern: pattern | pattern | ...
+
+ as_pattern: pattern => variable
+
+ array_pattern: [pattern, ..., *variable]
+ | Constant(pattern, ..., *variable)
+ | Constant[pattern, ..., *variable]
+
+ find_pattern: [*variable, pattern, ..., *variable]
+ | Constant(*variable, pattern, ..., *variable)
+ | Constant[*variable, pattern, ..., *variable]
+
+ hash_pattern: {key: pattern, key:, ..., **variable}
+ | Constant(key: pattern, key:, ..., **variable)
+ | Constant[key: pattern, key:, ..., **variable]
+
+== Appendix B. Some undefined behavior examples
+
+To leave room for optimization in the future, the specification contains some undefined behavior.
+
+Use of a variable in an unmatched pattern:
+
+ case [0, 1]
+ in [a, 2]
+ "not matched"
+ in b
+ "matched"
+ in c
+ "not matched"
+ end
+ a #=> undefined
+ c #=> undefined
+
+Number of +deconstruct+, +deconstruct_keys+ method calls:
+
+ $i = 0
+ ary = [0]
+ def ary.deconstruct
+ $i += 1
+ self
+ end
+ case ary
+ in [0, 1]
+ "not matched"
+ in [0]
+ "matched"
+ end
+ $i #=> undefined
diff --git a/doc/syntax/precedence.rdoc b/doc/syntax/precedence.rdoc
index 515626c74f..f64691ab1f 100644
--- a/doc/syntax/precedence.rdoc
+++ b/doc/syntax/precedence.rdoc
@@ -49,10 +49,14 @@ Unary <code>+</code> and unary <code>-</code> are for <code>+1</code>,
<code>-1</code> or <code>-(a + b)</code>.
Modifier-if, modifier-unless, etc. are for the modifier versions of those
-keywords. For example, this is a modifier-unless expression:
+keywords. For example, this is a modifier-unless statement:
a += 1 unless a.zero?
+Note that <code>(a if b rescue c)</code> is parsed as <code>((a if b) rescue
+c)</code> due to reasons not related to precedence. See {modifier
+statements}[control_expressions_rdoc.html#label-Modifier+Statements].
+
<code>{ ... }</code> blocks have priority below all listed operations, but
<code>do ... end</code> blocks have lower priority.
diff --git a/doc/syntax/refinements.rdoc b/doc/syntax/refinements.rdoc
index 310599d447..c900ab1bdc 100644
--- a/doc/syntax/refinements.rdoc
+++ b/doc/syntax/refinements.rdoc
@@ -7,7 +7,7 @@ changes. This can cause unintended side-effects or breakage of programs.
Refinements are designed to reduce the impact of monkey patching on other
users of the monkey-patched class. Refinements provide a way to extend a
-class locally.
+class locally. Refinements can modify both classes and modules.
Here is a basic refinement:
@@ -26,8 +26,7 @@ Here is a basic refinement:
end
First, a class +C+ is defined. Next a refinement for +C+ is created using
-Module#refine. Refinements only modify classes, not modules so the argument
-must be a class.
+Module#refine.
Module#refine creates an anonymous module that contains the changes or
refinements to the class (+C+ in the example). +self+ in the refine block is
@@ -181,8 +180,8 @@ When not evaluated:
# not activated here
When defining multiple refinements in the same module inside multiple +refine+ blocks,
-all refinements from the same module are active when a refined method(any of the +.to_json+ method from Example below) is
-called for the first time:
+all refinements from the same module are active when a refined method
+(any of the +to_json+ methods from the example below) is called:
module ToJSON
refine Integer do
@@ -227,7 +226,8 @@ Note that methods in a subclass have priority over refinements in a
superclass. For example, if the method <code>/</code> is defined in a
refinement for Numeric <code>1 / 2</code> invokes the original Integer#/
because Integer is a subclass of Numeric and is searched before the refinements
-for the superclass Numeric. Since the method <code>/</code> is also present in child +Integer+ therefore, the method lookup never went to the superclass.
+for the superclass Numeric. Since the method <code>/</code> is also present
+in child +Integer+, the method lookup does not move up to the superclass.
However, if a method +foo+ is defined on Numeric in a refinement, <code>1.foo</code>
invokes that method since +foo+ does not exist on Integer.
@@ -245,18 +245,40 @@ When +super+ is invoked method lookup checks:
Note that +super+ in a method of a refinement invokes the method in the
refined class even if there is another refinement which has been activated in
-the same context.
+the same context. This is only true for +super+ in a method of a refinement, it
+does not apply to +super+ in a method in a module that is included in a refinement.
-== Indirect Method Calls
+== Methods Introspection
-When using indirect method access such as Kernel#send, Kernel#method or
-Kernel#respond_to? refinements are not honored for the caller context during
-method lookup.
+When using introspection methods such as Kernel#method or Kernel#methods refinements are not honored.
This behavior may be changed in the future.
+== Refinement inheritance by Module#include
+
+When a module X is included into a module Y, Y inherits refinements from X.
+
+For example, C inherits refinements from A and B in the following code:
+
+ module A
+ refine X do ... end
+ refine Y do ... end
+ end
+ module B
+ refine Z do ... end
+ end
+ module C
+ include A
+ include B
+ end
+
+ using C
+ # Refinements in A and B are activated here.
+
+Refinements in descendants have higher precedence than those of ancestors.
+
== Further Reading
-See https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/RefinementsSpec for the
+See https://bugs.ruby-lang.org/projects/ruby-master/wiki/RefinementsSpec for the
current specification for implementing refinements. The specification also
contains more details.
diff --git a/template/yarvarch.en b/doc/yarvarch.en
index 7a76e25b7e..7a76e25b7e 100644
--- a/template/yarvarch.en
+++ b/doc/yarvarch.en
diff --git a/template/yarvarch.ja b/doc/yarvarch.ja
index 2739ec6b14..2739ec6b14 100644
--- a/template/yarvarch.ja
+++ b/doc/yarvarch.ja
diff --git a/enc/Makefile.in b/enc/Makefile.in
index 8385236494..3854f66de6 100644
--- a/enc/Makefile.in
+++ b/enc/Makefile.in
@@ -11,6 +11,7 @@ exec_prefix = @exec_prefix@
libdir = @libdir@
top_srcdir = $(encsrcdir:/enc=)
srcdir = $(top_srcdir)
+tooldir = $(top_srcdir)/tool
arch = @arch@
EXTOUT = @EXTOUT@
hdrdir = $(srcdir)/include
@@ -20,6 +21,7 @@ TRANSSODIR = $(ENCSODIR)/trans
DLEXT = @DLEXT@
OBJEXT = @OBJEXT@
LIBEXT = @LIBEXT@
+EXEEXT = @EXEEXT@
TIMESTAMPDIR = $(EXTOUT)/.timestamp
ENC_TRANS_D = $(TIMESTAMPDIR)/.enc-trans.time
ENC_TRANS_SO_D = $(TIMESTAMPDIR)/.enc-trans.so.time
@@ -33,6 +35,7 @@ RUBY_SO_NAME = @RUBY_SO_NAME@
LIBRUBY = @LIBRUBY@
LIBRUBYARG_SHARED = @LIBRUBYARG_SHARED@
LIBRUBYARG_STATIC = $(LIBRUBYARG_SHARED)
+BUILTRUBY = $(topdir)/miniruby$(EXEEXT)
empty =
AR = @AR@
diff --git a/enc/ascii.c b/enc/ascii.c
index 8b32c414fe..a2fef2f879 100644
--- a/enc/ascii.c
+++ b/enc/ascii.c
@@ -61,6 +61,8 @@ OnigEncodingDefine(ascii, ASCII) = {
ENC_ALIAS("BINARY", "ASCII-8BIT")
ENC_REPLICATE("IBM437", "ASCII-8BIT")
ENC_ALIAS("CP437", "IBM437")
+ENC_REPLICATE("IBM720", "ASCII-8BIT")
+ENC_ALIAS("CP720", "IBM720")
ENC_REPLICATE("IBM737", "ASCII-8BIT")
ENC_ALIAS("CP737", "IBM737")
ENC_REPLICATE("IBM775", "ASCII-8BIT")
diff --git a/enc/cesu_8.c b/enc/cesu_8.c
new file mode 100644
index 0000000000..decbb928f4
--- /dev/null
+++ b/enc/cesu_8.c
@@ -0,0 +1,454 @@
+/**********************************************************************
+ cesu_8.c - Oniguruma (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regenc.h"
+#ifdef RUBY
+# include "encindex.h"
+#endif
+
+#define USE_INVALID_CODE_SCHEME
+
+#ifdef USE_INVALID_CODE_SCHEME
+/* virtual codepoint values for invalid encoding byte 0xfe and 0xff */
+# define INVALID_CODE_FE 0xfffffffe
+# define INVALID_CODE_FF 0xffffffff
+#endif
+#define VALID_CODE_LIMIT 0x0010ffff
+
+#define utf8_islead(c) ((UChar )((c) & 0xc0) != 0x80)
+
+static const int EncLen_CESU8[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+typedef enum {
+ FAILURE = -2,
+ ACCEPT,
+ S0, S1, S2, S3,
+ S4, S5, S6, S7
+} state_t;
+#define A ACCEPT
+#define F FAILURE
+static const signed char trans[][0x100] = {
+ { /* S0 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 1 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 2 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 3 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 4 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 5 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 6 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 7 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 8 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 9 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* a */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* b */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* c */ F, F, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* e */ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+ { /* S1 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 8 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 9 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* a */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* b */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+ { /* S2 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 8 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 9 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* b */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+ { /* S3 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 8 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* b */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+ { /* S4 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 8 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* a */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ /* b */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+ { /* S5 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 8 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ /* 9 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ /* a */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ /* b */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+ { /* S6 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 8 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 9 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* a */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* b */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, 7, F, F,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+ { /* S7 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 8 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 9 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* a */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* b */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+ },
+};
+#undef A
+#undef F
+
+static int
+mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc ARG_UNUSED)
+{
+ int firstbyte = *p++;
+ state_t s;
+ s = trans[0][firstbyte];
+ if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(1) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+ if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(EncLen_CESU8[firstbyte]-1);
+ s = trans[s][*p++];
+ if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(2) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+ if (p == e) {
+ int len = EncLen_CESU8[firstbyte];
+ if (s == 4) { /* S4 is CESU-8's surrogate pair; len is 6 */
+ len = 6;
+ }
+ return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(len-2);
+ }
+ s = trans[s][*p++];
+ if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(3) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+ if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(3);
+ s = trans[s][*p++];
+ if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(4) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+ if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(2);
+ s = trans[s][*p++];
+ if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(5) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+ if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(1);
+ s = trans[s][*p++];
+ return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(6) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+}
+
+static int
+is_mbc_newline(const UChar* p, const UChar* end, OnigEncoding enc)
+{
+ if (p < end) {
+ if (*p == 0x0a) return 1;
+
+#ifdef USE_UNICODE_ALL_LINE_TERMINATORS
+ if (*p == 0x0b || *p == 0x0c || *p == 0x0d) return 1;
+ if (p + 1 < end) {
+ if (*(p+1) == 0x85 && *p == 0xc2) /* U+0085 */
+ return 1;
+ if (p + 2 < end) {
+ if ((*(p+2) == 0xa8 || *(p+2) == 0xa9)
+ && *(p+1) == 0x80 && *p == 0xe2) /* U+2028, U+2029 */
+ return 1;
+ }
+ }
+#endif
+ }
+
+ return 0;
+}
+
+static OnigCodePoint
+mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc)
+{
+ int len;
+
+ len = mbc_enc_len(p, end, enc);
+ switch (len) {
+ case 1:
+ return *p;
+ case 2:
+ return ((p[0] & 0x1F) << 6) | (p[1] & 0x3f);
+ case 3:
+ return ((p[0] & 0xF) << 12) | ((p[1] & 0x3f) << 6) | (p[2] & 0x3f);
+ case 6:
+ {
+ int high = ((p[0] & 0xF) << 12) | ((p[1] & 0x3f) << 6) | (p[2] & 0x3f);
+ int low = ((p[3] & 0xF) << 12) | ((p[4] & 0x3f) << 6) | (p[5] & 0x3f);
+ return ((high & 0x03ff) << 10) + (low & 0x03ff) + 0x10000;
+ }
+ }
+#ifdef USE_INVALID_CODE_SCHEME
+ if (*p > 0xfd) {
+ return ((*p == 0xfe) ? INVALID_CODE_FE : INVALID_CODE_FF);
+ }
+#endif
+ return (OnigCodePoint )*p;
+}
+
+static int
+code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
+{
+ if ((code & 0xffffff80) == 0) return 1;
+ else if ((code & 0xfffff800) == 0) return 2;
+ else if ((code & 0xffff0000) == 0) return 3;
+ else if (code <= VALID_CODE_LIMIT) return 6;
+#ifdef USE_INVALID_CODE_SCHEME
+ else if (code == INVALID_CODE_FE) return 1;
+ else if (code == INVALID_CODE_FF) return 1;
+#endif
+ else
+ return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+}
+
+static int
+code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc ARG_UNUSED)
+{
+#define UTF8_TRAILS(code, shift) (UChar )((((code) >> (shift)) & 0x3f) | 0x80)
+#define UTF8_TRAIL0(code) (UChar )(((code) & 0x3f) | 0x80)
+
+ if ((code & 0xffffff80) == 0) {
+ *buf = (UChar )code;
+ return 1;
+ }
+ else {
+ UChar *p = buf;
+
+ if ((code & 0xfffff800) == 0) {
+ *p++ = (UChar )(((code>>6)& 0x1f) | 0xc0);
+ }
+ else if ((code & 0xffff0000) == 0) {
+ *p++ = (UChar )(((code>>12) & 0x0f) | 0xe0);
+ *p++ = UTF8_TRAILS(code, 6);
+ }
+ else if (code <= VALID_CODE_LIMIT) {
+ unsigned int high = (code >> 10) + 0xD7C0;
+ code = (code & 0x3FF) + 0xDC00;
+ *p++ = (UChar )(((high>>12) & 0x0f) | 0xe0);
+ *p++ = UTF8_TRAILS(high, 6);
+ *p++ = UTF8_TRAIL0(high);
+ *p++ = (UChar )(((code>>12) & 0x0f) | 0xe0);
+ *p++ = UTF8_TRAILS(code, 6);
+ }
+#ifdef USE_INVALID_CODE_SCHEME
+ else if (code == INVALID_CODE_FE) {
+ *p = 0xfe;
+ return 1;
+ }
+ else if (code == INVALID_CODE_FF) {
+ *p = 0xff;
+ return 1;
+ }
+#endif
+ else {
+ return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+ }
+
+ *p++ = UTF8_TRAIL0(code);
+ return (int )(p - buf);
+ }
+}
+
+static int
+mbc_case_fold(OnigCaseFoldType flag, const UChar** pp,
+ const UChar* end, UChar* fold, OnigEncoding enc)
+{
+ const UChar* p = *pp;
+
+ if (ONIGENC_IS_MBC_ASCII(p)) {
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (*p == 0x49) {
+ *fold++ = 0xc4;
+ *fold = 0xb1;
+ (*pp)++;
+ return 2;
+ }
+ }
+#endif
+
+ *fold = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
+ (*pp)++;
+ return 1; /* return byte length of converted char to lower */
+ }
+ else {
+ return onigenc_unicode_mbc_case_fold(enc, flag, pp, end, fold);
+ }
+}
+
+
+static int
+get_ctype_code_range(OnigCtype ctype, OnigCodePoint *sb_out,
+ const OnigCodePoint* ranges[], OnigEncoding enc ARG_UNUSED)
+{
+ *sb_out = 0x80;
+ return onigenc_unicode_ctype_code_range(ctype, ranges);
+}
+
+
+static UChar*
+left_adjust_char_head(const UChar* start, const UChar* s, const UChar* end, OnigEncoding enc ARG_UNUSED)
+{
+ const UChar *p;
+
+ if (s <= start) return (UChar* )s;
+ p = s;
+
+ while (!utf8_islead(*p) && p > start) p--;
+ return (UChar* )p;
+}
+
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[],
+ OnigEncoding enc)
+{
+ return onigenc_unicode_get_case_fold_codes_by_str(enc, flag, p, end, items);
+}
+
+OnigEncodingDefine(cesu_8, CESU_8) = {
+ mbc_enc_len,
+ "CESU-8", /* name */
+ 6, /* max byte length */
+ 1, /* min byte length */
+ is_mbc_newline,
+ mbc_to_code,
+ code_to_mbclen,
+ code_to_mbc,
+ mbc_case_fold,
+ onigenc_unicode_apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_unicode_property_name_to_ctype,
+ onigenc_unicode_is_code_ctype,
+ get_ctype_code_range,
+ left_adjust_char_head,
+ onigenc_always_true_is_allowed_reverse_match,
+ onigenc_unicode_case_map,
+ ENCINDEX_UTF_8,
+ ONIGENC_FLAG_UNICODE,
+};
diff --git a/enc/cp949.c b/enc/cp949.c
index bd2c8d21a4..1600d0cd5b 100644
--- a/enc/cp949.c
+++ b/enc/cp949.c
@@ -218,5 +218,5 @@ OnigEncodingDefine(cp949, CP949) = {
/*
* Name: CP949
* Link: http://www.microsoft.com/globaldev/reference/dbcs/949.mspx
- * Link: http://en.wikipedia.org/wiki/EUC-KR#EUC-KR
+ * Link: https://en.wikipedia.org/wiki/EUC-KR#EUC-KR
*/
diff --git a/enc/depend b/enc/depend
index 71345a91fc..26f8e70c15 100644
--- a/enc/depend
+++ b/enc/depend
@@ -97,7 +97,7 @@ $(ENCSOS) $(TRANSSOS): $(ENC_TRANS_SO_D)
<%=transvpath_prefix%>.trans<%=transvpath_prefix%>.c:
$(ECHO) generating table from $@
- $(Q)$(MINIRUBY) "$(srcdir)/tool/transcode-tblgen.rb" -vo "$@" "$<"
+ $(Q)$(MINIRUBY) "$(tooldir)/transcode-tblgen.rb" -vo "$@" "$<"
% unless ENCS.empty? or TRANS.empty?
@@ -113,7 +113,7 @@ enc/<%=e%>.$(OBJEXT): <%=deps.map {|n| rule_subst % n}.join(' ')%>
% if src.empty?
% src = trans.scan(/^\s*transcode_tblgen_\w+\s+[\'\"]([^\'\"]*)/).flatten.map{|c|c.downcase+"-tbl.rb"}
% end
-<%=transvpath % "#{e}.c"%>: <%= src.map {|s| transvpath % "#{s}"}.join(" ")%> $(srcdir)/tool/transcode-tblgen.rb
+<%=transvpath % "#{e}.c"%>: <%= src.map {|s| transvpath % "#{s}"}.join(" ")%> $(tooldir)/transcode-tblgen.rb
% end
% end
@@ -178,260 +178,2206 @@ clean-srcs:
<%# vim: set ft=eruby noexpandtab ts=8 sw=2 : -%>
# AUTOGENERATED DEPENDENCIES START
+enc/ascii.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/ascii.$(OBJEXT): $(top_srcdir)/encindex.h
enc/ascii.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/ascii.$(OBJEXT): internal/anyargs.h
+enc/ascii.$(OBJEXT): internal/arithmetic.h
+enc/ascii.$(OBJEXT): internal/arithmetic/char.h
+enc/ascii.$(OBJEXT): internal/arithmetic/double.h
+enc/ascii.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/ascii.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/ascii.$(OBJEXT): internal/arithmetic/int.h
+enc/ascii.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/ascii.$(OBJEXT): internal/arithmetic/long.h
+enc/ascii.$(OBJEXT): internal/arithmetic/long_long.h
+enc/ascii.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/ascii.$(OBJEXT): internal/arithmetic/off_t.h
+enc/ascii.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/ascii.$(OBJEXT): internal/arithmetic/short.h
+enc/ascii.$(OBJEXT): internal/arithmetic/size_t.h
+enc/ascii.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/ascii.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/ascii.$(OBJEXT): internal/assume.h
+enc/ascii.$(OBJEXT): internal/attr/alloc_size.h
+enc/ascii.$(OBJEXT): internal/attr/artificial.h
+enc/ascii.$(OBJEXT): internal/attr/cold.h
+enc/ascii.$(OBJEXT): internal/attr/const.h
+enc/ascii.$(OBJEXT): internal/attr/constexpr.h
+enc/ascii.$(OBJEXT): internal/attr/deprecated.h
+enc/ascii.$(OBJEXT): internal/attr/diagnose_if.h
+enc/ascii.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/ascii.$(OBJEXT): internal/attr/error.h
+enc/ascii.$(OBJEXT): internal/attr/flag_enum.h
+enc/ascii.$(OBJEXT): internal/attr/forceinline.h
+enc/ascii.$(OBJEXT): internal/attr/format.h
+enc/ascii.$(OBJEXT): internal/attr/maybe_unused.h
+enc/ascii.$(OBJEXT): internal/attr/noalias.h
+enc/ascii.$(OBJEXT): internal/attr/nodiscard.h
+enc/ascii.$(OBJEXT): internal/attr/noexcept.h
+enc/ascii.$(OBJEXT): internal/attr/noinline.h
+enc/ascii.$(OBJEXT): internal/attr/nonnull.h
+enc/ascii.$(OBJEXT): internal/attr/noreturn.h
+enc/ascii.$(OBJEXT): internal/attr/pure.h
+enc/ascii.$(OBJEXT): internal/attr/restrict.h
+enc/ascii.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/ascii.$(OBJEXT): internal/attr/warning.h
+enc/ascii.$(OBJEXT): internal/attr/weakref.h
+enc/ascii.$(OBJEXT): internal/cast.h
+enc/ascii.$(OBJEXT): internal/compiler_is.h
+enc/ascii.$(OBJEXT): internal/compiler_is/apple.h
+enc/ascii.$(OBJEXT): internal/compiler_is/clang.h
+enc/ascii.$(OBJEXT): internal/compiler_is/gcc.h
+enc/ascii.$(OBJEXT): internal/compiler_is/intel.h
+enc/ascii.$(OBJEXT): internal/compiler_is/msvc.h
+enc/ascii.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/ascii.$(OBJEXT): internal/compiler_since.h
+enc/ascii.$(OBJEXT): internal/config.h
+enc/ascii.$(OBJEXT): internal/constant_p.h
+enc/ascii.$(OBJEXT): internal/core.h
+enc/ascii.$(OBJEXT): internal/core/rarray.h
+enc/ascii.$(OBJEXT): internal/core/rbasic.h
+enc/ascii.$(OBJEXT): internal/core/rbignum.h
+enc/ascii.$(OBJEXT): internal/core/rclass.h
+enc/ascii.$(OBJEXT): internal/core/rdata.h
+enc/ascii.$(OBJEXT): internal/core/rfile.h
+enc/ascii.$(OBJEXT): internal/core/rhash.h
+enc/ascii.$(OBJEXT): internal/core/robject.h
+enc/ascii.$(OBJEXT): internal/core/rregexp.h
+enc/ascii.$(OBJEXT): internal/core/rstring.h
+enc/ascii.$(OBJEXT): internal/core/rstruct.h
+enc/ascii.$(OBJEXT): internal/core/rtypeddata.h
+enc/ascii.$(OBJEXT): internal/ctype.h
+enc/ascii.$(OBJEXT): internal/dllexport.h
+enc/ascii.$(OBJEXT): internal/dosish.h
+enc/ascii.$(OBJEXT): internal/error.h
+enc/ascii.$(OBJEXT): internal/eval.h
+enc/ascii.$(OBJEXT): internal/event.h
+enc/ascii.$(OBJEXT): internal/fl_type.h
+enc/ascii.$(OBJEXT): internal/gc.h
+enc/ascii.$(OBJEXT): internal/glob.h
+enc/ascii.$(OBJEXT): internal/globals.h
+enc/ascii.$(OBJEXT): internal/has/attribute.h
+enc/ascii.$(OBJEXT): internal/has/builtin.h
+enc/ascii.$(OBJEXT): internal/has/c_attribute.h
+enc/ascii.$(OBJEXT): internal/has/cpp_attribute.h
+enc/ascii.$(OBJEXT): internal/has/declspec_attribute.h
+enc/ascii.$(OBJEXT): internal/has/extension.h
+enc/ascii.$(OBJEXT): internal/has/feature.h
+enc/ascii.$(OBJEXT): internal/has/warning.h
+enc/ascii.$(OBJEXT): internal/intern/array.h
+enc/ascii.$(OBJEXT): internal/intern/bignum.h
+enc/ascii.$(OBJEXT): internal/intern/class.h
+enc/ascii.$(OBJEXT): internal/intern/compar.h
+enc/ascii.$(OBJEXT): internal/intern/complex.h
+enc/ascii.$(OBJEXT): internal/intern/cont.h
+enc/ascii.$(OBJEXT): internal/intern/dir.h
+enc/ascii.$(OBJEXT): internal/intern/enum.h
+enc/ascii.$(OBJEXT): internal/intern/enumerator.h
+enc/ascii.$(OBJEXT): internal/intern/error.h
+enc/ascii.$(OBJEXT): internal/intern/eval.h
+enc/ascii.$(OBJEXT): internal/intern/file.h
+enc/ascii.$(OBJEXT): internal/intern/gc.h
+enc/ascii.$(OBJEXT): internal/intern/hash.h
+enc/ascii.$(OBJEXT): internal/intern/io.h
+enc/ascii.$(OBJEXT): internal/intern/load.h
+enc/ascii.$(OBJEXT): internal/intern/marshal.h
+enc/ascii.$(OBJEXT): internal/intern/numeric.h
+enc/ascii.$(OBJEXT): internal/intern/object.h
+enc/ascii.$(OBJEXT): internal/intern/parse.h
+enc/ascii.$(OBJEXT): internal/intern/proc.h
+enc/ascii.$(OBJEXT): internal/intern/process.h
+enc/ascii.$(OBJEXT): internal/intern/random.h
+enc/ascii.$(OBJEXT): internal/intern/range.h
+enc/ascii.$(OBJEXT): internal/intern/rational.h
+enc/ascii.$(OBJEXT): internal/intern/re.h
+enc/ascii.$(OBJEXT): internal/intern/ruby.h
+enc/ascii.$(OBJEXT): internal/intern/select.h
+enc/ascii.$(OBJEXT): internal/intern/select/largesize.h
+enc/ascii.$(OBJEXT): internal/intern/signal.h
+enc/ascii.$(OBJEXT): internal/intern/sprintf.h
+enc/ascii.$(OBJEXT): internal/intern/string.h
+enc/ascii.$(OBJEXT): internal/intern/struct.h
+enc/ascii.$(OBJEXT): internal/intern/thread.h
+enc/ascii.$(OBJEXT): internal/intern/time.h
+enc/ascii.$(OBJEXT): internal/intern/variable.h
+enc/ascii.$(OBJEXT): internal/intern/vm.h
+enc/ascii.$(OBJEXT): internal/interpreter.h
+enc/ascii.$(OBJEXT): internal/iterator.h
+enc/ascii.$(OBJEXT): internal/memory.h
+enc/ascii.$(OBJEXT): internal/method.h
+enc/ascii.$(OBJEXT): internal/module.h
+enc/ascii.$(OBJEXT): internal/newobj.h
+enc/ascii.$(OBJEXT): internal/rgengc.h
+enc/ascii.$(OBJEXT): internal/scan_args.h
+enc/ascii.$(OBJEXT): internal/special_consts.h
+enc/ascii.$(OBJEXT): internal/static_assert.h
+enc/ascii.$(OBJEXT): internal/stdalign.h
+enc/ascii.$(OBJEXT): internal/stdbool.h
+enc/ascii.$(OBJEXT): internal/symbol.h
+enc/ascii.$(OBJEXT): internal/token_paste.h
+enc/ascii.$(OBJEXT): internal/value.h
+enc/ascii.$(OBJEXT): internal/value_type.h
+enc/ascii.$(OBJEXT): internal/variable.h
+enc/ascii.$(OBJEXT): internal/warning_push.h
+enc/ascii.$(OBJEXT): internal/xmalloc.h
+enc/ascii.$(OBJEXT): assert.h
+enc/ascii.$(OBJEXT): backward/2/assume.h
+enc/ascii.$(OBJEXT): backward/2/attributes.h
+enc/ascii.$(OBJEXT): backward/2/bool.h
+enc/ascii.$(OBJEXT): backward/2/gcc_version_since.h
+enc/ascii.$(OBJEXT): backward/2/inttypes.h
+enc/ascii.$(OBJEXT): backward/2/limits.h
+enc/ascii.$(OBJEXT): backward/2/long_long.h
+enc/ascii.$(OBJEXT): backward/2/stdalign.h
+enc/ascii.$(OBJEXT): backward/2/stdarg.h
enc/ascii.$(OBJEXT): config.h
enc/ascii.$(OBJEXT): defines.h
enc/ascii.$(OBJEXT): enc/ascii.c
+enc/ascii.$(OBJEXT): encoding.h
+enc/ascii.$(OBJEXT): intern.h
enc/ascii.$(OBJEXT): missing.h
enc/ascii.$(OBJEXT): onigmo.h
enc/ascii.$(OBJEXT): oniguruma.h
+enc/ascii.$(OBJEXT): st.h
+enc/ascii.$(OBJEXT): subst.h
enc/big5.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/big5.$(OBJEXT): internal/assume.h
+enc/big5.$(OBJEXT): internal/attr/alloc_size.h
+enc/big5.$(OBJEXT): internal/attr/cold.h
+enc/big5.$(OBJEXT): internal/attr/const.h
+enc/big5.$(OBJEXT): internal/attr/deprecated.h
+enc/big5.$(OBJEXT): internal/attr/error.h
+enc/big5.$(OBJEXT): internal/attr/forceinline.h
+enc/big5.$(OBJEXT): internal/attr/format.h
+enc/big5.$(OBJEXT): internal/attr/maybe_unused.h
+enc/big5.$(OBJEXT): internal/attr/nodiscard.h
+enc/big5.$(OBJEXT): internal/attr/noexcept.h
+enc/big5.$(OBJEXT): internal/attr/noinline.h
+enc/big5.$(OBJEXT): internal/attr/nonnull.h
+enc/big5.$(OBJEXT): internal/attr/noreturn.h
+enc/big5.$(OBJEXT): internal/attr/pure.h
+enc/big5.$(OBJEXT): internal/attr/restrict.h
+enc/big5.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/big5.$(OBJEXT): internal/attr/warning.h
+enc/big5.$(OBJEXT): internal/cast.h
+enc/big5.$(OBJEXT): internal/compiler_is.h
+enc/big5.$(OBJEXT): internal/compiler_is/apple.h
+enc/big5.$(OBJEXT): internal/compiler_is/clang.h
+enc/big5.$(OBJEXT): internal/compiler_is/gcc.h
+enc/big5.$(OBJEXT): internal/compiler_is/intel.h
+enc/big5.$(OBJEXT): internal/compiler_is/msvc.h
+enc/big5.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/big5.$(OBJEXT): internal/compiler_since.h
+enc/big5.$(OBJEXT): internal/config.h
+enc/big5.$(OBJEXT): internal/dllexport.h
+enc/big5.$(OBJEXT): internal/dosish.h
+enc/big5.$(OBJEXT): internal/has/attribute.h
+enc/big5.$(OBJEXT): internal/has/builtin.h
+enc/big5.$(OBJEXT): internal/has/c_attribute.h
+enc/big5.$(OBJEXT): internal/has/cpp_attribute.h
+enc/big5.$(OBJEXT): internal/has/declspec_attribute.h
+enc/big5.$(OBJEXT): internal/has/extension.h
+enc/big5.$(OBJEXT): internal/has/feature.h
+enc/big5.$(OBJEXT): internal/has/warning.h
+enc/big5.$(OBJEXT): internal/stdalign.h
+enc/big5.$(OBJEXT): internal/stdbool.h
+enc/big5.$(OBJEXT): internal/token_paste.h
+enc/big5.$(OBJEXT): internal/warning_push.h
+enc/big5.$(OBJEXT): internal/xmalloc.h
+enc/big5.$(OBJEXT): assert.h
+enc/big5.$(OBJEXT): backward/2/assume.h
+enc/big5.$(OBJEXT): backward/2/attributes.h
+enc/big5.$(OBJEXT): backward/2/bool.h
+enc/big5.$(OBJEXT): backward/2/gcc_version_since.h
+enc/big5.$(OBJEXT): backward/2/long_long.h
+enc/big5.$(OBJEXT): backward/2/stdalign.h
+enc/big5.$(OBJEXT): backward/2/stdarg.h
enc/big5.$(OBJEXT): config.h
enc/big5.$(OBJEXT): defines.h
enc/big5.$(OBJEXT): enc/big5.c
enc/big5.$(OBJEXT): missing.h
enc/big5.$(OBJEXT): onigmo.h
-enc/big5.$(OBJEXT): oniguruma.h
+enc/cesu_8.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+enc/cesu_8.$(OBJEXT): $(top_srcdir)/encindex.h
+enc/cesu_8.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/cesu_8.$(OBJEXT): internal/anyargs.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/char.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/double.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/int.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/long.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/long_long.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/off_t.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/short.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/size_t.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/cesu_8.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/cesu_8.$(OBJEXT): internal/assume.h
+enc/cesu_8.$(OBJEXT): internal/attr/alloc_size.h
+enc/cesu_8.$(OBJEXT): internal/attr/artificial.h
+enc/cesu_8.$(OBJEXT): internal/attr/cold.h
+enc/cesu_8.$(OBJEXT): internal/attr/const.h
+enc/cesu_8.$(OBJEXT): internal/attr/constexpr.h
+enc/cesu_8.$(OBJEXT): internal/attr/deprecated.h
+enc/cesu_8.$(OBJEXT): internal/attr/diagnose_if.h
+enc/cesu_8.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/cesu_8.$(OBJEXT): internal/attr/error.h
+enc/cesu_8.$(OBJEXT): internal/attr/flag_enum.h
+enc/cesu_8.$(OBJEXT): internal/attr/forceinline.h
+enc/cesu_8.$(OBJEXT): internal/attr/format.h
+enc/cesu_8.$(OBJEXT): internal/attr/maybe_unused.h
+enc/cesu_8.$(OBJEXT): internal/attr/noalias.h
+enc/cesu_8.$(OBJEXT): internal/attr/nodiscard.h
+enc/cesu_8.$(OBJEXT): internal/attr/noexcept.h
+enc/cesu_8.$(OBJEXT): internal/attr/noinline.h
+enc/cesu_8.$(OBJEXT): internal/attr/nonnull.h
+enc/cesu_8.$(OBJEXT): internal/attr/noreturn.h
+enc/cesu_8.$(OBJEXT): internal/attr/pure.h
+enc/cesu_8.$(OBJEXT): internal/attr/restrict.h
+enc/cesu_8.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/cesu_8.$(OBJEXT): internal/attr/warning.h
+enc/cesu_8.$(OBJEXT): internal/attr/weakref.h
+enc/cesu_8.$(OBJEXT): internal/cast.h
+enc/cesu_8.$(OBJEXT): internal/compiler_is.h
+enc/cesu_8.$(OBJEXT): internal/compiler_is/apple.h
+enc/cesu_8.$(OBJEXT): internal/compiler_is/clang.h
+enc/cesu_8.$(OBJEXT): internal/compiler_is/gcc.h
+enc/cesu_8.$(OBJEXT): internal/compiler_is/intel.h
+enc/cesu_8.$(OBJEXT): internal/compiler_is/msvc.h
+enc/cesu_8.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/cesu_8.$(OBJEXT): internal/compiler_since.h
+enc/cesu_8.$(OBJEXT): internal/config.h
+enc/cesu_8.$(OBJEXT): internal/constant_p.h
+enc/cesu_8.$(OBJEXT): internal/core.h
+enc/cesu_8.$(OBJEXT): internal/core/rarray.h
+enc/cesu_8.$(OBJEXT): internal/core/rbasic.h
+enc/cesu_8.$(OBJEXT): internal/core/rbignum.h
+enc/cesu_8.$(OBJEXT): internal/core/rclass.h
+enc/cesu_8.$(OBJEXT): internal/core/rdata.h
+enc/cesu_8.$(OBJEXT): internal/core/rfile.h
+enc/cesu_8.$(OBJEXT): internal/core/rhash.h
+enc/cesu_8.$(OBJEXT): internal/core/robject.h
+enc/cesu_8.$(OBJEXT): internal/core/rregexp.h
+enc/cesu_8.$(OBJEXT): internal/core/rstring.h
+enc/cesu_8.$(OBJEXT): internal/core/rstruct.h
+enc/cesu_8.$(OBJEXT): internal/core/rtypeddata.h
+enc/cesu_8.$(OBJEXT): internal/ctype.h
+enc/cesu_8.$(OBJEXT): internal/dllexport.h
+enc/cesu_8.$(OBJEXT): internal/dosish.h
+enc/cesu_8.$(OBJEXT): internal/error.h
+enc/cesu_8.$(OBJEXT): internal/eval.h
+enc/cesu_8.$(OBJEXT): internal/event.h
+enc/cesu_8.$(OBJEXT): internal/fl_type.h
+enc/cesu_8.$(OBJEXT): internal/gc.h
+enc/cesu_8.$(OBJEXT): internal/glob.h
+enc/cesu_8.$(OBJEXT): internal/globals.h
+enc/cesu_8.$(OBJEXT): internal/has/attribute.h
+enc/cesu_8.$(OBJEXT): internal/has/builtin.h
+enc/cesu_8.$(OBJEXT): internal/has/c_attribute.h
+enc/cesu_8.$(OBJEXT): internal/has/cpp_attribute.h
+enc/cesu_8.$(OBJEXT): internal/has/declspec_attribute.h
+enc/cesu_8.$(OBJEXT): internal/has/extension.h
+enc/cesu_8.$(OBJEXT): internal/has/feature.h
+enc/cesu_8.$(OBJEXT): internal/has/warning.h
+enc/cesu_8.$(OBJEXT): internal/intern/array.h
+enc/cesu_8.$(OBJEXT): internal/intern/bignum.h
+enc/cesu_8.$(OBJEXT): internal/intern/class.h
+enc/cesu_8.$(OBJEXT): internal/intern/compar.h
+enc/cesu_8.$(OBJEXT): internal/intern/complex.h
+enc/cesu_8.$(OBJEXT): internal/intern/cont.h
+enc/cesu_8.$(OBJEXT): internal/intern/dir.h
+enc/cesu_8.$(OBJEXT): internal/intern/enum.h
+enc/cesu_8.$(OBJEXT): internal/intern/enumerator.h
+enc/cesu_8.$(OBJEXT): internal/intern/error.h
+enc/cesu_8.$(OBJEXT): internal/intern/eval.h
+enc/cesu_8.$(OBJEXT): internal/intern/file.h
+enc/cesu_8.$(OBJEXT): internal/intern/gc.h
+enc/cesu_8.$(OBJEXT): internal/intern/hash.h
+enc/cesu_8.$(OBJEXT): internal/intern/io.h
+enc/cesu_8.$(OBJEXT): internal/intern/load.h
+enc/cesu_8.$(OBJEXT): internal/intern/marshal.h
+enc/cesu_8.$(OBJEXT): internal/intern/numeric.h
+enc/cesu_8.$(OBJEXT): internal/intern/object.h
+enc/cesu_8.$(OBJEXT): internal/intern/parse.h
+enc/cesu_8.$(OBJEXT): internal/intern/proc.h
+enc/cesu_8.$(OBJEXT): internal/intern/process.h
+enc/cesu_8.$(OBJEXT): internal/intern/random.h
+enc/cesu_8.$(OBJEXT): internal/intern/range.h
+enc/cesu_8.$(OBJEXT): internal/intern/rational.h
+enc/cesu_8.$(OBJEXT): internal/intern/re.h
+enc/cesu_8.$(OBJEXT): internal/intern/ruby.h
+enc/cesu_8.$(OBJEXT): internal/intern/select.h
+enc/cesu_8.$(OBJEXT): internal/intern/select/largesize.h
+enc/cesu_8.$(OBJEXT): internal/intern/signal.h
+enc/cesu_8.$(OBJEXT): internal/intern/sprintf.h
+enc/cesu_8.$(OBJEXT): internal/intern/string.h
+enc/cesu_8.$(OBJEXT): internal/intern/struct.h
+enc/cesu_8.$(OBJEXT): internal/intern/thread.h
+enc/cesu_8.$(OBJEXT): internal/intern/time.h
+enc/cesu_8.$(OBJEXT): internal/intern/variable.h
+enc/cesu_8.$(OBJEXT): internal/intern/vm.h
+enc/cesu_8.$(OBJEXT): internal/interpreter.h
+enc/cesu_8.$(OBJEXT): internal/iterator.h
+enc/cesu_8.$(OBJEXT): internal/memory.h
+enc/cesu_8.$(OBJEXT): internal/method.h
+enc/cesu_8.$(OBJEXT): internal/module.h
+enc/cesu_8.$(OBJEXT): internal/newobj.h
+enc/cesu_8.$(OBJEXT): internal/rgengc.h
+enc/cesu_8.$(OBJEXT): internal/scan_args.h
+enc/cesu_8.$(OBJEXT): internal/special_consts.h
+enc/cesu_8.$(OBJEXT): internal/static_assert.h
+enc/cesu_8.$(OBJEXT): internal/stdalign.h
+enc/cesu_8.$(OBJEXT): internal/stdbool.h
+enc/cesu_8.$(OBJEXT): internal/symbol.h
+enc/cesu_8.$(OBJEXT): internal/token_paste.h
+enc/cesu_8.$(OBJEXT): internal/value.h
+enc/cesu_8.$(OBJEXT): internal/value_type.h
+enc/cesu_8.$(OBJEXT): internal/variable.h
+enc/cesu_8.$(OBJEXT): internal/warning_push.h
+enc/cesu_8.$(OBJEXT): internal/xmalloc.h
+enc/cesu_8.$(OBJEXT): assert.h
+enc/cesu_8.$(OBJEXT): backward.h
+enc/cesu_8.$(OBJEXT): backward/2/assume.h
+enc/cesu_8.$(OBJEXT): backward/2/attributes.h
+enc/cesu_8.$(OBJEXT): backward/2/bool.h
+enc/cesu_8.$(OBJEXT): backward/2/gcc_version_since.h
+enc/cesu_8.$(OBJEXT): backward/2/inttypes.h
+enc/cesu_8.$(OBJEXT): backward/2/limits.h
+enc/cesu_8.$(OBJEXT): backward/2/long_long.h
+enc/cesu_8.$(OBJEXT): backward/2/stdalign.h
+enc/cesu_8.$(OBJEXT): backward/2/stdarg.h
+enc/cesu_8.$(OBJEXT): config.h
+enc/cesu_8.$(OBJEXT): defines.h
+enc/cesu_8.$(OBJEXT): enc/cesu_8.c
+enc/cesu_8.$(OBJEXT): encoding.h
+enc/cesu_8.$(OBJEXT): intern.h
+enc/cesu_8.$(OBJEXT): missing.h
+enc/cesu_8.$(OBJEXT): onigmo.h
+enc/cesu_8.$(OBJEXT): oniguruma.h
+enc/cesu_8.$(OBJEXT): st.h
+enc/cesu_8.$(OBJEXT): subst.h
enc/cp949.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/cp949.$(OBJEXT): internal/assume.h
+enc/cp949.$(OBJEXT): internal/attr/alloc_size.h
+enc/cp949.$(OBJEXT): internal/attr/cold.h
+enc/cp949.$(OBJEXT): internal/attr/const.h
+enc/cp949.$(OBJEXT): internal/attr/deprecated.h
+enc/cp949.$(OBJEXT): internal/attr/error.h
+enc/cp949.$(OBJEXT): internal/attr/forceinline.h
+enc/cp949.$(OBJEXT): internal/attr/format.h
+enc/cp949.$(OBJEXT): internal/attr/maybe_unused.h
+enc/cp949.$(OBJEXT): internal/attr/nodiscard.h
+enc/cp949.$(OBJEXT): internal/attr/noexcept.h
+enc/cp949.$(OBJEXT): internal/attr/noinline.h
+enc/cp949.$(OBJEXT): internal/attr/nonnull.h
+enc/cp949.$(OBJEXT): internal/attr/noreturn.h
+enc/cp949.$(OBJEXT): internal/attr/pure.h
+enc/cp949.$(OBJEXT): internal/attr/restrict.h
+enc/cp949.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/cp949.$(OBJEXT): internal/attr/warning.h
+enc/cp949.$(OBJEXT): internal/cast.h
+enc/cp949.$(OBJEXT): internal/compiler_is.h
+enc/cp949.$(OBJEXT): internal/compiler_is/apple.h
+enc/cp949.$(OBJEXT): internal/compiler_is/clang.h
+enc/cp949.$(OBJEXT): internal/compiler_is/gcc.h
+enc/cp949.$(OBJEXT): internal/compiler_is/intel.h
+enc/cp949.$(OBJEXT): internal/compiler_is/msvc.h
+enc/cp949.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/cp949.$(OBJEXT): internal/compiler_since.h
+enc/cp949.$(OBJEXT): internal/config.h
+enc/cp949.$(OBJEXT): internal/dllexport.h
+enc/cp949.$(OBJEXT): internal/dosish.h
+enc/cp949.$(OBJEXT): internal/has/attribute.h
+enc/cp949.$(OBJEXT): internal/has/builtin.h
+enc/cp949.$(OBJEXT): internal/has/c_attribute.h
+enc/cp949.$(OBJEXT): internal/has/cpp_attribute.h
+enc/cp949.$(OBJEXT): internal/has/declspec_attribute.h
+enc/cp949.$(OBJEXT): internal/has/extension.h
+enc/cp949.$(OBJEXT): internal/has/feature.h
+enc/cp949.$(OBJEXT): internal/has/warning.h
+enc/cp949.$(OBJEXT): internal/stdalign.h
+enc/cp949.$(OBJEXT): internal/stdbool.h
+enc/cp949.$(OBJEXT): internal/token_paste.h
+enc/cp949.$(OBJEXT): internal/warning_push.h
+enc/cp949.$(OBJEXT): internal/xmalloc.h
+enc/cp949.$(OBJEXT): assert.h
+enc/cp949.$(OBJEXT): backward/2/assume.h
+enc/cp949.$(OBJEXT): backward/2/attributes.h
+enc/cp949.$(OBJEXT): backward/2/bool.h
+enc/cp949.$(OBJEXT): backward/2/gcc_version_since.h
+enc/cp949.$(OBJEXT): backward/2/long_long.h
+enc/cp949.$(OBJEXT): backward/2/stdalign.h
+enc/cp949.$(OBJEXT): backward/2/stdarg.h
enc/cp949.$(OBJEXT): config.h
enc/cp949.$(OBJEXT): defines.h
enc/cp949.$(OBJEXT): enc/cp949.c
enc/cp949.$(OBJEXT): missing.h
enc/cp949.$(OBJEXT): onigmo.h
-enc/cp949.$(OBJEXT): oniguruma.h
-enc/emacs_mule.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/emacs_mule.$(OBJEXT): $(top_srcdir)/regenc.h
-enc/emacs_mule.$(OBJEXT): $(top_srcdir)/regint.h
-enc/emacs_mule.$(OBJEXT): backward.h
+enc/emacs_mule.$(OBJEXT): internal/assume.h
+enc/emacs_mule.$(OBJEXT): internal/attr/alloc_size.h
+enc/emacs_mule.$(OBJEXT): internal/attr/cold.h
+enc/emacs_mule.$(OBJEXT): internal/attr/const.h
+enc/emacs_mule.$(OBJEXT): internal/attr/deprecated.h
+enc/emacs_mule.$(OBJEXT): internal/attr/error.h
+enc/emacs_mule.$(OBJEXT): internal/attr/forceinline.h
+enc/emacs_mule.$(OBJEXT): internal/attr/format.h
+enc/emacs_mule.$(OBJEXT): internal/attr/maybe_unused.h
+enc/emacs_mule.$(OBJEXT): internal/attr/nodiscard.h
+enc/emacs_mule.$(OBJEXT): internal/attr/noexcept.h
+enc/emacs_mule.$(OBJEXT): internal/attr/noinline.h
+enc/emacs_mule.$(OBJEXT): internal/attr/nonnull.h
+enc/emacs_mule.$(OBJEXT): internal/attr/noreturn.h
+enc/emacs_mule.$(OBJEXT): internal/attr/pure.h
+enc/emacs_mule.$(OBJEXT): internal/attr/restrict.h
+enc/emacs_mule.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/emacs_mule.$(OBJEXT): internal/attr/warning.h
+enc/emacs_mule.$(OBJEXT): internal/cast.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_is.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_is/apple.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_is/clang.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_is/gcc.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_is/intel.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_is/msvc.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/emacs_mule.$(OBJEXT): internal/compiler_since.h
+enc/emacs_mule.$(OBJEXT): internal/config.h
+enc/emacs_mule.$(OBJEXT): internal/dllexport.h
+enc/emacs_mule.$(OBJEXT): internal/dosish.h
+enc/emacs_mule.$(OBJEXT): internal/has/attribute.h
+enc/emacs_mule.$(OBJEXT): internal/has/builtin.h
+enc/emacs_mule.$(OBJEXT): internal/has/c_attribute.h
+enc/emacs_mule.$(OBJEXT): internal/has/cpp_attribute.h
+enc/emacs_mule.$(OBJEXT): internal/has/declspec_attribute.h
+enc/emacs_mule.$(OBJEXT): internal/has/extension.h
+enc/emacs_mule.$(OBJEXT): internal/has/feature.h
+enc/emacs_mule.$(OBJEXT): internal/has/warning.h
+enc/emacs_mule.$(OBJEXT): internal/stdalign.h
+enc/emacs_mule.$(OBJEXT): internal/stdbool.h
+enc/emacs_mule.$(OBJEXT): internal/token_paste.h
+enc/emacs_mule.$(OBJEXT): internal/warning_push.h
+enc/emacs_mule.$(OBJEXT): internal/xmalloc.h
+enc/emacs_mule.$(OBJEXT): assert.h
+enc/emacs_mule.$(OBJEXT): backward/2/assume.h
+enc/emacs_mule.$(OBJEXT): backward/2/attributes.h
+enc/emacs_mule.$(OBJEXT): backward/2/bool.h
+enc/emacs_mule.$(OBJEXT): backward/2/gcc_version_since.h
+enc/emacs_mule.$(OBJEXT): backward/2/long_long.h
+enc/emacs_mule.$(OBJEXT): backward/2/stdalign.h
+enc/emacs_mule.$(OBJEXT): backward/2/stdarg.h
enc/emacs_mule.$(OBJEXT): config.h
enc/emacs_mule.$(OBJEXT): defines.h
enc/emacs_mule.$(OBJEXT): enc/emacs_mule.c
-enc/emacs_mule.$(OBJEXT): intern.h
enc/emacs_mule.$(OBJEXT): missing.h
enc/emacs_mule.$(OBJEXT): onigmo.h
-enc/emacs_mule.$(OBJEXT): oniguruma.h
-enc/emacs_mule.$(OBJEXT): st.h
-enc/emacs_mule.$(OBJEXT): subst.h
+enc/encdb.$(OBJEXT): $(hdrdir)/ruby.h
enc/encdb.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-enc/encdb.$(OBJEXT): $(top_srcdir)/include/ruby.h
enc/encdb.$(OBJEXT): $(top_srcdir)/internal.h
+enc/encdb.$(OBJEXT): $(top_srcdir)/internal/encoding.h
+enc/encdb.$(OBJEXT): internal/anyargs.h
+enc/encdb.$(OBJEXT): internal/arithmetic.h
+enc/encdb.$(OBJEXT): internal/arithmetic/char.h
+enc/encdb.$(OBJEXT): internal/arithmetic/double.h
+enc/encdb.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/encdb.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/encdb.$(OBJEXT): internal/arithmetic/int.h
+enc/encdb.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/encdb.$(OBJEXT): internal/arithmetic/long.h
+enc/encdb.$(OBJEXT): internal/arithmetic/long_long.h
+enc/encdb.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/encdb.$(OBJEXT): internal/arithmetic/off_t.h
+enc/encdb.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/encdb.$(OBJEXT): internal/arithmetic/short.h
+enc/encdb.$(OBJEXT): internal/arithmetic/size_t.h
+enc/encdb.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/encdb.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/encdb.$(OBJEXT): internal/assume.h
+enc/encdb.$(OBJEXT): internal/attr/alloc_size.h
+enc/encdb.$(OBJEXT): internal/attr/artificial.h
+enc/encdb.$(OBJEXT): internal/attr/cold.h
+enc/encdb.$(OBJEXT): internal/attr/const.h
+enc/encdb.$(OBJEXT): internal/attr/constexpr.h
+enc/encdb.$(OBJEXT): internal/attr/deprecated.h
+enc/encdb.$(OBJEXT): internal/attr/diagnose_if.h
+enc/encdb.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/encdb.$(OBJEXT): internal/attr/error.h
+enc/encdb.$(OBJEXT): internal/attr/flag_enum.h
+enc/encdb.$(OBJEXT): internal/attr/forceinline.h
+enc/encdb.$(OBJEXT): internal/attr/format.h
+enc/encdb.$(OBJEXT): internal/attr/maybe_unused.h
+enc/encdb.$(OBJEXT): internal/attr/noalias.h
+enc/encdb.$(OBJEXT): internal/attr/nodiscard.h
+enc/encdb.$(OBJEXT): internal/attr/noexcept.h
+enc/encdb.$(OBJEXT): internal/attr/noinline.h
+enc/encdb.$(OBJEXT): internal/attr/nonnull.h
+enc/encdb.$(OBJEXT): internal/attr/noreturn.h
+enc/encdb.$(OBJEXT): internal/attr/pure.h
+enc/encdb.$(OBJEXT): internal/attr/restrict.h
+enc/encdb.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/encdb.$(OBJEXT): internal/attr/warning.h
+enc/encdb.$(OBJEXT): internal/attr/weakref.h
+enc/encdb.$(OBJEXT): internal/cast.h
+enc/encdb.$(OBJEXT): internal/compiler_is.h
+enc/encdb.$(OBJEXT): internal/compiler_is/apple.h
+enc/encdb.$(OBJEXT): internal/compiler_is/clang.h
+enc/encdb.$(OBJEXT): internal/compiler_is/gcc.h
+enc/encdb.$(OBJEXT): internal/compiler_is/intel.h
+enc/encdb.$(OBJEXT): internal/compiler_is/msvc.h
+enc/encdb.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/encdb.$(OBJEXT): internal/compiler_since.h
+enc/encdb.$(OBJEXT): internal/config.h
+enc/encdb.$(OBJEXT): internal/constant_p.h
+enc/encdb.$(OBJEXT): internal/core.h
+enc/encdb.$(OBJEXT): internal/core/rarray.h
+enc/encdb.$(OBJEXT): internal/core/rbasic.h
+enc/encdb.$(OBJEXT): internal/core/rbignum.h
+enc/encdb.$(OBJEXT): internal/core/rclass.h
+enc/encdb.$(OBJEXT): internal/core/rdata.h
+enc/encdb.$(OBJEXT): internal/core/rfile.h
+enc/encdb.$(OBJEXT): internal/core/rhash.h
+enc/encdb.$(OBJEXT): internal/core/robject.h
+enc/encdb.$(OBJEXT): internal/core/rregexp.h
+enc/encdb.$(OBJEXT): internal/core/rstring.h
+enc/encdb.$(OBJEXT): internal/core/rstruct.h
+enc/encdb.$(OBJEXT): internal/core/rtypeddata.h
+enc/encdb.$(OBJEXT): internal/ctype.h
+enc/encdb.$(OBJEXT): internal/dllexport.h
+enc/encdb.$(OBJEXT): internal/dosish.h
+enc/encdb.$(OBJEXT): internal/error.h
+enc/encdb.$(OBJEXT): internal/eval.h
+enc/encdb.$(OBJEXT): internal/event.h
+enc/encdb.$(OBJEXT): internal/fl_type.h
+enc/encdb.$(OBJEXT): internal/gc.h
+enc/encdb.$(OBJEXT): internal/glob.h
+enc/encdb.$(OBJEXT): internal/globals.h
+enc/encdb.$(OBJEXT): internal/has/attribute.h
+enc/encdb.$(OBJEXT): internal/has/builtin.h
+enc/encdb.$(OBJEXT): internal/has/c_attribute.h
+enc/encdb.$(OBJEXT): internal/has/cpp_attribute.h
+enc/encdb.$(OBJEXT): internal/has/declspec_attribute.h
+enc/encdb.$(OBJEXT): internal/has/extension.h
+enc/encdb.$(OBJEXT): internal/has/feature.h
+enc/encdb.$(OBJEXT): internal/has/warning.h
+enc/encdb.$(OBJEXT): internal/intern/array.h
+enc/encdb.$(OBJEXT): internal/intern/bignum.h
+enc/encdb.$(OBJEXT): internal/intern/class.h
+enc/encdb.$(OBJEXT): internal/intern/compar.h
+enc/encdb.$(OBJEXT): internal/intern/complex.h
+enc/encdb.$(OBJEXT): internal/intern/cont.h
+enc/encdb.$(OBJEXT): internal/intern/dir.h
+enc/encdb.$(OBJEXT): internal/intern/enum.h
+enc/encdb.$(OBJEXT): internal/intern/enumerator.h
+enc/encdb.$(OBJEXT): internal/intern/error.h
+enc/encdb.$(OBJEXT): internal/intern/eval.h
+enc/encdb.$(OBJEXT): internal/intern/file.h
+enc/encdb.$(OBJEXT): internal/intern/gc.h
+enc/encdb.$(OBJEXT): internal/intern/hash.h
+enc/encdb.$(OBJEXT): internal/intern/io.h
+enc/encdb.$(OBJEXT): internal/intern/load.h
+enc/encdb.$(OBJEXT): internal/intern/marshal.h
+enc/encdb.$(OBJEXT): internal/intern/numeric.h
+enc/encdb.$(OBJEXT): internal/intern/object.h
+enc/encdb.$(OBJEXT): internal/intern/parse.h
+enc/encdb.$(OBJEXT): internal/intern/proc.h
+enc/encdb.$(OBJEXT): internal/intern/process.h
+enc/encdb.$(OBJEXT): internal/intern/random.h
+enc/encdb.$(OBJEXT): internal/intern/range.h
+enc/encdb.$(OBJEXT): internal/intern/rational.h
+enc/encdb.$(OBJEXT): internal/intern/re.h
+enc/encdb.$(OBJEXT): internal/intern/ruby.h
+enc/encdb.$(OBJEXT): internal/intern/select.h
+enc/encdb.$(OBJEXT): internal/intern/select/largesize.h
+enc/encdb.$(OBJEXT): internal/intern/signal.h
+enc/encdb.$(OBJEXT): internal/intern/sprintf.h
+enc/encdb.$(OBJEXT): internal/intern/string.h
+enc/encdb.$(OBJEXT): internal/intern/struct.h
+enc/encdb.$(OBJEXT): internal/intern/thread.h
+enc/encdb.$(OBJEXT): internal/intern/time.h
+enc/encdb.$(OBJEXT): internal/intern/variable.h
+enc/encdb.$(OBJEXT): internal/intern/vm.h
+enc/encdb.$(OBJEXT): internal/interpreter.h
+enc/encdb.$(OBJEXT): internal/iterator.h
+enc/encdb.$(OBJEXT): internal/memory.h
+enc/encdb.$(OBJEXT): internal/method.h
+enc/encdb.$(OBJEXT): internal/module.h
+enc/encdb.$(OBJEXT): internal/newobj.h
+enc/encdb.$(OBJEXT): internal/rgengc.h
+enc/encdb.$(OBJEXT): internal/scan_args.h
+enc/encdb.$(OBJEXT): internal/special_consts.h
+enc/encdb.$(OBJEXT): internal/static_assert.h
+enc/encdb.$(OBJEXT): internal/stdalign.h
+enc/encdb.$(OBJEXT): internal/stdbool.h
+enc/encdb.$(OBJEXT): internal/symbol.h
+enc/encdb.$(OBJEXT): internal/token_paste.h
+enc/encdb.$(OBJEXT): internal/value.h
+enc/encdb.$(OBJEXT): internal/value_type.h
+enc/encdb.$(OBJEXT): internal/variable.h
+enc/encdb.$(OBJEXT): internal/warning_push.h
+enc/encdb.$(OBJEXT): internal/xmalloc.h
+enc/encdb.$(OBJEXT): assert.h
enc/encdb.$(OBJEXT): backward.h
+enc/encdb.$(OBJEXT): backward/2/assume.h
+enc/encdb.$(OBJEXT): backward/2/attributes.h
+enc/encdb.$(OBJEXT): backward/2/bool.h
+enc/encdb.$(OBJEXT): backward/2/gcc_version_since.h
+enc/encdb.$(OBJEXT): backward/2/inttypes.h
+enc/encdb.$(OBJEXT): backward/2/limits.h
+enc/encdb.$(OBJEXT): backward/2/long_long.h
+enc/encdb.$(OBJEXT): backward/2/stdalign.h
+enc/encdb.$(OBJEXT): backward/2/stdarg.h
enc/encdb.$(OBJEXT): config.h
enc/encdb.$(OBJEXT): defines.h
enc/encdb.$(OBJEXT): enc/encdb.c
enc/encdb.$(OBJEXT): encdb.h
enc/encdb.$(OBJEXT): encoding.h
enc/encdb.$(OBJEXT): intern.h
-enc/encdb.$(OBJEXT): io.h
enc/encdb.$(OBJEXT): missing.h
enc/encdb.$(OBJEXT): onigmo.h
enc/encdb.$(OBJEXT): oniguruma.h
enc/encdb.$(OBJEXT): st.h
enc/encdb.$(OBJEXT): subst.h
-enc/euc_jp.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/euc_jp.$(OBJEXT): $(top_srcdir)/regenc.h
-enc/euc_jp.$(OBJEXT): $(top_srcdir)/regint.h
-enc/euc_jp.$(OBJEXT): backward.h
+enc/euc_jp.$(OBJEXT): internal/assume.h
+enc/euc_jp.$(OBJEXT): internal/attr/alloc_size.h
+enc/euc_jp.$(OBJEXT): internal/attr/cold.h
+enc/euc_jp.$(OBJEXT): internal/attr/const.h
+enc/euc_jp.$(OBJEXT): internal/attr/deprecated.h
+enc/euc_jp.$(OBJEXT): internal/attr/error.h
+enc/euc_jp.$(OBJEXT): internal/attr/forceinline.h
+enc/euc_jp.$(OBJEXT): internal/attr/format.h
+enc/euc_jp.$(OBJEXT): internal/attr/maybe_unused.h
+enc/euc_jp.$(OBJEXT): internal/attr/nodiscard.h
+enc/euc_jp.$(OBJEXT): internal/attr/noexcept.h
+enc/euc_jp.$(OBJEXT): internal/attr/noinline.h
+enc/euc_jp.$(OBJEXT): internal/attr/nonnull.h
+enc/euc_jp.$(OBJEXT): internal/attr/noreturn.h
+enc/euc_jp.$(OBJEXT): internal/attr/pure.h
+enc/euc_jp.$(OBJEXT): internal/attr/restrict.h
+enc/euc_jp.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/euc_jp.$(OBJEXT): internal/attr/warning.h
+enc/euc_jp.$(OBJEXT): internal/cast.h
+enc/euc_jp.$(OBJEXT): internal/compiler_is.h
+enc/euc_jp.$(OBJEXT): internal/compiler_is/apple.h
+enc/euc_jp.$(OBJEXT): internal/compiler_is/clang.h
+enc/euc_jp.$(OBJEXT): internal/compiler_is/gcc.h
+enc/euc_jp.$(OBJEXT): internal/compiler_is/intel.h
+enc/euc_jp.$(OBJEXT): internal/compiler_is/msvc.h
+enc/euc_jp.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/euc_jp.$(OBJEXT): internal/compiler_since.h
+enc/euc_jp.$(OBJEXT): internal/config.h
+enc/euc_jp.$(OBJEXT): internal/dllexport.h
+enc/euc_jp.$(OBJEXT): internal/dosish.h
+enc/euc_jp.$(OBJEXT): internal/has/attribute.h
+enc/euc_jp.$(OBJEXT): internal/has/builtin.h
+enc/euc_jp.$(OBJEXT): internal/has/c_attribute.h
+enc/euc_jp.$(OBJEXT): internal/has/cpp_attribute.h
+enc/euc_jp.$(OBJEXT): internal/has/declspec_attribute.h
+enc/euc_jp.$(OBJEXT): internal/has/extension.h
+enc/euc_jp.$(OBJEXT): internal/has/feature.h
+enc/euc_jp.$(OBJEXT): internal/has/warning.h
+enc/euc_jp.$(OBJEXT): internal/stdalign.h
+enc/euc_jp.$(OBJEXT): internal/stdbool.h
+enc/euc_jp.$(OBJEXT): internal/token_paste.h
+enc/euc_jp.$(OBJEXT): internal/warning_push.h
+enc/euc_jp.$(OBJEXT): internal/xmalloc.h
+enc/euc_jp.$(OBJEXT): assert.h
+enc/euc_jp.$(OBJEXT): backward/2/assume.h
+enc/euc_jp.$(OBJEXT): backward/2/attributes.h
+enc/euc_jp.$(OBJEXT): backward/2/bool.h
+enc/euc_jp.$(OBJEXT): backward/2/gcc_version_since.h
+enc/euc_jp.$(OBJEXT): backward/2/long_long.h
+enc/euc_jp.$(OBJEXT): backward/2/stdalign.h
+enc/euc_jp.$(OBJEXT): backward/2/stdarg.h
enc/euc_jp.$(OBJEXT): config.h
enc/euc_jp.$(OBJEXT): defines.h
enc/euc_jp.$(OBJEXT): enc/euc_jp.c
enc/euc_jp.$(OBJEXT): enc/jis/props.h
enc/euc_jp.$(OBJEXT): enc/jis/props.kwd
-enc/euc_jp.$(OBJEXT): intern.h
enc/euc_jp.$(OBJEXT): missing.h
enc/euc_jp.$(OBJEXT): onigmo.h
-enc/euc_jp.$(OBJEXT): oniguruma.h
-enc/euc_jp.$(OBJEXT): st.h
-enc/euc_jp.$(OBJEXT): subst.h
enc/euc_kr.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/euc_kr.$(OBJEXT): internal/assume.h
+enc/euc_kr.$(OBJEXT): internal/attr/alloc_size.h
+enc/euc_kr.$(OBJEXT): internal/attr/cold.h
+enc/euc_kr.$(OBJEXT): internal/attr/const.h
+enc/euc_kr.$(OBJEXT): internal/attr/deprecated.h
+enc/euc_kr.$(OBJEXT): internal/attr/error.h
+enc/euc_kr.$(OBJEXT): internal/attr/forceinline.h
+enc/euc_kr.$(OBJEXT): internal/attr/format.h
+enc/euc_kr.$(OBJEXT): internal/attr/maybe_unused.h
+enc/euc_kr.$(OBJEXT): internal/attr/nodiscard.h
+enc/euc_kr.$(OBJEXT): internal/attr/noexcept.h
+enc/euc_kr.$(OBJEXT): internal/attr/noinline.h
+enc/euc_kr.$(OBJEXT): internal/attr/nonnull.h
+enc/euc_kr.$(OBJEXT): internal/attr/noreturn.h
+enc/euc_kr.$(OBJEXT): internal/attr/pure.h
+enc/euc_kr.$(OBJEXT): internal/attr/restrict.h
+enc/euc_kr.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/euc_kr.$(OBJEXT): internal/attr/warning.h
+enc/euc_kr.$(OBJEXT): internal/cast.h
+enc/euc_kr.$(OBJEXT): internal/compiler_is.h
+enc/euc_kr.$(OBJEXT): internal/compiler_is/apple.h
+enc/euc_kr.$(OBJEXT): internal/compiler_is/clang.h
+enc/euc_kr.$(OBJEXT): internal/compiler_is/gcc.h
+enc/euc_kr.$(OBJEXT): internal/compiler_is/intel.h
+enc/euc_kr.$(OBJEXT): internal/compiler_is/msvc.h
+enc/euc_kr.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/euc_kr.$(OBJEXT): internal/compiler_since.h
+enc/euc_kr.$(OBJEXT): internal/config.h
+enc/euc_kr.$(OBJEXT): internal/dllexport.h
+enc/euc_kr.$(OBJEXT): internal/dosish.h
+enc/euc_kr.$(OBJEXT): internal/has/attribute.h
+enc/euc_kr.$(OBJEXT): internal/has/builtin.h
+enc/euc_kr.$(OBJEXT): internal/has/c_attribute.h
+enc/euc_kr.$(OBJEXT): internal/has/cpp_attribute.h
+enc/euc_kr.$(OBJEXT): internal/has/declspec_attribute.h
+enc/euc_kr.$(OBJEXT): internal/has/extension.h
+enc/euc_kr.$(OBJEXT): internal/has/feature.h
+enc/euc_kr.$(OBJEXT): internal/has/warning.h
+enc/euc_kr.$(OBJEXT): internal/stdalign.h
+enc/euc_kr.$(OBJEXT): internal/stdbool.h
+enc/euc_kr.$(OBJEXT): internal/token_paste.h
+enc/euc_kr.$(OBJEXT): internal/warning_push.h
+enc/euc_kr.$(OBJEXT): internal/xmalloc.h
+enc/euc_kr.$(OBJEXT): assert.h
+enc/euc_kr.$(OBJEXT): backward/2/assume.h
+enc/euc_kr.$(OBJEXT): backward/2/attributes.h
+enc/euc_kr.$(OBJEXT): backward/2/bool.h
+enc/euc_kr.$(OBJEXT): backward/2/gcc_version_since.h
+enc/euc_kr.$(OBJEXT): backward/2/long_long.h
+enc/euc_kr.$(OBJEXT): backward/2/stdalign.h
+enc/euc_kr.$(OBJEXT): backward/2/stdarg.h
enc/euc_kr.$(OBJEXT): config.h
enc/euc_kr.$(OBJEXT): defines.h
enc/euc_kr.$(OBJEXT): enc/euc_kr.c
enc/euc_kr.$(OBJEXT): missing.h
enc/euc_kr.$(OBJEXT): onigmo.h
-enc/euc_kr.$(OBJEXT): oniguruma.h
enc/euc_tw.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/euc_tw.$(OBJEXT): internal/assume.h
+enc/euc_tw.$(OBJEXT): internal/attr/alloc_size.h
+enc/euc_tw.$(OBJEXT): internal/attr/cold.h
+enc/euc_tw.$(OBJEXT): internal/attr/const.h
+enc/euc_tw.$(OBJEXT): internal/attr/deprecated.h
+enc/euc_tw.$(OBJEXT): internal/attr/error.h
+enc/euc_tw.$(OBJEXT): internal/attr/forceinline.h
+enc/euc_tw.$(OBJEXT): internal/attr/format.h
+enc/euc_tw.$(OBJEXT): internal/attr/maybe_unused.h
+enc/euc_tw.$(OBJEXT): internal/attr/nodiscard.h
+enc/euc_tw.$(OBJEXT): internal/attr/noexcept.h
+enc/euc_tw.$(OBJEXT): internal/attr/noinline.h
+enc/euc_tw.$(OBJEXT): internal/attr/nonnull.h
+enc/euc_tw.$(OBJEXT): internal/attr/noreturn.h
+enc/euc_tw.$(OBJEXT): internal/attr/pure.h
+enc/euc_tw.$(OBJEXT): internal/attr/restrict.h
+enc/euc_tw.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/euc_tw.$(OBJEXT): internal/attr/warning.h
+enc/euc_tw.$(OBJEXT): internal/cast.h
+enc/euc_tw.$(OBJEXT): internal/compiler_is.h
+enc/euc_tw.$(OBJEXT): internal/compiler_is/apple.h
+enc/euc_tw.$(OBJEXT): internal/compiler_is/clang.h
+enc/euc_tw.$(OBJEXT): internal/compiler_is/gcc.h
+enc/euc_tw.$(OBJEXT): internal/compiler_is/intel.h
+enc/euc_tw.$(OBJEXT): internal/compiler_is/msvc.h
+enc/euc_tw.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/euc_tw.$(OBJEXT): internal/compiler_since.h
+enc/euc_tw.$(OBJEXT): internal/config.h
+enc/euc_tw.$(OBJEXT): internal/dllexport.h
+enc/euc_tw.$(OBJEXT): internal/dosish.h
+enc/euc_tw.$(OBJEXT): internal/has/attribute.h
+enc/euc_tw.$(OBJEXT): internal/has/builtin.h
+enc/euc_tw.$(OBJEXT): internal/has/c_attribute.h
+enc/euc_tw.$(OBJEXT): internal/has/cpp_attribute.h
+enc/euc_tw.$(OBJEXT): internal/has/declspec_attribute.h
+enc/euc_tw.$(OBJEXT): internal/has/extension.h
+enc/euc_tw.$(OBJEXT): internal/has/feature.h
+enc/euc_tw.$(OBJEXT): internal/has/warning.h
+enc/euc_tw.$(OBJEXT): internal/stdalign.h
+enc/euc_tw.$(OBJEXT): internal/stdbool.h
+enc/euc_tw.$(OBJEXT): internal/token_paste.h
+enc/euc_tw.$(OBJEXT): internal/warning_push.h
+enc/euc_tw.$(OBJEXT): internal/xmalloc.h
+enc/euc_tw.$(OBJEXT): assert.h
+enc/euc_tw.$(OBJEXT): backward/2/assume.h
+enc/euc_tw.$(OBJEXT): backward/2/attributes.h
+enc/euc_tw.$(OBJEXT): backward/2/bool.h
+enc/euc_tw.$(OBJEXT): backward/2/gcc_version_since.h
+enc/euc_tw.$(OBJEXT): backward/2/long_long.h
+enc/euc_tw.$(OBJEXT): backward/2/stdalign.h
+enc/euc_tw.$(OBJEXT): backward/2/stdarg.h
enc/euc_tw.$(OBJEXT): config.h
enc/euc_tw.$(OBJEXT): defines.h
enc/euc_tw.$(OBJEXT): enc/euc_tw.c
enc/euc_tw.$(OBJEXT): missing.h
enc/euc_tw.$(OBJEXT): onigmo.h
-enc/euc_tw.$(OBJEXT): oniguruma.h
enc/gb18030.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/gb18030.$(OBJEXT): internal/assume.h
+enc/gb18030.$(OBJEXT): internal/attr/alloc_size.h
+enc/gb18030.$(OBJEXT): internal/attr/cold.h
+enc/gb18030.$(OBJEXT): internal/attr/const.h
+enc/gb18030.$(OBJEXT): internal/attr/deprecated.h
+enc/gb18030.$(OBJEXT): internal/attr/error.h
+enc/gb18030.$(OBJEXT): internal/attr/forceinline.h
+enc/gb18030.$(OBJEXT): internal/attr/format.h
+enc/gb18030.$(OBJEXT): internal/attr/maybe_unused.h
+enc/gb18030.$(OBJEXT): internal/attr/nodiscard.h
+enc/gb18030.$(OBJEXT): internal/attr/noexcept.h
+enc/gb18030.$(OBJEXT): internal/attr/noinline.h
+enc/gb18030.$(OBJEXT): internal/attr/nonnull.h
+enc/gb18030.$(OBJEXT): internal/attr/noreturn.h
+enc/gb18030.$(OBJEXT): internal/attr/pure.h
+enc/gb18030.$(OBJEXT): internal/attr/restrict.h
+enc/gb18030.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/gb18030.$(OBJEXT): internal/attr/warning.h
+enc/gb18030.$(OBJEXT): internal/cast.h
+enc/gb18030.$(OBJEXT): internal/compiler_is.h
+enc/gb18030.$(OBJEXT): internal/compiler_is/apple.h
+enc/gb18030.$(OBJEXT): internal/compiler_is/clang.h
+enc/gb18030.$(OBJEXT): internal/compiler_is/gcc.h
+enc/gb18030.$(OBJEXT): internal/compiler_is/intel.h
+enc/gb18030.$(OBJEXT): internal/compiler_is/msvc.h
+enc/gb18030.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/gb18030.$(OBJEXT): internal/compiler_since.h
+enc/gb18030.$(OBJEXT): internal/config.h
+enc/gb18030.$(OBJEXT): internal/dllexport.h
+enc/gb18030.$(OBJEXT): internal/dosish.h
+enc/gb18030.$(OBJEXT): internal/has/attribute.h
+enc/gb18030.$(OBJEXT): internal/has/builtin.h
+enc/gb18030.$(OBJEXT): internal/has/c_attribute.h
+enc/gb18030.$(OBJEXT): internal/has/cpp_attribute.h
+enc/gb18030.$(OBJEXT): internal/has/declspec_attribute.h
+enc/gb18030.$(OBJEXT): internal/has/extension.h
+enc/gb18030.$(OBJEXT): internal/has/feature.h
+enc/gb18030.$(OBJEXT): internal/has/warning.h
+enc/gb18030.$(OBJEXT): internal/stdalign.h
+enc/gb18030.$(OBJEXT): internal/stdbool.h
+enc/gb18030.$(OBJEXT): internal/token_paste.h
+enc/gb18030.$(OBJEXT): internal/warning_push.h
+enc/gb18030.$(OBJEXT): internal/xmalloc.h
+enc/gb18030.$(OBJEXT): assert.h
+enc/gb18030.$(OBJEXT): backward/2/assume.h
+enc/gb18030.$(OBJEXT): backward/2/attributes.h
+enc/gb18030.$(OBJEXT): backward/2/bool.h
+enc/gb18030.$(OBJEXT): backward/2/gcc_version_since.h
+enc/gb18030.$(OBJEXT): backward/2/long_long.h
+enc/gb18030.$(OBJEXT): backward/2/stdalign.h
+enc/gb18030.$(OBJEXT): backward/2/stdarg.h
enc/gb18030.$(OBJEXT): config.h
enc/gb18030.$(OBJEXT): defines.h
enc/gb18030.$(OBJEXT): enc/gb18030.c
enc/gb18030.$(OBJEXT): missing.h
enc/gb18030.$(OBJEXT): onigmo.h
-enc/gb18030.$(OBJEXT): oniguruma.h
-enc/gb2312.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/gb2312.$(OBJEXT): $(top_srcdir)/regenc.h
-enc/gb2312.$(OBJEXT): backward.h
+enc/gb2312.$(OBJEXT): internal/assume.h
+enc/gb2312.$(OBJEXT): internal/attr/alloc_size.h
+enc/gb2312.$(OBJEXT): internal/attr/cold.h
+enc/gb2312.$(OBJEXT): internal/attr/const.h
+enc/gb2312.$(OBJEXT): internal/attr/deprecated.h
+enc/gb2312.$(OBJEXT): internal/attr/error.h
+enc/gb2312.$(OBJEXT): internal/attr/forceinline.h
+enc/gb2312.$(OBJEXT): internal/attr/format.h
+enc/gb2312.$(OBJEXT): internal/attr/maybe_unused.h
+enc/gb2312.$(OBJEXT): internal/attr/nodiscard.h
+enc/gb2312.$(OBJEXT): internal/attr/noexcept.h
+enc/gb2312.$(OBJEXT): internal/attr/noinline.h
+enc/gb2312.$(OBJEXT): internal/attr/nonnull.h
+enc/gb2312.$(OBJEXT): internal/attr/noreturn.h
+enc/gb2312.$(OBJEXT): internal/attr/pure.h
+enc/gb2312.$(OBJEXT): internal/attr/restrict.h
+enc/gb2312.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/gb2312.$(OBJEXT): internal/attr/warning.h
+enc/gb2312.$(OBJEXT): internal/cast.h
+enc/gb2312.$(OBJEXT): internal/compiler_is.h
+enc/gb2312.$(OBJEXT): internal/compiler_is/apple.h
+enc/gb2312.$(OBJEXT): internal/compiler_is/clang.h
+enc/gb2312.$(OBJEXT): internal/compiler_is/gcc.h
+enc/gb2312.$(OBJEXT): internal/compiler_is/intel.h
+enc/gb2312.$(OBJEXT): internal/compiler_is/msvc.h
+enc/gb2312.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/gb2312.$(OBJEXT): internal/compiler_since.h
+enc/gb2312.$(OBJEXT): internal/config.h
+enc/gb2312.$(OBJEXT): internal/dllexport.h
+enc/gb2312.$(OBJEXT): internal/dosish.h
+enc/gb2312.$(OBJEXT): internal/has/attribute.h
+enc/gb2312.$(OBJEXT): internal/has/builtin.h
+enc/gb2312.$(OBJEXT): internal/has/c_attribute.h
+enc/gb2312.$(OBJEXT): internal/has/cpp_attribute.h
+enc/gb2312.$(OBJEXT): internal/has/declspec_attribute.h
+enc/gb2312.$(OBJEXT): internal/has/extension.h
+enc/gb2312.$(OBJEXT): internal/has/feature.h
+enc/gb2312.$(OBJEXT): internal/has/warning.h
+enc/gb2312.$(OBJEXT): internal/stdalign.h
+enc/gb2312.$(OBJEXT): internal/stdbool.h
+enc/gb2312.$(OBJEXT): internal/token_paste.h
+enc/gb2312.$(OBJEXT): internal/warning_push.h
+enc/gb2312.$(OBJEXT): internal/xmalloc.h
+enc/gb2312.$(OBJEXT): assert.h
+enc/gb2312.$(OBJEXT): backward/2/assume.h
+enc/gb2312.$(OBJEXT): backward/2/attributes.h
+enc/gb2312.$(OBJEXT): backward/2/bool.h
+enc/gb2312.$(OBJEXT): backward/2/gcc_version_since.h
+enc/gb2312.$(OBJEXT): backward/2/long_long.h
+enc/gb2312.$(OBJEXT): backward/2/stdalign.h
+enc/gb2312.$(OBJEXT): backward/2/stdarg.h
enc/gb2312.$(OBJEXT): config.h
enc/gb2312.$(OBJEXT): defines.h
enc/gb2312.$(OBJEXT): enc/gb2312.c
-enc/gb2312.$(OBJEXT): encoding.h
-enc/gb2312.$(OBJEXT): intern.h
enc/gb2312.$(OBJEXT): missing.h
enc/gb2312.$(OBJEXT): onigmo.h
-enc/gb2312.$(OBJEXT): oniguruma.h
-enc/gb2312.$(OBJEXT): st.h
-enc/gb2312.$(OBJEXT): subst.h
enc/gbk.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/gbk.$(OBJEXT): internal/assume.h
+enc/gbk.$(OBJEXT): internal/attr/alloc_size.h
+enc/gbk.$(OBJEXT): internal/attr/cold.h
+enc/gbk.$(OBJEXT): internal/attr/const.h
+enc/gbk.$(OBJEXT): internal/attr/deprecated.h
+enc/gbk.$(OBJEXT): internal/attr/error.h
+enc/gbk.$(OBJEXT): internal/attr/forceinline.h
+enc/gbk.$(OBJEXT): internal/attr/format.h
+enc/gbk.$(OBJEXT): internal/attr/maybe_unused.h
+enc/gbk.$(OBJEXT): internal/attr/nodiscard.h
+enc/gbk.$(OBJEXT): internal/attr/noexcept.h
+enc/gbk.$(OBJEXT): internal/attr/noinline.h
+enc/gbk.$(OBJEXT): internal/attr/nonnull.h
+enc/gbk.$(OBJEXT): internal/attr/noreturn.h
+enc/gbk.$(OBJEXT): internal/attr/pure.h
+enc/gbk.$(OBJEXT): internal/attr/restrict.h
+enc/gbk.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/gbk.$(OBJEXT): internal/attr/warning.h
+enc/gbk.$(OBJEXT): internal/cast.h
+enc/gbk.$(OBJEXT): internal/compiler_is.h
+enc/gbk.$(OBJEXT): internal/compiler_is/apple.h
+enc/gbk.$(OBJEXT): internal/compiler_is/clang.h
+enc/gbk.$(OBJEXT): internal/compiler_is/gcc.h
+enc/gbk.$(OBJEXT): internal/compiler_is/intel.h
+enc/gbk.$(OBJEXT): internal/compiler_is/msvc.h
+enc/gbk.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/gbk.$(OBJEXT): internal/compiler_since.h
+enc/gbk.$(OBJEXT): internal/config.h
+enc/gbk.$(OBJEXT): internal/dllexport.h
+enc/gbk.$(OBJEXT): internal/dosish.h
+enc/gbk.$(OBJEXT): internal/has/attribute.h
+enc/gbk.$(OBJEXT): internal/has/builtin.h
+enc/gbk.$(OBJEXT): internal/has/c_attribute.h
+enc/gbk.$(OBJEXT): internal/has/cpp_attribute.h
+enc/gbk.$(OBJEXT): internal/has/declspec_attribute.h
+enc/gbk.$(OBJEXT): internal/has/extension.h
+enc/gbk.$(OBJEXT): internal/has/feature.h
+enc/gbk.$(OBJEXT): internal/has/warning.h
+enc/gbk.$(OBJEXT): internal/stdalign.h
+enc/gbk.$(OBJEXT): internal/stdbool.h
+enc/gbk.$(OBJEXT): internal/token_paste.h
+enc/gbk.$(OBJEXT): internal/warning_push.h
+enc/gbk.$(OBJEXT): internal/xmalloc.h
+enc/gbk.$(OBJEXT): assert.h
+enc/gbk.$(OBJEXT): backward/2/assume.h
+enc/gbk.$(OBJEXT): backward/2/attributes.h
+enc/gbk.$(OBJEXT): backward/2/bool.h
+enc/gbk.$(OBJEXT): backward/2/gcc_version_since.h
+enc/gbk.$(OBJEXT): backward/2/long_long.h
+enc/gbk.$(OBJEXT): backward/2/stdalign.h
+enc/gbk.$(OBJEXT): backward/2/stdarg.h
enc/gbk.$(OBJEXT): config.h
enc/gbk.$(OBJEXT): defines.h
enc/gbk.$(OBJEXT): enc/gbk.c
enc/gbk.$(OBJEXT): missing.h
enc/gbk.$(OBJEXT): onigmo.h
-enc/gbk.$(OBJEXT): oniguruma.h
enc/iso_8859_1.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_1.$(OBJEXT): internal/assume.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_1.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_1.$(OBJEXT): internal/cast.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_1.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_1.$(OBJEXT): internal/config.h
+enc/iso_8859_1.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_1.$(OBJEXT): internal/dosish.h
+enc/iso_8859_1.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_1.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_1.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_1.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_1.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_1.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_1.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_1.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_1.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_1.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_1.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_1.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_1.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_1.$(OBJEXT): assert.h
+enc/iso_8859_1.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_1.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_1.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_1.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_1.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_1.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_1.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_1.$(OBJEXT): config.h
enc/iso_8859_1.$(OBJEXT): defines.h
enc/iso_8859_1.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_1.$(OBJEXT): enc/iso_8859_1.c
enc/iso_8859_1.$(OBJEXT): missing.h
enc/iso_8859_1.$(OBJEXT): onigmo.h
-enc/iso_8859_1.$(OBJEXT): oniguruma.h
enc/iso_8859_10.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_10.$(OBJEXT): internal/assume.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_10.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_10.$(OBJEXT): internal/cast.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_10.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_10.$(OBJEXT): internal/config.h
+enc/iso_8859_10.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_10.$(OBJEXT): internal/dosish.h
+enc/iso_8859_10.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_10.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_10.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_10.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_10.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_10.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_10.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_10.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_10.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_10.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_10.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_10.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_10.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_10.$(OBJEXT): assert.h
+enc/iso_8859_10.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_10.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_10.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_10.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_10.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_10.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_10.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_10.$(OBJEXT): config.h
enc/iso_8859_10.$(OBJEXT): defines.h
enc/iso_8859_10.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_10.$(OBJEXT): enc/iso_8859_10.c
enc/iso_8859_10.$(OBJEXT): missing.h
enc/iso_8859_10.$(OBJEXT): onigmo.h
-enc/iso_8859_10.$(OBJEXT): oniguruma.h
enc/iso_8859_11.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_11.$(OBJEXT): internal/assume.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_11.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_11.$(OBJEXT): internal/cast.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_11.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_11.$(OBJEXT): internal/config.h
+enc/iso_8859_11.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_11.$(OBJEXT): internal/dosish.h
+enc/iso_8859_11.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_11.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_11.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_11.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_11.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_11.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_11.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_11.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_11.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_11.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_11.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_11.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_11.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_11.$(OBJEXT): assert.h
+enc/iso_8859_11.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_11.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_11.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_11.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_11.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_11.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_11.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_11.$(OBJEXT): config.h
enc/iso_8859_11.$(OBJEXT): defines.h
enc/iso_8859_11.$(OBJEXT): enc/iso_8859_11.c
enc/iso_8859_11.$(OBJEXT): missing.h
enc/iso_8859_11.$(OBJEXT): onigmo.h
-enc/iso_8859_11.$(OBJEXT): oniguruma.h
enc/iso_8859_13.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_13.$(OBJEXT): internal/assume.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_13.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_13.$(OBJEXT): internal/cast.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_13.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_13.$(OBJEXT): internal/config.h
+enc/iso_8859_13.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_13.$(OBJEXT): internal/dosish.h
+enc/iso_8859_13.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_13.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_13.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_13.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_13.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_13.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_13.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_13.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_13.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_13.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_13.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_13.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_13.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_13.$(OBJEXT): assert.h
+enc/iso_8859_13.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_13.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_13.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_13.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_13.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_13.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_13.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_13.$(OBJEXT): config.h
enc/iso_8859_13.$(OBJEXT): defines.h
enc/iso_8859_13.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_13.$(OBJEXT): enc/iso_8859_13.c
enc/iso_8859_13.$(OBJEXT): missing.h
enc/iso_8859_13.$(OBJEXT): onigmo.h
-enc/iso_8859_13.$(OBJEXT): oniguruma.h
enc/iso_8859_14.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_14.$(OBJEXT): internal/assume.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_14.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_14.$(OBJEXT): internal/cast.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_14.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_14.$(OBJEXT): internal/config.h
+enc/iso_8859_14.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_14.$(OBJEXT): internal/dosish.h
+enc/iso_8859_14.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_14.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_14.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_14.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_14.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_14.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_14.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_14.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_14.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_14.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_14.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_14.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_14.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_14.$(OBJEXT): assert.h
+enc/iso_8859_14.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_14.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_14.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_14.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_14.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_14.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_14.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_14.$(OBJEXT): config.h
enc/iso_8859_14.$(OBJEXT): defines.h
enc/iso_8859_14.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_14.$(OBJEXT): enc/iso_8859_14.c
enc/iso_8859_14.$(OBJEXT): missing.h
enc/iso_8859_14.$(OBJEXT): onigmo.h
-enc/iso_8859_14.$(OBJEXT): oniguruma.h
enc/iso_8859_15.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_15.$(OBJEXT): internal/assume.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_15.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_15.$(OBJEXT): internal/cast.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_15.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_15.$(OBJEXT): internal/config.h
+enc/iso_8859_15.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_15.$(OBJEXT): internal/dosish.h
+enc/iso_8859_15.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_15.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_15.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_15.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_15.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_15.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_15.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_15.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_15.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_15.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_15.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_15.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_15.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_15.$(OBJEXT): assert.h
+enc/iso_8859_15.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_15.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_15.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_15.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_15.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_15.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_15.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_15.$(OBJEXT): config.h
enc/iso_8859_15.$(OBJEXT): defines.h
enc/iso_8859_15.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_15.$(OBJEXT): enc/iso_8859_15.c
enc/iso_8859_15.$(OBJEXT): missing.h
enc/iso_8859_15.$(OBJEXT): onigmo.h
-enc/iso_8859_15.$(OBJEXT): oniguruma.h
enc/iso_8859_16.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_16.$(OBJEXT): internal/assume.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_16.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_16.$(OBJEXT): internal/cast.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_16.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_16.$(OBJEXT): internal/config.h
+enc/iso_8859_16.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_16.$(OBJEXT): internal/dosish.h
+enc/iso_8859_16.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_16.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_16.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_16.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_16.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_16.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_16.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_16.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_16.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_16.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_16.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_16.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_16.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_16.$(OBJEXT): assert.h
+enc/iso_8859_16.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_16.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_16.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_16.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_16.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_16.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_16.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_16.$(OBJEXT): config.h
enc/iso_8859_16.$(OBJEXT): defines.h
enc/iso_8859_16.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_16.$(OBJEXT): enc/iso_8859_16.c
enc/iso_8859_16.$(OBJEXT): missing.h
enc/iso_8859_16.$(OBJEXT): onigmo.h
-enc/iso_8859_16.$(OBJEXT): oniguruma.h
enc/iso_8859_2.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_2.$(OBJEXT): internal/assume.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_2.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_2.$(OBJEXT): internal/cast.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_2.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_2.$(OBJEXT): internal/config.h
+enc/iso_8859_2.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_2.$(OBJEXT): internal/dosish.h
+enc/iso_8859_2.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_2.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_2.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_2.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_2.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_2.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_2.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_2.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_2.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_2.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_2.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_2.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_2.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_2.$(OBJEXT): assert.h
+enc/iso_8859_2.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_2.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_2.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_2.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_2.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_2.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_2.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_2.$(OBJEXT): config.h
enc/iso_8859_2.$(OBJEXT): defines.h
enc/iso_8859_2.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_2.$(OBJEXT): enc/iso_8859_2.c
enc/iso_8859_2.$(OBJEXT): missing.h
enc/iso_8859_2.$(OBJEXT): onigmo.h
-enc/iso_8859_2.$(OBJEXT): oniguruma.h
enc/iso_8859_3.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_3.$(OBJEXT): internal/assume.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_3.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_3.$(OBJEXT): internal/cast.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_3.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_3.$(OBJEXT): internal/config.h
+enc/iso_8859_3.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_3.$(OBJEXT): internal/dosish.h
+enc/iso_8859_3.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_3.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_3.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_3.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_3.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_3.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_3.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_3.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_3.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_3.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_3.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_3.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_3.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_3.$(OBJEXT): assert.h
+enc/iso_8859_3.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_3.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_3.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_3.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_3.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_3.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_3.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_3.$(OBJEXT): config.h
enc/iso_8859_3.$(OBJEXT): defines.h
enc/iso_8859_3.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_3.$(OBJEXT): enc/iso_8859_3.c
enc/iso_8859_3.$(OBJEXT): missing.h
enc/iso_8859_3.$(OBJEXT): onigmo.h
-enc/iso_8859_3.$(OBJEXT): oniguruma.h
enc/iso_8859_4.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_4.$(OBJEXT): internal/assume.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_4.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_4.$(OBJEXT): internal/cast.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_4.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_4.$(OBJEXT): internal/config.h
+enc/iso_8859_4.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_4.$(OBJEXT): internal/dosish.h
+enc/iso_8859_4.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_4.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_4.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_4.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_4.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_4.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_4.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_4.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_4.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_4.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_4.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_4.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_4.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_4.$(OBJEXT): assert.h
+enc/iso_8859_4.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_4.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_4.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_4.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_4.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_4.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_4.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_4.$(OBJEXT): config.h
enc/iso_8859_4.$(OBJEXT): defines.h
enc/iso_8859_4.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_4.$(OBJEXT): enc/iso_8859_4.c
enc/iso_8859_4.$(OBJEXT): missing.h
enc/iso_8859_4.$(OBJEXT): onigmo.h
-enc/iso_8859_4.$(OBJEXT): oniguruma.h
enc/iso_8859_5.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_5.$(OBJEXT): internal/assume.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_5.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_5.$(OBJEXT): internal/cast.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_5.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_5.$(OBJEXT): internal/config.h
+enc/iso_8859_5.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_5.$(OBJEXT): internal/dosish.h
+enc/iso_8859_5.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_5.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_5.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_5.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_5.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_5.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_5.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_5.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_5.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_5.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_5.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_5.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_5.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_5.$(OBJEXT): assert.h
+enc/iso_8859_5.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_5.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_5.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_5.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_5.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_5.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_5.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_5.$(OBJEXT): config.h
enc/iso_8859_5.$(OBJEXT): defines.h
enc/iso_8859_5.$(OBJEXT): enc/iso_8859_5.c
enc/iso_8859_5.$(OBJEXT): missing.h
enc/iso_8859_5.$(OBJEXT): onigmo.h
-enc/iso_8859_5.$(OBJEXT): oniguruma.h
enc/iso_8859_6.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_6.$(OBJEXT): internal/assume.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_6.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_6.$(OBJEXT): internal/cast.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_6.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_6.$(OBJEXT): internal/config.h
+enc/iso_8859_6.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_6.$(OBJEXT): internal/dosish.h
+enc/iso_8859_6.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_6.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_6.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_6.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_6.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_6.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_6.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_6.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_6.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_6.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_6.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_6.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_6.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_6.$(OBJEXT): assert.h
+enc/iso_8859_6.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_6.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_6.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_6.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_6.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_6.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_6.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_6.$(OBJEXT): config.h
enc/iso_8859_6.$(OBJEXT): defines.h
enc/iso_8859_6.$(OBJEXT): enc/iso_8859_6.c
enc/iso_8859_6.$(OBJEXT): missing.h
enc/iso_8859_6.$(OBJEXT): onigmo.h
-enc/iso_8859_6.$(OBJEXT): oniguruma.h
enc/iso_8859_7.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_7.$(OBJEXT): internal/assume.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_7.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_7.$(OBJEXT): internal/cast.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_7.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_7.$(OBJEXT): internal/config.h
+enc/iso_8859_7.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_7.$(OBJEXT): internal/dosish.h
+enc/iso_8859_7.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_7.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_7.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_7.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_7.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_7.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_7.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_7.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_7.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_7.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_7.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_7.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_7.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_7.$(OBJEXT): assert.h
+enc/iso_8859_7.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_7.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_7.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_7.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_7.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_7.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_7.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_7.$(OBJEXT): config.h
enc/iso_8859_7.$(OBJEXT): defines.h
enc/iso_8859_7.$(OBJEXT): enc/iso_8859_7.c
enc/iso_8859_7.$(OBJEXT): missing.h
enc/iso_8859_7.$(OBJEXT): onigmo.h
-enc/iso_8859_7.$(OBJEXT): oniguruma.h
enc/iso_8859_8.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_8.$(OBJEXT): internal/assume.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_8.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_8.$(OBJEXT): internal/cast.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_8.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_8.$(OBJEXT): internal/config.h
+enc/iso_8859_8.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_8.$(OBJEXT): internal/dosish.h
+enc/iso_8859_8.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_8.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_8.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_8.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_8.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_8.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_8.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_8.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_8.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_8.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_8.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_8.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_8.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_8.$(OBJEXT): assert.h
+enc/iso_8859_8.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_8.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_8.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_8.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_8.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_8.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_8.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_8.$(OBJEXT): config.h
enc/iso_8859_8.$(OBJEXT): defines.h
enc/iso_8859_8.$(OBJEXT): enc/iso_8859_8.c
enc/iso_8859_8.$(OBJEXT): missing.h
enc/iso_8859_8.$(OBJEXT): onigmo.h
-enc/iso_8859_8.$(OBJEXT): oniguruma.h
enc/iso_8859_9.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/iso_8859_9.$(OBJEXT): internal/assume.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/alloc_size.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/cold.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/const.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/deprecated.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/error.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/forceinline.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/format.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/maybe_unused.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/nodiscard.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/noexcept.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/noinline.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/nonnull.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/noreturn.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/pure.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/restrict.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/iso_8859_9.$(OBJEXT): internal/attr/warning.h
+enc/iso_8859_9.$(OBJEXT): internal/cast.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_is.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_is/apple.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_is/clang.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_is/gcc.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_is/intel.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_is/msvc.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/iso_8859_9.$(OBJEXT): internal/compiler_since.h
+enc/iso_8859_9.$(OBJEXT): internal/config.h
+enc/iso_8859_9.$(OBJEXT): internal/dllexport.h
+enc/iso_8859_9.$(OBJEXT): internal/dosish.h
+enc/iso_8859_9.$(OBJEXT): internal/has/attribute.h
+enc/iso_8859_9.$(OBJEXT): internal/has/builtin.h
+enc/iso_8859_9.$(OBJEXT): internal/has/c_attribute.h
+enc/iso_8859_9.$(OBJEXT): internal/has/cpp_attribute.h
+enc/iso_8859_9.$(OBJEXT): internal/has/declspec_attribute.h
+enc/iso_8859_9.$(OBJEXT): internal/has/extension.h
+enc/iso_8859_9.$(OBJEXT): internal/has/feature.h
+enc/iso_8859_9.$(OBJEXT): internal/has/warning.h
+enc/iso_8859_9.$(OBJEXT): internal/stdalign.h
+enc/iso_8859_9.$(OBJEXT): internal/stdbool.h
+enc/iso_8859_9.$(OBJEXT): internal/token_paste.h
+enc/iso_8859_9.$(OBJEXT): internal/warning_push.h
+enc/iso_8859_9.$(OBJEXT): internal/xmalloc.h
+enc/iso_8859_9.$(OBJEXT): assert.h
+enc/iso_8859_9.$(OBJEXT): backward/2/assume.h
+enc/iso_8859_9.$(OBJEXT): backward/2/attributes.h
+enc/iso_8859_9.$(OBJEXT): backward/2/bool.h
+enc/iso_8859_9.$(OBJEXT): backward/2/gcc_version_since.h
+enc/iso_8859_9.$(OBJEXT): backward/2/long_long.h
+enc/iso_8859_9.$(OBJEXT): backward/2/stdalign.h
+enc/iso_8859_9.$(OBJEXT): backward/2/stdarg.h
enc/iso_8859_9.$(OBJEXT): config.h
enc/iso_8859_9.$(OBJEXT): defines.h
enc/iso_8859_9.$(OBJEXT): enc/iso_8859.h
enc/iso_8859_9.$(OBJEXT): enc/iso_8859_9.c
enc/iso_8859_9.$(OBJEXT): missing.h
enc/iso_8859_9.$(OBJEXT): onigmo.h
-enc/iso_8859_9.$(OBJEXT): oniguruma.h
enc/koi8_r.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/koi8_r.$(OBJEXT): internal/assume.h
+enc/koi8_r.$(OBJEXT): internal/attr/alloc_size.h
+enc/koi8_r.$(OBJEXT): internal/attr/cold.h
+enc/koi8_r.$(OBJEXT): internal/attr/const.h
+enc/koi8_r.$(OBJEXT): internal/attr/deprecated.h
+enc/koi8_r.$(OBJEXT): internal/attr/error.h
+enc/koi8_r.$(OBJEXT): internal/attr/forceinline.h
+enc/koi8_r.$(OBJEXT): internal/attr/format.h
+enc/koi8_r.$(OBJEXT): internal/attr/maybe_unused.h
+enc/koi8_r.$(OBJEXT): internal/attr/nodiscard.h
+enc/koi8_r.$(OBJEXT): internal/attr/noexcept.h
+enc/koi8_r.$(OBJEXT): internal/attr/noinline.h
+enc/koi8_r.$(OBJEXT): internal/attr/nonnull.h
+enc/koi8_r.$(OBJEXT): internal/attr/noreturn.h
+enc/koi8_r.$(OBJEXT): internal/attr/pure.h
+enc/koi8_r.$(OBJEXT): internal/attr/restrict.h
+enc/koi8_r.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/koi8_r.$(OBJEXT): internal/attr/warning.h
+enc/koi8_r.$(OBJEXT): internal/cast.h
+enc/koi8_r.$(OBJEXT): internal/compiler_is.h
+enc/koi8_r.$(OBJEXT): internal/compiler_is/apple.h
+enc/koi8_r.$(OBJEXT): internal/compiler_is/clang.h
+enc/koi8_r.$(OBJEXT): internal/compiler_is/gcc.h
+enc/koi8_r.$(OBJEXT): internal/compiler_is/intel.h
+enc/koi8_r.$(OBJEXT): internal/compiler_is/msvc.h
+enc/koi8_r.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/koi8_r.$(OBJEXT): internal/compiler_since.h
+enc/koi8_r.$(OBJEXT): internal/config.h
+enc/koi8_r.$(OBJEXT): internal/dllexport.h
+enc/koi8_r.$(OBJEXT): internal/dosish.h
+enc/koi8_r.$(OBJEXT): internal/has/attribute.h
+enc/koi8_r.$(OBJEXT): internal/has/builtin.h
+enc/koi8_r.$(OBJEXT): internal/has/c_attribute.h
+enc/koi8_r.$(OBJEXT): internal/has/cpp_attribute.h
+enc/koi8_r.$(OBJEXT): internal/has/declspec_attribute.h
+enc/koi8_r.$(OBJEXT): internal/has/extension.h
+enc/koi8_r.$(OBJEXT): internal/has/feature.h
+enc/koi8_r.$(OBJEXT): internal/has/warning.h
+enc/koi8_r.$(OBJEXT): internal/stdalign.h
+enc/koi8_r.$(OBJEXT): internal/stdbool.h
+enc/koi8_r.$(OBJEXT): internal/token_paste.h
+enc/koi8_r.$(OBJEXT): internal/warning_push.h
+enc/koi8_r.$(OBJEXT): internal/xmalloc.h
+enc/koi8_r.$(OBJEXT): assert.h
+enc/koi8_r.$(OBJEXT): backward/2/assume.h
+enc/koi8_r.$(OBJEXT): backward/2/attributes.h
+enc/koi8_r.$(OBJEXT): backward/2/bool.h
+enc/koi8_r.$(OBJEXT): backward/2/gcc_version_since.h
+enc/koi8_r.$(OBJEXT): backward/2/long_long.h
+enc/koi8_r.$(OBJEXT): backward/2/stdalign.h
+enc/koi8_r.$(OBJEXT): backward/2/stdarg.h
enc/koi8_r.$(OBJEXT): config.h
enc/koi8_r.$(OBJEXT): defines.h
enc/koi8_r.$(OBJEXT): enc/koi8_r.c
enc/koi8_r.$(OBJEXT): missing.h
enc/koi8_r.$(OBJEXT): onigmo.h
-enc/koi8_r.$(OBJEXT): oniguruma.h
enc/koi8_u.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/koi8_u.$(OBJEXT): internal/assume.h
+enc/koi8_u.$(OBJEXT): internal/attr/alloc_size.h
+enc/koi8_u.$(OBJEXT): internal/attr/cold.h
+enc/koi8_u.$(OBJEXT): internal/attr/const.h
+enc/koi8_u.$(OBJEXT): internal/attr/deprecated.h
+enc/koi8_u.$(OBJEXT): internal/attr/error.h
+enc/koi8_u.$(OBJEXT): internal/attr/forceinline.h
+enc/koi8_u.$(OBJEXT): internal/attr/format.h
+enc/koi8_u.$(OBJEXT): internal/attr/maybe_unused.h
+enc/koi8_u.$(OBJEXT): internal/attr/nodiscard.h
+enc/koi8_u.$(OBJEXT): internal/attr/noexcept.h
+enc/koi8_u.$(OBJEXT): internal/attr/noinline.h
+enc/koi8_u.$(OBJEXT): internal/attr/nonnull.h
+enc/koi8_u.$(OBJEXT): internal/attr/noreturn.h
+enc/koi8_u.$(OBJEXT): internal/attr/pure.h
+enc/koi8_u.$(OBJEXT): internal/attr/restrict.h
+enc/koi8_u.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/koi8_u.$(OBJEXT): internal/attr/warning.h
+enc/koi8_u.$(OBJEXT): internal/cast.h
+enc/koi8_u.$(OBJEXT): internal/compiler_is.h
+enc/koi8_u.$(OBJEXT): internal/compiler_is/apple.h
+enc/koi8_u.$(OBJEXT): internal/compiler_is/clang.h
+enc/koi8_u.$(OBJEXT): internal/compiler_is/gcc.h
+enc/koi8_u.$(OBJEXT): internal/compiler_is/intel.h
+enc/koi8_u.$(OBJEXT): internal/compiler_is/msvc.h
+enc/koi8_u.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/koi8_u.$(OBJEXT): internal/compiler_since.h
+enc/koi8_u.$(OBJEXT): internal/config.h
+enc/koi8_u.$(OBJEXT): internal/dllexport.h
+enc/koi8_u.$(OBJEXT): internal/dosish.h
+enc/koi8_u.$(OBJEXT): internal/has/attribute.h
+enc/koi8_u.$(OBJEXT): internal/has/builtin.h
+enc/koi8_u.$(OBJEXT): internal/has/c_attribute.h
+enc/koi8_u.$(OBJEXT): internal/has/cpp_attribute.h
+enc/koi8_u.$(OBJEXT): internal/has/declspec_attribute.h
+enc/koi8_u.$(OBJEXT): internal/has/extension.h
+enc/koi8_u.$(OBJEXT): internal/has/feature.h
+enc/koi8_u.$(OBJEXT): internal/has/warning.h
+enc/koi8_u.$(OBJEXT): internal/stdalign.h
+enc/koi8_u.$(OBJEXT): internal/stdbool.h
+enc/koi8_u.$(OBJEXT): internal/token_paste.h
+enc/koi8_u.$(OBJEXT): internal/warning_push.h
+enc/koi8_u.$(OBJEXT): internal/xmalloc.h
+enc/koi8_u.$(OBJEXT): assert.h
+enc/koi8_u.$(OBJEXT): backward/2/assume.h
+enc/koi8_u.$(OBJEXT): backward/2/attributes.h
+enc/koi8_u.$(OBJEXT): backward/2/bool.h
+enc/koi8_u.$(OBJEXT): backward/2/gcc_version_since.h
+enc/koi8_u.$(OBJEXT): backward/2/long_long.h
+enc/koi8_u.$(OBJEXT): backward/2/stdalign.h
+enc/koi8_u.$(OBJEXT): backward/2/stdarg.h
enc/koi8_u.$(OBJEXT): config.h
enc/koi8_u.$(OBJEXT): defines.h
enc/koi8_u.$(OBJEXT): enc/koi8_u.c
enc/koi8_u.$(OBJEXT): missing.h
enc/koi8_u.$(OBJEXT): onigmo.h
-enc/koi8_u.$(OBJEXT): oniguruma.h
-enc/shift_jis.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/shift_jis.$(OBJEXT): $(top_srcdir)/regenc.h
-enc/shift_jis.$(OBJEXT): $(top_srcdir)/regint.h
-enc/shift_jis.$(OBJEXT): backward.h
+enc/shift_jis.$(OBJEXT): internal/assume.h
+enc/shift_jis.$(OBJEXT): internal/attr/alloc_size.h
+enc/shift_jis.$(OBJEXT): internal/attr/cold.h
+enc/shift_jis.$(OBJEXT): internal/attr/const.h
+enc/shift_jis.$(OBJEXT): internal/attr/deprecated.h
+enc/shift_jis.$(OBJEXT): internal/attr/error.h
+enc/shift_jis.$(OBJEXT): internal/attr/forceinline.h
+enc/shift_jis.$(OBJEXT): internal/attr/format.h
+enc/shift_jis.$(OBJEXT): internal/attr/maybe_unused.h
+enc/shift_jis.$(OBJEXT): internal/attr/nodiscard.h
+enc/shift_jis.$(OBJEXT): internal/attr/noexcept.h
+enc/shift_jis.$(OBJEXT): internal/attr/noinline.h
+enc/shift_jis.$(OBJEXT): internal/attr/nonnull.h
+enc/shift_jis.$(OBJEXT): internal/attr/noreturn.h
+enc/shift_jis.$(OBJEXT): internal/attr/pure.h
+enc/shift_jis.$(OBJEXT): internal/attr/restrict.h
+enc/shift_jis.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/shift_jis.$(OBJEXT): internal/attr/warning.h
+enc/shift_jis.$(OBJEXT): internal/cast.h
+enc/shift_jis.$(OBJEXT): internal/compiler_is.h
+enc/shift_jis.$(OBJEXT): internal/compiler_is/apple.h
+enc/shift_jis.$(OBJEXT): internal/compiler_is/clang.h
+enc/shift_jis.$(OBJEXT): internal/compiler_is/gcc.h
+enc/shift_jis.$(OBJEXT): internal/compiler_is/intel.h
+enc/shift_jis.$(OBJEXT): internal/compiler_is/msvc.h
+enc/shift_jis.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/shift_jis.$(OBJEXT): internal/compiler_since.h
+enc/shift_jis.$(OBJEXT): internal/config.h
+enc/shift_jis.$(OBJEXT): internal/dllexport.h
+enc/shift_jis.$(OBJEXT): internal/dosish.h
+enc/shift_jis.$(OBJEXT): internal/has/attribute.h
+enc/shift_jis.$(OBJEXT): internal/has/builtin.h
+enc/shift_jis.$(OBJEXT): internal/has/c_attribute.h
+enc/shift_jis.$(OBJEXT): internal/has/cpp_attribute.h
+enc/shift_jis.$(OBJEXT): internal/has/declspec_attribute.h
+enc/shift_jis.$(OBJEXT): internal/has/extension.h
+enc/shift_jis.$(OBJEXT): internal/has/feature.h
+enc/shift_jis.$(OBJEXT): internal/has/warning.h
+enc/shift_jis.$(OBJEXT): internal/stdalign.h
+enc/shift_jis.$(OBJEXT): internal/stdbool.h
+enc/shift_jis.$(OBJEXT): internal/token_paste.h
+enc/shift_jis.$(OBJEXT): internal/warning_push.h
+enc/shift_jis.$(OBJEXT): internal/xmalloc.h
+enc/shift_jis.$(OBJEXT): assert.h
+enc/shift_jis.$(OBJEXT): backward/2/assume.h
+enc/shift_jis.$(OBJEXT): backward/2/attributes.h
+enc/shift_jis.$(OBJEXT): backward/2/bool.h
+enc/shift_jis.$(OBJEXT): backward/2/gcc_version_since.h
+enc/shift_jis.$(OBJEXT): backward/2/long_long.h
+enc/shift_jis.$(OBJEXT): backward/2/stdalign.h
+enc/shift_jis.$(OBJEXT): backward/2/stdarg.h
enc/shift_jis.$(OBJEXT): config.h
enc/shift_jis.$(OBJEXT): defines.h
enc/shift_jis.$(OBJEXT): enc/jis/props.h
enc/shift_jis.$(OBJEXT): enc/jis/props.kwd
enc/shift_jis.$(OBJEXT): enc/shift_jis.c
-enc/shift_jis.$(OBJEXT): intern.h
+enc/shift_jis.$(OBJEXT): enc/shift_jis.h
enc/shift_jis.$(OBJEXT): missing.h
enc/shift_jis.$(OBJEXT): onigmo.h
-enc/shift_jis.$(OBJEXT): oniguruma.h
-enc/shift_jis.$(OBJEXT): st.h
-enc/shift_jis.$(OBJEXT): subst.h
enc/trans/big5.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/big5.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/big5.$(OBJEXT): internal/anyargs.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/big5.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/big5.$(OBJEXT): internal/assume.h
+enc/trans/big5.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/big5.$(OBJEXT): internal/attr/artificial.h
+enc/trans/big5.$(OBJEXT): internal/attr/cold.h
+enc/trans/big5.$(OBJEXT): internal/attr/const.h
+enc/trans/big5.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/big5.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/big5.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/big5.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/big5.$(OBJEXT): internal/attr/error.h
+enc/trans/big5.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/big5.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/big5.$(OBJEXT): internal/attr/format.h
+enc/trans/big5.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/big5.$(OBJEXT): internal/attr/noalias.h
+enc/trans/big5.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/big5.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/big5.$(OBJEXT): internal/attr/noinline.h
+enc/trans/big5.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/big5.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/big5.$(OBJEXT): internal/attr/pure.h
+enc/trans/big5.$(OBJEXT): internal/attr/restrict.h
+enc/trans/big5.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/big5.$(OBJEXT): internal/attr/warning.h
+enc/trans/big5.$(OBJEXT): internal/attr/weakref.h
+enc/trans/big5.$(OBJEXT): internal/cast.h
+enc/trans/big5.$(OBJEXT): internal/compiler_is.h
+enc/trans/big5.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/big5.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/big5.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/big5.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/big5.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/big5.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/big5.$(OBJEXT): internal/compiler_since.h
+enc/trans/big5.$(OBJEXT): internal/config.h
+enc/trans/big5.$(OBJEXT): internal/constant_p.h
+enc/trans/big5.$(OBJEXT): internal/core.h
+enc/trans/big5.$(OBJEXT): internal/core/rarray.h
+enc/trans/big5.$(OBJEXT): internal/core/rbasic.h
+enc/trans/big5.$(OBJEXT): internal/core/rbignum.h
+enc/trans/big5.$(OBJEXT): internal/core/rclass.h
+enc/trans/big5.$(OBJEXT): internal/core/rdata.h
+enc/trans/big5.$(OBJEXT): internal/core/rfile.h
+enc/trans/big5.$(OBJEXT): internal/core/rhash.h
+enc/trans/big5.$(OBJEXT): internal/core/robject.h
+enc/trans/big5.$(OBJEXT): internal/core/rregexp.h
+enc/trans/big5.$(OBJEXT): internal/core/rstring.h
+enc/trans/big5.$(OBJEXT): internal/core/rstruct.h
+enc/trans/big5.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/big5.$(OBJEXT): internal/ctype.h
+enc/trans/big5.$(OBJEXT): internal/dllexport.h
+enc/trans/big5.$(OBJEXT): internal/dosish.h
+enc/trans/big5.$(OBJEXT): internal/error.h
+enc/trans/big5.$(OBJEXT): internal/eval.h
+enc/trans/big5.$(OBJEXT): internal/event.h
+enc/trans/big5.$(OBJEXT): internal/fl_type.h
+enc/trans/big5.$(OBJEXT): internal/gc.h
+enc/trans/big5.$(OBJEXT): internal/glob.h
+enc/trans/big5.$(OBJEXT): internal/globals.h
+enc/trans/big5.$(OBJEXT): internal/has/attribute.h
+enc/trans/big5.$(OBJEXT): internal/has/builtin.h
+enc/trans/big5.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/big5.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/big5.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/big5.$(OBJEXT): internal/has/extension.h
+enc/trans/big5.$(OBJEXT): internal/has/feature.h
+enc/trans/big5.$(OBJEXT): internal/has/warning.h
+enc/trans/big5.$(OBJEXT): internal/intern/array.h
+enc/trans/big5.$(OBJEXT): internal/intern/bignum.h
+enc/trans/big5.$(OBJEXT): internal/intern/class.h
+enc/trans/big5.$(OBJEXT): internal/intern/compar.h
+enc/trans/big5.$(OBJEXT): internal/intern/complex.h
+enc/trans/big5.$(OBJEXT): internal/intern/cont.h
+enc/trans/big5.$(OBJEXT): internal/intern/dir.h
+enc/trans/big5.$(OBJEXT): internal/intern/enum.h
+enc/trans/big5.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/big5.$(OBJEXT): internal/intern/error.h
+enc/trans/big5.$(OBJEXT): internal/intern/eval.h
+enc/trans/big5.$(OBJEXT): internal/intern/file.h
+enc/trans/big5.$(OBJEXT): internal/intern/gc.h
+enc/trans/big5.$(OBJEXT): internal/intern/hash.h
+enc/trans/big5.$(OBJEXT): internal/intern/io.h
+enc/trans/big5.$(OBJEXT): internal/intern/load.h
+enc/trans/big5.$(OBJEXT): internal/intern/marshal.h
+enc/trans/big5.$(OBJEXT): internal/intern/numeric.h
+enc/trans/big5.$(OBJEXT): internal/intern/object.h
+enc/trans/big5.$(OBJEXT): internal/intern/parse.h
+enc/trans/big5.$(OBJEXT): internal/intern/proc.h
+enc/trans/big5.$(OBJEXT): internal/intern/process.h
+enc/trans/big5.$(OBJEXT): internal/intern/random.h
+enc/trans/big5.$(OBJEXT): internal/intern/range.h
+enc/trans/big5.$(OBJEXT): internal/intern/rational.h
+enc/trans/big5.$(OBJEXT): internal/intern/re.h
+enc/trans/big5.$(OBJEXT): internal/intern/ruby.h
+enc/trans/big5.$(OBJEXT): internal/intern/select.h
+enc/trans/big5.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/big5.$(OBJEXT): internal/intern/signal.h
+enc/trans/big5.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/big5.$(OBJEXT): internal/intern/string.h
+enc/trans/big5.$(OBJEXT): internal/intern/struct.h
+enc/trans/big5.$(OBJEXT): internal/intern/thread.h
+enc/trans/big5.$(OBJEXT): internal/intern/time.h
+enc/trans/big5.$(OBJEXT): internal/intern/variable.h
+enc/trans/big5.$(OBJEXT): internal/intern/vm.h
+enc/trans/big5.$(OBJEXT): internal/interpreter.h
+enc/trans/big5.$(OBJEXT): internal/iterator.h
+enc/trans/big5.$(OBJEXT): internal/memory.h
+enc/trans/big5.$(OBJEXT): internal/method.h
+enc/trans/big5.$(OBJEXT): internal/module.h
+enc/trans/big5.$(OBJEXT): internal/newobj.h
+enc/trans/big5.$(OBJEXT): internal/rgengc.h
+enc/trans/big5.$(OBJEXT): internal/scan_args.h
+enc/trans/big5.$(OBJEXT): internal/special_consts.h
+enc/trans/big5.$(OBJEXT): internal/static_assert.h
+enc/trans/big5.$(OBJEXT): internal/stdalign.h
+enc/trans/big5.$(OBJEXT): internal/stdbool.h
+enc/trans/big5.$(OBJEXT): internal/symbol.h
+enc/trans/big5.$(OBJEXT): internal/token_paste.h
+enc/trans/big5.$(OBJEXT): internal/value.h
+enc/trans/big5.$(OBJEXT): internal/value_type.h
+enc/trans/big5.$(OBJEXT): internal/variable.h
+enc/trans/big5.$(OBJEXT): internal/warning_push.h
+enc/trans/big5.$(OBJEXT): internal/xmalloc.h
+enc/trans/big5.$(OBJEXT): assert.h
enc/trans/big5.$(OBJEXT): backward.h
+enc/trans/big5.$(OBJEXT): backward/2/assume.h
+enc/trans/big5.$(OBJEXT): backward/2/attributes.h
+enc/trans/big5.$(OBJEXT): backward/2/bool.h
+enc/trans/big5.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/big5.$(OBJEXT): backward/2/inttypes.h
+enc/trans/big5.$(OBJEXT): backward/2/limits.h
+enc/trans/big5.$(OBJEXT): backward/2/long_long.h
+enc/trans/big5.$(OBJEXT): backward/2/stdalign.h
+enc/trans/big5.$(OBJEXT): backward/2/stdarg.h
enc/trans/big5.$(OBJEXT): config.h
enc/trans/big5.$(OBJEXT): defines.h
enc/trans/big5.$(OBJEXT): enc/trans/big5.c
@@ -439,9 +2385,319 @@ enc/trans/big5.$(OBJEXT): intern.h
enc/trans/big5.$(OBJEXT): missing.h
enc/trans/big5.$(OBJEXT): st.h
enc/trans/big5.$(OBJEXT): subst.h
+enc/trans/cesu_8.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+enc/trans/cesu_8.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/cesu_8.$(OBJEXT): internal/anyargs.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/cesu_8.$(OBJEXT): internal/assume.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/artificial.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/cold.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/const.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/error.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/format.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/noalias.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/noinline.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/pure.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/restrict.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/warning.h
+enc/trans/cesu_8.$(OBJEXT): internal/attr/weakref.h
+enc/trans/cesu_8.$(OBJEXT): internal/cast.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_is.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/cesu_8.$(OBJEXT): internal/compiler_since.h
+enc/trans/cesu_8.$(OBJEXT): internal/config.h
+enc/trans/cesu_8.$(OBJEXT): internal/constant_p.h
+enc/trans/cesu_8.$(OBJEXT): internal/core.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rarray.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rbasic.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rbignum.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rclass.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rdata.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rfile.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rhash.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/robject.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rregexp.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rstring.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rstruct.h
+enc/trans/cesu_8.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/cesu_8.$(OBJEXT): internal/ctype.h
+enc/trans/cesu_8.$(OBJEXT): internal/dllexport.h
+enc/trans/cesu_8.$(OBJEXT): internal/dosish.h
+enc/trans/cesu_8.$(OBJEXT): internal/error.h
+enc/trans/cesu_8.$(OBJEXT): internal/eval.h
+enc/trans/cesu_8.$(OBJEXT): internal/event.h
+enc/trans/cesu_8.$(OBJEXT): internal/fl_type.h
+enc/trans/cesu_8.$(OBJEXT): internal/gc.h
+enc/trans/cesu_8.$(OBJEXT): internal/glob.h
+enc/trans/cesu_8.$(OBJEXT): internal/globals.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/attribute.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/builtin.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/extension.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/feature.h
+enc/trans/cesu_8.$(OBJEXT): internal/has/warning.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/array.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/bignum.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/class.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/compar.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/complex.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/cont.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/dir.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/enum.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/error.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/eval.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/file.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/gc.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/hash.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/io.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/load.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/marshal.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/numeric.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/object.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/parse.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/proc.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/process.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/random.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/range.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/rational.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/re.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/ruby.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/select.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/signal.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/string.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/struct.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/thread.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/time.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/variable.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/vm.h
+enc/trans/cesu_8.$(OBJEXT): internal/interpreter.h
+enc/trans/cesu_8.$(OBJEXT): internal/iterator.h
+enc/trans/cesu_8.$(OBJEXT): internal/memory.h
+enc/trans/cesu_8.$(OBJEXT): internal/method.h
+enc/trans/cesu_8.$(OBJEXT): internal/module.h
+enc/trans/cesu_8.$(OBJEXT): internal/newobj.h
+enc/trans/cesu_8.$(OBJEXT): internal/rgengc.h
+enc/trans/cesu_8.$(OBJEXT): internal/scan_args.h
+enc/trans/cesu_8.$(OBJEXT): internal/special_consts.h
+enc/trans/cesu_8.$(OBJEXT): internal/static_assert.h
+enc/trans/cesu_8.$(OBJEXT): internal/stdalign.h
+enc/trans/cesu_8.$(OBJEXT): internal/stdbool.h
+enc/trans/cesu_8.$(OBJEXT): internal/symbol.h
+enc/trans/cesu_8.$(OBJEXT): internal/token_paste.h
+enc/trans/cesu_8.$(OBJEXT): internal/value.h
+enc/trans/cesu_8.$(OBJEXT): internal/value_type.h
+enc/trans/cesu_8.$(OBJEXT): internal/variable.h
+enc/trans/cesu_8.$(OBJEXT): internal/warning_push.h
+enc/trans/cesu_8.$(OBJEXT): internal/xmalloc.h
+enc/trans/cesu_8.$(OBJEXT): assert.h
+enc/trans/cesu_8.$(OBJEXT): backward.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/assume.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/attributes.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/bool.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/inttypes.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/limits.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/long_long.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/stdalign.h
+enc/trans/cesu_8.$(OBJEXT): backward/2/stdarg.h
+enc/trans/cesu_8.$(OBJEXT): config.h
+enc/trans/cesu_8.$(OBJEXT): defines.h
+enc/trans/cesu_8.$(OBJEXT): enc/trans/cesu_8.c
+enc/trans/cesu_8.$(OBJEXT): intern.h
+enc/trans/cesu_8.$(OBJEXT): missing.h
+enc/trans/cesu_8.$(OBJEXT): st.h
+enc/trans/cesu_8.$(OBJEXT): subst.h
enc/trans/chinese.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/chinese.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/chinese.$(OBJEXT): internal/anyargs.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/chinese.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/chinese.$(OBJEXT): internal/assume.h
+enc/trans/chinese.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/chinese.$(OBJEXT): internal/attr/artificial.h
+enc/trans/chinese.$(OBJEXT): internal/attr/cold.h
+enc/trans/chinese.$(OBJEXT): internal/attr/const.h
+enc/trans/chinese.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/chinese.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/chinese.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/chinese.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/chinese.$(OBJEXT): internal/attr/error.h
+enc/trans/chinese.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/chinese.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/chinese.$(OBJEXT): internal/attr/format.h
+enc/trans/chinese.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/chinese.$(OBJEXT): internal/attr/noalias.h
+enc/trans/chinese.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/chinese.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/chinese.$(OBJEXT): internal/attr/noinline.h
+enc/trans/chinese.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/chinese.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/chinese.$(OBJEXT): internal/attr/pure.h
+enc/trans/chinese.$(OBJEXT): internal/attr/restrict.h
+enc/trans/chinese.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/chinese.$(OBJEXT): internal/attr/warning.h
+enc/trans/chinese.$(OBJEXT): internal/attr/weakref.h
+enc/trans/chinese.$(OBJEXT): internal/cast.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_is.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/chinese.$(OBJEXT): internal/compiler_since.h
+enc/trans/chinese.$(OBJEXT): internal/config.h
+enc/trans/chinese.$(OBJEXT): internal/constant_p.h
+enc/trans/chinese.$(OBJEXT): internal/core.h
+enc/trans/chinese.$(OBJEXT): internal/core/rarray.h
+enc/trans/chinese.$(OBJEXT): internal/core/rbasic.h
+enc/trans/chinese.$(OBJEXT): internal/core/rbignum.h
+enc/trans/chinese.$(OBJEXT): internal/core/rclass.h
+enc/trans/chinese.$(OBJEXT): internal/core/rdata.h
+enc/trans/chinese.$(OBJEXT): internal/core/rfile.h
+enc/trans/chinese.$(OBJEXT): internal/core/rhash.h
+enc/trans/chinese.$(OBJEXT): internal/core/robject.h
+enc/trans/chinese.$(OBJEXT): internal/core/rregexp.h
+enc/trans/chinese.$(OBJEXT): internal/core/rstring.h
+enc/trans/chinese.$(OBJEXT): internal/core/rstruct.h
+enc/trans/chinese.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/chinese.$(OBJEXT): internal/ctype.h
+enc/trans/chinese.$(OBJEXT): internal/dllexport.h
+enc/trans/chinese.$(OBJEXT): internal/dosish.h
+enc/trans/chinese.$(OBJEXT): internal/error.h
+enc/trans/chinese.$(OBJEXT): internal/eval.h
+enc/trans/chinese.$(OBJEXT): internal/event.h
+enc/trans/chinese.$(OBJEXT): internal/fl_type.h
+enc/trans/chinese.$(OBJEXT): internal/gc.h
+enc/trans/chinese.$(OBJEXT): internal/glob.h
+enc/trans/chinese.$(OBJEXT): internal/globals.h
+enc/trans/chinese.$(OBJEXT): internal/has/attribute.h
+enc/trans/chinese.$(OBJEXT): internal/has/builtin.h
+enc/trans/chinese.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/chinese.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/chinese.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/chinese.$(OBJEXT): internal/has/extension.h
+enc/trans/chinese.$(OBJEXT): internal/has/feature.h
+enc/trans/chinese.$(OBJEXT): internal/has/warning.h
+enc/trans/chinese.$(OBJEXT): internal/intern/array.h
+enc/trans/chinese.$(OBJEXT): internal/intern/bignum.h
+enc/trans/chinese.$(OBJEXT): internal/intern/class.h
+enc/trans/chinese.$(OBJEXT): internal/intern/compar.h
+enc/trans/chinese.$(OBJEXT): internal/intern/complex.h
+enc/trans/chinese.$(OBJEXT): internal/intern/cont.h
+enc/trans/chinese.$(OBJEXT): internal/intern/dir.h
+enc/trans/chinese.$(OBJEXT): internal/intern/enum.h
+enc/trans/chinese.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/chinese.$(OBJEXT): internal/intern/error.h
+enc/trans/chinese.$(OBJEXT): internal/intern/eval.h
+enc/trans/chinese.$(OBJEXT): internal/intern/file.h
+enc/trans/chinese.$(OBJEXT): internal/intern/gc.h
+enc/trans/chinese.$(OBJEXT): internal/intern/hash.h
+enc/trans/chinese.$(OBJEXT): internal/intern/io.h
+enc/trans/chinese.$(OBJEXT): internal/intern/load.h
+enc/trans/chinese.$(OBJEXT): internal/intern/marshal.h
+enc/trans/chinese.$(OBJEXT): internal/intern/numeric.h
+enc/trans/chinese.$(OBJEXT): internal/intern/object.h
+enc/trans/chinese.$(OBJEXT): internal/intern/parse.h
+enc/trans/chinese.$(OBJEXT): internal/intern/proc.h
+enc/trans/chinese.$(OBJEXT): internal/intern/process.h
+enc/trans/chinese.$(OBJEXT): internal/intern/random.h
+enc/trans/chinese.$(OBJEXT): internal/intern/range.h
+enc/trans/chinese.$(OBJEXT): internal/intern/rational.h
+enc/trans/chinese.$(OBJEXT): internal/intern/re.h
+enc/trans/chinese.$(OBJEXT): internal/intern/ruby.h
+enc/trans/chinese.$(OBJEXT): internal/intern/select.h
+enc/trans/chinese.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/chinese.$(OBJEXT): internal/intern/signal.h
+enc/trans/chinese.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/chinese.$(OBJEXT): internal/intern/string.h
+enc/trans/chinese.$(OBJEXT): internal/intern/struct.h
+enc/trans/chinese.$(OBJEXT): internal/intern/thread.h
+enc/trans/chinese.$(OBJEXT): internal/intern/time.h
+enc/trans/chinese.$(OBJEXT): internal/intern/variable.h
+enc/trans/chinese.$(OBJEXT): internal/intern/vm.h
+enc/trans/chinese.$(OBJEXT): internal/interpreter.h
+enc/trans/chinese.$(OBJEXT): internal/iterator.h
+enc/trans/chinese.$(OBJEXT): internal/memory.h
+enc/trans/chinese.$(OBJEXT): internal/method.h
+enc/trans/chinese.$(OBJEXT): internal/module.h
+enc/trans/chinese.$(OBJEXT): internal/newobj.h
+enc/trans/chinese.$(OBJEXT): internal/rgengc.h
+enc/trans/chinese.$(OBJEXT): internal/scan_args.h
+enc/trans/chinese.$(OBJEXT): internal/special_consts.h
+enc/trans/chinese.$(OBJEXT): internal/static_assert.h
+enc/trans/chinese.$(OBJEXT): internal/stdalign.h
+enc/trans/chinese.$(OBJEXT): internal/stdbool.h
+enc/trans/chinese.$(OBJEXT): internal/symbol.h
+enc/trans/chinese.$(OBJEXT): internal/token_paste.h
+enc/trans/chinese.$(OBJEXT): internal/value.h
+enc/trans/chinese.$(OBJEXT): internal/value_type.h
+enc/trans/chinese.$(OBJEXT): internal/variable.h
+enc/trans/chinese.$(OBJEXT): internal/warning_push.h
+enc/trans/chinese.$(OBJEXT): internal/xmalloc.h
+enc/trans/chinese.$(OBJEXT): assert.h
enc/trans/chinese.$(OBJEXT): backward.h
+enc/trans/chinese.$(OBJEXT): backward/2/assume.h
+enc/trans/chinese.$(OBJEXT): backward/2/attributes.h
+enc/trans/chinese.$(OBJEXT): backward/2/bool.h
+enc/trans/chinese.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/chinese.$(OBJEXT): backward/2/inttypes.h
+enc/trans/chinese.$(OBJEXT): backward/2/limits.h
+enc/trans/chinese.$(OBJEXT): backward/2/long_long.h
+enc/trans/chinese.$(OBJEXT): backward/2/stdalign.h
+enc/trans/chinese.$(OBJEXT): backward/2/stdarg.h
enc/trans/chinese.$(OBJEXT): config.h
enc/trans/chinese.$(OBJEXT): defines.h
enc/trans/chinese.$(OBJEXT): enc/trans/chinese.c
@@ -451,7 +2707,157 @@ enc/trans/chinese.$(OBJEXT): st.h
enc/trans/chinese.$(OBJEXT): subst.h
enc/trans/ebcdic.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/ebcdic.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/ebcdic.$(OBJEXT): internal/anyargs.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/ebcdic.$(OBJEXT): internal/assume.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/artificial.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/cold.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/const.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/error.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/format.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/noalias.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/noinline.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/pure.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/restrict.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/warning.h
+enc/trans/ebcdic.$(OBJEXT): internal/attr/weakref.h
+enc/trans/ebcdic.$(OBJEXT): internal/cast.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_is.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/ebcdic.$(OBJEXT): internal/compiler_since.h
+enc/trans/ebcdic.$(OBJEXT): internal/config.h
+enc/trans/ebcdic.$(OBJEXT): internal/constant_p.h
+enc/trans/ebcdic.$(OBJEXT): internal/core.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rarray.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rbasic.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rbignum.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rclass.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rdata.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rfile.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rhash.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/robject.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rregexp.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rstring.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rstruct.h
+enc/trans/ebcdic.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/ebcdic.$(OBJEXT): internal/ctype.h
+enc/trans/ebcdic.$(OBJEXT): internal/dllexport.h
+enc/trans/ebcdic.$(OBJEXT): internal/dosish.h
+enc/trans/ebcdic.$(OBJEXT): internal/error.h
+enc/trans/ebcdic.$(OBJEXT): internal/eval.h
+enc/trans/ebcdic.$(OBJEXT): internal/event.h
+enc/trans/ebcdic.$(OBJEXT): internal/fl_type.h
+enc/trans/ebcdic.$(OBJEXT): internal/gc.h
+enc/trans/ebcdic.$(OBJEXT): internal/glob.h
+enc/trans/ebcdic.$(OBJEXT): internal/globals.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/attribute.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/builtin.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/extension.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/feature.h
+enc/trans/ebcdic.$(OBJEXT): internal/has/warning.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/array.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/bignum.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/class.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/compar.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/complex.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/cont.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/dir.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/enum.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/error.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/eval.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/file.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/gc.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/hash.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/io.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/load.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/marshal.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/numeric.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/object.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/parse.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/proc.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/process.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/random.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/range.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/rational.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/re.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/ruby.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/select.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/signal.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/string.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/struct.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/thread.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/time.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/variable.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/vm.h
+enc/trans/ebcdic.$(OBJEXT): internal/interpreter.h
+enc/trans/ebcdic.$(OBJEXT): internal/iterator.h
+enc/trans/ebcdic.$(OBJEXT): internal/memory.h
+enc/trans/ebcdic.$(OBJEXT): internal/method.h
+enc/trans/ebcdic.$(OBJEXT): internal/module.h
+enc/trans/ebcdic.$(OBJEXT): internal/newobj.h
+enc/trans/ebcdic.$(OBJEXT): internal/rgengc.h
+enc/trans/ebcdic.$(OBJEXT): internal/scan_args.h
+enc/trans/ebcdic.$(OBJEXT): internal/special_consts.h
+enc/trans/ebcdic.$(OBJEXT): internal/static_assert.h
+enc/trans/ebcdic.$(OBJEXT): internal/stdalign.h
+enc/trans/ebcdic.$(OBJEXT): internal/stdbool.h
+enc/trans/ebcdic.$(OBJEXT): internal/symbol.h
+enc/trans/ebcdic.$(OBJEXT): internal/token_paste.h
+enc/trans/ebcdic.$(OBJEXT): internal/value.h
+enc/trans/ebcdic.$(OBJEXT): internal/value_type.h
+enc/trans/ebcdic.$(OBJEXT): internal/variable.h
+enc/trans/ebcdic.$(OBJEXT): internal/warning_push.h
+enc/trans/ebcdic.$(OBJEXT): internal/xmalloc.h
+enc/trans/ebcdic.$(OBJEXT): assert.h
enc/trans/ebcdic.$(OBJEXT): backward.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/assume.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/attributes.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/bool.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/inttypes.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/limits.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/long_long.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/stdalign.h
+enc/trans/ebcdic.$(OBJEXT): backward/2/stdarg.h
enc/trans/ebcdic.$(OBJEXT): config.h
enc/trans/ebcdic.$(OBJEXT): defines.h
enc/trans/ebcdic.$(OBJEXT): enc/trans/ebcdic.c
@@ -461,7 +2867,157 @@ enc/trans/ebcdic.$(OBJEXT): st.h
enc/trans/ebcdic.$(OBJEXT): subst.h
enc/trans/emoji.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/emoji.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/emoji.$(OBJEXT): internal/anyargs.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/emoji.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/emoji.$(OBJEXT): internal/assume.h
+enc/trans/emoji.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/emoji.$(OBJEXT): internal/attr/artificial.h
+enc/trans/emoji.$(OBJEXT): internal/attr/cold.h
+enc/trans/emoji.$(OBJEXT): internal/attr/const.h
+enc/trans/emoji.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/emoji.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/emoji.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/emoji.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/emoji.$(OBJEXT): internal/attr/error.h
+enc/trans/emoji.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/emoji.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/emoji.$(OBJEXT): internal/attr/format.h
+enc/trans/emoji.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/emoji.$(OBJEXT): internal/attr/noalias.h
+enc/trans/emoji.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/emoji.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/emoji.$(OBJEXT): internal/attr/noinline.h
+enc/trans/emoji.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/emoji.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/emoji.$(OBJEXT): internal/attr/pure.h
+enc/trans/emoji.$(OBJEXT): internal/attr/restrict.h
+enc/trans/emoji.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/emoji.$(OBJEXT): internal/attr/warning.h
+enc/trans/emoji.$(OBJEXT): internal/attr/weakref.h
+enc/trans/emoji.$(OBJEXT): internal/cast.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_is.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/emoji.$(OBJEXT): internal/compiler_since.h
+enc/trans/emoji.$(OBJEXT): internal/config.h
+enc/trans/emoji.$(OBJEXT): internal/constant_p.h
+enc/trans/emoji.$(OBJEXT): internal/core.h
+enc/trans/emoji.$(OBJEXT): internal/core/rarray.h
+enc/trans/emoji.$(OBJEXT): internal/core/rbasic.h
+enc/trans/emoji.$(OBJEXT): internal/core/rbignum.h
+enc/trans/emoji.$(OBJEXT): internal/core/rclass.h
+enc/trans/emoji.$(OBJEXT): internal/core/rdata.h
+enc/trans/emoji.$(OBJEXT): internal/core/rfile.h
+enc/trans/emoji.$(OBJEXT): internal/core/rhash.h
+enc/trans/emoji.$(OBJEXT): internal/core/robject.h
+enc/trans/emoji.$(OBJEXT): internal/core/rregexp.h
+enc/trans/emoji.$(OBJEXT): internal/core/rstring.h
+enc/trans/emoji.$(OBJEXT): internal/core/rstruct.h
+enc/trans/emoji.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/emoji.$(OBJEXT): internal/ctype.h
+enc/trans/emoji.$(OBJEXT): internal/dllexport.h
+enc/trans/emoji.$(OBJEXT): internal/dosish.h
+enc/trans/emoji.$(OBJEXT): internal/error.h
+enc/trans/emoji.$(OBJEXT): internal/eval.h
+enc/trans/emoji.$(OBJEXT): internal/event.h
+enc/trans/emoji.$(OBJEXT): internal/fl_type.h
+enc/trans/emoji.$(OBJEXT): internal/gc.h
+enc/trans/emoji.$(OBJEXT): internal/glob.h
+enc/trans/emoji.$(OBJEXT): internal/globals.h
+enc/trans/emoji.$(OBJEXT): internal/has/attribute.h
+enc/trans/emoji.$(OBJEXT): internal/has/builtin.h
+enc/trans/emoji.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/emoji.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/emoji.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/emoji.$(OBJEXT): internal/has/extension.h
+enc/trans/emoji.$(OBJEXT): internal/has/feature.h
+enc/trans/emoji.$(OBJEXT): internal/has/warning.h
+enc/trans/emoji.$(OBJEXT): internal/intern/array.h
+enc/trans/emoji.$(OBJEXT): internal/intern/bignum.h
+enc/trans/emoji.$(OBJEXT): internal/intern/class.h
+enc/trans/emoji.$(OBJEXT): internal/intern/compar.h
+enc/trans/emoji.$(OBJEXT): internal/intern/complex.h
+enc/trans/emoji.$(OBJEXT): internal/intern/cont.h
+enc/trans/emoji.$(OBJEXT): internal/intern/dir.h
+enc/trans/emoji.$(OBJEXT): internal/intern/enum.h
+enc/trans/emoji.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/emoji.$(OBJEXT): internal/intern/error.h
+enc/trans/emoji.$(OBJEXT): internal/intern/eval.h
+enc/trans/emoji.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji.$(OBJEXT): internal/intern/gc.h
+enc/trans/emoji.$(OBJEXT): internal/intern/hash.h
+enc/trans/emoji.$(OBJEXT): internal/intern/io.h
+enc/trans/emoji.$(OBJEXT): internal/intern/load.h
+enc/trans/emoji.$(OBJEXT): internal/intern/marshal.h
+enc/trans/emoji.$(OBJEXT): internal/intern/numeric.h
+enc/trans/emoji.$(OBJEXT): internal/intern/object.h
+enc/trans/emoji.$(OBJEXT): internal/intern/parse.h
+enc/trans/emoji.$(OBJEXT): internal/intern/proc.h
+enc/trans/emoji.$(OBJEXT): internal/intern/process.h
+enc/trans/emoji.$(OBJEXT): internal/intern/random.h
+enc/trans/emoji.$(OBJEXT): internal/intern/range.h
+enc/trans/emoji.$(OBJEXT): internal/intern/rational.h
+enc/trans/emoji.$(OBJEXT): internal/intern/re.h
+enc/trans/emoji.$(OBJEXT): internal/intern/ruby.h
+enc/trans/emoji.$(OBJEXT): internal/intern/select.h
+enc/trans/emoji.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/emoji.$(OBJEXT): internal/intern/signal.h
+enc/trans/emoji.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/emoji.$(OBJEXT): internal/intern/string.h
+enc/trans/emoji.$(OBJEXT): internal/intern/struct.h
+enc/trans/emoji.$(OBJEXT): internal/intern/thread.h
+enc/trans/emoji.$(OBJEXT): internal/intern/time.h
+enc/trans/emoji.$(OBJEXT): internal/intern/variable.h
+enc/trans/emoji.$(OBJEXT): internal/intern/vm.h
+enc/trans/emoji.$(OBJEXT): internal/interpreter.h
+enc/trans/emoji.$(OBJEXT): internal/iterator.h
+enc/trans/emoji.$(OBJEXT): internal/memory.h
+enc/trans/emoji.$(OBJEXT): internal/method.h
+enc/trans/emoji.$(OBJEXT): internal/module.h
+enc/trans/emoji.$(OBJEXT): internal/newobj.h
+enc/trans/emoji.$(OBJEXT): internal/rgengc.h
+enc/trans/emoji.$(OBJEXT): internal/scan_args.h
+enc/trans/emoji.$(OBJEXT): internal/special_consts.h
+enc/trans/emoji.$(OBJEXT): internal/static_assert.h
+enc/trans/emoji.$(OBJEXT): internal/stdalign.h
+enc/trans/emoji.$(OBJEXT): internal/stdbool.h
+enc/trans/emoji.$(OBJEXT): internal/symbol.h
+enc/trans/emoji.$(OBJEXT): internal/token_paste.h
+enc/trans/emoji.$(OBJEXT): internal/value.h
+enc/trans/emoji.$(OBJEXT): internal/value_type.h
+enc/trans/emoji.$(OBJEXT): internal/variable.h
+enc/trans/emoji.$(OBJEXT): internal/warning_push.h
+enc/trans/emoji.$(OBJEXT): internal/xmalloc.h
+enc/trans/emoji.$(OBJEXT): assert.h
enc/trans/emoji.$(OBJEXT): backward.h
+enc/trans/emoji.$(OBJEXT): backward/2/assume.h
+enc/trans/emoji.$(OBJEXT): backward/2/attributes.h
+enc/trans/emoji.$(OBJEXT): backward/2/bool.h
+enc/trans/emoji.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/emoji.$(OBJEXT): backward/2/inttypes.h
+enc/trans/emoji.$(OBJEXT): backward/2/limits.h
+enc/trans/emoji.$(OBJEXT): backward/2/long_long.h
+enc/trans/emoji.$(OBJEXT): backward/2/stdalign.h
+enc/trans/emoji.$(OBJEXT): backward/2/stdarg.h
enc/trans/emoji.$(OBJEXT): config.h
enc/trans/emoji.$(OBJEXT): defines.h
enc/trans/emoji.$(OBJEXT): enc/trans/emoji.c
@@ -471,7 +3027,157 @@ enc/trans/emoji.$(OBJEXT): st.h
enc/trans/emoji.$(OBJEXT): subst.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/anyargs.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/assume.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/artificial.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/cold.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/const.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/error.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/format.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/noalias.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/noinline.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/pure.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/restrict.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/warning.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/weakref.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/cast.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_is.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/compiler_since.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/config.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/constant_p.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rarray.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rbasic.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rbignum.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rclass.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rdata.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rfile.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rhash.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/robject.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rregexp.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rstring.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rstruct.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/ctype.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/dllexport.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/dosish.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/error.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/eval.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/event.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/fl_type.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/gc.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/glob.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/globals.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/attribute.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/builtin.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/extension.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/feature.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/has/warning.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/array.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/bignum.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/class.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/compar.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/complex.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/cont.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/dir.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/enum.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/error.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/eval.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/gc.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/hash.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/io.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/load.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/marshal.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/numeric.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/object.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/parse.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/proc.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/process.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/random.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/range.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/rational.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/re.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/ruby.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/select.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/signal.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/string.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/struct.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/thread.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/time.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/variable.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/vm.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/interpreter.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/iterator.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/memory.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/method.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/module.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/rgengc.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/scan_args.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/special_consts.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/static_assert.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/stdalign.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/stdbool.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/symbol.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/token_paste.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/value.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/value_type.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/variable.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/warning_push.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/xmalloc.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): assert.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/assume.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/attributes.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/bool.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/inttypes.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/limits.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/long_long.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/stdalign.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): backward/2/stdarg.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): config.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): defines.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): enc/trans/emoji_iso2022_kddi.c
@@ -481,7 +3187,157 @@ enc/trans/emoji_iso2022_kddi.$(OBJEXT): st.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): subst.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/anyargs.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/assume.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/artificial.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/cold.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/const.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/error.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/format.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/noalias.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/noinline.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/pure.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/restrict.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/warning.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/weakref.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/cast.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_is.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/compiler_since.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/config.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/constant_p.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rarray.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rbasic.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rbignum.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rclass.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rdata.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rfile.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rhash.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/robject.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rregexp.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rstring.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rstruct.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/ctype.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/dllexport.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/dosish.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/error.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/eval.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/event.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/fl_type.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/gc.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/glob.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/globals.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/attribute.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/builtin.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/extension.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/feature.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/has/warning.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/array.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/bignum.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/class.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/compar.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/complex.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/cont.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/dir.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/enum.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/error.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/eval.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/gc.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/hash.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/io.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/load.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/marshal.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/numeric.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/object.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/parse.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/proc.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/process.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/random.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/range.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/rational.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/re.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/ruby.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/select.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/signal.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/string.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/struct.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/thread.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/time.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/variable.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/vm.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/interpreter.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/iterator.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/memory.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/method.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/module.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/rgengc.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/scan_args.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/special_consts.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/static_assert.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/stdalign.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/stdbool.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/symbol.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/token_paste.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/value.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/value_type.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/variable.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/warning_push.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/xmalloc.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): assert.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): backward.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/assume.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/attributes.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/bool.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/inttypes.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/limits.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/long_long.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/stdalign.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): backward/2/stdarg.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): config.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): defines.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): enc/trans/emoji_sjis_docomo.c
@@ -491,7 +3347,157 @@ enc/trans/emoji_sjis_docomo.$(OBJEXT): st.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): subst.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/anyargs.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/assume.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/artificial.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/cold.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/const.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/error.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/format.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/noalias.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/noinline.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/pure.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/restrict.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/warning.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/weakref.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/cast.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_is.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/compiler_since.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/config.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/constant_p.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rarray.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rbasic.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rbignum.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rclass.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rdata.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rfile.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rhash.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/robject.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rregexp.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rstring.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rstruct.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/ctype.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/dllexport.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/dosish.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/error.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/eval.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/event.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/fl_type.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/gc.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/glob.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/globals.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/attribute.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/builtin.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/extension.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/feature.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/has/warning.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/array.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/bignum.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/class.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/compar.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/complex.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/cont.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/dir.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/enum.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/error.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/eval.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/gc.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/hash.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/io.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/load.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/marshal.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/numeric.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/object.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/parse.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/proc.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/process.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/random.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/range.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/rational.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/re.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/ruby.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/select.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/signal.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/string.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/struct.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/thread.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/time.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/variable.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/vm.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/interpreter.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/iterator.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/memory.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/method.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/module.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/rgengc.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/scan_args.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/special_consts.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/static_assert.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/stdalign.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/stdbool.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/symbol.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/token_paste.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/value.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/value_type.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/variable.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/warning_push.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/xmalloc.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): assert.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): backward.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/assume.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/attributes.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/bool.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/inttypes.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/limits.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/long_long.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/stdalign.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): backward/2/stdarg.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): config.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): defines.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): enc/trans/emoji_sjis_kddi.c
@@ -501,7 +3507,157 @@ enc/trans/emoji_sjis_kddi.$(OBJEXT): st.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): subst.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/anyargs.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/assume.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/artificial.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/cold.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/const.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/error.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/format.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/noalias.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/noinline.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/pure.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/restrict.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/warning.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/weakref.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/cast.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_is.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/compiler_since.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/config.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/constant_p.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rarray.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rbasic.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rbignum.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rclass.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rdata.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rfile.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rhash.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/robject.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rregexp.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rstring.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rstruct.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/ctype.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/dllexport.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/dosish.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/error.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/eval.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/event.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/fl_type.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/gc.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/glob.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/globals.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/attribute.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/builtin.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/extension.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/feature.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/has/warning.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/array.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/bignum.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/class.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/compar.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/complex.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/cont.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/dir.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/enum.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/error.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/eval.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/gc.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/hash.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/io.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/load.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/marshal.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/numeric.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/object.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/parse.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/proc.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/process.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/random.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/range.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/rational.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/re.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/ruby.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/select.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/signal.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/string.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/struct.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/thread.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/time.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/variable.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/vm.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/interpreter.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/iterator.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/memory.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/method.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/module.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/rgengc.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/scan_args.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/special_consts.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/static_assert.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/stdalign.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/stdbool.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/symbol.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/token_paste.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/value.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/value_type.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/variable.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/warning_push.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/xmalloc.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): assert.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): backward.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/assume.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/attributes.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/bool.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/inttypes.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/limits.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/long_long.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/stdalign.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): backward/2/stdarg.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): config.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): defines.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): enc/trans/emoji_sjis_softbank.c
@@ -511,7 +3667,157 @@ enc/trans/emoji_sjis_softbank.$(OBJEXT): st.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): subst.h
enc/trans/escape.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/escape.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/escape.$(OBJEXT): internal/anyargs.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/escape.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/escape.$(OBJEXT): internal/assume.h
+enc/trans/escape.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/escape.$(OBJEXT): internal/attr/artificial.h
+enc/trans/escape.$(OBJEXT): internal/attr/cold.h
+enc/trans/escape.$(OBJEXT): internal/attr/const.h
+enc/trans/escape.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/escape.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/escape.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/escape.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/escape.$(OBJEXT): internal/attr/error.h
+enc/trans/escape.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/escape.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/escape.$(OBJEXT): internal/attr/format.h
+enc/trans/escape.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/escape.$(OBJEXT): internal/attr/noalias.h
+enc/trans/escape.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/escape.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/escape.$(OBJEXT): internal/attr/noinline.h
+enc/trans/escape.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/escape.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/escape.$(OBJEXT): internal/attr/pure.h
+enc/trans/escape.$(OBJEXT): internal/attr/restrict.h
+enc/trans/escape.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/escape.$(OBJEXT): internal/attr/warning.h
+enc/trans/escape.$(OBJEXT): internal/attr/weakref.h
+enc/trans/escape.$(OBJEXT): internal/cast.h
+enc/trans/escape.$(OBJEXT): internal/compiler_is.h
+enc/trans/escape.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/escape.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/escape.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/escape.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/escape.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/escape.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/escape.$(OBJEXT): internal/compiler_since.h
+enc/trans/escape.$(OBJEXT): internal/config.h
+enc/trans/escape.$(OBJEXT): internal/constant_p.h
+enc/trans/escape.$(OBJEXT): internal/core.h
+enc/trans/escape.$(OBJEXT): internal/core/rarray.h
+enc/trans/escape.$(OBJEXT): internal/core/rbasic.h
+enc/trans/escape.$(OBJEXT): internal/core/rbignum.h
+enc/trans/escape.$(OBJEXT): internal/core/rclass.h
+enc/trans/escape.$(OBJEXT): internal/core/rdata.h
+enc/trans/escape.$(OBJEXT): internal/core/rfile.h
+enc/trans/escape.$(OBJEXT): internal/core/rhash.h
+enc/trans/escape.$(OBJEXT): internal/core/robject.h
+enc/trans/escape.$(OBJEXT): internal/core/rregexp.h
+enc/trans/escape.$(OBJEXT): internal/core/rstring.h
+enc/trans/escape.$(OBJEXT): internal/core/rstruct.h
+enc/trans/escape.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/escape.$(OBJEXT): internal/ctype.h
+enc/trans/escape.$(OBJEXT): internal/dllexport.h
+enc/trans/escape.$(OBJEXT): internal/dosish.h
+enc/trans/escape.$(OBJEXT): internal/error.h
+enc/trans/escape.$(OBJEXT): internal/eval.h
+enc/trans/escape.$(OBJEXT): internal/event.h
+enc/trans/escape.$(OBJEXT): internal/fl_type.h
+enc/trans/escape.$(OBJEXT): internal/gc.h
+enc/trans/escape.$(OBJEXT): internal/glob.h
+enc/trans/escape.$(OBJEXT): internal/globals.h
+enc/trans/escape.$(OBJEXT): internal/has/attribute.h
+enc/trans/escape.$(OBJEXT): internal/has/builtin.h
+enc/trans/escape.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/escape.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/escape.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/escape.$(OBJEXT): internal/has/extension.h
+enc/trans/escape.$(OBJEXT): internal/has/feature.h
+enc/trans/escape.$(OBJEXT): internal/has/warning.h
+enc/trans/escape.$(OBJEXT): internal/intern/array.h
+enc/trans/escape.$(OBJEXT): internal/intern/bignum.h
+enc/trans/escape.$(OBJEXT): internal/intern/class.h
+enc/trans/escape.$(OBJEXT): internal/intern/compar.h
+enc/trans/escape.$(OBJEXT): internal/intern/complex.h
+enc/trans/escape.$(OBJEXT): internal/intern/cont.h
+enc/trans/escape.$(OBJEXT): internal/intern/dir.h
+enc/trans/escape.$(OBJEXT): internal/intern/enum.h
+enc/trans/escape.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/escape.$(OBJEXT): internal/intern/error.h
+enc/trans/escape.$(OBJEXT): internal/intern/eval.h
+enc/trans/escape.$(OBJEXT): internal/intern/file.h
+enc/trans/escape.$(OBJEXT): internal/intern/gc.h
+enc/trans/escape.$(OBJEXT): internal/intern/hash.h
+enc/trans/escape.$(OBJEXT): internal/intern/io.h
+enc/trans/escape.$(OBJEXT): internal/intern/load.h
+enc/trans/escape.$(OBJEXT): internal/intern/marshal.h
+enc/trans/escape.$(OBJEXT): internal/intern/numeric.h
+enc/trans/escape.$(OBJEXT): internal/intern/object.h
+enc/trans/escape.$(OBJEXT): internal/intern/parse.h
+enc/trans/escape.$(OBJEXT): internal/intern/proc.h
+enc/trans/escape.$(OBJEXT): internal/intern/process.h
+enc/trans/escape.$(OBJEXT): internal/intern/random.h
+enc/trans/escape.$(OBJEXT): internal/intern/range.h
+enc/trans/escape.$(OBJEXT): internal/intern/rational.h
+enc/trans/escape.$(OBJEXT): internal/intern/re.h
+enc/trans/escape.$(OBJEXT): internal/intern/ruby.h
+enc/trans/escape.$(OBJEXT): internal/intern/select.h
+enc/trans/escape.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/escape.$(OBJEXT): internal/intern/signal.h
+enc/trans/escape.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/escape.$(OBJEXT): internal/intern/string.h
+enc/trans/escape.$(OBJEXT): internal/intern/struct.h
+enc/trans/escape.$(OBJEXT): internal/intern/thread.h
+enc/trans/escape.$(OBJEXT): internal/intern/time.h
+enc/trans/escape.$(OBJEXT): internal/intern/variable.h
+enc/trans/escape.$(OBJEXT): internal/intern/vm.h
+enc/trans/escape.$(OBJEXT): internal/interpreter.h
+enc/trans/escape.$(OBJEXT): internal/iterator.h
+enc/trans/escape.$(OBJEXT): internal/memory.h
+enc/trans/escape.$(OBJEXT): internal/method.h
+enc/trans/escape.$(OBJEXT): internal/module.h
+enc/trans/escape.$(OBJEXT): internal/newobj.h
+enc/trans/escape.$(OBJEXT): internal/rgengc.h
+enc/trans/escape.$(OBJEXT): internal/scan_args.h
+enc/trans/escape.$(OBJEXT): internal/special_consts.h
+enc/trans/escape.$(OBJEXT): internal/static_assert.h
+enc/trans/escape.$(OBJEXT): internal/stdalign.h
+enc/trans/escape.$(OBJEXT): internal/stdbool.h
+enc/trans/escape.$(OBJEXT): internal/symbol.h
+enc/trans/escape.$(OBJEXT): internal/token_paste.h
+enc/trans/escape.$(OBJEXT): internal/value.h
+enc/trans/escape.$(OBJEXT): internal/value_type.h
+enc/trans/escape.$(OBJEXT): internal/variable.h
+enc/trans/escape.$(OBJEXT): internal/warning_push.h
+enc/trans/escape.$(OBJEXT): internal/xmalloc.h
+enc/trans/escape.$(OBJEXT): assert.h
enc/trans/escape.$(OBJEXT): backward.h
+enc/trans/escape.$(OBJEXT): backward/2/assume.h
+enc/trans/escape.$(OBJEXT): backward/2/attributes.h
+enc/trans/escape.$(OBJEXT): backward/2/bool.h
+enc/trans/escape.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/escape.$(OBJEXT): backward/2/inttypes.h
+enc/trans/escape.$(OBJEXT): backward/2/limits.h
+enc/trans/escape.$(OBJEXT): backward/2/long_long.h
+enc/trans/escape.$(OBJEXT): backward/2/stdalign.h
+enc/trans/escape.$(OBJEXT): backward/2/stdarg.h
enc/trans/escape.$(OBJEXT): config.h
enc/trans/escape.$(OBJEXT): defines.h
enc/trans/escape.$(OBJEXT): enc/trans/escape.c
@@ -521,7 +3827,157 @@ enc/trans/escape.$(OBJEXT): st.h
enc/trans/escape.$(OBJEXT): subst.h
enc/trans/gb18030.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/gb18030.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/gb18030.$(OBJEXT): internal/anyargs.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/gb18030.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/gb18030.$(OBJEXT): internal/assume.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/artificial.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/cold.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/const.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/error.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/format.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/noalias.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/noinline.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/pure.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/restrict.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/warning.h
+enc/trans/gb18030.$(OBJEXT): internal/attr/weakref.h
+enc/trans/gb18030.$(OBJEXT): internal/cast.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_is.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/gb18030.$(OBJEXT): internal/compiler_since.h
+enc/trans/gb18030.$(OBJEXT): internal/config.h
+enc/trans/gb18030.$(OBJEXT): internal/constant_p.h
+enc/trans/gb18030.$(OBJEXT): internal/core.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rarray.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rbasic.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rbignum.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rclass.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rdata.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rfile.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rhash.h
+enc/trans/gb18030.$(OBJEXT): internal/core/robject.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rregexp.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rstring.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rstruct.h
+enc/trans/gb18030.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/gb18030.$(OBJEXT): internal/ctype.h
+enc/trans/gb18030.$(OBJEXT): internal/dllexport.h
+enc/trans/gb18030.$(OBJEXT): internal/dosish.h
+enc/trans/gb18030.$(OBJEXT): internal/error.h
+enc/trans/gb18030.$(OBJEXT): internal/eval.h
+enc/trans/gb18030.$(OBJEXT): internal/event.h
+enc/trans/gb18030.$(OBJEXT): internal/fl_type.h
+enc/trans/gb18030.$(OBJEXT): internal/gc.h
+enc/trans/gb18030.$(OBJEXT): internal/glob.h
+enc/trans/gb18030.$(OBJEXT): internal/globals.h
+enc/trans/gb18030.$(OBJEXT): internal/has/attribute.h
+enc/trans/gb18030.$(OBJEXT): internal/has/builtin.h
+enc/trans/gb18030.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/gb18030.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/gb18030.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/gb18030.$(OBJEXT): internal/has/extension.h
+enc/trans/gb18030.$(OBJEXT): internal/has/feature.h
+enc/trans/gb18030.$(OBJEXT): internal/has/warning.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/array.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/bignum.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/class.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/compar.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/complex.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/cont.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/dir.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/enum.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/error.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/eval.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/file.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/gc.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/hash.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/io.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/load.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/marshal.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/numeric.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/object.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/parse.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/proc.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/process.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/random.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/range.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/rational.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/re.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/ruby.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/select.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/signal.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/string.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/struct.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/thread.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/time.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/variable.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/vm.h
+enc/trans/gb18030.$(OBJEXT): internal/interpreter.h
+enc/trans/gb18030.$(OBJEXT): internal/iterator.h
+enc/trans/gb18030.$(OBJEXT): internal/memory.h
+enc/trans/gb18030.$(OBJEXT): internal/method.h
+enc/trans/gb18030.$(OBJEXT): internal/module.h
+enc/trans/gb18030.$(OBJEXT): internal/newobj.h
+enc/trans/gb18030.$(OBJEXT): internal/rgengc.h
+enc/trans/gb18030.$(OBJEXT): internal/scan_args.h
+enc/trans/gb18030.$(OBJEXT): internal/special_consts.h
+enc/trans/gb18030.$(OBJEXT): internal/static_assert.h
+enc/trans/gb18030.$(OBJEXT): internal/stdalign.h
+enc/trans/gb18030.$(OBJEXT): internal/stdbool.h
+enc/trans/gb18030.$(OBJEXT): internal/symbol.h
+enc/trans/gb18030.$(OBJEXT): internal/token_paste.h
+enc/trans/gb18030.$(OBJEXT): internal/value.h
+enc/trans/gb18030.$(OBJEXT): internal/value_type.h
+enc/trans/gb18030.$(OBJEXT): internal/variable.h
+enc/trans/gb18030.$(OBJEXT): internal/warning_push.h
+enc/trans/gb18030.$(OBJEXT): internal/xmalloc.h
+enc/trans/gb18030.$(OBJEXT): assert.h
enc/trans/gb18030.$(OBJEXT): backward.h
+enc/trans/gb18030.$(OBJEXT): backward/2/assume.h
+enc/trans/gb18030.$(OBJEXT): backward/2/attributes.h
+enc/trans/gb18030.$(OBJEXT): backward/2/bool.h
+enc/trans/gb18030.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/gb18030.$(OBJEXT): backward/2/inttypes.h
+enc/trans/gb18030.$(OBJEXT): backward/2/limits.h
+enc/trans/gb18030.$(OBJEXT): backward/2/long_long.h
+enc/trans/gb18030.$(OBJEXT): backward/2/stdalign.h
+enc/trans/gb18030.$(OBJEXT): backward/2/stdarg.h
enc/trans/gb18030.$(OBJEXT): config.h
enc/trans/gb18030.$(OBJEXT): defines.h
enc/trans/gb18030.$(OBJEXT): enc/trans/gb18030.c
@@ -531,7 +3987,157 @@ enc/trans/gb18030.$(OBJEXT): st.h
enc/trans/gb18030.$(OBJEXT): subst.h
enc/trans/gbk.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/gbk.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/gbk.$(OBJEXT): internal/anyargs.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/gbk.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/gbk.$(OBJEXT): internal/assume.h
+enc/trans/gbk.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/gbk.$(OBJEXT): internal/attr/artificial.h
+enc/trans/gbk.$(OBJEXT): internal/attr/cold.h
+enc/trans/gbk.$(OBJEXT): internal/attr/const.h
+enc/trans/gbk.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/gbk.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/gbk.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/gbk.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/gbk.$(OBJEXT): internal/attr/error.h
+enc/trans/gbk.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/gbk.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/gbk.$(OBJEXT): internal/attr/format.h
+enc/trans/gbk.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/gbk.$(OBJEXT): internal/attr/noalias.h
+enc/trans/gbk.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/gbk.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/gbk.$(OBJEXT): internal/attr/noinline.h
+enc/trans/gbk.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/gbk.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/gbk.$(OBJEXT): internal/attr/pure.h
+enc/trans/gbk.$(OBJEXT): internal/attr/restrict.h
+enc/trans/gbk.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/gbk.$(OBJEXT): internal/attr/warning.h
+enc/trans/gbk.$(OBJEXT): internal/attr/weakref.h
+enc/trans/gbk.$(OBJEXT): internal/cast.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_is.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/gbk.$(OBJEXT): internal/compiler_since.h
+enc/trans/gbk.$(OBJEXT): internal/config.h
+enc/trans/gbk.$(OBJEXT): internal/constant_p.h
+enc/trans/gbk.$(OBJEXT): internal/core.h
+enc/trans/gbk.$(OBJEXT): internal/core/rarray.h
+enc/trans/gbk.$(OBJEXT): internal/core/rbasic.h
+enc/trans/gbk.$(OBJEXT): internal/core/rbignum.h
+enc/trans/gbk.$(OBJEXT): internal/core/rclass.h
+enc/trans/gbk.$(OBJEXT): internal/core/rdata.h
+enc/trans/gbk.$(OBJEXT): internal/core/rfile.h
+enc/trans/gbk.$(OBJEXT): internal/core/rhash.h
+enc/trans/gbk.$(OBJEXT): internal/core/robject.h
+enc/trans/gbk.$(OBJEXT): internal/core/rregexp.h
+enc/trans/gbk.$(OBJEXT): internal/core/rstring.h
+enc/trans/gbk.$(OBJEXT): internal/core/rstruct.h
+enc/trans/gbk.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/gbk.$(OBJEXT): internal/ctype.h
+enc/trans/gbk.$(OBJEXT): internal/dllexport.h
+enc/trans/gbk.$(OBJEXT): internal/dosish.h
+enc/trans/gbk.$(OBJEXT): internal/error.h
+enc/trans/gbk.$(OBJEXT): internal/eval.h
+enc/trans/gbk.$(OBJEXT): internal/event.h
+enc/trans/gbk.$(OBJEXT): internal/fl_type.h
+enc/trans/gbk.$(OBJEXT): internal/gc.h
+enc/trans/gbk.$(OBJEXT): internal/glob.h
+enc/trans/gbk.$(OBJEXT): internal/globals.h
+enc/trans/gbk.$(OBJEXT): internal/has/attribute.h
+enc/trans/gbk.$(OBJEXT): internal/has/builtin.h
+enc/trans/gbk.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/gbk.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/gbk.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/gbk.$(OBJEXT): internal/has/extension.h
+enc/trans/gbk.$(OBJEXT): internal/has/feature.h
+enc/trans/gbk.$(OBJEXT): internal/has/warning.h
+enc/trans/gbk.$(OBJEXT): internal/intern/array.h
+enc/trans/gbk.$(OBJEXT): internal/intern/bignum.h
+enc/trans/gbk.$(OBJEXT): internal/intern/class.h
+enc/trans/gbk.$(OBJEXT): internal/intern/compar.h
+enc/trans/gbk.$(OBJEXT): internal/intern/complex.h
+enc/trans/gbk.$(OBJEXT): internal/intern/cont.h
+enc/trans/gbk.$(OBJEXT): internal/intern/dir.h
+enc/trans/gbk.$(OBJEXT): internal/intern/enum.h
+enc/trans/gbk.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/gbk.$(OBJEXT): internal/intern/error.h
+enc/trans/gbk.$(OBJEXT): internal/intern/eval.h
+enc/trans/gbk.$(OBJEXT): internal/intern/file.h
+enc/trans/gbk.$(OBJEXT): internal/intern/gc.h
+enc/trans/gbk.$(OBJEXT): internal/intern/hash.h
+enc/trans/gbk.$(OBJEXT): internal/intern/io.h
+enc/trans/gbk.$(OBJEXT): internal/intern/load.h
+enc/trans/gbk.$(OBJEXT): internal/intern/marshal.h
+enc/trans/gbk.$(OBJEXT): internal/intern/numeric.h
+enc/trans/gbk.$(OBJEXT): internal/intern/object.h
+enc/trans/gbk.$(OBJEXT): internal/intern/parse.h
+enc/trans/gbk.$(OBJEXT): internal/intern/proc.h
+enc/trans/gbk.$(OBJEXT): internal/intern/process.h
+enc/trans/gbk.$(OBJEXT): internal/intern/random.h
+enc/trans/gbk.$(OBJEXT): internal/intern/range.h
+enc/trans/gbk.$(OBJEXT): internal/intern/rational.h
+enc/trans/gbk.$(OBJEXT): internal/intern/re.h
+enc/trans/gbk.$(OBJEXT): internal/intern/ruby.h
+enc/trans/gbk.$(OBJEXT): internal/intern/select.h
+enc/trans/gbk.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/gbk.$(OBJEXT): internal/intern/signal.h
+enc/trans/gbk.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/gbk.$(OBJEXT): internal/intern/string.h
+enc/trans/gbk.$(OBJEXT): internal/intern/struct.h
+enc/trans/gbk.$(OBJEXT): internal/intern/thread.h
+enc/trans/gbk.$(OBJEXT): internal/intern/time.h
+enc/trans/gbk.$(OBJEXT): internal/intern/variable.h
+enc/trans/gbk.$(OBJEXT): internal/intern/vm.h
+enc/trans/gbk.$(OBJEXT): internal/interpreter.h
+enc/trans/gbk.$(OBJEXT): internal/iterator.h
+enc/trans/gbk.$(OBJEXT): internal/memory.h
+enc/trans/gbk.$(OBJEXT): internal/method.h
+enc/trans/gbk.$(OBJEXT): internal/module.h
+enc/trans/gbk.$(OBJEXT): internal/newobj.h
+enc/trans/gbk.$(OBJEXT): internal/rgengc.h
+enc/trans/gbk.$(OBJEXT): internal/scan_args.h
+enc/trans/gbk.$(OBJEXT): internal/special_consts.h
+enc/trans/gbk.$(OBJEXT): internal/static_assert.h
+enc/trans/gbk.$(OBJEXT): internal/stdalign.h
+enc/trans/gbk.$(OBJEXT): internal/stdbool.h
+enc/trans/gbk.$(OBJEXT): internal/symbol.h
+enc/trans/gbk.$(OBJEXT): internal/token_paste.h
+enc/trans/gbk.$(OBJEXT): internal/value.h
+enc/trans/gbk.$(OBJEXT): internal/value_type.h
+enc/trans/gbk.$(OBJEXT): internal/variable.h
+enc/trans/gbk.$(OBJEXT): internal/warning_push.h
+enc/trans/gbk.$(OBJEXT): internal/xmalloc.h
+enc/trans/gbk.$(OBJEXT): assert.h
enc/trans/gbk.$(OBJEXT): backward.h
+enc/trans/gbk.$(OBJEXT): backward/2/assume.h
+enc/trans/gbk.$(OBJEXT): backward/2/attributes.h
+enc/trans/gbk.$(OBJEXT): backward/2/bool.h
+enc/trans/gbk.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/gbk.$(OBJEXT): backward/2/inttypes.h
+enc/trans/gbk.$(OBJEXT): backward/2/limits.h
+enc/trans/gbk.$(OBJEXT): backward/2/long_long.h
+enc/trans/gbk.$(OBJEXT): backward/2/stdalign.h
+enc/trans/gbk.$(OBJEXT): backward/2/stdarg.h
enc/trans/gbk.$(OBJEXT): config.h
enc/trans/gbk.$(OBJEXT): defines.h
enc/trans/gbk.$(OBJEXT): enc/trans/gbk.c
@@ -541,7 +4147,157 @@ enc/trans/gbk.$(OBJEXT): st.h
enc/trans/gbk.$(OBJEXT): subst.h
enc/trans/iso2022.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/iso2022.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/iso2022.$(OBJEXT): internal/anyargs.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/iso2022.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/iso2022.$(OBJEXT): internal/assume.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/artificial.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/cold.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/const.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/error.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/format.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/noalias.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/noinline.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/pure.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/restrict.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/warning.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/weakref.h
+enc/trans/iso2022.$(OBJEXT): internal/cast.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_is.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/iso2022.$(OBJEXT): internal/compiler_since.h
+enc/trans/iso2022.$(OBJEXT): internal/config.h
+enc/trans/iso2022.$(OBJEXT): internal/constant_p.h
+enc/trans/iso2022.$(OBJEXT): internal/core.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rarray.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rbasic.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rbignum.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rclass.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rdata.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rfile.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rhash.h
+enc/trans/iso2022.$(OBJEXT): internal/core/robject.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rregexp.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rstring.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rstruct.h
+enc/trans/iso2022.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/iso2022.$(OBJEXT): internal/ctype.h
+enc/trans/iso2022.$(OBJEXT): internal/dllexport.h
+enc/trans/iso2022.$(OBJEXT): internal/dosish.h
+enc/trans/iso2022.$(OBJEXT): internal/error.h
+enc/trans/iso2022.$(OBJEXT): internal/eval.h
+enc/trans/iso2022.$(OBJEXT): internal/event.h
+enc/trans/iso2022.$(OBJEXT): internal/fl_type.h
+enc/trans/iso2022.$(OBJEXT): internal/gc.h
+enc/trans/iso2022.$(OBJEXT): internal/glob.h
+enc/trans/iso2022.$(OBJEXT): internal/globals.h
+enc/trans/iso2022.$(OBJEXT): internal/has/attribute.h
+enc/trans/iso2022.$(OBJEXT): internal/has/builtin.h
+enc/trans/iso2022.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/iso2022.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/iso2022.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/iso2022.$(OBJEXT): internal/has/extension.h
+enc/trans/iso2022.$(OBJEXT): internal/has/feature.h
+enc/trans/iso2022.$(OBJEXT): internal/has/warning.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/array.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/bignum.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/class.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/compar.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/complex.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/cont.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/dir.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/enum.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/error.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/eval.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/file.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/gc.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/hash.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/io.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/load.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/marshal.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/numeric.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/object.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/parse.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/proc.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/process.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/random.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/range.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/rational.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/re.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/ruby.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/select.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/signal.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/string.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/struct.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/thread.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/time.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/variable.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/vm.h
+enc/trans/iso2022.$(OBJEXT): internal/interpreter.h
+enc/trans/iso2022.$(OBJEXT): internal/iterator.h
+enc/trans/iso2022.$(OBJEXT): internal/memory.h
+enc/trans/iso2022.$(OBJEXT): internal/method.h
+enc/trans/iso2022.$(OBJEXT): internal/module.h
+enc/trans/iso2022.$(OBJEXT): internal/newobj.h
+enc/trans/iso2022.$(OBJEXT): internal/rgengc.h
+enc/trans/iso2022.$(OBJEXT): internal/scan_args.h
+enc/trans/iso2022.$(OBJEXT): internal/special_consts.h
+enc/trans/iso2022.$(OBJEXT): internal/static_assert.h
+enc/trans/iso2022.$(OBJEXT): internal/stdalign.h
+enc/trans/iso2022.$(OBJEXT): internal/stdbool.h
+enc/trans/iso2022.$(OBJEXT): internal/symbol.h
+enc/trans/iso2022.$(OBJEXT): internal/token_paste.h
+enc/trans/iso2022.$(OBJEXT): internal/value.h
+enc/trans/iso2022.$(OBJEXT): internal/value_type.h
+enc/trans/iso2022.$(OBJEXT): internal/variable.h
+enc/trans/iso2022.$(OBJEXT): internal/warning_push.h
+enc/trans/iso2022.$(OBJEXT): internal/xmalloc.h
+enc/trans/iso2022.$(OBJEXT): assert.h
enc/trans/iso2022.$(OBJEXT): backward.h
+enc/trans/iso2022.$(OBJEXT): backward/2/assume.h
+enc/trans/iso2022.$(OBJEXT): backward/2/attributes.h
+enc/trans/iso2022.$(OBJEXT): backward/2/bool.h
+enc/trans/iso2022.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/iso2022.$(OBJEXT): backward/2/inttypes.h
+enc/trans/iso2022.$(OBJEXT): backward/2/limits.h
+enc/trans/iso2022.$(OBJEXT): backward/2/long_long.h
+enc/trans/iso2022.$(OBJEXT): backward/2/stdalign.h
+enc/trans/iso2022.$(OBJEXT): backward/2/stdarg.h
enc/trans/iso2022.$(OBJEXT): config.h
enc/trans/iso2022.$(OBJEXT): defines.h
enc/trans/iso2022.$(OBJEXT): enc/trans/iso2022.c
@@ -551,7 +4307,157 @@ enc/trans/iso2022.$(OBJEXT): st.h
enc/trans/iso2022.$(OBJEXT): subst.h
enc/trans/japanese.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/japanese.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/japanese.$(OBJEXT): internal/anyargs.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/japanese.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/japanese.$(OBJEXT): internal/assume.h
+enc/trans/japanese.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/japanese.$(OBJEXT): internal/attr/artificial.h
+enc/trans/japanese.$(OBJEXT): internal/attr/cold.h
+enc/trans/japanese.$(OBJEXT): internal/attr/const.h
+enc/trans/japanese.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/japanese.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/japanese.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/japanese.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/japanese.$(OBJEXT): internal/attr/error.h
+enc/trans/japanese.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/japanese.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/japanese.$(OBJEXT): internal/attr/format.h
+enc/trans/japanese.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/japanese.$(OBJEXT): internal/attr/noalias.h
+enc/trans/japanese.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/japanese.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/japanese.$(OBJEXT): internal/attr/noinline.h
+enc/trans/japanese.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/japanese.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/japanese.$(OBJEXT): internal/attr/pure.h
+enc/trans/japanese.$(OBJEXT): internal/attr/restrict.h
+enc/trans/japanese.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/japanese.$(OBJEXT): internal/attr/warning.h
+enc/trans/japanese.$(OBJEXT): internal/attr/weakref.h
+enc/trans/japanese.$(OBJEXT): internal/cast.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_is.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/japanese.$(OBJEXT): internal/compiler_since.h
+enc/trans/japanese.$(OBJEXT): internal/config.h
+enc/trans/japanese.$(OBJEXT): internal/constant_p.h
+enc/trans/japanese.$(OBJEXT): internal/core.h
+enc/trans/japanese.$(OBJEXT): internal/core/rarray.h
+enc/trans/japanese.$(OBJEXT): internal/core/rbasic.h
+enc/trans/japanese.$(OBJEXT): internal/core/rbignum.h
+enc/trans/japanese.$(OBJEXT): internal/core/rclass.h
+enc/trans/japanese.$(OBJEXT): internal/core/rdata.h
+enc/trans/japanese.$(OBJEXT): internal/core/rfile.h
+enc/trans/japanese.$(OBJEXT): internal/core/rhash.h
+enc/trans/japanese.$(OBJEXT): internal/core/robject.h
+enc/trans/japanese.$(OBJEXT): internal/core/rregexp.h
+enc/trans/japanese.$(OBJEXT): internal/core/rstring.h
+enc/trans/japanese.$(OBJEXT): internal/core/rstruct.h
+enc/trans/japanese.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/japanese.$(OBJEXT): internal/ctype.h
+enc/trans/japanese.$(OBJEXT): internal/dllexport.h
+enc/trans/japanese.$(OBJEXT): internal/dosish.h
+enc/trans/japanese.$(OBJEXT): internal/error.h
+enc/trans/japanese.$(OBJEXT): internal/eval.h
+enc/trans/japanese.$(OBJEXT): internal/event.h
+enc/trans/japanese.$(OBJEXT): internal/fl_type.h
+enc/trans/japanese.$(OBJEXT): internal/gc.h
+enc/trans/japanese.$(OBJEXT): internal/glob.h
+enc/trans/japanese.$(OBJEXT): internal/globals.h
+enc/trans/japanese.$(OBJEXT): internal/has/attribute.h
+enc/trans/japanese.$(OBJEXT): internal/has/builtin.h
+enc/trans/japanese.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/japanese.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/japanese.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/japanese.$(OBJEXT): internal/has/extension.h
+enc/trans/japanese.$(OBJEXT): internal/has/feature.h
+enc/trans/japanese.$(OBJEXT): internal/has/warning.h
+enc/trans/japanese.$(OBJEXT): internal/intern/array.h
+enc/trans/japanese.$(OBJEXT): internal/intern/bignum.h
+enc/trans/japanese.$(OBJEXT): internal/intern/class.h
+enc/trans/japanese.$(OBJEXT): internal/intern/compar.h
+enc/trans/japanese.$(OBJEXT): internal/intern/complex.h
+enc/trans/japanese.$(OBJEXT): internal/intern/cont.h
+enc/trans/japanese.$(OBJEXT): internal/intern/dir.h
+enc/trans/japanese.$(OBJEXT): internal/intern/enum.h
+enc/trans/japanese.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/japanese.$(OBJEXT): internal/intern/error.h
+enc/trans/japanese.$(OBJEXT): internal/intern/eval.h
+enc/trans/japanese.$(OBJEXT): internal/intern/file.h
+enc/trans/japanese.$(OBJEXT): internal/intern/gc.h
+enc/trans/japanese.$(OBJEXT): internal/intern/hash.h
+enc/trans/japanese.$(OBJEXT): internal/intern/io.h
+enc/trans/japanese.$(OBJEXT): internal/intern/load.h
+enc/trans/japanese.$(OBJEXT): internal/intern/marshal.h
+enc/trans/japanese.$(OBJEXT): internal/intern/numeric.h
+enc/trans/japanese.$(OBJEXT): internal/intern/object.h
+enc/trans/japanese.$(OBJEXT): internal/intern/parse.h
+enc/trans/japanese.$(OBJEXT): internal/intern/proc.h
+enc/trans/japanese.$(OBJEXT): internal/intern/process.h
+enc/trans/japanese.$(OBJEXT): internal/intern/random.h
+enc/trans/japanese.$(OBJEXT): internal/intern/range.h
+enc/trans/japanese.$(OBJEXT): internal/intern/rational.h
+enc/trans/japanese.$(OBJEXT): internal/intern/re.h
+enc/trans/japanese.$(OBJEXT): internal/intern/ruby.h
+enc/trans/japanese.$(OBJEXT): internal/intern/select.h
+enc/trans/japanese.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/japanese.$(OBJEXT): internal/intern/signal.h
+enc/trans/japanese.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/japanese.$(OBJEXT): internal/intern/string.h
+enc/trans/japanese.$(OBJEXT): internal/intern/struct.h
+enc/trans/japanese.$(OBJEXT): internal/intern/thread.h
+enc/trans/japanese.$(OBJEXT): internal/intern/time.h
+enc/trans/japanese.$(OBJEXT): internal/intern/variable.h
+enc/trans/japanese.$(OBJEXT): internal/intern/vm.h
+enc/trans/japanese.$(OBJEXT): internal/interpreter.h
+enc/trans/japanese.$(OBJEXT): internal/iterator.h
+enc/trans/japanese.$(OBJEXT): internal/memory.h
+enc/trans/japanese.$(OBJEXT): internal/method.h
+enc/trans/japanese.$(OBJEXT): internal/module.h
+enc/trans/japanese.$(OBJEXT): internal/newobj.h
+enc/trans/japanese.$(OBJEXT): internal/rgengc.h
+enc/trans/japanese.$(OBJEXT): internal/scan_args.h
+enc/trans/japanese.$(OBJEXT): internal/special_consts.h
+enc/trans/japanese.$(OBJEXT): internal/static_assert.h
+enc/trans/japanese.$(OBJEXT): internal/stdalign.h
+enc/trans/japanese.$(OBJEXT): internal/stdbool.h
+enc/trans/japanese.$(OBJEXT): internal/symbol.h
+enc/trans/japanese.$(OBJEXT): internal/token_paste.h
+enc/trans/japanese.$(OBJEXT): internal/value.h
+enc/trans/japanese.$(OBJEXT): internal/value_type.h
+enc/trans/japanese.$(OBJEXT): internal/variable.h
+enc/trans/japanese.$(OBJEXT): internal/warning_push.h
+enc/trans/japanese.$(OBJEXT): internal/xmalloc.h
+enc/trans/japanese.$(OBJEXT): assert.h
enc/trans/japanese.$(OBJEXT): backward.h
+enc/trans/japanese.$(OBJEXT): backward/2/assume.h
+enc/trans/japanese.$(OBJEXT): backward/2/attributes.h
+enc/trans/japanese.$(OBJEXT): backward/2/bool.h
+enc/trans/japanese.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/japanese.$(OBJEXT): backward/2/inttypes.h
+enc/trans/japanese.$(OBJEXT): backward/2/limits.h
+enc/trans/japanese.$(OBJEXT): backward/2/long_long.h
+enc/trans/japanese.$(OBJEXT): backward/2/stdalign.h
+enc/trans/japanese.$(OBJEXT): backward/2/stdarg.h
enc/trans/japanese.$(OBJEXT): config.h
enc/trans/japanese.$(OBJEXT): defines.h
enc/trans/japanese.$(OBJEXT): enc/trans/japanese.c
@@ -561,7 +4467,157 @@ enc/trans/japanese.$(OBJEXT): st.h
enc/trans/japanese.$(OBJEXT): subst.h
enc/trans/japanese_euc.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/japanese_euc.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/japanese_euc.$(OBJEXT): internal/anyargs.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/japanese_euc.$(OBJEXT): internal/assume.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/artificial.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/cold.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/const.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/error.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/format.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/noalias.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/noinline.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/pure.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/restrict.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/warning.h
+enc/trans/japanese_euc.$(OBJEXT): internal/attr/weakref.h
+enc/trans/japanese_euc.$(OBJEXT): internal/cast.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_is.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/japanese_euc.$(OBJEXT): internal/compiler_since.h
+enc/trans/japanese_euc.$(OBJEXT): internal/config.h
+enc/trans/japanese_euc.$(OBJEXT): internal/constant_p.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rarray.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rbasic.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rbignum.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rclass.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rdata.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rfile.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rhash.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/robject.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rregexp.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rstring.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rstruct.h
+enc/trans/japanese_euc.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/japanese_euc.$(OBJEXT): internal/ctype.h
+enc/trans/japanese_euc.$(OBJEXT): internal/dllexport.h
+enc/trans/japanese_euc.$(OBJEXT): internal/dosish.h
+enc/trans/japanese_euc.$(OBJEXT): internal/error.h
+enc/trans/japanese_euc.$(OBJEXT): internal/eval.h
+enc/trans/japanese_euc.$(OBJEXT): internal/event.h
+enc/trans/japanese_euc.$(OBJEXT): internal/fl_type.h
+enc/trans/japanese_euc.$(OBJEXT): internal/gc.h
+enc/trans/japanese_euc.$(OBJEXT): internal/glob.h
+enc/trans/japanese_euc.$(OBJEXT): internal/globals.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/attribute.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/builtin.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/extension.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/feature.h
+enc/trans/japanese_euc.$(OBJEXT): internal/has/warning.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/array.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/bignum.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/class.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/compar.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/complex.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/cont.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/dir.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/enum.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/error.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/eval.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/file.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/gc.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/hash.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/io.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/load.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/marshal.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/numeric.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/object.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/parse.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/proc.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/process.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/random.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/range.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/rational.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/re.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/ruby.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/select.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/signal.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/string.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/struct.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/thread.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/time.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/variable.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/vm.h
+enc/trans/japanese_euc.$(OBJEXT): internal/interpreter.h
+enc/trans/japanese_euc.$(OBJEXT): internal/iterator.h
+enc/trans/japanese_euc.$(OBJEXT): internal/memory.h
+enc/trans/japanese_euc.$(OBJEXT): internal/method.h
+enc/trans/japanese_euc.$(OBJEXT): internal/module.h
+enc/trans/japanese_euc.$(OBJEXT): internal/newobj.h
+enc/trans/japanese_euc.$(OBJEXT): internal/rgengc.h
+enc/trans/japanese_euc.$(OBJEXT): internal/scan_args.h
+enc/trans/japanese_euc.$(OBJEXT): internal/special_consts.h
+enc/trans/japanese_euc.$(OBJEXT): internal/static_assert.h
+enc/trans/japanese_euc.$(OBJEXT): internal/stdalign.h
+enc/trans/japanese_euc.$(OBJEXT): internal/stdbool.h
+enc/trans/japanese_euc.$(OBJEXT): internal/symbol.h
+enc/trans/japanese_euc.$(OBJEXT): internal/token_paste.h
+enc/trans/japanese_euc.$(OBJEXT): internal/value.h
+enc/trans/japanese_euc.$(OBJEXT): internal/value_type.h
+enc/trans/japanese_euc.$(OBJEXT): internal/variable.h
+enc/trans/japanese_euc.$(OBJEXT): internal/warning_push.h
+enc/trans/japanese_euc.$(OBJEXT): internal/xmalloc.h
+enc/trans/japanese_euc.$(OBJEXT): assert.h
enc/trans/japanese_euc.$(OBJEXT): backward.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/assume.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/attributes.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/bool.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/inttypes.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/limits.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/long_long.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/stdalign.h
+enc/trans/japanese_euc.$(OBJEXT): backward/2/stdarg.h
enc/trans/japanese_euc.$(OBJEXT): config.h
enc/trans/japanese_euc.$(OBJEXT): defines.h
enc/trans/japanese_euc.$(OBJEXT): enc/trans/japanese_euc.c
@@ -571,7 +4627,157 @@ enc/trans/japanese_euc.$(OBJEXT): st.h
enc/trans/japanese_euc.$(OBJEXT): subst.h
enc/trans/japanese_sjis.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/japanese_sjis.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/anyargs.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/assume.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/artificial.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/cold.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/const.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/error.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/format.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/noalias.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/noinline.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/pure.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/restrict.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/warning.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/attr/weakref.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/cast.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_is.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/compiler_since.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/config.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/constant_p.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rarray.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rbasic.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rbignum.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rclass.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rdata.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rfile.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rhash.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/robject.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rregexp.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rstring.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rstruct.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/ctype.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/dllexport.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/dosish.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/error.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/eval.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/event.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/fl_type.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/gc.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/glob.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/globals.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/attribute.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/builtin.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/extension.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/feature.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/has/warning.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/array.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/bignum.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/class.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/compar.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/complex.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/cont.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/dir.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/enum.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/error.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/eval.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/file.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/gc.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/hash.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/io.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/load.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/marshal.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/numeric.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/object.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/parse.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/proc.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/process.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/random.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/range.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/rational.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/re.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/ruby.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/select.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/signal.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/string.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/struct.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/thread.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/time.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/variable.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/vm.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/interpreter.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/iterator.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/memory.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/method.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/module.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/newobj.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/rgengc.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/scan_args.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/special_consts.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/static_assert.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/stdalign.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/stdbool.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/symbol.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/token_paste.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/value.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/value_type.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/variable.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/warning_push.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/xmalloc.h
+enc/trans/japanese_sjis.$(OBJEXT): assert.h
enc/trans/japanese_sjis.$(OBJEXT): backward.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/assume.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/attributes.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/bool.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/inttypes.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/limits.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/long_long.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/stdalign.h
+enc/trans/japanese_sjis.$(OBJEXT): backward/2/stdarg.h
enc/trans/japanese_sjis.$(OBJEXT): config.h
enc/trans/japanese_sjis.$(OBJEXT): defines.h
enc/trans/japanese_sjis.$(OBJEXT): enc/trans/japanese_sjis.c
@@ -581,7 +4787,157 @@ enc/trans/japanese_sjis.$(OBJEXT): st.h
enc/trans/japanese_sjis.$(OBJEXT): subst.h
enc/trans/korean.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/korean.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/korean.$(OBJEXT): internal/anyargs.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/korean.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/korean.$(OBJEXT): internal/assume.h
+enc/trans/korean.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/korean.$(OBJEXT): internal/attr/artificial.h
+enc/trans/korean.$(OBJEXT): internal/attr/cold.h
+enc/trans/korean.$(OBJEXT): internal/attr/const.h
+enc/trans/korean.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/korean.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/korean.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/korean.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/korean.$(OBJEXT): internal/attr/error.h
+enc/trans/korean.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/korean.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/korean.$(OBJEXT): internal/attr/format.h
+enc/trans/korean.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/korean.$(OBJEXT): internal/attr/noalias.h
+enc/trans/korean.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/korean.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/korean.$(OBJEXT): internal/attr/noinline.h
+enc/trans/korean.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/korean.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/korean.$(OBJEXT): internal/attr/pure.h
+enc/trans/korean.$(OBJEXT): internal/attr/restrict.h
+enc/trans/korean.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/korean.$(OBJEXT): internal/attr/warning.h
+enc/trans/korean.$(OBJEXT): internal/attr/weakref.h
+enc/trans/korean.$(OBJEXT): internal/cast.h
+enc/trans/korean.$(OBJEXT): internal/compiler_is.h
+enc/trans/korean.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/korean.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/korean.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/korean.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/korean.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/korean.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/korean.$(OBJEXT): internal/compiler_since.h
+enc/trans/korean.$(OBJEXT): internal/config.h
+enc/trans/korean.$(OBJEXT): internal/constant_p.h
+enc/trans/korean.$(OBJEXT): internal/core.h
+enc/trans/korean.$(OBJEXT): internal/core/rarray.h
+enc/trans/korean.$(OBJEXT): internal/core/rbasic.h
+enc/trans/korean.$(OBJEXT): internal/core/rbignum.h
+enc/trans/korean.$(OBJEXT): internal/core/rclass.h
+enc/trans/korean.$(OBJEXT): internal/core/rdata.h
+enc/trans/korean.$(OBJEXT): internal/core/rfile.h
+enc/trans/korean.$(OBJEXT): internal/core/rhash.h
+enc/trans/korean.$(OBJEXT): internal/core/robject.h
+enc/trans/korean.$(OBJEXT): internal/core/rregexp.h
+enc/trans/korean.$(OBJEXT): internal/core/rstring.h
+enc/trans/korean.$(OBJEXT): internal/core/rstruct.h
+enc/trans/korean.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/korean.$(OBJEXT): internal/ctype.h
+enc/trans/korean.$(OBJEXT): internal/dllexport.h
+enc/trans/korean.$(OBJEXT): internal/dosish.h
+enc/trans/korean.$(OBJEXT): internal/error.h
+enc/trans/korean.$(OBJEXT): internal/eval.h
+enc/trans/korean.$(OBJEXT): internal/event.h
+enc/trans/korean.$(OBJEXT): internal/fl_type.h
+enc/trans/korean.$(OBJEXT): internal/gc.h
+enc/trans/korean.$(OBJEXT): internal/glob.h
+enc/trans/korean.$(OBJEXT): internal/globals.h
+enc/trans/korean.$(OBJEXT): internal/has/attribute.h
+enc/trans/korean.$(OBJEXT): internal/has/builtin.h
+enc/trans/korean.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/korean.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/korean.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/korean.$(OBJEXT): internal/has/extension.h
+enc/trans/korean.$(OBJEXT): internal/has/feature.h
+enc/trans/korean.$(OBJEXT): internal/has/warning.h
+enc/trans/korean.$(OBJEXT): internal/intern/array.h
+enc/trans/korean.$(OBJEXT): internal/intern/bignum.h
+enc/trans/korean.$(OBJEXT): internal/intern/class.h
+enc/trans/korean.$(OBJEXT): internal/intern/compar.h
+enc/trans/korean.$(OBJEXT): internal/intern/complex.h
+enc/trans/korean.$(OBJEXT): internal/intern/cont.h
+enc/trans/korean.$(OBJEXT): internal/intern/dir.h
+enc/trans/korean.$(OBJEXT): internal/intern/enum.h
+enc/trans/korean.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/korean.$(OBJEXT): internal/intern/error.h
+enc/trans/korean.$(OBJEXT): internal/intern/eval.h
+enc/trans/korean.$(OBJEXT): internal/intern/file.h
+enc/trans/korean.$(OBJEXT): internal/intern/gc.h
+enc/trans/korean.$(OBJEXT): internal/intern/hash.h
+enc/trans/korean.$(OBJEXT): internal/intern/io.h
+enc/trans/korean.$(OBJEXT): internal/intern/load.h
+enc/trans/korean.$(OBJEXT): internal/intern/marshal.h
+enc/trans/korean.$(OBJEXT): internal/intern/numeric.h
+enc/trans/korean.$(OBJEXT): internal/intern/object.h
+enc/trans/korean.$(OBJEXT): internal/intern/parse.h
+enc/trans/korean.$(OBJEXT): internal/intern/proc.h
+enc/trans/korean.$(OBJEXT): internal/intern/process.h
+enc/trans/korean.$(OBJEXT): internal/intern/random.h
+enc/trans/korean.$(OBJEXT): internal/intern/range.h
+enc/trans/korean.$(OBJEXT): internal/intern/rational.h
+enc/trans/korean.$(OBJEXT): internal/intern/re.h
+enc/trans/korean.$(OBJEXT): internal/intern/ruby.h
+enc/trans/korean.$(OBJEXT): internal/intern/select.h
+enc/trans/korean.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/korean.$(OBJEXT): internal/intern/signal.h
+enc/trans/korean.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/korean.$(OBJEXT): internal/intern/string.h
+enc/trans/korean.$(OBJEXT): internal/intern/struct.h
+enc/trans/korean.$(OBJEXT): internal/intern/thread.h
+enc/trans/korean.$(OBJEXT): internal/intern/time.h
+enc/trans/korean.$(OBJEXT): internal/intern/variable.h
+enc/trans/korean.$(OBJEXT): internal/intern/vm.h
+enc/trans/korean.$(OBJEXT): internal/interpreter.h
+enc/trans/korean.$(OBJEXT): internal/iterator.h
+enc/trans/korean.$(OBJEXT): internal/memory.h
+enc/trans/korean.$(OBJEXT): internal/method.h
+enc/trans/korean.$(OBJEXT): internal/module.h
+enc/trans/korean.$(OBJEXT): internal/newobj.h
+enc/trans/korean.$(OBJEXT): internal/rgengc.h
+enc/trans/korean.$(OBJEXT): internal/scan_args.h
+enc/trans/korean.$(OBJEXT): internal/special_consts.h
+enc/trans/korean.$(OBJEXT): internal/static_assert.h
+enc/trans/korean.$(OBJEXT): internal/stdalign.h
+enc/trans/korean.$(OBJEXT): internal/stdbool.h
+enc/trans/korean.$(OBJEXT): internal/symbol.h
+enc/trans/korean.$(OBJEXT): internal/token_paste.h
+enc/trans/korean.$(OBJEXT): internal/value.h
+enc/trans/korean.$(OBJEXT): internal/value_type.h
+enc/trans/korean.$(OBJEXT): internal/variable.h
+enc/trans/korean.$(OBJEXT): internal/warning_push.h
+enc/trans/korean.$(OBJEXT): internal/xmalloc.h
+enc/trans/korean.$(OBJEXT): assert.h
enc/trans/korean.$(OBJEXT): backward.h
+enc/trans/korean.$(OBJEXT): backward/2/assume.h
+enc/trans/korean.$(OBJEXT): backward/2/attributes.h
+enc/trans/korean.$(OBJEXT): backward/2/bool.h
+enc/trans/korean.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/korean.$(OBJEXT): backward/2/inttypes.h
+enc/trans/korean.$(OBJEXT): backward/2/limits.h
+enc/trans/korean.$(OBJEXT): backward/2/long_long.h
+enc/trans/korean.$(OBJEXT): backward/2/stdalign.h
+enc/trans/korean.$(OBJEXT): backward/2/stdarg.h
enc/trans/korean.$(OBJEXT): config.h
enc/trans/korean.$(OBJEXT): defines.h
enc/trans/korean.$(OBJEXT): enc/trans/korean.c
@@ -591,6 +4947,156 @@ enc/trans/korean.$(OBJEXT): st.h
enc/trans/korean.$(OBJEXT): subst.h
enc/trans/newline.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/newline.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/newline.$(OBJEXT): internal/anyargs.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/newline.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/newline.$(OBJEXT): internal/assume.h
+enc/trans/newline.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/newline.$(OBJEXT): internal/attr/artificial.h
+enc/trans/newline.$(OBJEXT): internal/attr/cold.h
+enc/trans/newline.$(OBJEXT): internal/attr/const.h
+enc/trans/newline.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/newline.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/newline.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/newline.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/newline.$(OBJEXT): internal/attr/error.h
+enc/trans/newline.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/newline.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/newline.$(OBJEXT): internal/attr/format.h
+enc/trans/newline.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/newline.$(OBJEXT): internal/attr/noalias.h
+enc/trans/newline.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/newline.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/newline.$(OBJEXT): internal/attr/noinline.h
+enc/trans/newline.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/newline.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/newline.$(OBJEXT): internal/attr/pure.h
+enc/trans/newline.$(OBJEXT): internal/attr/restrict.h
+enc/trans/newline.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/newline.$(OBJEXT): internal/attr/warning.h
+enc/trans/newline.$(OBJEXT): internal/attr/weakref.h
+enc/trans/newline.$(OBJEXT): internal/cast.h
+enc/trans/newline.$(OBJEXT): internal/compiler_is.h
+enc/trans/newline.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/newline.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/newline.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/newline.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/newline.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/newline.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/newline.$(OBJEXT): internal/compiler_since.h
+enc/trans/newline.$(OBJEXT): internal/config.h
+enc/trans/newline.$(OBJEXT): internal/constant_p.h
+enc/trans/newline.$(OBJEXT): internal/core.h
+enc/trans/newline.$(OBJEXT): internal/core/rarray.h
+enc/trans/newline.$(OBJEXT): internal/core/rbasic.h
+enc/trans/newline.$(OBJEXT): internal/core/rbignum.h
+enc/trans/newline.$(OBJEXT): internal/core/rclass.h
+enc/trans/newline.$(OBJEXT): internal/core/rdata.h
+enc/trans/newline.$(OBJEXT): internal/core/rfile.h
+enc/trans/newline.$(OBJEXT): internal/core/rhash.h
+enc/trans/newline.$(OBJEXT): internal/core/robject.h
+enc/trans/newline.$(OBJEXT): internal/core/rregexp.h
+enc/trans/newline.$(OBJEXT): internal/core/rstring.h
+enc/trans/newline.$(OBJEXT): internal/core/rstruct.h
+enc/trans/newline.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/newline.$(OBJEXT): internal/ctype.h
+enc/trans/newline.$(OBJEXT): internal/dllexport.h
+enc/trans/newline.$(OBJEXT): internal/dosish.h
+enc/trans/newline.$(OBJEXT): internal/error.h
+enc/trans/newline.$(OBJEXT): internal/eval.h
+enc/trans/newline.$(OBJEXT): internal/event.h
+enc/trans/newline.$(OBJEXT): internal/fl_type.h
+enc/trans/newline.$(OBJEXT): internal/gc.h
+enc/trans/newline.$(OBJEXT): internal/glob.h
+enc/trans/newline.$(OBJEXT): internal/globals.h
+enc/trans/newline.$(OBJEXT): internal/has/attribute.h
+enc/trans/newline.$(OBJEXT): internal/has/builtin.h
+enc/trans/newline.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/newline.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/newline.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/newline.$(OBJEXT): internal/has/extension.h
+enc/trans/newline.$(OBJEXT): internal/has/feature.h
+enc/trans/newline.$(OBJEXT): internal/has/warning.h
+enc/trans/newline.$(OBJEXT): internal/intern/array.h
+enc/trans/newline.$(OBJEXT): internal/intern/bignum.h
+enc/trans/newline.$(OBJEXT): internal/intern/class.h
+enc/trans/newline.$(OBJEXT): internal/intern/compar.h
+enc/trans/newline.$(OBJEXT): internal/intern/complex.h
+enc/trans/newline.$(OBJEXT): internal/intern/cont.h
+enc/trans/newline.$(OBJEXT): internal/intern/dir.h
+enc/trans/newline.$(OBJEXT): internal/intern/enum.h
+enc/trans/newline.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/newline.$(OBJEXT): internal/intern/error.h
+enc/trans/newline.$(OBJEXT): internal/intern/eval.h
+enc/trans/newline.$(OBJEXT): internal/intern/file.h
+enc/trans/newline.$(OBJEXT): internal/intern/gc.h
+enc/trans/newline.$(OBJEXT): internal/intern/hash.h
+enc/trans/newline.$(OBJEXT): internal/intern/io.h
+enc/trans/newline.$(OBJEXT): internal/intern/load.h
+enc/trans/newline.$(OBJEXT): internal/intern/marshal.h
+enc/trans/newline.$(OBJEXT): internal/intern/numeric.h
+enc/trans/newline.$(OBJEXT): internal/intern/object.h
+enc/trans/newline.$(OBJEXT): internal/intern/parse.h
+enc/trans/newline.$(OBJEXT): internal/intern/proc.h
+enc/trans/newline.$(OBJEXT): internal/intern/process.h
+enc/trans/newline.$(OBJEXT): internal/intern/random.h
+enc/trans/newline.$(OBJEXT): internal/intern/range.h
+enc/trans/newline.$(OBJEXT): internal/intern/rational.h
+enc/trans/newline.$(OBJEXT): internal/intern/re.h
+enc/trans/newline.$(OBJEXT): internal/intern/ruby.h
+enc/trans/newline.$(OBJEXT): internal/intern/select.h
+enc/trans/newline.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/newline.$(OBJEXT): internal/intern/signal.h
+enc/trans/newline.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/newline.$(OBJEXT): internal/intern/string.h
+enc/trans/newline.$(OBJEXT): internal/intern/struct.h
+enc/trans/newline.$(OBJEXT): internal/intern/thread.h
+enc/trans/newline.$(OBJEXT): internal/intern/time.h
+enc/trans/newline.$(OBJEXT): internal/intern/variable.h
+enc/trans/newline.$(OBJEXT): internal/intern/vm.h
+enc/trans/newline.$(OBJEXT): internal/interpreter.h
+enc/trans/newline.$(OBJEXT): internal/iterator.h
+enc/trans/newline.$(OBJEXT): internal/memory.h
+enc/trans/newline.$(OBJEXT): internal/method.h
+enc/trans/newline.$(OBJEXT): internal/module.h
+enc/trans/newline.$(OBJEXT): internal/newobj.h
+enc/trans/newline.$(OBJEXT): internal/rgengc.h
+enc/trans/newline.$(OBJEXT): internal/scan_args.h
+enc/trans/newline.$(OBJEXT): internal/special_consts.h
+enc/trans/newline.$(OBJEXT): internal/static_assert.h
+enc/trans/newline.$(OBJEXT): internal/stdalign.h
+enc/trans/newline.$(OBJEXT): internal/stdbool.h
+enc/trans/newline.$(OBJEXT): internal/symbol.h
+enc/trans/newline.$(OBJEXT): internal/token_paste.h
+enc/trans/newline.$(OBJEXT): internal/value.h
+enc/trans/newline.$(OBJEXT): internal/value_type.h
+enc/trans/newline.$(OBJEXT): internal/variable.h
+enc/trans/newline.$(OBJEXT): internal/warning_push.h
+enc/trans/newline.$(OBJEXT): internal/xmalloc.h
+enc/trans/newline.$(OBJEXT): assert.h
+enc/trans/newline.$(OBJEXT): backward/2/assume.h
+enc/trans/newline.$(OBJEXT): backward/2/attributes.h
+enc/trans/newline.$(OBJEXT): backward/2/bool.h
+enc/trans/newline.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/newline.$(OBJEXT): backward/2/inttypes.h
+enc/trans/newline.$(OBJEXT): backward/2/limits.h
+enc/trans/newline.$(OBJEXT): backward/2/long_long.h
+enc/trans/newline.$(OBJEXT): backward/2/stdalign.h
+enc/trans/newline.$(OBJEXT): backward/2/stdarg.h
enc/trans/newline.$(OBJEXT): config.h
enc/trans/newline.$(OBJEXT): defines.h
enc/trans/newline.$(OBJEXT): enc/trans/newline.c
@@ -600,7 +5106,157 @@ enc/trans/newline.$(OBJEXT): st.h
enc/trans/newline.$(OBJEXT): subst.h
enc/trans/single_byte.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/single_byte.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/single_byte.$(OBJEXT): internal/anyargs.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/single_byte.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/single_byte.$(OBJEXT): internal/assume.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/artificial.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/cold.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/const.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/error.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/format.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/noalias.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/noinline.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/pure.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/restrict.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/warning.h
+enc/trans/single_byte.$(OBJEXT): internal/attr/weakref.h
+enc/trans/single_byte.$(OBJEXT): internal/cast.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_is.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/single_byte.$(OBJEXT): internal/compiler_since.h
+enc/trans/single_byte.$(OBJEXT): internal/config.h
+enc/trans/single_byte.$(OBJEXT): internal/constant_p.h
+enc/trans/single_byte.$(OBJEXT): internal/core.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rarray.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rbasic.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rbignum.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rclass.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rdata.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rfile.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rhash.h
+enc/trans/single_byte.$(OBJEXT): internal/core/robject.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rregexp.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rstring.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rstruct.h
+enc/trans/single_byte.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/single_byte.$(OBJEXT): internal/ctype.h
+enc/trans/single_byte.$(OBJEXT): internal/dllexport.h
+enc/trans/single_byte.$(OBJEXT): internal/dosish.h
+enc/trans/single_byte.$(OBJEXT): internal/error.h
+enc/trans/single_byte.$(OBJEXT): internal/eval.h
+enc/trans/single_byte.$(OBJEXT): internal/event.h
+enc/trans/single_byte.$(OBJEXT): internal/fl_type.h
+enc/trans/single_byte.$(OBJEXT): internal/gc.h
+enc/trans/single_byte.$(OBJEXT): internal/glob.h
+enc/trans/single_byte.$(OBJEXT): internal/globals.h
+enc/trans/single_byte.$(OBJEXT): internal/has/attribute.h
+enc/trans/single_byte.$(OBJEXT): internal/has/builtin.h
+enc/trans/single_byte.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/single_byte.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/single_byte.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/single_byte.$(OBJEXT): internal/has/extension.h
+enc/trans/single_byte.$(OBJEXT): internal/has/feature.h
+enc/trans/single_byte.$(OBJEXT): internal/has/warning.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/array.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/bignum.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/class.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/compar.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/complex.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/cont.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/dir.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/enum.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/error.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/eval.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/file.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/gc.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/hash.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/io.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/load.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/marshal.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/numeric.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/object.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/parse.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/proc.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/process.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/random.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/range.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/rational.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/re.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/ruby.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/select.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/signal.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/string.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/struct.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/thread.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/time.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/variable.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/vm.h
+enc/trans/single_byte.$(OBJEXT): internal/interpreter.h
+enc/trans/single_byte.$(OBJEXT): internal/iterator.h
+enc/trans/single_byte.$(OBJEXT): internal/memory.h
+enc/trans/single_byte.$(OBJEXT): internal/method.h
+enc/trans/single_byte.$(OBJEXT): internal/module.h
+enc/trans/single_byte.$(OBJEXT): internal/newobj.h
+enc/trans/single_byte.$(OBJEXT): internal/rgengc.h
+enc/trans/single_byte.$(OBJEXT): internal/scan_args.h
+enc/trans/single_byte.$(OBJEXT): internal/special_consts.h
+enc/trans/single_byte.$(OBJEXT): internal/static_assert.h
+enc/trans/single_byte.$(OBJEXT): internal/stdalign.h
+enc/trans/single_byte.$(OBJEXT): internal/stdbool.h
+enc/trans/single_byte.$(OBJEXT): internal/symbol.h
+enc/trans/single_byte.$(OBJEXT): internal/token_paste.h
+enc/trans/single_byte.$(OBJEXT): internal/value.h
+enc/trans/single_byte.$(OBJEXT): internal/value_type.h
+enc/trans/single_byte.$(OBJEXT): internal/variable.h
+enc/trans/single_byte.$(OBJEXT): internal/warning_push.h
+enc/trans/single_byte.$(OBJEXT): internal/xmalloc.h
+enc/trans/single_byte.$(OBJEXT): assert.h
enc/trans/single_byte.$(OBJEXT): backward.h
+enc/trans/single_byte.$(OBJEXT): backward/2/assume.h
+enc/trans/single_byte.$(OBJEXT): backward/2/attributes.h
+enc/trans/single_byte.$(OBJEXT): backward/2/bool.h
+enc/trans/single_byte.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/single_byte.$(OBJEXT): backward/2/inttypes.h
+enc/trans/single_byte.$(OBJEXT): backward/2/limits.h
+enc/trans/single_byte.$(OBJEXT): backward/2/long_long.h
+enc/trans/single_byte.$(OBJEXT): backward/2/stdalign.h
+enc/trans/single_byte.$(OBJEXT): backward/2/stdarg.h
enc/trans/single_byte.$(OBJEXT): config.h
enc/trans/single_byte.$(OBJEXT): defines.h
enc/trans/single_byte.$(OBJEXT): enc/trans/single_byte.c
@@ -612,7 +5268,157 @@ enc/trans/transdb.$(OBJEXT): enc/trans/transdb.c
enc/trans/transdb.$(OBJEXT): transdb.h
enc/trans/utf8_mac.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/utf8_mac.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/utf8_mac.$(OBJEXT): internal/anyargs.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/utf8_mac.$(OBJEXT): internal/assume.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/artificial.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/cold.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/const.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/error.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/format.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/noalias.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/noinline.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/pure.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/restrict.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/warning.h
+enc/trans/utf8_mac.$(OBJEXT): internal/attr/weakref.h
+enc/trans/utf8_mac.$(OBJEXT): internal/cast.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_is.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/utf8_mac.$(OBJEXT): internal/compiler_since.h
+enc/trans/utf8_mac.$(OBJEXT): internal/config.h
+enc/trans/utf8_mac.$(OBJEXT): internal/constant_p.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rarray.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rbasic.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rbignum.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rclass.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rdata.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rfile.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rhash.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/robject.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rregexp.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rstring.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rstruct.h
+enc/trans/utf8_mac.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/utf8_mac.$(OBJEXT): internal/ctype.h
+enc/trans/utf8_mac.$(OBJEXT): internal/dllexport.h
+enc/trans/utf8_mac.$(OBJEXT): internal/dosish.h
+enc/trans/utf8_mac.$(OBJEXT): internal/error.h
+enc/trans/utf8_mac.$(OBJEXT): internal/eval.h
+enc/trans/utf8_mac.$(OBJEXT): internal/event.h
+enc/trans/utf8_mac.$(OBJEXT): internal/fl_type.h
+enc/trans/utf8_mac.$(OBJEXT): internal/gc.h
+enc/trans/utf8_mac.$(OBJEXT): internal/glob.h
+enc/trans/utf8_mac.$(OBJEXT): internal/globals.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/attribute.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/builtin.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/extension.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/feature.h
+enc/trans/utf8_mac.$(OBJEXT): internal/has/warning.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/array.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/bignum.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/class.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/compar.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/complex.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/cont.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/dir.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/enum.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/error.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/eval.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/file.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/gc.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/hash.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/io.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/load.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/marshal.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/numeric.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/object.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/parse.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/proc.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/process.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/random.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/range.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/rational.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/re.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/ruby.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/select.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/signal.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/string.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/struct.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/thread.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/time.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/variable.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/vm.h
+enc/trans/utf8_mac.$(OBJEXT): internal/interpreter.h
+enc/trans/utf8_mac.$(OBJEXT): internal/iterator.h
+enc/trans/utf8_mac.$(OBJEXT): internal/memory.h
+enc/trans/utf8_mac.$(OBJEXT): internal/method.h
+enc/trans/utf8_mac.$(OBJEXT): internal/module.h
+enc/trans/utf8_mac.$(OBJEXT): internal/newobj.h
+enc/trans/utf8_mac.$(OBJEXT): internal/rgengc.h
+enc/trans/utf8_mac.$(OBJEXT): internal/scan_args.h
+enc/trans/utf8_mac.$(OBJEXT): internal/special_consts.h
+enc/trans/utf8_mac.$(OBJEXT): internal/static_assert.h
+enc/trans/utf8_mac.$(OBJEXT): internal/stdalign.h
+enc/trans/utf8_mac.$(OBJEXT): internal/stdbool.h
+enc/trans/utf8_mac.$(OBJEXT): internal/symbol.h
+enc/trans/utf8_mac.$(OBJEXT): internal/token_paste.h
+enc/trans/utf8_mac.$(OBJEXT): internal/value.h
+enc/trans/utf8_mac.$(OBJEXT): internal/value_type.h
+enc/trans/utf8_mac.$(OBJEXT): internal/variable.h
+enc/trans/utf8_mac.$(OBJEXT): internal/warning_push.h
+enc/trans/utf8_mac.$(OBJEXT): internal/xmalloc.h
+enc/trans/utf8_mac.$(OBJEXT): assert.h
enc/trans/utf8_mac.$(OBJEXT): backward.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/assume.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/attributes.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/bool.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/inttypes.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/limits.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/long_long.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/stdalign.h
+enc/trans/utf8_mac.$(OBJEXT): backward/2/stdarg.h
enc/trans/utf8_mac.$(OBJEXT): config.h
enc/trans/utf8_mac.$(OBJEXT): defines.h
enc/trans/utf8_mac.$(OBJEXT): enc/trans/utf8_mac.c
@@ -622,7 +5428,157 @@ enc/trans/utf8_mac.$(OBJEXT): st.h
enc/trans/utf8_mac.$(OBJEXT): subst.h
enc/trans/utf_16_32.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/trans/utf_16_32.$(OBJEXT): $(top_srcdir)/transcode_data.h
+enc/trans/utf_16_32.$(OBJEXT): internal/anyargs.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/char.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/double.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/int.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/long.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/long_long.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/off_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/short.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/size_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/trans/utf_16_32.$(OBJEXT): internal/assume.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/alloc_size.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/artificial.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/cold.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/const.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/constexpr.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/deprecated.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/diagnose_if.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/error.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/flag_enum.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/forceinline.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/format.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/maybe_unused.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/noalias.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/nodiscard.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/noexcept.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/noinline.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/noreturn.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/pure.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/restrict.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/warning.h
+enc/trans/utf_16_32.$(OBJEXT): internal/attr/weakref.h
+enc/trans/utf_16_32.$(OBJEXT): internal/cast.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_is.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_is/apple.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_is/clang.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_is/gcc.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_is/intel.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_is/msvc.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/trans/utf_16_32.$(OBJEXT): internal/compiler_since.h
+enc/trans/utf_16_32.$(OBJEXT): internal/config.h
+enc/trans/utf_16_32.$(OBJEXT): internal/constant_p.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rarray.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rbasic.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rbignum.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rclass.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rdata.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rfile.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rhash.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/robject.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rregexp.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rstring.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rstruct.h
+enc/trans/utf_16_32.$(OBJEXT): internal/core/rtypeddata.h
+enc/trans/utf_16_32.$(OBJEXT): internal/ctype.h
+enc/trans/utf_16_32.$(OBJEXT): internal/dllexport.h
+enc/trans/utf_16_32.$(OBJEXT): internal/dosish.h
+enc/trans/utf_16_32.$(OBJEXT): internal/error.h
+enc/trans/utf_16_32.$(OBJEXT): internal/eval.h
+enc/trans/utf_16_32.$(OBJEXT): internal/event.h
+enc/trans/utf_16_32.$(OBJEXT): internal/fl_type.h
+enc/trans/utf_16_32.$(OBJEXT): internal/gc.h
+enc/trans/utf_16_32.$(OBJEXT): internal/glob.h
+enc/trans/utf_16_32.$(OBJEXT): internal/globals.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/attribute.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/builtin.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/c_attribute.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/cpp_attribute.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/declspec_attribute.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/extension.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/feature.h
+enc/trans/utf_16_32.$(OBJEXT): internal/has/warning.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/array.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/bignum.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/class.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/compar.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/complex.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/cont.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/dir.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/enum.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/enumerator.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/error.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/eval.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/file.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/gc.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/hash.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/io.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/load.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/marshal.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/numeric.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/object.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/parse.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/proc.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/process.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/random.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/range.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/rational.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/re.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/ruby.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/select.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/select/largesize.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/signal.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/sprintf.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/string.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/struct.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/thread.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/time.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/variable.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/vm.h
+enc/trans/utf_16_32.$(OBJEXT): internal/interpreter.h
+enc/trans/utf_16_32.$(OBJEXT): internal/iterator.h
+enc/trans/utf_16_32.$(OBJEXT): internal/memory.h
+enc/trans/utf_16_32.$(OBJEXT): internal/method.h
+enc/trans/utf_16_32.$(OBJEXT): internal/module.h
+enc/trans/utf_16_32.$(OBJEXT): internal/newobj.h
+enc/trans/utf_16_32.$(OBJEXT): internal/rgengc.h
+enc/trans/utf_16_32.$(OBJEXT): internal/scan_args.h
+enc/trans/utf_16_32.$(OBJEXT): internal/special_consts.h
+enc/trans/utf_16_32.$(OBJEXT): internal/static_assert.h
+enc/trans/utf_16_32.$(OBJEXT): internal/stdalign.h
+enc/trans/utf_16_32.$(OBJEXT): internal/stdbool.h
+enc/trans/utf_16_32.$(OBJEXT): internal/symbol.h
+enc/trans/utf_16_32.$(OBJEXT): internal/token_paste.h
+enc/trans/utf_16_32.$(OBJEXT): internal/value.h
+enc/trans/utf_16_32.$(OBJEXT): internal/value_type.h
+enc/trans/utf_16_32.$(OBJEXT): internal/variable.h
+enc/trans/utf_16_32.$(OBJEXT): internal/warning_push.h
+enc/trans/utf_16_32.$(OBJEXT): internal/xmalloc.h
+enc/trans/utf_16_32.$(OBJEXT): assert.h
enc/trans/utf_16_32.$(OBJEXT): backward.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/assume.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/attributes.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/bool.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/gcc_version_since.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/inttypes.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/limits.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/long_long.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/stdalign.h
+enc/trans/utf_16_32.$(OBJEXT): backward/2/stdarg.h
enc/trans/utf_16_32.$(OBJEXT): config.h
enc/trans/utf_16_32.$(OBJEXT): defines.h
enc/trans/utf_16_32.$(OBJEXT): enc/trans/utf_16_32.c
@@ -635,93 +5591,1004 @@ enc/unicode.$(OBJEXT): $(UNICODE_HDR_DIR)/name2ctype.h
enc/unicode.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/unicode.$(OBJEXT): $(top_srcdir)/regenc.h
enc/unicode.$(OBJEXT): $(top_srcdir)/regint.h
+enc/unicode.$(OBJEXT): internal/anyargs.h
+enc/unicode.$(OBJEXT): internal/arithmetic.h
+enc/unicode.$(OBJEXT): internal/arithmetic/char.h
+enc/unicode.$(OBJEXT): internal/arithmetic/double.h
+enc/unicode.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/unicode.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/unicode.$(OBJEXT): internal/arithmetic/int.h
+enc/unicode.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/unicode.$(OBJEXT): internal/arithmetic/long.h
+enc/unicode.$(OBJEXT): internal/arithmetic/long_long.h
+enc/unicode.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/unicode.$(OBJEXT): internal/arithmetic/off_t.h
+enc/unicode.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/unicode.$(OBJEXT): internal/arithmetic/short.h
+enc/unicode.$(OBJEXT): internal/arithmetic/size_t.h
+enc/unicode.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/unicode.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/unicode.$(OBJEXT): internal/assume.h
+enc/unicode.$(OBJEXT): internal/attr/alloc_size.h
+enc/unicode.$(OBJEXT): internal/attr/artificial.h
+enc/unicode.$(OBJEXT): internal/attr/cold.h
+enc/unicode.$(OBJEXT): internal/attr/const.h
+enc/unicode.$(OBJEXT): internal/attr/constexpr.h
+enc/unicode.$(OBJEXT): internal/attr/deprecated.h
+enc/unicode.$(OBJEXT): internal/attr/diagnose_if.h
+enc/unicode.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/unicode.$(OBJEXT): internal/attr/error.h
+enc/unicode.$(OBJEXT): internal/attr/flag_enum.h
+enc/unicode.$(OBJEXT): internal/attr/forceinline.h
+enc/unicode.$(OBJEXT): internal/attr/format.h
+enc/unicode.$(OBJEXT): internal/attr/maybe_unused.h
+enc/unicode.$(OBJEXT): internal/attr/noalias.h
+enc/unicode.$(OBJEXT): internal/attr/nodiscard.h
+enc/unicode.$(OBJEXT): internal/attr/noexcept.h
+enc/unicode.$(OBJEXT): internal/attr/noinline.h
+enc/unicode.$(OBJEXT): internal/attr/nonnull.h
+enc/unicode.$(OBJEXT): internal/attr/noreturn.h
+enc/unicode.$(OBJEXT): internal/attr/pure.h
+enc/unicode.$(OBJEXT): internal/attr/restrict.h
+enc/unicode.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/unicode.$(OBJEXT): internal/attr/warning.h
+enc/unicode.$(OBJEXT): internal/attr/weakref.h
+enc/unicode.$(OBJEXT): internal/cast.h
+enc/unicode.$(OBJEXT): internal/compiler_is.h
+enc/unicode.$(OBJEXT): internal/compiler_is/apple.h
+enc/unicode.$(OBJEXT): internal/compiler_is/clang.h
+enc/unicode.$(OBJEXT): internal/compiler_is/gcc.h
+enc/unicode.$(OBJEXT): internal/compiler_is/intel.h
+enc/unicode.$(OBJEXT): internal/compiler_is/msvc.h
+enc/unicode.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/unicode.$(OBJEXT): internal/compiler_since.h
+enc/unicode.$(OBJEXT): internal/config.h
+enc/unicode.$(OBJEXT): internal/constant_p.h
+enc/unicode.$(OBJEXT): internal/core.h
+enc/unicode.$(OBJEXT): internal/core/rarray.h
+enc/unicode.$(OBJEXT): internal/core/rbasic.h
+enc/unicode.$(OBJEXT): internal/core/rbignum.h
+enc/unicode.$(OBJEXT): internal/core/rclass.h
+enc/unicode.$(OBJEXT): internal/core/rdata.h
+enc/unicode.$(OBJEXT): internal/core/rfile.h
+enc/unicode.$(OBJEXT): internal/core/rhash.h
+enc/unicode.$(OBJEXT): internal/core/robject.h
+enc/unicode.$(OBJEXT): internal/core/rregexp.h
+enc/unicode.$(OBJEXT): internal/core/rstring.h
+enc/unicode.$(OBJEXT): internal/core/rstruct.h
+enc/unicode.$(OBJEXT): internal/core/rtypeddata.h
+enc/unicode.$(OBJEXT): internal/ctype.h
+enc/unicode.$(OBJEXT): internal/dllexport.h
+enc/unicode.$(OBJEXT): internal/dosish.h
+enc/unicode.$(OBJEXT): internal/error.h
+enc/unicode.$(OBJEXT): internal/eval.h
+enc/unicode.$(OBJEXT): internal/event.h
+enc/unicode.$(OBJEXT): internal/fl_type.h
+enc/unicode.$(OBJEXT): internal/gc.h
+enc/unicode.$(OBJEXT): internal/glob.h
+enc/unicode.$(OBJEXT): internal/globals.h
+enc/unicode.$(OBJEXT): internal/has/attribute.h
+enc/unicode.$(OBJEXT): internal/has/builtin.h
+enc/unicode.$(OBJEXT): internal/has/c_attribute.h
+enc/unicode.$(OBJEXT): internal/has/cpp_attribute.h
+enc/unicode.$(OBJEXT): internal/has/declspec_attribute.h
+enc/unicode.$(OBJEXT): internal/has/extension.h
+enc/unicode.$(OBJEXT): internal/has/feature.h
+enc/unicode.$(OBJEXT): internal/has/warning.h
+enc/unicode.$(OBJEXT): internal/intern/array.h
+enc/unicode.$(OBJEXT): internal/intern/bignum.h
+enc/unicode.$(OBJEXT): internal/intern/class.h
+enc/unicode.$(OBJEXT): internal/intern/compar.h
+enc/unicode.$(OBJEXT): internal/intern/complex.h
+enc/unicode.$(OBJEXT): internal/intern/cont.h
+enc/unicode.$(OBJEXT): internal/intern/dir.h
+enc/unicode.$(OBJEXT): internal/intern/enum.h
+enc/unicode.$(OBJEXT): internal/intern/enumerator.h
+enc/unicode.$(OBJEXT): internal/intern/error.h
+enc/unicode.$(OBJEXT): internal/intern/eval.h
+enc/unicode.$(OBJEXT): internal/intern/file.h
+enc/unicode.$(OBJEXT): internal/intern/gc.h
+enc/unicode.$(OBJEXT): internal/intern/hash.h
+enc/unicode.$(OBJEXT): internal/intern/io.h
+enc/unicode.$(OBJEXT): internal/intern/load.h
+enc/unicode.$(OBJEXT): internal/intern/marshal.h
+enc/unicode.$(OBJEXT): internal/intern/numeric.h
+enc/unicode.$(OBJEXT): internal/intern/object.h
+enc/unicode.$(OBJEXT): internal/intern/parse.h
+enc/unicode.$(OBJEXT): internal/intern/proc.h
+enc/unicode.$(OBJEXT): internal/intern/process.h
+enc/unicode.$(OBJEXT): internal/intern/random.h
+enc/unicode.$(OBJEXT): internal/intern/range.h
+enc/unicode.$(OBJEXT): internal/intern/rational.h
+enc/unicode.$(OBJEXT): internal/intern/re.h
+enc/unicode.$(OBJEXT): internal/intern/ruby.h
+enc/unicode.$(OBJEXT): internal/intern/select.h
+enc/unicode.$(OBJEXT): internal/intern/select/largesize.h
+enc/unicode.$(OBJEXT): internal/intern/signal.h
+enc/unicode.$(OBJEXT): internal/intern/sprintf.h
+enc/unicode.$(OBJEXT): internal/intern/string.h
+enc/unicode.$(OBJEXT): internal/intern/struct.h
+enc/unicode.$(OBJEXT): internal/intern/thread.h
+enc/unicode.$(OBJEXT): internal/intern/time.h
+enc/unicode.$(OBJEXT): internal/intern/variable.h
+enc/unicode.$(OBJEXT): internal/intern/vm.h
+enc/unicode.$(OBJEXT): internal/interpreter.h
+enc/unicode.$(OBJEXT): internal/iterator.h
+enc/unicode.$(OBJEXT): internal/memory.h
+enc/unicode.$(OBJEXT): internal/method.h
+enc/unicode.$(OBJEXT): internal/module.h
+enc/unicode.$(OBJEXT): internal/newobj.h
+enc/unicode.$(OBJEXT): internal/rgengc.h
+enc/unicode.$(OBJEXT): internal/scan_args.h
+enc/unicode.$(OBJEXT): internal/special_consts.h
+enc/unicode.$(OBJEXT): internal/static_assert.h
+enc/unicode.$(OBJEXT): internal/stdalign.h
+enc/unicode.$(OBJEXT): internal/stdbool.h
+enc/unicode.$(OBJEXT): internal/symbol.h
+enc/unicode.$(OBJEXT): internal/token_paste.h
+enc/unicode.$(OBJEXT): internal/value.h
+enc/unicode.$(OBJEXT): internal/value_type.h
+enc/unicode.$(OBJEXT): internal/variable.h
+enc/unicode.$(OBJEXT): internal/warning_push.h
+enc/unicode.$(OBJEXT): internal/xmalloc.h
+enc/unicode.$(OBJEXT): assert.h
+enc/unicode.$(OBJEXT): backward/2/assume.h
+enc/unicode.$(OBJEXT): backward/2/attributes.h
+enc/unicode.$(OBJEXT): backward/2/bool.h
+enc/unicode.$(OBJEXT): backward/2/gcc_version_since.h
+enc/unicode.$(OBJEXT): backward/2/inttypes.h
+enc/unicode.$(OBJEXT): backward/2/limits.h
+enc/unicode.$(OBJEXT): backward/2/long_long.h
+enc/unicode.$(OBJEXT): backward/2/stdalign.h
+enc/unicode.$(OBJEXT): backward/2/stdarg.h
enc/unicode.$(OBJEXT): config.h
enc/unicode.$(OBJEXT): defines.h
enc/unicode.$(OBJEXT): enc/unicode.c
enc/unicode.$(OBJEXT): intern.h
enc/unicode.$(OBJEXT): missing.h
enc/unicode.$(OBJEXT): onigmo.h
-enc/unicode.$(OBJEXT): oniguruma.h
enc/unicode.$(OBJEXT): st.h
enc/unicode.$(OBJEXT): subst.h
+enc/us_ascii.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/us_ascii.$(OBJEXT): $(top_srcdir)/encindex.h
enc/us_ascii.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/us_ascii.$(OBJEXT): internal/anyargs.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/char.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/double.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/int.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/long.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/long_long.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/off_t.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/short.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/size_t.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/us_ascii.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/us_ascii.$(OBJEXT): internal/assume.h
+enc/us_ascii.$(OBJEXT): internal/attr/alloc_size.h
+enc/us_ascii.$(OBJEXT): internal/attr/artificial.h
+enc/us_ascii.$(OBJEXT): internal/attr/cold.h
+enc/us_ascii.$(OBJEXT): internal/attr/const.h
+enc/us_ascii.$(OBJEXT): internal/attr/constexpr.h
+enc/us_ascii.$(OBJEXT): internal/attr/deprecated.h
+enc/us_ascii.$(OBJEXT): internal/attr/diagnose_if.h
+enc/us_ascii.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/us_ascii.$(OBJEXT): internal/attr/error.h
+enc/us_ascii.$(OBJEXT): internal/attr/flag_enum.h
+enc/us_ascii.$(OBJEXT): internal/attr/forceinline.h
+enc/us_ascii.$(OBJEXT): internal/attr/format.h
+enc/us_ascii.$(OBJEXT): internal/attr/maybe_unused.h
+enc/us_ascii.$(OBJEXT): internal/attr/noalias.h
+enc/us_ascii.$(OBJEXT): internal/attr/nodiscard.h
+enc/us_ascii.$(OBJEXT): internal/attr/noexcept.h
+enc/us_ascii.$(OBJEXT): internal/attr/noinline.h
+enc/us_ascii.$(OBJEXT): internal/attr/nonnull.h
+enc/us_ascii.$(OBJEXT): internal/attr/noreturn.h
+enc/us_ascii.$(OBJEXT): internal/attr/pure.h
+enc/us_ascii.$(OBJEXT): internal/attr/restrict.h
+enc/us_ascii.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/us_ascii.$(OBJEXT): internal/attr/warning.h
+enc/us_ascii.$(OBJEXT): internal/attr/weakref.h
+enc/us_ascii.$(OBJEXT): internal/cast.h
+enc/us_ascii.$(OBJEXT): internal/compiler_is.h
+enc/us_ascii.$(OBJEXT): internal/compiler_is/apple.h
+enc/us_ascii.$(OBJEXT): internal/compiler_is/clang.h
+enc/us_ascii.$(OBJEXT): internal/compiler_is/gcc.h
+enc/us_ascii.$(OBJEXT): internal/compiler_is/intel.h
+enc/us_ascii.$(OBJEXT): internal/compiler_is/msvc.h
+enc/us_ascii.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/us_ascii.$(OBJEXT): internal/compiler_since.h
+enc/us_ascii.$(OBJEXT): internal/config.h
+enc/us_ascii.$(OBJEXT): internal/constant_p.h
+enc/us_ascii.$(OBJEXT): internal/core.h
+enc/us_ascii.$(OBJEXT): internal/core/rarray.h
+enc/us_ascii.$(OBJEXT): internal/core/rbasic.h
+enc/us_ascii.$(OBJEXT): internal/core/rbignum.h
+enc/us_ascii.$(OBJEXT): internal/core/rclass.h
+enc/us_ascii.$(OBJEXT): internal/core/rdata.h
+enc/us_ascii.$(OBJEXT): internal/core/rfile.h
+enc/us_ascii.$(OBJEXT): internal/core/rhash.h
+enc/us_ascii.$(OBJEXT): internal/core/robject.h
+enc/us_ascii.$(OBJEXT): internal/core/rregexp.h
+enc/us_ascii.$(OBJEXT): internal/core/rstring.h
+enc/us_ascii.$(OBJEXT): internal/core/rstruct.h
+enc/us_ascii.$(OBJEXT): internal/core/rtypeddata.h
+enc/us_ascii.$(OBJEXT): internal/ctype.h
+enc/us_ascii.$(OBJEXT): internal/dllexport.h
+enc/us_ascii.$(OBJEXT): internal/dosish.h
+enc/us_ascii.$(OBJEXT): internal/error.h
+enc/us_ascii.$(OBJEXT): internal/eval.h
+enc/us_ascii.$(OBJEXT): internal/event.h
+enc/us_ascii.$(OBJEXT): internal/fl_type.h
+enc/us_ascii.$(OBJEXT): internal/gc.h
+enc/us_ascii.$(OBJEXT): internal/glob.h
+enc/us_ascii.$(OBJEXT): internal/globals.h
+enc/us_ascii.$(OBJEXT): internal/has/attribute.h
+enc/us_ascii.$(OBJEXT): internal/has/builtin.h
+enc/us_ascii.$(OBJEXT): internal/has/c_attribute.h
+enc/us_ascii.$(OBJEXT): internal/has/cpp_attribute.h
+enc/us_ascii.$(OBJEXT): internal/has/declspec_attribute.h
+enc/us_ascii.$(OBJEXT): internal/has/extension.h
+enc/us_ascii.$(OBJEXT): internal/has/feature.h
+enc/us_ascii.$(OBJEXT): internal/has/warning.h
+enc/us_ascii.$(OBJEXT): internal/intern/array.h
+enc/us_ascii.$(OBJEXT): internal/intern/bignum.h
+enc/us_ascii.$(OBJEXT): internal/intern/class.h
+enc/us_ascii.$(OBJEXT): internal/intern/compar.h
+enc/us_ascii.$(OBJEXT): internal/intern/complex.h
+enc/us_ascii.$(OBJEXT): internal/intern/cont.h
+enc/us_ascii.$(OBJEXT): internal/intern/dir.h
+enc/us_ascii.$(OBJEXT): internal/intern/enum.h
+enc/us_ascii.$(OBJEXT): internal/intern/enumerator.h
+enc/us_ascii.$(OBJEXT): internal/intern/error.h
+enc/us_ascii.$(OBJEXT): internal/intern/eval.h
+enc/us_ascii.$(OBJEXT): internal/intern/file.h
+enc/us_ascii.$(OBJEXT): internal/intern/gc.h
+enc/us_ascii.$(OBJEXT): internal/intern/hash.h
+enc/us_ascii.$(OBJEXT): internal/intern/io.h
+enc/us_ascii.$(OBJEXT): internal/intern/load.h
+enc/us_ascii.$(OBJEXT): internal/intern/marshal.h
+enc/us_ascii.$(OBJEXT): internal/intern/numeric.h
+enc/us_ascii.$(OBJEXT): internal/intern/object.h
+enc/us_ascii.$(OBJEXT): internal/intern/parse.h
+enc/us_ascii.$(OBJEXT): internal/intern/proc.h
+enc/us_ascii.$(OBJEXT): internal/intern/process.h
+enc/us_ascii.$(OBJEXT): internal/intern/random.h
+enc/us_ascii.$(OBJEXT): internal/intern/range.h
+enc/us_ascii.$(OBJEXT): internal/intern/rational.h
+enc/us_ascii.$(OBJEXT): internal/intern/re.h
+enc/us_ascii.$(OBJEXT): internal/intern/ruby.h
+enc/us_ascii.$(OBJEXT): internal/intern/select.h
+enc/us_ascii.$(OBJEXT): internal/intern/select/largesize.h
+enc/us_ascii.$(OBJEXT): internal/intern/signal.h
+enc/us_ascii.$(OBJEXT): internal/intern/sprintf.h
+enc/us_ascii.$(OBJEXT): internal/intern/string.h
+enc/us_ascii.$(OBJEXT): internal/intern/struct.h
+enc/us_ascii.$(OBJEXT): internal/intern/thread.h
+enc/us_ascii.$(OBJEXT): internal/intern/time.h
+enc/us_ascii.$(OBJEXT): internal/intern/variable.h
+enc/us_ascii.$(OBJEXT): internal/intern/vm.h
+enc/us_ascii.$(OBJEXT): internal/interpreter.h
+enc/us_ascii.$(OBJEXT): internal/iterator.h
+enc/us_ascii.$(OBJEXT): internal/memory.h
+enc/us_ascii.$(OBJEXT): internal/method.h
+enc/us_ascii.$(OBJEXT): internal/module.h
+enc/us_ascii.$(OBJEXT): internal/newobj.h
+enc/us_ascii.$(OBJEXT): internal/rgengc.h
+enc/us_ascii.$(OBJEXT): internal/scan_args.h
+enc/us_ascii.$(OBJEXT): internal/special_consts.h
+enc/us_ascii.$(OBJEXT): internal/static_assert.h
+enc/us_ascii.$(OBJEXT): internal/stdalign.h
+enc/us_ascii.$(OBJEXT): internal/stdbool.h
+enc/us_ascii.$(OBJEXT): internal/symbol.h
+enc/us_ascii.$(OBJEXT): internal/token_paste.h
+enc/us_ascii.$(OBJEXT): internal/value.h
+enc/us_ascii.$(OBJEXT): internal/value_type.h
+enc/us_ascii.$(OBJEXT): internal/variable.h
+enc/us_ascii.$(OBJEXT): internal/warning_push.h
+enc/us_ascii.$(OBJEXT): internal/xmalloc.h
+enc/us_ascii.$(OBJEXT): assert.h
+enc/us_ascii.$(OBJEXT): backward/2/assume.h
+enc/us_ascii.$(OBJEXT): backward/2/attributes.h
+enc/us_ascii.$(OBJEXT): backward/2/bool.h
+enc/us_ascii.$(OBJEXT): backward/2/gcc_version_since.h
+enc/us_ascii.$(OBJEXT): backward/2/inttypes.h
+enc/us_ascii.$(OBJEXT): backward/2/limits.h
+enc/us_ascii.$(OBJEXT): backward/2/long_long.h
+enc/us_ascii.$(OBJEXT): backward/2/stdalign.h
+enc/us_ascii.$(OBJEXT): backward/2/stdarg.h
enc/us_ascii.$(OBJEXT): config.h
enc/us_ascii.$(OBJEXT): defines.h
enc/us_ascii.$(OBJEXT): enc/us_ascii.c
+enc/us_ascii.$(OBJEXT): encoding.h
+enc/us_ascii.$(OBJEXT): intern.h
enc/us_ascii.$(OBJEXT): missing.h
enc/us_ascii.$(OBJEXT): onigmo.h
enc/us_ascii.$(OBJEXT): oniguruma.h
+enc/us_ascii.$(OBJEXT): st.h
+enc/us_ascii.$(OBJEXT): subst.h
enc/utf_16be.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/utf_16be.$(OBJEXT): internal/assume.h
+enc/utf_16be.$(OBJEXT): internal/attr/alloc_size.h
+enc/utf_16be.$(OBJEXT): internal/attr/cold.h
+enc/utf_16be.$(OBJEXT): internal/attr/const.h
+enc/utf_16be.$(OBJEXT): internal/attr/deprecated.h
+enc/utf_16be.$(OBJEXT): internal/attr/error.h
+enc/utf_16be.$(OBJEXT): internal/attr/forceinline.h
+enc/utf_16be.$(OBJEXT): internal/attr/format.h
+enc/utf_16be.$(OBJEXT): internal/attr/maybe_unused.h
+enc/utf_16be.$(OBJEXT): internal/attr/nodiscard.h
+enc/utf_16be.$(OBJEXT): internal/attr/noexcept.h
+enc/utf_16be.$(OBJEXT): internal/attr/noinline.h
+enc/utf_16be.$(OBJEXT): internal/attr/nonnull.h
+enc/utf_16be.$(OBJEXT): internal/attr/noreturn.h
+enc/utf_16be.$(OBJEXT): internal/attr/pure.h
+enc/utf_16be.$(OBJEXT): internal/attr/restrict.h
+enc/utf_16be.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/utf_16be.$(OBJEXT): internal/attr/warning.h
+enc/utf_16be.$(OBJEXT): internal/cast.h
+enc/utf_16be.$(OBJEXT): internal/compiler_is.h
+enc/utf_16be.$(OBJEXT): internal/compiler_is/apple.h
+enc/utf_16be.$(OBJEXT): internal/compiler_is/clang.h
+enc/utf_16be.$(OBJEXT): internal/compiler_is/gcc.h
+enc/utf_16be.$(OBJEXT): internal/compiler_is/intel.h
+enc/utf_16be.$(OBJEXT): internal/compiler_is/msvc.h
+enc/utf_16be.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/utf_16be.$(OBJEXT): internal/compiler_since.h
+enc/utf_16be.$(OBJEXT): internal/config.h
+enc/utf_16be.$(OBJEXT): internal/dllexport.h
+enc/utf_16be.$(OBJEXT): internal/dosish.h
+enc/utf_16be.$(OBJEXT): internal/has/attribute.h
+enc/utf_16be.$(OBJEXT): internal/has/builtin.h
+enc/utf_16be.$(OBJEXT): internal/has/c_attribute.h
+enc/utf_16be.$(OBJEXT): internal/has/cpp_attribute.h
+enc/utf_16be.$(OBJEXT): internal/has/declspec_attribute.h
+enc/utf_16be.$(OBJEXT): internal/has/extension.h
+enc/utf_16be.$(OBJEXT): internal/has/feature.h
+enc/utf_16be.$(OBJEXT): internal/has/warning.h
+enc/utf_16be.$(OBJEXT): internal/stdalign.h
+enc/utf_16be.$(OBJEXT): internal/stdbool.h
+enc/utf_16be.$(OBJEXT): internal/token_paste.h
+enc/utf_16be.$(OBJEXT): internal/warning_push.h
+enc/utf_16be.$(OBJEXT): internal/xmalloc.h
+enc/utf_16be.$(OBJEXT): assert.h
+enc/utf_16be.$(OBJEXT): backward/2/assume.h
+enc/utf_16be.$(OBJEXT): backward/2/attributes.h
+enc/utf_16be.$(OBJEXT): backward/2/bool.h
+enc/utf_16be.$(OBJEXT): backward/2/gcc_version_since.h
+enc/utf_16be.$(OBJEXT): backward/2/long_long.h
+enc/utf_16be.$(OBJEXT): backward/2/stdalign.h
+enc/utf_16be.$(OBJEXT): backward/2/stdarg.h
enc/utf_16be.$(OBJEXT): config.h
enc/utf_16be.$(OBJEXT): defines.h
enc/utf_16be.$(OBJEXT): enc/iso_8859.h
enc/utf_16be.$(OBJEXT): enc/utf_16be.c
enc/utf_16be.$(OBJEXT): missing.h
enc/utf_16be.$(OBJEXT): onigmo.h
-enc/utf_16be.$(OBJEXT): oniguruma.h
enc/utf_16le.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/utf_16le.$(OBJEXT): internal/assume.h
+enc/utf_16le.$(OBJEXT): internal/attr/alloc_size.h
+enc/utf_16le.$(OBJEXT): internal/attr/cold.h
+enc/utf_16le.$(OBJEXT): internal/attr/const.h
+enc/utf_16le.$(OBJEXT): internal/attr/deprecated.h
+enc/utf_16le.$(OBJEXT): internal/attr/error.h
+enc/utf_16le.$(OBJEXT): internal/attr/forceinline.h
+enc/utf_16le.$(OBJEXT): internal/attr/format.h
+enc/utf_16le.$(OBJEXT): internal/attr/maybe_unused.h
+enc/utf_16le.$(OBJEXT): internal/attr/nodiscard.h
+enc/utf_16le.$(OBJEXT): internal/attr/noexcept.h
+enc/utf_16le.$(OBJEXT): internal/attr/noinline.h
+enc/utf_16le.$(OBJEXT): internal/attr/nonnull.h
+enc/utf_16le.$(OBJEXT): internal/attr/noreturn.h
+enc/utf_16le.$(OBJEXT): internal/attr/pure.h
+enc/utf_16le.$(OBJEXT): internal/attr/restrict.h
+enc/utf_16le.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/utf_16le.$(OBJEXT): internal/attr/warning.h
+enc/utf_16le.$(OBJEXT): internal/cast.h
+enc/utf_16le.$(OBJEXT): internal/compiler_is.h
+enc/utf_16le.$(OBJEXT): internal/compiler_is/apple.h
+enc/utf_16le.$(OBJEXT): internal/compiler_is/clang.h
+enc/utf_16le.$(OBJEXT): internal/compiler_is/gcc.h
+enc/utf_16le.$(OBJEXT): internal/compiler_is/intel.h
+enc/utf_16le.$(OBJEXT): internal/compiler_is/msvc.h
+enc/utf_16le.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/utf_16le.$(OBJEXT): internal/compiler_since.h
+enc/utf_16le.$(OBJEXT): internal/config.h
+enc/utf_16le.$(OBJEXT): internal/dllexport.h
+enc/utf_16le.$(OBJEXT): internal/dosish.h
+enc/utf_16le.$(OBJEXT): internal/has/attribute.h
+enc/utf_16le.$(OBJEXT): internal/has/builtin.h
+enc/utf_16le.$(OBJEXT): internal/has/c_attribute.h
+enc/utf_16le.$(OBJEXT): internal/has/cpp_attribute.h
+enc/utf_16le.$(OBJEXT): internal/has/declspec_attribute.h
+enc/utf_16le.$(OBJEXT): internal/has/extension.h
+enc/utf_16le.$(OBJEXT): internal/has/feature.h
+enc/utf_16le.$(OBJEXT): internal/has/warning.h
+enc/utf_16le.$(OBJEXT): internal/stdalign.h
+enc/utf_16le.$(OBJEXT): internal/stdbool.h
+enc/utf_16le.$(OBJEXT): internal/token_paste.h
+enc/utf_16le.$(OBJEXT): internal/warning_push.h
+enc/utf_16le.$(OBJEXT): internal/xmalloc.h
+enc/utf_16le.$(OBJEXT): assert.h
+enc/utf_16le.$(OBJEXT): backward/2/assume.h
+enc/utf_16le.$(OBJEXT): backward/2/attributes.h
+enc/utf_16le.$(OBJEXT): backward/2/bool.h
+enc/utf_16le.$(OBJEXT): backward/2/gcc_version_since.h
+enc/utf_16le.$(OBJEXT): backward/2/long_long.h
+enc/utf_16le.$(OBJEXT): backward/2/stdalign.h
+enc/utf_16le.$(OBJEXT): backward/2/stdarg.h
enc/utf_16le.$(OBJEXT): config.h
enc/utf_16le.$(OBJEXT): defines.h
enc/utf_16le.$(OBJEXT): enc/iso_8859.h
enc/utf_16le.$(OBJEXT): enc/utf_16le.c
enc/utf_16le.$(OBJEXT): missing.h
enc/utf_16le.$(OBJEXT): onigmo.h
-enc/utf_16le.$(OBJEXT): oniguruma.h
enc/utf_32be.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/utf_32be.$(OBJEXT): internal/assume.h
+enc/utf_32be.$(OBJEXT): internal/attr/alloc_size.h
+enc/utf_32be.$(OBJEXT): internal/attr/cold.h
+enc/utf_32be.$(OBJEXT): internal/attr/const.h
+enc/utf_32be.$(OBJEXT): internal/attr/deprecated.h
+enc/utf_32be.$(OBJEXT): internal/attr/error.h
+enc/utf_32be.$(OBJEXT): internal/attr/forceinline.h
+enc/utf_32be.$(OBJEXT): internal/attr/format.h
+enc/utf_32be.$(OBJEXT): internal/attr/maybe_unused.h
+enc/utf_32be.$(OBJEXT): internal/attr/nodiscard.h
+enc/utf_32be.$(OBJEXT): internal/attr/noexcept.h
+enc/utf_32be.$(OBJEXT): internal/attr/noinline.h
+enc/utf_32be.$(OBJEXT): internal/attr/nonnull.h
+enc/utf_32be.$(OBJEXT): internal/attr/noreturn.h
+enc/utf_32be.$(OBJEXT): internal/attr/pure.h
+enc/utf_32be.$(OBJEXT): internal/attr/restrict.h
+enc/utf_32be.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/utf_32be.$(OBJEXT): internal/attr/warning.h
+enc/utf_32be.$(OBJEXT): internal/cast.h
+enc/utf_32be.$(OBJEXT): internal/compiler_is.h
+enc/utf_32be.$(OBJEXT): internal/compiler_is/apple.h
+enc/utf_32be.$(OBJEXT): internal/compiler_is/clang.h
+enc/utf_32be.$(OBJEXT): internal/compiler_is/gcc.h
+enc/utf_32be.$(OBJEXT): internal/compiler_is/intel.h
+enc/utf_32be.$(OBJEXT): internal/compiler_is/msvc.h
+enc/utf_32be.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/utf_32be.$(OBJEXT): internal/compiler_since.h
+enc/utf_32be.$(OBJEXT): internal/config.h
+enc/utf_32be.$(OBJEXT): internal/dllexport.h
+enc/utf_32be.$(OBJEXT): internal/dosish.h
+enc/utf_32be.$(OBJEXT): internal/has/attribute.h
+enc/utf_32be.$(OBJEXT): internal/has/builtin.h
+enc/utf_32be.$(OBJEXT): internal/has/c_attribute.h
+enc/utf_32be.$(OBJEXT): internal/has/cpp_attribute.h
+enc/utf_32be.$(OBJEXT): internal/has/declspec_attribute.h
+enc/utf_32be.$(OBJEXT): internal/has/extension.h
+enc/utf_32be.$(OBJEXT): internal/has/feature.h
+enc/utf_32be.$(OBJEXT): internal/has/warning.h
+enc/utf_32be.$(OBJEXT): internal/stdalign.h
+enc/utf_32be.$(OBJEXT): internal/stdbool.h
+enc/utf_32be.$(OBJEXT): internal/token_paste.h
+enc/utf_32be.$(OBJEXT): internal/warning_push.h
+enc/utf_32be.$(OBJEXT): internal/xmalloc.h
+enc/utf_32be.$(OBJEXT): assert.h
+enc/utf_32be.$(OBJEXT): backward/2/assume.h
+enc/utf_32be.$(OBJEXT): backward/2/attributes.h
+enc/utf_32be.$(OBJEXT): backward/2/bool.h
+enc/utf_32be.$(OBJEXT): backward/2/gcc_version_since.h
+enc/utf_32be.$(OBJEXT): backward/2/long_long.h
+enc/utf_32be.$(OBJEXT): backward/2/stdalign.h
+enc/utf_32be.$(OBJEXT): backward/2/stdarg.h
enc/utf_32be.$(OBJEXT): config.h
enc/utf_32be.$(OBJEXT): defines.h
enc/utf_32be.$(OBJEXT): enc/iso_8859.h
enc/utf_32be.$(OBJEXT): enc/utf_32be.c
enc/utf_32be.$(OBJEXT): missing.h
enc/utf_32be.$(OBJEXT): onigmo.h
-enc/utf_32be.$(OBJEXT): oniguruma.h
enc/utf_32le.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/utf_32le.$(OBJEXT): internal/assume.h
+enc/utf_32le.$(OBJEXT): internal/attr/alloc_size.h
+enc/utf_32le.$(OBJEXT): internal/attr/cold.h
+enc/utf_32le.$(OBJEXT): internal/attr/const.h
+enc/utf_32le.$(OBJEXT): internal/attr/deprecated.h
+enc/utf_32le.$(OBJEXT): internal/attr/error.h
+enc/utf_32le.$(OBJEXT): internal/attr/forceinline.h
+enc/utf_32le.$(OBJEXT): internal/attr/format.h
+enc/utf_32le.$(OBJEXT): internal/attr/maybe_unused.h
+enc/utf_32le.$(OBJEXT): internal/attr/nodiscard.h
+enc/utf_32le.$(OBJEXT): internal/attr/noexcept.h
+enc/utf_32le.$(OBJEXT): internal/attr/noinline.h
+enc/utf_32le.$(OBJEXT): internal/attr/nonnull.h
+enc/utf_32le.$(OBJEXT): internal/attr/noreturn.h
+enc/utf_32le.$(OBJEXT): internal/attr/pure.h
+enc/utf_32le.$(OBJEXT): internal/attr/restrict.h
+enc/utf_32le.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/utf_32le.$(OBJEXT): internal/attr/warning.h
+enc/utf_32le.$(OBJEXT): internal/cast.h
+enc/utf_32le.$(OBJEXT): internal/compiler_is.h
+enc/utf_32le.$(OBJEXT): internal/compiler_is/apple.h
+enc/utf_32le.$(OBJEXT): internal/compiler_is/clang.h
+enc/utf_32le.$(OBJEXT): internal/compiler_is/gcc.h
+enc/utf_32le.$(OBJEXT): internal/compiler_is/intel.h
+enc/utf_32le.$(OBJEXT): internal/compiler_is/msvc.h
+enc/utf_32le.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/utf_32le.$(OBJEXT): internal/compiler_since.h
+enc/utf_32le.$(OBJEXT): internal/config.h
+enc/utf_32le.$(OBJEXT): internal/dllexport.h
+enc/utf_32le.$(OBJEXT): internal/dosish.h
+enc/utf_32le.$(OBJEXT): internal/has/attribute.h
+enc/utf_32le.$(OBJEXT): internal/has/builtin.h
+enc/utf_32le.$(OBJEXT): internal/has/c_attribute.h
+enc/utf_32le.$(OBJEXT): internal/has/cpp_attribute.h
+enc/utf_32le.$(OBJEXT): internal/has/declspec_attribute.h
+enc/utf_32le.$(OBJEXT): internal/has/extension.h
+enc/utf_32le.$(OBJEXT): internal/has/feature.h
+enc/utf_32le.$(OBJEXT): internal/has/warning.h
+enc/utf_32le.$(OBJEXT): internal/stdalign.h
+enc/utf_32le.$(OBJEXT): internal/stdbool.h
+enc/utf_32le.$(OBJEXT): internal/token_paste.h
+enc/utf_32le.$(OBJEXT): internal/warning_push.h
+enc/utf_32le.$(OBJEXT): internal/xmalloc.h
+enc/utf_32le.$(OBJEXT): assert.h
+enc/utf_32le.$(OBJEXT): backward/2/assume.h
+enc/utf_32le.$(OBJEXT): backward/2/attributes.h
+enc/utf_32le.$(OBJEXT): backward/2/bool.h
+enc/utf_32le.$(OBJEXT): backward/2/gcc_version_since.h
+enc/utf_32le.$(OBJEXT): backward/2/long_long.h
+enc/utf_32le.$(OBJEXT): backward/2/stdalign.h
+enc/utf_32le.$(OBJEXT): backward/2/stdarg.h
enc/utf_32le.$(OBJEXT): config.h
enc/utf_32le.$(OBJEXT): defines.h
enc/utf_32le.$(OBJEXT): enc/iso_8859.h
enc/utf_32le.$(OBJEXT): enc/utf_32le.c
enc/utf_32le.$(OBJEXT): missing.h
enc/utf_32le.$(OBJEXT): onigmo.h
-enc/utf_32le.$(OBJEXT): oniguruma.h
+enc/utf_8.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/utf_8.$(OBJEXT): $(top_srcdir)/encindex.h
enc/utf_8.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/utf_8.$(OBJEXT): internal/anyargs.h
+enc/utf_8.$(OBJEXT): internal/arithmetic.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/char.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/double.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/fixnum.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/gid_t.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/int.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/intptr_t.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/long.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/long_long.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/mode_t.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/off_t.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/pid_t.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/short.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/size_t.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/st_data_t.h
+enc/utf_8.$(OBJEXT): internal/arithmetic/uid_t.h
+enc/utf_8.$(OBJEXT): internal/assume.h
+enc/utf_8.$(OBJEXT): internal/attr/alloc_size.h
+enc/utf_8.$(OBJEXT): internal/attr/artificial.h
+enc/utf_8.$(OBJEXT): internal/attr/cold.h
+enc/utf_8.$(OBJEXT): internal/attr/const.h
+enc/utf_8.$(OBJEXT): internal/attr/constexpr.h
+enc/utf_8.$(OBJEXT): internal/attr/deprecated.h
+enc/utf_8.$(OBJEXT): internal/attr/diagnose_if.h
+enc/utf_8.$(OBJEXT): internal/attr/enum_extensibility.h
+enc/utf_8.$(OBJEXT): internal/attr/error.h
+enc/utf_8.$(OBJEXT): internal/attr/flag_enum.h
+enc/utf_8.$(OBJEXT): internal/attr/forceinline.h
+enc/utf_8.$(OBJEXT): internal/attr/format.h
+enc/utf_8.$(OBJEXT): internal/attr/maybe_unused.h
+enc/utf_8.$(OBJEXT): internal/attr/noalias.h
+enc/utf_8.$(OBJEXT): internal/attr/nodiscard.h
+enc/utf_8.$(OBJEXT): internal/attr/noexcept.h
+enc/utf_8.$(OBJEXT): internal/attr/noinline.h
+enc/utf_8.$(OBJEXT): internal/attr/nonnull.h
+enc/utf_8.$(OBJEXT): internal/attr/noreturn.h
+enc/utf_8.$(OBJEXT): internal/attr/pure.h
+enc/utf_8.$(OBJEXT): internal/attr/restrict.h
+enc/utf_8.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/utf_8.$(OBJEXT): internal/attr/warning.h
+enc/utf_8.$(OBJEXT): internal/attr/weakref.h
+enc/utf_8.$(OBJEXT): internal/cast.h
+enc/utf_8.$(OBJEXT): internal/compiler_is.h
+enc/utf_8.$(OBJEXT): internal/compiler_is/apple.h
+enc/utf_8.$(OBJEXT): internal/compiler_is/clang.h
+enc/utf_8.$(OBJEXT): internal/compiler_is/gcc.h
+enc/utf_8.$(OBJEXT): internal/compiler_is/intel.h
+enc/utf_8.$(OBJEXT): internal/compiler_is/msvc.h
+enc/utf_8.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/utf_8.$(OBJEXT): internal/compiler_since.h
+enc/utf_8.$(OBJEXT): internal/config.h
+enc/utf_8.$(OBJEXT): internal/constant_p.h
+enc/utf_8.$(OBJEXT): internal/core.h
+enc/utf_8.$(OBJEXT): internal/core/rarray.h
+enc/utf_8.$(OBJEXT): internal/core/rbasic.h
+enc/utf_8.$(OBJEXT): internal/core/rbignum.h
+enc/utf_8.$(OBJEXT): internal/core/rclass.h
+enc/utf_8.$(OBJEXT): internal/core/rdata.h
+enc/utf_8.$(OBJEXT): internal/core/rfile.h
+enc/utf_8.$(OBJEXT): internal/core/rhash.h
+enc/utf_8.$(OBJEXT): internal/core/robject.h
+enc/utf_8.$(OBJEXT): internal/core/rregexp.h
+enc/utf_8.$(OBJEXT): internal/core/rstring.h
+enc/utf_8.$(OBJEXT): internal/core/rstruct.h
+enc/utf_8.$(OBJEXT): internal/core/rtypeddata.h
+enc/utf_8.$(OBJEXT): internal/ctype.h
+enc/utf_8.$(OBJEXT): internal/dllexport.h
+enc/utf_8.$(OBJEXT): internal/dosish.h
+enc/utf_8.$(OBJEXT): internal/error.h
+enc/utf_8.$(OBJEXT): internal/eval.h
+enc/utf_8.$(OBJEXT): internal/event.h
+enc/utf_8.$(OBJEXT): internal/fl_type.h
+enc/utf_8.$(OBJEXT): internal/gc.h
+enc/utf_8.$(OBJEXT): internal/glob.h
+enc/utf_8.$(OBJEXT): internal/globals.h
+enc/utf_8.$(OBJEXT): internal/has/attribute.h
+enc/utf_8.$(OBJEXT): internal/has/builtin.h
+enc/utf_8.$(OBJEXT): internal/has/c_attribute.h
+enc/utf_8.$(OBJEXT): internal/has/cpp_attribute.h
+enc/utf_8.$(OBJEXT): internal/has/declspec_attribute.h
+enc/utf_8.$(OBJEXT): internal/has/extension.h
+enc/utf_8.$(OBJEXT): internal/has/feature.h
+enc/utf_8.$(OBJEXT): internal/has/warning.h
+enc/utf_8.$(OBJEXT): internal/intern/array.h
+enc/utf_8.$(OBJEXT): internal/intern/bignum.h
+enc/utf_8.$(OBJEXT): internal/intern/class.h
+enc/utf_8.$(OBJEXT): internal/intern/compar.h
+enc/utf_8.$(OBJEXT): internal/intern/complex.h
+enc/utf_8.$(OBJEXT): internal/intern/cont.h
+enc/utf_8.$(OBJEXT): internal/intern/dir.h
+enc/utf_8.$(OBJEXT): internal/intern/enum.h
+enc/utf_8.$(OBJEXT): internal/intern/enumerator.h
+enc/utf_8.$(OBJEXT): internal/intern/error.h
+enc/utf_8.$(OBJEXT): internal/intern/eval.h
+enc/utf_8.$(OBJEXT): internal/intern/file.h
+enc/utf_8.$(OBJEXT): internal/intern/gc.h
+enc/utf_8.$(OBJEXT): internal/intern/hash.h
+enc/utf_8.$(OBJEXT): internal/intern/io.h
+enc/utf_8.$(OBJEXT): internal/intern/load.h
+enc/utf_8.$(OBJEXT): internal/intern/marshal.h
+enc/utf_8.$(OBJEXT): internal/intern/numeric.h
+enc/utf_8.$(OBJEXT): internal/intern/object.h
+enc/utf_8.$(OBJEXT): internal/intern/parse.h
+enc/utf_8.$(OBJEXT): internal/intern/proc.h
+enc/utf_8.$(OBJEXT): internal/intern/process.h
+enc/utf_8.$(OBJEXT): internal/intern/random.h
+enc/utf_8.$(OBJEXT): internal/intern/range.h
+enc/utf_8.$(OBJEXT): internal/intern/rational.h
+enc/utf_8.$(OBJEXT): internal/intern/re.h
+enc/utf_8.$(OBJEXT): internal/intern/ruby.h
+enc/utf_8.$(OBJEXT): internal/intern/select.h
+enc/utf_8.$(OBJEXT): internal/intern/select/largesize.h
+enc/utf_8.$(OBJEXT): internal/intern/signal.h
+enc/utf_8.$(OBJEXT): internal/intern/sprintf.h
+enc/utf_8.$(OBJEXT): internal/intern/string.h
+enc/utf_8.$(OBJEXT): internal/intern/struct.h
+enc/utf_8.$(OBJEXT): internal/intern/thread.h
+enc/utf_8.$(OBJEXT): internal/intern/time.h
+enc/utf_8.$(OBJEXT): internal/intern/variable.h
+enc/utf_8.$(OBJEXT): internal/intern/vm.h
+enc/utf_8.$(OBJEXT): internal/interpreter.h
+enc/utf_8.$(OBJEXT): internal/iterator.h
+enc/utf_8.$(OBJEXT): internal/memory.h
+enc/utf_8.$(OBJEXT): internal/method.h
+enc/utf_8.$(OBJEXT): internal/module.h
+enc/utf_8.$(OBJEXT): internal/newobj.h
+enc/utf_8.$(OBJEXT): internal/rgengc.h
+enc/utf_8.$(OBJEXT): internal/scan_args.h
+enc/utf_8.$(OBJEXT): internal/special_consts.h
+enc/utf_8.$(OBJEXT): internal/static_assert.h
+enc/utf_8.$(OBJEXT): internal/stdalign.h
+enc/utf_8.$(OBJEXT): internal/stdbool.h
+enc/utf_8.$(OBJEXT): internal/symbol.h
+enc/utf_8.$(OBJEXT): internal/token_paste.h
+enc/utf_8.$(OBJEXT): internal/value.h
+enc/utf_8.$(OBJEXT): internal/value_type.h
+enc/utf_8.$(OBJEXT): internal/variable.h
+enc/utf_8.$(OBJEXT): internal/warning_push.h
+enc/utf_8.$(OBJEXT): internal/xmalloc.h
+enc/utf_8.$(OBJEXT): assert.h
+enc/utf_8.$(OBJEXT): backward/2/assume.h
+enc/utf_8.$(OBJEXT): backward/2/attributes.h
+enc/utf_8.$(OBJEXT): backward/2/bool.h
+enc/utf_8.$(OBJEXT): backward/2/gcc_version_since.h
+enc/utf_8.$(OBJEXT): backward/2/inttypes.h
+enc/utf_8.$(OBJEXT): backward/2/limits.h
+enc/utf_8.$(OBJEXT): backward/2/long_long.h
+enc/utf_8.$(OBJEXT): backward/2/stdalign.h
+enc/utf_8.$(OBJEXT): backward/2/stdarg.h
enc/utf_8.$(OBJEXT): config.h
enc/utf_8.$(OBJEXT): defines.h
enc/utf_8.$(OBJEXT): enc/utf_8.c
+enc/utf_8.$(OBJEXT): encoding.h
+enc/utf_8.$(OBJEXT): intern.h
enc/utf_8.$(OBJEXT): missing.h
enc/utf_8.$(OBJEXT): onigmo.h
enc/utf_8.$(OBJEXT): oniguruma.h
+enc/utf_8.$(OBJEXT): st.h
+enc/utf_8.$(OBJEXT): subst.h
enc/windows_1250.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/windows_1250.$(OBJEXT): internal/assume.h
+enc/windows_1250.$(OBJEXT): internal/attr/alloc_size.h
+enc/windows_1250.$(OBJEXT): internal/attr/cold.h
+enc/windows_1250.$(OBJEXT): internal/attr/const.h
+enc/windows_1250.$(OBJEXT): internal/attr/deprecated.h
+enc/windows_1250.$(OBJEXT): internal/attr/error.h
+enc/windows_1250.$(OBJEXT): internal/attr/forceinline.h
+enc/windows_1250.$(OBJEXT): internal/attr/format.h
+enc/windows_1250.$(OBJEXT): internal/attr/maybe_unused.h
+enc/windows_1250.$(OBJEXT): internal/attr/nodiscard.h
+enc/windows_1250.$(OBJEXT): internal/attr/noexcept.h
+enc/windows_1250.$(OBJEXT): internal/attr/noinline.h
+enc/windows_1250.$(OBJEXT): internal/attr/nonnull.h
+enc/windows_1250.$(OBJEXT): internal/attr/noreturn.h
+enc/windows_1250.$(OBJEXT): internal/attr/pure.h
+enc/windows_1250.$(OBJEXT): internal/attr/restrict.h
+enc/windows_1250.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/windows_1250.$(OBJEXT): internal/attr/warning.h
+enc/windows_1250.$(OBJEXT): internal/cast.h
+enc/windows_1250.$(OBJEXT): internal/compiler_is.h
+enc/windows_1250.$(OBJEXT): internal/compiler_is/apple.h
+enc/windows_1250.$(OBJEXT): internal/compiler_is/clang.h
+enc/windows_1250.$(OBJEXT): internal/compiler_is/gcc.h
+enc/windows_1250.$(OBJEXT): internal/compiler_is/intel.h
+enc/windows_1250.$(OBJEXT): internal/compiler_is/msvc.h
+enc/windows_1250.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/windows_1250.$(OBJEXT): internal/compiler_since.h
+enc/windows_1250.$(OBJEXT): internal/config.h
+enc/windows_1250.$(OBJEXT): internal/dllexport.h
+enc/windows_1250.$(OBJEXT): internal/dosish.h
+enc/windows_1250.$(OBJEXT): internal/has/attribute.h
+enc/windows_1250.$(OBJEXT): internal/has/builtin.h
+enc/windows_1250.$(OBJEXT): internal/has/c_attribute.h
+enc/windows_1250.$(OBJEXT): internal/has/cpp_attribute.h
+enc/windows_1250.$(OBJEXT): internal/has/declspec_attribute.h
+enc/windows_1250.$(OBJEXT): internal/has/extension.h
+enc/windows_1250.$(OBJEXT): internal/has/feature.h
+enc/windows_1250.$(OBJEXT): internal/has/warning.h
+enc/windows_1250.$(OBJEXT): internal/stdalign.h
+enc/windows_1250.$(OBJEXT): internal/stdbool.h
+enc/windows_1250.$(OBJEXT): internal/token_paste.h
+enc/windows_1250.$(OBJEXT): internal/warning_push.h
+enc/windows_1250.$(OBJEXT): internal/xmalloc.h
+enc/windows_1250.$(OBJEXT): assert.h
+enc/windows_1250.$(OBJEXT): backward/2/assume.h
+enc/windows_1250.$(OBJEXT): backward/2/attributes.h
+enc/windows_1250.$(OBJEXT): backward/2/bool.h
+enc/windows_1250.$(OBJEXT): backward/2/gcc_version_since.h
+enc/windows_1250.$(OBJEXT): backward/2/long_long.h
+enc/windows_1250.$(OBJEXT): backward/2/stdalign.h
+enc/windows_1250.$(OBJEXT): backward/2/stdarg.h
enc/windows_1250.$(OBJEXT): config.h
enc/windows_1250.$(OBJEXT): defines.h
enc/windows_1250.$(OBJEXT): enc/iso_8859.h
enc/windows_1250.$(OBJEXT): enc/windows_1250.c
enc/windows_1250.$(OBJEXT): missing.h
enc/windows_1250.$(OBJEXT): onigmo.h
-enc/windows_1250.$(OBJEXT): oniguruma.h
enc/windows_1251.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/windows_1251.$(OBJEXT): internal/assume.h
+enc/windows_1251.$(OBJEXT): internal/attr/alloc_size.h
+enc/windows_1251.$(OBJEXT): internal/attr/cold.h
+enc/windows_1251.$(OBJEXT): internal/attr/const.h
+enc/windows_1251.$(OBJEXT): internal/attr/deprecated.h
+enc/windows_1251.$(OBJEXT): internal/attr/error.h
+enc/windows_1251.$(OBJEXT): internal/attr/forceinline.h
+enc/windows_1251.$(OBJEXT): internal/attr/format.h
+enc/windows_1251.$(OBJEXT): internal/attr/maybe_unused.h
+enc/windows_1251.$(OBJEXT): internal/attr/nodiscard.h
+enc/windows_1251.$(OBJEXT): internal/attr/noexcept.h
+enc/windows_1251.$(OBJEXT): internal/attr/noinline.h
+enc/windows_1251.$(OBJEXT): internal/attr/nonnull.h
+enc/windows_1251.$(OBJEXT): internal/attr/noreturn.h
+enc/windows_1251.$(OBJEXT): internal/attr/pure.h
+enc/windows_1251.$(OBJEXT): internal/attr/restrict.h
+enc/windows_1251.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/windows_1251.$(OBJEXT): internal/attr/warning.h
+enc/windows_1251.$(OBJEXT): internal/cast.h
+enc/windows_1251.$(OBJEXT): internal/compiler_is.h
+enc/windows_1251.$(OBJEXT): internal/compiler_is/apple.h
+enc/windows_1251.$(OBJEXT): internal/compiler_is/clang.h
+enc/windows_1251.$(OBJEXT): internal/compiler_is/gcc.h
+enc/windows_1251.$(OBJEXT): internal/compiler_is/intel.h
+enc/windows_1251.$(OBJEXT): internal/compiler_is/msvc.h
+enc/windows_1251.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/windows_1251.$(OBJEXT): internal/compiler_since.h
+enc/windows_1251.$(OBJEXT): internal/config.h
+enc/windows_1251.$(OBJEXT): internal/dllexport.h
+enc/windows_1251.$(OBJEXT): internal/dosish.h
+enc/windows_1251.$(OBJEXT): internal/has/attribute.h
+enc/windows_1251.$(OBJEXT): internal/has/builtin.h
+enc/windows_1251.$(OBJEXT): internal/has/c_attribute.h
+enc/windows_1251.$(OBJEXT): internal/has/cpp_attribute.h
+enc/windows_1251.$(OBJEXT): internal/has/declspec_attribute.h
+enc/windows_1251.$(OBJEXT): internal/has/extension.h
+enc/windows_1251.$(OBJEXT): internal/has/feature.h
+enc/windows_1251.$(OBJEXT): internal/has/warning.h
+enc/windows_1251.$(OBJEXT): internal/stdalign.h
+enc/windows_1251.$(OBJEXT): internal/stdbool.h
+enc/windows_1251.$(OBJEXT): internal/token_paste.h
+enc/windows_1251.$(OBJEXT): internal/warning_push.h
+enc/windows_1251.$(OBJEXT): internal/xmalloc.h
+enc/windows_1251.$(OBJEXT): assert.h
+enc/windows_1251.$(OBJEXT): backward/2/assume.h
+enc/windows_1251.$(OBJEXT): backward/2/attributes.h
+enc/windows_1251.$(OBJEXT): backward/2/bool.h
+enc/windows_1251.$(OBJEXT): backward/2/gcc_version_since.h
+enc/windows_1251.$(OBJEXT): backward/2/long_long.h
+enc/windows_1251.$(OBJEXT): backward/2/stdalign.h
+enc/windows_1251.$(OBJEXT): backward/2/stdarg.h
enc/windows_1251.$(OBJEXT): config.h
enc/windows_1251.$(OBJEXT): defines.h
enc/windows_1251.$(OBJEXT): enc/windows_1251.c
enc/windows_1251.$(OBJEXT): missing.h
enc/windows_1251.$(OBJEXT): onigmo.h
-enc/windows_1251.$(OBJEXT): oniguruma.h
enc/windows_1252.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/windows_1252.$(OBJEXT): internal/assume.h
+enc/windows_1252.$(OBJEXT): internal/attr/alloc_size.h
+enc/windows_1252.$(OBJEXT): internal/attr/cold.h
+enc/windows_1252.$(OBJEXT): internal/attr/const.h
+enc/windows_1252.$(OBJEXT): internal/attr/deprecated.h
+enc/windows_1252.$(OBJEXT): internal/attr/error.h
+enc/windows_1252.$(OBJEXT): internal/attr/forceinline.h
+enc/windows_1252.$(OBJEXT): internal/attr/format.h
+enc/windows_1252.$(OBJEXT): internal/attr/maybe_unused.h
+enc/windows_1252.$(OBJEXT): internal/attr/nodiscard.h
+enc/windows_1252.$(OBJEXT): internal/attr/noexcept.h
+enc/windows_1252.$(OBJEXT): internal/attr/noinline.h
+enc/windows_1252.$(OBJEXT): internal/attr/nonnull.h
+enc/windows_1252.$(OBJEXT): internal/attr/noreturn.h
+enc/windows_1252.$(OBJEXT): internal/attr/pure.h
+enc/windows_1252.$(OBJEXT): internal/attr/restrict.h
+enc/windows_1252.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/windows_1252.$(OBJEXT): internal/attr/warning.h
+enc/windows_1252.$(OBJEXT): internal/cast.h
+enc/windows_1252.$(OBJEXT): internal/compiler_is.h
+enc/windows_1252.$(OBJEXT): internal/compiler_is/apple.h
+enc/windows_1252.$(OBJEXT): internal/compiler_is/clang.h
+enc/windows_1252.$(OBJEXT): internal/compiler_is/gcc.h
+enc/windows_1252.$(OBJEXT): internal/compiler_is/intel.h
+enc/windows_1252.$(OBJEXT): internal/compiler_is/msvc.h
+enc/windows_1252.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/windows_1252.$(OBJEXT): internal/compiler_since.h
+enc/windows_1252.$(OBJEXT): internal/config.h
+enc/windows_1252.$(OBJEXT): internal/dllexport.h
+enc/windows_1252.$(OBJEXT): internal/dosish.h
+enc/windows_1252.$(OBJEXT): internal/has/attribute.h
+enc/windows_1252.$(OBJEXT): internal/has/builtin.h
+enc/windows_1252.$(OBJEXT): internal/has/c_attribute.h
+enc/windows_1252.$(OBJEXT): internal/has/cpp_attribute.h
+enc/windows_1252.$(OBJEXT): internal/has/declspec_attribute.h
+enc/windows_1252.$(OBJEXT): internal/has/extension.h
+enc/windows_1252.$(OBJEXT): internal/has/feature.h
+enc/windows_1252.$(OBJEXT): internal/has/warning.h
+enc/windows_1252.$(OBJEXT): internal/stdalign.h
+enc/windows_1252.$(OBJEXT): internal/stdbool.h
+enc/windows_1252.$(OBJEXT): internal/token_paste.h
+enc/windows_1252.$(OBJEXT): internal/warning_push.h
+enc/windows_1252.$(OBJEXT): internal/xmalloc.h
+enc/windows_1252.$(OBJEXT): assert.h
+enc/windows_1252.$(OBJEXT): backward/2/assume.h
+enc/windows_1252.$(OBJEXT): backward/2/attributes.h
+enc/windows_1252.$(OBJEXT): backward/2/bool.h
+enc/windows_1252.$(OBJEXT): backward/2/gcc_version_since.h
+enc/windows_1252.$(OBJEXT): backward/2/long_long.h
+enc/windows_1252.$(OBJEXT): backward/2/stdalign.h
+enc/windows_1252.$(OBJEXT): backward/2/stdarg.h
enc/windows_1252.$(OBJEXT): config.h
enc/windows_1252.$(OBJEXT): defines.h
enc/windows_1252.$(OBJEXT): enc/iso_8859.h
enc/windows_1252.$(OBJEXT): enc/windows_1252.c
enc/windows_1252.$(OBJEXT): missing.h
enc/windows_1252.$(OBJEXT): onigmo.h
-enc/windows_1252.$(OBJEXT): oniguruma.h
enc/windows_1253.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/windows_1253.$(OBJEXT): internal/assume.h
+enc/windows_1253.$(OBJEXT): internal/attr/alloc_size.h
+enc/windows_1253.$(OBJEXT): internal/attr/cold.h
+enc/windows_1253.$(OBJEXT): internal/attr/const.h
+enc/windows_1253.$(OBJEXT): internal/attr/deprecated.h
+enc/windows_1253.$(OBJEXT): internal/attr/error.h
+enc/windows_1253.$(OBJEXT): internal/attr/forceinline.h
+enc/windows_1253.$(OBJEXT): internal/attr/format.h
+enc/windows_1253.$(OBJEXT): internal/attr/maybe_unused.h
+enc/windows_1253.$(OBJEXT): internal/attr/nodiscard.h
+enc/windows_1253.$(OBJEXT): internal/attr/noexcept.h
+enc/windows_1253.$(OBJEXT): internal/attr/noinline.h
+enc/windows_1253.$(OBJEXT): internal/attr/nonnull.h
+enc/windows_1253.$(OBJEXT): internal/attr/noreturn.h
+enc/windows_1253.$(OBJEXT): internal/attr/pure.h
+enc/windows_1253.$(OBJEXT): internal/attr/restrict.h
+enc/windows_1253.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/windows_1253.$(OBJEXT): internal/attr/warning.h
+enc/windows_1253.$(OBJEXT): internal/cast.h
+enc/windows_1253.$(OBJEXT): internal/compiler_is.h
+enc/windows_1253.$(OBJEXT): internal/compiler_is/apple.h
+enc/windows_1253.$(OBJEXT): internal/compiler_is/clang.h
+enc/windows_1253.$(OBJEXT): internal/compiler_is/gcc.h
+enc/windows_1253.$(OBJEXT): internal/compiler_is/intel.h
+enc/windows_1253.$(OBJEXT): internal/compiler_is/msvc.h
+enc/windows_1253.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/windows_1253.$(OBJEXT): internal/compiler_since.h
+enc/windows_1253.$(OBJEXT): internal/config.h
+enc/windows_1253.$(OBJEXT): internal/dllexport.h
+enc/windows_1253.$(OBJEXT): internal/dosish.h
+enc/windows_1253.$(OBJEXT): internal/has/attribute.h
+enc/windows_1253.$(OBJEXT): internal/has/builtin.h
+enc/windows_1253.$(OBJEXT): internal/has/c_attribute.h
+enc/windows_1253.$(OBJEXT): internal/has/cpp_attribute.h
+enc/windows_1253.$(OBJEXT): internal/has/declspec_attribute.h
+enc/windows_1253.$(OBJEXT): internal/has/extension.h
+enc/windows_1253.$(OBJEXT): internal/has/feature.h
+enc/windows_1253.$(OBJEXT): internal/has/warning.h
+enc/windows_1253.$(OBJEXT): internal/stdalign.h
+enc/windows_1253.$(OBJEXT): internal/stdbool.h
+enc/windows_1253.$(OBJEXT): internal/token_paste.h
+enc/windows_1253.$(OBJEXT): internal/warning_push.h
+enc/windows_1253.$(OBJEXT): internal/xmalloc.h
+enc/windows_1253.$(OBJEXT): assert.h
+enc/windows_1253.$(OBJEXT): backward/2/assume.h
+enc/windows_1253.$(OBJEXT): backward/2/attributes.h
+enc/windows_1253.$(OBJEXT): backward/2/bool.h
+enc/windows_1253.$(OBJEXT): backward/2/gcc_version_since.h
+enc/windows_1253.$(OBJEXT): backward/2/long_long.h
+enc/windows_1253.$(OBJEXT): backward/2/stdalign.h
+enc/windows_1253.$(OBJEXT): backward/2/stdarg.h
enc/windows_1253.$(OBJEXT): config.h
enc/windows_1253.$(OBJEXT): defines.h
enc/windows_1253.$(OBJEXT): enc/windows_1253.c
enc/windows_1253.$(OBJEXT): missing.h
enc/windows_1253.$(OBJEXT): onigmo.h
enc/windows_1254.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/windows_1254.$(OBJEXT): internal/assume.h
+enc/windows_1254.$(OBJEXT): internal/attr/alloc_size.h
+enc/windows_1254.$(OBJEXT): internal/attr/cold.h
+enc/windows_1254.$(OBJEXT): internal/attr/const.h
+enc/windows_1254.$(OBJEXT): internal/attr/deprecated.h
+enc/windows_1254.$(OBJEXT): internal/attr/error.h
+enc/windows_1254.$(OBJEXT): internal/attr/forceinline.h
+enc/windows_1254.$(OBJEXT): internal/attr/format.h
+enc/windows_1254.$(OBJEXT): internal/attr/maybe_unused.h
+enc/windows_1254.$(OBJEXT): internal/attr/nodiscard.h
+enc/windows_1254.$(OBJEXT): internal/attr/noexcept.h
+enc/windows_1254.$(OBJEXT): internal/attr/noinline.h
+enc/windows_1254.$(OBJEXT): internal/attr/nonnull.h
+enc/windows_1254.$(OBJEXT): internal/attr/noreturn.h
+enc/windows_1254.$(OBJEXT): internal/attr/pure.h
+enc/windows_1254.$(OBJEXT): internal/attr/restrict.h
+enc/windows_1254.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/windows_1254.$(OBJEXT): internal/attr/warning.h
+enc/windows_1254.$(OBJEXT): internal/cast.h
+enc/windows_1254.$(OBJEXT): internal/compiler_is.h
+enc/windows_1254.$(OBJEXT): internal/compiler_is/apple.h
+enc/windows_1254.$(OBJEXT): internal/compiler_is/clang.h
+enc/windows_1254.$(OBJEXT): internal/compiler_is/gcc.h
+enc/windows_1254.$(OBJEXT): internal/compiler_is/intel.h
+enc/windows_1254.$(OBJEXT): internal/compiler_is/msvc.h
+enc/windows_1254.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/windows_1254.$(OBJEXT): internal/compiler_since.h
+enc/windows_1254.$(OBJEXT): internal/config.h
+enc/windows_1254.$(OBJEXT): internal/dllexport.h
+enc/windows_1254.$(OBJEXT): internal/dosish.h
+enc/windows_1254.$(OBJEXT): internal/has/attribute.h
+enc/windows_1254.$(OBJEXT): internal/has/builtin.h
+enc/windows_1254.$(OBJEXT): internal/has/c_attribute.h
+enc/windows_1254.$(OBJEXT): internal/has/cpp_attribute.h
+enc/windows_1254.$(OBJEXT): internal/has/declspec_attribute.h
+enc/windows_1254.$(OBJEXT): internal/has/extension.h
+enc/windows_1254.$(OBJEXT): internal/has/feature.h
+enc/windows_1254.$(OBJEXT): internal/has/warning.h
+enc/windows_1254.$(OBJEXT): internal/stdalign.h
+enc/windows_1254.$(OBJEXT): internal/stdbool.h
+enc/windows_1254.$(OBJEXT): internal/token_paste.h
+enc/windows_1254.$(OBJEXT): internal/warning_push.h
+enc/windows_1254.$(OBJEXT): internal/xmalloc.h
+enc/windows_1254.$(OBJEXT): assert.h
+enc/windows_1254.$(OBJEXT): backward/2/assume.h
+enc/windows_1254.$(OBJEXT): backward/2/attributes.h
+enc/windows_1254.$(OBJEXT): backward/2/bool.h
+enc/windows_1254.$(OBJEXT): backward/2/gcc_version_since.h
+enc/windows_1254.$(OBJEXT): backward/2/long_long.h
+enc/windows_1254.$(OBJEXT): backward/2/stdalign.h
+enc/windows_1254.$(OBJEXT): backward/2/stdarg.h
enc/windows_1254.$(OBJEXT): config.h
enc/windows_1254.$(OBJEXT): defines.h
enc/windows_1254.$(OBJEXT): enc/iso_8859.h
@@ -729,26 +6596,121 @@ enc/windows_1254.$(OBJEXT): enc/windows_1254.c
enc/windows_1254.$(OBJEXT): missing.h
enc/windows_1254.$(OBJEXT): onigmo.h
enc/windows_1257.$(OBJEXT): $(top_srcdir)/regenc.h
+enc/windows_1257.$(OBJEXT): internal/assume.h
+enc/windows_1257.$(OBJEXT): internal/attr/alloc_size.h
+enc/windows_1257.$(OBJEXT): internal/attr/cold.h
+enc/windows_1257.$(OBJEXT): internal/attr/const.h
+enc/windows_1257.$(OBJEXT): internal/attr/deprecated.h
+enc/windows_1257.$(OBJEXT): internal/attr/error.h
+enc/windows_1257.$(OBJEXT): internal/attr/forceinline.h
+enc/windows_1257.$(OBJEXT): internal/attr/format.h
+enc/windows_1257.$(OBJEXT): internal/attr/maybe_unused.h
+enc/windows_1257.$(OBJEXT): internal/attr/nodiscard.h
+enc/windows_1257.$(OBJEXT): internal/attr/noexcept.h
+enc/windows_1257.$(OBJEXT): internal/attr/noinline.h
+enc/windows_1257.$(OBJEXT): internal/attr/nonnull.h
+enc/windows_1257.$(OBJEXT): internal/attr/noreturn.h
+enc/windows_1257.$(OBJEXT): internal/attr/pure.h
+enc/windows_1257.$(OBJEXT): internal/attr/restrict.h
+enc/windows_1257.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/windows_1257.$(OBJEXT): internal/attr/warning.h
+enc/windows_1257.$(OBJEXT): internal/cast.h
+enc/windows_1257.$(OBJEXT): internal/compiler_is.h
+enc/windows_1257.$(OBJEXT): internal/compiler_is/apple.h
+enc/windows_1257.$(OBJEXT): internal/compiler_is/clang.h
+enc/windows_1257.$(OBJEXT): internal/compiler_is/gcc.h
+enc/windows_1257.$(OBJEXT): internal/compiler_is/intel.h
+enc/windows_1257.$(OBJEXT): internal/compiler_is/msvc.h
+enc/windows_1257.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/windows_1257.$(OBJEXT): internal/compiler_since.h
+enc/windows_1257.$(OBJEXT): internal/config.h
+enc/windows_1257.$(OBJEXT): internal/dllexport.h
+enc/windows_1257.$(OBJEXT): internal/dosish.h
+enc/windows_1257.$(OBJEXT): internal/has/attribute.h
+enc/windows_1257.$(OBJEXT): internal/has/builtin.h
+enc/windows_1257.$(OBJEXT): internal/has/c_attribute.h
+enc/windows_1257.$(OBJEXT): internal/has/cpp_attribute.h
+enc/windows_1257.$(OBJEXT): internal/has/declspec_attribute.h
+enc/windows_1257.$(OBJEXT): internal/has/extension.h
+enc/windows_1257.$(OBJEXT): internal/has/feature.h
+enc/windows_1257.$(OBJEXT): internal/has/warning.h
+enc/windows_1257.$(OBJEXT): internal/stdalign.h
+enc/windows_1257.$(OBJEXT): internal/stdbool.h
+enc/windows_1257.$(OBJEXT): internal/token_paste.h
+enc/windows_1257.$(OBJEXT): internal/warning_push.h
+enc/windows_1257.$(OBJEXT): internal/xmalloc.h
+enc/windows_1257.$(OBJEXT): assert.h
+enc/windows_1257.$(OBJEXT): backward/2/assume.h
+enc/windows_1257.$(OBJEXT): backward/2/attributes.h
+enc/windows_1257.$(OBJEXT): backward/2/bool.h
+enc/windows_1257.$(OBJEXT): backward/2/gcc_version_since.h
+enc/windows_1257.$(OBJEXT): backward/2/long_long.h
+enc/windows_1257.$(OBJEXT): backward/2/stdalign.h
+enc/windows_1257.$(OBJEXT): backward/2/stdarg.h
enc/windows_1257.$(OBJEXT): config.h
enc/windows_1257.$(OBJEXT): defines.h
enc/windows_1257.$(OBJEXT): enc/iso_8859.h
enc/windows_1257.$(OBJEXT): enc/windows_1257.c
enc/windows_1257.$(OBJEXT): missing.h
enc/windows_1257.$(OBJEXT): onigmo.h
-enc/windows_31j.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enc/windows_31j.$(OBJEXT): $(top_srcdir)/regenc.h
-enc/windows_31j.$(OBJEXT): $(top_srcdir)/regint.h
-enc/windows_31j.$(OBJEXT): backward.h
+enc/windows_31j.$(OBJEXT): internal/assume.h
+enc/windows_31j.$(OBJEXT): internal/attr/alloc_size.h
+enc/windows_31j.$(OBJEXT): internal/attr/cold.h
+enc/windows_31j.$(OBJEXT): internal/attr/const.h
+enc/windows_31j.$(OBJEXT): internal/attr/deprecated.h
+enc/windows_31j.$(OBJEXT): internal/attr/error.h
+enc/windows_31j.$(OBJEXT): internal/attr/forceinline.h
+enc/windows_31j.$(OBJEXT): internal/attr/format.h
+enc/windows_31j.$(OBJEXT): internal/attr/maybe_unused.h
+enc/windows_31j.$(OBJEXT): internal/attr/nodiscard.h
+enc/windows_31j.$(OBJEXT): internal/attr/noexcept.h
+enc/windows_31j.$(OBJEXT): internal/attr/noinline.h
+enc/windows_31j.$(OBJEXT): internal/attr/nonnull.h
+enc/windows_31j.$(OBJEXT): internal/attr/noreturn.h
+enc/windows_31j.$(OBJEXT): internal/attr/pure.h
+enc/windows_31j.$(OBJEXT): internal/attr/restrict.h
+enc/windows_31j.$(OBJEXT): internal/attr/returns_nonnull.h
+enc/windows_31j.$(OBJEXT): internal/attr/warning.h
+enc/windows_31j.$(OBJEXT): internal/cast.h
+enc/windows_31j.$(OBJEXT): internal/compiler_is.h
+enc/windows_31j.$(OBJEXT): internal/compiler_is/apple.h
+enc/windows_31j.$(OBJEXT): internal/compiler_is/clang.h
+enc/windows_31j.$(OBJEXT): internal/compiler_is/gcc.h
+enc/windows_31j.$(OBJEXT): internal/compiler_is/intel.h
+enc/windows_31j.$(OBJEXT): internal/compiler_is/msvc.h
+enc/windows_31j.$(OBJEXT): internal/compiler_is/sunpro.h
+enc/windows_31j.$(OBJEXT): internal/compiler_since.h
+enc/windows_31j.$(OBJEXT): internal/config.h
+enc/windows_31j.$(OBJEXT): internal/dllexport.h
+enc/windows_31j.$(OBJEXT): internal/dosish.h
+enc/windows_31j.$(OBJEXT): internal/has/attribute.h
+enc/windows_31j.$(OBJEXT): internal/has/builtin.h
+enc/windows_31j.$(OBJEXT): internal/has/c_attribute.h
+enc/windows_31j.$(OBJEXT): internal/has/cpp_attribute.h
+enc/windows_31j.$(OBJEXT): internal/has/declspec_attribute.h
+enc/windows_31j.$(OBJEXT): internal/has/extension.h
+enc/windows_31j.$(OBJEXT): internal/has/feature.h
+enc/windows_31j.$(OBJEXT): internal/has/warning.h
+enc/windows_31j.$(OBJEXT): internal/stdalign.h
+enc/windows_31j.$(OBJEXT): internal/stdbool.h
+enc/windows_31j.$(OBJEXT): internal/token_paste.h
+enc/windows_31j.$(OBJEXT): internal/warning_push.h
+enc/windows_31j.$(OBJEXT): internal/xmalloc.h
+enc/windows_31j.$(OBJEXT): assert.h
+enc/windows_31j.$(OBJEXT): backward/2/assume.h
+enc/windows_31j.$(OBJEXT): backward/2/attributes.h
+enc/windows_31j.$(OBJEXT): backward/2/bool.h
+enc/windows_31j.$(OBJEXT): backward/2/gcc_version_since.h
+enc/windows_31j.$(OBJEXT): backward/2/long_long.h
+enc/windows_31j.$(OBJEXT): backward/2/stdalign.h
+enc/windows_31j.$(OBJEXT): backward/2/stdarg.h
enc/windows_31j.$(OBJEXT): config.h
enc/windows_31j.$(OBJEXT): defines.h
enc/windows_31j.$(OBJEXT): enc/jis/props.h
enc/windows_31j.$(OBJEXT): enc/jis/props.kwd
-enc/windows_31j.$(OBJEXT): enc/shift_jis.c
+enc/windows_31j.$(OBJEXT): enc/shift_jis.h
enc/windows_31j.$(OBJEXT): enc/windows_31j.c
-enc/windows_31j.$(OBJEXT): intern.h
enc/windows_31j.$(OBJEXT): missing.h
enc/windows_31j.$(OBJEXT): onigmo.h
-enc/windows_31j.$(OBJEXT): oniguruma.h
-enc/windows_31j.$(OBJEXT): st.h
-enc/windows_31j.$(OBJEXT): subst.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/enc/encdb.c b/enc/encdb.c
index a41e4edc6d..a1936df804 100644
--- a/enc/encdb.c
+++ b/enc/encdb.c
@@ -9,7 +9,7 @@
**********************************************************************/
-#include "internal.h"
+#include "internal/encoding.h"
#define ENC_REPLICATE(name, orig) rb_encdb_replicate((name), (orig))
#define ENC_ALIAS(name, orig) rb_encdb_alias((name), (orig))
diff --git a/enc/euc_jp.c b/enc/euc_jp.c
index ded051af69..d283bf4ebb 100644
--- a/enc/euc_jp.c
+++ b/enc/euc_jp.c
@@ -593,7 +593,7 @@ ENC_ALIAS("eucJP", "EUC-JP") /* UI-OSF Application Platform Profile for Japanese
* Name: eucJP-ms
* Link: http://home.m05.itscom.net/numa/cde/ucs-conv/ucs-conv.html
* Link: http://www2d.biglobe.ne.jp/~msyk/charcode/cp932/eucJP-ms.html
- * Link: http://ja.wikipedia.org/wiki/EUC-JP
+ * Link: https://ja.wikipedia.org/wiki/EUC-JP
*/
ENC_REPLICATE("eucJP-ms", "EUC-JP") /* TOG/JVC CDE/Motif Technical WG */
ENC_ALIAS("euc-jp-ms", "eucJP-ms")
@@ -610,7 +610,7 @@ ENC_REPLICATE("CP51932", "EUC-JP")
/*
* Name: EUC-JIS-2004
- * Link: http://ja.wikipedia.org/wiki/EUC-JIS-2004
+ * Link: https://ja.wikipedia.org/wiki/EUC-JIS-2004
*/
ENC_REPLICATE("EUC-JIS-2004", "EUC-JP") /* defined at JIS X 0213:2004 */
ENC_ALIAS("EUC-JISX0213", "EUC-JIS-2004") /* defined at JIS X 0213:2000, and obsolete at JIS X 0213:2004 */
diff --git a/enc/gb2312.c b/enc/gb2312.c
index 6fc15735fc..20c8f5b7cc 100644
--- a/enc/gb2312.c
+++ b/enc/gb2312.c
@@ -1,13 +1,11 @@
-#include <ruby/ruby.h>
-#include <ruby/encoding.h>
#include "regenc.h"
void
Init_gb2312(void)
{
- rb_enc_register("GB2312", rb_enc_find("EUC-KR"));
}
+ENC_REPLICATE("GB2312", "EUC-KR")
ENC_ALIAS("EUC-CN", "GB2312")
ENC_ALIAS("eucCN", "GB2312")
ENC_REPLICATE("GB12345", "GB2312")
diff --git a/enc/iso_8859_11.c b/enc/iso_8859_11.c
index 85e8f2cdb4..b9c6119fd9 100644
--- a/enc/iso_8859_11.c
+++ b/enc/iso_8859_11.c
@@ -102,7 +102,7 @@ ENC_ALIAS("ISO8859-11", "ISO-8859-11")
/*
* Name: TIS-620
* MIBenum: 2259
- * Link: http://en.wikipedia.org/wiki/Thai_Industrial_Standard_620-2533
+ * Link: https://en.wikipedia.org/wiki/Thai_Industrial_Standard_620-2533
*/
ENC_REPLICATE("TIS-620", "ISO-8859-11")
diff --git a/enc/iso_8859_6.c b/enc/iso_8859_6.c
index 6d852ac8c0..cdb74054d1 100644
--- a/enc/iso_8859_6.c
+++ b/enc/iso_8859_6.c
@@ -104,7 +104,7 @@ ENC_ALIAS("ISO8859-6", "ISO-8859-6")
* MIBenum: 2256
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1256.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1256
+ * Link: https://en.wikipedia.org/wiki/Windows-1256
*/
ENC_REPLICATE("Windows-1256", "ISO-8859-6")
ENC_ALIAS("CP1256", "Windows-1256")
diff --git a/enc/iso_8859_8.c b/enc/iso_8859_8.c
index 0a7a29e82e..e256855f21 100644
--- a/enc/iso_8859_8.c
+++ b/enc/iso_8859_8.c
@@ -104,7 +104,7 @@ ENC_ALIAS("ISO8859-8", "ISO-8859-8")
* MIBenum: 2255
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1255.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1255
+ * Link: https://en.wikipedia.org/wiki/Windows-1255
*/
ENC_REPLICATE("Windows-1255", "ISO-8859-8")
ENC_ALIAS("CP1255", "Windows-1255")
diff --git a/enc/jis/props.h.blt b/enc/jis/props.h.blt
index 4ae2e1fd23..54aa94f8bc 100644
--- a/enc/jis/props.h.blt
+++ b/enc/jis/props.h.blt
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
/* Command-line: gperf -k1,3 -7 -c -j1 -i1 -t -C -P -t --ignore-case -H onig_jis_property_hash -Q onig_jis_property_pool -N onig_jis_property enc/jis/props.kwd */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -25,20 +25,21 @@
&& ('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
+#define gperf_offsetof(s, n) (short)offsetof(struct s##_t, s##_str##n)
#line 1 "enc/jis/props.kwd"
/* -*- c -*- */
#define GPERF_DOWNCASE 1
#define GPERF_CASE_STRNCMP 1
static inline int
-gperf_case_strncmp(const char *s1, const char *s2, unsigned int n)
+gperf_case_strncmp(const char *s1, const char *s2, size_t n)
{
const UChar *str = (const UChar *)s1;
const UChar *s = (const UChar *)s2;
- return onigenc_with_ascii_strnicmp(ONIG_ENCODING_ASCII, str, str + n, s, n);
+ return onigenc_with_ascii_strnicmp(ONIG_ENCODING_ASCII, str, str + n, s, (int)n);
}
enum onigenc_jis_ctype {
@@ -68,7 +69,7 @@ struct enc_property {
unsigned char ctype;
};
-static const struct enc_property *onig_jis_property(const char *str, unsigned int len);
+static const struct enc_property *onig_jis_property(/*const char *str, unsigned int len*/);
#line 43 "enc/jis/props.kwd"
struct enc_property;
@@ -107,10 +108,7 @@ static unsigned char gperf_downcase[256] =
#ifndef GPERF_CASE_STRNCMP
#define GPERF_CASE_STRNCMP 1
static int
-gperf_case_strncmp (s1, s2, n)
- register const char *s1;
- register const char *s2;
- register unsigned int n;
+gperf_case_strncmp (register const char *s1, register const char *s2, register size_t n)
{
for (; n > 0;)
{
@@ -127,15 +125,15 @@ gperf_case_strncmp (s1, s2, n)
}
#endif
-#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || defined(__GNUC_STDC_INLINE__)
-inline
-#elif defined(__GNUC__)
+#ifdef __GNUC__
__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
#endif
static unsigned int
-onig_jis_property_hash (str, len)
- register const char *str;
- register unsigned int len;
+onig_jis_property_hash (register const char *str, register size_t len)
{
static const unsigned char asso_values[] =
{
@@ -153,7 +151,7 @@ onig_jis_property_hash (str, len)
1, 13, 13, 13, 1, 13, 1, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13
};
- return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]];
+ return (unsigned int)len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]];
}
struct onig_jis_property_pool_t
@@ -175,41 +173,33 @@ static const struct onig_jis_property_pool_t onig_jis_property_pool_contents =
"cyrillic"
};
#define onig_jis_property_pool ((const char *) &onig_jis_property_pool_contents)
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct enc_property *
-onig_jis_property (str, len)
- register const char *str;
- register unsigned int len;
+onig_jis_property (register const char *str, register size_t len)
{
static const struct enc_property wordlist[] =
{
{-1}, {-1}, {-1}, {-1}, {-1},
#line 48 "enc/jis/props.kwd"
- {(char)offsetof(struct onig_jis_property_pool_t, onig_jis_property_pool_str5), onigenc_jis_han},
+ {gperf_offsetof(onig_jis_property_pool, 5), onigenc_jis_han},
{-1},
#line 49 "enc/jis/props.kwd"
- {(char)offsetof(struct onig_jis_property_pool_t, onig_jis_property_pool_str7), onigenc_jis_latin},
+ {gperf_offsetof(onig_jis_property_pool, 7), onigenc_jis_latin},
#line 50 "enc/jis/props.kwd"
- {(char)offsetof(struct onig_jis_property_pool_t, onig_jis_property_pool_str8), onigenc_jis_greek},
+ {gperf_offsetof(onig_jis_property_pool, 8), onigenc_jis_greek},
{-1},
#line 46 "enc/jis/props.kwd"
- {(char)offsetof(struct onig_jis_property_pool_t, onig_jis_property_pool_str10), onigenc_jis_hiragana},
+ {gperf_offsetof(onig_jis_property_pool, 10), onigenc_jis_hiragana},
#line 47 "enc/jis/props.kwd"
- {(char)offsetof(struct onig_jis_property_pool_t, onig_jis_property_pool_str11), onigenc_jis_katakana},
+ {gperf_offsetof(onig_jis_property_pool, 11), onigenc_jis_katakana},
#line 51 "enc/jis/props.kwd"
- {(char)offsetof(struct onig_jis_property_pool_t, onig_jis_property_pool_str12), onigenc_jis_cyrillic}
+ {gperf_offsetof(onig_jis_property_pool, 12), onigenc_jis_cyrillic}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = onig_jis_property_hash (str, len);
+ register unsigned int key = onig_jis_property_hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register int o = wordlist[key].name;
if (o >= 0)
diff --git a/enc/jis/props.kwd b/enc/jis/props.kwd
index f3235c0100..659cf0aff4 100644
--- a/enc/jis/props.kwd
+++ b/enc/jis/props.kwd
@@ -3,11 +3,11 @@
#define GPERF_CASE_STRNCMP 1
static inline int
-gperf_case_strncmp(const char *s1, const char *s2, unsigned int n)
+gperf_case_strncmp(const char *s1, const char *s2, size_t n)
{
const UChar *str = (const UChar *)s1;
const UChar *s = (const UChar *)s2;
- return onigenc_with_ascii_strnicmp(ONIG_ENCODING_ASCII, str, str + n, s, n);
+ return onigenc_with_ascii_strnicmp(ONIG_ENCODING_ASCII, str, str + n, s, (int)n);
}
enum onigenc_jis_ctype {
@@ -37,7 +37,7 @@ struct enc_property {
unsigned char ctype;
};
-static const struct enc_property *onig_jis_property(const char *str, unsigned int len);
+static const struct enc_property *onig_jis_property(/*!ANSI{*/const char *str, unsigned int len/*}!ANSI*/);
%}
struct enc_property;
diff --git a/enc/jis/props.src b/enc/jis/props.src
index f3235c0100..659cf0aff4 100644
--- a/enc/jis/props.src
+++ b/enc/jis/props.src
@@ -3,11 +3,11 @@
#define GPERF_CASE_STRNCMP 1
static inline int
-gperf_case_strncmp(const char *s1, const char *s2, unsigned int n)
+gperf_case_strncmp(const char *s1, const char *s2, size_t n)
{
const UChar *str = (const UChar *)s1;
const UChar *s = (const UChar *)s2;
- return onigenc_with_ascii_strnicmp(ONIG_ENCODING_ASCII, str, str + n, s, n);
+ return onigenc_with_ascii_strnicmp(ONIG_ENCODING_ASCII, str, str + n, s, (int)n);
}
enum onigenc_jis_ctype {
@@ -37,7 +37,7 @@ struct enc_property {
unsigned char ctype;
};
-static const struct enc_property *onig_jis_property(const char *str, unsigned int len);
+static const struct enc_property *onig_jis_property(/*!ANSI{*/const char *str, unsigned int len/*}!ANSI*/);
%}
struct enc_property;
diff --git a/enc/make_encmake.rb b/enc/make_encmake.rb
index 4ab85f36e3..bc0597e3f4 100755
--- a/enc/make_encmake.rb
+++ b/enc/make_encmake.rb
@@ -121,7 +121,11 @@ ENCS, ENC_DEPS = target_encodings
ATRANS, TRANS = target_transcoders
if File.exist?(depend = File.join($srcdir, "depend"))
- erb = ERB.new(File.read(depend), nil, '%')
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
+ erb = ERB.new(File.read(depend), trim_mode: '%')
+ else
+ erb = ERB.new(File.read(depend), nil, '%')
+ end
erb.filename = depend
tmp = erb.result(binding)
dep = "\n#### depend ####\n\n" << depend_rules(tmp).join
@@ -135,7 +139,11 @@ open(ARGV[0], 'wb') {|f|
}
if MODULE_TYPE == :static
filename = "encinit.c.erb"
- erb = ERB.new(File.read(File.join($srcdir, filename)), nil, '%-')
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
+ erb = ERB.new(File.read(File.join($srcdir, filename)), trim_mode: '%-')
+ else
+ erb = ERB.new(File.read(File.join($srcdir, filename)), nil, '%-')
+ end
erb.filename = "enc/#{filename}"
tmp = erb.result(binding)
begin
diff --git a/enc/shift_jis.c b/enc/shift_jis.c
index eacca9a5db..f1355d2d95 100644
--- a/enc/shift_jis.c
+++ b/enc/shift_jis.c
@@ -1,9 +1,9 @@
/**********************************************************************
- sjis.c - Onigmo (Oniguruma-mod) (regular expression library)
+ shift_jis.c - Onigmo (Oniguruma-mod) (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
- * Copyright (c) 2011 K.Takata <kentkt AT csc DOT jp>
+ * Copyright (c) 2002-2009 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2017 K.Takata <kentkt AT csc DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,524 +28,8 @@
* SUCH DAMAGE.
*/
-#include "regenc.h"
+#include "shift_jis.h"
-static const int EncLen_SJIS[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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,
- 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, 1, 1
-};
-
-static const char SJIS_CAN_BE_TRAIL_TABLE[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0
-};
-
-static const OnigPairCaseFoldCodes CaseFoldMap[] = {
- /* Fullwidth Alphabet */
- { 0x8260, 0x8281 },
- { 0x8261, 0x8282 },
- { 0x8262, 0x8283 },
- { 0x8263, 0x8284 },
- { 0x8264, 0x8285 },
- { 0x8265, 0x8286 },
- { 0x8266, 0x8287 },
- { 0x8267, 0x8288 },
- { 0x8268, 0x8289 },
- { 0x8269, 0x828a },
- { 0x826a, 0x828b },
- { 0x826b, 0x828c },
- { 0x826c, 0x828d },
- { 0x826d, 0x828e },
- { 0x826e, 0x828f },
- { 0x826f, 0x8290 },
- { 0x8270, 0x8291 },
- { 0x8271, 0x8292 },
- { 0x8272, 0x8293 },
- { 0x8273, 0x8294 },
- { 0x8274, 0x8295 },
- { 0x8275, 0x8296 },
- { 0x8276, 0x8297 },
- { 0x8277, 0x8298 },
- { 0x8278, 0x8299 },
- { 0x8279, 0x829a },
-
- /* Greek */
- { 0x839f, 0x83bf },
- { 0x83a0, 0x83c0 },
- { 0x83a1, 0x83c1 },
- { 0x83a2, 0x83c2 },
- { 0x83a3, 0x83c3 },
- { 0x83a4, 0x83c4 },
- { 0x83a5, 0x83c5 },
- { 0x83a6, 0x83c6 },
- { 0x83a7, 0x83c7 },
- { 0x83a8, 0x83c8 },
- { 0x83a9, 0x83c9 },
- { 0x83aa, 0x83ca },
- { 0x83ab, 0x83cb },
- { 0x83ac, 0x83cc },
- { 0x83ad, 0x83cd },
- { 0x83ae, 0x83ce },
- { 0x83af, 0x83cf },
- { 0x83b0, 0x83d0 },
- { 0x83b1, 0x83d1 },
- { 0x83b2, 0x83d2 },
- { 0x83b3, 0x83d3 },
- { 0x83b4, 0x83d4 },
- { 0x83b5, 0x83d5 },
- { 0x83b6, 0x83d6 },
-
- /* Cyrillic */
- { 0x8440, 0x8470 },
- { 0x8441, 0x8471 },
- { 0x8442, 0x8472 },
- { 0x8443, 0x8473 },
- { 0x8444, 0x8474 },
- { 0x8445, 0x8475 },
- { 0x8446, 0x8476 },
- { 0x8447, 0x8477 },
- { 0x8448, 0x8478 },
- { 0x8449, 0x8479 },
- { 0x844a, 0x847a },
- { 0x844b, 0x847b },
- { 0x844c, 0x847c },
- { 0x844d, 0x847d },
- { 0x844e, 0x847e },
- { 0x844f, 0x8480 },
- { 0x8450, 0x8481 },
- { 0x8451, 0x8482 },
- { 0x8452, 0x8483 },
- { 0x8453, 0x8484 },
- { 0x8454, 0x8485 },
- { 0x8455, 0x8486 },
- { 0x8456, 0x8487 },
- { 0x8457, 0x8488 },
- { 0x8458, 0x8489 },
- { 0x8459, 0x848a },
- { 0x845a, 0x848b },
- { 0x845b, 0x848c },
- { 0x845c, 0x848d },
- { 0x845d, 0x848e },
- { 0x845e, 0x848f },
- { 0x845f, 0x8490 },
- { 0x8460, 0x8491 },
-};
-
-#define SJIS_ISMB_FIRST(byte) (EncLen_SJIS[byte] > 1)
-#define SJIS_ISMB_TRAIL(byte) SJIS_CAN_BE_TRAIL_TABLE[(byte)]
-
-typedef enum { FAILURE = -2, ACCEPT = -1, S0 = 0, S1 } state_t;
-#define A ACCEPT
-#define F FAILURE
-static const signed char trans[][0x100] = {
- { /* S0 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* 0 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 1 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 2 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 3 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 4 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 5 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 6 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 7 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 8 */ F, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* a */ F, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* b */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* c */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* d */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, F, F, F
- },
- { /* S1 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
- /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
- /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
- /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
- /* 4 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 5 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 6 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 7 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, F,
- /* 8 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* 9 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* a */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* b */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* c */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* d */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* e */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
- /* f */ A, A, A, A, A, A, A, A, A, A, A, A, A, F, F, F
- }
-};
-#undef A
-#undef F
-
-static int
-mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc ARG_UNUSED)
-{
- int firstbyte = *p++;
- state_t s;
- s = trans[0][firstbyte];
- if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(1) :
- ONIGENC_CONSTRUCT_MBCLEN_INVALID();
- if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(EncLen_SJIS[firstbyte]-1);
- s = trans[s][*p++];
- return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(2) :
- ONIGENC_CONSTRUCT_MBCLEN_INVALID();
-}
-
-static int
-code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
-{
- if (code < 256) {
- if (EncLen_SJIS[(int )code] == 1)
- return 1;
- else
- return ONIGERR_INVALID_CODE_POINT_VALUE;
- }
- else if (code <= 0xffff) {
- int low = code & 0xff;
- if (! SJIS_ISMB_TRAIL(low))
- return ONIGERR_INVALID_CODE_POINT_VALUE;
- return 2;
- }
- else
- return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
-}
-
-static OnigCodePoint
-mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc)
-{
- int c, i, len;
- OnigCodePoint n;
-
- len = mbc_enc_len(p, end, enc);
- c = *p++;
- n = c;
- if (len == 1) return n;
-
- for (i = 1; i < len; i++) {
- if (p >= end) break;
- c = *p++;
- n <<= 8; n += c;
- }
- return n;
-}
-
-static int
-code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc)
-{
- UChar *p = buf;
-
- if ((code & 0xff00) != 0) *p++ = (UChar )(((code >> 8) & 0xff));
- *p++ = (UChar )(code & 0xff);
-
-#if 0
- if (mbc_enc_len(buf, p, enc) != (p - buf))
- return REGERR_INVALID_CODE_POINT_VALUE;
-#endif
- return (int )(p - buf);
-}
-
-static int
-apply_all_case_fold(OnigCaseFoldType flag,
- OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc)
-{
- return onigenc_apply_all_case_fold_with_map(
- numberof(CaseFoldMap), CaseFoldMap, 0,
- flag, f, arg);
-}
-
-static OnigCodePoint
-get_lower_case(OnigCodePoint code)
-{
- if (ONIGENC_IS_IN_RANGE(code, 0x8260, 0x8279)) {
- /* Fullwidth Alphabet */
- return (OnigCodePoint )(code + 0x0021);
- }
- else if (ONIGENC_IS_IN_RANGE(code, 0x839f, 0x83b6)) {
- /* Greek */
- return (OnigCodePoint )(code + 0x0020);
- }
- else if (ONIGENC_IS_IN_RANGE(code, 0x8440, 0x8460)) {
- /* Cyrillic */
- int d = (code >= 0x844f) ? 1 : 0;
- return (OnigCodePoint )(code + (0x0030 + d));
- }
- return code;
-}
-
-static OnigCodePoint
-get_upper_case(OnigCodePoint code)
-{
- if (ONIGENC_IS_IN_RANGE(code, 0x8281, 0x829a)) {
- /* Fullwidth Alphabet */
- return (OnigCodePoint )(code - 0x0021);
- }
- else if (ONIGENC_IS_IN_RANGE(code, 0x83bf, 0x83d6)) {
- /* Greek */
- return (OnigCodePoint )(code - 0x0020);
- }
- else if (ONIGENC_IS_IN_RANGE(code, 0x8470, 0x847e) ||
- ONIGENC_IS_IN_RANGE(code, 0x8480, 0x8491)) {
- /* Cyrillic */
- int d = (code >= 0x8480) ? 1 : 0;
- return (OnigCodePoint )(code - (0x0030 - d));
- }
- return code;
-}
-
-static int
-get_case_fold_codes_by_str(OnigCaseFoldType flag,
- const OnigUChar* p, const OnigUChar* end,
- OnigCaseFoldCodeItem items[], OnigEncoding enc)
-{
- int len;
- OnigCodePoint code, code_lo, code_up;
-
- code = mbc_to_code(p, end, enc);
- if (ONIGENC_IS_ASCII_CODE(code))
- return onigenc_ascii_get_case_fold_codes_by_str(flag, p, end, items, enc);
-
- len = mbc_enc_len(p, end, enc);
- code_lo = get_lower_case(code);
- code_up = get_upper_case(code);
-
- if (code != code_lo) {
- items[0].byte_len = len;
- items[0].code_len = 1;
- items[0].code[0] = code_lo;
- return 1;
- }
- else if (code != code_up) {
- items[0].byte_len = len;
- items[0].code_len = 1;
- items[0].code[0] = code_up;
- return 1;
- }
-
- return 0;
-}
-
-static int
-mbc_case_fold(OnigCaseFoldType flag,
- const UChar** pp, const UChar* end, UChar* lower,
- OnigEncoding enc)
-{
- const UChar* p = *pp;
-
- if (ONIGENC_IS_MBC_ASCII(p)) {
- *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
- (*pp)++;
- return 1;
- }
- else {
- OnigCodePoint code;
- int len;
-
- code = get_lower_case(mbc_to_code(p, end, enc));
- len = code_to_mbc(code, lower, enc);
- (*pp) += len;
- return len; /* return byte length of converted char to lower */
- }
-}
-
-#if 0
-static int
-is_mbc_ambiguous(OnigCaseFoldType flag,
- const UChar** pp, const UChar* end)
-{
- return onigenc_mbn_is_mbc_ambiguous(enc, flag, pp, end);
-
-}
-#endif
-
-#if 0
-static int
-is_code_ctype(OnigCodePoint code, unsigned int ctype)
-{
- if (code < 128)
- return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
- else {
- if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
- return (code_to_mbclen(code) > 1 ? TRUE : FALSE);
- }
- }
-
- return FALSE;
-}
-#endif
-
-static UChar*
-left_adjust_char_head(const UChar* start, const UChar* s, const UChar* end, OnigEncoding enc)
-{
- const UChar *p;
- int len;
-
- if (s <= start) return (UChar* )s;
- p = s;
-
- if (SJIS_ISMB_TRAIL(*p)) {
- while (p > start) {
- if (! SJIS_ISMB_FIRST(*--p)) {
- p++;
- break;
- }
- }
- }
- len = mbc_enc_len(p, end, enc);
- if (p + len > s) return (UChar* )p;
- p += len;
- return (UChar* )(p + ((s - p) & ~1));
-}
-
-static int
-is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc ARG_UNUSED)
-{
- const UChar c = *s;
- return (SJIS_ISMB_TRAIL(c) ? FALSE : TRUE);
-}
-
-
-static const OnigCodePoint CR_Hiragana[] = {
- 1,
- 0x829f, 0x82f1
-}; /* CR_Hiragana */
-
-static const OnigCodePoint CR_Katakana[] = {
- 4,
- 0x00a6, 0x00af,
- 0x00b1, 0x00dd,
- 0x8340, 0x837e,
- 0x8380, 0x8396,
-}; /* CR_Katakana */
-
-#ifdef ENC_CP932
-static const OnigCodePoint CR_Han[] = {
- 6,
- 0x8157, 0x8157,
- 0x889f, 0x9872, /* Kanji level 1 */
- 0x989f, 0x9ffc, /* Kanji level 2 */
- 0xe040, 0xeaa4, /* Kanji level 2 */
- 0xed40, 0xeeec, /* NEC-selected IBM extended characters (without symbols) */
- 0xfa5c, 0xfc4b, /* IBM extended characters (without symbols) */
-}; /* CR_Han */
-#else
-static const OnigCodePoint CR_Han[] = {
- 4,
- 0x8157, 0x8157,
- 0x889f, 0x9872, /* Kanji level 1 */
- 0x989f, 0x9ffc, /* Kanji level 2 */
- 0xe040, 0xeaa4, /* Kanji level 2 */
-}; /* CR_Han */
-#endif
-
-static const OnigCodePoint CR_Latin[] = {
- 4,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x8260, 0x8279,
- 0x8281, 0x829a,
-}; /* CR_Latin */
-
-static const OnigCodePoint CR_Greek[] = {
- 2,
- 0x839f, 0x83b6,
- 0x83bf, 0x83d6,
-}; /* CR_Greek */
-
-static const OnigCodePoint CR_Cyrillic[] = {
- 3,
- 0x8440, 0x8460,
- 0x8470, 0x847f,
- 0x8480, 0x8491,
-}; /* CR_Cyrillic */
-
-#include "enc/jis/props.h"
-
-static int
-property_name_to_ctype(OnigEncoding enc, const UChar* p, const UChar* end)
-{
- const UChar *s = p, *e = end;
- const struct enc_property *prop =
- onig_jis_property((const char* )s, (unsigned int )(e - s));
-
- if (!prop) {
- return onigenc_minimum_property_name_to_ctype(enc, s, e);
- }
-
- return (int )prop->ctype;
-}
-
-static int
-is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc)
-{
- if (ctype <= ONIGENC_MAX_STD_CTYPE) {
- if (code < 128)
- return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
- else {
- if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
- return TRUE;
- }
- }
- }
- else {
- ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
- if (ctype >= (unsigned int )PropertyListNum)
- return ONIGERR_TYPE_BUG;
-
- return onig_is_in_code_range((UChar* )PropertyList[ctype], code);
- }
-
- return FALSE;
-}
-
-static int
-get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out,
- const OnigCodePoint* ranges[], OnigEncoding enc ARG_UNUSED)
-{
- if (ctype <= ONIGENC_MAX_STD_CTYPE) {
- return ONIG_NO_SUPPORT_CONFIG;
- }
- else {
- *sb_out = 0x80;
-
- ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
- if (ctype >= (OnigCtype )PropertyListNum)
- return ONIGERR_TYPE_BUG;
-
- *ranges = PropertyList[ctype];
- return 0;
- }
-}
-
-#ifndef ENC_CP932
OnigEncodingDefine(shift_jis, Shift_JIS) = {
mbc_enc_len,
"Shift_JIS", /* name */
@@ -571,14 +55,13 @@ OnigEncodingDefine(shift_jis, Shift_JIS) = {
* Name: Shift_JIS
* MIBenum: 17
* Link: http://www.iana.org/assignments/character-sets
- * Link: http://ja.wikipedia.org/wiki/Shift_JIS
+ * Link: https://ja.wikipedia.org/wiki/Shift_JIS
*/
/*
* Name: MacJapanese
* Link: http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/JAPANESE.TXT
- * Link: http://ja.wikipedia.org/wiki/MacJapanese
+ * Link: https://ja.wikipedia.org/wiki/MacJapanese
*/
ENC_REPLICATE("MacJapanese", "Shift_JIS")
ENC_ALIAS("MacJapan", "MacJapanese")
-#endif
diff --git a/enc/shift_jis.h b/enc/shift_jis.h
new file mode 100644
index 0000000000..d552401595
--- /dev/null
+++ b/enc/shift_jis.h
@@ -0,0 +1,546 @@
+/**********************************************************************
+ shift_jis.h - Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011 K.Takata <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regenc.h"
+
+static const int EncLen_SJIS[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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,
+ 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, 1, 1
+};
+
+static const char SJIS_CAN_BE_TRAIL_TABLE[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0
+};
+
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ /* Fullwidth Alphabet */
+ { 0x8260, 0x8281 },
+ { 0x8261, 0x8282 },
+ { 0x8262, 0x8283 },
+ { 0x8263, 0x8284 },
+ { 0x8264, 0x8285 },
+ { 0x8265, 0x8286 },
+ { 0x8266, 0x8287 },
+ { 0x8267, 0x8288 },
+ { 0x8268, 0x8289 },
+ { 0x8269, 0x828a },
+ { 0x826a, 0x828b },
+ { 0x826b, 0x828c },
+ { 0x826c, 0x828d },
+ { 0x826d, 0x828e },
+ { 0x826e, 0x828f },
+ { 0x826f, 0x8290 },
+ { 0x8270, 0x8291 },
+ { 0x8271, 0x8292 },
+ { 0x8272, 0x8293 },
+ { 0x8273, 0x8294 },
+ { 0x8274, 0x8295 },
+ { 0x8275, 0x8296 },
+ { 0x8276, 0x8297 },
+ { 0x8277, 0x8298 },
+ { 0x8278, 0x8299 },
+ { 0x8279, 0x829a },
+
+ /* Greek */
+ { 0x839f, 0x83bf },
+ { 0x83a0, 0x83c0 },
+ { 0x83a1, 0x83c1 },
+ { 0x83a2, 0x83c2 },
+ { 0x83a3, 0x83c3 },
+ { 0x83a4, 0x83c4 },
+ { 0x83a5, 0x83c5 },
+ { 0x83a6, 0x83c6 },
+ { 0x83a7, 0x83c7 },
+ { 0x83a8, 0x83c8 },
+ { 0x83a9, 0x83c9 },
+ { 0x83aa, 0x83ca },
+ { 0x83ab, 0x83cb },
+ { 0x83ac, 0x83cc },
+ { 0x83ad, 0x83cd },
+ { 0x83ae, 0x83ce },
+ { 0x83af, 0x83cf },
+ { 0x83b0, 0x83d0 },
+ { 0x83b1, 0x83d1 },
+ { 0x83b2, 0x83d2 },
+ { 0x83b3, 0x83d3 },
+ { 0x83b4, 0x83d4 },
+ { 0x83b5, 0x83d5 },
+ { 0x83b6, 0x83d6 },
+
+ /* Cyrillic */
+ { 0x8440, 0x8470 },
+ { 0x8441, 0x8471 },
+ { 0x8442, 0x8472 },
+ { 0x8443, 0x8473 },
+ { 0x8444, 0x8474 },
+ { 0x8445, 0x8475 },
+ { 0x8446, 0x8476 },
+ { 0x8447, 0x8477 },
+ { 0x8448, 0x8478 },
+ { 0x8449, 0x8479 },
+ { 0x844a, 0x847a },
+ { 0x844b, 0x847b },
+ { 0x844c, 0x847c },
+ { 0x844d, 0x847d },
+ { 0x844e, 0x847e },
+ { 0x844f, 0x8480 },
+ { 0x8450, 0x8481 },
+ { 0x8451, 0x8482 },
+ { 0x8452, 0x8483 },
+ { 0x8453, 0x8484 },
+ { 0x8454, 0x8485 },
+ { 0x8455, 0x8486 },
+ { 0x8456, 0x8487 },
+ { 0x8457, 0x8488 },
+ { 0x8458, 0x8489 },
+ { 0x8459, 0x848a },
+ { 0x845a, 0x848b },
+ { 0x845b, 0x848c },
+ { 0x845c, 0x848d },
+ { 0x845d, 0x848e },
+ { 0x845e, 0x848f },
+ { 0x845f, 0x8490 },
+ { 0x8460, 0x8491 },
+};
+
+#define SJIS_ISMB_FIRST(byte) (EncLen_SJIS[byte] > 1)
+#define SJIS_ISMB_TRAIL(byte) SJIS_CAN_BE_TRAIL_TABLE[(byte)]
+
+typedef enum { FAILURE = -2, ACCEPT = -1, S0 = 0, S1 } state_t;
+#define A ACCEPT
+#define F FAILURE
+static const signed char trans[][0x100] = {
+ { /* S0 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 1 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 2 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 3 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 4 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 5 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 6 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 7 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 8 */ F, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* a */ F, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* b */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* c */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* d */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ /* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, F, F, F
+ },
+ { /* S1 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ /* 4 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 5 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 6 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 7 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, F,
+ /* 8 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* 9 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* a */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* b */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* c */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* d */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* e */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+ /* f */ A, A, A, A, A, A, A, A, A, A, A, A, A, F, F, F
+ }
+};
+#undef A
+#undef F
+
+static int
+mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc ARG_UNUSED)
+{
+ int firstbyte = *p++;
+ state_t s;
+ s = trans[0][firstbyte];
+ if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(1) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+ if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(EncLen_SJIS[firstbyte]-1);
+ s = trans[s][*p++];
+ return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(2) :
+ ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+}
+
+static int
+code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
+{
+ if (code < 256) {
+ if (EncLen_SJIS[(int )code] == 1)
+ return 1;
+ else
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
+ }
+ else if (code <= 0xffff) {
+ int low = code & 0xff;
+ if (! SJIS_ISMB_TRAIL(low))
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
+ return 2;
+ }
+ else
+ return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+}
+
+static OnigCodePoint
+mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc)
+{
+ int c, i, len;
+ OnigCodePoint n;
+
+ len = mbc_enc_len(p, end, enc);
+ c = *p++;
+ n = c;
+ if (len == 1) return n;
+
+ for (i = 1; i < len; i++) {
+ if (p >= end) break;
+ c = *p++;
+ n <<= 8; n += c;
+ }
+ return n;
+}
+
+static int
+code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc)
+{
+ UChar *p = buf;
+
+ if ((code & 0xff00) != 0) *p++ = (UChar )(((code >> 8) & 0xff));
+ *p++ = (UChar )(code & 0xff);
+
+#if 0
+ if (mbc_enc_len(buf, p, enc) != (p - buf))
+ return REGERR_INVALID_CODE_POINT_VALUE;
+#endif
+ return (int )(p - buf);
+}
+
+static int
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc)
+{
+ return onigenc_apply_all_case_fold_with_map(
+ numberof(CaseFoldMap), CaseFoldMap, 0,
+ flag, f, arg);
+}
+
+static OnigCodePoint
+get_lower_case(OnigCodePoint code)
+{
+ if (ONIGENC_IS_IN_RANGE(code, 0x8260, 0x8279)) {
+ /* Fullwidth Alphabet */
+ return (OnigCodePoint )(code + 0x0021);
+ }
+ else if (ONIGENC_IS_IN_RANGE(code, 0x839f, 0x83b6)) {
+ /* Greek */
+ return (OnigCodePoint )(code + 0x0020);
+ }
+ else if (ONIGENC_IS_IN_RANGE(code, 0x8440, 0x8460)) {
+ /* Cyrillic */
+ int d = (code >= 0x844f) ? 1 : 0;
+ return (OnigCodePoint )(code + (0x0030 + d));
+ }
+ return code;
+}
+
+static OnigCodePoint
+get_upper_case(OnigCodePoint code)
+{
+ if (ONIGENC_IS_IN_RANGE(code, 0x8281, 0x829a)) {
+ /* Fullwidth Alphabet */
+ return (OnigCodePoint )(code - 0x0021);
+ }
+ else if (ONIGENC_IS_IN_RANGE(code, 0x83bf, 0x83d6)) {
+ /* Greek */
+ return (OnigCodePoint )(code - 0x0020);
+ }
+ else if (ONIGENC_IS_IN_RANGE(code, 0x8470, 0x847e) ||
+ ONIGENC_IS_IN_RANGE(code, 0x8480, 0x8491)) {
+ /* Cyrillic */
+ int d = (code >= 0x8480) ? 1 : 0;
+ return (OnigCodePoint )(code - (0x0030 - d));
+ }
+ return code;
+}
+
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end,
+ OnigCaseFoldCodeItem items[], OnigEncoding enc)
+{
+ int len;
+ OnigCodePoint code, code_lo, code_up;
+
+ code = mbc_to_code(p, end, enc);
+ if (ONIGENC_IS_ASCII_CODE(code))
+ return onigenc_ascii_get_case_fold_codes_by_str(flag, p, end, items, enc);
+
+ len = mbc_enc_len(p, end, enc);
+ code_lo = get_lower_case(code);
+ code_up = get_upper_case(code);
+
+ if (code != code_lo) {
+ items[0].byte_len = len;
+ items[0].code_len = 1;
+ items[0].code[0] = code_lo;
+ return 1;
+ }
+ else if (code != code_up) {
+ items[0].byte_len = len;
+ items[0].code_len = 1;
+ items[0].code[0] = code_up;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end, UChar* lower,
+ OnigEncoding enc)
+{
+ const UChar* p = *pp;
+
+ if (ONIGENC_IS_MBC_ASCII(p)) {
+ *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
+ (*pp)++;
+ return 1;
+ }
+ else {
+ OnigCodePoint code;
+ int len;
+
+ code = get_lower_case(mbc_to_code(p, end, enc));
+ len = code_to_mbc(code, lower, enc);
+ (*pp) += len;
+ return len; /* return byte length of converted char to lower */
+ }
+}
+
+#if 0
+static int
+is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
+{
+ return onigenc_mbn_is_mbc_ambiguous(enc, flag, pp, end);
+
+}
+#endif
+
+#if 0
+static int
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
+{
+ if (code < 128)
+ return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
+ else {
+ if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
+ return (code_to_mbclen(code) > 1 ? TRUE : FALSE);
+ }
+ }
+
+ return FALSE;
+}
+#endif
+
+static UChar*
+left_adjust_char_head(const UChar* start, const UChar* s, const UChar* end, OnigEncoding enc)
+{
+ const UChar *p;
+ int len;
+
+ if (s <= start) return (UChar* )s;
+ p = s;
+
+ if (SJIS_ISMB_TRAIL(*p)) {
+ while (p > start) {
+ if (! SJIS_ISMB_FIRST(*--p)) {
+ p++;
+ break;
+ }
+ }
+ }
+ len = mbc_enc_len(p, end, enc);
+ if (p + len > s) return (UChar* )p;
+ p += len;
+ return (UChar* )(p + ((s - p) & ~1));
+}
+
+static int
+is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc ARG_UNUSED)
+{
+ const UChar c = *s;
+ return (SJIS_ISMB_TRAIL(c) ? FALSE : TRUE);
+}
+
+
+static const OnigCodePoint CR_Hiragana[] = {
+ 1,
+ 0x829f, 0x82f1
+}; /* CR_Hiragana */
+
+static const OnigCodePoint CR_Katakana[] = {
+ 4,
+ 0x00a6, 0x00af,
+ 0x00b1, 0x00dd,
+ 0x8340, 0x837e,
+ 0x8380, 0x8396,
+}; /* CR_Katakana */
+
+#ifdef ENC_CP932
+static const OnigCodePoint CR_Han[] = {
+ 6,
+ 0x8157, 0x8157,
+ 0x889f, 0x9872, /* Kanji level 1 */
+ 0x989f, 0x9ffc, /* Kanji level 2 */
+ 0xe040, 0xeaa4, /* Kanji level 2 */
+ 0xed40, 0xeeec, /* NEC-selected IBM extended characters (without symbols) */
+ 0xfa5c, 0xfc4b, /* IBM extended characters (without symbols) */
+}; /* CR_Han */
+#else
+static const OnigCodePoint CR_Han[] = {
+ 4,
+ 0x8157, 0x8157,
+ 0x889f, 0x9872, /* Kanji level 1 */
+ 0x989f, 0x9ffc, /* Kanji level 2 */
+ 0xe040, 0xeaa4, /* Kanji level 2 */
+}; /* CR_Han */
+#endif
+
+static const OnigCodePoint CR_Latin[] = {
+ 4,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x8260, 0x8279,
+ 0x8281, 0x829a,
+}; /* CR_Latin */
+
+static const OnigCodePoint CR_Greek[] = {
+ 2,
+ 0x839f, 0x83b6,
+ 0x83bf, 0x83d6,
+}; /* CR_Greek */
+
+static const OnigCodePoint CR_Cyrillic[] = {
+ 3,
+ 0x8440, 0x8460,
+ 0x8470, 0x847f,
+ 0x8480, 0x8491,
+}; /* CR_Cyrillic */
+
+#include "enc/jis/props.h"
+
+static int
+property_name_to_ctype(OnigEncoding enc, const UChar* p, const UChar* end)
+{
+ const UChar *s = p, *e = end;
+ const struct enc_property *prop =
+ onig_jis_property((const char* )s, (unsigned int )(e - s));
+
+ if (!prop) {
+ return onigenc_minimum_property_name_to_ctype(enc, s, e);
+ }
+
+ return (int )prop->ctype;
+}
+
+static int
+is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc)
+{
+ if (ctype <= ONIGENC_MAX_STD_CTYPE) {
+ if (code < 128)
+ return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
+ else {
+ if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
+ return TRUE;
+ }
+ }
+ }
+ else {
+ ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
+ if (ctype >= (unsigned int )PropertyListNum)
+ return ONIGERR_TYPE_BUG;
+
+ return onig_is_in_code_range((UChar* )PropertyList[ctype], code);
+ }
+
+ return FALSE;
+}
+
+static int
+get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out,
+ const OnigCodePoint* ranges[], OnigEncoding enc ARG_UNUSED)
+{
+ if (ctype <= ONIGENC_MAX_STD_CTYPE) {
+ return ONIG_NO_SUPPORT_CONFIG;
+ }
+ else {
+ *sb_out = 0x80;
+
+ ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
+ if (ctype >= (OnigCtype )PropertyListNum)
+ return ONIGERR_TYPE_BUG;
+
+ *ranges = PropertyList[ctype];
+ return 0;
+ }
+}
diff --git a/enc/trans/JIS/JISX0212%UCS.src b/enc/trans/JIS/JISX0212%UCS.src
index aa51257b99..0e1ab4c9b9 100644
--- a/enc/trans/JIS/JISX0212%UCS.src
+++ b/enc/trans/JIS/JISX0212%UCS.src
@@ -67,7 +67,7 @@ BEGIN_MAP
#
# However, JIS X 0212 maintains the distinction between
# the lowercase forms of these two elements at 0x2942 and 0x2943.
-# Given the structre of these JIS encodings, it is clear that
+# Given the structure of these JIS encodings, it is clear that
# 0x2922 and 0x2942 are intended to be a capital/small pair.
# Consequently, in the Unicode mapping, 0x2922 is treated as
# LATIN CAPITAL LETTER D WITH STROKE.
diff --git a/enc/trans/JIS/UCS%JISX0212.src b/enc/trans/JIS/UCS%JISX0212.src
index 65383a1c9f..c7711c8ac0 100644
--- a/enc/trans/JIS/UCS%JISX0212.src
+++ b/enc/trans/JIS/UCS%JISX0212.src
@@ -67,7 +67,7 @@ BEGIN_MAP
#
# However, JIS X 0212 maintains the distinction between
# the lowercase forms of these two elements at 0x2942 and 0x2943.
-# Given the structre of these JIS encodings, it is clear that
+# Given the structure of these JIS encodings, it is clear that
# 0x2922 and 0x2942 are intended to be a capital/small pair.
# Consequently, in the Unicode mapping, 0x2922 is treated as
# LATIN CAPITAL LETTER D WITH STROKE.
diff --git a/enc/trans/cesu_8.trans b/enc/trans/cesu_8.trans
new file mode 100644
index 0000000000..4e17b1ddbb
--- /dev/null
+++ b/enc/trans/cesu_8.trans
@@ -0,0 +1,85 @@
+#include "transcode_data.h"
+
+<%
+ map = {}
+ map["{00-7f}"] = :nomap
+ map["{c2-df}{80-bf}"] = :nomap
+ map["e0{a0-bf}{80-bf}"] = :nomap
+ map["{e1-ec}{80-bf}{80-bf}"] = :nomap
+ map["ed{80-9f}{80-bf}"] = :nomap
+ map["{ee-ef}{80-bf}{80-bf}"] = :nomap
+ map["ed{a0-af}{80-bf}ed{b0-bf}{80-bf}"] = :func_so # surrogate pairs
+ transcode_generate_node(ActionMap.parse(map), "from_CESU_8")
+
+ map = {}
+ map["{00-7f}"] = :nomap
+ map["{c2-df}{80-bf}"] = :nomap
+ map["e0{a0-bf}{80-bf}"] = :nomap
+ map["{e1-ec}{80-bf}{80-bf}"] = :nomap
+ map["ed{80-9f}{80-bf}"] = :nomap
+ map["{ee-ef}{80-bf}{80-bf}"] = :nomap
+ map["f0{90-bf}{80-bf}{80-bf}"] = :func_so # planes 1-3
+ map["{f1-f3}{80-bf}{80-bf}{80-bf}"] = :func_so # planes 4-15
+ map["f4{80-8f}{80-bf}{80-bf}"] = :func_so # plane 16
+ transcode_generate_node(ActionMap.parse(map), "to_CESU_8")
+%>
+
+<%= transcode_generated_code %>
+
+static ssize_t
+fun_so_from_cesu_8(void *statep, const unsigned char *s, size_t l, unsigned char *o, size_t osize)
+{
+ unsigned int scalar = ( ((s[1]&0x0F)<<16) | ((s[2]&0x3F)<<10)
+ | ((s[4]&0x0F)<< 6) | (s[5]&0x3F)
+ ) + 0x10000;
+ o[0] = 0xF0 | (scalar>>18);
+ o[1] = 0x80 | ((scalar>>12)&0x3F);
+ o[2] = 0x80 | ((scalar>> 6)&0x3F);
+ o[3] = 0x80 | ( scalar &0x3F);
+ return 4;
+}
+
+static ssize_t
+fun_so_to_cesu_8(void *statep, const unsigned char *s, size_t l, unsigned char *o, size_t osize)
+{
+ unsigned int scalar = ((s[0]&0x07)<<18) | ((s[1]&0x3F)<<12)
+ | ((s[2]&0x3F)<< 6) | (s[3]&0x3F);
+ scalar -= 0x10000;
+ o[0] = 0xED;
+ o[1] = 0xA0 | (scalar>>16);
+ o[2] = 0x80 | ((scalar>>10)&0x3F);
+ o[3] = 0xED;
+ o[4] = 0xB0 | ((scalar>> 6)&0x0F);
+ o[5] = 0x80 | (scalar &0x3F);
+ return 6;
+}
+
+static const rb_transcoder
+rb_from_CESU_8 = {
+ "CESU-8", "UTF-8", from_CESU_8,
+ TRANSCODE_TABLE_INFO,
+ 1, /* input_unit_length */
+ 6, /* max_input */
+ 4, /* max_output */
+ asciicompat_decoder, /* asciicompat_type */
+ 0, NULL, NULL, /* state_size, state_init, state_fini */
+ NULL, NULL, NULL, fun_so_from_cesu_8
+};
+
+static const rb_transcoder
+rb_to_CESU_8 = {
+ "UTF-8", "CESU-8", to_CESU_8,
+ TRANSCODE_TABLE_INFO,
+ 1, /* input_unit_length */
+ 4, /* max_input */
+ 6, /* max_output */
+ asciicompat_encoder, /* asciicompat_type */
+ 0, NULL, NULL, /* state_size, state_init, state_fini */
+ NULL, NULL, NULL, fun_so_to_cesu_8
+};
+
+TRANS_INIT(cesu_8)
+{
+ rb_register_transcoder(&rb_from_CESU_8);
+ rb_register_transcoder(&rb_to_CESU_8);
+}
diff --git a/enc/trans/escape.trans b/enc/trans/escape.trans
index c76ffa0e06..36d9dd0f13 100644
--- a/enc/trans/escape.trans
+++ b/enc/trans/escape.trans
@@ -18,9 +18,10 @@
], nil)
transcode_tblgen("", "xml_attr_content_escape", [
- ["{00-21,23-25,27-3B,3D,3F-FF}", :nomap],
+ ["{00-21,23-25,28-3B,3D,3F-FF}", :nomap],
["22", hexstr("&quot;")],
["26", hexstr("&amp;")],
+ ["27", hexstr("&apos;")],
["3C", hexstr("&lt;")],
["3E", hexstr("&gt;")]
], nil)
diff --git a/enc/trans/ibm720-tbl.rb b/enc/trans/ibm720-tbl.rb
new file mode 100644
index 0000000000..558684d649
--- /dev/null
+++ b/enc/trans/ibm720-tbl.rb
@@ -0,0 +1,122 @@
+IBM720_TO_UCS_TBL = [
+ ["FF",0xA0],
+ ["9C",0xA3],
+ ["94",0xA4],
+ ["AE",0xAB],
+ ["F8",0xB0],
+ ["FD",0xB2],
+ ["E6",0xB5],
+ ["FA",0xB7],
+ ["AF",0xBB],
+ ["85",0xE0],
+ ["83",0xE2],
+ ["87",0xE7],
+ ["8A",0xE8],
+ ["82",0xE9],
+ ["88",0xEA],
+ ["89",0xEB],
+ ["8C",0xEE],
+ ["8B",0xEF],
+ ["93",0xF4],
+ ["97",0xF9],
+ ["96",0xFB],
+ ["98",0x621],
+ ["99",0x622],
+ ["9A",0x623],
+ ["9B",0x624],
+ ["9D",0x625],
+ ["9E",0x626],
+ ["9F",0x627],
+ ["A0",0x628],
+ ["A1",0x629],
+ ["A2",0x62A],
+ ["A3",0x62B],
+ ["A4",0x62C],
+ ["A5",0x62D],
+ ["A6",0x62E],
+ ["A7",0x62F],
+ ["A8",0x630],
+ ["A9",0x631],
+ ["AA",0x632],
+ ["AB",0x633],
+ ["AC",0x634],
+ ["AD",0x635],
+ ["E0",0x636],
+ ["E1",0x637],
+ ["E2",0x638],
+ ["E3",0x639],
+ ["E4",0x63A],
+ ["95",0x640],
+ ["E5",0x641],
+ ["E7",0x642],
+ ["E8",0x643],
+ ["E9",0x644],
+ ["EA",0x645],
+ ["EB",0x646],
+ ["EC",0x647],
+ ["ED",0x648],
+ ["EE",0x649],
+ ["EF",0x64A],
+ ["F1",0x64B],
+ ["F2",0x64C],
+ ["F3",0x64D],
+ ["F4",0x64E],
+ ["F5",0x64F],
+ ["F6",0x650],
+ ["91",0x651],
+ ["92",0x652],
+ ["FC",0x207F],
+ ["F9",0x2219],
+ ["FB",0x221A],
+ ["F7",0x2248],
+ ["F0",0x2261],
+ ["C4",0x2500],
+ ["B3",0x2502],
+ ["DA",0x250C],
+ ["BF",0x2510],
+ ["C0",0x2514],
+ ["D9",0x2518],
+ ["C3",0x251C],
+ ["B4",0x2524],
+ ["C2",0x252C],
+ ["C1",0x2534],
+ ["C5",0x253C],
+ ["CD",0x2550],
+ ["BA",0x2551],
+ ["D5",0x2552],
+ ["D6",0x2553],
+ ["C9",0x2554],
+ ["B8",0x2555],
+ ["B7",0x2556],
+ ["BB",0x2557],
+ ["D4",0x2558],
+ ["D3",0x2559],
+ ["C8",0x255A],
+ ["BE",0x255B],
+ ["BD",0x255C],
+ ["BC",0x255D],
+ ["C6",0x255E],
+ ["C7",0x255F],
+ ["CC",0x2560],
+ ["B5",0x2561],
+ ["B6",0x2562],
+ ["B9",0x2563],
+ ["D1",0x2564],
+ ["D2",0x2565],
+ ["CB",0x2566],
+ ["CF",0x2567],
+ ["D0",0x2568],
+ ["CA",0x2569],
+ ["D8",0x256A],
+ ["D7",0x256B],
+ ["CE",0x256C],
+ ["DF",0x2580],
+ ["DC",0x2584],
+ ["DB",0x2588],
+ ["DD",0x258C],
+ ["DE",0x2590],
+ ["B0",0x2591],
+ ["B1",0x2592],
+ ["B2",0x2593],
+ ["FE",0x25A0],
+]
diff --git a/enc/trans/newline.trans b/enc/trans/newline.trans
index a200ec00a7..9e763407f9 100644
--- a/enc/trans/newline.trans
+++ b/enc/trans/newline.trans
@@ -98,7 +98,7 @@ rb_universal_newline = {
2, /* max_output */
asciicompat_converter, /* asciicompat_type */
2, universal_newline_init, universal_newline_init, /* state_size, state_init, state_fini */
- NULL, NULL, NULL, fun_so_universal_newline,
+ 0, 0, 0, fun_so_universal_newline,
universal_newline_finish
};
@@ -110,8 +110,8 @@ rb_crlf_newline = {
1, /* max_input */
2, /* max_output */
asciicompat_converter, /* asciicompat_type */
- 0, NULL, NULL, /* state_size, state_init, state_fini */
- NULL, NULL, NULL, NULL
+ 0, 0, 0, /* state_size, state_init, state_fini */
+ 0, 0, 0, 0
};
static const rb_transcoder
@@ -122,8 +122,8 @@ rb_cr_newline = {
1, /* max_input */
1, /* max_output */
asciicompat_converter, /* asciicompat_type */
- 0, NULL, NULL, /* state_size, state_init, state_fini */
- NULL, NULL, NULL, NULL
+ 0, 0, 0, /* state_size, state_init, state_fini */
+ 0, 0, 0, 0
};
void
diff --git a/enc/trans/single_byte.trans b/enc/trans/single_byte.trans
index cf521bed38..0d5407b918 100644
--- a/enc/trans/single_byte.trans
+++ b/enc/trans/single_byte.trans
@@ -51,8 +51,9 @@
transcode_tblgen_singlebyte "WINDOWS-1256"
transcode_tblgen_singlebyte "WINDOWS-1257"
transcode_tblgen_singlebyte "IBM437"
- transcode_tblgen_singlebyte "IBM775"
+ transcode_tblgen_singlebyte "IBM720"
transcode_tblgen_singlebyte "IBM737"
+ transcode_tblgen_singlebyte "IBM775"
transcode_tblgen_singlebyte "IBM852"
transcode_tblgen_singlebyte "IBM855"
transcode_tblgen_singlebyte "IBM857"
diff --git a/enc/unicode.c b/enc/unicode.c
index 72ff5a96e7..18fba02476 100644
--- a/enc/unicode.c
+++ b/enc/unicode.c
@@ -493,6 +493,10 @@ onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc,
#endif
if ((to = onigenc_unicode_fold_lookup(code)) != 0) {
+ if (OnigCodePointCount(to->n) == 0) {
+ /* any codepoint should not be empty */
+ UNREACHABLE_RETURN(0);
+ }
if (OnigCodePointCount(to->n) == 1) {
OnigCodePoint orig_code = code;
@@ -683,8 +687,10 @@ onigenc_unicode_case_map(OnigCaseFoldType* flagP,
MODIFIED;
if (flags & ONIGENC_CASE_FOLD_TURKISH_AZERI && code == 'i')
code = I_WITH_DOT_ABOVE;
- else
- code += 'A' - 'a';
+ else {
+ code -= 'a';
+ code += 'A';
+ }
}
}
else if (code >= 'A' && code <= 'Z') {
@@ -717,7 +723,11 @@ onigenc_unicode_case_map(OnigCaseFoldType* flagP,
}
}
else if ((folded = onigenc_unicode_fold_lookup(code)) != 0) { /* data about character found in CaseFold_11_Table */
- if ((flags & ONIGENC_CASE_TITLECASE) /* Titlecase needed, */
+ if ((flags & ONIGENC_CASE_TITLECASE) && code>=0x1C90 && code<=0x1CBF) { /* Georgian MTAVRULI */
+ MODIFIED;
+ code += 0x10D0 - 0x1C90;
+ }
+ else if ((flags & ONIGENC_CASE_TITLECASE) /* Titlecase needed, */
&& (OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_IS_TITLECASE)) { /* but already Titlecase */
/* already Titlecase, no changes needed */
}
@@ -770,10 +780,15 @@ SpecialsCopy:
}
}
}
- else if ((folded = onigenc_unicode_unfold1_lookup(code)) != 0 /* data about character found in CaseUnfold_11_Table */
- && flags & OnigCaseFoldFlags(folded->n)) { /* needs and data availability match */
- MODIFIED;
- code = folded->code[(flags & OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_TITLECASE) ? 1 : 0];
+ else if ((folded = onigenc_unicode_unfold1_lookup(code)) != 0) { /* data about character found in CaseUnfold_11_Table */
+ if ((flags & ONIGENC_CASE_TITLECASE) /* Titlecase needed, */
+ && (OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_IS_TITLECASE)) { /* but already Titlecase */
+ /* already Titlecase, no changes needed */
+ }
+ else if (flags & OnigCaseFoldFlags(folded->n)) { /* needs and data availability match */
+ MODIFIED;
+ code = folded->code[(flags & OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_TITLECASE) ? 1 : 0];
+ }
}
}
to += ONIGENC_CODE_TO_MBC(enc, code, to);
diff --git a/enc/unicode/10.0.0/casefold.h b/enc/unicode/10.0.0/casefold.h
deleted file mode 100644
index 714ebe6f73..0000000000
--- a/enc/unicode/10.0.0/casefold.h
+++ /dev/null
@@ -1,7068 +0,0 @@
-/* DO NOT EDIT THIS FILE. */
-/* Generated by enc/unicode/case-folding.rb */
-
-#if defined ONIG_UNICODE_VERSION_STRING && !( \
- ONIG_UNICODE_VERSION_MAJOR == 10 && \
- ONIG_UNICODE_VERSION_MINOR == 0 && \
- ONIG_UNICODE_VERSION_TEENY == 0 && \
- 1)
-# error ONIG_UNICODE_VERSION_STRING mismatch
-#endif
-#define ONIG_UNICODE_VERSION_STRING "10.0.0"
-#define ONIG_UNICODE_VERSION_MAJOR 10
-#define ONIG_UNICODE_VERSION_MINOR 0
-#define ONIG_UNICODE_VERSION_TEENY 0
-
-static const CaseFold_11_Type CaseFold_11_Table[] = {
-#define CaseFold (*(CaseFold_11_Type (*)[1399])(CaseFold_11_Table+0))
- {0x0041, {1|F|D, {0x0061}}},
- {0x0042, {1|F|D, {0x0062}}},
- {0x0043, {1|F|D, {0x0063}}},
- {0x0044, {1|F|D, {0x0064}}},
- {0x0045, {1|F|D, {0x0065}}},
- {0x0046, {1|F|D, {0x0066}}},
- {0x0047, {1|F|D, {0x0067}}},
- {0x0048, {1|F|D, {0x0068}}},
- {0x004a, {1|F|D, {0x006a}}},
- {0x004b, {1|F|D, {0x006b}}},
- {0x004c, {1|F|D, {0x006c}}},
- {0x004d, {1|F|D, {0x006d}}},
- {0x004e, {1|F|D, {0x006e}}},
- {0x004f, {1|F|D, {0x006f}}},
- {0x0050, {1|F|D, {0x0070}}},
- {0x0051, {1|F|D, {0x0071}}},
- {0x0052, {1|F|D, {0x0072}}},
- {0x0053, {1|F|D, {0x0073}}},
- {0x0054, {1|F|D, {0x0074}}},
- {0x0055, {1|F|D, {0x0075}}},
- {0x0056, {1|F|D, {0x0076}}},
- {0x0057, {1|F|D, {0x0077}}},
- {0x0058, {1|F|D, {0x0078}}},
- {0x0059, {1|F|D, {0x0079}}},
- {0x005a, {1|F|D, {0x007a}}},
- {0x00b5, {1|F|SU|I(0), {0x03bc}}},
- {0x00c0, {1|F|D, {0x00e0}}},
- {0x00c1, {1|F|D, {0x00e1}}},
- {0x00c2, {1|F|D, {0x00e2}}},
- {0x00c3, {1|F|D, {0x00e3}}},
- {0x00c4, {1|F|D, {0x00e4}}},
- {0x00c5, {1|F|D, {0x00e5}}},
- {0x00c6, {1|F|D, {0x00e6}}},
- {0x00c7, {1|F|D, {0x00e7}}},
- {0x00c8, {1|F|D, {0x00e8}}},
- {0x00c9, {1|F|D, {0x00e9}}},
- {0x00ca, {1|F|D, {0x00ea}}},
- {0x00cb, {1|F|D, {0x00eb}}},
- {0x00cc, {1|F|D, {0x00ec}}},
- {0x00cd, {1|F|D, {0x00ed}}},
- {0x00ce, {1|F|D, {0x00ee}}},
- {0x00cf, {1|F|D, {0x00ef}}},
- {0x00d0, {1|F|D, {0x00f0}}},
- {0x00d1, {1|F|D, {0x00f1}}},
- {0x00d2, {1|F|D, {0x00f2}}},
- {0x00d3, {1|F|D, {0x00f3}}},
- {0x00d4, {1|F|D, {0x00f4}}},
- {0x00d5, {1|F|D, {0x00f5}}},
- {0x00d6, {1|F|D, {0x00f6}}},
- {0x00d8, {1|F|D, {0x00f8}}},
- {0x00d9, {1|F|D, {0x00f9}}},
- {0x00da, {1|F|D, {0x00fa}}},
- {0x00db, {1|F|D, {0x00fb}}},
- {0x00dc, {1|F|D, {0x00fc}}},
- {0x00dd, {1|F|D, {0x00fd}}},
- {0x00de, {1|F|D, {0x00fe}}},
- {0x00df, {2|F|ST|SU|I(1), {0x0073, 0x0073}}},
- {0x0100, {1|F|D, {0x0101}}},
- {0x0102, {1|F|D, {0x0103}}},
- {0x0104, {1|F|D, {0x0105}}},
- {0x0106, {1|F|D, {0x0107}}},
- {0x0108, {1|F|D, {0x0109}}},
- {0x010a, {1|F|D, {0x010b}}},
- {0x010c, {1|F|D, {0x010d}}},
- {0x010e, {1|F|D, {0x010f}}},
- {0x0110, {1|F|D, {0x0111}}},
- {0x0112, {1|F|D, {0x0113}}},
- {0x0114, {1|F|D, {0x0115}}},
- {0x0116, {1|F|D, {0x0117}}},
- {0x0118, {1|F|D, {0x0119}}},
- {0x011a, {1|F|D, {0x011b}}},
- {0x011c, {1|F|D, {0x011d}}},
- {0x011e, {1|F|D, {0x011f}}},
- {0x0120, {1|F|D, {0x0121}}},
- {0x0122, {1|F|D, {0x0123}}},
- {0x0124, {1|F|D, {0x0125}}},
- {0x0126, {1|F|D, {0x0127}}},
- {0x0128, {1|F|D, {0x0129}}},
- {0x012a, {1|F|D, {0x012b}}},
- {0x012c, {1|F|D, {0x012d}}},
- {0x012e, {1|F|D, {0x012f}}},
- {0x0132, {1|F|D, {0x0133}}},
- {0x0134, {1|F|D, {0x0135}}},
- {0x0136, {1|F|D, {0x0137}}},
- {0x0139, {1|F|D, {0x013a}}},
- {0x013b, {1|F|D, {0x013c}}},
- {0x013d, {1|F|D, {0x013e}}},
- {0x013f, {1|F|D, {0x0140}}},
- {0x0141, {1|F|D, {0x0142}}},
- {0x0143, {1|F|D, {0x0144}}},
- {0x0145, {1|F|D, {0x0146}}},
- {0x0147, {1|F|D, {0x0148}}},
- {0x0149, {2|F|SU|I(5), {0x02bc, 0x006e}}},
- {0x014a, {1|F|D, {0x014b}}},
- {0x014c, {1|F|D, {0x014d}}},
- {0x014e, {1|F|D, {0x014f}}},
- {0x0150, {1|F|D, {0x0151}}},
- {0x0152, {1|F|D, {0x0153}}},
- {0x0154, {1|F|D, {0x0155}}},
- {0x0156, {1|F|D, {0x0157}}},
- {0x0158, {1|F|D, {0x0159}}},
- {0x015a, {1|F|D, {0x015b}}},
- {0x015c, {1|F|D, {0x015d}}},
- {0x015e, {1|F|D, {0x015f}}},
- {0x0160, {1|F|D, {0x0161}}},
- {0x0162, {1|F|D, {0x0163}}},
- {0x0164, {1|F|D, {0x0165}}},
- {0x0166, {1|F|D, {0x0167}}},
- {0x0168, {1|F|D, {0x0169}}},
- {0x016a, {1|F|D, {0x016b}}},
- {0x016c, {1|F|D, {0x016d}}},
- {0x016e, {1|F|D, {0x016f}}},
- {0x0170, {1|F|D, {0x0171}}},
- {0x0172, {1|F|D, {0x0173}}},
- {0x0174, {1|F|D, {0x0175}}},
- {0x0176, {1|F|D, {0x0177}}},
- {0x0178, {1|F|D, {0x00ff}}},
- {0x0179, {1|F|D, {0x017a}}},
- {0x017b, {1|F|D, {0x017c}}},
- {0x017d, {1|F|D, {0x017e}}},
- {0x017f, {1|F|SU|I(7), {0x0073}}},
- {0x0181, {1|F|D, {0x0253}}},
- {0x0182, {1|F|D, {0x0183}}},
- {0x0184, {1|F|D, {0x0185}}},
- {0x0186, {1|F|D, {0x0254}}},
- {0x0187, {1|F|D, {0x0188}}},
- {0x0189, {1|F|D, {0x0256}}},
- {0x018a, {1|F|D, {0x0257}}},
- {0x018b, {1|F|D, {0x018c}}},
- {0x018e, {1|F|D, {0x01dd}}},
- {0x018f, {1|F|D, {0x0259}}},
- {0x0190, {1|F|D, {0x025b}}},
- {0x0191, {1|F|D, {0x0192}}},
- {0x0193, {1|F|D, {0x0260}}},
- {0x0194, {1|F|D, {0x0263}}},
- {0x0196, {1|F|D, {0x0269}}},
- {0x0197, {1|F|D, {0x0268}}},
- {0x0198, {1|F|D, {0x0199}}},
- {0x019c, {1|F|D, {0x026f}}},
- {0x019d, {1|F|D, {0x0272}}},
- {0x019f, {1|F|D, {0x0275}}},
- {0x01a0, {1|F|D, {0x01a1}}},
- {0x01a2, {1|F|D, {0x01a3}}},
- {0x01a4, {1|F|D, {0x01a5}}},
- {0x01a6, {1|F|D, {0x0280}}},
- {0x01a7, {1|F|D, {0x01a8}}},
- {0x01a9, {1|F|D, {0x0283}}},
- {0x01ac, {1|F|D, {0x01ad}}},
- {0x01ae, {1|F|D, {0x0288}}},
- {0x01af, {1|F|D, {0x01b0}}},
- {0x01b1, {1|F|D, {0x028a}}},
- {0x01b2, {1|F|D, {0x028b}}},
- {0x01b3, {1|F|D, {0x01b4}}},
- {0x01b5, {1|F|D, {0x01b6}}},
- {0x01b7, {1|F|D, {0x0292}}},
- {0x01b8, {1|F|D, {0x01b9}}},
- {0x01bc, {1|F|D, {0x01bd}}},
- {0x01c4, {1|F|D|ST|I(8), {0x01c6}}},
- {0x01c5, {1|F|D|IT|SU|I(9), {0x01c6}}},
- {0x01c7, {1|F|D|ST|I(12), {0x01c9}}},
- {0x01c8, {1|F|D|IT|SU|I(13), {0x01c9}}},
- {0x01ca, {1|F|D|ST|I(16), {0x01cc}}},
- {0x01cb, {1|F|D|IT|SU|I(17), {0x01cc}}},
- {0x01cd, {1|F|D, {0x01ce}}},
- {0x01cf, {1|F|D, {0x01d0}}},
- {0x01d1, {1|F|D, {0x01d2}}},
- {0x01d3, {1|F|D, {0x01d4}}},
- {0x01d5, {1|F|D, {0x01d6}}},
- {0x01d7, {1|F|D, {0x01d8}}},
- {0x01d9, {1|F|D, {0x01da}}},
- {0x01db, {1|F|D, {0x01dc}}},
- {0x01de, {1|F|D, {0x01df}}},
- {0x01e0, {1|F|D, {0x01e1}}},
- {0x01e2, {1|F|D, {0x01e3}}},
- {0x01e4, {1|F|D, {0x01e5}}},
- {0x01e6, {1|F|D, {0x01e7}}},
- {0x01e8, {1|F|D, {0x01e9}}},
- {0x01ea, {1|F|D, {0x01eb}}},
- {0x01ec, {1|F|D, {0x01ed}}},
- {0x01ee, {1|F|D, {0x01ef}}},
- {0x01f0, {2|F|SU|I(20), {0x006a, 0x030c}}},
- {0x01f1, {1|F|D|ST|I(22), {0x01f3}}},
- {0x01f2, {1|F|D|IT|SU|I(23), {0x01f3}}},
- {0x01f4, {1|F|D, {0x01f5}}},
- {0x01f6, {1|F|D, {0x0195}}},
- {0x01f7, {1|F|D, {0x01bf}}},
- {0x01f8, {1|F|D, {0x01f9}}},
- {0x01fa, {1|F|D, {0x01fb}}},
- {0x01fc, {1|F|D, {0x01fd}}},
- {0x01fe, {1|F|D, {0x01ff}}},
- {0x0200, {1|F|D, {0x0201}}},
- {0x0202, {1|F|D, {0x0203}}},
- {0x0204, {1|F|D, {0x0205}}},
- {0x0206, {1|F|D, {0x0207}}},
- {0x0208, {1|F|D, {0x0209}}},
- {0x020a, {1|F|D, {0x020b}}},
- {0x020c, {1|F|D, {0x020d}}},
- {0x020e, {1|F|D, {0x020f}}},
- {0x0210, {1|F|D, {0x0211}}},
- {0x0212, {1|F|D, {0x0213}}},
- {0x0214, {1|F|D, {0x0215}}},
- {0x0216, {1|F|D, {0x0217}}},
- {0x0218, {1|F|D, {0x0219}}},
- {0x021a, {1|F|D, {0x021b}}},
- {0x021c, {1|F|D, {0x021d}}},
- {0x021e, {1|F|D, {0x021f}}},
- {0x0220, {1|F|D, {0x019e}}},
- {0x0222, {1|F|D, {0x0223}}},
- {0x0224, {1|F|D, {0x0225}}},
- {0x0226, {1|F|D, {0x0227}}},
- {0x0228, {1|F|D, {0x0229}}},
- {0x022a, {1|F|D, {0x022b}}},
- {0x022c, {1|F|D, {0x022d}}},
- {0x022e, {1|F|D, {0x022f}}},
- {0x0230, {1|F|D, {0x0231}}},
- {0x0232, {1|F|D, {0x0233}}},
- {0x023a, {1|F|D, {0x2c65}}},
- {0x023b, {1|F|D, {0x023c}}},
- {0x023d, {1|F|D, {0x019a}}},
- {0x023e, {1|F|D, {0x2c66}}},
- {0x0241, {1|F|D, {0x0242}}},
- {0x0243, {1|F|D, {0x0180}}},
- {0x0244, {1|F|D, {0x0289}}},
- {0x0245, {1|F|D, {0x028c}}},
- {0x0246, {1|F|D, {0x0247}}},
- {0x0248, {1|F|D, {0x0249}}},
- {0x024a, {1|F|D, {0x024b}}},
- {0x024c, {1|F|D, {0x024d}}},
- {0x024e, {1|F|D, {0x024f}}},
- {0x0345, {1|F|SU|I(26), {0x03b9}}},
- {0x0370, {1|F|D, {0x0371}}},
- {0x0372, {1|F|D, {0x0373}}},
- {0x0376, {1|F|D, {0x0377}}},
- {0x037f, {1|F|D, {0x03f3}}},
- {0x0386, {1|F|D, {0x03ac}}},
- {0x0388, {1|F|D, {0x03ad}}},
- {0x0389, {1|F|D, {0x03ae}}},
- {0x038a, {1|F|D, {0x03af}}},
- {0x038c, {1|F|D, {0x03cc}}},
- {0x038e, {1|F|D, {0x03cd}}},
- {0x038f, {1|F|D, {0x03ce}}},
- {0x0390, {3|F|SU|I(27), {0x03b9, 0x0308, 0x0301}}},
- {0x0391, {1|F|D, {0x03b1}}},
- {0x0392, {1|F|D, {0x03b2}}},
- {0x0393, {1|F|D, {0x03b3}}},
- {0x0394, {1|F|D, {0x03b4}}},
- {0x0395, {1|F|D, {0x03b5}}},
- {0x0396, {1|F|D, {0x03b6}}},
- {0x0397, {1|F|D, {0x03b7}}},
- {0x0398, {1|F|D, {0x03b8}}},
- {0x0399, {1|F|D, {0x03b9}}},
- {0x039a, {1|F|D, {0x03ba}}},
- {0x039b, {1|F|D, {0x03bb}}},
- {0x039c, {1|F|D, {0x03bc}}},
- {0x039d, {1|F|D, {0x03bd}}},
- {0x039e, {1|F|D, {0x03be}}},
- {0x039f, {1|F|D, {0x03bf}}},
- {0x03a0, {1|F|D, {0x03c0}}},
- {0x03a1, {1|F|D, {0x03c1}}},
- {0x03a3, {1|F|D, {0x03c3}}},
- {0x03a4, {1|F|D, {0x03c4}}},
- {0x03a5, {1|F|D, {0x03c5}}},
- {0x03a6, {1|F|D, {0x03c6}}},
- {0x03a7, {1|F|D, {0x03c7}}},
- {0x03a8, {1|F|D, {0x03c8}}},
- {0x03a9, {1|F|D, {0x03c9}}},
- {0x03aa, {1|F|D, {0x03ca}}},
- {0x03ab, {1|F|D, {0x03cb}}},
- {0x03b0, {3|F|SU|I(30), {0x03c5, 0x0308, 0x0301}}},
- {0x03c2, {1|F|SU|I(33), {0x03c3}}},
- {0x03cf, {1|F|D, {0x03d7}}},
- {0x03d0, {1|F|SU|I(34), {0x03b2}}},
- {0x03d1, {1|F|SU|I(35), {0x03b8}}},
- {0x03d5, {1|F|SU|I(36), {0x03c6}}},
- {0x03d6, {1|F|SU|I(37), {0x03c0}}},
- {0x03d8, {1|F|D, {0x03d9}}},
- {0x03da, {1|F|D, {0x03db}}},
- {0x03dc, {1|F|D, {0x03dd}}},
- {0x03de, {1|F|D, {0x03df}}},
- {0x03e0, {1|F|D, {0x03e1}}},
- {0x03e2, {1|F|D, {0x03e3}}},
- {0x03e4, {1|F|D, {0x03e5}}},
- {0x03e6, {1|F|D, {0x03e7}}},
- {0x03e8, {1|F|D, {0x03e9}}},
- {0x03ea, {1|F|D, {0x03eb}}},
- {0x03ec, {1|F|D, {0x03ed}}},
- {0x03ee, {1|F|D, {0x03ef}}},
- {0x03f0, {1|F|SU|I(38), {0x03ba}}},
- {0x03f1, {1|F|SU|I(39), {0x03c1}}},
- {0x03f4, {1|F|D, {0x03b8}}},
- {0x03f5, {1|F|SU|I(40), {0x03b5}}},
- {0x03f7, {1|F|D, {0x03f8}}},
- {0x03f9, {1|F|D, {0x03f2}}},
- {0x03fa, {1|F|D, {0x03fb}}},
- {0x03fd, {1|F|D, {0x037b}}},
- {0x03fe, {1|F|D, {0x037c}}},
- {0x03ff, {1|F|D, {0x037d}}},
- {0x0400, {1|F|D, {0x0450}}},
- {0x0401, {1|F|D, {0x0451}}},
- {0x0402, {1|F|D, {0x0452}}},
- {0x0403, {1|F|D, {0x0453}}},
- {0x0404, {1|F|D, {0x0454}}},
- {0x0405, {1|F|D, {0x0455}}},
- {0x0406, {1|F|D, {0x0456}}},
- {0x0407, {1|F|D, {0x0457}}},
- {0x0408, {1|F|D, {0x0458}}},
- {0x0409, {1|F|D, {0x0459}}},
- {0x040a, {1|F|D, {0x045a}}},
- {0x040b, {1|F|D, {0x045b}}},
- {0x040c, {1|F|D, {0x045c}}},
- {0x040d, {1|F|D, {0x045d}}},
- {0x040e, {1|F|D, {0x045e}}},
- {0x040f, {1|F|D, {0x045f}}},
- {0x0410, {1|F|D, {0x0430}}},
- {0x0411, {1|F|D, {0x0431}}},
- {0x0412, {1|F|D, {0x0432}}},
- {0x0413, {1|F|D, {0x0433}}},
- {0x0414, {1|F|D, {0x0434}}},
- {0x0415, {1|F|D, {0x0435}}},
- {0x0416, {1|F|D, {0x0436}}},
- {0x0417, {1|F|D, {0x0437}}},
- {0x0418, {1|F|D, {0x0438}}},
- {0x0419, {1|F|D, {0x0439}}},
- {0x041a, {1|F|D, {0x043a}}},
- {0x041b, {1|F|D, {0x043b}}},
- {0x041c, {1|F|D, {0x043c}}},
- {0x041d, {1|F|D, {0x043d}}},
- {0x041e, {1|F|D, {0x043e}}},
- {0x041f, {1|F|D, {0x043f}}},
- {0x0420, {1|F|D, {0x0440}}},
- {0x0421, {1|F|D, {0x0441}}},
- {0x0422, {1|F|D, {0x0442}}},
- {0x0423, {1|F|D, {0x0443}}},
- {0x0424, {1|F|D, {0x0444}}},
- {0x0425, {1|F|D, {0x0445}}},
- {0x0426, {1|F|D, {0x0446}}},
- {0x0427, {1|F|D, {0x0447}}},
- {0x0428, {1|F|D, {0x0448}}},
- {0x0429, {1|F|D, {0x0449}}},
- {0x042a, {1|F|D, {0x044a}}},
- {0x042b, {1|F|D, {0x044b}}},
- {0x042c, {1|F|D, {0x044c}}},
- {0x042d, {1|F|D, {0x044d}}},
- {0x042e, {1|F|D, {0x044e}}},
- {0x042f, {1|F|D, {0x044f}}},
- {0x0460, {1|F|D, {0x0461}}},
- {0x0462, {1|F|D, {0x0463}}},
- {0x0464, {1|F|D, {0x0465}}},
- {0x0466, {1|F|D, {0x0467}}},
- {0x0468, {1|F|D, {0x0469}}},
- {0x046a, {1|F|D, {0x046b}}},
- {0x046c, {1|F|D, {0x046d}}},
- {0x046e, {1|F|D, {0x046f}}},
- {0x0470, {1|F|D, {0x0471}}},
- {0x0472, {1|F|D, {0x0473}}},
- {0x0474, {1|F|D, {0x0475}}},
- {0x0476, {1|F|D, {0x0477}}},
- {0x0478, {1|F|D, {0x0479}}},
- {0x047a, {1|F|D, {0x047b}}},
- {0x047c, {1|F|D, {0x047d}}},
- {0x047e, {1|F|D, {0x047f}}},
- {0x0480, {1|F|D, {0x0481}}},
- {0x048a, {1|F|D, {0x048b}}},
- {0x048c, {1|F|D, {0x048d}}},
- {0x048e, {1|F|D, {0x048f}}},
- {0x0490, {1|F|D, {0x0491}}},
- {0x0492, {1|F|D, {0x0493}}},
- {0x0494, {1|F|D, {0x0495}}},
- {0x0496, {1|F|D, {0x0497}}},
- {0x0498, {1|F|D, {0x0499}}},
- {0x049a, {1|F|D, {0x049b}}},
- {0x049c, {1|F|D, {0x049d}}},
- {0x049e, {1|F|D, {0x049f}}},
- {0x04a0, {1|F|D, {0x04a1}}},
- {0x04a2, {1|F|D, {0x04a3}}},
- {0x04a4, {1|F|D, {0x04a5}}},
- {0x04a6, {1|F|D, {0x04a7}}},
- {0x04a8, {1|F|D, {0x04a9}}},
- {0x04aa, {1|F|D, {0x04ab}}},
- {0x04ac, {1|F|D, {0x04ad}}},
- {0x04ae, {1|F|D, {0x04af}}},
- {0x04b0, {1|F|D, {0x04b1}}},
- {0x04b2, {1|F|D, {0x04b3}}},
- {0x04b4, {1|F|D, {0x04b5}}},
- {0x04b6, {1|F|D, {0x04b7}}},
- {0x04b8, {1|F|D, {0x04b9}}},
- {0x04ba, {1|F|D, {0x04bb}}},
- {0x04bc, {1|F|D, {0x04bd}}},
- {0x04be, {1|F|D, {0x04bf}}},
- {0x04c0, {1|F|D, {0x04cf}}},
- {0x04c1, {1|F|D, {0x04c2}}},
- {0x04c3, {1|F|D, {0x04c4}}},
- {0x04c5, {1|F|D, {0x04c6}}},
- {0x04c7, {1|F|D, {0x04c8}}},
- {0x04c9, {1|F|D, {0x04ca}}},
- {0x04cb, {1|F|D, {0x04cc}}},
- {0x04cd, {1|F|D, {0x04ce}}},
- {0x04d0, {1|F|D, {0x04d1}}},
- {0x04d2, {1|F|D, {0x04d3}}},
- {0x04d4, {1|F|D, {0x04d5}}},
- {0x04d6, {1|F|D, {0x04d7}}},
- {0x04d8, {1|F|D, {0x04d9}}},
- {0x04da, {1|F|D, {0x04db}}},
- {0x04dc, {1|F|D, {0x04dd}}},
- {0x04de, {1|F|D, {0x04df}}},
- {0x04e0, {1|F|D, {0x04e1}}},
- {0x04e2, {1|F|D, {0x04e3}}},
- {0x04e4, {1|F|D, {0x04e5}}},
- {0x04e6, {1|F|D, {0x04e7}}},
- {0x04e8, {1|F|D, {0x04e9}}},
- {0x04ea, {1|F|D, {0x04eb}}},
- {0x04ec, {1|F|D, {0x04ed}}},
- {0x04ee, {1|F|D, {0x04ef}}},
- {0x04f0, {1|F|D, {0x04f1}}},
- {0x04f2, {1|F|D, {0x04f3}}},
- {0x04f4, {1|F|D, {0x04f5}}},
- {0x04f6, {1|F|D, {0x04f7}}},
- {0x04f8, {1|F|D, {0x04f9}}},
- {0x04fa, {1|F|D, {0x04fb}}},
- {0x04fc, {1|F|D, {0x04fd}}},
- {0x04fe, {1|F|D, {0x04ff}}},
- {0x0500, {1|F|D, {0x0501}}},
- {0x0502, {1|F|D, {0x0503}}},
- {0x0504, {1|F|D, {0x0505}}},
- {0x0506, {1|F|D, {0x0507}}},
- {0x0508, {1|F|D, {0x0509}}},
- {0x050a, {1|F|D, {0x050b}}},
- {0x050c, {1|F|D, {0x050d}}},
- {0x050e, {1|F|D, {0x050f}}},
- {0x0510, {1|F|D, {0x0511}}},
- {0x0512, {1|F|D, {0x0513}}},
- {0x0514, {1|F|D, {0x0515}}},
- {0x0516, {1|F|D, {0x0517}}},
- {0x0518, {1|F|D, {0x0519}}},
- {0x051a, {1|F|D, {0x051b}}},
- {0x051c, {1|F|D, {0x051d}}},
- {0x051e, {1|F|D, {0x051f}}},
- {0x0520, {1|F|D, {0x0521}}},
- {0x0522, {1|F|D, {0x0523}}},
- {0x0524, {1|F|D, {0x0525}}},
- {0x0526, {1|F|D, {0x0527}}},
- {0x0528, {1|F|D, {0x0529}}},
- {0x052a, {1|F|D, {0x052b}}},
- {0x052c, {1|F|D, {0x052d}}},
- {0x052e, {1|F|D, {0x052f}}},
- {0x0531, {1|F|D, {0x0561}}},
- {0x0532, {1|F|D, {0x0562}}},
- {0x0533, {1|F|D, {0x0563}}},
- {0x0534, {1|F|D, {0x0564}}},
- {0x0535, {1|F|D, {0x0565}}},
- {0x0536, {1|F|D, {0x0566}}},
- {0x0537, {1|F|D, {0x0567}}},
- {0x0538, {1|F|D, {0x0568}}},
- {0x0539, {1|F|D, {0x0569}}},
- {0x053a, {1|F|D, {0x056a}}},
- {0x053b, {1|F|D, {0x056b}}},
- {0x053c, {1|F|D, {0x056c}}},
- {0x053d, {1|F|D, {0x056d}}},
- {0x053e, {1|F|D, {0x056e}}},
- {0x053f, {1|F|D, {0x056f}}},
- {0x0540, {1|F|D, {0x0570}}},
- {0x0541, {1|F|D, {0x0571}}},
- {0x0542, {1|F|D, {0x0572}}},
- {0x0543, {1|F|D, {0x0573}}},
- {0x0544, {1|F|D, {0x0574}}},
- {0x0545, {1|F|D, {0x0575}}},
- {0x0546, {1|F|D, {0x0576}}},
- {0x0547, {1|F|D, {0x0577}}},
- {0x0548, {1|F|D, {0x0578}}},
- {0x0549, {1|F|D, {0x0579}}},
- {0x054a, {1|F|D, {0x057a}}},
- {0x054b, {1|F|D, {0x057b}}},
- {0x054c, {1|F|D, {0x057c}}},
- {0x054d, {1|F|D, {0x057d}}},
- {0x054e, {1|F|D, {0x057e}}},
- {0x054f, {1|F|D, {0x057f}}},
- {0x0550, {1|F|D, {0x0580}}},
- {0x0551, {1|F|D, {0x0581}}},
- {0x0552, {1|F|D, {0x0582}}},
- {0x0553, {1|F|D, {0x0583}}},
- {0x0554, {1|F|D, {0x0584}}},
- {0x0555, {1|F|D, {0x0585}}},
- {0x0556, {1|F|D, {0x0586}}},
- {0x0587, {2|F|ST|SU|I(41), {0x0565, 0x0582}}},
- {0x10a0, {1|F|D, {0x2d00}}},
- {0x10a1, {1|F|D, {0x2d01}}},
- {0x10a2, {1|F|D, {0x2d02}}},
- {0x10a3, {1|F|D, {0x2d03}}},
- {0x10a4, {1|F|D, {0x2d04}}},
- {0x10a5, {1|F|D, {0x2d05}}},
- {0x10a6, {1|F|D, {0x2d06}}},
- {0x10a7, {1|F|D, {0x2d07}}},
- {0x10a8, {1|F|D, {0x2d08}}},
- {0x10a9, {1|F|D, {0x2d09}}},
- {0x10aa, {1|F|D, {0x2d0a}}},
- {0x10ab, {1|F|D, {0x2d0b}}},
- {0x10ac, {1|F|D, {0x2d0c}}},
- {0x10ad, {1|F|D, {0x2d0d}}},
- {0x10ae, {1|F|D, {0x2d0e}}},
- {0x10af, {1|F|D, {0x2d0f}}},
- {0x10b0, {1|F|D, {0x2d10}}},
- {0x10b1, {1|F|D, {0x2d11}}},
- {0x10b2, {1|F|D, {0x2d12}}},
- {0x10b3, {1|F|D, {0x2d13}}},
- {0x10b4, {1|F|D, {0x2d14}}},
- {0x10b5, {1|F|D, {0x2d15}}},
- {0x10b6, {1|F|D, {0x2d16}}},
- {0x10b7, {1|F|D, {0x2d17}}},
- {0x10b8, {1|F|D, {0x2d18}}},
- {0x10b9, {1|F|D, {0x2d19}}},
- {0x10ba, {1|F|D, {0x2d1a}}},
- {0x10bb, {1|F|D, {0x2d1b}}},
- {0x10bc, {1|F|D, {0x2d1c}}},
- {0x10bd, {1|F|D, {0x2d1d}}},
- {0x10be, {1|F|D, {0x2d1e}}},
- {0x10bf, {1|F|D, {0x2d1f}}},
- {0x10c0, {1|F|D, {0x2d20}}},
- {0x10c1, {1|F|D, {0x2d21}}},
- {0x10c2, {1|F|D, {0x2d22}}},
- {0x10c3, {1|F|D, {0x2d23}}},
- {0x10c4, {1|F|D, {0x2d24}}},
- {0x10c5, {1|F|D, {0x2d25}}},
- {0x10c7, {1|F|D, {0x2d27}}},
- {0x10cd, {1|F|D, {0x2d2d}}},
- {0x13f8, {1|F|U, {0x13f0}}},
- {0x13f9, {1|F|U, {0x13f1}}},
- {0x13fa, {1|F|U, {0x13f2}}},
- {0x13fb, {1|F|U, {0x13f3}}},
- {0x13fc, {1|F|U, {0x13f4}}},
- {0x13fd, {1|F|U, {0x13f5}}},
- {0x1c80, {1|F|SU|I(45), {0x0432}}},
- {0x1c81, {1|F|SU|I(46), {0x0434}}},
- {0x1c82, {1|F|SU|I(47), {0x043e}}},
- {0x1c83, {1|F|SU|I(48), {0x0441}}},
- {0x1c84, {1|F|SU|I(49), {0x0442}}},
- {0x1c85, {1|F|SU|I(50), {0x0442}}},
- {0x1c86, {1|F|SU|I(51), {0x044a}}},
- {0x1c87, {1|F|SU|I(52), {0x0463}}},
- {0x1c88, {1|F|SU|I(53), {0xa64b}}},
- {0x1e00, {1|F|D, {0x1e01}}},
- {0x1e02, {1|F|D, {0x1e03}}},
- {0x1e04, {1|F|D, {0x1e05}}},
- {0x1e06, {1|F|D, {0x1e07}}},
- {0x1e08, {1|F|D, {0x1e09}}},
- {0x1e0a, {1|F|D, {0x1e0b}}},
- {0x1e0c, {1|F|D, {0x1e0d}}},
- {0x1e0e, {1|F|D, {0x1e0f}}},
- {0x1e10, {1|F|D, {0x1e11}}},
- {0x1e12, {1|F|D, {0x1e13}}},
- {0x1e14, {1|F|D, {0x1e15}}},
- {0x1e16, {1|F|D, {0x1e17}}},
- {0x1e18, {1|F|D, {0x1e19}}},
- {0x1e1a, {1|F|D, {0x1e1b}}},
- {0x1e1c, {1|F|D, {0x1e1d}}},
- {0x1e1e, {1|F|D, {0x1e1f}}},
- {0x1e20, {1|F|D, {0x1e21}}},
- {0x1e22, {1|F|D, {0x1e23}}},
- {0x1e24, {1|F|D, {0x1e25}}},
- {0x1e26, {1|F|D, {0x1e27}}},
- {0x1e28, {1|F|D, {0x1e29}}},
- {0x1e2a, {1|F|D, {0x1e2b}}},
- {0x1e2c, {1|F|D, {0x1e2d}}},
- {0x1e2e, {1|F|D, {0x1e2f}}},
- {0x1e30, {1|F|D, {0x1e31}}},
- {0x1e32, {1|F|D, {0x1e33}}},
- {0x1e34, {1|F|D, {0x1e35}}},
- {0x1e36, {1|F|D, {0x1e37}}},
- {0x1e38, {1|F|D, {0x1e39}}},
- {0x1e3a, {1|F|D, {0x1e3b}}},
- {0x1e3c, {1|F|D, {0x1e3d}}},
- {0x1e3e, {1|F|D, {0x1e3f}}},
- {0x1e40, {1|F|D, {0x1e41}}},
- {0x1e42, {1|F|D, {0x1e43}}},
- {0x1e44, {1|F|D, {0x1e45}}},
- {0x1e46, {1|F|D, {0x1e47}}},
- {0x1e48, {1|F|D, {0x1e49}}},
- {0x1e4a, {1|F|D, {0x1e4b}}},
- {0x1e4c, {1|F|D, {0x1e4d}}},
- {0x1e4e, {1|F|D, {0x1e4f}}},
- {0x1e50, {1|F|D, {0x1e51}}},
- {0x1e52, {1|F|D, {0x1e53}}},
- {0x1e54, {1|F|D, {0x1e55}}},
- {0x1e56, {1|F|D, {0x1e57}}},
- {0x1e58, {1|F|D, {0x1e59}}},
- {0x1e5a, {1|F|D, {0x1e5b}}},
- {0x1e5c, {1|F|D, {0x1e5d}}},
- {0x1e5e, {1|F|D, {0x1e5f}}},
- {0x1e60, {1|F|D, {0x1e61}}},
- {0x1e62, {1|F|D, {0x1e63}}},
- {0x1e64, {1|F|D, {0x1e65}}},
- {0x1e66, {1|F|D, {0x1e67}}},
- {0x1e68, {1|F|D, {0x1e69}}},
- {0x1e6a, {1|F|D, {0x1e6b}}},
- {0x1e6c, {1|F|D, {0x1e6d}}},
- {0x1e6e, {1|F|D, {0x1e6f}}},
- {0x1e70, {1|F|D, {0x1e71}}},
- {0x1e72, {1|F|D, {0x1e73}}},
- {0x1e74, {1|F|D, {0x1e75}}},
- {0x1e76, {1|F|D, {0x1e77}}},
- {0x1e78, {1|F|D, {0x1e79}}},
- {0x1e7a, {1|F|D, {0x1e7b}}},
- {0x1e7c, {1|F|D, {0x1e7d}}},
- {0x1e7e, {1|F|D, {0x1e7f}}},
- {0x1e80, {1|F|D, {0x1e81}}},
- {0x1e82, {1|F|D, {0x1e83}}},
- {0x1e84, {1|F|D, {0x1e85}}},
- {0x1e86, {1|F|D, {0x1e87}}},
- {0x1e88, {1|F|D, {0x1e89}}},
- {0x1e8a, {1|F|D, {0x1e8b}}},
- {0x1e8c, {1|F|D, {0x1e8d}}},
- {0x1e8e, {1|F|D, {0x1e8f}}},
- {0x1e90, {1|F|D, {0x1e91}}},
- {0x1e92, {1|F|D, {0x1e93}}},
- {0x1e94, {1|F|D, {0x1e95}}},
- {0x1e96, {2|F|SU|I(54), {0x0068, 0x0331}}},
- {0x1e97, {2|F|SU|I(56), {0x0074, 0x0308}}},
- {0x1e98, {2|F|SU|I(58), {0x0077, 0x030a}}},
- {0x1e99, {2|F|SU|I(60), {0x0079, 0x030a}}},
- {0x1e9a, {2|F|SU|I(62), {0x0061, 0x02be}}},
- {0x1e9b, {1|F|SU|I(64), {0x1e61}}},
- {0x1e9e, {2|F|SL|I(65), {0x0073, 0x0073}}},
- {0x1ea0, {1|F|D, {0x1ea1}}},
- {0x1ea2, {1|F|D, {0x1ea3}}},
- {0x1ea4, {1|F|D, {0x1ea5}}},
- {0x1ea6, {1|F|D, {0x1ea7}}},
- {0x1ea8, {1|F|D, {0x1ea9}}},
- {0x1eaa, {1|F|D, {0x1eab}}},
- {0x1eac, {1|F|D, {0x1ead}}},
- {0x1eae, {1|F|D, {0x1eaf}}},
- {0x1eb0, {1|F|D, {0x1eb1}}},
- {0x1eb2, {1|F|D, {0x1eb3}}},
- {0x1eb4, {1|F|D, {0x1eb5}}},
- {0x1eb6, {1|F|D, {0x1eb7}}},
- {0x1eb8, {1|F|D, {0x1eb9}}},
- {0x1eba, {1|F|D, {0x1ebb}}},
- {0x1ebc, {1|F|D, {0x1ebd}}},
- {0x1ebe, {1|F|D, {0x1ebf}}},
- {0x1ec0, {1|F|D, {0x1ec1}}},
- {0x1ec2, {1|F|D, {0x1ec3}}},
- {0x1ec4, {1|F|D, {0x1ec5}}},
- {0x1ec6, {1|F|D, {0x1ec7}}},
- {0x1ec8, {1|F|D, {0x1ec9}}},
- {0x1eca, {1|F|D, {0x1ecb}}},
- {0x1ecc, {1|F|D, {0x1ecd}}},
- {0x1ece, {1|F|D, {0x1ecf}}},
- {0x1ed0, {1|F|D, {0x1ed1}}},
- {0x1ed2, {1|F|D, {0x1ed3}}},
- {0x1ed4, {1|F|D, {0x1ed5}}},
- {0x1ed6, {1|F|D, {0x1ed7}}},
- {0x1ed8, {1|F|D, {0x1ed9}}},
- {0x1eda, {1|F|D, {0x1edb}}},
- {0x1edc, {1|F|D, {0x1edd}}},
- {0x1ede, {1|F|D, {0x1edf}}},
- {0x1ee0, {1|F|D, {0x1ee1}}},
- {0x1ee2, {1|F|D, {0x1ee3}}},
- {0x1ee4, {1|F|D, {0x1ee5}}},
- {0x1ee6, {1|F|D, {0x1ee7}}},
- {0x1ee8, {1|F|D, {0x1ee9}}},
- {0x1eea, {1|F|D, {0x1eeb}}},
- {0x1eec, {1|F|D, {0x1eed}}},
- {0x1eee, {1|F|D, {0x1eef}}},
- {0x1ef0, {1|F|D, {0x1ef1}}},
- {0x1ef2, {1|F|D, {0x1ef3}}},
- {0x1ef4, {1|F|D, {0x1ef5}}},
- {0x1ef6, {1|F|D, {0x1ef7}}},
- {0x1ef8, {1|F|D, {0x1ef9}}},
- {0x1efa, {1|F|D, {0x1efb}}},
- {0x1efc, {1|F|D, {0x1efd}}},
- {0x1efe, {1|F|D, {0x1eff}}},
- {0x1f08, {1|F|D, {0x1f00}}},
- {0x1f09, {1|F|D, {0x1f01}}},
- {0x1f0a, {1|F|D, {0x1f02}}},
- {0x1f0b, {1|F|D, {0x1f03}}},
- {0x1f0c, {1|F|D, {0x1f04}}},
- {0x1f0d, {1|F|D, {0x1f05}}},
- {0x1f0e, {1|F|D, {0x1f06}}},
- {0x1f0f, {1|F|D, {0x1f07}}},
- {0x1f18, {1|F|D, {0x1f10}}},
- {0x1f19, {1|F|D, {0x1f11}}},
- {0x1f1a, {1|F|D, {0x1f12}}},
- {0x1f1b, {1|F|D, {0x1f13}}},
- {0x1f1c, {1|F|D, {0x1f14}}},
- {0x1f1d, {1|F|D, {0x1f15}}},
- {0x1f28, {1|F|D, {0x1f20}}},
- {0x1f29, {1|F|D, {0x1f21}}},
- {0x1f2a, {1|F|D, {0x1f22}}},
- {0x1f2b, {1|F|D, {0x1f23}}},
- {0x1f2c, {1|F|D, {0x1f24}}},
- {0x1f2d, {1|F|D, {0x1f25}}},
- {0x1f2e, {1|F|D, {0x1f26}}},
- {0x1f2f, {1|F|D, {0x1f27}}},
- {0x1f38, {1|F|D, {0x1f30}}},
- {0x1f39, {1|F|D, {0x1f31}}},
- {0x1f3a, {1|F|D, {0x1f32}}},
- {0x1f3b, {1|F|D, {0x1f33}}},
- {0x1f3c, {1|F|D, {0x1f34}}},
- {0x1f3d, {1|F|D, {0x1f35}}},
- {0x1f3e, {1|F|D, {0x1f36}}},
- {0x1f3f, {1|F|D, {0x1f37}}},
- {0x1f48, {1|F|D, {0x1f40}}},
- {0x1f49, {1|F|D, {0x1f41}}},
- {0x1f4a, {1|F|D, {0x1f42}}},
- {0x1f4b, {1|F|D, {0x1f43}}},
- {0x1f4c, {1|F|D, {0x1f44}}},
- {0x1f4d, {1|F|D, {0x1f45}}},
- {0x1f50, {2|F|SU|I(66), {0x03c5, 0x0313}}},
- {0x1f52, {3|F|SU|I(68), {0x03c5, 0x0313, 0x0300}}},
- {0x1f54, {3|F|SU|I(71), {0x03c5, 0x0313, 0x0301}}},
- {0x1f56, {3|F|SU|I(74), {0x03c5, 0x0313, 0x0342}}},
- {0x1f59, {1|F|D, {0x1f51}}},
- {0x1f5b, {1|F|D, {0x1f53}}},
- {0x1f5d, {1|F|D, {0x1f55}}},
- {0x1f5f, {1|F|D, {0x1f57}}},
- {0x1f68, {1|F|D, {0x1f60}}},
- {0x1f69, {1|F|D, {0x1f61}}},
- {0x1f6a, {1|F|D, {0x1f62}}},
- {0x1f6b, {1|F|D, {0x1f63}}},
- {0x1f6c, {1|F|D, {0x1f64}}},
- {0x1f6d, {1|F|D, {0x1f65}}},
- {0x1f6e, {1|F|D, {0x1f66}}},
- {0x1f6f, {1|F|D, {0x1f67}}},
- {0x1f80, {2|F|ST|SU|I(77), {0x1f00, 0x03b9}}},
- {0x1f81, {2|F|ST|SU|I(80), {0x1f01, 0x03b9}}},
- {0x1f82, {2|F|ST|SU|I(83), {0x1f02, 0x03b9}}},
- {0x1f83, {2|F|ST|SU|I(86), {0x1f03, 0x03b9}}},
- {0x1f84, {2|F|ST|SU|I(89), {0x1f04, 0x03b9}}},
- {0x1f85, {2|F|ST|SU|I(92), {0x1f05, 0x03b9}}},
- {0x1f86, {2|F|ST|SU|I(95), {0x1f06, 0x03b9}}},
- {0x1f87, {2|F|ST|SU|I(98), {0x1f07, 0x03b9}}},
- {0x1f88, {2|F|IT|SL|SU|I(101), {0x1f00, 0x03b9}}},
- {0x1f89, {2|F|IT|SL|SU|I(106), {0x1f01, 0x03b9}}},
- {0x1f8a, {2|F|IT|SL|SU|I(111), {0x1f02, 0x03b9}}},
- {0x1f8b, {2|F|IT|SL|SU|I(116), {0x1f03, 0x03b9}}},
- {0x1f8c, {2|F|IT|SL|SU|I(121), {0x1f04, 0x03b9}}},
- {0x1f8d, {2|F|IT|SL|SU|I(126), {0x1f05, 0x03b9}}},
- {0x1f8e, {2|F|IT|SL|SU|I(131), {0x1f06, 0x03b9}}},
- {0x1f8f, {2|F|IT|SL|SU|I(136), {0x1f07, 0x03b9}}},
- {0x1f90, {2|F|ST|SU|I(141), {0x1f20, 0x03b9}}},
- {0x1f91, {2|F|ST|SU|I(144), {0x1f21, 0x03b9}}},
- {0x1f92, {2|F|ST|SU|I(147), {0x1f22, 0x03b9}}},
- {0x1f93, {2|F|ST|SU|I(150), {0x1f23, 0x03b9}}},
- {0x1f94, {2|F|ST|SU|I(153), {0x1f24, 0x03b9}}},
- {0x1f95, {2|F|ST|SU|I(156), {0x1f25, 0x03b9}}},
- {0x1f96, {2|F|ST|SU|I(159), {0x1f26, 0x03b9}}},
- {0x1f97, {2|F|ST|SU|I(162), {0x1f27, 0x03b9}}},
- {0x1f98, {2|F|IT|SL|SU|I(165), {0x1f20, 0x03b9}}},
- {0x1f99, {2|F|IT|SL|SU|I(170), {0x1f21, 0x03b9}}},
- {0x1f9a, {2|F|IT|SL|SU|I(175), {0x1f22, 0x03b9}}},
- {0x1f9b, {2|F|IT|SL|SU|I(180), {0x1f23, 0x03b9}}},
- {0x1f9c, {2|F|IT|SL|SU|I(185), {0x1f24, 0x03b9}}},
- {0x1f9d, {2|F|IT|SL|SU|I(190), {0x1f25, 0x03b9}}},
- {0x1f9e, {2|F|IT|SL|SU|I(195), {0x1f26, 0x03b9}}},
- {0x1f9f, {2|F|IT|SL|SU|I(200), {0x1f27, 0x03b9}}},
- {0x1fa0, {2|F|ST|SU|I(205), {0x1f60, 0x03b9}}},
- {0x1fa1, {2|F|ST|SU|I(208), {0x1f61, 0x03b9}}},
- {0x1fa2, {2|F|ST|SU|I(211), {0x1f62, 0x03b9}}},
- {0x1fa3, {2|F|ST|SU|I(214), {0x1f63, 0x03b9}}},
- {0x1fa4, {2|F|ST|SU|I(217), {0x1f64, 0x03b9}}},
- {0x1fa5, {2|F|ST|SU|I(220), {0x1f65, 0x03b9}}},
- {0x1fa6, {2|F|ST|SU|I(223), {0x1f66, 0x03b9}}},
- {0x1fa7, {2|F|ST|SU|I(226), {0x1f67, 0x03b9}}},
- {0x1fa8, {2|F|IT|SL|SU|I(229), {0x1f60, 0x03b9}}},
- {0x1fa9, {2|F|IT|SL|SU|I(234), {0x1f61, 0x03b9}}},
- {0x1faa, {2|F|IT|SL|SU|I(239), {0x1f62, 0x03b9}}},
- {0x1fab, {2|F|IT|SL|SU|I(244), {0x1f63, 0x03b9}}},
- {0x1fac, {2|F|IT|SL|SU|I(249), {0x1f64, 0x03b9}}},
- {0x1fad, {2|F|IT|SL|SU|I(254), {0x1f65, 0x03b9}}},
- {0x1fae, {2|F|IT|SL|SU|I(259), {0x1f66, 0x03b9}}},
- {0x1faf, {2|F|IT|SL|SU|I(264), {0x1f67, 0x03b9}}},
- {0x1fb2, {2|F|ST|SU|I(269), {0x1f70, 0x03b9}}},
- {0x1fb3, {2|F|ST|SU|I(273), {0x03b1, 0x03b9}}},
- {0x1fb4, {2|F|ST|SU|I(276), {0x03ac, 0x03b9}}},
- {0x1fb6, {2|F|SU|I(280), {0x03b1, 0x0342}}},
- {0x1fb7, {3|F|ST|SU|I(282), {0x03b1, 0x0342, 0x03b9}}},
- {0x1fb8, {1|F|D, {0x1fb0}}},
- {0x1fb9, {1|F|D, {0x1fb1}}},
- {0x1fba, {1|F|D, {0x1f70}}},
- {0x1fbb, {1|F|D, {0x1f71}}},
- {0x1fbc, {2|F|IT|SL|SU|I(288), {0x03b1, 0x03b9}}},
- {0x1fbe, {1|F|SU|I(293), {0x03b9}}},
- {0x1fc2, {2|F|ST|SU|I(294), {0x1f74, 0x03b9}}},
- {0x1fc3, {2|F|ST|SU|I(298), {0x03b7, 0x03b9}}},
- {0x1fc4, {2|F|ST|SU|I(301), {0x03ae, 0x03b9}}},
- {0x1fc6, {2|F|SU|I(305), {0x03b7, 0x0342}}},
- {0x1fc7, {3|F|ST|SU|I(307), {0x03b7, 0x0342, 0x03b9}}},
- {0x1fc8, {1|F|D, {0x1f72}}},
- {0x1fc9, {1|F|D, {0x1f73}}},
- {0x1fca, {1|F|D, {0x1f74}}},
- {0x1fcb, {1|F|D, {0x1f75}}},
- {0x1fcc, {2|F|IT|SL|SU|I(313), {0x03b7, 0x03b9}}},
- {0x1fd2, {3|F|SU|I(318), {0x03b9, 0x0308, 0x0300}}},
- {0x1fd3, {3|F|SU|I(321), {0x03b9, 0x0308, 0x0301}}},
- {0x1fd6, {2|F|SU|I(324), {0x03b9, 0x0342}}},
- {0x1fd7, {3|F|SU|I(326), {0x03b9, 0x0308, 0x0342}}},
- {0x1fd8, {1|F|D, {0x1fd0}}},
- {0x1fd9, {1|F|D, {0x1fd1}}},
- {0x1fda, {1|F|D, {0x1f76}}},
- {0x1fdb, {1|F|D, {0x1f77}}},
- {0x1fe2, {3|F|SU|I(329), {0x03c5, 0x0308, 0x0300}}},
- {0x1fe3, {3|F|SU|I(332), {0x03c5, 0x0308, 0x0301}}},
- {0x1fe4, {2|F|SU|I(335), {0x03c1, 0x0313}}},
- {0x1fe6, {2|F|SU|I(337), {0x03c5, 0x0342}}},
- {0x1fe7, {3|F|SU|I(339), {0x03c5, 0x0308, 0x0342}}},
- {0x1fe8, {1|F|D, {0x1fe0}}},
- {0x1fe9, {1|F|D, {0x1fe1}}},
- {0x1fea, {1|F|D, {0x1f7a}}},
- {0x1feb, {1|F|D, {0x1f7b}}},
- {0x1fec, {1|F|D, {0x1fe5}}},
- {0x1ff2, {2|F|ST|SU|I(342), {0x1f7c, 0x03b9}}},
- {0x1ff3, {2|F|ST|SU|I(346), {0x03c9, 0x03b9}}},
- {0x1ff4, {2|F|ST|SU|I(349), {0x03ce, 0x03b9}}},
- {0x1ff6, {2|F|SU|I(353), {0x03c9, 0x0342}}},
- {0x1ff7, {3|F|ST|SU|I(355), {0x03c9, 0x0342, 0x03b9}}},
- {0x1ff8, {1|F|D, {0x1f78}}},
- {0x1ff9, {1|F|D, {0x1f79}}},
- {0x1ffa, {1|F|D, {0x1f7c}}},
- {0x1ffb, {1|F|D, {0x1f7d}}},
- {0x1ffc, {2|F|IT|SL|SU|I(361), {0x03c9, 0x03b9}}},
- {0x2126, {1|F|D, {0x03c9}}},
- {0x212a, {1|F|D, {0x006b}}},
- {0x212b, {1|F|D, {0x00e5}}},
- {0x2132, {1|F|D, {0x214e}}},
- {0x2160, {1|F|D, {0x2170}}},
- {0x2161, {1|F|D, {0x2171}}},
- {0x2162, {1|F|D, {0x2172}}},
- {0x2163, {1|F|D, {0x2173}}},
- {0x2164, {1|F|D, {0x2174}}},
- {0x2165, {1|F|D, {0x2175}}},
- {0x2166, {1|F|D, {0x2176}}},
- {0x2167, {1|F|D, {0x2177}}},
- {0x2168, {1|F|D, {0x2178}}},
- {0x2169, {1|F|D, {0x2179}}},
- {0x216a, {1|F|D, {0x217a}}},
- {0x216b, {1|F|D, {0x217b}}},
- {0x216c, {1|F|D, {0x217c}}},
- {0x216d, {1|F|D, {0x217d}}},
- {0x216e, {1|F|D, {0x217e}}},
- {0x216f, {1|F|D, {0x217f}}},
- {0x2183, {1|F|D, {0x2184}}},
- {0x24b6, {1|F|D, {0x24d0}}},
- {0x24b7, {1|F|D, {0x24d1}}},
- {0x24b8, {1|F|D, {0x24d2}}},
- {0x24b9, {1|F|D, {0x24d3}}},
- {0x24ba, {1|F|D, {0x24d4}}},
- {0x24bb, {1|F|D, {0x24d5}}},
- {0x24bc, {1|F|D, {0x24d6}}},
- {0x24bd, {1|F|D, {0x24d7}}},
- {0x24be, {1|F|D, {0x24d8}}},
- {0x24bf, {1|F|D, {0x24d9}}},
- {0x24c0, {1|F|D, {0x24da}}},
- {0x24c1, {1|F|D, {0x24db}}},
- {0x24c2, {1|F|D, {0x24dc}}},
- {0x24c3, {1|F|D, {0x24dd}}},
- {0x24c4, {1|F|D, {0x24de}}},
- {0x24c5, {1|F|D, {0x24df}}},
- {0x24c6, {1|F|D, {0x24e0}}},
- {0x24c7, {1|F|D, {0x24e1}}},
- {0x24c8, {1|F|D, {0x24e2}}},
- {0x24c9, {1|F|D, {0x24e3}}},
- {0x24ca, {1|F|D, {0x24e4}}},
- {0x24cb, {1|F|D, {0x24e5}}},
- {0x24cc, {1|F|D, {0x24e6}}},
- {0x24cd, {1|F|D, {0x24e7}}},
- {0x24ce, {1|F|D, {0x24e8}}},
- {0x24cf, {1|F|D, {0x24e9}}},
- {0x2c00, {1|F|D, {0x2c30}}},
- {0x2c01, {1|F|D, {0x2c31}}},
- {0x2c02, {1|F|D, {0x2c32}}},
- {0x2c03, {1|F|D, {0x2c33}}},
- {0x2c04, {1|F|D, {0x2c34}}},
- {0x2c05, {1|F|D, {0x2c35}}},
- {0x2c06, {1|F|D, {0x2c36}}},
- {0x2c07, {1|F|D, {0x2c37}}},
- {0x2c08, {1|F|D, {0x2c38}}},
- {0x2c09, {1|F|D, {0x2c39}}},
- {0x2c0a, {1|F|D, {0x2c3a}}},
- {0x2c0b, {1|F|D, {0x2c3b}}},
- {0x2c0c, {1|F|D, {0x2c3c}}},
- {0x2c0d, {1|F|D, {0x2c3d}}},
- {0x2c0e, {1|F|D, {0x2c3e}}},
- {0x2c0f, {1|F|D, {0x2c3f}}},
- {0x2c10, {1|F|D, {0x2c40}}},
- {0x2c11, {1|F|D, {0x2c41}}},
- {0x2c12, {1|F|D, {0x2c42}}},
- {0x2c13, {1|F|D, {0x2c43}}},
- {0x2c14, {1|F|D, {0x2c44}}},
- {0x2c15, {1|F|D, {0x2c45}}},
- {0x2c16, {1|F|D, {0x2c46}}},
- {0x2c17, {1|F|D, {0x2c47}}},
- {0x2c18, {1|F|D, {0x2c48}}},
- {0x2c19, {1|F|D, {0x2c49}}},
- {0x2c1a, {1|F|D, {0x2c4a}}},
- {0x2c1b, {1|F|D, {0x2c4b}}},
- {0x2c1c, {1|F|D, {0x2c4c}}},
- {0x2c1d, {1|F|D, {0x2c4d}}},
- {0x2c1e, {1|F|D, {0x2c4e}}},
- {0x2c1f, {1|F|D, {0x2c4f}}},
- {0x2c20, {1|F|D, {0x2c50}}},
- {0x2c21, {1|F|D, {0x2c51}}},
- {0x2c22, {1|F|D, {0x2c52}}},
- {0x2c23, {1|F|D, {0x2c53}}},
- {0x2c24, {1|F|D, {0x2c54}}},
- {0x2c25, {1|F|D, {0x2c55}}},
- {0x2c26, {1|F|D, {0x2c56}}},
- {0x2c27, {1|F|D, {0x2c57}}},
- {0x2c28, {1|F|D, {0x2c58}}},
- {0x2c29, {1|F|D, {0x2c59}}},
- {0x2c2a, {1|F|D, {0x2c5a}}},
- {0x2c2b, {1|F|D, {0x2c5b}}},
- {0x2c2c, {1|F|D, {0x2c5c}}},
- {0x2c2d, {1|F|D, {0x2c5d}}},
- {0x2c2e, {1|F|D, {0x2c5e}}},
- {0x2c60, {1|F|D, {0x2c61}}},
- {0x2c62, {1|F|D, {0x026b}}},
- {0x2c63, {1|F|D, {0x1d7d}}},
- {0x2c64, {1|F|D, {0x027d}}},
- {0x2c67, {1|F|D, {0x2c68}}},
- {0x2c69, {1|F|D, {0x2c6a}}},
- {0x2c6b, {1|F|D, {0x2c6c}}},
- {0x2c6d, {1|F|D, {0x0251}}},
- {0x2c6e, {1|F|D, {0x0271}}},
- {0x2c6f, {1|F|D, {0x0250}}},
- {0x2c70, {1|F|D, {0x0252}}},
- {0x2c72, {1|F|D, {0x2c73}}},
- {0x2c75, {1|F|D, {0x2c76}}},
- {0x2c7e, {1|F|D, {0x023f}}},
- {0x2c7f, {1|F|D, {0x0240}}},
- {0x2c80, {1|F|D, {0x2c81}}},
- {0x2c82, {1|F|D, {0x2c83}}},
- {0x2c84, {1|F|D, {0x2c85}}},
- {0x2c86, {1|F|D, {0x2c87}}},
- {0x2c88, {1|F|D, {0x2c89}}},
- {0x2c8a, {1|F|D, {0x2c8b}}},
- {0x2c8c, {1|F|D, {0x2c8d}}},
- {0x2c8e, {1|F|D, {0x2c8f}}},
- {0x2c90, {1|F|D, {0x2c91}}},
- {0x2c92, {1|F|D, {0x2c93}}},
- {0x2c94, {1|F|D, {0x2c95}}},
- {0x2c96, {1|F|D, {0x2c97}}},
- {0x2c98, {1|F|D, {0x2c99}}},
- {0x2c9a, {1|F|D, {0x2c9b}}},
- {0x2c9c, {1|F|D, {0x2c9d}}},
- {0x2c9e, {1|F|D, {0x2c9f}}},
- {0x2ca0, {1|F|D, {0x2ca1}}},
- {0x2ca2, {1|F|D, {0x2ca3}}},
- {0x2ca4, {1|F|D, {0x2ca5}}},
- {0x2ca6, {1|F|D, {0x2ca7}}},
- {0x2ca8, {1|F|D, {0x2ca9}}},
- {0x2caa, {1|F|D, {0x2cab}}},
- {0x2cac, {1|F|D, {0x2cad}}},
- {0x2cae, {1|F|D, {0x2caf}}},
- {0x2cb0, {1|F|D, {0x2cb1}}},
- {0x2cb2, {1|F|D, {0x2cb3}}},
- {0x2cb4, {1|F|D, {0x2cb5}}},
- {0x2cb6, {1|F|D, {0x2cb7}}},
- {0x2cb8, {1|F|D, {0x2cb9}}},
- {0x2cba, {1|F|D, {0x2cbb}}},
- {0x2cbc, {1|F|D, {0x2cbd}}},
- {0x2cbe, {1|F|D, {0x2cbf}}},
- {0x2cc0, {1|F|D, {0x2cc1}}},
- {0x2cc2, {1|F|D, {0x2cc3}}},
- {0x2cc4, {1|F|D, {0x2cc5}}},
- {0x2cc6, {1|F|D, {0x2cc7}}},
- {0x2cc8, {1|F|D, {0x2cc9}}},
- {0x2cca, {1|F|D, {0x2ccb}}},
- {0x2ccc, {1|F|D, {0x2ccd}}},
- {0x2cce, {1|F|D, {0x2ccf}}},
- {0x2cd0, {1|F|D, {0x2cd1}}},
- {0x2cd2, {1|F|D, {0x2cd3}}},
- {0x2cd4, {1|F|D, {0x2cd5}}},
- {0x2cd6, {1|F|D, {0x2cd7}}},
- {0x2cd8, {1|F|D, {0x2cd9}}},
- {0x2cda, {1|F|D, {0x2cdb}}},
- {0x2cdc, {1|F|D, {0x2cdd}}},
- {0x2cde, {1|F|D, {0x2cdf}}},
- {0x2ce0, {1|F|D, {0x2ce1}}},
- {0x2ce2, {1|F|D, {0x2ce3}}},
- {0x2ceb, {1|F|D, {0x2cec}}},
- {0x2ced, {1|F|D, {0x2cee}}},
- {0x2cf2, {1|F|D, {0x2cf3}}},
- {0xa640, {1|F|D, {0xa641}}},
- {0xa642, {1|F|D, {0xa643}}},
- {0xa644, {1|F|D, {0xa645}}},
- {0xa646, {1|F|D, {0xa647}}},
- {0xa648, {1|F|D, {0xa649}}},
- {0xa64a, {1|F|D, {0xa64b}}},
- {0xa64c, {1|F|D, {0xa64d}}},
- {0xa64e, {1|F|D, {0xa64f}}},
- {0xa650, {1|F|D, {0xa651}}},
- {0xa652, {1|F|D, {0xa653}}},
- {0xa654, {1|F|D, {0xa655}}},
- {0xa656, {1|F|D, {0xa657}}},
- {0xa658, {1|F|D, {0xa659}}},
- {0xa65a, {1|F|D, {0xa65b}}},
- {0xa65c, {1|F|D, {0xa65d}}},
- {0xa65e, {1|F|D, {0xa65f}}},
- {0xa660, {1|F|D, {0xa661}}},
- {0xa662, {1|F|D, {0xa663}}},
- {0xa664, {1|F|D, {0xa665}}},
- {0xa666, {1|F|D, {0xa667}}},
- {0xa668, {1|F|D, {0xa669}}},
- {0xa66a, {1|F|D, {0xa66b}}},
- {0xa66c, {1|F|D, {0xa66d}}},
- {0xa680, {1|F|D, {0xa681}}},
- {0xa682, {1|F|D, {0xa683}}},
- {0xa684, {1|F|D, {0xa685}}},
- {0xa686, {1|F|D, {0xa687}}},
- {0xa688, {1|F|D, {0xa689}}},
- {0xa68a, {1|F|D, {0xa68b}}},
- {0xa68c, {1|F|D, {0xa68d}}},
- {0xa68e, {1|F|D, {0xa68f}}},
- {0xa690, {1|F|D, {0xa691}}},
- {0xa692, {1|F|D, {0xa693}}},
- {0xa694, {1|F|D, {0xa695}}},
- {0xa696, {1|F|D, {0xa697}}},
- {0xa698, {1|F|D, {0xa699}}},
- {0xa69a, {1|F|D, {0xa69b}}},
- {0xa722, {1|F|D, {0xa723}}},
- {0xa724, {1|F|D, {0xa725}}},
- {0xa726, {1|F|D, {0xa727}}},
- {0xa728, {1|F|D, {0xa729}}},
- {0xa72a, {1|F|D, {0xa72b}}},
- {0xa72c, {1|F|D, {0xa72d}}},
- {0xa72e, {1|F|D, {0xa72f}}},
- {0xa732, {1|F|D, {0xa733}}},
- {0xa734, {1|F|D, {0xa735}}},
- {0xa736, {1|F|D, {0xa737}}},
- {0xa738, {1|F|D, {0xa739}}},
- {0xa73a, {1|F|D, {0xa73b}}},
- {0xa73c, {1|F|D, {0xa73d}}},
- {0xa73e, {1|F|D, {0xa73f}}},
- {0xa740, {1|F|D, {0xa741}}},
- {0xa742, {1|F|D, {0xa743}}},
- {0xa744, {1|F|D, {0xa745}}},
- {0xa746, {1|F|D, {0xa747}}},
- {0xa748, {1|F|D, {0xa749}}},
- {0xa74a, {1|F|D, {0xa74b}}},
- {0xa74c, {1|F|D, {0xa74d}}},
- {0xa74e, {1|F|D, {0xa74f}}},
- {0xa750, {1|F|D, {0xa751}}},
- {0xa752, {1|F|D, {0xa753}}},
- {0xa754, {1|F|D, {0xa755}}},
- {0xa756, {1|F|D, {0xa757}}},
- {0xa758, {1|F|D, {0xa759}}},
- {0xa75a, {1|F|D, {0xa75b}}},
- {0xa75c, {1|F|D, {0xa75d}}},
- {0xa75e, {1|F|D, {0xa75f}}},
- {0xa760, {1|F|D, {0xa761}}},
- {0xa762, {1|F|D, {0xa763}}},
- {0xa764, {1|F|D, {0xa765}}},
- {0xa766, {1|F|D, {0xa767}}},
- {0xa768, {1|F|D, {0xa769}}},
- {0xa76a, {1|F|D, {0xa76b}}},
- {0xa76c, {1|F|D, {0xa76d}}},
- {0xa76e, {1|F|D, {0xa76f}}},
- {0xa779, {1|F|D, {0xa77a}}},
- {0xa77b, {1|F|D, {0xa77c}}},
- {0xa77d, {1|F|D, {0x1d79}}},
- {0xa77e, {1|F|D, {0xa77f}}},
- {0xa780, {1|F|D, {0xa781}}},
- {0xa782, {1|F|D, {0xa783}}},
- {0xa784, {1|F|D, {0xa785}}},
- {0xa786, {1|F|D, {0xa787}}},
- {0xa78b, {1|F|D, {0xa78c}}},
- {0xa78d, {1|F|D, {0x0265}}},
- {0xa790, {1|F|D, {0xa791}}},
- {0xa792, {1|F|D, {0xa793}}},
- {0xa796, {1|F|D, {0xa797}}},
- {0xa798, {1|F|D, {0xa799}}},
- {0xa79a, {1|F|D, {0xa79b}}},
- {0xa79c, {1|F|D, {0xa79d}}},
- {0xa79e, {1|F|D, {0xa79f}}},
- {0xa7a0, {1|F|D, {0xa7a1}}},
- {0xa7a2, {1|F|D, {0xa7a3}}},
- {0xa7a4, {1|F|D, {0xa7a5}}},
- {0xa7a6, {1|F|D, {0xa7a7}}},
- {0xa7a8, {1|F|D, {0xa7a9}}},
- {0xa7aa, {1|F|D, {0x0266}}},
- {0xa7ab, {1|F|D, {0x025c}}},
- {0xa7ac, {1|F|D, {0x0261}}},
- {0xa7ad, {1|F|D, {0x026c}}},
- {0xa7ae, {1|F|D, {0x026a}}},
- {0xa7b0, {1|F|D, {0x029e}}},
- {0xa7b1, {1|F|D, {0x0287}}},
- {0xa7b2, {1|F|D, {0x029d}}},
- {0xa7b3, {1|F|D, {0xab53}}},
- {0xa7b4, {1|F|D, {0xa7b5}}},
- {0xa7b6, {1|F|D, {0xa7b7}}},
- {0xab70, {1|F|U, {0x13a0}}},
- {0xab71, {1|F|U, {0x13a1}}},
- {0xab72, {1|F|U, {0x13a2}}},
- {0xab73, {1|F|U, {0x13a3}}},
- {0xab74, {1|F|U, {0x13a4}}},
- {0xab75, {1|F|U, {0x13a5}}},
- {0xab76, {1|F|U, {0x13a6}}},
- {0xab77, {1|F|U, {0x13a7}}},
- {0xab78, {1|F|U, {0x13a8}}},
- {0xab79, {1|F|U, {0x13a9}}},
- {0xab7a, {1|F|U, {0x13aa}}},
- {0xab7b, {1|F|U, {0x13ab}}},
- {0xab7c, {1|F|U, {0x13ac}}},
- {0xab7d, {1|F|U, {0x13ad}}},
- {0xab7e, {1|F|U, {0x13ae}}},
- {0xab7f, {1|F|U, {0x13af}}},
- {0xab80, {1|F|U, {0x13b0}}},
- {0xab81, {1|F|U, {0x13b1}}},
- {0xab82, {1|F|U, {0x13b2}}},
- {0xab83, {1|F|U, {0x13b3}}},
- {0xab84, {1|F|U, {0x13b4}}},
- {0xab85, {1|F|U, {0x13b5}}},
- {0xab86, {1|F|U, {0x13b6}}},
- {0xab87, {1|F|U, {0x13b7}}},
- {0xab88, {1|F|U, {0x13b8}}},
- {0xab89, {1|F|U, {0x13b9}}},
- {0xab8a, {1|F|U, {0x13ba}}},
- {0xab8b, {1|F|U, {0x13bb}}},
- {0xab8c, {1|F|U, {0x13bc}}},
- {0xab8d, {1|F|U, {0x13bd}}},
- {0xab8e, {1|F|U, {0x13be}}},
- {0xab8f, {1|F|U, {0x13bf}}},
- {0xab90, {1|F|U, {0x13c0}}},
- {0xab91, {1|F|U, {0x13c1}}},
- {0xab92, {1|F|U, {0x13c2}}},
- {0xab93, {1|F|U, {0x13c3}}},
- {0xab94, {1|F|U, {0x13c4}}},
- {0xab95, {1|F|U, {0x13c5}}},
- {0xab96, {1|F|U, {0x13c6}}},
- {0xab97, {1|F|U, {0x13c7}}},
- {0xab98, {1|F|U, {0x13c8}}},
- {0xab99, {1|F|U, {0x13c9}}},
- {0xab9a, {1|F|U, {0x13ca}}},
- {0xab9b, {1|F|U, {0x13cb}}},
- {0xab9c, {1|F|U, {0x13cc}}},
- {0xab9d, {1|F|U, {0x13cd}}},
- {0xab9e, {1|F|U, {0x13ce}}},
- {0xab9f, {1|F|U, {0x13cf}}},
- {0xaba0, {1|F|U, {0x13d0}}},
- {0xaba1, {1|F|U, {0x13d1}}},
- {0xaba2, {1|F|U, {0x13d2}}},
- {0xaba3, {1|F|U, {0x13d3}}},
- {0xaba4, {1|F|U, {0x13d4}}},
- {0xaba5, {1|F|U, {0x13d5}}},
- {0xaba6, {1|F|U, {0x13d6}}},
- {0xaba7, {1|F|U, {0x13d7}}},
- {0xaba8, {1|F|U, {0x13d8}}},
- {0xaba9, {1|F|U, {0x13d9}}},
- {0xabaa, {1|F|U, {0x13da}}},
- {0xabab, {1|F|U, {0x13db}}},
- {0xabac, {1|F|U, {0x13dc}}},
- {0xabad, {1|F|U, {0x13dd}}},
- {0xabae, {1|F|U, {0x13de}}},
- {0xabaf, {1|F|U, {0x13df}}},
- {0xabb0, {1|F|U, {0x13e0}}},
- {0xabb1, {1|F|U, {0x13e1}}},
- {0xabb2, {1|F|U, {0x13e2}}},
- {0xabb3, {1|F|U, {0x13e3}}},
- {0xabb4, {1|F|U, {0x13e4}}},
- {0xabb5, {1|F|U, {0x13e5}}},
- {0xabb6, {1|F|U, {0x13e6}}},
- {0xabb7, {1|F|U, {0x13e7}}},
- {0xabb8, {1|F|U, {0x13e8}}},
- {0xabb9, {1|F|U, {0x13e9}}},
- {0xabba, {1|F|U, {0x13ea}}},
- {0xabbb, {1|F|U, {0x13eb}}},
- {0xabbc, {1|F|U, {0x13ec}}},
- {0xabbd, {1|F|U, {0x13ed}}},
- {0xabbe, {1|F|U, {0x13ee}}},
- {0xabbf, {1|F|U, {0x13ef}}},
- {0xfb00, {2|F|ST|SU|I(366), {0x0066, 0x0066}}},
- {0xfb01, {2|F|ST|SU|I(370), {0x0066, 0x0069}}},
- {0xfb02, {2|F|ST|SU|I(374), {0x0066, 0x006c}}},
- {0xfb03, {3|F|ST|SU|I(378), {0x0066, 0x0066, 0x0069}}},
- {0xfb04, {3|F|ST|SU|I(384), {0x0066, 0x0066, 0x006c}}},
- {0xfb05, {2|F|ST|SU|I(390), {0x0073, 0x0074}}},
- {0xfb06, {2|F|ST|SU|I(394), {0x0073, 0x0074}}},
- {0xfb13, {2|F|ST|SU|I(398), {0x0574, 0x0576}}},
- {0xfb14, {2|F|ST|SU|I(402), {0x0574, 0x0565}}},
- {0xfb15, {2|F|ST|SU|I(406), {0x0574, 0x056b}}},
- {0xfb16, {2|F|ST|SU|I(410), {0x057e, 0x0576}}},
- {0xfb17, {2|F|ST|SU|I(414), {0x0574, 0x056d}}},
- {0xff21, {1|F|D, {0xff41}}},
- {0xff22, {1|F|D, {0xff42}}},
- {0xff23, {1|F|D, {0xff43}}},
- {0xff24, {1|F|D, {0xff44}}},
- {0xff25, {1|F|D, {0xff45}}},
- {0xff26, {1|F|D, {0xff46}}},
- {0xff27, {1|F|D, {0xff47}}},
- {0xff28, {1|F|D, {0xff48}}},
- {0xff29, {1|F|D, {0xff49}}},
- {0xff2a, {1|F|D, {0xff4a}}},
- {0xff2b, {1|F|D, {0xff4b}}},
- {0xff2c, {1|F|D, {0xff4c}}},
- {0xff2d, {1|F|D, {0xff4d}}},
- {0xff2e, {1|F|D, {0xff4e}}},
- {0xff2f, {1|F|D, {0xff4f}}},
- {0xff30, {1|F|D, {0xff50}}},
- {0xff31, {1|F|D, {0xff51}}},
- {0xff32, {1|F|D, {0xff52}}},
- {0xff33, {1|F|D, {0xff53}}},
- {0xff34, {1|F|D, {0xff54}}},
- {0xff35, {1|F|D, {0xff55}}},
- {0xff36, {1|F|D, {0xff56}}},
- {0xff37, {1|F|D, {0xff57}}},
- {0xff38, {1|F|D, {0xff58}}},
- {0xff39, {1|F|D, {0xff59}}},
- {0xff3a, {1|F|D, {0xff5a}}},
- {0x10400, {1|F|D, {0x10428}}},
- {0x10401, {1|F|D, {0x10429}}},
- {0x10402, {1|F|D, {0x1042a}}},
- {0x10403, {1|F|D, {0x1042b}}},
- {0x10404, {1|F|D, {0x1042c}}},
- {0x10405, {1|F|D, {0x1042d}}},
- {0x10406, {1|F|D, {0x1042e}}},
- {0x10407, {1|F|D, {0x1042f}}},
- {0x10408, {1|F|D, {0x10430}}},
- {0x10409, {1|F|D, {0x10431}}},
- {0x1040a, {1|F|D, {0x10432}}},
- {0x1040b, {1|F|D, {0x10433}}},
- {0x1040c, {1|F|D, {0x10434}}},
- {0x1040d, {1|F|D, {0x10435}}},
- {0x1040e, {1|F|D, {0x10436}}},
- {0x1040f, {1|F|D, {0x10437}}},
- {0x10410, {1|F|D, {0x10438}}},
- {0x10411, {1|F|D, {0x10439}}},
- {0x10412, {1|F|D, {0x1043a}}},
- {0x10413, {1|F|D, {0x1043b}}},
- {0x10414, {1|F|D, {0x1043c}}},
- {0x10415, {1|F|D, {0x1043d}}},
- {0x10416, {1|F|D, {0x1043e}}},
- {0x10417, {1|F|D, {0x1043f}}},
- {0x10418, {1|F|D, {0x10440}}},
- {0x10419, {1|F|D, {0x10441}}},
- {0x1041a, {1|F|D, {0x10442}}},
- {0x1041b, {1|F|D, {0x10443}}},
- {0x1041c, {1|F|D, {0x10444}}},
- {0x1041d, {1|F|D, {0x10445}}},
- {0x1041e, {1|F|D, {0x10446}}},
- {0x1041f, {1|F|D, {0x10447}}},
- {0x10420, {1|F|D, {0x10448}}},
- {0x10421, {1|F|D, {0x10449}}},
- {0x10422, {1|F|D, {0x1044a}}},
- {0x10423, {1|F|D, {0x1044b}}},
- {0x10424, {1|F|D, {0x1044c}}},
- {0x10425, {1|F|D, {0x1044d}}},
- {0x10426, {1|F|D, {0x1044e}}},
- {0x10427, {1|F|D, {0x1044f}}},
- {0x104b0, {1|F|D, {0x104d8}}},
- {0x104b1, {1|F|D, {0x104d9}}},
- {0x104b2, {1|F|D, {0x104da}}},
- {0x104b3, {1|F|D, {0x104db}}},
- {0x104b4, {1|F|D, {0x104dc}}},
- {0x104b5, {1|F|D, {0x104dd}}},
- {0x104b6, {1|F|D, {0x104de}}},
- {0x104b7, {1|F|D, {0x104df}}},
- {0x104b8, {1|F|D, {0x104e0}}},
- {0x104b9, {1|F|D, {0x104e1}}},
- {0x104ba, {1|F|D, {0x104e2}}},
- {0x104bb, {1|F|D, {0x104e3}}},
- {0x104bc, {1|F|D, {0x104e4}}},
- {0x104bd, {1|F|D, {0x104e5}}},
- {0x104be, {1|F|D, {0x104e6}}},
- {0x104bf, {1|F|D, {0x104e7}}},
- {0x104c0, {1|F|D, {0x104e8}}},
- {0x104c1, {1|F|D, {0x104e9}}},
- {0x104c2, {1|F|D, {0x104ea}}},
- {0x104c3, {1|F|D, {0x104eb}}},
- {0x104c4, {1|F|D, {0x104ec}}},
- {0x104c5, {1|F|D, {0x104ed}}},
- {0x104c6, {1|F|D, {0x104ee}}},
- {0x104c7, {1|F|D, {0x104ef}}},
- {0x104c8, {1|F|D, {0x104f0}}},
- {0x104c9, {1|F|D, {0x104f1}}},
- {0x104ca, {1|F|D, {0x104f2}}},
- {0x104cb, {1|F|D, {0x104f3}}},
- {0x104cc, {1|F|D, {0x104f4}}},
- {0x104cd, {1|F|D, {0x104f5}}},
- {0x104ce, {1|F|D, {0x104f6}}},
- {0x104cf, {1|F|D, {0x104f7}}},
- {0x104d0, {1|F|D, {0x104f8}}},
- {0x104d1, {1|F|D, {0x104f9}}},
- {0x104d2, {1|F|D, {0x104fa}}},
- {0x104d3, {1|F|D, {0x104fb}}},
- {0x10c80, {1|F|D, {0x10cc0}}},
- {0x10c81, {1|F|D, {0x10cc1}}},
- {0x10c82, {1|F|D, {0x10cc2}}},
- {0x10c83, {1|F|D, {0x10cc3}}},
- {0x10c84, {1|F|D, {0x10cc4}}},
- {0x10c85, {1|F|D, {0x10cc5}}},
- {0x10c86, {1|F|D, {0x10cc6}}},
- {0x10c87, {1|F|D, {0x10cc7}}},
- {0x10c88, {1|F|D, {0x10cc8}}},
- {0x10c89, {1|F|D, {0x10cc9}}},
- {0x10c8a, {1|F|D, {0x10cca}}},
- {0x10c8b, {1|F|D, {0x10ccb}}},
- {0x10c8c, {1|F|D, {0x10ccc}}},
- {0x10c8d, {1|F|D, {0x10ccd}}},
- {0x10c8e, {1|F|D, {0x10cce}}},
- {0x10c8f, {1|F|D, {0x10ccf}}},
- {0x10c90, {1|F|D, {0x10cd0}}},
- {0x10c91, {1|F|D, {0x10cd1}}},
- {0x10c92, {1|F|D, {0x10cd2}}},
- {0x10c93, {1|F|D, {0x10cd3}}},
- {0x10c94, {1|F|D, {0x10cd4}}},
- {0x10c95, {1|F|D, {0x10cd5}}},
- {0x10c96, {1|F|D, {0x10cd6}}},
- {0x10c97, {1|F|D, {0x10cd7}}},
- {0x10c98, {1|F|D, {0x10cd8}}},
- {0x10c99, {1|F|D, {0x10cd9}}},
- {0x10c9a, {1|F|D, {0x10cda}}},
- {0x10c9b, {1|F|D, {0x10cdb}}},
- {0x10c9c, {1|F|D, {0x10cdc}}},
- {0x10c9d, {1|F|D, {0x10cdd}}},
- {0x10c9e, {1|F|D, {0x10cde}}},
- {0x10c9f, {1|F|D, {0x10cdf}}},
- {0x10ca0, {1|F|D, {0x10ce0}}},
- {0x10ca1, {1|F|D, {0x10ce1}}},
- {0x10ca2, {1|F|D, {0x10ce2}}},
- {0x10ca3, {1|F|D, {0x10ce3}}},
- {0x10ca4, {1|F|D, {0x10ce4}}},
- {0x10ca5, {1|F|D, {0x10ce5}}},
- {0x10ca6, {1|F|D, {0x10ce6}}},
- {0x10ca7, {1|F|D, {0x10ce7}}},
- {0x10ca8, {1|F|D, {0x10ce8}}},
- {0x10ca9, {1|F|D, {0x10ce9}}},
- {0x10caa, {1|F|D, {0x10cea}}},
- {0x10cab, {1|F|D, {0x10ceb}}},
- {0x10cac, {1|F|D, {0x10cec}}},
- {0x10cad, {1|F|D, {0x10ced}}},
- {0x10cae, {1|F|D, {0x10cee}}},
- {0x10caf, {1|F|D, {0x10cef}}},
- {0x10cb0, {1|F|D, {0x10cf0}}},
- {0x10cb1, {1|F|D, {0x10cf1}}},
- {0x10cb2, {1|F|D, {0x10cf2}}},
- {0x118a0, {1|F|D, {0x118c0}}},
- {0x118a1, {1|F|D, {0x118c1}}},
- {0x118a2, {1|F|D, {0x118c2}}},
- {0x118a3, {1|F|D, {0x118c3}}},
- {0x118a4, {1|F|D, {0x118c4}}},
- {0x118a5, {1|F|D, {0x118c5}}},
- {0x118a6, {1|F|D, {0x118c6}}},
- {0x118a7, {1|F|D, {0x118c7}}},
- {0x118a8, {1|F|D, {0x118c8}}},
- {0x118a9, {1|F|D, {0x118c9}}},
- {0x118aa, {1|F|D, {0x118ca}}},
- {0x118ab, {1|F|D, {0x118cb}}},
- {0x118ac, {1|F|D, {0x118cc}}},
- {0x118ad, {1|F|D, {0x118cd}}},
- {0x118ae, {1|F|D, {0x118ce}}},
- {0x118af, {1|F|D, {0x118cf}}},
- {0x118b0, {1|F|D, {0x118d0}}},
- {0x118b1, {1|F|D, {0x118d1}}},
- {0x118b2, {1|F|D, {0x118d2}}},
- {0x118b3, {1|F|D, {0x118d3}}},
- {0x118b4, {1|F|D, {0x118d4}}},
- {0x118b5, {1|F|D, {0x118d5}}},
- {0x118b6, {1|F|D, {0x118d6}}},
- {0x118b7, {1|F|D, {0x118d7}}},
- {0x118b8, {1|F|D, {0x118d8}}},
- {0x118b9, {1|F|D, {0x118d9}}},
- {0x118ba, {1|F|D, {0x118da}}},
- {0x118bb, {1|F|D, {0x118db}}},
- {0x118bc, {1|F|D, {0x118dc}}},
- {0x118bd, {1|F|D, {0x118dd}}},
- {0x118be, {1|F|D, {0x118de}}},
- {0x118bf, {1|F|D, {0x118df}}},
- {0x1e900, {1|F|D, {0x1e922}}},
- {0x1e901, {1|F|D, {0x1e923}}},
- {0x1e902, {1|F|D, {0x1e924}}},
- {0x1e903, {1|F|D, {0x1e925}}},
- {0x1e904, {1|F|D, {0x1e926}}},
- {0x1e905, {1|F|D, {0x1e927}}},
- {0x1e906, {1|F|D, {0x1e928}}},
- {0x1e907, {1|F|D, {0x1e929}}},
- {0x1e908, {1|F|D, {0x1e92a}}},
- {0x1e909, {1|F|D, {0x1e92b}}},
- {0x1e90a, {1|F|D, {0x1e92c}}},
- {0x1e90b, {1|F|D, {0x1e92d}}},
- {0x1e90c, {1|F|D, {0x1e92e}}},
- {0x1e90d, {1|F|D, {0x1e92f}}},
- {0x1e90e, {1|F|D, {0x1e930}}},
- {0x1e90f, {1|F|D, {0x1e931}}},
- {0x1e910, {1|F|D, {0x1e932}}},
- {0x1e911, {1|F|D, {0x1e933}}},
- {0x1e912, {1|F|D, {0x1e934}}},
- {0x1e913, {1|F|D, {0x1e935}}},
- {0x1e914, {1|F|D, {0x1e936}}},
- {0x1e915, {1|F|D, {0x1e937}}},
- {0x1e916, {1|F|D, {0x1e938}}},
- {0x1e917, {1|F|D, {0x1e939}}},
- {0x1e918, {1|F|D, {0x1e93a}}},
- {0x1e919, {1|F|D, {0x1e93b}}},
- {0x1e91a, {1|F|D, {0x1e93c}}},
- {0x1e91b, {1|F|D, {0x1e93d}}},
- {0x1e91c, {1|F|D, {0x1e93e}}},
- {0x1e91d, {1|F|D, {0x1e93f}}},
- {0x1e91e, {1|F|D, {0x1e940}}},
- {0x1e91f, {1|F|D, {0x1e941}}},
- {0x1e920, {1|F|D, {0x1e942}}},
- {0x1e921, {1|F|D, {0x1e943}}},
-#define CaseFold_Locale (*(CaseFold_11_Type (*)[2])(CaseFold_11_Table+1399))
- {0x0049, {1|F|D, {0x0069}}},
- {0x0130, {2|F|D, {0x0069, 0x0307}}},
-};
-
-/* C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -7 -k1,2,3 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseFold_11_hash -N onigenc_unicode_CaseFold_11_lookup -n */
-
-/* maximum key range = 3623, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-/*ARGSUSED*/
-static unsigned int
-onigenc_unicode_CaseFold_11_hash(const OnigCodePoint code)
-{
- static const unsigned short asso_values[] =
- {
- 1, 3627, 2, 28, 3, 303, 218, 5, 21, 167,
- 2, 199, 194, 7, 3627, 3627, 3627, 3627, 3627, 3627,
- 3627, 3627, 3627, 3627, 3627, 3627, 3627, 28, 3627, 3627,
- 3627, 3627, 3627, 3627, 3627, 282, 3627, 3627, 3627, 3627,
- 3627, 113, 3627, 3627, 3627, 3627, 3627, 3627, 3627, 3627,
- 3627, 318, 3627, 3627, 3627, 3627, 3627, 3627, 3627, 1197,
- 3627, 3627, 149, 73, 513, 1, 3627, 3627, 267, 17,
- 3627, 3627, 3627, 3627, 3627, 286, 3627, 3627, 289, 617,
- 291, 28, 1163, 444, 36, 430, 954, 110, 1767, 5,
- 11, 22, 1761, 486, 1921, 250, 1746, 122, 1905, 163,
- 1716, 262, 1880, 80, 1503, 68, 1704, 157, 1681, 376,
- 1673, 209, 1822, 203, 1406, 498, 1622, 362, 1588, 316,
- 475, 599, 1228, 538, 1160, 585, 1510, 544, 331, 685,
- 1672, 603, 1536, 840, 1684, 786, 1594, 743, 1380, 700,
- 142, 839, 1302, 865, 1173, 1329, 1730, 1043, 1449, 969,
- 1437, 1108, 1360, 925, 1497, 723, 154, 810, 391, 1083,
- 1777, 1047, 436, 1051, 47, 1342, 8, 974, 98, 1318,
- 781, 1314, 148, 1403, 39, 1357, 18, 1265, 11, 928,
- 92, 1205, 2, 1295, 3, 1181, 187, 1151, 385, 1132,
- 107, 1280, 8, 1678, 41, 511, 42, 1655, 78, 294,
- 134, 1857, 17, 784, 2, 1113, 57, 496, 52
- };
- return asso_values[bits_of(code, 2)+81] + asso_values[bits_of(code, 1)+2] + asso_values[bits_of(code, 0)];
-}
-
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-static const CodePointList3 *
-onigenc_unicode_CaseFold_11_lookup(const OnigCodePoint code)
-{
- enum
- {
- MIN_CODE_VALUE = 0x41,
- MAX_CODE_VALUE = 0x1e921,
- TOTAL_KEYWORDS = 1401,
- MIN_WORD_LENGTH = 3,
- MAX_WORD_LENGTH = 3,
- MIN_HASH_VALUE = 4,
- MAX_HASH_VALUE = 3626
- };
-
- static const short wordlist[] =
- {
- -1, -1, -1, -1,
- /*0x1ffb*/ 816,
- /*0x1fe7*/ 802,
- /*0x017b*/ 118,
- /*0x1f88*/ 729,
- /*0x0408*/ 305,
- /*0x0108*/ 61,
- /*0x10408*/ 1214,
- /*0x0055*/ 19,
- /*0xab88*/ 1112,
- /*0x1f89*/ 730,
- /*0x0409*/ 306,
- /*0x2c67*/ 916,
- /*0x10409*/ 1215,
- /*0x2c08*/ 873,
- /*0xab89*/ 1113,
- /*0x1ff9*/ 814,
- /*0x2c6f*/ 921,
- /*0x0179*/ 117,
- -1,
- /*0x2c09*/ 874,
- /*0x1f8a*/ 731,
- /*0x040a*/ 307,
- /*0x010a*/ 62,
- /*0x1040a*/ 1216,
- /*0x2c88*/ 931,
- /*0xab8a*/ 1114,
- /*0x1f80*/ 721,
- /*0x0400*/ 297,
- /*0x0100*/ 57,
- /*0x10400*/ 1206,
- /*0x2c0a*/ 875,
- /*0xab80*/ 1104,
- /*0x10c88*/ 1290,
- /*0x00d5*/ 47,
- /*0x1f83*/ 724,
- /*0x0403*/ 300,
- /*0x2c00*/ 865,
- /*0x10403*/ 1209,
- /*0x10c89*/ 1291,
- /*0xab83*/ 1107,
- /*0x1ff3*/ 809,
- /*0x2c8a*/ 932,
- /*0x1e908*/ 1373,
- /*0x00df*/ 56,
- /*0x2c03*/ 868,
- /*0x1fd3*/ 791,
- /*0x0053*/ 17,
- /*0x2c80*/ 927,
- /*0x1e909*/ 1374,
- /*0x10c8a*/ 1292,
- /*0x2183*/ 838,
- -1,
- /*0x017f*/ 120,
- -1,
- /*0xa780*/ 1059,
- /*0x10c80*/ 1282,
- -1,
- /*0x017d*/ 119,
- -1,
- /*0x1e90a*/ 1375,
- /*0x2c7f*/ 926,
- -1, -1,
- /*0x10c83*/ 1285,
- /*0x00dd*/ 54,
- /*0x1e900*/ 1365,
- /*0x1f98*/ 745,
- /*0x0418*/ 321,
- /*0x0118*/ 69,
- /*0x10418*/ 1230,
- /*0x037f*/ 233,
- /*0xab98*/ 1128,
- /*0x00d3*/ 45,
- /*0x1e903*/ 1368,
- -1,
- /*0x1e88*/ 607,
- /*0x2c18*/ 889,
- -1,
- /*0x1f96*/ 743,
- /*0x0416*/ 319,
- /*0x0116*/ 68,
- /*0x10416*/ 1228,
- -1,
- /*0xab96*/ 1126,
- -1, -1,
- /*0x2c75*/ 924,
- /*0x2c98*/ 939,
- /*0x2c16*/ 887,
- -1,
- /*0x1fe3*/ 799,
- -1,
- /*0x1e8a*/ 608,
- -1,
- /*0xa798*/ 1068,
- /*0x10c98*/ 1306,
- /*0x1fd7*/ 793,
- /*0x0057*/ 21,
- /*0x1e80*/ 603,
- /*0x2c96*/ 938,
- /*0x2c63*/ 914,
- -1, -1, -1, -1,
- /*0x1e918*/ 1389,
- /*0xa796*/ 1067,
- /*0x10c96*/ 1304,
- /*0x1f86*/ 727,
- /*0x0406*/ 303,
- /*0x0106*/ 60,
- /*0x10406*/ 1212,
- /*0x13fb*/ 527,
- /*0xab86*/ 1110,
- -1,
- /*0x2c6d*/ 919,
- -1,
- /*0x1e916*/ 1387,
- /*0x2c06*/ 871,
- -1,
- /*0x1f90*/ 737,
- /*0x0410*/ 313,
- /*0x0110*/ 65,
- /*0x10410*/ 1222,
- -1,
- /*0xab90*/ 1120,
- /*0x2ced*/ 978,
- /*0x13f9*/ 525,
- -1,
- /*0x2c86*/ 930,
- /*0x2c10*/ 881,
- -1,
- /*0x1ff7*/ 812,
- -1, -1, -1,
- /*0xa786*/ 1062,
- /*0x10c86*/ 1288,
- /*0x1e98*/ 616,
- -1,
- /*0x1fbb*/ 777,
- /*0x2c90*/ 935,
- /*0x013b*/ 85,
- -1, -1,
- /*0xabbb*/ 1163,
- /*0x1fdb*/ 797,
- /*0x1e906*/ 1371,
- /*0xa790*/ 1065,
- /*0x10c90*/ 1298,
- /*0x1e96*/ 614,
- /*0x1e08*/ 543,
- /*0x1fcb*/ 788,
- /*0x004b*/ 9,
- -1,
- /*0x1f9a*/ 747,
- /*0x041a*/ 323,
- /*0x011a*/ 70,
- /*0x1041a*/ 1232,
- /*0x1e910*/ 1381,
- /*0xab9a*/ 1130,
- /*0x1f92*/ 739,
- /*0x0412*/ 315,
- /*0x0112*/ 66,
- /*0x10412*/ 1224,
- /*0x2c1a*/ 891,
- /*0xab92*/ 1122,
- /*0x13fd*/ 529,
- /*0x1e0a*/ 544,
- /*0x0388*/ 235,
- -1,
- /*0x2c12*/ 883,
- /*0x03d5*/ 273,
- /*0x00db*/ 52,
- /*0x1e00*/ 539,
- /*0x0389*/ 236,
- /*0x2c9a*/ 940,
- -1, -1,
- /*0x00cb*/ 37,
- /*0x1e86*/ 606,
- /*0x03f9*/ 292,
- /*0x2c92*/ 936,
- /*0xa79a*/ 1069,
- /*0x10c9a*/ 1308,
- /*0x1fe9*/ 804,
- /*0x038a*/ 237,
- -1, -1,
- /*0xa792*/ 1066,
- /*0x10c92*/ 1300,
- -1,
- /*0x1e90*/ 611,
- -1,
- /*0x1e91a*/ 1391,
- /*0x2c69*/ 917,
- /*0x0508*/ 425,
- -1, -1,
- /*0x0555*/ 481,
- /*0x1e912*/ 1383,
- /*0x1fa0*/ 753,
- /*0x0420*/ 329,
- /*0x0120*/ 73,
- /*0x10420*/ 1238,
- /*0x03f1*/ 288,
- /*0xaba0*/ 1136,
- /*0x1f9e*/ 751,
- /*0x041e*/ 327,
- /*0x011e*/ 72,
- /*0x1041e*/ 1236,
- /*0x2c20*/ 897,
- /*0xab9e*/ 1134,
- /*0x050a*/ 426,
- /*0x1e18*/ 551,
- -1,
- /*0x03ff*/ 296,
- /*0x2c1e*/ 895,
- /*0x048a*/ 362,
- /*0x0500*/ 421,
- /*0x0208*/ 194,
- /*0x03fd*/ 294,
- /*0x2ca0*/ 943,
- -1,
- /*0x0480*/ 361,
- -1,
- /*0x1e16*/ 550,
- /*0x1e9a*/ 618,
- /*0x2c9e*/ 942,
- /*0xa7a0*/ 1072,
- /*0x10ca0*/ 1314,
- -1,
- /*0x0398*/ 249,
- /*0x1e92*/ 612,
- -1,
- /*0xa79e*/ 1071,
- /*0x10c9e*/ 1312,
- /*0x020a*/ 195,
- /*0x0553*/ 479,
- -1,
- /*0x1e920*/ 1397,
- -1,
- /*0x03f5*/ 290,
- /*0x0200*/ 190,
- /*0x0396*/ 247,
- /*0x104d3*/ 1281,
- /*0x1e91e*/ 1395,
- -1,
- /*0x1f8e*/ 735,
- /*0x040e*/ 311,
- /*0x010e*/ 64,
- /*0x1040e*/ 1220,
- -1,
- /*0xab8e*/ 1118,
- -1, -1,
- /*0x1e06*/ 542,
- -1,
- /*0x2c0e*/ 879,
- /*0x0518*/ 433,
- /*0x1f94*/ 741,
- /*0x0414*/ 317,
- /*0x0114*/ 67,
- /*0x10414*/ 1226,
- /*0x0498*/ 369,
- /*0xab94*/ 1124,
- /*0x2165*/ 827,
- /*0x2167*/ 829,
- /*0x1e10*/ 547,
- /*0x2c8e*/ 934,
- /*0x2c14*/ 885,
- /*0x0516*/ 432,
- /*0x216f*/ 837,
- /*0x1ea0*/ 621,
- /*0x0386*/ 234,
- /*0x2161*/ 823,
- /*0x0496*/ 368,
- /*0x10c8e*/ 1296,
- -1,
- /*0x1e9e*/ 620,
- -1,
- /*0x2c94*/ 937,
- -1,
- /*0x0218*/ 202,
- -1, -1,
- /*0x0390*/ 241,
- /*0x1e90e*/ 1379,
- -1,
- /*0x10c94*/ 1302,
- -1,
- /*0xa77b*/ 1056,
- /*0x1ff6*/ 811,
- /*0x0476*/ 356,
- /*0x0176*/ 115,
- /*0x0216*/ 201,
- -1, -1,
- /*0x03f7*/ 291,
- /*0x1e914*/ 1385,
- -1,
- /*0x0506*/ 424,
- -1,
- /*0x1e1a*/ 552,
- -1, -1,
- /*0xa779*/ 1055,
- -1,
- /*0x01d5*/ 167,
- /*0x1e12*/ 548,
- -1,
- /*0x0189*/ 126,
- /*0x0376*/ 232,
- /*0x0510*/ 429,
- /*0x1fa6*/ 759,
- /*0x0426*/ 335,
- /*0x0126*/ 76,
- /*0x10426*/ 1244,
- /*0x0490*/ 365,
- /*0xaba6*/ 1142,
- /*0x1e8e*/ 610,
- /*0x039a*/ 251,
- /*0x018a*/ 127,
- -1,
- /*0x2c26*/ 903,
- /*0x0206*/ 193,
- -1,
- /*0x0392*/ 243,
- -1,
- /*0x1faf*/ 768,
- /*0x042f*/ 344,
- -1,
- /*0x1e94*/ 613,
- /*0x053b*/ 455,
- /*0xabaf*/ 1151,
- /*0x2ca6*/ 946,
- -1,
- /*0x0210*/ 198,
- -1, -1,
- /*0x104bb*/ 1257,
- /*0x01f1*/ 181,
- /*0xa7a6*/ 1075,
- /*0x10ca6*/ 1320,
- -1,
- /*0x054b*/ 471,
- /*0xa77d*/ 1057,
- /*0x01d3*/ 166,
- /*0x051a*/ 434,
- /*0x1e20*/ 555,
- /*0x04cb*/ 395,
- -1,
- /*0x104cb*/ 1273,
- /*0x049a*/ 370,
- /*0x0512*/ 430,
- /*0x1e1e*/ 554,
- /*0x2163*/ 825,
- /*0x023b*/ 217,
- /*0x10caf*/ 1329,
- /*0x0492*/ 366,
- /*0x1fa4*/ 757,
- /*0x0424*/ 333,
- /*0x0124*/ 75,
- /*0x10424*/ 1242,
- /*0x1ef6*/ 664,
- /*0xaba4*/ 1140,
- -1,
- /*0x03a0*/ 257,
- /*0x0198*/ 137,
- -1,
- /*0x2c24*/ 901,
- /*0x216d*/ 835,
- /*0x021a*/ 203,
- /*0x039e*/ 255,
- /*0x1f9c*/ 749,
- /*0x041c*/ 325,
- /*0x011c*/ 71,
- /*0x1041c*/ 1234,
- /*0x0212*/ 199,
- /*0xab9c*/ 1132,
- /*0x0196*/ 135,
- /*0x2ca4*/ 945,
- -1,
- /*0x1feb*/ 806,
- /*0x2c1c*/ 893,
- -1,
- /*0x1ea6*/ 624,
- -1,
- /*0xa7a4*/ 1074,
- /*0x10ca4*/ 1318,
- /*0x004d*/ 11,
- -1, -1,
- /*0x2c6b*/ 918,
- /*0x0520*/ 437,
- /*0x2c9c*/ 941,
- /*0x1e0e*/ 546,
- -1,
- /*0x01d7*/ 168,
- /*0x04a0*/ 373,
- /*0x051e*/ 436,
- -1,
- /*0xa79c*/ 1070,
- /*0x10c9c*/ 1310,
- /*0x2ceb*/ 977,
- /*0x049e*/ 372,
- -1, -1,
- /*0x1e14*/ 549,
- -1,
- /*0x0186*/ 124,
- -1, -1,
- /*0x1e91c*/ 1393,
- /*0x038e*/ 239,
- -1,
- /*0x00cd*/ 39,
- -1,
- /*0x0220*/ 206,
- -1, -1,
- /*0x10bb*/ 511,
- /*0x0190*/ 131,
- -1,
- /*0x021e*/ 205,
- /*0x24bb*/ 844,
- /*0x0394*/ 245,
- -1,
- /*0x1f84*/ 725,
- /*0x0404*/ 301,
- /*0x0104*/ 59,
- /*0x10404*/ 1210,
- /*0x1ea4*/ 623,
- /*0xab84*/ 1108,
- /*0x01f7*/ 185,
- /*0x0051*/ 15,
- -1,
- /*0x24cb*/ 860,
- /*0x2c04*/ 869,
- -1,
- /*0x1e76*/ 598,
- /*0x050e*/ 428,
- /*0x1f82*/ 723,
- /*0x0402*/ 299,
- /*0x0102*/ 58,
- /*0x10402*/ 1208,
- /*0x048e*/ 364,
- /*0xab82*/ 1106,
- /*0x01db*/ 170,
- /*0x2c84*/ 929,
- -1,
- /*0x2169*/ 831,
- /*0x2c02*/ 867,
- /*0x0514*/ 431,
- /*0x01cb*/ 162,
- -1,
- /*0xa784*/ 1061,
- /*0x10c84*/ 1286,
- /*0x0494*/ 367,
- /*0x118bb*/ 1360,
- -1,
- /*0x00d1*/ 43,
- /*0x1e26*/ 558,
- /*0x2c82*/ 928,
- -1,
- /*0x020e*/ 197,
- -1,
- /*0x1e904*/ 1369,
- -1, -1,
- /*0xa782*/ 1060,
- /*0x10c82*/ 1284,
- -1,
- /*0x1fa7*/ 760,
- /*0x0427*/ 336,
- -1,
- /*0x10427*/ 1245,
- /*0x0214*/ 200,
- /*0xaba7*/ 1143,
- -1,
- /*0x03a6*/ 262,
- /*0x1e902*/ 1367,
- /*0x10a0*/ 484,
- /*0x2c27*/ 904,
- /*0x1f8c*/ 733,
- /*0x040c*/ 309,
- /*0x010c*/ 63,
- /*0x1040c*/ 1218,
- -1,
- /*0xab8c*/ 1116,
- /*0x04f6*/ 416,
- -1, -1, -1,
- /*0x2c0c*/ 877,
- /*0x047e*/ 360,
- /*0x1fa2*/ 755,
- /*0x0422*/ 331,
- /*0x0122*/ 74,
- /*0x10422*/ 1240,
- /*0x1e84*/ 605,
- /*0xaba2*/ 1138,
- /*0x10ca7*/ 1321,
- /*0x01a0*/ 141,
- /*0x2c7e*/ 925,
- /*0x2c8c*/ 933,
- /*0x2c22*/ 899,
- /*0x0526*/ 440,
- /*0x1e24*/ 557,
- /*0x1ff2*/ 808,
- /*0x0472*/ 354,
- /*0x0172*/ 113,
- /*0x04a6*/ 376,
- /*0x10c8c*/ 1294,
- /*0x1e82*/ 604,
- /*0x1f08*/ 669,
- -1,
- /*0x2ca2*/ 944,
- /*0x1f6f*/ 720,
- /*0x2c72*/ 923,
- /*0x118a0*/ 1333,
- /*0x1f09*/ 670,
- /*0x1e1c*/ 553,
- /*0x1e90c*/ 1377,
- /*0xa7a2*/ 1073,
- /*0x10ca2*/ 1316,
- /*0x03a4*/ 260,
- /*0xfb00*/ 1168,
- /*0x1f5f*/ 712,
- /*0x0372*/ 231,
- /*0x2cf2*/ 979,
- /*0x0226*/ 209,
- /*0x1f0a*/ 671,
- -1, -1,
- /*0xfb03*/ 1171,
- /*0x1faa*/ 763,
- /*0x042a*/ 339,
- /*0x012a*/ 78,
- -1,
- /*0x039c*/ 253,
- /*0xabaa*/ 1146,
- /*0x1fae*/ 767,
- /*0x042e*/ 343,
- /*0x012e*/ 80,
- -1,
- /*0x2c2a*/ 907,
- /*0xabae*/ 1150,
- -1,
- /*0x1f5d*/ 711,
- /*0x018e*/ 129,
- -1,
- /*0x2c2e*/ 911,
- /*0x0524*/ 439,
- -1, -1,
- /*0x1e8c*/ 609,
- /*0x2caa*/ 948,
- /*0x04a4*/ 375,
- -1, -1, -1,
- /*0x0194*/ 134,
- /*0x2cae*/ 950,
- /*0xa7aa*/ 1077,
- /*0x10caa*/ 1324,
- /*0x1efe*/ 668,
- /*0x051c*/ 435,
- /*0x1ea2*/ 622,
- -1,
- /*0xa7ae*/ 1081,
- /*0x10cae*/ 1328,
- /*0x049c*/ 371,
- -1, -1, -1,
- /*0x1e04*/ 541,
- /*0x0224*/ 208,
- /*0x1f18*/ 677,
- /*0xfb16*/ 1178,
- /*0x2126*/ 818,
- /*0x1ef2*/ 662,
- /*0x054d*/ 473,
- /*0x1fac*/ 765,
- /*0x042c*/ 341,
- /*0x012c*/ 79,
- -1,
- /*0x04cd*/ 396,
- /*0xabac*/ 1148,
- /*0x104cd*/ 1275,
- /*0x1e02*/ 540,
- /*0x021c*/ 204,
- -1,
- /*0x2c2c*/ 909,
- /*0x01f6*/ 184,
- /*0x10a6*/ 490,
- -1,
- /*0x1fa8*/ 761,
- /*0x0428*/ 337,
- /*0x0128*/ 77,
- /*0x03d1*/ 272,
- /*0x1fb2*/ 769,
- /*0xaba8*/ 1144,
- /*0x0132*/ 81,
- /*0x2cac*/ 949,
- /*0xa726*/ 1019,
- /*0xabb2*/ 1154,
- /*0x2c28*/ 905,
- /*0x1eaa*/ 626,
- /*0xfb06*/ 1174,
- /*0x10af*/ 499,
- /*0xa7ac*/ 1079,
- /*0x10cac*/ 1326,
- -1,
- /*0x1eae*/ 628,
- -1,
- /*0x01a6*/ 144,
- /*0x1f6d*/ 718,
- /*0x2ca8*/ 947,
- -1,
- /*0xa688*/ 1007,
- /*0x0504*/ 423,
- /*0x2cb2*/ 952,
- -1, -1,
- /*0xa7a8*/ 1076,
- /*0x10ca8*/ 1322,
- /*0x0551*/ 477,
- -1,
- /*0xa7b2*/ 1084,
- /*0x10cb2*/ 1332,
- /*0x01af*/ 149,
- /*0x1e0c*/ 545,
- /*0x118a6*/ 1339,
- /*0x104d1*/ 1279,
- /*0x0502*/ 422,
- -1,
- /*0xa68a*/ 1008,
- -1,
- /*0x03a7*/ 263,
- -1,
- /*0x10a4*/ 488,
- /*0x1e7e*/ 602,
- /*0xa680*/ 1003,
- /*0x1e22*/ 556,
- /*0x0204*/ 192,
- -1, -1,
- /*0x118af*/ 1348,
- /*0x216b*/ 833,
- /*0x038c*/ 238,
- /*0xa724*/ 1018,
- /*0x1f3b*/ 694,
- -1, -1,
- /*0x1eac*/ 627,
- -1,
- /*0x1e72*/ 596,
- /*0x1f5b*/ 710,
- /*0x0202*/ 191,
- /*0x03fe*/ 295,
- -1,
- /*0x01a4*/ 143,
- -1,
- /*0x1f4b*/ 702,
- -1, -1,
- /*0x1f1a*/ 679,
- -1,
- /*0x1ea8*/ 625,
- /*0x10cd*/ 523,
- /*0xff26*/ 1185,
- -1,
- /*0x1eb2*/ 630,
- /*0x24cd*/ 862,
- -1,
- /*0x019c*/ 138,
- /*0x050c*/ 427,
- -1,
- /*0x118a4*/ 1337,
- -1, -1,
- /*0x048c*/ 363,
- /*0xa698*/ 1015,
- /*0x1e2a*/ 560,
- /*0x0130*/ 1400,
- /*0xff2f*/ 1194,
- -1,
- /*0xabb0*/ 1152,
- /*0x0522*/ 438,
- /*0x1e2e*/ 562,
- /*0x01cd*/ 163,
- /*0x04fe*/ 420,
- -1,
- /*0x04a2*/ 374,
- /*0xa696*/ 1014,
- -1,
- /*0x1f69*/ 714,
- /*0x1fba*/ 776,
- -1, -1,
- /*0x020c*/ 196,
- /*0x03aa*/ 266,
- /*0xabba*/ 1162,
- /*0x2cb0*/ 951,
- -1, -1,
- /*0x04f2*/ 414,
- -1, -1, -1,
- /*0xa7b0*/ 1082,
- /*0x10cb0*/ 1330,
- /*0x0222*/ 207,
- -1, -1, -1,
- /*0xff24*/ 1183,
- -1,
- /*0x2cba*/ 956,
- -1,
- /*0x1fca*/ 787,
- /*0x004a*/ 8,
- /*0x014a*/ 93,
- -1,
- /*0xa686*/ 1006,
- -1, -1, -1,
- /*0x052a*/ 442,
- /*0x0184*/ 123,
- /*0x1e2c*/ 561,
- -1, -1,
- /*0x04aa*/ 378,
- /*0x052e*/ 444,
- /*0x01d1*/ 165,
- /*0xa690*/ 1011,
- -1, -1,
- /*0x04ae*/ 380,
- /*0x1fb8*/ 774,
- /*0x2cca*/ 964,
- -1,
- /*0x0182*/ 122,
- /*0x1e28*/ 559,
- /*0xabb8*/ 1160,
- -1,
- /*0x00ca*/ 36,
- /*0x1e32*/ 564,
- -1, -1, -1,
- /*0x022a*/ 211,
- /*0x10a7*/ 491,
- /*0x1eb0*/ 629,
- -1, -1, -1,
- /*0x022e*/ 213,
- /*0x1f0e*/ 675,
- /*0xfb14*/ 1176,
- /*0x2cb8*/ 955,
- /*0x03a8*/ 264,
- -1, -1, -1, -1, -1, -1,
- /*0x1eba*/ 634,
- -1,
- /*0xa69a*/ 1016,
- -1, -1,
- /*0x01a7*/ 145,
- /*0x052c*/ 443,
- /*0x10a2*/ 486,
- /*0xa692*/ 1012,
- /*0x1fd9*/ 795,
- /*0x0059*/ 23,
- /*0x04ac*/ 379,
- /*0x1ffa*/ 815,
- /*0x047a*/ 358,
- /*0x1fb6*/ 772,
- /*0xa77e*/ 1058,
- /*0x0136*/ 83,
- /*0xa722*/ 1017,
- -1,
- /*0xabb6*/ 1158,
- /*0x0528*/ 441,
- -1,
- /*0x118a7*/ 1340,
- /*0x1eca*/ 642,
- /*0x0532*/ 446,
- /*0x04a8*/ 377,
- /*0x01fe*/ 189,
- -1,
- /*0x01a2*/ 142,
- /*0x04b2*/ 382,
- /*0x022c*/ 212,
- /*0x104b2*/ 1248,
- /*0x212a*/ 819,
- -1, -1,
- /*0x2cb6*/ 954,
- /*0x00d9*/ 50,
- -1,
- /*0x1fcc*/ 789,
- /*0x004c*/ 10,
- /*0x014c*/ 94,
- /*0x01f2*/ 182,
- /*0xa7b6*/ 1087,
- /*0x1eb8*/ 633,
- /*0x0228*/ 210,
- /*0x118a2*/ 1335,
- -1,
- /*0x10aa*/ 494,
- /*0x0232*/ 215,
- -1, -1, -1, -1,
- /*0x10ae*/ 498,
- -1, -1, -1,
- /*0xa72a*/ 1021,
- -1,
- /*0x2ccc*/ 965,
- /*0xff27*/ 1186,
- /*0x1e30*/ 563,
- -1,
- /*0xa72e*/ 1023,
- -1,
- /*0x00cc*/ 38,
- -1,
- /*0x1fbc*/ 778,
- /*0x1fb4*/ 771,
- -1,
- /*0x0134*/ 82,
- /*0x1f2f*/ 690,
- /*0xabbc*/ 1164,
- /*0xabb4*/ 1156,
- /*0x01ae*/ 148,
- -1,
- /*0x1e3a*/ 568,
- -1, -1,
- /*0x03b0*/ 268,
- -1, -1, -1,
- /*0xff22*/ 1181,
- /*0x1efa*/ 666,
- /*0x118aa*/ 1343,
- /*0x1eb6*/ 632,
- -1,
- /*0x2cbc*/ 957,
- /*0x2cb4*/ 953,
- -1,
- /*0x118ae*/ 1347,
- -1,
- /*0x1fbe*/ 779,
- /*0x10ac*/ 496,
- /*0xa68e*/ 1010,
- /*0xa7b4*/ 1086,
- /*0x2132*/ 821,
- /*0xabbe*/ 1166,
- /*0x1e4a*/ 576,
- -1, -1, -1, -1,
- /*0xa72c*/ 1022,
- -1, -1,
- /*0xa694*/ 1013,
- /*0x10a8*/ 492,
- -1,
- /*0x1ecc*/ 643,
- /*0x04b0*/ 381,
- /*0x10b2*/ 502,
- /*0x104b0*/ 1246,
- /*0x2cbe*/ 958,
- /*0x01ac*/ 147,
- /*0x1f1c*/ 681,
- -1,
- /*0xa728*/ 1020,
- /*0x1e38*/ 567,
- -1,
- /*0x053a*/ 454,
- /*0xa732*/ 1024,
- /*0xff2a*/ 1189,
- /*0x13fa*/ 526,
- /*0x1f6b*/ 716,
- /*0x04ba*/ 386,
- -1,
- /*0x104ba*/ 1256,
- /*0xff2e*/ 1193,
- /*0x0230*/ 214,
- /*0x1f4d*/ 704,
- /*0x118ac*/ 1345,
- /*0x01b2*/ 151,
- -1, -1, -1, -1, -1,
- /*0x1ebc*/ 635,
- /*0x1eb4*/ 631,
- -1, -1, -1,
- /*0x054a*/ 470,
- /*0x023a*/ 216,
- /*0x118a8*/ 1341,
- -1, -1, -1,
- /*0x118b2*/ 1351,
- /*0x104ca*/ 1272,
- -1,
- /*0x1fc8*/ 785,
- /*0x0048*/ 7,
- -1,
- /*0x1fe2*/ 798,
- /*0x0462*/ 346,
- /*0x0162*/ 105,
- /*0xfb04*/ 1172,
- /*0x1e7a*/ 600,
- -1,
- /*0x1e36*/ 566,
- -1,
- /*0x0538*/ 452,
- /*0x1ebe*/ 636,
- /*0x2c62*/ 913,
- -1,
- /*0x024a*/ 226,
- /*0x04b8*/ 385,
- /*0xff2c*/ 1191,
- /*0x104b8*/ 1254,
- -1,
- /*0xfb02*/ 1170,
- /*0x2cc8*/ 963,
- -1, -1,
- /*0x2ce2*/ 976,
- /*0x03fa*/ 293,
- -1,
- /*0x00c8*/ 34,
- -1,
- /*0x1f85*/ 726,
- /*0x0405*/ 302,
- /*0xff28*/ 1187,
- /*0x10405*/ 1211,
- /*0x1e4c*/ 577,
- /*0xab85*/ 1109,
- /*0xff32*/ 1197,
- -1, -1, -1,
- /*0x2c05*/ 870,
- -1,
- /*0x10b0*/ 500,
- -1, -1,
- /*0x1fc4*/ 782,
- /*0x0044*/ 3,
- -1, -1, -1,
- /*0x1fd6*/ 792,
- /*0x0056*/ 20,
- /*0x0156*/ 99,
- -1, -1,
- /*0x0536*/ 450,
- -1,
- /*0x10ba*/ 510,
- /*0x04fa*/ 418,
- /*0x10c85*/ 1287,
- /*0x04b6*/ 384,
- /*0x24ba*/ 843,
- /*0x104b6*/ 1252,
- /*0x1e3c*/ 569,
- /*0x1e34*/ 565,
- -1,
- /*0x2cc4*/ 961,
- /*0xa73a*/ 1028,
- -1,
- /*0x1e905*/ 1370,
- -1,
- /*0x2cd6*/ 970,
- /*0x00c4*/ 30,
- /*0x1ec8*/ 641,
- /*0x1f0c*/ 673,
- -1,
- /*0x1ee2*/ 654,
- /*0x00d6*/ 48,
- -1,
- /*0x054c*/ 472,
- /*0x118b0*/ 1349,
- -1, -1, -1,
- /*0x24ca*/ 859,
- -1,
- /*0x104cc*/ 1274,
- -1,
- /*0xa64a*/ 985,
- /*0x1e3e*/ 570,
- /*0xa74a*/ 1036,
- -1, -1, -1, -1,
- /*0x118ba*/ 1359,
- -1, -1, -1, -1,
- /*0x10b8*/ 508,
- /*0x01ca*/ 161,
- -1,
- /*0x024c*/ 227,
- /*0x24b8*/ 841,
- -1, -1, -1,
- /*0x053c*/ 456,
- /*0x0534*/ 448,
- /*0xa738*/ 1027,
- -1, -1,
- /*0x04bc*/ 387,
- /*0x04b4*/ 383,
- /*0x104bc*/ 1258,
- /*0x104b4*/ 1250,
- /*0x1ec4*/ 639,
- /*0xff30*/ 1195,
- /*0x1fc2*/ 780,
- /*0x0042*/ 1,
- /*0x01b8*/ 155,
- /*0x1ed6*/ 648,
- /*0xa684*/ 1005,
- /*0x0050*/ 14,
- /*0x0150*/ 96,
- /*0x1f2a*/ 685,
- /*0x1fd2*/ 790,
- /*0x0052*/ 16,
- /*0x0152*/ 97,
- -1, -1,
- /*0x1f2e*/ 689,
- /*0xff3a*/ 1205,
- /*0x053e*/ 458,
- -1, -1,
- /*0xa682*/ 1004,
- /*0x118b8*/ 1357,
- /*0x04be*/ 388,
- /*0x2cc2*/ 960,
- /*0x104be*/ 1260,
- -1,
- /*0x10b6*/ 506,
- /*0x2cd0*/ 967,
- -1,
- /*0x00c2*/ 28,
- /*0x24b6*/ 839,
- /*0x2cd2*/ 968,
- /*0x1e48*/ 575,
- /*0x00d0*/ 42,
- -1,
- /*0x1e62*/ 588,
- /*0xa736*/ 1026,
- /*0x00d2*/ 44,
- -1, -1, -1,
- /*0x023e*/ 219,
- /*0x01d9*/ 169,
- /*0x004e*/ 12,
- /*0x014e*/ 95,
- /*0x01fa*/ 187,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x03e2*/ 280,
- /*0x24cc*/ 861,
- -1,
- /*0x1f2c*/ 687,
- -1,
- /*0xa64c*/ 986,
- /*0xff38*/ 1203,
- /*0xa74c*/ 1037,
- -1,
- /*0xa68c*/ 1009,
- /*0x2cce*/ 966,
- /*0x118b6*/ 1355,
- -1, -1,
- /*0x1fc6*/ 783,
- /*0x0046*/ 5,
- /*0x00ce*/ 40,
- /*0x1f28*/ 683,
- -1,
- /*0x1ffc*/ 817,
- /*0x047c*/ 359,
- /*0x1ec2*/ 638,
- -1,
- /*0x1e44*/ 573,
- /*0x0548*/ 468,
- /*0x1ed0*/ 645,
- /*0x10bc*/ 512,
- /*0x10b4*/ 504,
- /*0x1e56*/ 582,
- /*0x1ed2*/ 646,
- /*0x24bc*/ 845,
- /*0x104c8*/ 1270,
- /*0x04e2*/ 406,
- -1, -1,
- /*0x2cc6*/ 962,
- /*0xa73c*/ 1029,
- /*0xa734*/ 1025,
- /*0x1fec*/ 807,
- /*0x046c*/ 351,
- /*0x016c*/ 110,
- /*0x00c6*/ 32,
- -1, -1, -1, -1,
- /*0x03d6*/ 274,
- /*0x01bc*/ 156,
- /*0x0248*/ 225,
- /*0xff36*/ 1201,
- -1, -1,
- /*0x10be*/ 514,
- -1, -1, -1,
- /*0x24be*/ 847,
- /*0x1fea*/ 805,
- /*0x046a*/ 350,
- /*0x016a*/ 109,
- -1,
- /*0x1ece*/ 644,
- /*0xa73e*/ 1030,
- -1,
- /*0x118bc*/ 1361,
- /*0x118b4*/ 1353,
- /*0x1fab*/ 764,
- /*0x042b*/ 340,
- /*0x0544*/ 464,
- /*0x1f81*/ 722,
- /*0x0401*/ 298,
- /*0xabab*/ 1147,
- /*0x10401*/ 1207,
- /*0x0556*/ 482,
- /*0xab81*/ 1105,
- /*0x104c4*/ 1266,
- /*0x2c2b*/ 908,
- -1,
- /*0x04d6*/ 400,
- /*0x2c01*/ 866,
- -1,
- /*0x013f*/ 87,
- -1, -1,
- /*0xabbf*/ 1167,
- -1,
- /*0x1ec6*/ 640,
- /*0x1fe8*/ 803,
- /*0x0468*/ 349,
- /*0x0168*/ 108,
- /*0x118be*/ 1363,
- /*0x1efc*/ 667,
- /*0x0244*/ 222,
- -1,
- /*0xa7ab*/ 1078,
- /*0x10cab*/ 1325,
- -1,
- /*0x1e42*/ 572,
- /*0x10c81*/ 1283,
- -1,
- /*0x2162*/ 824,
- /*0x1e50*/ 579,
- -1,
- /*0xff34*/ 1199,
- -1,
- /*0x1e52*/ 580,
- -1,
- /*0x1c88*/ 538,
- /*0x1e901*/ 1366,
- -1,
- /*0x1eec*/ 659,
- /*0x1fe4*/ 800,
- /*0x0464*/ 347,
- /*0x0164*/ 106,
- -1,
- /*0x03c2*/ 269,
- /*0x24c8*/ 857,
- -1,
- /*0x1f3a*/ 693,
- /*0x03d0*/ 271,
- /*0xa648*/ 984,
- /*0x2c64*/ 915,
- /*0xa748*/ 1035,
- /*0xa662*/ 997,
- -1,
- /*0xa762*/ 1048,
- -1, -1, -1,
- /*0x1eea*/ 658,
- /*0x1c80*/ 530,
- /*0x13fc*/ 528,
- -1,
- /*0x01c8*/ 160,
- /*0x1fa9*/ 762,
- /*0x0429*/ 338,
- /*0x01e2*/ 173,
- /*0x1e4e*/ 578,
- /*0x1c83*/ 533,
- /*0xaba9*/ 1145,
- -1,
- /*0x1f4a*/ 701,
- /*0x0542*/ 462,
- -1,
- /*0x2c29*/ 906,
- -1,
- /*0x0550*/ 476,
- -1, -1,
- /*0x104c2*/ 1264,
- /*0x0552*/ 478,
- /*0x04d0*/ 397,
- -1,
- /*0x104d0*/ 1278,
- -1,
- /*0x04d2*/ 398,
- /*0x10c4*/ 520,
- /*0x104d2*/ 1280,
- -1,
- /*0x1ee8*/ 657,
- /*0x24c4*/ 853,
- /*0x1f38*/ 691,
- /*0x1e46*/ 574,
- /*0x10ca9*/ 1323,
- /*0xa644*/ 982,
- -1,
- /*0xa744*/ 1033,
- /*0x1e7c*/ 601,
- -1,
- /*0xa656*/ 991,
- -1,
- /*0xa756*/ 1042,
- /*0x0460*/ 345,
- /*0x0160*/ 104,
- -1, -1, -1,
- /*0x01c4*/ 157,
- -1, -1, -1,
- /*0x2c60*/ 912,
- /*0x054e*/ 474,
- /*0x1ee4*/ 655,
- -1, -1,
- /*0x1e6c*/ 593,
- /*0x046e*/ 352,
- /*0x016e*/ 111,
- /*0x104ce*/ 1276,
- -1, -1,
- /*0x2ce0*/ 975,
- -1, -1, -1,
- /*0x2c6e*/ 920,
- -1, -1,
- /*0x1f59*/ 709,
- -1,
- /*0x1fe6*/ 801,
- /*0x0466*/ 348,
- /*0x0166*/ 107,
- /*0x03ec*/ 285,
- /*0x1e6a*/ 592,
- /*0x024e*/ 228,
- /*0x0546*/ 466,
- -1, -1,
- /*0x013d*/ 86,
- -1,
- /*0x1c86*/ 536,
- /*0xabbd*/ 1165,
- /*0x104c6*/ 1268,
- -1, -1,
- /*0x04fc*/ 419,
- -1, -1,
- /*0x1fda*/ 796,
- /*0x005a*/ 24,
- /*0x015a*/ 101,
- /*0x03ea*/ 284,
- /*0x1fd8*/ 794,
- /*0x0058*/ 22,
- /*0x0158*/ 100,
- -1,
- /*0x1f4c*/ 703,
- -1,
- /*0x10c2*/ 518,
- /*0x0246*/ 224,
- /*0x03ab*/ 267,
- -1,
- /*0x24c2*/ 851,
- /*0x1e68*/ 591,
- /*0x04ec*/ 411,
- -1,
- /*0xa642*/ 981,
- -1,
- /*0xa742*/ 1032,
- /*0x2cda*/ 972,
- /*0xa650*/ 988,
- /*0x1ee0*/ 653,
- /*0xa750*/ 1039,
- /*0x2cd8*/ 971,
- /*0xa652*/ 989,
- /*0x00da*/ 51,
- /*0xa752*/ 1040,
- /*0x0054*/ 18,
- /*0x0154*/ 98,
- /*0x00d8*/ 49,
- -1,
- /*0x03e8*/ 283,
- -1,
- /*0x04ea*/ 410,
- /*0x2cc0*/ 959,
- /*0x1f3c*/ 695,
- /*0x1eee*/ 660,
- /*0x1e64*/ 589,
- -1, -1,
- /*0x00c0*/ 26,
- -1, -1,
- /*0x015e*/ 103,
- /*0x1fc7*/ 784,
- /*0x0047*/ 6,
- /*0x0147*/ 91,
- /*0x2cd4*/ 969,
- -1, -1,
- /*0x053f*/ 459,
- /*0x1ee6*/ 656,
- /*0x24ce*/ 863,
- /*0x00d4*/ 46,
- -1,
- /*0x03e4*/ 281,
- /*0xa64e*/ 987,
- /*0x104bf*/ 1261,
- /*0xa74e*/ 1038,
- -1, -1,
- /*0x1f3e*/ 697,
- /*0x2cde*/ 974,
- /*0x04e8*/ 409,
- /*0x1fb9*/ 775,
- -1,
- /*0x0139*/ 84,
- -1,
- /*0x00de*/ 55,
- /*0xabb9*/ 1161,
- /*0x1eda*/ 650,
- /*0x00c7*/ 33,
- -1, -1,
- /*0x1ed8*/ 649,
- -1, -1,
- /*0x24c6*/ 855,
- /*0x03a9*/ 265,
- -1, -1,
- /*0xa646*/ 983,
- /*0x216c*/ 834,
- /*0xa746*/ 1034,
- -1,
- /*0x1ec0*/ 637,
- -1,
- /*0x04e4*/ 407,
- -1,
- /*0x015c*/ 102,
- /*0x1fa1*/ 754,
- /*0x0421*/ 330,
- -1,
- /*0x10421*/ 1239,
- -1,
- /*0xaba1*/ 1137,
- -1,
- /*0x1e60*/ 587,
- /*0x1ed4*/ 647,
- /*0x01fc*/ 188,
- /*0x2c21*/ 898,
- /*0x216a*/ 832,
- -1, -1, -1,
- /*0xa66c*/ 1002,
- -1,
- /*0xa76c*/ 1053,
- /*0x2cdc*/ 973,
- -1,
- /*0x212b*/ 820,
- -1,
- /*0x1e6e*/ 594,
- /*0x1ede*/ 652,
- /*0x00dc*/ 53,
- /*0x03e0*/ 279,
- -1, -1,
- /*0x01ec*/ 178,
- /*0x10ca1*/ 1315,
- -1,
- /*0x1f48*/ 699,
- /*0x0045*/ 4,
- /*0x0145*/ 90,
- /*0xa66a*/ 1001,
- /*0x10ab*/ 495,
- /*0xa76a*/ 1052,
- /*0x1e66*/ 590,
- -1,
- /*0x1e921*/ 1398,
- /*0x03ee*/ 286,
- /*0x2168*/ 830,
- -1,
- /*0x1fc3*/ 781,
- /*0x0043*/ 2,
- /*0x0143*/ 89,
- -1,
- /*0x01ea*/ 177,
- /*0x10bf*/ 515,
- /*0xfb05*/ 1173,
- -1,
- /*0x0345*/ 229,
- /*0x24bf*/ 848,
- -1, -1,
- /*0x03e6*/ 282,
- /*0x1e5a*/ 584,
- /*0x04e0*/ 405,
- /*0x00c5*/ 31,
- /*0x0181*/ 121,
- /*0x1e58*/ 583,
- -1, -1, -1,
- /*0xa668*/ 1000,
- /*0x2164*/ 826,
- /*0xa768*/ 1051,
- -1, -1,
- /*0x1edc*/ 651,
- /*0x00c3*/ 29,
- /*0x1e40*/ 571,
- /*0x04ee*/ 412,
- /*0x118ab*/ 1344,
- /*0x03da*/ 276,
- -1, -1,
- /*0x01e8*/ 176,
- /*0x03d8*/ 275,
- -1,
- /*0x1f56*/ 708,
- -1, -1, -1,
- /*0x1e54*/ 581,
- -1,
- /*0x118bf*/ 1364,
- /*0x04e6*/ 408,
- /*0xa664*/ 998,
- /*0x053d*/ 457,
- /*0xa764*/ 1049,
- /*0x1fc9*/ 786,
- /*0x0049*/ 1399,
- /*0x0149*/ 92,
- -1, -1,
- /*0x104bd*/ 1259,
- /*0x1f97*/ 744,
- /*0x0417*/ 320,
- /*0x1e5e*/ 586,
- /*0x10417*/ 1229,
- /*0x01e4*/ 174,
- /*0xab97*/ 1127,
- /*0x10a9*/ 493,
- /*0x1fad*/ 766,
- /*0x042d*/ 342,
- /*0x04da*/ 402,
- /*0x2c17*/ 888,
- -1,
- /*0xabad*/ 1149,
- /*0x04d8*/ 401,
- /*0xff2b*/ 1190,
- -1,
- /*0x023d*/ 218,
- /*0x2c2d*/ 910,
- -1,
- /*0x0540*/ 460,
- /*0x03de*/ 278,
- /*0x00c9*/ 35,
- -1, -1,
- /*0x04c0*/ 389,
- -1,
- /*0x104c0*/ 1262,
- /*0x01a9*/ 146,
- /*0x2160*/ 822,
- /*0x10c97*/ 1305,
- -1, -1,
- /*0x0554*/ 480,
- /*0x1fb3*/ 770,
- -1,
- /*0xa7ad*/ 1080,
- /*0x10cad*/ 1327,
- /*0x04d4*/ 399,
- /*0xabb3*/ 1155,
- /*0x1e917*/ 1388,
- -1, -1, -1,
- /*0x216e*/ 836,
- /*0x118a9*/ 1342,
- -1, -1, -1,
- /*0x1e5c*/ 585,
- -1,
- /*0x0547*/ 467,
- /*0xa660*/ 996,
- /*0x04de*/ 404,
- /*0xa760*/ 1047,
- -1,
- /*0x04c7*/ 393,
- /*0x1f50*/ 705,
- /*0x104c7*/ 1269,
- /*0x2166*/ 828,
- -1,
- /*0x1f52*/ 706,
- /*0xa7b3*/ 1085,
- -1, -1,
- /*0x01e0*/ 172,
- -1,
- /*0x03dc*/ 277,
- -1,
- /*0xa76e*/ 1054,
- /*0x03a1*/ 258,
- /*0x0539*/ 453,
- -1,
- /*0x1e97*/ 615,
- -1, -1, -1, -1,
- /*0x104b9*/ 1255,
- -1,
- /*0x01ee*/ 179,
- /*0x10bd*/ 513,
- /*0xa666*/ 999,
- /*0xff29*/ 1188,
- /*0xa766*/ 1050,
- /*0x24bd*/ 846,
- /*0x1fa5*/ 758,
- /*0x0425*/ 334,
- -1,
- /*0x10425*/ 1243,
- -1,
- /*0xaba5*/ 1141,
- /*0x1fb7*/ 773,
- -1, -1,
- /*0x01e6*/ 175,
- /*0x2c25*/ 902,
- /*0xabb7*/ 1159,
- -1,
- /*0x04dc*/ 403,
- -1,
- /*0xa65a*/ 993,
- -1,
- /*0xa75a*/ 1044,
- -1,
- /*0xa658*/ 992,
- -1,
- /*0xa758*/ 1043,
- /*0x10c0*/ 516,
- -1, -1, -1,
- /*0x24c0*/ 849,
- -1, -1,
- /*0x10ca5*/ 1319,
- /*0xa640*/ 980,
- -1,
- /*0xa740*/ 1031,
- /*0x118bd*/ 1362,
- /*0x1fa3*/ 756,
- /*0x0423*/ 332,
- -1,
- /*0x10423*/ 1241,
- /*0x1c84*/ 534,
- /*0xaba3*/ 1139,
- -1, -1,
- /*0x0545*/ 465,
- /*0xa654*/ 990,
- /*0x2c23*/ 900,
- /*0xa754*/ 1041,
- -1,
- /*0x04c5*/ 392,
- -1,
- /*0x104c5*/ 1267,
- -1, -1,
- /*0x1c82*/ 532,
- /*0x10c7*/ 522,
- /*0x0543*/ 463,
- -1,
- /*0x1f6c*/ 717,
- /*0x24c7*/ 856,
- /*0xa65e*/ 995,
- /*0x04c3*/ 391,
- /*0xa75e*/ 1046,
- /*0x104c3*/ 1265,
- -1,
- /*0x10ca3*/ 1317,
- -1, -1,
- /*0x0245*/ 223,
- /*0x1ff4*/ 810,
- /*0x0474*/ 355,
- /*0x0174*/ 114,
- -1,
- /*0x01de*/ 171,
- -1,
- /*0x10b9*/ 509,
- /*0x01c7*/ 159,
- /*0x1f6a*/ 715,
- /*0xfb01*/ 1169,
- /*0x24b9*/ 842,
- /*0x0243*/ 221,
- -1, -1,
- /*0x0397*/ 248,
- -1, -1,
- /*0x1f2b*/ 686,
- /*0x1f9d*/ 750,
- /*0x041d*/ 326,
- -1,
- /*0x1041d*/ 1235,
- /*0xabb1*/ 1153,
- /*0xab9d*/ 1133,
- /*0x0470*/ 353,
- /*0x0170*/ 112,
- /*0x1f9b*/ 748,
- /*0x041b*/ 324,
- /*0x2c1d*/ 894,
- /*0x1041b*/ 1233,
- /*0x1f3f*/ 698,
- /*0xab9b*/ 1131,
- /*0x10a1*/ 485,
- /*0x2c70*/ 922,
- /*0xabb5*/ 1157,
- /*0x0549*/ 469,
- /*0x2c1b*/ 892,
- /*0xa65c*/ 994,
- /*0x1f68*/ 713,
- /*0xa75c*/ 1045,
- /*0x04c9*/ 394,
- -1,
- /*0x104c9*/ 1271,
- /*0x0370*/ 230,
- /*0x118b9*/ 1358,
- /*0xa7b1*/ 1083,
- /*0x10cb1*/ 1331,
- /*0x10c9d*/ 1311,
- -1,
- /*0x1f99*/ 746,
- /*0x0419*/ 322,
- -1,
- /*0x10419*/ 1231,
- -1,
- /*0xab99*/ 1129,
- /*0x10c9b*/ 1309,
- /*0x00b5*/ 25,
- /*0x1e91d*/ 1394,
- -1,
- /*0x2c19*/ 890,
- -1,
- /*0x1f93*/ 740,
- /*0x0413*/ 316,
- /*0x10c5*/ 521,
- /*0x10413*/ 1225,
- /*0x1e91b*/ 1392,
- /*0xab93*/ 1123,
- /*0x24c5*/ 854,
- -1, -1,
- /*0x118a1*/ 1334,
- /*0x2c13*/ 884,
- /*0x1ef4*/ 663,
- -1,
- /*0x0533*/ 447,
- /*0x10c3*/ 519,
- /*0x0041*/ 0,
- /*0x0141*/ 88,
- /*0x10c99*/ 1307,
- /*0x24c3*/ 852,
- -1,
- /*0x104b3*/ 1249,
- /*0xff39*/ 1204,
- -1,
- /*0x01c5*/ 158,
- /*0x1f29*/ 684,
- -1, -1,
- /*0x1e919*/ 1390,
- -1,
- /*0x10c93*/ 1301,
- /*0x1f8f*/ 736,
- /*0x040f*/ 312,
- -1,
- /*0x1040f*/ 1221,
- /*0x1ef0*/ 661,
- /*0xab8f*/ 1119,
- -1,
- /*0x1e9b*/ 619,
- /*0x03a5*/ 261,
- /*0x1e913*/ 1384,
- /*0x2c0f*/ 880,
- /*0x00c1*/ 27,
- -1, -1, -1,
- /*0x1f8b*/ 732,
- /*0x040b*/ 308,
- /*0xff21*/ 1180,
- /*0x1040b*/ 1217,
- -1,
- /*0xab8b*/ 1115,
- /*0x1f87*/ 728,
- /*0x0407*/ 304,
- /*0xab7b*/ 1099,
- /*0x10407*/ 1213,
- /*0x2c0b*/ 876,
- /*0xab87*/ 1111,
- /*0x0587*/ 483,
- -1,
- /*0x10c8f*/ 1297,
- /*0x1e99*/ 617,
- /*0x2c07*/ 872,
- /*0x004f*/ 13,
- -1, -1, -1,
- /*0x24c9*/ 858,
- -1,
- /*0xab79*/ 1097,
- /*0x1e90f*/ 1380,
- -1,
- /*0x0537*/ 451,
- /*0x03a3*/ 259,
- /*0xa78b*/ 1063,
- /*0x10c8b*/ 1293,
- /*0x10ad*/ 497,
- /*0x1f6e*/ 719,
- -1,
- /*0x104b7*/ 1253,
- -1,
- /*0x10c87*/ 1289,
- -1, -1, -1,
- /*0x1e90b*/ 1376,
- -1, -1,
- /*0x1e74*/ 597,
- /*0x00cf*/ 41,
- /*0x0197*/ 136,
- /*0x1e907*/ 1372,
- -1,
- /*0xab71*/ 1089,
- /*0xab73*/ 1091,
- -1, -1, -1, -1,
- /*0x1f3d*/ 696,
- -1, -1,
- /*0x10b3*/ 503,
- -1,
- /*0xab7f*/ 1103,
- -1,
- /*0x03f4*/ 289,
- /*0x1f9f*/ 752,
- /*0x041f*/ 328,
- /*0xab7d*/ 1101,
- /*0x1041f*/ 1237,
- /*0x1e70*/ 595,
- /*0xab9f*/ 1135,
- -1,
- /*0x118ad*/ 1346,
- -1, -1,
- /*0x2c1f*/ 896,
- -1, -1, -1, -1, -1,
- /*0x01b3*/ 152,
- /*0x039d*/ 254,
- -1, -1, -1, -1,
- /*0x03f0*/ 287,
- /*0xab75*/ 1093,
- -1,
- /*0x039b*/ 252,
- -1, -1, -1,
- /*0x10c9f*/ 1313,
- -1,
- /*0x04f4*/ 415,
- /*0x1f54*/ 707,
- /*0x118b3*/ 1352,
- -1,
- /*0x1ff8*/ 813,
- /*0x0478*/ 357,
- /*0x0178*/ 116,
- -1,
- /*0x1e91f*/ 1396,
- -1, -1, -1,
- /*0x0531*/ 445,
- -1,
- /*0xff2d*/ 1192,
- -1,
- /*0x10a5*/ 489,
- /*0x0399*/ 250,
- -1,
- /*0x104b1*/ 1247,
- -1, -1,
- /*0x10b7*/ 507,
- /*0x04f0*/ 413,
- /*0x0535*/ 449,
- -1,
- /*0x24b7*/ 840,
- /*0x1f95*/ 742,
- /*0x0415*/ 318,
- /*0x0393*/ 244,
- /*0x10415*/ 1227,
- /*0x104b5*/ 1251,
- /*0xab95*/ 1125,
- -1, -1, -1, -1,
- /*0x2c15*/ 886,
- -1,
- /*0x1f39*/ 692,
- /*0xff33*/ 1198,
- -1, -1,
- /*0x01b7*/ 154,
- -1, -1, -1, -1,
- /*0xab77*/ 1095,
- -1,
- /*0x10a3*/ 487,
- -1,
- /*0x1f91*/ 738,
- /*0x0411*/ 314,
- /*0x118a5*/ 1338,
- /*0x10411*/ 1223,
- /*0x10c95*/ 1303,
- /*0xab91*/ 1121,
- -1,
- /*0x038f*/ 240,
- /*0x118b7*/ 1356,
- -1,
- /*0x2c11*/ 882,
- -1, -1, -1,
- /*0x1e915*/ 1386,
- -1,
- /*0x1f8d*/ 734,
- /*0x040d*/ 310,
- /*0x0541*/ 461,
- /*0x1040d*/ 1219,
- -1,
- /*0xab8d*/ 1117,
- -1,
- /*0x04c1*/ 390,
- /*0x1ef8*/ 665,
- /*0x104c1*/ 1263,
- /*0x2c0d*/ 878,
- -1, -1,
- /*0x10c91*/ 1299,
- -1, -1, -1, -1, -1, -1,
- /*0x118a3*/ 1336,
- -1,
- /*0x03cf*/ 270,
- /*0x1e911*/ 1382,
- /*0xff25*/ 1184,
- -1,
- /*0x0241*/ 220,
- -1,
- /*0xa78d*/ 1064,
- /*0x10c8d*/ 1295,
- /*0xff37*/ 1202,
- -1,
- /*0x10b1*/ 501,
- -1, -1, -1,
- /*0x01f4*/ 183,
- -1, -1,
- /*0x1e90d*/ 1378,
- -1, -1, -1, -1,
- /*0x10b5*/ 505,
- -1, -1, -1,
- /*0x13f8*/ 524,
- /*0x054f*/ 475,
- -1, -1, -1,
- /*0x01b1*/ 150,
- /*0x019d*/ 139,
- -1,
- /*0x104cf*/ 1277,
- -1,
- /*0xff23*/ 1182,
- /*0x01f0*/ 180,
- -1, -1, -1, -1, -1,
- /*0x01b5*/ 153,
- -1,
- /*0x039f*/ 256,
- -1, -1,
- /*0x118b1*/ 1350,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0x118b5*/ 1354,
- /*0xfb17*/ 1179,
- /*0x1e78*/ 599,
- -1, -1, -1,
- /*0x1f49*/ 700,
- -1,
- /*0x10c1*/ 517,
- -1, -1, -1,
- /*0x24c1*/ 850,
- -1, -1,
- /*0x0193*/ 133,
- -1, -1, -1,
- /*0x1f2d*/ 688,
- -1, -1, -1, -1, -1, -1,
- /*0xff31*/ 1196,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0xff35*/ 1200,
- -1, -1, -1, -1,
- /*0x0395*/ 246,
- -1,
- /*0x018f*/ 130,
- -1, -1, -1, -1, -1, -1,
- /*0x04f8*/ 417,
- -1, -1, -1, -1, -1,
- /*0xab76*/ 1094,
- /*0x24cf*/ 864,
- /*0x018b*/ 128,
- -1, -1, -1, -1, -1,
- /*0x0187*/ 125,
- -1,
- /*0x0391*/ 242,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x01cf*/ 164,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x019f*/ 140,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x1c85*/ 535,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x01f8*/ 186,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x1f1d*/ 682,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x1f1b*/ 680,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x0191*/ 132,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x1f19*/ 678,
- /*0xfb13*/ 1175,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x1f0f*/ 676,
- -1, -1, -1, -1,
- /*0xab7e*/ 1102,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0x1f0b*/ 672,
- -1, -1, -1, -1,
- /*0xab72*/ 1090,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x1c81*/ 531,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0xfb15*/ 1177,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0x1f0d*/ 674,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0xab7a*/ 1098,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0xab7c*/ 1100,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x1c87*/ 537,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0xab74*/ 1092,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0xab70*/ 1088,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0xab78*/ 1096
- };
-
- if (code <= MAX_CODE_VALUE && code >= MIN_CODE_VALUE)
- {
- register int key = onigenc_unicode_CaseFold_11_hash(code);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register short s = wordlist[key];
-
- if (s >= 0 && code1_equal(code, CaseFold_11_Table[s].from))
- return &CaseFold_11_Table[s].to;
- }
- }
- return 0;
-}
-
-static const CaseUnfold_11_Type CaseUnfold_11_Table[] = {
-#define CaseUnfold_11 (*(CaseUnfold_11_Type (*)[1266])(CaseUnfold_11_Table+0))
- {0x0061, {1|U, {0x0041}}},
- {0x0062, {1|U, {0x0042}}},
- {0x0063, {1|U, {0x0043}}},
- {0x0064, {1|U, {0x0044}}},
- {0x0065, {1|U, {0x0045}}},
- {0x0066, {1|U, {0x0046}}},
- {0x0067, {1|U, {0x0047}}},
- {0x0068, {1|U, {0x0048}}},
- {0x006a, {1|U, {0x004a}}},
- {0x006b, {2|U, {0x004b, 0x212a}}},
- {0x006c, {1|U, {0x004c}}},
- {0x006d, {1|U, {0x004d}}},
- {0x006e, {1|U, {0x004e}}},
- {0x006f, {1|U, {0x004f}}},
- {0x0070, {1|U, {0x0050}}},
- {0x0071, {1|U, {0x0051}}},
- {0x0072, {1|U, {0x0052}}},
- {0x0073, {2|U, {0x0053, 0x017f}}},
- {0x0074, {1|U, {0x0054}}},
- {0x0075, {1|U, {0x0055}}},
- {0x0076, {1|U, {0x0056}}},
- {0x0077, {1|U, {0x0057}}},
- {0x0078, {1|U, {0x0058}}},
- {0x0079, {1|U, {0x0059}}},
- {0x007a, {1|U, {0x005a}}},
- {0x00e0, {1|U, {0x00c0}}},
- {0x00e1, {1|U, {0x00c1}}},
- {0x00e2, {1|U, {0x00c2}}},
- {0x00e3, {1|U, {0x00c3}}},
- {0x00e4, {1|U, {0x00c4}}},
- {0x00e5, {2|U, {0x00c5, 0x212b}}},
- {0x00e6, {1|U, {0x00c6}}},
- {0x00e7, {1|U, {0x00c7}}},
- {0x00e8, {1|U, {0x00c8}}},
- {0x00e9, {1|U, {0x00c9}}},
- {0x00ea, {1|U, {0x00ca}}},
- {0x00eb, {1|U, {0x00cb}}},
- {0x00ec, {1|U, {0x00cc}}},
- {0x00ed, {1|U, {0x00cd}}},
- {0x00ee, {1|U, {0x00ce}}},
- {0x00ef, {1|U, {0x00cf}}},
- {0x00f0, {1|U, {0x00d0}}},
- {0x00f1, {1|U, {0x00d1}}},
- {0x00f2, {1|U, {0x00d2}}},
- {0x00f3, {1|U, {0x00d3}}},
- {0x00f4, {1|U, {0x00d4}}},
- {0x00f5, {1|U, {0x00d5}}},
- {0x00f6, {1|U, {0x00d6}}},
- {0x00f8, {1|U, {0x00d8}}},
- {0x00f9, {1|U, {0x00d9}}},
- {0x00fa, {1|U, {0x00da}}},
- {0x00fb, {1|U, {0x00db}}},
- {0x00fc, {1|U, {0x00dc}}},
- {0x00fd, {1|U, {0x00dd}}},
- {0x00fe, {1|U, {0x00de}}},
- {0x00ff, {1|U, {0x0178}}},
- {0x0101, {1|U, {0x0100}}},
- {0x0103, {1|U, {0x0102}}},
- {0x0105, {1|U, {0x0104}}},
- {0x0107, {1|U, {0x0106}}},
- {0x0109, {1|U, {0x0108}}},
- {0x010b, {1|U, {0x010a}}},
- {0x010d, {1|U, {0x010c}}},
- {0x010f, {1|U, {0x010e}}},
- {0x0111, {1|U, {0x0110}}},
- {0x0113, {1|U, {0x0112}}},
- {0x0115, {1|U, {0x0114}}},
- {0x0117, {1|U, {0x0116}}},
- {0x0119, {1|U, {0x0118}}},
- {0x011b, {1|U, {0x011a}}},
- {0x011d, {1|U, {0x011c}}},
- {0x011f, {1|U, {0x011e}}},
- {0x0121, {1|U, {0x0120}}},
- {0x0123, {1|U, {0x0122}}},
- {0x0125, {1|U, {0x0124}}},
- {0x0127, {1|U, {0x0126}}},
- {0x0129, {1|U, {0x0128}}},
- {0x012b, {1|U, {0x012a}}},
- {0x012d, {1|U, {0x012c}}},
- {0x012f, {1|U, {0x012e}}},
- {0x0133, {1|U, {0x0132}}},
- {0x0135, {1|U, {0x0134}}},
- {0x0137, {1|U, {0x0136}}},
- {0x013a, {1|U, {0x0139}}},
- {0x013c, {1|U, {0x013b}}},
- {0x013e, {1|U, {0x013d}}},
- {0x0140, {1|U, {0x013f}}},
- {0x0142, {1|U, {0x0141}}},
- {0x0144, {1|U, {0x0143}}},
- {0x0146, {1|U, {0x0145}}},
- {0x0148, {1|U, {0x0147}}},
- {0x014b, {1|U, {0x014a}}},
- {0x014d, {1|U, {0x014c}}},
- {0x014f, {1|U, {0x014e}}},
- {0x0151, {1|U, {0x0150}}},
- {0x0153, {1|U, {0x0152}}},
- {0x0155, {1|U, {0x0154}}},
- {0x0157, {1|U, {0x0156}}},
- {0x0159, {1|U, {0x0158}}},
- {0x015b, {1|U, {0x015a}}},
- {0x015d, {1|U, {0x015c}}},
- {0x015f, {1|U, {0x015e}}},
- {0x0161, {1|U, {0x0160}}},
- {0x0163, {1|U, {0x0162}}},
- {0x0165, {1|U, {0x0164}}},
- {0x0167, {1|U, {0x0166}}},
- {0x0169, {1|U, {0x0168}}},
- {0x016b, {1|U, {0x016a}}},
- {0x016d, {1|U, {0x016c}}},
- {0x016f, {1|U, {0x016e}}},
- {0x0171, {1|U, {0x0170}}},
- {0x0173, {1|U, {0x0172}}},
- {0x0175, {1|U, {0x0174}}},
- {0x0177, {1|U, {0x0176}}},
- {0x017a, {1|U, {0x0179}}},
- {0x017c, {1|U, {0x017b}}},
- {0x017e, {1|U, {0x017d}}},
- {0x0180, {1|U, {0x0243}}},
- {0x0183, {1|U, {0x0182}}},
- {0x0185, {1|U, {0x0184}}},
- {0x0188, {1|U, {0x0187}}},
- {0x018c, {1|U, {0x018b}}},
- {0x0192, {1|U, {0x0191}}},
- {0x0195, {1|U, {0x01f6}}},
- {0x0199, {1|U, {0x0198}}},
- {0x019a, {1|U, {0x023d}}},
- {0x019e, {1|U, {0x0220}}},
- {0x01a1, {1|U, {0x01a0}}},
- {0x01a3, {1|U, {0x01a2}}},
- {0x01a5, {1|U, {0x01a4}}},
- {0x01a8, {1|U, {0x01a7}}},
- {0x01ad, {1|U, {0x01ac}}},
- {0x01b0, {1|U, {0x01af}}},
- {0x01b4, {1|U, {0x01b3}}},
- {0x01b6, {1|U, {0x01b5}}},
- {0x01b9, {1|U, {0x01b8}}},
- {0x01bd, {1|U, {0x01bc}}},
- {0x01bf, {1|U, {0x01f7}}},
- {0x01c6, {2|U|ST, {0x01c4, 0x01c5}}},
- {0x01c9, {2|U|ST, {0x01c7, 0x01c8}}},
- {0x01cc, {2|U|ST, {0x01ca, 0x01cb}}},
- {0x01ce, {1|U, {0x01cd}}},
- {0x01d0, {1|U, {0x01cf}}},
- {0x01d2, {1|U, {0x01d1}}},
- {0x01d4, {1|U, {0x01d3}}},
- {0x01d6, {1|U, {0x01d5}}},
- {0x01d8, {1|U, {0x01d7}}},
- {0x01da, {1|U, {0x01d9}}},
- {0x01dc, {1|U, {0x01db}}},
- {0x01dd, {1|U, {0x018e}}},
- {0x01df, {1|U, {0x01de}}},
- {0x01e1, {1|U, {0x01e0}}},
- {0x01e3, {1|U, {0x01e2}}},
- {0x01e5, {1|U, {0x01e4}}},
- {0x01e7, {1|U, {0x01e6}}},
- {0x01e9, {1|U, {0x01e8}}},
- {0x01eb, {1|U, {0x01ea}}},
- {0x01ed, {1|U, {0x01ec}}},
- {0x01ef, {1|U, {0x01ee}}},
- {0x01f3, {2|U|ST, {0x01f1, 0x01f2}}},
- {0x01f5, {1|U, {0x01f4}}},
- {0x01f9, {1|U, {0x01f8}}},
- {0x01fb, {1|U, {0x01fa}}},
- {0x01fd, {1|U, {0x01fc}}},
- {0x01ff, {1|U, {0x01fe}}},
- {0x0201, {1|U, {0x0200}}},
- {0x0203, {1|U, {0x0202}}},
- {0x0205, {1|U, {0x0204}}},
- {0x0207, {1|U, {0x0206}}},
- {0x0209, {1|U, {0x0208}}},
- {0x020b, {1|U, {0x020a}}},
- {0x020d, {1|U, {0x020c}}},
- {0x020f, {1|U, {0x020e}}},
- {0x0211, {1|U, {0x0210}}},
- {0x0213, {1|U, {0x0212}}},
- {0x0215, {1|U, {0x0214}}},
- {0x0217, {1|U, {0x0216}}},
- {0x0219, {1|U, {0x0218}}},
- {0x021b, {1|U, {0x021a}}},
- {0x021d, {1|U, {0x021c}}},
- {0x021f, {1|U, {0x021e}}},
- {0x0223, {1|U, {0x0222}}},
- {0x0225, {1|U, {0x0224}}},
- {0x0227, {1|U, {0x0226}}},
- {0x0229, {1|U, {0x0228}}},
- {0x022b, {1|U, {0x022a}}},
- {0x022d, {1|U, {0x022c}}},
- {0x022f, {1|U, {0x022e}}},
- {0x0231, {1|U, {0x0230}}},
- {0x0233, {1|U, {0x0232}}},
- {0x023c, {1|U, {0x023b}}},
- {0x023f, {1|U, {0x2c7e}}},
- {0x0240, {1|U, {0x2c7f}}},
- {0x0242, {1|U, {0x0241}}},
- {0x0247, {1|U, {0x0246}}},
- {0x0249, {1|U, {0x0248}}},
- {0x024b, {1|U, {0x024a}}},
- {0x024d, {1|U, {0x024c}}},
- {0x024f, {1|U, {0x024e}}},
- {0x0250, {1|U, {0x2c6f}}},
- {0x0251, {1|U, {0x2c6d}}},
- {0x0252, {1|U, {0x2c70}}},
- {0x0253, {1|U, {0x0181}}},
- {0x0254, {1|U, {0x0186}}},
- {0x0256, {1|U, {0x0189}}},
- {0x0257, {1|U, {0x018a}}},
- {0x0259, {1|U, {0x018f}}},
- {0x025b, {1|U, {0x0190}}},
- {0x025c, {1|U, {0xa7ab}}},
- {0x0260, {1|U, {0x0193}}},
- {0x0261, {1|U, {0xa7ac}}},
- {0x0263, {1|U, {0x0194}}},
- {0x0265, {1|U, {0xa78d}}},
- {0x0266, {1|U, {0xa7aa}}},
- {0x0268, {1|U, {0x0197}}},
- {0x0269, {1|U, {0x0196}}},
- {0x026a, {1|U, {0xa7ae}}},
- {0x026b, {1|U, {0x2c62}}},
- {0x026c, {1|U, {0xa7ad}}},
- {0x026f, {1|U, {0x019c}}},
- {0x0271, {1|U, {0x2c6e}}},
- {0x0272, {1|U, {0x019d}}},
- {0x0275, {1|U, {0x019f}}},
- {0x027d, {1|U, {0x2c64}}},
- {0x0280, {1|U, {0x01a6}}},
- {0x0283, {1|U, {0x01a9}}},
- {0x0287, {1|U, {0xa7b1}}},
- {0x0288, {1|U, {0x01ae}}},
- {0x0289, {1|U, {0x0244}}},
- {0x028a, {1|U, {0x01b1}}},
- {0x028b, {1|U, {0x01b2}}},
- {0x028c, {1|U, {0x0245}}},
- {0x0292, {1|U, {0x01b7}}},
- {0x029d, {1|U, {0xa7b2}}},
- {0x029e, {1|U, {0xa7b0}}},
- {0x0371, {1|U, {0x0370}}},
- {0x0373, {1|U, {0x0372}}},
- {0x0377, {1|U, {0x0376}}},
- {0x037b, {1|U, {0x03fd}}},
- {0x037c, {1|U, {0x03fe}}},
- {0x037d, {1|U, {0x03ff}}},
- {0x03ac, {1|U, {0x0386}}},
- {0x03ad, {1|U, {0x0388}}},
- {0x03ae, {1|U, {0x0389}}},
- {0x03af, {1|U, {0x038a}}},
- {0x03b1, {1|U, {0x0391}}},
- {0x03b2, {2|U, {0x0392, 0x03d0}}},
- {0x03b3, {1|U, {0x0393}}},
- {0x03b4, {1|U, {0x0394}}},
- {0x03b5, {2|U, {0x0395, 0x03f5}}},
- {0x03b6, {1|U, {0x0396}}},
- {0x03b7, {1|U, {0x0397}}},
- {0x03b8, {3|U, {0x0398, 0x03d1, 0x03f4}}},
- {0x03b9, {3|U, {0x0399, 0x0345, 0x1fbe}}},
- {0x03ba, {2|U, {0x039a, 0x03f0}}},
- {0x03bb, {1|U, {0x039b}}},
- {0x03bc, {2|U, {0x039c, 0x00b5}}},
- {0x03bd, {1|U, {0x039d}}},
- {0x03be, {1|U, {0x039e}}},
- {0x03bf, {1|U, {0x039f}}},
- {0x03c0, {2|U, {0x03a0, 0x03d6}}},
- {0x03c1, {2|U, {0x03a1, 0x03f1}}},
- {0x03c3, {2|U, {0x03a3, 0x03c2}}},
- {0x03c4, {1|U, {0x03a4}}},
- {0x03c5, {1|U, {0x03a5}}},
- {0x03c6, {2|U, {0x03a6, 0x03d5}}},
- {0x03c7, {1|U, {0x03a7}}},
- {0x03c8, {1|U, {0x03a8}}},
- {0x03c9, {2|U, {0x03a9, 0x2126}}},
- {0x03ca, {1|U, {0x03aa}}},
- {0x03cb, {1|U, {0x03ab}}},
- {0x03cc, {1|U, {0x038c}}},
- {0x03cd, {1|U, {0x038e}}},
- {0x03ce, {1|U, {0x038f}}},
- {0x03d7, {1|U, {0x03cf}}},
- {0x03d9, {1|U, {0x03d8}}},
- {0x03db, {1|U, {0x03da}}},
- {0x03dd, {1|U, {0x03dc}}},
- {0x03df, {1|U, {0x03de}}},
- {0x03e1, {1|U, {0x03e0}}},
- {0x03e3, {1|U, {0x03e2}}},
- {0x03e5, {1|U, {0x03e4}}},
- {0x03e7, {1|U, {0x03e6}}},
- {0x03e9, {1|U, {0x03e8}}},
- {0x03eb, {1|U, {0x03ea}}},
- {0x03ed, {1|U, {0x03ec}}},
- {0x03ef, {1|U, {0x03ee}}},
- {0x03f2, {1|U, {0x03f9}}},
- {0x03f3, {1|U, {0x037f}}},
- {0x03f8, {1|U, {0x03f7}}},
- {0x03fb, {1|U, {0x03fa}}},
- {0x0430, {1|U, {0x0410}}},
- {0x0431, {1|U, {0x0411}}},
- {0x0432, {2|U, {0x0412, 0x1c80}}},
- {0x0433, {1|U, {0x0413}}},
- {0x0434, {2|U, {0x0414, 0x1c81}}},
- {0x0435, {1|U, {0x0415}}},
- {0x0436, {1|U, {0x0416}}},
- {0x0437, {1|U, {0x0417}}},
- {0x0438, {1|U, {0x0418}}},
- {0x0439, {1|U, {0x0419}}},
- {0x043a, {1|U, {0x041a}}},
- {0x043b, {1|U, {0x041b}}},
- {0x043c, {1|U, {0x041c}}},
- {0x043d, {1|U, {0x041d}}},
- {0x043e, {2|U, {0x041e, 0x1c82}}},
- {0x043f, {1|U, {0x041f}}},
- {0x0440, {1|U, {0x0420}}},
- {0x0441, {2|U, {0x0421, 0x1c83}}},
- {0x0442, {3|U, {0x0422, 0x1c84, 0x1c85}}},
- {0x0443, {1|U, {0x0423}}},
- {0x0444, {1|U, {0x0424}}},
- {0x0445, {1|U, {0x0425}}},
- {0x0446, {1|U, {0x0426}}},
- {0x0447, {1|U, {0x0427}}},
- {0x0448, {1|U, {0x0428}}},
- {0x0449, {1|U, {0x0429}}},
- {0x044a, {2|U, {0x042a, 0x1c86}}},
- {0x044b, {1|U, {0x042b}}},
- {0x044c, {1|U, {0x042c}}},
- {0x044d, {1|U, {0x042d}}},
- {0x044e, {1|U, {0x042e}}},
- {0x044f, {1|U, {0x042f}}},
- {0x0450, {1|U, {0x0400}}},
- {0x0451, {1|U, {0x0401}}},
- {0x0452, {1|U, {0x0402}}},
- {0x0453, {1|U, {0x0403}}},
- {0x0454, {1|U, {0x0404}}},
- {0x0455, {1|U, {0x0405}}},
- {0x0456, {1|U, {0x0406}}},
- {0x0457, {1|U, {0x0407}}},
- {0x0458, {1|U, {0x0408}}},
- {0x0459, {1|U, {0x0409}}},
- {0x045a, {1|U, {0x040a}}},
- {0x045b, {1|U, {0x040b}}},
- {0x045c, {1|U, {0x040c}}},
- {0x045d, {1|U, {0x040d}}},
- {0x045e, {1|U, {0x040e}}},
- {0x045f, {1|U, {0x040f}}},
- {0x0461, {1|U, {0x0460}}},
- {0x0463, {2|U, {0x0462, 0x1c87}}},
- {0x0465, {1|U, {0x0464}}},
- {0x0467, {1|U, {0x0466}}},
- {0x0469, {1|U, {0x0468}}},
- {0x046b, {1|U, {0x046a}}},
- {0x046d, {1|U, {0x046c}}},
- {0x046f, {1|U, {0x046e}}},
- {0x0471, {1|U, {0x0470}}},
- {0x0473, {1|U, {0x0472}}},
- {0x0475, {1|U, {0x0474}}},
- {0x0477, {1|U, {0x0476}}},
- {0x0479, {1|U, {0x0478}}},
- {0x047b, {1|U, {0x047a}}},
- {0x047d, {1|U, {0x047c}}},
- {0x047f, {1|U, {0x047e}}},
- {0x0481, {1|U, {0x0480}}},
- {0x048b, {1|U, {0x048a}}},
- {0x048d, {1|U, {0x048c}}},
- {0x048f, {1|U, {0x048e}}},
- {0x0491, {1|U, {0x0490}}},
- {0x0493, {1|U, {0x0492}}},
- {0x0495, {1|U, {0x0494}}},
- {0x0497, {1|U, {0x0496}}},
- {0x0499, {1|U, {0x0498}}},
- {0x049b, {1|U, {0x049a}}},
- {0x049d, {1|U, {0x049c}}},
- {0x049f, {1|U, {0x049e}}},
- {0x04a1, {1|U, {0x04a0}}},
- {0x04a3, {1|U, {0x04a2}}},
- {0x04a5, {1|U, {0x04a4}}},
- {0x04a7, {1|U, {0x04a6}}},
- {0x04a9, {1|U, {0x04a8}}},
- {0x04ab, {1|U, {0x04aa}}},
- {0x04ad, {1|U, {0x04ac}}},
- {0x04af, {1|U, {0x04ae}}},
- {0x04b1, {1|U, {0x04b0}}},
- {0x04b3, {1|U, {0x04b2}}},
- {0x04b5, {1|U, {0x04b4}}},
- {0x04b7, {1|U, {0x04b6}}},
- {0x04b9, {1|U, {0x04b8}}},
- {0x04bb, {1|U, {0x04ba}}},
- {0x04bd, {1|U, {0x04bc}}},
- {0x04bf, {1|U, {0x04be}}},
- {0x04c2, {1|U, {0x04c1}}},
- {0x04c4, {1|U, {0x04c3}}},
- {0x04c6, {1|U, {0x04c5}}},
- {0x04c8, {1|U, {0x04c7}}},
- {0x04ca, {1|U, {0x04c9}}},
- {0x04cc, {1|U, {0x04cb}}},
- {0x04ce, {1|U, {0x04cd}}},
- {0x04cf, {1|U, {0x04c0}}},
- {0x04d1, {1|U, {0x04d0}}},
- {0x04d3, {1|U, {0x04d2}}},
- {0x04d5, {1|U, {0x04d4}}},
- {0x04d7, {1|U, {0x04d6}}},
- {0x04d9, {1|U, {0x04d8}}},
- {0x04db, {1|U, {0x04da}}},
- {0x04dd, {1|U, {0x04dc}}},
- {0x04df, {1|U, {0x04de}}},
- {0x04e1, {1|U, {0x04e0}}},
- {0x04e3, {1|U, {0x04e2}}},
- {0x04e5, {1|U, {0x04e4}}},
- {0x04e7, {1|U, {0x04e6}}},
- {0x04e9, {1|U, {0x04e8}}},
- {0x04eb, {1|U, {0x04ea}}},
- {0x04ed, {1|U, {0x04ec}}},
- {0x04ef, {1|U, {0x04ee}}},
- {0x04f1, {1|U, {0x04f0}}},
- {0x04f3, {1|U, {0x04f2}}},
- {0x04f5, {1|U, {0x04f4}}},
- {0x04f7, {1|U, {0x04f6}}},
- {0x04f9, {1|U, {0x04f8}}},
- {0x04fb, {1|U, {0x04fa}}},
- {0x04fd, {1|U, {0x04fc}}},
- {0x04ff, {1|U, {0x04fe}}},
- {0x0501, {1|U, {0x0500}}},
- {0x0503, {1|U, {0x0502}}},
- {0x0505, {1|U, {0x0504}}},
- {0x0507, {1|U, {0x0506}}},
- {0x0509, {1|U, {0x0508}}},
- {0x050b, {1|U, {0x050a}}},
- {0x050d, {1|U, {0x050c}}},
- {0x050f, {1|U, {0x050e}}},
- {0x0511, {1|U, {0x0510}}},
- {0x0513, {1|U, {0x0512}}},
- {0x0515, {1|U, {0x0514}}},
- {0x0517, {1|U, {0x0516}}},
- {0x0519, {1|U, {0x0518}}},
- {0x051b, {1|U, {0x051a}}},
- {0x051d, {1|U, {0x051c}}},
- {0x051f, {1|U, {0x051e}}},
- {0x0521, {1|U, {0x0520}}},
- {0x0523, {1|U, {0x0522}}},
- {0x0525, {1|U, {0x0524}}},
- {0x0527, {1|U, {0x0526}}},
- {0x0529, {1|U, {0x0528}}},
- {0x052b, {1|U, {0x052a}}},
- {0x052d, {1|U, {0x052c}}},
- {0x052f, {1|U, {0x052e}}},
- {0x0561, {1|U, {0x0531}}},
- {0x0562, {1|U, {0x0532}}},
- {0x0563, {1|U, {0x0533}}},
- {0x0564, {1|U, {0x0534}}},
- {0x0565, {1|U, {0x0535}}},
- {0x0566, {1|U, {0x0536}}},
- {0x0567, {1|U, {0x0537}}},
- {0x0568, {1|U, {0x0538}}},
- {0x0569, {1|U, {0x0539}}},
- {0x056a, {1|U, {0x053a}}},
- {0x056b, {1|U, {0x053b}}},
- {0x056c, {1|U, {0x053c}}},
- {0x056d, {1|U, {0x053d}}},
- {0x056e, {1|U, {0x053e}}},
- {0x056f, {1|U, {0x053f}}},
- {0x0570, {1|U, {0x0540}}},
- {0x0571, {1|U, {0x0541}}},
- {0x0572, {1|U, {0x0542}}},
- {0x0573, {1|U, {0x0543}}},
- {0x0574, {1|U, {0x0544}}},
- {0x0575, {1|U, {0x0545}}},
- {0x0576, {1|U, {0x0546}}},
- {0x0577, {1|U, {0x0547}}},
- {0x0578, {1|U, {0x0548}}},
- {0x0579, {1|U, {0x0549}}},
- {0x057a, {1|U, {0x054a}}},
- {0x057b, {1|U, {0x054b}}},
- {0x057c, {1|U, {0x054c}}},
- {0x057d, {1|U, {0x054d}}},
- {0x057e, {1|U, {0x054e}}},
- {0x057f, {1|U, {0x054f}}},
- {0x0580, {1|U, {0x0550}}},
- {0x0581, {1|U, {0x0551}}},
- {0x0582, {1|U, {0x0552}}},
- {0x0583, {1|U, {0x0553}}},
- {0x0584, {1|U, {0x0554}}},
- {0x0585, {1|U, {0x0555}}},
- {0x0586, {1|U, {0x0556}}},
- {0x13a0, {1|D, {0xab70}}},
- {0x13a1, {1|D, {0xab71}}},
- {0x13a2, {1|D, {0xab72}}},
- {0x13a3, {1|D, {0xab73}}},
- {0x13a4, {1|D, {0xab74}}},
- {0x13a5, {1|D, {0xab75}}},
- {0x13a6, {1|D, {0xab76}}},
- {0x13a7, {1|D, {0xab77}}},
- {0x13a8, {1|D, {0xab78}}},
- {0x13a9, {1|D, {0xab79}}},
- {0x13aa, {1|D, {0xab7a}}},
- {0x13ab, {1|D, {0xab7b}}},
- {0x13ac, {1|D, {0xab7c}}},
- {0x13ad, {1|D, {0xab7d}}},
- {0x13ae, {1|D, {0xab7e}}},
- {0x13af, {1|D, {0xab7f}}},
- {0x13b0, {1|D, {0xab80}}},
- {0x13b1, {1|D, {0xab81}}},
- {0x13b2, {1|D, {0xab82}}},
- {0x13b3, {1|D, {0xab83}}},
- {0x13b4, {1|D, {0xab84}}},
- {0x13b5, {1|D, {0xab85}}},
- {0x13b6, {1|D, {0xab86}}},
- {0x13b7, {1|D, {0xab87}}},
- {0x13b8, {1|D, {0xab88}}},
- {0x13b9, {1|D, {0xab89}}},
- {0x13ba, {1|D, {0xab8a}}},
- {0x13bb, {1|D, {0xab8b}}},
- {0x13bc, {1|D, {0xab8c}}},
- {0x13bd, {1|D, {0xab8d}}},
- {0x13be, {1|D, {0xab8e}}},
- {0x13bf, {1|D, {0xab8f}}},
- {0x13c0, {1|D, {0xab90}}},
- {0x13c1, {1|D, {0xab91}}},
- {0x13c2, {1|D, {0xab92}}},
- {0x13c3, {1|D, {0xab93}}},
- {0x13c4, {1|D, {0xab94}}},
- {0x13c5, {1|D, {0xab95}}},
- {0x13c6, {1|D, {0xab96}}},
- {0x13c7, {1|D, {0xab97}}},
- {0x13c8, {1|D, {0xab98}}},
- {0x13c9, {1|D, {0xab99}}},
- {0x13ca, {1|D, {0xab9a}}},
- {0x13cb, {1|D, {0xab9b}}},
- {0x13cc, {1|D, {0xab9c}}},
- {0x13cd, {1|D, {0xab9d}}},
- {0x13ce, {1|D, {0xab9e}}},
- {0x13cf, {1|D, {0xab9f}}},
- {0x13d0, {1|D, {0xaba0}}},
- {0x13d1, {1|D, {0xaba1}}},
- {0x13d2, {1|D, {0xaba2}}},
- {0x13d3, {1|D, {0xaba3}}},
- {0x13d4, {1|D, {0xaba4}}},
- {0x13d5, {1|D, {0xaba5}}},
- {0x13d6, {1|D, {0xaba6}}},
- {0x13d7, {1|D, {0xaba7}}},
- {0x13d8, {1|D, {0xaba8}}},
- {0x13d9, {1|D, {0xaba9}}},
- {0x13da, {1|D, {0xabaa}}},
- {0x13db, {1|D, {0xabab}}},
- {0x13dc, {1|D, {0xabac}}},
- {0x13dd, {1|D, {0xabad}}},
- {0x13de, {1|D, {0xabae}}},
- {0x13df, {1|D, {0xabaf}}},
- {0x13e0, {1|D, {0xabb0}}},
- {0x13e1, {1|D, {0xabb1}}},
- {0x13e2, {1|D, {0xabb2}}},
- {0x13e3, {1|D, {0xabb3}}},
- {0x13e4, {1|D, {0xabb4}}},
- {0x13e5, {1|D, {0xabb5}}},
- {0x13e6, {1|D, {0xabb6}}},
- {0x13e7, {1|D, {0xabb7}}},
- {0x13e8, {1|D, {0xabb8}}},
- {0x13e9, {1|D, {0xabb9}}},
- {0x13ea, {1|D, {0xabba}}},
- {0x13eb, {1|D, {0xabbb}}},
- {0x13ec, {1|D, {0xabbc}}},
- {0x13ed, {1|D, {0xabbd}}},
- {0x13ee, {1|D, {0xabbe}}},
- {0x13ef, {1|D, {0xabbf}}},
- {0x13f0, {1|D, {0x13f8}}},
- {0x13f1, {1|D, {0x13f9}}},
- {0x13f2, {1|D, {0x13fa}}},
- {0x13f3, {1|D, {0x13fb}}},
- {0x13f4, {1|D, {0x13fc}}},
- {0x13f5, {1|D, {0x13fd}}},
- {0x1d79, {1|U, {0xa77d}}},
- {0x1d7d, {1|U, {0x2c63}}},
- {0x1e01, {1|U, {0x1e00}}},
- {0x1e03, {1|U, {0x1e02}}},
- {0x1e05, {1|U, {0x1e04}}},
- {0x1e07, {1|U, {0x1e06}}},
- {0x1e09, {1|U, {0x1e08}}},
- {0x1e0b, {1|U, {0x1e0a}}},
- {0x1e0d, {1|U, {0x1e0c}}},
- {0x1e0f, {1|U, {0x1e0e}}},
- {0x1e11, {1|U, {0x1e10}}},
- {0x1e13, {1|U, {0x1e12}}},
- {0x1e15, {1|U, {0x1e14}}},
- {0x1e17, {1|U, {0x1e16}}},
- {0x1e19, {1|U, {0x1e18}}},
- {0x1e1b, {1|U, {0x1e1a}}},
- {0x1e1d, {1|U, {0x1e1c}}},
- {0x1e1f, {1|U, {0x1e1e}}},
- {0x1e21, {1|U, {0x1e20}}},
- {0x1e23, {1|U, {0x1e22}}},
- {0x1e25, {1|U, {0x1e24}}},
- {0x1e27, {1|U, {0x1e26}}},
- {0x1e29, {1|U, {0x1e28}}},
- {0x1e2b, {1|U, {0x1e2a}}},
- {0x1e2d, {1|U, {0x1e2c}}},
- {0x1e2f, {1|U, {0x1e2e}}},
- {0x1e31, {1|U, {0x1e30}}},
- {0x1e33, {1|U, {0x1e32}}},
- {0x1e35, {1|U, {0x1e34}}},
- {0x1e37, {1|U, {0x1e36}}},
- {0x1e39, {1|U, {0x1e38}}},
- {0x1e3b, {1|U, {0x1e3a}}},
- {0x1e3d, {1|U, {0x1e3c}}},
- {0x1e3f, {1|U, {0x1e3e}}},
- {0x1e41, {1|U, {0x1e40}}},
- {0x1e43, {1|U, {0x1e42}}},
- {0x1e45, {1|U, {0x1e44}}},
- {0x1e47, {1|U, {0x1e46}}},
- {0x1e49, {1|U, {0x1e48}}},
- {0x1e4b, {1|U, {0x1e4a}}},
- {0x1e4d, {1|U, {0x1e4c}}},
- {0x1e4f, {1|U, {0x1e4e}}},
- {0x1e51, {1|U, {0x1e50}}},
- {0x1e53, {1|U, {0x1e52}}},
- {0x1e55, {1|U, {0x1e54}}},
- {0x1e57, {1|U, {0x1e56}}},
- {0x1e59, {1|U, {0x1e58}}},
- {0x1e5b, {1|U, {0x1e5a}}},
- {0x1e5d, {1|U, {0x1e5c}}},
- {0x1e5f, {1|U, {0x1e5e}}},
- {0x1e61, {2|U, {0x1e60, 0x1e9b}}},
- {0x1e63, {1|U, {0x1e62}}},
- {0x1e65, {1|U, {0x1e64}}},
- {0x1e67, {1|U, {0x1e66}}},
- {0x1e69, {1|U, {0x1e68}}},
- {0x1e6b, {1|U, {0x1e6a}}},
- {0x1e6d, {1|U, {0x1e6c}}},
- {0x1e6f, {1|U, {0x1e6e}}},
- {0x1e71, {1|U, {0x1e70}}},
- {0x1e73, {1|U, {0x1e72}}},
- {0x1e75, {1|U, {0x1e74}}},
- {0x1e77, {1|U, {0x1e76}}},
- {0x1e79, {1|U, {0x1e78}}},
- {0x1e7b, {1|U, {0x1e7a}}},
- {0x1e7d, {1|U, {0x1e7c}}},
- {0x1e7f, {1|U, {0x1e7e}}},
- {0x1e81, {1|U, {0x1e80}}},
- {0x1e83, {1|U, {0x1e82}}},
- {0x1e85, {1|U, {0x1e84}}},
- {0x1e87, {1|U, {0x1e86}}},
- {0x1e89, {1|U, {0x1e88}}},
- {0x1e8b, {1|U, {0x1e8a}}},
- {0x1e8d, {1|U, {0x1e8c}}},
- {0x1e8f, {1|U, {0x1e8e}}},
- {0x1e91, {1|U, {0x1e90}}},
- {0x1e93, {1|U, {0x1e92}}},
- {0x1e95, {1|U, {0x1e94}}},
- {0x1ea1, {1|U, {0x1ea0}}},
- {0x1ea3, {1|U, {0x1ea2}}},
- {0x1ea5, {1|U, {0x1ea4}}},
- {0x1ea7, {1|U, {0x1ea6}}},
- {0x1ea9, {1|U, {0x1ea8}}},
- {0x1eab, {1|U, {0x1eaa}}},
- {0x1ead, {1|U, {0x1eac}}},
- {0x1eaf, {1|U, {0x1eae}}},
- {0x1eb1, {1|U, {0x1eb0}}},
- {0x1eb3, {1|U, {0x1eb2}}},
- {0x1eb5, {1|U, {0x1eb4}}},
- {0x1eb7, {1|U, {0x1eb6}}},
- {0x1eb9, {1|U, {0x1eb8}}},
- {0x1ebb, {1|U, {0x1eba}}},
- {0x1ebd, {1|U, {0x1ebc}}},
- {0x1ebf, {1|U, {0x1ebe}}},
- {0x1ec1, {1|U, {0x1ec0}}},
- {0x1ec3, {1|U, {0x1ec2}}},
- {0x1ec5, {1|U, {0x1ec4}}},
- {0x1ec7, {1|U, {0x1ec6}}},
- {0x1ec9, {1|U, {0x1ec8}}},
- {0x1ecb, {1|U, {0x1eca}}},
- {0x1ecd, {1|U, {0x1ecc}}},
- {0x1ecf, {1|U, {0x1ece}}},
- {0x1ed1, {1|U, {0x1ed0}}},
- {0x1ed3, {1|U, {0x1ed2}}},
- {0x1ed5, {1|U, {0x1ed4}}},
- {0x1ed7, {1|U, {0x1ed6}}},
- {0x1ed9, {1|U, {0x1ed8}}},
- {0x1edb, {1|U, {0x1eda}}},
- {0x1edd, {1|U, {0x1edc}}},
- {0x1edf, {1|U, {0x1ede}}},
- {0x1ee1, {1|U, {0x1ee0}}},
- {0x1ee3, {1|U, {0x1ee2}}},
- {0x1ee5, {1|U, {0x1ee4}}},
- {0x1ee7, {1|U, {0x1ee6}}},
- {0x1ee9, {1|U, {0x1ee8}}},
- {0x1eeb, {1|U, {0x1eea}}},
- {0x1eed, {1|U, {0x1eec}}},
- {0x1eef, {1|U, {0x1eee}}},
- {0x1ef1, {1|U, {0x1ef0}}},
- {0x1ef3, {1|U, {0x1ef2}}},
- {0x1ef5, {1|U, {0x1ef4}}},
- {0x1ef7, {1|U, {0x1ef6}}},
- {0x1ef9, {1|U, {0x1ef8}}},
- {0x1efb, {1|U, {0x1efa}}},
- {0x1efd, {1|U, {0x1efc}}},
- {0x1eff, {1|U, {0x1efe}}},
- {0x1f00, {1|U, {0x1f08}}},
- {0x1f01, {1|U, {0x1f09}}},
- {0x1f02, {1|U, {0x1f0a}}},
- {0x1f03, {1|U, {0x1f0b}}},
- {0x1f04, {1|U, {0x1f0c}}},
- {0x1f05, {1|U, {0x1f0d}}},
- {0x1f06, {1|U, {0x1f0e}}},
- {0x1f07, {1|U, {0x1f0f}}},
- {0x1f10, {1|U, {0x1f18}}},
- {0x1f11, {1|U, {0x1f19}}},
- {0x1f12, {1|U, {0x1f1a}}},
- {0x1f13, {1|U, {0x1f1b}}},
- {0x1f14, {1|U, {0x1f1c}}},
- {0x1f15, {1|U, {0x1f1d}}},
- {0x1f20, {1|U, {0x1f28}}},
- {0x1f21, {1|U, {0x1f29}}},
- {0x1f22, {1|U, {0x1f2a}}},
- {0x1f23, {1|U, {0x1f2b}}},
- {0x1f24, {1|U, {0x1f2c}}},
- {0x1f25, {1|U, {0x1f2d}}},
- {0x1f26, {1|U, {0x1f2e}}},
- {0x1f27, {1|U, {0x1f2f}}},
- {0x1f30, {1|U, {0x1f38}}},
- {0x1f31, {1|U, {0x1f39}}},
- {0x1f32, {1|U, {0x1f3a}}},
- {0x1f33, {1|U, {0x1f3b}}},
- {0x1f34, {1|U, {0x1f3c}}},
- {0x1f35, {1|U, {0x1f3d}}},
- {0x1f36, {1|U, {0x1f3e}}},
- {0x1f37, {1|U, {0x1f3f}}},
- {0x1f40, {1|U, {0x1f48}}},
- {0x1f41, {1|U, {0x1f49}}},
- {0x1f42, {1|U, {0x1f4a}}},
- {0x1f43, {1|U, {0x1f4b}}},
- {0x1f44, {1|U, {0x1f4c}}},
- {0x1f45, {1|U, {0x1f4d}}},
- {0x1f51, {1|U, {0x1f59}}},
- {0x1f53, {1|U, {0x1f5b}}},
- {0x1f55, {1|U, {0x1f5d}}},
- {0x1f57, {1|U, {0x1f5f}}},
- {0x1f60, {1|U, {0x1f68}}},
- {0x1f61, {1|U, {0x1f69}}},
- {0x1f62, {1|U, {0x1f6a}}},
- {0x1f63, {1|U, {0x1f6b}}},
- {0x1f64, {1|U, {0x1f6c}}},
- {0x1f65, {1|U, {0x1f6d}}},
- {0x1f66, {1|U, {0x1f6e}}},
- {0x1f67, {1|U, {0x1f6f}}},
- {0x1f70, {1|U, {0x1fba}}},
- {0x1f71, {1|U, {0x1fbb}}},
- {0x1f72, {1|U, {0x1fc8}}},
- {0x1f73, {1|U, {0x1fc9}}},
- {0x1f74, {1|U, {0x1fca}}},
- {0x1f75, {1|U, {0x1fcb}}},
- {0x1f76, {1|U, {0x1fda}}},
- {0x1f77, {1|U, {0x1fdb}}},
- {0x1f78, {1|U, {0x1ff8}}},
- {0x1f79, {1|U, {0x1ff9}}},
- {0x1f7a, {1|U, {0x1fea}}},
- {0x1f7b, {1|U, {0x1feb}}},
- {0x1f7c, {1|U, {0x1ffa}}},
- {0x1f7d, {1|U, {0x1ffb}}},
- {0x1fb0, {1|U, {0x1fb8}}},
- {0x1fb1, {1|U, {0x1fb9}}},
- {0x1fd0, {1|U, {0x1fd8}}},
- {0x1fd1, {1|U, {0x1fd9}}},
- {0x1fe0, {1|U, {0x1fe8}}},
- {0x1fe1, {1|U, {0x1fe9}}},
- {0x1fe5, {1|U, {0x1fec}}},
- {0x214e, {1|U, {0x2132}}},
- {0x2170, {1|U, {0x2160}}},
- {0x2171, {1|U, {0x2161}}},
- {0x2172, {1|U, {0x2162}}},
- {0x2173, {1|U, {0x2163}}},
- {0x2174, {1|U, {0x2164}}},
- {0x2175, {1|U, {0x2165}}},
- {0x2176, {1|U, {0x2166}}},
- {0x2177, {1|U, {0x2167}}},
- {0x2178, {1|U, {0x2168}}},
- {0x2179, {1|U, {0x2169}}},
- {0x217a, {1|U, {0x216a}}},
- {0x217b, {1|U, {0x216b}}},
- {0x217c, {1|U, {0x216c}}},
- {0x217d, {1|U, {0x216d}}},
- {0x217e, {1|U, {0x216e}}},
- {0x217f, {1|U, {0x216f}}},
- {0x2184, {1|U, {0x2183}}},
- {0x24d0, {1|U, {0x24b6}}},
- {0x24d1, {1|U, {0x24b7}}},
- {0x24d2, {1|U, {0x24b8}}},
- {0x24d3, {1|U, {0x24b9}}},
- {0x24d4, {1|U, {0x24ba}}},
- {0x24d5, {1|U, {0x24bb}}},
- {0x24d6, {1|U, {0x24bc}}},
- {0x24d7, {1|U, {0x24bd}}},
- {0x24d8, {1|U, {0x24be}}},
- {0x24d9, {1|U, {0x24bf}}},
- {0x24da, {1|U, {0x24c0}}},
- {0x24db, {1|U, {0x24c1}}},
- {0x24dc, {1|U, {0x24c2}}},
- {0x24dd, {1|U, {0x24c3}}},
- {0x24de, {1|U, {0x24c4}}},
- {0x24df, {1|U, {0x24c5}}},
- {0x24e0, {1|U, {0x24c6}}},
- {0x24e1, {1|U, {0x24c7}}},
- {0x24e2, {1|U, {0x24c8}}},
- {0x24e3, {1|U, {0x24c9}}},
- {0x24e4, {1|U, {0x24ca}}},
- {0x24e5, {1|U, {0x24cb}}},
- {0x24e6, {1|U, {0x24cc}}},
- {0x24e7, {1|U, {0x24cd}}},
- {0x24e8, {1|U, {0x24ce}}},
- {0x24e9, {1|U, {0x24cf}}},
- {0x2c30, {1|U, {0x2c00}}},
- {0x2c31, {1|U, {0x2c01}}},
- {0x2c32, {1|U, {0x2c02}}},
- {0x2c33, {1|U, {0x2c03}}},
- {0x2c34, {1|U, {0x2c04}}},
- {0x2c35, {1|U, {0x2c05}}},
- {0x2c36, {1|U, {0x2c06}}},
- {0x2c37, {1|U, {0x2c07}}},
- {0x2c38, {1|U, {0x2c08}}},
- {0x2c39, {1|U, {0x2c09}}},
- {0x2c3a, {1|U, {0x2c0a}}},
- {0x2c3b, {1|U, {0x2c0b}}},
- {0x2c3c, {1|U, {0x2c0c}}},
- {0x2c3d, {1|U, {0x2c0d}}},
- {0x2c3e, {1|U, {0x2c0e}}},
- {0x2c3f, {1|U, {0x2c0f}}},
- {0x2c40, {1|U, {0x2c10}}},
- {0x2c41, {1|U, {0x2c11}}},
- {0x2c42, {1|U, {0x2c12}}},
- {0x2c43, {1|U, {0x2c13}}},
- {0x2c44, {1|U, {0x2c14}}},
- {0x2c45, {1|U, {0x2c15}}},
- {0x2c46, {1|U, {0x2c16}}},
- {0x2c47, {1|U, {0x2c17}}},
- {0x2c48, {1|U, {0x2c18}}},
- {0x2c49, {1|U, {0x2c19}}},
- {0x2c4a, {1|U, {0x2c1a}}},
- {0x2c4b, {1|U, {0x2c1b}}},
- {0x2c4c, {1|U, {0x2c1c}}},
- {0x2c4d, {1|U, {0x2c1d}}},
- {0x2c4e, {1|U, {0x2c1e}}},
- {0x2c4f, {1|U, {0x2c1f}}},
- {0x2c50, {1|U, {0x2c20}}},
- {0x2c51, {1|U, {0x2c21}}},
- {0x2c52, {1|U, {0x2c22}}},
- {0x2c53, {1|U, {0x2c23}}},
- {0x2c54, {1|U, {0x2c24}}},
- {0x2c55, {1|U, {0x2c25}}},
- {0x2c56, {1|U, {0x2c26}}},
- {0x2c57, {1|U, {0x2c27}}},
- {0x2c58, {1|U, {0x2c28}}},
- {0x2c59, {1|U, {0x2c29}}},
- {0x2c5a, {1|U, {0x2c2a}}},
- {0x2c5b, {1|U, {0x2c2b}}},
- {0x2c5c, {1|U, {0x2c2c}}},
- {0x2c5d, {1|U, {0x2c2d}}},
- {0x2c5e, {1|U, {0x2c2e}}},
- {0x2c61, {1|U, {0x2c60}}},
- {0x2c65, {1|U, {0x023a}}},
- {0x2c66, {1|U, {0x023e}}},
- {0x2c68, {1|U, {0x2c67}}},
- {0x2c6a, {1|U, {0x2c69}}},
- {0x2c6c, {1|U, {0x2c6b}}},
- {0x2c73, {1|U, {0x2c72}}},
- {0x2c76, {1|U, {0x2c75}}},
- {0x2c81, {1|U, {0x2c80}}},
- {0x2c83, {1|U, {0x2c82}}},
- {0x2c85, {1|U, {0x2c84}}},
- {0x2c87, {1|U, {0x2c86}}},
- {0x2c89, {1|U, {0x2c88}}},
- {0x2c8b, {1|U, {0x2c8a}}},
- {0x2c8d, {1|U, {0x2c8c}}},
- {0x2c8f, {1|U, {0x2c8e}}},
- {0x2c91, {1|U, {0x2c90}}},
- {0x2c93, {1|U, {0x2c92}}},
- {0x2c95, {1|U, {0x2c94}}},
- {0x2c97, {1|U, {0x2c96}}},
- {0x2c99, {1|U, {0x2c98}}},
- {0x2c9b, {1|U, {0x2c9a}}},
- {0x2c9d, {1|U, {0x2c9c}}},
- {0x2c9f, {1|U, {0x2c9e}}},
- {0x2ca1, {1|U, {0x2ca0}}},
- {0x2ca3, {1|U, {0x2ca2}}},
- {0x2ca5, {1|U, {0x2ca4}}},
- {0x2ca7, {1|U, {0x2ca6}}},
- {0x2ca9, {1|U, {0x2ca8}}},
- {0x2cab, {1|U, {0x2caa}}},
- {0x2cad, {1|U, {0x2cac}}},
- {0x2caf, {1|U, {0x2cae}}},
- {0x2cb1, {1|U, {0x2cb0}}},
- {0x2cb3, {1|U, {0x2cb2}}},
- {0x2cb5, {1|U, {0x2cb4}}},
- {0x2cb7, {1|U, {0x2cb6}}},
- {0x2cb9, {1|U, {0x2cb8}}},
- {0x2cbb, {1|U, {0x2cba}}},
- {0x2cbd, {1|U, {0x2cbc}}},
- {0x2cbf, {1|U, {0x2cbe}}},
- {0x2cc1, {1|U, {0x2cc0}}},
- {0x2cc3, {1|U, {0x2cc2}}},
- {0x2cc5, {1|U, {0x2cc4}}},
- {0x2cc7, {1|U, {0x2cc6}}},
- {0x2cc9, {1|U, {0x2cc8}}},
- {0x2ccb, {1|U, {0x2cca}}},
- {0x2ccd, {1|U, {0x2ccc}}},
- {0x2ccf, {1|U, {0x2cce}}},
- {0x2cd1, {1|U, {0x2cd0}}},
- {0x2cd3, {1|U, {0x2cd2}}},
- {0x2cd5, {1|U, {0x2cd4}}},
- {0x2cd7, {1|U, {0x2cd6}}},
- {0x2cd9, {1|U, {0x2cd8}}},
- {0x2cdb, {1|U, {0x2cda}}},
- {0x2cdd, {1|U, {0x2cdc}}},
- {0x2cdf, {1|U, {0x2cde}}},
- {0x2ce1, {1|U, {0x2ce0}}},
- {0x2ce3, {1|U, {0x2ce2}}},
- {0x2cec, {1|U, {0x2ceb}}},
- {0x2cee, {1|U, {0x2ced}}},
- {0x2cf3, {1|U, {0x2cf2}}},
- {0x2d00, {1|U, {0x10a0}}},
- {0x2d01, {1|U, {0x10a1}}},
- {0x2d02, {1|U, {0x10a2}}},
- {0x2d03, {1|U, {0x10a3}}},
- {0x2d04, {1|U, {0x10a4}}},
- {0x2d05, {1|U, {0x10a5}}},
- {0x2d06, {1|U, {0x10a6}}},
- {0x2d07, {1|U, {0x10a7}}},
- {0x2d08, {1|U, {0x10a8}}},
- {0x2d09, {1|U, {0x10a9}}},
- {0x2d0a, {1|U, {0x10aa}}},
- {0x2d0b, {1|U, {0x10ab}}},
- {0x2d0c, {1|U, {0x10ac}}},
- {0x2d0d, {1|U, {0x10ad}}},
- {0x2d0e, {1|U, {0x10ae}}},
- {0x2d0f, {1|U, {0x10af}}},
- {0x2d10, {1|U, {0x10b0}}},
- {0x2d11, {1|U, {0x10b1}}},
- {0x2d12, {1|U, {0x10b2}}},
- {0x2d13, {1|U, {0x10b3}}},
- {0x2d14, {1|U, {0x10b4}}},
- {0x2d15, {1|U, {0x10b5}}},
- {0x2d16, {1|U, {0x10b6}}},
- {0x2d17, {1|U, {0x10b7}}},
- {0x2d18, {1|U, {0x10b8}}},
- {0x2d19, {1|U, {0x10b9}}},
- {0x2d1a, {1|U, {0x10ba}}},
- {0x2d1b, {1|U, {0x10bb}}},
- {0x2d1c, {1|U, {0x10bc}}},
- {0x2d1d, {1|U, {0x10bd}}},
- {0x2d1e, {1|U, {0x10be}}},
- {0x2d1f, {1|U, {0x10bf}}},
- {0x2d20, {1|U, {0x10c0}}},
- {0x2d21, {1|U, {0x10c1}}},
- {0x2d22, {1|U, {0x10c2}}},
- {0x2d23, {1|U, {0x10c3}}},
- {0x2d24, {1|U, {0x10c4}}},
- {0x2d25, {1|U, {0x10c5}}},
- {0x2d27, {1|U, {0x10c7}}},
- {0x2d2d, {1|U, {0x10cd}}},
- {0xa641, {1|U, {0xa640}}},
- {0xa643, {1|U, {0xa642}}},
- {0xa645, {1|U, {0xa644}}},
- {0xa647, {1|U, {0xa646}}},
- {0xa649, {1|U, {0xa648}}},
- {0xa64b, {2|U, {0xa64a, 0x1c88}}},
- {0xa64d, {1|U, {0xa64c}}},
- {0xa64f, {1|U, {0xa64e}}},
- {0xa651, {1|U, {0xa650}}},
- {0xa653, {1|U, {0xa652}}},
- {0xa655, {1|U, {0xa654}}},
- {0xa657, {1|U, {0xa656}}},
- {0xa659, {1|U, {0xa658}}},
- {0xa65b, {1|U, {0xa65a}}},
- {0xa65d, {1|U, {0xa65c}}},
- {0xa65f, {1|U, {0xa65e}}},
- {0xa661, {1|U, {0xa660}}},
- {0xa663, {1|U, {0xa662}}},
- {0xa665, {1|U, {0xa664}}},
- {0xa667, {1|U, {0xa666}}},
- {0xa669, {1|U, {0xa668}}},
- {0xa66b, {1|U, {0xa66a}}},
- {0xa66d, {1|U, {0xa66c}}},
- {0xa681, {1|U, {0xa680}}},
- {0xa683, {1|U, {0xa682}}},
- {0xa685, {1|U, {0xa684}}},
- {0xa687, {1|U, {0xa686}}},
- {0xa689, {1|U, {0xa688}}},
- {0xa68b, {1|U, {0xa68a}}},
- {0xa68d, {1|U, {0xa68c}}},
- {0xa68f, {1|U, {0xa68e}}},
- {0xa691, {1|U, {0xa690}}},
- {0xa693, {1|U, {0xa692}}},
- {0xa695, {1|U, {0xa694}}},
- {0xa697, {1|U, {0xa696}}},
- {0xa699, {1|U, {0xa698}}},
- {0xa69b, {1|U, {0xa69a}}},
- {0xa723, {1|U, {0xa722}}},
- {0xa725, {1|U, {0xa724}}},
- {0xa727, {1|U, {0xa726}}},
- {0xa729, {1|U, {0xa728}}},
- {0xa72b, {1|U, {0xa72a}}},
- {0xa72d, {1|U, {0xa72c}}},
- {0xa72f, {1|U, {0xa72e}}},
- {0xa733, {1|U, {0xa732}}},
- {0xa735, {1|U, {0xa734}}},
- {0xa737, {1|U, {0xa736}}},
- {0xa739, {1|U, {0xa738}}},
- {0xa73b, {1|U, {0xa73a}}},
- {0xa73d, {1|U, {0xa73c}}},
- {0xa73f, {1|U, {0xa73e}}},
- {0xa741, {1|U, {0xa740}}},
- {0xa743, {1|U, {0xa742}}},
- {0xa745, {1|U, {0xa744}}},
- {0xa747, {1|U, {0xa746}}},
- {0xa749, {1|U, {0xa748}}},
- {0xa74b, {1|U, {0xa74a}}},
- {0xa74d, {1|U, {0xa74c}}},
- {0xa74f, {1|U, {0xa74e}}},
- {0xa751, {1|U, {0xa750}}},
- {0xa753, {1|U, {0xa752}}},
- {0xa755, {1|U, {0xa754}}},
- {0xa757, {1|U, {0xa756}}},
- {0xa759, {1|U, {0xa758}}},
- {0xa75b, {1|U, {0xa75a}}},
- {0xa75d, {1|U, {0xa75c}}},
- {0xa75f, {1|U, {0xa75e}}},
- {0xa761, {1|U, {0xa760}}},
- {0xa763, {1|U, {0xa762}}},
- {0xa765, {1|U, {0xa764}}},
- {0xa767, {1|U, {0xa766}}},
- {0xa769, {1|U, {0xa768}}},
- {0xa76b, {1|U, {0xa76a}}},
- {0xa76d, {1|U, {0xa76c}}},
- {0xa76f, {1|U, {0xa76e}}},
- {0xa77a, {1|U, {0xa779}}},
- {0xa77c, {1|U, {0xa77b}}},
- {0xa77f, {1|U, {0xa77e}}},
- {0xa781, {1|U, {0xa780}}},
- {0xa783, {1|U, {0xa782}}},
- {0xa785, {1|U, {0xa784}}},
- {0xa787, {1|U, {0xa786}}},
- {0xa78c, {1|U, {0xa78b}}},
- {0xa791, {1|U, {0xa790}}},
- {0xa793, {1|U, {0xa792}}},
- {0xa797, {1|U, {0xa796}}},
- {0xa799, {1|U, {0xa798}}},
- {0xa79b, {1|U, {0xa79a}}},
- {0xa79d, {1|U, {0xa79c}}},
- {0xa79f, {1|U, {0xa79e}}},
- {0xa7a1, {1|U, {0xa7a0}}},
- {0xa7a3, {1|U, {0xa7a2}}},
- {0xa7a5, {1|U, {0xa7a4}}},
- {0xa7a7, {1|U, {0xa7a6}}},
- {0xa7a9, {1|U, {0xa7a8}}},
- {0xa7b5, {1|U, {0xa7b4}}},
- {0xa7b7, {1|U, {0xa7b6}}},
- {0xab53, {1|U, {0xa7b3}}},
- {0xff41, {1|U, {0xff21}}},
- {0xff42, {1|U, {0xff22}}},
- {0xff43, {1|U, {0xff23}}},
- {0xff44, {1|U, {0xff24}}},
- {0xff45, {1|U, {0xff25}}},
- {0xff46, {1|U, {0xff26}}},
- {0xff47, {1|U, {0xff27}}},
- {0xff48, {1|U, {0xff28}}},
- {0xff49, {1|U, {0xff29}}},
- {0xff4a, {1|U, {0xff2a}}},
- {0xff4b, {1|U, {0xff2b}}},
- {0xff4c, {1|U, {0xff2c}}},
- {0xff4d, {1|U, {0xff2d}}},
- {0xff4e, {1|U, {0xff2e}}},
- {0xff4f, {1|U, {0xff2f}}},
- {0xff50, {1|U, {0xff30}}},
- {0xff51, {1|U, {0xff31}}},
- {0xff52, {1|U, {0xff32}}},
- {0xff53, {1|U, {0xff33}}},
- {0xff54, {1|U, {0xff34}}},
- {0xff55, {1|U, {0xff35}}},
- {0xff56, {1|U, {0xff36}}},
- {0xff57, {1|U, {0xff37}}},
- {0xff58, {1|U, {0xff38}}},
- {0xff59, {1|U, {0xff39}}},
- {0xff5a, {1|U, {0xff3a}}},
- {0x10428, {1|U, {0x10400}}},
- {0x10429, {1|U, {0x10401}}},
- {0x1042a, {1|U, {0x10402}}},
- {0x1042b, {1|U, {0x10403}}},
- {0x1042c, {1|U, {0x10404}}},
- {0x1042d, {1|U, {0x10405}}},
- {0x1042e, {1|U, {0x10406}}},
- {0x1042f, {1|U, {0x10407}}},
- {0x10430, {1|U, {0x10408}}},
- {0x10431, {1|U, {0x10409}}},
- {0x10432, {1|U, {0x1040a}}},
- {0x10433, {1|U, {0x1040b}}},
- {0x10434, {1|U, {0x1040c}}},
- {0x10435, {1|U, {0x1040d}}},
- {0x10436, {1|U, {0x1040e}}},
- {0x10437, {1|U, {0x1040f}}},
- {0x10438, {1|U, {0x10410}}},
- {0x10439, {1|U, {0x10411}}},
- {0x1043a, {1|U, {0x10412}}},
- {0x1043b, {1|U, {0x10413}}},
- {0x1043c, {1|U, {0x10414}}},
- {0x1043d, {1|U, {0x10415}}},
- {0x1043e, {1|U, {0x10416}}},
- {0x1043f, {1|U, {0x10417}}},
- {0x10440, {1|U, {0x10418}}},
- {0x10441, {1|U, {0x10419}}},
- {0x10442, {1|U, {0x1041a}}},
- {0x10443, {1|U, {0x1041b}}},
- {0x10444, {1|U, {0x1041c}}},
- {0x10445, {1|U, {0x1041d}}},
- {0x10446, {1|U, {0x1041e}}},
- {0x10447, {1|U, {0x1041f}}},
- {0x10448, {1|U, {0x10420}}},
- {0x10449, {1|U, {0x10421}}},
- {0x1044a, {1|U, {0x10422}}},
- {0x1044b, {1|U, {0x10423}}},
- {0x1044c, {1|U, {0x10424}}},
- {0x1044d, {1|U, {0x10425}}},
- {0x1044e, {1|U, {0x10426}}},
- {0x1044f, {1|U, {0x10427}}},
- {0x104d8, {1|U, {0x104b0}}},
- {0x104d9, {1|U, {0x104b1}}},
- {0x104da, {1|U, {0x104b2}}},
- {0x104db, {1|U, {0x104b3}}},
- {0x104dc, {1|U, {0x104b4}}},
- {0x104dd, {1|U, {0x104b5}}},
- {0x104de, {1|U, {0x104b6}}},
- {0x104df, {1|U, {0x104b7}}},
- {0x104e0, {1|U, {0x104b8}}},
- {0x104e1, {1|U, {0x104b9}}},
- {0x104e2, {1|U, {0x104ba}}},
- {0x104e3, {1|U, {0x104bb}}},
- {0x104e4, {1|U, {0x104bc}}},
- {0x104e5, {1|U, {0x104bd}}},
- {0x104e6, {1|U, {0x104be}}},
- {0x104e7, {1|U, {0x104bf}}},
- {0x104e8, {1|U, {0x104c0}}},
- {0x104e9, {1|U, {0x104c1}}},
- {0x104ea, {1|U, {0x104c2}}},
- {0x104eb, {1|U, {0x104c3}}},
- {0x104ec, {1|U, {0x104c4}}},
- {0x104ed, {1|U, {0x104c5}}},
- {0x104ee, {1|U, {0x104c6}}},
- {0x104ef, {1|U, {0x104c7}}},
- {0x104f0, {1|U, {0x104c8}}},
- {0x104f1, {1|U, {0x104c9}}},
- {0x104f2, {1|U, {0x104ca}}},
- {0x104f3, {1|U, {0x104cb}}},
- {0x104f4, {1|U, {0x104cc}}},
- {0x104f5, {1|U, {0x104cd}}},
- {0x104f6, {1|U, {0x104ce}}},
- {0x104f7, {1|U, {0x104cf}}},
- {0x104f8, {1|U, {0x104d0}}},
- {0x104f9, {1|U, {0x104d1}}},
- {0x104fa, {1|U, {0x104d2}}},
- {0x104fb, {1|U, {0x104d3}}},
- {0x10cc0, {1|U, {0x10c80}}},
- {0x10cc1, {1|U, {0x10c81}}},
- {0x10cc2, {1|U, {0x10c82}}},
- {0x10cc3, {1|U, {0x10c83}}},
- {0x10cc4, {1|U, {0x10c84}}},
- {0x10cc5, {1|U, {0x10c85}}},
- {0x10cc6, {1|U, {0x10c86}}},
- {0x10cc7, {1|U, {0x10c87}}},
- {0x10cc8, {1|U, {0x10c88}}},
- {0x10cc9, {1|U, {0x10c89}}},
- {0x10cca, {1|U, {0x10c8a}}},
- {0x10ccb, {1|U, {0x10c8b}}},
- {0x10ccc, {1|U, {0x10c8c}}},
- {0x10ccd, {1|U, {0x10c8d}}},
- {0x10cce, {1|U, {0x10c8e}}},
- {0x10ccf, {1|U, {0x10c8f}}},
- {0x10cd0, {1|U, {0x10c90}}},
- {0x10cd1, {1|U, {0x10c91}}},
- {0x10cd2, {1|U, {0x10c92}}},
- {0x10cd3, {1|U, {0x10c93}}},
- {0x10cd4, {1|U, {0x10c94}}},
- {0x10cd5, {1|U, {0x10c95}}},
- {0x10cd6, {1|U, {0x10c96}}},
- {0x10cd7, {1|U, {0x10c97}}},
- {0x10cd8, {1|U, {0x10c98}}},
- {0x10cd9, {1|U, {0x10c99}}},
- {0x10cda, {1|U, {0x10c9a}}},
- {0x10cdb, {1|U, {0x10c9b}}},
- {0x10cdc, {1|U, {0x10c9c}}},
- {0x10cdd, {1|U, {0x10c9d}}},
- {0x10cde, {1|U, {0x10c9e}}},
- {0x10cdf, {1|U, {0x10c9f}}},
- {0x10ce0, {1|U, {0x10ca0}}},
- {0x10ce1, {1|U, {0x10ca1}}},
- {0x10ce2, {1|U, {0x10ca2}}},
- {0x10ce3, {1|U, {0x10ca3}}},
- {0x10ce4, {1|U, {0x10ca4}}},
- {0x10ce5, {1|U, {0x10ca5}}},
- {0x10ce6, {1|U, {0x10ca6}}},
- {0x10ce7, {1|U, {0x10ca7}}},
- {0x10ce8, {1|U, {0x10ca8}}},
- {0x10ce9, {1|U, {0x10ca9}}},
- {0x10cea, {1|U, {0x10caa}}},
- {0x10ceb, {1|U, {0x10cab}}},
- {0x10cec, {1|U, {0x10cac}}},
- {0x10ced, {1|U, {0x10cad}}},
- {0x10cee, {1|U, {0x10cae}}},
- {0x10cef, {1|U, {0x10caf}}},
- {0x10cf0, {1|U, {0x10cb0}}},
- {0x10cf1, {1|U, {0x10cb1}}},
- {0x10cf2, {1|U, {0x10cb2}}},
- {0x118c0, {1|U, {0x118a0}}},
- {0x118c1, {1|U, {0x118a1}}},
- {0x118c2, {1|U, {0x118a2}}},
- {0x118c3, {1|U, {0x118a3}}},
- {0x118c4, {1|U, {0x118a4}}},
- {0x118c5, {1|U, {0x118a5}}},
- {0x118c6, {1|U, {0x118a6}}},
- {0x118c7, {1|U, {0x118a7}}},
- {0x118c8, {1|U, {0x118a8}}},
- {0x118c9, {1|U, {0x118a9}}},
- {0x118ca, {1|U, {0x118aa}}},
- {0x118cb, {1|U, {0x118ab}}},
- {0x118cc, {1|U, {0x118ac}}},
- {0x118cd, {1|U, {0x118ad}}},
- {0x118ce, {1|U, {0x118ae}}},
- {0x118cf, {1|U, {0x118af}}},
- {0x118d0, {1|U, {0x118b0}}},
- {0x118d1, {1|U, {0x118b1}}},
- {0x118d2, {1|U, {0x118b2}}},
- {0x118d3, {1|U, {0x118b3}}},
- {0x118d4, {1|U, {0x118b4}}},
- {0x118d5, {1|U, {0x118b5}}},
- {0x118d6, {1|U, {0x118b6}}},
- {0x118d7, {1|U, {0x118b7}}},
- {0x118d8, {1|U, {0x118b8}}},
- {0x118d9, {1|U, {0x118b9}}},
- {0x118da, {1|U, {0x118ba}}},
- {0x118db, {1|U, {0x118bb}}},
- {0x118dc, {1|U, {0x118bc}}},
- {0x118dd, {1|U, {0x118bd}}},
- {0x118de, {1|U, {0x118be}}},
- {0x118df, {1|U, {0x118bf}}},
- {0x1e922, {1|U, {0x1e900}}},
- {0x1e923, {1|U, {0x1e901}}},
- {0x1e924, {1|U, {0x1e902}}},
- {0x1e925, {1|U, {0x1e903}}},
- {0x1e926, {1|U, {0x1e904}}},
- {0x1e927, {1|U, {0x1e905}}},
- {0x1e928, {1|U, {0x1e906}}},
- {0x1e929, {1|U, {0x1e907}}},
- {0x1e92a, {1|U, {0x1e908}}},
- {0x1e92b, {1|U, {0x1e909}}},
- {0x1e92c, {1|U, {0x1e90a}}},
- {0x1e92d, {1|U, {0x1e90b}}},
- {0x1e92e, {1|U, {0x1e90c}}},
- {0x1e92f, {1|U, {0x1e90d}}},
- {0x1e930, {1|U, {0x1e90e}}},
- {0x1e931, {1|U, {0x1e90f}}},
- {0x1e932, {1|U, {0x1e910}}},
- {0x1e933, {1|U, {0x1e911}}},
- {0x1e934, {1|U, {0x1e912}}},
- {0x1e935, {1|U, {0x1e913}}},
- {0x1e936, {1|U, {0x1e914}}},
- {0x1e937, {1|U, {0x1e915}}},
- {0x1e938, {1|U, {0x1e916}}},
- {0x1e939, {1|U, {0x1e917}}},
- {0x1e93a, {1|U, {0x1e918}}},
- {0x1e93b, {1|U, {0x1e919}}},
- {0x1e93c, {1|U, {0x1e91a}}},
- {0x1e93d, {1|U, {0x1e91b}}},
- {0x1e93e, {1|U, {0x1e91c}}},
- {0x1e93f, {1|U, {0x1e91d}}},
- {0x1e940, {1|U, {0x1e91e}}},
- {0x1e941, {1|U, {0x1e91f}}},
- {0x1e942, {1|U, {0x1e920}}},
- {0x1e943, {1|U, {0x1e921}}},
-#define CaseUnfold_11_Locale (*(CaseUnfold_11_Type (*)[1])(CaseUnfold_11_Table+1266))
- {0x0069, {1|U, {0x0049}}},
-};
-
-/* C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -7 -k1,2,3 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_11_hash -N onigenc_unicode_CaseUnfold_11_lookup -n */
-
-/* maximum key range = 2216, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-/*ARGSUSED*/
-static unsigned int
-onigenc_unicode_CaseUnfold_11_hash(const OnigCodePoint code)
-{
- static const unsigned short asso_values[] =
- {
- 1, 2219, 2, 14, 4, 807, 9, 379, 10, 179,
- 70, 161, 2, 3, 411, 4, 2219, 2219, 2219, 2219,
- 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219, 80,
- 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219,
- 2219, 2219, 2219, 1, 2219, 2219, 2219, 2219, 2219, 2219,
- 2219, 2219, 2219, 210, 2219, 2219, 2219, 2219, 2219, 2219,
- 2219, 2219, 53, 2219, 7, 8, 306, 607, 169, 844,
- 431, 722, 125, 1047, 489, 1394, 15, 16, 324, 1361,
- 140, 521, 47, 461, 221, 985, 70, 965, 9, 1085,
- 51, 1029, 223, 11, 430, 1168, 122, 1457, 344, 930,
- 91, 711, 31, 651, 157, 772, 224, 876, 262, 900,
- 254, 686, 221, 830, 1335, 755, 432, 623, 1382, 675,
- 1275, 587, 99, 821, 1530, 958, 195, 810, 1518, 739,
- 330, 361, 767, 313, 941, 400, 925, 384, 1142, 295,
- 1295, 242, 1103, 229, 1082, 206, 1066, 104, 1317, 137,
- 1249, 263, 1229, 115, 1154, 71, 135, 60, 1211, 158,
- 1472, 175, 1232, 1, 1345, 27, 1269, 38, 1111, 87,
- 1189, 49, 1256, 503, 1157, 574, 1410, 556, 1200, 787,
- 948, 486, 1316, 797, 1218, 1044, 1282, 1007, 1126, 996,
- 818, 1019, 218, 1072
- };
- return asso_values[bits_of(code, 2)+66] + asso_values[bits_of(code, 1)+4] + asso_values[bits_of(code, 0)];
-}
-
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-static const CodePointList3 *
-onigenc_unicode_CaseUnfold_11_lookup(const OnigCodePoint code)
-{
- enum
- {
- MIN_CODE_VALUE = 0x61,
- MAX_CODE_VALUE = 0x1e943,
- TOTAL_KEYWORDS = 1267,
- MIN_WORD_LENGTH = 3,
- MAX_WORD_LENGTH = 3,
- MIN_HASH_VALUE = 3,
- MAX_HASH_VALUE = 2218
- };
-
- static const short wordlist[] =
- {
- -1, -1, -1,
- /*0x13e1*/ 542,
- /*0x0461*/ 339,
- /*0x04e1*/ 399,
- /*0x0061*/ 0,
- -1,
- /*0x104e1*/ 1122,
- /*0x1e61*/ 613,
- /*0x1ee1*/ 672,
- /*0x0161*/ 102,
- /*0x0261*/ 210,
- /*0x2ce1*/ 904,
- -1,
- /*0x049b*/ 364,
- -1, -1,
- /*0x24e1*/ 792,
- /*0x1e1b*/ 578,
- /*0x048b*/ 356,
- /*0x011b*/ 69,
- /*0x021b*/ 178,
- /*0x2c9b*/ 869,
- /*0x1e0b*/ 570,
- /*0x1e8b*/ 634,
- /*0x010b*/ 61,
- /*0x020b*/ 170,
- /*0x2c8b*/ 861,
- /*0x13e3*/ 544,
- /*0x0463*/ 340,
- /*0x04e3*/ 400,
- /*0x0063*/ 2,
- /*0x13a4*/ 481,
- /*0x104e3*/ 1124,
- /*0x1e63*/ 614,
- /*0x1ee3*/ 673,
- /*0x0163*/ 103,
- /*0x0263*/ 211,
- /*0x2ce3*/ 905,
- /*0x13e5*/ 546,
- /*0x0465*/ 341,
- /*0x04e5*/ 401,
- /*0x0065*/ 4,
- /*0x24e3*/ 794,
- /*0x104e5*/ 1126,
- /*0x1e65*/ 615,
- /*0x1ee5*/ 674,
- /*0x0165*/ 104,
- /*0x0265*/ 212,
- /*0xa761*/ 1016,
- /*0x13e9*/ 550,
- /*0x0469*/ 343,
- /*0x04e9*/ 403,
- /*0x0069*/ 1266,
- /*0x24e5*/ 796,
- /*0x104e9*/ 1130,
- /*0x1e69*/ 617,
- /*0x1ee9*/ 676,
- /*0x0169*/ 106,
- /*0x0269*/ 215,
- -1,
- /*0x13db*/ 536,
- /*0x045b*/ 334,
- /*0x04db*/ 396,
- -1,
- /*0x24e9*/ 800,
- /*0x104db*/ 1116,
- /*0x1e5b*/ 610,
- /*0x1edb*/ 669,
- /*0x015b*/ 99,
- /*0x025b*/ 207,
- /*0x2cdb*/ 901,
- /*0x13d9*/ 534,
- /*0x0459*/ 332,
- /*0x04d9*/ 395,
- /*0xa763*/ 1017,
- /*0x24db*/ 786,
- /*0x104d9*/ 1114,
- /*0x1e59*/ 609,
- /*0x1ed9*/ 668,
- /*0x0159*/ 98,
- /*0x0259*/ 206,
- /*0x2cd9*/ 900,
- -1,
- /*0x10ce1*/ 1182,
- -1,
- /*0xa765*/ 1018,
- /*0x24d9*/ 784,
- /*0x13e7*/ 548,
- /*0x0467*/ 342,
- /*0x04e7*/ 402,
- /*0x0067*/ 6,
- /*0x13a2*/ 479,
- /*0x104e7*/ 1128,
- /*0x1e67*/ 616,
- /*0x1ee7*/ 675,
- /*0x0167*/ 105,
- /*0xa769*/ 1020,
- -1, -1,
- /*0x13b8*/ 501,
- /*0x0438*/ 299,
- -1,
- /*0x24e7*/ 798,
- /*0x10438*/ 1089,
- /*0x13d1*/ 526,
- /*0x0451*/ 324,
- /*0x04d1*/ 391,
- /*0xa75b*/ 1013,
- -1,
- /*0x10ce3*/ 1184,
- /*0x1e51*/ 605,
- /*0x1ed1*/ 664,
- /*0x0151*/ 94,
- /*0x0251*/ 200,
- /*0x2cd1*/ 896,
- /*0x13d7*/ 532,
- /*0x0457*/ 330,
- /*0x04d7*/ 394,
- /*0xa759*/ 1012,
- /*0x24d1*/ 776,
- /*0x10ce5*/ 1186,
- /*0x1e57*/ 608,
- /*0x1ed7*/ 667,
- /*0x0157*/ 97,
- /*0x0257*/ 205,
- /*0x2cd7*/ 899,
- -1, -1,
- /*0x0586*/ 476,
- -1,
- /*0x24d7*/ 782,
- /*0x10ce9*/ 1190,
- -1, -1,
- /*0xa767*/ 1019,
- /*0x13da*/ 535,
- /*0x045a*/ 333,
- /*0x13d3*/ 528,
- /*0x0453*/ 326,
- /*0x04d3*/ 392,
- /*0x104da*/ 1115,
- /*0xa661*/ 965,
- /*0x10cdb*/ 1176,
- /*0x1e53*/ 606,
- /*0x1ed3*/ 665,
- /*0x0153*/ 95,
- /*0x0253*/ 202,
- /*0x2cd3*/ 897,
- -1, -1,
- /*0x24da*/ 785,
- /*0xa751*/ 1008,
- /*0x24d3*/ 778,
- /*0x10cd9*/ 1174,
- -1, -1, -1,
- /*0x13a6*/ 483,
- /*0x13dd*/ 538,
- /*0x045d*/ 336,
- /*0x04dd*/ 397,
- /*0x03e1*/ 279,
- /*0xa757*/ 1011,
- /*0x104dd*/ 1118,
- /*0x1e5d*/ 611,
- /*0x1edd*/ 670,
- /*0x015d*/ 100,
- /*0xa663*/ 966,
- /*0x2cdd*/ 902,
- /*0x10ce7*/ 1188,
- -1, -1,
- /*0x0582*/ 472,
- /*0x24dd*/ 788,
- -1,
- /*0x13df*/ 540,
- /*0x045f*/ 338,
- /*0x04df*/ 398,
- /*0xa665*/ 967,
- -1,
- /*0x104df*/ 1120,
- /*0x1e5f*/ 612,
- /*0x1edf*/ 671,
- /*0x015f*/ 101,
- /*0xa753*/ 1009,
- /*0x2cdf*/ 903,
- /*0x10cd1*/ 1166,
- /*0x03e3*/ 280,
- /*0xab53*/ 1046,
- /*0xa669*/ 969,
- /*0x24df*/ 790,
- -1, -1,
- /*0x028a*/ 229,
- /*0x028b*/ 230,
- /*0x13bc*/ 505,
- /*0x043c*/ 303,
- /*0x10cd7*/ 1172,
- /*0x03e5*/ 281,
- /*0x1043c*/ 1093,
- /*0xa65b*/ 962,
- -1, -1,
- /*0x013c*/ 84,
- /*0x023c*/ 190,
- /*0xa75d*/ 1014,
- /*0x13cf*/ 524,
- /*0x044f*/ 322,
- /*0x04cf*/ 390,
- /*0x03e9*/ 283,
- /*0x1044f*/ 1112,
- /*0xa659*/ 961,
- /*0x1e4f*/ 604,
- /*0x1ecf*/ 663,
- /*0x014f*/ 93,
- /*0x024f*/ 198,
- /*0x2ccf*/ 895,
- /*0x10cda*/ 1175,
- -1,
- /*0x10cd3*/ 1168,
- /*0x03db*/ 276,
- /*0x13ae*/ 491,
- /*0xa75f*/ 1015,
- /*0x2c61*/ 848,
- /*0x13a8*/ 485,
- /*0x1042e*/ 1079,
- /*0x017e*/ 116,
- /*0xa667*/ 968,
- /*0x10428*/ 1073,
- /*0x13cd*/ 522,
- /*0x044d*/ 320,
- /*0x03d9*/ 275,
- -1,
- /*0x1044d*/ 1110,
- -1,
- /*0x1e4d*/ 603,
- /*0x1ecd*/ 662,
- /*0x014d*/ 92,
- /*0x024d*/ 197,
- /*0x2ccd*/ 894,
- /*0x10cdd*/ 1178,
- -1,
- /*0x13cb*/ 520,
- /*0x044b*/ 318,
- /*0xa651*/ 957,
- -1,
- /*0x1044b*/ 1108,
- /*0x03e7*/ 282,
- /*0x1e4b*/ 602,
- /*0x1ecb*/ 661,
- /*0x014b*/ 91,
- /*0x024b*/ 196,
- /*0x2ccb*/ 893,
- /*0xa74f*/ 1007,
- /*0x13ac*/ 489,
- /*0xa657*/ 960,
- -1,
- /*0x10cdf*/ 1180,
- /*0x1042c*/ 1077,
- /*0x03b8*/ 252,
- /*0x2c65*/ 849,
- -1,
- /*0x13aa*/ 487,
- /*0x13d5*/ 530,
- /*0x0455*/ 328,
- /*0x04d5*/ 393,
- /*0x1042a*/ 1075,
- -1, -1,
- /*0x1e55*/ 607,
- /*0x1ed5*/ 666,
- /*0x0155*/ 96,
- /*0x118db*/ 1227,
- /*0x2cd5*/ 898,
- -1,
- /*0x03d7*/ 274,
- /*0xa74d*/ 1006,
- /*0xa653*/ 958,
- /*0x24d5*/ 780,
- -1, -1, -1,
- /*0x2c5b*/ 844,
- /*0x118d9*/ 1225,
- -1, -1, -1, -1,
- /*0x10ccf*/ 1164,
- /*0xa74b*/ 1005,
- -1, -1, -1,
- /*0x2c59*/ 842,
- -1,
- /*0x13c9*/ 518,
- /*0x0449*/ 316,
- -1,
- /*0xa65d*/ 963,
- /*0x10449*/ 1106,
- /*0x029e*/ 234,
- /*0x1e49*/ 601,
- /*0x1ec9*/ 660,
- -1,
- /*0x0249*/ 195,
- /*0x2cc9*/ 892,
- /*0x1f61*/ 729,
- -1, -1,
- /*0x0580*/ 470,
- /*0xa755*/ 1010,
- /*0x10ccd*/ 1162,
- -1,
- /*0x13c3*/ 512,
- /*0x0443*/ 310,
- /*0xa65f*/ 964,
- /*0x118d1*/ 1217,
- /*0x10443*/ 1100,
- /*0x03dd*/ 277,
- /*0x1e43*/ 598,
- /*0x1ec3*/ 657,
- /*0x2c38*/ 809,
- -1,
- /*0x2cc3*/ 889,
- /*0x10ccb*/ 1160,
- -1,
- /*0x2c51*/ 834,
- /*0x118d7*/ 1223,
- -1, -1,
- /*0x13c0*/ 509,
- /*0x0440*/ 307,
- /*0x1f63*/ 731,
- -1,
- /*0x10440*/ 1097,
- /*0x03df*/ 278,
- /*0x1f24*/ 706,
- /*0x2c57*/ 840,
- /*0x0140*/ 86,
- /*0x0240*/ 192,
- -1, -1,
- /*0xa749*/ 1004,
- /*0x1f65*/ 733,
- /*0x13a0*/ 477,
- /*0x10cd5*/ 1170,
- /*0xa64f*/ 956,
- /*0x118da*/ 1226,
- -1,
- /*0x118d3*/ 1219,
- -1, -1,
- /*0x1f10*/ 696,
- -1, -1,
- /*0x03bc*/ 256,
- -1,
- /*0x2c5a*/ 843,
- -1,
- /*0x2c53*/ 836,
- /*0xa743*/ 1001,
- /*0x13c1*/ 510,
- /*0x0441*/ 308,
- -1, -1,
- /*0x10441*/ 1098,
- -1,
- /*0x1e41*/ 597,
- /*0x1ec1*/ 656,
- /*0xa64d*/ 955,
- /*0x118dd*/ 1229,
- /*0x2cc1*/ 888,
- -1, -1, -1,
- /*0x1f14*/ 700,
- -1,
- /*0x10cc9*/ 1158,
- -1,
- /*0x01e1*/ 151,
- /*0x2c5d*/ 846,
- /*0x03ae*/ 243,
- /*0xa64b*/ 954,
- -1,
- /*0x13c7*/ 516,
- /*0x0447*/ 314,
- -1,
- /*0x118df*/ 1231,
- /*0x10447*/ 1104,
- /*0x03cd*/ 272,
- /*0x1e47*/ 600,
- /*0x1ec7*/ 659,
- /*0x1f67*/ 735,
- /*0x0247*/ 194,
- /*0x2cc7*/ 891,
- /*0x10cc3*/ 1152,
- /*0x1f22*/ 704,
- -1, -1,
- /*0x0292*/ 232,
- /*0x13c5*/ 514,
- /*0x0445*/ 312,
- /*0x03cb*/ 270,
- /*0xa655*/ 959,
- /*0x10445*/ 1102,
- /*0x01e3*/ 152,
- /*0x1e45*/ 599,
- /*0x1ec5*/ 658,
- /*0xa741*/ 1000,
- /*0x1f51*/ 724,
- /*0x2cc5*/ 890,
- /*0x0561*/ 439,
- /*0x10cc0*/ 1149,
- /*0xff59*/ 1071,
- /*0x03ac*/ 241,
- -1,
- /*0x01e5*/ 153,
- /*0x2c3c*/ 813,
- /*0x118cf*/ 1215,
- -1,
- /*0x1f57*/ 727,
- /*0x051b*/ 428,
- -1, -1, -1, -1,
- /*0x050b*/ 420,
- /*0x01e9*/ 155,
- /*0x2c4f*/ 832,
- -1,
- /*0x1f06*/ 694,
- /*0xa747*/ 1003,
- /*0x13b2*/ 495,
- /*0x0432*/ 293,
- /*0x0584*/ 474,
- /*0xa649*/ 953,
- /*0x10432*/ 1083,
- /*0x0563*/ 441,
- /*0x2d16*/ 931,
- -1,
- /*0x2d1b*/ 936,
- /*0x118cd*/ 1213,
- /*0x1f53*/ 725,
- /*0x10cc1*/ 1150,
- /*0x2d0a*/ 919,
- /*0x2d0b*/ 920,
- /*0xff51*/ 1063,
- /*0xa745*/ 1002,
- /*0x0565*/ 443,
- -1, -1,
- /*0x2c4d*/ 830,
- -1,
- /*0xa643*/ 950,
- /*0x118cb*/ 1211,
- /*0x03c9*/ 268,
- -1,
- /*0xff57*/ 1069,
- -1,
- /*0x0569*/ 447,
- /*0x2d24*/ 945,
- -1,
- /*0x1f26*/ 708,
- /*0x0491*/ 359,
- /*0x2c4b*/ 828,
- /*0x01e7*/ 154,
- /*0x10cc7*/ 1156,
- /*0x1e11*/ 573,
- /*0x1e91*/ 637,
- /*0x0111*/ 64,
- /*0x0211*/ 173,
- /*0x2c91*/ 864,
- /*0xa79b*/ 1036,
- /*0x03c3*/ 262,
- /*0x1f02*/ 690,
- /*0x118d5*/ 1221,
- /*0x2d10*/ 925,
- /*0xff5a*/ 1072,
- /*0x1e924*/ 1234,
- /*0xff53*/ 1065,
- /*0x2d18*/ 933,
- -1,
- /*0x10cc5*/ 1154,
- -1,
- /*0x0280*/ 224,
- /*0x2c55*/ 838,
- /*0x13f3*/ 560,
- /*0x0473*/ 348,
- /*0x04f3*/ 408,
- /*0x0073*/ 17,
- /*0x03c0*/ 260,
- /*0x104f3*/ 1140,
- /*0x1e73*/ 622,
- /*0x1ef3*/ 681,
- /*0x0173*/ 111,
- -1,
- /*0x2cf3*/ 908,
- /*0x0567*/ 445,
- -1,
- /*0x2d14*/ 929,
- /*0x019e*/ 126,
- /*0xa641*/ 949,
- /*0x028c*/ 231,
- /*0x13eb*/ 552,
- /*0x046b*/ 344,
- /*0x04eb*/ 404,
- /*0x006b*/ 9,
- /*0x118c9*/ 1209,
- /*0x104eb*/ 1132,
- /*0x1e6b*/ 618,
- /*0x1eeb*/ 677,
- /*0x016b*/ 107,
- /*0x026b*/ 217,
- /*0x01da*/ 147,
- -1, -1, -1,
- /*0x2c49*/ 826,
- -1, -1,
- /*0x2d22*/ 943,
- /*0x03c1*/ 261,
- -1,
- /*0x048f*/ 358,
- /*0xa647*/ 952,
- /*0x118c3*/ 1203,
- /*0x1f12*/ 698,
- /*0x1e0f*/ 572,
- /*0x1e8f*/ 636,
- /*0x010f*/ 63,
- /*0x020f*/ 172,
- /*0x2c8f*/ 863,
- /*0xa69b*/ 985,
- -1, -1,
- /*0x2c43*/ 820,
- /*0x01dd*/ 149,
- /*0xa68b*/ 977,
- /*0x1e922*/ 1232,
- -1,
- /*0xa645*/ 951,
- -1,
- /*0x118c0*/ 1200,
- -1,
- /*0x03c7*/ 266,
- -1,
- /*0x1e938*/ 1254,
- -1,
- /*0xff4f*/ 1061,
- -1,
- /*0xa76b*/ 1021,
- /*0x2d1e*/ 939,
- /*0x2c40*/ 817,
- /*0x01df*/ 150,
- /*0x2d06*/ 915,
- /*0x0373*/ 236,
- /*0x13ef*/ 556,
- /*0x046f*/ 346,
- /*0x04ef*/ 406,
- /*0x006f*/ 13,
- /*0x03c5*/ 264,
- /*0x104ef*/ 1136,
- /*0x1e6f*/ 620,
- /*0x1eef*/ 679,
- /*0x016f*/ 109,
- /*0x026f*/ 219,
- -1, -1,
- /*0x1f55*/ 726,
- /*0x2d0e*/ 923,
- -1,
- /*0xff4d*/ 1059,
- -1,
- /*0x118c1*/ 1201,
- /*0x13ed*/ 554,
- /*0x046d*/ 345,
- /*0x04ed*/ 405,
- /*0x006d*/ 11,
- -1,
- /*0x104ed*/ 1134,
- /*0x1e6d*/ 619,
- /*0x1eed*/ 678,
- /*0x016d*/ 108,
- /*0x2c41*/ 818,
- /*0xff4b*/ 1057,
- /*0x10ceb*/ 1192,
- -1,
- /*0x13b7*/ 500,
- /*0x0437*/ 298,
- /*0x04b7*/ 378,
- -1,
- /*0x10437*/ 1088,
- /*0x03b2*/ 246,
- /*0x1e37*/ 592,
- /*0x1eb7*/ 651,
- /*0x0137*/ 82,
- /*0x118c7*/ 1207,
- /*0x2cb7*/ 883,
- /*0x2d02*/ 911,
- /*0x0192*/ 122,
- -1,
- /*0x019a*/ 125,
- /*0x01a8*/ 130,
- /*0xa76f*/ 1023,
- /*0x1e926*/ 1236,
- /*0xff55*/ 1067,
- /*0x2c47*/ 824,
- /*0x1fe1*/ 755,
- -1,
- /*0x0481*/ 355,
- /*0x0581*/ 471,
- /*0x1f00*/ 688,
- /*0x118c5*/ 1205,
- /*0x1e01*/ 565,
- /*0x1e81*/ 629,
- /*0x0101*/ 56,
- /*0x0201*/ 165,
- /*0x2c81*/ 856,
- /*0x1f43*/ 721,
- -1, -1,
- /*0xa76d*/ 1022,
- /*0x2c45*/ 822,
- /*0x13b3*/ 496,
- /*0x0433*/ 294,
- /*0x04b3*/ 376,
- -1,
- /*0x10433*/ 1084,
- /*0x057e*/ 468,
- /*0x1e33*/ 590,
- /*0x1eb3*/ 649,
- /*0x0133*/ 80,
- /*0x0233*/ 189,
- /*0x2cb3*/ 881,
- /*0xa737*/ 995,
- /*0x1f40*/ 718,
- -1,
- /*0xff49*/ 1055,
- /*0x10cef*/ 1196,
- -1, -1, -1,
- /*0x1e93c*/ 1258,
- /*0xa66b*/ 970,
- /*0x1fe5*/ 756,
- -1,
- /*0x03f3*/ 288,
- -1,
- /*0x217e*/ 772,
- /*0x1f20*/ 702,
- /*0x2d12*/ 927,
- /*0x13a5*/ 482,
- /*0x2d1a*/ 935,
- /*0x04a5*/ 369,
- /*0x2c32*/ 803,
- /*0xff43*/ 1049,
- /*0x10ced*/ 1194,
- /*0x1e25*/ 583,
- /*0x1ea5*/ 642,
- /*0x0125*/ 74,
- /*0x0225*/ 182,
- /*0x2ca5*/ 874,
- -1,
- /*0x03eb*/ 284,
- -1, -1,
- /*0x1f41*/ 719,
- /*0x0288*/ 227,
- /*0x1e92e*/ 1244,
- -1,
- /*0xa733*/ 993,
- /*0x1e928*/ 1238,
- -1,
- /*0x01c9*/ 139,
- -1,
- /*0x13b5*/ 498,
- /*0x0435*/ 296,
- /*0x04b5*/ 377,
- -1,
- /*0x10435*/ 1086,
- -1,
- /*0x1e35*/ 591,
- /*0x1eb5*/ 650,
- /*0x0135*/ 81,
- /*0x0180*/ 117,
- /*0x2cb5*/ 882,
- /*0x13ad*/ 490,
- -1,
- /*0x04ad*/ 373,
- -1,
- /*0x1042d*/ 1078,
- -1,
- /*0x1e2d*/ 587,
- /*0x1ead*/ 646,
- /*0x012d*/ 78,
- /*0x022d*/ 186,
- /*0x2cad*/ 878,
- -1,
- /*0xa725*/ 987,
- -1, -1,
- /*0x1e92c*/ 1242,
- /*0x018c*/ 121,
- /*0xff41*/ 1047,
- -1,
- /*0x1f45*/ 723,
- -1, -1,
- /*0x2c73*/ 854,
- /*0x1e92a*/ 1240,
- /*0x1fd1*/ 753,
- /*0x13a3*/ 480,
- -1,
- /*0x04a3*/ 368,
- /*0xa66d*/ 971,
- -1,
- /*0x03ef*/ 286,
- /*0x1e23*/ 582,
- /*0x1ea3*/ 641,
- /*0x0123*/ 73,
- /*0x0223*/ 181,
- /*0x2ca3*/ 873,
- /*0xa735*/ 994,
- -1, -1,
- /*0x0585*/ 475,
- /*0xff47*/ 1053,
- -1,
- /*0x1e05*/ 567,
- /*0x1e85*/ 631,
- /*0x0105*/ 58,
- /*0x0205*/ 167,
- /*0x2c85*/ 858,
- /*0xa72d*/ 991,
- /*0x03ed*/ 285,
- /*0x2d00*/ 909,
- /*0x1f04*/ 692,
- /*0x1f32*/ 712,
- -1,
- /*0x13bf*/ 508,
- /*0x043f*/ 306,
- /*0x04bf*/ 382,
- /*0xff45*/ 1051,
- /*0x1043f*/ 1096,
- -1,
- /*0x1e3f*/ 596,
- /*0x1ebf*/ 655,
- /*0x03b7*/ 251,
- /*0x023f*/ 191,
- /*0x2cbf*/ 887,
- -1, -1, -1,
- /*0x2d0c*/ 921,
- -1,
- /*0x13b1*/ 494,
- /*0x0431*/ 292,
- /*0x04b1*/ 375,
- /*0xa723*/ 986,
- /*0x10431*/ 1082,
- /*0x1e943*/ 1265,
- /*0x1e31*/ 589,
- /*0x1eb1*/ 648,
- -1,
- /*0x0231*/ 188,
- /*0x2cb1*/ 880,
- /*0x1f11*/ 697,
- /*0x13c2*/ 511,
- /*0x0442*/ 309,
- /*0x04c2*/ 383,
- -1,
- /*0x10442*/ 1099,
- /*0x13a7*/ 484,
- /*0x2d20*/ 941,
- /*0x04a7*/ 370,
- /*0x0142*/ 87,
- /*0x0242*/ 193,
- /*0x1e940*/ 1262,
- /*0x1e27*/ 584,
- /*0x1ea7*/ 643,
- /*0x0127*/ 75,
- /*0x0227*/ 183,
- /*0x2ca7*/ 875,
- /*0x03b3*/ 247,
- -1,
- /*0xa78c*/ 1031,
- /*0xa73f*/ 999,
- /*0x13f1*/ 558,
- /*0x0471*/ 347,
- /*0x04f1*/ 407,
- /*0x0071*/ 15,
- /*0x1f73*/ 739,
- /*0x104f1*/ 1138,
- /*0x1e71*/ 621,
- /*0x1ef1*/ 680,
- /*0x0171*/ 110,
- /*0x0271*/ 220,
- /*0x13f5*/ 562,
- /*0x0475*/ 349,
- /*0x04f5*/ 409,
- /*0x0075*/ 19,
- -1,
- /*0x104f5*/ 1142,
- /*0x1e75*/ 623,
- /*0x1ef5*/ 682,
- /*0x0175*/ 112,
- /*0x0275*/ 222,
- /*0x00e1*/ 26,
- /*0x1e941*/ 1263,
- /*0x2c37*/ 808,
- /*0x13bd*/ 506,
- /*0x043d*/ 304,
- /*0x04bd*/ 381,
- -1,
- /*0x1043d*/ 1094,
- -1,
- /*0x1e3d*/ 595,
- /*0x1ebd*/ 654,
- -1,
- /*0xa727*/ 988,
- /*0x2cbd*/ 886,
- /*0x13b9*/ 502,
- /*0x0439*/ 300,
- /*0x04b9*/ 379,
- -1,
- /*0x10439*/ 1090,
- /*0x017c*/ 115,
- /*0x1e39*/ 593,
- /*0x1eb9*/ 652,
- -1,
- /*0x13af*/ 492,
- /*0x2cb9*/ 884,
- /*0x04af*/ 374,
- /*0x00e3*/ 28,
- /*0x1042f*/ 1080,
- /*0x03b5*/ 249,
- /*0x1e2f*/ 588,
- /*0x1eaf*/ 647,
- /*0x012f*/ 79,
- /*0x022f*/ 187,
- /*0x2caf*/ 879,
- -1, -1, -1,
- /*0x00e5*/ 30,
- /*0x2c33*/ 804,
- /*0x03ad*/ 242,
- /*0x0583*/ 473,
- -1,
- /*0x10cc2*/ 1151,
- /*0x1e03*/ 566,
- /*0x1e83*/ 630,
- /*0x0103*/ 57,
- /*0x0203*/ 166,
- /*0x2c83*/ 857,
- /*0x00e9*/ 34,
- /*0x0371*/ 235,
- /*0xa73d*/ 998,
- -1,
- /*0x2d1c*/ 937,
- /*0x2d04*/ 913,
- -1, -1, -1,
- /*0x01f3*/ 159,
- /*0xa77c*/ 1025,
- -1,
- /*0x0188*/ 120,
- /*0xa739*/ 996,
- /*0x10cf1*/ 1198,
- -1,
- /*0x0511*/ 423,
- -1, -1, -1, -1,
- /*0x13a9*/ 486,
- /*0xa72f*/ 992,
- /*0x04a9*/ 371,
- /*0x1e932*/ 1248,
- /*0x10429*/ 1074,
- /*0x01eb*/ 156,
- /*0x1e29*/ 585,
- /*0x1ea9*/ 644,
- /*0x0129*/ 76,
- /*0x0229*/ 184,
- /*0x2ca9*/ 876,
- /*0x037c*/ 239,
- -1, -1,
- /*0x2d11*/ 926,
- -1,
- /*0x1f37*/ 717,
- /*0x00e7*/ 32,
- -1, -1,
- /*0x0573*/ 457,
- /*0x2c35*/ 806,
- -1,
- /*0x03bf*/ 259,
- /*0x13ab*/ 488,
- -1,
- /*0x04ab*/ 372,
- -1,
- /*0x1042b*/ 1076,
- -1,
- /*0x1e2b*/ 586,
- /*0x1eab*/ 645,
- /*0x012b*/ 77,
- /*0x022b*/ 185,
- /*0x2cab*/ 877,
- -1,
- /*0x1f01*/ 689,
- /*0x056b*/ 449,
- -1,
- /*0x03b1*/ 245,
- /*0x2173*/ 761,
- -1,
- /*0x2d08*/ 917,
- -1, -1, -1,
- /*0xa791*/ 1032,
- /*0xa729*/ 989,
- -1,
- /*0x13c6*/ 515,
- /*0x0446*/ 313,
- /*0x04c6*/ 385,
- /*0x1f33*/ 713,
- /*0x10446*/ 1103,
- /*0x13a1*/ 478,
- /*0x050f*/ 422,
- /*0x04a1*/ 367,
- /*0x0146*/ 89,
- /*0x01ef*/ 158,
- -1,
- /*0x1e21*/ 581,
- /*0x1ea1*/ 640,
- /*0x0121*/ 72,
- -1,
- /*0x2ca1*/ 872,
- /*0x13c4*/ 513,
- /*0x0444*/ 311,
- /*0x04c4*/ 384,
- -1,
- /*0x10444*/ 1101,
- -1,
- /*0xa72b*/ 990,
- /*0x13f2*/ 559,
- /*0x0144*/ 88,
- /*0x2d0f*/ 924,
- /*0x0072*/ 16,
- /*0x01ed*/ 157,
- /*0x104f2*/ 1139,
- -1, -1,
- /*0x1f25*/ 707,
- /*0x0272*/ 221,
- /*0x13bb*/ 504,
- /*0x043b*/ 302,
- /*0x04bb*/ 380,
- /*0x2c3f*/ 816,
- /*0x1043b*/ 1092,
- -1,
- /*0x1e3b*/ 594,
- /*0x1ebb*/ 653,
- /*0x056f*/ 453,
- /*0x0495*/ 361,
- /*0x2cbb*/ 885,
- -1,
- /*0x03bd*/ 257,
- /*0x1e15*/ 575,
- /*0x1e95*/ 639,
- /*0x0115*/ 66,
- /*0x0215*/ 175,
- /*0x2c95*/ 866,
- -1,
- /*0x2c31*/ 802,
- -1,
- /*0x118c2*/ 1202,
- /*0x1f35*/ 715,
- /*0x03b9*/ 253,
- /*0xa691*/ 980,
- -1,
- /*0x056d*/ 451,
- -1, -1,
- /*0x0493*/ 360,
- -1,
- /*0x2c42*/ 819,
- /*0x03af*/ 244,
- /*0x1e13*/ 574,
- /*0x1e93*/ 638,
- /*0x0113*/ 65,
- /*0x0213*/ 174,
- /*0x2c93*/ 865,
- -1,
- /*0x047b*/ 352,
- /*0x04fb*/ 412,
- -1, -1,
- /*0x104fb*/ 1148,
- /*0x1e7b*/ 626,
- /*0x1efb*/ 685,
- -1,
- /*0xa73b*/ 997,
- -1,
- /*0x10cc6*/ 1155,
- /*0x0479*/ 351,
- /*0x04f9*/ 411,
- /*0x0079*/ 23,
- -1,
- /*0x104f9*/ 1146,
- /*0x1e79*/ 625,
- /*0x1ef9*/ 684,
- -1,
- /*0x1f23*/ 705,
- /*0x0501*/ 415,
- -1, -1,
- /*0x047d*/ 353,
- /*0x04fd*/ 413,
- /*0x0283*/ 225,
- /*0x10cc4*/ 1153,
- /*0x00fe*/ 54,
- /*0x1e7d*/ 627,
- /*0x1efd*/ 686,
- /*0x1f05*/ 693,
- /*0x027d*/ 223,
- /*0x01a5*/ 129,
- /*0x10cf2*/ 1199,
- /*0x0499*/ 363,
- /*0x2c3d*/ 814,
- -1,
- /*0x1e937*/ 1253,
- /*0x1e19*/ 577,
- /*0x2d01*/ 910,
- /*0x0119*/ 68,
- /*0x0219*/ 177,
- /*0x2c99*/ 868,
- -1, -1,
- /*0xa68f*/ 979,
- /*0x2c39*/ 810,
- -1,
- /*0x0477*/ 350,
- /*0x04f7*/ 410,
- /*0x0077*/ 21,
- /*0xa7b7*/ 1045,
- /*0x104f7*/ 1144,
- /*0x1e77*/ 624,
- /*0x1ef7*/ 683,
- /*0x0177*/ 113,
- /*0x1e07*/ 568,
- /*0x1e87*/ 632,
- /*0x0107*/ 59,
- /*0x0207*/ 168,
- /*0x2c87*/ 859,
- -1,
- /*0x1d79*/ 563,
- /*0x1f31*/ 711,
- /*0x0525*/ 433,
- -1, -1,
- /*0x01ad*/ 131,
- /*0x037b*/ 238,
- /*0x13d0*/ 525,
- /*0x0450*/ 323,
- /*0xa781*/ 1027,
- -1,
- /*0x1e933*/ 1249,
- /*0x1d7d*/ 564,
- /*0x1f42*/ 720,
- /*0x047f*/ 354,
- /*0x04ff*/ 414,
- /*0x0250*/ 199,
- -1,
- /*0x1f27*/ 709,
- /*0x1e7f*/ 628,
- /*0x1eff*/ 687,
- /*0x2d25*/ 946,
- /*0x24d0*/ 775,
- /*0x13ce*/ 523,
- /*0x044e*/ 321,
- /*0x04ce*/ 389,
- /*0x03c6*/ 265,
- /*0x1044e*/ 1111,
- /*0x0497*/ 362,
- /*0x037d*/ 240,
- /*0x01a3*/ 128,
- -1,
- /*0x1e17*/ 576,
- /*0x1f71*/ 737,
- /*0x0117*/ 67,
- /*0x0217*/ 176,
- /*0x2c97*/ 867,
- /*0x052d*/ 437,
- -1,
- /*0x1e925*/ 1235,
- -1,
- /*0x0185*/ 119,
- /*0x03c4*/ 263,
- /*0x1f75*/ 741,
- /*0x13cc*/ 521,
- /*0x044c*/ 319,
- /*0x04cc*/ 388,
- -1,
- /*0x1044c*/ 1109,
- /*0x03f2*/ 287,
- /*0xff42*/ 1048,
- -1,
- /*0x13e6*/ 547,
- /*0xa7a5*/ 1041,
- /*0x0377*/ 237,
- /*0x0066*/ 5,
- /*0x2d2d*/ 948,
- /*0x104e6*/ 1127,
- /*0x01bf*/ 137,
- /*0x03bb*/ 255,
- /*0xa77f*/ 1026,
- /*0x0266*/ 213,
- /*0x0523*/ 432,
- /*0x1e935*/ 1251,
- /*0x1f7c*/ 748,
- -1, -1,
- /*0x24e6*/ 797,
- -1,
- /*0xa681*/ 972,
- /*0x007a*/ 24,
- -1,
- /*0x104fa*/ 1147,
- /*0x0505*/ 417,
- /*0x1e92d*/ 1243,
- /*0x017a*/ 114,
- -1,
- /*0xa7b5*/ 1044,
- /*0x118c6*/ 1206,
- -1, -1,
- /*0x2d23*/ 944,
- -1,
- /*0x13c8*/ 517,
- /*0x0448*/ 315,
- /*0x04c8*/ 386,
- -1,
- /*0x10448*/ 1105,
- /*0x2c46*/ 823,
- /*0x10cd0*/ 1165,
- /*0x1f03*/ 691,
- /*0x0148*/ 90,
- /*0x2d05*/ 914,
- /*0x2184*/ 774,
- /*0x118c4*/ 1204,
- /*0x13d8*/ 533,
- /*0x0458*/ 331,
- /*0x03fb*/ 290,
- /*0x13ec*/ 553,
- /*0x1e923*/ 1233,
- /*0x104d8*/ 1113,
- /*0x006c*/ 10,
- -1,
- /*0x104ec*/ 1133,
- /*0x2c44*/ 821,
- /*0x10cce*/ 1163,
- -1,
- /*0x026c*/ 218,
- /*0x2cec*/ 906,
- -1,
- /*0x24d8*/ 783,
- /*0x049d*/ 365,
- -1,
- /*0xa7a3*/ 1040,
- /*0xa77a*/ 1024,
- /*0x1e1d*/ 579,
- /*0x01f5*/ 160,
- /*0x011d*/ 70,
- /*0x021d*/ 179,
- /*0x2c9d*/ 870,
- -1,
- /*0x2c3b*/ 812,
- -1,
- /*0x0527*/ 434,
- /*0xa785*/ 1029,
- -1,
- /*0x10ccc*/ 1161,
- /*0x1e93f*/ 1261,
- -1,
- /*0x01bd*/ 136,
- /*0x13e8*/ 549,
- -1, -1,
- /*0x0068*/ 7,
- /*0x10ce6*/ 1187,
- /*0x104e8*/ 1129,
- -1, -1,
- /*0x0571*/ 455,
- /*0x0268*/ 214,
- /*0x01b9*/ 135,
- /*0x13f0*/ 557,
- /*0x2d27*/ 947,
- /*0x1e931*/ 1247,
- /*0x0070*/ 14,
- /*0x24e8*/ 799,
- /*0x104f0*/ 1137,
- -1,
- /*0x0575*/ 459,
- -1, -1, -1,
- /*0x13dc*/ 537,
- /*0x045c*/ 335,
- -1,
- /*0x1e942*/ 1264,
- -1,
- /*0x104dc*/ 1117,
- /*0x2171*/ 759,
- -1,
- /*0x1e927*/ 1237,
- /*0x025c*/ 208,
- /*0x0076*/ 20,
- /*0x0183*/ 118,
- /*0x104f6*/ 1143,
- /*0x10cc8*/ 1157,
- /*0x0287*/ 226,
- /*0x24dc*/ 787,
- /*0x2175*/ 763,
- /*0x057c*/ 466,
- /*0x13d6*/ 531,
- /*0x0456*/ 329,
- -1,
- /*0x13e0*/ 541,
- /*0xa7a7*/ 1042,
- -1,
- /*0x1f21*/ 703,
- /*0x10cd8*/ 1173,
- /*0x104e0*/ 1121,
- /*0x0256*/ 204,
- /*0x10cec*/ 1193,
- /*0x052f*/ 438,
- /*0x0260*/ 209,
- /*0x03ce*/ 273,
- /*0xa685*/ 974,
- /*0x24d6*/ 781,
- -1,
- /*0x1f44*/ 722,
- /*0x24e0*/ 791,
- /*0x217c*/ 770,
- /*0x13d4*/ 529,
- /*0x0454*/ 327,
- -1, -1,
- /*0x1f72*/ 738,
- /*0x0503*/ 416,
- -1,
- /*0x13ea*/ 551,
- /*0x1e93d*/ 1259,
- /*0x0254*/ 203,
- /*0x006a*/ 8,
- -1,
- /*0x104ea*/ 1131,
- -1,
- /*0x03cc*/ 271,
- /*0x24d4*/ 779,
- /*0x026a*/ 216,
- -1,
- /*0xff46*/ 1052,
- /*0x1e939*/ 1255,
- /*0x13e4*/ 545,
- /*0x1f15*/ 701,
- /*0x10ce8*/ 1189,
- /*0x0064*/ 3,
- /*0x2d03*/ 912,
- /*0x104e4*/ 1125,
- /*0x13b6*/ 499,
- /*0x0436*/ 297,
- /*0x1e92f*/ 1245,
- /*0x118d0*/ 1216,
- /*0x10436*/ 1087,
- -1, -1,
- /*0x10cf0*/ 1197,
- /*0xff44*/ 1050,
- /*0x24e4*/ 795,
- /*0x0078*/ 22,
- /*0x0529*/ 435,
- /*0x104f8*/ 1145,
- /*0x2c50*/ 833,
- -1,
- /*0x1f13*/ 699,
- -1,
- /*0x00f3*/ 44,
- /*0x10cdc*/ 1177,
- /*0x118ce*/ 1214,
- /*0x13ca*/ 519,
- /*0x044a*/ 317,
- /*0x04ca*/ 387,
- -1,
- /*0x1044a*/ 1107,
- -1,
- /*0x1f7b*/ 747,
- /*0x03c8*/ 267,
- /*0x01c6*/ 138,
- /*0x2c4e*/ 831,
- /*0xa783*/ 1028,
- -1, -1,
- /*0x01a1*/ 127,
- /*0x00eb*/ 36,
- /*0x052b*/ 436,
- /*0x10cd6*/ 1171,
- /*0x1f79*/ 745,
- -1,
- /*0x10ce0*/ 1181,
- /*0x118cc*/ 1212,
- /*0x13f4*/ 561,
- /*0x13d2*/ 527,
- /*0x0452*/ 325,
- /*0x0074*/ 18,
- -1,
- /*0x104f4*/ 1141,
- -1,
- /*0x1e929*/ 1239,
- /*0x1f7d*/ 749,
- /*0x2c4c*/ 829,
- /*0x0252*/ 201,
- -1, -1, -1, -1,
- /*0x10cd4*/ 1169,
- /*0x24d2*/ 777,
- /*0x2c66*/ 850,
- -1,
- /*0x13b0*/ 493,
- /*0x0430*/ 291,
- /*0xa7a9*/ 1043,
- /*0x10cea*/ 1191,
- /*0x10430*/ 1081,
- /*0x0521*/ 431,
- -1, -1,
- /*0x0195*/ 123,
- -1,
- /*0x13e2*/ 543,
- /*0x029d*/ 233,
- /*0x1e92b*/ 1241,
- /*0x0062*/ 1,
- /*0x1f77*/ 743,
- /*0x104e2*/ 1123,
- /*0x10ce4*/ 1185,
- /*0x1f07*/ 695,
- -1,
- /*0x118c8*/ 1208,
- -1, -1, -1,
- /*0x0572*/ 456,
- /*0x2d21*/ 942,
- /*0x24e2*/ 793,
- /*0x1fb1*/ 751,
- /*0x00ef*/ 40,
- /*0x048d*/ 357,
- /*0x2c48*/ 825,
- /*0xa683*/ 973,
- /*0x118d8*/ 1224,
- /*0x1e0d*/ 571,
- /*0x1e8d*/ 635,
- /*0x010d*/ 62,
- /*0x020d*/ 171,
- /*0x2c8d*/ 862,
- -1, -1,
- /*0x01fb*/ 162,
- /*0x0515*/ 425,
- /*0x2c58*/ 841,
- /*0x10cca*/ 1159,
- /*0x2172*/ 760,
- /*0x2c6c*/ 853,
- /*0x00ed*/ 38,
- -1,
- /*0x13b4*/ 497,
- /*0x0434*/ 295,
- -1,
- /*0x01f9*/ 161,
- /*0x10434*/ 1085,
- -1, -1, -1, -1,
- /*0xa7a1*/ 1039,
- -1, -1,
- /*0x2d15*/ 930,
- /*0x0513*/ 424,
- -1,
- /*0x01fd*/ 163,
- -1,
- /*0x10cd2*/ 1167,
- /*0x1e09*/ 569,
- /*0x1e89*/ 633,
- /*0x0109*/ 60,
- /*0x0209*/ 169,
- /*0x2c89*/ 860,
- /*0x1e93b*/ 1257,
- /*0x057b*/ 465,
- /*0x0199*/ 124,
- /*0xff50*/ 1062,
- -1,
- /*0x13ee*/ 555,
- /*0x2c68*/ 851,
- -1,
- /*0x006e*/ 12,
- /*0x2d13*/ 928,
- /*0x104ee*/ 1135,
- /*0x1f66*/ 734,
- /*0x0579*/ 463,
- -1, -1,
- /*0x2cee*/ 907,
- -1, -1,
- /*0x118dc*/ 1228,
- /*0xff4e*/ 1060,
- -1,
- /*0x217b*/ 769,
- /*0x10ce2*/ 1183,
- -1,
- /*0x057d*/ 467,
- -1,
- /*0x1f7a*/ 746,
- -1,
- /*0x2c5c*/ 845,
- -1,
- /*0x03b6*/ 250,
- -1,
- /*0x2179*/ 767,
- -1,
- /*0x0519*/ 427,
- /*0x2c76*/ 855,
- /*0x118d6*/ 1222,
- /*0x03f8*/ 289,
- -1,
- /*0x01d0*/ 142,
- /*0xff4c*/ 1058,
- /*0xa793*/ 1033,
- -1, -1,
- /*0x217d*/ 771,
- /*0x01ff*/ 164,
- /*0x2c56*/ 839,
- -1, -1,
- /*0x0577*/ 461,
- /*0x03ca*/ 269,
- -1,
- /*0x0507*/ 418,
- /*0x2d19*/ 934,
- /*0x049f*/ 366,
- /*0x01ce*/ 141,
- /*0x118d4*/ 1220,
- -1,
- /*0x1e1f*/ 580,
- -1,
- /*0x011f*/ 71,
- /*0x021f*/ 180,
- /*0x2c9f*/ 871,
- -1, -1, -1,
- /*0x2c54*/ 837,
- /*0x13de*/ 539,
- /*0x045e*/ 337,
- /*0x2177*/ 765,
- -1,
- /*0x2d07*/ 916,
- /*0x104de*/ 1119,
- /*0x2c6a*/ 852,
- -1, -1,
- /*0x01cc*/ 140,
- /*0x057f*/ 469,
- -1,
- /*0xff48*/ 1054,
- -1,
- /*0xa695*/ 982,
- /*0x24de*/ 789,
- -1, -1,
- /*0xa799*/ 1035,
- -1,
- /*0x10cee*/ 1195,
- -1, -1,
- /*0x0517*/ 426,
- /*0xff58*/ 1070,
- /*0x2c36*/ 807,
- -1, -1, -1, -1,
- /*0x217f*/ 773,
- -1, -1,
- /*0x1f70*/ 736,
- /*0xa693*/ 981,
- /*0x118ca*/ 1210,
- /*0xa787*/ 1030,
- -1, -1, -1,
- /*0x214e*/ 757,
- -1,
- /*0x2d17*/ 932,
- -1, -1,
- /*0x2c4a*/ 827,
- /*0x13be*/ 507,
- /*0x043e*/ 305,
- -1,
- /*0x0566*/ 444,
- /*0x1043e*/ 1095,
- /*0x1f76*/ 742,
- -1, -1,
- /*0x013e*/ 85,
- -1, -1,
- /*0x118d2*/ 1218,
- /*0x13ba*/ 503,
- /*0x043a*/ 301,
- /*0x01d8*/ 146,
- -1,
- /*0x1043a*/ 1091,
- -1,
- /*0x057a*/ 464,
- /*0x1f60*/ 728,
- /*0x013a*/ 83,
- /*0x2c52*/ 835,
- -1, -1,
- /*0x03b4*/ 248,
- -1, -1, -1,
- /*0xa797*/ 1034,
- -1, -1, -1,
- /*0xa699*/ 984,
- -1, -1, -1,
- /*0x10cde*/ 1179,
- -1,
- /*0x217a*/ 768,
- /*0x2c30*/ 801,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0x056c*/ 450,
- /*0xa687*/ 975,
- -1, -1,
- /*0xff56*/ 1068,
- /*0x0289*/ 228,
- -1,
- /*0x1f64*/ 732,
- -1, -1, -1,
- /*0x051d*/ 429,
- -1,
- /*0x1f36*/ 716,
- -1, -1, -1, -1, -1, -1,
- /*0x1f78*/ 744,
- -1,
- /*0x01dc*/ 148,
- -1,
- /*0xff54*/ 1066,
- -1,
- /*0x00f1*/ 42,
- -1, -1, -1,
- /*0x2d1d*/ 938,
- -1,
- /*0x0568*/ 446,
- -1, -1, -1,
- /*0x00f5*/ 46,
- /*0x2c34*/ 805,
- -1,
- /*0xa697*/ 983,
- /*0x01d6*/ 145,
- -1, -1,
- /*0x0570*/ 454,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x1f74*/ 740,
- -1, -1,
- /*0x00fc*/ 52,
- -1, -1,
- /*0x01d4*/ 144,
- /*0x0576*/ 460,
- /*0xa79d*/ 1037,
- /*0x2170*/ 758,
- -1, -1, -1, -1, -1, -1,
- /*0xff4a*/ 1056,
- -1, -1,
- /*0x1f30*/ 710,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x2176*/ 764,
- -1,
- /*0x1f62*/ 730,
- -1, -1,
- /*0x01b6*/ 134,
- -1, -1, -1, -1, -1,
- /*0xff52*/ 1064,
- -1, -1, -1, -1, -1, -1,
- /*0x056a*/ 448,
- -1, -1, -1, -1, -1,
- /*0x1fd0*/ 752,
- -1, -1, -1, -1, -1,
- /*0x03be*/ 258,
- /*0x0564*/ 442,
- -1, -1, -1, -1,
- /*0x118de*/ 1230,
- -1, -1,
- /*0x1f34*/ 714,
- -1, -1,
- /*0x03ba*/ 254,
- -1,
- /*0x0578*/ 462,
- -1,
- /*0x2c5e*/ 847,
- /*0x01d2*/ 143,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x2178*/ 766,
- /*0x01b0*/ 132,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x1e936*/ 1252,
- -1, -1, -1,
- /*0x0574*/ 458,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x2c3e*/ 815,
- -1, -1, -1, -1, -1,
- /*0x2174*/ 762,
- -1, -1, -1, -1, -1,
- /*0x2c3a*/ 811,
- -1,
- /*0x00f2*/ 43,
- /*0x0562*/ 440,
- -1, -1, -1, -1,
- /*0x01b4*/ 133,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x050d*/ 421,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x1e930*/ 1246,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x2d0d*/ 922,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0x00fb*/ 51,
- -1,
- /*0x0509*/ 419,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x00f9*/ 49,
- -1, -1, -1, -1, -1, -1,
- /*0x056e*/ 452,
- -1, -1,
- /*0x2d09*/ 918,
- -1,
- /*0x00fd*/ 53,
- -1, -1, -1,
- /*0x1e934*/ 1250,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x1fe0*/ 754,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x051f*/ 430,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x00ff*/ 55,
- -1, -1, -1,
- /*0xa68d*/ 978,
- -1, -1, -1,
- /*0x2d1f*/ 940,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0xa689*/ 976,
- -1,
- /*0x00e6*/ 31,
- /*0xa79f*/ 1038,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x00fa*/ 50,
- -1, -1, -1, -1, -1, -1,
- -1, -1,
- /*0x1fb0*/ 750,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0x00ec*/ 37,
- -1,
- /*0x1e93e*/ 1260,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0x1e93a*/ 1256,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0x00e8*/ 33,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x00f0*/ 41,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0x00f6*/ 47,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1,
- /*0x00e0*/ 25,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0x00ea*/ 35,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- /*0x00e4*/ 29,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- /*0x00f8*/ 48,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0x00f4*/ 45,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x00e2*/ 27,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
- /*0x00ee*/ 39
- };
-
- if (code <= MAX_CODE_VALUE && code >= MIN_CODE_VALUE)
- {
- register int key = onigenc_unicode_CaseUnfold_11_hash(code);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register short s = wordlist[key];
-
- if (s >= 0 && code1_equal(code, CaseUnfold_11_Table[s].from))
- return &CaseUnfold_11_Table[s].to;
- }
- }
- return 0;
-}
-
-static const CaseUnfold_12_Type CaseUnfold_12_Table[] = {
-#define CaseUnfold_12 (*(CaseUnfold_12_Type (*)[58])(CaseUnfold_12_Table+0))
- {{0x0061, 0x02be}, {1, {0x1e9a}}},
- {{0x0066, 0x0066}, {1, {0xfb00}}},
- {{0x0066, 0x0069}, {1, {0xfb01}}},
- {{0x0066, 0x006c}, {1, {0xfb02}}},
- {{0x0068, 0x0331}, {1, {0x1e96}}},
- {{0x006a, 0x030c}, {1, {0x01f0}}},
- {{0x0073, 0x0073}, {2, {0x00df, 0x1e9e}}},
- {{0x0073, 0x0074}, {2, {0xfb05, 0xfb06}}},
- {{0x0074, 0x0308}, {1, {0x1e97}}},
- {{0x0077, 0x030a}, {1, {0x1e98}}},
- {{0x0079, 0x030a}, {1, {0x1e99}}},
- {{0x02bc, 0x006e}, {1, {0x0149}}},
- {{0x03ac, 0x03b9}, {1, {0x1fb4}}},
- {{0x03ae, 0x03b9}, {1, {0x1fc4}}},
- {{0x03b1, 0x0342}, {1, {0x1fb6}}},
- {{0x03b1, 0x03b9}, {2, {0x1fb3, 0x1fbc}}},
- {{0x03b7, 0x0342}, {1, {0x1fc6}}},
- {{0x03b7, 0x03b9}, {2, {0x1fc3, 0x1fcc}}},
- {{0x03b9, 0x0342}, {1, {0x1fd6}}},
- {{0x03c1, 0x0313}, {1, {0x1fe4}}},
- {{0x03c5, 0x0313}, {1, {0x1f50}}},
- {{0x03c5, 0x0342}, {1, {0x1fe6}}},
- {{0x03c9, 0x0342}, {1, {0x1ff6}}},
- {{0x03c9, 0x03b9}, {2, {0x1ff3, 0x1ffc}}},
- {{0x03ce, 0x03b9}, {1, {0x1ff4}}},
- {{0x0565, 0x0582}, {1, {0x0587}}},
- {{0x0574, 0x0565}, {1, {0xfb14}}},
- {{0x0574, 0x056b}, {1, {0xfb15}}},
- {{0x0574, 0x056d}, {1, {0xfb17}}},
- {{0x0574, 0x0576}, {1, {0xfb13}}},
- {{0x057e, 0x0576}, {1, {0xfb16}}},
- {{0x1f00, 0x03b9}, {2, {0x1f80, 0x1f88}}},
- {{0x1f01, 0x03b9}, {2, {0x1f81, 0x1f89}}},
- {{0x1f02, 0x03b9}, {2, {0x1f82, 0x1f8a}}},
- {{0x1f03, 0x03b9}, {2, {0x1f83, 0x1f8b}}},
- {{0x1f04, 0x03b9}, {2, {0x1f84, 0x1f8c}}},
- {{0x1f05, 0x03b9}, {2, {0x1f85, 0x1f8d}}},
- {{0x1f06, 0x03b9}, {2, {0x1f86, 0x1f8e}}},
- {{0x1f07, 0x03b9}, {2, {0x1f87, 0x1f8f}}},
- {{0x1f20, 0x03b9}, {2, {0x1f90, 0x1f98}}},
- {{0x1f21, 0x03b9}, {2, {0x1f91, 0x1f99}}},
- {{0x1f22, 0x03b9}, {2, {0x1f92, 0x1f9a}}},
- {{0x1f23, 0x03b9}, {2, {0x1f93, 0x1f9b}}},
- {{0x1f24, 0x03b9}, {2, {0x1f94, 0x1f9c}}},
- {{0x1f25, 0x03b9}, {2, {0x1f95, 0x1f9d}}},
- {{0x1f26, 0x03b9}, {2, {0x1f96, 0x1f9e}}},
- {{0x1f27, 0x03b9}, {2, {0x1f97, 0x1f9f}}},
- {{0x1f60, 0x03b9}, {2, {0x1fa0, 0x1fa8}}},
- {{0x1f61, 0x03b9}, {2, {0x1fa1, 0x1fa9}}},
- {{0x1f62, 0x03b9}, {2, {0x1fa2, 0x1faa}}},
- {{0x1f63, 0x03b9}, {2, {0x1fa3, 0x1fab}}},
- {{0x1f64, 0x03b9}, {2, {0x1fa4, 0x1fac}}},
- {{0x1f65, 0x03b9}, {2, {0x1fa5, 0x1fad}}},
- {{0x1f66, 0x03b9}, {2, {0x1fa6, 0x1fae}}},
- {{0x1f67, 0x03b9}, {2, {0x1fa7, 0x1faf}}},
- {{0x1f70, 0x03b9}, {1, {0x1fb2}}},
- {{0x1f74, 0x03b9}, {1, {0x1fc2}}},
- {{0x1f7c, 0x03b9}, {1, {0x1ff2}}},
-#define CaseUnfold_12_Locale (*(CaseUnfold_12_Type (*)[1])(CaseUnfold_12_Table+58))
- {{0x0069, 0x0307}, {1, {0x0130}}},
-};
-
-/* C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -7 -k1,2,3,4,5,6 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_12_hash -N onigenc_unicode_CaseUnfold_12_lookup -n */
-
-/* maximum key range = 71, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-/*ARGSUSED*/
-static unsigned int
-onigenc_unicode_CaseUnfold_12_hash(const OnigCodePoint *codes)
-{
- static const unsigned char asso_values[] =
- {
- 3, 58, 54, 57, 56, 16, 8, 2, 43, 82,
- 3, 1, 23, 82, 82, 82, 82, 82, 82, 4,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 52, 51, 50, 49, 48, 47, 46, 45,
- 82, 82, 82, 82, 43, 82, 42, 82, 82, 13,
- 82, 82, 82, 82, 82, 11, 82, 1, 82, 82,
- 14, 82, 1, 82, 82, 31, 3, 82, 82, 30,
- 82, 82, 82, 10, 82, 82, 82, 82, 37, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 37, 15, 36, 35,
- 34, 17, 1, 33, 12, 4, 23, 23, 26, 21,
- 13, 82, 27, 82, 82, 2, 5, 82, 11, 16,
- 82, 15, 82, 82, 23, 82, 8, 82
- };
- return asso_values[bits_at(codes, 5)] + asso_values[bits_at(codes, 4)] + asso_values[bits_at(codes, 3)] + asso_values[bits_at(codes, 2)] + asso_values[bits_at(codes, 1)] + asso_values[bits_at(codes, 0)];
-}
-
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-static const CodePointList2 *
-onigenc_unicode_CaseUnfold_12_lookup(const OnigCodePoint *codes)
-{
- enum
- {
- MIN_CODE_VALUE = 0x61,
- MAX_CODE_VALUE = 0x1f7c,
- TOTAL_KEYWORDS = 59,
- MIN_WORD_LENGTH = 6,
- MAX_WORD_LENGTH = 6,
- MIN_HASH_VALUE = 11,
- MAX_HASH_VALUE = 81
- };
-
- static const short wordlist[] =
- {
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1,
- /*0x1f66,0x03b9*/ 53,
- /*0x1f07,0x03b9*/ 38,
- /*0x1f00,0x03b9*/ 31,
- /*0x0066,0x0066*/ 1,
- /*0x1f74,0x03b9*/ 56,
- /*0x0073,0x0073*/ 6,
- /*0x0066,0x0069*/ 2,
- /*0x1f06,0x03b9*/ 37,
- /*0x0073,0x0074*/ 7,
- /*0x03b9,0x0342*/ 18,
- /*0x03c9,0x03b9*/ 23,
- /*0x03b7,0x03b9*/ 17,
- /*0x0069,0x0307*/ 58,
- /*0x03b1,0x03b9*/ 15,
- /*0x1f61,0x03b9*/ 48,
- /*0x1f05,0x03b9*/ 36,
- /*0x1f65,0x03b9*/ 52,
- /*0x0574,0x0576*/ 29,
- /*0x03c9,0x0342*/ 22,
- /*0x03b7,0x0342*/ 16,
- /*0x057e,0x0576*/ 30,
- /*0x03b1,0x0342*/ 14,
- /*0x1f7c,0x03b9*/ 57,
- /*0x0574,0x0565*/ 26,
- /*0x0079,0x030a*/ 10,
- /*0x0077,0x030a*/ 9,
- /*0x1f70,0x03b9*/ 55,
- /*0x0574,0x056d*/ 28,
- /*0x0066,0x006c*/ 3,
- /*0x0574,0x056b*/ 27,
- /*0x0061,0x02be*/ 0,
- /*0x0068,0x0331*/ 4,
- /*0x1f67,0x03b9*/ 54,
- /*0x1f64,0x03b9*/ 51,
- /*0x1f63,0x03b9*/ 50,
- /*0x1f62,0x03b9*/ 49,
- /*0x1f60,0x03b9*/ 47,
- /*0x03ce,0x03b9*/ 24,
- /*0x03c5,0x0342*/ 21,
- /*0x03c5,0x0313*/ 20,
- /*0x03c1,0x0313*/ 19,
- /*0x02bc,0x006e*/ 11,
- /*0x03ae,0x03b9*/ 13,
- /*0x03ac,0x03b9*/ 12,
- /*0x1f27,0x03b9*/ 46,
- /*0x1f26,0x03b9*/ 45,
- /*0x1f25,0x03b9*/ 44,
- /*0x1f24,0x03b9*/ 43,
- /*0x1f23,0x03b9*/ 42,
- /*0x1f22,0x03b9*/ 41,
- /*0x1f21,0x03b9*/ 40,
- /*0x1f20,0x03b9*/ 39,
- /*0x006a,0x030c*/ 5,
- /*0x1f02,0x03b9*/ 33,
- /*0x0074,0x0308*/ 8,
- /*0x1f04,0x03b9*/ 35,
- /*0x1f03,0x03b9*/ 34,
- /*0x1f01,0x03b9*/ 32,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- /*0x0565,0x0582*/ 25
- };
-
- if (codes[0] <= MAX_CODE_VALUE && codes[0] >= MIN_CODE_VALUE &&
- codes[1] <= MAX_CODE_VALUE && codes[1] >= MIN_CODE_VALUE)
- {
- register int key = onigenc_unicode_CaseUnfold_12_hash(codes);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register short s = wordlist[key];
-
- if (s >= 0 && code2_equal(codes, CaseUnfold_12_Table[s].from))
- return &CaseUnfold_12_Table[s].to;
- }
- }
- return 0;
-}
-
-static const CaseUnfold_13_Type CaseUnfold_13_Table[] = {
-#define CaseUnfold_13 (*(CaseUnfold_13_Type (*)[14])(CaseUnfold_13_Table+0))
- {{0x0066, 0x0066, 0x0069}, {1, {0xfb03}}},
- {{0x0066, 0x0066, 0x006c}, {1, {0xfb04}}},
- {{0x03b1, 0x0342, 0x03b9}, {1, {0x1fb7}}},
- {{0x03b7, 0x0342, 0x03b9}, {1, {0x1fc7}}},
- {{0x03b9, 0x0308, 0x0300}, {1, {0x1fd2}}},
- {{0x03b9, 0x0308, 0x0301}, {2, {0x0390, 0x1fd3}}},
- {{0x03b9, 0x0308, 0x0342}, {1, {0x1fd7}}},
- {{0x03c5, 0x0308, 0x0300}, {1, {0x1fe2}}},
- {{0x03c5, 0x0308, 0x0301}, {2, {0x03b0, 0x1fe3}}},
- {{0x03c5, 0x0308, 0x0342}, {1, {0x1fe7}}},
- {{0x03c5, 0x0313, 0x0300}, {1, {0x1f52}}},
- {{0x03c5, 0x0313, 0x0301}, {1, {0x1f54}}},
- {{0x03c5, 0x0313, 0x0342}, {1, {0x1f56}}},
- {{0x03c9, 0x0342, 0x03b9}, {1, {0x1ff7}}},
-};
-
-/* C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -7 -k1,2,3,4,5,6,7,8,9 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_13_hash -N onigenc_unicode_CaseUnfold_13_lookup -n */
-
-/* maximum key range = 20, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-/*ARGSUSED*/
-static unsigned int
-onigenc_unicode_CaseUnfold_13_hash(const OnigCodePoint *codes)
-{
- static const unsigned char asso_values[] =
- {
- 7, 4, 47, 47, 47, 47, 1, 1, 2, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 1,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 11,
- 47, 47, 47, 47, 47, 10, 47, 2, 47, 47,
- 47, 47, 47, 47, 47, 47, 1, 47, 47, 1,
- 47, 47, 47, 9, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 1, 47, 47, 2, 47, 47, 1, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47
- };
- return asso_values[bits_at(codes, 8)] + asso_values[bits_at(codes, 7)] + asso_values[bits_at(codes, 6)] + asso_values[bits_at(codes, 5)] + asso_values[bits_at(codes, 4)] + asso_values[bits_at(codes, 3)] + asso_values[bits_at(codes, 2)] + asso_values[bits_at(codes, 1)] + asso_values[bits_at(codes, 0)];
-}
-
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-static const CodePointList2 *
-onigenc_unicode_CaseUnfold_13_lookup(const OnigCodePoint *codes)
-{
- enum
- {
- MIN_CODE_VALUE = 0x66,
- MAX_CODE_VALUE = 0x3c9,
- TOTAL_KEYWORDS = 14,
- MIN_WORD_LENGTH = 9,
- MAX_WORD_LENGTH = 9,
- MIN_HASH_VALUE = 27,
- MAX_HASH_VALUE = 46
- };
-
- static const short wordlist[] =
- {
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1,
- /*0x03c5,0x0313,0x0342*/ 12,
- /*0x03c5,0x0308,0x0342*/ 9,
- /*0x03b9,0x0308,0x0342*/ 6,
- /*0x03c5,0x0313,0x0301*/ 11,
- /*0x03c5,0x0308,0x0301*/ 8,
- /*0x03b9,0x0308,0x0301*/ 5,
- /*0x03c5,0x0313,0x0300*/ 10,
- /*0x03c5,0x0308,0x0300*/ 7,
- /*0x03b9,0x0308,0x0300*/ 4,
- /*0x03c9,0x0342,0x03b9*/ 13,
- /*0x03b7,0x0342,0x03b9*/ 3,
- /*0x03b1,0x0342,0x03b9*/ 2,
- -1, -1, -1, -1, -1, -1,
- /*0x0066,0x0066,0x006c*/ 1,
- /*0x0066,0x0066,0x0069*/ 0
- };
-
- if (codes[0] <= MAX_CODE_VALUE && codes[0] >= MIN_CODE_VALUE &&
- codes[1] <= MAX_CODE_VALUE && codes[1] >= MIN_CODE_VALUE &&
- codes[2] <= MAX_CODE_VALUE && codes[2] >= MIN_CODE_VALUE)
- {
- register int key = onigenc_unicode_CaseUnfold_13_hash(codes);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register short s = wordlist[key];
-
- if (s >= 0 && code3_equal(codes, CaseUnfold_13_Table[s].from))
- return &CaseUnfold_13_Table[s].to;
- }
- }
- return 0;
-}
-
-static const OnigCodePoint CaseMappingSpecials[] = {
- L(1)|0x039C,
- L(2)|0x0053, 0x0073, L(2)|0x0053, 0x0053,
- L(2)|0x02BC, 0x004E,
- L(1)|0x0053,
- L(1)|0x01C5,
- L(2)|0x0064, 0x017D, L(1)|0x01C4,
- L(1)|0x01C8,
- L(2)|0x006C, 0x004A, L(1)|0x01C7,
- L(1)|0x01CB,
- L(2)|0x006E, 0x004A, L(1)|0x01CA,
- L(2)|0x004A, 0x030C,
- L(1)|0x01F2,
- L(2)|0x0064, 0x005A, L(1)|0x01F1,
- L(1)|0x0399,
- L(3)|0x0399, 0x0308, 0x0301,
- L(3)|0x03A5, 0x0308, 0x0301,
- L(1)|0x03A3,
- L(1)|0x0392,
- L(1)|0x0398,
- L(1)|0x03A6,
- L(1)|0x03A0,
- L(1)|0x039A,
- L(1)|0x03A1,
- L(1)|0x0395,
- L(2)|0x0535, 0x0582, L(2)|0x0535, 0x0552,
- L(1)|0x0412,
- L(1)|0x0414,
- L(1)|0x041E,
- L(1)|0x0421,
- L(1)|0x0422,
- L(1)|0x0422,
- L(1)|0x042A,
- L(1)|0x0462,
- L(1)|0xA64A,
- L(2)|0x0048, 0x0331,
- L(2)|0x0054, 0x0308,
- L(2)|0x0057, 0x030A,
- L(2)|0x0059, 0x030A,
- L(2)|0x0041, 0x02BE,
- L(1)|0x1E60,
- L(1)|0x00DF,
- L(2)|0x03A5, 0x0313,
- L(3)|0x03A5, 0x0313, 0x0300,
- L(3)|0x03A5, 0x0313, 0x0301,
- L(3)|0x03A5, 0x0313, 0x0342,
- L(1)|0x1F88, L(2)|0x1F08, 0x0399,
- L(1)|0x1F89, L(2)|0x1F09, 0x0399,
- L(1)|0x1F8A, L(2)|0x1F0A, 0x0399,
- L(1)|0x1F8B, L(2)|0x1F0B, 0x0399,
- L(1)|0x1F8C, L(2)|0x1F0C, 0x0399,
- L(1)|0x1F8D, L(2)|0x1F0D, 0x0399,
- L(1)|0x1F8E, L(2)|0x1F0E, 0x0399,
- L(1)|0x1F8F, L(2)|0x1F0F, 0x0399,
- L(2)|0x1F00, 0x0399, L(1)|0x1F80, L(2)|0x1F08, 0x0399,
- L(2)|0x1F01, 0x0399, L(1)|0x1F81, L(2)|0x1F09, 0x0399,
- L(2)|0x1F02, 0x0399, L(1)|0x1F82, L(2)|0x1F0A, 0x0399,
- L(2)|0x1F03, 0x0399, L(1)|0x1F83, L(2)|0x1F0B, 0x0399,
- L(2)|0x1F04, 0x0399, L(1)|0x1F84, L(2)|0x1F0C, 0x0399,
- L(2)|0x1F05, 0x0399, L(1)|0x1F85, L(2)|0x1F0D, 0x0399,
- L(2)|0x1F06, 0x0399, L(1)|0x1F86, L(2)|0x1F0E, 0x0399,
- L(2)|0x1F07, 0x0399, L(1)|0x1F87, L(2)|0x1F0F, 0x0399,
- L(1)|0x1F98, L(2)|0x1F28, 0x0399,
- L(1)|0x1F99, L(2)|0x1F29, 0x0399,
- L(1)|0x1F9A, L(2)|0x1F2A, 0x0399,
- L(1)|0x1F9B, L(2)|0x1F2B, 0x0399,
- L(1)|0x1F9C, L(2)|0x1F2C, 0x0399,
- L(1)|0x1F9D, L(2)|0x1F2D, 0x0399,
- L(1)|0x1F9E, L(2)|0x1F2E, 0x0399,
- L(1)|0x1F9F, L(2)|0x1F2F, 0x0399,
- L(2)|0x1F20, 0x0399, L(1)|0x1F90, L(2)|0x1F28, 0x0399,
- L(2)|0x1F21, 0x0399, L(1)|0x1F91, L(2)|0x1F29, 0x0399,
- L(2)|0x1F22, 0x0399, L(1)|0x1F92, L(2)|0x1F2A, 0x0399,
- L(2)|0x1F23, 0x0399, L(1)|0x1F93, L(2)|0x1F2B, 0x0399,
- L(2)|0x1F24, 0x0399, L(1)|0x1F94, L(2)|0x1F2C, 0x0399,
- L(2)|0x1F25, 0x0399, L(1)|0x1F95, L(2)|0x1F2D, 0x0399,
- L(2)|0x1F26, 0x0399, L(1)|0x1F96, L(2)|0x1F2E, 0x0399,
- L(2)|0x1F27, 0x0399, L(1)|0x1F97, L(2)|0x1F2F, 0x0399,
- L(1)|0x1FA8, L(2)|0x1F68, 0x0399,
- L(1)|0x1FA9, L(2)|0x1F69, 0x0399,
- L(1)|0x1FAA, L(2)|0x1F6A, 0x0399,
- L(1)|0x1FAB, L(2)|0x1F6B, 0x0399,
- L(1)|0x1FAC, L(2)|0x1F6C, 0x0399,
- L(1)|0x1FAD, L(2)|0x1F6D, 0x0399,
- L(1)|0x1FAE, L(2)|0x1F6E, 0x0399,
- L(1)|0x1FAF, L(2)|0x1F6F, 0x0399,
- L(2)|0x1F60, 0x0399, L(1)|0x1FA0, L(2)|0x1F68, 0x0399,
- L(2)|0x1F61, 0x0399, L(1)|0x1FA1, L(2)|0x1F69, 0x0399,
- L(2)|0x1F62, 0x0399, L(1)|0x1FA2, L(2)|0x1F6A, 0x0399,
- L(2)|0x1F63, 0x0399, L(1)|0x1FA3, L(2)|0x1F6B, 0x0399,
- L(2)|0x1F64, 0x0399, L(1)|0x1FA4, L(2)|0x1F6C, 0x0399,
- L(2)|0x1F65, 0x0399, L(1)|0x1FA5, L(2)|0x1F6D, 0x0399,
- L(2)|0x1F66, 0x0399, L(1)|0x1FA6, L(2)|0x1F6E, 0x0399,
- L(2)|0x1F67, 0x0399, L(1)|0x1FA7, L(2)|0x1F6F, 0x0399,
- L(2)|0x1FBA, 0x0345, L(2)|0x1FBA, 0x0399,
- L(1)|0x1FBC, L(2)|0x0391, 0x0399,
- L(2)|0x0386, 0x0345, L(2)|0x0386, 0x0399,
- L(2)|0x0391, 0x0342,
- L(3)|0x0391, 0x0342, 0x0345, L(3)|0x0391, 0x0342, 0x0399,
- L(2)|0x03B1, 0x0399, L(1)|0x1FB3, L(2)|0x0391, 0x0399,
- L(1)|0x0399,
- L(2)|0x1FCA, 0x0345, L(2)|0x1FCA, 0x0399,
- L(1)|0x1FCC, L(2)|0x0397, 0x0399,
- L(2)|0x0389, 0x0345, L(2)|0x0389, 0x0399,
- L(2)|0x0397, 0x0342,
- L(3)|0x0397, 0x0342, 0x0345, L(3)|0x0397, 0x0342, 0x0399,
- L(2)|0x03B7, 0x0399, L(1)|0x1FC3, L(2)|0x0397, 0x0399,
- L(3)|0x0399, 0x0308, 0x0300,
- L(3)|0x0399, 0x0308, 0x0301,
- L(2)|0x0399, 0x0342,
- L(3)|0x0399, 0x0308, 0x0342,
- L(3)|0x03A5, 0x0308, 0x0300,
- L(3)|0x03A5, 0x0308, 0x0301,
- L(2)|0x03A1, 0x0313,
- L(2)|0x03A5, 0x0342,
- L(3)|0x03A5, 0x0308, 0x0342,
- L(2)|0x1FFA, 0x0345, L(2)|0x1FFA, 0x0399,
- L(1)|0x1FFC, L(2)|0x03A9, 0x0399,
- L(2)|0x038F, 0x0345, L(2)|0x038F, 0x0399,
- L(2)|0x03A9, 0x0342,
- L(3)|0x03A9, 0x0342, 0x0345, L(3)|0x03A9, 0x0342, 0x0399,
- L(2)|0x03C9, 0x0399, L(1)|0x1FF3, L(2)|0x03A9, 0x0399,
- L(2)|0x0046, 0x0066, L(2)|0x0046, 0x0046,
- L(2)|0x0046, 0x0069, L(2)|0x0046, 0x0049,
- L(2)|0x0046, 0x006C, L(2)|0x0046, 0x004C,
- L(3)|0x0046, 0x0066, 0x0069, L(3)|0x0046, 0x0046, 0x0049,
- L(3)|0x0046, 0x0066, 0x006C, L(3)|0x0046, 0x0046, 0x004C,
- L(2)|0x0053, 0x0074, L(2)|0x0053, 0x0054,
- L(2)|0x0053, 0x0074, L(2)|0x0053, 0x0054,
- L(2)|0x0544, 0x0576, L(2)|0x0544, 0x0546,
- L(2)|0x0544, 0x0565, L(2)|0x0544, 0x0535,
- L(2)|0x0544, 0x056B, L(2)|0x0544, 0x053B,
- L(2)|0x054E, 0x0576, L(2)|0x054E, 0x0546,
- L(2)|0x0544, 0x056D, L(2)|0x0544, 0x053D,
-};
diff --git a/enc/unicode/10.0.0/name2ctype.h b/enc/unicode/10.0.0/name2ctype.h
deleted file mode 100644
index 94b7c83f6e..0000000000
--- a/enc/unicode/10.0.0/name2ctype.h
+++ /dev/null
@@ -1,38087 +0,0 @@
-/* C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -7 -c -j1 -i1 -t -C -P -T -H uniname2ctype_hash -Q uniname2ctype_pool -N uniname2ctype_p */
-#ifndef USE_UNICODE_PROPERTIES
-/* Computed positions: -k'1,3' */
-#else /* USE_UNICODE_PROPERTIES */
-/* Computed positions: -k'1-3,5-6,12,16,$' */
-#endif /* USE_UNICODE_PROPERTIES */
-
-#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
- && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
- && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
- && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
- && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
- && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
- && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
- && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
- && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
- && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
- && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
- && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
- && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
- && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
- && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
- && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
- && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
- && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
- && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
- && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
- && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
- && ('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>."
-#endif
-
-
-
-/* 'NEWLINE': [[:NEWLINE:]] */
-static const OnigCodePoint CR_NEWLINE[] = {
- 1,
- 0x000a, 0x000a,
-}; /* CR_NEWLINE */
-
-/* 'Alpha': [[:Alpha:]] */
-static const OnigCodePoint CR_Alpha[] = {
- 660,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0345, 0x0345,
- 0x0370, 0x0374,
- 0x0376, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x05b0, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x061a,
- 0x0620, 0x0657,
- 0x0659, 0x065f,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06e1, 0x06e8,
- 0x06ed, 0x06ef,
- 0x06fa, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x073f,
- 0x074d, 0x07b1,
- 0x07ca, 0x07ea,
- 0x07f4, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x0817,
- 0x081a, 0x082c,
- 0x0840, 0x0858,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x08df,
- 0x08e3, 0x08e9,
- 0x08f0, 0x093b,
- 0x093d, 0x094c,
- 0x094e, 0x0950,
- 0x0955, 0x0963,
- 0x0971, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bd, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cc,
- 0x09ce, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09f0, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4c,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a70, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abd, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acc,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0af9, 0x0afc,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3d, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4c,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcc,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4c,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c80, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbd, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccc,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4c,
- 0x0d4e, 0x0d4e,
- 0x0d54, 0x0d57,
- 0x0d5f, 0x0d63,
- 0x0d7a, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e46,
- 0x0e4d, 0x0e4d,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ecd, 0x0ecd,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f40, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f81,
- 0x0f88, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x1000, 0x1036,
- 0x1038, 0x1038,
- 0x103b, 0x103f,
- 0x1050, 0x1062,
- 0x1065, 0x1068,
- 0x106e, 0x1086,
- 0x108e, 0x108e,
- 0x109c, 0x109d,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135f, 0x135f,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1713,
- 0x1720, 0x1733,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17b3,
- 0x17b6, 0x17c8,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dc,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x1938,
- 0x1950, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x1a00, 0x1a1b,
- 0x1a20, 0x1a5e,
- 0x1a61, 0x1a74,
- 0x1aa7, 0x1aa7,
- 0x1b00, 0x1b33,
- 0x1b35, 0x1b43,
- 0x1b45, 0x1b4b,
- 0x1b80, 0x1ba9,
- 0x1bac, 0x1baf,
- 0x1bba, 0x1be5,
- 0x1be7, 0x1bf1,
- 0x1c00, 0x1c35,
- 0x1c4d, 0x1c4f,
- 0x1c5a, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf3,
- 0x1cf5, 0x1cf6,
- 0x1d00, 0x1dbf,
- 0x1de7, 0x1df4,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x24b6, 0x24e9,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2dff,
- 0x2e2f, 0x2e2f,
- 0x3005, 0x3007,
- 0x3021, 0x3029,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa61f,
- 0xa62a, 0xa62b,
- 0xa640, 0xa66e,
- 0xa674, 0xa67b,
- 0xa67f, 0xa6ef,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa801,
- 0xa803, 0xa805,
- 0xa807, 0xa80a,
- 0xa80c, 0xa827,
- 0xa840, 0xa873,
- 0xa880, 0xa8c3,
- 0xa8c5, 0xa8c5,
- 0xa8f2, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa90a, 0xa92a,
- 0xa930, 0xa952,
- 0xa960, 0xa97c,
- 0xa980, 0xa9b2,
- 0xa9b4, 0xa9bf,
- 0xa9cf, 0xa9cf,
- 0xa9e0, 0xa9e4,
- 0xa9e6, 0xa9ef,
- 0xa9fa, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaa7a,
- 0xaa7e, 0xaabe,
- 0xaac0, 0xaac0,
- 0xaac2, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaef,
- 0xaaf2, 0xaaf5,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabea,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10140, 0x10174,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031f,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x103d1, 0x103d5,
- 0x10400, 0x1049d,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae4,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11000, 0x11045,
- 0x11082, 0x110b8,
- 0x110d0, 0x110e8,
- 0x11100, 0x11132,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11180, 0x111bf,
- 0x111c1, 0x111c4,
- 0x111da, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x11234,
- 0x11237, 0x11237,
- 0x1123e, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112e8,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133d, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134c,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11400, 0x11441,
- 0x11443, 0x11445,
- 0x11447, 0x1144a,
- 0x11480, 0x114c1,
- 0x114c4, 0x114c5,
- 0x114c7, 0x114c7,
- 0x11580, 0x115b5,
- 0x115b8, 0x115be,
- 0x115d8, 0x115dd,
- 0x11600, 0x1163e,
- 0x11640, 0x11640,
- 0x11644, 0x11644,
- 0x11680, 0x116b5,
- 0x11700, 0x11719,
- 0x1171d, 0x1172a,
- 0x118a0, 0x118df,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a32,
- 0x11a35, 0x11a3e,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a97,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c3e,
- 0x11c40, 0x11c40,
- 0x11c72, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d41,
- 0x11d43, 0x11d43,
- 0x11d46, 0x11d47,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16ad0, 0x16aed,
- 0x16b00, 0x16b36,
- 0x16b40, 0x16b43,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f93, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9e, 0x1bc9e,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e900, 0x1e943,
- 0x1e947, 0x1e947,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1f130, 0x1f149,
- 0x1f150, 0x1f169,
- 0x1f170, 0x1f189,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_Alpha */
-
-/* 'Blank': [[:Blank:]] */
-static const OnigCodePoint CR_Blank[] = {
- 8,
- 0x0009, 0x0009,
- 0x0020, 0x0020,
- 0x00a0, 0x00a0,
- 0x1680, 0x1680,
- 0x2000, 0x200a,
- 0x202f, 0x202f,
- 0x205f, 0x205f,
- 0x3000, 0x3000,
-}; /* CR_Blank */
-
-/* 'Cntrl': [[:Cntrl:]] */
-static const OnigCodePoint CR_Cntrl[] = {
- 2,
- 0x0000, 0x001f,
- 0x007f, 0x009f,
-}; /* CR_Cntrl */
-
-/* 'Digit': [[:Digit:]] */
-static const OnigCodePoint CR_Digit[] = {
- 55,
- 0x0030, 0x0039,
- 0x0660, 0x0669,
- 0x06f0, 0x06f9,
- 0x07c0, 0x07c9,
- 0x0966, 0x096f,
- 0x09e6, 0x09ef,
- 0x0a66, 0x0a6f,
- 0x0ae6, 0x0aef,
- 0x0b66, 0x0b6f,
- 0x0be6, 0x0bef,
- 0x0c66, 0x0c6f,
- 0x0ce6, 0x0cef,
- 0x0d66, 0x0d6f,
- 0x0de6, 0x0def,
- 0x0e50, 0x0e59,
- 0x0ed0, 0x0ed9,
- 0x0f20, 0x0f29,
- 0x1040, 0x1049,
- 0x1090, 0x1099,
- 0x17e0, 0x17e9,
- 0x1810, 0x1819,
- 0x1946, 0x194f,
- 0x19d0, 0x19d9,
- 0x1a80, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1b50, 0x1b59,
- 0x1bb0, 0x1bb9,
- 0x1c40, 0x1c49,
- 0x1c50, 0x1c59,
- 0xa620, 0xa629,
- 0xa8d0, 0xa8d9,
- 0xa900, 0xa909,
- 0xa9d0, 0xa9d9,
- 0xa9f0, 0xa9f9,
- 0xaa50, 0xaa59,
- 0xabf0, 0xabf9,
- 0xff10, 0xff19,
- 0x104a0, 0x104a9,
- 0x11066, 0x1106f,
- 0x110f0, 0x110f9,
- 0x11136, 0x1113f,
- 0x111d0, 0x111d9,
- 0x112f0, 0x112f9,
- 0x11450, 0x11459,
- 0x114d0, 0x114d9,
- 0x11650, 0x11659,
- 0x116c0, 0x116c9,
- 0x11730, 0x11739,
- 0x118e0, 0x118e9,
- 0x11c50, 0x11c59,
- 0x11d50, 0x11d59,
- 0x16a60, 0x16a69,
- 0x16b50, 0x16b59,
- 0x1d7ce, 0x1d7ff,
- 0x1e950, 0x1e959,
-}; /* CR_Digit */
-
-/* 'Graph': [[:Graph:]] */
-static const OnigCodePoint CR_Graph[] = {
- 654,
- 0x0021, 0x007e,
- 0x00a1, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fd,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4f,
- 0x0d54, 0x0d63,
- 0x0d66, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x167f,
- 0x1681, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c88,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf9,
- 0x1d00, 0x1df9,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x200b, 0x2027,
- 0x202a, 0x202e,
- 0x2030, 0x205e,
- 0x2060, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20bf,
- 0x20d0, 0x20f0,
- 0x2100, 0x218b,
- 0x2190, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e49,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3001, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fea,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa6f7,
- 0xa700, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c5,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fd,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab65,
- 0xab70, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xe000, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xfffd,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102fb,
- 0x10300, 0x10323,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11150, 0x11176,
- 0x11180, 0x111cd,
- 0x111d0, 0x111df,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x11459,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115dd,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
- 0x11660, 0x1166c,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x1173f,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a47,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c45,
- 0x11c50, 0x11c6c,
- 0x11c70, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1e8,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1da8b,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1e95e, 0x1e95f,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xf0000, 0xffffd,
- 0x100000, 0x10fffd,
-}; /* CR_Graph */
-
-/* 'Lower': [[:Lower:]] */
-static const OnigCodePoint CR_Lower[] = {
- 640,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00df, 0x00f6,
- 0x00f8, 0x00ff,
- 0x0101, 0x0101,
- 0x0103, 0x0103,
- 0x0105, 0x0105,
- 0x0107, 0x0107,
- 0x0109, 0x0109,
- 0x010b, 0x010b,
- 0x010d, 0x010d,
- 0x010f, 0x010f,
- 0x0111, 0x0111,
- 0x0113, 0x0113,
- 0x0115, 0x0115,
- 0x0117, 0x0117,
- 0x0119, 0x0119,
- 0x011b, 0x011b,
- 0x011d, 0x011d,
- 0x011f, 0x011f,
- 0x0121, 0x0121,
- 0x0123, 0x0123,
- 0x0125, 0x0125,
- 0x0127, 0x0127,
- 0x0129, 0x0129,
- 0x012b, 0x012b,
- 0x012d, 0x012d,
- 0x012f, 0x012f,
- 0x0131, 0x0131,
- 0x0133, 0x0133,
- 0x0135, 0x0135,
- 0x0137, 0x0138,
- 0x013a, 0x013a,
- 0x013c, 0x013c,
- 0x013e, 0x013e,
- 0x0140, 0x0140,
- 0x0142, 0x0142,
- 0x0144, 0x0144,
- 0x0146, 0x0146,
- 0x0148, 0x0149,
- 0x014b, 0x014b,
- 0x014d, 0x014d,
- 0x014f, 0x014f,
- 0x0151, 0x0151,
- 0x0153, 0x0153,
- 0x0155, 0x0155,
- 0x0157, 0x0157,
- 0x0159, 0x0159,
- 0x015b, 0x015b,
- 0x015d, 0x015d,
- 0x015f, 0x015f,
- 0x0161, 0x0161,
- 0x0163, 0x0163,
- 0x0165, 0x0165,
- 0x0167, 0x0167,
- 0x0169, 0x0169,
- 0x016b, 0x016b,
- 0x016d, 0x016d,
- 0x016f, 0x016f,
- 0x0171, 0x0171,
- 0x0173, 0x0173,
- 0x0175, 0x0175,
- 0x0177, 0x0177,
- 0x017a, 0x017a,
- 0x017c, 0x017c,
- 0x017e, 0x0180,
- 0x0183, 0x0183,
- 0x0185, 0x0185,
- 0x0188, 0x0188,
- 0x018c, 0x018d,
- 0x0192, 0x0192,
- 0x0195, 0x0195,
- 0x0199, 0x019b,
- 0x019e, 0x019e,
- 0x01a1, 0x01a1,
- 0x01a3, 0x01a3,
- 0x01a5, 0x01a5,
- 0x01a8, 0x01a8,
- 0x01aa, 0x01ab,
- 0x01ad, 0x01ad,
- 0x01b0, 0x01b0,
- 0x01b4, 0x01b4,
- 0x01b6, 0x01b6,
- 0x01b9, 0x01ba,
- 0x01bd, 0x01bf,
- 0x01c6, 0x01c6,
- 0x01c9, 0x01c9,
- 0x01cc, 0x01cc,
- 0x01ce, 0x01ce,
- 0x01d0, 0x01d0,
- 0x01d2, 0x01d2,
- 0x01d4, 0x01d4,
- 0x01d6, 0x01d6,
- 0x01d8, 0x01d8,
- 0x01da, 0x01da,
- 0x01dc, 0x01dd,
- 0x01df, 0x01df,
- 0x01e1, 0x01e1,
- 0x01e3, 0x01e3,
- 0x01e5, 0x01e5,
- 0x01e7, 0x01e7,
- 0x01e9, 0x01e9,
- 0x01eb, 0x01eb,
- 0x01ed, 0x01ed,
- 0x01ef, 0x01f0,
- 0x01f3, 0x01f3,
- 0x01f5, 0x01f5,
- 0x01f9, 0x01f9,
- 0x01fb, 0x01fb,
- 0x01fd, 0x01fd,
- 0x01ff, 0x01ff,
- 0x0201, 0x0201,
- 0x0203, 0x0203,
- 0x0205, 0x0205,
- 0x0207, 0x0207,
- 0x0209, 0x0209,
- 0x020b, 0x020b,
- 0x020d, 0x020d,
- 0x020f, 0x020f,
- 0x0211, 0x0211,
- 0x0213, 0x0213,
- 0x0215, 0x0215,
- 0x0217, 0x0217,
- 0x0219, 0x0219,
- 0x021b, 0x021b,
- 0x021d, 0x021d,
- 0x021f, 0x021f,
- 0x0221, 0x0221,
- 0x0223, 0x0223,
- 0x0225, 0x0225,
- 0x0227, 0x0227,
- 0x0229, 0x0229,
- 0x022b, 0x022b,
- 0x022d, 0x022d,
- 0x022f, 0x022f,
- 0x0231, 0x0231,
- 0x0233, 0x0239,
- 0x023c, 0x023c,
- 0x023f, 0x0240,
- 0x0242, 0x0242,
- 0x0247, 0x0247,
- 0x0249, 0x0249,
- 0x024b, 0x024b,
- 0x024d, 0x024d,
- 0x024f, 0x0293,
- 0x0295, 0x02b8,
- 0x02c0, 0x02c1,
- 0x02e0, 0x02e4,
- 0x0345, 0x0345,
- 0x0371, 0x0371,
- 0x0373, 0x0373,
- 0x0377, 0x0377,
- 0x037a, 0x037d,
- 0x0390, 0x0390,
- 0x03ac, 0x03ce,
- 0x03d0, 0x03d1,
- 0x03d5, 0x03d7,
- 0x03d9, 0x03d9,
- 0x03db, 0x03db,
- 0x03dd, 0x03dd,
- 0x03df, 0x03df,
- 0x03e1, 0x03e1,
- 0x03e3, 0x03e3,
- 0x03e5, 0x03e5,
- 0x03e7, 0x03e7,
- 0x03e9, 0x03e9,
- 0x03eb, 0x03eb,
- 0x03ed, 0x03ed,
- 0x03ef, 0x03f3,
- 0x03f5, 0x03f5,
- 0x03f8, 0x03f8,
- 0x03fb, 0x03fc,
- 0x0430, 0x045f,
- 0x0461, 0x0461,
- 0x0463, 0x0463,
- 0x0465, 0x0465,
- 0x0467, 0x0467,
- 0x0469, 0x0469,
- 0x046b, 0x046b,
- 0x046d, 0x046d,
- 0x046f, 0x046f,
- 0x0471, 0x0471,
- 0x0473, 0x0473,
- 0x0475, 0x0475,
- 0x0477, 0x0477,
- 0x0479, 0x0479,
- 0x047b, 0x047b,
- 0x047d, 0x047d,
- 0x047f, 0x047f,
- 0x0481, 0x0481,
- 0x048b, 0x048b,
- 0x048d, 0x048d,
- 0x048f, 0x048f,
- 0x0491, 0x0491,
- 0x0493, 0x0493,
- 0x0495, 0x0495,
- 0x0497, 0x0497,
- 0x0499, 0x0499,
- 0x049b, 0x049b,
- 0x049d, 0x049d,
- 0x049f, 0x049f,
- 0x04a1, 0x04a1,
- 0x04a3, 0x04a3,
- 0x04a5, 0x04a5,
- 0x04a7, 0x04a7,
- 0x04a9, 0x04a9,
- 0x04ab, 0x04ab,
- 0x04ad, 0x04ad,
- 0x04af, 0x04af,
- 0x04b1, 0x04b1,
- 0x04b3, 0x04b3,
- 0x04b5, 0x04b5,
- 0x04b7, 0x04b7,
- 0x04b9, 0x04b9,
- 0x04bb, 0x04bb,
- 0x04bd, 0x04bd,
- 0x04bf, 0x04bf,
- 0x04c2, 0x04c2,
- 0x04c4, 0x04c4,
- 0x04c6, 0x04c6,
- 0x04c8, 0x04c8,
- 0x04ca, 0x04ca,
- 0x04cc, 0x04cc,
- 0x04ce, 0x04cf,
- 0x04d1, 0x04d1,
- 0x04d3, 0x04d3,
- 0x04d5, 0x04d5,
- 0x04d7, 0x04d7,
- 0x04d9, 0x04d9,
- 0x04db, 0x04db,
- 0x04dd, 0x04dd,
- 0x04df, 0x04df,
- 0x04e1, 0x04e1,
- 0x04e3, 0x04e3,
- 0x04e5, 0x04e5,
- 0x04e7, 0x04e7,
- 0x04e9, 0x04e9,
- 0x04eb, 0x04eb,
- 0x04ed, 0x04ed,
- 0x04ef, 0x04ef,
- 0x04f1, 0x04f1,
- 0x04f3, 0x04f3,
- 0x04f5, 0x04f5,
- 0x04f7, 0x04f7,
- 0x04f9, 0x04f9,
- 0x04fb, 0x04fb,
- 0x04fd, 0x04fd,
- 0x04ff, 0x04ff,
- 0x0501, 0x0501,
- 0x0503, 0x0503,
- 0x0505, 0x0505,
- 0x0507, 0x0507,
- 0x0509, 0x0509,
- 0x050b, 0x050b,
- 0x050d, 0x050d,
- 0x050f, 0x050f,
- 0x0511, 0x0511,
- 0x0513, 0x0513,
- 0x0515, 0x0515,
- 0x0517, 0x0517,
- 0x0519, 0x0519,
- 0x051b, 0x051b,
- 0x051d, 0x051d,
- 0x051f, 0x051f,
- 0x0521, 0x0521,
- 0x0523, 0x0523,
- 0x0525, 0x0525,
- 0x0527, 0x0527,
- 0x0529, 0x0529,
- 0x052b, 0x052b,
- 0x052d, 0x052d,
- 0x052f, 0x052f,
- 0x0561, 0x0587,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1d00, 0x1dbf,
- 0x1e01, 0x1e01,
- 0x1e03, 0x1e03,
- 0x1e05, 0x1e05,
- 0x1e07, 0x1e07,
- 0x1e09, 0x1e09,
- 0x1e0b, 0x1e0b,
- 0x1e0d, 0x1e0d,
- 0x1e0f, 0x1e0f,
- 0x1e11, 0x1e11,
- 0x1e13, 0x1e13,
- 0x1e15, 0x1e15,
- 0x1e17, 0x1e17,
- 0x1e19, 0x1e19,
- 0x1e1b, 0x1e1b,
- 0x1e1d, 0x1e1d,
- 0x1e1f, 0x1e1f,
- 0x1e21, 0x1e21,
- 0x1e23, 0x1e23,
- 0x1e25, 0x1e25,
- 0x1e27, 0x1e27,
- 0x1e29, 0x1e29,
- 0x1e2b, 0x1e2b,
- 0x1e2d, 0x1e2d,
- 0x1e2f, 0x1e2f,
- 0x1e31, 0x1e31,
- 0x1e33, 0x1e33,
- 0x1e35, 0x1e35,
- 0x1e37, 0x1e37,
- 0x1e39, 0x1e39,
- 0x1e3b, 0x1e3b,
- 0x1e3d, 0x1e3d,
- 0x1e3f, 0x1e3f,
- 0x1e41, 0x1e41,
- 0x1e43, 0x1e43,
- 0x1e45, 0x1e45,
- 0x1e47, 0x1e47,
- 0x1e49, 0x1e49,
- 0x1e4b, 0x1e4b,
- 0x1e4d, 0x1e4d,
- 0x1e4f, 0x1e4f,
- 0x1e51, 0x1e51,
- 0x1e53, 0x1e53,
- 0x1e55, 0x1e55,
- 0x1e57, 0x1e57,
- 0x1e59, 0x1e59,
- 0x1e5b, 0x1e5b,
- 0x1e5d, 0x1e5d,
- 0x1e5f, 0x1e5f,
- 0x1e61, 0x1e61,
- 0x1e63, 0x1e63,
- 0x1e65, 0x1e65,
- 0x1e67, 0x1e67,
- 0x1e69, 0x1e69,
- 0x1e6b, 0x1e6b,
- 0x1e6d, 0x1e6d,
- 0x1e6f, 0x1e6f,
- 0x1e71, 0x1e71,
- 0x1e73, 0x1e73,
- 0x1e75, 0x1e75,
- 0x1e77, 0x1e77,
- 0x1e79, 0x1e79,
- 0x1e7b, 0x1e7b,
- 0x1e7d, 0x1e7d,
- 0x1e7f, 0x1e7f,
- 0x1e81, 0x1e81,
- 0x1e83, 0x1e83,
- 0x1e85, 0x1e85,
- 0x1e87, 0x1e87,
- 0x1e89, 0x1e89,
- 0x1e8b, 0x1e8b,
- 0x1e8d, 0x1e8d,
- 0x1e8f, 0x1e8f,
- 0x1e91, 0x1e91,
- 0x1e93, 0x1e93,
- 0x1e95, 0x1e9d,
- 0x1e9f, 0x1e9f,
- 0x1ea1, 0x1ea1,
- 0x1ea3, 0x1ea3,
- 0x1ea5, 0x1ea5,
- 0x1ea7, 0x1ea7,
- 0x1ea9, 0x1ea9,
- 0x1eab, 0x1eab,
- 0x1ead, 0x1ead,
- 0x1eaf, 0x1eaf,
- 0x1eb1, 0x1eb1,
- 0x1eb3, 0x1eb3,
- 0x1eb5, 0x1eb5,
- 0x1eb7, 0x1eb7,
- 0x1eb9, 0x1eb9,
- 0x1ebb, 0x1ebb,
- 0x1ebd, 0x1ebd,
- 0x1ebf, 0x1ebf,
- 0x1ec1, 0x1ec1,
- 0x1ec3, 0x1ec3,
- 0x1ec5, 0x1ec5,
- 0x1ec7, 0x1ec7,
- 0x1ec9, 0x1ec9,
- 0x1ecb, 0x1ecb,
- 0x1ecd, 0x1ecd,
- 0x1ecf, 0x1ecf,
- 0x1ed1, 0x1ed1,
- 0x1ed3, 0x1ed3,
- 0x1ed5, 0x1ed5,
- 0x1ed7, 0x1ed7,
- 0x1ed9, 0x1ed9,
- 0x1edb, 0x1edb,
- 0x1edd, 0x1edd,
- 0x1edf, 0x1edf,
- 0x1ee1, 0x1ee1,
- 0x1ee3, 0x1ee3,
- 0x1ee5, 0x1ee5,
- 0x1ee7, 0x1ee7,
- 0x1ee9, 0x1ee9,
- 0x1eeb, 0x1eeb,
- 0x1eed, 0x1eed,
- 0x1eef, 0x1eef,
- 0x1ef1, 0x1ef1,
- 0x1ef3, 0x1ef3,
- 0x1ef5, 0x1ef5,
- 0x1ef7, 0x1ef7,
- 0x1ef9, 0x1ef9,
- 0x1efb, 0x1efb,
- 0x1efd, 0x1efd,
- 0x1eff, 0x1f07,
- 0x1f10, 0x1f15,
- 0x1f20, 0x1f27,
- 0x1f30, 0x1f37,
- 0x1f40, 0x1f45,
- 0x1f50, 0x1f57,
- 0x1f60, 0x1f67,
- 0x1f70, 0x1f7d,
- 0x1f80, 0x1f87,
- 0x1f90, 0x1f97,
- 0x1fa0, 0x1fa7,
- 0x1fb0, 0x1fb4,
- 0x1fb6, 0x1fb7,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fc7,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fd7,
- 0x1fe0, 0x1fe7,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ff7,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x210a, 0x210a,
- 0x210e, 0x210f,
- 0x2113, 0x2113,
- 0x212f, 0x212f,
- 0x2134, 0x2134,
- 0x2139, 0x2139,
- 0x213c, 0x213d,
- 0x2146, 0x2149,
- 0x214e, 0x214e,
- 0x2170, 0x217f,
- 0x2184, 0x2184,
- 0x24d0, 0x24e9,
- 0x2c30, 0x2c5e,
- 0x2c61, 0x2c61,
- 0x2c65, 0x2c66,
- 0x2c68, 0x2c68,
- 0x2c6a, 0x2c6a,
- 0x2c6c, 0x2c6c,
- 0x2c71, 0x2c71,
- 0x2c73, 0x2c74,
- 0x2c76, 0x2c7d,
- 0x2c81, 0x2c81,
- 0x2c83, 0x2c83,
- 0x2c85, 0x2c85,
- 0x2c87, 0x2c87,
- 0x2c89, 0x2c89,
- 0x2c8b, 0x2c8b,
- 0x2c8d, 0x2c8d,
- 0x2c8f, 0x2c8f,
- 0x2c91, 0x2c91,
- 0x2c93, 0x2c93,
- 0x2c95, 0x2c95,
- 0x2c97, 0x2c97,
- 0x2c99, 0x2c99,
- 0x2c9b, 0x2c9b,
- 0x2c9d, 0x2c9d,
- 0x2c9f, 0x2c9f,
- 0x2ca1, 0x2ca1,
- 0x2ca3, 0x2ca3,
- 0x2ca5, 0x2ca5,
- 0x2ca7, 0x2ca7,
- 0x2ca9, 0x2ca9,
- 0x2cab, 0x2cab,
- 0x2cad, 0x2cad,
- 0x2caf, 0x2caf,
- 0x2cb1, 0x2cb1,
- 0x2cb3, 0x2cb3,
- 0x2cb5, 0x2cb5,
- 0x2cb7, 0x2cb7,
- 0x2cb9, 0x2cb9,
- 0x2cbb, 0x2cbb,
- 0x2cbd, 0x2cbd,
- 0x2cbf, 0x2cbf,
- 0x2cc1, 0x2cc1,
- 0x2cc3, 0x2cc3,
- 0x2cc5, 0x2cc5,
- 0x2cc7, 0x2cc7,
- 0x2cc9, 0x2cc9,
- 0x2ccb, 0x2ccb,
- 0x2ccd, 0x2ccd,
- 0x2ccf, 0x2ccf,
- 0x2cd1, 0x2cd1,
- 0x2cd3, 0x2cd3,
- 0x2cd5, 0x2cd5,
- 0x2cd7, 0x2cd7,
- 0x2cd9, 0x2cd9,
- 0x2cdb, 0x2cdb,
- 0x2cdd, 0x2cdd,
- 0x2cdf, 0x2cdf,
- 0x2ce1, 0x2ce1,
- 0x2ce3, 0x2ce4,
- 0x2cec, 0x2cec,
- 0x2cee, 0x2cee,
- 0x2cf3, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0xa641, 0xa641,
- 0xa643, 0xa643,
- 0xa645, 0xa645,
- 0xa647, 0xa647,
- 0xa649, 0xa649,
- 0xa64b, 0xa64b,
- 0xa64d, 0xa64d,
- 0xa64f, 0xa64f,
- 0xa651, 0xa651,
- 0xa653, 0xa653,
- 0xa655, 0xa655,
- 0xa657, 0xa657,
- 0xa659, 0xa659,
- 0xa65b, 0xa65b,
- 0xa65d, 0xa65d,
- 0xa65f, 0xa65f,
- 0xa661, 0xa661,
- 0xa663, 0xa663,
- 0xa665, 0xa665,
- 0xa667, 0xa667,
- 0xa669, 0xa669,
- 0xa66b, 0xa66b,
- 0xa66d, 0xa66d,
- 0xa681, 0xa681,
- 0xa683, 0xa683,
- 0xa685, 0xa685,
- 0xa687, 0xa687,
- 0xa689, 0xa689,
- 0xa68b, 0xa68b,
- 0xa68d, 0xa68d,
- 0xa68f, 0xa68f,
- 0xa691, 0xa691,
- 0xa693, 0xa693,
- 0xa695, 0xa695,
- 0xa697, 0xa697,
- 0xa699, 0xa699,
- 0xa69b, 0xa69d,
- 0xa723, 0xa723,
- 0xa725, 0xa725,
- 0xa727, 0xa727,
- 0xa729, 0xa729,
- 0xa72b, 0xa72b,
- 0xa72d, 0xa72d,
- 0xa72f, 0xa731,
- 0xa733, 0xa733,
- 0xa735, 0xa735,
- 0xa737, 0xa737,
- 0xa739, 0xa739,
- 0xa73b, 0xa73b,
- 0xa73d, 0xa73d,
- 0xa73f, 0xa73f,
- 0xa741, 0xa741,
- 0xa743, 0xa743,
- 0xa745, 0xa745,
- 0xa747, 0xa747,
- 0xa749, 0xa749,
- 0xa74b, 0xa74b,
- 0xa74d, 0xa74d,
- 0xa74f, 0xa74f,
- 0xa751, 0xa751,
- 0xa753, 0xa753,
- 0xa755, 0xa755,
- 0xa757, 0xa757,
- 0xa759, 0xa759,
- 0xa75b, 0xa75b,
- 0xa75d, 0xa75d,
- 0xa75f, 0xa75f,
- 0xa761, 0xa761,
- 0xa763, 0xa763,
- 0xa765, 0xa765,
- 0xa767, 0xa767,
- 0xa769, 0xa769,
- 0xa76b, 0xa76b,
- 0xa76d, 0xa76d,
- 0xa76f, 0xa778,
- 0xa77a, 0xa77a,
- 0xa77c, 0xa77c,
- 0xa77f, 0xa77f,
- 0xa781, 0xa781,
- 0xa783, 0xa783,
- 0xa785, 0xa785,
- 0xa787, 0xa787,
- 0xa78c, 0xa78c,
- 0xa78e, 0xa78e,
- 0xa791, 0xa791,
- 0xa793, 0xa795,
- 0xa797, 0xa797,
- 0xa799, 0xa799,
- 0xa79b, 0xa79b,
- 0xa79d, 0xa79d,
- 0xa79f, 0xa79f,
- 0xa7a1, 0xa7a1,
- 0xa7a3, 0xa7a3,
- 0xa7a5, 0xa7a5,
- 0xa7a7, 0xa7a7,
- 0xa7a9, 0xa7a9,
- 0xa7b5, 0xa7b5,
- 0xa7b7, 0xa7b7,
- 0xa7f8, 0xa7fa,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff41, 0xff5a,
- 0x10428, 0x1044f,
- 0x104d8, 0x104fb,
- 0x10cc0, 0x10cf2,
- 0x118c0, 0x118df,
- 0x1d41a, 0x1d433,
- 0x1d44e, 0x1d454,
- 0x1d456, 0x1d467,
- 0x1d482, 0x1d49b,
- 0x1d4b6, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d4cf,
- 0x1d4ea, 0x1d503,
- 0x1d51e, 0x1d537,
- 0x1d552, 0x1d56b,
- 0x1d586, 0x1d59f,
- 0x1d5ba, 0x1d5d3,
- 0x1d5ee, 0x1d607,
- 0x1d622, 0x1d63b,
- 0x1d656, 0x1d66f,
- 0x1d68a, 0x1d6a5,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6e1,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d71b,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d755,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d78f,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7c9,
- 0x1d7cb, 0x1d7cb,
- 0x1e922, 0x1e943,
-}; /* CR_Lower */
-
-/* 'Print': [[:Print:]] */
-static const OnigCodePoint CR_Print[] = {
- 651,
- 0x0020, 0x007e,
- 0x00a0, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fd,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4f,
- 0x0d54, 0x0d63,
- 0x0d66, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c88,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf9,
- 0x1d00, 0x1df9,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2027,
- 0x202a, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20bf,
- 0x20d0, 0x20f0,
- 0x2100, 0x218b,
- 0x2190, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e49,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fea,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa6f7,
- 0xa700, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c5,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fd,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab65,
- 0xab70, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xe000, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xfffd,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102fb,
- 0x10300, 0x10323,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11150, 0x11176,
- 0x11180, 0x111cd,
- 0x111d0, 0x111df,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x11459,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115dd,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
- 0x11660, 0x1166c,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x1173f,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a47,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c45,
- 0x11c50, 0x11c6c,
- 0x11c70, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1e8,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1da8b,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1e95e, 0x1e95f,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xf0000, 0xffffd,
- 0x100000, 0x10fffd,
-}; /* CR_Print */
-
-/* 'XPosixPunct': [[:Punct:]] */
-static const OnigCodePoint CR_XPosixPunct[] = {
- 167,
- 0x0021, 0x002f,
- 0x003a, 0x0040,
- 0x005b, 0x0060,
- 0x007b, 0x007e,
- 0x00a1, 0x00a1,
- 0x00a7, 0x00a7,
- 0x00ab, 0x00ab,
- 0x00b6, 0x00b7,
- 0x00bb, 0x00bb,
- 0x00bf, 0x00bf,
- 0x037e, 0x037e,
- 0x0387, 0x0387,
- 0x055a, 0x055f,
- 0x0589, 0x058a,
- 0x05be, 0x05be,
- 0x05c0, 0x05c0,
- 0x05c3, 0x05c3,
- 0x05c6, 0x05c6,
- 0x05f3, 0x05f4,
- 0x0609, 0x060a,
- 0x060c, 0x060d,
- 0x061b, 0x061b,
- 0x061e, 0x061f,
- 0x066a, 0x066d,
- 0x06d4, 0x06d4,
- 0x0700, 0x070d,
- 0x07f7, 0x07f9,
- 0x0830, 0x083e,
- 0x085e, 0x085e,
- 0x0964, 0x0965,
- 0x0970, 0x0970,
- 0x09fd, 0x09fd,
- 0x0af0, 0x0af0,
- 0x0df4, 0x0df4,
- 0x0e4f, 0x0e4f,
- 0x0e5a, 0x0e5b,
- 0x0f04, 0x0f12,
- 0x0f14, 0x0f14,
- 0x0f3a, 0x0f3d,
- 0x0f85, 0x0f85,
- 0x0fd0, 0x0fd4,
- 0x0fd9, 0x0fda,
- 0x104a, 0x104f,
- 0x10fb, 0x10fb,
- 0x1360, 0x1368,
- 0x1400, 0x1400,
- 0x166d, 0x166e,
- 0x169b, 0x169c,
- 0x16eb, 0x16ed,
- 0x1735, 0x1736,
- 0x17d4, 0x17d6,
- 0x17d8, 0x17da,
- 0x1800, 0x180a,
- 0x1944, 0x1945,
- 0x1a1e, 0x1a1f,
- 0x1aa0, 0x1aa6,
- 0x1aa8, 0x1aad,
- 0x1b5a, 0x1b60,
- 0x1bfc, 0x1bff,
- 0x1c3b, 0x1c3f,
- 0x1c7e, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd3, 0x1cd3,
- 0x2010, 0x2027,
- 0x2030, 0x2043,
- 0x2045, 0x2051,
- 0x2053, 0x205e,
- 0x207d, 0x207e,
- 0x208d, 0x208e,
- 0x2308, 0x230b,
- 0x2329, 0x232a,
- 0x2768, 0x2775,
- 0x27c5, 0x27c6,
- 0x27e6, 0x27ef,
- 0x2983, 0x2998,
- 0x29d8, 0x29db,
- 0x29fc, 0x29fd,
- 0x2cf9, 0x2cfc,
- 0x2cfe, 0x2cff,
- 0x2d70, 0x2d70,
- 0x2e00, 0x2e2e,
- 0x2e30, 0x2e49,
- 0x3001, 0x3003,
- 0x3008, 0x3011,
- 0x3014, 0x301f,
- 0x3030, 0x3030,
- 0x303d, 0x303d,
- 0x30a0, 0x30a0,
- 0x30fb, 0x30fb,
- 0xa4fe, 0xa4ff,
- 0xa60d, 0xa60f,
- 0xa673, 0xa673,
- 0xa67e, 0xa67e,
- 0xa6f2, 0xa6f7,
- 0xa874, 0xa877,
- 0xa8ce, 0xa8cf,
- 0xa8f8, 0xa8fa,
- 0xa8fc, 0xa8fc,
- 0xa92e, 0xa92f,
- 0xa95f, 0xa95f,
- 0xa9c1, 0xa9cd,
- 0xa9de, 0xa9df,
- 0xaa5c, 0xaa5f,
- 0xaade, 0xaadf,
- 0xaaf0, 0xaaf1,
- 0xabeb, 0xabeb,
- 0xfd3e, 0xfd3f,
- 0xfe10, 0xfe19,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe61,
- 0xfe63, 0xfe63,
- 0xfe68, 0xfe68,
- 0xfe6a, 0xfe6b,
- 0xff01, 0xff03,
- 0xff05, 0xff0a,
- 0xff0c, 0xff0f,
- 0xff1a, 0xff1b,
- 0xff1f, 0xff20,
- 0xff3b, 0xff3d,
- 0xff3f, 0xff3f,
- 0xff5b, 0xff5b,
- 0xff5d, 0xff5d,
- 0xff5f, 0xff65,
- 0x10100, 0x10102,
- 0x1039f, 0x1039f,
- 0x103d0, 0x103d0,
- 0x1056f, 0x1056f,
- 0x10857, 0x10857,
- 0x1091f, 0x1091f,
- 0x1093f, 0x1093f,
- 0x10a50, 0x10a58,
- 0x10a7f, 0x10a7f,
- 0x10af0, 0x10af6,
- 0x10b39, 0x10b3f,
- 0x10b99, 0x10b9c,
- 0x11047, 0x1104d,
- 0x110bb, 0x110bc,
- 0x110be, 0x110c1,
- 0x11140, 0x11143,
- 0x11174, 0x11175,
- 0x111c5, 0x111c9,
- 0x111cd, 0x111cd,
- 0x111db, 0x111db,
- 0x111dd, 0x111df,
- 0x11238, 0x1123d,
- 0x112a9, 0x112a9,
- 0x1144b, 0x1144f,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x114c6, 0x114c6,
- 0x115c1, 0x115d7,
- 0x11641, 0x11643,
- 0x11660, 0x1166c,
- 0x1173c, 0x1173e,
- 0x11a3f, 0x11a46,
- 0x11a9a, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11c41, 0x11c45,
- 0x11c70, 0x11c71,
- 0x12470, 0x12474,
- 0x16a6e, 0x16a6f,
- 0x16af5, 0x16af5,
- 0x16b37, 0x16b3b,
- 0x16b44, 0x16b44,
- 0x1bc9f, 0x1bc9f,
- 0x1da87, 0x1da8b,
- 0x1e95e, 0x1e95f,
-}; /* CR_XPosixPunct */
-
-/* 'Space': [[:Space:]] */
-static const OnigCodePoint CR_Space[] = {
- 10,
- 0x0009, 0x000d,
- 0x0020, 0x0020,
- 0x0085, 0x0085,
- 0x00a0, 0x00a0,
- 0x1680, 0x1680,
- 0x2000, 0x200a,
- 0x2028, 0x2029,
- 0x202f, 0x202f,
- 0x205f, 0x205f,
- 0x3000, 0x3000,
-}; /* CR_Space */
-
-/* 'Upper': [[:Upper:]] */
-static const OnigCodePoint CR_Upper[] = {
- 632,
- 0x0041, 0x005a,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00de,
- 0x0100, 0x0100,
- 0x0102, 0x0102,
- 0x0104, 0x0104,
- 0x0106, 0x0106,
- 0x0108, 0x0108,
- 0x010a, 0x010a,
- 0x010c, 0x010c,
- 0x010e, 0x010e,
- 0x0110, 0x0110,
- 0x0112, 0x0112,
- 0x0114, 0x0114,
- 0x0116, 0x0116,
- 0x0118, 0x0118,
- 0x011a, 0x011a,
- 0x011c, 0x011c,
- 0x011e, 0x011e,
- 0x0120, 0x0120,
- 0x0122, 0x0122,
- 0x0124, 0x0124,
- 0x0126, 0x0126,
- 0x0128, 0x0128,
- 0x012a, 0x012a,
- 0x012c, 0x012c,
- 0x012e, 0x012e,
- 0x0130, 0x0130,
- 0x0132, 0x0132,
- 0x0134, 0x0134,
- 0x0136, 0x0136,
- 0x0139, 0x0139,
- 0x013b, 0x013b,
- 0x013d, 0x013d,
- 0x013f, 0x013f,
- 0x0141, 0x0141,
- 0x0143, 0x0143,
- 0x0145, 0x0145,
- 0x0147, 0x0147,
- 0x014a, 0x014a,
- 0x014c, 0x014c,
- 0x014e, 0x014e,
- 0x0150, 0x0150,
- 0x0152, 0x0152,
- 0x0154, 0x0154,
- 0x0156, 0x0156,
- 0x0158, 0x0158,
- 0x015a, 0x015a,
- 0x015c, 0x015c,
- 0x015e, 0x015e,
- 0x0160, 0x0160,
- 0x0162, 0x0162,
- 0x0164, 0x0164,
- 0x0166, 0x0166,
- 0x0168, 0x0168,
- 0x016a, 0x016a,
- 0x016c, 0x016c,
- 0x016e, 0x016e,
- 0x0170, 0x0170,
- 0x0172, 0x0172,
- 0x0174, 0x0174,
- 0x0176, 0x0176,
- 0x0178, 0x0179,
- 0x017b, 0x017b,
- 0x017d, 0x017d,
- 0x0181, 0x0182,
- 0x0184, 0x0184,
- 0x0186, 0x0187,
- 0x0189, 0x018b,
- 0x018e, 0x0191,
- 0x0193, 0x0194,
- 0x0196, 0x0198,
- 0x019c, 0x019d,
- 0x019f, 0x01a0,
- 0x01a2, 0x01a2,
- 0x01a4, 0x01a4,
- 0x01a6, 0x01a7,
- 0x01a9, 0x01a9,
- 0x01ac, 0x01ac,
- 0x01ae, 0x01af,
- 0x01b1, 0x01b3,
- 0x01b5, 0x01b5,
- 0x01b7, 0x01b8,
- 0x01bc, 0x01bc,
- 0x01c4, 0x01c4,
- 0x01c7, 0x01c7,
- 0x01ca, 0x01ca,
- 0x01cd, 0x01cd,
- 0x01cf, 0x01cf,
- 0x01d1, 0x01d1,
- 0x01d3, 0x01d3,
- 0x01d5, 0x01d5,
- 0x01d7, 0x01d7,
- 0x01d9, 0x01d9,
- 0x01db, 0x01db,
- 0x01de, 0x01de,
- 0x01e0, 0x01e0,
- 0x01e2, 0x01e2,
- 0x01e4, 0x01e4,
- 0x01e6, 0x01e6,
- 0x01e8, 0x01e8,
- 0x01ea, 0x01ea,
- 0x01ec, 0x01ec,
- 0x01ee, 0x01ee,
- 0x01f1, 0x01f1,
- 0x01f4, 0x01f4,
- 0x01f6, 0x01f8,
- 0x01fa, 0x01fa,
- 0x01fc, 0x01fc,
- 0x01fe, 0x01fe,
- 0x0200, 0x0200,
- 0x0202, 0x0202,
- 0x0204, 0x0204,
- 0x0206, 0x0206,
- 0x0208, 0x0208,
- 0x020a, 0x020a,
- 0x020c, 0x020c,
- 0x020e, 0x020e,
- 0x0210, 0x0210,
- 0x0212, 0x0212,
- 0x0214, 0x0214,
- 0x0216, 0x0216,
- 0x0218, 0x0218,
- 0x021a, 0x021a,
- 0x021c, 0x021c,
- 0x021e, 0x021e,
- 0x0220, 0x0220,
- 0x0222, 0x0222,
- 0x0224, 0x0224,
- 0x0226, 0x0226,
- 0x0228, 0x0228,
- 0x022a, 0x022a,
- 0x022c, 0x022c,
- 0x022e, 0x022e,
- 0x0230, 0x0230,
- 0x0232, 0x0232,
- 0x023a, 0x023b,
- 0x023d, 0x023e,
- 0x0241, 0x0241,
- 0x0243, 0x0246,
- 0x0248, 0x0248,
- 0x024a, 0x024a,
- 0x024c, 0x024c,
- 0x024e, 0x024e,
- 0x0370, 0x0370,
- 0x0372, 0x0372,
- 0x0376, 0x0376,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x038f,
- 0x0391, 0x03a1,
- 0x03a3, 0x03ab,
- 0x03cf, 0x03cf,
- 0x03d2, 0x03d4,
- 0x03d8, 0x03d8,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03e2,
- 0x03e4, 0x03e4,
- 0x03e6, 0x03e6,
- 0x03e8, 0x03e8,
- 0x03ea, 0x03ea,
- 0x03ec, 0x03ec,
- 0x03ee, 0x03ee,
- 0x03f4, 0x03f4,
- 0x03f7, 0x03f7,
- 0x03f9, 0x03fa,
- 0x03fd, 0x042f,
- 0x0460, 0x0460,
- 0x0462, 0x0462,
- 0x0464, 0x0464,
- 0x0466, 0x0466,
- 0x0468, 0x0468,
- 0x046a, 0x046a,
- 0x046c, 0x046c,
- 0x046e, 0x046e,
- 0x0470, 0x0470,
- 0x0472, 0x0472,
- 0x0474, 0x0474,
- 0x0476, 0x0476,
- 0x0478, 0x0478,
- 0x047a, 0x047a,
- 0x047c, 0x047c,
- 0x047e, 0x047e,
- 0x0480, 0x0480,
- 0x048a, 0x048a,
- 0x048c, 0x048c,
- 0x048e, 0x048e,
- 0x0490, 0x0490,
- 0x0492, 0x0492,
- 0x0494, 0x0494,
- 0x0496, 0x0496,
- 0x0498, 0x0498,
- 0x049a, 0x049a,
- 0x049c, 0x049c,
- 0x049e, 0x049e,
- 0x04a0, 0x04a0,
- 0x04a2, 0x04a2,
- 0x04a4, 0x04a4,
- 0x04a6, 0x04a6,
- 0x04a8, 0x04a8,
- 0x04aa, 0x04aa,
- 0x04ac, 0x04ac,
- 0x04ae, 0x04ae,
- 0x04b0, 0x04b0,
- 0x04b2, 0x04b2,
- 0x04b4, 0x04b4,
- 0x04b6, 0x04b6,
- 0x04b8, 0x04b8,
- 0x04ba, 0x04ba,
- 0x04bc, 0x04bc,
- 0x04be, 0x04be,
- 0x04c0, 0x04c1,
- 0x04c3, 0x04c3,
- 0x04c5, 0x04c5,
- 0x04c7, 0x04c7,
- 0x04c9, 0x04c9,
- 0x04cb, 0x04cb,
- 0x04cd, 0x04cd,
- 0x04d0, 0x04d0,
- 0x04d2, 0x04d2,
- 0x04d4, 0x04d4,
- 0x04d6, 0x04d6,
- 0x04d8, 0x04d8,
- 0x04da, 0x04da,
- 0x04dc, 0x04dc,
- 0x04de, 0x04de,
- 0x04e0, 0x04e0,
- 0x04e2, 0x04e2,
- 0x04e4, 0x04e4,
- 0x04e6, 0x04e6,
- 0x04e8, 0x04e8,
- 0x04ea, 0x04ea,
- 0x04ec, 0x04ec,
- 0x04ee, 0x04ee,
- 0x04f0, 0x04f0,
- 0x04f2, 0x04f2,
- 0x04f4, 0x04f4,
- 0x04f6, 0x04f6,
- 0x04f8, 0x04f8,
- 0x04fa, 0x04fa,
- 0x04fc, 0x04fc,
- 0x04fe, 0x04fe,
- 0x0500, 0x0500,
- 0x0502, 0x0502,
- 0x0504, 0x0504,
- 0x0506, 0x0506,
- 0x0508, 0x0508,
- 0x050a, 0x050a,
- 0x050c, 0x050c,
- 0x050e, 0x050e,
- 0x0510, 0x0510,
- 0x0512, 0x0512,
- 0x0514, 0x0514,
- 0x0516, 0x0516,
- 0x0518, 0x0518,
- 0x051a, 0x051a,
- 0x051c, 0x051c,
- 0x051e, 0x051e,
- 0x0520, 0x0520,
- 0x0522, 0x0522,
- 0x0524, 0x0524,
- 0x0526, 0x0526,
- 0x0528, 0x0528,
- 0x052a, 0x052a,
- 0x052c, 0x052c,
- 0x052e, 0x052e,
- 0x0531, 0x0556,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x13a0, 0x13f5,
- 0x1e00, 0x1e00,
- 0x1e02, 0x1e02,
- 0x1e04, 0x1e04,
- 0x1e06, 0x1e06,
- 0x1e08, 0x1e08,
- 0x1e0a, 0x1e0a,
- 0x1e0c, 0x1e0c,
- 0x1e0e, 0x1e0e,
- 0x1e10, 0x1e10,
- 0x1e12, 0x1e12,
- 0x1e14, 0x1e14,
- 0x1e16, 0x1e16,
- 0x1e18, 0x1e18,
- 0x1e1a, 0x1e1a,
- 0x1e1c, 0x1e1c,
- 0x1e1e, 0x1e1e,
- 0x1e20, 0x1e20,
- 0x1e22, 0x1e22,
- 0x1e24, 0x1e24,
- 0x1e26, 0x1e26,
- 0x1e28, 0x1e28,
- 0x1e2a, 0x1e2a,
- 0x1e2c, 0x1e2c,
- 0x1e2e, 0x1e2e,
- 0x1e30, 0x1e30,
- 0x1e32, 0x1e32,
- 0x1e34, 0x1e34,
- 0x1e36, 0x1e36,
- 0x1e38, 0x1e38,
- 0x1e3a, 0x1e3a,
- 0x1e3c, 0x1e3c,
- 0x1e3e, 0x1e3e,
- 0x1e40, 0x1e40,
- 0x1e42, 0x1e42,
- 0x1e44, 0x1e44,
- 0x1e46, 0x1e46,
- 0x1e48, 0x1e48,
- 0x1e4a, 0x1e4a,
- 0x1e4c, 0x1e4c,
- 0x1e4e, 0x1e4e,
- 0x1e50, 0x1e50,
- 0x1e52, 0x1e52,
- 0x1e54, 0x1e54,
- 0x1e56, 0x1e56,
- 0x1e58, 0x1e58,
- 0x1e5a, 0x1e5a,
- 0x1e5c, 0x1e5c,
- 0x1e5e, 0x1e5e,
- 0x1e60, 0x1e60,
- 0x1e62, 0x1e62,
- 0x1e64, 0x1e64,
- 0x1e66, 0x1e66,
- 0x1e68, 0x1e68,
- 0x1e6a, 0x1e6a,
- 0x1e6c, 0x1e6c,
- 0x1e6e, 0x1e6e,
- 0x1e70, 0x1e70,
- 0x1e72, 0x1e72,
- 0x1e74, 0x1e74,
- 0x1e76, 0x1e76,
- 0x1e78, 0x1e78,
- 0x1e7a, 0x1e7a,
- 0x1e7c, 0x1e7c,
- 0x1e7e, 0x1e7e,
- 0x1e80, 0x1e80,
- 0x1e82, 0x1e82,
- 0x1e84, 0x1e84,
- 0x1e86, 0x1e86,
- 0x1e88, 0x1e88,
- 0x1e8a, 0x1e8a,
- 0x1e8c, 0x1e8c,
- 0x1e8e, 0x1e8e,
- 0x1e90, 0x1e90,
- 0x1e92, 0x1e92,
- 0x1e94, 0x1e94,
- 0x1e9e, 0x1e9e,
- 0x1ea0, 0x1ea0,
- 0x1ea2, 0x1ea2,
- 0x1ea4, 0x1ea4,
- 0x1ea6, 0x1ea6,
- 0x1ea8, 0x1ea8,
- 0x1eaa, 0x1eaa,
- 0x1eac, 0x1eac,
- 0x1eae, 0x1eae,
- 0x1eb0, 0x1eb0,
- 0x1eb2, 0x1eb2,
- 0x1eb4, 0x1eb4,
- 0x1eb6, 0x1eb6,
- 0x1eb8, 0x1eb8,
- 0x1eba, 0x1eba,
- 0x1ebc, 0x1ebc,
- 0x1ebe, 0x1ebe,
- 0x1ec0, 0x1ec0,
- 0x1ec2, 0x1ec2,
- 0x1ec4, 0x1ec4,
- 0x1ec6, 0x1ec6,
- 0x1ec8, 0x1ec8,
- 0x1eca, 0x1eca,
- 0x1ecc, 0x1ecc,
- 0x1ece, 0x1ece,
- 0x1ed0, 0x1ed0,
- 0x1ed2, 0x1ed2,
- 0x1ed4, 0x1ed4,
- 0x1ed6, 0x1ed6,
- 0x1ed8, 0x1ed8,
- 0x1eda, 0x1eda,
- 0x1edc, 0x1edc,
- 0x1ede, 0x1ede,
- 0x1ee0, 0x1ee0,
- 0x1ee2, 0x1ee2,
- 0x1ee4, 0x1ee4,
- 0x1ee6, 0x1ee6,
- 0x1ee8, 0x1ee8,
- 0x1eea, 0x1eea,
- 0x1eec, 0x1eec,
- 0x1eee, 0x1eee,
- 0x1ef0, 0x1ef0,
- 0x1ef2, 0x1ef2,
- 0x1ef4, 0x1ef4,
- 0x1ef6, 0x1ef6,
- 0x1ef8, 0x1ef8,
- 0x1efa, 0x1efa,
- 0x1efc, 0x1efc,
- 0x1efe, 0x1efe,
- 0x1f08, 0x1f0f,
- 0x1f18, 0x1f1d,
- 0x1f28, 0x1f2f,
- 0x1f38, 0x1f3f,
- 0x1f48, 0x1f4d,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f5f,
- 0x1f68, 0x1f6f,
- 0x1fb8, 0x1fbb,
- 0x1fc8, 0x1fcb,
- 0x1fd8, 0x1fdb,
- 0x1fe8, 0x1fec,
- 0x1ff8, 0x1ffb,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210b, 0x210d,
- 0x2110, 0x2112,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x2130, 0x2133,
- 0x213e, 0x213f,
- 0x2145, 0x2145,
- 0x2160, 0x216f,
- 0x2183, 0x2183,
- 0x24b6, 0x24cf,
- 0x2c00, 0x2c2e,
- 0x2c60, 0x2c60,
- 0x2c62, 0x2c64,
- 0x2c67, 0x2c67,
- 0x2c69, 0x2c69,
- 0x2c6b, 0x2c6b,
- 0x2c6d, 0x2c70,
- 0x2c72, 0x2c72,
- 0x2c75, 0x2c75,
- 0x2c7e, 0x2c80,
- 0x2c82, 0x2c82,
- 0x2c84, 0x2c84,
- 0x2c86, 0x2c86,
- 0x2c88, 0x2c88,
- 0x2c8a, 0x2c8a,
- 0x2c8c, 0x2c8c,
- 0x2c8e, 0x2c8e,
- 0x2c90, 0x2c90,
- 0x2c92, 0x2c92,
- 0x2c94, 0x2c94,
- 0x2c96, 0x2c96,
- 0x2c98, 0x2c98,
- 0x2c9a, 0x2c9a,
- 0x2c9c, 0x2c9c,
- 0x2c9e, 0x2c9e,
- 0x2ca0, 0x2ca0,
- 0x2ca2, 0x2ca2,
- 0x2ca4, 0x2ca4,
- 0x2ca6, 0x2ca6,
- 0x2ca8, 0x2ca8,
- 0x2caa, 0x2caa,
- 0x2cac, 0x2cac,
- 0x2cae, 0x2cae,
- 0x2cb0, 0x2cb0,
- 0x2cb2, 0x2cb2,
- 0x2cb4, 0x2cb4,
- 0x2cb6, 0x2cb6,
- 0x2cb8, 0x2cb8,
- 0x2cba, 0x2cba,
- 0x2cbc, 0x2cbc,
- 0x2cbe, 0x2cbe,
- 0x2cc0, 0x2cc0,
- 0x2cc2, 0x2cc2,
- 0x2cc4, 0x2cc4,
- 0x2cc6, 0x2cc6,
- 0x2cc8, 0x2cc8,
- 0x2cca, 0x2cca,
- 0x2ccc, 0x2ccc,
- 0x2cce, 0x2cce,
- 0x2cd0, 0x2cd0,
- 0x2cd2, 0x2cd2,
- 0x2cd4, 0x2cd4,
- 0x2cd6, 0x2cd6,
- 0x2cd8, 0x2cd8,
- 0x2cda, 0x2cda,
- 0x2cdc, 0x2cdc,
- 0x2cde, 0x2cde,
- 0x2ce0, 0x2ce0,
- 0x2ce2, 0x2ce2,
- 0x2ceb, 0x2ceb,
- 0x2ced, 0x2ced,
- 0x2cf2, 0x2cf2,
- 0xa640, 0xa640,
- 0xa642, 0xa642,
- 0xa644, 0xa644,
- 0xa646, 0xa646,
- 0xa648, 0xa648,
- 0xa64a, 0xa64a,
- 0xa64c, 0xa64c,
- 0xa64e, 0xa64e,
- 0xa650, 0xa650,
- 0xa652, 0xa652,
- 0xa654, 0xa654,
- 0xa656, 0xa656,
- 0xa658, 0xa658,
- 0xa65a, 0xa65a,
- 0xa65c, 0xa65c,
- 0xa65e, 0xa65e,
- 0xa660, 0xa660,
- 0xa662, 0xa662,
- 0xa664, 0xa664,
- 0xa666, 0xa666,
- 0xa668, 0xa668,
- 0xa66a, 0xa66a,
- 0xa66c, 0xa66c,
- 0xa680, 0xa680,
- 0xa682, 0xa682,
- 0xa684, 0xa684,
- 0xa686, 0xa686,
- 0xa688, 0xa688,
- 0xa68a, 0xa68a,
- 0xa68c, 0xa68c,
- 0xa68e, 0xa68e,
- 0xa690, 0xa690,
- 0xa692, 0xa692,
- 0xa694, 0xa694,
- 0xa696, 0xa696,
- 0xa698, 0xa698,
- 0xa69a, 0xa69a,
- 0xa722, 0xa722,
- 0xa724, 0xa724,
- 0xa726, 0xa726,
- 0xa728, 0xa728,
- 0xa72a, 0xa72a,
- 0xa72c, 0xa72c,
- 0xa72e, 0xa72e,
- 0xa732, 0xa732,
- 0xa734, 0xa734,
- 0xa736, 0xa736,
- 0xa738, 0xa738,
- 0xa73a, 0xa73a,
- 0xa73c, 0xa73c,
- 0xa73e, 0xa73e,
- 0xa740, 0xa740,
- 0xa742, 0xa742,
- 0xa744, 0xa744,
- 0xa746, 0xa746,
- 0xa748, 0xa748,
- 0xa74a, 0xa74a,
- 0xa74c, 0xa74c,
- 0xa74e, 0xa74e,
- 0xa750, 0xa750,
- 0xa752, 0xa752,
- 0xa754, 0xa754,
- 0xa756, 0xa756,
- 0xa758, 0xa758,
- 0xa75a, 0xa75a,
- 0xa75c, 0xa75c,
- 0xa75e, 0xa75e,
- 0xa760, 0xa760,
- 0xa762, 0xa762,
- 0xa764, 0xa764,
- 0xa766, 0xa766,
- 0xa768, 0xa768,
- 0xa76a, 0xa76a,
- 0xa76c, 0xa76c,
- 0xa76e, 0xa76e,
- 0xa779, 0xa779,
- 0xa77b, 0xa77b,
- 0xa77d, 0xa77e,
- 0xa780, 0xa780,
- 0xa782, 0xa782,
- 0xa784, 0xa784,
- 0xa786, 0xa786,
- 0xa78b, 0xa78b,
- 0xa78d, 0xa78d,
- 0xa790, 0xa790,
- 0xa792, 0xa792,
- 0xa796, 0xa796,
- 0xa798, 0xa798,
- 0xa79a, 0xa79a,
- 0xa79c, 0xa79c,
- 0xa79e, 0xa79e,
- 0xa7a0, 0xa7a0,
- 0xa7a2, 0xa7a2,
- 0xa7a4, 0xa7a4,
- 0xa7a6, 0xa7a6,
- 0xa7a8, 0xa7a8,
- 0xa7aa, 0xa7ae,
- 0xa7b0, 0xa7b4,
- 0xa7b6, 0xa7b6,
- 0xff21, 0xff3a,
- 0x10400, 0x10427,
- 0x104b0, 0x104d3,
- 0x10c80, 0x10cb2,
- 0x118a0, 0x118bf,
- 0x1d400, 0x1d419,
- 0x1d434, 0x1d44d,
- 0x1d468, 0x1d481,
- 0x1d49c, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b5,
- 0x1d4d0, 0x1d4e9,
- 0x1d504, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d538, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d56c, 0x1d585,
- 0x1d5a0, 0x1d5b9,
- 0x1d5d4, 0x1d5ed,
- 0x1d608, 0x1d621,
- 0x1d63c, 0x1d655,
- 0x1d670, 0x1d689,
- 0x1d6a8, 0x1d6c0,
- 0x1d6e2, 0x1d6fa,
- 0x1d71c, 0x1d734,
- 0x1d756, 0x1d76e,
- 0x1d790, 0x1d7a8,
- 0x1d7ca, 0x1d7ca,
- 0x1e900, 0x1e921,
- 0x1f130, 0x1f149,
- 0x1f150, 0x1f169,
- 0x1f170, 0x1f189,
-}; /* CR_Upper */
-
-/* 'XDigit': [[:XDigit:]] */
-static const OnigCodePoint CR_XDigit[] = {
- 3,
- 0x0030, 0x0039,
- 0x0041, 0x0046,
- 0x0061, 0x0066,
-}; /* CR_XDigit */
-
-/* 'Word': [[:Word:]] */
-static const OnigCodePoint CR_Word[] = {
- 692,
- 0x0030, 0x0039,
- 0x0041, 0x005a,
- 0x005f, 0x005f,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0300, 0x0374,
- 0x0376, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x0483, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x0591, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x061a,
- 0x0620, 0x0669,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06df, 0x06e8,
- 0x06ea, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x082d,
- 0x0840, 0x085b,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x08e1,
- 0x08e3, 0x0963,
- 0x0966, 0x096f,
- 0x0971, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af9, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b6f,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bef,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c80, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d54, 0x0d57,
- 0x0d5f, 0x0d63,
- 0x0d66, 0x0d6f,
- 0x0d7a, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e4e,
- 0x0e50, 0x0e59,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f18, 0x0f19,
- 0x0f20, 0x0f29,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x1000, 0x1049,
- 0x1050, 0x109d,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x135f,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1734,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dd,
- 0x17e0, 0x17e9,
- 0x180b, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1946, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19d9,
- 0x1a00, 0x1a1b,
- 0x1a20, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa7, 0x1aa7,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b59,
- 0x1b6b, 0x1b73,
- 0x1b80, 0x1bf3,
- 0x1c00, 0x1c37,
- 0x1c40, 0x1c49,
- 0x1c4d, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1cf9,
- 0x1d00, 0x1df9,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x203f, 0x2040,
- 0x2054, 0x2054,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x20d0, 0x20f0,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x24b6, 0x24e9,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2dff,
- 0x2e2f, 0x2e2f,
- 0x3005, 0x3007,
- 0x3021, 0x302f,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x3099, 0x309a,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa62b,
- 0xa640, 0xa672,
- 0xa674, 0xa67d,
- 0xa67f, 0xa6f1,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa827,
- 0xa840, 0xa873,
- 0xa880, 0xa8c5,
- 0xa8d0, 0xa8d9,
- 0xa8e0, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa900, 0xa92d,
- 0xa930, 0xa953,
- 0xa960, 0xa97c,
- 0xa980, 0xa9c0,
- 0xa9cf, 0xa9d9,
- 0xa9e0, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaef,
- 0xaaf2, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabea,
- 0xabec, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe2f,
- 0xfe33, 0xfe34,
- 0xfe4d, 0xfe4f,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff10, 0xff19,
- 0xff21, 0xff3a,
- 0xff3f, 0xff3f,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10140, 0x10174,
- 0x101fd, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102e0,
- 0x10300, 0x1031f,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x103d1, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a3f,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae6,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11000, 0x11046,
- 0x11066, 0x1106f,
- 0x1107f, 0x110ba,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x1113f,
- 0x11150, 0x11173,
- 0x11176, 0x11176,
- 0x11180, 0x111c4,
- 0x111ca, 0x111cc,
- 0x111d0, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x11237,
- 0x1123e, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x1144a,
- 0x11450, 0x11459,
- 0x11480, 0x114c5,
- 0x114c7, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115c0,
- 0x115d8, 0x115dd,
- 0x11600, 0x11640,
- 0x11644, 0x11644,
- 0x11650, 0x11659,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x11739,
- 0x118a0, 0x118e9,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a3e,
- 0x11a47, 0x11a47,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a99,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c40,
- 0x11c50, 0x11c59,
- 0x11c72, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af4,
- 0x16b00, 0x16b36,
- 0x16b40, 0x16b43,
- 0x16b50, 0x16b59,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9d, 0x1bc9e,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d242, 0x1d244,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1da00, 0x1da36,
- 0x1da3b, 0x1da6c,
- 0x1da75, 0x1da75,
- 0x1da84, 0x1da84,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8d0, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1f130, 0x1f149,
- 0x1f150, 0x1f169,
- 0x1f170, 0x1f189,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
- 0xe0100, 0xe01ef,
-}; /* CR_Word */
-
-/* 'Alnum': [[:Alnum:]] */
-static const OnigCodePoint CR_Alnum[] = {
- 695,
- 0x0030, 0x0039,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0345, 0x0345,
- 0x0370, 0x0374,
- 0x0376, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x05b0, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x061a,
- 0x0620, 0x0657,
- 0x0659, 0x0669,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06e1, 0x06e8,
- 0x06ed, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x073f,
- 0x074d, 0x07b1,
- 0x07c0, 0x07ea,
- 0x07f4, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x0817,
- 0x081a, 0x082c,
- 0x0840, 0x0858,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x08df,
- 0x08e3, 0x08e9,
- 0x08f0, 0x093b,
- 0x093d, 0x094c,
- 0x094e, 0x0950,
- 0x0955, 0x0963,
- 0x0966, 0x096f,
- 0x0971, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bd, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cc,
- 0x09ce, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4c,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abd, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acc,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af9, 0x0afc,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3d, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4c,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b6f,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcc,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bef,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4c,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c80, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbd, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccc,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4c,
- 0x0d4e, 0x0d4e,
- 0x0d54, 0x0d57,
- 0x0d5f, 0x0d63,
- 0x0d66, 0x0d6f,
- 0x0d7a, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e46,
- 0x0e4d, 0x0e4d,
- 0x0e50, 0x0e59,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ecd, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f20, 0x0f29,
- 0x0f40, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f81,
- 0x0f88, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x1000, 0x1036,
- 0x1038, 0x1038,
- 0x103b, 0x1049,
- 0x1050, 0x1062,
- 0x1065, 0x1068,
- 0x106e, 0x1086,
- 0x108e, 0x108e,
- 0x1090, 0x1099,
- 0x109c, 0x109d,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135f, 0x135f,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1713,
- 0x1720, 0x1733,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17b3,
- 0x17b6, 0x17c8,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dc,
- 0x17e0, 0x17e9,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x1938,
- 0x1946, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19d9,
- 0x1a00, 0x1a1b,
- 0x1a20, 0x1a5e,
- 0x1a61, 0x1a74,
- 0x1a80, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa7, 0x1aa7,
- 0x1b00, 0x1b33,
- 0x1b35, 0x1b43,
- 0x1b45, 0x1b4b,
- 0x1b50, 0x1b59,
- 0x1b80, 0x1ba9,
- 0x1bac, 0x1be5,
- 0x1be7, 0x1bf1,
- 0x1c00, 0x1c35,
- 0x1c40, 0x1c49,
- 0x1c4d, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf3,
- 0x1cf5, 0x1cf6,
- 0x1d00, 0x1dbf,
- 0x1de7, 0x1df4,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x24b6, 0x24e9,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2dff,
- 0x2e2f, 0x2e2f,
- 0x3005, 0x3007,
- 0x3021, 0x3029,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa62b,
- 0xa640, 0xa66e,
- 0xa674, 0xa67b,
- 0xa67f, 0xa6ef,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa801,
- 0xa803, 0xa805,
- 0xa807, 0xa80a,
- 0xa80c, 0xa827,
- 0xa840, 0xa873,
- 0xa880, 0xa8c3,
- 0xa8c5, 0xa8c5,
- 0xa8d0, 0xa8d9,
- 0xa8f2, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa900, 0xa92a,
- 0xa930, 0xa952,
- 0xa960, 0xa97c,
- 0xa980, 0xa9b2,
- 0xa9b4, 0xa9bf,
- 0xa9cf, 0xa9d9,
- 0xa9e0, 0xa9e4,
- 0xa9e6, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaa7a,
- 0xaa7e, 0xaabe,
- 0xaac0, 0xaac0,
- 0xaac2, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaef,
- 0xaaf2, 0xaaf5,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabea,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff10, 0xff19,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10140, 0x10174,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031f,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x103d1, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae4,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11000, 0x11045,
- 0x11066, 0x1106f,
- 0x11082, 0x110b8,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11132,
- 0x11136, 0x1113f,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11180, 0x111bf,
- 0x111c1, 0x111c4,
- 0x111d0, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x11234,
- 0x11237, 0x11237,
- 0x1123e, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112e8,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133d, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134c,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11400, 0x11441,
- 0x11443, 0x11445,
- 0x11447, 0x1144a,
- 0x11450, 0x11459,
- 0x11480, 0x114c1,
- 0x114c4, 0x114c5,
- 0x114c7, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115be,
- 0x115d8, 0x115dd,
- 0x11600, 0x1163e,
- 0x11640, 0x11640,
- 0x11644, 0x11644,
- 0x11650, 0x11659,
- 0x11680, 0x116b5,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172a,
- 0x11730, 0x11739,
- 0x118a0, 0x118e9,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a32,
- 0x11a35, 0x11a3e,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a97,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c3e,
- 0x11c40, 0x11c40,
- 0x11c50, 0x11c59,
- 0x11c72, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d41,
- 0x11d43, 0x11d43,
- 0x11d46, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16ad0, 0x16aed,
- 0x16b00, 0x16b36,
- 0x16b40, 0x16b43,
- 0x16b50, 0x16b59,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f93, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9e, 0x1bc9e,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e900, 0x1e943,
- 0x1e947, 0x1e947,
- 0x1e950, 0x1e959,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1f130, 0x1f149,
- 0x1f150, 0x1f169,
- 0x1f170, 0x1f189,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_Alnum */
-
-/* 'ASCII': [[:ASCII:]] */
-static const OnigCodePoint CR_ASCII[] = {
- 1,
- 0x0000, 0x007f,
-}; /* CR_ASCII */
-
-/* 'Punct' */
-static const OnigCodePoint CR_Punct[] = {
- 172,
- 0x0021, 0x0023,
- 0x0025, 0x002a,
- 0x002c, 0x002f,
- 0x003a, 0x003b,
- 0x003f, 0x0040,
- 0x005b, 0x005d,
- 0x005f, 0x005f,
- 0x007b, 0x007b,
- 0x007d, 0x007d,
- 0x00a1, 0x00a1,
- 0x00a7, 0x00a7,
- 0x00ab, 0x00ab,
- 0x00b6, 0x00b7,
- 0x00bb, 0x00bb,
- 0x00bf, 0x00bf,
- 0x037e, 0x037e,
- 0x0387, 0x0387,
- 0x055a, 0x055f,
- 0x0589, 0x058a,
- 0x05be, 0x05be,
- 0x05c0, 0x05c0,
- 0x05c3, 0x05c3,
- 0x05c6, 0x05c6,
- 0x05f3, 0x05f4,
- 0x0609, 0x060a,
- 0x060c, 0x060d,
- 0x061b, 0x061b,
- 0x061e, 0x061f,
- 0x066a, 0x066d,
- 0x06d4, 0x06d4,
- 0x0700, 0x070d,
- 0x07f7, 0x07f9,
- 0x0830, 0x083e,
- 0x085e, 0x085e,
- 0x0964, 0x0965,
- 0x0970, 0x0970,
- 0x09fd, 0x09fd,
- 0x0af0, 0x0af0,
- 0x0df4, 0x0df4,
- 0x0e4f, 0x0e4f,
- 0x0e5a, 0x0e5b,
- 0x0f04, 0x0f12,
- 0x0f14, 0x0f14,
- 0x0f3a, 0x0f3d,
- 0x0f85, 0x0f85,
- 0x0fd0, 0x0fd4,
- 0x0fd9, 0x0fda,
- 0x104a, 0x104f,
- 0x10fb, 0x10fb,
- 0x1360, 0x1368,
- 0x1400, 0x1400,
- 0x166d, 0x166e,
- 0x169b, 0x169c,
- 0x16eb, 0x16ed,
- 0x1735, 0x1736,
- 0x17d4, 0x17d6,
- 0x17d8, 0x17da,
- 0x1800, 0x180a,
- 0x1944, 0x1945,
- 0x1a1e, 0x1a1f,
- 0x1aa0, 0x1aa6,
- 0x1aa8, 0x1aad,
- 0x1b5a, 0x1b60,
- 0x1bfc, 0x1bff,
- 0x1c3b, 0x1c3f,
- 0x1c7e, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd3, 0x1cd3,
- 0x2010, 0x2027,
- 0x2030, 0x2043,
- 0x2045, 0x2051,
- 0x2053, 0x205e,
- 0x207d, 0x207e,
- 0x208d, 0x208e,
- 0x2308, 0x230b,
- 0x2329, 0x232a,
- 0x2768, 0x2775,
- 0x27c5, 0x27c6,
- 0x27e6, 0x27ef,
- 0x2983, 0x2998,
- 0x29d8, 0x29db,
- 0x29fc, 0x29fd,
- 0x2cf9, 0x2cfc,
- 0x2cfe, 0x2cff,
- 0x2d70, 0x2d70,
- 0x2e00, 0x2e2e,
- 0x2e30, 0x2e49,
- 0x3001, 0x3003,
- 0x3008, 0x3011,
- 0x3014, 0x301f,
- 0x3030, 0x3030,
- 0x303d, 0x303d,
- 0x30a0, 0x30a0,
- 0x30fb, 0x30fb,
- 0xa4fe, 0xa4ff,
- 0xa60d, 0xa60f,
- 0xa673, 0xa673,
- 0xa67e, 0xa67e,
- 0xa6f2, 0xa6f7,
- 0xa874, 0xa877,
- 0xa8ce, 0xa8cf,
- 0xa8f8, 0xa8fa,
- 0xa8fc, 0xa8fc,
- 0xa92e, 0xa92f,
- 0xa95f, 0xa95f,
- 0xa9c1, 0xa9cd,
- 0xa9de, 0xa9df,
- 0xaa5c, 0xaa5f,
- 0xaade, 0xaadf,
- 0xaaf0, 0xaaf1,
- 0xabeb, 0xabeb,
- 0xfd3e, 0xfd3f,
- 0xfe10, 0xfe19,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe61,
- 0xfe63, 0xfe63,
- 0xfe68, 0xfe68,
- 0xfe6a, 0xfe6b,
- 0xff01, 0xff03,
- 0xff05, 0xff0a,
- 0xff0c, 0xff0f,
- 0xff1a, 0xff1b,
- 0xff1f, 0xff20,
- 0xff3b, 0xff3d,
- 0xff3f, 0xff3f,
- 0xff5b, 0xff5b,
- 0xff5d, 0xff5d,
- 0xff5f, 0xff65,
- 0x10100, 0x10102,
- 0x1039f, 0x1039f,
- 0x103d0, 0x103d0,
- 0x1056f, 0x1056f,
- 0x10857, 0x10857,
- 0x1091f, 0x1091f,
- 0x1093f, 0x1093f,
- 0x10a50, 0x10a58,
- 0x10a7f, 0x10a7f,
- 0x10af0, 0x10af6,
- 0x10b39, 0x10b3f,
- 0x10b99, 0x10b9c,
- 0x11047, 0x1104d,
- 0x110bb, 0x110bc,
- 0x110be, 0x110c1,
- 0x11140, 0x11143,
- 0x11174, 0x11175,
- 0x111c5, 0x111c9,
- 0x111cd, 0x111cd,
- 0x111db, 0x111db,
- 0x111dd, 0x111df,
- 0x11238, 0x1123d,
- 0x112a9, 0x112a9,
- 0x1144b, 0x1144f,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x114c6, 0x114c6,
- 0x115c1, 0x115d7,
- 0x11641, 0x11643,
- 0x11660, 0x1166c,
- 0x1173c, 0x1173e,
- 0x11a3f, 0x11a46,
- 0x11a9a, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11c41, 0x11c45,
- 0x11c70, 0x11c71,
- 0x12470, 0x12474,
- 0x16a6e, 0x16a6f,
- 0x16af5, 0x16af5,
- 0x16b37, 0x16b3b,
- 0x16b44, 0x16b44,
- 0x1bc9f, 0x1bc9f,
- 0x1da87, 0x1da8b,
- 0x1e95e, 0x1e95f,
-}; /* CR_Punct */
-
-#ifdef USE_UNICODE_PROPERTIES
-/* 'Any': - */
-static const OnigCodePoint CR_Any[] = {
- 1,
- 0x0000, 0x10ffff,
-}; /* CR_Any */
-
-/* 'Assigned': - */
-static const OnigCodePoint CR_Assigned[] = {
- 649,
- 0x0000, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fd,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4f,
- 0x0d54, 0x0d63,
- 0x0d66, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c88,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf9,
- 0x1d00, 0x1df9,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20bf,
- 0x20d0, 0x20f0,
- 0x2100, 0x218b,
- 0x2190, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e49,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fea,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa6f7,
- 0xa700, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c5,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fd,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab65,
- 0xab70, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xfffd,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102fb,
- 0x10300, 0x10323,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11150, 0x11176,
- 0x11180, 0x111cd,
- 0x111d0, 0x111df,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x11459,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115dd,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
- 0x11660, 0x1166c,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x1173f,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a47,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c45,
- 0x11c50, 0x11c6c,
- 0x11c70, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1e8,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1da8b,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1e95e, 0x1e95f,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xf0000, 0xffffd,
- 0x100000, 0x10fffd,
-}; /* CR_Assigned */
-
-/* 'C': Major Category */
-static const OnigCodePoint CR_C[] = {
- 653,
- 0x0000, 0x001f,
- 0x007f, 0x009f,
- 0x00ad, 0x00ad,
- 0x0378, 0x0379,
- 0x0380, 0x0383,
- 0x038b, 0x038b,
- 0x038d, 0x038d,
- 0x03a2, 0x03a2,
- 0x0530, 0x0530,
- 0x0557, 0x0558,
- 0x0560, 0x0560,
- 0x0588, 0x0588,
- 0x058b, 0x058c,
- 0x0590, 0x0590,
- 0x05c8, 0x05cf,
- 0x05eb, 0x05ef,
- 0x05f5, 0x0605,
- 0x061c, 0x061d,
- 0x06dd, 0x06dd,
- 0x070e, 0x070f,
- 0x074b, 0x074c,
- 0x07b2, 0x07bf,
- 0x07fb, 0x07ff,
- 0x082e, 0x082f,
- 0x083f, 0x083f,
- 0x085c, 0x085d,
- 0x085f, 0x085f,
- 0x086b, 0x089f,
- 0x08b5, 0x08b5,
- 0x08be, 0x08d3,
- 0x08e2, 0x08e2,
- 0x0984, 0x0984,
- 0x098d, 0x098e,
- 0x0991, 0x0992,
- 0x09a9, 0x09a9,
- 0x09b1, 0x09b1,
- 0x09b3, 0x09b5,
- 0x09ba, 0x09bb,
- 0x09c5, 0x09c6,
- 0x09c9, 0x09ca,
- 0x09cf, 0x09d6,
- 0x09d8, 0x09db,
- 0x09de, 0x09de,
- 0x09e4, 0x09e5,
- 0x09fe, 0x0a00,
- 0x0a04, 0x0a04,
- 0x0a0b, 0x0a0e,
- 0x0a11, 0x0a12,
- 0x0a29, 0x0a29,
- 0x0a31, 0x0a31,
- 0x0a34, 0x0a34,
- 0x0a37, 0x0a37,
- 0x0a3a, 0x0a3b,
- 0x0a3d, 0x0a3d,
- 0x0a43, 0x0a46,
- 0x0a49, 0x0a4a,
- 0x0a4e, 0x0a50,
- 0x0a52, 0x0a58,
- 0x0a5d, 0x0a5d,
- 0x0a5f, 0x0a65,
- 0x0a76, 0x0a80,
- 0x0a84, 0x0a84,
- 0x0a8e, 0x0a8e,
- 0x0a92, 0x0a92,
- 0x0aa9, 0x0aa9,
- 0x0ab1, 0x0ab1,
- 0x0ab4, 0x0ab4,
- 0x0aba, 0x0abb,
- 0x0ac6, 0x0ac6,
- 0x0aca, 0x0aca,
- 0x0ace, 0x0acf,
- 0x0ad1, 0x0adf,
- 0x0ae4, 0x0ae5,
- 0x0af2, 0x0af8,
- 0x0b00, 0x0b00,
- 0x0b04, 0x0b04,
- 0x0b0d, 0x0b0e,
- 0x0b11, 0x0b12,
- 0x0b29, 0x0b29,
- 0x0b31, 0x0b31,
- 0x0b34, 0x0b34,
- 0x0b3a, 0x0b3b,
- 0x0b45, 0x0b46,
- 0x0b49, 0x0b4a,
- 0x0b4e, 0x0b55,
- 0x0b58, 0x0b5b,
- 0x0b5e, 0x0b5e,
- 0x0b64, 0x0b65,
- 0x0b78, 0x0b81,
- 0x0b84, 0x0b84,
- 0x0b8b, 0x0b8d,
- 0x0b91, 0x0b91,
- 0x0b96, 0x0b98,
- 0x0b9b, 0x0b9b,
- 0x0b9d, 0x0b9d,
- 0x0ba0, 0x0ba2,
- 0x0ba5, 0x0ba7,
- 0x0bab, 0x0bad,
- 0x0bba, 0x0bbd,
- 0x0bc3, 0x0bc5,
- 0x0bc9, 0x0bc9,
- 0x0bce, 0x0bcf,
- 0x0bd1, 0x0bd6,
- 0x0bd8, 0x0be5,
- 0x0bfb, 0x0bff,
- 0x0c04, 0x0c04,
- 0x0c0d, 0x0c0d,
- 0x0c11, 0x0c11,
- 0x0c29, 0x0c29,
- 0x0c3a, 0x0c3c,
- 0x0c45, 0x0c45,
- 0x0c49, 0x0c49,
- 0x0c4e, 0x0c54,
- 0x0c57, 0x0c57,
- 0x0c5b, 0x0c5f,
- 0x0c64, 0x0c65,
- 0x0c70, 0x0c77,
- 0x0c84, 0x0c84,
- 0x0c8d, 0x0c8d,
- 0x0c91, 0x0c91,
- 0x0ca9, 0x0ca9,
- 0x0cb4, 0x0cb4,
- 0x0cba, 0x0cbb,
- 0x0cc5, 0x0cc5,
- 0x0cc9, 0x0cc9,
- 0x0cce, 0x0cd4,
- 0x0cd7, 0x0cdd,
- 0x0cdf, 0x0cdf,
- 0x0ce4, 0x0ce5,
- 0x0cf0, 0x0cf0,
- 0x0cf3, 0x0cff,
- 0x0d04, 0x0d04,
- 0x0d0d, 0x0d0d,
- 0x0d11, 0x0d11,
- 0x0d45, 0x0d45,
- 0x0d49, 0x0d49,
- 0x0d50, 0x0d53,
- 0x0d64, 0x0d65,
- 0x0d80, 0x0d81,
- 0x0d84, 0x0d84,
- 0x0d97, 0x0d99,
- 0x0db2, 0x0db2,
- 0x0dbc, 0x0dbc,
- 0x0dbe, 0x0dbf,
- 0x0dc7, 0x0dc9,
- 0x0dcb, 0x0dce,
- 0x0dd5, 0x0dd5,
- 0x0dd7, 0x0dd7,
- 0x0de0, 0x0de5,
- 0x0df0, 0x0df1,
- 0x0df5, 0x0e00,
- 0x0e3b, 0x0e3e,
- 0x0e5c, 0x0e80,
- 0x0e83, 0x0e83,
- 0x0e85, 0x0e86,
- 0x0e89, 0x0e89,
- 0x0e8b, 0x0e8c,
- 0x0e8e, 0x0e93,
- 0x0e98, 0x0e98,
- 0x0ea0, 0x0ea0,
- 0x0ea4, 0x0ea4,
- 0x0ea6, 0x0ea6,
- 0x0ea8, 0x0ea9,
- 0x0eac, 0x0eac,
- 0x0eba, 0x0eba,
- 0x0ebe, 0x0ebf,
- 0x0ec5, 0x0ec5,
- 0x0ec7, 0x0ec7,
- 0x0ece, 0x0ecf,
- 0x0eda, 0x0edb,
- 0x0ee0, 0x0eff,
- 0x0f48, 0x0f48,
- 0x0f6d, 0x0f70,
- 0x0f98, 0x0f98,
- 0x0fbd, 0x0fbd,
- 0x0fcd, 0x0fcd,
- 0x0fdb, 0x0fff,
- 0x10c6, 0x10c6,
- 0x10c8, 0x10cc,
- 0x10ce, 0x10cf,
- 0x1249, 0x1249,
- 0x124e, 0x124f,
- 0x1257, 0x1257,
- 0x1259, 0x1259,
- 0x125e, 0x125f,
- 0x1289, 0x1289,
- 0x128e, 0x128f,
- 0x12b1, 0x12b1,
- 0x12b6, 0x12b7,
- 0x12bf, 0x12bf,
- 0x12c1, 0x12c1,
- 0x12c6, 0x12c7,
- 0x12d7, 0x12d7,
- 0x1311, 0x1311,
- 0x1316, 0x1317,
- 0x135b, 0x135c,
- 0x137d, 0x137f,
- 0x139a, 0x139f,
- 0x13f6, 0x13f7,
- 0x13fe, 0x13ff,
- 0x169d, 0x169f,
- 0x16f9, 0x16ff,
- 0x170d, 0x170d,
- 0x1715, 0x171f,
- 0x1737, 0x173f,
- 0x1754, 0x175f,
- 0x176d, 0x176d,
- 0x1771, 0x1771,
- 0x1774, 0x177f,
- 0x17de, 0x17df,
- 0x17ea, 0x17ef,
- 0x17fa, 0x17ff,
- 0x180e, 0x180f,
- 0x181a, 0x181f,
- 0x1878, 0x187f,
- 0x18ab, 0x18af,
- 0x18f6, 0x18ff,
- 0x191f, 0x191f,
- 0x192c, 0x192f,
- 0x193c, 0x193f,
- 0x1941, 0x1943,
- 0x196e, 0x196f,
- 0x1975, 0x197f,
- 0x19ac, 0x19af,
- 0x19ca, 0x19cf,
- 0x19db, 0x19dd,
- 0x1a1c, 0x1a1d,
- 0x1a5f, 0x1a5f,
- 0x1a7d, 0x1a7e,
- 0x1a8a, 0x1a8f,
- 0x1a9a, 0x1a9f,
- 0x1aae, 0x1aaf,
- 0x1abf, 0x1aff,
- 0x1b4c, 0x1b4f,
- 0x1b7d, 0x1b7f,
- 0x1bf4, 0x1bfb,
- 0x1c38, 0x1c3a,
- 0x1c4a, 0x1c4c,
- 0x1c89, 0x1cbf,
- 0x1cc8, 0x1ccf,
- 0x1cfa, 0x1cff,
- 0x1dfa, 0x1dfa,
- 0x1f16, 0x1f17,
- 0x1f1e, 0x1f1f,
- 0x1f46, 0x1f47,
- 0x1f4e, 0x1f4f,
- 0x1f58, 0x1f58,
- 0x1f5a, 0x1f5a,
- 0x1f5c, 0x1f5c,
- 0x1f5e, 0x1f5e,
- 0x1f7e, 0x1f7f,
- 0x1fb5, 0x1fb5,
- 0x1fc5, 0x1fc5,
- 0x1fd4, 0x1fd5,
- 0x1fdc, 0x1fdc,
- 0x1ff0, 0x1ff1,
- 0x1ff5, 0x1ff5,
- 0x1fff, 0x1fff,
- 0x200b, 0x200f,
- 0x202a, 0x202e,
- 0x2060, 0x206f,
- 0x2072, 0x2073,
- 0x208f, 0x208f,
- 0x209d, 0x209f,
- 0x20c0, 0x20cf,
- 0x20f1, 0x20ff,
- 0x218c, 0x218f,
- 0x2427, 0x243f,
- 0x244b, 0x245f,
- 0x2b74, 0x2b75,
- 0x2b96, 0x2b97,
- 0x2bba, 0x2bbc,
- 0x2bc9, 0x2bc9,
- 0x2bd3, 0x2beb,
- 0x2bf0, 0x2bff,
- 0x2c2f, 0x2c2f,
- 0x2c5f, 0x2c5f,
- 0x2cf4, 0x2cf8,
- 0x2d26, 0x2d26,
- 0x2d28, 0x2d2c,
- 0x2d2e, 0x2d2f,
- 0x2d68, 0x2d6e,
- 0x2d71, 0x2d7e,
- 0x2d97, 0x2d9f,
- 0x2da7, 0x2da7,
- 0x2daf, 0x2daf,
- 0x2db7, 0x2db7,
- 0x2dbf, 0x2dbf,
- 0x2dc7, 0x2dc7,
- 0x2dcf, 0x2dcf,
- 0x2dd7, 0x2dd7,
- 0x2ddf, 0x2ddf,
- 0x2e4a, 0x2e7f,
- 0x2e9a, 0x2e9a,
- 0x2ef4, 0x2eff,
- 0x2fd6, 0x2fef,
- 0x2ffc, 0x2fff,
- 0x3040, 0x3040,
- 0x3097, 0x3098,
- 0x3100, 0x3104,
- 0x312f, 0x3130,
- 0x318f, 0x318f,
- 0x31bb, 0x31bf,
- 0x31e4, 0x31ef,
- 0x321f, 0x321f,
- 0x32ff, 0x32ff,
- 0x4db6, 0x4dbf,
- 0x9feb, 0x9fff,
- 0xa48d, 0xa48f,
- 0xa4c7, 0xa4cf,
- 0xa62c, 0xa63f,
- 0xa6f8, 0xa6ff,
- 0xa7af, 0xa7af,
- 0xa7b8, 0xa7f6,
- 0xa82c, 0xa82f,
- 0xa83a, 0xa83f,
- 0xa878, 0xa87f,
- 0xa8c6, 0xa8cd,
- 0xa8da, 0xa8df,
- 0xa8fe, 0xa8ff,
- 0xa954, 0xa95e,
- 0xa97d, 0xa97f,
- 0xa9ce, 0xa9ce,
- 0xa9da, 0xa9dd,
- 0xa9ff, 0xa9ff,
- 0xaa37, 0xaa3f,
- 0xaa4e, 0xaa4f,
- 0xaa5a, 0xaa5b,
- 0xaac3, 0xaada,
- 0xaaf7, 0xab00,
- 0xab07, 0xab08,
- 0xab0f, 0xab10,
- 0xab17, 0xab1f,
- 0xab27, 0xab27,
- 0xab2f, 0xab2f,
- 0xab66, 0xab6f,
- 0xabee, 0xabef,
- 0xabfa, 0xabff,
- 0xd7a4, 0xd7af,
- 0xd7c7, 0xd7ca,
- 0xd7fc, 0xf8ff,
- 0xfa6e, 0xfa6f,
- 0xfada, 0xfaff,
- 0xfb07, 0xfb12,
- 0xfb18, 0xfb1c,
- 0xfb37, 0xfb37,
- 0xfb3d, 0xfb3d,
- 0xfb3f, 0xfb3f,
- 0xfb42, 0xfb42,
- 0xfb45, 0xfb45,
- 0xfbc2, 0xfbd2,
- 0xfd40, 0xfd4f,
- 0xfd90, 0xfd91,
- 0xfdc8, 0xfdef,
- 0xfdfe, 0xfdff,
- 0xfe1a, 0xfe1f,
- 0xfe53, 0xfe53,
- 0xfe67, 0xfe67,
- 0xfe6c, 0xfe6f,
- 0xfe75, 0xfe75,
- 0xfefd, 0xff00,
- 0xffbf, 0xffc1,
- 0xffc8, 0xffc9,
- 0xffd0, 0xffd1,
- 0xffd8, 0xffd9,
- 0xffdd, 0xffdf,
- 0xffe7, 0xffe7,
- 0xffef, 0xfffb,
- 0xfffe, 0xffff,
- 0x1000c, 0x1000c,
- 0x10027, 0x10027,
- 0x1003b, 0x1003b,
- 0x1003e, 0x1003e,
- 0x1004e, 0x1004f,
- 0x1005e, 0x1007f,
- 0x100fb, 0x100ff,
- 0x10103, 0x10106,
- 0x10134, 0x10136,
- 0x1018f, 0x1018f,
- 0x1019c, 0x1019f,
- 0x101a1, 0x101cf,
- 0x101fe, 0x1027f,
- 0x1029d, 0x1029f,
- 0x102d1, 0x102df,
- 0x102fc, 0x102ff,
- 0x10324, 0x1032c,
- 0x1034b, 0x1034f,
- 0x1037b, 0x1037f,
- 0x1039e, 0x1039e,
- 0x103c4, 0x103c7,
- 0x103d6, 0x103ff,
- 0x1049e, 0x1049f,
- 0x104aa, 0x104af,
- 0x104d4, 0x104d7,
- 0x104fc, 0x104ff,
- 0x10528, 0x1052f,
- 0x10564, 0x1056e,
- 0x10570, 0x105ff,
- 0x10737, 0x1073f,
- 0x10756, 0x1075f,
- 0x10768, 0x107ff,
- 0x10806, 0x10807,
- 0x10809, 0x10809,
- 0x10836, 0x10836,
- 0x10839, 0x1083b,
- 0x1083d, 0x1083e,
- 0x10856, 0x10856,
- 0x1089f, 0x108a6,
- 0x108b0, 0x108df,
- 0x108f3, 0x108f3,
- 0x108f6, 0x108fa,
- 0x1091c, 0x1091e,
- 0x1093a, 0x1093e,
- 0x10940, 0x1097f,
- 0x109b8, 0x109bb,
- 0x109d0, 0x109d1,
- 0x10a04, 0x10a04,
- 0x10a07, 0x10a0b,
- 0x10a14, 0x10a14,
- 0x10a18, 0x10a18,
- 0x10a34, 0x10a37,
- 0x10a3b, 0x10a3e,
- 0x10a48, 0x10a4f,
- 0x10a59, 0x10a5f,
- 0x10aa0, 0x10abf,
- 0x10ae7, 0x10aea,
- 0x10af7, 0x10aff,
- 0x10b36, 0x10b38,
- 0x10b56, 0x10b57,
- 0x10b73, 0x10b77,
- 0x10b92, 0x10b98,
- 0x10b9d, 0x10ba8,
- 0x10bb0, 0x10bff,
- 0x10c49, 0x10c7f,
- 0x10cb3, 0x10cbf,
- 0x10cf3, 0x10cf9,
- 0x10d00, 0x10e5f,
- 0x10e7f, 0x10fff,
- 0x1104e, 0x11051,
- 0x11070, 0x1107e,
- 0x110bd, 0x110bd,
- 0x110c2, 0x110cf,
- 0x110e9, 0x110ef,
- 0x110fa, 0x110ff,
- 0x11135, 0x11135,
- 0x11144, 0x1114f,
- 0x11177, 0x1117f,
- 0x111ce, 0x111cf,
- 0x111e0, 0x111e0,
- 0x111f5, 0x111ff,
- 0x11212, 0x11212,
- 0x1123f, 0x1127f,
- 0x11287, 0x11287,
- 0x11289, 0x11289,
- 0x1128e, 0x1128e,
- 0x1129e, 0x1129e,
- 0x112aa, 0x112af,
- 0x112eb, 0x112ef,
- 0x112fa, 0x112ff,
- 0x11304, 0x11304,
- 0x1130d, 0x1130e,
- 0x11311, 0x11312,
- 0x11329, 0x11329,
- 0x11331, 0x11331,
- 0x11334, 0x11334,
- 0x1133a, 0x1133b,
- 0x11345, 0x11346,
- 0x11349, 0x1134a,
- 0x1134e, 0x1134f,
- 0x11351, 0x11356,
- 0x11358, 0x1135c,
- 0x11364, 0x11365,
- 0x1136d, 0x1136f,
- 0x11375, 0x113ff,
- 0x1145a, 0x1145a,
- 0x1145c, 0x1145c,
- 0x1145e, 0x1147f,
- 0x114c8, 0x114cf,
- 0x114da, 0x1157f,
- 0x115b6, 0x115b7,
- 0x115de, 0x115ff,
- 0x11645, 0x1164f,
- 0x1165a, 0x1165f,
- 0x1166d, 0x1167f,
- 0x116b8, 0x116bf,
- 0x116ca, 0x116ff,
- 0x1171a, 0x1171c,
- 0x1172c, 0x1172f,
- 0x11740, 0x1189f,
- 0x118f3, 0x118fe,
- 0x11900, 0x119ff,
- 0x11a48, 0x11a4f,
- 0x11a84, 0x11a85,
- 0x11a9d, 0x11a9d,
- 0x11aa3, 0x11abf,
- 0x11af9, 0x11bff,
- 0x11c09, 0x11c09,
- 0x11c37, 0x11c37,
- 0x11c46, 0x11c4f,
- 0x11c6d, 0x11c6f,
- 0x11c90, 0x11c91,
- 0x11ca8, 0x11ca8,
- 0x11cb7, 0x11cff,
- 0x11d07, 0x11d07,
- 0x11d0a, 0x11d0a,
- 0x11d37, 0x11d39,
- 0x11d3b, 0x11d3b,
- 0x11d3e, 0x11d3e,
- 0x11d48, 0x11d4f,
- 0x11d5a, 0x11fff,
- 0x1239a, 0x123ff,
- 0x1246f, 0x1246f,
- 0x12475, 0x1247f,
- 0x12544, 0x12fff,
- 0x1342f, 0x143ff,
- 0x14647, 0x167ff,
- 0x16a39, 0x16a3f,
- 0x16a5f, 0x16a5f,
- 0x16a6a, 0x16a6d,
- 0x16a70, 0x16acf,
- 0x16aee, 0x16aef,
- 0x16af6, 0x16aff,
- 0x16b46, 0x16b4f,
- 0x16b5a, 0x16b5a,
- 0x16b62, 0x16b62,
- 0x16b78, 0x16b7c,
- 0x16b90, 0x16eff,
- 0x16f45, 0x16f4f,
- 0x16f7f, 0x16f8e,
- 0x16fa0, 0x16fdf,
- 0x16fe2, 0x16fff,
- 0x187ed, 0x187ff,
- 0x18af3, 0x1afff,
- 0x1b11f, 0x1b16f,
- 0x1b2fc, 0x1bbff,
- 0x1bc6b, 0x1bc6f,
- 0x1bc7d, 0x1bc7f,
- 0x1bc89, 0x1bc8f,
- 0x1bc9a, 0x1bc9b,
- 0x1bca0, 0x1cfff,
- 0x1d0f6, 0x1d0ff,
- 0x1d127, 0x1d128,
- 0x1d173, 0x1d17a,
- 0x1d1e9, 0x1d1ff,
- 0x1d246, 0x1d2ff,
- 0x1d357, 0x1d35f,
- 0x1d372, 0x1d3ff,
- 0x1d455, 0x1d455,
- 0x1d49d, 0x1d49d,
- 0x1d4a0, 0x1d4a1,
- 0x1d4a3, 0x1d4a4,
- 0x1d4a7, 0x1d4a8,
- 0x1d4ad, 0x1d4ad,
- 0x1d4ba, 0x1d4ba,
- 0x1d4bc, 0x1d4bc,
- 0x1d4c4, 0x1d4c4,
- 0x1d506, 0x1d506,
- 0x1d50b, 0x1d50c,
- 0x1d515, 0x1d515,
- 0x1d51d, 0x1d51d,
- 0x1d53a, 0x1d53a,
- 0x1d53f, 0x1d53f,
- 0x1d545, 0x1d545,
- 0x1d547, 0x1d549,
- 0x1d551, 0x1d551,
- 0x1d6a6, 0x1d6a7,
- 0x1d7cc, 0x1d7cd,
- 0x1da8c, 0x1da9a,
- 0x1daa0, 0x1daa0,
- 0x1dab0, 0x1dfff,
- 0x1e007, 0x1e007,
- 0x1e019, 0x1e01a,
- 0x1e022, 0x1e022,
- 0x1e025, 0x1e025,
- 0x1e02b, 0x1e7ff,
- 0x1e8c5, 0x1e8c6,
- 0x1e8d7, 0x1e8ff,
- 0x1e94b, 0x1e94f,
- 0x1e95a, 0x1e95d,
- 0x1e960, 0x1edff,
- 0x1ee04, 0x1ee04,
- 0x1ee20, 0x1ee20,
- 0x1ee23, 0x1ee23,
- 0x1ee25, 0x1ee26,
- 0x1ee28, 0x1ee28,
- 0x1ee33, 0x1ee33,
- 0x1ee38, 0x1ee38,
- 0x1ee3a, 0x1ee3a,
- 0x1ee3c, 0x1ee41,
- 0x1ee43, 0x1ee46,
- 0x1ee48, 0x1ee48,
- 0x1ee4a, 0x1ee4a,
- 0x1ee4c, 0x1ee4c,
- 0x1ee50, 0x1ee50,
- 0x1ee53, 0x1ee53,
- 0x1ee55, 0x1ee56,
- 0x1ee58, 0x1ee58,
- 0x1ee5a, 0x1ee5a,
- 0x1ee5c, 0x1ee5c,
- 0x1ee5e, 0x1ee5e,
- 0x1ee60, 0x1ee60,
- 0x1ee63, 0x1ee63,
- 0x1ee65, 0x1ee66,
- 0x1ee6b, 0x1ee6b,
- 0x1ee73, 0x1ee73,
- 0x1ee78, 0x1ee78,
- 0x1ee7d, 0x1ee7d,
- 0x1ee7f, 0x1ee7f,
- 0x1ee8a, 0x1ee8a,
- 0x1ee9c, 0x1eea0,
- 0x1eea4, 0x1eea4,
- 0x1eeaa, 0x1eeaa,
- 0x1eebc, 0x1eeef,
- 0x1eef2, 0x1efff,
- 0x1f02c, 0x1f02f,
- 0x1f094, 0x1f09f,
- 0x1f0af, 0x1f0b0,
- 0x1f0c0, 0x1f0c0,
- 0x1f0d0, 0x1f0d0,
- 0x1f0f6, 0x1f0ff,
- 0x1f10d, 0x1f10f,
- 0x1f12f, 0x1f12f,
- 0x1f16c, 0x1f16f,
- 0x1f1ad, 0x1f1e5,
- 0x1f203, 0x1f20f,
- 0x1f23c, 0x1f23f,
- 0x1f249, 0x1f24f,
- 0x1f252, 0x1f25f,
- 0x1f266, 0x1f2ff,
- 0x1f6d5, 0x1f6df,
- 0x1f6ed, 0x1f6ef,
- 0x1f6f9, 0x1f6ff,
- 0x1f774, 0x1f77f,
- 0x1f7d5, 0x1f7ff,
- 0x1f80c, 0x1f80f,
- 0x1f848, 0x1f84f,
- 0x1f85a, 0x1f85f,
- 0x1f888, 0x1f88f,
- 0x1f8ae, 0x1f8ff,
- 0x1f90c, 0x1f90f,
- 0x1f93f, 0x1f93f,
- 0x1f94d, 0x1f94f,
- 0x1f96c, 0x1f97f,
- 0x1f998, 0x1f9bf,
- 0x1f9c1, 0x1f9cf,
- 0x1f9e7, 0x1ffff,
- 0x2a6d7, 0x2a6ff,
- 0x2b735, 0x2b73f,
- 0x2b81e, 0x2b81f,
- 0x2cea2, 0x2ceaf,
- 0x2ebe1, 0x2f7ff,
- 0x2fa1e, 0xe00ff,
- 0xe01f0, 0x10ffff,
-}; /* CR_C */
-
-/* 'Cc': General Category */
-#define CR_Cc CR_Cntrl
-
-/* 'Cf': General Category */
-static const OnigCodePoint CR_Cf[] = {
- 18,
- 0x00ad, 0x00ad,
- 0x0600, 0x0605,
- 0x061c, 0x061c,
- 0x06dd, 0x06dd,
- 0x070f, 0x070f,
- 0x08e2, 0x08e2,
- 0x180e, 0x180e,
- 0x200b, 0x200f,
- 0x202a, 0x202e,
- 0x2060, 0x2064,
- 0x2066, 0x206f,
- 0xfeff, 0xfeff,
- 0xfff9, 0xfffb,
- 0x110bd, 0x110bd,
- 0x1bca0, 0x1bca3,
- 0x1d173, 0x1d17a,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
-}; /* CR_Cf */
-
-/* 'Cn': General Category */
-static const OnigCodePoint CR_Cn[] = {
- 649,
- 0x0378, 0x0379,
- 0x0380, 0x0383,
- 0x038b, 0x038b,
- 0x038d, 0x038d,
- 0x03a2, 0x03a2,
- 0x0530, 0x0530,
- 0x0557, 0x0558,
- 0x0560, 0x0560,
- 0x0588, 0x0588,
- 0x058b, 0x058c,
- 0x0590, 0x0590,
- 0x05c8, 0x05cf,
- 0x05eb, 0x05ef,
- 0x05f5, 0x05ff,
- 0x061d, 0x061d,
- 0x070e, 0x070e,
- 0x074b, 0x074c,
- 0x07b2, 0x07bf,
- 0x07fb, 0x07ff,
- 0x082e, 0x082f,
- 0x083f, 0x083f,
- 0x085c, 0x085d,
- 0x085f, 0x085f,
- 0x086b, 0x089f,
- 0x08b5, 0x08b5,
- 0x08be, 0x08d3,
- 0x0984, 0x0984,
- 0x098d, 0x098e,
- 0x0991, 0x0992,
- 0x09a9, 0x09a9,
- 0x09b1, 0x09b1,
- 0x09b3, 0x09b5,
- 0x09ba, 0x09bb,
- 0x09c5, 0x09c6,
- 0x09c9, 0x09ca,
- 0x09cf, 0x09d6,
- 0x09d8, 0x09db,
- 0x09de, 0x09de,
- 0x09e4, 0x09e5,
- 0x09fe, 0x0a00,
- 0x0a04, 0x0a04,
- 0x0a0b, 0x0a0e,
- 0x0a11, 0x0a12,
- 0x0a29, 0x0a29,
- 0x0a31, 0x0a31,
- 0x0a34, 0x0a34,
- 0x0a37, 0x0a37,
- 0x0a3a, 0x0a3b,
- 0x0a3d, 0x0a3d,
- 0x0a43, 0x0a46,
- 0x0a49, 0x0a4a,
- 0x0a4e, 0x0a50,
- 0x0a52, 0x0a58,
- 0x0a5d, 0x0a5d,
- 0x0a5f, 0x0a65,
- 0x0a76, 0x0a80,
- 0x0a84, 0x0a84,
- 0x0a8e, 0x0a8e,
- 0x0a92, 0x0a92,
- 0x0aa9, 0x0aa9,
- 0x0ab1, 0x0ab1,
- 0x0ab4, 0x0ab4,
- 0x0aba, 0x0abb,
- 0x0ac6, 0x0ac6,
- 0x0aca, 0x0aca,
- 0x0ace, 0x0acf,
- 0x0ad1, 0x0adf,
- 0x0ae4, 0x0ae5,
- 0x0af2, 0x0af8,
- 0x0b00, 0x0b00,
- 0x0b04, 0x0b04,
- 0x0b0d, 0x0b0e,
- 0x0b11, 0x0b12,
- 0x0b29, 0x0b29,
- 0x0b31, 0x0b31,
- 0x0b34, 0x0b34,
- 0x0b3a, 0x0b3b,
- 0x0b45, 0x0b46,
- 0x0b49, 0x0b4a,
- 0x0b4e, 0x0b55,
- 0x0b58, 0x0b5b,
- 0x0b5e, 0x0b5e,
- 0x0b64, 0x0b65,
- 0x0b78, 0x0b81,
- 0x0b84, 0x0b84,
- 0x0b8b, 0x0b8d,
- 0x0b91, 0x0b91,
- 0x0b96, 0x0b98,
- 0x0b9b, 0x0b9b,
- 0x0b9d, 0x0b9d,
- 0x0ba0, 0x0ba2,
- 0x0ba5, 0x0ba7,
- 0x0bab, 0x0bad,
- 0x0bba, 0x0bbd,
- 0x0bc3, 0x0bc5,
- 0x0bc9, 0x0bc9,
- 0x0bce, 0x0bcf,
- 0x0bd1, 0x0bd6,
- 0x0bd8, 0x0be5,
- 0x0bfb, 0x0bff,
- 0x0c04, 0x0c04,
- 0x0c0d, 0x0c0d,
- 0x0c11, 0x0c11,
- 0x0c29, 0x0c29,
- 0x0c3a, 0x0c3c,
- 0x0c45, 0x0c45,
- 0x0c49, 0x0c49,
- 0x0c4e, 0x0c54,
- 0x0c57, 0x0c57,
- 0x0c5b, 0x0c5f,
- 0x0c64, 0x0c65,
- 0x0c70, 0x0c77,
- 0x0c84, 0x0c84,
- 0x0c8d, 0x0c8d,
- 0x0c91, 0x0c91,
- 0x0ca9, 0x0ca9,
- 0x0cb4, 0x0cb4,
- 0x0cba, 0x0cbb,
- 0x0cc5, 0x0cc5,
- 0x0cc9, 0x0cc9,
- 0x0cce, 0x0cd4,
- 0x0cd7, 0x0cdd,
- 0x0cdf, 0x0cdf,
- 0x0ce4, 0x0ce5,
- 0x0cf0, 0x0cf0,
- 0x0cf3, 0x0cff,
- 0x0d04, 0x0d04,
- 0x0d0d, 0x0d0d,
- 0x0d11, 0x0d11,
- 0x0d45, 0x0d45,
- 0x0d49, 0x0d49,
- 0x0d50, 0x0d53,
- 0x0d64, 0x0d65,
- 0x0d80, 0x0d81,
- 0x0d84, 0x0d84,
- 0x0d97, 0x0d99,
- 0x0db2, 0x0db2,
- 0x0dbc, 0x0dbc,
- 0x0dbe, 0x0dbf,
- 0x0dc7, 0x0dc9,
- 0x0dcb, 0x0dce,
- 0x0dd5, 0x0dd5,
- 0x0dd7, 0x0dd7,
- 0x0de0, 0x0de5,
- 0x0df0, 0x0df1,
- 0x0df5, 0x0e00,
- 0x0e3b, 0x0e3e,
- 0x0e5c, 0x0e80,
- 0x0e83, 0x0e83,
- 0x0e85, 0x0e86,
- 0x0e89, 0x0e89,
- 0x0e8b, 0x0e8c,
- 0x0e8e, 0x0e93,
- 0x0e98, 0x0e98,
- 0x0ea0, 0x0ea0,
- 0x0ea4, 0x0ea4,
- 0x0ea6, 0x0ea6,
- 0x0ea8, 0x0ea9,
- 0x0eac, 0x0eac,
- 0x0eba, 0x0eba,
- 0x0ebe, 0x0ebf,
- 0x0ec5, 0x0ec5,
- 0x0ec7, 0x0ec7,
- 0x0ece, 0x0ecf,
- 0x0eda, 0x0edb,
- 0x0ee0, 0x0eff,
- 0x0f48, 0x0f48,
- 0x0f6d, 0x0f70,
- 0x0f98, 0x0f98,
- 0x0fbd, 0x0fbd,
- 0x0fcd, 0x0fcd,
- 0x0fdb, 0x0fff,
- 0x10c6, 0x10c6,
- 0x10c8, 0x10cc,
- 0x10ce, 0x10cf,
- 0x1249, 0x1249,
- 0x124e, 0x124f,
- 0x1257, 0x1257,
- 0x1259, 0x1259,
- 0x125e, 0x125f,
- 0x1289, 0x1289,
- 0x128e, 0x128f,
- 0x12b1, 0x12b1,
- 0x12b6, 0x12b7,
- 0x12bf, 0x12bf,
- 0x12c1, 0x12c1,
- 0x12c6, 0x12c7,
- 0x12d7, 0x12d7,
- 0x1311, 0x1311,
- 0x1316, 0x1317,
- 0x135b, 0x135c,
- 0x137d, 0x137f,
- 0x139a, 0x139f,
- 0x13f6, 0x13f7,
- 0x13fe, 0x13ff,
- 0x169d, 0x169f,
- 0x16f9, 0x16ff,
- 0x170d, 0x170d,
- 0x1715, 0x171f,
- 0x1737, 0x173f,
- 0x1754, 0x175f,
- 0x176d, 0x176d,
- 0x1771, 0x1771,
- 0x1774, 0x177f,
- 0x17de, 0x17df,
- 0x17ea, 0x17ef,
- 0x17fa, 0x17ff,
- 0x180f, 0x180f,
- 0x181a, 0x181f,
- 0x1878, 0x187f,
- 0x18ab, 0x18af,
- 0x18f6, 0x18ff,
- 0x191f, 0x191f,
- 0x192c, 0x192f,
- 0x193c, 0x193f,
- 0x1941, 0x1943,
- 0x196e, 0x196f,
- 0x1975, 0x197f,
- 0x19ac, 0x19af,
- 0x19ca, 0x19cf,
- 0x19db, 0x19dd,
- 0x1a1c, 0x1a1d,
- 0x1a5f, 0x1a5f,
- 0x1a7d, 0x1a7e,
- 0x1a8a, 0x1a8f,
- 0x1a9a, 0x1a9f,
- 0x1aae, 0x1aaf,
- 0x1abf, 0x1aff,
- 0x1b4c, 0x1b4f,
- 0x1b7d, 0x1b7f,
- 0x1bf4, 0x1bfb,
- 0x1c38, 0x1c3a,
- 0x1c4a, 0x1c4c,
- 0x1c89, 0x1cbf,
- 0x1cc8, 0x1ccf,
- 0x1cfa, 0x1cff,
- 0x1dfa, 0x1dfa,
- 0x1f16, 0x1f17,
- 0x1f1e, 0x1f1f,
- 0x1f46, 0x1f47,
- 0x1f4e, 0x1f4f,
- 0x1f58, 0x1f58,
- 0x1f5a, 0x1f5a,
- 0x1f5c, 0x1f5c,
- 0x1f5e, 0x1f5e,
- 0x1f7e, 0x1f7f,
- 0x1fb5, 0x1fb5,
- 0x1fc5, 0x1fc5,
- 0x1fd4, 0x1fd5,
- 0x1fdc, 0x1fdc,
- 0x1ff0, 0x1ff1,
- 0x1ff5, 0x1ff5,
- 0x1fff, 0x1fff,
- 0x2065, 0x2065,
- 0x2072, 0x2073,
- 0x208f, 0x208f,
- 0x209d, 0x209f,
- 0x20c0, 0x20cf,
- 0x20f1, 0x20ff,
- 0x218c, 0x218f,
- 0x2427, 0x243f,
- 0x244b, 0x245f,
- 0x2b74, 0x2b75,
- 0x2b96, 0x2b97,
- 0x2bba, 0x2bbc,
- 0x2bc9, 0x2bc9,
- 0x2bd3, 0x2beb,
- 0x2bf0, 0x2bff,
- 0x2c2f, 0x2c2f,
- 0x2c5f, 0x2c5f,
- 0x2cf4, 0x2cf8,
- 0x2d26, 0x2d26,
- 0x2d28, 0x2d2c,
- 0x2d2e, 0x2d2f,
- 0x2d68, 0x2d6e,
- 0x2d71, 0x2d7e,
- 0x2d97, 0x2d9f,
- 0x2da7, 0x2da7,
- 0x2daf, 0x2daf,
- 0x2db7, 0x2db7,
- 0x2dbf, 0x2dbf,
- 0x2dc7, 0x2dc7,
- 0x2dcf, 0x2dcf,
- 0x2dd7, 0x2dd7,
- 0x2ddf, 0x2ddf,
- 0x2e4a, 0x2e7f,
- 0x2e9a, 0x2e9a,
- 0x2ef4, 0x2eff,
- 0x2fd6, 0x2fef,
- 0x2ffc, 0x2fff,
- 0x3040, 0x3040,
- 0x3097, 0x3098,
- 0x3100, 0x3104,
- 0x312f, 0x3130,
- 0x318f, 0x318f,
- 0x31bb, 0x31bf,
- 0x31e4, 0x31ef,
- 0x321f, 0x321f,
- 0x32ff, 0x32ff,
- 0x4db6, 0x4dbf,
- 0x9feb, 0x9fff,
- 0xa48d, 0xa48f,
- 0xa4c7, 0xa4cf,
- 0xa62c, 0xa63f,
- 0xa6f8, 0xa6ff,
- 0xa7af, 0xa7af,
- 0xa7b8, 0xa7f6,
- 0xa82c, 0xa82f,
- 0xa83a, 0xa83f,
- 0xa878, 0xa87f,
- 0xa8c6, 0xa8cd,
- 0xa8da, 0xa8df,
- 0xa8fe, 0xa8ff,
- 0xa954, 0xa95e,
- 0xa97d, 0xa97f,
- 0xa9ce, 0xa9ce,
- 0xa9da, 0xa9dd,
- 0xa9ff, 0xa9ff,
- 0xaa37, 0xaa3f,
- 0xaa4e, 0xaa4f,
- 0xaa5a, 0xaa5b,
- 0xaac3, 0xaada,
- 0xaaf7, 0xab00,
- 0xab07, 0xab08,
- 0xab0f, 0xab10,
- 0xab17, 0xab1f,
- 0xab27, 0xab27,
- 0xab2f, 0xab2f,
- 0xab66, 0xab6f,
- 0xabee, 0xabef,
- 0xabfa, 0xabff,
- 0xd7a4, 0xd7af,
- 0xd7c7, 0xd7ca,
- 0xd7fc, 0xd7ff,
- 0xfa6e, 0xfa6f,
- 0xfada, 0xfaff,
- 0xfb07, 0xfb12,
- 0xfb18, 0xfb1c,
- 0xfb37, 0xfb37,
- 0xfb3d, 0xfb3d,
- 0xfb3f, 0xfb3f,
- 0xfb42, 0xfb42,
- 0xfb45, 0xfb45,
- 0xfbc2, 0xfbd2,
- 0xfd40, 0xfd4f,
- 0xfd90, 0xfd91,
- 0xfdc8, 0xfdef,
- 0xfdfe, 0xfdff,
- 0xfe1a, 0xfe1f,
- 0xfe53, 0xfe53,
- 0xfe67, 0xfe67,
- 0xfe6c, 0xfe6f,
- 0xfe75, 0xfe75,
- 0xfefd, 0xfefe,
- 0xff00, 0xff00,
- 0xffbf, 0xffc1,
- 0xffc8, 0xffc9,
- 0xffd0, 0xffd1,
- 0xffd8, 0xffd9,
- 0xffdd, 0xffdf,
- 0xffe7, 0xffe7,
- 0xffef, 0xfff8,
- 0xfffe, 0xffff,
- 0x1000c, 0x1000c,
- 0x10027, 0x10027,
- 0x1003b, 0x1003b,
- 0x1003e, 0x1003e,
- 0x1004e, 0x1004f,
- 0x1005e, 0x1007f,
- 0x100fb, 0x100ff,
- 0x10103, 0x10106,
- 0x10134, 0x10136,
- 0x1018f, 0x1018f,
- 0x1019c, 0x1019f,
- 0x101a1, 0x101cf,
- 0x101fe, 0x1027f,
- 0x1029d, 0x1029f,
- 0x102d1, 0x102df,
- 0x102fc, 0x102ff,
- 0x10324, 0x1032c,
- 0x1034b, 0x1034f,
- 0x1037b, 0x1037f,
- 0x1039e, 0x1039e,
- 0x103c4, 0x103c7,
- 0x103d6, 0x103ff,
- 0x1049e, 0x1049f,
- 0x104aa, 0x104af,
- 0x104d4, 0x104d7,
- 0x104fc, 0x104ff,
- 0x10528, 0x1052f,
- 0x10564, 0x1056e,
- 0x10570, 0x105ff,
- 0x10737, 0x1073f,
- 0x10756, 0x1075f,
- 0x10768, 0x107ff,
- 0x10806, 0x10807,
- 0x10809, 0x10809,
- 0x10836, 0x10836,
- 0x10839, 0x1083b,
- 0x1083d, 0x1083e,
- 0x10856, 0x10856,
- 0x1089f, 0x108a6,
- 0x108b0, 0x108df,
- 0x108f3, 0x108f3,
- 0x108f6, 0x108fa,
- 0x1091c, 0x1091e,
- 0x1093a, 0x1093e,
- 0x10940, 0x1097f,
- 0x109b8, 0x109bb,
- 0x109d0, 0x109d1,
- 0x10a04, 0x10a04,
- 0x10a07, 0x10a0b,
- 0x10a14, 0x10a14,
- 0x10a18, 0x10a18,
- 0x10a34, 0x10a37,
- 0x10a3b, 0x10a3e,
- 0x10a48, 0x10a4f,
- 0x10a59, 0x10a5f,
- 0x10aa0, 0x10abf,
- 0x10ae7, 0x10aea,
- 0x10af7, 0x10aff,
- 0x10b36, 0x10b38,
- 0x10b56, 0x10b57,
- 0x10b73, 0x10b77,
- 0x10b92, 0x10b98,
- 0x10b9d, 0x10ba8,
- 0x10bb0, 0x10bff,
- 0x10c49, 0x10c7f,
- 0x10cb3, 0x10cbf,
- 0x10cf3, 0x10cf9,
- 0x10d00, 0x10e5f,
- 0x10e7f, 0x10fff,
- 0x1104e, 0x11051,
- 0x11070, 0x1107e,
- 0x110c2, 0x110cf,
- 0x110e9, 0x110ef,
- 0x110fa, 0x110ff,
- 0x11135, 0x11135,
- 0x11144, 0x1114f,
- 0x11177, 0x1117f,
- 0x111ce, 0x111cf,
- 0x111e0, 0x111e0,
- 0x111f5, 0x111ff,
- 0x11212, 0x11212,
- 0x1123f, 0x1127f,
- 0x11287, 0x11287,
- 0x11289, 0x11289,
- 0x1128e, 0x1128e,
- 0x1129e, 0x1129e,
- 0x112aa, 0x112af,
- 0x112eb, 0x112ef,
- 0x112fa, 0x112ff,
- 0x11304, 0x11304,
- 0x1130d, 0x1130e,
- 0x11311, 0x11312,
- 0x11329, 0x11329,
- 0x11331, 0x11331,
- 0x11334, 0x11334,
- 0x1133a, 0x1133b,
- 0x11345, 0x11346,
- 0x11349, 0x1134a,
- 0x1134e, 0x1134f,
- 0x11351, 0x11356,
- 0x11358, 0x1135c,
- 0x11364, 0x11365,
- 0x1136d, 0x1136f,
- 0x11375, 0x113ff,
- 0x1145a, 0x1145a,
- 0x1145c, 0x1145c,
- 0x1145e, 0x1147f,
- 0x114c8, 0x114cf,
- 0x114da, 0x1157f,
- 0x115b6, 0x115b7,
- 0x115de, 0x115ff,
- 0x11645, 0x1164f,
- 0x1165a, 0x1165f,
- 0x1166d, 0x1167f,
- 0x116b8, 0x116bf,
- 0x116ca, 0x116ff,
- 0x1171a, 0x1171c,
- 0x1172c, 0x1172f,
- 0x11740, 0x1189f,
- 0x118f3, 0x118fe,
- 0x11900, 0x119ff,
- 0x11a48, 0x11a4f,
- 0x11a84, 0x11a85,
- 0x11a9d, 0x11a9d,
- 0x11aa3, 0x11abf,
- 0x11af9, 0x11bff,
- 0x11c09, 0x11c09,
- 0x11c37, 0x11c37,
- 0x11c46, 0x11c4f,
- 0x11c6d, 0x11c6f,
- 0x11c90, 0x11c91,
- 0x11ca8, 0x11ca8,
- 0x11cb7, 0x11cff,
- 0x11d07, 0x11d07,
- 0x11d0a, 0x11d0a,
- 0x11d37, 0x11d39,
- 0x11d3b, 0x11d3b,
- 0x11d3e, 0x11d3e,
- 0x11d48, 0x11d4f,
- 0x11d5a, 0x11fff,
- 0x1239a, 0x123ff,
- 0x1246f, 0x1246f,
- 0x12475, 0x1247f,
- 0x12544, 0x12fff,
- 0x1342f, 0x143ff,
- 0x14647, 0x167ff,
- 0x16a39, 0x16a3f,
- 0x16a5f, 0x16a5f,
- 0x16a6a, 0x16a6d,
- 0x16a70, 0x16acf,
- 0x16aee, 0x16aef,
- 0x16af6, 0x16aff,
- 0x16b46, 0x16b4f,
- 0x16b5a, 0x16b5a,
- 0x16b62, 0x16b62,
- 0x16b78, 0x16b7c,
- 0x16b90, 0x16eff,
- 0x16f45, 0x16f4f,
- 0x16f7f, 0x16f8e,
- 0x16fa0, 0x16fdf,
- 0x16fe2, 0x16fff,
- 0x187ed, 0x187ff,
- 0x18af3, 0x1afff,
- 0x1b11f, 0x1b16f,
- 0x1b2fc, 0x1bbff,
- 0x1bc6b, 0x1bc6f,
- 0x1bc7d, 0x1bc7f,
- 0x1bc89, 0x1bc8f,
- 0x1bc9a, 0x1bc9b,
- 0x1bca4, 0x1cfff,
- 0x1d0f6, 0x1d0ff,
- 0x1d127, 0x1d128,
- 0x1d1e9, 0x1d1ff,
- 0x1d246, 0x1d2ff,
- 0x1d357, 0x1d35f,
- 0x1d372, 0x1d3ff,
- 0x1d455, 0x1d455,
- 0x1d49d, 0x1d49d,
- 0x1d4a0, 0x1d4a1,
- 0x1d4a3, 0x1d4a4,
- 0x1d4a7, 0x1d4a8,
- 0x1d4ad, 0x1d4ad,
- 0x1d4ba, 0x1d4ba,
- 0x1d4bc, 0x1d4bc,
- 0x1d4c4, 0x1d4c4,
- 0x1d506, 0x1d506,
- 0x1d50b, 0x1d50c,
- 0x1d515, 0x1d515,
- 0x1d51d, 0x1d51d,
- 0x1d53a, 0x1d53a,
- 0x1d53f, 0x1d53f,
- 0x1d545, 0x1d545,
- 0x1d547, 0x1d549,
- 0x1d551, 0x1d551,
- 0x1d6a6, 0x1d6a7,
- 0x1d7cc, 0x1d7cd,
- 0x1da8c, 0x1da9a,
- 0x1daa0, 0x1daa0,
- 0x1dab0, 0x1dfff,
- 0x1e007, 0x1e007,
- 0x1e019, 0x1e01a,
- 0x1e022, 0x1e022,
- 0x1e025, 0x1e025,
- 0x1e02b, 0x1e7ff,
- 0x1e8c5, 0x1e8c6,
- 0x1e8d7, 0x1e8ff,
- 0x1e94b, 0x1e94f,
- 0x1e95a, 0x1e95d,
- 0x1e960, 0x1edff,
- 0x1ee04, 0x1ee04,
- 0x1ee20, 0x1ee20,
- 0x1ee23, 0x1ee23,
- 0x1ee25, 0x1ee26,
- 0x1ee28, 0x1ee28,
- 0x1ee33, 0x1ee33,
- 0x1ee38, 0x1ee38,
- 0x1ee3a, 0x1ee3a,
- 0x1ee3c, 0x1ee41,
- 0x1ee43, 0x1ee46,
- 0x1ee48, 0x1ee48,
- 0x1ee4a, 0x1ee4a,
- 0x1ee4c, 0x1ee4c,
- 0x1ee50, 0x1ee50,
- 0x1ee53, 0x1ee53,
- 0x1ee55, 0x1ee56,
- 0x1ee58, 0x1ee58,
- 0x1ee5a, 0x1ee5a,
- 0x1ee5c, 0x1ee5c,
- 0x1ee5e, 0x1ee5e,
- 0x1ee60, 0x1ee60,
- 0x1ee63, 0x1ee63,
- 0x1ee65, 0x1ee66,
- 0x1ee6b, 0x1ee6b,
- 0x1ee73, 0x1ee73,
- 0x1ee78, 0x1ee78,
- 0x1ee7d, 0x1ee7d,
- 0x1ee7f, 0x1ee7f,
- 0x1ee8a, 0x1ee8a,
- 0x1ee9c, 0x1eea0,
- 0x1eea4, 0x1eea4,
- 0x1eeaa, 0x1eeaa,
- 0x1eebc, 0x1eeef,
- 0x1eef2, 0x1efff,
- 0x1f02c, 0x1f02f,
- 0x1f094, 0x1f09f,
- 0x1f0af, 0x1f0b0,
- 0x1f0c0, 0x1f0c0,
- 0x1f0d0, 0x1f0d0,
- 0x1f0f6, 0x1f0ff,
- 0x1f10d, 0x1f10f,
- 0x1f12f, 0x1f12f,
- 0x1f16c, 0x1f16f,
- 0x1f1ad, 0x1f1e5,
- 0x1f203, 0x1f20f,
- 0x1f23c, 0x1f23f,
- 0x1f249, 0x1f24f,
- 0x1f252, 0x1f25f,
- 0x1f266, 0x1f2ff,
- 0x1f6d5, 0x1f6df,
- 0x1f6ed, 0x1f6ef,
- 0x1f6f9, 0x1f6ff,
- 0x1f774, 0x1f77f,
- 0x1f7d5, 0x1f7ff,
- 0x1f80c, 0x1f80f,
- 0x1f848, 0x1f84f,
- 0x1f85a, 0x1f85f,
- 0x1f888, 0x1f88f,
- 0x1f8ae, 0x1f8ff,
- 0x1f90c, 0x1f90f,
- 0x1f93f, 0x1f93f,
- 0x1f94d, 0x1f94f,
- 0x1f96c, 0x1f97f,
- 0x1f998, 0x1f9bf,
- 0x1f9c1, 0x1f9cf,
- 0x1f9e7, 0x1ffff,
- 0x2a6d7, 0x2a6ff,
- 0x2b735, 0x2b73f,
- 0x2b81e, 0x2b81f,
- 0x2cea2, 0x2ceaf,
- 0x2ebe1, 0x2f7ff,
- 0x2fa1e, 0xe0000,
- 0xe0002, 0xe001f,
- 0xe0080, 0xe00ff,
- 0xe01f0, 0xeffff,
- 0xffffe, 0xfffff,
- 0x10fffe, 0x10ffff,
-}; /* CR_Cn */
-
-/* 'Co': General Category */
-static const OnigCodePoint CR_Co[] = {
- 3,
- 0xe000, 0xf8ff,
- 0xf0000, 0xffffd,
- 0x100000, 0x10fffd,
-}; /* CR_Co */
-
-/* 'Cs': General Category */
-static const OnigCodePoint CR_Cs[] = {
- 1,
- 0xd800, 0xdfff,
-}; /* CR_Cs */
-
-/* 'L': Major Category */
-static const OnigCodePoint CR_L[] = {
- 585,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0370, 0x0374,
- 0x0376, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0620, 0x064a,
- 0x066e, 0x066f,
- 0x0671, 0x06d3,
- 0x06d5, 0x06d5,
- 0x06e5, 0x06e6,
- 0x06ee, 0x06ef,
- 0x06fa, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x0710,
- 0x0712, 0x072f,
- 0x074d, 0x07a5,
- 0x07b1, 0x07b1,
- 0x07ca, 0x07ea,
- 0x07f4, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x0815,
- 0x081a, 0x081a,
- 0x0824, 0x0824,
- 0x0828, 0x0828,
- 0x0840, 0x0858,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x0904, 0x0939,
- 0x093d, 0x093d,
- 0x0950, 0x0950,
- 0x0958, 0x0961,
- 0x0971, 0x0980,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bd, 0x09bd,
- 0x09ce, 0x09ce,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e1,
- 0x09f0, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a72, 0x0a74,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abd, 0x0abd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae1,
- 0x0af9, 0x0af9,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3d, 0x0b3d,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b71, 0x0b71,
- 0x0b83, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bd0, 0x0bd0,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c3d,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c61,
- 0x0c80, 0x0c80,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbd, 0x0cbd,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0cf1, 0x0cf2,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d3d,
- 0x0d4e, 0x0d4e,
- 0x0d54, 0x0d56,
- 0x0d5f, 0x0d61,
- 0x0d7a, 0x0d7f,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0e01, 0x0e30,
- 0x0e32, 0x0e33,
- 0x0e40, 0x0e46,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb0,
- 0x0eb2, 0x0eb3,
- 0x0ebd, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f40, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f88, 0x0f8c,
- 0x1000, 0x102a,
- 0x103f, 0x103f,
- 0x1050, 0x1055,
- 0x105a, 0x105d,
- 0x1061, 0x1061,
- 0x1065, 0x1066,
- 0x106e, 0x1070,
- 0x1075, 0x1081,
- 0x108e, 0x108e,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16f1, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1711,
- 0x1720, 0x1731,
- 0x1740, 0x1751,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1780, 0x17b3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dc,
- 0x1820, 0x1877,
- 0x1880, 0x1884,
- 0x1887, 0x18a8,
- 0x18aa, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1950, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x1a00, 0x1a16,
- 0x1a20, 0x1a54,
- 0x1aa7, 0x1aa7,
- 0x1b05, 0x1b33,
- 0x1b45, 0x1b4b,
- 0x1b83, 0x1ba0,
- 0x1bae, 0x1baf,
- 0x1bba, 0x1be5,
- 0x1c00, 0x1c23,
- 0x1c4d, 0x1c4f,
- 0x1c5a, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf1,
- 0x1cf5, 0x1cf6,
- 0x1d00, 0x1dbf,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2183, 0x2184,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2e2f, 0x2e2f,
- 0x3005, 0x3006,
- 0x3031, 0x3035,
- 0x303b, 0x303c,
- 0x3041, 0x3096,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa61f,
- 0xa62a, 0xa62b,
- 0xa640, 0xa66e,
- 0xa67f, 0xa69d,
- 0xa6a0, 0xa6e5,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa801,
- 0xa803, 0xa805,
- 0xa807, 0xa80a,
- 0xa80c, 0xa822,
- 0xa840, 0xa873,
- 0xa882, 0xa8b3,
- 0xa8f2, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa90a, 0xa925,
- 0xa930, 0xa946,
- 0xa960, 0xa97c,
- 0xa984, 0xa9b2,
- 0xa9cf, 0xa9cf,
- 0xa9e0, 0xa9e4,
- 0xa9e6, 0xa9ef,
- 0xa9fa, 0xa9fe,
- 0xaa00, 0xaa28,
- 0xaa40, 0xaa42,
- 0xaa44, 0xaa4b,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaa7a,
- 0xaa7e, 0xaaaf,
- 0xaab1, 0xaab1,
- 0xaab5, 0xaab6,
- 0xaab9, 0xaabd,
- 0xaac0, 0xaac0,
- 0xaac2, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaea,
- 0xaaf2, 0xaaf4,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabe2,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb1d,
- 0xfb1f, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031f,
- 0x1032d, 0x10340,
- 0x10342, 0x10349,
- 0x10350, 0x10375,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x10400, 0x1049d,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a00,
- 0x10a10, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae4,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11003, 0x11037,
- 0x11083, 0x110af,
- 0x110d0, 0x110e8,
- 0x11103, 0x11126,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11183, 0x111b2,
- 0x111c1, 0x111c4,
- 0x111da, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x1122b,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112de,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133d, 0x1133d,
- 0x11350, 0x11350,
- 0x1135d, 0x11361,
- 0x11400, 0x11434,
- 0x11447, 0x1144a,
- 0x11480, 0x114af,
- 0x114c4, 0x114c5,
- 0x114c7, 0x114c7,
- 0x11580, 0x115ae,
- 0x115d8, 0x115db,
- 0x11600, 0x1162f,
- 0x11644, 0x11644,
- 0x11680, 0x116aa,
- 0x11700, 0x11719,
- 0x118a0, 0x118df,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a00,
- 0x11a0b, 0x11a32,
- 0x11a3a, 0x11a3a,
- 0x11a50, 0x11a50,
- 0x11a5c, 0x11a83,
- 0x11a86, 0x11a89,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c2e,
- 0x11c40, 0x11c40,
- 0x11c72, 0x11c8f,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d30,
- 0x11d46, 0x11d46,
- 0x12000, 0x12399,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16ad0, 0x16aed,
- 0x16b00, 0x16b2f,
- 0x16b40, 0x16b43,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f50,
- 0x16f93, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1e800, 0x1e8c4,
- 0x1e900, 0x1e943,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_L */
-
-/* 'LC': General Category */
-static const OnigCodePoint CR_LC[] = {
- 126,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00b5, 0x00b5,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x01ba,
- 0x01bc, 0x01bf,
- 0x01c4, 0x0293,
- 0x0295, 0x02af,
- 0x0370, 0x0373,
- 0x0376, 0x0377,
- 0x037b, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0561, 0x0587,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1d00, 0x1d2b,
- 0x1d6b, 0x1d77,
- 0x1d79, 0x1d9a,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2134,
- 0x2139, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2183, 0x2184,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2c7b,
- 0x2c7e, 0x2ce4,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0xa640, 0xa66d,
- 0xa680, 0xa69b,
- 0xa722, 0xa76f,
- 0xa771, 0xa787,
- 0xa78b, 0xa78e,
- 0xa790, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7fa, 0xa7fa,
- 0xab30, 0xab5a,
- 0xab60, 0xab65,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0x10400, 0x1044f,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x118a0, 0x118df,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1e900, 0x1e943,
-}; /* CR_LC */
-
-/* 'Ll': General Category */
-static const OnigCodePoint CR_Ll[] = {
- 633,
- 0x0061, 0x007a,
- 0x00b5, 0x00b5,
- 0x00df, 0x00f6,
- 0x00f8, 0x00ff,
- 0x0101, 0x0101,
- 0x0103, 0x0103,
- 0x0105, 0x0105,
- 0x0107, 0x0107,
- 0x0109, 0x0109,
- 0x010b, 0x010b,
- 0x010d, 0x010d,
- 0x010f, 0x010f,
- 0x0111, 0x0111,
- 0x0113, 0x0113,
- 0x0115, 0x0115,
- 0x0117, 0x0117,
- 0x0119, 0x0119,
- 0x011b, 0x011b,
- 0x011d, 0x011d,
- 0x011f, 0x011f,
- 0x0121, 0x0121,
- 0x0123, 0x0123,
- 0x0125, 0x0125,
- 0x0127, 0x0127,
- 0x0129, 0x0129,
- 0x012b, 0x012b,
- 0x012d, 0x012d,
- 0x012f, 0x012f,
- 0x0131, 0x0131,
- 0x0133, 0x0133,
- 0x0135, 0x0135,
- 0x0137, 0x0138,
- 0x013a, 0x013a,
- 0x013c, 0x013c,
- 0x013e, 0x013e,
- 0x0140, 0x0140,
- 0x0142, 0x0142,
- 0x0144, 0x0144,
- 0x0146, 0x0146,
- 0x0148, 0x0149,
- 0x014b, 0x014b,
- 0x014d, 0x014d,
- 0x014f, 0x014f,
- 0x0151, 0x0151,
- 0x0153, 0x0153,
- 0x0155, 0x0155,
- 0x0157, 0x0157,
- 0x0159, 0x0159,
- 0x015b, 0x015b,
- 0x015d, 0x015d,
- 0x015f, 0x015f,
- 0x0161, 0x0161,
- 0x0163, 0x0163,
- 0x0165, 0x0165,
- 0x0167, 0x0167,
- 0x0169, 0x0169,
- 0x016b, 0x016b,
- 0x016d, 0x016d,
- 0x016f, 0x016f,
- 0x0171, 0x0171,
- 0x0173, 0x0173,
- 0x0175, 0x0175,
- 0x0177, 0x0177,
- 0x017a, 0x017a,
- 0x017c, 0x017c,
- 0x017e, 0x0180,
- 0x0183, 0x0183,
- 0x0185, 0x0185,
- 0x0188, 0x0188,
- 0x018c, 0x018d,
- 0x0192, 0x0192,
- 0x0195, 0x0195,
- 0x0199, 0x019b,
- 0x019e, 0x019e,
- 0x01a1, 0x01a1,
- 0x01a3, 0x01a3,
- 0x01a5, 0x01a5,
- 0x01a8, 0x01a8,
- 0x01aa, 0x01ab,
- 0x01ad, 0x01ad,
- 0x01b0, 0x01b0,
- 0x01b4, 0x01b4,
- 0x01b6, 0x01b6,
- 0x01b9, 0x01ba,
- 0x01bd, 0x01bf,
- 0x01c6, 0x01c6,
- 0x01c9, 0x01c9,
- 0x01cc, 0x01cc,
- 0x01ce, 0x01ce,
- 0x01d0, 0x01d0,
- 0x01d2, 0x01d2,
- 0x01d4, 0x01d4,
- 0x01d6, 0x01d6,
- 0x01d8, 0x01d8,
- 0x01da, 0x01da,
- 0x01dc, 0x01dd,
- 0x01df, 0x01df,
- 0x01e1, 0x01e1,
- 0x01e3, 0x01e3,
- 0x01e5, 0x01e5,
- 0x01e7, 0x01e7,
- 0x01e9, 0x01e9,
- 0x01eb, 0x01eb,
- 0x01ed, 0x01ed,
- 0x01ef, 0x01f0,
- 0x01f3, 0x01f3,
- 0x01f5, 0x01f5,
- 0x01f9, 0x01f9,
- 0x01fb, 0x01fb,
- 0x01fd, 0x01fd,
- 0x01ff, 0x01ff,
- 0x0201, 0x0201,
- 0x0203, 0x0203,
- 0x0205, 0x0205,
- 0x0207, 0x0207,
- 0x0209, 0x0209,
- 0x020b, 0x020b,
- 0x020d, 0x020d,
- 0x020f, 0x020f,
- 0x0211, 0x0211,
- 0x0213, 0x0213,
- 0x0215, 0x0215,
- 0x0217, 0x0217,
- 0x0219, 0x0219,
- 0x021b, 0x021b,
- 0x021d, 0x021d,
- 0x021f, 0x021f,
- 0x0221, 0x0221,
- 0x0223, 0x0223,
- 0x0225, 0x0225,
- 0x0227, 0x0227,
- 0x0229, 0x0229,
- 0x022b, 0x022b,
- 0x022d, 0x022d,
- 0x022f, 0x022f,
- 0x0231, 0x0231,
- 0x0233, 0x0239,
- 0x023c, 0x023c,
- 0x023f, 0x0240,
- 0x0242, 0x0242,
- 0x0247, 0x0247,
- 0x0249, 0x0249,
- 0x024b, 0x024b,
- 0x024d, 0x024d,
- 0x024f, 0x0293,
- 0x0295, 0x02af,
- 0x0371, 0x0371,
- 0x0373, 0x0373,
- 0x0377, 0x0377,
- 0x037b, 0x037d,
- 0x0390, 0x0390,
- 0x03ac, 0x03ce,
- 0x03d0, 0x03d1,
- 0x03d5, 0x03d7,
- 0x03d9, 0x03d9,
- 0x03db, 0x03db,
- 0x03dd, 0x03dd,
- 0x03df, 0x03df,
- 0x03e1, 0x03e1,
- 0x03e3, 0x03e3,
- 0x03e5, 0x03e5,
- 0x03e7, 0x03e7,
- 0x03e9, 0x03e9,
- 0x03eb, 0x03eb,
- 0x03ed, 0x03ed,
- 0x03ef, 0x03f3,
- 0x03f5, 0x03f5,
- 0x03f8, 0x03f8,
- 0x03fb, 0x03fc,
- 0x0430, 0x045f,
- 0x0461, 0x0461,
- 0x0463, 0x0463,
- 0x0465, 0x0465,
- 0x0467, 0x0467,
- 0x0469, 0x0469,
- 0x046b, 0x046b,
- 0x046d, 0x046d,
- 0x046f, 0x046f,
- 0x0471, 0x0471,
- 0x0473, 0x0473,
- 0x0475, 0x0475,
- 0x0477, 0x0477,
- 0x0479, 0x0479,
- 0x047b, 0x047b,
- 0x047d, 0x047d,
- 0x047f, 0x047f,
- 0x0481, 0x0481,
- 0x048b, 0x048b,
- 0x048d, 0x048d,
- 0x048f, 0x048f,
- 0x0491, 0x0491,
- 0x0493, 0x0493,
- 0x0495, 0x0495,
- 0x0497, 0x0497,
- 0x0499, 0x0499,
- 0x049b, 0x049b,
- 0x049d, 0x049d,
- 0x049f, 0x049f,
- 0x04a1, 0x04a1,
- 0x04a3, 0x04a3,
- 0x04a5, 0x04a5,
- 0x04a7, 0x04a7,
- 0x04a9, 0x04a9,
- 0x04ab, 0x04ab,
- 0x04ad, 0x04ad,
- 0x04af, 0x04af,
- 0x04b1, 0x04b1,
- 0x04b3, 0x04b3,
- 0x04b5, 0x04b5,
- 0x04b7, 0x04b7,
- 0x04b9, 0x04b9,
- 0x04bb, 0x04bb,
- 0x04bd, 0x04bd,
- 0x04bf, 0x04bf,
- 0x04c2, 0x04c2,
- 0x04c4, 0x04c4,
- 0x04c6, 0x04c6,
- 0x04c8, 0x04c8,
- 0x04ca, 0x04ca,
- 0x04cc, 0x04cc,
- 0x04ce, 0x04cf,
- 0x04d1, 0x04d1,
- 0x04d3, 0x04d3,
- 0x04d5, 0x04d5,
- 0x04d7, 0x04d7,
- 0x04d9, 0x04d9,
- 0x04db, 0x04db,
- 0x04dd, 0x04dd,
- 0x04df, 0x04df,
- 0x04e1, 0x04e1,
- 0x04e3, 0x04e3,
- 0x04e5, 0x04e5,
- 0x04e7, 0x04e7,
- 0x04e9, 0x04e9,
- 0x04eb, 0x04eb,
- 0x04ed, 0x04ed,
- 0x04ef, 0x04ef,
- 0x04f1, 0x04f1,
- 0x04f3, 0x04f3,
- 0x04f5, 0x04f5,
- 0x04f7, 0x04f7,
- 0x04f9, 0x04f9,
- 0x04fb, 0x04fb,
- 0x04fd, 0x04fd,
- 0x04ff, 0x04ff,
- 0x0501, 0x0501,
- 0x0503, 0x0503,
- 0x0505, 0x0505,
- 0x0507, 0x0507,
- 0x0509, 0x0509,
- 0x050b, 0x050b,
- 0x050d, 0x050d,
- 0x050f, 0x050f,
- 0x0511, 0x0511,
- 0x0513, 0x0513,
- 0x0515, 0x0515,
- 0x0517, 0x0517,
- 0x0519, 0x0519,
- 0x051b, 0x051b,
- 0x051d, 0x051d,
- 0x051f, 0x051f,
- 0x0521, 0x0521,
- 0x0523, 0x0523,
- 0x0525, 0x0525,
- 0x0527, 0x0527,
- 0x0529, 0x0529,
- 0x052b, 0x052b,
- 0x052d, 0x052d,
- 0x052f, 0x052f,
- 0x0561, 0x0587,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1d00, 0x1d2b,
- 0x1d6b, 0x1d77,
- 0x1d79, 0x1d9a,
- 0x1e01, 0x1e01,
- 0x1e03, 0x1e03,
- 0x1e05, 0x1e05,
- 0x1e07, 0x1e07,
- 0x1e09, 0x1e09,
- 0x1e0b, 0x1e0b,
- 0x1e0d, 0x1e0d,
- 0x1e0f, 0x1e0f,
- 0x1e11, 0x1e11,
- 0x1e13, 0x1e13,
- 0x1e15, 0x1e15,
- 0x1e17, 0x1e17,
- 0x1e19, 0x1e19,
- 0x1e1b, 0x1e1b,
- 0x1e1d, 0x1e1d,
- 0x1e1f, 0x1e1f,
- 0x1e21, 0x1e21,
- 0x1e23, 0x1e23,
- 0x1e25, 0x1e25,
- 0x1e27, 0x1e27,
- 0x1e29, 0x1e29,
- 0x1e2b, 0x1e2b,
- 0x1e2d, 0x1e2d,
- 0x1e2f, 0x1e2f,
- 0x1e31, 0x1e31,
- 0x1e33, 0x1e33,
- 0x1e35, 0x1e35,
- 0x1e37, 0x1e37,
- 0x1e39, 0x1e39,
- 0x1e3b, 0x1e3b,
- 0x1e3d, 0x1e3d,
- 0x1e3f, 0x1e3f,
- 0x1e41, 0x1e41,
- 0x1e43, 0x1e43,
- 0x1e45, 0x1e45,
- 0x1e47, 0x1e47,
- 0x1e49, 0x1e49,
- 0x1e4b, 0x1e4b,
- 0x1e4d, 0x1e4d,
- 0x1e4f, 0x1e4f,
- 0x1e51, 0x1e51,
- 0x1e53, 0x1e53,
- 0x1e55, 0x1e55,
- 0x1e57, 0x1e57,
- 0x1e59, 0x1e59,
- 0x1e5b, 0x1e5b,
- 0x1e5d, 0x1e5d,
- 0x1e5f, 0x1e5f,
- 0x1e61, 0x1e61,
- 0x1e63, 0x1e63,
- 0x1e65, 0x1e65,
- 0x1e67, 0x1e67,
- 0x1e69, 0x1e69,
- 0x1e6b, 0x1e6b,
- 0x1e6d, 0x1e6d,
- 0x1e6f, 0x1e6f,
- 0x1e71, 0x1e71,
- 0x1e73, 0x1e73,
- 0x1e75, 0x1e75,
- 0x1e77, 0x1e77,
- 0x1e79, 0x1e79,
- 0x1e7b, 0x1e7b,
- 0x1e7d, 0x1e7d,
- 0x1e7f, 0x1e7f,
- 0x1e81, 0x1e81,
- 0x1e83, 0x1e83,
- 0x1e85, 0x1e85,
- 0x1e87, 0x1e87,
- 0x1e89, 0x1e89,
- 0x1e8b, 0x1e8b,
- 0x1e8d, 0x1e8d,
- 0x1e8f, 0x1e8f,
- 0x1e91, 0x1e91,
- 0x1e93, 0x1e93,
- 0x1e95, 0x1e9d,
- 0x1e9f, 0x1e9f,
- 0x1ea1, 0x1ea1,
- 0x1ea3, 0x1ea3,
- 0x1ea5, 0x1ea5,
- 0x1ea7, 0x1ea7,
- 0x1ea9, 0x1ea9,
- 0x1eab, 0x1eab,
- 0x1ead, 0x1ead,
- 0x1eaf, 0x1eaf,
- 0x1eb1, 0x1eb1,
- 0x1eb3, 0x1eb3,
- 0x1eb5, 0x1eb5,
- 0x1eb7, 0x1eb7,
- 0x1eb9, 0x1eb9,
- 0x1ebb, 0x1ebb,
- 0x1ebd, 0x1ebd,
- 0x1ebf, 0x1ebf,
- 0x1ec1, 0x1ec1,
- 0x1ec3, 0x1ec3,
- 0x1ec5, 0x1ec5,
- 0x1ec7, 0x1ec7,
- 0x1ec9, 0x1ec9,
- 0x1ecb, 0x1ecb,
- 0x1ecd, 0x1ecd,
- 0x1ecf, 0x1ecf,
- 0x1ed1, 0x1ed1,
- 0x1ed3, 0x1ed3,
- 0x1ed5, 0x1ed5,
- 0x1ed7, 0x1ed7,
- 0x1ed9, 0x1ed9,
- 0x1edb, 0x1edb,
- 0x1edd, 0x1edd,
- 0x1edf, 0x1edf,
- 0x1ee1, 0x1ee1,
- 0x1ee3, 0x1ee3,
- 0x1ee5, 0x1ee5,
- 0x1ee7, 0x1ee7,
- 0x1ee9, 0x1ee9,
- 0x1eeb, 0x1eeb,
- 0x1eed, 0x1eed,
- 0x1eef, 0x1eef,
- 0x1ef1, 0x1ef1,
- 0x1ef3, 0x1ef3,
- 0x1ef5, 0x1ef5,
- 0x1ef7, 0x1ef7,
- 0x1ef9, 0x1ef9,
- 0x1efb, 0x1efb,
- 0x1efd, 0x1efd,
- 0x1eff, 0x1f07,
- 0x1f10, 0x1f15,
- 0x1f20, 0x1f27,
- 0x1f30, 0x1f37,
- 0x1f40, 0x1f45,
- 0x1f50, 0x1f57,
- 0x1f60, 0x1f67,
- 0x1f70, 0x1f7d,
- 0x1f80, 0x1f87,
- 0x1f90, 0x1f97,
- 0x1fa0, 0x1fa7,
- 0x1fb0, 0x1fb4,
- 0x1fb6, 0x1fb7,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fc7,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fd7,
- 0x1fe0, 0x1fe7,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ff7,
- 0x210a, 0x210a,
- 0x210e, 0x210f,
- 0x2113, 0x2113,
- 0x212f, 0x212f,
- 0x2134, 0x2134,
- 0x2139, 0x2139,
- 0x213c, 0x213d,
- 0x2146, 0x2149,
- 0x214e, 0x214e,
- 0x2184, 0x2184,
- 0x2c30, 0x2c5e,
- 0x2c61, 0x2c61,
- 0x2c65, 0x2c66,
- 0x2c68, 0x2c68,
- 0x2c6a, 0x2c6a,
- 0x2c6c, 0x2c6c,
- 0x2c71, 0x2c71,
- 0x2c73, 0x2c74,
- 0x2c76, 0x2c7b,
- 0x2c81, 0x2c81,
- 0x2c83, 0x2c83,
- 0x2c85, 0x2c85,
- 0x2c87, 0x2c87,
- 0x2c89, 0x2c89,
- 0x2c8b, 0x2c8b,
- 0x2c8d, 0x2c8d,
- 0x2c8f, 0x2c8f,
- 0x2c91, 0x2c91,
- 0x2c93, 0x2c93,
- 0x2c95, 0x2c95,
- 0x2c97, 0x2c97,
- 0x2c99, 0x2c99,
- 0x2c9b, 0x2c9b,
- 0x2c9d, 0x2c9d,
- 0x2c9f, 0x2c9f,
- 0x2ca1, 0x2ca1,
- 0x2ca3, 0x2ca3,
- 0x2ca5, 0x2ca5,
- 0x2ca7, 0x2ca7,
- 0x2ca9, 0x2ca9,
- 0x2cab, 0x2cab,
- 0x2cad, 0x2cad,
- 0x2caf, 0x2caf,
- 0x2cb1, 0x2cb1,
- 0x2cb3, 0x2cb3,
- 0x2cb5, 0x2cb5,
- 0x2cb7, 0x2cb7,
- 0x2cb9, 0x2cb9,
- 0x2cbb, 0x2cbb,
- 0x2cbd, 0x2cbd,
- 0x2cbf, 0x2cbf,
- 0x2cc1, 0x2cc1,
- 0x2cc3, 0x2cc3,
- 0x2cc5, 0x2cc5,
- 0x2cc7, 0x2cc7,
- 0x2cc9, 0x2cc9,
- 0x2ccb, 0x2ccb,
- 0x2ccd, 0x2ccd,
- 0x2ccf, 0x2ccf,
- 0x2cd1, 0x2cd1,
- 0x2cd3, 0x2cd3,
- 0x2cd5, 0x2cd5,
- 0x2cd7, 0x2cd7,
- 0x2cd9, 0x2cd9,
- 0x2cdb, 0x2cdb,
- 0x2cdd, 0x2cdd,
- 0x2cdf, 0x2cdf,
- 0x2ce1, 0x2ce1,
- 0x2ce3, 0x2ce4,
- 0x2cec, 0x2cec,
- 0x2cee, 0x2cee,
- 0x2cf3, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0xa641, 0xa641,
- 0xa643, 0xa643,
- 0xa645, 0xa645,
- 0xa647, 0xa647,
- 0xa649, 0xa649,
- 0xa64b, 0xa64b,
- 0xa64d, 0xa64d,
- 0xa64f, 0xa64f,
- 0xa651, 0xa651,
- 0xa653, 0xa653,
- 0xa655, 0xa655,
- 0xa657, 0xa657,
- 0xa659, 0xa659,
- 0xa65b, 0xa65b,
- 0xa65d, 0xa65d,
- 0xa65f, 0xa65f,
- 0xa661, 0xa661,
- 0xa663, 0xa663,
- 0xa665, 0xa665,
- 0xa667, 0xa667,
- 0xa669, 0xa669,
- 0xa66b, 0xa66b,
- 0xa66d, 0xa66d,
- 0xa681, 0xa681,
- 0xa683, 0xa683,
- 0xa685, 0xa685,
- 0xa687, 0xa687,
- 0xa689, 0xa689,
- 0xa68b, 0xa68b,
- 0xa68d, 0xa68d,
- 0xa68f, 0xa68f,
- 0xa691, 0xa691,
- 0xa693, 0xa693,
- 0xa695, 0xa695,
- 0xa697, 0xa697,
- 0xa699, 0xa699,
- 0xa69b, 0xa69b,
- 0xa723, 0xa723,
- 0xa725, 0xa725,
- 0xa727, 0xa727,
- 0xa729, 0xa729,
- 0xa72b, 0xa72b,
- 0xa72d, 0xa72d,
- 0xa72f, 0xa731,
- 0xa733, 0xa733,
- 0xa735, 0xa735,
- 0xa737, 0xa737,
- 0xa739, 0xa739,
- 0xa73b, 0xa73b,
- 0xa73d, 0xa73d,
- 0xa73f, 0xa73f,
- 0xa741, 0xa741,
- 0xa743, 0xa743,
- 0xa745, 0xa745,
- 0xa747, 0xa747,
- 0xa749, 0xa749,
- 0xa74b, 0xa74b,
- 0xa74d, 0xa74d,
- 0xa74f, 0xa74f,
- 0xa751, 0xa751,
- 0xa753, 0xa753,
- 0xa755, 0xa755,
- 0xa757, 0xa757,
- 0xa759, 0xa759,
- 0xa75b, 0xa75b,
- 0xa75d, 0xa75d,
- 0xa75f, 0xa75f,
- 0xa761, 0xa761,
- 0xa763, 0xa763,
- 0xa765, 0xa765,
- 0xa767, 0xa767,
- 0xa769, 0xa769,
- 0xa76b, 0xa76b,
- 0xa76d, 0xa76d,
- 0xa76f, 0xa76f,
- 0xa771, 0xa778,
- 0xa77a, 0xa77a,
- 0xa77c, 0xa77c,
- 0xa77f, 0xa77f,
- 0xa781, 0xa781,
- 0xa783, 0xa783,
- 0xa785, 0xa785,
- 0xa787, 0xa787,
- 0xa78c, 0xa78c,
- 0xa78e, 0xa78e,
- 0xa791, 0xa791,
- 0xa793, 0xa795,
- 0xa797, 0xa797,
- 0xa799, 0xa799,
- 0xa79b, 0xa79b,
- 0xa79d, 0xa79d,
- 0xa79f, 0xa79f,
- 0xa7a1, 0xa7a1,
- 0xa7a3, 0xa7a3,
- 0xa7a5, 0xa7a5,
- 0xa7a7, 0xa7a7,
- 0xa7a9, 0xa7a9,
- 0xa7b5, 0xa7b5,
- 0xa7b7, 0xa7b7,
- 0xa7fa, 0xa7fa,
- 0xab30, 0xab5a,
- 0xab60, 0xab65,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff41, 0xff5a,
- 0x10428, 0x1044f,
- 0x104d8, 0x104fb,
- 0x10cc0, 0x10cf2,
- 0x118c0, 0x118df,
- 0x1d41a, 0x1d433,
- 0x1d44e, 0x1d454,
- 0x1d456, 0x1d467,
- 0x1d482, 0x1d49b,
- 0x1d4b6, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d4cf,
- 0x1d4ea, 0x1d503,
- 0x1d51e, 0x1d537,
- 0x1d552, 0x1d56b,
- 0x1d586, 0x1d59f,
- 0x1d5ba, 0x1d5d3,
- 0x1d5ee, 0x1d607,
- 0x1d622, 0x1d63b,
- 0x1d656, 0x1d66f,
- 0x1d68a, 0x1d6a5,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6e1,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d71b,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d755,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d78f,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7c9,
- 0x1d7cb, 0x1d7cb,
- 0x1e922, 0x1e943,
-}; /* CR_Ll */
-
-/* 'Lm': General Category */
-static const OnigCodePoint CR_Lm[] = {
- 57,
- 0x02b0, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0374, 0x0374,
- 0x037a, 0x037a,
- 0x0559, 0x0559,
- 0x0640, 0x0640,
- 0x06e5, 0x06e6,
- 0x07f4, 0x07f5,
- 0x07fa, 0x07fa,
- 0x081a, 0x081a,
- 0x0824, 0x0824,
- 0x0828, 0x0828,
- 0x0971, 0x0971,
- 0x0e46, 0x0e46,
- 0x0ec6, 0x0ec6,
- 0x10fc, 0x10fc,
- 0x17d7, 0x17d7,
- 0x1843, 0x1843,
- 0x1aa7, 0x1aa7,
- 0x1c78, 0x1c7d,
- 0x1d2c, 0x1d6a,
- 0x1d78, 0x1d78,
- 0x1d9b, 0x1dbf,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2c7c, 0x2c7d,
- 0x2d6f, 0x2d6f,
- 0x2e2f, 0x2e2f,
- 0x3005, 0x3005,
- 0x3031, 0x3035,
- 0x303b, 0x303b,
- 0x309d, 0x309e,
- 0x30fc, 0x30fe,
- 0xa015, 0xa015,
- 0xa4f8, 0xa4fd,
- 0xa60c, 0xa60c,
- 0xa67f, 0xa67f,
- 0xa69c, 0xa69d,
- 0xa717, 0xa71f,
- 0xa770, 0xa770,
- 0xa788, 0xa788,
- 0xa7f8, 0xa7f9,
- 0xa9cf, 0xa9cf,
- 0xa9e6, 0xa9e6,
- 0xaa70, 0xaa70,
- 0xaadd, 0xaadd,
- 0xaaf3, 0xaaf4,
- 0xab5c, 0xab5f,
- 0xff70, 0xff70,
- 0xff9e, 0xff9f,
- 0x16b40, 0x16b43,
- 0x16f93, 0x16f9f,
- 0x16fe0, 0x16fe1,
-}; /* CR_Lm */
-
-/* 'Lo': General Category */
-static const OnigCodePoint CR_Lo[] = {
- 459,
- 0x00aa, 0x00aa,
- 0x00ba, 0x00ba,
- 0x01bb, 0x01bb,
- 0x01c0, 0x01c3,
- 0x0294, 0x0294,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0620, 0x063f,
- 0x0641, 0x064a,
- 0x066e, 0x066f,
- 0x0671, 0x06d3,
- 0x06d5, 0x06d5,
- 0x06ee, 0x06ef,
- 0x06fa, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x0710,
- 0x0712, 0x072f,
- 0x074d, 0x07a5,
- 0x07b1, 0x07b1,
- 0x07ca, 0x07ea,
- 0x0800, 0x0815,
- 0x0840, 0x0858,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x0904, 0x0939,
- 0x093d, 0x093d,
- 0x0950, 0x0950,
- 0x0958, 0x0961,
- 0x0972, 0x0980,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bd, 0x09bd,
- 0x09ce, 0x09ce,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e1,
- 0x09f0, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a72, 0x0a74,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abd, 0x0abd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae1,
- 0x0af9, 0x0af9,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3d, 0x0b3d,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b71, 0x0b71,
- 0x0b83, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bd0, 0x0bd0,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c3d,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c61,
- 0x0c80, 0x0c80,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbd, 0x0cbd,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0cf1, 0x0cf2,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d3d,
- 0x0d4e, 0x0d4e,
- 0x0d54, 0x0d56,
- 0x0d5f, 0x0d61,
- 0x0d7a, 0x0d7f,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0e01, 0x0e30,
- 0x0e32, 0x0e33,
- 0x0e40, 0x0e45,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb0,
- 0x0eb2, 0x0eb3,
- 0x0ebd, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f40, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f88, 0x0f8c,
- 0x1000, 0x102a,
- 0x103f, 0x103f,
- 0x1050, 0x1055,
- 0x105a, 0x105d,
- 0x1061, 0x1061,
- 0x1065, 0x1066,
- 0x106e, 0x1070,
- 0x1075, 0x1081,
- 0x108e, 0x108e,
- 0x10d0, 0x10fa,
- 0x10fd, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x1380, 0x138f,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16f1, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1711,
- 0x1720, 0x1731,
- 0x1740, 0x1751,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1780, 0x17b3,
- 0x17dc, 0x17dc,
- 0x1820, 0x1842,
- 0x1844, 0x1877,
- 0x1880, 0x1884,
- 0x1887, 0x18a8,
- 0x18aa, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1950, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x1a00, 0x1a16,
- 0x1a20, 0x1a54,
- 0x1b05, 0x1b33,
- 0x1b45, 0x1b4b,
- 0x1b83, 0x1ba0,
- 0x1bae, 0x1baf,
- 0x1bba, 0x1be5,
- 0x1c00, 0x1c23,
- 0x1c4d, 0x1c4f,
- 0x1c5a, 0x1c77,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf1,
- 0x1cf5, 0x1cf6,
- 0x2135, 0x2138,
- 0x2d30, 0x2d67,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x3006, 0x3006,
- 0x303c, 0x303c,
- 0x3041, 0x3096,
- 0x309f, 0x309f,
- 0x30a1, 0x30fa,
- 0x30ff, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa014,
- 0xa016, 0xa48c,
- 0xa4d0, 0xa4f7,
- 0xa500, 0xa60b,
- 0xa610, 0xa61f,
- 0xa62a, 0xa62b,
- 0xa66e, 0xa66e,
- 0xa6a0, 0xa6e5,
- 0xa78f, 0xa78f,
- 0xa7f7, 0xa7f7,
- 0xa7fb, 0xa801,
- 0xa803, 0xa805,
- 0xa807, 0xa80a,
- 0xa80c, 0xa822,
- 0xa840, 0xa873,
- 0xa882, 0xa8b3,
- 0xa8f2, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa90a, 0xa925,
- 0xa930, 0xa946,
- 0xa960, 0xa97c,
- 0xa984, 0xa9b2,
- 0xa9e0, 0xa9e4,
- 0xa9e7, 0xa9ef,
- 0xa9fa, 0xa9fe,
- 0xaa00, 0xaa28,
- 0xaa40, 0xaa42,
- 0xaa44, 0xaa4b,
- 0xaa60, 0xaa6f,
- 0xaa71, 0xaa76,
- 0xaa7a, 0xaa7a,
- 0xaa7e, 0xaaaf,
- 0xaab1, 0xaab1,
- 0xaab5, 0xaab6,
- 0xaab9, 0xaabd,
- 0xaac0, 0xaac0,
- 0xaac2, 0xaac2,
- 0xaadb, 0xaadc,
- 0xaae0, 0xaaea,
- 0xaaf2, 0xaaf2,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xabc0, 0xabe2,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb1d, 0xfb1d,
- 0xfb1f, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff66, 0xff6f,
- 0xff71, 0xff9d,
- 0xffa0, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031f,
- 0x1032d, 0x10340,
- 0x10342, 0x10349,
- 0x10350, 0x10375,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x10450, 0x1049d,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a00,
- 0x10a10, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae4,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x11003, 0x11037,
- 0x11083, 0x110af,
- 0x110d0, 0x110e8,
- 0x11103, 0x11126,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11183, 0x111b2,
- 0x111c1, 0x111c4,
- 0x111da, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x1122b,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112de,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133d, 0x1133d,
- 0x11350, 0x11350,
- 0x1135d, 0x11361,
- 0x11400, 0x11434,
- 0x11447, 0x1144a,
- 0x11480, 0x114af,
- 0x114c4, 0x114c5,
- 0x114c7, 0x114c7,
- 0x11580, 0x115ae,
- 0x115d8, 0x115db,
- 0x11600, 0x1162f,
- 0x11644, 0x11644,
- 0x11680, 0x116aa,
- 0x11700, 0x11719,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a00,
- 0x11a0b, 0x11a32,
- 0x11a3a, 0x11a3a,
- 0x11a50, 0x11a50,
- 0x11a5c, 0x11a83,
- 0x11a86, 0x11a89,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c2e,
- 0x11c40, 0x11c40,
- 0x11c72, 0x11c8f,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d30,
- 0x11d46, 0x11d46,
- 0x12000, 0x12399,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16ad0, 0x16aed,
- 0x16b00, 0x16b2f,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f50,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1e800, 0x1e8c4,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_Lo */
-
-/* 'Lt': General Category */
-static const OnigCodePoint CR_Lt[] = {
- 10,
- 0x01c5, 0x01c5,
- 0x01c8, 0x01c8,
- 0x01cb, 0x01cb,
- 0x01f2, 0x01f2,
- 0x1f88, 0x1f8f,
- 0x1f98, 0x1f9f,
- 0x1fa8, 0x1faf,
- 0x1fbc, 0x1fbc,
- 0x1fcc, 0x1fcc,
- 0x1ffc, 0x1ffc,
-}; /* CR_Lt */
-
-/* 'Lu': General Category */
-static const OnigCodePoint CR_Lu[] = {
- 627,
- 0x0041, 0x005a,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00de,
- 0x0100, 0x0100,
- 0x0102, 0x0102,
- 0x0104, 0x0104,
- 0x0106, 0x0106,
- 0x0108, 0x0108,
- 0x010a, 0x010a,
- 0x010c, 0x010c,
- 0x010e, 0x010e,
- 0x0110, 0x0110,
- 0x0112, 0x0112,
- 0x0114, 0x0114,
- 0x0116, 0x0116,
- 0x0118, 0x0118,
- 0x011a, 0x011a,
- 0x011c, 0x011c,
- 0x011e, 0x011e,
- 0x0120, 0x0120,
- 0x0122, 0x0122,
- 0x0124, 0x0124,
- 0x0126, 0x0126,
- 0x0128, 0x0128,
- 0x012a, 0x012a,
- 0x012c, 0x012c,
- 0x012e, 0x012e,
- 0x0130, 0x0130,
- 0x0132, 0x0132,
- 0x0134, 0x0134,
- 0x0136, 0x0136,
- 0x0139, 0x0139,
- 0x013b, 0x013b,
- 0x013d, 0x013d,
- 0x013f, 0x013f,
- 0x0141, 0x0141,
- 0x0143, 0x0143,
- 0x0145, 0x0145,
- 0x0147, 0x0147,
- 0x014a, 0x014a,
- 0x014c, 0x014c,
- 0x014e, 0x014e,
- 0x0150, 0x0150,
- 0x0152, 0x0152,
- 0x0154, 0x0154,
- 0x0156, 0x0156,
- 0x0158, 0x0158,
- 0x015a, 0x015a,
- 0x015c, 0x015c,
- 0x015e, 0x015e,
- 0x0160, 0x0160,
- 0x0162, 0x0162,
- 0x0164, 0x0164,
- 0x0166, 0x0166,
- 0x0168, 0x0168,
- 0x016a, 0x016a,
- 0x016c, 0x016c,
- 0x016e, 0x016e,
- 0x0170, 0x0170,
- 0x0172, 0x0172,
- 0x0174, 0x0174,
- 0x0176, 0x0176,
- 0x0178, 0x0179,
- 0x017b, 0x017b,
- 0x017d, 0x017d,
- 0x0181, 0x0182,
- 0x0184, 0x0184,
- 0x0186, 0x0187,
- 0x0189, 0x018b,
- 0x018e, 0x0191,
- 0x0193, 0x0194,
- 0x0196, 0x0198,
- 0x019c, 0x019d,
- 0x019f, 0x01a0,
- 0x01a2, 0x01a2,
- 0x01a4, 0x01a4,
- 0x01a6, 0x01a7,
- 0x01a9, 0x01a9,
- 0x01ac, 0x01ac,
- 0x01ae, 0x01af,
- 0x01b1, 0x01b3,
- 0x01b5, 0x01b5,
- 0x01b7, 0x01b8,
- 0x01bc, 0x01bc,
- 0x01c4, 0x01c4,
- 0x01c7, 0x01c7,
- 0x01ca, 0x01ca,
- 0x01cd, 0x01cd,
- 0x01cf, 0x01cf,
- 0x01d1, 0x01d1,
- 0x01d3, 0x01d3,
- 0x01d5, 0x01d5,
- 0x01d7, 0x01d7,
- 0x01d9, 0x01d9,
- 0x01db, 0x01db,
- 0x01de, 0x01de,
- 0x01e0, 0x01e0,
- 0x01e2, 0x01e2,
- 0x01e4, 0x01e4,
- 0x01e6, 0x01e6,
- 0x01e8, 0x01e8,
- 0x01ea, 0x01ea,
- 0x01ec, 0x01ec,
- 0x01ee, 0x01ee,
- 0x01f1, 0x01f1,
- 0x01f4, 0x01f4,
- 0x01f6, 0x01f8,
- 0x01fa, 0x01fa,
- 0x01fc, 0x01fc,
- 0x01fe, 0x01fe,
- 0x0200, 0x0200,
- 0x0202, 0x0202,
- 0x0204, 0x0204,
- 0x0206, 0x0206,
- 0x0208, 0x0208,
- 0x020a, 0x020a,
- 0x020c, 0x020c,
- 0x020e, 0x020e,
- 0x0210, 0x0210,
- 0x0212, 0x0212,
- 0x0214, 0x0214,
- 0x0216, 0x0216,
- 0x0218, 0x0218,
- 0x021a, 0x021a,
- 0x021c, 0x021c,
- 0x021e, 0x021e,
- 0x0220, 0x0220,
- 0x0222, 0x0222,
- 0x0224, 0x0224,
- 0x0226, 0x0226,
- 0x0228, 0x0228,
- 0x022a, 0x022a,
- 0x022c, 0x022c,
- 0x022e, 0x022e,
- 0x0230, 0x0230,
- 0x0232, 0x0232,
- 0x023a, 0x023b,
- 0x023d, 0x023e,
- 0x0241, 0x0241,
- 0x0243, 0x0246,
- 0x0248, 0x0248,
- 0x024a, 0x024a,
- 0x024c, 0x024c,
- 0x024e, 0x024e,
- 0x0370, 0x0370,
- 0x0372, 0x0372,
- 0x0376, 0x0376,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x038f,
- 0x0391, 0x03a1,
- 0x03a3, 0x03ab,
- 0x03cf, 0x03cf,
- 0x03d2, 0x03d4,
- 0x03d8, 0x03d8,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03e2,
- 0x03e4, 0x03e4,
- 0x03e6, 0x03e6,
- 0x03e8, 0x03e8,
- 0x03ea, 0x03ea,
- 0x03ec, 0x03ec,
- 0x03ee, 0x03ee,
- 0x03f4, 0x03f4,
- 0x03f7, 0x03f7,
- 0x03f9, 0x03fa,
- 0x03fd, 0x042f,
- 0x0460, 0x0460,
- 0x0462, 0x0462,
- 0x0464, 0x0464,
- 0x0466, 0x0466,
- 0x0468, 0x0468,
- 0x046a, 0x046a,
- 0x046c, 0x046c,
- 0x046e, 0x046e,
- 0x0470, 0x0470,
- 0x0472, 0x0472,
- 0x0474, 0x0474,
- 0x0476, 0x0476,
- 0x0478, 0x0478,
- 0x047a, 0x047a,
- 0x047c, 0x047c,
- 0x047e, 0x047e,
- 0x0480, 0x0480,
- 0x048a, 0x048a,
- 0x048c, 0x048c,
- 0x048e, 0x048e,
- 0x0490, 0x0490,
- 0x0492, 0x0492,
- 0x0494, 0x0494,
- 0x0496, 0x0496,
- 0x0498, 0x0498,
- 0x049a, 0x049a,
- 0x049c, 0x049c,
- 0x049e, 0x049e,
- 0x04a0, 0x04a0,
- 0x04a2, 0x04a2,
- 0x04a4, 0x04a4,
- 0x04a6, 0x04a6,
- 0x04a8, 0x04a8,
- 0x04aa, 0x04aa,
- 0x04ac, 0x04ac,
- 0x04ae, 0x04ae,
- 0x04b0, 0x04b0,
- 0x04b2, 0x04b2,
- 0x04b4, 0x04b4,
- 0x04b6, 0x04b6,
- 0x04b8, 0x04b8,
- 0x04ba, 0x04ba,
- 0x04bc, 0x04bc,
- 0x04be, 0x04be,
- 0x04c0, 0x04c1,
- 0x04c3, 0x04c3,
- 0x04c5, 0x04c5,
- 0x04c7, 0x04c7,
- 0x04c9, 0x04c9,
- 0x04cb, 0x04cb,
- 0x04cd, 0x04cd,
- 0x04d0, 0x04d0,
- 0x04d2, 0x04d2,
- 0x04d4, 0x04d4,
- 0x04d6, 0x04d6,
- 0x04d8, 0x04d8,
- 0x04da, 0x04da,
- 0x04dc, 0x04dc,
- 0x04de, 0x04de,
- 0x04e0, 0x04e0,
- 0x04e2, 0x04e2,
- 0x04e4, 0x04e4,
- 0x04e6, 0x04e6,
- 0x04e8, 0x04e8,
- 0x04ea, 0x04ea,
- 0x04ec, 0x04ec,
- 0x04ee, 0x04ee,
- 0x04f0, 0x04f0,
- 0x04f2, 0x04f2,
- 0x04f4, 0x04f4,
- 0x04f6, 0x04f6,
- 0x04f8, 0x04f8,
- 0x04fa, 0x04fa,
- 0x04fc, 0x04fc,
- 0x04fe, 0x04fe,
- 0x0500, 0x0500,
- 0x0502, 0x0502,
- 0x0504, 0x0504,
- 0x0506, 0x0506,
- 0x0508, 0x0508,
- 0x050a, 0x050a,
- 0x050c, 0x050c,
- 0x050e, 0x050e,
- 0x0510, 0x0510,
- 0x0512, 0x0512,
- 0x0514, 0x0514,
- 0x0516, 0x0516,
- 0x0518, 0x0518,
- 0x051a, 0x051a,
- 0x051c, 0x051c,
- 0x051e, 0x051e,
- 0x0520, 0x0520,
- 0x0522, 0x0522,
- 0x0524, 0x0524,
- 0x0526, 0x0526,
- 0x0528, 0x0528,
- 0x052a, 0x052a,
- 0x052c, 0x052c,
- 0x052e, 0x052e,
- 0x0531, 0x0556,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x13a0, 0x13f5,
- 0x1e00, 0x1e00,
- 0x1e02, 0x1e02,
- 0x1e04, 0x1e04,
- 0x1e06, 0x1e06,
- 0x1e08, 0x1e08,
- 0x1e0a, 0x1e0a,
- 0x1e0c, 0x1e0c,
- 0x1e0e, 0x1e0e,
- 0x1e10, 0x1e10,
- 0x1e12, 0x1e12,
- 0x1e14, 0x1e14,
- 0x1e16, 0x1e16,
- 0x1e18, 0x1e18,
- 0x1e1a, 0x1e1a,
- 0x1e1c, 0x1e1c,
- 0x1e1e, 0x1e1e,
- 0x1e20, 0x1e20,
- 0x1e22, 0x1e22,
- 0x1e24, 0x1e24,
- 0x1e26, 0x1e26,
- 0x1e28, 0x1e28,
- 0x1e2a, 0x1e2a,
- 0x1e2c, 0x1e2c,
- 0x1e2e, 0x1e2e,
- 0x1e30, 0x1e30,
- 0x1e32, 0x1e32,
- 0x1e34, 0x1e34,
- 0x1e36, 0x1e36,
- 0x1e38, 0x1e38,
- 0x1e3a, 0x1e3a,
- 0x1e3c, 0x1e3c,
- 0x1e3e, 0x1e3e,
- 0x1e40, 0x1e40,
- 0x1e42, 0x1e42,
- 0x1e44, 0x1e44,
- 0x1e46, 0x1e46,
- 0x1e48, 0x1e48,
- 0x1e4a, 0x1e4a,
- 0x1e4c, 0x1e4c,
- 0x1e4e, 0x1e4e,
- 0x1e50, 0x1e50,
- 0x1e52, 0x1e52,
- 0x1e54, 0x1e54,
- 0x1e56, 0x1e56,
- 0x1e58, 0x1e58,
- 0x1e5a, 0x1e5a,
- 0x1e5c, 0x1e5c,
- 0x1e5e, 0x1e5e,
- 0x1e60, 0x1e60,
- 0x1e62, 0x1e62,
- 0x1e64, 0x1e64,
- 0x1e66, 0x1e66,
- 0x1e68, 0x1e68,
- 0x1e6a, 0x1e6a,
- 0x1e6c, 0x1e6c,
- 0x1e6e, 0x1e6e,
- 0x1e70, 0x1e70,
- 0x1e72, 0x1e72,
- 0x1e74, 0x1e74,
- 0x1e76, 0x1e76,
- 0x1e78, 0x1e78,
- 0x1e7a, 0x1e7a,
- 0x1e7c, 0x1e7c,
- 0x1e7e, 0x1e7e,
- 0x1e80, 0x1e80,
- 0x1e82, 0x1e82,
- 0x1e84, 0x1e84,
- 0x1e86, 0x1e86,
- 0x1e88, 0x1e88,
- 0x1e8a, 0x1e8a,
- 0x1e8c, 0x1e8c,
- 0x1e8e, 0x1e8e,
- 0x1e90, 0x1e90,
- 0x1e92, 0x1e92,
- 0x1e94, 0x1e94,
- 0x1e9e, 0x1e9e,
- 0x1ea0, 0x1ea0,
- 0x1ea2, 0x1ea2,
- 0x1ea4, 0x1ea4,
- 0x1ea6, 0x1ea6,
- 0x1ea8, 0x1ea8,
- 0x1eaa, 0x1eaa,
- 0x1eac, 0x1eac,
- 0x1eae, 0x1eae,
- 0x1eb0, 0x1eb0,
- 0x1eb2, 0x1eb2,
- 0x1eb4, 0x1eb4,
- 0x1eb6, 0x1eb6,
- 0x1eb8, 0x1eb8,
- 0x1eba, 0x1eba,
- 0x1ebc, 0x1ebc,
- 0x1ebe, 0x1ebe,
- 0x1ec0, 0x1ec0,
- 0x1ec2, 0x1ec2,
- 0x1ec4, 0x1ec4,
- 0x1ec6, 0x1ec6,
- 0x1ec8, 0x1ec8,
- 0x1eca, 0x1eca,
- 0x1ecc, 0x1ecc,
- 0x1ece, 0x1ece,
- 0x1ed0, 0x1ed0,
- 0x1ed2, 0x1ed2,
- 0x1ed4, 0x1ed4,
- 0x1ed6, 0x1ed6,
- 0x1ed8, 0x1ed8,
- 0x1eda, 0x1eda,
- 0x1edc, 0x1edc,
- 0x1ede, 0x1ede,
- 0x1ee0, 0x1ee0,
- 0x1ee2, 0x1ee2,
- 0x1ee4, 0x1ee4,
- 0x1ee6, 0x1ee6,
- 0x1ee8, 0x1ee8,
- 0x1eea, 0x1eea,
- 0x1eec, 0x1eec,
- 0x1eee, 0x1eee,
- 0x1ef0, 0x1ef0,
- 0x1ef2, 0x1ef2,
- 0x1ef4, 0x1ef4,
- 0x1ef6, 0x1ef6,
- 0x1ef8, 0x1ef8,
- 0x1efa, 0x1efa,
- 0x1efc, 0x1efc,
- 0x1efe, 0x1efe,
- 0x1f08, 0x1f0f,
- 0x1f18, 0x1f1d,
- 0x1f28, 0x1f2f,
- 0x1f38, 0x1f3f,
- 0x1f48, 0x1f4d,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f5f,
- 0x1f68, 0x1f6f,
- 0x1fb8, 0x1fbb,
- 0x1fc8, 0x1fcb,
- 0x1fd8, 0x1fdb,
- 0x1fe8, 0x1fec,
- 0x1ff8, 0x1ffb,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210b, 0x210d,
- 0x2110, 0x2112,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x2130, 0x2133,
- 0x213e, 0x213f,
- 0x2145, 0x2145,
- 0x2183, 0x2183,
- 0x2c00, 0x2c2e,
- 0x2c60, 0x2c60,
- 0x2c62, 0x2c64,
- 0x2c67, 0x2c67,
- 0x2c69, 0x2c69,
- 0x2c6b, 0x2c6b,
- 0x2c6d, 0x2c70,
- 0x2c72, 0x2c72,
- 0x2c75, 0x2c75,
- 0x2c7e, 0x2c80,
- 0x2c82, 0x2c82,
- 0x2c84, 0x2c84,
- 0x2c86, 0x2c86,
- 0x2c88, 0x2c88,
- 0x2c8a, 0x2c8a,
- 0x2c8c, 0x2c8c,
- 0x2c8e, 0x2c8e,
- 0x2c90, 0x2c90,
- 0x2c92, 0x2c92,
- 0x2c94, 0x2c94,
- 0x2c96, 0x2c96,
- 0x2c98, 0x2c98,
- 0x2c9a, 0x2c9a,
- 0x2c9c, 0x2c9c,
- 0x2c9e, 0x2c9e,
- 0x2ca0, 0x2ca0,
- 0x2ca2, 0x2ca2,
- 0x2ca4, 0x2ca4,
- 0x2ca6, 0x2ca6,
- 0x2ca8, 0x2ca8,
- 0x2caa, 0x2caa,
- 0x2cac, 0x2cac,
- 0x2cae, 0x2cae,
- 0x2cb0, 0x2cb0,
- 0x2cb2, 0x2cb2,
- 0x2cb4, 0x2cb4,
- 0x2cb6, 0x2cb6,
- 0x2cb8, 0x2cb8,
- 0x2cba, 0x2cba,
- 0x2cbc, 0x2cbc,
- 0x2cbe, 0x2cbe,
- 0x2cc0, 0x2cc0,
- 0x2cc2, 0x2cc2,
- 0x2cc4, 0x2cc4,
- 0x2cc6, 0x2cc6,
- 0x2cc8, 0x2cc8,
- 0x2cca, 0x2cca,
- 0x2ccc, 0x2ccc,
- 0x2cce, 0x2cce,
- 0x2cd0, 0x2cd0,
- 0x2cd2, 0x2cd2,
- 0x2cd4, 0x2cd4,
- 0x2cd6, 0x2cd6,
- 0x2cd8, 0x2cd8,
- 0x2cda, 0x2cda,
- 0x2cdc, 0x2cdc,
- 0x2cde, 0x2cde,
- 0x2ce0, 0x2ce0,
- 0x2ce2, 0x2ce2,
- 0x2ceb, 0x2ceb,
- 0x2ced, 0x2ced,
- 0x2cf2, 0x2cf2,
- 0xa640, 0xa640,
- 0xa642, 0xa642,
- 0xa644, 0xa644,
- 0xa646, 0xa646,
- 0xa648, 0xa648,
- 0xa64a, 0xa64a,
- 0xa64c, 0xa64c,
- 0xa64e, 0xa64e,
- 0xa650, 0xa650,
- 0xa652, 0xa652,
- 0xa654, 0xa654,
- 0xa656, 0xa656,
- 0xa658, 0xa658,
- 0xa65a, 0xa65a,
- 0xa65c, 0xa65c,
- 0xa65e, 0xa65e,
- 0xa660, 0xa660,
- 0xa662, 0xa662,
- 0xa664, 0xa664,
- 0xa666, 0xa666,
- 0xa668, 0xa668,
- 0xa66a, 0xa66a,
- 0xa66c, 0xa66c,
- 0xa680, 0xa680,
- 0xa682, 0xa682,
- 0xa684, 0xa684,
- 0xa686, 0xa686,
- 0xa688, 0xa688,
- 0xa68a, 0xa68a,
- 0xa68c, 0xa68c,
- 0xa68e, 0xa68e,
- 0xa690, 0xa690,
- 0xa692, 0xa692,
- 0xa694, 0xa694,
- 0xa696, 0xa696,
- 0xa698, 0xa698,
- 0xa69a, 0xa69a,
- 0xa722, 0xa722,
- 0xa724, 0xa724,
- 0xa726, 0xa726,
- 0xa728, 0xa728,
- 0xa72a, 0xa72a,
- 0xa72c, 0xa72c,
- 0xa72e, 0xa72e,
- 0xa732, 0xa732,
- 0xa734, 0xa734,
- 0xa736, 0xa736,
- 0xa738, 0xa738,
- 0xa73a, 0xa73a,
- 0xa73c, 0xa73c,
- 0xa73e, 0xa73e,
- 0xa740, 0xa740,
- 0xa742, 0xa742,
- 0xa744, 0xa744,
- 0xa746, 0xa746,
- 0xa748, 0xa748,
- 0xa74a, 0xa74a,
- 0xa74c, 0xa74c,
- 0xa74e, 0xa74e,
- 0xa750, 0xa750,
- 0xa752, 0xa752,
- 0xa754, 0xa754,
- 0xa756, 0xa756,
- 0xa758, 0xa758,
- 0xa75a, 0xa75a,
- 0xa75c, 0xa75c,
- 0xa75e, 0xa75e,
- 0xa760, 0xa760,
- 0xa762, 0xa762,
- 0xa764, 0xa764,
- 0xa766, 0xa766,
- 0xa768, 0xa768,
- 0xa76a, 0xa76a,
- 0xa76c, 0xa76c,
- 0xa76e, 0xa76e,
- 0xa779, 0xa779,
- 0xa77b, 0xa77b,
- 0xa77d, 0xa77e,
- 0xa780, 0xa780,
- 0xa782, 0xa782,
- 0xa784, 0xa784,
- 0xa786, 0xa786,
- 0xa78b, 0xa78b,
- 0xa78d, 0xa78d,
- 0xa790, 0xa790,
- 0xa792, 0xa792,
- 0xa796, 0xa796,
- 0xa798, 0xa798,
- 0xa79a, 0xa79a,
- 0xa79c, 0xa79c,
- 0xa79e, 0xa79e,
- 0xa7a0, 0xa7a0,
- 0xa7a2, 0xa7a2,
- 0xa7a4, 0xa7a4,
- 0xa7a6, 0xa7a6,
- 0xa7a8, 0xa7a8,
- 0xa7aa, 0xa7ae,
- 0xa7b0, 0xa7b4,
- 0xa7b6, 0xa7b6,
- 0xff21, 0xff3a,
- 0x10400, 0x10427,
- 0x104b0, 0x104d3,
- 0x10c80, 0x10cb2,
- 0x118a0, 0x118bf,
- 0x1d400, 0x1d419,
- 0x1d434, 0x1d44d,
- 0x1d468, 0x1d481,
- 0x1d49c, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b5,
- 0x1d4d0, 0x1d4e9,
- 0x1d504, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d538, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d56c, 0x1d585,
- 0x1d5a0, 0x1d5b9,
- 0x1d5d4, 0x1d5ed,
- 0x1d608, 0x1d621,
- 0x1d63c, 0x1d655,
- 0x1d670, 0x1d689,
- 0x1d6a8, 0x1d6c0,
- 0x1d6e2, 0x1d6fa,
- 0x1d71c, 0x1d734,
- 0x1d756, 0x1d76e,
- 0x1d790, 0x1d7a8,
- 0x1d7ca, 0x1d7ca,
- 0x1e900, 0x1e921,
-}; /* CR_Lu */
-
-/* 'M': Major Category */
-static const OnigCodePoint CR_M[] = {
- 263,
- 0x0300, 0x036f,
- 0x0483, 0x0489,
- 0x0591, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x0610, 0x061a,
- 0x064b, 0x065f,
- 0x0670, 0x0670,
- 0x06d6, 0x06dc,
- 0x06df, 0x06e4,
- 0x06e7, 0x06e8,
- 0x06ea, 0x06ed,
- 0x0711, 0x0711,
- 0x0730, 0x074a,
- 0x07a6, 0x07b0,
- 0x07eb, 0x07f3,
- 0x0816, 0x0819,
- 0x081b, 0x0823,
- 0x0825, 0x0827,
- 0x0829, 0x082d,
- 0x0859, 0x085b,
- 0x08d4, 0x08e1,
- 0x08e3, 0x0903,
- 0x093a, 0x093c,
- 0x093e, 0x094f,
- 0x0951, 0x0957,
- 0x0962, 0x0963,
- 0x0981, 0x0983,
- 0x09bc, 0x09bc,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09e2, 0x09e3,
- 0x0a01, 0x0a03,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a70, 0x0a71,
- 0x0a75, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0abc, 0x0abc,
- 0x0abe, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ae2, 0x0ae3,
- 0x0afa, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b3c, 0x0b3c,
- 0x0b3e, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b62, 0x0b63,
- 0x0b82, 0x0b82,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0c00, 0x0c03,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c62, 0x0c63,
- 0x0c81, 0x0c83,
- 0x0cbc, 0x0cbc,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0ce2, 0x0ce3,
- 0x0d00, 0x0d03,
- 0x0d3b, 0x0d3c,
- 0x0d3e, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d62, 0x0d63,
- 0x0d82, 0x0d83,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0e31, 0x0e31,
- 0x0e34, 0x0e3a,
- 0x0e47, 0x0e4e,
- 0x0eb1, 0x0eb1,
- 0x0eb4, 0x0eb9,
- 0x0ebb, 0x0ebc,
- 0x0ec8, 0x0ecd,
- 0x0f18, 0x0f19,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f3f,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f87,
- 0x0f8d, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x102b, 0x103e,
- 0x1056, 0x1059,
- 0x105e, 0x1060,
- 0x1062, 0x1064,
- 0x1067, 0x106d,
- 0x1071, 0x1074,
- 0x1082, 0x108d,
- 0x108f, 0x108f,
- 0x109a, 0x109d,
- 0x135d, 0x135f,
- 0x1712, 0x1714,
- 0x1732, 0x1734,
- 0x1752, 0x1753,
- 0x1772, 0x1773,
- 0x17b4, 0x17d3,
- 0x17dd, 0x17dd,
- 0x180b, 0x180d,
- 0x1885, 0x1886,
- 0x18a9, 0x18a9,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1a17, 0x1a1b,
- 0x1a55, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a7f,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b04,
- 0x1b34, 0x1b44,
- 0x1b6b, 0x1b73,
- 0x1b80, 0x1b82,
- 0x1ba1, 0x1bad,
- 0x1be6, 0x1bf3,
- 0x1c24, 0x1c37,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1ce8,
- 0x1ced, 0x1ced,
- 0x1cf2, 0x1cf4,
- 0x1cf7, 0x1cf9,
- 0x1dc0, 0x1df9,
- 0x1dfb, 0x1dff,
- 0x20d0, 0x20f0,
- 0x2cef, 0x2cf1,
- 0x2d7f, 0x2d7f,
- 0x2de0, 0x2dff,
- 0x302a, 0x302f,
- 0x3099, 0x309a,
- 0xa66f, 0xa672,
- 0xa674, 0xa67d,
- 0xa69e, 0xa69f,
- 0xa6f0, 0xa6f1,
- 0xa802, 0xa802,
- 0xa806, 0xa806,
- 0xa80b, 0xa80b,
- 0xa823, 0xa827,
- 0xa880, 0xa881,
- 0xa8b4, 0xa8c5,
- 0xa8e0, 0xa8f1,
- 0xa926, 0xa92d,
- 0xa947, 0xa953,
- 0xa980, 0xa983,
- 0xa9b3, 0xa9c0,
- 0xa9e5, 0xa9e5,
- 0xaa29, 0xaa36,
- 0xaa43, 0xaa43,
- 0xaa4c, 0xaa4d,
- 0xaa7b, 0xaa7d,
- 0xaab0, 0xaab0,
- 0xaab2, 0xaab4,
- 0xaab7, 0xaab8,
- 0xaabe, 0xaabf,
- 0xaac1, 0xaac1,
- 0xaaeb, 0xaaef,
- 0xaaf5, 0xaaf6,
- 0xabe3, 0xabea,
- 0xabec, 0xabed,
- 0xfb1e, 0xfb1e,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe2f,
- 0x101fd, 0x101fd,
- 0x102e0, 0x102e0,
- 0x10376, 0x1037a,
- 0x10a01, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a0f,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a3f,
- 0x10ae5, 0x10ae6,
- 0x11000, 0x11002,
- 0x11038, 0x11046,
- 0x1107f, 0x11082,
- 0x110b0, 0x110ba,
- 0x11100, 0x11102,
- 0x11127, 0x11134,
- 0x11173, 0x11173,
- 0x11180, 0x11182,
- 0x111b3, 0x111c0,
- 0x111ca, 0x111cc,
- 0x1122c, 0x11237,
- 0x1123e, 0x1123e,
- 0x112df, 0x112ea,
- 0x11300, 0x11303,
- 0x1133c, 0x1133c,
- 0x1133e, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11357, 0x11357,
- 0x11362, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11435, 0x11446,
- 0x114b0, 0x114c3,
- 0x115af, 0x115b5,
- 0x115b8, 0x115c0,
- 0x115dc, 0x115dd,
- 0x11630, 0x11640,
- 0x116ab, 0x116b7,
- 0x1171d, 0x1172b,
- 0x11a01, 0x11a0a,
- 0x11a33, 0x11a39,
- 0x11a3b, 0x11a3e,
- 0x11a47, 0x11a47,
- 0x11a51, 0x11a5b,
- 0x11a8a, 0x11a99,
- 0x11c2f, 0x11c36,
- 0x11c38, 0x11c3f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d31, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d45,
- 0x11d47, 0x11d47,
- 0x16af0, 0x16af4,
- 0x16b30, 0x16b36,
- 0x16f51, 0x16f7e,
- 0x16f8f, 0x16f92,
- 0x1bc9d, 0x1bc9e,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d242, 0x1d244,
- 0x1da00, 0x1da36,
- 0x1da3b, 0x1da6c,
- 0x1da75, 0x1da75,
- 0x1da84, 0x1da84,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e8d0, 0x1e8d6,
- 0x1e944, 0x1e94a,
- 0xe0100, 0xe01ef,
-}; /* CR_M */
-
-/* 'Mc': General Category */
-static const OnigCodePoint CR_Mc[] = {
- 160,
- 0x0903, 0x0903,
- 0x093b, 0x093b,
- 0x093e, 0x0940,
- 0x0949, 0x094c,
- 0x094e, 0x094f,
- 0x0982, 0x0983,
- 0x09be, 0x09c0,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cc,
- 0x09d7, 0x09d7,
- 0x0a03, 0x0a03,
- 0x0a3e, 0x0a40,
- 0x0a83, 0x0a83,
- 0x0abe, 0x0ac0,
- 0x0ac9, 0x0ac9,
- 0x0acb, 0x0acc,
- 0x0b02, 0x0b03,
- 0x0b3e, 0x0b3e,
- 0x0b40, 0x0b40,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4c,
- 0x0b57, 0x0b57,
- 0x0bbe, 0x0bbf,
- 0x0bc1, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcc,
- 0x0bd7, 0x0bd7,
- 0x0c01, 0x0c03,
- 0x0c41, 0x0c44,
- 0x0c82, 0x0c83,
- 0x0cbe, 0x0cbe,
- 0x0cc0, 0x0cc4,
- 0x0cc7, 0x0cc8,
- 0x0cca, 0x0ccb,
- 0x0cd5, 0x0cd6,
- 0x0d02, 0x0d03,
- 0x0d3e, 0x0d40,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4c,
- 0x0d57, 0x0d57,
- 0x0d82, 0x0d83,
- 0x0dcf, 0x0dd1,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0f3e, 0x0f3f,
- 0x0f7f, 0x0f7f,
- 0x102b, 0x102c,
- 0x1031, 0x1031,
- 0x1038, 0x1038,
- 0x103b, 0x103c,
- 0x1056, 0x1057,
- 0x1062, 0x1064,
- 0x1067, 0x106d,
- 0x1083, 0x1084,
- 0x1087, 0x108c,
- 0x108f, 0x108f,
- 0x109a, 0x109c,
- 0x17b6, 0x17b6,
- 0x17be, 0x17c5,
- 0x17c7, 0x17c8,
- 0x1923, 0x1926,
- 0x1929, 0x192b,
- 0x1930, 0x1931,
- 0x1933, 0x1938,
- 0x1a19, 0x1a1a,
- 0x1a55, 0x1a55,
- 0x1a57, 0x1a57,
- 0x1a61, 0x1a61,
- 0x1a63, 0x1a64,
- 0x1a6d, 0x1a72,
- 0x1b04, 0x1b04,
- 0x1b35, 0x1b35,
- 0x1b3b, 0x1b3b,
- 0x1b3d, 0x1b41,
- 0x1b43, 0x1b44,
- 0x1b82, 0x1b82,
- 0x1ba1, 0x1ba1,
- 0x1ba6, 0x1ba7,
- 0x1baa, 0x1baa,
- 0x1be7, 0x1be7,
- 0x1bea, 0x1bec,
- 0x1bee, 0x1bee,
- 0x1bf2, 0x1bf3,
- 0x1c24, 0x1c2b,
- 0x1c34, 0x1c35,
- 0x1ce1, 0x1ce1,
- 0x1cf2, 0x1cf3,
- 0x1cf7, 0x1cf7,
- 0x302e, 0x302f,
- 0xa823, 0xa824,
- 0xa827, 0xa827,
- 0xa880, 0xa881,
- 0xa8b4, 0xa8c3,
- 0xa952, 0xa953,
- 0xa983, 0xa983,
- 0xa9b4, 0xa9b5,
- 0xa9ba, 0xa9bb,
- 0xa9bd, 0xa9c0,
- 0xaa2f, 0xaa30,
- 0xaa33, 0xaa34,
- 0xaa4d, 0xaa4d,
- 0xaa7b, 0xaa7b,
- 0xaa7d, 0xaa7d,
- 0xaaeb, 0xaaeb,
- 0xaaee, 0xaaef,
- 0xaaf5, 0xaaf5,
- 0xabe3, 0xabe4,
- 0xabe6, 0xabe7,
- 0xabe9, 0xabea,
- 0xabec, 0xabec,
- 0x11000, 0x11000,
- 0x11002, 0x11002,
- 0x11082, 0x11082,
- 0x110b0, 0x110b2,
- 0x110b7, 0x110b8,
- 0x1112c, 0x1112c,
- 0x11182, 0x11182,
- 0x111b3, 0x111b5,
- 0x111bf, 0x111c0,
- 0x1122c, 0x1122e,
- 0x11232, 0x11233,
- 0x11235, 0x11235,
- 0x112e0, 0x112e2,
- 0x11302, 0x11303,
- 0x1133e, 0x1133f,
- 0x11341, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11357, 0x11357,
- 0x11362, 0x11363,
- 0x11435, 0x11437,
- 0x11440, 0x11441,
- 0x11445, 0x11445,
- 0x114b0, 0x114b2,
- 0x114b9, 0x114b9,
- 0x114bb, 0x114be,
- 0x114c1, 0x114c1,
- 0x115af, 0x115b1,
- 0x115b8, 0x115bb,
- 0x115be, 0x115be,
- 0x11630, 0x11632,
- 0x1163b, 0x1163c,
- 0x1163e, 0x1163e,
- 0x116ac, 0x116ac,
- 0x116ae, 0x116af,
- 0x116b6, 0x116b6,
- 0x11720, 0x11721,
- 0x11726, 0x11726,
- 0x11a07, 0x11a08,
- 0x11a39, 0x11a39,
- 0x11a57, 0x11a58,
- 0x11a97, 0x11a97,
- 0x11c2f, 0x11c2f,
- 0x11c3e, 0x11c3e,
- 0x11ca9, 0x11ca9,
- 0x11cb1, 0x11cb1,
- 0x11cb4, 0x11cb4,
- 0x16f51, 0x16f7e,
- 0x1d165, 0x1d166,
- 0x1d16d, 0x1d172,
-}; /* CR_Mc */
-
-/* 'Me': General Category */
-static const OnigCodePoint CR_Me[] = {
- 5,
- 0x0488, 0x0489,
- 0x1abe, 0x1abe,
- 0x20dd, 0x20e0,
- 0x20e2, 0x20e4,
- 0xa670, 0xa672,
-}; /* CR_Me */
-
-/* 'Mn': General Category */
-static const OnigCodePoint CR_Mn[] = {
- 301,
- 0x0300, 0x036f,
- 0x0483, 0x0487,
- 0x0591, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x0610, 0x061a,
- 0x064b, 0x065f,
- 0x0670, 0x0670,
- 0x06d6, 0x06dc,
- 0x06df, 0x06e4,
- 0x06e7, 0x06e8,
- 0x06ea, 0x06ed,
- 0x0711, 0x0711,
- 0x0730, 0x074a,
- 0x07a6, 0x07b0,
- 0x07eb, 0x07f3,
- 0x0816, 0x0819,
- 0x081b, 0x0823,
- 0x0825, 0x0827,
- 0x0829, 0x082d,
- 0x0859, 0x085b,
- 0x08d4, 0x08e1,
- 0x08e3, 0x0902,
- 0x093a, 0x093a,
- 0x093c, 0x093c,
- 0x0941, 0x0948,
- 0x094d, 0x094d,
- 0x0951, 0x0957,
- 0x0962, 0x0963,
- 0x0981, 0x0981,
- 0x09bc, 0x09bc,
- 0x09c1, 0x09c4,
- 0x09cd, 0x09cd,
- 0x09e2, 0x09e3,
- 0x0a01, 0x0a02,
- 0x0a3c, 0x0a3c,
- 0x0a41, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a70, 0x0a71,
- 0x0a75, 0x0a75,
- 0x0a81, 0x0a82,
- 0x0abc, 0x0abc,
- 0x0ac1, 0x0ac5,
- 0x0ac7, 0x0ac8,
- 0x0acd, 0x0acd,
- 0x0ae2, 0x0ae3,
- 0x0afa, 0x0aff,
- 0x0b01, 0x0b01,
- 0x0b3c, 0x0b3c,
- 0x0b3f, 0x0b3f,
- 0x0b41, 0x0b44,
- 0x0b4d, 0x0b4d,
- 0x0b56, 0x0b56,
- 0x0b62, 0x0b63,
- 0x0b82, 0x0b82,
- 0x0bc0, 0x0bc0,
- 0x0bcd, 0x0bcd,
- 0x0c00, 0x0c00,
- 0x0c3e, 0x0c40,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c62, 0x0c63,
- 0x0c81, 0x0c81,
- 0x0cbc, 0x0cbc,
- 0x0cbf, 0x0cbf,
- 0x0cc6, 0x0cc6,
- 0x0ccc, 0x0ccd,
- 0x0ce2, 0x0ce3,
- 0x0d00, 0x0d01,
- 0x0d3b, 0x0d3c,
- 0x0d41, 0x0d44,
- 0x0d4d, 0x0d4d,
- 0x0d62, 0x0d63,
- 0x0dca, 0x0dca,
- 0x0dd2, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0e31, 0x0e31,
- 0x0e34, 0x0e3a,
- 0x0e47, 0x0e4e,
- 0x0eb1, 0x0eb1,
- 0x0eb4, 0x0eb9,
- 0x0ebb, 0x0ebc,
- 0x0ec8, 0x0ecd,
- 0x0f18, 0x0f19,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f71, 0x0f7e,
- 0x0f80, 0x0f84,
- 0x0f86, 0x0f87,
- 0x0f8d, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x102d, 0x1030,
- 0x1032, 0x1037,
- 0x1039, 0x103a,
- 0x103d, 0x103e,
- 0x1058, 0x1059,
- 0x105e, 0x1060,
- 0x1071, 0x1074,
- 0x1082, 0x1082,
- 0x1085, 0x1086,
- 0x108d, 0x108d,
- 0x109d, 0x109d,
- 0x135d, 0x135f,
- 0x1712, 0x1714,
- 0x1732, 0x1734,
- 0x1752, 0x1753,
- 0x1772, 0x1773,
- 0x17b4, 0x17b5,
- 0x17b7, 0x17bd,
- 0x17c6, 0x17c6,
- 0x17c9, 0x17d3,
- 0x17dd, 0x17dd,
- 0x180b, 0x180d,
- 0x1885, 0x1886,
- 0x18a9, 0x18a9,
- 0x1920, 0x1922,
- 0x1927, 0x1928,
- 0x1932, 0x1932,
- 0x1939, 0x193b,
- 0x1a17, 0x1a18,
- 0x1a1b, 0x1a1b,
- 0x1a56, 0x1a56,
- 0x1a58, 0x1a5e,
- 0x1a60, 0x1a60,
- 0x1a62, 0x1a62,
- 0x1a65, 0x1a6c,
- 0x1a73, 0x1a7c,
- 0x1a7f, 0x1a7f,
- 0x1ab0, 0x1abd,
- 0x1b00, 0x1b03,
- 0x1b34, 0x1b34,
- 0x1b36, 0x1b3a,
- 0x1b3c, 0x1b3c,
- 0x1b42, 0x1b42,
- 0x1b6b, 0x1b73,
- 0x1b80, 0x1b81,
- 0x1ba2, 0x1ba5,
- 0x1ba8, 0x1ba9,
- 0x1bab, 0x1bad,
- 0x1be6, 0x1be6,
- 0x1be8, 0x1be9,
- 0x1bed, 0x1bed,
- 0x1bef, 0x1bf1,
- 0x1c2c, 0x1c33,
- 0x1c36, 0x1c37,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1ce0,
- 0x1ce2, 0x1ce8,
- 0x1ced, 0x1ced,
- 0x1cf4, 0x1cf4,
- 0x1cf8, 0x1cf9,
- 0x1dc0, 0x1df9,
- 0x1dfb, 0x1dff,
- 0x20d0, 0x20dc,
- 0x20e1, 0x20e1,
- 0x20e5, 0x20f0,
- 0x2cef, 0x2cf1,
- 0x2d7f, 0x2d7f,
- 0x2de0, 0x2dff,
- 0x302a, 0x302d,
- 0x3099, 0x309a,
- 0xa66f, 0xa66f,
- 0xa674, 0xa67d,
- 0xa69e, 0xa69f,
- 0xa6f0, 0xa6f1,
- 0xa802, 0xa802,
- 0xa806, 0xa806,
- 0xa80b, 0xa80b,
- 0xa825, 0xa826,
- 0xa8c4, 0xa8c5,
- 0xa8e0, 0xa8f1,
- 0xa926, 0xa92d,
- 0xa947, 0xa951,
- 0xa980, 0xa982,
- 0xa9b3, 0xa9b3,
- 0xa9b6, 0xa9b9,
- 0xa9bc, 0xa9bc,
- 0xa9e5, 0xa9e5,
- 0xaa29, 0xaa2e,
- 0xaa31, 0xaa32,
- 0xaa35, 0xaa36,
- 0xaa43, 0xaa43,
- 0xaa4c, 0xaa4c,
- 0xaa7c, 0xaa7c,
- 0xaab0, 0xaab0,
- 0xaab2, 0xaab4,
- 0xaab7, 0xaab8,
- 0xaabe, 0xaabf,
- 0xaac1, 0xaac1,
- 0xaaec, 0xaaed,
- 0xaaf6, 0xaaf6,
- 0xabe5, 0xabe5,
- 0xabe8, 0xabe8,
- 0xabed, 0xabed,
- 0xfb1e, 0xfb1e,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe2f,
- 0x101fd, 0x101fd,
- 0x102e0, 0x102e0,
- 0x10376, 0x1037a,
- 0x10a01, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a0f,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a3f,
- 0x10ae5, 0x10ae6,
- 0x11001, 0x11001,
- 0x11038, 0x11046,
- 0x1107f, 0x11081,
- 0x110b3, 0x110b6,
- 0x110b9, 0x110ba,
- 0x11100, 0x11102,
- 0x11127, 0x1112b,
- 0x1112d, 0x11134,
- 0x11173, 0x11173,
- 0x11180, 0x11181,
- 0x111b6, 0x111be,
- 0x111ca, 0x111cc,
- 0x1122f, 0x11231,
- 0x11234, 0x11234,
- 0x11236, 0x11237,
- 0x1123e, 0x1123e,
- 0x112df, 0x112df,
- 0x112e3, 0x112ea,
- 0x11300, 0x11301,
- 0x1133c, 0x1133c,
- 0x11340, 0x11340,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11438, 0x1143f,
- 0x11442, 0x11444,
- 0x11446, 0x11446,
- 0x114b3, 0x114b8,
- 0x114ba, 0x114ba,
- 0x114bf, 0x114c0,
- 0x114c2, 0x114c3,
- 0x115b2, 0x115b5,
- 0x115bc, 0x115bd,
- 0x115bf, 0x115c0,
- 0x115dc, 0x115dd,
- 0x11633, 0x1163a,
- 0x1163d, 0x1163d,
- 0x1163f, 0x11640,
- 0x116ab, 0x116ab,
- 0x116ad, 0x116ad,
- 0x116b0, 0x116b5,
- 0x116b7, 0x116b7,
- 0x1171d, 0x1171f,
- 0x11722, 0x11725,
- 0x11727, 0x1172b,
- 0x11a01, 0x11a06,
- 0x11a09, 0x11a0a,
- 0x11a33, 0x11a38,
- 0x11a3b, 0x11a3e,
- 0x11a47, 0x11a47,
- 0x11a51, 0x11a56,
- 0x11a59, 0x11a5b,
- 0x11a8a, 0x11a96,
- 0x11a98, 0x11a99,
- 0x11c30, 0x11c36,
- 0x11c38, 0x11c3d,
- 0x11c3f, 0x11c3f,
- 0x11c92, 0x11ca7,
- 0x11caa, 0x11cb0,
- 0x11cb2, 0x11cb3,
- 0x11cb5, 0x11cb6,
- 0x11d31, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d45,
- 0x11d47, 0x11d47,
- 0x16af0, 0x16af4,
- 0x16b30, 0x16b36,
- 0x16f8f, 0x16f92,
- 0x1bc9d, 0x1bc9e,
- 0x1d167, 0x1d169,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d242, 0x1d244,
- 0x1da00, 0x1da36,
- 0x1da3b, 0x1da6c,
- 0x1da75, 0x1da75,
- 0x1da84, 0x1da84,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e8d0, 0x1e8d6,
- 0x1e944, 0x1e94a,
- 0xe0100, 0xe01ef,
-}; /* CR_Mn */
-
-/* 'N': Major Category */
-static const OnigCodePoint CR_N[] = {
- 116,
- 0x0030, 0x0039,
- 0x00b2, 0x00b3,
- 0x00b9, 0x00b9,
- 0x00bc, 0x00be,
- 0x0660, 0x0669,
- 0x06f0, 0x06f9,
- 0x07c0, 0x07c9,
- 0x0966, 0x096f,
- 0x09e6, 0x09ef,
- 0x09f4, 0x09f9,
- 0x0a66, 0x0a6f,
- 0x0ae6, 0x0aef,
- 0x0b66, 0x0b6f,
- 0x0b72, 0x0b77,
- 0x0be6, 0x0bf2,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7e,
- 0x0ce6, 0x0cef,
- 0x0d58, 0x0d5e,
- 0x0d66, 0x0d78,
- 0x0de6, 0x0def,
- 0x0e50, 0x0e59,
- 0x0ed0, 0x0ed9,
- 0x0f20, 0x0f33,
- 0x1040, 0x1049,
- 0x1090, 0x1099,
- 0x1369, 0x137c,
- 0x16ee, 0x16f0,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1810, 0x1819,
- 0x1946, 0x194f,
- 0x19d0, 0x19da,
- 0x1a80, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1b50, 0x1b59,
- 0x1bb0, 0x1bb9,
- 0x1c40, 0x1c49,
- 0x1c50, 0x1c59,
- 0x2070, 0x2070,
- 0x2074, 0x2079,
- 0x2080, 0x2089,
- 0x2150, 0x2182,
- 0x2185, 0x2189,
- 0x2460, 0x249b,
- 0x24ea, 0x24ff,
- 0x2776, 0x2793,
- 0x2cfd, 0x2cfd,
- 0x3007, 0x3007,
- 0x3021, 0x3029,
- 0x3038, 0x303a,
- 0x3192, 0x3195,
- 0x3220, 0x3229,
- 0x3248, 0x324f,
- 0x3251, 0x325f,
- 0x3280, 0x3289,
- 0x32b1, 0x32bf,
- 0xa620, 0xa629,
- 0xa6e6, 0xa6ef,
- 0xa830, 0xa835,
- 0xa8d0, 0xa8d9,
- 0xa900, 0xa909,
- 0xa9d0, 0xa9d9,
- 0xa9f0, 0xa9f9,
- 0xaa50, 0xaa59,
- 0xabf0, 0xabf9,
- 0xff10, 0xff19,
- 0x10107, 0x10133,
- 0x10140, 0x10178,
- 0x1018a, 0x1018b,
- 0x102e1, 0x102fb,
- 0x10320, 0x10323,
- 0x10341, 0x10341,
- 0x1034a, 0x1034a,
- 0x103d1, 0x103d5,
- 0x104a0, 0x104a9,
- 0x10858, 0x1085f,
- 0x10879, 0x1087f,
- 0x108a7, 0x108af,
- 0x108fb, 0x108ff,
- 0x10916, 0x1091b,
- 0x109bc, 0x109bd,
- 0x109c0, 0x109cf,
- 0x109d2, 0x109ff,
- 0x10a40, 0x10a47,
- 0x10a7d, 0x10a7e,
- 0x10a9d, 0x10a9f,
- 0x10aeb, 0x10aef,
- 0x10b58, 0x10b5f,
- 0x10b78, 0x10b7f,
- 0x10ba9, 0x10baf,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11052, 0x1106f,
- 0x110f0, 0x110f9,
- 0x11136, 0x1113f,
- 0x111d0, 0x111d9,
- 0x111e1, 0x111f4,
- 0x112f0, 0x112f9,
- 0x11450, 0x11459,
- 0x114d0, 0x114d9,
- 0x11650, 0x11659,
- 0x116c0, 0x116c9,
- 0x11730, 0x1173b,
- 0x118e0, 0x118f2,
- 0x11c50, 0x11c6c,
- 0x11d50, 0x11d59,
- 0x12400, 0x1246e,
- 0x16a60, 0x16a69,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x1d360, 0x1d371,
- 0x1d7ce, 0x1d7ff,
- 0x1e8c7, 0x1e8cf,
- 0x1e950, 0x1e959,
- 0x1f100, 0x1f10c,
-}; /* CR_N */
-
-/* 'Nd': General Category */
-#define CR_Nd CR_Digit
-
-/* 'Nl': General Category */
-static const OnigCodePoint CR_Nl[] = {
- 12,
- 0x16ee, 0x16f0,
- 0x2160, 0x2182,
- 0x2185, 0x2188,
- 0x3007, 0x3007,
- 0x3021, 0x3029,
- 0x3038, 0x303a,
- 0xa6e6, 0xa6ef,
- 0x10140, 0x10174,
- 0x10341, 0x10341,
- 0x1034a, 0x1034a,
- 0x103d1, 0x103d5,
- 0x12400, 0x1246e,
-}; /* CR_Nl */
-
-/* 'No': General Category */
-static const OnigCodePoint CR_No[] = {
- 60,
- 0x00b2, 0x00b3,
- 0x00b9, 0x00b9,
- 0x00bc, 0x00be,
- 0x09f4, 0x09f9,
- 0x0b72, 0x0b77,
- 0x0bf0, 0x0bf2,
- 0x0c78, 0x0c7e,
- 0x0d58, 0x0d5e,
- 0x0d70, 0x0d78,
- 0x0f2a, 0x0f33,
- 0x1369, 0x137c,
- 0x17f0, 0x17f9,
- 0x19da, 0x19da,
- 0x2070, 0x2070,
- 0x2074, 0x2079,
- 0x2080, 0x2089,
- 0x2150, 0x215f,
- 0x2189, 0x2189,
- 0x2460, 0x249b,
- 0x24ea, 0x24ff,
- 0x2776, 0x2793,
- 0x2cfd, 0x2cfd,
- 0x3192, 0x3195,
- 0x3220, 0x3229,
- 0x3248, 0x324f,
- 0x3251, 0x325f,
- 0x3280, 0x3289,
- 0x32b1, 0x32bf,
- 0xa830, 0xa835,
- 0x10107, 0x10133,
- 0x10175, 0x10178,
- 0x1018a, 0x1018b,
- 0x102e1, 0x102fb,
- 0x10320, 0x10323,
- 0x10858, 0x1085f,
- 0x10879, 0x1087f,
- 0x108a7, 0x108af,
- 0x108fb, 0x108ff,
- 0x10916, 0x1091b,
- 0x109bc, 0x109bd,
- 0x109c0, 0x109cf,
- 0x109d2, 0x109ff,
- 0x10a40, 0x10a47,
- 0x10a7d, 0x10a7e,
- 0x10a9d, 0x10a9f,
- 0x10aeb, 0x10aef,
- 0x10b58, 0x10b5f,
- 0x10b78, 0x10b7f,
- 0x10ba9, 0x10baf,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11052, 0x11065,
- 0x111e1, 0x111f4,
- 0x1173a, 0x1173b,
- 0x118ea, 0x118f2,
- 0x11c5a, 0x11c6c,
- 0x16b5b, 0x16b61,
- 0x1d360, 0x1d371,
- 0x1e8c7, 0x1e8cf,
- 0x1f100, 0x1f10c,
-}; /* CR_No */
-
-/* 'P': Major Category */
-#define CR_P CR_Punct
-
-/* 'Pc': General Category */
-static const OnigCodePoint CR_Pc[] = {
- 6,
- 0x005f, 0x005f,
- 0x203f, 0x2040,
- 0x2054, 0x2054,
- 0xfe33, 0xfe34,
- 0xfe4d, 0xfe4f,
- 0xff3f, 0xff3f,
-}; /* CR_Pc */
-
-/* 'Pd': General Category */
-static const OnigCodePoint CR_Pd[] = {
- 17,
- 0x002d, 0x002d,
- 0x058a, 0x058a,
- 0x05be, 0x05be,
- 0x1400, 0x1400,
- 0x1806, 0x1806,
- 0x2010, 0x2015,
- 0x2e17, 0x2e17,
- 0x2e1a, 0x2e1a,
- 0x2e3a, 0x2e3b,
- 0x2e40, 0x2e40,
- 0x301c, 0x301c,
- 0x3030, 0x3030,
- 0x30a0, 0x30a0,
- 0xfe31, 0xfe32,
- 0xfe58, 0xfe58,
- 0xfe63, 0xfe63,
- 0xff0d, 0xff0d,
-}; /* CR_Pd */
-
-/* 'Pe': General Category */
-static const OnigCodePoint CR_Pe[] = {
- 72,
- 0x0029, 0x0029,
- 0x005d, 0x005d,
- 0x007d, 0x007d,
- 0x0f3b, 0x0f3b,
- 0x0f3d, 0x0f3d,
- 0x169c, 0x169c,
- 0x2046, 0x2046,
- 0x207e, 0x207e,
- 0x208e, 0x208e,
- 0x2309, 0x2309,
- 0x230b, 0x230b,
- 0x232a, 0x232a,
- 0x2769, 0x2769,
- 0x276b, 0x276b,
- 0x276d, 0x276d,
- 0x276f, 0x276f,
- 0x2771, 0x2771,
- 0x2773, 0x2773,
- 0x2775, 0x2775,
- 0x27c6, 0x27c6,
- 0x27e7, 0x27e7,
- 0x27e9, 0x27e9,
- 0x27eb, 0x27eb,
- 0x27ed, 0x27ed,
- 0x27ef, 0x27ef,
- 0x2984, 0x2984,
- 0x2986, 0x2986,
- 0x2988, 0x2988,
- 0x298a, 0x298a,
- 0x298c, 0x298c,
- 0x298e, 0x298e,
- 0x2990, 0x2990,
- 0x2992, 0x2992,
- 0x2994, 0x2994,
- 0x2996, 0x2996,
- 0x2998, 0x2998,
- 0x29d9, 0x29d9,
- 0x29db, 0x29db,
- 0x29fd, 0x29fd,
- 0x2e23, 0x2e23,
- 0x2e25, 0x2e25,
- 0x2e27, 0x2e27,
- 0x2e29, 0x2e29,
- 0x3009, 0x3009,
- 0x300b, 0x300b,
- 0x300d, 0x300d,
- 0x300f, 0x300f,
- 0x3011, 0x3011,
- 0x3015, 0x3015,
- 0x3017, 0x3017,
- 0x3019, 0x3019,
- 0x301b, 0x301b,
- 0x301e, 0x301f,
- 0xfd3e, 0xfd3e,
- 0xfe18, 0xfe18,
- 0xfe36, 0xfe36,
- 0xfe38, 0xfe38,
- 0xfe3a, 0xfe3a,
- 0xfe3c, 0xfe3c,
- 0xfe3e, 0xfe3e,
- 0xfe40, 0xfe40,
- 0xfe42, 0xfe42,
- 0xfe44, 0xfe44,
- 0xfe48, 0xfe48,
- 0xfe5a, 0xfe5a,
- 0xfe5c, 0xfe5c,
- 0xfe5e, 0xfe5e,
- 0xff09, 0xff09,
- 0xff3d, 0xff3d,
- 0xff5d, 0xff5d,
- 0xff60, 0xff60,
- 0xff63, 0xff63,
-}; /* CR_Pe */
-
-/* 'Pf': General Category */
-static const OnigCodePoint CR_Pf[] = {
- 10,
- 0x00bb, 0x00bb,
- 0x2019, 0x2019,
- 0x201d, 0x201d,
- 0x203a, 0x203a,
- 0x2e03, 0x2e03,
- 0x2e05, 0x2e05,
- 0x2e0a, 0x2e0a,
- 0x2e0d, 0x2e0d,
- 0x2e1d, 0x2e1d,
- 0x2e21, 0x2e21,
-}; /* CR_Pf */
-
-/* 'Pi': General Category */
-static const OnigCodePoint CR_Pi[] = {
- 11,
- 0x00ab, 0x00ab,
- 0x2018, 0x2018,
- 0x201b, 0x201c,
- 0x201f, 0x201f,
- 0x2039, 0x2039,
- 0x2e02, 0x2e02,
- 0x2e04, 0x2e04,
- 0x2e09, 0x2e09,
- 0x2e0c, 0x2e0c,
- 0x2e1c, 0x2e1c,
- 0x2e20, 0x2e20,
-}; /* CR_Pi */
-
-/* 'Po': General Category */
-static const OnigCodePoint CR_Po[] = {
- 169,
- 0x0021, 0x0023,
- 0x0025, 0x0027,
- 0x002a, 0x002a,
- 0x002c, 0x002c,
- 0x002e, 0x002f,
- 0x003a, 0x003b,
- 0x003f, 0x0040,
- 0x005c, 0x005c,
- 0x00a1, 0x00a1,
- 0x00a7, 0x00a7,
- 0x00b6, 0x00b7,
- 0x00bf, 0x00bf,
- 0x037e, 0x037e,
- 0x0387, 0x0387,
- 0x055a, 0x055f,
- 0x0589, 0x0589,
- 0x05c0, 0x05c0,
- 0x05c3, 0x05c3,
- 0x05c6, 0x05c6,
- 0x05f3, 0x05f4,
- 0x0609, 0x060a,
- 0x060c, 0x060d,
- 0x061b, 0x061b,
- 0x061e, 0x061f,
- 0x066a, 0x066d,
- 0x06d4, 0x06d4,
- 0x0700, 0x070d,
- 0x07f7, 0x07f9,
- 0x0830, 0x083e,
- 0x085e, 0x085e,
- 0x0964, 0x0965,
- 0x0970, 0x0970,
- 0x09fd, 0x09fd,
- 0x0af0, 0x0af0,
- 0x0df4, 0x0df4,
- 0x0e4f, 0x0e4f,
- 0x0e5a, 0x0e5b,
- 0x0f04, 0x0f12,
- 0x0f14, 0x0f14,
- 0x0f85, 0x0f85,
- 0x0fd0, 0x0fd4,
- 0x0fd9, 0x0fda,
- 0x104a, 0x104f,
- 0x10fb, 0x10fb,
- 0x1360, 0x1368,
- 0x166d, 0x166e,
- 0x16eb, 0x16ed,
- 0x1735, 0x1736,
- 0x17d4, 0x17d6,
- 0x17d8, 0x17da,
- 0x1800, 0x1805,
- 0x1807, 0x180a,
- 0x1944, 0x1945,
- 0x1a1e, 0x1a1f,
- 0x1aa0, 0x1aa6,
- 0x1aa8, 0x1aad,
- 0x1b5a, 0x1b60,
- 0x1bfc, 0x1bff,
- 0x1c3b, 0x1c3f,
- 0x1c7e, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd3, 0x1cd3,
- 0x2016, 0x2017,
- 0x2020, 0x2027,
- 0x2030, 0x2038,
- 0x203b, 0x203e,
- 0x2041, 0x2043,
- 0x2047, 0x2051,
- 0x2053, 0x2053,
- 0x2055, 0x205e,
- 0x2cf9, 0x2cfc,
- 0x2cfe, 0x2cff,
- 0x2d70, 0x2d70,
- 0x2e00, 0x2e01,
- 0x2e06, 0x2e08,
- 0x2e0b, 0x2e0b,
- 0x2e0e, 0x2e16,
- 0x2e18, 0x2e19,
- 0x2e1b, 0x2e1b,
- 0x2e1e, 0x2e1f,
- 0x2e2a, 0x2e2e,
- 0x2e30, 0x2e39,
- 0x2e3c, 0x2e3f,
- 0x2e41, 0x2e41,
- 0x2e43, 0x2e49,
- 0x3001, 0x3003,
- 0x303d, 0x303d,
- 0x30fb, 0x30fb,
- 0xa4fe, 0xa4ff,
- 0xa60d, 0xa60f,
- 0xa673, 0xa673,
- 0xa67e, 0xa67e,
- 0xa6f2, 0xa6f7,
- 0xa874, 0xa877,
- 0xa8ce, 0xa8cf,
- 0xa8f8, 0xa8fa,
- 0xa8fc, 0xa8fc,
- 0xa92e, 0xa92f,
- 0xa95f, 0xa95f,
- 0xa9c1, 0xa9cd,
- 0xa9de, 0xa9df,
- 0xaa5c, 0xaa5f,
- 0xaade, 0xaadf,
- 0xaaf0, 0xaaf1,
- 0xabeb, 0xabeb,
- 0xfe10, 0xfe16,
- 0xfe19, 0xfe19,
- 0xfe30, 0xfe30,
- 0xfe45, 0xfe46,
- 0xfe49, 0xfe4c,
- 0xfe50, 0xfe52,
- 0xfe54, 0xfe57,
- 0xfe5f, 0xfe61,
- 0xfe68, 0xfe68,
- 0xfe6a, 0xfe6b,
- 0xff01, 0xff03,
- 0xff05, 0xff07,
- 0xff0a, 0xff0a,
- 0xff0c, 0xff0c,
- 0xff0e, 0xff0f,
- 0xff1a, 0xff1b,
- 0xff1f, 0xff20,
- 0xff3c, 0xff3c,
- 0xff61, 0xff61,
- 0xff64, 0xff65,
- 0x10100, 0x10102,
- 0x1039f, 0x1039f,
- 0x103d0, 0x103d0,
- 0x1056f, 0x1056f,
- 0x10857, 0x10857,
- 0x1091f, 0x1091f,
- 0x1093f, 0x1093f,
- 0x10a50, 0x10a58,
- 0x10a7f, 0x10a7f,
- 0x10af0, 0x10af6,
- 0x10b39, 0x10b3f,
- 0x10b99, 0x10b9c,
- 0x11047, 0x1104d,
- 0x110bb, 0x110bc,
- 0x110be, 0x110c1,
- 0x11140, 0x11143,
- 0x11174, 0x11175,
- 0x111c5, 0x111c9,
- 0x111cd, 0x111cd,
- 0x111db, 0x111db,
- 0x111dd, 0x111df,
- 0x11238, 0x1123d,
- 0x112a9, 0x112a9,
- 0x1144b, 0x1144f,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x114c6, 0x114c6,
- 0x115c1, 0x115d7,
- 0x11641, 0x11643,
- 0x11660, 0x1166c,
- 0x1173c, 0x1173e,
- 0x11a3f, 0x11a46,
- 0x11a9a, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11c41, 0x11c45,
- 0x11c70, 0x11c71,
- 0x12470, 0x12474,
- 0x16a6e, 0x16a6f,
- 0x16af5, 0x16af5,
- 0x16b37, 0x16b3b,
- 0x16b44, 0x16b44,
- 0x1bc9f, 0x1bc9f,
- 0x1da87, 0x1da8b,
- 0x1e95e, 0x1e95f,
-}; /* CR_Po */
-
-/* 'Ps': General Category */
-static const OnigCodePoint CR_Ps[] = {
- 75,
- 0x0028, 0x0028,
- 0x005b, 0x005b,
- 0x007b, 0x007b,
- 0x0f3a, 0x0f3a,
- 0x0f3c, 0x0f3c,
- 0x169b, 0x169b,
- 0x201a, 0x201a,
- 0x201e, 0x201e,
- 0x2045, 0x2045,
- 0x207d, 0x207d,
- 0x208d, 0x208d,
- 0x2308, 0x2308,
- 0x230a, 0x230a,
- 0x2329, 0x2329,
- 0x2768, 0x2768,
- 0x276a, 0x276a,
- 0x276c, 0x276c,
- 0x276e, 0x276e,
- 0x2770, 0x2770,
- 0x2772, 0x2772,
- 0x2774, 0x2774,
- 0x27c5, 0x27c5,
- 0x27e6, 0x27e6,
- 0x27e8, 0x27e8,
- 0x27ea, 0x27ea,
- 0x27ec, 0x27ec,
- 0x27ee, 0x27ee,
- 0x2983, 0x2983,
- 0x2985, 0x2985,
- 0x2987, 0x2987,
- 0x2989, 0x2989,
- 0x298b, 0x298b,
- 0x298d, 0x298d,
- 0x298f, 0x298f,
- 0x2991, 0x2991,
- 0x2993, 0x2993,
- 0x2995, 0x2995,
- 0x2997, 0x2997,
- 0x29d8, 0x29d8,
- 0x29da, 0x29da,
- 0x29fc, 0x29fc,
- 0x2e22, 0x2e22,
- 0x2e24, 0x2e24,
- 0x2e26, 0x2e26,
- 0x2e28, 0x2e28,
- 0x2e42, 0x2e42,
- 0x3008, 0x3008,
- 0x300a, 0x300a,
- 0x300c, 0x300c,
- 0x300e, 0x300e,
- 0x3010, 0x3010,
- 0x3014, 0x3014,
- 0x3016, 0x3016,
- 0x3018, 0x3018,
- 0x301a, 0x301a,
- 0x301d, 0x301d,
- 0xfd3f, 0xfd3f,
- 0xfe17, 0xfe17,
- 0xfe35, 0xfe35,
- 0xfe37, 0xfe37,
- 0xfe39, 0xfe39,
- 0xfe3b, 0xfe3b,
- 0xfe3d, 0xfe3d,
- 0xfe3f, 0xfe3f,
- 0xfe41, 0xfe41,
- 0xfe43, 0xfe43,
- 0xfe47, 0xfe47,
- 0xfe59, 0xfe59,
- 0xfe5b, 0xfe5b,
- 0xfe5d, 0xfe5d,
- 0xff08, 0xff08,
- 0xff3b, 0xff3b,
- 0xff5b, 0xff5b,
- 0xff5f, 0xff5f,
- 0xff62, 0xff62,
-}; /* CR_Ps */
-
-/* 'S': Major Category */
-static const OnigCodePoint CR_S[] = {
- 217,
- 0x0024, 0x0024,
- 0x002b, 0x002b,
- 0x003c, 0x003e,
- 0x005e, 0x005e,
- 0x0060, 0x0060,
- 0x007c, 0x007c,
- 0x007e, 0x007e,
- 0x00a2, 0x00a6,
- 0x00a8, 0x00a9,
- 0x00ac, 0x00ac,
- 0x00ae, 0x00b1,
- 0x00b4, 0x00b4,
- 0x00b8, 0x00b8,
- 0x00d7, 0x00d7,
- 0x00f7, 0x00f7,
- 0x02c2, 0x02c5,
- 0x02d2, 0x02df,
- 0x02e5, 0x02eb,
- 0x02ed, 0x02ed,
- 0x02ef, 0x02ff,
- 0x0375, 0x0375,
- 0x0384, 0x0385,
- 0x03f6, 0x03f6,
- 0x0482, 0x0482,
- 0x058d, 0x058f,
- 0x0606, 0x0608,
- 0x060b, 0x060b,
- 0x060e, 0x060f,
- 0x06de, 0x06de,
- 0x06e9, 0x06e9,
- 0x06fd, 0x06fe,
- 0x07f6, 0x07f6,
- 0x09f2, 0x09f3,
- 0x09fa, 0x09fb,
- 0x0af1, 0x0af1,
- 0x0b70, 0x0b70,
- 0x0bf3, 0x0bfa,
- 0x0c7f, 0x0c7f,
- 0x0d4f, 0x0d4f,
- 0x0d79, 0x0d79,
- 0x0e3f, 0x0e3f,
- 0x0f01, 0x0f03,
- 0x0f13, 0x0f13,
- 0x0f15, 0x0f17,
- 0x0f1a, 0x0f1f,
- 0x0f34, 0x0f34,
- 0x0f36, 0x0f36,
- 0x0f38, 0x0f38,
- 0x0fbe, 0x0fc5,
- 0x0fc7, 0x0fcc,
- 0x0fce, 0x0fcf,
- 0x0fd5, 0x0fd8,
- 0x109e, 0x109f,
- 0x1390, 0x1399,
- 0x17db, 0x17db,
- 0x1940, 0x1940,
- 0x19de, 0x19ff,
- 0x1b61, 0x1b6a,
- 0x1b74, 0x1b7c,
- 0x1fbd, 0x1fbd,
- 0x1fbf, 0x1fc1,
- 0x1fcd, 0x1fcf,
- 0x1fdd, 0x1fdf,
- 0x1fed, 0x1fef,
- 0x1ffd, 0x1ffe,
- 0x2044, 0x2044,
- 0x2052, 0x2052,
- 0x207a, 0x207c,
- 0x208a, 0x208c,
- 0x20a0, 0x20bf,
- 0x2100, 0x2101,
- 0x2103, 0x2106,
- 0x2108, 0x2109,
- 0x2114, 0x2114,
- 0x2116, 0x2118,
- 0x211e, 0x2123,
- 0x2125, 0x2125,
- 0x2127, 0x2127,
- 0x2129, 0x2129,
- 0x212e, 0x212e,
- 0x213a, 0x213b,
- 0x2140, 0x2144,
- 0x214a, 0x214d,
- 0x214f, 0x214f,
- 0x218a, 0x218b,
- 0x2190, 0x2307,
- 0x230c, 0x2328,
- 0x232b, 0x2426,
- 0x2440, 0x244a,
- 0x249c, 0x24e9,
- 0x2500, 0x2767,
- 0x2794, 0x27c4,
- 0x27c7, 0x27e5,
- 0x27f0, 0x2982,
- 0x2999, 0x29d7,
- 0x29dc, 0x29fb,
- 0x29fe, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2ce5, 0x2cea,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3004, 0x3004,
- 0x3012, 0x3013,
- 0x3020, 0x3020,
- 0x3036, 0x3037,
- 0x303e, 0x303f,
- 0x309b, 0x309c,
- 0x3190, 0x3191,
- 0x3196, 0x319f,
- 0x31c0, 0x31e3,
- 0x3200, 0x321e,
- 0x322a, 0x3247,
- 0x3250, 0x3250,
- 0x3260, 0x327f,
- 0x328a, 0x32b0,
- 0x32c0, 0x32fe,
- 0x3300, 0x33ff,
- 0x4dc0, 0x4dff,
- 0xa490, 0xa4c6,
- 0xa700, 0xa716,
- 0xa720, 0xa721,
- 0xa789, 0xa78a,
- 0xa828, 0xa82b,
- 0xa836, 0xa839,
- 0xaa77, 0xaa79,
- 0xab5b, 0xab5b,
- 0xfb29, 0xfb29,
- 0xfbb2, 0xfbc1,
- 0xfdfc, 0xfdfd,
- 0xfe62, 0xfe62,
- 0xfe64, 0xfe66,
- 0xfe69, 0xfe69,
- 0xff04, 0xff04,
- 0xff0b, 0xff0b,
- 0xff1c, 0xff1e,
- 0xff3e, 0xff3e,
- 0xff40, 0xff40,
- 0xff5c, 0xff5c,
- 0xff5e, 0xff5e,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfffc, 0xfffd,
- 0x10137, 0x1013f,
- 0x10179, 0x10189,
- 0x1018c, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fc,
- 0x10877, 0x10878,
- 0x10ac8, 0x10ac8,
- 0x1173f, 0x1173f,
- 0x16b3c, 0x16b3f,
- 0x16b45, 0x16b45,
- 0x1bc9c, 0x1bc9c,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d164,
- 0x1d16a, 0x1d16c,
- 0x1d183, 0x1d184,
- 0x1d18c, 0x1d1a9,
- 0x1d1ae, 0x1d1e8,
- 0x1d200, 0x1d241,
- 0x1d245, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d6c1, 0x1d6c1,
- 0x1d6db, 0x1d6db,
- 0x1d6fb, 0x1d6fb,
- 0x1d715, 0x1d715,
- 0x1d735, 0x1d735,
- 0x1d74f, 0x1d74f,
- 0x1d76f, 0x1d76f,
- 0x1d789, 0x1d789,
- 0x1d7a9, 0x1d7a9,
- 0x1d7c3, 0x1d7c3,
- 0x1d800, 0x1d9ff,
- 0x1da37, 0x1da3a,
- 0x1da6d, 0x1da74,
- 0x1da76, 0x1da83,
- 0x1da85, 0x1da86,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
-}; /* CR_S */
-
-/* 'Sc': General Category */
-static const OnigCodePoint CR_Sc[] = {
- 17,
- 0x0024, 0x0024,
- 0x00a2, 0x00a5,
- 0x058f, 0x058f,
- 0x060b, 0x060b,
- 0x09f2, 0x09f3,
- 0x09fb, 0x09fb,
- 0x0af1, 0x0af1,
- 0x0bf9, 0x0bf9,
- 0x0e3f, 0x0e3f,
- 0x17db, 0x17db,
- 0x20a0, 0x20bf,
- 0xa838, 0xa838,
- 0xfdfc, 0xfdfc,
- 0xfe69, 0xfe69,
- 0xff04, 0xff04,
- 0xffe0, 0xffe1,
- 0xffe5, 0xffe6,
-}; /* CR_Sc */
-
-/* 'Sk': General Category */
-static const OnigCodePoint CR_Sk[] = {
- 29,
- 0x005e, 0x005e,
- 0x0060, 0x0060,
- 0x00a8, 0x00a8,
- 0x00af, 0x00af,
- 0x00b4, 0x00b4,
- 0x00b8, 0x00b8,
- 0x02c2, 0x02c5,
- 0x02d2, 0x02df,
- 0x02e5, 0x02eb,
- 0x02ed, 0x02ed,
- 0x02ef, 0x02ff,
- 0x0375, 0x0375,
- 0x0384, 0x0385,
- 0x1fbd, 0x1fbd,
- 0x1fbf, 0x1fc1,
- 0x1fcd, 0x1fcf,
- 0x1fdd, 0x1fdf,
- 0x1fed, 0x1fef,
- 0x1ffd, 0x1ffe,
- 0x309b, 0x309c,
- 0xa700, 0xa716,
- 0xa720, 0xa721,
- 0xa789, 0xa78a,
- 0xab5b, 0xab5b,
- 0xfbb2, 0xfbc1,
- 0xff3e, 0xff3e,
- 0xff40, 0xff40,
- 0xffe3, 0xffe3,
- 0x1f3fb, 0x1f3ff,
-}; /* CR_Sk */
-
-/* 'Sm': General Category */
-static const OnigCodePoint CR_Sm[] = {
- 64,
- 0x002b, 0x002b,
- 0x003c, 0x003e,
- 0x007c, 0x007c,
- 0x007e, 0x007e,
- 0x00ac, 0x00ac,
- 0x00b1, 0x00b1,
- 0x00d7, 0x00d7,
- 0x00f7, 0x00f7,
- 0x03f6, 0x03f6,
- 0x0606, 0x0608,
- 0x2044, 0x2044,
- 0x2052, 0x2052,
- 0x207a, 0x207c,
- 0x208a, 0x208c,
- 0x2118, 0x2118,
- 0x2140, 0x2144,
- 0x214b, 0x214b,
- 0x2190, 0x2194,
- 0x219a, 0x219b,
- 0x21a0, 0x21a0,
- 0x21a3, 0x21a3,
- 0x21a6, 0x21a6,
- 0x21ae, 0x21ae,
- 0x21ce, 0x21cf,
- 0x21d2, 0x21d2,
- 0x21d4, 0x21d4,
- 0x21f4, 0x22ff,
- 0x2320, 0x2321,
- 0x237c, 0x237c,
- 0x239b, 0x23b3,
- 0x23dc, 0x23e1,
- 0x25b7, 0x25b7,
- 0x25c1, 0x25c1,
- 0x25f8, 0x25ff,
- 0x266f, 0x266f,
- 0x27c0, 0x27c4,
- 0x27c7, 0x27e5,
- 0x27f0, 0x27ff,
- 0x2900, 0x2982,
- 0x2999, 0x29d7,
- 0x29dc, 0x29fb,
- 0x29fe, 0x2aff,
- 0x2b30, 0x2b44,
- 0x2b47, 0x2b4c,
- 0xfb29, 0xfb29,
- 0xfe62, 0xfe62,
- 0xfe64, 0xfe66,
- 0xff0b, 0xff0b,
- 0xff1c, 0xff1e,
- 0xff5c, 0xff5c,
- 0xff5e, 0xff5e,
- 0xffe2, 0xffe2,
- 0xffe9, 0xffec,
- 0x1d6c1, 0x1d6c1,
- 0x1d6db, 0x1d6db,
- 0x1d6fb, 0x1d6fb,
- 0x1d715, 0x1d715,
- 0x1d735, 0x1d735,
- 0x1d74f, 0x1d74f,
- 0x1d76f, 0x1d76f,
- 0x1d789, 0x1d789,
- 0x1d7a9, 0x1d7a9,
- 0x1d7c3, 0x1d7c3,
- 0x1eef0, 0x1eef1,
-}; /* CR_Sm */
-
-/* 'So': General Category */
-static const OnigCodePoint CR_So[] = {
- 173,
- 0x00a6, 0x00a6,
- 0x00a9, 0x00a9,
- 0x00ae, 0x00ae,
- 0x00b0, 0x00b0,
- 0x0482, 0x0482,
- 0x058d, 0x058e,
- 0x060e, 0x060f,
- 0x06de, 0x06de,
- 0x06e9, 0x06e9,
- 0x06fd, 0x06fe,
- 0x07f6, 0x07f6,
- 0x09fa, 0x09fa,
- 0x0b70, 0x0b70,
- 0x0bf3, 0x0bf8,
- 0x0bfa, 0x0bfa,
- 0x0c7f, 0x0c7f,
- 0x0d4f, 0x0d4f,
- 0x0d79, 0x0d79,
- 0x0f01, 0x0f03,
- 0x0f13, 0x0f13,
- 0x0f15, 0x0f17,
- 0x0f1a, 0x0f1f,
- 0x0f34, 0x0f34,
- 0x0f36, 0x0f36,
- 0x0f38, 0x0f38,
- 0x0fbe, 0x0fc5,
- 0x0fc7, 0x0fcc,
- 0x0fce, 0x0fcf,
- 0x0fd5, 0x0fd8,
- 0x109e, 0x109f,
- 0x1390, 0x1399,
- 0x1940, 0x1940,
- 0x19de, 0x19ff,
- 0x1b61, 0x1b6a,
- 0x1b74, 0x1b7c,
- 0x2100, 0x2101,
- 0x2103, 0x2106,
- 0x2108, 0x2109,
- 0x2114, 0x2114,
- 0x2116, 0x2117,
- 0x211e, 0x2123,
- 0x2125, 0x2125,
- 0x2127, 0x2127,
- 0x2129, 0x2129,
- 0x212e, 0x212e,
- 0x213a, 0x213b,
- 0x214a, 0x214a,
- 0x214c, 0x214d,
- 0x214f, 0x214f,
- 0x218a, 0x218b,
- 0x2195, 0x2199,
- 0x219c, 0x219f,
- 0x21a1, 0x21a2,
- 0x21a4, 0x21a5,
- 0x21a7, 0x21ad,
- 0x21af, 0x21cd,
- 0x21d0, 0x21d1,
- 0x21d3, 0x21d3,
- 0x21d5, 0x21f3,
- 0x2300, 0x2307,
- 0x230c, 0x231f,
- 0x2322, 0x2328,
- 0x232b, 0x237b,
- 0x237d, 0x239a,
- 0x23b4, 0x23db,
- 0x23e2, 0x2426,
- 0x2440, 0x244a,
- 0x249c, 0x24e9,
- 0x2500, 0x25b6,
- 0x25b8, 0x25c0,
- 0x25c2, 0x25f7,
- 0x2600, 0x266e,
- 0x2670, 0x2767,
- 0x2794, 0x27bf,
- 0x2800, 0x28ff,
- 0x2b00, 0x2b2f,
- 0x2b45, 0x2b46,
- 0x2b4d, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2ce5, 0x2cea,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3004, 0x3004,
- 0x3012, 0x3013,
- 0x3020, 0x3020,
- 0x3036, 0x3037,
- 0x303e, 0x303f,
- 0x3190, 0x3191,
- 0x3196, 0x319f,
- 0x31c0, 0x31e3,
- 0x3200, 0x321e,
- 0x322a, 0x3247,
- 0x3250, 0x3250,
- 0x3260, 0x327f,
- 0x328a, 0x32b0,
- 0x32c0, 0x32fe,
- 0x3300, 0x33ff,
- 0x4dc0, 0x4dff,
- 0xa490, 0xa4c6,
- 0xa828, 0xa82b,
- 0xa836, 0xa837,
- 0xa839, 0xa839,
- 0xaa77, 0xaa79,
- 0xfdfd, 0xfdfd,
- 0xffe4, 0xffe4,
- 0xffe8, 0xffe8,
- 0xffed, 0xffee,
- 0xfffc, 0xfffd,
- 0x10137, 0x1013f,
- 0x10179, 0x10189,
- 0x1018c, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fc,
- 0x10877, 0x10878,
- 0x10ac8, 0x10ac8,
- 0x1173f, 0x1173f,
- 0x16b3c, 0x16b3f,
- 0x16b45, 0x16b45,
- 0x1bc9c, 0x1bc9c,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d164,
- 0x1d16a, 0x1d16c,
- 0x1d183, 0x1d184,
- 0x1d18c, 0x1d1a9,
- 0x1d1ae, 0x1d1e8,
- 0x1d200, 0x1d241,
- 0x1d245, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d800, 0x1d9ff,
- 0x1da37, 0x1da3a,
- 0x1da6d, 0x1da74,
- 0x1da76, 0x1da83,
- 0x1da85, 0x1da86,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f3fa,
- 0x1f400, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
-}; /* CR_So */
-
-/* 'Z': Major Category */
-static const OnigCodePoint CR_Z[] = {
- 8,
- 0x0020, 0x0020,
- 0x00a0, 0x00a0,
- 0x1680, 0x1680,
- 0x2000, 0x200a,
- 0x2028, 0x2029,
- 0x202f, 0x202f,
- 0x205f, 0x205f,
- 0x3000, 0x3000,
-}; /* CR_Z */
-
-/* 'Zl': General Category */
-static const OnigCodePoint CR_Zl[] = {
- 1,
- 0x2028, 0x2028,
-}; /* CR_Zl */
-
-/* 'Zp': General Category */
-static const OnigCodePoint CR_Zp[] = {
- 1,
- 0x2029, 0x2029,
-}; /* CR_Zp */
-
-/* 'Zs': General Category */
-static const OnigCodePoint CR_Zs[] = {
- 7,
- 0x0020, 0x0020,
- 0x00a0, 0x00a0,
- 0x1680, 0x1680,
- 0x2000, 0x200a,
- 0x202f, 0x202f,
- 0x205f, 0x205f,
- 0x3000, 0x3000,
-}; /* CR_Zs */
-
-/* 'Math': Derived Property */
-static const OnigCodePoint CR_Math[] = {
- 138,
- 0x002b, 0x002b,
- 0x003c, 0x003e,
- 0x005e, 0x005e,
- 0x007c, 0x007c,
- 0x007e, 0x007e,
- 0x00ac, 0x00ac,
- 0x00b1, 0x00b1,
- 0x00d7, 0x00d7,
- 0x00f7, 0x00f7,
- 0x03d0, 0x03d2,
- 0x03d5, 0x03d5,
- 0x03f0, 0x03f1,
- 0x03f4, 0x03f6,
- 0x0606, 0x0608,
- 0x2016, 0x2016,
- 0x2032, 0x2034,
- 0x2040, 0x2040,
- 0x2044, 0x2044,
- 0x2052, 0x2052,
- 0x2061, 0x2064,
- 0x207a, 0x207e,
- 0x208a, 0x208e,
- 0x20d0, 0x20dc,
- 0x20e1, 0x20e1,
- 0x20e5, 0x20e6,
- 0x20eb, 0x20ef,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2118, 0x211d,
- 0x2124, 0x2124,
- 0x2128, 0x2129,
- 0x212c, 0x212d,
- 0x212f, 0x2131,
- 0x2133, 0x2138,
- 0x213c, 0x2149,
- 0x214b, 0x214b,
- 0x2190, 0x21a7,
- 0x21a9, 0x21ae,
- 0x21b0, 0x21b1,
- 0x21b6, 0x21b7,
- 0x21bc, 0x21db,
- 0x21dd, 0x21dd,
- 0x21e4, 0x21e5,
- 0x21f4, 0x22ff,
- 0x2308, 0x230b,
- 0x2320, 0x2321,
- 0x237c, 0x237c,
- 0x239b, 0x23b5,
- 0x23b7, 0x23b7,
- 0x23d0, 0x23d0,
- 0x23dc, 0x23e2,
- 0x25a0, 0x25a1,
- 0x25ae, 0x25b7,
- 0x25bc, 0x25c1,
- 0x25c6, 0x25c7,
- 0x25ca, 0x25cb,
- 0x25cf, 0x25d3,
- 0x25e2, 0x25e2,
- 0x25e4, 0x25e4,
- 0x25e7, 0x25ec,
- 0x25f8, 0x25ff,
- 0x2605, 0x2606,
- 0x2640, 0x2640,
- 0x2642, 0x2642,
- 0x2660, 0x2663,
- 0x266d, 0x266f,
- 0x27c0, 0x27ff,
- 0x2900, 0x2aff,
- 0x2b30, 0x2b44,
- 0x2b47, 0x2b4c,
- 0xfb29, 0xfb29,
- 0xfe61, 0xfe66,
- 0xfe68, 0xfe68,
- 0xff0b, 0xff0b,
- 0xff1c, 0xff1e,
- 0xff3c, 0xff3c,
- 0xff3e, 0xff3e,
- 0xff5c, 0xff5c,
- 0xff5e, 0xff5e,
- 0xffe2, 0xffe2,
- 0xffe9, 0xffec,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
-}; /* CR_Math */
-
-/* 'Alphabetic': Derived Property */
-#define CR_Alphabetic CR_Alpha
-
-/* 'Lowercase': Derived Property */
-#define CR_Lowercase CR_Lower
-
-/* 'Uppercase': Derived Property */
-#define CR_Uppercase CR_Upper
-
-/* 'Cased': Derived Property */
-static const OnigCodePoint CR_Cased[] = {
- 135,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x01ba,
- 0x01bc, 0x01bf,
- 0x01c4, 0x0293,
- 0x0295, 0x02b8,
- 0x02c0, 0x02c1,
- 0x02e0, 0x02e4,
- 0x0345, 0x0345,
- 0x0370, 0x0373,
- 0x0376, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0561, 0x0587,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1d00, 0x1dbf,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2134,
- 0x2139, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x217f,
- 0x2183, 0x2184,
- 0x24b6, 0x24e9,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0xa640, 0xa66d,
- 0xa680, 0xa69d,
- 0xa722, 0xa787,
- 0xa78b, 0xa78e,
- 0xa790, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f8, 0xa7fa,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0x10400, 0x1044f,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x118a0, 0x118df,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1e900, 0x1e943,
- 0x1f130, 0x1f149,
- 0x1f150, 0x1f169,
- 0x1f170, 0x1f189,
-}; /* CR_Cased */
-
-/* 'Case_Ignorable': Derived Property */
-static const OnigCodePoint CR_Case_Ignorable[] = {
- 381,
- 0x0027, 0x0027,
- 0x002e, 0x002e,
- 0x003a, 0x003a,
- 0x005e, 0x005e,
- 0x0060, 0x0060,
- 0x00a8, 0x00a8,
- 0x00ad, 0x00ad,
- 0x00af, 0x00af,
- 0x00b4, 0x00b4,
- 0x00b7, 0x00b8,
- 0x02b0, 0x036f,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x0384, 0x0385,
- 0x0387, 0x0387,
- 0x0483, 0x0489,
- 0x0559, 0x0559,
- 0x0591, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x05f4, 0x05f4,
- 0x0600, 0x0605,
- 0x0610, 0x061a,
- 0x061c, 0x061c,
- 0x0640, 0x0640,
- 0x064b, 0x065f,
- 0x0670, 0x0670,
- 0x06d6, 0x06dd,
- 0x06df, 0x06e8,
- 0x06ea, 0x06ed,
- 0x070f, 0x070f,
- 0x0711, 0x0711,
- 0x0730, 0x074a,
- 0x07a6, 0x07b0,
- 0x07eb, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0816, 0x082d,
- 0x0859, 0x085b,
- 0x08d4, 0x0902,
- 0x093a, 0x093a,
- 0x093c, 0x093c,
- 0x0941, 0x0948,
- 0x094d, 0x094d,
- 0x0951, 0x0957,
- 0x0962, 0x0963,
- 0x0971, 0x0971,
- 0x0981, 0x0981,
- 0x09bc, 0x09bc,
- 0x09c1, 0x09c4,
- 0x09cd, 0x09cd,
- 0x09e2, 0x09e3,
- 0x0a01, 0x0a02,
- 0x0a3c, 0x0a3c,
- 0x0a41, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a70, 0x0a71,
- 0x0a75, 0x0a75,
- 0x0a81, 0x0a82,
- 0x0abc, 0x0abc,
- 0x0ac1, 0x0ac5,
- 0x0ac7, 0x0ac8,
- 0x0acd, 0x0acd,
- 0x0ae2, 0x0ae3,
- 0x0afa, 0x0aff,
- 0x0b01, 0x0b01,
- 0x0b3c, 0x0b3c,
- 0x0b3f, 0x0b3f,
- 0x0b41, 0x0b44,
- 0x0b4d, 0x0b4d,
- 0x0b56, 0x0b56,
- 0x0b62, 0x0b63,
- 0x0b82, 0x0b82,
- 0x0bc0, 0x0bc0,
- 0x0bcd, 0x0bcd,
- 0x0c00, 0x0c00,
- 0x0c3e, 0x0c40,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c62, 0x0c63,
- 0x0c81, 0x0c81,
- 0x0cbc, 0x0cbc,
- 0x0cbf, 0x0cbf,
- 0x0cc6, 0x0cc6,
- 0x0ccc, 0x0ccd,
- 0x0ce2, 0x0ce3,
- 0x0d00, 0x0d01,
- 0x0d3b, 0x0d3c,
- 0x0d41, 0x0d44,
- 0x0d4d, 0x0d4d,
- 0x0d62, 0x0d63,
- 0x0dca, 0x0dca,
- 0x0dd2, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0e31, 0x0e31,
- 0x0e34, 0x0e3a,
- 0x0e46, 0x0e4e,
- 0x0eb1, 0x0eb1,
- 0x0eb4, 0x0eb9,
- 0x0ebb, 0x0ebc,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0f18, 0x0f19,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f71, 0x0f7e,
- 0x0f80, 0x0f84,
- 0x0f86, 0x0f87,
- 0x0f8d, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x102d, 0x1030,
- 0x1032, 0x1037,
- 0x1039, 0x103a,
- 0x103d, 0x103e,
- 0x1058, 0x1059,
- 0x105e, 0x1060,
- 0x1071, 0x1074,
- 0x1082, 0x1082,
- 0x1085, 0x1086,
- 0x108d, 0x108d,
- 0x109d, 0x109d,
- 0x10fc, 0x10fc,
- 0x135d, 0x135f,
- 0x1712, 0x1714,
- 0x1732, 0x1734,
- 0x1752, 0x1753,
- 0x1772, 0x1773,
- 0x17b4, 0x17b5,
- 0x17b7, 0x17bd,
- 0x17c6, 0x17c6,
- 0x17c9, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dd, 0x17dd,
- 0x180b, 0x180e,
- 0x1843, 0x1843,
- 0x1885, 0x1886,
- 0x18a9, 0x18a9,
- 0x1920, 0x1922,
- 0x1927, 0x1928,
- 0x1932, 0x1932,
- 0x1939, 0x193b,
- 0x1a17, 0x1a18,
- 0x1a1b, 0x1a1b,
- 0x1a56, 0x1a56,
- 0x1a58, 0x1a5e,
- 0x1a60, 0x1a60,
- 0x1a62, 0x1a62,
- 0x1a65, 0x1a6c,
- 0x1a73, 0x1a7c,
- 0x1a7f, 0x1a7f,
- 0x1aa7, 0x1aa7,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b03,
- 0x1b34, 0x1b34,
- 0x1b36, 0x1b3a,
- 0x1b3c, 0x1b3c,
- 0x1b42, 0x1b42,
- 0x1b6b, 0x1b73,
- 0x1b80, 0x1b81,
- 0x1ba2, 0x1ba5,
- 0x1ba8, 0x1ba9,
- 0x1bab, 0x1bad,
- 0x1be6, 0x1be6,
- 0x1be8, 0x1be9,
- 0x1bed, 0x1bed,
- 0x1bef, 0x1bf1,
- 0x1c2c, 0x1c33,
- 0x1c36, 0x1c37,
- 0x1c78, 0x1c7d,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1ce0,
- 0x1ce2, 0x1ce8,
- 0x1ced, 0x1ced,
- 0x1cf4, 0x1cf4,
- 0x1cf8, 0x1cf9,
- 0x1d2c, 0x1d6a,
- 0x1d78, 0x1d78,
- 0x1d9b, 0x1df9,
- 0x1dfb, 0x1dff,
- 0x1fbd, 0x1fbd,
- 0x1fbf, 0x1fc1,
- 0x1fcd, 0x1fcf,
- 0x1fdd, 0x1fdf,
- 0x1fed, 0x1fef,
- 0x1ffd, 0x1ffe,
- 0x200b, 0x200f,
- 0x2018, 0x2019,
- 0x2024, 0x2024,
- 0x2027, 0x2027,
- 0x202a, 0x202e,
- 0x2060, 0x2064,
- 0x2066, 0x206f,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x20d0, 0x20f0,
- 0x2c7c, 0x2c7d,
- 0x2cef, 0x2cf1,
- 0x2d6f, 0x2d6f,
- 0x2d7f, 0x2d7f,
- 0x2de0, 0x2dff,
- 0x2e2f, 0x2e2f,
- 0x3005, 0x3005,
- 0x302a, 0x302d,
- 0x3031, 0x3035,
- 0x303b, 0x303b,
- 0x3099, 0x309e,
- 0x30fc, 0x30fe,
- 0xa015, 0xa015,
- 0xa4f8, 0xa4fd,
- 0xa60c, 0xa60c,
- 0xa66f, 0xa672,
- 0xa674, 0xa67d,
- 0xa67f, 0xa67f,
- 0xa69c, 0xa69f,
- 0xa6f0, 0xa6f1,
- 0xa700, 0xa721,
- 0xa770, 0xa770,
- 0xa788, 0xa78a,
- 0xa7f8, 0xa7f9,
- 0xa802, 0xa802,
- 0xa806, 0xa806,
- 0xa80b, 0xa80b,
- 0xa825, 0xa826,
- 0xa8c4, 0xa8c5,
- 0xa8e0, 0xa8f1,
- 0xa926, 0xa92d,
- 0xa947, 0xa951,
- 0xa980, 0xa982,
- 0xa9b3, 0xa9b3,
- 0xa9b6, 0xa9b9,
- 0xa9bc, 0xa9bc,
- 0xa9cf, 0xa9cf,
- 0xa9e5, 0xa9e6,
- 0xaa29, 0xaa2e,
- 0xaa31, 0xaa32,
- 0xaa35, 0xaa36,
- 0xaa43, 0xaa43,
- 0xaa4c, 0xaa4c,
- 0xaa70, 0xaa70,
- 0xaa7c, 0xaa7c,
- 0xaab0, 0xaab0,
- 0xaab2, 0xaab4,
- 0xaab7, 0xaab8,
- 0xaabe, 0xaabf,
- 0xaac1, 0xaac1,
- 0xaadd, 0xaadd,
- 0xaaec, 0xaaed,
- 0xaaf3, 0xaaf4,
- 0xaaf6, 0xaaf6,
- 0xab5b, 0xab5f,
- 0xabe5, 0xabe5,
- 0xabe8, 0xabe8,
- 0xabed, 0xabed,
- 0xfb1e, 0xfb1e,
- 0xfbb2, 0xfbc1,
- 0xfe00, 0xfe0f,
- 0xfe13, 0xfe13,
- 0xfe20, 0xfe2f,
- 0xfe52, 0xfe52,
- 0xfe55, 0xfe55,
- 0xfeff, 0xfeff,
- 0xff07, 0xff07,
- 0xff0e, 0xff0e,
- 0xff1a, 0xff1a,
- 0xff3e, 0xff3e,
- 0xff40, 0xff40,
- 0xff70, 0xff70,
- 0xff9e, 0xff9f,
- 0xffe3, 0xffe3,
- 0xfff9, 0xfffb,
- 0x101fd, 0x101fd,
- 0x102e0, 0x102e0,
- 0x10376, 0x1037a,
- 0x10a01, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a0f,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a3f,
- 0x10ae5, 0x10ae6,
- 0x11001, 0x11001,
- 0x11038, 0x11046,
- 0x1107f, 0x11081,
- 0x110b3, 0x110b6,
- 0x110b9, 0x110ba,
- 0x110bd, 0x110bd,
- 0x11100, 0x11102,
- 0x11127, 0x1112b,
- 0x1112d, 0x11134,
- 0x11173, 0x11173,
- 0x11180, 0x11181,
- 0x111b6, 0x111be,
- 0x111ca, 0x111cc,
- 0x1122f, 0x11231,
- 0x11234, 0x11234,
- 0x11236, 0x11237,
- 0x1123e, 0x1123e,
- 0x112df, 0x112df,
- 0x112e3, 0x112ea,
- 0x11300, 0x11301,
- 0x1133c, 0x1133c,
- 0x11340, 0x11340,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11438, 0x1143f,
- 0x11442, 0x11444,
- 0x11446, 0x11446,
- 0x114b3, 0x114b8,
- 0x114ba, 0x114ba,
- 0x114bf, 0x114c0,
- 0x114c2, 0x114c3,
- 0x115b2, 0x115b5,
- 0x115bc, 0x115bd,
- 0x115bf, 0x115c0,
- 0x115dc, 0x115dd,
- 0x11633, 0x1163a,
- 0x1163d, 0x1163d,
- 0x1163f, 0x11640,
- 0x116ab, 0x116ab,
- 0x116ad, 0x116ad,
- 0x116b0, 0x116b5,
- 0x116b7, 0x116b7,
- 0x1171d, 0x1171f,
- 0x11722, 0x11725,
- 0x11727, 0x1172b,
- 0x11a01, 0x11a06,
- 0x11a09, 0x11a0a,
- 0x11a33, 0x11a38,
- 0x11a3b, 0x11a3e,
- 0x11a47, 0x11a47,
- 0x11a51, 0x11a56,
- 0x11a59, 0x11a5b,
- 0x11a8a, 0x11a96,
- 0x11a98, 0x11a99,
- 0x11c30, 0x11c36,
- 0x11c38, 0x11c3d,
- 0x11c3f, 0x11c3f,
- 0x11c92, 0x11ca7,
- 0x11caa, 0x11cb0,
- 0x11cb2, 0x11cb3,
- 0x11cb5, 0x11cb6,
- 0x11d31, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d45,
- 0x11d47, 0x11d47,
- 0x16af0, 0x16af4,
- 0x16b30, 0x16b36,
- 0x16b40, 0x16b43,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x1bc9d, 0x1bc9e,
- 0x1bca0, 0x1bca3,
- 0x1d167, 0x1d169,
- 0x1d173, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d242, 0x1d244,
- 0x1da00, 0x1da36,
- 0x1da3b, 0x1da6c,
- 0x1da75, 0x1da75,
- 0x1da84, 0x1da84,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e8d0, 0x1e8d6,
- 0x1e944, 0x1e94a,
- 0x1f3fb, 0x1f3ff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
-}; /* CR_Case_Ignorable */
-
-/* 'Changes_When_Lowercased': Derived Property */
-static const OnigCodePoint CR_Changes_When_Lowercased[] = {
- 590,
- 0x0041, 0x005a,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00de,
- 0x0100, 0x0100,
- 0x0102, 0x0102,
- 0x0104, 0x0104,
- 0x0106, 0x0106,
- 0x0108, 0x0108,
- 0x010a, 0x010a,
- 0x010c, 0x010c,
- 0x010e, 0x010e,
- 0x0110, 0x0110,
- 0x0112, 0x0112,
- 0x0114, 0x0114,
- 0x0116, 0x0116,
- 0x0118, 0x0118,
- 0x011a, 0x011a,
- 0x011c, 0x011c,
- 0x011e, 0x011e,
- 0x0120, 0x0120,
- 0x0122, 0x0122,
- 0x0124, 0x0124,
- 0x0126, 0x0126,
- 0x0128, 0x0128,
- 0x012a, 0x012a,
- 0x012c, 0x012c,
- 0x012e, 0x012e,
- 0x0130, 0x0130,
- 0x0132, 0x0132,
- 0x0134, 0x0134,
- 0x0136, 0x0136,
- 0x0139, 0x0139,
- 0x013b, 0x013b,
- 0x013d, 0x013d,
- 0x013f, 0x013f,
- 0x0141, 0x0141,
- 0x0143, 0x0143,
- 0x0145, 0x0145,
- 0x0147, 0x0147,
- 0x014a, 0x014a,
- 0x014c, 0x014c,
- 0x014e, 0x014e,
- 0x0150, 0x0150,
- 0x0152, 0x0152,
- 0x0154, 0x0154,
- 0x0156, 0x0156,
- 0x0158, 0x0158,
- 0x015a, 0x015a,
- 0x015c, 0x015c,
- 0x015e, 0x015e,
- 0x0160, 0x0160,
- 0x0162, 0x0162,
- 0x0164, 0x0164,
- 0x0166, 0x0166,
- 0x0168, 0x0168,
- 0x016a, 0x016a,
- 0x016c, 0x016c,
- 0x016e, 0x016e,
- 0x0170, 0x0170,
- 0x0172, 0x0172,
- 0x0174, 0x0174,
- 0x0176, 0x0176,
- 0x0178, 0x0179,
- 0x017b, 0x017b,
- 0x017d, 0x017d,
- 0x0181, 0x0182,
- 0x0184, 0x0184,
- 0x0186, 0x0187,
- 0x0189, 0x018b,
- 0x018e, 0x0191,
- 0x0193, 0x0194,
- 0x0196, 0x0198,
- 0x019c, 0x019d,
- 0x019f, 0x01a0,
- 0x01a2, 0x01a2,
- 0x01a4, 0x01a4,
- 0x01a6, 0x01a7,
- 0x01a9, 0x01a9,
- 0x01ac, 0x01ac,
- 0x01ae, 0x01af,
- 0x01b1, 0x01b3,
- 0x01b5, 0x01b5,
- 0x01b7, 0x01b8,
- 0x01bc, 0x01bc,
- 0x01c4, 0x01c5,
- 0x01c7, 0x01c8,
- 0x01ca, 0x01cb,
- 0x01cd, 0x01cd,
- 0x01cf, 0x01cf,
- 0x01d1, 0x01d1,
- 0x01d3, 0x01d3,
- 0x01d5, 0x01d5,
- 0x01d7, 0x01d7,
- 0x01d9, 0x01d9,
- 0x01db, 0x01db,
- 0x01de, 0x01de,
- 0x01e0, 0x01e0,
- 0x01e2, 0x01e2,
- 0x01e4, 0x01e4,
- 0x01e6, 0x01e6,
- 0x01e8, 0x01e8,
- 0x01ea, 0x01ea,
- 0x01ec, 0x01ec,
- 0x01ee, 0x01ee,
- 0x01f1, 0x01f2,
- 0x01f4, 0x01f4,
- 0x01f6, 0x01f8,
- 0x01fa, 0x01fa,
- 0x01fc, 0x01fc,
- 0x01fe, 0x01fe,
- 0x0200, 0x0200,
- 0x0202, 0x0202,
- 0x0204, 0x0204,
- 0x0206, 0x0206,
- 0x0208, 0x0208,
- 0x020a, 0x020a,
- 0x020c, 0x020c,
- 0x020e, 0x020e,
- 0x0210, 0x0210,
- 0x0212, 0x0212,
- 0x0214, 0x0214,
- 0x0216, 0x0216,
- 0x0218, 0x0218,
- 0x021a, 0x021a,
- 0x021c, 0x021c,
- 0x021e, 0x021e,
- 0x0220, 0x0220,
- 0x0222, 0x0222,
- 0x0224, 0x0224,
- 0x0226, 0x0226,
- 0x0228, 0x0228,
- 0x022a, 0x022a,
- 0x022c, 0x022c,
- 0x022e, 0x022e,
- 0x0230, 0x0230,
- 0x0232, 0x0232,
- 0x023a, 0x023b,
- 0x023d, 0x023e,
- 0x0241, 0x0241,
- 0x0243, 0x0246,
- 0x0248, 0x0248,
- 0x024a, 0x024a,
- 0x024c, 0x024c,
- 0x024e, 0x024e,
- 0x0370, 0x0370,
- 0x0372, 0x0372,
- 0x0376, 0x0376,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x038f,
- 0x0391, 0x03a1,
- 0x03a3, 0x03ab,
- 0x03cf, 0x03cf,
- 0x03d8, 0x03d8,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03e2,
- 0x03e4, 0x03e4,
- 0x03e6, 0x03e6,
- 0x03e8, 0x03e8,
- 0x03ea, 0x03ea,
- 0x03ec, 0x03ec,
- 0x03ee, 0x03ee,
- 0x03f4, 0x03f4,
- 0x03f7, 0x03f7,
- 0x03f9, 0x03fa,
- 0x03fd, 0x042f,
- 0x0460, 0x0460,
- 0x0462, 0x0462,
- 0x0464, 0x0464,
- 0x0466, 0x0466,
- 0x0468, 0x0468,
- 0x046a, 0x046a,
- 0x046c, 0x046c,
- 0x046e, 0x046e,
- 0x0470, 0x0470,
- 0x0472, 0x0472,
- 0x0474, 0x0474,
- 0x0476, 0x0476,
- 0x0478, 0x0478,
- 0x047a, 0x047a,
- 0x047c, 0x047c,
- 0x047e, 0x047e,
- 0x0480, 0x0480,
- 0x048a, 0x048a,
- 0x048c, 0x048c,
- 0x048e, 0x048e,
- 0x0490, 0x0490,
- 0x0492, 0x0492,
- 0x0494, 0x0494,
- 0x0496, 0x0496,
- 0x0498, 0x0498,
- 0x049a, 0x049a,
- 0x049c, 0x049c,
- 0x049e, 0x049e,
- 0x04a0, 0x04a0,
- 0x04a2, 0x04a2,
- 0x04a4, 0x04a4,
- 0x04a6, 0x04a6,
- 0x04a8, 0x04a8,
- 0x04aa, 0x04aa,
- 0x04ac, 0x04ac,
- 0x04ae, 0x04ae,
- 0x04b0, 0x04b0,
- 0x04b2, 0x04b2,
- 0x04b4, 0x04b4,
- 0x04b6, 0x04b6,
- 0x04b8, 0x04b8,
- 0x04ba, 0x04ba,
- 0x04bc, 0x04bc,
- 0x04be, 0x04be,
- 0x04c0, 0x04c1,
- 0x04c3, 0x04c3,
- 0x04c5, 0x04c5,
- 0x04c7, 0x04c7,
- 0x04c9, 0x04c9,
- 0x04cb, 0x04cb,
- 0x04cd, 0x04cd,
- 0x04d0, 0x04d0,
- 0x04d2, 0x04d2,
- 0x04d4, 0x04d4,
- 0x04d6, 0x04d6,
- 0x04d8, 0x04d8,
- 0x04da, 0x04da,
- 0x04dc, 0x04dc,
- 0x04de, 0x04de,
- 0x04e0, 0x04e0,
- 0x04e2, 0x04e2,
- 0x04e4, 0x04e4,
- 0x04e6, 0x04e6,
- 0x04e8, 0x04e8,
- 0x04ea, 0x04ea,
- 0x04ec, 0x04ec,
- 0x04ee, 0x04ee,
- 0x04f0, 0x04f0,
- 0x04f2, 0x04f2,
- 0x04f4, 0x04f4,
- 0x04f6, 0x04f6,
- 0x04f8, 0x04f8,
- 0x04fa, 0x04fa,
- 0x04fc, 0x04fc,
- 0x04fe, 0x04fe,
- 0x0500, 0x0500,
- 0x0502, 0x0502,
- 0x0504, 0x0504,
- 0x0506, 0x0506,
- 0x0508, 0x0508,
- 0x050a, 0x050a,
- 0x050c, 0x050c,
- 0x050e, 0x050e,
- 0x0510, 0x0510,
- 0x0512, 0x0512,
- 0x0514, 0x0514,
- 0x0516, 0x0516,
- 0x0518, 0x0518,
- 0x051a, 0x051a,
- 0x051c, 0x051c,
- 0x051e, 0x051e,
- 0x0520, 0x0520,
- 0x0522, 0x0522,
- 0x0524, 0x0524,
- 0x0526, 0x0526,
- 0x0528, 0x0528,
- 0x052a, 0x052a,
- 0x052c, 0x052c,
- 0x052e, 0x052e,
- 0x0531, 0x0556,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x13a0, 0x13f5,
- 0x1e00, 0x1e00,
- 0x1e02, 0x1e02,
- 0x1e04, 0x1e04,
- 0x1e06, 0x1e06,
- 0x1e08, 0x1e08,
- 0x1e0a, 0x1e0a,
- 0x1e0c, 0x1e0c,
- 0x1e0e, 0x1e0e,
- 0x1e10, 0x1e10,
- 0x1e12, 0x1e12,
- 0x1e14, 0x1e14,
- 0x1e16, 0x1e16,
- 0x1e18, 0x1e18,
- 0x1e1a, 0x1e1a,
- 0x1e1c, 0x1e1c,
- 0x1e1e, 0x1e1e,
- 0x1e20, 0x1e20,
- 0x1e22, 0x1e22,
- 0x1e24, 0x1e24,
- 0x1e26, 0x1e26,
- 0x1e28, 0x1e28,
- 0x1e2a, 0x1e2a,
- 0x1e2c, 0x1e2c,
- 0x1e2e, 0x1e2e,
- 0x1e30, 0x1e30,
- 0x1e32, 0x1e32,
- 0x1e34, 0x1e34,
- 0x1e36, 0x1e36,
- 0x1e38, 0x1e38,
- 0x1e3a, 0x1e3a,
- 0x1e3c, 0x1e3c,
- 0x1e3e, 0x1e3e,
- 0x1e40, 0x1e40,
- 0x1e42, 0x1e42,
- 0x1e44, 0x1e44,
- 0x1e46, 0x1e46,
- 0x1e48, 0x1e48,
- 0x1e4a, 0x1e4a,
- 0x1e4c, 0x1e4c,
- 0x1e4e, 0x1e4e,
- 0x1e50, 0x1e50,
- 0x1e52, 0x1e52,
- 0x1e54, 0x1e54,
- 0x1e56, 0x1e56,
- 0x1e58, 0x1e58,
- 0x1e5a, 0x1e5a,
- 0x1e5c, 0x1e5c,
- 0x1e5e, 0x1e5e,
- 0x1e60, 0x1e60,
- 0x1e62, 0x1e62,
- 0x1e64, 0x1e64,
- 0x1e66, 0x1e66,
- 0x1e68, 0x1e68,
- 0x1e6a, 0x1e6a,
- 0x1e6c, 0x1e6c,
- 0x1e6e, 0x1e6e,
- 0x1e70, 0x1e70,
- 0x1e72, 0x1e72,
- 0x1e74, 0x1e74,
- 0x1e76, 0x1e76,
- 0x1e78, 0x1e78,
- 0x1e7a, 0x1e7a,
- 0x1e7c, 0x1e7c,
- 0x1e7e, 0x1e7e,
- 0x1e80, 0x1e80,
- 0x1e82, 0x1e82,
- 0x1e84, 0x1e84,
- 0x1e86, 0x1e86,
- 0x1e88, 0x1e88,
- 0x1e8a, 0x1e8a,
- 0x1e8c, 0x1e8c,
- 0x1e8e, 0x1e8e,
- 0x1e90, 0x1e90,
- 0x1e92, 0x1e92,
- 0x1e94, 0x1e94,
- 0x1e9e, 0x1e9e,
- 0x1ea0, 0x1ea0,
- 0x1ea2, 0x1ea2,
- 0x1ea4, 0x1ea4,
- 0x1ea6, 0x1ea6,
- 0x1ea8, 0x1ea8,
- 0x1eaa, 0x1eaa,
- 0x1eac, 0x1eac,
- 0x1eae, 0x1eae,
- 0x1eb0, 0x1eb0,
- 0x1eb2, 0x1eb2,
- 0x1eb4, 0x1eb4,
- 0x1eb6, 0x1eb6,
- 0x1eb8, 0x1eb8,
- 0x1eba, 0x1eba,
- 0x1ebc, 0x1ebc,
- 0x1ebe, 0x1ebe,
- 0x1ec0, 0x1ec0,
- 0x1ec2, 0x1ec2,
- 0x1ec4, 0x1ec4,
- 0x1ec6, 0x1ec6,
- 0x1ec8, 0x1ec8,
- 0x1eca, 0x1eca,
- 0x1ecc, 0x1ecc,
- 0x1ece, 0x1ece,
- 0x1ed0, 0x1ed0,
- 0x1ed2, 0x1ed2,
- 0x1ed4, 0x1ed4,
- 0x1ed6, 0x1ed6,
- 0x1ed8, 0x1ed8,
- 0x1eda, 0x1eda,
- 0x1edc, 0x1edc,
- 0x1ede, 0x1ede,
- 0x1ee0, 0x1ee0,
- 0x1ee2, 0x1ee2,
- 0x1ee4, 0x1ee4,
- 0x1ee6, 0x1ee6,
- 0x1ee8, 0x1ee8,
- 0x1eea, 0x1eea,
- 0x1eec, 0x1eec,
- 0x1eee, 0x1eee,
- 0x1ef0, 0x1ef0,
- 0x1ef2, 0x1ef2,
- 0x1ef4, 0x1ef4,
- 0x1ef6, 0x1ef6,
- 0x1ef8, 0x1ef8,
- 0x1efa, 0x1efa,
- 0x1efc, 0x1efc,
- 0x1efe, 0x1efe,
- 0x1f08, 0x1f0f,
- 0x1f18, 0x1f1d,
- 0x1f28, 0x1f2f,
- 0x1f38, 0x1f3f,
- 0x1f48, 0x1f4d,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f5f,
- 0x1f68, 0x1f6f,
- 0x1f88, 0x1f8f,
- 0x1f98, 0x1f9f,
- 0x1fa8, 0x1faf,
- 0x1fb8, 0x1fbc,
- 0x1fc8, 0x1fcc,
- 0x1fd8, 0x1fdb,
- 0x1fe8, 0x1fec,
- 0x1ff8, 0x1ffc,
- 0x2126, 0x2126,
- 0x212a, 0x212b,
- 0x2132, 0x2132,
- 0x2160, 0x216f,
- 0x2183, 0x2183,
- 0x24b6, 0x24cf,
- 0x2c00, 0x2c2e,
- 0x2c60, 0x2c60,
- 0x2c62, 0x2c64,
- 0x2c67, 0x2c67,
- 0x2c69, 0x2c69,
- 0x2c6b, 0x2c6b,
- 0x2c6d, 0x2c70,
- 0x2c72, 0x2c72,
- 0x2c75, 0x2c75,
- 0x2c7e, 0x2c80,
- 0x2c82, 0x2c82,
- 0x2c84, 0x2c84,
- 0x2c86, 0x2c86,
- 0x2c88, 0x2c88,
- 0x2c8a, 0x2c8a,
- 0x2c8c, 0x2c8c,
- 0x2c8e, 0x2c8e,
- 0x2c90, 0x2c90,
- 0x2c92, 0x2c92,
- 0x2c94, 0x2c94,
- 0x2c96, 0x2c96,
- 0x2c98, 0x2c98,
- 0x2c9a, 0x2c9a,
- 0x2c9c, 0x2c9c,
- 0x2c9e, 0x2c9e,
- 0x2ca0, 0x2ca0,
- 0x2ca2, 0x2ca2,
- 0x2ca4, 0x2ca4,
- 0x2ca6, 0x2ca6,
- 0x2ca8, 0x2ca8,
- 0x2caa, 0x2caa,
- 0x2cac, 0x2cac,
- 0x2cae, 0x2cae,
- 0x2cb0, 0x2cb0,
- 0x2cb2, 0x2cb2,
- 0x2cb4, 0x2cb4,
- 0x2cb6, 0x2cb6,
- 0x2cb8, 0x2cb8,
- 0x2cba, 0x2cba,
- 0x2cbc, 0x2cbc,
- 0x2cbe, 0x2cbe,
- 0x2cc0, 0x2cc0,
- 0x2cc2, 0x2cc2,
- 0x2cc4, 0x2cc4,
- 0x2cc6, 0x2cc6,
- 0x2cc8, 0x2cc8,
- 0x2cca, 0x2cca,
- 0x2ccc, 0x2ccc,
- 0x2cce, 0x2cce,
- 0x2cd0, 0x2cd0,
- 0x2cd2, 0x2cd2,
- 0x2cd4, 0x2cd4,
- 0x2cd6, 0x2cd6,
- 0x2cd8, 0x2cd8,
- 0x2cda, 0x2cda,
- 0x2cdc, 0x2cdc,
- 0x2cde, 0x2cde,
- 0x2ce0, 0x2ce0,
- 0x2ce2, 0x2ce2,
- 0x2ceb, 0x2ceb,
- 0x2ced, 0x2ced,
- 0x2cf2, 0x2cf2,
- 0xa640, 0xa640,
- 0xa642, 0xa642,
- 0xa644, 0xa644,
- 0xa646, 0xa646,
- 0xa648, 0xa648,
- 0xa64a, 0xa64a,
- 0xa64c, 0xa64c,
- 0xa64e, 0xa64e,
- 0xa650, 0xa650,
- 0xa652, 0xa652,
- 0xa654, 0xa654,
- 0xa656, 0xa656,
- 0xa658, 0xa658,
- 0xa65a, 0xa65a,
- 0xa65c, 0xa65c,
- 0xa65e, 0xa65e,
- 0xa660, 0xa660,
- 0xa662, 0xa662,
- 0xa664, 0xa664,
- 0xa666, 0xa666,
- 0xa668, 0xa668,
- 0xa66a, 0xa66a,
- 0xa66c, 0xa66c,
- 0xa680, 0xa680,
- 0xa682, 0xa682,
- 0xa684, 0xa684,
- 0xa686, 0xa686,
- 0xa688, 0xa688,
- 0xa68a, 0xa68a,
- 0xa68c, 0xa68c,
- 0xa68e, 0xa68e,
- 0xa690, 0xa690,
- 0xa692, 0xa692,
- 0xa694, 0xa694,
- 0xa696, 0xa696,
- 0xa698, 0xa698,
- 0xa69a, 0xa69a,
- 0xa722, 0xa722,
- 0xa724, 0xa724,
- 0xa726, 0xa726,
- 0xa728, 0xa728,
- 0xa72a, 0xa72a,
- 0xa72c, 0xa72c,
- 0xa72e, 0xa72e,
- 0xa732, 0xa732,
- 0xa734, 0xa734,
- 0xa736, 0xa736,
- 0xa738, 0xa738,
- 0xa73a, 0xa73a,
- 0xa73c, 0xa73c,
- 0xa73e, 0xa73e,
- 0xa740, 0xa740,
- 0xa742, 0xa742,
- 0xa744, 0xa744,
- 0xa746, 0xa746,
- 0xa748, 0xa748,
- 0xa74a, 0xa74a,
- 0xa74c, 0xa74c,
- 0xa74e, 0xa74e,
- 0xa750, 0xa750,
- 0xa752, 0xa752,
- 0xa754, 0xa754,
- 0xa756, 0xa756,
- 0xa758, 0xa758,
- 0xa75a, 0xa75a,
- 0xa75c, 0xa75c,
- 0xa75e, 0xa75e,
- 0xa760, 0xa760,
- 0xa762, 0xa762,
- 0xa764, 0xa764,
- 0xa766, 0xa766,
- 0xa768, 0xa768,
- 0xa76a, 0xa76a,
- 0xa76c, 0xa76c,
- 0xa76e, 0xa76e,
- 0xa779, 0xa779,
- 0xa77b, 0xa77b,
- 0xa77d, 0xa77e,
- 0xa780, 0xa780,
- 0xa782, 0xa782,
- 0xa784, 0xa784,
- 0xa786, 0xa786,
- 0xa78b, 0xa78b,
- 0xa78d, 0xa78d,
- 0xa790, 0xa790,
- 0xa792, 0xa792,
- 0xa796, 0xa796,
- 0xa798, 0xa798,
- 0xa79a, 0xa79a,
- 0xa79c, 0xa79c,
- 0xa79e, 0xa79e,
- 0xa7a0, 0xa7a0,
- 0xa7a2, 0xa7a2,
- 0xa7a4, 0xa7a4,
- 0xa7a6, 0xa7a6,
- 0xa7a8, 0xa7a8,
- 0xa7aa, 0xa7ae,
- 0xa7b0, 0xa7b4,
- 0xa7b6, 0xa7b6,
- 0xff21, 0xff3a,
- 0x10400, 0x10427,
- 0x104b0, 0x104d3,
- 0x10c80, 0x10cb2,
- 0x118a0, 0x118bf,
- 0x1e900, 0x1e921,
-}; /* CR_Changes_When_Lowercased */
-
-/* 'Changes_When_Uppercased': Derived Property */
-static const OnigCodePoint CR_Changes_When_Uppercased[] = {
- 607,
- 0x0061, 0x007a,
- 0x00b5, 0x00b5,
- 0x00df, 0x00f6,
- 0x00f8, 0x00ff,
- 0x0101, 0x0101,
- 0x0103, 0x0103,
- 0x0105, 0x0105,
- 0x0107, 0x0107,
- 0x0109, 0x0109,
- 0x010b, 0x010b,
- 0x010d, 0x010d,
- 0x010f, 0x010f,
- 0x0111, 0x0111,
- 0x0113, 0x0113,
- 0x0115, 0x0115,
- 0x0117, 0x0117,
- 0x0119, 0x0119,
- 0x011b, 0x011b,
- 0x011d, 0x011d,
- 0x011f, 0x011f,
- 0x0121, 0x0121,
- 0x0123, 0x0123,
- 0x0125, 0x0125,
- 0x0127, 0x0127,
- 0x0129, 0x0129,
- 0x012b, 0x012b,
- 0x012d, 0x012d,
- 0x012f, 0x012f,
- 0x0131, 0x0131,
- 0x0133, 0x0133,
- 0x0135, 0x0135,
- 0x0137, 0x0137,
- 0x013a, 0x013a,
- 0x013c, 0x013c,
- 0x013e, 0x013e,
- 0x0140, 0x0140,
- 0x0142, 0x0142,
- 0x0144, 0x0144,
- 0x0146, 0x0146,
- 0x0148, 0x0149,
- 0x014b, 0x014b,
- 0x014d, 0x014d,
- 0x014f, 0x014f,
- 0x0151, 0x0151,
- 0x0153, 0x0153,
- 0x0155, 0x0155,
- 0x0157, 0x0157,
- 0x0159, 0x0159,
- 0x015b, 0x015b,
- 0x015d, 0x015d,
- 0x015f, 0x015f,
- 0x0161, 0x0161,
- 0x0163, 0x0163,
- 0x0165, 0x0165,
- 0x0167, 0x0167,
- 0x0169, 0x0169,
- 0x016b, 0x016b,
- 0x016d, 0x016d,
- 0x016f, 0x016f,
- 0x0171, 0x0171,
- 0x0173, 0x0173,
- 0x0175, 0x0175,
- 0x0177, 0x0177,
- 0x017a, 0x017a,
- 0x017c, 0x017c,
- 0x017e, 0x0180,
- 0x0183, 0x0183,
- 0x0185, 0x0185,
- 0x0188, 0x0188,
- 0x018c, 0x018c,
- 0x0192, 0x0192,
- 0x0195, 0x0195,
- 0x0199, 0x019a,
- 0x019e, 0x019e,
- 0x01a1, 0x01a1,
- 0x01a3, 0x01a3,
- 0x01a5, 0x01a5,
- 0x01a8, 0x01a8,
- 0x01ad, 0x01ad,
- 0x01b0, 0x01b0,
- 0x01b4, 0x01b4,
- 0x01b6, 0x01b6,
- 0x01b9, 0x01b9,
- 0x01bd, 0x01bd,
- 0x01bf, 0x01bf,
- 0x01c5, 0x01c6,
- 0x01c8, 0x01c9,
- 0x01cb, 0x01cc,
- 0x01ce, 0x01ce,
- 0x01d0, 0x01d0,
- 0x01d2, 0x01d2,
- 0x01d4, 0x01d4,
- 0x01d6, 0x01d6,
- 0x01d8, 0x01d8,
- 0x01da, 0x01da,
- 0x01dc, 0x01dd,
- 0x01df, 0x01df,
- 0x01e1, 0x01e1,
- 0x01e3, 0x01e3,
- 0x01e5, 0x01e5,
- 0x01e7, 0x01e7,
- 0x01e9, 0x01e9,
- 0x01eb, 0x01eb,
- 0x01ed, 0x01ed,
- 0x01ef, 0x01f0,
- 0x01f2, 0x01f3,
- 0x01f5, 0x01f5,
- 0x01f9, 0x01f9,
- 0x01fb, 0x01fb,
- 0x01fd, 0x01fd,
- 0x01ff, 0x01ff,
- 0x0201, 0x0201,
- 0x0203, 0x0203,
- 0x0205, 0x0205,
- 0x0207, 0x0207,
- 0x0209, 0x0209,
- 0x020b, 0x020b,
- 0x020d, 0x020d,
- 0x020f, 0x020f,
- 0x0211, 0x0211,
- 0x0213, 0x0213,
- 0x0215, 0x0215,
- 0x0217, 0x0217,
- 0x0219, 0x0219,
- 0x021b, 0x021b,
- 0x021d, 0x021d,
- 0x021f, 0x021f,
- 0x0223, 0x0223,
- 0x0225, 0x0225,
- 0x0227, 0x0227,
- 0x0229, 0x0229,
- 0x022b, 0x022b,
- 0x022d, 0x022d,
- 0x022f, 0x022f,
- 0x0231, 0x0231,
- 0x0233, 0x0233,
- 0x023c, 0x023c,
- 0x023f, 0x0240,
- 0x0242, 0x0242,
- 0x0247, 0x0247,
- 0x0249, 0x0249,
- 0x024b, 0x024b,
- 0x024d, 0x024d,
- 0x024f, 0x0254,
- 0x0256, 0x0257,
- 0x0259, 0x0259,
- 0x025b, 0x025c,
- 0x0260, 0x0261,
- 0x0263, 0x0263,
- 0x0265, 0x0266,
- 0x0268, 0x026c,
- 0x026f, 0x026f,
- 0x0271, 0x0272,
- 0x0275, 0x0275,
- 0x027d, 0x027d,
- 0x0280, 0x0280,
- 0x0283, 0x0283,
- 0x0287, 0x028c,
- 0x0292, 0x0292,
- 0x029d, 0x029e,
- 0x0345, 0x0345,
- 0x0371, 0x0371,
- 0x0373, 0x0373,
- 0x0377, 0x0377,
- 0x037b, 0x037d,
- 0x0390, 0x0390,
- 0x03ac, 0x03ce,
- 0x03d0, 0x03d1,
- 0x03d5, 0x03d7,
- 0x03d9, 0x03d9,
- 0x03db, 0x03db,
- 0x03dd, 0x03dd,
- 0x03df, 0x03df,
- 0x03e1, 0x03e1,
- 0x03e3, 0x03e3,
- 0x03e5, 0x03e5,
- 0x03e7, 0x03e7,
- 0x03e9, 0x03e9,
- 0x03eb, 0x03eb,
- 0x03ed, 0x03ed,
- 0x03ef, 0x03f3,
- 0x03f5, 0x03f5,
- 0x03f8, 0x03f8,
- 0x03fb, 0x03fb,
- 0x0430, 0x045f,
- 0x0461, 0x0461,
- 0x0463, 0x0463,
- 0x0465, 0x0465,
- 0x0467, 0x0467,
- 0x0469, 0x0469,
- 0x046b, 0x046b,
- 0x046d, 0x046d,
- 0x046f, 0x046f,
- 0x0471, 0x0471,
- 0x0473, 0x0473,
- 0x0475, 0x0475,
- 0x0477, 0x0477,
- 0x0479, 0x0479,
- 0x047b, 0x047b,
- 0x047d, 0x047d,
- 0x047f, 0x047f,
- 0x0481, 0x0481,
- 0x048b, 0x048b,
- 0x048d, 0x048d,
- 0x048f, 0x048f,
- 0x0491, 0x0491,
- 0x0493, 0x0493,
- 0x0495, 0x0495,
- 0x0497, 0x0497,
- 0x0499, 0x0499,
- 0x049b, 0x049b,
- 0x049d, 0x049d,
- 0x049f, 0x049f,
- 0x04a1, 0x04a1,
- 0x04a3, 0x04a3,
- 0x04a5, 0x04a5,
- 0x04a7, 0x04a7,
- 0x04a9, 0x04a9,
- 0x04ab, 0x04ab,
- 0x04ad, 0x04ad,
- 0x04af, 0x04af,
- 0x04b1, 0x04b1,
- 0x04b3, 0x04b3,
- 0x04b5, 0x04b5,
- 0x04b7, 0x04b7,
- 0x04b9, 0x04b9,
- 0x04bb, 0x04bb,
- 0x04bd, 0x04bd,
- 0x04bf, 0x04bf,
- 0x04c2, 0x04c2,
- 0x04c4, 0x04c4,
- 0x04c6, 0x04c6,
- 0x04c8, 0x04c8,
- 0x04ca, 0x04ca,
- 0x04cc, 0x04cc,
- 0x04ce, 0x04cf,
- 0x04d1, 0x04d1,
- 0x04d3, 0x04d3,
- 0x04d5, 0x04d5,
- 0x04d7, 0x04d7,
- 0x04d9, 0x04d9,
- 0x04db, 0x04db,
- 0x04dd, 0x04dd,
- 0x04df, 0x04df,
- 0x04e1, 0x04e1,
- 0x04e3, 0x04e3,
- 0x04e5, 0x04e5,
- 0x04e7, 0x04e7,
- 0x04e9, 0x04e9,
- 0x04eb, 0x04eb,
- 0x04ed, 0x04ed,
- 0x04ef, 0x04ef,
- 0x04f1, 0x04f1,
- 0x04f3, 0x04f3,
- 0x04f5, 0x04f5,
- 0x04f7, 0x04f7,
- 0x04f9, 0x04f9,
- 0x04fb, 0x04fb,
- 0x04fd, 0x04fd,
- 0x04ff, 0x04ff,
- 0x0501, 0x0501,
- 0x0503, 0x0503,
- 0x0505, 0x0505,
- 0x0507, 0x0507,
- 0x0509, 0x0509,
- 0x050b, 0x050b,
- 0x050d, 0x050d,
- 0x050f, 0x050f,
- 0x0511, 0x0511,
- 0x0513, 0x0513,
- 0x0515, 0x0515,
- 0x0517, 0x0517,
- 0x0519, 0x0519,
- 0x051b, 0x051b,
- 0x051d, 0x051d,
- 0x051f, 0x051f,
- 0x0521, 0x0521,
- 0x0523, 0x0523,
- 0x0525, 0x0525,
- 0x0527, 0x0527,
- 0x0529, 0x0529,
- 0x052b, 0x052b,
- 0x052d, 0x052d,
- 0x052f, 0x052f,
- 0x0561, 0x0587,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1d79, 0x1d79,
- 0x1d7d, 0x1d7d,
- 0x1e01, 0x1e01,
- 0x1e03, 0x1e03,
- 0x1e05, 0x1e05,
- 0x1e07, 0x1e07,
- 0x1e09, 0x1e09,
- 0x1e0b, 0x1e0b,
- 0x1e0d, 0x1e0d,
- 0x1e0f, 0x1e0f,
- 0x1e11, 0x1e11,
- 0x1e13, 0x1e13,
- 0x1e15, 0x1e15,
- 0x1e17, 0x1e17,
- 0x1e19, 0x1e19,
- 0x1e1b, 0x1e1b,
- 0x1e1d, 0x1e1d,
- 0x1e1f, 0x1e1f,
- 0x1e21, 0x1e21,
- 0x1e23, 0x1e23,
- 0x1e25, 0x1e25,
- 0x1e27, 0x1e27,
- 0x1e29, 0x1e29,
- 0x1e2b, 0x1e2b,
- 0x1e2d, 0x1e2d,
- 0x1e2f, 0x1e2f,
- 0x1e31, 0x1e31,
- 0x1e33, 0x1e33,
- 0x1e35, 0x1e35,
- 0x1e37, 0x1e37,
- 0x1e39, 0x1e39,
- 0x1e3b, 0x1e3b,
- 0x1e3d, 0x1e3d,
- 0x1e3f, 0x1e3f,
- 0x1e41, 0x1e41,
- 0x1e43, 0x1e43,
- 0x1e45, 0x1e45,
- 0x1e47, 0x1e47,
- 0x1e49, 0x1e49,
- 0x1e4b, 0x1e4b,
- 0x1e4d, 0x1e4d,
- 0x1e4f, 0x1e4f,
- 0x1e51, 0x1e51,
- 0x1e53, 0x1e53,
- 0x1e55, 0x1e55,
- 0x1e57, 0x1e57,
- 0x1e59, 0x1e59,
- 0x1e5b, 0x1e5b,
- 0x1e5d, 0x1e5d,
- 0x1e5f, 0x1e5f,
- 0x1e61, 0x1e61,
- 0x1e63, 0x1e63,
- 0x1e65, 0x1e65,
- 0x1e67, 0x1e67,
- 0x1e69, 0x1e69,
- 0x1e6b, 0x1e6b,
- 0x1e6d, 0x1e6d,
- 0x1e6f, 0x1e6f,
- 0x1e71, 0x1e71,
- 0x1e73, 0x1e73,
- 0x1e75, 0x1e75,
- 0x1e77, 0x1e77,
- 0x1e79, 0x1e79,
- 0x1e7b, 0x1e7b,
- 0x1e7d, 0x1e7d,
- 0x1e7f, 0x1e7f,
- 0x1e81, 0x1e81,
- 0x1e83, 0x1e83,
- 0x1e85, 0x1e85,
- 0x1e87, 0x1e87,
- 0x1e89, 0x1e89,
- 0x1e8b, 0x1e8b,
- 0x1e8d, 0x1e8d,
- 0x1e8f, 0x1e8f,
- 0x1e91, 0x1e91,
- 0x1e93, 0x1e93,
- 0x1e95, 0x1e9b,
- 0x1ea1, 0x1ea1,
- 0x1ea3, 0x1ea3,
- 0x1ea5, 0x1ea5,
- 0x1ea7, 0x1ea7,
- 0x1ea9, 0x1ea9,
- 0x1eab, 0x1eab,
- 0x1ead, 0x1ead,
- 0x1eaf, 0x1eaf,
- 0x1eb1, 0x1eb1,
- 0x1eb3, 0x1eb3,
- 0x1eb5, 0x1eb5,
- 0x1eb7, 0x1eb7,
- 0x1eb9, 0x1eb9,
- 0x1ebb, 0x1ebb,
- 0x1ebd, 0x1ebd,
- 0x1ebf, 0x1ebf,
- 0x1ec1, 0x1ec1,
- 0x1ec3, 0x1ec3,
- 0x1ec5, 0x1ec5,
- 0x1ec7, 0x1ec7,
- 0x1ec9, 0x1ec9,
- 0x1ecb, 0x1ecb,
- 0x1ecd, 0x1ecd,
- 0x1ecf, 0x1ecf,
- 0x1ed1, 0x1ed1,
- 0x1ed3, 0x1ed3,
- 0x1ed5, 0x1ed5,
- 0x1ed7, 0x1ed7,
- 0x1ed9, 0x1ed9,
- 0x1edb, 0x1edb,
- 0x1edd, 0x1edd,
- 0x1edf, 0x1edf,
- 0x1ee1, 0x1ee1,
- 0x1ee3, 0x1ee3,
- 0x1ee5, 0x1ee5,
- 0x1ee7, 0x1ee7,
- 0x1ee9, 0x1ee9,
- 0x1eeb, 0x1eeb,
- 0x1eed, 0x1eed,
- 0x1eef, 0x1eef,
- 0x1ef1, 0x1ef1,
- 0x1ef3, 0x1ef3,
- 0x1ef5, 0x1ef5,
- 0x1ef7, 0x1ef7,
- 0x1ef9, 0x1ef9,
- 0x1efb, 0x1efb,
- 0x1efd, 0x1efd,
- 0x1eff, 0x1f07,
- 0x1f10, 0x1f15,
- 0x1f20, 0x1f27,
- 0x1f30, 0x1f37,
- 0x1f40, 0x1f45,
- 0x1f50, 0x1f57,
- 0x1f60, 0x1f67,
- 0x1f70, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fb7,
- 0x1fbc, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fc7,
- 0x1fcc, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fd7,
- 0x1fe0, 0x1fe7,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ff7,
- 0x1ffc, 0x1ffc,
- 0x214e, 0x214e,
- 0x2170, 0x217f,
- 0x2184, 0x2184,
- 0x24d0, 0x24e9,
- 0x2c30, 0x2c5e,
- 0x2c61, 0x2c61,
- 0x2c65, 0x2c66,
- 0x2c68, 0x2c68,
- 0x2c6a, 0x2c6a,
- 0x2c6c, 0x2c6c,
- 0x2c73, 0x2c73,
- 0x2c76, 0x2c76,
- 0x2c81, 0x2c81,
- 0x2c83, 0x2c83,
- 0x2c85, 0x2c85,
- 0x2c87, 0x2c87,
- 0x2c89, 0x2c89,
- 0x2c8b, 0x2c8b,
- 0x2c8d, 0x2c8d,
- 0x2c8f, 0x2c8f,
- 0x2c91, 0x2c91,
- 0x2c93, 0x2c93,
- 0x2c95, 0x2c95,
- 0x2c97, 0x2c97,
- 0x2c99, 0x2c99,
- 0x2c9b, 0x2c9b,
- 0x2c9d, 0x2c9d,
- 0x2c9f, 0x2c9f,
- 0x2ca1, 0x2ca1,
- 0x2ca3, 0x2ca3,
- 0x2ca5, 0x2ca5,
- 0x2ca7, 0x2ca7,
- 0x2ca9, 0x2ca9,
- 0x2cab, 0x2cab,
- 0x2cad, 0x2cad,
- 0x2caf, 0x2caf,
- 0x2cb1, 0x2cb1,
- 0x2cb3, 0x2cb3,
- 0x2cb5, 0x2cb5,
- 0x2cb7, 0x2cb7,
- 0x2cb9, 0x2cb9,
- 0x2cbb, 0x2cbb,
- 0x2cbd, 0x2cbd,
- 0x2cbf, 0x2cbf,
- 0x2cc1, 0x2cc1,
- 0x2cc3, 0x2cc3,
- 0x2cc5, 0x2cc5,
- 0x2cc7, 0x2cc7,
- 0x2cc9, 0x2cc9,
- 0x2ccb, 0x2ccb,
- 0x2ccd, 0x2ccd,
- 0x2ccf, 0x2ccf,
- 0x2cd1, 0x2cd1,
- 0x2cd3, 0x2cd3,
- 0x2cd5, 0x2cd5,
- 0x2cd7, 0x2cd7,
- 0x2cd9, 0x2cd9,
- 0x2cdb, 0x2cdb,
- 0x2cdd, 0x2cdd,
- 0x2cdf, 0x2cdf,
- 0x2ce1, 0x2ce1,
- 0x2ce3, 0x2ce3,
- 0x2cec, 0x2cec,
- 0x2cee, 0x2cee,
- 0x2cf3, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0xa641, 0xa641,
- 0xa643, 0xa643,
- 0xa645, 0xa645,
- 0xa647, 0xa647,
- 0xa649, 0xa649,
- 0xa64b, 0xa64b,
- 0xa64d, 0xa64d,
- 0xa64f, 0xa64f,
- 0xa651, 0xa651,
- 0xa653, 0xa653,
- 0xa655, 0xa655,
- 0xa657, 0xa657,
- 0xa659, 0xa659,
- 0xa65b, 0xa65b,
- 0xa65d, 0xa65d,
- 0xa65f, 0xa65f,
- 0xa661, 0xa661,
- 0xa663, 0xa663,
- 0xa665, 0xa665,
- 0xa667, 0xa667,
- 0xa669, 0xa669,
- 0xa66b, 0xa66b,
- 0xa66d, 0xa66d,
- 0xa681, 0xa681,
- 0xa683, 0xa683,
- 0xa685, 0xa685,
- 0xa687, 0xa687,
- 0xa689, 0xa689,
- 0xa68b, 0xa68b,
- 0xa68d, 0xa68d,
- 0xa68f, 0xa68f,
- 0xa691, 0xa691,
- 0xa693, 0xa693,
- 0xa695, 0xa695,
- 0xa697, 0xa697,
- 0xa699, 0xa699,
- 0xa69b, 0xa69b,
- 0xa723, 0xa723,
- 0xa725, 0xa725,
- 0xa727, 0xa727,
- 0xa729, 0xa729,
- 0xa72b, 0xa72b,
- 0xa72d, 0xa72d,
- 0xa72f, 0xa72f,
- 0xa733, 0xa733,
- 0xa735, 0xa735,
- 0xa737, 0xa737,
- 0xa739, 0xa739,
- 0xa73b, 0xa73b,
- 0xa73d, 0xa73d,
- 0xa73f, 0xa73f,
- 0xa741, 0xa741,
- 0xa743, 0xa743,
- 0xa745, 0xa745,
- 0xa747, 0xa747,
- 0xa749, 0xa749,
- 0xa74b, 0xa74b,
- 0xa74d, 0xa74d,
- 0xa74f, 0xa74f,
- 0xa751, 0xa751,
- 0xa753, 0xa753,
- 0xa755, 0xa755,
- 0xa757, 0xa757,
- 0xa759, 0xa759,
- 0xa75b, 0xa75b,
- 0xa75d, 0xa75d,
- 0xa75f, 0xa75f,
- 0xa761, 0xa761,
- 0xa763, 0xa763,
- 0xa765, 0xa765,
- 0xa767, 0xa767,
- 0xa769, 0xa769,
- 0xa76b, 0xa76b,
- 0xa76d, 0xa76d,
- 0xa76f, 0xa76f,
- 0xa77a, 0xa77a,
- 0xa77c, 0xa77c,
- 0xa77f, 0xa77f,
- 0xa781, 0xa781,
- 0xa783, 0xa783,
- 0xa785, 0xa785,
- 0xa787, 0xa787,
- 0xa78c, 0xa78c,
- 0xa791, 0xa791,
- 0xa793, 0xa793,
- 0xa797, 0xa797,
- 0xa799, 0xa799,
- 0xa79b, 0xa79b,
- 0xa79d, 0xa79d,
- 0xa79f, 0xa79f,
- 0xa7a1, 0xa7a1,
- 0xa7a3, 0xa7a3,
- 0xa7a5, 0xa7a5,
- 0xa7a7, 0xa7a7,
- 0xa7a9, 0xa7a9,
- 0xa7b5, 0xa7b5,
- 0xa7b7, 0xa7b7,
- 0xab53, 0xab53,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff41, 0xff5a,
- 0x10428, 0x1044f,
- 0x104d8, 0x104fb,
- 0x10cc0, 0x10cf2,
- 0x118c0, 0x118df,
- 0x1e922, 0x1e943,
-}; /* CR_Changes_When_Uppercased */
-
-/* 'Changes_When_Titlecased': Derived Property */
-static const OnigCodePoint CR_Changes_When_Titlecased[] = {
- 608,
- 0x0061, 0x007a,
- 0x00b5, 0x00b5,
- 0x00df, 0x00f6,
- 0x00f8, 0x00ff,
- 0x0101, 0x0101,
- 0x0103, 0x0103,
- 0x0105, 0x0105,
- 0x0107, 0x0107,
- 0x0109, 0x0109,
- 0x010b, 0x010b,
- 0x010d, 0x010d,
- 0x010f, 0x010f,
- 0x0111, 0x0111,
- 0x0113, 0x0113,
- 0x0115, 0x0115,
- 0x0117, 0x0117,
- 0x0119, 0x0119,
- 0x011b, 0x011b,
- 0x011d, 0x011d,
- 0x011f, 0x011f,
- 0x0121, 0x0121,
- 0x0123, 0x0123,
- 0x0125, 0x0125,
- 0x0127, 0x0127,
- 0x0129, 0x0129,
- 0x012b, 0x012b,
- 0x012d, 0x012d,
- 0x012f, 0x012f,
- 0x0131, 0x0131,
- 0x0133, 0x0133,
- 0x0135, 0x0135,
- 0x0137, 0x0137,
- 0x013a, 0x013a,
- 0x013c, 0x013c,
- 0x013e, 0x013e,
- 0x0140, 0x0140,
- 0x0142, 0x0142,
- 0x0144, 0x0144,
- 0x0146, 0x0146,
- 0x0148, 0x0149,
- 0x014b, 0x014b,
- 0x014d, 0x014d,
- 0x014f, 0x014f,
- 0x0151, 0x0151,
- 0x0153, 0x0153,
- 0x0155, 0x0155,
- 0x0157, 0x0157,
- 0x0159, 0x0159,
- 0x015b, 0x015b,
- 0x015d, 0x015d,
- 0x015f, 0x015f,
- 0x0161, 0x0161,
- 0x0163, 0x0163,
- 0x0165, 0x0165,
- 0x0167, 0x0167,
- 0x0169, 0x0169,
- 0x016b, 0x016b,
- 0x016d, 0x016d,
- 0x016f, 0x016f,
- 0x0171, 0x0171,
- 0x0173, 0x0173,
- 0x0175, 0x0175,
- 0x0177, 0x0177,
- 0x017a, 0x017a,
- 0x017c, 0x017c,
- 0x017e, 0x0180,
- 0x0183, 0x0183,
- 0x0185, 0x0185,
- 0x0188, 0x0188,
- 0x018c, 0x018c,
- 0x0192, 0x0192,
- 0x0195, 0x0195,
- 0x0199, 0x019a,
- 0x019e, 0x019e,
- 0x01a1, 0x01a1,
- 0x01a3, 0x01a3,
- 0x01a5, 0x01a5,
- 0x01a8, 0x01a8,
- 0x01ad, 0x01ad,
- 0x01b0, 0x01b0,
- 0x01b4, 0x01b4,
- 0x01b6, 0x01b6,
- 0x01b9, 0x01b9,
- 0x01bd, 0x01bd,
- 0x01bf, 0x01bf,
- 0x01c4, 0x01c4,
- 0x01c6, 0x01c7,
- 0x01c9, 0x01ca,
- 0x01cc, 0x01cc,
- 0x01ce, 0x01ce,
- 0x01d0, 0x01d0,
- 0x01d2, 0x01d2,
- 0x01d4, 0x01d4,
- 0x01d6, 0x01d6,
- 0x01d8, 0x01d8,
- 0x01da, 0x01da,
- 0x01dc, 0x01dd,
- 0x01df, 0x01df,
- 0x01e1, 0x01e1,
- 0x01e3, 0x01e3,
- 0x01e5, 0x01e5,
- 0x01e7, 0x01e7,
- 0x01e9, 0x01e9,
- 0x01eb, 0x01eb,
- 0x01ed, 0x01ed,
- 0x01ef, 0x01f1,
- 0x01f3, 0x01f3,
- 0x01f5, 0x01f5,
- 0x01f9, 0x01f9,
- 0x01fb, 0x01fb,
- 0x01fd, 0x01fd,
- 0x01ff, 0x01ff,
- 0x0201, 0x0201,
- 0x0203, 0x0203,
- 0x0205, 0x0205,
- 0x0207, 0x0207,
- 0x0209, 0x0209,
- 0x020b, 0x020b,
- 0x020d, 0x020d,
- 0x020f, 0x020f,
- 0x0211, 0x0211,
- 0x0213, 0x0213,
- 0x0215, 0x0215,
- 0x0217, 0x0217,
- 0x0219, 0x0219,
- 0x021b, 0x021b,
- 0x021d, 0x021d,
- 0x021f, 0x021f,
- 0x0223, 0x0223,
- 0x0225, 0x0225,
- 0x0227, 0x0227,
- 0x0229, 0x0229,
- 0x022b, 0x022b,
- 0x022d, 0x022d,
- 0x022f, 0x022f,
- 0x0231, 0x0231,
- 0x0233, 0x0233,
- 0x023c, 0x023c,
- 0x023f, 0x0240,
- 0x0242, 0x0242,
- 0x0247, 0x0247,
- 0x0249, 0x0249,
- 0x024b, 0x024b,
- 0x024d, 0x024d,
- 0x024f, 0x0254,
- 0x0256, 0x0257,
- 0x0259, 0x0259,
- 0x025b, 0x025c,
- 0x0260, 0x0261,
- 0x0263, 0x0263,
- 0x0265, 0x0266,
- 0x0268, 0x026c,
- 0x026f, 0x026f,
- 0x0271, 0x0272,
- 0x0275, 0x0275,
- 0x027d, 0x027d,
- 0x0280, 0x0280,
- 0x0283, 0x0283,
- 0x0287, 0x028c,
- 0x0292, 0x0292,
- 0x029d, 0x029e,
- 0x0345, 0x0345,
- 0x0371, 0x0371,
- 0x0373, 0x0373,
- 0x0377, 0x0377,
- 0x037b, 0x037d,
- 0x0390, 0x0390,
- 0x03ac, 0x03ce,
- 0x03d0, 0x03d1,
- 0x03d5, 0x03d7,
- 0x03d9, 0x03d9,
- 0x03db, 0x03db,
- 0x03dd, 0x03dd,
- 0x03df, 0x03df,
- 0x03e1, 0x03e1,
- 0x03e3, 0x03e3,
- 0x03e5, 0x03e5,
- 0x03e7, 0x03e7,
- 0x03e9, 0x03e9,
- 0x03eb, 0x03eb,
- 0x03ed, 0x03ed,
- 0x03ef, 0x03f3,
- 0x03f5, 0x03f5,
- 0x03f8, 0x03f8,
- 0x03fb, 0x03fb,
- 0x0430, 0x045f,
- 0x0461, 0x0461,
- 0x0463, 0x0463,
- 0x0465, 0x0465,
- 0x0467, 0x0467,
- 0x0469, 0x0469,
- 0x046b, 0x046b,
- 0x046d, 0x046d,
- 0x046f, 0x046f,
- 0x0471, 0x0471,
- 0x0473, 0x0473,
- 0x0475, 0x0475,
- 0x0477, 0x0477,
- 0x0479, 0x0479,
- 0x047b, 0x047b,
- 0x047d, 0x047d,
- 0x047f, 0x047f,
- 0x0481, 0x0481,
- 0x048b, 0x048b,
- 0x048d, 0x048d,
- 0x048f, 0x048f,
- 0x0491, 0x0491,
- 0x0493, 0x0493,
- 0x0495, 0x0495,
- 0x0497, 0x0497,
- 0x0499, 0x0499,
- 0x049b, 0x049b,
- 0x049d, 0x049d,
- 0x049f, 0x049f,
- 0x04a1, 0x04a1,
- 0x04a3, 0x04a3,
- 0x04a5, 0x04a5,
- 0x04a7, 0x04a7,
- 0x04a9, 0x04a9,
- 0x04ab, 0x04ab,
- 0x04ad, 0x04ad,
- 0x04af, 0x04af,
- 0x04b1, 0x04b1,
- 0x04b3, 0x04b3,
- 0x04b5, 0x04b5,
- 0x04b7, 0x04b7,
- 0x04b9, 0x04b9,
- 0x04bb, 0x04bb,
- 0x04bd, 0x04bd,
- 0x04bf, 0x04bf,
- 0x04c2, 0x04c2,
- 0x04c4, 0x04c4,
- 0x04c6, 0x04c6,
- 0x04c8, 0x04c8,
- 0x04ca, 0x04ca,
- 0x04cc, 0x04cc,
- 0x04ce, 0x04cf,
- 0x04d1, 0x04d1,
- 0x04d3, 0x04d3,
- 0x04d5, 0x04d5,
- 0x04d7, 0x04d7,
- 0x04d9, 0x04d9,
- 0x04db, 0x04db,
- 0x04dd, 0x04dd,
- 0x04df, 0x04df,
- 0x04e1, 0x04e1,
- 0x04e3, 0x04e3,
- 0x04e5, 0x04e5,
- 0x04e7, 0x04e7,
- 0x04e9, 0x04e9,
- 0x04eb, 0x04eb,
- 0x04ed, 0x04ed,
- 0x04ef, 0x04ef,
- 0x04f1, 0x04f1,
- 0x04f3, 0x04f3,
- 0x04f5, 0x04f5,
- 0x04f7, 0x04f7,
- 0x04f9, 0x04f9,
- 0x04fb, 0x04fb,
- 0x04fd, 0x04fd,
- 0x04ff, 0x04ff,
- 0x0501, 0x0501,
- 0x0503, 0x0503,
- 0x0505, 0x0505,
- 0x0507, 0x0507,
- 0x0509, 0x0509,
- 0x050b, 0x050b,
- 0x050d, 0x050d,
- 0x050f, 0x050f,
- 0x0511, 0x0511,
- 0x0513, 0x0513,
- 0x0515, 0x0515,
- 0x0517, 0x0517,
- 0x0519, 0x0519,
- 0x051b, 0x051b,
- 0x051d, 0x051d,
- 0x051f, 0x051f,
- 0x0521, 0x0521,
- 0x0523, 0x0523,
- 0x0525, 0x0525,
- 0x0527, 0x0527,
- 0x0529, 0x0529,
- 0x052b, 0x052b,
- 0x052d, 0x052d,
- 0x052f, 0x052f,
- 0x0561, 0x0587,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1d79, 0x1d79,
- 0x1d7d, 0x1d7d,
- 0x1e01, 0x1e01,
- 0x1e03, 0x1e03,
- 0x1e05, 0x1e05,
- 0x1e07, 0x1e07,
- 0x1e09, 0x1e09,
- 0x1e0b, 0x1e0b,
- 0x1e0d, 0x1e0d,
- 0x1e0f, 0x1e0f,
- 0x1e11, 0x1e11,
- 0x1e13, 0x1e13,
- 0x1e15, 0x1e15,
- 0x1e17, 0x1e17,
- 0x1e19, 0x1e19,
- 0x1e1b, 0x1e1b,
- 0x1e1d, 0x1e1d,
- 0x1e1f, 0x1e1f,
- 0x1e21, 0x1e21,
- 0x1e23, 0x1e23,
- 0x1e25, 0x1e25,
- 0x1e27, 0x1e27,
- 0x1e29, 0x1e29,
- 0x1e2b, 0x1e2b,
- 0x1e2d, 0x1e2d,
- 0x1e2f, 0x1e2f,
- 0x1e31, 0x1e31,
- 0x1e33, 0x1e33,
- 0x1e35, 0x1e35,
- 0x1e37, 0x1e37,
- 0x1e39, 0x1e39,
- 0x1e3b, 0x1e3b,
- 0x1e3d, 0x1e3d,
- 0x1e3f, 0x1e3f,
- 0x1e41, 0x1e41,
- 0x1e43, 0x1e43,
- 0x1e45, 0x1e45,
- 0x1e47, 0x1e47,
- 0x1e49, 0x1e49,
- 0x1e4b, 0x1e4b,
- 0x1e4d, 0x1e4d,
- 0x1e4f, 0x1e4f,
- 0x1e51, 0x1e51,
- 0x1e53, 0x1e53,
- 0x1e55, 0x1e55,
- 0x1e57, 0x1e57,
- 0x1e59, 0x1e59,
- 0x1e5b, 0x1e5b,
- 0x1e5d, 0x1e5d,
- 0x1e5f, 0x1e5f,
- 0x1e61, 0x1e61,
- 0x1e63, 0x1e63,
- 0x1e65, 0x1e65,
- 0x1e67, 0x1e67,
- 0x1e69, 0x1e69,
- 0x1e6b, 0x1e6b,
- 0x1e6d, 0x1e6d,
- 0x1e6f, 0x1e6f,
- 0x1e71, 0x1e71,
- 0x1e73, 0x1e73,
- 0x1e75, 0x1e75,
- 0x1e77, 0x1e77,
- 0x1e79, 0x1e79,
- 0x1e7b, 0x1e7b,
- 0x1e7d, 0x1e7d,
- 0x1e7f, 0x1e7f,
- 0x1e81, 0x1e81,
- 0x1e83, 0x1e83,
- 0x1e85, 0x1e85,
- 0x1e87, 0x1e87,
- 0x1e89, 0x1e89,
- 0x1e8b, 0x1e8b,
- 0x1e8d, 0x1e8d,
- 0x1e8f, 0x1e8f,
- 0x1e91, 0x1e91,
- 0x1e93, 0x1e93,
- 0x1e95, 0x1e9b,
- 0x1ea1, 0x1ea1,
- 0x1ea3, 0x1ea3,
- 0x1ea5, 0x1ea5,
- 0x1ea7, 0x1ea7,
- 0x1ea9, 0x1ea9,
- 0x1eab, 0x1eab,
- 0x1ead, 0x1ead,
- 0x1eaf, 0x1eaf,
- 0x1eb1, 0x1eb1,
- 0x1eb3, 0x1eb3,
- 0x1eb5, 0x1eb5,
- 0x1eb7, 0x1eb7,
- 0x1eb9, 0x1eb9,
- 0x1ebb, 0x1ebb,
- 0x1ebd, 0x1ebd,
- 0x1ebf, 0x1ebf,
- 0x1ec1, 0x1ec1,
- 0x1ec3, 0x1ec3,
- 0x1ec5, 0x1ec5,
- 0x1ec7, 0x1ec7,
- 0x1ec9, 0x1ec9,
- 0x1ecb, 0x1ecb,
- 0x1ecd, 0x1ecd,
- 0x1ecf, 0x1ecf,
- 0x1ed1, 0x1ed1,
- 0x1ed3, 0x1ed3,
- 0x1ed5, 0x1ed5,
- 0x1ed7, 0x1ed7,
- 0x1ed9, 0x1ed9,
- 0x1edb, 0x1edb,
- 0x1edd, 0x1edd,
- 0x1edf, 0x1edf,
- 0x1ee1, 0x1ee1,
- 0x1ee3, 0x1ee3,
- 0x1ee5, 0x1ee5,
- 0x1ee7, 0x1ee7,
- 0x1ee9, 0x1ee9,
- 0x1eeb, 0x1eeb,
- 0x1eed, 0x1eed,
- 0x1eef, 0x1eef,
- 0x1ef1, 0x1ef1,
- 0x1ef3, 0x1ef3,
- 0x1ef5, 0x1ef5,
- 0x1ef7, 0x1ef7,
- 0x1ef9, 0x1ef9,
- 0x1efb, 0x1efb,
- 0x1efd, 0x1efd,
- 0x1eff, 0x1f07,
- 0x1f10, 0x1f15,
- 0x1f20, 0x1f27,
- 0x1f30, 0x1f37,
- 0x1f40, 0x1f45,
- 0x1f50, 0x1f57,
- 0x1f60, 0x1f67,
- 0x1f70, 0x1f7d,
- 0x1f80, 0x1f87,
- 0x1f90, 0x1f97,
- 0x1fa0, 0x1fa7,
- 0x1fb0, 0x1fb4,
- 0x1fb6, 0x1fb7,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fc7,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fd7,
- 0x1fe0, 0x1fe7,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ff7,
- 0x214e, 0x214e,
- 0x2170, 0x217f,
- 0x2184, 0x2184,
- 0x24d0, 0x24e9,
- 0x2c30, 0x2c5e,
- 0x2c61, 0x2c61,
- 0x2c65, 0x2c66,
- 0x2c68, 0x2c68,
- 0x2c6a, 0x2c6a,
- 0x2c6c, 0x2c6c,
- 0x2c73, 0x2c73,
- 0x2c76, 0x2c76,
- 0x2c81, 0x2c81,
- 0x2c83, 0x2c83,
- 0x2c85, 0x2c85,
- 0x2c87, 0x2c87,
- 0x2c89, 0x2c89,
- 0x2c8b, 0x2c8b,
- 0x2c8d, 0x2c8d,
- 0x2c8f, 0x2c8f,
- 0x2c91, 0x2c91,
- 0x2c93, 0x2c93,
- 0x2c95, 0x2c95,
- 0x2c97, 0x2c97,
- 0x2c99, 0x2c99,
- 0x2c9b, 0x2c9b,
- 0x2c9d, 0x2c9d,
- 0x2c9f, 0x2c9f,
- 0x2ca1, 0x2ca1,
- 0x2ca3, 0x2ca3,
- 0x2ca5, 0x2ca5,
- 0x2ca7, 0x2ca7,
- 0x2ca9, 0x2ca9,
- 0x2cab, 0x2cab,
- 0x2cad, 0x2cad,
- 0x2caf, 0x2caf,
- 0x2cb1, 0x2cb1,
- 0x2cb3, 0x2cb3,
- 0x2cb5, 0x2cb5,
- 0x2cb7, 0x2cb7,
- 0x2cb9, 0x2cb9,
- 0x2cbb, 0x2cbb,
- 0x2cbd, 0x2cbd,
- 0x2cbf, 0x2cbf,
- 0x2cc1, 0x2cc1,
- 0x2cc3, 0x2cc3,
- 0x2cc5, 0x2cc5,
- 0x2cc7, 0x2cc7,
- 0x2cc9, 0x2cc9,
- 0x2ccb, 0x2ccb,
- 0x2ccd, 0x2ccd,
- 0x2ccf, 0x2ccf,
- 0x2cd1, 0x2cd1,
- 0x2cd3, 0x2cd3,
- 0x2cd5, 0x2cd5,
- 0x2cd7, 0x2cd7,
- 0x2cd9, 0x2cd9,
- 0x2cdb, 0x2cdb,
- 0x2cdd, 0x2cdd,
- 0x2cdf, 0x2cdf,
- 0x2ce1, 0x2ce1,
- 0x2ce3, 0x2ce3,
- 0x2cec, 0x2cec,
- 0x2cee, 0x2cee,
- 0x2cf3, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0xa641, 0xa641,
- 0xa643, 0xa643,
- 0xa645, 0xa645,
- 0xa647, 0xa647,
- 0xa649, 0xa649,
- 0xa64b, 0xa64b,
- 0xa64d, 0xa64d,
- 0xa64f, 0xa64f,
- 0xa651, 0xa651,
- 0xa653, 0xa653,
- 0xa655, 0xa655,
- 0xa657, 0xa657,
- 0xa659, 0xa659,
- 0xa65b, 0xa65b,
- 0xa65d, 0xa65d,
- 0xa65f, 0xa65f,
- 0xa661, 0xa661,
- 0xa663, 0xa663,
- 0xa665, 0xa665,
- 0xa667, 0xa667,
- 0xa669, 0xa669,
- 0xa66b, 0xa66b,
- 0xa66d, 0xa66d,
- 0xa681, 0xa681,
- 0xa683, 0xa683,
- 0xa685, 0xa685,
- 0xa687, 0xa687,
- 0xa689, 0xa689,
- 0xa68b, 0xa68b,
- 0xa68d, 0xa68d,
- 0xa68f, 0xa68f,
- 0xa691, 0xa691,
- 0xa693, 0xa693,
- 0xa695, 0xa695,
- 0xa697, 0xa697,
- 0xa699, 0xa699,
- 0xa69b, 0xa69b,
- 0xa723, 0xa723,
- 0xa725, 0xa725,
- 0xa727, 0xa727,
- 0xa729, 0xa729,
- 0xa72b, 0xa72b,
- 0xa72d, 0xa72d,
- 0xa72f, 0xa72f,
- 0xa733, 0xa733,
- 0xa735, 0xa735,
- 0xa737, 0xa737,
- 0xa739, 0xa739,
- 0xa73b, 0xa73b,
- 0xa73d, 0xa73d,
- 0xa73f, 0xa73f,
- 0xa741, 0xa741,
- 0xa743, 0xa743,
- 0xa745, 0xa745,
- 0xa747, 0xa747,
- 0xa749, 0xa749,
- 0xa74b, 0xa74b,
- 0xa74d, 0xa74d,
- 0xa74f, 0xa74f,
- 0xa751, 0xa751,
- 0xa753, 0xa753,
- 0xa755, 0xa755,
- 0xa757, 0xa757,
- 0xa759, 0xa759,
- 0xa75b, 0xa75b,
- 0xa75d, 0xa75d,
- 0xa75f, 0xa75f,
- 0xa761, 0xa761,
- 0xa763, 0xa763,
- 0xa765, 0xa765,
- 0xa767, 0xa767,
- 0xa769, 0xa769,
- 0xa76b, 0xa76b,
- 0xa76d, 0xa76d,
- 0xa76f, 0xa76f,
- 0xa77a, 0xa77a,
- 0xa77c, 0xa77c,
- 0xa77f, 0xa77f,
- 0xa781, 0xa781,
- 0xa783, 0xa783,
- 0xa785, 0xa785,
- 0xa787, 0xa787,
- 0xa78c, 0xa78c,
- 0xa791, 0xa791,
- 0xa793, 0xa793,
- 0xa797, 0xa797,
- 0xa799, 0xa799,
- 0xa79b, 0xa79b,
- 0xa79d, 0xa79d,
- 0xa79f, 0xa79f,
- 0xa7a1, 0xa7a1,
- 0xa7a3, 0xa7a3,
- 0xa7a5, 0xa7a5,
- 0xa7a7, 0xa7a7,
- 0xa7a9, 0xa7a9,
- 0xa7b5, 0xa7b5,
- 0xa7b7, 0xa7b7,
- 0xab53, 0xab53,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff41, 0xff5a,
- 0x10428, 0x1044f,
- 0x104d8, 0x104fb,
- 0x10cc0, 0x10cf2,
- 0x118c0, 0x118df,
- 0x1e922, 0x1e943,
-}; /* CR_Changes_When_Titlecased */
-
-/* 'Changes_When_Casefolded': Derived Property */
-static const OnigCodePoint CR_Changes_When_Casefolded[] = {
- 603,
- 0x0041, 0x005a,
- 0x00b5, 0x00b5,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00df,
- 0x0100, 0x0100,
- 0x0102, 0x0102,
- 0x0104, 0x0104,
- 0x0106, 0x0106,
- 0x0108, 0x0108,
- 0x010a, 0x010a,
- 0x010c, 0x010c,
- 0x010e, 0x010e,
- 0x0110, 0x0110,
- 0x0112, 0x0112,
- 0x0114, 0x0114,
- 0x0116, 0x0116,
- 0x0118, 0x0118,
- 0x011a, 0x011a,
- 0x011c, 0x011c,
- 0x011e, 0x011e,
- 0x0120, 0x0120,
- 0x0122, 0x0122,
- 0x0124, 0x0124,
- 0x0126, 0x0126,
- 0x0128, 0x0128,
- 0x012a, 0x012a,
- 0x012c, 0x012c,
- 0x012e, 0x012e,
- 0x0130, 0x0130,
- 0x0132, 0x0132,
- 0x0134, 0x0134,
- 0x0136, 0x0136,
- 0x0139, 0x0139,
- 0x013b, 0x013b,
- 0x013d, 0x013d,
- 0x013f, 0x013f,
- 0x0141, 0x0141,
- 0x0143, 0x0143,
- 0x0145, 0x0145,
- 0x0147, 0x0147,
- 0x0149, 0x014a,
- 0x014c, 0x014c,
- 0x014e, 0x014e,
- 0x0150, 0x0150,
- 0x0152, 0x0152,
- 0x0154, 0x0154,
- 0x0156, 0x0156,
- 0x0158, 0x0158,
- 0x015a, 0x015a,
- 0x015c, 0x015c,
- 0x015e, 0x015e,
- 0x0160, 0x0160,
- 0x0162, 0x0162,
- 0x0164, 0x0164,
- 0x0166, 0x0166,
- 0x0168, 0x0168,
- 0x016a, 0x016a,
- 0x016c, 0x016c,
- 0x016e, 0x016e,
- 0x0170, 0x0170,
- 0x0172, 0x0172,
- 0x0174, 0x0174,
- 0x0176, 0x0176,
- 0x0178, 0x0179,
- 0x017b, 0x017b,
- 0x017d, 0x017d,
- 0x017f, 0x017f,
- 0x0181, 0x0182,
- 0x0184, 0x0184,
- 0x0186, 0x0187,
- 0x0189, 0x018b,
- 0x018e, 0x0191,
- 0x0193, 0x0194,
- 0x0196, 0x0198,
- 0x019c, 0x019d,
- 0x019f, 0x01a0,
- 0x01a2, 0x01a2,
- 0x01a4, 0x01a4,
- 0x01a6, 0x01a7,
- 0x01a9, 0x01a9,
- 0x01ac, 0x01ac,
- 0x01ae, 0x01af,
- 0x01b1, 0x01b3,
- 0x01b5, 0x01b5,
- 0x01b7, 0x01b8,
- 0x01bc, 0x01bc,
- 0x01c4, 0x01c5,
- 0x01c7, 0x01c8,
- 0x01ca, 0x01cb,
- 0x01cd, 0x01cd,
- 0x01cf, 0x01cf,
- 0x01d1, 0x01d1,
- 0x01d3, 0x01d3,
- 0x01d5, 0x01d5,
- 0x01d7, 0x01d7,
- 0x01d9, 0x01d9,
- 0x01db, 0x01db,
- 0x01de, 0x01de,
- 0x01e0, 0x01e0,
- 0x01e2, 0x01e2,
- 0x01e4, 0x01e4,
- 0x01e6, 0x01e6,
- 0x01e8, 0x01e8,
- 0x01ea, 0x01ea,
- 0x01ec, 0x01ec,
- 0x01ee, 0x01ee,
- 0x01f1, 0x01f2,
- 0x01f4, 0x01f4,
- 0x01f6, 0x01f8,
- 0x01fa, 0x01fa,
- 0x01fc, 0x01fc,
- 0x01fe, 0x01fe,
- 0x0200, 0x0200,
- 0x0202, 0x0202,
- 0x0204, 0x0204,
- 0x0206, 0x0206,
- 0x0208, 0x0208,
- 0x020a, 0x020a,
- 0x020c, 0x020c,
- 0x020e, 0x020e,
- 0x0210, 0x0210,
- 0x0212, 0x0212,
- 0x0214, 0x0214,
- 0x0216, 0x0216,
- 0x0218, 0x0218,
- 0x021a, 0x021a,
- 0x021c, 0x021c,
- 0x021e, 0x021e,
- 0x0220, 0x0220,
- 0x0222, 0x0222,
- 0x0224, 0x0224,
- 0x0226, 0x0226,
- 0x0228, 0x0228,
- 0x022a, 0x022a,
- 0x022c, 0x022c,
- 0x022e, 0x022e,
- 0x0230, 0x0230,
- 0x0232, 0x0232,
- 0x023a, 0x023b,
- 0x023d, 0x023e,
- 0x0241, 0x0241,
- 0x0243, 0x0246,
- 0x0248, 0x0248,
- 0x024a, 0x024a,
- 0x024c, 0x024c,
- 0x024e, 0x024e,
- 0x0345, 0x0345,
- 0x0370, 0x0370,
- 0x0372, 0x0372,
- 0x0376, 0x0376,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x038f,
- 0x0391, 0x03a1,
- 0x03a3, 0x03ab,
- 0x03c2, 0x03c2,
- 0x03cf, 0x03d1,
- 0x03d5, 0x03d6,
- 0x03d8, 0x03d8,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03e2,
- 0x03e4, 0x03e4,
- 0x03e6, 0x03e6,
- 0x03e8, 0x03e8,
- 0x03ea, 0x03ea,
- 0x03ec, 0x03ec,
- 0x03ee, 0x03ee,
- 0x03f0, 0x03f1,
- 0x03f4, 0x03f5,
- 0x03f7, 0x03f7,
- 0x03f9, 0x03fa,
- 0x03fd, 0x042f,
- 0x0460, 0x0460,
- 0x0462, 0x0462,
- 0x0464, 0x0464,
- 0x0466, 0x0466,
- 0x0468, 0x0468,
- 0x046a, 0x046a,
- 0x046c, 0x046c,
- 0x046e, 0x046e,
- 0x0470, 0x0470,
- 0x0472, 0x0472,
- 0x0474, 0x0474,
- 0x0476, 0x0476,
- 0x0478, 0x0478,
- 0x047a, 0x047a,
- 0x047c, 0x047c,
- 0x047e, 0x047e,
- 0x0480, 0x0480,
- 0x048a, 0x048a,
- 0x048c, 0x048c,
- 0x048e, 0x048e,
- 0x0490, 0x0490,
- 0x0492, 0x0492,
- 0x0494, 0x0494,
- 0x0496, 0x0496,
- 0x0498, 0x0498,
- 0x049a, 0x049a,
- 0x049c, 0x049c,
- 0x049e, 0x049e,
- 0x04a0, 0x04a0,
- 0x04a2, 0x04a2,
- 0x04a4, 0x04a4,
- 0x04a6, 0x04a6,
- 0x04a8, 0x04a8,
- 0x04aa, 0x04aa,
- 0x04ac, 0x04ac,
- 0x04ae, 0x04ae,
- 0x04b0, 0x04b0,
- 0x04b2, 0x04b2,
- 0x04b4, 0x04b4,
- 0x04b6, 0x04b6,
- 0x04b8, 0x04b8,
- 0x04ba, 0x04ba,
- 0x04bc, 0x04bc,
- 0x04be, 0x04be,
- 0x04c0, 0x04c1,
- 0x04c3, 0x04c3,
- 0x04c5, 0x04c5,
- 0x04c7, 0x04c7,
- 0x04c9, 0x04c9,
- 0x04cb, 0x04cb,
- 0x04cd, 0x04cd,
- 0x04d0, 0x04d0,
- 0x04d2, 0x04d2,
- 0x04d4, 0x04d4,
- 0x04d6, 0x04d6,
- 0x04d8, 0x04d8,
- 0x04da, 0x04da,
- 0x04dc, 0x04dc,
- 0x04de, 0x04de,
- 0x04e0, 0x04e0,
- 0x04e2, 0x04e2,
- 0x04e4, 0x04e4,
- 0x04e6, 0x04e6,
- 0x04e8, 0x04e8,
- 0x04ea, 0x04ea,
- 0x04ec, 0x04ec,
- 0x04ee, 0x04ee,
- 0x04f0, 0x04f0,
- 0x04f2, 0x04f2,
- 0x04f4, 0x04f4,
- 0x04f6, 0x04f6,
- 0x04f8, 0x04f8,
- 0x04fa, 0x04fa,
- 0x04fc, 0x04fc,
- 0x04fe, 0x04fe,
- 0x0500, 0x0500,
- 0x0502, 0x0502,
- 0x0504, 0x0504,
- 0x0506, 0x0506,
- 0x0508, 0x0508,
- 0x050a, 0x050a,
- 0x050c, 0x050c,
- 0x050e, 0x050e,
- 0x0510, 0x0510,
- 0x0512, 0x0512,
- 0x0514, 0x0514,
- 0x0516, 0x0516,
- 0x0518, 0x0518,
- 0x051a, 0x051a,
- 0x051c, 0x051c,
- 0x051e, 0x051e,
- 0x0520, 0x0520,
- 0x0522, 0x0522,
- 0x0524, 0x0524,
- 0x0526, 0x0526,
- 0x0528, 0x0528,
- 0x052a, 0x052a,
- 0x052c, 0x052c,
- 0x052e, 0x052e,
- 0x0531, 0x0556,
- 0x0587, 0x0587,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1e00, 0x1e00,
- 0x1e02, 0x1e02,
- 0x1e04, 0x1e04,
- 0x1e06, 0x1e06,
- 0x1e08, 0x1e08,
- 0x1e0a, 0x1e0a,
- 0x1e0c, 0x1e0c,
- 0x1e0e, 0x1e0e,
- 0x1e10, 0x1e10,
- 0x1e12, 0x1e12,
- 0x1e14, 0x1e14,
- 0x1e16, 0x1e16,
- 0x1e18, 0x1e18,
- 0x1e1a, 0x1e1a,
- 0x1e1c, 0x1e1c,
- 0x1e1e, 0x1e1e,
- 0x1e20, 0x1e20,
- 0x1e22, 0x1e22,
- 0x1e24, 0x1e24,
- 0x1e26, 0x1e26,
- 0x1e28, 0x1e28,
- 0x1e2a, 0x1e2a,
- 0x1e2c, 0x1e2c,
- 0x1e2e, 0x1e2e,
- 0x1e30, 0x1e30,
- 0x1e32, 0x1e32,
- 0x1e34, 0x1e34,
- 0x1e36, 0x1e36,
- 0x1e38, 0x1e38,
- 0x1e3a, 0x1e3a,
- 0x1e3c, 0x1e3c,
- 0x1e3e, 0x1e3e,
- 0x1e40, 0x1e40,
- 0x1e42, 0x1e42,
- 0x1e44, 0x1e44,
- 0x1e46, 0x1e46,
- 0x1e48, 0x1e48,
- 0x1e4a, 0x1e4a,
- 0x1e4c, 0x1e4c,
- 0x1e4e, 0x1e4e,
- 0x1e50, 0x1e50,
- 0x1e52, 0x1e52,
- 0x1e54, 0x1e54,
- 0x1e56, 0x1e56,
- 0x1e58, 0x1e58,
- 0x1e5a, 0x1e5a,
- 0x1e5c, 0x1e5c,
- 0x1e5e, 0x1e5e,
- 0x1e60, 0x1e60,
- 0x1e62, 0x1e62,
- 0x1e64, 0x1e64,
- 0x1e66, 0x1e66,
- 0x1e68, 0x1e68,
- 0x1e6a, 0x1e6a,
- 0x1e6c, 0x1e6c,
- 0x1e6e, 0x1e6e,
- 0x1e70, 0x1e70,
- 0x1e72, 0x1e72,
- 0x1e74, 0x1e74,
- 0x1e76, 0x1e76,
- 0x1e78, 0x1e78,
- 0x1e7a, 0x1e7a,
- 0x1e7c, 0x1e7c,
- 0x1e7e, 0x1e7e,
- 0x1e80, 0x1e80,
- 0x1e82, 0x1e82,
- 0x1e84, 0x1e84,
- 0x1e86, 0x1e86,
- 0x1e88, 0x1e88,
- 0x1e8a, 0x1e8a,
- 0x1e8c, 0x1e8c,
- 0x1e8e, 0x1e8e,
- 0x1e90, 0x1e90,
- 0x1e92, 0x1e92,
- 0x1e94, 0x1e94,
- 0x1e9a, 0x1e9b,
- 0x1e9e, 0x1e9e,
- 0x1ea0, 0x1ea0,
- 0x1ea2, 0x1ea2,
- 0x1ea4, 0x1ea4,
- 0x1ea6, 0x1ea6,
- 0x1ea8, 0x1ea8,
- 0x1eaa, 0x1eaa,
- 0x1eac, 0x1eac,
- 0x1eae, 0x1eae,
- 0x1eb0, 0x1eb0,
- 0x1eb2, 0x1eb2,
- 0x1eb4, 0x1eb4,
- 0x1eb6, 0x1eb6,
- 0x1eb8, 0x1eb8,
- 0x1eba, 0x1eba,
- 0x1ebc, 0x1ebc,
- 0x1ebe, 0x1ebe,
- 0x1ec0, 0x1ec0,
- 0x1ec2, 0x1ec2,
- 0x1ec4, 0x1ec4,
- 0x1ec6, 0x1ec6,
- 0x1ec8, 0x1ec8,
- 0x1eca, 0x1eca,
- 0x1ecc, 0x1ecc,
- 0x1ece, 0x1ece,
- 0x1ed0, 0x1ed0,
- 0x1ed2, 0x1ed2,
- 0x1ed4, 0x1ed4,
- 0x1ed6, 0x1ed6,
- 0x1ed8, 0x1ed8,
- 0x1eda, 0x1eda,
- 0x1edc, 0x1edc,
- 0x1ede, 0x1ede,
- 0x1ee0, 0x1ee0,
- 0x1ee2, 0x1ee2,
- 0x1ee4, 0x1ee4,
- 0x1ee6, 0x1ee6,
- 0x1ee8, 0x1ee8,
- 0x1eea, 0x1eea,
- 0x1eec, 0x1eec,
- 0x1eee, 0x1eee,
- 0x1ef0, 0x1ef0,
- 0x1ef2, 0x1ef2,
- 0x1ef4, 0x1ef4,
- 0x1ef6, 0x1ef6,
- 0x1ef8, 0x1ef8,
- 0x1efa, 0x1efa,
- 0x1efc, 0x1efc,
- 0x1efe, 0x1efe,
- 0x1f08, 0x1f0f,
- 0x1f18, 0x1f1d,
- 0x1f28, 0x1f2f,
- 0x1f38, 0x1f3f,
- 0x1f48, 0x1f4d,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f5f,
- 0x1f68, 0x1f6f,
- 0x1f80, 0x1faf,
- 0x1fb2, 0x1fb4,
- 0x1fb7, 0x1fbc,
- 0x1fc2, 0x1fc4,
- 0x1fc7, 0x1fcc,
- 0x1fd8, 0x1fdb,
- 0x1fe8, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff7, 0x1ffc,
- 0x2126, 0x2126,
- 0x212a, 0x212b,
- 0x2132, 0x2132,
- 0x2160, 0x216f,
- 0x2183, 0x2183,
- 0x24b6, 0x24cf,
- 0x2c00, 0x2c2e,
- 0x2c60, 0x2c60,
- 0x2c62, 0x2c64,
- 0x2c67, 0x2c67,
- 0x2c69, 0x2c69,
- 0x2c6b, 0x2c6b,
- 0x2c6d, 0x2c70,
- 0x2c72, 0x2c72,
- 0x2c75, 0x2c75,
- 0x2c7e, 0x2c80,
- 0x2c82, 0x2c82,
- 0x2c84, 0x2c84,
- 0x2c86, 0x2c86,
- 0x2c88, 0x2c88,
- 0x2c8a, 0x2c8a,
- 0x2c8c, 0x2c8c,
- 0x2c8e, 0x2c8e,
- 0x2c90, 0x2c90,
- 0x2c92, 0x2c92,
- 0x2c94, 0x2c94,
- 0x2c96, 0x2c96,
- 0x2c98, 0x2c98,
- 0x2c9a, 0x2c9a,
- 0x2c9c, 0x2c9c,
- 0x2c9e, 0x2c9e,
- 0x2ca0, 0x2ca0,
- 0x2ca2, 0x2ca2,
- 0x2ca4, 0x2ca4,
- 0x2ca6, 0x2ca6,
- 0x2ca8, 0x2ca8,
- 0x2caa, 0x2caa,
- 0x2cac, 0x2cac,
- 0x2cae, 0x2cae,
- 0x2cb0, 0x2cb0,
- 0x2cb2, 0x2cb2,
- 0x2cb4, 0x2cb4,
- 0x2cb6, 0x2cb6,
- 0x2cb8, 0x2cb8,
- 0x2cba, 0x2cba,
- 0x2cbc, 0x2cbc,
- 0x2cbe, 0x2cbe,
- 0x2cc0, 0x2cc0,
- 0x2cc2, 0x2cc2,
- 0x2cc4, 0x2cc4,
- 0x2cc6, 0x2cc6,
- 0x2cc8, 0x2cc8,
- 0x2cca, 0x2cca,
- 0x2ccc, 0x2ccc,
- 0x2cce, 0x2cce,
- 0x2cd0, 0x2cd0,
- 0x2cd2, 0x2cd2,
- 0x2cd4, 0x2cd4,
- 0x2cd6, 0x2cd6,
- 0x2cd8, 0x2cd8,
- 0x2cda, 0x2cda,
- 0x2cdc, 0x2cdc,
- 0x2cde, 0x2cde,
- 0x2ce0, 0x2ce0,
- 0x2ce2, 0x2ce2,
- 0x2ceb, 0x2ceb,
- 0x2ced, 0x2ced,
- 0x2cf2, 0x2cf2,
- 0xa640, 0xa640,
- 0xa642, 0xa642,
- 0xa644, 0xa644,
- 0xa646, 0xa646,
- 0xa648, 0xa648,
- 0xa64a, 0xa64a,
- 0xa64c, 0xa64c,
- 0xa64e, 0xa64e,
- 0xa650, 0xa650,
- 0xa652, 0xa652,
- 0xa654, 0xa654,
- 0xa656, 0xa656,
- 0xa658, 0xa658,
- 0xa65a, 0xa65a,
- 0xa65c, 0xa65c,
- 0xa65e, 0xa65e,
- 0xa660, 0xa660,
- 0xa662, 0xa662,
- 0xa664, 0xa664,
- 0xa666, 0xa666,
- 0xa668, 0xa668,
- 0xa66a, 0xa66a,
- 0xa66c, 0xa66c,
- 0xa680, 0xa680,
- 0xa682, 0xa682,
- 0xa684, 0xa684,
- 0xa686, 0xa686,
- 0xa688, 0xa688,
- 0xa68a, 0xa68a,
- 0xa68c, 0xa68c,
- 0xa68e, 0xa68e,
- 0xa690, 0xa690,
- 0xa692, 0xa692,
- 0xa694, 0xa694,
- 0xa696, 0xa696,
- 0xa698, 0xa698,
- 0xa69a, 0xa69a,
- 0xa722, 0xa722,
- 0xa724, 0xa724,
- 0xa726, 0xa726,
- 0xa728, 0xa728,
- 0xa72a, 0xa72a,
- 0xa72c, 0xa72c,
- 0xa72e, 0xa72e,
- 0xa732, 0xa732,
- 0xa734, 0xa734,
- 0xa736, 0xa736,
- 0xa738, 0xa738,
- 0xa73a, 0xa73a,
- 0xa73c, 0xa73c,
- 0xa73e, 0xa73e,
- 0xa740, 0xa740,
- 0xa742, 0xa742,
- 0xa744, 0xa744,
- 0xa746, 0xa746,
- 0xa748, 0xa748,
- 0xa74a, 0xa74a,
- 0xa74c, 0xa74c,
- 0xa74e, 0xa74e,
- 0xa750, 0xa750,
- 0xa752, 0xa752,
- 0xa754, 0xa754,
- 0xa756, 0xa756,
- 0xa758, 0xa758,
- 0xa75a, 0xa75a,
- 0xa75c, 0xa75c,
- 0xa75e, 0xa75e,
- 0xa760, 0xa760,
- 0xa762, 0xa762,
- 0xa764, 0xa764,
- 0xa766, 0xa766,
- 0xa768, 0xa768,
- 0xa76a, 0xa76a,
- 0xa76c, 0xa76c,
- 0xa76e, 0xa76e,
- 0xa779, 0xa779,
- 0xa77b, 0xa77b,
- 0xa77d, 0xa77e,
- 0xa780, 0xa780,
- 0xa782, 0xa782,
- 0xa784, 0xa784,
- 0xa786, 0xa786,
- 0xa78b, 0xa78b,
- 0xa78d, 0xa78d,
- 0xa790, 0xa790,
- 0xa792, 0xa792,
- 0xa796, 0xa796,
- 0xa798, 0xa798,
- 0xa79a, 0xa79a,
- 0xa79c, 0xa79c,
- 0xa79e, 0xa79e,
- 0xa7a0, 0xa7a0,
- 0xa7a2, 0xa7a2,
- 0xa7a4, 0xa7a4,
- 0xa7a6, 0xa7a6,
- 0xa7a8, 0xa7a8,
- 0xa7aa, 0xa7ae,
- 0xa7b0, 0xa7b4,
- 0xa7b6, 0xa7b6,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff21, 0xff3a,
- 0x10400, 0x10427,
- 0x104b0, 0x104d3,
- 0x10c80, 0x10cb2,
- 0x118a0, 0x118bf,
- 0x1e900, 0x1e921,
-}; /* CR_Changes_When_Casefolded */
-
-/* 'Changes_When_Casemapped': Derived Property */
-static const OnigCodePoint CR_Changes_When_Casemapped[] = {
- 116,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00b5, 0x00b5,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x0137,
- 0x0139, 0x018c,
- 0x018e, 0x019a,
- 0x019c, 0x01a9,
- 0x01ac, 0x01b9,
- 0x01bc, 0x01bd,
- 0x01bf, 0x01bf,
- 0x01c4, 0x0220,
- 0x0222, 0x0233,
- 0x023a, 0x0254,
- 0x0256, 0x0257,
- 0x0259, 0x0259,
- 0x025b, 0x025c,
- 0x0260, 0x0261,
- 0x0263, 0x0263,
- 0x0265, 0x0266,
- 0x0268, 0x026c,
- 0x026f, 0x026f,
- 0x0271, 0x0272,
- 0x0275, 0x0275,
- 0x027d, 0x027d,
- 0x0280, 0x0280,
- 0x0283, 0x0283,
- 0x0287, 0x028c,
- 0x0292, 0x0292,
- 0x029d, 0x029e,
- 0x0345, 0x0345,
- 0x0370, 0x0373,
- 0x0376, 0x0377,
- 0x037b, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03d1,
- 0x03d5, 0x03f5,
- 0x03f7, 0x03fb,
- 0x03fd, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0561, 0x0587,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1c80, 0x1c88,
- 0x1d79, 0x1d79,
- 0x1d7d, 0x1d7d,
- 0x1e00, 0x1e9b,
- 0x1e9e, 0x1e9e,
- 0x1ea0, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2126, 0x2126,
- 0x212a, 0x212b,
- 0x2132, 0x2132,
- 0x214e, 0x214e,
- 0x2160, 0x217f,
- 0x2183, 0x2184,
- 0x24b6, 0x24e9,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2c70,
- 0x2c72, 0x2c73,
- 0x2c75, 0x2c76,
- 0x2c7e, 0x2ce3,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0xa640, 0xa66d,
- 0xa680, 0xa69b,
- 0xa722, 0xa72f,
- 0xa732, 0xa76f,
- 0xa779, 0xa787,
- 0xa78b, 0xa78d,
- 0xa790, 0xa793,
- 0xa796, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xab53, 0xab53,
- 0xab70, 0xabbf,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0x10400, 0x1044f,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x118a0, 0x118df,
- 0x1e900, 0x1e943,
-}; /* CR_Changes_When_Casemapped */
-
-/* 'ID_Start': Derived Property */
-static const OnigCodePoint CR_ID_Start[] = {
- 585,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0370, 0x0374,
- 0x0376, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0620, 0x064a,
- 0x066e, 0x066f,
- 0x0671, 0x06d3,
- 0x06d5, 0x06d5,
- 0x06e5, 0x06e6,
- 0x06ee, 0x06ef,
- 0x06fa, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x0710,
- 0x0712, 0x072f,
- 0x074d, 0x07a5,
- 0x07b1, 0x07b1,
- 0x07ca, 0x07ea,
- 0x07f4, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x0815,
- 0x081a, 0x081a,
- 0x0824, 0x0824,
- 0x0828, 0x0828,
- 0x0840, 0x0858,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x0904, 0x0939,
- 0x093d, 0x093d,
- 0x0950, 0x0950,
- 0x0958, 0x0961,
- 0x0971, 0x0980,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bd, 0x09bd,
- 0x09ce, 0x09ce,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e1,
- 0x09f0, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a72, 0x0a74,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abd, 0x0abd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae1,
- 0x0af9, 0x0af9,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3d, 0x0b3d,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b71, 0x0b71,
- 0x0b83, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bd0, 0x0bd0,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c3d,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c61,
- 0x0c80, 0x0c80,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbd, 0x0cbd,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0cf1, 0x0cf2,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d3d,
- 0x0d4e, 0x0d4e,
- 0x0d54, 0x0d56,
- 0x0d5f, 0x0d61,
- 0x0d7a, 0x0d7f,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0e01, 0x0e30,
- 0x0e32, 0x0e33,
- 0x0e40, 0x0e46,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb0,
- 0x0eb2, 0x0eb3,
- 0x0ebd, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f40, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f88, 0x0f8c,
- 0x1000, 0x102a,
- 0x103f, 0x103f,
- 0x1050, 0x1055,
- 0x105a, 0x105d,
- 0x1061, 0x1061,
- 0x1065, 0x1066,
- 0x106e, 0x1070,
- 0x1075, 0x1081,
- 0x108e, 0x108e,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1711,
- 0x1720, 0x1731,
- 0x1740, 0x1751,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1780, 0x17b3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dc,
- 0x1820, 0x1877,
- 0x1880, 0x18a8,
- 0x18aa, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1950, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x1a00, 0x1a16,
- 0x1a20, 0x1a54,
- 0x1aa7, 0x1aa7,
- 0x1b05, 0x1b33,
- 0x1b45, 0x1b4b,
- 0x1b83, 0x1ba0,
- 0x1bae, 0x1baf,
- 0x1bba, 0x1be5,
- 0x1c00, 0x1c23,
- 0x1c4d, 0x1c4f,
- 0x1c5a, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf1,
- 0x1cf5, 0x1cf6,
- 0x1d00, 0x1dbf,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2118, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x3005, 0x3007,
- 0x3021, 0x3029,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x309b, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa61f,
- 0xa62a, 0xa62b,
- 0xa640, 0xa66e,
- 0xa67f, 0xa69d,
- 0xa6a0, 0xa6ef,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa801,
- 0xa803, 0xa805,
- 0xa807, 0xa80a,
- 0xa80c, 0xa822,
- 0xa840, 0xa873,
- 0xa882, 0xa8b3,
- 0xa8f2, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa90a, 0xa925,
- 0xa930, 0xa946,
- 0xa960, 0xa97c,
- 0xa984, 0xa9b2,
- 0xa9cf, 0xa9cf,
- 0xa9e0, 0xa9e4,
- 0xa9e6, 0xa9ef,
- 0xa9fa, 0xa9fe,
- 0xaa00, 0xaa28,
- 0xaa40, 0xaa42,
- 0xaa44, 0xaa4b,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaa7a,
- 0xaa7e, 0xaaaf,
- 0xaab1, 0xaab1,
- 0xaab5, 0xaab6,
- 0xaab9, 0xaabd,
- 0xaac0, 0xaac0,
- 0xaac2, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaea,
- 0xaaf2, 0xaaf4,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabe2,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb1d,
- 0xfb1f, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10140, 0x10174,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031f,
- 0x1032d, 0x1034a,
- 0x10350, 0x10375,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x103d1, 0x103d5,
- 0x10400, 0x1049d,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a00,
- 0x10a10, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae4,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11003, 0x11037,
- 0x11083, 0x110af,
- 0x110d0, 0x110e8,
- 0x11103, 0x11126,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11183, 0x111b2,
- 0x111c1, 0x111c4,
- 0x111da, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x1122b,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112de,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133d, 0x1133d,
- 0x11350, 0x11350,
- 0x1135d, 0x11361,
- 0x11400, 0x11434,
- 0x11447, 0x1144a,
- 0x11480, 0x114af,
- 0x114c4, 0x114c5,
- 0x114c7, 0x114c7,
- 0x11580, 0x115ae,
- 0x115d8, 0x115db,
- 0x11600, 0x1162f,
- 0x11644, 0x11644,
- 0x11680, 0x116aa,
- 0x11700, 0x11719,
- 0x118a0, 0x118df,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a00,
- 0x11a0b, 0x11a32,
- 0x11a3a, 0x11a3a,
- 0x11a50, 0x11a50,
- 0x11a5c, 0x11a83,
- 0x11a86, 0x11a89,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c2e,
- 0x11c40, 0x11c40,
- 0x11c72, 0x11c8f,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d30,
- 0x11d46, 0x11d46,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16ad0, 0x16aed,
- 0x16b00, 0x16b2f,
- 0x16b40, 0x16b43,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f50,
- 0x16f93, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1e800, 0x1e8c4,
- 0x1e900, 0x1e943,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_ID_Start */
-
-/* 'ID_Continue': Derived Property */
-static const OnigCodePoint CR_ID_Continue[] = {
- 689,
- 0x0030, 0x0039,
- 0x0041, 0x005a,
- 0x005f, 0x005f,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00b7, 0x00b7,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0300, 0x0374,
- 0x0376, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x0483, 0x0487,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x0591, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x061a,
- 0x0620, 0x0669,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06df, 0x06e8,
- 0x06ea, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x082d,
- 0x0840, 0x085b,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x08e1,
- 0x08e3, 0x0963,
- 0x0966, 0x096f,
- 0x0971, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af9, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b6f,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bef,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c80, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d54, 0x0d57,
- 0x0d5f, 0x0d63,
- 0x0d66, 0x0d6f,
- 0x0d7a, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e4e,
- 0x0e50, 0x0e59,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f18, 0x0f19,
- 0x0f20, 0x0f29,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x1000, 0x1049,
- 0x1050, 0x109d,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x135f,
- 0x1369, 0x1371,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1734,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dd,
- 0x17e0, 0x17e9,
- 0x180b, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1946, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x1a00, 0x1a1b,
- 0x1a20, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa7, 0x1aa7,
- 0x1ab0, 0x1abd,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b59,
- 0x1b6b, 0x1b73,
- 0x1b80, 0x1bf3,
- 0x1c00, 0x1c37,
- 0x1c40, 0x1c49,
- 0x1c4d, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1cf9,
- 0x1d00, 0x1df9,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x203f, 0x2040,
- 0x2054, 0x2054,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x20d0, 0x20dc,
- 0x20e1, 0x20e1,
- 0x20e5, 0x20f0,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2118, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2dff,
- 0x3005, 0x3007,
- 0x3021, 0x302f,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x3099, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa62b,
- 0xa640, 0xa66f,
- 0xa674, 0xa67d,
- 0xa67f, 0xa6f1,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa827,
- 0xa840, 0xa873,
- 0xa880, 0xa8c5,
- 0xa8d0, 0xa8d9,
- 0xa8e0, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa900, 0xa92d,
- 0xa930, 0xa953,
- 0xa960, 0xa97c,
- 0xa980, 0xa9c0,
- 0xa9cf, 0xa9d9,
- 0xa9e0, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaef,
- 0xaaf2, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabea,
- 0xabec, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe2f,
- 0xfe33, 0xfe34,
- 0xfe4d, 0xfe4f,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff10, 0xff19,
- 0xff21, 0xff3a,
- 0xff3f, 0xff3f,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10140, 0x10174,
- 0x101fd, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102e0,
- 0x10300, 0x1031f,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x103d1, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a3f,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae6,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11000, 0x11046,
- 0x11066, 0x1106f,
- 0x1107f, 0x110ba,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x1113f,
- 0x11150, 0x11173,
- 0x11176, 0x11176,
- 0x11180, 0x111c4,
- 0x111ca, 0x111cc,
- 0x111d0, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x11237,
- 0x1123e, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x1144a,
- 0x11450, 0x11459,
- 0x11480, 0x114c5,
- 0x114c7, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115c0,
- 0x115d8, 0x115dd,
- 0x11600, 0x11640,
- 0x11644, 0x11644,
- 0x11650, 0x11659,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x11739,
- 0x118a0, 0x118e9,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a3e,
- 0x11a47, 0x11a47,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a99,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c40,
- 0x11c50, 0x11c59,
- 0x11c72, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af4,
- 0x16b00, 0x16b36,
- 0x16b40, 0x16b43,
- 0x16b50, 0x16b59,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9d, 0x1bc9e,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d242, 0x1d244,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1da00, 0x1da36,
- 0x1da3b, 0x1da6c,
- 0x1da75, 0x1da75,
- 0x1da84, 0x1da84,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8d0, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
- 0xe0100, 0xe01ef,
-}; /* CR_ID_Continue */
-
-/* 'XID_Start': Derived Property */
-static const OnigCodePoint CR_XID_Start[] = {
- 592,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0370, 0x0374,
- 0x0376, 0x0377,
- 0x037b, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0620, 0x064a,
- 0x066e, 0x066f,
- 0x0671, 0x06d3,
- 0x06d5, 0x06d5,
- 0x06e5, 0x06e6,
- 0x06ee, 0x06ef,
- 0x06fa, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x0710,
- 0x0712, 0x072f,
- 0x074d, 0x07a5,
- 0x07b1, 0x07b1,
- 0x07ca, 0x07ea,
- 0x07f4, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x0815,
- 0x081a, 0x081a,
- 0x0824, 0x0824,
- 0x0828, 0x0828,
- 0x0840, 0x0858,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x0904, 0x0939,
- 0x093d, 0x093d,
- 0x0950, 0x0950,
- 0x0958, 0x0961,
- 0x0971, 0x0980,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bd, 0x09bd,
- 0x09ce, 0x09ce,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e1,
- 0x09f0, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a72, 0x0a74,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abd, 0x0abd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae1,
- 0x0af9, 0x0af9,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3d, 0x0b3d,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b71, 0x0b71,
- 0x0b83, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bd0, 0x0bd0,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c3d,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c61,
- 0x0c80, 0x0c80,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbd, 0x0cbd,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0cf1, 0x0cf2,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d3d,
- 0x0d4e, 0x0d4e,
- 0x0d54, 0x0d56,
- 0x0d5f, 0x0d61,
- 0x0d7a, 0x0d7f,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0e01, 0x0e30,
- 0x0e32, 0x0e32,
- 0x0e40, 0x0e46,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb0,
- 0x0eb2, 0x0eb2,
- 0x0ebd, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f40, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f88, 0x0f8c,
- 0x1000, 0x102a,
- 0x103f, 0x103f,
- 0x1050, 0x1055,
- 0x105a, 0x105d,
- 0x1061, 0x1061,
- 0x1065, 0x1066,
- 0x106e, 0x1070,
- 0x1075, 0x1081,
- 0x108e, 0x108e,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1711,
- 0x1720, 0x1731,
- 0x1740, 0x1751,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1780, 0x17b3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dc,
- 0x1820, 0x1877,
- 0x1880, 0x18a8,
- 0x18aa, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1950, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x1a00, 0x1a16,
- 0x1a20, 0x1a54,
- 0x1aa7, 0x1aa7,
- 0x1b05, 0x1b33,
- 0x1b45, 0x1b4b,
- 0x1b83, 0x1ba0,
- 0x1bae, 0x1baf,
- 0x1bba, 0x1be5,
- 0x1c00, 0x1c23,
- 0x1c4d, 0x1c4f,
- 0x1c5a, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf1,
- 0x1cf5, 0x1cf6,
- 0x1d00, 0x1dbf,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2118, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x3005, 0x3007,
- 0x3021, 0x3029,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa61f,
- 0xa62a, 0xa62b,
- 0xa640, 0xa66e,
- 0xa67f, 0xa69d,
- 0xa6a0, 0xa6ef,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa801,
- 0xa803, 0xa805,
- 0xa807, 0xa80a,
- 0xa80c, 0xa822,
- 0xa840, 0xa873,
- 0xa882, 0xa8b3,
- 0xa8f2, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa90a, 0xa925,
- 0xa930, 0xa946,
- 0xa960, 0xa97c,
- 0xa984, 0xa9b2,
- 0xa9cf, 0xa9cf,
- 0xa9e0, 0xa9e4,
- 0xa9e6, 0xa9ef,
- 0xa9fa, 0xa9fe,
- 0xaa00, 0xaa28,
- 0xaa40, 0xaa42,
- 0xaa44, 0xaa4b,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaa7a,
- 0xaa7e, 0xaaaf,
- 0xaab1, 0xaab1,
- 0xaab5, 0xaab6,
- 0xaab9, 0xaabd,
- 0xaac0, 0xaac0,
- 0xaac2, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaea,
- 0xaaf2, 0xaaf4,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabe2,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb1d,
- 0xfb1f, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfc5d,
- 0xfc64, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdf9,
- 0xfe71, 0xfe71,
- 0xfe73, 0xfe73,
- 0xfe77, 0xfe77,
- 0xfe79, 0xfe79,
- 0xfe7b, 0xfe7b,
- 0xfe7d, 0xfe7d,
- 0xfe7f, 0xfefc,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xff9d,
- 0xffa0, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10140, 0x10174,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031f,
- 0x1032d, 0x1034a,
- 0x10350, 0x10375,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x103d1, 0x103d5,
- 0x10400, 0x1049d,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a00,
- 0x10a10, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae4,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11003, 0x11037,
- 0x11083, 0x110af,
- 0x110d0, 0x110e8,
- 0x11103, 0x11126,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11183, 0x111b2,
- 0x111c1, 0x111c4,
- 0x111da, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x1122b,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112de,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133d, 0x1133d,
- 0x11350, 0x11350,
- 0x1135d, 0x11361,
- 0x11400, 0x11434,
- 0x11447, 0x1144a,
- 0x11480, 0x114af,
- 0x114c4, 0x114c5,
- 0x114c7, 0x114c7,
- 0x11580, 0x115ae,
- 0x115d8, 0x115db,
- 0x11600, 0x1162f,
- 0x11644, 0x11644,
- 0x11680, 0x116aa,
- 0x11700, 0x11719,
- 0x118a0, 0x118df,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a00,
- 0x11a0b, 0x11a32,
- 0x11a3a, 0x11a3a,
- 0x11a50, 0x11a50,
- 0x11a5c, 0x11a83,
- 0x11a86, 0x11a89,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c2e,
- 0x11c40, 0x11c40,
- 0x11c72, 0x11c8f,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d30,
- 0x11d46, 0x11d46,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16ad0, 0x16aed,
- 0x16b00, 0x16b2f,
- 0x16b40, 0x16b43,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f50,
- 0x16f93, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1e800, 0x1e8c4,
- 0x1e900, 0x1e943,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_XID_Start */
-
-/* 'XID_Continue': Derived Property */
-static const OnigCodePoint CR_XID_Continue[] = {
- 696,
- 0x0030, 0x0039,
- 0x0041, 0x005a,
- 0x005f, 0x005f,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00b7, 0x00b7,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ec, 0x02ec,
- 0x02ee, 0x02ee,
- 0x0300, 0x0374,
- 0x0376, 0x0377,
- 0x037b, 0x037d,
- 0x037f, 0x037f,
- 0x0386, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03f5,
- 0x03f7, 0x0481,
- 0x0483, 0x0487,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x0591, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x061a,
- 0x0620, 0x0669,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06df, 0x06e8,
- 0x06ea, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07f5,
- 0x07fa, 0x07fa,
- 0x0800, 0x082d,
- 0x0840, 0x085b,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x08e1,
- 0x08e3, 0x0963,
- 0x0966, 0x096f,
- 0x0971, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09f1,
- 0x09fc, 0x09fc,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af9, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b6f,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bef,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c80, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d54, 0x0d57,
- 0x0d5f, 0x0d63,
- 0x0d66, 0x0d6f,
- 0x0d7a, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e4e,
- 0x0e50, 0x0e59,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f00,
- 0x0f18, 0x0f19,
- 0x0f20, 0x0f29,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x1000, 0x1049,
- 0x1050, 0x109d,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x135f,
- 0x1369, 0x1371,
- 0x1380, 0x138f,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1401, 0x166c,
- 0x166f, 0x167f,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1734,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dd,
- 0x17e0, 0x17e9,
- 0x180b, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1946, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x1a00, 0x1a1b,
- 0x1a20, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa7, 0x1aa7,
- 0x1ab0, 0x1abd,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b59,
- 0x1b6b, 0x1b73,
- 0x1b80, 0x1bf3,
- 0x1c00, 0x1c37,
- 0x1c40, 0x1c49,
- 0x1c4d, 0x1c7d,
- 0x1c80, 0x1c88,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1cf9,
- 0x1d00, 0x1df9,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x203f, 0x2040,
- 0x2054, 0x2054,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x20d0, 0x20dc,
- 0x20e1, 0x20e1,
- 0x20e5, 0x20f0,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2118, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x2139,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2ce4,
- 0x2ceb, 0x2cf3,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d6f,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2dff,
- 0x3005, 0x3007,
- 0x3021, 0x302f,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x3099, 0x309a,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x31a0, 0x31ba,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xa000, 0xa48c,
- 0xa4d0, 0xa4fd,
- 0xa500, 0xa60c,
- 0xa610, 0xa62b,
- 0xa640, 0xa66f,
- 0xa674, 0xa67d,
- 0xa67f, 0xa6f1,
- 0xa717, 0xa71f,
- 0xa722, 0xa788,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa827,
- 0xa840, 0xa873,
- 0xa880, 0xa8c5,
- 0xa8d0, 0xa8d9,
- 0xa8e0, 0xa8f7,
- 0xa8fb, 0xa8fb,
- 0xa8fd, 0xa8fd,
- 0xa900, 0xa92d,
- 0xa930, 0xa953,
- 0xa960, 0xa97c,
- 0xa980, 0xa9c0,
- 0xa9cf, 0xa9d9,
- 0xa9e0, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa60, 0xaa76,
- 0xaa7a, 0xaac2,
- 0xaadb, 0xaadd,
- 0xaae0, 0xaaef,
- 0xaaf2, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5a,
- 0xab5c, 0xab65,
- 0xab70, 0xabea,
- 0xabec, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfc5d,
- 0xfc64, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdf9,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe2f,
- 0xfe33, 0xfe34,
- 0xfe4d, 0xfe4f,
- 0xfe71, 0xfe71,
- 0xfe73, 0xfe73,
- 0xfe77, 0xfe77,
- 0xfe79, 0xfe79,
- 0xfe7b, 0xfe7b,
- 0xfe7d, 0xfe7d,
- 0xfe7f, 0xfefc,
- 0xff10, 0xff19,
- 0xff21, 0xff3a,
- 0xff3f, 0xff3f,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10140, 0x10174,
- 0x101fd, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102e0,
- 0x10300, 0x1031f,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103cf,
- 0x103d1, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089e,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a3f,
- 0x10a60, 0x10a7c,
- 0x10a80, 0x10a9c,
- 0x10ac0, 0x10ac7,
- 0x10ac9, 0x10ae6,
- 0x10b00, 0x10b35,
- 0x10b40, 0x10b55,
- 0x10b60, 0x10b72,
- 0x10b80, 0x10b91,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x11000, 0x11046,
- 0x11066, 0x1106f,
- 0x1107f, 0x110ba,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x1113f,
- 0x11150, 0x11173,
- 0x11176, 0x11176,
- 0x11180, 0x111c4,
- 0x111ca, 0x111cc,
- 0x111d0, 0x111da,
- 0x111dc, 0x111dc,
- 0x11200, 0x11211,
- 0x11213, 0x11237,
- 0x1123e, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a8,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x1144a,
- 0x11450, 0x11459,
- 0x11480, 0x114c5,
- 0x114c7, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115c0,
- 0x115d8, 0x115dd,
- 0x11600, 0x11640,
- 0x11644, 0x11644,
- 0x11650, 0x11659,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x11739,
- 0x118a0, 0x118e9,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a3e,
- 0x11a47, 0x11a47,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a99,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c40,
- 0x11c50, 0x11c59,
- 0x11c72, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af4,
- 0x16b00, 0x16b36,
- 0x16b40, 0x16b43,
- 0x16b50, 0x16b59,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9d, 0x1bc9e,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d242, 0x1d244,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1da00, 0x1da36,
- 0x1da3b, 0x1da6c,
- 0x1da75, 0x1da75,
- 0x1da84, 0x1da84,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8d0, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
- 0xe0100, 0xe01ef,
-}; /* CR_XID_Continue */
-
-/* 'Default_Ignorable_Code_Point': Derived Property */
-static const OnigCodePoint CR_Default_Ignorable_Code_Point[] = {
- 17,
- 0x00ad, 0x00ad,
- 0x034f, 0x034f,
- 0x061c, 0x061c,
- 0x115f, 0x1160,
- 0x17b4, 0x17b5,
- 0x180b, 0x180e,
- 0x200b, 0x200f,
- 0x202a, 0x202e,
- 0x2060, 0x206f,
- 0x3164, 0x3164,
- 0xfe00, 0xfe0f,
- 0xfeff, 0xfeff,
- 0xffa0, 0xffa0,
- 0xfff0, 0xfff8,
- 0x1bca0, 0x1bca3,
- 0x1d173, 0x1d17a,
- 0xe0000, 0xe0fff,
-}; /* CR_Default_Ignorable_Code_Point */
-
-/* 'Grapheme_Extend': Derived Property */
-static const OnigCodePoint CR_Grapheme_Extend[] = {
- 319,
- 0x0300, 0x036f,
- 0x0483, 0x0489,
- 0x0591, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x0610, 0x061a,
- 0x064b, 0x065f,
- 0x0670, 0x0670,
- 0x06d6, 0x06dc,
- 0x06df, 0x06e4,
- 0x06e7, 0x06e8,
- 0x06ea, 0x06ed,
- 0x0711, 0x0711,
- 0x0730, 0x074a,
- 0x07a6, 0x07b0,
- 0x07eb, 0x07f3,
- 0x0816, 0x0819,
- 0x081b, 0x0823,
- 0x0825, 0x0827,
- 0x0829, 0x082d,
- 0x0859, 0x085b,
- 0x08d4, 0x08e1,
- 0x08e3, 0x0902,
- 0x093a, 0x093a,
- 0x093c, 0x093c,
- 0x0941, 0x0948,
- 0x094d, 0x094d,
- 0x0951, 0x0957,
- 0x0962, 0x0963,
- 0x0981, 0x0981,
- 0x09bc, 0x09bc,
- 0x09be, 0x09be,
- 0x09c1, 0x09c4,
- 0x09cd, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09e2, 0x09e3,
- 0x0a01, 0x0a02,
- 0x0a3c, 0x0a3c,
- 0x0a41, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a70, 0x0a71,
- 0x0a75, 0x0a75,
- 0x0a81, 0x0a82,
- 0x0abc, 0x0abc,
- 0x0ac1, 0x0ac5,
- 0x0ac7, 0x0ac8,
- 0x0acd, 0x0acd,
- 0x0ae2, 0x0ae3,
- 0x0afa, 0x0aff,
- 0x0b01, 0x0b01,
- 0x0b3c, 0x0b3c,
- 0x0b3e, 0x0b3f,
- 0x0b41, 0x0b44,
- 0x0b4d, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b62, 0x0b63,
- 0x0b82, 0x0b82,
- 0x0bbe, 0x0bbe,
- 0x0bc0, 0x0bc0,
- 0x0bcd, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0c00, 0x0c00,
- 0x0c3e, 0x0c40,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c62, 0x0c63,
- 0x0c81, 0x0c81,
- 0x0cbc, 0x0cbc,
- 0x0cbf, 0x0cbf,
- 0x0cc2, 0x0cc2,
- 0x0cc6, 0x0cc6,
- 0x0ccc, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0ce2, 0x0ce3,
- 0x0d00, 0x0d01,
- 0x0d3b, 0x0d3c,
- 0x0d3e, 0x0d3e,
- 0x0d41, 0x0d44,
- 0x0d4d, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d62, 0x0d63,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dcf,
- 0x0dd2, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0ddf, 0x0ddf,
- 0x0e31, 0x0e31,
- 0x0e34, 0x0e3a,
- 0x0e47, 0x0e4e,
- 0x0eb1, 0x0eb1,
- 0x0eb4, 0x0eb9,
- 0x0ebb, 0x0ebc,
- 0x0ec8, 0x0ecd,
- 0x0f18, 0x0f19,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f71, 0x0f7e,
- 0x0f80, 0x0f84,
- 0x0f86, 0x0f87,
- 0x0f8d, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x102d, 0x1030,
- 0x1032, 0x1037,
- 0x1039, 0x103a,
- 0x103d, 0x103e,
- 0x1058, 0x1059,
- 0x105e, 0x1060,
- 0x1071, 0x1074,
- 0x1082, 0x1082,
- 0x1085, 0x1086,
- 0x108d, 0x108d,
- 0x109d, 0x109d,
- 0x135d, 0x135f,
- 0x1712, 0x1714,
- 0x1732, 0x1734,
- 0x1752, 0x1753,
- 0x1772, 0x1773,
- 0x17b4, 0x17b5,
- 0x17b7, 0x17bd,
- 0x17c6, 0x17c6,
- 0x17c9, 0x17d3,
- 0x17dd, 0x17dd,
- 0x180b, 0x180d,
- 0x1885, 0x1886,
- 0x18a9, 0x18a9,
- 0x1920, 0x1922,
- 0x1927, 0x1928,
- 0x1932, 0x1932,
- 0x1939, 0x193b,
- 0x1a17, 0x1a18,
- 0x1a1b, 0x1a1b,
- 0x1a56, 0x1a56,
- 0x1a58, 0x1a5e,
- 0x1a60, 0x1a60,
- 0x1a62, 0x1a62,
- 0x1a65, 0x1a6c,
- 0x1a73, 0x1a7c,
- 0x1a7f, 0x1a7f,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b03,
- 0x1b34, 0x1b34,
- 0x1b36, 0x1b3a,
- 0x1b3c, 0x1b3c,
- 0x1b42, 0x1b42,
- 0x1b6b, 0x1b73,
- 0x1b80, 0x1b81,
- 0x1ba2, 0x1ba5,
- 0x1ba8, 0x1ba9,
- 0x1bab, 0x1bad,
- 0x1be6, 0x1be6,
- 0x1be8, 0x1be9,
- 0x1bed, 0x1bed,
- 0x1bef, 0x1bf1,
- 0x1c2c, 0x1c33,
- 0x1c36, 0x1c37,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1ce0,
- 0x1ce2, 0x1ce8,
- 0x1ced, 0x1ced,
- 0x1cf4, 0x1cf4,
- 0x1cf8, 0x1cf9,
- 0x1dc0, 0x1df9,
- 0x1dfb, 0x1dff,
- 0x200c, 0x200c,
- 0x20d0, 0x20f0,
- 0x2cef, 0x2cf1,
- 0x2d7f, 0x2d7f,
- 0x2de0, 0x2dff,
- 0x302a, 0x302f,
- 0x3099, 0x309a,
- 0xa66f, 0xa672,
- 0xa674, 0xa67d,
- 0xa69e, 0xa69f,
- 0xa6f0, 0xa6f1,
- 0xa802, 0xa802,
- 0xa806, 0xa806,
- 0xa80b, 0xa80b,
- 0xa825, 0xa826,
- 0xa8c4, 0xa8c5,
- 0xa8e0, 0xa8f1,
- 0xa926, 0xa92d,
- 0xa947, 0xa951,
- 0xa980, 0xa982,
- 0xa9b3, 0xa9b3,
- 0xa9b6, 0xa9b9,
- 0xa9bc, 0xa9bc,
- 0xa9e5, 0xa9e5,
- 0xaa29, 0xaa2e,
- 0xaa31, 0xaa32,
- 0xaa35, 0xaa36,
- 0xaa43, 0xaa43,
- 0xaa4c, 0xaa4c,
- 0xaa7c, 0xaa7c,
- 0xaab0, 0xaab0,
- 0xaab2, 0xaab4,
- 0xaab7, 0xaab8,
- 0xaabe, 0xaabf,
- 0xaac1, 0xaac1,
- 0xaaec, 0xaaed,
- 0xaaf6, 0xaaf6,
- 0xabe5, 0xabe5,
- 0xabe8, 0xabe8,
- 0xabed, 0xabed,
- 0xfb1e, 0xfb1e,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe2f,
- 0xff9e, 0xff9f,
- 0x101fd, 0x101fd,
- 0x102e0, 0x102e0,
- 0x10376, 0x1037a,
- 0x10a01, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a0f,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a3f,
- 0x10ae5, 0x10ae6,
- 0x11001, 0x11001,
- 0x11038, 0x11046,
- 0x1107f, 0x11081,
- 0x110b3, 0x110b6,
- 0x110b9, 0x110ba,
- 0x11100, 0x11102,
- 0x11127, 0x1112b,
- 0x1112d, 0x11134,
- 0x11173, 0x11173,
- 0x11180, 0x11181,
- 0x111b6, 0x111be,
- 0x111ca, 0x111cc,
- 0x1122f, 0x11231,
- 0x11234, 0x11234,
- 0x11236, 0x11237,
- 0x1123e, 0x1123e,
- 0x112df, 0x112df,
- 0x112e3, 0x112ea,
- 0x11300, 0x11301,
- 0x1133c, 0x1133c,
- 0x1133e, 0x1133e,
- 0x11340, 0x11340,
- 0x11357, 0x11357,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11438, 0x1143f,
- 0x11442, 0x11444,
- 0x11446, 0x11446,
- 0x114b0, 0x114b0,
- 0x114b3, 0x114b8,
- 0x114ba, 0x114ba,
- 0x114bd, 0x114bd,
- 0x114bf, 0x114c0,
- 0x114c2, 0x114c3,
- 0x115af, 0x115af,
- 0x115b2, 0x115b5,
- 0x115bc, 0x115bd,
- 0x115bf, 0x115c0,
- 0x115dc, 0x115dd,
- 0x11633, 0x1163a,
- 0x1163d, 0x1163d,
- 0x1163f, 0x11640,
- 0x116ab, 0x116ab,
- 0x116ad, 0x116ad,
- 0x116b0, 0x116b5,
- 0x116b7, 0x116b7,
- 0x1171d, 0x1171f,
- 0x11722, 0x11725,
- 0x11727, 0x1172b,
- 0x11a01, 0x11a06,
- 0x11a09, 0x11a0a,
- 0x11a33, 0x11a38,
- 0x11a3b, 0x11a3e,
- 0x11a47, 0x11a47,
- 0x11a51, 0x11a56,
- 0x11a59, 0x11a5b,
- 0x11a8a, 0x11a96,
- 0x11a98, 0x11a99,
- 0x11c30, 0x11c36,
- 0x11c38, 0x11c3d,
- 0x11c3f, 0x11c3f,
- 0x11c92, 0x11ca7,
- 0x11caa, 0x11cb0,
- 0x11cb2, 0x11cb3,
- 0x11cb5, 0x11cb6,
- 0x11d31, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d45,
- 0x11d47, 0x11d47,
- 0x16af0, 0x16af4,
- 0x16b30, 0x16b36,
- 0x16f8f, 0x16f92,
- 0x1bc9d, 0x1bc9e,
- 0x1d165, 0x1d165,
- 0x1d167, 0x1d169,
- 0x1d16e, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d242, 0x1d244,
- 0x1da00, 0x1da36,
- 0x1da3b, 0x1da6c,
- 0x1da75, 0x1da75,
- 0x1da84, 0x1da84,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e8d0, 0x1e8d6,
- 0x1e944, 0x1e94a,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
-}; /* CR_Grapheme_Extend */
-
-/* 'Grapheme_Base': Derived Property */
-static const OnigCodePoint CR_Grapheme_Base[] = {
- 791,
- 0x0020, 0x007e,
- 0x00a0, 0x00ac,
- 0x00ae, 0x02ff,
- 0x0370, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x0482,
- 0x048a, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x05be, 0x05be,
- 0x05c0, 0x05c0,
- 0x05c3, 0x05c3,
- 0x05c6, 0x05c6,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0606, 0x060f,
- 0x061b, 0x061b,
- 0x061e, 0x064a,
- 0x0660, 0x066f,
- 0x0671, 0x06d5,
- 0x06de, 0x06de,
- 0x06e5, 0x06e6,
- 0x06e9, 0x06e9,
- 0x06ee, 0x070d,
- 0x0710, 0x0710,
- 0x0712, 0x072f,
- 0x074d, 0x07a5,
- 0x07b1, 0x07b1,
- 0x07c0, 0x07ea,
- 0x07f4, 0x07fa,
- 0x0800, 0x0815,
- 0x081a, 0x081a,
- 0x0824, 0x0824,
- 0x0828, 0x0828,
- 0x0830, 0x083e,
- 0x0840, 0x0858,
- 0x085e, 0x085e,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x0903, 0x0939,
- 0x093b, 0x093b,
- 0x093d, 0x0940,
- 0x0949, 0x094c,
- 0x094e, 0x0950,
- 0x0958, 0x0961,
- 0x0964, 0x0980,
- 0x0982, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bd, 0x09bd,
- 0x09bf, 0x09c0,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cc,
- 0x09ce, 0x09ce,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e1,
- 0x09e6, 0x09fd,
- 0x0a03, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3e, 0x0a40,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a6f,
- 0x0a72, 0x0a74,
- 0x0a83, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abd, 0x0ac0,
- 0x0ac9, 0x0ac9,
- 0x0acb, 0x0acc,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae1,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0af9,
- 0x0b02, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3d, 0x0b3d,
- 0x0b40, 0x0b40,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4c,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b77,
- 0x0b83, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbf, 0x0bbf,
- 0x0bc1, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcc,
- 0x0bd0, 0x0bd0,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c3d,
- 0x0c41, 0x0c44,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c80,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbd, 0x0cbe,
- 0x0cc0, 0x0cc1,
- 0x0cc3, 0x0cc4,
- 0x0cc7, 0x0cc8,
- 0x0cca, 0x0ccb,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d3d,
- 0x0d3f, 0x0d40,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4c,
- 0x0d4e, 0x0d4f,
- 0x0d54, 0x0d56,
- 0x0d58, 0x0d61,
- 0x0d66, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dd0, 0x0dd1,
- 0x0dd8, 0x0dde,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e30,
- 0x0e32, 0x0e33,
- 0x0e3f, 0x0e46,
- 0x0e4f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb0,
- 0x0eb2, 0x0eb3,
- 0x0ebd, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f17,
- 0x0f1a, 0x0f34,
- 0x0f36, 0x0f36,
- 0x0f38, 0x0f38,
- 0x0f3a, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f7f, 0x0f7f,
- 0x0f85, 0x0f85,
- 0x0f88, 0x0f8c,
- 0x0fbe, 0x0fc5,
- 0x0fc7, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x102c,
- 0x1031, 0x1031,
- 0x1038, 0x1038,
- 0x103b, 0x103c,
- 0x103f, 0x1057,
- 0x105a, 0x105d,
- 0x1061, 0x1070,
- 0x1075, 0x1081,
- 0x1083, 0x1084,
- 0x1087, 0x108c,
- 0x108e, 0x109c,
- 0x109e, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x1360, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1711,
- 0x1720, 0x1731,
- 0x1735, 0x1736,
- 0x1740, 0x1751,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1780, 0x17b3,
- 0x17b6, 0x17b6,
- 0x17be, 0x17c5,
- 0x17c7, 0x17c8,
- 0x17d4, 0x17dc,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180a,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x1884,
- 0x1887, 0x18a8,
- 0x18aa, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1923, 0x1926,
- 0x1929, 0x192b,
- 0x1930, 0x1931,
- 0x1933, 0x1938,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a16,
- 0x1a19, 0x1a1a,
- 0x1a1e, 0x1a55,
- 0x1a57, 0x1a57,
- 0x1a61, 0x1a61,
- 0x1a63, 0x1a64,
- 0x1a6d, 0x1a72,
- 0x1a80, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1b04, 0x1b33,
- 0x1b35, 0x1b35,
- 0x1b3b, 0x1b3b,
- 0x1b3d, 0x1b41,
- 0x1b43, 0x1b4b,
- 0x1b50, 0x1b6a,
- 0x1b74, 0x1b7c,
- 0x1b82, 0x1ba1,
- 0x1ba6, 0x1ba7,
- 0x1baa, 0x1baa,
- 0x1bae, 0x1be5,
- 0x1be7, 0x1be7,
- 0x1bea, 0x1bec,
- 0x1bee, 0x1bee,
- 0x1bf2, 0x1bf3,
- 0x1bfc, 0x1c2b,
- 0x1c34, 0x1c35,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c88,
- 0x1cc0, 0x1cc7,
- 0x1cd3, 0x1cd3,
- 0x1ce1, 0x1ce1,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf3,
- 0x1cf5, 0x1cf7,
- 0x1d00, 0x1dbf,
- 0x1e00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x200a,
- 0x2010, 0x2027,
- 0x202f, 0x205f,
- 0x2070, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20bf,
- 0x2100, 0x218b,
- 0x2190, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cee,
- 0x2cf2, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2e00, 0x2e49,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x3029,
- 0x3030, 0x303f,
- 0x3041, 0x3096,
- 0x309b, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fea,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa66e,
- 0xa673, 0xa673,
- 0xa67e, 0xa69d,
- 0xa6a0, 0xa6ef,
- 0xa6f2, 0xa6f7,
- 0xa700, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa801,
- 0xa803, 0xa805,
- 0xa807, 0xa80a,
- 0xa80c, 0xa824,
- 0xa827, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c3,
- 0xa8ce, 0xa8d9,
- 0xa8f2, 0xa8fd,
- 0xa900, 0xa925,
- 0xa92e, 0xa946,
- 0xa952, 0xa953,
- 0xa95f, 0xa97c,
- 0xa983, 0xa9b2,
- 0xa9b4, 0xa9b5,
- 0xa9ba, 0xa9bb,
- 0xa9bd, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9e4,
- 0xa9e6, 0xa9fe,
- 0xaa00, 0xaa28,
- 0xaa2f, 0xaa30,
- 0xaa33, 0xaa34,
- 0xaa40, 0xaa42,
- 0xaa44, 0xaa4b,
- 0xaa4d, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa7b,
- 0xaa7d, 0xaaaf,
- 0xaab1, 0xaab1,
- 0xaab5, 0xaab6,
- 0xaab9, 0xaabd,
- 0xaac0, 0xaac0,
- 0xaac2, 0xaac2,
- 0xaadb, 0xaaeb,
- 0xaaee, 0xaaf5,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab65,
- 0xab70, 0xabe4,
- 0xabe6, 0xabe7,
- 0xabe9, 0xabec,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb1d,
- 0xfb1f, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe10, 0xfe19,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff01, 0xff9d,
- 0xffa0, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfffc, 0xfffd,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fc,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e1, 0x102fb,
- 0x10300, 0x10323,
- 0x1032d, 0x1034a,
- 0x10350, 0x10375,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x10a00,
- 0x10a10, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a40, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae4,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11000, 0x11000,
- 0x11002, 0x11037,
- 0x11047, 0x1104d,
- 0x11052, 0x1106f,
- 0x11082, 0x110b2,
- 0x110b7, 0x110b8,
- 0x110bb, 0x110bc,
- 0x110be, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11103, 0x11126,
- 0x1112c, 0x1112c,
- 0x11136, 0x11143,
- 0x11150, 0x11172,
- 0x11174, 0x11176,
- 0x11182, 0x111b5,
- 0x111bf, 0x111c9,
- 0x111cd, 0x111cd,
- 0x111d0, 0x111df,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1122e,
- 0x11232, 0x11233,
- 0x11235, 0x11235,
- 0x11238, 0x1123d,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
- 0x112b0, 0x112de,
- 0x112e0, 0x112e2,
- 0x112f0, 0x112f9,
- 0x11302, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133d, 0x1133d,
- 0x1133f, 0x1133f,
- 0x11341, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x1135d, 0x11363,
- 0x11400, 0x11437,
- 0x11440, 0x11441,
- 0x11445, 0x11445,
- 0x11447, 0x11459,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x11480, 0x114af,
- 0x114b1, 0x114b2,
- 0x114b9, 0x114b9,
- 0x114bb, 0x114bc,
- 0x114be, 0x114be,
- 0x114c1, 0x114c1,
- 0x114c4, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115ae,
- 0x115b0, 0x115b1,
- 0x115b8, 0x115bb,
- 0x115be, 0x115be,
- 0x115c1, 0x115db,
- 0x11600, 0x11632,
- 0x1163b, 0x1163c,
- 0x1163e, 0x1163e,
- 0x11641, 0x11644,
- 0x11650, 0x11659,
- 0x11660, 0x1166c,
- 0x11680, 0x116aa,
- 0x116ac, 0x116ac,
- 0x116ae, 0x116af,
- 0x116b6, 0x116b6,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x11720, 0x11721,
- 0x11726, 0x11726,
- 0x11730, 0x1173f,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a00,
- 0x11a07, 0x11a08,
- 0x11a0b, 0x11a32,
- 0x11a39, 0x11a3a,
- 0x11a3f, 0x11a46,
- 0x11a50, 0x11a50,
- 0x11a57, 0x11a58,
- 0x11a5c, 0x11a83,
- 0x11a86, 0x11a89,
- 0x11a97, 0x11a97,
- 0x11a9a, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c2f,
- 0x11c3e, 0x11c3e,
- 0x11c40, 0x11c45,
- 0x11c50, 0x11c6c,
- 0x11c70, 0x11c8f,
- 0x11ca9, 0x11ca9,
- 0x11cb1, 0x11cb1,
- 0x11cb4, 0x11cb4,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d30,
- 0x11d46, 0x11d46,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af5, 0x16af5,
- 0x16b00, 0x16b2f,
- 0x16b37, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f93, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bc9c,
- 0x1bc9f, 0x1bc9f,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d164,
- 0x1d166, 0x1d166,
- 0x1d16a, 0x1d16d,
- 0x1d183, 0x1d184,
- 0x1d18c, 0x1d1a9,
- 0x1d1ae, 0x1d1e8,
- 0x1d200, 0x1d241,
- 0x1d245, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d9ff,
- 0x1da37, 0x1da3a,
- 0x1da6d, 0x1da74,
- 0x1da76, 0x1da83,
- 0x1da85, 0x1da8b,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8cf,
- 0x1e900, 0x1e943,
- 0x1e950, 0x1e959,
- 0x1e95e, 0x1e95f,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_Grapheme_Base */
-
-/* 'Grapheme_Link': Derived Property */
-static const OnigCodePoint CR_Grapheme_Link[] = {
- 48,
- 0x094d, 0x094d,
- 0x09cd, 0x09cd,
- 0x0a4d, 0x0a4d,
- 0x0acd, 0x0acd,
- 0x0b4d, 0x0b4d,
- 0x0bcd, 0x0bcd,
- 0x0c4d, 0x0c4d,
- 0x0ccd, 0x0ccd,
- 0x0d3b, 0x0d3c,
- 0x0d4d, 0x0d4d,
- 0x0dca, 0x0dca,
- 0x0e3a, 0x0e3a,
- 0x0f84, 0x0f84,
- 0x1039, 0x103a,
- 0x1714, 0x1714,
- 0x1734, 0x1734,
- 0x17d2, 0x17d2,
- 0x1a60, 0x1a60,
- 0x1b44, 0x1b44,
- 0x1baa, 0x1bab,
- 0x1bf2, 0x1bf3,
- 0x2d7f, 0x2d7f,
- 0xa806, 0xa806,
- 0xa8c4, 0xa8c4,
- 0xa953, 0xa953,
- 0xa9c0, 0xa9c0,
- 0xaaf6, 0xaaf6,
- 0xabed, 0xabed,
- 0x10a3f, 0x10a3f,
- 0x11046, 0x11046,
- 0x1107f, 0x1107f,
- 0x110b9, 0x110b9,
- 0x11133, 0x11134,
- 0x111c0, 0x111c0,
- 0x11235, 0x11235,
- 0x112ea, 0x112ea,
- 0x1134d, 0x1134d,
- 0x11442, 0x11442,
- 0x114c2, 0x114c2,
- 0x115bf, 0x115bf,
- 0x1163f, 0x1163f,
- 0x116b6, 0x116b6,
- 0x1172b, 0x1172b,
- 0x11a34, 0x11a34,
- 0x11a47, 0x11a47,
- 0x11a99, 0x11a99,
- 0x11c3f, 0x11c3f,
- 0x11d44, 0x11d45,
-}; /* CR_Grapheme_Link */
-
-/* 'Common': Script */
-static const OnigCodePoint CR_Common[] = {
- 164,
- 0x0000, 0x0040,
- 0x005b, 0x0060,
- 0x007b, 0x00a9,
- 0x00ab, 0x00b9,
- 0x00bb, 0x00bf,
- 0x00d7, 0x00d7,
- 0x00f7, 0x00f7,
- 0x02b9, 0x02df,
- 0x02e5, 0x02e9,
- 0x02ec, 0x02ff,
- 0x0374, 0x0374,
- 0x037e, 0x037e,
- 0x0385, 0x0385,
- 0x0387, 0x0387,
- 0x0589, 0x0589,
- 0x0605, 0x0605,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0640, 0x0640,
- 0x06dd, 0x06dd,
- 0x08e2, 0x08e2,
- 0x0964, 0x0965,
- 0x0e3f, 0x0e3f,
- 0x0fd5, 0x0fd8,
- 0x10fb, 0x10fb,
- 0x16eb, 0x16ed,
- 0x1735, 0x1736,
- 0x1802, 0x1803,
- 0x1805, 0x1805,
- 0x1cd3, 0x1cd3,
- 0x1ce1, 0x1ce1,
- 0x1ce9, 0x1cec,
- 0x1cee, 0x1cf3,
- 0x1cf5, 0x1cf7,
- 0x2000, 0x200b,
- 0x200e, 0x2064,
- 0x2066, 0x2070,
- 0x2074, 0x207e,
- 0x2080, 0x208e,
- 0x20a0, 0x20bf,
- 0x2100, 0x2125,
- 0x2127, 0x2129,
- 0x212c, 0x2131,
- 0x2133, 0x214d,
- 0x214f, 0x215f,
- 0x2189, 0x218b,
- 0x2190, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x27ff,
- 0x2900, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2e00, 0x2e49,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x3004,
- 0x3006, 0x3006,
- 0x3008, 0x3020,
- 0x3030, 0x3037,
- 0x303c, 0x303f,
- 0x309b, 0x309c,
- 0x30a0, 0x30a0,
- 0x30fb, 0x30fc,
- 0x3190, 0x319f,
- 0x31c0, 0x31e3,
- 0x3220, 0x325f,
- 0x327f, 0x32cf,
- 0x3358, 0x33ff,
- 0x4dc0, 0x4dff,
- 0xa700, 0xa721,
- 0xa788, 0xa78a,
- 0xa830, 0xa839,
- 0xa92e, 0xa92e,
- 0xa9cf, 0xa9cf,
- 0xab5b, 0xab5b,
- 0xfd3e, 0xfd3f,
- 0xfe10, 0xfe19,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfeff, 0xfeff,
- 0xff01, 0xff20,
- 0xff3b, 0xff40,
- 0xff5b, 0xff65,
- 0xff70, 0xff70,
- 0xff9e, 0xff9f,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xfffd,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1013f,
- 0x10190, 0x1019b,
- 0x101d0, 0x101fc,
- 0x102e1, 0x102fb,
- 0x1bca0, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d166,
- 0x1d16a, 0x1d17a,
- 0x1d183, 0x1d184,
- 0x1d18c, 0x1d1a9,
- 0x1d1ae, 0x1d1e8,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f1ff,
- 0x1f201, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
-}; /* CR_Common */
-
-/* 'Latin': Script */
-static const OnigCodePoint CR_Latin[] = {
- 31,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x02b8,
- 0x02e0, 0x02e4,
- 0x1d00, 0x1d25,
- 0x1d2c, 0x1d5c,
- 0x1d62, 0x1d65,
- 0x1d6b, 0x1d77,
- 0x1d79, 0x1dbe,
- 0x1e00, 0x1eff,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x212a, 0x212b,
- 0x2132, 0x2132,
- 0x214e, 0x214e,
- 0x2160, 0x2188,
- 0x2c60, 0x2c7f,
- 0xa722, 0xa787,
- 0xa78b, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa7ff,
- 0xab30, 0xab5a,
- 0xab5c, 0xab64,
- 0xfb00, 0xfb06,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
-}; /* CR_Latin */
-
-/* 'Greek': Script */
-static const OnigCodePoint CR_Greek[] = {
- 36,
- 0x0370, 0x0373,
- 0x0375, 0x0377,
- 0x037a, 0x037d,
- 0x037f, 0x037f,
- 0x0384, 0x0384,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03e1,
- 0x03f0, 0x03ff,
- 0x1d26, 0x1d2a,
- 0x1d5d, 0x1d61,
- 0x1d66, 0x1d6a,
- 0x1dbf, 0x1dbf,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2126, 0x2126,
- 0xab65, 0xab65,
- 0x10140, 0x1018e,
- 0x101a0, 0x101a0,
- 0x1d200, 0x1d245,
-}; /* CR_Greek */
-
-/* 'Cyrillic': Script */
-static const OnigCodePoint CR_Cyrillic[] = {
- 8,
- 0x0400, 0x0484,
- 0x0487, 0x052f,
- 0x1c80, 0x1c88,
- 0x1d2b, 0x1d2b,
- 0x1d78, 0x1d78,
- 0x2de0, 0x2dff,
- 0xa640, 0xa69f,
- 0xfe2e, 0xfe2f,
-}; /* CR_Cyrillic */
-
-/* 'Armenian': Script */
-static const OnigCodePoint CR_Armenian[] = {
- 6,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x058a, 0x058a,
- 0x058d, 0x058f,
- 0xfb13, 0xfb17,
-}; /* CR_Armenian */
-
-/* 'Hebrew': Script */
-static const OnigCodePoint CR_Hebrew[] = {
- 9,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfb4f,
-}; /* CR_Hebrew */
-
-/* 'Arabic': Script */
-static const OnigCodePoint CR_Arabic[] = {
- 57,
- 0x0600, 0x0604,
- 0x0606, 0x060b,
- 0x060d, 0x061a,
- 0x061c, 0x061c,
- 0x061e, 0x061e,
- 0x0620, 0x063f,
- 0x0641, 0x064a,
- 0x0656, 0x066f,
- 0x0671, 0x06dc,
- 0x06de, 0x06ff,
- 0x0750, 0x077f,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x08e1,
- 0x08e3, 0x08ff,
- 0xfb50, 0xfbc1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0x10e60, 0x10e7e,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
-}; /* CR_Arabic */
-
-/* 'Syriac': Script */
-static const OnigCodePoint CR_Syriac[] = {
- 4,
- 0x0700, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x074f,
- 0x0860, 0x086a,
-}; /* CR_Syriac */
-
-/* 'Thaana': Script */
-static const OnigCodePoint CR_Thaana[] = {
- 1,
- 0x0780, 0x07b1,
-}; /* CR_Thaana */
-
-/* 'Devanagari': Script */
-static const OnigCodePoint CR_Devanagari[] = {
- 4,
- 0x0900, 0x0950,
- 0x0953, 0x0963,
- 0x0966, 0x097f,
- 0xa8e0, 0xa8fd,
-}; /* CR_Devanagari */
-
-/* 'Bengali': Script */
-static const OnigCodePoint CR_Bengali[] = {
- 14,
- 0x0980, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fd,
-}; /* CR_Bengali */
-
-/* 'Gurmukhi': Script */
-static const OnigCodePoint CR_Gurmukhi[] = {
- 16,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
-}; /* CR_Gurmukhi */
-
-/* 'Gujarati': Script */
-static const OnigCodePoint CR_Gujarati[] = {
- 14,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0aff,
-}; /* CR_Gujarati */
-
-/* 'Oriya': Script */
-static const OnigCodePoint CR_Oriya[] = {
- 14,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
-}; /* CR_Oriya */
-
-/* 'Tamil': Script */
-static const OnigCodePoint CR_Tamil[] = {
- 16,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
-}; /* CR_Tamil */
-
-/* 'Telugu': Script */
-static const OnigCodePoint CR_Telugu[] = {
- 13,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
-}; /* CR_Telugu */
-
-/* 'Kannada': Script */
-static const OnigCodePoint CR_Kannada[] = {
- 14,
- 0x0c80, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
-}; /* CR_Kannada */
-
-/* 'Malayalam': Script */
-static const OnigCodePoint CR_Malayalam[] = {
- 8,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4f,
- 0x0d54, 0x0d63,
- 0x0d66, 0x0d7f,
-}; /* CR_Malayalam */
-
-/* 'Sinhala': Script */
-static const OnigCodePoint CR_Sinhala[] = {
- 13,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x111e1, 0x111f4,
-}; /* CR_Sinhala */
-
-/* 'Thai': Script */
-static const OnigCodePoint CR_Thai[] = {
- 2,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e5b,
-}; /* CR_Thai */
-
-/* 'Lao': Script */
-static const OnigCodePoint CR_Lao[] = {
- 18,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
-}; /* CR_Lao */
-
-/* 'Tibetan': Script */
-static const OnigCodePoint CR_Tibetan[] = {
- 7,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fd4,
- 0x0fd9, 0x0fda,
-}; /* CR_Tibetan */
-
-/* 'Myanmar': Script */
-static const OnigCodePoint CR_Myanmar[] = {
- 3,
- 0x1000, 0x109f,
- 0xa9e0, 0xa9fe,
- 0xaa60, 0xaa7f,
-}; /* CR_Myanmar */
-
-/* 'Georgian': Script */
-static const OnigCodePoint CR_Georgian[] = {
- 8,
- 0x10a0, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x10fa,
- 0x10fc, 0x10ff,
- 0x2d00, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
-}; /* CR_Georgian */
-
-/* 'Hangul': Script */
-static const OnigCodePoint CR_Hangul[] = {
- 14,
- 0x1100, 0x11ff,
- 0x302e, 0x302f,
- 0x3131, 0x318e,
- 0x3200, 0x321e,
- 0x3260, 0x327e,
- 0xa960, 0xa97c,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xffa0, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
-}; /* CR_Hangul */
-
-/* 'Ethiopic': Script */
-static const OnigCodePoint CR_Ethiopic[] = {
- 32,
- 0x1200, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
-}; /* CR_Ethiopic */
-
-/* 'Cherokee': Script */
-static const OnigCodePoint CR_Cherokee[] = {
- 3,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0xab70, 0xabbf,
-}; /* CR_Cherokee */
-
-/* 'Canadian_Aboriginal': Script */
-static const OnigCodePoint CR_Canadian_Aboriginal[] = {
- 2,
- 0x1400, 0x167f,
- 0x18b0, 0x18f5,
-}; /* CR_Canadian_Aboriginal */
-
-/* 'Ogham': Script */
-static const OnigCodePoint CR_Ogham[] = {
- 1,
- 0x1680, 0x169c,
-}; /* CR_Ogham */
-
-/* 'Runic': Script */
-static const OnigCodePoint CR_Runic[] = {
- 2,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f8,
-}; /* CR_Runic */
-
-/* 'Khmer': Script */
-static const OnigCodePoint CR_Khmer[] = {
- 4,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x19e0, 0x19ff,
-}; /* CR_Khmer */
-
-/* 'Mongolian': Script */
-static const OnigCodePoint CR_Mongolian[] = {
- 7,
- 0x1800, 0x1801,
- 0x1804, 0x1804,
- 0x1806, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x11660, 0x1166c,
-}; /* CR_Mongolian */
-
-/* 'Hiragana': Script */
-static const OnigCodePoint CR_Hiragana[] = {
- 4,
- 0x3041, 0x3096,
- 0x309d, 0x309f,
- 0x1b001, 0x1b11e,
- 0x1f200, 0x1f200,
-}; /* CR_Hiragana */
-
-/* 'Katakana': Script */
-static const OnigCodePoint CR_Katakana[] = {
- 8,
- 0x30a1, 0x30fa,
- 0x30fd, 0x30ff,
- 0x31f0, 0x31ff,
- 0x32d0, 0x32fe,
- 0x3300, 0x3357,
- 0xff66, 0xff6f,
- 0xff71, 0xff9d,
- 0x1b000, 0x1b000,
-}; /* CR_Katakana */
-
-/* 'Bopomofo': Script */
-static const OnigCodePoint CR_Bopomofo[] = {
- 3,
- 0x02ea, 0x02eb,
- 0x3105, 0x312e,
- 0x31a0, 0x31ba,
-}; /* CR_Bopomofo */
-
-/* 'Han': Script */
-static const OnigCodePoint CR_Han[] = {
- 17,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x3005, 0x3005,
- 0x3007, 0x3007,
- 0x3021, 0x3029,
- 0x3038, 0x303b,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_Han */
-
-/* 'Yi': Script */
-static const OnigCodePoint CR_Yi[] = {
- 2,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
-}; /* CR_Yi */
-
-/* 'Old_Italic': Script */
-static const OnigCodePoint CR_Old_Italic[] = {
- 2,
- 0x10300, 0x10323,
- 0x1032d, 0x1032f,
-}; /* CR_Old_Italic */
-
-/* 'Gothic': Script */
-static const OnigCodePoint CR_Gothic[] = {
- 1,
- 0x10330, 0x1034a,
-}; /* CR_Gothic */
-
-/* 'Deseret': Script */
-static const OnigCodePoint CR_Deseret[] = {
- 1,
- 0x10400, 0x1044f,
-}; /* CR_Deseret */
-
-/* 'Inherited': Script */
-static const OnigCodePoint CR_Inherited[] = {
- 27,
- 0x0300, 0x036f,
- 0x0485, 0x0486,
- 0x064b, 0x0655,
- 0x0670, 0x0670,
- 0x0951, 0x0952,
- 0x1ab0, 0x1abe,
- 0x1cd0, 0x1cd2,
- 0x1cd4, 0x1ce0,
- 0x1ce2, 0x1ce8,
- 0x1ced, 0x1ced,
- 0x1cf4, 0x1cf4,
- 0x1cf8, 0x1cf9,
- 0x1dc0, 0x1df9,
- 0x1dfb, 0x1dff,
- 0x200c, 0x200d,
- 0x20d0, 0x20f0,
- 0x302a, 0x302d,
- 0x3099, 0x309a,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe2d,
- 0x101fd, 0x101fd,
- 0x102e0, 0x102e0,
- 0x1d167, 0x1d169,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0xe0100, 0xe01ef,
-}; /* CR_Inherited */
-
-/* 'Tagalog': Script */
-static const OnigCodePoint CR_Tagalog[] = {
- 2,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
-}; /* CR_Tagalog */
-
-/* 'Hanunoo': Script */
-static const OnigCodePoint CR_Hanunoo[] = {
- 1,
- 0x1720, 0x1734,
-}; /* CR_Hanunoo */
-
-/* 'Buhid': Script */
-static const OnigCodePoint CR_Buhid[] = {
- 1,
- 0x1740, 0x1753,
-}; /* CR_Buhid */
-
-/* 'Tagbanwa': Script */
-static const OnigCodePoint CR_Tagbanwa[] = {
- 3,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
-}; /* CR_Tagbanwa */
-
-/* 'Limbu': Script */
-static const OnigCodePoint CR_Limbu[] = {
- 5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x194f,
-}; /* CR_Limbu */
-
-/* 'Tai_Le': Script */
-static const OnigCodePoint CR_Tai_Le[] = {
- 2,
- 0x1950, 0x196d,
- 0x1970, 0x1974,
-}; /* CR_Tai_Le */
-
-/* 'Linear_B': Script */
-static const OnigCodePoint CR_Linear_B[] = {
- 7,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
-}; /* CR_Linear_B */
-
-/* 'Ugaritic': Script */
-static const OnigCodePoint CR_Ugaritic[] = {
- 2,
- 0x10380, 0x1039d,
- 0x1039f, 0x1039f,
-}; /* CR_Ugaritic */
-
-/* 'Shavian': Script */
-static const OnigCodePoint CR_Shavian[] = {
- 1,
- 0x10450, 0x1047f,
-}; /* CR_Shavian */
-
-/* 'Osmanya': Script */
-static const OnigCodePoint CR_Osmanya[] = {
- 2,
- 0x10480, 0x1049d,
- 0x104a0, 0x104a9,
-}; /* CR_Osmanya */
-
-/* 'Cypriot': Script */
-static const OnigCodePoint CR_Cypriot[] = {
- 6,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
-}; /* CR_Cypriot */
-
-/* 'Braille': Script */
-static const OnigCodePoint CR_Braille[] = {
- 1,
- 0x2800, 0x28ff,
-}; /* CR_Braille */
-
-/* 'Buginese': Script */
-static const OnigCodePoint CR_Buginese[] = {
- 2,
- 0x1a00, 0x1a1b,
- 0x1a1e, 0x1a1f,
-}; /* CR_Buginese */
-
-/* 'Coptic': Script */
-static const OnigCodePoint CR_Coptic[] = {
- 3,
- 0x03e2, 0x03ef,
- 0x2c80, 0x2cf3,
- 0x2cf9, 0x2cff,
-}; /* CR_Coptic */
-
-/* 'New_Tai_Lue': Script */
-static const OnigCodePoint CR_New_Tai_Lue[] = {
- 4,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x19df,
-}; /* CR_New_Tai_Lue */
-
-/* 'Glagolitic': Script */
-static const OnigCodePoint CR_Glagolitic[] = {
- 7,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
-}; /* CR_Glagolitic */
-
-/* 'Tifinagh': Script */
-static const OnigCodePoint CR_Tifinagh[] = {
- 3,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d7f,
-}; /* CR_Tifinagh */
-
-/* 'Syloti_Nagri': Script */
-static const OnigCodePoint CR_Syloti_Nagri[] = {
- 1,
- 0xa800, 0xa82b,
-}; /* CR_Syloti_Nagri */
-
-/* 'Old_Persian': Script */
-static const OnigCodePoint CR_Old_Persian[] = {
- 2,
- 0x103a0, 0x103c3,
- 0x103c8, 0x103d5,
-}; /* CR_Old_Persian */
-
-/* 'Kharoshthi': Script */
-static const OnigCodePoint CR_Kharoshthi[] = {
- 8,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
-}; /* CR_Kharoshthi */
-
-/* 'Balinese': Script */
-static const OnigCodePoint CR_Balinese[] = {
- 2,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
-}; /* CR_Balinese */
-
-/* 'Cuneiform': Script */
-static const OnigCodePoint CR_Cuneiform[] = {
- 4,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
-}; /* CR_Cuneiform */
-
-/* 'Phoenician': Script */
-static const OnigCodePoint CR_Phoenician[] = {
- 2,
- 0x10900, 0x1091b,
- 0x1091f, 0x1091f,
-}; /* CR_Phoenician */
-
-/* 'Phags_Pa': Script */
-static const OnigCodePoint CR_Phags_Pa[] = {
- 1,
- 0xa840, 0xa877,
-}; /* CR_Phags_Pa */
-
-/* 'Nko': Script */
-static const OnigCodePoint CR_Nko[] = {
- 1,
- 0x07c0, 0x07fa,
-}; /* CR_Nko */
-
-/* 'Sundanese': Script */
-static const OnigCodePoint CR_Sundanese[] = {
- 2,
- 0x1b80, 0x1bbf,
- 0x1cc0, 0x1cc7,
-}; /* CR_Sundanese */
-
-/* 'Lepcha': Script */
-static const OnigCodePoint CR_Lepcha[] = {
- 3,
- 0x1c00, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c4f,
-}; /* CR_Lepcha */
-
-/* 'Ol_Chiki': Script */
-static const OnigCodePoint CR_Ol_Chiki[] = {
- 1,
- 0x1c50, 0x1c7f,
-}; /* CR_Ol_Chiki */
-
-/* 'Vai': Script */
-static const OnigCodePoint CR_Vai[] = {
- 1,
- 0xa500, 0xa62b,
-}; /* CR_Vai */
-
-/* 'Saurashtra': Script */
-static const OnigCodePoint CR_Saurashtra[] = {
- 2,
- 0xa880, 0xa8c5,
- 0xa8ce, 0xa8d9,
-}; /* CR_Saurashtra */
-
-/* 'Kayah_Li': Script */
-static const OnigCodePoint CR_Kayah_Li[] = {
- 2,
- 0xa900, 0xa92d,
- 0xa92f, 0xa92f,
-}; /* CR_Kayah_Li */
-
-/* 'Rejang': Script */
-static const OnigCodePoint CR_Rejang[] = {
- 2,
- 0xa930, 0xa953,
- 0xa95f, 0xa95f,
-}; /* CR_Rejang */
-
-/* 'Lycian': Script */
-static const OnigCodePoint CR_Lycian[] = {
- 1,
- 0x10280, 0x1029c,
-}; /* CR_Lycian */
-
-/* 'Carian': Script */
-static const OnigCodePoint CR_Carian[] = {
- 1,
- 0x102a0, 0x102d0,
-}; /* CR_Carian */
-
-/* 'Lydian': Script */
-static const OnigCodePoint CR_Lydian[] = {
- 2,
- 0x10920, 0x10939,
- 0x1093f, 0x1093f,
-}; /* CR_Lydian */
-
-/* 'Cham': Script */
-static const OnigCodePoint CR_Cham[] = {
- 4,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa5f,
-}; /* CR_Cham */
-
-/* 'Tai_Tham': Script */
-static const OnigCodePoint CR_Tai_Tham[] = {
- 5,
- 0x1a20, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
-}; /* CR_Tai_Tham */
-
-/* 'Tai_Viet': Script */
-static const OnigCodePoint CR_Tai_Viet[] = {
- 2,
- 0xaa80, 0xaac2,
- 0xaadb, 0xaadf,
-}; /* CR_Tai_Viet */
-
-/* 'Avestan': Script */
-static const OnigCodePoint CR_Avestan[] = {
- 2,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b3f,
-}; /* CR_Avestan */
-
-/* 'Egyptian_Hieroglyphs': Script */
-static const OnigCodePoint CR_Egyptian_Hieroglyphs[] = {
- 1,
- 0x13000, 0x1342e,
-}; /* CR_Egyptian_Hieroglyphs */
-
-/* 'Samaritan': Script */
-static const OnigCodePoint CR_Samaritan[] = {
- 2,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
-}; /* CR_Samaritan */
-
-/* 'Lisu': Script */
-static const OnigCodePoint CR_Lisu[] = {
- 1,
- 0xa4d0, 0xa4ff,
-}; /* CR_Lisu */
-
-/* 'Bamum': Script */
-static const OnigCodePoint CR_Bamum[] = {
- 2,
- 0xa6a0, 0xa6f7,
- 0x16800, 0x16a38,
-}; /* CR_Bamum */
-
-/* 'Javanese': Script */
-static const OnigCodePoint CR_Javanese[] = {
- 3,
- 0xa980, 0xa9cd,
- 0xa9d0, 0xa9d9,
- 0xa9de, 0xa9df,
-}; /* CR_Javanese */
-
-/* 'Meetei_Mayek': Script */
-static const OnigCodePoint CR_Meetei_Mayek[] = {
- 3,
- 0xaae0, 0xaaf6,
- 0xabc0, 0xabed,
- 0xabf0, 0xabf9,
-}; /* CR_Meetei_Mayek */
-
-/* 'Imperial_Aramaic': Script */
-static const OnigCodePoint CR_Imperial_Aramaic[] = {
- 2,
- 0x10840, 0x10855,
- 0x10857, 0x1085f,
-}; /* CR_Imperial_Aramaic */
-
-/* 'Old_South_Arabian': Script */
-static const OnigCodePoint CR_Old_South_Arabian[] = {
- 1,
- 0x10a60, 0x10a7f,
-}; /* CR_Old_South_Arabian */
-
-/* 'Inscriptional_Parthian': Script */
-static const OnigCodePoint CR_Inscriptional_Parthian[] = {
- 2,
- 0x10b40, 0x10b55,
- 0x10b58, 0x10b5f,
-}; /* CR_Inscriptional_Parthian */
-
-/* 'Inscriptional_Pahlavi': Script */
-static const OnigCodePoint CR_Inscriptional_Pahlavi[] = {
- 2,
- 0x10b60, 0x10b72,
- 0x10b78, 0x10b7f,
-}; /* CR_Inscriptional_Pahlavi */
-
-/* 'Old_Turkic': Script */
-static const OnigCodePoint CR_Old_Turkic[] = {
- 1,
- 0x10c00, 0x10c48,
-}; /* CR_Old_Turkic */
-
-/* 'Kaithi': Script */
-static const OnigCodePoint CR_Kaithi[] = {
- 1,
- 0x11080, 0x110c1,
-}; /* CR_Kaithi */
-
-/* 'Batak': Script */
-static const OnigCodePoint CR_Batak[] = {
- 2,
- 0x1bc0, 0x1bf3,
- 0x1bfc, 0x1bff,
-}; /* CR_Batak */
-
-/* 'Brahmi': Script */
-static const OnigCodePoint CR_Brahmi[] = {
- 3,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x1107f,
-}; /* CR_Brahmi */
-
-/* 'Mandaic': Script */
-static const OnigCodePoint CR_Mandaic[] = {
- 2,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
-}; /* CR_Mandaic */
-
-/* 'Chakma': Script */
-static const OnigCodePoint CR_Chakma[] = {
- 2,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
-}; /* CR_Chakma */
-
-/* 'Meroitic_Cursive': Script */
-static const OnigCodePoint CR_Meroitic_Cursive[] = {
- 3,
- 0x109a0, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x109ff,
-}; /* CR_Meroitic_Cursive */
-
-/* 'Meroitic_Hieroglyphs': Script */
-static const OnigCodePoint CR_Meroitic_Hieroglyphs[] = {
- 1,
- 0x10980, 0x1099f,
-}; /* CR_Meroitic_Hieroglyphs */
-
-/* 'Miao': Script */
-static const OnigCodePoint CR_Miao[] = {
- 3,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
-}; /* CR_Miao */
-
-/* 'Sharada': Script */
-static const OnigCodePoint CR_Sharada[] = {
- 2,
- 0x11180, 0x111cd,
- 0x111d0, 0x111df,
-}; /* CR_Sharada */
-
-/* 'Sora_Sompeng': Script */
-static const OnigCodePoint CR_Sora_Sompeng[] = {
- 2,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
-}; /* CR_Sora_Sompeng */
-
-/* 'Takri': Script */
-static const OnigCodePoint CR_Takri[] = {
- 2,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
-}; /* CR_Takri */
-
-/* 'Caucasian_Albanian': Script */
-static const OnigCodePoint CR_Caucasian_Albanian[] = {
- 2,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
-}; /* CR_Caucasian_Albanian */
-
-/* 'Bassa_Vah': Script */
-static const OnigCodePoint CR_Bassa_Vah[] = {
- 2,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
-}; /* CR_Bassa_Vah */
-
-/* 'Duployan': Script */
-static const OnigCodePoint CR_Duployan[] = {
- 5,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bc9f,
-}; /* CR_Duployan */
-
-/* 'Elbasan': Script */
-static const OnigCodePoint CR_Elbasan[] = {
- 1,
- 0x10500, 0x10527,
-}; /* CR_Elbasan */
-
-/* 'Grantha': Script */
-static const OnigCodePoint CR_Grantha[] = {
- 15,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
-}; /* CR_Grantha */
-
-/* 'Pahawh_Hmong': Script */
-static const OnigCodePoint CR_Pahawh_Hmong[] = {
- 5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
-}; /* CR_Pahawh_Hmong */
-
-/* 'Khojki': Script */
-static const OnigCodePoint CR_Khojki[] = {
- 2,
- 0x11200, 0x11211,
- 0x11213, 0x1123e,
-}; /* CR_Khojki */
-
-/* 'Linear_A': Script */
-static const OnigCodePoint CR_Linear_A[] = {
- 3,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
-}; /* CR_Linear_A */
-
-/* 'Mahajani': Script */
-static const OnigCodePoint CR_Mahajani[] = {
- 1,
- 0x11150, 0x11176,
-}; /* CR_Mahajani */
-
-/* 'Manichaean': Script */
-static const OnigCodePoint CR_Manichaean[] = {
- 2,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
-}; /* CR_Manichaean */
-
-/* 'Mende_Kikakui': Script */
-static const OnigCodePoint CR_Mende_Kikakui[] = {
- 2,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
-}; /* CR_Mende_Kikakui */
-
-/* 'Modi': Script */
-static const OnigCodePoint CR_Modi[] = {
- 2,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
-}; /* CR_Modi */
-
-/* 'Mro': Script */
-static const OnigCodePoint CR_Mro[] = {
- 3,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
-}; /* CR_Mro */
-
-/* 'Old_North_Arabian': Script */
-static const OnigCodePoint CR_Old_North_Arabian[] = {
- 1,
- 0x10a80, 0x10a9f,
-}; /* CR_Old_North_Arabian */
-
-/* 'Nabataean': Script */
-static const OnigCodePoint CR_Nabataean[] = {
- 2,
- 0x10880, 0x1089e,
- 0x108a7, 0x108af,
-}; /* CR_Nabataean */
-
-/* 'Palmyrene': Script */
-static const OnigCodePoint CR_Palmyrene[] = {
- 1,
- 0x10860, 0x1087f,
-}; /* CR_Palmyrene */
-
-/* 'Pau_Cin_Hau': Script */
-static const OnigCodePoint CR_Pau_Cin_Hau[] = {
- 1,
- 0x11ac0, 0x11af8,
-}; /* CR_Pau_Cin_Hau */
-
-/* 'Old_Permic': Script */
-static const OnigCodePoint CR_Old_Permic[] = {
- 1,
- 0x10350, 0x1037a,
-}; /* CR_Old_Permic */
-
-/* 'Psalter_Pahlavi': Script */
-static const OnigCodePoint CR_Psalter_Pahlavi[] = {
- 3,
- 0x10b80, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
-}; /* CR_Psalter_Pahlavi */
-
-/* 'Siddham': Script */
-static const OnigCodePoint CR_Siddham[] = {
- 2,
- 0x11580, 0x115b5,
- 0x115b8, 0x115dd,
-}; /* CR_Siddham */
-
-/* 'Khudawadi': Script */
-static const OnigCodePoint CR_Khudawadi[] = {
- 2,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
-}; /* CR_Khudawadi */
-
-/* 'Tirhuta': Script */
-static const OnigCodePoint CR_Tirhuta[] = {
- 2,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
-}; /* CR_Tirhuta */
-
-/* 'Warang_Citi': Script */
-static const OnigCodePoint CR_Warang_Citi[] = {
- 2,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
-}; /* CR_Warang_Citi */
-
-/* 'Ahom': Script */
-static const OnigCodePoint CR_Ahom[] = {
- 3,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x1173f,
-}; /* CR_Ahom */
-
-/* 'Anatolian_Hieroglyphs': Script */
-static const OnigCodePoint CR_Anatolian_Hieroglyphs[] = {
- 1,
- 0x14400, 0x14646,
-}; /* CR_Anatolian_Hieroglyphs */
-
-/* 'Hatran': Script */
-static const OnigCodePoint CR_Hatran[] = {
- 3,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x108ff,
-}; /* CR_Hatran */
-
-/* 'Multani': Script */
-static const OnigCodePoint CR_Multani[] = {
- 5,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
-}; /* CR_Multani */
-
-/* 'Old_Hungarian': Script */
-static const OnigCodePoint CR_Old_Hungarian[] = {
- 3,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
-}; /* CR_Old_Hungarian */
-
-/* 'SignWriting': Script */
-static const OnigCodePoint CR_SignWriting[] = {
- 3,
- 0x1d800, 0x1da8b,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
-}; /* CR_SignWriting */
-
-/* 'Adlam': Script */
-static const OnigCodePoint CR_Adlam[] = {
- 3,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1e95e, 0x1e95f,
-}; /* CR_Adlam */
-
-/* 'Bhaiksuki': Script */
-static const OnigCodePoint CR_Bhaiksuki[] = {
- 4,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c45,
- 0x11c50, 0x11c6c,
-}; /* CR_Bhaiksuki */
-
-/* 'Marchen': Script */
-static const OnigCodePoint CR_Marchen[] = {
- 3,
- 0x11c70, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
-}; /* CR_Marchen */
-
-/* 'Newa': Script */
-static const OnigCodePoint CR_Newa[] = {
- 3,
- 0x11400, 0x11459,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
-}; /* CR_Newa */
-
-/* 'Osage': Script */
-static const OnigCodePoint CR_Osage[] = {
- 2,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
-}; /* CR_Osage */
-
-/* 'Tangut': Script */
-static const OnigCodePoint CR_Tangut[] = {
- 3,
- 0x16fe0, 0x16fe0,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
-}; /* CR_Tangut */
-
-/* 'Masaram_Gondi': Script */
-static const OnigCodePoint CR_Masaram_Gondi[] = {
- 7,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
-}; /* CR_Masaram_Gondi */
-
-/* 'Nushu': Script */
-static const OnigCodePoint CR_Nushu[] = {
- 2,
- 0x16fe1, 0x16fe1,
- 0x1b170, 0x1b2fb,
-}; /* CR_Nushu */
-
-/* 'Soyombo': Script */
-static const OnigCodePoint CR_Soyombo[] = {
- 3,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a9c,
- 0x11a9e, 0x11aa2,
-}; /* CR_Soyombo */
-
-/* 'Zanabazar_Square': Script */
-static const OnigCodePoint CR_Zanabazar_Square[] = {
- 1,
- 0x11a00, 0x11a47,
-}; /* CR_Zanabazar_Square */
-
-/* 'White_Space': Binary Property */
-#define CR_White_Space CR_Space
-
-/* 'Bidi_Control': Binary Property */
-static const OnigCodePoint CR_Bidi_Control[] = {
- 4,
- 0x061c, 0x061c,
- 0x200e, 0x200f,
- 0x202a, 0x202e,
- 0x2066, 0x2069,
-}; /* CR_Bidi_Control */
-
-/* 'Join_Control': Binary Property */
-static const OnigCodePoint CR_Join_Control[] = {
- 1,
- 0x200c, 0x200d,
-}; /* CR_Join_Control */
-
-/* 'Dash': Binary Property */
-static const OnigCodePoint CR_Dash[] = {
- 21,
- 0x002d, 0x002d,
- 0x058a, 0x058a,
- 0x05be, 0x05be,
- 0x1400, 0x1400,
- 0x1806, 0x1806,
- 0x2010, 0x2015,
- 0x2053, 0x2053,
- 0x207b, 0x207b,
- 0x208b, 0x208b,
- 0x2212, 0x2212,
- 0x2e17, 0x2e17,
- 0x2e1a, 0x2e1a,
- 0x2e3a, 0x2e3b,
- 0x2e40, 0x2e40,
- 0x301c, 0x301c,
- 0x3030, 0x3030,
- 0x30a0, 0x30a0,
- 0xfe31, 0xfe32,
- 0xfe58, 0xfe58,
- 0xfe63, 0xfe63,
- 0xff0d, 0xff0d,
-}; /* CR_Dash */
-
-/* 'Hyphen': Binary Property */
-static const OnigCodePoint CR_Hyphen[] = {
- 10,
- 0x002d, 0x002d,
- 0x00ad, 0x00ad,
- 0x058a, 0x058a,
- 0x1806, 0x1806,
- 0x2010, 0x2011,
- 0x2e17, 0x2e17,
- 0x30fb, 0x30fb,
- 0xfe63, 0xfe63,
- 0xff0d, 0xff0d,
- 0xff65, 0xff65,
-}; /* CR_Hyphen */
-
-/* 'Quotation_Mark': Binary Property */
-static const OnigCodePoint CR_Quotation_Mark[] = {
- 13,
- 0x0022, 0x0022,
- 0x0027, 0x0027,
- 0x00ab, 0x00ab,
- 0x00bb, 0x00bb,
- 0x2018, 0x201f,
- 0x2039, 0x203a,
- 0x2e42, 0x2e42,
- 0x300c, 0x300f,
- 0x301d, 0x301f,
- 0xfe41, 0xfe44,
- 0xff02, 0xff02,
- 0xff07, 0xff07,
- 0xff62, 0xff63,
-}; /* CR_Quotation_Mark */
-
-/* 'Terminal_Punctuation': Binary Property */
-static const OnigCodePoint CR_Terminal_Punctuation[] = {
- 97,
- 0x0021, 0x0021,
- 0x002c, 0x002c,
- 0x002e, 0x002e,
- 0x003a, 0x003b,
- 0x003f, 0x003f,
- 0x037e, 0x037e,
- 0x0387, 0x0387,
- 0x0589, 0x0589,
- 0x05c3, 0x05c3,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x06d4, 0x06d4,
- 0x0700, 0x070a,
- 0x070c, 0x070c,
- 0x07f8, 0x07f9,
- 0x0830, 0x083e,
- 0x085e, 0x085e,
- 0x0964, 0x0965,
- 0x0e5a, 0x0e5b,
- 0x0f08, 0x0f08,
- 0x0f0d, 0x0f12,
- 0x104a, 0x104b,
- 0x1361, 0x1368,
- 0x166d, 0x166e,
- 0x16eb, 0x16ed,
- 0x1735, 0x1736,
- 0x17d4, 0x17d6,
- 0x17da, 0x17da,
- 0x1802, 0x1805,
- 0x1808, 0x1809,
- 0x1944, 0x1945,
- 0x1aa8, 0x1aab,
- 0x1b5a, 0x1b5b,
- 0x1b5d, 0x1b5f,
- 0x1c3b, 0x1c3f,
- 0x1c7e, 0x1c7f,
- 0x203c, 0x203d,
- 0x2047, 0x2049,
- 0x2e2e, 0x2e2e,
- 0x2e3c, 0x2e3c,
- 0x2e41, 0x2e41,
- 0x3001, 0x3002,
- 0xa4fe, 0xa4ff,
- 0xa60d, 0xa60f,
- 0xa6f3, 0xa6f7,
- 0xa876, 0xa877,
- 0xa8ce, 0xa8cf,
- 0xa92f, 0xa92f,
- 0xa9c7, 0xa9c9,
- 0xaa5d, 0xaa5f,
- 0xaadf, 0xaadf,
- 0xaaf0, 0xaaf1,
- 0xabeb, 0xabeb,
- 0xfe50, 0xfe52,
- 0xfe54, 0xfe57,
- 0xff01, 0xff01,
- 0xff0c, 0xff0c,
- 0xff0e, 0xff0e,
- 0xff1a, 0xff1b,
- 0xff1f, 0xff1f,
- 0xff61, 0xff61,
- 0xff64, 0xff64,
- 0x1039f, 0x1039f,
- 0x103d0, 0x103d0,
- 0x10857, 0x10857,
- 0x1091f, 0x1091f,
- 0x10a56, 0x10a57,
- 0x10af0, 0x10af5,
- 0x10b3a, 0x10b3f,
- 0x10b99, 0x10b9c,
- 0x11047, 0x1104d,
- 0x110be, 0x110c1,
- 0x11141, 0x11143,
- 0x111c5, 0x111c6,
- 0x111cd, 0x111cd,
- 0x111de, 0x111df,
- 0x11238, 0x1123c,
- 0x112a9, 0x112a9,
- 0x1144b, 0x1144d,
- 0x1145b, 0x1145b,
- 0x115c2, 0x115c5,
- 0x115c9, 0x115d7,
- 0x11641, 0x11642,
- 0x1173c, 0x1173e,
- 0x11a42, 0x11a43,
- 0x11a9b, 0x11a9c,
- 0x11aa1, 0x11aa2,
- 0x11c41, 0x11c43,
- 0x11c71, 0x11c71,
- 0x12470, 0x12474,
- 0x16a6e, 0x16a6f,
- 0x16af5, 0x16af5,
- 0x16b37, 0x16b39,
- 0x16b44, 0x16b44,
- 0x1bc9f, 0x1bc9f,
- 0x1da87, 0x1da8a,
-}; /* CR_Terminal_Punctuation */
-
-/* 'Other_Math': Binary Property */
-static const OnigCodePoint CR_Other_Math[] = {
- 134,
- 0x005e, 0x005e,
- 0x03d0, 0x03d2,
- 0x03d5, 0x03d5,
- 0x03f0, 0x03f1,
- 0x03f4, 0x03f5,
- 0x2016, 0x2016,
- 0x2032, 0x2034,
- 0x2040, 0x2040,
- 0x2061, 0x2064,
- 0x207d, 0x207e,
- 0x208d, 0x208e,
- 0x20d0, 0x20dc,
- 0x20e1, 0x20e1,
- 0x20e5, 0x20e6,
- 0x20eb, 0x20ef,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2128, 0x2129,
- 0x212c, 0x212d,
- 0x212f, 0x2131,
- 0x2133, 0x2138,
- 0x213c, 0x213f,
- 0x2145, 0x2149,
- 0x2195, 0x2199,
- 0x219c, 0x219f,
- 0x21a1, 0x21a2,
- 0x21a4, 0x21a5,
- 0x21a7, 0x21a7,
- 0x21a9, 0x21ad,
- 0x21b0, 0x21b1,
- 0x21b6, 0x21b7,
- 0x21bc, 0x21cd,
- 0x21d0, 0x21d1,
- 0x21d3, 0x21d3,
- 0x21d5, 0x21db,
- 0x21dd, 0x21dd,
- 0x21e4, 0x21e5,
- 0x2308, 0x230b,
- 0x23b4, 0x23b5,
- 0x23b7, 0x23b7,
- 0x23d0, 0x23d0,
- 0x23e2, 0x23e2,
- 0x25a0, 0x25a1,
- 0x25ae, 0x25b6,
- 0x25bc, 0x25c0,
- 0x25c6, 0x25c7,
- 0x25ca, 0x25cb,
- 0x25cf, 0x25d3,
- 0x25e2, 0x25e2,
- 0x25e4, 0x25e4,
- 0x25e7, 0x25ec,
- 0x2605, 0x2606,
- 0x2640, 0x2640,
- 0x2642, 0x2642,
- 0x2660, 0x2663,
- 0x266d, 0x266e,
- 0x27c5, 0x27c6,
- 0x27e6, 0x27ef,
- 0x2983, 0x2998,
- 0x29d8, 0x29db,
- 0x29fc, 0x29fd,
- 0xfe61, 0xfe61,
- 0xfe63, 0xfe63,
- 0xfe68, 0xfe68,
- 0xff3c, 0xff3c,
- 0xff3e, 0xff3e,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
-}; /* CR_Other_Math */
-
-/* 'Hex_Digit': Binary Property */
-static const OnigCodePoint CR_Hex_Digit[] = {
- 6,
- 0x0030, 0x0039,
- 0x0041, 0x0046,
- 0x0061, 0x0066,
- 0xff10, 0xff19,
- 0xff21, 0xff26,
- 0xff41, 0xff46,
-}; /* CR_Hex_Digit */
-
-/* 'ASCII_Hex_Digit': Binary Property */
-#define CR_ASCII_Hex_Digit CR_XDigit
-
-/* 'Other_Alphabetic': Binary Property */
-static const OnigCodePoint CR_Other_Alphabetic[] = {
- 206,
- 0x0345, 0x0345,
- 0x05b0, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c5,
- 0x05c7, 0x05c7,
- 0x0610, 0x061a,
- 0x064b, 0x0657,
- 0x0659, 0x065f,
- 0x0670, 0x0670,
- 0x06d6, 0x06dc,
- 0x06e1, 0x06e4,
- 0x06e7, 0x06e8,
- 0x06ed, 0x06ed,
- 0x0711, 0x0711,
- 0x0730, 0x073f,
- 0x07a6, 0x07b0,
- 0x0816, 0x0817,
- 0x081b, 0x0823,
- 0x0825, 0x0827,
- 0x0829, 0x082c,
- 0x08d4, 0x08df,
- 0x08e3, 0x08e9,
- 0x08f0, 0x0903,
- 0x093a, 0x093b,
- 0x093e, 0x094c,
- 0x094e, 0x094f,
- 0x0955, 0x0957,
- 0x0962, 0x0963,
- 0x0981, 0x0983,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cc,
- 0x09d7, 0x09d7,
- 0x09e2, 0x09e3,
- 0x0a01, 0x0a03,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4c,
- 0x0a51, 0x0a51,
- 0x0a70, 0x0a71,
- 0x0a75, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0abe, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acc,
- 0x0ae2, 0x0ae3,
- 0x0afa, 0x0afc,
- 0x0b01, 0x0b03,
- 0x0b3e, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4c,
- 0x0b56, 0x0b57,
- 0x0b62, 0x0b63,
- 0x0b82, 0x0b82,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcc,
- 0x0bd7, 0x0bd7,
- 0x0c00, 0x0c03,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4c,
- 0x0c55, 0x0c56,
- 0x0c62, 0x0c63,
- 0x0c81, 0x0c83,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccc,
- 0x0cd5, 0x0cd6,
- 0x0ce2, 0x0ce3,
- 0x0d00, 0x0d03,
- 0x0d3e, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4c,
- 0x0d57, 0x0d57,
- 0x0d62, 0x0d63,
- 0x0d82, 0x0d83,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0e31, 0x0e31,
- 0x0e34, 0x0e3a,
- 0x0e4d, 0x0e4d,
- 0x0eb1, 0x0eb1,
- 0x0eb4, 0x0eb9,
- 0x0ebb, 0x0ebc,
- 0x0ecd, 0x0ecd,
- 0x0f71, 0x0f81,
- 0x0f8d, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x102b, 0x1036,
- 0x1038, 0x1038,
- 0x103b, 0x103e,
- 0x1056, 0x1059,
- 0x105e, 0x1060,
- 0x1062, 0x1062,
- 0x1067, 0x1068,
- 0x1071, 0x1074,
- 0x1082, 0x1086,
- 0x109c, 0x109d,
- 0x135f, 0x135f,
- 0x1712, 0x1713,
- 0x1732, 0x1733,
- 0x1752, 0x1753,
- 0x1772, 0x1773,
- 0x17b6, 0x17c8,
- 0x1885, 0x1886,
- 0x18a9, 0x18a9,
- 0x1920, 0x192b,
- 0x1930, 0x1938,
- 0x1a17, 0x1a1b,
- 0x1a55, 0x1a5e,
- 0x1a61, 0x1a74,
- 0x1b00, 0x1b04,
- 0x1b35, 0x1b43,
- 0x1b80, 0x1b82,
- 0x1ba1, 0x1ba9,
- 0x1bac, 0x1bad,
- 0x1be7, 0x1bf1,
- 0x1c24, 0x1c35,
- 0x1cf2, 0x1cf3,
- 0x1de7, 0x1df4,
- 0x24b6, 0x24e9,
- 0x2de0, 0x2dff,
- 0xa674, 0xa67b,
- 0xa69e, 0xa69f,
- 0xa823, 0xa827,
- 0xa880, 0xa881,
- 0xa8b4, 0xa8c3,
- 0xa8c5, 0xa8c5,
- 0xa926, 0xa92a,
- 0xa947, 0xa952,
- 0xa980, 0xa983,
- 0xa9b4, 0xa9bf,
- 0xaa29, 0xaa36,
- 0xaa43, 0xaa43,
- 0xaa4c, 0xaa4d,
- 0xaab0, 0xaab0,
- 0xaab2, 0xaab4,
- 0xaab7, 0xaab8,
- 0xaabe, 0xaabe,
- 0xaaeb, 0xaaef,
- 0xaaf5, 0xaaf5,
- 0xabe3, 0xabea,
- 0xfb1e, 0xfb1e,
- 0x10376, 0x1037a,
- 0x10a01, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a0f,
- 0x11000, 0x11002,
- 0x11038, 0x11045,
- 0x11082, 0x11082,
- 0x110b0, 0x110b8,
- 0x11100, 0x11102,
- 0x11127, 0x11132,
- 0x11180, 0x11182,
- 0x111b3, 0x111bf,
- 0x1122c, 0x11234,
- 0x11237, 0x11237,
- 0x1123e, 0x1123e,
- 0x112df, 0x112e8,
- 0x11300, 0x11303,
- 0x1133e, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134c,
- 0x11357, 0x11357,
- 0x11362, 0x11363,
- 0x11435, 0x11441,
- 0x11443, 0x11445,
- 0x114b0, 0x114c1,
- 0x115af, 0x115b5,
- 0x115b8, 0x115be,
- 0x115dc, 0x115dd,
- 0x11630, 0x1163e,
- 0x11640, 0x11640,
- 0x116ab, 0x116b5,
- 0x1171d, 0x1172a,
- 0x11a01, 0x11a0a,
- 0x11a35, 0x11a39,
- 0x11a3b, 0x11a3e,
- 0x11a51, 0x11a5b,
- 0x11a8a, 0x11a97,
- 0x11c2f, 0x11c36,
- 0x11c38, 0x11c3e,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d31, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d41,
- 0x11d43, 0x11d43,
- 0x11d47, 0x11d47,
- 0x16b30, 0x16b36,
- 0x16f51, 0x16f7e,
- 0x1bc9e, 0x1bc9e,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e947, 0x1e947,
- 0x1f130, 0x1f149,
- 0x1f150, 0x1f169,
- 0x1f170, 0x1f189,
-}; /* CR_Other_Alphabetic */
-
-/* 'Ideographic': Binary Property */
-static const OnigCodePoint CR_Ideographic[] = {
- 16,
- 0x3006, 0x3007,
- 0x3021, 0x3029,
- 0x3038, 0x303a,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b170, 0x1b2fb,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
-}; /* CR_Ideographic */
-
-/* 'Diacritic': Binary Property */
-static const OnigCodePoint CR_Diacritic[] = {
- 159,
- 0x005e, 0x005e,
- 0x0060, 0x0060,
- 0x00a8, 0x00a8,
- 0x00af, 0x00af,
- 0x00b4, 0x00b4,
- 0x00b7, 0x00b8,
- 0x02b0, 0x034e,
- 0x0350, 0x0357,
- 0x035d, 0x0362,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x0384, 0x0385,
- 0x0483, 0x0487,
- 0x0559, 0x0559,
- 0x0591, 0x05a1,
- 0x05a3, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c4,
- 0x064b, 0x0652,
- 0x0657, 0x0658,
- 0x06df, 0x06e0,
- 0x06e5, 0x06e6,
- 0x06ea, 0x06ec,
- 0x0730, 0x074a,
- 0x07a6, 0x07b0,
- 0x07eb, 0x07f5,
- 0x0818, 0x0819,
- 0x08e3, 0x08fe,
- 0x093c, 0x093c,
- 0x094d, 0x094d,
- 0x0951, 0x0954,
- 0x0971, 0x0971,
- 0x09bc, 0x09bc,
- 0x09cd, 0x09cd,
- 0x0a3c, 0x0a3c,
- 0x0a4d, 0x0a4d,
- 0x0abc, 0x0abc,
- 0x0acd, 0x0acd,
- 0x0afd, 0x0aff,
- 0x0b3c, 0x0b3c,
- 0x0b4d, 0x0b4d,
- 0x0bcd, 0x0bcd,
- 0x0c4d, 0x0c4d,
- 0x0cbc, 0x0cbc,
- 0x0ccd, 0x0ccd,
- 0x0d3b, 0x0d3c,
- 0x0d4d, 0x0d4d,
- 0x0dca, 0x0dca,
- 0x0e47, 0x0e4c,
- 0x0e4e, 0x0e4e,
- 0x0ec8, 0x0ecc,
- 0x0f18, 0x0f19,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f3f,
- 0x0f82, 0x0f84,
- 0x0f86, 0x0f87,
- 0x0fc6, 0x0fc6,
- 0x1037, 0x1037,
- 0x1039, 0x103a,
- 0x1087, 0x108d,
- 0x108f, 0x108f,
- 0x109a, 0x109b,
- 0x17c9, 0x17d3,
- 0x17dd, 0x17dd,
- 0x1939, 0x193b,
- 0x1a75, 0x1a7c,
- 0x1a7f, 0x1a7f,
- 0x1ab0, 0x1abd,
- 0x1b34, 0x1b34,
- 0x1b44, 0x1b44,
- 0x1b6b, 0x1b73,
- 0x1baa, 0x1bab,
- 0x1c36, 0x1c37,
- 0x1c78, 0x1c7d,
- 0x1cd0, 0x1ce8,
- 0x1ced, 0x1ced,
- 0x1cf4, 0x1cf4,
- 0x1cf7, 0x1cf9,
- 0x1d2c, 0x1d6a,
- 0x1dc4, 0x1dcf,
- 0x1df5, 0x1df9,
- 0x1dfd, 0x1dff,
- 0x1fbd, 0x1fbd,
- 0x1fbf, 0x1fc1,
- 0x1fcd, 0x1fcf,
- 0x1fdd, 0x1fdf,
- 0x1fed, 0x1fef,
- 0x1ffd, 0x1ffe,
- 0x2cef, 0x2cf1,
- 0x2e2f, 0x2e2f,
- 0x302a, 0x302f,
- 0x3099, 0x309c,
- 0x30fc, 0x30fc,
- 0xa66f, 0xa66f,
- 0xa67c, 0xa67d,
- 0xa67f, 0xa67f,
- 0xa69c, 0xa69d,
- 0xa6f0, 0xa6f1,
- 0xa717, 0xa721,
- 0xa788, 0xa788,
- 0xa7f8, 0xa7f9,
- 0xa8c4, 0xa8c4,
- 0xa8e0, 0xa8f1,
- 0xa92b, 0xa92e,
- 0xa953, 0xa953,
- 0xa9b3, 0xa9b3,
- 0xa9c0, 0xa9c0,
- 0xa9e5, 0xa9e5,
- 0xaa7b, 0xaa7d,
- 0xaabf, 0xaac2,
- 0xaaf6, 0xaaf6,
- 0xab5b, 0xab5f,
- 0xabec, 0xabed,
- 0xfb1e, 0xfb1e,
- 0xfe20, 0xfe2f,
- 0xff3e, 0xff3e,
- 0xff40, 0xff40,
- 0xff70, 0xff70,
- 0xff9e, 0xff9f,
- 0xffe3, 0xffe3,
- 0x102e0, 0x102e0,
- 0x10ae5, 0x10ae6,
- 0x110b9, 0x110ba,
- 0x11133, 0x11134,
- 0x11173, 0x11173,
- 0x111c0, 0x111c0,
- 0x111ca, 0x111cc,
- 0x11235, 0x11236,
- 0x112e9, 0x112ea,
- 0x1133c, 0x1133c,
- 0x1134d, 0x1134d,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11442, 0x11442,
- 0x11446, 0x11446,
- 0x114c2, 0x114c3,
- 0x115bf, 0x115c0,
- 0x1163f, 0x1163f,
- 0x116b6, 0x116b7,
- 0x1172b, 0x1172b,
- 0x11a34, 0x11a34,
- 0x11a47, 0x11a47,
- 0x11a99, 0x11a99,
- 0x11c3f, 0x11c3f,
- 0x11d42, 0x11d42,
- 0x11d44, 0x11d45,
- 0x16af0, 0x16af4,
- 0x16f8f, 0x16f9f,
- 0x1d167, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1e8d0, 0x1e8d6,
- 0x1e944, 0x1e946,
- 0x1e948, 0x1e94a,
-}; /* CR_Diacritic */
-
-/* 'Extender': Binary Property */
-static const OnigCodePoint CR_Extender[] = {
- 29,
- 0x00b7, 0x00b7,
- 0x02d0, 0x02d1,
- 0x0640, 0x0640,
- 0x07fa, 0x07fa,
- 0x0e46, 0x0e46,
- 0x0ec6, 0x0ec6,
- 0x180a, 0x180a,
- 0x1843, 0x1843,
- 0x1aa7, 0x1aa7,
- 0x1c36, 0x1c36,
- 0x1c7b, 0x1c7b,
- 0x3005, 0x3005,
- 0x3031, 0x3035,
- 0x309d, 0x309e,
- 0x30fc, 0x30fe,
- 0xa015, 0xa015,
- 0xa60c, 0xa60c,
- 0xa9cf, 0xa9cf,
- 0xa9e6, 0xa9e6,
- 0xaa70, 0xaa70,
- 0xaadd, 0xaadd,
- 0xaaf3, 0xaaf4,
- 0xff70, 0xff70,
- 0x1135d, 0x1135d,
- 0x115c6, 0x115c8,
- 0x11a98, 0x11a98,
- 0x16b42, 0x16b43,
- 0x16fe0, 0x16fe1,
- 0x1e944, 0x1e946,
-}; /* CR_Extender */
-
-/* 'Other_Lowercase': Binary Property */
-static const OnigCodePoint CR_Other_Lowercase[] = {
- 20,
- 0x00aa, 0x00aa,
- 0x00ba, 0x00ba,
- 0x02b0, 0x02b8,
- 0x02c0, 0x02c1,
- 0x02e0, 0x02e4,
- 0x0345, 0x0345,
- 0x037a, 0x037a,
- 0x1d2c, 0x1d6a,
- 0x1d78, 0x1d78,
- 0x1d9b, 0x1dbf,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x2090, 0x209c,
- 0x2170, 0x217f,
- 0x24d0, 0x24e9,
- 0x2c7c, 0x2c7d,
- 0xa69c, 0xa69d,
- 0xa770, 0xa770,
- 0xa7f8, 0xa7f9,
- 0xab5c, 0xab5f,
-}; /* CR_Other_Lowercase */
-
-/* 'Other_Uppercase': Binary Property */
-static const OnigCodePoint CR_Other_Uppercase[] = {
- 5,
- 0x2160, 0x216f,
- 0x24b6, 0x24cf,
- 0x1f130, 0x1f149,
- 0x1f150, 0x1f169,
- 0x1f170, 0x1f189,
-}; /* CR_Other_Uppercase */
-
-/* 'Noncharacter_Code_Point': Binary Property */
-static const OnigCodePoint CR_Noncharacter_Code_Point[] = {
- 18,
- 0xfdd0, 0xfdef,
- 0xfffe, 0xffff,
- 0x1fffe, 0x1ffff,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xefffe, 0xeffff,
- 0xffffe, 0xfffff,
- 0x10fffe, 0x10ffff,
-}; /* CR_Noncharacter_Code_Point */
-
-/* 'Other_Grapheme_Extend': Binary Property */
-static const OnigCodePoint CR_Other_Grapheme_Extend[] = {
- 23,
- 0x09be, 0x09be,
- 0x09d7, 0x09d7,
- 0x0b3e, 0x0b3e,
- 0x0b57, 0x0b57,
- 0x0bbe, 0x0bbe,
- 0x0bd7, 0x0bd7,
- 0x0cc2, 0x0cc2,
- 0x0cd5, 0x0cd6,
- 0x0d3e, 0x0d3e,
- 0x0d57, 0x0d57,
- 0x0dcf, 0x0dcf,
- 0x0ddf, 0x0ddf,
- 0x200c, 0x200c,
- 0x302e, 0x302f,
- 0xff9e, 0xff9f,
- 0x1133e, 0x1133e,
- 0x11357, 0x11357,
- 0x114b0, 0x114b0,
- 0x114bd, 0x114bd,
- 0x115af, 0x115af,
- 0x1d165, 0x1d165,
- 0x1d16e, 0x1d172,
- 0xe0020, 0xe007f,
-}; /* CR_Other_Grapheme_Extend */
-
-/* 'IDS_Binary_Operator': Binary Property */
-static const OnigCodePoint CR_IDS_Binary_Operator[] = {
- 2,
- 0x2ff0, 0x2ff1,
- 0x2ff4, 0x2ffb,
-}; /* CR_IDS_Binary_Operator */
-
-/* 'IDS_Trinary_Operator': Binary Property */
-static const OnigCodePoint CR_IDS_Trinary_Operator[] = {
- 1,
- 0x2ff2, 0x2ff3,
-}; /* CR_IDS_Trinary_Operator */
-
-/* 'Radical': Binary Property */
-static const OnigCodePoint CR_Radical[] = {
- 3,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
-}; /* CR_Radical */
-
-/* 'Unified_Ideograph': Binary Property */
-static const OnigCodePoint CR_Unified_Ideograph[] = {
- 14,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fea,
- 0xfa0e, 0xfa0f,
- 0xfa11, 0xfa11,
- 0xfa13, 0xfa14,
- 0xfa1f, 0xfa1f,
- 0xfa21, 0xfa21,
- 0xfa23, 0xfa24,
- 0xfa27, 0xfa29,
- 0x20000, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
-}; /* CR_Unified_Ideograph */
-
-/* 'Other_Default_Ignorable_Code_Point': Binary Property */
-static const OnigCodePoint CR_Other_Default_Ignorable_Code_Point[] = {
- 11,
- 0x034f, 0x034f,
- 0x115f, 0x1160,
- 0x17b4, 0x17b5,
- 0x2065, 0x2065,
- 0x3164, 0x3164,
- 0xffa0, 0xffa0,
- 0xfff0, 0xfff8,
- 0xe0000, 0xe0000,
- 0xe0002, 0xe001f,
- 0xe0080, 0xe00ff,
- 0xe01f0, 0xe0fff,
-}; /* CR_Other_Default_Ignorable_Code_Point */
-
-/* 'Deprecated': Binary Property */
-static const OnigCodePoint CR_Deprecated[] = {
- 8,
- 0x0149, 0x0149,
- 0x0673, 0x0673,
- 0x0f77, 0x0f77,
- 0x0f79, 0x0f79,
- 0x17a3, 0x17a4,
- 0x206a, 0x206f,
- 0x2329, 0x232a,
- 0xe0001, 0xe0001,
-}; /* CR_Deprecated */
-
-/* 'Soft_Dotted': Binary Property */
-static const OnigCodePoint CR_Soft_Dotted[] = {
- 31,
- 0x0069, 0x006a,
- 0x012f, 0x012f,
- 0x0249, 0x0249,
- 0x0268, 0x0268,
- 0x029d, 0x029d,
- 0x02b2, 0x02b2,
- 0x03f3, 0x03f3,
- 0x0456, 0x0456,
- 0x0458, 0x0458,
- 0x1d62, 0x1d62,
- 0x1d96, 0x1d96,
- 0x1da4, 0x1da4,
- 0x1da8, 0x1da8,
- 0x1e2d, 0x1e2d,
- 0x1ecb, 0x1ecb,
- 0x2071, 0x2071,
- 0x2148, 0x2149,
- 0x2c7c, 0x2c7c,
- 0x1d422, 0x1d423,
- 0x1d456, 0x1d457,
- 0x1d48a, 0x1d48b,
- 0x1d4be, 0x1d4bf,
- 0x1d4f2, 0x1d4f3,
- 0x1d526, 0x1d527,
- 0x1d55a, 0x1d55b,
- 0x1d58e, 0x1d58f,
- 0x1d5c2, 0x1d5c3,
- 0x1d5f6, 0x1d5f7,
- 0x1d62a, 0x1d62b,
- 0x1d65e, 0x1d65f,
- 0x1d692, 0x1d693,
-}; /* CR_Soft_Dotted */
-
-/* 'Logical_Order_Exception': Binary Property */
-static const OnigCodePoint CR_Logical_Order_Exception[] = {
- 7,
- 0x0e40, 0x0e44,
- 0x0ec0, 0x0ec4,
- 0x19b5, 0x19b7,
- 0x19ba, 0x19ba,
- 0xaab5, 0xaab6,
- 0xaab9, 0xaab9,
- 0xaabb, 0xaabc,
-}; /* CR_Logical_Order_Exception */
-
-/* 'Other_ID_Start': Binary Property */
-static const OnigCodePoint CR_Other_ID_Start[] = {
- 4,
- 0x1885, 0x1886,
- 0x2118, 0x2118,
- 0x212e, 0x212e,
- 0x309b, 0x309c,
-}; /* CR_Other_ID_Start */
-
-/* 'Other_ID_Continue': Binary Property */
-static const OnigCodePoint CR_Other_ID_Continue[] = {
- 4,
- 0x00b7, 0x00b7,
- 0x0387, 0x0387,
- 0x1369, 0x1371,
- 0x19da, 0x19da,
-}; /* CR_Other_ID_Continue */
-
-/* 'Sentence_Terminal': Binary Property */
-static const OnigCodePoint CR_Sentence_Terminal[] = {
- 68,
- 0x0021, 0x0021,
- 0x002e, 0x002e,
- 0x003f, 0x003f,
- 0x0589, 0x0589,
- 0x061f, 0x061f,
- 0x06d4, 0x06d4,
- 0x0700, 0x0702,
- 0x07f9, 0x07f9,
- 0x0964, 0x0965,
- 0x104a, 0x104b,
- 0x1362, 0x1362,
- 0x1367, 0x1368,
- 0x166e, 0x166e,
- 0x1735, 0x1736,
- 0x1803, 0x1803,
- 0x1809, 0x1809,
- 0x1944, 0x1945,
- 0x1aa8, 0x1aab,
- 0x1b5a, 0x1b5b,
- 0x1b5e, 0x1b5f,
- 0x1c3b, 0x1c3c,
- 0x1c7e, 0x1c7f,
- 0x203c, 0x203d,
- 0x2047, 0x2049,
- 0x2e2e, 0x2e2e,
- 0x2e3c, 0x2e3c,
- 0x3002, 0x3002,
- 0xa4ff, 0xa4ff,
- 0xa60e, 0xa60f,
- 0xa6f3, 0xa6f3,
- 0xa6f7, 0xa6f7,
- 0xa876, 0xa877,
- 0xa8ce, 0xa8cf,
- 0xa92f, 0xa92f,
- 0xa9c8, 0xa9c9,
- 0xaa5d, 0xaa5f,
- 0xaaf0, 0xaaf1,
- 0xabeb, 0xabeb,
- 0xfe52, 0xfe52,
- 0xfe56, 0xfe57,
- 0xff01, 0xff01,
- 0xff0e, 0xff0e,
- 0xff1f, 0xff1f,
- 0xff61, 0xff61,
- 0x10a56, 0x10a57,
- 0x11047, 0x11048,
- 0x110be, 0x110c1,
- 0x11141, 0x11143,
- 0x111c5, 0x111c6,
- 0x111cd, 0x111cd,
- 0x111de, 0x111df,
- 0x11238, 0x11239,
- 0x1123b, 0x1123c,
- 0x112a9, 0x112a9,
- 0x1144b, 0x1144c,
- 0x115c2, 0x115c3,
- 0x115c9, 0x115d7,
- 0x11641, 0x11642,
- 0x1173c, 0x1173e,
- 0x11a42, 0x11a43,
- 0x11a9b, 0x11a9c,
- 0x11c41, 0x11c42,
- 0x16a6e, 0x16a6f,
- 0x16af5, 0x16af5,
- 0x16b37, 0x16b38,
- 0x16b44, 0x16b44,
- 0x1bc9f, 0x1bc9f,
- 0x1da88, 0x1da88,
-}; /* CR_Sentence_Terminal */
-
-/* 'Variation_Selector': Binary Property */
-static const OnigCodePoint CR_Variation_Selector[] = {
- 3,
- 0x180b, 0x180d,
- 0xfe00, 0xfe0f,
- 0xe0100, 0xe01ef,
-}; /* CR_Variation_Selector */
-
-/* 'Pattern_White_Space': Binary Property */
-static const OnigCodePoint CR_Pattern_White_Space[] = {
- 5,
- 0x0009, 0x000d,
- 0x0020, 0x0020,
- 0x0085, 0x0085,
- 0x200e, 0x200f,
- 0x2028, 0x2029,
-}; /* CR_Pattern_White_Space */
-
-/* 'Pattern_Syntax': Binary Property */
-static const OnigCodePoint CR_Pattern_Syntax[] = {
- 28,
- 0x0021, 0x002f,
- 0x003a, 0x0040,
- 0x005b, 0x005e,
- 0x0060, 0x0060,
- 0x007b, 0x007e,
- 0x00a1, 0x00a7,
- 0x00a9, 0x00a9,
- 0x00ab, 0x00ac,
- 0x00ae, 0x00ae,
- 0x00b0, 0x00b1,
- 0x00b6, 0x00b6,
- 0x00bb, 0x00bb,
- 0x00bf, 0x00bf,
- 0x00d7, 0x00d7,
- 0x00f7, 0x00f7,
- 0x2010, 0x2027,
- 0x2030, 0x203e,
- 0x2041, 0x2053,
- 0x2055, 0x205e,
- 0x2190, 0x245f,
- 0x2500, 0x2775,
- 0x2794, 0x2bff,
- 0x2e00, 0x2e7f,
- 0x3001, 0x3003,
- 0x3008, 0x3020,
- 0x3030, 0x3030,
- 0xfd3e, 0xfd3f,
- 0xfe45, 0xfe46,
-}; /* CR_Pattern_Syntax */
-
-/* 'Prepended_Concatenation_Mark': Binary Property */
-static const OnigCodePoint CR_Prepended_Concatenation_Mark[] = {
- 5,
- 0x0600, 0x0605,
- 0x06dd, 0x06dd,
- 0x070f, 0x070f,
- 0x08e2, 0x08e2,
- 0x110bd, 0x110bd,
-}; /* CR_Prepended_Concatenation_Mark */
-
-/* 'Regional_Indicator': Binary Property */
-static const OnigCodePoint CR_Regional_Indicator[] = {
- 1,
- 0x1f1e6, 0x1f1ff,
-}; /* CR_Regional_Indicator */
-
-/* 'Unknown': Script */
-static const OnigCodePoint CR_Unknown[] = {
- 647,
- 0x0378, 0x0379,
- 0x0380, 0x0383,
- 0x038b, 0x038b,
- 0x038d, 0x038d,
- 0x03a2, 0x03a2,
- 0x0530, 0x0530,
- 0x0557, 0x0558,
- 0x0560, 0x0560,
- 0x0588, 0x0588,
- 0x058b, 0x058c,
- 0x0590, 0x0590,
- 0x05c8, 0x05cf,
- 0x05eb, 0x05ef,
- 0x05f5, 0x05ff,
- 0x061d, 0x061d,
- 0x070e, 0x070e,
- 0x074b, 0x074c,
- 0x07b2, 0x07bf,
- 0x07fb, 0x07ff,
- 0x082e, 0x082f,
- 0x083f, 0x083f,
- 0x085c, 0x085d,
- 0x085f, 0x085f,
- 0x086b, 0x089f,
- 0x08b5, 0x08b5,
- 0x08be, 0x08d3,
- 0x0984, 0x0984,
- 0x098d, 0x098e,
- 0x0991, 0x0992,
- 0x09a9, 0x09a9,
- 0x09b1, 0x09b1,
- 0x09b3, 0x09b5,
- 0x09ba, 0x09bb,
- 0x09c5, 0x09c6,
- 0x09c9, 0x09ca,
- 0x09cf, 0x09d6,
- 0x09d8, 0x09db,
- 0x09de, 0x09de,
- 0x09e4, 0x09e5,
- 0x09fe, 0x0a00,
- 0x0a04, 0x0a04,
- 0x0a0b, 0x0a0e,
- 0x0a11, 0x0a12,
- 0x0a29, 0x0a29,
- 0x0a31, 0x0a31,
- 0x0a34, 0x0a34,
- 0x0a37, 0x0a37,
- 0x0a3a, 0x0a3b,
- 0x0a3d, 0x0a3d,
- 0x0a43, 0x0a46,
- 0x0a49, 0x0a4a,
- 0x0a4e, 0x0a50,
- 0x0a52, 0x0a58,
- 0x0a5d, 0x0a5d,
- 0x0a5f, 0x0a65,
- 0x0a76, 0x0a80,
- 0x0a84, 0x0a84,
- 0x0a8e, 0x0a8e,
- 0x0a92, 0x0a92,
- 0x0aa9, 0x0aa9,
- 0x0ab1, 0x0ab1,
- 0x0ab4, 0x0ab4,
- 0x0aba, 0x0abb,
- 0x0ac6, 0x0ac6,
- 0x0aca, 0x0aca,
- 0x0ace, 0x0acf,
- 0x0ad1, 0x0adf,
- 0x0ae4, 0x0ae5,
- 0x0af2, 0x0af8,
- 0x0b00, 0x0b00,
- 0x0b04, 0x0b04,
- 0x0b0d, 0x0b0e,
- 0x0b11, 0x0b12,
- 0x0b29, 0x0b29,
- 0x0b31, 0x0b31,
- 0x0b34, 0x0b34,
- 0x0b3a, 0x0b3b,
- 0x0b45, 0x0b46,
- 0x0b49, 0x0b4a,
- 0x0b4e, 0x0b55,
- 0x0b58, 0x0b5b,
- 0x0b5e, 0x0b5e,
- 0x0b64, 0x0b65,
- 0x0b78, 0x0b81,
- 0x0b84, 0x0b84,
- 0x0b8b, 0x0b8d,
- 0x0b91, 0x0b91,
- 0x0b96, 0x0b98,
- 0x0b9b, 0x0b9b,
- 0x0b9d, 0x0b9d,
- 0x0ba0, 0x0ba2,
- 0x0ba5, 0x0ba7,
- 0x0bab, 0x0bad,
- 0x0bba, 0x0bbd,
- 0x0bc3, 0x0bc5,
- 0x0bc9, 0x0bc9,
- 0x0bce, 0x0bcf,
- 0x0bd1, 0x0bd6,
- 0x0bd8, 0x0be5,
- 0x0bfb, 0x0bff,
- 0x0c04, 0x0c04,
- 0x0c0d, 0x0c0d,
- 0x0c11, 0x0c11,
- 0x0c29, 0x0c29,
- 0x0c3a, 0x0c3c,
- 0x0c45, 0x0c45,
- 0x0c49, 0x0c49,
- 0x0c4e, 0x0c54,
- 0x0c57, 0x0c57,
- 0x0c5b, 0x0c5f,
- 0x0c64, 0x0c65,
- 0x0c70, 0x0c77,
- 0x0c84, 0x0c84,
- 0x0c8d, 0x0c8d,
- 0x0c91, 0x0c91,
- 0x0ca9, 0x0ca9,
- 0x0cb4, 0x0cb4,
- 0x0cba, 0x0cbb,
- 0x0cc5, 0x0cc5,
- 0x0cc9, 0x0cc9,
- 0x0cce, 0x0cd4,
- 0x0cd7, 0x0cdd,
- 0x0cdf, 0x0cdf,
- 0x0ce4, 0x0ce5,
- 0x0cf0, 0x0cf0,
- 0x0cf3, 0x0cff,
- 0x0d04, 0x0d04,
- 0x0d0d, 0x0d0d,
- 0x0d11, 0x0d11,
- 0x0d45, 0x0d45,
- 0x0d49, 0x0d49,
- 0x0d50, 0x0d53,
- 0x0d64, 0x0d65,
- 0x0d80, 0x0d81,
- 0x0d84, 0x0d84,
- 0x0d97, 0x0d99,
- 0x0db2, 0x0db2,
- 0x0dbc, 0x0dbc,
- 0x0dbe, 0x0dbf,
- 0x0dc7, 0x0dc9,
- 0x0dcb, 0x0dce,
- 0x0dd5, 0x0dd5,
- 0x0dd7, 0x0dd7,
- 0x0de0, 0x0de5,
- 0x0df0, 0x0df1,
- 0x0df5, 0x0e00,
- 0x0e3b, 0x0e3e,
- 0x0e5c, 0x0e80,
- 0x0e83, 0x0e83,
- 0x0e85, 0x0e86,
- 0x0e89, 0x0e89,
- 0x0e8b, 0x0e8c,
- 0x0e8e, 0x0e93,
- 0x0e98, 0x0e98,
- 0x0ea0, 0x0ea0,
- 0x0ea4, 0x0ea4,
- 0x0ea6, 0x0ea6,
- 0x0ea8, 0x0ea9,
- 0x0eac, 0x0eac,
- 0x0eba, 0x0eba,
- 0x0ebe, 0x0ebf,
- 0x0ec5, 0x0ec5,
- 0x0ec7, 0x0ec7,
- 0x0ece, 0x0ecf,
- 0x0eda, 0x0edb,
- 0x0ee0, 0x0eff,
- 0x0f48, 0x0f48,
- 0x0f6d, 0x0f70,
- 0x0f98, 0x0f98,
- 0x0fbd, 0x0fbd,
- 0x0fcd, 0x0fcd,
- 0x0fdb, 0x0fff,
- 0x10c6, 0x10c6,
- 0x10c8, 0x10cc,
- 0x10ce, 0x10cf,
- 0x1249, 0x1249,
- 0x124e, 0x124f,
- 0x1257, 0x1257,
- 0x1259, 0x1259,
- 0x125e, 0x125f,
- 0x1289, 0x1289,
- 0x128e, 0x128f,
- 0x12b1, 0x12b1,
- 0x12b6, 0x12b7,
- 0x12bf, 0x12bf,
- 0x12c1, 0x12c1,
- 0x12c6, 0x12c7,
- 0x12d7, 0x12d7,
- 0x1311, 0x1311,
- 0x1316, 0x1317,
- 0x135b, 0x135c,
- 0x137d, 0x137f,
- 0x139a, 0x139f,
- 0x13f6, 0x13f7,
- 0x13fe, 0x13ff,
- 0x169d, 0x169f,
- 0x16f9, 0x16ff,
- 0x170d, 0x170d,
- 0x1715, 0x171f,
- 0x1737, 0x173f,
- 0x1754, 0x175f,
- 0x176d, 0x176d,
- 0x1771, 0x1771,
- 0x1774, 0x177f,
- 0x17de, 0x17df,
- 0x17ea, 0x17ef,
- 0x17fa, 0x17ff,
- 0x180f, 0x180f,
- 0x181a, 0x181f,
- 0x1878, 0x187f,
- 0x18ab, 0x18af,
- 0x18f6, 0x18ff,
- 0x191f, 0x191f,
- 0x192c, 0x192f,
- 0x193c, 0x193f,
- 0x1941, 0x1943,
- 0x196e, 0x196f,
- 0x1975, 0x197f,
- 0x19ac, 0x19af,
- 0x19ca, 0x19cf,
- 0x19db, 0x19dd,
- 0x1a1c, 0x1a1d,
- 0x1a5f, 0x1a5f,
- 0x1a7d, 0x1a7e,
- 0x1a8a, 0x1a8f,
- 0x1a9a, 0x1a9f,
- 0x1aae, 0x1aaf,
- 0x1abf, 0x1aff,
- 0x1b4c, 0x1b4f,
- 0x1b7d, 0x1b7f,
- 0x1bf4, 0x1bfb,
- 0x1c38, 0x1c3a,
- 0x1c4a, 0x1c4c,
- 0x1c89, 0x1cbf,
- 0x1cc8, 0x1ccf,
- 0x1cfa, 0x1cff,
- 0x1dfa, 0x1dfa,
- 0x1f16, 0x1f17,
- 0x1f1e, 0x1f1f,
- 0x1f46, 0x1f47,
- 0x1f4e, 0x1f4f,
- 0x1f58, 0x1f58,
- 0x1f5a, 0x1f5a,
- 0x1f5c, 0x1f5c,
- 0x1f5e, 0x1f5e,
- 0x1f7e, 0x1f7f,
- 0x1fb5, 0x1fb5,
- 0x1fc5, 0x1fc5,
- 0x1fd4, 0x1fd5,
- 0x1fdc, 0x1fdc,
- 0x1ff0, 0x1ff1,
- 0x1ff5, 0x1ff5,
- 0x1fff, 0x1fff,
- 0x2065, 0x2065,
- 0x2072, 0x2073,
- 0x208f, 0x208f,
- 0x209d, 0x209f,
- 0x20c0, 0x20cf,
- 0x20f1, 0x20ff,
- 0x218c, 0x218f,
- 0x2427, 0x243f,
- 0x244b, 0x245f,
- 0x2b74, 0x2b75,
- 0x2b96, 0x2b97,
- 0x2bba, 0x2bbc,
- 0x2bc9, 0x2bc9,
- 0x2bd3, 0x2beb,
- 0x2bf0, 0x2bff,
- 0x2c2f, 0x2c2f,
- 0x2c5f, 0x2c5f,
- 0x2cf4, 0x2cf8,
- 0x2d26, 0x2d26,
- 0x2d28, 0x2d2c,
- 0x2d2e, 0x2d2f,
- 0x2d68, 0x2d6e,
- 0x2d71, 0x2d7e,
- 0x2d97, 0x2d9f,
- 0x2da7, 0x2da7,
- 0x2daf, 0x2daf,
- 0x2db7, 0x2db7,
- 0x2dbf, 0x2dbf,
- 0x2dc7, 0x2dc7,
- 0x2dcf, 0x2dcf,
- 0x2dd7, 0x2dd7,
- 0x2ddf, 0x2ddf,
- 0x2e4a, 0x2e7f,
- 0x2e9a, 0x2e9a,
- 0x2ef4, 0x2eff,
- 0x2fd6, 0x2fef,
- 0x2ffc, 0x2fff,
- 0x3040, 0x3040,
- 0x3097, 0x3098,
- 0x3100, 0x3104,
- 0x312f, 0x3130,
- 0x318f, 0x318f,
- 0x31bb, 0x31bf,
- 0x31e4, 0x31ef,
- 0x321f, 0x321f,
- 0x32ff, 0x32ff,
- 0x4db6, 0x4dbf,
- 0x9feb, 0x9fff,
- 0xa48d, 0xa48f,
- 0xa4c7, 0xa4cf,
- 0xa62c, 0xa63f,
- 0xa6f8, 0xa6ff,
- 0xa7af, 0xa7af,
- 0xa7b8, 0xa7f6,
- 0xa82c, 0xa82f,
- 0xa83a, 0xa83f,
- 0xa878, 0xa87f,
- 0xa8c6, 0xa8cd,
- 0xa8da, 0xa8df,
- 0xa8fe, 0xa8ff,
- 0xa954, 0xa95e,
- 0xa97d, 0xa97f,
- 0xa9ce, 0xa9ce,
- 0xa9da, 0xa9dd,
- 0xa9ff, 0xa9ff,
- 0xaa37, 0xaa3f,
- 0xaa4e, 0xaa4f,
- 0xaa5a, 0xaa5b,
- 0xaac3, 0xaada,
- 0xaaf7, 0xab00,
- 0xab07, 0xab08,
- 0xab0f, 0xab10,
- 0xab17, 0xab1f,
- 0xab27, 0xab27,
- 0xab2f, 0xab2f,
- 0xab66, 0xab6f,
- 0xabee, 0xabef,
- 0xabfa, 0xabff,
- 0xd7a4, 0xd7af,
- 0xd7c7, 0xd7ca,
- 0xd7fc, 0xf8ff,
- 0xfa6e, 0xfa6f,
- 0xfada, 0xfaff,
- 0xfb07, 0xfb12,
- 0xfb18, 0xfb1c,
- 0xfb37, 0xfb37,
- 0xfb3d, 0xfb3d,
- 0xfb3f, 0xfb3f,
- 0xfb42, 0xfb42,
- 0xfb45, 0xfb45,
- 0xfbc2, 0xfbd2,
- 0xfd40, 0xfd4f,
- 0xfd90, 0xfd91,
- 0xfdc8, 0xfdef,
- 0xfdfe, 0xfdff,
- 0xfe1a, 0xfe1f,
- 0xfe53, 0xfe53,
- 0xfe67, 0xfe67,
- 0xfe6c, 0xfe6f,
- 0xfe75, 0xfe75,
- 0xfefd, 0xfefe,
- 0xff00, 0xff00,
- 0xffbf, 0xffc1,
- 0xffc8, 0xffc9,
- 0xffd0, 0xffd1,
- 0xffd8, 0xffd9,
- 0xffdd, 0xffdf,
- 0xffe7, 0xffe7,
- 0xffef, 0xfff8,
- 0xfffe, 0xffff,
- 0x1000c, 0x1000c,
- 0x10027, 0x10027,
- 0x1003b, 0x1003b,
- 0x1003e, 0x1003e,
- 0x1004e, 0x1004f,
- 0x1005e, 0x1007f,
- 0x100fb, 0x100ff,
- 0x10103, 0x10106,
- 0x10134, 0x10136,
- 0x1018f, 0x1018f,
- 0x1019c, 0x1019f,
- 0x101a1, 0x101cf,
- 0x101fe, 0x1027f,
- 0x1029d, 0x1029f,
- 0x102d1, 0x102df,
- 0x102fc, 0x102ff,
- 0x10324, 0x1032c,
- 0x1034b, 0x1034f,
- 0x1037b, 0x1037f,
- 0x1039e, 0x1039e,
- 0x103c4, 0x103c7,
- 0x103d6, 0x103ff,
- 0x1049e, 0x1049f,
- 0x104aa, 0x104af,
- 0x104d4, 0x104d7,
- 0x104fc, 0x104ff,
- 0x10528, 0x1052f,
- 0x10564, 0x1056e,
- 0x10570, 0x105ff,
- 0x10737, 0x1073f,
- 0x10756, 0x1075f,
- 0x10768, 0x107ff,
- 0x10806, 0x10807,
- 0x10809, 0x10809,
- 0x10836, 0x10836,
- 0x10839, 0x1083b,
- 0x1083d, 0x1083e,
- 0x10856, 0x10856,
- 0x1089f, 0x108a6,
- 0x108b0, 0x108df,
- 0x108f3, 0x108f3,
- 0x108f6, 0x108fa,
- 0x1091c, 0x1091e,
- 0x1093a, 0x1093e,
- 0x10940, 0x1097f,
- 0x109b8, 0x109bb,
- 0x109d0, 0x109d1,
- 0x10a04, 0x10a04,
- 0x10a07, 0x10a0b,
- 0x10a14, 0x10a14,
- 0x10a18, 0x10a18,
- 0x10a34, 0x10a37,
- 0x10a3b, 0x10a3e,
- 0x10a48, 0x10a4f,
- 0x10a59, 0x10a5f,
- 0x10aa0, 0x10abf,
- 0x10ae7, 0x10aea,
- 0x10af7, 0x10aff,
- 0x10b36, 0x10b38,
- 0x10b56, 0x10b57,
- 0x10b73, 0x10b77,
- 0x10b92, 0x10b98,
- 0x10b9d, 0x10ba8,
- 0x10bb0, 0x10bff,
- 0x10c49, 0x10c7f,
- 0x10cb3, 0x10cbf,
- 0x10cf3, 0x10cf9,
- 0x10d00, 0x10e5f,
- 0x10e7f, 0x10fff,
- 0x1104e, 0x11051,
- 0x11070, 0x1107e,
- 0x110c2, 0x110cf,
- 0x110e9, 0x110ef,
- 0x110fa, 0x110ff,
- 0x11135, 0x11135,
- 0x11144, 0x1114f,
- 0x11177, 0x1117f,
- 0x111ce, 0x111cf,
- 0x111e0, 0x111e0,
- 0x111f5, 0x111ff,
- 0x11212, 0x11212,
- 0x1123f, 0x1127f,
- 0x11287, 0x11287,
- 0x11289, 0x11289,
- 0x1128e, 0x1128e,
- 0x1129e, 0x1129e,
- 0x112aa, 0x112af,
- 0x112eb, 0x112ef,
- 0x112fa, 0x112ff,
- 0x11304, 0x11304,
- 0x1130d, 0x1130e,
- 0x11311, 0x11312,
- 0x11329, 0x11329,
- 0x11331, 0x11331,
- 0x11334, 0x11334,
- 0x1133a, 0x1133b,
- 0x11345, 0x11346,
- 0x11349, 0x1134a,
- 0x1134e, 0x1134f,
- 0x11351, 0x11356,
- 0x11358, 0x1135c,
- 0x11364, 0x11365,
- 0x1136d, 0x1136f,
- 0x11375, 0x113ff,
- 0x1145a, 0x1145a,
- 0x1145c, 0x1145c,
- 0x1145e, 0x1147f,
- 0x114c8, 0x114cf,
- 0x114da, 0x1157f,
- 0x115b6, 0x115b7,
- 0x115de, 0x115ff,
- 0x11645, 0x1164f,
- 0x1165a, 0x1165f,
- 0x1166d, 0x1167f,
- 0x116b8, 0x116bf,
- 0x116ca, 0x116ff,
- 0x1171a, 0x1171c,
- 0x1172c, 0x1172f,
- 0x11740, 0x1189f,
- 0x118f3, 0x118fe,
- 0x11900, 0x119ff,
- 0x11a48, 0x11a4f,
- 0x11a84, 0x11a85,
- 0x11a9d, 0x11a9d,
- 0x11aa3, 0x11abf,
- 0x11af9, 0x11bff,
- 0x11c09, 0x11c09,
- 0x11c37, 0x11c37,
- 0x11c46, 0x11c4f,
- 0x11c6d, 0x11c6f,
- 0x11c90, 0x11c91,
- 0x11ca8, 0x11ca8,
- 0x11cb7, 0x11cff,
- 0x11d07, 0x11d07,
- 0x11d0a, 0x11d0a,
- 0x11d37, 0x11d39,
- 0x11d3b, 0x11d3b,
- 0x11d3e, 0x11d3e,
- 0x11d48, 0x11d4f,
- 0x11d5a, 0x11fff,
- 0x1239a, 0x123ff,
- 0x1246f, 0x1246f,
- 0x12475, 0x1247f,
- 0x12544, 0x12fff,
- 0x1342f, 0x143ff,
- 0x14647, 0x167ff,
- 0x16a39, 0x16a3f,
- 0x16a5f, 0x16a5f,
- 0x16a6a, 0x16a6d,
- 0x16a70, 0x16acf,
- 0x16aee, 0x16aef,
- 0x16af6, 0x16aff,
- 0x16b46, 0x16b4f,
- 0x16b5a, 0x16b5a,
- 0x16b62, 0x16b62,
- 0x16b78, 0x16b7c,
- 0x16b90, 0x16eff,
- 0x16f45, 0x16f4f,
- 0x16f7f, 0x16f8e,
- 0x16fa0, 0x16fdf,
- 0x16fe2, 0x16fff,
- 0x187ed, 0x187ff,
- 0x18af3, 0x1afff,
- 0x1b11f, 0x1b16f,
- 0x1b2fc, 0x1bbff,
- 0x1bc6b, 0x1bc6f,
- 0x1bc7d, 0x1bc7f,
- 0x1bc89, 0x1bc8f,
- 0x1bc9a, 0x1bc9b,
- 0x1bca4, 0x1cfff,
- 0x1d0f6, 0x1d0ff,
- 0x1d127, 0x1d128,
- 0x1d1e9, 0x1d1ff,
- 0x1d246, 0x1d2ff,
- 0x1d357, 0x1d35f,
- 0x1d372, 0x1d3ff,
- 0x1d455, 0x1d455,
- 0x1d49d, 0x1d49d,
- 0x1d4a0, 0x1d4a1,
- 0x1d4a3, 0x1d4a4,
- 0x1d4a7, 0x1d4a8,
- 0x1d4ad, 0x1d4ad,
- 0x1d4ba, 0x1d4ba,
- 0x1d4bc, 0x1d4bc,
- 0x1d4c4, 0x1d4c4,
- 0x1d506, 0x1d506,
- 0x1d50b, 0x1d50c,
- 0x1d515, 0x1d515,
- 0x1d51d, 0x1d51d,
- 0x1d53a, 0x1d53a,
- 0x1d53f, 0x1d53f,
- 0x1d545, 0x1d545,
- 0x1d547, 0x1d549,
- 0x1d551, 0x1d551,
- 0x1d6a6, 0x1d6a7,
- 0x1d7cc, 0x1d7cd,
- 0x1da8c, 0x1da9a,
- 0x1daa0, 0x1daa0,
- 0x1dab0, 0x1dfff,
- 0x1e007, 0x1e007,
- 0x1e019, 0x1e01a,
- 0x1e022, 0x1e022,
- 0x1e025, 0x1e025,
- 0x1e02b, 0x1e7ff,
- 0x1e8c5, 0x1e8c6,
- 0x1e8d7, 0x1e8ff,
- 0x1e94b, 0x1e94f,
- 0x1e95a, 0x1e95d,
- 0x1e960, 0x1edff,
- 0x1ee04, 0x1ee04,
- 0x1ee20, 0x1ee20,
- 0x1ee23, 0x1ee23,
- 0x1ee25, 0x1ee26,
- 0x1ee28, 0x1ee28,
- 0x1ee33, 0x1ee33,
- 0x1ee38, 0x1ee38,
- 0x1ee3a, 0x1ee3a,
- 0x1ee3c, 0x1ee41,
- 0x1ee43, 0x1ee46,
- 0x1ee48, 0x1ee48,
- 0x1ee4a, 0x1ee4a,
- 0x1ee4c, 0x1ee4c,
- 0x1ee50, 0x1ee50,
- 0x1ee53, 0x1ee53,
- 0x1ee55, 0x1ee56,
- 0x1ee58, 0x1ee58,
- 0x1ee5a, 0x1ee5a,
- 0x1ee5c, 0x1ee5c,
- 0x1ee5e, 0x1ee5e,
- 0x1ee60, 0x1ee60,
- 0x1ee63, 0x1ee63,
- 0x1ee65, 0x1ee66,
- 0x1ee6b, 0x1ee6b,
- 0x1ee73, 0x1ee73,
- 0x1ee78, 0x1ee78,
- 0x1ee7d, 0x1ee7d,
- 0x1ee7f, 0x1ee7f,
- 0x1ee8a, 0x1ee8a,
- 0x1ee9c, 0x1eea0,
- 0x1eea4, 0x1eea4,
- 0x1eeaa, 0x1eeaa,
- 0x1eebc, 0x1eeef,
- 0x1eef2, 0x1efff,
- 0x1f02c, 0x1f02f,
- 0x1f094, 0x1f09f,
- 0x1f0af, 0x1f0b0,
- 0x1f0c0, 0x1f0c0,
- 0x1f0d0, 0x1f0d0,
- 0x1f0f6, 0x1f0ff,
- 0x1f10d, 0x1f10f,
- 0x1f12f, 0x1f12f,
- 0x1f16c, 0x1f16f,
- 0x1f1ad, 0x1f1e5,
- 0x1f203, 0x1f20f,
- 0x1f23c, 0x1f23f,
- 0x1f249, 0x1f24f,
- 0x1f252, 0x1f25f,
- 0x1f266, 0x1f2ff,
- 0x1f6d5, 0x1f6df,
- 0x1f6ed, 0x1f6ef,
- 0x1f6f9, 0x1f6ff,
- 0x1f774, 0x1f77f,
- 0x1f7d5, 0x1f7ff,
- 0x1f80c, 0x1f80f,
- 0x1f848, 0x1f84f,
- 0x1f85a, 0x1f85f,
- 0x1f888, 0x1f88f,
- 0x1f8ae, 0x1f8ff,
- 0x1f90c, 0x1f90f,
- 0x1f93f, 0x1f93f,
- 0x1f94d, 0x1f94f,
- 0x1f96c, 0x1f97f,
- 0x1f998, 0x1f9bf,
- 0x1f9c1, 0x1f9cf,
- 0x1f9e7, 0x1ffff,
- 0x2a6d7, 0x2a6ff,
- 0x2b735, 0x2b73f,
- 0x2b81e, 0x2b81f,
- 0x2cea2, 0x2ceaf,
- 0x2ebe1, 0x2f7ff,
- 0x2fa1e, 0xe0000,
- 0xe0002, 0xe001f,
- 0xe0080, 0xe00ff,
- 0xe01f0, 0x10ffff,
-}; /* CR_Unknown */
-
-#ifdef USE_UNICODE_AGE_PROPERTIES
-/* 'Age_1_1': Derived Age 1.1 */
-static const OnigCodePoint CR_Age_1_1[] = {
- 288,
- 0x0000, 0x01f5,
- 0x01fa, 0x0217,
- 0x0250, 0x02a8,
- 0x02b0, 0x02de,
- 0x02e0, 0x02e9,
- 0x0300, 0x0345,
- 0x0360, 0x0361,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03d6,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03f3,
- 0x0401, 0x040c,
- 0x040e, 0x044f,
- 0x0451, 0x045c,
- 0x045e, 0x0486,
- 0x0490, 0x04c4,
- 0x04c7, 0x04c8,
- 0x04cb, 0x04cc,
- 0x04d0, 0x04eb,
- 0x04ee, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x0589,
- 0x05b0, 0x05b9,
- 0x05bb, 0x05c3,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0652,
- 0x0660, 0x066d,
- 0x0670, 0x06b7,
- 0x06ba, 0x06be,
- 0x06c0, 0x06ce,
- 0x06d0, 0x06ed,
- 0x06f0, 0x06f9,
- 0x0901, 0x0903,
- 0x0905, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09bc,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a02, 0x0a02,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8b,
- 0x0a8d, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae0,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b36, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b70,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f6,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1e00, 0x1e9a,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x202e,
- 0x2030, 0x2046,
- 0x206a, 0x2070,
- 0x2074, 0x208e,
- 0x20a0, 0x20aa,
- 0x20d0, 0x20e1,
- 0x2100, 0x2138,
- 0x2153, 0x2182,
- 0x2190, 0x21ea,
- 0x2200, 0x22f1,
- 0x2300, 0x2300,
- 0x2302, 0x237a,
- 0x2400, 0x2424,
- 0x2440, 0x244a,
- 0x2460, 0x24ea,
- 0x2500, 0x2595,
- 0x25a0, 0x25ef,
- 0x2600, 0x2613,
- 0x261a, 0x266f,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2767,
- 0x2776, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x3000, 0x3037,
- 0x303f, 0x303f,
- 0x3041, 0x3094,
- 0x3099, 0x309e,
- 0x30a1, 0x30fe,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x319f,
- 0x3200, 0x321c,
- 0x3220, 0x3243,
- 0x3260, 0x327b,
- 0x327f, 0x32b0,
- 0x32c0, 0x32cb,
- 0x32d0, 0x32fe,
- 0x3300, 0x3376,
- 0x337b, 0x33dd,
- 0x33e0, 0x33fe,
- 0x4e00, 0x9fa5,
- 0xe000, 0xfa2d,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1e, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe44,
- 0xfe49, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe72,
- 0xfe74, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xff5e,
- 0xff61, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfffd, 0xffff,
-}; /* CR_Age_1_1 */
-
-/* 'Age_2_0': Derived Age 2.0 */
-static const OnigCodePoint CR_Age_2_0[] = {
- 312,
- 0x0000, 0x01f5,
- 0x01fa, 0x0217,
- 0x0250, 0x02a8,
- 0x02b0, 0x02de,
- 0x02e0, 0x02e9,
- 0x0300, 0x0345,
- 0x0360, 0x0361,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03d6,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03f3,
- 0x0401, 0x040c,
- 0x040e, 0x044f,
- 0x0451, 0x045c,
- 0x045e, 0x0486,
- 0x0490, 0x04c4,
- 0x04c7, 0x04c8,
- 0x04cb, 0x04cc,
- 0x04d0, 0x04eb,
- 0x04ee, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x0589,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0652,
- 0x0660, 0x066d,
- 0x0670, 0x06b7,
- 0x06ba, 0x06be,
- 0x06c0, 0x06ce,
- 0x06d0, 0x06ed,
- 0x06f0, 0x06f9,
- 0x0901, 0x0903,
- 0x0905, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09bc,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a02, 0x0a02,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8b,
- 0x0a8d, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae0,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b36, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b70,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f69,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f95,
- 0x0f97, 0x0f97,
- 0x0f99, 0x0fad,
- 0x0fb1, 0x0fb7,
- 0x0fb9, 0x0fb9,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f6,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x202e,
- 0x2030, 0x2046,
- 0x206a, 0x2070,
- 0x2074, 0x208e,
- 0x20a0, 0x20ab,
- 0x20d0, 0x20e1,
- 0x2100, 0x2138,
- 0x2153, 0x2182,
- 0x2190, 0x21ea,
- 0x2200, 0x22f1,
- 0x2300, 0x2300,
- 0x2302, 0x237a,
- 0x2400, 0x2424,
- 0x2440, 0x244a,
- 0x2460, 0x24ea,
- 0x2500, 0x2595,
- 0x25a0, 0x25ef,
- 0x2600, 0x2613,
- 0x261a, 0x266f,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2767,
- 0x2776, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x3000, 0x3037,
- 0x303f, 0x303f,
- 0x3041, 0x3094,
- 0x3099, 0x309e,
- 0x30a1, 0x30fe,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x319f,
- 0x3200, 0x321c,
- 0x3220, 0x3243,
- 0x3260, 0x327b,
- 0x327f, 0x32b0,
- 0x32c0, 0x32cb,
- 0x32d0, 0x32fe,
- 0x3300, 0x3376,
- 0x337b, 0x33dd,
- 0x33e0, 0x33fe,
- 0x4e00, 0x9fa5,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1e, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe44,
- 0xfe49, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe72,
- 0xfe74, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xff5e,
- 0xff61, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfffd, 0xffff,
- 0x1fffe, 0x1ffff,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_2_0 */
-
-/* 'Age_2_1': Derived Age 2.1 */
-static const OnigCodePoint CR_Age_2_1[] = {
- 312,
- 0x0000, 0x01f5,
- 0x01fa, 0x0217,
- 0x0250, 0x02a8,
- 0x02b0, 0x02de,
- 0x02e0, 0x02e9,
- 0x0300, 0x0345,
- 0x0360, 0x0361,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03d6,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03f3,
- 0x0401, 0x040c,
- 0x040e, 0x044f,
- 0x0451, 0x045c,
- 0x045e, 0x0486,
- 0x0490, 0x04c4,
- 0x04c7, 0x04c8,
- 0x04cb, 0x04cc,
- 0x04d0, 0x04eb,
- 0x04ee, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x0589,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0652,
- 0x0660, 0x066d,
- 0x0670, 0x06b7,
- 0x06ba, 0x06be,
- 0x06c0, 0x06ce,
- 0x06d0, 0x06ed,
- 0x06f0, 0x06f9,
- 0x0901, 0x0903,
- 0x0905, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09bc,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a02, 0x0a02,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8b,
- 0x0a8d, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae0,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b36, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b70,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f69,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f95,
- 0x0f97, 0x0f97,
- 0x0f99, 0x0fad,
- 0x0fb1, 0x0fb7,
- 0x0fb9, 0x0fb9,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f6,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x202e,
- 0x2030, 0x2046,
- 0x206a, 0x2070,
- 0x2074, 0x208e,
- 0x20a0, 0x20ac,
- 0x20d0, 0x20e1,
- 0x2100, 0x2138,
- 0x2153, 0x2182,
- 0x2190, 0x21ea,
- 0x2200, 0x22f1,
- 0x2300, 0x2300,
- 0x2302, 0x237a,
- 0x2400, 0x2424,
- 0x2440, 0x244a,
- 0x2460, 0x24ea,
- 0x2500, 0x2595,
- 0x25a0, 0x25ef,
- 0x2600, 0x2613,
- 0x261a, 0x266f,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2767,
- 0x2776, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x3000, 0x3037,
- 0x303f, 0x303f,
- 0x3041, 0x3094,
- 0x3099, 0x309e,
- 0x30a1, 0x30fe,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x319f,
- 0x3200, 0x321c,
- 0x3220, 0x3243,
- 0x3260, 0x327b,
- 0x327f, 0x32b0,
- 0x32c0, 0x32cb,
- 0x32d0, 0x32fe,
- 0x3300, 0x3376,
- 0x337b, 0x33dd,
- 0x33e0, 0x33fe,
- 0x4e00, 0x9fa5,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1e, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe44,
- 0xfe49, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe72,
- 0xfe74, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xff5e,
- 0xff61, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfffc, 0xffff,
- 0x1fffe, 0x1ffff,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_2_1 */
-
-/* 'Age_3_0': Derived Age 3.0 */
-static const OnigCodePoint CR_Age_3_0[] = {
- 369,
- 0x0000, 0x021f,
- 0x0222, 0x0233,
- 0x0250, 0x02ad,
- 0x02b0, 0x02ee,
- 0x0300, 0x034e,
- 0x0360, 0x0362,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03d7,
- 0x03da, 0x03f3,
- 0x0400, 0x0486,
- 0x0488, 0x0489,
- 0x048c, 0x04c4,
- 0x04c7, 0x04c8,
- 0x04cb, 0x04cc,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0655,
- 0x0660, 0x066d,
- 0x0670, 0x06ed,
- 0x06f0, 0x06fe,
- 0x0700, 0x070d,
- 0x070f, 0x072c,
- 0x0730, 0x074a,
- 0x0780, 0x07b0,
- 0x0901, 0x0903,
- 0x0905, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09bc,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a02, 0x0a02,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8b,
- 0x0a8d, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae0,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b36, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b70,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f6,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1780, 0x17dc,
- 0x17e0, 0x17e9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2046,
- 0x2048, 0x204d,
- 0x206a, 0x2070,
- 0x2074, 0x208e,
- 0x20a0, 0x20af,
- 0x20d0, 0x20e3,
- 0x2100, 0x213a,
- 0x2153, 0x2183,
- 0x2190, 0x21f3,
- 0x2200, 0x22f1,
- 0x2300, 0x237b,
- 0x237d, 0x239a,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x24ea,
- 0x2500, 0x2595,
- 0x25a0, 0x25f7,
- 0x2600, 0x2613,
- 0x2619, 0x2671,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2767,
- 0x2776, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x2800, 0x28ff,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303a,
- 0x303e, 0x303f,
- 0x3041, 0x3094,
- 0x3099, 0x309e,
- 0x30a1, 0x30fe,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x3200, 0x321c,
- 0x3220, 0x3243,
- 0x3260, 0x327b,
- 0x327f, 0x32b0,
- 0x32c0, 0x32cb,
- 0x32d0, 0x32fe,
- 0x3300, 0x3376,
- 0x337b, 0x33dd,
- 0x33e0, 0x33fe,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4a1,
- 0xa4a4, 0xa4b3,
- 0xa4b5, 0xa4c0,
- 0xa4c2, 0xa4c4,
- 0xa4c6, 0xa4c6,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe44,
- 0xfe49, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe72,
- 0xfe74, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xff5e,
- 0xff61, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xffff,
- 0x1fffe, 0x1ffff,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_3_0 */
-
-/* 'Age_3_1': Derived Age 3.1 */
-static const OnigCodePoint CR_Age_3_1[] = {
- 402,
- 0x0000, 0x021f,
- 0x0222, 0x0233,
- 0x0250, 0x02ad,
- 0x02b0, 0x02ee,
- 0x0300, 0x034e,
- 0x0360, 0x0362,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03d7,
- 0x03da, 0x03f5,
- 0x0400, 0x0486,
- 0x0488, 0x0489,
- 0x048c, 0x04c4,
- 0x04c7, 0x04c8,
- 0x04cb, 0x04cc,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0655,
- 0x0660, 0x066d,
- 0x0670, 0x06ed,
- 0x06f0, 0x06fe,
- 0x0700, 0x070d,
- 0x070f, 0x072c,
- 0x0730, 0x074a,
- 0x0780, 0x07b0,
- 0x0901, 0x0903,
- 0x0905, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09bc,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a02, 0x0a02,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8b,
- 0x0a8d, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae0,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b36, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b70,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f6,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1780, 0x17dc,
- 0x17e0, 0x17e9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2046,
- 0x2048, 0x204d,
- 0x206a, 0x2070,
- 0x2074, 0x208e,
- 0x20a0, 0x20af,
- 0x20d0, 0x20e3,
- 0x2100, 0x213a,
- 0x2153, 0x2183,
- 0x2190, 0x21f3,
- 0x2200, 0x22f1,
- 0x2300, 0x237b,
- 0x237d, 0x239a,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x24ea,
- 0x2500, 0x2595,
- 0x25a0, 0x25f7,
- 0x2600, 0x2613,
- 0x2619, 0x2671,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2767,
- 0x2776, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x2800, 0x28ff,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303a,
- 0x303e, 0x303f,
- 0x3041, 0x3094,
- 0x3099, 0x309e,
- 0x30a1, 0x30fe,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x3200, 0x321c,
- 0x3220, 0x3243,
- 0x3260, 0x327b,
- 0x327f, 0x32b0,
- 0x32c0, 0x32cb,
- 0x32d0, 0x32fe,
- 0x3300, 0x3376,
- 0x337b, 0x33dd,
- 0x33e0, 0x33fe,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4a1,
- 0xa4a4, 0xa4b3,
- 0xa4b5, 0xa4c0,
- 0xa4c2, 0xa4c4,
- 0xa4c6, 0xa4c6,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfb,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe44,
- 0xfe49, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe72,
- 0xfe74, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xff5e,
- 0xff61, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xffff,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10400, 0x10425,
- 0x10428, 0x1044d,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d12a, 0x1d1dd,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c0,
- 0x1d4c2, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x1fffe, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_3_1 */
-
-/* 'Age_3_2': Derived Age 3.2 */
-static const OnigCodePoint CR_Age_3_2[] = {
- 397,
- 0x0000, 0x0220,
- 0x0222, 0x0233,
- 0x0250, 0x02ad,
- 0x02b0, 0x02ee,
- 0x0300, 0x034f,
- 0x0360, 0x036f,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03f6,
- 0x0400, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x060c, 0x060c,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0655,
- 0x0660, 0x06ed,
- 0x06f0, 0x06fe,
- 0x0700, 0x070d,
- 0x070f, 0x072c,
- 0x0730, 0x074a,
- 0x0780, 0x07b1,
- 0x0901, 0x0903,
- 0x0905, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09bc,
- 0x09be, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a02, 0x0a02,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8b,
- 0x0a8d, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae0,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b36, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b70,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbe, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dc,
- 0x17e0, 0x17e9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2052,
- 0x2057, 0x2057,
- 0x205f, 0x2063,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x20a0, 0x20b1,
- 0x20d0, 0x20ea,
- 0x2100, 0x213a,
- 0x213d, 0x214b,
- 0x2153, 0x2183,
- 0x2190, 0x23ce,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x24fe,
- 0x2500, 0x2613,
- 0x2616, 0x2617,
- 0x2619, 0x267d,
- 0x2680, 0x2689,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27d0, 0x27eb,
- 0x27f0, 0x2aff,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31f0, 0x321c,
- 0x3220, 0x3243,
- 0x3251, 0x327b,
- 0x327f, 0x32cb,
- 0x32d0, 0x32fe,
- 0x3300, 0x3376,
- 0x337b, 0x33dd,
- 0x33e0, 0x33fe,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfc,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe46,
- 0xfe49, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xffff,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10400, 0x10425,
- 0x10428, 0x1044d,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d12a, 0x1d1dd,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c0,
- 0x1d4c2, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x1fffe, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_3_2 */
-
-/* 'Age_4_0': Derived Age 4.0 */
-static const OnigCodePoint CR_Age_4_0[] = {
- 412,
- 0x0000, 0x0236,
- 0x0250, 0x0357,
- 0x035d, 0x036f,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03fb,
- 0x0400, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x060c, 0x0615,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0658,
- 0x0660, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x074f,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x19e0, 0x19ff,
- 0x1d00, 0x1d6b,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2054,
- 0x2057, 0x2057,
- 0x205f, 0x2063,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x20a0, 0x20b1,
- 0x20d0, 0x20ea,
- 0x2100, 0x213b,
- 0x213d, 0x214b,
- 0x2153, 0x2183,
- 0x2190, 0x23d0,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2617,
- 0x2619, 0x267d,
- 0x2680, 0x2691,
- 0x26a0, 0x26a1,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27d0, 0x27eb,
- 0x27f0, 0x2b0d,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31f0, 0x321e,
- 0x3220, 0x3243,
- 0x3250, 0x327d,
- 0x327f, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fa5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1013f,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x1039f,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d12a, 0x1d1dd,
- 0x1d300, 0x1d356,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x1fffe, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_4_0 */
-
-/* 'Age_4_1': Derived Age 4.1 */
-static const OnigCodePoint CR_Age_4_1[] = {
- 430,
- 0x0000, 0x0241,
- 0x0250, 0x036f,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05b9,
- 0x05bb, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x060b, 0x0615,
- 0x061b, 0x061b,
- 0x061e, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x065e,
- 0x0660, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x076d,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x097d, 0x097d,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fd1,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10fc,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135f, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19a9,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19d9,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a1f,
- 0x1d00, 0x1dc3,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2063,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x2094,
- 0x20a0, 0x20b5,
- 0x20d0, 0x20eb,
- 0x2100, 0x214c,
- 0x2153, 0x2183,
- 0x2190, 0x23db,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x269c,
- 0x26a0, 0x26b1,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27c0, 0x27c6,
- 0x27d0, 0x27eb,
- 0x27f0, 0x2b13,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c80, 0x2cea,
- 0x2cf9, 0x2d25,
- 0x2d30, 0x2d65,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2e00, 0x2e17,
- 0x2e1c, 0x2e1d,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31c0, 0x31cf,
- 0x31f0, 0x321e,
- 0x3220, 0x3243,
- 0x3250, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fbb,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa700, 0xa716,
- 0xa800, 0xa82b,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d12a, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x1fffe, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_4_1 */
-
-/* 'Age_5_0': Derived Age 5.0 */
-static const OnigCodePoint CR_Age_5_0[] = {
- 440,
- 0x0000, 0x036f,
- 0x0374, 0x0375,
- 0x037a, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x0486,
- 0x0488, 0x0513,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x060b, 0x0615,
- 0x061b, 0x061b,
- 0x061e, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x065e,
- 0x0660, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x076d,
- 0x0780, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x097b, 0x097f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fd1,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10fc,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135f, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19a9,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19d9,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a1f,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1d00, 0x1dca,
- 0x1dfe, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2063,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x2094,
- 0x20a0, 0x20b5,
- 0x20d0, 0x20ef,
- 0x2100, 0x214e,
- 0x2153, 0x2184,
- 0x2190, 0x23e7,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x269c,
- 0x26a0, 0x26b2,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27c0, 0x27ca,
- 0x27d0, 0x27eb,
- 0x27f0, 0x2b1a,
- 0x2b20, 0x2b23,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2c6c,
- 0x2c74, 0x2c77,
- 0x2c80, 0x2cea,
- 0x2cf9, 0x2d25,
- 0x2d30, 0x2d65,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2e00, 0x2e17,
- 0x2e1c, 0x2e1d,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31c0, 0x31cf,
- 0x31f0, 0x321e,
- 0x3220, 0x3243,
- 0x3250, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fbb,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa700, 0xa71a,
- 0xa720, 0xa721,
- 0xa800, 0xa82b,
- 0xa840, 0xa877,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x10900, 0x10919,
- 0x1091f, 0x1091f,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x12000, 0x1236e,
- 0x12400, 0x12462,
- 0x12470, 0x12473,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d12a, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1fffe, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_5_0 */
-
-/* 'Age_5_1': Derived Age 5.1 */
-static const OnigCodePoint CR_Age_5_1[] = {
- 455,
- 0x0000, 0x0377,
- 0x037a, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x0523,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x0606, 0x061b,
- 0x061e, 0x061f,
- 0x0621, 0x065e,
- 0x0660, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0972,
- 0x097b, 0x097f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c59,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fd4,
- 0x1000, 0x1099,
- 0x109e, 0x10c5,
- 0x10d0, 0x10fc,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135f, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19a9,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19d9,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a1f,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1baa,
- 0x1bae, 0x1bb9,
- 0x1c00, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1d00, 0x1de6,
- 0x1dfe, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x2094,
- 0x20a0, 0x20b5,
- 0x20d0, 0x20f0,
- 0x2100, 0x214f,
- 0x2153, 0x2188,
- 0x2190, 0x23e7,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x269d,
- 0x26a0, 0x26bc,
- 0x26c0, 0x26c3,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27c0, 0x27ca,
- 0x27cc, 0x27cc,
- 0x27d0, 0x2b4c,
- 0x2b50, 0x2b54,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2c6f,
- 0x2c71, 0x2c7d,
- 0x2c80, 0x2cea,
- 0x2cf9, 0x2d25,
- 0x2d30, 0x2d65,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e30,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x3243,
- 0x3250, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fc3,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa500, 0xa62b,
- 0xa640, 0xa65f,
- 0xa662, 0xa673,
- 0xa67c, 0xa697,
- 0xa700, 0xa78c,
- 0xa7fb, 0xa82b,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa900, 0xa953,
- 0xa95f, 0xa95f,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa5f,
- 0xac00, 0xd7a3,
- 0xd800, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe26,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10190, 0x1019b,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x10900, 0x10919,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x12000, 0x1236e,
- 0x12400, 0x12462,
- 0x12470, 0x12473,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1fffe, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_5_1 */
-
-/* 'Age_5_2': Derived Age 5.2 */
-static const OnigCodePoint CR_Age_5_2[] = {
- 495,
- 0x0000, 0x0377,
- 0x037a, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x0525,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x0606, 0x061b,
- 0x061e, 0x061f,
- 0x0621, 0x065e,
- 0x0660, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0900, 0x0939,
- 0x093c, 0x094e,
- 0x0950, 0x0955,
- 0x0958, 0x0972,
- 0x0979, 0x097f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c59,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fd8,
- 0x1000, 0x10c5,
- 0x10d0, 0x10fc,
- 0x1100, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135f, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1400, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1baa,
- 0x1bae, 0x1bb9,
- 0x1c00, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1cd0, 0x1cf2,
- 0x1d00, 0x1de6,
- 0x1dfd, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x2094,
- 0x20a0, 0x20b8,
- 0x20d0, 0x20f0,
- 0x2100, 0x2189,
- 0x2190, 0x23e8,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x26cd,
- 0x26cf, 0x26e1,
- 0x26e3, 0x26e3,
- 0x26e8, 0x26ff,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27c0, 0x27ca,
- 0x27cc, 0x27cc,
- 0x27d0, 0x2b4c,
- 0x2b50, 0x2b59,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf1,
- 0x2cf9, 0x2d25,
- 0x2d30, 0x2d65,
- 0x2d6f, 0x2d6f,
- 0x2d80, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e31,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fcb,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa65f,
- 0xa662, 0xa673,
- 0xa67c, 0xa697,
- 0xa6a0, 0xa6f7,
- 0xa700, 0xa78c,
- 0xa7fb, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fb,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9df,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa7b,
- 0xaa80, 0xaac2,
- 0xaadb, 0xaadf,
- 0xabc0, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa2d,
- 0xfa30, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe26,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10190, 0x1019b,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1085f,
- 0x10900, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a7f,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b7f,
- 0x10c00, 0x10c48,
- 0x10e60, 0x10e7e,
- 0x11080, 0x110c1,
- 0x12000, 0x1236e,
- 0x12400, 0x12462,
- 0x12470, 0x12473,
- 0x13000, 0x1342e,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f100, 0x1f10a,
- 0x1f110, 0x1f12e,
- 0x1f131, 0x1f131,
- 0x1f13d, 0x1f13d,
- 0x1f13f, 0x1f13f,
- 0x1f142, 0x1f142,
- 0x1f146, 0x1f146,
- 0x1f14a, 0x1f14e,
- 0x1f157, 0x1f157,
- 0x1f15f, 0x1f15f,
- 0x1f179, 0x1f179,
- 0x1f17b, 0x1f17c,
- 0x1f17f, 0x1f17f,
- 0x1f18a, 0x1f18d,
- 0x1f190, 0x1f190,
- 0x1f200, 0x1f200,
- 0x1f210, 0x1f231,
- 0x1f240, 0x1f248,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_5_2 */
-
-/* 'Age_6_0': Derived Age 6.0 */
-static const OnigCodePoint CR_Age_6_0[] = {
- 511,
- 0x0000, 0x0377,
- 0x037a, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x0527,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x0606, 0x061b,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x0900, 0x0977,
- 0x0979, 0x097f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c59,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10d0, 0x10fc,
- 0x1100, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1400, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1baa,
- 0x1bae, 0x1bb9,
- 0x1bc0, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1cd0, 0x1cf2,
- 0x1d00, 0x1de6,
- 0x1dfc, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20b9,
- 0x20d0, 0x20f0,
- 0x2100, 0x2189,
- 0x2190, 0x23f3,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x26ff,
- 0x2701, 0x27ca,
- 0x27cc, 0x27cc,
- 0x27ce, 0x2b4c,
- 0x2b50, 0x2b59,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf1,
- 0x2cf9, 0x2d25,
- 0x2d30, 0x2d65,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e31,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fcb,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa673,
- 0xa67c, 0xa697,
- 0xa6a0, 0xa6f7,
- 0xa700, 0xa78e,
- 0xa790, 0xa791,
- 0xa7a0, 0xa7a9,
- 0xa7fa, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fb,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9df,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa7b,
- 0xaa80, 0xaac2,
- 0xaadb, 0xaadf,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xabc0, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa2d,
- 0xfa30, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe26,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10190, 0x1019b,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1085f,
- 0x10900, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a7f,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b7f,
- 0x10c00, 0x10c48,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x11080, 0x110c1,
- 0x12000, 0x1236e,
- 0x12400, 0x12462,
- 0x12470, 0x12473,
- 0x13000, 0x1342e,
- 0x16800, 0x16a38,
- 0x1b000, 0x1b001,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0be,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0df,
- 0x1f100, 0x1f10a,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f169,
- 0x1f170, 0x1f19a,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23a,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f300, 0x1f320,
- 0x1f330, 0x1f335,
- 0x1f337, 0x1f37c,
- 0x1f380, 0x1f393,
- 0x1f3a0, 0x1f3c4,
- 0x1f3c6, 0x1f3ca,
- 0x1f3e0, 0x1f3f0,
- 0x1f400, 0x1f43e,
- 0x1f440, 0x1f440,
- 0x1f442, 0x1f4f7,
- 0x1f4f9, 0x1f4fc,
- 0x1f500, 0x1f53d,
- 0x1f550, 0x1f567,
- 0x1f5fb, 0x1f5ff,
- 0x1f601, 0x1f610,
- 0x1f612, 0x1f614,
- 0x1f616, 0x1f616,
- 0x1f618, 0x1f618,
- 0x1f61a, 0x1f61a,
- 0x1f61c, 0x1f61e,
- 0x1f620, 0x1f625,
- 0x1f628, 0x1f62b,
- 0x1f62d, 0x1f62d,
- 0x1f630, 0x1f633,
- 0x1f635, 0x1f640,
- 0x1f645, 0x1f64f,
- 0x1f680, 0x1f6c5,
- 0x1f700, 0x1f773,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_6_0 */
-
-/* 'Age_6_1': Derived Age 6.1 */
-static const OnigCodePoint CR_Age_6_1[] = {
- 549,
- 0x0000, 0x0377,
- 0x037a, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x0527,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058f, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0604,
- 0x0606, 0x061b,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x08a0, 0x08a0,
- 0x08a2, 0x08ac,
- 0x08e4, 0x08fe,
- 0x0900, 0x0977,
- 0x0979, 0x097f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c59,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1400, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf6,
- 0x1d00, 0x1de6,
- 0x1dfc, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20b9,
- 0x20d0, 0x20f0,
- 0x2100, 0x2189,
- 0x2190, 0x23f3,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x26ff,
- 0x2701, 0x2b4c,
- 0x2b50, 0x2b59,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e3b,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fcc,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa697,
- 0xa69f, 0xa6f7,
- 0xa700, 0xa78e,
- 0xa790, 0xa793,
- 0xa7a0, 0xa7aa,
- 0xa7f8, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fb,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9df,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa7b,
- 0xaa80, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xabc0, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe26,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10190, 0x1019b,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1085f,
- 0x10900, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a7f,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b7f,
- 0x10c00, 0x10c48,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x11080, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11180, 0x111c8,
- 0x111d0, 0x111d9,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x12000, 0x1236e,
- 0x12400, 0x12462,
- 0x12470, 0x12473,
- 0x13000, 0x1342e,
- 0x16800, 0x16a38,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x1b000, 0x1b001,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0be,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0df,
- 0x1f100, 0x1f10a,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f19a,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23a,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f300, 0x1f320,
- 0x1f330, 0x1f335,
- 0x1f337, 0x1f37c,
- 0x1f380, 0x1f393,
- 0x1f3a0, 0x1f3c4,
- 0x1f3c6, 0x1f3ca,
- 0x1f3e0, 0x1f3f0,
- 0x1f400, 0x1f43e,
- 0x1f440, 0x1f440,
- 0x1f442, 0x1f4f7,
- 0x1f4f9, 0x1f4fc,
- 0x1f500, 0x1f53d,
- 0x1f540, 0x1f543,
- 0x1f550, 0x1f567,
- 0x1f5fb, 0x1f640,
- 0x1f645, 0x1f64f,
- 0x1f680, 0x1f6c5,
- 0x1f700, 0x1f773,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_6_1 */
-
-/* 'Age_6_2': Derived Age 6.2 */
-static const OnigCodePoint CR_Age_6_2[] = {
- 549,
- 0x0000, 0x0377,
- 0x037a, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x0527,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058f, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0604,
- 0x0606, 0x061b,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x08a0, 0x08a0,
- 0x08a2, 0x08ac,
- 0x08e4, 0x08fe,
- 0x0900, 0x0977,
- 0x0979, 0x097f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c59,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1400, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf6,
- 0x1d00, 0x1de6,
- 0x1dfc, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20ba,
- 0x20d0, 0x20f0,
- 0x2100, 0x2189,
- 0x2190, 0x23f3,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x26ff,
- 0x2701, 0x2b4c,
- 0x2b50, 0x2b59,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e3b,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fcc,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa697,
- 0xa69f, 0xa6f7,
- 0xa700, 0xa78e,
- 0xa790, 0xa793,
- 0xa7a0, 0xa7aa,
- 0xa7f8, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fb,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9df,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa7b,
- 0xaa80, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xabc0, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe26,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10190, 0x1019b,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1085f,
- 0x10900, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a7f,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b7f,
- 0x10c00, 0x10c48,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x11080, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11180, 0x111c8,
- 0x111d0, 0x111d9,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x12000, 0x1236e,
- 0x12400, 0x12462,
- 0x12470, 0x12473,
- 0x13000, 0x1342e,
- 0x16800, 0x16a38,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x1b000, 0x1b001,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0be,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0df,
- 0x1f100, 0x1f10a,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f19a,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23a,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f300, 0x1f320,
- 0x1f330, 0x1f335,
- 0x1f337, 0x1f37c,
- 0x1f380, 0x1f393,
- 0x1f3a0, 0x1f3c4,
- 0x1f3c6, 0x1f3ca,
- 0x1f3e0, 0x1f3f0,
- 0x1f400, 0x1f43e,
- 0x1f440, 0x1f440,
- 0x1f442, 0x1f4f7,
- 0x1f4f9, 0x1f4fc,
- 0x1f500, 0x1f53d,
- 0x1f540, 0x1f543,
- 0x1f550, 0x1f567,
- 0x1f5fb, 0x1f640,
- 0x1f645, 0x1f64f,
- 0x1f680, 0x1f6c5,
- 0x1f700, 0x1f773,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_6_2 */
-
-/* 'Age_6_3': Derived Age 6.3 */
-static const OnigCodePoint CR_Age_6_3[] = {
- 549,
- 0x0000, 0x0377,
- 0x037a, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x0527,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058f, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0604,
- 0x0606, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x08a0, 0x08a0,
- 0x08a2, 0x08ac,
- 0x08e4, 0x08fe,
- 0x0900, 0x0977,
- 0x0979, 0x097f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c59,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1400, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf6,
- 0x1d00, 0x1de6,
- 0x1dfc, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20ba,
- 0x20d0, 0x20f0,
- 0x2100, 0x2189,
- 0x2190, 0x23f3,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x26ff,
- 0x2701, 0x2b4c,
- 0x2b50, 0x2b59,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e3b,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fcc,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa697,
- 0xa69f, 0xa6f7,
- 0xa700, 0xa78e,
- 0xa790, 0xa793,
- 0xa7a0, 0xa7aa,
- 0xa7f8, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fb,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9df,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaa7b,
- 0xaa80, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xabc0, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe26,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018a,
- 0x10190, 0x1019b,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1085f,
- 0x10900, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a7f,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b7f,
- 0x10c00, 0x10c48,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x11080, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11180, 0x111c8,
- 0x111d0, 0x111d9,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x12000, 0x1236e,
- 0x12400, 0x12462,
- 0x12470, 0x12473,
- 0x13000, 0x1342e,
- 0x16800, 0x16a38,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x1b000, 0x1b001,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0be,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0df,
- 0x1f100, 0x1f10a,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f19a,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23a,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f300, 0x1f320,
- 0x1f330, 0x1f335,
- 0x1f337, 0x1f37c,
- 0x1f380, 0x1f393,
- 0x1f3a0, 0x1f3c4,
- 0x1f3c6, 0x1f3ca,
- 0x1f3e0, 0x1f3f0,
- 0x1f400, 0x1f43e,
- 0x1f440, 0x1f440,
- 0x1f442, 0x1f4f7,
- 0x1f4f9, 0x1f4fc,
- 0x1f500, 0x1f53d,
- 0x1f540, 0x1f543,
- 0x1f550, 0x1f567,
- 0x1f5fb, 0x1f640,
- 0x1f645, 0x1f64f,
- 0x1f680, 0x1f6c5,
- 0x1f700, 0x1f773,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_6_3 */
-
-/* 'Age_7_0': Derived Age 7.0 */
-static const OnigCodePoint CR_Age_7_0[] = {
- 610,
- 0x0000, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x08a0, 0x08b2,
- 0x08e4, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c59,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c81, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d01, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f4,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf6,
- 0x1cf8, 0x1cf9,
- 0x1d00, 0x1df5,
- 0x1dfc, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20bd,
- 0x20d0, 0x20f0,
- 0x2100, 0x2189,
- 0x2190, 0x23fa,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd1,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e42,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fcc,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa69d,
- 0xa69f, 0xa6f7,
- 0xa700, 0xa78e,
- 0xa790, 0xa7ad,
- 0xa7b0, 0xa7b1,
- 0xa7f7, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fb,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab5f,
- 0xab64, 0xab65,
- 0xabc0, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe2d,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018c,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102fb,
- 0x10300, 0x10323,
- 0x10330, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x10900, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109be, 0x109bf,
- 0x10a00, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11150, 0x11176,
- 0x11180, 0x111c8,
- 0x111cd, 0x111cd,
- 0x111d0, 0x111da,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1123d,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11301, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115c9,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11ac0, 0x11af8,
- 0x12000, 0x12398,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x13000, 0x1342e,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x1b000, 0x1b001,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1dd,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1d7ff,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f19a,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23a,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f300, 0x1f32c,
- 0x1f330, 0x1f37d,
- 0x1f380, 0x1f3ce,
- 0x1f3d4, 0x1f3f7,
- 0x1f400, 0x1f4fe,
- 0x1f500, 0x1f54a,
- 0x1f550, 0x1f579,
- 0x1f57b, 0x1f5a3,
- 0x1f5a5, 0x1f642,
- 0x1f645, 0x1f6cf,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f3,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_7_0 */
-
-/* 'Age_8_0': Derived Age 8.0 */
-static const OnigCodePoint CR_Age_8_0[] = {
- 623,
- 0x0000, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x08a0, 0x08b4,
- 0x08e3, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0af9,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c7f,
- 0x0c81, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d01, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4e,
- 0x0d57, 0x0d57,
- 0x0d5f, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf6,
- 0x1cf8, 0x1cf9,
- 0x1d00, 0x1df5,
- 0x1dfc, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20be,
- 0x20d0, 0x20f0,
- 0x2100, 0x218b,
- 0x2190, 0x23fa,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd1,
- 0x2bec, 0x2bef,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e42,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fd5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa6f7,
- 0xa700, 0xa7ad,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c4,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fd,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab65,
- 0xab70, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018c,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102fb,
- 0x10300, 0x10323,
- 0x10330, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11150, 0x11176,
- 0x11180, 0x111cd,
- 0x111d0, 0x111df,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1123d,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115dd,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x1173f,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11ac0, 0x11af8,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x1b000, 0x1b001,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1e8,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1da8b,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f19a,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23a,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f300, 0x1f579,
- 0x1f57b, 0x1f5a3,
- 0x1f5a5, 0x1f6d0,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f3,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f910, 0x1f918,
- 0x1f980, 0x1f984,
- 0x1f9c0, 0x1f9c0,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_8_0 */
-
-/* 'Age_9_0': Derived Age 9.0 */
-static const OnigCodePoint CR_Age_9_0[] = {
- 648,
- 0x0000, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fb,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0af9,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d01, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d3a,
- 0x0d3d, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4f,
- 0x0d54, 0x0d63,
- 0x0d66, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c88,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf6,
- 0x1cf8, 0x1cf9,
- 0x1d00, 0x1df5,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20be,
- 0x20d0, 0x20f0,
- 0x2100, 0x218b,
- 0x2190, 0x23fe,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd1,
- 0x2bec, 0x2bef,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e44,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312d,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fd5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa6f7,
- 0xa700, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c5,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fd,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab65,
- 0xab70, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102fb,
- 0x10300, 0x10323,
- 0x10330, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11150, 0x11176,
- 0x11180, 0x111cd,
- 0x111d0, 0x111df,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x11459,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115dd,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
- 0x11660, 0x1166c,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x1173f,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c45,
- 0x11c50, 0x11c6c,
- 0x11c70, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe0,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b001,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1e8,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1da8b,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1e95e, 0x1e95f,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f300, 0x1f6d2,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f6,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f910, 0x1f91e,
- 0x1f920, 0x1f927,
- 0x1f930, 0x1f930,
- 0x1f933, 0x1f93e,
- 0x1f940, 0x1f94b,
- 0x1f950, 0x1f95e,
- 0x1f980, 0x1f991,
- 0x1f9c0, 0x1f9c0,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_9_0 */
-
-/* 'Age_10_0': Derived Age 10.0 */
-static const OnigCodePoint CR_Age_10_0[] = {
- 659,
- 0x0000, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x052f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x058d, 0x058f,
- 0x0591, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x061c,
- 0x061e, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x0800, 0x082d,
- 0x0830, 0x083e,
- 0x0840, 0x085b,
- 0x085e, 0x085e,
- 0x0860, 0x086a,
- 0x08a0, 0x08b4,
- 0x08b6, 0x08bd,
- 0x08d4, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fd,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a75,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0aff,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c39,
- 0x0c3d, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c58, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c78, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce3,
- 0x0ce6, 0x0cef,
- 0x0cf1, 0x0cf2,
- 0x0d00, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d44,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4f,
- 0x0d54, 0x0d63,
- 0x0d66, 0x0d7f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6c,
- 0x0f71, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fce, 0x0fda,
- 0x1000, 0x10c5,
- 0x10c7, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12d6,
- 0x12d8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x191e,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a5e,
- 0x1a60, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1abe,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c88,
- 0x1cc0, 0x1cc7,
- 0x1cd0, 0x1cf9,
- 0x1d00, 0x1df9,
- 0x1dfb, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2064,
- 0x2066, 0x2071,
- 0x2074, 0x208e,
- 0x2090, 0x209c,
- 0x20a0, 0x20bf,
- 0x20d0, 0x20f0,
- 0x2100, 0x218b,
- 0x2190, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2b95,
- 0x2b98, 0x2bb9,
- 0x2bbd, 0x2bc8,
- 0x2bca, 0x2bd2,
- 0x2bec, 0x2bef,
- 0x2c00, 0x2c2e,
- 0x2c30, 0x2c5e,
- 0x2c60, 0x2cf3,
- 0x2cf9, 0x2d25,
- 0x2d27, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2da6,
- 0x2da8, 0x2dae,
- 0x2db0, 0x2db6,
- 0x2db8, 0x2dbe,
- 0x2dc0, 0x2dc6,
- 0x2dc8, 0x2dce,
- 0x2dd0, 0x2dd6,
- 0x2dd8, 0x2dde,
- 0x2de0, 0x2e49,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312e,
- 0x3131, 0x318e,
- 0x3190, 0x31ba,
- 0x31c0, 0x31e3,
- 0x31f0, 0x321e,
- 0x3220, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fea,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa6f7,
- 0xa700, 0xa7ae,
- 0xa7b0, 0xa7b7,
- 0xa7f7, 0xa82b,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c5,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fd,
- 0xa900, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9cd,
- 0xa9cf, 0xa9d9,
- 0xa9de, 0xa9fe,
- 0xaa00, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab26,
- 0xab28, 0xab2e,
- 0xab30, 0xab65,
- 0xab70, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xd800, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdd0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1018e,
- 0x10190, 0x1019b,
- 0x101a0, 0x101a0,
- 0x101d0, 0x101fd,
- 0x10280, 0x1029c,
- 0x102a0, 0x102d0,
- 0x102e0, 0x102fb,
- 0x10300, 0x10323,
- 0x1032d, 0x1034a,
- 0x10350, 0x1037a,
- 0x10380, 0x1039d,
- 0x1039f, 0x103c3,
- 0x103c8, 0x103d5,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x104b0, 0x104d3,
- 0x104d8, 0x104fb,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x1056f, 0x1056f,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x10855,
- 0x10857, 0x1089e,
- 0x108a7, 0x108af,
- 0x108e0, 0x108f2,
- 0x108f4, 0x108f5,
- 0x108fb, 0x1091b,
- 0x1091f, 0x10939,
- 0x1093f, 0x1093f,
- 0x10980, 0x109b7,
- 0x109bc, 0x109cf,
- 0x109d2, 0x10a03,
- 0x10a05, 0x10a06,
- 0x10a0c, 0x10a13,
- 0x10a15, 0x10a17,
- 0x10a19, 0x10a33,
- 0x10a38, 0x10a3a,
- 0x10a3f, 0x10a47,
- 0x10a50, 0x10a58,
- 0x10a60, 0x10a9f,
- 0x10ac0, 0x10ae6,
- 0x10aeb, 0x10af6,
- 0x10b00, 0x10b35,
- 0x10b39, 0x10b55,
- 0x10b58, 0x10b72,
- 0x10b78, 0x10b91,
- 0x10b99, 0x10b9c,
- 0x10ba9, 0x10baf,
- 0x10c00, 0x10c48,
- 0x10c80, 0x10cb2,
- 0x10cc0, 0x10cf2,
- 0x10cfa, 0x10cff,
- 0x10e60, 0x10e7e,
- 0x11000, 0x1104d,
- 0x11052, 0x1106f,
- 0x1107f, 0x110c1,
- 0x110d0, 0x110e8,
- 0x110f0, 0x110f9,
- 0x11100, 0x11134,
- 0x11136, 0x11143,
- 0x11150, 0x11176,
- 0x11180, 0x111cd,
- 0x111d0, 0x111df,
- 0x111e1, 0x111f4,
- 0x11200, 0x11211,
- 0x11213, 0x1123e,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128a, 0x1128d,
- 0x1128f, 0x1129d,
- 0x1129f, 0x112a9,
- 0x112b0, 0x112ea,
- 0x112f0, 0x112f9,
- 0x11300, 0x11303,
- 0x11305, 0x1130c,
- 0x1130f, 0x11310,
- 0x11313, 0x11328,
- 0x1132a, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133c, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135d, 0x11363,
- 0x11366, 0x1136c,
- 0x11370, 0x11374,
- 0x11400, 0x11459,
- 0x1145b, 0x1145b,
- 0x1145d, 0x1145d,
- 0x11480, 0x114c7,
- 0x114d0, 0x114d9,
- 0x11580, 0x115b5,
- 0x115b8, 0x115dd,
- 0x11600, 0x11644,
- 0x11650, 0x11659,
- 0x11660, 0x1166c,
- 0x11680, 0x116b7,
- 0x116c0, 0x116c9,
- 0x11700, 0x11719,
- 0x1171d, 0x1172b,
- 0x11730, 0x1173f,
- 0x118a0, 0x118f2,
- 0x118ff, 0x118ff,
- 0x11a00, 0x11a47,
- 0x11a50, 0x11a83,
- 0x11a86, 0x11a9c,
- 0x11a9e, 0x11aa2,
- 0x11ac0, 0x11af8,
- 0x11c00, 0x11c08,
- 0x11c0a, 0x11c36,
- 0x11c38, 0x11c45,
- 0x11c50, 0x11c6c,
- 0x11c70, 0x11c8f,
- 0x11c92, 0x11ca7,
- 0x11ca9, 0x11cb6,
- 0x11d00, 0x11d06,
- 0x11d08, 0x11d09,
- 0x11d0b, 0x11d36,
- 0x11d3a, 0x11d3a,
- 0x11d3c, 0x11d3d,
- 0x11d3f, 0x11d47,
- 0x11d50, 0x11d59,
- 0x12000, 0x12399,
- 0x12400, 0x1246e,
- 0x12470, 0x12474,
- 0x12480, 0x12543,
- 0x13000, 0x1342e,
- 0x14400, 0x14646,
- 0x16800, 0x16a38,
- 0x16a40, 0x16a5e,
- 0x16a60, 0x16a69,
- 0x16a6e, 0x16a6f,
- 0x16ad0, 0x16aed,
- 0x16af0, 0x16af5,
- 0x16b00, 0x16b45,
- 0x16b50, 0x16b59,
- 0x16b5b, 0x16b61,
- 0x16b63, 0x16b77,
- 0x16b7d, 0x16b8f,
- 0x16f00, 0x16f44,
- 0x16f50, 0x16f7e,
- 0x16f8f, 0x16f9f,
- 0x16fe0, 0x16fe1,
- 0x17000, 0x187ec,
- 0x18800, 0x18af2,
- 0x1b000, 0x1b11e,
- 0x1b170, 0x1b2fb,
- 0x1bc00, 0x1bc6a,
- 0x1bc70, 0x1bc7c,
- 0x1bc80, 0x1bc88,
- 0x1bc90, 0x1bc99,
- 0x1bc9c, 0x1bca3,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d129, 0x1d1e8,
- 0x1d200, 0x1d245,
- 0x1d300, 0x1d356,
- 0x1d360, 0x1d371,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a5,
- 0x1d6a8, 0x1d7cb,
- 0x1d7ce, 0x1da8b,
- 0x1da9b, 0x1da9f,
- 0x1daa1, 0x1daaf,
- 0x1e000, 0x1e006,
- 0x1e008, 0x1e018,
- 0x1e01b, 0x1e021,
- 0x1e023, 0x1e024,
- 0x1e026, 0x1e02a,
- 0x1e800, 0x1e8c4,
- 0x1e8c7, 0x1e8d6,
- 0x1e900, 0x1e94a,
- 0x1e950, 0x1e959,
- 0x1e95e, 0x1e95f,
- 0x1ee00, 0x1ee03,
- 0x1ee05, 0x1ee1f,
- 0x1ee21, 0x1ee22,
- 0x1ee24, 0x1ee24,
- 0x1ee27, 0x1ee27,
- 0x1ee29, 0x1ee32,
- 0x1ee34, 0x1ee37,
- 0x1ee39, 0x1ee39,
- 0x1ee3b, 0x1ee3b,
- 0x1ee42, 0x1ee42,
- 0x1ee47, 0x1ee47,
- 0x1ee49, 0x1ee49,
- 0x1ee4b, 0x1ee4b,
- 0x1ee4d, 0x1ee4f,
- 0x1ee51, 0x1ee52,
- 0x1ee54, 0x1ee54,
- 0x1ee57, 0x1ee57,
- 0x1ee59, 0x1ee59,
- 0x1ee5b, 0x1ee5b,
- 0x1ee5d, 0x1ee5d,
- 0x1ee5f, 0x1ee5f,
- 0x1ee61, 0x1ee62,
- 0x1ee64, 0x1ee64,
- 0x1ee67, 0x1ee6a,
- 0x1ee6c, 0x1ee72,
- 0x1ee74, 0x1ee77,
- 0x1ee79, 0x1ee7c,
- 0x1ee7e, 0x1ee7e,
- 0x1ee80, 0x1ee89,
- 0x1ee8b, 0x1ee9b,
- 0x1eea1, 0x1eea3,
- 0x1eea5, 0x1eea9,
- 0x1eeab, 0x1eebb,
- 0x1eef0, 0x1eef1,
- 0x1f000, 0x1f02b,
- 0x1f030, 0x1f093,
- 0x1f0a0, 0x1f0ae,
- 0x1f0b1, 0x1f0bf,
- 0x1f0c1, 0x1f0cf,
- 0x1f0d1, 0x1f0f5,
- 0x1f100, 0x1f10c,
- 0x1f110, 0x1f12e,
- 0x1f130, 0x1f16b,
- 0x1f170, 0x1f1ac,
- 0x1f1e6, 0x1f202,
- 0x1f210, 0x1f23b,
- 0x1f240, 0x1f248,
- 0x1f250, 0x1f251,
- 0x1f260, 0x1f265,
- 0x1f300, 0x1f6d4,
- 0x1f6e0, 0x1f6ec,
- 0x1f6f0, 0x1f6f8,
- 0x1f700, 0x1f773,
- 0x1f780, 0x1f7d4,
- 0x1f800, 0x1f80b,
- 0x1f810, 0x1f847,
- 0x1f850, 0x1f859,
- 0x1f860, 0x1f887,
- 0x1f890, 0x1f8ad,
- 0x1f900, 0x1f90b,
- 0x1f910, 0x1f93e,
- 0x1f940, 0x1f94c,
- 0x1f950, 0x1f96b,
- 0x1f980, 0x1f997,
- 0x1f9c0, 0x1f9c0,
- 0x1f9d0, 0x1f9e6,
- 0x1fffe, 0x2a6d6,
- 0x2a700, 0x2b734,
- 0x2b740, 0x2b81d,
- 0x2b820, 0x2cea1,
- 0x2ceb0, 0x2ebe0,
- 0x2f800, 0x2fa1d,
- 0x2fffe, 0x2ffff,
- 0x3fffe, 0x3ffff,
- 0x4fffe, 0x4ffff,
- 0x5fffe, 0x5ffff,
- 0x6fffe, 0x6ffff,
- 0x7fffe, 0x7ffff,
- 0x8fffe, 0x8ffff,
- 0x9fffe, 0x9ffff,
- 0xafffe, 0xaffff,
- 0xbfffe, 0xbffff,
- 0xcfffe, 0xcffff,
- 0xdfffe, 0xdffff,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xefffe, 0x10ffff,
-}; /* CR_Age_10_0 */
-
-#endif /* USE_UNICODE_AGE_PROPERTIES */
-/* 'Grapheme_Cluster_Break_Prepend': Grapheme_Cluster_Break=Prepend */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_Prepend[] = {
- 10,
- 0x0600, 0x0605,
- 0x06dd, 0x06dd,
- 0x070f, 0x070f,
- 0x08e2, 0x08e2,
- 0x0d4e, 0x0d4e,
- 0x110bd, 0x110bd,
- 0x111c2, 0x111c3,
- 0x11a3a, 0x11a3a,
- 0x11a86, 0x11a89,
- 0x11d46, 0x11d46,
-}; /* CR_Grapheme_Cluster_Break_Prepend */
-
-/* 'Grapheme_Cluster_Break_CR': Grapheme_Cluster_Break=CR */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_CR[] = {
- 1,
- 0x000d, 0x000d,
-}; /* CR_Grapheme_Cluster_Break_CR */
-
-/* 'Grapheme_Cluster_Break_LF': Grapheme_Cluster_Break=LF */
-#define CR_Grapheme_Cluster_Break_LF CR_NEWLINE
-
-/* 'Grapheme_Cluster_Break_Control': Grapheme_Cluster_Break=Control */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_Control[] = {
- 19,
- 0x0000, 0x0009,
- 0x000b, 0x000c,
- 0x000e, 0x001f,
- 0x007f, 0x009f,
- 0x00ad, 0x00ad,
- 0x061c, 0x061c,
- 0x180e, 0x180e,
- 0x200b, 0x200b,
- 0x200e, 0x200f,
- 0x2028, 0x202e,
- 0x2060, 0x206f,
- 0xd800, 0xdfff,
- 0xfeff, 0xfeff,
- 0xfff0, 0xfffb,
- 0x1bca0, 0x1bca3,
- 0x1d173, 0x1d17a,
- 0xe0000, 0xe001f,
- 0xe0080, 0xe00ff,
- 0xe01f0, 0xe0fff,
-}; /* CR_Grapheme_Cluster_Break_Control */
-
-/* 'Grapheme_Cluster_Break_Extend': Grapheme_Cluster_Break=Extend */
-#define CR_Grapheme_Cluster_Break_Extend CR_Grapheme_Extend
-
-/* 'Grapheme_Cluster_Break_Regional_Indicator': Grapheme_Cluster_Break=Regional_Indicator */
-#define CR_Grapheme_Cluster_Break_Regional_Indicator CR_Regional_Indicator
-
-/* 'Grapheme_Cluster_Break_SpacingMark': Grapheme_Cluster_Break=SpacingMark */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_SpacingMark[] = {
- 145,
- 0x0903, 0x0903,
- 0x093b, 0x093b,
- 0x093e, 0x0940,
- 0x0949, 0x094c,
- 0x094e, 0x094f,
- 0x0982, 0x0983,
- 0x09bf, 0x09c0,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cc,
- 0x0a03, 0x0a03,
- 0x0a3e, 0x0a40,
- 0x0a83, 0x0a83,
- 0x0abe, 0x0ac0,
- 0x0ac9, 0x0ac9,
- 0x0acb, 0x0acc,
- 0x0b02, 0x0b03,
- 0x0b40, 0x0b40,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4c,
- 0x0bbf, 0x0bbf,
- 0x0bc1, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcc,
- 0x0c01, 0x0c03,
- 0x0c41, 0x0c44,
- 0x0c82, 0x0c83,
- 0x0cbe, 0x0cbe,
- 0x0cc0, 0x0cc1,
- 0x0cc3, 0x0cc4,
- 0x0cc7, 0x0cc8,
- 0x0cca, 0x0ccb,
- 0x0d02, 0x0d03,
- 0x0d3f, 0x0d40,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4c,
- 0x0d82, 0x0d83,
- 0x0dd0, 0x0dd1,
- 0x0dd8, 0x0dde,
- 0x0df2, 0x0df3,
- 0x0e33, 0x0e33,
- 0x0eb3, 0x0eb3,
- 0x0f3e, 0x0f3f,
- 0x0f7f, 0x0f7f,
- 0x1031, 0x1031,
- 0x103b, 0x103c,
- 0x1056, 0x1057,
- 0x1084, 0x1084,
- 0x17b6, 0x17b6,
- 0x17be, 0x17c5,
- 0x17c7, 0x17c8,
- 0x1923, 0x1926,
- 0x1929, 0x192b,
- 0x1930, 0x1931,
- 0x1933, 0x1938,
- 0x1a19, 0x1a1a,
- 0x1a55, 0x1a55,
- 0x1a57, 0x1a57,
- 0x1a6d, 0x1a72,
- 0x1b04, 0x1b04,
- 0x1b35, 0x1b35,
- 0x1b3b, 0x1b3b,
- 0x1b3d, 0x1b41,
- 0x1b43, 0x1b44,
- 0x1b82, 0x1b82,
- 0x1ba1, 0x1ba1,
- 0x1ba6, 0x1ba7,
- 0x1baa, 0x1baa,
- 0x1be7, 0x1be7,
- 0x1bea, 0x1bec,
- 0x1bee, 0x1bee,
- 0x1bf2, 0x1bf3,
- 0x1c24, 0x1c2b,
- 0x1c34, 0x1c35,
- 0x1ce1, 0x1ce1,
- 0x1cf2, 0x1cf3,
- 0x1cf7, 0x1cf7,
- 0xa823, 0xa824,
- 0xa827, 0xa827,
- 0xa880, 0xa881,
- 0xa8b4, 0xa8c3,
- 0xa952, 0xa953,
- 0xa983, 0xa983,
- 0xa9b4, 0xa9b5,
- 0xa9ba, 0xa9bb,
- 0xa9bd, 0xa9c0,
- 0xaa2f, 0xaa30,
- 0xaa33, 0xaa34,
- 0xaa4d, 0xaa4d,
- 0xaaeb, 0xaaeb,
- 0xaaee, 0xaaef,
- 0xaaf5, 0xaaf5,
- 0xabe3, 0xabe4,
- 0xabe6, 0xabe7,
- 0xabe9, 0xabea,
- 0xabec, 0xabec,
- 0x11000, 0x11000,
- 0x11002, 0x11002,
- 0x11082, 0x11082,
- 0x110b0, 0x110b2,
- 0x110b7, 0x110b8,
- 0x1112c, 0x1112c,
- 0x11182, 0x11182,
- 0x111b3, 0x111b5,
- 0x111bf, 0x111c0,
- 0x1122c, 0x1122e,
- 0x11232, 0x11233,
- 0x11235, 0x11235,
- 0x112e0, 0x112e2,
- 0x11302, 0x11303,
- 0x1133f, 0x1133f,
- 0x11341, 0x11344,
- 0x11347, 0x11348,
- 0x1134b, 0x1134d,
- 0x11362, 0x11363,
- 0x11435, 0x11437,
- 0x11440, 0x11441,
- 0x11445, 0x11445,
- 0x114b1, 0x114b2,
- 0x114b9, 0x114b9,
- 0x114bb, 0x114bc,
- 0x114be, 0x114be,
- 0x114c1, 0x114c1,
- 0x115b0, 0x115b1,
- 0x115b8, 0x115bb,
- 0x115be, 0x115be,
- 0x11630, 0x11632,
- 0x1163b, 0x1163c,
- 0x1163e, 0x1163e,
- 0x116ac, 0x116ac,
- 0x116ae, 0x116af,
- 0x116b6, 0x116b6,
- 0x11720, 0x11721,
- 0x11726, 0x11726,
- 0x11a07, 0x11a08,
- 0x11a39, 0x11a39,
- 0x11a57, 0x11a58,
- 0x11a97, 0x11a97,
- 0x11c2f, 0x11c2f,
- 0x11c3e, 0x11c3e,
- 0x11ca9, 0x11ca9,
- 0x11cb1, 0x11cb1,
- 0x11cb4, 0x11cb4,
- 0x16f51, 0x16f7e,
- 0x1d166, 0x1d166,
- 0x1d16d, 0x1d16d,
-}; /* CR_Grapheme_Cluster_Break_SpacingMark */
-
-/* 'Grapheme_Cluster_Break_L': Grapheme_Cluster_Break=L */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_L[] = {
- 2,
- 0x1100, 0x115f,
- 0xa960, 0xa97c,
-}; /* CR_Grapheme_Cluster_Break_L */
-
-/* 'Grapheme_Cluster_Break_V': Grapheme_Cluster_Break=V */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_V[] = {
- 2,
- 0x1160, 0x11a7,
- 0xd7b0, 0xd7c6,
-}; /* CR_Grapheme_Cluster_Break_V */
-
-/* 'Grapheme_Cluster_Break_T': Grapheme_Cluster_Break=T */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_T[] = {
- 2,
- 0x11a8, 0x11ff,
- 0xd7cb, 0xd7fb,
-}; /* CR_Grapheme_Cluster_Break_T */
-
-/* 'Grapheme_Cluster_Break_LV': Grapheme_Cluster_Break=LV */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_LV[] = {
- 399,
- 0xac00, 0xac00,
- 0xac1c, 0xac1c,
- 0xac38, 0xac38,
- 0xac54, 0xac54,
- 0xac70, 0xac70,
- 0xac8c, 0xac8c,
- 0xaca8, 0xaca8,
- 0xacc4, 0xacc4,
- 0xace0, 0xace0,
- 0xacfc, 0xacfc,
- 0xad18, 0xad18,
- 0xad34, 0xad34,
- 0xad50, 0xad50,
- 0xad6c, 0xad6c,
- 0xad88, 0xad88,
- 0xada4, 0xada4,
- 0xadc0, 0xadc0,
- 0xaddc, 0xaddc,
- 0xadf8, 0xadf8,
- 0xae14, 0xae14,
- 0xae30, 0xae30,
- 0xae4c, 0xae4c,
- 0xae68, 0xae68,
- 0xae84, 0xae84,
- 0xaea0, 0xaea0,
- 0xaebc, 0xaebc,
- 0xaed8, 0xaed8,
- 0xaef4, 0xaef4,
- 0xaf10, 0xaf10,
- 0xaf2c, 0xaf2c,
- 0xaf48, 0xaf48,
- 0xaf64, 0xaf64,
- 0xaf80, 0xaf80,
- 0xaf9c, 0xaf9c,
- 0xafb8, 0xafb8,
- 0xafd4, 0xafd4,
- 0xaff0, 0xaff0,
- 0xb00c, 0xb00c,
- 0xb028, 0xb028,
- 0xb044, 0xb044,
- 0xb060, 0xb060,
- 0xb07c, 0xb07c,
- 0xb098, 0xb098,
- 0xb0b4, 0xb0b4,
- 0xb0d0, 0xb0d0,
- 0xb0ec, 0xb0ec,
- 0xb108, 0xb108,
- 0xb124, 0xb124,
- 0xb140, 0xb140,
- 0xb15c, 0xb15c,
- 0xb178, 0xb178,
- 0xb194, 0xb194,
- 0xb1b0, 0xb1b0,
- 0xb1cc, 0xb1cc,
- 0xb1e8, 0xb1e8,
- 0xb204, 0xb204,
- 0xb220, 0xb220,
- 0xb23c, 0xb23c,
- 0xb258, 0xb258,
- 0xb274, 0xb274,
- 0xb290, 0xb290,
- 0xb2ac, 0xb2ac,
- 0xb2c8, 0xb2c8,
- 0xb2e4, 0xb2e4,
- 0xb300, 0xb300,
- 0xb31c, 0xb31c,
- 0xb338, 0xb338,
- 0xb354, 0xb354,
- 0xb370, 0xb370,
- 0xb38c, 0xb38c,
- 0xb3a8, 0xb3a8,
- 0xb3c4, 0xb3c4,
- 0xb3e0, 0xb3e0,
- 0xb3fc, 0xb3fc,
- 0xb418, 0xb418,
- 0xb434, 0xb434,
- 0xb450, 0xb450,
- 0xb46c, 0xb46c,
- 0xb488, 0xb488,
- 0xb4a4, 0xb4a4,
- 0xb4c0, 0xb4c0,
- 0xb4dc, 0xb4dc,
- 0xb4f8, 0xb4f8,
- 0xb514, 0xb514,
- 0xb530, 0xb530,
- 0xb54c, 0xb54c,
- 0xb568, 0xb568,
- 0xb584, 0xb584,
- 0xb5a0, 0xb5a0,
- 0xb5bc, 0xb5bc,
- 0xb5d8, 0xb5d8,
- 0xb5f4, 0xb5f4,
- 0xb610, 0xb610,
- 0xb62c, 0xb62c,
- 0xb648, 0xb648,
- 0xb664, 0xb664,
- 0xb680, 0xb680,
- 0xb69c, 0xb69c,
- 0xb6b8, 0xb6b8,
- 0xb6d4, 0xb6d4,
- 0xb6f0, 0xb6f0,
- 0xb70c, 0xb70c,
- 0xb728, 0xb728,
- 0xb744, 0xb744,
- 0xb760, 0xb760,
- 0xb77c, 0xb77c,
- 0xb798, 0xb798,
- 0xb7b4, 0xb7b4,
- 0xb7d0, 0xb7d0,
- 0xb7ec, 0xb7ec,
- 0xb808, 0xb808,
- 0xb824, 0xb824,
- 0xb840, 0xb840,
- 0xb85c, 0xb85c,
- 0xb878, 0xb878,
- 0xb894, 0xb894,
- 0xb8b0, 0xb8b0,
- 0xb8cc, 0xb8cc,
- 0xb8e8, 0xb8e8,
- 0xb904, 0xb904,
- 0xb920, 0xb920,
- 0xb93c, 0xb93c,
- 0xb958, 0xb958,
- 0xb974, 0xb974,
- 0xb990, 0xb990,
- 0xb9ac, 0xb9ac,
- 0xb9c8, 0xb9c8,
- 0xb9e4, 0xb9e4,
- 0xba00, 0xba00,
- 0xba1c, 0xba1c,
- 0xba38, 0xba38,
- 0xba54, 0xba54,
- 0xba70, 0xba70,
- 0xba8c, 0xba8c,
- 0xbaa8, 0xbaa8,
- 0xbac4, 0xbac4,
- 0xbae0, 0xbae0,
- 0xbafc, 0xbafc,
- 0xbb18, 0xbb18,
- 0xbb34, 0xbb34,
- 0xbb50, 0xbb50,
- 0xbb6c, 0xbb6c,
- 0xbb88, 0xbb88,
- 0xbba4, 0xbba4,
- 0xbbc0, 0xbbc0,
- 0xbbdc, 0xbbdc,
- 0xbbf8, 0xbbf8,
- 0xbc14, 0xbc14,
- 0xbc30, 0xbc30,
- 0xbc4c, 0xbc4c,
- 0xbc68, 0xbc68,
- 0xbc84, 0xbc84,
- 0xbca0, 0xbca0,
- 0xbcbc, 0xbcbc,
- 0xbcd8, 0xbcd8,
- 0xbcf4, 0xbcf4,
- 0xbd10, 0xbd10,
- 0xbd2c, 0xbd2c,
- 0xbd48, 0xbd48,
- 0xbd64, 0xbd64,
- 0xbd80, 0xbd80,
- 0xbd9c, 0xbd9c,
- 0xbdb8, 0xbdb8,
- 0xbdd4, 0xbdd4,
- 0xbdf0, 0xbdf0,
- 0xbe0c, 0xbe0c,
- 0xbe28, 0xbe28,
- 0xbe44, 0xbe44,
- 0xbe60, 0xbe60,
- 0xbe7c, 0xbe7c,
- 0xbe98, 0xbe98,
- 0xbeb4, 0xbeb4,
- 0xbed0, 0xbed0,
- 0xbeec, 0xbeec,
- 0xbf08, 0xbf08,
- 0xbf24, 0xbf24,
- 0xbf40, 0xbf40,
- 0xbf5c, 0xbf5c,
- 0xbf78, 0xbf78,
- 0xbf94, 0xbf94,
- 0xbfb0, 0xbfb0,
- 0xbfcc, 0xbfcc,
- 0xbfe8, 0xbfe8,
- 0xc004, 0xc004,
- 0xc020, 0xc020,
- 0xc03c, 0xc03c,
- 0xc058, 0xc058,
- 0xc074, 0xc074,
- 0xc090, 0xc090,
- 0xc0ac, 0xc0ac,
- 0xc0c8, 0xc0c8,
- 0xc0e4, 0xc0e4,
- 0xc100, 0xc100,
- 0xc11c, 0xc11c,
- 0xc138, 0xc138,
- 0xc154, 0xc154,
- 0xc170, 0xc170,
- 0xc18c, 0xc18c,
- 0xc1a8, 0xc1a8,
- 0xc1c4, 0xc1c4,
- 0xc1e0, 0xc1e0,
- 0xc1fc, 0xc1fc,
- 0xc218, 0xc218,
- 0xc234, 0xc234,
- 0xc250, 0xc250,
- 0xc26c, 0xc26c,
- 0xc288, 0xc288,
- 0xc2a4, 0xc2a4,
- 0xc2c0, 0xc2c0,
- 0xc2dc, 0xc2dc,
- 0xc2f8, 0xc2f8,
- 0xc314, 0xc314,
- 0xc330, 0xc330,
- 0xc34c, 0xc34c,
- 0xc368, 0xc368,
- 0xc384, 0xc384,
- 0xc3a0, 0xc3a0,
- 0xc3bc, 0xc3bc,
- 0xc3d8, 0xc3d8,
- 0xc3f4, 0xc3f4,
- 0xc410, 0xc410,
- 0xc42c, 0xc42c,
- 0xc448, 0xc448,
- 0xc464, 0xc464,
- 0xc480, 0xc480,
- 0xc49c, 0xc49c,
- 0xc4b8, 0xc4b8,
- 0xc4d4, 0xc4d4,
- 0xc4f0, 0xc4f0,
- 0xc50c, 0xc50c,
- 0xc528, 0xc528,
- 0xc544, 0xc544,
- 0xc560, 0xc560,
- 0xc57c, 0xc57c,
- 0xc598, 0xc598,
- 0xc5b4, 0xc5b4,
- 0xc5d0, 0xc5d0,
- 0xc5ec, 0xc5ec,
- 0xc608, 0xc608,
- 0xc624, 0xc624,
- 0xc640, 0xc640,
- 0xc65c, 0xc65c,
- 0xc678, 0xc678,
- 0xc694, 0xc694,
- 0xc6b0, 0xc6b0,
- 0xc6cc, 0xc6cc,
- 0xc6e8, 0xc6e8,
- 0xc704, 0xc704,
- 0xc720, 0xc720,
- 0xc73c, 0xc73c,
- 0xc758, 0xc758,
- 0xc774, 0xc774,
- 0xc790, 0xc790,
- 0xc7ac, 0xc7ac,
- 0xc7c8, 0xc7c8,
- 0xc7e4, 0xc7e4,
- 0xc800, 0xc800,
- 0xc81c, 0xc81c,
- 0xc838, 0xc838,
- 0xc854, 0xc854,
- 0xc870, 0xc870,
- 0xc88c, 0xc88c,
- 0xc8a8, 0xc8a8,
- 0xc8c4, 0xc8c4,
- 0xc8e0, 0xc8e0,
- 0xc8fc, 0xc8fc,
- 0xc918, 0xc918,
- 0xc934, 0xc934,
- 0xc950, 0xc950,
- 0xc96c, 0xc96c,
- 0xc988, 0xc988,
- 0xc9a4, 0xc9a4,
- 0xc9c0, 0xc9c0,
- 0xc9dc, 0xc9dc,
- 0xc9f8, 0xc9f8,
- 0xca14, 0xca14,
- 0xca30, 0xca30,
- 0xca4c, 0xca4c,
- 0xca68, 0xca68,
- 0xca84, 0xca84,
- 0xcaa0, 0xcaa0,
- 0xcabc, 0xcabc,
- 0xcad8, 0xcad8,
- 0xcaf4, 0xcaf4,
- 0xcb10, 0xcb10,
- 0xcb2c, 0xcb2c,
- 0xcb48, 0xcb48,
- 0xcb64, 0xcb64,
- 0xcb80, 0xcb80,
- 0xcb9c, 0xcb9c,
- 0xcbb8, 0xcbb8,
- 0xcbd4, 0xcbd4,
- 0xcbf0, 0xcbf0,
- 0xcc0c, 0xcc0c,
- 0xcc28, 0xcc28,
- 0xcc44, 0xcc44,
- 0xcc60, 0xcc60,
- 0xcc7c, 0xcc7c,
- 0xcc98, 0xcc98,
- 0xccb4, 0xccb4,
- 0xccd0, 0xccd0,
- 0xccec, 0xccec,
- 0xcd08, 0xcd08,
- 0xcd24, 0xcd24,
- 0xcd40, 0xcd40,
- 0xcd5c, 0xcd5c,
- 0xcd78, 0xcd78,
- 0xcd94, 0xcd94,
- 0xcdb0, 0xcdb0,
- 0xcdcc, 0xcdcc,
- 0xcde8, 0xcde8,
- 0xce04, 0xce04,
- 0xce20, 0xce20,
- 0xce3c, 0xce3c,
- 0xce58, 0xce58,
- 0xce74, 0xce74,
- 0xce90, 0xce90,
- 0xceac, 0xceac,
- 0xcec8, 0xcec8,
- 0xcee4, 0xcee4,
- 0xcf00, 0xcf00,
- 0xcf1c, 0xcf1c,
- 0xcf38, 0xcf38,
- 0xcf54, 0xcf54,
- 0xcf70, 0xcf70,
- 0xcf8c, 0xcf8c,
- 0xcfa8, 0xcfa8,
- 0xcfc4, 0xcfc4,
- 0xcfe0, 0xcfe0,
- 0xcffc, 0xcffc,
- 0xd018, 0xd018,
- 0xd034, 0xd034,
- 0xd050, 0xd050,
- 0xd06c, 0xd06c,
- 0xd088, 0xd088,
- 0xd0a4, 0xd0a4,
- 0xd0c0, 0xd0c0,
- 0xd0dc, 0xd0dc,
- 0xd0f8, 0xd0f8,
- 0xd114, 0xd114,
- 0xd130, 0xd130,
- 0xd14c, 0xd14c,
- 0xd168, 0xd168,
- 0xd184, 0xd184,
- 0xd1a0, 0xd1a0,
- 0xd1bc, 0xd1bc,
- 0xd1d8, 0xd1d8,
- 0xd1f4, 0xd1f4,
- 0xd210, 0xd210,
- 0xd22c, 0xd22c,
- 0xd248, 0xd248,
- 0xd264, 0xd264,
- 0xd280, 0xd280,
- 0xd29c, 0xd29c,
- 0xd2b8, 0xd2b8,
- 0xd2d4, 0xd2d4,
- 0xd2f0, 0xd2f0,
- 0xd30c, 0xd30c,
- 0xd328, 0xd328,
- 0xd344, 0xd344,
- 0xd360, 0xd360,
- 0xd37c, 0xd37c,
- 0xd398, 0xd398,
- 0xd3b4, 0xd3b4,
- 0xd3d0, 0xd3d0,
- 0xd3ec, 0xd3ec,
- 0xd408, 0xd408,
- 0xd424, 0xd424,
- 0xd440, 0xd440,
- 0xd45c, 0xd45c,
- 0xd478, 0xd478,
- 0xd494, 0xd494,
- 0xd4b0, 0xd4b0,
- 0xd4cc, 0xd4cc,
- 0xd4e8, 0xd4e8,
- 0xd504, 0xd504,
- 0xd520, 0xd520,
- 0xd53c, 0xd53c,
- 0xd558, 0xd558,
- 0xd574, 0xd574,
- 0xd590, 0xd590,
- 0xd5ac, 0xd5ac,
- 0xd5c8, 0xd5c8,
- 0xd5e4, 0xd5e4,
- 0xd600, 0xd600,
- 0xd61c, 0xd61c,
- 0xd638, 0xd638,
- 0xd654, 0xd654,
- 0xd670, 0xd670,
- 0xd68c, 0xd68c,
- 0xd6a8, 0xd6a8,
- 0xd6c4, 0xd6c4,
- 0xd6e0, 0xd6e0,
- 0xd6fc, 0xd6fc,
- 0xd718, 0xd718,
- 0xd734, 0xd734,
- 0xd750, 0xd750,
- 0xd76c, 0xd76c,
- 0xd788, 0xd788,
-}; /* CR_Grapheme_Cluster_Break_LV */
-
-/* 'Grapheme_Cluster_Break_LVT': Grapheme_Cluster_Break=LVT */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_LVT[] = {
- 399,
- 0xac01, 0xac1b,
- 0xac1d, 0xac37,
- 0xac39, 0xac53,
- 0xac55, 0xac6f,
- 0xac71, 0xac8b,
- 0xac8d, 0xaca7,
- 0xaca9, 0xacc3,
- 0xacc5, 0xacdf,
- 0xace1, 0xacfb,
- 0xacfd, 0xad17,
- 0xad19, 0xad33,
- 0xad35, 0xad4f,
- 0xad51, 0xad6b,
- 0xad6d, 0xad87,
- 0xad89, 0xada3,
- 0xada5, 0xadbf,
- 0xadc1, 0xaddb,
- 0xaddd, 0xadf7,
- 0xadf9, 0xae13,
- 0xae15, 0xae2f,
- 0xae31, 0xae4b,
- 0xae4d, 0xae67,
- 0xae69, 0xae83,
- 0xae85, 0xae9f,
- 0xaea1, 0xaebb,
- 0xaebd, 0xaed7,
- 0xaed9, 0xaef3,
- 0xaef5, 0xaf0f,
- 0xaf11, 0xaf2b,
- 0xaf2d, 0xaf47,
- 0xaf49, 0xaf63,
- 0xaf65, 0xaf7f,
- 0xaf81, 0xaf9b,
- 0xaf9d, 0xafb7,
- 0xafb9, 0xafd3,
- 0xafd5, 0xafef,
- 0xaff1, 0xb00b,
- 0xb00d, 0xb027,
- 0xb029, 0xb043,
- 0xb045, 0xb05f,
- 0xb061, 0xb07b,
- 0xb07d, 0xb097,
- 0xb099, 0xb0b3,
- 0xb0b5, 0xb0cf,
- 0xb0d1, 0xb0eb,
- 0xb0ed, 0xb107,
- 0xb109, 0xb123,
- 0xb125, 0xb13f,
- 0xb141, 0xb15b,
- 0xb15d, 0xb177,
- 0xb179, 0xb193,
- 0xb195, 0xb1af,
- 0xb1b1, 0xb1cb,
- 0xb1cd, 0xb1e7,
- 0xb1e9, 0xb203,
- 0xb205, 0xb21f,
- 0xb221, 0xb23b,
- 0xb23d, 0xb257,
- 0xb259, 0xb273,
- 0xb275, 0xb28f,
- 0xb291, 0xb2ab,
- 0xb2ad, 0xb2c7,
- 0xb2c9, 0xb2e3,
- 0xb2e5, 0xb2ff,
- 0xb301, 0xb31b,
- 0xb31d, 0xb337,
- 0xb339, 0xb353,
- 0xb355, 0xb36f,
- 0xb371, 0xb38b,
- 0xb38d, 0xb3a7,
- 0xb3a9, 0xb3c3,
- 0xb3c5, 0xb3df,
- 0xb3e1, 0xb3fb,
- 0xb3fd, 0xb417,
- 0xb419, 0xb433,
- 0xb435, 0xb44f,
- 0xb451, 0xb46b,
- 0xb46d, 0xb487,
- 0xb489, 0xb4a3,
- 0xb4a5, 0xb4bf,
- 0xb4c1, 0xb4db,
- 0xb4dd, 0xb4f7,
- 0xb4f9, 0xb513,
- 0xb515, 0xb52f,
- 0xb531, 0xb54b,
- 0xb54d, 0xb567,
- 0xb569, 0xb583,
- 0xb585, 0xb59f,
- 0xb5a1, 0xb5bb,
- 0xb5bd, 0xb5d7,
- 0xb5d9, 0xb5f3,
- 0xb5f5, 0xb60f,
- 0xb611, 0xb62b,
- 0xb62d, 0xb647,
- 0xb649, 0xb663,
- 0xb665, 0xb67f,
- 0xb681, 0xb69b,
- 0xb69d, 0xb6b7,
- 0xb6b9, 0xb6d3,
- 0xb6d5, 0xb6ef,
- 0xb6f1, 0xb70b,
- 0xb70d, 0xb727,
- 0xb729, 0xb743,
- 0xb745, 0xb75f,
- 0xb761, 0xb77b,
- 0xb77d, 0xb797,
- 0xb799, 0xb7b3,
- 0xb7b5, 0xb7cf,
- 0xb7d1, 0xb7eb,
- 0xb7ed, 0xb807,
- 0xb809, 0xb823,
- 0xb825, 0xb83f,
- 0xb841, 0xb85b,
- 0xb85d, 0xb877,
- 0xb879, 0xb893,
- 0xb895, 0xb8af,
- 0xb8b1, 0xb8cb,
- 0xb8cd, 0xb8e7,
- 0xb8e9, 0xb903,
- 0xb905, 0xb91f,
- 0xb921, 0xb93b,
- 0xb93d, 0xb957,
- 0xb959, 0xb973,
- 0xb975, 0xb98f,
- 0xb991, 0xb9ab,
- 0xb9ad, 0xb9c7,
- 0xb9c9, 0xb9e3,
- 0xb9e5, 0xb9ff,
- 0xba01, 0xba1b,
- 0xba1d, 0xba37,
- 0xba39, 0xba53,
- 0xba55, 0xba6f,
- 0xba71, 0xba8b,
- 0xba8d, 0xbaa7,
- 0xbaa9, 0xbac3,
- 0xbac5, 0xbadf,
- 0xbae1, 0xbafb,
- 0xbafd, 0xbb17,
- 0xbb19, 0xbb33,
- 0xbb35, 0xbb4f,
- 0xbb51, 0xbb6b,
- 0xbb6d, 0xbb87,
- 0xbb89, 0xbba3,
- 0xbba5, 0xbbbf,
- 0xbbc1, 0xbbdb,
- 0xbbdd, 0xbbf7,
- 0xbbf9, 0xbc13,
- 0xbc15, 0xbc2f,
- 0xbc31, 0xbc4b,
- 0xbc4d, 0xbc67,
- 0xbc69, 0xbc83,
- 0xbc85, 0xbc9f,
- 0xbca1, 0xbcbb,
- 0xbcbd, 0xbcd7,
- 0xbcd9, 0xbcf3,
- 0xbcf5, 0xbd0f,
- 0xbd11, 0xbd2b,
- 0xbd2d, 0xbd47,
- 0xbd49, 0xbd63,
- 0xbd65, 0xbd7f,
- 0xbd81, 0xbd9b,
- 0xbd9d, 0xbdb7,
- 0xbdb9, 0xbdd3,
- 0xbdd5, 0xbdef,
- 0xbdf1, 0xbe0b,
- 0xbe0d, 0xbe27,
- 0xbe29, 0xbe43,
- 0xbe45, 0xbe5f,
- 0xbe61, 0xbe7b,
- 0xbe7d, 0xbe97,
- 0xbe99, 0xbeb3,
- 0xbeb5, 0xbecf,
- 0xbed1, 0xbeeb,
- 0xbeed, 0xbf07,
- 0xbf09, 0xbf23,
- 0xbf25, 0xbf3f,
- 0xbf41, 0xbf5b,
- 0xbf5d, 0xbf77,
- 0xbf79, 0xbf93,
- 0xbf95, 0xbfaf,
- 0xbfb1, 0xbfcb,
- 0xbfcd, 0xbfe7,
- 0xbfe9, 0xc003,
- 0xc005, 0xc01f,
- 0xc021, 0xc03b,
- 0xc03d, 0xc057,
- 0xc059, 0xc073,
- 0xc075, 0xc08f,
- 0xc091, 0xc0ab,
- 0xc0ad, 0xc0c7,
- 0xc0c9, 0xc0e3,
- 0xc0e5, 0xc0ff,
- 0xc101, 0xc11b,
- 0xc11d, 0xc137,
- 0xc139, 0xc153,
- 0xc155, 0xc16f,
- 0xc171, 0xc18b,
- 0xc18d, 0xc1a7,
- 0xc1a9, 0xc1c3,
- 0xc1c5, 0xc1df,
- 0xc1e1, 0xc1fb,
- 0xc1fd, 0xc217,
- 0xc219, 0xc233,
- 0xc235, 0xc24f,
- 0xc251, 0xc26b,
- 0xc26d, 0xc287,
- 0xc289, 0xc2a3,
- 0xc2a5, 0xc2bf,
- 0xc2c1, 0xc2db,
- 0xc2dd, 0xc2f7,
- 0xc2f9, 0xc313,
- 0xc315, 0xc32f,
- 0xc331, 0xc34b,
- 0xc34d, 0xc367,
- 0xc369, 0xc383,
- 0xc385, 0xc39f,
- 0xc3a1, 0xc3bb,
- 0xc3bd, 0xc3d7,
- 0xc3d9, 0xc3f3,
- 0xc3f5, 0xc40f,
- 0xc411, 0xc42b,
- 0xc42d, 0xc447,
- 0xc449, 0xc463,
- 0xc465, 0xc47f,
- 0xc481, 0xc49b,
- 0xc49d, 0xc4b7,
- 0xc4b9, 0xc4d3,
- 0xc4d5, 0xc4ef,
- 0xc4f1, 0xc50b,
- 0xc50d, 0xc527,
- 0xc529, 0xc543,
- 0xc545, 0xc55f,
- 0xc561, 0xc57b,
- 0xc57d, 0xc597,
- 0xc599, 0xc5b3,
- 0xc5b5, 0xc5cf,
- 0xc5d1, 0xc5eb,
- 0xc5ed, 0xc607,
- 0xc609, 0xc623,
- 0xc625, 0xc63f,
- 0xc641, 0xc65b,
- 0xc65d, 0xc677,
- 0xc679, 0xc693,
- 0xc695, 0xc6af,
- 0xc6b1, 0xc6cb,
- 0xc6cd, 0xc6e7,
- 0xc6e9, 0xc703,
- 0xc705, 0xc71f,
- 0xc721, 0xc73b,
- 0xc73d, 0xc757,
- 0xc759, 0xc773,
- 0xc775, 0xc78f,
- 0xc791, 0xc7ab,
- 0xc7ad, 0xc7c7,
- 0xc7c9, 0xc7e3,
- 0xc7e5, 0xc7ff,
- 0xc801, 0xc81b,
- 0xc81d, 0xc837,
- 0xc839, 0xc853,
- 0xc855, 0xc86f,
- 0xc871, 0xc88b,
- 0xc88d, 0xc8a7,
- 0xc8a9, 0xc8c3,
- 0xc8c5, 0xc8df,
- 0xc8e1, 0xc8fb,
- 0xc8fd, 0xc917,
- 0xc919, 0xc933,
- 0xc935, 0xc94f,
- 0xc951, 0xc96b,
- 0xc96d, 0xc987,
- 0xc989, 0xc9a3,
- 0xc9a5, 0xc9bf,
- 0xc9c1, 0xc9db,
- 0xc9dd, 0xc9f7,
- 0xc9f9, 0xca13,
- 0xca15, 0xca2f,
- 0xca31, 0xca4b,
- 0xca4d, 0xca67,
- 0xca69, 0xca83,
- 0xca85, 0xca9f,
- 0xcaa1, 0xcabb,
- 0xcabd, 0xcad7,
- 0xcad9, 0xcaf3,
- 0xcaf5, 0xcb0f,
- 0xcb11, 0xcb2b,
- 0xcb2d, 0xcb47,
- 0xcb49, 0xcb63,
- 0xcb65, 0xcb7f,
- 0xcb81, 0xcb9b,
- 0xcb9d, 0xcbb7,
- 0xcbb9, 0xcbd3,
- 0xcbd5, 0xcbef,
- 0xcbf1, 0xcc0b,
- 0xcc0d, 0xcc27,
- 0xcc29, 0xcc43,
- 0xcc45, 0xcc5f,
- 0xcc61, 0xcc7b,
- 0xcc7d, 0xcc97,
- 0xcc99, 0xccb3,
- 0xccb5, 0xcccf,
- 0xccd1, 0xcceb,
- 0xcced, 0xcd07,
- 0xcd09, 0xcd23,
- 0xcd25, 0xcd3f,
- 0xcd41, 0xcd5b,
- 0xcd5d, 0xcd77,
- 0xcd79, 0xcd93,
- 0xcd95, 0xcdaf,
- 0xcdb1, 0xcdcb,
- 0xcdcd, 0xcde7,
- 0xcde9, 0xce03,
- 0xce05, 0xce1f,
- 0xce21, 0xce3b,
- 0xce3d, 0xce57,
- 0xce59, 0xce73,
- 0xce75, 0xce8f,
- 0xce91, 0xceab,
- 0xcead, 0xcec7,
- 0xcec9, 0xcee3,
- 0xcee5, 0xceff,
- 0xcf01, 0xcf1b,
- 0xcf1d, 0xcf37,
- 0xcf39, 0xcf53,
- 0xcf55, 0xcf6f,
- 0xcf71, 0xcf8b,
- 0xcf8d, 0xcfa7,
- 0xcfa9, 0xcfc3,
- 0xcfc5, 0xcfdf,
- 0xcfe1, 0xcffb,
- 0xcffd, 0xd017,
- 0xd019, 0xd033,
- 0xd035, 0xd04f,
- 0xd051, 0xd06b,
- 0xd06d, 0xd087,
- 0xd089, 0xd0a3,
- 0xd0a5, 0xd0bf,
- 0xd0c1, 0xd0db,
- 0xd0dd, 0xd0f7,
- 0xd0f9, 0xd113,
- 0xd115, 0xd12f,
- 0xd131, 0xd14b,
- 0xd14d, 0xd167,
- 0xd169, 0xd183,
- 0xd185, 0xd19f,
- 0xd1a1, 0xd1bb,
- 0xd1bd, 0xd1d7,
- 0xd1d9, 0xd1f3,
- 0xd1f5, 0xd20f,
- 0xd211, 0xd22b,
- 0xd22d, 0xd247,
- 0xd249, 0xd263,
- 0xd265, 0xd27f,
- 0xd281, 0xd29b,
- 0xd29d, 0xd2b7,
- 0xd2b9, 0xd2d3,
- 0xd2d5, 0xd2ef,
- 0xd2f1, 0xd30b,
- 0xd30d, 0xd327,
- 0xd329, 0xd343,
- 0xd345, 0xd35f,
- 0xd361, 0xd37b,
- 0xd37d, 0xd397,
- 0xd399, 0xd3b3,
- 0xd3b5, 0xd3cf,
- 0xd3d1, 0xd3eb,
- 0xd3ed, 0xd407,
- 0xd409, 0xd423,
- 0xd425, 0xd43f,
- 0xd441, 0xd45b,
- 0xd45d, 0xd477,
- 0xd479, 0xd493,
- 0xd495, 0xd4af,
- 0xd4b1, 0xd4cb,
- 0xd4cd, 0xd4e7,
- 0xd4e9, 0xd503,
- 0xd505, 0xd51f,
- 0xd521, 0xd53b,
- 0xd53d, 0xd557,
- 0xd559, 0xd573,
- 0xd575, 0xd58f,
- 0xd591, 0xd5ab,
- 0xd5ad, 0xd5c7,
- 0xd5c9, 0xd5e3,
- 0xd5e5, 0xd5ff,
- 0xd601, 0xd61b,
- 0xd61d, 0xd637,
- 0xd639, 0xd653,
- 0xd655, 0xd66f,
- 0xd671, 0xd68b,
- 0xd68d, 0xd6a7,
- 0xd6a9, 0xd6c3,
- 0xd6c5, 0xd6df,
- 0xd6e1, 0xd6fb,
- 0xd6fd, 0xd717,
- 0xd719, 0xd733,
- 0xd735, 0xd74f,
- 0xd751, 0xd76b,
- 0xd76d, 0xd787,
- 0xd789, 0xd7a3,
-}; /* CR_Grapheme_Cluster_Break_LVT */
-
-/* 'Grapheme_Cluster_Break_E_Base': Grapheme_Cluster_Break=E_Base */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_E_Base[] = {
- 31,
- 0x261d, 0x261d,
- 0x26f9, 0x26f9,
- 0x270a, 0x270d,
- 0x1f385, 0x1f385,
- 0x1f3c2, 0x1f3c4,
- 0x1f3c7, 0x1f3c7,
- 0x1f3ca, 0x1f3cc,
- 0x1f442, 0x1f443,
- 0x1f446, 0x1f450,
- 0x1f46e, 0x1f46e,
- 0x1f470, 0x1f478,
- 0x1f47c, 0x1f47c,
- 0x1f481, 0x1f483,
- 0x1f485, 0x1f487,
- 0x1f4aa, 0x1f4aa,
- 0x1f574, 0x1f575,
- 0x1f57a, 0x1f57a,
- 0x1f590, 0x1f590,
- 0x1f595, 0x1f596,
- 0x1f645, 0x1f647,
- 0x1f64b, 0x1f64f,
- 0x1f6a3, 0x1f6a3,
- 0x1f6b4, 0x1f6b6,
- 0x1f6c0, 0x1f6c0,
- 0x1f6cc, 0x1f6cc,
- 0x1f918, 0x1f91c,
- 0x1f91e, 0x1f91f,
- 0x1f926, 0x1f926,
- 0x1f930, 0x1f939,
- 0x1f93d, 0x1f93e,
- 0x1f9d1, 0x1f9dd,
-}; /* CR_Grapheme_Cluster_Break_E_Base */
-
-/* 'Grapheme_Cluster_Break_E_Modifier': Grapheme_Cluster_Break=E_Modifier */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_E_Modifier[] = {
- 1,
- 0x1f3fb, 0x1f3ff,
-}; /* CR_Grapheme_Cluster_Break_E_Modifier */
-
-/* 'Grapheme_Cluster_Break_ZWJ': Grapheme_Cluster_Break=ZWJ */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_ZWJ[] = {
- 1,
- 0x200d, 0x200d,
-}; /* CR_Grapheme_Cluster_Break_ZWJ */
-
-/* 'Grapheme_Cluster_Break_Glue_After_Zwj': Grapheme_Cluster_Break=Glue_After_Zwj */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_Glue_After_Zwj[] = {
- 20,
- 0x2640, 0x2640,
- 0x2642, 0x2642,
- 0x2695, 0x2696,
- 0x2708, 0x2708,
- 0x2764, 0x2764,
- 0x1f308, 0x1f308,
- 0x1f33e, 0x1f33e,
- 0x1f373, 0x1f373,
- 0x1f393, 0x1f393,
- 0x1f3a4, 0x1f3a4,
- 0x1f3a8, 0x1f3a8,
- 0x1f3eb, 0x1f3eb,
- 0x1f3ed, 0x1f3ed,
- 0x1f48b, 0x1f48b,
- 0x1f4bb, 0x1f4bc,
- 0x1f527, 0x1f527,
- 0x1f52c, 0x1f52c,
- 0x1f5e8, 0x1f5e8,
- 0x1f680, 0x1f680,
- 0x1f692, 0x1f692,
-}; /* CR_Grapheme_Cluster_Break_Glue_After_Zwj */
-
-/* 'Grapheme_Cluster_Break_E_Base_GAZ': Grapheme_Cluster_Break=E_Base_GAZ */
-static const OnigCodePoint CR_Grapheme_Cluster_Break_E_Base_GAZ[] = {
- 1,
- 0x1f466, 0x1f469,
-}; /* CR_Grapheme_Cluster_Break_E_Base_GAZ */
-
-/* 'In_Basic_Latin': Block */
-#define CR_In_Basic_Latin CR_ASCII
-
-/* 'In_Latin_1_Supplement': Block */
-static const OnigCodePoint CR_In_Latin_1_Supplement[] = {
- 1,
- 0x0080, 0x00ff,
-}; /* CR_In_Latin_1_Supplement */
-
-/* 'In_Latin_Extended_A': Block */
-static const OnigCodePoint CR_In_Latin_Extended_A[] = {
- 1,
- 0x0100, 0x017f,
-}; /* CR_In_Latin_Extended_A */
-
-/* 'In_Latin_Extended_B': Block */
-static const OnigCodePoint CR_In_Latin_Extended_B[] = {
- 1,
- 0x0180, 0x024f,
-}; /* CR_In_Latin_Extended_B */
-
-/* 'In_IPA_Extensions': Block */
-static const OnigCodePoint CR_In_IPA_Extensions[] = {
- 1,
- 0x0250, 0x02af,
-}; /* CR_In_IPA_Extensions */
-
-/* 'In_Spacing_Modifier_Letters': Block */
-static const OnigCodePoint CR_In_Spacing_Modifier_Letters[] = {
- 1,
- 0x02b0, 0x02ff,
-}; /* CR_In_Spacing_Modifier_Letters */
-
-/* 'In_Combining_Diacritical_Marks': Block */
-static const OnigCodePoint CR_In_Combining_Diacritical_Marks[] = {
- 1,
- 0x0300, 0x036f,
-}; /* CR_In_Combining_Diacritical_Marks */
-
-/* 'In_Greek_and_Coptic': Block */
-static const OnigCodePoint CR_In_Greek_and_Coptic[] = {
- 1,
- 0x0370, 0x03ff,
-}; /* CR_In_Greek_and_Coptic */
-
-/* 'In_Cyrillic': Block */
-static const OnigCodePoint CR_In_Cyrillic[] = {
- 1,
- 0x0400, 0x04ff,
-}; /* CR_In_Cyrillic */
-
-/* 'In_Cyrillic_Supplement': Block */
-static const OnigCodePoint CR_In_Cyrillic_Supplement[] = {
- 1,
- 0x0500, 0x052f,
-}; /* CR_In_Cyrillic_Supplement */
-
-/* 'In_Armenian': Block */
-static const OnigCodePoint CR_In_Armenian[] = {
- 1,
- 0x0530, 0x058f,
-}; /* CR_In_Armenian */
-
-/* 'In_Hebrew': Block */
-static const OnigCodePoint CR_In_Hebrew[] = {
- 1,
- 0x0590, 0x05ff,
-}; /* CR_In_Hebrew */
-
-/* 'In_Arabic': Block */
-static const OnigCodePoint CR_In_Arabic[] = {
- 1,
- 0x0600, 0x06ff,
-}; /* CR_In_Arabic */
-
-/* 'In_Syriac': Block */
-static const OnigCodePoint CR_In_Syriac[] = {
- 1,
- 0x0700, 0x074f,
-}; /* CR_In_Syriac */
-
-/* 'In_Arabic_Supplement': Block */
-static const OnigCodePoint CR_In_Arabic_Supplement[] = {
- 1,
- 0x0750, 0x077f,
-}; /* CR_In_Arabic_Supplement */
-
-/* 'In_Thaana': Block */
-static const OnigCodePoint CR_In_Thaana[] = {
- 1,
- 0x0780, 0x07bf,
-}; /* CR_In_Thaana */
-
-/* 'In_NKo': Block */
-static const OnigCodePoint CR_In_NKo[] = {
- 1,
- 0x07c0, 0x07ff,
-}; /* CR_In_NKo */
-
-/* 'In_Samaritan': Block */
-static const OnigCodePoint CR_In_Samaritan[] = {
- 1,
- 0x0800, 0x083f,
-}; /* CR_In_Samaritan */
-
-/* 'In_Mandaic': Block */
-static const OnigCodePoint CR_In_Mandaic[] = {
- 1,
- 0x0840, 0x085f,
-}; /* CR_In_Mandaic */
-
-/* 'In_Syriac_Supplement': Block */
-static const OnigCodePoint CR_In_Syriac_Supplement[] = {
- 1,
- 0x0860, 0x086f,
-}; /* CR_In_Syriac_Supplement */
-
-/* 'In_Arabic_Extended_A': Block */
-static const OnigCodePoint CR_In_Arabic_Extended_A[] = {
- 1,
- 0x08a0, 0x08ff,
-}; /* CR_In_Arabic_Extended_A */
-
-/* 'In_Devanagari': Block */
-static const OnigCodePoint CR_In_Devanagari[] = {
- 1,
- 0x0900, 0x097f,
-}; /* CR_In_Devanagari */
-
-/* 'In_Bengali': Block */
-static const OnigCodePoint CR_In_Bengali[] = {
- 1,
- 0x0980, 0x09ff,
-}; /* CR_In_Bengali */
-
-/* 'In_Gurmukhi': Block */
-static const OnigCodePoint CR_In_Gurmukhi[] = {
- 1,
- 0x0a00, 0x0a7f,
-}; /* CR_In_Gurmukhi */
-
-/* 'In_Gujarati': Block */
-static const OnigCodePoint CR_In_Gujarati[] = {
- 1,
- 0x0a80, 0x0aff,
-}; /* CR_In_Gujarati */
-
-/* 'In_Oriya': Block */
-static const OnigCodePoint CR_In_Oriya[] = {
- 1,
- 0x0b00, 0x0b7f,
-}; /* CR_In_Oriya */
-
-/* 'In_Tamil': Block */
-static const OnigCodePoint CR_In_Tamil[] = {
- 1,
- 0x0b80, 0x0bff,
-}; /* CR_In_Tamil */
-
-/* 'In_Telugu': Block */
-static const OnigCodePoint CR_In_Telugu[] = {
- 1,
- 0x0c00, 0x0c7f,
-}; /* CR_In_Telugu */
-
-/* 'In_Kannada': Block */
-static const OnigCodePoint CR_In_Kannada[] = {
- 1,
- 0x0c80, 0x0cff,
-}; /* CR_In_Kannada */
-
-/* 'In_Malayalam': Block */
-static const OnigCodePoint CR_In_Malayalam[] = {
- 1,
- 0x0d00, 0x0d7f,
-}; /* CR_In_Malayalam */
-
-/* 'In_Sinhala': Block */
-static const OnigCodePoint CR_In_Sinhala[] = {
- 1,
- 0x0d80, 0x0dff,
-}; /* CR_In_Sinhala */
-
-/* 'In_Thai': Block */
-static const OnigCodePoint CR_In_Thai[] = {
- 1,
- 0x0e00, 0x0e7f,
-}; /* CR_In_Thai */
-
-/* 'In_Lao': Block */
-static const OnigCodePoint CR_In_Lao[] = {
- 1,
- 0x0e80, 0x0eff,
-}; /* CR_In_Lao */
-
-/* 'In_Tibetan': Block */
-static const OnigCodePoint CR_In_Tibetan[] = {
- 1,
- 0x0f00, 0x0fff,
-}; /* CR_In_Tibetan */
-
-/* 'In_Myanmar': Block */
-static const OnigCodePoint CR_In_Myanmar[] = {
- 1,
- 0x1000, 0x109f,
-}; /* CR_In_Myanmar */
-
-/* 'In_Georgian': Block */
-static const OnigCodePoint CR_In_Georgian[] = {
- 1,
- 0x10a0, 0x10ff,
-}; /* CR_In_Georgian */
-
-/* 'In_Hangul_Jamo': Block */
-static const OnigCodePoint CR_In_Hangul_Jamo[] = {
- 1,
- 0x1100, 0x11ff,
-}; /* CR_In_Hangul_Jamo */
-
-/* 'In_Ethiopic': Block */
-static const OnigCodePoint CR_In_Ethiopic[] = {
- 1,
- 0x1200, 0x137f,
-}; /* CR_In_Ethiopic */
-
-/* 'In_Ethiopic_Supplement': Block */
-static const OnigCodePoint CR_In_Ethiopic_Supplement[] = {
- 1,
- 0x1380, 0x139f,
-}; /* CR_In_Ethiopic_Supplement */
-
-/* 'In_Cherokee': Block */
-static const OnigCodePoint CR_In_Cherokee[] = {
- 1,
- 0x13a0, 0x13ff,
-}; /* CR_In_Cherokee */
-
-/* 'In_Unified_Canadian_Aboriginal_Syllabics': Block */
-static const OnigCodePoint CR_In_Unified_Canadian_Aboriginal_Syllabics[] = {
- 1,
- 0x1400, 0x167f,
-}; /* CR_In_Unified_Canadian_Aboriginal_Syllabics */
-
-/* 'In_Ogham': Block */
-static const OnigCodePoint CR_In_Ogham[] = {
- 1,
- 0x1680, 0x169f,
-}; /* CR_In_Ogham */
-
-/* 'In_Runic': Block */
-static const OnigCodePoint CR_In_Runic[] = {
- 1,
- 0x16a0, 0x16ff,
-}; /* CR_In_Runic */
-
-/* 'In_Tagalog': Block */
-static const OnigCodePoint CR_In_Tagalog[] = {
- 1,
- 0x1700, 0x171f,
-}; /* CR_In_Tagalog */
-
-/* 'In_Hanunoo': Block */
-static const OnigCodePoint CR_In_Hanunoo[] = {
- 1,
- 0x1720, 0x173f,
-}; /* CR_In_Hanunoo */
-
-/* 'In_Buhid': Block */
-static const OnigCodePoint CR_In_Buhid[] = {
- 1,
- 0x1740, 0x175f,
-}; /* CR_In_Buhid */
-
-/* 'In_Tagbanwa': Block */
-static const OnigCodePoint CR_In_Tagbanwa[] = {
- 1,
- 0x1760, 0x177f,
-}; /* CR_In_Tagbanwa */
-
-/* 'In_Khmer': Block */
-static const OnigCodePoint CR_In_Khmer[] = {
- 1,
- 0x1780, 0x17ff,
-}; /* CR_In_Khmer */
-
-/* 'In_Mongolian': Block */
-static const OnigCodePoint CR_In_Mongolian[] = {
- 1,
- 0x1800, 0x18af,
-}; /* CR_In_Mongolian */
-
-/* 'In_Unified_Canadian_Aboriginal_Syllabics_Extended': Block */
-static const OnigCodePoint CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended[] = {
- 1,
- 0x18b0, 0x18ff,
-}; /* CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended */
-
-/* 'In_Limbu': Block */
-static const OnigCodePoint CR_In_Limbu[] = {
- 1,
- 0x1900, 0x194f,
-}; /* CR_In_Limbu */
-
-/* 'In_Tai_Le': Block */
-static const OnigCodePoint CR_In_Tai_Le[] = {
- 1,
- 0x1950, 0x197f,
-}; /* CR_In_Tai_Le */
-
-/* 'In_New_Tai_Lue': Block */
-static const OnigCodePoint CR_In_New_Tai_Lue[] = {
- 1,
- 0x1980, 0x19df,
-}; /* CR_In_New_Tai_Lue */
-
-/* 'In_Khmer_Symbols': Block */
-static const OnigCodePoint CR_In_Khmer_Symbols[] = {
- 1,
- 0x19e0, 0x19ff,
-}; /* CR_In_Khmer_Symbols */
-
-/* 'In_Buginese': Block */
-static const OnigCodePoint CR_In_Buginese[] = {
- 1,
- 0x1a00, 0x1a1f,
-}; /* CR_In_Buginese */
-
-/* 'In_Tai_Tham': Block */
-static const OnigCodePoint CR_In_Tai_Tham[] = {
- 1,
- 0x1a20, 0x1aaf,
-}; /* CR_In_Tai_Tham */
-
-/* 'In_Combining_Diacritical_Marks_Extended': Block */
-static const OnigCodePoint CR_In_Combining_Diacritical_Marks_Extended[] = {
- 1,
- 0x1ab0, 0x1aff,
-}; /* CR_In_Combining_Diacritical_Marks_Extended */
-
-/* 'In_Balinese': Block */
-static const OnigCodePoint CR_In_Balinese[] = {
- 1,
- 0x1b00, 0x1b7f,
-}; /* CR_In_Balinese */
-
-/* 'In_Sundanese': Block */
-static const OnigCodePoint CR_In_Sundanese[] = {
- 1,
- 0x1b80, 0x1bbf,
-}; /* CR_In_Sundanese */
-
-/* 'In_Batak': Block */
-static const OnigCodePoint CR_In_Batak[] = {
- 1,
- 0x1bc0, 0x1bff,
-}; /* CR_In_Batak */
-
-/* 'In_Lepcha': Block */
-static const OnigCodePoint CR_In_Lepcha[] = {
- 1,
- 0x1c00, 0x1c4f,
-}; /* CR_In_Lepcha */
-
-/* 'In_Ol_Chiki': Block */
-#define CR_In_Ol_Chiki CR_Ol_Chiki
-
-/* 'In_Cyrillic_Extended_C': Block */
-static const OnigCodePoint CR_In_Cyrillic_Extended_C[] = {
- 1,
- 0x1c80, 0x1c8f,
-}; /* CR_In_Cyrillic_Extended_C */
-
-/* 'In_Sundanese_Supplement': Block */
-static const OnigCodePoint CR_In_Sundanese_Supplement[] = {
- 1,
- 0x1cc0, 0x1ccf,
-}; /* CR_In_Sundanese_Supplement */
-
-/* 'In_Vedic_Extensions': Block */
-static const OnigCodePoint CR_In_Vedic_Extensions[] = {
- 1,
- 0x1cd0, 0x1cff,
-}; /* CR_In_Vedic_Extensions */
-
-/* 'In_Phonetic_Extensions': Block */
-static const OnigCodePoint CR_In_Phonetic_Extensions[] = {
- 1,
- 0x1d00, 0x1d7f,
-}; /* CR_In_Phonetic_Extensions */
-
-/* 'In_Phonetic_Extensions_Supplement': Block */
-static const OnigCodePoint CR_In_Phonetic_Extensions_Supplement[] = {
- 1,
- 0x1d80, 0x1dbf,
-}; /* CR_In_Phonetic_Extensions_Supplement */
-
-/* 'In_Combining_Diacritical_Marks_Supplement': Block */
-static const OnigCodePoint CR_In_Combining_Diacritical_Marks_Supplement[] = {
- 1,
- 0x1dc0, 0x1dff,
-}; /* CR_In_Combining_Diacritical_Marks_Supplement */
-
-/* 'In_Latin_Extended_Additional': Block */
-static const OnigCodePoint CR_In_Latin_Extended_Additional[] = {
- 1,
- 0x1e00, 0x1eff,
-}; /* CR_In_Latin_Extended_Additional */
-
-/* 'In_Greek_Extended': Block */
-static const OnigCodePoint CR_In_Greek_Extended[] = {
- 1,
- 0x1f00, 0x1fff,
-}; /* CR_In_Greek_Extended */
-
-/* 'In_General_Punctuation': Block */
-static const OnigCodePoint CR_In_General_Punctuation[] = {
- 1,
- 0x2000, 0x206f,
-}; /* CR_In_General_Punctuation */
-
-/* 'In_Superscripts_and_Subscripts': Block */
-static const OnigCodePoint CR_In_Superscripts_and_Subscripts[] = {
- 1,
- 0x2070, 0x209f,
-}; /* CR_In_Superscripts_and_Subscripts */
-
-/* 'In_Currency_Symbols': Block */
-static const OnigCodePoint CR_In_Currency_Symbols[] = {
- 1,
- 0x20a0, 0x20cf,
-}; /* CR_In_Currency_Symbols */
-
-/* 'In_Combining_Diacritical_Marks_for_Symbols': Block */
-static const OnigCodePoint CR_In_Combining_Diacritical_Marks_for_Symbols[] = {
- 1,
- 0x20d0, 0x20ff,
-}; /* CR_In_Combining_Diacritical_Marks_for_Symbols */
-
-/* 'In_Letterlike_Symbols': Block */
-static const OnigCodePoint CR_In_Letterlike_Symbols[] = {
- 1,
- 0x2100, 0x214f,
-}; /* CR_In_Letterlike_Symbols */
-
-/* 'In_Number_Forms': Block */
-static const OnigCodePoint CR_In_Number_Forms[] = {
- 1,
- 0x2150, 0x218f,
-}; /* CR_In_Number_Forms */
-
-/* 'In_Arrows': Block */
-static const OnigCodePoint CR_In_Arrows[] = {
- 1,
- 0x2190, 0x21ff,
-}; /* CR_In_Arrows */
-
-/* 'In_Mathematical_Operators': Block */
-static const OnigCodePoint CR_In_Mathematical_Operators[] = {
- 1,
- 0x2200, 0x22ff,
-}; /* CR_In_Mathematical_Operators */
-
-/* 'In_Miscellaneous_Technical': Block */
-static const OnigCodePoint CR_In_Miscellaneous_Technical[] = {
- 1,
- 0x2300, 0x23ff,
-}; /* CR_In_Miscellaneous_Technical */
-
-/* 'In_Control_Pictures': Block */
-static const OnigCodePoint CR_In_Control_Pictures[] = {
- 1,
- 0x2400, 0x243f,
-}; /* CR_In_Control_Pictures */
-
-/* 'In_Optical_Character_Recognition': Block */
-static const OnigCodePoint CR_In_Optical_Character_Recognition[] = {
- 1,
- 0x2440, 0x245f,
-}; /* CR_In_Optical_Character_Recognition */
-
-/* 'In_Enclosed_Alphanumerics': Block */
-static const OnigCodePoint CR_In_Enclosed_Alphanumerics[] = {
- 1,
- 0x2460, 0x24ff,
-}; /* CR_In_Enclosed_Alphanumerics */
-
-/* 'In_Box_Drawing': Block */
-static const OnigCodePoint CR_In_Box_Drawing[] = {
- 1,
- 0x2500, 0x257f,
-}; /* CR_In_Box_Drawing */
-
-/* 'In_Block_Elements': Block */
-static const OnigCodePoint CR_In_Block_Elements[] = {
- 1,
- 0x2580, 0x259f,
-}; /* CR_In_Block_Elements */
-
-/* 'In_Geometric_Shapes': Block */
-static const OnigCodePoint CR_In_Geometric_Shapes[] = {
- 1,
- 0x25a0, 0x25ff,
-}; /* CR_In_Geometric_Shapes */
-
-/* 'In_Miscellaneous_Symbols': Block */
-static const OnigCodePoint CR_In_Miscellaneous_Symbols[] = {
- 1,
- 0x2600, 0x26ff,
-}; /* CR_In_Miscellaneous_Symbols */
-
-/* 'In_Dingbats': Block */
-static const OnigCodePoint CR_In_Dingbats[] = {
- 1,
- 0x2700, 0x27bf,
-}; /* CR_In_Dingbats */
-
-/* 'In_Miscellaneous_Mathematical_Symbols_A': Block */
-static const OnigCodePoint CR_In_Miscellaneous_Mathematical_Symbols_A[] = {
- 1,
- 0x27c0, 0x27ef,
-}; /* CR_In_Miscellaneous_Mathematical_Symbols_A */
-
-/* 'In_Supplemental_Arrows_A': Block */
-static const OnigCodePoint CR_In_Supplemental_Arrows_A[] = {
- 1,
- 0x27f0, 0x27ff,
-}; /* CR_In_Supplemental_Arrows_A */
-
-/* 'In_Braille_Patterns': Block */
-#define CR_In_Braille_Patterns CR_Braille
-
-/* 'In_Supplemental_Arrows_B': Block */
-static const OnigCodePoint CR_In_Supplemental_Arrows_B[] = {
- 1,
- 0x2900, 0x297f,
-}; /* CR_In_Supplemental_Arrows_B */
-
-/* 'In_Miscellaneous_Mathematical_Symbols_B': Block */
-static const OnigCodePoint CR_In_Miscellaneous_Mathematical_Symbols_B[] = {
- 1,
- 0x2980, 0x29ff,
-}; /* CR_In_Miscellaneous_Mathematical_Symbols_B */
-
-/* 'In_Supplemental_Mathematical_Operators': Block */
-static const OnigCodePoint CR_In_Supplemental_Mathematical_Operators[] = {
- 1,
- 0x2a00, 0x2aff,
-}; /* CR_In_Supplemental_Mathematical_Operators */
-
-/* 'In_Miscellaneous_Symbols_and_Arrows': Block */
-static const OnigCodePoint CR_In_Miscellaneous_Symbols_and_Arrows[] = {
- 1,
- 0x2b00, 0x2bff,
-}; /* CR_In_Miscellaneous_Symbols_and_Arrows */
-
-/* 'In_Glagolitic': Block */
-static const OnigCodePoint CR_In_Glagolitic[] = {
- 1,
- 0x2c00, 0x2c5f,
-}; /* CR_In_Glagolitic */
-
-/* 'In_Latin_Extended_C': Block */
-static const OnigCodePoint CR_In_Latin_Extended_C[] = {
- 1,
- 0x2c60, 0x2c7f,
-}; /* CR_In_Latin_Extended_C */
-
-/* 'In_Coptic': Block */
-static const OnigCodePoint CR_In_Coptic[] = {
- 1,
- 0x2c80, 0x2cff,
-}; /* CR_In_Coptic */
-
-/* 'In_Georgian_Supplement': Block */
-static const OnigCodePoint CR_In_Georgian_Supplement[] = {
- 1,
- 0x2d00, 0x2d2f,
-}; /* CR_In_Georgian_Supplement */
-
-/* 'In_Tifinagh': Block */
-static const OnigCodePoint CR_In_Tifinagh[] = {
- 1,
- 0x2d30, 0x2d7f,
-}; /* CR_In_Tifinagh */
-
-/* 'In_Ethiopic_Extended': Block */
-static const OnigCodePoint CR_In_Ethiopic_Extended[] = {
- 1,
- 0x2d80, 0x2ddf,
-}; /* CR_In_Ethiopic_Extended */
-
-/* 'In_Cyrillic_Extended_A': Block */
-static const OnigCodePoint CR_In_Cyrillic_Extended_A[] = {
- 1,
- 0x2de0, 0x2dff,
-}; /* CR_In_Cyrillic_Extended_A */
-
-/* 'In_Supplemental_Punctuation': Block */
-static const OnigCodePoint CR_In_Supplemental_Punctuation[] = {
- 1,
- 0x2e00, 0x2e7f,
-}; /* CR_In_Supplemental_Punctuation */
-
-/* 'In_CJK_Radicals_Supplement': Block */
-static const OnigCodePoint CR_In_CJK_Radicals_Supplement[] = {
- 1,
- 0x2e80, 0x2eff,
-}; /* CR_In_CJK_Radicals_Supplement */
-
-/* 'In_Kangxi_Radicals': Block */
-static const OnigCodePoint CR_In_Kangxi_Radicals[] = {
- 1,
- 0x2f00, 0x2fdf,
-}; /* CR_In_Kangxi_Radicals */
-
-/* 'In_Ideographic_Description_Characters': Block */
-static const OnigCodePoint CR_In_Ideographic_Description_Characters[] = {
- 1,
- 0x2ff0, 0x2fff,
-}; /* CR_In_Ideographic_Description_Characters */
-
-/* 'In_CJK_Symbols_and_Punctuation': Block */
-static const OnigCodePoint CR_In_CJK_Symbols_and_Punctuation[] = {
- 1,
- 0x3000, 0x303f,
-}; /* CR_In_CJK_Symbols_and_Punctuation */
-
-/* 'In_Hiragana': Block */
-static const OnigCodePoint CR_In_Hiragana[] = {
- 1,
- 0x3040, 0x309f,
-}; /* CR_In_Hiragana */
-
-/* 'In_Katakana': Block */
-static const OnigCodePoint CR_In_Katakana[] = {
- 1,
- 0x30a0, 0x30ff,
-}; /* CR_In_Katakana */
-
-/* 'In_Bopomofo': Block */
-static const OnigCodePoint CR_In_Bopomofo[] = {
- 1,
- 0x3100, 0x312f,
-}; /* CR_In_Bopomofo */
-
-/* 'In_Hangul_Compatibility_Jamo': Block */
-static const OnigCodePoint CR_In_Hangul_Compatibility_Jamo[] = {
- 1,
- 0x3130, 0x318f,
-}; /* CR_In_Hangul_Compatibility_Jamo */
-
-/* 'In_Kanbun': Block */
-static const OnigCodePoint CR_In_Kanbun[] = {
- 1,
- 0x3190, 0x319f,
-}; /* CR_In_Kanbun */
-
-/* 'In_Bopomofo_Extended': Block */
-static const OnigCodePoint CR_In_Bopomofo_Extended[] = {
- 1,
- 0x31a0, 0x31bf,
-}; /* CR_In_Bopomofo_Extended */
-
-/* 'In_CJK_Strokes': Block */
-static const OnigCodePoint CR_In_CJK_Strokes[] = {
- 1,
- 0x31c0, 0x31ef,
-}; /* CR_In_CJK_Strokes */
-
-/* 'In_Katakana_Phonetic_Extensions': Block */
-static const OnigCodePoint CR_In_Katakana_Phonetic_Extensions[] = {
- 1,
- 0x31f0, 0x31ff,
-}; /* CR_In_Katakana_Phonetic_Extensions */
-
-/* 'In_Enclosed_CJK_Letters_and_Months': Block */
-static const OnigCodePoint CR_In_Enclosed_CJK_Letters_and_Months[] = {
- 1,
- 0x3200, 0x32ff,
-}; /* CR_In_Enclosed_CJK_Letters_and_Months */
-
-/* 'In_CJK_Compatibility': Block */
-static const OnigCodePoint CR_In_CJK_Compatibility[] = {
- 1,
- 0x3300, 0x33ff,
-}; /* CR_In_CJK_Compatibility */
-
-/* 'In_CJK_Unified_Ideographs_Extension_A': Block */
-static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_A[] = {
- 1,
- 0x3400, 0x4dbf,
-}; /* CR_In_CJK_Unified_Ideographs_Extension_A */
-
-/* 'In_Yijing_Hexagram_Symbols': Block */
-static const OnigCodePoint CR_In_Yijing_Hexagram_Symbols[] = {
- 1,
- 0x4dc0, 0x4dff,
-}; /* CR_In_Yijing_Hexagram_Symbols */
-
-/* 'In_CJK_Unified_Ideographs': Block */
-static const OnigCodePoint CR_In_CJK_Unified_Ideographs[] = {
- 1,
- 0x4e00, 0x9fff,
-}; /* CR_In_CJK_Unified_Ideographs */
-
-/* 'In_Yi_Syllables': Block */
-static const OnigCodePoint CR_In_Yi_Syllables[] = {
- 1,
- 0xa000, 0xa48f,
-}; /* CR_In_Yi_Syllables */
-
-/* 'In_Yi_Radicals': Block */
-static const OnigCodePoint CR_In_Yi_Radicals[] = {
- 1,
- 0xa490, 0xa4cf,
-}; /* CR_In_Yi_Radicals */
-
-/* 'In_Lisu': Block */
-#define CR_In_Lisu CR_Lisu
-
-/* 'In_Vai': Block */
-static const OnigCodePoint CR_In_Vai[] = {
- 1,
- 0xa500, 0xa63f,
-}; /* CR_In_Vai */
-
-/* 'In_Cyrillic_Extended_B': Block */
-static const OnigCodePoint CR_In_Cyrillic_Extended_B[] = {
- 1,
- 0xa640, 0xa69f,
-}; /* CR_In_Cyrillic_Extended_B */
-
-/* 'In_Bamum': Block */
-static const OnigCodePoint CR_In_Bamum[] = {
- 1,
- 0xa6a0, 0xa6ff,
-}; /* CR_In_Bamum */
-
-/* 'In_Modifier_Tone_Letters': Block */
-static const OnigCodePoint CR_In_Modifier_Tone_Letters[] = {
- 1,
- 0xa700, 0xa71f,
-}; /* CR_In_Modifier_Tone_Letters */
-
-/* 'In_Latin_Extended_D': Block */
-static const OnigCodePoint CR_In_Latin_Extended_D[] = {
- 1,
- 0xa720, 0xa7ff,
-}; /* CR_In_Latin_Extended_D */
-
-/* 'In_Syloti_Nagri': Block */
-static const OnigCodePoint CR_In_Syloti_Nagri[] = {
- 1,
- 0xa800, 0xa82f,
-}; /* CR_In_Syloti_Nagri */
-
-/* 'In_Common_Indic_Number_Forms': Block */
-static const OnigCodePoint CR_In_Common_Indic_Number_Forms[] = {
- 1,
- 0xa830, 0xa83f,
-}; /* CR_In_Common_Indic_Number_Forms */
-
-/* 'In_Phags_pa': Block */
-static const OnigCodePoint CR_In_Phags_pa[] = {
- 1,
- 0xa840, 0xa87f,
-}; /* CR_In_Phags_pa */
-
-/* 'In_Saurashtra': Block */
-static const OnigCodePoint CR_In_Saurashtra[] = {
- 1,
- 0xa880, 0xa8df,
-}; /* CR_In_Saurashtra */
-
-/* 'In_Devanagari_Extended': Block */
-static const OnigCodePoint CR_In_Devanagari_Extended[] = {
- 1,
- 0xa8e0, 0xa8ff,
-}; /* CR_In_Devanagari_Extended */
-
-/* 'In_Kayah_Li': Block */
-static const OnigCodePoint CR_In_Kayah_Li[] = {
- 1,
- 0xa900, 0xa92f,
-}; /* CR_In_Kayah_Li */
-
-/* 'In_Rejang': Block */
-static const OnigCodePoint CR_In_Rejang[] = {
- 1,
- 0xa930, 0xa95f,
-}; /* CR_In_Rejang */
-
-/* 'In_Hangul_Jamo_Extended_A': Block */
-static const OnigCodePoint CR_In_Hangul_Jamo_Extended_A[] = {
- 1,
- 0xa960, 0xa97f,
-}; /* CR_In_Hangul_Jamo_Extended_A */
-
-/* 'In_Javanese': Block */
-static const OnigCodePoint CR_In_Javanese[] = {
- 1,
- 0xa980, 0xa9df,
-}; /* CR_In_Javanese */
-
-/* 'In_Myanmar_Extended_B': Block */
-static const OnigCodePoint CR_In_Myanmar_Extended_B[] = {
- 1,
- 0xa9e0, 0xa9ff,
-}; /* CR_In_Myanmar_Extended_B */
-
-/* 'In_Cham': Block */
-static const OnigCodePoint CR_In_Cham[] = {
- 1,
- 0xaa00, 0xaa5f,
-}; /* CR_In_Cham */
-
-/* 'In_Myanmar_Extended_A': Block */
-static const OnigCodePoint CR_In_Myanmar_Extended_A[] = {
- 1,
- 0xaa60, 0xaa7f,
-}; /* CR_In_Myanmar_Extended_A */
-
-/* 'In_Tai_Viet': Block */
-static const OnigCodePoint CR_In_Tai_Viet[] = {
- 1,
- 0xaa80, 0xaadf,
-}; /* CR_In_Tai_Viet */
-
-/* 'In_Meetei_Mayek_Extensions': Block */
-static const OnigCodePoint CR_In_Meetei_Mayek_Extensions[] = {
- 1,
- 0xaae0, 0xaaff,
-}; /* CR_In_Meetei_Mayek_Extensions */
-
-/* 'In_Ethiopic_Extended_A': Block */
-static const OnigCodePoint CR_In_Ethiopic_Extended_A[] = {
- 1,
- 0xab00, 0xab2f,
-}; /* CR_In_Ethiopic_Extended_A */
-
-/* 'In_Latin_Extended_E': Block */
-static const OnigCodePoint CR_In_Latin_Extended_E[] = {
- 1,
- 0xab30, 0xab6f,
-}; /* CR_In_Latin_Extended_E */
-
-/* 'In_Cherokee_Supplement': Block */
-static const OnigCodePoint CR_In_Cherokee_Supplement[] = {
- 1,
- 0xab70, 0xabbf,
-}; /* CR_In_Cherokee_Supplement */
-
-/* 'In_Meetei_Mayek': Block */
-static const OnigCodePoint CR_In_Meetei_Mayek[] = {
- 1,
- 0xabc0, 0xabff,
-}; /* CR_In_Meetei_Mayek */
-
-/* 'In_Hangul_Syllables': Block */
-static const OnigCodePoint CR_In_Hangul_Syllables[] = {
- 1,
- 0xac00, 0xd7af,
-}; /* CR_In_Hangul_Syllables */
-
-/* 'In_Hangul_Jamo_Extended_B': Block */
-static const OnigCodePoint CR_In_Hangul_Jamo_Extended_B[] = {
- 1,
- 0xd7b0, 0xd7ff,
-}; /* CR_In_Hangul_Jamo_Extended_B */
-
-/* 'In_High_Surrogates': Block */
-static const OnigCodePoint CR_In_High_Surrogates[] = {
- 1,
- 0xd800, 0xdb7f,
-}; /* CR_In_High_Surrogates */
-
-/* 'In_High_Private_Use_Surrogates': Block */
-static const OnigCodePoint CR_In_High_Private_Use_Surrogates[] = {
- 1,
- 0xdb80, 0xdbff,
-}; /* CR_In_High_Private_Use_Surrogates */
-
-/* 'In_Low_Surrogates': Block */
-static const OnigCodePoint CR_In_Low_Surrogates[] = {
- 1,
- 0xdc00, 0xdfff,
-}; /* CR_In_Low_Surrogates */
-
-/* 'In_Private_Use_Area': Block */
-static const OnigCodePoint CR_In_Private_Use_Area[] = {
- 1,
- 0xe000, 0xf8ff,
-}; /* CR_In_Private_Use_Area */
-
-/* 'In_CJK_Compatibility_Ideographs': Block */
-static const OnigCodePoint CR_In_CJK_Compatibility_Ideographs[] = {
- 1,
- 0xf900, 0xfaff,
-}; /* CR_In_CJK_Compatibility_Ideographs */
-
-/* 'In_Alphabetic_Presentation_Forms': Block */
-static const OnigCodePoint CR_In_Alphabetic_Presentation_Forms[] = {
- 1,
- 0xfb00, 0xfb4f,
-}; /* CR_In_Alphabetic_Presentation_Forms */
-
-/* 'In_Arabic_Presentation_Forms_A': Block */
-static const OnigCodePoint CR_In_Arabic_Presentation_Forms_A[] = {
- 1,
- 0xfb50, 0xfdff,
-}; /* CR_In_Arabic_Presentation_Forms_A */
-
-/* 'In_Variation_Selectors': Block */
-static const OnigCodePoint CR_In_Variation_Selectors[] = {
- 1,
- 0xfe00, 0xfe0f,
-}; /* CR_In_Variation_Selectors */
-
-/* 'In_Vertical_Forms': Block */
-static const OnigCodePoint CR_In_Vertical_Forms[] = {
- 1,
- 0xfe10, 0xfe1f,
-}; /* CR_In_Vertical_Forms */
-
-/* 'In_Combining_Half_Marks': Block */
-static const OnigCodePoint CR_In_Combining_Half_Marks[] = {
- 1,
- 0xfe20, 0xfe2f,
-}; /* CR_In_Combining_Half_Marks */
-
-/* 'In_CJK_Compatibility_Forms': Block */
-static const OnigCodePoint CR_In_CJK_Compatibility_Forms[] = {
- 1,
- 0xfe30, 0xfe4f,
-}; /* CR_In_CJK_Compatibility_Forms */
-
-/* 'In_Small_Form_Variants': Block */
-static const OnigCodePoint CR_In_Small_Form_Variants[] = {
- 1,
- 0xfe50, 0xfe6f,
-}; /* CR_In_Small_Form_Variants */
-
-/* 'In_Arabic_Presentation_Forms_B': Block */
-static const OnigCodePoint CR_In_Arabic_Presentation_Forms_B[] = {
- 1,
- 0xfe70, 0xfeff,
-}; /* CR_In_Arabic_Presentation_Forms_B */
-
-/* 'In_Halfwidth_and_Fullwidth_Forms': Block */
-static const OnigCodePoint CR_In_Halfwidth_and_Fullwidth_Forms[] = {
- 1,
- 0xff00, 0xffef,
-}; /* CR_In_Halfwidth_and_Fullwidth_Forms */
-
-/* 'In_Specials': Block */
-static const OnigCodePoint CR_In_Specials[] = {
- 1,
- 0xfff0, 0xffff,
-}; /* CR_In_Specials */
-
-/* 'In_Linear_B_Syllabary': Block */
-static const OnigCodePoint CR_In_Linear_B_Syllabary[] = {
- 1,
- 0x10000, 0x1007f,
-}; /* CR_In_Linear_B_Syllabary */
-
-/* 'In_Linear_B_Ideograms': Block */
-static const OnigCodePoint CR_In_Linear_B_Ideograms[] = {
- 1,
- 0x10080, 0x100ff,
-}; /* CR_In_Linear_B_Ideograms */
-
-/* 'In_Aegean_Numbers': Block */
-static const OnigCodePoint CR_In_Aegean_Numbers[] = {
- 1,
- 0x10100, 0x1013f,
-}; /* CR_In_Aegean_Numbers */
-
-/* 'In_Ancient_Greek_Numbers': Block */
-static const OnigCodePoint CR_In_Ancient_Greek_Numbers[] = {
- 1,
- 0x10140, 0x1018f,
-}; /* CR_In_Ancient_Greek_Numbers */
-
-/* 'In_Ancient_Symbols': Block */
-static const OnigCodePoint CR_In_Ancient_Symbols[] = {
- 1,
- 0x10190, 0x101cf,
-}; /* CR_In_Ancient_Symbols */
-
-/* 'In_Phaistos_Disc': Block */
-static const OnigCodePoint CR_In_Phaistos_Disc[] = {
- 1,
- 0x101d0, 0x101ff,
-}; /* CR_In_Phaistos_Disc */
-
-/* 'In_Lycian': Block */
-static const OnigCodePoint CR_In_Lycian[] = {
- 1,
- 0x10280, 0x1029f,
-}; /* CR_In_Lycian */
-
-/* 'In_Carian': Block */
-static const OnigCodePoint CR_In_Carian[] = {
- 1,
- 0x102a0, 0x102df,
-}; /* CR_In_Carian */
-
-/* 'In_Coptic_Epact_Numbers': Block */
-static const OnigCodePoint CR_In_Coptic_Epact_Numbers[] = {
- 1,
- 0x102e0, 0x102ff,
-}; /* CR_In_Coptic_Epact_Numbers */
-
-/* 'In_Old_Italic': Block */
-static const OnigCodePoint CR_In_Old_Italic[] = {
- 1,
- 0x10300, 0x1032f,
-}; /* CR_In_Old_Italic */
-
-/* 'In_Gothic': Block */
-static const OnigCodePoint CR_In_Gothic[] = {
- 1,
- 0x10330, 0x1034f,
-}; /* CR_In_Gothic */
-
-/* 'In_Old_Permic': Block */
-static const OnigCodePoint CR_In_Old_Permic[] = {
- 1,
- 0x10350, 0x1037f,
-}; /* CR_In_Old_Permic */
-
-/* 'In_Ugaritic': Block */
-static const OnigCodePoint CR_In_Ugaritic[] = {
- 1,
- 0x10380, 0x1039f,
-}; /* CR_In_Ugaritic */
-
-/* 'In_Old_Persian': Block */
-static const OnigCodePoint CR_In_Old_Persian[] = {
- 1,
- 0x103a0, 0x103df,
-}; /* CR_In_Old_Persian */
-
-/* 'In_Deseret': Block */
-#define CR_In_Deseret CR_Deseret
-
-/* 'In_Shavian': Block */
-#define CR_In_Shavian CR_Shavian
-
-/* 'In_Osmanya': Block */
-static const OnigCodePoint CR_In_Osmanya[] = {
- 1,
- 0x10480, 0x104af,
-}; /* CR_In_Osmanya */
-
-/* 'In_Osage': Block */
-static const OnigCodePoint CR_In_Osage[] = {
- 1,
- 0x104b0, 0x104ff,
-}; /* CR_In_Osage */
-
-/* 'In_Elbasan': Block */
-static const OnigCodePoint CR_In_Elbasan[] = {
- 1,
- 0x10500, 0x1052f,
-}; /* CR_In_Elbasan */
-
-/* 'In_Caucasian_Albanian': Block */
-static const OnigCodePoint CR_In_Caucasian_Albanian[] = {
- 1,
- 0x10530, 0x1056f,
-}; /* CR_In_Caucasian_Albanian */
-
-/* 'In_Linear_A': Block */
-static const OnigCodePoint CR_In_Linear_A[] = {
- 1,
- 0x10600, 0x1077f,
-}; /* CR_In_Linear_A */
-
-/* 'In_Cypriot_Syllabary': Block */
-static const OnigCodePoint CR_In_Cypriot_Syllabary[] = {
- 1,
- 0x10800, 0x1083f,
-}; /* CR_In_Cypriot_Syllabary */
-
-/* 'In_Imperial_Aramaic': Block */
-static const OnigCodePoint CR_In_Imperial_Aramaic[] = {
- 1,
- 0x10840, 0x1085f,
-}; /* CR_In_Imperial_Aramaic */
-
-/* 'In_Palmyrene': Block */
-#define CR_In_Palmyrene CR_Palmyrene
-
-/* 'In_Nabataean': Block */
-static const OnigCodePoint CR_In_Nabataean[] = {
- 1,
- 0x10880, 0x108af,
-}; /* CR_In_Nabataean */
-
-/* 'In_Hatran': Block */
-static const OnigCodePoint CR_In_Hatran[] = {
- 1,
- 0x108e0, 0x108ff,
-}; /* CR_In_Hatran */
-
-/* 'In_Phoenician': Block */
-static const OnigCodePoint CR_In_Phoenician[] = {
- 1,
- 0x10900, 0x1091f,
-}; /* CR_In_Phoenician */
-
-/* 'In_Lydian': Block */
-static const OnigCodePoint CR_In_Lydian[] = {
- 1,
- 0x10920, 0x1093f,
-}; /* CR_In_Lydian */
-
-/* 'In_Meroitic_Hieroglyphs': Block */
-#define CR_In_Meroitic_Hieroglyphs CR_Meroitic_Hieroglyphs
-
-/* 'In_Meroitic_Cursive': Block */
-static const OnigCodePoint CR_In_Meroitic_Cursive[] = {
- 1,
- 0x109a0, 0x109ff,
-}; /* CR_In_Meroitic_Cursive */
-
-/* 'In_Kharoshthi': Block */
-static const OnigCodePoint CR_In_Kharoshthi[] = {
- 1,
- 0x10a00, 0x10a5f,
-}; /* CR_In_Kharoshthi */
-
-/* 'In_Old_South_Arabian': Block */
-#define CR_In_Old_South_Arabian CR_Old_South_Arabian
-
-/* 'In_Old_North_Arabian': Block */
-#define CR_In_Old_North_Arabian CR_Old_North_Arabian
-
-/* 'In_Manichaean': Block */
-static const OnigCodePoint CR_In_Manichaean[] = {
- 1,
- 0x10ac0, 0x10aff,
-}; /* CR_In_Manichaean */
-
-/* 'In_Avestan': Block */
-static const OnigCodePoint CR_In_Avestan[] = {
- 1,
- 0x10b00, 0x10b3f,
-}; /* CR_In_Avestan */
-
-/* 'In_Inscriptional_Parthian': Block */
-static const OnigCodePoint CR_In_Inscriptional_Parthian[] = {
- 1,
- 0x10b40, 0x10b5f,
-}; /* CR_In_Inscriptional_Parthian */
-
-/* 'In_Inscriptional_Pahlavi': Block */
-static const OnigCodePoint CR_In_Inscriptional_Pahlavi[] = {
- 1,
- 0x10b60, 0x10b7f,
-}; /* CR_In_Inscriptional_Pahlavi */
-
-/* 'In_Psalter_Pahlavi': Block */
-static const OnigCodePoint CR_In_Psalter_Pahlavi[] = {
- 1,
- 0x10b80, 0x10baf,
-}; /* CR_In_Psalter_Pahlavi */
-
-/* 'In_Old_Turkic': Block */
-static const OnigCodePoint CR_In_Old_Turkic[] = {
- 1,
- 0x10c00, 0x10c4f,
-}; /* CR_In_Old_Turkic */
-
-/* 'In_Old_Hungarian': Block */
-static const OnigCodePoint CR_In_Old_Hungarian[] = {
- 1,
- 0x10c80, 0x10cff,
-}; /* CR_In_Old_Hungarian */
-
-/* 'In_Rumi_Numeral_Symbols': Block */
-static const OnigCodePoint CR_In_Rumi_Numeral_Symbols[] = {
- 1,
- 0x10e60, 0x10e7f,
-}; /* CR_In_Rumi_Numeral_Symbols */
-
-/* 'In_Brahmi': Block */
-static const OnigCodePoint CR_In_Brahmi[] = {
- 1,
- 0x11000, 0x1107f,
-}; /* CR_In_Brahmi */
-
-/* 'In_Kaithi': Block */
-static const OnigCodePoint CR_In_Kaithi[] = {
- 1,
- 0x11080, 0x110cf,
-}; /* CR_In_Kaithi */
-
-/* 'In_Sora_Sompeng': Block */
-static const OnigCodePoint CR_In_Sora_Sompeng[] = {
- 1,
- 0x110d0, 0x110ff,
-}; /* CR_In_Sora_Sompeng */
-
-/* 'In_Chakma': Block */
-static const OnigCodePoint CR_In_Chakma[] = {
- 1,
- 0x11100, 0x1114f,
-}; /* CR_In_Chakma */
-
-/* 'In_Mahajani': Block */
-static const OnigCodePoint CR_In_Mahajani[] = {
- 1,
- 0x11150, 0x1117f,
-}; /* CR_In_Mahajani */
-
-/* 'In_Sharada': Block */
-static const OnigCodePoint CR_In_Sharada[] = {
- 1,
- 0x11180, 0x111df,
-}; /* CR_In_Sharada */
-
-/* 'In_Sinhala_Archaic_Numbers': Block */
-static const OnigCodePoint CR_In_Sinhala_Archaic_Numbers[] = {
- 1,
- 0x111e0, 0x111ff,
-}; /* CR_In_Sinhala_Archaic_Numbers */
-
-/* 'In_Khojki': Block */
-static const OnigCodePoint CR_In_Khojki[] = {
- 1,
- 0x11200, 0x1124f,
-}; /* CR_In_Khojki */
-
-/* 'In_Multani': Block */
-static const OnigCodePoint CR_In_Multani[] = {
- 1,
- 0x11280, 0x112af,
-}; /* CR_In_Multani */
-
-/* 'In_Khudawadi': Block */
-static const OnigCodePoint CR_In_Khudawadi[] = {
- 1,
- 0x112b0, 0x112ff,
-}; /* CR_In_Khudawadi */
-
-/* 'In_Grantha': Block */
-static const OnigCodePoint CR_In_Grantha[] = {
- 1,
- 0x11300, 0x1137f,
-}; /* CR_In_Grantha */
-
-/* 'In_Newa': Block */
-static const OnigCodePoint CR_In_Newa[] = {
- 1,
- 0x11400, 0x1147f,
-}; /* CR_In_Newa */
-
-/* 'In_Tirhuta': Block */
-static const OnigCodePoint CR_In_Tirhuta[] = {
- 1,
- 0x11480, 0x114df,
-}; /* CR_In_Tirhuta */
-
-/* 'In_Siddham': Block */
-static const OnigCodePoint CR_In_Siddham[] = {
- 1,
- 0x11580, 0x115ff,
-}; /* CR_In_Siddham */
-
-/* 'In_Modi': Block */
-static const OnigCodePoint CR_In_Modi[] = {
- 1,
- 0x11600, 0x1165f,
-}; /* CR_In_Modi */
-
-/* 'In_Mongolian_Supplement': Block */
-static const OnigCodePoint CR_In_Mongolian_Supplement[] = {
- 1,
- 0x11660, 0x1167f,
-}; /* CR_In_Mongolian_Supplement */
-
-/* 'In_Takri': Block */
-static const OnigCodePoint CR_In_Takri[] = {
- 1,
- 0x11680, 0x116cf,
-}; /* CR_In_Takri */
-
-/* 'In_Ahom': Block */
-static const OnigCodePoint CR_In_Ahom[] = {
- 1,
- 0x11700, 0x1173f,
-}; /* CR_In_Ahom */
-
-/* 'In_Warang_Citi': Block */
-static const OnigCodePoint CR_In_Warang_Citi[] = {
- 1,
- 0x118a0, 0x118ff,
-}; /* CR_In_Warang_Citi */
-
-/* 'In_Zanabazar_Square': Block */
-static const OnigCodePoint CR_In_Zanabazar_Square[] = {
- 1,
- 0x11a00, 0x11a4f,
-}; /* CR_In_Zanabazar_Square */
-
-/* 'In_Soyombo': Block */
-static const OnigCodePoint CR_In_Soyombo[] = {
- 1,
- 0x11a50, 0x11aaf,
-}; /* CR_In_Soyombo */
-
-/* 'In_Pau_Cin_Hau': Block */
-static const OnigCodePoint CR_In_Pau_Cin_Hau[] = {
- 1,
- 0x11ac0, 0x11aff,
-}; /* CR_In_Pau_Cin_Hau */
-
-/* 'In_Bhaiksuki': Block */
-static const OnigCodePoint CR_In_Bhaiksuki[] = {
- 1,
- 0x11c00, 0x11c6f,
-}; /* CR_In_Bhaiksuki */
-
-/* 'In_Marchen': Block */
-static const OnigCodePoint CR_In_Marchen[] = {
- 1,
- 0x11c70, 0x11cbf,
-}; /* CR_In_Marchen */
-
-/* 'In_Masaram_Gondi': Block */
-static const OnigCodePoint CR_In_Masaram_Gondi[] = {
- 1,
- 0x11d00, 0x11d5f,
-}; /* CR_In_Masaram_Gondi */
-
-/* 'In_Cuneiform': Block */
-static const OnigCodePoint CR_In_Cuneiform[] = {
- 1,
- 0x12000, 0x123ff,
-}; /* CR_In_Cuneiform */
-
-/* 'In_Cuneiform_Numbers_and_Punctuation': Block */
-static const OnigCodePoint CR_In_Cuneiform_Numbers_and_Punctuation[] = {
- 1,
- 0x12400, 0x1247f,
-}; /* CR_In_Cuneiform_Numbers_and_Punctuation */
-
-/* 'In_Early_Dynastic_Cuneiform': Block */
-static const OnigCodePoint CR_In_Early_Dynastic_Cuneiform[] = {
- 1,
- 0x12480, 0x1254f,
-}; /* CR_In_Early_Dynastic_Cuneiform */
-
-/* 'In_Egyptian_Hieroglyphs': Block */
-static const OnigCodePoint CR_In_Egyptian_Hieroglyphs[] = {
- 1,
- 0x13000, 0x1342f,
-}; /* CR_In_Egyptian_Hieroglyphs */
-
-/* 'In_Anatolian_Hieroglyphs': Block */
-static const OnigCodePoint CR_In_Anatolian_Hieroglyphs[] = {
- 1,
- 0x14400, 0x1467f,
-}; /* CR_In_Anatolian_Hieroglyphs */
-
-/* 'In_Bamum_Supplement': Block */
-static const OnigCodePoint CR_In_Bamum_Supplement[] = {
- 1,
- 0x16800, 0x16a3f,
-}; /* CR_In_Bamum_Supplement */
-
-/* 'In_Mro': Block */
-static const OnigCodePoint CR_In_Mro[] = {
- 1,
- 0x16a40, 0x16a6f,
-}; /* CR_In_Mro */
-
-/* 'In_Bassa_Vah': Block */
-static const OnigCodePoint CR_In_Bassa_Vah[] = {
- 1,
- 0x16ad0, 0x16aff,
-}; /* CR_In_Bassa_Vah */
-
-/* 'In_Pahawh_Hmong': Block */
-static const OnigCodePoint CR_In_Pahawh_Hmong[] = {
- 1,
- 0x16b00, 0x16b8f,
-}; /* CR_In_Pahawh_Hmong */
-
-/* 'In_Miao': Block */
-static const OnigCodePoint CR_In_Miao[] = {
- 1,
- 0x16f00, 0x16f9f,
-}; /* CR_In_Miao */
-
-/* 'In_Ideographic_Symbols_and_Punctuation': Block */
-static const OnigCodePoint CR_In_Ideographic_Symbols_and_Punctuation[] = {
- 1,
- 0x16fe0, 0x16fff,
-}; /* CR_In_Ideographic_Symbols_and_Punctuation */
-
-/* 'In_Tangut': Block */
-static const OnigCodePoint CR_In_Tangut[] = {
- 1,
- 0x17000, 0x187ff,
-}; /* CR_In_Tangut */
-
-/* 'In_Tangut_Components': Block */
-static const OnigCodePoint CR_In_Tangut_Components[] = {
- 1,
- 0x18800, 0x18aff,
-}; /* CR_In_Tangut_Components */
-
-/* 'In_Kana_Supplement': Block */
-static const OnigCodePoint CR_In_Kana_Supplement[] = {
- 1,
- 0x1b000, 0x1b0ff,
-}; /* CR_In_Kana_Supplement */
-
-/* 'In_Kana_Extended_A': Block */
-static const OnigCodePoint CR_In_Kana_Extended_A[] = {
- 1,
- 0x1b100, 0x1b12f,
-}; /* CR_In_Kana_Extended_A */
-
-/* 'In_Nushu': Block */
-static const OnigCodePoint CR_In_Nushu[] = {
- 1,
- 0x1b170, 0x1b2ff,
-}; /* CR_In_Nushu */
-
-/* 'In_Duployan': Block */
-static const OnigCodePoint CR_In_Duployan[] = {
- 1,
- 0x1bc00, 0x1bc9f,
-}; /* CR_In_Duployan */
-
-/* 'In_Shorthand_Format_Controls': Block */
-static const OnigCodePoint CR_In_Shorthand_Format_Controls[] = {
- 1,
- 0x1bca0, 0x1bcaf,
-}; /* CR_In_Shorthand_Format_Controls */
-
-/* 'In_Byzantine_Musical_Symbols': Block */
-static const OnigCodePoint CR_In_Byzantine_Musical_Symbols[] = {
- 1,
- 0x1d000, 0x1d0ff,
-}; /* CR_In_Byzantine_Musical_Symbols */
-
-/* 'In_Musical_Symbols': Block */
-static const OnigCodePoint CR_In_Musical_Symbols[] = {
- 1,
- 0x1d100, 0x1d1ff,
-}; /* CR_In_Musical_Symbols */
-
-/* 'In_Ancient_Greek_Musical_Notation': Block */
-static const OnigCodePoint CR_In_Ancient_Greek_Musical_Notation[] = {
- 1,
- 0x1d200, 0x1d24f,
-}; /* CR_In_Ancient_Greek_Musical_Notation */
-
-/* 'In_Tai_Xuan_Jing_Symbols': Block */
-static const OnigCodePoint CR_In_Tai_Xuan_Jing_Symbols[] = {
- 1,
- 0x1d300, 0x1d35f,
-}; /* CR_In_Tai_Xuan_Jing_Symbols */
-
-/* 'In_Counting_Rod_Numerals': Block */
-static const OnigCodePoint CR_In_Counting_Rod_Numerals[] = {
- 1,
- 0x1d360, 0x1d37f,
-}; /* CR_In_Counting_Rod_Numerals */
-
-/* 'In_Mathematical_Alphanumeric_Symbols': Block */
-static const OnigCodePoint CR_In_Mathematical_Alphanumeric_Symbols[] = {
- 1,
- 0x1d400, 0x1d7ff,
-}; /* CR_In_Mathematical_Alphanumeric_Symbols */
-
-/* 'In_Sutton_SignWriting': Block */
-static const OnigCodePoint CR_In_Sutton_SignWriting[] = {
- 1,
- 0x1d800, 0x1daaf,
-}; /* CR_In_Sutton_SignWriting */
-
-/* 'In_Glagolitic_Supplement': Block */
-static const OnigCodePoint CR_In_Glagolitic_Supplement[] = {
- 1,
- 0x1e000, 0x1e02f,
-}; /* CR_In_Glagolitic_Supplement */
-
-/* 'In_Mende_Kikakui': Block */
-static const OnigCodePoint CR_In_Mende_Kikakui[] = {
- 1,
- 0x1e800, 0x1e8df,
-}; /* CR_In_Mende_Kikakui */
-
-/* 'In_Adlam': Block */
-static const OnigCodePoint CR_In_Adlam[] = {
- 1,
- 0x1e900, 0x1e95f,
-}; /* CR_In_Adlam */
-
-/* 'In_Arabic_Mathematical_Alphabetic_Symbols': Block */
-static const OnigCodePoint CR_In_Arabic_Mathematical_Alphabetic_Symbols[] = {
- 1,
- 0x1ee00, 0x1eeff,
-}; /* CR_In_Arabic_Mathematical_Alphabetic_Symbols */
-
-/* 'In_Mahjong_Tiles': Block */
-static const OnigCodePoint CR_In_Mahjong_Tiles[] = {
- 1,
- 0x1f000, 0x1f02f,
-}; /* CR_In_Mahjong_Tiles */
-
-/* 'In_Domino_Tiles': Block */
-static const OnigCodePoint CR_In_Domino_Tiles[] = {
- 1,
- 0x1f030, 0x1f09f,
-}; /* CR_In_Domino_Tiles */
-
-/* 'In_Playing_Cards': Block */
-static const OnigCodePoint CR_In_Playing_Cards[] = {
- 1,
- 0x1f0a0, 0x1f0ff,
-}; /* CR_In_Playing_Cards */
-
-/* 'In_Enclosed_Alphanumeric_Supplement': Block */
-static const OnigCodePoint CR_In_Enclosed_Alphanumeric_Supplement[] = {
- 1,
- 0x1f100, 0x1f1ff,
-}; /* CR_In_Enclosed_Alphanumeric_Supplement */
-
-/* 'In_Enclosed_Ideographic_Supplement': Block */
-static const OnigCodePoint CR_In_Enclosed_Ideographic_Supplement[] = {
- 1,
- 0x1f200, 0x1f2ff,
-}; /* CR_In_Enclosed_Ideographic_Supplement */
-
-/* 'In_Miscellaneous_Symbols_and_Pictographs': Block */
-static const OnigCodePoint CR_In_Miscellaneous_Symbols_and_Pictographs[] = {
- 1,
- 0x1f300, 0x1f5ff,
-}; /* CR_In_Miscellaneous_Symbols_and_Pictographs */
-
-/* 'In_Emoticons': Block */
-static const OnigCodePoint CR_In_Emoticons[] = {
- 1,
- 0x1f600, 0x1f64f,
-}; /* CR_In_Emoticons */
-
-/* 'In_Ornamental_Dingbats': Block */
-static const OnigCodePoint CR_In_Ornamental_Dingbats[] = {
- 1,
- 0x1f650, 0x1f67f,
-}; /* CR_In_Ornamental_Dingbats */
-
-/* 'In_Transport_and_Map_Symbols': Block */
-static const OnigCodePoint CR_In_Transport_and_Map_Symbols[] = {
- 1,
- 0x1f680, 0x1f6ff,
-}; /* CR_In_Transport_and_Map_Symbols */
-
-/* 'In_Alchemical_Symbols': Block */
-static const OnigCodePoint CR_In_Alchemical_Symbols[] = {
- 1,
- 0x1f700, 0x1f77f,
-}; /* CR_In_Alchemical_Symbols */
-
-/* 'In_Geometric_Shapes_Extended': Block */
-static const OnigCodePoint CR_In_Geometric_Shapes_Extended[] = {
- 1,
- 0x1f780, 0x1f7ff,
-}; /* CR_In_Geometric_Shapes_Extended */
-
-/* 'In_Supplemental_Arrows_C': Block */
-static const OnigCodePoint CR_In_Supplemental_Arrows_C[] = {
- 1,
- 0x1f800, 0x1f8ff,
-}; /* CR_In_Supplemental_Arrows_C */
-
-/* 'In_Supplemental_Symbols_and_Pictographs': Block */
-static const OnigCodePoint CR_In_Supplemental_Symbols_and_Pictographs[] = {
- 1,
- 0x1f900, 0x1f9ff,
-}; /* CR_In_Supplemental_Symbols_and_Pictographs */
-
-/* 'In_CJK_Unified_Ideographs_Extension_B': Block */
-static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_B[] = {
- 1,
- 0x20000, 0x2a6df,
-}; /* CR_In_CJK_Unified_Ideographs_Extension_B */
-
-/* 'In_CJK_Unified_Ideographs_Extension_C': Block */
-static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_C[] = {
- 1,
- 0x2a700, 0x2b73f,
-}; /* CR_In_CJK_Unified_Ideographs_Extension_C */
-
-/* 'In_CJK_Unified_Ideographs_Extension_D': Block */
-static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_D[] = {
- 1,
- 0x2b740, 0x2b81f,
-}; /* CR_In_CJK_Unified_Ideographs_Extension_D */
-
-/* 'In_CJK_Unified_Ideographs_Extension_E': Block */
-static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_E[] = {
- 1,
- 0x2b820, 0x2ceaf,
-}; /* CR_In_CJK_Unified_Ideographs_Extension_E */
-
-/* 'In_CJK_Unified_Ideographs_Extension_F': Block */
-static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_F[] = {
- 1,
- 0x2ceb0, 0x2ebef,
-}; /* CR_In_CJK_Unified_Ideographs_Extension_F */
-
-/* 'In_CJK_Compatibility_Ideographs_Supplement': Block */
-static const OnigCodePoint CR_In_CJK_Compatibility_Ideographs_Supplement[] = {
- 1,
- 0x2f800, 0x2fa1f,
-}; /* CR_In_CJK_Compatibility_Ideographs_Supplement */
-
-/* 'In_Tags': Block */
-static const OnigCodePoint CR_In_Tags[] = {
- 1,
- 0xe0000, 0xe007f,
-}; /* CR_In_Tags */
-
-/* 'In_Variation_Selectors_Supplement': Block */
-static const OnigCodePoint CR_In_Variation_Selectors_Supplement[] = {
- 1,
- 0xe0100, 0xe01ef,
-}; /* CR_In_Variation_Selectors_Supplement */
-
-/* 'In_Supplementary_Private_Use_Area_A': Block */
-static const OnigCodePoint CR_In_Supplementary_Private_Use_Area_A[] = {
- 1,
- 0xf0000, 0xfffff,
-}; /* CR_In_Supplementary_Private_Use_Area_A */
-
-/* 'In_Supplementary_Private_Use_Area_B': Block */
-static const OnigCodePoint CR_In_Supplementary_Private_Use_Area_B[] = {
- 1,
- 0x100000, 0x10ffff,
-}; /* CR_In_Supplementary_Private_Use_Area_B */
-
-/* 'In_No_Block': Block */
-static const OnigCodePoint CR_In_No_Block[] = {
- 47,
- 0x0870, 0x089f,
- 0x1c90, 0x1cbf,
- 0x2fe0, 0x2fef,
- 0x10200, 0x1027f,
- 0x103e0, 0x103ff,
- 0x10570, 0x105ff,
- 0x10780, 0x107ff,
- 0x108b0, 0x108df,
- 0x10940, 0x1097f,
- 0x10aa0, 0x10abf,
- 0x10bb0, 0x10bff,
- 0x10c50, 0x10c7f,
- 0x10d00, 0x10e5f,
- 0x10e80, 0x10fff,
- 0x11250, 0x1127f,
- 0x11380, 0x113ff,
- 0x114e0, 0x1157f,
- 0x116d0, 0x116ff,
- 0x11740, 0x1189f,
- 0x11900, 0x119ff,
- 0x11ab0, 0x11abf,
- 0x11b00, 0x11bff,
- 0x11cc0, 0x11cff,
- 0x11d60, 0x11fff,
- 0x12550, 0x12fff,
- 0x13430, 0x143ff,
- 0x14680, 0x167ff,
- 0x16a70, 0x16acf,
- 0x16b90, 0x16eff,
- 0x16fa0, 0x16fdf,
- 0x18b00, 0x1afff,
- 0x1b130, 0x1b16f,
- 0x1b300, 0x1bbff,
- 0x1bcb0, 0x1cfff,
- 0x1d250, 0x1d2ff,
- 0x1d380, 0x1d3ff,
- 0x1dab0, 0x1dfff,
- 0x1e030, 0x1e7ff,
- 0x1e8e0, 0x1e8ff,
- 0x1e960, 0x1edff,
- 0x1ef00, 0x1efff,
- 0x1fa00, 0x1ffff,
- 0x2a6e0, 0x2a6ff,
- 0x2ebf0, 0x2f7ff,
- 0x2fa20, 0xdffff,
- 0xe0080, 0xe00ff,
- 0xe01f0, 0xeffff,
-}; /* CR_In_No_Block */
-
-#endif /* USE_UNICODE_PROPERTIES */
-static const OnigCodePoint* const CodeRanges[] = {
- CR_NEWLINE,
- CR_Alpha,
- CR_Blank,
- CR_Cntrl,
- CR_Digit,
- CR_Graph,
- CR_Lower,
- CR_Print,
- CR_XPosixPunct,
- CR_Space,
- CR_Upper,
- CR_XDigit,
- CR_Word,
- CR_Alnum,
- CR_ASCII,
- CR_Punct,
-#ifdef USE_UNICODE_PROPERTIES
- CR_Any,
- CR_Assigned,
- CR_C,
- CR_Cc,
- CR_Cf,
- CR_Cn,
- CR_Co,
- CR_Cs,
- CR_L,
- CR_LC,
- CR_Ll,
- CR_Lm,
- CR_Lo,
- CR_Lt,
- CR_Lu,
- CR_M,
- CR_Mc,
- CR_Me,
- CR_Mn,
- CR_N,
- CR_Nd,
- CR_Nl,
- CR_No,
- CR_P,
- CR_Pc,
- CR_Pd,
- CR_Pe,
- CR_Pf,
- CR_Pi,
- CR_Po,
- CR_Ps,
- CR_S,
- CR_Sc,
- CR_Sk,
- CR_Sm,
- CR_So,
- CR_Z,
- CR_Zl,
- CR_Zp,
- CR_Zs,
- CR_Math,
- CR_Alphabetic,
- CR_Lowercase,
- CR_Uppercase,
- CR_Cased,
- CR_Case_Ignorable,
- CR_Changes_When_Lowercased,
- CR_Changes_When_Uppercased,
- CR_Changes_When_Titlecased,
- CR_Changes_When_Casefolded,
- CR_Changes_When_Casemapped,
- CR_ID_Start,
- CR_ID_Continue,
- CR_XID_Start,
- CR_XID_Continue,
- CR_Default_Ignorable_Code_Point,
- CR_Grapheme_Extend,
- CR_Grapheme_Base,
- CR_Grapheme_Link,
- CR_Common,
- CR_Latin,
- CR_Greek,
- CR_Cyrillic,
- CR_Armenian,
- CR_Hebrew,
- CR_Arabic,
- CR_Syriac,
- CR_Thaana,
- CR_Devanagari,
- CR_Bengali,
- CR_Gurmukhi,
- CR_Gujarati,
- CR_Oriya,
- CR_Tamil,
- CR_Telugu,
- CR_Kannada,
- CR_Malayalam,
- CR_Sinhala,
- CR_Thai,
- CR_Lao,
- CR_Tibetan,
- CR_Myanmar,
- CR_Georgian,
- CR_Hangul,
- CR_Ethiopic,
- CR_Cherokee,
- CR_Canadian_Aboriginal,
- CR_Ogham,
- CR_Runic,
- CR_Khmer,
- CR_Mongolian,
- CR_Hiragana,
- CR_Katakana,
- CR_Bopomofo,
- CR_Han,
- CR_Yi,
- CR_Old_Italic,
- CR_Gothic,
- CR_Deseret,
- CR_Inherited,
- CR_Tagalog,
- CR_Hanunoo,
- CR_Buhid,
- CR_Tagbanwa,
- CR_Limbu,
- CR_Tai_Le,
- CR_Linear_B,
- CR_Ugaritic,
- CR_Shavian,
- CR_Osmanya,
- CR_Cypriot,
- CR_Braille,
- CR_Buginese,
- CR_Coptic,
- CR_New_Tai_Lue,
- CR_Glagolitic,
- CR_Tifinagh,
- CR_Syloti_Nagri,
- CR_Old_Persian,
- CR_Kharoshthi,
- CR_Balinese,
- CR_Cuneiform,
- CR_Phoenician,
- CR_Phags_Pa,
- CR_Nko,
- CR_Sundanese,
- CR_Lepcha,
- CR_Ol_Chiki,
- CR_Vai,
- CR_Saurashtra,
- CR_Kayah_Li,
- CR_Rejang,
- CR_Lycian,
- CR_Carian,
- CR_Lydian,
- CR_Cham,
- CR_Tai_Tham,
- CR_Tai_Viet,
- CR_Avestan,
- CR_Egyptian_Hieroglyphs,
- CR_Samaritan,
- CR_Lisu,
- CR_Bamum,
- CR_Javanese,
- CR_Meetei_Mayek,
- CR_Imperial_Aramaic,
- CR_Old_South_Arabian,
- CR_Inscriptional_Parthian,
- CR_Inscriptional_Pahlavi,
- CR_Old_Turkic,
- CR_Kaithi,
- CR_Batak,
- CR_Brahmi,
- CR_Mandaic,
- CR_Chakma,
- CR_Meroitic_Cursive,
- CR_Meroitic_Hieroglyphs,
- CR_Miao,
- CR_Sharada,
- CR_Sora_Sompeng,
- CR_Takri,
- CR_Caucasian_Albanian,
- CR_Bassa_Vah,
- CR_Duployan,
- CR_Elbasan,
- CR_Grantha,
- CR_Pahawh_Hmong,
- CR_Khojki,
- CR_Linear_A,
- CR_Mahajani,
- CR_Manichaean,
- CR_Mende_Kikakui,
- CR_Modi,
- CR_Mro,
- CR_Old_North_Arabian,
- CR_Nabataean,
- CR_Palmyrene,
- CR_Pau_Cin_Hau,
- CR_Old_Permic,
- CR_Psalter_Pahlavi,
- CR_Siddham,
- CR_Khudawadi,
- CR_Tirhuta,
- CR_Warang_Citi,
- CR_Ahom,
- CR_Anatolian_Hieroglyphs,
- CR_Hatran,
- CR_Multani,
- CR_Old_Hungarian,
- CR_SignWriting,
- CR_Adlam,
- CR_Bhaiksuki,
- CR_Marchen,
- CR_Newa,
- CR_Osage,
- CR_Tangut,
- CR_Masaram_Gondi,
- CR_Nushu,
- CR_Soyombo,
- CR_Zanabazar_Square,
- CR_White_Space,
- CR_Bidi_Control,
- CR_Join_Control,
- CR_Dash,
- CR_Hyphen,
- CR_Quotation_Mark,
- CR_Terminal_Punctuation,
- CR_Other_Math,
- CR_Hex_Digit,
- CR_ASCII_Hex_Digit,
- CR_Other_Alphabetic,
- CR_Ideographic,
- CR_Diacritic,
- CR_Extender,
- CR_Other_Lowercase,
- CR_Other_Uppercase,
- CR_Noncharacter_Code_Point,
- CR_Other_Grapheme_Extend,
- CR_IDS_Binary_Operator,
- CR_IDS_Trinary_Operator,
- CR_Radical,
- CR_Unified_Ideograph,
- CR_Other_Default_Ignorable_Code_Point,
- CR_Deprecated,
- CR_Soft_Dotted,
- CR_Logical_Order_Exception,
- CR_Other_ID_Start,
- CR_Other_ID_Continue,
- CR_Sentence_Terminal,
- CR_Variation_Selector,
- CR_Pattern_White_Space,
- CR_Pattern_Syntax,
- CR_Prepended_Concatenation_Mark,
- CR_Regional_Indicator,
- CR_Unknown,
-#ifdef USE_UNICODE_AGE_PROPERTIES
- CR_Age_1_1,
- CR_Age_2_0,
- CR_Age_2_1,
- CR_Age_3_0,
- CR_Age_3_1,
- CR_Age_3_2,
- CR_Age_4_0,
- CR_Age_4_1,
- CR_Age_5_0,
- CR_Age_5_1,
- CR_Age_5_2,
- CR_Age_6_0,
- CR_Age_6_1,
- CR_Age_6_2,
- CR_Age_6_3,
- CR_Age_7_0,
- CR_Age_8_0,
- CR_Age_9_0,
- CR_Age_10_0,
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- CR_Grapheme_Cluster_Break_Prepend,
- CR_Grapheme_Cluster_Break_CR,
- CR_Grapheme_Cluster_Break_LF,
- CR_Grapheme_Cluster_Break_Control,
- CR_Grapheme_Cluster_Break_Extend,
- CR_Grapheme_Cluster_Break_Regional_Indicator,
- CR_Grapheme_Cluster_Break_SpacingMark,
- CR_Grapheme_Cluster_Break_L,
- CR_Grapheme_Cluster_Break_V,
- CR_Grapheme_Cluster_Break_T,
- CR_Grapheme_Cluster_Break_LV,
- CR_Grapheme_Cluster_Break_LVT,
- CR_Grapheme_Cluster_Break_E_Base,
- CR_Grapheme_Cluster_Break_E_Modifier,
- CR_Grapheme_Cluster_Break_ZWJ,
- CR_Grapheme_Cluster_Break_Glue_After_Zwj,
- CR_Grapheme_Cluster_Break_E_Base_GAZ,
- CR_In_Basic_Latin,
- CR_In_Latin_1_Supplement,
- CR_In_Latin_Extended_A,
- CR_In_Latin_Extended_B,
- CR_In_IPA_Extensions,
- CR_In_Spacing_Modifier_Letters,
- CR_In_Combining_Diacritical_Marks,
- CR_In_Greek_and_Coptic,
- CR_In_Cyrillic,
- CR_In_Cyrillic_Supplement,
- CR_In_Armenian,
- CR_In_Hebrew,
- CR_In_Arabic,
- CR_In_Syriac,
- CR_In_Arabic_Supplement,
- CR_In_Thaana,
- CR_In_NKo,
- CR_In_Samaritan,
- CR_In_Mandaic,
- CR_In_Syriac_Supplement,
- CR_In_Arabic_Extended_A,
- CR_In_Devanagari,
- CR_In_Bengali,
- CR_In_Gurmukhi,
- CR_In_Gujarati,
- CR_In_Oriya,
- CR_In_Tamil,
- CR_In_Telugu,
- CR_In_Kannada,
- CR_In_Malayalam,
- CR_In_Sinhala,
- CR_In_Thai,
- CR_In_Lao,
- CR_In_Tibetan,
- CR_In_Myanmar,
- CR_In_Georgian,
- CR_In_Hangul_Jamo,
- CR_In_Ethiopic,
- CR_In_Ethiopic_Supplement,
- CR_In_Cherokee,
- CR_In_Unified_Canadian_Aboriginal_Syllabics,
- CR_In_Ogham,
- CR_In_Runic,
- CR_In_Tagalog,
- CR_In_Hanunoo,
- CR_In_Buhid,
- CR_In_Tagbanwa,
- CR_In_Khmer,
- CR_In_Mongolian,
- CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended,
- CR_In_Limbu,
- CR_In_Tai_Le,
- CR_In_New_Tai_Lue,
- CR_In_Khmer_Symbols,
- CR_In_Buginese,
- CR_In_Tai_Tham,
- CR_In_Combining_Diacritical_Marks_Extended,
- CR_In_Balinese,
- CR_In_Sundanese,
- CR_In_Batak,
- CR_In_Lepcha,
- CR_In_Ol_Chiki,
- CR_In_Cyrillic_Extended_C,
- CR_In_Sundanese_Supplement,
- CR_In_Vedic_Extensions,
- CR_In_Phonetic_Extensions,
- CR_In_Phonetic_Extensions_Supplement,
- CR_In_Combining_Diacritical_Marks_Supplement,
- CR_In_Latin_Extended_Additional,
- CR_In_Greek_Extended,
- CR_In_General_Punctuation,
- CR_In_Superscripts_and_Subscripts,
- CR_In_Currency_Symbols,
- CR_In_Combining_Diacritical_Marks_for_Symbols,
- CR_In_Letterlike_Symbols,
- CR_In_Number_Forms,
- CR_In_Arrows,
- CR_In_Mathematical_Operators,
- CR_In_Miscellaneous_Technical,
- CR_In_Control_Pictures,
- CR_In_Optical_Character_Recognition,
- CR_In_Enclosed_Alphanumerics,
- CR_In_Box_Drawing,
- CR_In_Block_Elements,
- CR_In_Geometric_Shapes,
- CR_In_Miscellaneous_Symbols,
- CR_In_Dingbats,
- CR_In_Miscellaneous_Mathematical_Symbols_A,
- CR_In_Supplemental_Arrows_A,
- CR_In_Braille_Patterns,
- CR_In_Supplemental_Arrows_B,
- CR_In_Miscellaneous_Mathematical_Symbols_B,
- CR_In_Supplemental_Mathematical_Operators,
- CR_In_Miscellaneous_Symbols_and_Arrows,
- CR_In_Glagolitic,
- CR_In_Latin_Extended_C,
- CR_In_Coptic,
- CR_In_Georgian_Supplement,
- CR_In_Tifinagh,
- CR_In_Ethiopic_Extended,
- CR_In_Cyrillic_Extended_A,
- CR_In_Supplemental_Punctuation,
- CR_In_CJK_Radicals_Supplement,
- CR_In_Kangxi_Radicals,
- CR_In_Ideographic_Description_Characters,
- CR_In_CJK_Symbols_and_Punctuation,
- CR_In_Hiragana,
- CR_In_Katakana,
- CR_In_Bopomofo,
- CR_In_Hangul_Compatibility_Jamo,
- CR_In_Kanbun,
- CR_In_Bopomofo_Extended,
- CR_In_CJK_Strokes,
- CR_In_Katakana_Phonetic_Extensions,
- CR_In_Enclosed_CJK_Letters_and_Months,
- CR_In_CJK_Compatibility,
- CR_In_CJK_Unified_Ideographs_Extension_A,
- CR_In_Yijing_Hexagram_Symbols,
- CR_In_CJK_Unified_Ideographs,
- CR_In_Yi_Syllables,
- CR_In_Yi_Radicals,
- CR_In_Lisu,
- CR_In_Vai,
- CR_In_Cyrillic_Extended_B,
- CR_In_Bamum,
- CR_In_Modifier_Tone_Letters,
- CR_In_Latin_Extended_D,
- CR_In_Syloti_Nagri,
- CR_In_Common_Indic_Number_Forms,
- CR_In_Phags_pa,
- CR_In_Saurashtra,
- CR_In_Devanagari_Extended,
- CR_In_Kayah_Li,
- CR_In_Rejang,
- CR_In_Hangul_Jamo_Extended_A,
- CR_In_Javanese,
- CR_In_Myanmar_Extended_B,
- CR_In_Cham,
- CR_In_Myanmar_Extended_A,
- CR_In_Tai_Viet,
- CR_In_Meetei_Mayek_Extensions,
- CR_In_Ethiopic_Extended_A,
- CR_In_Latin_Extended_E,
- CR_In_Cherokee_Supplement,
- CR_In_Meetei_Mayek,
- CR_In_Hangul_Syllables,
- CR_In_Hangul_Jamo_Extended_B,
- CR_In_High_Surrogates,
- CR_In_High_Private_Use_Surrogates,
- CR_In_Low_Surrogates,
- CR_In_Private_Use_Area,
- CR_In_CJK_Compatibility_Ideographs,
- CR_In_Alphabetic_Presentation_Forms,
- CR_In_Arabic_Presentation_Forms_A,
- CR_In_Variation_Selectors,
- CR_In_Vertical_Forms,
- CR_In_Combining_Half_Marks,
- CR_In_CJK_Compatibility_Forms,
- CR_In_Small_Form_Variants,
- CR_In_Arabic_Presentation_Forms_B,
- CR_In_Halfwidth_and_Fullwidth_Forms,
- CR_In_Specials,
- CR_In_Linear_B_Syllabary,
- CR_In_Linear_B_Ideograms,
- CR_In_Aegean_Numbers,
- CR_In_Ancient_Greek_Numbers,
- CR_In_Ancient_Symbols,
- CR_In_Phaistos_Disc,
- CR_In_Lycian,
- CR_In_Carian,
- CR_In_Coptic_Epact_Numbers,
- CR_In_Old_Italic,
- CR_In_Gothic,
- CR_In_Old_Permic,
- CR_In_Ugaritic,
- CR_In_Old_Persian,
- CR_In_Deseret,
- CR_In_Shavian,
- CR_In_Osmanya,
- CR_In_Osage,
- CR_In_Elbasan,
- CR_In_Caucasian_Albanian,
- CR_In_Linear_A,
- CR_In_Cypriot_Syllabary,
- CR_In_Imperial_Aramaic,
- CR_In_Palmyrene,
- CR_In_Nabataean,
- CR_In_Hatran,
- CR_In_Phoenician,
- CR_In_Lydian,
- CR_In_Meroitic_Hieroglyphs,
- CR_In_Meroitic_Cursive,
- CR_In_Kharoshthi,
- CR_In_Old_South_Arabian,
- CR_In_Old_North_Arabian,
- CR_In_Manichaean,
- CR_In_Avestan,
- CR_In_Inscriptional_Parthian,
- CR_In_Inscriptional_Pahlavi,
- CR_In_Psalter_Pahlavi,
- CR_In_Old_Turkic,
- CR_In_Old_Hungarian,
- CR_In_Rumi_Numeral_Symbols,
- CR_In_Brahmi,
- CR_In_Kaithi,
- CR_In_Sora_Sompeng,
- CR_In_Chakma,
- CR_In_Mahajani,
- CR_In_Sharada,
- CR_In_Sinhala_Archaic_Numbers,
- CR_In_Khojki,
- CR_In_Multani,
- CR_In_Khudawadi,
- CR_In_Grantha,
- CR_In_Newa,
- CR_In_Tirhuta,
- CR_In_Siddham,
- CR_In_Modi,
- CR_In_Mongolian_Supplement,
- CR_In_Takri,
- CR_In_Ahom,
- CR_In_Warang_Citi,
- CR_In_Zanabazar_Square,
- CR_In_Soyombo,
- CR_In_Pau_Cin_Hau,
- CR_In_Bhaiksuki,
- CR_In_Marchen,
- CR_In_Masaram_Gondi,
- CR_In_Cuneiform,
- CR_In_Cuneiform_Numbers_and_Punctuation,
- CR_In_Early_Dynastic_Cuneiform,
- CR_In_Egyptian_Hieroglyphs,
- CR_In_Anatolian_Hieroglyphs,
- CR_In_Bamum_Supplement,
- CR_In_Mro,
- CR_In_Bassa_Vah,
- CR_In_Pahawh_Hmong,
- CR_In_Miao,
- CR_In_Ideographic_Symbols_and_Punctuation,
- CR_In_Tangut,
- CR_In_Tangut_Components,
- CR_In_Kana_Supplement,
- CR_In_Kana_Extended_A,
- CR_In_Nushu,
- CR_In_Duployan,
- CR_In_Shorthand_Format_Controls,
- CR_In_Byzantine_Musical_Symbols,
- CR_In_Musical_Symbols,
- CR_In_Ancient_Greek_Musical_Notation,
- CR_In_Tai_Xuan_Jing_Symbols,
- CR_In_Counting_Rod_Numerals,
- CR_In_Mathematical_Alphanumeric_Symbols,
- CR_In_Sutton_SignWriting,
- CR_In_Glagolitic_Supplement,
- CR_In_Mende_Kikakui,
- CR_In_Adlam,
- CR_In_Arabic_Mathematical_Alphabetic_Symbols,
- CR_In_Mahjong_Tiles,
- CR_In_Domino_Tiles,
- CR_In_Playing_Cards,
- CR_In_Enclosed_Alphanumeric_Supplement,
- CR_In_Enclosed_Ideographic_Supplement,
- CR_In_Miscellaneous_Symbols_and_Pictographs,
- CR_In_Emoticons,
- CR_In_Ornamental_Dingbats,
- CR_In_Transport_and_Map_Symbols,
- CR_In_Alchemical_Symbols,
- CR_In_Geometric_Shapes_Extended,
- CR_In_Supplemental_Arrows_C,
- CR_In_Supplemental_Symbols_and_Pictographs,
- CR_In_CJK_Unified_Ideographs_Extension_B,
- CR_In_CJK_Unified_Ideographs_Extension_C,
- CR_In_CJK_Unified_Ideographs_Extension_D,
- CR_In_CJK_Unified_Ideographs_Extension_E,
- CR_In_CJK_Unified_Ideographs_Extension_F,
- CR_In_CJK_Compatibility_Ideographs_Supplement,
- CR_In_Tags,
- CR_In_Variation_Selectors_Supplement,
- CR_In_Supplementary_Private_Use_Area_A,
- CR_In_Supplementary_Private_Use_Area_B,
- CR_In_No_Block,
-#endif /* USE_UNICODE_PROPERTIES */
-};
-struct uniname2ctype_struct {
- short name;
- unsigned short ctype;
-};
-#define uniname2ctype_offset(str) offsetof(struct uniname2ctype_pool_t, uniname2ctype_pool_##str)
-
-static const struct uniname2ctype_struct *uniname2ctype_p(const char *, unsigned int);
-
-#ifndef USE_UNICODE_PROPERTIES
-#define TOTAL_KEYWORDS 15
-#define MIN_WORD_LENGTH 4
-#define MAX_WORD_LENGTH 11
-#define MIN_HASH_VALUE 6
-#define MAX_HASH_VALUE 20
-/* maximum key range = 15, duplicates = 0 */
-#else /* USE_UNICODE_PROPERTIES */
-#ifndef USE_UNICODE_AGE_PROPERTIES
-#define TOTAL_KEYWORDS 770
-#else /* USE_UNICODE_AGE_PROPERTIES */
-#define TOTAL_KEYWORDS 789
-#endif /* USE_UNICODE_AGE_PROPERTIES */
-#define MIN_WORD_LENGTH 1
-#define MAX_WORD_LENGTH 44
-#define MIN_HASH_VALUE 10
-#define MAX_HASH_VALUE 6145
-/* maximum key range = 6136, duplicates = 0 */
-#endif /* USE_UNICODE_PROPERTIES */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static unsigned int
-uniname2ctype_hash (str, len)
- register const char *str;
- register unsigned int len;
-{
-#ifndef USE_UNICODE_PROPERTIES
- static const unsigned char asso_values[] =
-#else /* USE_UNICODE_PROPERTIES */
- static const unsigned short asso_values[] =
-#endif /* USE_UNICODE_PROPERTIES */
- {
-#ifndef USE_UNICODE_PROPERTIES
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 3, 12, 5,
- 4, 21, 21, 10, 21, 1, 21, 21, 11, 21,
- 2, 1, 1, 21, 1, 7, 4, 6, 21, 1,
- 4, 21, 21, 21, 21, 21, 21, 21
-#else /* USE_UNICODE_PROPERTIES */
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
-#ifndef USE_UNICODE_AGE_PROPERTIES
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
-#else /* USE_UNICODE_AGE_PROPERTIES */
- 6146, 6146, 6146, 6146, 6146, 6146, 1, 6146, 2, 1,
- 5, 27, 2, 15, 7, 11, 9, 8, 6146, 6146,
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
- 6146, 6146, 6146, 6146, 6146, 6146, 6146, 5, 1058, 101,
- 332, 9, 777, 1271, 842, 3, 1142, 17, 491, 70,
- 1, 15, 741, 1115, 39, 174, 260, 566, 1127, 1473,
- 502, 1554, 13, 2, 12, 6146, 6146, 6146, 6146, 6146
-#endif /* USE_UNICODE_PROPERTIES */
- };
-#ifndef USE_UNICODE_PROPERTIES
- return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]];
-#else /* USE_UNICODE_PROPERTIES */
- register int hval = len;
-
- switch (hval)
- {
- default:
- hval += asso_values[(unsigned char)str[15]];
- /*FALLTHROUGH*/
- case 15:
- case 14:
- case 13:
- case 12:
- hval += asso_values[(unsigned char)str[11]];
- /*FALLTHROUGH*/
- case 11:
- case 10:
- case 9:
- case 8:
- case 7:
- case 6:
- hval += asso_values[(unsigned char)str[5]];
- /*FALLTHROUGH*/
- case 5:
- hval += asso_values[(unsigned char)str[4]];
- /*FALLTHROUGH*/
- case 4:
- case 3:
- hval += asso_values[(unsigned char)str[2]];
- /*FALLTHROUGH*/
- case 2:
- hval += asso_values[(unsigned char)str[1]];
- /*FALLTHROUGH*/
- case 1:
- hval += asso_values[(unsigned char)str[0]+2];
- break;
- }
- return hval + asso_values[(unsigned char)str[len - 1]];
-#endif /* USE_UNICODE_PROPERTIES */
-}
-
-struct uniname2ctype_pool_t
- {
-#ifndef USE_UNICODE_PROPERTIES
- char uniname2ctype_pool_str6[sizeof("word")];
- char uniname2ctype_pool_str7[sizeof("print")];
- char uniname2ctype_pool_str8[sizeof("punct")];
- char uniname2ctype_pool_str9[sizeof("alpha")];
- char uniname2ctype_pool_str10[sizeof("alnum")];
- char uniname2ctype_pool_str11[sizeof("xdigit")];
- char uniname2ctype_pool_str12[sizeof("upper")];
- char uniname2ctype_pool_str13[sizeof("ascii")];
- char uniname2ctype_pool_str14[sizeof("cntrl")];
- char uniname2ctype_pool_str15[sizeof("space")];
- char uniname2ctype_pool_str16[sizeof("xposixpunct")];
- char uniname2ctype_pool_str17[sizeof("lower")];
- char uniname2ctype_pool_str18[sizeof("graph")];
- char uniname2ctype_pool_str19[sizeof("digit")];
- char uniname2ctype_pool_str20[sizeof("blank")];
-#else /* USE_UNICODE_PROPERTIES */
- char uniname2ctype_pool_str10[sizeof("yi")];
- char uniname2ctype_pool_str13[sizeof("cn")];
- char uniname2ctype_pool_str14[sizeof("lina")];
- char uniname2ctype_pool_str15[sizeof("yiii")];
- char uniname2ctype_pool_str16[sizeof("lana")];
- char uniname2ctype_pool_str17[sizeof("ci")];
- char uniname2ctype_pool_str19[sizeof("mn")];
- char uniname2ctype_pool_str26[sizeof("z")];
- char uniname2ctype_pool_str28[sizeof("mani")];
- char uniname2ctype_pool_str33[sizeof("lo")];
- char uniname2ctype_pool_str35[sizeof("me")];
- char uniname2ctype_pool_str37[sizeof("loe")];
- char uniname2ctype_pool_str39[sizeof("lao")];
- char uniname2ctype_pool_str40[sizeof("laoo")];
- char uniname2ctype_pool_str41[sizeof("co")];
- char uniname2ctype_pool_str42[sizeof("miao")];
- char uniname2ctype_pool_str47[sizeof("pi")];
- char uniname2ctype_pool_str51[sizeof("inkannada")];
- char uniname2ctype_pool_str52[sizeof("gran")];
- char uniname2ctype_pool_str54[sizeof("innko")];
- char uniname2ctype_pool_str55[sizeof("zzzz")];
- char uniname2ctype_pool_str59[sizeof("pe")];
- char uniname2ctype_pool_str60[sizeof("cari")];
- char uniname2ctype_pool_str61[sizeof("lineara")];
- char uniname2ctype_pool_str66[sizeof("carian")];
- char uniname2ctype_pool_str69[sizeof("mendekikakui")];
- char uniname2ctype_pool_str70[sizeof("geor")];
- char uniname2ctype_pool_str71[sizeof("po")];
- char uniname2ctype_pool_str72[sizeof("grek")];
- char uniname2ctype_pool_str73[sizeof("meeteimayek")];
- char uniname2ctype_pool_str80[sizeof("mark")];
- char uniname2ctype_pool_str82[sizeof("mero")];
- char uniname2ctype_pool_str85[sizeof("kana")];
- char uniname2ctype_pool_str86[sizeof("m")];
- char uniname2ctype_pool_str87[sizeof("mro")];
- char uniname2ctype_pool_str88[sizeof("mroo")];
- char uniname2ctype_pool_str90[sizeof("greek")];
- char uniname2ctype_pool_str93[sizeof("gonm")];
- char uniname2ctype_pool_str97[sizeof("inkharoshthi")];
- char uniname2ctype_pool_str105[sizeof("cakm")];
- char uniname2ctype_pool_str106[sizeof("inmanichaean")];
- char uniname2ctype_pool_str111[sizeof("c")];
- char uniname2ctype_pool_str113[sizeof("inarmenian")];
- char uniname2ctype_pool_str117[sizeof("common")];
- char uniname2ctype_pool_str122[sizeof("inosmanya")];
- char uniname2ctype_pool_str123[sizeof("inmro")];
- char uniname2ctype_pool_str129[sizeof("inmiao")];
- char uniname2ctype_pool_str137[sizeof("mandaic")];
- char uniname2ctype_pool_str142[sizeof("inmyanmar")];
- char uniname2ctype_pool_str143[sizeof("lm")];
- char uniname2ctype_pool_str150[sizeof("prependedconcatenationmark")];
- char uniname2ctype_pool_str153[sizeof("inideographicsymbolsandpunctuation")];
- char uniname2ctype_pool_str154[sizeof("inchakma")];
- char uniname2ctype_pool_str160[sizeof("inkhmer")];
- char uniname2ctype_pool_str161[sizeof("perm")];
- char uniname2ctype_pool_str162[sizeof("connectorpunctuation")];
- char uniname2ctype_pool_str164[sizeof("marc")];
- char uniname2ctype_pool_str167[sizeof("combiningmark")];
- char uniname2ctype_pool_str168[sizeof("merc")];
- char uniname2ctype_pool_str169[sizeof("inrunic")];
- char uniname2ctype_pool_str170[sizeof("incarian")];
- char uniname2ctype_pool_str172[sizeof("incuneiformnumbersandpunctuation")];
- char uniname2ctype_pool_str184[sizeof("inahom")];
- char uniname2ctype_pool_str186[sizeof("incherokee")];
- char uniname2ctype_pool_str191[sizeof("qaai")];
- char uniname2ctype_pool_str193[sizeof("cans")];
- char uniname2ctype_pool_str205[sizeof("lc")];
- char uniname2ctype_pool_str210[sizeof("incuneiform")];
- char uniname2ctype_pool_str213[sizeof("cc")];
- char uniname2ctype_pool_str215[sizeof("armn")];
- char uniname2ctype_pool_str216[sizeof("inavestan")];
- char uniname2ctype_pool_str217[sizeof("armi")];
- char uniname2ctype_pool_str219[sizeof("mc")];
- char uniname2ctype_pool_str223[sizeof("armenian")];
- char uniname2ctype_pool_str227[sizeof("inipaextensions")];
- char uniname2ctype_pool_str238[sizeof("inmarchen")];
- char uniname2ctype_pool_str243[sizeof("pc")];
- char uniname2ctype_pool_str250[sizeof("insharada")];
- char uniname2ctype_pool_str255[sizeof("lineseparator")];
- char uniname2ctype_pool_str256[sizeof("masaramgondi")];
- char uniname2ctype_pool_str259[sizeof("inarrows")];
- char uniname2ctype_pool_str268[sizeof("ri")];
- char uniname2ctype_pool_str270[sizeof("incham")];
- char uniname2ctype_pool_str271[sizeof("latn")];
- char uniname2ctype_pool_str272[sizeof("incyrillic")];
- char uniname2ctype_pool_str273[sizeof("latin")];
- char uniname2ctype_pool_str276[sizeof("inzanabazarsquare")];
- char uniname2ctype_pool_str279[sizeof("insamaritan")];
- char uniname2ctype_pool_str283[sizeof("pcm")];
- char uniname2ctype_pool_str285[sizeof("inmasaramgondi")];
- char uniname2ctype_pool_str288[sizeof("qmark")];
- char uniname2ctype_pool_str289[sizeof("qaac")];
- char uniname2ctype_pool_str291[sizeof("mtei")];
- char uniname2ctype_pool_str295[sizeof("inthai")];
- char uniname2ctype_pool_str300[sizeof("inscriptionalparthian")];
- char uniname2ctype_pool_str301[sizeof("inthaana")];
- char uniname2ctype_pool_str309[sizeof("inkaithi")];
- char uniname2ctype_pool_str311[sizeof("initialpunctuation")];
- char uniname2ctype_pool_str315[sizeof("inkatakana")];
- char uniname2ctype_pool_str317[sizeof("inkhmersymbols")];
- char uniname2ctype_pool_str343[sizeof("insyriac")];
- char uniname2ctype_pool_str344[sizeof("intakri")];
- char uniname2ctype_pool_str345[sizeof("prti")];
- char uniname2ctype_pool_str356[sizeof("arabic")];
- char uniname2ctype_pool_str357[sizeof("mand")];
- char uniname2ctype_pool_str359[sizeof("cs")];
- char uniname2ctype_pool_str361[sizeof("mend")];
- char uniname2ctype_pool_str362[sizeof("zs")];
- char uniname2ctype_pool_str363[sizeof("letter")];
- char uniname2ctype_pool_str365[sizeof("privateuse")];
- char uniname2ctype_pool_str369[sizeof("modi")];
- char uniname2ctype_pool_str370[sizeof("katakana")];
- char uniname2ctype_pool_str377[sizeof("ideo")];
- char uniname2ctype_pool_str383[sizeof("brai")];
- char uniname2ctype_pool_str384[sizeof("xidcontinue")];
- char uniname2ctype_pool_str386[sizeof("inmyanmarextendeda")];
- char uniname2ctype_pool_str387[sizeof("ascii")];
- char uniname2ctype_pool_str389[sizeof("ps")];
- char uniname2ctype_pool_str393[sizeof("inkanaextendeda")];
- char uniname2ctype_pool_str396[sizeof("inmeeteimayek")];
- char uniname2ctype_pool_str399[sizeof("inruminumeralsymbols")];
- char uniname2ctype_pool_str408[sizeof("letternumber")];
- char uniname2ctype_pool_str412[sizeof("knda")];
- char uniname2ctype_pool_str425[sizeof("kannada")];
- char uniname2ctype_pool_str428[sizeof("inoldnortharabian")];
- char uniname2ctype_pool_str430[sizeof("inideographicdescriptioncharacters")];
- char uniname2ctype_pool_str432[sizeof("inmodi")];
- char uniname2ctype_pool_str440[sizeof("incjkcompatibilityforms")];
- char uniname2ctype_pool_str445[sizeof("incjkcompatibilityideographs")];
- char uniname2ctype_pool_str453[sizeof("xidc")];
- char uniname2ctype_pool_str455[sizeof("inmendekikakui")];
- char uniname2ctype_pool_str458[sizeof("brahmi")];
- char uniname2ctype_pool_str480[sizeof("inolditalic")];
- char uniname2ctype_pool_str482[sizeof("inmiscellaneousmathematicalsymbolsa")];
- char uniname2ctype_pool_str486[sizeof("inspecials")];
- char uniname2ctype_pool_str487[sizeof("inemoticons")];
- char uniname2ctype_pool_str488[sizeof("patternwhitespace")];
- char uniname2ctype_pool_str489[sizeof("gothic")];
- char uniname2ctype_pool_str492[sizeof("intransportandmapsymbols")];
- char uniname2ctype_pool_str493[sizeof("l")];
- char uniname2ctype_pool_str509[sizeof("psalterpahlavi")];
- char uniname2ctype_pool_str516[sizeof("vai")];
- char uniname2ctype_pool_str517[sizeof("vaii")];
- char uniname2ctype_pool_str523[sizeof("lt")];
- char uniname2ctype_pool_str524[sizeof("meroiticcursive")];
- char uniname2ctype_pool_str526[sizeof("xids")];
- char uniname2ctype_pool_str530[sizeof("incommonindicnumberforms")];
- char uniname2ctype_pool_str531[sizeof("inmandaic")];
- char uniname2ctype_pool_str533[sizeof("inlineara")];
- char uniname2ctype_pool_str541[sizeof("incjkcompatibilityideographssupplement")];
- char uniname2ctype_pool_str544[sizeof("inlao")];
- char uniname2ctype_pool_str545[sizeof("insundanese")];
- char uniname2ctype_pool_str547[sizeof("mongolian")];
- char uniname2ctype_pool_str552[sizeof("bamum")];
- char uniname2ctype_pool_str554[sizeof("idc")];
- char uniname2ctype_pool_str561[sizeof("inancientsymbols")];
- char uniname2ctype_pool_str573[sizeof("kali")];
- char uniname2ctype_pool_str574[sizeof("grlink")];
- char uniname2ctype_pool_str576[sizeof("grext")];
- char uniname2ctype_pool_str577[sizeof("control")];
- char uniname2ctype_pool_str586[sizeof("inkanasupplement")];
- char uniname2ctype_pool_str591[sizeof("inopticalcharacterrecognition")];
- char uniname2ctype_pool_str596[sizeof("inadlam")];
- char uniname2ctype_pool_str598[sizeof("so")];
- char uniname2ctype_pool_str601[sizeof("inoldsoutharabian")];
- char uniname2ctype_pool_str602[sizeof("sk")];
- char uniname2ctype_pool_str606[sizeof("print")];
- char uniname2ctype_pool_str607[sizeof("idsbinaryoperator")];
- char uniname2ctype_pool_str609[sizeof("palm")];
- char uniname2ctype_pool_str618[sizeof("batk")];
- char uniname2ctype_pool_str619[sizeof("indominotiles")];
- char uniname2ctype_pool_str620[sizeof("intaitham")];
- char uniname2ctype_pool_str622[sizeof("inlycian")];
- char uniname2ctype_pool_str629[sizeof("sora")];
- char uniname2ctype_pool_str636[sizeof("batak")];
- char uniname2ctype_pool_str642[sizeof("inmodifiertoneletters")];
- char uniname2ctype_pool_str657[sizeof("patws")];
- char uniname2ctype_pool_str665[sizeof("inmalayalam")];
- char uniname2ctype_pool_str670[sizeof("incjkstrokes")];
- char uniname2ctype_pool_str681[sizeof("incontrolpictures")];
- char uniname2ctype_pool_str684[sizeof("samr")];
- char uniname2ctype_pool_str689[sizeof("bass")];
- char uniname2ctype_pool_str693[sizeof("samaritan")];
- char uniname2ctype_pool_str699[sizeof("inmusicalsymbols")];
- char uniname2ctype_pool_str700[sizeof("ids")];
- char uniname2ctype_pool_str705[sizeof("pd")];
- char uniname2ctype_pool_str708[sizeof("sm")];
- char uniname2ctype_pool_str715[sizeof("pauc")];
- char uniname2ctype_pool_str716[sizeof("joinc")];
- char uniname2ctype_pool_str725[sizeof("inlinearbideograms")];
- char uniname2ctype_pool_str730[sizeof("idcontinue")];
- char uniname2ctype_pool_str732[sizeof("inancientgreekmusicalnotation")];
- char uniname2ctype_pool_str737[sizeof("inoldturkic")];
- char uniname2ctype_pool_str738[sizeof("alnum")];
- char uniname2ctype_pool_str739[sizeof("inugaritic")];
- char uniname2ctype_pool_str741[sizeof("s")];
- char uniname2ctype_pool_str742[sizeof("inmiscellaneoussymbols")];
- char uniname2ctype_pool_str743[sizeof("n")];
- char uniname2ctype_pool_str748[sizeof("lisu")];
- char uniname2ctype_pool_str751[sizeof("inmiscellaneoussymbolsandarrows")];
- char uniname2ctype_pool_str753[sizeof("insylotinagri")];
- char uniname2ctype_pool_str756[sizeof("inmiscellaneoussymbolsandpictographs")];
- char uniname2ctype_pool_str770[sizeof("sc")];
- char uniname2ctype_pool_str773[sizeof("no")];
- char uniname2ctype_pool_str777[sizeof("ital")];
- char uniname2ctype_pool_str781[sizeof("p")];
- char uniname2ctype_pool_str782[sizeof("xpeo")];
- char uniname2ctype_pool_str785[sizeof("di")];
- char uniname2ctype_pool_str787[sizeof("idst")];
- char uniname2ctype_pool_str788[sizeof("intaile")];
- char uniname2ctype_pool_str791[sizeof("nko")];
- char uniname2ctype_pool_str792[sizeof("nkoo")];
- char uniname2ctype_pool_str793[sizeof("dia")];
- char uniname2ctype_pool_str797[sizeof("inphoenician")];
- char uniname2ctype_pool_str799[sizeof("inlatinextendeda")];
- char uniname2ctype_pool_str802[sizeof("indeseret")];
- char uniname2ctype_pool_str807[sizeof("inlatinextendede")];
- char uniname2ctype_pool_str812[sizeof("incaucasianalbanian")];
- char uniname2ctype_pool_str819[sizeof("insaurashtra")];
- char uniname2ctype_pool_str823[sizeof("inmeeteimayekextensions")];
- char uniname2ctype_pool_str834[sizeof("idstart")];
- char uniname2ctype_pool_str835[sizeof("bali")];
- char uniname2ctype_pool_str837[sizeof("inspacingmodifierletters")];
- char uniname2ctype_pool_str848[sizeof("bengali")];
- char uniname2ctype_pool_str849[sizeof("intamil")];
- char uniname2ctype_pool_str851[sizeof("inmultani")];
- char uniname2ctype_pool_str852[sizeof("vs")];
- char uniname2ctype_pool_str853[sizeof("inlydian")];
- char uniname2ctype_pool_str855[sizeof("balinese")];
- char uniname2ctype_pool_str856[sizeof("lepc")];
- char uniname2ctype_pool_str857[sizeof("cased")];
- char uniname2ctype_pool_str862[sizeof("zinh")];
- char uniname2ctype_pool_str867[sizeof("blank")];
- char uniname2ctype_pool_str870[sizeof("runr")];
- char uniname2ctype_pool_str872[sizeof("patternsyntax")];
- char uniname2ctype_pool_str874[sizeof("bidic")];
- char uniname2ctype_pool_str877[sizeof("xdigit")];
- char uniname2ctype_pool_str881[sizeof("xidstart")];
- char uniname2ctype_pool_str885[sizeof("inphaistosdisc")];
- char uniname2ctype_pool_str897[sizeof("inancientgreeknumbers")];
- char uniname2ctype_pool_str899[sizeof("canadianaboriginal")];
- char uniname2ctype_pool_str903[sizeof("cher")];
- char uniname2ctype_pool_str905[sizeof("plrd")];
- char uniname2ctype_pool_str906[sizeof("sind")];
- char uniname2ctype_pool_str909[sizeof("cherokee")];
- char uniname2ctype_pool_str911[sizeof("phoenician")];
- char uniname2ctype_pool_str918[sizeof("marchen")];
- char uniname2ctype_pool_str919[sizeof("inhiragana")];
- char uniname2ctype_pool_str926[sizeof("inearlydynasticcuneiform")];
- char uniname2ctype_pool_str928[sizeof("graphemebase")];
- char uniname2ctype_pool_str930[sizeof("cham")];
- char uniname2ctype_pool_str931[sizeof("inimperialaramaic")];
- char uniname2ctype_pool_str932[sizeof("kaithi")];
- char uniname2ctype_pool_str935[sizeof("insiddham")];
- char uniname2ctype_pool_str937[sizeof("diacritic")];
- char uniname2ctype_pool_str942[sizeof("chakma")];
- char uniname2ctype_pool_str944[sizeof("graphemelink")];
- char uniname2ctype_pool_str947[sizeof("inkhudawadi")];
- char uniname2ctype_pool_str948[sizeof("inmahajani")];
- char uniname2ctype_pool_str956[sizeof("khojki")];
- char uniname2ctype_pool_str957[sizeof("inogham")];
- char uniname2ctype_pool_str960[sizeof("khar")];
- char uniname2ctype_pool_str966[sizeof("incountingrodnumerals")];
- char uniname2ctype_pool_str975[sizeof("manichaean")];
- char uniname2ctype_pool_str976[sizeof("coptic")];
- char uniname2ctype_pool_str977[sizeof("bamu")];
- char uniname2ctype_pool_str980[sizeof("sterm")];
- char uniname2ctype_pool_str983[sizeof("inethiopic")];
- char uniname2ctype_pool_str985[sizeof("ll")];
- char uniname2ctype_pool_str988[sizeof("inolchiki")];
- char uniname2ctype_pool_str991[sizeof("inlatinextendedc")];
- char uniname2ctype_pool_str996[sizeof("zl")];
- char uniname2ctype_pool_str998[sizeof("adlm")];
- char uniname2ctype_pool_str1016[sizeof("incyrillicsupplement")];
- char uniname2ctype_pool_str1019[sizeof("incyrillicextendeda")];
- char uniname2ctype_pool_str1022[sizeof("incherokeesupplement")];
- char uniname2ctype_pool_str1023[sizeof("decimalnumber")];
- char uniname2ctype_pool_str1025[sizeof("khmr")];
- char uniname2ctype_pool_str1029[sizeof("copt")];
- char uniname2ctype_pool_str1032[sizeof("ahom")];
- char uniname2ctype_pool_str1034[sizeof("runic")];
- char uniname2ctype_pool_str1048[sizeof("intaixuanjingsymbols")];
- char uniname2ctype_pool_str1049[sizeof("insinhala")];
- char uniname2ctype_pool_str1053[sizeof("cprt")];
- char uniname2ctype_pool_str1056[sizeof("imperialaramaic")];
- char uniname2ctype_pool_str1061[sizeof("casedletter")];
- char uniname2ctype_pool_str1065[sizeof("khmer")];
- char uniname2ctype_pool_str1067[sizeof("linb")];
- char uniname2ctype_pool_str1069[sizeof("adlam")];
- char uniname2ctype_pool_str1076[sizeof("ininscriptionalparthian")];
- char uniname2ctype_pool_str1077[sizeof("ininscriptionalpahlavi")];
- char uniname2ctype_pool_str1078[sizeof("sinhala")];
- char uniname2ctype_pool_str1080[sizeof("zanb")];
- char uniname2ctype_pool_str1086[sizeof("incjkunifiedideographsextensiona")];
- char uniname2ctype_pool_str1088[sizeof("multani")];
- char uniname2ctype_pool_str1089[sizeof("quotationmark")];
- char uniname2ctype_pool_str1090[sizeof("incjkunifiedideographsextensione")];
- char uniname2ctype_pool_str1094[sizeof("innabataean")];
- char uniname2ctype_pool_str1098[sizeof("inbhaiksuki")];
- char uniname2ctype_pool_str1100[sizeof("inelbasan")];
- char uniname2ctype_pool_str1103[sizeof("inkanbun")];
- char uniname2ctype_pool_str1104[sizeof("inscriptionalpahlavi")];
- char uniname2ctype_pool_str1107[sizeof("bopo")];
- char uniname2ctype_pool_str1114[sizeof("linearb")];
- char uniname2ctype_pool_str1115[sizeof("incyrillicextendedc")];
- char uniname2ctype_pool_str1116[sizeof("glagolitic")];
- char uniname2ctype_pool_str1119[sizeof("kharoshthi")];
- char uniname2ctype_pool_str1120[sizeof("inoldpersian")];
- char uniname2ctype_pool_str1124[sizeof("goth")];
- char uniname2ctype_pool_str1126[sizeof("math")];
- char uniname2ctype_pool_str1127[sizeof("joincontrol")];
- char uniname2ctype_pool_str1131[sizeof("punct")];
- char uniname2ctype_pool_str1135[sizeof("lu")];
- char uniname2ctype_pool_str1136[sizeof("limb")];
- char uniname2ctype_pool_str1147[sizeof("inmiscellaneoustechnical")];
- char uniname2ctype_pool_str1152[sizeof("han")];
- char uniname2ctype_pool_str1155[sizeof("hani")];
- char uniname2ctype_pool_str1156[sizeof("invai")];
- char uniname2ctype_pool_str1157[sizeof("sundanese")];
- char uniname2ctype_pool_str1158[sizeof("taile")];
- char uniname2ctype_pool_str1160[sizeof("takri")];
- char uniname2ctype_pool_str1161[sizeof("grantha")];
- char uniname2ctype_pool_str1167[sizeof("hano")];
- char uniname2ctype_pool_str1168[sizeof("inhatran")];
- char uniname2ctype_pool_str1172[sizeof("oriya")];
- char uniname2ctype_pool_str1173[sizeof("intirhuta")];
- char uniname2ctype_pool_str1178[sizeof("guru")];
- char uniname2ctype_pool_str1179[sizeof("kthi")];
- char uniname2ctype_pool_str1180[sizeof("saur")];
- char uniname2ctype_pool_str1182[sizeof("incjkunifiedideographsextensionc")];
- char uniname2ctype_pool_str1186[sizeof("hanunoo")];
- char uniname2ctype_pool_str1189[sizeof("paucinhau")];
- char uniname2ctype_pool_str1192[sizeof("takr")];
- char uniname2ctype_pool_str1193[sizeof("hira")];
- char uniname2ctype_pool_str1195[sizeof("inarabic")];
- char uniname2ctype_pool_str1196[sizeof("bopomofo")];
- char uniname2ctype_pool_str1201[sizeof("radical")];
- char uniname2ctype_pool_str1202[sizeof("gurmukhi")];
- char uniname2ctype_pool_str1203[sizeof("inkhojki")];
- char uniname2ctype_pool_str1207[sizeof("arab")];
- char uniname2ctype_pool_str1211[sizeof("limbu")];
- char uniname2ctype_pool_str1218[sizeof("inoldpermic")];
- char uniname2ctype_pool_str1222[sizeof("brah")];
- char uniname2ctype_pool_str1225[sizeof("inoldhungarian")];
- char uniname2ctype_pool_str1227[sizeof("inshorthandformatcontrols")];
- char uniname2ctype_pool_str1229[sizeof("incoptic")];
- char uniname2ctype_pool_str1232[sizeof("sd")];
- char uniname2ctype_pool_str1237[sizeof("sidd")];
- char uniname2ctype_pool_str1243[sizeof("inherited")];
- char uniname2ctype_pool_str1245[sizeof("incjkunifiedideographs")];
- char uniname2ctype_pool_str1249[sizeof("term")];
- char uniname2ctype_pool_str1252[sizeof("incjksymbolsandpunctuation")];
- char uniname2ctype_pool_str1253[sizeof("graphemeextend")];
- char uniname2ctype_pool_str1254[sizeof("dsrt")];
- char uniname2ctype_pool_str1257[sizeof("cntrl")];
- char uniname2ctype_pool_str1259[sizeof("xsux")];
- char uniname2ctype_pool_str1262[sizeof("insyriacsupplement")];
- char uniname2ctype_pool_str1267[sizeof("inbasiclatin")];
- char uniname2ctype_pool_str1275[sizeof("deseret")];
- char uniname2ctype_pool_str1281[sizeof("inenclosedideographicsupplement")];
- char uniname2ctype_pool_str1285[sizeof("bidicontrol")];
- char uniname2ctype_pool_str1288[sizeof("closepunctuation")];
- char uniname2ctype_pool_str1294[sizeof("inlatinextendedadditional")];
- char uniname2ctype_pool_str1296[sizeof("inarabicpresentationformsa")];
- char uniname2ctype_pool_str1298[sizeof("grbase")];
- char uniname2ctype_pool_str1306[sizeof("mong")];
- char uniname2ctype_pool_str1307[sizeof("anatolianhieroglyphs")];
- char uniname2ctype_pool_str1308[sizeof("inenclosedalphanumerics")];
- char uniname2ctype_pool_str1309[sizeof("ingrantha")];
- char uniname2ctype_pool_str1310[sizeof("georgian")];
- char uniname2ctype_pool_str1317[sizeof("osage")];
- char uniname2ctype_pool_str1325[sizeof("inosage")];
- char uniname2ctype_pool_str1326[sizeof("ingeneralpunctuation")];
- char uniname2ctype_pool_str1331[sizeof("saurashtra")];
- char uniname2ctype_pool_str1334[sizeof("inshavian")];
- char uniname2ctype_pool_str1335[sizeof("space")];
- char uniname2ctype_pool_str1336[sizeof("mult")];
- char uniname2ctype_pool_str1340[sizeof("inpalmyrene")];
- char uniname2ctype_pool_str1341[sizeof("inanatolianhieroglyphs")];
- char uniname2ctype_pool_str1344[sizeof("spacingmark")];
- char uniname2ctype_pool_str1348[sizeof("alpha")];
- char uniname2ctype_pool_str1354[sizeof("ingeorgian")];
- char uniname2ctype_pool_str1355[sizeof("intibetan")];
- char uniname2ctype_pool_str1364[sizeof("inlepcha")];
- char uniname2ctype_pool_str1365[sizeof("inbatak")];
- char uniname2ctype_pool_str1368[sizeof("osma")];
- char uniname2ctype_pool_str1369[sizeof("bhks")];
- char uniname2ctype_pool_str1372[sizeof("inmongolian")];
- char uniname2ctype_pool_str1373[sizeof("variationselector")];
- char uniname2ctype_pool_str1374[sizeof("braille")];
- char uniname2ctype_pool_str1379[sizeof("phli")];
- char uniname2ctype_pool_str1382[sizeof("bhaiksuki")];
- char uniname2ctype_pool_str1388[sizeof("phnx")];
- char uniname2ctype_pool_str1390[sizeof("inblockelements")];
-#ifdef USE_UNICODE_AGE_PROPERTIES
- char uniname2ctype_pool_str1391[sizeof("age=1.1")];
- char uniname2ctype_pool_str1392[sizeof("age=4.1")];
- char uniname2ctype_pool_str1393[sizeof("age=4.0")];
- char uniname2ctype_pool_str1394[sizeof("age=10.0")];
- char uniname2ctype_pool_str1395[sizeof("age=2.1")];
- char uniname2ctype_pool_str1396[sizeof("age=2.0")];
- char uniname2ctype_pool_str1397[sizeof("age=6.1")];
- char uniname2ctype_pool_str1398[sizeof("age=6.0")];
- char uniname2ctype_pool_str1399[sizeof("age=9.0")];
- char uniname2ctype_pool_str1400[sizeof("age=8.0")];
- char uniname2ctype_pool_str1401[sizeof("age=6.2")];
- char uniname2ctype_pool_str1402[sizeof("age=7.0")];
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- char uniname2ctype_pool_str1403[sizeof("inenclosedalphanumericsupplement")];
- char uniname2ctype_pool_str1404[sizeof("innumberforms")];
-#ifdef USE_UNICODE_AGE_PROPERTIES
- char uniname2ctype_pool_str1405[sizeof("age=5.1")];
- char uniname2ctype_pool_str1406[sizeof("age=5.0")];
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- char uniname2ctype_pool_str1407[sizeof("nd")];
- char uniname2ctype_pool_str1408[sizeof("separator")];
-#ifdef USE_UNICODE_AGE_PROPERTIES
- char uniname2ctype_pool_str1409[sizeof("age=5.2")];
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- char uniname2ctype_pool_str1411[sizeof("ingurmukhi")];
- char uniname2ctype_pool_str1413[sizeof("incjkunifiedideographsextensiond")];
- char uniname2ctype_pool_str1414[sizeof("taiviet")];
- char uniname2ctype_pool_str1416[sizeof("sinh")];
-#ifdef USE_UNICODE_AGE_PROPERTIES
- char uniname2ctype_pool_str1417[sizeof("age=3.1")];
- char uniname2ctype_pool_str1418[sizeof("age=3.0")];
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- char uniname2ctype_pool_str1420[sizeof("hatran")];
-#ifdef USE_UNICODE_AGE_PROPERTIES
- char uniname2ctype_pool_str1421[sizeof("age=3.2")];
- char uniname2ctype_pool_str1423[sizeof("age=6.3")];
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- char uniname2ctype_pool_str1427[sizeof("format")];
- char uniname2ctype_pool_str1429[sizeof("shavian")];
- char uniname2ctype_pool_str1434[sizeof("insinhalaarchaicnumbers")];
- char uniname2ctype_pool_str1435[sizeof("cuneiform")];
- char uniname2ctype_pool_str1439[sizeof("inmyanmarextendedb")];
- char uniname2ctype_pool_str1444[sizeof("punctuation")];
- char uniname2ctype_pool_str1449[sizeof("inarabicextendeda")];
- char uniname2ctype_pool_str1450[sizeof("hatr")];
- char uniname2ctype_pool_str1451[sizeof("inhanunoo")];
- char uniname2ctype_pool_str1453[sizeof("inlatinextendedd")];
- char uniname2ctype_pool_str1455[sizeof("modifierletter")];
- char uniname2ctype_pool_str1456[sizeof("odi")];
- char uniname2ctype_pool_str1458[sizeof("ahex")];
- char uniname2ctype_pool_str1463[sizeof("logicalorderexception")];
- char uniname2ctype_pool_str1464[sizeof("inbyzantinemusicalsymbols")];
- char uniname2ctype_pool_str1469[sizeof("sund")];
- char uniname2ctype_pool_str1470[sizeof("number")];
- char uniname2ctype_pool_str1471[sizeof("insundanesesupplement")];
- char uniname2ctype_pool_str1485[sizeof("incopticepactnumbers")];
- char uniname2ctype_pool_str1496[sizeof("zp")];
- char uniname2ctype_pool_str1497[sizeof("asciihexdigit")];
- char uniname2ctype_pool_str1500[sizeof("indevanagari")];
- char uniname2ctype_pool_str1508[sizeof("innewa")];
- char uniname2ctype_pool_str1510[sizeof("avestan")];
- char uniname2ctype_pool_str1521[sizeof("insorasompeng")];
- char uniname2ctype_pool_str1535[sizeof("inmiscellaneousmathematicalsymbolsb")];
- char uniname2ctype_pool_str1536[sizeof("inbraillepatterns")];
- char uniname2ctype_pool_str1539[sizeof("nonspacingmark")];
- char uniname2ctype_pool_str1540[sizeof("ingreekandcoptic")];
- char uniname2ctype_pool_str1545[sizeof("xposixpunct")];
- char uniname2ctype_pool_str1553[sizeof("inwarangciti")];
- char uniname2ctype_pool_str1555[sizeof("oidc")];
- char uniname2ctype_pool_str1560[sizeof("terminalpunctuation")];
- char uniname2ctype_pool_str1565[sizeof("cf")];
- char uniname2ctype_pool_str1572[sizeof("lower")];
- char uniname2ctype_pool_str1580[sizeof("inunifiedcanadianaboriginalsyllabics")];
- char uniname2ctype_pool_str1585[sizeof("idsb")];
- char uniname2ctype_pool_str1589[sizeof("inbalinese")];
- char uniname2ctype_pool_str1593[sizeof("induployan")];
- char uniname2ctype_pool_str1594[sizeof("innoblock")];
- char uniname2ctype_pool_str1595[sizeof("pf")];
- char uniname2ctype_pool_str1602[sizeof("inoriya")];
- char uniname2ctype_pool_str1604[sizeof("inkatakanaphoneticextensions")];
- char uniname2ctype_pool_str1606[sizeof("inkayahli")];
- char uniname2ctype_pool_str1607[sizeof("wara")];
- char uniname2ctype_pool_str1608[sizeof("innushu")];
- char uniname2ctype_pool_str1609[sizeof("lepcha")];
- char uniname2ctype_pool_str1611[sizeof("inmeroitichieroglyphs")];
- char uniname2ctype_pool_str1617[sizeof("beng")];
- char uniname2ctype_pool_str1623[sizeof("idstrinaryoperator")];
- char uniname2ctype_pool_str1628[sizeof("oids")];
- char uniname2ctype_pool_str1630[sizeof("regionalindicator")];
- char uniname2ctype_pool_str1631[sizeof("enclosingmark")];
- char uniname2ctype_pool_str1632[sizeof("java")];
- char uniname2ctype_pool_str1636[sizeof("tale")];
- char uniname2ctype_pool_str1645[sizeof("inphoneticextensions")];
- char uniname2ctype_pool_str1647[sizeof("lowercase")];
- char uniname2ctype_pool_str1648[sizeof("inverticalforms")];
- char uniname2ctype_pool_str1650[sizeof("javanese")];
- char uniname2ctype_pool_str1654[sizeof("sentenceterminal")];
- char uniname2ctype_pool_str1655[sizeof("ingreekextended")];
- char uniname2ctype_pool_str1656[sizeof("invariationselectors")];
- char uniname2ctype_pool_str1657[sizeof("cwcm")];
- char uniname2ctype_pool_str1663[sizeof("lyci")];
- char uniname2ctype_pool_str1666[sizeof("avst")];
- char uniname2ctype_pool_str1669[sizeof("lycian")];
- char uniname2ctype_pool_str1671[sizeof("zanabazarsquare")];
- char uniname2ctype_pool_str1672[sizeof("sarb")];
- char uniname2ctype_pool_str1673[sizeof("invedicextensions")];
- char uniname2ctype_pool_str1674[sizeof("inkangxiradicals")];
- char uniname2ctype_pool_str1677[sizeof("intaiviet")];
- char uniname2ctype_pool_str1682[sizeof("mymr")];
- char uniname2ctype_pool_str1690[sizeof("incjkradicalssupplement")];
- char uniname2ctype_pool_str1695[sizeof("myanmar")];
- char uniname2ctype_pool_str1697[sizeof("taml")];
- char uniname2ctype_pool_str1714[sizeof("olower")];
- char uniname2ctype_pool_str1725[sizeof("nl")];
- char uniname2ctype_pool_str1727[sizeof("inethiopicsupplement")];
- char uniname2ctype_pool_str1728[sizeof("olck")];
- char uniname2ctype_pool_str1730[sizeof("inethiopicextendeda")];
- char uniname2ctype_pool_str1736[sizeof("graph")];
- char uniname2ctype_pool_str1737[sizeof("olchiki")];
- char uniname2ctype_pool_str1741[sizeof("inphoneticextensionssupplement")];
- char uniname2ctype_pool_str1746[sizeof("inunifiedcanadianaboriginalsyllabicsextended")];
- char uniname2ctype_pool_str1748[sizeof("ingeometricshapes")];
- char uniname2ctype_pool_str1752[sizeof("invariationselectorssupplement")];
- char uniname2ctype_pool_str1754[sizeof("gujr")];
- char uniname2ctype_pool_str1762[sizeof("sharada")];
- char uniname2ctype_pool_str1766[sizeof("gujarati")];
- char uniname2ctype_pool_str1767[sizeof("nchar")];
- char uniname2ctype_pool_str1772[sizeof("innewtailue")];
- char uniname2ctype_pool_str1774[sizeof("glag")];
- char uniname2ctype_pool_str1780[sizeof("ideographic")];
- char uniname2ctype_pool_str1783[sizeof("shrd")];
- char uniname2ctype_pool_str1785[sizeof("insoyombo")];
- char uniname2ctype_pool_str1789[sizeof("inbamum")];
- char uniname2ctype_pool_str1800[sizeof("inlatin1supplement")];
- char uniname2ctype_pool_str1802[sizeof("dash")];
- char uniname2ctype_pool_str1806[sizeof("indingbats")];
- char uniname2ctype_pool_str1808[sizeof("spaceseparator")];
- char uniname2ctype_pool_str1813[sizeof("phagspa")];
- char uniname2ctype_pool_str1814[sizeof("titlecaseletter")];
- char uniname2ctype_pool_str1815[sizeof("incjkcompatibility")];
- char uniname2ctype_pool_str1818[sizeof("intangut")];
- char uniname2ctype_pool_str1819[sizeof("incombiningdiacriticalmarks")];
- char uniname2ctype_pool_str1821[sizeof("inlisu")];
- char uniname2ctype_pool_str1825[sizeof("siddham")];
- char uniname2ctype_pool_str1829[sizeof("incombiningdiacriticalmarksforsymbols")];
- char uniname2ctype_pool_str1840[sizeof("caucasianalbanian")];
- char uniname2ctype_pool_str1843[sizeof("uideo")];
- char uniname2ctype_pool_str1846[sizeof("indevanagariextended")];
- char uniname2ctype_pool_str1847[sizeof("narb")];
- char uniname2ctype_pool_str1857[sizeof("inbopomofo")];
- char uniname2ctype_pool_str1858[sizeof("incjkunifiedideographsextensionf")];
- char uniname2ctype_pool_str1861[sizeof("inmeroiticcursive")];
- char uniname2ctype_pool_str1866[sizeof("patsyn")];
- char uniname2ctype_pool_str1885[sizeof("insuperscriptsandsubscripts")];
- char uniname2ctype_pool_str1894[sizeof("lydi")];
- char uniname2ctype_pool_str1900[sizeof("lydian")];
- char uniname2ctype_pool_str1903[sizeof("intags")];
- char uniname2ctype_pool_str1909[sizeof("intelugu")];
- char uniname2ctype_pool_str1910[sizeof("intifinagh")];
- char uniname2ctype_pool_str1914[sizeof("ingeometricshapesextended")];
- char uniname2ctype_pool_str1915[sizeof("incombiningdiacriticalmarkssupplement")];
- char uniname2ctype_pool_str1922[sizeof("deva")];
- char uniname2ctype_pool_str1924[sizeof("inprivateusearea")];
- char uniname2ctype_pool_str1932[sizeof("devanagari")];
- char uniname2ctype_pool_str1933[sizeof("noncharactercodepoint")];
- char uniname2ctype_pool_str1934[sizeof("inbrahmi")];
- char uniname2ctype_pool_str1943[sizeof("lowercaseletter")];
- char uniname2ctype_pool_str1944[sizeof("word")];
- char uniname2ctype_pool_str1975[sizeof("caseignorable")];
- char uniname2ctype_pool_str1976[sizeof("inyiradicals")];
- char uniname2ctype_pool_str1979[sizeof("deprecated")];
- char uniname2ctype_pool_str1981[sizeof("thai")];
- char uniname2ctype_pool_str1983[sizeof("thaa")];
- char uniname2ctype_pool_str1985[sizeof("incombiningdiacriticalmarksextended")];
- char uniname2ctype_pool_str1989[sizeof("inmathematicalalphanumericsymbols")];
- char uniname2ctype_pool_str1991[sizeof("thaana")];
- char uniname2ctype_pool_str1995[sizeof("inornamentaldingbats")];
- char uniname2ctype_pool_str1997[sizeof("oldpersian")];
- char uniname2ctype_pool_str1998[sizeof("unassigned")];
- char uniname2ctype_pool_str1999[sizeof("insupplementalarrowsa")];
- char uniname2ctype_pool_str2003[sizeof("inpaucinhau")];
- char uniname2ctype_pool_str2005[sizeof("cwt")];
- char uniname2ctype_pool_str2007[sizeof("tirhuta")];
- char uniname2ctype_pool_str2008[sizeof("mahj")];
- char uniname2ctype_pool_str2013[sizeof("insmallformvariants")];
- char uniname2ctype_pool_str2015[sizeof("tirh")];
- char uniname2ctype_pool_str2017[sizeof("orkh")];
- char uniname2ctype_pool_str2020[sizeof("mahajani")];
- char uniname2ctype_pool_str2047[sizeof("softdotted")];
- char uniname2ctype_pool_str2049[sizeof("inphagspa")];
- char uniname2ctype_pool_str2056[sizeof("inethiopicextended")];
- char uniname2ctype_pool_str2059[sizeof("taitham")];
- char uniname2ctype_pool_str2061[sizeof("assigned")];
- char uniname2ctype_pool_str2068[sizeof("nbat")];
- char uniname2ctype_pool_str2072[sizeof("incyrillicextendedb")];
- char uniname2ctype_pool_str2073[sizeof("khoj")];
- char uniname2ctype_pool_str2076[sizeof("buhd")];
- char uniname2ctype_pool_str2079[sizeof("nabataean")];
- char uniname2ctype_pool_str2084[sizeof("inalphabeticpresentationforms")];
- char uniname2ctype_pool_str2091[sizeof("sorasompeng")];
- char uniname2ctype_pool_str2095[sizeof("insupplementalarrowsc")];
- char uniname2ctype_pool_str2096[sizeof("oldpermic")];
- char uniname2ctype_pool_str2097[sizeof("cyrl")];
- char uniname2ctype_pool_str2101[sizeof("finalpunctuation")];
- char uniname2ctype_pool_str2112[sizeof("meroitichieroglyphs")];
- char uniname2ctype_pool_str2114[sizeof("inarabicsupplement")];
- char uniname2ctype_pool_str2117[sizeof("phlp")];
- char uniname2ctype_pool_str2119[sizeof("inpsalterpahlavi")];
- char uniname2ctype_pool_str2134[sizeof("mlym")];
- char uniname2ctype_pool_str2139[sizeof("incjkunifiedideographsextensionb")];
- char uniname2ctype_pool_str2146[sizeof("palmyrene")];
- char uniname2ctype_pool_str2148[sizeof("insupplementalmathematicaloperators")];
- char uniname2ctype_pool_str2149[sizeof("malayalam")];
- char uniname2ctype_pool_str2154[sizeof("soyo")];
- char uniname2ctype_pool_str2158[sizeof("hex")];
- char uniname2ctype_pool_str2161[sizeof("phag")];
- char uniname2ctype_pool_str2165[sizeof("graphemeclusterbreak=ebase")];
- char uniname2ctype_pool_str2172[sizeof("graphemeclusterbreak=ebasegaz")];
- char uniname2ctype_pool_str2174[sizeof("inhanguljamo")];
- char uniname2ctype_pool_str2176[sizeof("bugi")];
- char uniname2ctype_pool_str2179[sizeof("graphemeclusterbreak=spacingmark")];
- char uniname2ctype_pool_str2182[sizeof("inhanguljamoextendeda")];
- char uniname2ctype_pool_str2187[sizeof("currencysymbol")];
- char uniname2ctype_pool_str2189[sizeof("tamil")];
- char uniname2ctype_pool_str2192[sizeof("graphemeclusterbreak=cr")];
- char uniname2ctype_pool_str2193[sizeof("talu")];
- char uniname2ctype_pool_str2196[sizeof("buginese")];
- char uniname2ctype_pool_str2197[sizeof("telu")];
- char uniname2ctype_pool_str2198[sizeof("ingeorgiansupplement")];
- char uniname2ctype_pool_str2199[sizeof("graphemeclusterbreak=emodifier")];
- char uniname2ctype_pool_str2207[sizeof("graphemeclusterbreak=regionalindicator")];
- char uniname2ctype_pool_str2210[sizeof("inlimbu")];
- char uniname2ctype_pool_str2224[sizeof("inenclosedcjklettersandmonths")];
- char uniname2ctype_pool_str2225[sizeof("tangut")];
- char uniname2ctype_pool_str2229[sizeof("inmathematicaloperators")];
- char uniname2ctype_pool_str2232[sizeof("newa")];
- char uniname2ctype_pool_str2249[sizeof("newtailue")];
- char uniname2ctype_pool_str2252[sizeof("hebr")];
- char uniname2ctype_pool_str2260[sizeof("inbuhid")];
- char uniname2ctype_pool_str2263[sizeof("insuttonsignwriting")];
- char uniname2ctype_pool_str2264[sizeof("syrc")];
- char uniname2ctype_pool_str2271[sizeof("dep")];
- char uniname2ctype_pool_str2276[sizeof("inbassavah")];
- char uniname2ctype_pool_str2286[sizeof("otheridcontinue")];
- char uniname2ctype_pool_str2289[sizeof("inletterlikesymbols")];
- char uniname2ctype_pool_str2296[sizeof("ext")];
- char uniname2ctype_pool_str2300[sizeof("other")];
- char uniname2ctype_pool_str2306[sizeof("inmongoliansupplement")];
- char uniname2ctype_pool_str2307[sizeof("othernumber")];
- char uniname2ctype_pool_str2311[sizeof("injavanese")];
- char uniname2ctype_pool_str2313[sizeof("olditalic")];
- char uniname2ctype_pool_str2327[sizeof("nshu")];
- char uniname2ctype_pool_str2349[sizeof("inarabicpresentationformsb")];
- char uniname2ctype_pool_str2350[sizeof("inlowsurrogates")];
- char uniname2ctype_pool_str2353[sizeof("incombininghalfmarks")];
- char uniname2ctype_pool_str2360[sizeof("inbengali")];
- char uniname2ctype_pool_str2364[sizeof("cwcf")];
- char uniname2ctype_pool_str2369[sizeof("inbuginese")];
- char uniname2ctype_pool_str2372[sizeof("syriac")];
- char uniname2ctype_pool_str2380[sizeof("ethi")];
- char uniname2ctype_pool_str2386[sizeof("otheralphabetic")];
- char uniname2ctype_pool_str2399[sizeof("inarabicmathematicalalphabeticsymbols")];
- char uniname2ctype_pool_str2408[sizeof("tang")];
- char uniname2ctype_pool_str2409[sizeof("buhid")];
- char uniname2ctype_pool_str2412[sizeof("graphemeclusterbreak=t")];
- char uniname2ctype_pool_str2413[sizeof("extender")];
- char uniname2ctype_pool_str2414[sizeof("graphemeclusterbreak=lvt")];
- char uniname2ctype_pool_str2422[sizeof("tagbanwa")];
- char uniname2ctype_pool_str2423[sizeof("hang")];
- char uniname2ctype_pool_str2433[sizeof("incurrencysymbols")];
- char uniname2ctype_pool_str2449[sizeof("ingujarati")];
- char uniname2ctype_pool_str2451[sizeof("paragraphseparator")];
- char uniname2ctype_pool_str2452[sizeof("tibt")];
- char uniname2ctype_pool_str2461[sizeof("tibetan")];
- char uniname2ctype_pool_str2465[sizeof("ogam")];
- char uniname2ctype_pool_str2467[sizeof("cwl")];
- char uniname2ctype_pool_str2469[sizeof("oalpha")];
- char uniname2ctype_pool_str2473[sizeof("hiragana")];
- char uniname2ctype_pool_str2475[sizeof("surrogate")];
- char uniname2ctype_pool_str2481[sizeof("inbamumsupplement")];
- char uniname2ctype_pool_str2483[sizeof("inrejang")];
- char uniname2ctype_pool_str2484[sizeof("intangutcomponents")];
- char uniname2ctype_pool_str2488[sizeof("hmng")];
- char uniname2ctype_pool_str2489[sizeof("graphemeclusterbreak=extend")];
- char uniname2ctype_pool_str2490[sizeof("graphemeclusterbreak=prepend")];
- char uniname2ctype_pool_str2493[sizeof("bassavah")];
- char uniname2ctype_pool_str2500[sizeof("ingothic")];
- char uniname2ctype_pool_str2507[sizeof("alphabetic")];
- char uniname2ctype_pool_str2509[sizeof("mathsymbol")];
- char uniname2ctype_pool_str2515[sizeof("oupper")];
- char uniname2ctype_pool_str2519[sizeof("oldhungarian")];
- char uniname2ctype_pool_str2523[sizeof("tavt")];
- char uniname2ctype_pool_str2526[sizeof("insupplementalpunctuation")];
- char uniname2ctype_pool_str2539[sizeof("dashpunctuation")];
- char uniname2ctype_pool_str2545[sizeof("inplayingcards")];
- char uniname2ctype_pool_str2550[sizeof("inaegeannumbers")];
- char uniname2ctype_pool_str2573[sizeof("osge")];
- char uniname2ctype_pool_str2576[sizeof("digit")];
- char uniname2ctype_pool_str2579[sizeof("dupl")];
- char uniname2ctype_pool_str2587[sizeof("inlinearbsyllabary")];
- char uniname2ctype_pool_str2589[sizeof("cypriot")];
- char uniname2ctype_pool_str2594[sizeof("wspace")];
- char uniname2ctype_pool_str2601[sizeof("whitespace")];
- char uniname2ctype_pool_str2617[sizeof("cwu")];
- char uniname2ctype_pool_str2618[sizeof("nushu")];
- char uniname2ctype_pool_str2622[sizeof("intagbanwa")];
- char uniname2ctype_pool_str2630[sizeof("sylo")];
- char uniname2ctype_pool_str2643[sizeof("graphemeclusterbreak=l")];
- char uniname2ctype_pool_str2649[sizeof("graphemeclusterbreak=control")];
- char uniname2ctype_pool_str2653[sizeof("oldturkic")];
- char uniname2ctype_pool_str2660[sizeof("changeswhencasemapped")];
- char uniname2ctype_pool_str2678[sizeof("rjng")];
- char uniname2ctype_pool_str2693[sizeof("cyrillic")];
- char uniname2ctype_pool_str2702[sizeof("hangul")];
- char uniname2ctype_pool_str2705[sizeof("modifiersymbol")];
- char uniname2ctype_pool_str2708[sizeof("inalchemicalsymbols")];
- char uniname2ctype_pool_str2710[sizeof("insupplementaryprivateuseareaa")];
- char uniname2ctype_pool_str2717[sizeof("orya")];
- char uniname2ctype_pool_str2751[sizeof("inmahjongtiles")];
- char uniname2ctype_pool_str2758[sizeof("changeswhentitlecased")];
- char uniname2ctype_pool_str2763[sizeof("tifinagh")];
- char uniname2ctype_pool_str2775[sizeof("otherlowercase")];
- char uniname2ctype_pool_str2779[sizeof("inglagolitic")];
- char uniname2ctype_pool_str2791[sizeof("otheridstart")];
- char uniname2ctype_pool_str2792[sizeof("ugar")];
- char uniname2ctype_pool_str2797[sizeof("otherletter")];
- char uniname2ctype_pool_str2823[sizeof("inhangulsyllables")];
- char uniname2ctype_pool_str2829[sizeof("elba")];
- char uniname2ctype_pool_str2834[sizeof("intagalog")];
- char uniname2ctype_pool_str2850[sizeof("otheruppercase")];
- char uniname2ctype_pool_str2879[sizeof("omath")];
- char uniname2ctype_pool_str2883[sizeof("warangciti")];
- char uniname2ctype_pool_str2888[sizeof("sylotinagri")];
- char uniname2ctype_pool_str2890[sizeof("shaw")];
- char uniname2ctype_pool_str2891[sizeof("inpahawhhmong")];
- char uniname2ctype_pool_str2901[sizeof("inhalfwidthandfullwidthforms")];
- char uniname2ctype_pool_str2905[sizeof("inlatinextendedb")];
- char uniname2ctype_pool_str2926[sizeof("osmanya")];
- char uniname2ctype_pool_str2930[sizeof("graphemeclusterbreak=lf")];
- char uniname2ctype_pool_str2932[sizeof("othersymbol")];
- char uniname2ctype_pool_str2953[sizeof("defaultignorablecodepoint")];
- char uniname2ctype_pool_str2967[sizeof("incypriotsyllabary")];
- char uniname2ctype_pool_str2968[sizeof("khudawadi")];
- char uniname2ctype_pool_str2972[sizeof("kayahli")];
- char uniname2ctype_pool_str2984[sizeof("hung")];
- char uniname2ctype_pool_str2987[sizeof("unknown")];
- char uniname2ctype_pool_str2989[sizeof("inyijinghexagramsymbols")];
- char uniname2ctype_pool_str3007[sizeof("elbasan")];
- char uniname2ctype_pool_str3016[sizeof("inbopomofoextended")];
- char uniname2ctype_pool_str3019[sizeof("changeswhenlowercased")];
- char uniname2ctype_pool_str3020[sizeof("otherpunctuation")];
- char uniname2ctype_pool_str3038[sizeof("upper")];
- char uniname2ctype_pool_str3052[sizeof("insupplementalarrowsb")];
- char uniname2ctype_pool_str3066[sizeof("oldnortharabian")];
- char uniname2ctype_pool_str3094[sizeof("changeswhenuppercased")];
- char uniname2ctype_pool_str3113[sizeof("uppercase")];
- char uniname2ctype_pool_str3121[sizeof("ugaritic")];
- char uniname2ctype_pool_str3153[sizeof("otherdefaultignorablecodepoint")];
- char uniname2ctype_pool_str3177[sizeof("othermath")];
- char uniname2ctype_pool_str3180[sizeof("tfng")];
- char uniname2ctype_pool_str3193[sizeof("symbol")];
- char uniname2ctype_pool_str3195[sizeof("hexdigit")];
- char uniname2ctype_pool_str3213[sizeof("any")];
- char uniname2ctype_pool_str3235[sizeof("inhanguljamoextendedb")];
- char uniname2ctype_pool_str3238[sizeof("ethiopic")];
- char uniname2ctype_pool_str3276[sizeof("aghb")];
- char uniname2ctype_pool_str3279[sizeof("graphemeclusterbreak=v")];
- char uniname2ctype_pool_str3280[sizeof("graphemeclusterbreak=lv")];
- char uniname2ctype_pool_str3285[sizeof("soyombo")];
- char uniname2ctype_pool_str3296[sizeof("graphemeclusterbreak=zwj")];
- char uniname2ctype_pool_str3305[sizeof("graphemeclusterbreak=glueafterzwj")];
- char uniname2ctype_pool_str3315[sizeof("sgnw")];
- char uniname2ctype_pool_str3367[sizeof("changeswhencasefolded")];
- char uniname2ctype_pool_str3373[sizeof("ogham")];
- char uniname2ctype_pool_str3409[sizeof("uppercaseletter")];
- char uniname2ctype_pool_str3438[sizeof("inhebrew")];
- char uniname2ctype_pool_str3442[sizeof("inhighprivateusesurrogates")];
- char uniname2ctype_pool_str3448[sizeof("openpunctuation")];
- char uniname2ctype_pool_str3453[sizeof("ogrext")];
- char uniname2ctype_pool_str3454[sizeof("hyphen")];
- char uniname2ctype_pool_str3465[sizeof("tagb")];
- char uniname2ctype_pool_str3496[sizeof("inyisyllables")];
- char uniname2ctype_pool_str3593[sizeof("oldsoutharabian")];
- char uniname2ctype_pool_str3662[sizeof("duployan")];
- char uniname2ctype_pool_str3676[sizeof("hluw")];
- char uniname2ctype_pool_str3689[sizeof("inglagoliticsupplement")];
- char uniname2ctype_pool_str3697[sizeof("insupplementalsymbolsandpictographs")];
- char uniname2ctype_pool_str3763[sizeof("insupplementaryprivateuseareab")];
- char uniname2ctype_pool_str3791[sizeof("inegyptianhieroglyphs")];
- char uniname2ctype_pool_str3960[sizeof("rejang")];
- char uniname2ctype_pool_str3971[sizeof("inhangulcompatibilityjamo")];
- char uniname2ctype_pool_str4036[sizeof("telugu")];
- char uniname2ctype_pool_str4164[sizeof("tglg")];
- char uniname2ctype_pool_str4187[sizeof("tagalog")];
- char uniname2ctype_pool_str4208[sizeof("othergraphemeextend")];
- char uniname2ctype_pool_str4460[sizeof("unifiedideograph")];
- char uniname2ctype_pool_str4464[sizeof("inboxdrawing")];
- char uniname2ctype_pool_str4483[sizeof("pahawhhmong")];
- char uniname2ctype_pool_str4608[sizeof("inhighsurrogates")];
- char uniname2ctype_pool_str4634[sizeof("signwriting")];
- char uniname2ctype_pool_str4678[sizeof("zyyy")];
- char uniname2ctype_pool_str4841[sizeof("egyp")];
- char uniname2ctype_pool_str5170[sizeof("hebrew")];
- char uniname2ctype_pool_str6145[sizeof("egyptianhieroglyphs")];
-#endif /* USE_UNICODE_PROPERTIES */
- };
-static const struct uniname2ctype_pool_t uniname2ctype_pool_contents =
- {
-#ifndef USE_UNICODE_PROPERTIES
- "word",
-#else /* USE_UNICODE_PROPERTIES */
- "yi",
- "cn",
- "lina",
- "yiii",
- "lana",
- "ci",
- "mn",
- "z",
- "mani",
- "lo",
- "me",
- "loe",
- "lao",
- "laoo",
- "co",
- "miao",
- "pi",
- "inkannada",
- "gran",
- "innko",
- "zzzz",
- "pe",
- "cari",
- "lineara",
- "carian",
- "mendekikakui",
- "geor",
- "po",
- "grek",
- "meeteimayek",
- "mark",
- "mero",
- "kana",
- "m",
- "mro",
- "mroo",
- "greek",
- "gonm",
- "inkharoshthi",
- "cakm",
- "inmanichaean",
- "c",
- "inarmenian",
- "common",
- "inosmanya",
- "inmro",
- "inmiao",
- "mandaic",
- "inmyanmar",
- "lm",
- "prependedconcatenationmark",
- "inideographicsymbolsandpunctuation",
- "inchakma",
- "inkhmer",
- "perm",
- "connectorpunctuation",
- "marc",
- "combiningmark",
- "merc",
- "inrunic",
- "incarian",
- "incuneiformnumbersandpunctuation",
- "inahom",
- "incherokee",
- "qaai",
- "cans",
- "lc",
- "incuneiform",
- "cc",
- "armn",
- "inavestan",
- "armi",
- "mc",
- "armenian",
- "inipaextensions",
- "inmarchen",
- "pc",
- "insharada",
- "lineseparator",
- "masaramgondi",
- "inarrows",
- "ri",
- "incham",
- "latn",
- "incyrillic",
- "latin",
- "inzanabazarsquare",
- "insamaritan",
- "pcm",
- "inmasaramgondi",
- "qmark",
- "qaac",
- "mtei",
- "inthai",
- "inscriptionalparthian",
- "inthaana",
- "inkaithi",
- "initialpunctuation",
- "inkatakana",
- "inkhmersymbols",
- "insyriac",
- "intakri",
- "prti",
- "arabic",
- "mand",
- "cs",
- "mend",
- "zs",
- "letter",
- "privateuse",
- "modi",
- "katakana",
- "ideo",
- "brai",
- "xidcontinue",
- "inmyanmarextendeda",
- "ascii",
- "ps",
- "inkanaextendeda",
- "inmeeteimayek",
- "inruminumeralsymbols",
- "letternumber",
- "knda",
- "kannada",
- "inoldnortharabian",
- "inideographicdescriptioncharacters",
- "inmodi",
- "incjkcompatibilityforms",
- "incjkcompatibilityideographs",
- "xidc",
- "inmendekikakui",
- "brahmi",
- "inolditalic",
- "inmiscellaneousmathematicalsymbolsa",
- "inspecials",
- "inemoticons",
- "patternwhitespace",
- "gothic",
- "intransportandmapsymbols",
- "l",
- "psalterpahlavi",
- "vai",
- "vaii",
- "lt",
- "meroiticcursive",
- "xids",
- "incommonindicnumberforms",
- "inmandaic",
- "inlineara",
- "incjkcompatibilityideographssupplement",
- "inlao",
- "insundanese",
- "mongolian",
- "bamum",
- "idc",
- "inancientsymbols",
- "kali",
- "grlink",
- "grext",
- "control",
- "inkanasupplement",
- "inopticalcharacterrecognition",
- "inadlam",
- "so",
- "inoldsoutharabian",
- "sk",
-#endif /* USE_UNICODE_PROPERTIES */
- "print",
-#ifndef USE_UNICODE_PROPERTIES
- "punct",
- "alpha",
-#else /* USE_UNICODE_PROPERTIES */
- "idsbinaryoperator",
- "palm",
- "batk",
- "indominotiles",
- "intaitham",
- "inlycian",
- "sora",
- "batak",
- "inmodifiertoneletters",
- "patws",
- "inmalayalam",
- "incjkstrokes",
- "incontrolpictures",
- "samr",
- "bass",
- "samaritan",
- "inmusicalsymbols",
- "ids",
- "pd",
- "sm",
- "pauc",
- "joinc",
- "inlinearbideograms",
- "idcontinue",
- "inancientgreekmusicalnotation",
- "inoldturkic",
-#endif /* USE_UNICODE_PROPERTIES */
- "alnum",
-#ifdef USE_UNICODE_PROPERTIES
- "inugaritic",
- "s",
- "inmiscellaneoussymbols",
- "n",
- "lisu",
- "inmiscellaneoussymbolsandarrows",
- "insylotinagri",
- "inmiscellaneoussymbolsandpictographs",
- "sc",
- "no",
- "ital",
- "p",
- "xpeo",
- "di",
- "idst",
- "intaile",
- "nko",
- "nkoo",
- "dia",
- "inphoenician",
- "inlatinextendeda",
- "indeseret",
- "inlatinextendede",
- "incaucasianalbanian",
- "insaurashtra",
- "inmeeteimayekextensions",
- "idstart",
- "bali",
- "inspacingmodifierletters",
- "bengali",
- "intamil",
- "inmultani",
- "vs",
- "inlydian",
- "balinese",
- "lepc",
- "cased",
- "zinh",
- "blank",
- "runr",
- "patternsyntax",
- "bidic",
-#endif /* USE_UNICODE_PROPERTIES */
- "xdigit",
-#ifndef USE_UNICODE_PROPERTIES
- "upper",
- "ascii",
-#else /* USE_UNICODE_PROPERTIES */
- "xidstart",
- "inphaistosdisc",
- "inancientgreeknumbers",
- "canadianaboriginal",
- "cher",
- "plrd",
- "sind",
- "cherokee",
- "phoenician",
- "marchen",
- "inhiragana",
- "inearlydynasticcuneiform",
- "graphemebase",
- "cham",
- "inimperialaramaic",
- "kaithi",
- "insiddham",
- "diacritic",
- "chakma",
- "graphemelink",
- "inkhudawadi",
- "inmahajani",
- "khojki",
- "inogham",
- "khar",
- "incountingrodnumerals",
- "manichaean",
- "coptic",
- "bamu",
- "sterm",
- "inethiopic",
- "ll",
- "inolchiki",
- "inlatinextendedc",
- "zl",
- "adlm",
- "incyrillicsupplement",
- "incyrillicextendeda",
- "incherokeesupplement",
- "decimalnumber",
- "khmr",
- "copt",
- "ahom",
- "runic",
- "intaixuanjingsymbols",
- "insinhala",
- "cprt",
- "imperialaramaic",
- "casedletter",
- "khmer",
- "linb",
- "adlam",
- "ininscriptionalparthian",
- "ininscriptionalpahlavi",
- "sinhala",
- "zanb",
- "incjkunifiedideographsextensiona",
- "multani",
- "quotationmark",
- "incjkunifiedideographsextensione",
- "innabataean",
- "inbhaiksuki",
- "inelbasan",
- "inkanbun",
- "inscriptionalpahlavi",
- "bopo",
- "linearb",
- "incyrillicextendedc",
- "glagolitic",
- "kharoshthi",
- "inoldpersian",
- "goth",
- "math",
- "joincontrol",
- "punct",
- "lu",
- "limb",
- "inmiscellaneoustechnical",
- "han",
- "hani",
- "invai",
- "sundanese",
- "taile",
- "takri",
- "grantha",
- "hano",
- "inhatran",
- "oriya",
- "intirhuta",
- "guru",
- "kthi",
- "saur",
- "incjkunifiedideographsextensionc",
- "hanunoo",
- "paucinhau",
- "takr",
- "hira",
- "inarabic",
- "bopomofo",
- "radical",
- "gurmukhi",
- "inkhojki",
- "arab",
- "limbu",
- "inoldpermic",
- "brah",
- "inoldhungarian",
- "inshorthandformatcontrols",
- "incoptic",
- "sd",
- "sidd",
- "inherited",
- "incjkunifiedideographs",
- "term",
- "incjksymbolsandpunctuation",
- "graphemeextend",
- "dsrt",
-#endif /* USE_UNICODE_PROPERTIES */
- "cntrl",
-#ifdef USE_UNICODE_PROPERTIES
- "xsux",
- "insyriacsupplement",
- "inbasiclatin",
- "deseret",
- "inenclosedideographicsupplement",
- "bidicontrol",
- "closepunctuation",
- "inlatinextendedadditional",
- "inarabicpresentationformsa",
- "grbase",
- "mong",
- "anatolianhieroglyphs",
- "inenclosedalphanumerics",
- "ingrantha",
- "georgian",
- "osage",
- "inosage",
- "ingeneralpunctuation",
- "saurashtra",
- "inshavian",
-#endif /* USE_UNICODE_PROPERTIES */
- "space",
-#ifdef USE_UNICODE_PROPERTIES
- "mult",
- "inpalmyrene",
- "inanatolianhieroglyphs",
- "spacingmark",
- "alpha",
- "ingeorgian",
- "intibetan",
- "inlepcha",
- "inbatak",
- "osma",
- "bhks",
- "inmongolian",
- "variationselector",
- "braille",
- "phli",
- "bhaiksuki",
- "phnx",
- "inblockelements",
-#ifdef USE_UNICODE_AGE_PROPERTIES
- "age=1.1",
- "age=4.1",
- "age=4.0",
- "age=10.0",
- "age=2.1",
- "age=2.0",
- "age=6.1",
- "age=6.0",
- "age=9.0",
- "age=8.0",
- "age=6.2",
- "age=7.0",
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- "inenclosedalphanumericsupplement",
- "innumberforms",
-#ifdef USE_UNICODE_AGE_PROPERTIES
- "age=5.1",
- "age=5.0",
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- "nd",
- "separator",
-#ifdef USE_UNICODE_AGE_PROPERTIES
- "age=5.2",
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- "ingurmukhi",
- "incjkunifiedideographsextensiond",
- "taiviet",
- "sinh",
-#ifdef USE_UNICODE_AGE_PROPERTIES
- "age=3.1",
- "age=3.0",
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- "hatran",
-#ifdef USE_UNICODE_AGE_PROPERTIES
- "age=3.2",
- "age=6.3",
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- "format",
- "shavian",
- "insinhalaarchaicnumbers",
- "cuneiform",
- "inmyanmarextendedb",
- "punctuation",
- "inarabicextendeda",
- "hatr",
- "inhanunoo",
- "inlatinextendedd",
- "modifierletter",
- "odi",
- "ahex",
- "logicalorderexception",
- "inbyzantinemusicalsymbols",
- "sund",
- "number",
- "insundanesesupplement",
- "incopticepactnumbers",
- "zp",
- "asciihexdigit",
- "indevanagari",
- "innewa",
- "avestan",
- "insorasompeng",
- "inmiscellaneousmathematicalsymbolsb",
- "inbraillepatterns",
- "nonspacingmark",
- "ingreekandcoptic",
-#endif /* USE_UNICODE_PROPERTIES */
- "xposixpunct",
-#ifdef USE_UNICODE_PROPERTIES
- "inwarangciti",
- "oidc",
- "terminalpunctuation",
- "cf",
-#endif /* USE_UNICODE_PROPERTIES */
- "lower",
-#ifdef USE_UNICODE_PROPERTIES
- "inunifiedcanadianaboriginalsyllabics",
- "idsb",
- "inbalinese",
- "induployan",
- "innoblock",
- "pf",
- "inoriya",
- "inkatakanaphoneticextensions",
- "inkayahli",
- "wara",
- "innushu",
- "lepcha",
- "inmeroitichieroglyphs",
- "beng",
- "idstrinaryoperator",
- "oids",
- "regionalindicator",
- "enclosingmark",
- "java",
- "tale",
- "inphoneticextensions",
- "lowercase",
- "inverticalforms",
- "javanese",
- "sentenceterminal",
- "ingreekextended",
- "invariationselectors",
- "cwcm",
- "lyci",
- "avst",
- "lycian",
- "zanabazarsquare",
- "sarb",
- "invedicextensions",
- "inkangxiradicals",
- "intaiviet",
- "mymr",
- "incjkradicalssupplement",
- "myanmar",
- "taml",
- "olower",
- "nl",
- "inethiopicsupplement",
- "olck",
- "inethiopicextendeda",
-#endif /* USE_UNICODE_PROPERTIES */
- "graph",
-#ifdef USE_UNICODE_PROPERTIES
- "olchiki",
- "inphoneticextensionssupplement",
- "inunifiedcanadianaboriginalsyllabicsextended",
- "ingeometricshapes",
- "invariationselectorssupplement",
- "gujr",
- "sharada",
- "gujarati",
- "nchar",
- "innewtailue",
- "glag",
- "ideographic",
- "shrd",
- "insoyombo",
- "inbamum",
- "inlatin1supplement",
- "dash",
- "indingbats",
- "spaceseparator",
- "phagspa",
- "titlecaseletter",
- "incjkcompatibility",
- "intangut",
- "incombiningdiacriticalmarks",
- "inlisu",
- "siddham",
- "incombiningdiacriticalmarksforsymbols",
- "caucasianalbanian",
- "uideo",
- "indevanagariextended",
- "narb",
- "inbopomofo",
- "incjkunifiedideographsextensionf",
- "inmeroiticcursive",
- "patsyn",
- "insuperscriptsandsubscripts",
- "lydi",
- "lydian",
- "intags",
- "intelugu",
- "intifinagh",
- "ingeometricshapesextended",
- "incombiningdiacriticalmarkssupplement",
- "deva",
- "inprivateusearea",
- "devanagari",
- "noncharactercodepoint",
- "inbrahmi",
- "lowercaseletter",
- "word",
- "caseignorable",
- "inyiradicals",
- "deprecated",
- "thai",
- "thaa",
- "incombiningdiacriticalmarksextended",
- "inmathematicalalphanumericsymbols",
- "thaana",
- "inornamentaldingbats",
- "oldpersian",
- "unassigned",
- "insupplementalarrowsa",
- "inpaucinhau",
- "cwt",
- "tirhuta",
- "mahj",
- "insmallformvariants",
- "tirh",
- "orkh",
- "mahajani",
- "softdotted",
- "inphagspa",
- "inethiopicextended",
- "taitham",
- "assigned",
- "nbat",
- "incyrillicextendedb",
- "khoj",
- "buhd",
- "nabataean",
- "inalphabeticpresentationforms",
- "sorasompeng",
- "insupplementalarrowsc",
- "oldpermic",
- "cyrl",
- "finalpunctuation",
- "meroitichieroglyphs",
- "inarabicsupplement",
- "phlp",
- "inpsalterpahlavi",
- "mlym",
- "incjkunifiedideographsextensionb",
- "palmyrene",
- "insupplementalmathematicaloperators",
- "malayalam",
- "soyo",
- "hex",
- "phag",
- "graphemeclusterbreak=ebase",
- "graphemeclusterbreak=ebasegaz",
- "inhanguljamo",
- "bugi",
- "graphemeclusterbreak=spacingmark",
- "inhanguljamoextendeda",
- "currencysymbol",
- "tamil",
- "graphemeclusterbreak=cr",
- "talu",
- "buginese",
- "telu",
- "ingeorgiansupplement",
- "graphemeclusterbreak=emodifier",
- "graphemeclusterbreak=regionalindicator",
- "inlimbu",
- "inenclosedcjklettersandmonths",
- "tangut",
- "inmathematicaloperators",
- "newa",
- "newtailue",
- "hebr",
- "inbuhid",
- "insuttonsignwriting",
- "syrc",
- "dep",
- "inbassavah",
- "otheridcontinue",
- "inletterlikesymbols",
- "ext",
- "other",
- "inmongoliansupplement",
- "othernumber",
- "injavanese",
- "olditalic",
- "nshu",
- "inarabicpresentationformsb",
- "inlowsurrogates",
- "incombininghalfmarks",
- "inbengali",
- "cwcf",
- "inbuginese",
- "syriac",
- "ethi",
- "otheralphabetic",
- "inarabicmathematicalalphabeticsymbols",
- "tang",
- "buhid",
- "graphemeclusterbreak=t",
- "extender",
- "graphemeclusterbreak=lvt",
- "tagbanwa",
- "hang",
- "incurrencysymbols",
- "ingujarati",
- "paragraphseparator",
- "tibt",
- "tibetan",
- "ogam",
- "cwl",
- "oalpha",
- "hiragana",
- "surrogate",
- "inbamumsupplement",
- "inrejang",
- "intangutcomponents",
- "hmng",
- "graphemeclusterbreak=extend",
- "graphemeclusterbreak=prepend",
- "bassavah",
- "ingothic",
- "alphabetic",
- "mathsymbol",
- "oupper",
- "oldhungarian",
- "tavt",
- "insupplementalpunctuation",
- "dashpunctuation",
- "inplayingcards",
- "inaegeannumbers",
- "osge",
-#endif /* USE_UNICODE_PROPERTIES */
- "digit",
-#ifndef USE_UNICODE_PROPERTIES
- "blank"
-#else /* USE_UNICODE_PROPERTIES */
- "dupl",
- "inlinearbsyllabary",
- "cypriot",
- "wspace",
- "whitespace",
- "cwu",
- "nushu",
- "intagbanwa",
- "sylo",
- "graphemeclusterbreak=l",
- "graphemeclusterbreak=control",
- "oldturkic",
- "changeswhencasemapped",
- "rjng",
- "cyrillic",
- "hangul",
- "modifiersymbol",
- "inalchemicalsymbols",
- "insupplementaryprivateuseareaa",
- "orya",
- "inmahjongtiles",
- "changeswhentitlecased",
- "tifinagh",
- "otherlowercase",
- "inglagolitic",
- "otheridstart",
- "ugar",
- "otherletter",
- "inhangulsyllables",
- "elba",
- "intagalog",
- "otheruppercase",
- "omath",
- "warangciti",
- "sylotinagri",
- "shaw",
- "inpahawhhmong",
- "inhalfwidthandfullwidthforms",
- "inlatinextendedb",
- "osmanya",
- "graphemeclusterbreak=lf",
- "othersymbol",
- "defaultignorablecodepoint",
- "incypriotsyllabary",
- "khudawadi",
- "kayahli",
- "hung",
- "unknown",
- "inyijinghexagramsymbols",
- "elbasan",
- "inbopomofoextended",
- "changeswhenlowercased",
- "otherpunctuation",
- "upper",
- "insupplementalarrowsb",
- "oldnortharabian",
- "changeswhenuppercased",
- "uppercase",
- "ugaritic",
- "otherdefaultignorablecodepoint",
- "othermath",
- "tfng",
- "symbol",
- "hexdigit",
- "any",
- "inhanguljamoextendedb",
- "ethiopic",
- "aghb",
- "graphemeclusterbreak=v",
- "graphemeclusterbreak=lv",
- "soyombo",
- "graphemeclusterbreak=zwj",
- "graphemeclusterbreak=glueafterzwj",
- "sgnw",
- "changeswhencasefolded",
- "ogham",
- "uppercaseletter",
- "inhebrew",
- "inhighprivateusesurrogates",
- "openpunctuation",
- "ogrext",
- "hyphen",
- "tagb",
- "inyisyllables",
- "oldsoutharabian",
- "duployan",
- "hluw",
- "inglagoliticsupplement",
- "insupplementalsymbolsandpictographs",
- "insupplementaryprivateuseareab",
- "inegyptianhieroglyphs",
- "rejang",
- "inhangulcompatibilityjamo",
- "telugu",
- "tglg",
- "tagalog",
- "othergraphemeextend",
- "unifiedideograph",
- "inboxdrawing",
- "pahawhhmong",
- "inhighsurrogates",
- "signwriting",
- "zyyy",
- "egyp",
- "hebrew",
- "egyptianhieroglyphs"
-#endif /* USE_UNICODE_PROPERTIES */
- };
-#define uniname2ctype_pool ((const char *) &uniname2ctype_pool_contents)
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-const struct uniname2ctype_struct *
-uniname2ctype_p (str, len)
- register const char *str;
- register unsigned int len;
-{
- static const struct uniname2ctype_struct wordlist[] =
- {
-#ifdef USE_UNICODE_PROPERTIES
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str10), 111},
- {-1}, {-1},
- {uniname2ctype_offset(str13), 21},
- {uniname2ctype_offset(str14), 184},
- {uniname2ctype_offset(str15), 111},
- {uniname2ctype_offset(str16), 152},
- {uniname2ctype_offset(str17), 61},
- {-1},
- {uniname2ctype_offset(str19), 34},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str26), 52},
- {-1},
- {uniname2ctype_offset(str28), 186},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str33), 28},
- {-1},
- {uniname2ctype_offset(str35), 33},
- {-1},
- {uniname2ctype_offset(str37), 241},
- {-1},
- {uniname2ctype_offset(str39), 95},
- {uniname2ctype_offset(str40), 95},
- {uniname2ctype_offset(str41), 22},
- {uniname2ctype_offset(str42), 173},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str47), 44},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str51), 315},
- {uniname2ctype_offset(str52), 181},
- {-1},
- {uniname2ctype_offset(str54), 303},
- {uniname2ctype_offset(str55), 250},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str59), 42},
- {uniname2ctype_offset(str60), 149},
- {uniname2ctype_offset(str61), 184},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str66), 149},
- {-1}, {-1},
- {uniname2ctype_offset(str69), 187},
- {uniname2ctype_offset(str70), 98},
- {uniname2ctype_offset(str71), 45},
- {uniname2ctype_offset(str72), 77},
- {uniname2ctype_offset(str73), 160},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str80), 31},
- {-1},
- {uniname2ctype_offset(str82), 172},
- {-1}, {-1},
- {uniname2ctype_offset(str85), 108},
- {uniname2ctype_offset(str86), 31},
- {uniname2ctype_offset(str87), 189},
- {uniname2ctype_offset(str88), 189},
- {-1},
- {uniname2ctype_offset(str90), 77},
- {-1}, {-1},
- {uniname2ctype_offset(str93), 212},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str97), 479},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str105), 170},
- {uniname2ctype_offset(str106), 482},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str111), 18},
- {-1},
- {uniname2ctype_offset(str113), 297},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str117), 75},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str122), 465},
- {uniname2ctype_offset(str123), 521},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str129), 524},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str137), 169},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str142), 321},
- {uniname2ctype_offset(str143), 27},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str150), 248},
- {-1}, {-1},
- {uniname2ctype_offset(str153), 525},
- {uniname2ctype_offset(str154), 493},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str160), 334},
- {uniname2ctype_offset(str161), 194},
- {uniname2ctype_offset(str162), 40},
- {-1},
- {uniname2ctype_offset(str164), 208},
- {-1}, {-1},
- {uniname2ctype_offset(str167), 31},
- {uniname2ctype_offset(str168), 171},
- {uniname2ctype_offset(str169), 329},
- {uniname2ctype_offset(str170), 456},
- {-1},
- {uniname2ctype_offset(str172), 516},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str184), 507},
- {-1},
- {uniname2ctype_offset(str186), 326},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str191), 115},
- {-1},
- {uniname2ctype_offset(str193), 102},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str205), 25},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str210), 515},
- {-1}, {-1},
- {uniname2ctype_offset(str213), 19},
- {-1},
- {uniname2ctype_offset(str215), 79},
- {uniname2ctype_offset(str216), 483},
- {uniname2ctype_offset(str217), 161},
- {-1},
- {uniname2ctype_offset(str219), 32},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str223), 79},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str227), 291},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str238), 513},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str243), 40},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str250), 495},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str255), 53},
- {uniname2ctype_offset(str256), 212},
- {-1}, {-1},
- {uniname2ctype_offset(str259), 363},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str268), 249},
- {-1},
- {uniname2ctype_offset(str270), 424},
- {uniname2ctype_offset(str271), 76},
- {uniname2ctype_offset(str272), 295},
- {uniname2ctype_offset(str273), 76},
- {-1}, {-1},
- {uniname2ctype_offset(str276), 509},
- {-1}, {-1},
- {uniname2ctype_offset(str279), 304},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str283), 248},
- {-1},
- {uniname2ctype_offset(str285), 514},
- {-1}, {-1},
- {uniname2ctype_offset(str288), 221},
- {uniname2ctype_offset(str289), 129},
- {-1},
- {uniname2ctype_offset(str291), 160},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str295), 318},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str300), 163},
- {uniname2ctype_offset(str301), 302},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str309), 491},
- {-1},
- {uniname2ctype_offset(str311), 44},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str315), 394},
- {-1},
- {uniname2ctype_offset(str317), 340},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str343), 300},
- {uniname2ctype_offset(str344), 506},
- {uniname2ctype_offset(str345), 163},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str356), 81},
- {uniname2ctype_offset(str357), 169},
- {-1},
- {uniname2ctype_offset(str359), 23},
- {-1},
- {uniname2ctype_offset(str361), 187},
- {uniname2ctype_offset(str362), 55},
- {uniname2ctype_offset(str363), 24},
- {-1},
- {uniname2ctype_offset(str365), 22},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str369), 188},
- {uniname2ctype_offset(str370), 108},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str377), 227},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str383), 127},
- {uniname2ctype_offset(str384), 70},
- {-1},
- {uniname2ctype_offset(str386), 425},
- {uniname2ctype_offset(str387), 14},
- {-1},
- {uniname2ctype_offset(str389), 46},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str393), 529},
- {-1}, {-1},
- {uniname2ctype_offset(str396), 431},
- {-1}, {-1},
- {uniname2ctype_offset(str399), 489},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str408), 37},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str412), 91},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str425), 91},
- {-1}, {-1},
- {uniname2ctype_offset(str428), 481},
- {-1},
- {uniname2ctype_offset(str430), 391},
- {-1},
- {uniname2ctype_offset(str432), 504},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str440), 444},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str445), 438},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str453), 70},
- {-1},
- {uniname2ctype_offset(str455), 541},
- {-1}, {-1},
- {uniname2ctype_offset(str458), 168},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str480), 458},
- {-1},
- {uniname2ctype_offset(str482), 374},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str486), 448},
- {uniname2ctype_offset(str487), 550},
- {uniname2ctype_offset(str488), 246},
- {uniname2ctype_offset(str489), 113},
- {-1}, {-1},
- {uniname2ctype_offset(str492), 552},
- {uniname2ctype_offset(str493), 24},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str509), 195},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str516), 144},
- {uniname2ctype_offset(str517), 144},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str523), 29},
- {uniname2ctype_offset(str524), 171},
- {-1},
- {uniname2ctype_offset(str526), 69},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str530), 415},
- {uniname2ctype_offset(str531), 305},
- {-1},
- {uniname2ctype_offset(str533), 469},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str541), 562},
- {-1}, {-1},
- {uniname2ctype_offset(str544), 319},
- {uniname2ctype_offset(str545), 345},
- {-1},
- {uniname2ctype_offset(str547), 106},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str552), 158},
- {-1},
- {uniname2ctype_offset(str554), 68},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str561), 453},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str573), 146},
- {uniname2ctype_offset(str574), 74},
- {-1},
- {uniname2ctype_offset(str576), 72},
- {uniname2ctype_offset(str577), 19},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str586), 528},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str591), 367},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str596), 542},
- {-1},
- {uniname2ctype_offset(str598), 51},
- {-1}, {-1},
- {uniname2ctype_offset(str601), 480},
- {uniname2ctype_offset(str602), 49},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str606), 7},
- {uniname2ctype_offset(str607), 234},
- {-1},
- {uniname2ctype_offset(str609), 192},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str618), 167},
- {uniname2ctype_offset(str619), 545},
- {uniname2ctype_offset(str620), 342},
- {-1},
- {uniname2ctype_offset(str622), 455},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str629), 175},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str636), 167},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str642), 412},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str657), 246},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str665), 316},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str670), 399},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str681), 366},
- {-1}, {-1},
- {uniname2ctype_offset(str684), 156},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str689), 178},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str693), 156},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str699), 534},
- {uniname2ctype_offset(str700), 67},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str705), 41},
- {-1}, {-1},
- {uniname2ctype_offset(str708), 50},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str715), 193},
- {uniname2ctype_offset(str716), 218},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str725), 450},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str730), 68},
- {-1},
- {uniname2ctype_offset(str732), 535},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str737), 487},
- {uniname2ctype_offset(str738), 13},
- {uniname2ctype_offset(str739), 461},
- {-1},
- {uniname2ctype_offset(str741), 47},
- {uniname2ctype_offset(str742), 372},
- {uniname2ctype_offset(str743), 35},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str748), 157},
- {-1}, {-1},
- {uniname2ctype_offset(str751), 380},
- {-1},
- {uniname2ctype_offset(str753), 414},
- {-1}, {-1},
- {uniname2ctype_offset(str756), 549},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str770), 48},
- {-1}, {-1},
- {uniname2ctype_offset(str773), 38},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str777), 112},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str781), 39},
- {uniname2ctype_offset(str782), 134},
- {-1}, {-1},
- {uniname2ctype_offset(str785), 71},
- {-1},
- {uniname2ctype_offset(str787), 235},
- {uniname2ctype_offset(str788), 338},
- {-1}, {-1},
- {uniname2ctype_offset(str791), 140},
- {uniname2ctype_offset(str792), 140},
- {uniname2ctype_offset(str793), 228},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str797), 475},
- {-1},
- {uniname2ctype_offset(str799), 289},
- {-1}, {-1},
- {uniname2ctype_offset(str802), 463},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str807), 429},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str812), 468},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str819), 417},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str823), 427},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str834), 67},
- {uniname2ctype_offset(str835), 136},
- {-1},
- {uniname2ctype_offset(str837), 292},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str848), 85},
- {uniname2ctype_offset(str849), 313},
- {-1},
- {uniname2ctype_offset(str851), 498},
- {uniname2ctype_offset(str852), 245},
- {uniname2ctype_offset(str853), 476},
- {-1},
- {uniname2ctype_offset(str855), 136},
- {uniname2ctype_offset(str856), 142},
- {uniname2ctype_offset(str857), 60},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str862), 115},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str867), 2},
- {-1}, {-1},
- {uniname2ctype_offset(str870), 104},
- {-1},
- {uniname2ctype_offset(str872), 247},
- {-1},
- {uniname2ctype_offset(str874), 217},
- {-1}, {-1},
- {uniname2ctype_offset(str877), 11},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str881), 69},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str885), 454},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str897), 452},
- {-1},
- {uniname2ctype_offset(str899), 102},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str903), 101},
- {-1},
- {uniname2ctype_offset(str905), 173},
- {uniname2ctype_offset(str906), 197},
- {-1}, {-1},
- {uniname2ctype_offset(str909), 101},
- {-1},
- {uniname2ctype_offset(str911), 138},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str918), 208},
- {uniname2ctype_offset(str919), 393},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str926), 517},
- {-1},
- {uniname2ctype_offset(str928), 73},
- {-1},
- {uniname2ctype_offset(str930), 151},
- {uniname2ctype_offset(str931), 471},
- {uniname2ctype_offset(str932), 166},
- {-1}, {-1},
- {uniname2ctype_offset(str935), 503},
- {-1},
- {uniname2ctype_offset(str937), 228},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str942), 170},
- {-1},
- {uniname2ctype_offset(str944), 74},
- {-1}, {-1},
- {uniname2ctype_offset(str947), 499},
- {uniname2ctype_offset(str948), 494},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str956), 183},
- {uniname2ctype_offset(str957), 328},
- {-1}, {-1},
- {uniname2ctype_offset(str960), 135},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str966), 537},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str975), 186},
- {uniname2ctype_offset(str976), 129},
- {uniname2ctype_offset(str977), 158},
- {-1}, {-1},
- {uniname2ctype_offset(str980), 244},
- {-1}, {-1},
- {uniname2ctype_offset(str983), 324},
- {-1},
- {uniname2ctype_offset(str985), 26},
- {-1}, {-1},
- {uniname2ctype_offset(str988), 348},
- {-1}, {-1},
- {uniname2ctype_offset(str991), 382},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str996), 53},
- {-1},
- {uniname2ctype_offset(str998), 206},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1016), 296},
- {-1}, {-1},
- {uniname2ctype_offset(str1019), 387},
- {-1}, {-1},
- {uniname2ctype_offset(str1022), 430},
- {uniname2ctype_offset(str1023), 36},
- {-1},
- {uniname2ctype_offset(str1025), 105},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1029), 129},
- {-1}, {-1},
- {uniname2ctype_offset(str1032), 200},
- {-1},
- {uniname2ctype_offset(str1034), 104},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1048), 536},
- {uniname2ctype_offset(str1049), 317},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1053), 126},
- {-1}, {-1},
- {uniname2ctype_offset(str1056), 161},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1061), 25},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1065), 105},
- {-1},
- {uniname2ctype_offset(str1067), 122},
- {-1},
- {uniname2ctype_offset(str1069), 206},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1076), 484},
- {uniname2ctype_offset(str1077), 485},
- {uniname2ctype_offset(str1078), 93},
- {-1},
- {uniname2ctype_offset(str1080), 215},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1086), 403},
- {-1},
- {uniname2ctype_offset(str1088), 203},
- {uniname2ctype_offset(str1089), 221},
- {uniname2ctype_offset(str1090), 560},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1094), 473},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1098), 512},
- {-1},
- {uniname2ctype_offset(str1100), 467},
- {-1}, {-1},
- {uniname2ctype_offset(str1103), 397},
- {uniname2ctype_offset(str1104), 164},
- {-1}, {-1},
- {uniname2ctype_offset(str1107), 109},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1114), 122},
- {uniname2ctype_offset(str1115), 349},
- {uniname2ctype_offset(str1116), 131},
- {-1}, {-1},
- {uniname2ctype_offset(str1119), 135},
- {uniname2ctype_offset(str1120), 462},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1124), 113},
- {-1},
- {uniname2ctype_offset(str1126), 56},
- {uniname2ctype_offset(str1127), 218},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1131), 15},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1135), 30},
- {uniname2ctype_offset(str1136), 120},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str1147), 365},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1152), 110},
- {-1}, {-1},
- {uniname2ctype_offset(str1155), 110},
- {uniname2ctype_offset(str1156), 409},
- {uniname2ctype_offset(str1157), 141},
- {uniname2ctype_offset(str1158), 121},
- {-1},
- {uniname2ctype_offset(str1160), 176},
- {uniname2ctype_offset(str1161), 181},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1167), 117},
- {uniname2ctype_offset(str1168), 474},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1172), 88},
- {uniname2ctype_offset(str1173), 502},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1178), 86},
- {uniname2ctype_offset(str1179), 166},
- {uniname2ctype_offset(str1180), 145},
- {-1},
- {uniname2ctype_offset(str1182), 558},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1186), 117},
- {-1}, {-1},
- {uniname2ctype_offset(str1189), 193},
- {-1}, {-1},
- {uniname2ctype_offset(str1192), 176},
- {uniname2ctype_offset(str1193), 107},
- {-1},
- {uniname2ctype_offset(str1195), 299},
- {uniname2ctype_offset(str1196), 109},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1201), 236},
- {uniname2ctype_offset(str1202), 86},
- {uniname2ctype_offset(str1203), 497},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1207), 81},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1211), 120},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1218), 460},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1222), 168},
- {-1}, {-1},
- {uniname2ctype_offset(str1225), 488},
- {-1},
- {uniname2ctype_offset(str1227), 532},
- {-1},
- {uniname2ctype_offset(str1229), 383},
- {-1}, {-1},
- {uniname2ctype_offset(str1232), 240},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1237), 196},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1243), 115},
- {-1},
- {uniname2ctype_offset(str1245), 405},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1249), 222},
- {-1}, {-1},
- {uniname2ctype_offset(str1252), 392},
- {uniname2ctype_offset(str1253), 72},
- {uniname2ctype_offset(str1254), 114},
- {-1}, {-1},
- {uniname2ctype_offset(str1257), 3},
- {-1},
- {uniname2ctype_offset(str1259), 137},
- {-1}, {-1},
- {uniname2ctype_offset(str1262), 306},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1267), 287},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1275), 114},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1281), 548},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1285), 217},
- {-1}, {-1},
- {uniname2ctype_offset(str1288), 42},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1294), 355},
- {-1},
- {uniname2ctype_offset(str1296), 440},
- {-1},
- {uniname2ctype_offset(str1298), 73},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1306), 106},
- {uniname2ctype_offset(str1307), 201},
- {uniname2ctype_offset(str1308), 368},
- {uniname2ctype_offset(str1309), 500},
- {uniname2ctype_offset(str1310), 98},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1317), 210},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1325), 466},
- {uniname2ctype_offset(str1326), 357},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1331), 145},
- {-1}, {-1},
- {uniname2ctype_offset(str1334), 464},
- {uniname2ctype_offset(str1335), 9},
- {uniname2ctype_offset(str1336), 203},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1340), 472},
- {uniname2ctype_offset(str1341), 519},
- {-1}, {-1},
- {uniname2ctype_offset(str1344), 32},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1348), 1},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1354), 322},
- {uniname2ctype_offset(str1355), 320},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1364), 347},
- {uniname2ctype_offset(str1365), 346},
- {-1}, {-1},
- {uniname2ctype_offset(str1368), 125},
- {uniname2ctype_offset(str1369), 207},
- {-1}, {-1},
- {uniname2ctype_offset(str1372), 335},
- {uniname2ctype_offset(str1373), 245},
- {uniname2ctype_offset(str1374), 127},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1379), 164},
- {-1}, {-1},
- {uniname2ctype_offset(str1382), 207},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1388), 138},
- {-1},
- {uniname2ctype_offset(str1390), 370},
-#ifndef USE_UNICODE_AGE_PROPERTIES
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
-#else /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1391), 251},
- {uniname2ctype_offset(str1392), 258},
- {uniname2ctype_offset(str1393), 257},
- {uniname2ctype_offset(str1394), 269},
- {uniname2ctype_offset(str1395), 253},
- {uniname2ctype_offset(str1396), 252},
- {uniname2ctype_offset(str1397), 263},
- {uniname2ctype_offset(str1398), 262},
- {uniname2ctype_offset(str1399), 268},
- {uniname2ctype_offset(str1400), 267},
- {uniname2ctype_offset(str1401), 264},
- {uniname2ctype_offset(str1402), 266},
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1403), 547},
- {uniname2ctype_offset(str1404), 362},
-#ifndef USE_UNICODE_AGE_PROPERTIES
- {-1}, {-1},
-#else /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1405), 260},
- {uniname2ctype_offset(str1406), 259},
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1407), 36},
- {uniname2ctype_offset(str1408), 52},
-#ifndef USE_UNICODE_AGE_PROPERTIES
- {-1}, {-1},
-#else /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1409), 261},
- {-1},
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1411), 310},
- {-1},
- {uniname2ctype_offset(str1413), 559},
- {uniname2ctype_offset(str1414), 153},
- {-1},
- {uniname2ctype_offset(str1416), 93},
-#ifndef USE_UNICODE_AGE_PROPERTIES
- {-1}, {-1}, {-1},
-#else /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1417), 255},
- {uniname2ctype_offset(str1418), 254},
- {-1},
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1420), 202},
-#ifndef USE_UNICODE_AGE_PROPERTIES
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#else /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1421), 256},
- {-1},
- {uniname2ctype_offset(str1423), 265},
- {-1}, {-1}, {-1},
-#endif /* USE_UNICODE_AGE_PROPERTIES */
- {uniname2ctype_offset(str1427), 20},
- {-1},
- {uniname2ctype_offset(str1429), 124},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1434), 496},
- {uniname2ctype_offset(str1435), 137},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1439), 423},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1444), 39},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1449), 307},
- {uniname2ctype_offset(str1450), 202},
- {uniname2ctype_offset(str1451), 331},
- {-1},
- {uniname2ctype_offset(str1453), 413},
- {-1},
- {uniname2ctype_offset(str1455), 27},
- {uniname2ctype_offset(str1456), 238},
- {-1},
- {uniname2ctype_offset(str1458), 225},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1463), 241},
- {uniname2ctype_offset(str1464), 533},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1469), 141},
- {uniname2ctype_offset(str1470), 35},
- {uniname2ctype_offset(str1471), 350},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1485), 457},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str1496), 54},
- {uniname2ctype_offset(str1497), 225},
- {-1}, {-1},
- {uniname2ctype_offset(str1500), 308},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1508), 501},
- {-1},
- {uniname2ctype_offset(str1510), 154},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str1521), 492},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1535), 378},
- {uniname2ctype_offset(str1536), 376},
- {-1}, {-1},
- {uniname2ctype_offset(str1539), 34},
- {uniname2ctype_offset(str1540), 294},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1545), 8},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1553), 508},
- {-1},
- {uniname2ctype_offset(str1555), 243},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1560), 222},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1565), 20},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1572), 6},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1580), 327},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1585), 234},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1589), 344},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1593), 531},
- {uniname2ctype_offset(str1594), 567},
- {uniname2ctype_offset(str1595), 43},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1602), 312},
- {-1},
- {uniname2ctype_offset(str1604), 400},
- {-1},
- {uniname2ctype_offset(str1606), 419},
- {uniname2ctype_offset(str1607), 199},
- {uniname2ctype_offset(str1608), 530},
- {uniname2ctype_offset(str1609), 142},
- {-1},
- {uniname2ctype_offset(str1611), 477},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1617), 85},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1623), 235},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1628), 242},
- {-1},
- {uniname2ctype_offset(str1630), 249},
- {uniname2ctype_offset(str1631), 33},
- {uniname2ctype_offset(str1632), 159},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1636), 121},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1645), 352},
- {-1},
- {uniname2ctype_offset(str1647), 58},
- {uniname2ctype_offset(str1648), 442},
- {-1},
- {uniname2ctype_offset(str1650), 159},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1654), 244},
- {uniname2ctype_offset(str1655), 356},
- {uniname2ctype_offset(str1656), 441},
- {uniname2ctype_offset(str1657), 66},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1663), 148},
- {-1}, {-1},
- {uniname2ctype_offset(str1666), 154},
- {-1}, {-1},
- {uniname2ctype_offset(str1669), 148},
- {-1},
- {uniname2ctype_offset(str1671), 215},
- {uniname2ctype_offset(str1672), 162},
- {uniname2ctype_offset(str1673), 351},
- {uniname2ctype_offset(str1674), 390},
- {-1}, {-1},
- {uniname2ctype_offset(str1677), 426},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1682), 97},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1690), 389},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1695), 97},
- {-1},
- {uniname2ctype_offset(str1697), 89},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1714), 230},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str1725), 37},
- {-1},
- {uniname2ctype_offset(str1727), 325},
- {uniname2ctype_offset(str1728), 143},
- {-1},
- {uniname2ctype_offset(str1730), 428},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1736), 5},
- {uniname2ctype_offset(str1737), 143},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1741), 353},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1746), 336},
- {-1},
- {uniname2ctype_offset(str1748), 371},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1752), 564},
- {-1},
- {uniname2ctype_offset(str1754), 87},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1762), 174},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1766), 87},
- {uniname2ctype_offset(str1767), 232},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1772), 339},
- {-1},
- {uniname2ctype_offset(str1774), 131},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1780), 227},
- {-1}, {-1},
- {uniname2ctype_offset(str1783), 174},
- {-1},
- {uniname2ctype_offset(str1785), 510},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1789), 411},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str1800), 288},
- {-1},
- {uniname2ctype_offset(str1802), 219},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1806), 373},
- {-1},
- {uniname2ctype_offset(str1808), 55},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1813), 139},
- {uniname2ctype_offset(str1814), 29},
- {uniname2ctype_offset(str1815), 402},
- {-1}, {-1},
- {uniname2ctype_offset(str1818), 526},
- {uniname2ctype_offset(str1819), 293},
- {-1},
- {uniname2ctype_offset(str1821), 408},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1825), 196},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1829), 360},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str1840), 177},
- {-1}, {-1},
- {uniname2ctype_offset(str1843), 237},
- {-1}, {-1},
- {uniname2ctype_offset(str1846), 418},
- {uniname2ctype_offset(str1847), 190},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1857), 395},
- {uniname2ctype_offset(str1858), 561},
- {-1}, {-1},
- {uniname2ctype_offset(str1861), 478},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1866), 247},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1885), 358},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1894), 150},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1900), 150},
- {-1}, {-1},
- {uniname2ctype_offset(str1903), 563},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1909), 314},
- {uniname2ctype_offset(str1910), 385},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1914), 554},
- {uniname2ctype_offset(str1915), 354},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1922), 84},
- {-1},
- {uniname2ctype_offset(str1924), 437},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1932), 84},
- {uniname2ctype_offset(str1933), 232},
- {uniname2ctype_offset(str1934), 490},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1943), 26},
- {uniname2ctype_offset(str1944), 12},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1975), 61},
- {uniname2ctype_offset(str1976), 407},
- {-1}, {-1},
- {uniname2ctype_offset(str1979), 239},
- {-1},
- {uniname2ctype_offset(str1981), 94},
- {-1},
- {uniname2ctype_offset(str1983), 83},
- {-1},
- {uniname2ctype_offset(str1985), 343},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1989), 538},
- {-1},
- {uniname2ctype_offset(str1991), 83},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str1995), 551},
- {-1},
- {uniname2ctype_offset(str1997), 134},
- {uniname2ctype_offset(str1998), 21},
- {uniname2ctype_offset(str1999), 375},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2003), 511},
- {-1},
- {uniname2ctype_offset(str2005), 64},
- {-1},
- {uniname2ctype_offset(str2007), 198},
- {uniname2ctype_offset(str2008), 185},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2013), 445},
- {-1},
- {uniname2ctype_offset(str2015), 198},
- {-1},
- {uniname2ctype_offset(str2017), 165},
- {-1}, {-1},
- {uniname2ctype_offset(str2020), 185},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2047), 240},
- {-1},
- {uniname2ctype_offset(str2049), 416},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2056), 386},
- {-1}, {-1},
- {uniname2ctype_offset(str2059), 152},
- {-1},
- {uniname2ctype_offset(str2061), 17},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2068), 191},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2072), 410},
- {uniname2ctype_offset(str2073), 183},
- {-1}, {-1},
- {uniname2ctype_offset(str2076), 118},
- {-1}, {-1},
- {uniname2ctype_offset(str2079), 191},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2084), 439},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2091), 175},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2095), 555},
- {uniname2ctype_offset(str2096), 194},
- {uniname2ctype_offset(str2097), 78},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2101), 43},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str2112), 172},
- {-1},
- {uniname2ctype_offset(str2114), 301},
- {-1}, {-1},
- {uniname2ctype_offset(str2117), 195},
- {-1},
- {uniname2ctype_offset(str2119), 486},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2134), 92},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2139), 557},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2146), 192},
- {-1},
- {uniname2ctype_offset(str2148), 379},
- {uniname2ctype_offset(str2149), 92},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2154), 214},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2158), 224},
- {-1}, {-1},
- {uniname2ctype_offset(str2161), 139},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2165), 282},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2172), 286},
- {-1},
- {uniname2ctype_offset(str2174), 323},
- {-1},
- {uniname2ctype_offset(str2176), 128},
- {-1}, {-1},
- {uniname2ctype_offset(str2179), 276},
- {-1}, {-1},
- {uniname2ctype_offset(str2182), 421},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2187), 48},
- {-1},
- {uniname2ctype_offset(str2189), 89},
- {-1}, {-1},
- {uniname2ctype_offset(str2192), 271},
- {uniname2ctype_offset(str2193), 130},
- {-1}, {-1},
- {uniname2ctype_offset(str2196), 128},
- {uniname2ctype_offset(str2197), 90},
- {uniname2ctype_offset(str2198), 384},
- {uniname2ctype_offset(str2199), 283},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2207), 275},
- {-1}, {-1},
- {uniname2ctype_offset(str2210), 337},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2224), 401},
- {uniname2ctype_offset(str2225), 211},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2229), 364},
- {-1}, {-1},
- {uniname2ctype_offset(str2232), 209},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2249), 130},
- {-1}, {-1},
- {uniname2ctype_offset(str2252), 80},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2260), 332},
- {-1}, {-1},
- {uniname2ctype_offset(str2263), 539},
- {uniname2ctype_offset(str2264), 82},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2271), 239},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2276), 522},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2286), 243},
- {-1}, {-1},
- {uniname2ctype_offset(str2289), 361},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2296), 229},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2300), 18},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2306), 505},
- {uniname2ctype_offset(str2307), 38},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2311), 422},
- {-1},
- {uniname2ctype_offset(str2313), 112},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2327), 213},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2349), 446},
- {uniname2ctype_offset(str2350), 436},
- {-1}, {-1},
- {uniname2ctype_offset(str2353), 443},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2360), 309},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2364), 65},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2369), 341},
- {-1}, {-1},
- {uniname2ctype_offset(str2372), 82},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2380), 100},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2386), 226},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2399), 543},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2408), 211},
- {uniname2ctype_offset(str2409), 118},
- {-1}, {-1},
- {uniname2ctype_offset(str2412), 279},
- {uniname2ctype_offset(str2413), 229},
- {uniname2ctype_offset(str2414), 281},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2422), 119},
- {uniname2ctype_offset(str2423), 99},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2433), 359},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2449), 311},
- {-1},
- {uniname2ctype_offset(str2451), 54},
- {uniname2ctype_offset(str2452), 96},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2461), 96},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2465), 103},
- {-1},
- {uniname2ctype_offset(str2467), 62},
- {-1},
- {uniname2ctype_offset(str2469), 226},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2473), 107},
- {-1},
- {uniname2ctype_offset(str2475), 23},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2481), 520},
- {-1},
- {uniname2ctype_offset(str2483), 420},
- {uniname2ctype_offset(str2484), 527},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2488), 182},
- {uniname2ctype_offset(str2489), 274},
- {uniname2ctype_offset(str2490), 270},
- {-1}, {-1},
- {uniname2ctype_offset(str2493), 178},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2500), 459},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2507), 57},
- {-1},
- {uniname2ctype_offset(str2509), 50},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2515), 231},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2519), 204},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2523), 153},
- {-1}, {-1},
- {uniname2ctype_offset(str2526), 388},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2539), 41},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2545), 546},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2550), 451},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2573), 210},
- {-1}, {-1},
- {uniname2ctype_offset(str2576), 4},
- {-1}, {-1},
- {uniname2ctype_offset(str2579), 179},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2587), 449},
- {-1},
- {uniname2ctype_offset(str2589), 126},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2594), 216},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2601), 216},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2617), 63},
- {uniname2ctype_offset(str2618), 213},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2622), 333},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2630), 133},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2643), 277},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2649), 273},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2653), 165},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2660), 66},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2678), 147},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2693), 78},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2702), 99},
- {-1}, {-1},
- {uniname2ctype_offset(str2705), 49},
- {-1}, {-1},
- {uniname2ctype_offset(str2708), 553},
- {-1},
- {uniname2ctype_offset(str2710), 565},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2717), 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},
- {uniname2ctype_offset(str2751), 544},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2758), 64},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2763), 132},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str2775), 230},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2779), 381},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str2791), 242},
- {uniname2ctype_offset(str2792), 123},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2797), 28},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2823), 432},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2829), 180},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2834), 330},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2850), 231},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str2879), 223},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2883), 199},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2888), 133},
- {-1},
- {uniname2ctype_offset(str2890), 124},
- {uniname2ctype_offset(str2891), 523},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2901), 447},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2905), 290},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str2926), 125},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2930), 272},
- {-1},
- {uniname2ctype_offset(str2932), 51},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str2953), 71},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2967), 470},
- {uniname2ctype_offset(str2968), 197},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str2972), 146},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str2984), 204},
- {-1}, {-1},
- {uniname2ctype_offset(str2987), 250},
- {-1},
- {uniname2ctype_offset(str2989), 404},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3007), 180},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3016), 398},
- {-1}, {-1},
- {uniname2ctype_offset(str3019), 62},
- {uniname2ctype_offset(str3020), 45},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3038), 10},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3052), 377},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3066), 190},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3094), 63},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3113), 59},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3121), 123},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3153), 238},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3177), 223},
- {-1}, {-1},
- {uniname2ctype_offset(str3180), 132},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3193), 47},
- {-1},
- {uniname2ctype_offset(str3195), 224},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3213), 16},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3235), 433},
- {-1}, {-1},
- {uniname2ctype_offset(str3238), 100},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str3276), 177},
- {-1}, {-1},
- {uniname2ctype_offset(str3279), 278},
- {uniname2ctype_offset(str3280), 280},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3285), 214},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str3296), 284},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3305), 285},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3315), 205},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3367), 65},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3373), 103},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3409), 30},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str3438), 298},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3442), 435},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3448), 46},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3453), 233},
- {uniname2ctype_offset(str3454), 220},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str3465), 119},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3496), 406},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3593), 162},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3662), 179},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3676), 201},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3689), 540},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3697), 556},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str3763), 566},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str3791), 518},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#endif /* USE_UNICODE_PROPERTIES */
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#ifndef USE_UNICODE_PROPERTIES
- {uniname2ctype_offset(str6), 12},
- {uniname2ctype_offset(str7), 7},
- {uniname2ctype_offset(str8), 15},
- {uniname2ctype_offset(str9), 1},
- {uniname2ctype_offset(str10), 13},
- {uniname2ctype_offset(str11), 11},
- {uniname2ctype_offset(str12), 10},
- {uniname2ctype_offset(str13), 14},
- {uniname2ctype_offset(str14), 3},
- {uniname2ctype_offset(str15), 9},
- {uniname2ctype_offset(str16), 8},
- {uniname2ctype_offset(str17), 6},
- {uniname2ctype_offset(str18), 5},
- {uniname2ctype_offset(str19), 4},
- {uniname2ctype_offset(str20), 2}
-#else /* USE_UNICODE_PROPERTIES */
- {uniname2ctype_offset(str3960), 147},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str3971), 396},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str4036), 90},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1},
- {uniname2ctype_offset(str4164), 116},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4187), 116},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str4208), 233},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4460), 237},
- {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4464), 369},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4483), 182},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4608), 434},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4634), 205},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4678), 75},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str4841), 155},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
- {uniname2ctype_offset(str5170), 80},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1},
- {uniname2ctype_offset(str6145), 155}
-#endif /* USE_UNICODE_PROPERTIES */
- };
-
- if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- {
- register int key = uniname2ctype_hash (str, len);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register int o = wordlist[key].name;
- if (o >= 0)
- {
- register const char *s = o + uniname2ctype_pool;
-
- if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
- return &wordlist[key];
- }
- }
- }
- return 0;
-}
-
-static int
-uniname2ctype(const UChar *name, unsigned int len)
-{
- const struct uniname2ctype_struct *p = uniname2ctype_p((const char *)name, len);
- if (p) return p->ctype;
- return -1;
-}
-#if defined ONIG_UNICODE_VERSION_STRING && !( \
- ONIG_UNICODE_VERSION_MAJOR == 10 && \
- ONIG_UNICODE_VERSION_MINOR == 0 && \
- ONIG_UNICODE_VERSION_TEENY == 0 && \
- 1)
-# error ONIG_UNICODE_VERSION_STRING mismatch
-#endif
-#define ONIG_UNICODE_VERSION_STRING "10.0.0"
-#define ONIG_UNICODE_VERSION_MAJOR 10
-#define ONIG_UNICODE_VERSION_MINOR 0
-#define ONIG_UNICODE_VERSION_TEENY 0
diff --git a/enc/unicode/12.1.0/casefold.h b/enc/unicode/12.1.0/casefold.h
new file mode 100644
index 0000000000..4c62f0faee
--- /dev/null
+++ b/enc/unicode/12.1.0/casefold.h
@@ -0,0 +1,7428 @@
+/* DO NOT EDIT THIS FILE. */
+/* Generated by enc/unicode/case-folding.rb */
+
+#if defined ONIG_UNICODE_VERSION_STRING && !( \
+ ONIG_UNICODE_VERSION_MAJOR == 12 && \
+ ONIG_UNICODE_VERSION_MINOR == 1 && \
+ ONIG_UNICODE_VERSION_TEENY == 0 && \
+ 1)
+# error ONIG_UNICODE_VERSION_STRING mismatch
+#endif
+#define ONIG_UNICODE_VERSION_STRING "12.1.0"
+#define ONIG_UNICODE_VERSION_MAJOR 12
+#define ONIG_UNICODE_VERSION_MINOR 1
+#define ONIG_UNICODE_VERSION_TEENY 0
+
+static const CaseFold_11_Type CaseFold_11_Table[] = {
+#define CaseFold (*(CaseFold_11_Type (*)[1485])(CaseFold_11_Table+0))
+ {0x0041, {1|F|D, {0x0061}}},
+ {0x0042, {1|F|D, {0x0062}}},
+ {0x0043, {1|F|D, {0x0063}}},
+ {0x0044, {1|F|D, {0x0064}}},
+ {0x0045, {1|F|D, {0x0065}}},
+ {0x0046, {1|F|D, {0x0066}}},
+ {0x0047, {1|F|D, {0x0067}}},
+ {0x0048, {1|F|D, {0x0068}}},
+ {0x004a, {1|F|D, {0x006a}}},
+ {0x004b, {1|F|D, {0x006b}}},
+ {0x004c, {1|F|D, {0x006c}}},
+ {0x004d, {1|F|D, {0x006d}}},
+ {0x004e, {1|F|D, {0x006e}}},
+ {0x004f, {1|F|D, {0x006f}}},
+ {0x0050, {1|F|D, {0x0070}}},
+ {0x0051, {1|F|D, {0x0071}}},
+ {0x0052, {1|F|D, {0x0072}}},
+ {0x0053, {1|F|D, {0x0073}}},
+ {0x0054, {1|F|D, {0x0074}}},
+ {0x0055, {1|F|D, {0x0075}}},
+ {0x0056, {1|F|D, {0x0076}}},
+ {0x0057, {1|F|D, {0x0077}}},
+ {0x0058, {1|F|D, {0x0078}}},
+ {0x0059, {1|F|D, {0x0079}}},
+ {0x005a, {1|F|D, {0x007a}}},
+ {0x00b5, {1|F|SU|I(0), {0x03bc}}},
+ {0x00c0, {1|F|D, {0x00e0}}},
+ {0x00c1, {1|F|D, {0x00e1}}},
+ {0x00c2, {1|F|D, {0x00e2}}},
+ {0x00c3, {1|F|D, {0x00e3}}},
+ {0x00c4, {1|F|D, {0x00e4}}},
+ {0x00c5, {1|F|D, {0x00e5}}},
+ {0x00c6, {1|F|D, {0x00e6}}},
+ {0x00c7, {1|F|D, {0x00e7}}},
+ {0x00c8, {1|F|D, {0x00e8}}},
+ {0x00c9, {1|F|D, {0x00e9}}},
+ {0x00ca, {1|F|D, {0x00ea}}},
+ {0x00cb, {1|F|D, {0x00eb}}},
+ {0x00cc, {1|F|D, {0x00ec}}},
+ {0x00cd, {1|F|D, {0x00ed}}},
+ {0x00ce, {1|F|D, {0x00ee}}},
+ {0x00cf, {1|F|D, {0x00ef}}},
+ {0x00d0, {1|F|D, {0x00f0}}},
+ {0x00d1, {1|F|D, {0x00f1}}},
+ {0x00d2, {1|F|D, {0x00f2}}},
+ {0x00d3, {1|F|D, {0x00f3}}},
+ {0x00d4, {1|F|D, {0x00f4}}},
+ {0x00d5, {1|F|D, {0x00f5}}},
+ {0x00d6, {1|F|D, {0x00f6}}},
+ {0x00d8, {1|F|D, {0x00f8}}},
+ {0x00d9, {1|F|D, {0x00f9}}},
+ {0x00da, {1|F|D, {0x00fa}}},
+ {0x00db, {1|F|D, {0x00fb}}},
+ {0x00dc, {1|F|D, {0x00fc}}},
+ {0x00dd, {1|F|D, {0x00fd}}},
+ {0x00de, {1|F|D, {0x00fe}}},
+ {0x00df, {2|F|ST|SU|I(1), {0x0073, 0x0073}}},
+ {0x0100, {1|F|D, {0x0101}}},
+ {0x0102, {1|F|D, {0x0103}}},
+ {0x0104, {1|F|D, {0x0105}}},
+ {0x0106, {1|F|D, {0x0107}}},
+ {0x0108, {1|F|D, {0x0109}}},
+ {0x010a, {1|F|D, {0x010b}}},
+ {0x010c, {1|F|D, {0x010d}}},
+ {0x010e, {1|F|D, {0x010f}}},
+ {0x0110, {1|F|D, {0x0111}}},
+ {0x0112, {1|F|D, {0x0113}}},
+ {0x0114, {1|F|D, {0x0115}}},
+ {0x0116, {1|F|D, {0x0117}}},
+ {0x0118, {1|F|D, {0x0119}}},
+ {0x011a, {1|F|D, {0x011b}}},
+ {0x011c, {1|F|D, {0x011d}}},
+ {0x011e, {1|F|D, {0x011f}}},
+ {0x0120, {1|F|D, {0x0121}}},
+ {0x0122, {1|F|D, {0x0123}}},
+ {0x0124, {1|F|D, {0x0125}}},
+ {0x0126, {1|F|D, {0x0127}}},
+ {0x0128, {1|F|D, {0x0129}}},
+ {0x012a, {1|F|D, {0x012b}}},
+ {0x012c, {1|F|D, {0x012d}}},
+ {0x012e, {1|F|D, {0x012f}}},
+ {0x0132, {1|F|D, {0x0133}}},
+ {0x0134, {1|F|D, {0x0135}}},
+ {0x0136, {1|F|D, {0x0137}}},
+ {0x0139, {1|F|D, {0x013a}}},
+ {0x013b, {1|F|D, {0x013c}}},
+ {0x013d, {1|F|D, {0x013e}}},
+ {0x013f, {1|F|D, {0x0140}}},
+ {0x0141, {1|F|D, {0x0142}}},
+ {0x0143, {1|F|D, {0x0144}}},
+ {0x0145, {1|F|D, {0x0146}}},
+ {0x0147, {1|F|D, {0x0148}}},
+ {0x0149, {2|F|SU|I(5), {0x02bc, 0x006e}}},
+ {0x014a, {1|F|D, {0x014b}}},
+ {0x014c, {1|F|D, {0x014d}}},
+ {0x014e, {1|F|D, {0x014f}}},
+ {0x0150, {1|F|D, {0x0151}}},
+ {0x0152, {1|F|D, {0x0153}}},
+ {0x0154, {1|F|D, {0x0155}}},
+ {0x0156, {1|F|D, {0x0157}}},
+ {0x0158, {1|F|D, {0x0159}}},
+ {0x015a, {1|F|D, {0x015b}}},
+ {0x015c, {1|F|D, {0x015d}}},
+ {0x015e, {1|F|D, {0x015f}}},
+ {0x0160, {1|F|D, {0x0161}}},
+ {0x0162, {1|F|D, {0x0163}}},
+ {0x0164, {1|F|D, {0x0165}}},
+ {0x0166, {1|F|D, {0x0167}}},
+ {0x0168, {1|F|D, {0x0169}}},
+ {0x016a, {1|F|D, {0x016b}}},
+ {0x016c, {1|F|D, {0x016d}}},
+ {0x016e, {1|F|D, {0x016f}}},
+ {0x0170, {1|F|D, {0x0171}}},
+ {0x0172, {1|F|D, {0x0173}}},
+ {0x0174, {1|F|D, {0x0175}}},
+ {0x0176, {1|F|D, {0x0177}}},
+ {0x0178, {1|F|D, {0x00ff}}},
+ {0x0179, {1|F|D, {0x017a}}},
+ {0x017b, {1|F|D, {0x017c}}},
+ {0x017d, {1|F|D, {0x017e}}},
+ {0x017f, {1|F|SU|I(7), {0x0073}}},
+ {0x0181, {1|F|D, {0x0253}}},
+ {0x0182, {1|F|D, {0x0183}}},
+ {0x0184, {1|F|D, {0x0185}}},
+ {0x0186, {1|F|D, {0x0254}}},
+ {0x0187, {1|F|D, {0x0188}}},
+ {0x0189, {1|F|D, {0x0256}}},
+ {0x018a, {1|F|D, {0x0257}}},
+ {0x018b, {1|F|D, {0x018c}}},
+ {0x018e, {1|F|D, {0x01dd}}},
+ {0x018f, {1|F|D, {0x0259}}},
+ {0x0190, {1|F|D, {0x025b}}},
+ {0x0191, {1|F|D, {0x0192}}},
+ {0x0193, {1|F|D, {0x0260}}},
+ {0x0194, {1|F|D, {0x0263}}},
+ {0x0196, {1|F|D, {0x0269}}},
+ {0x0197, {1|F|D, {0x0268}}},
+ {0x0198, {1|F|D, {0x0199}}},
+ {0x019c, {1|F|D, {0x026f}}},
+ {0x019d, {1|F|D, {0x0272}}},
+ {0x019f, {1|F|D, {0x0275}}},
+ {0x01a0, {1|F|D, {0x01a1}}},
+ {0x01a2, {1|F|D, {0x01a3}}},
+ {0x01a4, {1|F|D, {0x01a5}}},
+ {0x01a6, {1|F|D, {0x0280}}},
+ {0x01a7, {1|F|D, {0x01a8}}},
+ {0x01a9, {1|F|D, {0x0283}}},
+ {0x01ac, {1|F|D, {0x01ad}}},
+ {0x01ae, {1|F|D, {0x0288}}},
+ {0x01af, {1|F|D, {0x01b0}}},
+ {0x01b1, {1|F|D, {0x028a}}},
+ {0x01b2, {1|F|D, {0x028b}}},
+ {0x01b3, {1|F|D, {0x01b4}}},
+ {0x01b5, {1|F|D, {0x01b6}}},
+ {0x01b7, {1|F|D, {0x0292}}},
+ {0x01b8, {1|F|D, {0x01b9}}},
+ {0x01bc, {1|F|D, {0x01bd}}},
+ {0x01c4, {1|F|D|ST|I(8), {0x01c6}}},
+ {0x01c5, {1|F|D|IT|SU|I(9), {0x01c6}}},
+ {0x01c7, {1|F|D|ST|I(12), {0x01c9}}},
+ {0x01c8, {1|F|D|IT|SU|I(13), {0x01c9}}},
+ {0x01ca, {1|F|D|ST|I(16), {0x01cc}}},
+ {0x01cb, {1|F|D|IT|SU|I(17), {0x01cc}}},
+ {0x01cd, {1|F|D, {0x01ce}}},
+ {0x01cf, {1|F|D, {0x01d0}}},
+ {0x01d1, {1|F|D, {0x01d2}}},
+ {0x01d3, {1|F|D, {0x01d4}}},
+ {0x01d5, {1|F|D, {0x01d6}}},
+ {0x01d7, {1|F|D, {0x01d8}}},
+ {0x01d9, {1|F|D, {0x01da}}},
+ {0x01db, {1|F|D, {0x01dc}}},
+ {0x01de, {1|F|D, {0x01df}}},
+ {0x01e0, {1|F|D, {0x01e1}}},
+ {0x01e2, {1|F|D, {0x01e3}}},
+ {0x01e4, {1|F|D, {0x01e5}}},
+ {0x01e6, {1|F|D, {0x01e7}}},
+ {0x01e8, {1|F|D, {0x01e9}}},
+ {0x01ea, {1|F|D, {0x01eb}}},
+ {0x01ec, {1|F|D, {0x01ed}}},
+ {0x01ee, {1|F|D, {0x01ef}}},
+ {0x01f0, {2|F|SU|I(20), {0x006a, 0x030c}}},
+ {0x01f1, {1|F|D|ST|I(22), {0x01f3}}},
+ {0x01f2, {1|F|D|IT|SU|I(23), {0x01f3}}},
+ {0x01f4, {1|F|D, {0x01f5}}},
+ {0x01f6, {1|F|D, {0x0195}}},
+ {0x01f7, {1|F|D, {0x01bf}}},
+ {0x01f8, {1|F|D, {0x01f9}}},
+ {0x01fa, {1|F|D, {0x01fb}}},
+ {0x01fc, {1|F|D, {0x01fd}}},
+ {0x01fe, {1|F|D, {0x01ff}}},
+ {0x0200, {1|F|D, {0x0201}}},
+ {0x0202, {1|F|D, {0x0203}}},
+ {0x0204, {1|F|D, {0x0205}}},
+ {0x0206, {1|F|D, {0x0207}}},
+ {0x0208, {1|F|D, {0x0209}}},
+ {0x020a, {1|F|D, {0x020b}}},
+ {0x020c, {1|F|D, {0x020d}}},
+ {0x020e, {1|F|D, {0x020f}}},
+ {0x0210, {1|F|D, {0x0211}}},
+ {0x0212, {1|F|D, {0x0213}}},
+ {0x0214, {1|F|D, {0x0215}}},
+ {0x0216, {1|F|D, {0x0217}}},
+ {0x0218, {1|F|D, {0x0219}}},
+ {0x021a, {1|F|D, {0x021b}}},
+ {0x021c, {1|F|D, {0x021d}}},
+ {0x021e, {1|F|D, {0x021f}}},
+ {0x0220, {1|F|D, {0x019e}}},
+ {0x0222, {1|F|D, {0x0223}}},
+ {0x0224, {1|F|D, {0x0225}}},
+ {0x0226, {1|F|D, {0x0227}}},
+ {0x0228, {1|F|D, {0x0229}}},
+ {0x022a, {1|F|D, {0x022b}}},
+ {0x022c, {1|F|D, {0x022d}}},
+ {0x022e, {1|F|D, {0x022f}}},
+ {0x0230, {1|F|D, {0x0231}}},
+ {0x0232, {1|F|D, {0x0233}}},
+ {0x023a, {1|F|D, {0x2c65}}},
+ {0x023b, {1|F|D, {0x023c}}},
+ {0x023d, {1|F|D, {0x019a}}},
+ {0x023e, {1|F|D, {0x2c66}}},
+ {0x0241, {1|F|D, {0x0242}}},
+ {0x0243, {1|F|D, {0x0180}}},
+ {0x0244, {1|F|D, {0x0289}}},
+ {0x0245, {1|F|D, {0x028c}}},
+ {0x0246, {1|F|D, {0x0247}}},
+ {0x0248, {1|F|D, {0x0249}}},
+ {0x024a, {1|F|D, {0x024b}}},
+ {0x024c, {1|F|D, {0x024d}}},
+ {0x024e, {1|F|D, {0x024f}}},
+ {0x0345, {1|F|SU|I(26), {0x03b9}}},
+ {0x0370, {1|F|D, {0x0371}}},
+ {0x0372, {1|F|D, {0x0373}}},
+ {0x0376, {1|F|D, {0x0377}}},
+ {0x037f, {1|F|D, {0x03f3}}},
+ {0x0386, {1|F|D, {0x03ac}}},
+ {0x0388, {1|F|D, {0x03ad}}},
+ {0x0389, {1|F|D, {0x03ae}}},
+ {0x038a, {1|F|D, {0x03af}}},
+ {0x038c, {1|F|D, {0x03cc}}},
+ {0x038e, {1|F|D, {0x03cd}}},
+ {0x038f, {1|F|D, {0x03ce}}},
+ {0x0390, {3|F|SU|I(27), {0x03b9, 0x0308, 0x0301}}},
+ {0x0391, {1|F|D, {0x03b1}}},
+ {0x0392, {1|F|D, {0x03b2}}},
+ {0x0393, {1|F|D, {0x03b3}}},
+ {0x0394, {1|F|D, {0x03b4}}},
+ {0x0395, {1|F|D, {0x03b5}}},
+ {0x0396, {1|F|D, {0x03b6}}},
+ {0x0397, {1|F|D, {0x03b7}}},
+ {0x0398, {1|F|D, {0x03b8}}},
+ {0x0399, {1|F|D, {0x03b9}}},
+ {0x039a, {1|F|D, {0x03ba}}},
+ {0x039b, {1|F|D, {0x03bb}}},
+ {0x039c, {1|F|D, {0x03bc}}},
+ {0x039d, {1|F|D, {0x03bd}}},
+ {0x039e, {1|F|D, {0x03be}}},
+ {0x039f, {1|F|D, {0x03bf}}},
+ {0x03a0, {1|F|D, {0x03c0}}},
+ {0x03a1, {1|F|D, {0x03c1}}},
+ {0x03a3, {1|F|D, {0x03c3}}},
+ {0x03a4, {1|F|D, {0x03c4}}},
+ {0x03a5, {1|F|D, {0x03c5}}},
+ {0x03a6, {1|F|D, {0x03c6}}},
+ {0x03a7, {1|F|D, {0x03c7}}},
+ {0x03a8, {1|F|D, {0x03c8}}},
+ {0x03a9, {1|F|D, {0x03c9}}},
+ {0x03aa, {1|F|D, {0x03ca}}},
+ {0x03ab, {1|F|D, {0x03cb}}},
+ {0x03b0, {3|F|SU|I(30), {0x03c5, 0x0308, 0x0301}}},
+ {0x03c2, {1|F|SU|I(33), {0x03c3}}},
+ {0x03cf, {1|F|D, {0x03d7}}},
+ {0x03d0, {1|F|SU|I(34), {0x03b2}}},
+ {0x03d1, {1|F|SU|I(35), {0x03b8}}},
+ {0x03d5, {1|F|SU|I(36), {0x03c6}}},
+ {0x03d6, {1|F|SU|I(37), {0x03c0}}},
+ {0x03d8, {1|F|D, {0x03d9}}},
+ {0x03da, {1|F|D, {0x03db}}},
+ {0x03dc, {1|F|D, {0x03dd}}},
+ {0x03de, {1|F|D, {0x03df}}},
+ {0x03e0, {1|F|D, {0x03e1}}},
+ {0x03e2, {1|F|D, {0x03e3}}},
+ {0x03e4, {1|F|D, {0x03e5}}},
+ {0x03e6, {1|F|D, {0x03e7}}},
+ {0x03e8, {1|F|D, {0x03e9}}},
+ {0x03ea, {1|F|D, {0x03eb}}},
+ {0x03ec, {1|F|D, {0x03ed}}},
+ {0x03ee, {1|F|D, {0x03ef}}},
+ {0x03f0, {1|F|SU|I(38), {0x03ba}}},
+ {0x03f1, {1|F|SU|I(39), {0x03c1}}},
+ {0x03f4, {1|F|D, {0x03b8}}},
+ {0x03f5, {1|F|SU|I(40), {0x03b5}}},
+ {0x03f7, {1|F|D, {0x03f8}}},
+ {0x03f9, {1|F|D, {0x03f2}}},
+ {0x03fa, {1|F|D, {0x03fb}}},
+ {0x03fd, {1|F|D, {0x037b}}},
+ {0x03fe, {1|F|D, {0x037c}}},
+ {0x03ff, {1|F|D, {0x037d}}},
+ {0x0400, {1|F|D, {0x0450}}},
+ {0x0401, {1|F|D, {0x0451}}},
+ {0x0402, {1|F|D, {0x0452}}},
+ {0x0403, {1|F|D, {0x0453}}},
+ {0x0404, {1|F|D, {0x0454}}},
+ {0x0405, {1|F|D, {0x0455}}},
+ {0x0406, {1|F|D, {0x0456}}},
+ {0x0407, {1|F|D, {0x0457}}},
+ {0x0408, {1|F|D, {0x0458}}},
+ {0x0409, {1|F|D, {0x0459}}},
+ {0x040a, {1|F|D, {0x045a}}},
+ {0x040b, {1|F|D, {0x045b}}},
+ {0x040c, {1|F|D, {0x045c}}},
+ {0x040d, {1|F|D, {0x045d}}},
+ {0x040e, {1|F|D, {0x045e}}},
+ {0x040f, {1|F|D, {0x045f}}},
+ {0x0410, {1|F|D, {0x0430}}},
+ {0x0411, {1|F|D, {0x0431}}},
+ {0x0412, {1|F|D, {0x0432}}},
+ {0x0413, {1|F|D, {0x0433}}},
+ {0x0414, {1|F|D, {0x0434}}},
+ {0x0415, {1|F|D, {0x0435}}},
+ {0x0416, {1|F|D, {0x0436}}},
+ {0x0417, {1|F|D, {0x0437}}},
+ {0x0418, {1|F|D, {0x0438}}},
+ {0x0419, {1|F|D, {0x0439}}},
+ {0x041a, {1|F|D, {0x043a}}},
+ {0x041b, {1|F|D, {0x043b}}},
+ {0x041c, {1|F|D, {0x043c}}},
+ {0x041d, {1|F|D, {0x043d}}},
+ {0x041e, {1|F|D, {0x043e}}},
+ {0x041f, {1|F|D, {0x043f}}},
+ {0x0420, {1|F|D, {0x0440}}},
+ {0x0421, {1|F|D, {0x0441}}},
+ {0x0422, {1|F|D, {0x0442}}},
+ {0x0423, {1|F|D, {0x0443}}},
+ {0x0424, {1|F|D, {0x0444}}},
+ {0x0425, {1|F|D, {0x0445}}},
+ {0x0426, {1|F|D, {0x0446}}},
+ {0x0427, {1|F|D, {0x0447}}},
+ {0x0428, {1|F|D, {0x0448}}},
+ {0x0429, {1|F|D, {0x0449}}},
+ {0x042a, {1|F|D, {0x044a}}},
+ {0x042b, {1|F|D, {0x044b}}},
+ {0x042c, {1|F|D, {0x044c}}},
+ {0x042d, {1|F|D, {0x044d}}},
+ {0x042e, {1|F|D, {0x044e}}},
+ {0x042f, {1|F|D, {0x044f}}},
+ {0x0460, {1|F|D, {0x0461}}},
+ {0x0462, {1|F|D, {0x0463}}},
+ {0x0464, {1|F|D, {0x0465}}},
+ {0x0466, {1|F|D, {0x0467}}},
+ {0x0468, {1|F|D, {0x0469}}},
+ {0x046a, {1|F|D, {0x046b}}},
+ {0x046c, {1|F|D, {0x046d}}},
+ {0x046e, {1|F|D, {0x046f}}},
+ {0x0470, {1|F|D, {0x0471}}},
+ {0x0472, {1|F|D, {0x0473}}},
+ {0x0474, {1|F|D, {0x0475}}},
+ {0x0476, {1|F|D, {0x0477}}},
+ {0x0478, {1|F|D, {0x0479}}},
+ {0x047a, {1|F|D, {0x047b}}},
+ {0x047c, {1|F|D, {0x047d}}},
+ {0x047e, {1|F|D, {0x047f}}},
+ {0x0480, {1|F|D, {0x0481}}},
+ {0x048a, {1|F|D, {0x048b}}},
+ {0x048c, {1|F|D, {0x048d}}},
+ {0x048e, {1|F|D, {0x048f}}},
+ {0x0490, {1|F|D, {0x0491}}},
+ {0x0492, {1|F|D, {0x0493}}},
+ {0x0494, {1|F|D, {0x0495}}},
+ {0x0496, {1|F|D, {0x0497}}},
+ {0x0498, {1|F|D, {0x0499}}},
+ {0x049a, {1|F|D, {0x049b}}},
+ {0x049c, {1|F|D, {0x049d}}},
+ {0x049e, {1|F|D, {0x049f}}},
+ {0x04a0, {1|F|D, {0x04a1}}},
+ {0x04a2, {1|F|D, {0x04a3}}},
+ {0x04a4, {1|F|D, {0x04a5}}},
+ {0x04a6, {1|F|D, {0x04a7}}},
+ {0x04a8, {1|F|D, {0x04a9}}},
+ {0x04aa, {1|F|D, {0x04ab}}},
+ {0x04ac, {1|F|D, {0x04ad}}},
+ {0x04ae, {1|F|D, {0x04af}}},
+ {0x04b0, {1|F|D, {0x04b1}}},
+ {0x04b2, {1|F|D, {0x04b3}}},
+ {0x04b4, {1|F|D, {0x04b5}}},
+ {0x04b6, {1|F|D, {0x04b7}}},
+ {0x04b8, {1|F|D, {0x04b9}}},
+ {0x04ba, {1|F|D, {0x04bb}}},
+ {0x04bc, {1|F|D, {0x04bd}}},
+ {0x04be, {1|F|D, {0x04bf}}},
+ {0x04c0, {1|F|D, {0x04cf}}},
+ {0x04c1, {1|F|D, {0x04c2}}},
+ {0x04c3, {1|F|D, {0x04c4}}},
+ {0x04c5, {1|F|D, {0x04c6}}},
+ {0x04c7, {1|F|D, {0x04c8}}},
+ {0x04c9, {1|F|D, {0x04ca}}},
+ {0x04cb, {1|F|D, {0x04cc}}},
+ {0x04cd, {1|F|D, {0x04ce}}},
+ {0x04d0, {1|F|D, {0x04d1}}},
+ {0x04d2, {1|F|D, {0x04d3}}},
+ {0x04d4, {1|F|D, {0x04d5}}},
+ {0x04d6, {1|F|D, {0x04d7}}},
+ {0x04d8, {1|F|D, {0x04d9}}},
+ {0x04da, {1|F|D, {0x04db}}},
+ {0x04dc, {1|F|D, {0x04dd}}},
+ {0x04de, {1|F|D, {0x04df}}},
+ {0x04e0, {1|F|D, {0x04e1}}},
+ {0x04e2, {1|F|D, {0x04e3}}},
+ {0x04e4, {1|F|D, {0x04e5}}},
+ {0x04e6, {1|F|D, {0x04e7}}},
+ {0x04e8, {1|F|D, {0x04e9}}},
+ {0x04ea, {1|F|D, {0x04eb}}},
+ {0x04ec, {1|F|D, {0x04ed}}},
+ {0x04ee, {1|F|D, {0x04ef}}},
+ {0x04f0, {1|F|D, {0x04f1}}},
+ {0x04f2, {1|F|D, {0x04f3}}},
+ {0x04f4, {1|F|D, {0x04f5}}},
+ {0x04f6, {1|F|D, {0x04f7}}},
+ {0x04f8, {1|F|D, {0x04f9}}},
+ {0x04fa, {1|F|D, {0x04fb}}},
+ {0x04fc, {1|F|D, {0x04fd}}},
+ {0x04fe, {1|F|D, {0x04ff}}},
+ {0x0500, {1|F|D, {0x0501}}},
+ {0x0502, {1|F|D, {0x0503}}},
+ {0x0504, {1|F|D, {0x0505}}},
+ {0x0506, {1|F|D, {0x0507}}},
+ {0x0508, {1|F|D, {0x0509}}},
+ {0x050a, {1|F|D, {0x050b}}},
+ {0x050c, {1|F|D, {0x050d}}},
+ {0x050e, {1|F|D, {0x050f}}},
+ {0x0510, {1|F|D, {0x0511}}},
+ {0x0512, {1|F|D, {0x0513}}},
+ {0x0514, {1|F|D, {0x0515}}},
+ {0x0516, {1|F|D, {0x0517}}},
+ {0x0518, {1|F|D, {0x0519}}},
+ {0x051a, {1|F|D, {0x051b}}},
+ {0x051c, {1|F|D, {0x051d}}},
+ {0x051e, {1|F|D, {0x051f}}},
+ {0x0520, {1|F|D, {0x0521}}},
+ {0x0522, {1|F|D, {0x0523}}},
+ {0x0524, {1|F|D, {0x0525}}},
+ {0x0526, {1|F|D, {0x0527}}},
+ {0x0528, {1|F|D, {0x0529}}},
+ {0x052a, {1|F|D, {0x052b}}},
+ {0x052c, {1|F|D, {0x052d}}},
+ {0x052e, {1|F|D, {0x052f}}},
+ {0x0531, {1|F|D, {0x0561}}},
+ {0x0532, {1|F|D, {0x0562}}},
+ {0x0533, {1|F|D, {0x0563}}},
+ {0x0534, {1|F|D, {0x0564}}},
+ {0x0535, {1|F|D, {0x0565}}},
+ {0x0536, {1|F|D, {0x0566}}},
+ {0x0537, {1|F|D, {0x0567}}},
+ {0x0538, {1|F|D, {0x0568}}},
+ {0x0539, {1|F|D, {0x0569}}},
+ {0x053a, {1|F|D, {0x056a}}},
+ {0x053b, {1|F|D, {0x056b}}},
+ {0x053c, {1|F|D, {0x056c}}},
+ {0x053d, {1|F|D, {0x056d}}},
+ {0x053e, {1|F|D, {0x056e}}},
+ {0x053f, {1|F|D, {0x056f}}},
+ {0x0540, {1|F|D, {0x0570}}},
+ {0x0541, {1|F|D, {0x0571}}},
+ {0x0542, {1|F|D, {0x0572}}},
+ {0x0543, {1|F|D, {0x0573}}},
+ {0x0544, {1|F|D, {0x0574}}},
+ {0x0545, {1|F|D, {0x0575}}},
+ {0x0546, {1|F|D, {0x0576}}},
+ {0x0547, {1|F|D, {0x0577}}},
+ {0x0548, {1|F|D, {0x0578}}},
+ {0x0549, {1|F|D, {0x0579}}},
+ {0x054a, {1|F|D, {0x057a}}},
+ {0x054b, {1|F|D, {0x057b}}},
+ {0x054c, {1|F|D, {0x057c}}},
+ {0x054d, {1|F|D, {0x057d}}},
+ {0x054e, {1|F|D, {0x057e}}},
+ {0x054f, {1|F|D, {0x057f}}},
+ {0x0550, {1|F|D, {0x0580}}},
+ {0x0551, {1|F|D, {0x0581}}},
+ {0x0552, {1|F|D, {0x0582}}},
+ {0x0553, {1|F|D, {0x0583}}},
+ {0x0554, {1|F|D, {0x0584}}},
+ {0x0555, {1|F|D, {0x0585}}},
+ {0x0556, {1|F|D, {0x0586}}},
+ {0x0587, {2|F|ST|SU|I(41), {0x0565, 0x0582}}},
+ {0x10a0, {1|F|D, {0x2d00}}},
+ {0x10a1, {1|F|D, {0x2d01}}},
+ {0x10a2, {1|F|D, {0x2d02}}},
+ {0x10a3, {1|F|D, {0x2d03}}},
+ {0x10a4, {1|F|D, {0x2d04}}},
+ {0x10a5, {1|F|D, {0x2d05}}},
+ {0x10a6, {1|F|D, {0x2d06}}},
+ {0x10a7, {1|F|D, {0x2d07}}},
+ {0x10a8, {1|F|D, {0x2d08}}},
+ {0x10a9, {1|F|D, {0x2d09}}},
+ {0x10aa, {1|F|D, {0x2d0a}}},
+ {0x10ab, {1|F|D, {0x2d0b}}},
+ {0x10ac, {1|F|D, {0x2d0c}}},
+ {0x10ad, {1|F|D, {0x2d0d}}},
+ {0x10ae, {1|F|D, {0x2d0e}}},
+ {0x10af, {1|F|D, {0x2d0f}}},
+ {0x10b0, {1|F|D, {0x2d10}}},
+ {0x10b1, {1|F|D, {0x2d11}}},
+ {0x10b2, {1|F|D, {0x2d12}}},
+ {0x10b3, {1|F|D, {0x2d13}}},
+ {0x10b4, {1|F|D, {0x2d14}}},
+ {0x10b5, {1|F|D, {0x2d15}}},
+ {0x10b6, {1|F|D, {0x2d16}}},
+ {0x10b7, {1|F|D, {0x2d17}}},
+ {0x10b8, {1|F|D, {0x2d18}}},
+ {0x10b9, {1|F|D, {0x2d19}}},
+ {0x10ba, {1|F|D, {0x2d1a}}},
+ {0x10bb, {1|F|D, {0x2d1b}}},
+ {0x10bc, {1|F|D, {0x2d1c}}},
+ {0x10bd, {1|F|D, {0x2d1d}}},
+ {0x10be, {1|F|D, {0x2d1e}}},
+ {0x10bf, {1|F|D, {0x2d1f}}},
+ {0x10c0, {1|F|D, {0x2d20}}},
+ {0x10c1, {1|F|D, {0x2d21}}},
+ {0x10c2, {1|F|D, {0x2d22}}},
+ {0x10c3, {1|F|D, {0x2d23}}},
+ {0x10c4, {1|F|D, {0x2d24}}},
+ {0x10c5, {1|F|D, {0x2d25}}},
+ {0x10c7, {1|F|D, {0x2d27}}},
+ {0x10cd, {1|F|D, {0x2d2d}}},
+ {0x13f8, {1|F|U, {0x13f0}}},
+ {0x13f9, {1|F|U, {0x13f1}}},
+ {0x13fa, {1|F|U, {0x13f2}}},
+ {0x13fb, {1|F|U, {0x13f3}}},
+ {0x13fc, {1|F|U, {0x13f4}}},
+ {0x13fd, {1|F|U, {0x13f5}}},
+ {0x1c80, {1|F|SU|I(45), {0x0432}}},
+ {0x1c81, {1|F|SU|I(46), {0x0434}}},
+ {0x1c82, {1|F|SU|I(47), {0x043e}}},
+ {0x1c83, {1|F|SU|I(48), {0x0441}}},
+ {0x1c84, {1|F|SU|I(49), {0x0442}}},
+ {0x1c85, {1|F|SU|I(50), {0x0442}}},
+ {0x1c86, {1|F|SU|I(51), {0x044a}}},
+ {0x1c87, {1|F|SU|I(52), {0x0463}}},
+ {0x1c88, {1|F|SU|I(53), {0xa64b}}},
+ {0x1c90, {1|F|D, {0x10d0}}},
+ {0x1c91, {1|F|D, {0x10d1}}},
+ {0x1c92, {1|F|D, {0x10d2}}},
+ {0x1c93, {1|F|D, {0x10d3}}},
+ {0x1c94, {1|F|D, {0x10d4}}},
+ {0x1c95, {1|F|D, {0x10d5}}},
+ {0x1c96, {1|F|D, {0x10d6}}},
+ {0x1c97, {1|F|D, {0x10d7}}},
+ {0x1c98, {1|F|D, {0x10d8}}},
+ {0x1c99, {1|F|D, {0x10d9}}},
+ {0x1c9a, {1|F|D, {0x10da}}},
+ {0x1c9b, {1|F|D, {0x10db}}},
+ {0x1c9c, {1|F|D, {0x10dc}}},
+ {0x1c9d, {1|F|D, {0x10dd}}},
+ {0x1c9e, {1|F|D, {0x10de}}},
+ {0x1c9f, {1|F|D, {0x10df}}},
+ {0x1ca0, {1|F|D, {0x10e0}}},
+ {0x1ca1, {1|F|D, {0x10e1}}},
+ {0x1ca2, {1|F|D, {0x10e2}}},
+ {0x1ca3, {1|F|D, {0x10e3}}},
+ {0x1ca4, {1|F|D, {0x10e4}}},
+ {0x1ca5, {1|F|D, {0x10e5}}},
+ {0x1ca6, {1|F|D, {0x10e6}}},
+ {0x1ca7, {1|F|D, {0x10e7}}},
+ {0x1ca8, {1|F|D, {0x10e8}}},
+ {0x1ca9, {1|F|D, {0x10e9}}},
+ {0x1caa, {1|F|D, {0x10ea}}},
+ {0x1cab, {1|F|D, {0x10eb}}},
+ {0x1cac, {1|F|D, {0x10ec}}},
+ {0x1cad, {1|F|D, {0x10ed}}},
+ {0x1cae, {1|F|D, {0x10ee}}},
+ {0x1caf, {1|F|D, {0x10ef}}},
+ {0x1cb0, {1|F|D, {0x10f0}}},
+ {0x1cb1, {1|F|D, {0x10f1}}},
+ {0x1cb2, {1|F|D, {0x10f2}}},
+ {0x1cb3, {1|F|D, {0x10f3}}},
+ {0x1cb4, {1|F|D, {0x10f4}}},
+ {0x1cb5, {1|F|D, {0x10f5}}},
+ {0x1cb6, {1|F|D, {0x10f6}}},
+ {0x1cb7, {1|F|D, {0x10f7}}},
+ {0x1cb8, {1|F|D, {0x10f8}}},
+ {0x1cb9, {1|F|D, {0x10f9}}},
+ {0x1cba, {1|F|D, {0x10fa}}},
+ {0x1cbd, {1|F|D, {0x10fd}}},
+ {0x1cbe, {1|F|D, {0x10fe}}},
+ {0x1cbf, {1|F|D, {0x10ff}}},
+ {0x1e00, {1|F|D, {0x1e01}}},
+ {0x1e02, {1|F|D, {0x1e03}}},
+ {0x1e04, {1|F|D, {0x1e05}}},
+ {0x1e06, {1|F|D, {0x1e07}}},
+ {0x1e08, {1|F|D, {0x1e09}}},
+ {0x1e0a, {1|F|D, {0x1e0b}}},
+ {0x1e0c, {1|F|D, {0x1e0d}}},
+ {0x1e0e, {1|F|D, {0x1e0f}}},
+ {0x1e10, {1|F|D, {0x1e11}}},
+ {0x1e12, {1|F|D, {0x1e13}}},
+ {0x1e14, {1|F|D, {0x1e15}}},
+ {0x1e16, {1|F|D, {0x1e17}}},
+ {0x1e18, {1|F|D, {0x1e19}}},
+ {0x1e1a, {1|F|D, {0x1e1b}}},
+ {0x1e1c, {1|F|D, {0x1e1d}}},
+ {0x1e1e, {1|F|D, {0x1e1f}}},
+ {0x1e20, {1|F|D, {0x1e21}}},
+ {0x1e22, {1|F|D, {0x1e23}}},
+ {0x1e24, {1|F|D, {0x1e25}}},
+ {0x1e26, {1|F|D, {0x1e27}}},
+ {0x1e28, {1|F|D, {0x1e29}}},
+ {0x1e2a, {1|F|D, {0x1e2b}}},
+ {0x1e2c, {1|F|D, {0x1e2d}}},
+ {0x1e2e, {1|F|D, {0x1e2f}}},
+ {0x1e30, {1|F|D, {0x1e31}}},
+ {0x1e32, {1|F|D, {0x1e33}}},
+ {0x1e34, {1|F|D, {0x1e35}}},
+ {0x1e36, {1|F|D, {0x1e37}}},
+ {0x1e38, {1|F|D, {0x1e39}}},
+ {0x1e3a, {1|F|D, {0x1e3b}}},
+ {0x1e3c, {1|F|D, {0x1e3d}}},
+ {0x1e3e, {1|F|D, {0x1e3f}}},
+ {0x1e40, {1|F|D, {0x1e41}}},
+ {0x1e42, {1|F|D, {0x1e43}}},
+ {0x1e44, {1|F|D, {0x1e45}}},
+ {0x1e46, {1|F|D, {0x1e47}}},
+ {0x1e48, {1|F|D, {0x1e49}}},
+ {0x1e4a, {1|F|D, {0x1e4b}}},
+ {0x1e4c, {1|F|D, {0x1e4d}}},
+ {0x1e4e, {1|F|D, {0x1e4f}}},
+ {0x1e50, {1|F|D, {0x1e51}}},
+ {0x1e52, {1|F|D, {0x1e53}}},
+ {0x1e54, {1|F|D, {0x1e55}}},
+ {0x1e56, {1|F|D, {0x1e57}}},
+ {0x1e58, {1|F|D, {0x1e59}}},
+ {0x1e5a, {1|F|D, {0x1e5b}}},
+ {0x1e5c, {1|F|D, {0x1e5d}}},
+ {0x1e5e, {1|F|D, {0x1e5f}}},
+ {0x1e60, {1|F|D, {0x1e61}}},
+ {0x1e62, {1|F|D, {0x1e63}}},
+ {0x1e64, {1|F|D, {0x1e65}}},
+ {0x1e66, {1|F|D, {0x1e67}}},
+ {0x1e68, {1|F|D, {0x1e69}}},
+ {0x1e6a, {1|F|D, {0x1e6b}}},
+ {0x1e6c, {1|F|D, {0x1e6d}}},
+ {0x1e6e, {1|F|D, {0x1e6f}}},
+ {0x1e70, {1|F|D, {0x1e71}}},
+ {0x1e72, {1|F|D, {0x1e73}}},
+ {0x1e74, {1|F|D, {0x1e75}}},
+ {0x1e76, {1|F|D, {0x1e77}}},
+ {0x1e78, {1|F|D, {0x1e79}}},
+ {0x1e7a, {1|F|D, {0x1e7b}}},
+ {0x1e7c, {1|F|D, {0x1e7d}}},
+ {0x1e7e, {1|F|D, {0x1e7f}}},
+ {0x1e80, {1|F|D, {0x1e81}}},
+ {0x1e82, {1|F|D, {0x1e83}}},
+ {0x1e84, {1|F|D, {0x1e85}}},
+ {0x1e86, {1|F|D, {0x1e87}}},
+ {0x1e88, {1|F|D, {0x1e89}}},
+ {0x1e8a, {1|F|D, {0x1e8b}}},
+ {0x1e8c, {1|F|D, {0x1e8d}}},
+ {0x1e8e, {1|F|D, {0x1e8f}}},
+ {0x1e90, {1|F|D, {0x1e91}}},
+ {0x1e92, {1|F|D, {0x1e93}}},
+ {0x1e94, {1|F|D, {0x1e95}}},
+ {0x1e96, {2|F|SU|I(54), {0x0068, 0x0331}}},
+ {0x1e97, {2|F|SU|I(56), {0x0074, 0x0308}}},
+ {0x1e98, {2|F|SU|I(58), {0x0077, 0x030a}}},
+ {0x1e99, {2|F|SU|I(60), {0x0079, 0x030a}}},
+ {0x1e9a, {2|F|SU|I(62), {0x0061, 0x02be}}},
+ {0x1e9b, {1|F|SU|I(64), {0x1e61}}},
+ {0x1e9e, {2|F|SL|I(65), {0x0073, 0x0073}}},
+ {0x1ea0, {1|F|D, {0x1ea1}}},
+ {0x1ea2, {1|F|D, {0x1ea3}}},
+ {0x1ea4, {1|F|D, {0x1ea5}}},
+ {0x1ea6, {1|F|D, {0x1ea7}}},
+ {0x1ea8, {1|F|D, {0x1ea9}}},
+ {0x1eaa, {1|F|D, {0x1eab}}},
+ {0x1eac, {1|F|D, {0x1ead}}},
+ {0x1eae, {1|F|D, {0x1eaf}}},
+ {0x1eb0, {1|F|D, {0x1eb1}}},
+ {0x1eb2, {1|F|D, {0x1eb3}}},
+ {0x1eb4, {1|F|D, {0x1eb5}}},
+ {0x1eb6, {1|F|D, {0x1eb7}}},
+ {0x1eb8, {1|F|D, {0x1eb9}}},
+ {0x1eba, {1|F|D, {0x1ebb}}},
+ {0x1ebc, {1|F|D, {0x1ebd}}},
+ {0x1ebe, {1|F|D, {0x1ebf}}},
+ {0x1ec0, {1|F|D, {0x1ec1}}},
+ {0x1ec2, {1|F|D, {0x1ec3}}},
+ {0x1ec4, {1|F|D, {0x1ec5}}},
+ {0x1ec6, {1|F|D, {0x1ec7}}},
+ {0x1ec8, {1|F|D, {0x1ec9}}},
+ {0x1eca, {1|F|D, {0x1ecb}}},
+ {0x1ecc, {1|F|D, {0x1ecd}}},
+ {0x1ece, {1|F|D, {0x1ecf}}},
+ {0x1ed0, {1|F|D, {0x1ed1}}},
+ {0x1ed2, {1|F|D, {0x1ed3}}},
+ {0x1ed4, {1|F|D, {0x1ed5}}},
+ {0x1ed6, {1|F|D, {0x1ed7}}},
+ {0x1ed8, {1|F|D, {0x1ed9}}},
+ {0x1eda, {1|F|D, {0x1edb}}},
+ {0x1edc, {1|F|D, {0x1edd}}},
+ {0x1ede, {1|F|D, {0x1edf}}},
+ {0x1ee0, {1|F|D, {0x1ee1}}},
+ {0x1ee2, {1|F|D, {0x1ee3}}},
+ {0x1ee4, {1|F|D, {0x1ee5}}},
+ {0x1ee6, {1|F|D, {0x1ee7}}},
+ {0x1ee8, {1|F|D, {0x1ee9}}},
+ {0x1eea, {1|F|D, {0x1eeb}}},
+ {0x1eec, {1|F|D, {0x1eed}}},
+ {0x1eee, {1|F|D, {0x1eef}}},
+ {0x1ef0, {1|F|D, {0x1ef1}}},
+ {0x1ef2, {1|F|D, {0x1ef3}}},
+ {0x1ef4, {1|F|D, {0x1ef5}}},
+ {0x1ef6, {1|F|D, {0x1ef7}}},
+ {0x1ef8, {1|F|D, {0x1ef9}}},
+ {0x1efa, {1|F|D, {0x1efb}}},
+ {0x1efc, {1|F|D, {0x1efd}}},
+ {0x1efe, {1|F|D, {0x1eff}}},
+ {0x1f08, {1|F|D, {0x1f00}}},
+ {0x1f09, {1|F|D, {0x1f01}}},
+ {0x1f0a, {1|F|D, {0x1f02}}},
+ {0x1f0b, {1|F|D, {0x1f03}}},
+ {0x1f0c, {1|F|D, {0x1f04}}},
+ {0x1f0d, {1|F|D, {0x1f05}}},
+ {0x1f0e, {1|F|D, {0x1f06}}},
+ {0x1f0f, {1|F|D, {0x1f07}}},
+ {0x1f18, {1|F|D, {0x1f10}}},
+ {0x1f19, {1|F|D, {0x1f11}}},
+ {0x1f1a, {1|F|D, {0x1f12}}},
+ {0x1f1b, {1|F|D, {0x1f13}}},
+ {0x1f1c, {1|F|D, {0x1f14}}},
+ {0x1f1d, {1|F|D, {0x1f15}}},
+ {0x1f28, {1|F|D, {0x1f20}}},
+ {0x1f29, {1|F|D, {0x1f21}}},
+ {0x1f2a, {1|F|D, {0x1f22}}},
+ {0x1f2b, {1|F|D, {0x1f23}}},
+ {0x1f2c, {1|F|D, {0x1f24}}},
+ {0x1f2d, {1|F|D, {0x1f25}}},
+ {0x1f2e, {1|F|D, {0x1f26}}},
+ {0x1f2f, {1|F|D, {0x1f27}}},
+ {0x1f38, {1|F|D, {0x1f30}}},
+ {0x1f39, {1|F|D, {0x1f31}}},
+ {0x1f3a, {1|F|D, {0x1f32}}},
+ {0x1f3b, {1|F|D, {0x1f33}}},
+ {0x1f3c, {1|F|D, {0x1f34}}},
+ {0x1f3d, {1|F|D, {0x1f35}}},
+ {0x1f3e, {1|F|D, {0x1f36}}},
+ {0x1f3f, {1|F|D, {0x1f37}}},
+ {0x1f48, {1|F|D, {0x1f40}}},
+ {0x1f49, {1|F|D, {0x1f41}}},
+ {0x1f4a, {1|F|D, {0x1f42}}},
+ {0x1f4b, {1|F|D, {0x1f43}}},
+ {0x1f4c, {1|F|D, {0x1f44}}},
+ {0x1f4d, {1|F|D, {0x1f45}}},
+ {0x1f50, {2|F|SU|I(66), {0x03c5, 0x0313}}},
+ {0x1f52, {3|F|SU|I(68), {0x03c5, 0x0313, 0x0300}}},
+ {0x1f54, {3|F|SU|I(71), {0x03c5, 0x0313, 0x0301}}},
+ {0x1f56, {3|F|SU|I(74), {0x03c5, 0x0313, 0x0342}}},
+ {0x1f59, {1|F|D, {0x1f51}}},
+ {0x1f5b, {1|F|D, {0x1f53}}},
+ {0x1f5d, {1|F|D, {0x1f55}}},
+ {0x1f5f, {1|F|D, {0x1f57}}},
+ {0x1f68, {1|F|D, {0x1f60}}},
+ {0x1f69, {1|F|D, {0x1f61}}},
+ {0x1f6a, {1|F|D, {0x1f62}}},
+ {0x1f6b, {1|F|D, {0x1f63}}},
+ {0x1f6c, {1|F|D, {0x1f64}}},
+ {0x1f6d, {1|F|D, {0x1f65}}},
+ {0x1f6e, {1|F|D, {0x1f66}}},
+ {0x1f6f, {1|F|D, {0x1f67}}},
+ {0x1f80, {2|F|ST|SU|I(77), {0x1f00, 0x03b9}}},
+ {0x1f81, {2|F|ST|SU|I(80), {0x1f01, 0x03b9}}},
+ {0x1f82, {2|F|ST|SU|I(83), {0x1f02, 0x03b9}}},
+ {0x1f83, {2|F|ST|SU|I(86), {0x1f03, 0x03b9}}},
+ {0x1f84, {2|F|ST|SU|I(89), {0x1f04, 0x03b9}}},
+ {0x1f85, {2|F|ST|SU|I(92), {0x1f05, 0x03b9}}},
+ {0x1f86, {2|F|ST|SU|I(95), {0x1f06, 0x03b9}}},
+ {0x1f87, {2|F|ST|SU|I(98), {0x1f07, 0x03b9}}},
+ {0x1f88, {2|F|IT|SL|SU|I(101), {0x1f00, 0x03b9}}},
+ {0x1f89, {2|F|IT|SL|SU|I(106), {0x1f01, 0x03b9}}},
+ {0x1f8a, {2|F|IT|SL|SU|I(111), {0x1f02, 0x03b9}}},
+ {0x1f8b, {2|F|IT|SL|SU|I(116), {0x1f03, 0x03b9}}},
+ {0x1f8c, {2|F|IT|SL|SU|I(121), {0x1f04, 0x03b9}}},
+ {0x1f8d, {2|F|IT|SL|SU|I(126), {0x1f05, 0x03b9}}},
+ {0x1f8e, {2|F|IT|SL|SU|I(131), {0x1f06, 0x03b9}}},
+ {0x1f8f, {2|F|IT|SL|SU|I(136), {0x1f07, 0x03b9}}},
+ {0x1f90, {2|F|ST|SU|I(141), {0x1f20, 0x03b9}}},
+ {0x1f91, {2|F|ST|SU|I(144), {0x1f21, 0x03b9}}},
+ {0x1f92, {2|F|ST|SU|I(147), {0x1f22, 0x03b9}}},
+ {0x1f93, {2|F|ST|SU|I(150), {0x1f23, 0x03b9}}},
+ {0x1f94, {2|F|ST|SU|I(153), {0x1f24, 0x03b9}}},
+ {0x1f95, {2|F|ST|SU|I(156), {0x1f25, 0x03b9}}},
+ {0x1f96, {2|F|ST|SU|I(159), {0x1f26, 0x03b9}}},
+ {0x1f97, {2|F|ST|SU|I(162), {0x1f27, 0x03b9}}},
+ {0x1f98, {2|F|IT|SL|SU|I(165), {0x1f20, 0x03b9}}},
+ {0x1f99, {2|F|IT|SL|SU|I(170), {0x1f21, 0x03b9}}},
+ {0x1f9a, {2|F|IT|SL|SU|I(175), {0x1f22, 0x03b9}}},
+ {0x1f9b, {2|F|IT|SL|SU|I(180), {0x1f23, 0x03b9}}},
+ {0x1f9c, {2|F|IT|SL|SU|I(185), {0x1f24, 0x03b9}}},
+ {0x1f9d, {2|F|IT|SL|SU|I(190), {0x1f25, 0x03b9}}},
+ {0x1f9e, {2|F|IT|SL|SU|I(195), {0x1f26, 0x03b9}}},
+ {0x1f9f, {2|F|IT|SL|SU|I(200), {0x1f27, 0x03b9}}},
+ {0x1fa0, {2|F|ST|SU|I(205), {0x1f60, 0x03b9}}},
+ {0x1fa1, {2|F|ST|SU|I(208), {0x1f61, 0x03b9}}},
+ {0x1fa2, {2|F|ST|SU|I(211), {0x1f62, 0x03b9}}},
+ {0x1fa3, {2|F|ST|SU|I(214), {0x1f63, 0x03b9}}},
+ {0x1fa4, {2|F|ST|SU|I(217), {0x1f64, 0x03b9}}},
+ {0x1fa5, {2|F|ST|SU|I(220), {0x1f65, 0x03b9}}},
+ {0x1fa6, {2|F|ST|SU|I(223), {0x1f66, 0x03b9}}},
+ {0x1fa7, {2|F|ST|SU|I(226), {0x1f67, 0x03b9}}},
+ {0x1fa8, {2|F|IT|SL|SU|I(229), {0x1f60, 0x03b9}}},
+ {0x1fa9, {2|F|IT|SL|SU|I(234), {0x1f61, 0x03b9}}},
+ {0x1faa, {2|F|IT|SL|SU|I(239), {0x1f62, 0x03b9}}},
+ {0x1fab, {2|F|IT|SL|SU|I(244), {0x1f63, 0x03b9}}},
+ {0x1fac, {2|F|IT|SL|SU|I(249), {0x1f64, 0x03b9}}},
+ {0x1fad, {2|F|IT|SL|SU|I(254), {0x1f65, 0x03b9}}},
+ {0x1fae, {2|F|IT|SL|SU|I(259), {0x1f66, 0x03b9}}},
+ {0x1faf, {2|F|IT|SL|SU|I(264), {0x1f67, 0x03b9}}},
+ {0x1fb2, {2|F|ST|SU|I(269), {0x1f70, 0x03b9}}},
+ {0x1fb3, {2|F|ST|SU|I(273), {0x03b1, 0x03b9}}},
+ {0x1fb4, {2|F|ST|SU|I(276), {0x03ac, 0x03b9}}},
+ {0x1fb6, {2|F|SU|I(280), {0x03b1, 0x0342}}},
+ {0x1fb7, {3|F|ST|SU|I(282), {0x03b1, 0x0342, 0x03b9}}},
+ {0x1fb8, {1|F|D, {0x1fb0}}},
+ {0x1fb9, {1|F|D, {0x1fb1}}},
+ {0x1fba, {1|F|D, {0x1f70}}},
+ {0x1fbb, {1|F|D, {0x1f71}}},
+ {0x1fbc, {2|F|IT|SL|SU|I(288), {0x03b1, 0x03b9}}},
+ {0x1fbe, {1|F|SU|I(293), {0x03b9}}},
+ {0x1fc2, {2|F|ST|SU|I(294), {0x1f74, 0x03b9}}},
+ {0x1fc3, {2|F|ST|SU|I(298), {0x03b7, 0x03b9}}},
+ {0x1fc4, {2|F|ST|SU|I(301), {0x03ae, 0x03b9}}},
+ {0x1fc6, {2|F|SU|I(305), {0x03b7, 0x0342}}},
+ {0x1fc7, {3|F|ST|SU|I(307), {0x03b7, 0x0342, 0x03b9}}},
+ {0x1fc8, {1|F|D, {0x1f72}}},
+ {0x1fc9, {1|F|D, {0x1f73}}},
+ {0x1fca, {1|F|D, {0x1f74}}},
+ {0x1fcb, {1|F|D, {0x1f75}}},
+ {0x1fcc, {2|F|IT|SL|SU|I(313), {0x03b7, 0x03b9}}},
+ {0x1fd2, {3|F|SU|I(318), {0x03b9, 0x0308, 0x0300}}},
+ {0x1fd3, {3|F|SU|I(321), {0x03b9, 0x0308, 0x0301}}},
+ {0x1fd6, {2|F|SU|I(324), {0x03b9, 0x0342}}},
+ {0x1fd7, {3|F|SU|I(326), {0x03b9, 0x0308, 0x0342}}},
+ {0x1fd8, {1|F|D, {0x1fd0}}},
+ {0x1fd9, {1|F|D, {0x1fd1}}},
+ {0x1fda, {1|F|D, {0x1f76}}},
+ {0x1fdb, {1|F|D, {0x1f77}}},
+ {0x1fe2, {3|F|SU|I(329), {0x03c5, 0x0308, 0x0300}}},
+ {0x1fe3, {3|F|SU|I(332), {0x03c5, 0x0308, 0x0301}}},
+ {0x1fe4, {2|F|SU|I(335), {0x03c1, 0x0313}}},
+ {0x1fe6, {2|F|SU|I(337), {0x03c5, 0x0342}}},
+ {0x1fe7, {3|F|SU|I(339), {0x03c5, 0x0308, 0x0342}}},
+ {0x1fe8, {1|F|D, {0x1fe0}}},
+ {0x1fe9, {1|F|D, {0x1fe1}}},
+ {0x1fea, {1|F|D, {0x1f7a}}},
+ {0x1feb, {1|F|D, {0x1f7b}}},
+ {0x1fec, {1|F|D, {0x1fe5}}},
+ {0x1ff2, {2|F|ST|SU|I(342), {0x1f7c, 0x03b9}}},
+ {0x1ff3, {2|F|ST|SU|I(346), {0x03c9, 0x03b9}}},
+ {0x1ff4, {2|F|ST|SU|I(349), {0x03ce, 0x03b9}}},
+ {0x1ff6, {2|F|SU|I(353), {0x03c9, 0x0342}}},
+ {0x1ff7, {3|F|ST|SU|I(355), {0x03c9, 0x0342, 0x03b9}}},
+ {0x1ff8, {1|F|D, {0x1f78}}},
+ {0x1ff9, {1|F|D, {0x1f79}}},
+ {0x1ffa, {1|F|D, {0x1f7c}}},
+ {0x1ffb, {1|F|D, {0x1f7d}}},
+ {0x1ffc, {2|F|IT|SL|SU|I(361), {0x03c9, 0x03b9}}},
+ {0x2126, {1|F|D, {0x03c9}}},
+ {0x212a, {1|F|D, {0x006b}}},
+ {0x212b, {1|F|D, {0x00e5}}},
+ {0x2132, {1|F|D, {0x214e}}},
+ {0x2160, {1|F|D, {0x2170}}},
+ {0x2161, {1|F|D, {0x2171}}},
+ {0x2162, {1|F|D, {0x2172}}},
+ {0x2163, {1|F|D, {0x2173}}},
+ {0x2164, {1|F|D, {0x2174}}},
+ {0x2165, {1|F|D, {0x2175}}},
+ {0x2166, {1|F|D, {0x2176}}},
+ {0x2167, {1|F|D, {0x2177}}},
+ {0x2168, {1|F|D, {0x2178}}},
+ {0x2169, {1|F|D, {0x2179}}},
+ {0x216a, {1|F|D, {0x217a}}},
+ {0x216b, {1|F|D, {0x217b}}},
+ {0x216c, {1|F|D, {0x217c}}},
+ {0x216d, {1|F|D, {0x217d}}},
+ {0x216e, {1|F|D, {0x217e}}},
+ {0x216f, {1|F|D, {0x217f}}},
+ {0x2183, {1|F|D, {0x2184}}},
+ {0x24b6, {1|F|D, {0x24d0}}},
+ {0x24b7, {1|F|D, {0x24d1}}},
+ {0x24b8, {1|F|D, {0x24d2}}},
+ {0x24b9, {1|F|D, {0x24d3}}},
+ {0x24ba, {1|F|D, {0x24d4}}},
+ {0x24bb, {1|F|D, {0x24d5}}},
+ {0x24bc, {1|F|D, {0x24d6}}},
+ {0x24bd, {1|F|D, {0x24d7}}},
+ {0x24be, {1|F|D, {0x24d8}}},
+ {0x24bf, {1|F|D, {0x24d9}}},
+ {0x24c0, {1|F|D, {0x24da}}},
+ {0x24c1, {1|F|D, {0x24db}}},
+ {0x24c2, {1|F|D, {0x24dc}}},
+ {0x24c3, {1|F|D, {0x24dd}}},
+ {0x24c4, {1|F|D, {0x24de}}},
+ {0x24c5, {1|F|D, {0x24df}}},
+ {0x24c6, {1|F|D, {0x24e0}}},
+ {0x24c7, {1|F|D, {0x24e1}}},
+ {0x24c8, {1|F|D, {0x24e2}}},
+ {0x24c9, {1|F|D, {0x24e3}}},
+ {0x24ca, {1|F|D, {0x24e4}}},
+ {0x24cb, {1|F|D, {0x24e5}}},
+ {0x24cc, {1|F|D, {0x24e6}}},
+ {0x24cd, {1|F|D, {0x24e7}}},
+ {0x24ce, {1|F|D, {0x24e8}}},
+ {0x24cf, {1|F|D, {0x24e9}}},
+ {0x2c00, {1|F|D, {0x2c30}}},
+ {0x2c01, {1|F|D, {0x2c31}}},
+ {0x2c02, {1|F|D, {0x2c32}}},
+ {0x2c03, {1|F|D, {0x2c33}}},
+ {0x2c04, {1|F|D, {0x2c34}}},
+ {0x2c05, {1|F|D, {0x2c35}}},
+ {0x2c06, {1|F|D, {0x2c36}}},
+ {0x2c07, {1|F|D, {0x2c37}}},
+ {0x2c08, {1|F|D, {0x2c38}}},
+ {0x2c09, {1|F|D, {0x2c39}}},
+ {0x2c0a, {1|F|D, {0x2c3a}}},
+ {0x2c0b, {1|F|D, {0x2c3b}}},
+ {0x2c0c, {1|F|D, {0x2c3c}}},
+ {0x2c0d, {1|F|D, {0x2c3d}}},
+ {0x2c0e, {1|F|D, {0x2c3e}}},
+ {0x2c0f, {1|F|D, {0x2c3f}}},
+ {0x2c10, {1|F|D, {0x2c40}}},
+ {0x2c11, {1|F|D, {0x2c41}}},
+ {0x2c12, {1|F|D, {0x2c42}}},
+ {0x2c13, {1|F|D, {0x2c43}}},
+ {0x2c14, {1|F|D, {0x2c44}}},
+ {0x2c15, {1|F|D, {0x2c45}}},
+ {0x2c16, {1|F|D, {0x2c46}}},
+ {0x2c17, {1|F|D, {0x2c47}}},
+ {0x2c18, {1|F|D, {0x2c48}}},
+ {0x2c19, {1|F|D, {0x2c49}}},
+ {0x2c1a, {1|F|D, {0x2c4a}}},
+ {0x2c1b, {1|F|D, {0x2c4b}}},
+ {0x2c1c, {1|F|D, {0x2c4c}}},
+ {0x2c1d, {1|F|D, {0x2c4d}}},
+ {0x2c1e, {1|F|D, {0x2c4e}}},
+ {0x2c1f, {1|F|D, {0x2c4f}}},
+ {0x2c20, {1|F|D, {0x2c50}}},
+ {0x2c21, {1|F|D, {0x2c51}}},
+ {0x2c22, {1|F|D, {0x2c52}}},
+ {0x2c23, {1|F|D, {0x2c53}}},
+ {0x2c24, {1|F|D, {0x2c54}}},
+ {0x2c25, {1|F|D, {0x2c55}}},
+ {0x2c26, {1|F|D, {0x2c56}}},
+ {0x2c27, {1|F|D, {0x2c57}}},
+ {0x2c28, {1|F|D, {0x2c58}}},
+ {0x2c29, {1|F|D, {0x2c59}}},
+ {0x2c2a, {1|F|D, {0x2c5a}}},
+ {0x2c2b, {1|F|D, {0x2c5b}}},
+ {0x2c2c, {1|F|D, {0x2c5c}}},
+ {0x2c2d, {1|F|D, {0x2c5d}}},
+ {0x2c2e, {1|F|D, {0x2c5e}}},
+ {0x2c60, {1|F|D, {0x2c61}}},
+ {0x2c62, {1|F|D, {0x026b}}},
+ {0x2c63, {1|F|D, {0x1d7d}}},
+ {0x2c64, {1|F|D, {0x027d}}},
+ {0x2c67, {1|F|D, {0x2c68}}},
+ {0x2c69, {1|F|D, {0x2c6a}}},
+ {0x2c6b, {1|F|D, {0x2c6c}}},
+ {0x2c6d, {1|F|D, {0x0251}}},
+ {0x2c6e, {1|F|D, {0x0271}}},
+ {0x2c6f, {1|F|D, {0x0250}}},
+ {0x2c70, {1|F|D, {0x0252}}},
+ {0x2c72, {1|F|D, {0x2c73}}},
+ {0x2c75, {1|F|D, {0x2c76}}},
+ {0x2c7e, {1|F|D, {0x023f}}},
+ {0x2c7f, {1|F|D, {0x0240}}},
+ {0x2c80, {1|F|D, {0x2c81}}},
+ {0x2c82, {1|F|D, {0x2c83}}},
+ {0x2c84, {1|F|D, {0x2c85}}},
+ {0x2c86, {1|F|D, {0x2c87}}},
+ {0x2c88, {1|F|D, {0x2c89}}},
+ {0x2c8a, {1|F|D, {0x2c8b}}},
+ {0x2c8c, {1|F|D, {0x2c8d}}},
+ {0x2c8e, {1|F|D, {0x2c8f}}},
+ {0x2c90, {1|F|D, {0x2c91}}},
+ {0x2c92, {1|F|D, {0x2c93}}},
+ {0x2c94, {1|F|D, {0x2c95}}},
+ {0x2c96, {1|F|D, {0x2c97}}},
+ {0x2c98, {1|F|D, {0x2c99}}},
+ {0x2c9a, {1|F|D, {0x2c9b}}},
+ {0x2c9c, {1|F|D, {0x2c9d}}},
+ {0x2c9e, {1|F|D, {0x2c9f}}},
+ {0x2ca0, {1|F|D, {0x2ca1}}},
+ {0x2ca2, {1|F|D, {0x2ca3}}},
+ {0x2ca4, {1|F|D, {0x2ca5}}},
+ {0x2ca6, {1|F|D, {0x2ca7}}},
+ {0x2ca8, {1|F|D, {0x2ca9}}},
+ {0x2caa, {1|F|D, {0x2cab}}},
+ {0x2cac, {1|F|D, {0x2cad}}},
+ {0x2cae, {1|F|D, {0x2caf}}},
+ {0x2cb0, {1|F|D, {0x2cb1}}},
+ {0x2cb2, {1|F|D, {0x2cb3}}},
+ {0x2cb4, {1|F|D, {0x2cb5}}},
+ {0x2cb6, {1|F|D, {0x2cb7}}},
+ {0x2cb8, {1|F|D, {0x2cb9}}},
+ {0x2cba, {1|F|D, {0x2cbb}}},
+ {0x2cbc, {1|F|D, {0x2cbd}}},
+ {0x2cbe, {1|F|D, {0x2cbf}}},
+ {0x2cc0, {1|F|D, {0x2cc1}}},
+ {0x2cc2, {1|F|D, {0x2cc3}}},
+ {0x2cc4, {1|F|D, {0x2cc5}}},
+ {0x2cc6, {1|F|D, {0x2cc7}}},
+ {0x2cc8, {1|F|D, {0x2cc9}}},
+ {0x2cca, {1|F|D, {0x2ccb}}},
+ {0x2ccc, {1|F|D, {0x2ccd}}},
+ {0x2cce, {1|F|D, {0x2ccf}}},
+ {0x2cd0, {1|F|D, {0x2cd1}}},
+ {0x2cd2, {1|F|D, {0x2cd3}}},
+ {0x2cd4, {1|F|D, {0x2cd5}}},
+ {0x2cd6, {1|F|D, {0x2cd7}}},
+ {0x2cd8, {1|F|D, {0x2cd9}}},
+ {0x2cda, {1|F|D, {0x2cdb}}},
+ {0x2cdc, {1|F|D, {0x2cdd}}},
+ {0x2cde, {1|F|D, {0x2cdf}}},
+ {0x2ce0, {1|F|D, {0x2ce1}}},
+ {0x2ce2, {1|F|D, {0x2ce3}}},
+ {0x2ceb, {1|F|D, {0x2cec}}},
+ {0x2ced, {1|F|D, {0x2cee}}},
+ {0x2cf2, {1|F|D, {0x2cf3}}},
+ {0xa640, {1|F|D, {0xa641}}},
+ {0xa642, {1|F|D, {0xa643}}},
+ {0xa644, {1|F|D, {0xa645}}},
+ {0xa646, {1|F|D, {0xa647}}},
+ {0xa648, {1|F|D, {0xa649}}},
+ {0xa64a, {1|F|D, {0xa64b}}},
+ {0xa64c, {1|F|D, {0xa64d}}},
+ {0xa64e, {1|F|D, {0xa64f}}},
+ {0xa650, {1|F|D, {0xa651}}},
+ {0xa652, {1|F|D, {0xa653}}},
+ {0xa654, {1|F|D, {0xa655}}},
+ {0xa656, {1|F|D, {0xa657}}},
+ {0xa658, {1|F|D, {0xa659}}},
+ {0xa65a, {1|F|D, {0xa65b}}},
+ {0xa65c, {1|F|D, {0xa65d}}},
+ {0xa65e, {1|F|D, {0xa65f}}},
+ {0xa660, {1|F|D, {0xa661}}},
+ {0xa662, {1|F|D, {0xa663}}},
+ {0xa664, {1|F|D, {0xa665}}},
+ {0xa666, {1|F|D, {0xa667}}},
+ {0xa668, {1|F|D, {0xa669}}},
+ {0xa66a, {1|F|D, {0xa66b}}},
+ {0xa66c, {1|F|D, {0xa66d}}},
+ {0xa680, {1|F|D, {0xa681}}},
+ {0xa682, {1|F|D, {0xa683}}},
+ {0xa684, {1|F|D, {0xa685}}},
+ {0xa686, {1|F|D, {0xa687}}},
+ {0xa688, {1|F|D, {0xa689}}},
+ {0xa68a, {1|F|D, {0xa68b}}},
+ {0xa68c, {1|F|D, {0xa68d}}},
+ {0xa68e, {1|F|D, {0xa68f}}},
+ {0xa690, {1|F|D, {0xa691}}},
+ {0xa692, {1|F|D, {0xa693}}},
+ {0xa694, {1|F|D, {0xa695}}},
+ {0xa696, {1|F|D, {0xa697}}},
+ {0xa698, {1|F|D, {0xa699}}},
+ {0xa69a, {1|F|D, {0xa69b}}},
+ {0xa722, {1|F|D, {0xa723}}},
+ {0xa724, {1|F|D, {0xa725}}},
+ {0xa726, {1|F|D, {0xa727}}},
+ {0xa728, {1|F|D, {0xa729}}},
+ {0xa72a, {1|F|D, {0xa72b}}},
+ {0xa72c, {1|F|D, {0xa72d}}},
+ {0xa72e, {1|F|D, {0xa72f}}},
+ {0xa732, {1|F|D, {0xa733}}},
+ {0xa734, {1|F|D, {0xa735}}},
+ {0xa736, {1|F|D, {0xa737}}},
+ {0xa738, {1|F|D, {0xa739}}},
+ {0xa73a, {1|F|D, {0xa73b}}},
+ {0xa73c, {1|F|D, {0xa73d}}},
+ {0xa73e, {1|F|D, {0xa73f}}},
+ {0xa740, {1|F|D, {0xa741}}},
+ {0xa742, {1|F|D, {0xa743}}},
+ {0xa744, {1|F|D, {0xa745}}},
+ {0xa746, {1|F|D, {0xa747}}},
+ {0xa748, {1|F|D, {0xa749}}},
+ {0xa74a, {1|F|D, {0xa74b}}},
+ {0xa74c, {1|F|D, {0xa74d}}},
+ {0xa74e, {1|F|D, {0xa74f}}},
+ {0xa750, {1|F|D, {0xa751}}},
+ {0xa752, {1|F|D, {0xa753}}},
+ {0xa754, {1|F|D, {0xa755}}},
+ {0xa756, {1|F|D, {0xa757}}},
+ {0xa758, {1|F|D, {0xa759}}},
+ {0xa75a, {1|F|D, {0xa75b}}},
+ {0xa75c, {1|F|D, {0xa75d}}},
+ {0xa75e, {1|F|D, {0xa75f}}},
+ {0xa760, {1|F|D, {0xa761}}},
+ {0xa762, {1|F|D, {0xa763}}},
+ {0xa764, {1|F|D, {0xa765}}},
+ {0xa766, {1|F|D, {0xa767}}},
+ {0xa768, {1|F|D, {0xa769}}},
+ {0xa76a, {1|F|D, {0xa76b}}},
+ {0xa76c, {1|F|D, {0xa76d}}},
+ {0xa76e, {1|F|D, {0xa76f}}},
+ {0xa779, {1|F|D, {0xa77a}}},
+ {0xa77b, {1|F|D, {0xa77c}}},
+ {0xa77d, {1|F|D, {0x1d79}}},
+ {0xa77e, {1|F|D, {0xa77f}}},
+ {0xa780, {1|F|D, {0xa781}}},
+ {0xa782, {1|F|D, {0xa783}}},
+ {0xa784, {1|F|D, {0xa785}}},
+ {0xa786, {1|F|D, {0xa787}}},
+ {0xa78b, {1|F|D, {0xa78c}}},
+ {0xa78d, {1|F|D, {0x0265}}},
+ {0xa790, {1|F|D, {0xa791}}},
+ {0xa792, {1|F|D, {0xa793}}},
+ {0xa796, {1|F|D, {0xa797}}},
+ {0xa798, {1|F|D, {0xa799}}},
+ {0xa79a, {1|F|D, {0xa79b}}},
+ {0xa79c, {1|F|D, {0xa79d}}},
+ {0xa79e, {1|F|D, {0xa79f}}},
+ {0xa7a0, {1|F|D, {0xa7a1}}},
+ {0xa7a2, {1|F|D, {0xa7a3}}},
+ {0xa7a4, {1|F|D, {0xa7a5}}},
+ {0xa7a6, {1|F|D, {0xa7a7}}},
+ {0xa7a8, {1|F|D, {0xa7a9}}},
+ {0xa7aa, {1|F|D, {0x0266}}},
+ {0xa7ab, {1|F|D, {0x025c}}},
+ {0xa7ac, {1|F|D, {0x0261}}},
+ {0xa7ad, {1|F|D, {0x026c}}},
+ {0xa7ae, {1|F|D, {0x026a}}},
+ {0xa7b0, {1|F|D, {0x029e}}},
+ {0xa7b1, {1|F|D, {0x0287}}},
+ {0xa7b2, {1|F|D, {0x029d}}},
+ {0xa7b3, {1|F|D, {0xab53}}},
+ {0xa7b4, {1|F|D, {0xa7b5}}},
+ {0xa7b6, {1|F|D, {0xa7b7}}},
+ {0xa7b8, {1|F|D, {0xa7b9}}},
+ {0xa7ba, {1|F|D, {0xa7bb}}},
+ {0xa7bc, {1|F|D, {0xa7bd}}},
+ {0xa7be, {1|F|D, {0xa7bf}}},
+ {0xa7c2, {1|F|D, {0xa7c3}}},
+ {0xa7c4, {1|F|D, {0xa794}}},
+ {0xa7c5, {1|F|D, {0x0282}}},
+ {0xa7c6, {1|F|D, {0x1d8e}}},
+ {0xab70, {1|F|U, {0x13a0}}},
+ {0xab71, {1|F|U, {0x13a1}}},
+ {0xab72, {1|F|U, {0x13a2}}},
+ {0xab73, {1|F|U, {0x13a3}}},
+ {0xab74, {1|F|U, {0x13a4}}},
+ {0xab75, {1|F|U, {0x13a5}}},
+ {0xab76, {1|F|U, {0x13a6}}},
+ {0xab77, {1|F|U, {0x13a7}}},
+ {0xab78, {1|F|U, {0x13a8}}},
+ {0xab79, {1|F|U, {0x13a9}}},
+ {0xab7a, {1|F|U, {0x13aa}}},
+ {0xab7b, {1|F|U, {0x13ab}}},
+ {0xab7c, {1|F|U, {0x13ac}}},
+ {0xab7d, {1|F|U, {0x13ad}}},
+ {0xab7e, {1|F|U, {0x13ae}}},
+ {0xab7f, {1|F|U, {0x13af}}},
+ {0xab80, {1|F|U, {0x13b0}}},
+ {0xab81, {1|F|U, {0x13b1}}},
+ {0xab82, {1|F|U, {0x13b2}}},
+ {0xab83, {1|F|U, {0x13b3}}},
+ {0xab84, {1|F|U, {0x13b4}}},
+ {0xab85, {1|F|U, {0x13b5}}},
+ {0xab86, {1|F|U, {0x13b6}}},
+ {0xab87, {1|F|U, {0x13b7}}},
+ {0xab88, {1|F|U, {0x13b8}}},
+ {0xab89, {1|F|U, {0x13b9}}},
+ {0xab8a, {1|F|U, {0x13ba}}},
+ {0xab8b, {1|F|U, {0x13bb}}},
+ {0xab8c, {1|F|U, {0x13bc}}},
+ {0xab8d, {1|F|U, {0x13bd}}},
+ {0xab8e, {1|F|U, {0x13be}}},
+ {0xab8f, {1|F|U, {0x13bf}}},
+ {0xab90, {1|F|U, {0x13c0}}},
+ {0xab91, {1|F|U, {0x13c1}}},
+ {0xab92, {1|F|U, {0x13c2}}},
+ {0xab93, {1|F|U, {0x13c3}}},
+ {0xab94, {1|F|U, {0x13c4}}},
+ {0xab95, {1|F|U, {0x13c5}}},
+ {0xab96, {1|F|U, {0x13c6}}},
+ {0xab97, {1|F|U, {0x13c7}}},
+ {0xab98, {1|F|U, {0x13c8}}},
+ {0xab99, {1|F|U, {0x13c9}}},
+ {0xab9a, {1|F|U, {0x13ca}}},
+ {0xab9b, {1|F|U, {0x13cb}}},
+ {0xab9c, {1|F|U, {0x13cc}}},
+ {0xab9d, {1|F|U, {0x13cd}}},
+ {0xab9e, {1|F|U, {0x13ce}}},
+ {0xab9f, {1|F|U, {0x13cf}}},
+ {0xaba0, {1|F|U, {0x13d0}}},
+ {0xaba1, {1|F|U, {0x13d1}}},
+ {0xaba2, {1|F|U, {0x13d2}}},
+ {0xaba3, {1|F|U, {0x13d3}}},
+ {0xaba4, {1|F|U, {0x13d4}}},
+ {0xaba5, {1|F|U, {0x13d5}}},
+ {0xaba6, {1|F|U, {0x13d6}}},
+ {0xaba7, {1|F|U, {0x13d7}}},
+ {0xaba8, {1|F|U, {0x13d8}}},
+ {0xaba9, {1|F|U, {0x13d9}}},
+ {0xabaa, {1|F|U, {0x13da}}},
+ {0xabab, {1|F|U, {0x13db}}},
+ {0xabac, {1|F|U, {0x13dc}}},
+ {0xabad, {1|F|U, {0x13dd}}},
+ {0xabae, {1|F|U, {0x13de}}},
+ {0xabaf, {1|F|U, {0x13df}}},
+ {0xabb0, {1|F|U, {0x13e0}}},
+ {0xabb1, {1|F|U, {0x13e1}}},
+ {0xabb2, {1|F|U, {0x13e2}}},
+ {0xabb3, {1|F|U, {0x13e3}}},
+ {0xabb4, {1|F|U, {0x13e4}}},
+ {0xabb5, {1|F|U, {0x13e5}}},
+ {0xabb6, {1|F|U, {0x13e6}}},
+ {0xabb7, {1|F|U, {0x13e7}}},
+ {0xabb8, {1|F|U, {0x13e8}}},
+ {0xabb9, {1|F|U, {0x13e9}}},
+ {0xabba, {1|F|U, {0x13ea}}},
+ {0xabbb, {1|F|U, {0x13eb}}},
+ {0xabbc, {1|F|U, {0x13ec}}},
+ {0xabbd, {1|F|U, {0x13ed}}},
+ {0xabbe, {1|F|U, {0x13ee}}},
+ {0xabbf, {1|F|U, {0x13ef}}},
+ {0xfb00, {2|F|ST|SU|I(366), {0x0066, 0x0066}}},
+ {0xfb01, {2|F|ST|SU|I(370), {0x0066, 0x0069}}},
+ {0xfb02, {2|F|ST|SU|I(374), {0x0066, 0x006c}}},
+ {0xfb03, {3|F|ST|SU|I(378), {0x0066, 0x0066, 0x0069}}},
+ {0xfb04, {3|F|ST|SU|I(384), {0x0066, 0x0066, 0x006c}}},
+ {0xfb05, {2|F|ST|SU|I(390), {0x0073, 0x0074}}},
+ {0xfb06, {2|F|ST|SU|I(394), {0x0073, 0x0074}}},
+ {0xfb13, {2|F|ST|SU|I(398), {0x0574, 0x0576}}},
+ {0xfb14, {2|F|ST|SU|I(402), {0x0574, 0x0565}}},
+ {0xfb15, {2|F|ST|SU|I(406), {0x0574, 0x056b}}},
+ {0xfb16, {2|F|ST|SU|I(410), {0x057e, 0x0576}}},
+ {0xfb17, {2|F|ST|SU|I(414), {0x0574, 0x056d}}},
+ {0xff21, {1|F|D, {0xff41}}},
+ {0xff22, {1|F|D, {0xff42}}},
+ {0xff23, {1|F|D, {0xff43}}},
+ {0xff24, {1|F|D, {0xff44}}},
+ {0xff25, {1|F|D, {0xff45}}},
+ {0xff26, {1|F|D, {0xff46}}},
+ {0xff27, {1|F|D, {0xff47}}},
+ {0xff28, {1|F|D, {0xff48}}},
+ {0xff29, {1|F|D, {0xff49}}},
+ {0xff2a, {1|F|D, {0xff4a}}},
+ {0xff2b, {1|F|D, {0xff4b}}},
+ {0xff2c, {1|F|D, {0xff4c}}},
+ {0xff2d, {1|F|D, {0xff4d}}},
+ {0xff2e, {1|F|D, {0xff4e}}},
+ {0xff2f, {1|F|D, {0xff4f}}},
+ {0xff30, {1|F|D, {0xff50}}},
+ {0xff31, {1|F|D, {0xff51}}},
+ {0xff32, {1|F|D, {0xff52}}},
+ {0xff33, {1|F|D, {0xff53}}},
+ {0xff34, {1|F|D, {0xff54}}},
+ {0xff35, {1|F|D, {0xff55}}},
+ {0xff36, {1|F|D, {0xff56}}},
+ {0xff37, {1|F|D, {0xff57}}},
+ {0xff38, {1|F|D, {0xff58}}},
+ {0xff39, {1|F|D, {0xff59}}},
+ {0xff3a, {1|F|D, {0xff5a}}},
+ {0x10400, {1|F|D, {0x10428}}},
+ {0x10401, {1|F|D, {0x10429}}},
+ {0x10402, {1|F|D, {0x1042a}}},
+ {0x10403, {1|F|D, {0x1042b}}},
+ {0x10404, {1|F|D, {0x1042c}}},
+ {0x10405, {1|F|D, {0x1042d}}},
+ {0x10406, {1|F|D, {0x1042e}}},
+ {0x10407, {1|F|D, {0x1042f}}},
+ {0x10408, {1|F|D, {0x10430}}},
+ {0x10409, {1|F|D, {0x10431}}},
+ {0x1040a, {1|F|D, {0x10432}}},
+ {0x1040b, {1|F|D, {0x10433}}},
+ {0x1040c, {1|F|D, {0x10434}}},
+ {0x1040d, {1|F|D, {0x10435}}},
+ {0x1040e, {1|F|D, {0x10436}}},
+ {0x1040f, {1|F|D, {0x10437}}},
+ {0x10410, {1|F|D, {0x10438}}},
+ {0x10411, {1|F|D, {0x10439}}},
+ {0x10412, {1|F|D, {0x1043a}}},
+ {0x10413, {1|F|D, {0x1043b}}},
+ {0x10414, {1|F|D, {0x1043c}}},
+ {0x10415, {1|F|D, {0x1043d}}},
+ {0x10416, {1|F|D, {0x1043e}}},
+ {0x10417, {1|F|D, {0x1043f}}},
+ {0x10418, {1|F|D, {0x10440}}},
+ {0x10419, {1|F|D, {0x10441}}},
+ {0x1041a, {1|F|D, {0x10442}}},
+ {0x1041b, {1|F|D, {0x10443}}},
+ {0x1041c, {1|F|D, {0x10444}}},
+ {0x1041d, {1|F|D, {0x10445}}},
+ {0x1041e, {1|F|D, {0x10446}}},
+ {0x1041f, {1|F|D, {0x10447}}},
+ {0x10420, {1|F|D, {0x10448}}},
+ {0x10421, {1|F|D, {0x10449}}},
+ {0x10422, {1|F|D, {0x1044a}}},
+ {0x10423, {1|F|D, {0x1044b}}},
+ {0x10424, {1|F|D, {0x1044c}}},
+ {0x10425, {1|F|D, {0x1044d}}},
+ {0x10426, {1|F|D, {0x1044e}}},
+ {0x10427, {1|F|D, {0x1044f}}},
+ {0x104b0, {1|F|D, {0x104d8}}},
+ {0x104b1, {1|F|D, {0x104d9}}},
+ {0x104b2, {1|F|D, {0x104da}}},
+ {0x104b3, {1|F|D, {0x104db}}},
+ {0x104b4, {1|F|D, {0x104dc}}},
+ {0x104b5, {1|F|D, {0x104dd}}},
+ {0x104b6, {1|F|D, {0x104de}}},
+ {0x104b7, {1|F|D, {0x104df}}},
+ {0x104b8, {1|F|D, {0x104e0}}},
+ {0x104b9, {1|F|D, {0x104e1}}},
+ {0x104ba, {1|F|D, {0x104e2}}},
+ {0x104bb, {1|F|D, {0x104e3}}},
+ {0x104bc, {1|F|D, {0x104e4}}},
+ {0x104bd, {1|F|D, {0x104e5}}},
+ {0x104be, {1|F|D, {0x104e6}}},
+ {0x104bf, {1|F|D, {0x104e7}}},
+ {0x104c0, {1|F|D, {0x104e8}}},
+ {0x104c1, {1|F|D, {0x104e9}}},
+ {0x104c2, {1|F|D, {0x104ea}}},
+ {0x104c3, {1|F|D, {0x104eb}}},
+ {0x104c4, {1|F|D, {0x104ec}}},
+ {0x104c5, {1|F|D, {0x104ed}}},
+ {0x104c6, {1|F|D, {0x104ee}}},
+ {0x104c7, {1|F|D, {0x104ef}}},
+ {0x104c8, {1|F|D, {0x104f0}}},
+ {0x104c9, {1|F|D, {0x104f1}}},
+ {0x104ca, {1|F|D, {0x104f2}}},
+ {0x104cb, {1|F|D, {0x104f3}}},
+ {0x104cc, {1|F|D, {0x104f4}}},
+ {0x104cd, {1|F|D, {0x104f5}}},
+ {0x104ce, {1|F|D, {0x104f6}}},
+ {0x104cf, {1|F|D, {0x104f7}}},
+ {0x104d0, {1|F|D, {0x104f8}}},
+ {0x104d1, {1|F|D, {0x104f9}}},
+ {0x104d2, {1|F|D, {0x104fa}}},
+ {0x104d3, {1|F|D, {0x104fb}}},
+ {0x10c80, {1|F|D, {0x10cc0}}},
+ {0x10c81, {1|F|D, {0x10cc1}}},
+ {0x10c82, {1|F|D, {0x10cc2}}},
+ {0x10c83, {1|F|D, {0x10cc3}}},
+ {0x10c84, {1|F|D, {0x10cc4}}},
+ {0x10c85, {1|F|D, {0x10cc5}}},
+ {0x10c86, {1|F|D, {0x10cc6}}},
+ {0x10c87, {1|F|D, {0x10cc7}}},
+ {0x10c88, {1|F|D, {0x10cc8}}},
+ {0x10c89, {1|F|D, {0x10cc9}}},
+ {0x10c8a, {1|F|D, {0x10cca}}},
+ {0x10c8b, {1|F|D, {0x10ccb}}},
+ {0x10c8c, {1|F|D, {0x10ccc}}},
+ {0x10c8d, {1|F|D, {0x10ccd}}},
+ {0x10c8e, {1|F|D, {0x10cce}}},
+ {0x10c8f, {1|F|D, {0x10ccf}}},
+ {0x10c90, {1|F|D, {0x10cd0}}},
+ {0x10c91, {1|F|D, {0x10cd1}}},
+ {0x10c92, {1|F|D, {0x10cd2}}},
+ {0x10c93, {1|F|D, {0x10cd3}}},
+ {0x10c94, {1|F|D, {0x10cd4}}},
+ {0x10c95, {1|F|D, {0x10cd5}}},
+ {0x10c96, {1|F|D, {0x10cd6}}},
+ {0x10c97, {1|F|D, {0x10cd7}}},
+ {0x10c98, {1|F|D, {0x10cd8}}},
+ {0x10c99, {1|F|D, {0x10cd9}}},
+ {0x10c9a, {1|F|D, {0x10cda}}},
+ {0x10c9b, {1|F|D, {0x10cdb}}},
+ {0x10c9c, {1|F|D, {0x10cdc}}},
+ {0x10c9d, {1|F|D, {0x10cdd}}},
+ {0x10c9e, {1|F|D, {0x10cde}}},
+ {0x10c9f, {1|F|D, {0x10cdf}}},
+ {0x10ca0, {1|F|D, {0x10ce0}}},
+ {0x10ca1, {1|F|D, {0x10ce1}}},
+ {0x10ca2, {1|F|D, {0x10ce2}}},
+ {0x10ca3, {1|F|D, {0x10ce3}}},
+ {0x10ca4, {1|F|D, {0x10ce4}}},
+ {0x10ca5, {1|F|D, {0x10ce5}}},
+ {0x10ca6, {1|F|D, {0x10ce6}}},
+ {0x10ca7, {1|F|D, {0x10ce7}}},
+ {0x10ca8, {1|F|D, {0x10ce8}}},
+ {0x10ca9, {1|F|D, {0x10ce9}}},
+ {0x10caa, {1|F|D, {0x10cea}}},
+ {0x10cab, {1|F|D, {0x10ceb}}},
+ {0x10cac, {1|F|D, {0x10cec}}},
+ {0x10cad, {1|F|D, {0x10ced}}},
+ {0x10cae, {1|F|D, {0x10cee}}},
+ {0x10caf, {1|F|D, {0x10cef}}},
+ {0x10cb0, {1|F|D, {0x10cf0}}},
+ {0x10cb1, {1|F|D, {0x10cf1}}},
+ {0x10cb2, {1|F|D, {0x10cf2}}},
+ {0x118a0, {1|F|D, {0x118c0}}},
+ {0x118a1, {1|F|D, {0x118c1}}},
+ {0x118a2, {1|F|D, {0x118c2}}},
+ {0x118a3, {1|F|D, {0x118c3}}},
+ {0x118a4, {1|F|D, {0x118c4}}},
+ {0x118a5, {1|F|D, {0x118c5}}},
+ {0x118a6, {1|F|D, {0x118c6}}},
+ {0x118a7, {1|F|D, {0x118c7}}},
+ {0x118a8, {1|F|D, {0x118c8}}},
+ {0x118a9, {1|F|D, {0x118c9}}},
+ {0x118aa, {1|F|D, {0x118ca}}},
+ {0x118ab, {1|F|D, {0x118cb}}},
+ {0x118ac, {1|F|D, {0x118cc}}},
+ {0x118ad, {1|F|D, {0x118cd}}},
+ {0x118ae, {1|F|D, {0x118ce}}},
+ {0x118af, {1|F|D, {0x118cf}}},
+ {0x118b0, {1|F|D, {0x118d0}}},
+ {0x118b1, {1|F|D, {0x118d1}}},
+ {0x118b2, {1|F|D, {0x118d2}}},
+ {0x118b3, {1|F|D, {0x118d3}}},
+ {0x118b4, {1|F|D, {0x118d4}}},
+ {0x118b5, {1|F|D, {0x118d5}}},
+ {0x118b6, {1|F|D, {0x118d6}}},
+ {0x118b7, {1|F|D, {0x118d7}}},
+ {0x118b8, {1|F|D, {0x118d8}}},
+ {0x118b9, {1|F|D, {0x118d9}}},
+ {0x118ba, {1|F|D, {0x118da}}},
+ {0x118bb, {1|F|D, {0x118db}}},
+ {0x118bc, {1|F|D, {0x118dc}}},
+ {0x118bd, {1|F|D, {0x118dd}}},
+ {0x118be, {1|F|D, {0x118de}}},
+ {0x118bf, {1|F|D, {0x118df}}},
+ {0x16e40, {1|F|D, {0x16e60}}},
+ {0x16e41, {1|F|D, {0x16e61}}},
+ {0x16e42, {1|F|D, {0x16e62}}},
+ {0x16e43, {1|F|D, {0x16e63}}},
+ {0x16e44, {1|F|D, {0x16e64}}},
+ {0x16e45, {1|F|D, {0x16e65}}},
+ {0x16e46, {1|F|D, {0x16e66}}},
+ {0x16e47, {1|F|D, {0x16e67}}},
+ {0x16e48, {1|F|D, {0x16e68}}},
+ {0x16e49, {1|F|D, {0x16e69}}},
+ {0x16e4a, {1|F|D, {0x16e6a}}},
+ {0x16e4b, {1|F|D, {0x16e6b}}},
+ {0x16e4c, {1|F|D, {0x16e6c}}},
+ {0x16e4d, {1|F|D, {0x16e6d}}},
+ {0x16e4e, {1|F|D, {0x16e6e}}},
+ {0x16e4f, {1|F|D, {0x16e6f}}},
+ {0x16e50, {1|F|D, {0x16e70}}},
+ {0x16e51, {1|F|D, {0x16e71}}},
+ {0x16e52, {1|F|D, {0x16e72}}},
+ {0x16e53, {1|F|D, {0x16e73}}},
+ {0x16e54, {1|F|D, {0x16e74}}},
+ {0x16e55, {1|F|D, {0x16e75}}},
+ {0x16e56, {1|F|D, {0x16e76}}},
+ {0x16e57, {1|F|D, {0x16e77}}},
+ {0x16e58, {1|F|D, {0x16e78}}},
+ {0x16e59, {1|F|D, {0x16e79}}},
+ {0x16e5a, {1|F|D, {0x16e7a}}},
+ {0x16e5b, {1|F|D, {0x16e7b}}},
+ {0x16e5c, {1|F|D, {0x16e7c}}},
+ {0x16e5d, {1|F|D, {0x16e7d}}},
+ {0x16e5e, {1|F|D, {0x16e7e}}},
+ {0x16e5f, {1|F|D, {0x16e7f}}},
+ {0x1e900, {1|F|D, {0x1e922}}},
+ {0x1e901, {1|F|D, {0x1e923}}},
+ {0x1e902, {1|F|D, {0x1e924}}},
+ {0x1e903, {1|F|D, {0x1e925}}},
+ {0x1e904, {1|F|D, {0x1e926}}},
+ {0x1e905, {1|F|D, {0x1e927}}},
+ {0x1e906, {1|F|D, {0x1e928}}},
+ {0x1e907, {1|F|D, {0x1e929}}},
+ {0x1e908, {1|F|D, {0x1e92a}}},
+ {0x1e909, {1|F|D, {0x1e92b}}},
+ {0x1e90a, {1|F|D, {0x1e92c}}},
+ {0x1e90b, {1|F|D, {0x1e92d}}},
+ {0x1e90c, {1|F|D, {0x1e92e}}},
+ {0x1e90d, {1|F|D, {0x1e92f}}},
+ {0x1e90e, {1|F|D, {0x1e930}}},
+ {0x1e90f, {1|F|D, {0x1e931}}},
+ {0x1e910, {1|F|D, {0x1e932}}},
+ {0x1e911, {1|F|D, {0x1e933}}},
+ {0x1e912, {1|F|D, {0x1e934}}},
+ {0x1e913, {1|F|D, {0x1e935}}},
+ {0x1e914, {1|F|D, {0x1e936}}},
+ {0x1e915, {1|F|D, {0x1e937}}},
+ {0x1e916, {1|F|D, {0x1e938}}},
+ {0x1e917, {1|F|D, {0x1e939}}},
+ {0x1e918, {1|F|D, {0x1e93a}}},
+ {0x1e919, {1|F|D, {0x1e93b}}},
+ {0x1e91a, {1|F|D, {0x1e93c}}},
+ {0x1e91b, {1|F|D, {0x1e93d}}},
+ {0x1e91c, {1|F|D, {0x1e93e}}},
+ {0x1e91d, {1|F|D, {0x1e93f}}},
+ {0x1e91e, {1|F|D, {0x1e940}}},
+ {0x1e91f, {1|F|D, {0x1e941}}},
+ {0x1e920, {1|F|D, {0x1e942}}},
+ {0x1e921, {1|F|D, {0x1e943}}},
+#define CaseFold_Locale (*(CaseFold_11_Type (*)[2])(CaseFold_11_Table+1485))
+ {0x0049, {1|F|D, {0x0069}}},
+ {0x0130, {2|F|D, {0x0069, 0x0307}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseFold_11_hash -N onigenc_unicode_CaseFold_11_lookup -n */
+
+/* maximum key range = 3500, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseFold_11_hash(const OnigCodePoint code)
+{
+ static const unsigned short asso_values[] =
+ {
+ 5, 273, 4, 8, 3, 1, 86, 9, 2, 289,
+ 290, 3, 3510, 3510, 3510, 3510, 3510, 3510, 3510, 3510,
+ 3510, 3510, 3510, 3510, 3510, 50, 3510, 3510, 3510, 3510,
+ 3510, 3510, 3510, 225, 3510, 3510, 3510, 3510, 3510, 28,
+ 3510, 3510, 3510, 3510, 3510, 3510, 3510, 3510, 3510, 394,
+ 3510, 3510, 3510, 3510, 3510, 3510, 3510, 47, 3510, 3510,
+ 255, 40, 286, 1, 3510, 3510, 599, 8, 3510, 3510,
+ 3510, 3510, 3510, 282, 3510, 3510, 267, 667, 473, 39,
+ 2019, 189, 47, 175, 2001, 107, 1626, 6, 12, 25,
+ 1961, 678, 1128, 526, 1945, 148, 1923, 371, 1720, 134,
+ 1857, 80, 1375, 66, 1705, 300, 1635, 445, 1611, 472,
+ 1795, 216, 1303, 499, 1552, 270, 1511, 243, 121, 619,
+ 1284, 540, 875, 592, 1484, 567, 412, 703, 1692, 387,
+ 1782, 781, 1767, 664, 1718, 648, 1316, 608, 1647, 715,
+ 1592, 771, 1544, 1029, 1563, 887, 1296, 861, 1194, 978,
+ 95, 899, 1257, 835, 1335, 765, 1529, 984, 862, 938,
+ 1460, 759, 329, 1079, 1159, 940, 234, 1101, 1204, 990,
+ 949, 1493, 92, 1438, 77, 1391, 7, 1073, 44, 1377,
+ 2, 1435, 4, 1321, 428, 1274, 332, 1206, 11, 1426,
+ 46, 478, 200, 1502, 31, 1400, 153, 1663, 352, 1820,
+ 229, 1733, 265, 1405, 315, 1879, 198
+ };
+ return asso_values[bits_of(code, 2)+79] + asso_values[bits_of(code, 1)] + asso_values[bits_of(code, 0)];
+}
+
+static const CodePointList3 *
+onigenc_unicode_CaseFold_11_lookup(const OnigCodePoint code)
+{
+ enum
+ {
+ MIN_CODE_VALUE = 0x41,
+ MAX_CODE_VALUE = 0x1e921,
+ TOTAL_KEYWORDS = 1487,
+ MIN_WORD_LENGTH = 3,
+ MAX_WORD_LENGTH = 3,
+ MIN_HASH_VALUE = 10,
+ MAX_HASH_VALUE = 3509
+ };
+
+ static const short wordlist[] =
+ {
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0x1fe7*/ 848,
+ /*0x10408*/ 1268,
+ /*0x1f88*/ 775,
+ /*0x0408*/ 305,
+ /*0x0208*/ 194,
+ /*0x0108*/ 61,
+ /*0xab88*/ 1166,
+ /*0x10409*/ 1269,
+ /*0x1f89*/ 776,
+ /*0x0409*/ 306,
+ /*0x0388*/ 235,
+ /*0x2c67*/ 962,
+ /*0xab89*/ 1167,
+ /*0x2c08*/ 919,
+ -1,
+ /*0x0189*/ 126,
+ /*0x0389*/ 236,
+ -1,
+ /*0x2c6d*/ 965,
+ /*0x2c09*/ 920,
+ /*0x1040a*/ 1270,
+ /*0x1f8a*/ 777,
+ /*0x040a*/ 307,
+ /*0x020a*/ 195,
+ /*0x010a*/ 62,
+ /*0xab8a*/ 1168,
+ /*0x2c88*/ 977,
+ /*0x1ff3*/ 855,
+ /*0x018a*/ 127,
+ /*0x038a*/ 237,
+ -1,
+ /*0x2ced*/ 1024,
+ /*0x2c0a*/ 921,
+ -1,
+ /*0x10400*/ 1260,
+ /*0x1f80*/ 767,
+ /*0x0400*/ 297,
+ /*0x0200*/ 190,
+ /*0x0100*/ 57,
+ /*0xab80*/ 1158,
+ /*0x1fe3*/ 845,
+ /*0x1e88*/ 653,
+ /*0x10403*/ 1263,
+ /*0x1f83*/ 770,
+ /*0x0403*/ 300,
+ /*0x2c8a*/ 978,
+ /*0x2c00*/ 911,
+ /*0xab83*/ 1161,
+ /*0x1c88*/ 538,
+ /*0x10c88*/ 1344,
+ /*0x2183*/ 884,
+ /*0x2c63*/ 960,
+ /*0x1e908*/ 1459,
+ /*0x2c6f*/ 967,
+ /*0x2c03*/ 914,
+ /*0x10c89*/ 1345,
+ -1, -1,
+ /*0x1e909*/ 1460,
+ /*0x2c80*/ 973,
+ /*0x1e8a*/ 654,
+ /*0x10418*/ 1284,
+ /*0x1f98*/ 791,
+ /*0x0418*/ 321,
+ /*0x0218*/ 202,
+ /*0x0118*/ 69,
+ /*0xab98*/ 1182,
+ -1,
+ /*0x10c8a*/ 1346,
+ /*0x0198*/ 137,
+ /*0x0398*/ 249,
+ /*0x1e90a*/ 1461,
+ /*0xa780*/ 1105,
+ /*0x2c18*/ 935,
+ /*0x1e80*/ 649,
+ /*0x10416*/ 1282,
+ /*0x1f96*/ 789,
+ /*0x0416*/ 319,
+ /*0x0216*/ 201,
+ /*0x0116*/ 68,
+ /*0xab96*/ 1180,
+ /*0x1c80*/ 530,
+ /*0x10c80*/ 1336,
+ /*0x0196*/ 135,
+ /*0x0396*/ 247,
+ /*0x1e900*/ 1451,
+ /*0x2c98*/ 985,
+ /*0x2c16*/ 933,
+ -1,
+ /*0x1c83*/ 533,
+ /*0x10c83*/ 1339,
+ /*0x1fc7*/ 830,
+ -1,
+ /*0x1e903*/ 1454,
+ /*0x0147*/ 91,
+ /*0x0047*/ 6,
+ -1, -1,
+ /*0x01c7*/ 159,
+ /*0xa798*/ 1114,
+ /*0x2c96*/ 984,
+ /*0x1e98*/ 662,
+ /*0x10406*/ 1266,
+ /*0x1f86*/ 773,
+ /*0x0406*/ 303,
+ /*0x0206*/ 193,
+ /*0x0106*/ 60,
+ /*0xab86*/ 1164,
+ /*0x1c98*/ 547,
+ /*0x10c98*/ 1360,
+ /*0x0186*/ 124,
+ /*0x0386*/ 234,
+ /*0x1e918*/ 1475,
+ /*0xa796*/ 1113,
+ /*0x2c06*/ 917,
+ /*0x1e96*/ 660,
+ /*0x10427*/ 1299,
+ /*0x1fa7*/ 806,
+ /*0x0427*/ 336,
+ -1, -1,
+ /*0xaba7*/ 1197,
+ /*0x1c96*/ 545,
+ /*0x10c96*/ 1358,
+ /*0x01a7*/ 145,
+ /*0x03a7*/ 263,
+ /*0x1e916*/ 1473,
+ /*0x2c86*/ 976,
+ /*0x2c27*/ 950,
+ /*0x10414*/ 1280,
+ /*0x1f94*/ 787,
+ /*0x0414*/ 317,
+ /*0x0214*/ 200,
+ /*0x0114*/ 67,
+ /*0xab94*/ 1178,
+ -1, -1,
+ /*0x0194*/ 134,
+ /*0x0394*/ 245,
+ -1,
+ /*0xa786*/ 1108,
+ /*0x2c14*/ 931,
+ /*0x1e86*/ 652,
+ /*0x10410*/ 1276,
+ /*0x1f90*/ 783,
+ /*0x0410*/ 313,
+ /*0x0210*/ 198,
+ /*0x0110*/ 65,
+ /*0xab90*/ 1174,
+ /*0x1c86*/ 536,
+ /*0x10c86*/ 1342,
+ /*0x0190*/ 131,
+ /*0x0390*/ 241,
+ /*0x1e906*/ 1457,
+ /*0x2c94*/ 983,
+ /*0x2c10*/ 927,
+ -1,
+ /*0x03f5*/ 290,
+ /*0xfb00*/ 1222,
+ -1,
+ /*0x2c75*/ 970,
+ -1, -1,
+ /*0x1ca7*/ 562,
+ /*0x10ca7*/ 1375,
+ -1,
+ /*0xfb03*/ 1225,
+ -1,
+ /*0x2c90*/ 981,
+ /*0x1e94*/ 659,
+ /*0x10404*/ 1264,
+ /*0x1f84*/ 771,
+ /*0x0404*/ 301,
+ /*0x0204*/ 192,
+ /*0x0104*/ 59,
+ /*0xab84*/ 1162,
+ /*0x1c94*/ 543,
+ /*0x10c94*/ 1356,
+ /*0x0184*/ 123,
+ -1,
+ /*0x1e914*/ 1471,
+ /*0xa790*/ 1111,
+ /*0x2c04*/ 915,
+ /*0x1e90*/ 657,
+ /*0x10402*/ 1262,
+ /*0x1f82*/ 769,
+ /*0x0402*/ 299,
+ /*0x0202*/ 191,
+ /*0x0102*/ 58,
+ /*0xab82*/ 1160,
+ /*0x1c90*/ 539,
+ /*0x10c90*/ 1352,
+ /*0x0182*/ 122,
+ -1,
+ /*0x1e910*/ 1467,
+ /*0x2c84*/ 975,
+ /*0x2c02*/ 913,
+ /*0x017f*/ 120,
+ -1,
+ /*0xfb16*/ 1232,
+ -1, -1,
+ /*0x03ff*/ 296,
+ /*0x01f1*/ 181,
+ /*0x03f1*/ 288,
+ /*0x2c7f*/ 972,
+ -1, -1,
+ /*0xa784*/ 1107,
+ /*0x2c82*/ 974,
+ /*0x1e84*/ 651,
+ /*0x10420*/ 1292,
+ /*0x1fa0*/ 799,
+ /*0x0420*/ 329,
+ /*0x0220*/ 206,
+ /*0x0120*/ 73,
+ /*0xaba0*/ 1190,
+ /*0x1c84*/ 534,
+ /*0x10c84*/ 1340,
+ /*0x01a0*/ 141,
+ /*0x03a0*/ 257,
+ /*0x1e904*/ 1455,
+ /*0xa782*/ 1106,
+ /*0x2c20*/ 943,
+ /*0x1e82*/ 650,
+ /*0x1ff9*/ 860,
+ /*0xfb06*/ 1228,
+ -1,
+ /*0x0179*/ 117,
+ -1,
+ /*0x1fd7*/ 839,
+ /*0x1c82*/ 532,
+ /*0x10c82*/ 1338,
+ /*0x03f9*/ 292,
+ /*0x0057*/ 21,
+ /*0x1e902*/ 1453,
+ /*0x2ca0*/ 989,
+ /*0x01d7*/ 168,
+ /*0x10426*/ 1298,
+ /*0x1fa6*/ 805,
+ /*0x0426*/ 335,
+ /*0x0226*/ 209,
+ /*0x0126*/ 76,
+ /*0xaba6*/ 1196,
+ -1, -1,
+ /*0x01a6*/ 144,
+ /*0x03a6*/ 262,
+ -1,
+ /*0xa7a0*/ 1118,
+ /*0x2c26*/ 949,
+ /*0x1ea0*/ 667,
+ /*0x13f9*/ 525,
+ /*0xfb14*/ 1230,
+ -1, -1,
+ /*0x1e08*/ 589,
+ -1,
+ /*0x1ca0*/ 555,
+ /*0x10ca0*/ 1368,
+ -1,
+ /*0x1ffb*/ 862,
+ /*0x1e920*/ 1483,
+ /*0x2ca6*/ 992,
+ /*0x017b*/ 118,
+ /*0x10424*/ 1296,
+ /*0x1fa4*/ 803,
+ /*0x0424*/ 333,
+ /*0x0224*/ 208,
+ /*0x0124*/ 75,
+ /*0xaba4*/ 1194,
+ -1, -1,
+ /*0x01a4*/ 143,
+ /*0x03a4*/ 260,
+ /*0x1e0a*/ 590,
+ /*0xa7a6*/ 1121,
+ /*0x2c24*/ 947,
+ /*0x1ea6*/ 670,
+ /*0x037f*/ 233,
+ -1, -1, -1, -1, -1,
+ /*0x1ca6*/ 561,
+ /*0x10ca6*/ 1374,
+ /*0x1f08*/ 715,
+ /*0x13fb*/ 527,
+ /*0x1e00*/ 585,
+ /*0x2ca4*/ 991,
+ /*0x0508*/ 425,
+ /*0x1f6d*/ 764,
+ /*0x1f09*/ 716,
+ /*0xfb04*/ 1226,
+ /*0x1041a*/ 1286,
+ /*0x1f9a*/ 793,
+ /*0x041a*/ 323,
+ /*0x021a*/ 203,
+ /*0x011a*/ 70,
+ /*0xab9a*/ 1184,
+ -1, -1,
+ /*0xa7a4*/ 1120,
+ /*0x039a*/ 251,
+ /*0x1ea4*/ 669,
+ /*0x1f0a*/ 717,
+ /*0x2c1a*/ 937,
+ /*0xfb02*/ 1224,
+ /*0x048a*/ 362,
+ /*0x050a*/ 426,
+ -1,
+ /*0x1ca4*/ 559,
+ /*0x10ca4*/ 1372,
+ /*0x017d*/ 119,
+ /*0x10c7*/ 522,
+ /*0x1e18*/ 597,
+ -1, -1,
+ /*0x03fd*/ 294,
+ /*0x2c9a*/ 986,
+ -1, -1,
+ /*0x0480*/ 361,
+ /*0x0500*/ 421,
+ /*0x1fd3*/ 837,
+ -1,
+ /*0x1f6f*/ 766,
+ /*0x1feb*/ 852,
+ /*0x0053*/ 17,
+ /*0x1e16*/ 596,
+ -1,
+ /*0x01d3*/ 166,
+ /*0xa79a*/ 1115,
+ -1,
+ /*0x1e9a*/ 664,
+ -1, -1,
+ /*0x13fd*/ 529,
+ /*0x2c6b*/ 964,
+ -1,
+ /*0x10a7*/ 491,
+ /*0x1c9a*/ 549,
+ /*0x10c9a*/ 1362,
+ -1,
+ /*0x00df*/ 56,
+ /*0x1e91a*/ 1477,
+ /*0x1f18*/ 723,
+ /*0x1ff7*/ 858,
+ -1,
+ /*0x0498*/ 369,
+ /*0x0518*/ 433,
+ /*0x2ceb*/ 1023,
+ -1, -1,
+ /*0x01f7*/ 185,
+ /*0x03f7*/ 291,
+ /*0x1e06*/ 588,
+ /*0x1f5f*/ 758,
+ -1,
+ /*0x00dd*/ 54,
+ -1, -1,
+ /*0x00c7*/ 33,
+ /*0x0496*/ 368,
+ /*0x0516*/ 432,
+ /*0x10412*/ 1278,
+ /*0x1f92*/ 785,
+ /*0x0412*/ 315,
+ /*0x0212*/ 199,
+ /*0x0112*/ 66,
+ /*0xab92*/ 1176,
+ /*0x24c7*/ 902,
+ /*0x1f5d*/ 757,
+ -1,
+ /*0x0392*/ 243,
+ -1,
+ /*0x104c7*/ 1323,
+ /*0x2c12*/ 929,
+ /*0x04c7*/ 393,
+ /*0x0547*/ 467,
+ -1, -1,
+ /*0x1fb2*/ 815,
+ /*0x1e14*/ 595,
+ /*0x0232*/ 215,
+ /*0x0132*/ 81,
+ /*0xabb2*/ 1208,
+ -1, -1,
+ /*0x01b2*/ 151,
+ /*0x2c92*/ 982,
+ /*0x0506*/ 424,
+ -1, -1, -1, -1, -1,
+ /*0x1e10*/ 593,
+ -1, -1, -1, -1, -1,
+ /*0xa792*/ 1112,
+ -1,
+ /*0x1e92*/ 658,
+ /*0x2cb2*/ 998,
+ /*0x1faf*/ 814,
+ /*0x042f*/ 344,
+ -1, -1,
+ /*0xabaf*/ 1205,
+ /*0x1c92*/ 541,
+ /*0x10c92*/ 1354,
+ /*0x01af*/ 149,
+ -1,
+ /*0x1e912*/ 1469,
+ /*0x0494*/ 367,
+ /*0x0514*/ 431,
+ /*0xa7b2*/ 1130,
+ -1,
+ /*0x1eb2*/ 676,
+ -1,
+ /*0x1fe9*/ 850,
+ /*0x1e04*/ 587,
+ -1, -1, -1,
+ /*0x1cb2*/ 573,
+ /*0x10cb2*/ 1386,
+ -1,
+ /*0x0490*/ 365,
+ /*0x0510*/ 429,
+ -1,
+ /*0x2c69*/ 963,
+ /*0x10a0*/ 484,
+ -1, -1,
+ /*0x1e02*/ 586,
+ /*0x1041c*/ 1288,
+ /*0x1f9c*/ 795,
+ /*0x041c*/ 325,
+ /*0x021c*/ 204,
+ /*0x011c*/ 71,
+ /*0xab9c*/ 1186,
+ -1, -1,
+ /*0x019c*/ 138,
+ /*0x039c*/ 253,
+ -1, -1,
+ /*0x2c1c*/ 939,
+ -1,
+ /*0x1caf*/ 570,
+ /*0x10caf*/ 1383,
+ -1, -1, -1, -1,
+ /*0x0504*/ 423,
+ -1, -1,
+ /*0x10a6*/ 490,
+ -1,
+ /*0x2c9c*/ 987,
+ /*0x1e20*/ 601,
+ /*0x1041e*/ 1290,
+ /*0x1f9e*/ 797,
+ /*0x041e*/ 327,
+ /*0x021e*/ 205,
+ /*0x011e*/ 72,
+ /*0xab9e*/ 1188,
+ -1,
+ /*0x0502*/ 422,
+ /*0x0470*/ 353,
+ /*0x039e*/ 255,
+ /*0x0170*/ 112,
+ /*0xa79c*/ 1116,
+ /*0x2c1e*/ 941,
+ -1,
+ /*0x01f0*/ 180,
+ /*0x03f0*/ 287,
+ -1, -1,
+ /*0x2c70*/ 968,
+ -1,
+ /*0x1c9c*/ 551,
+ /*0x10c9c*/ 1364,
+ -1,
+ /*0x10a4*/ 488,
+ /*0x1e91c*/ 1479,
+ /*0x2c9e*/ 988,
+ /*0x1e26*/ 604,
+ /*0x10422*/ 1294,
+ /*0x1fa2*/ 801,
+ /*0x0422*/ 331,
+ /*0x0222*/ 207,
+ /*0x0122*/ 74,
+ /*0xaba2*/ 1192,
+ /*0x04a0*/ 373,
+ /*0x0520*/ 437,
+ /*0x01a2*/ 142,
+ -1, -1,
+ /*0xa79e*/ 1117,
+ /*0x2c22*/ 945,
+ /*0x1e9e*/ 666,
+ /*0x118a7*/ 1394,
+ -1, -1, -1, -1,
+ /*0x1ef0*/ 707,
+ /*0x1c9e*/ 553,
+ /*0x10c9e*/ 1366,
+ -1, -1,
+ /*0x1e91e*/ 1481,
+ /*0x2ca2*/ 990,
+ /*0x1e24*/ 603,
+ /*0x1040e*/ 1274,
+ /*0x1f8e*/ 781,
+ /*0x040e*/ 311,
+ /*0x020e*/ 197,
+ /*0x010e*/ 64,
+ /*0xab8e*/ 1172,
+ /*0x04a6*/ 376,
+ /*0x0526*/ 440,
+ /*0x018e*/ 129,
+ /*0x038e*/ 239,
+ /*0xff27*/ 1240,
+ /*0xa7a2*/ 1119,
+ /*0x2c0e*/ 925,
+ /*0x1ea2*/ 668,
+ -1,
+ /*0x1faa*/ 809,
+ /*0x042a*/ 339,
+ /*0x022a*/ 211,
+ /*0x012a*/ 78,
+ /*0xabaa*/ 1200,
+ /*0x1ca2*/ 557,
+ /*0x10ca2*/ 1370,
+ -1,
+ /*0x03aa*/ 266,
+ -1,
+ /*0x2c8e*/ 980,
+ /*0x2c2a*/ 953,
+ -1, -1,
+ /*0x1e1a*/ 598,
+ -1, -1, -1,
+ /*0x04a4*/ 375,
+ /*0x0524*/ 439,
+ -1, -1, -1,
+ /*0x0370*/ 230,
+ /*0x2caa*/ 994,
+ /*0x1e8e*/ 656,
+ -1,
+ /*0x1fae*/ 813,
+ /*0x042e*/ 343,
+ /*0x022e*/ 213,
+ /*0x012e*/ 80,
+ /*0xabae*/ 1204,
+ -1,
+ /*0x10c8e*/ 1350,
+ /*0x01ae*/ 148,
+ -1,
+ /*0x1e90e*/ 1465,
+ /*0xa7aa*/ 1123,
+ /*0x2c2e*/ 957,
+ /*0x1eaa*/ 672,
+ -1, -1, -1, -1, -1,
+ /*0x1f1a*/ 725,
+ /*0x1caa*/ 565,
+ /*0x10caa*/ 1378,
+ /*0x049a*/ 370,
+ /*0x051a*/ 434,
+ -1,
+ /*0x2cae*/ 996,
+ /*0x1fac*/ 811,
+ /*0x042c*/ 341,
+ /*0x022c*/ 212,
+ /*0x012c*/ 79,
+ /*0xabac*/ 1202,
+ -1, -1,
+ /*0x01ac*/ 147,
+ /*0x2165*/ 873,
+ /*0x00d3*/ 45,
+ /*0x2167*/ 875,
+ /*0x2c2c*/ 955,
+ /*0xa7ae*/ 1127,
+ /*0x2161*/ 869,
+ /*0x1eae*/ 674,
+ /*0x118a0*/ 1387,
+ /*0x1fba*/ 822,
+ /*0x216d*/ 881,
+ /*0x023a*/ 216,
+ /*0x10b2*/ 502,
+ /*0xabba*/ 1216,
+ /*0x1cae*/ 569,
+ /*0x10cae*/ 1382,
+ /*0x104d3*/ 1335,
+ /*0x2cac*/ 995,
+ /*0x1f6b*/ 762,
+ /*0x0553*/ 479,
+ /*0x1fa8*/ 807,
+ /*0x0428*/ 337,
+ /*0x0228*/ 210,
+ /*0x0128*/ 77,
+ /*0xaba8*/ 1198,
+ -1,
+ /*0x1e12*/ 594,
+ -1,
+ /*0x03a8*/ 264,
+ -1,
+ /*0xa7ac*/ 1125,
+ /*0x2c28*/ 951,
+ /*0x1eac*/ 673,
+ /*0x2cba*/ 1002,
+ -1,
+ /*0x118a6*/ 1393,
+ -1,
+ /*0x10af*/ 499,
+ -1,
+ /*0x1cac*/ 567,
+ /*0x10cac*/ 1380,
+ -1,
+ /*0x1e32*/ 610,
+ /*0x2163*/ 871,
+ /*0x2ca8*/ 993,
+ /*0x216f*/ 883,
+ /*0xa7ba*/ 1135,
+ -1,
+ /*0x1eba*/ 680,
+ /*0x1fb8*/ 820,
+ -1, -1, -1,
+ /*0xabb8*/ 1214,
+ -1,
+ /*0x1cba*/ 581,
+ /*0x01b8*/ 155,
+ /*0xa7a8*/ 1122,
+ /*0xff26*/ 1239,
+ /*0x1ea8*/ 671,
+ /*0x0492*/ 366,
+ /*0x0512*/ 430,
+ /*0x118a4*/ 1391,
+ -1, -1,
+ /*0x1fb6*/ 818,
+ /*0x1ca8*/ 563,
+ /*0x10ca8*/ 1376,
+ /*0x0136*/ 83,
+ /*0xabb6*/ 1212,
+ -1, -1,
+ /*0xa688*/ 1053,
+ /*0x2cb8*/ 1001,
+ /*0x104b2*/ 1302,
+ -1,
+ /*0x04b2*/ 382,
+ /*0x0532*/ 446,
+ /*0x1040c*/ 1272,
+ /*0x1f8c*/ 779,
+ /*0x040c*/ 309,
+ /*0x020c*/ 196,
+ /*0x010c*/ 63,
+ /*0xab8c*/ 1170,
+ -1,
+ /*0xff24*/ 1237,
+ /*0xa7b8*/ 1134,
+ /*0x038c*/ 238,
+ /*0x1eb8*/ 679,
+ /*0x2cb6*/ 1000,
+ /*0x2c0c*/ 923,
+ /*0xa68a*/ 1054,
+ -1, -1, -1,
+ /*0x1cb8*/ 579,
+ -1, -1,
+ /*0x1f2f*/ 736,
+ -1,
+ /*0x1e1c*/ 599,
+ /*0xa779*/ 1101,
+ /*0xa7b6*/ 1133,
+ /*0x2c8c*/ 979,
+ /*0x1eb6*/ 678,
+ /*0xa680*/ 1049,
+ /*0x0230*/ 214,
+ /*0x0130*/ 1486,
+ /*0xabb0*/ 1206,
+ -1, -1,
+ /*0x1cb6*/ 577,
+ /*0x03b0*/ 268,
+ -1,
+ /*0x1f69*/ 760,
+ /*0xa726*/ 1065,
+ /*0x1fbc*/ 824,
+ -1,
+ /*0x1e8c*/ 655,
+ -1,
+ /*0xabbc*/ 1218,
+ -1, -1,
+ /*0x01bc*/ 156,
+ /*0x10a2*/ 486,
+ -1,
+ /*0x10c8c*/ 1348,
+ /*0x1e1e*/ 600,
+ /*0x2cb0*/ 997,
+ /*0x1e90c*/ 1463,
+ -1,
+ /*0x1f1c*/ 727,
+ /*0xa698*/ 1061,
+ /*0x1e70*/ 641,
+ /*0x049c*/ 371,
+ /*0x051c*/ 435,
+ -1,
+ /*0xa77b*/ 1102,
+ -1, -1,
+ /*0x2cbc*/ 1003,
+ /*0xa7b0*/ 1128,
+ /*0xa724*/ 1064,
+ /*0x1eb0*/ 675,
+ -1, -1,
+ /*0xa696*/ 1060,
+ -1, -1, -1,
+ /*0x1cb0*/ 571,
+ /*0x10cb0*/ 1384,
+ -1,
+ /*0xa7bc*/ 1136,
+ /*0x1e22*/ 602,
+ /*0x1ebc*/ 681,
+ -1, -1, -1, -1,
+ /*0x1fd2*/ 836,
+ /*0x049e*/ 372,
+ /*0x051e*/ 436,
+ /*0x0152*/ 97,
+ /*0x0052*/ 16,
+ /*0x10aa*/ 494,
+ /*0x1fcc*/ 835,
+ /*0x04f0*/ 413,
+ /*0x024c*/ 227,
+ /*0x014c*/ 94,
+ /*0x004c*/ 10,
+ -1,
+ /*0x1fbe*/ 825,
+ /*0xa686*/ 1052,
+ /*0x023e*/ 219,
+ -1,
+ /*0xabbe*/ 1220,
+ -1, -1,
+ /*0x118b2*/ 1405,
+ -1,
+ /*0x1e0e*/ 592,
+ /*0x1fb4*/ 817,
+ -1,
+ /*0x2cd2*/ 1014,
+ /*0x0134*/ 82,
+ /*0xabb4*/ 1210,
+ /*0xa77d*/ 1103,
+ /*0x04a2*/ 374,
+ /*0x0522*/ 438,
+ /*0x2ccc*/ 1011,
+ -1,
+ /*0x10ae*/ 498,
+ -1, -1,
+ /*0x1e2a*/ 606,
+ /*0x2cbe*/ 1004,
+ -1, -1,
+ /*0x1ed2*/ 692,
+ /*0xa694*/ 1059,
+ -1,
+ /*0xff32*/ 1251,
+ -1,
+ /*0x118af*/ 1402,
+ /*0x1ecc*/ 689,
+ /*0x2cb4*/ 999,
+ -1, -1,
+ /*0xa7be*/ 1137,
+ -1,
+ /*0x1ebe*/ 682,
+ /*0x1f0e*/ 721,
+ -1,
+ /*0xa690*/ 1057,
+ /*0x048e*/ 364,
+ /*0x050e*/ 428,
+ /*0x10ac*/ 496,
+ /*0x1cbe*/ 583,
+ /*0xa7b4*/ 1132,
+ -1,
+ /*0x1eb4*/ 677,
+ /*0x1e2e*/ 608,
+ -1, -1, -1,
+ /*0x1f2a*/ 731,
+ /*0xff2f*/ 1248,
+ /*0x1cb4*/ 575,
+ /*0x04aa*/ 378,
+ /*0x052a*/ 442,
+ -1, -1,
+ /*0x10ba*/ 510,
+ -1, -1,
+ /*0x1fca*/ 833,
+ -1,
+ /*0x024a*/ 226,
+ /*0x014a*/ 93,
+ /*0x004a*/ 8,
+ /*0xa684*/ 1051,
+ /*0x2126*/ 864,
+ /*0x01ca*/ 161,
+ /*0x10a8*/ 492,
+ -1, -1,
+ /*0x1e2c*/ 607,
+ -1, -1, -1, -1, -1,
+ /*0x1f2e*/ 735,
+ -1,
+ /*0xa682*/ 1050,
+ /*0x04ae*/ 380,
+ /*0x052e*/ 444,
+ -1,
+ /*0xa732*/ 1070,
+ /*0x2cca*/ 1010,
+ -1,
+ /*0x1fc4*/ 828,
+ /*0x1e3a*/ 614,
+ /*0x0244*/ 222,
+ -1,
+ /*0x0044*/ 3,
+ /*0x004f*/ 13,
+ -1,
+ /*0x01c4*/ 157,
+ /*0x01cf*/ 164,
+ /*0x03cf*/ 270,
+ -1,
+ /*0x10b8*/ 508,
+ /*0x1e28*/ 605,
+ /*0x1eca*/ 688,
+ /*0x1fab*/ 810,
+ /*0x042b*/ 340,
+ /*0x1f2c*/ 733,
+ -1,
+ /*0xabab*/ 1201,
+ /*0x04ac*/ 379,
+ /*0x052c*/ 443,
+ -1,
+ /*0x03ab*/ 267,
+ -1,
+ /*0x2cc4*/ 1007,
+ /*0x2c2b*/ 954,
+ /*0x1fc2*/ 826,
+ /*0x10b6*/ 506,
+ /*0x24ba*/ 889,
+ /*0x118a2*/ 1389,
+ /*0x0042*/ 1,
+ -1,
+ /*0x1f3a*/ 739,
+ /*0x104ba*/ 1310,
+ /*0x03c2*/ 269,
+ /*0x04ba*/ 386,
+ /*0x053a*/ 454,
+ /*0xa7c4*/ 1139,
+ /*0x1fc8*/ 831,
+ /*0x1ec4*/ 685,
+ /*0x0248*/ 225,
+ /*0x1e38*/ 613,
+ /*0x0048*/ 7,
+ /*0x1f28*/ 729,
+ -1,
+ /*0x01c8*/ 160,
+ /*0x04a8*/ 377,
+ /*0x0528*/ 441,
+ -1, -1,
+ /*0x2cc2*/ 1006,
+ /*0xa7ab*/ 1124,
+ /*0xff22*/ 1235,
+ -1, -1, -1, -1,
+ /*0x1e36*/ 612,
+ -1, -1,
+ /*0x1cab*/ 566,
+ /*0x10cab*/ 1379,
+ /*0x2cc8*/ 1009,
+ /*0xa7c2*/ 1138,
+ -1,
+ /*0x1ec2*/ 684,
+ /*0x10b0*/ 500,
+ -1,
+ /*0x24b8*/ 887,
+ /*0x216b*/ 879,
+ /*0x118aa*/ 1397,
+ /*0x1e0c*/ 591,
+ /*0x1f38*/ 737,
+ /*0x104b8*/ 1308,
+ -1,
+ /*0x04b8*/ 385,
+ /*0x0538*/ 452,
+ /*0x1ec8*/ 687,
+ /*0x10bc*/ 512,
+ /*0x1fd6*/ 838,
+ /*0x0150*/ 96,
+ /*0x0050*/ 14,
+ /*0x0156*/ 99,
+ /*0x0056*/ 20,
+ /*0x24b6*/ 885,
+ /*0x03d0*/ 271,
+ -1,
+ /*0x03d6*/ 274,
+ /*0x1fdb*/ 843,
+ /*0x104b6*/ 1306,
+ -1,
+ /*0x04b6*/ 384,
+ /*0x0536*/ 450,
+ /*0xff2a*/ 1243,
+ -1,
+ /*0x01db*/ 170,
+ /*0x1e30*/ 609,
+ /*0x118ae*/ 1401,
+ -1, -1, -1,
+ /*0x2cd0*/ 1013,
+ /*0x1f0c*/ 719,
+ /*0x2cd6*/ 1016,
+ /*0xa69a*/ 1062,
+ /*0x048c*/ 363,
+ /*0x050c*/ 427,
+ -1,
+ /*0x1e3c*/ 615,
+ /*0xa722*/ 1063,
+ -1, -1, -1, -1, -1, -1,
+ /*0x1ed0*/ 691,
+ /*0x1fc6*/ 829,
+ /*0x1ed6*/ 694,
+ /*0x0246*/ 224,
+ /*0xff2e*/ 1247,
+ /*0x0046*/ 5,
+ /*0x118ac*/ 1399,
+ -1,
+ /*0x2132*/ 867,
+ /*0x024e*/ 228,
+ /*0x014e*/ 95,
+ /*0x004e*/ 12,
+ /*0x104b0*/ 1300,
+ /*0x1fda*/ 842,
+ /*0x04b0*/ 381,
+ -1,
+ /*0x015a*/ 101,
+ /*0x005a*/ 24,
+ /*0x10be*/ 514,
+ /*0x24bc*/ 891,
+ -1,
+ /*0x03da*/ 276,
+ /*0x118ba*/ 1413,
+ /*0x1f3c*/ 741,
+ /*0x104bc*/ 1312,
+ /*0x2cc6*/ 1008,
+ /*0x04bc*/ 387,
+ /*0x053c*/ 456,
+ /*0x10b4*/ 504,
+ /*0xff2c*/ 1245,
+ -1,
+ /*0x2cce*/ 1012,
+ -1,
+ /*0x118a8*/ 1395,
+ /*0xa72a*/ 1067,
+ -1,
+ /*0x1e52*/ 626,
+ /*0x2cda*/ 1018,
+ /*0xa7c6*/ 1141,
+ -1,
+ /*0x1ec6*/ 686,
+ -1,
+ /*0x1e4c*/ 623,
+ -1, -1,
+ /*0xff3a*/ 1259,
+ /*0x1ece*/ 690,
+ /*0xa652*/ 1035,
+ /*0x1e3e*/ 616,
+ /*0x2169*/ 877,
+ -1, -1,
+ /*0x1eda*/ 696,
+ /*0xa64c*/ 1032,
+ /*0x00d2*/ 44,
+ -1,
+ /*0xff28*/ 1241,
+ -1,
+ /*0x1e34*/ 611,
+ /*0xa692*/ 1058,
+ /*0x00cc*/ 38,
+ /*0xa72e*/ 1069,
+ /*0x118b8*/ 1411,
+ -1, -1, -1, -1,
+ /*0x1f52*/ 752,
+ /*0x104d2*/ 1334,
+ /*0x24cc*/ 907,
+ /*0x04d2*/ 398,
+ /*0x0552*/ 478,
+ -1,
+ /*0x1f4c*/ 749,
+ /*0x104cc*/ 1328,
+ /*0x24be*/ 893,
+ /*0x2cc0*/ 1005,
+ /*0x054c*/ 472,
+ /*0x118b6*/ 1409,
+ /*0x1f3e*/ 743,
+ /*0x104be*/ 1314,
+ -1,
+ /*0x04be*/ 388,
+ /*0x053e*/ 458,
+ -1,
+ /*0xff38*/ 1257,
+ /*0xa72c*/ 1068,
+ -1, -1, -1,
+ /*0x104b4*/ 1304,
+ /*0x1ec0*/ 683,
+ /*0x04b4*/ 383,
+ /*0x0534*/ 448,
+ -1, -1,
+ /*0x1fe2*/ 844,
+ /*0x0462*/ 346,
+ -1,
+ /*0x0162*/ 105,
+ -1,
+ /*0xff36*/ 1255,
+ /*0xa73a*/ 1074,
+ /*0x01e2*/ 173,
+ /*0x03e2*/ 280,
+ /*0x0154*/ 98,
+ /*0x0054*/ 18,
+ /*0x2c62*/ 959,
+ /*0x10c4*/ 520,
+ -1, -1, -1,
+ /*0x1e4a*/ 622,
+ /*0xa728*/ 1066,
+ -1, -1, -1,
+ /*0x118b0*/ 1403,
+ -1, -1,
+ /*0x2ce2*/ 1022,
+ -1,
+ /*0x10ab*/ 495,
+ /*0xa64a*/ 1031,
+ /*0x1fd8*/ 840,
+ -1,
+ /*0x2cd4*/ 1015,
+ /*0x0158*/ 100,
+ /*0x0058*/ 22,
+ /*0x118bc*/ 1415,
+ /*0x00ca*/ 36,
+ -1,
+ /*0x03d8*/ 275,
+ -1,
+ /*0x10c2*/ 518,
+ /*0x1ee2*/ 700,
+ -1, -1,
+ /*0x1e44*/ 619,
+ /*0x24ca*/ 905,
+ /*0xff30*/ 1249,
+ /*0x1ed4*/ 693,
+ /*0xa738*/ 1073,
+ /*0x1f4a*/ 747,
+ /*0x104ca*/ 1326,
+ -1, -1,
+ /*0x054a*/ 470,
+ /*0x2cd8*/ 1017,
+ /*0xa644*/ 1028,
+ /*0x1040d*/ 1273,
+ /*0x1f8d*/ 780,
+ /*0x040d*/ 310,
+ -1, -1,
+ /*0xab8d*/ 1171,
+ /*0x00c4*/ 30,
+ /*0x00cf*/ 41,
+ /*0xa736*/ 1072,
+ -1, -1,
+ /*0x212a*/ 865,
+ /*0x2c0d*/ 924,
+ /*0x1ed8*/ 695,
+ /*0x1e42*/ 618,
+ /*0x24c4*/ 899,
+ /*0x24cf*/ 910,
+ -1, -1, -1,
+ /*0x104c4*/ 1320,
+ /*0x104cf*/ 1331,
+ -1,
+ /*0x0544*/ 464,
+ /*0x054f*/ 475,
+ /*0xa642*/ 1027,
+ /*0x1e48*/ 621,
+ -1, -1, -1, -1, -1,
+ /*0x00c2*/ 28,
+ /*0x1f2b*/ 732,
+ -1,
+ /*0x118be*/ 1417,
+ /*0x0055*/ 19,
+ /*0xa648*/ 1030,
+ /*0xa78d*/ 1110,
+ /*0x01d5*/ 167,
+ /*0x03d5*/ 273,
+ /*0x24c2*/ 897,
+ -1, -1,
+ /*0x00c8*/ 34,
+ /*0x118b4*/ 1407,
+ /*0x104c2*/ 1318,
+ -1,
+ /*0x10c8d*/ 1349,
+ /*0x0542*/ 462,
+ -1,
+ /*0x1e90d*/ 1464,
+ -1,
+ /*0x24c8*/ 903,
+ -1, -1, -1,
+ /*0x1f48*/ 745,
+ /*0x104c8*/ 1324,
+ /*0xa73c*/ 1075,
+ -1,
+ /*0x0548*/ 468,
+ -1, -1,
+ /*0xa68e*/ 1056,
+ /*0x1e50*/ 625,
+ -1,
+ /*0x1e56*/ 628,
+ /*0xff34*/ 1253,
+ /*0x0245*/ 223,
+ /*0x0145*/ 90,
+ /*0x0045*/ 4,
+ -1,
+ /*0x16e5f*/ 1450,
+ /*0x01c5*/ 158,
+ -1,
+ /*0xa650*/ 1034,
+ /*0x1fd9*/ 841,
+ /*0xa656*/ 1037,
+ /*0x1fec*/ 853,
+ /*0x046c*/ 351,
+ /*0x0059*/ 23,
+ /*0x016c*/ 110,
+ /*0x00d0*/ 42,
+ /*0x01d9*/ 169,
+ /*0x00d6*/ 48,
+ /*0x01ec*/ 178,
+ /*0x03ec*/ 285,
+ /*0x16e5d*/ 1448,
+ -1, -1,
+ /*0x16e47*/ 1426,
+ -1, -1,
+ /*0x00db*/ 52,
+ -1,
+ /*0x1f50*/ 751,
+ /*0x104d0*/ 1332,
+ /*0x1f56*/ 754,
+ /*0x04d0*/ 397,
+ /*0x0550*/ 476,
+ /*0x04d6*/ 400,
+ /*0x0556*/ 482,
+ /*0xa752*/ 1086,
+ /*0xa7c5*/ 1140,
+ /*0x1e46*/ 620,
+ -1,
+ /*0x1f5b*/ 756,
+ -1,
+ /*0xa74c*/ 1083,
+ -1,
+ /*0x1e4e*/ 624,
+ -1, -1, -1,
+ /*0xa73e*/ 1076,
+ /*0xa646*/ 1029,
+ /*0x1e5a*/ 630,
+ /*0x1eec*/ 705,
+ -1, -1, -1,
+ /*0xa64e*/ 1033,
+ /*0x00c6*/ 32,
+ -1,
+ /*0xa734*/ 1071,
+ /*0x10c0*/ 516,
+ -1,
+ /*0xa65a*/ 1039,
+ /*0x00ce*/ 40,
+ /*0x1fc9*/ 832,
+ -1,
+ /*0x24c6*/ 901,
+ /*0x0149*/ 92,
+ /*0x0049*/ 1485,
+ /*0x00da*/ 51,
+ -1,
+ /*0x104c6*/ 1322,
+ /*0x24ce*/ 909,
+ /*0x118ab*/ 1398,
+ /*0x0546*/ 466,
+ -1, -1,
+ /*0x104ce*/ 1330,
+ -1, -1,
+ /*0x054e*/ 474,
+ /*0x1fea*/ 851,
+ /*0x046a*/ 350,
+ -1,
+ /*0x016a*/ 109,
+ /*0x04da*/ 402,
+ /*0x0345*/ 229,
+ -1,
+ /*0x01ea*/ 177,
+ /*0x03ea*/ 284,
+ /*0x1e40*/ 617,
+ /*0x1fa9*/ 808,
+ /*0x0429*/ 338,
+ -1, -1,
+ /*0xaba9*/ 1199,
+ /*0xff2b*/ 1244,
+ -1,
+ /*0x01a9*/ 146,
+ /*0x03a9*/ 265,
+ -1,
+ /*0xa640*/ 1026,
+ /*0x2c29*/ 952,
+ /*0x1fc3*/ 827,
+ -1,
+ /*0x0243*/ 221,
+ /*0x0143*/ 89,
+ /*0x0043*/ 2,
+ /*0x00c0*/ 26,
+ /*0x10421*/ 1293,
+ /*0x1fa1*/ 800,
+ /*0x0421*/ 330,
+ -1,
+ /*0xa74a*/ 1082,
+ /*0xaba1*/ 1191,
+ -1, -1,
+ /*0x24c0*/ 895,
+ /*0x03a1*/ 258,
+ -1,
+ /*0x1eea*/ 704,
+ /*0x2c21*/ 944,
+ /*0x104c0*/ 1316,
+ /*0x1fb9*/ 821,
+ /*0x04c0*/ 389,
+ /*0x0540*/ 460,
+ /*0x0139*/ 84,
+ /*0xabb9*/ 1215,
+ /*0x1fe8*/ 849,
+ /*0x0468*/ 349,
+ -1,
+ /*0x0168*/ 108,
+ -1, -1,
+ /*0x1e62*/ 634,
+ /*0x01e8*/ 176,
+ /*0x03e8*/ 283,
+ /*0x1ca9*/ 564,
+ /*0x10ca9*/ 1377,
+ /*0xa744*/ 1079,
+ /*0x1e54*/ 627,
+ -1,
+ /*0x1fcb*/ 834,
+ -1, -1,
+ /*0xa662*/ 1043,
+ /*0x004b*/ 9,
+ -1, -1,
+ /*0x01cb*/ 162,
+ /*0xa68c*/ 1055,
+ /*0xa654*/ 1036,
+ -1, -1, -1, -1,
+ /*0x1ca1*/ 556,
+ /*0x10ca1*/ 1369,
+ /*0x00d4*/ 46,
+ -1,
+ /*0x1e921*/ 1484,
+ -1,
+ /*0x1e58*/ 629,
+ -1,
+ /*0x16e57*/ 1442,
+ /*0xa742*/ 1078,
+ -1,
+ /*0x1ee8*/ 703,
+ /*0x04e2*/ 406,
+ /*0x1cb9*/ 580,
+ -1,
+ /*0x1f54*/ 753,
+ -1,
+ /*0xa658*/ 1038,
+ /*0x04d4*/ 399,
+ /*0x0554*/ 480,
+ -1,
+ /*0xa748*/ 1081,
+ -1, -1,
+ /*0x00d8*/ 49,
+ /*0x10417*/ 1283,
+ /*0x1f97*/ 790,
+ /*0x0417*/ 320,
+ /*0x1fe4*/ 846,
+ /*0x0464*/ 347,
+ /*0xab97*/ 1181,
+ /*0x0164*/ 106,
+ -1,
+ /*0x0197*/ 136,
+ /*0x0397*/ 248,
+ /*0x01e4*/ 174,
+ /*0x03e4*/ 281,
+ /*0x2c17*/ 934,
+ -1,
+ /*0x2c64*/ 961,
+ /*0x04d8*/ 401,
+ -1, -1,
+ /*0x0460*/ 345,
+ -1,
+ /*0x0160*/ 104,
+ -1, -1, -1,
+ /*0x01e0*/ 172,
+ /*0x03e0*/ 279,
+ /*0x1ff4*/ 856,
+ /*0x0474*/ 355,
+ /*0x2c60*/ 958,
+ /*0x0174*/ 114,
+ -1,
+ /*0x1ffc*/ 863,
+ /*0x047c*/ 359,
+ /*0x01f4*/ 183,
+ /*0x03f4*/ 289,
+ /*0xa750*/ 1085,
+ -1,
+ /*0xa756*/ 1088,
+ /*0x01fc*/ 188,
+ /*0x1f0d*/ 720,
+ /*0x1e97*/ 661,
+ /*0x2ce0*/ 1021,
+ /*0x1ee4*/ 701,
+ -1,
+ /*0x10c5*/ 521,
+ -1, -1,
+ /*0x1c97*/ 546,
+ /*0x10c97*/ 1359,
+ -1, -1,
+ /*0x1e917*/ 1474,
+ -1,
+ /*0x046e*/ 352,
+ -1,
+ /*0x016e*/ 111,
+ /*0x1ee0*/ 699,
+ /*0x00d5*/ 47,
+ /*0x13fc*/ 528,
+ /*0x01ee*/ 179,
+ /*0x03ee*/ 286,
+ /*0x1fe6*/ 847,
+ /*0x0466*/ 348,
+ /*0x2c6e*/ 966,
+ /*0x0166*/ 107,
+ /*0x1ef4*/ 709,
+ -1,
+ /*0x015e*/ 103,
+ /*0x01e6*/ 175,
+ /*0x03e6*/ 282,
+ /*0x1efc*/ 713,
+ /*0x01de*/ 171,
+ /*0x03de*/ 278,
+ -1,
+ /*0x0555*/ 481,
+ /*0xa746*/ 1080,
+ -1, -1,
+ /*0x16e53*/ 1438,
+ -1, -1,
+ /*0xa74e*/ 1084,
+ -1, -1, -1, -1,
+ /*0x1e6c*/ 639,
+ /*0xa75a*/ 1090,
+ /*0x2cde*/ 1020,
+ -1,
+ /*0x0051*/ 15,
+ /*0x1eee*/ 706,
+ /*0x00c5*/ 31,
+ /*0x01d1*/ 165,
+ /*0x03d1*/ 272,
+ -1, -1,
+ /*0xa66c*/ 1048,
+ -1,
+ /*0x212b*/ 866,
+ /*0x1ee6*/ 702,
+ /*0x24c5*/ 900,
+ /*0x00d9*/ 50,
+ /*0x1ede*/ 698,
+ -1, -1,
+ /*0x104c5*/ 1321,
+ -1,
+ /*0x04c5*/ 392,
+ /*0x0545*/ 465,
+ /*0x1fad*/ 812,
+ /*0x042d*/ 342,
+ -1, -1,
+ /*0xabad*/ 1203,
+ /*0x1f59*/ 755,
+ -1,
+ /*0x1f6c*/ 763,
+ -1, -1,
+ /*0x04ec*/ 411,
+ /*0x2c2d*/ 956,
+ /*0x015c*/ 102,
+ -1,
+ /*0xfb17*/ 1233,
+ -1,
+ /*0xa740*/ 1077,
+ /*0x03dc*/ 277,
+ /*0x1ff2*/ 854,
+ /*0x0472*/ 354,
+ -1,
+ /*0x0172*/ 113,
+ -1, -1,
+ /*0x10a9*/ 493,
+ /*0x01f2*/ 182,
+ /*0x10425*/ 1297,
+ /*0x1fa5*/ 804,
+ /*0x0425*/ 334,
+ /*0x2c72*/ 969,
+ -1,
+ /*0xaba5*/ 1195,
+ -1,
+ /*0x2cdc*/ 1019,
+ -1,
+ /*0x03a5*/ 261,
+ /*0x10c3*/ 519,
+ /*0xa7ad*/ 1126,
+ /*0x2c25*/ 948,
+ -1, -1, -1,
+ /*0x2cf2*/ 1025,
+ /*0x10a1*/ 485,
+ /*0x1e6a*/ 638,
+ /*0x00c9*/ 35,
+ /*0x1cad*/ 568,
+ /*0x10cad*/ 1381,
+ /*0x1edc*/ 697,
+ /*0x004d*/ 11,
+ -1, -1,
+ /*0x01cd*/ 163,
+ -1,
+ /*0x24c9*/ 904,
+ /*0xa66a*/ 1047,
+ /*0x10b9*/ 509,
+ /*0x1ef2*/ 708,
+ /*0x1f49*/ 746,
+ /*0x104c9*/ 1325,
+ /*0xa762*/ 1094,
+ /*0x04c9*/ 394,
+ /*0x0549*/ 469,
+ /*0x013f*/ 87,
+ /*0xabbf*/ 1221,
+ -1,
+ /*0xa754*/ 1087,
+ /*0x10423*/ 1295,
+ /*0x1fa3*/ 802,
+ /*0x0423*/ 332,
+ -1, -1,
+ /*0xaba3*/ 1193,
+ /*0x1ca5*/ 560,
+ /*0x10ca5*/ 1373,
+ /*0x1f6a*/ 761,
+ /*0x03a3*/ 259,
+ -1,
+ /*0x04ea*/ 410,
+ /*0x2c23*/ 946,
+ -1,
+ /*0x0241*/ 220,
+ /*0x0141*/ 88,
+ /*0x0041*/ 0,
+ /*0x00c3*/ 29,
+ /*0x1f29*/ 730,
+ -1, -1,
+ /*0xa758*/ 1089,
+ -1, -1,
+ /*0x1e68*/ 637,
+ -1,
+ /*0x24c3*/ 898,
+ -1, -1, -1, -1,
+ /*0x104c3*/ 1319,
+ -1,
+ /*0x04c3*/ 391,
+ /*0x0543*/ 463,
+ /*0xa668*/ 1046,
+ /*0x0372*/ 231,
+ -1, -1,
+ /*0x1cbf*/ 584,
+ -1, -1, -1,
+ /*0x023d*/ 218,
+ /*0x013d*/ 86,
+ /*0xabbd*/ 1219,
+ /*0x24b9*/ 888,
+ /*0x1ca3*/ 558,
+ /*0x10ca3*/ 1371,
+ -1,
+ /*0x1f39*/ 738,
+ /*0x104b9*/ 1309,
+ -1, -1,
+ /*0x0539*/ 453,
+ /*0x1f68*/ 759,
+ /*0x00cb*/ 37,
+ -1,
+ /*0x04e8*/ 409,
+ /*0x1041d*/ 1289,
+ /*0x1f9d*/ 796,
+ /*0x041d*/ 326,
+ -1, -1,
+ /*0xab9d*/ 1187,
+ /*0x24cb*/ 906,
+ -1,
+ /*0x019d*/ 139,
+ /*0x039d*/ 254,
+ /*0x1f4b*/ 748,
+ /*0x104cb*/ 1327,
+ /*0x2c1d*/ 940,
+ /*0x04cb*/ 395,
+ /*0x054b*/ 471,
+ /*0x10407*/ 1267,
+ /*0x1f87*/ 774,
+ /*0x0407*/ 304,
+ /*0x0587*/ 483,
+ -1,
+ /*0xab87*/ 1165,
+ /*0x1e64*/ 635,
+ -1,
+ /*0x0187*/ 125,
+ /*0x1041b*/ 1287,
+ /*0x1f9b*/ 794,
+ /*0x041b*/ 324,
+ /*0x2c07*/ 918,
+ /*0x1cbd*/ 582,
+ /*0xab9b*/ 1185,
+ -1, -1,
+ /*0xa664*/ 1044,
+ /*0x039b*/ 252,
+ -1,
+ /*0x1e60*/ 633,
+ /*0x2c1b*/ 938,
+ /*0x1fbb*/ 823,
+ -1,
+ /*0x023b*/ 217,
+ /*0x013b*/ 85,
+ /*0xabbb*/ 1217,
+ -1, -1,
+ /*0x1e74*/ 643,
+ /*0xab73*/ 1145,
+ /*0xa660*/ 1042,
+ /*0x1c9d*/ 552,
+ /*0x10c9d*/ 1365,
+ /*0x1e7c*/ 647,
+ -1,
+ /*0x1e91d*/ 1480,
+ -1,
+ /*0x1ff6*/ 857,
+ /*0x0476*/ 356,
+ /*0x04e4*/ 407,
+ /*0x0176*/ 115,
+ -1, -1, -1,
+ /*0x01f6*/ 184,
+ /*0x2162*/ 870,
+ /*0x1c87*/ 537,
+ /*0x10c87*/ 1343,
+ /*0x1e9b*/ 665,
+ /*0x118a9*/ 1396,
+ /*0x1e907*/ 1458,
+ /*0xa76c*/ 1099,
+ -1,
+ /*0x04e0*/ 405,
+ /*0x1e6e*/ 640,
+ /*0x1c9b*/ 550,
+ /*0x10c9b*/ 1363,
+ -1, -1,
+ /*0x1e91b*/ 1478,
+ -1, -1,
+ /*0x04f4*/ 415,
+ /*0x1e66*/ 636,
+ -1, -1,
+ /*0x1e5e*/ 632,
+ /*0x04fc*/ 419,
+ /*0x118a1*/ 1388,
+ -1,
+ /*0xabb1*/ 1207,
+ -1,
+ /*0xff29*/ 1242,
+ /*0x01b1*/ 150,
+ /*0xa666*/ 1045,
+ -1,
+ /*0x1ef6*/ 710,
+ /*0xa65e*/ 1041,
+ /*0x10419*/ 1285,
+ /*0x1f99*/ 792,
+ /*0x0419*/ 322,
+ /*0x118b9*/ 1412,
+ /*0x10ad*/ 497,
+ /*0xab99*/ 1183,
+ /*0x00de*/ 55,
+ /*0x1f6e*/ 765,
+ -1,
+ /*0x0399*/ 250,
+ /*0x04ee*/ 412,
+ -1,
+ /*0x2c19*/ 936,
+ /*0xff21*/ 1234,
+ /*0x1fb7*/ 819,
+ /*0x10413*/ 1279,
+ /*0x1f93*/ 786,
+ /*0x0413*/ 316,
+ /*0xabb7*/ 1213,
+ /*0x04e6*/ 408,
+ /*0xab93*/ 1177,
+ /*0x01b7*/ 154,
+ /*0x04de*/ 404,
+ /*0x0193*/ 133,
+ /*0x0393*/ 244,
+ /*0xa7b1*/ 1129,
+ /*0xff39*/ 1258,
+ /*0x2c13*/ 930,
+ /*0x00d1*/ 43,
+ /*0x1ffa*/ 861,
+ /*0x047a*/ 358,
+ /*0x10a5*/ 489,
+ -1, -1,
+ /*0x1cb1*/ 572,
+ /*0x10cb1*/ 1385,
+ /*0x01fa*/ 187,
+ /*0x03fa*/ 293,
+ -1, -1,
+ /*0x1e99*/ 663,
+ /*0xa76a*/ 1098,
+ /*0x104d1*/ 1333,
+ /*0x1e5c*/ 631,
+ /*0x0376*/ 232,
+ /*0x0551*/ 477,
+ -1,
+ /*0x1c99*/ 548,
+ /*0x10c99*/ 1361,
+ /*0x10cd*/ 523,
+ -1,
+ /*0x1e919*/ 1476,
+ /*0x1e72*/ 642,
+ -1,
+ /*0xa65c*/ 1040,
+ -1,
+ /*0x13fa*/ 526,
+ -1, -1, -1,
+ /*0x1cb7*/ 578,
+ /*0x00dc*/ 53,
+ /*0x1c93*/ 542,
+ /*0x10c93*/ 1355,
+ /*0x10bf*/ 515,
+ /*0x1f2d*/ 734,
+ /*0x1e913*/ 1470,
+ /*0xabb5*/ 1211,
+ /*0x1efa*/ 712,
+ -1,
+ /*0x01b5*/ 153,
+ -1,
+ /*0x10a3*/ 487,
+ /*0xab75*/ 1147,
+ -1, -1, -1,
+ /*0x04dc*/ 403,
+ /*0x1fb3*/ 816,
+ -1, -1, -1,
+ /*0xabb3*/ 1209,
+ /*0x10c1*/ 517,
+ -1,
+ /*0x01b3*/ 152,
+ /*0x04f2*/ 414,
+ -1,
+ /*0xa768*/ 1097,
+ -1,
+ /*0x1041f*/ 1291,
+ /*0x1f9f*/ 798,
+ /*0x041f*/ 328,
+ -1, -1,
+ /*0xab9f*/ 1189,
+ -1,
+ /*0x00cd*/ 39,
+ /*0x019f*/ 140,
+ /*0x039f*/ 256,
+ /*0x216c*/ 880,
+ -1,
+ /*0x2c1f*/ 942,
+ -1, -1, -1,
+ /*0x24cd*/ 908,
+ -1, -1,
+ /*0x1cb5*/ 576,
+ /*0x1f4d*/ 750,
+ /*0x104cd*/ 1329,
+ /*0x10bd*/ 513,
+ /*0x04cd*/ 396,
+ /*0x054d*/ 473,
+ /*0xa7b3*/ 1131,
+ /*0x1ff8*/ 859,
+ /*0x0478*/ 357,
+ /*0xab7f*/ 1157,
+ /*0x0178*/ 116,
+ /*0xab71*/ 1143,
+ /*0x24bf*/ 894,
+ -1,
+ /*0x01f8*/ 186,
+ /*0x1cb3*/ 574,
+ /*0x1f3f*/ 744,
+ /*0x104bf*/ 1315,
+ -1, -1,
+ /*0x053f*/ 459,
+ -1,
+ /*0x00c1*/ 27,
+ -1, -1, -1, -1, -1,
+ /*0x1c9f*/ 554,
+ /*0x10c9f*/ 1367,
+ /*0xfb13*/ 1229,
+ /*0x24c1*/ 896,
+ /*0x1e91f*/ 1482,
+ -1,
+ /*0x13f8*/ 524,
+ /*0xa764*/ 1095,
+ /*0x104c1*/ 1317,
+ -1,
+ /*0x04c1*/ 390,
+ /*0x0541*/ 461,
+ /*0xab79*/ 1151,
+ -1, -1,
+ /*0x10415*/ 1281,
+ /*0x1f95*/ 788,
+ /*0x0415*/ 318,
+ /*0x1ef8*/ 711,
+ -1,
+ /*0xab95*/ 1179,
+ /*0xa760*/ 1093,
+ -1, -1,
+ /*0x0395*/ 246,
+ -1, -1,
+ /*0x2c15*/ 932,
+ -1, -1,
+ /*0x10bb*/ 511,
+ /*0x216a*/ 878,
+ /*0x24bd*/ 892,
+ -1,
+ /*0x118ad*/ 1400,
+ -1,
+ /*0x1f3d*/ 742,
+ /*0x104bd*/ 1313,
+ -1,
+ /*0x047e*/ 360,
+ /*0x053d*/ 457,
+ /*0x16e52*/ 1437,
+ -1, -1, -1,
+ /*0x01fe*/ 189,
+ /*0x03fe*/ 295,
+ /*0x16e4c*/ 1431,
+ /*0xab7b*/ 1153,
+ /*0x2c7e*/ 971,
+ -1, -1, -1, -1, -1,
+ /*0x1f1d*/ 728,
+ /*0xa76e*/ 1100,
+ /*0xff2d*/ 1246,
+ -1, -1, -1,
+ /*0x118a5*/ 1392,
+ /*0x1c95*/ 544,
+ /*0x10c95*/ 1357,
+ -1,
+ /*0xa766*/ 1096,
+ /*0x1e915*/ 1472,
+ -1,
+ /*0xa75e*/ 1092,
+ -1, -1, -1, -1, -1, -1,
+ /*0x10b1*/ 501,
+ /*0x1e76*/ 644,
+ /*0x1efe*/ 714,
+ /*0x2168*/ 876,
+ /*0x1f1b*/ 726,
+ -1,
+ /*0x10411*/ 1277,
+ /*0x1f91*/ 784,
+ /*0x0411*/ 314,
+ /*0xff25*/ 1238,
+ -1,
+ /*0xab91*/ 1175,
+ /*0x24bb*/ 890,
+ -1,
+ /*0x0191*/ 132,
+ /*0x0391*/ 242,
+ /*0x1f3b*/ 740,
+ /*0x104bb*/ 1311,
+ /*0x2c11*/ 928,
+ /*0x118bf*/ 1418,
+ /*0x053b*/ 455,
+ -1, -1,
+ /*0xab7d*/ 1155,
+ -1, -1,
+ /*0x10b7*/ 507,
+ /*0x118a3*/ 1390,
+ /*0x1040f*/ 1275,
+ /*0x1f8f*/ 782,
+ /*0x040f*/ 312,
+ -1, -1,
+ /*0xab8f*/ 1173,
+ -1,
+ /*0x04f6*/ 416,
+ /*0x018f*/ 130,
+ /*0x038f*/ 240,
+ -1, -1,
+ /*0x2c0f*/ 926,
+ -1,
+ /*0x16e4a*/ 1429,
+ -1,
+ /*0x1040b*/ 1271,
+ /*0x1f8b*/ 778,
+ /*0x040b*/ 308,
+ -1,
+ /*0xa75c*/ 1091,
+ /*0xab8b*/ 1169,
+ /*0xff23*/ 1236,
+ -1,
+ /*0x018b*/ 128,
+ /*0x1c91*/ 540,
+ /*0x10c91*/ 1353,
+ -1,
+ /*0x2c0b*/ 922,
+ /*0x1e911*/ 1468,
+ -1,
+ /*0x2164*/ 872,
+ /*0xab77*/ 1149,
+ -1,
+ /*0x104b1*/ 1301,
+ -1,
+ /*0xfb15*/ 1231,
+ /*0x0531*/ 445,
+ -1,
+ /*0x118bd*/ 1416,
+ /*0x16e44*/ 1423,
+ /*0x16e4f*/ 1434,
+ -1,
+ /*0x1e7a*/ 646,
+ -1,
+ /*0x2160*/ 868,
+ /*0x1f19*/ 724,
+ /*0x10b5*/ 505,
+ /*0x10c8f*/ 1351,
+ -1, -1,
+ /*0x1e90f*/ 1466,
+ -1, -1,
+ /*0xa78b*/ 1109,
+ /*0x24b7*/ 886,
+ /*0x10405*/ 1265,
+ /*0x1f85*/ 772,
+ /*0x0405*/ 302,
+ -1,
+ /*0x104b7*/ 1307,
+ /*0xab85*/ 1163,
+ /*0x10b3*/ 503,
+ /*0x0537*/ 451,
+ /*0x10c8b*/ 1347,
+ -1,
+ /*0x16e42*/ 1421,
+ /*0x1e90b*/ 1462,
+ /*0x2c05*/ 916,
+ -1, -1, -1, -1, -1,
+ /*0x10401*/ 1261,
+ /*0x1f81*/ 768,
+ /*0x0401*/ 298,
+ /*0x04fa*/ 418,
+ /*0x16e48*/ 1427,
+ /*0xab81*/ 1159,
+ /*0x216e*/ 882,
+ -1,
+ /*0x0181*/ 121,
+ -1, -1, -1,
+ /*0x2c01*/ 912,
+ -1, -1,
+ /*0x2166*/ 874,
+ -1, -1, -1, -1,
+ /*0x118bb*/ 1414,
+ /*0x00b5*/ 25,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x1c85*/ 535,
+ /*0x10c85*/ 1341,
+ -1, -1,
+ /*0x1e905*/ 1456,
+ -1,
+ /*0x104b5*/ 1305,
+ -1, -1,
+ /*0x0535*/ 449,
+ -1, -1, -1, -1,
+ /*0x16e50*/ 1435,
+ -1,
+ /*0x16e56*/ 1441,
+ -1,
+ /*0x1c81*/ 531,
+ /*0x10c81*/ 1337,
+ -1,
+ /*0x104b3*/ 1303,
+ /*0x1e901*/ 1452,
+ -1,
+ /*0x0533*/ 447,
+ /*0x16e5b*/ 1446,
+ -1,
+ /*0x1e78*/ 645,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x118b1*/ 1404,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ /*0x16e46*/ 1425,
+ /*0xab70*/ 1142,
+ -1, -1, -1,
+ /*0xff31*/ 1250,
+ /*0x16e4e*/ 1433,
+ /*0x04f8*/ 417,
+ /*0x118b7*/ 1410,
+ -1, -1, -1,
+ /*0x16e5a*/ 1445,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0xfb05*/ 1227,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0xff37*/ 1256,
+ /*0x1e7e*/ 648,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0xfb01*/ 1223,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0x16e40*/ 1419,
+ -1, -1, -1, -1, -1,
+ /*0x118b5*/ 1408,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x04fe*/ 420,
+ -1, -1, -1, -1, -1,
+ /*0x118b3*/ 1406,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0xff35*/ 1254,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0xff33*/ 1252,
+ -1, -1, -1, -1, -1,
+ /*0x16e54*/ 1439,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0x16e58*/ 1443,
+ -1, -1, -1, -1, -1,
+ /*0x1f0f*/ 722,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0x1f0b*/ 718,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ /*0x16e55*/ 1440,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0x16e45*/ 1424,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0x16e59*/ 1444,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0xa77e*/ 1104,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ /*0x16e49*/ 1428,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x16e43*/ 1422,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x16e4b*/ 1430,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ /*0x16e5e*/ 1449,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0x16e51*/ 1436,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x16e5c*/ 1447,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ /*0x16e4d*/ 1432,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0x16e41*/ 1420,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0xab74*/ 1146,
+ -1, -1, -1, -1,
+ /*0xab7c*/ 1154,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ /*0xab72*/ 1144,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0xab76*/ 1148,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0xab7a*/ 1152,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0xab78*/ 1150,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0xab7e*/ 1156
+ };
+
+ if (code <= MAX_CODE_VALUE && code >= MIN_CODE_VALUE)
+ {
+ register unsigned int key = onigenc_unicode_CaseFold_11_hash(code);
+
+ if (key <= MAX_HASH_VALUE)
+ {
+ register short s = wordlist[key];
+
+ if (s >= 0 && code1_equal(code, CaseFold_11_Table[s].from))
+ return &CaseFold_11_Table[s].to;
+ }
+ }
+ return 0;
+}
+
+static const CaseUnfold_11_Type CaseUnfold_11_Table[] = {
+#define CaseUnfold_11 (*(CaseUnfold_11_Type (*)[1352])(CaseUnfold_11_Table+0))
+ {0x0061, {1|U, {0x0041}}},
+ {0x0062, {1|U, {0x0042}}},
+ {0x0063, {1|U, {0x0043}}},
+ {0x0064, {1|U, {0x0044}}},
+ {0x0065, {1|U, {0x0045}}},
+ {0x0066, {1|U, {0x0046}}},
+ {0x0067, {1|U, {0x0047}}},
+ {0x0068, {1|U, {0x0048}}},
+ {0x006a, {1|U, {0x004a}}},
+ {0x006b, {2|U, {0x004b, 0x212a}}},
+ {0x006c, {1|U, {0x004c}}},
+ {0x006d, {1|U, {0x004d}}},
+ {0x006e, {1|U, {0x004e}}},
+ {0x006f, {1|U, {0x004f}}},
+ {0x0070, {1|U, {0x0050}}},
+ {0x0071, {1|U, {0x0051}}},
+ {0x0072, {1|U, {0x0052}}},
+ {0x0073, {2|U, {0x0053, 0x017f}}},
+ {0x0074, {1|U, {0x0054}}},
+ {0x0075, {1|U, {0x0055}}},
+ {0x0076, {1|U, {0x0056}}},
+ {0x0077, {1|U, {0x0057}}},
+ {0x0078, {1|U, {0x0058}}},
+ {0x0079, {1|U, {0x0059}}},
+ {0x007a, {1|U, {0x005a}}},
+ {0x00e0, {1|U, {0x00c0}}},
+ {0x00e1, {1|U, {0x00c1}}},
+ {0x00e2, {1|U, {0x00c2}}},
+ {0x00e3, {1|U, {0x00c3}}},
+ {0x00e4, {1|U, {0x00c4}}},
+ {0x00e5, {2|U, {0x00c5, 0x212b}}},
+ {0x00e6, {1|U, {0x00c6}}},
+ {0x00e7, {1|U, {0x00c7}}},
+ {0x00e8, {1|U, {0x00c8}}},
+ {0x00e9, {1|U, {0x00c9}}},
+ {0x00ea, {1|U, {0x00ca}}},
+ {0x00eb, {1|U, {0x00cb}}},
+ {0x00ec, {1|U, {0x00cc}}},
+ {0x00ed, {1|U, {0x00cd}}},
+ {0x00ee, {1|U, {0x00ce}}},
+ {0x00ef, {1|U, {0x00cf}}},
+ {0x00f0, {1|U, {0x00d0}}},
+ {0x00f1, {1|U, {0x00d1}}},
+ {0x00f2, {1|U, {0x00d2}}},
+ {0x00f3, {1|U, {0x00d3}}},
+ {0x00f4, {1|U, {0x00d4}}},
+ {0x00f5, {1|U, {0x00d5}}},
+ {0x00f6, {1|U, {0x00d6}}},
+ {0x00f8, {1|U, {0x00d8}}},
+ {0x00f9, {1|U, {0x00d9}}},
+ {0x00fa, {1|U, {0x00da}}},
+ {0x00fb, {1|U, {0x00db}}},
+ {0x00fc, {1|U, {0x00dc}}},
+ {0x00fd, {1|U, {0x00dd}}},
+ {0x00fe, {1|U, {0x00de}}},
+ {0x00ff, {1|U, {0x0178}}},
+ {0x0101, {1|U, {0x0100}}},
+ {0x0103, {1|U, {0x0102}}},
+ {0x0105, {1|U, {0x0104}}},
+ {0x0107, {1|U, {0x0106}}},
+ {0x0109, {1|U, {0x0108}}},
+ {0x010b, {1|U, {0x010a}}},
+ {0x010d, {1|U, {0x010c}}},
+ {0x010f, {1|U, {0x010e}}},
+ {0x0111, {1|U, {0x0110}}},
+ {0x0113, {1|U, {0x0112}}},
+ {0x0115, {1|U, {0x0114}}},
+ {0x0117, {1|U, {0x0116}}},
+ {0x0119, {1|U, {0x0118}}},
+ {0x011b, {1|U, {0x011a}}},
+ {0x011d, {1|U, {0x011c}}},
+ {0x011f, {1|U, {0x011e}}},
+ {0x0121, {1|U, {0x0120}}},
+ {0x0123, {1|U, {0x0122}}},
+ {0x0125, {1|U, {0x0124}}},
+ {0x0127, {1|U, {0x0126}}},
+ {0x0129, {1|U, {0x0128}}},
+ {0x012b, {1|U, {0x012a}}},
+ {0x012d, {1|U, {0x012c}}},
+ {0x012f, {1|U, {0x012e}}},
+ {0x0133, {1|U, {0x0132}}},
+ {0x0135, {1|U, {0x0134}}},
+ {0x0137, {1|U, {0x0136}}},
+ {0x013a, {1|U, {0x0139}}},
+ {0x013c, {1|U, {0x013b}}},
+ {0x013e, {1|U, {0x013d}}},
+ {0x0140, {1|U, {0x013f}}},
+ {0x0142, {1|U, {0x0141}}},
+ {0x0144, {1|U, {0x0143}}},
+ {0x0146, {1|U, {0x0145}}},
+ {0x0148, {1|U, {0x0147}}},
+ {0x014b, {1|U, {0x014a}}},
+ {0x014d, {1|U, {0x014c}}},
+ {0x014f, {1|U, {0x014e}}},
+ {0x0151, {1|U, {0x0150}}},
+ {0x0153, {1|U, {0x0152}}},
+ {0x0155, {1|U, {0x0154}}},
+ {0x0157, {1|U, {0x0156}}},
+ {0x0159, {1|U, {0x0158}}},
+ {0x015b, {1|U, {0x015a}}},
+ {0x015d, {1|U, {0x015c}}},
+ {0x015f, {1|U, {0x015e}}},
+ {0x0161, {1|U, {0x0160}}},
+ {0x0163, {1|U, {0x0162}}},
+ {0x0165, {1|U, {0x0164}}},
+ {0x0167, {1|U, {0x0166}}},
+ {0x0169, {1|U, {0x0168}}},
+ {0x016b, {1|U, {0x016a}}},
+ {0x016d, {1|U, {0x016c}}},
+ {0x016f, {1|U, {0x016e}}},
+ {0x0171, {1|U, {0x0170}}},
+ {0x0173, {1|U, {0x0172}}},
+ {0x0175, {1|U, {0x0174}}},
+ {0x0177, {1|U, {0x0176}}},
+ {0x017a, {1|U, {0x0179}}},
+ {0x017c, {1|U, {0x017b}}},
+ {0x017e, {1|U, {0x017d}}},
+ {0x0180, {1|U, {0x0243}}},
+ {0x0183, {1|U, {0x0182}}},
+ {0x0185, {1|U, {0x0184}}},
+ {0x0188, {1|U, {0x0187}}},
+ {0x018c, {1|U, {0x018b}}},
+ {0x0192, {1|U, {0x0191}}},
+ {0x0195, {1|U, {0x01f6}}},
+ {0x0199, {1|U, {0x0198}}},
+ {0x019a, {1|U, {0x023d}}},
+ {0x019e, {1|U, {0x0220}}},
+ {0x01a1, {1|U, {0x01a0}}},
+ {0x01a3, {1|U, {0x01a2}}},
+ {0x01a5, {1|U, {0x01a4}}},
+ {0x01a8, {1|U, {0x01a7}}},
+ {0x01ad, {1|U, {0x01ac}}},
+ {0x01b0, {1|U, {0x01af}}},
+ {0x01b4, {1|U, {0x01b3}}},
+ {0x01b6, {1|U, {0x01b5}}},
+ {0x01b9, {1|U, {0x01b8}}},
+ {0x01bd, {1|U, {0x01bc}}},
+ {0x01bf, {1|U, {0x01f7}}},
+ {0x01c6, {2|U|ST, {0x01c4, 0x01c5}}},
+ {0x01c9, {2|U|ST, {0x01c7, 0x01c8}}},
+ {0x01cc, {2|U|ST, {0x01ca, 0x01cb}}},
+ {0x01ce, {1|U, {0x01cd}}},
+ {0x01d0, {1|U, {0x01cf}}},
+ {0x01d2, {1|U, {0x01d1}}},
+ {0x01d4, {1|U, {0x01d3}}},
+ {0x01d6, {1|U, {0x01d5}}},
+ {0x01d8, {1|U, {0x01d7}}},
+ {0x01da, {1|U, {0x01d9}}},
+ {0x01dc, {1|U, {0x01db}}},
+ {0x01dd, {1|U, {0x018e}}},
+ {0x01df, {1|U, {0x01de}}},
+ {0x01e1, {1|U, {0x01e0}}},
+ {0x01e3, {1|U, {0x01e2}}},
+ {0x01e5, {1|U, {0x01e4}}},
+ {0x01e7, {1|U, {0x01e6}}},
+ {0x01e9, {1|U, {0x01e8}}},
+ {0x01eb, {1|U, {0x01ea}}},
+ {0x01ed, {1|U, {0x01ec}}},
+ {0x01ef, {1|U, {0x01ee}}},
+ {0x01f3, {2|U|ST, {0x01f1, 0x01f2}}},
+ {0x01f5, {1|U, {0x01f4}}},
+ {0x01f9, {1|U, {0x01f8}}},
+ {0x01fb, {1|U, {0x01fa}}},
+ {0x01fd, {1|U, {0x01fc}}},
+ {0x01ff, {1|U, {0x01fe}}},
+ {0x0201, {1|U, {0x0200}}},
+ {0x0203, {1|U, {0x0202}}},
+ {0x0205, {1|U, {0x0204}}},
+ {0x0207, {1|U, {0x0206}}},
+ {0x0209, {1|U, {0x0208}}},
+ {0x020b, {1|U, {0x020a}}},
+ {0x020d, {1|U, {0x020c}}},
+ {0x020f, {1|U, {0x020e}}},
+ {0x0211, {1|U, {0x0210}}},
+ {0x0213, {1|U, {0x0212}}},
+ {0x0215, {1|U, {0x0214}}},
+ {0x0217, {1|U, {0x0216}}},
+ {0x0219, {1|U, {0x0218}}},
+ {0x021b, {1|U, {0x021a}}},
+ {0x021d, {1|U, {0x021c}}},
+ {0x021f, {1|U, {0x021e}}},
+ {0x0223, {1|U, {0x0222}}},
+ {0x0225, {1|U, {0x0224}}},
+ {0x0227, {1|U, {0x0226}}},
+ {0x0229, {1|U, {0x0228}}},
+ {0x022b, {1|U, {0x022a}}},
+ {0x022d, {1|U, {0x022c}}},
+ {0x022f, {1|U, {0x022e}}},
+ {0x0231, {1|U, {0x0230}}},
+ {0x0233, {1|U, {0x0232}}},
+ {0x023c, {1|U, {0x023b}}},
+ {0x023f, {1|U, {0x2c7e}}},
+ {0x0240, {1|U, {0x2c7f}}},
+ {0x0242, {1|U, {0x0241}}},
+ {0x0247, {1|U, {0x0246}}},
+ {0x0249, {1|U, {0x0248}}},
+ {0x024b, {1|U, {0x024a}}},
+ {0x024d, {1|U, {0x024c}}},
+ {0x024f, {1|U, {0x024e}}},
+ {0x0250, {1|U, {0x2c6f}}},
+ {0x0251, {1|U, {0x2c6d}}},
+ {0x0252, {1|U, {0x2c70}}},
+ {0x0253, {1|U, {0x0181}}},
+ {0x0254, {1|U, {0x0186}}},
+ {0x0256, {1|U, {0x0189}}},
+ {0x0257, {1|U, {0x018a}}},
+ {0x0259, {1|U, {0x018f}}},
+ {0x025b, {1|U, {0x0190}}},
+ {0x025c, {1|U, {0xa7ab}}},
+ {0x0260, {1|U, {0x0193}}},
+ {0x0261, {1|U, {0xa7ac}}},
+ {0x0263, {1|U, {0x0194}}},
+ {0x0265, {1|U, {0xa78d}}},
+ {0x0266, {1|U, {0xa7aa}}},
+ {0x0268, {1|U, {0x0197}}},
+ {0x0269, {1|U, {0x0196}}},
+ {0x026a, {1|U, {0xa7ae}}},
+ {0x026b, {1|U, {0x2c62}}},
+ {0x026c, {1|U, {0xa7ad}}},
+ {0x026f, {1|U, {0x019c}}},
+ {0x0271, {1|U, {0x2c6e}}},
+ {0x0272, {1|U, {0x019d}}},
+ {0x0275, {1|U, {0x019f}}},
+ {0x027d, {1|U, {0x2c64}}},
+ {0x0280, {1|U, {0x01a6}}},
+ {0x0282, {1|U, {0xa7c5}}},
+ {0x0283, {1|U, {0x01a9}}},
+ {0x0287, {1|U, {0xa7b1}}},
+ {0x0288, {1|U, {0x01ae}}},
+ {0x0289, {1|U, {0x0244}}},
+ {0x028a, {1|U, {0x01b1}}},
+ {0x028b, {1|U, {0x01b2}}},
+ {0x028c, {1|U, {0x0245}}},
+ {0x0292, {1|U, {0x01b7}}},
+ {0x029d, {1|U, {0xa7b2}}},
+ {0x029e, {1|U, {0xa7b0}}},
+ {0x0371, {1|U, {0x0370}}},
+ {0x0373, {1|U, {0x0372}}},
+ {0x0377, {1|U, {0x0376}}},
+ {0x037b, {1|U, {0x03fd}}},
+ {0x037c, {1|U, {0x03fe}}},
+ {0x037d, {1|U, {0x03ff}}},
+ {0x03ac, {1|U, {0x0386}}},
+ {0x03ad, {1|U, {0x0388}}},
+ {0x03ae, {1|U, {0x0389}}},
+ {0x03af, {1|U, {0x038a}}},
+ {0x03b1, {1|U, {0x0391}}},
+ {0x03b2, {2|U, {0x0392, 0x03d0}}},
+ {0x03b3, {1|U, {0x0393}}},
+ {0x03b4, {1|U, {0x0394}}},
+ {0x03b5, {2|U, {0x0395, 0x03f5}}},
+ {0x03b6, {1|U, {0x0396}}},
+ {0x03b7, {1|U, {0x0397}}},
+ {0x03b8, {3|U, {0x0398, 0x03d1, 0x03f4}}},
+ {0x03b9, {3|U, {0x0399, 0x0345, 0x1fbe}}},
+ {0x03ba, {2|U, {0x039a, 0x03f0}}},
+ {0x03bb, {1|U, {0x039b}}},
+ {0x03bc, {2|U, {0x039c, 0x00b5}}},
+ {0x03bd, {1|U, {0x039d}}},
+ {0x03be, {1|U, {0x039e}}},
+ {0x03bf, {1|U, {0x039f}}},
+ {0x03c0, {2|U, {0x03a0, 0x03d6}}},
+ {0x03c1, {2|U, {0x03a1, 0x03f1}}},
+ {0x03c3, {2|U, {0x03a3, 0x03c2}}},
+ {0x03c4, {1|U, {0x03a4}}},
+ {0x03c5, {1|U, {0x03a5}}},
+ {0x03c6, {2|U, {0x03a6, 0x03d5}}},
+ {0x03c7, {1|U, {0x03a7}}},
+ {0x03c8, {1|U, {0x03a8}}},
+ {0x03c9, {2|U, {0x03a9, 0x2126}}},
+ {0x03ca, {1|U, {0x03aa}}},
+ {0x03cb, {1|U, {0x03ab}}},
+ {0x03cc, {1|U, {0x038c}}},
+ {0x03cd, {1|U, {0x038e}}},
+ {0x03ce, {1|U, {0x038f}}},
+ {0x03d7, {1|U, {0x03cf}}},
+ {0x03d9, {1|U, {0x03d8}}},
+ {0x03db, {1|U, {0x03da}}},
+ {0x03dd, {1|U, {0x03dc}}},
+ {0x03df, {1|U, {0x03de}}},
+ {0x03e1, {1|U, {0x03e0}}},
+ {0x03e3, {1|U, {0x03e2}}},
+ {0x03e5, {1|U, {0x03e4}}},
+ {0x03e7, {1|U, {0x03e6}}},
+ {0x03e9, {1|U, {0x03e8}}},
+ {0x03eb, {1|U, {0x03ea}}},
+ {0x03ed, {1|U, {0x03ec}}},
+ {0x03ef, {1|U, {0x03ee}}},
+ {0x03f2, {1|U, {0x03f9}}},
+ {0x03f3, {1|U, {0x037f}}},
+ {0x03f8, {1|U, {0x03f7}}},
+ {0x03fb, {1|U, {0x03fa}}},
+ {0x0430, {1|U, {0x0410}}},
+ {0x0431, {1|U, {0x0411}}},
+ {0x0432, {2|U, {0x0412, 0x1c80}}},
+ {0x0433, {1|U, {0x0413}}},
+ {0x0434, {2|U, {0x0414, 0x1c81}}},
+ {0x0435, {1|U, {0x0415}}},
+ {0x0436, {1|U, {0x0416}}},
+ {0x0437, {1|U, {0x0417}}},
+ {0x0438, {1|U, {0x0418}}},
+ {0x0439, {1|U, {0x0419}}},
+ {0x043a, {1|U, {0x041a}}},
+ {0x043b, {1|U, {0x041b}}},
+ {0x043c, {1|U, {0x041c}}},
+ {0x043d, {1|U, {0x041d}}},
+ {0x043e, {2|U, {0x041e, 0x1c82}}},
+ {0x043f, {1|U, {0x041f}}},
+ {0x0440, {1|U, {0x0420}}},
+ {0x0441, {2|U, {0x0421, 0x1c83}}},
+ {0x0442, {3|U, {0x0422, 0x1c84, 0x1c85}}},
+ {0x0443, {1|U, {0x0423}}},
+ {0x0444, {1|U, {0x0424}}},
+ {0x0445, {1|U, {0x0425}}},
+ {0x0446, {1|U, {0x0426}}},
+ {0x0447, {1|U, {0x0427}}},
+ {0x0448, {1|U, {0x0428}}},
+ {0x0449, {1|U, {0x0429}}},
+ {0x044a, {2|U, {0x042a, 0x1c86}}},
+ {0x044b, {1|U, {0x042b}}},
+ {0x044c, {1|U, {0x042c}}},
+ {0x044d, {1|U, {0x042d}}},
+ {0x044e, {1|U, {0x042e}}},
+ {0x044f, {1|U, {0x042f}}},
+ {0x0450, {1|U, {0x0400}}},
+ {0x0451, {1|U, {0x0401}}},
+ {0x0452, {1|U, {0x0402}}},
+ {0x0453, {1|U, {0x0403}}},
+ {0x0454, {1|U, {0x0404}}},
+ {0x0455, {1|U, {0x0405}}},
+ {0x0456, {1|U, {0x0406}}},
+ {0x0457, {1|U, {0x0407}}},
+ {0x0458, {1|U, {0x0408}}},
+ {0x0459, {1|U, {0x0409}}},
+ {0x045a, {1|U, {0x040a}}},
+ {0x045b, {1|U, {0x040b}}},
+ {0x045c, {1|U, {0x040c}}},
+ {0x045d, {1|U, {0x040d}}},
+ {0x045e, {1|U, {0x040e}}},
+ {0x045f, {1|U, {0x040f}}},
+ {0x0461, {1|U, {0x0460}}},
+ {0x0463, {2|U, {0x0462, 0x1c87}}},
+ {0x0465, {1|U, {0x0464}}},
+ {0x0467, {1|U, {0x0466}}},
+ {0x0469, {1|U, {0x0468}}},
+ {0x046b, {1|U, {0x046a}}},
+ {0x046d, {1|U, {0x046c}}},
+ {0x046f, {1|U, {0x046e}}},
+ {0x0471, {1|U, {0x0470}}},
+ {0x0473, {1|U, {0x0472}}},
+ {0x0475, {1|U, {0x0474}}},
+ {0x0477, {1|U, {0x0476}}},
+ {0x0479, {1|U, {0x0478}}},
+ {0x047b, {1|U, {0x047a}}},
+ {0x047d, {1|U, {0x047c}}},
+ {0x047f, {1|U, {0x047e}}},
+ {0x0481, {1|U, {0x0480}}},
+ {0x048b, {1|U, {0x048a}}},
+ {0x048d, {1|U, {0x048c}}},
+ {0x048f, {1|U, {0x048e}}},
+ {0x0491, {1|U, {0x0490}}},
+ {0x0493, {1|U, {0x0492}}},
+ {0x0495, {1|U, {0x0494}}},
+ {0x0497, {1|U, {0x0496}}},
+ {0x0499, {1|U, {0x0498}}},
+ {0x049b, {1|U, {0x049a}}},
+ {0x049d, {1|U, {0x049c}}},
+ {0x049f, {1|U, {0x049e}}},
+ {0x04a1, {1|U, {0x04a0}}},
+ {0x04a3, {1|U, {0x04a2}}},
+ {0x04a5, {1|U, {0x04a4}}},
+ {0x04a7, {1|U, {0x04a6}}},
+ {0x04a9, {1|U, {0x04a8}}},
+ {0x04ab, {1|U, {0x04aa}}},
+ {0x04ad, {1|U, {0x04ac}}},
+ {0x04af, {1|U, {0x04ae}}},
+ {0x04b1, {1|U, {0x04b0}}},
+ {0x04b3, {1|U, {0x04b2}}},
+ {0x04b5, {1|U, {0x04b4}}},
+ {0x04b7, {1|U, {0x04b6}}},
+ {0x04b9, {1|U, {0x04b8}}},
+ {0x04bb, {1|U, {0x04ba}}},
+ {0x04bd, {1|U, {0x04bc}}},
+ {0x04bf, {1|U, {0x04be}}},
+ {0x04c2, {1|U, {0x04c1}}},
+ {0x04c4, {1|U, {0x04c3}}},
+ {0x04c6, {1|U, {0x04c5}}},
+ {0x04c8, {1|U, {0x04c7}}},
+ {0x04ca, {1|U, {0x04c9}}},
+ {0x04cc, {1|U, {0x04cb}}},
+ {0x04ce, {1|U, {0x04cd}}},
+ {0x04cf, {1|U, {0x04c0}}},
+ {0x04d1, {1|U, {0x04d0}}},
+ {0x04d3, {1|U, {0x04d2}}},
+ {0x04d5, {1|U, {0x04d4}}},
+ {0x04d7, {1|U, {0x04d6}}},
+ {0x04d9, {1|U, {0x04d8}}},
+ {0x04db, {1|U, {0x04da}}},
+ {0x04dd, {1|U, {0x04dc}}},
+ {0x04df, {1|U, {0x04de}}},
+ {0x04e1, {1|U, {0x04e0}}},
+ {0x04e3, {1|U, {0x04e2}}},
+ {0x04e5, {1|U, {0x04e4}}},
+ {0x04e7, {1|U, {0x04e6}}},
+ {0x04e9, {1|U, {0x04e8}}},
+ {0x04eb, {1|U, {0x04ea}}},
+ {0x04ed, {1|U, {0x04ec}}},
+ {0x04ef, {1|U, {0x04ee}}},
+ {0x04f1, {1|U, {0x04f0}}},
+ {0x04f3, {1|U, {0x04f2}}},
+ {0x04f5, {1|U, {0x04f4}}},
+ {0x04f7, {1|U, {0x04f6}}},
+ {0x04f9, {1|U, {0x04f8}}},
+ {0x04fb, {1|U, {0x04fa}}},
+ {0x04fd, {1|U, {0x04fc}}},
+ {0x04ff, {1|U, {0x04fe}}},
+ {0x0501, {1|U, {0x0500}}},
+ {0x0503, {1|U, {0x0502}}},
+ {0x0505, {1|U, {0x0504}}},
+ {0x0507, {1|U, {0x0506}}},
+ {0x0509, {1|U, {0x0508}}},
+ {0x050b, {1|U, {0x050a}}},
+ {0x050d, {1|U, {0x050c}}},
+ {0x050f, {1|U, {0x050e}}},
+ {0x0511, {1|U, {0x0510}}},
+ {0x0513, {1|U, {0x0512}}},
+ {0x0515, {1|U, {0x0514}}},
+ {0x0517, {1|U, {0x0516}}},
+ {0x0519, {1|U, {0x0518}}},
+ {0x051b, {1|U, {0x051a}}},
+ {0x051d, {1|U, {0x051c}}},
+ {0x051f, {1|U, {0x051e}}},
+ {0x0521, {1|U, {0x0520}}},
+ {0x0523, {1|U, {0x0522}}},
+ {0x0525, {1|U, {0x0524}}},
+ {0x0527, {1|U, {0x0526}}},
+ {0x0529, {1|U, {0x0528}}},
+ {0x052b, {1|U, {0x052a}}},
+ {0x052d, {1|U, {0x052c}}},
+ {0x052f, {1|U, {0x052e}}},
+ {0x0561, {1|U, {0x0531}}},
+ {0x0562, {1|U, {0x0532}}},
+ {0x0563, {1|U, {0x0533}}},
+ {0x0564, {1|U, {0x0534}}},
+ {0x0565, {1|U, {0x0535}}},
+ {0x0566, {1|U, {0x0536}}},
+ {0x0567, {1|U, {0x0537}}},
+ {0x0568, {1|U, {0x0538}}},
+ {0x0569, {1|U, {0x0539}}},
+ {0x056a, {1|U, {0x053a}}},
+ {0x056b, {1|U, {0x053b}}},
+ {0x056c, {1|U, {0x053c}}},
+ {0x056d, {1|U, {0x053d}}},
+ {0x056e, {1|U, {0x053e}}},
+ {0x056f, {1|U, {0x053f}}},
+ {0x0570, {1|U, {0x0540}}},
+ {0x0571, {1|U, {0x0541}}},
+ {0x0572, {1|U, {0x0542}}},
+ {0x0573, {1|U, {0x0543}}},
+ {0x0574, {1|U, {0x0544}}},
+ {0x0575, {1|U, {0x0545}}},
+ {0x0576, {1|U, {0x0546}}},
+ {0x0577, {1|U, {0x0547}}},
+ {0x0578, {1|U, {0x0548}}},
+ {0x0579, {1|U, {0x0549}}},
+ {0x057a, {1|U, {0x054a}}},
+ {0x057b, {1|U, {0x054b}}},
+ {0x057c, {1|U, {0x054c}}},
+ {0x057d, {1|U, {0x054d}}},
+ {0x057e, {1|U, {0x054e}}},
+ {0x057f, {1|U, {0x054f}}},
+ {0x0580, {1|U, {0x0550}}},
+ {0x0581, {1|U, {0x0551}}},
+ {0x0582, {1|U, {0x0552}}},
+ {0x0583, {1|U, {0x0553}}},
+ {0x0584, {1|U, {0x0554}}},
+ {0x0585, {1|U, {0x0555}}},
+ {0x0586, {1|U, {0x0556}}},
+ {0x10d0, {1|U|IT, {0x1c90}}},
+ {0x10d1, {1|U|IT, {0x1c91}}},
+ {0x10d2, {1|U|IT, {0x1c92}}},
+ {0x10d3, {1|U|IT, {0x1c93}}},
+ {0x10d4, {1|U|IT, {0x1c94}}},
+ {0x10d5, {1|U|IT, {0x1c95}}},
+ {0x10d6, {1|U|IT, {0x1c96}}},
+ {0x10d7, {1|U|IT, {0x1c97}}},
+ {0x10d8, {1|U|IT, {0x1c98}}},
+ {0x10d9, {1|U|IT, {0x1c99}}},
+ {0x10da, {1|U|IT, {0x1c9a}}},
+ {0x10db, {1|U|IT, {0x1c9b}}},
+ {0x10dc, {1|U|IT, {0x1c9c}}},
+ {0x10dd, {1|U|IT, {0x1c9d}}},
+ {0x10de, {1|U|IT, {0x1c9e}}},
+ {0x10df, {1|U|IT, {0x1c9f}}},
+ {0x10e0, {1|U|IT, {0x1ca0}}},
+ {0x10e1, {1|U|IT, {0x1ca1}}},
+ {0x10e2, {1|U|IT, {0x1ca2}}},
+ {0x10e3, {1|U|IT, {0x1ca3}}},
+ {0x10e4, {1|U|IT, {0x1ca4}}},
+ {0x10e5, {1|U|IT, {0x1ca5}}},
+ {0x10e6, {1|U|IT, {0x1ca6}}},
+ {0x10e7, {1|U|IT, {0x1ca7}}},
+ {0x10e8, {1|U|IT, {0x1ca8}}},
+ {0x10e9, {1|U|IT, {0x1ca9}}},
+ {0x10ea, {1|U|IT, {0x1caa}}},
+ {0x10eb, {1|U|IT, {0x1cab}}},
+ {0x10ec, {1|U|IT, {0x1cac}}},
+ {0x10ed, {1|U|IT, {0x1cad}}},
+ {0x10ee, {1|U|IT, {0x1cae}}},
+ {0x10ef, {1|U|IT, {0x1caf}}},
+ {0x10f0, {1|U|IT, {0x1cb0}}},
+ {0x10f1, {1|U|IT, {0x1cb1}}},
+ {0x10f2, {1|U|IT, {0x1cb2}}},
+ {0x10f3, {1|U|IT, {0x1cb3}}},
+ {0x10f4, {1|U|IT, {0x1cb4}}},
+ {0x10f5, {1|U|IT, {0x1cb5}}},
+ {0x10f6, {1|U|IT, {0x1cb6}}},
+ {0x10f7, {1|U|IT, {0x1cb7}}},
+ {0x10f8, {1|U|IT, {0x1cb8}}},
+ {0x10f9, {1|U|IT, {0x1cb9}}},
+ {0x10fa, {1|U|IT, {0x1cba}}},
+ {0x10fd, {1|U|IT, {0x1cbd}}},
+ {0x10fe, {1|U|IT, {0x1cbe}}},
+ {0x10ff, {1|U|IT, {0x1cbf}}},
+ {0x13a0, {1|D, {0xab70}}},
+ {0x13a1, {1|D, {0xab71}}},
+ {0x13a2, {1|D, {0xab72}}},
+ {0x13a3, {1|D, {0xab73}}},
+ {0x13a4, {1|D, {0xab74}}},
+ {0x13a5, {1|D, {0xab75}}},
+ {0x13a6, {1|D, {0xab76}}},
+ {0x13a7, {1|D, {0xab77}}},
+ {0x13a8, {1|D, {0xab78}}},
+ {0x13a9, {1|D, {0xab79}}},
+ {0x13aa, {1|D, {0xab7a}}},
+ {0x13ab, {1|D, {0xab7b}}},
+ {0x13ac, {1|D, {0xab7c}}},
+ {0x13ad, {1|D, {0xab7d}}},
+ {0x13ae, {1|D, {0xab7e}}},
+ {0x13af, {1|D, {0xab7f}}},
+ {0x13b0, {1|D, {0xab80}}},
+ {0x13b1, {1|D, {0xab81}}},
+ {0x13b2, {1|D, {0xab82}}},
+ {0x13b3, {1|D, {0xab83}}},
+ {0x13b4, {1|D, {0xab84}}},
+ {0x13b5, {1|D, {0xab85}}},
+ {0x13b6, {1|D, {0xab86}}},
+ {0x13b7, {1|D, {0xab87}}},
+ {0x13b8, {1|D, {0xab88}}},
+ {0x13b9, {1|D, {0xab89}}},
+ {0x13ba, {1|D, {0xab8a}}},
+ {0x13bb, {1|D, {0xab8b}}},
+ {0x13bc, {1|D, {0xab8c}}},
+ {0x13bd, {1|D, {0xab8d}}},
+ {0x13be, {1|D, {0xab8e}}},
+ {0x13bf, {1|D, {0xab8f}}},
+ {0x13c0, {1|D, {0xab90}}},
+ {0x13c1, {1|D, {0xab91}}},
+ {0x13c2, {1|D, {0xab92}}},
+ {0x13c3, {1|D, {0xab93}}},
+ {0x13c4, {1|D, {0xab94}}},
+ {0x13c5, {1|D, {0xab95}}},
+ {0x13c6, {1|D, {0xab96}}},
+ {0x13c7, {1|D, {0xab97}}},
+ {0x13c8, {1|D, {0xab98}}},
+ {0x13c9, {1|D, {0xab99}}},
+ {0x13ca, {1|D, {0xab9a}}},
+ {0x13cb, {1|D, {0xab9b}}},
+ {0x13cc, {1|D, {0xab9c}}},
+ {0x13cd, {1|D, {0xab9d}}},
+ {0x13ce, {1|D, {0xab9e}}},
+ {0x13cf, {1|D, {0xab9f}}},
+ {0x13d0, {1|D, {0xaba0}}},
+ {0x13d1, {1|D, {0xaba1}}},
+ {0x13d2, {1|D, {0xaba2}}},
+ {0x13d3, {1|D, {0xaba3}}},
+ {0x13d4, {1|D, {0xaba4}}},
+ {0x13d5, {1|D, {0xaba5}}},
+ {0x13d6, {1|D, {0xaba6}}},
+ {0x13d7, {1|D, {0xaba7}}},
+ {0x13d8, {1|D, {0xaba8}}},
+ {0x13d9, {1|D, {0xaba9}}},
+ {0x13da, {1|D, {0xabaa}}},
+ {0x13db, {1|D, {0xabab}}},
+ {0x13dc, {1|D, {0xabac}}},
+ {0x13dd, {1|D, {0xabad}}},
+ {0x13de, {1|D, {0xabae}}},
+ {0x13df, {1|D, {0xabaf}}},
+ {0x13e0, {1|D, {0xabb0}}},
+ {0x13e1, {1|D, {0xabb1}}},
+ {0x13e2, {1|D, {0xabb2}}},
+ {0x13e3, {1|D, {0xabb3}}},
+ {0x13e4, {1|D, {0xabb4}}},
+ {0x13e5, {1|D, {0xabb5}}},
+ {0x13e6, {1|D, {0xabb6}}},
+ {0x13e7, {1|D, {0xabb7}}},
+ {0x13e8, {1|D, {0xabb8}}},
+ {0x13e9, {1|D, {0xabb9}}},
+ {0x13ea, {1|D, {0xabba}}},
+ {0x13eb, {1|D, {0xabbb}}},
+ {0x13ec, {1|D, {0xabbc}}},
+ {0x13ed, {1|D, {0xabbd}}},
+ {0x13ee, {1|D, {0xabbe}}},
+ {0x13ef, {1|D, {0xabbf}}},
+ {0x13f0, {1|D, {0x13f8}}},
+ {0x13f1, {1|D, {0x13f9}}},
+ {0x13f2, {1|D, {0x13fa}}},
+ {0x13f3, {1|D, {0x13fb}}},
+ {0x13f4, {1|D, {0x13fc}}},
+ {0x13f5, {1|D, {0x13fd}}},
+ {0x1d79, {1|U, {0xa77d}}},
+ {0x1d7d, {1|U, {0x2c63}}},
+ {0x1d8e, {1|U, {0xa7c6}}},
+ {0x1e01, {1|U, {0x1e00}}},
+ {0x1e03, {1|U, {0x1e02}}},
+ {0x1e05, {1|U, {0x1e04}}},
+ {0x1e07, {1|U, {0x1e06}}},
+ {0x1e09, {1|U, {0x1e08}}},
+ {0x1e0b, {1|U, {0x1e0a}}},
+ {0x1e0d, {1|U, {0x1e0c}}},
+ {0x1e0f, {1|U, {0x1e0e}}},
+ {0x1e11, {1|U, {0x1e10}}},
+ {0x1e13, {1|U, {0x1e12}}},
+ {0x1e15, {1|U, {0x1e14}}},
+ {0x1e17, {1|U, {0x1e16}}},
+ {0x1e19, {1|U, {0x1e18}}},
+ {0x1e1b, {1|U, {0x1e1a}}},
+ {0x1e1d, {1|U, {0x1e1c}}},
+ {0x1e1f, {1|U, {0x1e1e}}},
+ {0x1e21, {1|U, {0x1e20}}},
+ {0x1e23, {1|U, {0x1e22}}},
+ {0x1e25, {1|U, {0x1e24}}},
+ {0x1e27, {1|U, {0x1e26}}},
+ {0x1e29, {1|U, {0x1e28}}},
+ {0x1e2b, {1|U, {0x1e2a}}},
+ {0x1e2d, {1|U, {0x1e2c}}},
+ {0x1e2f, {1|U, {0x1e2e}}},
+ {0x1e31, {1|U, {0x1e30}}},
+ {0x1e33, {1|U, {0x1e32}}},
+ {0x1e35, {1|U, {0x1e34}}},
+ {0x1e37, {1|U, {0x1e36}}},
+ {0x1e39, {1|U, {0x1e38}}},
+ {0x1e3b, {1|U, {0x1e3a}}},
+ {0x1e3d, {1|U, {0x1e3c}}},
+ {0x1e3f, {1|U, {0x1e3e}}},
+ {0x1e41, {1|U, {0x1e40}}},
+ {0x1e43, {1|U, {0x1e42}}},
+ {0x1e45, {1|U, {0x1e44}}},
+ {0x1e47, {1|U, {0x1e46}}},
+ {0x1e49, {1|U, {0x1e48}}},
+ {0x1e4b, {1|U, {0x1e4a}}},
+ {0x1e4d, {1|U, {0x1e4c}}},
+ {0x1e4f, {1|U, {0x1e4e}}},
+ {0x1e51, {1|U, {0x1e50}}},
+ {0x1e53, {1|U, {0x1e52}}},
+ {0x1e55, {1|U, {0x1e54}}},
+ {0x1e57, {1|U, {0x1e56}}},
+ {0x1e59, {1|U, {0x1e58}}},
+ {0x1e5b, {1|U, {0x1e5a}}},
+ {0x1e5d, {1|U, {0x1e5c}}},
+ {0x1e5f, {1|U, {0x1e5e}}},
+ {0x1e61, {2|U, {0x1e60, 0x1e9b}}},
+ {0x1e63, {1|U, {0x1e62}}},
+ {0x1e65, {1|U, {0x1e64}}},
+ {0x1e67, {1|U, {0x1e66}}},
+ {0x1e69, {1|U, {0x1e68}}},
+ {0x1e6b, {1|U, {0x1e6a}}},
+ {0x1e6d, {1|U, {0x1e6c}}},
+ {0x1e6f, {1|U, {0x1e6e}}},
+ {0x1e71, {1|U, {0x1e70}}},
+ {0x1e73, {1|U, {0x1e72}}},
+ {0x1e75, {1|U, {0x1e74}}},
+ {0x1e77, {1|U, {0x1e76}}},
+ {0x1e79, {1|U, {0x1e78}}},
+ {0x1e7b, {1|U, {0x1e7a}}},
+ {0x1e7d, {1|U, {0x1e7c}}},
+ {0x1e7f, {1|U, {0x1e7e}}},
+ {0x1e81, {1|U, {0x1e80}}},
+ {0x1e83, {1|U, {0x1e82}}},
+ {0x1e85, {1|U, {0x1e84}}},
+ {0x1e87, {1|U, {0x1e86}}},
+ {0x1e89, {1|U, {0x1e88}}},
+ {0x1e8b, {1|U, {0x1e8a}}},
+ {0x1e8d, {1|U, {0x1e8c}}},
+ {0x1e8f, {1|U, {0x1e8e}}},
+ {0x1e91, {1|U, {0x1e90}}},
+ {0x1e93, {1|U, {0x1e92}}},
+ {0x1e95, {1|U, {0x1e94}}},
+ {0x1ea1, {1|U, {0x1ea0}}},
+ {0x1ea3, {1|U, {0x1ea2}}},
+ {0x1ea5, {1|U, {0x1ea4}}},
+ {0x1ea7, {1|U, {0x1ea6}}},
+ {0x1ea9, {1|U, {0x1ea8}}},
+ {0x1eab, {1|U, {0x1eaa}}},
+ {0x1ead, {1|U, {0x1eac}}},
+ {0x1eaf, {1|U, {0x1eae}}},
+ {0x1eb1, {1|U, {0x1eb0}}},
+ {0x1eb3, {1|U, {0x1eb2}}},
+ {0x1eb5, {1|U, {0x1eb4}}},
+ {0x1eb7, {1|U, {0x1eb6}}},
+ {0x1eb9, {1|U, {0x1eb8}}},
+ {0x1ebb, {1|U, {0x1eba}}},
+ {0x1ebd, {1|U, {0x1ebc}}},
+ {0x1ebf, {1|U, {0x1ebe}}},
+ {0x1ec1, {1|U, {0x1ec0}}},
+ {0x1ec3, {1|U, {0x1ec2}}},
+ {0x1ec5, {1|U, {0x1ec4}}},
+ {0x1ec7, {1|U, {0x1ec6}}},
+ {0x1ec9, {1|U, {0x1ec8}}},
+ {0x1ecb, {1|U, {0x1eca}}},
+ {0x1ecd, {1|U, {0x1ecc}}},
+ {0x1ecf, {1|U, {0x1ece}}},
+ {0x1ed1, {1|U, {0x1ed0}}},
+ {0x1ed3, {1|U, {0x1ed2}}},
+ {0x1ed5, {1|U, {0x1ed4}}},
+ {0x1ed7, {1|U, {0x1ed6}}},
+ {0x1ed9, {1|U, {0x1ed8}}},
+ {0x1edb, {1|U, {0x1eda}}},
+ {0x1edd, {1|U, {0x1edc}}},
+ {0x1edf, {1|U, {0x1ede}}},
+ {0x1ee1, {1|U, {0x1ee0}}},
+ {0x1ee3, {1|U, {0x1ee2}}},
+ {0x1ee5, {1|U, {0x1ee4}}},
+ {0x1ee7, {1|U, {0x1ee6}}},
+ {0x1ee9, {1|U, {0x1ee8}}},
+ {0x1eeb, {1|U, {0x1eea}}},
+ {0x1eed, {1|U, {0x1eec}}},
+ {0x1eef, {1|U, {0x1eee}}},
+ {0x1ef1, {1|U, {0x1ef0}}},
+ {0x1ef3, {1|U, {0x1ef2}}},
+ {0x1ef5, {1|U, {0x1ef4}}},
+ {0x1ef7, {1|U, {0x1ef6}}},
+ {0x1ef9, {1|U, {0x1ef8}}},
+ {0x1efb, {1|U, {0x1efa}}},
+ {0x1efd, {1|U, {0x1efc}}},
+ {0x1eff, {1|U, {0x1efe}}},
+ {0x1f00, {1|U, {0x1f08}}},
+ {0x1f01, {1|U, {0x1f09}}},
+ {0x1f02, {1|U, {0x1f0a}}},
+ {0x1f03, {1|U, {0x1f0b}}},
+ {0x1f04, {1|U, {0x1f0c}}},
+ {0x1f05, {1|U, {0x1f0d}}},
+ {0x1f06, {1|U, {0x1f0e}}},
+ {0x1f07, {1|U, {0x1f0f}}},
+ {0x1f10, {1|U, {0x1f18}}},
+ {0x1f11, {1|U, {0x1f19}}},
+ {0x1f12, {1|U, {0x1f1a}}},
+ {0x1f13, {1|U, {0x1f1b}}},
+ {0x1f14, {1|U, {0x1f1c}}},
+ {0x1f15, {1|U, {0x1f1d}}},
+ {0x1f20, {1|U, {0x1f28}}},
+ {0x1f21, {1|U, {0x1f29}}},
+ {0x1f22, {1|U, {0x1f2a}}},
+ {0x1f23, {1|U, {0x1f2b}}},
+ {0x1f24, {1|U, {0x1f2c}}},
+ {0x1f25, {1|U, {0x1f2d}}},
+ {0x1f26, {1|U, {0x1f2e}}},
+ {0x1f27, {1|U, {0x1f2f}}},
+ {0x1f30, {1|U, {0x1f38}}},
+ {0x1f31, {1|U, {0x1f39}}},
+ {0x1f32, {1|U, {0x1f3a}}},
+ {0x1f33, {1|U, {0x1f3b}}},
+ {0x1f34, {1|U, {0x1f3c}}},
+ {0x1f35, {1|U, {0x1f3d}}},
+ {0x1f36, {1|U, {0x1f3e}}},
+ {0x1f37, {1|U, {0x1f3f}}},
+ {0x1f40, {1|U, {0x1f48}}},
+ {0x1f41, {1|U, {0x1f49}}},
+ {0x1f42, {1|U, {0x1f4a}}},
+ {0x1f43, {1|U, {0x1f4b}}},
+ {0x1f44, {1|U, {0x1f4c}}},
+ {0x1f45, {1|U, {0x1f4d}}},
+ {0x1f51, {1|U, {0x1f59}}},
+ {0x1f53, {1|U, {0x1f5b}}},
+ {0x1f55, {1|U, {0x1f5d}}},
+ {0x1f57, {1|U, {0x1f5f}}},
+ {0x1f60, {1|U, {0x1f68}}},
+ {0x1f61, {1|U, {0x1f69}}},
+ {0x1f62, {1|U, {0x1f6a}}},
+ {0x1f63, {1|U, {0x1f6b}}},
+ {0x1f64, {1|U, {0x1f6c}}},
+ {0x1f65, {1|U, {0x1f6d}}},
+ {0x1f66, {1|U, {0x1f6e}}},
+ {0x1f67, {1|U, {0x1f6f}}},
+ {0x1f70, {1|U, {0x1fba}}},
+ {0x1f71, {1|U, {0x1fbb}}},
+ {0x1f72, {1|U, {0x1fc8}}},
+ {0x1f73, {1|U, {0x1fc9}}},
+ {0x1f74, {1|U, {0x1fca}}},
+ {0x1f75, {1|U, {0x1fcb}}},
+ {0x1f76, {1|U, {0x1fda}}},
+ {0x1f77, {1|U, {0x1fdb}}},
+ {0x1f78, {1|U, {0x1ff8}}},
+ {0x1f79, {1|U, {0x1ff9}}},
+ {0x1f7a, {1|U, {0x1fea}}},
+ {0x1f7b, {1|U, {0x1feb}}},
+ {0x1f7c, {1|U, {0x1ffa}}},
+ {0x1f7d, {1|U, {0x1ffb}}},
+ {0x1fb0, {1|U, {0x1fb8}}},
+ {0x1fb1, {1|U, {0x1fb9}}},
+ {0x1fd0, {1|U, {0x1fd8}}},
+ {0x1fd1, {1|U, {0x1fd9}}},
+ {0x1fe0, {1|U, {0x1fe8}}},
+ {0x1fe1, {1|U, {0x1fe9}}},
+ {0x1fe5, {1|U, {0x1fec}}},
+ {0x214e, {1|U, {0x2132}}},
+ {0x2170, {1|U, {0x2160}}},
+ {0x2171, {1|U, {0x2161}}},
+ {0x2172, {1|U, {0x2162}}},
+ {0x2173, {1|U, {0x2163}}},
+ {0x2174, {1|U, {0x2164}}},
+ {0x2175, {1|U, {0x2165}}},
+ {0x2176, {1|U, {0x2166}}},
+ {0x2177, {1|U, {0x2167}}},
+ {0x2178, {1|U, {0x2168}}},
+ {0x2179, {1|U, {0x2169}}},
+ {0x217a, {1|U, {0x216a}}},
+ {0x217b, {1|U, {0x216b}}},
+ {0x217c, {1|U, {0x216c}}},
+ {0x217d, {1|U, {0x216d}}},
+ {0x217e, {1|U, {0x216e}}},
+ {0x217f, {1|U, {0x216f}}},
+ {0x2184, {1|U, {0x2183}}},
+ {0x24d0, {1|U, {0x24b6}}},
+ {0x24d1, {1|U, {0x24b7}}},
+ {0x24d2, {1|U, {0x24b8}}},
+ {0x24d3, {1|U, {0x24b9}}},
+ {0x24d4, {1|U, {0x24ba}}},
+ {0x24d5, {1|U, {0x24bb}}},
+ {0x24d6, {1|U, {0x24bc}}},
+ {0x24d7, {1|U, {0x24bd}}},
+ {0x24d8, {1|U, {0x24be}}},
+ {0x24d9, {1|U, {0x24bf}}},
+ {0x24da, {1|U, {0x24c0}}},
+ {0x24db, {1|U, {0x24c1}}},
+ {0x24dc, {1|U, {0x24c2}}},
+ {0x24dd, {1|U, {0x24c3}}},
+ {0x24de, {1|U, {0x24c4}}},
+ {0x24df, {1|U, {0x24c5}}},
+ {0x24e0, {1|U, {0x24c6}}},
+ {0x24e1, {1|U, {0x24c7}}},
+ {0x24e2, {1|U, {0x24c8}}},
+ {0x24e3, {1|U, {0x24c9}}},
+ {0x24e4, {1|U, {0x24ca}}},
+ {0x24e5, {1|U, {0x24cb}}},
+ {0x24e6, {1|U, {0x24cc}}},
+ {0x24e7, {1|U, {0x24cd}}},
+ {0x24e8, {1|U, {0x24ce}}},
+ {0x24e9, {1|U, {0x24cf}}},
+ {0x2c30, {1|U, {0x2c00}}},
+ {0x2c31, {1|U, {0x2c01}}},
+ {0x2c32, {1|U, {0x2c02}}},
+ {0x2c33, {1|U, {0x2c03}}},
+ {0x2c34, {1|U, {0x2c04}}},
+ {0x2c35, {1|U, {0x2c05}}},
+ {0x2c36, {1|U, {0x2c06}}},
+ {0x2c37, {1|U, {0x2c07}}},
+ {0x2c38, {1|U, {0x2c08}}},
+ {0x2c39, {1|U, {0x2c09}}},
+ {0x2c3a, {1|U, {0x2c0a}}},
+ {0x2c3b, {1|U, {0x2c0b}}},
+ {0x2c3c, {1|U, {0x2c0c}}},
+ {0x2c3d, {1|U, {0x2c0d}}},
+ {0x2c3e, {1|U, {0x2c0e}}},
+ {0x2c3f, {1|U, {0x2c0f}}},
+ {0x2c40, {1|U, {0x2c10}}},
+ {0x2c41, {1|U, {0x2c11}}},
+ {0x2c42, {1|U, {0x2c12}}},
+ {0x2c43, {1|U, {0x2c13}}},
+ {0x2c44, {1|U, {0x2c14}}},
+ {0x2c45, {1|U, {0x2c15}}},
+ {0x2c46, {1|U, {0x2c16}}},
+ {0x2c47, {1|U, {0x2c17}}},
+ {0x2c48, {1|U, {0x2c18}}},
+ {0x2c49, {1|U, {0x2c19}}},
+ {0x2c4a, {1|U, {0x2c1a}}},
+ {0x2c4b, {1|U, {0x2c1b}}},
+ {0x2c4c, {1|U, {0x2c1c}}},
+ {0x2c4d, {1|U, {0x2c1d}}},
+ {0x2c4e, {1|U, {0x2c1e}}},
+ {0x2c4f, {1|U, {0x2c1f}}},
+ {0x2c50, {1|U, {0x2c20}}},
+ {0x2c51, {1|U, {0x2c21}}},
+ {0x2c52, {1|U, {0x2c22}}},
+ {0x2c53, {1|U, {0x2c23}}},
+ {0x2c54, {1|U, {0x2c24}}},
+ {0x2c55, {1|U, {0x2c25}}},
+ {0x2c56, {1|U, {0x2c26}}},
+ {0x2c57, {1|U, {0x2c27}}},
+ {0x2c58, {1|U, {0x2c28}}},
+ {0x2c59, {1|U, {0x2c29}}},
+ {0x2c5a, {1|U, {0x2c2a}}},
+ {0x2c5b, {1|U, {0x2c2b}}},
+ {0x2c5c, {1|U, {0x2c2c}}},
+ {0x2c5d, {1|U, {0x2c2d}}},
+ {0x2c5e, {1|U, {0x2c2e}}},
+ {0x2c61, {1|U, {0x2c60}}},
+ {0x2c65, {1|U, {0x023a}}},
+ {0x2c66, {1|U, {0x023e}}},
+ {0x2c68, {1|U, {0x2c67}}},
+ {0x2c6a, {1|U, {0x2c69}}},
+ {0x2c6c, {1|U, {0x2c6b}}},
+ {0x2c73, {1|U, {0x2c72}}},
+ {0x2c76, {1|U, {0x2c75}}},
+ {0x2c81, {1|U, {0x2c80}}},
+ {0x2c83, {1|U, {0x2c82}}},
+ {0x2c85, {1|U, {0x2c84}}},
+ {0x2c87, {1|U, {0x2c86}}},
+ {0x2c89, {1|U, {0x2c88}}},
+ {0x2c8b, {1|U, {0x2c8a}}},
+ {0x2c8d, {1|U, {0x2c8c}}},
+ {0x2c8f, {1|U, {0x2c8e}}},
+ {0x2c91, {1|U, {0x2c90}}},
+ {0x2c93, {1|U, {0x2c92}}},
+ {0x2c95, {1|U, {0x2c94}}},
+ {0x2c97, {1|U, {0x2c96}}},
+ {0x2c99, {1|U, {0x2c98}}},
+ {0x2c9b, {1|U, {0x2c9a}}},
+ {0x2c9d, {1|U, {0x2c9c}}},
+ {0x2c9f, {1|U, {0x2c9e}}},
+ {0x2ca1, {1|U, {0x2ca0}}},
+ {0x2ca3, {1|U, {0x2ca2}}},
+ {0x2ca5, {1|U, {0x2ca4}}},
+ {0x2ca7, {1|U, {0x2ca6}}},
+ {0x2ca9, {1|U, {0x2ca8}}},
+ {0x2cab, {1|U, {0x2caa}}},
+ {0x2cad, {1|U, {0x2cac}}},
+ {0x2caf, {1|U, {0x2cae}}},
+ {0x2cb1, {1|U, {0x2cb0}}},
+ {0x2cb3, {1|U, {0x2cb2}}},
+ {0x2cb5, {1|U, {0x2cb4}}},
+ {0x2cb7, {1|U, {0x2cb6}}},
+ {0x2cb9, {1|U, {0x2cb8}}},
+ {0x2cbb, {1|U, {0x2cba}}},
+ {0x2cbd, {1|U, {0x2cbc}}},
+ {0x2cbf, {1|U, {0x2cbe}}},
+ {0x2cc1, {1|U, {0x2cc0}}},
+ {0x2cc3, {1|U, {0x2cc2}}},
+ {0x2cc5, {1|U, {0x2cc4}}},
+ {0x2cc7, {1|U, {0x2cc6}}},
+ {0x2cc9, {1|U, {0x2cc8}}},
+ {0x2ccb, {1|U, {0x2cca}}},
+ {0x2ccd, {1|U, {0x2ccc}}},
+ {0x2ccf, {1|U, {0x2cce}}},
+ {0x2cd1, {1|U, {0x2cd0}}},
+ {0x2cd3, {1|U, {0x2cd2}}},
+ {0x2cd5, {1|U, {0x2cd4}}},
+ {0x2cd7, {1|U, {0x2cd6}}},
+ {0x2cd9, {1|U, {0x2cd8}}},
+ {0x2cdb, {1|U, {0x2cda}}},
+ {0x2cdd, {1|U, {0x2cdc}}},
+ {0x2cdf, {1|U, {0x2cde}}},
+ {0x2ce1, {1|U, {0x2ce0}}},
+ {0x2ce3, {1|U, {0x2ce2}}},
+ {0x2cec, {1|U, {0x2ceb}}},
+ {0x2cee, {1|U, {0x2ced}}},
+ {0x2cf3, {1|U, {0x2cf2}}},
+ {0x2d00, {1|U, {0x10a0}}},
+ {0x2d01, {1|U, {0x10a1}}},
+ {0x2d02, {1|U, {0x10a2}}},
+ {0x2d03, {1|U, {0x10a3}}},
+ {0x2d04, {1|U, {0x10a4}}},
+ {0x2d05, {1|U, {0x10a5}}},
+ {0x2d06, {1|U, {0x10a6}}},
+ {0x2d07, {1|U, {0x10a7}}},
+ {0x2d08, {1|U, {0x10a8}}},
+ {0x2d09, {1|U, {0x10a9}}},
+ {0x2d0a, {1|U, {0x10aa}}},
+ {0x2d0b, {1|U, {0x10ab}}},
+ {0x2d0c, {1|U, {0x10ac}}},
+ {0x2d0d, {1|U, {0x10ad}}},
+ {0x2d0e, {1|U, {0x10ae}}},
+ {0x2d0f, {1|U, {0x10af}}},
+ {0x2d10, {1|U, {0x10b0}}},
+ {0x2d11, {1|U, {0x10b1}}},
+ {0x2d12, {1|U, {0x10b2}}},
+ {0x2d13, {1|U, {0x10b3}}},
+ {0x2d14, {1|U, {0x10b4}}},
+ {0x2d15, {1|U, {0x10b5}}},
+ {0x2d16, {1|U, {0x10b6}}},
+ {0x2d17, {1|U, {0x10b7}}},
+ {0x2d18, {1|U, {0x10b8}}},
+ {0x2d19, {1|U, {0x10b9}}},
+ {0x2d1a, {1|U, {0x10ba}}},
+ {0x2d1b, {1|U, {0x10bb}}},
+ {0x2d1c, {1|U, {0x10bc}}},
+ {0x2d1d, {1|U, {0x10bd}}},
+ {0x2d1e, {1|U, {0x10be}}},
+ {0x2d1f, {1|U, {0x10bf}}},
+ {0x2d20, {1|U, {0x10c0}}},
+ {0x2d21, {1|U, {0x10c1}}},
+ {0x2d22, {1|U, {0x10c2}}},
+ {0x2d23, {1|U, {0x10c3}}},
+ {0x2d24, {1|U, {0x10c4}}},
+ {0x2d25, {1|U, {0x10c5}}},
+ {0x2d27, {1|U, {0x10c7}}},
+ {0x2d2d, {1|U, {0x10cd}}},
+ {0xa641, {1|U, {0xa640}}},
+ {0xa643, {1|U, {0xa642}}},
+ {0xa645, {1|U, {0xa644}}},
+ {0xa647, {1|U, {0xa646}}},
+ {0xa649, {1|U, {0xa648}}},
+ {0xa64b, {2|U, {0xa64a, 0x1c88}}},
+ {0xa64d, {1|U, {0xa64c}}},
+ {0xa64f, {1|U, {0xa64e}}},
+ {0xa651, {1|U, {0xa650}}},
+ {0xa653, {1|U, {0xa652}}},
+ {0xa655, {1|U, {0xa654}}},
+ {0xa657, {1|U, {0xa656}}},
+ {0xa659, {1|U, {0xa658}}},
+ {0xa65b, {1|U, {0xa65a}}},
+ {0xa65d, {1|U, {0xa65c}}},
+ {0xa65f, {1|U, {0xa65e}}},
+ {0xa661, {1|U, {0xa660}}},
+ {0xa663, {1|U, {0xa662}}},
+ {0xa665, {1|U, {0xa664}}},
+ {0xa667, {1|U, {0xa666}}},
+ {0xa669, {1|U, {0xa668}}},
+ {0xa66b, {1|U, {0xa66a}}},
+ {0xa66d, {1|U, {0xa66c}}},
+ {0xa681, {1|U, {0xa680}}},
+ {0xa683, {1|U, {0xa682}}},
+ {0xa685, {1|U, {0xa684}}},
+ {0xa687, {1|U, {0xa686}}},
+ {0xa689, {1|U, {0xa688}}},
+ {0xa68b, {1|U, {0xa68a}}},
+ {0xa68d, {1|U, {0xa68c}}},
+ {0xa68f, {1|U, {0xa68e}}},
+ {0xa691, {1|U, {0xa690}}},
+ {0xa693, {1|U, {0xa692}}},
+ {0xa695, {1|U, {0xa694}}},
+ {0xa697, {1|U, {0xa696}}},
+ {0xa699, {1|U, {0xa698}}},
+ {0xa69b, {1|U, {0xa69a}}},
+ {0xa723, {1|U, {0xa722}}},
+ {0xa725, {1|U, {0xa724}}},
+ {0xa727, {1|U, {0xa726}}},
+ {0xa729, {1|U, {0xa728}}},
+ {0xa72b, {1|U, {0xa72a}}},
+ {0xa72d, {1|U, {0xa72c}}},
+ {0xa72f, {1|U, {0xa72e}}},
+ {0xa733, {1|U, {0xa732}}},
+ {0xa735, {1|U, {0xa734}}},
+ {0xa737, {1|U, {0xa736}}},
+ {0xa739, {1|U, {0xa738}}},
+ {0xa73b, {1|U, {0xa73a}}},
+ {0xa73d, {1|U, {0xa73c}}},
+ {0xa73f, {1|U, {0xa73e}}},
+ {0xa741, {1|U, {0xa740}}},
+ {0xa743, {1|U, {0xa742}}},
+ {0xa745, {1|U, {0xa744}}},
+ {0xa747, {1|U, {0xa746}}},
+ {0xa749, {1|U, {0xa748}}},
+ {0xa74b, {1|U, {0xa74a}}},
+ {0xa74d, {1|U, {0xa74c}}},
+ {0xa74f, {1|U, {0xa74e}}},
+ {0xa751, {1|U, {0xa750}}},
+ {0xa753, {1|U, {0xa752}}},
+ {0xa755, {1|U, {0xa754}}},
+ {0xa757, {1|U, {0xa756}}},
+ {0xa759, {1|U, {0xa758}}},
+ {0xa75b, {1|U, {0xa75a}}},
+ {0xa75d, {1|U, {0xa75c}}},
+ {0xa75f, {1|U, {0xa75e}}},
+ {0xa761, {1|U, {0xa760}}},
+ {0xa763, {1|U, {0xa762}}},
+ {0xa765, {1|U, {0xa764}}},
+ {0xa767, {1|U, {0xa766}}},
+ {0xa769, {1|U, {0xa768}}},
+ {0xa76b, {1|U, {0xa76a}}},
+ {0xa76d, {1|U, {0xa76c}}},
+ {0xa76f, {1|U, {0xa76e}}},
+ {0xa77a, {1|U, {0xa779}}},
+ {0xa77c, {1|U, {0xa77b}}},
+ {0xa77f, {1|U, {0xa77e}}},
+ {0xa781, {1|U, {0xa780}}},
+ {0xa783, {1|U, {0xa782}}},
+ {0xa785, {1|U, {0xa784}}},
+ {0xa787, {1|U, {0xa786}}},
+ {0xa78c, {1|U, {0xa78b}}},
+ {0xa791, {1|U, {0xa790}}},
+ {0xa793, {1|U, {0xa792}}},
+ {0xa794, {1|U, {0xa7c4}}},
+ {0xa797, {1|U, {0xa796}}},
+ {0xa799, {1|U, {0xa798}}},
+ {0xa79b, {1|U, {0xa79a}}},
+ {0xa79d, {1|U, {0xa79c}}},
+ {0xa79f, {1|U, {0xa79e}}},
+ {0xa7a1, {1|U, {0xa7a0}}},
+ {0xa7a3, {1|U, {0xa7a2}}},
+ {0xa7a5, {1|U, {0xa7a4}}},
+ {0xa7a7, {1|U, {0xa7a6}}},
+ {0xa7a9, {1|U, {0xa7a8}}},
+ {0xa7b5, {1|U, {0xa7b4}}},
+ {0xa7b7, {1|U, {0xa7b6}}},
+ {0xa7b9, {1|U, {0xa7b8}}},
+ {0xa7bb, {1|U, {0xa7ba}}},
+ {0xa7bd, {1|U, {0xa7bc}}},
+ {0xa7bf, {1|U, {0xa7be}}},
+ {0xa7c3, {1|U, {0xa7c2}}},
+ {0xab53, {1|U, {0xa7b3}}},
+ {0xff41, {1|U, {0xff21}}},
+ {0xff42, {1|U, {0xff22}}},
+ {0xff43, {1|U, {0xff23}}},
+ {0xff44, {1|U, {0xff24}}},
+ {0xff45, {1|U, {0xff25}}},
+ {0xff46, {1|U, {0xff26}}},
+ {0xff47, {1|U, {0xff27}}},
+ {0xff48, {1|U, {0xff28}}},
+ {0xff49, {1|U, {0xff29}}},
+ {0xff4a, {1|U, {0xff2a}}},
+ {0xff4b, {1|U, {0xff2b}}},
+ {0xff4c, {1|U, {0xff2c}}},
+ {0xff4d, {1|U, {0xff2d}}},
+ {0xff4e, {1|U, {0xff2e}}},
+ {0xff4f, {1|U, {0xff2f}}},
+ {0xff50, {1|U, {0xff30}}},
+ {0xff51, {1|U, {0xff31}}},
+ {0xff52, {1|U, {0xff32}}},
+ {0xff53, {1|U, {0xff33}}},
+ {0xff54, {1|U, {0xff34}}},
+ {0xff55, {1|U, {0xff35}}},
+ {0xff56, {1|U, {0xff36}}},
+ {0xff57, {1|U, {0xff37}}},
+ {0xff58, {1|U, {0xff38}}},
+ {0xff59, {1|U, {0xff39}}},
+ {0xff5a, {1|U, {0xff3a}}},
+ {0x10428, {1|U, {0x10400}}},
+ {0x10429, {1|U, {0x10401}}},
+ {0x1042a, {1|U, {0x10402}}},
+ {0x1042b, {1|U, {0x10403}}},
+ {0x1042c, {1|U, {0x10404}}},
+ {0x1042d, {1|U, {0x10405}}},
+ {0x1042e, {1|U, {0x10406}}},
+ {0x1042f, {1|U, {0x10407}}},
+ {0x10430, {1|U, {0x10408}}},
+ {0x10431, {1|U, {0x10409}}},
+ {0x10432, {1|U, {0x1040a}}},
+ {0x10433, {1|U, {0x1040b}}},
+ {0x10434, {1|U, {0x1040c}}},
+ {0x10435, {1|U, {0x1040d}}},
+ {0x10436, {1|U, {0x1040e}}},
+ {0x10437, {1|U, {0x1040f}}},
+ {0x10438, {1|U, {0x10410}}},
+ {0x10439, {1|U, {0x10411}}},
+ {0x1043a, {1|U, {0x10412}}},
+ {0x1043b, {1|U, {0x10413}}},
+ {0x1043c, {1|U, {0x10414}}},
+ {0x1043d, {1|U, {0x10415}}},
+ {0x1043e, {1|U, {0x10416}}},
+ {0x1043f, {1|U, {0x10417}}},
+ {0x10440, {1|U, {0x10418}}},
+ {0x10441, {1|U, {0x10419}}},
+ {0x10442, {1|U, {0x1041a}}},
+ {0x10443, {1|U, {0x1041b}}},
+ {0x10444, {1|U, {0x1041c}}},
+ {0x10445, {1|U, {0x1041d}}},
+ {0x10446, {1|U, {0x1041e}}},
+ {0x10447, {1|U, {0x1041f}}},
+ {0x10448, {1|U, {0x10420}}},
+ {0x10449, {1|U, {0x10421}}},
+ {0x1044a, {1|U, {0x10422}}},
+ {0x1044b, {1|U, {0x10423}}},
+ {0x1044c, {1|U, {0x10424}}},
+ {0x1044d, {1|U, {0x10425}}},
+ {0x1044e, {1|U, {0x10426}}},
+ {0x1044f, {1|U, {0x10427}}},
+ {0x104d8, {1|U, {0x104b0}}},
+ {0x104d9, {1|U, {0x104b1}}},
+ {0x104da, {1|U, {0x104b2}}},
+ {0x104db, {1|U, {0x104b3}}},
+ {0x104dc, {1|U, {0x104b4}}},
+ {0x104dd, {1|U, {0x104b5}}},
+ {0x104de, {1|U, {0x104b6}}},
+ {0x104df, {1|U, {0x104b7}}},
+ {0x104e0, {1|U, {0x104b8}}},
+ {0x104e1, {1|U, {0x104b9}}},
+ {0x104e2, {1|U, {0x104ba}}},
+ {0x104e3, {1|U, {0x104bb}}},
+ {0x104e4, {1|U, {0x104bc}}},
+ {0x104e5, {1|U, {0x104bd}}},
+ {0x104e6, {1|U, {0x104be}}},
+ {0x104e7, {1|U, {0x104bf}}},
+ {0x104e8, {1|U, {0x104c0}}},
+ {0x104e9, {1|U, {0x104c1}}},
+ {0x104ea, {1|U, {0x104c2}}},
+ {0x104eb, {1|U, {0x104c3}}},
+ {0x104ec, {1|U, {0x104c4}}},
+ {0x104ed, {1|U, {0x104c5}}},
+ {0x104ee, {1|U, {0x104c6}}},
+ {0x104ef, {1|U, {0x104c7}}},
+ {0x104f0, {1|U, {0x104c8}}},
+ {0x104f1, {1|U, {0x104c9}}},
+ {0x104f2, {1|U, {0x104ca}}},
+ {0x104f3, {1|U, {0x104cb}}},
+ {0x104f4, {1|U, {0x104cc}}},
+ {0x104f5, {1|U, {0x104cd}}},
+ {0x104f6, {1|U, {0x104ce}}},
+ {0x104f7, {1|U, {0x104cf}}},
+ {0x104f8, {1|U, {0x104d0}}},
+ {0x104f9, {1|U, {0x104d1}}},
+ {0x104fa, {1|U, {0x104d2}}},
+ {0x104fb, {1|U, {0x104d3}}},
+ {0x10cc0, {1|U, {0x10c80}}},
+ {0x10cc1, {1|U, {0x10c81}}},
+ {0x10cc2, {1|U, {0x10c82}}},
+ {0x10cc3, {1|U, {0x10c83}}},
+ {0x10cc4, {1|U, {0x10c84}}},
+ {0x10cc5, {1|U, {0x10c85}}},
+ {0x10cc6, {1|U, {0x10c86}}},
+ {0x10cc7, {1|U, {0x10c87}}},
+ {0x10cc8, {1|U, {0x10c88}}},
+ {0x10cc9, {1|U, {0x10c89}}},
+ {0x10cca, {1|U, {0x10c8a}}},
+ {0x10ccb, {1|U, {0x10c8b}}},
+ {0x10ccc, {1|U, {0x10c8c}}},
+ {0x10ccd, {1|U, {0x10c8d}}},
+ {0x10cce, {1|U, {0x10c8e}}},
+ {0x10ccf, {1|U, {0x10c8f}}},
+ {0x10cd0, {1|U, {0x10c90}}},
+ {0x10cd1, {1|U, {0x10c91}}},
+ {0x10cd2, {1|U, {0x10c92}}},
+ {0x10cd3, {1|U, {0x10c93}}},
+ {0x10cd4, {1|U, {0x10c94}}},
+ {0x10cd5, {1|U, {0x10c95}}},
+ {0x10cd6, {1|U, {0x10c96}}},
+ {0x10cd7, {1|U, {0x10c97}}},
+ {0x10cd8, {1|U, {0x10c98}}},
+ {0x10cd9, {1|U, {0x10c99}}},
+ {0x10cda, {1|U, {0x10c9a}}},
+ {0x10cdb, {1|U, {0x10c9b}}},
+ {0x10cdc, {1|U, {0x10c9c}}},
+ {0x10cdd, {1|U, {0x10c9d}}},
+ {0x10cde, {1|U, {0x10c9e}}},
+ {0x10cdf, {1|U, {0x10c9f}}},
+ {0x10ce0, {1|U, {0x10ca0}}},
+ {0x10ce1, {1|U, {0x10ca1}}},
+ {0x10ce2, {1|U, {0x10ca2}}},
+ {0x10ce3, {1|U, {0x10ca3}}},
+ {0x10ce4, {1|U, {0x10ca4}}},
+ {0x10ce5, {1|U, {0x10ca5}}},
+ {0x10ce6, {1|U, {0x10ca6}}},
+ {0x10ce7, {1|U, {0x10ca7}}},
+ {0x10ce8, {1|U, {0x10ca8}}},
+ {0x10ce9, {1|U, {0x10ca9}}},
+ {0x10cea, {1|U, {0x10caa}}},
+ {0x10ceb, {1|U, {0x10cab}}},
+ {0x10cec, {1|U, {0x10cac}}},
+ {0x10ced, {1|U, {0x10cad}}},
+ {0x10cee, {1|U, {0x10cae}}},
+ {0x10cef, {1|U, {0x10caf}}},
+ {0x10cf0, {1|U, {0x10cb0}}},
+ {0x10cf1, {1|U, {0x10cb1}}},
+ {0x10cf2, {1|U, {0x10cb2}}},
+ {0x118c0, {1|U, {0x118a0}}},
+ {0x118c1, {1|U, {0x118a1}}},
+ {0x118c2, {1|U, {0x118a2}}},
+ {0x118c3, {1|U, {0x118a3}}},
+ {0x118c4, {1|U, {0x118a4}}},
+ {0x118c5, {1|U, {0x118a5}}},
+ {0x118c6, {1|U, {0x118a6}}},
+ {0x118c7, {1|U, {0x118a7}}},
+ {0x118c8, {1|U, {0x118a8}}},
+ {0x118c9, {1|U, {0x118a9}}},
+ {0x118ca, {1|U, {0x118aa}}},
+ {0x118cb, {1|U, {0x118ab}}},
+ {0x118cc, {1|U, {0x118ac}}},
+ {0x118cd, {1|U, {0x118ad}}},
+ {0x118ce, {1|U, {0x118ae}}},
+ {0x118cf, {1|U, {0x118af}}},
+ {0x118d0, {1|U, {0x118b0}}},
+ {0x118d1, {1|U, {0x118b1}}},
+ {0x118d2, {1|U, {0x118b2}}},
+ {0x118d3, {1|U, {0x118b3}}},
+ {0x118d4, {1|U, {0x118b4}}},
+ {0x118d5, {1|U, {0x118b5}}},
+ {0x118d6, {1|U, {0x118b6}}},
+ {0x118d7, {1|U, {0x118b7}}},
+ {0x118d8, {1|U, {0x118b8}}},
+ {0x118d9, {1|U, {0x118b9}}},
+ {0x118da, {1|U, {0x118ba}}},
+ {0x118db, {1|U, {0x118bb}}},
+ {0x118dc, {1|U, {0x118bc}}},
+ {0x118dd, {1|U, {0x118bd}}},
+ {0x118de, {1|U, {0x118be}}},
+ {0x118df, {1|U, {0x118bf}}},
+ {0x16e60, {1|U, {0x16e40}}},
+ {0x16e61, {1|U, {0x16e41}}},
+ {0x16e62, {1|U, {0x16e42}}},
+ {0x16e63, {1|U, {0x16e43}}},
+ {0x16e64, {1|U, {0x16e44}}},
+ {0x16e65, {1|U, {0x16e45}}},
+ {0x16e66, {1|U, {0x16e46}}},
+ {0x16e67, {1|U, {0x16e47}}},
+ {0x16e68, {1|U, {0x16e48}}},
+ {0x16e69, {1|U, {0x16e49}}},
+ {0x16e6a, {1|U, {0x16e4a}}},
+ {0x16e6b, {1|U, {0x16e4b}}},
+ {0x16e6c, {1|U, {0x16e4c}}},
+ {0x16e6d, {1|U, {0x16e4d}}},
+ {0x16e6e, {1|U, {0x16e4e}}},
+ {0x16e6f, {1|U, {0x16e4f}}},
+ {0x16e70, {1|U, {0x16e50}}},
+ {0x16e71, {1|U, {0x16e51}}},
+ {0x16e72, {1|U, {0x16e52}}},
+ {0x16e73, {1|U, {0x16e53}}},
+ {0x16e74, {1|U, {0x16e54}}},
+ {0x16e75, {1|U, {0x16e55}}},
+ {0x16e76, {1|U, {0x16e56}}},
+ {0x16e77, {1|U, {0x16e57}}},
+ {0x16e78, {1|U, {0x16e58}}},
+ {0x16e79, {1|U, {0x16e59}}},
+ {0x16e7a, {1|U, {0x16e5a}}},
+ {0x16e7b, {1|U, {0x16e5b}}},
+ {0x16e7c, {1|U, {0x16e5c}}},
+ {0x16e7d, {1|U, {0x16e5d}}},
+ {0x16e7e, {1|U, {0x16e5e}}},
+ {0x16e7f, {1|U, {0x16e5f}}},
+ {0x1e922, {1|U, {0x1e900}}},
+ {0x1e923, {1|U, {0x1e901}}},
+ {0x1e924, {1|U, {0x1e902}}},
+ {0x1e925, {1|U, {0x1e903}}},
+ {0x1e926, {1|U, {0x1e904}}},
+ {0x1e927, {1|U, {0x1e905}}},
+ {0x1e928, {1|U, {0x1e906}}},
+ {0x1e929, {1|U, {0x1e907}}},
+ {0x1e92a, {1|U, {0x1e908}}},
+ {0x1e92b, {1|U, {0x1e909}}},
+ {0x1e92c, {1|U, {0x1e90a}}},
+ {0x1e92d, {1|U, {0x1e90b}}},
+ {0x1e92e, {1|U, {0x1e90c}}},
+ {0x1e92f, {1|U, {0x1e90d}}},
+ {0x1e930, {1|U, {0x1e90e}}},
+ {0x1e931, {1|U, {0x1e90f}}},
+ {0x1e932, {1|U, {0x1e910}}},
+ {0x1e933, {1|U, {0x1e911}}},
+ {0x1e934, {1|U, {0x1e912}}},
+ {0x1e935, {1|U, {0x1e913}}},
+ {0x1e936, {1|U, {0x1e914}}},
+ {0x1e937, {1|U, {0x1e915}}},
+ {0x1e938, {1|U, {0x1e916}}},
+ {0x1e939, {1|U, {0x1e917}}},
+ {0x1e93a, {1|U, {0x1e918}}},
+ {0x1e93b, {1|U, {0x1e919}}},
+ {0x1e93c, {1|U, {0x1e91a}}},
+ {0x1e93d, {1|U, {0x1e91b}}},
+ {0x1e93e, {1|U, {0x1e91c}}},
+ {0x1e93f, {1|U, {0x1e91d}}},
+ {0x1e940, {1|U, {0x1e91e}}},
+ {0x1e941, {1|U, {0x1e91f}}},
+ {0x1e942, {1|U, {0x1e920}}},
+ {0x1e943, {1|U, {0x1e921}}},
+#define CaseUnfold_11_Locale (*(CaseUnfold_11_Type (*)[1])(CaseUnfold_11_Table+1352))
+ {0x0069, {1|U, {0x0049}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_11_hash -N onigenc_unicode_CaseUnfold_11_lookup -n */
+
+/* maximum key range = 2507, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseUnfold_11_hash(const OnigCodePoint code)
+{
+ static const unsigned short asso_values[] =
+ {
+ 1, 2510, 2, 7, 4, 582, 9, 308, 197, 674,
+ 297, 20, 2, 3, 303, 351, 2510, 2510, 2510, 2510,
+ 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 112,
+ 2510, 2510, 2510, 2510, 2510, 2510, 2510, 120, 2510, 2510,
+ 2510, 2510, 2510, 1, 2510, 2510, 2510, 2510, 2510, 2510,
+ 2510, 2510, 2510, 278, 2510, 2510, 2510, 2510, 2510, 2510,
+ 2510, 2510, 12, 1, 7, 8, 218, 878, 222, 1178,
+ 480, 1102, 54, 1340, 151, 1615, 8, 15, 106, 1607,
+ 225, 854, 87, 490, 44, 1351, 5, 1281, 3, 1470,
+ 11, 1215, 377, 10, 441, 599, 152, 1642, 127, 1334,
+ 702, 841, 594, 827, 123, 916, 146, 1118, 117, 1363,
+ 254, 812, 249, 1096, 1630, 945, 437, 745, 1600, 718,
+ 1593, 704, 152, 1005, 383, 1064, 1493, 975, 236, 676,
+ 761, 579, 1017, 557, 1241, 628, 1195, 614, 1506, 464,
+ 1576, 535, 1432, 513, 1159, 423, 1026, 276, 1460, 291,
+ 1453, 392, 1263, 201, 1442, 85, 1412, 70, 1430, 100,
+ 1632, 129, 1410, 1, 1386, 25, 1373, 35, 656, 55,
+ 1188, 45, 1308, 160, 687, 227, 355, 175, 1201, 328,
+ 1030, 367, 1483, 414, 1479, 1166, 1418, 783, 994, 937,
+ 1083, 959, 1463, 967
+ };
+ return asso_values[bits_of(code, 2)+66] + asso_values[bits_of(code, 1)+4] + asso_values[bits_of(code, 0)];
+}
+
+static const CodePointList3 *
+onigenc_unicode_CaseUnfold_11_lookup(const OnigCodePoint code)
+{
+ enum
+ {
+ MIN_CODE_VALUE = 0x61,
+ MAX_CODE_VALUE = 0x1e943,
+ TOTAL_KEYWORDS = 1353,
+ MIN_WORD_LENGTH = 3,
+ MAX_WORD_LENGTH = 3,
+ MIN_HASH_VALUE = 3,
+ MAX_HASH_VALUE = 2509
+ };
+
+ static const short wordlist[] =
+ {
+ -1, -1, -1,
+ /*0x13e1*/ 589,
+ /*0x0461*/ 340,
+ /*0x04e1*/ 400,
+ /*0x0061*/ 0,
+ -1,
+ /*0x104e1*/ 1176,
+ /*0x1e61*/ 661,
+ /*0x1ee1*/ 720,
+ /*0x0161*/ 102,
+ /*0x2ce1*/ 952,
+ -1,
+ /*0x049b*/ 365,
+ -1, -1,
+ /*0x24e1*/ 840,
+ /*0x1e1b*/ 626,
+ /*0x048b*/ 357,
+ /*0x011b*/ 69,
+ /*0x2c9b*/ 917,
+ /*0x03e1*/ 280,
+ /*0x1e0b*/ 618,
+ /*0x1e8b*/ 682,
+ /*0x010b*/ 61,
+ /*0x2c8b*/ 909,
+ /*0x13e3*/ 591,
+ /*0x0463*/ 341,
+ /*0x04e3*/ 401,
+ /*0x0063*/ 2,
+ -1,
+ /*0x104e3*/ 1178,
+ /*0x1e63*/ 662,
+ /*0x1ee3*/ 721,
+ /*0x0163*/ 103,
+ /*0x2ce3*/ 953,
+ /*0x13e5*/ 593,
+ /*0x0465*/ 342,
+ /*0x04e5*/ 402,
+ /*0x0065*/ 4,
+ /*0x24e3*/ 842,
+ /*0x104e5*/ 1180,
+ /*0x1e65*/ 663,
+ /*0x1ee5*/ 722,
+ /*0x0165*/ 104,
+ /*0x03e3*/ 281,
+ /*0x13e9*/ 597,
+ /*0x0469*/ 344,
+ /*0x04e9*/ 404,
+ /*0x0069*/ 1352,
+ /*0x24e5*/ 844,
+ /*0x104e9*/ 1184,
+ /*0x1e69*/ 665,
+ /*0x1ee9*/ 724,
+ /*0x0169*/ 106,
+ /*0x03e5*/ 282,
+ /*0x13e7*/ 595,
+ /*0x0467*/ 343,
+ /*0x04e7*/ 403,
+ /*0x0067*/ 6,
+ /*0x24e9*/ 848,
+ /*0x104e7*/ 1182,
+ /*0x1e67*/ 664,
+ /*0x1ee7*/ 723,
+ /*0x0167*/ 105,
+ /*0x03e9*/ 284,
+ -1, -1, -1, -1,
+ /*0x24e7*/ 846,
+ /*0x13db*/ 583,
+ /*0x045b*/ 335,
+ /*0x04db*/ 397,
+ -1,
+ /*0x03e7*/ 283,
+ /*0x104db*/ 1170,
+ /*0x1e5b*/ 658,
+ /*0x1edb*/ 717,
+ /*0x015b*/ 99,
+ /*0x2cdb*/ 949,
+ -1, -1, -1, -1,
+ /*0x24db*/ 834,
+ /*0x13d9*/ 581,
+ /*0x0459*/ 333,
+ /*0x04d9*/ 396,
+ /*0xa761*/ 1064,
+ /*0x03db*/ 277,
+ /*0x104d9*/ 1168,
+ /*0x1e59*/ 657,
+ /*0x1ed9*/ 716,
+ /*0x0159*/ 98,
+ /*0x2cd9*/ 948,
+ -1, -1, -1, -1,
+ /*0x24d9*/ 832,
+ /*0x13dd*/ 585,
+ /*0x045d*/ 337,
+ /*0x04dd*/ 398,
+ -1,
+ /*0x03d9*/ 276,
+ /*0x104dd*/ 1172,
+ /*0x1e5d*/ 659,
+ /*0x1edd*/ 718,
+ /*0x015d*/ 100,
+ /*0x2cdd*/ 950,
+ -1, -1,
+ /*0xa763*/ 1065,
+ -1,
+ /*0x24dd*/ 836,
+ /*0x10ce1*/ 1236,
+ -1,
+ /*0x13aa*/ 534,
+ -1,
+ /*0x03dd*/ 278,
+ /*0x10e1*/ 495,
+ /*0x1042a*/ 1129,
+ /*0xa765*/ 1066,
+ /*0x13a6*/ 530,
+ -1, -1, -1,
+ /*0x13a0*/ 524,
+ -1,
+ /*0x13df*/ 587,
+ /*0x045f*/ 339,
+ /*0x04df*/ 399,
+ /*0xa769*/ 1068,
+ -1,
+ /*0x104df*/ 1174,
+ /*0x1e5f*/ 660,
+ /*0x1edf*/ 719,
+ /*0x015f*/ 101,
+ /*0x2cdf*/ 951,
+ /*0x10ce3*/ 1238,
+ -1, -1,
+ /*0xa767*/ 1067,
+ /*0x24df*/ 838,
+ /*0x10e3*/ 497,
+ -1,
+ /*0x13a8*/ 532,
+ -1,
+ /*0x03df*/ 279,
+ /*0x10ce5*/ 1240,
+ /*0x10428*/ 1127,
+ -1,
+ /*0x13b8*/ 548,
+ /*0x0438*/ 300,
+ /*0x10e5*/ 499,
+ -1,
+ /*0x10438*/ 1143,
+ /*0xa75b*/ 1061,
+ -1,
+ /*0x10ce9*/ 1244,
+ /*0x13eb*/ 599,
+ /*0x046b*/ 345,
+ /*0x04eb*/ 405,
+ /*0x006b*/ 9,
+ /*0x10e9*/ 503,
+ /*0x104eb*/ 1186,
+ /*0x1e6b*/ 666,
+ /*0x1eeb*/ 725,
+ /*0x016b*/ 107,
+ /*0x10ce7*/ 1242,
+ -1,
+ /*0x03b8*/ 253,
+ /*0xa759*/ 1060,
+ -1,
+ /*0x10e7*/ 501,
+ /*0x13ef*/ 603,
+ /*0x046f*/ 347,
+ /*0x04ef*/ 407,
+ /*0x006f*/ 13,
+ /*0x03eb*/ 285,
+ /*0x104ef*/ 1190,
+ /*0x1e6f*/ 668,
+ /*0x1eef*/ 727,
+ /*0x016f*/ 109,
+ /*0x10cdb*/ 1230,
+ -1, -1,
+ /*0xa75d*/ 1062,
+ -1,
+ /*0x10db*/ 489,
+ -1, -1, -1, -1,
+ /*0x03ef*/ 287,
+ -1, -1,
+ /*0x0261*/ 210,
+ -1,
+ /*0x10cd9*/ 1228,
+ -1,
+ /*0x13d7*/ 579,
+ /*0x0457*/ 331,
+ /*0x04d7*/ 395,
+ /*0x10d9*/ 487,
+ -1,
+ /*0x021b*/ 178,
+ /*0x1e57*/ 656,
+ /*0x1ed7*/ 715,
+ /*0x0157*/ 97,
+ /*0x2cd7*/ 947,
+ /*0x020b*/ 170,
+ -1, -1,
+ /*0x10cdd*/ 1232,
+ /*0x24d7*/ 830,
+ /*0xa75f*/ 1063,
+ -1,
+ /*0x1f61*/ 777,
+ /*0x10dd*/ 491,
+ /*0x03d7*/ 275,
+ /*0x0263*/ 211,
+ /*0x1f14*/ 748,
+ -1, -1,
+ /*0x1d8e*/ 612,
+ /*0xa661*/ 1013,
+ /*0x13ed*/ 601,
+ /*0x046d*/ 346,
+ /*0x04ed*/ 406,
+ /*0x006d*/ 11,
+ /*0x0265*/ 212,
+ /*0x104ed*/ 1188,
+ /*0x1e6d*/ 667,
+ /*0x1eed*/ 726,
+ /*0x016d*/ 108,
+ /*0x13be*/ 554,
+ /*0x043e*/ 306,
+ -1, -1,
+ /*0x1043e*/ 1149,
+ /*0x0269*/ 215,
+ /*0x1f63*/ 779,
+ /*0x10cdf*/ 1234,
+ /*0x013e*/ 85,
+ -1,
+ /*0x03ed*/ 286,
+ /*0xa76b*/ 1069,
+ /*0x10df*/ 493,
+ /*0x13ae*/ 538,
+ /*0xa663*/ 1014,
+ -1,
+ /*0x1f65*/ 781,
+ /*0x1042e*/ 1133,
+ /*0x13ac*/ 536,
+ /*0x03be*/ 259,
+ -1, -1,
+ /*0x1042c*/ 1131,
+ -1,
+ /*0xa665*/ 1015,
+ /*0x1f12*/ 746,
+ /*0xa76f*/ 1071,
+ -1, -1, -1,
+ /*0x025b*/ 207,
+ -1,
+ /*0x03ae*/ 244,
+ -1,
+ /*0xa669*/ 1017,
+ /*0x1f06*/ 742,
+ /*0x1f67*/ 783,
+ /*0x03ac*/ 242,
+ /*0x10ceb*/ 1246,
+ -1,
+ /*0x13d1*/ 573,
+ /*0x0451*/ 325,
+ /*0x04d1*/ 392,
+ /*0x10eb*/ 505,
+ /*0xa667*/ 1016,
+ /*0x0259*/ 206,
+ /*0x1e51*/ 653,
+ /*0x1ed1*/ 712,
+ /*0x0151*/ 94,
+ /*0x2cd1*/ 944,
+ -1, -1,
+ /*0xa757*/ 1059,
+ /*0x10cef*/ 1250,
+ /*0x24d1*/ 824,
+ /*0x13d3*/ 575,
+ /*0x0453*/ 327,
+ /*0x04d3*/ 393,
+ /*0x10ef*/ 509,
+ /*0xa65b*/ 1010,
+ -1,
+ /*0x1e53*/ 654,
+ /*0x1ed3*/ 713,
+ /*0x0153*/ 95,
+ /*0x2cd3*/ 945,
+ -1,
+ /*0xab53*/ 1100,
+ /*0x0561*/ 440,
+ /*0x1f10*/ 744,
+ /*0x24d3*/ 826,
+ -1, -1,
+ /*0x01e1*/ 151,
+ -1,
+ /*0xa659*/ 1009,
+ -1,
+ /*0x051b*/ 429,
+ -1,
+ /*0xa76d*/ 1070,
+ /*0x10cd7*/ 1226,
+ -1,
+ /*0x050b*/ 421,
+ -1, -1,
+ /*0x10d7*/ 485,
+ -1, -1, -1, -1,
+ /*0xa65d*/ 1011,
+ -1,
+ /*0x0563*/ 442,
+ /*0x13f1*/ 605,
+ /*0x0471*/ 348,
+ /*0x04f1*/ 408,
+ /*0x0071*/ 15,
+ /*0x01e3*/ 152,
+ /*0x104f1*/ 1192,
+ /*0x1e71*/ 669,
+ /*0x1ef1*/ 728,
+ /*0x0171*/ 110,
+ /*0x0565*/ 444,
+ -1, -1,
+ /*0x1f26*/ 756,
+ /*0x10ced*/ 1248,
+ /*0x01e5*/ 153,
+ -1,
+ /*0x1f20*/ 750,
+ -1,
+ /*0x10ed*/ 507,
+ /*0x0569*/ 448,
+ -1, -1,
+ /*0x118db*/ 1281,
+ /*0x0192*/ 122,
+ /*0x01e9*/ 155,
+ -1,
+ /*0xa65f*/ 1012,
+ /*0x13ee*/ 602,
+ /*0x026b*/ 217,
+ /*0x0567*/ 446,
+ /*0x006e*/ 12,
+ -1,
+ /*0x104ee*/ 1189,
+ -1,
+ /*0x01e7*/ 154,
+ /*0xa751*/ 1056,
+ /*0x2cee*/ 955,
+ /*0x118d9*/ 1279,
+ -1,
+ /*0x13f3*/ 607,
+ /*0x0473*/ 349,
+ /*0x04f3*/ 409,
+ /*0x0073*/ 17,
+ /*0x026f*/ 219,
+ /*0x104f3*/ 1194,
+ /*0x1e73*/ 670,
+ /*0x1ef3*/ 729,
+ /*0x0173*/ 111,
+ /*0x2cf3*/ 956,
+ /*0x2c61*/ 896,
+ /*0xa753*/ 1057,
+ -1,
+ /*0x118dd*/ 1283,
+ -1, -1,
+ /*0x13ba*/ 550,
+ /*0x043a*/ 302,
+ /*0xa66b*/ 1018,
+ /*0x03f3*/ 289,
+ /*0x1043a*/ 1145,
+ -1, -1,
+ /*0x10cd1*/ 1220,
+ /*0x013a*/ 83,
+ /*0x13d5*/ 577,
+ /*0x0455*/ 329,
+ /*0x04d5*/ 394,
+ /*0x10d1*/ 479,
+ -1,
+ /*0x0257*/ 205,
+ /*0x1e55*/ 655,
+ /*0x1ed5*/ 714,
+ /*0x0155*/ 96,
+ /*0x2cd5*/ 946,
+ /*0x03ba*/ 255,
+ -1,
+ /*0x0586*/ 477,
+ /*0x10cd3*/ 1222,
+ /*0x24d5*/ 828,
+ /*0x01dd*/ 149,
+ -1,
+ /*0x118df*/ 1285,
+ /*0x10d3*/ 481,
+ /*0x2c65*/ 897,
+ -1,
+ /*0x018c*/ 121,
+ /*0x13f5*/ 609,
+ /*0x0475*/ 350,
+ /*0x04f5*/ 410,
+ /*0x0075*/ 19,
+ /*0x1f57*/ 775,
+ /*0x104f5*/ 1196,
+ /*0x1e75*/ 671,
+ /*0x1ef5*/ 730,
+ /*0x0175*/ 112,
+ /*0x13cf*/ 571,
+ /*0x044f*/ 323,
+ /*0x04cf*/ 391,
+ /*0xa657*/ 1008,
+ /*0x1044f*/ 1166,
+ /*0x1e92a*/ 1326,
+ /*0x1e4f*/ 652,
+ /*0x1ecf*/ 711,
+ /*0x014f*/ 93,
+ /*0x2ccf*/ 943,
+ -1,
+ /*0x1e926*/ 1322,
+ /*0x1f00*/ 736,
+ /*0x01df*/ 150,
+ /*0x13b2*/ 542,
+ /*0x0432*/ 294,
+ /*0x1f02*/ 738,
+ -1,
+ /*0x10432*/ 1137,
+ /*0x10cf1*/ 1252,
+ /*0x2d16*/ 979,
+ -1,
+ /*0x2d14*/ 977,
+ /*0x2c5b*/ 892,
+ /*0x10f1*/ 511,
+ /*0x2d0a*/ 967,
+ -1,
+ /*0x2d1b*/ 984,
+ /*0x2d18*/ 981,
+ /*0xa66d*/ 1019,
+ /*0x01a8*/ 130,
+ -1,
+ /*0x2d0b*/ 968,
+ /*0x03b2*/ 247,
+ /*0x1e928*/ 1324,
+ /*0x0188*/ 120,
+ /*0x019e*/ 126,
+ -1,
+ /*0x2c59*/ 890,
+ /*0x056b*/ 450,
+ /*0x1e938*/ 1340,
+ /*0x13c9*/ 565,
+ /*0x0449*/ 317,
+ -1,
+ /*0x01eb*/ 156,
+ /*0x10449*/ 1160,
+ /*0x10cee*/ 1249,
+ /*0x1e49*/ 649,
+ /*0x1ec9*/ 708,
+ /*0x0251*/ 200,
+ /*0x2cc9*/ 940,
+ /*0x10ee*/ 508,
+ -1,
+ /*0x2c5d*/ 894,
+ /*0x056f*/ 454,
+ -1,
+ /*0xa755*/ 1058,
+ -1,
+ /*0x118d7*/ 1277,
+ /*0x01ef*/ 158,
+ /*0x03c9*/ 269,
+ /*0x2d12*/ 975,
+ -1,
+ /*0x10f3*/ 513,
+ /*0x0253*/ 202,
+ -1, -1, -1, -1,
+ /*0x0491*/ 360,
+ /*0x1f51*/ 772,
+ /*0x2d06*/ 963,
+ /*0xa794*/ 1082,
+ /*0x1e11*/ 621,
+ /*0x1e91*/ 685,
+ /*0x0111*/ 64,
+ /*0x2c91*/ 912,
+ /*0xa79b*/ 1085,
+ /*0xa651*/ 1005,
+ -1, -1, -1, -1,
+ /*0x10cd5*/ 1224,
+ -1,
+ /*0x1f53*/ 773,
+ -1,
+ /*0xa74f*/ 1055,
+ /*0x10d5*/ 483,
+ -1,
+ /*0x13cd*/ 569,
+ /*0x044d*/ 321,
+ -1,
+ /*0xa653*/ 1006,
+ /*0x1044d*/ 1164,
+ -1,
+ /*0x1e4d*/ 651,
+ /*0x1ecd*/ 710,
+ /*0x014d*/ 92,
+ /*0x2ccd*/ 942,
+ -1,
+ /*0x0271*/ 220,
+ /*0x0180*/ 117,
+ -1,
+ /*0x2d10*/ 973,
+ /*0x2c38*/ 857,
+ /*0x056d*/ 452,
+ -1, -1,
+ /*0x03cd*/ 273,
+ /*0x10f5*/ 515,
+ /*0x01ed*/ 157,
+ /*0x13cb*/ 567,
+ /*0x044b*/ 319,
+ /*0x10ccf*/ 1218,
+ -1,
+ /*0x1044b*/ 1162,
+ -1,
+ /*0x1e4b*/ 650,
+ /*0x1ecb*/ 709,
+ /*0x014b*/ 91,
+ /*0x2ccb*/ 941,
+ /*0x1f71*/ 785,
+ /*0x2d0c*/ 969,
+ /*0x1e93e*/ 1346,
+ -1, -1, -1,
+ /*0xa749*/ 1052,
+ -1, -1,
+ /*0x03cb*/ 271,
+ -1,
+ /*0x118d1*/ 1271,
+ /*0x13c3*/ 559,
+ /*0x0443*/ 311,
+ -1,
+ /*0x1e92e*/ 1330,
+ /*0x10443*/ 1154,
+ -1,
+ /*0x1e43*/ 646,
+ /*0x1ec3*/ 705,
+ /*0x1e92c*/ 1328,
+ /*0x2cc3*/ 937,
+ /*0x2d20*/ 989,
+ /*0x0580*/ 471,
+ -1, -1,
+ /*0x118d3*/ 1273,
+ /*0x0582*/ 473,
+ -1, -1, -1,
+ /*0x03c3*/ 263,
+ /*0x2c57*/ 888,
+ /*0x10cc9*/ 1212,
+ /*0x13c1*/ 557,
+ /*0x0441*/ 309,
+ -1,
+ /*0x00e1*/ 26,
+ /*0x10441*/ 1152,
+ /*0x1f73*/ 787,
+ /*0x1e41*/ 645,
+ /*0x1ec1*/ 704,
+ -1,
+ /*0x2cc1*/ 936,
+ -1, -1,
+ /*0x2d08*/ 965,
+ /*0x2d1e*/ 987,
+ -1,
+ /*0x13a4*/ 528,
+ -1,
+ /*0xa78c*/ 1079,
+ -1,
+ /*0x03c1*/ 262,
+ -1,
+ /*0xa74d*/ 1054,
+ /*0x049d*/ 366,
+ -1, -1, -1,
+ /*0x1e1d*/ 627,
+ /*0x00e3*/ 28,
+ /*0x011d*/ 70,
+ /*0x2c9d*/ 918,
+ /*0x1f55*/ 774,
+ /*0x0275*/ 222,
+ -1,
+ /*0x2c3e*/ 863,
+ -1,
+ /*0x13c7*/ 563,
+ /*0x0447*/ 315,
+ /*0x00e5*/ 30,
+ /*0xa655*/ 1007,
+ /*0x10447*/ 1158,
+ /*0x024f*/ 198,
+ /*0x1e47*/ 648,
+ /*0x1ec7*/ 707,
+ /*0xa74b*/ 1053,
+ /*0x2cc7*/ 939,
+ /*0x0371*/ 236,
+ -1,
+ /*0x00e9*/ 34,
+ /*0x10ccd*/ 1216,
+ /*0x13c5*/ 561,
+ /*0x0445*/ 313,
+ /*0x0571*/ 456,
+ /*0x1f75*/ 789,
+ /*0x10445*/ 1156,
+ /*0x03c7*/ 267,
+ /*0x1e45*/ 647,
+ /*0x1ec5*/ 706,
+ /*0x00e7*/ 32,
+ /*0x2cc5*/ 938,
+ -1, -1, -1, -1, -1, -1,
+ /*0xa743*/ 1049,
+ -1, -1,
+ /*0x03c5*/ 265,
+ /*0xa64f*/ 1004,
+ /*0x10ccb*/ 1214,
+ -1, -1,
+ /*0x2c51*/ 882,
+ -1,
+ /*0x1f32*/ 760,
+ -1,
+ /*0x13e6*/ 594,
+ /*0x056e*/ 453,
+ /*0x2d00*/ 957,
+ /*0x0066*/ 5,
+ /*0x0249*/ 195,
+ /*0x104e6*/ 1181,
+ /*0x2d02*/ 959,
+ /*0x0373*/ 237,
+ -1,
+ /*0x2d0e*/ 971,
+ /*0xa741*/ 1048,
+ /*0x2c53*/ 884,
+ -1,
+ /*0x0573*/ 458,
+ /*0x24e6*/ 845,
+ /*0x10cc3*/ 1206,
+ /*0x118d5*/ 1275,
+ -1,
+ /*0x01f3*/ 159,
+ -1,
+ /*0x13bf*/ 555,
+ /*0x043f*/ 307,
+ /*0x04bf*/ 383,
+ -1,
+ /*0x1043f*/ 1150,
+ /*0x028a*/ 230,
+ /*0x1e3f*/ 644,
+ /*0x1ebf*/ 703,
+ /*0x019a*/ 125,
+ /*0x2cbf*/ 935,
+ /*0x0211*/ 173,
+ /*0x13ec*/ 600,
+ /*0x028b*/ 231,
+ /*0xa649*/ 1001,
+ /*0x006c*/ 10,
+ -1,
+ /*0x104ec*/ 1187,
+ /*0x10cc1*/ 1204,
+ /*0x1e93a*/ 1342,
+ /*0x03bf*/ 260,
+ /*0x2cec*/ 954,
+ /*0x1f04*/ 740,
+ -1, -1, -1,
+ /*0xa747*/ 1051,
+ /*0x13a2*/ 526,
+ /*0x118cf*/ 1269,
+ /*0x13b7*/ 547,
+ /*0x0437*/ 299,
+ /*0x04b7*/ 379,
+ /*0x1f11*/ 745,
+ /*0x10437*/ 1142,
+ /*0x024d*/ 197,
+ /*0x1e37*/ 640,
+ /*0x1eb7*/ 699,
+ /*0x0137*/ 82,
+ /*0x2cb7*/ 931,
+ -1,
+ /*0xa745*/ 1050,
+ /*0x0575*/ 460,
+ /*0x0292*/ 233,
+ /*0x13b5*/ 545,
+ /*0x0435*/ 297,
+ /*0x04b5*/ 378,
+ /*0x01f5*/ 160,
+ /*0x10435*/ 1140,
+ /*0x03b7*/ 252,
+ /*0x1e35*/ 639,
+ /*0x1eb5*/ 698,
+ /*0x0135*/ 81,
+ /*0x2cb5*/ 930,
+ /*0x10cc7*/ 1210,
+ -1, -1,
+ /*0x024b*/ 196,
+ -1,
+ /*0x16e61*/ 1287,
+ -1, -1, -1,
+ /*0x03b5*/ 250,
+ /*0xa64d*/ 1003,
+ -1, -1,
+ /*0x00eb*/ 36,
+ /*0x10cc5*/ 1208,
+ /*0x2c73*/ 902,
+ /*0x118c9*/ 1263,
+ /*0x13b3*/ 543,
+ /*0x0433*/ 295,
+ /*0x04b3*/ 377,
+ /*0x1e932*/ 1334,
+ /*0x10433*/ 1138,
+ -1,
+ /*0x1e33*/ 638,
+ /*0x1eb3*/ 697,
+ /*0x0133*/ 80,
+ /*0x2cb3*/ 929,
+ -1,
+ /*0x00ef*/ 40,
+ /*0x16e63*/ 1289,
+ -1,
+ /*0x2c3a*/ 859,
+ /*0xa64b*/ 1002,
+ /*0x13c0*/ 556,
+ /*0x0440*/ 308,
+ /*0xa73f*/ 1047,
+ /*0x03b3*/ 248,
+ /*0x10440*/ 1151,
+ -1,
+ /*0x16e65*/ 1291,
+ /*0x2c55*/ 886,
+ /*0x0140*/ 86,
+ /*0x10ce6*/ 1241,
+ /*0x01c9*/ 139,
+ -1, -1,
+ /*0x1f43*/ 769,
+ /*0x10e6*/ 500,
+ -1,
+ /*0x16e69*/ 1295,
+ -1,
+ /*0x028c*/ 232,
+ /*0x03c0*/ 261,
+ -1,
+ /*0xa643*/ 998,
+ -1,
+ /*0x0479*/ 352,
+ /*0x04f9*/ 412,
+ /*0x0079*/ 23,
+ /*0x16e67*/ 1293,
+ /*0x104f9*/ 1200,
+ /*0x1e79*/ 673,
+ /*0x1ef9*/ 732,
+ /*0xa737*/ 1043,
+ /*0x0511*/ 424,
+ /*0x118cd*/ 1267,
+ /*0x1d79*/ 610,
+ /*0x021d*/ 179,
+ /*0x1f41*/ 767,
+ -1, -1,
+ /*0x2c4f*/ 880,
+ -1,
+ /*0x10cec*/ 1247,
+ -1, -1,
+ /*0xa641*/ 997,
+ /*0xa735*/ 1042,
+ /*0x10ec*/ 506,
+ /*0x2171*/ 807,
+ /*0x00ed*/ 38,
+ -1,
+ /*0x0247*/ 194,
+ /*0x1f24*/ 754,
+ /*0x13ad*/ 537,
+ /*0x2c32*/ 851,
+ /*0x04ad*/ 374,
+ /*0x118cb*/ 1265,
+ /*0x1042d*/ 1132,
+ /*0x2d1a*/ 983,
+ /*0x1e2d*/ 635,
+ /*0x1ead*/ 694,
+ /*0x012d*/ 78,
+ /*0x2cad*/ 926,
+ -1, -1,
+ /*0x0288*/ 228,
+ /*0x029e*/ 235,
+ -1,
+ /*0x13a5*/ 529,
+ -1,
+ /*0x04a5*/ 370,
+ /*0x0584*/ 475,
+ /*0x03ad*/ 243,
+ /*0xa733*/ 1041,
+ /*0x1e25*/ 631,
+ /*0x1ea5*/ 690,
+ /*0x0125*/ 74,
+ /*0x2ca5*/ 922,
+ /*0x118c3*/ 1257,
+ -1,
+ /*0xa647*/ 1000,
+ /*0x2c49*/ 874,
+ /*0x13a3*/ 527,
+ -1,
+ /*0x04a3*/ 369,
+ -1,
+ /*0x1f45*/ 771,
+ /*0x2173*/ 809,
+ /*0x1e23*/ 630,
+ /*0x1ea3*/ 689,
+ /*0x0123*/ 73,
+ /*0x2ca3*/ 921,
+ /*0xff59*/ 1125,
+ /*0x0266*/ 213,
+ /*0xa645*/ 999,
+ -1, -1,
+ /*0x048f*/ 359,
+ -1, -1,
+ /*0x118c1*/ 1255,
+ /*0x1e0f*/ 620,
+ /*0x1e8f*/ 684,
+ /*0x010f*/ 63,
+ /*0x2c8f*/ 911,
+ /*0xa69b*/ 1033,
+ -1, -1, -1,
+ /*0x1e943*/ 1351,
+ /*0xa68b*/ 1025,
+ -1, -1,
+ /*0x023f*/ 191,
+ /*0x1f66*/ 782,
+ -1,
+ /*0x10cc0*/ 1203,
+ -1, -1,
+ /*0x1fe1*/ 803,
+ -1,
+ /*0x0481*/ 356,
+ /*0x2d1c*/ 985,
+ -1,
+ /*0x026c*/ 218,
+ /*0x1e01*/ 613,
+ /*0x1e81*/ 677,
+ /*0x0101*/ 56,
+ /*0x2c81*/ 904,
+ -1,
+ /*0x2c4d*/ 878,
+ /*0x1e941*/ 1349,
+ /*0x0280*/ 224,
+ /*0x16e6b*/ 1297,
+ /*0x2175*/ 811,
+ /*0x118c7*/ 1261,
+ /*0x0282*/ 225,
+ -1, -1, -1,
+ /*0xa72d*/ 1039,
+ -1,
+ /*0x051d*/ 430,
+ /*0x10f9*/ 519,
+ -1, -1,
+ /*0x1e924*/ 1320,
+ -1,
+ /*0x16e6f*/ 1301,
+ /*0x118c5*/ 1259,
+ /*0x00f1*/ 42,
+ -1,
+ /*0x2c4b*/ 876,
+ /*0x1fe5*/ 804,
+ -1,
+ /*0xa725*/ 1035,
+ -1,
+ /*0x13a7*/ 531,
+ -1,
+ /*0x04a7*/ 371,
+ /*0x1f22*/ 752,
+ /*0x2d04*/ 961,
+ /*0x1f37*/ 765,
+ /*0x1e27*/ 632,
+ /*0x1ea7*/ 691,
+ /*0x0127*/ 75,
+ /*0x2ca7*/ 923,
+ -1, -1,
+ /*0xa723*/ 1034,
+ -1,
+ /*0x2d11*/ 974,
+ -1, -1,
+ /*0x2c43*/ 868,
+ -1,
+ /*0x1f35*/ 763,
+ /*0x00ee*/ 39,
+ -1,
+ /*0x047b*/ 353,
+ /*0x04fb*/ 413,
+ -1,
+ /*0x0233*/ 189,
+ /*0x104fb*/ 1202,
+ /*0x1e7b*/ 674,
+ /*0x1efb*/ 733,
+ /*0x13b1*/ 541,
+ /*0x0431*/ 293,
+ /*0x04b1*/ 376,
+ /*0x00f3*/ 44,
+ /*0x10431*/ 1136,
+ -1,
+ /*0x1e31*/ 637,
+ /*0x1eb1*/ 696,
+ -1,
+ /*0x2cb1*/ 928,
+ /*0x2c41*/ 866,
+ /*0x03fb*/ 291,
+ /*0x0240*/ 192,
+ /*0x0566*/ 445,
+ /*0x16e6d*/ 1299,
+ /*0x047d*/ 354,
+ /*0x04fd*/ 414,
+ /*0x1f33*/ 761,
+ -1,
+ /*0x03b1*/ 246,
+ /*0x1e7d*/ 675,
+ /*0x1efd*/ 734,
+ /*0xff57*/ 1123,
+ /*0x047f*/ 355,
+ /*0x04ff*/ 415,
+ /*0x1d7d*/ 611,
+ -1, -1,
+ /*0x1e7f*/ 676,
+ /*0x1eff*/ 735,
+ /*0x13bd*/ 553,
+ /*0x043d*/ 305,
+ /*0x04bd*/ 382,
+ /*0x1f40*/ 766,
+ /*0x1043d*/ 1148,
+ /*0xa791*/ 1080,
+ /*0x1e3d*/ 643,
+ /*0x1ebd*/ 702,
+ /*0x01bf*/ 137,
+ /*0x2cbd*/ 934,
+ -1, -1,
+ /*0x1e93f*/ 1347,
+ -1,
+ /*0x056c*/ 451,
+ /*0x2c47*/ 872,
+ -1, -1, -1,
+ /*0x03bd*/ 258,
+ /*0x00f5*/ 46,
+ -1,
+ /*0x007a*/ 24,
+ -1,
+ /*0x104fa*/ 1201,
+ /*0x1f79*/ 793,
+ -1,
+ /*0x017a*/ 114,
+ /*0xa727*/ 1036,
+ /*0x2c45*/ 870,
+ /*0x13b9*/ 549,
+ /*0x0439*/ 301,
+ /*0x04b9*/ 380,
+ /*0x022d*/ 186,
+ /*0x10439*/ 1144,
+ -1,
+ /*0x1e39*/ 641,
+ /*0x1eb9*/ 700,
+ /*0x1e922*/ 1318,
+ /*0x2cb9*/ 932,
+ /*0x1e937*/ 1339,
+ -1,
+ /*0x13c2*/ 558,
+ /*0x0442*/ 310,
+ /*0x04c2*/ 384,
+ -1,
+ /*0x10442*/ 1153,
+ -1,
+ /*0x0225*/ 182,
+ /*0x03b9*/ 254,
+ /*0x0142*/ 87,
+ /*0x13d0*/ 572,
+ /*0x0450*/ 324,
+ -1,
+ /*0x1e935*/ 1337,
+ /*0x13f2*/ 606,
+ -1,
+ /*0x2c66*/ 898,
+ /*0x0072*/ 16,
+ /*0x2d24*/ 993,
+ /*0x104f2*/ 1193,
+ -1,
+ /*0x0223*/ 181,
+ -1,
+ /*0x2d1d*/ 986,
+ /*0x24d0*/ 823,
+ /*0x118c0*/ 1254,
+ /*0xff51*/ 1117,
+ -1,
+ /*0x1f25*/ 755,
+ -1, -1,
+ /*0xa7c3*/ 1099,
+ -1,
+ /*0x03f2*/ 288,
+ /*0x020f*/ 172,
+ -1,
+ /*0x2c3f*/ 864,
+ -1,
+ /*0xa77f*/ 1074,
+ -1,
+ /*0x1e933*/ 1335,
+ /*0xff53*/ 1119,
+ /*0x1f23*/ 753,
+ -1,
+ /*0x16e71*/ 1303,
+ -1,
+ /*0xa73d*/ 1046,
+ /*0x2c6c*/ 901,
+ /*0x13bb*/ 551,
+ /*0x043b*/ 303,
+ /*0x04bb*/ 381,
+ -1,
+ /*0x1043b*/ 1146,
+ -1,
+ /*0x1e3b*/ 642,
+ /*0x1ebb*/ 701,
+ /*0x1e940*/ 1348,
+ /*0x2cbb*/ 933,
+ /*0x0201*/ 165,
+ -1, -1, -1,
+ /*0x10fd*/ 521,
+ -1,
+ /*0x2c37*/ 856,
+ /*0xa77a*/ 1072,
+ -1,
+ /*0x03bb*/ 256,
+ -1,
+ /*0x0579*/ 464,
+ /*0x10ff*/ 523,
+ /*0x16e6e*/ 1300,
+ -1,
+ /*0xa79d*/ 1086,
+ /*0x01f9*/ 161,
+ /*0x017c*/ 115,
+ /*0xa739*/ 1044,
+ -1,
+ /*0x2c35*/ 854,
+ /*0x1f01*/ 737,
+ /*0x13af*/ 539,
+ -1,
+ /*0x04af*/ 375,
+ /*0x16e73*/ 1305,
+ /*0x1042f*/ 1134,
+ -1,
+ /*0x1e2f*/ 636,
+ /*0x1eaf*/ 695,
+ /*0x012f*/ 79,
+ /*0x2caf*/ 927,
+ -1, -1,
+ /*0x1e05*/ 615,
+ /*0x1e85*/ 679,
+ /*0x0105*/ 58,
+ /*0x2c85*/ 906,
+ /*0x0227*/ 183,
+ /*0x10fa*/ 520,
+ /*0x052d*/ 438,
+ /*0x03af*/ 245,
+ -1, -1,
+ /*0x13a9*/ 533,
+ /*0x01ad*/ 131,
+ /*0x04a9*/ 372,
+ /*0x2c33*/ 852,
+ /*0x10429*/ 1128,
+ /*0x1e92d*/ 1329,
+ /*0x1e29*/ 633,
+ /*0x1ea9*/ 692,
+ /*0x0129*/ 76,
+ /*0x2ca9*/ 924,
+ -1,
+ /*0x0525*/ 434,
+ -1,
+ /*0x10cc2*/ 1205,
+ -1,
+ /*0x1f27*/ 757,
+ /*0x01a5*/ 129,
+ -1, -1,
+ /*0x2c40*/ 865,
+ /*0x1e925*/ 1321,
+ -1,
+ /*0x10cd0*/ 1219,
+ /*0x0231*/ 188,
+ /*0x2d22*/ 991,
+ /*0x0523*/ 433,
+ /*0x10cf2*/ 1253,
+ /*0x10d0*/ 478,
+ /*0x16e75*/ 1307,
+ -1,
+ /*0x01a3*/ 128,
+ /*0x10f2*/ 512,
+ -1,
+ /*0xa73b*/ 1045,
+ /*0x1e923*/ 1319,
+ /*0x1fd1*/ 801,
+ /*0x1f7b*/ 795,
+ /*0x027d*/ 223,
+ /*0x050f*/ 423,
+ -1,
+ /*0xff55*/ 1121,
+ /*0x13ce*/ 570,
+ /*0x044e*/ 322,
+ /*0x04ce*/ 390,
+ /*0x1f31*/ 759,
+ /*0x1044e*/ 1165,
+ -1, -1,
+ /*0xa7bf*/ 1098,
+ /*0x0477*/ 351,
+ /*0x04f7*/ 411,
+ /*0x0077*/ 21,
+ /*0xa77c*/ 1073,
+ /*0x104f7*/ 1198,
+ /*0x1e77*/ 672,
+ /*0x1ef7*/ 731,
+ /*0x0177*/ 113,
+ -1,
+ /*0x1f7d*/ 797,
+ -1,
+ /*0x03ce*/ 274,
+ -1,
+ /*0x0501*/ 416,
+ -1, -1,
+ /*0xa72f*/ 1040,
+ /*0x1e03*/ 614,
+ /*0x1e83*/ 678,
+ /*0x0103*/ 57,
+ /*0x2c83*/ 905,
+ /*0x13e8*/ 596,
+ /*0xff4f*/ 1115,
+ -1,
+ /*0x0068*/ 7,
+ -1,
+ /*0x104e8*/ 1183,
+ /*0xa7b7*/ 1094,
+ /*0x13c6*/ 562,
+ /*0x0446*/ 314,
+ /*0x04c6*/ 386,
+ -1,
+ /*0x10446*/ 1157,
+ -1,
+ /*0x13f0*/ 604,
+ /*0x24e8*/ 847,
+ /*0x0146*/ 89,
+ /*0x0070*/ 14,
+ /*0xa729*/ 1037,
+ /*0x104f0*/ 1191,
+ -1,
+ /*0xa7b5*/ 1093,
+ -1, -1,
+ /*0x1f7a*/ 794,
+ -1,
+ /*0x0242*/ 193,
+ /*0x03c6*/ 266,
+ -1, -1,
+ /*0x0499*/ 364,
+ /*0x0527*/ 435,
+ -1, -1,
+ /*0x1e19*/ 625,
+ /*0x0250*/ 199,
+ /*0x0119*/ 68,
+ /*0x2c99*/ 916,
+ -1,
+ /*0x0272*/ 221,
+ /*0x1e927*/ 1323,
+ /*0x0581*/ 472,
+ -1,
+ /*0xff49*/ 1109,
+ -1, -1,
+ /*0x037b*/ 239,
+ /*0x1f42*/ 768,
+ -1, -1,
+ /*0x00e6*/ 31,
+ -1,
+ /*0x057b*/ 466,
+ -1,
+ /*0x13c4*/ 560,
+ /*0x0444*/ 312,
+ /*0x04c4*/ 385,
+ /*0x01fb*/ 162,
+ /*0x10444*/ 1155,
+ -1,
+ /*0x1f72*/ 786,
+ -1,
+ /*0x0144*/ 88,
+ -1, -1,
+ /*0x2d2d*/ 996,
+ -1, -1,
+ /*0x037d*/ 241,
+ /*0x1e931*/ 1333,
+ -1, -1, -1,
+ /*0x03c4*/ 264,
+ /*0x057d*/ 468,
+ /*0x2179*/ 815,
+ /*0x13d6*/ 578,
+ /*0x0456*/ 330,
+ -1,
+ /*0x01fd*/ 163,
+ /*0x2d25*/ 994,
+ /*0x00ec*/ 37,
+ /*0x057f*/ 470,
+ -1, -1,
+ /*0x029d*/ 234,
+ /*0x10cce*/ 1217,
+ /*0x01ff*/ 164,
+ -1, -1,
+ /*0x24d6*/ 829,
+ -1,
+ /*0xff4d*/ 1113,
+ -1,
+ /*0x2d23*/ 992,
+ /*0x01bd*/ 136,
+ /*0x0495*/ 362,
+ -1,
+ /*0x10f7*/ 517,
+ /*0x1e93d*/ 1345,
+ /*0x1e15*/ 623,
+ /*0x1e95*/ 687,
+ /*0x0115*/ 66,
+ /*0x2c95*/ 914,
+ -1,
+ /*0x022f*/ 187,
+ -1,
+ /*0x2d0f*/ 972,
+ -1,
+ /*0x057a*/ 465,
+ /*0x118c2*/ 1256,
+ /*0x0205*/ 167,
+ -1,
+ /*0x1f7c*/ 796,
+ /*0xff4b*/ 1111,
+ /*0x10ce8*/ 1243,
+ -1, -1, -1,
+ /*0x118d0*/ 1270,
+ /*0x10e8*/ 502,
+ /*0x13ea*/ 598,
+ /*0x10cc6*/ 1209,
+ -1,
+ /*0x006a*/ 8,
+ /*0x01b9*/ 135,
+ /*0x104ea*/ 1185,
+ /*0x0229*/ 184,
+ /*0x10cf0*/ 1251,
+ /*0x1e939*/ 1341,
+ /*0xa7a5*/ 1090,
+ /*0x2d01*/ 958,
+ /*0x1f05*/ 741,
+ /*0x10f0*/ 510,
+ /*0x2c31*/ 850,
+ -1,
+ /*0xff43*/ 1103,
+ -1, -1, -1, -1,
+ /*0x1e942*/ 1350,
+ -1, -1,
+ /*0xa7a3*/ 1089,
+ /*0x0572*/ 457,
+ /*0x01d0*/ 142,
+ /*0x13a1*/ 525,
+ -1,
+ /*0x04a1*/ 368,
+ -1, -1, -1,
+ /*0x1e21*/ 629,
+ /*0x1ea1*/ 688,
+ /*0x0121*/ 72,
+ /*0x2ca1*/ 920,
+ /*0xa691*/ 1028,
+ /*0xff41*/ 1101,
+ /*0x1e07*/ 616,
+ /*0x1e87*/ 680,
+ /*0x0107*/ 59,
+ /*0x2c87*/ 907,
+ -1,
+ /*0x2c3d*/ 862,
+ -1,
+ /*0x0493*/ 361,
+ -1,
+ /*0x10cc4*/ 1207,
+ /*0x2d27*/ 995,
+ /*0x1e13*/ 622,
+ /*0x1e93*/ 686,
+ /*0x0113*/ 65,
+ /*0x2c93*/ 913,
+ -1, -1,
+ /*0x13ab*/ 535,
+ /*0x00f9*/ 49,
+ /*0x04ab*/ 373,
+ -1,
+ /*0x1042b*/ 1130,
+ /*0xa781*/ 1075,
+ /*0x1e2b*/ 634,
+ /*0x1eab*/ 693,
+ /*0x012b*/ 77,
+ /*0x2cab*/ 925,
+ /*0x13e4*/ 592,
+ /*0x0203*/ 166,
+ /*0x1e93b*/ 1343,
+ /*0x0064*/ 3,
+ /*0x10cd6*/ 1225,
+ /*0x104e4*/ 1179,
+ /*0x037c*/ 240,
+ /*0xff47*/ 1107,
+ /*0x2c39*/ 858,
+ /*0x10d6*/ 484,
+ /*0x1f77*/ 791,
+ /*0x0268*/ 214,
+ /*0x057c*/ 467,
+ /*0x13e2*/ 590,
+ /*0x24e4*/ 843,
+ /*0x16e66*/ 1292,
+ /*0x0062*/ 1,
+ -1,
+ /*0x104e2*/ 1177,
+ -1,
+ /*0x2c42*/ 867,
+ /*0xff45*/ 1105,
+ /*0x1f03*/ 739,
+ -1, -1,
+ /*0x052f*/ 439,
+ -1,
+ /*0x24e2*/ 841,
+ -1,
+ /*0x2c50*/ 881,
+ -1,
+ /*0x0505*/ 418,
+ -1,
+ /*0xa7a7*/ 1091,
+ /*0x1e92f*/ 1331,
+ -1,
+ /*0x0185*/ 119,
+ /*0x13e0*/ 588,
+ /*0x0219*/ 177,
+ /*0x13da*/ 582,
+ /*0x045a*/ 334,
+ -1,
+ /*0x104e0*/ 1175,
+ /*0x217b*/ 817,
+ /*0x104da*/ 1169,
+ /*0x1f70*/ 784,
+ /*0x16e6c*/ 1298,
+ /*0x0529*/ 436,
+ /*0x0078*/ 22,
+ /*0x10cea*/ 1245,
+ /*0x104f8*/ 1199,
+ /*0x24e0*/ 839,
+ -1,
+ /*0x24da*/ 833,
+ /*0x10ea*/ 504,
+ -1,
+ /*0x1e929*/ 1325,
+ /*0x13dc*/ 584,
+ /*0x045c*/ 336,
+ /*0x13cc*/ 568,
+ /*0x044c*/ 320,
+ /*0x04cc*/ 389,
+ /*0x104dc*/ 1171,
+ /*0x1044c*/ 1163,
+ /*0x03f8*/ 290,
+ /*0x217d*/ 819,
+ /*0x118ce*/ 1268,
+ /*0x2c3b*/ 860,
+ -1,
+ /*0x13d8*/ 580,
+ /*0x0458*/ 332,
+ /*0x24dc*/ 835,
+ -1,
+ /*0x217f*/ 821,
+ /*0x104d8*/ 1167,
+ -1, -1,
+ /*0xa72b*/ 1038,
+ /*0x03cc*/ 272,
+ /*0x0585*/ 476,
+ /*0x13d4*/ 576,
+ /*0x0454*/ 328,
+ -1,
+ /*0x24d8*/ 831,
+ -1,
+ /*0x1f44*/ 770,
+ /*0x0256*/ 204,
+ /*0x13d2*/ 574,
+ /*0x0452*/ 326,
+ /*0x0377*/ 238,
+ -1, -1,
+ /*0xa7bd*/ 1097,
+ /*0x01ce*/ 141,
+ /*0x24d4*/ 827,
+ /*0x0577*/ 462,
+ -1, -1,
+ /*0x017e*/ 116,
+ /*0x0497*/ 363,
+ /*0x217a*/ 816,
+ /*0x24d2*/ 825,
+ /*0x118c6*/ 1260,
+ /*0x1e17*/ 624,
+ /*0x0215*/ 175,
+ /*0x0117*/ 67,
+ /*0x2c97*/ 915,
+ /*0x0503*/ 417,
+ -1,
+ /*0x0076*/ 20,
+ /*0x13f4*/ 608,
+ /*0x104f6*/ 1197,
+ /*0x0183*/ 118,
+ /*0x0074*/ 18,
+ /*0x10ce4*/ 1239,
+ /*0x104f4*/ 1195,
+ -1,
+ /*0x0568*/ 447,
+ -1,
+ /*0x10e4*/ 498,
+ /*0x13bc*/ 552,
+ /*0x043c*/ 304,
+ /*0xa7b9*/ 1095,
+ -1,
+ /*0x1043c*/ 1147,
+ /*0x1f15*/ 749,
+ -1,
+ /*0x10ce2*/ 1237,
+ /*0x013c*/ 84,
+ /*0x01c6*/ 138,
+ /*0x0570*/ 455,
+ /*0x026a*/ 216,
+ /*0x10e2*/ 496,
+ /*0x13c8*/ 564,
+ /*0x0448*/ 316,
+ /*0x04c8*/ 387,
+ /*0x2172*/ 808,
+ /*0x10448*/ 1159,
+ -1,
+ /*0x03bc*/ 257,
+ -1,
+ /*0x0148*/ 90,
+ /*0x16e79*/ 1311,
+ -1,
+ /*0x0519*/ 428,
+ /*0x00fb*/ 51,
+ -1, -1,
+ /*0x118c4*/ 1258,
+ /*0x0199*/ 124,
+ -1,
+ /*0x10ce0*/ 1235,
+ /*0x03c8*/ 268,
+ /*0x10cda*/ 1229,
+ -1,
+ /*0x0583*/ 474,
+ /*0x10e0*/ 494,
+ -1,
+ /*0x10da*/ 488,
+ -1, -1, -1,
+ /*0x2c4e*/ 879,
+ /*0x0207*/ 168,
+ /*0x10f8*/ 518,
+ -1, -1,
+ /*0x00fd*/ 53,
+ -1,
+ /*0x2d05*/ 962,
+ /*0x118d6*/ 1276,
+ /*0x10cdc*/ 1231,
+ -1,
+ /*0x10ccc*/ 1215,
+ /*0x0213*/ 174,
+ /*0x00ff*/ 55,
+ /*0x10dc*/ 490,
+ -1,
+ /*0x1f21*/ 751,
+ -1, -1,
+ /*0xa7bb*/ 1096,
+ -1,
+ /*0x10cd8*/ 1227,
+ /*0x1f07*/ 743,
+ -1,
+ /*0x022b*/ 185,
+ -1,
+ /*0x10d8*/ 486,
+ /*0x217c*/ 818,
+ -1,
+ /*0x2c68*/ 899,
+ -1, -1,
+ /*0x10cd4*/ 1223,
+ /*0x1f13*/ 747,
+ -1,
+ /*0x01d6*/ 145,
+ /*0x2c46*/ 871,
+ /*0x10d4*/ 482,
+ -1,
+ /*0x10cd2*/ 1221,
+ /*0x00fa*/ 50,
+ /*0x13ca*/ 566,
+ /*0x044a*/ 318,
+ /*0x04ca*/ 388,
+ /*0x10d2*/ 480,
+ /*0x1044a*/ 1161,
+ /*0x2184*/ 822,
+ /*0x10fe*/ 522,
+ /*0x0515*/ 426,
+ -1, -1, -1, -1,
+ /*0x0195*/ 123,
+ -1,
+ /*0x1f64*/ 780,
+ -1,
+ /*0xa785*/ 1077,
+ /*0x13b6*/ 546,
+ /*0x0436*/ 298,
+ /*0x03ca*/ 270,
+ -1,
+ /*0x10436*/ 1141,
+ /*0x10f6*/ 516,
+ -1,
+ /*0x13b4*/ 544,
+ /*0x0434*/ 296,
+ /*0x10f4*/ 514,
+ /*0x1f62*/ 778,
+ /*0x10434*/ 1139,
+ -1,
+ /*0x0260*/ 209,
+ -1,
+ /*0xa7a9*/ 1092,
+ /*0x048d*/ 358,
+ /*0x056a*/ 449,
+ /*0x00f2*/ 43,
+ /*0x03b6*/ 251,
+ /*0x1e0d*/ 619,
+ /*0x1e8d*/ 683,
+ /*0x010d*/ 62,
+ /*0x2c8d*/ 910,
+ /*0x2c44*/ 869,
+ /*0x2d03*/ 960,
+ /*0x03b4*/ 249,
+ /*0x10cc8*/ 1211,
+ /*0x1e09*/ 617,
+ /*0x1e89*/ 681,
+ /*0x0109*/ 60,
+ /*0x2c89*/ 908,
+ -1,
+ /*0x025c*/ 208,
+ /*0x1f60*/ 776,
+ -1, -1,
+ /*0x13b0*/ 540,
+ /*0x0430*/ 292,
+ /*0x13de*/ 586,
+ /*0x045e*/ 338,
+ /*0x10430*/ 1135,
+ /*0x1f78*/ 792,
+ /*0x0521*/ 432,
+ /*0x104de*/ 1173,
+ /*0x214e*/ 805,
+ /*0x2c56*/ 887,
+ -1,
+ /*0x01a1*/ 127,
+ /*0x0507*/ 419,
+ -1,
+ /*0x049f*/ 367,
+ /*0x2177*/ 813,
+ /*0x24de*/ 837,
+ -1,
+ /*0x1e1f*/ 628,
+ /*0x0254*/ 203,
+ /*0x011f*/ 71,
+ /*0x2c9f*/ 919,
+ -1,
+ /*0x0513*/ 425,
+ -1,
+ /*0x2d19*/ 982,
+ /*0x0252*/ 201,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x00fc*/ 52,
+ /*0x052b*/ 437,
+ /*0x0217*/ 176,
+ -1,
+ /*0xa783*/ 1076,
+ /*0x16e7b*/ 1313,
+ -1, -1, -1, -1,
+ /*0x1e92b*/ 1327,
+ /*0x0564*/ 443,
+ -1, -1, -1, -1,
+ /*0x2170*/ 806,
+ -1, -1, -1,
+ /*0x2c6a*/ 900,
+ -1, -1, -1,
+ /*0x0562*/ 441,
+ /*0x023c*/ 190,
+ /*0x10cca*/ 1213,
+ /*0x16e7d*/ 1315,
+ /*0x118da*/ 1280,
+ -1, -1, -1,
+ /*0x1f76*/ 790,
+ -1, -1,
+ /*0x16e7f*/ 1317,
+ /*0x1f74*/ 788,
+ -1, -1, -1, -1,
+ /*0xa799*/ 1084,
+ -1, -1,
+ /*0xa68f*/ 1027,
+ -1,
+ /*0x118dc*/ 1282,
+ -1,
+ /*0x118cc*/ 1266,
+ -1, -1, -1, -1, -1, -1,
+ /*0x01da*/ 147,
+ /*0x0578*/ 463,
+ /*0x2d15*/ 978,
+ /*0x118d8*/ 1278,
+ -1, -1, -1,
+ /*0x16e7a*/ 1312,
+ -1, -1, -1, -1, -1,
+ /*0xa681*/ 1020,
+ /*0x118d4*/ 1274,
+ -1, -1, -1,
+ /*0x01dc*/ 148,
+ -1,
+ /*0x01cc*/ 140,
+ /*0x118d2*/ 1272,
+ -1, -1, -1, -1, -1,
+ /*0x10cde*/ 1233,
+ -1, -1,
+ /*0x01d8*/ 146,
+ -1,
+ /*0x10de*/ 492,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x01d4*/ 144,
+ -1,
+ /*0x16e72*/ 1304,
+ -1, -1,
+ /*0x057e*/ 469,
+ -1,
+ /*0x01d2*/ 143,
+ -1,
+ /*0x00e8*/ 33,
+ -1, -1,
+ /*0x0517*/ 427,
+ -1,
+ /*0x2d21*/ 990,
+ -1, -1, -1, -1, -1,
+ /*0x2d07*/ 964,
+ /*0x0576*/ 461,
+ /*0x00f0*/ 41,
+ /*0xff42*/ 1102,
+ -1,
+ /*0x0574*/ 459,
+ /*0x118c8*/ 1262,
+ -1,
+ /*0x2c5a*/ 891,
+ -1, -1,
+ /*0x2d13*/ 976,
+ /*0xff50*/ 1116,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0x020d*/ 171,
+ /*0x1e93c*/ 1344,
+ -1,
+ /*0x2c5c*/ 893,
+ -1,
+ /*0x2c4c*/ 877,
+ -1,
+ /*0x1f36*/ 764,
+ /*0x0209*/ 169,
+ -1, -1, -1,
+ /*0x16e7c*/ 1314,
+ -1,
+ /*0x1f34*/ 762,
+ /*0x2c58*/ 889,
+ -1, -1, -1,
+ /*0x1fb1*/ 799,
+ -1,
+ /*0xa7a1*/ 1088,
+ -1, -1, -1, -1,
+ /*0x2c54*/ 885,
+ /*0xa787*/ 1078,
+ -1, -1, -1, -1, -1,
+ /*0x2c52*/ 883,
+ -1,
+ /*0x021f*/ 180,
+ -1, -1,
+ /*0xa793*/ 1081,
+ -1, -1, -1, -1, -1,
+ /*0x1f30*/ 758,
+ -1, -1, -1,
+ /*0x0283*/ 226,
+ -1, -1, -1,
+ /*0x2c76*/ 903,
+ /*0x118ca*/ 1264,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ /*0x2c3c*/ 861,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ /*0x2c48*/ 873,
+ -1, -1, -1, -1, -1, -1,
+ /*0x00ea*/ 35,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x2178*/ 814,
+ /*0x16e77*/ 1309,
+ -1,
+ /*0x01b6*/ 134,
+ -1, -1,
+ /*0x1fd0*/ 800,
+ /*0x1e936*/ 1338,
+ -1, -1,
+ /*0x01b4*/ 133,
+ -1,
+ /*0x050d*/ 422,
+ /*0x2d17*/ 980,
+ /*0x1e934*/ 1336,
+ /*0x118de*/ 1284,
+ -1, -1, -1, -1,
+ /*0x0509*/ 420,
+ -1, -1,
+ /*0x16e68*/ 1294,
+ -1, -1, -1, -1,
+ /*0xff4e*/ 1114,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x16e70*/ 1302,
+ -1, -1, -1,
+ /*0x01b0*/ 132,
+ -1, -1, -1,
+ /*0x1e930*/ 1332,
+ /*0x217e*/ 820,
+ -1,
+ /*0x051f*/ 431,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x2c4a*/ 875,
+ -1,
+ /*0x00e4*/ 29,
+ -1,
+ /*0xa685*/ 1022,
+ -1,
+ /*0x2176*/ 812,
+ -1,
+ /*0xa797*/ 1083,
+ /*0xff46*/ 1106,
+ /*0x2174*/ 810,
+ -1, -1, -1, -1,
+ /*0x00e2*/ 27,
+ -1,
+ /*0x2c36*/ 855,
+ -1, -1, -1, -1, -1, -1,
+ /*0x2c34*/ 853,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x00e0*/ 25,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x00f8*/ 48,
+ -1, -1, -1, -1, -1, -1,
+ /*0x2c30*/ 849,
+ /*0xff44*/ 1104,
+ /*0x2c5e*/ 895,
+ -1, -1, -1, -1,
+ /*0x0287*/ 227,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0xff56*/ 1122,
+ -1, -1,
+ /*0xa683*/ 1021,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x16e6a*/ 1296,
+ -1, -1, -1,
+ /*0x00fe*/ 54,
+ -1, -1,
+ /*0x2d0d*/ 970,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x2d09*/ 966,
+ -1, -1, -1, -1,
+ /*0x00f6*/ 47,
+ -1, -1, -1,
+ /*0x00f4*/ 45,
+ -1, -1, -1, -1,
+ /*0xa699*/ 1032,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ /*0x2d1f*/ 988,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0x16e64*/ 1290,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ /*0x16e62*/ 1288,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0xa79f*/ 1087,
+ -1, -1,
+ /*0xa695*/ 1030,
+ -1, -1, -1, -1, -1, -1,
+ /*0x16e60*/ 1286,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x16e78*/ 1310,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0xff5a*/ 1126,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0xa687*/ 1023,
+ /*0x16e7e*/ 1316,
+ -1, -1,
+ /*0xff4c*/ 1112,
+ -1, -1, -1, -1, -1, -1,
+ /*0xa693*/ 1029,
+ -1, -1,
+ /*0xff58*/ 1124,
+ -1, -1,
+ /*0x16e76*/ 1308,
+ -1, -1, -1,
+ /*0x16e74*/ 1306,
+ -1, -1, -1,
+ /*0xff54*/ 1120,
+ -1, -1, -1, -1, -1, -1,
+ /*0xff52*/ 1118,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0xff48*/ 1108,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1,
+ /*0x1fe0*/ 802,
+ /*0x0289*/ 229,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ /*0xa697*/ 1031,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ /*0xff4a*/ 1110,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ /*0xa68d*/ 1026,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0xa689*/ 1024,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1,
+ /*0x1fb0*/ 798
+ };
+
+ if (code <= MAX_CODE_VALUE && code >= MIN_CODE_VALUE)
+ {
+ register unsigned int key = onigenc_unicode_CaseUnfold_11_hash(code);
+
+ if (key <= MAX_HASH_VALUE)
+ {
+ register short s = wordlist[key];
+
+ if (s >= 0 && code1_equal(code, CaseUnfold_11_Table[s].from))
+ return &CaseUnfold_11_Table[s].to;
+ }
+ }
+ return 0;
+}
+
+static const CaseUnfold_12_Type CaseUnfold_12_Table[] = {
+#define CaseUnfold_12 (*(CaseUnfold_12_Type (*)[58])(CaseUnfold_12_Table+0))
+ {{0x0061, 0x02be}, {1, {0x1e9a}}},
+ {{0x0066, 0x0066}, {1, {0xfb00}}},
+ {{0x0066, 0x0069}, {1, {0xfb01}}},
+ {{0x0066, 0x006c}, {1, {0xfb02}}},
+ {{0x0068, 0x0331}, {1, {0x1e96}}},
+ {{0x006a, 0x030c}, {1, {0x01f0}}},
+ {{0x0073, 0x0073}, {2, {0x00df, 0x1e9e}}},
+ {{0x0073, 0x0074}, {2, {0xfb05, 0xfb06}}},
+ {{0x0074, 0x0308}, {1, {0x1e97}}},
+ {{0x0077, 0x030a}, {1, {0x1e98}}},
+ {{0x0079, 0x030a}, {1, {0x1e99}}},
+ {{0x02bc, 0x006e}, {1, {0x0149}}},
+ {{0x03ac, 0x03b9}, {1, {0x1fb4}}},
+ {{0x03ae, 0x03b9}, {1, {0x1fc4}}},
+ {{0x03b1, 0x0342}, {1, {0x1fb6}}},
+ {{0x03b1, 0x03b9}, {2, {0x1fb3, 0x1fbc}}},
+ {{0x03b7, 0x0342}, {1, {0x1fc6}}},
+ {{0x03b7, 0x03b9}, {2, {0x1fc3, 0x1fcc}}},
+ {{0x03b9, 0x0342}, {1, {0x1fd6}}},
+ {{0x03c1, 0x0313}, {1, {0x1fe4}}},
+ {{0x03c5, 0x0313}, {1, {0x1f50}}},
+ {{0x03c5, 0x0342}, {1, {0x1fe6}}},
+ {{0x03c9, 0x0342}, {1, {0x1ff6}}},
+ {{0x03c9, 0x03b9}, {2, {0x1ff3, 0x1ffc}}},
+ {{0x03ce, 0x03b9}, {1, {0x1ff4}}},
+ {{0x0565, 0x0582}, {1, {0x0587}}},
+ {{0x0574, 0x0565}, {1, {0xfb14}}},
+ {{0x0574, 0x056b}, {1, {0xfb15}}},
+ {{0x0574, 0x056d}, {1, {0xfb17}}},
+ {{0x0574, 0x0576}, {1, {0xfb13}}},
+ {{0x057e, 0x0576}, {1, {0xfb16}}},
+ {{0x1f00, 0x03b9}, {2, {0x1f80, 0x1f88}}},
+ {{0x1f01, 0x03b9}, {2, {0x1f81, 0x1f89}}},
+ {{0x1f02, 0x03b9}, {2, {0x1f82, 0x1f8a}}},
+ {{0x1f03, 0x03b9}, {2, {0x1f83, 0x1f8b}}},
+ {{0x1f04, 0x03b9}, {2, {0x1f84, 0x1f8c}}},
+ {{0x1f05, 0x03b9}, {2, {0x1f85, 0x1f8d}}},
+ {{0x1f06, 0x03b9}, {2, {0x1f86, 0x1f8e}}},
+ {{0x1f07, 0x03b9}, {2, {0x1f87, 0x1f8f}}},
+ {{0x1f20, 0x03b9}, {2, {0x1f90, 0x1f98}}},
+ {{0x1f21, 0x03b9}, {2, {0x1f91, 0x1f99}}},
+ {{0x1f22, 0x03b9}, {2, {0x1f92, 0x1f9a}}},
+ {{0x1f23, 0x03b9}, {2, {0x1f93, 0x1f9b}}},
+ {{0x1f24, 0x03b9}, {2, {0x1f94, 0x1f9c}}},
+ {{0x1f25, 0x03b9}, {2, {0x1f95, 0x1f9d}}},
+ {{0x1f26, 0x03b9}, {2, {0x1f96, 0x1f9e}}},
+ {{0x1f27, 0x03b9}, {2, {0x1f97, 0x1f9f}}},
+ {{0x1f60, 0x03b9}, {2, {0x1fa0, 0x1fa8}}},
+ {{0x1f61, 0x03b9}, {2, {0x1fa1, 0x1fa9}}},
+ {{0x1f62, 0x03b9}, {2, {0x1fa2, 0x1faa}}},
+ {{0x1f63, 0x03b9}, {2, {0x1fa3, 0x1fab}}},
+ {{0x1f64, 0x03b9}, {2, {0x1fa4, 0x1fac}}},
+ {{0x1f65, 0x03b9}, {2, {0x1fa5, 0x1fad}}},
+ {{0x1f66, 0x03b9}, {2, {0x1fa6, 0x1fae}}},
+ {{0x1f67, 0x03b9}, {2, {0x1fa7, 0x1faf}}},
+ {{0x1f70, 0x03b9}, {1, {0x1fb2}}},
+ {{0x1f74, 0x03b9}, {1, {0x1fc2}}},
+ {{0x1f7c, 0x03b9}, {1, {0x1ff2}}},
+#define CaseUnfold_12_Locale (*(CaseUnfold_12_Type (*)[1])(CaseUnfold_12_Table+58))
+ {{0x0069, 0x0307}, {1, {0x0130}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3,4,5,6 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_12_hash -N onigenc_unicode_CaseUnfold_12_lookup -n */
+
+/* maximum key range = 71, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseUnfold_12_hash(const OnigCodePoint *codes)
+{
+ static const unsigned char asso_values[] =
+ {
+ 3, 58, 54, 57, 56, 16, 8, 2, 43, 82,
+ 3, 1, 23, 82, 82, 82, 82, 82, 82, 4,
+ 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+ 82, 82, 52, 51, 50, 49, 48, 47, 46, 45,
+ 82, 82, 82, 82, 43, 82, 42, 82, 82, 13,
+ 82, 82, 82, 82, 82, 11, 82, 1, 82, 82,
+ 14, 82, 1, 82, 82, 31, 3, 82, 82, 30,
+ 82, 82, 82, 10, 82, 82, 82, 82, 37, 82,
+ 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+ 82, 82, 82, 82, 82, 82, 37, 15, 36, 35,
+ 34, 17, 1, 33, 12, 4, 23, 23, 26, 21,
+ 13, 82, 27, 82, 82, 2, 5, 82, 11, 16,
+ 82, 15, 82, 82, 23, 82, 8, 82
+ };
+ return asso_values[bits_at(codes, 5)] + asso_values[bits_at(codes, 4)] + asso_values[bits_at(codes, 3)] + asso_values[bits_at(codes, 2)] + asso_values[bits_at(codes, 1)] + asso_values[bits_at(codes, 0)];
+}
+
+static const CodePointList2 *
+onigenc_unicode_CaseUnfold_12_lookup(const OnigCodePoint *codes)
+{
+ enum
+ {
+ MIN_CODE_VALUE = 0x61,
+ MAX_CODE_VALUE = 0x1f7c,
+ TOTAL_KEYWORDS = 59,
+ MIN_WORD_LENGTH = 6,
+ MAX_WORD_LENGTH = 6,
+ MIN_HASH_VALUE = 11,
+ MAX_HASH_VALUE = 81
+ };
+
+ static const short wordlist[] =
+ {
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ /*0x1f66,0x03b9*/ 53,
+ /*0x1f07,0x03b9*/ 38,
+ /*0x1f00,0x03b9*/ 31,
+ /*0x0066,0x0066*/ 1,
+ /*0x1f74,0x03b9*/ 56,
+ /*0x0073,0x0073*/ 6,
+ /*0x0066,0x0069*/ 2,
+ /*0x1f06,0x03b9*/ 37,
+ /*0x0073,0x0074*/ 7,
+ /*0x03b9,0x0342*/ 18,
+ /*0x03c9,0x03b9*/ 23,
+ /*0x03b7,0x03b9*/ 17,
+ /*0x0069,0x0307*/ 58,
+ /*0x03b1,0x03b9*/ 15,
+ /*0x1f61,0x03b9*/ 48,
+ /*0x1f05,0x03b9*/ 36,
+ /*0x1f65,0x03b9*/ 52,
+ /*0x0574,0x0576*/ 29,
+ /*0x03c9,0x0342*/ 22,
+ /*0x03b7,0x0342*/ 16,
+ /*0x057e,0x0576*/ 30,
+ /*0x03b1,0x0342*/ 14,
+ /*0x1f7c,0x03b9*/ 57,
+ /*0x0574,0x0565*/ 26,
+ /*0x0079,0x030a*/ 10,
+ /*0x0077,0x030a*/ 9,
+ /*0x1f70,0x03b9*/ 55,
+ /*0x0574,0x056d*/ 28,
+ /*0x0066,0x006c*/ 3,
+ /*0x0574,0x056b*/ 27,
+ /*0x0061,0x02be*/ 0,
+ /*0x0068,0x0331*/ 4,
+ /*0x1f67,0x03b9*/ 54,
+ /*0x1f64,0x03b9*/ 51,
+ /*0x1f63,0x03b9*/ 50,
+ /*0x1f62,0x03b9*/ 49,
+ /*0x1f60,0x03b9*/ 47,
+ /*0x03ce,0x03b9*/ 24,
+ /*0x03c5,0x0342*/ 21,
+ /*0x03c5,0x0313*/ 20,
+ /*0x03c1,0x0313*/ 19,
+ /*0x02bc,0x006e*/ 11,
+ /*0x03ae,0x03b9*/ 13,
+ /*0x03ac,0x03b9*/ 12,
+ /*0x1f27,0x03b9*/ 46,
+ /*0x1f26,0x03b9*/ 45,
+ /*0x1f25,0x03b9*/ 44,
+ /*0x1f24,0x03b9*/ 43,
+ /*0x1f23,0x03b9*/ 42,
+ /*0x1f22,0x03b9*/ 41,
+ /*0x1f21,0x03b9*/ 40,
+ /*0x1f20,0x03b9*/ 39,
+ /*0x006a,0x030c*/ 5,
+ /*0x1f02,0x03b9*/ 33,
+ /*0x0074,0x0308*/ 8,
+ /*0x1f04,0x03b9*/ 35,
+ /*0x1f03,0x03b9*/ 34,
+ /*0x1f01,0x03b9*/ 32,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ /*0x0565,0x0582*/ 25
+ };
+
+ if (codes[0] <= MAX_CODE_VALUE && codes[0] >= MIN_CODE_VALUE &&
+ codes[1] <= MAX_CODE_VALUE && codes[1] >= MIN_CODE_VALUE)
+ {
+ register unsigned int key = onigenc_unicode_CaseUnfold_12_hash(codes);
+
+ if (key <= MAX_HASH_VALUE)
+ {
+ register short s = wordlist[key];
+
+ if (s >= 0 && code2_equal(codes, CaseUnfold_12_Table[s].from))
+ return &CaseUnfold_12_Table[s].to;
+ }
+ }
+ return 0;
+}
+
+static const CaseUnfold_13_Type CaseUnfold_13_Table[] = {
+#define CaseUnfold_13 (*(CaseUnfold_13_Type (*)[14])(CaseUnfold_13_Table+0))
+ {{0x0066, 0x0066, 0x0069}, {1, {0xfb03}}},
+ {{0x0066, 0x0066, 0x006c}, {1, {0xfb04}}},
+ {{0x03b1, 0x0342, 0x03b9}, {1, {0x1fb7}}},
+ {{0x03b7, 0x0342, 0x03b9}, {1, {0x1fc7}}},
+ {{0x03b9, 0x0308, 0x0300}, {1, {0x1fd2}}},
+ {{0x03b9, 0x0308, 0x0301}, {2, {0x0390, 0x1fd3}}},
+ {{0x03b9, 0x0308, 0x0342}, {1, {0x1fd7}}},
+ {{0x03c5, 0x0308, 0x0300}, {1, {0x1fe2}}},
+ {{0x03c5, 0x0308, 0x0301}, {2, {0x03b0, 0x1fe3}}},
+ {{0x03c5, 0x0308, 0x0342}, {1, {0x1fe7}}},
+ {{0x03c5, 0x0313, 0x0300}, {1, {0x1f52}}},
+ {{0x03c5, 0x0313, 0x0301}, {1, {0x1f54}}},
+ {{0x03c5, 0x0313, 0x0342}, {1, {0x1f56}}},
+ {{0x03c9, 0x0342, 0x03b9}, {1, {0x1ff7}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3,4,5,6,7,8,9 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_13_hash -N onigenc_unicode_CaseUnfold_13_lookup -n */
+
+/* maximum key range = 20, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseUnfold_13_hash(const OnigCodePoint *codes)
+{
+ static const unsigned char asso_values[] =
+ {
+ 7, 4, 47, 47, 47, 47, 1, 1, 2, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 11,
+ 47, 47, 47, 47, 47, 10, 47, 2, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 47, 47, 1,
+ 47, 47, 47, 9, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 1, 47, 47, 2, 47, 47, 1, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47
+ };
+ return asso_values[bits_at(codes, 8)] + asso_values[bits_at(codes, 7)] + asso_values[bits_at(codes, 6)] + asso_values[bits_at(codes, 5)] + asso_values[bits_at(codes, 4)] + asso_values[bits_at(codes, 3)] + asso_values[bits_at(codes, 2)] + asso_values[bits_at(codes, 1)] + asso_values[bits_at(codes, 0)];
+}
+
+static const CodePointList2 *
+onigenc_unicode_CaseUnfold_13_lookup(const OnigCodePoint *codes)
+{
+ enum
+ {
+ MIN_CODE_VALUE = 0x66,
+ MAX_CODE_VALUE = 0x3c9,
+ TOTAL_KEYWORDS = 14,
+ MIN_WORD_LENGTH = 9,
+ MAX_WORD_LENGTH = 9,
+ MIN_HASH_VALUE = 27,
+ MAX_HASH_VALUE = 46
+ };
+
+ static const short wordlist[] =
+ {
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ /*0x03c5,0x0313,0x0342*/ 12,
+ /*0x03c5,0x0308,0x0342*/ 9,
+ /*0x03b9,0x0308,0x0342*/ 6,
+ /*0x03c5,0x0313,0x0301*/ 11,
+ /*0x03c5,0x0308,0x0301*/ 8,
+ /*0x03b9,0x0308,0x0301*/ 5,
+ /*0x03c5,0x0313,0x0300*/ 10,
+ /*0x03c5,0x0308,0x0300*/ 7,
+ /*0x03b9,0x0308,0x0300*/ 4,
+ /*0x03c9,0x0342,0x03b9*/ 13,
+ /*0x03b7,0x0342,0x03b9*/ 3,
+ /*0x03b1,0x0342,0x03b9*/ 2,
+ -1, -1, -1, -1, -1, -1,
+ /*0x0066,0x0066,0x006c*/ 1,
+ /*0x0066,0x0066,0x0069*/ 0
+ };
+
+ if (codes[0] <= MAX_CODE_VALUE && codes[0] >= MIN_CODE_VALUE &&
+ codes[1] <= MAX_CODE_VALUE && codes[1] >= MIN_CODE_VALUE &&
+ codes[2] <= MAX_CODE_VALUE && codes[2] >= MIN_CODE_VALUE)
+ {
+ register unsigned int key = onigenc_unicode_CaseUnfold_13_hash(codes);
+
+ if (key <= MAX_HASH_VALUE)
+ {
+ register short s = wordlist[key];
+
+ if (s >= 0 && code3_equal(codes, CaseUnfold_13_Table[s].from))
+ return &CaseUnfold_13_Table[s].to;
+ }
+ }
+ return 0;
+}
+
+static const OnigCodePoint CaseMappingSpecials[] = {
+ L(1)|0x039C,
+ L(2)|0x0053, 0x0073, L(2)|0x0053, 0x0053,
+ L(2)|0x02BC, 0x004E,
+ L(1)|0x0053,
+ L(1)|0x01C5,
+ L(2)|0x0064, 0x017D, L(1)|0x01C4,
+ L(1)|0x01C8,
+ L(2)|0x006C, 0x004A, L(1)|0x01C7,
+ L(1)|0x01CB,
+ L(2)|0x006E, 0x004A, L(1)|0x01CA,
+ L(2)|0x004A, 0x030C,
+ L(1)|0x01F2,
+ L(2)|0x0064, 0x005A, L(1)|0x01F1,
+ L(1)|0x0399,
+ L(3)|0x0399, 0x0308, 0x0301,
+ L(3)|0x03A5, 0x0308, 0x0301,
+ L(1)|0x03A3,
+ L(1)|0x0392,
+ L(1)|0x0398,
+ L(1)|0x03A6,
+ L(1)|0x03A0,
+ L(1)|0x039A,
+ L(1)|0x03A1,
+ L(1)|0x0395,
+ L(2)|0x0535, 0x0582, L(2)|0x0535, 0x0552,
+ L(1)|0x0412,
+ L(1)|0x0414,
+ L(1)|0x041E,
+ L(1)|0x0421,
+ L(1)|0x0422,
+ L(1)|0x0422,
+ L(1)|0x042A,
+ L(1)|0x0462,
+ L(1)|0xA64A,
+ L(2)|0x0048, 0x0331,
+ L(2)|0x0054, 0x0308,
+ L(2)|0x0057, 0x030A,
+ L(2)|0x0059, 0x030A,
+ L(2)|0x0041, 0x02BE,
+ L(1)|0x1E60,
+ L(1)|0x00DF,
+ L(2)|0x03A5, 0x0313,
+ L(3)|0x03A5, 0x0313, 0x0300,
+ L(3)|0x03A5, 0x0313, 0x0301,
+ L(3)|0x03A5, 0x0313, 0x0342,
+ L(1)|0x1F88, L(2)|0x1F08, 0x0399,
+ L(1)|0x1F89, L(2)|0x1F09, 0x0399,
+ L(1)|0x1F8A, L(2)|0x1F0A, 0x0399,
+ L(1)|0x1F8B, L(2)|0x1F0B, 0x0399,
+ L(1)|0x1F8C, L(2)|0x1F0C, 0x0399,
+ L(1)|0x1F8D, L(2)|0x1F0D, 0x0399,
+ L(1)|0x1F8E, L(2)|0x1F0E, 0x0399,
+ L(1)|0x1F8F, L(2)|0x1F0F, 0x0399,
+ L(2)|0x1F00, 0x0399, L(1)|0x1F80, L(2)|0x1F08, 0x0399,
+ L(2)|0x1F01, 0x0399, L(1)|0x1F81, L(2)|0x1F09, 0x0399,
+ L(2)|0x1F02, 0x0399, L(1)|0x1F82, L(2)|0x1F0A, 0x0399,
+ L(2)|0x1F03, 0x0399, L(1)|0x1F83, L(2)|0x1F0B, 0x0399,
+ L(2)|0x1F04, 0x0399, L(1)|0x1F84, L(2)|0x1F0C, 0x0399,
+ L(2)|0x1F05, 0x0399, L(1)|0x1F85, L(2)|0x1F0D, 0x0399,
+ L(2)|0x1F06, 0x0399, L(1)|0x1F86, L(2)|0x1F0E, 0x0399,
+ L(2)|0x1F07, 0x0399, L(1)|0x1F87, L(2)|0x1F0F, 0x0399,
+ L(1)|0x1F98, L(2)|0x1F28, 0x0399,
+ L(1)|0x1F99, L(2)|0x1F29, 0x0399,
+ L(1)|0x1F9A, L(2)|0x1F2A, 0x0399,
+ L(1)|0x1F9B, L(2)|0x1F2B, 0x0399,
+ L(1)|0x1F9C, L(2)|0x1F2C, 0x0399,
+ L(1)|0x1F9D, L(2)|0x1F2D, 0x0399,
+ L(1)|0x1F9E, L(2)|0x1F2E, 0x0399,
+ L(1)|0x1F9F, L(2)|0x1F2F, 0x0399,
+ L(2)|0x1F20, 0x0399, L(1)|0x1F90, L(2)|0x1F28, 0x0399,
+ L(2)|0x1F21, 0x0399, L(1)|0x1F91, L(2)|0x1F29, 0x0399,
+ L(2)|0x1F22, 0x0399, L(1)|0x1F92, L(2)|0x1F2A, 0x0399,
+ L(2)|0x1F23, 0x0399, L(1)|0x1F93, L(2)|0x1F2B, 0x0399,
+ L(2)|0x1F24, 0x0399, L(1)|0x1F94, L(2)|0x1F2C, 0x0399,
+ L(2)|0x1F25, 0x0399, L(1)|0x1F95, L(2)|0x1F2D, 0x0399,
+ L(2)|0x1F26, 0x0399, L(1)|0x1F96, L(2)|0x1F2E, 0x0399,
+ L(2)|0x1F27, 0x0399, L(1)|0x1F97, L(2)|0x1F2F, 0x0399,
+ L(1)|0x1FA8, L(2)|0x1F68, 0x0399,
+ L(1)|0x1FA9, L(2)|0x1F69, 0x0399,
+ L(1)|0x1FAA, L(2)|0x1F6A, 0x0399,
+ L(1)|0x1FAB, L(2)|0x1F6B, 0x0399,
+ L(1)|0x1FAC, L(2)|0x1F6C, 0x0399,
+ L(1)|0x1FAD, L(2)|0x1F6D, 0x0399,
+ L(1)|0x1FAE, L(2)|0x1F6E, 0x0399,
+ L(1)|0x1FAF, L(2)|0x1F6F, 0x0399,
+ L(2)|0x1F60, 0x0399, L(1)|0x1FA0, L(2)|0x1F68, 0x0399,
+ L(2)|0x1F61, 0x0399, L(1)|0x1FA1, L(2)|0x1F69, 0x0399,
+ L(2)|0x1F62, 0x0399, L(1)|0x1FA2, L(2)|0x1F6A, 0x0399,
+ L(2)|0x1F63, 0x0399, L(1)|0x1FA3, L(2)|0x1F6B, 0x0399,
+ L(2)|0x1F64, 0x0399, L(1)|0x1FA4, L(2)|0x1F6C, 0x0399,
+ L(2)|0x1F65, 0x0399, L(1)|0x1FA5, L(2)|0x1F6D, 0x0399,
+ L(2)|0x1F66, 0x0399, L(1)|0x1FA6, L(2)|0x1F6E, 0x0399,
+ L(2)|0x1F67, 0x0399, L(1)|0x1FA7, L(2)|0x1F6F, 0x0399,
+ L(2)|0x1FBA, 0x0345, L(2)|0x1FBA, 0x0399,
+ L(1)|0x1FBC, L(2)|0x0391, 0x0399,
+ L(2)|0x0386, 0x0345, L(2)|0x0386, 0x0399,
+ L(2)|0x0391, 0x0342,
+ L(3)|0x0391, 0x0342, 0x0345, L(3)|0x0391, 0x0342, 0x0399,
+ L(2)|0x03B1, 0x0399, L(1)|0x1FB3, L(2)|0x0391, 0x0399,
+ L(1)|0x0399,
+ L(2)|0x1FCA, 0x0345, L(2)|0x1FCA, 0x0399,
+ L(1)|0x1FCC, L(2)|0x0397, 0x0399,
+ L(2)|0x0389, 0x0345, L(2)|0x0389, 0x0399,
+ L(2)|0x0397, 0x0342,
+ L(3)|0x0397, 0x0342, 0x0345, L(3)|0x0397, 0x0342, 0x0399,
+ L(2)|0x03B7, 0x0399, L(1)|0x1FC3, L(2)|0x0397, 0x0399,
+ L(3)|0x0399, 0x0308, 0x0300,
+ L(3)|0x0399, 0x0308, 0x0301,
+ L(2)|0x0399, 0x0342,
+ L(3)|0x0399, 0x0308, 0x0342,
+ L(3)|0x03A5, 0x0308, 0x0300,
+ L(3)|0x03A5, 0x0308, 0x0301,
+ L(2)|0x03A1, 0x0313,
+ L(2)|0x03A5, 0x0342,
+ L(3)|0x03A5, 0x0308, 0x0342,
+ L(2)|0x1FFA, 0x0345, L(2)|0x1FFA, 0x0399,
+ L(1)|0x1FFC, L(2)|0x03A9, 0x0399,
+ L(2)|0x038F, 0x0345, L(2)|0x038F, 0x0399,
+ L(2)|0x03A9, 0x0342,
+ L(3)|0x03A9, 0x0342, 0x0345, L(3)|0x03A9, 0x0342, 0x0399,
+ L(2)|0x03C9, 0x0399, L(1)|0x1FF3, L(2)|0x03A9, 0x0399,
+ L(2)|0x0046, 0x0066, L(2)|0x0046, 0x0046,
+ L(2)|0x0046, 0x0069, L(2)|0x0046, 0x0049,
+ L(2)|0x0046, 0x006C, L(2)|0x0046, 0x004C,
+ L(3)|0x0046, 0x0066, 0x0069, L(3)|0x0046, 0x0046, 0x0049,
+ L(3)|0x0046, 0x0066, 0x006C, L(3)|0x0046, 0x0046, 0x004C,
+ L(2)|0x0053, 0x0074, L(2)|0x0053, 0x0054,
+ L(2)|0x0053, 0x0074, L(2)|0x0053, 0x0054,
+ L(2)|0x0544, 0x0576, L(2)|0x0544, 0x0546,
+ L(2)|0x0544, 0x0565, L(2)|0x0544, 0x0535,
+ L(2)|0x0544, 0x056B, L(2)|0x0544, 0x053B,
+ L(2)|0x054E, 0x0576, L(2)|0x054E, 0x0546,
+ L(2)|0x0544, 0x056D, L(2)|0x0544, 0x053D,
+};
diff --git a/enc/unicode/12.1.0/name2ctype.h b/enc/unicode/12.1.0/name2ctype.h
new file mode 100644
index 0000000000..b2270d5cac
--- /dev/null
+++ b/enc/unicode/12.1.0/name2ctype.h
@@ -0,0 +1,41810 @@
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -c -j1 -i1 -t -C -P -T -H uniname2ctype_hash -Q uniname2ctype_pool -N uniname2ctype_p */
+#ifndef USE_UNICODE_PROPERTIES
+/* Computed positions: -k'1,3' */
+#else /* USE_UNICODE_PROPERTIES */
+/* Computed positions: -k'1-3,5-6,12,16,$' */
+#endif /* USE_UNICODE_PROPERTIES */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('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-gperf@gnu.org>."
+#endif
+
+
+
+/* 'NEWLINE': [[:NEWLINE:]] */
+static const OnigCodePoint CR_NEWLINE[] = {
+ 1,
+ 0x000a, 0x000a,
+}; /* CR_NEWLINE */
+
+/* 'Alpha': [[:Alpha:]] */
+static const OnigCodePoint CR_Alpha[] = {
+ 679,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0345, 0x0345,
+ 0x0370, 0x0374,
+ 0x0376, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x05b0, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0610, 0x061a,
+ 0x0620, 0x0657,
+ 0x0659, 0x065f,
+ 0x066e, 0x06d3,
+ 0x06d5, 0x06dc,
+ 0x06e1, 0x06e8,
+ 0x06ed, 0x06ef,
+ 0x06fa, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x073f,
+ 0x074d, 0x07b1,
+ 0x07ca, 0x07ea,
+ 0x07f4, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x0800, 0x0817,
+ 0x081a, 0x082c,
+ 0x0840, 0x0858,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d4, 0x08df,
+ 0x08e3, 0x08e9,
+ 0x08f0, 0x093b,
+ 0x093d, 0x094c,
+ 0x094e, 0x0950,
+ 0x0955, 0x0963,
+ 0x0971, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cc,
+ 0x09ce, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09f0, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4c,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a70, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acc,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0af9, 0x0afc,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4c,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b71, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcc,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0c00, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4c,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c80, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccc,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4c,
+ 0x0d4e, 0x0d4e,
+ 0x0d54, 0x0d57,
+ 0x0d5f, 0x0d63,
+ 0x0d7a, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df3,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e46,
+ 0x0e4d, 0x0e4d,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ecd, 0x0ecd,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f81,
+ 0x0f88, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x1000, 0x1036,
+ 0x1038, 0x1038,
+ 0x103b, 0x103f,
+ 0x1050, 0x108f,
+ 0x109a, 0x109d,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1713,
+ 0x1720, 0x1733,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17b3,
+ 0x17b6, 0x17c8,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dc,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x1938,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x1a00, 0x1a1b,
+ 0x1a20, 0x1a5e,
+ 0x1a61, 0x1a74,
+ 0x1aa7, 0x1aa7,
+ 0x1b00, 0x1b33,
+ 0x1b35, 0x1b43,
+ 0x1b45, 0x1b4b,
+ 0x1b80, 0x1ba9,
+ 0x1bac, 0x1baf,
+ 0x1bba, 0x1be5,
+ 0x1be7, 0x1bf1,
+ 0x1c00, 0x1c36,
+ 0x1c4d, 0x1c4f,
+ 0x1c5a, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf6,
+ 0x1cfa, 0x1cfa,
+ 0x1d00, 0x1dbf,
+ 0x1de7, 0x1df4,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x24b6, 0x24e9,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2dff,
+ 0x2e2f, 0x2e2f,
+ 0x3005, 0x3007,
+ 0x3021, 0x3029,
+ 0x3031, 0x3035,
+ 0x3038, 0x303c,
+ 0x3041, 0x3096,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa61f,
+ 0xa62a, 0xa62b,
+ 0xa640, 0xa66e,
+ 0xa674, 0xa67b,
+ 0xa67f, 0xa6ef,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa805,
+ 0xa807, 0xa827,
+ 0xa840, 0xa873,
+ 0xa880, 0xa8c3,
+ 0xa8c5, 0xa8c5,
+ 0xa8f2, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa8ff,
+ 0xa90a, 0xa92a,
+ 0xa930, 0xa952,
+ 0xa960, 0xa97c,
+ 0xa980, 0xa9b2,
+ 0xa9b4, 0xa9bf,
+ 0xa9cf, 0xa9cf,
+ 0xa9e0, 0xa9ef,
+ 0xa9fa, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaabe,
+ 0xaac0, 0xaac0,
+ 0xaac2, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaef,
+ 0xaaf2, 0xaaf5,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabea,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10140, 0x10174,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae4,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d27,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f45,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x11045,
+ 0x11082, 0x110b8,
+ 0x110d0, 0x110e8,
+ 0x11100, 0x11132,
+ 0x11144, 0x11146,
+ 0x11150, 0x11172,
+ 0x11176, 0x11176,
+ 0x11180, 0x111bf,
+ 0x111c1, 0x111c4,
+ 0x111da, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x11234,
+ 0x11237, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112e8,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133d, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134c,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11400, 0x11441,
+ 0x11443, 0x11445,
+ 0x11447, 0x1144a,
+ 0x1145f, 0x1145f,
+ 0x11480, 0x114c1,
+ 0x114c4, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115be,
+ 0x115d8, 0x115dd,
+ 0x11600, 0x1163e,
+ 0x11640, 0x11640,
+ 0x11644, 0x11644,
+ 0x11680, 0x116b5,
+ 0x116b8, 0x116b8,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172a,
+ 0x11800, 0x11838,
+ 0x118a0, 0x118df,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119df,
+ 0x119e1, 0x119e1,
+ 0x119e3, 0x119e4,
+ 0x11a00, 0x11a32,
+ 0x11a35, 0x11a3e,
+ 0x11a50, 0x11a97,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c3e,
+ 0x11c40, 0x11c40,
+ 0x11c72, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d41,
+ 0x11d43, 0x11d43,
+ 0x11d46, 0x11d47,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d96,
+ 0x11d98, 0x11d98,
+ 0x11ee0, 0x11ef6,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16ad0, 0x16aed,
+ 0x16b00, 0x16b2f,
+ 0x16b40, 0x16b43,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9e, 0x1bc9e,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e137, 0x1e13d,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2eb,
+ 0x1e800, 0x1e8c4,
+ 0x1e900, 0x1e943,
+ 0x1e947, 0x1e947,
+ 0x1e94b, 0x1e94b,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1f130, 0x1f149,
+ 0x1f150, 0x1f169,
+ 0x1f170, 0x1f189,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_Alpha */
+
+/* 'Blank': [[:Blank:]] */
+static const OnigCodePoint CR_Blank[] = {
+ 8,
+ 0x0009, 0x0009,
+ 0x0020, 0x0020,
+ 0x00a0, 0x00a0,
+ 0x1680, 0x1680,
+ 0x2000, 0x200a,
+ 0x202f, 0x202f,
+ 0x205f, 0x205f,
+ 0x3000, 0x3000,
+}; /* CR_Blank */
+
+/* 'Cntrl': [[:Cntrl:]] */
+static const OnigCodePoint CR_Cntrl[] = {
+ 2,
+ 0x0000, 0x001f,
+ 0x007f, 0x009f,
+}; /* CR_Cntrl */
+
+/* 'Digit': [[:Digit:]] */
+static const OnigCodePoint CR_Digit[] = {
+ 59,
+ 0x0030, 0x0039,
+ 0x0660, 0x0669,
+ 0x06f0, 0x06f9,
+ 0x07c0, 0x07c9,
+ 0x0966, 0x096f,
+ 0x09e6, 0x09ef,
+ 0x0a66, 0x0a6f,
+ 0x0ae6, 0x0aef,
+ 0x0b66, 0x0b6f,
+ 0x0be6, 0x0bef,
+ 0x0c66, 0x0c6f,
+ 0x0ce6, 0x0cef,
+ 0x0d66, 0x0d6f,
+ 0x0de6, 0x0def,
+ 0x0e50, 0x0e59,
+ 0x0ed0, 0x0ed9,
+ 0x0f20, 0x0f29,
+ 0x1040, 0x1049,
+ 0x1090, 0x1099,
+ 0x17e0, 0x17e9,
+ 0x1810, 0x1819,
+ 0x1946, 0x194f,
+ 0x19d0, 0x19d9,
+ 0x1a80, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1b50, 0x1b59,
+ 0x1bb0, 0x1bb9,
+ 0x1c40, 0x1c49,
+ 0x1c50, 0x1c59,
+ 0xa620, 0xa629,
+ 0xa8d0, 0xa8d9,
+ 0xa900, 0xa909,
+ 0xa9d0, 0xa9d9,
+ 0xa9f0, 0xa9f9,
+ 0xaa50, 0xaa59,
+ 0xabf0, 0xabf9,
+ 0xff10, 0xff19,
+ 0x104a0, 0x104a9,
+ 0x10d30, 0x10d39,
+ 0x11066, 0x1106f,
+ 0x110f0, 0x110f9,
+ 0x11136, 0x1113f,
+ 0x111d0, 0x111d9,
+ 0x112f0, 0x112f9,
+ 0x11450, 0x11459,
+ 0x114d0, 0x114d9,
+ 0x11650, 0x11659,
+ 0x116c0, 0x116c9,
+ 0x11730, 0x11739,
+ 0x118e0, 0x118e9,
+ 0x11c50, 0x11c59,
+ 0x11d50, 0x11d59,
+ 0x11da0, 0x11da9,
+ 0x16a60, 0x16a69,
+ 0x16b50, 0x16b59,
+ 0x1d7ce, 0x1d7ff,
+ 0x1e140, 0x1e149,
+ 0x1e2f0, 0x1e2f9,
+ 0x1e950, 0x1e959,
+}; /* CR_Digit */
+
+/* 'Graph': [[:Graph:]] */
+static const OnigCodePoint CR_Graph[] = {
+ 671,
+ 0x0021, 0x007e,
+ 0x00a1, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a76,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x167f,
+ 0x1681, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd0, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x200b, 0x2027,
+ 0x202a, 0x202e,
+ 0x2030, 0x205e,
+ 0x2060, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e4f,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3001, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x4db5,
+ 0x4dc0, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab67,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xe000, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xfffd,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a48,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f00, 0x10f27,
+ 0x10f30, 0x10f59,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110cd, 0x110cd,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11146,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145f,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x11800, 0x1183b,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e4,
+ 0x11a00, 0x11a47,
+ 0x11a50, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef8,
+ 0x11fc0, 0x11ff1,
+ 0x11fff, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x13430, 0x13438,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e9a,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14f,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e2ff, 0x1e2ff,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ec71, 0x1ecb4,
+ 0x1ed01, 0x1ed3d,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xf0000, 0xffffd,
+ 0x100000, 0x10fffd,
+}; /* CR_Graph */
+
+/* 'Lower': [[:Lower:]] */
+static const OnigCodePoint CR_Lower[] = {
+ 649,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00df, 0x00f6,
+ 0x00f8, 0x00ff,
+ 0x0101, 0x0101,
+ 0x0103, 0x0103,
+ 0x0105, 0x0105,
+ 0x0107, 0x0107,
+ 0x0109, 0x0109,
+ 0x010b, 0x010b,
+ 0x010d, 0x010d,
+ 0x010f, 0x010f,
+ 0x0111, 0x0111,
+ 0x0113, 0x0113,
+ 0x0115, 0x0115,
+ 0x0117, 0x0117,
+ 0x0119, 0x0119,
+ 0x011b, 0x011b,
+ 0x011d, 0x011d,
+ 0x011f, 0x011f,
+ 0x0121, 0x0121,
+ 0x0123, 0x0123,
+ 0x0125, 0x0125,
+ 0x0127, 0x0127,
+ 0x0129, 0x0129,
+ 0x012b, 0x012b,
+ 0x012d, 0x012d,
+ 0x012f, 0x012f,
+ 0x0131, 0x0131,
+ 0x0133, 0x0133,
+ 0x0135, 0x0135,
+ 0x0137, 0x0138,
+ 0x013a, 0x013a,
+ 0x013c, 0x013c,
+ 0x013e, 0x013e,
+ 0x0140, 0x0140,
+ 0x0142, 0x0142,
+ 0x0144, 0x0144,
+ 0x0146, 0x0146,
+ 0x0148, 0x0149,
+ 0x014b, 0x014b,
+ 0x014d, 0x014d,
+ 0x014f, 0x014f,
+ 0x0151, 0x0151,
+ 0x0153, 0x0153,
+ 0x0155, 0x0155,
+ 0x0157, 0x0157,
+ 0x0159, 0x0159,
+ 0x015b, 0x015b,
+ 0x015d, 0x015d,
+ 0x015f, 0x015f,
+ 0x0161, 0x0161,
+ 0x0163, 0x0163,
+ 0x0165, 0x0165,
+ 0x0167, 0x0167,
+ 0x0169, 0x0169,
+ 0x016b, 0x016b,
+ 0x016d, 0x016d,
+ 0x016f, 0x016f,
+ 0x0171, 0x0171,
+ 0x0173, 0x0173,
+ 0x0175, 0x0175,
+ 0x0177, 0x0177,
+ 0x017a, 0x017a,
+ 0x017c, 0x017c,
+ 0x017e, 0x0180,
+ 0x0183, 0x0183,
+ 0x0185, 0x0185,
+ 0x0188, 0x0188,
+ 0x018c, 0x018d,
+ 0x0192, 0x0192,
+ 0x0195, 0x0195,
+ 0x0199, 0x019b,
+ 0x019e, 0x019e,
+ 0x01a1, 0x01a1,
+ 0x01a3, 0x01a3,
+ 0x01a5, 0x01a5,
+ 0x01a8, 0x01a8,
+ 0x01aa, 0x01ab,
+ 0x01ad, 0x01ad,
+ 0x01b0, 0x01b0,
+ 0x01b4, 0x01b4,
+ 0x01b6, 0x01b6,
+ 0x01b9, 0x01ba,
+ 0x01bd, 0x01bf,
+ 0x01c6, 0x01c6,
+ 0x01c9, 0x01c9,
+ 0x01cc, 0x01cc,
+ 0x01ce, 0x01ce,
+ 0x01d0, 0x01d0,
+ 0x01d2, 0x01d2,
+ 0x01d4, 0x01d4,
+ 0x01d6, 0x01d6,
+ 0x01d8, 0x01d8,
+ 0x01da, 0x01da,
+ 0x01dc, 0x01dd,
+ 0x01df, 0x01df,
+ 0x01e1, 0x01e1,
+ 0x01e3, 0x01e3,
+ 0x01e5, 0x01e5,
+ 0x01e7, 0x01e7,
+ 0x01e9, 0x01e9,
+ 0x01eb, 0x01eb,
+ 0x01ed, 0x01ed,
+ 0x01ef, 0x01f0,
+ 0x01f3, 0x01f3,
+ 0x01f5, 0x01f5,
+ 0x01f9, 0x01f9,
+ 0x01fb, 0x01fb,
+ 0x01fd, 0x01fd,
+ 0x01ff, 0x01ff,
+ 0x0201, 0x0201,
+ 0x0203, 0x0203,
+ 0x0205, 0x0205,
+ 0x0207, 0x0207,
+ 0x0209, 0x0209,
+ 0x020b, 0x020b,
+ 0x020d, 0x020d,
+ 0x020f, 0x020f,
+ 0x0211, 0x0211,
+ 0x0213, 0x0213,
+ 0x0215, 0x0215,
+ 0x0217, 0x0217,
+ 0x0219, 0x0219,
+ 0x021b, 0x021b,
+ 0x021d, 0x021d,
+ 0x021f, 0x021f,
+ 0x0221, 0x0221,
+ 0x0223, 0x0223,
+ 0x0225, 0x0225,
+ 0x0227, 0x0227,
+ 0x0229, 0x0229,
+ 0x022b, 0x022b,
+ 0x022d, 0x022d,
+ 0x022f, 0x022f,
+ 0x0231, 0x0231,
+ 0x0233, 0x0239,
+ 0x023c, 0x023c,
+ 0x023f, 0x0240,
+ 0x0242, 0x0242,
+ 0x0247, 0x0247,
+ 0x0249, 0x0249,
+ 0x024b, 0x024b,
+ 0x024d, 0x024d,
+ 0x024f, 0x0293,
+ 0x0295, 0x02b8,
+ 0x02c0, 0x02c1,
+ 0x02e0, 0x02e4,
+ 0x0345, 0x0345,
+ 0x0371, 0x0371,
+ 0x0373, 0x0373,
+ 0x0377, 0x0377,
+ 0x037a, 0x037d,
+ 0x0390, 0x0390,
+ 0x03ac, 0x03ce,
+ 0x03d0, 0x03d1,
+ 0x03d5, 0x03d7,
+ 0x03d9, 0x03d9,
+ 0x03db, 0x03db,
+ 0x03dd, 0x03dd,
+ 0x03df, 0x03df,
+ 0x03e1, 0x03e1,
+ 0x03e3, 0x03e3,
+ 0x03e5, 0x03e5,
+ 0x03e7, 0x03e7,
+ 0x03e9, 0x03e9,
+ 0x03eb, 0x03eb,
+ 0x03ed, 0x03ed,
+ 0x03ef, 0x03f3,
+ 0x03f5, 0x03f5,
+ 0x03f8, 0x03f8,
+ 0x03fb, 0x03fc,
+ 0x0430, 0x045f,
+ 0x0461, 0x0461,
+ 0x0463, 0x0463,
+ 0x0465, 0x0465,
+ 0x0467, 0x0467,
+ 0x0469, 0x0469,
+ 0x046b, 0x046b,
+ 0x046d, 0x046d,
+ 0x046f, 0x046f,
+ 0x0471, 0x0471,
+ 0x0473, 0x0473,
+ 0x0475, 0x0475,
+ 0x0477, 0x0477,
+ 0x0479, 0x0479,
+ 0x047b, 0x047b,
+ 0x047d, 0x047d,
+ 0x047f, 0x047f,
+ 0x0481, 0x0481,
+ 0x048b, 0x048b,
+ 0x048d, 0x048d,
+ 0x048f, 0x048f,
+ 0x0491, 0x0491,
+ 0x0493, 0x0493,
+ 0x0495, 0x0495,
+ 0x0497, 0x0497,
+ 0x0499, 0x0499,
+ 0x049b, 0x049b,
+ 0x049d, 0x049d,
+ 0x049f, 0x049f,
+ 0x04a1, 0x04a1,
+ 0x04a3, 0x04a3,
+ 0x04a5, 0x04a5,
+ 0x04a7, 0x04a7,
+ 0x04a9, 0x04a9,
+ 0x04ab, 0x04ab,
+ 0x04ad, 0x04ad,
+ 0x04af, 0x04af,
+ 0x04b1, 0x04b1,
+ 0x04b3, 0x04b3,
+ 0x04b5, 0x04b5,
+ 0x04b7, 0x04b7,
+ 0x04b9, 0x04b9,
+ 0x04bb, 0x04bb,
+ 0x04bd, 0x04bd,
+ 0x04bf, 0x04bf,
+ 0x04c2, 0x04c2,
+ 0x04c4, 0x04c4,
+ 0x04c6, 0x04c6,
+ 0x04c8, 0x04c8,
+ 0x04ca, 0x04ca,
+ 0x04cc, 0x04cc,
+ 0x04ce, 0x04cf,
+ 0x04d1, 0x04d1,
+ 0x04d3, 0x04d3,
+ 0x04d5, 0x04d5,
+ 0x04d7, 0x04d7,
+ 0x04d9, 0x04d9,
+ 0x04db, 0x04db,
+ 0x04dd, 0x04dd,
+ 0x04df, 0x04df,
+ 0x04e1, 0x04e1,
+ 0x04e3, 0x04e3,
+ 0x04e5, 0x04e5,
+ 0x04e7, 0x04e7,
+ 0x04e9, 0x04e9,
+ 0x04eb, 0x04eb,
+ 0x04ed, 0x04ed,
+ 0x04ef, 0x04ef,
+ 0x04f1, 0x04f1,
+ 0x04f3, 0x04f3,
+ 0x04f5, 0x04f5,
+ 0x04f7, 0x04f7,
+ 0x04f9, 0x04f9,
+ 0x04fb, 0x04fb,
+ 0x04fd, 0x04fd,
+ 0x04ff, 0x04ff,
+ 0x0501, 0x0501,
+ 0x0503, 0x0503,
+ 0x0505, 0x0505,
+ 0x0507, 0x0507,
+ 0x0509, 0x0509,
+ 0x050b, 0x050b,
+ 0x050d, 0x050d,
+ 0x050f, 0x050f,
+ 0x0511, 0x0511,
+ 0x0513, 0x0513,
+ 0x0515, 0x0515,
+ 0x0517, 0x0517,
+ 0x0519, 0x0519,
+ 0x051b, 0x051b,
+ 0x051d, 0x051d,
+ 0x051f, 0x051f,
+ 0x0521, 0x0521,
+ 0x0523, 0x0523,
+ 0x0525, 0x0525,
+ 0x0527, 0x0527,
+ 0x0529, 0x0529,
+ 0x052b, 0x052b,
+ 0x052d, 0x052d,
+ 0x052f, 0x052f,
+ 0x0560, 0x0588,
+ 0x10d0, 0x10fa,
+ 0x10fd, 0x10ff,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1d00, 0x1dbf,
+ 0x1e01, 0x1e01,
+ 0x1e03, 0x1e03,
+ 0x1e05, 0x1e05,
+ 0x1e07, 0x1e07,
+ 0x1e09, 0x1e09,
+ 0x1e0b, 0x1e0b,
+ 0x1e0d, 0x1e0d,
+ 0x1e0f, 0x1e0f,
+ 0x1e11, 0x1e11,
+ 0x1e13, 0x1e13,
+ 0x1e15, 0x1e15,
+ 0x1e17, 0x1e17,
+ 0x1e19, 0x1e19,
+ 0x1e1b, 0x1e1b,
+ 0x1e1d, 0x1e1d,
+ 0x1e1f, 0x1e1f,
+ 0x1e21, 0x1e21,
+ 0x1e23, 0x1e23,
+ 0x1e25, 0x1e25,
+ 0x1e27, 0x1e27,
+ 0x1e29, 0x1e29,
+ 0x1e2b, 0x1e2b,
+ 0x1e2d, 0x1e2d,
+ 0x1e2f, 0x1e2f,
+ 0x1e31, 0x1e31,
+ 0x1e33, 0x1e33,
+ 0x1e35, 0x1e35,
+ 0x1e37, 0x1e37,
+ 0x1e39, 0x1e39,
+ 0x1e3b, 0x1e3b,
+ 0x1e3d, 0x1e3d,
+ 0x1e3f, 0x1e3f,
+ 0x1e41, 0x1e41,
+ 0x1e43, 0x1e43,
+ 0x1e45, 0x1e45,
+ 0x1e47, 0x1e47,
+ 0x1e49, 0x1e49,
+ 0x1e4b, 0x1e4b,
+ 0x1e4d, 0x1e4d,
+ 0x1e4f, 0x1e4f,
+ 0x1e51, 0x1e51,
+ 0x1e53, 0x1e53,
+ 0x1e55, 0x1e55,
+ 0x1e57, 0x1e57,
+ 0x1e59, 0x1e59,
+ 0x1e5b, 0x1e5b,
+ 0x1e5d, 0x1e5d,
+ 0x1e5f, 0x1e5f,
+ 0x1e61, 0x1e61,
+ 0x1e63, 0x1e63,
+ 0x1e65, 0x1e65,
+ 0x1e67, 0x1e67,
+ 0x1e69, 0x1e69,
+ 0x1e6b, 0x1e6b,
+ 0x1e6d, 0x1e6d,
+ 0x1e6f, 0x1e6f,
+ 0x1e71, 0x1e71,
+ 0x1e73, 0x1e73,
+ 0x1e75, 0x1e75,
+ 0x1e77, 0x1e77,
+ 0x1e79, 0x1e79,
+ 0x1e7b, 0x1e7b,
+ 0x1e7d, 0x1e7d,
+ 0x1e7f, 0x1e7f,
+ 0x1e81, 0x1e81,
+ 0x1e83, 0x1e83,
+ 0x1e85, 0x1e85,
+ 0x1e87, 0x1e87,
+ 0x1e89, 0x1e89,
+ 0x1e8b, 0x1e8b,
+ 0x1e8d, 0x1e8d,
+ 0x1e8f, 0x1e8f,
+ 0x1e91, 0x1e91,
+ 0x1e93, 0x1e93,
+ 0x1e95, 0x1e9d,
+ 0x1e9f, 0x1e9f,
+ 0x1ea1, 0x1ea1,
+ 0x1ea3, 0x1ea3,
+ 0x1ea5, 0x1ea5,
+ 0x1ea7, 0x1ea7,
+ 0x1ea9, 0x1ea9,
+ 0x1eab, 0x1eab,
+ 0x1ead, 0x1ead,
+ 0x1eaf, 0x1eaf,
+ 0x1eb1, 0x1eb1,
+ 0x1eb3, 0x1eb3,
+ 0x1eb5, 0x1eb5,
+ 0x1eb7, 0x1eb7,
+ 0x1eb9, 0x1eb9,
+ 0x1ebb, 0x1ebb,
+ 0x1ebd, 0x1ebd,
+ 0x1ebf, 0x1ebf,
+ 0x1ec1, 0x1ec1,
+ 0x1ec3, 0x1ec3,
+ 0x1ec5, 0x1ec5,
+ 0x1ec7, 0x1ec7,
+ 0x1ec9, 0x1ec9,
+ 0x1ecb, 0x1ecb,
+ 0x1ecd, 0x1ecd,
+ 0x1ecf, 0x1ecf,
+ 0x1ed1, 0x1ed1,
+ 0x1ed3, 0x1ed3,
+ 0x1ed5, 0x1ed5,
+ 0x1ed7, 0x1ed7,
+ 0x1ed9, 0x1ed9,
+ 0x1edb, 0x1edb,
+ 0x1edd, 0x1edd,
+ 0x1edf, 0x1edf,
+ 0x1ee1, 0x1ee1,
+ 0x1ee3, 0x1ee3,
+ 0x1ee5, 0x1ee5,
+ 0x1ee7, 0x1ee7,
+ 0x1ee9, 0x1ee9,
+ 0x1eeb, 0x1eeb,
+ 0x1eed, 0x1eed,
+ 0x1eef, 0x1eef,
+ 0x1ef1, 0x1ef1,
+ 0x1ef3, 0x1ef3,
+ 0x1ef5, 0x1ef5,
+ 0x1ef7, 0x1ef7,
+ 0x1ef9, 0x1ef9,
+ 0x1efb, 0x1efb,
+ 0x1efd, 0x1efd,
+ 0x1eff, 0x1f07,
+ 0x1f10, 0x1f15,
+ 0x1f20, 0x1f27,
+ 0x1f30, 0x1f37,
+ 0x1f40, 0x1f45,
+ 0x1f50, 0x1f57,
+ 0x1f60, 0x1f67,
+ 0x1f70, 0x1f7d,
+ 0x1f80, 0x1f87,
+ 0x1f90, 0x1f97,
+ 0x1fa0, 0x1fa7,
+ 0x1fb0, 0x1fb4,
+ 0x1fb6, 0x1fb7,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fc7,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fd7,
+ 0x1fe0, 0x1fe7,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ff7,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x210a, 0x210a,
+ 0x210e, 0x210f,
+ 0x2113, 0x2113,
+ 0x212f, 0x212f,
+ 0x2134, 0x2134,
+ 0x2139, 0x2139,
+ 0x213c, 0x213d,
+ 0x2146, 0x2149,
+ 0x214e, 0x214e,
+ 0x2170, 0x217f,
+ 0x2184, 0x2184,
+ 0x24d0, 0x24e9,
+ 0x2c30, 0x2c5e,
+ 0x2c61, 0x2c61,
+ 0x2c65, 0x2c66,
+ 0x2c68, 0x2c68,
+ 0x2c6a, 0x2c6a,
+ 0x2c6c, 0x2c6c,
+ 0x2c71, 0x2c71,
+ 0x2c73, 0x2c74,
+ 0x2c76, 0x2c7d,
+ 0x2c81, 0x2c81,
+ 0x2c83, 0x2c83,
+ 0x2c85, 0x2c85,
+ 0x2c87, 0x2c87,
+ 0x2c89, 0x2c89,
+ 0x2c8b, 0x2c8b,
+ 0x2c8d, 0x2c8d,
+ 0x2c8f, 0x2c8f,
+ 0x2c91, 0x2c91,
+ 0x2c93, 0x2c93,
+ 0x2c95, 0x2c95,
+ 0x2c97, 0x2c97,
+ 0x2c99, 0x2c99,
+ 0x2c9b, 0x2c9b,
+ 0x2c9d, 0x2c9d,
+ 0x2c9f, 0x2c9f,
+ 0x2ca1, 0x2ca1,
+ 0x2ca3, 0x2ca3,
+ 0x2ca5, 0x2ca5,
+ 0x2ca7, 0x2ca7,
+ 0x2ca9, 0x2ca9,
+ 0x2cab, 0x2cab,
+ 0x2cad, 0x2cad,
+ 0x2caf, 0x2caf,
+ 0x2cb1, 0x2cb1,
+ 0x2cb3, 0x2cb3,
+ 0x2cb5, 0x2cb5,
+ 0x2cb7, 0x2cb7,
+ 0x2cb9, 0x2cb9,
+ 0x2cbb, 0x2cbb,
+ 0x2cbd, 0x2cbd,
+ 0x2cbf, 0x2cbf,
+ 0x2cc1, 0x2cc1,
+ 0x2cc3, 0x2cc3,
+ 0x2cc5, 0x2cc5,
+ 0x2cc7, 0x2cc7,
+ 0x2cc9, 0x2cc9,
+ 0x2ccb, 0x2ccb,
+ 0x2ccd, 0x2ccd,
+ 0x2ccf, 0x2ccf,
+ 0x2cd1, 0x2cd1,
+ 0x2cd3, 0x2cd3,
+ 0x2cd5, 0x2cd5,
+ 0x2cd7, 0x2cd7,
+ 0x2cd9, 0x2cd9,
+ 0x2cdb, 0x2cdb,
+ 0x2cdd, 0x2cdd,
+ 0x2cdf, 0x2cdf,
+ 0x2ce1, 0x2ce1,
+ 0x2ce3, 0x2ce4,
+ 0x2cec, 0x2cec,
+ 0x2cee, 0x2cee,
+ 0x2cf3, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0xa641, 0xa641,
+ 0xa643, 0xa643,
+ 0xa645, 0xa645,
+ 0xa647, 0xa647,
+ 0xa649, 0xa649,
+ 0xa64b, 0xa64b,
+ 0xa64d, 0xa64d,
+ 0xa64f, 0xa64f,
+ 0xa651, 0xa651,
+ 0xa653, 0xa653,
+ 0xa655, 0xa655,
+ 0xa657, 0xa657,
+ 0xa659, 0xa659,
+ 0xa65b, 0xa65b,
+ 0xa65d, 0xa65d,
+ 0xa65f, 0xa65f,
+ 0xa661, 0xa661,
+ 0xa663, 0xa663,
+ 0xa665, 0xa665,
+ 0xa667, 0xa667,
+ 0xa669, 0xa669,
+ 0xa66b, 0xa66b,
+ 0xa66d, 0xa66d,
+ 0xa681, 0xa681,
+ 0xa683, 0xa683,
+ 0xa685, 0xa685,
+ 0xa687, 0xa687,
+ 0xa689, 0xa689,
+ 0xa68b, 0xa68b,
+ 0xa68d, 0xa68d,
+ 0xa68f, 0xa68f,
+ 0xa691, 0xa691,
+ 0xa693, 0xa693,
+ 0xa695, 0xa695,
+ 0xa697, 0xa697,
+ 0xa699, 0xa699,
+ 0xa69b, 0xa69d,
+ 0xa723, 0xa723,
+ 0xa725, 0xa725,
+ 0xa727, 0xa727,
+ 0xa729, 0xa729,
+ 0xa72b, 0xa72b,
+ 0xa72d, 0xa72d,
+ 0xa72f, 0xa731,
+ 0xa733, 0xa733,
+ 0xa735, 0xa735,
+ 0xa737, 0xa737,
+ 0xa739, 0xa739,
+ 0xa73b, 0xa73b,
+ 0xa73d, 0xa73d,
+ 0xa73f, 0xa73f,
+ 0xa741, 0xa741,
+ 0xa743, 0xa743,
+ 0xa745, 0xa745,
+ 0xa747, 0xa747,
+ 0xa749, 0xa749,
+ 0xa74b, 0xa74b,
+ 0xa74d, 0xa74d,
+ 0xa74f, 0xa74f,
+ 0xa751, 0xa751,
+ 0xa753, 0xa753,
+ 0xa755, 0xa755,
+ 0xa757, 0xa757,
+ 0xa759, 0xa759,
+ 0xa75b, 0xa75b,
+ 0xa75d, 0xa75d,
+ 0xa75f, 0xa75f,
+ 0xa761, 0xa761,
+ 0xa763, 0xa763,
+ 0xa765, 0xa765,
+ 0xa767, 0xa767,
+ 0xa769, 0xa769,
+ 0xa76b, 0xa76b,
+ 0xa76d, 0xa76d,
+ 0xa76f, 0xa778,
+ 0xa77a, 0xa77a,
+ 0xa77c, 0xa77c,
+ 0xa77f, 0xa77f,
+ 0xa781, 0xa781,
+ 0xa783, 0xa783,
+ 0xa785, 0xa785,
+ 0xa787, 0xa787,
+ 0xa78c, 0xa78c,
+ 0xa78e, 0xa78e,
+ 0xa791, 0xa791,
+ 0xa793, 0xa795,
+ 0xa797, 0xa797,
+ 0xa799, 0xa799,
+ 0xa79b, 0xa79b,
+ 0xa79d, 0xa79d,
+ 0xa79f, 0xa79f,
+ 0xa7a1, 0xa7a1,
+ 0xa7a3, 0xa7a3,
+ 0xa7a5, 0xa7a5,
+ 0xa7a7, 0xa7a7,
+ 0xa7a9, 0xa7a9,
+ 0xa7af, 0xa7af,
+ 0xa7b5, 0xa7b5,
+ 0xa7b7, 0xa7b7,
+ 0xa7b9, 0xa7b9,
+ 0xa7bb, 0xa7bb,
+ 0xa7bd, 0xa7bd,
+ 0xa7bf, 0xa7bf,
+ 0xa7c3, 0xa7c3,
+ 0xa7f8, 0xa7fa,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff41, 0xff5a,
+ 0x10428, 0x1044f,
+ 0x104d8, 0x104fb,
+ 0x10cc0, 0x10cf2,
+ 0x118c0, 0x118df,
+ 0x16e60, 0x16e7f,
+ 0x1d41a, 0x1d433,
+ 0x1d44e, 0x1d454,
+ 0x1d456, 0x1d467,
+ 0x1d482, 0x1d49b,
+ 0x1d4b6, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d4cf,
+ 0x1d4ea, 0x1d503,
+ 0x1d51e, 0x1d537,
+ 0x1d552, 0x1d56b,
+ 0x1d586, 0x1d59f,
+ 0x1d5ba, 0x1d5d3,
+ 0x1d5ee, 0x1d607,
+ 0x1d622, 0x1d63b,
+ 0x1d656, 0x1d66f,
+ 0x1d68a, 0x1d6a5,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6e1,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d71b,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d755,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d78f,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7c9,
+ 0x1d7cb, 0x1d7cb,
+ 0x1e922, 0x1e943,
+}; /* CR_Lower */
+
+/* 'Print': [[:Print:]] */
+static const OnigCodePoint CR_Print[] = {
+ 668,
+ 0x0020, 0x007e,
+ 0x00a0, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a76,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd0, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2027,
+ 0x202a, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e4f,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x4db5,
+ 0x4dc0, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab67,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xe000, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xfffd,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a48,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f00, 0x10f27,
+ 0x10f30, 0x10f59,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110cd, 0x110cd,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11146,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145f,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x11800, 0x1183b,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e4,
+ 0x11a00, 0x11a47,
+ 0x11a50, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef8,
+ 0x11fc0, 0x11ff1,
+ 0x11fff, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x13430, 0x13438,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e9a,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14f,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e2ff, 0x1e2ff,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ec71, 0x1ecb4,
+ 0x1ed01, 0x1ed3d,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xf0000, 0xffffd,
+ 0x100000, 0x10fffd,
+}; /* CR_Print */
+
+/* 'XPosixPunct': [[:Punct:]] */
+static const OnigCodePoint CR_XPosixPunct[] = {
+ 177,
+ 0x0021, 0x002f,
+ 0x003a, 0x0040,
+ 0x005b, 0x0060,
+ 0x007b, 0x007e,
+ 0x00a1, 0x00a1,
+ 0x00a7, 0x00a7,
+ 0x00ab, 0x00ab,
+ 0x00b6, 0x00b7,
+ 0x00bb, 0x00bb,
+ 0x00bf, 0x00bf,
+ 0x037e, 0x037e,
+ 0x0387, 0x0387,
+ 0x055a, 0x055f,
+ 0x0589, 0x058a,
+ 0x05be, 0x05be,
+ 0x05c0, 0x05c0,
+ 0x05c3, 0x05c3,
+ 0x05c6, 0x05c6,
+ 0x05f3, 0x05f4,
+ 0x0609, 0x060a,
+ 0x060c, 0x060d,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x066a, 0x066d,
+ 0x06d4, 0x06d4,
+ 0x0700, 0x070d,
+ 0x07f7, 0x07f9,
+ 0x0830, 0x083e,
+ 0x085e, 0x085e,
+ 0x0964, 0x0965,
+ 0x0970, 0x0970,
+ 0x09fd, 0x09fd,
+ 0x0a76, 0x0a76,
+ 0x0af0, 0x0af0,
+ 0x0c77, 0x0c77,
+ 0x0c84, 0x0c84,
+ 0x0df4, 0x0df4,
+ 0x0e4f, 0x0e4f,
+ 0x0e5a, 0x0e5b,
+ 0x0f04, 0x0f12,
+ 0x0f14, 0x0f14,
+ 0x0f3a, 0x0f3d,
+ 0x0f85, 0x0f85,
+ 0x0fd0, 0x0fd4,
+ 0x0fd9, 0x0fda,
+ 0x104a, 0x104f,
+ 0x10fb, 0x10fb,
+ 0x1360, 0x1368,
+ 0x1400, 0x1400,
+ 0x166e, 0x166e,
+ 0x169b, 0x169c,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x17d4, 0x17d6,
+ 0x17d8, 0x17da,
+ 0x1800, 0x180a,
+ 0x1944, 0x1945,
+ 0x1a1e, 0x1a1f,
+ 0x1aa0, 0x1aa6,
+ 0x1aa8, 0x1aad,
+ 0x1b5a, 0x1b60,
+ 0x1bfc, 0x1bff,
+ 0x1c3b, 0x1c3f,
+ 0x1c7e, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd3, 0x1cd3,
+ 0x2010, 0x2027,
+ 0x2030, 0x2043,
+ 0x2045, 0x2051,
+ 0x2053, 0x205e,
+ 0x207d, 0x207e,
+ 0x208d, 0x208e,
+ 0x2308, 0x230b,
+ 0x2329, 0x232a,
+ 0x2768, 0x2775,
+ 0x27c5, 0x27c6,
+ 0x27e6, 0x27ef,
+ 0x2983, 0x2998,
+ 0x29d8, 0x29db,
+ 0x29fc, 0x29fd,
+ 0x2cf9, 0x2cfc,
+ 0x2cfe, 0x2cff,
+ 0x2d70, 0x2d70,
+ 0x2e00, 0x2e2e,
+ 0x2e30, 0x2e4f,
+ 0x3001, 0x3003,
+ 0x3008, 0x3011,
+ 0x3014, 0x301f,
+ 0x3030, 0x3030,
+ 0x303d, 0x303d,
+ 0x30a0, 0x30a0,
+ 0x30fb, 0x30fb,
+ 0xa4fe, 0xa4ff,
+ 0xa60d, 0xa60f,
+ 0xa673, 0xa673,
+ 0xa67e, 0xa67e,
+ 0xa6f2, 0xa6f7,
+ 0xa874, 0xa877,
+ 0xa8ce, 0xa8cf,
+ 0xa8f8, 0xa8fa,
+ 0xa8fc, 0xa8fc,
+ 0xa92e, 0xa92f,
+ 0xa95f, 0xa95f,
+ 0xa9c1, 0xa9cd,
+ 0xa9de, 0xa9df,
+ 0xaa5c, 0xaa5f,
+ 0xaade, 0xaadf,
+ 0xaaf0, 0xaaf1,
+ 0xabeb, 0xabeb,
+ 0xfd3e, 0xfd3f,
+ 0xfe10, 0xfe19,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe61,
+ 0xfe63, 0xfe63,
+ 0xfe68, 0xfe68,
+ 0xfe6a, 0xfe6b,
+ 0xff01, 0xff03,
+ 0xff05, 0xff0a,
+ 0xff0c, 0xff0f,
+ 0xff1a, 0xff1b,
+ 0xff1f, 0xff20,
+ 0xff3b, 0xff3d,
+ 0xff3f, 0xff3f,
+ 0xff5b, 0xff5b,
+ 0xff5d, 0xff5d,
+ 0xff5f, 0xff65,
+ 0x10100, 0x10102,
+ 0x1039f, 0x1039f,
+ 0x103d0, 0x103d0,
+ 0x1056f, 0x1056f,
+ 0x10857, 0x10857,
+ 0x1091f, 0x1091f,
+ 0x1093f, 0x1093f,
+ 0x10a50, 0x10a58,
+ 0x10a7f, 0x10a7f,
+ 0x10af0, 0x10af6,
+ 0x10b39, 0x10b3f,
+ 0x10b99, 0x10b9c,
+ 0x10f55, 0x10f59,
+ 0x11047, 0x1104d,
+ 0x110bb, 0x110bc,
+ 0x110be, 0x110c1,
+ 0x11140, 0x11143,
+ 0x11174, 0x11175,
+ 0x111c5, 0x111c8,
+ 0x111cd, 0x111cd,
+ 0x111db, 0x111db,
+ 0x111dd, 0x111df,
+ 0x11238, 0x1123d,
+ 0x112a9, 0x112a9,
+ 0x1144b, 0x1144f,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145d,
+ 0x114c6, 0x114c6,
+ 0x115c1, 0x115d7,
+ 0x11641, 0x11643,
+ 0x11660, 0x1166c,
+ 0x1173c, 0x1173e,
+ 0x1183b, 0x1183b,
+ 0x119e2, 0x119e2,
+ 0x11a3f, 0x11a46,
+ 0x11a9a, 0x11a9c,
+ 0x11a9e, 0x11aa2,
+ 0x11c41, 0x11c45,
+ 0x11c70, 0x11c71,
+ 0x11ef7, 0x11ef8,
+ 0x11fff, 0x11fff,
+ 0x12470, 0x12474,
+ 0x16a6e, 0x16a6f,
+ 0x16af5, 0x16af5,
+ 0x16b37, 0x16b3b,
+ 0x16b44, 0x16b44,
+ 0x16e97, 0x16e9a,
+ 0x16fe2, 0x16fe2,
+ 0x1bc9f, 0x1bc9f,
+ 0x1da87, 0x1da8b,
+ 0x1e95e, 0x1e95f,
+}; /* CR_XPosixPunct */
+
+/* 'Space': [[:Space:]] */
+static const OnigCodePoint CR_Space[] = {
+ 10,
+ 0x0009, 0x000d,
+ 0x0020, 0x0020,
+ 0x0085, 0x0085,
+ 0x00a0, 0x00a0,
+ 0x1680, 0x1680,
+ 0x2000, 0x200a,
+ 0x2028, 0x2029,
+ 0x202f, 0x202f,
+ 0x205f, 0x205f,
+ 0x3000, 0x3000,
+}; /* CR_Space */
+
+/* 'Upper': [[:Upper:]] */
+static const OnigCodePoint CR_Upper[] = {
+ 641,
+ 0x0041, 0x005a,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00de,
+ 0x0100, 0x0100,
+ 0x0102, 0x0102,
+ 0x0104, 0x0104,
+ 0x0106, 0x0106,
+ 0x0108, 0x0108,
+ 0x010a, 0x010a,
+ 0x010c, 0x010c,
+ 0x010e, 0x010e,
+ 0x0110, 0x0110,
+ 0x0112, 0x0112,
+ 0x0114, 0x0114,
+ 0x0116, 0x0116,
+ 0x0118, 0x0118,
+ 0x011a, 0x011a,
+ 0x011c, 0x011c,
+ 0x011e, 0x011e,
+ 0x0120, 0x0120,
+ 0x0122, 0x0122,
+ 0x0124, 0x0124,
+ 0x0126, 0x0126,
+ 0x0128, 0x0128,
+ 0x012a, 0x012a,
+ 0x012c, 0x012c,
+ 0x012e, 0x012e,
+ 0x0130, 0x0130,
+ 0x0132, 0x0132,
+ 0x0134, 0x0134,
+ 0x0136, 0x0136,
+ 0x0139, 0x0139,
+ 0x013b, 0x013b,
+ 0x013d, 0x013d,
+ 0x013f, 0x013f,
+ 0x0141, 0x0141,
+ 0x0143, 0x0143,
+ 0x0145, 0x0145,
+ 0x0147, 0x0147,
+ 0x014a, 0x014a,
+ 0x014c, 0x014c,
+ 0x014e, 0x014e,
+ 0x0150, 0x0150,
+ 0x0152, 0x0152,
+ 0x0154, 0x0154,
+ 0x0156, 0x0156,
+ 0x0158, 0x0158,
+ 0x015a, 0x015a,
+ 0x015c, 0x015c,
+ 0x015e, 0x015e,
+ 0x0160, 0x0160,
+ 0x0162, 0x0162,
+ 0x0164, 0x0164,
+ 0x0166, 0x0166,
+ 0x0168, 0x0168,
+ 0x016a, 0x016a,
+ 0x016c, 0x016c,
+ 0x016e, 0x016e,
+ 0x0170, 0x0170,
+ 0x0172, 0x0172,
+ 0x0174, 0x0174,
+ 0x0176, 0x0176,
+ 0x0178, 0x0179,
+ 0x017b, 0x017b,
+ 0x017d, 0x017d,
+ 0x0181, 0x0182,
+ 0x0184, 0x0184,
+ 0x0186, 0x0187,
+ 0x0189, 0x018b,
+ 0x018e, 0x0191,
+ 0x0193, 0x0194,
+ 0x0196, 0x0198,
+ 0x019c, 0x019d,
+ 0x019f, 0x01a0,
+ 0x01a2, 0x01a2,
+ 0x01a4, 0x01a4,
+ 0x01a6, 0x01a7,
+ 0x01a9, 0x01a9,
+ 0x01ac, 0x01ac,
+ 0x01ae, 0x01af,
+ 0x01b1, 0x01b3,
+ 0x01b5, 0x01b5,
+ 0x01b7, 0x01b8,
+ 0x01bc, 0x01bc,
+ 0x01c4, 0x01c4,
+ 0x01c7, 0x01c7,
+ 0x01ca, 0x01ca,
+ 0x01cd, 0x01cd,
+ 0x01cf, 0x01cf,
+ 0x01d1, 0x01d1,
+ 0x01d3, 0x01d3,
+ 0x01d5, 0x01d5,
+ 0x01d7, 0x01d7,
+ 0x01d9, 0x01d9,
+ 0x01db, 0x01db,
+ 0x01de, 0x01de,
+ 0x01e0, 0x01e0,
+ 0x01e2, 0x01e2,
+ 0x01e4, 0x01e4,
+ 0x01e6, 0x01e6,
+ 0x01e8, 0x01e8,
+ 0x01ea, 0x01ea,
+ 0x01ec, 0x01ec,
+ 0x01ee, 0x01ee,
+ 0x01f1, 0x01f1,
+ 0x01f4, 0x01f4,
+ 0x01f6, 0x01f8,
+ 0x01fa, 0x01fa,
+ 0x01fc, 0x01fc,
+ 0x01fe, 0x01fe,
+ 0x0200, 0x0200,
+ 0x0202, 0x0202,
+ 0x0204, 0x0204,
+ 0x0206, 0x0206,
+ 0x0208, 0x0208,
+ 0x020a, 0x020a,
+ 0x020c, 0x020c,
+ 0x020e, 0x020e,
+ 0x0210, 0x0210,
+ 0x0212, 0x0212,
+ 0x0214, 0x0214,
+ 0x0216, 0x0216,
+ 0x0218, 0x0218,
+ 0x021a, 0x021a,
+ 0x021c, 0x021c,
+ 0x021e, 0x021e,
+ 0x0220, 0x0220,
+ 0x0222, 0x0222,
+ 0x0224, 0x0224,
+ 0x0226, 0x0226,
+ 0x0228, 0x0228,
+ 0x022a, 0x022a,
+ 0x022c, 0x022c,
+ 0x022e, 0x022e,
+ 0x0230, 0x0230,
+ 0x0232, 0x0232,
+ 0x023a, 0x023b,
+ 0x023d, 0x023e,
+ 0x0241, 0x0241,
+ 0x0243, 0x0246,
+ 0x0248, 0x0248,
+ 0x024a, 0x024a,
+ 0x024c, 0x024c,
+ 0x024e, 0x024e,
+ 0x0370, 0x0370,
+ 0x0372, 0x0372,
+ 0x0376, 0x0376,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x038f,
+ 0x0391, 0x03a1,
+ 0x03a3, 0x03ab,
+ 0x03cf, 0x03cf,
+ 0x03d2, 0x03d4,
+ 0x03d8, 0x03d8,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03e2,
+ 0x03e4, 0x03e4,
+ 0x03e6, 0x03e6,
+ 0x03e8, 0x03e8,
+ 0x03ea, 0x03ea,
+ 0x03ec, 0x03ec,
+ 0x03ee, 0x03ee,
+ 0x03f4, 0x03f4,
+ 0x03f7, 0x03f7,
+ 0x03f9, 0x03fa,
+ 0x03fd, 0x042f,
+ 0x0460, 0x0460,
+ 0x0462, 0x0462,
+ 0x0464, 0x0464,
+ 0x0466, 0x0466,
+ 0x0468, 0x0468,
+ 0x046a, 0x046a,
+ 0x046c, 0x046c,
+ 0x046e, 0x046e,
+ 0x0470, 0x0470,
+ 0x0472, 0x0472,
+ 0x0474, 0x0474,
+ 0x0476, 0x0476,
+ 0x0478, 0x0478,
+ 0x047a, 0x047a,
+ 0x047c, 0x047c,
+ 0x047e, 0x047e,
+ 0x0480, 0x0480,
+ 0x048a, 0x048a,
+ 0x048c, 0x048c,
+ 0x048e, 0x048e,
+ 0x0490, 0x0490,
+ 0x0492, 0x0492,
+ 0x0494, 0x0494,
+ 0x0496, 0x0496,
+ 0x0498, 0x0498,
+ 0x049a, 0x049a,
+ 0x049c, 0x049c,
+ 0x049e, 0x049e,
+ 0x04a0, 0x04a0,
+ 0x04a2, 0x04a2,
+ 0x04a4, 0x04a4,
+ 0x04a6, 0x04a6,
+ 0x04a8, 0x04a8,
+ 0x04aa, 0x04aa,
+ 0x04ac, 0x04ac,
+ 0x04ae, 0x04ae,
+ 0x04b0, 0x04b0,
+ 0x04b2, 0x04b2,
+ 0x04b4, 0x04b4,
+ 0x04b6, 0x04b6,
+ 0x04b8, 0x04b8,
+ 0x04ba, 0x04ba,
+ 0x04bc, 0x04bc,
+ 0x04be, 0x04be,
+ 0x04c0, 0x04c1,
+ 0x04c3, 0x04c3,
+ 0x04c5, 0x04c5,
+ 0x04c7, 0x04c7,
+ 0x04c9, 0x04c9,
+ 0x04cb, 0x04cb,
+ 0x04cd, 0x04cd,
+ 0x04d0, 0x04d0,
+ 0x04d2, 0x04d2,
+ 0x04d4, 0x04d4,
+ 0x04d6, 0x04d6,
+ 0x04d8, 0x04d8,
+ 0x04da, 0x04da,
+ 0x04dc, 0x04dc,
+ 0x04de, 0x04de,
+ 0x04e0, 0x04e0,
+ 0x04e2, 0x04e2,
+ 0x04e4, 0x04e4,
+ 0x04e6, 0x04e6,
+ 0x04e8, 0x04e8,
+ 0x04ea, 0x04ea,
+ 0x04ec, 0x04ec,
+ 0x04ee, 0x04ee,
+ 0x04f0, 0x04f0,
+ 0x04f2, 0x04f2,
+ 0x04f4, 0x04f4,
+ 0x04f6, 0x04f6,
+ 0x04f8, 0x04f8,
+ 0x04fa, 0x04fa,
+ 0x04fc, 0x04fc,
+ 0x04fe, 0x04fe,
+ 0x0500, 0x0500,
+ 0x0502, 0x0502,
+ 0x0504, 0x0504,
+ 0x0506, 0x0506,
+ 0x0508, 0x0508,
+ 0x050a, 0x050a,
+ 0x050c, 0x050c,
+ 0x050e, 0x050e,
+ 0x0510, 0x0510,
+ 0x0512, 0x0512,
+ 0x0514, 0x0514,
+ 0x0516, 0x0516,
+ 0x0518, 0x0518,
+ 0x051a, 0x051a,
+ 0x051c, 0x051c,
+ 0x051e, 0x051e,
+ 0x0520, 0x0520,
+ 0x0522, 0x0522,
+ 0x0524, 0x0524,
+ 0x0526, 0x0526,
+ 0x0528, 0x0528,
+ 0x052a, 0x052a,
+ 0x052c, 0x052c,
+ 0x052e, 0x052e,
+ 0x0531, 0x0556,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x13a0, 0x13f5,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1e00, 0x1e00,
+ 0x1e02, 0x1e02,
+ 0x1e04, 0x1e04,
+ 0x1e06, 0x1e06,
+ 0x1e08, 0x1e08,
+ 0x1e0a, 0x1e0a,
+ 0x1e0c, 0x1e0c,
+ 0x1e0e, 0x1e0e,
+ 0x1e10, 0x1e10,
+ 0x1e12, 0x1e12,
+ 0x1e14, 0x1e14,
+ 0x1e16, 0x1e16,
+ 0x1e18, 0x1e18,
+ 0x1e1a, 0x1e1a,
+ 0x1e1c, 0x1e1c,
+ 0x1e1e, 0x1e1e,
+ 0x1e20, 0x1e20,
+ 0x1e22, 0x1e22,
+ 0x1e24, 0x1e24,
+ 0x1e26, 0x1e26,
+ 0x1e28, 0x1e28,
+ 0x1e2a, 0x1e2a,
+ 0x1e2c, 0x1e2c,
+ 0x1e2e, 0x1e2e,
+ 0x1e30, 0x1e30,
+ 0x1e32, 0x1e32,
+ 0x1e34, 0x1e34,
+ 0x1e36, 0x1e36,
+ 0x1e38, 0x1e38,
+ 0x1e3a, 0x1e3a,
+ 0x1e3c, 0x1e3c,
+ 0x1e3e, 0x1e3e,
+ 0x1e40, 0x1e40,
+ 0x1e42, 0x1e42,
+ 0x1e44, 0x1e44,
+ 0x1e46, 0x1e46,
+ 0x1e48, 0x1e48,
+ 0x1e4a, 0x1e4a,
+ 0x1e4c, 0x1e4c,
+ 0x1e4e, 0x1e4e,
+ 0x1e50, 0x1e50,
+ 0x1e52, 0x1e52,
+ 0x1e54, 0x1e54,
+ 0x1e56, 0x1e56,
+ 0x1e58, 0x1e58,
+ 0x1e5a, 0x1e5a,
+ 0x1e5c, 0x1e5c,
+ 0x1e5e, 0x1e5e,
+ 0x1e60, 0x1e60,
+ 0x1e62, 0x1e62,
+ 0x1e64, 0x1e64,
+ 0x1e66, 0x1e66,
+ 0x1e68, 0x1e68,
+ 0x1e6a, 0x1e6a,
+ 0x1e6c, 0x1e6c,
+ 0x1e6e, 0x1e6e,
+ 0x1e70, 0x1e70,
+ 0x1e72, 0x1e72,
+ 0x1e74, 0x1e74,
+ 0x1e76, 0x1e76,
+ 0x1e78, 0x1e78,
+ 0x1e7a, 0x1e7a,
+ 0x1e7c, 0x1e7c,
+ 0x1e7e, 0x1e7e,
+ 0x1e80, 0x1e80,
+ 0x1e82, 0x1e82,
+ 0x1e84, 0x1e84,
+ 0x1e86, 0x1e86,
+ 0x1e88, 0x1e88,
+ 0x1e8a, 0x1e8a,
+ 0x1e8c, 0x1e8c,
+ 0x1e8e, 0x1e8e,
+ 0x1e90, 0x1e90,
+ 0x1e92, 0x1e92,
+ 0x1e94, 0x1e94,
+ 0x1e9e, 0x1e9e,
+ 0x1ea0, 0x1ea0,
+ 0x1ea2, 0x1ea2,
+ 0x1ea4, 0x1ea4,
+ 0x1ea6, 0x1ea6,
+ 0x1ea8, 0x1ea8,
+ 0x1eaa, 0x1eaa,
+ 0x1eac, 0x1eac,
+ 0x1eae, 0x1eae,
+ 0x1eb0, 0x1eb0,
+ 0x1eb2, 0x1eb2,
+ 0x1eb4, 0x1eb4,
+ 0x1eb6, 0x1eb6,
+ 0x1eb8, 0x1eb8,
+ 0x1eba, 0x1eba,
+ 0x1ebc, 0x1ebc,
+ 0x1ebe, 0x1ebe,
+ 0x1ec0, 0x1ec0,
+ 0x1ec2, 0x1ec2,
+ 0x1ec4, 0x1ec4,
+ 0x1ec6, 0x1ec6,
+ 0x1ec8, 0x1ec8,
+ 0x1eca, 0x1eca,
+ 0x1ecc, 0x1ecc,
+ 0x1ece, 0x1ece,
+ 0x1ed0, 0x1ed0,
+ 0x1ed2, 0x1ed2,
+ 0x1ed4, 0x1ed4,
+ 0x1ed6, 0x1ed6,
+ 0x1ed8, 0x1ed8,
+ 0x1eda, 0x1eda,
+ 0x1edc, 0x1edc,
+ 0x1ede, 0x1ede,
+ 0x1ee0, 0x1ee0,
+ 0x1ee2, 0x1ee2,
+ 0x1ee4, 0x1ee4,
+ 0x1ee6, 0x1ee6,
+ 0x1ee8, 0x1ee8,
+ 0x1eea, 0x1eea,
+ 0x1eec, 0x1eec,
+ 0x1eee, 0x1eee,
+ 0x1ef0, 0x1ef0,
+ 0x1ef2, 0x1ef2,
+ 0x1ef4, 0x1ef4,
+ 0x1ef6, 0x1ef6,
+ 0x1ef8, 0x1ef8,
+ 0x1efa, 0x1efa,
+ 0x1efc, 0x1efc,
+ 0x1efe, 0x1efe,
+ 0x1f08, 0x1f0f,
+ 0x1f18, 0x1f1d,
+ 0x1f28, 0x1f2f,
+ 0x1f38, 0x1f3f,
+ 0x1f48, 0x1f4d,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f5f,
+ 0x1f68, 0x1f6f,
+ 0x1fb8, 0x1fbb,
+ 0x1fc8, 0x1fcb,
+ 0x1fd8, 0x1fdb,
+ 0x1fe8, 0x1fec,
+ 0x1ff8, 0x1ffb,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210b, 0x210d,
+ 0x2110, 0x2112,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x2130, 0x2133,
+ 0x213e, 0x213f,
+ 0x2145, 0x2145,
+ 0x2160, 0x216f,
+ 0x2183, 0x2183,
+ 0x24b6, 0x24cf,
+ 0x2c00, 0x2c2e,
+ 0x2c60, 0x2c60,
+ 0x2c62, 0x2c64,
+ 0x2c67, 0x2c67,
+ 0x2c69, 0x2c69,
+ 0x2c6b, 0x2c6b,
+ 0x2c6d, 0x2c70,
+ 0x2c72, 0x2c72,
+ 0x2c75, 0x2c75,
+ 0x2c7e, 0x2c80,
+ 0x2c82, 0x2c82,
+ 0x2c84, 0x2c84,
+ 0x2c86, 0x2c86,
+ 0x2c88, 0x2c88,
+ 0x2c8a, 0x2c8a,
+ 0x2c8c, 0x2c8c,
+ 0x2c8e, 0x2c8e,
+ 0x2c90, 0x2c90,
+ 0x2c92, 0x2c92,
+ 0x2c94, 0x2c94,
+ 0x2c96, 0x2c96,
+ 0x2c98, 0x2c98,
+ 0x2c9a, 0x2c9a,
+ 0x2c9c, 0x2c9c,
+ 0x2c9e, 0x2c9e,
+ 0x2ca0, 0x2ca0,
+ 0x2ca2, 0x2ca2,
+ 0x2ca4, 0x2ca4,
+ 0x2ca6, 0x2ca6,
+ 0x2ca8, 0x2ca8,
+ 0x2caa, 0x2caa,
+ 0x2cac, 0x2cac,
+ 0x2cae, 0x2cae,
+ 0x2cb0, 0x2cb0,
+ 0x2cb2, 0x2cb2,
+ 0x2cb4, 0x2cb4,
+ 0x2cb6, 0x2cb6,
+ 0x2cb8, 0x2cb8,
+ 0x2cba, 0x2cba,
+ 0x2cbc, 0x2cbc,
+ 0x2cbe, 0x2cbe,
+ 0x2cc0, 0x2cc0,
+ 0x2cc2, 0x2cc2,
+ 0x2cc4, 0x2cc4,
+ 0x2cc6, 0x2cc6,
+ 0x2cc8, 0x2cc8,
+ 0x2cca, 0x2cca,
+ 0x2ccc, 0x2ccc,
+ 0x2cce, 0x2cce,
+ 0x2cd0, 0x2cd0,
+ 0x2cd2, 0x2cd2,
+ 0x2cd4, 0x2cd4,
+ 0x2cd6, 0x2cd6,
+ 0x2cd8, 0x2cd8,
+ 0x2cda, 0x2cda,
+ 0x2cdc, 0x2cdc,
+ 0x2cde, 0x2cde,
+ 0x2ce0, 0x2ce0,
+ 0x2ce2, 0x2ce2,
+ 0x2ceb, 0x2ceb,
+ 0x2ced, 0x2ced,
+ 0x2cf2, 0x2cf2,
+ 0xa640, 0xa640,
+ 0xa642, 0xa642,
+ 0xa644, 0xa644,
+ 0xa646, 0xa646,
+ 0xa648, 0xa648,
+ 0xa64a, 0xa64a,
+ 0xa64c, 0xa64c,
+ 0xa64e, 0xa64e,
+ 0xa650, 0xa650,
+ 0xa652, 0xa652,
+ 0xa654, 0xa654,
+ 0xa656, 0xa656,
+ 0xa658, 0xa658,
+ 0xa65a, 0xa65a,
+ 0xa65c, 0xa65c,
+ 0xa65e, 0xa65e,
+ 0xa660, 0xa660,
+ 0xa662, 0xa662,
+ 0xa664, 0xa664,
+ 0xa666, 0xa666,
+ 0xa668, 0xa668,
+ 0xa66a, 0xa66a,
+ 0xa66c, 0xa66c,
+ 0xa680, 0xa680,
+ 0xa682, 0xa682,
+ 0xa684, 0xa684,
+ 0xa686, 0xa686,
+ 0xa688, 0xa688,
+ 0xa68a, 0xa68a,
+ 0xa68c, 0xa68c,
+ 0xa68e, 0xa68e,
+ 0xa690, 0xa690,
+ 0xa692, 0xa692,
+ 0xa694, 0xa694,
+ 0xa696, 0xa696,
+ 0xa698, 0xa698,
+ 0xa69a, 0xa69a,
+ 0xa722, 0xa722,
+ 0xa724, 0xa724,
+ 0xa726, 0xa726,
+ 0xa728, 0xa728,
+ 0xa72a, 0xa72a,
+ 0xa72c, 0xa72c,
+ 0xa72e, 0xa72e,
+ 0xa732, 0xa732,
+ 0xa734, 0xa734,
+ 0xa736, 0xa736,
+ 0xa738, 0xa738,
+ 0xa73a, 0xa73a,
+ 0xa73c, 0xa73c,
+ 0xa73e, 0xa73e,
+ 0xa740, 0xa740,
+ 0xa742, 0xa742,
+ 0xa744, 0xa744,
+ 0xa746, 0xa746,
+ 0xa748, 0xa748,
+ 0xa74a, 0xa74a,
+ 0xa74c, 0xa74c,
+ 0xa74e, 0xa74e,
+ 0xa750, 0xa750,
+ 0xa752, 0xa752,
+ 0xa754, 0xa754,
+ 0xa756, 0xa756,
+ 0xa758, 0xa758,
+ 0xa75a, 0xa75a,
+ 0xa75c, 0xa75c,
+ 0xa75e, 0xa75e,
+ 0xa760, 0xa760,
+ 0xa762, 0xa762,
+ 0xa764, 0xa764,
+ 0xa766, 0xa766,
+ 0xa768, 0xa768,
+ 0xa76a, 0xa76a,
+ 0xa76c, 0xa76c,
+ 0xa76e, 0xa76e,
+ 0xa779, 0xa779,
+ 0xa77b, 0xa77b,
+ 0xa77d, 0xa77e,
+ 0xa780, 0xa780,
+ 0xa782, 0xa782,
+ 0xa784, 0xa784,
+ 0xa786, 0xa786,
+ 0xa78b, 0xa78b,
+ 0xa78d, 0xa78d,
+ 0xa790, 0xa790,
+ 0xa792, 0xa792,
+ 0xa796, 0xa796,
+ 0xa798, 0xa798,
+ 0xa79a, 0xa79a,
+ 0xa79c, 0xa79c,
+ 0xa79e, 0xa79e,
+ 0xa7a0, 0xa7a0,
+ 0xa7a2, 0xa7a2,
+ 0xa7a4, 0xa7a4,
+ 0xa7a6, 0xa7a6,
+ 0xa7a8, 0xa7a8,
+ 0xa7aa, 0xa7ae,
+ 0xa7b0, 0xa7b4,
+ 0xa7b6, 0xa7b6,
+ 0xa7b8, 0xa7b8,
+ 0xa7ba, 0xa7ba,
+ 0xa7bc, 0xa7bc,
+ 0xa7be, 0xa7be,
+ 0xa7c2, 0xa7c2,
+ 0xa7c4, 0xa7c6,
+ 0xff21, 0xff3a,
+ 0x10400, 0x10427,
+ 0x104b0, 0x104d3,
+ 0x10c80, 0x10cb2,
+ 0x118a0, 0x118bf,
+ 0x16e40, 0x16e5f,
+ 0x1d400, 0x1d419,
+ 0x1d434, 0x1d44d,
+ 0x1d468, 0x1d481,
+ 0x1d49c, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b5,
+ 0x1d4d0, 0x1d4e9,
+ 0x1d504, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d538, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d56c, 0x1d585,
+ 0x1d5a0, 0x1d5b9,
+ 0x1d5d4, 0x1d5ed,
+ 0x1d608, 0x1d621,
+ 0x1d63c, 0x1d655,
+ 0x1d670, 0x1d689,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6e2, 0x1d6fa,
+ 0x1d71c, 0x1d734,
+ 0x1d756, 0x1d76e,
+ 0x1d790, 0x1d7a8,
+ 0x1d7ca, 0x1d7ca,
+ 0x1e900, 0x1e921,
+ 0x1f130, 0x1f149,
+ 0x1f150, 0x1f169,
+ 0x1f170, 0x1f189,
+}; /* CR_Upper */
+
+/* 'XDigit': [[:XDigit:]] */
+static const OnigCodePoint CR_XDigit[] = {
+ 3,
+ 0x0030, 0x0039,
+ 0x0041, 0x0046,
+ 0x0061, 0x0066,
+}; /* CR_XDigit */
+
+/* 'Word': [[:Word:]] */
+static const OnigCodePoint CR_Word[] = {
+ 716,
+ 0x0030, 0x0039,
+ 0x0041, 0x005a,
+ 0x005f, 0x005f,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0300, 0x0374,
+ 0x0376, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x0483, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0610, 0x061a,
+ 0x0620, 0x0669,
+ 0x066e, 0x06d3,
+ 0x06d5, 0x06dc,
+ 0x06df, 0x06e8,
+ 0x06ea, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x07fd, 0x07fd,
+ 0x0800, 0x082d,
+ 0x0840, 0x085b,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x0963,
+ 0x0966, 0x096f,
+ 0x0971, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b6f,
+ 0x0b71, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bef,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c80, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d54, 0x0d57,
+ 0x0d5f, 0x0d63,
+ 0x0d66, 0x0d6f,
+ 0x0d7a, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df3,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e4e,
+ 0x0e50, 0x0e59,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f18, 0x0f19,
+ 0x0f20, 0x0f29,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f3e, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f84,
+ 0x0f86, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x1000, 0x1049,
+ 0x1050, 0x109d,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x135f,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1734,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17d3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x180b, 0x180d,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1946, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x1a00, 0x1a1b,
+ 0x1a20, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa7, 0x1aa7,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b59,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1bf3,
+ 0x1c00, 0x1c37,
+ 0x1c40, 0x1c49,
+ 0x1c4d, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x203f, 0x2040,
+ 0x2054, 0x2054,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x20d0, 0x20f0,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x24b6, 0x24e9,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2dff,
+ 0x2e2f, 0x2e2f,
+ 0x3005, 0x3007,
+ 0x3021, 0x302f,
+ 0x3031, 0x3035,
+ 0x3038, 0x303c,
+ 0x3041, 0x3096,
+ 0x3099, 0x309a,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa62b,
+ 0xa640, 0xa672,
+ 0xa674, 0xa67d,
+ 0xa67f, 0xa6f1,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa827,
+ 0xa840, 0xa873,
+ 0xa880, 0xa8c5,
+ 0xa8d0, 0xa8d9,
+ 0xa8e0, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa92d,
+ 0xa930, 0xa953,
+ 0xa960, 0xa97c,
+ 0xa980, 0xa9c0,
+ 0xa9cf, 0xa9d9,
+ 0xa9e0, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaef,
+ 0xaaf2, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabea,
+ 0xabec, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2f,
+ 0xfe33, 0xfe34,
+ 0xfe4d, 0xfe4f,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff10, 0xff19,
+ 0xff21, 0xff3a,
+ 0xff3f, 0xff3f,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10140, 0x10174,
+ 0x101fd, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102e0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae6,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f50,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x11046,
+ 0x11066, 0x1106f,
+ 0x1107f, 0x110ba,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x1113f,
+ 0x11144, 0x11146,
+ 0x11150, 0x11173,
+ 0x11176, 0x11176,
+ 0x11180, 0x111c4,
+ 0x111c9, 0x111cc,
+ 0x111d0, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x1144a,
+ 0x11450, 0x11459,
+ 0x1145e, 0x1145f,
+ 0x11480, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115c0,
+ 0x115d8, 0x115dd,
+ 0x11600, 0x11640,
+ 0x11644, 0x11644,
+ 0x11650, 0x11659,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x11739,
+ 0x11800, 0x1183a,
+ 0x118a0, 0x118e9,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e1,
+ 0x119e3, 0x119e4,
+ 0x11a00, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a50, 0x11a99,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c40,
+ 0x11c50, 0x11c59,
+ 0x11c72, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef6,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af4,
+ 0x16b00, 0x16b36,
+ 0x16b40, 0x16b43,
+ 0x16b50, 0x16b59,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9d, 0x1bc9e,
+ 0x1d165, 0x1d169,
+ 0x1d16d, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e800, 0x1e8c4,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1f130, 0x1f149,
+ 0x1f150, 0x1f169,
+ 0x1f170, 0x1f189,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0xe0100, 0xe01ef,
+}; /* CR_Word */
+
+/* 'Alnum': [[:Alnum:]] */
+static const OnigCodePoint CR_Alnum[] = {
+ 715,
+ 0x0030, 0x0039,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0345, 0x0345,
+ 0x0370, 0x0374,
+ 0x0376, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x05b0, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0610, 0x061a,
+ 0x0620, 0x0657,
+ 0x0659, 0x0669,
+ 0x066e, 0x06d3,
+ 0x06d5, 0x06dc,
+ 0x06e1, 0x06e8,
+ 0x06ed, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x073f,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07ea,
+ 0x07f4, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x0800, 0x0817,
+ 0x081a, 0x082c,
+ 0x0840, 0x0858,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d4, 0x08df,
+ 0x08e3, 0x08e9,
+ 0x08f0, 0x093b,
+ 0x093d, 0x094c,
+ 0x094e, 0x0950,
+ 0x0955, 0x0963,
+ 0x0966, 0x096f,
+ 0x0971, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cc,
+ 0x09ce, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4c,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acc,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af9, 0x0afc,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4c,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b6f,
+ 0x0b71, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcc,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bef,
+ 0x0c00, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4c,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c80, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccc,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4c,
+ 0x0d4e, 0x0d4e,
+ 0x0d54, 0x0d57,
+ 0x0d5f, 0x0d63,
+ 0x0d66, 0x0d6f,
+ 0x0d7a, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df3,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e46,
+ 0x0e4d, 0x0e4d,
+ 0x0e50, 0x0e59,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ecd, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f20, 0x0f29,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f81,
+ 0x0f88, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x1000, 0x1036,
+ 0x1038, 0x1038,
+ 0x103b, 0x1049,
+ 0x1050, 0x109d,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1713,
+ 0x1720, 0x1733,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17b3,
+ 0x17b6, 0x17c8,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dc,
+ 0x17e0, 0x17e9,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x1938,
+ 0x1946, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x1a00, 0x1a1b,
+ 0x1a20, 0x1a5e,
+ 0x1a61, 0x1a74,
+ 0x1a80, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa7, 0x1aa7,
+ 0x1b00, 0x1b33,
+ 0x1b35, 0x1b43,
+ 0x1b45, 0x1b4b,
+ 0x1b50, 0x1b59,
+ 0x1b80, 0x1ba9,
+ 0x1bac, 0x1be5,
+ 0x1be7, 0x1bf1,
+ 0x1c00, 0x1c36,
+ 0x1c40, 0x1c49,
+ 0x1c4d, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf6,
+ 0x1cfa, 0x1cfa,
+ 0x1d00, 0x1dbf,
+ 0x1de7, 0x1df4,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x24b6, 0x24e9,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2dff,
+ 0x2e2f, 0x2e2f,
+ 0x3005, 0x3007,
+ 0x3021, 0x3029,
+ 0x3031, 0x3035,
+ 0x3038, 0x303c,
+ 0x3041, 0x3096,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa62b,
+ 0xa640, 0xa66e,
+ 0xa674, 0xa67b,
+ 0xa67f, 0xa6ef,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa805,
+ 0xa807, 0xa827,
+ 0xa840, 0xa873,
+ 0xa880, 0xa8c3,
+ 0xa8c5, 0xa8c5,
+ 0xa8d0, 0xa8d9,
+ 0xa8f2, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa92a,
+ 0xa930, 0xa952,
+ 0xa960, 0xa97c,
+ 0xa980, 0xa9b2,
+ 0xa9b4, 0xa9bf,
+ 0xa9cf, 0xa9d9,
+ 0xa9e0, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaabe,
+ 0xaac0, 0xaac0,
+ 0xaac2, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaef,
+ 0xaaf2, 0xaaf5,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabea,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff10, 0xff19,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10140, 0x10174,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae4,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f45,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x11045,
+ 0x11066, 0x1106f,
+ 0x11082, 0x110b8,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11132,
+ 0x11136, 0x1113f,
+ 0x11144, 0x11146,
+ 0x11150, 0x11172,
+ 0x11176, 0x11176,
+ 0x11180, 0x111bf,
+ 0x111c1, 0x111c4,
+ 0x111d0, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x11234,
+ 0x11237, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112e8,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133d, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134c,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11400, 0x11441,
+ 0x11443, 0x11445,
+ 0x11447, 0x1144a,
+ 0x11450, 0x11459,
+ 0x1145f, 0x1145f,
+ 0x11480, 0x114c1,
+ 0x114c4, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115be,
+ 0x115d8, 0x115dd,
+ 0x11600, 0x1163e,
+ 0x11640, 0x11640,
+ 0x11644, 0x11644,
+ 0x11650, 0x11659,
+ 0x11680, 0x116b5,
+ 0x116b8, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172a,
+ 0x11730, 0x11739,
+ 0x11800, 0x11838,
+ 0x118a0, 0x118e9,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119df,
+ 0x119e1, 0x119e1,
+ 0x119e3, 0x119e4,
+ 0x11a00, 0x11a32,
+ 0x11a35, 0x11a3e,
+ 0x11a50, 0x11a97,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c3e,
+ 0x11c40, 0x11c40,
+ 0x11c50, 0x11c59,
+ 0x11c72, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d41,
+ 0x11d43, 0x11d43,
+ 0x11d46, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d96,
+ 0x11d98, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef6,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16ad0, 0x16aed,
+ 0x16b00, 0x16b2f,
+ 0x16b40, 0x16b43,
+ 0x16b50, 0x16b59,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9e, 0x1bc9e,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e137, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2eb,
+ 0x1e2f0, 0x1e2f9,
+ 0x1e800, 0x1e8c4,
+ 0x1e900, 0x1e943,
+ 0x1e947, 0x1e947,
+ 0x1e94b, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1f130, 0x1f149,
+ 0x1f150, 0x1f169,
+ 0x1f170, 0x1f189,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_Alnum */
+
+/* 'ASCII': [[:ASCII:]] */
+static const OnigCodePoint CR_ASCII[] = {
+ 1,
+ 0x0000, 0x007f,
+}; /* CR_ASCII */
+
+/* 'Punct' */
+static const OnigCodePoint CR_Punct[] = {
+ 182,
+ 0x0021, 0x0023,
+ 0x0025, 0x002a,
+ 0x002c, 0x002f,
+ 0x003a, 0x003b,
+ 0x003f, 0x0040,
+ 0x005b, 0x005d,
+ 0x005f, 0x005f,
+ 0x007b, 0x007b,
+ 0x007d, 0x007d,
+ 0x00a1, 0x00a1,
+ 0x00a7, 0x00a7,
+ 0x00ab, 0x00ab,
+ 0x00b6, 0x00b7,
+ 0x00bb, 0x00bb,
+ 0x00bf, 0x00bf,
+ 0x037e, 0x037e,
+ 0x0387, 0x0387,
+ 0x055a, 0x055f,
+ 0x0589, 0x058a,
+ 0x05be, 0x05be,
+ 0x05c0, 0x05c0,
+ 0x05c3, 0x05c3,
+ 0x05c6, 0x05c6,
+ 0x05f3, 0x05f4,
+ 0x0609, 0x060a,
+ 0x060c, 0x060d,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x066a, 0x066d,
+ 0x06d4, 0x06d4,
+ 0x0700, 0x070d,
+ 0x07f7, 0x07f9,
+ 0x0830, 0x083e,
+ 0x085e, 0x085e,
+ 0x0964, 0x0965,
+ 0x0970, 0x0970,
+ 0x09fd, 0x09fd,
+ 0x0a76, 0x0a76,
+ 0x0af0, 0x0af0,
+ 0x0c77, 0x0c77,
+ 0x0c84, 0x0c84,
+ 0x0df4, 0x0df4,
+ 0x0e4f, 0x0e4f,
+ 0x0e5a, 0x0e5b,
+ 0x0f04, 0x0f12,
+ 0x0f14, 0x0f14,
+ 0x0f3a, 0x0f3d,
+ 0x0f85, 0x0f85,
+ 0x0fd0, 0x0fd4,
+ 0x0fd9, 0x0fda,
+ 0x104a, 0x104f,
+ 0x10fb, 0x10fb,
+ 0x1360, 0x1368,
+ 0x1400, 0x1400,
+ 0x166e, 0x166e,
+ 0x169b, 0x169c,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x17d4, 0x17d6,
+ 0x17d8, 0x17da,
+ 0x1800, 0x180a,
+ 0x1944, 0x1945,
+ 0x1a1e, 0x1a1f,
+ 0x1aa0, 0x1aa6,
+ 0x1aa8, 0x1aad,
+ 0x1b5a, 0x1b60,
+ 0x1bfc, 0x1bff,
+ 0x1c3b, 0x1c3f,
+ 0x1c7e, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd3, 0x1cd3,
+ 0x2010, 0x2027,
+ 0x2030, 0x2043,
+ 0x2045, 0x2051,
+ 0x2053, 0x205e,
+ 0x207d, 0x207e,
+ 0x208d, 0x208e,
+ 0x2308, 0x230b,
+ 0x2329, 0x232a,
+ 0x2768, 0x2775,
+ 0x27c5, 0x27c6,
+ 0x27e6, 0x27ef,
+ 0x2983, 0x2998,
+ 0x29d8, 0x29db,
+ 0x29fc, 0x29fd,
+ 0x2cf9, 0x2cfc,
+ 0x2cfe, 0x2cff,
+ 0x2d70, 0x2d70,
+ 0x2e00, 0x2e2e,
+ 0x2e30, 0x2e4f,
+ 0x3001, 0x3003,
+ 0x3008, 0x3011,
+ 0x3014, 0x301f,
+ 0x3030, 0x3030,
+ 0x303d, 0x303d,
+ 0x30a0, 0x30a0,
+ 0x30fb, 0x30fb,
+ 0xa4fe, 0xa4ff,
+ 0xa60d, 0xa60f,
+ 0xa673, 0xa673,
+ 0xa67e, 0xa67e,
+ 0xa6f2, 0xa6f7,
+ 0xa874, 0xa877,
+ 0xa8ce, 0xa8cf,
+ 0xa8f8, 0xa8fa,
+ 0xa8fc, 0xa8fc,
+ 0xa92e, 0xa92f,
+ 0xa95f, 0xa95f,
+ 0xa9c1, 0xa9cd,
+ 0xa9de, 0xa9df,
+ 0xaa5c, 0xaa5f,
+ 0xaade, 0xaadf,
+ 0xaaf0, 0xaaf1,
+ 0xabeb, 0xabeb,
+ 0xfd3e, 0xfd3f,
+ 0xfe10, 0xfe19,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe61,
+ 0xfe63, 0xfe63,
+ 0xfe68, 0xfe68,
+ 0xfe6a, 0xfe6b,
+ 0xff01, 0xff03,
+ 0xff05, 0xff0a,
+ 0xff0c, 0xff0f,
+ 0xff1a, 0xff1b,
+ 0xff1f, 0xff20,
+ 0xff3b, 0xff3d,
+ 0xff3f, 0xff3f,
+ 0xff5b, 0xff5b,
+ 0xff5d, 0xff5d,
+ 0xff5f, 0xff65,
+ 0x10100, 0x10102,
+ 0x1039f, 0x1039f,
+ 0x103d0, 0x103d0,
+ 0x1056f, 0x1056f,
+ 0x10857, 0x10857,
+ 0x1091f, 0x1091f,
+ 0x1093f, 0x1093f,
+ 0x10a50, 0x10a58,
+ 0x10a7f, 0x10a7f,
+ 0x10af0, 0x10af6,
+ 0x10b39, 0x10b3f,
+ 0x10b99, 0x10b9c,
+ 0x10f55, 0x10f59,
+ 0x11047, 0x1104d,
+ 0x110bb, 0x110bc,
+ 0x110be, 0x110c1,
+ 0x11140, 0x11143,
+ 0x11174, 0x11175,
+ 0x111c5, 0x111c8,
+ 0x111cd, 0x111cd,
+ 0x111db, 0x111db,
+ 0x111dd, 0x111df,
+ 0x11238, 0x1123d,
+ 0x112a9, 0x112a9,
+ 0x1144b, 0x1144f,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145d,
+ 0x114c6, 0x114c6,
+ 0x115c1, 0x115d7,
+ 0x11641, 0x11643,
+ 0x11660, 0x1166c,
+ 0x1173c, 0x1173e,
+ 0x1183b, 0x1183b,
+ 0x119e2, 0x119e2,
+ 0x11a3f, 0x11a46,
+ 0x11a9a, 0x11a9c,
+ 0x11a9e, 0x11aa2,
+ 0x11c41, 0x11c45,
+ 0x11c70, 0x11c71,
+ 0x11ef7, 0x11ef8,
+ 0x11fff, 0x11fff,
+ 0x12470, 0x12474,
+ 0x16a6e, 0x16a6f,
+ 0x16af5, 0x16af5,
+ 0x16b37, 0x16b3b,
+ 0x16b44, 0x16b44,
+ 0x16e97, 0x16e9a,
+ 0x16fe2, 0x16fe2,
+ 0x1bc9f, 0x1bc9f,
+ 0x1da87, 0x1da8b,
+ 0x1e95e, 0x1e95f,
+}; /* CR_Punct */
+
+#ifdef USE_UNICODE_PROPERTIES
+/* 'Any': - */
+static const OnigCodePoint CR_Any[] = {
+ 1,
+ 0x0000, 0x10ffff,
+}; /* CR_Any */
+
+/* 'Assigned': - */
+static const OnigCodePoint CR_Assigned[] = {
+ 666,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a76,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd0, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e4f,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x4db5,
+ 0x4dc0, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab67,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xfffd,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a48,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f00, 0x10f27,
+ 0x10f30, 0x10f59,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110cd, 0x110cd,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11146,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145f,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x11800, 0x1183b,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e4,
+ 0x11a00, 0x11a47,
+ 0x11a50, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef8,
+ 0x11fc0, 0x11ff1,
+ 0x11fff, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x13430, 0x13438,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e9a,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14f,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e2ff, 0x1e2ff,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ec71, 0x1ecb4,
+ 0x1ed01, 0x1ed3d,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xf0000, 0xffffd,
+ 0x100000, 0x10fffd,
+}; /* CR_Assigned */
+
+/* 'C': Major Category */
+static const OnigCodePoint CR_C[] = {
+ 668,
+ 0x0000, 0x001f,
+ 0x007f, 0x009f,
+ 0x00ad, 0x00ad,
+ 0x0378, 0x0379,
+ 0x0380, 0x0383,
+ 0x038b, 0x038b,
+ 0x038d, 0x038d,
+ 0x03a2, 0x03a2,
+ 0x0530, 0x0530,
+ 0x0557, 0x0558,
+ 0x058b, 0x058c,
+ 0x0590, 0x0590,
+ 0x05c8, 0x05cf,
+ 0x05eb, 0x05ee,
+ 0x05f5, 0x0605,
+ 0x061c, 0x061d,
+ 0x06dd, 0x06dd,
+ 0x070e, 0x070f,
+ 0x074b, 0x074c,
+ 0x07b2, 0x07bf,
+ 0x07fb, 0x07fc,
+ 0x082e, 0x082f,
+ 0x083f, 0x083f,
+ 0x085c, 0x085d,
+ 0x085f, 0x085f,
+ 0x086b, 0x089f,
+ 0x08b5, 0x08b5,
+ 0x08be, 0x08d2,
+ 0x08e2, 0x08e2,
+ 0x0984, 0x0984,
+ 0x098d, 0x098e,
+ 0x0991, 0x0992,
+ 0x09a9, 0x09a9,
+ 0x09b1, 0x09b1,
+ 0x09b3, 0x09b5,
+ 0x09ba, 0x09bb,
+ 0x09c5, 0x09c6,
+ 0x09c9, 0x09ca,
+ 0x09cf, 0x09d6,
+ 0x09d8, 0x09db,
+ 0x09de, 0x09de,
+ 0x09e4, 0x09e5,
+ 0x09ff, 0x0a00,
+ 0x0a04, 0x0a04,
+ 0x0a0b, 0x0a0e,
+ 0x0a11, 0x0a12,
+ 0x0a29, 0x0a29,
+ 0x0a31, 0x0a31,
+ 0x0a34, 0x0a34,
+ 0x0a37, 0x0a37,
+ 0x0a3a, 0x0a3b,
+ 0x0a3d, 0x0a3d,
+ 0x0a43, 0x0a46,
+ 0x0a49, 0x0a4a,
+ 0x0a4e, 0x0a50,
+ 0x0a52, 0x0a58,
+ 0x0a5d, 0x0a5d,
+ 0x0a5f, 0x0a65,
+ 0x0a77, 0x0a80,
+ 0x0a84, 0x0a84,
+ 0x0a8e, 0x0a8e,
+ 0x0a92, 0x0a92,
+ 0x0aa9, 0x0aa9,
+ 0x0ab1, 0x0ab1,
+ 0x0ab4, 0x0ab4,
+ 0x0aba, 0x0abb,
+ 0x0ac6, 0x0ac6,
+ 0x0aca, 0x0aca,
+ 0x0ace, 0x0acf,
+ 0x0ad1, 0x0adf,
+ 0x0ae4, 0x0ae5,
+ 0x0af2, 0x0af8,
+ 0x0b00, 0x0b00,
+ 0x0b04, 0x0b04,
+ 0x0b0d, 0x0b0e,
+ 0x0b11, 0x0b12,
+ 0x0b29, 0x0b29,
+ 0x0b31, 0x0b31,
+ 0x0b34, 0x0b34,
+ 0x0b3a, 0x0b3b,
+ 0x0b45, 0x0b46,
+ 0x0b49, 0x0b4a,
+ 0x0b4e, 0x0b55,
+ 0x0b58, 0x0b5b,
+ 0x0b5e, 0x0b5e,
+ 0x0b64, 0x0b65,
+ 0x0b78, 0x0b81,
+ 0x0b84, 0x0b84,
+ 0x0b8b, 0x0b8d,
+ 0x0b91, 0x0b91,
+ 0x0b96, 0x0b98,
+ 0x0b9b, 0x0b9b,
+ 0x0b9d, 0x0b9d,
+ 0x0ba0, 0x0ba2,
+ 0x0ba5, 0x0ba7,
+ 0x0bab, 0x0bad,
+ 0x0bba, 0x0bbd,
+ 0x0bc3, 0x0bc5,
+ 0x0bc9, 0x0bc9,
+ 0x0bce, 0x0bcf,
+ 0x0bd1, 0x0bd6,
+ 0x0bd8, 0x0be5,
+ 0x0bfb, 0x0bff,
+ 0x0c0d, 0x0c0d,
+ 0x0c11, 0x0c11,
+ 0x0c29, 0x0c29,
+ 0x0c3a, 0x0c3c,
+ 0x0c45, 0x0c45,
+ 0x0c49, 0x0c49,
+ 0x0c4e, 0x0c54,
+ 0x0c57, 0x0c57,
+ 0x0c5b, 0x0c5f,
+ 0x0c64, 0x0c65,
+ 0x0c70, 0x0c76,
+ 0x0c8d, 0x0c8d,
+ 0x0c91, 0x0c91,
+ 0x0ca9, 0x0ca9,
+ 0x0cb4, 0x0cb4,
+ 0x0cba, 0x0cbb,
+ 0x0cc5, 0x0cc5,
+ 0x0cc9, 0x0cc9,
+ 0x0cce, 0x0cd4,
+ 0x0cd7, 0x0cdd,
+ 0x0cdf, 0x0cdf,
+ 0x0ce4, 0x0ce5,
+ 0x0cf0, 0x0cf0,
+ 0x0cf3, 0x0cff,
+ 0x0d04, 0x0d04,
+ 0x0d0d, 0x0d0d,
+ 0x0d11, 0x0d11,
+ 0x0d45, 0x0d45,
+ 0x0d49, 0x0d49,
+ 0x0d50, 0x0d53,
+ 0x0d64, 0x0d65,
+ 0x0d80, 0x0d81,
+ 0x0d84, 0x0d84,
+ 0x0d97, 0x0d99,
+ 0x0db2, 0x0db2,
+ 0x0dbc, 0x0dbc,
+ 0x0dbe, 0x0dbf,
+ 0x0dc7, 0x0dc9,
+ 0x0dcb, 0x0dce,
+ 0x0dd5, 0x0dd5,
+ 0x0dd7, 0x0dd7,
+ 0x0de0, 0x0de5,
+ 0x0df0, 0x0df1,
+ 0x0df5, 0x0e00,
+ 0x0e3b, 0x0e3e,
+ 0x0e5c, 0x0e80,
+ 0x0e83, 0x0e83,
+ 0x0e85, 0x0e85,
+ 0x0e8b, 0x0e8b,
+ 0x0ea4, 0x0ea4,
+ 0x0ea6, 0x0ea6,
+ 0x0ebe, 0x0ebf,
+ 0x0ec5, 0x0ec5,
+ 0x0ec7, 0x0ec7,
+ 0x0ece, 0x0ecf,
+ 0x0eda, 0x0edb,
+ 0x0ee0, 0x0eff,
+ 0x0f48, 0x0f48,
+ 0x0f6d, 0x0f70,
+ 0x0f98, 0x0f98,
+ 0x0fbd, 0x0fbd,
+ 0x0fcd, 0x0fcd,
+ 0x0fdb, 0x0fff,
+ 0x10c6, 0x10c6,
+ 0x10c8, 0x10cc,
+ 0x10ce, 0x10cf,
+ 0x1249, 0x1249,
+ 0x124e, 0x124f,
+ 0x1257, 0x1257,
+ 0x1259, 0x1259,
+ 0x125e, 0x125f,
+ 0x1289, 0x1289,
+ 0x128e, 0x128f,
+ 0x12b1, 0x12b1,
+ 0x12b6, 0x12b7,
+ 0x12bf, 0x12bf,
+ 0x12c1, 0x12c1,
+ 0x12c6, 0x12c7,
+ 0x12d7, 0x12d7,
+ 0x1311, 0x1311,
+ 0x1316, 0x1317,
+ 0x135b, 0x135c,
+ 0x137d, 0x137f,
+ 0x139a, 0x139f,
+ 0x13f6, 0x13f7,
+ 0x13fe, 0x13ff,
+ 0x169d, 0x169f,
+ 0x16f9, 0x16ff,
+ 0x170d, 0x170d,
+ 0x1715, 0x171f,
+ 0x1737, 0x173f,
+ 0x1754, 0x175f,
+ 0x176d, 0x176d,
+ 0x1771, 0x1771,
+ 0x1774, 0x177f,
+ 0x17de, 0x17df,
+ 0x17ea, 0x17ef,
+ 0x17fa, 0x17ff,
+ 0x180e, 0x180f,
+ 0x181a, 0x181f,
+ 0x1879, 0x187f,
+ 0x18ab, 0x18af,
+ 0x18f6, 0x18ff,
+ 0x191f, 0x191f,
+ 0x192c, 0x192f,
+ 0x193c, 0x193f,
+ 0x1941, 0x1943,
+ 0x196e, 0x196f,
+ 0x1975, 0x197f,
+ 0x19ac, 0x19af,
+ 0x19ca, 0x19cf,
+ 0x19db, 0x19dd,
+ 0x1a1c, 0x1a1d,
+ 0x1a5f, 0x1a5f,
+ 0x1a7d, 0x1a7e,
+ 0x1a8a, 0x1a8f,
+ 0x1a9a, 0x1a9f,
+ 0x1aae, 0x1aaf,
+ 0x1abf, 0x1aff,
+ 0x1b4c, 0x1b4f,
+ 0x1b7d, 0x1b7f,
+ 0x1bf4, 0x1bfb,
+ 0x1c38, 0x1c3a,
+ 0x1c4a, 0x1c4c,
+ 0x1c89, 0x1c8f,
+ 0x1cbb, 0x1cbc,
+ 0x1cc8, 0x1ccf,
+ 0x1cfb, 0x1cff,
+ 0x1dfa, 0x1dfa,
+ 0x1f16, 0x1f17,
+ 0x1f1e, 0x1f1f,
+ 0x1f46, 0x1f47,
+ 0x1f4e, 0x1f4f,
+ 0x1f58, 0x1f58,
+ 0x1f5a, 0x1f5a,
+ 0x1f5c, 0x1f5c,
+ 0x1f5e, 0x1f5e,
+ 0x1f7e, 0x1f7f,
+ 0x1fb5, 0x1fb5,
+ 0x1fc5, 0x1fc5,
+ 0x1fd4, 0x1fd5,
+ 0x1fdc, 0x1fdc,
+ 0x1ff0, 0x1ff1,
+ 0x1ff5, 0x1ff5,
+ 0x1fff, 0x1fff,
+ 0x200b, 0x200f,
+ 0x202a, 0x202e,
+ 0x2060, 0x206f,
+ 0x2072, 0x2073,
+ 0x208f, 0x208f,
+ 0x209d, 0x209f,
+ 0x20c0, 0x20cf,
+ 0x20f1, 0x20ff,
+ 0x218c, 0x218f,
+ 0x2427, 0x243f,
+ 0x244b, 0x245f,
+ 0x2b74, 0x2b75,
+ 0x2b96, 0x2b97,
+ 0x2c2f, 0x2c2f,
+ 0x2c5f, 0x2c5f,
+ 0x2cf4, 0x2cf8,
+ 0x2d26, 0x2d26,
+ 0x2d28, 0x2d2c,
+ 0x2d2e, 0x2d2f,
+ 0x2d68, 0x2d6e,
+ 0x2d71, 0x2d7e,
+ 0x2d97, 0x2d9f,
+ 0x2da7, 0x2da7,
+ 0x2daf, 0x2daf,
+ 0x2db7, 0x2db7,
+ 0x2dbf, 0x2dbf,
+ 0x2dc7, 0x2dc7,
+ 0x2dcf, 0x2dcf,
+ 0x2dd7, 0x2dd7,
+ 0x2ddf, 0x2ddf,
+ 0x2e50, 0x2e7f,
+ 0x2e9a, 0x2e9a,
+ 0x2ef4, 0x2eff,
+ 0x2fd6, 0x2fef,
+ 0x2ffc, 0x2fff,
+ 0x3040, 0x3040,
+ 0x3097, 0x3098,
+ 0x3100, 0x3104,
+ 0x3130, 0x3130,
+ 0x318f, 0x318f,
+ 0x31bb, 0x31bf,
+ 0x31e4, 0x31ef,
+ 0x321f, 0x321f,
+ 0x4db6, 0x4dbf,
+ 0x9ff0, 0x9fff,
+ 0xa48d, 0xa48f,
+ 0xa4c7, 0xa4cf,
+ 0xa62c, 0xa63f,
+ 0xa6f8, 0xa6ff,
+ 0xa7c0, 0xa7c1,
+ 0xa7c7, 0xa7f6,
+ 0xa82c, 0xa82f,
+ 0xa83a, 0xa83f,
+ 0xa878, 0xa87f,
+ 0xa8c6, 0xa8cd,
+ 0xa8da, 0xa8df,
+ 0xa954, 0xa95e,
+ 0xa97d, 0xa97f,
+ 0xa9ce, 0xa9ce,
+ 0xa9da, 0xa9dd,
+ 0xa9ff, 0xa9ff,
+ 0xaa37, 0xaa3f,
+ 0xaa4e, 0xaa4f,
+ 0xaa5a, 0xaa5b,
+ 0xaac3, 0xaada,
+ 0xaaf7, 0xab00,
+ 0xab07, 0xab08,
+ 0xab0f, 0xab10,
+ 0xab17, 0xab1f,
+ 0xab27, 0xab27,
+ 0xab2f, 0xab2f,
+ 0xab68, 0xab6f,
+ 0xabee, 0xabef,
+ 0xabfa, 0xabff,
+ 0xd7a4, 0xd7af,
+ 0xd7c7, 0xd7ca,
+ 0xd7fc, 0xf8ff,
+ 0xfa6e, 0xfa6f,
+ 0xfada, 0xfaff,
+ 0xfb07, 0xfb12,
+ 0xfb18, 0xfb1c,
+ 0xfb37, 0xfb37,
+ 0xfb3d, 0xfb3d,
+ 0xfb3f, 0xfb3f,
+ 0xfb42, 0xfb42,
+ 0xfb45, 0xfb45,
+ 0xfbc2, 0xfbd2,
+ 0xfd40, 0xfd4f,
+ 0xfd90, 0xfd91,
+ 0xfdc8, 0xfdef,
+ 0xfdfe, 0xfdff,
+ 0xfe1a, 0xfe1f,
+ 0xfe53, 0xfe53,
+ 0xfe67, 0xfe67,
+ 0xfe6c, 0xfe6f,
+ 0xfe75, 0xfe75,
+ 0xfefd, 0xff00,
+ 0xffbf, 0xffc1,
+ 0xffc8, 0xffc9,
+ 0xffd0, 0xffd1,
+ 0xffd8, 0xffd9,
+ 0xffdd, 0xffdf,
+ 0xffe7, 0xffe7,
+ 0xffef, 0xfffb,
+ 0xfffe, 0xffff,
+ 0x1000c, 0x1000c,
+ 0x10027, 0x10027,
+ 0x1003b, 0x1003b,
+ 0x1003e, 0x1003e,
+ 0x1004e, 0x1004f,
+ 0x1005e, 0x1007f,
+ 0x100fb, 0x100ff,
+ 0x10103, 0x10106,
+ 0x10134, 0x10136,
+ 0x1018f, 0x1018f,
+ 0x1019c, 0x1019f,
+ 0x101a1, 0x101cf,
+ 0x101fe, 0x1027f,
+ 0x1029d, 0x1029f,
+ 0x102d1, 0x102df,
+ 0x102fc, 0x102ff,
+ 0x10324, 0x1032c,
+ 0x1034b, 0x1034f,
+ 0x1037b, 0x1037f,
+ 0x1039e, 0x1039e,
+ 0x103c4, 0x103c7,
+ 0x103d6, 0x103ff,
+ 0x1049e, 0x1049f,
+ 0x104aa, 0x104af,
+ 0x104d4, 0x104d7,
+ 0x104fc, 0x104ff,
+ 0x10528, 0x1052f,
+ 0x10564, 0x1056e,
+ 0x10570, 0x105ff,
+ 0x10737, 0x1073f,
+ 0x10756, 0x1075f,
+ 0x10768, 0x107ff,
+ 0x10806, 0x10807,
+ 0x10809, 0x10809,
+ 0x10836, 0x10836,
+ 0x10839, 0x1083b,
+ 0x1083d, 0x1083e,
+ 0x10856, 0x10856,
+ 0x1089f, 0x108a6,
+ 0x108b0, 0x108df,
+ 0x108f3, 0x108f3,
+ 0x108f6, 0x108fa,
+ 0x1091c, 0x1091e,
+ 0x1093a, 0x1093e,
+ 0x10940, 0x1097f,
+ 0x109b8, 0x109bb,
+ 0x109d0, 0x109d1,
+ 0x10a04, 0x10a04,
+ 0x10a07, 0x10a0b,
+ 0x10a14, 0x10a14,
+ 0x10a18, 0x10a18,
+ 0x10a36, 0x10a37,
+ 0x10a3b, 0x10a3e,
+ 0x10a49, 0x10a4f,
+ 0x10a59, 0x10a5f,
+ 0x10aa0, 0x10abf,
+ 0x10ae7, 0x10aea,
+ 0x10af7, 0x10aff,
+ 0x10b36, 0x10b38,
+ 0x10b56, 0x10b57,
+ 0x10b73, 0x10b77,
+ 0x10b92, 0x10b98,
+ 0x10b9d, 0x10ba8,
+ 0x10bb0, 0x10bff,
+ 0x10c49, 0x10c7f,
+ 0x10cb3, 0x10cbf,
+ 0x10cf3, 0x10cf9,
+ 0x10d28, 0x10d2f,
+ 0x10d3a, 0x10e5f,
+ 0x10e7f, 0x10eff,
+ 0x10f28, 0x10f2f,
+ 0x10f5a, 0x10fdf,
+ 0x10ff7, 0x10fff,
+ 0x1104e, 0x11051,
+ 0x11070, 0x1107e,
+ 0x110bd, 0x110bd,
+ 0x110c2, 0x110cf,
+ 0x110e9, 0x110ef,
+ 0x110fa, 0x110ff,
+ 0x11135, 0x11135,
+ 0x11147, 0x1114f,
+ 0x11177, 0x1117f,
+ 0x111ce, 0x111cf,
+ 0x111e0, 0x111e0,
+ 0x111f5, 0x111ff,
+ 0x11212, 0x11212,
+ 0x1123f, 0x1127f,
+ 0x11287, 0x11287,
+ 0x11289, 0x11289,
+ 0x1128e, 0x1128e,
+ 0x1129e, 0x1129e,
+ 0x112aa, 0x112af,
+ 0x112eb, 0x112ef,
+ 0x112fa, 0x112ff,
+ 0x11304, 0x11304,
+ 0x1130d, 0x1130e,
+ 0x11311, 0x11312,
+ 0x11329, 0x11329,
+ 0x11331, 0x11331,
+ 0x11334, 0x11334,
+ 0x1133a, 0x1133a,
+ 0x11345, 0x11346,
+ 0x11349, 0x1134a,
+ 0x1134e, 0x1134f,
+ 0x11351, 0x11356,
+ 0x11358, 0x1135c,
+ 0x11364, 0x11365,
+ 0x1136d, 0x1136f,
+ 0x11375, 0x113ff,
+ 0x1145a, 0x1145a,
+ 0x1145c, 0x1145c,
+ 0x11460, 0x1147f,
+ 0x114c8, 0x114cf,
+ 0x114da, 0x1157f,
+ 0x115b6, 0x115b7,
+ 0x115de, 0x115ff,
+ 0x11645, 0x1164f,
+ 0x1165a, 0x1165f,
+ 0x1166d, 0x1167f,
+ 0x116b9, 0x116bf,
+ 0x116ca, 0x116ff,
+ 0x1171b, 0x1171c,
+ 0x1172c, 0x1172f,
+ 0x11740, 0x117ff,
+ 0x1183c, 0x1189f,
+ 0x118f3, 0x118fe,
+ 0x11900, 0x1199f,
+ 0x119a8, 0x119a9,
+ 0x119d8, 0x119d9,
+ 0x119e5, 0x119ff,
+ 0x11a48, 0x11a4f,
+ 0x11aa3, 0x11abf,
+ 0x11af9, 0x11bff,
+ 0x11c09, 0x11c09,
+ 0x11c37, 0x11c37,
+ 0x11c46, 0x11c4f,
+ 0x11c6d, 0x11c6f,
+ 0x11c90, 0x11c91,
+ 0x11ca8, 0x11ca8,
+ 0x11cb7, 0x11cff,
+ 0x11d07, 0x11d07,
+ 0x11d0a, 0x11d0a,
+ 0x11d37, 0x11d39,
+ 0x11d3b, 0x11d3b,
+ 0x11d3e, 0x11d3e,
+ 0x11d48, 0x11d4f,
+ 0x11d5a, 0x11d5f,
+ 0x11d66, 0x11d66,
+ 0x11d69, 0x11d69,
+ 0x11d8f, 0x11d8f,
+ 0x11d92, 0x11d92,
+ 0x11d99, 0x11d9f,
+ 0x11daa, 0x11edf,
+ 0x11ef9, 0x11fbf,
+ 0x11ff2, 0x11ffe,
+ 0x1239a, 0x123ff,
+ 0x1246f, 0x1246f,
+ 0x12475, 0x1247f,
+ 0x12544, 0x12fff,
+ 0x1342f, 0x143ff,
+ 0x14647, 0x167ff,
+ 0x16a39, 0x16a3f,
+ 0x16a5f, 0x16a5f,
+ 0x16a6a, 0x16a6d,
+ 0x16a70, 0x16acf,
+ 0x16aee, 0x16aef,
+ 0x16af6, 0x16aff,
+ 0x16b46, 0x16b4f,
+ 0x16b5a, 0x16b5a,
+ 0x16b62, 0x16b62,
+ 0x16b78, 0x16b7c,
+ 0x16b90, 0x16e3f,
+ 0x16e9b, 0x16eff,
+ 0x16f4b, 0x16f4e,
+ 0x16f88, 0x16f8e,
+ 0x16fa0, 0x16fdf,
+ 0x16fe4, 0x16fff,
+ 0x187f8, 0x187ff,
+ 0x18af3, 0x1afff,
+ 0x1b11f, 0x1b14f,
+ 0x1b153, 0x1b163,
+ 0x1b168, 0x1b16f,
+ 0x1b2fc, 0x1bbff,
+ 0x1bc6b, 0x1bc6f,
+ 0x1bc7d, 0x1bc7f,
+ 0x1bc89, 0x1bc8f,
+ 0x1bc9a, 0x1bc9b,
+ 0x1bca0, 0x1cfff,
+ 0x1d0f6, 0x1d0ff,
+ 0x1d127, 0x1d128,
+ 0x1d173, 0x1d17a,
+ 0x1d1e9, 0x1d1ff,
+ 0x1d246, 0x1d2df,
+ 0x1d2f4, 0x1d2ff,
+ 0x1d357, 0x1d35f,
+ 0x1d379, 0x1d3ff,
+ 0x1d455, 0x1d455,
+ 0x1d49d, 0x1d49d,
+ 0x1d4a0, 0x1d4a1,
+ 0x1d4a3, 0x1d4a4,
+ 0x1d4a7, 0x1d4a8,
+ 0x1d4ad, 0x1d4ad,
+ 0x1d4ba, 0x1d4ba,
+ 0x1d4bc, 0x1d4bc,
+ 0x1d4c4, 0x1d4c4,
+ 0x1d506, 0x1d506,
+ 0x1d50b, 0x1d50c,
+ 0x1d515, 0x1d515,
+ 0x1d51d, 0x1d51d,
+ 0x1d53a, 0x1d53a,
+ 0x1d53f, 0x1d53f,
+ 0x1d545, 0x1d545,
+ 0x1d547, 0x1d549,
+ 0x1d551, 0x1d551,
+ 0x1d6a6, 0x1d6a7,
+ 0x1d7cc, 0x1d7cd,
+ 0x1da8c, 0x1da9a,
+ 0x1daa0, 0x1daa0,
+ 0x1dab0, 0x1dfff,
+ 0x1e007, 0x1e007,
+ 0x1e019, 0x1e01a,
+ 0x1e022, 0x1e022,
+ 0x1e025, 0x1e025,
+ 0x1e02b, 0x1e0ff,
+ 0x1e12d, 0x1e12f,
+ 0x1e13e, 0x1e13f,
+ 0x1e14a, 0x1e14d,
+ 0x1e150, 0x1e2bf,
+ 0x1e2fa, 0x1e2fe,
+ 0x1e300, 0x1e7ff,
+ 0x1e8c5, 0x1e8c6,
+ 0x1e8d7, 0x1e8ff,
+ 0x1e94c, 0x1e94f,
+ 0x1e95a, 0x1e95d,
+ 0x1e960, 0x1ec70,
+ 0x1ecb5, 0x1ed00,
+ 0x1ed3e, 0x1edff,
+ 0x1ee04, 0x1ee04,
+ 0x1ee20, 0x1ee20,
+ 0x1ee23, 0x1ee23,
+ 0x1ee25, 0x1ee26,
+ 0x1ee28, 0x1ee28,
+ 0x1ee33, 0x1ee33,
+ 0x1ee38, 0x1ee38,
+ 0x1ee3a, 0x1ee3a,
+ 0x1ee3c, 0x1ee41,
+ 0x1ee43, 0x1ee46,
+ 0x1ee48, 0x1ee48,
+ 0x1ee4a, 0x1ee4a,
+ 0x1ee4c, 0x1ee4c,
+ 0x1ee50, 0x1ee50,
+ 0x1ee53, 0x1ee53,
+ 0x1ee55, 0x1ee56,
+ 0x1ee58, 0x1ee58,
+ 0x1ee5a, 0x1ee5a,
+ 0x1ee5c, 0x1ee5c,
+ 0x1ee5e, 0x1ee5e,
+ 0x1ee60, 0x1ee60,
+ 0x1ee63, 0x1ee63,
+ 0x1ee65, 0x1ee66,
+ 0x1ee6b, 0x1ee6b,
+ 0x1ee73, 0x1ee73,
+ 0x1ee78, 0x1ee78,
+ 0x1ee7d, 0x1ee7d,
+ 0x1ee7f, 0x1ee7f,
+ 0x1ee8a, 0x1ee8a,
+ 0x1ee9c, 0x1eea0,
+ 0x1eea4, 0x1eea4,
+ 0x1eeaa, 0x1eeaa,
+ 0x1eebc, 0x1eeef,
+ 0x1eef2, 0x1efff,
+ 0x1f02c, 0x1f02f,
+ 0x1f094, 0x1f09f,
+ 0x1f0af, 0x1f0b0,
+ 0x1f0c0, 0x1f0c0,
+ 0x1f0d0, 0x1f0d0,
+ 0x1f0f6, 0x1f0ff,
+ 0x1f10d, 0x1f10f,
+ 0x1f16d, 0x1f16f,
+ 0x1f1ad, 0x1f1e5,
+ 0x1f203, 0x1f20f,
+ 0x1f23c, 0x1f23f,
+ 0x1f249, 0x1f24f,
+ 0x1f252, 0x1f25f,
+ 0x1f266, 0x1f2ff,
+ 0x1f6d6, 0x1f6df,
+ 0x1f6ed, 0x1f6ef,
+ 0x1f6fb, 0x1f6ff,
+ 0x1f774, 0x1f77f,
+ 0x1f7d9, 0x1f7df,
+ 0x1f7ec, 0x1f7ff,
+ 0x1f80c, 0x1f80f,
+ 0x1f848, 0x1f84f,
+ 0x1f85a, 0x1f85f,
+ 0x1f888, 0x1f88f,
+ 0x1f8ae, 0x1f8ff,
+ 0x1f90c, 0x1f90c,
+ 0x1f972, 0x1f972,
+ 0x1f977, 0x1f979,
+ 0x1f9a3, 0x1f9a4,
+ 0x1f9ab, 0x1f9ad,
+ 0x1f9cb, 0x1f9cc,
+ 0x1fa54, 0x1fa5f,
+ 0x1fa6e, 0x1fa6f,
+ 0x1fa74, 0x1fa77,
+ 0x1fa7b, 0x1fa7f,
+ 0x1fa83, 0x1fa8f,
+ 0x1fa96, 0x1ffff,
+ 0x2a6d7, 0x2a6ff,
+ 0x2b735, 0x2b73f,
+ 0x2b81e, 0x2b81f,
+ 0x2cea2, 0x2ceaf,
+ 0x2ebe1, 0x2f7ff,
+ 0x2fa1e, 0xe00ff,
+ 0xe01f0, 0x10ffff,
+}; /* CR_C */
+
+/* 'Cc': General Category */
+#define CR_Cc CR_Cntrl
+
+/* 'Cf': General Category */
+static const OnigCodePoint CR_Cf[] = {
+ 20,
+ 0x00ad, 0x00ad,
+ 0x0600, 0x0605,
+ 0x061c, 0x061c,
+ 0x06dd, 0x06dd,
+ 0x070f, 0x070f,
+ 0x08e2, 0x08e2,
+ 0x180e, 0x180e,
+ 0x200b, 0x200f,
+ 0x202a, 0x202e,
+ 0x2060, 0x2064,
+ 0x2066, 0x206f,
+ 0xfeff, 0xfeff,
+ 0xfff9, 0xfffb,
+ 0x110bd, 0x110bd,
+ 0x110cd, 0x110cd,
+ 0x13430, 0x13438,
+ 0x1bca0, 0x1bca3,
+ 0x1d173, 0x1d17a,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+}; /* CR_Cf */
+
+/* 'Cn': General Category */
+static const OnigCodePoint CR_Cn[] = {
+ 666,
+ 0x0378, 0x0379,
+ 0x0380, 0x0383,
+ 0x038b, 0x038b,
+ 0x038d, 0x038d,
+ 0x03a2, 0x03a2,
+ 0x0530, 0x0530,
+ 0x0557, 0x0558,
+ 0x058b, 0x058c,
+ 0x0590, 0x0590,
+ 0x05c8, 0x05cf,
+ 0x05eb, 0x05ee,
+ 0x05f5, 0x05ff,
+ 0x061d, 0x061d,
+ 0x070e, 0x070e,
+ 0x074b, 0x074c,
+ 0x07b2, 0x07bf,
+ 0x07fb, 0x07fc,
+ 0x082e, 0x082f,
+ 0x083f, 0x083f,
+ 0x085c, 0x085d,
+ 0x085f, 0x085f,
+ 0x086b, 0x089f,
+ 0x08b5, 0x08b5,
+ 0x08be, 0x08d2,
+ 0x0984, 0x0984,
+ 0x098d, 0x098e,
+ 0x0991, 0x0992,
+ 0x09a9, 0x09a9,
+ 0x09b1, 0x09b1,
+ 0x09b3, 0x09b5,
+ 0x09ba, 0x09bb,
+ 0x09c5, 0x09c6,
+ 0x09c9, 0x09ca,
+ 0x09cf, 0x09d6,
+ 0x09d8, 0x09db,
+ 0x09de, 0x09de,
+ 0x09e4, 0x09e5,
+ 0x09ff, 0x0a00,
+ 0x0a04, 0x0a04,
+ 0x0a0b, 0x0a0e,
+ 0x0a11, 0x0a12,
+ 0x0a29, 0x0a29,
+ 0x0a31, 0x0a31,
+ 0x0a34, 0x0a34,
+ 0x0a37, 0x0a37,
+ 0x0a3a, 0x0a3b,
+ 0x0a3d, 0x0a3d,
+ 0x0a43, 0x0a46,
+ 0x0a49, 0x0a4a,
+ 0x0a4e, 0x0a50,
+ 0x0a52, 0x0a58,
+ 0x0a5d, 0x0a5d,
+ 0x0a5f, 0x0a65,
+ 0x0a77, 0x0a80,
+ 0x0a84, 0x0a84,
+ 0x0a8e, 0x0a8e,
+ 0x0a92, 0x0a92,
+ 0x0aa9, 0x0aa9,
+ 0x0ab1, 0x0ab1,
+ 0x0ab4, 0x0ab4,
+ 0x0aba, 0x0abb,
+ 0x0ac6, 0x0ac6,
+ 0x0aca, 0x0aca,
+ 0x0ace, 0x0acf,
+ 0x0ad1, 0x0adf,
+ 0x0ae4, 0x0ae5,
+ 0x0af2, 0x0af8,
+ 0x0b00, 0x0b00,
+ 0x0b04, 0x0b04,
+ 0x0b0d, 0x0b0e,
+ 0x0b11, 0x0b12,
+ 0x0b29, 0x0b29,
+ 0x0b31, 0x0b31,
+ 0x0b34, 0x0b34,
+ 0x0b3a, 0x0b3b,
+ 0x0b45, 0x0b46,
+ 0x0b49, 0x0b4a,
+ 0x0b4e, 0x0b55,
+ 0x0b58, 0x0b5b,
+ 0x0b5e, 0x0b5e,
+ 0x0b64, 0x0b65,
+ 0x0b78, 0x0b81,
+ 0x0b84, 0x0b84,
+ 0x0b8b, 0x0b8d,
+ 0x0b91, 0x0b91,
+ 0x0b96, 0x0b98,
+ 0x0b9b, 0x0b9b,
+ 0x0b9d, 0x0b9d,
+ 0x0ba0, 0x0ba2,
+ 0x0ba5, 0x0ba7,
+ 0x0bab, 0x0bad,
+ 0x0bba, 0x0bbd,
+ 0x0bc3, 0x0bc5,
+ 0x0bc9, 0x0bc9,
+ 0x0bce, 0x0bcf,
+ 0x0bd1, 0x0bd6,
+ 0x0bd8, 0x0be5,
+ 0x0bfb, 0x0bff,
+ 0x0c0d, 0x0c0d,
+ 0x0c11, 0x0c11,
+ 0x0c29, 0x0c29,
+ 0x0c3a, 0x0c3c,
+ 0x0c45, 0x0c45,
+ 0x0c49, 0x0c49,
+ 0x0c4e, 0x0c54,
+ 0x0c57, 0x0c57,
+ 0x0c5b, 0x0c5f,
+ 0x0c64, 0x0c65,
+ 0x0c70, 0x0c76,
+ 0x0c8d, 0x0c8d,
+ 0x0c91, 0x0c91,
+ 0x0ca9, 0x0ca9,
+ 0x0cb4, 0x0cb4,
+ 0x0cba, 0x0cbb,
+ 0x0cc5, 0x0cc5,
+ 0x0cc9, 0x0cc9,
+ 0x0cce, 0x0cd4,
+ 0x0cd7, 0x0cdd,
+ 0x0cdf, 0x0cdf,
+ 0x0ce4, 0x0ce5,
+ 0x0cf0, 0x0cf0,
+ 0x0cf3, 0x0cff,
+ 0x0d04, 0x0d04,
+ 0x0d0d, 0x0d0d,
+ 0x0d11, 0x0d11,
+ 0x0d45, 0x0d45,
+ 0x0d49, 0x0d49,
+ 0x0d50, 0x0d53,
+ 0x0d64, 0x0d65,
+ 0x0d80, 0x0d81,
+ 0x0d84, 0x0d84,
+ 0x0d97, 0x0d99,
+ 0x0db2, 0x0db2,
+ 0x0dbc, 0x0dbc,
+ 0x0dbe, 0x0dbf,
+ 0x0dc7, 0x0dc9,
+ 0x0dcb, 0x0dce,
+ 0x0dd5, 0x0dd5,
+ 0x0dd7, 0x0dd7,
+ 0x0de0, 0x0de5,
+ 0x0df0, 0x0df1,
+ 0x0df5, 0x0e00,
+ 0x0e3b, 0x0e3e,
+ 0x0e5c, 0x0e80,
+ 0x0e83, 0x0e83,
+ 0x0e85, 0x0e85,
+ 0x0e8b, 0x0e8b,
+ 0x0ea4, 0x0ea4,
+ 0x0ea6, 0x0ea6,
+ 0x0ebe, 0x0ebf,
+ 0x0ec5, 0x0ec5,
+ 0x0ec7, 0x0ec7,
+ 0x0ece, 0x0ecf,
+ 0x0eda, 0x0edb,
+ 0x0ee0, 0x0eff,
+ 0x0f48, 0x0f48,
+ 0x0f6d, 0x0f70,
+ 0x0f98, 0x0f98,
+ 0x0fbd, 0x0fbd,
+ 0x0fcd, 0x0fcd,
+ 0x0fdb, 0x0fff,
+ 0x10c6, 0x10c6,
+ 0x10c8, 0x10cc,
+ 0x10ce, 0x10cf,
+ 0x1249, 0x1249,
+ 0x124e, 0x124f,
+ 0x1257, 0x1257,
+ 0x1259, 0x1259,
+ 0x125e, 0x125f,
+ 0x1289, 0x1289,
+ 0x128e, 0x128f,
+ 0x12b1, 0x12b1,
+ 0x12b6, 0x12b7,
+ 0x12bf, 0x12bf,
+ 0x12c1, 0x12c1,
+ 0x12c6, 0x12c7,
+ 0x12d7, 0x12d7,
+ 0x1311, 0x1311,
+ 0x1316, 0x1317,
+ 0x135b, 0x135c,
+ 0x137d, 0x137f,
+ 0x139a, 0x139f,
+ 0x13f6, 0x13f7,
+ 0x13fe, 0x13ff,
+ 0x169d, 0x169f,
+ 0x16f9, 0x16ff,
+ 0x170d, 0x170d,
+ 0x1715, 0x171f,
+ 0x1737, 0x173f,
+ 0x1754, 0x175f,
+ 0x176d, 0x176d,
+ 0x1771, 0x1771,
+ 0x1774, 0x177f,
+ 0x17de, 0x17df,
+ 0x17ea, 0x17ef,
+ 0x17fa, 0x17ff,
+ 0x180f, 0x180f,
+ 0x181a, 0x181f,
+ 0x1879, 0x187f,
+ 0x18ab, 0x18af,
+ 0x18f6, 0x18ff,
+ 0x191f, 0x191f,
+ 0x192c, 0x192f,
+ 0x193c, 0x193f,
+ 0x1941, 0x1943,
+ 0x196e, 0x196f,
+ 0x1975, 0x197f,
+ 0x19ac, 0x19af,
+ 0x19ca, 0x19cf,
+ 0x19db, 0x19dd,
+ 0x1a1c, 0x1a1d,
+ 0x1a5f, 0x1a5f,
+ 0x1a7d, 0x1a7e,
+ 0x1a8a, 0x1a8f,
+ 0x1a9a, 0x1a9f,
+ 0x1aae, 0x1aaf,
+ 0x1abf, 0x1aff,
+ 0x1b4c, 0x1b4f,
+ 0x1b7d, 0x1b7f,
+ 0x1bf4, 0x1bfb,
+ 0x1c38, 0x1c3a,
+ 0x1c4a, 0x1c4c,
+ 0x1c89, 0x1c8f,
+ 0x1cbb, 0x1cbc,
+ 0x1cc8, 0x1ccf,
+ 0x1cfb, 0x1cff,
+ 0x1dfa, 0x1dfa,
+ 0x1f16, 0x1f17,
+ 0x1f1e, 0x1f1f,
+ 0x1f46, 0x1f47,
+ 0x1f4e, 0x1f4f,
+ 0x1f58, 0x1f58,
+ 0x1f5a, 0x1f5a,
+ 0x1f5c, 0x1f5c,
+ 0x1f5e, 0x1f5e,
+ 0x1f7e, 0x1f7f,
+ 0x1fb5, 0x1fb5,
+ 0x1fc5, 0x1fc5,
+ 0x1fd4, 0x1fd5,
+ 0x1fdc, 0x1fdc,
+ 0x1ff0, 0x1ff1,
+ 0x1ff5, 0x1ff5,
+ 0x1fff, 0x1fff,
+ 0x2065, 0x2065,
+ 0x2072, 0x2073,
+ 0x208f, 0x208f,
+ 0x209d, 0x209f,
+ 0x20c0, 0x20cf,
+ 0x20f1, 0x20ff,
+ 0x218c, 0x218f,
+ 0x2427, 0x243f,
+ 0x244b, 0x245f,
+ 0x2b74, 0x2b75,
+ 0x2b96, 0x2b97,
+ 0x2c2f, 0x2c2f,
+ 0x2c5f, 0x2c5f,
+ 0x2cf4, 0x2cf8,
+ 0x2d26, 0x2d26,
+ 0x2d28, 0x2d2c,
+ 0x2d2e, 0x2d2f,
+ 0x2d68, 0x2d6e,
+ 0x2d71, 0x2d7e,
+ 0x2d97, 0x2d9f,
+ 0x2da7, 0x2da7,
+ 0x2daf, 0x2daf,
+ 0x2db7, 0x2db7,
+ 0x2dbf, 0x2dbf,
+ 0x2dc7, 0x2dc7,
+ 0x2dcf, 0x2dcf,
+ 0x2dd7, 0x2dd7,
+ 0x2ddf, 0x2ddf,
+ 0x2e50, 0x2e7f,
+ 0x2e9a, 0x2e9a,
+ 0x2ef4, 0x2eff,
+ 0x2fd6, 0x2fef,
+ 0x2ffc, 0x2fff,
+ 0x3040, 0x3040,
+ 0x3097, 0x3098,
+ 0x3100, 0x3104,
+ 0x3130, 0x3130,
+ 0x318f, 0x318f,
+ 0x31bb, 0x31bf,
+ 0x31e4, 0x31ef,
+ 0x321f, 0x321f,
+ 0x4db6, 0x4dbf,
+ 0x9ff0, 0x9fff,
+ 0xa48d, 0xa48f,
+ 0xa4c7, 0xa4cf,
+ 0xa62c, 0xa63f,
+ 0xa6f8, 0xa6ff,
+ 0xa7c0, 0xa7c1,
+ 0xa7c7, 0xa7f6,
+ 0xa82c, 0xa82f,
+ 0xa83a, 0xa83f,
+ 0xa878, 0xa87f,
+ 0xa8c6, 0xa8cd,
+ 0xa8da, 0xa8df,
+ 0xa954, 0xa95e,
+ 0xa97d, 0xa97f,
+ 0xa9ce, 0xa9ce,
+ 0xa9da, 0xa9dd,
+ 0xa9ff, 0xa9ff,
+ 0xaa37, 0xaa3f,
+ 0xaa4e, 0xaa4f,
+ 0xaa5a, 0xaa5b,
+ 0xaac3, 0xaada,
+ 0xaaf7, 0xab00,
+ 0xab07, 0xab08,
+ 0xab0f, 0xab10,
+ 0xab17, 0xab1f,
+ 0xab27, 0xab27,
+ 0xab2f, 0xab2f,
+ 0xab68, 0xab6f,
+ 0xabee, 0xabef,
+ 0xabfa, 0xabff,
+ 0xd7a4, 0xd7af,
+ 0xd7c7, 0xd7ca,
+ 0xd7fc, 0xd7ff,
+ 0xfa6e, 0xfa6f,
+ 0xfada, 0xfaff,
+ 0xfb07, 0xfb12,
+ 0xfb18, 0xfb1c,
+ 0xfb37, 0xfb37,
+ 0xfb3d, 0xfb3d,
+ 0xfb3f, 0xfb3f,
+ 0xfb42, 0xfb42,
+ 0xfb45, 0xfb45,
+ 0xfbc2, 0xfbd2,
+ 0xfd40, 0xfd4f,
+ 0xfd90, 0xfd91,
+ 0xfdc8, 0xfdef,
+ 0xfdfe, 0xfdff,
+ 0xfe1a, 0xfe1f,
+ 0xfe53, 0xfe53,
+ 0xfe67, 0xfe67,
+ 0xfe6c, 0xfe6f,
+ 0xfe75, 0xfe75,
+ 0xfefd, 0xfefe,
+ 0xff00, 0xff00,
+ 0xffbf, 0xffc1,
+ 0xffc8, 0xffc9,
+ 0xffd0, 0xffd1,
+ 0xffd8, 0xffd9,
+ 0xffdd, 0xffdf,
+ 0xffe7, 0xffe7,
+ 0xffef, 0xfff8,
+ 0xfffe, 0xffff,
+ 0x1000c, 0x1000c,
+ 0x10027, 0x10027,
+ 0x1003b, 0x1003b,
+ 0x1003e, 0x1003e,
+ 0x1004e, 0x1004f,
+ 0x1005e, 0x1007f,
+ 0x100fb, 0x100ff,
+ 0x10103, 0x10106,
+ 0x10134, 0x10136,
+ 0x1018f, 0x1018f,
+ 0x1019c, 0x1019f,
+ 0x101a1, 0x101cf,
+ 0x101fe, 0x1027f,
+ 0x1029d, 0x1029f,
+ 0x102d1, 0x102df,
+ 0x102fc, 0x102ff,
+ 0x10324, 0x1032c,
+ 0x1034b, 0x1034f,
+ 0x1037b, 0x1037f,
+ 0x1039e, 0x1039e,
+ 0x103c4, 0x103c7,
+ 0x103d6, 0x103ff,
+ 0x1049e, 0x1049f,
+ 0x104aa, 0x104af,
+ 0x104d4, 0x104d7,
+ 0x104fc, 0x104ff,
+ 0x10528, 0x1052f,
+ 0x10564, 0x1056e,
+ 0x10570, 0x105ff,
+ 0x10737, 0x1073f,
+ 0x10756, 0x1075f,
+ 0x10768, 0x107ff,
+ 0x10806, 0x10807,
+ 0x10809, 0x10809,
+ 0x10836, 0x10836,
+ 0x10839, 0x1083b,
+ 0x1083d, 0x1083e,
+ 0x10856, 0x10856,
+ 0x1089f, 0x108a6,
+ 0x108b0, 0x108df,
+ 0x108f3, 0x108f3,
+ 0x108f6, 0x108fa,
+ 0x1091c, 0x1091e,
+ 0x1093a, 0x1093e,
+ 0x10940, 0x1097f,
+ 0x109b8, 0x109bb,
+ 0x109d0, 0x109d1,
+ 0x10a04, 0x10a04,
+ 0x10a07, 0x10a0b,
+ 0x10a14, 0x10a14,
+ 0x10a18, 0x10a18,
+ 0x10a36, 0x10a37,
+ 0x10a3b, 0x10a3e,
+ 0x10a49, 0x10a4f,
+ 0x10a59, 0x10a5f,
+ 0x10aa0, 0x10abf,
+ 0x10ae7, 0x10aea,
+ 0x10af7, 0x10aff,
+ 0x10b36, 0x10b38,
+ 0x10b56, 0x10b57,
+ 0x10b73, 0x10b77,
+ 0x10b92, 0x10b98,
+ 0x10b9d, 0x10ba8,
+ 0x10bb0, 0x10bff,
+ 0x10c49, 0x10c7f,
+ 0x10cb3, 0x10cbf,
+ 0x10cf3, 0x10cf9,
+ 0x10d28, 0x10d2f,
+ 0x10d3a, 0x10e5f,
+ 0x10e7f, 0x10eff,
+ 0x10f28, 0x10f2f,
+ 0x10f5a, 0x10fdf,
+ 0x10ff7, 0x10fff,
+ 0x1104e, 0x11051,
+ 0x11070, 0x1107e,
+ 0x110c2, 0x110cc,
+ 0x110ce, 0x110cf,
+ 0x110e9, 0x110ef,
+ 0x110fa, 0x110ff,
+ 0x11135, 0x11135,
+ 0x11147, 0x1114f,
+ 0x11177, 0x1117f,
+ 0x111ce, 0x111cf,
+ 0x111e0, 0x111e0,
+ 0x111f5, 0x111ff,
+ 0x11212, 0x11212,
+ 0x1123f, 0x1127f,
+ 0x11287, 0x11287,
+ 0x11289, 0x11289,
+ 0x1128e, 0x1128e,
+ 0x1129e, 0x1129e,
+ 0x112aa, 0x112af,
+ 0x112eb, 0x112ef,
+ 0x112fa, 0x112ff,
+ 0x11304, 0x11304,
+ 0x1130d, 0x1130e,
+ 0x11311, 0x11312,
+ 0x11329, 0x11329,
+ 0x11331, 0x11331,
+ 0x11334, 0x11334,
+ 0x1133a, 0x1133a,
+ 0x11345, 0x11346,
+ 0x11349, 0x1134a,
+ 0x1134e, 0x1134f,
+ 0x11351, 0x11356,
+ 0x11358, 0x1135c,
+ 0x11364, 0x11365,
+ 0x1136d, 0x1136f,
+ 0x11375, 0x113ff,
+ 0x1145a, 0x1145a,
+ 0x1145c, 0x1145c,
+ 0x11460, 0x1147f,
+ 0x114c8, 0x114cf,
+ 0x114da, 0x1157f,
+ 0x115b6, 0x115b7,
+ 0x115de, 0x115ff,
+ 0x11645, 0x1164f,
+ 0x1165a, 0x1165f,
+ 0x1166d, 0x1167f,
+ 0x116b9, 0x116bf,
+ 0x116ca, 0x116ff,
+ 0x1171b, 0x1171c,
+ 0x1172c, 0x1172f,
+ 0x11740, 0x117ff,
+ 0x1183c, 0x1189f,
+ 0x118f3, 0x118fe,
+ 0x11900, 0x1199f,
+ 0x119a8, 0x119a9,
+ 0x119d8, 0x119d9,
+ 0x119e5, 0x119ff,
+ 0x11a48, 0x11a4f,
+ 0x11aa3, 0x11abf,
+ 0x11af9, 0x11bff,
+ 0x11c09, 0x11c09,
+ 0x11c37, 0x11c37,
+ 0x11c46, 0x11c4f,
+ 0x11c6d, 0x11c6f,
+ 0x11c90, 0x11c91,
+ 0x11ca8, 0x11ca8,
+ 0x11cb7, 0x11cff,
+ 0x11d07, 0x11d07,
+ 0x11d0a, 0x11d0a,
+ 0x11d37, 0x11d39,
+ 0x11d3b, 0x11d3b,
+ 0x11d3e, 0x11d3e,
+ 0x11d48, 0x11d4f,
+ 0x11d5a, 0x11d5f,
+ 0x11d66, 0x11d66,
+ 0x11d69, 0x11d69,
+ 0x11d8f, 0x11d8f,
+ 0x11d92, 0x11d92,
+ 0x11d99, 0x11d9f,
+ 0x11daa, 0x11edf,
+ 0x11ef9, 0x11fbf,
+ 0x11ff2, 0x11ffe,
+ 0x1239a, 0x123ff,
+ 0x1246f, 0x1246f,
+ 0x12475, 0x1247f,
+ 0x12544, 0x12fff,
+ 0x1342f, 0x1342f,
+ 0x13439, 0x143ff,
+ 0x14647, 0x167ff,
+ 0x16a39, 0x16a3f,
+ 0x16a5f, 0x16a5f,
+ 0x16a6a, 0x16a6d,
+ 0x16a70, 0x16acf,
+ 0x16aee, 0x16aef,
+ 0x16af6, 0x16aff,
+ 0x16b46, 0x16b4f,
+ 0x16b5a, 0x16b5a,
+ 0x16b62, 0x16b62,
+ 0x16b78, 0x16b7c,
+ 0x16b90, 0x16e3f,
+ 0x16e9b, 0x16eff,
+ 0x16f4b, 0x16f4e,
+ 0x16f88, 0x16f8e,
+ 0x16fa0, 0x16fdf,
+ 0x16fe4, 0x16fff,
+ 0x187f8, 0x187ff,
+ 0x18af3, 0x1afff,
+ 0x1b11f, 0x1b14f,
+ 0x1b153, 0x1b163,
+ 0x1b168, 0x1b16f,
+ 0x1b2fc, 0x1bbff,
+ 0x1bc6b, 0x1bc6f,
+ 0x1bc7d, 0x1bc7f,
+ 0x1bc89, 0x1bc8f,
+ 0x1bc9a, 0x1bc9b,
+ 0x1bca4, 0x1cfff,
+ 0x1d0f6, 0x1d0ff,
+ 0x1d127, 0x1d128,
+ 0x1d1e9, 0x1d1ff,
+ 0x1d246, 0x1d2df,
+ 0x1d2f4, 0x1d2ff,
+ 0x1d357, 0x1d35f,
+ 0x1d379, 0x1d3ff,
+ 0x1d455, 0x1d455,
+ 0x1d49d, 0x1d49d,
+ 0x1d4a0, 0x1d4a1,
+ 0x1d4a3, 0x1d4a4,
+ 0x1d4a7, 0x1d4a8,
+ 0x1d4ad, 0x1d4ad,
+ 0x1d4ba, 0x1d4ba,
+ 0x1d4bc, 0x1d4bc,
+ 0x1d4c4, 0x1d4c4,
+ 0x1d506, 0x1d506,
+ 0x1d50b, 0x1d50c,
+ 0x1d515, 0x1d515,
+ 0x1d51d, 0x1d51d,
+ 0x1d53a, 0x1d53a,
+ 0x1d53f, 0x1d53f,
+ 0x1d545, 0x1d545,
+ 0x1d547, 0x1d549,
+ 0x1d551, 0x1d551,
+ 0x1d6a6, 0x1d6a7,
+ 0x1d7cc, 0x1d7cd,
+ 0x1da8c, 0x1da9a,
+ 0x1daa0, 0x1daa0,
+ 0x1dab0, 0x1dfff,
+ 0x1e007, 0x1e007,
+ 0x1e019, 0x1e01a,
+ 0x1e022, 0x1e022,
+ 0x1e025, 0x1e025,
+ 0x1e02b, 0x1e0ff,
+ 0x1e12d, 0x1e12f,
+ 0x1e13e, 0x1e13f,
+ 0x1e14a, 0x1e14d,
+ 0x1e150, 0x1e2bf,
+ 0x1e2fa, 0x1e2fe,
+ 0x1e300, 0x1e7ff,
+ 0x1e8c5, 0x1e8c6,
+ 0x1e8d7, 0x1e8ff,
+ 0x1e94c, 0x1e94f,
+ 0x1e95a, 0x1e95d,
+ 0x1e960, 0x1ec70,
+ 0x1ecb5, 0x1ed00,
+ 0x1ed3e, 0x1edff,
+ 0x1ee04, 0x1ee04,
+ 0x1ee20, 0x1ee20,
+ 0x1ee23, 0x1ee23,
+ 0x1ee25, 0x1ee26,
+ 0x1ee28, 0x1ee28,
+ 0x1ee33, 0x1ee33,
+ 0x1ee38, 0x1ee38,
+ 0x1ee3a, 0x1ee3a,
+ 0x1ee3c, 0x1ee41,
+ 0x1ee43, 0x1ee46,
+ 0x1ee48, 0x1ee48,
+ 0x1ee4a, 0x1ee4a,
+ 0x1ee4c, 0x1ee4c,
+ 0x1ee50, 0x1ee50,
+ 0x1ee53, 0x1ee53,
+ 0x1ee55, 0x1ee56,
+ 0x1ee58, 0x1ee58,
+ 0x1ee5a, 0x1ee5a,
+ 0x1ee5c, 0x1ee5c,
+ 0x1ee5e, 0x1ee5e,
+ 0x1ee60, 0x1ee60,
+ 0x1ee63, 0x1ee63,
+ 0x1ee65, 0x1ee66,
+ 0x1ee6b, 0x1ee6b,
+ 0x1ee73, 0x1ee73,
+ 0x1ee78, 0x1ee78,
+ 0x1ee7d, 0x1ee7d,
+ 0x1ee7f, 0x1ee7f,
+ 0x1ee8a, 0x1ee8a,
+ 0x1ee9c, 0x1eea0,
+ 0x1eea4, 0x1eea4,
+ 0x1eeaa, 0x1eeaa,
+ 0x1eebc, 0x1eeef,
+ 0x1eef2, 0x1efff,
+ 0x1f02c, 0x1f02f,
+ 0x1f094, 0x1f09f,
+ 0x1f0af, 0x1f0b0,
+ 0x1f0c0, 0x1f0c0,
+ 0x1f0d0, 0x1f0d0,
+ 0x1f0f6, 0x1f0ff,
+ 0x1f10d, 0x1f10f,
+ 0x1f16d, 0x1f16f,
+ 0x1f1ad, 0x1f1e5,
+ 0x1f203, 0x1f20f,
+ 0x1f23c, 0x1f23f,
+ 0x1f249, 0x1f24f,
+ 0x1f252, 0x1f25f,
+ 0x1f266, 0x1f2ff,
+ 0x1f6d6, 0x1f6df,
+ 0x1f6ed, 0x1f6ef,
+ 0x1f6fb, 0x1f6ff,
+ 0x1f774, 0x1f77f,
+ 0x1f7d9, 0x1f7df,
+ 0x1f7ec, 0x1f7ff,
+ 0x1f80c, 0x1f80f,
+ 0x1f848, 0x1f84f,
+ 0x1f85a, 0x1f85f,
+ 0x1f888, 0x1f88f,
+ 0x1f8ae, 0x1f8ff,
+ 0x1f90c, 0x1f90c,
+ 0x1f972, 0x1f972,
+ 0x1f977, 0x1f979,
+ 0x1f9a3, 0x1f9a4,
+ 0x1f9ab, 0x1f9ad,
+ 0x1f9cb, 0x1f9cc,
+ 0x1fa54, 0x1fa5f,
+ 0x1fa6e, 0x1fa6f,
+ 0x1fa74, 0x1fa77,
+ 0x1fa7b, 0x1fa7f,
+ 0x1fa83, 0x1fa8f,
+ 0x1fa96, 0x1ffff,
+ 0x2a6d7, 0x2a6ff,
+ 0x2b735, 0x2b73f,
+ 0x2b81e, 0x2b81f,
+ 0x2cea2, 0x2ceaf,
+ 0x2ebe1, 0x2f7ff,
+ 0x2fa1e, 0xe0000,
+ 0xe0002, 0xe001f,
+ 0xe0080, 0xe00ff,
+ 0xe01f0, 0xeffff,
+ 0xffffe, 0xfffff,
+ 0x10fffe, 0x10ffff,
+}; /* CR_Cn */
+
+/* 'Co': General Category */
+static const OnigCodePoint CR_Co[] = {
+ 3,
+ 0xe000, 0xf8ff,
+ 0xf0000, 0xffffd,
+ 0x100000, 0x10fffd,
+}; /* CR_Co */
+
+/* 'Cs': General Category */
+static const OnigCodePoint CR_Cs[] = {
+ 1,
+ 0xd800, 0xdfff,
+}; /* CR_Cs */
+
+/* 'L': Major Category */
+static const OnigCodePoint CR_L[] = {
+ 609,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0370, 0x0374,
+ 0x0376, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0620, 0x064a,
+ 0x066e, 0x066f,
+ 0x0671, 0x06d3,
+ 0x06d5, 0x06d5,
+ 0x06e5, 0x06e6,
+ 0x06ee, 0x06ef,
+ 0x06fa, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x0710,
+ 0x0712, 0x072f,
+ 0x074d, 0x07a5,
+ 0x07b1, 0x07b1,
+ 0x07ca, 0x07ea,
+ 0x07f4, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x0800, 0x0815,
+ 0x081a, 0x081a,
+ 0x0824, 0x0824,
+ 0x0828, 0x0828,
+ 0x0840, 0x0858,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x0904, 0x0939,
+ 0x093d, 0x093d,
+ 0x0950, 0x0950,
+ 0x0958, 0x0961,
+ 0x0971, 0x0980,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09bd,
+ 0x09ce, 0x09ce,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e1,
+ 0x09f0, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a72, 0x0a74,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0abd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae1,
+ 0x0af9, 0x0af9,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b3d,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b71, 0x0b71,
+ 0x0b83, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bd0, 0x0bd0,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c3d,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c61,
+ 0x0c80, 0x0c80,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cbd,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0cf1, 0x0cf2,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d3d,
+ 0x0d4e, 0x0d4e,
+ 0x0d54, 0x0d56,
+ 0x0d5f, 0x0d61,
+ 0x0d7a, 0x0d7f,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0e01, 0x0e30,
+ 0x0e32, 0x0e33,
+ 0x0e40, 0x0e46,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0eb0,
+ 0x0eb2, 0x0eb3,
+ 0x0ebd, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f88, 0x0f8c,
+ 0x1000, 0x102a,
+ 0x103f, 0x103f,
+ 0x1050, 0x1055,
+ 0x105a, 0x105d,
+ 0x1061, 0x1061,
+ 0x1065, 0x1066,
+ 0x106e, 0x1070,
+ 0x1075, 0x1081,
+ 0x108e, 0x108e,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16f1, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1711,
+ 0x1720, 0x1731,
+ 0x1740, 0x1751,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1780, 0x17b3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dc,
+ 0x1820, 0x1878,
+ 0x1880, 0x1884,
+ 0x1887, 0x18a8,
+ 0x18aa, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x1a00, 0x1a16,
+ 0x1a20, 0x1a54,
+ 0x1aa7, 0x1aa7,
+ 0x1b05, 0x1b33,
+ 0x1b45, 0x1b4b,
+ 0x1b83, 0x1ba0,
+ 0x1bae, 0x1baf,
+ 0x1bba, 0x1be5,
+ 0x1c00, 0x1c23,
+ 0x1c4d, 0x1c4f,
+ 0x1c5a, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf6,
+ 0x1cfa, 0x1cfa,
+ 0x1d00, 0x1dbf,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2183, 0x2184,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2e2f, 0x2e2f,
+ 0x3005, 0x3006,
+ 0x3031, 0x3035,
+ 0x303b, 0x303c,
+ 0x3041, 0x3096,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa61f,
+ 0xa62a, 0xa62b,
+ 0xa640, 0xa66e,
+ 0xa67f, 0xa69d,
+ 0xa6a0, 0xa6e5,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa801,
+ 0xa803, 0xa805,
+ 0xa807, 0xa80a,
+ 0xa80c, 0xa822,
+ 0xa840, 0xa873,
+ 0xa882, 0xa8b3,
+ 0xa8f2, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa8fe,
+ 0xa90a, 0xa925,
+ 0xa930, 0xa946,
+ 0xa960, 0xa97c,
+ 0xa984, 0xa9b2,
+ 0xa9cf, 0xa9cf,
+ 0xa9e0, 0xa9e4,
+ 0xa9e6, 0xa9ef,
+ 0xa9fa, 0xa9fe,
+ 0xaa00, 0xaa28,
+ 0xaa40, 0xaa42,
+ 0xaa44, 0xaa4b,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaa7a,
+ 0xaa7e, 0xaaaf,
+ 0xaab1, 0xaab1,
+ 0xaab5, 0xaab6,
+ 0xaab9, 0xaabd,
+ 0xaac0, 0xaac0,
+ 0xaac2, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaea,
+ 0xaaf2, 0xaaf4,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabe2,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb1d,
+ 0xfb1f, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x10340,
+ 0x10342, 0x10349,
+ 0x10350, 0x10375,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x10400, 0x1049d,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a00,
+ 0x10a10, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae4,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d23,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f45,
+ 0x10fe0, 0x10ff6,
+ 0x11003, 0x11037,
+ 0x11083, 0x110af,
+ 0x110d0, 0x110e8,
+ 0x11103, 0x11126,
+ 0x11144, 0x11144,
+ 0x11150, 0x11172,
+ 0x11176, 0x11176,
+ 0x11183, 0x111b2,
+ 0x111c1, 0x111c4,
+ 0x111da, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x1122b,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112de,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133d, 0x1133d,
+ 0x11350, 0x11350,
+ 0x1135d, 0x11361,
+ 0x11400, 0x11434,
+ 0x11447, 0x1144a,
+ 0x1145f, 0x1145f,
+ 0x11480, 0x114af,
+ 0x114c4, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x11580, 0x115ae,
+ 0x115d8, 0x115db,
+ 0x11600, 0x1162f,
+ 0x11644, 0x11644,
+ 0x11680, 0x116aa,
+ 0x116b8, 0x116b8,
+ 0x11700, 0x1171a,
+ 0x11800, 0x1182b,
+ 0x118a0, 0x118df,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d0,
+ 0x119e1, 0x119e1,
+ 0x119e3, 0x119e3,
+ 0x11a00, 0x11a00,
+ 0x11a0b, 0x11a32,
+ 0x11a3a, 0x11a3a,
+ 0x11a50, 0x11a50,
+ 0x11a5c, 0x11a89,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c2e,
+ 0x11c40, 0x11c40,
+ 0x11c72, 0x11c8f,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d30,
+ 0x11d46, 0x11d46,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d89,
+ 0x11d98, 0x11d98,
+ 0x11ee0, 0x11ef2,
+ 0x12000, 0x12399,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16ad0, 0x16aed,
+ 0x16b00, 0x16b2f,
+ 0x16b40, 0x16b43,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f50, 0x16f50,
+ 0x16f93, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1e100, 0x1e12c,
+ 0x1e137, 0x1e13d,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2eb,
+ 0x1e800, 0x1e8c4,
+ 0x1e900, 0x1e943,
+ 0x1e94b, 0x1e94b,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_L */
+
+/* 'LC': General Category */
+static const OnigCodePoint CR_LC[] = {
+ 131,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00b5, 0x00b5,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x01ba,
+ 0x01bc, 0x01bf,
+ 0x01c4, 0x0293,
+ 0x0295, 0x02af,
+ 0x0370, 0x0373,
+ 0x0376, 0x0377,
+ 0x037b, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0560, 0x0588,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fd, 0x10ff,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1d00, 0x1d2b,
+ 0x1d6b, 0x1d77,
+ 0x1d79, 0x1d9a,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2134,
+ 0x2139, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2183, 0x2184,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2c7b,
+ 0x2c7e, 0x2ce4,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0xa640, 0xa66d,
+ 0xa680, 0xa69b,
+ 0xa722, 0xa76f,
+ 0xa771, 0xa787,
+ 0xa78b, 0xa78e,
+ 0xa790, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7fa, 0xa7fa,
+ 0xab30, 0xab5a,
+ 0xab60, 0xab67,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0x10400, 0x1044f,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x118a0, 0x118df,
+ 0x16e40, 0x16e7f,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1e900, 0x1e943,
+}; /* CR_LC */
+
+/* 'Ll': General Category */
+static const OnigCodePoint CR_Ll[] = {
+ 642,
+ 0x0061, 0x007a,
+ 0x00b5, 0x00b5,
+ 0x00df, 0x00f6,
+ 0x00f8, 0x00ff,
+ 0x0101, 0x0101,
+ 0x0103, 0x0103,
+ 0x0105, 0x0105,
+ 0x0107, 0x0107,
+ 0x0109, 0x0109,
+ 0x010b, 0x010b,
+ 0x010d, 0x010d,
+ 0x010f, 0x010f,
+ 0x0111, 0x0111,
+ 0x0113, 0x0113,
+ 0x0115, 0x0115,
+ 0x0117, 0x0117,
+ 0x0119, 0x0119,
+ 0x011b, 0x011b,
+ 0x011d, 0x011d,
+ 0x011f, 0x011f,
+ 0x0121, 0x0121,
+ 0x0123, 0x0123,
+ 0x0125, 0x0125,
+ 0x0127, 0x0127,
+ 0x0129, 0x0129,
+ 0x012b, 0x012b,
+ 0x012d, 0x012d,
+ 0x012f, 0x012f,
+ 0x0131, 0x0131,
+ 0x0133, 0x0133,
+ 0x0135, 0x0135,
+ 0x0137, 0x0138,
+ 0x013a, 0x013a,
+ 0x013c, 0x013c,
+ 0x013e, 0x013e,
+ 0x0140, 0x0140,
+ 0x0142, 0x0142,
+ 0x0144, 0x0144,
+ 0x0146, 0x0146,
+ 0x0148, 0x0149,
+ 0x014b, 0x014b,
+ 0x014d, 0x014d,
+ 0x014f, 0x014f,
+ 0x0151, 0x0151,
+ 0x0153, 0x0153,
+ 0x0155, 0x0155,
+ 0x0157, 0x0157,
+ 0x0159, 0x0159,
+ 0x015b, 0x015b,
+ 0x015d, 0x015d,
+ 0x015f, 0x015f,
+ 0x0161, 0x0161,
+ 0x0163, 0x0163,
+ 0x0165, 0x0165,
+ 0x0167, 0x0167,
+ 0x0169, 0x0169,
+ 0x016b, 0x016b,
+ 0x016d, 0x016d,
+ 0x016f, 0x016f,
+ 0x0171, 0x0171,
+ 0x0173, 0x0173,
+ 0x0175, 0x0175,
+ 0x0177, 0x0177,
+ 0x017a, 0x017a,
+ 0x017c, 0x017c,
+ 0x017e, 0x0180,
+ 0x0183, 0x0183,
+ 0x0185, 0x0185,
+ 0x0188, 0x0188,
+ 0x018c, 0x018d,
+ 0x0192, 0x0192,
+ 0x0195, 0x0195,
+ 0x0199, 0x019b,
+ 0x019e, 0x019e,
+ 0x01a1, 0x01a1,
+ 0x01a3, 0x01a3,
+ 0x01a5, 0x01a5,
+ 0x01a8, 0x01a8,
+ 0x01aa, 0x01ab,
+ 0x01ad, 0x01ad,
+ 0x01b0, 0x01b0,
+ 0x01b4, 0x01b4,
+ 0x01b6, 0x01b6,
+ 0x01b9, 0x01ba,
+ 0x01bd, 0x01bf,
+ 0x01c6, 0x01c6,
+ 0x01c9, 0x01c9,
+ 0x01cc, 0x01cc,
+ 0x01ce, 0x01ce,
+ 0x01d0, 0x01d0,
+ 0x01d2, 0x01d2,
+ 0x01d4, 0x01d4,
+ 0x01d6, 0x01d6,
+ 0x01d8, 0x01d8,
+ 0x01da, 0x01da,
+ 0x01dc, 0x01dd,
+ 0x01df, 0x01df,
+ 0x01e1, 0x01e1,
+ 0x01e3, 0x01e3,
+ 0x01e5, 0x01e5,
+ 0x01e7, 0x01e7,
+ 0x01e9, 0x01e9,
+ 0x01eb, 0x01eb,
+ 0x01ed, 0x01ed,
+ 0x01ef, 0x01f0,
+ 0x01f3, 0x01f3,
+ 0x01f5, 0x01f5,
+ 0x01f9, 0x01f9,
+ 0x01fb, 0x01fb,
+ 0x01fd, 0x01fd,
+ 0x01ff, 0x01ff,
+ 0x0201, 0x0201,
+ 0x0203, 0x0203,
+ 0x0205, 0x0205,
+ 0x0207, 0x0207,
+ 0x0209, 0x0209,
+ 0x020b, 0x020b,
+ 0x020d, 0x020d,
+ 0x020f, 0x020f,
+ 0x0211, 0x0211,
+ 0x0213, 0x0213,
+ 0x0215, 0x0215,
+ 0x0217, 0x0217,
+ 0x0219, 0x0219,
+ 0x021b, 0x021b,
+ 0x021d, 0x021d,
+ 0x021f, 0x021f,
+ 0x0221, 0x0221,
+ 0x0223, 0x0223,
+ 0x0225, 0x0225,
+ 0x0227, 0x0227,
+ 0x0229, 0x0229,
+ 0x022b, 0x022b,
+ 0x022d, 0x022d,
+ 0x022f, 0x022f,
+ 0x0231, 0x0231,
+ 0x0233, 0x0239,
+ 0x023c, 0x023c,
+ 0x023f, 0x0240,
+ 0x0242, 0x0242,
+ 0x0247, 0x0247,
+ 0x0249, 0x0249,
+ 0x024b, 0x024b,
+ 0x024d, 0x024d,
+ 0x024f, 0x0293,
+ 0x0295, 0x02af,
+ 0x0371, 0x0371,
+ 0x0373, 0x0373,
+ 0x0377, 0x0377,
+ 0x037b, 0x037d,
+ 0x0390, 0x0390,
+ 0x03ac, 0x03ce,
+ 0x03d0, 0x03d1,
+ 0x03d5, 0x03d7,
+ 0x03d9, 0x03d9,
+ 0x03db, 0x03db,
+ 0x03dd, 0x03dd,
+ 0x03df, 0x03df,
+ 0x03e1, 0x03e1,
+ 0x03e3, 0x03e3,
+ 0x03e5, 0x03e5,
+ 0x03e7, 0x03e7,
+ 0x03e9, 0x03e9,
+ 0x03eb, 0x03eb,
+ 0x03ed, 0x03ed,
+ 0x03ef, 0x03f3,
+ 0x03f5, 0x03f5,
+ 0x03f8, 0x03f8,
+ 0x03fb, 0x03fc,
+ 0x0430, 0x045f,
+ 0x0461, 0x0461,
+ 0x0463, 0x0463,
+ 0x0465, 0x0465,
+ 0x0467, 0x0467,
+ 0x0469, 0x0469,
+ 0x046b, 0x046b,
+ 0x046d, 0x046d,
+ 0x046f, 0x046f,
+ 0x0471, 0x0471,
+ 0x0473, 0x0473,
+ 0x0475, 0x0475,
+ 0x0477, 0x0477,
+ 0x0479, 0x0479,
+ 0x047b, 0x047b,
+ 0x047d, 0x047d,
+ 0x047f, 0x047f,
+ 0x0481, 0x0481,
+ 0x048b, 0x048b,
+ 0x048d, 0x048d,
+ 0x048f, 0x048f,
+ 0x0491, 0x0491,
+ 0x0493, 0x0493,
+ 0x0495, 0x0495,
+ 0x0497, 0x0497,
+ 0x0499, 0x0499,
+ 0x049b, 0x049b,
+ 0x049d, 0x049d,
+ 0x049f, 0x049f,
+ 0x04a1, 0x04a1,
+ 0x04a3, 0x04a3,
+ 0x04a5, 0x04a5,
+ 0x04a7, 0x04a7,
+ 0x04a9, 0x04a9,
+ 0x04ab, 0x04ab,
+ 0x04ad, 0x04ad,
+ 0x04af, 0x04af,
+ 0x04b1, 0x04b1,
+ 0x04b3, 0x04b3,
+ 0x04b5, 0x04b5,
+ 0x04b7, 0x04b7,
+ 0x04b9, 0x04b9,
+ 0x04bb, 0x04bb,
+ 0x04bd, 0x04bd,
+ 0x04bf, 0x04bf,
+ 0x04c2, 0x04c2,
+ 0x04c4, 0x04c4,
+ 0x04c6, 0x04c6,
+ 0x04c8, 0x04c8,
+ 0x04ca, 0x04ca,
+ 0x04cc, 0x04cc,
+ 0x04ce, 0x04cf,
+ 0x04d1, 0x04d1,
+ 0x04d3, 0x04d3,
+ 0x04d5, 0x04d5,
+ 0x04d7, 0x04d7,
+ 0x04d9, 0x04d9,
+ 0x04db, 0x04db,
+ 0x04dd, 0x04dd,
+ 0x04df, 0x04df,
+ 0x04e1, 0x04e1,
+ 0x04e3, 0x04e3,
+ 0x04e5, 0x04e5,
+ 0x04e7, 0x04e7,
+ 0x04e9, 0x04e9,
+ 0x04eb, 0x04eb,
+ 0x04ed, 0x04ed,
+ 0x04ef, 0x04ef,
+ 0x04f1, 0x04f1,
+ 0x04f3, 0x04f3,
+ 0x04f5, 0x04f5,
+ 0x04f7, 0x04f7,
+ 0x04f9, 0x04f9,
+ 0x04fb, 0x04fb,
+ 0x04fd, 0x04fd,
+ 0x04ff, 0x04ff,
+ 0x0501, 0x0501,
+ 0x0503, 0x0503,
+ 0x0505, 0x0505,
+ 0x0507, 0x0507,
+ 0x0509, 0x0509,
+ 0x050b, 0x050b,
+ 0x050d, 0x050d,
+ 0x050f, 0x050f,
+ 0x0511, 0x0511,
+ 0x0513, 0x0513,
+ 0x0515, 0x0515,
+ 0x0517, 0x0517,
+ 0x0519, 0x0519,
+ 0x051b, 0x051b,
+ 0x051d, 0x051d,
+ 0x051f, 0x051f,
+ 0x0521, 0x0521,
+ 0x0523, 0x0523,
+ 0x0525, 0x0525,
+ 0x0527, 0x0527,
+ 0x0529, 0x0529,
+ 0x052b, 0x052b,
+ 0x052d, 0x052d,
+ 0x052f, 0x052f,
+ 0x0560, 0x0588,
+ 0x10d0, 0x10fa,
+ 0x10fd, 0x10ff,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1d00, 0x1d2b,
+ 0x1d6b, 0x1d77,
+ 0x1d79, 0x1d9a,
+ 0x1e01, 0x1e01,
+ 0x1e03, 0x1e03,
+ 0x1e05, 0x1e05,
+ 0x1e07, 0x1e07,
+ 0x1e09, 0x1e09,
+ 0x1e0b, 0x1e0b,
+ 0x1e0d, 0x1e0d,
+ 0x1e0f, 0x1e0f,
+ 0x1e11, 0x1e11,
+ 0x1e13, 0x1e13,
+ 0x1e15, 0x1e15,
+ 0x1e17, 0x1e17,
+ 0x1e19, 0x1e19,
+ 0x1e1b, 0x1e1b,
+ 0x1e1d, 0x1e1d,
+ 0x1e1f, 0x1e1f,
+ 0x1e21, 0x1e21,
+ 0x1e23, 0x1e23,
+ 0x1e25, 0x1e25,
+ 0x1e27, 0x1e27,
+ 0x1e29, 0x1e29,
+ 0x1e2b, 0x1e2b,
+ 0x1e2d, 0x1e2d,
+ 0x1e2f, 0x1e2f,
+ 0x1e31, 0x1e31,
+ 0x1e33, 0x1e33,
+ 0x1e35, 0x1e35,
+ 0x1e37, 0x1e37,
+ 0x1e39, 0x1e39,
+ 0x1e3b, 0x1e3b,
+ 0x1e3d, 0x1e3d,
+ 0x1e3f, 0x1e3f,
+ 0x1e41, 0x1e41,
+ 0x1e43, 0x1e43,
+ 0x1e45, 0x1e45,
+ 0x1e47, 0x1e47,
+ 0x1e49, 0x1e49,
+ 0x1e4b, 0x1e4b,
+ 0x1e4d, 0x1e4d,
+ 0x1e4f, 0x1e4f,
+ 0x1e51, 0x1e51,
+ 0x1e53, 0x1e53,
+ 0x1e55, 0x1e55,
+ 0x1e57, 0x1e57,
+ 0x1e59, 0x1e59,
+ 0x1e5b, 0x1e5b,
+ 0x1e5d, 0x1e5d,
+ 0x1e5f, 0x1e5f,
+ 0x1e61, 0x1e61,
+ 0x1e63, 0x1e63,
+ 0x1e65, 0x1e65,
+ 0x1e67, 0x1e67,
+ 0x1e69, 0x1e69,
+ 0x1e6b, 0x1e6b,
+ 0x1e6d, 0x1e6d,
+ 0x1e6f, 0x1e6f,
+ 0x1e71, 0x1e71,
+ 0x1e73, 0x1e73,
+ 0x1e75, 0x1e75,
+ 0x1e77, 0x1e77,
+ 0x1e79, 0x1e79,
+ 0x1e7b, 0x1e7b,
+ 0x1e7d, 0x1e7d,
+ 0x1e7f, 0x1e7f,
+ 0x1e81, 0x1e81,
+ 0x1e83, 0x1e83,
+ 0x1e85, 0x1e85,
+ 0x1e87, 0x1e87,
+ 0x1e89, 0x1e89,
+ 0x1e8b, 0x1e8b,
+ 0x1e8d, 0x1e8d,
+ 0x1e8f, 0x1e8f,
+ 0x1e91, 0x1e91,
+ 0x1e93, 0x1e93,
+ 0x1e95, 0x1e9d,
+ 0x1e9f, 0x1e9f,
+ 0x1ea1, 0x1ea1,
+ 0x1ea3, 0x1ea3,
+ 0x1ea5, 0x1ea5,
+ 0x1ea7, 0x1ea7,
+ 0x1ea9, 0x1ea9,
+ 0x1eab, 0x1eab,
+ 0x1ead, 0x1ead,
+ 0x1eaf, 0x1eaf,
+ 0x1eb1, 0x1eb1,
+ 0x1eb3, 0x1eb3,
+ 0x1eb5, 0x1eb5,
+ 0x1eb7, 0x1eb7,
+ 0x1eb9, 0x1eb9,
+ 0x1ebb, 0x1ebb,
+ 0x1ebd, 0x1ebd,
+ 0x1ebf, 0x1ebf,
+ 0x1ec1, 0x1ec1,
+ 0x1ec3, 0x1ec3,
+ 0x1ec5, 0x1ec5,
+ 0x1ec7, 0x1ec7,
+ 0x1ec9, 0x1ec9,
+ 0x1ecb, 0x1ecb,
+ 0x1ecd, 0x1ecd,
+ 0x1ecf, 0x1ecf,
+ 0x1ed1, 0x1ed1,
+ 0x1ed3, 0x1ed3,
+ 0x1ed5, 0x1ed5,
+ 0x1ed7, 0x1ed7,
+ 0x1ed9, 0x1ed9,
+ 0x1edb, 0x1edb,
+ 0x1edd, 0x1edd,
+ 0x1edf, 0x1edf,
+ 0x1ee1, 0x1ee1,
+ 0x1ee3, 0x1ee3,
+ 0x1ee5, 0x1ee5,
+ 0x1ee7, 0x1ee7,
+ 0x1ee9, 0x1ee9,
+ 0x1eeb, 0x1eeb,
+ 0x1eed, 0x1eed,
+ 0x1eef, 0x1eef,
+ 0x1ef1, 0x1ef1,
+ 0x1ef3, 0x1ef3,
+ 0x1ef5, 0x1ef5,
+ 0x1ef7, 0x1ef7,
+ 0x1ef9, 0x1ef9,
+ 0x1efb, 0x1efb,
+ 0x1efd, 0x1efd,
+ 0x1eff, 0x1f07,
+ 0x1f10, 0x1f15,
+ 0x1f20, 0x1f27,
+ 0x1f30, 0x1f37,
+ 0x1f40, 0x1f45,
+ 0x1f50, 0x1f57,
+ 0x1f60, 0x1f67,
+ 0x1f70, 0x1f7d,
+ 0x1f80, 0x1f87,
+ 0x1f90, 0x1f97,
+ 0x1fa0, 0x1fa7,
+ 0x1fb0, 0x1fb4,
+ 0x1fb6, 0x1fb7,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fc7,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fd7,
+ 0x1fe0, 0x1fe7,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ff7,
+ 0x210a, 0x210a,
+ 0x210e, 0x210f,
+ 0x2113, 0x2113,
+ 0x212f, 0x212f,
+ 0x2134, 0x2134,
+ 0x2139, 0x2139,
+ 0x213c, 0x213d,
+ 0x2146, 0x2149,
+ 0x214e, 0x214e,
+ 0x2184, 0x2184,
+ 0x2c30, 0x2c5e,
+ 0x2c61, 0x2c61,
+ 0x2c65, 0x2c66,
+ 0x2c68, 0x2c68,
+ 0x2c6a, 0x2c6a,
+ 0x2c6c, 0x2c6c,
+ 0x2c71, 0x2c71,
+ 0x2c73, 0x2c74,
+ 0x2c76, 0x2c7b,
+ 0x2c81, 0x2c81,
+ 0x2c83, 0x2c83,
+ 0x2c85, 0x2c85,
+ 0x2c87, 0x2c87,
+ 0x2c89, 0x2c89,
+ 0x2c8b, 0x2c8b,
+ 0x2c8d, 0x2c8d,
+ 0x2c8f, 0x2c8f,
+ 0x2c91, 0x2c91,
+ 0x2c93, 0x2c93,
+ 0x2c95, 0x2c95,
+ 0x2c97, 0x2c97,
+ 0x2c99, 0x2c99,
+ 0x2c9b, 0x2c9b,
+ 0x2c9d, 0x2c9d,
+ 0x2c9f, 0x2c9f,
+ 0x2ca1, 0x2ca1,
+ 0x2ca3, 0x2ca3,
+ 0x2ca5, 0x2ca5,
+ 0x2ca7, 0x2ca7,
+ 0x2ca9, 0x2ca9,
+ 0x2cab, 0x2cab,
+ 0x2cad, 0x2cad,
+ 0x2caf, 0x2caf,
+ 0x2cb1, 0x2cb1,
+ 0x2cb3, 0x2cb3,
+ 0x2cb5, 0x2cb5,
+ 0x2cb7, 0x2cb7,
+ 0x2cb9, 0x2cb9,
+ 0x2cbb, 0x2cbb,
+ 0x2cbd, 0x2cbd,
+ 0x2cbf, 0x2cbf,
+ 0x2cc1, 0x2cc1,
+ 0x2cc3, 0x2cc3,
+ 0x2cc5, 0x2cc5,
+ 0x2cc7, 0x2cc7,
+ 0x2cc9, 0x2cc9,
+ 0x2ccb, 0x2ccb,
+ 0x2ccd, 0x2ccd,
+ 0x2ccf, 0x2ccf,
+ 0x2cd1, 0x2cd1,
+ 0x2cd3, 0x2cd3,
+ 0x2cd5, 0x2cd5,
+ 0x2cd7, 0x2cd7,
+ 0x2cd9, 0x2cd9,
+ 0x2cdb, 0x2cdb,
+ 0x2cdd, 0x2cdd,
+ 0x2cdf, 0x2cdf,
+ 0x2ce1, 0x2ce1,
+ 0x2ce3, 0x2ce4,
+ 0x2cec, 0x2cec,
+ 0x2cee, 0x2cee,
+ 0x2cf3, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0xa641, 0xa641,
+ 0xa643, 0xa643,
+ 0xa645, 0xa645,
+ 0xa647, 0xa647,
+ 0xa649, 0xa649,
+ 0xa64b, 0xa64b,
+ 0xa64d, 0xa64d,
+ 0xa64f, 0xa64f,
+ 0xa651, 0xa651,
+ 0xa653, 0xa653,
+ 0xa655, 0xa655,
+ 0xa657, 0xa657,
+ 0xa659, 0xa659,
+ 0xa65b, 0xa65b,
+ 0xa65d, 0xa65d,
+ 0xa65f, 0xa65f,
+ 0xa661, 0xa661,
+ 0xa663, 0xa663,
+ 0xa665, 0xa665,
+ 0xa667, 0xa667,
+ 0xa669, 0xa669,
+ 0xa66b, 0xa66b,
+ 0xa66d, 0xa66d,
+ 0xa681, 0xa681,
+ 0xa683, 0xa683,
+ 0xa685, 0xa685,
+ 0xa687, 0xa687,
+ 0xa689, 0xa689,
+ 0xa68b, 0xa68b,
+ 0xa68d, 0xa68d,
+ 0xa68f, 0xa68f,
+ 0xa691, 0xa691,
+ 0xa693, 0xa693,
+ 0xa695, 0xa695,
+ 0xa697, 0xa697,
+ 0xa699, 0xa699,
+ 0xa69b, 0xa69b,
+ 0xa723, 0xa723,
+ 0xa725, 0xa725,
+ 0xa727, 0xa727,
+ 0xa729, 0xa729,
+ 0xa72b, 0xa72b,
+ 0xa72d, 0xa72d,
+ 0xa72f, 0xa731,
+ 0xa733, 0xa733,
+ 0xa735, 0xa735,
+ 0xa737, 0xa737,
+ 0xa739, 0xa739,
+ 0xa73b, 0xa73b,
+ 0xa73d, 0xa73d,
+ 0xa73f, 0xa73f,
+ 0xa741, 0xa741,
+ 0xa743, 0xa743,
+ 0xa745, 0xa745,
+ 0xa747, 0xa747,
+ 0xa749, 0xa749,
+ 0xa74b, 0xa74b,
+ 0xa74d, 0xa74d,
+ 0xa74f, 0xa74f,
+ 0xa751, 0xa751,
+ 0xa753, 0xa753,
+ 0xa755, 0xa755,
+ 0xa757, 0xa757,
+ 0xa759, 0xa759,
+ 0xa75b, 0xa75b,
+ 0xa75d, 0xa75d,
+ 0xa75f, 0xa75f,
+ 0xa761, 0xa761,
+ 0xa763, 0xa763,
+ 0xa765, 0xa765,
+ 0xa767, 0xa767,
+ 0xa769, 0xa769,
+ 0xa76b, 0xa76b,
+ 0xa76d, 0xa76d,
+ 0xa76f, 0xa76f,
+ 0xa771, 0xa778,
+ 0xa77a, 0xa77a,
+ 0xa77c, 0xa77c,
+ 0xa77f, 0xa77f,
+ 0xa781, 0xa781,
+ 0xa783, 0xa783,
+ 0xa785, 0xa785,
+ 0xa787, 0xa787,
+ 0xa78c, 0xa78c,
+ 0xa78e, 0xa78e,
+ 0xa791, 0xa791,
+ 0xa793, 0xa795,
+ 0xa797, 0xa797,
+ 0xa799, 0xa799,
+ 0xa79b, 0xa79b,
+ 0xa79d, 0xa79d,
+ 0xa79f, 0xa79f,
+ 0xa7a1, 0xa7a1,
+ 0xa7a3, 0xa7a3,
+ 0xa7a5, 0xa7a5,
+ 0xa7a7, 0xa7a7,
+ 0xa7a9, 0xa7a9,
+ 0xa7af, 0xa7af,
+ 0xa7b5, 0xa7b5,
+ 0xa7b7, 0xa7b7,
+ 0xa7b9, 0xa7b9,
+ 0xa7bb, 0xa7bb,
+ 0xa7bd, 0xa7bd,
+ 0xa7bf, 0xa7bf,
+ 0xa7c3, 0xa7c3,
+ 0xa7fa, 0xa7fa,
+ 0xab30, 0xab5a,
+ 0xab60, 0xab67,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff41, 0xff5a,
+ 0x10428, 0x1044f,
+ 0x104d8, 0x104fb,
+ 0x10cc0, 0x10cf2,
+ 0x118c0, 0x118df,
+ 0x16e60, 0x16e7f,
+ 0x1d41a, 0x1d433,
+ 0x1d44e, 0x1d454,
+ 0x1d456, 0x1d467,
+ 0x1d482, 0x1d49b,
+ 0x1d4b6, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d4cf,
+ 0x1d4ea, 0x1d503,
+ 0x1d51e, 0x1d537,
+ 0x1d552, 0x1d56b,
+ 0x1d586, 0x1d59f,
+ 0x1d5ba, 0x1d5d3,
+ 0x1d5ee, 0x1d607,
+ 0x1d622, 0x1d63b,
+ 0x1d656, 0x1d66f,
+ 0x1d68a, 0x1d6a5,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6e1,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d71b,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d755,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d78f,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7c9,
+ 0x1d7cb, 0x1d7cb,
+ 0x1e922, 0x1e943,
+}; /* CR_Ll */
+
+/* 'Lm': General Category */
+static const OnigCodePoint CR_Lm[] = {
+ 60,
+ 0x02b0, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0374, 0x0374,
+ 0x037a, 0x037a,
+ 0x0559, 0x0559,
+ 0x0640, 0x0640,
+ 0x06e5, 0x06e6,
+ 0x07f4, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x081a, 0x081a,
+ 0x0824, 0x0824,
+ 0x0828, 0x0828,
+ 0x0971, 0x0971,
+ 0x0e46, 0x0e46,
+ 0x0ec6, 0x0ec6,
+ 0x10fc, 0x10fc,
+ 0x17d7, 0x17d7,
+ 0x1843, 0x1843,
+ 0x1aa7, 0x1aa7,
+ 0x1c78, 0x1c7d,
+ 0x1d2c, 0x1d6a,
+ 0x1d78, 0x1d78,
+ 0x1d9b, 0x1dbf,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2c7c, 0x2c7d,
+ 0x2d6f, 0x2d6f,
+ 0x2e2f, 0x2e2f,
+ 0x3005, 0x3005,
+ 0x3031, 0x3035,
+ 0x303b, 0x303b,
+ 0x309d, 0x309e,
+ 0x30fc, 0x30fe,
+ 0xa015, 0xa015,
+ 0xa4f8, 0xa4fd,
+ 0xa60c, 0xa60c,
+ 0xa67f, 0xa67f,
+ 0xa69c, 0xa69d,
+ 0xa717, 0xa71f,
+ 0xa770, 0xa770,
+ 0xa788, 0xa788,
+ 0xa7f8, 0xa7f9,
+ 0xa9cf, 0xa9cf,
+ 0xa9e6, 0xa9e6,
+ 0xaa70, 0xaa70,
+ 0xaadd, 0xaadd,
+ 0xaaf3, 0xaaf4,
+ 0xab5c, 0xab5f,
+ 0xff70, 0xff70,
+ 0xff9e, 0xff9f,
+ 0x16b40, 0x16b43,
+ 0x16f93, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x1e137, 0x1e13d,
+ 0x1e94b, 0x1e94b,
+}; /* CR_Lm */
+
+/* 'Lo': General Category */
+static const OnigCodePoint CR_Lo[] = {
+ 476,
+ 0x00aa, 0x00aa,
+ 0x00ba, 0x00ba,
+ 0x01bb, 0x01bb,
+ 0x01c0, 0x01c3,
+ 0x0294, 0x0294,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0620, 0x063f,
+ 0x0641, 0x064a,
+ 0x066e, 0x066f,
+ 0x0671, 0x06d3,
+ 0x06d5, 0x06d5,
+ 0x06ee, 0x06ef,
+ 0x06fa, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x0710,
+ 0x0712, 0x072f,
+ 0x074d, 0x07a5,
+ 0x07b1, 0x07b1,
+ 0x07ca, 0x07ea,
+ 0x0800, 0x0815,
+ 0x0840, 0x0858,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x0904, 0x0939,
+ 0x093d, 0x093d,
+ 0x0950, 0x0950,
+ 0x0958, 0x0961,
+ 0x0972, 0x0980,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09bd,
+ 0x09ce, 0x09ce,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e1,
+ 0x09f0, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a72, 0x0a74,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0abd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae1,
+ 0x0af9, 0x0af9,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b3d,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b71, 0x0b71,
+ 0x0b83, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bd0, 0x0bd0,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c3d,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c61,
+ 0x0c80, 0x0c80,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cbd,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0cf1, 0x0cf2,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d3d,
+ 0x0d4e, 0x0d4e,
+ 0x0d54, 0x0d56,
+ 0x0d5f, 0x0d61,
+ 0x0d7a, 0x0d7f,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0e01, 0x0e30,
+ 0x0e32, 0x0e33,
+ 0x0e40, 0x0e45,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0eb0,
+ 0x0eb2, 0x0eb3,
+ 0x0ebd, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f88, 0x0f8c,
+ 0x1000, 0x102a,
+ 0x103f, 0x103f,
+ 0x1050, 0x1055,
+ 0x105a, 0x105d,
+ 0x1061, 0x1061,
+ 0x1065, 0x1066,
+ 0x106e, 0x1070,
+ 0x1075, 0x1081,
+ 0x108e, 0x108e,
+ 0x1100, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16f1, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1711,
+ 0x1720, 0x1731,
+ 0x1740, 0x1751,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1780, 0x17b3,
+ 0x17dc, 0x17dc,
+ 0x1820, 0x1842,
+ 0x1844, 0x1878,
+ 0x1880, 0x1884,
+ 0x1887, 0x18a8,
+ 0x18aa, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x1a00, 0x1a16,
+ 0x1a20, 0x1a54,
+ 0x1b05, 0x1b33,
+ 0x1b45, 0x1b4b,
+ 0x1b83, 0x1ba0,
+ 0x1bae, 0x1baf,
+ 0x1bba, 0x1be5,
+ 0x1c00, 0x1c23,
+ 0x1c4d, 0x1c4f,
+ 0x1c5a, 0x1c77,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf6,
+ 0x1cfa, 0x1cfa,
+ 0x2135, 0x2138,
+ 0x2d30, 0x2d67,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x3006, 0x3006,
+ 0x303c, 0x303c,
+ 0x3041, 0x3096,
+ 0x309f, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30ff, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa014,
+ 0xa016, 0xa48c,
+ 0xa4d0, 0xa4f7,
+ 0xa500, 0xa60b,
+ 0xa610, 0xa61f,
+ 0xa62a, 0xa62b,
+ 0xa66e, 0xa66e,
+ 0xa6a0, 0xa6e5,
+ 0xa78f, 0xa78f,
+ 0xa7f7, 0xa7f7,
+ 0xa7fb, 0xa801,
+ 0xa803, 0xa805,
+ 0xa807, 0xa80a,
+ 0xa80c, 0xa822,
+ 0xa840, 0xa873,
+ 0xa882, 0xa8b3,
+ 0xa8f2, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa8fe,
+ 0xa90a, 0xa925,
+ 0xa930, 0xa946,
+ 0xa960, 0xa97c,
+ 0xa984, 0xa9b2,
+ 0xa9e0, 0xa9e4,
+ 0xa9e7, 0xa9ef,
+ 0xa9fa, 0xa9fe,
+ 0xaa00, 0xaa28,
+ 0xaa40, 0xaa42,
+ 0xaa44, 0xaa4b,
+ 0xaa60, 0xaa6f,
+ 0xaa71, 0xaa76,
+ 0xaa7a, 0xaa7a,
+ 0xaa7e, 0xaaaf,
+ 0xaab1, 0xaab1,
+ 0xaab5, 0xaab6,
+ 0xaab9, 0xaabd,
+ 0xaac0, 0xaac0,
+ 0xaac2, 0xaac2,
+ 0xaadb, 0xaadc,
+ 0xaae0, 0xaaea,
+ 0xaaf2, 0xaaf2,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xabc0, 0xabe2,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb1d, 0xfb1d,
+ 0xfb1f, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff66, 0xff6f,
+ 0xff71, 0xff9d,
+ 0xffa0, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x10340,
+ 0x10342, 0x10349,
+ 0x10350, 0x10375,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x10450, 0x1049d,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a00,
+ 0x10a10, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae4,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10d00, 0x10d23,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f45,
+ 0x10fe0, 0x10ff6,
+ 0x11003, 0x11037,
+ 0x11083, 0x110af,
+ 0x110d0, 0x110e8,
+ 0x11103, 0x11126,
+ 0x11144, 0x11144,
+ 0x11150, 0x11172,
+ 0x11176, 0x11176,
+ 0x11183, 0x111b2,
+ 0x111c1, 0x111c4,
+ 0x111da, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x1122b,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112de,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133d, 0x1133d,
+ 0x11350, 0x11350,
+ 0x1135d, 0x11361,
+ 0x11400, 0x11434,
+ 0x11447, 0x1144a,
+ 0x1145f, 0x1145f,
+ 0x11480, 0x114af,
+ 0x114c4, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x11580, 0x115ae,
+ 0x115d8, 0x115db,
+ 0x11600, 0x1162f,
+ 0x11644, 0x11644,
+ 0x11680, 0x116aa,
+ 0x116b8, 0x116b8,
+ 0x11700, 0x1171a,
+ 0x11800, 0x1182b,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d0,
+ 0x119e1, 0x119e1,
+ 0x119e3, 0x119e3,
+ 0x11a00, 0x11a00,
+ 0x11a0b, 0x11a32,
+ 0x11a3a, 0x11a3a,
+ 0x11a50, 0x11a50,
+ 0x11a5c, 0x11a89,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c2e,
+ 0x11c40, 0x11c40,
+ 0x11c72, 0x11c8f,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d30,
+ 0x11d46, 0x11d46,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d89,
+ 0x11d98, 0x11d98,
+ 0x11ee0, 0x11ef2,
+ 0x12000, 0x12399,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16ad0, 0x16aed,
+ 0x16b00, 0x16b2f,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16f00, 0x16f4a,
+ 0x16f50, 0x16f50,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1e100, 0x1e12c,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2eb,
+ 0x1e800, 0x1e8c4,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_Lo */
+
+/* 'Lt': General Category */
+static const OnigCodePoint CR_Lt[] = {
+ 10,
+ 0x01c5, 0x01c5,
+ 0x01c8, 0x01c8,
+ 0x01cb, 0x01cb,
+ 0x01f2, 0x01f2,
+ 0x1f88, 0x1f8f,
+ 0x1f98, 0x1f9f,
+ 0x1fa8, 0x1faf,
+ 0x1fbc, 0x1fbc,
+ 0x1fcc, 0x1fcc,
+ 0x1ffc, 0x1ffc,
+}; /* CR_Lt */
+
+/* 'Lu': General Category */
+static const OnigCodePoint CR_Lu[] = {
+ 636,
+ 0x0041, 0x005a,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00de,
+ 0x0100, 0x0100,
+ 0x0102, 0x0102,
+ 0x0104, 0x0104,
+ 0x0106, 0x0106,
+ 0x0108, 0x0108,
+ 0x010a, 0x010a,
+ 0x010c, 0x010c,
+ 0x010e, 0x010e,
+ 0x0110, 0x0110,
+ 0x0112, 0x0112,
+ 0x0114, 0x0114,
+ 0x0116, 0x0116,
+ 0x0118, 0x0118,
+ 0x011a, 0x011a,
+ 0x011c, 0x011c,
+ 0x011e, 0x011e,
+ 0x0120, 0x0120,
+ 0x0122, 0x0122,
+ 0x0124, 0x0124,
+ 0x0126, 0x0126,
+ 0x0128, 0x0128,
+ 0x012a, 0x012a,
+ 0x012c, 0x012c,
+ 0x012e, 0x012e,
+ 0x0130, 0x0130,
+ 0x0132, 0x0132,
+ 0x0134, 0x0134,
+ 0x0136, 0x0136,
+ 0x0139, 0x0139,
+ 0x013b, 0x013b,
+ 0x013d, 0x013d,
+ 0x013f, 0x013f,
+ 0x0141, 0x0141,
+ 0x0143, 0x0143,
+ 0x0145, 0x0145,
+ 0x0147, 0x0147,
+ 0x014a, 0x014a,
+ 0x014c, 0x014c,
+ 0x014e, 0x014e,
+ 0x0150, 0x0150,
+ 0x0152, 0x0152,
+ 0x0154, 0x0154,
+ 0x0156, 0x0156,
+ 0x0158, 0x0158,
+ 0x015a, 0x015a,
+ 0x015c, 0x015c,
+ 0x015e, 0x015e,
+ 0x0160, 0x0160,
+ 0x0162, 0x0162,
+ 0x0164, 0x0164,
+ 0x0166, 0x0166,
+ 0x0168, 0x0168,
+ 0x016a, 0x016a,
+ 0x016c, 0x016c,
+ 0x016e, 0x016e,
+ 0x0170, 0x0170,
+ 0x0172, 0x0172,
+ 0x0174, 0x0174,
+ 0x0176, 0x0176,
+ 0x0178, 0x0179,
+ 0x017b, 0x017b,
+ 0x017d, 0x017d,
+ 0x0181, 0x0182,
+ 0x0184, 0x0184,
+ 0x0186, 0x0187,
+ 0x0189, 0x018b,
+ 0x018e, 0x0191,
+ 0x0193, 0x0194,
+ 0x0196, 0x0198,
+ 0x019c, 0x019d,
+ 0x019f, 0x01a0,
+ 0x01a2, 0x01a2,
+ 0x01a4, 0x01a4,
+ 0x01a6, 0x01a7,
+ 0x01a9, 0x01a9,
+ 0x01ac, 0x01ac,
+ 0x01ae, 0x01af,
+ 0x01b1, 0x01b3,
+ 0x01b5, 0x01b5,
+ 0x01b7, 0x01b8,
+ 0x01bc, 0x01bc,
+ 0x01c4, 0x01c4,
+ 0x01c7, 0x01c7,
+ 0x01ca, 0x01ca,
+ 0x01cd, 0x01cd,
+ 0x01cf, 0x01cf,
+ 0x01d1, 0x01d1,
+ 0x01d3, 0x01d3,
+ 0x01d5, 0x01d5,
+ 0x01d7, 0x01d7,
+ 0x01d9, 0x01d9,
+ 0x01db, 0x01db,
+ 0x01de, 0x01de,
+ 0x01e0, 0x01e0,
+ 0x01e2, 0x01e2,
+ 0x01e4, 0x01e4,
+ 0x01e6, 0x01e6,
+ 0x01e8, 0x01e8,
+ 0x01ea, 0x01ea,
+ 0x01ec, 0x01ec,
+ 0x01ee, 0x01ee,
+ 0x01f1, 0x01f1,
+ 0x01f4, 0x01f4,
+ 0x01f6, 0x01f8,
+ 0x01fa, 0x01fa,
+ 0x01fc, 0x01fc,
+ 0x01fe, 0x01fe,
+ 0x0200, 0x0200,
+ 0x0202, 0x0202,
+ 0x0204, 0x0204,
+ 0x0206, 0x0206,
+ 0x0208, 0x0208,
+ 0x020a, 0x020a,
+ 0x020c, 0x020c,
+ 0x020e, 0x020e,
+ 0x0210, 0x0210,
+ 0x0212, 0x0212,
+ 0x0214, 0x0214,
+ 0x0216, 0x0216,
+ 0x0218, 0x0218,
+ 0x021a, 0x021a,
+ 0x021c, 0x021c,
+ 0x021e, 0x021e,
+ 0x0220, 0x0220,
+ 0x0222, 0x0222,
+ 0x0224, 0x0224,
+ 0x0226, 0x0226,
+ 0x0228, 0x0228,
+ 0x022a, 0x022a,
+ 0x022c, 0x022c,
+ 0x022e, 0x022e,
+ 0x0230, 0x0230,
+ 0x0232, 0x0232,
+ 0x023a, 0x023b,
+ 0x023d, 0x023e,
+ 0x0241, 0x0241,
+ 0x0243, 0x0246,
+ 0x0248, 0x0248,
+ 0x024a, 0x024a,
+ 0x024c, 0x024c,
+ 0x024e, 0x024e,
+ 0x0370, 0x0370,
+ 0x0372, 0x0372,
+ 0x0376, 0x0376,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x038f,
+ 0x0391, 0x03a1,
+ 0x03a3, 0x03ab,
+ 0x03cf, 0x03cf,
+ 0x03d2, 0x03d4,
+ 0x03d8, 0x03d8,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03e2,
+ 0x03e4, 0x03e4,
+ 0x03e6, 0x03e6,
+ 0x03e8, 0x03e8,
+ 0x03ea, 0x03ea,
+ 0x03ec, 0x03ec,
+ 0x03ee, 0x03ee,
+ 0x03f4, 0x03f4,
+ 0x03f7, 0x03f7,
+ 0x03f9, 0x03fa,
+ 0x03fd, 0x042f,
+ 0x0460, 0x0460,
+ 0x0462, 0x0462,
+ 0x0464, 0x0464,
+ 0x0466, 0x0466,
+ 0x0468, 0x0468,
+ 0x046a, 0x046a,
+ 0x046c, 0x046c,
+ 0x046e, 0x046e,
+ 0x0470, 0x0470,
+ 0x0472, 0x0472,
+ 0x0474, 0x0474,
+ 0x0476, 0x0476,
+ 0x0478, 0x0478,
+ 0x047a, 0x047a,
+ 0x047c, 0x047c,
+ 0x047e, 0x047e,
+ 0x0480, 0x0480,
+ 0x048a, 0x048a,
+ 0x048c, 0x048c,
+ 0x048e, 0x048e,
+ 0x0490, 0x0490,
+ 0x0492, 0x0492,
+ 0x0494, 0x0494,
+ 0x0496, 0x0496,
+ 0x0498, 0x0498,
+ 0x049a, 0x049a,
+ 0x049c, 0x049c,
+ 0x049e, 0x049e,
+ 0x04a0, 0x04a0,
+ 0x04a2, 0x04a2,
+ 0x04a4, 0x04a4,
+ 0x04a6, 0x04a6,
+ 0x04a8, 0x04a8,
+ 0x04aa, 0x04aa,
+ 0x04ac, 0x04ac,
+ 0x04ae, 0x04ae,
+ 0x04b0, 0x04b0,
+ 0x04b2, 0x04b2,
+ 0x04b4, 0x04b4,
+ 0x04b6, 0x04b6,
+ 0x04b8, 0x04b8,
+ 0x04ba, 0x04ba,
+ 0x04bc, 0x04bc,
+ 0x04be, 0x04be,
+ 0x04c0, 0x04c1,
+ 0x04c3, 0x04c3,
+ 0x04c5, 0x04c5,
+ 0x04c7, 0x04c7,
+ 0x04c9, 0x04c9,
+ 0x04cb, 0x04cb,
+ 0x04cd, 0x04cd,
+ 0x04d0, 0x04d0,
+ 0x04d2, 0x04d2,
+ 0x04d4, 0x04d4,
+ 0x04d6, 0x04d6,
+ 0x04d8, 0x04d8,
+ 0x04da, 0x04da,
+ 0x04dc, 0x04dc,
+ 0x04de, 0x04de,
+ 0x04e0, 0x04e0,
+ 0x04e2, 0x04e2,
+ 0x04e4, 0x04e4,
+ 0x04e6, 0x04e6,
+ 0x04e8, 0x04e8,
+ 0x04ea, 0x04ea,
+ 0x04ec, 0x04ec,
+ 0x04ee, 0x04ee,
+ 0x04f0, 0x04f0,
+ 0x04f2, 0x04f2,
+ 0x04f4, 0x04f4,
+ 0x04f6, 0x04f6,
+ 0x04f8, 0x04f8,
+ 0x04fa, 0x04fa,
+ 0x04fc, 0x04fc,
+ 0x04fe, 0x04fe,
+ 0x0500, 0x0500,
+ 0x0502, 0x0502,
+ 0x0504, 0x0504,
+ 0x0506, 0x0506,
+ 0x0508, 0x0508,
+ 0x050a, 0x050a,
+ 0x050c, 0x050c,
+ 0x050e, 0x050e,
+ 0x0510, 0x0510,
+ 0x0512, 0x0512,
+ 0x0514, 0x0514,
+ 0x0516, 0x0516,
+ 0x0518, 0x0518,
+ 0x051a, 0x051a,
+ 0x051c, 0x051c,
+ 0x051e, 0x051e,
+ 0x0520, 0x0520,
+ 0x0522, 0x0522,
+ 0x0524, 0x0524,
+ 0x0526, 0x0526,
+ 0x0528, 0x0528,
+ 0x052a, 0x052a,
+ 0x052c, 0x052c,
+ 0x052e, 0x052e,
+ 0x0531, 0x0556,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x13a0, 0x13f5,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1e00, 0x1e00,
+ 0x1e02, 0x1e02,
+ 0x1e04, 0x1e04,
+ 0x1e06, 0x1e06,
+ 0x1e08, 0x1e08,
+ 0x1e0a, 0x1e0a,
+ 0x1e0c, 0x1e0c,
+ 0x1e0e, 0x1e0e,
+ 0x1e10, 0x1e10,
+ 0x1e12, 0x1e12,
+ 0x1e14, 0x1e14,
+ 0x1e16, 0x1e16,
+ 0x1e18, 0x1e18,
+ 0x1e1a, 0x1e1a,
+ 0x1e1c, 0x1e1c,
+ 0x1e1e, 0x1e1e,
+ 0x1e20, 0x1e20,
+ 0x1e22, 0x1e22,
+ 0x1e24, 0x1e24,
+ 0x1e26, 0x1e26,
+ 0x1e28, 0x1e28,
+ 0x1e2a, 0x1e2a,
+ 0x1e2c, 0x1e2c,
+ 0x1e2e, 0x1e2e,
+ 0x1e30, 0x1e30,
+ 0x1e32, 0x1e32,
+ 0x1e34, 0x1e34,
+ 0x1e36, 0x1e36,
+ 0x1e38, 0x1e38,
+ 0x1e3a, 0x1e3a,
+ 0x1e3c, 0x1e3c,
+ 0x1e3e, 0x1e3e,
+ 0x1e40, 0x1e40,
+ 0x1e42, 0x1e42,
+ 0x1e44, 0x1e44,
+ 0x1e46, 0x1e46,
+ 0x1e48, 0x1e48,
+ 0x1e4a, 0x1e4a,
+ 0x1e4c, 0x1e4c,
+ 0x1e4e, 0x1e4e,
+ 0x1e50, 0x1e50,
+ 0x1e52, 0x1e52,
+ 0x1e54, 0x1e54,
+ 0x1e56, 0x1e56,
+ 0x1e58, 0x1e58,
+ 0x1e5a, 0x1e5a,
+ 0x1e5c, 0x1e5c,
+ 0x1e5e, 0x1e5e,
+ 0x1e60, 0x1e60,
+ 0x1e62, 0x1e62,
+ 0x1e64, 0x1e64,
+ 0x1e66, 0x1e66,
+ 0x1e68, 0x1e68,
+ 0x1e6a, 0x1e6a,
+ 0x1e6c, 0x1e6c,
+ 0x1e6e, 0x1e6e,
+ 0x1e70, 0x1e70,
+ 0x1e72, 0x1e72,
+ 0x1e74, 0x1e74,
+ 0x1e76, 0x1e76,
+ 0x1e78, 0x1e78,
+ 0x1e7a, 0x1e7a,
+ 0x1e7c, 0x1e7c,
+ 0x1e7e, 0x1e7e,
+ 0x1e80, 0x1e80,
+ 0x1e82, 0x1e82,
+ 0x1e84, 0x1e84,
+ 0x1e86, 0x1e86,
+ 0x1e88, 0x1e88,
+ 0x1e8a, 0x1e8a,
+ 0x1e8c, 0x1e8c,
+ 0x1e8e, 0x1e8e,
+ 0x1e90, 0x1e90,
+ 0x1e92, 0x1e92,
+ 0x1e94, 0x1e94,
+ 0x1e9e, 0x1e9e,
+ 0x1ea0, 0x1ea0,
+ 0x1ea2, 0x1ea2,
+ 0x1ea4, 0x1ea4,
+ 0x1ea6, 0x1ea6,
+ 0x1ea8, 0x1ea8,
+ 0x1eaa, 0x1eaa,
+ 0x1eac, 0x1eac,
+ 0x1eae, 0x1eae,
+ 0x1eb0, 0x1eb0,
+ 0x1eb2, 0x1eb2,
+ 0x1eb4, 0x1eb4,
+ 0x1eb6, 0x1eb6,
+ 0x1eb8, 0x1eb8,
+ 0x1eba, 0x1eba,
+ 0x1ebc, 0x1ebc,
+ 0x1ebe, 0x1ebe,
+ 0x1ec0, 0x1ec0,
+ 0x1ec2, 0x1ec2,
+ 0x1ec4, 0x1ec4,
+ 0x1ec6, 0x1ec6,
+ 0x1ec8, 0x1ec8,
+ 0x1eca, 0x1eca,
+ 0x1ecc, 0x1ecc,
+ 0x1ece, 0x1ece,
+ 0x1ed0, 0x1ed0,
+ 0x1ed2, 0x1ed2,
+ 0x1ed4, 0x1ed4,
+ 0x1ed6, 0x1ed6,
+ 0x1ed8, 0x1ed8,
+ 0x1eda, 0x1eda,
+ 0x1edc, 0x1edc,
+ 0x1ede, 0x1ede,
+ 0x1ee0, 0x1ee0,
+ 0x1ee2, 0x1ee2,
+ 0x1ee4, 0x1ee4,
+ 0x1ee6, 0x1ee6,
+ 0x1ee8, 0x1ee8,
+ 0x1eea, 0x1eea,
+ 0x1eec, 0x1eec,
+ 0x1eee, 0x1eee,
+ 0x1ef0, 0x1ef0,
+ 0x1ef2, 0x1ef2,
+ 0x1ef4, 0x1ef4,
+ 0x1ef6, 0x1ef6,
+ 0x1ef8, 0x1ef8,
+ 0x1efa, 0x1efa,
+ 0x1efc, 0x1efc,
+ 0x1efe, 0x1efe,
+ 0x1f08, 0x1f0f,
+ 0x1f18, 0x1f1d,
+ 0x1f28, 0x1f2f,
+ 0x1f38, 0x1f3f,
+ 0x1f48, 0x1f4d,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f5f,
+ 0x1f68, 0x1f6f,
+ 0x1fb8, 0x1fbb,
+ 0x1fc8, 0x1fcb,
+ 0x1fd8, 0x1fdb,
+ 0x1fe8, 0x1fec,
+ 0x1ff8, 0x1ffb,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210b, 0x210d,
+ 0x2110, 0x2112,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x2130, 0x2133,
+ 0x213e, 0x213f,
+ 0x2145, 0x2145,
+ 0x2183, 0x2183,
+ 0x2c00, 0x2c2e,
+ 0x2c60, 0x2c60,
+ 0x2c62, 0x2c64,
+ 0x2c67, 0x2c67,
+ 0x2c69, 0x2c69,
+ 0x2c6b, 0x2c6b,
+ 0x2c6d, 0x2c70,
+ 0x2c72, 0x2c72,
+ 0x2c75, 0x2c75,
+ 0x2c7e, 0x2c80,
+ 0x2c82, 0x2c82,
+ 0x2c84, 0x2c84,
+ 0x2c86, 0x2c86,
+ 0x2c88, 0x2c88,
+ 0x2c8a, 0x2c8a,
+ 0x2c8c, 0x2c8c,
+ 0x2c8e, 0x2c8e,
+ 0x2c90, 0x2c90,
+ 0x2c92, 0x2c92,
+ 0x2c94, 0x2c94,
+ 0x2c96, 0x2c96,
+ 0x2c98, 0x2c98,
+ 0x2c9a, 0x2c9a,
+ 0x2c9c, 0x2c9c,
+ 0x2c9e, 0x2c9e,
+ 0x2ca0, 0x2ca0,
+ 0x2ca2, 0x2ca2,
+ 0x2ca4, 0x2ca4,
+ 0x2ca6, 0x2ca6,
+ 0x2ca8, 0x2ca8,
+ 0x2caa, 0x2caa,
+ 0x2cac, 0x2cac,
+ 0x2cae, 0x2cae,
+ 0x2cb0, 0x2cb0,
+ 0x2cb2, 0x2cb2,
+ 0x2cb4, 0x2cb4,
+ 0x2cb6, 0x2cb6,
+ 0x2cb8, 0x2cb8,
+ 0x2cba, 0x2cba,
+ 0x2cbc, 0x2cbc,
+ 0x2cbe, 0x2cbe,
+ 0x2cc0, 0x2cc0,
+ 0x2cc2, 0x2cc2,
+ 0x2cc4, 0x2cc4,
+ 0x2cc6, 0x2cc6,
+ 0x2cc8, 0x2cc8,
+ 0x2cca, 0x2cca,
+ 0x2ccc, 0x2ccc,
+ 0x2cce, 0x2cce,
+ 0x2cd0, 0x2cd0,
+ 0x2cd2, 0x2cd2,
+ 0x2cd4, 0x2cd4,
+ 0x2cd6, 0x2cd6,
+ 0x2cd8, 0x2cd8,
+ 0x2cda, 0x2cda,
+ 0x2cdc, 0x2cdc,
+ 0x2cde, 0x2cde,
+ 0x2ce0, 0x2ce0,
+ 0x2ce2, 0x2ce2,
+ 0x2ceb, 0x2ceb,
+ 0x2ced, 0x2ced,
+ 0x2cf2, 0x2cf2,
+ 0xa640, 0xa640,
+ 0xa642, 0xa642,
+ 0xa644, 0xa644,
+ 0xa646, 0xa646,
+ 0xa648, 0xa648,
+ 0xa64a, 0xa64a,
+ 0xa64c, 0xa64c,
+ 0xa64e, 0xa64e,
+ 0xa650, 0xa650,
+ 0xa652, 0xa652,
+ 0xa654, 0xa654,
+ 0xa656, 0xa656,
+ 0xa658, 0xa658,
+ 0xa65a, 0xa65a,
+ 0xa65c, 0xa65c,
+ 0xa65e, 0xa65e,
+ 0xa660, 0xa660,
+ 0xa662, 0xa662,
+ 0xa664, 0xa664,
+ 0xa666, 0xa666,
+ 0xa668, 0xa668,
+ 0xa66a, 0xa66a,
+ 0xa66c, 0xa66c,
+ 0xa680, 0xa680,
+ 0xa682, 0xa682,
+ 0xa684, 0xa684,
+ 0xa686, 0xa686,
+ 0xa688, 0xa688,
+ 0xa68a, 0xa68a,
+ 0xa68c, 0xa68c,
+ 0xa68e, 0xa68e,
+ 0xa690, 0xa690,
+ 0xa692, 0xa692,
+ 0xa694, 0xa694,
+ 0xa696, 0xa696,
+ 0xa698, 0xa698,
+ 0xa69a, 0xa69a,
+ 0xa722, 0xa722,
+ 0xa724, 0xa724,
+ 0xa726, 0xa726,
+ 0xa728, 0xa728,
+ 0xa72a, 0xa72a,
+ 0xa72c, 0xa72c,
+ 0xa72e, 0xa72e,
+ 0xa732, 0xa732,
+ 0xa734, 0xa734,
+ 0xa736, 0xa736,
+ 0xa738, 0xa738,
+ 0xa73a, 0xa73a,
+ 0xa73c, 0xa73c,
+ 0xa73e, 0xa73e,
+ 0xa740, 0xa740,
+ 0xa742, 0xa742,
+ 0xa744, 0xa744,
+ 0xa746, 0xa746,
+ 0xa748, 0xa748,
+ 0xa74a, 0xa74a,
+ 0xa74c, 0xa74c,
+ 0xa74e, 0xa74e,
+ 0xa750, 0xa750,
+ 0xa752, 0xa752,
+ 0xa754, 0xa754,
+ 0xa756, 0xa756,
+ 0xa758, 0xa758,
+ 0xa75a, 0xa75a,
+ 0xa75c, 0xa75c,
+ 0xa75e, 0xa75e,
+ 0xa760, 0xa760,
+ 0xa762, 0xa762,
+ 0xa764, 0xa764,
+ 0xa766, 0xa766,
+ 0xa768, 0xa768,
+ 0xa76a, 0xa76a,
+ 0xa76c, 0xa76c,
+ 0xa76e, 0xa76e,
+ 0xa779, 0xa779,
+ 0xa77b, 0xa77b,
+ 0xa77d, 0xa77e,
+ 0xa780, 0xa780,
+ 0xa782, 0xa782,
+ 0xa784, 0xa784,
+ 0xa786, 0xa786,
+ 0xa78b, 0xa78b,
+ 0xa78d, 0xa78d,
+ 0xa790, 0xa790,
+ 0xa792, 0xa792,
+ 0xa796, 0xa796,
+ 0xa798, 0xa798,
+ 0xa79a, 0xa79a,
+ 0xa79c, 0xa79c,
+ 0xa79e, 0xa79e,
+ 0xa7a0, 0xa7a0,
+ 0xa7a2, 0xa7a2,
+ 0xa7a4, 0xa7a4,
+ 0xa7a6, 0xa7a6,
+ 0xa7a8, 0xa7a8,
+ 0xa7aa, 0xa7ae,
+ 0xa7b0, 0xa7b4,
+ 0xa7b6, 0xa7b6,
+ 0xa7b8, 0xa7b8,
+ 0xa7ba, 0xa7ba,
+ 0xa7bc, 0xa7bc,
+ 0xa7be, 0xa7be,
+ 0xa7c2, 0xa7c2,
+ 0xa7c4, 0xa7c6,
+ 0xff21, 0xff3a,
+ 0x10400, 0x10427,
+ 0x104b0, 0x104d3,
+ 0x10c80, 0x10cb2,
+ 0x118a0, 0x118bf,
+ 0x16e40, 0x16e5f,
+ 0x1d400, 0x1d419,
+ 0x1d434, 0x1d44d,
+ 0x1d468, 0x1d481,
+ 0x1d49c, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b5,
+ 0x1d4d0, 0x1d4e9,
+ 0x1d504, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d538, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d56c, 0x1d585,
+ 0x1d5a0, 0x1d5b9,
+ 0x1d5d4, 0x1d5ed,
+ 0x1d608, 0x1d621,
+ 0x1d63c, 0x1d655,
+ 0x1d670, 0x1d689,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6e2, 0x1d6fa,
+ 0x1d71c, 0x1d734,
+ 0x1d756, 0x1d76e,
+ 0x1d790, 0x1d7a8,
+ 0x1d7ca, 0x1d7ca,
+ 0x1e900, 0x1e921,
+}; /* CR_Lu */
+
+/* 'M': Major Category */
+static const OnigCodePoint CR_M[] = {
+ 280,
+ 0x0300, 0x036f,
+ 0x0483, 0x0489,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x0610, 0x061a,
+ 0x064b, 0x065f,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dc,
+ 0x06df, 0x06e4,
+ 0x06e7, 0x06e8,
+ 0x06ea, 0x06ed,
+ 0x0711, 0x0711,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x07eb, 0x07f3,
+ 0x07fd, 0x07fd,
+ 0x0816, 0x0819,
+ 0x081b, 0x0823,
+ 0x0825, 0x0827,
+ 0x0829, 0x082d,
+ 0x0859, 0x085b,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x0903,
+ 0x093a, 0x093c,
+ 0x093e, 0x094f,
+ 0x0951, 0x0957,
+ 0x0962, 0x0963,
+ 0x0981, 0x0983,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09e2, 0x09e3,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a70, 0x0a71,
+ 0x0a75, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0abc, 0x0abc,
+ 0x0abe, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ae2, 0x0ae3,
+ 0x0afa, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b3c, 0x0b3c,
+ 0x0b3e, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b62, 0x0b63,
+ 0x0b82, 0x0b82,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0c00, 0x0c04,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c62, 0x0c63,
+ 0x0c81, 0x0c83,
+ 0x0cbc, 0x0cbc,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0ce2, 0x0ce3,
+ 0x0d00, 0x0d03,
+ 0x0d3b, 0x0d3c,
+ 0x0d3e, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d62, 0x0d63,
+ 0x0d82, 0x0d83,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df3,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e47, 0x0e4e,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0ebc,
+ 0x0ec8, 0x0ecd,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f3e, 0x0f3f,
+ 0x0f71, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0f8d, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x102b, 0x103e,
+ 0x1056, 0x1059,
+ 0x105e, 0x1060,
+ 0x1062, 0x1064,
+ 0x1067, 0x106d,
+ 0x1071, 0x1074,
+ 0x1082, 0x108d,
+ 0x108f, 0x108f,
+ 0x109a, 0x109d,
+ 0x135d, 0x135f,
+ 0x1712, 0x1714,
+ 0x1732, 0x1734,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b4, 0x17d3,
+ 0x17dd, 0x17dd,
+ 0x180b, 0x180d,
+ 0x1885, 0x1886,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1a17, 0x1a1b,
+ 0x1a55, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a7f,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b04,
+ 0x1b34, 0x1b44,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1b82,
+ 0x1ba1, 0x1bad,
+ 0x1be6, 0x1bf3,
+ 0x1c24, 0x1c37,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1ce8,
+ 0x1ced, 0x1ced,
+ 0x1cf4, 0x1cf4,
+ 0x1cf7, 0x1cf9,
+ 0x1dc0, 0x1df9,
+ 0x1dfb, 0x1dff,
+ 0x20d0, 0x20f0,
+ 0x2cef, 0x2cf1,
+ 0x2d7f, 0x2d7f,
+ 0x2de0, 0x2dff,
+ 0x302a, 0x302f,
+ 0x3099, 0x309a,
+ 0xa66f, 0xa672,
+ 0xa674, 0xa67d,
+ 0xa69e, 0xa69f,
+ 0xa6f0, 0xa6f1,
+ 0xa802, 0xa802,
+ 0xa806, 0xa806,
+ 0xa80b, 0xa80b,
+ 0xa823, 0xa827,
+ 0xa880, 0xa881,
+ 0xa8b4, 0xa8c5,
+ 0xa8e0, 0xa8f1,
+ 0xa8ff, 0xa8ff,
+ 0xa926, 0xa92d,
+ 0xa947, 0xa953,
+ 0xa980, 0xa983,
+ 0xa9b3, 0xa9c0,
+ 0xa9e5, 0xa9e5,
+ 0xaa29, 0xaa36,
+ 0xaa43, 0xaa43,
+ 0xaa4c, 0xaa4d,
+ 0xaa7b, 0xaa7d,
+ 0xaab0, 0xaab0,
+ 0xaab2, 0xaab4,
+ 0xaab7, 0xaab8,
+ 0xaabe, 0xaabf,
+ 0xaac1, 0xaac1,
+ 0xaaeb, 0xaaef,
+ 0xaaf5, 0xaaf6,
+ 0xabe3, 0xabea,
+ 0xabec, 0xabed,
+ 0xfb1e, 0xfb1e,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2f,
+ 0x101fd, 0x101fd,
+ 0x102e0, 0x102e0,
+ 0x10376, 0x1037a,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10ae5, 0x10ae6,
+ 0x10d24, 0x10d27,
+ 0x10f46, 0x10f50,
+ 0x11000, 0x11002,
+ 0x11038, 0x11046,
+ 0x1107f, 0x11082,
+ 0x110b0, 0x110ba,
+ 0x11100, 0x11102,
+ 0x11127, 0x11134,
+ 0x11145, 0x11146,
+ 0x11173, 0x11173,
+ 0x11180, 0x11182,
+ 0x111b3, 0x111c0,
+ 0x111c9, 0x111cc,
+ 0x1122c, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x112df, 0x112ea,
+ 0x11300, 0x11303,
+ 0x1133b, 0x1133c,
+ 0x1133e, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11357, 0x11357,
+ 0x11362, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11435, 0x11446,
+ 0x1145e, 0x1145e,
+ 0x114b0, 0x114c3,
+ 0x115af, 0x115b5,
+ 0x115b8, 0x115c0,
+ 0x115dc, 0x115dd,
+ 0x11630, 0x11640,
+ 0x116ab, 0x116b7,
+ 0x1171d, 0x1172b,
+ 0x1182c, 0x1183a,
+ 0x119d1, 0x119d7,
+ 0x119da, 0x119e0,
+ 0x119e4, 0x119e4,
+ 0x11a01, 0x11a0a,
+ 0x11a33, 0x11a39,
+ 0x11a3b, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a51, 0x11a5b,
+ 0x11a8a, 0x11a99,
+ 0x11c2f, 0x11c36,
+ 0x11c38, 0x11c3f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d31, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d45,
+ 0x11d47, 0x11d47,
+ 0x11d8a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d97,
+ 0x11ef3, 0x11ef6,
+ 0x16af0, 0x16af4,
+ 0x16b30, 0x16b36,
+ 0x16f4f, 0x16f4f,
+ 0x16f51, 0x16f87,
+ 0x16f8f, 0x16f92,
+ 0x1bc9d, 0x1bc9e,
+ 0x1d165, 0x1d169,
+ 0x1d16d, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e130, 0x1e136,
+ 0x1e2ec, 0x1e2ef,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e944, 0x1e94a,
+ 0xe0100, 0xe01ef,
+}; /* CR_M */
+
+/* 'Mc': General Category */
+static const OnigCodePoint CR_Mc[] = {
+ 168,
+ 0x0903, 0x0903,
+ 0x093b, 0x093b,
+ 0x093e, 0x0940,
+ 0x0949, 0x094c,
+ 0x094e, 0x094f,
+ 0x0982, 0x0983,
+ 0x09be, 0x09c0,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cc,
+ 0x09d7, 0x09d7,
+ 0x0a03, 0x0a03,
+ 0x0a3e, 0x0a40,
+ 0x0a83, 0x0a83,
+ 0x0abe, 0x0ac0,
+ 0x0ac9, 0x0ac9,
+ 0x0acb, 0x0acc,
+ 0x0b02, 0x0b03,
+ 0x0b3e, 0x0b3e,
+ 0x0b40, 0x0b40,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4c,
+ 0x0b57, 0x0b57,
+ 0x0bbe, 0x0bbf,
+ 0x0bc1, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcc,
+ 0x0bd7, 0x0bd7,
+ 0x0c01, 0x0c03,
+ 0x0c41, 0x0c44,
+ 0x0c82, 0x0c83,
+ 0x0cbe, 0x0cbe,
+ 0x0cc0, 0x0cc4,
+ 0x0cc7, 0x0cc8,
+ 0x0cca, 0x0ccb,
+ 0x0cd5, 0x0cd6,
+ 0x0d02, 0x0d03,
+ 0x0d3e, 0x0d40,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4c,
+ 0x0d57, 0x0d57,
+ 0x0d82, 0x0d83,
+ 0x0dcf, 0x0dd1,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df3,
+ 0x0f3e, 0x0f3f,
+ 0x0f7f, 0x0f7f,
+ 0x102b, 0x102c,
+ 0x1031, 0x1031,
+ 0x1038, 0x1038,
+ 0x103b, 0x103c,
+ 0x1056, 0x1057,
+ 0x1062, 0x1064,
+ 0x1067, 0x106d,
+ 0x1083, 0x1084,
+ 0x1087, 0x108c,
+ 0x108f, 0x108f,
+ 0x109a, 0x109c,
+ 0x17b6, 0x17b6,
+ 0x17be, 0x17c5,
+ 0x17c7, 0x17c8,
+ 0x1923, 0x1926,
+ 0x1929, 0x192b,
+ 0x1930, 0x1931,
+ 0x1933, 0x1938,
+ 0x1a19, 0x1a1a,
+ 0x1a55, 0x1a55,
+ 0x1a57, 0x1a57,
+ 0x1a61, 0x1a61,
+ 0x1a63, 0x1a64,
+ 0x1a6d, 0x1a72,
+ 0x1b04, 0x1b04,
+ 0x1b35, 0x1b35,
+ 0x1b3b, 0x1b3b,
+ 0x1b3d, 0x1b41,
+ 0x1b43, 0x1b44,
+ 0x1b82, 0x1b82,
+ 0x1ba1, 0x1ba1,
+ 0x1ba6, 0x1ba7,
+ 0x1baa, 0x1baa,
+ 0x1be7, 0x1be7,
+ 0x1bea, 0x1bec,
+ 0x1bee, 0x1bee,
+ 0x1bf2, 0x1bf3,
+ 0x1c24, 0x1c2b,
+ 0x1c34, 0x1c35,
+ 0x1ce1, 0x1ce1,
+ 0x1cf7, 0x1cf7,
+ 0x302e, 0x302f,
+ 0xa823, 0xa824,
+ 0xa827, 0xa827,
+ 0xa880, 0xa881,
+ 0xa8b4, 0xa8c3,
+ 0xa952, 0xa953,
+ 0xa983, 0xa983,
+ 0xa9b4, 0xa9b5,
+ 0xa9ba, 0xa9bb,
+ 0xa9be, 0xa9c0,
+ 0xaa2f, 0xaa30,
+ 0xaa33, 0xaa34,
+ 0xaa4d, 0xaa4d,
+ 0xaa7b, 0xaa7b,
+ 0xaa7d, 0xaa7d,
+ 0xaaeb, 0xaaeb,
+ 0xaaee, 0xaaef,
+ 0xaaf5, 0xaaf5,
+ 0xabe3, 0xabe4,
+ 0xabe6, 0xabe7,
+ 0xabe9, 0xabea,
+ 0xabec, 0xabec,
+ 0x11000, 0x11000,
+ 0x11002, 0x11002,
+ 0x11082, 0x11082,
+ 0x110b0, 0x110b2,
+ 0x110b7, 0x110b8,
+ 0x1112c, 0x1112c,
+ 0x11145, 0x11146,
+ 0x11182, 0x11182,
+ 0x111b3, 0x111b5,
+ 0x111bf, 0x111c0,
+ 0x1122c, 0x1122e,
+ 0x11232, 0x11233,
+ 0x11235, 0x11235,
+ 0x112e0, 0x112e2,
+ 0x11302, 0x11303,
+ 0x1133e, 0x1133f,
+ 0x11341, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11357, 0x11357,
+ 0x11362, 0x11363,
+ 0x11435, 0x11437,
+ 0x11440, 0x11441,
+ 0x11445, 0x11445,
+ 0x114b0, 0x114b2,
+ 0x114b9, 0x114b9,
+ 0x114bb, 0x114be,
+ 0x114c1, 0x114c1,
+ 0x115af, 0x115b1,
+ 0x115b8, 0x115bb,
+ 0x115be, 0x115be,
+ 0x11630, 0x11632,
+ 0x1163b, 0x1163c,
+ 0x1163e, 0x1163e,
+ 0x116ac, 0x116ac,
+ 0x116ae, 0x116af,
+ 0x116b6, 0x116b6,
+ 0x11720, 0x11721,
+ 0x11726, 0x11726,
+ 0x1182c, 0x1182e,
+ 0x11838, 0x11838,
+ 0x119d1, 0x119d3,
+ 0x119dc, 0x119df,
+ 0x119e4, 0x119e4,
+ 0x11a39, 0x11a39,
+ 0x11a57, 0x11a58,
+ 0x11a97, 0x11a97,
+ 0x11c2f, 0x11c2f,
+ 0x11c3e, 0x11c3e,
+ 0x11ca9, 0x11ca9,
+ 0x11cb1, 0x11cb1,
+ 0x11cb4, 0x11cb4,
+ 0x11d8a, 0x11d8e,
+ 0x11d93, 0x11d94,
+ 0x11d96, 0x11d96,
+ 0x11ef5, 0x11ef6,
+ 0x16f51, 0x16f87,
+ 0x1d165, 0x1d166,
+ 0x1d16d, 0x1d172,
+}; /* CR_Mc */
+
+/* 'Me': General Category */
+static const OnigCodePoint CR_Me[] = {
+ 5,
+ 0x0488, 0x0489,
+ 0x1abe, 0x1abe,
+ 0x20dd, 0x20e0,
+ 0x20e2, 0x20e4,
+ 0xa670, 0xa672,
+}; /* CR_Me */
+
+/* 'Mn': General Category */
+static const OnigCodePoint CR_Mn[] = {
+ 318,
+ 0x0300, 0x036f,
+ 0x0483, 0x0487,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x0610, 0x061a,
+ 0x064b, 0x065f,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dc,
+ 0x06df, 0x06e4,
+ 0x06e7, 0x06e8,
+ 0x06ea, 0x06ed,
+ 0x0711, 0x0711,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x07eb, 0x07f3,
+ 0x07fd, 0x07fd,
+ 0x0816, 0x0819,
+ 0x081b, 0x0823,
+ 0x0825, 0x0827,
+ 0x0829, 0x082d,
+ 0x0859, 0x085b,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x0902,
+ 0x093a, 0x093a,
+ 0x093c, 0x093c,
+ 0x0941, 0x0948,
+ 0x094d, 0x094d,
+ 0x0951, 0x0957,
+ 0x0962, 0x0963,
+ 0x0981, 0x0981,
+ 0x09bc, 0x09bc,
+ 0x09c1, 0x09c4,
+ 0x09cd, 0x09cd,
+ 0x09e2, 0x09e3,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a02,
+ 0x0a3c, 0x0a3c,
+ 0x0a41, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a70, 0x0a71,
+ 0x0a75, 0x0a75,
+ 0x0a81, 0x0a82,
+ 0x0abc, 0x0abc,
+ 0x0ac1, 0x0ac5,
+ 0x0ac7, 0x0ac8,
+ 0x0acd, 0x0acd,
+ 0x0ae2, 0x0ae3,
+ 0x0afa, 0x0aff,
+ 0x0b01, 0x0b01,
+ 0x0b3c, 0x0b3c,
+ 0x0b3f, 0x0b3f,
+ 0x0b41, 0x0b44,
+ 0x0b4d, 0x0b4d,
+ 0x0b56, 0x0b56,
+ 0x0b62, 0x0b63,
+ 0x0b82, 0x0b82,
+ 0x0bc0, 0x0bc0,
+ 0x0bcd, 0x0bcd,
+ 0x0c00, 0x0c00,
+ 0x0c04, 0x0c04,
+ 0x0c3e, 0x0c40,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c62, 0x0c63,
+ 0x0c81, 0x0c81,
+ 0x0cbc, 0x0cbc,
+ 0x0cbf, 0x0cbf,
+ 0x0cc6, 0x0cc6,
+ 0x0ccc, 0x0ccd,
+ 0x0ce2, 0x0ce3,
+ 0x0d00, 0x0d01,
+ 0x0d3b, 0x0d3c,
+ 0x0d41, 0x0d44,
+ 0x0d4d, 0x0d4d,
+ 0x0d62, 0x0d63,
+ 0x0dca, 0x0dca,
+ 0x0dd2, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e47, 0x0e4e,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0ebc,
+ 0x0ec8, 0x0ecd,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f71, 0x0f7e,
+ 0x0f80, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0f8d, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x102d, 0x1030,
+ 0x1032, 0x1037,
+ 0x1039, 0x103a,
+ 0x103d, 0x103e,
+ 0x1058, 0x1059,
+ 0x105e, 0x1060,
+ 0x1071, 0x1074,
+ 0x1082, 0x1082,
+ 0x1085, 0x1086,
+ 0x108d, 0x108d,
+ 0x109d, 0x109d,
+ 0x135d, 0x135f,
+ 0x1712, 0x1714,
+ 0x1732, 0x1734,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b4, 0x17b5,
+ 0x17b7, 0x17bd,
+ 0x17c6, 0x17c6,
+ 0x17c9, 0x17d3,
+ 0x17dd, 0x17dd,
+ 0x180b, 0x180d,
+ 0x1885, 0x1886,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x1922,
+ 0x1927, 0x1928,
+ 0x1932, 0x1932,
+ 0x1939, 0x193b,
+ 0x1a17, 0x1a18,
+ 0x1a1b, 0x1a1b,
+ 0x1a56, 0x1a56,
+ 0x1a58, 0x1a5e,
+ 0x1a60, 0x1a60,
+ 0x1a62, 0x1a62,
+ 0x1a65, 0x1a6c,
+ 0x1a73, 0x1a7c,
+ 0x1a7f, 0x1a7f,
+ 0x1ab0, 0x1abd,
+ 0x1b00, 0x1b03,
+ 0x1b34, 0x1b34,
+ 0x1b36, 0x1b3a,
+ 0x1b3c, 0x1b3c,
+ 0x1b42, 0x1b42,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1b81,
+ 0x1ba2, 0x1ba5,
+ 0x1ba8, 0x1ba9,
+ 0x1bab, 0x1bad,
+ 0x1be6, 0x1be6,
+ 0x1be8, 0x1be9,
+ 0x1bed, 0x1bed,
+ 0x1bef, 0x1bf1,
+ 0x1c2c, 0x1c33,
+ 0x1c36, 0x1c37,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1ce0,
+ 0x1ce2, 0x1ce8,
+ 0x1ced, 0x1ced,
+ 0x1cf4, 0x1cf4,
+ 0x1cf8, 0x1cf9,
+ 0x1dc0, 0x1df9,
+ 0x1dfb, 0x1dff,
+ 0x20d0, 0x20dc,
+ 0x20e1, 0x20e1,
+ 0x20e5, 0x20f0,
+ 0x2cef, 0x2cf1,
+ 0x2d7f, 0x2d7f,
+ 0x2de0, 0x2dff,
+ 0x302a, 0x302d,
+ 0x3099, 0x309a,
+ 0xa66f, 0xa66f,
+ 0xa674, 0xa67d,
+ 0xa69e, 0xa69f,
+ 0xa6f0, 0xa6f1,
+ 0xa802, 0xa802,
+ 0xa806, 0xa806,
+ 0xa80b, 0xa80b,
+ 0xa825, 0xa826,
+ 0xa8c4, 0xa8c5,
+ 0xa8e0, 0xa8f1,
+ 0xa8ff, 0xa8ff,
+ 0xa926, 0xa92d,
+ 0xa947, 0xa951,
+ 0xa980, 0xa982,
+ 0xa9b3, 0xa9b3,
+ 0xa9b6, 0xa9b9,
+ 0xa9bc, 0xa9bd,
+ 0xa9e5, 0xa9e5,
+ 0xaa29, 0xaa2e,
+ 0xaa31, 0xaa32,
+ 0xaa35, 0xaa36,
+ 0xaa43, 0xaa43,
+ 0xaa4c, 0xaa4c,
+ 0xaa7c, 0xaa7c,
+ 0xaab0, 0xaab0,
+ 0xaab2, 0xaab4,
+ 0xaab7, 0xaab8,
+ 0xaabe, 0xaabf,
+ 0xaac1, 0xaac1,
+ 0xaaec, 0xaaed,
+ 0xaaf6, 0xaaf6,
+ 0xabe5, 0xabe5,
+ 0xabe8, 0xabe8,
+ 0xabed, 0xabed,
+ 0xfb1e, 0xfb1e,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2f,
+ 0x101fd, 0x101fd,
+ 0x102e0, 0x102e0,
+ 0x10376, 0x1037a,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10ae5, 0x10ae6,
+ 0x10d24, 0x10d27,
+ 0x10f46, 0x10f50,
+ 0x11001, 0x11001,
+ 0x11038, 0x11046,
+ 0x1107f, 0x11081,
+ 0x110b3, 0x110b6,
+ 0x110b9, 0x110ba,
+ 0x11100, 0x11102,
+ 0x11127, 0x1112b,
+ 0x1112d, 0x11134,
+ 0x11173, 0x11173,
+ 0x11180, 0x11181,
+ 0x111b6, 0x111be,
+ 0x111c9, 0x111cc,
+ 0x1122f, 0x11231,
+ 0x11234, 0x11234,
+ 0x11236, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x112df, 0x112df,
+ 0x112e3, 0x112ea,
+ 0x11300, 0x11301,
+ 0x1133b, 0x1133c,
+ 0x11340, 0x11340,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11438, 0x1143f,
+ 0x11442, 0x11444,
+ 0x11446, 0x11446,
+ 0x1145e, 0x1145e,
+ 0x114b3, 0x114b8,
+ 0x114ba, 0x114ba,
+ 0x114bf, 0x114c0,
+ 0x114c2, 0x114c3,
+ 0x115b2, 0x115b5,
+ 0x115bc, 0x115bd,
+ 0x115bf, 0x115c0,
+ 0x115dc, 0x115dd,
+ 0x11633, 0x1163a,
+ 0x1163d, 0x1163d,
+ 0x1163f, 0x11640,
+ 0x116ab, 0x116ab,
+ 0x116ad, 0x116ad,
+ 0x116b0, 0x116b5,
+ 0x116b7, 0x116b7,
+ 0x1171d, 0x1171f,
+ 0x11722, 0x11725,
+ 0x11727, 0x1172b,
+ 0x1182f, 0x11837,
+ 0x11839, 0x1183a,
+ 0x119d4, 0x119d7,
+ 0x119da, 0x119db,
+ 0x119e0, 0x119e0,
+ 0x11a01, 0x11a0a,
+ 0x11a33, 0x11a38,
+ 0x11a3b, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a51, 0x11a56,
+ 0x11a59, 0x11a5b,
+ 0x11a8a, 0x11a96,
+ 0x11a98, 0x11a99,
+ 0x11c30, 0x11c36,
+ 0x11c38, 0x11c3d,
+ 0x11c3f, 0x11c3f,
+ 0x11c92, 0x11ca7,
+ 0x11caa, 0x11cb0,
+ 0x11cb2, 0x11cb3,
+ 0x11cb5, 0x11cb6,
+ 0x11d31, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d45,
+ 0x11d47, 0x11d47,
+ 0x11d90, 0x11d91,
+ 0x11d95, 0x11d95,
+ 0x11d97, 0x11d97,
+ 0x11ef3, 0x11ef4,
+ 0x16af0, 0x16af4,
+ 0x16b30, 0x16b36,
+ 0x16f4f, 0x16f4f,
+ 0x16f8f, 0x16f92,
+ 0x1bc9d, 0x1bc9e,
+ 0x1d167, 0x1d169,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e130, 0x1e136,
+ 0x1e2ec, 0x1e2ef,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e944, 0x1e94a,
+ 0xe0100, 0xe01ef,
+}; /* CR_Mn */
+
+/* 'N': Major Category */
+static const OnigCodePoint CR_N[] = {
+ 130,
+ 0x0030, 0x0039,
+ 0x00b2, 0x00b3,
+ 0x00b9, 0x00b9,
+ 0x00bc, 0x00be,
+ 0x0660, 0x0669,
+ 0x06f0, 0x06f9,
+ 0x07c0, 0x07c9,
+ 0x0966, 0x096f,
+ 0x09e6, 0x09ef,
+ 0x09f4, 0x09f9,
+ 0x0a66, 0x0a6f,
+ 0x0ae6, 0x0aef,
+ 0x0b66, 0x0b6f,
+ 0x0b72, 0x0b77,
+ 0x0be6, 0x0bf2,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7e,
+ 0x0ce6, 0x0cef,
+ 0x0d58, 0x0d5e,
+ 0x0d66, 0x0d78,
+ 0x0de6, 0x0def,
+ 0x0e50, 0x0e59,
+ 0x0ed0, 0x0ed9,
+ 0x0f20, 0x0f33,
+ 0x1040, 0x1049,
+ 0x1090, 0x1099,
+ 0x1369, 0x137c,
+ 0x16ee, 0x16f0,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1810, 0x1819,
+ 0x1946, 0x194f,
+ 0x19d0, 0x19da,
+ 0x1a80, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1b50, 0x1b59,
+ 0x1bb0, 0x1bb9,
+ 0x1c40, 0x1c49,
+ 0x1c50, 0x1c59,
+ 0x2070, 0x2070,
+ 0x2074, 0x2079,
+ 0x2080, 0x2089,
+ 0x2150, 0x2182,
+ 0x2185, 0x2189,
+ 0x2460, 0x249b,
+ 0x24ea, 0x24ff,
+ 0x2776, 0x2793,
+ 0x2cfd, 0x2cfd,
+ 0x3007, 0x3007,
+ 0x3021, 0x3029,
+ 0x3038, 0x303a,
+ 0x3192, 0x3195,
+ 0x3220, 0x3229,
+ 0x3248, 0x324f,
+ 0x3251, 0x325f,
+ 0x3280, 0x3289,
+ 0x32b1, 0x32bf,
+ 0xa620, 0xa629,
+ 0xa6e6, 0xa6ef,
+ 0xa830, 0xa835,
+ 0xa8d0, 0xa8d9,
+ 0xa900, 0xa909,
+ 0xa9d0, 0xa9d9,
+ 0xa9f0, 0xa9f9,
+ 0xaa50, 0xaa59,
+ 0xabf0, 0xabf9,
+ 0xff10, 0xff19,
+ 0x10107, 0x10133,
+ 0x10140, 0x10178,
+ 0x1018a, 0x1018b,
+ 0x102e1, 0x102fb,
+ 0x10320, 0x10323,
+ 0x10341, 0x10341,
+ 0x1034a, 0x1034a,
+ 0x103d1, 0x103d5,
+ 0x104a0, 0x104a9,
+ 0x10858, 0x1085f,
+ 0x10879, 0x1087f,
+ 0x108a7, 0x108af,
+ 0x108fb, 0x108ff,
+ 0x10916, 0x1091b,
+ 0x109bc, 0x109bd,
+ 0x109c0, 0x109cf,
+ 0x109d2, 0x109ff,
+ 0x10a40, 0x10a48,
+ 0x10a7d, 0x10a7e,
+ 0x10a9d, 0x10a9f,
+ 0x10aeb, 0x10aef,
+ 0x10b58, 0x10b5f,
+ 0x10b78, 0x10b7f,
+ 0x10ba9, 0x10baf,
+ 0x10cfa, 0x10cff,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f1d, 0x10f26,
+ 0x10f51, 0x10f54,
+ 0x11052, 0x1106f,
+ 0x110f0, 0x110f9,
+ 0x11136, 0x1113f,
+ 0x111d0, 0x111d9,
+ 0x111e1, 0x111f4,
+ 0x112f0, 0x112f9,
+ 0x11450, 0x11459,
+ 0x114d0, 0x114d9,
+ 0x11650, 0x11659,
+ 0x116c0, 0x116c9,
+ 0x11730, 0x1173b,
+ 0x118e0, 0x118f2,
+ 0x11c50, 0x11c6c,
+ 0x11d50, 0x11d59,
+ 0x11da0, 0x11da9,
+ 0x11fc0, 0x11fd4,
+ 0x12400, 0x1246e,
+ 0x16a60, 0x16a69,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16e80, 0x16e96,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d360, 0x1d378,
+ 0x1d7ce, 0x1d7ff,
+ 0x1e140, 0x1e149,
+ 0x1e2f0, 0x1e2f9,
+ 0x1e8c7, 0x1e8cf,
+ 0x1e950, 0x1e959,
+ 0x1ec71, 0x1ecab,
+ 0x1ecad, 0x1ecaf,
+ 0x1ecb1, 0x1ecb4,
+ 0x1ed01, 0x1ed2d,
+ 0x1ed2f, 0x1ed3d,
+ 0x1f100, 0x1f10c,
+}; /* CR_N */
+
+/* 'Nd': General Category */
+#define CR_Nd CR_Digit
+
+/* 'Nl': General Category */
+static const OnigCodePoint CR_Nl[] = {
+ 12,
+ 0x16ee, 0x16f0,
+ 0x2160, 0x2182,
+ 0x2185, 0x2188,
+ 0x3007, 0x3007,
+ 0x3021, 0x3029,
+ 0x3038, 0x303a,
+ 0xa6e6, 0xa6ef,
+ 0x10140, 0x10174,
+ 0x10341, 0x10341,
+ 0x1034a, 0x1034a,
+ 0x103d1, 0x103d5,
+ 0x12400, 0x1246e,
+}; /* CR_Nl */
+
+/* 'No': General Category */
+static const OnigCodePoint CR_No[] = {
+ 70,
+ 0x00b2, 0x00b3,
+ 0x00b9, 0x00b9,
+ 0x00bc, 0x00be,
+ 0x09f4, 0x09f9,
+ 0x0b72, 0x0b77,
+ 0x0bf0, 0x0bf2,
+ 0x0c78, 0x0c7e,
+ 0x0d58, 0x0d5e,
+ 0x0d70, 0x0d78,
+ 0x0f2a, 0x0f33,
+ 0x1369, 0x137c,
+ 0x17f0, 0x17f9,
+ 0x19da, 0x19da,
+ 0x2070, 0x2070,
+ 0x2074, 0x2079,
+ 0x2080, 0x2089,
+ 0x2150, 0x215f,
+ 0x2189, 0x2189,
+ 0x2460, 0x249b,
+ 0x24ea, 0x24ff,
+ 0x2776, 0x2793,
+ 0x2cfd, 0x2cfd,
+ 0x3192, 0x3195,
+ 0x3220, 0x3229,
+ 0x3248, 0x324f,
+ 0x3251, 0x325f,
+ 0x3280, 0x3289,
+ 0x32b1, 0x32bf,
+ 0xa830, 0xa835,
+ 0x10107, 0x10133,
+ 0x10175, 0x10178,
+ 0x1018a, 0x1018b,
+ 0x102e1, 0x102fb,
+ 0x10320, 0x10323,
+ 0x10858, 0x1085f,
+ 0x10879, 0x1087f,
+ 0x108a7, 0x108af,
+ 0x108fb, 0x108ff,
+ 0x10916, 0x1091b,
+ 0x109bc, 0x109bd,
+ 0x109c0, 0x109cf,
+ 0x109d2, 0x109ff,
+ 0x10a40, 0x10a48,
+ 0x10a7d, 0x10a7e,
+ 0x10a9d, 0x10a9f,
+ 0x10aeb, 0x10aef,
+ 0x10b58, 0x10b5f,
+ 0x10b78, 0x10b7f,
+ 0x10ba9, 0x10baf,
+ 0x10cfa, 0x10cff,
+ 0x10e60, 0x10e7e,
+ 0x10f1d, 0x10f26,
+ 0x10f51, 0x10f54,
+ 0x11052, 0x11065,
+ 0x111e1, 0x111f4,
+ 0x1173a, 0x1173b,
+ 0x118ea, 0x118f2,
+ 0x11c5a, 0x11c6c,
+ 0x11fc0, 0x11fd4,
+ 0x16b5b, 0x16b61,
+ 0x16e80, 0x16e96,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d360, 0x1d378,
+ 0x1e8c7, 0x1e8cf,
+ 0x1ec71, 0x1ecab,
+ 0x1ecad, 0x1ecaf,
+ 0x1ecb1, 0x1ecb4,
+ 0x1ed01, 0x1ed2d,
+ 0x1ed2f, 0x1ed3d,
+ 0x1f100, 0x1f10c,
+}; /* CR_No */
+
+/* 'P': Major Category */
+#define CR_P CR_Punct
+
+/* 'Pc': General Category */
+static const OnigCodePoint CR_Pc[] = {
+ 6,
+ 0x005f, 0x005f,
+ 0x203f, 0x2040,
+ 0x2054, 0x2054,
+ 0xfe33, 0xfe34,
+ 0xfe4d, 0xfe4f,
+ 0xff3f, 0xff3f,
+}; /* CR_Pc */
+
+/* 'Pd': General Category */
+static const OnigCodePoint CR_Pd[] = {
+ 17,
+ 0x002d, 0x002d,
+ 0x058a, 0x058a,
+ 0x05be, 0x05be,
+ 0x1400, 0x1400,
+ 0x1806, 0x1806,
+ 0x2010, 0x2015,
+ 0x2e17, 0x2e17,
+ 0x2e1a, 0x2e1a,
+ 0x2e3a, 0x2e3b,
+ 0x2e40, 0x2e40,
+ 0x301c, 0x301c,
+ 0x3030, 0x3030,
+ 0x30a0, 0x30a0,
+ 0xfe31, 0xfe32,
+ 0xfe58, 0xfe58,
+ 0xfe63, 0xfe63,
+ 0xff0d, 0xff0d,
+}; /* CR_Pd */
+
+/* 'Pe': General Category */
+static const OnigCodePoint CR_Pe[] = {
+ 72,
+ 0x0029, 0x0029,
+ 0x005d, 0x005d,
+ 0x007d, 0x007d,
+ 0x0f3b, 0x0f3b,
+ 0x0f3d, 0x0f3d,
+ 0x169c, 0x169c,
+ 0x2046, 0x2046,
+ 0x207e, 0x207e,
+ 0x208e, 0x208e,
+ 0x2309, 0x2309,
+ 0x230b, 0x230b,
+ 0x232a, 0x232a,
+ 0x2769, 0x2769,
+ 0x276b, 0x276b,
+ 0x276d, 0x276d,
+ 0x276f, 0x276f,
+ 0x2771, 0x2771,
+ 0x2773, 0x2773,
+ 0x2775, 0x2775,
+ 0x27c6, 0x27c6,
+ 0x27e7, 0x27e7,
+ 0x27e9, 0x27e9,
+ 0x27eb, 0x27eb,
+ 0x27ed, 0x27ed,
+ 0x27ef, 0x27ef,
+ 0x2984, 0x2984,
+ 0x2986, 0x2986,
+ 0x2988, 0x2988,
+ 0x298a, 0x298a,
+ 0x298c, 0x298c,
+ 0x298e, 0x298e,
+ 0x2990, 0x2990,
+ 0x2992, 0x2992,
+ 0x2994, 0x2994,
+ 0x2996, 0x2996,
+ 0x2998, 0x2998,
+ 0x29d9, 0x29d9,
+ 0x29db, 0x29db,
+ 0x29fd, 0x29fd,
+ 0x2e23, 0x2e23,
+ 0x2e25, 0x2e25,
+ 0x2e27, 0x2e27,
+ 0x2e29, 0x2e29,
+ 0x3009, 0x3009,
+ 0x300b, 0x300b,
+ 0x300d, 0x300d,
+ 0x300f, 0x300f,
+ 0x3011, 0x3011,
+ 0x3015, 0x3015,
+ 0x3017, 0x3017,
+ 0x3019, 0x3019,
+ 0x301b, 0x301b,
+ 0x301e, 0x301f,
+ 0xfd3e, 0xfd3e,
+ 0xfe18, 0xfe18,
+ 0xfe36, 0xfe36,
+ 0xfe38, 0xfe38,
+ 0xfe3a, 0xfe3a,
+ 0xfe3c, 0xfe3c,
+ 0xfe3e, 0xfe3e,
+ 0xfe40, 0xfe40,
+ 0xfe42, 0xfe42,
+ 0xfe44, 0xfe44,
+ 0xfe48, 0xfe48,
+ 0xfe5a, 0xfe5a,
+ 0xfe5c, 0xfe5c,
+ 0xfe5e, 0xfe5e,
+ 0xff09, 0xff09,
+ 0xff3d, 0xff3d,
+ 0xff5d, 0xff5d,
+ 0xff60, 0xff60,
+ 0xff63, 0xff63,
+}; /* CR_Pe */
+
+/* 'Pf': General Category */
+static const OnigCodePoint CR_Pf[] = {
+ 10,
+ 0x00bb, 0x00bb,
+ 0x2019, 0x2019,
+ 0x201d, 0x201d,
+ 0x203a, 0x203a,
+ 0x2e03, 0x2e03,
+ 0x2e05, 0x2e05,
+ 0x2e0a, 0x2e0a,
+ 0x2e0d, 0x2e0d,
+ 0x2e1d, 0x2e1d,
+ 0x2e21, 0x2e21,
+}; /* CR_Pf */
+
+/* 'Pi': General Category */
+static const OnigCodePoint CR_Pi[] = {
+ 11,
+ 0x00ab, 0x00ab,
+ 0x2018, 0x2018,
+ 0x201b, 0x201c,
+ 0x201f, 0x201f,
+ 0x2039, 0x2039,
+ 0x2e02, 0x2e02,
+ 0x2e04, 0x2e04,
+ 0x2e09, 0x2e09,
+ 0x2e0c, 0x2e0c,
+ 0x2e1c, 0x2e1c,
+ 0x2e20, 0x2e20,
+}; /* CR_Pi */
+
+/* 'Po': General Category */
+static const OnigCodePoint CR_Po[] = {
+ 179,
+ 0x0021, 0x0023,
+ 0x0025, 0x0027,
+ 0x002a, 0x002a,
+ 0x002c, 0x002c,
+ 0x002e, 0x002f,
+ 0x003a, 0x003b,
+ 0x003f, 0x0040,
+ 0x005c, 0x005c,
+ 0x00a1, 0x00a1,
+ 0x00a7, 0x00a7,
+ 0x00b6, 0x00b7,
+ 0x00bf, 0x00bf,
+ 0x037e, 0x037e,
+ 0x0387, 0x0387,
+ 0x055a, 0x055f,
+ 0x0589, 0x0589,
+ 0x05c0, 0x05c0,
+ 0x05c3, 0x05c3,
+ 0x05c6, 0x05c6,
+ 0x05f3, 0x05f4,
+ 0x0609, 0x060a,
+ 0x060c, 0x060d,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x066a, 0x066d,
+ 0x06d4, 0x06d4,
+ 0x0700, 0x070d,
+ 0x07f7, 0x07f9,
+ 0x0830, 0x083e,
+ 0x085e, 0x085e,
+ 0x0964, 0x0965,
+ 0x0970, 0x0970,
+ 0x09fd, 0x09fd,
+ 0x0a76, 0x0a76,
+ 0x0af0, 0x0af0,
+ 0x0c77, 0x0c77,
+ 0x0c84, 0x0c84,
+ 0x0df4, 0x0df4,
+ 0x0e4f, 0x0e4f,
+ 0x0e5a, 0x0e5b,
+ 0x0f04, 0x0f12,
+ 0x0f14, 0x0f14,
+ 0x0f85, 0x0f85,
+ 0x0fd0, 0x0fd4,
+ 0x0fd9, 0x0fda,
+ 0x104a, 0x104f,
+ 0x10fb, 0x10fb,
+ 0x1360, 0x1368,
+ 0x166e, 0x166e,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x17d4, 0x17d6,
+ 0x17d8, 0x17da,
+ 0x1800, 0x1805,
+ 0x1807, 0x180a,
+ 0x1944, 0x1945,
+ 0x1a1e, 0x1a1f,
+ 0x1aa0, 0x1aa6,
+ 0x1aa8, 0x1aad,
+ 0x1b5a, 0x1b60,
+ 0x1bfc, 0x1bff,
+ 0x1c3b, 0x1c3f,
+ 0x1c7e, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd3, 0x1cd3,
+ 0x2016, 0x2017,
+ 0x2020, 0x2027,
+ 0x2030, 0x2038,
+ 0x203b, 0x203e,
+ 0x2041, 0x2043,
+ 0x2047, 0x2051,
+ 0x2053, 0x2053,
+ 0x2055, 0x205e,
+ 0x2cf9, 0x2cfc,
+ 0x2cfe, 0x2cff,
+ 0x2d70, 0x2d70,
+ 0x2e00, 0x2e01,
+ 0x2e06, 0x2e08,
+ 0x2e0b, 0x2e0b,
+ 0x2e0e, 0x2e16,
+ 0x2e18, 0x2e19,
+ 0x2e1b, 0x2e1b,
+ 0x2e1e, 0x2e1f,
+ 0x2e2a, 0x2e2e,
+ 0x2e30, 0x2e39,
+ 0x2e3c, 0x2e3f,
+ 0x2e41, 0x2e41,
+ 0x2e43, 0x2e4f,
+ 0x3001, 0x3003,
+ 0x303d, 0x303d,
+ 0x30fb, 0x30fb,
+ 0xa4fe, 0xa4ff,
+ 0xa60d, 0xa60f,
+ 0xa673, 0xa673,
+ 0xa67e, 0xa67e,
+ 0xa6f2, 0xa6f7,
+ 0xa874, 0xa877,
+ 0xa8ce, 0xa8cf,
+ 0xa8f8, 0xa8fa,
+ 0xa8fc, 0xa8fc,
+ 0xa92e, 0xa92f,
+ 0xa95f, 0xa95f,
+ 0xa9c1, 0xa9cd,
+ 0xa9de, 0xa9df,
+ 0xaa5c, 0xaa5f,
+ 0xaade, 0xaadf,
+ 0xaaf0, 0xaaf1,
+ 0xabeb, 0xabeb,
+ 0xfe10, 0xfe16,
+ 0xfe19, 0xfe19,
+ 0xfe30, 0xfe30,
+ 0xfe45, 0xfe46,
+ 0xfe49, 0xfe4c,
+ 0xfe50, 0xfe52,
+ 0xfe54, 0xfe57,
+ 0xfe5f, 0xfe61,
+ 0xfe68, 0xfe68,
+ 0xfe6a, 0xfe6b,
+ 0xff01, 0xff03,
+ 0xff05, 0xff07,
+ 0xff0a, 0xff0a,
+ 0xff0c, 0xff0c,
+ 0xff0e, 0xff0f,
+ 0xff1a, 0xff1b,
+ 0xff1f, 0xff20,
+ 0xff3c, 0xff3c,
+ 0xff61, 0xff61,
+ 0xff64, 0xff65,
+ 0x10100, 0x10102,
+ 0x1039f, 0x1039f,
+ 0x103d0, 0x103d0,
+ 0x1056f, 0x1056f,
+ 0x10857, 0x10857,
+ 0x1091f, 0x1091f,
+ 0x1093f, 0x1093f,
+ 0x10a50, 0x10a58,
+ 0x10a7f, 0x10a7f,
+ 0x10af0, 0x10af6,
+ 0x10b39, 0x10b3f,
+ 0x10b99, 0x10b9c,
+ 0x10f55, 0x10f59,
+ 0x11047, 0x1104d,
+ 0x110bb, 0x110bc,
+ 0x110be, 0x110c1,
+ 0x11140, 0x11143,
+ 0x11174, 0x11175,
+ 0x111c5, 0x111c8,
+ 0x111cd, 0x111cd,
+ 0x111db, 0x111db,
+ 0x111dd, 0x111df,
+ 0x11238, 0x1123d,
+ 0x112a9, 0x112a9,
+ 0x1144b, 0x1144f,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145d,
+ 0x114c6, 0x114c6,
+ 0x115c1, 0x115d7,
+ 0x11641, 0x11643,
+ 0x11660, 0x1166c,
+ 0x1173c, 0x1173e,
+ 0x1183b, 0x1183b,
+ 0x119e2, 0x119e2,
+ 0x11a3f, 0x11a46,
+ 0x11a9a, 0x11a9c,
+ 0x11a9e, 0x11aa2,
+ 0x11c41, 0x11c45,
+ 0x11c70, 0x11c71,
+ 0x11ef7, 0x11ef8,
+ 0x11fff, 0x11fff,
+ 0x12470, 0x12474,
+ 0x16a6e, 0x16a6f,
+ 0x16af5, 0x16af5,
+ 0x16b37, 0x16b3b,
+ 0x16b44, 0x16b44,
+ 0x16e97, 0x16e9a,
+ 0x16fe2, 0x16fe2,
+ 0x1bc9f, 0x1bc9f,
+ 0x1da87, 0x1da8b,
+ 0x1e95e, 0x1e95f,
+}; /* CR_Po */
+
+/* 'Ps': General Category */
+static const OnigCodePoint CR_Ps[] = {
+ 75,
+ 0x0028, 0x0028,
+ 0x005b, 0x005b,
+ 0x007b, 0x007b,
+ 0x0f3a, 0x0f3a,
+ 0x0f3c, 0x0f3c,
+ 0x169b, 0x169b,
+ 0x201a, 0x201a,
+ 0x201e, 0x201e,
+ 0x2045, 0x2045,
+ 0x207d, 0x207d,
+ 0x208d, 0x208d,
+ 0x2308, 0x2308,
+ 0x230a, 0x230a,
+ 0x2329, 0x2329,
+ 0x2768, 0x2768,
+ 0x276a, 0x276a,
+ 0x276c, 0x276c,
+ 0x276e, 0x276e,
+ 0x2770, 0x2770,
+ 0x2772, 0x2772,
+ 0x2774, 0x2774,
+ 0x27c5, 0x27c5,
+ 0x27e6, 0x27e6,
+ 0x27e8, 0x27e8,
+ 0x27ea, 0x27ea,
+ 0x27ec, 0x27ec,
+ 0x27ee, 0x27ee,
+ 0x2983, 0x2983,
+ 0x2985, 0x2985,
+ 0x2987, 0x2987,
+ 0x2989, 0x2989,
+ 0x298b, 0x298b,
+ 0x298d, 0x298d,
+ 0x298f, 0x298f,
+ 0x2991, 0x2991,
+ 0x2993, 0x2993,
+ 0x2995, 0x2995,
+ 0x2997, 0x2997,
+ 0x29d8, 0x29d8,
+ 0x29da, 0x29da,
+ 0x29fc, 0x29fc,
+ 0x2e22, 0x2e22,
+ 0x2e24, 0x2e24,
+ 0x2e26, 0x2e26,
+ 0x2e28, 0x2e28,
+ 0x2e42, 0x2e42,
+ 0x3008, 0x3008,
+ 0x300a, 0x300a,
+ 0x300c, 0x300c,
+ 0x300e, 0x300e,
+ 0x3010, 0x3010,
+ 0x3014, 0x3014,
+ 0x3016, 0x3016,
+ 0x3018, 0x3018,
+ 0x301a, 0x301a,
+ 0x301d, 0x301d,
+ 0xfd3f, 0xfd3f,
+ 0xfe17, 0xfe17,
+ 0xfe35, 0xfe35,
+ 0xfe37, 0xfe37,
+ 0xfe39, 0xfe39,
+ 0xfe3b, 0xfe3b,
+ 0xfe3d, 0xfe3d,
+ 0xfe3f, 0xfe3f,
+ 0xfe41, 0xfe41,
+ 0xfe43, 0xfe43,
+ 0xfe47, 0xfe47,
+ 0xfe59, 0xfe59,
+ 0xfe5b, 0xfe5b,
+ 0xfe5d, 0xfe5d,
+ 0xff08, 0xff08,
+ 0xff3b, 0xff3b,
+ 0xff5b, 0xff5b,
+ 0xff5f, 0xff5f,
+ 0xff62, 0xff62,
+}; /* CR_Ps */
+
+/* 'S': Major Category */
+static const OnigCodePoint CR_S[] = {
+ 226,
+ 0x0024, 0x0024,
+ 0x002b, 0x002b,
+ 0x003c, 0x003e,
+ 0x005e, 0x005e,
+ 0x0060, 0x0060,
+ 0x007c, 0x007c,
+ 0x007e, 0x007e,
+ 0x00a2, 0x00a6,
+ 0x00a8, 0x00a9,
+ 0x00ac, 0x00ac,
+ 0x00ae, 0x00b1,
+ 0x00b4, 0x00b4,
+ 0x00b8, 0x00b8,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x02c2, 0x02c5,
+ 0x02d2, 0x02df,
+ 0x02e5, 0x02eb,
+ 0x02ed, 0x02ed,
+ 0x02ef, 0x02ff,
+ 0x0375, 0x0375,
+ 0x0384, 0x0385,
+ 0x03f6, 0x03f6,
+ 0x0482, 0x0482,
+ 0x058d, 0x058f,
+ 0x0606, 0x0608,
+ 0x060b, 0x060b,
+ 0x060e, 0x060f,
+ 0x06de, 0x06de,
+ 0x06e9, 0x06e9,
+ 0x06fd, 0x06fe,
+ 0x07f6, 0x07f6,
+ 0x07fe, 0x07ff,
+ 0x09f2, 0x09f3,
+ 0x09fa, 0x09fb,
+ 0x0af1, 0x0af1,
+ 0x0b70, 0x0b70,
+ 0x0bf3, 0x0bfa,
+ 0x0c7f, 0x0c7f,
+ 0x0d4f, 0x0d4f,
+ 0x0d79, 0x0d79,
+ 0x0e3f, 0x0e3f,
+ 0x0f01, 0x0f03,
+ 0x0f13, 0x0f13,
+ 0x0f15, 0x0f17,
+ 0x0f1a, 0x0f1f,
+ 0x0f34, 0x0f34,
+ 0x0f36, 0x0f36,
+ 0x0f38, 0x0f38,
+ 0x0fbe, 0x0fc5,
+ 0x0fc7, 0x0fcc,
+ 0x0fce, 0x0fcf,
+ 0x0fd5, 0x0fd8,
+ 0x109e, 0x109f,
+ 0x1390, 0x1399,
+ 0x166d, 0x166d,
+ 0x17db, 0x17db,
+ 0x1940, 0x1940,
+ 0x19de, 0x19ff,
+ 0x1b61, 0x1b6a,
+ 0x1b74, 0x1b7c,
+ 0x1fbd, 0x1fbd,
+ 0x1fbf, 0x1fc1,
+ 0x1fcd, 0x1fcf,
+ 0x1fdd, 0x1fdf,
+ 0x1fed, 0x1fef,
+ 0x1ffd, 0x1ffe,
+ 0x2044, 0x2044,
+ 0x2052, 0x2052,
+ 0x207a, 0x207c,
+ 0x208a, 0x208c,
+ 0x20a0, 0x20bf,
+ 0x2100, 0x2101,
+ 0x2103, 0x2106,
+ 0x2108, 0x2109,
+ 0x2114, 0x2114,
+ 0x2116, 0x2118,
+ 0x211e, 0x2123,
+ 0x2125, 0x2125,
+ 0x2127, 0x2127,
+ 0x2129, 0x2129,
+ 0x212e, 0x212e,
+ 0x213a, 0x213b,
+ 0x2140, 0x2144,
+ 0x214a, 0x214d,
+ 0x214f, 0x214f,
+ 0x218a, 0x218b,
+ 0x2190, 0x2307,
+ 0x230c, 0x2328,
+ 0x232b, 0x2426,
+ 0x2440, 0x244a,
+ 0x249c, 0x24e9,
+ 0x2500, 0x2767,
+ 0x2794, 0x27c4,
+ 0x27c7, 0x27e5,
+ 0x27f0, 0x2982,
+ 0x2999, 0x29d7,
+ 0x29dc, 0x29fb,
+ 0x29fe, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bff,
+ 0x2ce5, 0x2cea,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3004, 0x3004,
+ 0x3012, 0x3013,
+ 0x3020, 0x3020,
+ 0x3036, 0x3037,
+ 0x303e, 0x303f,
+ 0x309b, 0x309c,
+ 0x3190, 0x3191,
+ 0x3196, 0x319f,
+ 0x31c0, 0x31e3,
+ 0x3200, 0x321e,
+ 0x322a, 0x3247,
+ 0x3250, 0x3250,
+ 0x3260, 0x327f,
+ 0x328a, 0x32b0,
+ 0x32c0, 0x33ff,
+ 0x4dc0, 0x4dff,
+ 0xa490, 0xa4c6,
+ 0xa700, 0xa716,
+ 0xa720, 0xa721,
+ 0xa789, 0xa78a,
+ 0xa828, 0xa82b,
+ 0xa836, 0xa839,
+ 0xaa77, 0xaa79,
+ 0xab5b, 0xab5b,
+ 0xfb29, 0xfb29,
+ 0xfbb2, 0xfbc1,
+ 0xfdfc, 0xfdfd,
+ 0xfe62, 0xfe62,
+ 0xfe64, 0xfe66,
+ 0xfe69, 0xfe69,
+ 0xff04, 0xff04,
+ 0xff0b, 0xff0b,
+ 0xff1c, 0xff1e,
+ 0xff3e, 0xff3e,
+ 0xff40, 0xff40,
+ 0xff5c, 0xff5c,
+ 0xff5e, 0xff5e,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfffc, 0xfffd,
+ 0x10137, 0x1013f,
+ 0x10179, 0x10189,
+ 0x1018c, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fc,
+ 0x10877, 0x10878,
+ 0x10ac8, 0x10ac8,
+ 0x1173f, 0x1173f,
+ 0x11fd5, 0x11ff1,
+ 0x16b3c, 0x16b3f,
+ 0x16b45, 0x16b45,
+ 0x1bc9c, 0x1bc9c,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d164,
+ 0x1d16a, 0x1d16c,
+ 0x1d183, 0x1d184,
+ 0x1d18c, 0x1d1a9,
+ 0x1d1ae, 0x1d1e8,
+ 0x1d200, 0x1d241,
+ 0x1d245, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d6c1, 0x1d6c1,
+ 0x1d6db, 0x1d6db,
+ 0x1d6fb, 0x1d6fb,
+ 0x1d715, 0x1d715,
+ 0x1d735, 0x1d735,
+ 0x1d74f, 0x1d74f,
+ 0x1d76f, 0x1d76f,
+ 0x1d789, 0x1d789,
+ 0x1d7a9, 0x1d7a9,
+ 0x1d7c3, 0x1d7c3,
+ 0x1d800, 0x1d9ff,
+ 0x1da37, 0x1da3a,
+ 0x1da6d, 0x1da74,
+ 0x1da76, 0x1da83,
+ 0x1da85, 0x1da86,
+ 0x1e14f, 0x1e14f,
+ 0x1e2ff, 0x1e2ff,
+ 0x1ecac, 0x1ecac,
+ 0x1ecb0, 0x1ecb0,
+ 0x1ed2e, 0x1ed2e,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+}; /* CR_S */
+
+/* 'Sc': General Category */
+static const OnigCodePoint CR_Sc[] = {
+ 21,
+ 0x0024, 0x0024,
+ 0x00a2, 0x00a5,
+ 0x058f, 0x058f,
+ 0x060b, 0x060b,
+ 0x07fe, 0x07ff,
+ 0x09f2, 0x09f3,
+ 0x09fb, 0x09fb,
+ 0x0af1, 0x0af1,
+ 0x0bf9, 0x0bf9,
+ 0x0e3f, 0x0e3f,
+ 0x17db, 0x17db,
+ 0x20a0, 0x20bf,
+ 0xa838, 0xa838,
+ 0xfdfc, 0xfdfc,
+ 0xfe69, 0xfe69,
+ 0xff04, 0xff04,
+ 0xffe0, 0xffe1,
+ 0xffe5, 0xffe6,
+ 0x11fdd, 0x11fe0,
+ 0x1e2ff, 0x1e2ff,
+ 0x1ecb0, 0x1ecb0,
+}; /* CR_Sc */
+
+/* 'Sk': General Category */
+static const OnigCodePoint CR_Sk[] = {
+ 29,
+ 0x005e, 0x005e,
+ 0x0060, 0x0060,
+ 0x00a8, 0x00a8,
+ 0x00af, 0x00af,
+ 0x00b4, 0x00b4,
+ 0x00b8, 0x00b8,
+ 0x02c2, 0x02c5,
+ 0x02d2, 0x02df,
+ 0x02e5, 0x02eb,
+ 0x02ed, 0x02ed,
+ 0x02ef, 0x02ff,
+ 0x0375, 0x0375,
+ 0x0384, 0x0385,
+ 0x1fbd, 0x1fbd,
+ 0x1fbf, 0x1fc1,
+ 0x1fcd, 0x1fcf,
+ 0x1fdd, 0x1fdf,
+ 0x1fed, 0x1fef,
+ 0x1ffd, 0x1ffe,
+ 0x309b, 0x309c,
+ 0xa700, 0xa716,
+ 0xa720, 0xa721,
+ 0xa789, 0xa78a,
+ 0xab5b, 0xab5b,
+ 0xfbb2, 0xfbc1,
+ 0xff3e, 0xff3e,
+ 0xff40, 0xff40,
+ 0xffe3, 0xffe3,
+ 0x1f3fb, 0x1f3ff,
+}; /* CR_Sk */
+
+/* 'Sm': General Category */
+static const OnigCodePoint CR_Sm[] = {
+ 64,
+ 0x002b, 0x002b,
+ 0x003c, 0x003e,
+ 0x007c, 0x007c,
+ 0x007e, 0x007e,
+ 0x00ac, 0x00ac,
+ 0x00b1, 0x00b1,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x03f6, 0x03f6,
+ 0x0606, 0x0608,
+ 0x2044, 0x2044,
+ 0x2052, 0x2052,
+ 0x207a, 0x207c,
+ 0x208a, 0x208c,
+ 0x2118, 0x2118,
+ 0x2140, 0x2144,
+ 0x214b, 0x214b,
+ 0x2190, 0x2194,
+ 0x219a, 0x219b,
+ 0x21a0, 0x21a0,
+ 0x21a3, 0x21a3,
+ 0x21a6, 0x21a6,
+ 0x21ae, 0x21ae,
+ 0x21ce, 0x21cf,
+ 0x21d2, 0x21d2,
+ 0x21d4, 0x21d4,
+ 0x21f4, 0x22ff,
+ 0x2320, 0x2321,
+ 0x237c, 0x237c,
+ 0x239b, 0x23b3,
+ 0x23dc, 0x23e1,
+ 0x25b7, 0x25b7,
+ 0x25c1, 0x25c1,
+ 0x25f8, 0x25ff,
+ 0x266f, 0x266f,
+ 0x27c0, 0x27c4,
+ 0x27c7, 0x27e5,
+ 0x27f0, 0x27ff,
+ 0x2900, 0x2982,
+ 0x2999, 0x29d7,
+ 0x29dc, 0x29fb,
+ 0x29fe, 0x2aff,
+ 0x2b30, 0x2b44,
+ 0x2b47, 0x2b4c,
+ 0xfb29, 0xfb29,
+ 0xfe62, 0xfe62,
+ 0xfe64, 0xfe66,
+ 0xff0b, 0xff0b,
+ 0xff1c, 0xff1e,
+ 0xff5c, 0xff5c,
+ 0xff5e, 0xff5e,
+ 0xffe2, 0xffe2,
+ 0xffe9, 0xffec,
+ 0x1d6c1, 0x1d6c1,
+ 0x1d6db, 0x1d6db,
+ 0x1d6fb, 0x1d6fb,
+ 0x1d715, 0x1d715,
+ 0x1d735, 0x1d735,
+ 0x1d74f, 0x1d74f,
+ 0x1d76f, 0x1d76f,
+ 0x1d789, 0x1d789,
+ 0x1d7a9, 0x1d7a9,
+ 0x1d7c3, 0x1d7c3,
+ 0x1eef0, 0x1eef1,
+}; /* CR_Sm */
+
+/* 'So': General Category */
+static const OnigCodePoint CR_So[] = {
+ 180,
+ 0x00a6, 0x00a6,
+ 0x00a9, 0x00a9,
+ 0x00ae, 0x00ae,
+ 0x00b0, 0x00b0,
+ 0x0482, 0x0482,
+ 0x058d, 0x058e,
+ 0x060e, 0x060f,
+ 0x06de, 0x06de,
+ 0x06e9, 0x06e9,
+ 0x06fd, 0x06fe,
+ 0x07f6, 0x07f6,
+ 0x09fa, 0x09fa,
+ 0x0b70, 0x0b70,
+ 0x0bf3, 0x0bf8,
+ 0x0bfa, 0x0bfa,
+ 0x0c7f, 0x0c7f,
+ 0x0d4f, 0x0d4f,
+ 0x0d79, 0x0d79,
+ 0x0f01, 0x0f03,
+ 0x0f13, 0x0f13,
+ 0x0f15, 0x0f17,
+ 0x0f1a, 0x0f1f,
+ 0x0f34, 0x0f34,
+ 0x0f36, 0x0f36,
+ 0x0f38, 0x0f38,
+ 0x0fbe, 0x0fc5,
+ 0x0fc7, 0x0fcc,
+ 0x0fce, 0x0fcf,
+ 0x0fd5, 0x0fd8,
+ 0x109e, 0x109f,
+ 0x1390, 0x1399,
+ 0x166d, 0x166d,
+ 0x1940, 0x1940,
+ 0x19de, 0x19ff,
+ 0x1b61, 0x1b6a,
+ 0x1b74, 0x1b7c,
+ 0x2100, 0x2101,
+ 0x2103, 0x2106,
+ 0x2108, 0x2109,
+ 0x2114, 0x2114,
+ 0x2116, 0x2117,
+ 0x211e, 0x2123,
+ 0x2125, 0x2125,
+ 0x2127, 0x2127,
+ 0x2129, 0x2129,
+ 0x212e, 0x212e,
+ 0x213a, 0x213b,
+ 0x214a, 0x214a,
+ 0x214c, 0x214d,
+ 0x214f, 0x214f,
+ 0x218a, 0x218b,
+ 0x2195, 0x2199,
+ 0x219c, 0x219f,
+ 0x21a1, 0x21a2,
+ 0x21a4, 0x21a5,
+ 0x21a7, 0x21ad,
+ 0x21af, 0x21cd,
+ 0x21d0, 0x21d1,
+ 0x21d3, 0x21d3,
+ 0x21d5, 0x21f3,
+ 0x2300, 0x2307,
+ 0x230c, 0x231f,
+ 0x2322, 0x2328,
+ 0x232b, 0x237b,
+ 0x237d, 0x239a,
+ 0x23b4, 0x23db,
+ 0x23e2, 0x2426,
+ 0x2440, 0x244a,
+ 0x249c, 0x24e9,
+ 0x2500, 0x25b6,
+ 0x25b8, 0x25c0,
+ 0x25c2, 0x25f7,
+ 0x2600, 0x266e,
+ 0x2670, 0x2767,
+ 0x2794, 0x27bf,
+ 0x2800, 0x28ff,
+ 0x2b00, 0x2b2f,
+ 0x2b45, 0x2b46,
+ 0x2b4d, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bff,
+ 0x2ce5, 0x2cea,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3004, 0x3004,
+ 0x3012, 0x3013,
+ 0x3020, 0x3020,
+ 0x3036, 0x3037,
+ 0x303e, 0x303f,
+ 0x3190, 0x3191,
+ 0x3196, 0x319f,
+ 0x31c0, 0x31e3,
+ 0x3200, 0x321e,
+ 0x322a, 0x3247,
+ 0x3250, 0x3250,
+ 0x3260, 0x327f,
+ 0x328a, 0x32b0,
+ 0x32c0, 0x33ff,
+ 0x4dc0, 0x4dff,
+ 0xa490, 0xa4c6,
+ 0xa828, 0xa82b,
+ 0xa836, 0xa837,
+ 0xa839, 0xa839,
+ 0xaa77, 0xaa79,
+ 0xfdfd, 0xfdfd,
+ 0xffe4, 0xffe4,
+ 0xffe8, 0xffe8,
+ 0xffed, 0xffee,
+ 0xfffc, 0xfffd,
+ 0x10137, 0x1013f,
+ 0x10179, 0x10189,
+ 0x1018c, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fc,
+ 0x10877, 0x10878,
+ 0x10ac8, 0x10ac8,
+ 0x1173f, 0x1173f,
+ 0x11fd5, 0x11fdc,
+ 0x11fe1, 0x11ff1,
+ 0x16b3c, 0x16b3f,
+ 0x16b45, 0x16b45,
+ 0x1bc9c, 0x1bc9c,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d164,
+ 0x1d16a, 0x1d16c,
+ 0x1d183, 0x1d184,
+ 0x1d18c, 0x1d1a9,
+ 0x1d1ae, 0x1d1e8,
+ 0x1d200, 0x1d241,
+ 0x1d245, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d800, 0x1d9ff,
+ 0x1da37, 0x1da3a,
+ 0x1da6d, 0x1da74,
+ 0x1da76, 0x1da83,
+ 0x1da85, 0x1da86,
+ 0x1e14f, 0x1e14f,
+ 0x1ecac, 0x1ecac,
+ 0x1ed2e, 0x1ed2e,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f3fa,
+ 0x1f400, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+}; /* CR_So */
+
+/* 'Z': Major Category */
+static const OnigCodePoint CR_Z[] = {
+ 8,
+ 0x0020, 0x0020,
+ 0x00a0, 0x00a0,
+ 0x1680, 0x1680,
+ 0x2000, 0x200a,
+ 0x2028, 0x2029,
+ 0x202f, 0x202f,
+ 0x205f, 0x205f,
+ 0x3000, 0x3000,
+}; /* CR_Z */
+
+/* 'Zl': General Category */
+static const OnigCodePoint CR_Zl[] = {
+ 1,
+ 0x2028, 0x2028,
+}; /* CR_Zl */
+
+/* 'Zp': General Category */
+static const OnigCodePoint CR_Zp[] = {
+ 1,
+ 0x2029, 0x2029,
+}; /* CR_Zp */
+
+/* 'Zs': General Category */
+static const OnigCodePoint CR_Zs[] = {
+ 7,
+ 0x0020, 0x0020,
+ 0x00a0, 0x00a0,
+ 0x1680, 0x1680,
+ 0x2000, 0x200a,
+ 0x202f, 0x202f,
+ 0x205f, 0x205f,
+ 0x3000, 0x3000,
+}; /* CR_Zs */
+
+/* 'Math': Derived Property */
+static const OnigCodePoint CR_Math[] = {
+ 138,
+ 0x002b, 0x002b,
+ 0x003c, 0x003e,
+ 0x005e, 0x005e,
+ 0x007c, 0x007c,
+ 0x007e, 0x007e,
+ 0x00ac, 0x00ac,
+ 0x00b1, 0x00b1,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x03d0, 0x03d2,
+ 0x03d5, 0x03d5,
+ 0x03f0, 0x03f1,
+ 0x03f4, 0x03f6,
+ 0x0606, 0x0608,
+ 0x2016, 0x2016,
+ 0x2032, 0x2034,
+ 0x2040, 0x2040,
+ 0x2044, 0x2044,
+ 0x2052, 0x2052,
+ 0x2061, 0x2064,
+ 0x207a, 0x207e,
+ 0x208a, 0x208e,
+ 0x20d0, 0x20dc,
+ 0x20e1, 0x20e1,
+ 0x20e5, 0x20e6,
+ 0x20eb, 0x20ef,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2118, 0x211d,
+ 0x2124, 0x2124,
+ 0x2128, 0x2129,
+ 0x212c, 0x212d,
+ 0x212f, 0x2131,
+ 0x2133, 0x2138,
+ 0x213c, 0x2149,
+ 0x214b, 0x214b,
+ 0x2190, 0x21a7,
+ 0x21a9, 0x21ae,
+ 0x21b0, 0x21b1,
+ 0x21b6, 0x21b7,
+ 0x21bc, 0x21db,
+ 0x21dd, 0x21dd,
+ 0x21e4, 0x21e5,
+ 0x21f4, 0x22ff,
+ 0x2308, 0x230b,
+ 0x2320, 0x2321,
+ 0x237c, 0x237c,
+ 0x239b, 0x23b5,
+ 0x23b7, 0x23b7,
+ 0x23d0, 0x23d0,
+ 0x23dc, 0x23e2,
+ 0x25a0, 0x25a1,
+ 0x25ae, 0x25b7,
+ 0x25bc, 0x25c1,
+ 0x25c6, 0x25c7,
+ 0x25ca, 0x25cb,
+ 0x25cf, 0x25d3,
+ 0x25e2, 0x25e2,
+ 0x25e4, 0x25e4,
+ 0x25e7, 0x25ec,
+ 0x25f8, 0x25ff,
+ 0x2605, 0x2606,
+ 0x2640, 0x2640,
+ 0x2642, 0x2642,
+ 0x2660, 0x2663,
+ 0x266d, 0x266f,
+ 0x27c0, 0x27ff,
+ 0x2900, 0x2aff,
+ 0x2b30, 0x2b44,
+ 0x2b47, 0x2b4c,
+ 0xfb29, 0xfb29,
+ 0xfe61, 0xfe66,
+ 0xfe68, 0xfe68,
+ 0xff0b, 0xff0b,
+ 0xff1c, 0xff1e,
+ 0xff3c, 0xff3c,
+ 0xff3e, 0xff3e,
+ 0xff5c, 0xff5c,
+ 0xff5e, 0xff5e,
+ 0xffe2, 0xffe2,
+ 0xffe9, 0xffec,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+}; /* CR_Math */
+
+/* 'Alphabetic': Derived Property */
+#define CR_Alphabetic CR_Alpha
+
+/* 'Lowercase': Derived Property */
+#define CR_Lowercase CR_Lower
+
+/* 'Uppercase': Derived Property */
+#define CR_Uppercase CR_Upper
+
+/* 'Cased': Derived Property */
+static const OnigCodePoint CR_Cased[] = {
+ 140,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x01ba,
+ 0x01bc, 0x01bf,
+ 0x01c4, 0x0293,
+ 0x0295, 0x02b8,
+ 0x02c0, 0x02c1,
+ 0x02e0, 0x02e4,
+ 0x0345, 0x0345,
+ 0x0370, 0x0373,
+ 0x0376, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0560, 0x0588,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fd, 0x10ff,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1d00, 0x1dbf,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2134,
+ 0x2139, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x217f,
+ 0x2183, 0x2184,
+ 0x24b6, 0x24e9,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0xa640, 0xa66d,
+ 0xa680, 0xa69d,
+ 0xa722, 0xa787,
+ 0xa78b, 0xa78e,
+ 0xa790, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f8, 0xa7fa,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0x10400, 0x1044f,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x118a0, 0x118df,
+ 0x16e40, 0x16e7f,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1e900, 0x1e943,
+ 0x1f130, 0x1f149,
+ 0x1f150, 0x1f169,
+ 0x1f170, 0x1f189,
+}; /* CR_Cased */
+
+/* 'Case_Ignorable': Derived Property */
+static const OnigCodePoint CR_Case_Ignorable[] = {
+ 401,
+ 0x0027, 0x0027,
+ 0x002e, 0x002e,
+ 0x003a, 0x003a,
+ 0x005e, 0x005e,
+ 0x0060, 0x0060,
+ 0x00a8, 0x00a8,
+ 0x00ad, 0x00ad,
+ 0x00af, 0x00af,
+ 0x00b4, 0x00b4,
+ 0x00b7, 0x00b8,
+ 0x02b0, 0x036f,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x0384, 0x0385,
+ 0x0387, 0x0387,
+ 0x0483, 0x0489,
+ 0x0559, 0x0559,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x05f4, 0x05f4,
+ 0x0600, 0x0605,
+ 0x0610, 0x061a,
+ 0x061c, 0x061c,
+ 0x0640, 0x0640,
+ 0x064b, 0x065f,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dd,
+ 0x06df, 0x06e8,
+ 0x06ea, 0x06ed,
+ 0x070f, 0x070f,
+ 0x0711, 0x0711,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x07eb, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x07fd, 0x07fd,
+ 0x0816, 0x082d,
+ 0x0859, 0x085b,
+ 0x08d3, 0x0902,
+ 0x093a, 0x093a,
+ 0x093c, 0x093c,
+ 0x0941, 0x0948,
+ 0x094d, 0x094d,
+ 0x0951, 0x0957,
+ 0x0962, 0x0963,
+ 0x0971, 0x0971,
+ 0x0981, 0x0981,
+ 0x09bc, 0x09bc,
+ 0x09c1, 0x09c4,
+ 0x09cd, 0x09cd,
+ 0x09e2, 0x09e3,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a02,
+ 0x0a3c, 0x0a3c,
+ 0x0a41, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a70, 0x0a71,
+ 0x0a75, 0x0a75,
+ 0x0a81, 0x0a82,
+ 0x0abc, 0x0abc,
+ 0x0ac1, 0x0ac5,
+ 0x0ac7, 0x0ac8,
+ 0x0acd, 0x0acd,
+ 0x0ae2, 0x0ae3,
+ 0x0afa, 0x0aff,
+ 0x0b01, 0x0b01,
+ 0x0b3c, 0x0b3c,
+ 0x0b3f, 0x0b3f,
+ 0x0b41, 0x0b44,
+ 0x0b4d, 0x0b4d,
+ 0x0b56, 0x0b56,
+ 0x0b62, 0x0b63,
+ 0x0b82, 0x0b82,
+ 0x0bc0, 0x0bc0,
+ 0x0bcd, 0x0bcd,
+ 0x0c00, 0x0c00,
+ 0x0c04, 0x0c04,
+ 0x0c3e, 0x0c40,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c62, 0x0c63,
+ 0x0c81, 0x0c81,
+ 0x0cbc, 0x0cbc,
+ 0x0cbf, 0x0cbf,
+ 0x0cc6, 0x0cc6,
+ 0x0ccc, 0x0ccd,
+ 0x0ce2, 0x0ce3,
+ 0x0d00, 0x0d01,
+ 0x0d3b, 0x0d3c,
+ 0x0d41, 0x0d44,
+ 0x0d4d, 0x0d4d,
+ 0x0d62, 0x0d63,
+ 0x0dca, 0x0dca,
+ 0x0dd2, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e46, 0x0e4e,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0ebc,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f71, 0x0f7e,
+ 0x0f80, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0f8d, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x102d, 0x1030,
+ 0x1032, 0x1037,
+ 0x1039, 0x103a,
+ 0x103d, 0x103e,
+ 0x1058, 0x1059,
+ 0x105e, 0x1060,
+ 0x1071, 0x1074,
+ 0x1082, 0x1082,
+ 0x1085, 0x1086,
+ 0x108d, 0x108d,
+ 0x109d, 0x109d,
+ 0x10fc, 0x10fc,
+ 0x135d, 0x135f,
+ 0x1712, 0x1714,
+ 0x1732, 0x1734,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b4, 0x17b5,
+ 0x17b7, 0x17bd,
+ 0x17c6, 0x17c6,
+ 0x17c9, 0x17d3,
+ 0x17d7, 0x17d7,
+ 0x17dd, 0x17dd,
+ 0x180b, 0x180e,
+ 0x1843, 0x1843,
+ 0x1885, 0x1886,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x1922,
+ 0x1927, 0x1928,
+ 0x1932, 0x1932,
+ 0x1939, 0x193b,
+ 0x1a17, 0x1a18,
+ 0x1a1b, 0x1a1b,
+ 0x1a56, 0x1a56,
+ 0x1a58, 0x1a5e,
+ 0x1a60, 0x1a60,
+ 0x1a62, 0x1a62,
+ 0x1a65, 0x1a6c,
+ 0x1a73, 0x1a7c,
+ 0x1a7f, 0x1a7f,
+ 0x1aa7, 0x1aa7,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b03,
+ 0x1b34, 0x1b34,
+ 0x1b36, 0x1b3a,
+ 0x1b3c, 0x1b3c,
+ 0x1b42, 0x1b42,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1b81,
+ 0x1ba2, 0x1ba5,
+ 0x1ba8, 0x1ba9,
+ 0x1bab, 0x1bad,
+ 0x1be6, 0x1be6,
+ 0x1be8, 0x1be9,
+ 0x1bed, 0x1bed,
+ 0x1bef, 0x1bf1,
+ 0x1c2c, 0x1c33,
+ 0x1c36, 0x1c37,
+ 0x1c78, 0x1c7d,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1ce0,
+ 0x1ce2, 0x1ce8,
+ 0x1ced, 0x1ced,
+ 0x1cf4, 0x1cf4,
+ 0x1cf8, 0x1cf9,
+ 0x1d2c, 0x1d6a,
+ 0x1d78, 0x1d78,
+ 0x1d9b, 0x1df9,
+ 0x1dfb, 0x1dff,
+ 0x1fbd, 0x1fbd,
+ 0x1fbf, 0x1fc1,
+ 0x1fcd, 0x1fcf,
+ 0x1fdd, 0x1fdf,
+ 0x1fed, 0x1fef,
+ 0x1ffd, 0x1ffe,
+ 0x200b, 0x200f,
+ 0x2018, 0x2019,
+ 0x2024, 0x2024,
+ 0x2027, 0x2027,
+ 0x202a, 0x202e,
+ 0x2060, 0x2064,
+ 0x2066, 0x206f,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x20d0, 0x20f0,
+ 0x2c7c, 0x2c7d,
+ 0x2cef, 0x2cf1,
+ 0x2d6f, 0x2d6f,
+ 0x2d7f, 0x2d7f,
+ 0x2de0, 0x2dff,
+ 0x2e2f, 0x2e2f,
+ 0x3005, 0x3005,
+ 0x302a, 0x302d,
+ 0x3031, 0x3035,
+ 0x303b, 0x303b,
+ 0x3099, 0x309e,
+ 0x30fc, 0x30fe,
+ 0xa015, 0xa015,
+ 0xa4f8, 0xa4fd,
+ 0xa60c, 0xa60c,
+ 0xa66f, 0xa672,
+ 0xa674, 0xa67d,
+ 0xa67f, 0xa67f,
+ 0xa69c, 0xa69f,
+ 0xa6f0, 0xa6f1,
+ 0xa700, 0xa721,
+ 0xa770, 0xa770,
+ 0xa788, 0xa78a,
+ 0xa7f8, 0xa7f9,
+ 0xa802, 0xa802,
+ 0xa806, 0xa806,
+ 0xa80b, 0xa80b,
+ 0xa825, 0xa826,
+ 0xa8c4, 0xa8c5,
+ 0xa8e0, 0xa8f1,
+ 0xa8ff, 0xa8ff,
+ 0xa926, 0xa92d,
+ 0xa947, 0xa951,
+ 0xa980, 0xa982,
+ 0xa9b3, 0xa9b3,
+ 0xa9b6, 0xa9b9,
+ 0xa9bc, 0xa9bd,
+ 0xa9cf, 0xa9cf,
+ 0xa9e5, 0xa9e6,
+ 0xaa29, 0xaa2e,
+ 0xaa31, 0xaa32,
+ 0xaa35, 0xaa36,
+ 0xaa43, 0xaa43,
+ 0xaa4c, 0xaa4c,
+ 0xaa70, 0xaa70,
+ 0xaa7c, 0xaa7c,
+ 0xaab0, 0xaab0,
+ 0xaab2, 0xaab4,
+ 0xaab7, 0xaab8,
+ 0xaabe, 0xaabf,
+ 0xaac1, 0xaac1,
+ 0xaadd, 0xaadd,
+ 0xaaec, 0xaaed,
+ 0xaaf3, 0xaaf4,
+ 0xaaf6, 0xaaf6,
+ 0xab5b, 0xab5f,
+ 0xabe5, 0xabe5,
+ 0xabe8, 0xabe8,
+ 0xabed, 0xabed,
+ 0xfb1e, 0xfb1e,
+ 0xfbb2, 0xfbc1,
+ 0xfe00, 0xfe0f,
+ 0xfe13, 0xfe13,
+ 0xfe20, 0xfe2f,
+ 0xfe52, 0xfe52,
+ 0xfe55, 0xfe55,
+ 0xfeff, 0xfeff,
+ 0xff07, 0xff07,
+ 0xff0e, 0xff0e,
+ 0xff1a, 0xff1a,
+ 0xff3e, 0xff3e,
+ 0xff40, 0xff40,
+ 0xff70, 0xff70,
+ 0xff9e, 0xff9f,
+ 0xffe3, 0xffe3,
+ 0xfff9, 0xfffb,
+ 0x101fd, 0x101fd,
+ 0x102e0, 0x102e0,
+ 0x10376, 0x1037a,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10ae5, 0x10ae6,
+ 0x10d24, 0x10d27,
+ 0x10f46, 0x10f50,
+ 0x11001, 0x11001,
+ 0x11038, 0x11046,
+ 0x1107f, 0x11081,
+ 0x110b3, 0x110b6,
+ 0x110b9, 0x110ba,
+ 0x110bd, 0x110bd,
+ 0x110cd, 0x110cd,
+ 0x11100, 0x11102,
+ 0x11127, 0x1112b,
+ 0x1112d, 0x11134,
+ 0x11173, 0x11173,
+ 0x11180, 0x11181,
+ 0x111b6, 0x111be,
+ 0x111c9, 0x111cc,
+ 0x1122f, 0x11231,
+ 0x11234, 0x11234,
+ 0x11236, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x112df, 0x112df,
+ 0x112e3, 0x112ea,
+ 0x11300, 0x11301,
+ 0x1133b, 0x1133c,
+ 0x11340, 0x11340,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11438, 0x1143f,
+ 0x11442, 0x11444,
+ 0x11446, 0x11446,
+ 0x1145e, 0x1145e,
+ 0x114b3, 0x114b8,
+ 0x114ba, 0x114ba,
+ 0x114bf, 0x114c0,
+ 0x114c2, 0x114c3,
+ 0x115b2, 0x115b5,
+ 0x115bc, 0x115bd,
+ 0x115bf, 0x115c0,
+ 0x115dc, 0x115dd,
+ 0x11633, 0x1163a,
+ 0x1163d, 0x1163d,
+ 0x1163f, 0x11640,
+ 0x116ab, 0x116ab,
+ 0x116ad, 0x116ad,
+ 0x116b0, 0x116b5,
+ 0x116b7, 0x116b7,
+ 0x1171d, 0x1171f,
+ 0x11722, 0x11725,
+ 0x11727, 0x1172b,
+ 0x1182f, 0x11837,
+ 0x11839, 0x1183a,
+ 0x119d4, 0x119d7,
+ 0x119da, 0x119db,
+ 0x119e0, 0x119e0,
+ 0x11a01, 0x11a0a,
+ 0x11a33, 0x11a38,
+ 0x11a3b, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a51, 0x11a56,
+ 0x11a59, 0x11a5b,
+ 0x11a8a, 0x11a96,
+ 0x11a98, 0x11a99,
+ 0x11c30, 0x11c36,
+ 0x11c38, 0x11c3d,
+ 0x11c3f, 0x11c3f,
+ 0x11c92, 0x11ca7,
+ 0x11caa, 0x11cb0,
+ 0x11cb2, 0x11cb3,
+ 0x11cb5, 0x11cb6,
+ 0x11d31, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d45,
+ 0x11d47, 0x11d47,
+ 0x11d90, 0x11d91,
+ 0x11d95, 0x11d95,
+ 0x11d97, 0x11d97,
+ 0x11ef3, 0x11ef4,
+ 0x13430, 0x13438,
+ 0x16af0, 0x16af4,
+ 0x16b30, 0x16b36,
+ 0x16b40, 0x16b43,
+ 0x16f4f, 0x16f4f,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x1bc9d, 0x1bc9e,
+ 0x1bca0, 0x1bca3,
+ 0x1d167, 0x1d169,
+ 0x1d173, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e130, 0x1e13d,
+ 0x1e2ec, 0x1e2ef,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e944, 0x1e94b,
+ 0x1f3fb, 0x1f3ff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+}; /* CR_Case_Ignorable */
+
+/* 'Changes_When_Lowercased': Derived Property */
+static const OnigCodePoint CR_Changes_When_Lowercased[] = {
+ 599,
+ 0x0041, 0x005a,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00de,
+ 0x0100, 0x0100,
+ 0x0102, 0x0102,
+ 0x0104, 0x0104,
+ 0x0106, 0x0106,
+ 0x0108, 0x0108,
+ 0x010a, 0x010a,
+ 0x010c, 0x010c,
+ 0x010e, 0x010e,
+ 0x0110, 0x0110,
+ 0x0112, 0x0112,
+ 0x0114, 0x0114,
+ 0x0116, 0x0116,
+ 0x0118, 0x0118,
+ 0x011a, 0x011a,
+ 0x011c, 0x011c,
+ 0x011e, 0x011e,
+ 0x0120, 0x0120,
+ 0x0122, 0x0122,
+ 0x0124, 0x0124,
+ 0x0126, 0x0126,
+ 0x0128, 0x0128,
+ 0x012a, 0x012a,
+ 0x012c, 0x012c,
+ 0x012e, 0x012e,
+ 0x0130, 0x0130,
+ 0x0132, 0x0132,
+ 0x0134, 0x0134,
+ 0x0136, 0x0136,
+ 0x0139, 0x0139,
+ 0x013b, 0x013b,
+ 0x013d, 0x013d,
+ 0x013f, 0x013f,
+ 0x0141, 0x0141,
+ 0x0143, 0x0143,
+ 0x0145, 0x0145,
+ 0x0147, 0x0147,
+ 0x014a, 0x014a,
+ 0x014c, 0x014c,
+ 0x014e, 0x014e,
+ 0x0150, 0x0150,
+ 0x0152, 0x0152,
+ 0x0154, 0x0154,
+ 0x0156, 0x0156,
+ 0x0158, 0x0158,
+ 0x015a, 0x015a,
+ 0x015c, 0x015c,
+ 0x015e, 0x015e,
+ 0x0160, 0x0160,
+ 0x0162, 0x0162,
+ 0x0164, 0x0164,
+ 0x0166, 0x0166,
+ 0x0168, 0x0168,
+ 0x016a, 0x016a,
+ 0x016c, 0x016c,
+ 0x016e, 0x016e,
+ 0x0170, 0x0170,
+ 0x0172, 0x0172,
+ 0x0174, 0x0174,
+ 0x0176, 0x0176,
+ 0x0178, 0x0179,
+ 0x017b, 0x017b,
+ 0x017d, 0x017d,
+ 0x0181, 0x0182,
+ 0x0184, 0x0184,
+ 0x0186, 0x0187,
+ 0x0189, 0x018b,
+ 0x018e, 0x0191,
+ 0x0193, 0x0194,
+ 0x0196, 0x0198,
+ 0x019c, 0x019d,
+ 0x019f, 0x01a0,
+ 0x01a2, 0x01a2,
+ 0x01a4, 0x01a4,
+ 0x01a6, 0x01a7,
+ 0x01a9, 0x01a9,
+ 0x01ac, 0x01ac,
+ 0x01ae, 0x01af,
+ 0x01b1, 0x01b3,
+ 0x01b5, 0x01b5,
+ 0x01b7, 0x01b8,
+ 0x01bc, 0x01bc,
+ 0x01c4, 0x01c5,
+ 0x01c7, 0x01c8,
+ 0x01ca, 0x01cb,
+ 0x01cd, 0x01cd,
+ 0x01cf, 0x01cf,
+ 0x01d1, 0x01d1,
+ 0x01d3, 0x01d3,
+ 0x01d5, 0x01d5,
+ 0x01d7, 0x01d7,
+ 0x01d9, 0x01d9,
+ 0x01db, 0x01db,
+ 0x01de, 0x01de,
+ 0x01e0, 0x01e0,
+ 0x01e2, 0x01e2,
+ 0x01e4, 0x01e4,
+ 0x01e6, 0x01e6,
+ 0x01e8, 0x01e8,
+ 0x01ea, 0x01ea,
+ 0x01ec, 0x01ec,
+ 0x01ee, 0x01ee,
+ 0x01f1, 0x01f2,
+ 0x01f4, 0x01f4,
+ 0x01f6, 0x01f8,
+ 0x01fa, 0x01fa,
+ 0x01fc, 0x01fc,
+ 0x01fe, 0x01fe,
+ 0x0200, 0x0200,
+ 0x0202, 0x0202,
+ 0x0204, 0x0204,
+ 0x0206, 0x0206,
+ 0x0208, 0x0208,
+ 0x020a, 0x020a,
+ 0x020c, 0x020c,
+ 0x020e, 0x020e,
+ 0x0210, 0x0210,
+ 0x0212, 0x0212,
+ 0x0214, 0x0214,
+ 0x0216, 0x0216,
+ 0x0218, 0x0218,
+ 0x021a, 0x021a,
+ 0x021c, 0x021c,
+ 0x021e, 0x021e,
+ 0x0220, 0x0220,
+ 0x0222, 0x0222,
+ 0x0224, 0x0224,
+ 0x0226, 0x0226,
+ 0x0228, 0x0228,
+ 0x022a, 0x022a,
+ 0x022c, 0x022c,
+ 0x022e, 0x022e,
+ 0x0230, 0x0230,
+ 0x0232, 0x0232,
+ 0x023a, 0x023b,
+ 0x023d, 0x023e,
+ 0x0241, 0x0241,
+ 0x0243, 0x0246,
+ 0x0248, 0x0248,
+ 0x024a, 0x024a,
+ 0x024c, 0x024c,
+ 0x024e, 0x024e,
+ 0x0370, 0x0370,
+ 0x0372, 0x0372,
+ 0x0376, 0x0376,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x038f,
+ 0x0391, 0x03a1,
+ 0x03a3, 0x03ab,
+ 0x03cf, 0x03cf,
+ 0x03d8, 0x03d8,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03e2,
+ 0x03e4, 0x03e4,
+ 0x03e6, 0x03e6,
+ 0x03e8, 0x03e8,
+ 0x03ea, 0x03ea,
+ 0x03ec, 0x03ec,
+ 0x03ee, 0x03ee,
+ 0x03f4, 0x03f4,
+ 0x03f7, 0x03f7,
+ 0x03f9, 0x03fa,
+ 0x03fd, 0x042f,
+ 0x0460, 0x0460,
+ 0x0462, 0x0462,
+ 0x0464, 0x0464,
+ 0x0466, 0x0466,
+ 0x0468, 0x0468,
+ 0x046a, 0x046a,
+ 0x046c, 0x046c,
+ 0x046e, 0x046e,
+ 0x0470, 0x0470,
+ 0x0472, 0x0472,
+ 0x0474, 0x0474,
+ 0x0476, 0x0476,
+ 0x0478, 0x0478,
+ 0x047a, 0x047a,
+ 0x047c, 0x047c,
+ 0x047e, 0x047e,
+ 0x0480, 0x0480,
+ 0x048a, 0x048a,
+ 0x048c, 0x048c,
+ 0x048e, 0x048e,
+ 0x0490, 0x0490,
+ 0x0492, 0x0492,
+ 0x0494, 0x0494,
+ 0x0496, 0x0496,
+ 0x0498, 0x0498,
+ 0x049a, 0x049a,
+ 0x049c, 0x049c,
+ 0x049e, 0x049e,
+ 0x04a0, 0x04a0,
+ 0x04a2, 0x04a2,
+ 0x04a4, 0x04a4,
+ 0x04a6, 0x04a6,
+ 0x04a8, 0x04a8,
+ 0x04aa, 0x04aa,
+ 0x04ac, 0x04ac,
+ 0x04ae, 0x04ae,
+ 0x04b0, 0x04b0,
+ 0x04b2, 0x04b2,
+ 0x04b4, 0x04b4,
+ 0x04b6, 0x04b6,
+ 0x04b8, 0x04b8,
+ 0x04ba, 0x04ba,
+ 0x04bc, 0x04bc,
+ 0x04be, 0x04be,
+ 0x04c0, 0x04c1,
+ 0x04c3, 0x04c3,
+ 0x04c5, 0x04c5,
+ 0x04c7, 0x04c7,
+ 0x04c9, 0x04c9,
+ 0x04cb, 0x04cb,
+ 0x04cd, 0x04cd,
+ 0x04d0, 0x04d0,
+ 0x04d2, 0x04d2,
+ 0x04d4, 0x04d4,
+ 0x04d6, 0x04d6,
+ 0x04d8, 0x04d8,
+ 0x04da, 0x04da,
+ 0x04dc, 0x04dc,
+ 0x04de, 0x04de,
+ 0x04e0, 0x04e0,
+ 0x04e2, 0x04e2,
+ 0x04e4, 0x04e4,
+ 0x04e6, 0x04e6,
+ 0x04e8, 0x04e8,
+ 0x04ea, 0x04ea,
+ 0x04ec, 0x04ec,
+ 0x04ee, 0x04ee,
+ 0x04f0, 0x04f0,
+ 0x04f2, 0x04f2,
+ 0x04f4, 0x04f4,
+ 0x04f6, 0x04f6,
+ 0x04f8, 0x04f8,
+ 0x04fa, 0x04fa,
+ 0x04fc, 0x04fc,
+ 0x04fe, 0x04fe,
+ 0x0500, 0x0500,
+ 0x0502, 0x0502,
+ 0x0504, 0x0504,
+ 0x0506, 0x0506,
+ 0x0508, 0x0508,
+ 0x050a, 0x050a,
+ 0x050c, 0x050c,
+ 0x050e, 0x050e,
+ 0x0510, 0x0510,
+ 0x0512, 0x0512,
+ 0x0514, 0x0514,
+ 0x0516, 0x0516,
+ 0x0518, 0x0518,
+ 0x051a, 0x051a,
+ 0x051c, 0x051c,
+ 0x051e, 0x051e,
+ 0x0520, 0x0520,
+ 0x0522, 0x0522,
+ 0x0524, 0x0524,
+ 0x0526, 0x0526,
+ 0x0528, 0x0528,
+ 0x052a, 0x052a,
+ 0x052c, 0x052c,
+ 0x052e, 0x052e,
+ 0x0531, 0x0556,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x13a0, 0x13f5,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1e00, 0x1e00,
+ 0x1e02, 0x1e02,
+ 0x1e04, 0x1e04,
+ 0x1e06, 0x1e06,
+ 0x1e08, 0x1e08,
+ 0x1e0a, 0x1e0a,
+ 0x1e0c, 0x1e0c,
+ 0x1e0e, 0x1e0e,
+ 0x1e10, 0x1e10,
+ 0x1e12, 0x1e12,
+ 0x1e14, 0x1e14,
+ 0x1e16, 0x1e16,
+ 0x1e18, 0x1e18,
+ 0x1e1a, 0x1e1a,
+ 0x1e1c, 0x1e1c,
+ 0x1e1e, 0x1e1e,
+ 0x1e20, 0x1e20,
+ 0x1e22, 0x1e22,
+ 0x1e24, 0x1e24,
+ 0x1e26, 0x1e26,
+ 0x1e28, 0x1e28,
+ 0x1e2a, 0x1e2a,
+ 0x1e2c, 0x1e2c,
+ 0x1e2e, 0x1e2e,
+ 0x1e30, 0x1e30,
+ 0x1e32, 0x1e32,
+ 0x1e34, 0x1e34,
+ 0x1e36, 0x1e36,
+ 0x1e38, 0x1e38,
+ 0x1e3a, 0x1e3a,
+ 0x1e3c, 0x1e3c,
+ 0x1e3e, 0x1e3e,
+ 0x1e40, 0x1e40,
+ 0x1e42, 0x1e42,
+ 0x1e44, 0x1e44,
+ 0x1e46, 0x1e46,
+ 0x1e48, 0x1e48,
+ 0x1e4a, 0x1e4a,
+ 0x1e4c, 0x1e4c,
+ 0x1e4e, 0x1e4e,
+ 0x1e50, 0x1e50,
+ 0x1e52, 0x1e52,
+ 0x1e54, 0x1e54,
+ 0x1e56, 0x1e56,
+ 0x1e58, 0x1e58,
+ 0x1e5a, 0x1e5a,
+ 0x1e5c, 0x1e5c,
+ 0x1e5e, 0x1e5e,
+ 0x1e60, 0x1e60,
+ 0x1e62, 0x1e62,
+ 0x1e64, 0x1e64,
+ 0x1e66, 0x1e66,
+ 0x1e68, 0x1e68,
+ 0x1e6a, 0x1e6a,
+ 0x1e6c, 0x1e6c,
+ 0x1e6e, 0x1e6e,
+ 0x1e70, 0x1e70,
+ 0x1e72, 0x1e72,
+ 0x1e74, 0x1e74,
+ 0x1e76, 0x1e76,
+ 0x1e78, 0x1e78,
+ 0x1e7a, 0x1e7a,
+ 0x1e7c, 0x1e7c,
+ 0x1e7e, 0x1e7e,
+ 0x1e80, 0x1e80,
+ 0x1e82, 0x1e82,
+ 0x1e84, 0x1e84,
+ 0x1e86, 0x1e86,
+ 0x1e88, 0x1e88,
+ 0x1e8a, 0x1e8a,
+ 0x1e8c, 0x1e8c,
+ 0x1e8e, 0x1e8e,
+ 0x1e90, 0x1e90,
+ 0x1e92, 0x1e92,
+ 0x1e94, 0x1e94,
+ 0x1e9e, 0x1e9e,
+ 0x1ea0, 0x1ea0,
+ 0x1ea2, 0x1ea2,
+ 0x1ea4, 0x1ea4,
+ 0x1ea6, 0x1ea6,
+ 0x1ea8, 0x1ea8,
+ 0x1eaa, 0x1eaa,
+ 0x1eac, 0x1eac,
+ 0x1eae, 0x1eae,
+ 0x1eb0, 0x1eb0,
+ 0x1eb2, 0x1eb2,
+ 0x1eb4, 0x1eb4,
+ 0x1eb6, 0x1eb6,
+ 0x1eb8, 0x1eb8,
+ 0x1eba, 0x1eba,
+ 0x1ebc, 0x1ebc,
+ 0x1ebe, 0x1ebe,
+ 0x1ec0, 0x1ec0,
+ 0x1ec2, 0x1ec2,
+ 0x1ec4, 0x1ec4,
+ 0x1ec6, 0x1ec6,
+ 0x1ec8, 0x1ec8,
+ 0x1eca, 0x1eca,
+ 0x1ecc, 0x1ecc,
+ 0x1ece, 0x1ece,
+ 0x1ed0, 0x1ed0,
+ 0x1ed2, 0x1ed2,
+ 0x1ed4, 0x1ed4,
+ 0x1ed6, 0x1ed6,
+ 0x1ed8, 0x1ed8,
+ 0x1eda, 0x1eda,
+ 0x1edc, 0x1edc,
+ 0x1ede, 0x1ede,
+ 0x1ee0, 0x1ee0,
+ 0x1ee2, 0x1ee2,
+ 0x1ee4, 0x1ee4,
+ 0x1ee6, 0x1ee6,
+ 0x1ee8, 0x1ee8,
+ 0x1eea, 0x1eea,
+ 0x1eec, 0x1eec,
+ 0x1eee, 0x1eee,
+ 0x1ef0, 0x1ef0,
+ 0x1ef2, 0x1ef2,
+ 0x1ef4, 0x1ef4,
+ 0x1ef6, 0x1ef6,
+ 0x1ef8, 0x1ef8,
+ 0x1efa, 0x1efa,
+ 0x1efc, 0x1efc,
+ 0x1efe, 0x1efe,
+ 0x1f08, 0x1f0f,
+ 0x1f18, 0x1f1d,
+ 0x1f28, 0x1f2f,
+ 0x1f38, 0x1f3f,
+ 0x1f48, 0x1f4d,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f5f,
+ 0x1f68, 0x1f6f,
+ 0x1f88, 0x1f8f,
+ 0x1f98, 0x1f9f,
+ 0x1fa8, 0x1faf,
+ 0x1fb8, 0x1fbc,
+ 0x1fc8, 0x1fcc,
+ 0x1fd8, 0x1fdb,
+ 0x1fe8, 0x1fec,
+ 0x1ff8, 0x1ffc,
+ 0x2126, 0x2126,
+ 0x212a, 0x212b,
+ 0x2132, 0x2132,
+ 0x2160, 0x216f,
+ 0x2183, 0x2183,
+ 0x24b6, 0x24cf,
+ 0x2c00, 0x2c2e,
+ 0x2c60, 0x2c60,
+ 0x2c62, 0x2c64,
+ 0x2c67, 0x2c67,
+ 0x2c69, 0x2c69,
+ 0x2c6b, 0x2c6b,
+ 0x2c6d, 0x2c70,
+ 0x2c72, 0x2c72,
+ 0x2c75, 0x2c75,
+ 0x2c7e, 0x2c80,
+ 0x2c82, 0x2c82,
+ 0x2c84, 0x2c84,
+ 0x2c86, 0x2c86,
+ 0x2c88, 0x2c88,
+ 0x2c8a, 0x2c8a,
+ 0x2c8c, 0x2c8c,
+ 0x2c8e, 0x2c8e,
+ 0x2c90, 0x2c90,
+ 0x2c92, 0x2c92,
+ 0x2c94, 0x2c94,
+ 0x2c96, 0x2c96,
+ 0x2c98, 0x2c98,
+ 0x2c9a, 0x2c9a,
+ 0x2c9c, 0x2c9c,
+ 0x2c9e, 0x2c9e,
+ 0x2ca0, 0x2ca0,
+ 0x2ca2, 0x2ca2,
+ 0x2ca4, 0x2ca4,
+ 0x2ca6, 0x2ca6,
+ 0x2ca8, 0x2ca8,
+ 0x2caa, 0x2caa,
+ 0x2cac, 0x2cac,
+ 0x2cae, 0x2cae,
+ 0x2cb0, 0x2cb0,
+ 0x2cb2, 0x2cb2,
+ 0x2cb4, 0x2cb4,
+ 0x2cb6, 0x2cb6,
+ 0x2cb8, 0x2cb8,
+ 0x2cba, 0x2cba,
+ 0x2cbc, 0x2cbc,
+ 0x2cbe, 0x2cbe,
+ 0x2cc0, 0x2cc0,
+ 0x2cc2, 0x2cc2,
+ 0x2cc4, 0x2cc4,
+ 0x2cc6, 0x2cc6,
+ 0x2cc8, 0x2cc8,
+ 0x2cca, 0x2cca,
+ 0x2ccc, 0x2ccc,
+ 0x2cce, 0x2cce,
+ 0x2cd0, 0x2cd0,
+ 0x2cd2, 0x2cd2,
+ 0x2cd4, 0x2cd4,
+ 0x2cd6, 0x2cd6,
+ 0x2cd8, 0x2cd8,
+ 0x2cda, 0x2cda,
+ 0x2cdc, 0x2cdc,
+ 0x2cde, 0x2cde,
+ 0x2ce0, 0x2ce0,
+ 0x2ce2, 0x2ce2,
+ 0x2ceb, 0x2ceb,
+ 0x2ced, 0x2ced,
+ 0x2cf2, 0x2cf2,
+ 0xa640, 0xa640,
+ 0xa642, 0xa642,
+ 0xa644, 0xa644,
+ 0xa646, 0xa646,
+ 0xa648, 0xa648,
+ 0xa64a, 0xa64a,
+ 0xa64c, 0xa64c,
+ 0xa64e, 0xa64e,
+ 0xa650, 0xa650,
+ 0xa652, 0xa652,
+ 0xa654, 0xa654,
+ 0xa656, 0xa656,
+ 0xa658, 0xa658,
+ 0xa65a, 0xa65a,
+ 0xa65c, 0xa65c,
+ 0xa65e, 0xa65e,
+ 0xa660, 0xa660,
+ 0xa662, 0xa662,
+ 0xa664, 0xa664,
+ 0xa666, 0xa666,
+ 0xa668, 0xa668,
+ 0xa66a, 0xa66a,
+ 0xa66c, 0xa66c,
+ 0xa680, 0xa680,
+ 0xa682, 0xa682,
+ 0xa684, 0xa684,
+ 0xa686, 0xa686,
+ 0xa688, 0xa688,
+ 0xa68a, 0xa68a,
+ 0xa68c, 0xa68c,
+ 0xa68e, 0xa68e,
+ 0xa690, 0xa690,
+ 0xa692, 0xa692,
+ 0xa694, 0xa694,
+ 0xa696, 0xa696,
+ 0xa698, 0xa698,
+ 0xa69a, 0xa69a,
+ 0xa722, 0xa722,
+ 0xa724, 0xa724,
+ 0xa726, 0xa726,
+ 0xa728, 0xa728,
+ 0xa72a, 0xa72a,
+ 0xa72c, 0xa72c,
+ 0xa72e, 0xa72e,
+ 0xa732, 0xa732,
+ 0xa734, 0xa734,
+ 0xa736, 0xa736,
+ 0xa738, 0xa738,
+ 0xa73a, 0xa73a,
+ 0xa73c, 0xa73c,
+ 0xa73e, 0xa73e,
+ 0xa740, 0xa740,
+ 0xa742, 0xa742,
+ 0xa744, 0xa744,
+ 0xa746, 0xa746,
+ 0xa748, 0xa748,
+ 0xa74a, 0xa74a,
+ 0xa74c, 0xa74c,
+ 0xa74e, 0xa74e,
+ 0xa750, 0xa750,
+ 0xa752, 0xa752,
+ 0xa754, 0xa754,
+ 0xa756, 0xa756,
+ 0xa758, 0xa758,
+ 0xa75a, 0xa75a,
+ 0xa75c, 0xa75c,
+ 0xa75e, 0xa75e,
+ 0xa760, 0xa760,
+ 0xa762, 0xa762,
+ 0xa764, 0xa764,
+ 0xa766, 0xa766,
+ 0xa768, 0xa768,
+ 0xa76a, 0xa76a,
+ 0xa76c, 0xa76c,
+ 0xa76e, 0xa76e,
+ 0xa779, 0xa779,
+ 0xa77b, 0xa77b,
+ 0xa77d, 0xa77e,
+ 0xa780, 0xa780,
+ 0xa782, 0xa782,
+ 0xa784, 0xa784,
+ 0xa786, 0xa786,
+ 0xa78b, 0xa78b,
+ 0xa78d, 0xa78d,
+ 0xa790, 0xa790,
+ 0xa792, 0xa792,
+ 0xa796, 0xa796,
+ 0xa798, 0xa798,
+ 0xa79a, 0xa79a,
+ 0xa79c, 0xa79c,
+ 0xa79e, 0xa79e,
+ 0xa7a0, 0xa7a0,
+ 0xa7a2, 0xa7a2,
+ 0xa7a4, 0xa7a4,
+ 0xa7a6, 0xa7a6,
+ 0xa7a8, 0xa7a8,
+ 0xa7aa, 0xa7ae,
+ 0xa7b0, 0xa7b4,
+ 0xa7b6, 0xa7b6,
+ 0xa7b8, 0xa7b8,
+ 0xa7ba, 0xa7ba,
+ 0xa7bc, 0xa7bc,
+ 0xa7be, 0xa7be,
+ 0xa7c2, 0xa7c2,
+ 0xa7c4, 0xa7c6,
+ 0xff21, 0xff3a,
+ 0x10400, 0x10427,
+ 0x104b0, 0x104d3,
+ 0x10c80, 0x10cb2,
+ 0x118a0, 0x118bf,
+ 0x16e40, 0x16e5f,
+ 0x1e900, 0x1e921,
+}; /* CR_Changes_When_Lowercased */
+
+/* 'Changes_When_Uppercased': Derived Property */
+static const OnigCodePoint CR_Changes_When_Uppercased[] = {
+ 616,
+ 0x0061, 0x007a,
+ 0x00b5, 0x00b5,
+ 0x00df, 0x00f6,
+ 0x00f8, 0x00ff,
+ 0x0101, 0x0101,
+ 0x0103, 0x0103,
+ 0x0105, 0x0105,
+ 0x0107, 0x0107,
+ 0x0109, 0x0109,
+ 0x010b, 0x010b,
+ 0x010d, 0x010d,
+ 0x010f, 0x010f,
+ 0x0111, 0x0111,
+ 0x0113, 0x0113,
+ 0x0115, 0x0115,
+ 0x0117, 0x0117,
+ 0x0119, 0x0119,
+ 0x011b, 0x011b,
+ 0x011d, 0x011d,
+ 0x011f, 0x011f,
+ 0x0121, 0x0121,
+ 0x0123, 0x0123,
+ 0x0125, 0x0125,
+ 0x0127, 0x0127,
+ 0x0129, 0x0129,
+ 0x012b, 0x012b,
+ 0x012d, 0x012d,
+ 0x012f, 0x012f,
+ 0x0131, 0x0131,
+ 0x0133, 0x0133,
+ 0x0135, 0x0135,
+ 0x0137, 0x0137,
+ 0x013a, 0x013a,
+ 0x013c, 0x013c,
+ 0x013e, 0x013e,
+ 0x0140, 0x0140,
+ 0x0142, 0x0142,
+ 0x0144, 0x0144,
+ 0x0146, 0x0146,
+ 0x0148, 0x0149,
+ 0x014b, 0x014b,
+ 0x014d, 0x014d,
+ 0x014f, 0x014f,
+ 0x0151, 0x0151,
+ 0x0153, 0x0153,
+ 0x0155, 0x0155,
+ 0x0157, 0x0157,
+ 0x0159, 0x0159,
+ 0x015b, 0x015b,
+ 0x015d, 0x015d,
+ 0x015f, 0x015f,
+ 0x0161, 0x0161,
+ 0x0163, 0x0163,
+ 0x0165, 0x0165,
+ 0x0167, 0x0167,
+ 0x0169, 0x0169,
+ 0x016b, 0x016b,
+ 0x016d, 0x016d,
+ 0x016f, 0x016f,
+ 0x0171, 0x0171,
+ 0x0173, 0x0173,
+ 0x0175, 0x0175,
+ 0x0177, 0x0177,
+ 0x017a, 0x017a,
+ 0x017c, 0x017c,
+ 0x017e, 0x0180,
+ 0x0183, 0x0183,
+ 0x0185, 0x0185,
+ 0x0188, 0x0188,
+ 0x018c, 0x018c,
+ 0x0192, 0x0192,
+ 0x0195, 0x0195,
+ 0x0199, 0x019a,
+ 0x019e, 0x019e,
+ 0x01a1, 0x01a1,
+ 0x01a3, 0x01a3,
+ 0x01a5, 0x01a5,
+ 0x01a8, 0x01a8,
+ 0x01ad, 0x01ad,
+ 0x01b0, 0x01b0,
+ 0x01b4, 0x01b4,
+ 0x01b6, 0x01b6,
+ 0x01b9, 0x01b9,
+ 0x01bd, 0x01bd,
+ 0x01bf, 0x01bf,
+ 0x01c5, 0x01c6,
+ 0x01c8, 0x01c9,
+ 0x01cb, 0x01cc,
+ 0x01ce, 0x01ce,
+ 0x01d0, 0x01d0,
+ 0x01d2, 0x01d2,
+ 0x01d4, 0x01d4,
+ 0x01d6, 0x01d6,
+ 0x01d8, 0x01d8,
+ 0x01da, 0x01da,
+ 0x01dc, 0x01dd,
+ 0x01df, 0x01df,
+ 0x01e1, 0x01e1,
+ 0x01e3, 0x01e3,
+ 0x01e5, 0x01e5,
+ 0x01e7, 0x01e7,
+ 0x01e9, 0x01e9,
+ 0x01eb, 0x01eb,
+ 0x01ed, 0x01ed,
+ 0x01ef, 0x01f0,
+ 0x01f2, 0x01f3,
+ 0x01f5, 0x01f5,
+ 0x01f9, 0x01f9,
+ 0x01fb, 0x01fb,
+ 0x01fd, 0x01fd,
+ 0x01ff, 0x01ff,
+ 0x0201, 0x0201,
+ 0x0203, 0x0203,
+ 0x0205, 0x0205,
+ 0x0207, 0x0207,
+ 0x0209, 0x0209,
+ 0x020b, 0x020b,
+ 0x020d, 0x020d,
+ 0x020f, 0x020f,
+ 0x0211, 0x0211,
+ 0x0213, 0x0213,
+ 0x0215, 0x0215,
+ 0x0217, 0x0217,
+ 0x0219, 0x0219,
+ 0x021b, 0x021b,
+ 0x021d, 0x021d,
+ 0x021f, 0x021f,
+ 0x0223, 0x0223,
+ 0x0225, 0x0225,
+ 0x0227, 0x0227,
+ 0x0229, 0x0229,
+ 0x022b, 0x022b,
+ 0x022d, 0x022d,
+ 0x022f, 0x022f,
+ 0x0231, 0x0231,
+ 0x0233, 0x0233,
+ 0x023c, 0x023c,
+ 0x023f, 0x0240,
+ 0x0242, 0x0242,
+ 0x0247, 0x0247,
+ 0x0249, 0x0249,
+ 0x024b, 0x024b,
+ 0x024d, 0x024d,
+ 0x024f, 0x0254,
+ 0x0256, 0x0257,
+ 0x0259, 0x0259,
+ 0x025b, 0x025c,
+ 0x0260, 0x0261,
+ 0x0263, 0x0263,
+ 0x0265, 0x0266,
+ 0x0268, 0x026c,
+ 0x026f, 0x026f,
+ 0x0271, 0x0272,
+ 0x0275, 0x0275,
+ 0x027d, 0x027d,
+ 0x0280, 0x0280,
+ 0x0282, 0x0283,
+ 0x0287, 0x028c,
+ 0x0292, 0x0292,
+ 0x029d, 0x029e,
+ 0x0345, 0x0345,
+ 0x0371, 0x0371,
+ 0x0373, 0x0373,
+ 0x0377, 0x0377,
+ 0x037b, 0x037d,
+ 0x0390, 0x0390,
+ 0x03ac, 0x03ce,
+ 0x03d0, 0x03d1,
+ 0x03d5, 0x03d7,
+ 0x03d9, 0x03d9,
+ 0x03db, 0x03db,
+ 0x03dd, 0x03dd,
+ 0x03df, 0x03df,
+ 0x03e1, 0x03e1,
+ 0x03e3, 0x03e3,
+ 0x03e5, 0x03e5,
+ 0x03e7, 0x03e7,
+ 0x03e9, 0x03e9,
+ 0x03eb, 0x03eb,
+ 0x03ed, 0x03ed,
+ 0x03ef, 0x03f3,
+ 0x03f5, 0x03f5,
+ 0x03f8, 0x03f8,
+ 0x03fb, 0x03fb,
+ 0x0430, 0x045f,
+ 0x0461, 0x0461,
+ 0x0463, 0x0463,
+ 0x0465, 0x0465,
+ 0x0467, 0x0467,
+ 0x0469, 0x0469,
+ 0x046b, 0x046b,
+ 0x046d, 0x046d,
+ 0x046f, 0x046f,
+ 0x0471, 0x0471,
+ 0x0473, 0x0473,
+ 0x0475, 0x0475,
+ 0x0477, 0x0477,
+ 0x0479, 0x0479,
+ 0x047b, 0x047b,
+ 0x047d, 0x047d,
+ 0x047f, 0x047f,
+ 0x0481, 0x0481,
+ 0x048b, 0x048b,
+ 0x048d, 0x048d,
+ 0x048f, 0x048f,
+ 0x0491, 0x0491,
+ 0x0493, 0x0493,
+ 0x0495, 0x0495,
+ 0x0497, 0x0497,
+ 0x0499, 0x0499,
+ 0x049b, 0x049b,
+ 0x049d, 0x049d,
+ 0x049f, 0x049f,
+ 0x04a1, 0x04a1,
+ 0x04a3, 0x04a3,
+ 0x04a5, 0x04a5,
+ 0x04a7, 0x04a7,
+ 0x04a9, 0x04a9,
+ 0x04ab, 0x04ab,
+ 0x04ad, 0x04ad,
+ 0x04af, 0x04af,
+ 0x04b1, 0x04b1,
+ 0x04b3, 0x04b3,
+ 0x04b5, 0x04b5,
+ 0x04b7, 0x04b7,
+ 0x04b9, 0x04b9,
+ 0x04bb, 0x04bb,
+ 0x04bd, 0x04bd,
+ 0x04bf, 0x04bf,
+ 0x04c2, 0x04c2,
+ 0x04c4, 0x04c4,
+ 0x04c6, 0x04c6,
+ 0x04c8, 0x04c8,
+ 0x04ca, 0x04ca,
+ 0x04cc, 0x04cc,
+ 0x04ce, 0x04cf,
+ 0x04d1, 0x04d1,
+ 0x04d3, 0x04d3,
+ 0x04d5, 0x04d5,
+ 0x04d7, 0x04d7,
+ 0x04d9, 0x04d9,
+ 0x04db, 0x04db,
+ 0x04dd, 0x04dd,
+ 0x04df, 0x04df,
+ 0x04e1, 0x04e1,
+ 0x04e3, 0x04e3,
+ 0x04e5, 0x04e5,
+ 0x04e7, 0x04e7,
+ 0x04e9, 0x04e9,
+ 0x04eb, 0x04eb,
+ 0x04ed, 0x04ed,
+ 0x04ef, 0x04ef,
+ 0x04f1, 0x04f1,
+ 0x04f3, 0x04f3,
+ 0x04f5, 0x04f5,
+ 0x04f7, 0x04f7,
+ 0x04f9, 0x04f9,
+ 0x04fb, 0x04fb,
+ 0x04fd, 0x04fd,
+ 0x04ff, 0x04ff,
+ 0x0501, 0x0501,
+ 0x0503, 0x0503,
+ 0x0505, 0x0505,
+ 0x0507, 0x0507,
+ 0x0509, 0x0509,
+ 0x050b, 0x050b,
+ 0x050d, 0x050d,
+ 0x050f, 0x050f,
+ 0x0511, 0x0511,
+ 0x0513, 0x0513,
+ 0x0515, 0x0515,
+ 0x0517, 0x0517,
+ 0x0519, 0x0519,
+ 0x051b, 0x051b,
+ 0x051d, 0x051d,
+ 0x051f, 0x051f,
+ 0x0521, 0x0521,
+ 0x0523, 0x0523,
+ 0x0525, 0x0525,
+ 0x0527, 0x0527,
+ 0x0529, 0x0529,
+ 0x052b, 0x052b,
+ 0x052d, 0x052d,
+ 0x052f, 0x052f,
+ 0x0561, 0x0587,
+ 0x10d0, 0x10fa,
+ 0x10fd, 0x10ff,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1d79, 0x1d79,
+ 0x1d7d, 0x1d7d,
+ 0x1d8e, 0x1d8e,
+ 0x1e01, 0x1e01,
+ 0x1e03, 0x1e03,
+ 0x1e05, 0x1e05,
+ 0x1e07, 0x1e07,
+ 0x1e09, 0x1e09,
+ 0x1e0b, 0x1e0b,
+ 0x1e0d, 0x1e0d,
+ 0x1e0f, 0x1e0f,
+ 0x1e11, 0x1e11,
+ 0x1e13, 0x1e13,
+ 0x1e15, 0x1e15,
+ 0x1e17, 0x1e17,
+ 0x1e19, 0x1e19,
+ 0x1e1b, 0x1e1b,
+ 0x1e1d, 0x1e1d,
+ 0x1e1f, 0x1e1f,
+ 0x1e21, 0x1e21,
+ 0x1e23, 0x1e23,
+ 0x1e25, 0x1e25,
+ 0x1e27, 0x1e27,
+ 0x1e29, 0x1e29,
+ 0x1e2b, 0x1e2b,
+ 0x1e2d, 0x1e2d,
+ 0x1e2f, 0x1e2f,
+ 0x1e31, 0x1e31,
+ 0x1e33, 0x1e33,
+ 0x1e35, 0x1e35,
+ 0x1e37, 0x1e37,
+ 0x1e39, 0x1e39,
+ 0x1e3b, 0x1e3b,
+ 0x1e3d, 0x1e3d,
+ 0x1e3f, 0x1e3f,
+ 0x1e41, 0x1e41,
+ 0x1e43, 0x1e43,
+ 0x1e45, 0x1e45,
+ 0x1e47, 0x1e47,
+ 0x1e49, 0x1e49,
+ 0x1e4b, 0x1e4b,
+ 0x1e4d, 0x1e4d,
+ 0x1e4f, 0x1e4f,
+ 0x1e51, 0x1e51,
+ 0x1e53, 0x1e53,
+ 0x1e55, 0x1e55,
+ 0x1e57, 0x1e57,
+ 0x1e59, 0x1e59,
+ 0x1e5b, 0x1e5b,
+ 0x1e5d, 0x1e5d,
+ 0x1e5f, 0x1e5f,
+ 0x1e61, 0x1e61,
+ 0x1e63, 0x1e63,
+ 0x1e65, 0x1e65,
+ 0x1e67, 0x1e67,
+ 0x1e69, 0x1e69,
+ 0x1e6b, 0x1e6b,
+ 0x1e6d, 0x1e6d,
+ 0x1e6f, 0x1e6f,
+ 0x1e71, 0x1e71,
+ 0x1e73, 0x1e73,
+ 0x1e75, 0x1e75,
+ 0x1e77, 0x1e77,
+ 0x1e79, 0x1e79,
+ 0x1e7b, 0x1e7b,
+ 0x1e7d, 0x1e7d,
+ 0x1e7f, 0x1e7f,
+ 0x1e81, 0x1e81,
+ 0x1e83, 0x1e83,
+ 0x1e85, 0x1e85,
+ 0x1e87, 0x1e87,
+ 0x1e89, 0x1e89,
+ 0x1e8b, 0x1e8b,
+ 0x1e8d, 0x1e8d,
+ 0x1e8f, 0x1e8f,
+ 0x1e91, 0x1e91,
+ 0x1e93, 0x1e93,
+ 0x1e95, 0x1e9b,
+ 0x1ea1, 0x1ea1,
+ 0x1ea3, 0x1ea3,
+ 0x1ea5, 0x1ea5,
+ 0x1ea7, 0x1ea7,
+ 0x1ea9, 0x1ea9,
+ 0x1eab, 0x1eab,
+ 0x1ead, 0x1ead,
+ 0x1eaf, 0x1eaf,
+ 0x1eb1, 0x1eb1,
+ 0x1eb3, 0x1eb3,
+ 0x1eb5, 0x1eb5,
+ 0x1eb7, 0x1eb7,
+ 0x1eb9, 0x1eb9,
+ 0x1ebb, 0x1ebb,
+ 0x1ebd, 0x1ebd,
+ 0x1ebf, 0x1ebf,
+ 0x1ec1, 0x1ec1,
+ 0x1ec3, 0x1ec3,
+ 0x1ec5, 0x1ec5,
+ 0x1ec7, 0x1ec7,
+ 0x1ec9, 0x1ec9,
+ 0x1ecb, 0x1ecb,
+ 0x1ecd, 0x1ecd,
+ 0x1ecf, 0x1ecf,
+ 0x1ed1, 0x1ed1,
+ 0x1ed3, 0x1ed3,
+ 0x1ed5, 0x1ed5,
+ 0x1ed7, 0x1ed7,
+ 0x1ed9, 0x1ed9,
+ 0x1edb, 0x1edb,
+ 0x1edd, 0x1edd,
+ 0x1edf, 0x1edf,
+ 0x1ee1, 0x1ee1,
+ 0x1ee3, 0x1ee3,
+ 0x1ee5, 0x1ee5,
+ 0x1ee7, 0x1ee7,
+ 0x1ee9, 0x1ee9,
+ 0x1eeb, 0x1eeb,
+ 0x1eed, 0x1eed,
+ 0x1eef, 0x1eef,
+ 0x1ef1, 0x1ef1,
+ 0x1ef3, 0x1ef3,
+ 0x1ef5, 0x1ef5,
+ 0x1ef7, 0x1ef7,
+ 0x1ef9, 0x1ef9,
+ 0x1efb, 0x1efb,
+ 0x1efd, 0x1efd,
+ 0x1eff, 0x1f07,
+ 0x1f10, 0x1f15,
+ 0x1f20, 0x1f27,
+ 0x1f30, 0x1f37,
+ 0x1f40, 0x1f45,
+ 0x1f50, 0x1f57,
+ 0x1f60, 0x1f67,
+ 0x1f70, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fb7,
+ 0x1fbc, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fc7,
+ 0x1fcc, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fd7,
+ 0x1fe0, 0x1fe7,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ff7,
+ 0x1ffc, 0x1ffc,
+ 0x214e, 0x214e,
+ 0x2170, 0x217f,
+ 0x2184, 0x2184,
+ 0x24d0, 0x24e9,
+ 0x2c30, 0x2c5e,
+ 0x2c61, 0x2c61,
+ 0x2c65, 0x2c66,
+ 0x2c68, 0x2c68,
+ 0x2c6a, 0x2c6a,
+ 0x2c6c, 0x2c6c,
+ 0x2c73, 0x2c73,
+ 0x2c76, 0x2c76,
+ 0x2c81, 0x2c81,
+ 0x2c83, 0x2c83,
+ 0x2c85, 0x2c85,
+ 0x2c87, 0x2c87,
+ 0x2c89, 0x2c89,
+ 0x2c8b, 0x2c8b,
+ 0x2c8d, 0x2c8d,
+ 0x2c8f, 0x2c8f,
+ 0x2c91, 0x2c91,
+ 0x2c93, 0x2c93,
+ 0x2c95, 0x2c95,
+ 0x2c97, 0x2c97,
+ 0x2c99, 0x2c99,
+ 0x2c9b, 0x2c9b,
+ 0x2c9d, 0x2c9d,
+ 0x2c9f, 0x2c9f,
+ 0x2ca1, 0x2ca1,
+ 0x2ca3, 0x2ca3,
+ 0x2ca5, 0x2ca5,
+ 0x2ca7, 0x2ca7,
+ 0x2ca9, 0x2ca9,
+ 0x2cab, 0x2cab,
+ 0x2cad, 0x2cad,
+ 0x2caf, 0x2caf,
+ 0x2cb1, 0x2cb1,
+ 0x2cb3, 0x2cb3,
+ 0x2cb5, 0x2cb5,
+ 0x2cb7, 0x2cb7,
+ 0x2cb9, 0x2cb9,
+ 0x2cbb, 0x2cbb,
+ 0x2cbd, 0x2cbd,
+ 0x2cbf, 0x2cbf,
+ 0x2cc1, 0x2cc1,
+ 0x2cc3, 0x2cc3,
+ 0x2cc5, 0x2cc5,
+ 0x2cc7, 0x2cc7,
+ 0x2cc9, 0x2cc9,
+ 0x2ccb, 0x2ccb,
+ 0x2ccd, 0x2ccd,
+ 0x2ccf, 0x2ccf,
+ 0x2cd1, 0x2cd1,
+ 0x2cd3, 0x2cd3,
+ 0x2cd5, 0x2cd5,
+ 0x2cd7, 0x2cd7,
+ 0x2cd9, 0x2cd9,
+ 0x2cdb, 0x2cdb,
+ 0x2cdd, 0x2cdd,
+ 0x2cdf, 0x2cdf,
+ 0x2ce1, 0x2ce1,
+ 0x2ce3, 0x2ce3,
+ 0x2cec, 0x2cec,
+ 0x2cee, 0x2cee,
+ 0x2cf3, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0xa641, 0xa641,
+ 0xa643, 0xa643,
+ 0xa645, 0xa645,
+ 0xa647, 0xa647,
+ 0xa649, 0xa649,
+ 0xa64b, 0xa64b,
+ 0xa64d, 0xa64d,
+ 0xa64f, 0xa64f,
+ 0xa651, 0xa651,
+ 0xa653, 0xa653,
+ 0xa655, 0xa655,
+ 0xa657, 0xa657,
+ 0xa659, 0xa659,
+ 0xa65b, 0xa65b,
+ 0xa65d, 0xa65d,
+ 0xa65f, 0xa65f,
+ 0xa661, 0xa661,
+ 0xa663, 0xa663,
+ 0xa665, 0xa665,
+ 0xa667, 0xa667,
+ 0xa669, 0xa669,
+ 0xa66b, 0xa66b,
+ 0xa66d, 0xa66d,
+ 0xa681, 0xa681,
+ 0xa683, 0xa683,
+ 0xa685, 0xa685,
+ 0xa687, 0xa687,
+ 0xa689, 0xa689,
+ 0xa68b, 0xa68b,
+ 0xa68d, 0xa68d,
+ 0xa68f, 0xa68f,
+ 0xa691, 0xa691,
+ 0xa693, 0xa693,
+ 0xa695, 0xa695,
+ 0xa697, 0xa697,
+ 0xa699, 0xa699,
+ 0xa69b, 0xa69b,
+ 0xa723, 0xa723,
+ 0xa725, 0xa725,
+ 0xa727, 0xa727,
+ 0xa729, 0xa729,
+ 0xa72b, 0xa72b,
+ 0xa72d, 0xa72d,
+ 0xa72f, 0xa72f,
+ 0xa733, 0xa733,
+ 0xa735, 0xa735,
+ 0xa737, 0xa737,
+ 0xa739, 0xa739,
+ 0xa73b, 0xa73b,
+ 0xa73d, 0xa73d,
+ 0xa73f, 0xa73f,
+ 0xa741, 0xa741,
+ 0xa743, 0xa743,
+ 0xa745, 0xa745,
+ 0xa747, 0xa747,
+ 0xa749, 0xa749,
+ 0xa74b, 0xa74b,
+ 0xa74d, 0xa74d,
+ 0xa74f, 0xa74f,
+ 0xa751, 0xa751,
+ 0xa753, 0xa753,
+ 0xa755, 0xa755,
+ 0xa757, 0xa757,
+ 0xa759, 0xa759,
+ 0xa75b, 0xa75b,
+ 0xa75d, 0xa75d,
+ 0xa75f, 0xa75f,
+ 0xa761, 0xa761,
+ 0xa763, 0xa763,
+ 0xa765, 0xa765,
+ 0xa767, 0xa767,
+ 0xa769, 0xa769,
+ 0xa76b, 0xa76b,
+ 0xa76d, 0xa76d,
+ 0xa76f, 0xa76f,
+ 0xa77a, 0xa77a,
+ 0xa77c, 0xa77c,
+ 0xa77f, 0xa77f,
+ 0xa781, 0xa781,
+ 0xa783, 0xa783,
+ 0xa785, 0xa785,
+ 0xa787, 0xa787,
+ 0xa78c, 0xa78c,
+ 0xa791, 0xa791,
+ 0xa793, 0xa794,
+ 0xa797, 0xa797,
+ 0xa799, 0xa799,
+ 0xa79b, 0xa79b,
+ 0xa79d, 0xa79d,
+ 0xa79f, 0xa79f,
+ 0xa7a1, 0xa7a1,
+ 0xa7a3, 0xa7a3,
+ 0xa7a5, 0xa7a5,
+ 0xa7a7, 0xa7a7,
+ 0xa7a9, 0xa7a9,
+ 0xa7b5, 0xa7b5,
+ 0xa7b7, 0xa7b7,
+ 0xa7b9, 0xa7b9,
+ 0xa7bb, 0xa7bb,
+ 0xa7bd, 0xa7bd,
+ 0xa7bf, 0xa7bf,
+ 0xa7c3, 0xa7c3,
+ 0xab53, 0xab53,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff41, 0xff5a,
+ 0x10428, 0x1044f,
+ 0x104d8, 0x104fb,
+ 0x10cc0, 0x10cf2,
+ 0x118c0, 0x118df,
+ 0x16e60, 0x16e7f,
+ 0x1e922, 0x1e943,
+}; /* CR_Changes_When_Uppercased */
+
+/* 'Changes_When_Titlecased': Derived Property */
+static const OnigCodePoint CR_Changes_When_Titlecased[] = {
+ 615,
+ 0x0061, 0x007a,
+ 0x00b5, 0x00b5,
+ 0x00df, 0x00f6,
+ 0x00f8, 0x00ff,
+ 0x0101, 0x0101,
+ 0x0103, 0x0103,
+ 0x0105, 0x0105,
+ 0x0107, 0x0107,
+ 0x0109, 0x0109,
+ 0x010b, 0x010b,
+ 0x010d, 0x010d,
+ 0x010f, 0x010f,
+ 0x0111, 0x0111,
+ 0x0113, 0x0113,
+ 0x0115, 0x0115,
+ 0x0117, 0x0117,
+ 0x0119, 0x0119,
+ 0x011b, 0x011b,
+ 0x011d, 0x011d,
+ 0x011f, 0x011f,
+ 0x0121, 0x0121,
+ 0x0123, 0x0123,
+ 0x0125, 0x0125,
+ 0x0127, 0x0127,
+ 0x0129, 0x0129,
+ 0x012b, 0x012b,
+ 0x012d, 0x012d,
+ 0x012f, 0x012f,
+ 0x0131, 0x0131,
+ 0x0133, 0x0133,
+ 0x0135, 0x0135,
+ 0x0137, 0x0137,
+ 0x013a, 0x013a,
+ 0x013c, 0x013c,
+ 0x013e, 0x013e,
+ 0x0140, 0x0140,
+ 0x0142, 0x0142,
+ 0x0144, 0x0144,
+ 0x0146, 0x0146,
+ 0x0148, 0x0149,
+ 0x014b, 0x014b,
+ 0x014d, 0x014d,
+ 0x014f, 0x014f,
+ 0x0151, 0x0151,
+ 0x0153, 0x0153,
+ 0x0155, 0x0155,
+ 0x0157, 0x0157,
+ 0x0159, 0x0159,
+ 0x015b, 0x015b,
+ 0x015d, 0x015d,
+ 0x015f, 0x015f,
+ 0x0161, 0x0161,
+ 0x0163, 0x0163,
+ 0x0165, 0x0165,
+ 0x0167, 0x0167,
+ 0x0169, 0x0169,
+ 0x016b, 0x016b,
+ 0x016d, 0x016d,
+ 0x016f, 0x016f,
+ 0x0171, 0x0171,
+ 0x0173, 0x0173,
+ 0x0175, 0x0175,
+ 0x0177, 0x0177,
+ 0x017a, 0x017a,
+ 0x017c, 0x017c,
+ 0x017e, 0x0180,
+ 0x0183, 0x0183,
+ 0x0185, 0x0185,
+ 0x0188, 0x0188,
+ 0x018c, 0x018c,
+ 0x0192, 0x0192,
+ 0x0195, 0x0195,
+ 0x0199, 0x019a,
+ 0x019e, 0x019e,
+ 0x01a1, 0x01a1,
+ 0x01a3, 0x01a3,
+ 0x01a5, 0x01a5,
+ 0x01a8, 0x01a8,
+ 0x01ad, 0x01ad,
+ 0x01b0, 0x01b0,
+ 0x01b4, 0x01b4,
+ 0x01b6, 0x01b6,
+ 0x01b9, 0x01b9,
+ 0x01bd, 0x01bd,
+ 0x01bf, 0x01bf,
+ 0x01c4, 0x01c4,
+ 0x01c6, 0x01c7,
+ 0x01c9, 0x01ca,
+ 0x01cc, 0x01cc,
+ 0x01ce, 0x01ce,
+ 0x01d0, 0x01d0,
+ 0x01d2, 0x01d2,
+ 0x01d4, 0x01d4,
+ 0x01d6, 0x01d6,
+ 0x01d8, 0x01d8,
+ 0x01da, 0x01da,
+ 0x01dc, 0x01dd,
+ 0x01df, 0x01df,
+ 0x01e1, 0x01e1,
+ 0x01e3, 0x01e3,
+ 0x01e5, 0x01e5,
+ 0x01e7, 0x01e7,
+ 0x01e9, 0x01e9,
+ 0x01eb, 0x01eb,
+ 0x01ed, 0x01ed,
+ 0x01ef, 0x01f1,
+ 0x01f3, 0x01f3,
+ 0x01f5, 0x01f5,
+ 0x01f9, 0x01f9,
+ 0x01fb, 0x01fb,
+ 0x01fd, 0x01fd,
+ 0x01ff, 0x01ff,
+ 0x0201, 0x0201,
+ 0x0203, 0x0203,
+ 0x0205, 0x0205,
+ 0x0207, 0x0207,
+ 0x0209, 0x0209,
+ 0x020b, 0x020b,
+ 0x020d, 0x020d,
+ 0x020f, 0x020f,
+ 0x0211, 0x0211,
+ 0x0213, 0x0213,
+ 0x0215, 0x0215,
+ 0x0217, 0x0217,
+ 0x0219, 0x0219,
+ 0x021b, 0x021b,
+ 0x021d, 0x021d,
+ 0x021f, 0x021f,
+ 0x0223, 0x0223,
+ 0x0225, 0x0225,
+ 0x0227, 0x0227,
+ 0x0229, 0x0229,
+ 0x022b, 0x022b,
+ 0x022d, 0x022d,
+ 0x022f, 0x022f,
+ 0x0231, 0x0231,
+ 0x0233, 0x0233,
+ 0x023c, 0x023c,
+ 0x023f, 0x0240,
+ 0x0242, 0x0242,
+ 0x0247, 0x0247,
+ 0x0249, 0x0249,
+ 0x024b, 0x024b,
+ 0x024d, 0x024d,
+ 0x024f, 0x0254,
+ 0x0256, 0x0257,
+ 0x0259, 0x0259,
+ 0x025b, 0x025c,
+ 0x0260, 0x0261,
+ 0x0263, 0x0263,
+ 0x0265, 0x0266,
+ 0x0268, 0x026c,
+ 0x026f, 0x026f,
+ 0x0271, 0x0272,
+ 0x0275, 0x0275,
+ 0x027d, 0x027d,
+ 0x0280, 0x0280,
+ 0x0282, 0x0283,
+ 0x0287, 0x028c,
+ 0x0292, 0x0292,
+ 0x029d, 0x029e,
+ 0x0345, 0x0345,
+ 0x0371, 0x0371,
+ 0x0373, 0x0373,
+ 0x0377, 0x0377,
+ 0x037b, 0x037d,
+ 0x0390, 0x0390,
+ 0x03ac, 0x03ce,
+ 0x03d0, 0x03d1,
+ 0x03d5, 0x03d7,
+ 0x03d9, 0x03d9,
+ 0x03db, 0x03db,
+ 0x03dd, 0x03dd,
+ 0x03df, 0x03df,
+ 0x03e1, 0x03e1,
+ 0x03e3, 0x03e3,
+ 0x03e5, 0x03e5,
+ 0x03e7, 0x03e7,
+ 0x03e9, 0x03e9,
+ 0x03eb, 0x03eb,
+ 0x03ed, 0x03ed,
+ 0x03ef, 0x03f3,
+ 0x03f5, 0x03f5,
+ 0x03f8, 0x03f8,
+ 0x03fb, 0x03fb,
+ 0x0430, 0x045f,
+ 0x0461, 0x0461,
+ 0x0463, 0x0463,
+ 0x0465, 0x0465,
+ 0x0467, 0x0467,
+ 0x0469, 0x0469,
+ 0x046b, 0x046b,
+ 0x046d, 0x046d,
+ 0x046f, 0x046f,
+ 0x0471, 0x0471,
+ 0x0473, 0x0473,
+ 0x0475, 0x0475,
+ 0x0477, 0x0477,
+ 0x0479, 0x0479,
+ 0x047b, 0x047b,
+ 0x047d, 0x047d,
+ 0x047f, 0x047f,
+ 0x0481, 0x0481,
+ 0x048b, 0x048b,
+ 0x048d, 0x048d,
+ 0x048f, 0x048f,
+ 0x0491, 0x0491,
+ 0x0493, 0x0493,
+ 0x0495, 0x0495,
+ 0x0497, 0x0497,
+ 0x0499, 0x0499,
+ 0x049b, 0x049b,
+ 0x049d, 0x049d,
+ 0x049f, 0x049f,
+ 0x04a1, 0x04a1,
+ 0x04a3, 0x04a3,
+ 0x04a5, 0x04a5,
+ 0x04a7, 0x04a7,
+ 0x04a9, 0x04a9,
+ 0x04ab, 0x04ab,
+ 0x04ad, 0x04ad,
+ 0x04af, 0x04af,
+ 0x04b1, 0x04b1,
+ 0x04b3, 0x04b3,
+ 0x04b5, 0x04b5,
+ 0x04b7, 0x04b7,
+ 0x04b9, 0x04b9,
+ 0x04bb, 0x04bb,
+ 0x04bd, 0x04bd,
+ 0x04bf, 0x04bf,
+ 0x04c2, 0x04c2,
+ 0x04c4, 0x04c4,
+ 0x04c6, 0x04c6,
+ 0x04c8, 0x04c8,
+ 0x04ca, 0x04ca,
+ 0x04cc, 0x04cc,
+ 0x04ce, 0x04cf,
+ 0x04d1, 0x04d1,
+ 0x04d3, 0x04d3,
+ 0x04d5, 0x04d5,
+ 0x04d7, 0x04d7,
+ 0x04d9, 0x04d9,
+ 0x04db, 0x04db,
+ 0x04dd, 0x04dd,
+ 0x04df, 0x04df,
+ 0x04e1, 0x04e1,
+ 0x04e3, 0x04e3,
+ 0x04e5, 0x04e5,
+ 0x04e7, 0x04e7,
+ 0x04e9, 0x04e9,
+ 0x04eb, 0x04eb,
+ 0x04ed, 0x04ed,
+ 0x04ef, 0x04ef,
+ 0x04f1, 0x04f1,
+ 0x04f3, 0x04f3,
+ 0x04f5, 0x04f5,
+ 0x04f7, 0x04f7,
+ 0x04f9, 0x04f9,
+ 0x04fb, 0x04fb,
+ 0x04fd, 0x04fd,
+ 0x04ff, 0x04ff,
+ 0x0501, 0x0501,
+ 0x0503, 0x0503,
+ 0x0505, 0x0505,
+ 0x0507, 0x0507,
+ 0x0509, 0x0509,
+ 0x050b, 0x050b,
+ 0x050d, 0x050d,
+ 0x050f, 0x050f,
+ 0x0511, 0x0511,
+ 0x0513, 0x0513,
+ 0x0515, 0x0515,
+ 0x0517, 0x0517,
+ 0x0519, 0x0519,
+ 0x051b, 0x051b,
+ 0x051d, 0x051d,
+ 0x051f, 0x051f,
+ 0x0521, 0x0521,
+ 0x0523, 0x0523,
+ 0x0525, 0x0525,
+ 0x0527, 0x0527,
+ 0x0529, 0x0529,
+ 0x052b, 0x052b,
+ 0x052d, 0x052d,
+ 0x052f, 0x052f,
+ 0x0561, 0x0587,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1d79, 0x1d79,
+ 0x1d7d, 0x1d7d,
+ 0x1d8e, 0x1d8e,
+ 0x1e01, 0x1e01,
+ 0x1e03, 0x1e03,
+ 0x1e05, 0x1e05,
+ 0x1e07, 0x1e07,
+ 0x1e09, 0x1e09,
+ 0x1e0b, 0x1e0b,
+ 0x1e0d, 0x1e0d,
+ 0x1e0f, 0x1e0f,
+ 0x1e11, 0x1e11,
+ 0x1e13, 0x1e13,
+ 0x1e15, 0x1e15,
+ 0x1e17, 0x1e17,
+ 0x1e19, 0x1e19,
+ 0x1e1b, 0x1e1b,
+ 0x1e1d, 0x1e1d,
+ 0x1e1f, 0x1e1f,
+ 0x1e21, 0x1e21,
+ 0x1e23, 0x1e23,
+ 0x1e25, 0x1e25,
+ 0x1e27, 0x1e27,
+ 0x1e29, 0x1e29,
+ 0x1e2b, 0x1e2b,
+ 0x1e2d, 0x1e2d,
+ 0x1e2f, 0x1e2f,
+ 0x1e31, 0x1e31,
+ 0x1e33, 0x1e33,
+ 0x1e35, 0x1e35,
+ 0x1e37, 0x1e37,
+ 0x1e39, 0x1e39,
+ 0x1e3b, 0x1e3b,
+ 0x1e3d, 0x1e3d,
+ 0x1e3f, 0x1e3f,
+ 0x1e41, 0x1e41,
+ 0x1e43, 0x1e43,
+ 0x1e45, 0x1e45,
+ 0x1e47, 0x1e47,
+ 0x1e49, 0x1e49,
+ 0x1e4b, 0x1e4b,
+ 0x1e4d, 0x1e4d,
+ 0x1e4f, 0x1e4f,
+ 0x1e51, 0x1e51,
+ 0x1e53, 0x1e53,
+ 0x1e55, 0x1e55,
+ 0x1e57, 0x1e57,
+ 0x1e59, 0x1e59,
+ 0x1e5b, 0x1e5b,
+ 0x1e5d, 0x1e5d,
+ 0x1e5f, 0x1e5f,
+ 0x1e61, 0x1e61,
+ 0x1e63, 0x1e63,
+ 0x1e65, 0x1e65,
+ 0x1e67, 0x1e67,
+ 0x1e69, 0x1e69,
+ 0x1e6b, 0x1e6b,
+ 0x1e6d, 0x1e6d,
+ 0x1e6f, 0x1e6f,
+ 0x1e71, 0x1e71,
+ 0x1e73, 0x1e73,
+ 0x1e75, 0x1e75,
+ 0x1e77, 0x1e77,
+ 0x1e79, 0x1e79,
+ 0x1e7b, 0x1e7b,
+ 0x1e7d, 0x1e7d,
+ 0x1e7f, 0x1e7f,
+ 0x1e81, 0x1e81,
+ 0x1e83, 0x1e83,
+ 0x1e85, 0x1e85,
+ 0x1e87, 0x1e87,
+ 0x1e89, 0x1e89,
+ 0x1e8b, 0x1e8b,
+ 0x1e8d, 0x1e8d,
+ 0x1e8f, 0x1e8f,
+ 0x1e91, 0x1e91,
+ 0x1e93, 0x1e93,
+ 0x1e95, 0x1e9b,
+ 0x1ea1, 0x1ea1,
+ 0x1ea3, 0x1ea3,
+ 0x1ea5, 0x1ea5,
+ 0x1ea7, 0x1ea7,
+ 0x1ea9, 0x1ea9,
+ 0x1eab, 0x1eab,
+ 0x1ead, 0x1ead,
+ 0x1eaf, 0x1eaf,
+ 0x1eb1, 0x1eb1,
+ 0x1eb3, 0x1eb3,
+ 0x1eb5, 0x1eb5,
+ 0x1eb7, 0x1eb7,
+ 0x1eb9, 0x1eb9,
+ 0x1ebb, 0x1ebb,
+ 0x1ebd, 0x1ebd,
+ 0x1ebf, 0x1ebf,
+ 0x1ec1, 0x1ec1,
+ 0x1ec3, 0x1ec3,
+ 0x1ec5, 0x1ec5,
+ 0x1ec7, 0x1ec7,
+ 0x1ec9, 0x1ec9,
+ 0x1ecb, 0x1ecb,
+ 0x1ecd, 0x1ecd,
+ 0x1ecf, 0x1ecf,
+ 0x1ed1, 0x1ed1,
+ 0x1ed3, 0x1ed3,
+ 0x1ed5, 0x1ed5,
+ 0x1ed7, 0x1ed7,
+ 0x1ed9, 0x1ed9,
+ 0x1edb, 0x1edb,
+ 0x1edd, 0x1edd,
+ 0x1edf, 0x1edf,
+ 0x1ee1, 0x1ee1,
+ 0x1ee3, 0x1ee3,
+ 0x1ee5, 0x1ee5,
+ 0x1ee7, 0x1ee7,
+ 0x1ee9, 0x1ee9,
+ 0x1eeb, 0x1eeb,
+ 0x1eed, 0x1eed,
+ 0x1eef, 0x1eef,
+ 0x1ef1, 0x1ef1,
+ 0x1ef3, 0x1ef3,
+ 0x1ef5, 0x1ef5,
+ 0x1ef7, 0x1ef7,
+ 0x1ef9, 0x1ef9,
+ 0x1efb, 0x1efb,
+ 0x1efd, 0x1efd,
+ 0x1eff, 0x1f07,
+ 0x1f10, 0x1f15,
+ 0x1f20, 0x1f27,
+ 0x1f30, 0x1f37,
+ 0x1f40, 0x1f45,
+ 0x1f50, 0x1f57,
+ 0x1f60, 0x1f67,
+ 0x1f70, 0x1f7d,
+ 0x1f80, 0x1f87,
+ 0x1f90, 0x1f97,
+ 0x1fa0, 0x1fa7,
+ 0x1fb0, 0x1fb4,
+ 0x1fb6, 0x1fb7,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fc7,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fd7,
+ 0x1fe0, 0x1fe7,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ff7,
+ 0x214e, 0x214e,
+ 0x2170, 0x217f,
+ 0x2184, 0x2184,
+ 0x24d0, 0x24e9,
+ 0x2c30, 0x2c5e,
+ 0x2c61, 0x2c61,
+ 0x2c65, 0x2c66,
+ 0x2c68, 0x2c68,
+ 0x2c6a, 0x2c6a,
+ 0x2c6c, 0x2c6c,
+ 0x2c73, 0x2c73,
+ 0x2c76, 0x2c76,
+ 0x2c81, 0x2c81,
+ 0x2c83, 0x2c83,
+ 0x2c85, 0x2c85,
+ 0x2c87, 0x2c87,
+ 0x2c89, 0x2c89,
+ 0x2c8b, 0x2c8b,
+ 0x2c8d, 0x2c8d,
+ 0x2c8f, 0x2c8f,
+ 0x2c91, 0x2c91,
+ 0x2c93, 0x2c93,
+ 0x2c95, 0x2c95,
+ 0x2c97, 0x2c97,
+ 0x2c99, 0x2c99,
+ 0x2c9b, 0x2c9b,
+ 0x2c9d, 0x2c9d,
+ 0x2c9f, 0x2c9f,
+ 0x2ca1, 0x2ca1,
+ 0x2ca3, 0x2ca3,
+ 0x2ca5, 0x2ca5,
+ 0x2ca7, 0x2ca7,
+ 0x2ca9, 0x2ca9,
+ 0x2cab, 0x2cab,
+ 0x2cad, 0x2cad,
+ 0x2caf, 0x2caf,
+ 0x2cb1, 0x2cb1,
+ 0x2cb3, 0x2cb3,
+ 0x2cb5, 0x2cb5,
+ 0x2cb7, 0x2cb7,
+ 0x2cb9, 0x2cb9,
+ 0x2cbb, 0x2cbb,
+ 0x2cbd, 0x2cbd,
+ 0x2cbf, 0x2cbf,
+ 0x2cc1, 0x2cc1,
+ 0x2cc3, 0x2cc3,
+ 0x2cc5, 0x2cc5,
+ 0x2cc7, 0x2cc7,
+ 0x2cc9, 0x2cc9,
+ 0x2ccb, 0x2ccb,
+ 0x2ccd, 0x2ccd,
+ 0x2ccf, 0x2ccf,
+ 0x2cd1, 0x2cd1,
+ 0x2cd3, 0x2cd3,
+ 0x2cd5, 0x2cd5,
+ 0x2cd7, 0x2cd7,
+ 0x2cd9, 0x2cd9,
+ 0x2cdb, 0x2cdb,
+ 0x2cdd, 0x2cdd,
+ 0x2cdf, 0x2cdf,
+ 0x2ce1, 0x2ce1,
+ 0x2ce3, 0x2ce3,
+ 0x2cec, 0x2cec,
+ 0x2cee, 0x2cee,
+ 0x2cf3, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0xa641, 0xa641,
+ 0xa643, 0xa643,
+ 0xa645, 0xa645,
+ 0xa647, 0xa647,
+ 0xa649, 0xa649,
+ 0xa64b, 0xa64b,
+ 0xa64d, 0xa64d,
+ 0xa64f, 0xa64f,
+ 0xa651, 0xa651,
+ 0xa653, 0xa653,
+ 0xa655, 0xa655,
+ 0xa657, 0xa657,
+ 0xa659, 0xa659,
+ 0xa65b, 0xa65b,
+ 0xa65d, 0xa65d,
+ 0xa65f, 0xa65f,
+ 0xa661, 0xa661,
+ 0xa663, 0xa663,
+ 0xa665, 0xa665,
+ 0xa667, 0xa667,
+ 0xa669, 0xa669,
+ 0xa66b, 0xa66b,
+ 0xa66d, 0xa66d,
+ 0xa681, 0xa681,
+ 0xa683, 0xa683,
+ 0xa685, 0xa685,
+ 0xa687, 0xa687,
+ 0xa689, 0xa689,
+ 0xa68b, 0xa68b,
+ 0xa68d, 0xa68d,
+ 0xa68f, 0xa68f,
+ 0xa691, 0xa691,
+ 0xa693, 0xa693,
+ 0xa695, 0xa695,
+ 0xa697, 0xa697,
+ 0xa699, 0xa699,
+ 0xa69b, 0xa69b,
+ 0xa723, 0xa723,
+ 0xa725, 0xa725,
+ 0xa727, 0xa727,
+ 0xa729, 0xa729,
+ 0xa72b, 0xa72b,
+ 0xa72d, 0xa72d,
+ 0xa72f, 0xa72f,
+ 0xa733, 0xa733,
+ 0xa735, 0xa735,
+ 0xa737, 0xa737,
+ 0xa739, 0xa739,
+ 0xa73b, 0xa73b,
+ 0xa73d, 0xa73d,
+ 0xa73f, 0xa73f,
+ 0xa741, 0xa741,
+ 0xa743, 0xa743,
+ 0xa745, 0xa745,
+ 0xa747, 0xa747,
+ 0xa749, 0xa749,
+ 0xa74b, 0xa74b,
+ 0xa74d, 0xa74d,
+ 0xa74f, 0xa74f,
+ 0xa751, 0xa751,
+ 0xa753, 0xa753,
+ 0xa755, 0xa755,
+ 0xa757, 0xa757,
+ 0xa759, 0xa759,
+ 0xa75b, 0xa75b,
+ 0xa75d, 0xa75d,
+ 0xa75f, 0xa75f,
+ 0xa761, 0xa761,
+ 0xa763, 0xa763,
+ 0xa765, 0xa765,
+ 0xa767, 0xa767,
+ 0xa769, 0xa769,
+ 0xa76b, 0xa76b,
+ 0xa76d, 0xa76d,
+ 0xa76f, 0xa76f,
+ 0xa77a, 0xa77a,
+ 0xa77c, 0xa77c,
+ 0xa77f, 0xa77f,
+ 0xa781, 0xa781,
+ 0xa783, 0xa783,
+ 0xa785, 0xa785,
+ 0xa787, 0xa787,
+ 0xa78c, 0xa78c,
+ 0xa791, 0xa791,
+ 0xa793, 0xa794,
+ 0xa797, 0xa797,
+ 0xa799, 0xa799,
+ 0xa79b, 0xa79b,
+ 0xa79d, 0xa79d,
+ 0xa79f, 0xa79f,
+ 0xa7a1, 0xa7a1,
+ 0xa7a3, 0xa7a3,
+ 0xa7a5, 0xa7a5,
+ 0xa7a7, 0xa7a7,
+ 0xa7a9, 0xa7a9,
+ 0xa7b5, 0xa7b5,
+ 0xa7b7, 0xa7b7,
+ 0xa7b9, 0xa7b9,
+ 0xa7bb, 0xa7bb,
+ 0xa7bd, 0xa7bd,
+ 0xa7bf, 0xa7bf,
+ 0xa7c3, 0xa7c3,
+ 0xab53, 0xab53,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff41, 0xff5a,
+ 0x10428, 0x1044f,
+ 0x104d8, 0x104fb,
+ 0x10cc0, 0x10cf2,
+ 0x118c0, 0x118df,
+ 0x16e60, 0x16e7f,
+ 0x1e922, 0x1e943,
+}; /* CR_Changes_When_Titlecased */
+
+/* 'Changes_When_Casefolded': Derived Property */
+static const OnigCodePoint CR_Changes_When_Casefolded[] = {
+ 612,
+ 0x0041, 0x005a,
+ 0x00b5, 0x00b5,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00df,
+ 0x0100, 0x0100,
+ 0x0102, 0x0102,
+ 0x0104, 0x0104,
+ 0x0106, 0x0106,
+ 0x0108, 0x0108,
+ 0x010a, 0x010a,
+ 0x010c, 0x010c,
+ 0x010e, 0x010e,
+ 0x0110, 0x0110,
+ 0x0112, 0x0112,
+ 0x0114, 0x0114,
+ 0x0116, 0x0116,
+ 0x0118, 0x0118,
+ 0x011a, 0x011a,
+ 0x011c, 0x011c,
+ 0x011e, 0x011e,
+ 0x0120, 0x0120,
+ 0x0122, 0x0122,
+ 0x0124, 0x0124,
+ 0x0126, 0x0126,
+ 0x0128, 0x0128,
+ 0x012a, 0x012a,
+ 0x012c, 0x012c,
+ 0x012e, 0x012e,
+ 0x0130, 0x0130,
+ 0x0132, 0x0132,
+ 0x0134, 0x0134,
+ 0x0136, 0x0136,
+ 0x0139, 0x0139,
+ 0x013b, 0x013b,
+ 0x013d, 0x013d,
+ 0x013f, 0x013f,
+ 0x0141, 0x0141,
+ 0x0143, 0x0143,
+ 0x0145, 0x0145,
+ 0x0147, 0x0147,
+ 0x0149, 0x014a,
+ 0x014c, 0x014c,
+ 0x014e, 0x014e,
+ 0x0150, 0x0150,
+ 0x0152, 0x0152,
+ 0x0154, 0x0154,
+ 0x0156, 0x0156,
+ 0x0158, 0x0158,
+ 0x015a, 0x015a,
+ 0x015c, 0x015c,
+ 0x015e, 0x015e,
+ 0x0160, 0x0160,
+ 0x0162, 0x0162,
+ 0x0164, 0x0164,
+ 0x0166, 0x0166,
+ 0x0168, 0x0168,
+ 0x016a, 0x016a,
+ 0x016c, 0x016c,
+ 0x016e, 0x016e,
+ 0x0170, 0x0170,
+ 0x0172, 0x0172,
+ 0x0174, 0x0174,
+ 0x0176, 0x0176,
+ 0x0178, 0x0179,
+ 0x017b, 0x017b,
+ 0x017d, 0x017d,
+ 0x017f, 0x017f,
+ 0x0181, 0x0182,
+ 0x0184, 0x0184,
+ 0x0186, 0x0187,
+ 0x0189, 0x018b,
+ 0x018e, 0x0191,
+ 0x0193, 0x0194,
+ 0x0196, 0x0198,
+ 0x019c, 0x019d,
+ 0x019f, 0x01a0,
+ 0x01a2, 0x01a2,
+ 0x01a4, 0x01a4,
+ 0x01a6, 0x01a7,
+ 0x01a9, 0x01a9,
+ 0x01ac, 0x01ac,
+ 0x01ae, 0x01af,
+ 0x01b1, 0x01b3,
+ 0x01b5, 0x01b5,
+ 0x01b7, 0x01b8,
+ 0x01bc, 0x01bc,
+ 0x01c4, 0x01c5,
+ 0x01c7, 0x01c8,
+ 0x01ca, 0x01cb,
+ 0x01cd, 0x01cd,
+ 0x01cf, 0x01cf,
+ 0x01d1, 0x01d1,
+ 0x01d3, 0x01d3,
+ 0x01d5, 0x01d5,
+ 0x01d7, 0x01d7,
+ 0x01d9, 0x01d9,
+ 0x01db, 0x01db,
+ 0x01de, 0x01de,
+ 0x01e0, 0x01e0,
+ 0x01e2, 0x01e2,
+ 0x01e4, 0x01e4,
+ 0x01e6, 0x01e6,
+ 0x01e8, 0x01e8,
+ 0x01ea, 0x01ea,
+ 0x01ec, 0x01ec,
+ 0x01ee, 0x01ee,
+ 0x01f1, 0x01f2,
+ 0x01f4, 0x01f4,
+ 0x01f6, 0x01f8,
+ 0x01fa, 0x01fa,
+ 0x01fc, 0x01fc,
+ 0x01fe, 0x01fe,
+ 0x0200, 0x0200,
+ 0x0202, 0x0202,
+ 0x0204, 0x0204,
+ 0x0206, 0x0206,
+ 0x0208, 0x0208,
+ 0x020a, 0x020a,
+ 0x020c, 0x020c,
+ 0x020e, 0x020e,
+ 0x0210, 0x0210,
+ 0x0212, 0x0212,
+ 0x0214, 0x0214,
+ 0x0216, 0x0216,
+ 0x0218, 0x0218,
+ 0x021a, 0x021a,
+ 0x021c, 0x021c,
+ 0x021e, 0x021e,
+ 0x0220, 0x0220,
+ 0x0222, 0x0222,
+ 0x0224, 0x0224,
+ 0x0226, 0x0226,
+ 0x0228, 0x0228,
+ 0x022a, 0x022a,
+ 0x022c, 0x022c,
+ 0x022e, 0x022e,
+ 0x0230, 0x0230,
+ 0x0232, 0x0232,
+ 0x023a, 0x023b,
+ 0x023d, 0x023e,
+ 0x0241, 0x0241,
+ 0x0243, 0x0246,
+ 0x0248, 0x0248,
+ 0x024a, 0x024a,
+ 0x024c, 0x024c,
+ 0x024e, 0x024e,
+ 0x0345, 0x0345,
+ 0x0370, 0x0370,
+ 0x0372, 0x0372,
+ 0x0376, 0x0376,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x038f,
+ 0x0391, 0x03a1,
+ 0x03a3, 0x03ab,
+ 0x03c2, 0x03c2,
+ 0x03cf, 0x03d1,
+ 0x03d5, 0x03d6,
+ 0x03d8, 0x03d8,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03e2,
+ 0x03e4, 0x03e4,
+ 0x03e6, 0x03e6,
+ 0x03e8, 0x03e8,
+ 0x03ea, 0x03ea,
+ 0x03ec, 0x03ec,
+ 0x03ee, 0x03ee,
+ 0x03f0, 0x03f1,
+ 0x03f4, 0x03f5,
+ 0x03f7, 0x03f7,
+ 0x03f9, 0x03fa,
+ 0x03fd, 0x042f,
+ 0x0460, 0x0460,
+ 0x0462, 0x0462,
+ 0x0464, 0x0464,
+ 0x0466, 0x0466,
+ 0x0468, 0x0468,
+ 0x046a, 0x046a,
+ 0x046c, 0x046c,
+ 0x046e, 0x046e,
+ 0x0470, 0x0470,
+ 0x0472, 0x0472,
+ 0x0474, 0x0474,
+ 0x0476, 0x0476,
+ 0x0478, 0x0478,
+ 0x047a, 0x047a,
+ 0x047c, 0x047c,
+ 0x047e, 0x047e,
+ 0x0480, 0x0480,
+ 0x048a, 0x048a,
+ 0x048c, 0x048c,
+ 0x048e, 0x048e,
+ 0x0490, 0x0490,
+ 0x0492, 0x0492,
+ 0x0494, 0x0494,
+ 0x0496, 0x0496,
+ 0x0498, 0x0498,
+ 0x049a, 0x049a,
+ 0x049c, 0x049c,
+ 0x049e, 0x049e,
+ 0x04a0, 0x04a0,
+ 0x04a2, 0x04a2,
+ 0x04a4, 0x04a4,
+ 0x04a6, 0x04a6,
+ 0x04a8, 0x04a8,
+ 0x04aa, 0x04aa,
+ 0x04ac, 0x04ac,
+ 0x04ae, 0x04ae,
+ 0x04b0, 0x04b0,
+ 0x04b2, 0x04b2,
+ 0x04b4, 0x04b4,
+ 0x04b6, 0x04b6,
+ 0x04b8, 0x04b8,
+ 0x04ba, 0x04ba,
+ 0x04bc, 0x04bc,
+ 0x04be, 0x04be,
+ 0x04c0, 0x04c1,
+ 0x04c3, 0x04c3,
+ 0x04c5, 0x04c5,
+ 0x04c7, 0x04c7,
+ 0x04c9, 0x04c9,
+ 0x04cb, 0x04cb,
+ 0x04cd, 0x04cd,
+ 0x04d0, 0x04d0,
+ 0x04d2, 0x04d2,
+ 0x04d4, 0x04d4,
+ 0x04d6, 0x04d6,
+ 0x04d8, 0x04d8,
+ 0x04da, 0x04da,
+ 0x04dc, 0x04dc,
+ 0x04de, 0x04de,
+ 0x04e0, 0x04e0,
+ 0x04e2, 0x04e2,
+ 0x04e4, 0x04e4,
+ 0x04e6, 0x04e6,
+ 0x04e8, 0x04e8,
+ 0x04ea, 0x04ea,
+ 0x04ec, 0x04ec,
+ 0x04ee, 0x04ee,
+ 0x04f0, 0x04f0,
+ 0x04f2, 0x04f2,
+ 0x04f4, 0x04f4,
+ 0x04f6, 0x04f6,
+ 0x04f8, 0x04f8,
+ 0x04fa, 0x04fa,
+ 0x04fc, 0x04fc,
+ 0x04fe, 0x04fe,
+ 0x0500, 0x0500,
+ 0x0502, 0x0502,
+ 0x0504, 0x0504,
+ 0x0506, 0x0506,
+ 0x0508, 0x0508,
+ 0x050a, 0x050a,
+ 0x050c, 0x050c,
+ 0x050e, 0x050e,
+ 0x0510, 0x0510,
+ 0x0512, 0x0512,
+ 0x0514, 0x0514,
+ 0x0516, 0x0516,
+ 0x0518, 0x0518,
+ 0x051a, 0x051a,
+ 0x051c, 0x051c,
+ 0x051e, 0x051e,
+ 0x0520, 0x0520,
+ 0x0522, 0x0522,
+ 0x0524, 0x0524,
+ 0x0526, 0x0526,
+ 0x0528, 0x0528,
+ 0x052a, 0x052a,
+ 0x052c, 0x052c,
+ 0x052e, 0x052e,
+ 0x0531, 0x0556,
+ 0x0587, 0x0587,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1e00, 0x1e00,
+ 0x1e02, 0x1e02,
+ 0x1e04, 0x1e04,
+ 0x1e06, 0x1e06,
+ 0x1e08, 0x1e08,
+ 0x1e0a, 0x1e0a,
+ 0x1e0c, 0x1e0c,
+ 0x1e0e, 0x1e0e,
+ 0x1e10, 0x1e10,
+ 0x1e12, 0x1e12,
+ 0x1e14, 0x1e14,
+ 0x1e16, 0x1e16,
+ 0x1e18, 0x1e18,
+ 0x1e1a, 0x1e1a,
+ 0x1e1c, 0x1e1c,
+ 0x1e1e, 0x1e1e,
+ 0x1e20, 0x1e20,
+ 0x1e22, 0x1e22,
+ 0x1e24, 0x1e24,
+ 0x1e26, 0x1e26,
+ 0x1e28, 0x1e28,
+ 0x1e2a, 0x1e2a,
+ 0x1e2c, 0x1e2c,
+ 0x1e2e, 0x1e2e,
+ 0x1e30, 0x1e30,
+ 0x1e32, 0x1e32,
+ 0x1e34, 0x1e34,
+ 0x1e36, 0x1e36,
+ 0x1e38, 0x1e38,
+ 0x1e3a, 0x1e3a,
+ 0x1e3c, 0x1e3c,
+ 0x1e3e, 0x1e3e,
+ 0x1e40, 0x1e40,
+ 0x1e42, 0x1e42,
+ 0x1e44, 0x1e44,
+ 0x1e46, 0x1e46,
+ 0x1e48, 0x1e48,
+ 0x1e4a, 0x1e4a,
+ 0x1e4c, 0x1e4c,
+ 0x1e4e, 0x1e4e,
+ 0x1e50, 0x1e50,
+ 0x1e52, 0x1e52,
+ 0x1e54, 0x1e54,
+ 0x1e56, 0x1e56,
+ 0x1e58, 0x1e58,
+ 0x1e5a, 0x1e5a,
+ 0x1e5c, 0x1e5c,
+ 0x1e5e, 0x1e5e,
+ 0x1e60, 0x1e60,
+ 0x1e62, 0x1e62,
+ 0x1e64, 0x1e64,
+ 0x1e66, 0x1e66,
+ 0x1e68, 0x1e68,
+ 0x1e6a, 0x1e6a,
+ 0x1e6c, 0x1e6c,
+ 0x1e6e, 0x1e6e,
+ 0x1e70, 0x1e70,
+ 0x1e72, 0x1e72,
+ 0x1e74, 0x1e74,
+ 0x1e76, 0x1e76,
+ 0x1e78, 0x1e78,
+ 0x1e7a, 0x1e7a,
+ 0x1e7c, 0x1e7c,
+ 0x1e7e, 0x1e7e,
+ 0x1e80, 0x1e80,
+ 0x1e82, 0x1e82,
+ 0x1e84, 0x1e84,
+ 0x1e86, 0x1e86,
+ 0x1e88, 0x1e88,
+ 0x1e8a, 0x1e8a,
+ 0x1e8c, 0x1e8c,
+ 0x1e8e, 0x1e8e,
+ 0x1e90, 0x1e90,
+ 0x1e92, 0x1e92,
+ 0x1e94, 0x1e94,
+ 0x1e9a, 0x1e9b,
+ 0x1e9e, 0x1e9e,
+ 0x1ea0, 0x1ea0,
+ 0x1ea2, 0x1ea2,
+ 0x1ea4, 0x1ea4,
+ 0x1ea6, 0x1ea6,
+ 0x1ea8, 0x1ea8,
+ 0x1eaa, 0x1eaa,
+ 0x1eac, 0x1eac,
+ 0x1eae, 0x1eae,
+ 0x1eb0, 0x1eb0,
+ 0x1eb2, 0x1eb2,
+ 0x1eb4, 0x1eb4,
+ 0x1eb6, 0x1eb6,
+ 0x1eb8, 0x1eb8,
+ 0x1eba, 0x1eba,
+ 0x1ebc, 0x1ebc,
+ 0x1ebe, 0x1ebe,
+ 0x1ec0, 0x1ec0,
+ 0x1ec2, 0x1ec2,
+ 0x1ec4, 0x1ec4,
+ 0x1ec6, 0x1ec6,
+ 0x1ec8, 0x1ec8,
+ 0x1eca, 0x1eca,
+ 0x1ecc, 0x1ecc,
+ 0x1ece, 0x1ece,
+ 0x1ed0, 0x1ed0,
+ 0x1ed2, 0x1ed2,
+ 0x1ed4, 0x1ed4,
+ 0x1ed6, 0x1ed6,
+ 0x1ed8, 0x1ed8,
+ 0x1eda, 0x1eda,
+ 0x1edc, 0x1edc,
+ 0x1ede, 0x1ede,
+ 0x1ee0, 0x1ee0,
+ 0x1ee2, 0x1ee2,
+ 0x1ee4, 0x1ee4,
+ 0x1ee6, 0x1ee6,
+ 0x1ee8, 0x1ee8,
+ 0x1eea, 0x1eea,
+ 0x1eec, 0x1eec,
+ 0x1eee, 0x1eee,
+ 0x1ef0, 0x1ef0,
+ 0x1ef2, 0x1ef2,
+ 0x1ef4, 0x1ef4,
+ 0x1ef6, 0x1ef6,
+ 0x1ef8, 0x1ef8,
+ 0x1efa, 0x1efa,
+ 0x1efc, 0x1efc,
+ 0x1efe, 0x1efe,
+ 0x1f08, 0x1f0f,
+ 0x1f18, 0x1f1d,
+ 0x1f28, 0x1f2f,
+ 0x1f38, 0x1f3f,
+ 0x1f48, 0x1f4d,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f5f,
+ 0x1f68, 0x1f6f,
+ 0x1f80, 0x1faf,
+ 0x1fb2, 0x1fb4,
+ 0x1fb7, 0x1fbc,
+ 0x1fc2, 0x1fc4,
+ 0x1fc7, 0x1fcc,
+ 0x1fd8, 0x1fdb,
+ 0x1fe8, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff7, 0x1ffc,
+ 0x2126, 0x2126,
+ 0x212a, 0x212b,
+ 0x2132, 0x2132,
+ 0x2160, 0x216f,
+ 0x2183, 0x2183,
+ 0x24b6, 0x24cf,
+ 0x2c00, 0x2c2e,
+ 0x2c60, 0x2c60,
+ 0x2c62, 0x2c64,
+ 0x2c67, 0x2c67,
+ 0x2c69, 0x2c69,
+ 0x2c6b, 0x2c6b,
+ 0x2c6d, 0x2c70,
+ 0x2c72, 0x2c72,
+ 0x2c75, 0x2c75,
+ 0x2c7e, 0x2c80,
+ 0x2c82, 0x2c82,
+ 0x2c84, 0x2c84,
+ 0x2c86, 0x2c86,
+ 0x2c88, 0x2c88,
+ 0x2c8a, 0x2c8a,
+ 0x2c8c, 0x2c8c,
+ 0x2c8e, 0x2c8e,
+ 0x2c90, 0x2c90,
+ 0x2c92, 0x2c92,
+ 0x2c94, 0x2c94,
+ 0x2c96, 0x2c96,
+ 0x2c98, 0x2c98,
+ 0x2c9a, 0x2c9a,
+ 0x2c9c, 0x2c9c,
+ 0x2c9e, 0x2c9e,
+ 0x2ca0, 0x2ca0,
+ 0x2ca2, 0x2ca2,
+ 0x2ca4, 0x2ca4,
+ 0x2ca6, 0x2ca6,
+ 0x2ca8, 0x2ca8,
+ 0x2caa, 0x2caa,
+ 0x2cac, 0x2cac,
+ 0x2cae, 0x2cae,
+ 0x2cb0, 0x2cb0,
+ 0x2cb2, 0x2cb2,
+ 0x2cb4, 0x2cb4,
+ 0x2cb6, 0x2cb6,
+ 0x2cb8, 0x2cb8,
+ 0x2cba, 0x2cba,
+ 0x2cbc, 0x2cbc,
+ 0x2cbe, 0x2cbe,
+ 0x2cc0, 0x2cc0,
+ 0x2cc2, 0x2cc2,
+ 0x2cc4, 0x2cc4,
+ 0x2cc6, 0x2cc6,
+ 0x2cc8, 0x2cc8,
+ 0x2cca, 0x2cca,
+ 0x2ccc, 0x2ccc,
+ 0x2cce, 0x2cce,
+ 0x2cd0, 0x2cd0,
+ 0x2cd2, 0x2cd2,
+ 0x2cd4, 0x2cd4,
+ 0x2cd6, 0x2cd6,
+ 0x2cd8, 0x2cd8,
+ 0x2cda, 0x2cda,
+ 0x2cdc, 0x2cdc,
+ 0x2cde, 0x2cde,
+ 0x2ce0, 0x2ce0,
+ 0x2ce2, 0x2ce2,
+ 0x2ceb, 0x2ceb,
+ 0x2ced, 0x2ced,
+ 0x2cf2, 0x2cf2,
+ 0xa640, 0xa640,
+ 0xa642, 0xa642,
+ 0xa644, 0xa644,
+ 0xa646, 0xa646,
+ 0xa648, 0xa648,
+ 0xa64a, 0xa64a,
+ 0xa64c, 0xa64c,
+ 0xa64e, 0xa64e,
+ 0xa650, 0xa650,
+ 0xa652, 0xa652,
+ 0xa654, 0xa654,
+ 0xa656, 0xa656,
+ 0xa658, 0xa658,
+ 0xa65a, 0xa65a,
+ 0xa65c, 0xa65c,
+ 0xa65e, 0xa65e,
+ 0xa660, 0xa660,
+ 0xa662, 0xa662,
+ 0xa664, 0xa664,
+ 0xa666, 0xa666,
+ 0xa668, 0xa668,
+ 0xa66a, 0xa66a,
+ 0xa66c, 0xa66c,
+ 0xa680, 0xa680,
+ 0xa682, 0xa682,
+ 0xa684, 0xa684,
+ 0xa686, 0xa686,
+ 0xa688, 0xa688,
+ 0xa68a, 0xa68a,
+ 0xa68c, 0xa68c,
+ 0xa68e, 0xa68e,
+ 0xa690, 0xa690,
+ 0xa692, 0xa692,
+ 0xa694, 0xa694,
+ 0xa696, 0xa696,
+ 0xa698, 0xa698,
+ 0xa69a, 0xa69a,
+ 0xa722, 0xa722,
+ 0xa724, 0xa724,
+ 0xa726, 0xa726,
+ 0xa728, 0xa728,
+ 0xa72a, 0xa72a,
+ 0xa72c, 0xa72c,
+ 0xa72e, 0xa72e,
+ 0xa732, 0xa732,
+ 0xa734, 0xa734,
+ 0xa736, 0xa736,
+ 0xa738, 0xa738,
+ 0xa73a, 0xa73a,
+ 0xa73c, 0xa73c,
+ 0xa73e, 0xa73e,
+ 0xa740, 0xa740,
+ 0xa742, 0xa742,
+ 0xa744, 0xa744,
+ 0xa746, 0xa746,
+ 0xa748, 0xa748,
+ 0xa74a, 0xa74a,
+ 0xa74c, 0xa74c,
+ 0xa74e, 0xa74e,
+ 0xa750, 0xa750,
+ 0xa752, 0xa752,
+ 0xa754, 0xa754,
+ 0xa756, 0xa756,
+ 0xa758, 0xa758,
+ 0xa75a, 0xa75a,
+ 0xa75c, 0xa75c,
+ 0xa75e, 0xa75e,
+ 0xa760, 0xa760,
+ 0xa762, 0xa762,
+ 0xa764, 0xa764,
+ 0xa766, 0xa766,
+ 0xa768, 0xa768,
+ 0xa76a, 0xa76a,
+ 0xa76c, 0xa76c,
+ 0xa76e, 0xa76e,
+ 0xa779, 0xa779,
+ 0xa77b, 0xa77b,
+ 0xa77d, 0xa77e,
+ 0xa780, 0xa780,
+ 0xa782, 0xa782,
+ 0xa784, 0xa784,
+ 0xa786, 0xa786,
+ 0xa78b, 0xa78b,
+ 0xa78d, 0xa78d,
+ 0xa790, 0xa790,
+ 0xa792, 0xa792,
+ 0xa796, 0xa796,
+ 0xa798, 0xa798,
+ 0xa79a, 0xa79a,
+ 0xa79c, 0xa79c,
+ 0xa79e, 0xa79e,
+ 0xa7a0, 0xa7a0,
+ 0xa7a2, 0xa7a2,
+ 0xa7a4, 0xa7a4,
+ 0xa7a6, 0xa7a6,
+ 0xa7a8, 0xa7a8,
+ 0xa7aa, 0xa7ae,
+ 0xa7b0, 0xa7b4,
+ 0xa7b6, 0xa7b6,
+ 0xa7b8, 0xa7b8,
+ 0xa7ba, 0xa7ba,
+ 0xa7bc, 0xa7bc,
+ 0xa7be, 0xa7be,
+ 0xa7c2, 0xa7c2,
+ 0xa7c4, 0xa7c6,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff21, 0xff3a,
+ 0x10400, 0x10427,
+ 0x104b0, 0x104d3,
+ 0x10c80, 0x10cb2,
+ 0x118a0, 0x118bf,
+ 0x16e40, 0x16e5f,
+ 0x1e900, 0x1e921,
+}; /* CR_Changes_When_Casefolded */
+
+/* 'Changes_When_Casemapped': Derived Property */
+static const OnigCodePoint CR_Changes_When_Casemapped[] = {
+ 123,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00b5, 0x00b5,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x0137,
+ 0x0139, 0x018c,
+ 0x018e, 0x019a,
+ 0x019c, 0x01a9,
+ 0x01ac, 0x01b9,
+ 0x01bc, 0x01bd,
+ 0x01bf, 0x01bf,
+ 0x01c4, 0x0220,
+ 0x0222, 0x0233,
+ 0x023a, 0x0254,
+ 0x0256, 0x0257,
+ 0x0259, 0x0259,
+ 0x025b, 0x025c,
+ 0x0260, 0x0261,
+ 0x0263, 0x0263,
+ 0x0265, 0x0266,
+ 0x0268, 0x026c,
+ 0x026f, 0x026f,
+ 0x0271, 0x0272,
+ 0x0275, 0x0275,
+ 0x027d, 0x027d,
+ 0x0280, 0x0280,
+ 0x0282, 0x0283,
+ 0x0287, 0x028c,
+ 0x0292, 0x0292,
+ 0x029d, 0x029e,
+ 0x0345, 0x0345,
+ 0x0370, 0x0373,
+ 0x0376, 0x0377,
+ 0x037b, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03d1,
+ 0x03d5, 0x03f5,
+ 0x03f7, 0x03fb,
+ 0x03fd, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0561, 0x0587,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fd, 0x10ff,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1d79, 0x1d79,
+ 0x1d7d, 0x1d7d,
+ 0x1d8e, 0x1d8e,
+ 0x1e00, 0x1e9b,
+ 0x1e9e, 0x1e9e,
+ 0x1ea0, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2126, 0x2126,
+ 0x212a, 0x212b,
+ 0x2132, 0x2132,
+ 0x214e, 0x214e,
+ 0x2160, 0x217f,
+ 0x2183, 0x2184,
+ 0x24b6, 0x24e9,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2c70,
+ 0x2c72, 0x2c73,
+ 0x2c75, 0x2c76,
+ 0x2c7e, 0x2ce3,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0xa640, 0xa66d,
+ 0xa680, 0xa69b,
+ 0xa722, 0xa72f,
+ 0xa732, 0xa76f,
+ 0xa779, 0xa787,
+ 0xa78b, 0xa78d,
+ 0xa790, 0xa794,
+ 0xa796, 0xa7ae,
+ 0xa7b0, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xab53, 0xab53,
+ 0xab70, 0xabbf,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0x10400, 0x1044f,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x118a0, 0x118df,
+ 0x16e40, 0x16e7f,
+ 0x1e900, 0x1e943,
+}; /* CR_Changes_When_Casemapped */
+
+/* 'ID_Start': Derived Property */
+static const OnigCodePoint CR_ID_Start[] = {
+ 609,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0370, 0x0374,
+ 0x0376, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0620, 0x064a,
+ 0x066e, 0x066f,
+ 0x0671, 0x06d3,
+ 0x06d5, 0x06d5,
+ 0x06e5, 0x06e6,
+ 0x06ee, 0x06ef,
+ 0x06fa, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x0710,
+ 0x0712, 0x072f,
+ 0x074d, 0x07a5,
+ 0x07b1, 0x07b1,
+ 0x07ca, 0x07ea,
+ 0x07f4, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x0800, 0x0815,
+ 0x081a, 0x081a,
+ 0x0824, 0x0824,
+ 0x0828, 0x0828,
+ 0x0840, 0x0858,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x0904, 0x0939,
+ 0x093d, 0x093d,
+ 0x0950, 0x0950,
+ 0x0958, 0x0961,
+ 0x0971, 0x0980,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09bd,
+ 0x09ce, 0x09ce,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e1,
+ 0x09f0, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a72, 0x0a74,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0abd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae1,
+ 0x0af9, 0x0af9,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b3d,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b71, 0x0b71,
+ 0x0b83, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bd0, 0x0bd0,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c3d,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c61,
+ 0x0c80, 0x0c80,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cbd,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0cf1, 0x0cf2,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d3d,
+ 0x0d4e, 0x0d4e,
+ 0x0d54, 0x0d56,
+ 0x0d5f, 0x0d61,
+ 0x0d7a, 0x0d7f,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0e01, 0x0e30,
+ 0x0e32, 0x0e33,
+ 0x0e40, 0x0e46,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0eb0,
+ 0x0eb2, 0x0eb3,
+ 0x0ebd, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f88, 0x0f8c,
+ 0x1000, 0x102a,
+ 0x103f, 0x103f,
+ 0x1050, 0x1055,
+ 0x105a, 0x105d,
+ 0x1061, 0x1061,
+ 0x1065, 0x1066,
+ 0x106e, 0x1070,
+ 0x1075, 0x1081,
+ 0x108e, 0x108e,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1711,
+ 0x1720, 0x1731,
+ 0x1740, 0x1751,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1780, 0x17b3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dc,
+ 0x1820, 0x1878,
+ 0x1880, 0x18a8,
+ 0x18aa, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x1a00, 0x1a16,
+ 0x1a20, 0x1a54,
+ 0x1aa7, 0x1aa7,
+ 0x1b05, 0x1b33,
+ 0x1b45, 0x1b4b,
+ 0x1b83, 0x1ba0,
+ 0x1bae, 0x1baf,
+ 0x1bba, 0x1be5,
+ 0x1c00, 0x1c23,
+ 0x1c4d, 0x1c4f,
+ 0x1c5a, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf6,
+ 0x1cfa, 0x1cfa,
+ 0x1d00, 0x1dbf,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2118, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x3005, 0x3007,
+ 0x3021, 0x3029,
+ 0x3031, 0x3035,
+ 0x3038, 0x303c,
+ 0x3041, 0x3096,
+ 0x309b, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa61f,
+ 0xa62a, 0xa62b,
+ 0xa640, 0xa66e,
+ 0xa67f, 0xa69d,
+ 0xa6a0, 0xa6ef,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa801,
+ 0xa803, 0xa805,
+ 0xa807, 0xa80a,
+ 0xa80c, 0xa822,
+ 0xa840, 0xa873,
+ 0xa882, 0xa8b3,
+ 0xa8f2, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa8fe,
+ 0xa90a, 0xa925,
+ 0xa930, 0xa946,
+ 0xa960, 0xa97c,
+ 0xa984, 0xa9b2,
+ 0xa9cf, 0xa9cf,
+ 0xa9e0, 0xa9e4,
+ 0xa9e6, 0xa9ef,
+ 0xa9fa, 0xa9fe,
+ 0xaa00, 0xaa28,
+ 0xaa40, 0xaa42,
+ 0xaa44, 0xaa4b,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaa7a,
+ 0xaa7e, 0xaaaf,
+ 0xaab1, 0xaab1,
+ 0xaab5, 0xaab6,
+ 0xaab9, 0xaabd,
+ 0xaac0, 0xaac0,
+ 0xaac2, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaea,
+ 0xaaf2, 0xaaf4,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabe2,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb1d,
+ 0xfb1f, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10140, 0x10174,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x10375,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a00,
+ 0x10a10, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae4,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d23,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f45,
+ 0x10fe0, 0x10ff6,
+ 0x11003, 0x11037,
+ 0x11083, 0x110af,
+ 0x110d0, 0x110e8,
+ 0x11103, 0x11126,
+ 0x11144, 0x11144,
+ 0x11150, 0x11172,
+ 0x11176, 0x11176,
+ 0x11183, 0x111b2,
+ 0x111c1, 0x111c4,
+ 0x111da, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x1122b,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112de,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133d, 0x1133d,
+ 0x11350, 0x11350,
+ 0x1135d, 0x11361,
+ 0x11400, 0x11434,
+ 0x11447, 0x1144a,
+ 0x1145f, 0x1145f,
+ 0x11480, 0x114af,
+ 0x114c4, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x11580, 0x115ae,
+ 0x115d8, 0x115db,
+ 0x11600, 0x1162f,
+ 0x11644, 0x11644,
+ 0x11680, 0x116aa,
+ 0x116b8, 0x116b8,
+ 0x11700, 0x1171a,
+ 0x11800, 0x1182b,
+ 0x118a0, 0x118df,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d0,
+ 0x119e1, 0x119e1,
+ 0x119e3, 0x119e3,
+ 0x11a00, 0x11a00,
+ 0x11a0b, 0x11a32,
+ 0x11a3a, 0x11a3a,
+ 0x11a50, 0x11a50,
+ 0x11a5c, 0x11a89,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c2e,
+ 0x11c40, 0x11c40,
+ 0x11c72, 0x11c8f,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d30,
+ 0x11d46, 0x11d46,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d89,
+ 0x11d98, 0x11d98,
+ 0x11ee0, 0x11ef2,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16ad0, 0x16aed,
+ 0x16b00, 0x16b2f,
+ 0x16b40, 0x16b43,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f50, 0x16f50,
+ 0x16f93, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1e100, 0x1e12c,
+ 0x1e137, 0x1e13d,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2eb,
+ 0x1e800, 0x1e8c4,
+ 0x1e900, 0x1e943,
+ 0x1e94b, 0x1e94b,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_ID_Start */
+
+/* 'ID_Continue': Derived Property */
+static const OnigCodePoint CR_ID_Continue[] = {
+ 713,
+ 0x0030, 0x0039,
+ 0x0041, 0x005a,
+ 0x005f, 0x005f,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00b7, 0x00b7,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0300, 0x0374,
+ 0x0376, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x0483, 0x0487,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0610, 0x061a,
+ 0x0620, 0x0669,
+ 0x066e, 0x06d3,
+ 0x06d5, 0x06dc,
+ 0x06df, 0x06e8,
+ 0x06ea, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x07fd, 0x07fd,
+ 0x0800, 0x082d,
+ 0x0840, 0x085b,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x0963,
+ 0x0966, 0x096f,
+ 0x0971, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b6f,
+ 0x0b71, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bef,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c80, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d54, 0x0d57,
+ 0x0d5f, 0x0d63,
+ 0x0d66, 0x0d6f,
+ 0x0d7a, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df3,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e4e,
+ 0x0e50, 0x0e59,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f18, 0x0f19,
+ 0x0f20, 0x0f29,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f3e, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f84,
+ 0x0f86, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x1000, 0x1049,
+ 0x1050, 0x109d,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x135f,
+ 0x1369, 0x1371,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1734,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17d3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x180b, 0x180d,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1946, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x1a00, 0x1a1b,
+ 0x1a20, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa7, 0x1aa7,
+ 0x1ab0, 0x1abd,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b59,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1bf3,
+ 0x1c00, 0x1c37,
+ 0x1c40, 0x1c49,
+ 0x1c4d, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x203f, 0x2040,
+ 0x2054, 0x2054,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x20d0, 0x20dc,
+ 0x20e1, 0x20e1,
+ 0x20e5, 0x20f0,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2118, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2dff,
+ 0x3005, 0x3007,
+ 0x3021, 0x302f,
+ 0x3031, 0x3035,
+ 0x3038, 0x303c,
+ 0x3041, 0x3096,
+ 0x3099, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa62b,
+ 0xa640, 0xa66f,
+ 0xa674, 0xa67d,
+ 0xa67f, 0xa6f1,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa827,
+ 0xa840, 0xa873,
+ 0xa880, 0xa8c5,
+ 0xa8d0, 0xa8d9,
+ 0xa8e0, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa92d,
+ 0xa930, 0xa953,
+ 0xa960, 0xa97c,
+ 0xa980, 0xa9c0,
+ 0xa9cf, 0xa9d9,
+ 0xa9e0, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaef,
+ 0xaaf2, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabea,
+ 0xabec, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2f,
+ 0xfe33, 0xfe34,
+ 0xfe4d, 0xfe4f,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff10, 0xff19,
+ 0xff21, 0xff3a,
+ 0xff3f, 0xff3f,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10140, 0x10174,
+ 0x101fd, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102e0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae6,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f50,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x11046,
+ 0x11066, 0x1106f,
+ 0x1107f, 0x110ba,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x1113f,
+ 0x11144, 0x11146,
+ 0x11150, 0x11173,
+ 0x11176, 0x11176,
+ 0x11180, 0x111c4,
+ 0x111c9, 0x111cc,
+ 0x111d0, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x1144a,
+ 0x11450, 0x11459,
+ 0x1145e, 0x1145f,
+ 0x11480, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115c0,
+ 0x115d8, 0x115dd,
+ 0x11600, 0x11640,
+ 0x11644, 0x11644,
+ 0x11650, 0x11659,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x11739,
+ 0x11800, 0x1183a,
+ 0x118a0, 0x118e9,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e1,
+ 0x119e3, 0x119e4,
+ 0x11a00, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a50, 0x11a99,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c40,
+ 0x11c50, 0x11c59,
+ 0x11c72, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef6,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af4,
+ 0x16b00, 0x16b36,
+ 0x16b40, 0x16b43,
+ 0x16b50, 0x16b59,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9d, 0x1bc9e,
+ 0x1d165, 0x1d169,
+ 0x1d16d, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e800, 0x1e8c4,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0xe0100, 0xe01ef,
+}; /* CR_ID_Continue */
+
+/* 'XID_Start': Derived Property */
+static const OnigCodePoint CR_XID_Start[] = {
+ 616,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0370, 0x0374,
+ 0x0376, 0x0377,
+ 0x037b, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0620, 0x064a,
+ 0x066e, 0x066f,
+ 0x0671, 0x06d3,
+ 0x06d5, 0x06d5,
+ 0x06e5, 0x06e6,
+ 0x06ee, 0x06ef,
+ 0x06fa, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x0710,
+ 0x0712, 0x072f,
+ 0x074d, 0x07a5,
+ 0x07b1, 0x07b1,
+ 0x07ca, 0x07ea,
+ 0x07f4, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x0800, 0x0815,
+ 0x081a, 0x081a,
+ 0x0824, 0x0824,
+ 0x0828, 0x0828,
+ 0x0840, 0x0858,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x0904, 0x0939,
+ 0x093d, 0x093d,
+ 0x0950, 0x0950,
+ 0x0958, 0x0961,
+ 0x0971, 0x0980,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09bd,
+ 0x09ce, 0x09ce,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e1,
+ 0x09f0, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a72, 0x0a74,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0abd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae1,
+ 0x0af9, 0x0af9,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b3d,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b71, 0x0b71,
+ 0x0b83, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bd0, 0x0bd0,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c3d,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c61,
+ 0x0c80, 0x0c80,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cbd,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0cf1, 0x0cf2,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d3d,
+ 0x0d4e, 0x0d4e,
+ 0x0d54, 0x0d56,
+ 0x0d5f, 0x0d61,
+ 0x0d7a, 0x0d7f,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0e01, 0x0e30,
+ 0x0e32, 0x0e32,
+ 0x0e40, 0x0e46,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0eb0,
+ 0x0eb2, 0x0eb2,
+ 0x0ebd, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f88, 0x0f8c,
+ 0x1000, 0x102a,
+ 0x103f, 0x103f,
+ 0x1050, 0x1055,
+ 0x105a, 0x105d,
+ 0x1061, 0x1061,
+ 0x1065, 0x1066,
+ 0x106e, 0x1070,
+ 0x1075, 0x1081,
+ 0x108e, 0x108e,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1711,
+ 0x1720, 0x1731,
+ 0x1740, 0x1751,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1780, 0x17b3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dc,
+ 0x1820, 0x1878,
+ 0x1880, 0x18a8,
+ 0x18aa, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x1a00, 0x1a16,
+ 0x1a20, 0x1a54,
+ 0x1aa7, 0x1aa7,
+ 0x1b05, 0x1b33,
+ 0x1b45, 0x1b4b,
+ 0x1b83, 0x1ba0,
+ 0x1bae, 0x1baf,
+ 0x1bba, 0x1be5,
+ 0x1c00, 0x1c23,
+ 0x1c4d, 0x1c4f,
+ 0x1c5a, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf6,
+ 0x1cfa, 0x1cfa,
+ 0x1d00, 0x1dbf,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2118, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x3005, 0x3007,
+ 0x3021, 0x3029,
+ 0x3031, 0x3035,
+ 0x3038, 0x303c,
+ 0x3041, 0x3096,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa61f,
+ 0xa62a, 0xa62b,
+ 0xa640, 0xa66e,
+ 0xa67f, 0xa69d,
+ 0xa6a0, 0xa6ef,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa801,
+ 0xa803, 0xa805,
+ 0xa807, 0xa80a,
+ 0xa80c, 0xa822,
+ 0xa840, 0xa873,
+ 0xa882, 0xa8b3,
+ 0xa8f2, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa8fe,
+ 0xa90a, 0xa925,
+ 0xa930, 0xa946,
+ 0xa960, 0xa97c,
+ 0xa984, 0xa9b2,
+ 0xa9cf, 0xa9cf,
+ 0xa9e0, 0xa9e4,
+ 0xa9e6, 0xa9ef,
+ 0xa9fa, 0xa9fe,
+ 0xaa00, 0xaa28,
+ 0xaa40, 0xaa42,
+ 0xaa44, 0xaa4b,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaa7a,
+ 0xaa7e, 0xaaaf,
+ 0xaab1, 0xaab1,
+ 0xaab5, 0xaab6,
+ 0xaab9, 0xaabd,
+ 0xaac0, 0xaac0,
+ 0xaac2, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaea,
+ 0xaaf2, 0xaaf4,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabe2,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb1d,
+ 0xfb1f, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfc5d,
+ 0xfc64, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdf9,
+ 0xfe71, 0xfe71,
+ 0xfe73, 0xfe73,
+ 0xfe77, 0xfe77,
+ 0xfe79, 0xfe79,
+ 0xfe7b, 0xfe7b,
+ 0xfe7d, 0xfe7d,
+ 0xfe7f, 0xfefc,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0xff66, 0xff9d,
+ 0xffa0, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10140, 0x10174,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x10375,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a00,
+ 0x10a10, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae4,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d23,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f45,
+ 0x10fe0, 0x10ff6,
+ 0x11003, 0x11037,
+ 0x11083, 0x110af,
+ 0x110d0, 0x110e8,
+ 0x11103, 0x11126,
+ 0x11144, 0x11144,
+ 0x11150, 0x11172,
+ 0x11176, 0x11176,
+ 0x11183, 0x111b2,
+ 0x111c1, 0x111c4,
+ 0x111da, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x1122b,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112de,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133d, 0x1133d,
+ 0x11350, 0x11350,
+ 0x1135d, 0x11361,
+ 0x11400, 0x11434,
+ 0x11447, 0x1144a,
+ 0x1145f, 0x1145f,
+ 0x11480, 0x114af,
+ 0x114c4, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x11580, 0x115ae,
+ 0x115d8, 0x115db,
+ 0x11600, 0x1162f,
+ 0x11644, 0x11644,
+ 0x11680, 0x116aa,
+ 0x116b8, 0x116b8,
+ 0x11700, 0x1171a,
+ 0x11800, 0x1182b,
+ 0x118a0, 0x118df,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d0,
+ 0x119e1, 0x119e1,
+ 0x119e3, 0x119e3,
+ 0x11a00, 0x11a00,
+ 0x11a0b, 0x11a32,
+ 0x11a3a, 0x11a3a,
+ 0x11a50, 0x11a50,
+ 0x11a5c, 0x11a89,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c2e,
+ 0x11c40, 0x11c40,
+ 0x11c72, 0x11c8f,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d30,
+ 0x11d46, 0x11d46,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d89,
+ 0x11d98, 0x11d98,
+ 0x11ee0, 0x11ef2,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16ad0, 0x16aed,
+ 0x16b00, 0x16b2f,
+ 0x16b40, 0x16b43,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f50, 0x16f50,
+ 0x16f93, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1e100, 0x1e12c,
+ 0x1e137, 0x1e13d,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2eb,
+ 0x1e800, 0x1e8c4,
+ 0x1e900, 0x1e943,
+ 0x1e94b, 0x1e94b,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_XID_Start */
+
+/* 'XID_Continue': Derived Property */
+static const OnigCodePoint CR_XID_Continue[] = {
+ 720,
+ 0x0030, 0x0039,
+ 0x0041, 0x005a,
+ 0x005f, 0x005f,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00b7, 0x00b7,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ec, 0x02ec,
+ 0x02ee, 0x02ee,
+ 0x0300, 0x0374,
+ 0x0376, 0x0377,
+ 0x037b, 0x037d,
+ 0x037f, 0x037f,
+ 0x0386, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x0483, 0x0487,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0560, 0x0588,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f2,
+ 0x0610, 0x061a,
+ 0x0620, 0x0669,
+ 0x066e, 0x06d3,
+ 0x06d5, 0x06dc,
+ 0x06df, 0x06e8,
+ 0x06ea, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07f5,
+ 0x07fa, 0x07fa,
+ 0x07fd, 0x07fd,
+ 0x0800, 0x082d,
+ 0x0840, 0x085b,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x0963,
+ 0x0966, 0x096f,
+ 0x0971, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09f1,
+ 0x09fc, 0x09fc,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b6f,
+ 0x0b71, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bef,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c80, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d54, 0x0d57,
+ 0x0d5f, 0x0d63,
+ 0x0d66, 0x0d6f,
+ 0x0d7a, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df3,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e4e,
+ 0x0e50, 0x0e59,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f00,
+ 0x0f18, 0x0f19,
+ 0x0f20, 0x0f29,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f3e, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f84,
+ 0x0f86, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x1000, 0x1049,
+ 0x1050, 0x109d,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x135f,
+ 0x1369, 0x1371,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1401, 0x166c,
+ 0x166f, 0x167f,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1734,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17d3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x180b, 0x180d,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1946, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x1a00, 0x1a1b,
+ 0x1a20, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa7, 0x1aa7,
+ 0x1ab0, 0x1abd,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b59,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1bf3,
+ 0x1c00, 0x1c37,
+ 0x1c40, 0x1c49,
+ 0x1c4d, 0x1c7d,
+ 0x1c80, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x203f, 0x2040,
+ 0x2054, 0x2054,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x20d0, 0x20dc,
+ 0x20e1, 0x20e1,
+ 0x20e5, 0x20f0,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2118, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2ce4,
+ 0x2ceb, 0x2cf3,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d6f,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2dff,
+ 0x3005, 0x3007,
+ 0x3021, 0x302f,
+ 0x3031, 0x3035,
+ 0x3038, 0x303c,
+ 0x3041, 0x3096,
+ 0x3099, 0x309a,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31ba,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa4d0, 0xa4fd,
+ 0xa500, 0xa60c,
+ 0xa610, 0xa62b,
+ 0xa640, 0xa66f,
+ 0xa674, 0xa67d,
+ 0xa67f, 0xa6f1,
+ 0xa717, 0xa71f,
+ 0xa722, 0xa788,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa827,
+ 0xa840, 0xa873,
+ 0xa880, 0xa8c5,
+ 0xa8d0, 0xa8d9,
+ 0xa8e0, 0xa8f7,
+ 0xa8fb, 0xa8fb,
+ 0xa8fd, 0xa92d,
+ 0xa930, 0xa953,
+ 0xa960, 0xa97c,
+ 0xa980, 0xa9c0,
+ 0xa9cf, 0xa9d9,
+ 0xa9e0, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa60, 0xaa76,
+ 0xaa7a, 0xaac2,
+ 0xaadb, 0xaadd,
+ 0xaae0, 0xaaef,
+ 0xaaf2, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab67,
+ 0xab70, 0xabea,
+ 0xabec, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfc5d,
+ 0xfc64, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdf9,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2f,
+ 0xfe33, 0xfe34,
+ 0xfe4d, 0xfe4f,
+ 0xfe71, 0xfe71,
+ 0xfe73, 0xfe73,
+ 0xfe77, 0xfe77,
+ 0xfe79, 0xfe79,
+ 0xfe7b, 0xfe7b,
+ 0xfe7d, 0xfe7d,
+ 0xfe7f, 0xfefc,
+ 0xff10, 0xff19,
+ 0xff21, 0xff3a,
+ 0xff3f, 0xff3f,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10140, 0x10174,
+ 0x101fd, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102e0,
+ 0x10300, 0x1031f,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10860, 0x10876,
+ 0x10880, 0x1089e,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x10900, 0x10915,
+ 0x10920, 0x10939,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10a60, 0x10a7c,
+ 0x10a80, 0x10a9c,
+ 0x10ac0, 0x10ac7,
+ 0x10ac9, 0x10ae6,
+ 0x10b00, 0x10b35,
+ 0x10b40, 0x10b55,
+ 0x10b60, 0x10b72,
+ 0x10b80, 0x10b91,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10d00, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10f00, 0x10f1c,
+ 0x10f27, 0x10f27,
+ 0x10f30, 0x10f50,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x11046,
+ 0x11066, 0x1106f,
+ 0x1107f, 0x110ba,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x1113f,
+ 0x11144, 0x11146,
+ 0x11150, 0x11173,
+ 0x11176, 0x11176,
+ 0x11180, 0x111c4,
+ 0x111c9, 0x111cc,
+ 0x111d0, 0x111da,
+ 0x111dc, 0x111dc,
+ 0x11200, 0x11211,
+ 0x11213, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a8,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x1144a,
+ 0x11450, 0x11459,
+ 0x1145e, 0x1145f,
+ 0x11480, 0x114c5,
+ 0x114c7, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115c0,
+ 0x115d8, 0x115dd,
+ 0x11600, 0x11640,
+ 0x11644, 0x11644,
+ 0x11650, 0x11659,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x11739,
+ 0x11800, 0x1183a,
+ 0x118a0, 0x118e9,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e1,
+ 0x119e3, 0x119e4,
+ 0x11a00, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a50, 0x11a99,
+ 0x11a9d, 0x11a9d,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c40,
+ 0x11c50, 0x11c59,
+ 0x11c72, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef6,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af4,
+ 0x16b00, 0x16b36,
+ 0x16b40, 0x16b43,
+ 0x16b50, 0x16b59,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e7f,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9d, 0x1bc9e,
+ 0x1d165, 0x1d169,
+ 0x1d16d, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14e,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e800, 0x1e8c4,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0xe0100, 0xe01ef,
+}; /* CR_XID_Continue */
+
+/* 'Default_Ignorable_Code_Point': Derived Property */
+static const OnigCodePoint CR_Default_Ignorable_Code_Point[] = {
+ 17,
+ 0x00ad, 0x00ad,
+ 0x034f, 0x034f,
+ 0x061c, 0x061c,
+ 0x115f, 0x1160,
+ 0x17b4, 0x17b5,
+ 0x180b, 0x180e,
+ 0x200b, 0x200f,
+ 0x202a, 0x202e,
+ 0x2060, 0x206f,
+ 0x3164, 0x3164,
+ 0xfe00, 0xfe0f,
+ 0xfeff, 0xfeff,
+ 0xffa0, 0xffa0,
+ 0xfff0, 0xfff8,
+ 0x1bca0, 0x1bca3,
+ 0x1d173, 0x1d17a,
+ 0xe0000, 0xe0fff,
+}; /* CR_Default_Ignorable_Code_Point */
+
+/* 'Grapheme_Extend': Derived Property */
+static const OnigCodePoint CR_Grapheme_Extend[] = {
+ 335,
+ 0x0300, 0x036f,
+ 0x0483, 0x0489,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x0610, 0x061a,
+ 0x064b, 0x065f,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dc,
+ 0x06df, 0x06e4,
+ 0x06e7, 0x06e8,
+ 0x06ea, 0x06ed,
+ 0x0711, 0x0711,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x07eb, 0x07f3,
+ 0x07fd, 0x07fd,
+ 0x0816, 0x0819,
+ 0x081b, 0x0823,
+ 0x0825, 0x0827,
+ 0x0829, 0x082d,
+ 0x0859, 0x085b,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x0902,
+ 0x093a, 0x093a,
+ 0x093c, 0x093c,
+ 0x0941, 0x0948,
+ 0x094d, 0x094d,
+ 0x0951, 0x0957,
+ 0x0962, 0x0963,
+ 0x0981, 0x0981,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09be,
+ 0x09c1, 0x09c4,
+ 0x09cd, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09e2, 0x09e3,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a02,
+ 0x0a3c, 0x0a3c,
+ 0x0a41, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a70, 0x0a71,
+ 0x0a75, 0x0a75,
+ 0x0a81, 0x0a82,
+ 0x0abc, 0x0abc,
+ 0x0ac1, 0x0ac5,
+ 0x0ac7, 0x0ac8,
+ 0x0acd, 0x0acd,
+ 0x0ae2, 0x0ae3,
+ 0x0afa, 0x0aff,
+ 0x0b01, 0x0b01,
+ 0x0b3c, 0x0b3c,
+ 0x0b3e, 0x0b3f,
+ 0x0b41, 0x0b44,
+ 0x0b4d, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b62, 0x0b63,
+ 0x0b82, 0x0b82,
+ 0x0bbe, 0x0bbe,
+ 0x0bc0, 0x0bc0,
+ 0x0bcd, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0c00, 0x0c00,
+ 0x0c04, 0x0c04,
+ 0x0c3e, 0x0c40,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c62, 0x0c63,
+ 0x0c81, 0x0c81,
+ 0x0cbc, 0x0cbc,
+ 0x0cbf, 0x0cbf,
+ 0x0cc2, 0x0cc2,
+ 0x0cc6, 0x0cc6,
+ 0x0ccc, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0ce2, 0x0ce3,
+ 0x0d00, 0x0d01,
+ 0x0d3b, 0x0d3c,
+ 0x0d3e, 0x0d3e,
+ 0x0d41, 0x0d44,
+ 0x0d4d, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d62, 0x0d63,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dcf,
+ 0x0dd2, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0ddf, 0x0ddf,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e47, 0x0e4e,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0ebc,
+ 0x0ec8, 0x0ecd,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f71, 0x0f7e,
+ 0x0f80, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0f8d, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x102d, 0x1030,
+ 0x1032, 0x1037,
+ 0x1039, 0x103a,
+ 0x103d, 0x103e,
+ 0x1058, 0x1059,
+ 0x105e, 0x1060,
+ 0x1071, 0x1074,
+ 0x1082, 0x1082,
+ 0x1085, 0x1086,
+ 0x108d, 0x108d,
+ 0x109d, 0x109d,
+ 0x135d, 0x135f,
+ 0x1712, 0x1714,
+ 0x1732, 0x1734,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b4, 0x17b5,
+ 0x17b7, 0x17bd,
+ 0x17c6, 0x17c6,
+ 0x17c9, 0x17d3,
+ 0x17dd, 0x17dd,
+ 0x180b, 0x180d,
+ 0x1885, 0x1886,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x1922,
+ 0x1927, 0x1928,
+ 0x1932, 0x1932,
+ 0x1939, 0x193b,
+ 0x1a17, 0x1a18,
+ 0x1a1b, 0x1a1b,
+ 0x1a56, 0x1a56,
+ 0x1a58, 0x1a5e,
+ 0x1a60, 0x1a60,
+ 0x1a62, 0x1a62,
+ 0x1a65, 0x1a6c,
+ 0x1a73, 0x1a7c,
+ 0x1a7f, 0x1a7f,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b03,
+ 0x1b34, 0x1b3a,
+ 0x1b3c, 0x1b3c,
+ 0x1b42, 0x1b42,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1b81,
+ 0x1ba2, 0x1ba5,
+ 0x1ba8, 0x1ba9,
+ 0x1bab, 0x1bad,
+ 0x1be6, 0x1be6,
+ 0x1be8, 0x1be9,
+ 0x1bed, 0x1bed,
+ 0x1bef, 0x1bf1,
+ 0x1c2c, 0x1c33,
+ 0x1c36, 0x1c37,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1ce0,
+ 0x1ce2, 0x1ce8,
+ 0x1ced, 0x1ced,
+ 0x1cf4, 0x1cf4,
+ 0x1cf8, 0x1cf9,
+ 0x1dc0, 0x1df9,
+ 0x1dfb, 0x1dff,
+ 0x200c, 0x200c,
+ 0x20d0, 0x20f0,
+ 0x2cef, 0x2cf1,
+ 0x2d7f, 0x2d7f,
+ 0x2de0, 0x2dff,
+ 0x302a, 0x302f,
+ 0x3099, 0x309a,
+ 0xa66f, 0xa672,
+ 0xa674, 0xa67d,
+ 0xa69e, 0xa69f,
+ 0xa6f0, 0xa6f1,
+ 0xa802, 0xa802,
+ 0xa806, 0xa806,
+ 0xa80b, 0xa80b,
+ 0xa825, 0xa826,
+ 0xa8c4, 0xa8c5,
+ 0xa8e0, 0xa8f1,
+ 0xa8ff, 0xa8ff,
+ 0xa926, 0xa92d,
+ 0xa947, 0xa951,
+ 0xa980, 0xa982,
+ 0xa9b3, 0xa9b3,
+ 0xa9b6, 0xa9b9,
+ 0xa9bc, 0xa9bd,
+ 0xa9e5, 0xa9e5,
+ 0xaa29, 0xaa2e,
+ 0xaa31, 0xaa32,
+ 0xaa35, 0xaa36,
+ 0xaa43, 0xaa43,
+ 0xaa4c, 0xaa4c,
+ 0xaa7c, 0xaa7c,
+ 0xaab0, 0xaab0,
+ 0xaab2, 0xaab4,
+ 0xaab7, 0xaab8,
+ 0xaabe, 0xaabf,
+ 0xaac1, 0xaac1,
+ 0xaaec, 0xaaed,
+ 0xaaf6, 0xaaf6,
+ 0xabe5, 0xabe5,
+ 0xabe8, 0xabe8,
+ 0xabed, 0xabed,
+ 0xfb1e, 0xfb1e,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2f,
+ 0xff9e, 0xff9f,
+ 0x101fd, 0x101fd,
+ 0x102e0, 0x102e0,
+ 0x10376, 0x1037a,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10ae5, 0x10ae6,
+ 0x10d24, 0x10d27,
+ 0x10f46, 0x10f50,
+ 0x11001, 0x11001,
+ 0x11038, 0x11046,
+ 0x1107f, 0x11081,
+ 0x110b3, 0x110b6,
+ 0x110b9, 0x110ba,
+ 0x11100, 0x11102,
+ 0x11127, 0x1112b,
+ 0x1112d, 0x11134,
+ 0x11173, 0x11173,
+ 0x11180, 0x11181,
+ 0x111b6, 0x111be,
+ 0x111c9, 0x111cc,
+ 0x1122f, 0x11231,
+ 0x11234, 0x11234,
+ 0x11236, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x112df, 0x112df,
+ 0x112e3, 0x112ea,
+ 0x11300, 0x11301,
+ 0x1133b, 0x1133c,
+ 0x1133e, 0x1133e,
+ 0x11340, 0x11340,
+ 0x11357, 0x11357,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11438, 0x1143f,
+ 0x11442, 0x11444,
+ 0x11446, 0x11446,
+ 0x1145e, 0x1145e,
+ 0x114b0, 0x114b0,
+ 0x114b3, 0x114b8,
+ 0x114ba, 0x114ba,
+ 0x114bd, 0x114bd,
+ 0x114bf, 0x114c0,
+ 0x114c2, 0x114c3,
+ 0x115af, 0x115af,
+ 0x115b2, 0x115b5,
+ 0x115bc, 0x115bd,
+ 0x115bf, 0x115c0,
+ 0x115dc, 0x115dd,
+ 0x11633, 0x1163a,
+ 0x1163d, 0x1163d,
+ 0x1163f, 0x11640,
+ 0x116ab, 0x116ab,
+ 0x116ad, 0x116ad,
+ 0x116b0, 0x116b5,
+ 0x116b7, 0x116b7,
+ 0x1171d, 0x1171f,
+ 0x11722, 0x11725,
+ 0x11727, 0x1172b,
+ 0x1182f, 0x11837,
+ 0x11839, 0x1183a,
+ 0x119d4, 0x119d7,
+ 0x119da, 0x119db,
+ 0x119e0, 0x119e0,
+ 0x11a01, 0x11a0a,
+ 0x11a33, 0x11a38,
+ 0x11a3b, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a51, 0x11a56,
+ 0x11a59, 0x11a5b,
+ 0x11a8a, 0x11a96,
+ 0x11a98, 0x11a99,
+ 0x11c30, 0x11c36,
+ 0x11c38, 0x11c3d,
+ 0x11c3f, 0x11c3f,
+ 0x11c92, 0x11ca7,
+ 0x11caa, 0x11cb0,
+ 0x11cb2, 0x11cb3,
+ 0x11cb5, 0x11cb6,
+ 0x11d31, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d45,
+ 0x11d47, 0x11d47,
+ 0x11d90, 0x11d91,
+ 0x11d95, 0x11d95,
+ 0x11d97, 0x11d97,
+ 0x11ef3, 0x11ef4,
+ 0x16af0, 0x16af4,
+ 0x16b30, 0x16b36,
+ 0x16f4f, 0x16f4f,
+ 0x16f8f, 0x16f92,
+ 0x1bc9d, 0x1bc9e,
+ 0x1d165, 0x1d165,
+ 0x1d167, 0x1d169,
+ 0x1d16e, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e130, 0x1e136,
+ 0x1e2ec, 0x1e2ef,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e944, 0x1e94a,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+}; /* CR_Grapheme_Extend */
+
+/* 'Grapheme_Base': Derived Property */
+static const OnigCodePoint CR_Grapheme_Base[] = {
+ 819,
+ 0x0020, 0x007e,
+ 0x00a0, 0x00ac,
+ 0x00ae, 0x02ff,
+ 0x0370, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x0482,
+ 0x048a, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x058f,
+ 0x05be, 0x05be,
+ 0x05c0, 0x05c0,
+ 0x05c3, 0x05c3,
+ 0x05c6, 0x05c6,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0606, 0x060f,
+ 0x061b, 0x061b,
+ 0x061e, 0x064a,
+ 0x0660, 0x066f,
+ 0x0671, 0x06d5,
+ 0x06de, 0x06de,
+ 0x06e5, 0x06e6,
+ 0x06e9, 0x06e9,
+ 0x06ee, 0x070d,
+ 0x0710, 0x0710,
+ 0x0712, 0x072f,
+ 0x074d, 0x07a5,
+ 0x07b1, 0x07b1,
+ 0x07c0, 0x07ea,
+ 0x07f4, 0x07fa,
+ 0x07fe, 0x0815,
+ 0x081a, 0x081a,
+ 0x0824, 0x0824,
+ 0x0828, 0x0828,
+ 0x0830, 0x083e,
+ 0x0840, 0x0858,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x0903, 0x0939,
+ 0x093b, 0x093b,
+ 0x093d, 0x0940,
+ 0x0949, 0x094c,
+ 0x094e, 0x0950,
+ 0x0958, 0x0961,
+ 0x0964, 0x0980,
+ 0x0982, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09bd,
+ 0x09bf, 0x09c0,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cc,
+ 0x09ce, 0x09ce,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e1,
+ 0x09e6, 0x09fd,
+ 0x0a03, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3e, 0x0a40,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a6f,
+ 0x0a72, 0x0a74,
+ 0x0a76, 0x0a76,
+ 0x0a83, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0ac0,
+ 0x0ac9, 0x0ac9,
+ 0x0acb, 0x0acc,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae1,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0af9,
+ 0x0b02, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b3d,
+ 0x0b40, 0x0b40,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4c,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b77,
+ 0x0b83, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbf, 0x0bbf,
+ 0x0bc1, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcc,
+ 0x0bd0, 0x0bd0,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c3d,
+ 0x0c41, 0x0c44,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0c80,
+ 0x0c82, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cbe,
+ 0x0cc0, 0x0cc1,
+ 0x0cc3, 0x0cc4,
+ 0x0cc7, 0x0cc8,
+ 0x0cca, 0x0ccb,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d3d,
+ 0x0d3f, 0x0d40,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4c,
+ 0x0d4e, 0x0d4f,
+ 0x0d54, 0x0d56,
+ 0x0d58, 0x0d61,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dd0, 0x0dd1,
+ 0x0dd8, 0x0dde,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e30,
+ 0x0e32, 0x0e33,
+ 0x0e3f, 0x0e46,
+ 0x0e4f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0eb0,
+ 0x0eb2, 0x0eb3,
+ 0x0ebd, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f17,
+ 0x0f1a, 0x0f34,
+ 0x0f36, 0x0f36,
+ 0x0f38, 0x0f38,
+ 0x0f3a, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f7f, 0x0f7f,
+ 0x0f85, 0x0f85,
+ 0x0f88, 0x0f8c,
+ 0x0fbe, 0x0fc5,
+ 0x0fc7, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x102c,
+ 0x1031, 0x1031,
+ 0x1038, 0x1038,
+ 0x103b, 0x103c,
+ 0x103f, 0x1057,
+ 0x105a, 0x105d,
+ 0x1061, 0x1070,
+ 0x1075, 0x1081,
+ 0x1083, 0x1084,
+ 0x1087, 0x108c,
+ 0x108e, 0x109c,
+ 0x109e, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1360, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1711,
+ 0x1720, 0x1731,
+ 0x1735, 0x1736,
+ 0x1740, 0x1751,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1780, 0x17b3,
+ 0x17b6, 0x17b6,
+ 0x17be, 0x17c5,
+ 0x17c7, 0x17c8,
+ 0x17d4, 0x17dc,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180a,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x1884,
+ 0x1887, 0x18a8,
+ 0x18aa, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1923, 0x1926,
+ 0x1929, 0x192b,
+ 0x1930, 0x1931,
+ 0x1933, 0x1938,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a16,
+ 0x1a19, 0x1a1a,
+ 0x1a1e, 0x1a55,
+ 0x1a57, 0x1a57,
+ 0x1a61, 0x1a61,
+ 0x1a63, 0x1a64,
+ 0x1a6d, 0x1a72,
+ 0x1a80, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1b04, 0x1b33,
+ 0x1b3b, 0x1b3b,
+ 0x1b3d, 0x1b41,
+ 0x1b43, 0x1b4b,
+ 0x1b50, 0x1b6a,
+ 0x1b74, 0x1b7c,
+ 0x1b82, 0x1ba1,
+ 0x1ba6, 0x1ba7,
+ 0x1baa, 0x1baa,
+ 0x1bae, 0x1be5,
+ 0x1be7, 0x1be7,
+ 0x1bea, 0x1bec,
+ 0x1bee, 0x1bee,
+ 0x1bf2, 0x1bf3,
+ 0x1bfc, 0x1c2b,
+ 0x1c34, 0x1c35,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd3, 0x1cd3,
+ 0x1ce1, 0x1ce1,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf7,
+ 0x1cfa, 0x1cfa,
+ 0x1d00, 0x1dbf,
+ 0x1e00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x200a,
+ 0x2010, 0x2027,
+ 0x202f, 0x205f,
+ 0x2070, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cee,
+ 0x2cf2, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2e00, 0x2e4f,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x3029,
+ 0x3030, 0x303f,
+ 0x3041, 0x3096,
+ 0x309b, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x4db5,
+ 0x4dc0, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa66e,
+ 0xa673, 0xa673,
+ 0xa67e, 0xa69d,
+ 0xa6a0, 0xa6ef,
+ 0xa6f2, 0xa6f7,
+ 0xa700, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa801,
+ 0xa803, 0xa805,
+ 0xa807, 0xa80a,
+ 0xa80c, 0xa824,
+ 0xa827, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c3,
+ 0xa8ce, 0xa8d9,
+ 0xa8f2, 0xa8fe,
+ 0xa900, 0xa925,
+ 0xa92e, 0xa946,
+ 0xa952, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa983, 0xa9b2,
+ 0xa9b4, 0xa9b5,
+ 0xa9ba, 0xa9bb,
+ 0xa9be, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9e4,
+ 0xa9e6, 0xa9fe,
+ 0xaa00, 0xaa28,
+ 0xaa2f, 0xaa30,
+ 0xaa33, 0xaa34,
+ 0xaa40, 0xaa42,
+ 0xaa44, 0xaa4b,
+ 0xaa4d, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa7b,
+ 0xaa7d, 0xaaaf,
+ 0xaab1, 0xaab1,
+ 0xaab5, 0xaab6,
+ 0xaab9, 0xaabd,
+ 0xaac0, 0xaac0,
+ 0xaac2, 0xaac2,
+ 0xaadb, 0xaaeb,
+ 0xaaee, 0xaaf5,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab67,
+ 0xab70, 0xabe4,
+ 0xabe6, 0xabe7,
+ 0xabe9, 0xabec,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb1d,
+ 0xfb1f, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfd,
+ 0xfe10, 0xfe19,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff01, 0xff9d,
+ 0xffa0, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfffc, 0xfffd,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fc,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e1, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x10375,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a00,
+ 0x10a10, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a40, 0x10a48,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae4,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10d23,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f00, 0x10f27,
+ 0x10f30, 0x10f45,
+ 0x10f51, 0x10f59,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x11000,
+ 0x11002, 0x11037,
+ 0x11047, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x11082, 0x110b2,
+ 0x110b7, 0x110b8,
+ 0x110bb, 0x110bc,
+ 0x110be, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11103, 0x11126,
+ 0x1112c, 0x1112c,
+ 0x11136, 0x11146,
+ 0x11150, 0x11172,
+ 0x11174, 0x11176,
+ 0x11182, 0x111b5,
+ 0x111bf, 0x111c8,
+ 0x111cd, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1122e,
+ 0x11232, 0x11233,
+ 0x11235, 0x11235,
+ 0x11238, 0x1123d,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112de,
+ 0x112e0, 0x112e2,
+ 0x112f0, 0x112f9,
+ 0x11302, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133d, 0x1133d,
+ 0x1133f, 0x1133f,
+ 0x11341, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x1135d, 0x11363,
+ 0x11400, 0x11437,
+ 0x11440, 0x11441,
+ 0x11445, 0x11445,
+ 0x11447, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145d,
+ 0x1145f, 0x1145f,
+ 0x11480, 0x114af,
+ 0x114b1, 0x114b2,
+ 0x114b9, 0x114b9,
+ 0x114bb, 0x114bc,
+ 0x114be, 0x114be,
+ 0x114c1, 0x114c1,
+ 0x114c4, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115ae,
+ 0x115b0, 0x115b1,
+ 0x115b8, 0x115bb,
+ 0x115be, 0x115be,
+ 0x115c1, 0x115db,
+ 0x11600, 0x11632,
+ 0x1163b, 0x1163c,
+ 0x1163e, 0x1163e,
+ 0x11641, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116aa,
+ 0x116ac, 0x116ac,
+ 0x116ae, 0x116af,
+ 0x116b6, 0x116b6,
+ 0x116b8, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x11720, 0x11721,
+ 0x11726, 0x11726,
+ 0x11730, 0x1173f,
+ 0x11800, 0x1182e,
+ 0x11838, 0x11838,
+ 0x1183b, 0x1183b,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d3,
+ 0x119dc, 0x119df,
+ 0x119e1, 0x119e4,
+ 0x11a00, 0x11a00,
+ 0x11a0b, 0x11a32,
+ 0x11a39, 0x11a3a,
+ 0x11a3f, 0x11a46,
+ 0x11a50, 0x11a50,
+ 0x11a57, 0x11a58,
+ 0x11a5c, 0x11a89,
+ 0x11a97, 0x11a97,
+ 0x11a9a, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c2f,
+ 0x11c3e, 0x11c3e,
+ 0x11c40, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11ca9, 0x11ca9,
+ 0x11cb1, 0x11cb1,
+ 0x11cb4, 0x11cb4,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d30,
+ 0x11d46, 0x11d46,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d93, 0x11d94,
+ 0x11d96, 0x11d96,
+ 0x11d98, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef2,
+ 0x11ef5, 0x11ef8,
+ 0x11fc0, 0x11ff1,
+ 0x11fff, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af5, 0x16af5,
+ 0x16b00, 0x16b2f,
+ 0x16b37, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e9a,
+ 0x16f00, 0x16f4a,
+ 0x16f50, 0x16f87,
+ 0x16f93, 0x16f9f,
+ 0x16fe0, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bc9c,
+ 0x1bc9f, 0x1bc9f,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d164,
+ 0x1d166, 0x1d166,
+ 0x1d16a, 0x1d16d,
+ 0x1d183, 0x1d184,
+ 0x1d18c, 0x1d1a9,
+ 0x1d1ae, 0x1d1e8,
+ 0x1d200, 0x1d241,
+ 0x1d245, 0x1d245,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d9ff,
+ 0x1da37, 0x1da3a,
+ 0x1da6d, 0x1da74,
+ 0x1da76, 0x1da83,
+ 0x1da85, 0x1da8b,
+ 0x1e100, 0x1e12c,
+ 0x1e137, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14f,
+ 0x1e2c0, 0x1e2eb,
+ 0x1e2f0, 0x1e2f9,
+ 0x1e2ff, 0x1e2ff,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8cf,
+ 0x1e900, 0x1e943,
+ 0x1e94b, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ec71, 0x1ecb4,
+ 0x1ed01, 0x1ed3d,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_Grapheme_Base */
+
+/* 'Grapheme_Link': Derived Property */
+static const OnigCodePoint CR_Grapheme_Link[] = {
+ 52,
+ 0x094d, 0x094d,
+ 0x09cd, 0x09cd,
+ 0x0a4d, 0x0a4d,
+ 0x0acd, 0x0acd,
+ 0x0b4d, 0x0b4d,
+ 0x0bcd, 0x0bcd,
+ 0x0c4d, 0x0c4d,
+ 0x0ccd, 0x0ccd,
+ 0x0d3b, 0x0d3c,
+ 0x0d4d, 0x0d4d,
+ 0x0dca, 0x0dca,
+ 0x0e3a, 0x0e3a,
+ 0x0eba, 0x0eba,
+ 0x0f84, 0x0f84,
+ 0x1039, 0x103a,
+ 0x1714, 0x1714,
+ 0x1734, 0x1734,
+ 0x17d2, 0x17d2,
+ 0x1a60, 0x1a60,
+ 0x1b44, 0x1b44,
+ 0x1baa, 0x1bab,
+ 0x1bf2, 0x1bf3,
+ 0x2d7f, 0x2d7f,
+ 0xa806, 0xa806,
+ 0xa8c4, 0xa8c4,
+ 0xa953, 0xa953,
+ 0xa9c0, 0xa9c0,
+ 0xaaf6, 0xaaf6,
+ 0xabed, 0xabed,
+ 0x10a3f, 0x10a3f,
+ 0x11046, 0x11046,
+ 0x1107f, 0x1107f,
+ 0x110b9, 0x110b9,
+ 0x11133, 0x11134,
+ 0x111c0, 0x111c0,
+ 0x11235, 0x11235,
+ 0x112ea, 0x112ea,
+ 0x1134d, 0x1134d,
+ 0x11442, 0x11442,
+ 0x114c2, 0x114c2,
+ 0x115bf, 0x115bf,
+ 0x1163f, 0x1163f,
+ 0x116b6, 0x116b6,
+ 0x1172b, 0x1172b,
+ 0x11839, 0x11839,
+ 0x119e0, 0x119e0,
+ 0x11a34, 0x11a34,
+ 0x11a47, 0x11a47,
+ 0x11a99, 0x11a99,
+ 0x11c3f, 0x11c3f,
+ 0x11d44, 0x11d45,
+ 0x11d97, 0x11d97,
+}; /* CR_Grapheme_Link */
+
+/* 'Common': Script */
+static const OnigCodePoint CR_Common[] = {
+ 172,
+ 0x0000, 0x0040,
+ 0x005b, 0x0060,
+ 0x007b, 0x00a9,
+ 0x00ab, 0x00b9,
+ 0x00bb, 0x00bf,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x02b9, 0x02df,
+ 0x02e5, 0x02e9,
+ 0x02ec, 0x02ff,
+ 0x0374, 0x0374,
+ 0x037e, 0x037e,
+ 0x0385, 0x0385,
+ 0x0387, 0x0387,
+ 0x0589, 0x0589,
+ 0x0605, 0x0605,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0640, 0x0640,
+ 0x06dd, 0x06dd,
+ 0x08e2, 0x08e2,
+ 0x0964, 0x0965,
+ 0x0e3f, 0x0e3f,
+ 0x0fd5, 0x0fd8,
+ 0x10fb, 0x10fb,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x1802, 0x1803,
+ 0x1805, 0x1805,
+ 0x1cd3, 0x1cd3,
+ 0x1ce1, 0x1ce1,
+ 0x1ce9, 0x1cec,
+ 0x1cee, 0x1cf3,
+ 0x1cf5, 0x1cf7,
+ 0x1cfa, 0x1cfa,
+ 0x2000, 0x200b,
+ 0x200e, 0x2064,
+ 0x2066, 0x2070,
+ 0x2074, 0x207e,
+ 0x2080, 0x208e,
+ 0x20a0, 0x20bf,
+ 0x2100, 0x2125,
+ 0x2127, 0x2129,
+ 0x212c, 0x2131,
+ 0x2133, 0x214d,
+ 0x214f, 0x215f,
+ 0x2189, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x27ff,
+ 0x2900, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bff,
+ 0x2e00, 0x2e4f,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x3004,
+ 0x3006, 0x3006,
+ 0x3008, 0x3020,
+ 0x3030, 0x3037,
+ 0x303c, 0x303f,
+ 0x309b, 0x309c,
+ 0x30a0, 0x30a0,
+ 0x30fb, 0x30fc,
+ 0x3190, 0x319f,
+ 0x31c0, 0x31e3,
+ 0x3220, 0x325f,
+ 0x327f, 0x32cf,
+ 0x32ff, 0x32ff,
+ 0x3358, 0x33ff,
+ 0x4dc0, 0x4dff,
+ 0xa700, 0xa721,
+ 0xa788, 0xa78a,
+ 0xa830, 0xa839,
+ 0xa92e, 0xa92e,
+ 0xa9cf, 0xa9cf,
+ 0xab5b, 0xab5b,
+ 0xfd3e, 0xfd3f,
+ 0xfe10, 0xfe19,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xff20,
+ 0xff3b, 0xff40,
+ 0xff5b, 0xff65,
+ 0xff70, 0xff70,
+ 0xff9e, 0xff9f,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xfffd,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1013f,
+ 0x10190, 0x1019b,
+ 0x101d0, 0x101fc,
+ 0x102e1, 0x102fb,
+ 0x16fe2, 0x16fe3,
+ 0x1bca0, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d166,
+ 0x1d16a, 0x1d17a,
+ 0x1d183, 0x1d184,
+ 0x1d18c, 0x1d1a9,
+ 0x1d1ae, 0x1d1e8,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1ec71, 0x1ecb4,
+ 0x1ed01, 0x1ed3d,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f1ff,
+ 0x1f201, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+}; /* CR_Common */
+
+/* 'Latin': Script */
+static const OnigCodePoint CR_Latin[] = {
+ 32,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x02b8,
+ 0x02e0, 0x02e4,
+ 0x1d00, 0x1d25,
+ 0x1d2c, 0x1d5c,
+ 0x1d62, 0x1d65,
+ 0x1d6b, 0x1d77,
+ 0x1d79, 0x1dbe,
+ 0x1e00, 0x1eff,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x212a, 0x212b,
+ 0x2132, 0x2132,
+ 0x214e, 0x214e,
+ 0x2160, 0x2188,
+ 0x2c60, 0x2c7f,
+ 0xa722, 0xa787,
+ 0xa78b, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa7ff,
+ 0xab30, 0xab5a,
+ 0xab5c, 0xab64,
+ 0xab66, 0xab67,
+ 0xfb00, 0xfb06,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+}; /* CR_Latin */
+
+/* 'Greek': Script */
+static const OnigCodePoint CR_Greek[] = {
+ 36,
+ 0x0370, 0x0373,
+ 0x0375, 0x0377,
+ 0x037a, 0x037d,
+ 0x037f, 0x037f,
+ 0x0384, 0x0384,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03e1,
+ 0x03f0, 0x03ff,
+ 0x1d26, 0x1d2a,
+ 0x1d5d, 0x1d61,
+ 0x1d66, 0x1d6a,
+ 0x1dbf, 0x1dbf,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2126, 0x2126,
+ 0xab65, 0xab65,
+ 0x10140, 0x1018e,
+ 0x101a0, 0x101a0,
+ 0x1d200, 0x1d245,
+}; /* CR_Greek */
+
+/* 'Cyrillic': Script */
+static const OnigCodePoint CR_Cyrillic[] = {
+ 8,
+ 0x0400, 0x0484,
+ 0x0487, 0x052f,
+ 0x1c80, 0x1c88,
+ 0x1d2b, 0x1d2b,
+ 0x1d78, 0x1d78,
+ 0x2de0, 0x2dff,
+ 0xa640, 0xa69f,
+ 0xfe2e, 0xfe2f,
+}; /* CR_Cyrillic */
+
+/* 'Armenian': Script */
+static const OnigCodePoint CR_Armenian[] = {
+ 5,
+ 0x0531, 0x0556,
+ 0x0559, 0x0588,
+ 0x058a, 0x058a,
+ 0x058d, 0x058f,
+ 0xfb13, 0xfb17,
+}; /* CR_Armenian */
+
+/* 'Hebrew': Script */
+static const OnigCodePoint CR_Hebrew[] = {
+ 9,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfb4f,
+}; /* CR_Hebrew */
+
+/* 'Arabic': Script */
+static const OnigCodePoint CR_Arabic[] = {
+ 57,
+ 0x0600, 0x0604,
+ 0x0606, 0x060b,
+ 0x060d, 0x061a,
+ 0x061c, 0x061c,
+ 0x061e, 0x061e,
+ 0x0620, 0x063f,
+ 0x0641, 0x064a,
+ 0x0656, 0x066f,
+ 0x0671, 0x06dc,
+ 0x06de, 0x06ff,
+ 0x0750, 0x077f,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x08ff,
+ 0xfb50, 0xfbc1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfd,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0x10e60, 0x10e7e,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+}; /* CR_Arabic */
+
+/* 'Syriac': Script */
+static const OnigCodePoint CR_Syriac[] = {
+ 4,
+ 0x0700, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x074f,
+ 0x0860, 0x086a,
+}; /* CR_Syriac */
+
+/* 'Thaana': Script */
+static const OnigCodePoint CR_Thaana[] = {
+ 1,
+ 0x0780, 0x07b1,
+}; /* CR_Thaana */
+
+/* 'Devanagari': Script */
+static const OnigCodePoint CR_Devanagari[] = {
+ 4,
+ 0x0900, 0x0950,
+ 0x0955, 0x0963,
+ 0x0966, 0x097f,
+ 0xa8e0, 0xa8ff,
+}; /* CR_Devanagari */
+
+/* 'Bengali': Script */
+static const OnigCodePoint CR_Bengali[] = {
+ 14,
+ 0x0980, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fe,
+}; /* CR_Bengali */
+
+/* 'Gurmukhi': Script */
+static const OnigCodePoint CR_Gurmukhi[] = {
+ 16,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a76,
+}; /* CR_Gurmukhi */
+
+/* 'Gujarati': Script */
+static const OnigCodePoint CR_Gujarati[] = {
+ 14,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+}; /* CR_Gujarati */
+
+/* 'Oriya': Script */
+static const OnigCodePoint CR_Oriya[] = {
+ 14,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+}; /* CR_Oriya */
+
+/* 'Tamil': Script */
+static const OnigCodePoint CR_Tamil[] = {
+ 18,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x11fc0, 0x11ff1,
+ 0x11fff, 0x11fff,
+}; /* CR_Tamil */
+
+/* 'Telugu': Script */
+static const OnigCodePoint CR_Telugu[] = {
+ 12,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0c7f,
+}; /* CR_Telugu */
+
+/* 'Kannada': Script */
+static const OnigCodePoint CR_Kannada[] = {
+ 13,
+ 0x0c80, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+}; /* CR_Kannada */
+
+/* 'Malayalam': Script */
+static const OnigCodePoint CR_Malayalam[] = {
+ 8,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+}; /* CR_Malayalam */
+
+/* 'Sinhala': Script */
+static const OnigCodePoint CR_Sinhala[] = {
+ 13,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x111e1, 0x111f4,
+}; /* CR_Sinhala */
+
+/* 'Thai': Script */
+static const OnigCodePoint CR_Thai[] = {
+ 2,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e5b,
+}; /* CR_Thai */
+
+/* 'Lao': Script */
+static const OnigCodePoint CR_Lao[] = {
+ 11,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+}; /* CR_Lao */
+
+/* 'Tibetan': Script */
+static const OnigCodePoint CR_Tibetan[] = {
+ 7,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fd4,
+ 0x0fd9, 0x0fda,
+}; /* CR_Tibetan */
+
+/* 'Myanmar': Script */
+static const OnigCodePoint CR_Myanmar[] = {
+ 3,
+ 0x1000, 0x109f,
+ 0xa9e0, 0xa9fe,
+ 0xaa60, 0xaa7f,
+}; /* CR_Myanmar */
+
+/* 'Georgian': Script */
+static const OnigCodePoint CR_Georgian[] = {
+ 10,
+ 0x10a0, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x10ff,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cbf,
+ 0x2d00, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+}; /* CR_Georgian */
+
+/* 'Hangul': Script */
+static const OnigCodePoint CR_Hangul[] = {
+ 14,
+ 0x1100, 0x11ff,
+ 0x302e, 0x302f,
+ 0x3131, 0x318e,
+ 0x3200, 0x321e,
+ 0x3260, 0x327e,
+ 0xa960, 0xa97c,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xffa0, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+}; /* CR_Hangul */
+
+/* 'Ethiopic': Script */
+static const OnigCodePoint CR_Ethiopic[] = {
+ 32,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+}; /* CR_Ethiopic */
+
+/* 'Cherokee': Script */
+static const OnigCodePoint CR_Cherokee[] = {
+ 3,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0xab70, 0xabbf,
+}; /* CR_Cherokee */
+
+/* 'Canadian_Aboriginal': Script */
+static const OnigCodePoint CR_Canadian_Aboriginal[] = {
+ 2,
+ 0x1400, 0x167f,
+ 0x18b0, 0x18f5,
+}; /* CR_Canadian_Aboriginal */
+
+/* 'Ogham': Script */
+static const OnigCodePoint CR_Ogham[] = {
+ 1,
+ 0x1680, 0x169c,
+}; /* CR_Ogham */
+
+/* 'Runic': Script */
+static const OnigCodePoint CR_Runic[] = {
+ 2,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f8,
+}; /* CR_Runic */
+
+/* 'Khmer': Script */
+static const OnigCodePoint CR_Khmer[] = {
+ 4,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x19e0, 0x19ff,
+}; /* CR_Khmer */
+
+/* 'Mongolian': Script */
+static const OnigCodePoint CR_Mongolian[] = {
+ 7,
+ 0x1800, 0x1801,
+ 0x1804, 0x1804,
+ 0x1806, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x11660, 0x1166c,
+}; /* CR_Mongolian */
+
+/* 'Hiragana': Script */
+static const OnigCodePoint CR_Hiragana[] = {
+ 5,
+ 0x3041, 0x3096,
+ 0x309d, 0x309f,
+ 0x1b001, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1f200, 0x1f200,
+}; /* CR_Hiragana */
+
+/* 'Katakana': Script */
+static const OnigCodePoint CR_Katakana[] = {
+ 9,
+ 0x30a1, 0x30fa,
+ 0x30fd, 0x30ff,
+ 0x31f0, 0x31ff,
+ 0x32d0, 0x32fe,
+ 0x3300, 0x3357,
+ 0xff66, 0xff6f,
+ 0xff71, 0xff9d,
+ 0x1b000, 0x1b000,
+ 0x1b164, 0x1b167,
+}; /* CR_Katakana */
+
+/* 'Bopomofo': Script */
+static const OnigCodePoint CR_Bopomofo[] = {
+ 3,
+ 0x02ea, 0x02eb,
+ 0x3105, 0x312f,
+ 0x31a0, 0x31ba,
+}; /* CR_Bopomofo */
+
+/* 'Han': Script */
+static const OnigCodePoint CR_Han[] = {
+ 17,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x3005, 0x3005,
+ 0x3007, 0x3007,
+ 0x3021, 0x3029,
+ 0x3038, 0x303b,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_Han */
+
+/* 'Yi': Script */
+static const OnigCodePoint CR_Yi[] = {
+ 2,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+}; /* CR_Yi */
+
+/* 'Old_Italic': Script */
+static const OnigCodePoint CR_Old_Italic[] = {
+ 2,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1032f,
+}; /* CR_Old_Italic */
+
+/* 'Gothic': Script */
+static const OnigCodePoint CR_Gothic[] = {
+ 1,
+ 0x10330, 0x1034a,
+}; /* CR_Gothic */
+
+/* 'Deseret': Script */
+static const OnigCodePoint CR_Deseret[] = {
+ 1,
+ 0x10400, 0x1044f,
+}; /* CR_Deseret */
+
+/* 'Inherited': Script */
+static const OnigCodePoint CR_Inherited[] = {
+ 28,
+ 0x0300, 0x036f,
+ 0x0485, 0x0486,
+ 0x064b, 0x0655,
+ 0x0670, 0x0670,
+ 0x0951, 0x0954,
+ 0x1ab0, 0x1abe,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1ce0,
+ 0x1ce2, 0x1ce8,
+ 0x1ced, 0x1ced,
+ 0x1cf4, 0x1cf4,
+ 0x1cf8, 0x1cf9,
+ 0x1dc0, 0x1df9,
+ 0x1dfb, 0x1dff,
+ 0x200c, 0x200d,
+ 0x20d0, 0x20f0,
+ 0x302a, 0x302d,
+ 0x3099, 0x309a,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2d,
+ 0x101fd, 0x101fd,
+ 0x102e0, 0x102e0,
+ 0x1133b, 0x1133b,
+ 0x1d167, 0x1d169,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0xe0100, 0xe01ef,
+}; /* CR_Inherited */
+
+/* 'Tagalog': Script */
+static const OnigCodePoint CR_Tagalog[] = {
+ 2,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+}; /* CR_Tagalog */
+
+/* 'Hanunoo': Script */
+static const OnigCodePoint CR_Hanunoo[] = {
+ 1,
+ 0x1720, 0x1734,
+}; /* CR_Hanunoo */
+
+/* 'Buhid': Script */
+static const OnigCodePoint CR_Buhid[] = {
+ 1,
+ 0x1740, 0x1753,
+}; /* CR_Buhid */
+
+/* 'Tagbanwa': Script */
+static const OnigCodePoint CR_Tagbanwa[] = {
+ 3,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+}; /* CR_Tagbanwa */
+
+/* 'Limbu': Script */
+static const OnigCodePoint CR_Limbu[] = {
+ 5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x194f,
+}; /* CR_Limbu */
+
+/* 'Tai_Le': Script */
+static const OnigCodePoint CR_Tai_Le[] = {
+ 2,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+}; /* CR_Tai_Le */
+
+/* 'Linear_B': Script */
+static const OnigCodePoint CR_Linear_B[] = {
+ 7,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+}; /* CR_Linear_B */
+
+/* 'Ugaritic': Script */
+static const OnigCodePoint CR_Ugaritic[] = {
+ 2,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x1039f,
+}; /* CR_Ugaritic */
+
+/* 'Shavian': Script */
+static const OnigCodePoint CR_Shavian[] = {
+ 1,
+ 0x10450, 0x1047f,
+}; /* CR_Shavian */
+
+/* 'Osmanya': Script */
+static const OnigCodePoint CR_Osmanya[] = {
+ 2,
+ 0x10480, 0x1049d,
+ 0x104a0, 0x104a9,
+}; /* CR_Osmanya */
+
+/* 'Cypriot': Script */
+static const OnigCodePoint CR_Cypriot[] = {
+ 6,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+}; /* CR_Cypriot */
+
+/* 'Braille': Script */
+static const OnigCodePoint CR_Braille[] = {
+ 1,
+ 0x2800, 0x28ff,
+}; /* CR_Braille */
+
+/* 'Buginese': Script */
+static const OnigCodePoint CR_Buginese[] = {
+ 2,
+ 0x1a00, 0x1a1b,
+ 0x1a1e, 0x1a1f,
+}; /* CR_Buginese */
+
+/* 'Coptic': Script */
+static const OnigCodePoint CR_Coptic[] = {
+ 3,
+ 0x03e2, 0x03ef,
+ 0x2c80, 0x2cf3,
+ 0x2cf9, 0x2cff,
+}; /* CR_Coptic */
+
+/* 'New_Tai_Lue': Script */
+static const OnigCodePoint CR_New_Tai_Lue[] = {
+ 4,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x19df,
+}; /* CR_New_Tai_Lue */
+
+/* 'Glagolitic': Script */
+static const OnigCodePoint CR_Glagolitic[] = {
+ 7,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+}; /* CR_Glagolitic */
+
+/* 'Tifinagh': Script */
+static const OnigCodePoint CR_Tifinagh[] = {
+ 3,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d7f,
+}; /* CR_Tifinagh */
+
+/* 'Syloti_Nagri': Script */
+static const OnigCodePoint CR_Syloti_Nagri[] = {
+ 1,
+ 0xa800, 0xa82b,
+}; /* CR_Syloti_Nagri */
+
+/* 'Old_Persian': Script */
+static const OnigCodePoint CR_Old_Persian[] = {
+ 2,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103d5,
+}; /* CR_Old_Persian */
+
+/* 'Kharoshthi': Script */
+static const OnigCodePoint CR_Kharoshthi[] = {
+ 8,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a48,
+ 0x10a50, 0x10a58,
+}; /* CR_Kharoshthi */
+
+/* 'Balinese': Script */
+static const OnigCodePoint CR_Balinese[] = {
+ 2,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+}; /* CR_Balinese */
+
+/* 'Cuneiform': Script */
+static const OnigCodePoint CR_Cuneiform[] = {
+ 4,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+}; /* CR_Cuneiform */
+
+/* 'Phoenician': Script */
+static const OnigCodePoint CR_Phoenician[] = {
+ 2,
+ 0x10900, 0x1091b,
+ 0x1091f, 0x1091f,
+}; /* CR_Phoenician */
+
+/* 'Phags_Pa': Script */
+static const OnigCodePoint CR_Phags_Pa[] = {
+ 1,
+ 0xa840, 0xa877,
+}; /* CR_Phags_Pa */
+
+/* 'Nko': Script */
+static const OnigCodePoint CR_Nko[] = {
+ 2,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x07ff,
+}; /* CR_Nko */
+
+/* 'Sundanese': Script */
+static const OnigCodePoint CR_Sundanese[] = {
+ 2,
+ 0x1b80, 0x1bbf,
+ 0x1cc0, 0x1cc7,
+}; /* CR_Sundanese */
+
+/* 'Lepcha': Script */
+static const OnigCodePoint CR_Lepcha[] = {
+ 3,
+ 0x1c00, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c4f,
+}; /* CR_Lepcha */
+
+/* 'Ol_Chiki': Script */
+static const OnigCodePoint CR_Ol_Chiki[] = {
+ 1,
+ 0x1c50, 0x1c7f,
+}; /* CR_Ol_Chiki */
+
+/* 'Vai': Script */
+static const OnigCodePoint CR_Vai[] = {
+ 1,
+ 0xa500, 0xa62b,
+}; /* CR_Vai */
+
+/* 'Saurashtra': Script */
+static const OnigCodePoint CR_Saurashtra[] = {
+ 2,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+}; /* CR_Saurashtra */
+
+/* 'Kayah_Li': Script */
+static const OnigCodePoint CR_Kayah_Li[] = {
+ 2,
+ 0xa900, 0xa92d,
+ 0xa92f, 0xa92f,
+}; /* CR_Kayah_Li */
+
+/* 'Rejang': Script */
+static const OnigCodePoint CR_Rejang[] = {
+ 2,
+ 0xa930, 0xa953,
+ 0xa95f, 0xa95f,
+}; /* CR_Rejang */
+
+/* 'Lycian': Script */
+static const OnigCodePoint CR_Lycian[] = {
+ 1,
+ 0x10280, 0x1029c,
+}; /* CR_Lycian */
+
+/* 'Carian': Script */
+static const OnigCodePoint CR_Carian[] = {
+ 1,
+ 0x102a0, 0x102d0,
+}; /* CR_Carian */
+
+/* 'Lydian': Script */
+static const OnigCodePoint CR_Lydian[] = {
+ 2,
+ 0x10920, 0x10939,
+ 0x1093f, 0x1093f,
+}; /* CR_Lydian */
+
+/* 'Cham': Script */
+static const OnigCodePoint CR_Cham[] = {
+ 4,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa5f,
+}; /* CR_Cham */
+
+/* 'Tai_Tham': Script */
+static const OnigCodePoint CR_Tai_Tham[] = {
+ 5,
+ 0x1a20, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+}; /* CR_Tai_Tham */
+
+/* 'Tai_Viet': Script */
+static const OnigCodePoint CR_Tai_Viet[] = {
+ 2,
+ 0xaa80, 0xaac2,
+ 0xaadb, 0xaadf,
+}; /* CR_Tai_Viet */
+
+/* 'Avestan': Script */
+static const OnigCodePoint CR_Avestan[] = {
+ 2,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b3f,
+}; /* CR_Avestan */
+
+/* 'Egyptian_Hieroglyphs': Script */
+static const OnigCodePoint CR_Egyptian_Hieroglyphs[] = {
+ 2,
+ 0x13000, 0x1342e,
+ 0x13430, 0x13438,
+}; /* CR_Egyptian_Hieroglyphs */
+
+/* 'Samaritan': Script */
+static const OnigCodePoint CR_Samaritan[] = {
+ 2,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+}; /* CR_Samaritan */
+
+/* 'Lisu': Script */
+static const OnigCodePoint CR_Lisu[] = {
+ 1,
+ 0xa4d0, 0xa4ff,
+}; /* CR_Lisu */
+
+/* 'Bamum': Script */
+static const OnigCodePoint CR_Bamum[] = {
+ 2,
+ 0xa6a0, 0xa6f7,
+ 0x16800, 0x16a38,
+}; /* CR_Bamum */
+
+/* 'Javanese': Script */
+static const OnigCodePoint CR_Javanese[] = {
+ 3,
+ 0xa980, 0xa9cd,
+ 0xa9d0, 0xa9d9,
+ 0xa9de, 0xa9df,
+}; /* CR_Javanese */
+
+/* 'Meetei_Mayek': Script */
+static const OnigCodePoint CR_Meetei_Mayek[] = {
+ 3,
+ 0xaae0, 0xaaf6,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+}; /* CR_Meetei_Mayek */
+
+/* 'Imperial_Aramaic': Script */
+static const OnigCodePoint CR_Imperial_Aramaic[] = {
+ 2,
+ 0x10840, 0x10855,
+ 0x10857, 0x1085f,
+}; /* CR_Imperial_Aramaic */
+
+/* 'Old_South_Arabian': Script */
+static const OnigCodePoint CR_Old_South_Arabian[] = {
+ 1,
+ 0x10a60, 0x10a7f,
+}; /* CR_Old_South_Arabian */
+
+/* 'Inscriptional_Parthian': Script */
+static const OnigCodePoint CR_Inscriptional_Parthian[] = {
+ 2,
+ 0x10b40, 0x10b55,
+ 0x10b58, 0x10b5f,
+}; /* CR_Inscriptional_Parthian */
+
+/* 'Inscriptional_Pahlavi': Script */
+static const OnigCodePoint CR_Inscriptional_Pahlavi[] = {
+ 2,
+ 0x10b60, 0x10b72,
+ 0x10b78, 0x10b7f,
+}; /* CR_Inscriptional_Pahlavi */
+
+/* 'Old_Turkic': Script */
+static const OnigCodePoint CR_Old_Turkic[] = {
+ 1,
+ 0x10c00, 0x10c48,
+}; /* CR_Old_Turkic */
+
+/* 'Kaithi': Script */
+static const OnigCodePoint CR_Kaithi[] = {
+ 2,
+ 0x11080, 0x110c1,
+ 0x110cd, 0x110cd,
+}; /* CR_Kaithi */
+
+/* 'Batak': Script */
+static const OnigCodePoint CR_Batak[] = {
+ 2,
+ 0x1bc0, 0x1bf3,
+ 0x1bfc, 0x1bff,
+}; /* CR_Batak */
+
+/* 'Brahmi': Script */
+static const OnigCodePoint CR_Brahmi[] = {
+ 3,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x1107f,
+}; /* CR_Brahmi */
+
+/* 'Mandaic': Script */
+static const OnigCodePoint CR_Mandaic[] = {
+ 2,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+}; /* CR_Mandaic */
+
+/* 'Chakma': Script */
+static const OnigCodePoint CR_Chakma[] = {
+ 2,
+ 0x11100, 0x11134,
+ 0x11136, 0x11146,
+}; /* CR_Chakma */
+
+/* 'Meroitic_Cursive': Script */
+static const OnigCodePoint CR_Meroitic_Cursive[] = {
+ 3,
+ 0x109a0, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x109ff,
+}; /* CR_Meroitic_Cursive */
+
+/* 'Meroitic_Hieroglyphs': Script */
+static const OnigCodePoint CR_Meroitic_Hieroglyphs[] = {
+ 1,
+ 0x10980, 0x1099f,
+}; /* CR_Meroitic_Hieroglyphs */
+
+/* 'Miao': Script */
+static const OnigCodePoint CR_Miao[] = {
+ 3,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+}; /* CR_Miao */
+
+/* 'Sharada': Script */
+static const OnigCodePoint CR_Sharada[] = {
+ 2,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+}; /* CR_Sharada */
+
+/* 'Sora_Sompeng': Script */
+static const OnigCodePoint CR_Sora_Sompeng[] = {
+ 2,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+}; /* CR_Sora_Sompeng */
+
+/* 'Takri': Script */
+static const OnigCodePoint CR_Takri[] = {
+ 2,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+}; /* CR_Takri */
+
+/* 'Caucasian_Albanian': Script */
+static const OnigCodePoint CR_Caucasian_Albanian[] = {
+ 2,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+}; /* CR_Caucasian_Albanian */
+
+/* 'Bassa_Vah': Script */
+static const OnigCodePoint CR_Bassa_Vah[] = {
+ 2,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+}; /* CR_Bassa_Vah */
+
+/* 'Duployan': Script */
+static const OnigCodePoint CR_Duployan[] = {
+ 5,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bc9f,
+}; /* CR_Duployan */
+
+/* 'Elbasan': Script */
+static const OnigCodePoint CR_Elbasan[] = {
+ 1,
+ 0x10500, 0x10527,
+}; /* CR_Elbasan */
+
+/* 'Grantha': Script */
+static const OnigCodePoint CR_Grantha[] = {
+ 15,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133c, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+}; /* CR_Grantha */
+
+/* 'Pahawh_Hmong': Script */
+static const OnigCodePoint CR_Pahawh_Hmong[] = {
+ 5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+}; /* CR_Pahawh_Hmong */
+
+/* 'Khojki': Script */
+static const OnigCodePoint CR_Khojki[] = {
+ 2,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+}; /* CR_Khojki */
+
+/* 'Linear_A': Script */
+static const OnigCodePoint CR_Linear_A[] = {
+ 3,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+}; /* CR_Linear_A */
+
+/* 'Mahajani': Script */
+static const OnigCodePoint CR_Mahajani[] = {
+ 1,
+ 0x11150, 0x11176,
+}; /* CR_Mahajani */
+
+/* 'Manichaean': Script */
+static const OnigCodePoint CR_Manichaean[] = {
+ 2,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+}; /* CR_Manichaean */
+
+/* 'Mende_Kikakui': Script */
+static const OnigCodePoint CR_Mende_Kikakui[] = {
+ 2,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+}; /* CR_Mende_Kikakui */
+
+/* 'Modi': Script */
+static const OnigCodePoint CR_Modi[] = {
+ 2,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+}; /* CR_Modi */
+
+/* 'Mro': Script */
+static const OnigCodePoint CR_Mro[] = {
+ 3,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+}; /* CR_Mro */
+
+/* 'Old_North_Arabian': Script */
+static const OnigCodePoint CR_Old_North_Arabian[] = {
+ 1,
+ 0x10a80, 0x10a9f,
+}; /* CR_Old_North_Arabian */
+
+/* 'Nabataean': Script */
+static const OnigCodePoint CR_Nabataean[] = {
+ 2,
+ 0x10880, 0x1089e,
+ 0x108a7, 0x108af,
+}; /* CR_Nabataean */
+
+/* 'Palmyrene': Script */
+static const OnigCodePoint CR_Palmyrene[] = {
+ 1,
+ 0x10860, 0x1087f,
+}; /* CR_Palmyrene */
+
+/* 'Pau_Cin_Hau': Script */
+static const OnigCodePoint CR_Pau_Cin_Hau[] = {
+ 1,
+ 0x11ac0, 0x11af8,
+}; /* CR_Pau_Cin_Hau */
+
+/* 'Old_Permic': Script */
+static const OnigCodePoint CR_Old_Permic[] = {
+ 1,
+ 0x10350, 0x1037a,
+}; /* CR_Old_Permic */
+
+/* 'Psalter_Pahlavi': Script */
+static const OnigCodePoint CR_Psalter_Pahlavi[] = {
+ 3,
+ 0x10b80, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+}; /* CR_Psalter_Pahlavi */
+
+/* 'Siddham': Script */
+static const OnigCodePoint CR_Siddham[] = {
+ 2,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+}; /* CR_Siddham */
+
+/* 'Khudawadi': Script */
+static const OnigCodePoint CR_Khudawadi[] = {
+ 2,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+}; /* CR_Khudawadi */
+
+/* 'Tirhuta': Script */
+static const OnigCodePoint CR_Tirhuta[] = {
+ 2,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+}; /* CR_Tirhuta */
+
+/* 'Warang_Citi': Script */
+static const OnigCodePoint CR_Warang_Citi[] = {
+ 2,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+}; /* CR_Warang_Citi */
+
+/* 'Ahom': Script */
+static const OnigCodePoint CR_Ahom[] = {
+ 3,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+}; /* CR_Ahom */
+
+/* 'Anatolian_Hieroglyphs': Script */
+static const OnigCodePoint CR_Anatolian_Hieroglyphs[] = {
+ 1,
+ 0x14400, 0x14646,
+}; /* CR_Anatolian_Hieroglyphs */
+
+/* 'Hatran': Script */
+static const OnigCodePoint CR_Hatran[] = {
+ 3,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x108ff,
+}; /* CR_Hatran */
+
+/* 'Multani': Script */
+static const OnigCodePoint CR_Multani[] = {
+ 5,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+}; /* CR_Multani */
+
+/* 'Old_Hungarian': Script */
+static const OnigCodePoint CR_Old_Hungarian[] = {
+ 3,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10cff,
+}; /* CR_Old_Hungarian */
+
+/* 'SignWriting': Script */
+static const OnigCodePoint CR_SignWriting[] = {
+ 3,
+ 0x1d800, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+}; /* CR_SignWriting */
+
+/* 'Adlam': Script */
+static const OnigCodePoint CR_Adlam[] = {
+ 3,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+}; /* CR_Adlam */
+
+/* 'Bhaiksuki': Script */
+static const OnigCodePoint CR_Bhaiksuki[] = {
+ 4,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+}; /* CR_Bhaiksuki */
+
+/* 'Marchen': Script */
+static const OnigCodePoint CR_Marchen[] = {
+ 3,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+}; /* CR_Marchen */
+
+/* 'Newa': Script */
+static const OnigCodePoint CR_Newa[] = {
+ 3,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145f,
+}; /* CR_Newa */
+
+/* 'Osage': Script */
+static const OnigCodePoint CR_Osage[] = {
+ 2,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+}; /* CR_Osage */
+
+/* 'Tangut': Script */
+static const OnigCodePoint CR_Tangut[] = {
+ 3,
+ 0x16fe0, 0x16fe0,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+}; /* CR_Tangut */
+
+/* 'Masaram_Gondi': Script */
+static const OnigCodePoint CR_Masaram_Gondi[] = {
+ 7,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+}; /* CR_Masaram_Gondi */
+
+/* 'Nushu': Script */
+static const OnigCodePoint CR_Nushu[] = {
+ 2,
+ 0x16fe1, 0x16fe1,
+ 0x1b170, 0x1b2fb,
+}; /* CR_Nushu */
+
+/* 'Soyombo': Script */
+static const OnigCodePoint CR_Soyombo[] = {
+ 1,
+ 0x11a50, 0x11aa2,
+}; /* CR_Soyombo */
+
+/* 'Zanabazar_Square': Script */
+static const OnigCodePoint CR_Zanabazar_Square[] = {
+ 1,
+ 0x11a00, 0x11a47,
+}; /* CR_Zanabazar_Square */
+
+/* 'Dogra': Script */
+static const OnigCodePoint CR_Dogra[] = {
+ 1,
+ 0x11800, 0x1183b,
+}; /* CR_Dogra */
+
+/* 'Gunjala_Gondi': Script */
+static const OnigCodePoint CR_Gunjala_Gondi[] = {
+ 6,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+}; /* CR_Gunjala_Gondi */
+
+/* 'Makasar': Script */
+static const OnigCodePoint CR_Makasar[] = {
+ 1,
+ 0x11ee0, 0x11ef8,
+}; /* CR_Makasar */
+
+/* 'Medefaidrin': Script */
+static const OnigCodePoint CR_Medefaidrin[] = {
+ 1,
+ 0x16e40, 0x16e9a,
+}; /* CR_Medefaidrin */
+
+/* 'Hanifi_Rohingya': Script */
+static const OnigCodePoint CR_Hanifi_Rohingya[] = {
+ 2,
+ 0x10d00, 0x10d27,
+ 0x10d30, 0x10d39,
+}; /* CR_Hanifi_Rohingya */
+
+/* 'Sogdian': Script */
+static const OnigCodePoint CR_Sogdian[] = {
+ 1,
+ 0x10f30, 0x10f59,
+}; /* CR_Sogdian */
+
+/* 'Old_Sogdian': Script */
+static const OnigCodePoint CR_Old_Sogdian[] = {
+ 1,
+ 0x10f00, 0x10f27,
+}; /* CR_Old_Sogdian */
+
+/* 'Elymaic': Script */
+static const OnigCodePoint CR_Elymaic[] = {
+ 1,
+ 0x10fe0, 0x10ff6,
+}; /* CR_Elymaic */
+
+/* 'Nandinagari': Script */
+static const OnigCodePoint CR_Nandinagari[] = {
+ 3,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e4,
+}; /* CR_Nandinagari */
+
+/* 'Nyiakeng_Puachue_Hmong': Script */
+static const OnigCodePoint CR_Nyiakeng_Puachue_Hmong[] = {
+ 4,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14f,
+}; /* CR_Nyiakeng_Puachue_Hmong */
+
+/* 'Wancho': Script */
+static const OnigCodePoint CR_Wancho[] = {
+ 2,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e2ff, 0x1e2ff,
+}; /* CR_Wancho */
+
+/* 'White_Space': Binary Property */
+#define CR_White_Space CR_Space
+
+/* 'Bidi_Control': Binary Property */
+static const OnigCodePoint CR_Bidi_Control[] = {
+ 4,
+ 0x061c, 0x061c,
+ 0x200e, 0x200f,
+ 0x202a, 0x202e,
+ 0x2066, 0x2069,
+}; /* CR_Bidi_Control */
+
+/* 'Join_Control': Binary Property */
+static const OnigCodePoint CR_Join_Control[] = {
+ 1,
+ 0x200c, 0x200d,
+}; /* CR_Join_Control */
+
+/* 'Dash': Binary Property */
+static const OnigCodePoint CR_Dash[] = {
+ 21,
+ 0x002d, 0x002d,
+ 0x058a, 0x058a,
+ 0x05be, 0x05be,
+ 0x1400, 0x1400,
+ 0x1806, 0x1806,
+ 0x2010, 0x2015,
+ 0x2053, 0x2053,
+ 0x207b, 0x207b,
+ 0x208b, 0x208b,
+ 0x2212, 0x2212,
+ 0x2e17, 0x2e17,
+ 0x2e1a, 0x2e1a,
+ 0x2e3a, 0x2e3b,
+ 0x2e40, 0x2e40,
+ 0x301c, 0x301c,
+ 0x3030, 0x3030,
+ 0x30a0, 0x30a0,
+ 0xfe31, 0xfe32,
+ 0xfe58, 0xfe58,
+ 0xfe63, 0xfe63,
+ 0xff0d, 0xff0d,
+}; /* CR_Dash */
+
+/* 'Hyphen': Binary Property */
+static const OnigCodePoint CR_Hyphen[] = {
+ 10,
+ 0x002d, 0x002d,
+ 0x00ad, 0x00ad,
+ 0x058a, 0x058a,
+ 0x1806, 0x1806,
+ 0x2010, 0x2011,
+ 0x2e17, 0x2e17,
+ 0x30fb, 0x30fb,
+ 0xfe63, 0xfe63,
+ 0xff0d, 0xff0d,
+ 0xff65, 0xff65,
+}; /* CR_Hyphen */
+
+/* 'Quotation_Mark': Binary Property */
+static const OnigCodePoint CR_Quotation_Mark[] = {
+ 13,
+ 0x0022, 0x0022,
+ 0x0027, 0x0027,
+ 0x00ab, 0x00ab,
+ 0x00bb, 0x00bb,
+ 0x2018, 0x201f,
+ 0x2039, 0x203a,
+ 0x2e42, 0x2e42,
+ 0x300c, 0x300f,
+ 0x301d, 0x301f,
+ 0xfe41, 0xfe44,
+ 0xff02, 0xff02,
+ 0xff07, 0xff07,
+ 0xff62, 0xff63,
+}; /* CR_Quotation_Mark */
+
+/* 'Terminal_Punctuation': Binary Property */
+static const OnigCodePoint CR_Terminal_Punctuation[] = {
+ 102,
+ 0x0021, 0x0021,
+ 0x002c, 0x002c,
+ 0x002e, 0x002e,
+ 0x003a, 0x003b,
+ 0x003f, 0x003f,
+ 0x037e, 0x037e,
+ 0x0387, 0x0387,
+ 0x0589, 0x0589,
+ 0x05c3, 0x05c3,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x06d4, 0x06d4,
+ 0x0700, 0x070a,
+ 0x070c, 0x070c,
+ 0x07f8, 0x07f9,
+ 0x0830, 0x083e,
+ 0x085e, 0x085e,
+ 0x0964, 0x0965,
+ 0x0e5a, 0x0e5b,
+ 0x0f08, 0x0f08,
+ 0x0f0d, 0x0f12,
+ 0x104a, 0x104b,
+ 0x1361, 0x1368,
+ 0x166e, 0x166e,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x17d4, 0x17d6,
+ 0x17da, 0x17da,
+ 0x1802, 0x1805,
+ 0x1808, 0x1809,
+ 0x1944, 0x1945,
+ 0x1aa8, 0x1aab,
+ 0x1b5a, 0x1b5b,
+ 0x1b5d, 0x1b5f,
+ 0x1c3b, 0x1c3f,
+ 0x1c7e, 0x1c7f,
+ 0x203c, 0x203d,
+ 0x2047, 0x2049,
+ 0x2e2e, 0x2e2e,
+ 0x2e3c, 0x2e3c,
+ 0x2e41, 0x2e41,
+ 0x2e4c, 0x2e4c,
+ 0x2e4e, 0x2e4f,
+ 0x3001, 0x3002,
+ 0xa4fe, 0xa4ff,
+ 0xa60d, 0xa60f,
+ 0xa6f3, 0xa6f7,
+ 0xa876, 0xa877,
+ 0xa8ce, 0xa8cf,
+ 0xa92f, 0xa92f,
+ 0xa9c7, 0xa9c9,
+ 0xaa5d, 0xaa5f,
+ 0xaadf, 0xaadf,
+ 0xaaf0, 0xaaf1,
+ 0xabeb, 0xabeb,
+ 0xfe50, 0xfe52,
+ 0xfe54, 0xfe57,
+ 0xff01, 0xff01,
+ 0xff0c, 0xff0c,
+ 0xff0e, 0xff0e,
+ 0xff1a, 0xff1b,
+ 0xff1f, 0xff1f,
+ 0xff61, 0xff61,
+ 0xff64, 0xff64,
+ 0x1039f, 0x1039f,
+ 0x103d0, 0x103d0,
+ 0x10857, 0x10857,
+ 0x1091f, 0x1091f,
+ 0x10a56, 0x10a57,
+ 0x10af0, 0x10af5,
+ 0x10b3a, 0x10b3f,
+ 0x10b99, 0x10b9c,
+ 0x10f55, 0x10f59,
+ 0x11047, 0x1104d,
+ 0x110be, 0x110c1,
+ 0x11141, 0x11143,
+ 0x111c5, 0x111c6,
+ 0x111cd, 0x111cd,
+ 0x111de, 0x111df,
+ 0x11238, 0x1123c,
+ 0x112a9, 0x112a9,
+ 0x1144b, 0x1144d,
+ 0x1145b, 0x1145b,
+ 0x115c2, 0x115c5,
+ 0x115c9, 0x115d7,
+ 0x11641, 0x11642,
+ 0x1173c, 0x1173e,
+ 0x11a42, 0x11a43,
+ 0x11a9b, 0x11a9c,
+ 0x11aa1, 0x11aa2,
+ 0x11c41, 0x11c43,
+ 0x11c71, 0x11c71,
+ 0x11ef7, 0x11ef8,
+ 0x12470, 0x12474,
+ 0x16a6e, 0x16a6f,
+ 0x16af5, 0x16af5,
+ 0x16b37, 0x16b39,
+ 0x16b44, 0x16b44,
+ 0x16e97, 0x16e98,
+ 0x1bc9f, 0x1bc9f,
+ 0x1da87, 0x1da8a,
+}; /* CR_Terminal_Punctuation */
+
+/* 'Other_Math': Binary Property */
+static const OnigCodePoint CR_Other_Math[] = {
+ 134,
+ 0x005e, 0x005e,
+ 0x03d0, 0x03d2,
+ 0x03d5, 0x03d5,
+ 0x03f0, 0x03f1,
+ 0x03f4, 0x03f5,
+ 0x2016, 0x2016,
+ 0x2032, 0x2034,
+ 0x2040, 0x2040,
+ 0x2061, 0x2064,
+ 0x207d, 0x207e,
+ 0x208d, 0x208e,
+ 0x20d0, 0x20dc,
+ 0x20e1, 0x20e1,
+ 0x20e5, 0x20e6,
+ 0x20eb, 0x20ef,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2128, 0x2129,
+ 0x212c, 0x212d,
+ 0x212f, 0x2131,
+ 0x2133, 0x2138,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x2195, 0x2199,
+ 0x219c, 0x219f,
+ 0x21a1, 0x21a2,
+ 0x21a4, 0x21a5,
+ 0x21a7, 0x21a7,
+ 0x21a9, 0x21ad,
+ 0x21b0, 0x21b1,
+ 0x21b6, 0x21b7,
+ 0x21bc, 0x21cd,
+ 0x21d0, 0x21d1,
+ 0x21d3, 0x21d3,
+ 0x21d5, 0x21db,
+ 0x21dd, 0x21dd,
+ 0x21e4, 0x21e5,
+ 0x2308, 0x230b,
+ 0x23b4, 0x23b5,
+ 0x23b7, 0x23b7,
+ 0x23d0, 0x23d0,
+ 0x23e2, 0x23e2,
+ 0x25a0, 0x25a1,
+ 0x25ae, 0x25b6,
+ 0x25bc, 0x25c0,
+ 0x25c6, 0x25c7,
+ 0x25ca, 0x25cb,
+ 0x25cf, 0x25d3,
+ 0x25e2, 0x25e2,
+ 0x25e4, 0x25e4,
+ 0x25e7, 0x25ec,
+ 0x2605, 0x2606,
+ 0x2640, 0x2640,
+ 0x2642, 0x2642,
+ 0x2660, 0x2663,
+ 0x266d, 0x266e,
+ 0x27c5, 0x27c6,
+ 0x27e6, 0x27ef,
+ 0x2983, 0x2998,
+ 0x29d8, 0x29db,
+ 0x29fc, 0x29fd,
+ 0xfe61, 0xfe61,
+ 0xfe63, 0xfe63,
+ 0xfe68, 0xfe68,
+ 0xff3c, 0xff3c,
+ 0xff3e, 0xff3e,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+}; /* CR_Other_Math */
+
+/* 'Hex_Digit': Binary Property */
+static const OnigCodePoint CR_Hex_Digit[] = {
+ 6,
+ 0x0030, 0x0039,
+ 0x0041, 0x0046,
+ 0x0061, 0x0066,
+ 0xff10, 0xff19,
+ 0xff21, 0xff26,
+ 0xff41, 0xff46,
+}; /* CR_Hex_Digit */
+
+/* 'ASCII_Hex_Digit': Binary Property */
+#define CR_ASCII_Hex_Digit CR_XDigit
+
+/* 'Other_Alphabetic': Binary Property */
+static const OnigCodePoint CR_Other_Alphabetic[] = {
+ 221,
+ 0x0345, 0x0345,
+ 0x05b0, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x0610, 0x061a,
+ 0x064b, 0x0657,
+ 0x0659, 0x065f,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dc,
+ 0x06e1, 0x06e4,
+ 0x06e7, 0x06e8,
+ 0x06ed, 0x06ed,
+ 0x0711, 0x0711,
+ 0x0730, 0x073f,
+ 0x07a6, 0x07b0,
+ 0x0816, 0x0817,
+ 0x081b, 0x0823,
+ 0x0825, 0x0827,
+ 0x0829, 0x082c,
+ 0x08d4, 0x08df,
+ 0x08e3, 0x08e9,
+ 0x08f0, 0x0903,
+ 0x093a, 0x093b,
+ 0x093e, 0x094c,
+ 0x094e, 0x094f,
+ 0x0955, 0x0957,
+ 0x0962, 0x0963,
+ 0x0981, 0x0983,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cc,
+ 0x09d7, 0x09d7,
+ 0x09e2, 0x09e3,
+ 0x0a01, 0x0a03,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4c,
+ 0x0a51, 0x0a51,
+ 0x0a70, 0x0a71,
+ 0x0a75, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0abe, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acc,
+ 0x0ae2, 0x0ae3,
+ 0x0afa, 0x0afc,
+ 0x0b01, 0x0b03,
+ 0x0b3e, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4c,
+ 0x0b56, 0x0b57,
+ 0x0b62, 0x0b63,
+ 0x0b82, 0x0b82,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcc,
+ 0x0bd7, 0x0bd7,
+ 0x0c00, 0x0c03,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4c,
+ 0x0c55, 0x0c56,
+ 0x0c62, 0x0c63,
+ 0x0c81, 0x0c83,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccc,
+ 0x0cd5, 0x0cd6,
+ 0x0ce2, 0x0ce3,
+ 0x0d00, 0x0d03,
+ 0x0d3e, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4c,
+ 0x0d57, 0x0d57,
+ 0x0d62, 0x0d63,
+ 0x0d82, 0x0d83,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df3,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e4d, 0x0e4d,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0eb9,
+ 0x0ebb, 0x0ebc,
+ 0x0ecd, 0x0ecd,
+ 0x0f71, 0x0f81,
+ 0x0f8d, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x102b, 0x1036,
+ 0x1038, 0x1038,
+ 0x103b, 0x103e,
+ 0x1056, 0x1059,
+ 0x105e, 0x1060,
+ 0x1062, 0x1064,
+ 0x1067, 0x106d,
+ 0x1071, 0x1074,
+ 0x1082, 0x108d,
+ 0x108f, 0x108f,
+ 0x109a, 0x109d,
+ 0x1712, 0x1713,
+ 0x1732, 0x1733,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b6, 0x17c8,
+ 0x1885, 0x1886,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x192b,
+ 0x1930, 0x1938,
+ 0x1a17, 0x1a1b,
+ 0x1a55, 0x1a5e,
+ 0x1a61, 0x1a74,
+ 0x1b00, 0x1b04,
+ 0x1b35, 0x1b43,
+ 0x1b80, 0x1b82,
+ 0x1ba1, 0x1ba9,
+ 0x1bac, 0x1bad,
+ 0x1be7, 0x1bf1,
+ 0x1c24, 0x1c36,
+ 0x1de7, 0x1df4,
+ 0x24b6, 0x24e9,
+ 0x2de0, 0x2dff,
+ 0xa674, 0xa67b,
+ 0xa69e, 0xa69f,
+ 0xa802, 0xa802,
+ 0xa80b, 0xa80b,
+ 0xa823, 0xa827,
+ 0xa880, 0xa881,
+ 0xa8b4, 0xa8c3,
+ 0xa8c5, 0xa8c5,
+ 0xa8ff, 0xa8ff,
+ 0xa926, 0xa92a,
+ 0xa947, 0xa952,
+ 0xa980, 0xa983,
+ 0xa9b4, 0xa9bf,
+ 0xa9e5, 0xa9e5,
+ 0xaa29, 0xaa36,
+ 0xaa43, 0xaa43,
+ 0xaa4c, 0xaa4d,
+ 0xaa7b, 0xaa7d,
+ 0xaab0, 0xaab0,
+ 0xaab2, 0xaab4,
+ 0xaab7, 0xaab8,
+ 0xaabe, 0xaabe,
+ 0xaaeb, 0xaaef,
+ 0xaaf5, 0xaaf5,
+ 0xabe3, 0xabea,
+ 0xfb1e, 0xfb1e,
+ 0x10376, 0x1037a,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10d24, 0x10d27,
+ 0x11000, 0x11002,
+ 0x11038, 0x11045,
+ 0x11082, 0x11082,
+ 0x110b0, 0x110b8,
+ 0x11100, 0x11102,
+ 0x11127, 0x11132,
+ 0x11145, 0x11146,
+ 0x11180, 0x11182,
+ 0x111b3, 0x111bf,
+ 0x1122c, 0x11234,
+ 0x11237, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x112df, 0x112e8,
+ 0x11300, 0x11303,
+ 0x1133e, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134c,
+ 0x11357, 0x11357,
+ 0x11362, 0x11363,
+ 0x11435, 0x11441,
+ 0x11443, 0x11445,
+ 0x114b0, 0x114c1,
+ 0x115af, 0x115b5,
+ 0x115b8, 0x115be,
+ 0x115dc, 0x115dd,
+ 0x11630, 0x1163e,
+ 0x11640, 0x11640,
+ 0x116ab, 0x116b5,
+ 0x1171d, 0x1172a,
+ 0x1182c, 0x11838,
+ 0x119d1, 0x119d7,
+ 0x119da, 0x119df,
+ 0x119e4, 0x119e4,
+ 0x11a01, 0x11a0a,
+ 0x11a35, 0x11a39,
+ 0x11a3b, 0x11a3e,
+ 0x11a51, 0x11a5b,
+ 0x11a8a, 0x11a97,
+ 0x11c2f, 0x11c36,
+ 0x11c38, 0x11c3e,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d31, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d41,
+ 0x11d43, 0x11d43,
+ 0x11d47, 0x11d47,
+ 0x11d8a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d96,
+ 0x11ef3, 0x11ef6,
+ 0x16f4f, 0x16f4f,
+ 0x16f51, 0x16f87,
+ 0x16f8f, 0x16f92,
+ 0x1bc9e, 0x1bc9e,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e947, 0x1e947,
+ 0x1f130, 0x1f149,
+ 0x1f150, 0x1f169,
+ 0x1f170, 0x1f189,
+}; /* CR_Other_Alphabetic */
+
+/* 'Ideographic': Binary Property */
+static const OnigCodePoint CR_Ideographic[] = {
+ 16,
+ 0x3006, 0x3007,
+ 0x3021, 0x3029,
+ 0x3038, 0x303a,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b170, 0x1b2fb,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+}; /* CR_Ideographic */
+
+/* 'Diacritic': Binary Property */
+static const OnigCodePoint CR_Diacritic[] = {
+ 171,
+ 0x005e, 0x005e,
+ 0x0060, 0x0060,
+ 0x00a8, 0x00a8,
+ 0x00af, 0x00af,
+ 0x00b4, 0x00b4,
+ 0x00b7, 0x00b8,
+ 0x02b0, 0x034e,
+ 0x0350, 0x0357,
+ 0x035d, 0x0362,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x0384, 0x0385,
+ 0x0483, 0x0487,
+ 0x0559, 0x0559,
+ 0x0591, 0x05a1,
+ 0x05a3, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c4,
+ 0x064b, 0x0652,
+ 0x0657, 0x0658,
+ 0x06df, 0x06e0,
+ 0x06e5, 0x06e6,
+ 0x06ea, 0x06ec,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x07eb, 0x07f5,
+ 0x0818, 0x0819,
+ 0x08e3, 0x08fe,
+ 0x093c, 0x093c,
+ 0x094d, 0x094d,
+ 0x0951, 0x0954,
+ 0x0971, 0x0971,
+ 0x09bc, 0x09bc,
+ 0x09cd, 0x09cd,
+ 0x0a3c, 0x0a3c,
+ 0x0a4d, 0x0a4d,
+ 0x0abc, 0x0abc,
+ 0x0acd, 0x0acd,
+ 0x0afd, 0x0aff,
+ 0x0b3c, 0x0b3c,
+ 0x0b4d, 0x0b4d,
+ 0x0bcd, 0x0bcd,
+ 0x0c4d, 0x0c4d,
+ 0x0cbc, 0x0cbc,
+ 0x0ccd, 0x0ccd,
+ 0x0d3b, 0x0d3c,
+ 0x0d4d, 0x0d4d,
+ 0x0dca, 0x0dca,
+ 0x0e47, 0x0e4c,
+ 0x0e4e, 0x0e4e,
+ 0x0eba, 0x0eba,
+ 0x0ec8, 0x0ecc,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f3e, 0x0f3f,
+ 0x0f82, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0fc6, 0x0fc6,
+ 0x1037, 0x1037,
+ 0x1039, 0x103a,
+ 0x1063, 0x1064,
+ 0x1069, 0x106d,
+ 0x1087, 0x108d,
+ 0x108f, 0x108f,
+ 0x109a, 0x109b,
+ 0x135d, 0x135f,
+ 0x17c9, 0x17d3,
+ 0x17dd, 0x17dd,
+ 0x1939, 0x193b,
+ 0x1a75, 0x1a7c,
+ 0x1a7f, 0x1a7f,
+ 0x1ab0, 0x1abd,
+ 0x1b34, 0x1b34,
+ 0x1b44, 0x1b44,
+ 0x1b6b, 0x1b73,
+ 0x1baa, 0x1bab,
+ 0x1c36, 0x1c37,
+ 0x1c78, 0x1c7d,
+ 0x1cd0, 0x1ce8,
+ 0x1ced, 0x1ced,
+ 0x1cf4, 0x1cf4,
+ 0x1cf7, 0x1cf9,
+ 0x1d2c, 0x1d6a,
+ 0x1dc4, 0x1dcf,
+ 0x1df5, 0x1df9,
+ 0x1dfd, 0x1dff,
+ 0x1fbd, 0x1fbd,
+ 0x1fbf, 0x1fc1,
+ 0x1fcd, 0x1fcf,
+ 0x1fdd, 0x1fdf,
+ 0x1fed, 0x1fef,
+ 0x1ffd, 0x1ffe,
+ 0x2cef, 0x2cf1,
+ 0x2e2f, 0x2e2f,
+ 0x302a, 0x302f,
+ 0x3099, 0x309c,
+ 0x30fc, 0x30fc,
+ 0xa66f, 0xa66f,
+ 0xa67c, 0xa67d,
+ 0xa67f, 0xa67f,
+ 0xa69c, 0xa69d,
+ 0xa6f0, 0xa6f1,
+ 0xa700, 0xa721,
+ 0xa788, 0xa78a,
+ 0xa7f8, 0xa7f9,
+ 0xa8c4, 0xa8c4,
+ 0xa8e0, 0xa8f1,
+ 0xa92b, 0xa92e,
+ 0xa953, 0xa953,
+ 0xa9b3, 0xa9b3,
+ 0xa9c0, 0xa9c0,
+ 0xa9e5, 0xa9e5,
+ 0xaa7b, 0xaa7d,
+ 0xaabf, 0xaac2,
+ 0xaaf6, 0xaaf6,
+ 0xab5b, 0xab5f,
+ 0xabec, 0xabed,
+ 0xfb1e, 0xfb1e,
+ 0xfe20, 0xfe2f,
+ 0xff3e, 0xff3e,
+ 0xff40, 0xff40,
+ 0xff70, 0xff70,
+ 0xff9e, 0xff9f,
+ 0xffe3, 0xffe3,
+ 0x102e0, 0x102e0,
+ 0x10ae5, 0x10ae6,
+ 0x10d22, 0x10d27,
+ 0x10f46, 0x10f50,
+ 0x110b9, 0x110ba,
+ 0x11133, 0x11134,
+ 0x11173, 0x11173,
+ 0x111c0, 0x111c0,
+ 0x111ca, 0x111cc,
+ 0x11235, 0x11236,
+ 0x112e9, 0x112ea,
+ 0x1133c, 0x1133c,
+ 0x1134d, 0x1134d,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11442, 0x11442,
+ 0x11446, 0x11446,
+ 0x114c2, 0x114c3,
+ 0x115bf, 0x115c0,
+ 0x1163f, 0x1163f,
+ 0x116b6, 0x116b7,
+ 0x1172b, 0x1172b,
+ 0x11839, 0x1183a,
+ 0x119e0, 0x119e0,
+ 0x11a34, 0x11a34,
+ 0x11a47, 0x11a47,
+ 0x11a99, 0x11a99,
+ 0x11c3f, 0x11c3f,
+ 0x11d42, 0x11d42,
+ 0x11d44, 0x11d45,
+ 0x11d97, 0x11d97,
+ 0x16af0, 0x16af4,
+ 0x16b30, 0x16b36,
+ 0x16f8f, 0x16f9f,
+ 0x1d167, 0x1d169,
+ 0x1d16d, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1e130, 0x1e136,
+ 0x1e2ec, 0x1e2ef,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e944, 0x1e946,
+ 0x1e948, 0x1e94a,
+}; /* CR_Diacritic */
+
+/* 'Extender': Binary Property */
+static const OnigCodePoint CR_Extender[] = {
+ 31,
+ 0x00b7, 0x00b7,
+ 0x02d0, 0x02d1,
+ 0x0640, 0x0640,
+ 0x07fa, 0x07fa,
+ 0x0e46, 0x0e46,
+ 0x0ec6, 0x0ec6,
+ 0x180a, 0x180a,
+ 0x1843, 0x1843,
+ 0x1aa7, 0x1aa7,
+ 0x1c36, 0x1c36,
+ 0x1c7b, 0x1c7b,
+ 0x3005, 0x3005,
+ 0x3031, 0x3035,
+ 0x309d, 0x309e,
+ 0x30fc, 0x30fe,
+ 0xa015, 0xa015,
+ 0xa60c, 0xa60c,
+ 0xa9cf, 0xa9cf,
+ 0xa9e6, 0xa9e6,
+ 0xaa70, 0xaa70,
+ 0xaadd, 0xaadd,
+ 0xaaf3, 0xaaf4,
+ 0xff70, 0xff70,
+ 0x1135d, 0x1135d,
+ 0x115c6, 0x115c8,
+ 0x11a98, 0x11a98,
+ 0x16b42, 0x16b43,
+ 0x16fe0, 0x16fe1,
+ 0x16fe3, 0x16fe3,
+ 0x1e13c, 0x1e13d,
+ 0x1e944, 0x1e946,
+}; /* CR_Extender */
+
+/* 'Other_Lowercase': Binary Property */
+static const OnigCodePoint CR_Other_Lowercase[] = {
+ 20,
+ 0x00aa, 0x00aa,
+ 0x00ba, 0x00ba,
+ 0x02b0, 0x02b8,
+ 0x02c0, 0x02c1,
+ 0x02e0, 0x02e4,
+ 0x0345, 0x0345,
+ 0x037a, 0x037a,
+ 0x1d2c, 0x1d6a,
+ 0x1d78, 0x1d78,
+ 0x1d9b, 0x1dbf,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x209c,
+ 0x2170, 0x217f,
+ 0x24d0, 0x24e9,
+ 0x2c7c, 0x2c7d,
+ 0xa69c, 0xa69d,
+ 0xa770, 0xa770,
+ 0xa7f8, 0xa7f9,
+ 0xab5c, 0xab5f,
+}; /* CR_Other_Lowercase */
+
+/* 'Other_Uppercase': Binary Property */
+static const OnigCodePoint CR_Other_Uppercase[] = {
+ 5,
+ 0x2160, 0x216f,
+ 0x24b6, 0x24cf,
+ 0x1f130, 0x1f149,
+ 0x1f150, 0x1f169,
+ 0x1f170, 0x1f189,
+}; /* CR_Other_Uppercase */
+
+/* 'Noncharacter_Code_Point': Binary Property */
+static const OnigCodePoint CR_Noncharacter_Code_Point[] = {
+ 18,
+ 0xfdd0, 0xfdef,
+ 0xfffe, 0xffff,
+ 0x1fffe, 0x1ffff,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xefffe, 0xeffff,
+ 0xffffe, 0xfffff,
+ 0x10fffe, 0x10ffff,
+}; /* CR_Noncharacter_Code_Point */
+
+/* 'Other_Grapheme_Extend': Binary Property */
+static const OnigCodePoint CR_Other_Grapheme_Extend[] = {
+ 24,
+ 0x09be, 0x09be,
+ 0x09d7, 0x09d7,
+ 0x0b3e, 0x0b3e,
+ 0x0b57, 0x0b57,
+ 0x0bbe, 0x0bbe,
+ 0x0bd7, 0x0bd7,
+ 0x0cc2, 0x0cc2,
+ 0x0cd5, 0x0cd6,
+ 0x0d3e, 0x0d3e,
+ 0x0d57, 0x0d57,
+ 0x0dcf, 0x0dcf,
+ 0x0ddf, 0x0ddf,
+ 0x1b35, 0x1b35,
+ 0x200c, 0x200c,
+ 0x302e, 0x302f,
+ 0xff9e, 0xff9f,
+ 0x1133e, 0x1133e,
+ 0x11357, 0x11357,
+ 0x114b0, 0x114b0,
+ 0x114bd, 0x114bd,
+ 0x115af, 0x115af,
+ 0x1d165, 0x1d165,
+ 0x1d16e, 0x1d172,
+ 0xe0020, 0xe007f,
+}; /* CR_Other_Grapheme_Extend */
+
+/* 'IDS_Binary_Operator': Binary Property */
+static const OnigCodePoint CR_IDS_Binary_Operator[] = {
+ 2,
+ 0x2ff0, 0x2ff1,
+ 0x2ff4, 0x2ffb,
+}; /* CR_IDS_Binary_Operator */
+
+/* 'IDS_Trinary_Operator': Binary Property */
+static const OnigCodePoint CR_IDS_Trinary_Operator[] = {
+ 1,
+ 0x2ff2, 0x2ff3,
+}; /* CR_IDS_Trinary_Operator */
+
+/* 'Radical': Binary Property */
+static const OnigCodePoint CR_Radical[] = {
+ 3,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+}; /* CR_Radical */
+
+/* 'Unified_Ideograph': Binary Property */
+static const OnigCodePoint CR_Unified_Ideograph[] = {
+ 14,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fef,
+ 0xfa0e, 0xfa0f,
+ 0xfa11, 0xfa11,
+ 0xfa13, 0xfa14,
+ 0xfa1f, 0xfa1f,
+ 0xfa21, 0xfa21,
+ 0xfa23, 0xfa24,
+ 0xfa27, 0xfa29,
+ 0x20000, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+}; /* CR_Unified_Ideograph */
+
+/* 'Other_Default_Ignorable_Code_Point': Binary Property */
+static const OnigCodePoint CR_Other_Default_Ignorable_Code_Point[] = {
+ 11,
+ 0x034f, 0x034f,
+ 0x115f, 0x1160,
+ 0x17b4, 0x17b5,
+ 0x2065, 0x2065,
+ 0x3164, 0x3164,
+ 0xffa0, 0xffa0,
+ 0xfff0, 0xfff8,
+ 0xe0000, 0xe0000,
+ 0xe0002, 0xe001f,
+ 0xe0080, 0xe00ff,
+ 0xe01f0, 0xe0fff,
+}; /* CR_Other_Default_Ignorable_Code_Point */
+
+/* 'Deprecated': Binary Property */
+static const OnigCodePoint CR_Deprecated[] = {
+ 8,
+ 0x0149, 0x0149,
+ 0x0673, 0x0673,
+ 0x0f77, 0x0f77,
+ 0x0f79, 0x0f79,
+ 0x17a3, 0x17a4,
+ 0x206a, 0x206f,
+ 0x2329, 0x232a,
+ 0xe0001, 0xe0001,
+}; /* CR_Deprecated */
+
+/* 'Soft_Dotted': Binary Property */
+static const OnigCodePoint CR_Soft_Dotted[] = {
+ 31,
+ 0x0069, 0x006a,
+ 0x012f, 0x012f,
+ 0x0249, 0x0249,
+ 0x0268, 0x0268,
+ 0x029d, 0x029d,
+ 0x02b2, 0x02b2,
+ 0x03f3, 0x03f3,
+ 0x0456, 0x0456,
+ 0x0458, 0x0458,
+ 0x1d62, 0x1d62,
+ 0x1d96, 0x1d96,
+ 0x1da4, 0x1da4,
+ 0x1da8, 0x1da8,
+ 0x1e2d, 0x1e2d,
+ 0x1ecb, 0x1ecb,
+ 0x2071, 0x2071,
+ 0x2148, 0x2149,
+ 0x2c7c, 0x2c7c,
+ 0x1d422, 0x1d423,
+ 0x1d456, 0x1d457,
+ 0x1d48a, 0x1d48b,
+ 0x1d4be, 0x1d4bf,
+ 0x1d4f2, 0x1d4f3,
+ 0x1d526, 0x1d527,
+ 0x1d55a, 0x1d55b,
+ 0x1d58e, 0x1d58f,
+ 0x1d5c2, 0x1d5c3,
+ 0x1d5f6, 0x1d5f7,
+ 0x1d62a, 0x1d62b,
+ 0x1d65e, 0x1d65f,
+ 0x1d692, 0x1d693,
+}; /* CR_Soft_Dotted */
+
+/* 'Logical_Order_Exception': Binary Property */
+static const OnigCodePoint CR_Logical_Order_Exception[] = {
+ 7,
+ 0x0e40, 0x0e44,
+ 0x0ec0, 0x0ec4,
+ 0x19b5, 0x19b7,
+ 0x19ba, 0x19ba,
+ 0xaab5, 0xaab6,
+ 0xaab9, 0xaab9,
+ 0xaabb, 0xaabc,
+}; /* CR_Logical_Order_Exception */
+
+/* 'Other_ID_Start': Binary Property */
+static const OnigCodePoint CR_Other_ID_Start[] = {
+ 4,
+ 0x1885, 0x1886,
+ 0x2118, 0x2118,
+ 0x212e, 0x212e,
+ 0x309b, 0x309c,
+}; /* CR_Other_ID_Start */
+
+/* 'Other_ID_Continue': Binary Property */
+static const OnigCodePoint CR_Other_ID_Continue[] = {
+ 4,
+ 0x00b7, 0x00b7,
+ 0x0387, 0x0387,
+ 0x1369, 0x1371,
+ 0x19da, 0x19da,
+}; /* CR_Other_ID_Continue */
+
+/* 'Sentence_Terminal': Binary Property */
+static const OnigCodePoint CR_Sentence_Terminal[] = {
+ 74,
+ 0x0021, 0x0021,
+ 0x002e, 0x002e,
+ 0x003f, 0x003f,
+ 0x0589, 0x0589,
+ 0x061e, 0x061f,
+ 0x06d4, 0x06d4,
+ 0x0700, 0x0702,
+ 0x07f9, 0x07f9,
+ 0x0837, 0x0837,
+ 0x0839, 0x0839,
+ 0x083d, 0x083e,
+ 0x0964, 0x0965,
+ 0x104a, 0x104b,
+ 0x1362, 0x1362,
+ 0x1367, 0x1368,
+ 0x166e, 0x166e,
+ 0x1735, 0x1736,
+ 0x1803, 0x1803,
+ 0x1809, 0x1809,
+ 0x1944, 0x1945,
+ 0x1aa8, 0x1aab,
+ 0x1b5a, 0x1b5b,
+ 0x1b5e, 0x1b5f,
+ 0x1c3b, 0x1c3c,
+ 0x1c7e, 0x1c7f,
+ 0x203c, 0x203d,
+ 0x2047, 0x2049,
+ 0x2e2e, 0x2e2e,
+ 0x2e3c, 0x2e3c,
+ 0x3002, 0x3002,
+ 0xa4ff, 0xa4ff,
+ 0xa60e, 0xa60f,
+ 0xa6f3, 0xa6f3,
+ 0xa6f7, 0xa6f7,
+ 0xa876, 0xa877,
+ 0xa8ce, 0xa8cf,
+ 0xa92f, 0xa92f,
+ 0xa9c8, 0xa9c9,
+ 0xaa5d, 0xaa5f,
+ 0xaaf0, 0xaaf1,
+ 0xabeb, 0xabeb,
+ 0xfe52, 0xfe52,
+ 0xfe56, 0xfe57,
+ 0xff01, 0xff01,
+ 0xff0e, 0xff0e,
+ 0xff1f, 0xff1f,
+ 0xff61, 0xff61,
+ 0x10a56, 0x10a57,
+ 0x10f55, 0x10f59,
+ 0x11047, 0x11048,
+ 0x110be, 0x110c1,
+ 0x11141, 0x11143,
+ 0x111c5, 0x111c6,
+ 0x111cd, 0x111cd,
+ 0x111de, 0x111df,
+ 0x11238, 0x11239,
+ 0x1123b, 0x1123c,
+ 0x112a9, 0x112a9,
+ 0x1144b, 0x1144c,
+ 0x115c2, 0x115c3,
+ 0x115c9, 0x115d7,
+ 0x11641, 0x11642,
+ 0x1173c, 0x1173e,
+ 0x11a42, 0x11a43,
+ 0x11a9b, 0x11a9c,
+ 0x11c41, 0x11c42,
+ 0x11ef7, 0x11ef8,
+ 0x16a6e, 0x16a6f,
+ 0x16af5, 0x16af5,
+ 0x16b37, 0x16b38,
+ 0x16b44, 0x16b44,
+ 0x16e98, 0x16e98,
+ 0x1bc9f, 0x1bc9f,
+ 0x1da88, 0x1da88,
+}; /* CR_Sentence_Terminal */
+
+/* 'Variation_Selector': Binary Property */
+static const OnigCodePoint CR_Variation_Selector[] = {
+ 3,
+ 0x180b, 0x180d,
+ 0xfe00, 0xfe0f,
+ 0xe0100, 0xe01ef,
+}; /* CR_Variation_Selector */
+
+/* 'Pattern_White_Space': Binary Property */
+static const OnigCodePoint CR_Pattern_White_Space[] = {
+ 5,
+ 0x0009, 0x000d,
+ 0x0020, 0x0020,
+ 0x0085, 0x0085,
+ 0x200e, 0x200f,
+ 0x2028, 0x2029,
+}; /* CR_Pattern_White_Space */
+
+/* 'Pattern_Syntax': Binary Property */
+static const OnigCodePoint CR_Pattern_Syntax[] = {
+ 28,
+ 0x0021, 0x002f,
+ 0x003a, 0x0040,
+ 0x005b, 0x005e,
+ 0x0060, 0x0060,
+ 0x007b, 0x007e,
+ 0x00a1, 0x00a7,
+ 0x00a9, 0x00a9,
+ 0x00ab, 0x00ac,
+ 0x00ae, 0x00ae,
+ 0x00b0, 0x00b1,
+ 0x00b6, 0x00b6,
+ 0x00bb, 0x00bb,
+ 0x00bf, 0x00bf,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x2010, 0x2027,
+ 0x2030, 0x203e,
+ 0x2041, 0x2053,
+ 0x2055, 0x205e,
+ 0x2190, 0x245f,
+ 0x2500, 0x2775,
+ 0x2794, 0x2bff,
+ 0x2e00, 0x2e7f,
+ 0x3001, 0x3003,
+ 0x3008, 0x3020,
+ 0x3030, 0x3030,
+ 0xfd3e, 0xfd3f,
+ 0xfe45, 0xfe46,
+}; /* CR_Pattern_Syntax */
+
+/* 'Prepended_Concatenation_Mark': Binary Property */
+static const OnigCodePoint CR_Prepended_Concatenation_Mark[] = {
+ 6,
+ 0x0600, 0x0605,
+ 0x06dd, 0x06dd,
+ 0x070f, 0x070f,
+ 0x08e2, 0x08e2,
+ 0x110bd, 0x110bd,
+ 0x110cd, 0x110cd,
+}; /* CR_Prepended_Concatenation_Mark */
+
+/* 'Regional_Indicator': Binary Property */
+static const OnigCodePoint CR_Regional_Indicator[] = {
+ 1,
+ 0x1f1e6, 0x1f1ff,
+}; /* CR_Regional_Indicator */
+
+/* 'Emoji': Emoji */
+static const OnigCodePoint CR_Emoji[] = {
+ 151,
+ 0x0023, 0x0023,
+ 0x002a, 0x002a,
+ 0x0030, 0x0039,
+ 0x00a9, 0x00a9,
+ 0x00ae, 0x00ae,
+ 0x203c, 0x203c,
+ 0x2049, 0x2049,
+ 0x2122, 0x2122,
+ 0x2139, 0x2139,
+ 0x2194, 0x2199,
+ 0x21a9, 0x21aa,
+ 0x231a, 0x231b,
+ 0x2328, 0x2328,
+ 0x23cf, 0x23cf,
+ 0x23e9, 0x23f3,
+ 0x23f8, 0x23fa,
+ 0x24c2, 0x24c2,
+ 0x25aa, 0x25ab,
+ 0x25b6, 0x25b6,
+ 0x25c0, 0x25c0,
+ 0x25fb, 0x25fe,
+ 0x2600, 0x2604,
+ 0x260e, 0x260e,
+ 0x2611, 0x2611,
+ 0x2614, 0x2615,
+ 0x2618, 0x2618,
+ 0x261d, 0x261d,
+ 0x2620, 0x2620,
+ 0x2622, 0x2623,
+ 0x2626, 0x2626,
+ 0x262a, 0x262a,
+ 0x262e, 0x262f,
+ 0x2638, 0x263a,
+ 0x2640, 0x2640,
+ 0x2642, 0x2642,
+ 0x2648, 0x2653,
+ 0x265f, 0x2660,
+ 0x2663, 0x2663,
+ 0x2665, 0x2666,
+ 0x2668, 0x2668,
+ 0x267b, 0x267b,
+ 0x267e, 0x267f,
+ 0x2692, 0x2697,
+ 0x2699, 0x2699,
+ 0x269b, 0x269c,
+ 0x26a0, 0x26a1,
+ 0x26aa, 0x26ab,
+ 0x26b0, 0x26b1,
+ 0x26bd, 0x26be,
+ 0x26c4, 0x26c5,
+ 0x26c8, 0x26c8,
+ 0x26ce, 0x26cf,
+ 0x26d1, 0x26d1,
+ 0x26d3, 0x26d4,
+ 0x26e9, 0x26ea,
+ 0x26f0, 0x26f5,
+ 0x26f7, 0x26fa,
+ 0x26fd, 0x26fd,
+ 0x2702, 0x2702,
+ 0x2705, 0x2705,
+ 0x2708, 0x270d,
+ 0x270f, 0x270f,
+ 0x2712, 0x2712,
+ 0x2714, 0x2714,
+ 0x2716, 0x2716,
+ 0x271d, 0x271d,
+ 0x2721, 0x2721,
+ 0x2728, 0x2728,
+ 0x2733, 0x2734,
+ 0x2744, 0x2744,
+ 0x2747, 0x2747,
+ 0x274c, 0x274c,
+ 0x274e, 0x274e,
+ 0x2753, 0x2755,
+ 0x2757, 0x2757,
+ 0x2763, 0x2764,
+ 0x2795, 0x2797,
+ 0x27a1, 0x27a1,
+ 0x27b0, 0x27b0,
+ 0x27bf, 0x27bf,
+ 0x2934, 0x2935,
+ 0x2b05, 0x2b07,
+ 0x2b1b, 0x2b1c,
+ 0x2b50, 0x2b50,
+ 0x2b55, 0x2b55,
+ 0x3030, 0x3030,
+ 0x303d, 0x303d,
+ 0x3297, 0x3297,
+ 0x3299, 0x3299,
+ 0x1f004, 0x1f004,
+ 0x1f0cf, 0x1f0cf,
+ 0x1f170, 0x1f171,
+ 0x1f17e, 0x1f17f,
+ 0x1f18e, 0x1f18e,
+ 0x1f191, 0x1f19a,
+ 0x1f1e6, 0x1f1ff,
+ 0x1f201, 0x1f202,
+ 0x1f21a, 0x1f21a,
+ 0x1f22f, 0x1f22f,
+ 0x1f232, 0x1f23a,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f321,
+ 0x1f324, 0x1f393,
+ 0x1f396, 0x1f397,
+ 0x1f399, 0x1f39b,
+ 0x1f39e, 0x1f3f0,
+ 0x1f3f3, 0x1f3f5,
+ 0x1f3f7, 0x1f4fd,
+ 0x1f4ff, 0x1f53d,
+ 0x1f549, 0x1f54e,
+ 0x1f550, 0x1f567,
+ 0x1f56f, 0x1f570,
+ 0x1f573, 0x1f57a,
+ 0x1f587, 0x1f587,
+ 0x1f58a, 0x1f58d,
+ 0x1f590, 0x1f590,
+ 0x1f595, 0x1f596,
+ 0x1f5a4, 0x1f5a5,
+ 0x1f5a8, 0x1f5a8,
+ 0x1f5b1, 0x1f5b2,
+ 0x1f5bc, 0x1f5bc,
+ 0x1f5c2, 0x1f5c4,
+ 0x1f5d1, 0x1f5d3,
+ 0x1f5dc, 0x1f5de,
+ 0x1f5e1, 0x1f5e1,
+ 0x1f5e3, 0x1f5e3,
+ 0x1f5e8, 0x1f5e8,
+ 0x1f5ef, 0x1f5ef,
+ 0x1f5f3, 0x1f5f3,
+ 0x1f5fa, 0x1f64f,
+ 0x1f680, 0x1f6c5,
+ 0x1f6cb, 0x1f6d2,
+ 0x1f6d5, 0x1f6d5,
+ 0x1f6e0, 0x1f6e5,
+ 0x1f6e9, 0x1f6e9,
+ 0x1f6eb, 0x1f6ec,
+ 0x1f6f0, 0x1f6f0,
+ 0x1f6f3, 0x1f6fa,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f90d, 0x1f93a,
+ 0x1f93c, 0x1f945,
+ 0x1f947, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1f9ff,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+}; /* CR_Emoji */
+
+/* 'Emoji_Presentation': Emoji */
+static const OnigCodePoint CR_Emoji_Presentation[] = {
+ 81,
+ 0x231a, 0x231b,
+ 0x23e9, 0x23ec,
+ 0x23f0, 0x23f0,
+ 0x23f3, 0x23f3,
+ 0x25fd, 0x25fe,
+ 0x2614, 0x2615,
+ 0x2648, 0x2653,
+ 0x267f, 0x267f,
+ 0x2693, 0x2693,
+ 0x26a1, 0x26a1,
+ 0x26aa, 0x26ab,
+ 0x26bd, 0x26be,
+ 0x26c4, 0x26c5,
+ 0x26ce, 0x26ce,
+ 0x26d4, 0x26d4,
+ 0x26ea, 0x26ea,
+ 0x26f2, 0x26f3,
+ 0x26f5, 0x26f5,
+ 0x26fa, 0x26fa,
+ 0x26fd, 0x26fd,
+ 0x2705, 0x2705,
+ 0x270a, 0x270b,
+ 0x2728, 0x2728,
+ 0x274c, 0x274c,
+ 0x274e, 0x274e,
+ 0x2753, 0x2755,
+ 0x2757, 0x2757,
+ 0x2795, 0x2797,
+ 0x27b0, 0x27b0,
+ 0x27bf, 0x27bf,
+ 0x2b1b, 0x2b1c,
+ 0x2b50, 0x2b50,
+ 0x2b55, 0x2b55,
+ 0x1f004, 0x1f004,
+ 0x1f0cf, 0x1f0cf,
+ 0x1f18e, 0x1f18e,
+ 0x1f191, 0x1f19a,
+ 0x1f1e6, 0x1f1ff,
+ 0x1f201, 0x1f201,
+ 0x1f21a, 0x1f21a,
+ 0x1f22f, 0x1f22f,
+ 0x1f232, 0x1f236,
+ 0x1f238, 0x1f23a,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f320,
+ 0x1f32d, 0x1f335,
+ 0x1f337, 0x1f37c,
+ 0x1f37e, 0x1f393,
+ 0x1f3a0, 0x1f3ca,
+ 0x1f3cf, 0x1f3d3,
+ 0x1f3e0, 0x1f3f0,
+ 0x1f3f4, 0x1f3f4,
+ 0x1f3f8, 0x1f43e,
+ 0x1f440, 0x1f440,
+ 0x1f442, 0x1f4fc,
+ 0x1f4ff, 0x1f53d,
+ 0x1f54b, 0x1f54e,
+ 0x1f550, 0x1f567,
+ 0x1f57a, 0x1f57a,
+ 0x1f595, 0x1f596,
+ 0x1f5a4, 0x1f5a4,
+ 0x1f5fb, 0x1f64f,
+ 0x1f680, 0x1f6c5,
+ 0x1f6cc, 0x1f6cc,
+ 0x1f6d0, 0x1f6d2,
+ 0x1f6d5, 0x1f6d5,
+ 0x1f6eb, 0x1f6ec,
+ 0x1f6f4, 0x1f6fa,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f90d, 0x1f93a,
+ 0x1f93c, 0x1f945,
+ 0x1f947, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1f9ff,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+}; /* CR_Emoji_Presentation */
+
+/* 'Emoji_Modifier': Emoji */
+static const OnigCodePoint CR_Emoji_Modifier[] = {
+ 1,
+ 0x1f3fb, 0x1f3ff,
+}; /* CR_Emoji_Modifier */
+
+/* 'Emoji_Modifier_Base': Emoji */
+static const OnigCodePoint CR_Emoji_Modifier_Base[] = {
+ 36,
+ 0x261d, 0x261d,
+ 0x26f9, 0x26f9,
+ 0x270a, 0x270d,
+ 0x1f385, 0x1f385,
+ 0x1f3c2, 0x1f3c4,
+ 0x1f3c7, 0x1f3c7,
+ 0x1f3ca, 0x1f3cc,
+ 0x1f442, 0x1f443,
+ 0x1f446, 0x1f450,
+ 0x1f466, 0x1f478,
+ 0x1f47c, 0x1f47c,
+ 0x1f481, 0x1f483,
+ 0x1f485, 0x1f487,
+ 0x1f48f, 0x1f48f,
+ 0x1f491, 0x1f491,
+ 0x1f4aa, 0x1f4aa,
+ 0x1f574, 0x1f575,
+ 0x1f57a, 0x1f57a,
+ 0x1f590, 0x1f590,
+ 0x1f595, 0x1f596,
+ 0x1f645, 0x1f647,
+ 0x1f64b, 0x1f64f,
+ 0x1f6a3, 0x1f6a3,
+ 0x1f6b4, 0x1f6b6,
+ 0x1f6c0, 0x1f6c0,
+ 0x1f6cc, 0x1f6cc,
+ 0x1f90f, 0x1f90f,
+ 0x1f918, 0x1f91f,
+ 0x1f926, 0x1f926,
+ 0x1f930, 0x1f939,
+ 0x1f93c, 0x1f93e,
+ 0x1f9b5, 0x1f9b6,
+ 0x1f9b8, 0x1f9b9,
+ 0x1f9bb, 0x1f9bb,
+ 0x1f9cd, 0x1f9cf,
+ 0x1f9d1, 0x1f9dd,
+}; /* CR_Emoji_Modifier_Base */
+
+/* 'Emoji_Component': Emoji */
+static const OnigCodePoint CR_Emoji_Component[] = {
+ 10,
+ 0x0023, 0x0023,
+ 0x002a, 0x002a,
+ 0x0030, 0x0039,
+ 0x200d, 0x200d,
+ 0x20e3, 0x20e3,
+ 0xfe0f, 0xfe0f,
+ 0x1f1e6, 0x1f1ff,
+ 0x1f3fb, 0x1f3ff,
+ 0x1f9b0, 0x1f9b3,
+ 0xe0020, 0xe007f,
+}; /* CR_Emoji_Component */
+
+/* 'Extended_Pictographic': Emoji */
+static const OnigCodePoint CR_Extended_Pictographic[] = {
+ 77,
+ 0x00a9, 0x00a9,
+ 0x00ae, 0x00ae,
+ 0x203c, 0x203c,
+ 0x2049, 0x2049,
+ 0x2122, 0x2122,
+ 0x2139, 0x2139,
+ 0x2194, 0x2199,
+ 0x21a9, 0x21aa,
+ 0x231a, 0x231b,
+ 0x2328, 0x2328,
+ 0x2388, 0x2388,
+ 0x23cf, 0x23cf,
+ 0x23e9, 0x23f3,
+ 0x23f8, 0x23fa,
+ 0x24c2, 0x24c2,
+ 0x25aa, 0x25ab,
+ 0x25b6, 0x25b6,
+ 0x25c0, 0x25c0,
+ 0x25fb, 0x25fe,
+ 0x2600, 0x2605,
+ 0x2607, 0x2612,
+ 0x2614, 0x2685,
+ 0x2690, 0x2705,
+ 0x2708, 0x2712,
+ 0x2714, 0x2714,
+ 0x2716, 0x2716,
+ 0x271d, 0x271d,
+ 0x2721, 0x2721,
+ 0x2728, 0x2728,
+ 0x2733, 0x2734,
+ 0x2744, 0x2744,
+ 0x2747, 0x2747,
+ 0x274c, 0x274c,
+ 0x274e, 0x274e,
+ 0x2753, 0x2755,
+ 0x2757, 0x2757,
+ 0x2763, 0x2767,
+ 0x2795, 0x2797,
+ 0x27a1, 0x27a1,
+ 0x27b0, 0x27b0,
+ 0x27bf, 0x27bf,
+ 0x2934, 0x2935,
+ 0x2b05, 0x2b07,
+ 0x2b1b, 0x2b1c,
+ 0x2b50, 0x2b50,
+ 0x2b55, 0x2b55,
+ 0x3030, 0x3030,
+ 0x303d, 0x303d,
+ 0x3297, 0x3297,
+ 0x3299, 0x3299,
+ 0x1f000, 0x1f0ff,
+ 0x1f10d, 0x1f10f,
+ 0x1f12f, 0x1f12f,
+ 0x1f16c, 0x1f171,
+ 0x1f17e, 0x1f17f,
+ 0x1f18e, 0x1f18e,
+ 0x1f191, 0x1f19a,
+ 0x1f1ad, 0x1f1e5,
+ 0x1f201, 0x1f20f,
+ 0x1f21a, 0x1f21a,
+ 0x1f22f, 0x1f22f,
+ 0x1f232, 0x1f23a,
+ 0x1f23c, 0x1f23f,
+ 0x1f249, 0x1f3fa,
+ 0x1f400, 0x1f53d,
+ 0x1f546, 0x1f64f,
+ 0x1f680, 0x1f6ff,
+ 0x1f774, 0x1f77f,
+ 0x1f7d5, 0x1f7ff,
+ 0x1f80c, 0x1f80f,
+ 0x1f848, 0x1f84f,
+ 0x1f85a, 0x1f85f,
+ 0x1f888, 0x1f88f,
+ 0x1f8ae, 0x1f8ff,
+ 0x1f90c, 0x1f93a,
+ 0x1f93c, 0x1f945,
+ 0x1f947, 0x1fffd,
+}; /* CR_Extended_Pictographic */
+
+/* 'Unknown': Script */
+static const OnigCodePoint CR_Unknown[] = {
+ 664,
+ 0x0378, 0x0379,
+ 0x0380, 0x0383,
+ 0x038b, 0x038b,
+ 0x038d, 0x038d,
+ 0x03a2, 0x03a2,
+ 0x0530, 0x0530,
+ 0x0557, 0x0558,
+ 0x058b, 0x058c,
+ 0x0590, 0x0590,
+ 0x05c8, 0x05cf,
+ 0x05eb, 0x05ee,
+ 0x05f5, 0x05ff,
+ 0x061d, 0x061d,
+ 0x070e, 0x070e,
+ 0x074b, 0x074c,
+ 0x07b2, 0x07bf,
+ 0x07fb, 0x07fc,
+ 0x082e, 0x082f,
+ 0x083f, 0x083f,
+ 0x085c, 0x085d,
+ 0x085f, 0x085f,
+ 0x086b, 0x089f,
+ 0x08b5, 0x08b5,
+ 0x08be, 0x08d2,
+ 0x0984, 0x0984,
+ 0x098d, 0x098e,
+ 0x0991, 0x0992,
+ 0x09a9, 0x09a9,
+ 0x09b1, 0x09b1,
+ 0x09b3, 0x09b5,
+ 0x09ba, 0x09bb,
+ 0x09c5, 0x09c6,
+ 0x09c9, 0x09ca,
+ 0x09cf, 0x09d6,
+ 0x09d8, 0x09db,
+ 0x09de, 0x09de,
+ 0x09e4, 0x09e5,
+ 0x09ff, 0x0a00,
+ 0x0a04, 0x0a04,
+ 0x0a0b, 0x0a0e,
+ 0x0a11, 0x0a12,
+ 0x0a29, 0x0a29,
+ 0x0a31, 0x0a31,
+ 0x0a34, 0x0a34,
+ 0x0a37, 0x0a37,
+ 0x0a3a, 0x0a3b,
+ 0x0a3d, 0x0a3d,
+ 0x0a43, 0x0a46,
+ 0x0a49, 0x0a4a,
+ 0x0a4e, 0x0a50,
+ 0x0a52, 0x0a58,
+ 0x0a5d, 0x0a5d,
+ 0x0a5f, 0x0a65,
+ 0x0a77, 0x0a80,
+ 0x0a84, 0x0a84,
+ 0x0a8e, 0x0a8e,
+ 0x0a92, 0x0a92,
+ 0x0aa9, 0x0aa9,
+ 0x0ab1, 0x0ab1,
+ 0x0ab4, 0x0ab4,
+ 0x0aba, 0x0abb,
+ 0x0ac6, 0x0ac6,
+ 0x0aca, 0x0aca,
+ 0x0ace, 0x0acf,
+ 0x0ad1, 0x0adf,
+ 0x0ae4, 0x0ae5,
+ 0x0af2, 0x0af8,
+ 0x0b00, 0x0b00,
+ 0x0b04, 0x0b04,
+ 0x0b0d, 0x0b0e,
+ 0x0b11, 0x0b12,
+ 0x0b29, 0x0b29,
+ 0x0b31, 0x0b31,
+ 0x0b34, 0x0b34,
+ 0x0b3a, 0x0b3b,
+ 0x0b45, 0x0b46,
+ 0x0b49, 0x0b4a,
+ 0x0b4e, 0x0b55,
+ 0x0b58, 0x0b5b,
+ 0x0b5e, 0x0b5e,
+ 0x0b64, 0x0b65,
+ 0x0b78, 0x0b81,
+ 0x0b84, 0x0b84,
+ 0x0b8b, 0x0b8d,
+ 0x0b91, 0x0b91,
+ 0x0b96, 0x0b98,
+ 0x0b9b, 0x0b9b,
+ 0x0b9d, 0x0b9d,
+ 0x0ba0, 0x0ba2,
+ 0x0ba5, 0x0ba7,
+ 0x0bab, 0x0bad,
+ 0x0bba, 0x0bbd,
+ 0x0bc3, 0x0bc5,
+ 0x0bc9, 0x0bc9,
+ 0x0bce, 0x0bcf,
+ 0x0bd1, 0x0bd6,
+ 0x0bd8, 0x0be5,
+ 0x0bfb, 0x0bff,
+ 0x0c0d, 0x0c0d,
+ 0x0c11, 0x0c11,
+ 0x0c29, 0x0c29,
+ 0x0c3a, 0x0c3c,
+ 0x0c45, 0x0c45,
+ 0x0c49, 0x0c49,
+ 0x0c4e, 0x0c54,
+ 0x0c57, 0x0c57,
+ 0x0c5b, 0x0c5f,
+ 0x0c64, 0x0c65,
+ 0x0c70, 0x0c76,
+ 0x0c8d, 0x0c8d,
+ 0x0c91, 0x0c91,
+ 0x0ca9, 0x0ca9,
+ 0x0cb4, 0x0cb4,
+ 0x0cba, 0x0cbb,
+ 0x0cc5, 0x0cc5,
+ 0x0cc9, 0x0cc9,
+ 0x0cce, 0x0cd4,
+ 0x0cd7, 0x0cdd,
+ 0x0cdf, 0x0cdf,
+ 0x0ce4, 0x0ce5,
+ 0x0cf0, 0x0cf0,
+ 0x0cf3, 0x0cff,
+ 0x0d04, 0x0d04,
+ 0x0d0d, 0x0d0d,
+ 0x0d11, 0x0d11,
+ 0x0d45, 0x0d45,
+ 0x0d49, 0x0d49,
+ 0x0d50, 0x0d53,
+ 0x0d64, 0x0d65,
+ 0x0d80, 0x0d81,
+ 0x0d84, 0x0d84,
+ 0x0d97, 0x0d99,
+ 0x0db2, 0x0db2,
+ 0x0dbc, 0x0dbc,
+ 0x0dbe, 0x0dbf,
+ 0x0dc7, 0x0dc9,
+ 0x0dcb, 0x0dce,
+ 0x0dd5, 0x0dd5,
+ 0x0dd7, 0x0dd7,
+ 0x0de0, 0x0de5,
+ 0x0df0, 0x0df1,
+ 0x0df5, 0x0e00,
+ 0x0e3b, 0x0e3e,
+ 0x0e5c, 0x0e80,
+ 0x0e83, 0x0e83,
+ 0x0e85, 0x0e85,
+ 0x0e8b, 0x0e8b,
+ 0x0ea4, 0x0ea4,
+ 0x0ea6, 0x0ea6,
+ 0x0ebe, 0x0ebf,
+ 0x0ec5, 0x0ec5,
+ 0x0ec7, 0x0ec7,
+ 0x0ece, 0x0ecf,
+ 0x0eda, 0x0edb,
+ 0x0ee0, 0x0eff,
+ 0x0f48, 0x0f48,
+ 0x0f6d, 0x0f70,
+ 0x0f98, 0x0f98,
+ 0x0fbd, 0x0fbd,
+ 0x0fcd, 0x0fcd,
+ 0x0fdb, 0x0fff,
+ 0x10c6, 0x10c6,
+ 0x10c8, 0x10cc,
+ 0x10ce, 0x10cf,
+ 0x1249, 0x1249,
+ 0x124e, 0x124f,
+ 0x1257, 0x1257,
+ 0x1259, 0x1259,
+ 0x125e, 0x125f,
+ 0x1289, 0x1289,
+ 0x128e, 0x128f,
+ 0x12b1, 0x12b1,
+ 0x12b6, 0x12b7,
+ 0x12bf, 0x12bf,
+ 0x12c1, 0x12c1,
+ 0x12c6, 0x12c7,
+ 0x12d7, 0x12d7,
+ 0x1311, 0x1311,
+ 0x1316, 0x1317,
+ 0x135b, 0x135c,
+ 0x137d, 0x137f,
+ 0x139a, 0x139f,
+ 0x13f6, 0x13f7,
+ 0x13fe, 0x13ff,
+ 0x169d, 0x169f,
+ 0x16f9, 0x16ff,
+ 0x170d, 0x170d,
+ 0x1715, 0x171f,
+ 0x1737, 0x173f,
+ 0x1754, 0x175f,
+ 0x176d, 0x176d,
+ 0x1771, 0x1771,
+ 0x1774, 0x177f,
+ 0x17de, 0x17df,
+ 0x17ea, 0x17ef,
+ 0x17fa, 0x17ff,
+ 0x180f, 0x180f,
+ 0x181a, 0x181f,
+ 0x1879, 0x187f,
+ 0x18ab, 0x18af,
+ 0x18f6, 0x18ff,
+ 0x191f, 0x191f,
+ 0x192c, 0x192f,
+ 0x193c, 0x193f,
+ 0x1941, 0x1943,
+ 0x196e, 0x196f,
+ 0x1975, 0x197f,
+ 0x19ac, 0x19af,
+ 0x19ca, 0x19cf,
+ 0x19db, 0x19dd,
+ 0x1a1c, 0x1a1d,
+ 0x1a5f, 0x1a5f,
+ 0x1a7d, 0x1a7e,
+ 0x1a8a, 0x1a8f,
+ 0x1a9a, 0x1a9f,
+ 0x1aae, 0x1aaf,
+ 0x1abf, 0x1aff,
+ 0x1b4c, 0x1b4f,
+ 0x1b7d, 0x1b7f,
+ 0x1bf4, 0x1bfb,
+ 0x1c38, 0x1c3a,
+ 0x1c4a, 0x1c4c,
+ 0x1c89, 0x1c8f,
+ 0x1cbb, 0x1cbc,
+ 0x1cc8, 0x1ccf,
+ 0x1cfb, 0x1cff,
+ 0x1dfa, 0x1dfa,
+ 0x1f16, 0x1f17,
+ 0x1f1e, 0x1f1f,
+ 0x1f46, 0x1f47,
+ 0x1f4e, 0x1f4f,
+ 0x1f58, 0x1f58,
+ 0x1f5a, 0x1f5a,
+ 0x1f5c, 0x1f5c,
+ 0x1f5e, 0x1f5e,
+ 0x1f7e, 0x1f7f,
+ 0x1fb5, 0x1fb5,
+ 0x1fc5, 0x1fc5,
+ 0x1fd4, 0x1fd5,
+ 0x1fdc, 0x1fdc,
+ 0x1ff0, 0x1ff1,
+ 0x1ff5, 0x1ff5,
+ 0x1fff, 0x1fff,
+ 0x2065, 0x2065,
+ 0x2072, 0x2073,
+ 0x208f, 0x208f,
+ 0x209d, 0x209f,
+ 0x20c0, 0x20cf,
+ 0x20f1, 0x20ff,
+ 0x218c, 0x218f,
+ 0x2427, 0x243f,
+ 0x244b, 0x245f,
+ 0x2b74, 0x2b75,
+ 0x2b96, 0x2b97,
+ 0x2c2f, 0x2c2f,
+ 0x2c5f, 0x2c5f,
+ 0x2cf4, 0x2cf8,
+ 0x2d26, 0x2d26,
+ 0x2d28, 0x2d2c,
+ 0x2d2e, 0x2d2f,
+ 0x2d68, 0x2d6e,
+ 0x2d71, 0x2d7e,
+ 0x2d97, 0x2d9f,
+ 0x2da7, 0x2da7,
+ 0x2daf, 0x2daf,
+ 0x2db7, 0x2db7,
+ 0x2dbf, 0x2dbf,
+ 0x2dc7, 0x2dc7,
+ 0x2dcf, 0x2dcf,
+ 0x2dd7, 0x2dd7,
+ 0x2ddf, 0x2ddf,
+ 0x2e50, 0x2e7f,
+ 0x2e9a, 0x2e9a,
+ 0x2ef4, 0x2eff,
+ 0x2fd6, 0x2fef,
+ 0x2ffc, 0x2fff,
+ 0x3040, 0x3040,
+ 0x3097, 0x3098,
+ 0x3100, 0x3104,
+ 0x3130, 0x3130,
+ 0x318f, 0x318f,
+ 0x31bb, 0x31bf,
+ 0x31e4, 0x31ef,
+ 0x321f, 0x321f,
+ 0x4db6, 0x4dbf,
+ 0x9ff0, 0x9fff,
+ 0xa48d, 0xa48f,
+ 0xa4c7, 0xa4cf,
+ 0xa62c, 0xa63f,
+ 0xa6f8, 0xa6ff,
+ 0xa7c0, 0xa7c1,
+ 0xa7c7, 0xa7f6,
+ 0xa82c, 0xa82f,
+ 0xa83a, 0xa83f,
+ 0xa878, 0xa87f,
+ 0xa8c6, 0xa8cd,
+ 0xa8da, 0xa8df,
+ 0xa954, 0xa95e,
+ 0xa97d, 0xa97f,
+ 0xa9ce, 0xa9ce,
+ 0xa9da, 0xa9dd,
+ 0xa9ff, 0xa9ff,
+ 0xaa37, 0xaa3f,
+ 0xaa4e, 0xaa4f,
+ 0xaa5a, 0xaa5b,
+ 0xaac3, 0xaada,
+ 0xaaf7, 0xab00,
+ 0xab07, 0xab08,
+ 0xab0f, 0xab10,
+ 0xab17, 0xab1f,
+ 0xab27, 0xab27,
+ 0xab2f, 0xab2f,
+ 0xab68, 0xab6f,
+ 0xabee, 0xabef,
+ 0xabfa, 0xabff,
+ 0xd7a4, 0xd7af,
+ 0xd7c7, 0xd7ca,
+ 0xd7fc, 0xf8ff,
+ 0xfa6e, 0xfa6f,
+ 0xfada, 0xfaff,
+ 0xfb07, 0xfb12,
+ 0xfb18, 0xfb1c,
+ 0xfb37, 0xfb37,
+ 0xfb3d, 0xfb3d,
+ 0xfb3f, 0xfb3f,
+ 0xfb42, 0xfb42,
+ 0xfb45, 0xfb45,
+ 0xfbc2, 0xfbd2,
+ 0xfd40, 0xfd4f,
+ 0xfd90, 0xfd91,
+ 0xfdc8, 0xfdef,
+ 0xfdfe, 0xfdff,
+ 0xfe1a, 0xfe1f,
+ 0xfe53, 0xfe53,
+ 0xfe67, 0xfe67,
+ 0xfe6c, 0xfe6f,
+ 0xfe75, 0xfe75,
+ 0xfefd, 0xfefe,
+ 0xff00, 0xff00,
+ 0xffbf, 0xffc1,
+ 0xffc8, 0xffc9,
+ 0xffd0, 0xffd1,
+ 0xffd8, 0xffd9,
+ 0xffdd, 0xffdf,
+ 0xffe7, 0xffe7,
+ 0xffef, 0xfff8,
+ 0xfffe, 0xffff,
+ 0x1000c, 0x1000c,
+ 0x10027, 0x10027,
+ 0x1003b, 0x1003b,
+ 0x1003e, 0x1003e,
+ 0x1004e, 0x1004f,
+ 0x1005e, 0x1007f,
+ 0x100fb, 0x100ff,
+ 0x10103, 0x10106,
+ 0x10134, 0x10136,
+ 0x1018f, 0x1018f,
+ 0x1019c, 0x1019f,
+ 0x101a1, 0x101cf,
+ 0x101fe, 0x1027f,
+ 0x1029d, 0x1029f,
+ 0x102d1, 0x102df,
+ 0x102fc, 0x102ff,
+ 0x10324, 0x1032c,
+ 0x1034b, 0x1034f,
+ 0x1037b, 0x1037f,
+ 0x1039e, 0x1039e,
+ 0x103c4, 0x103c7,
+ 0x103d6, 0x103ff,
+ 0x1049e, 0x1049f,
+ 0x104aa, 0x104af,
+ 0x104d4, 0x104d7,
+ 0x104fc, 0x104ff,
+ 0x10528, 0x1052f,
+ 0x10564, 0x1056e,
+ 0x10570, 0x105ff,
+ 0x10737, 0x1073f,
+ 0x10756, 0x1075f,
+ 0x10768, 0x107ff,
+ 0x10806, 0x10807,
+ 0x10809, 0x10809,
+ 0x10836, 0x10836,
+ 0x10839, 0x1083b,
+ 0x1083d, 0x1083e,
+ 0x10856, 0x10856,
+ 0x1089f, 0x108a6,
+ 0x108b0, 0x108df,
+ 0x108f3, 0x108f3,
+ 0x108f6, 0x108fa,
+ 0x1091c, 0x1091e,
+ 0x1093a, 0x1093e,
+ 0x10940, 0x1097f,
+ 0x109b8, 0x109bb,
+ 0x109d0, 0x109d1,
+ 0x10a04, 0x10a04,
+ 0x10a07, 0x10a0b,
+ 0x10a14, 0x10a14,
+ 0x10a18, 0x10a18,
+ 0x10a36, 0x10a37,
+ 0x10a3b, 0x10a3e,
+ 0x10a49, 0x10a4f,
+ 0x10a59, 0x10a5f,
+ 0x10aa0, 0x10abf,
+ 0x10ae7, 0x10aea,
+ 0x10af7, 0x10aff,
+ 0x10b36, 0x10b38,
+ 0x10b56, 0x10b57,
+ 0x10b73, 0x10b77,
+ 0x10b92, 0x10b98,
+ 0x10b9d, 0x10ba8,
+ 0x10bb0, 0x10bff,
+ 0x10c49, 0x10c7f,
+ 0x10cb3, 0x10cbf,
+ 0x10cf3, 0x10cf9,
+ 0x10d28, 0x10d2f,
+ 0x10d3a, 0x10e5f,
+ 0x10e7f, 0x10eff,
+ 0x10f28, 0x10f2f,
+ 0x10f5a, 0x10fdf,
+ 0x10ff7, 0x10fff,
+ 0x1104e, 0x11051,
+ 0x11070, 0x1107e,
+ 0x110c2, 0x110cc,
+ 0x110ce, 0x110cf,
+ 0x110e9, 0x110ef,
+ 0x110fa, 0x110ff,
+ 0x11135, 0x11135,
+ 0x11147, 0x1114f,
+ 0x11177, 0x1117f,
+ 0x111ce, 0x111cf,
+ 0x111e0, 0x111e0,
+ 0x111f5, 0x111ff,
+ 0x11212, 0x11212,
+ 0x1123f, 0x1127f,
+ 0x11287, 0x11287,
+ 0x11289, 0x11289,
+ 0x1128e, 0x1128e,
+ 0x1129e, 0x1129e,
+ 0x112aa, 0x112af,
+ 0x112eb, 0x112ef,
+ 0x112fa, 0x112ff,
+ 0x11304, 0x11304,
+ 0x1130d, 0x1130e,
+ 0x11311, 0x11312,
+ 0x11329, 0x11329,
+ 0x11331, 0x11331,
+ 0x11334, 0x11334,
+ 0x1133a, 0x1133a,
+ 0x11345, 0x11346,
+ 0x11349, 0x1134a,
+ 0x1134e, 0x1134f,
+ 0x11351, 0x11356,
+ 0x11358, 0x1135c,
+ 0x11364, 0x11365,
+ 0x1136d, 0x1136f,
+ 0x11375, 0x113ff,
+ 0x1145a, 0x1145a,
+ 0x1145c, 0x1145c,
+ 0x11460, 0x1147f,
+ 0x114c8, 0x114cf,
+ 0x114da, 0x1157f,
+ 0x115b6, 0x115b7,
+ 0x115de, 0x115ff,
+ 0x11645, 0x1164f,
+ 0x1165a, 0x1165f,
+ 0x1166d, 0x1167f,
+ 0x116b9, 0x116bf,
+ 0x116ca, 0x116ff,
+ 0x1171b, 0x1171c,
+ 0x1172c, 0x1172f,
+ 0x11740, 0x117ff,
+ 0x1183c, 0x1189f,
+ 0x118f3, 0x118fe,
+ 0x11900, 0x1199f,
+ 0x119a8, 0x119a9,
+ 0x119d8, 0x119d9,
+ 0x119e5, 0x119ff,
+ 0x11a48, 0x11a4f,
+ 0x11aa3, 0x11abf,
+ 0x11af9, 0x11bff,
+ 0x11c09, 0x11c09,
+ 0x11c37, 0x11c37,
+ 0x11c46, 0x11c4f,
+ 0x11c6d, 0x11c6f,
+ 0x11c90, 0x11c91,
+ 0x11ca8, 0x11ca8,
+ 0x11cb7, 0x11cff,
+ 0x11d07, 0x11d07,
+ 0x11d0a, 0x11d0a,
+ 0x11d37, 0x11d39,
+ 0x11d3b, 0x11d3b,
+ 0x11d3e, 0x11d3e,
+ 0x11d48, 0x11d4f,
+ 0x11d5a, 0x11d5f,
+ 0x11d66, 0x11d66,
+ 0x11d69, 0x11d69,
+ 0x11d8f, 0x11d8f,
+ 0x11d92, 0x11d92,
+ 0x11d99, 0x11d9f,
+ 0x11daa, 0x11edf,
+ 0x11ef9, 0x11fbf,
+ 0x11ff2, 0x11ffe,
+ 0x1239a, 0x123ff,
+ 0x1246f, 0x1246f,
+ 0x12475, 0x1247f,
+ 0x12544, 0x12fff,
+ 0x1342f, 0x1342f,
+ 0x13439, 0x143ff,
+ 0x14647, 0x167ff,
+ 0x16a39, 0x16a3f,
+ 0x16a5f, 0x16a5f,
+ 0x16a6a, 0x16a6d,
+ 0x16a70, 0x16acf,
+ 0x16aee, 0x16aef,
+ 0x16af6, 0x16aff,
+ 0x16b46, 0x16b4f,
+ 0x16b5a, 0x16b5a,
+ 0x16b62, 0x16b62,
+ 0x16b78, 0x16b7c,
+ 0x16b90, 0x16e3f,
+ 0x16e9b, 0x16eff,
+ 0x16f4b, 0x16f4e,
+ 0x16f88, 0x16f8e,
+ 0x16fa0, 0x16fdf,
+ 0x16fe4, 0x16fff,
+ 0x187f8, 0x187ff,
+ 0x18af3, 0x1afff,
+ 0x1b11f, 0x1b14f,
+ 0x1b153, 0x1b163,
+ 0x1b168, 0x1b16f,
+ 0x1b2fc, 0x1bbff,
+ 0x1bc6b, 0x1bc6f,
+ 0x1bc7d, 0x1bc7f,
+ 0x1bc89, 0x1bc8f,
+ 0x1bc9a, 0x1bc9b,
+ 0x1bca4, 0x1cfff,
+ 0x1d0f6, 0x1d0ff,
+ 0x1d127, 0x1d128,
+ 0x1d1e9, 0x1d1ff,
+ 0x1d246, 0x1d2df,
+ 0x1d2f4, 0x1d2ff,
+ 0x1d357, 0x1d35f,
+ 0x1d379, 0x1d3ff,
+ 0x1d455, 0x1d455,
+ 0x1d49d, 0x1d49d,
+ 0x1d4a0, 0x1d4a1,
+ 0x1d4a3, 0x1d4a4,
+ 0x1d4a7, 0x1d4a8,
+ 0x1d4ad, 0x1d4ad,
+ 0x1d4ba, 0x1d4ba,
+ 0x1d4bc, 0x1d4bc,
+ 0x1d4c4, 0x1d4c4,
+ 0x1d506, 0x1d506,
+ 0x1d50b, 0x1d50c,
+ 0x1d515, 0x1d515,
+ 0x1d51d, 0x1d51d,
+ 0x1d53a, 0x1d53a,
+ 0x1d53f, 0x1d53f,
+ 0x1d545, 0x1d545,
+ 0x1d547, 0x1d549,
+ 0x1d551, 0x1d551,
+ 0x1d6a6, 0x1d6a7,
+ 0x1d7cc, 0x1d7cd,
+ 0x1da8c, 0x1da9a,
+ 0x1daa0, 0x1daa0,
+ 0x1dab0, 0x1dfff,
+ 0x1e007, 0x1e007,
+ 0x1e019, 0x1e01a,
+ 0x1e022, 0x1e022,
+ 0x1e025, 0x1e025,
+ 0x1e02b, 0x1e0ff,
+ 0x1e12d, 0x1e12f,
+ 0x1e13e, 0x1e13f,
+ 0x1e14a, 0x1e14d,
+ 0x1e150, 0x1e2bf,
+ 0x1e2fa, 0x1e2fe,
+ 0x1e300, 0x1e7ff,
+ 0x1e8c5, 0x1e8c6,
+ 0x1e8d7, 0x1e8ff,
+ 0x1e94c, 0x1e94f,
+ 0x1e95a, 0x1e95d,
+ 0x1e960, 0x1ec70,
+ 0x1ecb5, 0x1ed00,
+ 0x1ed3e, 0x1edff,
+ 0x1ee04, 0x1ee04,
+ 0x1ee20, 0x1ee20,
+ 0x1ee23, 0x1ee23,
+ 0x1ee25, 0x1ee26,
+ 0x1ee28, 0x1ee28,
+ 0x1ee33, 0x1ee33,
+ 0x1ee38, 0x1ee38,
+ 0x1ee3a, 0x1ee3a,
+ 0x1ee3c, 0x1ee41,
+ 0x1ee43, 0x1ee46,
+ 0x1ee48, 0x1ee48,
+ 0x1ee4a, 0x1ee4a,
+ 0x1ee4c, 0x1ee4c,
+ 0x1ee50, 0x1ee50,
+ 0x1ee53, 0x1ee53,
+ 0x1ee55, 0x1ee56,
+ 0x1ee58, 0x1ee58,
+ 0x1ee5a, 0x1ee5a,
+ 0x1ee5c, 0x1ee5c,
+ 0x1ee5e, 0x1ee5e,
+ 0x1ee60, 0x1ee60,
+ 0x1ee63, 0x1ee63,
+ 0x1ee65, 0x1ee66,
+ 0x1ee6b, 0x1ee6b,
+ 0x1ee73, 0x1ee73,
+ 0x1ee78, 0x1ee78,
+ 0x1ee7d, 0x1ee7d,
+ 0x1ee7f, 0x1ee7f,
+ 0x1ee8a, 0x1ee8a,
+ 0x1ee9c, 0x1eea0,
+ 0x1eea4, 0x1eea4,
+ 0x1eeaa, 0x1eeaa,
+ 0x1eebc, 0x1eeef,
+ 0x1eef2, 0x1efff,
+ 0x1f02c, 0x1f02f,
+ 0x1f094, 0x1f09f,
+ 0x1f0af, 0x1f0b0,
+ 0x1f0c0, 0x1f0c0,
+ 0x1f0d0, 0x1f0d0,
+ 0x1f0f6, 0x1f0ff,
+ 0x1f10d, 0x1f10f,
+ 0x1f16d, 0x1f16f,
+ 0x1f1ad, 0x1f1e5,
+ 0x1f203, 0x1f20f,
+ 0x1f23c, 0x1f23f,
+ 0x1f249, 0x1f24f,
+ 0x1f252, 0x1f25f,
+ 0x1f266, 0x1f2ff,
+ 0x1f6d6, 0x1f6df,
+ 0x1f6ed, 0x1f6ef,
+ 0x1f6fb, 0x1f6ff,
+ 0x1f774, 0x1f77f,
+ 0x1f7d9, 0x1f7df,
+ 0x1f7ec, 0x1f7ff,
+ 0x1f80c, 0x1f80f,
+ 0x1f848, 0x1f84f,
+ 0x1f85a, 0x1f85f,
+ 0x1f888, 0x1f88f,
+ 0x1f8ae, 0x1f8ff,
+ 0x1f90c, 0x1f90c,
+ 0x1f972, 0x1f972,
+ 0x1f977, 0x1f979,
+ 0x1f9a3, 0x1f9a4,
+ 0x1f9ab, 0x1f9ad,
+ 0x1f9cb, 0x1f9cc,
+ 0x1fa54, 0x1fa5f,
+ 0x1fa6e, 0x1fa6f,
+ 0x1fa74, 0x1fa77,
+ 0x1fa7b, 0x1fa7f,
+ 0x1fa83, 0x1fa8f,
+ 0x1fa96, 0x1ffff,
+ 0x2a6d7, 0x2a6ff,
+ 0x2b735, 0x2b73f,
+ 0x2b81e, 0x2b81f,
+ 0x2cea2, 0x2ceaf,
+ 0x2ebe1, 0x2f7ff,
+ 0x2fa1e, 0xe0000,
+ 0xe0002, 0xe001f,
+ 0xe0080, 0xe00ff,
+ 0xe01f0, 0x10ffff,
+}; /* CR_Unknown */
+
+#ifdef USE_UNICODE_AGE_PROPERTIES
+/* 'Age_1_1': Derived Age 1.1 */
+static const OnigCodePoint CR_Age_1_1[] = {
+ 288,
+ 0x0000, 0x01f5,
+ 0x01fa, 0x0217,
+ 0x0250, 0x02a8,
+ 0x02b0, 0x02de,
+ 0x02e0, 0x02e9,
+ 0x0300, 0x0345,
+ 0x0360, 0x0361,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03d6,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03f3,
+ 0x0401, 0x040c,
+ 0x040e, 0x044f,
+ 0x0451, 0x045c,
+ 0x045e, 0x0486,
+ 0x0490, 0x04c4,
+ 0x04c7, 0x04c8,
+ 0x04cb, 0x04cc,
+ 0x04d0, 0x04eb,
+ 0x04ee, 0x04f5,
+ 0x04f8, 0x04f9,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x0589,
+ 0x05b0, 0x05b9,
+ 0x05bb, 0x05c3,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x0652,
+ 0x0660, 0x066d,
+ 0x0670, 0x06b7,
+ 0x06ba, 0x06be,
+ 0x06c0, 0x06ce,
+ 0x06d0, 0x06ed,
+ 0x06f0, 0x06f9,
+ 0x0901, 0x0903,
+ 0x0905, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a02, 0x0a02,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8b,
+ 0x0a8d, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae0,
+ 0x0ae6, 0x0aef,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b36, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b70,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb5,
+ 0x0bb7, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be7, 0x0bf2,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10f6,
+ 0x10fb, 0x10fb,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1e00, 0x1e9a,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x202e,
+ 0x2030, 0x2046,
+ 0x206a, 0x2070,
+ 0x2074, 0x208e,
+ 0x20a0, 0x20aa,
+ 0x20d0, 0x20e1,
+ 0x2100, 0x2138,
+ 0x2153, 0x2182,
+ 0x2190, 0x21ea,
+ 0x2200, 0x22f1,
+ 0x2300, 0x2300,
+ 0x2302, 0x237a,
+ 0x2400, 0x2424,
+ 0x2440, 0x244a,
+ 0x2460, 0x24ea,
+ 0x2500, 0x2595,
+ 0x25a0, 0x25ef,
+ 0x2600, 0x2613,
+ 0x261a, 0x266f,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2767,
+ 0x2776, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x3000, 0x3037,
+ 0x303f, 0x303f,
+ 0x3041, 0x3094,
+ 0x3099, 0x309e,
+ 0x30a1, 0x30fe,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x319f,
+ 0x3200, 0x321c,
+ 0x3220, 0x3243,
+ 0x3260, 0x327b,
+ 0x327f, 0x32b0,
+ 0x32c0, 0x32cb,
+ 0x32d0, 0x32fe,
+ 0x3300, 0x3376,
+ 0x337b, 0x33dd,
+ 0x33e0, 0x33fe,
+ 0x4e00, 0x9fa5,
+ 0xe000, 0xfa2d,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1e, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe44,
+ 0xfe49, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe72,
+ 0xfe74, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xff5e,
+ 0xff61, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfffd, 0xffff,
+}; /* CR_Age_1_1 */
+
+/* 'Age_2_0': Derived Age 2.0 */
+static const OnigCodePoint CR_Age_2_0[] = {
+ 312,
+ 0x0000, 0x01f5,
+ 0x01fa, 0x0217,
+ 0x0250, 0x02a8,
+ 0x02b0, 0x02de,
+ 0x02e0, 0x02e9,
+ 0x0300, 0x0345,
+ 0x0360, 0x0361,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03d6,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03f3,
+ 0x0401, 0x040c,
+ 0x040e, 0x044f,
+ 0x0451, 0x045c,
+ 0x045e, 0x0486,
+ 0x0490, 0x04c4,
+ 0x04c7, 0x04c8,
+ 0x04cb, 0x04cc,
+ 0x04d0, 0x04eb,
+ 0x04ee, 0x04f5,
+ 0x04f8, 0x04f9,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x0589,
+ 0x0591, 0x05a1,
+ 0x05a3, 0x05b9,
+ 0x05bb, 0x05c4,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x0652,
+ 0x0660, 0x066d,
+ 0x0670, 0x06b7,
+ 0x06ba, 0x06be,
+ 0x06c0, 0x06ce,
+ 0x06d0, 0x06ed,
+ 0x06f0, 0x06f9,
+ 0x0901, 0x0903,
+ 0x0905, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a02, 0x0a02,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8b,
+ 0x0a8d, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae0,
+ 0x0ae6, 0x0aef,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b36, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b70,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb5,
+ 0x0bb7, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be7, 0x0bf2,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f69,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f95,
+ 0x0f97, 0x0f97,
+ 0x0f99, 0x0fad,
+ 0x0fb1, 0x0fb7,
+ 0x0fb9, 0x0fb9,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10f6,
+ 0x10fb, 0x10fb,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x202e,
+ 0x2030, 0x2046,
+ 0x206a, 0x2070,
+ 0x2074, 0x208e,
+ 0x20a0, 0x20ab,
+ 0x20d0, 0x20e1,
+ 0x2100, 0x2138,
+ 0x2153, 0x2182,
+ 0x2190, 0x21ea,
+ 0x2200, 0x22f1,
+ 0x2300, 0x2300,
+ 0x2302, 0x237a,
+ 0x2400, 0x2424,
+ 0x2440, 0x244a,
+ 0x2460, 0x24ea,
+ 0x2500, 0x2595,
+ 0x25a0, 0x25ef,
+ 0x2600, 0x2613,
+ 0x261a, 0x266f,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2767,
+ 0x2776, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x3000, 0x3037,
+ 0x303f, 0x303f,
+ 0x3041, 0x3094,
+ 0x3099, 0x309e,
+ 0x30a1, 0x30fe,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x319f,
+ 0x3200, 0x321c,
+ 0x3220, 0x3243,
+ 0x3260, 0x327b,
+ 0x327f, 0x32b0,
+ 0x32c0, 0x32cb,
+ 0x32d0, 0x32fe,
+ 0x3300, 0x3376,
+ 0x337b, 0x33dd,
+ 0x33e0, 0x33fe,
+ 0x4e00, 0x9fa5,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1e, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe44,
+ 0xfe49, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe72,
+ 0xfe74, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xff5e,
+ 0xff61, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfffd, 0xffff,
+ 0x1fffe, 0x1ffff,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_2_0 */
+
+/* 'Age_2_1': Derived Age 2.1 */
+static const OnigCodePoint CR_Age_2_1[] = {
+ 312,
+ 0x0000, 0x01f5,
+ 0x01fa, 0x0217,
+ 0x0250, 0x02a8,
+ 0x02b0, 0x02de,
+ 0x02e0, 0x02e9,
+ 0x0300, 0x0345,
+ 0x0360, 0x0361,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03d6,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03f3,
+ 0x0401, 0x040c,
+ 0x040e, 0x044f,
+ 0x0451, 0x045c,
+ 0x045e, 0x0486,
+ 0x0490, 0x04c4,
+ 0x04c7, 0x04c8,
+ 0x04cb, 0x04cc,
+ 0x04d0, 0x04eb,
+ 0x04ee, 0x04f5,
+ 0x04f8, 0x04f9,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x0589,
+ 0x0591, 0x05a1,
+ 0x05a3, 0x05b9,
+ 0x05bb, 0x05c4,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x0652,
+ 0x0660, 0x066d,
+ 0x0670, 0x06b7,
+ 0x06ba, 0x06be,
+ 0x06c0, 0x06ce,
+ 0x06d0, 0x06ed,
+ 0x06f0, 0x06f9,
+ 0x0901, 0x0903,
+ 0x0905, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a02, 0x0a02,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8b,
+ 0x0a8d, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae0,
+ 0x0ae6, 0x0aef,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b36, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b70,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb5,
+ 0x0bb7, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be7, 0x0bf2,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f69,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f95,
+ 0x0f97, 0x0f97,
+ 0x0f99, 0x0fad,
+ 0x0fb1, 0x0fb7,
+ 0x0fb9, 0x0fb9,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10f6,
+ 0x10fb, 0x10fb,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x202e,
+ 0x2030, 0x2046,
+ 0x206a, 0x2070,
+ 0x2074, 0x208e,
+ 0x20a0, 0x20ac,
+ 0x20d0, 0x20e1,
+ 0x2100, 0x2138,
+ 0x2153, 0x2182,
+ 0x2190, 0x21ea,
+ 0x2200, 0x22f1,
+ 0x2300, 0x2300,
+ 0x2302, 0x237a,
+ 0x2400, 0x2424,
+ 0x2440, 0x244a,
+ 0x2460, 0x24ea,
+ 0x2500, 0x2595,
+ 0x25a0, 0x25ef,
+ 0x2600, 0x2613,
+ 0x261a, 0x266f,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2767,
+ 0x2776, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x3000, 0x3037,
+ 0x303f, 0x303f,
+ 0x3041, 0x3094,
+ 0x3099, 0x309e,
+ 0x30a1, 0x30fe,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x319f,
+ 0x3200, 0x321c,
+ 0x3220, 0x3243,
+ 0x3260, 0x327b,
+ 0x327f, 0x32b0,
+ 0x32c0, 0x32cb,
+ 0x32d0, 0x32fe,
+ 0x3300, 0x3376,
+ 0x337b, 0x33dd,
+ 0x33e0, 0x33fe,
+ 0x4e00, 0x9fa5,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1e, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe44,
+ 0xfe49, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe72,
+ 0xfe74, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xff5e,
+ 0xff61, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfffc, 0xffff,
+ 0x1fffe, 0x1ffff,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_2_1 */
+
+/* 'Age_3_0': Derived Age 3.0 */
+static const OnigCodePoint CR_Age_3_0[] = {
+ 369,
+ 0x0000, 0x021f,
+ 0x0222, 0x0233,
+ 0x0250, 0x02ad,
+ 0x02b0, 0x02ee,
+ 0x0300, 0x034e,
+ 0x0360, 0x0362,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03d7,
+ 0x03da, 0x03f3,
+ 0x0400, 0x0486,
+ 0x0488, 0x0489,
+ 0x048c, 0x04c4,
+ 0x04c7, 0x04c8,
+ 0x04cb, 0x04cc,
+ 0x04d0, 0x04f5,
+ 0x04f8, 0x04f9,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05a1,
+ 0x05a3, 0x05b9,
+ 0x05bb, 0x05c4,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x0655,
+ 0x0660, 0x066d,
+ 0x0670, 0x06ed,
+ 0x06f0, 0x06fe,
+ 0x0700, 0x070d,
+ 0x070f, 0x072c,
+ 0x0730, 0x074a,
+ 0x0780, 0x07b0,
+ 0x0901, 0x0903,
+ 0x0905, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a02, 0x0a02,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8b,
+ 0x0a8d, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae0,
+ 0x0ae6, 0x0aef,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b36, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b70,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb5,
+ 0x0bb7, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be7, 0x0bf2,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fcf,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10f6,
+ 0x10fb, 0x10fb,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1206,
+ 0x1208, 0x1246,
+ 0x1248, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1286,
+ 0x1288, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12ae,
+ 0x12b0, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12ce,
+ 0x12d0, 0x12d6,
+ 0x12d8, 0x12ee,
+ 0x12f0, 0x130e,
+ 0x1310, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x131e,
+ 0x1320, 0x1346,
+ 0x1348, 0x135a,
+ 0x1361, 0x137c,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1780, 0x17dc,
+ 0x17e0, 0x17e9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2046,
+ 0x2048, 0x204d,
+ 0x206a, 0x2070,
+ 0x2074, 0x208e,
+ 0x20a0, 0x20af,
+ 0x20d0, 0x20e3,
+ 0x2100, 0x213a,
+ 0x2153, 0x2183,
+ 0x2190, 0x21f3,
+ 0x2200, 0x22f1,
+ 0x2300, 0x237b,
+ 0x237d, 0x239a,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x24ea,
+ 0x2500, 0x2595,
+ 0x25a0, 0x25f7,
+ 0x2600, 0x2613,
+ 0x2619, 0x2671,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2767,
+ 0x2776, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x2800, 0x28ff,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303a,
+ 0x303e, 0x303f,
+ 0x3041, 0x3094,
+ 0x3099, 0x309e,
+ 0x30a1, 0x30fe,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x3200, 0x321c,
+ 0x3220, 0x3243,
+ 0x3260, 0x327b,
+ 0x327f, 0x32b0,
+ 0x32c0, 0x32cb,
+ 0x32d0, 0x32fe,
+ 0x3300, 0x3376,
+ 0x337b, 0x33dd,
+ 0x33e0, 0x33fe,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fa5,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4a1,
+ 0xa4a4, 0xa4b3,
+ 0xa4b5, 0xa4c0,
+ 0xa4c2, 0xa4c4,
+ 0xa4c6, 0xa4c6,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe44,
+ 0xfe49, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe72,
+ 0xfe74, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xff5e,
+ 0xff61, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xffff,
+ 0x1fffe, 0x1ffff,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_3_0 */
+
+/* 'Age_3_1': Derived Age 3.1 */
+static const OnigCodePoint CR_Age_3_1[] = {
+ 402,
+ 0x0000, 0x021f,
+ 0x0222, 0x0233,
+ 0x0250, 0x02ad,
+ 0x02b0, 0x02ee,
+ 0x0300, 0x034e,
+ 0x0360, 0x0362,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03d7,
+ 0x03da, 0x03f5,
+ 0x0400, 0x0486,
+ 0x0488, 0x0489,
+ 0x048c, 0x04c4,
+ 0x04c7, 0x04c8,
+ 0x04cb, 0x04cc,
+ 0x04d0, 0x04f5,
+ 0x04f8, 0x04f9,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05a1,
+ 0x05a3, 0x05b9,
+ 0x05bb, 0x05c4,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x0655,
+ 0x0660, 0x066d,
+ 0x0670, 0x06ed,
+ 0x06f0, 0x06fe,
+ 0x0700, 0x070d,
+ 0x070f, 0x072c,
+ 0x0730, 0x074a,
+ 0x0780, 0x07b0,
+ 0x0901, 0x0903,
+ 0x0905, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a02, 0x0a02,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8b,
+ 0x0a8d, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae0,
+ 0x0ae6, 0x0aef,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b36, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b70,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb5,
+ 0x0bb7, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be7, 0x0bf2,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fcf,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10f6,
+ 0x10fb, 0x10fb,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1206,
+ 0x1208, 0x1246,
+ 0x1248, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1286,
+ 0x1288, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12ae,
+ 0x12b0, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12ce,
+ 0x12d0, 0x12d6,
+ 0x12d8, 0x12ee,
+ 0x12f0, 0x130e,
+ 0x1310, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x131e,
+ 0x1320, 0x1346,
+ 0x1348, 0x135a,
+ 0x1361, 0x137c,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1780, 0x17dc,
+ 0x17e0, 0x17e9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2046,
+ 0x2048, 0x204d,
+ 0x206a, 0x2070,
+ 0x2074, 0x208e,
+ 0x20a0, 0x20af,
+ 0x20d0, 0x20e3,
+ 0x2100, 0x213a,
+ 0x2153, 0x2183,
+ 0x2190, 0x21f3,
+ 0x2200, 0x22f1,
+ 0x2300, 0x237b,
+ 0x237d, 0x239a,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x24ea,
+ 0x2500, 0x2595,
+ 0x25a0, 0x25f7,
+ 0x2600, 0x2613,
+ 0x2619, 0x2671,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2767,
+ 0x2776, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x2800, 0x28ff,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303a,
+ 0x303e, 0x303f,
+ 0x3041, 0x3094,
+ 0x3099, 0x309e,
+ 0x30a1, 0x30fe,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x3200, 0x321c,
+ 0x3220, 0x3243,
+ 0x3260, 0x327b,
+ 0x327f, 0x32b0,
+ 0x32c0, 0x32cb,
+ 0x32d0, 0x32fe,
+ 0x3300, 0x3376,
+ 0x337b, 0x33dd,
+ 0x33e0, 0x33fe,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fa5,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4a1,
+ 0xa4a4, 0xa4b3,
+ 0xa4b5, 0xa4c0,
+ 0xa4c2, 0xa4c4,
+ 0xa4c6, 0xa4c6,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfb,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe44,
+ 0xfe49, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe72,
+ 0xfe74, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xff5e,
+ 0xff61, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xffff,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10400, 0x10425,
+ 0x10428, 0x1044d,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d1dd,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c0,
+ 0x1d4c2, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a3,
+ 0x1d6a8, 0x1d7c9,
+ 0x1d7ce, 0x1d7ff,
+ 0x1fffe, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_3_1 */
+
+/* 'Age_3_2': Derived Age 3.2 */
+static const OnigCodePoint CR_Age_3_2[] = {
+ 397,
+ 0x0000, 0x0220,
+ 0x0222, 0x0233,
+ 0x0250, 0x02ad,
+ 0x02b0, 0x02ee,
+ 0x0300, 0x034f,
+ 0x0360, 0x036f,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03f6,
+ 0x0400, 0x0486,
+ 0x0488, 0x04ce,
+ 0x04d0, 0x04f5,
+ 0x04f8, 0x04f9,
+ 0x0500, 0x050f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05a1,
+ 0x05a3, 0x05b9,
+ 0x05bb, 0x05c4,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x0655,
+ 0x0660, 0x06ed,
+ 0x06f0, 0x06fe,
+ 0x0700, 0x070d,
+ 0x070f, 0x072c,
+ 0x0730, 0x074a,
+ 0x0780, 0x07b1,
+ 0x0901, 0x0903,
+ 0x0905, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a02, 0x0a02,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8b,
+ 0x0a8d, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae0,
+ 0x0ae6, 0x0aef,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b36, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b70,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb5,
+ 0x0bb7, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be7, 0x0bf2,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fcf,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10f8,
+ 0x10fb, 0x10fb,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1206,
+ 0x1208, 0x1246,
+ 0x1248, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1286,
+ 0x1288, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12ae,
+ 0x12b0, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12ce,
+ 0x12d0, 0x12d6,
+ 0x12d8, 0x12ee,
+ 0x12f0, 0x130e,
+ 0x1310, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x131e,
+ 0x1320, 0x1346,
+ 0x1348, 0x135a,
+ 0x1361, 0x137c,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dc,
+ 0x17e0, 0x17e9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2052,
+ 0x2057, 0x2057,
+ 0x205f, 0x2063,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x20a0, 0x20b1,
+ 0x20d0, 0x20ea,
+ 0x2100, 0x213a,
+ 0x213d, 0x214b,
+ 0x2153, 0x2183,
+ 0x2190, 0x23ce,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x24fe,
+ 0x2500, 0x2613,
+ 0x2616, 0x2617,
+ 0x2619, 0x267d,
+ 0x2680, 0x2689,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27d0, 0x27eb,
+ 0x27f0, 0x2aff,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x31f0, 0x321c,
+ 0x3220, 0x3243,
+ 0x3251, 0x327b,
+ 0x327f, 0x32cb,
+ 0x32d0, 0x32fe,
+ 0x3300, 0x3376,
+ 0x337b, 0x33dd,
+ 0x33e0, 0x33fe,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fa5,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfc,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe46,
+ 0xfe49, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xffff,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10400, 0x10425,
+ 0x10428, 0x1044d,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d1dd,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c0,
+ 0x1d4c2, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a3,
+ 0x1d6a8, 0x1d7c9,
+ 0x1d7ce, 0x1d7ff,
+ 0x1fffe, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_3_2 */
+
+/* 'Age_4_0': Derived Age 4.0 */
+static const OnigCodePoint CR_Age_4_0[] = {
+ 412,
+ 0x0000, 0x0236,
+ 0x0250, 0x0357,
+ 0x035d, 0x036f,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03fb,
+ 0x0400, 0x0486,
+ 0x0488, 0x04ce,
+ 0x04d0, 0x04f5,
+ 0x04f8, 0x04f9,
+ 0x0500, 0x050f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05a1,
+ 0x05a3, 0x05b9,
+ 0x05bb, 0x05c4,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0603,
+ 0x060c, 0x0615,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x0658,
+ 0x0660, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x074f,
+ 0x0780, 0x07b1,
+ 0x0901, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb5,
+ 0x0bb7, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be7, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fcf,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10f8,
+ 0x10fb, 0x10fb,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1206,
+ 0x1208, 0x1246,
+ 0x1248, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1286,
+ 0x1288, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12ae,
+ 0x12b0, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12ce,
+ 0x12d0, 0x12d6,
+ 0x12d8, 0x12ee,
+ 0x12f0, 0x130e,
+ 0x1310, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x131e,
+ 0x1320, 0x1346,
+ 0x1348, 0x135a,
+ 0x1361, 0x137c,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x19e0, 0x19ff,
+ 0x1d00, 0x1d6b,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2054,
+ 0x2057, 0x2057,
+ 0x205f, 0x2063,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x20a0, 0x20b1,
+ 0x20d0, 0x20ea,
+ 0x2100, 0x213b,
+ 0x213d, 0x214b,
+ 0x2153, 0x2183,
+ 0x2190, 0x23d0,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2617,
+ 0x2619, 0x267d,
+ 0x2680, 0x2691,
+ 0x26a0, 0x26a1,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27d0, 0x27eb,
+ 0x27f0, 0x2b0d,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x31f0, 0x321e,
+ 0x3220, 0x3243,
+ 0x3250, 0x327d,
+ 0x327f, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fa5,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1013f,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x1039f,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d1dd,
+ 0x1d300, 0x1d356,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a3,
+ 0x1d6a8, 0x1d7c9,
+ 0x1d7ce, 0x1d7ff,
+ 0x1fffe, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_4_0 */
+
+/* 'Age_4_1': Derived Age 4.1 */
+static const OnigCodePoint CR_Age_4_1[] = {
+ 430,
+ 0x0000, 0x0241,
+ 0x0250, 0x036f,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x0486,
+ 0x0488, 0x04ce,
+ 0x04d0, 0x04f9,
+ 0x0500, 0x050f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0603,
+ 0x060b, 0x0615,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x065e,
+ 0x0660, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x076d,
+ 0x0780, 0x07b1,
+ 0x0901, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x097d, 0x097d,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fd1,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10fc,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a1f,
+ 0x1d00, 0x1dc3,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2063,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x2094,
+ 0x20a0, 0x20b5,
+ 0x20d0, 0x20eb,
+ 0x2100, 0x214c,
+ 0x2153, 0x2183,
+ 0x2190, 0x23db,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x269c,
+ 0x26a0, 0x26b1,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27c0, 0x27c6,
+ 0x27d0, 0x27eb,
+ 0x27f0, 0x2b13,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2cea,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x31c0, 0x31cf,
+ 0x31f0, 0x321e,
+ 0x3220, 0x3243,
+ 0x3250, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fbb,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa700, 0xa716,
+ 0xa800, 0xa82b,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7c9,
+ 0x1d7ce, 0x1d7ff,
+ 0x1fffe, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_4_1 */
+
+/* 'Age_5_0': Derived Age 5.0 */
+static const OnigCodePoint CR_Age_5_0[] = {
+ 440,
+ 0x0000, 0x036f,
+ 0x0374, 0x0375,
+ 0x037a, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x0486,
+ 0x0488, 0x0513,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0603,
+ 0x060b, 0x0615,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x065e,
+ 0x0660, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x076d,
+ 0x0780, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0901, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x097b, 0x097f,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fd1,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10fc,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a1f,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1d00, 0x1dca,
+ 0x1dfe, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2063,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x2094,
+ 0x20a0, 0x20b5,
+ 0x20d0, 0x20ef,
+ 0x2100, 0x214e,
+ 0x2153, 0x2184,
+ 0x2190, 0x23e7,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x269c,
+ 0x26a0, 0x26b2,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27c0, 0x27ca,
+ 0x27d0, 0x27eb,
+ 0x27f0, 0x2b1a,
+ 0x2b20, 0x2b23,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2c6c,
+ 0x2c74, 0x2c77,
+ 0x2c80, 0x2cea,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x31c0, 0x31cf,
+ 0x31f0, 0x321e,
+ 0x3220, 0x3243,
+ 0x3250, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fbb,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa700, 0xa71a,
+ 0xa720, 0xa721,
+ 0xa800, 0xa82b,
+ 0xa840, 0xa877,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x10900, 0x10919,
+ 0x1091f, 0x1091f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x12000, 0x1236e,
+ 0x12400, 0x12462,
+ 0x12470, 0x12473,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1fffe, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_5_0 */
+
+/* 'Age_5_1': Derived Age 5.1 */
+static const OnigCodePoint CR_Age_5_1[] = {
+ 455,
+ 0x0000, 0x0377,
+ 0x037a, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x0523,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0603,
+ 0x0606, 0x061b,
+ 0x061e, 0x061f,
+ 0x0621, 0x065e,
+ 0x0660, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0901, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0972,
+ 0x097b, 0x097f,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fd4,
+ 0x1000, 0x1099,
+ 0x109e, 0x10c5,
+ 0x10d0, 0x10fc,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a1f,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1baa,
+ 0x1bae, 0x1bb9,
+ 0x1c00, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1d00, 0x1de6,
+ 0x1dfe, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x2094,
+ 0x20a0, 0x20b5,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x214f,
+ 0x2153, 0x2188,
+ 0x2190, 0x23e7,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x269d,
+ 0x26a0, 0x26bc,
+ 0x26c0, 0x26c3,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27c0, 0x27ca,
+ 0x27cc, 0x27cc,
+ 0x27d0, 0x2b4c,
+ 0x2b50, 0x2b54,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2c6f,
+ 0x2c71, 0x2c7d,
+ 0x2c80, 0x2cea,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e30,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x3243,
+ 0x3250, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fc3,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa500, 0xa62b,
+ 0xa640, 0xa65f,
+ 0xa662, 0xa673,
+ 0xa67c, 0xa697,
+ 0xa700, 0xa78c,
+ 0xa7fb, 0xa82b,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa95f,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa5f,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe26,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10190, 0x1019b,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x10900, 0x10919,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x12000, 0x1236e,
+ 0x12400, 0x12462,
+ 0x12470, 0x12473,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1fffe, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_5_1 */
+
+/* 'Age_5_2': Derived Age 5.2 */
+static const OnigCodePoint CR_Age_5_2[] = {
+ 495,
+ 0x0000, 0x0377,
+ 0x037a, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x0525,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0603,
+ 0x0606, 0x061b,
+ 0x061e, 0x061f,
+ 0x0621, 0x065e,
+ 0x0660, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0900, 0x0939,
+ 0x093c, 0x094e,
+ 0x0950, 0x0955,
+ 0x0958, 0x0972,
+ 0x0979, 0x097f,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fd8,
+ 0x1000, 0x10c5,
+ 0x10d0, 0x10fc,
+ 0x1100, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1baa,
+ 0x1bae, 0x1bb9,
+ 0x1c00, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cd0, 0x1cf2,
+ 0x1d00, 0x1de6,
+ 0x1dfd, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x2094,
+ 0x20a0, 0x20b8,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x2189,
+ 0x2190, 0x23e8,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x26cd,
+ 0x26cf, 0x26e1,
+ 0x26e3, 0x26e3,
+ 0x26e8, 0x26ff,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27c0, 0x27ca,
+ 0x27cc, 0x27cc,
+ 0x27d0, 0x2b4c,
+ 0x2b50, 0x2b59,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf1,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e31,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fcb,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa65f,
+ 0xa662, 0xa673,
+ 0xa67c, 0xa697,
+ 0xa6a0, 0xa6f7,
+ 0xa700, 0xa78c,
+ 0xa7fb, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fb,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9df,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa7b,
+ 0xaa80, 0xaac2,
+ 0xaadb, 0xaadf,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe26,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10190, 0x1019b,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1085f,
+ 0x10900, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a7f,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b7f,
+ 0x10c00, 0x10c48,
+ 0x10e60, 0x10e7e,
+ 0x11080, 0x110c1,
+ 0x12000, 0x1236e,
+ 0x12400, 0x12462,
+ 0x12470, 0x12473,
+ 0x13000, 0x1342e,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f100, 0x1f10a,
+ 0x1f110, 0x1f12e,
+ 0x1f131, 0x1f131,
+ 0x1f13d, 0x1f13d,
+ 0x1f13f, 0x1f13f,
+ 0x1f142, 0x1f142,
+ 0x1f146, 0x1f146,
+ 0x1f14a, 0x1f14e,
+ 0x1f157, 0x1f157,
+ 0x1f15f, 0x1f15f,
+ 0x1f179, 0x1f179,
+ 0x1f17b, 0x1f17c,
+ 0x1f17f, 0x1f17f,
+ 0x1f18a, 0x1f18d,
+ 0x1f190, 0x1f190,
+ 0x1f200, 0x1f200,
+ 0x1f210, 0x1f231,
+ 0x1f240, 0x1f248,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_5_2 */
+
+/* 'Age_6_0': Derived Age 6.0 */
+static const OnigCodePoint CR_Age_6_0[] = {
+ 511,
+ 0x0000, 0x0377,
+ 0x037a, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x0527,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0603,
+ 0x0606, 0x061b,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0900, 0x0977,
+ 0x0979, 0x097f,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10d0, 0x10fc,
+ 0x1100, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1baa,
+ 0x1bae, 0x1bb9,
+ 0x1bc0, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cd0, 0x1cf2,
+ 0x1d00, 0x1de6,
+ 0x1dfc, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20b9,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x2189,
+ 0x2190, 0x23f3,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x26ff,
+ 0x2701, 0x27ca,
+ 0x27cc, 0x27cc,
+ 0x27ce, 0x2b4c,
+ 0x2b50, 0x2b59,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf1,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e31,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fcb,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa673,
+ 0xa67c, 0xa697,
+ 0xa6a0, 0xa6f7,
+ 0xa700, 0xa78e,
+ 0xa790, 0xa791,
+ 0xa7a0, 0xa7a9,
+ 0xa7fa, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fb,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9df,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa7b,
+ 0xaa80, 0xaac2,
+ 0xaadb, 0xaadf,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe26,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10190, 0x1019b,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1085f,
+ 0x10900, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a7f,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b7f,
+ 0x10c00, 0x10c48,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x11080, 0x110c1,
+ 0x12000, 0x1236e,
+ 0x12400, 0x12462,
+ 0x12470, 0x12473,
+ 0x13000, 0x1342e,
+ 0x16800, 0x16a38,
+ 0x1b000, 0x1b001,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0be,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0df,
+ 0x1f100, 0x1f10a,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f169,
+ 0x1f170, 0x1f19a,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23a,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f320,
+ 0x1f330, 0x1f335,
+ 0x1f337, 0x1f37c,
+ 0x1f380, 0x1f393,
+ 0x1f3a0, 0x1f3c4,
+ 0x1f3c6, 0x1f3ca,
+ 0x1f3e0, 0x1f3f0,
+ 0x1f400, 0x1f43e,
+ 0x1f440, 0x1f440,
+ 0x1f442, 0x1f4f7,
+ 0x1f4f9, 0x1f4fc,
+ 0x1f500, 0x1f53d,
+ 0x1f550, 0x1f567,
+ 0x1f5fb, 0x1f5ff,
+ 0x1f601, 0x1f610,
+ 0x1f612, 0x1f614,
+ 0x1f616, 0x1f616,
+ 0x1f618, 0x1f618,
+ 0x1f61a, 0x1f61a,
+ 0x1f61c, 0x1f61e,
+ 0x1f620, 0x1f625,
+ 0x1f628, 0x1f62b,
+ 0x1f62d, 0x1f62d,
+ 0x1f630, 0x1f633,
+ 0x1f635, 0x1f640,
+ 0x1f645, 0x1f64f,
+ 0x1f680, 0x1f6c5,
+ 0x1f700, 0x1f773,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_6_0 */
+
+/* 'Age_6_1': Derived Age 6.1 */
+static const OnigCodePoint CR_Age_6_1[] = {
+ 549,
+ 0x0000, 0x0377,
+ 0x037a, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x0527,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x058f, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0604,
+ 0x0606, 0x061b,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x08a0, 0x08a0,
+ 0x08a2, 0x08ac,
+ 0x08e4, 0x08fe,
+ 0x0900, 0x0977,
+ 0x0979, 0x097f,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd0, 0x1cf6,
+ 0x1d00, 0x1de6,
+ 0x1dfc, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20b9,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x2189,
+ 0x2190, 0x23f3,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x26ff,
+ 0x2701, 0x2b4c,
+ 0x2b50, 0x2b59,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e3b,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fcc,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa697,
+ 0xa69f, 0xa6f7,
+ 0xa700, 0xa78e,
+ 0xa790, 0xa793,
+ 0xa7a0, 0xa7aa,
+ 0xa7f8, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fb,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9df,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa7b,
+ 0xaa80, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe26,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10190, 0x1019b,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1085f,
+ 0x10900, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a7f,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b7f,
+ 0x10c00, 0x10c48,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x11080, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11143,
+ 0x11180, 0x111c8,
+ 0x111d0, 0x111d9,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x12000, 0x1236e,
+ 0x12400, 0x12462,
+ 0x12470, 0x12473,
+ 0x13000, 0x1342e,
+ 0x16800, 0x16a38,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x1b000, 0x1b001,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0be,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0df,
+ 0x1f100, 0x1f10a,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f16b,
+ 0x1f170, 0x1f19a,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23a,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f320,
+ 0x1f330, 0x1f335,
+ 0x1f337, 0x1f37c,
+ 0x1f380, 0x1f393,
+ 0x1f3a0, 0x1f3c4,
+ 0x1f3c6, 0x1f3ca,
+ 0x1f3e0, 0x1f3f0,
+ 0x1f400, 0x1f43e,
+ 0x1f440, 0x1f440,
+ 0x1f442, 0x1f4f7,
+ 0x1f4f9, 0x1f4fc,
+ 0x1f500, 0x1f53d,
+ 0x1f540, 0x1f543,
+ 0x1f550, 0x1f567,
+ 0x1f5fb, 0x1f640,
+ 0x1f645, 0x1f64f,
+ 0x1f680, 0x1f6c5,
+ 0x1f700, 0x1f773,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_6_1 */
+
+/* 'Age_6_2': Derived Age 6.2 */
+static const OnigCodePoint CR_Age_6_2[] = {
+ 549,
+ 0x0000, 0x0377,
+ 0x037a, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x0527,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x058f, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0604,
+ 0x0606, 0x061b,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x08a0, 0x08a0,
+ 0x08a2, 0x08ac,
+ 0x08e4, 0x08fe,
+ 0x0900, 0x0977,
+ 0x0979, 0x097f,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd0, 0x1cf6,
+ 0x1d00, 0x1de6,
+ 0x1dfc, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20ba,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x2189,
+ 0x2190, 0x23f3,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x26ff,
+ 0x2701, 0x2b4c,
+ 0x2b50, 0x2b59,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e3b,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fcc,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa697,
+ 0xa69f, 0xa6f7,
+ 0xa700, 0xa78e,
+ 0xa790, 0xa793,
+ 0xa7a0, 0xa7aa,
+ 0xa7f8, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fb,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9df,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa7b,
+ 0xaa80, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe26,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10190, 0x1019b,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1085f,
+ 0x10900, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a7f,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b7f,
+ 0x10c00, 0x10c48,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x11080, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11143,
+ 0x11180, 0x111c8,
+ 0x111d0, 0x111d9,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x12000, 0x1236e,
+ 0x12400, 0x12462,
+ 0x12470, 0x12473,
+ 0x13000, 0x1342e,
+ 0x16800, 0x16a38,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x1b000, 0x1b001,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0be,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0df,
+ 0x1f100, 0x1f10a,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f16b,
+ 0x1f170, 0x1f19a,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23a,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f320,
+ 0x1f330, 0x1f335,
+ 0x1f337, 0x1f37c,
+ 0x1f380, 0x1f393,
+ 0x1f3a0, 0x1f3c4,
+ 0x1f3c6, 0x1f3ca,
+ 0x1f3e0, 0x1f3f0,
+ 0x1f400, 0x1f43e,
+ 0x1f440, 0x1f440,
+ 0x1f442, 0x1f4f7,
+ 0x1f4f9, 0x1f4fc,
+ 0x1f500, 0x1f53d,
+ 0x1f540, 0x1f543,
+ 0x1f550, 0x1f567,
+ 0x1f5fb, 0x1f640,
+ 0x1f645, 0x1f64f,
+ 0x1f680, 0x1f6c5,
+ 0x1f700, 0x1f773,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_6_2 */
+
+/* 'Age_6_3': Derived Age 6.3 */
+static const OnigCodePoint CR_Age_6_3[] = {
+ 549,
+ 0x0000, 0x0377,
+ 0x037a, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x0527,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x058f, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0604,
+ 0x0606, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x08a0, 0x08a0,
+ 0x08a2, 0x08ac,
+ 0x08e4, 0x08fe,
+ 0x0900, 0x0977,
+ 0x0979, 0x097f,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd0, 0x1cf6,
+ 0x1d00, 0x1de6,
+ 0x1dfc, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20ba,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x2189,
+ 0x2190, 0x23f3,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x26ff,
+ 0x2701, 0x2b4c,
+ 0x2b50, 0x2b59,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e3b,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fcc,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa697,
+ 0xa69f, 0xa6f7,
+ 0xa700, 0xa78e,
+ 0xa790, 0xa793,
+ 0xa7a0, 0xa7aa,
+ 0xa7f8, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fb,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9df,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaa7b,
+ 0xaa80, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe26,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10190, 0x1019b,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1085f,
+ 0x10900, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a7f,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b7f,
+ 0x10c00, 0x10c48,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x11080, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11143,
+ 0x11180, 0x111c8,
+ 0x111d0, 0x111d9,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x12000, 0x1236e,
+ 0x12400, 0x12462,
+ 0x12470, 0x12473,
+ 0x13000, 0x1342e,
+ 0x16800, 0x16a38,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x1b000, 0x1b001,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0be,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0df,
+ 0x1f100, 0x1f10a,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f16b,
+ 0x1f170, 0x1f19a,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23a,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f320,
+ 0x1f330, 0x1f335,
+ 0x1f337, 0x1f37c,
+ 0x1f380, 0x1f393,
+ 0x1f3a0, 0x1f3c4,
+ 0x1f3c6, 0x1f3ca,
+ 0x1f3e0, 0x1f3f0,
+ 0x1f400, 0x1f43e,
+ 0x1f440, 0x1f440,
+ 0x1f442, 0x1f4f7,
+ 0x1f4f9, 0x1f4fc,
+ 0x1f500, 0x1f53d,
+ 0x1f540, 0x1f543,
+ 0x1f550, 0x1f567,
+ 0x1f5fb, 0x1f640,
+ 0x1f645, 0x1f64f,
+ 0x1f680, 0x1f6c5,
+ 0x1f700, 0x1f773,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_6_3 */
+
+/* 'Age_7_0': Derived Age 7.0 */
+static const OnigCodePoint CR_Age_7_0[] = {
+ 610,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x08a0, 0x08b2,
+ 0x08e4, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c59,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c81, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d01, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd0, 0x1cf6,
+ 0x1cf8, 0x1cf9,
+ 0x1d00, 0x1df5,
+ 0x1dfc, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bd,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x2189,
+ 0x2190, 0x23fa,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bb9,
+ 0x2bbd, 0x2bc8,
+ 0x2bca, 0x2bd1,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e42,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fcc,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa69d,
+ 0xa69f, 0xa6f7,
+ 0xa700, 0xa78e,
+ 0xa790, 0xa7ad,
+ 0xa7b0, 0xa7b1,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fb,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab5f,
+ 0xab64, 0xab65,
+ 0xabc0, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe2d,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018c,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x10900, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109be, 0x109bf,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11143,
+ 0x11150, 0x11176,
+ 0x11180, 0x111c8,
+ 0x111cd, 0x111cd,
+ 0x111d0, 0x111da,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123d,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11301, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133c, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115c9,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x11ac0, 0x11af8,
+ 0x12000, 0x12398,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x13000, 0x1342e,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x1b000, 0x1b001,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1d7ff,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f16b,
+ 0x1f170, 0x1f19a,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23a,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f32c,
+ 0x1f330, 0x1f37d,
+ 0x1f380, 0x1f3ce,
+ 0x1f3d4, 0x1f3f7,
+ 0x1f400, 0x1f4fe,
+ 0x1f500, 0x1f54a,
+ 0x1f550, 0x1f579,
+ 0x1f57b, 0x1f5a3,
+ 0x1f5a5, 0x1f642,
+ 0x1f645, 0x1f6cf,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6f3,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d4,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_7_0 */
+
+/* 'Age_8_0': Derived Age 8.0 */
+static const OnigCodePoint CR_Age_8_0[] = {
+ 623,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x08a0, 0x08b4,
+ 0x08e3, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0af9,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c7f,
+ 0x0c81, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d01, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4e,
+ 0x0d57, 0x0d57,
+ 0x0d5f, 0x0d63,
+ 0x0d66, 0x0d75,
+ 0x0d79, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c7f,
+ 0x1cc0, 0x1cc7,
+ 0x1cd0, 0x1cf6,
+ 0x1cf8, 0x1cf9,
+ 0x1d00, 0x1df5,
+ 0x1dfc, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20be,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x23fa,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bb9,
+ 0x2bbd, 0x2bc8,
+ 0x2bca, 0x2bd1,
+ 0x2bec, 0x2bef,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e42,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fd5,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7ad,
+ 0xa7b0, 0xa7b7,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c4,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fd,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab65,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018c,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10cff,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11143,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123d,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133c, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x11719,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x11ac0, 0x11af8,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x1b000, 0x1b001,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f16b,
+ 0x1f170, 0x1f19a,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23a,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f579,
+ 0x1f57b, 0x1f5a3,
+ 0x1f5a5, 0x1f6d0,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6f3,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d4,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f910, 0x1f918,
+ 0x1f980, 0x1f984,
+ 0x1f9c0, 0x1f9c0,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_8_0 */
+
+/* 'Age_9_0': Derived Age 9.0 */
+static const OnigCodePoint CR_Age_9_0[] = {
+ 648,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d4, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fb,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0af9,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d01, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d3a,
+ 0x0d3d, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1cc0, 0x1cc7,
+ 0x1cd0, 0x1cf6,
+ 0x1cf8, 0x1cf9,
+ 0x1d00, 0x1df5,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20be,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x23fe,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bb9,
+ 0x2bbd, 0x2bc8,
+ 0x2bca, 0x2bd1,
+ 0x2bec, 0x2bef,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e44,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312d,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fd5,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7ae,
+ 0xa7b0, 0xa7b7,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fd,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab65,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10cff,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11143,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133c, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145d,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x11719,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe0,
+ 0x17000, 0x187ec,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b001,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94a,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f16b,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f300, 0x1f6d2,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6f6,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d4,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f910, 0x1f91e,
+ 0x1f920, 0x1f927,
+ 0x1f930, 0x1f930,
+ 0x1f933, 0x1f93e,
+ 0x1f940, 0x1f94b,
+ 0x1f950, 0x1f95e,
+ 0x1f980, 0x1f991,
+ 0x1f9c0, 0x1f9c0,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_9_0 */
+
+/* 'Age_10_0': Derived Age 10.0 */
+static const OnigCodePoint CR_Age_10_0[] = {
+ 659,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x0800, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d4, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fd,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a75,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1cc0, 0x1cc7,
+ 0x1cd0, 0x1cf9,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bb9,
+ 0x2bbd, 0x2bc8,
+ 0x2bca, 0x2bd2,
+ 0x2bec, 0x2bef,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e49,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312e,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fea,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7ae,
+ 0xa7b0, 0xa7b7,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa8fd,
+ 0xa900, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab65,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10cff,
+ 0x10e60, 0x10e7e,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11143,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133c, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145d,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x11719,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x11a00, 0x11a47,
+ 0x11a50, 0x11a83,
+ 0x11a86, 0x11a9c,
+ 0x11a9e, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x17000, 0x187ec,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d371,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94a,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f12e,
+ 0x1f130, 0x1f16b,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d4,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6f8,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d4,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f910, 0x1f93e,
+ 0x1f940, 0x1f94c,
+ 0x1f950, 0x1f96b,
+ 0x1f980, 0x1f997,
+ 0x1f9c0, 0x1f9c0,
+ 0x1f9d0, 0x1f9e6,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_10_0 */
+
+/* 'Age_11_0': Derived Age 11.0 */
+static const OnigCodePoint CR_Age_11_0[] = {
+ 668,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a76,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c78, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd0, 0x1cf9,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2bc8,
+ 0x2bca, 0x2bfe,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e4e,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7b9,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab65,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a48,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f00, 0x10f27,
+ 0x10f30, 0x10f59,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110cd, 0x110cd,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11146,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145e,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b7,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x11800, 0x1183b,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x11a00, 0x11a47,
+ 0x11a50, 0x11a83,
+ 0x11a86, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef8,
+ 0x12000, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e9a,
+ 0x16f00, 0x16f44,
+ 0x16f50, 0x16f7e,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe1,
+ 0x17000, 0x187f1,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94a,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ec71, 0x1ecb4,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16b,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d4,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6f9,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f910, 0x1f93e,
+ 0x1f940, 0x1f970,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f97a,
+ 0x1f97c, 0x1f9a2,
+ 0x1f9b0, 0x1f9b9,
+ 0x1f9c0, 0x1f9c2,
+ 0x1f9d0, 0x1f9ff,
+ 0x1fa60, 0x1fa6d,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_11_0 */
+
+/* 'Age_12_0': Derived Age 12.0 */
+static const OnigCodePoint CR_Age_12_0[] = {
+ 677,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a76,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd0, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e4f,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab67,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a48,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f00, 0x10f27,
+ 0x10f30, 0x10f59,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110cd, 0x110cd,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11146,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145f,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x11800, 0x1183b,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e4,
+ 0x11a00, 0x11a47,
+ 0x11a50, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef8,
+ 0x11fc0, 0x11ff1,
+ 0x11fff, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x13430, 0x13438,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e9a,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14f,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e2ff, 0x1e2ff,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ec71, 0x1ecb4,
+ 0x1ed01, 0x1ed3d,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_12_0 */
+
+/* 'Age_12_1': Derived Age 12.1 */
+static const OnigCodePoint CR_Age_12_1[] = {
+ 676,
+ 0x0000, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x052f,
+ 0x0531, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x058f,
+ 0x0591, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0600, 0x061c,
+ 0x061e, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x082d,
+ 0x0830, 0x083e,
+ 0x0840, 0x085b,
+ 0x085e, 0x085e,
+ 0x0860, 0x086a,
+ 0x08a0, 0x08b4,
+ 0x08b6, 0x08bd,
+ 0x08d3, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fe,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a76,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0aff,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c39,
+ 0x0c3d, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c58, 0x0c5a,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce3,
+ 0x0ce6, 0x0cef,
+ 0x0cf1, 0x0cf2,
+ 0x0d00, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d44,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e86, 0x0e8a,
+ 0x0e8c, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6c,
+ 0x0f71, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fce, 0x0fda,
+ 0x1000, 0x10c5,
+ 0x10c7, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x191e,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a5e,
+ 0x1a60, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b4b,
+ 0x1b50, 0x1b7c,
+ 0x1b80, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd0, 0x1cfa,
+ 0x1d00, 0x1df9,
+ 0x1dfb, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2064,
+ 0x2066, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x209c,
+ 0x20a0, 0x20bf,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2b95,
+ 0x2b98, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c60, 0x2cf3,
+ 0x2cf9, 0x2d25,
+ 0x2d27, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2de0, 0x2e4f,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312f,
+ 0x3131, 0x318e,
+ 0x3190, 0x31ba,
+ 0x31c0, 0x31e3,
+ 0x31f0, 0x321e,
+ 0x3220, 0x4db5,
+ 0x4dc0, 0x9fef,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7bf,
+ 0xa7c2, 0xa7c6,
+ 0xa7f7, 0xa82b,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9cd,
+ 0xa9cf, 0xa9d9,
+ 0xa9de, 0xa9fe,
+ 0xaa00, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab26,
+ 0xab28, 0xab2e,
+ 0xab30, 0xab67,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xd800, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbc1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdd0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018e,
+ 0x10190, 0x1019b,
+ 0x101a0, 0x101a0,
+ 0x101d0, 0x101fd,
+ 0x10280, 0x1029c,
+ 0x102a0, 0x102d0,
+ 0x102e0, 0x102fb,
+ 0x10300, 0x10323,
+ 0x1032d, 0x1034a,
+ 0x10350, 0x1037a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x104b0, 0x104d3,
+ 0x104d8, 0x104fb,
+ 0x10500, 0x10527,
+ 0x10530, 0x10563,
+ 0x1056f, 0x1056f,
+ 0x10600, 0x10736,
+ 0x10740, 0x10755,
+ 0x10760, 0x10767,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x10855,
+ 0x10857, 0x1089e,
+ 0x108a7, 0x108af,
+ 0x108e0, 0x108f2,
+ 0x108f4, 0x108f5,
+ 0x108fb, 0x1091b,
+ 0x1091f, 0x10939,
+ 0x1093f, 0x1093f,
+ 0x10980, 0x109b7,
+ 0x109bc, 0x109cf,
+ 0x109d2, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a35,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a48,
+ 0x10a50, 0x10a58,
+ 0x10a60, 0x10a9f,
+ 0x10ac0, 0x10ae6,
+ 0x10aeb, 0x10af6,
+ 0x10b00, 0x10b35,
+ 0x10b39, 0x10b55,
+ 0x10b58, 0x10b72,
+ 0x10b78, 0x10b91,
+ 0x10b99, 0x10b9c,
+ 0x10ba9, 0x10baf,
+ 0x10c00, 0x10c48,
+ 0x10c80, 0x10cb2,
+ 0x10cc0, 0x10cf2,
+ 0x10cfa, 0x10d27,
+ 0x10d30, 0x10d39,
+ 0x10e60, 0x10e7e,
+ 0x10f00, 0x10f27,
+ 0x10f30, 0x10f59,
+ 0x10fe0, 0x10ff6,
+ 0x11000, 0x1104d,
+ 0x11052, 0x1106f,
+ 0x1107f, 0x110c1,
+ 0x110cd, 0x110cd,
+ 0x110d0, 0x110e8,
+ 0x110f0, 0x110f9,
+ 0x11100, 0x11134,
+ 0x11136, 0x11146,
+ 0x11150, 0x11176,
+ 0x11180, 0x111cd,
+ 0x111d0, 0x111df,
+ 0x111e1, 0x111f4,
+ 0x11200, 0x11211,
+ 0x11213, 0x1123e,
+ 0x11280, 0x11286,
+ 0x11288, 0x11288,
+ 0x1128a, 0x1128d,
+ 0x1128f, 0x1129d,
+ 0x1129f, 0x112a9,
+ 0x112b0, 0x112ea,
+ 0x112f0, 0x112f9,
+ 0x11300, 0x11303,
+ 0x11305, 0x1130c,
+ 0x1130f, 0x11310,
+ 0x11313, 0x11328,
+ 0x1132a, 0x11330,
+ 0x11332, 0x11333,
+ 0x11335, 0x11339,
+ 0x1133b, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11350, 0x11350,
+ 0x11357, 0x11357,
+ 0x1135d, 0x11363,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11400, 0x11459,
+ 0x1145b, 0x1145b,
+ 0x1145d, 0x1145f,
+ 0x11480, 0x114c7,
+ 0x114d0, 0x114d9,
+ 0x11580, 0x115b5,
+ 0x115b8, 0x115dd,
+ 0x11600, 0x11644,
+ 0x11650, 0x11659,
+ 0x11660, 0x1166c,
+ 0x11680, 0x116b8,
+ 0x116c0, 0x116c9,
+ 0x11700, 0x1171a,
+ 0x1171d, 0x1172b,
+ 0x11730, 0x1173f,
+ 0x11800, 0x1183b,
+ 0x118a0, 0x118f2,
+ 0x118ff, 0x118ff,
+ 0x119a0, 0x119a7,
+ 0x119aa, 0x119d7,
+ 0x119da, 0x119e4,
+ 0x11a00, 0x11a47,
+ 0x11a50, 0x11aa2,
+ 0x11ac0, 0x11af8,
+ 0x11c00, 0x11c08,
+ 0x11c0a, 0x11c36,
+ 0x11c38, 0x11c45,
+ 0x11c50, 0x11c6c,
+ 0x11c70, 0x11c8f,
+ 0x11c92, 0x11ca7,
+ 0x11ca9, 0x11cb6,
+ 0x11d00, 0x11d06,
+ 0x11d08, 0x11d09,
+ 0x11d0b, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d47,
+ 0x11d50, 0x11d59,
+ 0x11d60, 0x11d65,
+ 0x11d67, 0x11d68,
+ 0x11d6a, 0x11d8e,
+ 0x11d90, 0x11d91,
+ 0x11d93, 0x11d98,
+ 0x11da0, 0x11da9,
+ 0x11ee0, 0x11ef8,
+ 0x11fc0, 0x11ff1,
+ 0x11fff, 0x12399,
+ 0x12400, 0x1246e,
+ 0x12470, 0x12474,
+ 0x12480, 0x12543,
+ 0x13000, 0x1342e,
+ 0x13430, 0x13438,
+ 0x14400, 0x14646,
+ 0x16800, 0x16a38,
+ 0x16a40, 0x16a5e,
+ 0x16a60, 0x16a69,
+ 0x16a6e, 0x16a6f,
+ 0x16ad0, 0x16aed,
+ 0x16af0, 0x16af5,
+ 0x16b00, 0x16b45,
+ 0x16b50, 0x16b59,
+ 0x16b5b, 0x16b61,
+ 0x16b63, 0x16b77,
+ 0x16b7d, 0x16b8f,
+ 0x16e40, 0x16e9a,
+ 0x16f00, 0x16f4a,
+ 0x16f4f, 0x16f87,
+ 0x16f8f, 0x16f9f,
+ 0x16fe0, 0x16fe3,
+ 0x17000, 0x187f7,
+ 0x18800, 0x18af2,
+ 0x1b000, 0x1b11e,
+ 0x1b150, 0x1b152,
+ 0x1b164, 0x1b167,
+ 0x1b170, 0x1b2fb,
+ 0x1bc00, 0x1bc6a,
+ 0x1bc70, 0x1bc7c,
+ 0x1bc80, 0x1bc88,
+ 0x1bc90, 0x1bc99,
+ 0x1bc9c, 0x1bca3,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d129, 0x1d1e8,
+ 0x1d200, 0x1d245,
+ 0x1d2e0, 0x1d2f3,
+ 0x1d300, 0x1d356,
+ 0x1d360, 0x1d378,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7cb,
+ 0x1d7ce, 0x1da8b,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e100, 0x1e12c,
+ 0x1e130, 0x1e13d,
+ 0x1e140, 0x1e149,
+ 0x1e14e, 0x1e14f,
+ 0x1e2c0, 0x1e2f9,
+ 0x1e2ff, 0x1e2ff,
+ 0x1e800, 0x1e8c4,
+ 0x1e8c7, 0x1e8d6,
+ 0x1e900, 0x1e94b,
+ 0x1e950, 0x1e959,
+ 0x1e95e, 0x1e95f,
+ 0x1ec71, 0x1ecb4,
+ 0x1ed01, 0x1ed3d,
+ 0x1ee00, 0x1ee03,
+ 0x1ee05, 0x1ee1f,
+ 0x1ee21, 0x1ee22,
+ 0x1ee24, 0x1ee24,
+ 0x1ee27, 0x1ee27,
+ 0x1ee29, 0x1ee32,
+ 0x1ee34, 0x1ee37,
+ 0x1ee39, 0x1ee39,
+ 0x1ee3b, 0x1ee3b,
+ 0x1ee42, 0x1ee42,
+ 0x1ee47, 0x1ee47,
+ 0x1ee49, 0x1ee49,
+ 0x1ee4b, 0x1ee4b,
+ 0x1ee4d, 0x1ee4f,
+ 0x1ee51, 0x1ee52,
+ 0x1ee54, 0x1ee54,
+ 0x1ee57, 0x1ee57,
+ 0x1ee59, 0x1ee59,
+ 0x1ee5b, 0x1ee5b,
+ 0x1ee5d, 0x1ee5d,
+ 0x1ee5f, 0x1ee5f,
+ 0x1ee61, 0x1ee62,
+ 0x1ee64, 0x1ee64,
+ 0x1ee67, 0x1ee6a,
+ 0x1ee6c, 0x1ee72,
+ 0x1ee74, 0x1ee77,
+ 0x1ee79, 0x1ee7c,
+ 0x1ee7e, 0x1ee7e,
+ 0x1ee80, 0x1ee89,
+ 0x1ee8b, 0x1ee9b,
+ 0x1eea1, 0x1eea3,
+ 0x1eea5, 0x1eea9,
+ 0x1eeab, 0x1eebb,
+ 0x1eef0, 0x1eef1,
+ 0x1f000, 0x1f02b,
+ 0x1f030, 0x1f093,
+ 0x1f0a0, 0x1f0ae,
+ 0x1f0b1, 0x1f0bf,
+ 0x1f0c1, 0x1f0cf,
+ 0x1f0d1, 0x1f0f5,
+ 0x1f100, 0x1f10c,
+ 0x1f110, 0x1f16c,
+ 0x1f170, 0x1f1ac,
+ 0x1f1e6, 0x1f202,
+ 0x1f210, 0x1f23b,
+ 0x1f240, 0x1f248,
+ 0x1f250, 0x1f251,
+ 0x1f260, 0x1f265,
+ 0x1f300, 0x1f6d5,
+ 0x1f6e0, 0x1f6ec,
+ 0x1f6f0, 0x1f6fa,
+ 0x1f700, 0x1f773,
+ 0x1f780, 0x1f7d8,
+ 0x1f7e0, 0x1f7eb,
+ 0x1f800, 0x1f80b,
+ 0x1f810, 0x1f847,
+ 0x1f850, 0x1f859,
+ 0x1f860, 0x1f887,
+ 0x1f890, 0x1f8ad,
+ 0x1f900, 0x1f90b,
+ 0x1f90d, 0x1f971,
+ 0x1f973, 0x1f976,
+ 0x1f97a, 0x1f9a2,
+ 0x1f9a5, 0x1f9aa,
+ 0x1f9ae, 0x1f9ca,
+ 0x1f9cd, 0x1fa53,
+ 0x1fa60, 0x1fa6d,
+ 0x1fa70, 0x1fa73,
+ 0x1fa78, 0x1fa7a,
+ 0x1fa80, 0x1fa82,
+ 0x1fa90, 0x1fa95,
+ 0x1fffe, 0x2a6d6,
+ 0x2a700, 0x2b734,
+ 0x2b740, 0x2b81d,
+ 0x2b820, 0x2cea1,
+ 0x2ceb0, 0x2ebe0,
+ 0x2f800, 0x2fa1d,
+ 0x2fffe, 0x2ffff,
+ 0x3fffe, 0x3ffff,
+ 0x4fffe, 0x4ffff,
+ 0x5fffe, 0x5ffff,
+ 0x6fffe, 0x6ffff,
+ 0x7fffe, 0x7ffff,
+ 0x8fffe, 0x8ffff,
+ 0x9fffe, 0x9ffff,
+ 0xafffe, 0xaffff,
+ 0xbfffe, 0xbffff,
+ 0xcfffe, 0xcffff,
+ 0xdfffe, 0xdffff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xefffe, 0x10ffff,
+}; /* CR_Age_12_1 */
+
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+/* 'Grapheme_Cluster_Break_Prepend': Grapheme_Cluster_Break=Prepend */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_Prepend[] = {
+ 11,
+ 0x0600, 0x0605,
+ 0x06dd, 0x06dd,
+ 0x070f, 0x070f,
+ 0x08e2, 0x08e2,
+ 0x0d4e, 0x0d4e,
+ 0x110bd, 0x110bd,
+ 0x110cd, 0x110cd,
+ 0x111c2, 0x111c3,
+ 0x11a3a, 0x11a3a,
+ 0x11a84, 0x11a89,
+ 0x11d46, 0x11d46,
+}; /* CR_Grapheme_Cluster_Break_Prepend */
+
+/* 'Grapheme_Cluster_Break_CR': Grapheme_Cluster_Break=CR */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_CR[] = {
+ 1,
+ 0x000d, 0x000d,
+}; /* CR_Grapheme_Cluster_Break_CR */
+
+/* 'Grapheme_Cluster_Break_LF': Grapheme_Cluster_Break=LF */
+#define CR_Grapheme_Cluster_Break_LF CR_NEWLINE
+
+/* 'Grapheme_Cluster_Break_Control': Grapheme_Cluster_Break=Control */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_Control[] = {
+ 19,
+ 0x0000, 0x0009,
+ 0x000b, 0x000c,
+ 0x000e, 0x001f,
+ 0x007f, 0x009f,
+ 0x00ad, 0x00ad,
+ 0x061c, 0x061c,
+ 0x180e, 0x180e,
+ 0x200b, 0x200b,
+ 0x200e, 0x200f,
+ 0x2028, 0x202e,
+ 0x2060, 0x206f,
+ 0xfeff, 0xfeff,
+ 0xfff0, 0xfffb,
+ 0x13430, 0x13438,
+ 0x1bca0, 0x1bca3,
+ 0x1d173, 0x1d17a,
+ 0xe0000, 0xe001f,
+ 0xe0080, 0xe00ff,
+ 0xe01f0, 0xe0fff,
+}; /* CR_Grapheme_Cluster_Break_Control */
+
+/* 'Grapheme_Cluster_Break_Extend': Grapheme_Cluster_Break=Extend */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_Extend[] = {
+ 336,
+ 0x0300, 0x036f,
+ 0x0483, 0x0489,
+ 0x0591, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x0610, 0x061a,
+ 0x064b, 0x065f,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dc,
+ 0x06df, 0x06e4,
+ 0x06e7, 0x06e8,
+ 0x06ea, 0x06ed,
+ 0x0711, 0x0711,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x07eb, 0x07f3,
+ 0x07fd, 0x07fd,
+ 0x0816, 0x0819,
+ 0x081b, 0x0823,
+ 0x0825, 0x0827,
+ 0x0829, 0x082d,
+ 0x0859, 0x085b,
+ 0x08d3, 0x08e1,
+ 0x08e3, 0x0902,
+ 0x093a, 0x093a,
+ 0x093c, 0x093c,
+ 0x0941, 0x0948,
+ 0x094d, 0x094d,
+ 0x0951, 0x0957,
+ 0x0962, 0x0963,
+ 0x0981, 0x0981,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09be,
+ 0x09c1, 0x09c4,
+ 0x09cd, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09e2, 0x09e3,
+ 0x09fe, 0x09fe,
+ 0x0a01, 0x0a02,
+ 0x0a3c, 0x0a3c,
+ 0x0a41, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a70, 0x0a71,
+ 0x0a75, 0x0a75,
+ 0x0a81, 0x0a82,
+ 0x0abc, 0x0abc,
+ 0x0ac1, 0x0ac5,
+ 0x0ac7, 0x0ac8,
+ 0x0acd, 0x0acd,
+ 0x0ae2, 0x0ae3,
+ 0x0afa, 0x0aff,
+ 0x0b01, 0x0b01,
+ 0x0b3c, 0x0b3c,
+ 0x0b3e, 0x0b3f,
+ 0x0b41, 0x0b44,
+ 0x0b4d, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b62, 0x0b63,
+ 0x0b82, 0x0b82,
+ 0x0bbe, 0x0bbe,
+ 0x0bc0, 0x0bc0,
+ 0x0bcd, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0c00, 0x0c00,
+ 0x0c04, 0x0c04,
+ 0x0c3e, 0x0c40,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c62, 0x0c63,
+ 0x0c81, 0x0c81,
+ 0x0cbc, 0x0cbc,
+ 0x0cbf, 0x0cbf,
+ 0x0cc2, 0x0cc2,
+ 0x0cc6, 0x0cc6,
+ 0x0ccc, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0ce2, 0x0ce3,
+ 0x0d00, 0x0d01,
+ 0x0d3b, 0x0d3c,
+ 0x0d3e, 0x0d3e,
+ 0x0d41, 0x0d44,
+ 0x0d4d, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d62, 0x0d63,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dcf,
+ 0x0dd2, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0ddf, 0x0ddf,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e47, 0x0e4e,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0ebc,
+ 0x0ec8, 0x0ecd,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f71, 0x0f7e,
+ 0x0f80, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0f8d, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x102d, 0x1030,
+ 0x1032, 0x1037,
+ 0x1039, 0x103a,
+ 0x103d, 0x103e,
+ 0x1058, 0x1059,
+ 0x105e, 0x1060,
+ 0x1071, 0x1074,
+ 0x1082, 0x1082,
+ 0x1085, 0x1086,
+ 0x108d, 0x108d,
+ 0x109d, 0x109d,
+ 0x135d, 0x135f,
+ 0x1712, 0x1714,
+ 0x1732, 0x1734,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b4, 0x17b5,
+ 0x17b7, 0x17bd,
+ 0x17c6, 0x17c6,
+ 0x17c9, 0x17d3,
+ 0x17dd, 0x17dd,
+ 0x180b, 0x180d,
+ 0x1885, 0x1886,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x1922,
+ 0x1927, 0x1928,
+ 0x1932, 0x1932,
+ 0x1939, 0x193b,
+ 0x1a17, 0x1a18,
+ 0x1a1b, 0x1a1b,
+ 0x1a56, 0x1a56,
+ 0x1a58, 0x1a5e,
+ 0x1a60, 0x1a60,
+ 0x1a62, 0x1a62,
+ 0x1a65, 0x1a6c,
+ 0x1a73, 0x1a7c,
+ 0x1a7f, 0x1a7f,
+ 0x1ab0, 0x1abe,
+ 0x1b00, 0x1b03,
+ 0x1b34, 0x1b3a,
+ 0x1b3c, 0x1b3c,
+ 0x1b42, 0x1b42,
+ 0x1b6b, 0x1b73,
+ 0x1b80, 0x1b81,
+ 0x1ba2, 0x1ba5,
+ 0x1ba8, 0x1ba9,
+ 0x1bab, 0x1bad,
+ 0x1be6, 0x1be6,
+ 0x1be8, 0x1be9,
+ 0x1bed, 0x1bed,
+ 0x1bef, 0x1bf1,
+ 0x1c2c, 0x1c33,
+ 0x1c36, 0x1c37,
+ 0x1cd0, 0x1cd2,
+ 0x1cd4, 0x1ce0,
+ 0x1ce2, 0x1ce8,
+ 0x1ced, 0x1ced,
+ 0x1cf4, 0x1cf4,
+ 0x1cf8, 0x1cf9,
+ 0x1dc0, 0x1df9,
+ 0x1dfb, 0x1dff,
+ 0x200c, 0x200c,
+ 0x20d0, 0x20f0,
+ 0x2cef, 0x2cf1,
+ 0x2d7f, 0x2d7f,
+ 0x2de0, 0x2dff,
+ 0x302a, 0x302f,
+ 0x3099, 0x309a,
+ 0xa66f, 0xa672,
+ 0xa674, 0xa67d,
+ 0xa69e, 0xa69f,
+ 0xa6f0, 0xa6f1,
+ 0xa802, 0xa802,
+ 0xa806, 0xa806,
+ 0xa80b, 0xa80b,
+ 0xa825, 0xa826,
+ 0xa8c4, 0xa8c5,
+ 0xa8e0, 0xa8f1,
+ 0xa8ff, 0xa8ff,
+ 0xa926, 0xa92d,
+ 0xa947, 0xa951,
+ 0xa980, 0xa982,
+ 0xa9b3, 0xa9b3,
+ 0xa9b6, 0xa9b9,
+ 0xa9bc, 0xa9bd,
+ 0xa9e5, 0xa9e5,
+ 0xaa29, 0xaa2e,
+ 0xaa31, 0xaa32,
+ 0xaa35, 0xaa36,
+ 0xaa43, 0xaa43,
+ 0xaa4c, 0xaa4c,
+ 0xaa7c, 0xaa7c,
+ 0xaab0, 0xaab0,
+ 0xaab2, 0xaab4,
+ 0xaab7, 0xaab8,
+ 0xaabe, 0xaabf,
+ 0xaac1, 0xaac1,
+ 0xaaec, 0xaaed,
+ 0xaaf6, 0xaaf6,
+ 0xabe5, 0xabe5,
+ 0xabe8, 0xabe8,
+ 0xabed, 0xabed,
+ 0xfb1e, 0xfb1e,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe2f,
+ 0xff9e, 0xff9f,
+ 0x101fd, 0x101fd,
+ 0x102e0, 0x102e0,
+ 0x10376, 0x1037a,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x10ae5, 0x10ae6,
+ 0x10d24, 0x10d27,
+ 0x10f46, 0x10f50,
+ 0x11001, 0x11001,
+ 0x11038, 0x11046,
+ 0x1107f, 0x11081,
+ 0x110b3, 0x110b6,
+ 0x110b9, 0x110ba,
+ 0x11100, 0x11102,
+ 0x11127, 0x1112b,
+ 0x1112d, 0x11134,
+ 0x11173, 0x11173,
+ 0x11180, 0x11181,
+ 0x111b6, 0x111be,
+ 0x111c9, 0x111cc,
+ 0x1122f, 0x11231,
+ 0x11234, 0x11234,
+ 0x11236, 0x11237,
+ 0x1123e, 0x1123e,
+ 0x112df, 0x112df,
+ 0x112e3, 0x112ea,
+ 0x11300, 0x11301,
+ 0x1133b, 0x1133c,
+ 0x1133e, 0x1133e,
+ 0x11340, 0x11340,
+ 0x11357, 0x11357,
+ 0x11366, 0x1136c,
+ 0x11370, 0x11374,
+ 0x11438, 0x1143f,
+ 0x11442, 0x11444,
+ 0x11446, 0x11446,
+ 0x1145e, 0x1145e,
+ 0x114b0, 0x114b0,
+ 0x114b3, 0x114b8,
+ 0x114ba, 0x114ba,
+ 0x114bd, 0x114bd,
+ 0x114bf, 0x114c0,
+ 0x114c2, 0x114c3,
+ 0x115af, 0x115af,
+ 0x115b2, 0x115b5,
+ 0x115bc, 0x115bd,
+ 0x115bf, 0x115c0,
+ 0x115dc, 0x115dd,
+ 0x11633, 0x1163a,
+ 0x1163d, 0x1163d,
+ 0x1163f, 0x11640,
+ 0x116ab, 0x116ab,
+ 0x116ad, 0x116ad,
+ 0x116b0, 0x116b5,
+ 0x116b7, 0x116b7,
+ 0x1171d, 0x1171f,
+ 0x11722, 0x11725,
+ 0x11727, 0x1172b,
+ 0x1182f, 0x11837,
+ 0x11839, 0x1183a,
+ 0x119d4, 0x119d7,
+ 0x119da, 0x119db,
+ 0x119e0, 0x119e0,
+ 0x11a01, 0x11a0a,
+ 0x11a33, 0x11a38,
+ 0x11a3b, 0x11a3e,
+ 0x11a47, 0x11a47,
+ 0x11a51, 0x11a56,
+ 0x11a59, 0x11a5b,
+ 0x11a8a, 0x11a96,
+ 0x11a98, 0x11a99,
+ 0x11c30, 0x11c36,
+ 0x11c38, 0x11c3d,
+ 0x11c3f, 0x11c3f,
+ 0x11c92, 0x11ca7,
+ 0x11caa, 0x11cb0,
+ 0x11cb2, 0x11cb3,
+ 0x11cb5, 0x11cb6,
+ 0x11d31, 0x11d36,
+ 0x11d3a, 0x11d3a,
+ 0x11d3c, 0x11d3d,
+ 0x11d3f, 0x11d45,
+ 0x11d47, 0x11d47,
+ 0x11d90, 0x11d91,
+ 0x11d95, 0x11d95,
+ 0x11d97, 0x11d97,
+ 0x11ef3, 0x11ef4,
+ 0x16af0, 0x16af4,
+ 0x16b30, 0x16b36,
+ 0x16f4f, 0x16f4f,
+ 0x16f8f, 0x16f92,
+ 0x1bc9d, 0x1bc9e,
+ 0x1d165, 0x1d165,
+ 0x1d167, 0x1d169,
+ 0x1d16e, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1da00, 0x1da36,
+ 0x1da3b, 0x1da6c,
+ 0x1da75, 0x1da75,
+ 0x1da84, 0x1da84,
+ 0x1da9b, 0x1da9f,
+ 0x1daa1, 0x1daaf,
+ 0x1e000, 0x1e006,
+ 0x1e008, 0x1e018,
+ 0x1e01b, 0x1e021,
+ 0x1e023, 0x1e024,
+ 0x1e026, 0x1e02a,
+ 0x1e130, 0x1e136,
+ 0x1e2ec, 0x1e2ef,
+ 0x1e8d0, 0x1e8d6,
+ 0x1e944, 0x1e94a,
+ 0x1f3fb, 0x1f3ff,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+}; /* CR_Grapheme_Cluster_Break_Extend */
+
+/* 'Grapheme_Cluster_Break_Regional_Indicator': Grapheme_Cluster_Break=Regional_Indicator */
+#define CR_Grapheme_Cluster_Break_Regional_Indicator CR_Regional_Indicator
+
+/* 'Grapheme_Cluster_Break_SpacingMark': Grapheme_Cluster_Break=SpacingMark */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_SpacingMark[] = {
+ 152,
+ 0x0903, 0x0903,
+ 0x093b, 0x093b,
+ 0x093e, 0x0940,
+ 0x0949, 0x094c,
+ 0x094e, 0x094f,
+ 0x0982, 0x0983,
+ 0x09bf, 0x09c0,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cc,
+ 0x0a03, 0x0a03,
+ 0x0a3e, 0x0a40,
+ 0x0a83, 0x0a83,
+ 0x0abe, 0x0ac0,
+ 0x0ac9, 0x0ac9,
+ 0x0acb, 0x0acc,
+ 0x0b02, 0x0b03,
+ 0x0b40, 0x0b40,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4c,
+ 0x0bbf, 0x0bbf,
+ 0x0bc1, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcc,
+ 0x0c01, 0x0c03,
+ 0x0c41, 0x0c44,
+ 0x0c82, 0x0c83,
+ 0x0cbe, 0x0cbe,
+ 0x0cc0, 0x0cc1,
+ 0x0cc3, 0x0cc4,
+ 0x0cc7, 0x0cc8,
+ 0x0cca, 0x0ccb,
+ 0x0d02, 0x0d03,
+ 0x0d3f, 0x0d40,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4c,
+ 0x0d82, 0x0d83,
+ 0x0dd0, 0x0dd1,
+ 0x0dd8, 0x0dde,
+ 0x0df2, 0x0df3,
+ 0x0e33, 0x0e33,
+ 0x0eb3, 0x0eb3,
+ 0x0f3e, 0x0f3f,
+ 0x0f7f, 0x0f7f,
+ 0x1031, 0x1031,
+ 0x103b, 0x103c,
+ 0x1056, 0x1057,
+ 0x1084, 0x1084,
+ 0x17b6, 0x17b6,
+ 0x17be, 0x17c5,
+ 0x17c7, 0x17c8,
+ 0x1923, 0x1926,
+ 0x1929, 0x192b,
+ 0x1930, 0x1931,
+ 0x1933, 0x1938,
+ 0x1a19, 0x1a1a,
+ 0x1a55, 0x1a55,
+ 0x1a57, 0x1a57,
+ 0x1a6d, 0x1a72,
+ 0x1b04, 0x1b04,
+ 0x1b3b, 0x1b3b,
+ 0x1b3d, 0x1b41,
+ 0x1b43, 0x1b44,
+ 0x1b82, 0x1b82,
+ 0x1ba1, 0x1ba1,
+ 0x1ba6, 0x1ba7,
+ 0x1baa, 0x1baa,
+ 0x1be7, 0x1be7,
+ 0x1bea, 0x1bec,
+ 0x1bee, 0x1bee,
+ 0x1bf2, 0x1bf3,
+ 0x1c24, 0x1c2b,
+ 0x1c34, 0x1c35,
+ 0x1ce1, 0x1ce1,
+ 0x1cf7, 0x1cf7,
+ 0xa823, 0xa824,
+ 0xa827, 0xa827,
+ 0xa880, 0xa881,
+ 0xa8b4, 0xa8c3,
+ 0xa952, 0xa953,
+ 0xa983, 0xa983,
+ 0xa9b4, 0xa9b5,
+ 0xa9ba, 0xa9bb,
+ 0xa9be, 0xa9c0,
+ 0xaa2f, 0xaa30,
+ 0xaa33, 0xaa34,
+ 0xaa4d, 0xaa4d,
+ 0xaaeb, 0xaaeb,
+ 0xaaee, 0xaaef,
+ 0xaaf5, 0xaaf5,
+ 0xabe3, 0xabe4,
+ 0xabe6, 0xabe7,
+ 0xabe9, 0xabea,
+ 0xabec, 0xabec,
+ 0x11000, 0x11000,
+ 0x11002, 0x11002,
+ 0x11082, 0x11082,
+ 0x110b0, 0x110b2,
+ 0x110b7, 0x110b8,
+ 0x1112c, 0x1112c,
+ 0x11145, 0x11146,
+ 0x11182, 0x11182,
+ 0x111b3, 0x111b5,
+ 0x111bf, 0x111c0,
+ 0x1122c, 0x1122e,
+ 0x11232, 0x11233,
+ 0x11235, 0x11235,
+ 0x112e0, 0x112e2,
+ 0x11302, 0x11303,
+ 0x1133f, 0x1133f,
+ 0x11341, 0x11344,
+ 0x11347, 0x11348,
+ 0x1134b, 0x1134d,
+ 0x11362, 0x11363,
+ 0x11435, 0x11437,
+ 0x11440, 0x11441,
+ 0x11445, 0x11445,
+ 0x114b1, 0x114b2,
+ 0x114b9, 0x114b9,
+ 0x114bb, 0x114bc,
+ 0x114be, 0x114be,
+ 0x114c1, 0x114c1,
+ 0x115b0, 0x115b1,
+ 0x115b8, 0x115bb,
+ 0x115be, 0x115be,
+ 0x11630, 0x11632,
+ 0x1163b, 0x1163c,
+ 0x1163e, 0x1163e,
+ 0x116ac, 0x116ac,
+ 0x116ae, 0x116af,
+ 0x116b6, 0x116b6,
+ 0x11720, 0x11721,
+ 0x11726, 0x11726,
+ 0x1182c, 0x1182e,
+ 0x11838, 0x11838,
+ 0x119d1, 0x119d3,
+ 0x119dc, 0x119df,
+ 0x119e4, 0x119e4,
+ 0x11a39, 0x11a39,
+ 0x11a57, 0x11a58,
+ 0x11a97, 0x11a97,
+ 0x11c2f, 0x11c2f,
+ 0x11c3e, 0x11c3e,
+ 0x11ca9, 0x11ca9,
+ 0x11cb1, 0x11cb1,
+ 0x11cb4, 0x11cb4,
+ 0x11d8a, 0x11d8e,
+ 0x11d93, 0x11d94,
+ 0x11d96, 0x11d96,
+ 0x11ef5, 0x11ef6,
+ 0x16f51, 0x16f87,
+ 0x1d166, 0x1d166,
+ 0x1d16d, 0x1d16d,
+}; /* CR_Grapheme_Cluster_Break_SpacingMark */
+
+/* 'Grapheme_Cluster_Break_L': Grapheme_Cluster_Break=L */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_L[] = {
+ 2,
+ 0x1100, 0x115f,
+ 0xa960, 0xa97c,
+}; /* CR_Grapheme_Cluster_Break_L */
+
+/* 'Grapheme_Cluster_Break_V': Grapheme_Cluster_Break=V */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_V[] = {
+ 2,
+ 0x1160, 0x11a7,
+ 0xd7b0, 0xd7c6,
+}; /* CR_Grapheme_Cluster_Break_V */
+
+/* 'Grapheme_Cluster_Break_T': Grapheme_Cluster_Break=T */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_T[] = {
+ 2,
+ 0x11a8, 0x11ff,
+ 0xd7cb, 0xd7fb,
+}; /* CR_Grapheme_Cluster_Break_T */
+
+/* 'Grapheme_Cluster_Break_LV': Grapheme_Cluster_Break=LV */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_LV[] = {
+ 399,
+ 0xac00, 0xac00,
+ 0xac1c, 0xac1c,
+ 0xac38, 0xac38,
+ 0xac54, 0xac54,
+ 0xac70, 0xac70,
+ 0xac8c, 0xac8c,
+ 0xaca8, 0xaca8,
+ 0xacc4, 0xacc4,
+ 0xace0, 0xace0,
+ 0xacfc, 0xacfc,
+ 0xad18, 0xad18,
+ 0xad34, 0xad34,
+ 0xad50, 0xad50,
+ 0xad6c, 0xad6c,
+ 0xad88, 0xad88,
+ 0xada4, 0xada4,
+ 0xadc0, 0xadc0,
+ 0xaddc, 0xaddc,
+ 0xadf8, 0xadf8,
+ 0xae14, 0xae14,
+ 0xae30, 0xae30,
+ 0xae4c, 0xae4c,
+ 0xae68, 0xae68,
+ 0xae84, 0xae84,
+ 0xaea0, 0xaea0,
+ 0xaebc, 0xaebc,
+ 0xaed8, 0xaed8,
+ 0xaef4, 0xaef4,
+ 0xaf10, 0xaf10,
+ 0xaf2c, 0xaf2c,
+ 0xaf48, 0xaf48,
+ 0xaf64, 0xaf64,
+ 0xaf80, 0xaf80,
+ 0xaf9c, 0xaf9c,
+ 0xafb8, 0xafb8,
+ 0xafd4, 0xafd4,
+ 0xaff0, 0xaff0,
+ 0xb00c, 0xb00c,
+ 0xb028, 0xb028,
+ 0xb044, 0xb044,
+ 0xb060, 0xb060,
+ 0xb07c, 0xb07c,
+ 0xb098, 0xb098,
+ 0xb0b4, 0xb0b4,
+ 0xb0d0, 0xb0d0,
+ 0xb0ec, 0xb0ec,
+ 0xb108, 0xb108,
+ 0xb124, 0xb124,
+ 0xb140, 0xb140,
+ 0xb15c, 0xb15c,
+ 0xb178, 0xb178,
+ 0xb194, 0xb194,
+ 0xb1b0, 0xb1b0,
+ 0xb1cc, 0xb1cc,
+ 0xb1e8, 0xb1e8,
+ 0xb204, 0xb204,
+ 0xb220, 0xb220,
+ 0xb23c, 0xb23c,
+ 0xb258, 0xb258,
+ 0xb274, 0xb274,
+ 0xb290, 0xb290,
+ 0xb2ac, 0xb2ac,
+ 0xb2c8, 0xb2c8,
+ 0xb2e4, 0xb2e4,
+ 0xb300, 0xb300,
+ 0xb31c, 0xb31c,
+ 0xb338, 0xb338,
+ 0xb354, 0xb354,
+ 0xb370, 0xb370,
+ 0xb38c, 0xb38c,
+ 0xb3a8, 0xb3a8,
+ 0xb3c4, 0xb3c4,
+ 0xb3e0, 0xb3e0,
+ 0xb3fc, 0xb3fc,
+ 0xb418, 0xb418,
+ 0xb434, 0xb434,
+ 0xb450, 0xb450,
+ 0xb46c, 0xb46c,
+ 0xb488, 0xb488,
+ 0xb4a4, 0xb4a4,
+ 0xb4c0, 0xb4c0,
+ 0xb4dc, 0xb4dc,
+ 0xb4f8, 0xb4f8,
+ 0xb514, 0xb514,
+ 0xb530, 0xb530,
+ 0xb54c, 0xb54c,
+ 0xb568, 0xb568,
+ 0xb584, 0xb584,
+ 0xb5a0, 0xb5a0,
+ 0xb5bc, 0xb5bc,
+ 0xb5d8, 0xb5d8,
+ 0xb5f4, 0xb5f4,
+ 0xb610, 0xb610,
+ 0xb62c, 0xb62c,
+ 0xb648, 0xb648,
+ 0xb664, 0xb664,
+ 0xb680, 0xb680,
+ 0xb69c, 0xb69c,
+ 0xb6b8, 0xb6b8,
+ 0xb6d4, 0xb6d4,
+ 0xb6f0, 0xb6f0,
+ 0xb70c, 0xb70c,
+ 0xb728, 0xb728,
+ 0xb744, 0xb744,
+ 0xb760, 0xb760,
+ 0xb77c, 0xb77c,
+ 0xb798, 0xb798,
+ 0xb7b4, 0xb7b4,
+ 0xb7d0, 0xb7d0,
+ 0xb7ec, 0xb7ec,
+ 0xb808, 0xb808,
+ 0xb824, 0xb824,
+ 0xb840, 0xb840,
+ 0xb85c, 0xb85c,
+ 0xb878, 0xb878,
+ 0xb894, 0xb894,
+ 0xb8b0, 0xb8b0,
+ 0xb8cc, 0xb8cc,
+ 0xb8e8, 0xb8e8,
+ 0xb904, 0xb904,
+ 0xb920, 0xb920,
+ 0xb93c, 0xb93c,
+ 0xb958, 0xb958,
+ 0xb974, 0xb974,
+ 0xb990, 0xb990,
+ 0xb9ac, 0xb9ac,
+ 0xb9c8, 0xb9c8,
+ 0xb9e4, 0xb9e4,
+ 0xba00, 0xba00,
+ 0xba1c, 0xba1c,
+ 0xba38, 0xba38,
+ 0xba54, 0xba54,
+ 0xba70, 0xba70,
+ 0xba8c, 0xba8c,
+ 0xbaa8, 0xbaa8,
+ 0xbac4, 0xbac4,
+ 0xbae0, 0xbae0,
+ 0xbafc, 0xbafc,
+ 0xbb18, 0xbb18,
+ 0xbb34, 0xbb34,
+ 0xbb50, 0xbb50,
+ 0xbb6c, 0xbb6c,
+ 0xbb88, 0xbb88,
+ 0xbba4, 0xbba4,
+ 0xbbc0, 0xbbc0,
+ 0xbbdc, 0xbbdc,
+ 0xbbf8, 0xbbf8,
+ 0xbc14, 0xbc14,
+ 0xbc30, 0xbc30,
+ 0xbc4c, 0xbc4c,
+ 0xbc68, 0xbc68,
+ 0xbc84, 0xbc84,
+ 0xbca0, 0xbca0,
+ 0xbcbc, 0xbcbc,
+ 0xbcd8, 0xbcd8,
+ 0xbcf4, 0xbcf4,
+ 0xbd10, 0xbd10,
+ 0xbd2c, 0xbd2c,
+ 0xbd48, 0xbd48,
+ 0xbd64, 0xbd64,
+ 0xbd80, 0xbd80,
+ 0xbd9c, 0xbd9c,
+ 0xbdb8, 0xbdb8,
+ 0xbdd4, 0xbdd4,
+ 0xbdf0, 0xbdf0,
+ 0xbe0c, 0xbe0c,
+ 0xbe28, 0xbe28,
+ 0xbe44, 0xbe44,
+ 0xbe60, 0xbe60,
+ 0xbe7c, 0xbe7c,
+ 0xbe98, 0xbe98,
+ 0xbeb4, 0xbeb4,
+ 0xbed0, 0xbed0,
+ 0xbeec, 0xbeec,
+ 0xbf08, 0xbf08,
+ 0xbf24, 0xbf24,
+ 0xbf40, 0xbf40,
+ 0xbf5c, 0xbf5c,
+ 0xbf78, 0xbf78,
+ 0xbf94, 0xbf94,
+ 0xbfb0, 0xbfb0,
+ 0xbfcc, 0xbfcc,
+ 0xbfe8, 0xbfe8,
+ 0xc004, 0xc004,
+ 0xc020, 0xc020,
+ 0xc03c, 0xc03c,
+ 0xc058, 0xc058,
+ 0xc074, 0xc074,
+ 0xc090, 0xc090,
+ 0xc0ac, 0xc0ac,
+ 0xc0c8, 0xc0c8,
+ 0xc0e4, 0xc0e4,
+ 0xc100, 0xc100,
+ 0xc11c, 0xc11c,
+ 0xc138, 0xc138,
+ 0xc154, 0xc154,
+ 0xc170, 0xc170,
+ 0xc18c, 0xc18c,
+ 0xc1a8, 0xc1a8,
+ 0xc1c4, 0xc1c4,
+ 0xc1e0, 0xc1e0,
+ 0xc1fc, 0xc1fc,
+ 0xc218, 0xc218,
+ 0xc234, 0xc234,
+ 0xc250, 0xc250,
+ 0xc26c, 0xc26c,
+ 0xc288, 0xc288,
+ 0xc2a4, 0xc2a4,
+ 0xc2c0, 0xc2c0,
+ 0xc2dc, 0xc2dc,
+ 0xc2f8, 0xc2f8,
+ 0xc314, 0xc314,
+ 0xc330, 0xc330,
+ 0xc34c, 0xc34c,
+ 0xc368, 0xc368,
+ 0xc384, 0xc384,
+ 0xc3a0, 0xc3a0,
+ 0xc3bc, 0xc3bc,
+ 0xc3d8, 0xc3d8,
+ 0xc3f4, 0xc3f4,
+ 0xc410, 0xc410,
+ 0xc42c, 0xc42c,
+ 0xc448, 0xc448,
+ 0xc464, 0xc464,
+ 0xc480, 0xc480,
+ 0xc49c, 0xc49c,
+ 0xc4b8, 0xc4b8,
+ 0xc4d4, 0xc4d4,
+ 0xc4f0, 0xc4f0,
+ 0xc50c, 0xc50c,
+ 0xc528, 0xc528,
+ 0xc544, 0xc544,
+ 0xc560, 0xc560,
+ 0xc57c, 0xc57c,
+ 0xc598, 0xc598,
+ 0xc5b4, 0xc5b4,
+ 0xc5d0, 0xc5d0,
+ 0xc5ec, 0xc5ec,
+ 0xc608, 0xc608,
+ 0xc624, 0xc624,
+ 0xc640, 0xc640,
+ 0xc65c, 0xc65c,
+ 0xc678, 0xc678,
+ 0xc694, 0xc694,
+ 0xc6b0, 0xc6b0,
+ 0xc6cc, 0xc6cc,
+ 0xc6e8, 0xc6e8,
+ 0xc704, 0xc704,
+ 0xc720, 0xc720,
+ 0xc73c, 0xc73c,
+ 0xc758, 0xc758,
+ 0xc774, 0xc774,
+ 0xc790, 0xc790,
+ 0xc7ac, 0xc7ac,
+ 0xc7c8, 0xc7c8,
+ 0xc7e4, 0xc7e4,
+ 0xc800, 0xc800,
+ 0xc81c, 0xc81c,
+ 0xc838, 0xc838,
+ 0xc854, 0xc854,
+ 0xc870, 0xc870,
+ 0xc88c, 0xc88c,
+ 0xc8a8, 0xc8a8,
+ 0xc8c4, 0xc8c4,
+ 0xc8e0, 0xc8e0,
+ 0xc8fc, 0xc8fc,
+ 0xc918, 0xc918,
+ 0xc934, 0xc934,
+ 0xc950, 0xc950,
+ 0xc96c, 0xc96c,
+ 0xc988, 0xc988,
+ 0xc9a4, 0xc9a4,
+ 0xc9c0, 0xc9c0,
+ 0xc9dc, 0xc9dc,
+ 0xc9f8, 0xc9f8,
+ 0xca14, 0xca14,
+ 0xca30, 0xca30,
+ 0xca4c, 0xca4c,
+ 0xca68, 0xca68,
+ 0xca84, 0xca84,
+ 0xcaa0, 0xcaa0,
+ 0xcabc, 0xcabc,
+ 0xcad8, 0xcad8,
+ 0xcaf4, 0xcaf4,
+ 0xcb10, 0xcb10,
+ 0xcb2c, 0xcb2c,
+ 0xcb48, 0xcb48,
+ 0xcb64, 0xcb64,
+ 0xcb80, 0xcb80,
+ 0xcb9c, 0xcb9c,
+ 0xcbb8, 0xcbb8,
+ 0xcbd4, 0xcbd4,
+ 0xcbf0, 0xcbf0,
+ 0xcc0c, 0xcc0c,
+ 0xcc28, 0xcc28,
+ 0xcc44, 0xcc44,
+ 0xcc60, 0xcc60,
+ 0xcc7c, 0xcc7c,
+ 0xcc98, 0xcc98,
+ 0xccb4, 0xccb4,
+ 0xccd0, 0xccd0,
+ 0xccec, 0xccec,
+ 0xcd08, 0xcd08,
+ 0xcd24, 0xcd24,
+ 0xcd40, 0xcd40,
+ 0xcd5c, 0xcd5c,
+ 0xcd78, 0xcd78,
+ 0xcd94, 0xcd94,
+ 0xcdb0, 0xcdb0,
+ 0xcdcc, 0xcdcc,
+ 0xcde8, 0xcde8,
+ 0xce04, 0xce04,
+ 0xce20, 0xce20,
+ 0xce3c, 0xce3c,
+ 0xce58, 0xce58,
+ 0xce74, 0xce74,
+ 0xce90, 0xce90,
+ 0xceac, 0xceac,
+ 0xcec8, 0xcec8,
+ 0xcee4, 0xcee4,
+ 0xcf00, 0xcf00,
+ 0xcf1c, 0xcf1c,
+ 0xcf38, 0xcf38,
+ 0xcf54, 0xcf54,
+ 0xcf70, 0xcf70,
+ 0xcf8c, 0xcf8c,
+ 0xcfa8, 0xcfa8,
+ 0xcfc4, 0xcfc4,
+ 0xcfe0, 0xcfe0,
+ 0xcffc, 0xcffc,
+ 0xd018, 0xd018,
+ 0xd034, 0xd034,
+ 0xd050, 0xd050,
+ 0xd06c, 0xd06c,
+ 0xd088, 0xd088,
+ 0xd0a4, 0xd0a4,
+ 0xd0c0, 0xd0c0,
+ 0xd0dc, 0xd0dc,
+ 0xd0f8, 0xd0f8,
+ 0xd114, 0xd114,
+ 0xd130, 0xd130,
+ 0xd14c, 0xd14c,
+ 0xd168, 0xd168,
+ 0xd184, 0xd184,
+ 0xd1a0, 0xd1a0,
+ 0xd1bc, 0xd1bc,
+ 0xd1d8, 0xd1d8,
+ 0xd1f4, 0xd1f4,
+ 0xd210, 0xd210,
+ 0xd22c, 0xd22c,
+ 0xd248, 0xd248,
+ 0xd264, 0xd264,
+ 0xd280, 0xd280,
+ 0xd29c, 0xd29c,
+ 0xd2b8, 0xd2b8,
+ 0xd2d4, 0xd2d4,
+ 0xd2f0, 0xd2f0,
+ 0xd30c, 0xd30c,
+ 0xd328, 0xd328,
+ 0xd344, 0xd344,
+ 0xd360, 0xd360,
+ 0xd37c, 0xd37c,
+ 0xd398, 0xd398,
+ 0xd3b4, 0xd3b4,
+ 0xd3d0, 0xd3d0,
+ 0xd3ec, 0xd3ec,
+ 0xd408, 0xd408,
+ 0xd424, 0xd424,
+ 0xd440, 0xd440,
+ 0xd45c, 0xd45c,
+ 0xd478, 0xd478,
+ 0xd494, 0xd494,
+ 0xd4b0, 0xd4b0,
+ 0xd4cc, 0xd4cc,
+ 0xd4e8, 0xd4e8,
+ 0xd504, 0xd504,
+ 0xd520, 0xd520,
+ 0xd53c, 0xd53c,
+ 0xd558, 0xd558,
+ 0xd574, 0xd574,
+ 0xd590, 0xd590,
+ 0xd5ac, 0xd5ac,
+ 0xd5c8, 0xd5c8,
+ 0xd5e4, 0xd5e4,
+ 0xd600, 0xd600,
+ 0xd61c, 0xd61c,
+ 0xd638, 0xd638,
+ 0xd654, 0xd654,
+ 0xd670, 0xd670,
+ 0xd68c, 0xd68c,
+ 0xd6a8, 0xd6a8,
+ 0xd6c4, 0xd6c4,
+ 0xd6e0, 0xd6e0,
+ 0xd6fc, 0xd6fc,
+ 0xd718, 0xd718,
+ 0xd734, 0xd734,
+ 0xd750, 0xd750,
+ 0xd76c, 0xd76c,
+ 0xd788, 0xd788,
+}; /* CR_Grapheme_Cluster_Break_LV */
+
+/* 'Grapheme_Cluster_Break_LVT': Grapheme_Cluster_Break=LVT */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_LVT[] = {
+ 399,
+ 0xac01, 0xac1b,
+ 0xac1d, 0xac37,
+ 0xac39, 0xac53,
+ 0xac55, 0xac6f,
+ 0xac71, 0xac8b,
+ 0xac8d, 0xaca7,
+ 0xaca9, 0xacc3,
+ 0xacc5, 0xacdf,
+ 0xace1, 0xacfb,
+ 0xacfd, 0xad17,
+ 0xad19, 0xad33,
+ 0xad35, 0xad4f,
+ 0xad51, 0xad6b,
+ 0xad6d, 0xad87,
+ 0xad89, 0xada3,
+ 0xada5, 0xadbf,
+ 0xadc1, 0xaddb,
+ 0xaddd, 0xadf7,
+ 0xadf9, 0xae13,
+ 0xae15, 0xae2f,
+ 0xae31, 0xae4b,
+ 0xae4d, 0xae67,
+ 0xae69, 0xae83,
+ 0xae85, 0xae9f,
+ 0xaea1, 0xaebb,
+ 0xaebd, 0xaed7,
+ 0xaed9, 0xaef3,
+ 0xaef5, 0xaf0f,
+ 0xaf11, 0xaf2b,
+ 0xaf2d, 0xaf47,
+ 0xaf49, 0xaf63,
+ 0xaf65, 0xaf7f,
+ 0xaf81, 0xaf9b,
+ 0xaf9d, 0xafb7,
+ 0xafb9, 0xafd3,
+ 0xafd5, 0xafef,
+ 0xaff1, 0xb00b,
+ 0xb00d, 0xb027,
+ 0xb029, 0xb043,
+ 0xb045, 0xb05f,
+ 0xb061, 0xb07b,
+ 0xb07d, 0xb097,
+ 0xb099, 0xb0b3,
+ 0xb0b5, 0xb0cf,
+ 0xb0d1, 0xb0eb,
+ 0xb0ed, 0xb107,
+ 0xb109, 0xb123,
+ 0xb125, 0xb13f,
+ 0xb141, 0xb15b,
+ 0xb15d, 0xb177,
+ 0xb179, 0xb193,
+ 0xb195, 0xb1af,
+ 0xb1b1, 0xb1cb,
+ 0xb1cd, 0xb1e7,
+ 0xb1e9, 0xb203,
+ 0xb205, 0xb21f,
+ 0xb221, 0xb23b,
+ 0xb23d, 0xb257,
+ 0xb259, 0xb273,
+ 0xb275, 0xb28f,
+ 0xb291, 0xb2ab,
+ 0xb2ad, 0xb2c7,
+ 0xb2c9, 0xb2e3,
+ 0xb2e5, 0xb2ff,
+ 0xb301, 0xb31b,
+ 0xb31d, 0xb337,
+ 0xb339, 0xb353,
+ 0xb355, 0xb36f,
+ 0xb371, 0xb38b,
+ 0xb38d, 0xb3a7,
+ 0xb3a9, 0xb3c3,
+ 0xb3c5, 0xb3df,
+ 0xb3e1, 0xb3fb,
+ 0xb3fd, 0xb417,
+ 0xb419, 0xb433,
+ 0xb435, 0xb44f,
+ 0xb451, 0xb46b,
+ 0xb46d, 0xb487,
+ 0xb489, 0xb4a3,
+ 0xb4a5, 0xb4bf,
+ 0xb4c1, 0xb4db,
+ 0xb4dd, 0xb4f7,
+ 0xb4f9, 0xb513,
+ 0xb515, 0xb52f,
+ 0xb531, 0xb54b,
+ 0xb54d, 0xb567,
+ 0xb569, 0xb583,
+ 0xb585, 0xb59f,
+ 0xb5a1, 0xb5bb,
+ 0xb5bd, 0xb5d7,
+ 0xb5d9, 0xb5f3,
+ 0xb5f5, 0xb60f,
+ 0xb611, 0xb62b,
+ 0xb62d, 0xb647,
+ 0xb649, 0xb663,
+ 0xb665, 0xb67f,
+ 0xb681, 0xb69b,
+ 0xb69d, 0xb6b7,
+ 0xb6b9, 0xb6d3,
+ 0xb6d5, 0xb6ef,
+ 0xb6f1, 0xb70b,
+ 0xb70d, 0xb727,
+ 0xb729, 0xb743,
+ 0xb745, 0xb75f,
+ 0xb761, 0xb77b,
+ 0xb77d, 0xb797,
+ 0xb799, 0xb7b3,
+ 0xb7b5, 0xb7cf,
+ 0xb7d1, 0xb7eb,
+ 0xb7ed, 0xb807,
+ 0xb809, 0xb823,
+ 0xb825, 0xb83f,
+ 0xb841, 0xb85b,
+ 0xb85d, 0xb877,
+ 0xb879, 0xb893,
+ 0xb895, 0xb8af,
+ 0xb8b1, 0xb8cb,
+ 0xb8cd, 0xb8e7,
+ 0xb8e9, 0xb903,
+ 0xb905, 0xb91f,
+ 0xb921, 0xb93b,
+ 0xb93d, 0xb957,
+ 0xb959, 0xb973,
+ 0xb975, 0xb98f,
+ 0xb991, 0xb9ab,
+ 0xb9ad, 0xb9c7,
+ 0xb9c9, 0xb9e3,
+ 0xb9e5, 0xb9ff,
+ 0xba01, 0xba1b,
+ 0xba1d, 0xba37,
+ 0xba39, 0xba53,
+ 0xba55, 0xba6f,
+ 0xba71, 0xba8b,
+ 0xba8d, 0xbaa7,
+ 0xbaa9, 0xbac3,
+ 0xbac5, 0xbadf,
+ 0xbae1, 0xbafb,
+ 0xbafd, 0xbb17,
+ 0xbb19, 0xbb33,
+ 0xbb35, 0xbb4f,
+ 0xbb51, 0xbb6b,
+ 0xbb6d, 0xbb87,
+ 0xbb89, 0xbba3,
+ 0xbba5, 0xbbbf,
+ 0xbbc1, 0xbbdb,
+ 0xbbdd, 0xbbf7,
+ 0xbbf9, 0xbc13,
+ 0xbc15, 0xbc2f,
+ 0xbc31, 0xbc4b,
+ 0xbc4d, 0xbc67,
+ 0xbc69, 0xbc83,
+ 0xbc85, 0xbc9f,
+ 0xbca1, 0xbcbb,
+ 0xbcbd, 0xbcd7,
+ 0xbcd9, 0xbcf3,
+ 0xbcf5, 0xbd0f,
+ 0xbd11, 0xbd2b,
+ 0xbd2d, 0xbd47,
+ 0xbd49, 0xbd63,
+ 0xbd65, 0xbd7f,
+ 0xbd81, 0xbd9b,
+ 0xbd9d, 0xbdb7,
+ 0xbdb9, 0xbdd3,
+ 0xbdd5, 0xbdef,
+ 0xbdf1, 0xbe0b,
+ 0xbe0d, 0xbe27,
+ 0xbe29, 0xbe43,
+ 0xbe45, 0xbe5f,
+ 0xbe61, 0xbe7b,
+ 0xbe7d, 0xbe97,
+ 0xbe99, 0xbeb3,
+ 0xbeb5, 0xbecf,
+ 0xbed1, 0xbeeb,
+ 0xbeed, 0xbf07,
+ 0xbf09, 0xbf23,
+ 0xbf25, 0xbf3f,
+ 0xbf41, 0xbf5b,
+ 0xbf5d, 0xbf77,
+ 0xbf79, 0xbf93,
+ 0xbf95, 0xbfaf,
+ 0xbfb1, 0xbfcb,
+ 0xbfcd, 0xbfe7,
+ 0xbfe9, 0xc003,
+ 0xc005, 0xc01f,
+ 0xc021, 0xc03b,
+ 0xc03d, 0xc057,
+ 0xc059, 0xc073,
+ 0xc075, 0xc08f,
+ 0xc091, 0xc0ab,
+ 0xc0ad, 0xc0c7,
+ 0xc0c9, 0xc0e3,
+ 0xc0e5, 0xc0ff,
+ 0xc101, 0xc11b,
+ 0xc11d, 0xc137,
+ 0xc139, 0xc153,
+ 0xc155, 0xc16f,
+ 0xc171, 0xc18b,
+ 0xc18d, 0xc1a7,
+ 0xc1a9, 0xc1c3,
+ 0xc1c5, 0xc1df,
+ 0xc1e1, 0xc1fb,
+ 0xc1fd, 0xc217,
+ 0xc219, 0xc233,
+ 0xc235, 0xc24f,
+ 0xc251, 0xc26b,
+ 0xc26d, 0xc287,
+ 0xc289, 0xc2a3,
+ 0xc2a5, 0xc2bf,
+ 0xc2c1, 0xc2db,
+ 0xc2dd, 0xc2f7,
+ 0xc2f9, 0xc313,
+ 0xc315, 0xc32f,
+ 0xc331, 0xc34b,
+ 0xc34d, 0xc367,
+ 0xc369, 0xc383,
+ 0xc385, 0xc39f,
+ 0xc3a1, 0xc3bb,
+ 0xc3bd, 0xc3d7,
+ 0xc3d9, 0xc3f3,
+ 0xc3f5, 0xc40f,
+ 0xc411, 0xc42b,
+ 0xc42d, 0xc447,
+ 0xc449, 0xc463,
+ 0xc465, 0xc47f,
+ 0xc481, 0xc49b,
+ 0xc49d, 0xc4b7,
+ 0xc4b9, 0xc4d3,
+ 0xc4d5, 0xc4ef,
+ 0xc4f1, 0xc50b,
+ 0xc50d, 0xc527,
+ 0xc529, 0xc543,
+ 0xc545, 0xc55f,
+ 0xc561, 0xc57b,
+ 0xc57d, 0xc597,
+ 0xc599, 0xc5b3,
+ 0xc5b5, 0xc5cf,
+ 0xc5d1, 0xc5eb,
+ 0xc5ed, 0xc607,
+ 0xc609, 0xc623,
+ 0xc625, 0xc63f,
+ 0xc641, 0xc65b,
+ 0xc65d, 0xc677,
+ 0xc679, 0xc693,
+ 0xc695, 0xc6af,
+ 0xc6b1, 0xc6cb,
+ 0xc6cd, 0xc6e7,
+ 0xc6e9, 0xc703,
+ 0xc705, 0xc71f,
+ 0xc721, 0xc73b,
+ 0xc73d, 0xc757,
+ 0xc759, 0xc773,
+ 0xc775, 0xc78f,
+ 0xc791, 0xc7ab,
+ 0xc7ad, 0xc7c7,
+ 0xc7c9, 0xc7e3,
+ 0xc7e5, 0xc7ff,
+ 0xc801, 0xc81b,
+ 0xc81d, 0xc837,
+ 0xc839, 0xc853,
+ 0xc855, 0xc86f,
+ 0xc871, 0xc88b,
+ 0xc88d, 0xc8a7,
+ 0xc8a9, 0xc8c3,
+ 0xc8c5, 0xc8df,
+ 0xc8e1, 0xc8fb,
+ 0xc8fd, 0xc917,
+ 0xc919, 0xc933,
+ 0xc935, 0xc94f,
+ 0xc951, 0xc96b,
+ 0xc96d, 0xc987,
+ 0xc989, 0xc9a3,
+ 0xc9a5, 0xc9bf,
+ 0xc9c1, 0xc9db,
+ 0xc9dd, 0xc9f7,
+ 0xc9f9, 0xca13,
+ 0xca15, 0xca2f,
+ 0xca31, 0xca4b,
+ 0xca4d, 0xca67,
+ 0xca69, 0xca83,
+ 0xca85, 0xca9f,
+ 0xcaa1, 0xcabb,
+ 0xcabd, 0xcad7,
+ 0xcad9, 0xcaf3,
+ 0xcaf5, 0xcb0f,
+ 0xcb11, 0xcb2b,
+ 0xcb2d, 0xcb47,
+ 0xcb49, 0xcb63,
+ 0xcb65, 0xcb7f,
+ 0xcb81, 0xcb9b,
+ 0xcb9d, 0xcbb7,
+ 0xcbb9, 0xcbd3,
+ 0xcbd5, 0xcbef,
+ 0xcbf1, 0xcc0b,
+ 0xcc0d, 0xcc27,
+ 0xcc29, 0xcc43,
+ 0xcc45, 0xcc5f,
+ 0xcc61, 0xcc7b,
+ 0xcc7d, 0xcc97,
+ 0xcc99, 0xccb3,
+ 0xccb5, 0xcccf,
+ 0xccd1, 0xcceb,
+ 0xcced, 0xcd07,
+ 0xcd09, 0xcd23,
+ 0xcd25, 0xcd3f,
+ 0xcd41, 0xcd5b,
+ 0xcd5d, 0xcd77,
+ 0xcd79, 0xcd93,
+ 0xcd95, 0xcdaf,
+ 0xcdb1, 0xcdcb,
+ 0xcdcd, 0xcde7,
+ 0xcde9, 0xce03,
+ 0xce05, 0xce1f,
+ 0xce21, 0xce3b,
+ 0xce3d, 0xce57,
+ 0xce59, 0xce73,
+ 0xce75, 0xce8f,
+ 0xce91, 0xceab,
+ 0xcead, 0xcec7,
+ 0xcec9, 0xcee3,
+ 0xcee5, 0xceff,
+ 0xcf01, 0xcf1b,
+ 0xcf1d, 0xcf37,
+ 0xcf39, 0xcf53,
+ 0xcf55, 0xcf6f,
+ 0xcf71, 0xcf8b,
+ 0xcf8d, 0xcfa7,
+ 0xcfa9, 0xcfc3,
+ 0xcfc5, 0xcfdf,
+ 0xcfe1, 0xcffb,
+ 0xcffd, 0xd017,
+ 0xd019, 0xd033,
+ 0xd035, 0xd04f,
+ 0xd051, 0xd06b,
+ 0xd06d, 0xd087,
+ 0xd089, 0xd0a3,
+ 0xd0a5, 0xd0bf,
+ 0xd0c1, 0xd0db,
+ 0xd0dd, 0xd0f7,
+ 0xd0f9, 0xd113,
+ 0xd115, 0xd12f,
+ 0xd131, 0xd14b,
+ 0xd14d, 0xd167,
+ 0xd169, 0xd183,
+ 0xd185, 0xd19f,
+ 0xd1a1, 0xd1bb,
+ 0xd1bd, 0xd1d7,
+ 0xd1d9, 0xd1f3,
+ 0xd1f5, 0xd20f,
+ 0xd211, 0xd22b,
+ 0xd22d, 0xd247,
+ 0xd249, 0xd263,
+ 0xd265, 0xd27f,
+ 0xd281, 0xd29b,
+ 0xd29d, 0xd2b7,
+ 0xd2b9, 0xd2d3,
+ 0xd2d5, 0xd2ef,
+ 0xd2f1, 0xd30b,
+ 0xd30d, 0xd327,
+ 0xd329, 0xd343,
+ 0xd345, 0xd35f,
+ 0xd361, 0xd37b,
+ 0xd37d, 0xd397,
+ 0xd399, 0xd3b3,
+ 0xd3b5, 0xd3cf,
+ 0xd3d1, 0xd3eb,
+ 0xd3ed, 0xd407,
+ 0xd409, 0xd423,
+ 0xd425, 0xd43f,
+ 0xd441, 0xd45b,
+ 0xd45d, 0xd477,
+ 0xd479, 0xd493,
+ 0xd495, 0xd4af,
+ 0xd4b1, 0xd4cb,
+ 0xd4cd, 0xd4e7,
+ 0xd4e9, 0xd503,
+ 0xd505, 0xd51f,
+ 0xd521, 0xd53b,
+ 0xd53d, 0xd557,
+ 0xd559, 0xd573,
+ 0xd575, 0xd58f,
+ 0xd591, 0xd5ab,
+ 0xd5ad, 0xd5c7,
+ 0xd5c9, 0xd5e3,
+ 0xd5e5, 0xd5ff,
+ 0xd601, 0xd61b,
+ 0xd61d, 0xd637,
+ 0xd639, 0xd653,
+ 0xd655, 0xd66f,
+ 0xd671, 0xd68b,
+ 0xd68d, 0xd6a7,
+ 0xd6a9, 0xd6c3,
+ 0xd6c5, 0xd6df,
+ 0xd6e1, 0xd6fb,
+ 0xd6fd, 0xd717,
+ 0xd719, 0xd733,
+ 0xd735, 0xd74f,
+ 0xd751, 0xd76b,
+ 0xd76d, 0xd787,
+ 0xd789, 0xd7a3,
+}; /* CR_Grapheme_Cluster_Break_LVT */
+
+/* 'Grapheme_Cluster_Break_ZWJ': Grapheme_Cluster_Break=ZWJ */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_ZWJ[] = {
+ 1,
+ 0x200d, 0x200d,
+}; /* CR_Grapheme_Cluster_Break_ZWJ */
+
+/* 'In_Basic_Latin': Block */
+#define CR_In_Basic_Latin CR_ASCII
+
+/* 'In_Latin_1_Supplement': Block */
+static const OnigCodePoint CR_In_Latin_1_Supplement[] = {
+ 1,
+ 0x0080, 0x00ff,
+}; /* CR_In_Latin_1_Supplement */
+
+/* 'In_Latin_Extended_A': Block */
+static const OnigCodePoint CR_In_Latin_Extended_A[] = {
+ 1,
+ 0x0100, 0x017f,
+}; /* CR_In_Latin_Extended_A */
+
+/* 'In_Latin_Extended_B': Block */
+static const OnigCodePoint CR_In_Latin_Extended_B[] = {
+ 1,
+ 0x0180, 0x024f,
+}; /* CR_In_Latin_Extended_B */
+
+/* 'In_IPA_Extensions': Block */
+static const OnigCodePoint CR_In_IPA_Extensions[] = {
+ 1,
+ 0x0250, 0x02af,
+}; /* CR_In_IPA_Extensions */
+
+/* 'In_Spacing_Modifier_Letters': Block */
+static const OnigCodePoint CR_In_Spacing_Modifier_Letters[] = {
+ 1,
+ 0x02b0, 0x02ff,
+}; /* CR_In_Spacing_Modifier_Letters */
+
+/* 'In_Combining_Diacritical_Marks': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks[] = {
+ 1,
+ 0x0300, 0x036f,
+}; /* CR_In_Combining_Diacritical_Marks */
+
+/* 'In_Greek_and_Coptic': Block */
+static const OnigCodePoint CR_In_Greek_and_Coptic[] = {
+ 1,
+ 0x0370, 0x03ff,
+}; /* CR_In_Greek_and_Coptic */
+
+/* 'In_Cyrillic': Block */
+static const OnigCodePoint CR_In_Cyrillic[] = {
+ 1,
+ 0x0400, 0x04ff,
+}; /* CR_In_Cyrillic */
+
+/* 'In_Cyrillic_Supplement': Block */
+static const OnigCodePoint CR_In_Cyrillic_Supplement[] = {
+ 1,
+ 0x0500, 0x052f,
+}; /* CR_In_Cyrillic_Supplement */
+
+/* 'In_Armenian': Block */
+static const OnigCodePoint CR_In_Armenian[] = {
+ 1,
+ 0x0530, 0x058f,
+}; /* CR_In_Armenian */
+
+/* 'In_Hebrew': Block */
+static const OnigCodePoint CR_In_Hebrew[] = {
+ 1,
+ 0x0590, 0x05ff,
+}; /* CR_In_Hebrew */
+
+/* 'In_Arabic': Block */
+static const OnigCodePoint CR_In_Arabic[] = {
+ 1,
+ 0x0600, 0x06ff,
+}; /* CR_In_Arabic */
+
+/* 'In_Syriac': Block */
+static const OnigCodePoint CR_In_Syriac[] = {
+ 1,
+ 0x0700, 0x074f,
+}; /* CR_In_Syriac */
+
+/* 'In_Arabic_Supplement': Block */
+static const OnigCodePoint CR_In_Arabic_Supplement[] = {
+ 1,
+ 0x0750, 0x077f,
+}; /* CR_In_Arabic_Supplement */
+
+/* 'In_Thaana': Block */
+static const OnigCodePoint CR_In_Thaana[] = {
+ 1,
+ 0x0780, 0x07bf,
+}; /* CR_In_Thaana */
+
+/* 'In_NKo': Block */
+static const OnigCodePoint CR_In_NKo[] = {
+ 1,
+ 0x07c0, 0x07ff,
+}; /* CR_In_NKo */
+
+/* 'In_Samaritan': Block */
+static const OnigCodePoint CR_In_Samaritan[] = {
+ 1,
+ 0x0800, 0x083f,
+}; /* CR_In_Samaritan */
+
+/* 'In_Mandaic': Block */
+static const OnigCodePoint CR_In_Mandaic[] = {
+ 1,
+ 0x0840, 0x085f,
+}; /* CR_In_Mandaic */
+
+/* 'In_Syriac_Supplement': Block */
+static const OnigCodePoint CR_In_Syriac_Supplement[] = {
+ 1,
+ 0x0860, 0x086f,
+}; /* CR_In_Syriac_Supplement */
+
+/* 'In_Arabic_Extended_A': Block */
+static const OnigCodePoint CR_In_Arabic_Extended_A[] = {
+ 1,
+ 0x08a0, 0x08ff,
+}; /* CR_In_Arabic_Extended_A */
+
+/* 'In_Devanagari': Block */
+static const OnigCodePoint CR_In_Devanagari[] = {
+ 1,
+ 0x0900, 0x097f,
+}; /* CR_In_Devanagari */
+
+/* 'In_Bengali': Block */
+static const OnigCodePoint CR_In_Bengali[] = {
+ 1,
+ 0x0980, 0x09ff,
+}; /* CR_In_Bengali */
+
+/* 'In_Gurmukhi': Block */
+static const OnigCodePoint CR_In_Gurmukhi[] = {
+ 1,
+ 0x0a00, 0x0a7f,
+}; /* CR_In_Gurmukhi */
+
+/* 'In_Gujarati': Block */
+static const OnigCodePoint CR_In_Gujarati[] = {
+ 1,
+ 0x0a80, 0x0aff,
+}; /* CR_In_Gujarati */
+
+/* 'In_Oriya': Block */
+static const OnigCodePoint CR_In_Oriya[] = {
+ 1,
+ 0x0b00, 0x0b7f,
+}; /* CR_In_Oriya */
+
+/* 'In_Tamil': Block */
+static const OnigCodePoint CR_In_Tamil[] = {
+ 1,
+ 0x0b80, 0x0bff,
+}; /* CR_In_Tamil */
+
+/* 'In_Telugu': Block */
+static const OnigCodePoint CR_In_Telugu[] = {
+ 1,
+ 0x0c00, 0x0c7f,
+}; /* CR_In_Telugu */
+
+/* 'In_Kannada': Block */
+static const OnigCodePoint CR_In_Kannada[] = {
+ 1,
+ 0x0c80, 0x0cff,
+}; /* CR_In_Kannada */
+
+/* 'In_Malayalam': Block */
+static const OnigCodePoint CR_In_Malayalam[] = {
+ 1,
+ 0x0d00, 0x0d7f,
+}; /* CR_In_Malayalam */
+
+/* 'In_Sinhala': Block */
+static const OnigCodePoint CR_In_Sinhala[] = {
+ 1,
+ 0x0d80, 0x0dff,
+}; /* CR_In_Sinhala */
+
+/* 'In_Thai': Block */
+static const OnigCodePoint CR_In_Thai[] = {
+ 1,
+ 0x0e00, 0x0e7f,
+}; /* CR_In_Thai */
+
+/* 'In_Lao': Block */
+static const OnigCodePoint CR_In_Lao[] = {
+ 1,
+ 0x0e80, 0x0eff,
+}; /* CR_In_Lao */
+
+/* 'In_Tibetan': Block */
+static const OnigCodePoint CR_In_Tibetan[] = {
+ 1,
+ 0x0f00, 0x0fff,
+}; /* CR_In_Tibetan */
+
+/* 'In_Myanmar': Block */
+static const OnigCodePoint CR_In_Myanmar[] = {
+ 1,
+ 0x1000, 0x109f,
+}; /* CR_In_Myanmar */
+
+/* 'In_Georgian': Block */
+static const OnigCodePoint CR_In_Georgian[] = {
+ 1,
+ 0x10a0, 0x10ff,
+}; /* CR_In_Georgian */
+
+/* 'In_Hangul_Jamo': Block */
+static const OnigCodePoint CR_In_Hangul_Jamo[] = {
+ 1,
+ 0x1100, 0x11ff,
+}; /* CR_In_Hangul_Jamo */
+
+/* 'In_Ethiopic': Block */
+static const OnigCodePoint CR_In_Ethiopic[] = {
+ 1,
+ 0x1200, 0x137f,
+}; /* CR_In_Ethiopic */
+
+/* 'In_Ethiopic_Supplement': Block */
+static const OnigCodePoint CR_In_Ethiopic_Supplement[] = {
+ 1,
+ 0x1380, 0x139f,
+}; /* CR_In_Ethiopic_Supplement */
+
+/* 'In_Cherokee': Block */
+static const OnigCodePoint CR_In_Cherokee[] = {
+ 1,
+ 0x13a0, 0x13ff,
+}; /* CR_In_Cherokee */
+
+/* 'In_Unified_Canadian_Aboriginal_Syllabics': Block */
+static const OnigCodePoint CR_In_Unified_Canadian_Aboriginal_Syllabics[] = {
+ 1,
+ 0x1400, 0x167f,
+}; /* CR_In_Unified_Canadian_Aboriginal_Syllabics */
+
+/* 'In_Ogham': Block */
+static const OnigCodePoint CR_In_Ogham[] = {
+ 1,
+ 0x1680, 0x169f,
+}; /* CR_In_Ogham */
+
+/* 'In_Runic': Block */
+static const OnigCodePoint CR_In_Runic[] = {
+ 1,
+ 0x16a0, 0x16ff,
+}; /* CR_In_Runic */
+
+/* 'In_Tagalog': Block */
+static const OnigCodePoint CR_In_Tagalog[] = {
+ 1,
+ 0x1700, 0x171f,
+}; /* CR_In_Tagalog */
+
+/* 'In_Hanunoo': Block */
+static const OnigCodePoint CR_In_Hanunoo[] = {
+ 1,
+ 0x1720, 0x173f,
+}; /* CR_In_Hanunoo */
+
+/* 'In_Buhid': Block */
+static const OnigCodePoint CR_In_Buhid[] = {
+ 1,
+ 0x1740, 0x175f,
+}; /* CR_In_Buhid */
+
+/* 'In_Tagbanwa': Block */
+static const OnigCodePoint CR_In_Tagbanwa[] = {
+ 1,
+ 0x1760, 0x177f,
+}; /* CR_In_Tagbanwa */
+
+/* 'In_Khmer': Block */
+static const OnigCodePoint CR_In_Khmer[] = {
+ 1,
+ 0x1780, 0x17ff,
+}; /* CR_In_Khmer */
+
+/* 'In_Mongolian': Block */
+static const OnigCodePoint CR_In_Mongolian[] = {
+ 1,
+ 0x1800, 0x18af,
+}; /* CR_In_Mongolian */
+
+/* 'In_Unified_Canadian_Aboriginal_Syllabics_Extended': Block */
+static const OnigCodePoint CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended[] = {
+ 1,
+ 0x18b0, 0x18ff,
+}; /* CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended */
+
+/* 'In_Limbu': Block */
+static const OnigCodePoint CR_In_Limbu[] = {
+ 1,
+ 0x1900, 0x194f,
+}; /* CR_In_Limbu */
+
+/* 'In_Tai_Le': Block */
+static const OnigCodePoint CR_In_Tai_Le[] = {
+ 1,
+ 0x1950, 0x197f,
+}; /* CR_In_Tai_Le */
+
+/* 'In_New_Tai_Lue': Block */
+static const OnigCodePoint CR_In_New_Tai_Lue[] = {
+ 1,
+ 0x1980, 0x19df,
+}; /* CR_In_New_Tai_Lue */
+
+/* 'In_Khmer_Symbols': Block */
+static const OnigCodePoint CR_In_Khmer_Symbols[] = {
+ 1,
+ 0x19e0, 0x19ff,
+}; /* CR_In_Khmer_Symbols */
+
+/* 'In_Buginese': Block */
+static const OnigCodePoint CR_In_Buginese[] = {
+ 1,
+ 0x1a00, 0x1a1f,
+}; /* CR_In_Buginese */
+
+/* 'In_Tai_Tham': Block */
+static const OnigCodePoint CR_In_Tai_Tham[] = {
+ 1,
+ 0x1a20, 0x1aaf,
+}; /* CR_In_Tai_Tham */
+
+/* 'In_Combining_Diacritical_Marks_Extended': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks_Extended[] = {
+ 1,
+ 0x1ab0, 0x1aff,
+}; /* CR_In_Combining_Diacritical_Marks_Extended */
+
+/* 'In_Balinese': Block */
+static const OnigCodePoint CR_In_Balinese[] = {
+ 1,
+ 0x1b00, 0x1b7f,
+}; /* CR_In_Balinese */
+
+/* 'In_Sundanese': Block */
+static const OnigCodePoint CR_In_Sundanese[] = {
+ 1,
+ 0x1b80, 0x1bbf,
+}; /* CR_In_Sundanese */
+
+/* 'In_Batak': Block */
+static const OnigCodePoint CR_In_Batak[] = {
+ 1,
+ 0x1bc0, 0x1bff,
+}; /* CR_In_Batak */
+
+/* 'In_Lepcha': Block */
+static const OnigCodePoint CR_In_Lepcha[] = {
+ 1,
+ 0x1c00, 0x1c4f,
+}; /* CR_In_Lepcha */
+
+/* 'In_Ol_Chiki': Block */
+#define CR_In_Ol_Chiki CR_Ol_Chiki
+
+/* 'In_Cyrillic_Extended_C': Block */
+static const OnigCodePoint CR_In_Cyrillic_Extended_C[] = {
+ 1,
+ 0x1c80, 0x1c8f,
+}; /* CR_In_Cyrillic_Extended_C */
+
+/* 'In_Georgian_Extended': Block */
+static const OnigCodePoint CR_In_Georgian_Extended[] = {
+ 1,
+ 0x1c90, 0x1cbf,
+}; /* CR_In_Georgian_Extended */
+
+/* 'In_Sundanese_Supplement': Block */
+static const OnigCodePoint CR_In_Sundanese_Supplement[] = {
+ 1,
+ 0x1cc0, 0x1ccf,
+}; /* CR_In_Sundanese_Supplement */
+
+/* 'In_Vedic_Extensions': Block */
+static const OnigCodePoint CR_In_Vedic_Extensions[] = {
+ 1,
+ 0x1cd0, 0x1cff,
+}; /* CR_In_Vedic_Extensions */
+
+/* 'In_Phonetic_Extensions': Block */
+static const OnigCodePoint CR_In_Phonetic_Extensions[] = {
+ 1,
+ 0x1d00, 0x1d7f,
+}; /* CR_In_Phonetic_Extensions */
+
+/* 'In_Phonetic_Extensions_Supplement': Block */
+static const OnigCodePoint CR_In_Phonetic_Extensions_Supplement[] = {
+ 1,
+ 0x1d80, 0x1dbf,
+}; /* CR_In_Phonetic_Extensions_Supplement */
+
+/* 'In_Combining_Diacritical_Marks_Supplement': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks_Supplement[] = {
+ 1,
+ 0x1dc0, 0x1dff,
+}; /* CR_In_Combining_Diacritical_Marks_Supplement */
+
+/* 'In_Latin_Extended_Additional': Block */
+static const OnigCodePoint CR_In_Latin_Extended_Additional[] = {
+ 1,
+ 0x1e00, 0x1eff,
+}; /* CR_In_Latin_Extended_Additional */
+
+/* 'In_Greek_Extended': Block */
+static const OnigCodePoint CR_In_Greek_Extended[] = {
+ 1,
+ 0x1f00, 0x1fff,
+}; /* CR_In_Greek_Extended */
+
+/* 'In_General_Punctuation': Block */
+static const OnigCodePoint CR_In_General_Punctuation[] = {
+ 1,
+ 0x2000, 0x206f,
+}; /* CR_In_General_Punctuation */
+
+/* 'In_Superscripts_and_Subscripts': Block */
+static const OnigCodePoint CR_In_Superscripts_and_Subscripts[] = {
+ 1,
+ 0x2070, 0x209f,
+}; /* CR_In_Superscripts_and_Subscripts */
+
+/* 'In_Currency_Symbols': Block */
+static const OnigCodePoint CR_In_Currency_Symbols[] = {
+ 1,
+ 0x20a0, 0x20cf,
+}; /* CR_In_Currency_Symbols */
+
+/* 'In_Combining_Diacritical_Marks_for_Symbols': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks_for_Symbols[] = {
+ 1,
+ 0x20d0, 0x20ff,
+}; /* CR_In_Combining_Diacritical_Marks_for_Symbols */
+
+/* 'In_Letterlike_Symbols': Block */
+static const OnigCodePoint CR_In_Letterlike_Symbols[] = {
+ 1,
+ 0x2100, 0x214f,
+}; /* CR_In_Letterlike_Symbols */
+
+/* 'In_Number_Forms': Block */
+static const OnigCodePoint CR_In_Number_Forms[] = {
+ 1,
+ 0x2150, 0x218f,
+}; /* CR_In_Number_Forms */
+
+/* 'In_Arrows': Block */
+static const OnigCodePoint CR_In_Arrows[] = {
+ 1,
+ 0x2190, 0x21ff,
+}; /* CR_In_Arrows */
+
+/* 'In_Mathematical_Operators': Block */
+static const OnigCodePoint CR_In_Mathematical_Operators[] = {
+ 1,
+ 0x2200, 0x22ff,
+}; /* CR_In_Mathematical_Operators */
+
+/* 'In_Miscellaneous_Technical': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Technical[] = {
+ 1,
+ 0x2300, 0x23ff,
+}; /* CR_In_Miscellaneous_Technical */
+
+/* 'In_Control_Pictures': Block */
+static const OnigCodePoint CR_In_Control_Pictures[] = {
+ 1,
+ 0x2400, 0x243f,
+}; /* CR_In_Control_Pictures */
+
+/* 'In_Optical_Character_Recognition': Block */
+static const OnigCodePoint CR_In_Optical_Character_Recognition[] = {
+ 1,
+ 0x2440, 0x245f,
+}; /* CR_In_Optical_Character_Recognition */
+
+/* 'In_Enclosed_Alphanumerics': Block */
+static const OnigCodePoint CR_In_Enclosed_Alphanumerics[] = {
+ 1,
+ 0x2460, 0x24ff,
+}; /* CR_In_Enclosed_Alphanumerics */
+
+/* 'In_Box_Drawing': Block */
+static const OnigCodePoint CR_In_Box_Drawing[] = {
+ 1,
+ 0x2500, 0x257f,
+}; /* CR_In_Box_Drawing */
+
+/* 'In_Block_Elements': Block */
+static const OnigCodePoint CR_In_Block_Elements[] = {
+ 1,
+ 0x2580, 0x259f,
+}; /* CR_In_Block_Elements */
+
+/* 'In_Geometric_Shapes': Block */
+static const OnigCodePoint CR_In_Geometric_Shapes[] = {
+ 1,
+ 0x25a0, 0x25ff,
+}; /* CR_In_Geometric_Shapes */
+
+/* 'In_Miscellaneous_Symbols': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Symbols[] = {
+ 1,
+ 0x2600, 0x26ff,
+}; /* CR_In_Miscellaneous_Symbols */
+
+/* 'In_Dingbats': Block */
+static const OnigCodePoint CR_In_Dingbats[] = {
+ 1,
+ 0x2700, 0x27bf,
+}; /* CR_In_Dingbats */
+
+/* 'In_Miscellaneous_Mathematical_Symbols_A': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Mathematical_Symbols_A[] = {
+ 1,
+ 0x27c0, 0x27ef,
+}; /* CR_In_Miscellaneous_Mathematical_Symbols_A */
+
+/* 'In_Supplemental_Arrows_A': Block */
+static const OnigCodePoint CR_In_Supplemental_Arrows_A[] = {
+ 1,
+ 0x27f0, 0x27ff,
+}; /* CR_In_Supplemental_Arrows_A */
+
+/* 'In_Braille_Patterns': Block */
+#define CR_In_Braille_Patterns CR_Braille
+
+/* 'In_Supplemental_Arrows_B': Block */
+static const OnigCodePoint CR_In_Supplemental_Arrows_B[] = {
+ 1,
+ 0x2900, 0x297f,
+}; /* CR_In_Supplemental_Arrows_B */
+
+/* 'In_Miscellaneous_Mathematical_Symbols_B': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Mathematical_Symbols_B[] = {
+ 1,
+ 0x2980, 0x29ff,
+}; /* CR_In_Miscellaneous_Mathematical_Symbols_B */
+
+/* 'In_Supplemental_Mathematical_Operators': Block */
+static const OnigCodePoint CR_In_Supplemental_Mathematical_Operators[] = {
+ 1,
+ 0x2a00, 0x2aff,
+}; /* CR_In_Supplemental_Mathematical_Operators */
+
+/* 'In_Miscellaneous_Symbols_and_Arrows': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Symbols_and_Arrows[] = {
+ 1,
+ 0x2b00, 0x2bff,
+}; /* CR_In_Miscellaneous_Symbols_and_Arrows */
+
+/* 'In_Glagolitic': Block */
+static const OnigCodePoint CR_In_Glagolitic[] = {
+ 1,
+ 0x2c00, 0x2c5f,
+}; /* CR_In_Glagolitic */
+
+/* 'In_Latin_Extended_C': Block */
+static const OnigCodePoint CR_In_Latin_Extended_C[] = {
+ 1,
+ 0x2c60, 0x2c7f,
+}; /* CR_In_Latin_Extended_C */
+
+/* 'In_Coptic': Block */
+static const OnigCodePoint CR_In_Coptic[] = {
+ 1,
+ 0x2c80, 0x2cff,
+}; /* CR_In_Coptic */
+
+/* 'In_Georgian_Supplement': Block */
+static const OnigCodePoint CR_In_Georgian_Supplement[] = {
+ 1,
+ 0x2d00, 0x2d2f,
+}; /* CR_In_Georgian_Supplement */
+
+/* 'In_Tifinagh': Block */
+static const OnigCodePoint CR_In_Tifinagh[] = {
+ 1,
+ 0x2d30, 0x2d7f,
+}; /* CR_In_Tifinagh */
+
+/* 'In_Ethiopic_Extended': Block */
+static const OnigCodePoint CR_In_Ethiopic_Extended[] = {
+ 1,
+ 0x2d80, 0x2ddf,
+}; /* CR_In_Ethiopic_Extended */
+
+/* 'In_Cyrillic_Extended_A': Block */
+static const OnigCodePoint CR_In_Cyrillic_Extended_A[] = {
+ 1,
+ 0x2de0, 0x2dff,
+}; /* CR_In_Cyrillic_Extended_A */
+
+/* 'In_Supplemental_Punctuation': Block */
+static const OnigCodePoint CR_In_Supplemental_Punctuation[] = {
+ 1,
+ 0x2e00, 0x2e7f,
+}; /* CR_In_Supplemental_Punctuation */
+
+/* 'In_CJK_Radicals_Supplement': Block */
+static const OnigCodePoint CR_In_CJK_Radicals_Supplement[] = {
+ 1,
+ 0x2e80, 0x2eff,
+}; /* CR_In_CJK_Radicals_Supplement */
+
+/* 'In_Kangxi_Radicals': Block */
+static const OnigCodePoint CR_In_Kangxi_Radicals[] = {
+ 1,
+ 0x2f00, 0x2fdf,
+}; /* CR_In_Kangxi_Radicals */
+
+/* 'In_Ideographic_Description_Characters': Block */
+static const OnigCodePoint CR_In_Ideographic_Description_Characters[] = {
+ 1,
+ 0x2ff0, 0x2fff,
+}; /* CR_In_Ideographic_Description_Characters */
+
+/* 'In_CJK_Symbols_and_Punctuation': Block */
+static const OnigCodePoint CR_In_CJK_Symbols_and_Punctuation[] = {
+ 1,
+ 0x3000, 0x303f,
+}; /* CR_In_CJK_Symbols_and_Punctuation */
+
+/* 'In_Hiragana': Block */
+static const OnigCodePoint CR_In_Hiragana[] = {
+ 1,
+ 0x3040, 0x309f,
+}; /* CR_In_Hiragana */
+
+/* 'In_Katakana': Block */
+static const OnigCodePoint CR_In_Katakana[] = {
+ 1,
+ 0x30a0, 0x30ff,
+}; /* CR_In_Katakana */
+
+/* 'In_Bopomofo': Block */
+static const OnigCodePoint CR_In_Bopomofo[] = {
+ 1,
+ 0x3100, 0x312f,
+}; /* CR_In_Bopomofo */
+
+/* 'In_Hangul_Compatibility_Jamo': Block */
+static const OnigCodePoint CR_In_Hangul_Compatibility_Jamo[] = {
+ 1,
+ 0x3130, 0x318f,
+}; /* CR_In_Hangul_Compatibility_Jamo */
+
+/* 'In_Kanbun': Block */
+static const OnigCodePoint CR_In_Kanbun[] = {
+ 1,
+ 0x3190, 0x319f,
+}; /* CR_In_Kanbun */
+
+/* 'In_Bopomofo_Extended': Block */
+static const OnigCodePoint CR_In_Bopomofo_Extended[] = {
+ 1,
+ 0x31a0, 0x31bf,
+}; /* CR_In_Bopomofo_Extended */
+
+/* 'In_CJK_Strokes': Block */
+static const OnigCodePoint CR_In_CJK_Strokes[] = {
+ 1,
+ 0x31c0, 0x31ef,
+}; /* CR_In_CJK_Strokes */
+
+/* 'In_Katakana_Phonetic_Extensions': Block */
+static const OnigCodePoint CR_In_Katakana_Phonetic_Extensions[] = {
+ 1,
+ 0x31f0, 0x31ff,
+}; /* CR_In_Katakana_Phonetic_Extensions */
+
+/* 'In_Enclosed_CJK_Letters_and_Months': Block */
+static const OnigCodePoint CR_In_Enclosed_CJK_Letters_and_Months[] = {
+ 1,
+ 0x3200, 0x32ff,
+}; /* CR_In_Enclosed_CJK_Letters_and_Months */
+
+/* 'In_CJK_Compatibility': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility[] = {
+ 1,
+ 0x3300, 0x33ff,
+}; /* CR_In_CJK_Compatibility */
+
+/* 'In_CJK_Unified_Ideographs_Extension_A': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_A[] = {
+ 1,
+ 0x3400, 0x4dbf,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_A */
+
+/* 'In_Yijing_Hexagram_Symbols': Block */
+static const OnigCodePoint CR_In_Yijing_Hexagram_Symbols[] = {
+ 1,
+ 0x4dc0, 0x4dff,
+}; /* CR_In_Yijing_Hexagram_Symbols */
+
+/* 'In_CJK_Unified_Ideographs': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs[] = {
+ 1,
+ 0x4e00, 0x9fff,
+}; /* CR_In_CJK_Unified_Ideographs */
+
+/* 'In_Yi_Syllables': Block */
+static const OnigCodePoint CR_In_Yi_Syllables[] = {
+ 1,
+ 0xa000, 0xa48f,
+}; /* CR_In_Yi_Syllables */
+
+/* 'In_Yi_Radicals': Block */
+static const OnigCodePoint CR_In_Yi_Radicals[] = {
+ 1,
+ 0xa490, 0xa4cf,
+}; /* CR_In_Yi_Radicals */
+
+/* 'In_Lisu': Block */
+#define CR_In_Lisu CR_Lisu
+
+/* 'In_Vai': Block */
+static const OnigCodePoint CR_In_Vai[] = {
+ 1,
+ 0xa500, 0xa63f,
+}; /* CR_In_Vai */
+
+/* 'In_Cyrillic_Extended_B': Block */
+static const OnigCodePoint CR_In_Cyrillic_Extended_B[] = {
+ 1,
+ 0xa640, 0xa69f,
+}; /* CR_In_Cyrillic_Extended_B */
+
+/* 'In_Bamum': Block */
+static const OnigCodePoint CR_In_Bamum[] = {
+ 1,
+ 0xa6a0, 0xa6ff,
+}; /* CR_In_Bamum */
+
+/* 'In_Modifier_Tone_Letters': Block */
+static const OnigCodePoint CR_In_Modifier_Tone_Letters[] = {
+ 1,
+ 0xa700, 0xa71f,
+}; /* CR_In_Modifier_Tone_Letters */
+
+/* 'In_Latin_Extended_D': Block */
+static const OnigCodePoint CR_In_Latin_Extended_D[] = {
+ 1,
+ 0xa720, 0xa7ff,
+}; /* CR_In_Latin_Extended_D */
+
+/* 'In_Syloti_Nagri': Block */
+static const OnigCodePoint CR_In_Syloti_Nagri[] = {
+ 1,
+ 0xa800, 0xa82f,
+}; /* CR_In_Syloti_Nagri */
+
+/* 'In_Common_Indic_Number_Forms': Block */
+static const OnigCodePoint CR_In_Common_Indic_Number_Forms[] = {
+ 1,
+ 0xa830, 0xa83f,
+}; /* CR_In_Common_Indic_Number_Forms */
+
+/* 'In_Phags_pa': Block */
+static const OnigCodePoint CR_In_Phags_pa[] = {
+ 1,
+ 0xa840, 0xa87f,
+}; /* CR_In_Phags_pa */
+
+/* 'In_Saurashtra': Block */
+static const OnigCodePoint CR_In_Saurashtra[] = {
+ 1,
+ 0xa880, 0xa8df,
+}; /* CR_In_Saurashtra */
+
+/* 'In_Devanagari_Extended': Block */
+static const OnigCodePoint CR_In_Devanagari_Extended[] = {
+ 1,
+ 0xa8e0, 0xa8ff,
+}; /* CR_In_Devanagari_Extended */
+
+/* 'In_Kayah_Li': Block */
+static const OnigCodePoint CR_In_Kayah_Li[] = {
+ 1,
+ 0xa900, 0xa92f,
+}; /* CR_In_Kayah_Li */
+
+/* 'In_Rejang': Block */
+static const OnigCodePoint CR_In_Rejang[] = {
+ 1,
+ 0xa930, 0xa95f,
+}; /* CR_In_Rejang */
+
+/* 'In_Hangul_Jamo_Extended_A': Block */
+static const OnigCodePoint CR_In_Hangul_Jamo_Extended_A[] = {
+ 1,
+ 0xa960, 0xa97f,
+}; /* CR_In_Hangul_Jamo_Extended_A */
+
+/* 'In_Javanese': Block */
+static const OnigCodePoint CR_In_Javanese[] = {
+ 1,
+ 0xa980, 0xa9df,
+}; /* CR_In_Javanese */
+
+/* 'In_Myanmar_Extended_B': Block */
+static const OnigCodePoint CR_In_Myanmar_Extended_B[] = {
+ 1,
+ 0xa9e0, 0xa9ff,
+}; /* CR_In_Myanmar_Extended_B */
+
+/* 'In_Cham': Block */
+static const OnigCodePoint CR_In_Cham[] = {
+ 1,
+ 0xaa00, 0xaa5f,
+}; /* CR_In_Cham */
+
+/* 'In_Myanmar_Extended_A': Block */
+static const OnigCodePoint CR_In_Myanmar_Extended_A[] = {
+ 1,
+ 0xaa60, 0xaa7f,
+}; /* CR_In_Myanmar_Extended_A */
+
+/* 'In_Tai_Viet': Block */
+static const OnigCodePoint CR_In_Tai_Viet[] = {
+ 1,
+ 0xaa80, 0xaadf,
+}; /* CR_In_Tai_Viet */
+
+/* 'In_Meetei_Mayek_Extensions': Block */
+static const OnigCodePoint CR_In_Meetei_Mayek_Extensions[] = {
+ 1,
+ 0xaae0, 0xaaff,
+}; /* CR_In_Meetei_Mayek_Extensions */
+
+/* 'In_Ethiopic_Extended_A': Block */
+static const OnigCodePoint CR_In_Ethiopic_Extended_A[] = {
+ 1,
+ 0xab00, 0xab2f,
+}; /* CR_In_Ethiopic_Extended_A */
+
+/* 'In_Latin_Extended_E': Block */
+static const OnigCodePoint CR_In_Latin_Extended_E[] = {
+ 1,
+ 0xab30, 0xab6f,
+}; /* CR_In_Latin_Extended_E */
+
+/* 'In_Cherokee_Supplement': Block */
+static const OnigCodePoint CR_In_Cherokee_Supplement[] = {
+ 1,
+ 0xab70, 0xabbf,
+}; /* CR_In_Cherokee_Supplement */
+
+/* 'In_Meetei_Mayek': Block */
+static const OnigCodePoint CR_In_Meetei_Mayek[] = {
+ 1,
+ 0xabc0, 0xabff,
+}; /* CR_In_Meetei_Mayek */
+
+/* 'In_Hangul_Syllables': Block */
+static const OnigCodePoint CR_In_Hangul_Syllables[] = {
+ 1,
+ 0xac00, 0xd7af,
+}; /* CR_In_Hangul_Syllables */
+
+/* 'In_Hangul_Jamo_Extended_B': Block */
+static const OnigCodePoint CR_In_Hangul_Jamo_Extended_B[] = {
+ 1,
+ 0xd7b0, 0xd7ff,
+}; /* CR_In_Hangul_Jamo_Extended_B */
+
+/* 'In_High_Surrogates': Block */
+static const OnigCodePoint CR_In_High_Surrogates[] = {
+ 1,
+ 0xd800, 0xdb7f,
+}; /* CR_In_High_Surrogates */
+
+/* 'In_High_Private_Use_Surrogates': Block */
+static const OnigCodePoint CR_In_High_Private_Use_Surrogates[] = {
+ 1,
+ 0xdb80, 0xdbff,
+}; /* CR_In_High_Private_Use_Surrogates */
+
+/* 'In_Low_Surrogates': Block */
+static const OnigCodePoint CR_In_Low_Surrogates[] = {
+ 1,
+ 0xdc00, 0xdfff,
+}; /* CR_In_Low_Surrogates */
+
+/* 'In_Private_Use_Area': Block */
+static const OnigCodePoint CR_In_Private_Use_Area[] = {
+ 1,
+ 0xe000, 0xf8ff,
+}; /* CR_In_Private_Use_Area */
+
+/* 'In_CJK_Compatibility_Ideographs': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility_Ideographs[] = {
+ 1,
+ 0xf900, 0xfaff,
+}; /* CR_In_CJK_Compatibility_Ideographs */
+
+/* 'In_Alphabetic_Presentation_Forms': Block */
+static const OnigCodePoint CR_In_Alphabetic_Presentation_Forms[] = {
+ 1,
+ 0xfb00, 0xfb4f,
+}; /* CR_In_Alphabetic_Presentation_Forms */
+
+/* 'In_Arabic_Presentation_Forms_A': Block */
+static const OnigCodePoint CR_In_Arabic_Presentation_Forms_A[] = {
+ 1,
+ 0xfb50, 0xfdff,
+}; /* CR_In_Arabic_Presentation_Forms_A */
+
+/* 'In_Variation_Selectors': Block */
+static const OnigCodePoint CR_In_Variation_Selectors[] = {
+ 1,
+ 0xfe00, 0xfe0f,
+}; /* CR_In_Variation_Selectors */
+
+/* 'In_Vertical_Forms': Block */
+static const OnigCodePoint CR_In_Vertical_Forms[] = {
+ 1,
+ 0xfe10, 0xfe1f,
+}; /* CR_In_Vertical_Forms */
+
+/* 'In_Combining_Half_Marks': Block */
+static const OnigCodePoint CR_In_Combining_Half_Marks[] = {
+ 1,
+ 0xfe20, 0xfe2f,
+}; /* CR_In_Combining_Half_Marks */
+
+/* 'In_CJK_Compatibility_Forms': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility_Forms[] = {
+ 1,
+ 0xfe30, 0xfe4f,
+}; /* CR_In_CJK_Compatibility_Forms */
+
+/* 'In_Small_Form_Variants': Block */
+static const OnigCodePoint CR_In_Small_Form_Variants[] = {
+ 1,
+ 0xfe50, 0xfe6f,
+}; /* CR_In_Small_Form_Variants */
+
+/* 'In_Arabic_Presentation_Forms_B': Block */
+static const OnigCodePoint CR_In_Arabic_Presentation_Forms_B[] = {
+ 1,
+ 0xfe70, 0xfeff,
+}; /* CR_In_Arabic_Presentation_Forms_B */
+
+/* 'In_Halfwidth_and_Fullwidth_Forms': Block */
+static const OnigCodePoint CR_In_Halfwidth_and_Fullwidth_Forms[] = {
+ 1,
+ 0xff00, 0xffef,
+}; /* CR_In_Halfwidth_and_Fullwidth_Forms */
+
+/* 'In_Specials': Block */
+static const OnigCodePoint CR_In_Specials[] = {
+ 1,
+ 0xfff0, 0xffff,
+}; /* CR_In_Specials */
+
+/* 'In_Linear_B_Syllabary': Block */
+static const OnigCodePoint CR_In_Linear_B_Syllabary[] = {
+ 1,
+ 0x10000, 0x1007f,
+}; /* CR_In_Linear_B_Syllabary */
+
+/* 'In_Linear_B_Ideograms': Block */
+static const OnigCodePoint CR_In_Linear_B_Ideograms[] = {
+ 1,
+ 0x10080, 0x100ff,
+}; /* CR_In_Linear_B_Ideograms */
+
+/* 'In_Aegean_Numbers': Block */
+static const OnigCodePoint CR_In_Aegean_Numbers[] = {
+ 1,
+ 0x10100, 0x1013f,
+}; /* CR_In_Aegean_Numbers */
+
+/* 'In_Ancient_Greek_Numbers': Block */
+static const OnigCodePoint CR_In_Ancient_Greek_Numbers[] = {
+ 1,
+ 0x10140, 0x1018f,
+}; /* CR_In_Ancient_Greek_Numbers */
+
+/* 'In_Ancient_Symbols': Block */
+static const OnigCodePoint CR_In_Ancient_Symbols[] = {
+ 1,
+ 0x10190, 0x101cf,
+}; /* CR_In_Ancient_Symbols */
+
+/* 'In_Phaistos_Disc': Block */
+static const OnigCodePoint CR_In_Phaistos_Disc[] = {
+ 1,
+ 0x101d0, 0x101ff,
+}; /* CR_In_Phaistos_Disc */
+
+/* 'In_Lycian': Block */
+static const OnigCodePoint CR_In_Lycian[] = {
+ 1,
+ 0x10280, 0x1029f,
+}; /* CR_In_Lycian */
+
+/* 'In_Carian': Block */
+static const OnigCodePoint CR_In_Carian[] = {
+ 1,
+ 0x102a0, 0x102df,
+}; /* CR_In_Carian */
+
+/* 'In_Coptic_Epact_Numbers': Block */
+static const OnigCodePoint CR_In_Coptic_Epact_Numbers[] = {
+ 1,
+ 0x102e0, 0x102ff,
+}; /* CR_In_Coptic_Epact_Numbers */
+
+/* 'In_Old_Italic': Block */
+static const OnigCodePoint CR_In_Old_Italic[] = {
+ 1,
+ 0x10300, 0x1032f,
+}; /* CR_In_Old_Italic */
+
+/* 'In_Gothic': Block */
+static const OnigCodePoint CR_In_Gothic[] = {
+ 1,
+ 0x10330, 0x1034f,
+}; /* CR_In_Gothic */
+
+/* 'In_Old_Permic': Block */
+static const OnigCodePoint CR_In_Old_Permic[] = {
+ 1,
+ 0x10350, 0x1037f,
+}; /* CR_In_Old_Permic */
+
+/* 'In_Ugaritic': Block */
+static const OnigCodePoint CR_In_Ugaritic[] = {
+ 1,
+ 0x10380, 0x1039f,
+}; /* CR_In_Ugaritic */
+
+/* 'In_Old_Persian': Block */
+static const OnigCodePoint CR_In_Old_Persian[] = {
+ 1,
+ 0x103a0, 0x103df,
+}; /* CR_In_Old_Persian */
+
+/* 'In_Deseret': Block */
+#define CR_In_Deseret CR_Deseret
+
+/* 'In_Shavian': Block */
+#define CR_In_Shavian CR_Shavian
+
+/* 'In_Osmanya': Block */
+static const OnigCodePoint CR_In_Osmanya[] = {
+ 1,
+ 0x10480, 0x104af,
+}; /* CR_In_Osmanya */
+
+/* 'In_Osage': Block */
+static const OnigCodePoint CR_In_Osage[] = {
+ 1,
+ 0x104b0, 0x104ff,
+}; /* CR_In_Osage */
+
+/* 'In_Elbasan': Block */
+static const OnigCodePoint CR_In_Elbasan[] = {
+ 1,
+ 0x10500, 0x1052f,
+}; /* CR_In_Elbasan */
+
+/* 'In_Caucasian_Albanian': Block */
+static const OnigCodePoint CR_In_Caucasian_Albanian[] = {
+ 1,
+ 0x10530, 0x1056f,
+}; /* CR_In_Caucasian_Albanian */
+
+/* 'In_Linear_A': Block */
+static const OnigCodePoint CR_In_Linear_A[] = {
+ 1,
+ 0x10600, 0x1077f,
+}; /* CR_In_Linear_A */
+
+/* 'In_Cypriot_Syllabary': Block */
+static const OnigCodePoint CR_In_Cypriot_Syllabary[] = {
+ 1,
+ 0x10800, 0x1083f,
+}; /* CR_In_Cypriot_Syllabary */
+
+/* 'In_Imperial_Aramaic': Block */
+static const OnigCodePoint CR_In_Imperial_Aramaic[] = {
+ 1,
+ 0x10840, 0x1085f,
+}; /* CR_In_Imperial_Aramaic */
+
+/* 'In_Palmyrene': Block */
+#define CR_In_Palmyrene CR_Palmyrene
+
+/* 'In_Nabataean': Block */
+static const OnigCodePoint CR_In_Nabataean[] = {
+ 1,
+ 0x10880, 0x108af,
+}; /* CR_In_Nabataean */
+
+/* 'In_Hatran': Block */
+static const OnigCodePoint CR_In_Hatran[] = {
+ 1,
+ 0x108e0, 0x108ff,
+}; /* CR_In_Hatran */
+
+/* 'In_Phoenician': Block */
+static const OnigCodePoint CR_In_Phoenician[] = {
+ 1,
+ 0x10900, 0x1091f,
+}; /* CR_In_Phoenician */
+
+/* 'In_Lydian': Block */
+static const OnigCodePoint CR_In_Lydian[] = {
+ 1,
+ 0x10920, 0x1093f,
+}; /* CR_In_Lydian */
+
+/* 'In_Meroitic_Hieroglyphs': Block */
+#define CR_In_Meroitic_Hieroglyphs CR_Meroitic_Hieroglyphs
+
+/* 'In_Meroitic_Cursive': Block */
+static const OnigCodePoint CR_In_Meroitic_Cursive[] = {
+ 1,
+ 0x109a0, 0x109ff,
+}; /* CR_In_Meroitic_Cursive */
+
+/* 'In_Kharoshthi': Block */
+static const OnigCodePoint CR_In_Kharoshthi[] = {
+ 1,
+ 0x10a00, 0x10a5f,
+}; /* CR_In_Kharoshthi */
+
+/* 'In_Old_South_Arabian': Block */
+#define CR_In_Old_South_Arabian CR_Old_South_Arabian
+
+/* 'In_Old_North_Arabian': Block */
+#define CR_In_Old_North_Arabian CR_Old_North_Arabian
+
+/* 'In_Manichaean': Block */
+static const OnigCodePoint CR_In_Manichaean[] = {
+ 1,
+ 0x10ac0, 0x10aff,
+}; /* CR_In_Manichaean */
+
+/* 'In_Avestan': Block */
+static const OnigCodePoint CR_In_Avestan[] = {
+ 1,
+ 0x10b00, 0x10b3f,
+}; /* CR_In_Avestan */
+
+/* 'In_Inscriptional_Parthian': Block */
+static const OnigCodePoint CR_In_Inscriptional_Parthian[] = {
+ 1,
+ 0x10b40, 0x10b5f,
+}; /* CR_In_Inscriptional_Parthian */
+
+/* 'In_Inscriptional_Pahlavi': Block */
+static const OnigCodePoint CR_In_Inscriptional_Pahlavi[] = {
+ 1,
+ 0x10b60, 0x10b7f,
+}; /* CR_In_Inscriptional_Pahlavi */
+
+/* 'In_Psalter_Pahlavi': Block */
+static const OnigCodePoint CR_In_Psalter_Pahlavi[] = {
+ 1,
+ 0x10b80, 0x10baf,
+}; /* CR_In_Psalter_Pahlavi */
+
+/* 'In_Old_Turkic': Block */
+static const OnigCodePoint CR_In_Old_Turkic[] = {
+ 1,
+ 0x10c00, 0x10c4f,
+}; /* CR_In_Old_Turkic */
+
+/* 'In_Old_Hungarian': Block */
+static const OnigCodePoint CR_In_Old_Hungarian[] = {
+ 1,
+ 0x10c80, 0x10cff,
+}; /* CR_In_Old_Hungarian */
+
+/* 'In_Hanifi_Rohingya': Block */
+static const OnigCodePoint CR_In_Hanifi_Rohingya[] = {
+ 1,
+ 0x10d00, 0x10d3f,
+}; /* CR_In_Hanifi_Rohingya */
+
+/* 'In_Rumi_Numeral_Symbols': Block */
+static const OnigCodePoint CR_In_Rumi_Numeral_Symbols[] = {
+ 1,
+ 0x10e60, 0x10e7f,
+}; /* CR_In_Rumi_Numeral_Symbols */
+
+/* 'In_Old_Sogdian': Block */
+static const OnigCodePoint CR_In_Old_Sogdian[] = {
+ 1,
+ 0x10f00, 0x10f2f,
+}; /* CR_In_Old_Sogdian */
+
+/* 'In_Sogdian': Block */
+static const OnigCodePoint CR_In_Sogdian[] = {
+ 1,
+ 0x10f30, 0x10f6f,
+}; /* CR_In_Sogdian */
+
+/* 'In_Elymaic': Block */
+static const OnigCodePoint CR_In_Elymaic[] = {
+ 1,
+ 0x10fe0, 0x10fff,
+}; /* CR_In_Elymaic */
+
+/* 'In_Brahmi': Block */
+static const OnigCodePoint CR_In_Brahmi[] = {
+ 1,
+ 0x11000, 0x1107f,
+}; /* CR_In_Brahmi */
+
+/* 'In_Kaithi': Block */
+static const OnigCodePoint CR_In_Kaithi[] = {
+ 1,
+ 0x11080, 0x110cf,
+}; /* CR_In_Kaithi */
+
+/* 'In_Sora_Sompeng': Block */
+static const OnigCodePoint CR_In_Sora_Sompeng[] = {
+ 1,
+ 0x110d0, 0x110ff,
+}; /* CR_In_Sora_Sompeng */
+
+/* 'In_Chakma': Block */
+static const OnigCodePoint CR_In_Chakma[] = {
+ 1,
+ 0x11100, 0x1114f,
+}; /* CR_In_Chakma */
+
+/* 'In_Mahajani': Block */
+static const OnigCodePoint CR_In_Mahajani[] = {
+ 1,
+ 0x11150, 0x1117f,
+}; /* CR_In_Mahajani */
+
+/* 'In_Sharada': Block */
+static const OnigCodePoint CR_In_Sharada[] = {
+ 1,
+ 0x11180, 0x111df,
+}; /* CR_In_Sharada */
+
+/* 'In_Sinhala_Archaic_Numbers': Block */
+static const OnigCodePoint CR_In_Sinhala_Archaic_Numbers[] = {
+ 1,
+ 0x111e0, 0x111ff,
+}; /* CR_In_Sinhala_Archaic_Numbers */
+
+/* 'In_Khojki': Block */
+static const OnigCodePoint CR_In_Khojki[] = {
+ 1,
+ 0x11200, 0x1124f,
+}; /* CR_In_Khojki */
+
+/* 'In_Multani': Block */
+static const OnigCodePoint CR_In_Multani[] = {
+ 1,
+ 0x11280, 0x112af,
+}; /* CR_In_Multani */
+
+/* 'In_Khudawadi': Block */
+static const OnigCodePoint CR_In_Khudawadi[] = {
+ 1,
+ 0x112b0, 0x112ff,
+}; /* CR_In_Khudawadi */
+
+/* 'In_Grantha': Block */
+static const OnigCodePoint CR_In_Grantha[] = {
+ 1,
+ 0x11300, 0x1137f,
+}; /* CR_In_Grantha */
+
+/* 'In_Newa': Block */
+static const OnigCodePoint CR_In_Newa[] = {
+ 1,
+ 0x11400, 0x1147f,
+}; /* CR_In_Newa */
+
+/* 'In_Tirhuta': Block */
+static const OnigCodePoint CR_In_Tirhuta[] = {
+ 1,
+ 0x11480, 0x114df,
+}; /* CR_In_Tirhuta */
+
+/* 'In_Siddham': Block */
+static const OnigCodePoint CR_In_Siddham[] = {
+ 1,
+ 0x11580, 0x115ff,
+}; /* CR_In_Siddham */
+
+/* 'In_Modi': Block */
+static const OnigCodePoint CR_In_Modi[] = {
+ 1,
+ 0x11600, 0x1165f,
+}; /* CR_In_Modi */
+
+/* 'In_Mongolian_Supplement': Block */
+static const OnigCodePoint CR_In_Mongolian_Supplement[] = {
+ 1,
+ 0x11660, 0x1167f,
+}; /* CR_In_Mongolian_Supplement */
+
+/* 'In_Takri': Block */
+static const OnigCodePoint CR_In_Takri[] = {
+ 1,
+ 0x11680, 0x116cf,
+}; /* CR_In_Takri */
+
+/* 'In_Ahom': Block */
+static const OnigCodePoint CR_In_Ahom[] = {
+ 1,
+ 0x11700, 0x1173f,
+}; /* CR_In_Ahom */
+
+/* 'In_Dogra': Block */
+static const OnigCodePoint CR_In_Dogra[] = {
+ 1,
+ 0x11800, 0x1184f,
+}; /* CR_In_Dogra */
+
+/* 'In_Warang_Citi': Block */
+static const OnigCodePoint CR_In_Warang_Citi[] = {
+ 1,
+ 0x118a0, 0x118ff,
+}; /* CR_In_Warang_Citi */
+
+/* 'In_Nandinagari': Block */
+static const OnigCodePoint CR_In_Nandinagari[] = {
+ 1,
+ 0x119a0, 0x119ff,
+}; /* CR_In_Nandinagari */
+
+/* 'In_Zanabazar_Square': Block */
+static const OnigCodePoint CR_In_Zanabazar_Square[] = {
+ 1,
+ 0x11a00, 0x11a4f,
+}; /* CR_In_Zanabazar_Square */
+
+/* 'In_Soyombo': Block */
+static const OnigCodePoint CR_In_Soyombo[] = {
+ 1,
+ 0x11a50, 0x11aaf,
+}; /* CR_In_Soyombo */
+
+/* 'In_Pau_Cin_Hau': Block */
+static const OnigCodePoint CR_In_Pau_Cin_Hau[] = {
+ 1,
+ 0x11ac0, 0x11aff,
+}; /* CR_In_Pau_Cin_Hau */
+
+/* 'In_Bhaiksuki': Block */
+static const OnigCodePoint CR_In_Bhaiksuki[] = {
+ 1,
+ 0x11c00, 0x11c6f,
+}; /* CR_In_Bhaiksuki */
+
+/* 'In_Marchen': Block */
+static const OnigCodePoint CR_In_Marchen[] = {
+ 1,
+ 0x11c70, 0x11cbf,
+}; /* CR_In_Marchen */
+
+/* 'In_Masaram_Gondi': Block */
+static const OnigCodePoint CR_In_Masaram_Gondi[] = {
+ 1,
+ 0x11d00, 0x11d5f,
+}; /* CR_In_Masaram_Gondi */
+
+/* 'In_Gunjala_Gondi': Block */
+static const OnigCodePoint CR_In_Gunjala_Gondi[] = {
+ 1,
+ 0x11d60, 0x11daf,
+}; /* CR_In_Gunjala_Gondi */
+
+/* 'In_Makasar': Block */
+static const OnigCodePoint CR_In_Makasar[] = {
+ 1,
+ 0x11ee0, 0x11eff,
+}; /* CR_In_Makasar */
+
+/* 'In_Tamil_Supplement': Block */
+static const OnigCodePoint CR_In_Tamil_Supplement[] = {
+ 1,
+ 0x11fc0, 0x11fff,
+}; /* CR_In_Tamil_Supplement */
+
+/* 'In_Cuneiform': Block */
+static const OnigCodePoint CR_In_Cuneiform[] = {
+ 1,
+ 0x12000, 0x123ff,
+}; /* CR_In_Cuneiform */
+
+/* 'In_Cuneiform_Numbers_and_Punctuation': Block */
+static const OnigCodePoint CR_In_Cuneiform_Numbers_and_Punctuation[] = {
+ 1,
+ 0x12400, 0x1247f,
+}; /* CR_In_Cuneiform_Numbers_and_Punctuation */
+
+/* 'In_Early_Dynastic_Cuneiform': Block */
+static const OnigCodePoint CR_In_Early_Dynastic_Cuneiform[] = {
+ 1,
+ 0x12480, 0x1254f,
+}; /* CR_In_Early_Dynastic_Cuneiform */
+
+/* 'In_Egyptian_Hieroglyphs': Block */
+static const OnigCodePoint CR_In_Egyptian_Hieroglyphs[] = {
+ 1,
+ 0x13000, 0x1342f,
+}; /* CR_In_Egyptian_Hieroglyphs */
+
+/* 'In_Egyptian_Hieroglyph_Format_Controls': Block */
+static const OnigCodePoint CR_In_Egyptian_Hieroglyph_Format_Controls[] = {
+ 1,
+ 0x13430, 0x1343f,
+}; /* CR_In_Egyptian_Hieroglyph_Format_Controls */
+
+/* 'In_Anatolian_Hieroglyphs': Block */
+static const OnigCodePoint CR_In_Anatolian_Hieroglyphs[] = {
+ 1,
+ 0x14400, 0x1467f,
+}; /* CR_In_Anatolian_Hieroglyphs */
+
+/* 'In_Bamum_Supplement': Block */
+static const OnigCodePoint CR_In_Bamum_Supplement[] = {
+ 1,
+ 0x16800, 0x16a3f,
+}; /* CR_In_Bamum_Supplement */
+
+/* 'In_Mro': Block */
+static const OnigCodePoint CR_In_Mro[] = {
+ 1,
+ 0x16a40, 0x16a6f,
+}; /* CR_In_Mro */
+
+/* 'In_Bassa_Vah': Block */
+static const OnigCodePoint CR_In_Bassa_Vah[] = {
+ 1,
+ 0x16ad0, 0x16aff,
+}; /* CR_In_Bassa_Vah */
+
+/* 'In_Pahawh_Hmong': Block */
+static const OnigCodePoint CR_In_Pahawh_Hmong[] = {
+ 1,
+ 0x16b00, 0x16b8f,
+}; /* CR_In_Pahawh_Hmong */
+
+/* 'In_Medefaidrin': Block */
+static const OnigCodePoint CR_In_Medefaidrin[] = {
+ 1,
+ 0x16e40, 0x16e9f,
+}; /* CR_In_Medefaidrin */
+
+/* 'In_Miao': Block */
+static const OnigCodePoint CR_In_Miao[] = {
+ 1,
+ 0x16f00, 0x16f9f,
+}; /* CR_In_Miao */
+
+/* 'In_Ideographic_Symbols_and_Punctuation': Block */
+static const OnigCodePoint CR_In_Ideographic_Symbols_and_Punctuation[] = {
+ 1,
+ 0x16fe0, 0x16fff,
+}; /* CR_In_Ideographic_Symbols_and_Punctuation */
+
+/* 'In_Tangut': Block */
+static const OnigCodePoint CR_In_Tangut[] = {
+ 1,
+ 0x17000, 0x187ff,
+}; /* CR_In_Tangut */
+
+/* 'In_Tangut_Components': Block */
+static const OnigCodePoint CR_In_Tangut_Components[] = {
+ 1,
+ 0x18800, 0x18aff,
+}; /* CR_In_Tangut_Components */
+
+/* 'In_Kana_Supplement': Block */
+static const OnigCodePoint CR_In_Kana_Supplement[] = {
+ 1,
+ 0x1b000, 0x1b0ff,
+}; /* CR_In_Kana_Supplement */
+
+/* 'In_Kana_Extended_A': Block */
+static const OnigCodePoint CR_In_Kana_Extended_A[] = {
+ 1,
+ 0x1b100, 0x1b12f,
+}; /* CR_In_Kana_Extended_A */
+
+/* 'In_Small_Kana_Extension': Block */
+static const OnigCodePoint CR_In_Small_Kana_Extension[] = {
+ 1,
+ 0x1b130, 0x1b16f,
+}; /* CR_In_Small_Kana_Extension */
+
+/* 'In_Nushu': Block */
+static const OnigCodePoint CR_In_Nushu[] = {
+ 1,
+ 0x1b170, 0x1b2ff,
+}; /* CR_In_Nushu */
+
+/* 'In_Duployan': Block */
+static const OnigCodePoint CR_In_Duployan[] = {
+ 1,
+ 0x1bc00, 0x1bc9f,
+}; /* CR_In_Duployan */
+
+/* 'In_Shorthand_Format_Controls': Block */
+static const OnigCodePoint CR_In_Shorthand_Format_Controls[] = {
+ 1,
+ 0x1bca0, 0x1bcaf,
+}; /* CR_In_Shorthand_Format_Controls */
+
+/* 'In_Byzantine_Musical_Symbols': Block */
+static const OnigCodePoint CR_In_Byzantine_Musical_Symbols[] = {
+ 1,
+ 0x1d000, 0x1d0ff,
+}; /* CR_In_Byzantine_Musical_Symbols */
+
+/* 'In_Musical_Symbols': Block */
+static const OnigCodePoint CR_In_Musical_Symbols[] = {
+ 1,
+ 0x1d100, 0x1d1ff,
+}; /* CR_In_Musical_Symbols */
+
+/* 'In_Ancient_Greek_Musical_Notation': Block */
+static const OnigCodePoint CR_In_Ancient_Greek_Musical_Notation[] = {
+ 1,
+ 0x1d200, 0x1d24f,
+}; /* CR_In_Ancient_Greek_Musical_Notation */
+
+/* 'In_Mayan_Numerals': Block */
+static const OnigCodePoint CR_In_Mayan_Numerals[] = {
+ 1,
+ 0x1d2e0, 0x1d2ff,
+}; /* CR_In_Mayan_Numerals */
+
+/* 'In_Tai_Xuan_Jing_Symbols': Block */
+static const OnigCodePoint CR_In_Tai_Xuan_Jing_Symbols[] = {
+ 1,
+ 0x1d300, 0x1d35f,
+}; /* CR_In_Tai_Xuan_Jing_Symbols */
+
+/* 'In_Counting_Rod_Numerals': Block */
+static const OnigCodePoint CR_In_Counting_Rod_Numerals[] = {
+ 1,
+ 0x1d360, 0x1d37f,
+}; /* CR_In_Counting_Rod_Numerals */
+
+/* 'In_Mathematical_Alphanumeric_Symbols': Block */
+static const OnigCodePoint CR_In_Mathematical_Alphanumeric_Symbols[] = {
+ 1,
+ 0x1d400, 0x1d7ff,
+}; /* CR_In_Mathematical_Alphanumeric_Symbols */
+
+/* 'In_Sutton_SignWriting': Block */
+static const OnigCodePoint CR_In_Sutton_SignWriting[] = {
+ 1,
+ 0x1d800, 0x1daaf,
+}; /* CR_In_Sutton_SignWriting */
+
+/* 'In_Glagolitic_Supplement': Block */
+static const OnigCodePoint CR_In_Glagolitic_Supplement[] = {
+ 1,
+ 0x1e000, 0x1e02f,
+}; /* CR_In_Glagolitic_Supplement */
+
+/* 'In_Nyiakeng_Puachue_Hmong': Block */
+static const OnigCodePoint CR_In_Nyiakeng_Puachue_Hmong[] = {
+ 1,
+ 0x1e100, 0x1e14f,
+}; /* CR_In_Nyiakeng_Puachue_Hmong */
+
+/* 'In_Wancho': Block */
+static const OnigCodePoint CR_In_Wancho[] = {
+ 1,
+ 0x1e2c0, 0x1e2ff,
+}; /* CR_In_Wancho */
+
+/* 'In_Mende_Kikakui': Block */
+static const OnigCodePoint CR_In_Mende_Kikakui[] = {
+ 1,
+ 0x1e800, 0x1e8df,
+}; /* CR_In_Mende_Kikakui */
+
+/* 'In_Adlam': Block */
+static const OnigCodePoint CR_In_Adlam[] = {
+ 1,
+ 0x1e900, 0x1e95f,
+}; /* CR_In_Adlam */
+
+/* 'In_Indic_Siyaq_Numbers': Block */
+static const OnigCodePoint CR_In_Indic_Siyaq_Numbers[] = {
+ 1,
+ 0x1ec70, 0x1ecbf,
+}; /* CR_In_Indic_Siyaq_Numbers */
+
+/* 'In_Ottoman_Siyaq_Numbers': Block */
+static const OnigCodePoint CR_In_Ottoman_Siyaq_Numbers[] = {
+ 1,
+ 0x1ed00, 0x1ed4f,
+}; /* CR_In_Ottoman_Siyaq_Numbers */
+
+/* 'In_Arabic_Mathematical_Alphabetic_Symbols': Block */
+static const OnigCodePoint CR_In_Arabic_Mathematical_Alphabetic_Symbols[] = {
+ 1,
+ 0x1ee00, 0x1eeff,
+}; /* CR_In_Arabic_Mathematical_Alphabetic_Symbols */
+
+/* 'In_Mahjong_Tiles': Block */
+static const OnigCodePoint CR_In_Mahjong_Tiles[] = {
+ 1,
+ 0x1f000, 0x1f02f,
+}; /* CR_In_Mahjong_Tiles */
+
+/* 'In_Domino_Tiles': Block */
+static const OnigCodePoint CR_In_Domino_Tiles[] = {
+ 1,
+ 0x1f030, 0x1f09f,
+}; /* CR_In_Domino_Tiles */
+
+/* 'In_Playing_Cards': Block */
+static const OnigCodePoint CR_In_Playing_Cards[] = {
+ 1,
+ 0x1f0a0, 0x1f0ff,
+}; /* CR_In_Playing_Cards */
+
+/* 'In_Enclosed_Alphanumeric_Supplement': Block */
+static const OnigCodePoint CR_In_Enclosed_Alphanumeric_Supplement[] = {
+ 1,
+ 0x1f100, 0x1f1ff,
+}; /* CR_In_Enclosed_Alphanumeric_Supplement */
+
+/* 'In_Enclosed_Ideographic_Supplement': Block */
+static const OnigCodePoint CR_In_Enclosed_Ideographic_Supplement[] = {
+ 1,
+ 0x1f200, 0x1f2ff,
+}; /* CR_In_Enclosed_Ideographic_Supplement */
+
+/* 'In_Miscellaneous_Symbols_and_Pictographs': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Symbols_and_Pictographs[] = {
+ 1,
+ 0x1f300, 0x1f5ff,
+}; /* CR_In_Miscellaneous_Symbols_and_Pictographs */
+
+/* 'In_Emoticons': Block */
+static const OnigCodePoint CR_In_Emoticons[] = {
+ 1,
+ 0x1f600, 0x1f64f,
+}; /* CR_In_Emoticons */
+
+/* 'In_Ornamental_Dingbats': Block */
+static const OnigCodePoint CR_In_Ornamental_Dingbats[] = {
+ 1,
+ 0x1f650, 0x1f67f,
+}; /* CR_In_Ornamental_Dingbats */
+
+/* 'In_Transport_and_Map_Symbols': Block */
+static const OnigCodePoint CR_In_Transport_and_Map_Symbols[] = {
+ 1,
+ 0x1f680, 0x1f6ff,
+}; /* CR_In_Transport_and_Map_Symbols */
+
+/* 'In_Alchemical_Symbols': Block */
+static const OnigCodePoint CR_In_Alchemical_Symbols[] = {
+ 1,
+ 0x1f700, 0x1f77f,
+}; /* CR_In_Alchemical_Symbols */
+
+/* 'In_Geometric_Shapes_Extended': Block */
+static const OnigCodePoint CR_In_Geometric_Shapes_Extended[] = {
+ 1,
+ 0x1f780, 0x1f7ff,
+}; /* CR_In_Geometric_Shapes_Extended */
+
+/* 'In_Supplemental_Arrows_C': Block */
+static const OnigCodePoint CR_In_Supplemental_Arrows_C[] = {
+ 1,
+ 0x1f800, 0x1f8ff,
+}; /* CR_In_Supplemental_Arrows_C */
+
+/* 'In_Supplemental_Symbols_and_Pictographs': Block */
+static const OnigCodePoint CR_In_Supplemental_Symbols_and_Pictographs[] = {
+ 1,
+ 0x1f900, 0x1f9ff,
+}; /* CR_In_Supplemental_Symbols_and_Pictographs */
+
+/* 'In_Chess_Symbols': Block */
+static const OnigCodePoint CR_In_Chess_Symbols[] = {
+ 1,
+ 0x1fa00, 0x1fa6f,
+}; /* CR_In_Chess_Symbols */
+
+/* 'In_Symbols_and_Pictographs_Extended_A': Block */
+static const OnigCodePoint CR_In_Symbols_and_Pictographs_Extended_A[] = {
+ 1,
+ 0x1fa70, 0x1faff,
+}; /* CR_In_Symbols_and_Pictographs_Extended_A */
+
+/* 'In_CJK_Unified_Ideographs_Extension_B': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_B[] = {
+ 1,
+ 0x20000, 0x2a6df,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_B */
+
+/* 'In_CJK_Unified_Ideographs_Extension_C': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_C[] = {
+ 1,
+ 0x2a700, 0x2b73f,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_C */
+
+/* 'In_CJK_Unified_Ideographs_Extension_D': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_D[] = {
+ 1,
+ 0x2b740, 0x2b81f,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_D */
+
+/* 'In_CJK_Unified_Ideographs_Extension_E': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_E[] = {
+ 1,
+ 0x2b820, 0x2ceaf,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_E */
+
+/* 'In_CJK_Unified_Ideographs_Extension_F': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_F[] = {
+ 1,
+ 0x2ceb0, 0x2ebef,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_F */
+
+/* 'In_CJK_Compatibility_Ideographs_Supplement': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility_Ideographs_Supplement[] = {
+ 1,
+ 0x2f800, 0x2fa1f,
+}; /* CR_In_CJK_Compatibility_Ideographs_Supplement */
+
+/* 'In_Tags': Block */
+static const OnigCodePoint CR_In_Tags[] = {
+ 1,
+ 0xe0000, 0xe007f,
+}; /* CR_In_Tags */
+
+/* 'In_Variation_Selectors_Supplement': Block */
+static const OnigCodePoint CR_In_Variation_Selectors_Supplement[] = {
+ 1,
+ 0xe0100, 0xe01ef,
+}; /* CR_In_Variation_Selectors_Supplement */
+
+/* 'In_Supplementary_Private_Use_Area_A': Block */
+static const OnigCodePoint CR_In_Supplementary_Private_Use_Area_A[] = {
+ 1,
+ 0xf0000, 0xfffff,
+}; /* CR_In_Supplementary_Private_Use_Area_A */
+
+/* 'In_Supplementary_Private_Use_Area_B': Block */
+static const OnigCodePoint CR_In_Supplementary_Private_Use_Area_B[] = {
+ 1,
+ 0x100000, 0x10ffff,
+}; /* CR_In_Supplementary_Private_Use_Area_B */
+
+/* 'In_No_Block': Block */
+static const OnigCodePoint CR_In_No_Block[] = {
+ 53,
+ 0x0870, 0x089f,
+ 0x2fe0, 0x2fef,
+ 0x10200, 0x1027f,
+ 0x103e0, 0x103ff,
+ 0x10570, 0x105ff,
+ 0x10780, 0x107ff,
+ 0x108b0, 0x108df,
+ 0x10940, 0x1097f,
+ 0x10aa0, 0x10abf,
+ 0x10bb0, 0x10bff,
+ 0x10c50, 0x10c7f,
+ 0x10d40, 0x10e5f,
+ 0x10e80, 0x10eff,
+ 0x10f70, 0x10fdf,
+ 0x11250, 0x1127f,
+ 0x11380, 0x113ff,
+ 0x114e0, 0x1157f,
+ 0x116d0, 0x116ff,
+ 0x11740, 0x117ff,
+ 0x11850, 0x1189f,
+ 0x11900, 0x1199f,
+ 0x11ab0, 0x11abf,
+ 0x11b00, 0x11bff,
+ 0x11cc0, 0x11cff,
+ 0x11db0, 0x11edf,
+ 0x11f00, 0x11fbf,
+ 0x12550, 0x12fff,
+ 0x13440, 0x143ff,
+ 0x14680, 0x167ff,
+ 0x16a70, 0x16acf,
+ 0x16b90, 0x16e3f,
+ 0x16ea0, 0x16eff,
+ 0x16fa0, 0x16fdf,
+ 0x18b00, 0x1afff,
+ 0x1b300, 0x1bbff,
+ 0x1bcb0, 0x1cfff,
+ 0x1d250, 0x1d2df,
+ 0x1d380, 0x1d3ff,
+ 0x1dab0, 0x1dfff,
+ 0x1e030, 0x1e0ff,
+ 0x1e150, 0x1e2bf,
+ 0x1e300, 0x1e7ff,
+ 0x1e8e0, 0x1e8ff,
+ 0x1e960, 0x1ec6f,
+ 0x1ecc0, 0x1ecff,
+ 0x1ed50, 0x1edff,
+ 0x1ef00, 0x1efff,
+ 0x1fb00, 0x1ffff,
+ 0x2a6e0, 0x2a6ff,
+ 0x2ebf0, 0x2f7ff,
+ 0x2fa20, 0xdffff,
+ 0xe0080, 0xe00ff,
+ 0xe01f0, 0xeffff,
+}; /* CR_In_No_Block */
+
+#endif /* USE_UNICODE_PROPERTIES */
+static const OnigCodePoint* const CodeRanges[] = {
+ CR_NEWLINE,
+ CR_Alpha,
+ CR_Blank,
+ CR_Cntrl,
+ CR_Digit,
+ CR_Graph,
+ CR_Lower,
+ CR_Print,
+ CR_XPosixPunct,
+ CR_Space,
+ CR_Upper,
+ CR_XDigit,
+ CR_Word,
+ CR_Alnum,
+ CR_ASCII,
+ CR_Punct,
+#ifdef USE_UNICODE_PROPERTIES
+ CR_Any,
+ CR_Assigned,
+ CR_C,
+ CR_Cc,
+ CR_Cf,
+ CR_Cn,
+ CR_Co,
+ CR_Cs,
+ CR_L,
+ CR_LC,
+ CR_Ll,
+ CR_Lm,
+ CR_Lo,
+ CR_Lt,
+ CR_Lu,
+ CR_M,
+ CR_Mc,
+ CR_Me,
+ CR_Mn,
+ CR_N,
+ CR_Nd,
+ CR_Nl,
+ CR_No,
+ CR_P,
+ CR_Pc,
+ CR_Pd,
+ CR_Pe,
+ CR_Pf,
+ CR_Pi,
+ CR_Po,
+ CR_Ps,
+ CR_S,
+ CR_Sc,
+ CR_Sk,
+ CR_Sm,
+ CR_So,
+ CR_Z,
+ CR_Zl,
+ CR_Zp,
+ CR_Zs,
+ CR_Math,
+ CR_Alphabetic,
+ CR_Lowercase,
+ CR_Uppercase,
+ CR_Cased,
+ CR_Case_Ignorable,
+ CR_Changes_When_Lowercased,
+ CR_Changes_When_Uppercased,
+ CR_Changes_When_Titlecased,
+ CR_Changes_When_Casefolded,
+ CR_Changes_When_Casemapped,
+ CR_ID_Start,
+ CR_ID_Continue,
+ CR_XID_Start,
+ CR_XID_Continue,
+ CR_Default_Ignorable_Code_Point,
+ CR_Grapheme_Extend,
+ CR_Grapheme_Base,
+ CR_Grapheme_Link,
+ CR_Common,
+ CR_Latin,
+ CR_Greek,
+ CR_Cyrillic,
+ CR_Armenian,
+ CR_Hebrew,
+ CR_Arabic,
+ CR_Syriac,
+ CR_Thaana,
+ CR_Devanagari,
+ CR_Bengali,
+ CR_Gurmukhi,
+ CR_Gujarati,
+ CR_Oriya,
+ CR_Tamil,
+ CR_Telugu,
+ CR_Kannada,
+ CR_Malayalam,
+ CR_Sinhala,
+ CR_Thai,
+ CR_Lao,
+ CR_Tibetan,
+ CR_Myanmar,
+ CR_Georgian,
+ CR_Hangul,
+ CR_Ethiopic,
+ CR_Cherokee,
+ CR_Canadian_Aboriginal,
+ CR_Ogham,
+ CR_Runic,
+ CR_Khmer,
+ CR_Mongolian,
+ CR_Hiragana,
+ CR_Katakana,
+ CR_Bopomofo,
+ CR_Han,
+ CR_Yi,
+ CR_Old_Italic,
+ CR_Gothic,
+ CR_Deseret,
+ CR_Inherited,
+ CR_Tagalog,
+ CR_Hanunoo,
+ CR_Buhid,
+ CR_Tagbanwa,
+ CR_Limbu,
+ CR_Tai_Le,
+ CR_Linear_B,
+ CR_Ugaritic,
+ CR_Shavian,
+ CR_Osmanya,
+ CR_Cypriot,
+ CR_Braille,
+ CR_Buginese,
+ CR_Coptic,
+ CR_New_Tai_Lue,
+ CR_Glagolitic,
+ CR_Tifinagh,
+ CR_Syloti_Nagri,
+ CR_Old_Persian,
+ CR_Kharoshthi,
+ CR_Balinese,
+ CR_Cuneiform,
+ CR_Phoenician,
+ CR_Phags_Pa,
+ CR_Nko,
+ CR_Sundanese,
+ CR_Lepcha,
+ CR_Ol_Chiki,
+ CR_Vai,
+ CR_Saurashtra,
+ CR_Kayah_Li,
+ CR_Rejang,
+ CR_Lycian,
+ CR_Carian,
+ CR_Lydian,
+ CR_Cham,
+ CR_Tai_Tham,
+ CR_Tai_Viet,
+ CR_Avestan,
+ CR_Egyptian_Hieroglyphs,
+ CR_Samaritan,
+ CR_Lisu,
+ CR_Bamum,
+ CR_Javanese,
+ CR_Meetei_Mayek,
+ CR_Imperial_Aramaic,
+ CR_Old_South_Arabian,
+ CR_Inscriptional_Parthian,
+ CR_Inscriptional_Pahlavi,
+ CR_Old_Turkic,
+ CR_Kaithi,
+ CR_Batak,
+ CR_Brahmi,
+ CR_Mandaic,
+ CR_Chakma,
+ CR_Meroitic_Cursive,
+ CR_Meroitic_Hieroglyphs,
+ CR_Miao,
+ CR_Sharada,
+ CR_Sora_Sompeng,
+ CR_Takri,
+ CR_Caucasian_Albanian,
+ CR_Bassa_Vah,
+ CR_Duployan,
+ CR_Elbasan,
+ CR_Grantha,
+ CR_Pahawh_Hmong,
+ CR_Khojki,
+ CR_Linear_A,
+ CR_Mahajani,
+ CR_Manichaean,
+ CR_Mende_Kikakui,
+ CR_Modi,
+ CR_Mro,
+ CR_Old_North_Arabian,
+ CR_Nabataean,
+ CR_Palmyrene,
+ CR_Pau_Cin_Hau,
+ CR_Old_Permic,
+ CR_Psalter_Pahlavi,
+ CR_Siddham,
+ CR_Khudawadi,
+ CR_Tirhuta,
+ CR_Warang_Citi,
+ CR_Ahom,
+ CR_Anatolian_Hieroglyphs,
+ CR_Hatran,
+ CR_Multani,
+ CR_Old_Hungarian,
+ CR_SignWriting,
+ CR_Adlam,
+ CR_Bhaiksuki,
+ CR_Marchen,
+ CR_Newa,
+ CR_Osage,
+ CR_Tangut,
+ CR_Masaram_Gondi,
+ CR_Nushu,
+ CR_Soyombo,
+ CR_Zanabazar_Square,
+ CR_Dogra,
+ CR_Gunjala_Gondi,
+ CR_Makasar,
+ CR_Medefaidrin,
+ CR_Hanifi_Rohingya,
+ CR_Sogdian,
+ CR_Old_Sogdian,
+ CR_Elymaic,
+ CR_Nandinagari,
+ CR_Nyiakeng_Puachue_Hmong,
+ CR_Wancho,
+ CR_White_Space,
+ CR_Bidi_Control,
+ CR_Join_Control,
+ CR_Dash,
+ CR_Hyphen,
+ CR_Quotation_Mark,
+ CR_Terminal_Punctuation,
+ CR_Other_Math,
+ CR_Hex_Digit,
+ CR_ASCII_Hex_Digit,
+ CR_Other_Alphabetic,
+ CR_Ideographic,
+ CR_Diacritic,
+ CR_Extender,
+ CR_Other_Lowercase,
+ CR_Other_Uppercase,
+ CR_Noncharacter_Code_Point,
+ CR_Other_Grapheme_Extend,
+ CR_IDS_Binary_Operator,
+ CR_IDS_Trinary_Operator,
+ CR_Radical,
+ CR_Unified_Ideograph,
+ CR_Other_Default_Ignorable_Code_Point,
+ CR_Deprecated,
+ CR_Soft_Dotted,
+ CR_Logical_Order_Exception,
+ CR_Other_ID_Start,
+ CR_Other_ID_Continue,
+ CR_Sentence_Terminal,
+ CR_Variation_Selector,
+ CR_Pattern_White_Space,
+ CR_Pattern_Syntax,
+ CR_Prepended_Concatenation_Mark,
+ CR_Regional_Indicator,
+ CR_Emoji,
+ CR_Emoji_Presentation,
+ CR_Emoji_Modifier,
+ CR_Emoji_Modifier_Base,
+ CR_Emoji_Component,
+ CR_Extended_Pictographic,
+ CR_Unknown,
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ CR_Age_1_1,
+ CR_Age_2_0,
+ CR_Age_2_1,
+ CR_Age_3_0,
+ CR_Age_3_1,
+ CR_Age_3_2,
+ CR_Age_4_0,
+ CR_Age_4_1,
+ CR_Age_5_0,
+ CR_Age_5_1,
+ CR_Age_5_2,
+ CR_Age_6_0,
+ CR_Age_6_1,
+ CR_Age_6_2,
+ CR_Age_6_3,
+ CR_Age_7_0,
+ CR_Age_8_0,
+ CR_Age_9_0,
+ CR_Age_10_0,
+ CR_Age_11_0,
+ CR_Age_12_0,
+ CR_Age_12_1,
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ CR_Grapheme_Cluster_Break_Prepend,
+ CR_Grapheme_Cluster_Break_CR,
+ CR_Grapheme_Cluster_Break_LF,
+ CR_Grapheme_Cluster_Break_Control,
+ CR_Grapheme_Cluster_Break_Extend,
+ CR_Grapheme_Cluster_Break_Regional_Indicator,
+ CR_Grapheme_Cluster_Break_SpacingMark,
+ CR_Grapheme_Cluster_Break_L,
+ CR_Grapheme_Cluster_Break_V,
+ CR_Grapheme_Cluster_Break_T,
+ CR_Grapheme_Cluster_Break_LV,
+ CR_Grapheme_Cluster_Break_LVT,
+ CR_Grapheme_Cluster_Break_ZWJ,
+ CR_In_Basic_Latin,
+ CR_In_Latin_1_Supplement,
+ CR_In_Latin_Extended_A,
+ CR_In_Latin_Extended_B,
+ CR_In_IPA_Extensions,
+ CR_In_Spacing_Modifier_Letters,
+ CR_In_Combining_Diacritical_Marks,
+ CR_In_Greek_and_Coptic,
+ CR_In_Cyrillic,
+ CR_In_Cyrillic_Supplement,
+ CR_In_Armenian,
+ CR_In_Hebrew,
+ CR_In_Arabic,
+ CR_In_Syriac,
+ CR_In_Arabic_Supplement,
+ CR_In_Thaana,
+ CR_In_NKo,
+ CR_In_Samaritan,
+ CR_In_Mandaic,
+ CR_In_Syriac_Supplement,
+ CR_In_Arabic_Extended_A,
+ CR_In_Devanagari,
+ CR_In_Bengali,
+ CR_In_Gurmukhi,
+ CR_In_Gujarati,
+ CR_In_Oriya,
+ CR_In_Tamil,
+ CR_In_Telugu,
+ CR_In_Kannada,
+ CR_In_Malayalam,
+ CR_In_Sinhala,
+ CR_In_Thai,
+ CR_In_Lao,
+ CR_In_Tibetan,
+ CR_In_Myanmar,
+ CR_In_Georgian,
+ CR_In_Hangul_Jamo,
+ CR_In_Ethiopic,
+ CR_In_Ethiopic_Supplement,
+ CR_In_Cherokee,
+ CR_In_Unified_Canadian_Aboriginal_Syllabics,
+ CR_In_Ogham,
+ CR_In_Runic,
+ CR_In_Tagalog,
+ CR_In_Hanunoo,
+ CR_In_Buhid,
+ CR_In_Tagbanwa,
+ CR_In_Khmer,
+ CR_In_Mongolian,
+ CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended,
+ CR_In_Limbu,
+ CR_In_Tai_Le,
+ CR_In_New_Tai_Lue,
+ CR_In_Khmer_Symbols,
+ CR_In_Buginese,
+ CR_In_Tai_Tham,
+ CR_In_Combining_Diacritical_Marks_Extended,
+ CR_In_Balinese,
+ CR_In_Sundanese,
+ CR_In_Batak,
+ CR_In_Lepcha,
+ CR_In_Ol_Chiki,
+ CR_In_Cyrillic_Extended_C,
+ CR_In_Georgian_Extended,
+ CR_In_Sundanese_Supplement,
+ CR_In_Vedic_Extensions,
+ CR_In_Phonetic_Extensions,
+ CR_In_Phonetic_Extensions_Supplement,
+ CR_In_Combining_Diacritical_Marks_Supplement,
+ CR_In_Latin_Extended_Additional,
+ CR_In_Greek_Extended,
+ CR_In_General_Punctuation,
+ CR_In_Superscripts_and_Subscripts,
+ CR_In_Currency_Symbols,
+ CR_In_Combining_Diacritical_Marks_for_Symbols,
+ CR_In_Letterlike_Symbols,
+ CR_In_Number_Forms,
+ CR_In_Arrows,
+ CR_In_Mathematical_Operators,
+ CR_In_Miscellaneous_Technical,
+ CR_In_Control_Pictures,
+ CR_In_Optical_Character_Recognition,
+ CR_In_Enclosed_Alphanumerics,
+ CR_In_Box_Drawing,
+ CR_In_Block_Elements,
+ CR_In_Geometric_Shapes,
+ CR_In_Miscellaneous_Symbols,
+ CR_In_Dingbats,
+ CR_In_Miscellaneous_Mathematical_Symbols_A,
+ CR_In_Supplemental_Arrows_A,
+ CR_In_Braille_Patterns,
+ CR_In_Supplemental_Arrows_B,
+ CR_In_Miscellaneous_Mathematical_Symbols_B,
+ CR_In_Supplemental_Mathematical_Operators,
+ CR_In_Miscellaneous_Symbols_and_Arrows,
+ CR_In_Glagolitic,
+ CR_In_Latin_Extended_C,
+ CR_In_Coptic,
+ CR_In_Georgian_Supplement,
+ CR_In_Tifinagh,
+ CR_In_Ethiopic_Extended,
+ CR_In_Cyrillic_Extended_A,
+ CR_In_Supplemental_Punctuation,
+ CR_In_CJK_Radicals_Supplement,
+ CR_In_Kangxi_Radicals,
+ CR_In_Ideographic_Description_Characters,
+ CR_In_CJK_Symbols_and_Punctuation,
+ CR_In_Hiragana,
+ CR_In_Katakana,
+ CR_In_Bopomofo,
+ CR_In_Hangul_Compatibility_Jamo,
+ CR_In_Kanbun,
+ CR_In_Bopomofo_Extended,
+ CR_In_CJK_Strokes,
+ CR_In_Katakana_Phonetic_Extensions,
+ CR_In_Enclosed_CJK_Letters_and_Months,
+ CR_In_CJK_Compatibility,
+ CR_In_CJK_Unified_Ideographs_Extension_A,
+ CR_In_Yijing_Hexagram_Symbols,
+ CR_In_CJK_Unified_Ideographs,
+ CR_In_Yi_Syllables,
+ CR_In_Yi_Radicals,
+ CR_In_Lisu,
+ CR_In_Vai,
+ CR_In_Cyrillic_Extended_B,
+ CR_In_Bamum,
+ CR_In_Modifier_Tone_Letters,
+ CR_In_Latin_Extended_D,
+ CR_In_Syloti_Nagri,
+ CR_In_Common_Indic_Number_Forms,
+ CR_In_Phags_pa,
+ CR_In_Saurashtra,
+ CR_In_Devanagari_Extended,
+ CR_In_Kayah_Li,
+ CR_In_Rejang,
+ CR_In_Hangul_Jamo_Extended_A,
+ CR_In_Javanese,
+ CR_In_Myanmar_Extended_B,
+ CR_In_Cham,
+ CR_In_Myanmar_Extended_A,
+ CR_In_Tai_Viet,
+ CR_In_Meetei_Mayek_Extensions,
+ CR_In_Ethiopic_Extended_A,
+ CR_In_Latin_Extended_E,
+ CR_In_Cherokee_Supplement,
+ CR_In_Meetei_Mayek,
+ CR_In_Hangul_Syllables,
+ CR_In_Hangul_Jamo_Extended_B,
+ CR_In_High_Surrogates,
+ CR_In_High_Private_Use_Surrogates,
+ CR_In_Low_Surrogates,
+ CR_In_Private_Use_Area,
+ CR_In_CJK_Compatibility_Ideographs,
+ CR_In_Alphabetic_Presentation_Forms,
+ CR_In_Arabic_Presentation_Forms_A,
+ CR_In_Variation_Selectors,
+ CR_In_Vertical_Forms,
+ CR_In_Combining_Half_Marks,
+ CR_In_CJK_Compatibility_Forms,
+ CR_In_Small_Form_Variants,
+ CR_In_Arabic_Presentation_Forms_B,
+ CR_In_Halfwidth_and_Fullwidth_Forms,
+ CR_In_Specials,
+ CR_In_Linear_B_Syllabary,
+ CR_In_Linear_B_Ideograms,
+ CR_In_Aegean_Numbers,
+ CR_In_Ancient_Greek_Numbers,
+ CR_In_Ancient_Symbols,
+ CR_In_Phaistos_Disc,
+ CR_In_Lycian,
+ CR_In_Carian,
+ CR_In_Coptic_Epact_Numbers,
+ CR_In_Old_Italic,
+ CR_In_Gothic,
+ CR_In_Old_Permic,
+ CR_In_Ugaritic,
+ CR_In_Old_Persian,
+ CR_In_Deseret,
+ CR_In_Shavian,
+ CR_In_Osmanya,
+ CR_In_Osage,
+ CR_In_Elbasan,
+ CR_In_Caucasian_Albanian,
+ CR_In_Linear_A,
+ CR_In_Cypriot_Syllabary,
+ CR_In_Imperial_Aramaic,
+ CR_In_Palmyrene,
+ CR_In_Nabataean,
+ CR_In_Hatran,
+ CR_In_Phoenician,
+ CR_In_Lydian,
+ CR_In_Meroitic_Hieroglyphs,
+ CR_In_Meroitic_Cursive,
+ CR_In_Kharoshthi,
+ CR_In_Old_South_Arabian,
+ CR_In_Old_North_Arabian,
+ CR_In_Manichaean,
+ CR_In_Avestan,
+ CR_In_Inscriptional_Parthian,
+ CR_In_Inscriptional_Pahlavi,
+ CR_In_Psalter_Pahlavi,
+ CR_In_Old_Turkic,
+ CR_In_Old_Hungarian,
+ CR_In_Hanifi_Rohingya,
+ CR_In_Rumi_Numeral_Symbols,
+ CR_In_Old_Sogdian,
+ CR_In_Sogdian,
+ CR_In_Elymaic,
+ CR_In_Brahmi,
+ CR_In_Kaithi,
+ CR_In_Sora_Sompeng,
+ CR_In_Chakma,
+ CR_In_Mahajani,
+ CR_In_Sharada,
+ CR_In_Sinhala_Archaic_Numbers,
+ CR_In_Khojki,
+ CR_In_Multani,
+ CR_In_Khudawadi,
+ CR_In_Grantha,
+ CR_In_Newa,
+ CR_In_Tirhuta,
+ CR_In_Siddham,
+ CR_In_Modi,
+ CR_In_Mongolian_Supplement,
+ CR_In_Takri,
+ CR_In_Ahom,
+ CR_In_Dogra,
+ CR_In_Warang_Citi,
+ CR_In_Nandinagari,
+ CR_In_Zanabazar_Square,
+ CR_In_Soyombo,
+ CR_In_Pau_Cin_Hau,
+ CR_In_Bhaiksuki,
+ CR_In_Marchen,
+ CR_In_Masaram_Gondi,
+ CR_In_Gunjala_Gondi,
+ CR_In_Makasar,
+ CR_In_Tamil_Supplement,
+ CR_In_Cuneiform,
+ CR_In_Cuneiform_Numbers_and_Punctuation,
+ CR_In_Early_Dynastic_Cuneiform,
+ CR_In_Egyptian_Hieroglyphs,
+ CR_In_Egyptian_Hieroglyph_Format_Controls,
+ CR_In_Anatolian_Hieroglyphs,
+ CR_In_Bamum_Supplement,
+ CR_In_Mro,
+ CR_In_Bassa_Vah,
+ CR_In_Pahawh_Hmong,
+ CR_In_Medefaidrin,
+ CR_In_Miao,
+ CR_In_Ideographic_Symbols_and_Punctuation,
+ CR_In_Tangut,
+ CR_In_Tangut_Components,
+ CR_In_Kana_Supplement,
+ CR_In_Kana_Extended_A,
+ CR_In_Small_Kana_Extension,
+ CR_In_Nushu,
+ CR_In_Duployan,
+ CR_In_Shorthand_Format_Controls,
+ CR_In_Byzantine_Musical_Symbols,
+ CR_In_Musical_Symbols,
+ CR_In_Ancient_Greek_Musical_Notation,
+ CR_In_Mayan_Numerals,
+ CR_In_Tai_Xuan_Jing_Symbols,
+ CR_In_Counting_Rod_Numerals,
+ CR_In_Mathematical_Alphanumeric_Symbols,
+ CR_In_Sutton_SignWriting,
+ CR_In_Glagolitic_Supplement,
+ CR_In_Nyiakeng_Puachue_Hmong,
+ CR_In_Wancho,
+ CR_In_Mende_Kikakui,
+ CR_In_Adlam,
+ CR_In_Indic_Siyaq_Numbers,
+ CR_In_Ottoman_Siyaq_Numbers,
+ CR_In_Arabic_Mathematical_Alphabetic_Symbols,
+ CR_In_Mahjong_Tiles,
+ CR_In_Domino_Tiles,
+ CR_In_Playing_Cards,
+ CR_In_Enclosed_Alphanumeric_Supplement,
+ CR_In_Enclosed_Ideographic_Supplement,
+ CR_In_Miscellaneous_Symbols_and_Pictographs,
+ CR_In_Emoticons,
+ CR_In_Ornamental_Dingbats,
+ CR_In_Transport_and_Map_Symbols,
+ CR_In_Alchemical_Symbols,
+ CR_In_Geometric_Shapes_Extended,
+ CR_In_Supplemental_Arrows_C,
+ CR_In_Supplemental_Symbols_and_Pictographs,
+ CR_In_Chess_Symbols,
+ CR_In_Symbols_and_Pictographs_Extended_A,
+ CR_In_CJK_Unified_Ideographs_Extension_B,
+ CR_In_CJK_Unified_Ideographs_Extension_C,
+ CR_In_CJK_Unified_Ideographs_Extension_D,
+ CR_In_CJK_Unified_Ideographs_Extension_E,
+ CR_In_CJK_Unified_Ideographs_Extension_F,
+ CR_In_CJK_Compatibility_Ideographs_Supplement,
+ CR_In_Tags,
+ CR_In_Variation_Selectors_Supplement,
+ CR_In_Supplementary_Private_Use_Area_A,
+ CR_In_Supplementary_Private_Use_Area_B,
+ CR_In_No_Block,
+#endif /* USE_UNICODE_PROPERTIES */
+};
+struct uniname2ctype_struct {
+ short name;
+ unsigned short ctype;
+};
+#define uniname2ctype_offset(str) offsetof(struct uniname2ctype_pool_t, uniname2ctype_pool_##str)
+
+static const struct uniname2ctype_struct *uniname2ctype_p(
+#if !(1+0) /* if ANSI, old style not to conflict with generated prototype */
+ const char *, unsigned int
+#endif
+);
+
+#ifndef USE_UNICODE_PROPERTIES
+#define TOTAL_KEYWORDS 15
+#define MIN_WORD_LENGTH 4
+#define MAX_WORD_LENGTH 11
+#define MIN_HASH_VALUE 6
+#define MAX_HASH_VALUE 20
+/* maximum key range = 15, duplicates = 0 */
+#else /* USE_UNICODE_PROPERTIES */
+#ifndef USE_UNICODE_AGE_PROPERTIES
+#define TOTAL_KEYWORDS 814
+#else /* USE_UNICODE_AGE_PROPERTIES */
+#define TOTAL_KEYWORDS 836
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+#define MIN_WORD_LENGTH 1
+#define MAX_WORD_LENGTH 44
+#define MIN_HASH_VALUE 11
+#define MAX_HASH_VALUE 6098
+/* maximum key range = 6088, duplicates = 0 */
+#endif /* USE_UNICODE_PROPERTIES */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+uniname2ctype_hash (register const char *str, register size_t len)
+{
+#ifndef USE_UNICODE_PROPERTIES
+ static const unsigned char asso_values[] =
+#else /* USE_UNICODE_PROPERTIES */
+ static const unsigned short asso_values[] =
+#endif /* USE_UNICODE_PROPERTIES */
+ {
+#ifndef USE_UNICODE_PROPERTIES
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 3, 12, 5,
+ 4, 21, 21, 10, 21, 1, 21, 21, 11, 21,
+ 2, 1, 1, 21, 1, 7, 4, 6, 21, 1,
+ 4, 21, 21, 21, 21, 21, 21, 21
+#else /* USE_UNICODE_PROPERTIES */
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ 6099, 6099, 6099, 6099, 6099, 6099, 17, 6099, 3, 1,
+ 4, 13, 3, 22, 9, 16, 12, 5, 6099, 6099,
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099, 6099,
+ 6099, 6099, 6099, 6099, 6099, 6099, 6099, 1, 1425, 113,
+ 437, 37, 1023, 1071, 1051, 4, 1492, 9, 500, 88,
+ 8, 18, 1371, 797, 54, 203, 310, 619, 1608, 603,
+ 364, 1438, 20, 1, 3, 6099, 6099, 6099, 6099, 6099
+#endif /* USE_UNICODE_PROPERTIES */
+ };
+#ifndef USE_UNICODE_PROPERTIES
+ return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]];
+#else /* USE_UNICODE_PROPERTIES */
+ register unsigned int hval = (unsigned int)len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[15]];
+ /*FALLTHROUGH*/
+ case 15:
+ case 14:
+ case 13:
+ case 12:
+ hval += asso_values[(unsigned char)str[11]];
+ /*FALLTHROUGH*/
+ case 11:
+ case 10:
+ case 9:
+ case 8:
+ case 7:
+ case 6:
+ hval += asso_values[(unsigned char)str[5]];
+ /*FALLTHROUGH*/
+ case 5:
+ hval += asso_values[(unsigned char)str[4]];
+ /*FALLTHROUGH*/
+ case 4:
+ case 3:
+ hval += asso_values[(unsigned char)str[2]];
+ /*FALLTHROUGH*/
+ case 2:
+ hval += asso_values[(unsigned char)str[1]];
+ /*FALLTHROUGH*/
+ case 1:
+ hval += asso_values[(unsigned char)str[0]+2];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
+#endif /* USE_UNICODE_PROPERTIES */
+}
+
+struct uniname2ctype_pool_t
+ {
+#ifndef USE_UNICODE_PROPERTIES
+ char uniname2ctype_pool_str6[sizeof("word")];
+ char uniname2ctype_pool_str7[sizeof("print")];
+ char uniname2ctype_pool_str8[sizeof("punct")];
+ char uniname2ctype_pool_str9[sizeof("alpha")];
+ char uniname2ctype_pool_str10[sizeof("alnum")];
+ char uniname2ctype_pool_str11[sizeof("xdigit")];
+ char uniname2ctype_pool_str12[sizeof("upper")];
+ char uniname2ctype_pool_str13[sizeof("ascii")];
+ char uniname2ctype_pool_str14[sizeof("cntrl")];
+ char uniname2ctype_pool_str15[sizeof("space")];
+ char uniname2ctype_pool_str16[sizeof("xposixpunct")];
+ char uniname2ctype_pool_str17[sizeof("lower")];
+ char uniname2ctype_pool_str18[sizeof("graph")];
+ char uniname2ctype_pool_str19[sizeof("digit")];
+ char uniname2ctype_pool_str20[sizeof("blank")];
+#else /* USE_UNICODE_PROPERTIES */
+ char uniname2ctype_pool_str11[sizeof("yi")];
+ char uniname2ctype_pool_str17[sizeof("yiii")];
+ char uniname2ctype_pool_str22[sizeof("lana")];
+ char uniname2ctype_pool_str24[sizeof("z")];
+ char uniname2ctype_pool_str25[sizeof("lina")];
+ char uniname2ctype_pool_str33[sizeof("maka")];
+ char uniname2ctype_pool_str35[sizeof("mani")];
+ char uniname2ctype_pool_str36[sizeof("mn")];
+ char uniname2ctype_pool_str45[sizeof("miao")];
+ char uniname2ctype_pool_str46[sizeof("lo")];
+ char uniname2ctype_pool_str47[sizeof("ci")];
+ char uniname2ctype_pool_str48[sizeof("lao")];
+ char uniname2ctype_pool_str49[sizeof("laoo")];
+ char uniname2ctype_pool_str52[sizeof("inkannada")];
+ char uniname2ctype_pool_str55[sizeof("cn")];
+ char uniname2ctype_pool_str64[sizeof("pi")];
+ char uniname2ctype_pool_str66[sizeof("innko")];
+ char uniname2ctype_pool_str67[sizeof("zzzz")];
+ char uniname2ctype_pool_str71[sizeof("gran")];
+ char uniname2ctype_pool_str75[sizeof("co")];
+ char uniname2ctype_pool_str83[sizeof("lineara")];
+ char uniname2ctype_pool_str86[sizeof("mark")];
+ char uniname2ctype_pool_str92[sizeof("po")];
+ char uniname2ctype_pool_str94[sizeof("me")];
+ char uniname2ctype_pool_str100[sizeof("cari")];
+ char uniname2ctype_pool_str101[sizeof("inkharoshthi")];
+ char uniname2ctype_pool_str102[sizeof("kana")];
+ char uniname2ctype_pool_str103[sizeof("loe")];
+ char uniname2ctype_pool_str107[sizeof("m")];
+ char uniname2ctype_pool_str108[sizeof("grek")];
+ char uniname2ctype_pool_str111[sizeof("mro")];
+ char uniname2ctype_pool_str112[sizeof("mroo")];
+ char uniname2ctype_pool_str115[sizeof("carian")];
+ char uniname2ctype_pool_str117[sizeof("geor")];
+ char uniname2ctype_pool_str118[sizeof("greek")];
+ char uniname2ctype_pool_str122[sizeof("gonm")];
+ char uniname2ctype_pool_str129[sizeof("mendekikakui")];
+ char uniname2ctype_pool_str130[sizeof("pe")];
+ char uniname2ctype_pool_str131[sizeof("mero")];
+ char uniname2ctype_pool_str134[sizeof("inosmanya")];
+ char uniname2ctype_pool_str139[sizeof("cakm")];
+ char uniname2ctype_pool_str145[sizeof("inmanichaean")];
+ char uniname2ctype_pool_str146[sizeof("inmro")];
+ char uniname2ctype_pool_str148[sizeof("inmiao")];
+ char uniname2ctype_pool_str149[sizeof("inchakma")];
+ char uniname2ctype_pool_str151[sizeof("c")];
+ char uniname2ctype_pool_str152[sizeof("mandaic")];
+ char uniname2ctype_pool_str153[sizeof("meeteimayek")];
+ char uniname2ctype_pool_str161[sizeof("inarmenian")];
+ char uniname2ctype_pool_str177[sizeof("inmyanmar")];
+ char uniname2ctype_pool_str178[sizeof("inmakasar")];
+ char uniname2ctype_pool_str183[sizeof("common")];
+ char uniname2ctype_pool_str186[sizeof("lm")];
+ char uniname2ctype_pool_str190[sizeof("marc")];
+ char uniname2ctype_pool_str203[sizeof("inrunic")];
+ char uniname2ctype_pool_str204[sizeof("incarian")];
+ char uniname2ctype_pool_str210[sizeof("inideographicsymbolsandpunctuation")];
+ char uniname2ctype_pool_str212[sizeof("inkhmer")];
+ char uniname2ctype_pool_str213[sizeof("qaai")];
+ char uniname2ctype_pool_str218[sizeof("inahom")];
+ char uniname2ctype_pool_str226[sizeof("merc")];
+ char uniname2ctype_pool_str231[sizeof("combiningmark")];
+ char uniname2ctype_pool_str236[sizeof("lc")];
+ char uniname2ctype_pool_str237[sizeof("perm")];
+ char uniname2ctype_pool_str246[sizeof("mc")];
+ char uniname2ctype_pool_str250[sizeof("connectorpunctuation")];
+ char uniname2ctype_pool_str253[sizeof("cans")];
+ char uniname2ctype_pool_str260[sizeof("incuneiformnumbersandpunctuation")];
+ char uniname2ctype_pool_str263[sizeof("armi")];
+ char uniname2ctype_pool_str265[sizeof("cc")];
+ char uniname2ctype_pool_str267[sizeof("armn")];
+ char uniname2ctype_pool_str268[sizeof("incherokee")];
+ char uniname2ctype_pool_str270[sizeof("prependedconcatenationmark")];
+ char uniname2ctype_pool_str274[sizeof("incuneiform")];
+ char uniname2ctype_pool_str275[sizeof("inavestan")];
+ char uniname2ctype_pool_str281[sizeof("inipaextensions")];
+ char uniname2ctype_pool_str282[sizeof("pc")];
+ char uniname2ctype_pool_str283[sizeof("armenian")];
+ char uniname2ctype_pool_str285[sizeof("insharada")];
+ char uniname2ctype_pool_str289[sizeof("inmarchen")];
+ char uniname2ctype_pool_str293[sizeof("makasar")];
+ char uniname2ctype_pool_str297[sizeof("masaramgondi")];
+ char uniname2ctype_pool_str301[sizeof("inarrows")];
+ char uniname2ctype_pool_str311[sizeof("incyrillic")];
+ char uniname2ctype_pool_str313[sizeof("incham")];
+ char uniname2ctype_pool_str315[sizeof("qmark")];
+ char uniname2ctype_pool_str320[sizeof("ri")];
+ char uniname2ctype_pool_str322[sizeof("qaac")];
+ char uniname2ctype_pool_str328[sizeof("insamaritan")];
+ char uniname2ctype_pool_str331[sizeof("latn")];
+ char uniname2ctype_pool_str335[sizeof("inmasaramgondi")];
+ char uniname2ctype_pool_str338[sizeof("inthaana")];
+ char uniname2ctype_pool_str340[sizeof("latin")];
+ char uniname2ctype_pool_str342[sizeof("inthai")];
+ char uniname2ctype_pool_str345[sizeof("lineseparator")];
+ char uniname2ctype_pool_str346[sizeof("pcm")];
+ char uniname2ctype_pool_str348[sizeof("inkatakana")];
+ char uniname2ctype_pool_str352[sizeof("inkaithi")];
+ char uniname2ctype_pool_str357[sizeof("inzanabazarsquare")];
+ char uniname2ctype_pool_str362[sizeof("inscriptionalparthian")];
+ char uniname2ctype_pool_str366[sizeof("initialpunctuation")];
+ char uniname2ctype_pool_str373[sizeof("mtei")];
+ char uniname2ctype_pool_str376[sizeof("vai")];
+ char uniname2ctype_pool_str377[sizeof("vaii")];
+ char uniname2ctype_pool_str386[sizeof("inkhmersymbols")];
+ char uniname2ctype_pool_str399[sizeof("insyriac")];
+ char uniname2ctype_pool_str401[sizeof("intakri")];
+ char uniname2ctype_pool_str404[sizeof("arabic")];
+ char uniname2ctype_pool_str411[sizeof("zs")];
+ char uniname2ctype_pool_str418[sizeof("katakana")];
+ char uniname2ctype_pool_str426[sizeof("prti")];
+ char uniname2ctype_pool_str442[sizeof("ascii")];
+ char uniname2ctype_pool_str445[sizeof("cs")];
+ char uniname2ctype_pool_str462[sizeof("ps")];
+ char uniname2ctype_pool_str468[sizeof("mand")];
+ char uniname2ctype_pool_str470[sizeof("privateuse")];
+ char uniname2ctype_pool_str475[sizeof("inruminumeralsymbols")];
+ char uniname2ctype_pool_str480[sizeof("inmyanmarextendeda")];
+ char uniname2ctype_pool_str481[sizeof("modi")];
+ char uniname2ctype_pool_str486[sizeof("incjkcompatibilityforms")];
+ char uniname2ctype_pool_str488[sizeof("inkanaextendeda")];
+ char uniname2ctype_pool_str491[sizeof("incjkcompatibilityideographs")];
+ char uniname2ctype_pool_str500[sizeof("brai")];
+ char uniname2ctype_pool_str504[sizeof("mend")];
+ char uniname2ctype_pool_str505[sizeof("ideo")];
+ char uniname2ctype_pool_str506[sizeof("letter")];
+ char uniname2ctype_pool_str509[sizeof("l")];
+ char uniname2ctype_pool_str511[sizeof("inmeeteimayek")];
+ char uniname2ctype_pool_str520[sizeof("inideographicdescriptioncharacters")];
+ char uniname2ctype_pool_str535[sizeof("xidcontinue")];
+ char uniname2ctype_pool_str538[sizeof("knda")];
+ char uniname2ctype_pool_str541[sizeof("innandinagari")];
+ char uniname2ctype_pool_str543[sizeof("kannada")];
+ char uniname2ctype_pool_str556[sizeof("inmodi")];
+ char uniname2ctype_pool_str558[sizeof("inlao")];
+ char uniname2ctype_pool_str560[sizeof("inoldnortharabian")];
+ char uniname2ctype_pool_str565[sizeof("intransportandmapsymbols")];
+ char uniname2ctype_pool_str566[sizeof("letternumber")];
+ char uniname2ctype_pool_str568[sizeof("gothic")];
+ char uniname2ctype_pool_str572[sizeof("inlineara")];
+ char uniname2ctype_pool_str577[sizeof("inmendekikakui")];
+ char uniname2ctype_pool_str578[sizeof("xidc")];
+ char uniname2ctype_pool_str579[sizeof("mongolian")];
+ char uniname2ctype_pool_str582[sizeof("inmiscellaneousmathematicalsymbolsa")];
+ char uniname2ctype_pool_str583[sizeof("inspecials")];
+ char uniname2ctype_pool_str590[sizeof("grlink")];
+ char uniname2ctype_pool_str594[sizeof("brahmi")];
+ char uniname2ctype_pool_str596[sizeof("inemoticons")];
+ char uniname2ctype_pool_str597[sizeof("kali")];
+ char uniname2ctype_pool_str600[sizeof("inolditalic")];
+ char uniname2ctype_pool_str604[sizeof("inmedefaidrin")];
+ char uniname2ctype_pool_str605[sizeof("inchesssymbols")];
+ char uniname2ctype_pool_str608[sizeof("incjkcompatibilityideographssupplement")];
+ char uniname2ctype_pool_str614[sizeof("inadlam")];
+ char uniname2ctype_pool_str624[sizeof("psalterpahlavi")];
+ char uniname2ctype_pool_str625[sizeof("incommonindicnumberforms")];
+ char uniname2ctype_pool_str630[sizeof("lt")];
+ char uniname2ctype_pool_str636[sizeof("innewa")];
+ char uniname2ctype_pool_str639[sizeof("sk")];
+ char uniname2ctype_pool_str642[sizeof("control")];
+ char uniname2ctype_pool_str645[sizeof("inancientsymbols")];
+ char uniname2ctype_pool_str647[sizeof("palm")];
+ char uniname2ctype_pool_str650[sizeof("inlycian")];
+ char uniname2ctype_pool_str657[sizeof("so")];
+ char uniname2ctype_pool_str660[sizeof("patternwhitespace")];
+ char uniname2ctype_pool_str668[sizeof("xids")];
+ char uniname2ctype_pool_str672[sizeof("inmandaic")];
+ char uniname2ctype_pool_str675[sizeof("idc")];
+ char uniname2ctype_pool_str678[sizeof("meroiticcursive")];
+ char uniname2ctype_pool_str695[sizeof("inwarangciti")];
+ char uniname2ctype_pool_str696[sizeof("sora")];
+ char uniname2ctype_pool_str697[sizeof("inopticalcharacterrecognition")];
+ char uniname2ctype_pool_str703[sizeof("inoldsogdian")];
+ char uniname2ctype_pool_str705[sizeof("inmalayalam")];
+ char uniname2ctype_pool_str707[sizeof("bamum")];
+ char uniname2ctype_pool_str708[sizeof("inkanasupplement")];
+ char uniname2ctype_pool_str713[sizeof("insundanese")];
+ char uniname2ctype_pool_str720[sizeof("grext")];
+ char uniname2ctype_pool_str737[sizeof("print")];
+ char uniname2ctype_pool_str738[sizeof("intaitham")];
+ char uniname2ctype_pool_str742[sizeof("lower")];
+ char uniname2ctype_pool_str753[sizeof("joinc")];
+ char uniname2ctype_pool_str755[sizeof("inoldsoutharabian")];
+ char uniname2ctype_pool_str760[sizeof("incjkstrokes")];
+ char uniname2ctype_pool_str761[sizeof("batk")];
+ char uniname2ctype_pool_str766[sizeof("samr")];
+ char uniname2ctype_pool_str767[sizeof("inwancho")];
+ char uniname2ctype_pool_str771[sizeof("batak")];
+ char uniname2ctype_pool_str772[sizeof("vs")];
+ char uniname2ctype_pool_str776[sizeof("patws")];
+ char uniname2ctype_pool_str783[sizeof("samaritan")];
+ char uniname2ctype_pool_str787[sizeof("idsbinaryoperator")];
+ char uniname2ctype_pool_str791[sizeof("pauc")];
+ char uniname2ctype_pool_str794[sizeof("insmallkanaextension")];
+ char uniname2ctype_pool_str797[sizeof("sm")];
+ char uniname2ctype_pool_str799[sizeof("indominotiles")];
+ char uniname2ctype_pool_str802[sizeof("alnum")];
+ char uniname2ctype_pool_str809[sizeof("insylotinagri")];
+ char uniname2ctype_pool_str814[sizeof("inugaritic")];
+ char uniname2ctype_pool_str818[sizeof("incontrolpictures")];
+ char uniname2ctype_pool_str821[sizeof("inlinearbideograms")];
+ char uniname2ctype_pool_str822[sizeof("inmusicalsymbols")];
+ char uniname2ctype_pool_str823[sizeof("s")];
+ char uniname2ctype_pool_str824[sizeof("ital")];
+ char uniname2ctype_pool_str825[sizeof("inmodifiertoneletters")];
+ char uniname2ctype_pool_str828[sizeof("inancientgreekmusicalnotation")];
+ char uniname2ctype_pool_str834[sizeof("patternsyntax")];
+ char uniname2ctype_pool_str838[sizeof("lisu")];
+ char uniname2ctype_pool_str842[sizeof("lowercase")];
+ char uniname2ctype_pool_str845[sizeof("cwcm")];
+ char uniname2ctype_pool_str847[sizeof("sc")];
+ char uniname2ctype_pool_str848[sizeof("bass")];
+ char uniname2ctype_pool_str855[sizeof("ids")];
+ char uniname2ctype_pool_str857[sizeof("inlatinextendeda")];
+ char uniname2ctype_pool_str862[sizeof("oriya")];
+ char uniname2ctype_pool_str875[sizeof("intaile")];
+ char uniname2ctype_pool_str886[sizeof("inmiscellaneoussymbols")];
+ char uniname2ctype_pool_str895[sizeof("inmiscellaneoussymbolsandarrows")];
+ char uniname2ctype_pool_str898[sizeof("incaucasianalbanian")];
+ char uniname2ctype_pool_str900[sizeof("inmiscellaneoussymbolsandpictographs")];
+ char uniname2ctype_pool_str906[sizeof("inoldturkic")];
+ char uniname2ctype_pool_str907[sizeof("insaurashtra")];
+ char uniname2ctype_pool_str924[sizeof("idcontinue")];
+ char uniname2ctype_pool_str926[sizeof("intamil")];
+ char uniname2ctype_pool_str928[sizeof("inmultani")];
+ char uniname2ctype_pool_str929[sizeof("inlatinextendede")];
+ char uniname2ctype_pool_str930[sizeof("pd")];
+ char uniname2ctype_pool_str946[sizeof("bali")];
+ char uniname2ctype_pool_str961[sizeof("blank")];
+ char uniname2ctype_pool_str963[sizeof("idst")];
+ char uniname2ctype_pool_str974[sizeof("inlydian")];
+ char uniname2ctype_pool_str986[sizeof("innewtailue")];
+ char uniname2ctype_pool_str994[sizeof("bengali")];
+ char uniname2ctype_pool_str995[sizeof("runr")];
+ char uniname2ctype_pool_str1005[sizeof("zl")];
+ char uniname2ctype_pool_str1009[sizeof("incyrillicextendeda")];
+ char uniname2ctype_pool_str1010[sizeof("ll")];
+ char uniname2ctype_pool_str1013[sizeof("indeseret")];
+ char uniname2ctype_pool_str1014[sizeof("intaixuanjingsymbols")];
+ char uniname2ctype_pool_str1015[sizeof("inancientgreeknumbers")];
+ char uniname2ctype_pool_str1021[sizeof("idstart")];
+ char uniname2ctype_pool_str1025[sizeof("inmeeteimayekextensions")];
+ char uniname2ctype_pool_str1028[sizeof("balinese")];
+ char uniname2ctype_pool_str1032[sizeof("dia")];
+ char uniname2ctype_pool_str1033[sizeof("di")];
+ char uniname2ctype_pool_str1035[sizeof("inspacingmodifierletters")];
+ char uniname2ctype_pool_str1036[sizeof("inearlydynasticcuneiform")];
+ char uniname2ctype_pool_str1049[sizeof("plrd")];
+ char uniname2ctype_pool_str1067[sizeof("canadianaboriginal")];
+ char uniname2ctype_pool_str1070[sizeof("zinh")];
+ char uniname2ctype_pool_str1072[sizeof("sind")];
+ char uniname2ctype_pool_str1080[sizeof("osage")];
+ char uniname2ctype_pool_str1081[sizeof("inlatinextendedc")];
+ char uniname2ctype_pool_str1085[sizeof("uideo")];
+ char uniname2ctype_pool_str1087[sizeof("incountingrodnumerals")];
+ char uniname2ctype_pool_str1090[sizeof("xidstart")];
+ char uniname2ctype_pool_str1091[sizeof("xdigit")];
+ char uniname2ctype_pool_str1093[sizeof("osma")];
+ char uniname2ctype_pool_str1097[sizeof("inkhudawadi")];
+ char uniname2ctype_pool_str1102[sizeof("inhanifirohingya")];
+ char uniname2ctype_pool_str1105[sizeof("gong")];
+ char uniname2ctype_pool_str1107[sizeof("ingrantha")];
+ char uniname2ctype_pool_str1109[sizeof("bidic")];
+ char uniname2ctype_pool_str1119[sizeof("mong")];
+ char uniname2ctype_pool_str1120[sizeof("cased")];
+ char uniname2ctype_pool_str1121[sizeof("incyrillicextendedc")];
+ char uniname2ctype_pool_str1134[sizeof("inhiragana")];
+ char uniname2ctype_pool_str1140[sizeof("sinhala")];
+ char uniname2ctype_pool_str1142[sizeof("adlm")];
+ char uniname2ctype_pool_str1146[sizeof("glagolitic")];
+ char uniname2ctype_pool_str1147[sizeof("sterm")];
+ char uniname2ctype_pool_str1149[sizeof("bamu")];
+ char uniname2ctype_pool_str1150[sizeof("georgian")];
+ char uniname2ctype_pool_str1151[sizeof("inosage")];
+ char uniname2ctype_pool_str1152[sizeof("gunjalagondi")];
+ char uniname2ctype_pool_str1153[sizeof("phoenician")];
+ char uniname2ctype_pool_str1157[sizeof("multani")];
+ char uniname2ctype_pool_str1158[sizeof("kaithi")];
+ char uniname2ctype_pool_str1164[sizeof("joincontrol")];
+ char uniname2ctype_pool_str1168[sizeof("runic")];
+ char uniname2ctype_pool_str1170[sizeof("ingeneralpunctuation")];
+ char uniname2ctype_pool_str1171[sizeof("inmahajani")];
+ char uniname2ctype_pool_str1174[sizeof("incyrillicsupplement")];
+ char uniname2ctype_pool_str1175[sizeof("lowercaseletter")];
+ char uniname2ctype_pool_str1176[sizeof("marchen")];
+ char uniname2ctype_pool_str1177[sizeof("graphemelink")];
+ char uniname2ctype_pool_str1178[sizeof("ingeorgian")];
+ char uniname2ctype_pool_str1180[sizeof("khojki")];
+ char uniname2ctype_pool_str1181[sizeof("cham")];
+ char uniname2ctype_pool_str1182[sizeof("inogham")];
+ char uniname2ctype_pool_str1183[sizeof("cher")];
+ char uniname2ctype_pool_str1185[sizeof("chakma")];
+ char uniname2ctype_pool_str1190[sizeof("emoji")];
+ char uniname2ctype_pool_str1191[sizeof("insiddham")];
+ char uniname2ctype_pool_str1197[sizeof("cherokee")];
+ char uniname2ctype_pool_str1198[sizeof("khar")];
+ char uniname2ctype_pool_str1203[sizeof("inmongolian")];
+ char uniname2ctype_pool_str1207[sizeof("incherokeesupplement")];
+ char uniname2ctype_pool_str1208[sizeof("diacritic")];
+ char uniname2ctype_pool_str1209[sizeof("manichaean")];
+ char uniname2ctype_pool_str1210[sizeof("xsux")];
+ char uniname2ctype_pool_str1212[sizeof("inolchiki")];
+ char uniname2ctype_pool_str1227[sizeof("quotationmark")];
+ char uniname2ctype_pool_str1231[sizeof("adlam")];
+ char uniname2ctype_pool_str1232[sizeof("inethiopic")];
+ char uniname2ctype_pool_str1233[sizeof("graphemebase")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ char uniname2ctype_pool_str1234[sizeof("age=11.0")];
+ char uniname2ctype_pool_str1235[sizeof("age=12.1")];
+ char uniname2ctype_pool_str1236[sizeof("age=10.0")];
+ char uniname2ctype_pool_str1237[sizeof("age=12.0")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ char uniname2ctype_pool_str1243[sizeof("casedletter")];
+ char uniname2ctype_pool_str1244[sizeof("ingurmukhi")];
+ char uniname2ctype_pool_str1245[sizeof("odi")];
+ char uniname2ctype_pool_str1246[sizeof("incjkunifiedideographsextensiona")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ char uniname2ctype_pool_str1247[sizeof("age=1.1")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ char uniname2ctype_pool_str1248[sizeof("lu")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ char uniname2ctype_pool_str1249[sizeof("age=4.1")];
+ char uniname2ctype_pool_str1250[sizeof("age=2.1")];
+ char uniname2ctype_pool_str1251[sizeof("age=4.0")];
+ char uniname2ctype_pool_str1252[sizeof("age=2.0")];
+ char uniname2ctype_pool_str1253[sizeof("age=9.0")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ char uniname2ctype_pool_str1254[sizeof("intamilsupplement")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ char uniname2ctype_pool_str1255[sizeof("age=6.1")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ char uniname2ctype_pool_str1256[sizeof("unknown")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ char uniname2ctype_pool_str1257[sizeof("age=6.0")];
+ char uniname2ctype_pool_str1258[sizeof("age=6.2")];
+ char uniname2ctype_pool_str1259[sizeof("age=3.1")];
+ char uniname2ctype_pool_str1260[sizeof("age=8.0")];
+ char uniname2ctype_pool_str1261[sizeof("age=3.0")];
+ char uniname2ctype_pool_str1262[sizeof("age=3.2")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ char uniname2ctype_pool_str1263[sizeof("cwt")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ char uniname2ctype_pool_str1264[sizeof("age=7.0")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ char uniname2ctype_pool_str1266[sizeof("unassigned")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ char uniname2ctype_pool_str1267[sizeof("age=6.3")];
+ char uniname2ctype_pool_str1268[sizeof("age=5.1")];
+ char uniname2ctype_pool_str1270[sizeof("age=5.0")];
+ char uniname2ctype_pool_str1271[sizeof("age=5.2")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ char uniname2ctype_pool_str1274[sizeof("ahom")];
+ char uniname2ctype_pool_str1282[sizeof("incjkunifiedideographsextensione")];
+ char uniname2ctype_pool_str1285[sizeof("khmr")];
+ char uniname2ctype_pool_str1289[sizeof("insinhala")];
+ char uniname2ctype_pool_str1292[sizeof("inmiscellaneoustechnical")];
+ char uniname2ctype_pool_str1297[sizeof("saur")];
+ char uniname2ctype_pool_str1300[sizeof("guru")];
+ char uniname2ctype_pool_str1301[sizeof("sundanese")];
+ char uniname2ctype_pool_str1306[sizeof("punct")];
+ char uniname2ctype_pool_str1314[sizeof("paucinhau")];
+ char uniname2ctype_pool_str1317[sizeof("gurmukhi")];
+ char uniname2ctype_pool_str1319[sizeof("variationselector")];
+ char uniname2ctype_pool_str1331[sizeof("logicalorderexception")];
+ char uniname2ctype_pool_str1340[sizeof("khmer")];
+ char uniname2ctype_pool_str1343[sizeof("limbu")];
+ char uniname2ctype_pool_str1354[sizeof("inscriptionalpahlavi")];
+ char uniname2ctype_pool_str1355[sizeof("oidc")];
+ char uniname2ctype_pool_str1358[sizeof("incjkunifiedideographsextensionc")];
+ char uniname2ctype_pool_str1360[sizeof("cntrl")];
+ char uniname2ctype_pool_str1365[sizeof("inlatinextendedadditional")];
+ char uniname2ctype_pool_str1366[sizeof("decimalnumber")];
+ char uniname2ctype_pool_str1367[sizeof("insorasompeng")];
+ char uniname2ctype_pool_str1369[sizeof("radical")];
+ char uniname2ctype_pool_str1373[sizeof("emojimodifier")];
+ char uniname2ctype_pool_str1375[sizeof("kharoshthi")];
+ char uniname2ctype_pool_str1380[sizeof("n")];
+ char uniname2ctype_pool_str1384[sizeof("math")];
+ char uniname2ctype_pool_str1387[sizeof("goth")];
+ char uniname2ctype_pool_str1400[sizeof("anatolianhieroglyphs")];
+ char uniname2ctype_pool_str1401[sizeof("inenclosedalphanumerics")];
+ char uniname2ctype_pool_str1407[sizeof("nandinagari")];
+ char uniname2ctype_pool_str1409[sizeof("no")];
+ char uniname2ctype_pool_str1419[sizeof("nko")];
+ char uniname2ctype_pool_str1420[sizeof("nkoo")];
+ char uniname2ctype_pool_str1422[sizeof("ingreekandcoptic")];
+ char uniname2ctype_pool_str1423[sizeof("olck")];
+ char uniname2ctype_pool_str1426[sizeof("p")];
+ char uniname2ctype_pool_str1428[sizeof("grantha")];
+ char uniname2ctype_pool_str1434[sizeof("olchiki")];
+ char uniname2ctype_pool_str1438[sizeof("incjkunifiedideographs")];
+ char uniname2ctype_pool_str1441[sizeof("zanb")];
+ char uniname2ctype_pool_str1442[sizeof("intirhuta")];
+ char uniname2ctype_pool_str1445[sizeof("oids")];
+ char uniname2ctype_pool_str1448[sizeof("inhatran")];
+ char uniname2ctype_pool_str1449[sizeof("linb")];
+ char uniname2ctype_pool_str1450[sizeof("xpeo")];
+ char uniname2ctype_pool_str1451[sizeof("mult")];
+ char uniname2ctype_pool_str1454[sizeof("saurashtra")];
+ char uniname2ctype_pool_str1457[sizeof("kthi")];
+ char uniname2ctype_pool_str1462[sizeof("inbhaiksuki")];
+ char uniname2ctype_pool_str1466[sizeof("olower")];
+ char uniname2ctype_pool_str1470[sizeof("innabataean")];
+ char uniname2ctype_pool_str1471[sizeof("inphoenician")];
+ char uniname2ctype_pool_str1475[sizeof("inkanbun")];
+ char uniname2ctype_pool_str1476[sizeof("inmeroitichieroglyphs")];
+ char uniname2ctype_pool_str1478[sizeof("inkayahli")];
+ char uniname2ctype_pool_str1481[sizeof("phnx")];
+ char uniname2ctype_pool_str1485[sizeof("inoriya")];
+ char uniname2ctype_pool_str1489[sizeof("enclosingmark")];
+ char uniname2ctype_pool_str1495[sizeof("sd")];
+ char uniname2ctype_pool_str1497[sizeof("inelbasan")];
+ char uniname2ctype_pool_str1498[sizeof("wara")];
+ char uniname2ctype_pool_str1499[sizeof("inenclosedideographicsupplement")];
+ char uniname2ctype_pool_str1501[sizeof("sidd")];
+ char uniname2ctype_pool_str1507[sizeof("linearb")];
+ char uniname2ctype_pool_str1509[sizeof("hani")];
+ char uniname2ctype_pool_str1512[sizeof("han")];
+ char uniname2ctype_pool_str1517[sizeof("inenclosedalphanumericsupplement")];
+ char uniname2ctype_pool_str1519[sizeof("medf")];
+ char uniname2ctype_pool_str1520[sizeof("bidicontrol")];
+ char uniname2ctype_pool_str1523[sizeof("hano")];
+ char uniname2ctype_pool_str1524[sizeof("inphaistosdisc")];
+ char uniname2ctype_pool_str1529[sizeof("limb")];
+ char uniname2ctype_pool_str1531[sizeof("inkangxiradicals")];
+ char uniname2ctype_pool_str1533[sizeof("lepc")];
+ char uniname2ctype_pool_str1535[sizeof("medefaidrin")];
+ char uniname2ctype_pool_str1536[sizeof("braille")];
+ char uniname2ctype_pool_str1537[sizeof("regionalindicator")];
+ char uniname2ctype_pool_str1542[sizeof("inlowsurrogates")];
+ char uniname2ctype_pool_str1544[sizeof("inshorthandformatcontrols")];
+ char uniname2ctype_pool_str1547[sizeof("brah")];
+ char uniname2ctype_pool_str1548[sizeof("inkhojki")];
+ char uniname2ctype_pool_str1549[sizeof("inoldhungarian")];
+ char uniname2ctype_pool_str1552[sizeof("hanunoo")];
+ char uniname2ctype_pool_str1555[sizeof("hira")];
+ char uniname2ctype_pool_str1557[sizeof("beng")];
+ char uniname2ctype_pool_str1563[sizeof("emojimodifierbase")];
+ char uniname2ctype_pool_str1565[sizeof("inarabic")];
+ char uniname2ctype_pool_str1567[sizeof("lyci")];
+ char uniname2ctype_pool_str1569[sizeof("ahex")];
+ char uniname2ctype_pool_str1572[sizeof("inherited")];
+ char uniname2ctype_pool_str1580[sizeof("glag")];
+ char uniname2ctype_pool_str1582[sizeof("lycian")];
+ char uniname2ctype_pool_str1587[sizeof("indogra")];
+ char uniname2ctype_pool_str1594[sizeof("dsrt")];
+ char uniname2ctype_pool_str1597[sizeof("arab")];
+ char uniname2ctype_pool_str1602[sizeof("mymr")];
+ char uniname2ctype_pool_str1607[sizeof("myanmar")];
+ char uniname2ctype_pool_str1613[sizeof("phli")];
+ char uniname2ctype_pool_str1617[sizeof("inimperialaramaic")];
+ char uniname2ctype_pool_str1622[sizeof("ingreekextended")];
+ char uniname2ctype_pool_str1623[sizeof("inanatolianhieroglyphs")];
+ char uniname2ctype_pool_str1629[sizeof("punctuation")];
+ char uniname2ctype_pool_str1631[sizeof("takri")];
+ char uniname2ctype_pool_str1635[sizeof("graphemeextend")];
+ char uniname2ctype_pool_str1638[sizeof("invai")];
+ char uniname2ctype_pool_str1643[sizeof("cwl")];
+ char uniname2ctype_pool_str1654[sizeof("ingeometricshapes")];
+ char uniname2ctype_pool_str1655[sizeof("emojicomponent")];
+ char uniname2ctype_pool_str1662[sizeof("coptic")];
+ char uniname2ctype_pool_str1671[sizeof("deseret")];
+ char uniname2ctype_pool_str1675[sizeof("inarabicpresentationformsa")];
+ char uniname2ctype_pool_str1676[sizeof("takr")];
+ char uniname2ctype_pool_str1677[sizeof("inbasiclatin")];
+ char uniname2ctype_pool_str1682[sizeof("incjkunifiedideographsextensiond")];
+ char uniname2ctype_pool_str1686[sizeof("sinh")];
+ char uniname2ctype_pool_str1687[sizeof("sund")];
+ char uniname2ctype_pool_str1691[sizeof("shavian")];
+ char uniname2ctype_pool_str1692[sizeof("taile")];
+ char uniname2ctype_pool_str1699[sizeof("insundanesesupplement")];
+ char uniname2ctype_pool_str1702[sizeof("inelymaic")];
+ char uniname2ctype_pool_str1703[sizeof("insoyombo")];
+ char uniname2ctype_pool_str1704[sizeof("bhks")];
+ char uniname2ctype_pool_str1714[sizeof("bhaiksuki")];
+ char uniname2ctype_pool_str1716[sizeof("incjkcompatibility")];
+ char uniname2ctype_pool_str1722[sizeof("inhanunoo")];
+ char uniname2ctype_pool_str1724[sizeof("intangut")];
+ char uniname2ctype_pool_str1728[sizeof("sogdian")];
+ char uniname2ctype_pool_str1729[sizeof("inlatinextendedd")];
+ char uniname2ctype_pool_str1730[sizeof("sogo")];
+ char uniname2ctype_pool_str1731[sizeof("insinhalaarchaicnumbers")];
+ char uniname2ctype_pool_str1732[sizeof("ideographic")];
+ char uniname2ctype_pool_str1733[sizeof("ugar")];
+ char uniname2ctype_pool_str1740[sizeof("copt")];
+ char uniname2ctype_pool_str1742[sizeof("imperialaramaic")];
+ char uniname2ctype_pool_str1745[sizeof("insogdian")];
+ char uniname2ctype_pool_str1746[sizeof("indingbats")];
+ char uniname2ctype_pool_str1750[sizeof("format")];
+ char uniname2ctype_pool_str1752[sizeof("ininscriptionalpahlavi")];
+ char uniname2ctype_pool_str1757[sizeof("ininscriptionalparthian")];
+ char uniname2ctype_pool_str1766[sizeof("grbase")];
+ char uniname2ctype_pool_str1769[sizeof("inbatak")];
+ char uniname2ctype_pool_str1776[sizeof("cprt")];
+ char uniname2ctype_pool_str1780[sizeof("cwcf")];
+ char uniname2ctype_pool_str1788[sizeof("cuneiform")];
+ char uniname2ctype_pool_str1791[sizeof("term")];
+ char uniname2ctype_pool_str1806[sizeof("intibetan")];
+ char uniname2ctype_pool_str1810[sizeof("intags")];
+ char uniname2ctype_pool_str1811[sizeof("asciihexdigit")];
+ char uniname2ctype_pool_str1813[sizeof("sentenceterminal")];
+ char uniname2ctype_pool_str1816[sizeof("inmayannumerals")];
+ char uniname2ctype_pool_str1821[sizeof("nand")];
+ char uniname2ctype_pool_str1825[sizeof("patsyn")];
+ char uniname2ctype_pool_str1826[sizeof("hatran")];
+ char uniname2ctype_pool_str1828[sizeof("inblockelements")];
+ char uniname2ctype_pool_str1838[sizeof("inornamentaldingbats")];
+ char uniname2ctype_pool_str1842[sizeof("innumberforms")];
+ char uniname2ctype_pool_str1843[sizeof("oldpersian")];
+ char uniname2ctype_pool_str1846[sizeof("inshavian")];
+ char uniname2ctype_pool_str1848[sizeof("bopo")];
+ char uniname2ctype_pool_str1861[sizeof("hatr")];
+ char uniname2ctype_pool_str1866[sizeof("caseignorable")];
+ char uniname2ctype_pool_str1871[sizeof("inoldpersian")];
+ char uniname2ctype_pool_str1878[sizeof("modifierletter")];
+ char uniname2ctype_pool_str1881[sizeof("cwu")];
+ char uniname2ctype_pool_str1891[sizeof("lydi")];
+ char uniname2ctype_pool_str1892[sizeof("inbyzantinemusicalsymbols")];
+ char uniname2ctype_pool_str1896[sizeof("ingeometricshapesextended")];
+ char uniname2ctype_pool_str1904[sizeof("inmyanmarextendedb")];
+ char uniname2ctype_pool_str1905[sizeof("innushu")];
+ char uniname2ctype_pool_str1906[sizeof("lydian")];
+ char uniname2ctype_pool_str1911[sizeof("inunifiedcanadianaboriginalsyllabics")];
+ char uniname2ctype_pool_str1915[sizeof("orkh")];
+ char uniname2ctype_pool_str1928[sizeof("inyiradicals")];
+ char uniname2ctype_pool_str1929[sizeof("inkatakanaphoneticextensions")];
+ char uniname2ctype_pool_str1930[sizeof("inethiopicextendeda")];
+ char uniname2ctype_pool_str1932[sizeof("incoptic")];
+ char uniname2ctype_pool_str1936[sizeof("inarabicextendeda")];
+ char uniname2ctype_pool_str1947[sizeof("oldpermic")];
+ char uniname2ctype_pool_str1950[sizeof("incjksymbolsandpunctuation")];
+ char uniname2ctype_pool_str1951[sizeof("word")];
+ char uniname2ctype_pool_str1958[sizeof("bopomofo")];
+ char uniname2ctype_pool_str1961[sizeof("ogam")];
+ char uniname2ctype_pool_str1964[sizeof("inlisu")];
+ char uniname2ctype_pool_str1967[sizeof("inoldpermic")];
+ char uniname2ctype_pool_str1968[sizeof("innoblock")];
+ char uniname2ctype_pool_str1971[sizeof("taiviet")];
+ char uniname2ctype_pool_str1985[sizeof("inbraillepatterns")];
+ char uniname2ctype_pool_str1991[sizeof("alpha")];
+ char uniname2ctype_pool_str1993[sizeof("inbalinese")];
+ char uniname2ctype_pool_str1994[sizeof("sorasompeng")];
+ char uniname2ctype_pool_str1996[sizeof("closepunctuation")];
+ char uniname2ctype_pool_str2006[sizeof("inmiscellaneousmathematicalsymbolsb")];
+ char uniname2ctype_pool_str2010[sizeof("inlepcha")];
+ char uniname2ctype_pool_str2014[sizeof("insyriacsupplement")];
+ char uniname2ctype_pool_str2016[sizeof("newa")];
+ char uniname2ctype_pool_str2023[sizeof("spacingmark")];
+ char uniname2ctype_pool_str2024[sizeof("inpalmyrene")];
+ char uniname2ctype_pool_str2033[sizeof("cyrl")];
+ char uniname2ctype_pool_str2043[sizeof("assigned")];
+ char uniname2ctype_pool_str2048[sizeof("mlym")];
+ char uniname2ctype_pool_str2055[sizeof("malayalam")];
+ char uniname2ctype_pool_str2058[sizeof("ext")];
+ char uniname2ctype_pool_str2062[sizeof("newtailue")];
+ char uniname2ctype_pool_str2070[sizeof("space")];
+ char uniname2ctype_pool_str2073[sizeof("intelugu")];
+ char uniname2ctype_pool_str2078[sizeof("idsb")];
+ char uniname2ctype_pool_str2083[sizeof("indevanagari")];
+ char uniname2ctype_pool_str2084[sizeof("avestan")];
+ char uniname2ctype_pool_str2085[sizeof("cf")];
+ char uniname2ctype_pool_str2093[sizeof("palmyrene")];
+ char uniname2ctype_pool_str2095[sizeof("inethiopicsupplement")];
+ char uniname2ctype_pool_str2097[sizeof("soyo")];
+ char uniname2ctype_pool_str2098[sizeof("xposixpunct")];
+ char uniname2ctype_pool_str2102[sizeof("pf")];
+ char uniname2ctype_pool_str2103[sizeof("sarb")];
+ char uniname2ctype_pool_str2109[sizeof("zanabazarsquare")];
+ char uniname2ctype_pool_str2110[sizeof("ugaritic")];
+ char uniname2ctype_pool_str2112[sizeof("osge")];
+ char uniname2ctype_pool_str2114[sizeof("java")];
+ char uniname2ctype_pool_str2117[sizeof("sharada")];
+ char uniname2ctype_pool_str2119[sizeof("dogra")];
+ char uniname2ctype_pool_str2135[sizeof("bugi")];
+ char uniname2ctype_pool_str2137[sizeof("meroitichieroglyphs")];
+ char uniname2ctype_pool_str2145[sizeof("separator")];
+ char uniname2ctype_pool_str2146[sizeof("ingeorgiansupplement")];
+ char uniname2ctype_pool_str2149[sizeof("sogd")];
+ char uniname2ctype_pool_str2150[sizeof("tale")];
+ char uniname2ctype_pool_str2153[sizeof("inunifiedcanadianaboriginalsyllabicsextended")];
+ char uniname2ctype_pool_str2161[sizeof("terminalpunctuation")];
+ char uniname2ctype_pool_str2165[sizeof("shrd")];
+ char uniname2ctype_pool_str2166[sizeof("graph")];
+ char uniname2ctype_pool_str2167[sizeof("olditalic")];
+ char uniname2ctype_pool_str2170[sizeof("dogr")];
+ char uniname2ctype_pool_str2173[sizeof("gujr")];
+ char uniname2ctype_pool_str2181[sizeof("phag")];
+ char uniname2ctype_pool_str2182[sizeof("gujarati")];
+ char uniname2ctype_pool_str2195[sizeof("inhanguljamo")];
+ char uniname2ctype_pool_str2199[sizeof("javanese")];
+ char uniname2ctype_pool_str2201[sizeof("taml")];
+ char uniname2ctype_pool_str2204[sizeof("inphoneticextensions")];
+ char uniname2ctype_pool_str2207[sizeof("siddham")];
+ char uniname2ctype_pool_str2217[sizeof("buginese")];
+ char uniname2ctype_pool_str2218[sizeof("inmongoliansupplement")];
+ char uniname2ctype_pool_str2222[sizeof("invariationselectors")];
+ char uniname2ctype_pool_str2224[sizeof("inhanguljamoextendeda")];
+ char uniname2ctype_pool_str2225[sizeof("inverticalforms")];
+ char uniname2ctype_pool_str2228[sizeof("syrc")];
+ char uniname2ctype_pool_str2229[sizeof("number")];
+ char uniname2ctype_pool_str2235[sizeof("incopticepactnumbers")];
+ char uniname2ctype_pool_str2238[sizeof("avst")];
+ char uniname2ctype_pool_str2244[sizeof("inbamum")];
+ char uniname2ctype_pool_str2247[sizeof("nd")];
+ char uniname2ctype_pool_str2248[sizeof("insuttonsignwriting")];
+ char uniname2ctype_pool_str2252[sizeof("extender")];
+ char uniname2ctype_pool_str2258[sizeof("intaiviet")];
+ char uniname2ctype_pool_str2260[sizeof("hex")];
+ char uniname2ctype_pool_str2268[sizeof("incjkunifiedideographsextensionf")];
+ char uniname2ctype_pool_str2271[sizeof("other")];
+ char uniname2ctype_pool_str2272[sizeof("otheridcontinue")];
+ char uniname2ctype_pool_str2278[sizeof("shaw")];
+ char uniname2ctype_pool_str2282[sizeof("dash")];
+ char uniname2ctype_pool_str2285[sizeof("othernumber")];
+ char uniname2ctype_pool_str2294[sizeof("orya")];
+ char uniname2ctype_pool_str2302[sizeof("invedicextensions")];
+ char uniname2ctype_pool_str2305[sizeof("sgnw")];
+ char uniname2ctype_pool_str2312[sizeof("caucasianalbanian")];
+ char uniname2ctype_pool_str2315[sizeof("inmathematicalalphanumericsymbols")];
+ char uniname2ctype_pool_str2321[sizeof("inphoneticextensionssupplement")];
+ char uniname2ctype_pool_str2339[sizeof("invariationselectorssupplement")];
+ char uniname2ctype_pool_str2343[sizeof("induployan")];
+ char uniname2ctype_pool_str2344[sizeof("syriac")];
+ char uniname2ctype_pool_str2357[sizeof("oalpha")];
+ char uniname2ctype_pool_str2361[sizeof("innyiakengpuachuehmong")];
+ char uniname2ctype_pool_str2364[sizeof("incombiningdiacriticalmarks")];
+ char uniname2ctype_pool_str2365[sizeof("inethiopicextended")];
+ char uniname2ctype_pool_str2373[sizeof("nl")];
+ char uniname2ctype_pool_str2374[sizeof("incombiningdiacriticalmarksforsymbols")];
+ char uniname2ctype_pool_str2375[sizeof("khudawadi")];
+ char uniname2ctype_pool_str2378[sizeof("otheralphabetic")];
+ char uniname2ctype_pool_str2389[sizeof("oldhungarian")];
+ char uniname2ctype_pool_str2396[sizeof("incurrencysymbols")];
+ char uniname2ctype_pool_str2397[sizeof("incjkradicalssupplement")];
+ char uniname2ctype_pool_str2398[sizeof("inglagolitic")];
+ char uniname2ctype_pool_str2415[sizeof("intifinagh")];
+ char uniname2ctype_pool_str2416[sizeof("ingeorgianextended")];
+ char uniname2ctype_pool_str2427[sizeof("surrogate")];
+ char uniname2ctype_pool_str2433[sizeof("incyrillicextendedb")];
+ char uniname2ctype_pool_str2440[sizeof("ethi")];
+ char uniname2ctype_pool_str2451[sizeof("titlecaseletter")];
+ char uniname2ctype_pool_str2454[sizeof("rohg")];
+ char uniname2ctype_pool_str2458[sizeof("inmeroiticcursive")];
+ char uniname2ctype_pool_str2460[sizeof("idstrinaryoperator")];
+ char uniname2ctype_pool_str2470[sizeof("inphagspa")];
+ char uniname2ctype_pool_str2475[sizeof("lepcha")];
+ char uniname2ctype_pool_str2479[sizeof("intagalog")];
+ char uniname2ctype_pool_str2480[sizeof("mathsymbol")];
+ char uniname2ctype_pool_str2481[sizeof("incombiningdiacriticalmarkssupplement")];
+ char uniname2ctype_pool_str2506[sizeof("inbrahmi")];
+ char uniname2ctype_pool_str2513[sizeof("insymbolsandpictographsextendeda")];
+ char uniname2ctype_pool_str2519[sizeof("inlinearbsyllabary")];
+ char uniname2ctype_pool_str2529[sizeof("oldturkic")];
+ char uniname2ctype_pool_str2534[sizeof("inbengali")];
+ char uniname2ctype_pool_str2540[sizeof("wancho")];
+ char uniname2ctype_pool_str2542[sizeof("osmanya")];
+ char uniname2ctype_pool_str2548[sizeof("buhd")];
+ char uniname2ctype_pool_str2552[sizeof("insmallformvariants")];
+ char uniname2ctype_pool_str2561[sizeof("indevanagariextended")];
+ char uniname2ctype_pool_str2562[sizeof("softdotted")];
+ char uniname2ctype_pool_str2564[sizeof("inbuginese")];
+ char uniname2ctype_pool_str2566[sizeof("mahj")];
+ char uniname2ctype_pool_str2567[sizeof("inlatin1supplement")];
+ char uniname2ctype_pool_str2570[sizeof("ingothic")];
+ char uniname2ctype_pool_str2575[sizeof("mahajani")];
+ char uniname2ctype_pool_str2576[sizeof("hang")];
+ char uniname2ctype_pool_str2579[sizeof("sylo")];
+ char uniname2ctype_pool_str2586[sizeof("warangciti")];
+ char uniname2ctype_pool_str2595[sizeof("ingujarati")];
+ char uniname2ctype_pool_str2603[sizeof("tirhuta")];
+ char uniname2ctype_pool_str2606[sizeof("incombiningdiacriticalmarksextended")];
+ char uniname2ctype_pool_str2609[sizeof("spaceseparator")];
+ char uniname2ctype_pool_str2614[sizeof("ingunjalagondi")];
+ char uniname2ctype_pool_str2624[sizeof("wcho")];
+ char uniname2ctype_pool_str2631[sizeof("hiragana")];
+ char uniname2ctype_pool_str2634[sizeof("extendedpictographic")];
+ char uniname2ctype_pool_str2643[sizeof("inrejang")];
+ char uniname2ctype_pool_str2644[sizeof("inottomansiyaqnumbers")];
+ char uniname2ctype_pool_str2648[sizeof("nchar")];
+ char uniname2ctype_pool_str2650[sizeof("cyrillic")];
+ char uniname2ctype_pool_str2653[sizeof("khoj")];
+ char uniname2ctype_pool_str2656[sizeof("inlimbu")];
+ char uniname2ctype_pool_str2663[sizeof("hmng")];
+ char uniname2ctype_pool_str2665[sizeof("thaa")];
+ char uniname2ctype_pool_str2668[sizeof("thai")];
+ char uniname2ctype_pool_str2670[sizeof("incjkunifiedideographsextensionb")];
+ char uniname2ctype_pool_str2673[sizeof("deva")];
+ char uniname2ctype_pool_str2676[sizeof("thaana")];
+ char uniname2ctype_pool_str2688[sizeof("phagspa")];
+ char uniname2ctype_pool_str2691[sizeof("devanagari")];
+ char uniname2ctype_pool_str2692[sizeof("tang")];
+ char uniname2ctype_pool_str2694[sizeof("currencysymbol")];
+ char uniname2ctype_pool_str2698[sizeof("tagbanwa")];
+ char uniname2ctype_pool_str2701[sizeof("inenclosedcjklettersandmonths")];
+ char uniname2ctype_pool_str2702[sizeof("tamil")];
+ char uniname2ctype_pool_str2721[sizeof("tirh")];
+ char uniname2ctype_pool_str2723[sizeof("digit")];
+ char uniname2ctype_pool_str2732[sizeof("talu")];
+ char uniname2ctype_pool_str2747[sizeof("zp")];
+ char uniname2ctype_pool_str2750[sizeof("inpaucinhau")];
+ char uniname2ctype_pool_str2760[sizeof("taitham")];
+ char uniname2ctype_pool_str2764[sizeof("otherlowercase")];
+ char uniname2ctype_pool_str2768[sizeof("telu")];
+ char uniname2ctype_pool_str2769[sizeof("inaegeannumbers")];
+ char uniname2ctype_pool_str2777[sizeof("otherletter")];
+ char uniname2ctype_pool_str2780[sizeof("whitespace")];
+ char uniname2ctype_pool_str2793[sizeof("nonspacingmark")];
+ char uniname2ctype_pool_str2816[sizeof("graphemeclusterbreak=spacingmark")];
+ char uniname2ctype_pool_str2821[sizeof("inletterlikesymbols")];
+ char uniname2ctype_pool_str2834[sizeof("intagbanwa")];
+ char uniname2ctype_pool_str2841[sizeof("oldsogdian")];
+ char uniname2ctype_pool_str2848[sizeof("otheridstart")];
+ char uniname2ctype_pool_str2852[sizeof("graphemeclusterbreak=cr")];
+ char uniname2ctype_pool_str2855[sizeof("narb")];
+ char uniname2ctype_pool_str2856[sizeof("changeswhencasemapped")];
+ char uniname2ctype_pool_str2859[sizeof("inbopomofo")];
+ char uniname2ctype_pool_str2862[sizeof("tangut")];
+ char uniname2ctype_pool_str2867[sizeof("graphemeclusterbreak=regionalindicator")];
+ char uniname2ctype_pool_str2871[sizeof("noncharactercodepoint")];
+ char uniname2ctype_pool_str2883[sizeof("otheruppercase")];
+ char uniname2ctype_pool_str2885[sizeof("rjng")];
+ char uniname2ctype_pool_str2886[sizeof("sylotinagri")];
+ char uniname2ctype_pool_str2904[sizeof("inhangulsyllables")];
+ char uniname2ctype_pool_str2905[sizeof("emojipresentation")];
+ char uniname2ctype_pool_str2906[sizeof("inindicsiyaqnumbers")];
+ char uniname2ctype_pool_str2909[sizeof("inbassavah")];
+ char uniname2ctype_pool_str2912[sizeof("ogrext")];
+ char uniname2ctype_pool_str2926[sizeof("othersymbol")];
+ char uniname2ctype_pool_str2938[sizeof("oupper")];
+ char uniname2ctype_pool_str2941[sizeof("inbuhid")];
+ char uniname2ctype_pool_str2963[sizeof("hmnp")];
+ char uniname2ctype_pool_str2964[sizeof("inpsalterpahlavi")];
+ char uniname2ctype_pool_str2967[sizeof("finalpunctuation")];
+ char uniname2ctype_pool_str2980[sizeof("phlp")];
+ char uniname2ctype_pool_str2984[sizeof("inbamumsupplement")];
+ char uniname2ctype_pool_str2986[sizeof("buhid")];
+ char uniname2ctype_pool_str2987[sizeof("paragraphseparator")];
+ char uniname2ctype_pool_str2988[sizeof("inalphabeticpresentationforms")];
+ char uniname2ctype_pool_str2993[sizeof("omath")];
+ char uniname2ctype_pool_str3000[sizeof("any")];
+ char uniname2ctype_pool_str3001[sizeof("elba")];
+ char uniname2ctype_pool_str3002[sizeof("changeswhentitlecased")];
+ char uniname2ctype_pool_str3005[sizeof("incombininghalfmarks")];
+ char uniname2ctype_pool_str3006[sizeof("intangutcomponents")];
+ char uniname2ctype_pool_str3012[sizeof("hebr")];
+ char uniname2ctype_pool_str3028[sizeof("deprecated")];
+ char uniname2ctype_pool_str3045[sizeof("inarabicmathematicalalphabeticsymbols")];
+ char uniname2ctype_pool_str3055[sizeof("inprivateusearea")];
+ char uniname2ctype_pool_str3089[sizeof("kayahli")];
+ char uniname2ctype_pool_str3098[sizeof("inplayingcards")];
+ char uniname2ctype_pool_str3099[sizeof("inarabicpresentationformsb")];
+ char uniname2ctype_pool_str3100[sizeof("ogham")];
+ char uniname2ctype_pool_str3101[sizeof("elym")];
+ char uniname2ctype_pool_str3107[sizeof("graphemeclusterbreak=t")];
+ char uniname2ctype_pool_str3109[sizeof("graphemeclusterbreak=lvt")];
+ char uniname2ctype_pool_str3111[sizeof("nbat")];
+ char uniname2ctype_pool_str3125[sizeof("nabataean")];
+ char uniname2ctype_pool_str3126[sizeof("hangul")];
+ char uniname2ctype_pool_str3134[sizeof("elymaic")];
+ char uniname2ctype_pool_str3158[sizeof("inhebrew")];
+ char uniname2ctype_pool_str3165[sizeof("injavanese")];
+ char uniname2ctype_pool_str3169[sizeof("symbol")];
+ char uniname2ctype_pool_str3176[sizeof("inmathematicaloperators")];
+ char uniname2ctype_pool_str3180[sizeof("inarabicsupplement")];
+ char uniname2ctype_pool_str3185[sizeof("cypriot")];
+ char uniname2ctype_pool_str3194[sizeof("hung")];
+ char uniname2ctype_pool_str3205[sizeof("wspace")];
+ char uniname2ctype_pool_str3209[sizeof("changeswhenlowercased")];
+ char uniname2ctype_pool_str3215[sizeof("elbasan")];
+ char uniname2ctype_pool_str3218[sizeof("hluw")];
+ char uniname2ctype_pool_str3237[sizeof("insuperscriptsandsubscripts")];
+ char uniname2ctype_pool_str3239[sizeof("graphemeclusterbreak=extend")];
+ char uniname2ctype_pool_str3240[sizeof("graphemeclusterbreak=prepend")];
+ char uniname2ctype_pool_str3248[sizeof("nshu")];
+ char uniname2ctype_pool_str3254[sizeof("oldnortharabian")];
+ char uniname2ctype_pool_str3266[sizeof("inyijinghexagramsymbols")];
+ char uniname2ctype_pool_str3286[sizeof("hexdigit")];
+ char uniname2ctype_pool_str3297[sizeof("graphemeclusterbreak=l")];
+ char uniname2ctype_pool_str3303[sizeof("graphemeclusterbreak=control")];
+ char uniname2ctype_pool_str3309[sizeof("bassavah")];
+ char uniname2ctype_pool_str3317[sizeof("otherdefaultignorablecodepoint")];
+ char uniname2ctype_pool_str3328[sizeof("changeswhenuppercased")];
+ char uniname2ctype_pool_str3329[sizeof("inalchemicalsymbols")];
+ char uniname2ctype_pool_str3348[sizeof("insupplementalarrowsa")];
+ char uniname2ctype_pool_str3349[sizeof("inyisyllables")];
+ char uniname2ctype_pool_str3351[sizeof("tibt")];
+ char uniname2ctype_pool_str3360[sizeof("othermath")];
+ char uniname2ctype_pool_str3363[sizeof("tibetan")];
+ char uniname2ctype_pool_str3365[sizeof("inmahjongtiles")];
+ char uniname2ctype_pool_str3433[sizeof("signwriting")];
+ char uniname2ctype_pool_str3436[sizeof("nushu")];
+ char uniname2ctype_pool_str3439[sizeof("modifiersymbol")];
+ char uniname2ctype_pool_str3442[sizeof("inhalfwidthandfullwidthforms")];
+ char uniname2ctype_pool_str3458[sizeof("upper")];
+ char uniname2ctype_pool_str3460[sizeof("insupplementalarrowsc")];
+ char uniname2ctype_pool_str3511[sizeof("insupplementalmathematicaloperators")];
+ char uniname2ctype_pool_str3512[sizeof("incypriotsyllabary")];
+ char uniname2ctype_pool_str3517[sizeof("dupl")];
+ char uniname2ctype_pool_str3531[sizeof("tavt")];
+ char uniname2ctype_pool_str3532[sizeof("inpahawhhmong")];
+ char uniname2ctype_pool_str3533[sizeof("alphabetic")];
+ char uniname2ctype_pool_str3550[sizeof("dashpunctuation")];
+ char uniname2ctype_pool_str3558[sizeof("uppercase")];
+ char uniname2ctype_pool_str3613[sizeof("soyombo")];
+ char uniname2ctype_pool_str3614[sizeof("hanifirohingya")];
+ char uniname2ctype_pool_str3616[sizeof("otherpunctuation")];
+ char uniname2ctype_pool_str3628[sizeof("defaultignorablecodepoint")];
+ char uniname2ctype_pool_str3648[sizeof("inhanguljamoextendedb")];
+ char uniname2ctype_pool_str3664[sizeof("aghb")];
+ char uniname2ctype_pool_str3703[sizeof("tifinagh")];
+ char uniname2ctype_pool_str3705[sizeof("inlatinextendedb")];
+ char uniname2ctype_pool_str3714[sizeof("tfng")];
+ char uniname2ctype_pool_str3766[sizeof("inhighprivateusesurrogates")];
+ char uniname2ctype_pool_str3791[sizeof("changeswhencasefolded")];
+ char uniname2ctype_pool_str3805[sizeof("dep")];
+ char uniname2ctype_pool_str3819[sizeof("oldsoutharabian")];
+ char uniname2ctype_pool_str3821[sizeof("graphemeclusterbreak=lf")];
+ char uniname2ctype_pool_str3842[sizeof("pahawhhmong")];
+ char uniname2ctype_pool_str3845[sizeof("unifiedideograph")];
+ char uniname2ctype_pool_str3891[sizeof("uppercaseletter")];
+ char uniname2ctype_pool_str3924[sizeof("insupplementalpunctuation")];
+ char uniname2ctype_pool_str3942[sizeof("ethiopic")];
+ char uniname2ctype_pool_str3976[sizeof("inglagoliticsupplement")];
+ char uniname2ctype_pool_str3995[sizeof("rejang")];
+ char uniname2ctype_pool_str4087[sizeof("inbopomofoextended")];
+ char uniname2ctype_pool_str4109[sizeof("tagb")];
+ char uniname2ctype_pool_str4137[sizeof("othergraphemeextend")];
+ char uniname2ctype_pool_str4162[sizeof("inegyptianhieroglyphs")];
+ char uniname2ctype_pool_str4175[sizeof("inegyptianhieroglyphformatcontrols")];
+ char uniname2ctype_pool_str4203[sizeof("hebrew")];
+ char uniname2ctype_pool_str4254[sizeof("tglg")];
+ char uniname2ctype_pool_str4276[sizeof("tagalog")];
+ char uniname2ctype_pool_str4291[sizeof("graphemeclusterbreak=zwj")];
+ char uniname2ctype_pool_str4321[sizeof("zyyy")];
+ char uniname2ctype_pool_str4360[sizeof("hyphen")];
+ char uniname2ctype_pool_str4397[sizeof("inboxdrawing")];
+ char uniname2ctype_pool_str4405[sizeof("graphemeclusterbreak=v")];
+ char uniname2ctype_pool_str4406[sizeof("graphemeclusterbreak=lv")];
+ char uniname2ctype_pool_str4460[sizeof("telugu")];
+ char uniname2ctype_pool_str4485[sizeof("duployan")];
+ char uniname2ctype_pool_str4528[sizeof("openpunctuation")];
+ char uniname2ctype_pool_str4674[sizeof("insupplementaryprivateuseareaa")];
+ char uniname2ctype_pool_str4683[sizeof("inhighsurrogates")];
+ char uniname2ctype_pool_str4772[sizeof("insupplementalarrowsb")];
+ char uniname2ctype_pool_str4948[sizeof("insupplementalsymbolsandpictographs")];
+ char uniname2ctype_pool_str4955[sizeof("egyp")];
+ char uniname2ctype_pool_str4986[sizeof("inhangulcompatibilityjamo")];
+ char uniname2ctype_pool_str5114[sizeof("nyiakengpuachuehmong")];
+ char uniname2ctype_pool_str5608[sizeof("egyptianhieroglyphs")];
+ char uniname2ctype_pool_str6098[sizeof("insupplementaryprivateuseareab")];
+#endif /* USE_UNICODE_PROPERTIES */
+ };
+static const struct uniname2ctype_pool_t uniname2ctype_pool_contents =
+ {
+#ifndef USE_UNICODE_PROPERTIES
+ "word",
+#else /* USE_UNICODE_PROPERTIES */
+ "yi",
+ "yiii",
+ "lana",
+ "z",
+ "lina",
+ "maka",
+ "mani",
+ "mn",
+ "miao",
+ "lo",
+ "ci",
+ "lao",
+ "laoo",
+ "inkannada",
+ "cn",
+ "pi",
+ "innko",
+ "zzzz",
+ "gran",
+ "co",
+ "lineara",
+ "mark",
+ "po",
+ "me",
+ "cari",
+ "inkharoshthi",
+ "kana",
+ "loe",
+ "m",
+ "grek",
+ "mro",
+ "mroo",
+ "carian",
+ "geor",
+ "greek",
+ "gonm",
+ "mendekikakui",
+ "pe",
+ "mero",
+ "inosmanya",
+ "cakm",
+ "inmanichaean",
+ "inmro",
+ "inmiao",
+ "inchakma",
+ "c",
+ "mandaic",
+ "meeteimayek",
+ "inarmenian",
+ "inmyanmar",
+ "inmakasar",
+ "common",
+ "lm",
+ "marc",
+ "inrunic",
+ "incarian",
+ "inideographicsymbolsandpunctuation",
+ "inkhmer",
+ "qaai",
+ "inahom",
+ "merc",
+ "combiningmark",
+ "lc",
+ "perm",
+ "mc",
+ "connectorpunctuation",
+ "cans",
+ "incuneiformnumbersandpunctuation",
+ "armi",
+ "cc",
+ "armn",
+ "incherokee",
+ "prependedconcatenationmark",
+ "incuneiform",
+ "inavestan",
+ "inipaextensions",
+ "pc",
+ "armenian",
+ "insharada",
+ "inmarchen",
+ "makasar",
+ "masaramgondi",
+ "inarrows",
+ "incyrillic",
+ "incham",
+ "qmark",
+ "ri",
+ "qaac",
+ "insamaritan",
+ "latn",
+ "inmasaramgondi",
+ "inthaana",
+ "latin",
+ "inthai",
+ "lineseparator",
+ "pcm",
+ "inkatakana",
+ "inkaithi",
+ "inzanabazarsquare",
+ "inscriptionalparthian",
+ "initialpunctuation",
+ "mtei",
+ "vai",
+ "vaii",
+ "inkhmersymbols",
+ "insyriac",
+ "intakri",
+ "arabic",
+ "zs",
+ "katakana",
+ "prti",
+ "ascii",
+ "cs",
+ "ps",
+ "mand",
+ "privateuse",
+ "inruminumeralsymbols",
+ "inmyanmarextendeda",
+ "modi",
+ "incjkcompatibilityforms",
+ "inkanaextendeda",
+ "incjkcompatibilityideographs",
+ "brai",
+ "mend",
+ "ideo",
+ "letter",
+ "l",
+ "inmeeteimayek",
+ "inideographicdescriptioncharacters",
+ "xidcontinue",
+ "knda",
+ "innandinagari",
+ "kannada",
+ "inmodi",
+ "inlao",
+ "inoldnortharabian",
+ "intransportandmapsymbols",
+ "letternumber",
+ "gothic",
+ "inlineara",
+ "inmendekikakui",
+ "xidc",
+ "mongolian",
+ "inmiscellaneousmathematicalsymbolsa",
+ "inspecials",
+ "grlink",
+ "brahmi",
+ "inemoticons",
+ "kali",
+ "inolditalic",
+ "inmedefaidrin",
+ "inchesssymbols",
+ "incjkcompatibilityideographssupplement",
+ "inadlam",
+ "psalterpahlavi",
+ "incommonindicnumberforms",
+ "lt",
+ "innewa",
+ "sk",
+ "control",
+ "inancientsymbols",
+ "palm",
+ "inlycian",
+ "so",
+ "patternwhitespace",
+ "xids",
+ "inmandaic",
+ "idc",
+ "meroiticcursive",
+ "inwarangciti",
+ "sora",
+ "inopticalcharacterrecognition",
+ "inoldsogdian",
+ "inmalayalam",
+ "bamum",
+ "inkanasupplement",
+ "insundanese",
+ "grext",
+#endif /* USE_UNICODE_PROPERTIES */
+ "print",
+#ifndef USE_UNICODE_PROPERTIES
+ "punct",
+ "alpha",
+#else /* USE_UNICODE_PROPERTIES */
+ "intaitham",
+ "lower",
+ "joinc",
+ "inoldsoutharabian",
+ "incjkstrokes",
+ "batk",
+ "samr",
+ "inwancho",
+ "batak",
+ "vs",
+ "patws",
+ "samaritan",
+ "idsbinaryoperator",
+ "pauc",
+ "insmallkanaextension",
+ "sm",
+ "indominotiles",
+#endif /* USE_UNICODE_PROPERTIES */
+ "alnum",
+#ifdef USE_UNICODE_PROPERTIES
+ "insylotinagri",
+ "inugaritic",
+ "incontrolpictures",
+ "inlinearbideograms",
+ "inmusicalsymbols",
+ "s",
+ "ital",
+ "inmodifiertoneletters",
+ "inancientgreekmusicalnotation",
+ "patternsyntax",
+ "lisu",
+ "lowercase",
+ "cwcm",
+ "sc",
+ "bass",
+ "ids",
+ "inlatinextendeda",
+ "oriya",
+ "intaile",
+ "inmiscellaneoussymbols",
+ "inmiscellaneoussymbolsandarrows",
+ "incaucasianalbanian",
+ "inmiscellaneoussymbolsandpictographs",
+ "inoldturkic",
+ "insaurashtra",
+ "idcontinue",
+ "intamil",
+ "inmultani",
+ "inlatinextendede",
+ "pd",
+ "bali",
+ "blank",
+ "idst",
+ "inlydian",
+ "innewtailue",
+ "bengali",
+ "runr",
+ "zl",
+ "incyrillicextendeda",
+ "ll",
+ "indeseret",
+ "intaixuanjingsymbols",
+ "inancientgreeknumbers",
+ "idstart",
+ "inmeeteimayekextensions",
+ "balinese",
+ "dia",
+ "di",
+ "inspacingmodifierletters",
+ "inearlydynasticcuneiform",
+ "plrd",
+ "canadianaboriginal",
+ "zinh",
+ "sind",
+ "osage",
+ "inlatinextendedc",
+ "uideo",
+ "incountingrodnumerals",
+ "xidstart",
+#endif /* USE_UNICODE_PROPERTIES */
+ "xdigit",
+#ifndef USE_UNICODE_PROPERTIES
+ "upper",
+ "ascii",
+#else /* USE_UNICODE_PROPERTIES */
+ "osma",
+ "inkhudawadi",
+ "inhanifirohingya",
+ "gong",
+ "ingrantha",
+ "bidic",
+ "mong",
+ "cased",
+ "incyrillicextendedc",
+ "inhiragana",
+ "sinhala",
+ "adlm",
+ "glagolitic",
+ "sterm",
+ "bamu",
+ "georgian",
+ "inosage",
+ "gunjalagondi",
+ "phoenician",
+ "multani",
+ "kaithi",
+ "joincontrol",
+ "runic",
+ "ingeneralpunctuation",
+ "inmahajani",
+ "incyrillicsupplement",
+ "lowercaseletter",
+ "marchen",
+ "graphemelink",
+ "ingeorgian",
+ "khojki",
+ "cham",
+ "inogham",
+ "cher",
+ "chakma",
+ "emoji",
+ "insiddham",
+ "cherokee",
+ "khar",
+ "inmongolian",
+ "incherokeesupplement",
+ "diacritic",
+ "manichaean",
+ "xsux",
+ "inolchiki",
+ "quotationmark",
+ "adlam",
+ "inethiopic",
+ "graphemebase",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ "age=11.0",
+ "age=12.1",
+ "age=10.0",
+ "age=12.0",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ "casedletter",
+ "ingurmukhi",
+ "odi",
+ "incjkunifiedideographsextensiona",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ "age=1.1",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ "lu",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ "age=4.1",
+ "age=2.1",
+ "age=4.0",
+ "age=2.0",
+ "age=9.0",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ "intamilsupplement",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ "age=6.1",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ "unknown",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ "age=6.0",
+ "age=6.2",
+ "age=3.1",
+ "age=8.0",
+ "age=3.0",
+ "age=3.2",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ "cwt",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ "age=7.0",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ "unassigned",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+ "age=6.3",
+ "age=5.1",
+ "age=5.0",
+ "age=5.2",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ "ahom",
+ "incjkunifiedideographsextensione",
+ "khmr",
+ "insinhala",
+ "inmiscellaneoustechnical",
+ "saur",
+ "guru",
+ "sundanese",
+ "punct",
+ "paucinhau",
+ "gurmukhi",
+ "variationselector",
+ "logicalorderexception",
+ "khmer",
+ "limbu",
+ "inscriptionalpahlavi",
+ "oidc",
+ "incjkunifiedideographsextensionc",
+#endif /* USE_UNICODE_PROPERTIES */
+ "cntrl",
+#ifdef USE_UNICODE_PROPERTIES
+ "inlatinextendedadditional",
+ "decimalnumber",
+ "insorasompeng",
+ "radical",
+ "emojimodifier",
+ "kharoshthi",
+ "n",
+ "math",
+ "goth",
+ "anatolianhieroglyphs",
+ "inenclosedalphanumerics",
+ "nandinagari",
+ "no",
+ "nko",
+ "nkoo",
+ "ingreekandcoptic",
+ "olck",
+ "p",
+ "grantha",
+ "olchiki",
+ "incjkunifiedideographs",
+ "zanb",
+ "intirhuta",
+ "oids",
+ "inhatran",
+ "linb",
+ "xpeo",
+ "mult",
+ "saurashtra",
+ "kthi",
+ "inbhaiksuki",
+ "olower",
+ "innabataean",
+ "inphoenician",
+ "inkanbun",
+ "inmeroitichieroglyphs",
+ "inkayahli",
+ "phnx",
+ "inoriya",
+ "enclosingmark",
+ "sd",
+ "inelbasan",
+ "wara",
+ "inenclosedideographicsupplement",
+ "sidd",
+ "linearb",
+ "hani",
+ "han",
+ "inenclosedalphanumericsupplement",
+ "medf",
+ "bidicontrol",
+ "hano",
+ "inphaistosdisc",
+ "limb",
+ "inkangxiradicals",
+ "lepc",
+ "medefaidrin",
+ "braille",
+ "regionalindicator",
+ "inlowsurrogates",
+ "inshorthandformatcontrols",
+ "brah",
+ "inkhojki",
+ "inoldhungarian",
+ "hanunoo",
+ "hira",
+ "beng",
+ "emojimodifierbase",
+ "inarabic",
+ "lyci",
+ "ahex",
+ "inherited",
+ "glag",
+ "lycian",
+ "indogra",
+ "dsrt",
+ "arab",
+ "mymr",
+ "myanmar",
+ "phli",
+ "inimperialaramaic",
+ "ingreekextended",
+ "inanatolianhieroglyphs",
+ "punctuation",
+ "takri",
+ "graphemeextend",
+ "invai",
+ "cwl",
+ "ingeometricshapes",
+ "emojicomponent",
+ "coptic",
+ "deseret",
+ "inarabicpresentationformsa",
+ "takr",
+ "inbasiclatin",
+ "incjkunifiedideographsextensiond",
+ "sinh",
+ "sund",
+ "shavian",
+ "taile",
+ "insundanesesupplement",
+ "inelymaic",
+ "insoyombo",
+ "bhks",
+ "bhaiksuki",
+ "incjkcompatibility",
+ "inhanunoo",
+ "intangut",
+ "sogdian",
+ "inlatinextendedd",
+ "sogo",
+ "insinhalaarchaicnumbers",
+ "ideographic",
+ "ugar",
+ "copt",
+ "imperialaramaic",
+ "insogdian",
+ "indingbats",
+ "format",
+ "ininscriptionalpahlavi",
+ "ininscriptionalparthian",
+ "grbase",
+ "inbatak",
+ "cprt",
+ "cwcf",
+ "cuneiform",
+ "term",
+ "intibetan",
+ "intags",
+ "asciihexdigit",
+ "sentenceterminal",
+ "inmayannumerals",
+ "nand",
+ "patsyn",
+ "hatran",
+ "inblockelements",
+ "inornamentaldingbats",
+ "innumberforms",
+ "oldpersian",
+ "inshavian",
+ "bopo",
+ "hatr",
+ "caseignorable",
+ "inoldpersian",
+ "modifierletter",
+ "cwu",
+ "lydi",
+ "inbyzantinemusicalsymbols",
+ "ingeometricshapesextended",
+ "inmyanmarextendedb",
+ "innushu",
+ "lydian",
+ "inunifiedcanadianaboriginalsyllabics",
+ "orkh",
+ "inyiradicals",
+ "inkatakanaphoneticextensions",
+ "inethiopicextendeda",
+ "incoptic",
+ "inarabicextendeda",
+ "oldpermic",
+ "incjksymbolsandpunctuation",
+ "word",
+ "bopomofo",
+ "ogam",
+ "inlisu",
+ "inoldpermic",
+ "innoblock",
+ "taiviet",
+ "inbraillepatterns",
+ "alpha",
+ "inbalinese",
+ "sorasompeng",
+ "closepunctuation",
+ "inmiscellaneousmathematicalsymbolsb",
+ "inlepcha",
+ "insyriacsupplement",
+ "newa",
+ "spacingmark",
+ "inpalmyrene",
+ "cyrl",
+ "assigned",
+ "mlym",
+ "malayalam",
+ "ext",
+ "newtailue",
+#endif /* USE_UNICODE_PROPERTIES */
+ "space",
+#ifdef USE_UNICODE_PROPERTIES
+ "intelugu",
+ "idsb",
+ "indevanagari",
+ "avestan",
+ "cf",
+ "palmyrene",
+ "inethiopicsupplement",
+ "soyo",
+#endif /* USE_UNICODE_PROPERTIES */
+ "xposixpunct",
+#ifndef USE_UNICODE_PROPERTIES
+ "lower",
+#else /* USE_UNICODE_PROPERTIES */
+ "pf",
+ "sarb",
+ "zanabazarsquare",
+ "ugaritic",
+ "osge",
+ "java",
+ "sharada",
+ "dogra",
+ "bugi",
+ "meroitichieroglyphs",
+ "separator",
+ "ingeorgiansupplement",
+ "sogd",
+ "tale",
+ "inunifiedcanadianaboriginalsyllabicsextended",
+ "terminalpunctuation",
+ "shrd",
+#endif /* USE_UNICODE_PROPERTIES */
+ "graph",
+#ifdef USE_UNICODE_PROPERTIES
+ "olditalic",
+ "dogr",
+ "gujr",
+ "phag",
+ "gujarati",
+ "inhanguljamo",
+ "javanese",
+ "taml",
+ "inphoneticextensions",
+ "siddham",
+ "buginese",
+ "inmongoliansupplement",
+ "invariationselectors",
+ "inhanguljamoextendeda",
+ "inverticalforms",
+ "syrc",
+ "number",
+ "incopticepactnumbers",
+ "avst",
+ "inbamum",
+ "nd",
+ "insuttonsignwriting",
+ "extender",
+ "intaiviet",
+ "hex",
+ "incjkunifiedideographsextensionf",
+ "other",
+ "otheridcontinue",
+ "shaw",
+ "dash",
+ "othernumber",
+ "orya",
+ "invedicextensions",
+ "sgnw",
+ "caucasianalbanian",
+ "inmathematicalalphanumericsymbols",
+ "inphoneticextensionssupplement",
+ "invariationselectorssupplement",
+ "induployan",
+ "syriac",
+ "oalpha",
+ "innyiakengpuachuehmong",
+ "incombiningdiacriticalmarks",
+ "inethiopicextended",
+ "nl",
+ "incombiningdiacriticalmarksforsymbols",
+ "khudawadi",
+ "otheralphabetic",
+ "oldhungarian",
+ "incurrencysymbols",
+ "incjkradicalssupplement",
+ "inglagolitic",
+ "intifinagh",
+ "ingeorgianextended",
+ "surrogate",
+ "incyrillicextendedb",
+ "ethi",
+ "titlecaseletter",
+ "rohg",
+ "inmeroiticcursive",
+ "idstrinaryoperator",
+ "inphagspa",
+ "lepcha",
+ "intagalog",
+ "mathsymbol",
+ "incombiningdiacriticalmarkssupplement",
+ "inbrahmi",
+ "insymbolsandpictographsextendeda",
+ "inlinearbsyllabary",
+ "oldturkic",
+ "inbengali",
+ "wancho",
+ "osmanya",
+ "buhd",
+ "insmallformvariants",
+ "indevanagariextended",
+ "softdotted",
+ "inbuginese",
+ "mahj",
+ "inlatin1supplement",
+ "ingothic",
+ "mahajani",
+ "hang",
+ "sylo",
+ "warangciti",
+ "ingujarati",
+ "tirhuta",
+ "incombiningdiacriticalmarksextended",
+ "spaceseparator",
+ "ingunjalagondi",
+ "wcho",
+ "hiragana",
+ "extendedpictographic",
+ "inrejang",
+ "inottomansiyaqnumbers",
+ "nchar",
+ "cyrillic",
+ "khoj",
+ "inlimbu",
+ "hmng",
+ "thaa",
+ "thai",
+ "incjkunifiedideographsextensionb",
+ "deva",
+ "thaana",
+ "phagspa",
+ "devanagari",
+ "tang",
+ "currencysymbol",
+ "tagbanwa",
+ "inenclosedcjklettersandmonths",
+ "tamil",
+ "tirh",
+#endif /* USE_UNICODE_PROPERTIES */
+ "digit",
+#ifndef USE_UNICODE_PROPERTIES
+ "blank"
+#else /* USE_UNICODE_PROPERTIES */
+ "talu",
+ "zp",
+ "inpaucinhau",
+ "taitham",
+ "otherlowercase",
+ "telu",
+ "inaegeannumbers",
+ "otherletter",
+ "whitespace",
+ "nonspacingmark",
+ "graphemeclusterbreak=spacingmark",
+ "inletterlikesymbols",
+ "intagbanwa",
+ "oldsogdian",
+ "otheridstart",
+ "graphemeclusterbreak=cr",
+ "narb",
+ "changeswhencasemapped",
+ "inbopomofo",
+ "tangut",
+ "graphemeclusterbreak=regionalindicator",
+ "noncharactercodepoint",
+ "otheruppercase",
+ "rjng",
+ "sylotinagri",
+ "inhangulsyllables",
+ "emojipresentation",
+ "inindicsiyaqnumbers",
+ "inbassavah",
+ "ogrext",
+ "othersymbol",
+ "oupper",
+ "inbuhid",
+ "hmnp",
+ "inpsalterpahlavi",
+ "finalpunctuation",
+ "phlp",
+ "inbamumsupplement",
+ "buhid",
+ "paragraphseparator",
+ "inalphabeticpresentationforms",
+ "omath",
+ "any",
+ "elba",
+ "changeswhentitlecased",
+ "incombininghalfmarks",
+ "intangutcomponents",
+ "hebr",
+ "deprecated",
+ "inarabicmathematicalalphabeticsymbols",
+ "inprivateusearea",
+ "kayahli",
+ "inplayingcards",
+ "inarabicpresentationformsb",
+ "ogham",
+ "elym",
+ "graphemeclusterbreak=t",
+ "graphemeclusterbreak=lvt",
+ "nbat",
+ "nabataean",
+ "hangul",
+ "elymaic",
+ "inhebrew",
+ "injavanese",
+ "symbol",
+ "inmathematicaloperators",
+ "inarabicsupplement",
+ "cypriot",
+ "hung",
+ "wspace",
+ "changeswhenlowercased",
+ "elbasan",
+ "hluw",
+ "insuperscriptsandsubscripts",
+ "graphemeclusterbreak=extend",
+ "graphemeclusterbreak=prepend",
+ "nshu",
+ "oldnortharabian",
+ "inyijinghexagramsymbols",
+ "hexdigit",
+ "graphemeclusterbreak=l",
+ "graphemeclusterbreak=control",
+ "bassavah",
+ "otherdefaultignorablecodepoint",
+ "changeswhenuppercased",
+ "inalchemicalsymbols",
+ "insupplementalarrowsa",
+ "inyisyllables",
+ "tibt",
+ "othermath",
+ "tibetan",
+ "inmahjongtiles",
+ "signwriting",
+ "nushu",
+ "modifiersymbol",
+ "inhalfwidthandfullwidthforms",
+ "upper",
+ "insupplementalarrowsc",
+ "insupplementalmathematicaloperators",
+ "incypriotsyllabary",
+ "dupl",
+ "tavt",
+ "inpahawhhmong",
+ "alphabetic",
+ "dashpunctuation",
+ "uppercase",
+ "soyombo",
+ "hanifirohingya",
+ "otherpunctuation",
+ "defaultignorablecodepoint",
+ "inhanguljamoextendedb",
+ "aghb",
+ "tifinagh",
+ "inlatinextendedb",
+ "tfng",
+ "inhighprivateusesurrogates",
+ "changeswhencasefolded",
+ "dep",
+ "oldsoutharabian",
+ "graphemeclusterbreak=lf",
+ "pahawhhmong",
+ "unifiedideograph",
+ "uppercaseletter",
+ "insupplementalpunctuation",
+ "ethiopic",
+ "inglagoliticsupplement",
+ "rejang",
+ "inbopomofoextended",
+ "tagb",
+ "othergraphemeextend",
+ "inegyptianhieroglyphs",
+ "inegyptianhieroglyphformatcontrols",
+ "hebrew",
+ "tglg",
+ "tagalog",
+ "graphemeclusterbreak=zwj",
+ "zyyy",
+ "hyphen",
+ "inboxdrawing",
+ "graphemeclusterbreak=v",
+ "graphemeclusterbreak=lv",
+ "telugu",
+ "duployan",
+ "openpunctuation",
+ "insupplementaryprivateuseareaa",
+ "inhighsurrogates",
+ "insupplementalarrowsb",
+ "insupplementalsymbolsandpictographs",
+ "egyp",
+ "inhangulcompatibilityjamo",
+ "nyiakengpuachuehmong",
+ "egyptianhieroglyphs",
+ "insupplementaryprivateuseareab"
+#endif /* USE_UNICODE_PROPERTIES */
+ };
+#define uniname2ctype_pool ((const char *) &uniname2ctype_pool_contents)
+const struct uniname2ctype_struct *
+uniname2ctype_p (register const char *str, register size_t len)
+{
+ static const struct uniname2ctype_struct wordlist[] =
+ {
+#ifdef USE_UNICODE_PROPERTIES
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str11), 111},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str17), 111},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str22), 152},
+ {-1},
+ {uniname2ctype_offset(str24), 52},
+ {uniname2ctype_offset(str25), 184},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str33), 218},
+ {-1},
+ {uniname2ctype_offset(str35), 186},
+ {uniname2ctype_offset(str36), 34},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str45), 173},
+ {uniname2ctype_offset(str46), 28},
+ {uniname2ctype_offset(str47), 61},
+ {uniname2ctype_offset(str48), 95},
+ {uniname2ctype_offset(str49), 95},
+ {-1}, {-1},
+ {uniname2ctype_offset(str52), 331},
+ {-1}, {-1},
+ {uniname2ctype_offset(str55), 21},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str64), 44},
+ {-1},
+ {uniname2ctype_offset(str66), 319},
+ {uniname2ctype_offset(str67), 267},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str71), 181},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str75), 22},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str83), 184},
+ {-1}, {-1},
+ {uniname2ctype_offset(str86), 31},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str92), 45},
+ {-1},
+ {uniname2ctype_offset(str94), 33},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str100), 149},
+ {uniname2ctype_offset(str101), 496},
+ {uniname2ctype_offset(str102), 108},
+ {uniname2ctype_offset(str103), 252},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str107), 31},
+ {uniname2ctype_offset(str108), 77},
+ {-1}, {-1},
+ {uniname2ctype_offset(str111), 189},
+ {uniname2ctype_offset(str112), 189},
+ {-1}, {-1},
+ {uniname2ctype_offset(str115), 149},
+ {-1},
+ {uniname2ctype_offset(str117), 98},
+ {uniname2ctype_offset(str118), 77},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str122), 212},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str129), 187},
+ {uniname2ctype_offset(str130), 42},
+ {uniname2ctype_offset(str131), 172},
+ {-1}, {-1},
+ {uniname2ctype_offset(str134), 482},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str139), 170},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str145), 499},
+ {uniname2ctype_offset(str146), 548},
+ {-1},
+ {uniname2ctype_offset(str148), 552},
+ {uniname2ctype_offset(str149), 514},
+ {-1},
+ {uniname2ctype_offset(str151), 18},
+ {uniname2ctype_offset(str152), 169},
+ {uniname2ctype_offset(str153), 160},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str161), 313},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str177), 337},
+ {uniname2ctype_offset(str178), 539},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str183), 75},
+ {-1}, {-1},
+ {uniname2ctype_offset(str186), 27},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str190), 208},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str203), 345},
+ {uniname2ctype_offset(str204), 473},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str210), 553},
+ {-1},
+ {uniname2ctype_offset(str212), 350},
+ {uniname2ctype_offset(str213), 115},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str218), 528},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str226), 171},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str231), 31},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str236), 25},
+ {uniname2ctype_offset(str237), 194},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str246), 32},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str250), 40},
+ {-1}, {-1},
+ {uniname2ctype_offset(str253), 102},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str260), 542},
+ {-1}, {-1},
+ {uniname2ctype_offset(str263), 161},
+ {-1},
+ {uniname2ctype_offset(str265), 19},
+ {-1},
+ {uniname2ctype_offset(str267), 79},
+ {uniname2ctype_offset(str268), 342},
+ {-1},
+ {uniname2ctype_offset(str270), 259},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str274), 541},
+ {uniname2ctype_offset(str275), 500},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str281), 307},
+ {uniname2ctype_offset(str282), 40},
+ {uniname2ctype_offset(str283), 79},
+ {-1},
+ {uniname2ctype_offset(str285), 516},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str289), 536},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str293), 218},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str297), 212},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str301), 380},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str311), 311},
+ {-1},
+ {uniname2ctype_offset(str313), 441},
+ {-1},
+ {uniname2ctype_offset(str315), 232},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str320), 260},
+ {-1},
+ {uniname2ctype_offset(str322), 129},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str328), 320},
+ {-1}, {-1},
+ {uniname2ctype_offset(str331), 76},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str335), 537},
+ {-1}, {-1},
+ {uniname2ctype_offset(str338), 318},
+ {-1},
+ {uniname2ctype_offset(str340), 76},
+ {-1},
+ {uniname2ctype_offset(str342), 334},
+ {-1}, {-1},
+ {uniname2ctype_offset(str345), 53},
+ {uniname2ctype_offset(str346), 259},
+ {-1},
+ {uniname2ctype_offset(str348), 411},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str352), 512},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str357), 532},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str362), 163},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str366), 44},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str373), 160},
+ {-1}, {-1},
+ {uniname2ctype_offset(str376), 144},
+ {uniname2ctype_offset(str377), 144},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str386), 356},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str399), 316},
+ {-1},
+ {uniname2ctype_offset(str401), 527},
+ {-1}, {-1},
+ {uniname2ctype_offset(str404), 81},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str411), 55},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str418), 108},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str426), 163},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str442), 14},
+ {-1}, {-1},
+ {uniname2ctype_offset(str445), 23},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str462), 46},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str468), 169},
+ {-1},
+ {uniname2ctype_offset(str470), 22},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str475), 507},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str480), 442},
+ {uniname2ctype_offset(str481), 188},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str486), 461},
+ {-1},
+ {uniname2ctype_offset(str488), 557},
+ {-1}, {-1},
+ {uniname2ctype_offset(str491), 455},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str500), 127},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str504), 187},
+ {uniname2ctype_offset(str505), 238},
+ {uniname2ctype_offset(str506), 24},
+ {-1}, {-1},
+ {uniname2ctype_offset(str509), 24},
+ {-1},
+ {uniname2ctype_offset(str511), 448},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str520), 408},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str535), 70},
+ {-1}, {-1},
+ {uniname2ctype_offset(str538), 91},
+ {-1}, {-1},
+ {uniname2ctype_offset(str541), 531},
+ {-1},
+ {uniname2ctype_offset(str543), 91},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str556), 525},
+ {-1},
+ {uniname2ctype_offset(str558), 335},
+ {-1},
+ {uniname2ctype_offset(str560), 498},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str565), 586},
+ {uniname2ctype_offset(str566), 37},
+ {-1},
+ {uniname2ctype_offset(str568), 113},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str572), 486},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str577), 573},
+ {uniname2ctype_offset(str578), 70},
+ {uniname2ctype_offset(str579), 106},
+ {-1}, {-1},
+ {uniname2ctype_offset(str582), 391},
+ {uniname2ctype_offset(str583), 465},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str590), 74},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str594), 168},
+ {-1},
+ {uniname2ctype_offset(str596), 584},
+ {uniname2ctype_offset(str597), 146},
+ {-1}, {-1},
+ {uniname2ctype_offset(str600), 475},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str604), 551},
+ {uniname2ctype_offset(str605), 591},
+ {-1}, {-1},
+ {uniname2ctype_offset(str608), 598},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str614), 574},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str624), 195},
+ {uniname2ctype_offset(str625), 432},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str630), 29},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str636), 522},
+ {-1}, {-1},
+ {uniname2ctype_offset(str639), 49},
+ {-1}, {-1},
+ {uniname2ctype_offset(str642), 19},
+ {-1}, {-1},
+ {uniname2ctype_offset(str645), 470},
+ {-1},
+ {uniname2ctype_offset(str647), 192},
+ {-1}, {-1},
+ {uniname2ctype_offset(str650), 472},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str657), 51},
+ {-1}, {-1},
+ {uniname2ctype_offset(str660), 257},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str668), 69},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str672), 321},
+ {-1}, {-1},
+ {uniname2ctype_offset(str675), 68},
+ {-1}, {-1},
+ {uniname2ctype_offset(str678), 171},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str695), 530},
+ {uniname2ctype_offset(str696), 175},
+ {uniname2ctype_offset(str697), 384},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str703), 508},
+ {-1},
+ {uniname2ctype_offset(str705), 332},
+ {-1},
+ {uniname2ctype_offset(str707), 158},
+ {uniname2ctype_offset(str708), 556},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str713), 361},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str720), 72},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str737), 7},
+ {uniname2ctype_offset(str738), 358},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str742), 6},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str753), 229},
+ {-1},
+ {uniname2ctype_offset(str755), 497},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str760), 416},
+ {uniname2ctype_offset(str761), 167},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str766), 156},
+ {uniname2ctype_offset(str767), 572},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str771), 167},
+ {uniname2ctype_offset(str772), 256},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str776), 257},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str783), 156},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str787), 245},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str791), 193},
+ {-1}, {-1},
+ {uniname2ctype_offset(str794), 558},
+ {-1}, {-1},
+ {uniname2ctype_offset(str797), 50},
+ {-1},
+ {uniname2ctype_offset(str799), 579},
+ {-1}, {-1},
+ {uniname2ctype_offset(str802), 13},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str809), 431},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str814), 478},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str818), 383},
+ {-1}, {-1},
+ {uniname2ctype_offset(str821), 467},
+ {uniname2ctype_offset(str822), 563},
+ {uniname2ctype_offset(str823), 47},
+ {uniname2ctype_offset(str824), 112},
+ {uniname2ctype_offset(str825), 429},
+ {-1}, {-1},
+ {uniname2ctype_offset(str828), 564},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str834), 258},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str838), 157},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str842), 58},
+ {-1}, {-1},
+ {uniname2ctype_offset(str845), 66},
+ {-1},
+ {uniname2ctype_offset(str847), 48},
+ {uniname2ctype_offset(str848), 178},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str855), 67},
+ {-1},
+ {uniname2ctype_offset(str857), 305},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str862), 88},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str875), 354},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str886), 389},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str895), 397},
+ {-1}, {-1},
+ {uniname2ctype_offset(str898), 485},
+ {-1},
+ {uniname2ctype_offset(str900), 583},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str906), 504},
+ {uniname2ctype_offset(str907), 434},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str924), 68},
+ {-1},
+ {uniname2ctype_offset(str926), 329},
+ {-1},
+ {uniname2ctype_offset(str928), 519},
+ {uniname2ctype_offset(str929), 446},
+ {uniname2ctype_offset(str930), 41},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str946), 136},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str961), 2},
+ {-1},
+ {uniname2ctype_offset(str963), 246},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str974), 493},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str986), 355},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str994), 85},
+ {uniname2ctype_offset(str995), 104},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1005), 53},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1009), 404},
+ {uniname2ctype_offset(str1010), 26},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1013), 480},
+ {uniname2ctype_offset(str1014), 566},
+ {uniname2ctype_offset(str1015), 469},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1021), 67},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1025), 444},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1028), 136},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1032), 239},
+ {uniname2ctype_offset(str1033), 71},
+ {-1},
+ {uniname2ctype_offset(str1035), 308},
+ {uniname2ctype_offset(str1036), 543},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1049), 173},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1067), 102},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1070), 115},
+ {-1},
+ {uniname2ctype_offset(str1072), 197},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1080), 210},
+ {uniname2ctype_offset(str1081), 399},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1085), 248},
+ {-1},
+ {uniname2ctype_offset(str1087), 567},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1090), 69},
+ {uniname2ctype_offset(str1091), 11},
+ {-1},
+ {uniname2ctype_offset(str1093), 125},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1097), 520},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1102), 506},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1105), 217},
+ {-1},
+ {uniname2ctype_offset(str1107), 521},
+ {-1},
+ {uniname2ctype_offset(str1109), 228},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1119), 106},
+ {uniname2ctype_offset(str1120), 60},
+ {uniname2ctype_offset(str1121), 365},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1134), 410},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1140), 93},
+ {-1},
+ {uniname2ctype_offset(str1142), 206},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1146), 131},
+ {uniname2ctype_offset(str1147), 255},
+ {-1},
+ {uniname2ctype_offset(str1149), 158},
+ {uniname2ctype_offset(str1150), 98},
+ {uniname2ctype_offset(str1151), 483},
+ {uniname2ctype_offset(str1152), 217},
+ {uniname2ctype_offset(str1153), 138},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1157), 203},
+ {uniname2ctype_offset(str1158), 166},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1164), 229},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1168), 104},
+ {-1},
+ {uniname2ctype_offset(str1170), 374},
+ {uniname2ctype_offset(str1171), 515},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1174), 312},
+ {uniname2ctype_offset(str1175), 26},
+ {uniname2ctype_offset(str1176), 208},
+ {uniname2ctype_offset(str1177), 74},
+ {uniname2ctype_offset(str1178), 338},
+ {-1},
+ {uniname2ctype_offset(str1180), 183},
+ {uniname2ctype_offset(str1181), 151},
+ {uniname2ctype_offset(str1182), 344},
+ {uniname2ctype_offset(str1183), 101},
+ {-1},
+ {uniname2ctype_offset(str1185), 170},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1190), 261},
+ {uniname2ctype_offset(str1191), 524},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1197), 101},
+ {uniname2ctype_offset(str1198), 135},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1203), 351},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1207), 447},
+ {uniname2ctype_offset(str1208), 239},
+ {uniname2ctype_offset(str1209), 186},
+ {uniname2ctype_offset(str1210), 137},
+ {-1},
+ {uniname2ctype_offset(str1212), 364},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1227), 232},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1231), 206},
+ {uniname2ctype_offset(str1232), 340},
+ {uniname2ctype_offset(str1233), 73},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1234), 287},
+ {uniname2ctype_offset(str1235), 289},
+ {uniname2ctype_offset(str1236), 286},
+ {uniname2ctype_offset(str1237), 288},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1243), 25},
+ {uniname2ctype_offset(str1244), 326},
+ {uniname2ctype_offset(str1245), 249},
+ {uniname2ctype_offset(str1246), 420},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1247), 268},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1248), 30},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ {-1}, {-1}, {-1}, {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1249), 275},
+ {uniname2ctype_offset(str1250), 270},
+ {uniname2ctype_offset(str1251), 274},
+ {uniname2ctype_offset(str1252), 269},
+ {uniname2ctype_offset(str1253), 285},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1254), 540},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1255), 280},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1256), 267},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1257), 279},
+ {uniname2ctype_offset(str1258), 281},
+ {uniname2ctype_offset(str1259), 272},
+ {uniname2ctype_offset(str1260), 284},
+ {uniname2ctype_offset(str1261), 271},
+ {uniname2ctype_offset(str1262), 273},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1263), 64},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1264), 283},
+ {-1},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1266), 21},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1267), 282},
+ {uniname2ctype_offset(str1268), 277},
+ {-1},
+ {uniname2ctype_offset(str1270), 276},
+ {uniname2ctype_offset(str1271), 278},
+ {-1}, {-1},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+ {uniname2ctype_offset(str1274), 200},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1282), 596},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1285), 105},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1289), 333},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1292), 382},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1297), 145},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1300), 86},
+ {uniname2ctype_offset(str1301), 141},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1306), 15},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1314), 193},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1317), 86},
+ {-1},
+ {uniname2ctype_offset(str1319), 256},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1331), 252},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1340), 105},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1343), 120},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str1354), 164},
+ {uniname2ctype_offset(str1355), 254},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1358), 594},
+ {-1},
+ {uniname2ctype_offset(str1360), 3},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1365), 372},
+ {uniname2ctype_offset(str1366), 36},
+ {uniname2ctype_offset(str1367), 513},
+ {-1},
+ {uniname2ctype_offset(str1369), 247},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1373), 263},
+ {-1},
+ {uniname2ctype_offset(str1375), 135},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1380), 35},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1384), 56},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1387), 113},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1400), 201},
+ {uniname2ctype_offset(str1401), 385},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1407), 224},
+ {-1},
+ {uniname2ctype_offset(str1409), 38},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1419), 140},
+ {uniname2ctype_offset(str1420), 140},
+ {-1},
+ {uniname2ctype_offset(str1422), 310},
+ {uniname2ctype_offset(str1423), 143},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1426), 39},
+ {-1},
+ {uniname2ctype_offset(str1428), 181},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1434), 143},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1438), 422},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1441), 215},
+ {uniname2ctype_offset(str1442), 523},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1445), 253},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1448), 491},
+ {uniname2ctype_offset(str1449), 122},
+ {uniname2ctype_offset(str1450), 134},
+ {uniname2ctype_offset(str1451), 203},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1454), 145},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1457), 166},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1462), 535},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1466), 241},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1470), 490},
+ {uniname2ctype_offset(str1471), 492},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1475), 414},
+ {uniname2ctype_offset(str1476), 494},
+ {-1},
+ {uniname2ctype_offset(str1478), 436},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1481), 138},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1485), 328},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1489), 33},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1495), 251},
+ {-1},
+ {uniname2ctype_offset(str1497), 484},
+ {uniname2ctype_offset(str1498), 199},
+ {uniname2ctype_offset(str1499), 582},
+ {-1},
+ {uniname2ctype_offset(str1501), 196},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1507), 122},
+ {-1},
+ {uniname2ctype_offset(str1509), 110},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1512), 110},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1517), 581},
+ {-1},
+ {uniname2ctype_offset(str1519), 219},
+ {uniname2ctype_offset(str1520), 228},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1523), 117},
+ {uniname2ctype_offset(str1524), 471},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1529), 120},
+ {-1},
+ {uniname2ctype_offset(str1531), 407},
+ {-1},
+ {uniname2ctype_offset(str1533), 142},
+ {-1},
+ {uniname2ctype_offset(str1535), 219},
+ {uniname2ctype_offset(str1536), 127},
+ {uniname2ctype_offset(str1537), 260},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1542), 453},
+ {-1},
+ {uniname2ctype_offset(str1544), 561},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1547), 168},
+ {uniname2ctype_offset(str1548), 518},
+ {uniname2ctype_offset(str1549), 505},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1552), 117},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1555), 107},
+ {-1},
+ {uniname2ctype_offset(str1557), 85},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1563), 264},
+ {-1},
+ {uniname2ctype_offset(str1565), 315},
+ {-1},
+ {uniname2ctype_offset(str1567), 148},
+ {-1},
+ {uniname2ctype_offset(str1569), 236},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1572), 115},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1580), 131},
+ {-1},
+ {uniname2ctype_offset(str1582), 148},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1587), 529},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1594), 114},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1597), 81},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1602), 97},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1607), 97},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1613), 164},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1617), 488},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1622), 373},
+ {uniname2ctype_offset(str1623), 546},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1629), 39},
+ {-1},
+ {uniname2ctype_offset(str1631), 176},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1635), 72},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1638), 426},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1643), 62},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str1654), 388},
+ {uniname2ctype_offset(str1655), 265},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1662), 129},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1671), 114},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1675), 457},
+ {uniname2ctype_offset(str1676), 176},
+ {uniname2ctype_offset(str1677), 303},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1682), 595},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1686), 93},
+ {uniname2ctype_offset(str1687), 141},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1691), 124},
+ {uniname2ctype_offset(str1692), 121},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1699), 367},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1702), 510},
+ {uniname2ctype_offset(str1703), 533},
+ {uniname2ctype_offset(str1704), 207},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1714), 207},
+ {-1},
+ {uniname2ctype_offset(str1716), 419},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1722), 347},
+ {-1},
+ {uniname2ctype_offset(str1724), 554},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1728), 221},
+ {uniname2ctype_offset(str1729), 430},
+ {uniname2ctype_offset(str1730), 222},
+ {uniname2ctype_offset(str1731), 517},
+ {uniname2ctype_offset(str1732), 238},
+ {uniname2ctype_offset(str1733), 123},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1740), 129},
+ {-1},
+ {uniname2ctype_offset(str1742), 161},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1745), 509},
+ {uniname2ctype_offset(str1746), 390},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1750), 20},
+ {-1},
+ {uniname2ctype_offset(str1752), 502},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1757), 501},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1766), 73},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1769), 362},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1776), 126},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1780), 65},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1788), 137},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1791), 233},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1806), 336},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1810), 599},
+ {uniname2ctype_offset(str1811), 236},
+ {-1},
+ {uniname2ctype_offset(str1813), 255},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1816), 565},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1821), 224},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1825), 258},
+ {uniname2ctype_offset(str1826), 202},
+ {-1},
+ {uniname2ctype_offset(str1828), 387},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1838), 585},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1842), 379},
+ {uniname2ctype_offset(str1843), 134},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1846), 481},
+ {-1},
+ {uniname2ctype_offset(str1848), 109},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1861), 202},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1866), 61},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1871), 479},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1878), 27},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1881), 63},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1891), 150},
+ {uniname2ctype_offset(str1892), 562},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1896), 588},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1904), 440},
+ {uniname2ctype_offset(str1905), 559},
+ {uniname2ctype_offset(str1906), 150},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1911), 343},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1915), 165},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1928), 424},
+ {uniname2ctype_offset(str1929), 417},
+ {uniname2ctype_offset(str1930), 445},
+ {-1},
+ {uniname2ctype_offset(str1932), 400},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1936), 323},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str1947), 194},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1950), 409},
+ {uniname2ctype_offset(str1951), 12},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1958), 109},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1961), 103},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1964), 425},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1967), 477},
+ {uniname2ctype_offset(str1968), 603},
+ {-1}, {-1},
+ {uniname2ctype_offset(str1971), 153},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1985), 393},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str1991), 1},
+ {-1},
+ {uniname2ctype_offset(str1993), 360},
+ {uniname2ctype_offset(str1994), 175},
+ {-1},
+ {uniname2ctype_offset(str1996), 42},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2006), 395},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2010), 363},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2014), 322},
+ {-1},
+ {uniname2ctype_offset(str2016), 209},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2023), 32},
+ {uniname2ctype_offset(str2024), 489},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2033), 78},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2043), 17},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2048), 92},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2055), 92},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2058), 240},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2062), 130},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2070), 9},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2073), 330},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2078), 245},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2083), 324},
+ {uniname2ctype_offset(str2084), 154},
+ {uniname2ctype_offset(str2085), 20},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2093), 192},
+ {-1},
+ {uniname2ctype_offset(str2095), 341},
+ {-1},
+ {uniname2ctype_offset(str2097), 214},
+ {uniname2ctype_offset(str2098), 8},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2102), 43},
+ {uniname2ctype_offset(str2103), 162},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2109), 215},
+ {uniname2ctype_offset(str2110), 123},
+ {-1},
+ {uniname2ctype_offset(str2112), 210},
+ {-1},
+ {uniname2ctype_offset(str2114), 159},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2117), 174},
+ {-1},
+ {uniname2ctype_offset(str2119), 216},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2135), 128},
+ {-1},
+ {uniname2ctype_offset(str2137), 172},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2145), 52},
+ {uniname2ctype_offset(str2146), 401},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2149), 221},
+ {uniname2ctype_offset(str2150), 121},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2153), 352},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2161), 233},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2165), 174},
+ {uniname2ctype_offset(str2166), 5},
+ {uniname2ctype_offset(str2167), 112},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2170), 216},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2173), 87},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2181), 139},
+ {uniname2ctype_offset(str2182), 87},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2195), 339},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2199), 159},
+ {-1},
+ {uniname2ctype_offset(str2201), 89},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2204), 369},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2207), 196},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2217), 128},
+ {uniname2ctype_offset(str2218), 526},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2222), 458},
+ {-1},
+ {uniname2ctype_offset(str2224), 438},
+ {uniname2ctype_offset(str2225), 459},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2228), 82},
+ {uniname2ctype_offset(str2229), 35},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2235), 474},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2238), 154},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2244), 428},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2247), 36},
+ {uniname2ctype_offset(str2248), 569},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2252), 240},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2258), 443},
+ {-1},
+ {uniname2ctype_offset(str2260), 235},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2268), 597},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2271), 18},
+ {uniname2ctype_offset(str2272), 254},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2278), 124},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2282), 230},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2285), 38},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2294), 88},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2302), 368},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2305), 205},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2312), 177},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2315), 568},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2321), 370},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2339), 600},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2343), 560},
+ {uniname2ctype_offset(str2344), 82},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2357), 237},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2361), 571},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2364), 309},
+ {uniname2ctype_offset(str2365), 403},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2373), 37},
+ {uniname2ctype_offset(str2374), 377},
+ {uniname2ctype_offset(str2375), 197},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2378), 237},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str2389), 204},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2396), 376},
+ {uniname2ctype_offset(str2397), 406},
+ {uniname2ctype_offset(str2398), 398},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2415), 402},
+ {uniname2ctype_offset(str2416), 366},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str2427), 23},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2433), 427},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2440), 100},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str2451), 29},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2454), 220},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2458), 495},
+ {-1},
+ {uniname2ctype_offset(str2460), 246},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2470), 433},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2475), 142},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2479), 346},
+ {uniname2ctype_offset(str2480), 50},
+ {uniname2ctype_offset(str2481), 371},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2506), 511},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2513), 592},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2519), 466},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2529), 165},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2534), 325},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2540), 226},
+ {-1},
+ {uniname2ctype_offset(str2542), 125},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2548), 118},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2552), 462},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2561), 435},
+ {uniname2ctype_offset(str2562), 251},
+ {-1},
+ {uniname2ctype_offset(str2564), 357},
+ {-1},
+ {uniname2ctype_offset(str2566), 185},
+ {uniname2ctype_offset(str2567), 304},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2570), 476},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2575), 185},
+ {uniname2ctype_offset(str2576), 99},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2579), 133},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2586), 199},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2595), 327},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2603), 198},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2606), 359},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2609), 55},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2614), 538},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2624), 226},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2631), 107},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2634), 266},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2643), 437},
+ {uniname2ctype_offset(str2644), 576},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2648), 243},
+ {-1},
+ {uniname2ctype_offset(str2650), 78},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2653), 183},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2656), 353},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2663), 182},
+ {-1},
+ {uniname2ctype_offset(str2665), 83},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2668), 94},
+ {-1},
+ {uniname2ctype_offset(str2670), 593},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2673), 84},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2676), 83},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2688), 139},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2691), 84},
+ {uniname2ctype_offset(str2692), 211},
+ {-1},
+ {uniname2ctype_offset(str2694), 48},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2698), 119},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2701), 418},
+ {uniname2ctype_offset(str2702), 89},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2721), 198},
+ {-1},
+ {uniname2ctype_offset(str2723), 4},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2732), 130},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2747), 54},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2750), 534},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2760), 152},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2764), 241},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2768), 90},
+ {uniname2ctype_offset(str2769), 468},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2777), 28},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2780), 227},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2793), 34},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2816), 296},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2821), 378},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2834), 349},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2841), 222},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2848), 253},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2852), 291},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2855), 190},
+ {uniname2ctype_offset(str2856), 66},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2859), 412},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2862), 211},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2867), 295},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2871), 243},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2883), 242},
+ {-1},
+ {uniname2ctype_offset(str2885), 147},
+ {uniname2ctype_offset(str2886), 133},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2904), 449},
+ {uniname2ctype_offset(str2905), 262},
+ {uniname2ctype_offset(str2906), 575},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2909), 549},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2912), 244},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2926), 51},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2938), 242},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2941), 348},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2963), 225},
+ {uniname2ctype_offset(str2964), 503},
+ {-1}, {-1},
+ {uniname2ctype_offset(str2967), 43},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2980), 195},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2984), 547},
+ {-1},
+ {uniname2ctype_offset(str2986), 118},
+ {uniname2ctype_offset(str2987), 54},
+ {uniname2ctype_offset(str2988), 456},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str2993), 234},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3000), 16},
+ {uniname2ctype_offset(str3001), 180},
+ {uniname2ctype_offset(str3002), 64},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3005), 460},
+ {uniname2ctype_offset(str3006), 555},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3012), 80},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3028), 250},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3045), 577},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3055), 454},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3089), 146},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3098), 580},
+ {uniname2ctype_offset(str3099), 463},
+ {uniname2ctype_offset(str3100), 103},
+ {uniname2ctype_offset(str3101), 223},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3107), 299},
+ {-1},
+ {uniname2ctype_offset(str3109), 301},
+ {-1},
+ {uniname2ctype_offset(str3111), 191},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3125), 191},
+ {uniname2ctype_offset(str3126), 99},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3134), 223},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3158), 314},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3165), 439},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3169), 47},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3176), 381},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3180), 317},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3185), 126},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3194), 204},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str3205), 227},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3209), 62},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3215), 180},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3218), 201},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3237), 375},
+ {-1},
+ {uniname2ctype_offset(str3239), 294},
+ {uniname2ctype_offset(str3240), 290},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3248), 213},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3254), 190},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3266), 421},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str3286), 235},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str3297), 297},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3303), 293},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3309), 178},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3317), 249},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str3328), 63},
+ {uniname2ctype_offset(str3329), 587},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3348), 392},
+ {uniname2ctype_offset(str3349), 423},
+ {-1},
+ {uniname2ctype_offset(str3351), 96},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3360), 234},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3363), 96},
+ {-1},
+ {uniname2ctype_offset(str3365), 578},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3433), 205},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3436), 213},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3439), 49},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3442), 464},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3458), 10},
+ {-1},
+ {uniname2ctype_offset(str3460), 589},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3511), 396},
+ {uniname2ctype_offset(str3512), 487},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3517), 179},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3531), 153},
+ {uniname2ctype_offset(str3532), 550},
+ {uniname2ctype_offset(str3533), 57},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3550), 41},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3558), 59},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3613), 214},
+ {uniname2ctype_offset(str3614), 220},
+ {-1},
+ {uniname2ctype_offset(str3616), 45},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3628), 71},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str3648), 450},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3664), 177},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3703), 132},
+ {-1},
+ {uniname2ctype_offset(str3705), 306},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3714), 132},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3766), 452},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3791), 65},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3805), 250},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3819), 162},
+ {-1},
+ {uniname2ctype_offset(str3821), 292},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3842), 182},
+ {-1}, {-1},
+ {uniname2ctype_offset(str3845), 248},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3891), 30},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3924), 405},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3942), 100},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3976), 570},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str3995), 147},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str4087), 415},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4109), 119},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4137), 244},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4162), 544},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4175), 545},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4203), 80},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4254), 116},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4276), 116},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4291), 302},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str4321), 75},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1},
+ {uniname2ctype_offset(str4360), 231},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4397), 386},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4405), 298},
+ {uniname2ctype_offset(str4406), 300},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4460), 90},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4485), 179},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4528), 46},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str4674), 601},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4683), 451},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4772), 394},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4948), 590},
+#endif /* USE_UNICODE_PROPERTIES */
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#ifndef USE_UNICODE_PROPERTIES
+ {uniname2ctype_offset(str6), 12},
+ {uniname2ctype_offset(str7), 7},
+ {uniname2ctype_offset(str8), 15},
+ {uniname2ctype_offset(str9), 1},
+ {uniname2ctype_offset(str10), 13},
+ {uniname2ctype_offset(str11), 11},
+ {uniname2ctype_offset(str12), 10},
+ {uniname2ctype_offset(str13), 14},
+ {uniname2ctype_offset(str14), 3},
+ {uniname2ctype_offset(str15), 9},
+ {uniname2ctype_offset(str16), 8},
+ {uniname2ctype_offset(str17), 6},
+ {uniname2ctype_offset(str18), 5},
+ {uniname2ctype_offset(str19), 4},
+ {uniname2ctype_offset(str20), 2}
+#else /* USE_UNICODE_PROPERTIES */
+ {uniname2ctype_offset(str4955), 155},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str4986), 413},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {uniname2ctype_offset(str5114), 225},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str5608), 155},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1},
+ {uniname2ctype_offset(str6098), 602}
+#endif /* USE_UNICODE_PROPERTIES */
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register unsigned int key = uniname2ctype_hash (str, len);
+
+ if (key <= MAX_HASH_VALUE)
+ {
+ register int o = wordlist[key].name;
+ if (o >= 0)
+ {
+ register const char *s = o + uniname2ctype_pool;
+
+ if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ return &wordlist[key];
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+uniname2ctype(const UChar *name, unsigned int len)
+{
+ const struct uniname2ctype_struct *p = uniname2ctype_p((const char *)name, len);
+ if (p) return p->ctype;
+ return -1;
+}
+#if defined ONIG_UNICODE_VERSION_STRING && !( \
+ ONIG_UNICODE_VERSION_MAJOR == 12 && \
+ ONIG_UNICODE_VERSION_MINOR == 1 && \
+ ONIG_UNICODE_VERSION_TEENY == 0 && \
+ 1)
+# error ONIG_UNICODE_VERSION_STRING mismatch
+#endif
+#define ONIG_UNICODE_VERSION_STRING "12.1.0"
+#define ONIG_UNICODE_VERSION_MAJOR 12
+#define ONIG_UNICODE_VERSION_MINOR 1
+#define ONIG_UNICODE_VERSION_TEENY 0
+#if defined ONIG_UNICODE_EMOJI_VERSION_STRING && !( \
+ ONIG_UNICODE_EMOJI_VERSION_MAJOR == 12 && \
+ ONIG_UNICODE_EMOJI_VERSION_MINOR == 0 && \
+ 1)
+# error ONIG_UNICODE_EMOJI_VERSION_STRING mismatch
+#endif
+#define ONIG_UNICODE_EMOJI_VERSION_STRING "12.0"
+#define ONIG_UNICODE_EMOJI_VERSION_MAJOR 12
+#define ONIG_UNICODE_EMOJI_VERSION_MINOR 0
diff --git a/enc/unicode/case-folding.rb b/enc/unicode/case-folding.rb
index 829efefaf1..4a29fdebf7 100755..100644
--- a/enc/unicode/case-folding.rb
+++ b/enc/unicode/case-folding.rb
@@ -232,7 +232,7 @@ class CaseMapping
@version = nil
IO.foreach(File.join(mapping_directory, 'UnicodeData.txt'), mode: "rb") do |line|
next if line =~ /^</
- code, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11, upper, lower, title = line.chomp.split ';'
+ code, _, _, _, _, _, _, _, _, _, _, _, upper, lower, title = line.chomp.split ';'
unless upper and lower and title and (upper+lower+title)==''
@mappings[code] = MapItem.new(code, upper, lower, title)
end
@@ -264,7 +264,6 @@ class CaseMapping
from = Array(from).map {|i| "%04X" % i}.join(" ")
to = Array(to).map {|i| "%04X" % i}.join(" ")
item = map(from)
- specials_index = nil
specials = []
case type
when 'CaseFold_11'
@@ -309,7 +308,7 @@ class CaseMapping
end
unless item.upper == item.title
if item.code == item.title
- raise "Unpredicted case 1 in enc/unicode/case_folding.rb. Please contact https://bugs.ruby-lang.org/."
+ flags += '|IT' # was unpredicted case 1
elsif item.title==to[1]
flags += '|ST'
else
@@ -410,8 +409,8 @@ if $0 == __FILE__
s = f.string
end
if dest
- open(dest, "wb") do |f|
- f.print(s)
+ open(dest, "wb") do |file|
+ file.print(s)
end
else
STDOUT.print(s)
diff --git a/enc/windows_1250.c b/enc/windows_1250.c
index d2cf7b16bc..daf23e9d1e 100644
--- a/enc/windows_1250.c
+++ b/enc/windows_1250.c
@@ -266,6 +266,6 @@ OnigEncodingDefine(windows_1250, Windows_1250) = {
* MIBenum: 2251
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1250.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1250
+ * Link: https://en.wikipedia.org/wiki/Windows-1250
*/
ENC_ALIAS("CP1250", "Windows-1250")
diff --git a/enc/windows_1251.c b/enc/windows_1251.c
index fcd0f1015d..6c892c1b8c 100644
--- a/enc/windows_1251.c
+++ b/enc/windows_1251.c
@@ -248,6 +248,6 @@ OnigEncodingDefine(windows_1251, Windows_1251) = {
* MIBenum: 2251
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1251.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1251
+ * Link: https://en.wikipedia.org/wiki/Windows-1251
*/
ENC_ALIAS("CP1251", "Windows-1251")
diff --git a/enc/windows_1252.c b/enc/windows_1252.c
index 5f90c15601..b685878d3f 100644
--- a/enc/windows_1252.c
+++ b/enc/windows_1252.c
@@ -255,6 +255,6 @@ OnigEncodingDefine(windows_1252, Windows_1252) = {
* MIBenum: 2251
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1252.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1252
+ * Link: https://en.wikipedia.org/wiki/Windows-1252
*/
ENC_ALIAS("CP1252", "Windows-1252")
diff --git a/enc/windows_1253.c b/enc/windows_1253.c
index 9e9c63a581..b2a43581c3 100644
--- a/enc/windows_1253.c
+++ b/enc/windows_1253.c
@@ -32,7 +32,7 @@
* MIBenum: 2253
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1253.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1253
+ * Link: https://en.wikipedia.org/wiki/Windows-1253
*/
#include "regenc.h"
diff --git a/enc/windows_1254.c b/enc/windows_1254.c
index 9ae66978a2..5e6d92d3d2 100644
--- a/enc/windows_1254.c
+++ b/enc/windows_1254.c
@@ -32,7 +32,7 @@
* MIBenum: 2254
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1254.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1254
+ * Link: https://en.wikipedia.org/wiki/Windows-1254
*/
#include "regenc.h"
diff --git a/enc/windows_1257.c b/enc/windows_1257.c
index 936a94ac76..ada03b72bf 100644
--- a/enc/windows_1257.c
+++ b/enc/windows_1257.c
@@ -35,7 +35,7 @@
* MIBenum: 2257
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/sbcs/1257.mspx
- * Link: http://en.wikipedia.org/wiki/Windows-1257
+ * Link: https://en.wikipedia.org/wiki/Windows-1257
*/
#define ENC_CP1252_TO_LOWER_CASE(c) EncCP1252_ToLowerCaseTable[c]
diff --git a/enc/windows_31j.c b/enc/windows_31j.c
index 174f8983c4..1eb859596a 100644
--- a/enc/windows_31j.c
+++ b/enc/windows_31j.c
@@ -1,5 +1,5 @@
/**********************************************************************
- cp932.c - Onigmo (Oniguruma-mod) (regular expression library)
+ windows_31j.c - Onigmo (Oniguruma-mod) (regular expression library)
**********************************************************************/
/*-
* Copyright (c) 2002-2009 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
@@ -29,7 +29,7 @@
*/
#define ENC_CP932
-#include "shift_jis.c"
+#include "shift_jis.h"
OnigEncodingDefine(windows_31j, Windows_31J) = {
mbc_enc_len,
@@ -57,7 +57,7 @@ OnigEncodingDefine(windows_31j, Windows_31J) = {
* MIBenum: 2024
* Link: http://www.iana.org/assignments/character-sets
* Link: http://www.microsoft.com/globaldev/reference/dbcs/932.mspx
- * Link: http://ja.wikipedia.org/wiki/Windows-31J
+ * Link: https://ja.wikipedia.org/wiki/Windows-31J
* Link: http://source.icu-project.org/repos/icu/data/trunk/charset/data/ucm/windows-932-2000.ucm
*
* Windows Standard Character Set and its mapping to Unicode by Microsoft.
diff --git a/enc/x_emoji.h b/enc/x_emoji.h
index 23efa1dd9e..c0a3613f1b 100644
--- a/enc/x_emoji.h
+++ b/enc/x_emoji.h
@@ -2,8 +2,8 @@
/*
* Name: UTF8-DoCoMo, SJIS-DoCoMo
- * Link: https://www.nttdocomo.co.jp/english/service/developer/make/content/pictograph/basic/index.html
- * Link: https://www.nttdocomo.co.jp/english/service/developer/make/content/pictograph/extention/index.html
+ * Link: https://www.nttdocomo.co.jp/service/developer/make/content/pictograph/basic/index.html
+ * Link: https://www.nttdocomo.co.jp/service/developer/make/content/pictograph/extent%69on/index.html
*/
ENC_REPLICATE("UTF8-DoCoMo", "UTF-8")
ENC_REPLICATE("SJIS-DoCoMo", "Windows-31J")
diff --git a/encindex.h b/encindex.h
index dcb1646f3a..8457a7b39f 100644
--- a/encindex.h
+++ b/encindex.h
@@ -1,3 +1,5 @@
+#ifndef RUBY_ENCINDEX_H
+#define RUBY_ENCINDEX_H 1
/**********************************************************************
encindex.h -
@@ -9,8 +11,7 @@
**********************************************************************/
-#ifndef RUBY_ENCINDEX_H
-#define RUBY_ENCINDEX_H 1
+#include "ruby/encoding.h" /* rb_ascii8bit_encindex etc. */
#if defined(__cplusplus)
extern "C" {
#if 0
@@ -57,6 +58,8 @@ enum ruby_preserved_encindex {
#define rb_utf8_encindex() RUBY_ENCINDEX_UTF_8
#define rb_usascii_encindex() RUBY_ENCINDEX_US_ASCII
+int rb_enc_find_index2(const char *name, long len);
+
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
diff --git a/encoding.c b/encoding.c
index 68871db268..32d5a349eb 100644
--- a/encoding.c
+++ b/encoding.c
@@ -9,17 +9,29 @@
**********************************************************************/
-#include "internal.h"
+#include "ruby/internal/config.h"
+
+#include <ctype.h>
+
#include "encindex.h"
+#include "internal.h"
+#include "internal/enc.h"
+#include "internal/encoding.h"
+#include "internal/inits.h"
+#include "internal/load.h"
+#include "internal/object.h"
+#include "internal/string.h"
+#include "internal/vm.h"
#include "regenc.h"
-#include <ctype.h>
+#include "ruby/encoding.h"
#include "ruby/util.h"
-
#include "ruby_assert.h"
+#include "vm_sync.h"
+
#ifndef ENC_DEBUG
#define ENC_DEBUG 0
#endif
-#define ENC_ASSERT (!ENC_DEBUG)?(void)0:assert
+#define ENC_ASSERT(expr) RUBY_ASSERT_WHEN(ENC_DEBUG, expr)
#define MUST_STRING(str) (ENC_ASSERT(RB_TYPE_P(str, T_STRING)), str)
#undef rb_ascii8bit_encindex
@@ -43,7 +55,10 @@ void rb_encdb_set_unicode(int index);
static ID id_encoding;
VALUE rb_cEncoding;
-static VALUE rb_encoding_list;
+
+#define DEFAULT_ENCODING_LIST_CAPA 128
+static VALUE rb_default_encoding_list;
+static VALUE rb_additional_encoding_list;
struct rb_encoding_entry {
const char *name;
@@ -51,12 +66,27 @@ struct rb_encoding_entry {
rb_encoding *base;
};
-static struct {
+static struct enc_table {
struct rb_encoding_entry *list;
int count;
int size;
st_table *names;
-} enc_table;
+} global_enc_table;
+
+static rb_encoding *global_enc_ascii,
+ *global_enc_utf_8,
+ *global_enc_us_ascii;
+
+#define GLOBAL_ENC_TABLE_ENTER(enc_table) struct enc_table *enc_table = &global_enc_table; RB_VM_LOCK_ENTER()
+#define GLOBAL_ENC_TABLE_LEAVE() RB_VM_LOCK_LEAVE()
+#define GLOBAL_ENC_TABLE_EVAL(enc_table, expr) do { \
+ GLOBAL_ENC_TABLE_ENTER(enc_table); \
+ { \
+ expr; \
+ } \
+ GLOBAL_ENC_TABLE_LEAVE(); \
+} while (0)
+
#define ENC_DUMMY_FLAG (1<<24)
#define ENC_INDEX_MASK (~(~0U<<24))
@@ -65,18 +95,12 @@ static struct {
#define ENC_DUMMY_P(enc) ((enc)->ruby_encoding_index & ENC_DUMMY_FLAG)
#define ENC_SET_DUMMY(enc) ((enc)->ruby_encoding_index |= ENC_DUMMY_FLAG)
-void rb_enc_init(void);
-
#define ENCODING_COUNT ENCINDEX_BUILTIN_MAX
#define UNSPECIFIED_ENCODING INT_MAX
#define ENCODING_NAMELEN_MAX 63
#define valid_encoding_name_p(name) ((name) && strlen(name) <= ENCODING_NAMELEN_MAX)
-#define enc_autoload_p(enc) (!rb_enc_mbmaxlen(enc))
-
-static int load_encoding(const char *name);
-
static const rb_data_type_t encoding_data_type = {
"encoding",
{0, 0, 0,},
@@ -95,22 +119,69 @@ rb_data_is_encoding(VALUE obj)
static VALUE
enc_new(rb_encoding *encoding)
{
- return TypedData_Wrap_Struct(rb_cEncoding, &encoding_data_type, (void *)encoding);
+ VALUE enc = TypedData_Wrap_Struct(rb_cEncoding, &encoding_data_type, (void *)encoding);
+ rb_obj_freeze(enc);
+ FL_SET_RAW(enc, RUBY_FL_SHAREABLE);
+ return enc;
+}
+
+static void
+enc_list_update(int index, rb_raw_encoding *encoding)
+{
+ if (index < DEFAULT_ENCODING_LIST_CAPA) {
+ VALUE list = rb_default_encoding_list;
+ if (list && NIL_P(rb_ary_entry(list, index))) {
+ /* initialize encoding data */
+ rb_ary_store(list, index, enc_new(encoding));
+ }
+ }
+ else {
+ RB_VM_LOCK_ENTER();
+ {
+ VALUE list = rb_additional_encoding_list;
+ if (list && NIL_P(rb_ary_entry(list, index))) {
+ /* initialize encoding data */
+ rb_ary_store(list, index - DEFAULT_ENCODING_LIST_CAPA, enc_new(encoding));
+ }
+ }
+ RB_VM_LOCK_LEAVE();
+ }
}
static VALUE
-rb_enc_from_encoding_index(int idx)
+enc_list_lookup(int idx)
{
VALUE list, enc;
- if (!(list = rb_encoding_list)) {
- rb_bug("rb_enc_from_encoding_index(%d): no rb_encoding_list", idx);
+ if (idx < DEFAULT_ENCODING_LIST_CAPA) {
+ if (!(list = rb_default_encoding_list)) {
+ rb_bug("rb_enc_from_encoding_index(%d): no rb_default_encoding_list", idx);
+ }
+ enc = rb_ary_entry(list, idx);
+ }
+ else {
+ RB_VM_LOCK_ENTER();
+ {
+ if (!(list = rb_additional_encoding_list)) {
+ rb_bug("rb_enc_from_encoding_index(%d): no rb_additional_encoding_list", idx);
+ }
+ enc = rb_ary_entry(list, idx - DEFAULT_ENCODING_LIST_CAPA);
+ }
+ RB_VM_LOCK_LEAVE();
}
- enc = rb_ary_entry(list, idx);
+
if (NIL_P(enc)) {
- rb_bug("rb_enc_from_encoding_index(%d): not created yet", idx);
+ rb_bug("rb_enc_from_encoding_index(%d): not created yet", idx);
+ }
+ else {
+ return enc;
}
- return enc;
+}
+
+static VALUE
+rb_enc_from_encoding_index(int idx)
+{
+ return enc_list_lookup(idx);
}
VALUE
@@ -134,16 +205,14 @@ rb_enc_dummy_p(rb_encoding *enc)
return ENC_DUMMY_P(enc) != 0;
}
-static int enc_autoload(rb_encoding *);
-
static int
check_encoding(rb_encoding *enc)
{
int index = rb_enc_to_index(enc);
if (rb_enc_from_index(index) != enc)
return -1;
- if (enc_autoload_p(enc)) {
- index = enc_autoload(enc);
+ if (rb_enc_autoload_p(enc)) {
+ index = rb_enc_autoload(enc);
}
return index;
}
@@ -187,7 +256,7 @@ must_encindex(int index)
rb_raise(rb_eEncodingError, "wrong encoding index %d for %s (expected %d)",
index, rb_enc_name(enc), ENC_TO_ENCINDEX(enc));
}
- if (enc_autoload_p(enc) && enc_autoload(enc) == -1) {
+ if (rb_enc_autoload_p(enc) && rb_enc_autoload(enc) == -1) {
rb_loaderror("failed to load encoding (%s)",
rb_enc_name(enc));
}
@@ -198,6 +267,7 @@ int
rb_to_encoding_index(VALUE enc)
{
int idx;
+ const char *name;
idx = enc_check_encoding(enc);
if (idx >= 0) {
@@ -209,20 +279,33 @@ rb_to_encoding_index(VALUE enc)
if (!rb_enc_asciicompat(rb_enc_get(enc))) {
return -1;
}
- return rb_enc_find_index(StringValueCStr(enc));
+ if (!(name = rb_str_to_cstr(enc))) {
+ return -1;
+ }
+ return rb_enc_find_index(name);
+}
+
+static const char *
+name_for_encoding(volatile VALUE *enc)
+{
+ VALUE name = StringValue(*enc);
+ const char *n;
+
+ if (!rb_enc_asciicompat(rb_enc_get(name))) {
+ rb_raise(rb_eArgError, "invalid encoding name (non ASCII)");
+ }
+ if (!(n = rb_str_to_cstr(name))) {
+ rb_raise(rb_eArgError, "invalid encoding name (NUL byte)");
+ }
+ return n;
}
/* Returns encoding index or UNSPECIFIED_ENCODING */
static int
str_find_encindex(VALUE enc)
{
- int idx;
-
- StringValue(enc);
- if (!rb_enc_asciicompat(rb_enc_get(enc))) {
- rb_raise(rb_eArgError, "invalid name encoding (non ASCII)");
- }
- idx = rb_enc_find_index(StringValueCStr(enc));
+ int idx = rb_enc_find_index(name_for_encoding(&enc));
+ RB_GC_GUARD(enc);
return idx;
}
@@ -259,33 +342,26 @@ rb_find_encoding(VALUE enc)
return rb_enc_from_index(idx);
}
-void
-rb_gc_mark_encodings(void)
-{
-}
-
static int
-enc_table_expand(int newsize)
+enc_table_expand(struct enc_table *enc_table, int newsize)
{
struct rb_encoding_entry *ent;
int count = newsize;
- if (enc_table.size >= newsize) return newsize;
+ if (enc_table->size >= newsize) return newsize;
newsize = (newsize + 7) / 8 * 8;
- ent = realloc(enc_table.list, sizeof(*enc_table.list) * newsize);
- if (!ent) return -1;
- memset(ent + enc_table.size, 0, sizeof(*ent)*(newsize - enc_table.size));
- enc_table.list = ent;
- enc_table.size = newsize;
+ ent = REALLOC_N(enc_table->list, struct rb_encoding_entry, newsize);
+ memset(ent + enc_table->size, 0, sizeof(*ent)*(newsize - enc_table->size));
+ enc_table->list = ent;
+ enc_table->size = newsize;
return count;
}
static int
-enc_register_at(int index, const char *name, rb_encoding *base_encoding)
+enc_register_at(struct enc_table *enc_table, int index, const char *name, rb_encoding *base_encoding)
{
- struct rb_encoding_entry *ent = &enc_table.list[index];
+ struct rb_encoding_entry *ent = &enc_table->list[index];
rb_raw_encoding *encoding;
- VALUE list;
if (!valid_encoding_name_p(name)) return -1;
if (!ent->name) {
@@ -307,76 +383,120 @@ enc_register_at(int index, const char *name, rb_encoding *base_encoding)
encoding->name = name;
encoding->ruby_encoding_index = index;
ent->enc = encoding;
- st_insert(enc_table.names, (st_data_t)name, (st_data_t)index);
- list = rb_encoding_list;
- if (list && NIL_P(rb_ary_entry(list, index))) {
- /* initialize encoding data */
- rb_ary_store(list, index, enc_new(encoding));
- }
+ st_insert(enc_table->names, (st_data_t)name, (st_data_t)index);
+
+ enc_list_update(index, encoding);
return index;
}
static int
-enc_register(const char *name, rb_encoding *encoding)
+enc_register(struct enc_table *enc_table, const char *name, rb_encoding *encoding)
{
- int index = enc_table.count;
+ int index = enc_table->count;
- if ((index = enc_table_expand(index + 1)) < 0) return -1;
- enc_table.count = index;
- return enc_register_at(index - 1, name, encoding);
+ enc_table->count = enc_table_expand(enc_table, index + 1);
+ return enc_register_at(enc_table, index, name, encoding);
}
static void set_encoding_const(const char *, rb_encoding *);
-int rb_enc_registered(const char *name);
+static int enc_registered(struct enc_table *enc_table, const char *name);
+
+static rb_encoding *
+enc_from_index(struct enc_table *enc_table, int index)
+{
+ if (UNLIKELY(index < 0 || enc_table->count <= (index &= ENC_INDEX_MASK))) {
+ return 0;
+ }
+ return enc_table->list[index].enc;
+}
+
+rb_encoding *
+rb_enc_from_index(int index)
+{
+ rb_encoding *enc;
+
+ switch (index) {
+ case ENCINDEX_ASCII: return global_enc_ascii;
+ case ENCINDEX_UTF_8: return global_enc_utf_8;
+ case ENCINDEX_US_ASCII: return global_enc_us_ascii;
+ default:
+ GLOBAL_ENC_TABLE_EVAL(enc_table,
+ enc = enc_from_index(enc_table, index));
+ return enc;
+ }
+}
int
rb_enc_register(const char *name, rb_encoding *encoding)
{
- int index = rb_enc_registered(name);
+ int index;
+
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ index = enc_registered(enc_table, name);
+
+ if (index >= 0) {
+ rb_encoding *oldenc = enc_from_index(enc_table, index);
+ if (STRCASECMP(name, rb_enc_name(oldenc))) {
+ index = enc_register(enc_table, name, encoding);
+ }
+ else if (rb_enc_autoload_p(oldenc) || !ENC_DUMMY_P(oldenc)) {
+ enc_register_at(enc_table, index, name, encoding);
+ }
+ else {
+ rb_raise(rb_eArgError, "encoding %s is already registered", name);
+ }
+ }
+ else {
+ index = enc_register(enc_table, name, encoding);
+ set_encoding_const(name, rb_enc_from_index(index));
+ }
+ }
+ GLOBAL_ENC_TABLE_LEAVE();
+ return index;
+}
- if (index >= 0) {
- rb_encoding *oldenc = rb_enc_from_index(index);
- if (STRCASECMP(name, rb_enc_name(oldenc))) {
- index = enc_register(name, encoding);
- }
- else if (enc_autoload_p(oldenc) || !ENC_DUMMY_P(oldenc)) {
- enc_register_at(index, name, encoding);
- }
- else {
- rb_raise(rb_eArgError, "encoding %s is already registered", name);
- }
- }
- else {
- index = enc_register(name, encoding);
- set_encoding_const(name, rb_enc_from_index(index));
+int
+enc_registered(struct enc_table *enc_table, const char *name)
+{
+ st_data_t idx = 0;
+
+ if (!name) return -1;
+ if (!enc_table->list) return -1;
+ if (st_lookup(enc_table->names, (st_data_t)name, &idx)) {
+ return (int)idx;
}
- return index;
+ return -1;
}
void
rb_encdb_declare(const char *name)
{
- int idx = rb_enc_registered(name);
- if (idx < 0) {
- idx = enc_register(name, 0);
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ int idx = enc_registered(enc_table, name);
+ if (idx < 0) {
+ idx = enc_register(enc_table, name, 0);
+ }
+ set_encoding_const(name, rb_enc_from_index(idx));
}
- set_encoding_const(name, rb_enc_from_index(idx));
+ GLOBAL_ENC_TABLE_LEAVE();
}
static void
-enc_check_duplication(const char *name)
+enc_check_duplication(struct enc_table *enc_table, const char *name)
{
- if (rb_enc_registered(name) >= 0) {
+ if (enc_registered(enc_table, name) >= 0) {
rb_raise(rb_eArgError, "encoding %s is already registered", name);
}
}
static rb_encoding*
-set_base_encoding(int index, rb_encoding *base)
+set_base_encoding(struct enc_table *enc_table, int index, rb_encoding *base)
{
- rb_encoding *enc = enc_table.list[index].enc;
+ rb_encoding *enc = enc_table->list[index].enc;
- enc_table.list[index].base = base;
+ enc_table->list[index].base = base;
if (ENC_DUMMY_P(base)) ENC_SET_DUMMY((rb_raw_encoding *)enc);
return enc;
}
@@ -388,9 +508,13 @@ set_base_encoding(int index, rb_encoding *base)
void
rb_enc_set_base(const char *name, const char *orig)
{
- int idx = rb_enc_registered(name);
- int origidx = rb_enc_registered(orig);
- set_base_encoding(idx, rb_enc_from_index(origidx));
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ int idx = enc_registered(enc_table, name);
+ int origidx = enc_registered(enc_table, orig);
+ set_base_encoding(enc_table, idx, rb_enc_from_index(origidx));
+ }
+ GLOBAL_ENC_TABLE_LEAVE();
}
/* for encdb.h
@@ -399,24 +523,39 @@ rb_enc_set_base(const char *name, const char *orig)
int
rb_enc_set_dummy(int index)
{
- rb_encoding *enc = enc_table.list[index].enc;
+ rb_encoding *enc;
+
+ GLOBAL_ENC_TABLE_EVAL(enc_table,
+ enc = enc_table->list[index].enc);
ENC_SET_DUMMY((rb_raw_encoding *)enc);
return index;
}
-int
-rb_enc_replicate(const char *name, rb_encoding *encoding)
+static int
+enc_replicate(struct enc_table *enc_table, const char *name, rb_encoding *encoding)
{
int idx;
- enc_check_duplication(name);
- idx = enc_register(name, encoding);
- set_base_encoding(idx, encoding);
+ enc_check_duplication(enc_table, name);
+ idx = enc_register(enc_table, name, encoding);
+ if (idx < 0) rb_raise(rb_eArgError, "invalid encoding name: %s", name);
+ set_base_encoding(enc_table, idx, encoding);
set_encoding_const(name, rb_enc_from_index(idx));
return idx;
}
+int
+rb_enc_replicate(const char *name, rb_encoding *encoding)
+{
+ int r;
+
+ GLOBAL_ENC_TABLE_EVAL(enc_table,
+ r = enc_replicate(enc_table, name, encoding));
+
+ return r;
+}
+
/*
* call-seq:
* enc.replicate(name) -> encoding
@@ -427,59 +566,83 @@ rb_enc_replicate(const char *name, rb_encoding *encoding)
*
*/
static VALUE
-enc_replicate(VALUE encoding, VALUE name)
+enc_replicate_m(VALUE encoding, VALUE name)
{
- return rb_enc_from_encoding_index(
- rb_enc_replicate(StringValueCStr(name),
- rb_to_encoding(encoding)));
+ int idx = rb_enc_replicate(name_for_encoding(&name), rb_to_encoding(encoding));
+ RB_GC_GUARD(name);
+ return rb_enc_from_encoding_index(idx);
}
static int
-enc_replicate_with_index(const char *name, rb_encoding *origenc, int idx)
+enc_replicate_with_index(struct enc_table *enc_table, const char *name, rb_encoding *origenc, int idx)
{
if (idx < 0) {
- idx = enc_register(name, origenc);
+ idx = enc_register(enc_table, name, origenc);
}
else {
- idx = enc_register_at(idx, name, origenc);
+ idx = enc_register_at(enc_table, idx, name, origenc);
}
if (idx >= 0) {
- set_base_encoding(idx, origenc);
+ set_base_encoding(enc_table, idx, origenc);
set_encoding_const(name, rb_enc_from_index(idx));
}
+ else {
+ rb_raise(rb_eArgError, "failed to replicate encoding");
+ }
return idx;
}
int
rb_encdb_replicate(const char *name, const char *orig)
{
- int origidx = rb_enc_registered(orig);
- int idx = rb_enc_registered(name);
+ int r;
- if (origidx < 0) {
- origidx = enc_register(orig, 0);
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ int origidx = enc_registered(enc_table, orig);
+ int idx = enc_registered(enc_table, name);
+
+ if (origidx < 0) {
+ origidx = enc_register(enc_table, orig, 0);
+ }
+ r = enc_replicate_with_index(enc_table, name, rb_enc_from_index(origidx), idx);
}
- return enc_replicate_with_index(name, rb_enc_from_index(origidx), idx);
+ GLOBAL_ENC_TABLE_LEAVE();
+
+ return r;
}
int
rb_define_dummy_encoding(const char *name)
{
- int index = rb_enc_replicate(name, rb_ascii8bit_encoding());
- rb_encoding *enc = enc_table.list[index].enc;
+ int index;
+
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ index = enc_replicate(enc_table, name, rb_ascii8bit_encoding());
+ rb_encoding *enc = enc_table->list[index].enc;
+ ENC_SET_DUMMY((rb_raw_encoding *)enc);
+ }
+ GLOBAL_ENC_TABLE_LEAVE();
- ENC_SET_DUMMY((rb_raw_encoding *)enc);
return index;
}
int
rb_encdb_dummy(const char *name)
{
- int index = enc_replicate_with_index(name, rb_ascii8bit_encoding(),
- rb_enc_registered(name));
- rb_encoding *enc = enc_table.list[index].enc;
+ int index;
+
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ index = enc_replicate_with_index(enc_table, name,
+ rb_ascii8bit_encoding(),
+ enc_registered(enc_table, name));
+ rb_encoding *enc = enc_table->list[index].enc;
+ ENC_SET_DUMMY((rb_raw_encoding *)enc);
+ }
+ GLOBAL_ENC_TABLE_LEAVE();
- ENC_SET_DUMMY((rb_raw_encoding *)enc);
return index;
}
@@ -538,45 +701,58 @@ enc_dup_name(st_data_t name)
* else returns NULL.
*/
static int
-enc_alias_internal(const char *alias, int idx)
+enc_alias_internal(struct enc_table *enc_table, const char *alias, int idx)
{
- return st_insert2(enc_table.names, (st_data_t)alias, (st_data_t)idx,
+ return st_insert2(enc_table->names, (st_data_t)alias, (st_data_t)idx,
enc_dup_name);
}
static int
-enc_alias(const char *alias, int idx)
+enc_alias(struct enc_table *enc_table, const char *alias, int idx)
{
if (!valid_encoding_name_p(alias)) return -1;
- if (!enc_alias_internal(alias, idx))
- set_encoding_const(alias, rb_enc_from_index(idx));
+ if (!enc_alias_internal(enc_table, alias, idx))
+ set_encoding_const(alias, enc_from_index(enc_table, idx));
return idx;
}
int
rb_enc_alias(const char *alias, const char *orig)
{
- int idx;
+ int idx, r;
- enc_check_duplication(alias);
- if (!enc_table.list) {
- rb_enc_init();
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ enc_check_duplication(enc_table, alias);
+ if ((idx = rb_enc_find_index(orig)) < 0) {
+ r = -1;
+ }
+ else {
+ r = enc_alias(enc_table, alias, idx);
+ }
}
- if ((idx = rb_enc_find_index(orig)) < 0) {
- return -1;
- }
- return enc_alias(alias, idx);
+ GLOBAL_ENC_TABLE_LEAVE();
+
+ return r;
}
int
rb_encdb_alias(const char *alias, const char *orig)
{
- int idx = rb_enc_registered(orig);
+ int r;
- if (idx < 0) {
- idx = enc_register(orig, 0);
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ int idx = enc_registered(enc_table, orig);
+
+ if (idx < 0) {
+ idx = enc_register(enc_table, orig, 0);
+ }
+ r = enc_alias(enc_table, alias, idx);
}
- return enc_alias(alias, idx);
+ GLOBAL_ENC_TABLE_LEAVE();
+
+ return r;
}
void
@@ -585,19 +761,22 @@ rb_encdb_set_unicode(int index)
((rb_raw_encoding *)rb_enc_from_index(index))->flags |= ONIGENC_FLAG_UNICODE;
}
-void
-rb_enc_init(void)
+static void
+rb_enc_init(struct enc_table *enc_table)
{
- enc_table_expand(ENCODING_COUNT + 1);
- if (!enc_table.names) {
- enc_table.names = st_init_strcasetable();
+ enc_table_expand(enc_table, ENCODING_COUNT + 1);
+ if (!enc_table->names) {
+ enc_table->names = st_init_strcasetable();
}
-#define ENC_REGISTER(enc) enc_register_at(ENCINDEX_##enc, rb_enc_name(&OnigEncoding##enc), &OnigEncoding##enc)
+#define ENC_REGISTER(enc) enc_register_at(enc_table, ENCINDEX_##enc, rb_enc_name(&OnigEncoding##enc), &OnigEncoding##enc)
ENC_REGISTER(ASCII);
ENC_REGISTER(UTF_8);
ENC_REGISTER(US_ASCII);
+ global_enc_ascii = enc_table->list[ENCINDEX_ASCII].enc;
+ global_enc_utf_8 = enc_table->list[ENCINDEX_UTF_8].enc;
+ global_enc_us_ascii = enc_table->list[ENCINDEX_US_ASCII].enc;
#undef ENC_REGISTER
-#define ENCDB_REGISTER(name, enc) enc_register_at(ENCINDEX_##enc, name, NULL)
+#define ENCDB_REGISTER(name, enc) enc_register_at(enc_table, ENCINDEX_##enc, name, NULL)
ENCDB_REGISTER("UTF-16BE", UTF_16BE);
ENCDB_REGISTER("UTF-16LE", UTF_16LE);
ENCDB_REGISTER("UTF-32BE", UTF_32BE);
@@ -609,19 +788,7 @@ rb_enc_init(void)
ENCDB_REGISTER("EUC-JP", EUC_JP);
ENCDB_REGISTER("Windows-31J", Windows_31J);
#undef ENCDB_REGISTER
- enc_table.count = ENCINDEX_BUILTIN_MAX;
-}
-
-rb_encoding *
-rb_enc_from_index(int index)
-{
- if (!enc_table.list) {
- rb_enc_init();
- }
- if (index < 0 || enc_table.count <= (index &= ENC_INDEX_MASK)) {
- return 0;
- }
- return enc_table.list[index].enc;
+ enc_table->count = ENCINDEX_BUILTIN_MAX;
}
rb_encoding *
@@ -630,19 +797,6 @@ rb_enc_get_from_index(int index)
return must_encindex(index);
}
-int
-rb_enc_registered(const char *name)
-{
- st_data_t idx = 0;
-
- if (!name) return -1;
- if (!enc_table.list) return -1;
- if (st_lookup(enc_table.names, (st_data_t)name, &idx)) {
- return (int)idx;
- }
- return -1;
-}
-
static int
load_encoding(const char *name)
{
@@ -659,42 +813,63 @@ load_encoding(const char *name)
else if (ISUPPER(*s)) *s = (char)TOLOWER(*s);
++s;
}
- FL_UNSET(enclib, FL_TAINT);
- OBJ_FREEZE(enclib);
+ enclib = rb_fstring(enclib);
ruby_verbose = Qfalse;
ruby_debug = Qfalse;
errinfo = rb_errinfo();
- loaded = rb_require_internal(enclib, rb_safe_level());
+ loaded = rb_require_internal(enclib);
ruby_verbose = verbose;
ruby_debug = debug;
rb_set_errinfo(errinfo);
- if (loaded < 0 || 1 < loaded) return -1;
- if ((idx = rb_enc_registered(name)) < 0) return -1;
- if (enc_autoload_p(enc_table.list[idx].enc)) return -1;
+
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ if (loaded < 0 || 1 < loaded) {
+ idx = -1;
+ }
+ else if ((idx = enc_registered(enc_table, name)) < 0) {
+ idx = -1;
+ }
+ else if (rb_enc_autoload_p(enc_table->list[idx].enc)) {
+ idx = -1;
+ }
+ }
+ GLOBAL_ENC_TABLE_LEAVE();
+
return idx;
}
static int
-enc_autoload(rb_encoding *enc)
+enc_autoload_body(struct enc_table *enc_table, rb_encoding *enc)
{
- int i;
- rb_encoding *base = enc_table.list[ENC_TO_ENCINDEX(enc)].base;
+ rb_encoding *base = enc_table->list[ENC_TO_ENCINDEX(enc)].base;
if (base) {
- i = 0;
+ int i = 0;
do {
- if (i >= enc_table.count) return -1;
- } while (enc_table.list[i].enc != base && (++i, 1));
- if (enc_autoload_p(base)) {
- if (enc_autoload(base) < 0) return -1;
+ if (i >= enc_table->count) return -1;
+ } while (enc_table->list[i].enc != base && (++i, 1));
+ if (rb_enc_autoload_p(base)) {
+ if (rb_enc_autoload(base) < 0) return -1;
}
i = enc->ruby_encoding_index;
- enc_register_at(i & ENC_INDEX_MASK, rb_enc_name(enc), base);
- ((rb_raw_encoding *)enc)->ruby_encoding_index = i;
+ enc_register_at(enc_table, i & ENC_INDEX_MASK, rb_enc_name(enc), base);
+ ((rb_raw_encoding *)enc)->ruby_encoding_index = i;
i &= ENC_INDEX_MASK;
+ return i;
}
else {
- i = load_encoding(rb_enc_name(enc));
+ return -2;
+ }
+}
+
+int
+rb_enc_autoload(rb_encoding *enc)
+{
+ int i;
+ GLOBAL_ENC_TABLE_EVAL(enc_table, i = enc_autoload_body(enc_table, enc));
+ if (i == -2) {
+ i = load_encoding(rb_enc_name(enc));
}
return i;
}
@@ -703,9 +878,11 @@ enc_autoload(rb_encoding *enc)
int
rb_enc_find_index(const char *name)
{
- int i = rb_enc_registered(name);
+ int i;
rb_encoding *enc;
+ GLOBAL_ENC_TABLE_EVAL(enc_table, i = enc_registered(enc_table, name));
+
if (i < 0) {
i = load_encoding(name);
}
@@ -714,8 +891,8 @@ rb_enc_find_index(const char *name)
rb_raise(rb_eArgError, "encoding %s is not registered", name);
}
}
- else if (enc_autoload_p(enc)) {
- if (enc_autoload(enc) < 0) {
+ else if (rb_enc_autoload_p(enc)) {
+ if (rb_enc_autoload(enc) < 0) {
rb_warn("failed to load encoding (%s); use ASCII-8BIT instead",
name);
return 0;
@@ -724,6 +901,17 @@ rb_enc_find_index(const char *name)
return i;
}
+int
+rb_enc_find_index2(const char *name, long len)
+{
+ char buf[ENCODING_NAMELEN_MAX+1];
+
+ if (len > ENCODING_NAMELEN_MAX) return -1;
+ memcpy(buf, name, len);
+ buf[len] = '\0';
+ return rb_enc_find_index(buf);
+}
+
rb_encoding *
rb_enc_find(const char *name)
{
@@ -749,6 +937,12 @@ enc_capable(VALUE obj)
}
}
+int
+rb_enc_capable(VALUE obj)
+{
+ return enc_capable(obj);
+}
+
ID
rb_id_encoding(void)
{
@@ -763,8 +957,18 @@ enc_get_index_str(VALUE str)
if (i == ENCODING_INLINE_MAX) {
VALUE iv;
+#if 0
iv = rb_ivar_get(str, rb_id_encoding());
i = NUM2INT(iv);
+#else
+ /*
+ * Tentatively, assume ASCII-8BIT, if encoding index instance
+ * variable is not found. This can happen when freeing after
+ * all instance variables are removed in `obj_free`.
+ */
+ iv = rb_attr_get(str, rb_id_encoding());
+ i = NIL_P(iv) ? ENCINDEX_ASCII : NUM2INT(iv);
+#endif
}
return i;
}
@@ -780,24 +984,26 @@ rb_enc_get_index(VALUE obj)
obj = rb_sym2str(obj);
}
switch (BUILTIN_TYPE(obj)) {
- as_default:
- default:
case T_STRING:
+ case T_SYMBOL:
case T_REGEXP:
i = enc_get_index_str(obj);
break;
case T_FILE:
tmp = rb_funcallv(obj, rb_intern("internal_encoding"), 0, 0);
- if (NIL_P(tmp)) obj = rb_funcallv(obj, rb_intern("external_encoding"), 0, 0);
- else obj = tmp;
- if (NIL_P(obj)) break;
+ if (NIL_P(tmp)) {
+ tmp = rb_funcallv(obj, rb_intern("external_encoding"), 0, 0);
+ }
+ if (is_obj_encoding(tmp)) {
+ i = enc_check_encoding(tmp);
+ }
+ break;
case T_DATA:
if (is_data_encoding(obj)) {
i = enc_check_encoding(obj);
}
- else {
- goto as_default;
- }
+ break;
+ default:
break;
}
return i;
@@ -806,6 +1012,10 @@ rb_enc_get_index(VALUE obj)
static void
enc_set_index(VALUE obj, int idx)
{
+ if (!enc_capable(obj)) {
+ rb_raise(rb_eArgError, "cannot set encoding on non-encoding capable object");
+ }
+
if (idx < ENCODING_INLINE_MAX) {
ENCODING_SET_INLINED(obj, idx);
return;
@@ -897,7 +1107,7 @@ enc_compatible_latter(VALUE str1, VALUE str2, int idx1, int idx2)
if (isstr2 && RSTRING_LEN(str2) == 0)
return enc1;
isstr1 = RB_TYPE_P(str1, T_STRING);
- if (isstr1 && RSTRING_LEN(str1) == 0)
+ if (isstr1 && isstr2 && RSTRING_LEN(str1) == 0)
return (rb_enc_asciicompat(enc1) && rb_enc_str_asciionly_p(str2)) ? enc1 : enc2;
if (!rb_enc_asciicompat(enc1) || !rb_enc_asciicompat(enc2)) {
return 0;
@@ -1126,7 +1336,7 @@ enc_inspect(VALUE self)
"#<%"PRIsVALUE":%s%s%s>", rb_obj_class(self),
rb_enc_name(enc),
(ENC_DUMMY_P(enc) ? " (dummy)" : ""),
- enc_autoload_p(enc) ? " (autoload)" : "");
+ rb_enc_autoload_p(enc) ? " (autoload)" : "");
}
/*
@@ -1150,8 +1360,7 @@ enc_names_i(st_data_t name, st_data_t idx, st_data_t args)
VALUE *arg = (VALUE *)args;
if ((int)idx == (int)arg[0]) {
- VALUE str = rb_usascii_str_new2((char *)name);
- OBJ_FREEZE(str);
+ VALUE str = rb_fstring_cstr((char *)name);
rb_ary_push(arg[1], str);
}
return ST_CONTINUE;
@@ -1163,7 +1372,7 @@ enc_names_i(st_data_t name, st_data_t idx, st_data_t args)
*
* Returns the list of name and aliases of the encoding.
*
- * Encoding::WINDOWS_31J.names #=> ["Windows-31J", "CP932", "csWindows31J"]
+ * Encoding::WINDOWS_31J.names #=> ["Windows-31J", "CP932", "csWindows31J", "SJIS", "PCK"]
*/
static VALUE
enc_names(VALUE self)
@@ -1172,7 +1381,10 @@ enc_names(VALUE self)
args[0] = (VALUE)rb_to_encoding_index(self);
args[1] = rb_ary_new2(0);
- st_foreach(enc_table.names, enc_names_i, (st_data_t)args);
+
+ GLOBAL_ENC_TABLE_EVAL(enc_table,
+ st_foreach(enc_table->names, enc_names_i, (st_data_t)args));
+
return args[1];
}
@@ -1198,7 +1410,14 @@ static VALUE
enc_list(VALUE klass)
{
VALUE ary = rb_ary_new2(0);
- rb_ary_replace(ary, rb_encoding_list);
+
+ RB_VM_LOCK_ENTER();
+ {
+ rb_ary_replace(ary, rb_default_encoding_list);
+ rb_ary_concat(ary, rb_additional_encoding_list);
+ }
+ RB_VM_LOCK_LEAVE();
+
return ary;
}
@@ -1271,12 +1490,13 @@ enc_compatible_p(VALUE klass, VALUE str1, VALUE str2)
return rb_enc_from_encoding(enc);
}
+NORETURN(static VALUE enc_s_alloc(VALUE klass));
/* :nodoc: */
static VALUE
enc_s_alloc(VALUE klass)
{
rb_undefined_alloc(klass);
- return Qnil;
+ UNREACHABLE_RETURN(Qnil);
}
/* :nodoc: */
@@ -1304,10 +1524,7 @@ enc_m_loader(VALUE klass, VALUE str)
rb_encoding *
rb_ascii8bit_encoding(void)
{
- if (!enc_table.list) {
- rb_enc_init();
- }
- return enc_table.list[ENCINDEX_ASCII].enc;
+ return global_enc_ascii;
}
int
@@ -1319,10 +1536,7 @@ rb_ascii8bit_encindex(void)
rb_encoding *
rb_utf8_encoding(void)
{
- if (!enc_table.list) {
- rb_enc_init();
- }
- return enc_table.list[ENCINDEX_UTF_8].enc;
+ return global_enc_utf_8;
}
int
@@ -1334,10 +1548,7 @@ rb_utf8_encindex(void)
rb_encoding *
rb_usascii_encoding(void)
{
- if (!enc_table.list) {
- rb_enc_init();
- }
- return enc_table.list[ENCINDEX_US_ASCII].enc;
+ return global_enc_us_ascii;
}
int
@@ -1353,15 +1564,17 @@ rb_locale_encindex(void)
{
int idx = rb_locale_charmap_index();
- if (idx < 0) idx = ENCINDEX_ASCII;
+ if (idx < 0) idx = ENCINDEX_UTF_8;
- if (rb_enc_registered("locale") < 0) {
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ if (enc_registered(enc_table, "locale") < 0) {
# if defined _WIN32
void Init_w32_codepage(void);
Init_w32_codepage();
# endif
- enc_alias_internal("locale", idx);
+ enc_alias_internal(enc_table, "locale", idx);
}
+ GLOBAL_ENC_TABLE_LEAVE();
return idx;
}
@@ -1375,7 +1588,11 @@ rb_locale_encoding(void)
int
rb_filesystem_encindex(void)
{
- int idx = rb_enc_registered("filesystem");
+ int idx;
+
+ GLOBAL_ENC_TABLE_EVAL(enc_table,
+ idx = enc_registered(enc_table, "filesystem"));
+
if (idx < 0)
idx = ENCINDEX_ASCII;
return idx;
@@ -1403,20 +1620,25 @@ enc_set_default_encoding(struct default_encoding *def, VALUE encoding, const cha
/* Already set */
overridden = TRUE;
- if (NIL_P(encoding)) {
- def->index = -1;
- def->enc = 0;
- st_insert(enc_table.names, (st_data_t)strdup(name),
- (st_data_t)UNSPECIFIED_ENCODING);
- }
- else {
- def->index = rb_enc_to_index(rb_to_encoding(encoding));
- def->enc = 0;
- enc_alias_internal(name, def->index);
- }
-
- if (def == &default_external)
- enc_alias_internal("filesystem", Init_enc_set_filesystem_encoding());
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ if (NIL_P(encoding)) {
+ def->index = -1;
+ def->enc = 0;
+ st_insert(enc_table->names, (st_data_t)strdup(name),
+ (st_data_t)UNSPECIFIED_ENCODING);
+ }
+ else {
+ def->index = rb_enc_to_index(rb_to_encoding(encoding));
+ def->enc = 0;
+ enc_alias_internal(enc_table, name, def->index);
+ }
+
+ if (def == &default_external) {
+ enc_alias_internal(enc_table, "filesystem", Init_enc_set_filesystem_encoding());
+ }
+ }
+ GLOBAL_ENC_TABLE_LEAVE();
return overridden;
}
@@ -1463,9 +1685,11 @@ rb_enc_default_external(void)
* encoding may not be valid. Be sure to check String#valid_encoding?.
*
* File data written to disk will be transcoded to the default external
- * encoding when written.
+ * encoding when written, if default_internal is not nil.
*
- * The default external encoding is initialized by the locale or -E option.
+ * The default external encoding is initialized by the -E option.
+ * If -E isn't set, it is initialized to UTF-8 on Windows and the locale on
+ * other operating systems.
*/
static VALUE
get_default_external(VALUE klass)
@@ -1545,11 +1769,10 @@ rb_enc_default_internal(void)
* Additionally String#encode and String#encode! use the default internal
* encoding if no encoding is given.
*
- * The locale encoding (__ENCODING__), not default_internal, is used as the
+ * The script encoding (__ENCODING__), not default_internal, is used as the
* encoding of created strings.
*
- * Encoding::default_internal is initialized by the source file's
- * internal_encoding or -E option.
+ * Encoding::default_internal is initialized with -E option or nil otherwise.
*/
static VALUE
get_default_internal(VALUE klass)
@@ -1662,8 +1885,15 @@ rb_enc_name_list_i(st_data_t name, st_data_t idx, st_data_t arg)
static VALUE
rb_enc_name_list(VALUE klass)
{
- VALUE ary = rb_ary_new2(enc_table.names->num_entries);
- st_foreach(enc_table.names, rb_enc_name_list_i, (st_data_t)ary);
+ VALUE ary;
+
+ GLOBAL_ENC_TABLE_ENTER(enc_table);
+ {
+ ary = rb_ary_new2(enc_table->names->num_entries);
+ st_foreach(enc_table->names, rb_enc_name_list_i, (st_data_t)ary);
+ }
+ GLOBAL_ENC_TABLE_LEAVE();
+
return ary;
}
@@ -1685,8 +1915,7 @@ rb_enc_aliases_enc_i(st_data_t name, st_data_t orig, st_data_t arg)
str = rb_fstring_cstr(rb_enc_name(enc));
rb_ary_store(ary, idx, str);
}
- key = rb_usascii_str_new2((char *)name);
- OBJ_FREEZE(key);
+ key = rb_fstring_cstr((char *)name);
rb_hash_aset(aliases, key, str);
return ST_CONTINUE;
}
@@ -1698,8 +1927,8 @@ rb_enc_aliases_enc_i(st_data_t name, st_data_t orig, st_data_t arg)
* Returns the hash of available encoding alias and original encoding name.
*
* Encoding.aliases
- * #=> {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1986"=>"US-ASCII",
- * "SJIS"=>"Shift_JIS", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
+ * #=> {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1968"=>"US-ASCII",
+ * "SJIS"=>"Windows-31J", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
*
*/
@@ -1709,7 +1938,10 @@ rb_enc_aliases(VALUE klass)
VALUE aliases[2];
aliases[0] = rb_hash_new();
aliases[1] = rb_ary_new();
- st_foreach(enc_table.names, rb_enc_aliases_enc_i, (st_data_t)aliases);
+
+ GLOBAL_ENC_TABLE_EVAL(enc_table,
+ st_foreach(enc_table->names, rb_enc_aliases_enc_i, (st_data_t)aliases));
+
return aliases[0];
}
@@ -1739,11 +1971,11 @@ rb_enc_aliases(VALUE klass)
* "some string".encode "ISO-8859-1"
* #=> "some string"
*
- * <code>Encoding::ASCII_8BIT</code> is a special encoding that is usually
- * used for a byte string, not a character string. But as the name insists,
- * its characters in the range of ASCII are considered as ASCII characters.
- * This is useful when you use ASCII-8BIT characters with other ASCII
- * compatible characters.
+ * Encoding::ASCII_8BIT is a special encoding that is usually used for
+ * a byte string, not a character string. But as the name insists, its
+ * characters in the range of ASCII are considered as ASCII
+ * characters. This is useful when you use ASCII-8BIT characters with
+ * other ASCII compatible characters.
*
* == Changing an encoding
*
@@ -1781,11 +2013,12 @@ rb_enc_aliases(VALUE klass)
* All Ruby script code has an associated Encoding which any String literal
* created in the source code will be associated to.
*
- * The default script encoding is <code>Encoding::UTF-8</code> after v2.0, but it can
- * be changed by a magic comment on the first line of the source code file (or
- * second line, if there is a shebang line on the first). The comment must
- * contain the word <code>coding</code> or <code>encoding</code>, followed
- * by a colon, space and the Encoding name or alias:
+ * The default script encoding is Encoding::UTF_8 after v2.0, but it
+ * can be changed by a magic comment on the first line of the source
+ * code file (or second line, if there is a shebang line on the
+ * first). The comment must contain the word <code>coding</code> or
+ * <code>encoding</code>, followed by a colon, space and the Encoding
+ * name or alias:
*
* # encoding: UTF-8
*
@@ -1916,8 +2149,6 @@ rb_enc_aliases(VALUE klass)
void
Init_Encoding(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
VALUE list;
int i;
@@ -1930,7 +2161,7 @@ Init_Encoding(void)
rb_define_method(rb_cEncoding, "names", enc_names, 0);
rb_define_method(rb_cEncoding, "dummy?", enc_dummy_p, 0);
rb_define_method(rb_cEncoding, "ascii_compatible?", enc_ascii_compatible_p, 0);
- rb_define_method(rb_cEncoding, "replicate", enc_replicate, 1);
+ rb_define_method(rb_cEncoding, "replicate", enc_replicate_m, 1);
rb_define_singleton_method(rb_cEncoding, "list", enc_list, 0);
rb_define_singleton_method(rb_cEncoding, "name_list", rb_enc_name_list, 0);
rb_define_singleton_method(rb_cEncoding, "aliases", rb_enc_aliases, 0);
@@ -1946,16 +2177,29 @@ Init_Encoding(void)
rb_define_singleton_method(rb_cEncoding, "default_internal=", set_default_internal, 1);
rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0); /* in localeinit.c */
- list = rb_ary_new2(enc_table.count);
+ struct enc_table *enc_table = &global_enc_table;
+
+ if (DEFAULT_ENCODING_LIST_CAPA < enc_table->count) rb_bug("DEFAULT_ENCODING_LIST_CAPA is too small");
+
+ list = rb_additional_encoding_list = rb_ary_new();
+ RBASIC_CLEAR_CLASS(list);
+ rb_gc_register_mark_object(list);
+
+ list = rb_default_encoding_list = rb_ary_new2(DEFAULT_ENCODING_LIST_CAPA);
RBASIC_CLEAR_CLASS(list);
- rb_encoding_list = list;
rb_gc_register_mark_object(list);
- for (i = 0; i < enc_table.count; ++i) {
- rb_ary_push(list, enc_new(enc_table.list[i].enc));
+ for (i = 0; i < enc_table->count; ++i) {
+ rb_ary_push(list, enc_new(enc_table->list[i].enc));
}
- rb_marshal_define_compat(rb_cEncoding, Qnil, NULL, enc_m_loader);
+ rb_marshal_define_compat(rb_cEncoding, Qnil, 0, enc_m_loader);
+}
+
+void
+Init_encodings(void)
+{
+ rb_enc_init(&global_enc_table);
}
/* locale insensitive ctype functions */
@@ -1963,5 +2207,5 @@ Init_Encoding(void)
void
rb_enc_foreach_name(int (*func)(st_data_t name, st_data_t idx, st_data_t arg), st_data_t arg)
{
- st_foreach(enc_table.names, func, arg);
+ GLOBAL_ENC_TABLE_EVAL(enc_table, st_foreach(enc_table->names, func, arg));
}
diff --git a/enum.c b/enum.c
index 4613ab733c..b1a617d585 100644
--- a/enum.c
+++ b/enum.c
@@ -9,18 +9,26 @@
**********************************************************************/
+#include "id.h"
#include "internal.h"
+#include "internal/compar.h"
+#include "internal/enum.h"
+#include "internal/hash.h"
+#include "internal/imemo.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/proc.h"
+#include "internal/rational.h"
+#include "internal/re.h"
#include "ruby/util.h"
-#include "id.h"
+#include "ruby_assert.h"
#include "symbol.h"
-#include <assert.h>
-
VALUE rb_mEnumerable;
static ID id_next;
-static ID id_div;
+#define id_div idDiv
#define id_each idEach
#define id_eqq idEqq
#define id_cmp idCmp
@@ -75,6 +83,22 @@ grep_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
}
static VALUE
+grep_regexp_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
+{
+ struct MEMO *memo = MEMO_CAST(args);
+ VALUE converted_element, match;
+ ENUM_WANT_SVALUE();
+
+ /* In case element can't be converted to a Symbol or String: not a match (don't raise) */
+ converted_element = SYMBOL_P(i) ? i : rb_check_string_type(i);
+ match = NIL_P(converted_element) ? Qfalse : rb_reg_match_p(memo->v1, i, 0);
+ if (match == memo->u3.value) {
+ rb_ary_push(memo->v2, i);
+ }
+ return Qnil;
+}
+
+static VALUE
grep_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
{
struct MEMO *memo = MEMO_CAST(args);
@@ -86,6 +110,27 @@ grep_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
return Qnil;
}
+static VALUE
+enum_grep0(VALUE obj, VALUE pat, VALUE test)
+{
+ VALUE ary = rb_ary_new();
+ struct MEMO *memo = MEMO_NEW(pat, ary, test);
+ rb_block_call_func_t fn;
+ if (rb_block_given_p()) {
+ fn = grep_iter_i;
+ }
+ else if (RB_TYPE_P(pat, T_REGEXP) &&
+ LIKELY(rb_method_basic_definition_p(CLASS_OF(pat), idEqq))) {
+ fn = grep_regexp_i;
+ }
+ else {
+ fn = grep_i;
+ }
+ rb_block_call(obj, id_each, 0, 0, fn, (VALUE)memo);
+
+ return ary;
+}
+
/*
* call-seq:
* enum.grep(pattern) -> array
@@ -107,12 +152,7 @@ grep_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
static VALUE
enum_grep(VALUE obj, VALUE pat)
{
- VALUE ary = rb_ary_new();
- struct MEMO *memo = MEMO_NEW(pat, ary, Qtrue);
-
- rb_block_call(obj, id_each, 0, 0, rb_block_given_p() ? grep_iter_i : grep_i, (VALUE)memo);
-
- return ary;
+ return enum_grep0(obj, pat, Qtrue);
}
/*
@@ -133,12 +173,35 @@ enum_grep(VALUE obj, VALUE pat)
static VALUE
enum_grep_v(VALUE obj, VALUE pat)
{
- VALUE ary = rb_ary_new();
- struct MEMO *memo = MEMO_NEW(pat, ary, Qfalse);
+ return enum_grep0(obj, pat, Qfalse);
+}
- rb_block_call(obj, id_each, 0, 0, rb_block_given_p() ? grep_iter_i : grep_i, (VALUE)memo);
+#define COUNT_BIGNUM IMEMO_FL_USER0
+#define MEMO_V3_SET(m, v) RB_OBJ_WRITE((m), &(m)->u3.value, (v))
- return ary;
+static void
+imemo_count_up(struct MEMO *memo)
+{
+ if (memo->flags & COUNT_BIGNUM) {
+ MEMO_V3_SET(memo, rb_int_succ(memo->u3.value));
+ }
+ else if (++memo->u3.cnt == 0) {
+ /* overflow */
+ unsigned long buf[2] = {0, 1};
+ MEMO_V3_SET(memo, rb_big_unpack(buf, 2));
+ memo->flags |= COUNT_BIGNUM;
+ }
+}
+
+static VALUE
+imemo_count_value(struct MEMO *memo)
+{
+ if (memo->flags & COUNT_BIGNUM) {
+ return memo->u3.value;
+ }
+ else {
+ return ULONG2NUM(memo->u3.cnt);
+ }
}
static VALUE
@@ -149,7 +212,7 @@ count_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
ENUM_WANT_SVALUE();
if (rb_equal(i, memo->v1)) {
- memo->u3.cnt++;
+ imemo_count_up(memo);
}
return Qnil;
}
@@ -160,7 +223,7 @@ count_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
struct MEMO *memo = MEMO_CAST(memop);
if (RTEST(rb_yield_values2(argc, argv))) {
- memo->u3.cnt++;
+ imemo_count_up(memo);
}
return Qnil;
}
@@ -170,7 +233,7 @@ count_all_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
{
struct MEMO *memo = MEMO_CAST(memop);
- memo->u3.cnt++;
+ imemo_count_up(memo);
return Qnil;
}
@@ -217,7 +280,7 @@ enum_count(int argc, VALUE *argv, VALUE obj)
memo = MEMO_NEW(item, 0, 0);
rb_block_call(obj, id_each, 0, 0, func, (VALUE)memo);
- return INT2NUM(memo->u3.cnt);
+ return imemo_count_value(memo);
}
static VALUE
@@ -248,13 +311,15 @@ find_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
*
* If no block is given, an enumerator is returned instead.
*
- * (1..100).detect => #<Enumerator: 1..100:detect>
- * (1..100).find => #<Enumerator: 1..100:find>
+ * (1..100).detect #=> #<Enumerator: 1..100:detect>
+ * (1..100).find #=> #<Enumerator: 1..100:find>
*
- * (1..10).detect { |i| i % 5 == 0 and i % 7 == 0 } #=> nil
- * (1..10).find { |i| i % 5 == 0 and i % 7 == 0 } #=> nil
- * (1..100).detect { |i| i % 5 == 0 and i % 7 == 0 } #=> 35
- * (1..100).find { |i| i % 5 == 0 and i % 7 == 0 } #=> 35
+ * (1..10).detect { |i| i % 5 == 0 && i % 7 == 0 } #=> nil
+ * (1..10).find { |i| i % 5 == 0 && i % 7 == 0 } #=> nil
+ * (1..10).detect(-> {0}) { |i| i % 5 == 0 && i % 7 == 0 } #=> 0
+ * (1..10).find(-> {0}) { |i| i % 5 == 0 && i % 7 == 0 } #=> 0
+ * (1..100).detect { |i| i % 5 == 0 && i % 7 == 0 } #=> 35
+ * (1..100).find { |i| i % 5 == 0 && i % 7 == 0 } #=> 35
*
*/
@@ -264,7 +329,7 @@ enum_find(int argc, VALUE *argv, VALUE obj)
struct MEMO *memo;
VALUE if_none;
- rb_scan_args(argc, argv, "01", &if_none);
+ if_none = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
RETURN_ENUMERATOR(obj, argc, argv);
memo = MEMO_NEW(Qundef, 0, 0);
rb_block_call(obj, id_each, 0, 0, find_i, (VALUE)memo);
@@ -285,10 +350,10 @@ find_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
ENUM_WANT_SVALUE();
if (rb_equal(i, memo->v2)) {
- MEMO_V1_SET(memo, UINT2NUM(memo->u3.cnt));
+ MEMO_V1_SET(memo, imemo_count_value(memo));
rb_iter_break();
}
- memo->u3.cnt++;
+ imemo_count_up(memo);
return Qnil;
}
@@ -298,10 +363,10 @@ find_index_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
struct MEMO *memo = MEMO_CAST(memop);
if (RTEST(rb_yield_values2(argc, argv))) {
- MEMO_V1_SET(memo, UINT2NUM(memo->u3.cnt));
+ MEMO_V1_SET(memo, imemo_count_value(memo));
rb_iter_break();
}
- memo->u3.cnt++;
+ imemo_count_up(memo);
return Qnil;
}
@@ -318,9 +383,9 @@ find_index_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
*
* If neither block nor argument is given, an enumerator is returned instead.
*
- * (1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> nil
- * (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> 34
- * (1..100).find_index(50) #=> 49
+ * (1..10).find_index { |i| i % 5 == 0 && i % 7 == 0 } #=> nil
+ * (1..100).find_index { |i| i % 5 == 0 && i % 7 == 0 } #=> 34
+ * (1..100).find_index(50) #=> 49
*
*/
@@ -387,12 +452,17 @@ enum_size_over_p(VALUE obj, long n)
* call-seq:
* enum.find_all { |obj| block } -> array
* enum.select { |obj| block } -> array
+ * enum.filter { |obj| block } -> array
* enum.find_all -> an_enumerator
* enum.select -> an_enumerator
+ * enum.filter -> an_enumerator
*
* Returns an array containing all elements of +enum+
* for which the given +block+ returns a true value.
*
+ * The <i>find_all</i> and <i>select</i> methods are aliases.
+ * There is no performance benefit to either.
+ *
* If no block is given, an Enumerator is returned instead.
*
*
@@ -400,7 +470,9 @@ enum_size_over_p(VALUE obj, long n)
*
* [1,2,3,4,5].select { |num| num.even? } #=> [2, 4]
*
- * See also Enumerable#reject.
+ * [:foo, :bar].filter { |x| x == :foo } #=> [:foo]
+ *
+ * See also Enumerable#reject, Enumerable#grep.
*/
static VALUE
@@ -417,6 +489,46 @@ enum_find_all(VALUE obj)
}
static VALUE
+filter_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
+{
+ i = rb_yield_values2(argc, argv);
+
+ if (RTEST(i)) {
+ rb_ary_push(ary, i);
+ }
+
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.filter_map { |obj| block } -> array
+ * enum.filter_map -> an_enumerator
+ *
+ * Returns a new array containing the truthy results (everything except
+ * +false+ or +nil+) of running the +block+ for every element in +enum+.
+ *
+ * If no block is given, an Enumerator is returned instead.
+ *
+ *
+ * (1..10).filter_map { |i| i * 2 if i.even? } #=> [4, 8, 12, 16, 20]
+ *
+ */
+static VALUE
+enum_filter_map(VALUE obj)
+{
+ VALUE ary;
+
+ RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size);
+
+ ary = rb_ary_new();
+ rb_block_call(obj, id_each, 0, 0, filter_map_i, ary);
+
+ return ary;
+}
+
+
+static VALUE
reject_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
{
ENUM_WANT_SVALUE();
@@ -468,7 +580,6 @@ collect_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
static VALUE
collect_all(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
{
- rb_thread_check_ints();
rb_ary_push(ary, rb_enum_values_pack(argc, argv));
return Qnil;
@@ -571,49 +682,55 @@ enum_to_a(int argc, VALUE *argv, VALUE obj)
{
VALUE ary = rb_ary_new();
- rb_block_call(obj, id_each, argc, argv, collect_all, ary);
- OBJ_INFECT(ary, obj);
+ rb_block_call_kw(obj, id_each, argc, argv, collect_all, ary, RB_PASS_CALLED_KEYWORDS);
return ary;
}
static VALUE
+enum_hashify(VALUE obj, int argc, const VALUE *argv, rb_block_call_func *iter)
+{
+ VALUE hash = rb_hash_new();
+ rb_block_call(obj, id_each, argc, argv, iter, hash);
+ return hash;
+}
+
+static VALUE
enum_to_h_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
{
- VALUE key_value_pair;
ENUM_WANT_SVALUE();
- rb_thread_check_ints();
- key_value_pair = rb_check_array_type(i);
- if (NIL_P(key_value_pair)) {
- rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
- rb_builtin_class_name(i));
- }
- if (RARRAY_LEN(key_value_pair) != 2) {
- rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
- RARRAY_LEN(key_value_pair));
- }
- rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
- return Qnil;
+ return rb_hash_set_pair(hash, i);
+}
+
+static VALUE
+enum_to_h_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+{
+ return rb_hash_set_pair(hash, rb_yield_values2(argc, argv));
}
/*
* call-seq:
- * enum.to_h(*args) -> hash
+ * enum.to_h(*args) -> hash
+ * enum.to_h(*args) {...} -> hash
*
* Returns the result of interpreting <i>enum</i> as a list of
* <tt>[key, value]</tt> pairs.
*
* %i[hello world].each_with_index.to_h
* # => {:hello => 0, :world => 1}
+ *
+ * If a block is given, the results of the block on each element of
+ * the enum will be used as pairs.
+ *
+ * (1..5).to_h {|x| [x, x ** 2]}
+ * #=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
*/
static VALUE
enum_to_h(int argc, VALUE *argv, VALUE obj)
{
- VALUE hash = rb_hash_new();
- rb_block_call(obj, id_each, argc, argv, enum_to_h_i, hash);
- OBJ_INFECT(hash, obj);
- return hash;
+ rb_block_call_func *iter = rb_block_given_p() ? enum_to_h_ii : enum_to_h_i;
+ return enum_hashify(obj, argc, argv, iter);
}
static VALUE
@@ -645,7 +762,7 @@ inject_op_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, p))
}
else if (SYMBOL_P(name = memo->u3.value)) {
const ID mid = SYM2ID(name);
- MEMO_V1_SET(memo, rb_funcallv(memo->v1, mid, 1, &i));
+ MEMO_V1_SET(memo, rb_funcallv_public(memo->v1, mid, 1, &i));
}
else {
VALUE args[2];
@@ -707,7 +824,8 @@ ary_inject_op(VALUE ary, VALUE init, VALUE op)
}
}
for (; i < RARRAY_LEN(ary); i++) {
- v = rb_funcallv_public(v, id, 1, &RARRAY_CONST_PTR(ary)[i]);
+ VALUE arg = RARRAY_AREF(ary, i);
+ v = rb_funcallv_public(v, id, 1, &arg);
}
return v;
}
@@ -885,17 +1003,53 @@ group_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
static VALUE
enum_group_by(VALUE obj)
{
- VALUE hash;
-
RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size);
- hash = rb_hash_new();
- rb_block_call(obj, id_each, 0, 0, group_by_i, hash);
- OBJ_INFECT(hash, obj);
+ return enum_hashify(obj, 0, 0, group_by_i);
+}
- return hash;
+static void
+tally_up(VALUE hash, VALUE group)
+{
+ VALUE tally = rb_hash_aref(hash, group);
+ if (NIL_P(tally)) {
+ tally = INT2FIX(1);
+ }
+ else if (FIXNUM_P(tally) && tally < INT2FIX(FIXNUM_MAX)) {
+ tally += INT2FIX(1) & ~FIXNUM_FLAG;
+ }
+ else {
+ tally = rb_big_plus(tally, INT2FIX(1));
+ }
+ rb_hash_aset(hash, group, tally);
+}
+
+static VALUE
+tally_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+{
+ ENUM_WANT_SVALUE();
+ tally_up(hash, i);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.tally -> a_hash
+ *
+ * Tallies the collection, i.e., counts the occurrences of each element.
+ * Returns a hash with the elements of the collection as keys and the
+ * corresponding counts as values.
+ *
+ * ["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
+ */
+
+static VALUE
+enum_tally(VALUE obj)
+{
+ return enum_hashify(obj, 0, 0, tally_i);
}
+NORETURN(static VALUE first_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, params)));
static VALUE
first_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, params))
{
@@ -905,7 +1059,7 @@ first_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, params))
MEMO_V1_SET(memo, i);
rb_iter_break();
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
static VALUE enum_take(VALUE obj, VALUE n);
@@ -1042,10 +1196,10 @@ sort_by_cmp(const void *ap, const void *bp, void *data)
* %w{apple pear fig}.sort_by { |word| word.length }
* #=> ["fig", "pear", "apple"]
*
- * The current implementation of <code>sort_by</code> generates an
- * array of tuples containing the original collection element and the
- * mapped value. This makes <code>sort_by</code> fairly expensive when
- * the keysets are simple.
+ * The current implementation of #sort_by generates an array of
+ * tuples containing the original collection element and the mapped
+ * value. This makes #sort_by fairly expensive when the keysets are
+ * simple.
*
* require 'benchmark'
*
@@ -1064,15 +1218,15 @@ sort_by_cmp(const void *ap, const void *bp, void *data)
*
* However, consider the case where comparing the keys is a non-trivial
* operation. The following code sorts some files on modification time
- * using the basic <code>sort</code> method.
+ * using the basic #sort method.
*
* files = Dir["*"]
* sorted = files.sort { |a, b| File.new(a).mtime <=> File.new(b).mtime }
* sorted #=> ["mon", "tues", "wed", "thurs"]
*
- * This sort is inefficient: it generates two new <code>File</code>
+ * This sort is inefficient: it generates two new File
* objects during every comparison. A slightly better technique is to
- * use the <code>Kernel#test</code> method to generate the modification
+ * use the Kernel#test method to generate the modification
* times directly.
*
* files = Dir["*"]
@@ -1081,23 +1235,27 @@ sort_by_cmp(const void *ap, const void *bp, void *data)
* }
* sorted #=> ["mon", "tues", "wed", "thurs"]
*
- * This still generates many unnecessary <code>Time</code> objects. A
- * more efficient technique is to cache the sort keys (modification
- * times in this case) before the sort. Perl users often call this
- * approach a Schwartzian transform, after Randal Schwartz. We
- * construct a temporary array, where each element is an array
- * containing our sort key along with the filename. We sort this array,
- * and then extract the filename from the result.
+ * This still generates many unnecessary Time objects. A more
+ * efficient technique is to cache the sort keys (modification times
+ * in this case) before the sort. Perl users often call this approach
+ * a Schwartzian transform, after Randal Schwartz. We construct a
+ * temporary array, where each element is an array containing our
+ * sort key along with the filename. We sort this array, and then
+ * extract the filename from the result.
*
* sorted = Dir["*"].collect { |f|
* [test(?M, f), f]
* }.sort.collect { |f| f[1] }
* sorted #=> ["mon", "tues", "wed", "thurs"]
*
- * This is exactly what <code>sort_by</code> does internally.
+ * This is exactly what #sort_by does internally.
*
* sorted = Dir["*"].sort_by { |f| test(?M, f) }
* sorted #=> ["mon", "tues", "wed", "thurs"]
+ *
+ * To produce the reverse of a specific order, the following can be used:
+ *
+ * ary.sort_by { ... }.reverse!
*/
static VALUE
@@ -1120,7 +1278,6 @@ enum_sort_by(VALUE obj)
buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2);
rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil);
memo = MEMO_NEW(0, 0, 0);
- OBJ_INFECT(memo, obj);
data = (struct sort_by_data *)&memo->v1;
RB_OBJ_WRITE(memo, &data->ary, ary);
RB_OBJ_WRITE(memo, &data->buf, buf);
@@ -1133,9 +1290,9 @@ enum_sort_by(VALUE obj)
rb_ary_concat(ary, buf);
}
if (RARRAY_LEN(ary) > 2) {
- RARRAY_PTR_USE(ary, ptr,
- ruby_qsort(ptr, RARRAY_LEN(ary)/2, 2*sizeof(VALUE),
- sort_by_cmp, (void *)ary));
+ RARRAY_PTR_USE(ary, ptr,
+ ruby_qsort(ptr, RARRAY_LEN(ary)/2, 2*sizeof(VALUE),
+ sort_by_cmp, (void *)ary));
}
if (RBASIC(ary)->klass) {
rb_raise(rb_eRuntimeError, "sort_by reentered");
@@ -1145,12 +1302,13 @@ enum_sort_by(VALUE obj)
}
rb_ary_resize(ary, RARRAY_LEN(ary)/2);
RBASIC_SET_CLASS_RAW(ary, rb_cArray);
- OBJ_INFECT(ary, memo);
return ary;
}
-#define ENUMFUNC(name) rb_block_given_p() ? name##_iter_i : name##_i
+#define ENUMFUNC(name) argc ? name##_eqq : rb_block_given_p() ? name##_iter_i : name##_i
+
+#define MEMO_ENUM_NEW(v1) (rb_check_arity(argc, 0, 1), MEMO_NEW((v1), (argc ? *argv : 0), 0))
#define DEFINE_ENUMFUNCS(name) \
static VALUE enum_##name##_func(VALUE result, struct MEMO *memo); \
@@ -1168,8 +1326,21 @@ name##_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) \
} \
\
static VALUE \
+name##_eqq(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) \
+{ \
+ ENUM_WANT_SVALUE(); \
+ return enum_##name##_func(rb_funcallv(MEMO_CAST(memo)->v2, id_eqq, 1, &i), MEMO_CAST(memo)); \
+} \
+\
+static VALUE \
enum_##name##_func(VALUE result, struct MEMO *memo)
+#define WARN_UNUSED_BLOCK(argc) do { \
+ if ((argc) > 0 && rb_block_given_p()) { \
+ rb_warn("given block not used"); \
+ } \
+} while (0)
+
DEFINE_ENUMFUNCS(all)
{
if (!RTEST(result)) {
@@ -1182,6 +1353,7 @@ DEFINE_ENUMFUNCS(all)
/*
* call-seq:
* enum.all? [{ |obj| block } ] -> true or false
+ * enum.all?(pattern) -> true or false
*
* Passes each element of the collection to the given block. The method
* returns <code>true</code> if the block never returns
@@ -1190,17 +1362,23 @@ DEFINE_ENUMFUNCS(all)
* cause #all? to return +true+ when none of the collection members are
* +false+ or +nil+.
*
+ * If instead a pattern is supplied, the method returns whether
+ * <code>pattern === element</code> for every collection member.
+ *
* %w[ant bear cat].all? { |word| word.length >= 3 } #=> true
* %w[ant bear cat].all? { |word| word.length >= 4 } #=> false
+ * %w[ant bear cat].all?(/t/) #=> false
+ * [1, 2i, 3.14].all?(Numeric) #=> true
* [nil, true, 99].all? #=> false
* [].all? #=> true
*
*/
static VALUE
-enum_all(VALUE obj)
+enum_all(int argc, VALUE *argv, VALUE obj)
{
- struct MEMO *memo = MEMO_NEW(Qtrue, 0, 0);
+ struct MEMO *memo = MEMO_ENUM_NEW(Qtrue);
+ WARN_UNUSED_BLOCK(argc);
rb_block_call(obj, id_each, 0, 0, ENUMFUNC(all), (VALUE)memo);
return memo->v1;
}
@@ -1217,6 +1395,7 @@ DEFINE_ENUMFUNCS(any)
/*
* call-seq:
* enum.any? [{ |obj| block }] -> true or false
+ * enum.any?(pattern) -> true or false
*
* Passes each element of the collection to the given block. The method
* returns <code>true</code> if the block ever returns a value other
@@ -1225,17 +1404,23 @@ DEFINE_ENUMFUNCS(any)
* will cause #any? to return +true+ if at least one of the collection
* members is not +false+ or +nil+.
*
+ * If instead a pattern is supplied, the method returns whether
+ * <code>pattern === element</code> for any collection member.
+ *
* %w[ant bear cat].any? { |word| word.length >= 3 } #=> true
* %w[ant bear cat].any? { |word| word.length >= 4 } #=> true
+ * %w[ant bear cat].any?(/d/) #=> false
+ * [nil, true, 99].any?(Integer) #=> true
* [nil, true, 99].any? #=> true
* [].any? #=> false
*
*/
static VALUE
-enum_any(VALUE obj)
+enum_any(int argc, VALUE *argv, VALUE obj)
{
- struct MEMO *memo = MEMO_NEW(Qfalse, 0, 0);
+ struct MEMO *memo = MEMO_ENUM_NEW(Qfalse);
+ WARN_UNUSED_BLOCK(argc);
rb_block_call(obj, id_each, 0, 0, ENUMFUNC(any), (VALUE)memo);
return memo->v1;
}
@@ -1255,22 +1440,23 @@ DEFINE_ENUMFUNCS(one)
}
struct nmin_data {
- long n;
- long bufmax;
- long curlen;
- VALUE buf;
- VALUE limit;
- int (*cmpfunc)(const void *, const void *, void *);
- int rev; /* max if 1 */
- int by; /* min_by if 1 */
- const char *method;
+ long n;
+ long bufmax;
+ long curlen;
+ VALUE buf;
+ VALUE limit;
+ int (*cmpfunc)(const void *, const void *, void *);
+ int rev: 1; /* max if 1 */
+ int by: 1; /* min_by if 1 */
};
static VALUE
cmpint_reenter_check(struct nmin_data *data, VALUE val)
{
if (RBASIC(data->buf)->klass) {
- rb_raise(rb_eRuntimeError, "%s reentered", data->method);
+ rb_raise(rb_eRuntimeError, "%s%s reentered",
+ data->rev ? "max" : "min",
+ data->by ? "_by" : "");
}
return val;
}
@@ -1374,13 +1560,13 @@ nmin_filter(struct nmin_data *data)
#undef GETPTR
#undef SWAP
- data->limit = RARRAY_PTR(data->buf)[store_index*eltsize]; /* the last pivot */
+ data->limit = RARRAY_AREF(data->buf, store_index*eltsize); /* the last pivot */
data->curlen = data->n;
rb_ary_resize(data->buf, data->n * eltsize);
}
static VALUE
-nmin_i(VALUE i, VALUE *_data, int argc, VALUE *argv)
+nmin_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, _data))
{
struct nmin_data *data = (struct nmin_data *)_data;
VALUE cmpv;
@@ -1435,14 +1621,12 @@ rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary)
nmin_cmp;
data.rev = rev;
data.by = by;
- data.method = rev ? (by ? "max_by" : "max")
- : (by ? "min_by" : "min");
if (ary) {
long i;
for (i = 0; i < RARRAY_LEN(obj); i++) {
VALUE args[1];
args[0] = RARRAY_AREF(obj, i);
- nmin_i(obj, (VALUE*)&data, 1, args);
+ nmin_i(obj, (VALUE)&data, 1, args, Qundef);
}
}
else {
@@ -1452,18 +1636,22 @@ rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary)
result = data.buf;
if (by) {
long i;
- ruby_qsort(RARRAY_PTR(result),
- RARRAY_LEN(result)/2,
- sizeof(VALUE)*2,
- data.cmpfunc, (void *)&data);
- for (i=1; i<RARRAY_LEN(result); i+=2) {
- RARRAY_PTR(result)[i/2] = RARRAY_PTR(result)[i];
- }
+ RARRAY_PTR_USE(result, ptr, {
+ ruby_qsort(ptr,
+ RARRAY_LEN(result)/2,
+ sizeof(VALUE)*2,
+ data.cmpfunc, (void *)&data);
+ for (i=1; i<RARRAY_LEN(result); i+=2) {
+ ptr[i/2] = ptr[i];
+ }
+ });
rb_ary_resize(result, RARRAY_LEN(result)/2);
}
else {
- ruby_qsort(RARRAY_PTR(result), RARRAY_LEN(result), sizeof(VALUE),
- data.cmpfunc, (void *)&data);
+ RARRAY_PTR_USE(result, ptr, {
+ ruby_qsort(ptr, RARRAY_LEN(result), sizeof(VALUE),
+ data.cmpfunc, (void *)&data);
+ });
}
if (rev) {
rb_ary_reverse(result);
@@ -1476,6 +1664,7 @@ rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary)
/*
* call-seq:
* enum.one? [{ |obj| block }] -> true or false
+ * enum.one?(pattern) -> true or false
*
* Passes each element of the collection to the given block. The method
* returns <code>true</code> if the block returns <code>true</code>
@@ -1483,19 +1672,26 @@ rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary)
* <code>true</code> only if exactly one of the collection members is
* true.
*
+ * If instead a pattern is supplied, the method returns whether
+ * <code>pattern === element</code> for exactly one collection member.
+ *
* %w{ant bear cat}.one? { |word| word.length == 4 } #=> true
* %w{ant bear cat}.one? { |word| word.length > 4 } #=> false
* %w{ant bear cat}.one? { |word| word.length < 4 } #=> false
+ * %w{ant bear cat}.one?(/t/) #=> false
* [ nil, true, 99 ].one? #=> false
* [ nil, true, false ].one? #=> true
+ * [ nil, true, 99 ].one?(Integer) #=> true
+ * [].one? #=> false
*
*/
static VALUE
-enum_one(VALUE obj)
+enum_one(int argc, VALUE *argv, VALUE obj)
{
- struct MEMO *memo = MEMO_NEW(Qundef, 0, 0);
+ struct MEMO *memo = MEMO_ENUM_NEW(Qundef);
VALUE result;
+ WARN_UNUSED_BLOCK(argc);
rb_block_call(obj, id_each, 0, 0, ENUMFUNC(one), (VALUE)memo);
result = memo->v1;
if (result == Qundef) return Qfalse;
@@ -1514,23 +1710,31 @@ DEFINE_ENUMFUNCS(none)
/*
* call-seq:
* enum.none? [{ |obj| block }] -> true or false
+ * enum.none?(pattern) -> true or false
*
* Passes each element of the collection to the given block. The method
* returns <code>true</code> if the block never returns <code>true</code>
* for all elements. If the block is not given, <code>none?</code> will return
* <code>true</code> only if none of the collection members is true.
*
+ * If instead a pattern is supplied, the method returns whether
+ * <code>pattern === element</code> for none of the collection members.
+ *
* %w{ant bear cat}.none? { |word| word.length == 5 } #=> true
* %w{ant bear cat}.none? { |word| word.length >= 4 } #=> false
+ * %w{ant bear cat}.none?(/d/) #=> true
+ * [1, 3.14, 42].none?(Float) #=> false
* [].none? #=> true
* [nil].none? #=> true
* [nil, false].none? #=> true
* [nil, false, true].none? #=> false
*/
static VALUE
-enum_none(VALUE obj)
+enum_none(int argc, VALUE *argv, VALUE obj)
{
- struct MEMO *memo = MEMO_NEW(Qtrue, 0, 0);
+ struct MEMO *memo = MEMO_ENUM_NEW(Qtrue);
+
+ WARN_UNUSED_BLOCK(argc);
rb_block_call(obj, id_each, 0, 0, ENUMFUNC(none), (VALUE)memo);
return memo->v1;
}
@@ -1587,7 +1791,7 @@ min_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
* enum.min(n) { |a, b| block } -> array
*
* Returns the object in _enum_ with the minimum value. The
- * first form assumes all objects implement <code>Comparable</code>;
+ * first form assumes all objects implement <code><=></code>;
* the second uses the block to return <em>a <=> b</em>.
*
* a = %w(albatross dog horse)
@@ -1611,9 +1815,7 @@ enum_min(int argc, VALUE *argv, VALUE obj)
VALUE result;
VALUE num;
- rb_scan_args(argc, argv, "01", &num);
-
- if (!NIL_P(num))
+ if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(obj, num, 0, 0, 0);
m->min = Qundef;
@@ -1681,7 +1883,7 @@ max_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
* enum.max(n) { |a, b| block } -> array
*
* Returns the object in _enum_ with the maximum value. The
- * first form assumes all objects implement <code>Comparable</code>;
+ * first form assumes all objects implement <code><=></code>;
* the second uses the block to return <em>a <=> b</em>.
*
* a = %w(albatross dog horse)
@@ -1705,9 +1907,7 @@ enum_max(int argc, VALUE *argv, VALUE obj)
VALUE result;
VALUE num;
- rb_scan_args(argc, argv, "01", &num);
-
- if (!NIL_P(num))
+ if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(obj, num, 0, 1, 0);
m->max = Qundef;
@@ -1842,7 +2042,7 @@ minmax_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, _memo))
*
* Returns a two element array which contains the minimum and the
* maximum value in the enumerable. The first form assumes all
- * objects implement <code>Comparable</code>; the second uses the
+ * objects implement <code><=></code>; the second uses the
* block to return <em>a <=> b</em>.
*
* a = %w(albatross dog horse)
@@ -1926,11 +2126,11 @@ enum_min_by(int argc, VALUE *argv, VALUE obj)
struct MEMO *memo;
VALUE num;
- rb_scan_args(argc, argv, "01", &num);
+ rb_check_arity(argc, 0, 1);
RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size);
- if (!NIL_P(num))
+ if (argc && !NIL_P(num = argv[0]))
return rb_nmin_run(obj, num, 1, 0, 0);
memo = MEMO_NEW(Qundef, Qnil, 0);
@@ -2033,11 +2233,11 @@ enum_max_by(int argc, VALUE *argv, VALUE obj)
struct MEMO *memo;
VALUE num;
- rb_scan_args(argc, argv, "01", &num);
+ rb_check_arity(argc, 0, 1);
RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size);
- if (!NIL_P(num))
+ if (argc && !NIL_P(num = argv[0]))
return rb_nmin_run(obj, num, 1, 1, 0);
memo = MEMO_NEW(Qundef, Qnil, 0);
@@ -2174,10 +2374,10 @@ member_i(RB_BLOCK_CALL_FUNC_ARGLIST(iter, args))
* Returns <code>true</code> if any member of <i>enum</i> equals
* <i>obj</i>. Equality is tested using <code>==</code>.
*
- * IO.constants.include? :SEEK_SET #=> true
- * IO.constants.include? :SEEK_NO_FURTHER #=> false
- * IO.constants.member? :SEEK_SET #=> true
- * IO.constants.member? :SEEK_NO_FURTHER #=> false
+ * (1..10).include? 5 #=> true
+ * (1..10).include? 15 #=> false
+ * (1..10).member? 5 #=> true
+ * (1..10).member? 15 #=> false
*
*/
@@ -2193,9 +2393,11 @@ enum_member(VALUE obj, VALUE val)
static VALUE
each_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo))
{
- long n = MEMO_CAST(memo)->u3.cnt++;
+ struct MEMO *m = MEMO_CAST(memo);
+ VALUE n = imemo_count_value(m);
- return rb_yield_values(2, rb_enum_values_pack(argc, argv), INT2NUM(n));
+ imemo_count_up(m);
+ return rb_yield_values(2, rb_enum_values_pack(argc, argv), n);
}
/*
@@ -2239,27 +2441,33 @@ enum_each_with_index(int argc, VALUE *argv, VALUE obj)
*
* If no block is given, an enumerator is returned instead.
*
- * (1..3).reverse_each { |v| p v }
+ * (1..3).reverse_each { |v| p v }
*
- * produces:
+ * produces:
*
- * 3
- * 2
- * 1
+ * 3
+ * 2
+ * 1
*/
static VALUE
enum_reverse_each(int argc, VALUE *argv, VALUE obj)
{
VALUE ary;
- long i;
+ long len;
RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size);
ary = enum_to_a(argc, argv, obj);
- for (i = RARRAY_LEN(ary); --i >= 0; ) {
- rb_yield(RARRAY_AREF(ary, i));
+ len = RARRAY_LEN(ary);
+ while (len--) {
+ long nlen;
+ rb_yield(RARRAY_AREF(ary, len));
+ nlen = RARRAY_LEN(ary);
+ if (nlen < len) {
+ len = nlen;
+ }
}
return obj;
@@ -2359,10 +2567,15 @@ enum_each_slice_size(VALUE obj, VALUE args, VALUE eobj)
{
VALUE n, size;
long slice_size = NUM2LONG(RARRAY_AREF(args, 0));
+ ID infinite_p;
+ CONST_ID(infinite_p, "infinite?");
if (slice_size <= 0) rb_raise(rb_eArgError, "invalid slice size");
size = enum_size(obj, 0, 0);
if (size == Qnil) return Qnil;
+ if (RB_FLOAT_TYPE_P(size) && RTEST(rb_funcall(size, infinite_p, 0))) {
+ return size;
+ }
n = add_int(size, slice_size-1);
return div_int(n, slice_size);
@@ -2547,14 +2760,16 @@ zip_ary(RB_BLOCK_CALL_FUNC_ARGLIST(val, memoval))
}
static VALUE
-call_next(VALUE *v)
+call_next(VALUE w)
{
+ VALUE *v = (VALUE *)w;
return v[0] = rb_funcallv(v[1], id_next, 0, 0);
}
static VALUE
-call_stop(VALUE *v)
+call_stop(VALUE w, VALUE _)
{
+ VALUE *v = (VALUE *)w;
return v[0] = Qundef;
}
@@ -2840,17 +3055,19 @@ cycle_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
static VALUE
enum_cycle_size(VALUE self, VALUE args, VALUE eobj)
{
- long mul;
+ long mul = 0;
VALUE n = Qnil;
- VALUE size = enum_size(self, args, 0);
-
- if (size == Qnil) return Qnil;
+ VALUE size;
if (args && (RARRAY_LEN(args) > 0)) {
n = RARRAY_AREF(args, 0);
+ if (!NIL_P(n)) mul = NUM2LONG(n);
}
- if (n == Qnil) return DBL2NUM(INFINITY);
- mul = NUM2LONG(n);
+
+ size = enum_size(self, args, 0);
+ if (NIL_P(size) || FIXNUM_ZERO_P(size)) return size;
+
+ if (NIL_P(n)) return DBL2NUM(HUGE_VAL);
if (mul <= 0) return INT2FIX(0);
n = LONG2FIX(mul);
return rb_funcallv(size, '*', 1, &n);
@@ -2884,10 +3101,10 @@ enum_cycle(int argc, VALUE *argv, VALUE obj)
VALUE nv = Qnil;
long n, i, len;
- rb_scan_args(argc, argv, "01", &nv);
+ rb_check_arity(argc, 0, 1);
RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_cycle_size);
- if (NIL_P(nv)) {
+ if (!argc || NIL_P(nv = argv[0])) {
n = -1;
}
else {
@@ -3014,7 +3231,7 @@ chunk_i(RB_BLOCK_CALL_FUNC_ARGLIST(yielder, enumerator))
* The following example counts words for each initial letter.
*
* open("/usr/share/dict/words", "r:iso-8859-1") { |f|
- * f.chunk { |line| line.ord }.each { |ch, lines| p [ch.chr, lines.length] }
+ * f.chunk { |line| line.upcase.ord }.each { |ch, lines| p [ch.chr, lines.length] }
* }
* #=> ["\n", 1]
* # ["A", 1327]
@@ -3512,7 +3729,7 @@ slicewhen_i(RB_BLOCK_CALL_FUNC_ARGLIST(yielder, enumerator))
* Creates an enumerator for each chunked elements.
* The beginnings of chunks are defined by the block.
*
- * This method split each chunk using adjacent elements,
+ * This method splits each chunk using adjacent elements,
* _elt_before_ and _elt_after_,
* in the receiver enumerator.
* This method split chunks between _elt_before_ and _elt_after_ where
@@ -3591,7 +3808,7 @@ enum_slice_when(VALUE enumerable)
* Creates an enumerator for each chunked elements.
* The beginnings of chunks are defined by the block.
*
- * This method split each chunk using adjacent elements,
+ * This method splits each chunk using adjacent elements,
* _elt_before_ and _elt_after_,
* in the receiver enumerator.
* This method split chunks between _elt_before_ and _elt_after_ where
@@ -3659,103 +3876,141 @@ struct enum_sum_memo {
};
static void
-sum_iter(VALUE i, struct enum_sum_memo *memo)
+sum_iter_normalize_memo(struct enum_sum_memo *memo)
{
- const int unused = (assert(memo != NULL), 0);
+ assert(FIXABLE(memo->n));
+ memo->v = rb_fix_plus(LONG2FIX(memo->n), memo->v);
+ memo->n = 0;
- long n = memo->n;
- VALUE v = memo->v;
- VALUE r = memo->r;
- double f = memo->f;
- double c = memo->c;
+ switch (TYPE(memo->r)) {
+ case T_RATIONAL: memo->v = rb_rational_plus(memo->r, memo->v); break;
+ case T_UNDEF: break;
+ default: UNREACHABLE; /* or ...? */
+ }
+ memo->r = Qundef;
+}
- if (memo->block_given)
- i = rb_yield(i);
+static void
+sum_iter_fixnum(VALUE i, struct enum_sum_memo *memo)
+{
+ memo->n += FIX2LONG(i); /* should not overflow long type */
+ if (! FIXABLE(memo->n)) {
+ memo->v = rb_big_plus(LONG2NUM(memo->n), memo->v);
+ memo->n = 0;
+ }
+}
- if (memo->float_value)
- goto float_value;
+static void
+sum_iter_bignum(VALUE i, struct enum_sum_memo *memo)
+{
+ memo->v = rb_big_plus(i, memo->v);
+}
- if (FIXNUM_P(v) || RB_TYPE_P(v, T_BIGNUM) || RB_TYPE_P(v, T_RATIONAL)) {
- if (FIXNUM_P(i)) {
- n += FIX2LONG(i); /* should not overflow long type */
- if (!FIXABLE(n)) {
- v = rb_big_plus(LONG2NUM(n), v);
- n = 0;
- }
- }
- else if (RB_TYPE_P(i, T_BIGNUM))
- v = rb_big_plus(i, v);
- else if (RB_TYPE_P(i, T_RATIONAL)) {
- if (r == Qundef)
- r = i;
- else
- r = rb_rational_plus(r, i);
- }
- else {
- if (n != 0) {
- v = rb_fix_plus(LONG2FIX(n), v);
- n = 0;
- }
- if (r != Qundef) {
- /* r can be an Integer when mathn is loaded */
- if (FIXNUM_P(r))
- v = rb_fix_plus(r, v);
- else if (RB_TYPE_P(r, T_BIGNUM))
- v = rb_big_plus(r, v);
- else
- v = rb_rational_plus(r, v);
- r = Qundef;
- }
- if (RB_FLOAT_TYPE_P(i)) {
- f = NUM2DBL(v);
- c = 0.0;
- memo->float_value = 1;
- goto float_value;
- }
- else
- goto some_value;
- }
+static void
+sum_iter_rational(VALUE i, struct enum_sum_memo *memo)
+{
+ if (memo->r == Qundef) {
+ memo->r = i;
}
- else if (RB_FLOAT_TYPE_P(v)) {
- /*
- * Kahan-Babuska balancing compensated summation algorithm
- * See http://link.springer.com/article/10.1007/s00607-005-0139-x
- */
- double x, t;
-
- float_value:
- if (RB_FLOAT_TYPE_P(i))
- x = RFLOAT_VALUE(i);
- else if (FIXNUM_P(i))
- x = FIX2LONG(i);
- else if (RB_TYPE_P(i, T_BIGNUM))
- x = rb_big2dbl(i);
- else if (RB_TYPE_P(i, T_RATIONAL))
- x = rb_num2dbl(i);
- else {
- v = DBL2NUM(f);
- memo->float_value = 0;
- goto some_value;
+ else {
+ memo->r = rb_rational_plus(memo->r, i);
+ }
+}
+
+static void
+sum_iter_some_value(VALUE i, struct enum_sum_memo *memo)
+{
+ memo->v = rb_funcallv(memo->v, idPLUS, 1, &i);
+}
+
+static void
+sum_iter_Kahan_Babuska(VALUE i, struct enum_sum_memo *memo)
+{
+ /*
+ * Kahan-Babuska balancing compensated summation algorithm
+ * See https://link.springer.com/article/10.1007/s00607-005-0139-x
+ */
+ double x;
+
+ switch (TYPE(i)) {
+ case T_FLOAT: x = RFLOAT_VALUE(i); break;
+ case T_FIXNUM: x = FIX2LONG(i); break;
+ case T_BIGNUM: x = rb_big2dbl(i); break;
+ case T_RATIONAL: x = rb_num2dbl(i); break;
+ default:
+ memo->v = DBL2NUM(memo->f);
+ memo->float_value = 0;
+ sum_iter_some_value(i, memo);
+ return;
+ }
+
+ double f = memo->f;
+
+ if (isnan(f)) {
+ return;
+ }
+ else if (! isfinite(x)) {
+ if (isinf(x) && isinf(f) && signbit(x) != signbit(f)) {
+ i = DBL2NUM(f);
+ x = nan("");
}
+ memo->v = i;
+ memo->f = x;
+ return;
+ }
+ else if (isinf(f)) {
+ return;
+ }
- t = f + x;
- if (fabs(f) >= fabs(x))
- c += ((f - t) + x);
- else
- c += ((x - t) + f);
- f = t;
+ double c = memo->c;
+ double t = f + x;
+
+ if (fabs(f) >= fabs(x)) {
+ c += ((f - t) + x);
}
else {
- some_value:
- v = rb_funcallv(v, idPLUS, 1, &i);
+ c += ((x - t) + f);
}
+ f = t;
- memo->v = v;
- memo->n = n;
- memo->r = r;
memo->f = f;
memo->c = c;
- (void)unused;
+}
+
+static void
+sum_iter(VALUE i, struct enum_sum_memo *memo)
+{
+ assert(memo != NULL);
+ if (memo->block_given) {
+ i = rb_yield(i);
+ }
+
+ if (memo->float_value) {
+ sum_iter_Kahan_Babuska(i, memo);
+ }
+ else switch (TYPE(memo->v)) {
+ default: sum_iter_some_value(i, memo); return;
+ case T_FLOAT: sum_iter_Kahan_Babuska(i, memo); return;
+ case T_FIXNUM:
+ case T_BIGNUM:
+ case T_RATIONAL:
+ switch (TYPE(i)) {
+ case T_FIXNUM: sum_iter_fixnum(i, memo); return;
+ case T_BIGNUM: sum_iter_bignum(i, memo); return;
+ case T_RATIONAL: sum_iter_rational(i, memo); return;
+ case T_FLOAT:
+ sum_iter_normalize_memo(memo);
+ memo->f = NUM2DBL(memo->v);
+ memo->c = 0.0;
+ memo->float_value = 1;
+ sum_iter_Kahan_Babuska(i, memo);
+ return;
+ default:
+ sum_iter_normalize_memo(memo);
+ sum_iter_some_value(i, memo);
+ return;
+ }
+ }
}
static VALUE
@@ -3820,7 +4075,7 @@ int_range_sum(VALUE beg, VALUE end, int excl, VALUE init)
* { 1 => 10, 2 => 20 }.sum {|k, v| k * v } #=> 50
* (1..10).sum #=> 55
* (1..10).sum {|v| v * 2 } #=> 110
- * [Object.new].each.sum #=> TypeError
+ * ('a'..'z').sum #=> TypeError
*
* This method can be used for non-numeric objects by
* explicit <i>init</i> argument.
@@ -3828,8 +4083,12 @@ int_range_sum(VALUE beg, VALUE end, int excl, VALUE init)
* { 1 => 10, 2 => 20 }.sum([]) #=> [1, 10, 2, 20]
* "a\nb\nc".each_line.lazy.map(&:chomp).sum("") #=> "abc"
*
+ * If the method is applied to an Integer range without a block,
+ * the sum is not done by iteration, but instead using Gauss's summation
+ * formula.
+ *
* Enumerable#sum method may not respect method redefinition of "+"
- * methods such as Integer#+.
+ * methods such as Integer#+, or "each" methods such as Range#each.
*/
static VALUE
enum_sum(int argc, VALUE* argv, VALUE obj)
@@ -3838,11 +4097,8 @@ enum_sum(int argc, VALUE* argv, VALUE obj)
VALUE beg, end;
int excl;
- if (rb_scan_args(argc, argv, "01", &memo.v) == 0)
- memo.v = LONG2FIX(0);
-
+ memo.v = (rb_check_arity(argc, 0, 1) == 0) ? LONG2FIX(0) : argv[0];
memo.block_given = rb_block_given_p();
-
memo.n = 0;
memo.r = Qundef;
@@ -3850,6 +4106,10 @@ enum_sum(int argc, VALUE* argv, VALUE obj)
memo.f = RFLOAT_VALUE(memo.v);
memo.c = 0.0;
}
+ else {
+ memo.f = 0.0;
+ memo.c = 0.0;
+ }
if (RTEST(rb_range_values(obj, &beg, &end, &excl))) {
if (!memo.block_given && !memo.float_value &&
@@ -3872,13 +4132,7 @@ enum_sum(int argc, VALUE* argv, VALUE obj)
if (memo.n != 0)
memo.v = rb_fix_plus(LONG2FIX(memo.n), memo.v);
if (memo.r != Qundef) {
- /* r can be an Integer when mathn is loaded */
- if (FIXNUM_P(memo.r))
- memo.v = rb_fix_plus(memo.r, memo.v);
- else if (RB_TYPE_P(memo.r, T_BIGNUM))
- memo.v = rb_big_plus(memo.r, memo.v);
- else
- memo.v = rb_rational_plus(memo.r, memo.v);
+ memo.v = rb_rational_plus(memo.r, memo.v);
}
return memo.v;
}
@@ -3925,22 +4179,18 @@ enum_uniq(VALUE obj)
}
/*
- * The <code>Enumerable</code> mixin provides collection classes with
- * several traversal and searching methods, and with the ability to
- * sort. The class must provide a method <code>each</code>, which
- * yields successive members of the collection. If
- * <code>Enumerable#max</code>, <code>#min</code>, or
- * <code>#sort</code> is used, the objects in the collection must also
- * implement a meaningful <code><=></code> operator, as these methods
- * rely on an ordering between members of the collection.
+ * The Enumerable mixin provides collection classes with several
+ * traversal and searching methods, and with the ability to sort. The
+ * class must provide a method #each, which yields
+ * successive members of the collection. If Enumerable#max, #min, or
+ * #sort is used, the objects in the collection must also implement a
+ * meaningful <code><=></code> operator, as these methods rely on an
+ * ordering between members of the collection.
*/
void
Init_Enumerable(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
rb_mEnumerable = rb_define_module("Enumerable");
rb_define_method(rb_mEnumerable, "to_a", enum_to_a, -1);
@@ -3957,6 +4207,8 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, "find_index", enum_find_index, -1);
rb_define_method(rb_mEnumerable, "find_all", enum_find_all, 0);
rb_define_method(rb_mEnumerable, "select", enum_find_all, 0);
+ rb_define_method(rb_mEnumerable, "filter", enum_find_all, 0);
+ rb_define_method(rb_mEnumerable, "filter_map", enum_filter_map, 0);
rb_define_method(rb_mEnumerable, "reject", enum_reject, 0);
rb_define_method(rb_mEnumerable, "collect", enum_collect, 0);
rb_define_method(rb_mEnumerable, "map", enum_collect, 0);
@@ -3966,11 +4218,12 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, "reduce", enum_inject, -1);
rb_define_method(rb_mEnumerable, "partition", enum_partition, 0);
rb_define_method(rb_mEnumerable, "group_by", enum_group_by, 0);
+ rb_define_method(rb_mEnumerable, "tally", enum_tally, 0);
rb_define_method(rb_mEnumerable, "first", enum_first, -1);
- rb_define_method(rb_mEnumerable, "all?", enum_all, 0);
- rb_define_method(rb_mEnumerable, "any?", enum_any, 0);
- rb_define_method(rb_mEnumerable, "one?", enum_one, 0);
- rb_define_method(rb_mEnumerable, "none?", enum_none, 0);
+ rb_define_method(rb_mEnumerable, "all?", enum_all, -1);
+ rb_define_method(rb_mEnumerable, "any?", enum_any, -1);
+ rb_define_method(rb_mEnumerable, "one?", enum_one, -1);
+ rb_define_method(rb_mEnumerable, "none?", enum_none, -1);
rb_define_method(rb_mEnumerable, "min", enum_min, -1);
rb_define_method(rb_mEnumerable, "max", enum_max, -1);
rb_define_method(rb_mEnumerable, "minmax", enum_minmax, 0);
@@ -3999,6 +4252,5 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, "sum", enum_sum, -1);
rb_define_method(rb_mEnumerable, "uniq", enum_uniq, 0);
- id_next = rb_intern("next");
- id_div = rb_intern("div");
+ id_next = rb_intern_const("next");
}
diff --git a/enumerator.c b/enumerator.c
index a996566b7b..90d2ec433c 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -12,7 +12,22 @@
************************************************/
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include "id.h"
#include "internal.h"
+#include "internal/enumerator.h"
+#include "internal/error.h"
+#include "internal/hash.h"
+#include "internal/imemo.h"
+#include "internal/numeric.h"
+#include "internal/range.h"
+#include "internal/rational.h"
+#include "ruby/ruby.h"
/*
* Document-class: Enumerator
@@ -20,8 +35,8 @@
* A class which allows both internal and external iteration.
*
* An Enumerator can be created by the following methods.
- * - Kernel#to_enum
- * - Kernel#enum_for
+ * - Object#to_enum
+ * - Object#enum_for
* - Enumerator.new
*
* Most methods have two forms: a block form where the contents
@@ -67,6 +82,14 @@
* puts e.next # => 3
* puts e.next # raises StopIteration
*
+ * Note that enumeration sequence by +next+, +next_values+, +peek+ and
+ * +peek_values+ do not affect other non-external
+ * enumeration methods, unless the underlying iteration method itself has
+ * side-effect, e.g. IO#each_line.
+ *
+ * Moreover, implementation typically uses fibers so performance could be
+ * slower and exception stacktraces different than expected.
+ *
* You can use this to implement an internal iterator as follows:
*
* def ext_each(e)
@@ -101,10 +124,19 @@
*
*/
VALUE rb_cEnumerator;
-VALUE rb_cLazy;
-static ID id_rewind, id_each, id_new, id_initialize, id_yield, id_call, id_size, id_to_enum;
-static ID id_eqq, id_next, id_result, id_lazy, id_receiver, id_arguments, id_memo, id_method, id_force;
-static VALUE sym_each, sym_cycle;
+static VALUE rb_cLazy;
+static ID id_rewind, id_new, id_to_enum;
+static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force;
+static ID id_begin, id_end, id_step, id_exclude_end;
+static VALUE sym_each, sym_cycle, sym_yield;
+
+static VALUE lazy_use_super_method;
+
+#define id_call idCall
+#define id_each idEach
+#define id_eqq idEqq
+#define id_initialize idInitialize
+#define id_size idSize
VALUE rb_eStopIteration;
@@ -120,9 +152,10 @@ struct enumerator {
VALUE size;
VALUE procs;
rb_enumerator_size_func *size_fn;
+ int kw_splat;
};
-static VALUE rb_cGenerator, rb_cYielder;
+static VALUE rb_cGenerator, rb_cYielder, rb_cEnumProducer;
struct generator {
VALUE proc;
@@ -133,6 +166,11 @@ struct yielder {
VALUE proc;
};
+struct producer {
+ VALUE init;
+ VALUE proc;
+};
+
typedef struct MEMO *lazyenum_proc_func(VALUE, struct MEMO *, VALUE, long);
typedef VALUE lazyenum_size_func(VALUE, VALUE);
typedef struct {
@@ -149,6 +187,15 @@ struct proc_entry {
static VALUE generator_allocate(VALUE klass);
static VALUE generator_init(VALUE obj, VALUE proc);
+static VALUE rb_cEnumChain;
+
+struct enum_chain {
+ VALUE enums;
+ long pos;
+};
+
+VALUE rb_cArithSeq;
+
/*
* Enumerator
*/
@@ -156,15 +203,30 @@ static void
enumerator_mark(void *p)
{
struct enumerator *ptr = p;
- rb_gc_mark(ptr->obj);
- rb_gc_mark(ptr->args);
- rb_gc_mark(ptr->fib);
- rb_gc_mark(ptr->dst);
- rb_gc_mark(ptr->lookahead);
- rb_gc_mark(ptr->feedvalue);
- rb_gc_mark(ptr->stop_exc);
- rb_gc_mark(ptr->size);
- rb_gc_mark(ptr->procs);
+ rb_gc_mark_movable(ptr->obj);
+ rb_gc_mark_movable(ptr->args);
+ rb_gc_mark_movable(ptr->fib);
+ rb_gc_mark_movable(ptr->dst);
+ rb_gc_mark_movable(ptr->lookahead);
+ rb_gc_mark_movable(ptr->feedvalue);
+ rb_gc_mark_movable(ptr->stop_exc);
+ rb_gc_mark_movable(ptr->size);
+ rb_gc_mark_movable(ptr->procs);
+}
+
+static void
+enumerator_compact(void *p)
+{
+ struct enumerator *ptr = p;
+ ptr->obj = rb_gc_location(ptr->obj);
+ ptr->args = rb_gc_location(ptr->args);
+ ptr->fib = rb_gc_location(ptr->fib);
+ ptr->dst = rb_gc_location(ptr->dst);
+ ptr->lookahead = rb_gc_location(ptr->lookahead);
+ ptr->feedvalue = rb_gc_location(ptr->feedvalue);
+ ptr->stop_exc = rb_gc_location(ptr->stop_exc);
+ ptr->size = rb_gc_location(ptr->size);
+ ptr->procs = rb_gc_location(ptr->procs);
}
#define enumerator_free RUBY_TYPED_DEFAULT_FREE
@@ -181,6 +243,7 @@ static const rb_data_type_t enumerator_data_type = {
enumerator_mark,
enumerator_free,
enumerator_memsize,
+ enumerator_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -201,8 +264,16 @@ static void
proc_entry_mark(void *p)
{
struct proc_entry *ptr = p;
- rb_gc_mark(ptr->proc);
- rb_gc_mark(ptr->memo);
+ rb_gc_mark_movable(ptr->proc);
+ rb_gc_mark_movable(ptr->memo);
+}
+
+static void
+proc_entry_compact(void *p)
+{
+ struct proc_entry *ptr = p;
+ ptr->proc = rb_gc_location(ptr->proc);
+ ptr->memo = rb_gc_location(ptr->memo);
}
#define proc_entry_free RUBY_TYPED_DEFAULT_FREE
@@ -219,6 +290,7 @@ static const rb_data_type_t proc_entry_data_type = {
proc_entry_mark,
proc_entry_free,
proc_entry_memsize,
+ proc_entry_compact,
},
};
@@ -240,7 +312,8 @@ proc_entry_ptr(VALUE proc_entry)
* 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.
+ * +obj+, passing +args+ if any. What was _yielded_ by method becomes
+ * values of enumerator.
*
* 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).
@@ -259,6 +332,11 @@ proc_entry_ptr(VALUE proc_entry)
* a = [1, 2, 3]
* some_method(a.to_enum)
*
+ * # String#split in block form is more memory-effective:
+ * very_large_string.split("|") { |chunk| return chunk if chunk.include?('DATE') }
+ * # This could be rewritten more idiomatically with to_enum:
+ * very_large_string.to_enum(:split, "|").lazy.grep(/DATE/).first
+ *
* It is typical to call to_enum when defining methods for
* a generic Enumerable, in case no block is passed.
*
@@ -316,7 +394,7 @@ enumerator_allocate(VALUE klass)
}
static VALUE
-enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, VALUE size)
+enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, VALUE size, int kw_splat)
{
struct enumerator *ptr;
@@ -337,21 +415,38 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *ar
ptr->stop_exc = Qfalse;
ptr->size = size;
ptr->size_fn = size_fn;
+ ptr->kw_splat = kw_splat;
return enum_obj;
}
+static VALUE
+convert_to_feasible_size_value(VALUE obj)
+{
+ if (NIL_P(obj)) {
+ return obj;
+ }
+ else if (rb_respond_to(obj, id_call)) {
+ return obj;
+ }
+ else if (RB_FLOAT_TYPE_P(obj) && RFLOAT_VALUE(obj) == HUGE_VAL) {
+ return obj;
+ }
+ else {
+ return rb_to_int(obj);
+ }
+}
+
/*
* call-seq:
* Enumerator.new(size = nil) { |yielder| ... }
- * Enumerator.new(obj, method = :each, *args)
*
* Creates a new Enumerator object, which can be used as an
* Enumerable.
*
- * In the first form, iteration is defined by the given block, in
+ * Iteration is defined by the given block, in
* which a "yielder" object, given as block parameter, can be used to
- * yield a value by calling the +yield+ method (aliased as +<<+):
+ * yield a value by calling the +yield+ method (aliased as <code><<</code>):
*
* fib = Enumerator.new do |y|
* a = b = 1
@@ -361,55 +456,21 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *ar
* end
* end
*
- * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
+ * fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
*
* The optional parameter can be used to specify how to calculate the size
* in a lazy fashion (see Enumerator#size). It can either be a value or
* a callable object.
- *
- * In the second, deprecated, form, a generated Enumerator iterates over the
- * given object using the given method with the given arguments passed.
- *
- * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum
- * instead.
- *
- * e = Enumerator.new(ObjectSpace, :each_object)
- * #-> ObjectSpace.enum_for(:each_object)
- *
- * e.select { |obj| obj.is_a?(Class) } #=> array of all classes
- *
*/
static VALUE
enumerator_initialize(int argc, VALUE *argv, VALUE obj)
{
- VALUE recv, meth = sym_each;
- VALUE size = Qnil;
-
- if (rb_block_given_p()) {
- rb_check_arity(argc, 0, 1);
- recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
- if (argc) {
- if (NIL_P(argv[0]) || rb_respond_to(argv[0], id_call) ||
- (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == INFINITY)) {
- size = argv[0];
- }
- else {
- size = rb_to_int(argv[0]);
- }
- argc = 0;
- }
- }
- else {
- rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
- rb_warn("Enumerator.new without a block is deprecated; use Object#to_enum");
- recv = *argv++;
- if (--argc) {
- meth = *argv++;
- --argc;
- }
- }
+ VALUE iter = rb_block_proc();
+ VALUE recv = generator_init(generator_allocate(rb_cGenerator), iter);
+ VALUE arg0 = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
+ VALUE size = convert_to_feasible_size_value(arg0);
- return enumerator_init(obj, recv, meth, argc, argv, 0, size);
+ return enumerator_init(obj, recv, sym_each, 0, 0, 0, size, false);
}
/* :nodoc: */
@@ -453,7 +514,7 @@ rb_enumeratorize(VALUE obj, VALUE meth, int argc, const VALUE *argv)
}
static VALUE
-lazy_to_enum_i(VALUE self, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn);
+lazy_to_enum_i(VALUE self, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat);
VALUE
rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
@@ -461,10 +522,22 @@ rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, r
/* Similar effect as calling obj.to_enum, i.e. dispatching to either
Kernel#to_enum vs Lazy#to_enum */
if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
- return lazy_to_enum_i(obj, meth, argc, argv, size_fn);
+ return lazy_to_enum_i(obj, meth, argc, argv, size_fn, rb_keyword_given_p());
else
return enumerator_init(enumerator_allocate(rb_cEnumerator),
- obj, meth, argc, argv, size_fn, Qnil);
+ obj, meth, argc, argv, size_fn, Qnil, rb_keyword_given_p());
+}
+
+VALUE
+rb_enumeratorize_with_size_kw(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat)
+{
+ /* Similar effect as calling obj.to_enum, i.e. dispatching to either
+ Kernel#to_enum vs Lazy#to_enum */
+ if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
+ return lazy_to_enum_i(obj, meth, argc, argv, size_fn, kw_splat);
+ else
+ return enumerator_init(enumerator_allocate(rb_cEnumerator),
+ obj, meth, argc, argv, size_fn, Qnil, kw_splat);
}
static VALUE
@@ -479,7 +552,7 @@ enumerator_block_call(VALUE obj, rb_block_call_func *func, VALUE arg)
argc = RARRAY_LENINT(e->args);
argv = RARRAY_CONST_PTR(e->args);
}
- return rb_block_call(e->obj, meth, argc, argv, func, arg);
+ return rb_block_call_kw(e->obj, meth, argc, argv, func, arg, e->kw_splat);
}
/*
@@ -536,6 +609,8 @@ enumerator_each(int argc, VALUE *argv, VALUE obj)
args = rb_ary_new4(argc, argv);
}
e->args = args;
+ e->size = Qnil;
+ e->size_fn = 0;
}
if (!rb_block_given_p()) return obj;
return enumerator_block_call(obj, 0, obj);
@@ -580,12 +655,9 @@ enumerator_with_index(int argc, VALUE *argv, VALUE obj)
{
VALUE memo;
- rb_scan_args(argc, argv, "01", &memo);
+ rb_check_arity(argc, 0, 1);
RETURN_SIZED_ENUMERATOR(obj, argc, argv, enumerator_enum_size);
- if (NIL_P(memo))
- memo = INT2FIX(0);
- else
- memo = rb_to_int(memo);
+ memo = (!argc || NIL_P(memo = argv[0])) ? INT2FIX(0) : rb_to_int(memo);
return enumerator_block_call(obj, enumerator_with_index_i, (VALUE)MEMO_NEW(memo, 0, 0));
}
@@ -639,9 +711,9 @@ enumerator_with_object_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, memo))
* puts "#{string}: #{x}"
* end
*
- * # => foo:0
- * # => foo:1
- * # => foo:2
+ * # => foo: 0
+ * # => foo: 1
+ * # => foo: 2
*/
static VALUE
enumerator_with_object(VALUE obj, VALUE memo)
@@ -667,7 +739,7 @@ next_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, obj))
}
static VALUE
-next_i(VALUE curr, VALUE obj)
+next_i(RB_BLOCK_CALL_FUNC_ARGLIST(_, obj))
{
struct enumerator *e = enumerator_ptr(obj);
VALUE nil = Qnil;
@@ -721,6 +793,8 @@ get_next_values(VALUE obj, struct enumerator *e)
* internal position forward. When the position reached at the end,
* StopIteration is raised.
*
+ * See class-level notes about external iterators.
+ *
* This method can be used to distinguish <code>yield</code> and <code>yield
* nil</code>.
*
@@ -754,10 +828,6 @@ get_next_values(VALUE obj, struct enumerator *e)
* # yield nil [nil] nil
* # yield [1, 2] [[1, 2]] [1, 2]
*
- * Note that +next_values+ does not affect other non-external enumeration
- * methods unless underlying iteration method itself has side-effect, e.g.
- * IO#each_line.
- *
*/
static VALUE
@@ -811,9 +881,7 @@ ary2sv(VALUE args, int dup)
* p e.next #=> 3
* p e.next #raises StopIteration
*
- * Note that enumeration sequence by +next+ does not affect other non-external
- * enumeration methods, unless the underlying iteration methods itself has
- * side-effect, e.g. IO#each_line.
+ * See class-level notes about external iterators.
*
*/
@@ -843,6 +911,8 @@ enumerator_peek_values(VALUE obj)
* doesn't move the internal position forward. If the position is already at
* the end, StopIteration is raised.
*
+ * See class-level notes about external iterators.
+ *
* === Example
*
* o = Object.new
@@ -877,6 +947,8 @@ enumerator_peek_values_m(VALUE obj)
* position forward. If the position is already at the end, StopIteration
* is raised.
*
+ * See class-level notes about external iterators.
+ *
* === Example
*
* a = [1,2,3]
@@ -1000,7 +1072,6 @@ inspect_enumerator(VALUE obj, VALUE dummy, int recur)
if (recur) {
str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname));
- OBJ_TAINT(str);
return str;
}
@@ -1037,6 +1108,22 @@ inspect_enumerator(VALUE obj, VALUE dummy, int recur)
return str;
}
+static int
+key_symbol_p(VALUE key, VALUE val, VALUE arg)
+{
+ if (SYMBOL_P(key)) return ST_CONTINUE;
+ *(int *)arg = FALSE;
+ return ST_STOP;
+}
+
+static int
+kwd_append(VALUE key, VALUE val, VALUE str)
+{
+ if (!SYMBOL_P(key)) rb_raise(rb_eRuntimeError, "non-symbol key inserted");
+ rb_str_catf(str, "% "PRIsVALUE": %"PRIsVALUE", ", key, val);
+ return ST_CONTINUE;
+}
+
static VALUE
append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args)
{
@@ -1064,15 +1151,27 @@ append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args)
const VALUE *argv = RARRAY_CONST_PTR(eargs); /* WB: no new reference */
if (argc > 0) {
+ VALUE kwds = Qnil;
+
rb_str_buf_cat2(str, "(");
+ if (RB_TYPE_P(argv[argc-1], T_HASH) && !RHASH_EMPTY_P(argv[argc-1])) {
+ int all_key = TRUE;
+ rb_hash_foreach(argv[argc-1], key_symbol_p, (VALUE)&all_key);
+ if (all_key) kwds = argv[--argc];
+ }
+
while (argc--) {
VALUE arg = *argv++;
rb_str_append(str, rb_inspect(arg));
- rb_str_buf_cat2(str, argc > 0 ? ", " : ")");
- OBJ_INFECT(str, arg);
+ rb_str_buf_cat2(str, ", ");
}
+ if (!NIL_P(kwds)) {
+ rb_hash_foreach(kwds, kwd_append, str);
+ }
+ rb_str_set_len(str, RSTRING_LEN(str)-2);
+ rb_str_buf_cat2(str, ")");
}
}
@@ -1119,11 +1218,11 @@ enumerator_size(VALUE obj)
for (i = 0; i < RARRAY_LEN(e->procs); i++) {
VALUE proc = RARRAY_AREF(e->procs, i);
struct proc_entry *entry = proc_entry_ptr(proc);
- lazyenum_size_func *size = entry->fn->size;
- if (!size) {
+ lazyenum_size_func *size_fn = entry->fn->size;
+ if (!size_fn) {
return Qnil;
}
- receiver = (*size)(proc, receiver);
+ receiver = (*size_fn)(proc, receiver);
}
return receiver;
}
@@ -1135,7 +1234,7 @@ enumerator_size(VALUE obj)
argc = (int)RARRAY_LEN(e->args);
argv = RARRAY_CONST_PTR(e->args);
}
- size = rb_check_funcall(e->size, id_call, argc, argv);
+ size = rb_check_funcall_kw(e->size, id_call, argc, argv, e->kw_splat);
if (size != Qundef) return size;
return e->size;
}
@@ -1147,7 +1246,14 @@ static void
yielder_mark(void *p)
{
struct yielder *ptr = p;
- rb_gc_mark(ptr->proc);
+ rb_gc_mark_movable(ptr->proc);
+}
+
+static void
+yielder_compact(void *p)
+{
+ struct yielder *ptr = p;
+ ptr->proc = rb_gc_location(ptr->proc);
}
#define yielder_free RUBY_TYPED_DEFAULT_FREE
@@ -1164,6 +1270,7 @@ static const rb_data_type_t yielder_data_type = {
yielder_mark,
yielder_free,
yielder_memsize,
+ yielder_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -1224,21 +1331,44 @@ yielder_yield(VALUE obj, VALUE args)
{
struct yielder *ptr = yielder_ptr(obj);
- return rb_proc_call(ptr->proc, args);
+ return rb_proc_call_kw(ptr->proc, args, RB_PASS_CALLED_KEYWORDS);
}
/* :nodoc: */
static VALUE
-yielder_yield_push(VALUE obj, VALUE args)
+yielder_yield_push(VALUE obj, VALUE arg)
{
- yielder_yield(obj, args);
+ struct yielder *ptr = yielder_ptr(obj);
+
+ rb_proc_call_with_block(ptr->proc, 1, &arg, Qnil);
+
return obj;
}
+/*
+ * Returns a Proc object that takes arguments and yields them.
+ *
+ * This method is implemented so that a Yielder object can be directly
+ * passed to another method as a block argument.
+ *
+ * enum = Enumerator.new { |y|
+ * Dir.glob("*.rb") { |file|
+ * File.open(file) { |f| f.each_line(&y) }
+ * }
+ * }
+ */
+static VALUE
+yielder_to_proc(VALUE obj)
+{
+ VALUE method = rb_obj_method(obj, sym_yield);
+
+ return rb_funcall(method, idTo_proc, 0);
+}
+
static VALUE
yielder_yield_i(RB_BLOCK_CALL_FUNC_ARGLIST(obj, memo))
{
- return rb_yield_values2(argc, argv);
+ return rb_yield_values_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
}
static VALUE
@@ -1254,8 +1384,16 @@ static void
generator_mark(void *p)
{
struct generator *ptr = p;
- rb_gc_mark(ptr->proc);
- rb_gc_mark(ptr->obj);
+ rb_gc_mark_movable(ptr->proc);
+ rb_gc_mark_movable(ptr->obj);
+}
+
+static void
+generator_compact(void *p)
+{
+ struct generator *ptr = p;
+ ptr->proc = rb_gc_location(ptr->proc);
+ ptr->obj = rb_gc_location(ptr->obj);
}
#define generator_free RUBY_TYPED_DEFAULT_FREE
@@ -1272,6 +1410,7 @@ static const rb_data_type_t generator_data_type = {
generator_mark,
generator_free,
generator_memsize,
+ generator_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -1378,7 +1517,7 @@ generator_each(int argc, VALUE *argv, VALUE obj)
rb_ary_cat(args, argv, argc);
}
- return rb_proc_call(ptr->proc, args);
+ return rb_proc_call_kw(ptr->proc, args, RB_PASS_CALLED_KEYWORDS);
}
/* Lazy Enumerator methods */
@@ -1395,17 +1534,7 @@ lazyenum_size(VALUE self, VALUE args, VALUE eobj)
return enum_size(self);
}
-static VALUE
-lazy_size(VALUE self)
-{
- return enum_size(rb_ivar_get(self, id_receiver));
-}
-
-static VALUE
-lazy_receiver_size(VALUE generator, VALUE args, VALUE lazy)
-{
- return lazy_size(lazy);
-}
+#define lazy_receiver_size lazy_map_size
static VALUE
lazy_init_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
@@ -1447,24 +1576,47 @@ lazy_init_block_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
#define LAZY_MEMO_BREAK_P(memo) ((memo)->memo_flags & LAZY_MEMO_BREAK)
#define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED)
#define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK)
+#define LAZY_MEMO_RESET_BREAK(memo) ((memo)->memo_flags &= ~LAZY_MEMO_BREAK)
#define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value)
#define LAZY_MEMO_SET_PACKED(memo) ((memo)->memo_flags |= LAZY_MEMO_PACKED)
#define LAZY_MEMO_RESET_PACKED(memo) ((memo)->memo_flags &= ~LAZY_MEMO_PACKED)
+static VALUE lazy_yielder_result(struct MEMO *result, VALUE yielder, VALUE procs_array, VALUE memos, long i);
+
static VALUE
-lazy_init_yielder(VALUE val, VALUE m, int argc, VALUE *argv)
+lazy_init_yielder(RB_BLOCK_CALL_FUNC_ARGLIST(_, m))
{
VALUE yielder = RARRAY_AREF(m, 0);
VALUE procs_array = RARRAY_AREF(m, 1);
VALUE memos = rb_attr_get(yielder, id_memo);
- long i = 0;
struct MEMO *result;
- int cont = 1;
- result = MEMO_NEW(Qnil, rb_enum_values_pack(argc, argv),
+ result = MEMO_NEW(m, rb_enum_values_pack(argc, argv),
argc > 1 ? LAZY_MEMO_PACKED : 0);
+ return lazy_yielder_result(result, yielder, procs_array, memos, 0);
+}
- for (i = 0; i < RARRAY_LEN(procs_array); i++) {
+static VALUE
+lazy_yielder_yield(struct MEMO *result, long memo_index, int argc, const VALUE *argv)
+{
+ VALUE m = result->v1;
+ VALUE yielder = RARRAY_AREF(m, 0);
+ VALUE procs_array = RARRAY_AREF(m, 1);
+ VALUE memos = rb_attr_get(yielder, id_memo);
+ LAZY_MEMO_SET_VALUE(result, rb_enum_values_pack(argc, argv));
+ if (argc > 1)
+ LAZY_MEMO_SET_PACKED(result);
+ else
+ LAZY_MEMO_RESET_PACKED(result);
+ return lazy_yielder_result(result, yielder, procs_array, memos, memo_index);
+}
+
+static VALUE
+lazy_yielder_result(struct MEMO *result, VALUE yielder, VALUE procs_array, VALUE memos, long i)
+{
+ int cont = 1;
+
+ for (; i < RARRAY_LEN(procs_array); i++) {
VALUE proc = RARRAY_AREF(procs_array, i);
struct proc_entry *entry = proc_entry_ptr(proc);
if (!(*entry->fn->proc)(proc, result, memos, i)) {
@@ -1474,7 +1626,7 @@ lazy_init_yielder(VALUE val, VALUE m, int argc, VALUE *argv)
}
if (cont) {
- rb_funcall2(yielder, id_yield, 1, &(result->memo_value));
+ rb_funcall2(yielder, idLTLT, 1, &(result->memo_value));
}
if (LAZY_MEMO_BREAK_P(result)) {
rb_iter_break();
@@ -1483,7 +1635,7 @@ lazy_init_yielder(VALUE val, VALUE m, int argc, VALUE *argv)
}
static VALUE
-lazy_init_block(VALUE val, VALUE m, int argc, VALUE *argv)
+lazy_init_block(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
{
VALUE procs = RARRAY_AREF(m, 1);
@@ -1521,32 +1673,93 @@ lazy_generator_init(VALUE enumerator, VALUE procs)
}
/*
+ * Document-class: Enumerator::Lazy
+ *
+ * Enumerator::Lazy is a special type of Enumerator, that allows constructing
+ * chains of operations without evaluating them immediately, and evaluating
+ * values on as-needed basis. In order to do so it redefines most of Enumerable
+ * methods so that they just construct another lazy enumerator.
+ *
+ * Enumerator::Lazy can be constructed from any Enumerable with the
+ * Enumerable#lazy method.
+ *
+ * lazy = (1..Float::INFINITY).lazy.select(&:odd?).drop(10).take_while { |i| i < 30 }
+ * # => #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:select>:drop(10)>:take_while>
+ *
+ * The real enumeration is performed when any non-redefined Enumerable method
+ * is called, like Enumerable#first or Enumerable#to_a (the latter is aliased
+ * as #force for more semantic code):
+ *
+ * lazy.first(2)
+ * #=> [21, 23]
+ *
+ * lazy.force
+ * #=> [21, 23, 25, 27, 29]
+ *
+ * Note that most Enumerable methods that could be called with or without
+ * a block, on Enumerator::Lazy will always require a block:
+ *
+ * [1, 2, 3].map #=> #<Enumerator: [1, 2, 3]:map>
+ * [1, 2, 3].lazy.map # ArgumentError: tried to call lazy map without a block
+ *
+ * This class allows idiomatic calculations on long or infinite sequences, as well
+ * as chaining of calculations without constructing intermediate arrays.
+ *
+ * Example for working with a slowly calculated sequence:
+ *
+ * require 'open-uri'
+ *
+ * # This will fetch all URLs before selecting
+ * # necessary data
+ * URLS.map { |u| JSON.parse(open(u).read) }
+ * .select { |data| data.key?('stats') }
+ * .first(5)
+ *
+ * # This will fetch URLs one-by-one, only till
+ * # there is enough data to satisfy the condition
+ * URLS.lazy.map { |u| JSON.parse(open(u).read) }
+ * .select { |data| data.key?('stats') }
+ * .first(5)
+ *
+ * Ending a chain with ".eager" generates a non-lazy enumerator, which
+ * is suitable for returning or passing to another method that expects
+ * a normal enumerator.
+ *
+ * def active_items
+ * groups
+ * .lazy
+ * .flat_map(&:items)
+ * .reject(&:disabled)
+ * .eager
+ * end
+ *
+ * # This works lazily; if a checked item is found, it stops
+ * # iteration and does not look into remaining groups.
+ * first_checked = active_items.find(&:checked)
+ *
+ * # This returns an array of items like a normal enumerator does.
+ * all_checked = active_items.select(&:checked)
+ *
+ */
+
+/*
* call-seq:
- * Lazy.new(obj, size=nil) { |yielder, *values| ... }
+ * Lazy.new(obj, size=nil) { |yielder, *values| block }
*
* Creates a new Lazy enumerator. When the enumerator is actually enumerated
* (e.g. by calling #force), +obj+ will be enumerated and each value passed
* to the given block. The block can yield values back using +yielder+.
- * For example, to create a method +filter_map+ in both lazy and
- * non-lazy fashions:
+ * For example, to create a "filter+map" enumerator:
*
- * module Enumerable
- * def filter_map(&block)
- * map(&block).compact
+ * def filter_map(sequence)
+ * Lazy.new(sequence) do |yielder, *values|
+ * result = yield *values
+ * yielder << result if result
* end
* end
*
- * class Enumerator::Lazy
- * def filter_map
- * Lazy.new(self) do |yielder, *values|
- * result = yield *values
- * yielder << result if result
- * end
- * end
- * end
- *
- * (1..Float::INFINITY).lazy.filter_map{|i| i*i if i.even?}.first(5)
- * # => [4, 16, 36, 64, 100]
+ * filter_map(1..Float::INFINITY) {|i| i*i if i.even?}.first(5)
+ * #=> [4, 16, 36, 64, 100]
*/
static VALUE
lazy_initialize(int argc, VALUE *argv, VALUE self)
@@ -1564,12 +1777,26 @@ lazy_initialize(int argc, VALUE *argv, VALUE self)
}
generator = generator_allocate(rb_cGenerator);
rb_block_call(generator, id_initialize, 0, 0, lazy_init_block_i, obj);
- enumerator_init(self, generator, sym_each, 0, 0, 0, size);
+ enumerator_init(self, generator, sym_each, 0, 0, 0, size, 0);
rb_ivar_set(self, id_receiver, obj);
return self;
}
+#if 0 /* for RDoc */
+/*
+ * call-seq:
+ * lazy.to_a -> array
+ * lazy.force -> array
+ *
+ * Expands +lazy+ enumerator to an array.
+ * See Enumerable#to_a.
+ */
+static VALUE lazy_to_a(VALUE self)
+{
+}
+#endif
+
static void
lazy_set_args(VALUE lazy, VALUE args)
{
@@ -1584,6 +1811,7 @@ lazy_set_args(VALUE lazy, VALUE args)
}
}
+#if 0
static VALUE
lazy_set_method(VALUE lazy, VALUE args, rb_enumerator_size_func *size_fn)
{
@@ -1592,6 +1820,7 @@ lazy_set_method(VALUE lazy, VALUE args, rb_enumerator_size_func *size_fn)
e->size_fn = size_fn;
return lazy;
}
+#endif
static VALUE
lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
@@ -1637,11 +1866,9 @@ lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
* call-seq:
* e.lazy -> lazy_enumerator
*
- * Returns a lazy enumerator, whose methods map/collect,
- * flat_map/collect_concat, select/find_all, reject, grep, grep_v, zip, take,
- * take_while, drop, and drop_while enumerate values only on an
- * as-needed basis. However, if a block is given to zip, values
- * are enumerated immediately.
+ * Returns an Enumerator::Lazy, which redefines most Enumerable
+ * methods to postpone enumeration and enumerate values only on an
+ * as-needed basis.
*
* === Example
*
@@ -1667,33 +1894,33 @@ lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
static VALUE
enumerable_lazy(VALUE obj)
{
- VALUE result = lazy_to_enum_i(obj, sym_each, 0, 0, lazyenum_size);
+ VALUE result = lazy_to_enum_i(obj, sym_each, 0, 0, lazyenum_size, rb_keyword_given_p());
/* Qfalse indicates that the Enumerator::Lazy has no method name */
rb_ivar_set(result, id_method, Qfalse);
return result;
}
static VALUE
-lazy_to_enum_i(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
+lazy_to_enum_i(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat)
{
return enumerator_init(enumerator_allocate(rb_cLazy),
- obj, meth, argc, argv, size_fn, Qnil);
+ obj, meth, argc, argv, size_fn, Qnil, kw_splat);
}
/*
* call-seq:
- * lzy.to_enum(method = :each, *args) -> lazy_enum
- * lzy.enum_for(method = :each, *args) -> lazy_enum
- * lzy.to_enum(method = :each, *args) {|*args| block} -> lazy_enum
- * lzy.enum_for(method = :each, *args){|*args| block} -> lazy_enum
+ * lzy.to_enum(method = :each, *args) -> lazy_enum
+ * lzy.enum_for(method = :each, *args) -> lazy_enum
+ * lzy.to_enum(method = :each, *args) {|*args| block } -> lazy_enum
+ * lzy.enum_for(method = :each, *args) {|*args| block } -> lazy_enum
*
- * Similar to Kernel#to_enum, except it returns a lazy enumerator.
+ * Similar to Object#to_enum, except it returns a lazy enumerator.
* This makes it easy to define Enumerable methods that will
* naturally remain lazy if called from a lazy enumerator.
*
- * For example, continuing from the example in Kernel#to_enum:
+ * For example, continuing from the example in Object#to_enum:
*
- * # See Kernel#to_enum for the definition of repeat
+ * # See Object#to_enum for the definition of repeat
* r = 1..Float::INFINITY
* r.repeat(2).first(5) # => [1, 1, 2, 2, 3]
* r.repeat(2).class # => Enumerator
@@ -1706,13 +1933,16 @@ lazy_to_enum_i(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator
static VALUE
lazy_to_enum(int argc, VALUE *argv, VALUE self)
{
- VALUE lazy, meth = sym_each;
+ VALUE lazy, meth = sym_each, super_meth;
if (argc > 0) {
--argc;
meth = *argv++;
}
- lazy = lazy_to_enum_i(self, meth, argc, argv, 0);
+ if (RTEST((super_meth = rb_hash_aref(lazy_use_super_method, meth)))) {
+ meth = super_meth;
+ }
+ lazy = lazy_to_enum_i(self, meth, argc, argv, 0, rb_keyword_given_p());
if (rb_block_given_p()) {
enumerator_ptr(lazy)->size = rb_block_proc();
}
@@ -1720,6 +1950,26 @@ lazy_to_enum(int argc, VALUE *argv, VALUE self)
}
static VALUE
+lazy_eager_size(VALUE self, VALUE args, VALUE eobj)
+{
+ return enum_size(self);
+}
+
+/*
+ * call-seq:
+ * lzy.eager -> enum
+ *
+ * Returns a non-lazy Enumerator converted from the lazy enumerator.
+ */
+
+static VALUE
+lazy_eager(VALUE self)
+{
+ return enumerator_init(enumerator_allocate(rb_cEnumerator),
+ self, sym_each, 0, 0, lazy_eager_size, Qnil, 0);
+}
+
+static VALUE
lazyenum_yield(VALUE proc_entry, struct MEMO *result)
{
struct proc_entry *entry = proc_entry_ptr(proc_entry);
@@ -1759,6 +2009,19 @@ static const lazyenum_funcs lazy_map_funcs = {
lazy_map_proc, lazy_map_size,
};
+/*
+ * call-seq:
+ * lazy.collect { |obj| block } -> lazy_enumerator
+ * lazy.map { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#map, but chains operation to be lazy-evaluated.
+ *
+ * (1..Float::INFINITY).lazy.map {|i| i**2 }
+ * #=> #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:map>
+ * (1..Float::INFINITY).lazy.map {|i| i**2 }.first(3)
+ * #=> [1, 4, 9]
+ */
+
static VALUE
lazy_map(VALUE obj)
{
@@ -1769,75 +2032,77 @@ lazy_map(VALUE obj)
return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_map_funcs);
}
-static VALUE
-lazy_flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, yielder))
-{
- return rb_funcallv(yielder, id_yield, argc, argv);
-}
+struct flat_map_i_arg {
+ struct MEMO *result;
+ long index;
+};
static VALUE
-lazy_flat_map_each(VALUE obj, VALUE yielder)
+lazy_flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, y))
{
- rb_block_call(obj, id_each, 0, 0, lazy_flat_map_i, yielder);
- return Qnil;
+ struct flat_map_i_arg *arg = (struct flat_map_i_arg *)y;
+
+ return lazy_yielder_yield(arg->result, arg->index, argc, argv);
}
-static VALUE
-lazy_flat_map_to_ary(VALUE obj, VALUE yielder)
+static struct MEMO *
+lazy_flat_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
- VALUE ary = rb_check_array_type(obj);
- if (NIL_P(ary)) {
- rb_funcall(yielder, id_yield, 1, obj);
+ VALUE value = lazyenum_yield_values(proc_entry, result);
+ VALUE ary = 0;
+ const long proc_index = memo_index + 1;
+ int break_p = LAZY_MEMO_BREAK_P(result);
+
+ if (RB_TYPE_P(value, T_ARRAY)) {
+ ary = value;
}
- else {
- long i;
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- rb_funcall(yielder, id_yield, 1, RARRAY_AREF(ary, i));
- }
+ else if (rb_respond_to(value, id_force) && rb_respond_to(value, id_each)) {
+ struct flat_map_i_arg arg = {.result = result, .index = proc_index};
+ LAZY_MEMO_RESET_BREAK(result);
+ rb_block_call(value, id_each, 0, 0, lazy_flat_map_i, (VALUE)&arg);
+ if (break_p) LAZY_MEMO_SET_BREAK(result);
+ return 0;
}
- return Qnil;
-}
-static VALUE
-lazy_flat_map_proc(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
-{
- VALUE result = rb_yield_values2(argc - 1, &argv[1]);
- if (RB_TYPE_P(result, T_ARRAY)) {
- long i;
- for (i = 0; i < RARRAY_LEN(result); i++) {
- rb_funcall(argv[0], id_yield, 1, RARRAY_AREF(result, i));
- }
- }
- else {
- if (rb_respond_to(result, id_force) && rb_respond_to(result, id_each)) {
- lazy_flat_map_each(result, argv[0]);
- }
- else {
- lazy_flat_map_to_ary(result, argv[0]);
- }
+ if (ary || !NIL_P(ary = rb_check_array_type(value))) {
+ long i;
+ LAZY_MEMO_RESET_BREAK(result);
+ for (i = 0; i + 1 < RARRAY_LEN(ary); i++) {
+ const VALUE argv = RARRAY_AREF(ary, i);
+ lazy_yielder_yield(result, proc_index, 1, &argv);
+ }
+ if (break_p) LAZY_MEMO_SET_BREAK(result);
+ if (i >= RARRAY_LEN(ary)) return 0;
+ value = RARRAY_AREF(ary, i);
}
- return Qnil;
+ LAZY_MEMO_SET_VALUE(result, value);
+ LAZY_MEMO_RESET_PACKED(result);
+ return result;
}
+static const lazyenum_funcs lazy_flat_map_funcs = {
+ lazy_flat_map_proc, 0,
+};
+
/*
* call-seq:
* lazy.collect_concat { |obj| block } -> a_lazy_enumerator
* lazy.flat_map { |obj| block } -> a_lazy_enumerator
*
* Returns a new lazy enumerator with the concatenated results of running
- * <i>block</i> once for every element in <i>lazy</i>.
+ * +block+ once for every element in the lazy enumerator.
*
* ["foo", "bar"].lazy.flat_map {|i| i.each_char.lazy}.force
* #=> ["f", "o", "o", "b", "a", "r"]
*
- * A value <i>x</i> returned by <i>block</i> is decomposed if either of
+ * A value +x+ returned by +block+ is decomposed if either of
* the following conditions is true:
*
- * a) <i>x</i> responds to both each and force, which means that
- * <i>x</i> is a lazy enumerator.
- * b) <i>x</i> is an array or responds to to_ary.
+ * * +x+ responds to both each and force, which means that
+ * +x+ is a lazy enumerator.
+ * * +x+ is an array or responds to to_ary.
*
- * Otherwise, <i>x</i> is contained as-is in the return value.
+ * Otherwise, +x+ is contained as-is in the return value.
*
* [{a:1}, {b:2}].lazy.flat_map {|i| i}.force
* #=> [{:a=>1}, {:b=>2}]
@@ -1849,9 +2114,7 @@ lazy_flat_map(VALUE obj)
rb_raise(rb_eArgError, "tried to call lazy flat_map without a block");
}
- return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
- lazy_flat_map_proc, 0),
- Qnil, 0);
+ return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_flat_map_funcs);
}
static struct MEMO *
@@ -1866,6 +2129,14 @@ static const lazyenum_funcs lazy_select_funcs = {
lazy_select_proc, 0,
};
+/*
+ * call-seq:
+ * lazy.find_all { |obj| block } -> lazy_enumerator
+ * lazy.select { |obj| block } -> lazy_enumerator
+ * lazy.filter { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#select, but chains operation to be lazy-evaluated.
+ */
static VALUE
lazy_select(VALUE obj)
{
@@ -1877,6 +2148,40 @@ lazy_select(VALUE obj)
}
static struct MEMO *
+lazy_filter_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
+{
+ VALUE value = lazyenum_yield_values(proc_entry, result);
+ if (!RTEST(value)) return 0;
+ LAZY_MEMO_SET_VALUE(result, value);
+ LAZY_MEMO_RESET_PACKED(result);
+ return result;
+}
+
+static const lazyenum_funcs lazy_filter_map_funcs = {
+ lazy_filter_map_proc, 0,
+};
+
+/*
+ * call-seq:
+ * lazy.filter_map { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#filter_map, but chains operation to be lazy-evaluated.
+ *
+ * (1..).lazy.filter_map { |i| i * 2 if i.even? }.first(5)
+ * #=> [4, 8, 12, 16, 20]
+ */
+
+static VALUE
+lazy_filter_map(VALUE obj)
+{
+ if (!rb_block_given_p()) {
+ rb_raise(rb_eArgError, "tried to call lazy filter_map without a block");
+ }
+
+ return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_filter_map_funcs);
+}
+
+static struct MEMO *
lazy_reject_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
VALUE chain = lazyenum_yield(proc_entry, result);
@@ -1888,6 +2193,13 @@ static const lazyenum_funcs lazy_reject_funcs = {
lazy_reject_proc, 0,
};
+/*
+ * call-seq:
+ * lazy.reject { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#reject, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_reject(VALUE obj)
{
@@ -1929,6 +2241,14 @@ static const lazyenum_funcs lazy_grep_funcs = {
lazy_grep_proc, 0,
};
+/*
+ * call-seq:
+ * lazy.grep(pattern) -> lazy_enumerator
+ * lazy.grep(pattern) { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#grep, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_grep(VALUE obj, VALUE pattern)
{
@@ -1937,38 +2257,51 @@ lazy_grep(VALUE obj, VALUE pattern)
return lazy_add_method(obj, 0, 0, pattern, rb_ary_new3(1, pattern), funcs);
}
-static VALUE
-lazy_grep_v_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
+static struct MEMO *
+lazy_grep_v_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
- VALUE i = rb_enum_values_pack(argc - 1, argv + 1);
- VALUE result = rb_funcall(m, id_eqq, 1, i);
-
- if (!RTEST(result)) {
- rb_funcall(argv[0], id_yield, 1, i);
- }
- return Qnil;
+ struct proc_entry *entry = proc_entry_ptr(proc_entry);
+ VALUE chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
+ if (RTEST(chain)) return 0;
+ return result;
}
-static VALUE
-lazy_grep_v_iter(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
+static struct MEMO *
+lazy_grep_v_iter_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
- VALUE i = rb_enum_values_pack(argc - 1, argv + 1);
- VALUE result = rb_funcall(m, id_eqq, 1, i);
+ struct proc_entry *entry = proc_entry_ptr(proc_entry);
+ VALUE value, chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
- if (!RTEST(result)) {
- rb_funcall(argv[0], id_yield, 1, rb_yield(i));
- }
- return Qnil;
+ if (RTEST(chain)) return 0;
+ value = rb_proc_call_with_block(entry->proc, 1, &(result->memo_value), Qnil);
+ LAZY_MEMO_SET_VALUE(result, value);
+ LAZY_MEMO_RESET_PACKED(result);
+
+ return result;
}
+static const lazyenum_funcs lazy_grep_v_iter_funcs = {
+ lazy_grep_v_iter_proc, 0,
+};
+
+static const lazyenum_funcs lazy_grep_v_funcs = {
+ lazy_grep_v_proc, 0,
+};
+
+/*
+ * call-seq:
+ * lazy.grep_v(pattern) -> lazy_enumerator
+ * lazy.grep_v(pattern) { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#grep_v, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_grep_v(VALUE obj, VALUE pattern)
{
- return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
- rb_block_given_p() ?
- lazy_grep_v_iter : lazy_grep_v_func,
- pattern),
- rb_ary_new3(1, pattern), 0);
+ const lazyenum_funcs *const funcs = rb_block_given_p() ?
+ &lazy_grep_v_iter_funcs : &lazy_grep_v_funcs;
+ return lazy_add_method(obj, 0, 0, pattern, rb_ary_new3(1, pattern), funcs);
}
static VALUE
@@ -1978,69 +2311,78 @@ call_next(VALUE obj)
}
static VALUE
-next_stopped(VALUE obj)
+next_stopped(VALUE obj, VALUE _)
{
return Qnil;
}
-static VALUE
-lazy_zip_arrays_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, arrays))
+static struct MEMO *
+lazy_zip_arrays_func(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
- VALUE yielder, ary, memo;
- long i, count;
-
- yielder = argv[0];
- memo = rb_attr_get(yielder, id_memo);
- count = NIL_P(memo) ? 0 : NUM2LONG(memo);
+ struct proc_entry *entry = proc_entry_ptr(proc_entry);
+ VALUE ary, arrays = entry->memo;
+ VALUE memo = rb_ary_entry(memos, memo_index);
+ long i, count = NIL_P(memo) ? 0 : NUM2LONG(memo);
ary = rb_ary_new2(RARRAY_LEN(arrays) + 1);
- rb_ary_push(ary, argv[1]);
+ rb_ary_push(ary, result->memo_value);
for (i = 0; i < RARRAY_LEN(arrays); i++) {
rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
}
- rb_funcall(yielder, id_yield, 1, ary);
- rb_ivar_set(yielder, id_memo, LONG2NUM(++count));
- return Qnil;
+ LAZY_MEMO_SET_VALUE(result, ary);
+ LAZY_MEMO_SET_PACKED(result);
+ rb_ary_store(memos, memo_index, LONG2NUM(++count));
+ return result;
}
-static VALUE
-lazy_zip_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, zip_args))
+static struct MEMO *
+lazy_zip_func(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
- VALUE yielder, ary, arg, v;
+ struct proc_entry *entry = proc_entry_ptr(proc_entry);
+ VALUE arg = rb_ary_entry(memos, memo_index);
+ VALUE zip_args = entry->memo;
+ VALUE ary, v;
long i;
- yielder = argv[0];
- arg = rb_attr_get(yielder, id_memo);
if (NIL_P(arg)) {
arg = rb_ary_new2(RARRAY_LEN(zip_args));
for (i = 0; i < RARRAY_LEN(zip_args); i++) {
rb_ary_push(arg, rb_funcall(RARRAY_AREF(zip_args, i), id_to_enum, 0));
}
- rb_ivar_set(yielder, id_memo, arg);
+ rb_ary_store(memos, memo_index, arg);
}
ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
- v = Qnil;
- if (--argc > 0) {
- ++argv;
- v = argc > 1 ? rb_ary_new_from_values(argc, argv) : *argv;
- }
- rb_ary_push(ary, v);
+ rb_ary_push(ary, result->memo_value);
for (i = 0; i < RARRAY_LEN(arg); i++) {
v = rb_rescue2(call_next, RARRAY_AREF(arg, i), next_stopped, 0,
rb_eStopIteration, (VALUE)0);
rb_ary_push(ary, v);
}
- rb_funcall(yielder, id_yield, 1, ary);
- return Qnil;
+ LAZY_MEMO_SET_VALUE(result, ary);
+ LAZY_MEMO_SET_PACKED(result);
+ return result;
}
+static const lazyenum_funcs lazy_zip_funcs[] = {
+ {lazy_zip_func, lazy_receiver_size,},
+ {lazy_zip_arrays_func, lazy_receiver_size,},
+};
+
+/*
+ * call-seq:
+ * lazy.zip(arg, ...) -> lazy_enumerator
+ * lazy.zip(arg, ...) { |arr| block } -> nil
+ *
+ * Like Enumerable#zip, but chains operation to be lazy-evaluated.
+ * However, if a block is given to zip, values are enumerated immediately.
+ */
static VALUE
lazy_zip(int argc, VALUE *argv, VALUE obj)
{
VALUE ary, v;
long i;
- rb_block_call_func *func = lazy_zip_arrays_func;
+ const lazyenum_funcs *funcs = &lazy_zip_funcs[1];
if (rb_block_given_p()) {
return rb_call_super(argc, argv);
@@ -2057,15 +2399,13 @@ lazy_zip(int argc, VALUE *argv, VALUE obj)
}
}
ary = rb_ary_new4(argc, argv);
- func = lazy_zip_func;
+ funcs = &lazy_zip_funcs[0];
break;
}
rb_ary_push(ary, v);
}
- return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
- func, ary),
- ary, lazy_receiver_size);
+ return lazy_add_method(obj, 0, 0, ary, ary, funcs);
}
static struct MEMO *
@@ -2103,6 +2443,13 @@ static const lazyenum_funcs lazy_take_funcs = {
lazy_take_proc, lazy_take_size,
};
+/*
+ * call-seq:
+ * lazy.take(n) -> lazy_enumerator
+ *
+ * Like Enumerable#take, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_take(VALUE obj, VALUE n)
{
@@ -2138,6 +2485,13 @@ static const lazyenum_funcs lazy_take_while_funcs = {
lazy_take_while_proc, 0,
};
+/*
+ * call-seq:
+ * lazy.take_while { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#take_while, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_take_while(VALUE obj)
{
@@ -2185,6 +2539,13 @@ static const lazyenum_funcs lazy_drop_funcs = {
lazy_drop_proc, lazy_drop_size,
};
+/*
+ * call-seq:
+ * lazy.drop(n) -> lazy_enumerator
+ *
+ * Like Enumerable#drop, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_drop(VALUE obj, VALUE n)
{
@@ -2222,6 +2583,13 @@ static const lazyenum_funcs lazy_drop_while_funcs = {
lazy_drop_while_proc, 0,
};
+/*
+ * call-seq:
+ * lazy.drop_while { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#drop_while, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_drop_while(VALUE obj)
{
@@ -2232,47 +2600,189 @@ lazy_drop_while(VALUE obj)
return lazy_add_method(obj, 0, 0, Qfalse, Qnil, &lazy_drop_while_funcs);
}
-static VALUE
-lazy_uniq_i(VALUE i, VALUE hash, int argc, const VALUE *argv, VALUE yielder)
+static int
+lazy_uniq_check(VALUE chain, VALUE memos, long memo_index)
{
- if (rb_hash_add_new_element(hash, i, Qfalse))
- return Qnil;
- return rb_funcallv(yielder, id_yield, argc, argv);
+ VALUE hash = rb_ary_entry(memos, memo_index);
+
+ if (NIL_P(hash)) {
+ hash = rb_obj_hide(rb_hash_new());
+ rb_ary_store(memos, memo_index, hash);
+ }
+
+ return rb_hash_add_new_element(hash, chain, Qfalse);
}
-static VALUE
-lazy_uniq_func(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+static struct MEMO *
+lazy_uniq_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
- VALUE yielder = (--argc, *argv++);
- i = rb_enum_values_pack(argc, argv);
- return lazy_uniq_i(i, hash, argc, argv, yielder);
+ if (lazy_uniq_check(result->memo_value, memos, memo_index)) return 0;
+ return result;
}
-static VALUE
-lazy_uniq_iter(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+static struct MEMO *
+lazy_uniq_iter_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
- VALUE yielder = (--argc, *argv++);
- i = rb_yield_values2(argc, argv);
- return lazy_uniq_i(i, hash, argc, argv, yielder);
+ VALUE chain = lazyenum_yield(proc_entry, result);
+
+ if (lazy_uniq_check(chain, memos, memo_index)) return 0;
+ return result;
}
+static const lazyenum_funcs lazy_uniq_iter_funcs = {
+ lazy_uniq_iter_proc, 0,
+};
+
+static const lazyenum_funcs lazy_uniq_funcs = {
+ lazy_uniq_proc, 0,
+};
+
+/*
+ * call-seq:
+ * lazy.uniq -> lazy_enumerator
+ * lazy.uniq { |item| block } -> lazy_enumerator
+ *
+ * Like Enumerable#uniq, but chains operation to be lazy-evaluated.
+ */
+
static VALUE
lazy_uniq(VALUE obj)
{
- rb_block_call_func *const func =
- rb_block_given_p() ? lazy_uniq_iter : lazy_uniq_func;
- VALUE hash = rb_obj_hide(rb_hash_new());
- return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
- func, hash),
- 0, 0);
+ const lazyenum_funcs *const funcs =
+ rb_block_given_p() ? &lazy_uniq_iter_funcs : &lazy_uniq_funcs;
+ return lazy_add_method(obj, 0, 0, Qnil, Qnil, funcs);
+}
+
+static struct MEMO *
+lazy_with_index_proc(VALUE proc_entry, struct MEMO* result, VALUE memos, long memo_index)
+{
+ struct proc_entry *entry = proc_entry_ptr(proc_entry);
+ VALUE memo = rb_ary_entry(memos, memo_index);
+ VALUE argv[2];
+
+ if (NIL_P(memo)) {
+ memo = entry->memo;
+ }
+
+ argv[0] = result->memo_value;
+ argv[1] = memo;
+ if (entry->proc) {
+ rb_proc_call_with_block(entry->proc, 2, argv, Qnil);
+ LAZY_MEMO_RESET_PACKED(result);
+ }
+ else {
+ LAZY_MEMO_SET_VALUE(result, rb_ary_new_from_values(2, argv));
+ LAZY_MEMO_SET_PACKED(result);
+ }
+ rb_ary_store(memos, memo_index, LONG2NUM(NUM2LONG(memo) + 1));
+ return result;
}
static VALUE
+lazy_with_index_size(VALUE proc, VALUE receiver) {
+ return receiver;
+}
+
+static const lazyenum_funcs lazy_with_index_funcs = {
+ lazy_with_index_proc, lazy_with_index_size,
+};
+
+/*
+ * call-seq:
+ * lazy.with_index(offset = 0) {|(*args), idx| block }
+ * lazy.with_index(offset = 0)
+ *
+ * If a block is given, iterates the given block for each element
+ * with an index, which starts from +offset+, and returns a
+ * lazy enumerator that yields the same values (without the index).
+ *
+ * If a block is not given, returns a new lazy enumerator that
+ * includes the index, starting from +offset+.
+ *
+ * +offset+:: the starting index to use
+ *
+ * See Enumerator#with_index.
+ */
+static VALUE
+lazy_with_index(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE memo;
+
+ rb_scan_args(argc, argv, "01", &memo);
+ if (NIL_P(memo))
+ memo = LONG2NUM(0);
+
+ return lazy_add_method(obj, 0, 0, memo, rb_ary_new_from_values(1, &memo), &lazy_with_index_funcs);
+}
+
+#if 0 /* for RDoc */
+
+/*
+ * call-seq:
+ * lazy.chunk { |elt| ... } -> lazy_enumerator
+ *
+ * Like Enumerable#chunk, but chains operation to be lazy-evaluated.
+ */
+static VALUE lazy_chunk(VALUE self)
+{
+}
+
+/*
+ * call-seq:
+ * lazy.chunk_while {|elt_before, elt_after| bool } -> lazy_enumerator
+ *
+ * Like Enumerable#chunk_while, but chains operation to be lazy-evaluated.
+ */
+static VALUE lazy_chunk_while(VALUE self)
+{
+}
+
+/*
+ * call-seq:
+ * lazy.slice_after(pattern) -> lazy_enumerator
+ * lazy.slice_after { |elt| bool } -> lazy_enumerator
+ *
+ * Like Enumerable#slice_after, but chains operation to be lazy-evaluated.
+ */
+static VALUE lazy_slice_after(VALUE self)
+{
+}
+
+/*
+ * call-seq:
+ * lazy.slice_before(pattern) -> lazy_enumerator
+ * lazy.slice_before { |elt| bool } -> lazy_enumerator
+ *
+ * Like Enumerable#slice_before, but chains operation to be lazy-evaluated.
+ */
+static VALUE lazy_slice_before(VALUE self)
+{
+}
+
+/*
+ * call-seq:
+ * lazy.slice_when {|elt_before, elt_after| bool } -> lazy_enumerator
+ *
+ * Like Enumerable#slice_when, but chains operation to be lazy-evaluated.
+ */
+static VALUE lazy_slice_when(VALUE self)
+{
+}
+# endif
+
+static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
+/*
+ * call-seq:
+ * enum.lazy -> lazy_enumerator
+ *
+ * Returns self.
+ */
+
static VALUE
lazy_lazy(VALUE obj)
{
@@ -2332,9 +2842,1174 @@ stop_result(VALUE self)
return rb_attr_get(self, id_result);
}
+/*
+ * Producer
+ */
+
+static void
+producer_mark(void *p)
+{
+ struct producer *ptr = p;
+ rb_gc_mark_movable(ptr->init);
+ rb_gc_mark_movable(ptr->proc);
+}
+
+static void
+producer_compact(void *p)
+{
+ struct producer *ptr = p;
+ ptr->init = rb_gc_location(ptr->init);
+ ptr->proc = rb_gc_location(ptr->proc);
+}
+
+#define producer_free RUBY_TYPED_DEFAULT_FREE
+
+static size_t
+producer_memsize(const void *p)
+{
+ return sizeof(struct producer);
+}
+
+static const rb_data_type_t producer_data_type = {
+ "producer",
+ {
+ producer_mark,
+ producer_free,
+ producer_memsize,
+ producer_compact,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static struct producer *
+producer_ptr(VALUE obj)
+{
+ struct producer *ptr;
+
+ TypedData_Get_Struct(obj, struct producer, &producer_data_type, ptr);
+ if (!ptr || ptr->proc == Qundef) {
+ rb_raise(rb_eArgError, "uninitialized producer");
+ }
+ return ptr;
+}
+
+/* :nodoc: */
+static VALUE
+producer_allocate(VALUE klass)
+{
+ struct producer *ptr;
+ VALUE obj;
+
+ obj = TypedData_Make_Struct(klass, struct producer, &producer_data_type, ptr);
+ ptr->init = Qundef;
+ ptr->proc = Qundef;
+
+ return obj;
+}
+
+static VALUE
+producer_init(VALUE obj, VALUE init, VALUE proc)
+{
+ struct producer *ptr;
+
+ TypedData_Get_Struct(obj, struct producer, &producer_data_type, ptr);
+
+ if (!ptr) {
+ rb_raise(rb_eArgError, "unallocated producer");
+ }
+
+ ptr->init = init;
+ ptr->proc = proc;
+
+ return obj;
+}
+
+static VALUE
+producer_each_stop(VALUE dummy, VALUE exc)
+{
+ return rb_attr_get(exc, id_result);
+}
+
+NORETURN(static VALUE producer_each_i(VALUE obj));
+
+static VALUE
+producer_each_i(VALUE obj)
+{
+ struct producer *ptr;
+ VALUE init, proc, curr;
+
+ ptr = producer_ptr(obj);
+ init = ptr->init;
+ proc = ptr->proc;
+
+ if (init == Qundef) {
+ curr = Qnil;
+ }
+ else {
+ rb_yield(init);
+ curr = init;
+ }
+
+ for (;;) {
+ curr = rb_funcall(proc, id_call, 1, curr);
+ rb_yield(curr);
+ }
+
+ UNREACHABLE_RETURN(Qnil);
+}
+
+/* :nodoc: */
+static VALUE
+producer_each(VALUE obj)
+{
+ rb_need_block();
+
+ return rb_rescue2(producer_each_i, obj, producer_each_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
+}
+
+static VALUE
+producer_size(VALUE obj, VALUE args, VALUE eobj)
+{
+ return DBL2NUM(HUGE_VAL);
+}
+
+/*
+ * call-seq:
+ * Enumerator.produce(initial = nil) { |prev| block } -> enumerator
+ *
+ * Creates an infinite enumerator from any block, just called over and
+ * over. The 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,
+ * the first iteration receives +nil+, and its result becomes the first
+ * element of the iterator.
+ *
+ * Raising StopIteration from the block stops an iteration.
+ *
+ * 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 }
+ *
+ * Using ::produce together with Enumerable methods like Enumerable#detect,
+ * Enumerable#slice_after, Enumerable#take_while can provide Enumerator-based alternatives
+ * for +while+ and +until+ cycles:
+ *
+ * # Find next Tuesday
+ * require "date"
+ * Enumerator.produce(Date.today, &:succ).detect(&:tuesday?)
+ *
+ * # Simple lexer:
+ * require "strscan"
+ * scanner = StringScanner.new("7+38/6")
+ * PATTERN = %r{\d+|[-/+*]}
+ * Enumerator.produce { scanner.scan(PATTERN) }.slice_after { scanner.eos? }.first
+ * # => ["7", "+", "38", "/", "6"]
+ */
+static VALUE
+enumerator_s_produce(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE init, producer;
+
+ if (!rb_block_given_p()) rb_raise(rb_eArgError, "no block given");
+
+ if (rb_scan_args(argc, argv, "01", &init) == 0) {
+ init = Qundef;
+ }
+
+ producer = producer_init(producer_allocate(rb_cEnumProducer), init, rb_block_proc());
+
+ return rb_enumeratorize_with_size_kw(producer, sym_each, 0, 0, producer_size, RB_NO_KEYWORDS);
+}
+
+/*
+ * Document-class: Enumerator::Chain
+ *
+ * Enumerator::Chain is a subclass of Enumerator, which represents a
+ * chain of enumerables that works as a single enumerator.
+ *
+ * This type of objects can be created by Enumerable#chain and
+ * Enumerator#+.
+ */
+
+static void
+enum_chain_mark(void *p)
+{
+ struct enum_chain *ptr = p;
+ rb_gc_mark_movable(ptr->enums);
+}
+
+static void
+enum_chain_compact(void *p)
+{
+ struct enum_chain *ptr = p;
+ ptr->enums = rb_gc_location(ptr->enums);
+}
+
+#define enum_chain_free RUBY_TYPED_DEFAULT_FREE
+
+static size_t
+enum_chain_memsize(const void *p)
+{
+ return sizeof(struct enum_chain);
+}
+
+static const rb_data_type_t enum_chain_data_type = {
+ "chain",
+ {
+ enum_chain_mark,
+ enum_chain_free,
+ enum_chain_memsize,
+ enum_chain_compact,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static struct enum_chain *
+enum_chain_ptr(VALUE obj)
+{
+ struct enum_chain *ptr;
+
+ TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr);
+ if (!ptr || ptr->enums == Qundef) {
+ rb_raise(rb_eArgError, "uninitialized chain");
+ }
+ return ptr;
+}
+
+/* :nodoc: */
+static VALUE
+enum_chain_allocate(VALUE klass)
+{
+ struct enum_chain *ptr;
+ VALUE obj;
+
+ obj = TypedData_Make_Struct(klass, struct enum_chain, &enum_chain_data_type, ptr);
+ ptr->enums = Qundef;
+ ptr->pos = -1;
+
+ return obj;
+}
+
+/*
+ * call-seq:
+ * Enumerator::Chain.new(*enums) -> enum
+ *
+ * Generates a new enumerator object that iterates over the elements
+ * of given enumerable objects in sequence.
+ *
+ * e = Enumerator::Chain.new(1..3, [4, 5])
+ * e.to_a #=> [1, 2, 3, 4, 5]
+ * e.size #=> 5
+ */
+static VALUE
+enum_chain_initialize(VALUE obj, VALUE enums)
+{
+ struct enum_chain *ptr;
+
+ rb_check_frozen(obj);
+ TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr);
+
+ if (!ptr) rb_raise(rb_eArgError, "unallocated chain");
+
+ ptr->enums = rb_obj_freeze(enums);
+ ptr->pos = -1;
+
+ return obj;
+}
+
+/* :nodoc: */
+static VALUE
+enum_chain_init_copy(VALUE obj, VALUE orig)
+{
+ struct enum_chain *ptr0, *ptr1;
+
+ if (!OBJ_INIT_COPY(obj, orig)) return obj;
+ ptr0 = enum_chain_ptr(orig);
+
+ TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr1);
+
+ if (!ptr1) rb_raise(rb_eArgError, "unallocated chain");
+
+ ptr1->enums = ptr0->enums;
+ ptr1->pos = ptr0->pos;
+
+ return obj;
+}
+
+static VALUE
+enum_chain_total_size(VALUE enums)
+{
+ VALUE total = INT2FIX(0);
+ long i;
+
+ for (i = 0; i < RARRAY_LEN(enums); i++) {
+ VALUE size = enum_size(RARRAY_AREF(enums, i));
+
+ if (NIL_P(size) || (RB_TYPE_P(size, T_FLOAT) && isinf(NUM2DBL(size)))) {
+ return size;
+ }
+ if (!RB_INTEGER_TYPE_P(size)) {
+ return Qnil;
+ }
+
+ total = rb_funcall(total, '+', 1, size);
+ }
+
+ return total;
+}
+
+/*
+ * call-seq:
+ * obj.size -> int, Float::INFINITY or nil
+ *
+ * Returns the total size of the enumerator chain calculated by
+ * summing up the size of each enumerable in the chain. If any of the
+ * enumerables reports its size as nil or Float::INFINITY, that value
+ * is returned as the total size.
+ */
+static VALUE
+enum_chain_size(VALUE obj)
+{
+ return enum_chain_total_size(enum_chain_ptr(obj)->enums);
+}
+
+static VALUE
+enum_chain_enum_size(VALUE obj, VALUE args, VALUE eobj)
+{
+ return enum_chain_size(obj);
+}
+
+static VALUE
+enum_chain_enum_no_size(VALUE obj, VALUE args, VALUE eobj)
+{
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * obj.each(*args) { |...| ... } -> obj
+ * obj.each(*args) -> enumerator
+ *
+ * Iterates over the elements of the first enumerable by calling the
+ * "each" method on it with the given arguments, then proceeds to the
+ * following enumerables in sequence until all of the enumerables are
+ * exhausted.
+ *
+ * If no block is given, returns an enumerator.
+ */
+static VALUE
+enum_chain_each(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE enums, block;
+ struct enum_chain *objptr;
+ long i;
+
+ RETURN_SIZED_ENUMERATOR(obj, argc, argv, argc > 0 ? enum_chain_enum_no_size : enum_chain_enum_size);
+
+ objptr = enum_chain_ptr(obj);
+ enums = objptr->enums;
+ block = rb_block_proc();
+
+ for (i = 0; i < RARRAY_LEN(enums); i++) {
+ objptr->pos = i;
+ rb_funcall_with_block(RARRAY_AREF(enums, i), id_each, argc, argv, block);
+ }
+
+ return obj;
+}
+
+/*
+ * call-seq:
+ * obj.rewind -> obj
+ *
+ * Rewinds the enumerator chain by calling the "rewind" method on each
+ * enumerable in reverse order. Each call is performed only if the
+ * enumerable responds to the method.
+ */
+static VALUE
+enum_chain_rewind(VALUE obj)
+{
+ struct enum_chain *objptr = enum_chain_ptr(obj);
+ VALUE enums = objptr->enums;
+ long i;
+
+ for (i = objptr->pos; 0 <= i && i < RARRAY_LEN(enums); objptr->pos = --i) {
+ rb_check_funcall(RARRAY_AREF(enums, i), id_rewind, 0, 0);
+ }
+
+ return obj;
+}
+
+static VALUE
+inspect_enum_chain(VALUE obj, VALUE dummy, int recur)
+{
+ VALUE klass = rb_obj_class(obj);
+ struct enum_chain *ptr;
+
+ TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr);
+
+ if (!ptr || ptr->enums == Qundef) {
+ return rb_sprintf("#<%"PRIsVALUE": uninitialized>", rb_class_path(klass));
+ }
+
+ if (recur) {
+ return rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(klass));
+ }
+
+ return rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE">", rb_class_path(klass), ptr->enums);
+}
+
+/*
+ * call-seq:
+ * obj.inspect -> string
+ *
+ * Returns a printable version of the enumerator chain.
+ */
+static VALUE
+enum_chain_inspect(VALUE obj)
+{
+ return rb_exec_recursive(inspect_enum_chain, obj, 0);
+}
+
+/*
+ * call-seq:
+ * e.chain(*enums) -> enumerator
+ *
+ * Returns an enumerator object generated from this enumerator and
+ * given enumerables.
+ *
+ * e = (1..3).chain([4, 5])
+ * e.to_a #=> [1, 2, 3, 4, 5]
+ */
+static VALUE
+enum_chain(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE enums = rb_ary_new_from_values(1, &obj);
+ rb_ary_cat(enums, argv, argc);
+
+ return enum_chain_initialize(enum_chain_allocate(rb_cEnumChain), enums);
+}
+
+/*
+ * call-seq:
+ * e + enum -> enumerator
+ *
+ * Returns an enumerator object generated from this enumerator and a
+ * given enumerable.
+ *
+ * e = (1..3).each + [4, 5]
+ * e.to_a #=> [1, 2, 3, 4, 5]
+ */
+static VALUE
+enumerator_plus(VALUE obj, VALUE eobj)
+{
+ VALUE enums = rb_ary_new_from_args(2, obj, eobj);
+
+ return enum_chain_initialize(enum_chain_allocate(rb_cEnumChain), enums);
+}
+
+/*
+ * Document-class: Enumerator::ArithmeticSequence
+ *
+ * Enumerator::ArithmeticSequence is a subclass of Enumerator,
+ * that is a representation of sequences of numbers with common difference.
+ * Instances of this class can be generated by the Range#step and Numeric#step
+ * methods.
+ *
+ * The class can be used for slicing Array (see Array#slice) or custom
+ * collections.
+ */
+
+VALUE
+rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv,
+ rb_enumerator_size_func *size_fn,
+ VALUE beg, VALUE end, VALUE step, int excl)
+{
+ VALUE aseq = enumerator_init(enumerator_allocate(rb_cArithSeq),
+ obj, meth, argc, argv, size_fn, Qnil, rb_keyword_given_p());
+ rb_ivar_set(aseq, id_begin, beg);
+ rb_ivar_set(aseq, id_end, end);
+ rb_ivar_set(aseq, id_step, step);
+ rb_ivar_set(aseq, id_exclude_end, excl ? Qtrue : Qfalse);
+ return aseq;
+}
+
+/*
+ * call-seq: aseq.begin -> num or nil
+ *
+ * Returns the number that defines the first element of this arithmetic
+ * sequence.
+ */
+static inline VALUE
+arith_seq_begin(VALUE self)
+{
+ return rb_ivar_get(self, id_begin);
+}
+
+/*
+ * call-seq: aseq.end -> num or nil
+ *
+ * Returns the number that defines the end of this arithmetic sequence.
+ */
+static inline VALUE
+arith_seq_end(VALUE self)
+{
+ return rb_ivar_get(self, id_end);
+}
+
+/*
+ * call-seq: aseq.step -> num
+ *
+ * Returns the number that defines the common difference between
+ * two adjacent elements in this arithmetic sequence.
+ */
+static inline VALUE
+arith_seq_step(VALUE self)
+{
+ return rb_ivar_get(self, id_step);
+}
+
+/*
+ * call-seq: aseq.exclude_end? -> true or false
+ *
+ * Returns <code>true</code> if this arithmetic sequence excludes its end value.
+ */
+static inline VALUE
+arith_seq_exclude_end(VALUE self)
+{
+ return rb_ivar_get(self, id_exclude_end);
+}
+
+static inline int
+arith_seq_exclude_end_p(VALUE self)
+{
+ return RTEST(arith_seq_exclude_end(self));
+}
+
+int
+rb_arithmetic_sequence_extract(VALUE obj, rb_arithmetic_sequence_components_t *component)
+{
+ if (rb_obj_is_kind_of(obj, rb_cArithSeq)) {
+ component->begin = arith_seq_begin(obj);
+ component->end = arith_seq_end(obj);
+ component->step = arith_seq_step(obj);
+ component->exclude_end = arith_seq_exclude_end_p(obj);
+ return 1;
+ }
+ else if (rb_range_values(obj, &component->begin, &component->end, &component->exclude_end)) {
+ component->step = INT2FIX(1);
+ return 1;
+ }
+
+ return 0;
+}
+
+VALUE
+rb_arithmetic_sequence_beg_len_step(VALUE obj, long *begp, long *lenp, long *stepp, long len, int err)
+{
+ RUBY_ASSERT(begp != NULL);
+ RUBY_ASSERT(lenp != NULL);
+ RUBY_ASSERT(stepp != NULL);
+
+ rb_arithmetic_sequence_components_t aseq;
+ if (!rb_arithmetic_sequence_extract(obj, &aseq)) {
+ return Qfalse;
+ }
+
+ long step = NIL_P(aseq.step) ? 1 : NUM2LONG(aseq.step);
+ *stepp = step;
+
+ if (step < 0) {
+ VALUE tmp = aseq.begin;
+ aseq.begin = aseq.end;
+ aseq.end = tmp;
+ }
+
+ if (err == 0 && (step < -1 || step > 1)) {
+ if (rb_range_component_beg_len(aseq.begin, aseq.end, aseq.exclude_end, begp, lenp, len, 1) == Qtrue) {
+ if (*begp > len)
+ goto out_of_range;
+ if (*lenp > len)
+ goto out_of_range;
+ return Qtrue;
+ }
+ }
+ else {
+ return rb_range_component_beg_len(aseq.begin, aseq.end, aseq.exclude_end, begp, lenp, len, err);
+ }
+
+ out_of_range:
+ rb_raise(rb_eRangeError, "%+"PRIsVALUE" out of range", obj);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * aseq.first -> num or nil
+ * aseq.first(n) -> an_array
+ *
+ * Returns the first number in this arithmetic sequence,
+ * or an array of the first +n+ elements.
+ */
+static VALUE
+arith_seq_first(int argc, VALUE *argv, VALUE self)
+{
+ VALUE b, e, s, ary;
+ long n;
+ int x;
+
+ rb_check_arity(argc, 0, 1);
+
+ b = arith_seq_begin(self);
+ e = arith_seq_end(self);
+ s = arith_seq_step(self);
+ if (argc == 0) {
+ if (NIL_P(b)) {
+ return Qnil;
+ }
+ if (!NIL_P(e)) {
+ VALUE zero = INT2FIX(0);
+ int r = rb_cmpint(rb_num_coerce_cmp(s, zero, idCmp), s, zero);
+ if (r > 0 && RTEST(rb_funcall(b, '>', 1, e))) {
+ return Qnil;
+ }
+ if (r < 0 && RTEST(rb_funcall(b, '<', 1, e))) {
+ return Qnil;
+ }
+ }
+ return b;
+ }
+
+ // TODO: the following code should be extracted as arith_seq_take
+
+ n = NUM2LONG(argv[0]);
+ if (n < 0) {
+ rb_raise(rb_eArgError, "attempt to take negative size");
+ }
+ if (n == 0) {
+ return rb_ary_new_capa(0);
+ }
+
+ x = arith_seq_exclude_end_p(self);
+
+ if (FIXNUM_P(b) && NIL_P(e) && FIXNUM_P(s)) {
+ long i = FIX2LONG(b), unit = FIX2LONG(s);
+ ary = rb_ary_new_capa(n);
+ while (n > 0 && FIXABLE(i)) {
+ rb_ary_push(ary, LONG2FIX(i));
+ i += unit; // FIXABLE + FIXABLE never overflow;
+ --n;
+ }
+ if (n > 0) {
+ b = LONG2NUM(i);
+ while (n > 0) {
+ rb_ary_push(ary, b);
+ b = rb_big_plus(b, s);
+ --n;
+ }
+ }
+ return ary;
+ }
+ else if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(s)) {
+ long i = FIX2LONG(b);
+ long end = FIX2LONG(e);
+ long unit = FIX2LONG(s);
+ long len;
+
+ if (unit >= 0) {
+ if (!x) end += 1;
+
+ len = end - i;
+ if (len < 0) len = 0;
+ ary = rb_ary_new_capa((n < len) ? n : len);
+ while (n > 0 && i < end) {
+ rb_ary_push(ary, LONG2FIX(i));
+ if (i + unit < i) break;
+ i += unit;
+ --n;
+ }
+ }
+ else {
+ if (!x) end -= 1;
+
+ len = i - end;
+ if (len < 0) len = 0;
+ ary = rb_ary_new_capa((n < len) ? n : len);
+ while (n > 0 && i > end) {
+ rb_ary_push(ary, LONG2FIX(i));
+ if (i + unit > i) break;
+ i += unit;
+ --n;
+ }
+ }
+ return ary;
+ }
+ else if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {
+ /* generate values like ruby_float_step */
+
+ double unit = NUM2DBL(s);
+ double beg = NUM2DBL(b);
+ double end = NIL_P(e) ? (unit < 0 ? -1 : 1)*HUGE_VAL : NUM2DBL(e);
+ double len = ruby_float_step_size(beg, end, unit, x);
+ long i;
+
+ if (n > len)
+ n = (long)len;
+
+ if (isinf(unit)) {
+ if (len > 0) {
+ ary = rb_ary_new_capa(1);
+ rb_ary_push(ary, DBL2NUM(beg));
+ }
+ else {
+ ary = rb_ary_new_capa(0);
+ }
+ }
+ else if (unit == 0) {
+ VALUE val = DBL2NUM(beg);
+ ary = rb_ary_new_capa(n);
+ for (i = 0; i < len; ++i) {
+ rb_ary_push(ary, val);
+ }
+ }
+ else {
+ ary = rb_ary_new_capa(n);
+ for (i = 0; i < n; ++i) {
+ double d = i*unit+beg;
+ if (unit >= 0 ? end < d : d < end) d = end;
+ rb_ary_push(ary, DBL2NUM(d));
+ }
+ }
+
+ return ary;
+ }
+
+ return rb_call_super(argc, argv);
+}
+
+static inline VALUE
+num_plus(VALUE a, VALUE b)
+{
+ if (RB_INTEGER_TYPE_P(a)) {
+ return rb_int_plus(a, b);
+ }
+ else if (RB_FLOAT_TYPE_P(a)) {
+ return rb_float_plus(a, b);
+ }
+ else if (RB_TYPE_P(a, T_RATIONAL)) {
+ return rb_rational_plus(a, b);
+ }
+ else {
+ return rb_funcallv(a, '+', 1, &b);
+ }
+}
+
+static inline VALUE
+num_minus(VALUE a, VALUE b)
+{
+ if (RB_INTEGER_TYPE_P(a)) {
+ return rb_int_minus(a, b);
+ }
+ else if (RB_FLOAT_TYPE_P(a)) {
+ return rb_float_minus(a, b);
+ }
+ else if (RB_TYPE_P(a, T_RATIONAL)) {
+ return rb_rational_minus(a, b);
+ }
+ else {
+ return rb_funcallv(a, '-', 1, &b);
+ }
+}
+
+static inline VALUE
+num_mul(VALUE a, VALUE b)
+{
+ if (RB_INTEGER_TYPE_P(a)) {
+ return rb_int_mul(a, b);
+ }
+ else if (RB_FLOAT_TYPE_P(a)) {
+ return rb_float_mul(a, b);
+ }
+ else if (RB_TYPE_P(a, T_RATIONAL)) {
+ return rb_rational_mul(a, b);
+ }
+ else {
+ return rb_funcallv(a, '*', 1, &b);
+ }
+}
+
+static inline VALUE
+num_idiv(VALUE a, VALUE b)
+{
+ VALUE q;
+ if (RB_INTEGER_TYPE_P(a)) {
+ q = rb_int_idiv(a, b);
+ }
+ else if (RB_FLOAT_TYPE_P(a)) {
+ q = rb_float_div(a, b);
+ }
+ else if (RB_TYPE_P(a, T_RATIONAL)) {
+ q = rb_rational_div(a, b);
+ }
+ else {
+ q = rb_funcallv(a, idDiv, 1, &b);
+ }
+
+ if (RB_INTEGER_TYPE_P(q)) {
+ return q;
+ }
+ else if (RB_FLOAT_TYPE_P(q)) {
+ return rb_float_floor(q, 0);
+ }
+ else if (RB_TYPE_P(q, T_RATIONAL)) {
+ return rb_rational_floor(q, 0);
+ }
+ else {
+ return rb_funcall(q, rb_intern("floor"), 0);
+ }
+}
+
+/*
+ * call-seq:
+ * aseq.last -> num or nil
+ * aseq.last(n) -> an_array
+ *
+ * Returns the last number in this arithmetic sequence,
+ * or an array of the last +n+ elements.
+ */
+static VALUE
+arith_seq_last(int argc, VALUE *argv, VALUE self)
+{
+ VALUE b, e, s, len_1, len, last, nv, ary;
+ int last_is_adjusted;
+ long n;
+
+ e = arith_seq_end(self);
+ if (NIL_P(e)) {
+ rb_raise(rb_eRangeError,
+ "cannot get the last element of endless arithmetic sequence");
+ }
+
+ b = arith_seq_begin(self);
+ s = arith_seq_step(self);
+
+ len_1 = num_idiv(num_minus(e, b), s);
+ if (rb_num_negative_int_p(len_1)) {
+ if (argc == 0) {
+ return Qnil;
+ }
+ return rb_ary_new_capa(0);
+ }
+
+ last = num_plus(b, num_mul(s, len_1));
+ if ((last_is_adjusted = arith_seq_exclude_end_p(self) && rb_equal(last, e))) {
+ last = num_minus(last, s);
+ }
+
+ if (argc == 0) {
+ return last;
+ }
+
+ if (last_is_adjusted) {
+ len = len_1;
+ }
+ else {
+ len = rb_int_plus(len_1, INT2FIX(1));
+ }
+
+ rb_scan_args(argc, argv, "1", &nv);
+ if (!RB_INTEGER_TYPE_P(nv)) {
+ nv = rb_to_int(nv);
+ }
+ if (RTEST(rb_int_gt(nv, len))) {
+ nv = len;
+ }
+ n = NUM2LONG(nv);
+ if (n < 0) {
+ rb_raise(rb_eArgError, "negative array size");
+ }
+
+ ary = rb_ary_new_capa(n);
+ b = rb_int_minus(last, rb_int_mul(s, nv));
+ while (n) {
+ b = rb_int_plus(b, s);
+ rb_ary_push(ary, b);
+ --n;
+ }
+
+ return ary;
+}
+
+/*
+ * call-seq:
+ * aseq.inspect -> string
+ *
+ * Convert this arithmetic sequence to a printable form.
+ */
+static VALUE
+arith_seq_inspect(VALUE self)
+{
+ struct enumerator *e;
+ VALUE eobj, str, eargs;
+ int range_p;
+
+ TypedData_Get_Struct(self, struct enumerator, &enumerator_data_type, e);
+
+ eobj = rb_attr_get(self, id_receiver);
+ if (NIL_P(eobj)) {
+ eobj = e->obj;
+ }
+
+ range_p = RTEST(rb_obj_is_kind_of(eobj, rb_cRange));
+ str = rb_sprintf("(%s%"PRIsVALUE"%s.", range_p ? "(" : "", eobj, range_p ? ")" : "");
+
+ rb_str_buf_append(str, rb_id2str(e->meth));
+
+ eargs = rb_attr_get(eobj, id_arguments);
+ if (NIL_P(eargs)) {
+ eargs = e->args;
+ }
+ if (eargs != Qfalse) {
+ long argc = RARRAY_LEN(eargs);
+ const VALUE *argv = RARRAY_CONST_PTR(eargs); /* WB: no new reference */
+
+ if (argc > 0) {
+ VALUE kwds = Qnil;
+
+ rb_str_buf_cat2(str, "(");
+
+ if (RB_TYPE_P(argv[argc-1], T_HASH)) {
+ int all_key = TRUE;
+ rb_hash_foreach(argv[argc-1], key_symbol_p, (VALUE)&all_key);
+ if (all_key) kwds = argv[--argc];
+ }
+
+ while (argc--) {
+ VALUE arg = *argv++;
+
+ rb_str_append(str, rb_inspect(arg));
+ rb_str_buf_cat2(str, ", ");
+ }
+ if (!NIL_P(kwds)) {
+ rb_hash_foreach(kwds, kwd_append, str);
+ }
+ rb_str_set_len(str, RSTRING_LEN(str)-2); /* drop the last ", " */
+ rb_str_buf_cat2(str, ")");
+ }
+ }
+
+ rb_str_buf_cat2(str, ")");
+
+ return str;
+}
+
+/*
+ * call-seq:
+ * aseq == obj -> true or false
+ *
+ * Returns <code>true</code> only if +obj+ is an Enumerator::ArithmeticSequence,
+ * has equivalent begin, end, step, and exclude_end? settings.
+ */
+static VALUE
+arith_seq_eq(VALUE self, VALUE other)
+{
+ if (!RTEST(rb_obj_is_kind_of(other, rb_cArithSeq))) {
+ return Qfalse;
+ }
+
+ if (!rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {
+ return Qfalse;
+ }
+
+ if (!rb_equal(arith_seq_end(self), arith_seq_end(other))) {
+ return Qfalse;
+ }
+
+ if (!rb_equal(arith_seq_step(self), arith_seq_step(other))) {
+ return Qfalse;
+ }
+
+ if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {
+ return Qfalse;
+ }
+
+ return Qtrue;
+}
+
+/*
+ * call-seq:
+ * aseq.hash -> integer
+ *
+ * Compute a hash-value for this arithmetic sequence.
+ * Two arithmetic sequences with same begin, end, step, and exclude_end?
+ * values will generate the same hash-value.
+ *
+ * See also Object#hash.
+ */
+static VALUE
+arith_seq_hash(VALUE self)
+{
+ st_index_t hash;
+ VALUE v;
+
+ hash = rb_hash_start(arith_seq_exclude_end_p(self));
+ v = rb_hash(arith_seq_begin(self));
+ hash = rb_hash_uint(hash, NUM2LONG(v));
+ v = rb_hash(arith_seq_end(self));
+ hash = rb_hash_uint(hash, NUM2LONG(v));
+ v = rb_hash(arith_seq_step(self));
+ hash = rb_hash_uint(hash, NUM2LONG(v));
+ hash = rb_hash_end(hash);
+
+ return ST2FIX(hash);
+}
+
+#define NUM_GE(x, y) RTEST(rb_num_coerce_relop((x), (y), idGE))
+
+struct arith_seq_gen {
+ VALUE current;
+ VALUE end;
+ VALUE step;
+ int excl;
+};
+
+/*
+ * call-seq:
+ * aseq.each {|i| block } -> aseq
+ * aseq.each -> aseq
+ */
+static VALUE
+arith_seq_each(VALUE self)
+{
+ VALUE c, e, s, len_1, last;
+ int x;
+
+ if (!rb_block_given_p()) return self;
+
+ c = arith_seq_begin(self);
+ e = arith_seq_end(self);
+ s = arith_seq_step(self);
+ x = arith_seq_exclude_end_p(self);
+
+ if (!RB_TYPE_P(s, T_COMPLEX) && ruby_float_step(c, e, s, x, TRUE)) {
+ return self;
+ }
+
+ if (NIL_P(e)) {
+ while (1) {
+ rb_yield(c);
+ c = rb_int_plus(c, s);
+ }
+
+ return self;
+ }
+
+ if (rb_equal(s, INT2FIX(0))) {
+ while (1) {
+ rb_yield(c);
+ }
+
+ return self;
+ }
+
+ len_1 = num_idiv(num_minus(e, c), s);
+ last = num_plus(c, num_mul(s, len_1));
+ if (x && rb_equal(last, e)) {
+ last = num_minus(last, s);
+ }
+
+ if (rb_num_negative_int_p(s)) {
+ while (NUM_GE(c, last)) {
+ rb_yield(c);
+ c = num_plus(c, s);
+ }
+ }
+ else {
+ while (NUM_GE(last, c)) {
+ rb_yield(c);
+ c = num_plus(c, s);
+ }
+ }
+
+ return self;
+}
+
+/*
+ * call-seq:
+ * aseq.size -> num or nil
+ *
+ * Returns the number of elements in this arithmetic sequence if it is a finite
+ * sequence. Otherwise, returns <code>nil</code>.
+ */
+static VALUE
+arith_seq_size(VALUE self)
+{
+ VALUE b, e, s, len_1, len, last;
+ int x;
+
+ b = arith_seq_begin(self);
+ e = arith_seq_end(self);
+ s = arith_seq_step(self);
+ x = arith_seq_exclude_end_p(self);
+
+ if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {
+ double ee, n;
+
+ if (NIL_P(e)) {
+ if (rb_num_negative_int_p(s)) {
+ ee = -HUGE_VAL;
+ }
+ else {
+ ee = HUGE_VAL;
+ }
+ }
+ else {
+ ee = NUM2DBL(e);
+ }
+
+ n = ruby_float_step_size(NUM2DBL(b), ee, NUM2DBL(s), x);
+ if (isinf(n)) return DBL2NUM(n);
+ if (POSFIXABLE(n)) return LONG2FIX((long)n);
+ return rb_dbl2big(n);
+ }
+
+ if (NIL_P(e)) {
+ return DBL2NUM(HUGE_VAL);
+ }
+
+ if (!rb_obj_is_kind_of(s, rb_cNumeric)) {
+ s = rb_to_int(s);
+ }
+
+ if (rb_equal(s, INT2FIX(0))) {
+ return DBL2NUM(HUGE_VAL);
+ }
+
+ len_1 = rb_int_idiv(rb_int_minus(e, b), s);
+ if (rb_num_negative_int_p(len_1)) {
+ return INT2FIX(0);
+ }
+
+ last = rb_int_plus(b, rb_int_mul(s, len_1));
+ if (x && rb_equal(last, e)) {
+ len = len_1;
+ }
+ else {
+ len = rb_int_plus(len_1, INT2FIX(1));
+ }
+
+ return len;
+}
+
+#define sym(name) ID2SYM(rb_intern_const(name))
void
InitVM_Enumerator(void)
{
+ ID id_private = rb_intern_const("private");
+
rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
@@ -2357,19 +4032,62 @@ InitVM_Enumerator(void)
rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
rb_define_method(rb_cEnumerator, "inspect", enumerator_inspect, 0);
rb_define_method(rb_cEnumerator, "size", enumerator_size, 0);
+ rb_define_method(rb_cEnumerator, "+", enumerator_plus, 1);
+ rb_define_method(rb_mEnumerable, "chain", enum_chain, -1);
/* Lazy */
rb_cLazy = rb_define_class_under(rb_cEnumerator, "Lazy", rb_cEnumerator);
rb_define_method(rb_mEnumerable, "lazy", enumerable_lazy, 0);
+
+ rb_define_alias(rb_cLazy, "_enumerable_map", "map");
+ rb_define_alias(rb_cLazy, "_enumerable_collect", "collect");
+ rb_define_alias(rb_cLazy, "_enumerable_flat_map", "flat_map");
+ rb_define_alias(rb_cLazy, "_enumerable_collect_concat", "collect_concat");
+ rb_define_alias(rb_cLazy, "_enumerable_select", "select");
+ rb_define_alias(rb_cLazy, "_enumerable_find_all", "find_all");
+ rb_define_alias(rb_cLazy, "_enumerable_filter", "filter");
+ rb_define_alias(rb_cLazy, "_enumerable_filter_map", "filter_map");
+ rb_define_alias(rb_cLazy, "_enumerable_reject", "reject");
+ rb_define_alias(rb_cLazy, "_enumerable_grep", "grep");
+ rb_define_alias(rb_cLazy, "_enumerable_grep_v", "grep_v");
+ rb_define_alias(rb_cLazy, "_enumerable_zip", "zip");
+ rb_define_alias(rb_cLazy, "_enumerable_take", "take");
+ rb_define_alias(rb_cLazy, "_enumerable_take_while", "take_while");
+ rb_define_alias(rb_cLazy, "_enumerable_drop", "drop");
+ rb_define_alias(rb_cLazy, "_enumerable_drop_while", "drop_while");
+ rb_define_alias(rb_cLazy, "_enumerable_uniq", "uniq");
+ rb_define_private_method(rb_cLazy, "_enumerable_with_index", enumerator_with_index, -1);
+
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_map"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_collect"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_flat_map"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_collect_concat"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_select"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_find_all"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_filter"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_filter_map"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_reject"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_grep"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_grep_v"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_zip"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_take"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_take_while"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_drop"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_drop_while"));
+ rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_uniq"));
+
rb_define_method(rb_cLazy, "initialize", lazy_initialize, -1);
rb_define_method(rb_cLazy, "to_enum", lazy_to_enum, -1);
rb_define_method(rb_cLazy, "enum_for", lazy_to_enum, -1);
+ rb_define_method(rb_cLazy, "eager", lazy_eager, 0);
rb_define_method(rb_cLazy, "map", lazy_map, 0);
rb_define_method(rb_cLazy, "collect", lazy_map, 0);
rb_define_method(rb_cLazy, "flat_map", lazy_flat_map, 0);
rb_define_method(rb_cLazy, "collect_concat", lazy_flat_map, 0);
rb_define_method(rb_cLazy, "select", lazy_select, 0);
rb_define_method(rb_cLazy, "find_all", lazy_select, 0);
+ rb_define_method(rb_cLazy, "filter", lazy_select, 0);
+ rb_define_method(rb_cLazy, "filter_map", lazy_filter_map, 0);
rb_define_method(rb_cLazy, "reject", lazy_reject, 0);
rb_define_method(rb_cLazy, "grep", lazy_grep, 1);
rb_define_method(rb_cLazy, "grep_v", lazy_grep_v, 1);
@@ -2385,7 +4103,38 @@ InitVM_Enumerator(void)
rb_define_method(rb_cLazy, "slice_when", lazy_super, -1);
rb_define_method(rb_cLazy, "chunk_while", lazy_super, -1);
rb_define_method(rb_cLazy, "uniq", lazy_uniq, 0);
-
+ rb_define_method(rb_cLazy, "with_index", lazy_with_index, -1);
+
+ lazy_use_super_method = rb_hash_new_with_size(18);
+ rb_hash_aset(lazy_use_super_method, sym("map"), sym("_enumerable_map"));
+ rb_hash_aset(lazy_use_super_method, sym("collect"), sym("_enumerable_collect"));
+ rb_hash_aset(lazy_use_super_method, sym("flat_map"), sym("_enumerable_flat_map"));
+ rb_hash_aset(lazy_use_super_method, sym("collect_concat"), sym("_enumerable_collect_concat"));
+ rb_hash_aset(lazy_use_super_method, sym("select"), sym("_enumerable_select"));
+ rb_hash_aset(lazy_use_super_method, sym("find_all"), sym("_enumerable_find_all"));
+ rb_hash_aset(lazy_use_super_method, sym("filter"), sym("_enumerable_filter"));
+ rb_hash_aset(lazy_use_super_method, sym("filter_map"), sym("_enumerable_filter_map"));
+ rb_hash_aset(lazy_use_super_method, sym("reject"), sym("_enumerable_reject"));
+ rb_hash_aset(lazy_use_super_method, sym("grep"), sym("_enumerable_grep"));
+ rb_hash_aset(lazy_use_super_method, sym("grep_v"), sym("_enumerable_grep_v"));
+ rb_hash_aset(lazy_use_super_method, sym("zip"), sym("_enumerable_zip"));
+ rb_hash_aset(lazy_use_super_method, sym("take"), sym("_enumerable_take"));
+ rb_hash_aset(lazy_use_super_method, sym("take_while"), sym("_enumerable_take_while"));
+ rb_hash_aset(lazy_use_super_method, sym("drop"), sym("_enumerable_drop"));
+ rb_hash_aset(lazy_use_super_method, sym("drop_while"), sym("_enumerable_drop_while"));
+ rb_hash_aset(lazy_use_super_method, sym("uniq"), sym("_enumerable_uniq"));
+ rb_hash_aset(lazy_use_super_method, sym("with_index"), sym("_enumerable_with_index"));
+ rb_obj_freeze(lazy_use_super_method);
+ rb_gc_register_mark_object(lazy_use_super_method);
+
+#if 0 /* for RDoc */
+ rb_define_method(rb_cLazy, "to_a", lazy_to_a, 0);
+ rb_define_method(rb_cLazy, "chunk", lazy_chunk, 0);
+ rb_define_method(rb_cLazy, "chunk_while", lazy_chunk_while, 0);
+ rb_define_method(rb_cLazy, "slice_after", lazy_slice_after, 0);
+ rb_define_method(rb_cLazy, "slice_before", lazy_slice_before, 0);
+ rb_define_method(rb_cLazy, "slice_when", lazy_slice_when, 0);
+#endif
rb_define_alias(rb_cLazy, "force", "to_a");
rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
@@ -2404,34 +4153,67 @@ InitVM_Enumerator(void)
rb_define_alloc_func(rb_cYielder, yielder_allocate);
rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
- rb_define_method(rb_cYielder, "<<", yielder_yield_push, -2);
+ rb_define_method(rb_cYielder, "<<", yielder_yield_push, 1);
+ rb_define_method(rb_cYielder, "to_proc", yielder_to_proc, 0);
+
+ /* Producer */
+ rb_cEnumProducer = rb_define_class_under(rb_cEnumerator, "Producer", rb_cObject);
+ rb_define_alloc_func(rb_cEnumProducer, producer_allocate);
+ rb_define_method(rb_cEnumProducer, "each", producer_each, 0);
+ rb_define_singleton_method(rb_cEnumerator, "produce", enumerator_s_produce, -1);
+
+ /* Chain */
+ rb_cEnumChain = rb_define_class_under(rb_cEnumerator, "Chain", rb_cEnumerator);
+ rb_define_alloc_func(rb_cEnumChain, enum_chain_allocate);
+ rb_define_method(rb_cEnumChain, "initialize", enum_chain_initialize, -2);
+ rb_define_method(rb_cEnumChain, "initialize_copy", enum_chain_init_copy, 1);
+ rb_define_method(rb_cEnumChain, "each", enum_chain_each, -1);
+ rb_define_method(rb_cEnumChain, "size", enum_chain_size, 0);
+ rb_define_method(rb_cEnumChain, "rewind", enum_chain_rewind, 0);
+ rb_define_method(rb_cEnumChain, "inspect", enum_chain_inspect, 0);
+
+ /* ArithmeticSequence */
+ rb_cArithSeq = rb_define_class_under(rb_cEnumerator, "ArithmeticSequence", rb_cEnumerator);
+ rb_undef_alloc_func(rb_cArithSeq);
+ rb_undef_method(CLASS_OF(rb_cArithSeq), "new");
+ rb_define_method(rb_cArithSeq, "begin", arith_seq_begin, 0);
+ rb_define_method(rb_cArithSeq, "end", arith_seq_end, 0);
+ rb_define_method(rb_cArithSeq, "exclude_end?", arith_seq_exclude_end, 0);
+ rb_define_method(rb_cArithSeq, "step", arith_seq_step, 0);
+ rb_define_method(rb_cArithSeq, "first", arith_seq_first, -1);
+ rb_define_method(rb_cArithSeq, "last", arith_seq_last, -1);
+ rb_define_method(rb_cArithSeq, "inspect", arith_seq_inspect, 0);
+ rb_define_method(rb_cArithSeq, "==", arith_seq_eq, 1);
+ rb_define_method(rb_cArithSeq, "===", arith_seq_eq, 1);
+ rb_define_method(rb_cArithSeq, "eql?", arith_seq_eq, 1);
+ rb_define_method(rb_cArithSeq, "hash", arith_seq_hash, 0);
+ rb_define_method(rb_cArithSeq, "each", arith_seq_each, 0);
+ rb_define_method(rb_cArithSeq, "size", arith_seq_size, 0);
rb_provide("enumerator.so"); /* for backward compatibility */
}
+#undef sym
-#undef rb_intern
void
Init_Enumerator(void)
{
- id_rewind = rb_intern("rewind");
- id_each = rb_intern("each");
- id_call = rb_intern("call");
- id_size = rb_intern("size");
- id_yield = rb_intern("yield");
- id_new = rb_intern("new");
- id_initialize = rb_intern("initialize");
- id_next = rb_intern("next");
- id_result = rb_intern("result");
- id_lazy = rb_intern("lazy");
- id_eqq = rb_intern("===");
- id_receiver = rb_intern("receiver");
- id_arguments = rb_intern("arguments");
- id_memo = rb_intern("memo");
- id_method = rb_intern("method");
- id_force = rb_intern("force");
- id_to_enum = rb_intern("to_enum");
+ id_rewind = rb_intern_const("rewind");
+ id_new = rb_intern_const("new");
+ id_next = rb_intern_const("next");
+ id_result = rb_intern_const("result");
+ id_receiver = rb_intern_const("receiver");
+ id_arguments = rb_intern_const("arguments");
+ id_memo = rb_intern_const("memo");
+ id_method = rb_intern_const("method");
+ id_force = rb_intern_const("force");
+ id_to_enum = rb_intern_const("to_enum");
+ id_begin = rb_intern_const("begin");
+ id_end = rb_intern_const("end");
+ id_step = rb_intern_const("step");
+ id_exclude_end = rb_intern_const("exclude_end");
sym_each = ID2SYM(id_each);
- sym_cycle = ID2SYM(rb_intern("cycle"));
+ sym_cycle = ID2SYM(rb_intern_const("cycle"));
+ sym_yield = ID2SYM(rb_intern_const("yield"));
InitVM(Enumerator);
}
diff --git a/error.c b/error.c
index ffdd1a4ef1..d614a9c0a2 100644
--- a/error.c
+++ b/error.c
@@ -9,25 +9,40 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/st.h"
-#include "ruby_assert.h"
-#include "vm_core.h"
+#include "ruby/internal/config.h"
-#include <stdio.h>
+#include <errno.h>
#include <stdarg.h>
+#include <stdio.h>
+
#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
+# include <stdlib.h>
#endif
-#include <errno.h>
+
#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+# include <unistd.h>
#endif
#if defined __APPLE__
# include <AvailabilityMacros.h>
#endif
+#include "internal.h"
+#include "internal/error.h"
+#include "internal/eval.h"
+#include "internal/io.h"
+#include "internal/load.h"
+#include "internal/object.h"
+#include "internal/symbol.h"
+#include "internal/thread.h"
+#include "internal/variable.h"
+#include "ruby/encoding.h"
+#include "ruby/st.h"
+#include "ruby_assert.h"
+#include "vm_core.h"
+
+#include "builtin.h"
+
/*!
* \defgroup exception Exception handlings
* \{
@@ -48,26 +63,25 @@
VALUE rb_iseqw_local_variables(VALUE iseqval);
VALUE rb_iseqw_new(const rb_iseq_t *);
int rb_str_end_with_asciichar(VALUE str, int c);
+VALUE rb_ident_hash_new(void);
+long rb_backtrace_length_limit = -1;
VALUE rb_eEAGAIN;
VALUE rb_eEWOULDBLOCK;
VALUE rb_eEINPROGRESS;
-VALUE rb_mWarning;
-VALUE rb_cWarningBuffer;
+static VALUE rb_mWarning;
+static VALUE rb_cWarningBuffer;
static ID id_warn;
+static ID id_category;
+static ID id_deprecated;
+static ID id_experimental;
+static VALUE sym_category;
+static VALUE warning_categories;
+static VALUE warning_category_t_map;
extern const char ruby_description[];
-static const char REPORTBUG_MSG[] =
- "[NOTE]\n" \
- "You may have encountered a bug in the Ruby interpreter" \
- " or extension libraries.\n" \
- "Bug reports are welcome.\n" \
- ""
- "For details: http://www.ruby-lang.org/bugreport.html\n\n" \
- ;
-
static const char *
rb_strerrno(int err)
{
@@ -135,27 +149,115 @@ rb_syntax_error_append(VALUE exc, VALUE file, int line, int column,
return exc;
}
+static unsigned int warning_disabled_categories = (
+ 1U << RB_WARN_CATEGORY_DEPRECATED |
+ 0);
+
+static unsigned int
+rb_warning_category_mask(VALUE category)
+{
+ return 1U << rb_warning_category_from_name(category);
+}
+
+rb_warning_category_t
+rb_warning_category_from_name(VALUE category)
+{
+ VALUE cat_value;
+ Check_Type(category, T_SYMBOL);
+ cat_value = rb_hash_aref(warning_categories, category);
+ if (cat_value == Qnil) {
+ rb_raise(rb_eArgError, "unknown category: %"PRIsVALUE, category);
+ }
+ return NUM2INT(cat_value);
+}
+
void
-ruby_deprecated_internal_feature(const char *func)
+rb_warning_category_update(unsigned int mask, unsigned int bits)
+{
+ warning_disabled_categories &= ~mask;
+ warning_disabled_categories |= mask & ~bits;
+}
+
+MJIT_FUNC_EXPORTED bool
+rb_warning_category_enabled_p(rb_warning_category_t category)
+{
+ return !(warning_disabled_categories & (1U << category));
+}
+
+/*
+ * call-seq:
+ * Warning[category] -> true or false
+ *
+ * Returns the flag to show the warning messages for +category+.
+ * Supported categories are:
+ *
+ * +:deprecated+ :: deprecation warnings
+ * * assignment of non-nil value to <code>$,</code> and <code>$;</code>
+ * * keyword arguments
+ * * proc/lambda without block
+ * etc.
+ *
+ * +:experimental+ :: experimental features
+ * * Pattern matching
+ */
+
+static VALUE
+rb_warning_s_aref(VALUE mod, VALUE category)
{
- rb_print_backtrace();
- rb_fatal("%s is only for internal use and deprecated; do not use", func);
+ rb_warning_category_t cat = rb_warning_category_from_name(category);
+ if (rb_warning_category_enabled_p(cat))
+ return Qtrue;
+ return Qfalse;
}
/*
* call-seq:
- * warn(msg) -> nil
+ * Warning[category] = flag -> flag
*
- * Writes warning message +msg+ to $stderr, followed by a newline
- * if the message does not end in a newline. This method is called
- * by Ruby for all emitted warnings.
+ * Sets the warning flags for +category+.
+ * See Warning.[] for the categories.
*/
static VALUE
-rb_warning_s_warn(VALUE mod, VALUE str)
+rb_warning_s_aset(VALUE mod, VALUE category, VALUE flag)
{
+ unsigned int mask = rb_warning_category_mask(category);
+ unsigned int disabled = warning_disabled_categories;
+ if (!RTEST(flag))
+ disabled |= mask;
+ else
+ disabled &= ~mask;
+ warning_disabled_categories = disabled;
+ return flag;
+}
+
+/*
+ * call-seq:
+ * warn(msg, category: nil) -> nil
+ *
+ * Writes warning message +msg+ to $stderr. This method is called by
+ * Ruby for all emitted warnings. A +category+ may be included with
+ * the warning.
+ *
+ * See the documentation of the Warning module for how to customize this.
+ */
+
+static VALUE
+rb_warning_s_warn(int argc, VALUE *argv, VALUE mod)
+{
+ VALUE str;
+ VALUE opt;
+ VALUE category = Qnil;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ if (!NIL_P(opt)) rb_get_kwargs(opt, &id_category, 0, 1, &category);
+
Check_Type(str, T_STRING);
rb_must_asciicompat(str);
+ if (!NIL_P(category)) {
+ rb_warning_category_t cat = rb_warning_category_from_name(category);
+ if (!rb_warning_category_enabled_p(cat)) return Qnil;
+ }
rb_write_error_str(str);
return Qnil;
}
@@ -164,23 +266,72 @@ rb_warning_s_warn(VALUE mod, VALUE str)
* Document-module: Warning
*
* The Warning module contains a single method named #warn, and the
- * module extends itself, making <code>Warning.warn</code> available.
+ * module extends itself, making Warning.warn available.
* Warning.warn is called for all warnings issued by Ruby.
* By default, warnings are printed to $stderr.
*
- * By overriding Warning.warn, you can change how warnings are
- * handled by Ruby, either filtering some warnings, and/or outputting
- * warnings somewhere other than $stderr. When Warning.warn is
- * overridden, super can be called to get the default behavior of
- * printing the warning to $stderr.
+ * Changing the behavior of Warning.warn is useful to customize how warnings are
+ * handled by Ruby, for instance by filtering some warnings, and/or outputting
+ * warnings somewhere other than $stderr.
+ *
+ * If you want to change the behavior of Warning.warn you should use
+ * +Warning.extend(MyNewModuleWithWarnMethod)+ and you can use `super`
+ * to get the default behavior of printing the warning to $stderr.
+ *
+ * Example:
+ * module MyWarningFilter
+ * def warn(message, category: nil, **kwargs)
+ * if /some warning I want to ignore/.matches?(message)
+ * # ignore
+ * else
+ * super
+ * end
+ * end
+ * end
+ * Warning.extend MyWarningFilter
+ *
+ * You should never redefine Warning#warn (the instance method), as that will
+ * then no longer provide a way to use the default behavior.
+ *
+ * The +warning+ gem provides convenient ways to customize Warning.warn.
*/
-VALUE
+static VALUE
rb_warning_warn(VALUE mod, VALUE str)
{
return rb_funcallv(mod, id_warn, 1, &str);
}
+
+static int
+rb_warning_warn_arity(void)
+{
+ const rb_method_entry_t *me = rb_method_entry(rb_singleton_class(rb_mWarning), id_warn);
+ return me ? rb_method_entry_arity(me) : 1;
+}
+
+static VALUE
+rb_warn_category(VALUE str, VALUE category)
+{
+ if (category != Qnil) {
+ category = rb_to_symbol_type(category);
+ if (!RTEST(rb_hash_aref(warning_categories, category))) {
+ rb_raise(rb_eArgError, "invalid warning category used: %s", rb_id2name(SYM2ID(category)));
+ }
+ }
+
+ if (rb_warning_warn_arity() == 1) {
+ return rb_warning_warn(rb_mWarning, str);
+ }
+ else {
+ VALUE args[2];
+ args[0] = str;
+ args[1] = rb_hash_new();
+ rb_hash_aset(args[1], sym_category, category);
+ return rb_funcallv_kw(rb_mWarning, id_warn, 2, args, RB_PASS_KEYWORDS);
+ }
+}
+
static void
rb_write_warning_str(VALUE str)
{
@@ -225,15 +376,26 @@ rb_compile_warning(const char *file, int line, const char *fmt, ...)
rb_write_warning_str(str);
}
+void
+rb_category_compile_warn(rb_warning_category_t category, const char *file, int line, const char *fmt, ...)
+{
+ VALUE str;
+ va_list args;
+
+ if (NIL_P(ruby_verbose)) return;
+
+ va_start(args, fmt);
+ str = warn_vsprintf(NULL, file, line, fmt, args);
+ va_end(args);
+ rb_warn_category(str, rb_hash_fetch(warning_category_t_map, INT2NUM(category)));
+}
+
static VALUE
warning_string(rb_encoding *enc, const char *fmt, va_list args)
{
int line;
- VALUE file = rb_source_location(&line);
-
- return warn_vsprintf(enc,
- NIL_P(file) ? NULL : RSTRING_PTR(file), line,
- fmt, args);
+ const char *file = rb_source_location_cstr(&line);
+ return warn_vsprintf(enc, file, line, fmt, args);
}
#define with_warning_string(mesg, enc, fmt) \
@@ -253,6 +415,16 @@ rb_warn(const char *fmt, ...)
}
void
+rb_category_warn(rb_warning_category_t category, const char *fmt, ...)
+{
+ if (!NIL_P(ruby_verbose)) {
+ with_warning_string(mesg, 0, fmt) {
+ rb_warn_category(mesg, rb_hash_fetch(warning_category_t_map, INT2NUM(category)));
+ }
+ }
+}
+
+void
rb_enc_warn(rb_encoding *enc, const char *fmt, ...)
{
if (!NIL_P(ruby_verbose)) {
@@ -273,6 +445,17 @@ rb_warning(const char *fmt, ...)
}
}
+/* rb_category_warning() reports only in verbose mode */
+void
+rb_category_warning(rb_warning_category_t category, const char *fmt, ...)
+{
+ if (RTEST(ruby_verbose)) {
+ with_warning_string(mesg, 0, fmt) {
+ rb_warn_category(mesg, rb_hash_fetch(warning_category_t_map, INT2NUM(category)));
+ }
+ }
+}
+
VALUE
rb_warning_string(const char *fmt, ...)
{
@@ -293,6 +476,36 @@ rb_enc_warning(rb_encoding *enc, const char *fmt, ...)
}
#endif
+void
+rb_warn_deprecated(const char *fmt, const char *suggest, ...)
+{
+ if (NIL_P(ruby_verbose)) return;
+ if (!rb_warning_category_enabled_p(RB_WARN_CATEGORY_DEPRECATED)) return;
+ va_list args;
+ va_start(args, suggest);
+ VALUE mesg = warning_string(0, fmt, args);
+ va_end(args);
+ rb_str_set_len(mesg, RSTRING_LEN(mesg) - 1);
+ rb_str_cat_cstr(mesg, " is deprecated");
+ if (suggest) rb_str_catf(mesg, "; use %s instead", suggest);
+ rb_str_cat_cstr(mesg, "\n");
+ rb_warn_category(mesg, ID2SYM(id_deprecated));
+}
+
+void
+rb_warn_deprecated_to_remove(const char *fmt, const char *removal, ...)
+{
+ if (NIL_P(ruby_verbose)) return;
+ if (!rb_warning_category_enabled_p(RB_WARN_CATEGORY_DEPRECATED)) return;
+ va_list args;
+ va_start(args, removal);
+ VALUE mesg = warning_string(0, fmt, args);
+ va_end(args);
+ rb_str_set_len(mesg, RSTRING_LEN(mesg) - 1);
+ rb_str_catf(mesg, " is deprecated and will be removed in Ruby %s\n", removal);
+ rb_warn_category(mesg, ID2SYM(id_deprecated));
+}
+
static inline int
end_with_asciichar(VALUE str, int c)
{
@@ -300,36 +513,63 @@ end_with_asciichar(VALUE str, int c)
rb_str_end_with_asciichar(str, c);
}
-/*
- * call-seq:
- * warn(msg, ...) -> nil
- *
- * If warnings have been disabled (for example with the
- * <code>-W0</code> flag), does nothing. Otherwise,
- * converts each of the messages to strings, appends a newline
- * character to the string if the string does not end in a newline,
- * and calls <code>Warning.warn</code> with the string.
- *
- * warn("warning 1", "warning 2")
- *
- * <em>produces:</em>
- *
- * warning 1
- * warning 2
- */
+/* :nodoc: */
+static VALUE
+warning_write(int argc, VALUE *argv, VALUE buf)
+{
+ while (argc-- > 0) {
+ rb_str_append(buf, *argv++);
+ }
+ return buf;
+}
+
+VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal);
static VALUE
-rb_warn_m(int argc, VALUE *argv, VALUE exc)
+rb_warn_m(rb_execution_context_t *ec, VALUE exc, VALUE msgs, VALUE uplevel, VALUE category)
{
+ VALUE location = Qnil;
+ int argc = RARRAY_LENINT(msgs);
+ const VALUE *argv = RARRAY_CONST_PTR(msgs);
+
if (!NIL_P(ruby_verbose) && argc > 0) {
- VALUE str = argv[0];
- if (argc > 1 || !end_with_asciichar(str, '\n')) {
- str = rb_str_tmp_new(0);
+ VALUE str = argv[0];
+ if (!NIL_P(uplevel)) {
+ long lev = NUM2LONG(uplevel);
+ if (lev < 0) {
+ rb_raise(rb_eArgError, "negative level (%ld)", lev);
+ }
+ location = rb_ec_backtrace_location_ary(ec, lev + 1, 1, TRUE);
+ if (!NIL_P(location)) {
+ location = rb_ary_entry(location, 0);
+ }
+ }
+ if (argc > 1 || !NIL_P(uplevel) || !end_with_asciichar(str, '\n')) {
+ VALUE path;
+ if (NIL_P(uplevel)) {
+ str = rb_str_tmp_new(0);
+ }
+ else if (NIL_P(location) ||
+ NIL_P(path = rb_funcall(location, rb_intern("path"), 0))) {
+ str = rb_str_new_cstr("warning: ");
+ }
+ else {
+ str = rb_sprintf("%s:%ld: warning: ",
+ rb_string_value_ptr(&path),
+ NUM2LONG(rb_funcall(location, rb_intern("lineno"), 0)));
+ }
RBASIC_SET_CLASS(str, rb_cWarningBuffer);
rb_io_puts(argc, argv, str);
RBASIC_SET_CLASS(str, rb_cString);
}
- rb_write_warning_str(str);
+
+ if (exc == rb_mWarning) {
+ rb_must_asciicompat(str);
+ rb_write_error_str(str);
+ }
+ else {
+ rb_warn_category(str, category);
+ }
}
return Qnil;
}
@@ -368,8 +608,9 @@ bug_report_file(const char *file, int line)
if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len ||
(ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) {
- return out;
+ return out;
}
+
return NULL;
}
@@ -478,7 +719,6 @@ bug_report_end(FILE *out)
(*reporter->func)(out, reporter->data);
}
}
- fputs(REPORTBUG_MSG, out);
postscript_dump(out);
}
@@ -512,32 +752,42 @@ die(void)
}
void
-rb_bug(const char *fmt, ...)
+rb_bug_without_die(const char *fmt, va_list args)
{
const char *file = NULL;
int line = 0;
- if (GET_THREAD()) {
- file = rb_source_loc(&line);
+ if (GET_EC()) {
+ file = rb_source_location_cstr(&line);
}
- report_bug(file, line, fmt, NULL);
+ report_bug_valist(file, line, fmt, NULL, args);
+}
+void
+rb_bug(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ rb_bug_without_die(fmt, args);
+ va_end(args);
die();
}
void
-rb_bug_context(const void *ctx, const char *fmt, ...)
+rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int sig, const void *ctx, const char *fmt, ...)
{
const char *file = NULL;
int line = 0;
- if (GET_THREAD()) {
- file = rb_source_loc(&line);
+ if (GET_EC()) {
+ file = rb_source_location_cstr(&line);
}
report_bug(file, line, fmt, ctx);
+ if (default_sighandler) default_sighandler(sig);
+
die();
}
@@ -582,8 +832,6 @@ rb_async_bug_errno(const char *mesg, int errno_arg)
}
WRITE_CONST(2, "\n\n");
write_or_abort(2, ruby_description, strlen(ruby_description));
- WRITE_CONST(2, "\n\n");
- WRITE_CONST(2, REPORTBUG_MSG);
abort();
}
@@ -593,7 +841,7 @@ rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args)
report_bug_valist(RSTRING_PTR(file), line, fmt, NULL, args);
}
-void
+MJIT_FUNC_EXPORTED void
rb_assert_failure(const char *file, int line, const char *name, const char *expr)
{
FILE *out = stderr;
@@ -617,7 +865,7 @@ static const char builtin_types[][10] = {
"Array",
"Hash",
"Struct",
- "Bignum",
+ "Integer",
"File",
"Data", /* internal use: wrapped C pointers */
"MatchData", /* data of $~ */
@@ -628,7 +876,7 @@ static const char builtin_types[][10] = {
"true",
"false",
"Symbol", /* :symbol */
- "Fixnum",
+ "Integer",
"undef", /* internal use: #undef; should not happen */
"", /* 0x17 */
"", /* 0x18 */
@@ -648,6 +896,17 @@ rb_builtin_type_name(int t)
return 0;
}
+static VALUE
+displaying_class_of(VALUE x)
+{
+ switch (x) {
+ case Qfalse: return rb_fstring_cstr("false");
+ case Qnil: return rb_fstring_cstr("nil");
+ case Qtrue: return rb_fstring_cstr("true");
+ default: return rb_obj_class(x);
+ }
+}
+
static const char *
builtin_class_name(VALUE x)
{
@@ -695,13 +954,8 @@ unexpected_type(VALUE x, int xt, int t)
VALUE mesg, exc = rb_eFatal;
if (tname) {
- const char *cname = builtin_class_name(x);
- if (cname)
- mesg = rb_sprintf("wrong argument type %s (expected %s)",
- cname, tname);
- else
- mesg = rb_sprintf("wrong argument type %"PRIsVALUE" (expected %s)",
- rb_obj_class(x), tname);
+ mesg = rb_sprintf("wrong argument type %"PRIsVALUE" (expected %s)",
+ displaying_class_of(x), tname);
exc = rb_eTypeError;
}
else if (xt > T_MASK && xt <= 0x3f) {
@@ -759,29 +1013,36 @@ rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
return 1;
}
+#undef rb_typeddata_is_instance_of
+int
+rb_typeddata_is_instance_of(VALUE obj, const rb_data_type_t *data_type)
+{
+ return rb_typeddata_is_instance_of_inline(obj, data_type);
+}
+
void *
rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
{
- const char *etype;
+ VALUE actual;
if (!RB_TYPE_P(obj, T_DATA)) {
- wrong_type:
- etype = builtin_class_name(obj);
- if (!etype)
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)",
- rb_obj_class(obj), data_type->wrap_struct_name);
- wrong_datatype:
- rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
- etype, data_type->wrap_struct_name);
- }
- if (!RTYPEDDATA_P(obj)) {
- goto wrong_type;
+ actual = displaying_class_of(obj);
+ }
+ else if (!RTYPEDDATA_P(obj)) {
+ actual = displaying_class_of(obj);
}
else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
- etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
- goto wrong_datatype;
+ const char *name = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
+ actual = rb_str_new_cstr(name); /* or rb_fstring_cstr? not sure... */
+ }
+ else {
+ return DATA_PTR(obj);
}
- return DATA_PTR(obj);
+
+ const char *expected = data_type->wrap_struct_name;
+ rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)",
+ actual, expected);
+ UNREACHABLE_RETURN(NULL);
}
/* exception classes */
@@ -792,6 +1053,7 @@ VALUE rb_eSignal;
VALUE rb_eFatal;
VALUE rb_eStandardError;
VALUE rb_eRuntimeError;
+VALUE rb_eFrozenError;
VALUE rb_eTypeError;
VALUE rb_eArgError;
VALUE rb_eIndexError;
@@ -805,6 +1067,7 @@ VALUE rb_eSecurityError;
VALUE rb_eNotImpError;
VALUE rb_eNoMemError;
VALUE rb_cNameErrorMesg;
+VALUE rb_eNoMatchingPatternError;
VALUE rb_eScriptError;
VALUE rb_eSyntaxError;
@@ -814,22 +1077,24 @@ VALUE rb_eSystemCallError;
VALUE rb_mErrno;
static VALUE rb_eNOERROR;
-static ID id_new, id_cause, id_message, id_backtrace;
-static ID id_name, id_key, id_args, id_Errno, id_errno, id_i_path;
-static ID id_receiver, id_iseq, id_local_variables;
-static ID id_private_call_p;
-extern ID ruby_static_id_status;
+ID ruby_static_id_cause;
+#define id_cause ruby_static_id_cause
+static ID id_message, id_backtrace;
+static ID id_key, id_args, id_Errno, id_errno, id_i_path;
+static ID id_receiver, id_recv, id_iseq, id_local_variables;
+static ID id_private_call_p, id_top, id_bottom;
#define id_bt idBt
#define id_bt_locations idBt_locations
#define id_mesg idMesg
-#define id_status ruby_static_id_status
+#define id_name idName
#undef rb_exc_new_cstr
VALUE
rb_exc_new(VALUE etype, const char *ptr, long len)
{
- return rb_funcall(etype, id_new, 1, rb_str_new(ptr, len));
+ VALUE mesg = rb_str_new(ptr, len);
+ return rb_class_new_instance(1, &mesg, etype);
}
VALUE
@@ -842,12 +1107,22 @@ VALUE
rb_exc_new_str(VALUE etype, VALUE str)
{
StringValue(str);
- return rb_funcall(etype, id_new, 1, str);
+ return rb_class_new_instance(1, &str, etype);
+}
+
+static VALUE
+exc_init(VALUE exc, VALUE mesg)
+{
+ rb_ivar_set(exc, id_mesg, mesg);
+ rb_ivar_set(exc, id_bt, Qnil);
+
+ return exc;
}
/*
* call-seq:
- * Exception.new(msg = nil) -> exception
+ * Exception.new(msg = nil) -> exception
+ * Exception.exception(msg = nil) -> exception
*
* Construct a new Exception object, optionally passing in
* a message.
@@ -858,18 +1133,15 @@ exc_initialize(int argc, VALUE *argv, VALUE exc)
{
VALUE arg;
- rb_scan_args(argc, argv, "01", &arg);
- rb_ivar_set(exc, id_mesg, arg);
- rb_ivar_set(exc, id_bt, Qnil);
-
- return exc;
+ arg = (!rb_check_arity(argc, 0, 1) ? Qnil : argv[0]);
+ return exc_init(exc, arg);
}
/*
* Document-method: exception
*
* call-seq:
- * exc.exception(string) -> an_exception or exc
+ * exc.exception([string]) -> an_exception or exc
*
* With no argument, or if the argument is the same as the receiver,
* return the receiver. Otherwise, create a new
@@ -883,11 +1155,11 @@ exc_exception(int argc, VALUE *argv, VALUE self)
{
VALUE exc;
+ argc = rb_check_arity(argc, 0, 1);
if (argc == 0) return self;
if (argc == 1 && self == argv[0]) return self;
exc = rb_obj_clone(self);
- exc_initialize(argc, argv, exc);
-
+ rb_ivar_set(exc, id_mesg, argv[0]);
return exc;
}
@@ -908,6 +1180,93 @@ exc_to_s(VALUE exc)
return rb_String(mesg);
}
+/* FIXME: Include eval_error.c */
+void rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse);
+
+VALUE
+rb_get_message(VALUE exc)
+{
+ VALUE e = rb_check_funcall(exc, id_message, 0, 0);
+ if (e == Qundef) return Qnil;
+ if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
+ return e;
+}
+
+/*
+ * call-seq:
+ * Exception.to_tty? -> true or false
+ *
+ * Returns +true+ if exception messages will be sent to a tty.
+ */
+static VALUE
+exc_s_to_tty_p(VALUE self)
+{
+ return rb_stderr_tty_p() ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq:
+ * exception.full_message(highlight: bool, order: [:top or :bottom]) -> string
+ *
+ * Returns formatted string of _exception_.
+ * The returned string is formatted using the same format that Ruby uses
+ * when printing an uncaught exceptions to stderr.
+ *
+ * If _highlight_ is +true+ the default error handler will send the
+ * messages to a tty.
+ *
+ * _order_ must be either of +:top+ or +:bottom+, and places the error
+ * message and the innermost backtrace come at the top or the bottom.
+ *
+ * The default values of these options depend on <code>$stderr</code>
+ * and its +tty?+ at the timing of a call.
+ */
+
+static VALUE
+exc_full_message(int argc, VALUE *argv, VALUE exc)
+{
+ VALUE opt, str, emesg, errat;
+ enum {kw_highlight, kw_order, kw_max_};
+ static ID kw[kw_max_];
+ VALUE args[kw_max_] = {Qnil, Qnil};
+
+ rb_scan_args(argc, argv, "0:", &opt);
+ if (!NIL_P(opt)) {
+ if (!kw[0]) {
+#define INIT_KW(n) kw[kw_##n] = rb_intern_const(#n)
+ INIT_KW(highlight);
+ INIT_KW(order);
+#undef INIT_KW
+ }
+ rb_get_kwargs(opt, kw, 0, kw_max_, args);
+ switch (args[kw_highlight]) {
+ default:
+ rb_raise(rb_eArgError, "expected true or false as "
+ "highlight: %+"PRIsVALUE, args[kw_highlight]);
+ case Qundef: args[kw_highlight] = Qnil; break;
+ case Qtrue: case Qfalse: case Qnil: break;
+ }
+ if (args[kw_order] == Qundef) {
+ args[kw_order] = Qnil;
+ }
+ else {
+ ID id = rb_check_id(&args[kw_order]);
+ if (id == id_bottom) args[kw_order] = Qtrue;
+ else if (id == id_top) args[kw_order] = Qfalse;
+ else {
+ rb_raise(rb_eArgError, "expected :top or :bottom as "
+ "order: %+"PRIsVALUE, args[kw_order]);
+ }
+ }
+ }
+ str = rb_str_new2("");
+ errat = rb_get_backtrace(exc);
+ emesg = rb_get_message(exc);
+
+ rb_error_write(exc, emesg, errat, str, args[kw_highlight], args[kw_order]);
+ return str;
+}
+
/*
* call-seq:
* exception.message -> string
@@ -926,7 +1285,7 @@ exc_message(VALUE exc)
* call-seq:
* exception.inspect -> string
*
- * Return this exception's class name and message
+ * Return this exception's class name and message.
*/
static VALUE
@@ -937,7 +1296,7 @@ exc_inspect(VALUE exc)
klass = CLASS_OF(exc);
exc = rb_obj_as_string(exc);
if (RSTRING_LEN(exc) == 0) {
- return rb_str_dup(rb_class_name(klass));
+ return rb_class_name(klass);
}
str = rb_str_buf_new2("#<");
@@ -952,7 +1311,7 @@ exc_inspect(VALUE exc)
/*
* call-seq:
- * exception.backtrace -> array
+ * exception.backtrace -> array or nil
*
* Returns any backtrace associated with the exception. The backtrace
* is an array of strings, each containing either ``filename:lineNo: in
@@ -977,6 +1336,12 @@ exc_inspect(VALUE exc)
* prog.rb:2:in `a'
* prog.rb:6:in `b'
* prog.rb:10
+ *
+ * In the case no backtrace has been set, +nil+ is returned
+ *
+ * ex = StandardError.new
+ * ex.backtrace
+ * #=> nil
*/
static VALUE
@@ -994,34 +1359,38 @@ exc_backtrace(VALUE exc)
return obj;
}
+static VALUE rb_check_backtrace(VALUE);
+
VALUE
rb_get_backtrace(VALUE exc)
{
ID mid = id_backtrace;
+ VALUE info;
if (rb_method_basic_definition_p(CLASS_OF(exc), id_backtrace)) {
- VALUE info, klass = rb_eException;
- rb_thread_t *th = GET_THREAD();
+ VALUE klass = rb_eException;
+ rb_execution_context_t *ec = GET_EC();
if (NIL_P(exc))
return Qnil;
- EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, exc, mid, mid, klass, Qundef);
+ EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, exc, mid, mid, klass, Qundef);
info = exc_backtrace(exc);
- EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, exc, mid, mid, klass, info);
- if (NIL_P(info))
- return Qnil;
- return rb_check_backtrace(info);
+ EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, exc, mid, mid, klass, info);
+ }
+ else {
+ info = rb_funcallv(exc, mid, 0, 0);
}
- return rb_funcallv(exc, mid, 0, 0);
+ if (NIL_P(info)) return Qnil;
+ return rb_check_backtrace(info);
}
/*
* call-seq:
- * exception.backtrace_locations -> array
+ * exception.backtrace_locations -> array or nil
*
* Returns any backtrace associated with the exception. This method is
* similar to Exception#backtrace, but the backtrace is an array of
* Thread::Backtrace::Location.
*
- * Now, this method is not affected by Exception#set_backtrace().
+ * This method is not affected by Exception#set_backtrace().
*/
static VALUE
exc_backtrace_locations(VALUE exc)
@@ -1035,7 +1404,7 @@ exc_backtrace_locations(VALUE exc)
return obj;
}
-VALUE
+static VALUE
rb_check_backtrace(VALUE bt)
{
long i;
@@ -1073,7 +1442,7 @@ exc_set_backtrace(VALUE exc, VALUE bt)
return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_exc_set_backtrace(VALUE exc, VALUE bt)
{
return exc_set_backtrace(exc, bt);
@@ -1104,7 +1473,7 @@ try_convert_to_exception(VALUE obj)
* call-seq:
* exc == obj -> true or false
*
- * Equality---If <i>obj</i> is not an <code>Exception</code>, returns
+ * Equality---If <i>obj</i> is not an Exception, returns
* <code>false</code>. Otherwise, returns <code>true</code> if <i>exc</i> and
* <i>obj</i> share same class, messages, and backtrace.
*/
@@ -1233,6 +1602,49 @@ exit_success_p(VALUE exc)
return Qfalse;
}
+static VALUE
+err_init_recv(VALUE exc, VALUE recv)
+{
+ if (recv != Qundef) rb_ivar_set(exc, id_recv, recv);
+ return exc;
+}
+
+/*
+ * call-seq:
+ * FrozenError.new(msg=nil, receiver: nil) -> frozen_error
+ *
+ * Construct a new FrozenError exception. If given the <i>receiver</i>
+ * parameter may subsequently be examined using the FrozenError#receiver
+ * method.
+ *
+ * a = [].freeze
+ * raise FrozenError.new("can't modify frozen array", receiver: a)
+ */
+
+static VALUE
+frozen_err_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ID keywords[1];
+ VALUE values[numberof(keywords)], options;
+
+ argc = rb_scan_args(argc, argv, "*:", NULL, &options);
+ keywords[0] = id_receiver;
+ rb_get_kwargs(options, keywords, 0, numberof(values), values);
+ rb_call_super(argc, argv);
+ err_init_recv(self, values[0]);
+ return self;
+}
+
+/*
+ * Document-method: FrozenError#receiver
+ * call-seq:
+ * frozen_error.receiver -> object
+ *
+ * Return the receiver associated with this FrozenError exception.
+ */
+
+#define frozen_err_receiver name_err_receiver
+
void
rb_name_error(ID id, const char *fmt, ...)
{
@@ -1263,35 +1675,62 @@ rb_name_error_str(VALUE str, const char *fmt, ...)
rb_exc_raise(exc);
}
+static VALUE
+name_err_init_attr(VALUE exc, VALUE recv, VALUE method)
+{
+ const rb_execution_context_t *ec = GET_EC();
+ rb_control_frame_t *cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
+ cfp = rb_vm_get_ruby_level_next_cfp(ec, cfp);
+ rb_ivar_set(exc, id_name, method);
+ err_init_recv(exc, recv);
+ if (cfp) rb_ivar_set(exc, id_iseq, rb_iseqw_new(cfp->iseq));
+ return exc;
+}
+
/*
* call-seq:
- * NameError.new([msg, *, name]) -> name_error
+ * NameError.new(msg=nil, name=nil, receiver: nil) -> name_error
*
* Construct a new NameError exception. If given the <i>name</i>
- * parameter may subsequently be examined using the <code>NameError.name</code>
- * method.
+ * parameter may subsequently be examined using the NameError#name
+ * method. <i>receiver</i> parameter allows to pass object in
+ * context of which the error happened. Example:
+ *
+ * [1, 2, 3].method(:rject) # NameError with name "rject" and receiver: Array
+ * [1, 2, 3].singleton_method(:rject) # NameError with name "rject" and receiver: [1, 2, 3]
*/
static VALUE
name_err_initialize(int argc, VALUE *argv, VALUE self)
{
- VALUE name;
- VALUE iseqw = Qnil;
+ ID keywords[1];
+ VALUE values[numberof(keywords)], name, options;
+ argc = rb_scan_args(argc, argv, "*:", NULL, &options);
+ keywords[0] = id_receiver;
+ rb_get_kwargs(options, keywords, 0, numberof(values), values);
name = (argc > 1) ? argv[--argc] : Qnil;
rb_call_super(argc, argv);
- rb_ivar_set(self, id_name, name);
- {
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp =
- rb_vm_get_ruby_level_next_cfp(th,
- RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp));
- if (cfp) iseqw = rb_iseqw_new(cfp->iseq);
- }
- rb_ivar_set(self, id_iseq, iseqw);
+ name_err_init_attr(self, values[0], name);
return self;
}
+static VALUE rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method);
+
+static VALUE
+name_err_init(VALUE exc, VALUE mesg, VALUE recv, VALUE method)
+{
+ exc_init(exc, rb_name_err_mesg_new(mesg, recv, method));
+ return name_err_init_attr(exc, recv, method);
+}
+
+VALUE
+rb_name_err_new(VALUE mesg, VALUE recv, VALUE method)
+{
+ VALUE exc = rb_obj_alloc(rb_eNameError);
+ return name_err_init(exc, mesg, recv, method);
+}
+
/*
* call-seq:
* name_error.name -> string or nil
@@ -1329,25 +1768,49 @@ name_err_local_variables(VALUE self)
return vars;
}
+static VALUE
+nometh_err_init_attr(VALUE exc, VALUE args, int priv)
+{
+ rb_ivar_set(exc, id_args, args);
+ rb_ivar_set(exc, id_private_call_p, priv ? Qtrue : Qfalse);
+ return exc;
+}
+
/*
* call-seq:
- * NoMethodError.new([msg, *, name [, args]]) -> no_method_error
+ * NoMethodError.new(msg=nil, name=nil, args=nil, private=false, receiver: nil) -> no_method_error
*
* Construct a NoMethodError exception for a method of the given name
* called with the given arguments. The name may be accessed using
* the <code>#name</code> method on the resulting object, and the
* arguments using the <code>#args</code> method.
+ *
+ * If <i>private</i> argument were passed, it designates method was
+ * attempted to call in private context, and can be accessed with
+ * <code>#private_call?</code> method.
+ *
+ * <i>receiver</i> argument stores an object whose method was called.
*/
static VALUE
nometh_err_initialize(int argc, VALUE *argv, VALUE self)
{
- VALUE priv = (argc > 3) && (--argc, RTEST(argv[argc])) ? Qtrue : Qfalse;
- VALUE args = (argc > 2) ? argv[--argc] : Qnil;
- name_err_initialize(argc, argv, self);
- rb_ivar_set(self, id_args, args);
- rb_ivar_set(self, id_private_call_p, RTEST(priv) ? Qtrue : Qfalse);
- return self;
+ int priv;
+ VALUE args, options;
+ argc = rb_scan_args(argc, argv, "*:", NULL, &options);
+ priv = (argc > 3) && (--argc, RTEST(argv[argc]));
+ args = (argc > 2) ? argv[--argc] : Qnil;
+ if (!NIL_P(options)) argv[argc++] = options;
+ rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
+ return nometh_err_init_attr(self, args, priv);
+}
+
+VALUE
+rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv)
+{
+ VALUE exc = rb_obj_alloc(rb_eNoMethodError);
+ name_err_init(exc, mesg, recv, method);
+ return nometh_err_init_attr(exc, args, priv);
}
/* :nodoc: */
@@ -1384,10 +1847,10 @@ static const rb_data_type_t name_err_mesg_data_type = {
};
/* :nodoc: */
-VALUE
-rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method)
+static VALUE
+rb_name_err_mesg_init(VALUE klass, VALUE mesg, VALUE recv, VALUE method)
{
- VALUE result = TypedData_Wrap_Struct(rb_cNameErrorMesg, &name_err_mesg_data_type, 0);
+ VALUE result = TypedData_Wrap_Struct(klass, &name_err_mesg_data_type, 0);
VALUE *ptr = ALLOC_N(VALUE, NAME_ERR_MESG_COUNT);
ptr[NAME_ERR_MESG__MESG] = mesg;
@@ -1397,15 +1860,33 @@ rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method)
return result;
}
-VALUE
-rb_name_err_new(VALUE mesg, VALUE recv, VALUE method)
+/* :nodoc: */
+static VALUE
+rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method)
{
- VALUE exc = rb_obj_alloc(rb_eNameError);
- rb_ivar_set(exc, id_mesg, rb_name_err_mesg_new(mesg, recv, method));
- rb_ivar_set(exc, id_bt, Qnil);
- rb_ivar_set(exc, id_name, method);
- rb_ivar_set(exc, id_receiver, recv);
- return exc;
+ return rb_name_err_mesg_init(rb_cNameErrorMesg, mesg, recv, method);
+}
+
+/* :nodoc: */
+static VALUE
+name_err_mesg_alloc(VALUE klass)
+{
+ return rb_name_err_mesg_init(klass, Qnil, Qnil, Qnil);
+}
+
+/* :nodoc: */
+static VALUE
+name_err_mesg_init_copy(VALUE obj1, VALUE obj2)
+{
+ VALUE *ptr1, *ptr2;
+
+ if (obj1 == obj2) return obj1;
+ rb_obj_init_copy(obj1, obj2);
+
+ TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
+ TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
+ MEMCPY(ptr1, ptr2, VALUE, NAME_ERR_MESG_COUNT);
+ return obj1;
}
/* :nodoc: */
@@ -1430,6 +1911,17 @@ name_err_mesg_equal(VALUE obj1, VALUE obj2)
/* :nodoc: */
static VALUE
+name_err_mesg_receiver_name(VALUE obj)
+{
+ if (RB_SPECIAL_CONST_P(obj)) return Qundef;
+ if (RB_BUILTIN_TYPE(obj) == T_MODULE || RB_BUILTIN_TYPE(obj) == T_CLASS) {
+ return rb_check_funcall(obj, rb_intern("name"), 0, 0);
+ }
+ return Qundef;
+}
+
+/* :nodoc: */
+static VALUE
name_err_mesg_to_str(VALUE obj)
{
VALUE *ptr, mesg;
@@ -1456,14 +1948,17 @@ name_err_mesg_to_str(VALUE obj)
d = FAKE_CSTR(&d_str, "false");
break;
default:
- d = rb_protect(rb_inspect, obj, &state);
- if (state)
+ d = rb_protect(name_err_mesg_receiver_name, obj, &state);
+ if (state || d == Qundef || d == Qnil)
+ d = rb_protect(rb_inspect, obj, &state);
+ if (state) {
rb_set_errinfo(Qnil);
- if (NIL_P(d) || RSTRING_LEN(d) > 65) {
+ }
+ d = rb_check_string_type(d);
+ if (NIL_P(d)) {
d = rb_any_to_s(obj);
}
singleton = (RSTRING_LEN(d) > 0 && RSTRING_PTR(d)[0] == '#');
- d = QUOTE(d);
break;
}
if (!singleton) {
@@ -1473,7 +1968,7 @@ name_err_mesg_to_str(VALUE obj)
else {
c = s = FAKE_CSTR(&s_str, "");
}
- args[0] = QUOTE(rb_obj_as_string(ptr[NAME_ERR_MESG__NAME]));
+ args[0] = rb_obj_as_string(ptr[NAME_ERR_MESG__NAME]);
args[1] = d;
args[2] = s;
args[3] = c;
@@ -1508,7 +2003,7 @@ name_err_receiver(VALUE self)
{
VALUE *ptr, recv, mesg;
- recv = rb_ivar_lookup(self, id_receiver, Qundef);
+ recv = rb_ivar_lookup(self, id_recv, Qundef);
if (recv != Qundef) return recv;
mesg = rb_attr_get(self, id_mesg);
@@ -1533,6 +2028,13 @@ nometh_err_args(VALUE self)
return rb_attr_get(self, id_args);
}
+/*
+ * call-seq:
+ * no_method_error.private_call? -> true or false
+ *
+ * Return true if the caused method was called as private.
+ */
+
static VALUE
nometh_err_private_call_p(VALUE self)
{
@@ -1547,6 +2049,13 @@ rb_invalid_str(const char *str, const char *type)
rb_raise(rb_eArgError, "invalid value for %s: %+"PRIsVALUE, type, s);
}
+/*
+ * call-seq:
+ * key_error.receiver -> object
+ *
+ * Return the receiver associated with this KeyError exception.
+ */
+
static VALUE
key_err_receiver(VALUE self)
{
@@ -1557,6 +2066,13 @@ key_err_receiver(VALUE self)
rb_raise(rb_eArgError, "no receiver is available");
}
+/*
+ * call-seq:
+ * key_error.key -> object
+ *
+ * Return the key caused this KeyError exception.
+ */
+
static VALUE
key_err_key(VALUE self)
{
@@ -1580,6 +2096,38 @@ rb_key_err_new(VALUE mesg, VALUE recv, VALUE key)
/*
* call-seq:
+ * KeyError.new(message=nil, receiver: nil, key: nil) -> key_error
+ *
+ * Construct a new +KeyError+ exception with the given message,
+ * receiver and key.
+ */
+
+static VALUE
+key_err_initialize(int argc, VALUE *argv, VALUE self)
+{
+ VALUE options;
+
+ rb_call_super(rb_scan_args(argc, argv, "01:", NULL, &options), argv);
+
+ if (!NIL_P(options)) {
+ ID keywords[2];
+ VALUE values[numberof(keywords)];
+ int i;
+ keywords[0] = id_receiver;
+ keywords[1] = id_key;
+ rb_get_kwargs(options, keywords, 0, numberof(values), values);
+ for (i = 0; i < numberof(values); ++i) {
+ if (values[i] != Qundef) {
+ rb_ivar_set(self, keywords[i], values[i]);
+ }
+ }
+ }
+
+ return self;
+}
+
+/*
+ * call-seq:
* SyntaxError.new([msg]) -> syntax_error
*
* Construct a SyntaxError exception.
@@ -1590,7 +2138,7 @@ syntax_error_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE mesg;
if (argc == 0) {
- mesg = rb_fstring_cstr("compile error");
+ mesg = rb_fstring_lit("compile error");
argc = 1;
argv = &mesg;
}
@@ -1600,19 +2148,18 @@ syntax_error_initialize(int argc, VALUE *argv, VALUE self)
/*
* Document-module: Errno
*
- * Ruby exception objects are subclasses of <code>Exception</code>.
- * However, operating systems typically report errors using plain
- * integers. Module <code>Errno</code> is created dynamically to map
- * these operating system errors to Ruby classes, with each error
- * number generating its own subclass of <code>SystemCallError</code>.
- * As the subclass is created in module <code>Errno</code>, its name
- * will start <code>Errno::</code>.
+ * Ruby exception objects are subclasses of Exception. However,
+ * operating systems typically report errors using plain
+ * integers. Module Errno is created dynamically to map these
+ * operating system errors to Ruby classes, with each error number
+ * generating its own subclass of SystemCallError. As the subclass
+ * is created in module Errno, its name will start
+ * <code>Errno::</code>.
*
- * The names of the <code>Errno::</code> classes depend on
- * the environment in which Ruby runs. On a typical Unix or Windows
- * platform, there are <code>Errno</code> classes such as
- * <code>Errno::EACCES</code>, <code>Errno::EAGAIN</code>,
- * <code>Errno::EINTR</code>, and so on.
+ * The names of the <code>Errno::</code> classes depend on the
+ * environment in which Ruby runs. On a typical Unix or Windows
+ * platform, there are Errno classes such as Errno::EACCES,
+ * Errno::EAGAIN, Errno::EINTR, and so on.
*
* The integer operating system error number corresponding to a
* particular error is available as the class constant
@@ -1623,7 +2170,7 @@ syntax_error_initialize(int argc, VALUE *argv, VALUE self)
* Errno::EINTR::Errno #=> 4
*
* The full list of operating system errors on your particular platform
- * are available as the constants of <code>Errno</code>.
+ * are available as the constants of Errno.
*
* Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ...
*/
@@ -1682,11 +2229,10 @@ get_syserr(int n)
* call-seq:
* SystemCallError.new(msg, errno) -> system_call_error_subclass
*
- * If _errno_ corresponds to a known system error code, constructs
- * the appropriate <code>Errno</code> class for that error, otherwise
- * constructs a generic <code>SystemCallError</code> object. The
- * error number is subsequently available via the <code>errno</code>
- * method.
+ * If _errno_ corresponds to a known system error code, constructs the
+ * appropriate Errno class for that error, otherwise constructs a
+ * generic SystemCallError object. The error number is subsequently
+ * available via the #errno method.
*/
static VALUE
@@ -1727,7 +2273,6 @@ syserr_initialize(int argc, VALUE *argv, VALUE self)
if (!NIL_P(func)) rb_str_catf(errmsg, " @ %"PRIsVALUE, func);
rb_str_catf(errmsg, " - %"PRIsVALUE, str);
- OBJ_INFECT(errmsg, mesg);
}
mesg = errmsg;
@@ -1826,8 +2371,8 @@ syserr_eqq(VALUE self, VALUE exc)
/*
* Document-class: Interrupt
*
- * Raised with the interrupt signal is received, typically because the
- * user pressed on Control-C (on most posix platforms). As such, it is a
+ * Raised when the interrupt signal is received, typically because the
+ * user has pressed Control-C (on most posix platforms). As such, it is a
* subclass of +SignalException+.
*
* begin
@@ -2000,17 +2545,22 @@ syserr_eqq(VALUE self, VALUE exc)
*/
/*
- * Document-class: RuntimeError
+ * Document-class: FrozenError
*
- * A generic error class raised when an invalid operation is attempted.
+ * Raised when there is an attempt to modify a frozen object.
*
* [1, 2, 3].freeze << 4
*
* <em>raises the exception:</em>
*
- * RuntimeError: can't modify frozen Array
+ * FrozenError: can't modify frozen Array
+ */
+
+/*
+ * Document-class: RuntimeError
*
- * Kernel.raise will raise a RuntimeError if no Exception class is
+ * A generic error class raised when an invalid operation is attempted.
+ * Kernel#raise will raise a RuntimeError if no Exception class is
* specified.
*
* raise "ouch"
@@ -2023,19 +2573,7 @@ syserr_eqq(VALUE self, VALUE exc)
/*
* Document-class: SecurityError
*
- * Raised when attempting a potential unsafe operation, typically when
- * the $SAFE level is raised above 0.
- *
- * foo = "bar"
- * proc = Proc.new do
- * $SAFE = 3
- * foo.untaint
- * end
- * proc.call
- *
- * <em>raises the exception:</em>
- *
- * SecurityError: Insecure: Insecure operation `untaint' at level 3
+ * No longer used by internal code.
*/
/*
@@ -2077,7 +2615,7 @@ syserr_eqq(VALUE self, VALUE exc)
* Document-class: fatal
*
* fatal is an Exception that is raised when Ruby has encountered a fatal
- * error and must exit. You are not able to rescue fatal.
+ * error and must exit.
*/
/*
@@ -2086,32 +2624,48 @@ syserr_eqq(VALUE self, VALUE exc)
*/
/*
- * Descendants of class Exception are used to communicate between
+ * Document-class: Exception
+ *
+ * \Class Exception and its subclasses are used to communicate between
* Kernel#raise and +rescue+ statements in <code>begin ... end</code> blocks.
- * Exception objects carry information about the exception -- its type (the
- * exception's class name), an optional descriptive string, and optional
- * traceback information. Exception subclasses may add additional
- * information like NameError#name.
*
- * Programs may make subclasses of Exception, typically of StandardError or
- * RuntimeError, to provide custom classes and add additional information.
- * See the subclass list below for defaults for +raise+ and +rescue+.
+ * An Exception object carries information about an exception:
+ * - Its type (the exception's class).
+ * - An optional descriptive message.
+ * - Optional backtrace information.
+ *
+ * Some built-in subclasses of Exception have additional methods: e.g., NameError#name.
+ *
+ * == Defaults
+ *
+ * Two Ruby statements have default exception classes:
+ * - +raise+: defaults to RuntimeError.
+ * - +rescue+: defaults to StandardError.
+ *
+ * == Global Variables
*
* When an exception has been raised but not yet handled (in +rescue+,
- * +ensure+, +at_exit+ and +END+ blocks) the global variable <code>$!</code>
- * will contain the current exception and <code>$@</code> contains the
- * current exception's backtrace.
+ * +ensure+, +at_exit+ and +END+ blocks), two global variables are set:
+ * - <code>$!</code> contains the current exception.
+ * - <code>$@</code> contains its backtrace.
+ *
+ * == Custom Exceptions
+ *
+ * To provide additional or alternate information,
+ * a program may create custom exception classes
+ * that derive from the built-in exception classes.
*
- * It is recommended that a library should have one subclass of StandardError
- * or RuntimeError and have specific exception types inherit from it. This
- * allows the user to rescue a generic exception type to catch all exceptions
+ * A good practice is for a library to create a single "generic" exception class
+ * (typically a subclass of StandardError or RuntimeError)
+ * and have its other exception classes derive from that class.
+ * This allows the user to rescue the generic exception, thus catching all exceptions
* the library may raise even if future versions of the library add new
* exception subclasses.
*
* For example:
*
* class MyLibrary
- * class Error < RuntimeError
+ * class Error < ::StandardError
* end
*
* class WidgetError < Error
@@ -2122,8 +2676,10 @@ syserr_eqq(VALUE self, VALUE exc)
*
* end
*
- * To handle both WidgetError and FrobError the library user can rescue
- * MyLibrary::Error.
+ * To handle both MyLibrary::WidgetError and MyLibrary::FrobError the library
+ * user can rescue MyLibrary::Error.
+ *
+ * == Built-In Exception Classes
*
* The built-in subclasses of Exception are:
*
@@ -2135,7 +2691,7 @@ syserr_eqq(VALUE self, VALUE exc)
* * SecurityError
* * SignalException
* * Interrupt
- * * StandardError -- default for +rescue+
+ * * StandardError
* * ArgumentError
* * UncaughtThrowError
* * EncodingError
@@ -2145,13 +2701,15 @@ syserr_eqq(VALUE self, VALUE exc)
* * IndexError
* * KeyError
* * StopIteration
+ * * ClosedQueueError
* * LocalJumpError
* * NameError
* * NoMethodError
* * RangeError
* * FloatDomainError
* * RegexpError
- * * RuntimeError -- default for +raise+
+ * * RuntimeError
+ * * FrozenError
* * SystemCallError
* * Errno::*
* * ThreadError
@@ -2159,19 +2717,67 @@ syserr_eqq(VALUE self, VALUE exc)
* * ZeroDivisionError
* * SystemExit
* * SystemStackError
- * * fatal -- impossible to rescue
+ * * fatal
*/
+static VALUE
+exception_alloc(VALUE klass)
+{
+ return rb_class_allocate_instance(klass);
+}
+
+static VALUE
+exception_dumper(VALUE exc)
+{
+ // TODO: Currently, the instance variables "bt" and "bt_locations"
+ // refers to the same object (Array of String). But "bt_locations"
+ // should have an Array of Thread::Backtrace::Locations.
+
+ return exc;
+}
+
+static int
+ivar_copy_i(st_data_t key, st_data_t val, st_data_t exc)
+{
+ rb_ivar_set((VALUE) exc, (ID) key, (VALUE) val);
+ return ST_CONTINUE;
+}
+
+static VALUE
+exception_loader(VALUE exc, VALUE obj)
+{
+ // The loader function of rb_marshal_define_compat seems to be called for two events:
+ // one is for fixup (r_fixup_compat), the other is for TYPE_USERDEF.
+ // In the former case, the first argument is an instance of Exception (because
+ // we pass rb_eException to rb_marshal_define_compat). In the latter case, the first
+ // argument is a class object (see TYPE_USERDEF case in r_object0).
+ // We want to copy all instance variables (but "bt_locations") from obj to exc.
+ // But we do not want to do so in the second case, so the following branch is for that.
+ if (RB_TYPE_P(exc, T_CLASS)) return obj; // maybe called from Marshal's TYPE_USERDEF
+
+ rb_ivar_foreach(obj, ivar_copy_i, exc);
+
+ if (rb_attr_get(exc, id_bt) == rb_attr_get(exc, id_bt_locations)) {
+ rb_ivar_set(exc, id_bt_locations, Qnil);
+ }
+
+ return exc;
+}
+
void
Init_Exception(void)
{
rb_eException = rb_define_class("Exception", rb_cObject);
+ rb_define_alloc_func(rb_eException, exception_alloc);
+ rb_marshal_define_compat(rb_eException, rb_eException, exception_dumper, exception_loader);
rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
+ rb_define_singleton_method(rb_eException, "to_tty?", exc_s_to_tty_p, 0);
rb_define_method(rb_eException, "exception", exc_exception, -1);
rb_define_method(rb_eException, "initialize", exc_initialize, -1);
rb_define_method(rb_eException, "==", exc_equal, 1);
rb_define_method(rb_eException, "to_s", exc_to_s, 0);
rb_define_method(rb_eException, "message", exc_message, 0);
+ rb_define_method(rb_eException, "full_message", exc_full_message, -1);
rb_define_method(rb_eException, "inspect", exc_inspect, 0);
rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
rb_define_method(rb_eException, "backtrace_locations", exc_backtrace_locations, 0);
@@ -2192,6 +2798,7 @@ Init_Exception(void)
rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
+ rb_define_method(rb_eKeyError, "initialize", key_err_initialize, -1);
rb_define_method(rb_eKeyError, "receiver", key_err_receiver, 0);
rb_define_method(rb_eKeyError, "key", key_err_key, 0);
rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
@@ -2211,7 +2818,9 @@ Init_Exception(void)
rb_define_method(rb_eNameError, "name", name_err_name, 0);
rb_define_method(rb_eNameError, "receiver", name_err_receiver, 0);
rb_define_method(rb_eNameError, "local_variables", name_err_local_variables, 0);
- rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cData);
+ rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cObject);
+ rb_define_alloc_func(rb_cNameErrorMesg, name_err_mesg_alloc);
+ rb_define_method(rb_cNameErrorMesg, "initialize_copy", name_err_mesg_init_copy, 1);
rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_dump, 1);
@@ -2222,10 +2831,14 @@ Init_Exception(void)
rb_define_method(rb_eNoMethodError, "private_call?", nometh_err_private_call_p, 0);
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
+ rb_eFrozenError = rb_define_class("FrozenError", rb_eRuntimeError);
+ rb_define_method(rb_eFrozenError, "initialize", frozen_err_initialize, -1);
+ rb_define_method(rb_eFrozenError, "receiver", frozen_err_receiver, 0);
rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError);
+ rb_eNoMatchingPatternError = rb_define_class("NoMatchingPatternError", rb_eStandardError);
syserr_tbl = st_init_numtable();
rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
@@ -2236,19 +2849,18 @@ Init_Exception(void)
rb_mErrno = rb_define_module("Errno");
rb_mWarning = rb_define_module("Warning");
- rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, 1);
+ rb_define_singleton_method(rb_mWarning, "[]", rb_warning_s_aref, 1);
+ rb_define_singleton_method(rb_mWarning, "[]=", rb_warning_s_aset, 2);
+ rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, -1);
rb_extend_object(rb_mWarning, rb_mWarning);
+ /* :nodoc: */
rb_cWarningBuffer = rb_define_class_under(rb_mWarning, "buffer", rb_cString);
- rb_define_method(rb_cWarningBuffer, "write", rb_str_append, 1);
+ rb_define_method(rb_cWarningBuffer, "write", warning_write, -1);
- rb_define_global_function("warn", rb_warn_m, -1);
-
- id_new = rb_intern_const("new");
id_cause = rb_intern_const("cause");
id_message = rb_intern_const("message");
id_backtrace = rb_intern_const("backtrace");
- id_name = rb_intern_const("name");
id_key = rb_intern_const("key");
id_args = rb_intern_const("args");
id_receiver = rb_intern_const("receiver");
@@ -2258,7 +2870,28 @@ Init_Exception(void)
id_errno = rb_intern_const("errno");
id_i_path = rb_intern_const("@path");
id_warn = rb_intern_const("warn");
+ id_category = rb_intern_const("category");
+ id_deprecated = rb_intern_const("deprecated");
+ id_experimental = rb_intern_const("experimental");
+ id_top = rb_intern_const("top");
+ id_bottom = rb_intern_const("bottom");
id_iseq = rb_make_internal_id();
+ id_recv = rb_make_internal_id();
+
+ sym_category = ID2SYM(id_category);
+
+ warning_categories = rb_ident_hash_new();
+ rb_gc_register_mark_object(warning_categories);
+ rb_hash_aset(warning_categories, ID2SYM(id_deprecated), INT2NUM(RB_WARN_CATEGORY_DEPRECATED));
+ rb_hash_aset(warning_categories, ID2SYM(id_experimental), INT2NUM(RB_WARN_CATEGORY_EXPERIMENTAL));
+ rb_obj_freeze(warning_categories);
+
+ warning_category_t_map = rb_ident_hash_new();
+ rb_gc_register_mark_object(warning_category_t_map);
+ rb_hash_aset(warning_category_t_map, INT2NUM(RB_WARN_CATEGORY_NONE), Qnil);
+ rb_hash_aset(warning_category_t_map, INT2NUM(RB_WARN_CATEGORY_DEPRECATED), ID2SYM(id_deprecated));
+ rb_hash_aset(warning_category_t_map, INT2NUM(RB_WARN_CATEGORY_EXPERIMENTAL), ID2SYM(id_experimental));
+ rb_obj_freeze(warning_category_t_map);
}
void
@@ -2275,15 +2908,18 @@ rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
}
void
+rb_vraise(VALUE exc, const char *fmt, va_list ap)
+{
+ rb_exc_raise(rb_exc_new3(exc, rb_vsprintf(fmt, ap)));
+}
+
+void
rb_raise(VALUE exc, const char *fmt, ...)
{
va_list args;
- VALUE mesg;
-
va_start(args, fmt);
- mesg = rb_vsprintf(fmt, args);
+ rb_vraise(exc, fmt, args);
va_end(args);
- rb_exc_raise(rb_exc_new3(exc, mesg));
}
NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
@@ -2334,6 +2970,14 @@ rb_fatal(const char *fmt, ...)
va_list args;
VALUE mesg;
+ if (! ruby_thread_has_gvl_p()) {
+ /* The thread has no GVL. Object allocation impossible (cant run GC),
+ * thus no message can be printed out. */
+ fprintf(stderr, "[FATAL] rb_fatal() outside of GVL\n");
+ rb_print_backtrace();
+ die();
+ }
+
va_start(args, fmt);
mesg = rb_vsprintf(fmt, args);
va_end(args);
@@ -2418,6 +3062,12 @@ rb_sys_fail_path_in(const char *func_name, VALUE path)
void
rb_syserr_fail_path_in(const char *func_name, int n, VALUE path)
{
+ rb_exc_raise(rb_syserr_new_path_in(func_name, n, path));
+}
+
+VALUE
+rb_syserr_new_path_in(const char *func_name, int n, VALUE path)
+{
VALUE args[2];
if (!path) path = Qnil;
@@ -2429,7 +3079,7 @@ rb_syserr_fail_path_in(const char *func_name, int n, VALUE path)
}
args[0] = path;
args[1] = rb_str_new_cstr(func_name);
- rb_exc_raise(rb_class_new_instance(2, args, get_syserr(n)));
+ return rb_class_new_instance(2, args, get_syserr(n));
}
#endif
@@ -2577,7 +3227,33 @@ rb_load_fail(VALUE path, const char *err)
void
rb_error_frozen(const char *what)
{
- rb_raise(rb_eRuntimeError, "can't modify frozen %s", what);
+ rb_raise(rb_eFrozenError, "can't modify frozen %s", what);
+}
+
+void
+rb_frozen_error_raise(VALUE frozen_obj, const char *fmt, ...)
+{
+ va_list args;
+ VALUE exc, mesg;
+
+ va_start(args, fmt);
+ mesg = rb_vsprintf(fmt, args);
+ va_end(args);
+ exc = rb_exc_new3(rb_eFrozenError, mesg);
+ rb_ivar_set(exc, id_recv, frozen_obj);
+ rb_exc_raise(exc);
+}
+
+static VALUE
+inspect_frozen_obj(VALUE obj, VALUE mesg, int recur)
+{
+ if (recur) {
+ rb_str_cat_cstr(mesg, " ...");
+ }
+ else {
+ rb_str_append(mesg, rb_inspect(obj));
+ }
+ return mesg;
}
void
@@ -2585,18 +3261,20 @@ rb_error_frozen_object(VALUE frozen_obj)
{
VALUE debug_info;
const ID created_info = id_debug_created_info;
+ VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ",
+ CLASS_OF(frozen_obj));
+ VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg);
+
+ rb_ivar_set(exc, id_recv, frozen_obj);
+ rb_exec_recursive(inspect_frozen_obj, frozen_obj, mesg);
if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
VALUE path = rb_ary_entry(debug_info, 0);
VALUE line = rb_ary_entry(debug_info, 1);
- rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
- CLASS_OF(frozen_obj), path, line);
- }
- else {
- rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE,
- CLASS_OF(frozen_obj));
+ rb_str_catf(mesg, ", created at %"PRIsVALUE":%"PRIsVALUE, path, line);
}
+ rb_exc_raise(exc);
}
#undef rb_check_frozen
@@ -2609,12 +3287,14 @@ rb_check_frozen(VALUE obj)
void
rb_error_untrusted(VALUE obj)
{
+ rb_warn_deprecated_to_remove("rb_error_untrusted", "3.2");
}
#undef rb_check_trusted
void
rb_check_trusted(VALUE obj)
{
+ rb_warn_deprecated_to_remove("rb_check_trusted", "3.2");
}
void
@@ -2623,12 +3303,6 @@ rb_check_copyable(VALUE obj, VALUE orig)
if (!FL_ABLE(obj)) return;
rb_check_frozen_internal(obj);
if (!FL_ABLE(orig)) return;
- if ((~RBASIC(obj)->flags & RBASIC(orig)->flags) & FL_TAINT) {
- if (rb_safe_level() > 0) {
- rb_raise(rb_eSecurityError, "Insecure: can't modify %"PRIsVALUE,
- RBASIC(obj)->klass);
- }
- }
}
void
@@ -2642,6 +3316,8 @@ Init_syserr(void)
#undef undefined_error
}
+#include "warning.rbinc"
+
/*!
* \}
*/
diff --git a/eval.c b/eval.c
index 00b5156c86..839518185a 100644
--- a/eval.c
+++ b/eval.c
@@ -11,23 +11,46 @@
**********************************************************************/
-#include "internal.h"
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
#include "eval_intern.h"
-#include "iseq.h"
#include "gc.h"
+#include "internal.h"
+#include "internal/class.h"
+#include "internal/error.h"
+#include "internal/eval.h"
+#include "internal/hash.h"
+#include "internal/inits.h"
+#include "internal/io.h"
+#include "internal/object.h"
+#include "internal/thread.h"
+#include "internal/variable.h"
+#include "internal/scheduler.h"
+#include "iseq.h"
+#include "mjit.h"
+#include "probes.h"
+#include "probes_helper.h"
#include "ruby/vm.h"
#include "vm_core.h"
-#include "probes_helper.h"
+#include "ractor_core.h"
NORETURN(void rb_raise_jump(VALUE, VALUE));
+void rb_ec_clear_current_thread_trace_func(const rb_execution_context_t *ec);
+void rb_ec_clear_all_trace_func(const rb_execution_context_t *ec);
+
+static int rb_ec_cleanup(rb_execution_context_t *ec, volatile int ex);
+static int rb_ec_exec_node(rb_execution_context_t *ec, void *n);
VALUE rb_eLocalJumpError;
VALUE rb_eSysStackError;
ID ruby_static_id_signo, ruby_static_id_status;
-static ID id_cause;
-#define id_signo ruby_static_id_signo
-#define id_status ruby_static_id_status
+extern ID ruby_static_id_cause;
+#define id_cause ruby_static_id_cause
#define exception_error GET_VM()->special_exceptions[ruby_error_reenter]
@@ -39,7 +62,7 @@ static ID id_cause;
(BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE))
/*!
- * Initializes the Ruby VM and builtin libraries.
+ * Initializes the VM and builtin libraries.
* @retval 0 if succeeded.
* @retval non-zero an error occurred.
*/
@@ -52,17 +75,26 @@ ruby_setup(void)
return 0;
ruby_init_stack((void *)&state);
+
+ /*
+ * Disable THP early before mallocs happen because we want this to
+ * affect as many future pages as possible for CoW-friendliness
+ */
+#if defined(__linux__) && defined(PR_SET_THP_DISABLE)
+ prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);
+#endif
Init_BareVM();
Init_heap();
+ rb_vm_encoded_insn_data_table_init();
Init_vm_objects();
- PUSH_TAG();
- if ((state = EXEC_TAG()) == TAG_NONE) {
+ EC_PUSH_TAG(GET_EC());
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
rb_call_inits();
ruby_prog_init();
GET_VM()->running = 1;
}
- POP_TAG();
+ EC_POP_TAG();
return state;
}
@@ -78,7 +110,7 @@ ruby_init(void)
int state = ruby_setup();
if (state) {
if (RTEST(ruby_debug))
- error_print(GET_THREAD());
+ error_print(GET_EC());
exit(EXIT_FAILURE);
}
}
@@ -96,41 +128,60 @@ ruby_init(void)
void *
ruby_options(int argc, char **argv)
{
+ rb_execution_context_t *ec = GET_EC();
enum ruby_tag_type state;
void *volatile iseq = 0;
ruby_init_stack((void *)&iseq);
- PUSH_TAG();
- if ((state = EXEC_TAG()) == TAG_NONE) {
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
SAVE_ROOT_JMPBUF(GET_THREAD(), iseq = ruby_process_options(argc, argv));
}
else {
- rb_clear_trace_func();
- state = error_handle(state);
+ rb_ec_clear_current_thread_trace_func(ec);
+ state = error_handle(ec, state);
iseq = (void *)INT2FIX(state);
}
- POP_TAG();
+ EC_POP_TAG();
return iseq;
}
static void
-ruby_finalize_0(void)
+rb_ec_scheduler_finalize(rb_execution_context_t *ec)
+{
+ enum ruby_tag_type state;
+
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
+ rb_scheduler_set(Qnil);
+ }
+ else {
+ state = error_handle(ec, state);
+ }
+ EC_POP_TAG();
+}
+
+static void
+rb_ec_teardown(rb_execution_context_t *ec)
{
- PUSH_TAG();
- if (EXEC_TAG() == TAG_NONE) {
- rb_trap_exit();
+ // If the user code defined a scheduler for the top level thread, run it:
+ rb_ec_scheduler_finalize(ec);
+
+ EC_PUSH_TAG(ec);
+ if (EC_EXEC_TAG() == TAG_NONE) {
+ rb_vm_trap_exit(rb_ec_vm_ptr(ec));
}
- POP_TAG();
- rb_exec_end_proc();
- rb_clear_trace_func();
+ EC_POP_TAG();
+ rb_ec_exec_end_proc(ec);
+ rb_ec_clear_all_trace_func(ec);
}
static void
-ruby_finalize_1(void)
+rb_ec_finalize(rb_execution_context_t *ec)
{
ruby_sig_finalize();
- GET_THREAD()->ec.errinfo = Qnil;
- rb_gc_call_finalizer_at_exit();
+ ec->errinfo = Qnil;
+ rb_objspace_call_finalizer(rb_ec_vm_ptr(ec)->objspace);
}
/** Runs the VM finalization processes.
@@ -143,8 +194,9 @@ ruby_finalize_1(void)
void
ruby_finalize(void)
{
- ruby_finalize_0();
- ruby_finalize_1();
+ rb_execution_context_t *ec = GET_EC();
+ rb_ec_teardown(ec);
+ rb_ec_finalize(ec);
}
/** Destructs the VM.
@@ -160,32 +212,43 @@ ruby_finalize(void)
int
ruby_cleanup(volatile int ex)
{
+ return rb_ec_cleanup(GET_EC(), ex);
+}
+
+static int
+rb_ec_cleanup(rb_execution_context_t *ec, volatile int ex)
+{
int state;
- volatile VALUE errs[2];
- rb_thread_t *th = GET_THREAD();
+ volatile VALUE errs[2] = { Qundef, Qundef };
int nerr;
+ rb_thread_t *th = rb_ec_thread_ptr(ec);
+ rb_thread_t *const volatile th0 = th;
volatile int sysex = EXIT_SUCCESS;
volatile int step = 0;
rb_threadptr_interrupt(th);
rb_threadptr_check_signal(th);
- TH_PUSH_TAG(th);
- if ((state = EXEC_TAG()) == TAG_NONE) {
- SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(th); });
+
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
+ th = th0;
+ SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(ec); });
step_0: step++;
- errs[1] = th->ec.errinfo;
- th->ec.safe_level = 0;
+ th = th0;
+ errs[1] = ec->errinfo;
+ if (THROW_DATA_P(ec->errinfo)) ec->errinfo = Qnil;
ruby_init_stack(&errs[STACK_UPPER(errs, 0, 1)]);
- SAVE_ROOT_JMPBUF(th, ruby_finalize_0());
+ SAVE_ROOT_JMPBUF(th, rb_ec_teardown(ec));
step_1: step++;
+ th = th0;
/* protect from Thread#raise */
th->status = THREAD_KILLED;
- errs[0] = th->ec.errinfo;
- SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
+ errs[0] = ec->errinfo;
+ SAVE_ROOT_JMPBUF(th, rb_ractor_terminate_all());
}
else {
switch (step) {
@@ -194,16 +257,18 @@ ruby_cleanup(volatile int ex)
}
if (ex == 0) ex = state;
}
- th->ec.errinfo = errs[1];
- sysex = error_handle(ex);
+ th = th0;
+ ec->errinfo = errs[1];
+ sysex = error_handle(ec, ex);
state = 0;
for (nerr = 0; nerr < numberof(errs); ++nerr) {
VALUE err = ATOMIC_VALUE_EXCHANGE(errs[nerr], Qnil);
+ VALUE sig;
if (!RTEST(err)) continue;
- /* th->ec.errinfo contains a NODE while break'ing */
+ /* ec->errinfo contains a NODE while break'ing */
if (THROW_DATA_P(err)) continue;
if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
@@ -215,39 +280,45 @@ ruby_cleanup(volatile int ex)
state = NUM2INT(sig);
break;
}
+ else if (rb_obj_is_kind_of(err, rb_eSystemCallError) &&
+ FIXNUM_P(sig = rb_attr_get(err, id_signo))) {
+ state = NUM2INT(sig);
+ break;
+ }
else if (sysex == EXIT_SUCCESS) {
sysex = EXIT_FAILURE;
}
}
- ruby_finalize_1();
+ mjit_finish(true); // We still need ISeqs here.
+
+ rb_ec_finalize(ec);
/* unlock again if finalizer took mutexes. */
- rb_threadptr_unlock_all_locking_mutexes(GET_THREAD());
- TH_POP_TAG();
+ rb_threadptr_unlock_all_locking_mutexes(th);
+ EC_POP_TAG();
rb_thread_stop_timer_thread();
- ruby_vm_destruct(GET_VM());
+ ruby_vm_destruct(th->vm);
if (state) ruby_default_signal(state);
return sysex;
}
static int
-ruby_exec_internal(void *n)
+rb_ec_exec_node(rb_execution_context_t *ec, void *n)
{
volatile int state;
rb_iseq_t *iseq = (rb_iseq_t *)n;
- rb_thread_t *th = GET_THREAD();
-
if (!n) return 0;
- TH_PUSH_TAG(th);
- if ((state = EXEC_TAG()) == TAG_NONE) {
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
+ rb_thread_t *const th = rb_ec_thread_ptr(ec);
SAVE_ROOT_JMPBUF(th, {
rb_iseq_eval_main(iseq);
});
}
- TH_POP_TAG();
+ EC_POP_TAG();
return state;
}
@@ -294,12 +365,14 @@ ruby_executable_node(void *n, int *status)
int
ruby_run_node(void *n)
{
+ rb_execution_context_t *ec = GET_EC();
int status;
if (!ruby_executable_node(n, &status)) {
- ruby_cleanup(0);
+ rb_ec_cleanup(ec, 0);
return status;
}
- return ruby_cleanup(ruby_exec_node(n));
+ ruby_init_stack((void *)&status);
+ return rb_ec_cleanup(ec, rb_ec_exec_node(ec, n));
}
/*! Runs the given compiled source */
@@ -307,7 +380,7 @@ int
ruby_exec_node(void *n)
{
ruby_init_stack((void *)&n);
- return ruby_exec_internal(n);
+ return rb_ec_exec_node(GET_EC(), n);
}
/*
@@ -326,7 +399,7 @@ ruby_exec_node(void *n)
*/
static VALUE
-rb_mod_nesting(void)
+rb_mod_nesting(VALUE _)
{
VALUE ary = rb_ary_new();
const rb_cref_t *cref = rb_vm_cref();
@@ -401,10 +474,9 @@ rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
* \ingroup class
*/
void
-rb_frozen_class_p(VALUE klass)
+rb_class_modify_check(VALUE klass)
{
if (SPECIAL_CONST_P(klass)) {
- noclass:
Check_Type(klass, T_CLASS);
}
if (OBJ_FROZEN(klass)) {
@@ -422,6 +494,8 @@ rb_frozen_class_p(VALUE klass)
case T_CLASS:
desc = "Class";
break;
+ default:
+ break;
}
}
}
@@ -435,21 +509,22 @@ rb_frozen_class_p(VALUE klass)
desc = "class";
break;
default:
- goto noclass;
+ Check_Type(klass, T_CLASS);
+ UNREACHABLE;
}
}
- rb_error_frozen(desc);
+ rb_frozen_error_raise(klass, "can't modify frozen %s: %"PRIsVALUE, desc, klass);
}
}
-NORETURN(static void rb_longjmp(rb_thread_t *, int, volatile VALUE, VALUE));
+NORETURN(static void rb_longjmp(rb_execution_context_t *, int, volatile VALUE, VALUE));
static VALUE get_errinfo(void);
-static VALUE get_thread_errinfo(rb_thread_t *th);
+#define get_ec_errinfo(ec) rb_ec_get_errinfo(ec)
static VALUE
exc_setup_cause(VALUE exc, VALUE cause)
{
-#if SUPPORT_JOKE
+#if OPT_SUPPORT_JOKE
if (NIL_P(cause)) {
ID id_true_cause;
CONST_ID(id_true_cause, "true_cause");
@@ -473,77 +548,96 @@ exc_setup_cause(VALUE exc, VALUE cause)
}
static inline VALUE
-exc_setup_message(rb_thread_t *th, VALUE mesg, VALUE *cause)
+exc_setup_message(const rb_execution_context_t *ec, VALUE mesg, VALUE *cause)
{
int nocause = 0;
+ int nocircular = 0;
if (NIL_P(mesg)) {
- mesg = th->ec.errinfo;
- if (INTERNAL_EXCEPTION_P(mesg)) TH_JUMP_TAG(th, TAG_FATAL);
+ mesg = ec->errinfo;
+ if (INTERNAL_EXCEPTION_P(mesg)) EC_JUMP_TAG(ec, TAG_FATAL);
nocause = 1;
}
if (NIL_P(mesg)) {
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
nocause = 0;
+ nocircular = 1;
}
if (*cause == Qundef) {
if (nocause) {
*cause = Qnil;
+ nocircular = 1;
}
else if (!rb_ivar_defined(mesg, id_cause)) {
- *cause = get_thread_errinfo(th);
+ *cause = get_ec_errinfo(ec);
}
+ else {
+ nocircular = 1;
+ }
+ }
+ else if (!NIL_P(*cause) && !rb_obj_is_kind_of(*cause, rb_eException)) {
+ rb_raise(rb_eTypeError, "exception object expected");
+ }
+
+ if (!nocircular && !NIL_P(*cause) && *cause != Qundef && *cause != mesg) {
+ VALUE c = *cause;
+ while (!NIL_P(c = rb_attr_get(c, id_cause))) {
+ if (c == mesg) {
+ rb_raise(rb_eArgError, "circular causes");
+ }
+ }
}
return mesg;
}
static void
-setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
+setup_exception(rb_execution_context_t *ec, int tag, volatile VALUE mesg, VALUE cause)
{
VALUE e;
- const char *file = 0;
int line;
+ const char *file = rb_source_location_cstr(&line);
+ const char *const volatile file0 = file;
- file = rb_source_loc(&line);
if ((file && !NIL_P(mesg)) || (cause != Qundef)) {
volatile int state = 0;
- TH_PUSH_TAG(th);
- if (EXEC_TAG() == TAG_NONE && !(state = rb_threadptr_set_raised(th))) {
+ EC_PUSH_TAG(ec);
+ if (EC_EXEC_TAG() == TAG_NONE && !(state = rb_ec_set_raised(ec))) {
VALUE bt = rb_get_backtrace(mesg);
if (!NIL_P(bt) || cause == Qundef) {
if (OBJ_FROZEN(mesg)) {
mesg = rb_obj_dup(mesg);
}
}
- if (cause != Qundef) {
+ if (cause != Qundef && !THROW_DATA_P(cause)) {
exc_setup_cause(mesg, cause);
}
if (NIL_P(bt)) {
- VALUE at = rb_threadptr_backtrace_object(th);
+ VALUE at = rb_ec_backtrace_object(ec);
rb_ivar_set(mesg, idBt_locations, at);
set_backtrace(mesg, at);
}
- rb_threadptr_reset_raised(th);
+ rb_ec_reset_raised(ec);
}
- TH_POP_TAG();
+ EC_POP_TAG();
+ file = file0;
if (state) goto fatal;
}
if (!NIL_P(mesg)) {
- th->ec.errinfo = mesg;
+ ec->errinfo = mesg;
}
- if (RTEST(ruby_debug) && !NIL_P(e = th->ec.errinfo) &&
+ if (RTEST(ruby_debug) && !NIL_P(e = ec->errinfo) &&
!rb_obj_is_kind_of(e, rb_eSystemExit)) {
enum ruby_tag_type state;
mesg = e;
- TH_PUSH_TAG(th);
- if ((state = EXEC_TAG()) == TAG_NONE) {
- th->ec.errinfo = Qnil;
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
+ ec->errinfo = Qnil;
e = rb_obj_as_string(mesg);
- th->ec.errinfo = mesg;
+ ec->errinfo = mesg;
if (file && line) {
e = rb_sprintf("Exception `%"PRIsVALUE"' at %s:%d - %"PRIsVALUE"\n",
rb_obj_class(mesg), file, line, e);
@@ -558,35 +652,38 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
}
warn_print_str(e);
}
- TH_POP_TAG();
- if (state == TAG_FATAL && th->ec.errinfo == exception_error) {
- th->ec.errinfo = mesg;
+ EC_POP_TAG();
+ if (state == TAG_FATAL && ec->errinfo == exception_error) {
+ ec->errinfo = mesg;
}
else if (state) {
- rb_threadptr_reset_raised(th);
- TH_JUMP_TAG(th, state);
+ rb_ec_reset_raised(ec);
+ EC_JUMP_TAG(ec, state);
}
}
- if (rb_threadptr_set_raised(th)) {
- fatal:
- th->ec.errinfo = exception_error;
- rb_threadptr_reset_raised(th);
- TH_JUMP_TAG(th, TAG_FATAL);
+ if (rb_ec_set_raised(ec)) {
+ goto fatal;
}
if (tag != TAG_FATAL) {
- RUBY_DTRACE_HOOK(RAISE, rb_obj_classname(th->ec.errinfo));
- EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->ec.cfp->self, 0, 0, 0, mesg);
+ RUBY_DTRACE_HOOK(RAISE, rb_obj_classname(ec->errinfo));
+ EXEC_EVENT_HOOK(ec, RUBY_EVENT_RAISE, ec->cfp->self, 0, 0, 0, mesg);
}
+ return;
+
+ fatal:
+ ec->errinfo = exception_error;
+ rb_ec_reset_raised(ec);
+ EC_JUMP_TAG(ec, TAG_FATAL);
}
/*! \private */
void
-rb_threadptr_setup_exception(rb_thread_t *th, VALUE mesg, VALUE cause)
+rb_ec_setup_exception(const rb_execution_context_t *ec, VALUE mesg, VALUE cause)
{
if (cause == Qundef) {
- cause = get_thread_errinfo(th);
+ cause = get_ec_errinfo(ec);
}
if (cause != mesg) {
rb_ivar_set(mesg, id_cause, cause);
@@ -594,12 +691,12 @@ rb_threadptr_setup_exception(rb_thread_t *th, VALUE mesg, VALUE cause)
}
static void
-rb_longjmp(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
+rb_longjmp(rb_execution_context_t *ec, int tag, volatile VALUE mesg, VALUE cause)
{
- mesg = exc_setup_message(th, mesg, &cause);
- setup_exception(th, tag, mesg, cause);
- rb_thread_raised_clear(th);
- TH_JUMP_TAG(th, tag);
+ mesg = exc_setup_message(ec, mesg, &cause);
+ setup_exception(ec, tag, mesg, cause);
+ rb_ec_raised_clear(ec);
+ EC_JUMP_TAG(ec, tag);
}
static VALUE make_exception(int argc, const VALUE *argv, int isstr);
@@ -617,7 +714,7 @@ rb_exc_raise(VALUE mesg)
if (!NIL_P(mesg)) {
mesg = make_exception(1, &mesg, FALSE);
}
- rb_longjmp(GET_THREAD(), TAG_RAISE, mesg, Qundef);
+ rb_longjmp(GET_EC(), TAG_RAISE, mesg, Qundef);
}
/*!
@@ -633,7 +730,7 @@ rb_exc_fatal(VALUE mesg)
if (!NIL_P(mesg)) {
mesg = make_exception(1, &mesg, FALSE);
}
- rb_longjmp(GET_THREAD(), TAG_FATAL, mesg, Qnil);
+ rb_longjmp(GET_EC(), TAG_FATAL, mesg, Qnil);
}
/*!
@@ -643,7 +740,7 @@ rb_exc_fatal(VALUE mesg)
void
rb_interrupt(void)
{
- rb_raise(rb_eInterrupt, "%s", "");
+ rb_exc_raise(rb_exc_new(rb_eInterrupt, 0, 0));
}
enum {raise_opt_cause, raise_max_opt}; /*< \private */
@@ -670,95 +767,98 @@ extract_raise_opts(int argc, const VALUE *argv, VALUE *opts)
return argc;
}
+VALUE
+rb_f_raise(int argc, VALUE *argv)
+{
+ VALUE err;
+ VALUE opts[raise_max_opt], *const cause = &opts[raise_opt_cause];
+
+ argc = extract_raise_opts(argc, argv, opts);
+ if (argc == 0) {
+ if (*cause != Qundef) {
+ rb_raise(rb_eArgError, "only cause is given with no arguments");
+ }
+ err = get_errinfo();
+ if (!NIL_P(err)) {
+ argc = 1;
+ argv = &err;
+ }
+ }
+ rb_raise_jump(rb_make_exception(argc, argv), *cause);
+
+ UNREACHABLE_RETURN(Qnil);
+}
+
/*
* call-seq:
* raise
- * raise(string)
- * raise(exception [, string [, array]])
+ * raise(string, cause: $!)
+ * raise(exception [, string [, array]], cause: $!)
* fail
- * fail(string)
- * fail(exception [, string [, array]])
+ * fail(string, cause: $!)
+ * fail(exception [, string [, array]], cause: $!)
*
* With no arguments, raises the exception in <code>$!</code> or raises
- * a <code>RuntimeError</code> if <code>$!</code> is +nil+.
- * With a single +String+ argument, raises a
- * +RuntimeError+ with the string as a message. Otherwise,
- * the first parameter should be the name of an +Exception+
- * class (or an object that returns an +Exception+ object when sent
- * an +exception+ message). The optional second parameter sets the
- * message associated with the exception, and the third parameter is an
- * array of callback information. Exceptions are caught by the
- * +rescue+ clause of <code>begin...end</code> blocks.
+ * a RuntimeError if <code>$!</code> is +nil+. With a single +String+
+ * argument, raises a +RuntimeError+ with the string as a message. Otherwise,
+ * the first parameter should be an +Exception+ class (or another
+ * object that returns an +Exception+ object when sent an +exception+
+ * message). The optional second parameter sets the message associated with
+ * the exception (accessible via Exception#message), and the third parameter
+ * is an array of callback information (accessible via Exception#backtrace).
+ * The +cause+ of the generated exception (accessible via Exception#cause)
+ * is automatically set to the "current" exception (<code>$!</code>), if any.
+ * An alternative value, either an +Exception+ object or +nil+, can be
+ * specified via the +:cause+ argument.
+ *
+ * Exceptions are caught by the +rescue+ clause of
+ * <code>begin...end</code> blocks.
*
* raise "Failed to create socket"
* raise ArgumentError, "No parameters", caller
*/
static VALUE
-rb_f_raise(int argc, VALUE *argv)
+f_raise(int c, VALUE *v, VALUE _)
{
- VALUE err;
- VALUE opts[raise_max_opt], *const cause = &opts[raise_opt_cause];
-
- argc = extract_raise_opts(argc, argv, opts);
- if (argc == 0) {
- if (*cause != Qundef) {
- rb_raise(rb_eArgError, "only cause is given with no arguments");
- }
- err = get_errinfo();
- if (!NIL_P(err)) {
- argc = 1;
- argv = &err;
- }
- }
- rb_raise_jump(rb_make_exception(argc, argv), *cause);
-
- UNREACHABLE;
+ return rb_f_raise(c, v);
}
static VALUE
make_exception(int argc, const VALUE *argv, int isstr)
{
VALUE mesg, exc;
- int n;
mesg = Qnil;
switch (argc) {
case 0:
- break;
+ return Qnil;
case 1:
exc = argv[0];
- if (NIL_P(exc))
- break;
- if (isstr) {
+ if (isstr &&! NIL_P(exc)) {
mesg = rb_check_string_type(exc);
if (!NIL_P(mesg)) {
- mesg = rb_exc_new3(rb_eRuntimeError, mesg);
- break;
+ return rb_exc_new3(rb_eRuntimeError, mesg);
}
}
- n = 0;
- goto exception_call;
case 2:
case 3:
- exc = argv[0];
- n = 1;
- exception_call:
- mesg = rb_check_funcall(exc, idException, n, argv+1);
- if (mesg == Qundef) {
- rb_raise(rb_eTypeError, "exception class/object expected");
- }
break;
default:
- rb_check_arity(argc, 0, 3);
- break;
+ rb_error_arity(argc, 0, 3);
}
- if (argc > 0) {
- if (!rb_obj_is_kind_of(mesg, rb_eException))
- rb_raise(rb_eTypeError, "exception object expected");
- if (argc > 2)
- set_backtrace(mesg, argv[2]);
+ if (NIL_P(mesg)) {
+ mesg = rb_check_funcall(argv[0], idException, argc != 1, &argv[1]);
+ }
+ if (mesg == Qundef) {
+ rb_raise(rb_eTypeError, "exception class/object expected");
+ }
+ if (!rb_obj_is_kind_of(mesg, rb_eException)) {
+ rb_raise(rb_eTypeError, "exception object expected");
+ }
+ if (argc == 3) {
+ set_backtrace(mesg, argv[2]);
}
return mesg;
@@ -796,17 +896,17 @@ rb_make_exception(int argc, const VALUE *argv)
void
rb_raise_jump(VALUE mesg, VALUE cause)
{
- rb_thread_t *th = GET_THREAD();
- const rb_control_frame_t *cfp = th->ec.cfp;
+ rb_execution_context_t *ec = GET_EC();
+ const rb_control_frame_t *cfp = ec->cfp;
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
VALUE klass = me->owner;
VALUE self = cfp->self;
ID mid = me->called_id;
- rb_vm_pop_frame(th);
- EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, self, me->def->original_id, mid, klass, Qnil);
+ rb_vm_pop_frame(ec);
+ EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, self, me->def->original_id, mid, klass, Qnil);
- rb_longjmp(th, TAG_RAISE, mesg, cause);
+ rb_longjmp(ec, TAG_RAISE, mesg, cause);
}
/*!
@@ -823,7 +923,7 @@ rb_jump_tag(int tag)
if (UNLIKELY(tag < TAG_RETURN || tag > TAG_FATAL)) {
unknown_longjmp_status(tag);
}
- JUMP_TAG(tag);
+ EC_JUMP_TAG(GET_EC(), tag);
}
/*! Determines if the current method is given a block.
@@ -834,8 +934,7 @@ rb_jump_tag(int tag)
int
rb_block_given_p(void)
{
- rb_thread_t *th = GET_THREAD();
- if (rb_vm_frame_block_handler(th->ec.cfp) == VM_BLOCK_HANDLER_NONE) {
+ if (rb_vm_frame_block_handler(GET_EC()->cfp) == VM_BLOCK_HANDLER_NONE) {
return FALSE;
}
else {
@@ -843,15 +942,12 @@ rb_block_given_p(void)
}
}
-/*! Determines if the current method is an interator.
- *
- * An alias of rb_block_given_p().
- * \ingroup defmethod
- */
+int rb_vm_cframe_keyword_p(const rb_control_frame_t *cfp);
+
int
-rb_iterator_p(void)
+rb_keyword_given_p(void)
{
- return rb_block_given_p();
+ return rb_vm_cframe_keyword_p(GET_EC()->cfp);
}
VALUE rb_eThreadError;
@@ -892,59 +988,76 @@ rb_need_block(void)
* \ingroup exception
*/
VALUE
-rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
- VALUE (* r_proc) (ANYARGS), VALUE data2, ...)
+rb_rescue2(VALUE (* b_proc) (VALUE), VALUE data1,
+ VALUE (* r_proc) (VALUE, VALUE), VALUE data2, ...)
+{
+ va_list ap;
+ va_start(ap, data2);
+ VALUE ret = rb_vrescue2(b_proc, data1, r_proc, data2, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*!
+ * \copydoc rb_rescue2
+ * \param[in] args exception classes, terminated by (VALUE)0.
+ */
+VALUE
+rb_vrescue2(VALUE (* b_proc) (VALUE), VALUE data1,
+ VALUE (* r_proc) (VALUE, VALUE), VALUE data2,
+ va_list args)
{
enum ruby_tag_type state;
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *volatile cfp = th->ec.cfp;
+ rb_execution_context_t * volatile ec = GET_EC();
+ rb_control_frame_t *volatile cfp = ec->cfp;
volatile VALUE result = Qfalse;
- volatile VALUE e_info = th->ec.errinfo;
- va_list args;
+ volatile VALUE e_info = ec->errinfo;
- TH_PUSH_TAG(th);
- if ((state = TH_EXEC_TAG()) == TAG_NONE) {
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
retry_entry:
result = (*b_proc) (data1);
}
else if (result) {
/* escape from r_proc */
if (state == TAG_RETRY) {
- state = 0;
- th->ec.errinfo = Qnil;
+ state = TAG_NONE;
+ ec->errinfo = Qnil;
result = Qfalse;
goto retry_entry;
}
}
else {
- rb_vm_rewind_cfp(th, cfp);
+ rb_vm_rewind_cfp(ec, cfp);
if (state == TAG_RAISE) {
int handle = FALSE;
VALUE eclass;
+ va_list ap;
- va_init_list(args, data2);
- while ((eclass = va_arg(args, VALUE)) != 0) {
- if (rb_obj_is_kind_of(th->ec.errinfo, eclass)) {
+ result = Qnil;
+ /* reuses args when raised again after retrying in r_proc */
+ va_copy(ap, args);
+ while ((eclass = va_arg(ap, VALUE)) != 0) {
+ if (rb_obj_is_kind_of(ec->errinfo, eclass)) {
handle = TRUE;
break;
}
}
- va_end(args);
+ va_end(ap);
if (handle) {
- result = Qnil;
- state = 0;
+ state = TAG_NONE;
if (r_proc) {
- result = (*r_proc) (data2, th->ec.errinfo);
+ result = (*r_proc) (data2, ec->errinfo);
}
- th->ec.errinfo = e_info;
+ ec->errinfo = e_info;
}
}
}
- TH_POP_TAG();
+ EC_POP_TAG();
if (state)
- TH_JUMP_TAG(th, state);
+ EC_JUMP_TAG(ec, state);
return result;
}
@@ -964,8 +1077,8 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
* \ingroup exception
*/
VALUE
-rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
- VALUE (* r_proc)(ANYARGS), VALUE data2)
+rb_rescue(VALUE (* b_proc)(VALUE), VALUE data1,
+ VALUE (* r_proc)(VALUE, VALUE), VALUE data2)
{
return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
(VALUE)0);
@@ -993,25 +1106,25 @@ rb_protect(VALUE (* proc) (VALUE), VALUE data, int *pstate)
{
volatile VALUE result = Qnil;
volatile enum ruby_tag_type state;
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *volatile cfp = th->ec.cfp;
+ rb_execution_context_t * volatile ec = GET_EC();
+ rb_control_frame_t *volatile cfp = ec->cfp;
struct rb_vm_protect_tag protect_tag;
rb_jmpbuf_t org_jmpbuf;
- protect_tag.prev = th->ec.protect_tag;
+ protect_tag.prev = ec->protect_tag;
- TH_PUSH_TAG(th);
- th->ec.protect_tag = &protect_tag;
- MEMCPY(&org_jmpbuf, &(th)->root_jmpbuf, rb_jmpbuf_t, 1);
- if ((state = TH_EXEC_TAG()) == TAG_NONE) {
- SAVE_ROOT_JMPBUF(th, result = (*proc) (data));
+ EC_PUSH_TAG(ec);
+ ec->protect_tag = &protect_tag;
+ MEMCPY(&org_jmpbuf, &rb_ec_thread_ptr(ec)->root_jmpbuf, rb_jmpbuf_t, 1);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
+ SAVE_ROOT_JMPBUF(rb_ec_thread_ptr(ec), result = (*proc) (data));
}
else {
- rb_vm_rewind_cfp(th, cfp);
+ rb_vm_rewind_cfp(ec, cfp);
}
- MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
- th->ec.protect_tag = protect_tag.prev;
- TH_POP_TAG();
+ MEMCPY(&rb_ec_thread_ptr(ec)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
+ ec->protect_tag = protect_tag.prev;
+ EC_POP_TAG();
if (pstate != NULL) *pstate = state;
return result;
@@ -1032,37 +1145,37 @@ rb_protect(VALUE (* proc) (VALUE), VALUE data, int *pstate)
* \ingroup exception
*/
VALUE
-rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE data2)
+rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2)
{
int state;
volatile VALUE result = Qnil;
VALUE errinfo;
- rb_thread_t *const th = GET_THREAD();
+ rb_execution_context_t * volatile ec = GET_EC();
rb_ensure_list_t ensure_list;
ensure_list.entry.marker = 0;
ensure_list.entry.e_proc = e_proc;
ensure_list.entry.data2 = data2;
- ensure_list.next = th->ec.ensure_list;
- th->ec.ensure_list = &ensure_list;
- TH_PUSH_TAG(th);
- if ((state = EXEC_TAG()) == TAG_NONE) {
+ ensure_list.next = ec->ensure_list;
+ ec->ensure_list = &ensure_list;
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
result = (*b_proc) (data1);
}
- TH_POP_TAG();
- errinfo = th->ec.errinfo;
+ EC_POP_TAG();
+ errinfo = ec->errinfo;
if (!NIL_P(errinfo) && !RB_TYPE_P(errinfo, T_OBJECT)) {
- th->ec.errinfo = Qnil;
+ ec->errinfo = Qnil;
}
- th->ec.ensure_list=ensure_list.next;
+ ec->ensure_list=ensure_list.next;
(*ensure_list.entry.e_proc)(ensure_list.entry.data2);
- th->ec.errinfo = errinfo;
+ ec->errinfo = errinfo;
if (state)
- TH_JUMP_TAG(th, state);
+ EC_JUMP_TAG(ec, state);
return result;
}
static ID
-frame_func_id(rb_control_frame_t *cfp)
+frame_func_id(const rb_control_frame_t *cfp)
{
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
@@ -1102,7 +1215,7 @@ frame_called_id(rb_control_frame_t *cfp)
ID
rb_frame_this_func(void)
{
- return frame_func_id(GET_THREAD()->ec.cfp);
+ return frame_func_id(GET_EC()->cfp);
}
/*!
@@ -1119,15 +1232,15 @@ rb_frame_this_func(void)
ID
rb_frame_callee(void)
{
- return frame_called_id(GET_THREAD()->ec.cfp);
+ return frame_called_id(GET_EC()->cfp);
}
static rb_control_frame_t *
-previous_frame(rb_thread_t *th)
+previous_frame(const rb_execution_context_t *ec)
{
- rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->ec.cfp);
+ rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
/* check if prev_cfp can be accessible */
- if ((void *)(th->ec.vm_stack + th->ec.vm_stack_size) == (void *)(prev_cfp)) {
+ if ((void *)(ec->vm_stack + ec->vm_stack_size) == (void *)(prev_cfp)) {
return 0;
}
return prev_cfp;
@@ -1136,7 +1249,7 @@ previous_frame(rb_thread_t *th)
static ID
prev_frame_callee(void)
{
- rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
+ rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
if (!prev_cfp) return 0;
return frame_called_id(prev_cfp);
}
@@ -1144,7 +1257,7 @@ prev_frame_callee(void)
static ID
prev_frame_func(void)
{
- rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
+ rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
if (!prev_cfp) return 0;
return frame_func_id(prev_cfp);
}
@@ -1158,13 +1271,13 @@ prev_frame_func(void)
ID
rb_frame_last_func(void)
{
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->ec.cfp;
+ const rb_execution_context_t *ec = GET_EC();
+ const rb_control_frame_t *cfp = ec->cfp;
ID mid;
while (!(mid = frame_func_id(cfp)) &&
(cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp),
- !RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)));
+ !RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)));
return mid;
}
@@ -1173,11 +1286,11 @@ rb_frame_last_func(void)
* append_features(mod) -> mod
*
* When this module is included in another, Ruby calls
- * <code>append_features</code> in this module, passing it the
- * receiving module in _mod_. Ruby's default implementation is
- * to add the constants, methods, and module variables of this module
- * to _mod_ if this module has not already been added to
- * _mod_ or one of its ancestors. See also <code>Module#include</code>.
+ * #append_features in this module, passing it the receiving module
+ * in _mod_. Ruby's default implementation is to add the constants,
+ * methods, and module variables of this module to _mod_ if this
+ * module has not already been added to _mod_ or one of its
+ * ancestors. See also Module#include.
*/
static VALUE
@@ -1195,7 +1308,7 @@ rb_mod_append_features(VALUE module, VALUE include)
* call-seq:
* include(module, ...) -> self
*
- * Invokes <code>Module.append_features</code> on each parameter in reverse order.
+ * Invokes Module.append_features on each parameter in reverse order.
*/
static VALUE
@@ -1222,11 +1335,11 @@ rb_mod_include(int argc, VALUE *argv, VALUE module)
* prepend_features(mod) -> mod
*
* When this module is prepended in another, Ruby calls
- * <code>prepend_features</code> in this module, passing it the
- * receiving module in _mod_. Ruby's default implementation is
- * to overlay the constants, methods, and module variables of this module
- * to _mod_ if this module has not already been added to
- * _mod_ or one of its ancestors. See also <code>Module#prepend</code>.
+ * #prepend_features in this module, passing it the receiving module
+ * in _mod_. Ruby's default implementation is to overlay the
+ * constants, methods, and module variables of this module to _mod_
+ * if this module has not already been added to _mod_ or one of its
+ * ancestors. See also Module#prepend.
*/
static VALUE
@@ -1244,7 +1357,7 @@ rb_mod_prepend_features(VALUE module, VALUE prepend)
* call-seq:
* prepend(module, ...) -> self
*
- * Invokes <code>Module.prepend_features</code> on each parameter in reverse order.
+ * Invokes Module.prepend_features on each parameter in reverse order.
*/
static VALUE
@@ -1285,6 +1398,18 @@ hidden_identity_hash_new(void)
return hash;
}
+static VALUE
+refinement_superclass(VALUE superclass)
+{
+ if (RB_TYPE_P(superclass, T_MODULE)) {
+ /* FIXME: Should ancestors of superclass be used here? */
+ return rb_include_class_new(RCLASS_ORIGIN(superclass), rb_cBasicObject);
+ }
+ else {
+ return superclass;
+ }
+}
+
/*!
* \private
* \todo can be static?
@@ -1316,18 +1441,18 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
}
}
FL_SET(module, RMODULE_IS_OVERLAID);
+ superclass = refinement_superclass(superclass);
c = iclass = rb_include_class_new(module, superclass);
- RCLASS_REFINED_CLASS(c) = klass;
+ RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
- RCLASS_M_TBL(OBJ_WB_UNPROTECT(c)) =
- RCLASS_M_TBL(OBJ_WB_UNPROTECT(module)); /* TODO: check unprotecting */
+ RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
module = RCLASS_SUPER(module);
while (module && module != klass) {
FL_SET(module, RMODULE_IS_OVERLAID);
c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c)));
- RCLASS_REFINED_CLASS(c) = klass;
- module = RCLASS_SUPER(module);
+ RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
+ module = RCLASS_SUPER(module);
}
rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
}
@@ -1380,7 +1505,7 @@ rb_using_module(const rb_cref_t *cref, VALUE module)
{
Check_Type(module, T_MODULE);
using_module_recursive(cref, module);
- rb_clear_method_cache_by_class(rb_cObject);
+ rb_clear_method_cache_all();
}
/*! \private */
@@ -1410,13 +1535,14 @@ add_activated_refinement(VALUE activated_refinements,
}
}
FL_SET(refinement, RMODULE_IS_OVERLAID);
+ superclass = refinement_superclass(superclass);
c = iclass = rb_include_class_new(refinement, superclass);
- RCLASS_REFINED_CLASS(c) = klass;
+ RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
refinement = RCLASS_SUPER(refinement);
while (refinement && refinement != klass) {
FL_SET(refinement, RMODULE_IS_OVERLAID);
c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
- RCLASS_REFINED_CLASS(c) = klass;
+ RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
refinement = RCLASS_SUPER(refinement);
}
rb_hash_aset(activated_refinements, klass, iclass);
@@ -1439,7 +1565,7 @@ rb_mod_refine(VALUE module, VALUE klass)
id_refined_class, id_defined_at;
VALUE refinements, activated_refinements;
rb_thread_t *th = GET_THREAD();
- VALUE block_handler = rb_vm_frame_block_handler(th->ec.cfp);
+ VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
if (block_handler == VM_BLOCK_HANDLER_NONE) {
rb_raise(rb_eArgError, "no block given");
@@ -1464,8 +1590,9 @@ rb_mod_refine(VALUE module, VALUE klass)
}
refinement = rb_hash_lookup(refinements, klass);
if (NIL_P(refinement)) {
+ VALUE superclass = refinement_superclass(klass);
refinement = rb_module_new();
- RCLASS_SET_SUPER(refinement, klass);
+ RCLASS_SET_SUPER(refinement, superclass);
FL_SET(refinement, RMODULE_IS_REFINEMENT);
CONST_ID(id_refined_class, "__refined_class__");
rb_ivar_set(refinement, id_refined_class, klass);
@@ -1500,7 +1627,7 @@ ignored_block(VALUE module, const char *klass)
static VALUE
mod_using(VALUE self, VALUE module)
{
- rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
+ rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
if (prev_frame_func()) {
rb_raise(rb_eRuntimeError,
@@ -1554,13 +1681,13 @@ used_modules_i(VALUE _, VALUE mod, VALUE ary)
* [B, A]
*/
static VALUE
-rb_mod_s_used_modules(void)
+rb_mod_s_used_modules(VALUE _)
{
const rb_cref_t *cref = rb_vm_cref();
VALUE ary = rb_ary_new();
- while(cref) {
- if(!NIL_P(CREF_REFINEMENTS(cref))) {
+ while (cref) {
+ if (!NIL_P(CREF_REFINEMENTS(cref))) {
rb_hash_foreach(CREF_REFINEMENTS(cref), used_modules_i, ary);
}
cref = CREF_NEXT(cref);
@@ -1583,7 +1710,14 @@ void
rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
{
PASS_PASSED_BLOCK_HANDLER();
- rb_funcallv(obj, idInitialize, argc, argv);
+ rb_funcallv_kw(obj, idInitialize, argc, argv, RB_NO_KEYWORDS);
+}
+
+void
+rb_obj_call_init_kw(VALUE obj, int argc, const VALUE *argv, int kw_splat)
+{
+ PASS_PASSED_BLOCK_HANDLER();
+ rb_funcallv_kw(obj, idInitialize, argc, argv, kw_splat);
}
/*!
@@ -1604,7 +1738,7 @@ rb_extend_object(VALUE obj, VALUE module)
*
* Extends the specified object by adding this module's constants and
* methods (which are added as singleton methods). This is the callback
- * method used by <code>Object#extend</code>.
+ * method used by Object#extend.
*
* module Picky
* def Picky.extend_object(o)
@@ -1680,9 +1814,9 @@ rb_obj_extend(int argc, VALUE *argv, VALUE obj)
* call-seq:
* include(module, ...) -> self
*
- * Invokes <code>Module.append_features</code>
- * on each parameter in turn. Effectively adds the methods and constants
- * in each module to the receiver.
+ * Invokes Module.append_features on each parameter in turn.
+ * Effectively adds the methods and constants in each module to the
+ * receiver.
*/
static VALUE
@@ -1702,14 +1836,14 @@ top_include(int argc, VALUE *argv, VALUE self)
* using(module) -> self
*
* Import class refinements from <i>module</i> into the scope where
- * <code>using</code> is called.
+ * #using is called.
*/
static VALUE
top_using(VALUE self, VALUE module)
{
const rb_cref_t *cref = rb_vm_cref();
- rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
+ rb_control_frame_t *prev_cfp = previous_frame(GET_EC());
if (CREF_NEXT(cref) || (prev_cfp && rb_vm_frame_method_entry(prev_cfp))) {
rb_raise(rb_eRuntimeError, "main.using is permitted only at toplevel");
@@ -1722,10 +1856,10 @@ top_using(VALUE self, VALUE module)
}
static const VALUE *
-errinfo_place(rb_thread_t *th)
+errinfo_place(const rb_execution_context_t *ec)
{
- rb_control_frame_t *cfp = th->ec.cfp;
- rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
+ const rb_control_frame_t *cfp = ec->cfp;
+ const rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (VM_FRAME_RUBYFRAME_P(cfp)) {
@@ -1743,26 +1877,26 @@ errinfo_place(rb_thread_t *th)
return 0;
}
-static VALUE
-get_thread_errinfo(rb_thread_t *th)
+VALUE
+rb_ec_get_errinfo(const rb_execution_context_t *ec)
{
- const VALUE *ptr = errinfo_place(th);
+ const VALUE *ptr = errinfo_place(ec);
if (ptr) {
return *ptr;
}
else {
- return th->ec.errinfo;
+ return ec->errinfo;
}
}
static VALUE
get_errinfo(void)
{
- return get_thread_errinfo(GET_THREAD());
+ return get_ec_errinfo(GET_EC());
}
static VALUE
-errinfo_getter(ID id)
+errinfo_getter(ID id, VALUE *_)
{
return get_errinfo();
}
@@ -1776,8 +1910,7 @@ errinfo_getter(ID id)
VALUE
rb_errinfo(void)
{
- rb_thread_t *th = GET_THREAD();
- return th->ec.errinfo;
+ return GET_EC()->errinfo;
}
/*! Sets the current exception (\c $!) to the given value
@@ -1794,11 +1927,11 @@ rb_set_errinfo(VALUE err)
if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
rb_raise(rb_eTypeError, "assigning non-exception to $!");
}
- GET_THREAD()->ec.errinfo = err;
+ GET_EC()->errinfo = err;
}
static VALUE
-errat_getter(ID id)
+errat_getter(ID id, VALUE *_)
{
VALUE err = get_errinfo();
if (!NIL_P(err)) {
@@ -1830,7 +1963,7 @@ errat_setter(VALUE val, ID id, VALUE *var)
*/
static VALUE
-rb_f_method_name(void)
+rb_f_method_name(VALUE _)
{
ID fname = prev_frame_func(); /* need *method* ID */
@@ -1852,7 +1985,7 @@ rb_f_method_name(void)
*/
static VALUE
-rb_f_callee_name(void)
+rb_f_callee_name(VALUE _)
{
ID fname = prev_frame_callee(); /* need *callee* ID */
@@ -1875,7 +2008,7 @@ rb_f_callee_name(void)
*
*/
static VALUE
-f_current_dirname(void)
+f_current_dirname(VALUE _)
{
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
@@ -1885,16 +2018,82 @@ f_current_dirname(void)
return base;
}
+/*
+ * call-seq:
+ * global_variables -> array
+ *
+ * Returns an array of the names of global variables. This includes
+ * special regexp global variables such as <tt>$~</tt> and <tt>$+</tt>,
+ * but does not include the numbered regexp global variables (<tt>$1</tt>,
+ * <tt>$2</tt>, etc.).
+ *
+ * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
+ */
+
+static VALUE
+f_global_variables(VALUE _)
+{
+ return rb_f_global_variables();
+}
+
+/*
+ * call-seq:
+ * trace_var(symbol, cmd ) -> nil
+ * trace_var(symbol) {|val| block } -> nil
+ *
+ * Controls tracing of assignments to global variables. The parameter
+ * +symbol+ identifies the variable (as either a string name or a
+ * symbol identifier). _cmd_ (which may be a string or a
+ * +Proc+ object) or block is executed whenever the variable
+ * is assigned. The block or +Proc+ object receives the
+ * variable's new value as a parameter. Also see
+ * Kernel::untrace_var.
+ *
+ * trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
+ * $_ = "hello"
+ * $_ = ' there'
+ *
+ * <em>produces:</em>
+ *
+ * $_ is now 'hello'
+ * $_ is now ' there'
+ */
+
+static VALUE
+f_trace_var(int c, const VALUE *a, VALUE _)
+{
+ return rb_f_trace_var(c, a);
+}
+
+/*
+ * call-seq:
+ * untrace_var(symbol [, cmd] ) -> array or nil
+ *
+ * Removes tracing for the specified command on the given global
+ * variable and returns +nil+. If no command is specified,
+ * removes all tracing for that variable and returns an array
+ * containing the commands actually removed.
+ */
+
+static VALUE
+f_untrace_var(int c, const VALUE *a, VALUE _)
+{
+ return rb_f_untrace_var(c, a);
+}
+
void
Init_eval(void)
{
rb_define_virtual_variable("$@", errat_getter, errat_setter);
rb_define_virtual_variable("$!", errinfo_getter, 0);
- rb_define_global_function("raise", rb_f_raise, -1);
- rb_define_global_function("fail", rb_f_raise, -1);
+ rb_gvar_ractor_local("$@");
+ rb_gvar_ractor_local("$!");
+
+ rb_define_global_function("raise", f_raise, -1);
+ rb_define_global_function("fail", f_raise, -1);
- rb_define_global_function("global_variables", rb_f_global_variables, 0); /* in variable.c */
+ rb_define_global_function("global_variables", f_global_variables, 0);
rb_define_global_function("__method__", rb_f_method_name, 0);
rb_define_global_function("__callee__", rb_f_callee_name, 0);
@@ -1927,13 +2126,12 @@ Init_eval(void)
rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
- rb_define_global_function("trace_var", rb_f_trace_var, -1); /* in variable.c */
- rb_define_global_function("untrace_var", rb_f_untrace_var, -1); /* in variable.c */
+ rb_define_global_function("trace_var", f_trace_var, -1);
+ rb_define_global_function("untrace_var", f_untrace_var, -1);
rb_vm_register_special_exception(ruby_error_reenter, rb_eFatal, "exception reentered");
rb_vm_register_special_exception(ruby_error_stackfatal, rb_eFatal, "machine stack overflow in critical region");
id_signo = rb_intern_const("signo");
id_status = rb_intern_const("status");
- id_cause = rb_intern_const("cause");
}
diff --git a/eval_error.c b/eval_error.c
index fe6bae1145..841275eed0 100644
--- a/eval_error.c
+++ b/eval_error.c
@@ -3,6 +3,10 @@
* included by eval.c
*/
+#define write_warn(str, x) \
+ (NIL_P(str) ? warn_print(x) : (void)rb_str_cat_cstr(str, x))
+#define write_warn2(str, x, l) \
+ (NIL_P(str) ? warn_print2(x, l) : (void)rb_str_cat(str, x, l))
#ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
#define warn_print(x) RB_GNUC_EXTENSION_BLOCK( \
(__builtin_constant_p(x)) ? \
@@ -12,17 +16,20 @@
#else
#define warn_print(x) rb_write_error(x)
#endif
+
#define warn_print2(x,l) rb_write_error2((x),(l))
+
+#define write_warn_str(str,x) NIL_P(str) ? rb_write_error_str(x) : (void)rb_str_concat((str), (x))
#define warn_print_str(x) rb_write_error_str(x)
static VALUE error_pos_str(void);
static void
-error_pos(void)
+error_pos(const VALUE str)
{
- VALUE str = error_pos_str();
- if (!NIL_P(str)) {
- warn_print_str(str);
+ VALUE pos = error_pos_str();
+ if (!NIL_P(pos)) {
+ write_warn_str(str, pos);
}
}
@@ -32,7 +39,7 @@ error_pos_str(void)
int sourceline;
VALUE sourcefile = rb_source_location(&sourceline);
- if (sourcefile) {
+ if (!NIL_P(sourcefile)) {
ID caller_name;
if (sourceline == 0) {
return rb_sprintf("%"PRIsVALUE": ", sourcefile);
@@ -67,13 +74,61 @@ set_backtrace(VALUE info, VALUE bt)
}
static void
-error_print(rb_thread_t *th)
+error_print(rb_execution_context_t *ec)
+{
+ rb_ec_error_print(ec, ec->errinfo);
+}
+
+static void
+write_warnq(VALUE out, VALUE str, const char *ptr, long len)
{
- rb_threadptr_error_print(th, th->ec.errinfo);
+ if (NIL_P(out)) {
+ const char *beg = ptr;
+ const long olen = len;
+ for (; len > 0; --len, ++ptr) {
+ unsigned char c = *ptr;
+ switch (c) {
+ case '\n': case '\t': continue;
+ }
+ if (rb_iscntrl(c)) {
+ char buf[5];
+ const char *cc = 0;
+ if (ptr > beg) rb_write_error2(beg, ptr - beg);
+ beg = ptr + 1;
+ cc = ruby_escaped_char(c);
+ if (cc) {
+ rb_write_error2(cc, strlen(cc));
+ }
+ else {
+ rb_write_error2(buf, snprintf(buf, sizeof(buf), "\\x%02X", c));
+ }
+ }
+ else if (c == '\\') {
+ rb_write_error2(beg, ptr - beg + 1);
+ beg = ptr;
+ }
+ }
+ if (ptr > beg) {
+ if (beg == RSTRING_PTR(str) && olen == RSTRING_LEN(str))
+ rb_write_error_str(str);
+ else
+ rb_write_error2(beg, ptr - beg);
+ }
+ }
+ else {
+ rb_str_cat(out, ptr, len);
+ }
}
+#define CSI_BEGIN "\033["
+#define CSI_SGR "m"
+
+static const char underline[] = CSI_BEGIN"1;4"CSI_SGR;
+static const char bold[] = CSI_BEGIN"1"CSI_SGR;
+static const char reset[] = CSI_BEGIN""CSI_SGR;
+
static void
-print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg)
+print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, const VALUE str, int highlight)
{
const char *einfo = "";
long elen = 0;
@@ -82,131 +137,257 @@ print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg)
if (emesg != Qundef) {
if (NIL_P(errat) || RARRAY_LEN(errat) == 0 ||
NIL_P(mesg = RARRAY_AREF(errat, 0))) {
- error_pos();
+ error_pos(str);
}
else {
- warn_print_str(mesg);
- warn_print(": ");
+ write_warn_str(str, mesg);
+ write_warn(str, ": ");
}
if (!NIL_P(emesg)) {
einfo = RSTRING_PTR(emesg);
- elen = RSTRING_LEN(emesg);
+ elen = RSTRING_LEN(emesg);
}
}
if (eclass == rb_eRuntimeError && elen == 0) {
- warn_print("unhandled exception\n");
+ if (highlight) write_warn(str, underline);
+ write_warn(str, "unhandled exception");
+ if (highlight) write_warn(str, reset);
+ write_warn2(str, "\n", 1);
}
else {
VALUE epath;
epath = rb_class_name(eclass);
if (elen == 0) {
- warn_print_str(epath);
- warn_print("\n");
+ if (highlight) write_warn(str, underline);
+ write_warn_str(str, epath);
+ if (highlight) write_warn(str, reset);
+ write_warn(str, "\n");
}
else {
+ /* emesg is a String instance */
const char *tail = 0;
- long len = elen;
+ if (highlight) write_warn(str, bold);
if (RSTRING_PTR(epath)[0] == '#')
epath = 0;
if ((tail = memchr(einfo, '\n', elen)) != 0) {
- len = tail - einfo;
+ write_warnq(str, emesg, einfo, tail - einfo);
tail++; /* skip newline */
}
- warn_print_str(tail ? rb_str_subseq(emesg, 0, len) : emesg);
+ else {
+ write_warnq(str, emesg, einfo, elen);
+ }
if (epath) {
- warn_print(" (");
- warn_print_str(epath);
- warn_print(")\n");
+ write_warn(str, " (");
+ if (highlight) write_warn(str, underline);
+ write_warn_str(str, epath);
+ if (highlight) {
+ write_warn(str, reset);
+ write_warn(str, bold);
+ }
+ write_warn2(str, ")", 1);
+ if (highlight) write_warn(str, reset);
+ write_warn2(str, "\n", 1);
}
- if (tail) {
- warn_print_str(rb_str_subseq(emesg, tail - einfo, elen - len - 1));
+ if (tail && einfo+elen > tail) {
+ if (!highlight) {
+ write_warnq(str, emesg, tail, einfo+elen-tail);
+ if (einfo[elen-1] != '\n') write_warn2(str, "\n", 1);
+ }
+ else {
+ elen -= tail - einfo;
+ einfo = tail;
+ while (elen > 0) {
+ tail = memchr(einfo, '\n', elen);
+ if (!tail || tail > einfo) {
+ write_warn(str, bold);
+ write_warnq(str, emesg, einfo, tail ? tail-einfo : elen);
+ write_warn(str, reset);
+ if (!tail) {
+ write_warn2(str, "\n", 1);
+ break;
+ }
+ }
+ elen -= tail - einfo;
+ einfo = tail;
+ do ++tail; while (tail < einfo+elen && *tail == '\n');
+ write_warnq(str, emesg, einfo, tail-einfo);
+ elen -= tail - einfo;
+ einfo = tail;
+ }
+ }
+ }
+ else if (!epath) {
+ write_warn2(str, "\n", 1);
}
- if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1);
}
}
}
static void
-print_backtrace(const VALUE eclass, const VALUE errat, int reverse)
+print_backtrace(const VALUE eclass, const VALUE errat, const VALUE str, int reverse)
{
if (!NIL_P(errat)) {
long i;
long len = RARRAY_LEN(errat);
- int skip = eclass == rb_eSysStackError;
const int threshold = 1000000000;
- int width = ((int)log10((double)(len > threshold ?
+ int width = (len <= 1) ? INT_MIN : ((int)log10((double)(len > threshold ?
((len - 1) / threshold) :
len - 1)) +
(len < threshold ? 0 : 9) + 1);
-#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
-#define TRACE_HEAD 8
-#define TRACE_TAIL 5
+ long skip_start = -1, skip_len = 0;
+
+ // skip for stackoverflow
+ if (eclass == rb_eSysStackError) {
+ long trace_head = 9;
+ long trace_tail = 4;
+ long trace_max = trace_head + trace_tail + 5;
+ if (len > trace_max) {
+ skip_start = trace_head;
+ skip_len = len - trace_max + 5;
+ }
+ }
+
+ // skip for explicit limit
+ if (rb_backtrace_length_limit >= 0 && len > rb_backtrace_length_limit + 2) {
+ skip_start = rb_backtrace_length_limit + 1;
+ skip_len = len - skip_start;
+ }
for (i = 1; i < len; i++) {
+ if (i == skip_start) {
+ write_warn_str(str, rb_sprintf("\t ... %ld levels...\n", skip_len));
+ i += skip_len;
+ if (i >= len) break;
+ }
VALUE line = RARRAY_AREF(errat, reverse ? len - i : i);
if (RB_TYPE_P(line, T_STRING)) {
- VALUE str = rb_str_new_cstr("\t");
- if (reverse) rb_str_catf(str, "%*ld: ", width, len - i);
- warn_print_str(rb_str_catf(str, "from %"PRIsVALUE"\n", line));
- }
- if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
- warn_print_str(rb_sprintf("\t ... %ld levels...\n",
- len - TRACE_HEAD - TRACE_TAIL));
- i = len - TRACE_TAIL;
+ VALUE bt = rb_str_new_cstr("\t");
+ if (reverse) rb_str_catf(bt, "%*ld: ", width, len - i);
+ write_warn_str(str, rb_str_catf(bt, "from %"PRIsVALUE"\n", line));
}
}
}
}
+VALUE rb_get_message(VALUE exc);
+
+static int
+shown_cause_p(VALUE cause, VALUE *shown_causes)
+{
+ VALUE shown = *shown_causes;
+ if (!shown) {
+ *shown_causes = shown = rb_obj_hide(rb_ident_hash_new());
+ }
+ if (rb_hash_has_key(shown, cause)) return TRUE;
+ rb_hash_aset(shown, cause, Qtrue);
+ return FALSE;
+}
+
+static void
+show_cause(VALUE errinfo, VALUE str, VALUE highlight, VALUE reverse, VALUE *shown_causes)
+{
+ VALUE cause = rb_attr_get(errinfo, id_cause);
+ if (!NIL_P(cause) && rb_obj_is_kind_of(cause, rb_eException) &&
+ !shown_cause_p(cause, shown_causes)) {
+ volatile VALUE eclass = CLASS_OF(cause);
+ VALUE errat = rb_get_backtrace(cause);
+ VALUE emesg = rb_get_message(cause);
+ if (reverse) {
+ show_cause(cause, str, highlight, reverse, shown_causes);
+ print_backtrace(eclass, errat, str, TRUE);
+ print_errinfo(eclass, errat, emesg, str, highlight!=0);
+ }
+ else {
+ print_errinfo(eclass, errat, emesg, str, highlight!=0);
+ print_backtrace(eclass, errat, str, FALSE);
+ show_cause(cause, str, highlight, reverse, shown_causes);
+ }
+ }
+}
+
void
-rb_threadptr_error_print(rb_thread_t *volatile th, volatile VALUE errinfo)
+rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse)
{
- volatile VALUE errat = Qundef;
- volatile int raised_flag = th->ec.raised_flag;
- volatile VALUE eclass = Qundef, emesg = Qundef;
+ volatile VALUE eclass;
+ VALUE shown_causes = 0;
if (NIL_P(errinfo))
return;
- rb_thread_raised_clear(th);
- TH_PUSH_TAG(th);
- if (TH_EXEC_TAG() == TAG_NONE) {
- errat = rb_get_backtrace(errinfo);
- }
- else if (errat == Qundef) {
+ if (errat == Qundef) {
errat = Qnil;
}
- else if (eclass == Qundef || emesg != Qundef) {
- goto error;
+ eclass = CLASS_OF(errinfo);
+ if (NIL_P(reverse)) reverse = Qfalse;
+ if (NIL_P(highlight)) {
+ VALUE tty = (VALUE)rb_stderr_tty_p();
+ if (NIL_P(highlight)) highlight = tty;
}
- if ((eclass = CLASS_OF(errinfo)) != Qundef) {
- VALUE e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0);
- if (e != Qundef) {
- if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
- emesg = e;
+ if (reverse) {
+ static const char traceback[] = "Traceback "
+ "(most recent call last):\n";
+ const int bold_part = rb_strlen_lit("Traceback");
+ char buff[sizeof(traceback)+sizeof(bold)+sizeof(reset)-2], *p = buff;
+ const char *msg = traceback;
+ long len = sizeof(traceback) - 1;
+ if (highlight) {
+#define APPEND(s, l) (memcpy(p, s, l), p += (l))
+ APPEND(bold, sizeof(bold)-1);
+ APPEND(traceback, bold_part);
+ APPEND(reset, sizeof(reset)-1);
+ APPEND(traceback + bold_part, sizeof(traceback)-bold_part-1);
+#undef APPEND
+ len = p - (msg = buff);
}
- }
- if (rb_stderr_tty_p()) {
- warn_print("Traceback (most recent call last):\n");
- print_backtrace(eclass, errat, TRUE);
- print_errinfo(eclass, errat, emesg);
+ write_warn2(str, msg, len);
+ show_cause(errinfo, str, highlight, reverse, &shown_causes);
+ print_backtrace(eclass, errat, str, TRUE);
+ print_errinfo(eclass, errat, emesg, str, highlight!=0);
}
else {
- print_errinfo(eclass, errat, emesg);
- print_backtrace(eclass, errat, FALSE);
+ print_errinfo(eclass, errat, emesg, str, highlight!=0);
+ print_backtrace(eclass, errat, str, FALSE);
+ show_cause(errinfo, str, highlight, reverse, &shown_causes);
}
- error:
- TH_POP_TAG();
- th->ec.errinfo = errinfo;
- rb_thread_raised_set(th, raised_flag);
}
-#define undef_mesg_for(v, k) rb_fstring_cstr("undefined"v" method `%1$s' for "k" `%2$s'")
+void
+rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo)
+{
+ volatile uint8_t raised_flag = ec->raised_flag;
+ volatile VALUE errat = Qundef;
+ volatile VALUE emesg = Qundef;
+ volatile bool written = false;
+
+ if (NIL_P(errinfo))
+ return;
+ rb_ec_raised_clear(ec);
+
+ EC_PUSH_TAG(ec);
+ if (EC_EXEC_TAG() == TAG_NONE) {
+ errat = rb_get_backtrace(errinfo);
+ }
+ if (emesg == Qundef) {
+ emesg = Qnil;
+ emesg = rb_get_message(errinfo);
+ }
+
+ if (!written) {
+ written = true;
+ rb_error_write(errinfo, emesg, errat, Qnil, Qnil, Qfalse);
+ }
+
+ EC_POP_TAG();
+ ec->errinfo = errinfo;
+ rb_ec_raised_set(ec, raised_flag);
+}
+
+#define undef_mesg_for(v, k) rb_fstring_lit("undefined"v" method `%1$s' for "k" `%2$s'")
#define undef_mesg(v) ( \
is_mod ? \
undef_mesg_for(v, "module") : \
@@ -234,7 +415,7 @@ rb_print_undef_str(VALUE klass, VALUE name)
rb_name_err_raise_str(undef_mesg(""), klass, name);
}
-#define inaccessible_mesg_for(v, k) rb_fstring_cstr("method `%1$s' for "k" `%2$s' is "v)
+#define inaccessible_mesg_for(v, k) rb_fstring_lit("method `%1$s' for "k" `%2$s' is "v)
#define inaccessible_mesg(v) ( \
is_mod ? \
inaccessible_mesg_for(v, "module") : \
@@ -266,12 +447,11 @@ sysexit_status(VALUE err)
rb_bug("Unknown longjmp status %d", status)
static int
-error_handle(int ex)
+error_handle(rb_execution_context_t *ec, int ex)
{
int status = EXIT_FAILURE;
- rb_thread_t *th = GET_THREAD();
- if (rb_threadptr_set_raised(th))
+ if (rb_ec_set_raised(ec))
return EXIT_FAILURE;
switch (ex & TAG_MASK) {
case 0:
@@ -279,32 +459,32 @@ error_handle(int ex)
break;
case TAG_RETURN:
- error_pos();
+ error_pos(Qnil);
warn_print("unexpected return\n");
break;
case TAG_NEXT:
- error_pos();
+ error_pos(Qnil);
warn_print("unexpected next\n");
break;
case TAG_BREAK:
- error_pos();
+ error_pos(Qnil);
warn_print("unexpected break\n");
break;
case TAG_REDO:
- error_pos();
+ error_pos(Qnil);
warn_print("unexpected redo\n");
break;
case TAG_RETRY:
- error_pos();
+ error_pos(Qnil);
warn_print("retry outside of rescue clause\n");
break;
case TAG_THROW:
/* TODO: fix me */
- error_pos();
+ error_pos(Qnil);
warn_print("unexpected throw\n");
break;
case TAG_RAISE: {
- VALUE errinfo = th->ec.errinfo;
+ VALUE errinfo = ec->errinfo;
if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
status = sysexit_status(errinfo);
}
@@ -312,18 +492,22 @@ error_handle(int ex)
rb_ivar_get(errinfo, id_signo) != INT2FIX(SIGSEGV)) {
/* no message when exiting by signal */
}
+ else if (rb_obj_is_kind_of(errinfo, rb_eSystemCallError) &&
+ FIXNUM_P(rb_attr_get(errinfo, id_signo))) {
+ /* no message when exiting by error to be mapped to signal */
+ }
else {
- rb_threadptr_error_print(th, errinfo);
+ rb_ec_error_print(ec, errinfo);
}
break;
}
case TAG_FATAL:
- error_print(th);
+ error_print(ec);
break;
default:
unknown_longjmp_status(ex);
break;
}
- rb_threadptr_reset_raised(th);
+ rb_ec_reset_raised(ec);
return status;
}
diff --git a/eval_intern.h b/eval_intern.h
index 217eddc02c..9fa9031189 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -5,23 +5,22 @@
#include "vm_core.h"
static inline void
-vm_passed_block_handler_set(rb_thread_t *th, VALUE block_handler)
+vm_passed_block_handler_set(rb_execution_context_t *ec, VALUE block_handler)
{
vm_block_handler_verify(block_handler);
- th->passed_block_handler = block_handler;
+ ec->passed_block_handler = block_handler;
}
static inline void
-pass_passed_block_handler(rb_thread_t *th)
+pass_passed_block_handler(rb_execution_context_t *ec)
{
- VALUE block_handler = rb_vm_frame_block_handler(th->ec.cfp);
- vm_block_handler_verify(block_handler);
- vm_passed_block_handler_set(th, block_handler);
- VM_ENV_FLAGS_SET(th->ec.cfp->ep, VM_FRAME_FLAG_PASSED);
+ VALUE block_handler = rb_vm_frame_block_handler(ec->cfp);
+ vm_passed_block_handler_set(ec, block_handler);
+ VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_PASSED);
}
-#define PASS_PASSED_BLOCK_HANDLER_TH(th) pass_passed_block_handler(th)
-#define PASS_PASSED_BLOCK_HANDLER() pass_passed_block_handler(GET_THREAD())
+#define PASS_PASSED_BLOCK_HANDLER_EC(ec) pass_passed_block_handler(ec)
+#define PASS_PASSED_BLOCK_HANDLER() pass_passed_block_handler(GET_EC())
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -98,7 +97,7 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval
#define SAVE_ROOT_JMPBUF_AFTER_STMT \
} \
__except (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW ? \
- (rb_thread_raised_set(GET_THREAD(), RAISED_STACKOVERFLOW), \
+ (rb_ec_raised_set(GET_EC(), RAISED_STACKOVERFLOW), \
raise(SIGSEGV), \
EXCEPTION_EXECUTE_HANDLER) : \
EXCEPTION_CONTINUE_SEARCH) { \
@@ -128,26 +127,28 @@ LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *);
rb_fiber_start(); \
} while (0)
-#define TH_PUSH_TAG(th) do { \
- rb_thread_t * const _th = (th); \
+#define EC_PUSH_TAG(ec) do { \
+ rb_execution_context_t * const _ec = (ec); \
struct rb_vm_tag _tag; \
_tag.state = TAG_NONE; \
_tag.tag = Qundef; \
- _tag.prev = _th->ec.tag;
+ _tag.prev = _ec->tag; \
+ _tag.lock_rec = rb_ec_vm_lock_rec(_ec); \
-#define TH_POP_TAG() \
- _th->ec.tag = _tag.prev; \
+#define EC_POP_TAG() \
+ _ec->tag = _tag.prev; \
} while (0)
-#define TH_TMPPOP_TAG() \
- _th->ec.tag = _tag.prev
-
-#define TH_REPUSH_TAG() (void)(_th->ec.tag = &_tag)
+#define EC_TMPPOP_TAG() \
+ _ec->tag = _tag.prev
-#define PUSH_TAG() TH_PUSH_TAG(GET_THREAD())
-#define POP_TAG() TH_POP_TAG()
+#define EC_REPUSH_TAG() (void)(_ec->tag = &_tag)
-#if defined __GNUC__ && __GNUC__ == 4 && (__GNUC_MINOR__ >= 6 && __GNUC_MINOR__ <= 8)
+#if defined __GNUC__ && __GNUC__ == 4 && (__GNUC_MINOR__ >= 6 && __GNUC_MINOR__ <= 8) || __clang__
+/* This macro prevents GCC 4.6--4.8 from emitting maybe-uninitialized warnings.
+ * This macro also prevents Clang from dumping core in EC_EXEC_TAG().
+ * (I confirmed Clang 4.0.1 and 5.0.0.)
+ */
# define VAR_FROM_MEMORY(var) __extension__(*(__typeof__(var) volatile *)&(var))
# define VAR_INITIALIZED(var) ((var) = VAR_FROM_MEMORY(var))
# define VAR_NOCLOBBERED(var) volatile var
@@ -157,53 +158,42 @@ LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *);
# define VAR_NOCLOBBERED(var) var
#endif
-#if defined(USE_UNALIGNED_MEMBER_ACCESS) && USE_UNALIGNED_MEMBER_ACCESS && \
- defined(__clang__)
-# define UNALIGNED_MEMBER_ACCESS(expr) __extension__({ \
- _Pragma("GCC diagnostic push"); \
- _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); \
- typeof(expr) unaligned_member_access_result = (expr); \
- _Pragma("GCC diagnostic pop"); \
- unaligned_member_access_result; \
-})
-#else
-# define UNALIGNED_MEMBER_ACCESS(expr) expr
-#endif
-#define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
-
-#undef RB_OBJ_WRITE
-#define RB_OBJ_WRITE(a, slot, b) UNALIGNED_MEMBER_ACCESS(rb_obj_write((VALUE)(a), (VALUE *)(slot), (VALUE)(b), __FILE__, __LINE__))
+static inline void
+rb_ec_vm_lock_rec_check(const rb_execution_context_t *ec, unsigned int recorded_lock_rec)
+{
+ unsigned int current_lock_rec = rb_ec_vm_lock_rec(ec);
+ if (current_lock_rec != recorded_lock_rec) {
+ rb_ec_vm_lock_rec_release(ec, recorded_lock_rec, current_lock_rec);
+ }
+}
-/* clear th->ec.tag->state, and return the value */
+/* clear ec->tag->state, and return the value */
static inline int
-rb_threadptr_tag_state(rb_thread_t *th)
+rb_ec_tag_state(const rb_execution_context_t *ec)
{
- enum ruby_tag_type state = th->ec.tag->state;
- th->ec.tag->state = TAG_NONE;
+ struct rb_vm_tag *tag = ec->tag;
+ enum ruby_tag_type state = tag->state;
+ tag->state = TAG_NONE;
+ rb_ec_vm_lock_rec_check(ec, tag->lock_rec);
return state;
}
-NORETURN(static inline void rb_threadptr_tag_jump(rb_thread_t *, enum ruby_tag_type st));
+NORETURN(static inline void rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st));
static inline void
-rb_threadptr_tag_jump(rb_thread_t *th, enum ruby_tag_type st)
+rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st)
{
- th->ec.tag->state = st;
- ruby_longjmp(th->ec.tag->buf, 1);
+ ec->tag->state = st;
+ ruby_longjmp(ec->tag->buf, 1);
}
/*
setjmp() in assignment expression rhs is undefined behavior
[ISO/IEC 9899:1999] 7.13.1.1
*/
-#define TH_EXEC_TAG() \
- (ruby_setjmp(_tag.buf) ? rb_threadptr_tag_state(VAR_FROM_MEMORY(_th)) : (TH_REPUSH_TAG(), 0))
-
-#define EXEC_TAG() \
- TH_EXEC_TAG()
+#define EC_EXEC_TAG() \
+ (ruby_setjmp(_tag.buf) ? rb_ec_tag_state(VAR_FROM_MEMORY(_ec)) : (EC_REPUSH_TAG(), 0))
-#define TH_JUMP_TAG(th, st) rb_threadptr_tag_jump(th, st)
-
-#define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), (st))
+#define EC_JUMP_TAG(ec, st) rb_ec_tag_jump(ec, st)
#define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc)
@@ -272,21 +262,18 @@ CREF_OMOD_SHARED_UNSET(rb_cref_t *cref)
cref->flags &= ~CREF_FL_OMOD_SHARED;
}
-void rb_thread_cleanup(void);
-void rb_thread_wait_other_threads(void);
-
enum {
RAISED_EXCEPTION = 1,
RAISED_STACKOVERFLOW = 2,
RAISED_NOMEMORY = 4
};
-int rb_threadptr_set_raised(rb_thread_t *th);
-int rb_threadptr_reset_raised(rb_thread_t *th);
-#define rb_thread_raised_set(th, f) ((th)->ec.raised_flag |= (f))
-#define rb_thread_raised_reset(th, f) ((th)->ec.raised_flag &= ~(f))
-#define rb_thread_raised_p(th, f) (((th)->ec.raised_flag & (f)) != 0)
-#define rb_thread_raised_clear(th) ((th)->ec.raised_flag = 0)
-int rb_threadptr_stack_check(rb_thread_t *th);
+#define rb_ec_raised_set(ec, f) ((ec)->raised_flag |= (f))
+#define rb_ec_raised_reset(ec, f) ((ec)->raised_flag &= ~(f))
+#define rb_ec_raised_p(ec, f) (((ec)->raised_flag & (f)) != 0)
+#define rb_ec_raised_clear(ec) ((ec)->raised_flag = 0)
+int rb_ec_set_raised(rb_execution_context_t *ec);
+int rb_ec_reset_raised(rb_execution_context_t *ec);
+int rb_ec_stack_check(rb_execution_context_t *ec);
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self);
VALUE rb_make_exception(int argc, const VALUE *argv);
@@ -299,28 +286,32 @@ NORETURN(void rb_print_undef(VALUE, ID, rb_method_visibility_t));
NORETURN(void rb_print_undef_str(VALUE, VALUE));
NORETURN(void rb_print_inaccessible(VALUE, ID, rb_method_visibility_t));
NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
-#if 0
NORETURN(void rb_vm_jump_tag_but_local_jump(int));
-#endif
-NORETURN(void rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
- VALUE obj, int call_status));
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val);
rb_cref_t *rb_vm_cref(void);
rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void);
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
void rb_vm_set_progname(VALUE filename);
-void rb_thread_terminate_all(void);
VALUE rb_vm_cbase(void);
/* vm_backtrace.c */
-VALUE rb_threadptr_backtrace_object(rb_thread_t *th);
-VALUE rb_threadptr_backtrace_str_ary(rb_thread_t *th, long lev, long n);
-VALUE rb_threadptr_backtrace_location_ary(rb_thread_t *th, long lev, long n);
+VALUE rb_ec_backtrace_object(const rb_execution_context_t *ec);
+VALUE rb_ec_backtrace_str_ary(const rb_execution_context_t *ec, long lev, long n);
+VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal);
#ifndef CharNext /* defined as CharNext[AW] on Windows. */
# ifdef HAVE_MBLEN
-# define CharNext(p) ((p) + mblen((p), RUBY_MBCHAR_MAXSIZE))
+# define CharNext(p) rb_char_next(p)
+static inline const char *
+rb_char_next(const char *p)
+{
+ if (p) {
+ int len = mblen(p, RUBY_MBCHAR_MAXSIZE);
+ p += len > 0 ? len : 1;
+ }
+ return p;
+}
# else
# define CharNext(p) ((p) + 1)
# endif
diff --git a/eval_jump.c b/eval_jump.c
index 22722719b5..75d4ad0207 100644
--- a/eval_jump.c
+++ b/eval_jump.c
@@ -35,7 +35,7 @@ rb_call_end_proc(VALUE data)
*/
static VALUE
-rb_f_at_exit(void)
+rb_f_at_exit(VALUE _)
{
VALUE proc;
@@ -50,7 +50,6 @@ rb_f_at_exit(void)
struct end_proc_data {
void (*func) ();
VALUE data;
- int safe;
struct end_proc_data *next;
};
@@ -72,7 +71,6 @@ rb_set_end_proc(void (*func)(VALUE), VALUE data)
link->next = *list;
link->func = func;
link->data = data;
- link->safe = rb_safe_level();
*list = link;
}
@@ -104,38 +102,33 @@ exec_end_procs_chain(struct end_proc_data *volatile *procs, VALUE *errp)
*procs = link->next;
endproc = *link;
xfree(link);
- rb_set_safe_level_force(endproc.safe);
(*endproc.func) (endproc.data);
*errp = errinfo;
}
}
-void
-rb_exec_end_proc(void)
+static void
+rb_ec_exec_end_proc(rb_execution_context_t * ec)
{
enum ruby_tag_type state;
- volatile int safe = rb_safe_level();
- rb_thread_t *th = GET_THREAD();
- volatile VALUE errinfo = th->ec.errinfo;
+ volatile VALUE errinfo = ec->errinfo;
- TH_PUSH_TAG(th);
- if ((state = EXEC_TAG()) == TAG_NONE) {
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
again:
- exec_end_procs_chain(&ephemeral_end_procs, &th->ec.errinfo);
- exec_end_procs_chain(&end_procs, &th->ec.errinfo);
+ exec_end_procs_chain(&ephemeral_end_procs, &ec->errinfo);
+ exec_end_procs_chain(&end_procs, &ec->errinfo);
}
else {
- VAR_INITIALIZED(th);
- TH_TMPPOP_TAG();
- error_handle(state);
- if (!NIL_P(th->ec.errinfo)) errinfo = th->ec.errinfo;
- TH_REPUSH_TAG();
+ EC_TMPPOP_TAG();
+ error_handle(ec, state);
+ if (!NIL_P(ec->errinfo)) errinfo = ec->errinfo;
+ EC_REPUSH_TAG();
goto again;
}
- TH_POP_TAG();
+ EC_POP_TAG();
- rb_set_safe_level_force(safe);
- th->ec.errinfo = errinfo;
+ ec->errinfo = errinfo;
}
void
diff --git a/ext/-test-/RUBY_ALIGNOF/c.c b/ext/-test-/RUBY_ALIGNOF/c.c
new file mode 100644
index 0000000000..7a9f7cb498
--- /dev/null
+++ b/ext/-test-/RUBY_ALIGNOF/c.c
@@ -0,0 +1,15 @@
+#include "ruby.h"
+#include <stddef.h>
+
+struct T {
+ char _;
+ double t;
+};
+
+RBIMPL_STATIC_ASSERT(RUBY_ALIGNOF, RUBY_ALIGNOF(double) == offsetof(struct T, t));
+
+void
+Init_RUBY_ALIGNOF(void)
+{
+ // Windows linker mandates this symbol to exist.
+}
diff --git a/ext/-test-/RUBY_ALIGNOF/cpp.cpp b/ext/-test-/RUBY_ALIGNOF/cpp.cpp
new file mode 100644
index 0000000000..ed76d49b9f
--- /dev/null
+++ b/ext/-test-/RUBY_ALIGNOF/cpp.cpp
@@ -0,0 +1,9 @@
+#include "ruby.h"
+#include <cstddef>
+
+struct T {
+ char _;
+ double t;
+};
+
+RBIMPL_STATIC_ASSERT(RUBY_ALIGNOF, RUBY_ALIGNOF(double) == offsetof(T, t));
diff --git a/ext/-test-/RUBY_ALIGNOF/depend b/ext/-test-/RUBY_ALIGNOF/depend
new file mode 100644
index 0000000000..1662feda25
--- /dev/null
+++ b/ext/-test-/RUBY_ALIGNOF/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+c.o: $(RUBY_EXTCONF_H)
+c.o: $(arch_hdrdir)/ruby/config.h
+c.o: $(hdrdir)/ruby.h
+c.o: $(hdrdir)/ruby/assert.h
+c.o: $(hdrdir)/ruby/backward.h
+c.o: $(hdrdir)/ruby/backward/2/assume.h
+c.o: $(hdrdir)/ruby/backward/2/attributes.h
+c.o: $(hdrdir)/ruby/backward/2/bool.h
+c.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+c.o: $(hdrdir)/ruby/backward/2/inttypes.h
+c.o: $(hdrdir)/ruby/backward/2/limits.h
+c.o: $(hdrdir)/ruby/backward/2/long_long.h
+c.o: $(hdrdir)/ruby/backward/2/stdalign.h
+c.o: $(hdrdir)/ruby/backward/2/stdarg.h
+c.o: $(hdrdir)/ruby/defines.h
+c.o: $(hdrdir)/ruby/intern.h
+c.o: $(hdrdir)/ruby/internal/anyargs.h
+c.o: $(hdrdir)/ruby/internal/arithmetic.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+c.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+c.o: $(hdrdir)/ruby/internal/assume.h
+c.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+c.o: $(hdrdir)/ruby/internal/attr/artificial.h
+c.o: $(hdrdir)/ruby/internal/attr/cold.h
+c.o: $(hdrdir)/ruby/internal/attr/const.h
+c.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+c.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+c.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+c.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+c.o: $(hdrdir)/ruby/internal/attr/error.h
+c.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+c.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+c.o: $(hdrdir)/ruby/internal/attr/format.h
+c.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+c.o: $(hdrdir)/ruby/internal/attr/noalias.h
+c.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+c.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+c.o: $(hdrdir)/ruby/internal/attr/noinline.h
+c.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+c.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+c.o: $(hdrdir)/ruby/internal/attr/pure.h
+c.o: $(hdrdir)/ruby/internal/attr/restrict.h
+c.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+c.o: $(hdrdir)/ruby/internal/attr/warning.h
+c.o: $(hdrdir)/ruby/internal/attr/weakref.h
+c.o: $(hdrdir)/ruby/internal/cast.h
+c.o: $(hdrdir)/ruby/internal/compiler_is.h
+c.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+c.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+c.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+c.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+c.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+c.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+c.o: $(hdrdir)/ruby/internal/compiler_since.h
+c.o: $(hdrdir)/ruby/internal/config.h
+c.o: $(hdrdir)/ruby/internal/constant_p.h
+c.o: $(hdrdir)/ruby/internal/core.h
+c.o: $(hdrdir)/ruby/internal/core/rarray.h
+c.o: $(hdrdir)/ruby/internal/core/rbasic.h
+c.o: $(hdrdir)/ruby/internal/core/rbignum.h
+c.o: $(hdrdir)/ruby/internal/core/rclass.h
+c.o: $(hdrdir)/ruby/internal/core/rdata.h
+c.o: $(hdrdir)/ruby/internal/core/rfile.h
+c.o: $(hdrdir)/ruby/internal/core/rhash.h
+c.o: $(hdrdir)/ruby/internal/core/robject.h
+c.o: $(hdrdir)/ruby/internal/core/rregexp.h
+c.o: $(hdrdir)/ruby/internal/core/rstring.h
+c.o: $(hdrdir)/ruby/internal/core/rstruct.h
+c.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+c.o: $(hdrdir)/ruby/internal/ctype.h
+c.o: $(hdrdir)/ruby/internal/dllexport.h
+c.o: $(hdrdir)/ruby/internal/dosish.h
+c.o: $(hdrdir)/ruby/internal/error.h
+c.o: $(hdrdir)/ruby/internal/eval.h
+c.o: $(hdrdir)/ruby/internal/event.h
+c.o: $(hdrdir)/ruby/internal/fl_type.h
+c.o: $(hdrdir)/ruby/internal/gc.h
+c.o: $(hdrdir)/ruby/internal/glob.h
+c.o: $(hdrdir)/ruby/internal/globals.h
+c.o: $(hdrdir)/ruby/internal/has/attribute.h
+c.o: $(hdrdir)/ruby/internal/has/builtin.h
+c.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+c.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+c.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+c.o: $(hdrdir)/ruby/internal/has/extension.h
+c.o: $(hdrdir)/ruby/internal/has/feature.h
+c.o: $(hdrdir)/ruby/internal/has/warning.h
+c.o: $(hdrdir)/ruby/internal/intern/array.h
+c.o: $(hdrdir)/ruby/internal/intern/bignum.h
+c.o: $(hdrdir)/ruby/internal/intern/class.h
+c.o: $(hdrdir)/ruby/internal/intern/compar.h
+c.o: $(hdrdir)/ruby/internal/intern/complex.h
+c.o: $(hdrdir)/ruby/internal/intern/cont.h
+c.o: $(hdrdir)/ruby/internal/intern/dir.h
+c.o: $(hdrdir)/ruby/internal/intern/enum.h
+c.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+c.o: $(hdrdir)/ruby/internal/intern/error.h
+c.o: $(hdrdir)/ruby/internal/intern/eval.h
+c.o: $(hdrdir)/ruby/internal/intern/file.h
+c.o: $(hdrdir)/ruby/internal/intern/gc.h
+c.o: $(hdrdir)/ruby/internal/intern/hash.h
+c.o: $(hdrdir)/ruby/internal/intern/io.h
+c.o: $(hdrdir)/ruby/internal/intern/load.h
+c.o: $(hdrdir)/ruby/internal/intern/marshal.h
+c.o: $(hdrdir)/ruby/internal/intern/numeric.h
+c.o: $(hdrdir)/ruby/internal/intern/object.h
+c.o: $(hdrdir)/ruby/internal/intern/parse.h
+c.o: $(hdrdir)/ruby/internal/intern/proc.h
+c.o: $(hdrdir)/ruby/internal/intern/process.h
+c.o: $(hdrdir)/ruby/internal/intern/random.h
+c.o: $(hdrdir)/ruby/internal/intern/range.h
+c.o: $(hdrdir)/ruby/internal/intern/rational.h
+c.o: $(hdrdir)/ruby/internal/intern/re.h
+c.o: $(hdrdir)/ruby/internal/intern/ruby.h
+c.o: $(hdrdir)/ruby/internal/intern/select.h
+c.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+c.o: $(hdrdir)/ruby/internal/intern/signal.h
+c.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+c.o: $(hdrdir)/ruby/internal/intern/string.h
+c.o: $(hdrdir)/ruby/internal/intern/struct.h
+c.o: $(hdrdir)/ruby/internal/intern/thread.h
+c.o: $(hdrdir)/ruby/internal/intern/time.h
+c.o: $(hdrdir)/ruby/internal/intern/variable.h
+c.o: $(hdrdir)/ruby/internal/intern/vm.h
+c.o: $(hdrdir)/ruby/internal/interpreter.h
+c.o: $(hdrdir)/ruby/internal/iterator.h
+c.o: $(hdrdir)/ruby/internal/memory.h
+c.o: $(hdrdir)/ruby/internal/method.h
+c.o: $(hdrdir)/ruby/internal/module.h
+c.o: $(hdrdir)/ruby/internal/newobj.h
+c.o: $(hdrdir)/ruby/internal/rgengc.h
+c.o: $(hdrdir)/ruby/internal/scan_args.h
+c.o: $(hdrdir)/ruby/internal/special_consts.h
+c.o: $(hdrdir)/ruby/internal/static_assert.h
+c.o: $(hdrdir)/ruby/internal/stdalign.h
+c.o: $(hdrdir)/ruby/internal/stdbool.h
+c.o: $(hdrdir)/ruby/internal/symbol.h
+c.o: $(hdrdir)/ruby/internal/token_paste.h
+c.o: $(hdrdir)/ruby/internal/value.h
+c.o: $(hdrdir)/ruby/internal/value_type.h
+c.o: $(hdrdir)/ruby/internal/variable.h
+c.o: $(hdrdir)/ruby/internal/warning_push.h
+c.o: $(hdrdir)/ruby/internal/xmalloc.h
+c.o: $(hdrdir)/ruby/missing.h
+c.o: $(hdrdir)/ruby/ruby.h
+c.o: $(hdrdir)/ruby/st.h
+c.o: $(hdrdir)/ruby/subst.h
+c.o: c.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/RUBY_ALIGNOF/extconf.rb b/ext/-test-/RUBY_ALIGNOF/extconf.rb
new file mode 100644
index 0000000000..98a370e987
--- /dev/null
+++ b/ext/-test-/RUBY_ALIGNOF/extconf.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: false
+$objs = %W"c.#$OBJEXT"
+
+$objs << "cpp.#$OBJEXT" if MakeMakefile['C++'].have_devel?
+
+create_makefile("-test-/RUBY_ALIGNOF")
diff --git a/ext/-test-/arith_seq/extract/depend b/ext/-test-/arith_seq/extract/depend
new file mode 100644
index 0000000000..46117d1000
--- /dev/null
+++ b/ext/-test-/arith_seq/extract/depend
@@ -0,0 +1,162 @@
+# AUTOGENERATED DEPENDENCIES START
+extract.o: $(RUBY_EXTCONF_H)
+extract.o: $(arch_hdrdir)/ruby/config.h
+extract.o: $(hdrdir)/ruby/internal/anyargs.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+extract.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+extract.o: $(hdrdir)/ruby/internal/assume.h
+extract.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+extract.o: $(hdrdir)/ruby/internal/attr/artificial.h
+extract.o: $(hdrdir)/ruby/internal/attr/cold.h
+extract.o: $(hdrdir)/ruby/internal/attr/const.h
+extract.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+extract.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+extract.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+extract.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+extract.o: $(hdrdir)/ruby/internal/attr/error.h
+extract.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+extract.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+extract.o: $(hdrdir)/ruby/internal/attr/format.h
+extract.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+extract.o: $(hdrdir)/ruby/internal/attr/noalias.h
+extract.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+extract.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+extract.o: $(hdrdir)/ruby/internal/attr/noinline.h
+extract.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+extract.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+extract.o: $(hdrdir)/ruby/internal/attr/pure.h
+extract.o: $(hdrdir)/ruby/internal/attr/restrict.h
+extract.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+extract.o: $(hdrdir)/ruby/internal/attr/warning.h
+extract.o: $(hdrdir)/ruby/internal/attr/weakref.h
+extract.o: $(hdrdir)/ruby/internal/cast.h
+extract.o: $(hdrdir)/ruby/internal/compiler_is.h
+extract.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+extract.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+extract.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+extract.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+extract.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+extract.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+extract.o: $(hdrdir)/ruby/internal/compiler_since.h
+extract.o: $(hdrdir)/ruby/internal/config.h
+extract.o: $(hdrdir)/ruby/internal/constant_p.h
+extract.o: $(hdrdir)/ruby/internal/core.h
+extract.o: $(hdrdir)/ruby/internal/core/rarray.h
+extract.o: $(hdrdir)/ruby/internal/core/rbasic.h
+extract.o: $(hdrdir)/ruby/internal/core/rbignum.h
+extract.o: $(hdrdir)/ruby/internal/core/rclass.h
+extract.o: $(hdrdir)/ruby/internal/core/rdata.h
+extract.o: $(hdrdir)/ruby/internal/core/rfile.h
+extract.o: $(hdrdir)/ruby/internal/core/rhash.h
+extract.o: $(hdrdir)/ruby/internal/core/robject.h
+extract.o: $(hdrdir)/ruby/internal/core/rregexp.h
+extract.o: $(hdrdir)/ruby/internal/core/rstring.h
+extract.o: $(hdrdir)/ruby/internal/core/rstruct.h
+extract.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+extract.o: $(hdrdir)/ruby/internal/ctype.h
+extract.o: $(hdrdir)/ruby/internal/dllexport.h
+extract.o: $(hdrdir)/ruby/internal/dosish.h
+extract.o: $(hdrdir)/ruby/internal/error.h
+extract.o: $(hdrdir)/ruby/internal/eval.h
+extract.o: $(hdrdir)/ruby/internal/event.h
+extract.o: $(hdrdir)/ruby/internal/fl_type.h
+extract.o: $(hdrdir)/ruby/internal/gc.h
+extract.o: $(hdrdir)/ruby/internal/glob.h
+extract.o: $(hdrdir)/ruby/internal/globals.h
+extract.o: $(hdrdir)/ruby/internal/has/attribute.h
+extract.o: $(hdrdir)/ruby/internal/has/builtin.h
+extract.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+extract.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+extract.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+extract.o: $(hdrdir)/ruby/internal/has/extension.h
+extract.o: $(hdrdir)/ruby/internal/has/feature.h
+extract.o: $(hdrdir)/ruby/internal/has/warning.h
+extract.o: $(hdrdir)/ruby/internal/intern/array.h
+extract.o: $(hdrdir)/ruby/internal/intern/bignum.h
+extract.o: $(hdrdir)/ruby/internal/intern/class.h
+extract.o: $(hdrdir)/ruby/internal/intern/compar.h
+extract.o: $(hdrdir)/ruby/internal/intern/complex.h
+extract.o: $(hdrdir)/ruby/internal/intern/cont.h
+extract.o: $(hdrdir)/ruby/internal/intern/dir.h
+extract.o: $(hdrdir)/ruby/internal/intern/enum.h
+extract.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+extract.o: $(hdrdir)/ruby/internal/intern/error.h
+extract.o: $(hdrdir)/ruby/internal/intern/eval.h
+extract.o: $(hdrdir)/ruby/internal/intern/file.h
+extract.o: $(hdrdir)/ruby/internal/intern/gc.h
+extract.o: $(hdrdir)/ruby/internal/intern/hash.h
+extract.o: $(hdrdir)/ruby/internal/intern/io.h
+extract.o: $(hdrdir)/ruby/internal/intern/load.h
+extract.o: $(hdrdir)/ruby/internal/intern/marshal.h
+extract.o: $(hdrdir)/ruby/internal/intern/numeric.h
+extract.o: $(hdrdir)/ruby/internal/intern/object.h
+extract.o: $(hdrdir)/ruby/internal/intern/parse.h
+extract.o: $(hdrdir)/ruby/internal/intern/proc.h
+extract.o: $(hdrdir)/ruby/internal/intern/process.h
+extract.o: $(hdrdir)/ruby/internal/intern/random.h
+extract.o: $(hdrdir)/ruby/internal/intern/range.h
+extract.o: $(hdrdir)/ruby/internal/intern/rational.h
+extract.o: $(hdrdir)/ruby/internal/intern/re.h
+extract.o: $(hdrdir)/ruby/internal/intern/ruby.h
+extract.o: $(hdrdir)/ruby/internal/intern/select.h
+extract.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+extract.o: $(hdrdir)/ruby/internal/intern/signal.h
+extract.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+extract.o: $(hdrdir)/ruby/internal/intern/string.h
+extract.o: $(hdrdir)/ruby/internal/intern/struct.h
+extract.o: $(hdrdir)/ruby/internal/intern/thread.h
+extract.o: $(hdrdir)/ruby/internal/intern/time.h
+extract.o: $(hdrdir)/ruby/internal/intern/variable.h
+extract.o: $(hdrdir)/ruby/internal/intern/vm.h
+extract.o: $(hdrdir)/ruby/internal/interpreter.h
+extract.o: $(hdrdir)/ruby/internal/iterator.h
+extract.o: $(hdrdir)/ruby/internal/memory.h
+extract.o: $(hdrdir)/ruby/internal/method.h
+extract.o: $(hdrdir)/ruby/internal/module.h
+extract.o: $(hdrdir)/ruby/internal/newobj.h
+extract.o: $(hdrdir)/ruby/internal/rgengc.h
+extract.o: $(hdrdir)/ruby/internal/scan_args.h
+extract.o: $(hdrdir)/ruby/internal/special_consts.h
+extract.o: $(hdrdir)/ruby/internal/static_assert.h
+extract.o: $(hdrdir)/ruby/internal/stdalign.h
+extract.o: $(hdrdir)/ruby/internal/stdbool.h
+extract.o: $(hdrdir)/ruby/internal/symbol.h
+extract.o: $(hdrdir)/ruby/internal/token_paste.h
+extract.o: $(hdrdir)/ruby/internal/value.h
+extract.o: $(hdrdir)/ruby/internal/value_type.h
+extract.o: $(hdrdir)/ruby/internal/variable.h
+extract.o: $(hdrdir)/ruby/internal/warning_push.h
+extract.o: $(hdrdir)/ruby/internal/xmalloc.h
+extract.o: $(hdrdir)/ruby/assert.h
+extract.o: $(hdrdir)/ruby/backward.h
+extract.o: $(hdrdir)/ruby/backward/2/assume.h
+extract.o: $(hdrdir)/ruby/backward/2/attributes.h
+extract.o: $(hdrdir)/ruby/backward/2/bool.h
+extract.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+extract.o: $(hdrdir)/ruby/backward/2/inttypes.h
+extract.o: $(hdrdir)/ruby/backward/2/limits.h
+extract.o: $(hdrdir)/ruby/backward/2/long_long.h
+extract.o: $(hdrdir)/ruby/backward/2/stdalign.h
+extract.o: $(hdrdir)/ruby/backward/2/stdarg.h
+extract.o: $(hdrdir)/ruby/defines.h
+extract.o: $(hdrdir)/ruby/intern.h
+extract.o: $(hdrdir)/ruby/missing.h
+extract.o: $(hdrdir)/ruby/ruby.h
+extract.o: $(hdrdir)/ruby/st.h
+extract.o: $(hdrdir)/ruby/subst.h
+extract.o: extract.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/arith_seq/extract/extconf.rb b/ext/-test-/arith_seq/extract/extconf.rb
new file mode 100644
index 0000000000..9c368bf50e
--- /dev/null
+++ b/ext/-test-/arith_seq/extract/extconf.rb
@@ -0,0 +1,2 @@
+# frozen_string_literal: false
+create_makefile("-test-/arith_seq/extract")
diff --git a/ext/-test-/arith_seq/extract/extract.c b/ext/-test-/arith_seq/extract/extract.c
new file mode 100644
index 0000000000..93b89c239a
--- /dev/null
+++ b/ext/-test-/arith_seq/extract/extract.c
@@ -0,0 +1,27 @@
+#include "ruby/ruby.h"
+
+static VALUE
+arith_seq_s_extract(VALUE mod, VALUE obj)
+{
+ rb_arithmetic_sequence_components_t x;
+ VALUE ret;
+ int r;
+
+ r = rb_arithmetic_sequence_extract(obj, &x);
+
+ ret = rb_ary_new2(5);
+ rb_ary_store(ret, 0, r ? x.begin : Qnil);
+ rb_ary_store(ret, 1, r ? x.end : Qnil);
+ rb_ary_store(ret, 2, r ? x.step : Qnil);
+ rb_ary_store(ret, 3, r ? INT2FIX(x.exclude_end) : Qnil);
+ rb_ary_store(ret, 4, INT2FIX(r));
+
+ return ret;
+}
+
+void
+Init_extract(void)
+{
+ VALUE cArithSeq = rb_path2class("Enumerator::ArithmeticSequence");
+ rb_define_singleton_method(cArithSeq, "__extract__", arith_seq_s_extract, 1);
+}
diff --git a/ext/-test-/array/concat/depend b/ext/-test-/array/concat/depend
new file mode 100644
index 0000000000..4f2ba01f71
--- /dev/null
+++ b/ext/-test-/array/concat/depend
@@ -0,0 +1,322 @@
+# AUTOGENERATED DEPENDENCIES START
+resize.o: $(RUBY_EXTCONF_H)
+resize.o: $(arch_hdrdir)/ruby/config.h
+resize.o: $(hdrdir)/ruby/assert.h
+resize.o: $(hdrdir)/ruby/backward.h
+resize.o: $(hdrdir)/ruby/backward/2/assume.h
+resize.o: $(hdrdir)/ruby/backward/2/attributes.h
+resize.o: $(hdrdir)/ruby/backward/2/bool.h
+resize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+resize.o: $(hdrdir)/ruby/backward/2/inttypes.h
+resize.o: $(hdrdir)/ruby/backward/2/limits.h
+resize.o: $(hdrdir)/ruby/backward/2/long_long.h
+resize.o: $(hdrdir)/ruby/backward/2/stdalign.h
+resize.o: $(hdrdir)/ruby/backward/2/stdarg.h
+resize.o: $(hdrdir)/ruby/defines.h
+resize.o: $(hdrdir)/ruby/intern.h
+resize.o: $(hdrdir)/ruby/internal/anyargs.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+resize.o: $(hdrdir)/ruby/internal/assume.h
+resize.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+resize.o: $(hdrdir)/ruby/internal/attr/artificial.h
+resize.o: $(hdrdir)/ruby/internal/attr/cold.h
+resize.o: $(hdrdir)/ruby/internal/attr/const.h
+resize.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+resize.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+resize.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+resize.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+resize.o: $(hdrdir)/ruby/internal/attr/error.h
+resize.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+resize.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+resize.o: $(hdrdir)/ruby/internal/attr/format.h
+resize.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+resize.o: $(hdrdir)/ruby/internal/attr/noalias.h
+resize.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+resize.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+resize.o: $(hdrdir)/ruby/internal/attr/noinline.h
+resize.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+resize.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+resize.o: $(hdrdir)/ruby/internal/attr/pure.h
+resize.o: $(hdrdir)/ruby/internal/attr/restrict.h
+resize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+resize.o: $(hdrdir)/ruby/internal/attr/warning.h
+resize.o: $(hdrdir)/ruby/internal/attr/weakref.h
+resize.o: $(hdrdir)/ruby/internal/cast.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+resize.o: $(hdrdir)/ruby/internal/compiler_since.h
+resize.o: $(hdrdir)/ruby/internal/config.h
+resize.o: $(hdrdir)/ruby/internal/constant_p.h
+resize.o: $(hdrdir)/ruby/internal/core.h
+resize.o: $(hdrdir)/ruby/internal/core/rarray.h
+resize.o: $(hdrdir)/ruby/internal/core/rbasic.h
+resize.o: $(hdrdir)/ruby/internal/core/rbignum.h
+resize.o: $(hdrdir)/ruby/internal/core/rclass.h
+resize.o: $(hdrdir)/ruby/internal/core/rdata.h
+resize.o: $(hdrdir)/ruby/internal/core/rfile.h
+resize.o: $(hdrdir)/ruby/internal/core/rhash.h
+resize.o: $(hdrdir)/ruby/internal/core/robject.h
+resize.o: $(hdrdir)/ruby/internal/core/rregexp.h
+resize.o: $(hdrdir)/ruby/internal/core/rstring.h
+resize.o: $(hdrdir)/ruby/internal/core/rstruct.h
+resize.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+resize.o: $(hdrdir)/ruby/internal/ctype.h
+resize.o: $(hdrdir)/ruby/internal/dllexport.h
+resize.o: $(hdrdir)/ruby/internal/dosish.h
+resize.o: $(hdrdir)/ruby/internal/error.h
+resize.o: $(hdrdir)/ruby/internal/eval.h
+resize.o: $(hdrdir)/ruby/internal/event.h
+resize.o: $(hdrdir)/ruby/internal/fl_type.h
+resize.o: $(hdrdir)/ruby/internal/gc.h
+resize.o: $(hdrdir)/ruby/internal/glob.h
+resize.o: $(hdrdir)/ruby/internal/globals.h
+resize.o: $(hdrdir)/ruby/internal/has/attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/builtin.h
+resize.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/extension.h
+resize.o: $(hdrdir)/ruby/internal/has/feature.h
+resize.o: $(hdrdir)/ruby/internal/has/warning.h
+resize.o: $(hdrdir)/ruby/internal/intern/array.h
+resize.o: $(hdrdir)/ruby/internal/intern/bignum.h
+resize.o: $(hdrdir)/ruby/internal/intern/class.h
+resize.o: $(hdrdir)/ruby/internal/intern/compar.h
+resize.o: $(hdrdir)/ruby/internal/intern/complex.h
+resize.o: $(hdrdir)/ruby/internal/intern/cont.h
+resize.o: $(hdrdir)/ruby/internal/intern/dir.h
+resize.o: $(hdrdir)/ruby/internal/intern/enum.h
+resize.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+resize.o: $(hdrdir)/ruby/internal/intern/error.h
+resize.o: $(hdrdir)/ruby/internal/intern/eval.h
+resize.o: $(hdrdir)/ruby/internal/intern/file.h
+resize.o: $(hdrdir)/ruby/internal/intern/gc.h
+resize.o: $(hdrdir)/ruby/internal/intern/hash.h
+resize.o: $(hdrdir)/ruby/internal/intern/io.h
+resize.o: $(hdrdir)/ruby/internal/intern/load.h
+resize.o: $(hdrdir)/ruby/internal/intern/marshal.h
+resize.o: $(hdrdir)/ruby/internal/intern/numeric.h
+resize.o: $(hdrdir)/ruby/internal/intern/object.h
+resize.o: $(hdrdir)/ruby/internal/intern/parse.h
+resize.o: $(hdrdir)/ruby/internal/intern/proc.h
+resize.o: $(hdrdir)/ruby/internal/intern/process.h
+resize.o: $(hdrdir)/ruby/internal/intern/random.h
+resize.o: $(hdrdir)/ruby/internal/intern/range.h
+resize.o: $(hdrdir)/ruby/internal/intern/rational.h
+resize.o: $(hdrdir)/ruby/internal/intern/re.h
+resize.o: $(hdrdir)/ruby/internal/intern/ruby.h
+resize.o: $(hdrdir)/ruby/internal/intern/select.h
+resize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+resize.o: $(hdrdir)/ruby/internal/intern/signal.h
+resize.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+resize.o: $(hdrdir)/ruby/internal/intern/string.h
+resize.o: $(hdrdir)/ruby/internal/intern/struct.h
+resize.o: $(hdrdir)/ruby/internal/intern/thread.h
+resize.o: $(hdrdir)/ruby/internal/intern/time.h
+resize.o: $(hdrdir)/ruby/internal/intern/variable.h
+resize.o: $(hdrdir)/ruby/internal/intern/vm.h
+resize.o: $(hdrdir)/ruby/internal/interpreter.h
+resize.o: $(hdrdir)/ruby/internal/iterator.h
+resize.o: $(hdrdir)/ruby/internal/memory.h
+resize.o: $(hdrdir)/ruby/internal/method.h
+resize.o: $(hdrdir)/ruby/internal/module.h
+resize.o: $(hdrdir)/ruby/internal/newobj.h
+resize.o: $(hdrdir)/ruby/internal/rgengc.h
+resize.o: $(hdrdir)/ruby/internal/scan_args.h
+resize.o: $(hdrdir)/ruby/internal/special_consts.h
+resize.o: $(hdrdir)/ruby/internal/static_assert.h
+resize.o: $(hdrdir)/ruby/internal/stdalign.h
+resize.o: $(hdrdir)/ruby/internal/stdbool.h
+resize.o: $(hdrdir)/ruby/internal/symbol.h
+resize.o: $(hdrdir)/ruby/internal/value.h
+resize.o: $(hdrdir)/ruby/internal/value_type.h
+resize.o: $(hdrdir)/ruby/internal/variable.h
+resize.o: $(hdrdir)/ruby/internal/warning_push.h
+resize.o: $(hdrdir)/ruby/internal/xmalloc.h
+resize.o: $(hdrdir)/ruby/missing.h
+resize.o: $(hdrdir)/ruby/ruby.h
+resize.o: $(hdrdir)/ruby/st.h
+resize.o: $(hdrdir)/ruby/subst.h
+resize.o: resize.c
+to_ary_conact.o: $(RUBY_EXTCONF_H)
+to_ary_conact.o: $(arch_hdrdir)/ruby/config.h
+to_ary_conact.o: $(hdrdir)/ruby.h
+to_ary_conact.o: $(hdrdir)/ruby/assert.h
+to_ary_conact.o: $(hdrdir)/ruby/backward.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/assume.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/attributes.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/bool.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/inttypes.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/limits.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/long_long.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/stdalign.h
+to_ary_conact.o: $(hdrdir)/ruby/backward/2/stdarg.h
+to_ary_conact.o: $(hdrdir)/ruby/defines.h
+to_ary_conact.o: $(hdrdir)/ruby/intern.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/anyargs.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/assume.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/artificial.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/cold.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/const.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/error.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/format.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noalias.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noinline.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/pure.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/restrict.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/warning.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/attr/weakref.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/cast.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_since.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/config.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/constant_p.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rarray.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rbasic.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rbignum.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rclass.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rdata.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rfile.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rhash.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/robject.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rregexp.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rstring.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rstruct.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/ctype.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/dllexport.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/dosish.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/error.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/eval.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/event.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/fl_type.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/gc.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/glob.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/globals.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/attribute.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/builtin.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/extension.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/feature.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/has/warning.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/array.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/bignum.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/class.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/compar.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/complex.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/cont.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/dir.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/enum.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/error.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/eval.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/file.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/gc.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/hash.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/io.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/load.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/marshal.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/numeric.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/object.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/parse.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/proc.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/process.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/random.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/range.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/rational.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/re.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/ruby.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/select.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/signal.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/string.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/struct.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/thread.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/time.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/variable.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/intern/vm.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/interpreter.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/iterator.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/memory.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/method.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/module.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/newobj.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/rgengc.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/scan_args.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/special_consts.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/static_assert.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/stdalign.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/stdbool.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/symbol.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/token_paste.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/value.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/value_type.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/variable.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/warning_push.h
+to_ary_conact.o: $(hdrdir)/ruby/internal/xmalloc.h
+to_ary_conact.o: $(hdrdir)/ruby/missing.h
+to_ary_conact.o: $(hdrdir)/ruby/ruby.h
+to_ary_conact.o: $(hdrdir)/ruby/st.h
+to_ary_conact.o: $(hdrdir)/ruby/subst.h
+to_ary_conact.o: to_ary_conact.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/array/concat/extconf.rb b/ext/-test-/array/concat/extconf.rb
new file mode 100644
index 0000000000..cdd79126c9
--- /dev/null
+++ b/ext/-test-/array/concat/extconf.rb
@@ -0,0 +1,2 @@
+# frozen_string_literal: false
+create_makefile("-test-/array/to_ary_concat")
diff --git a/ext/-test-/array/concat/to_ary_conact.c b/ext/-test-/array/concat/to_ary_conact.c
new file mode 100644
index 0000000000..ec1fd321ce
--- /dev/null
+++ b/ext/-test-/array/concat/to_ary_conact.c
@@ -0,0 +1,34 @@
+#include "ruby.h"
+
+// Bar
+
+typedef struct {
+ int dummy;
+} Bar;
+
+static rb_data_type_t Bar_type = {
+ "Bar",
+ {NULL, RUBY_TYPED_DEFAULT_FREE, NULL },
+};
+
+static VALUE
+Bar_alloc(VALUE klass)
+{
+ return TypedData_Wrap_Struct(klass, &Bar_type, NULL);
+}
+
+VALUE Bar_to_ary(VALUE _self) {
+ VALUE ary = rb_ary_new2(2);
+ VALUE foo = rb_ary_new2(0);
+ rb_ary_push(ary, foo);
+ rb_ary_push(ary, foo);
+ rb_ary_push(ary, foo);
+ return ary;
+}
+
+void Init_to_ary_concat() {
+ VALUE mBug = rb_define_module("Bug");
+ VALUE bar = rb_define_class_under(mBug, "Bar", rb_cObject);
+ rb_define_alloc_func(bar, Bar_alloc);
+ rb_define_method(bar, "to_ary", Bar_to_ary, 0);
+}
diff --git a/ext/-test-/array/resize/depend b/ext/-test-/array/resize/depend
index 177c527db2..7c52b21e59 100644
--- a/ext/-test-/array/resize/depend
+++ b/ext/-test-/array/resize/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
resize.o: $(RUBY_EXTCONF_H)
resize.o: $(arch_hdrdir)/ruby/config.h
+resize.o: $(hdrdir)/ruby/internal/anyargs.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+resize.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+resize.o: $(hdrdir)/ruby/internal/assume.h
+resize.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+resize.o: $(hdrdir)/ruby/internal/attr/artificial.h
+resize.o: $(hdrdir)/ruby/internal/attr/cold.h
+resize.o: $(hdrdir)/ruby/internal/attr/const.h
+resize.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+resize.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+resize.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+resize.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+resize.o: $(hdrdir)/ruby/internal/attr/error.h
+resize.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+resize.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+resize.o: $(hdrdir)/ruby/internal/attr/format.h
+resize.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+resize.o: $(hdrdir)/ruby/internal/attr/noalias.h
+resize.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+resize.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+resize.o: $(hdrdir)/ruby/internal/attr/noinline.h
+resize.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+resize.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+resize.o: $(hdrdir)/ruby/internal/attr/pure.h
+resize.o: $(hdrdir)/ruby/internal/attr/restrict.h
+resize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+resize.o: $(hdrdir)/ruby/internal/attr/warning.h
+resize.o: $(hdrdir)/ruby/internal/attr/weakref.h
+resize.o: $(hdrdir)/ruby/internal/cast.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+resize.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+resize.o: $(hdrdir)/ruby/internal/compiler_since.h
+resize.o: $(hdrdir)/ruby/internal/config.h
+resize.o: $(hdrdir)/ruby/internal/constant_p.h
+resize.o: $(hdrdir)/ruby/internal/core.h
+resize.o: $(hdrdir)/ruby/internal/core/rarray.h
+resize.o: $(hdrdir)/ruby/internal/core/rbasic.h
+resize.o: $(hdrdir)/ruby/internal/core/rbignum.h
+resize.o: $(hdrdir)/ruby/internal/core/rclass.h
+resize.o: $(hdrdir)/ruby/internal/core/rdata.h
+resize.o: $(hdrdir)/ruby/internal/core/rfile.h
+resize.o: $(hdrdir)/ruby/internal/core/rhash.h
+resize.o: $(hdrdir)/ruby/internal/core/robject.h
+resize.o: $(hdrdir)/ruby/internal/core/rregexp.h
+resize.o: $(hdrdir)/ruby/internal/core/rstring.h
+resize.o: $(hdrdir)/ruby/internal/core/rstruct.h
+resize.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+resize.o: $(hdrdir)/ruby/internal/ctype.h
+resize.o: $(hdrdir)/ruby/internal/dllexport.h
+resize.o: $(hdrdir)/ruby/internal/dosish.h
+resize.o: $(hdrdir)/ruby/internal/error.h
+resize.o: $(hdrdir)/ruby/internal/eval.h
+resize.o: $(hdrdir)/ruby/internal/event.h
+resize.o: $(hdrdir)/ruby/internal/fl_type.h
+resize.o: $(hdrdir)/ruby/internal/gc.h
+resize.o: $(hdrdir)/ruby/internal/glob.h
+resize.o: $(hdrdir)/ruby/internal/globals.h
+resize.o: $(hdrdir)/ruby/internal/has/attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/builtin.h
+resize.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+resize.o: $(hdrdir)/ruby/internal/has/extension.h
+resize.o: $(hdrdir)/ruby/internal/has/feature.h
+resize.o: $(hdrdir)/ruby/internal/has/warning.h
+resize.o: $(hdrdir)/ruby/internal/intern/array.h
+resize.o: $(hdrdir)/ruby/internal/intern/bignum.h
+resize.o: $(hdrdir)/ruby/internal/intern/class.h
+resize.o: $(hdrdir)/ruby/internal/intern/compar.h
+resize.o: $(hdrdir)/ruby/internal/intern/complex.h
+resize.o: $(hdrdir)/ruby/internal/intern/cont.h
+resize.o: $(hdrdir)/ruby/internal/intern/dir.h
+resize.o: $(hdrdir)/ruby/internal/intern/enum.h
+resize.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+resize.o: $(hdrdir)/ruby/internal/intern/error.h
+resize.o: $(hdrdir)/ruby/internal/intern/eval.h
+resize.o: $(hdrdir)/ruby/internal/intern/file.h
+resize.o: $(hdrdir)/ruby/internal/intern/gc.h
+resize.o: $(hdrdir)/ruby/internal/intern/hash.h
+resize.o: $(hdrdir)/ruby/internal/intern/io.h
+resize.o: $(hdrdir)/ruby/internal/intern/load.h
+resize.o: $(hdrdir)/ruby/internal/intern/marshal.h
+resize.o: $(hdrdir)/ruby/internal/intern/numeric.h
+resize.o: $(hdrdir)/ruby/internal/intern/object.h
+resize.o: $(hdrdir)/ruby/internal/intern/parse.h
+resize.o: $(hdrdir)/ruby/internal/intern/proc.h
+resize.o: $(hdrdir)/ruby/internal/intern/process.h
+resize.o: $(hdrdir)/ruby/internal/intern/random.h
+resize.o: $(hdrdir)/ruby/internal/intern/range.h
+resize.o: $(hdrdir)/ruby/internal/intern/rational.h
+resize.o: $(hdrdir)/ruby/internal/intern/re.h
+resize.o: $(hdrdir)/ruby/internal/intern/ruby.h
+resize.o: $(hdrdir)/ruby/internal/intern/select.h
+resize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+resize.o: $(hdrdir)/ruby/internal/intern/signal.h
+resize.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+resize.o: $(hdrdir)/ruby/internal/intern/string.h
+resize.o: $(hdrdir)/ruby/internal/intern/struct.h
+resize.o: $(hdrdir)/ruby/internal/intern/thread.h
+resize.o: $(hdrdir)/ruby/internal/intern/time.h
+resize.o: $(hdrdir)/ruby/internal/intern/variable.h
+resize.o: $(hdrdir)/ruby/internal/intern/vm.h
+resize.o: $(hdrdir)/ruby/internal/interpreter.h
+resize.o: $(hdrdir)/ruby/internal/iterator.h
+resize.o: $(hdrdir)/ruby/internal/memory.h
+resize.o: $(hdrdir)/ruby/internal/method.h
+resize.o: $(hdrdir)/ruby/internal/module.h
+resize.o: $(hdrdir)/ruby/internal/newobj.h
+resize.o: $(hdrdir)/ruby/internal/rgengc.h
+resize.o: $(hdrdir)/ruby/internal/scan_args.h
+resize.o: $(hdrdir)/ruby/internal/special_consts.h
+resize.o: $(hdrdir)/ruby/internal/static_assert.h
+resize.o: $(hdrdir)/ruby/internal/stdalign.h
+resize.o: $(hdrdir)/ruby/internal/stdbool.h
+resize.o: $(hdrdir)/ruby/internal/symbol.h
+resize.o: $(hdrdir)/ruby/internal/token_paste.h
+resize.o: $(hdrdir)/ruby/internal/value.h
+resize.o: $(hdrdir)/ruby/internal/value_type.h
+resize.o: $(hdrdir)/ruby/internal/variable.h
+resize.o: $(hdrdir)/ruby/internal/warning_push.h
+resize.o: $(hdrdir)/ruby/internal/xmalloc.h
+resize.o: $(hdrdir)/ruby/assert.h
resize.o: $(hdrdir)/ruby/backward.h
+resize.o: $(hdrdir)/ruby/backward/2/assume.h
+resize.o: $(hdrdir)/ruby/backward/2/attributes.h
+resize.o: $(hdrdir)/ruby/backward/2/bool.h
+resize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+resize.o: $(hdrdir)/ruby/backward/2/inttypes.h
+resize.o: $(hdrdir)/ruby/backward/2/limits.h
+resize.o: $(hdrdir)/ruby/backward/2/long_long.h
+resize.o: $(hdrdir)/ruby/backward/2/stdalign.h
+resize.o: $(hdrdir)/ruby/backward/2/stdarg.h
resize.o: $(hdrdir)/ruby/defines.h
resize.o: $(hdrdir)/ruby/intern.h
resize.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/-test-/bignum/big2str.c b/ext/-test-/bignum/big2str.c
index ec4bde2915..bc5a933f82 100644
--- a/ext/-test-/bignum/big2str.c
+++ b/ext/-test-/bignum/big2str.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/bignum.h"
static VALUE
big(VALUE x)
diff --git a/ext/-test-/bignum/bigzero.c b/ext/-test-/bignum/bigzero.c
index 35117db7ae..e2bfebcd3e 100644
--- a/ext/-test-/bignum/bigzero.c
+++ b/ext/-test-/bignum/bigzero.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/bignum.h"
static VALUE
bug_big_zero(VALUE self, VALUE length)
diff --git a/ext/-test-/bignum/depend b/ext/-test-/bignum/depend
index 60e711489c..7ddf1da1dc 100644
--- a/ext/-test-/bignum/depend
+++ b/ext/-test-/bignum/depend
@@ -1,115 +1,1141 @@
-big2str.o: big2str.c
-div.o: div.c
-intpack.o: intpack.c
-mul.o: mul.c
-str2big.o: str2big.c
-
# AUTOGENERATED DEPENDENCIES START
big2str.o: $(RUBY_EXTCONF_H)
big2str.o: $(arch_hdrdir)/ruby/config.h
+big2str.o: $(hdrdir)/ruby.h
+big2str.o: $(hdrdir)/ruby/internal/anyargs.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+big2str.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+big2str.o: $(hdrdir)/ruby/internal/assume.h
+big2str.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+big2str.o: $(hdrdir)/ruby/internal/attr/artificial.h
+big2str.o: $(hdrdir)/ruby/internal/attr/cold.h
+big2str.o: $(hdrdir)/ruby/internal/attr/const.h
+big2str.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+big2str.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+big2str.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+big2str.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+big2str.o: $(hdrdir)/ruby/internal/attr/error.h
+big2str.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+big2str.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+big2str.o: $(hdrdir)/ruby/internal/attr/format.h
+big2str.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+big2str.o: $(hdrdir)/ruby/internal/attr/noalias.h
+big2str.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+big2str.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+big2str.o: $(hdrdir)/ruby/internal/attr/noinline.h
+big2str.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+big2str.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+big2str.o: $(hdrdir)/ruby/internal/attr/pure.h
+big2str.o: $(hdrdir)/ruby/internal/attr/restrict.h
+big2str.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+big2str.o: $(hdrdir)/ruby/internal/attr/warning.h
+big2str.o: $(hdrdir)/ruby/internal/attr/weakref.h
+big2str.o: $(hdrdir)/ruby/internal/cast.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_is.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+big2str.o: $(hdrdir)/ruby/internal/compiler_since.h
+big2str.o: $(hdrdir)/ruby/internal/config.h
+big2str.o: $(hdrdir)/ruby/internal/constant_p.h
+big2str.o: $(hdrdir)/ruby/internal/core.h
+big2str.o: $(hdrdir)/ruby/internal/core/rarray.h
+big2str.o: $(hdrdir)/ruby/internal/core/rbasic.h
+big2str.o: $(hdrdir)/ruby/internal/core/rbignum.h
+big2str.o: $(hdrdir)/ruby/internal/core/rclass.h
+big2str.o: $(hdrdir)/ruby/internal/core/rdata.h
+big2str.o: $(hdrdir)/ruby/internal/core/rfile.h
+big2str.o: $(hdrdir)/ruby/internal/core/rhash.h
+big2str.o: $(hdrdir)/ruby/internal/core/robject.h
+big2str.o: $(hdrdir)/ruby/internal/core/rregexp.h
+big2str.o: $(hdrdir)/ruby/internal/core/rstring.h
+big2str.o: $(hdrdir)/ruby/internal/core/rstruct.h
+big2str.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+big2str.o: $(hdrdir)/ruby/internal/ctype.h
+big2str.o: $(hdrdir)/ruby/internal/dllexport.h
+big2str.o: $(hdrdir)/ruby/internal/dosish.h
+big2str.o: $(hdrdir)/ruby/internal/error.h
+big2str.o: $(hdrdir)/ruby/internal/eval.h
+big2str.o: $(hdrdir)/ruby/internal/event.h
+big2str.o: $(hdrdir)/ruby/internal/fl_type.h
+big2str.o: $(hdrdir)/ruby/internal/gc.h
+big2str.o: $(hdrdir)/ruby/internal/glob.h
+big2str.o: $(hdrdir)/ruby/internal/globals.h
+big2str.o: $(hdrdir)/ruby/internal/has/attribute.h
+big2str.o: $(hdrdir)/ruby/internal/has/builtin.h
+big2str.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+big2str.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+big2str.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+big2str.o: $(hdrdir)/ruby/internal/has/extension.h
+big2str.o: $(hdrdir)/ruby/internal/has/feature.h
+big2str.o: $(hdrdir)/ruby/internal/has/warning.h
+big2str.o: $(hdrdir)/ruby/internal/intern/array.h
+big2str.o: $(hdrdir)/ruby/internal/intern/bignum.h
+big2str.o: $(hdrdir)/ruby/internal/intern/class.h
+big2str.o: $(hdrdir)/ruby/internal/intern/compar.h
+big2str.o: $(hdrdir)/ruby/internal/intern/complex.h
+big2str.o: $(hdrdir)/ruby/internal/intern/cont.h
+big2str.o: $(hdrdir)/ruby/internal/intern/dir.h
+big2str.o: $(hdrdir)/ruby/internal/intern/enum.h
+big2str.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+big2str.o: $(hdrdir)/ruby/internal/intern/error.h
+big2str.o: $(hdrdir)/ruby/internal/intern/eval.h
+big2str.o: $(hdrdir)/ruby/internal/intern/file.h
+big2str.o: $(hdrdir)/ruby/internal/intern/gc.h
+big2str.o: $(hdrdir)/ruby/internal/intern/hash.h
+big2str.o: $(hdrdir)/ruby/internal/intern/io.h
+big2str.o: $(hdrdir)/ruby/internal/intern/load.h
+big2str.o: $(hdrdir)/ruby/internal/intern/marshal.h
+big2str.o: $(hdrdir)/ruby/internal/intern/numeric.h
+big2str.o: $(hdrdir)/ruby/internal/intern/object.h
+big2str.o: $(hdrdir)/ruby/internal/intern/parse.h
+big2str.o: $(hdrdir)/ruby/internal/intern/proc.h
+big2str.o: $(hdrdir)/ruby/internal/intern/process.h
+big2str.o: $(hdrdir)/ruby/internal/intern/random.h
+big2str.o: $(hdrdir)/ruby/internal/intern/range.h
+big2str.o: $(hdrdir)/ruby/internal/intern/rational.h
+big2str.o: $(hdrdir)/ruby/internal/intern/re.h
+big2str.o: $(hdrdir)/ruby/internal/intern/ruby.h
+big2str.o: $(hdrdir)/ruby/internal/intern/select.h
+big2str.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+big2str.o: $(hdrdir)/ruby/internal/intern/signal.h
+big2str.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+big2str.o: $(hdrdir)/ruby/internal/intern/string.h
+big2str.o: $(hdrdir)/ruby/internal/intern/struct.h
+big2str.o: $(hdrdir)/ruby/internal/intern/thread.h
+big2str.o: $(hdrdir)/ruby/internal/intern/time.h
+big2str.o: $(hdrdir)/ruby/internal/intern/variable.h
+big2str.o: $(hdrdir)/ruby/internal/intern/vm.h
+big2str.o: $(hdrdir)/ruby/internal/interpreter.h
+big2str.o: $(hdrdir)/ruby/internal/iterator.h
+big2str.o: $(hdrdir)/ruby/internal/memory.h
+big2str.o: $(hdrdir)/ruby/internal/method.h
+big2str.o: $(hdrdir)/ruby/internal/module.h
+big2str.o: $(hdrdir)/ruby/internal/newobj.h
+big2str.o: $(hdrdir)/ruby/internal/rgengc.h
+big2str.o: $(hdrdir)/ruby/internal/scan_args.h
+big2str.o: $(hdrdir)/ruby/internal/special_consts.h
+big2str.o: $(hdrdir)/ruby/internal/static_assert.h
+big2str.o: $(hdrdir)/ruby/internal/stdalign.h
+big2str.o: $(hdrdir)/ruby/internal/stdbool.h
+big2str.o: $(hdrdir)/ruby/internal/symbol.h
+big2str.o: $(hdrdir)/ruby/internal/token_paste.h
+big2str.o: $(hdrdir)/ruby/internal/value.h
+big2str.o: $(hdrdir)/ruby/internal/value_type.h
+big2str.o: $(hdrdir)/ruby/internal/variable.h
+big2str.o: $(hdrdir)/ruby/internal/warning_push.h
+big2str.o: $(hdrdir)/ruby/internal/xmalloc.h
+big2str.o: $(hdrdir)/ruby/assert.h
big2str.o: $(hdrdir)/ruby/backward.h
+big2str.o: $(hdrdir)/ruby/backward/2/assume.h
+big2str.o: $(hdrdir)/ruby/backward/2/attributes.h
+big2str.o: $(hdrdir)/ruby/backward/2/bool.h
+big2str.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+big2str.o: $(hdrdir)/ruby/backward/2/inttypes.h
+big2str.o: $(hdrdir)/ruby/backward/2/limits.h
+big2str.o: $(hdrdir)/ruby/backward/2/long_long.h
+big2str.o: $(hdrdir)/ruby/backward/2/stdalign.h
+big2str.o: $(hdrdir)/ruby/backward/2/stdarg.h
big2str.o: $(hdrdir)/ruby/defines.h
-big2str.o: $(hdrdir)/ruby/encoding.h
big2str.o: $(hdrdir)/ruby/intern.h
-big2str.o: $(hdrdir)/ruby/io.h
big2str.o: $(hdrdir)/ruby/missing.h
-big2str.o: $(hdrdir)/ruby/onigmo.h
-big2str.o: $(hdrdir)/ruby/oniguruma.h
big2str.o: $(hdrdir)/ruby/ruby.h
big2str.o: $(hdrdir)/ruby/st.h
big2str.o: $(hdrdir)/ruby/subst.h
-big2str.o: $(top_srcdir)/include/ruby.h
big2str.o: $(top_srcdir)/internal.h
+big2str.o: $(top_srcdir)/internal/bignum.h
big2str.o: big2str.c
bigzero.o: $(RUBY_EXTCONF_H)
bigzero.o: $(arch_hdrdir)/ruby/config.h
+bigzero.o: $(hdrdir)/ruby.h
+bigzero.o: $(hdrdir)/ruby/internal/anyargs.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bigzero.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bigzero.o: $(hdrdir)/ruby/internal/assume.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/cold.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/const.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/error.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/format.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/pure.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/warning.h
+bigzero.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bigzero.o: $(hdrdir)/ruby/internal/cast.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_is.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bigzero.o: $(hdrdir)/ruby/internal/compiler_since.h
+bigzero.o: $(hdrdir)/ruby/internal/config.h
+bigzero.o: $(hdrdir)/ruby/internal/constant_p.h
+bigzero.o: $(hdrdir)/ruby/internal/core.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rarray.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rclass.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rdata.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rfile.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rhash.h
+bigzero.o: $(hdrdir)/ruby/internal/core/robject.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rstring.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bigzero.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bigzero.o: $(hdrdir)/ruby/internal/ctype.h
+bigzero.o: $(hdrdir)/ruby/internal/dllexport.h
+bigzero.o: $(hdrdir)/ruby/internal/dosish.h
+bigzero.o: $(hdrdir)/ruby/internal/error.h
+bigzero.o: $(hdrdir)/ruby/internal/eval.h
+bigzero.o: $(hdrdir)/ruby/internal/event.h
+bigzero.o: $(hdrdir)/ruby/internal/fl_type.h
+bigzero.o: $(hdrdir)/ruby/internal/gc.h
+bigzero.o: $(hdrdir)/ruby/internal/glob.h
+bigzero.o: $(hdrdir)/ruby/internal/globals.h
+bigzero.o: $(hdrdir)/ruby/internal/has/attribute.h
+bigzero.o: $(hdrdir)/ruby/internal/has/builtin.h
+bigzero.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bigzero.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bigzero.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bigzero.o: $(hdrdir)/ruby/internal/has/extension.h
+bigzero.o: $(hdrdir)/ruby/internal/has/feature.h
+bigzero.o: $(hdrdir)/ruby/internal/has/warning.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/array.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/class.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/compar.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/complex.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/cont.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/dir.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/enum.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/error.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/eval.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/file.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/gc.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/hash.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/io.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/load.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/object.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/parse.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/proc.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/process.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/random.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/range.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/rational.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/re.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/select.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/signal.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/string.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/struct.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/thread.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/time.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/variable.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/vm.h
+bigzero.o: $(hdrdir)/ruby/internal/interpreter.h
+bigzero.o: $(hdrdir)/ruby/internal/iterator.h
+bigzero.o: $(hdrdir)/ruby/internal/memory.h
+bigzero.o: $(hdrdir)/ruby/internal/method.h
+bigzero.o: $(hdrdir)/ruby/internal/module.h
+bigzero.o: $(hdrdir)/ruby/internal/newobj.h
+bigzero.o: $(hdrdir)/ruby/internal/rgengc.h
+bigzero.o: $(hdrdir)/ruby/internal/scan_args.h
+bigzero.o: $(hdrdir)/ruby/internal/special_consts.h
+bigzero.o: $(hdrdir)/ruby/internal/static_assert.h
+bigzero.o: $(hdrdir)/ruby/internal/stdalign.h
+bigzero.o: $(hdrdir)/ruby/internal/stdbool.h
+bigzero.o: $(hdrdir)/ruby/internal/symbol.h
+bigzero.o: $(hdrdir)/ruby/internal/token_paste.h
+bigzero.o: $(hdrdir)/ruby/internal/value.h
+bigzero.o: $(hdrdir)/ruby/internal/value_type.h
+bigzero.o: $(hdrdir)/ruby/internal/variable.h
+bigzero.o: $(hdrdir)/ruby/internal/warning_push.h
+bigzero.o: $(hdrdir)/ruby/internal/xmalloc.h
+bigzero.o: $(hdrdir)/ruby/assert.h
bigzero.o: $(hdrdir)/ruby/backward.h
+bigzero.o: $(hdrdir)/ruby/backward/2/assume.h
+bigzero.o: $(hdrdir)/ruby/backward/2/attributes.h
+bigzero.o: $(hdrdir)/ruby/backward/2/bool.h
+bigzero.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bigzero.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bigzero.o: $(hdrdir)/ruby/backward/2/limits.h
+bigzero.o: $(hdrdir)/ruby/backward/2/long_long.h
+bigzero.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bigzero.o: $(hdrdir)/ruby/backward/2/stdarg.h
bigzero.o: $(hdrdir)/ruby/defines.h
-bigzero.o: $(hdrdir)/ruby/encoding.h
bigzero.o: $(hdrdir)/ruby/intern.h
-bigzero.o: $(hdrdir)/ruby/io.h
bigzero.o: $(hdrdir)/ruby/missing.h
-bigzero.o: $(hdrdir)/ruby/onigmo.h
-bigzero.o: $(hdrdir)/ruby/oniguruma.h
bigzero.o: $(hdrdir)/ruby/ruby.h
bigzero.o: $(hdrdir)/ruby/st.h
bigzero.o: $(hdrdir)/ruby/subst.h
-bigzero.o: $(top_srcdir)/include/ruby.h
bigzero.o: $(top_srcdir)/internal.h
+bigzero.o: $(top_srcdir)/internal/bignum.h
bigzero.o: bigzero.c
div.o: $(RUBY_EXTCONF_H)
div.o: $(arch_hdrdir)/ruby/config.h
+div.o: $(hdrdir)/ruby.h
+div.o: $(hdrdir)/ruby/internal/anyargs.h
+div.o: $(hdrdir)/ruby/internal/arithmetic.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+div.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+div.o: $(hdrdir)/ruby/internal/assume.h
+div.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+div.o: $(hdrdir)/ruby/internal/attr/artificial.h
+div.o: $(hdrdir)/ruby/internal/attr/cold.h
+div.o: $(hdrdir)/ruby/internal/attr/const.h
+div.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+div.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+div.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+div.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+div.o: $(hdrdir)/ruby/internal/attr/error.h
+div.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+div.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+div.o: $(hdrdir)/ruby/internal/attr/format.h
+div.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+div.o: $(hdrdir)/ruby/internal/attr/noalias.h
+div.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+div.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+div.o: $(hdrdir)/ruby/internal/attr/noinline.h
+div.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+div.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+div.o: $(hdrdir)/ruby/internal/attr/pure.h
+div.o: $(hdrdir)/ruby/internal/attr/restrict.h
+div.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+div.o: $(hdrdir)/ruby/internal/attr/warning.h
+div.o: $(hdrdir)/ruby/internal/attr/weakref.h
+div.o: $(hdrdir)/ruby/internal/cast.h
+div.o: $(hdrdir)/ruby/internal/compiler_is.h
+div.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+div.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+div.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+div.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+div.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+div.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+div.o: $(hdrdir)/ruby/internal/compiler_since.h
+div.o: $(hdrdir)/ruby/internal/config.h
+div.o: $(hdrdir)/ruby/internal/constant_p.h
+div.o: $(hdrdir)/ruby/internal/core.h
+div.o: $(hdrdir)/ruby/internal/core/rarray.h
+div.o: $(hdrdir)/ruby/internal/core/rbasic.h
+div.o: $(hdrdir)/ruby/internal/core/rbignum.h
+div.o: $(hdrdir)/ruby/internal/core/rclass.h
+div.o: $(hdrdir)/ruby/internal/core/rdata.h
+div.o: $(hdrdir)/ruby/internal/core/rfile.h
+div.o: $(hdrdir)/ruby/internal/core/rhash.h
+div.o: $(hdrdir)/ruby/internal/core/robject.h
+div.o: $(hdrdir)/ruby/internal/core/rregexp.h
+div.o: $(hdrdir)/ruby/internal/core/rstring.h
+div.o: $(hdrdir)/ruby/internal/core/rstruct.h
+div.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+div.o: $(hdrdir)/ruby/internal/ctype.h
+div.o: $(hdrdir)/ruby/internal/dllexport.h
+div.o: $(hdrdir)/ruby/internal/dosish.h
+div.o: $(hdrdir)/ruby/internal/error.h
+div.o: $(hdrdir)/ruby/internal/eval.h
+div.o: $(hdrdir)/ruby/internal/event.h
+div.o: $(hdrdir)/ruby/internal/fl_type.h
+div.o: $(hdrdir)/ruby/internal/gc.h
+div.o: $(hdrdir)/ruby/internal/glob.h
+div.o: $(hdrdir)/ruby/internal/globals.h
+div.o: $(hdrdir)/ruby/internal/has/attribute.h
+div.o: $(hdrdir)/ruby/internal/has/builtin.h
+div.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+div.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+div.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+div.o: $(hdrdir)/ruby/internal/has/extension.h
+div.o: $(hdrdir)/ruby/internal/has/feature.h
+div.o: $(hdrdir)/ruby/internal/has/warning.h
+div.o: $(hdrdir)/ruby/internal/intern/array.h
+div.o: $(hdrdir)/ruby/internal/intern/bignum.h
+div.o: $(hdrdir)/ruby/internal/intern/class.h
+div.o: $(hdrdir)/ruby/internal/intern/compar.h
+div.o: $(hdrdir)/ruby/internal/intern/complex.h
+div.o: $(hdrdir)/ruby/internal/intern/cont.h
+div.o: $(hdrdir)/ruby/internal/intern/dir.h
+div.o: $(hdrdir)/ruby/internal/intern/enum.h
+div.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+div.o: $(hdrdir)/ruby/internal/intern/error.h
+div.o: $(hdrdir)/ruby/internal/intern/eval.h
+div.o: $(hdrdir)/ruby/internal/intern/file.h
+div.o: $(hdrdir)/ruby/internal/intern/gc.h
+div.o: $(hdrdir)/ruby/internal/intern/hash.h
+div.o: $(hdrdir)/ruby/internal/intern/io.h
+div.o: $(hdrdir)/ruby/internal/intern/load.h
+div.o: $(hdrdir)/ruby/internal/intern/marshal.h
+div.o: $(hdrdir)/ruby/internal/intern/numeric.h
+div.o: $(hdrdir)/ruby/internal/intern/object.h
+div.o: $(hdrdir)/ruby/internal/intern/parse.h
+div.o: $(hdrdir)/ruby/internal/intern/proc.h
+div.o: $(hdrdir)/ruby/internal/intern/process.h
+div.o: $(hdrdir)/ruby/internal/intern/random.h
+div.o: $(hdrdir)/ruby/internal/intern/range.h
+div.o: $(hdrdir)/ruby/internal/intern/rational.h
+div.o: $(hdrdir)/ruby/internal/intern/re.h
+div.o: $(hdrdir)/ruby/internal/intern/ruby.h
+div.o: $(hdrdir)/ruby/internal/intern/select.h
+div.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+div.o: $(hdrdir)/ruby/internal/intern/signal.h
+div.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+div.o: $(hdrdir)/ruby/internal/intern/string.h
+div.o: $(hdrdir)/ruby/internal/intern/struct.h
+div.o: $(hdrdir)/ruby/internal/intern/thread.h
+div.o: $(hdrdir)/ruby/internal/intern/time.h
+div.o: $(hdrdir)/ruby/internal/intern/variable.h
+div.o: $(hdrdir)/ruby/internal/intern/vm.h
+div.o: $(hdrdir)/ruby/internal/interpreter.h
+div.o: $(hdrdir)/ruby/internal/iterator.h
+div.o: $(hdrdir)/ruby/internal/memory.h
+div.o: $(hdrdir)/ruby/internal/method.h
+div.o: $(hdrdir)/ruby/internal/module.h
+div.o: $(hdrdir)/ruby/internal/newobj.h
+div.o: $(hdrdir)/ruby/internal/rgengc.h
+div.o: $(hdrdir)/ruby/internal/scan_args.h
+div.o: $(hdrdir)/ruby/internal/special_consts.h
+div.o: $(hdrdir)/ruby/internal/static_assert.h
+div.o: $(hdrdir)/ruby/internal/stdalign.h
+div.o: $(hdrdir)/ruby/internal/stdbool.h
+div.o: $(hdrdir)/ruby/internal/symbol.h
+div.o: $(hdrdir)/ruby/internal/token_paste.h
+div.o: $(hdrdir)/ruby/internal/value.h
+div.o: $(hdrdir)/ruby/internal/value_type.h
+div.o: $(hdrdir)/ruby/internal/variable.h
+div.o: $(hdrdir)/ruby/internal/warning_push.h
+div.o: $(hdrdir)/ruby/internal/xmalloc.h
+div.o: $(hdrdir)/ruby/assert.h
div.o: $(hdrdir)/ruby/backward.h
+div.o: $(hdrdir)/ruby/backward/2/assume.h
+div.o: $(hdrdir)/ruby/backward/2/attributes.h
+div.o: $(hdrdir)/ruby/backward/2/bool.h
+div.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+div.o: $(hdrdir)/ruby/backward/2/inttypes.h
+div.o: $(hdrdir)/ruby/backward/2/limits.h
+div.o: $(hdrdir)/ruby/backward/2/long_long.h
+div.o: $(hdrdir)/ruby/backward/2/stdalign.h
+div.o: $(hdrdir)/ruby/backward/2/stdarg.h
div.o: $(hdrdir)/ruby/defines.h
-div.o: $(hdrdir)/ruby/encoding.h
div.o: $(hdrdir)/ruby/intern.h
-div.o: $(hdrdir)/ruby/io.h
div.o: $(hdrdir)/ruby/missing.h
-div.o: $(hdrdir)/ruby/onigmo.h
-div.o: $(hdrdir)/ruby/oniguruma.h
div.o: $(hdrdir)/ruby/ruby.h
div.o: $(hdrdir)/ruby/st.h
div.o: $(hdrdir)/ruby/subst.h
-div.o: $(top_srcdir)/include/ruby.h
div.o: $(top_srcdir)/internal.h
+div.o: $(top_srcdir)/internal/bignum.h
div.o: div.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
intpack.o: $(RUBY_EXTCONF_H)
intpack.o: $(arch_hdrdir)/ruby/config.h
+intpack.o: $(hdrdir)/ruby.h
+intpack.o: $(hdrdir)/ruby/internal/anyargs.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+intpack.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+intpack.o: $(hdrdir)/ruby/internal/assume.h
+intpack.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+intpack.o: $(hdrdir)/ruby/internal/attr/artificial.h
+intpack.o: $(hdrdir)/ruby/internal/attr/cold.h
+intpack.o: $(hdrdir)/ruby/internal/attr/const.h
+intpack.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+intpack.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+intpack.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+intpack.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+intpack.o: $(hdrdir)/ruby/internal/attr/error.h
+intpack.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+intpack.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+intpack.o: $(hdrdir)/ruby/internal/attr/format.h
+intpack.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+intpack.o: $(hdrdir)/ruby/internal/attr/noalias.h
+intpack.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+intpack.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+intpack.o: $(hdrdir)/ruby/internal/attr/noinline.h
+intpack.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+intpack.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+intpack.o: $(hdrdir)/ruby/internal/attr/pure.h
+intpack.o: $(hdrdir)/ruby/internal/attr/restrict.h
+intpack.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+intpack.o: $(hdrdir)/ruby/internal/attr/warning.h
+intpack.o: $(hdrdir)/ruby/internal/attr/weakref.h
+intpack.o: $(hdrdir)/ruby/internal/cast.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_is.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+intpack.o: $(hdrdir)/ruby/internal/compiler_since.h
+intpack.o: $(hdrdir)/ruby/internal/config.h
+intpack.o: $(hdrdir)/ruby/internal/constant_p.h
+intpack.o: $(hdrdir)/ruby/internal/core.h
+intpack.o: $(hdrdir)/ruby/internal/core/rarray.h
+intpack.o: $(hdrdir)/ruby/internal/core/rbasic.h
+intpack.o: $(hdrdir)/ruby/internal/core/rbignum.h
+intpack.o: $(hdrdir)/ruby/internal/core/rclass.h
+intpack.o: $(hdrdir)/ruby/internal/core/rdata.h
+intpack.o: $(hdrdir)/ruby/internal/core/rfile.h
+intpack.o: $(hdrdir)/ruby/internal/core/rhash.h
+intpack.o: $(hdrdir)/ruby/internal/core/robject.h
+intpack.o: $(hdrdir)/ruby/internal/core/rregexp.h
+intpack.o: $(hdrdir)/ruby/internal/core/rstring.h
+intpack.o: $(hdrdir)/ruby/internal/core/rstruct.h
+intpack.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+intpack.o: $(hdrdir)/ruby/internal/ctype.h
+intpack.o: $(hdrdir)/ruby/internal/dllexport.h
+intpack.o: $(hdrdir)/ruby/internal/dosish.h
+intpack.o: $(hdrdir)/ruby/internal/error.h
+intpack.o: $(hdrdir)/ruby/internal/eval.h
+intpack.o: $(hdrdir)/ruby/internal/event.h
+intpack.o: $(hdrdir)/ruby/internal/fl_type.h
+intpack.o: $(hdrdir)/ruby/internal/gc.h
+intpack.o: $(hdrdir)/ruby/internal/glob.h
+intpack.o: $(hdrdir)/ruby/internal/globals.h
+intpack.o: $(hdrdir)/ruby/internal/has/attribute.h
+intpack.o: $(hdrdir)/ruby/internal/has/builtin.h
+intpack.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+intpack.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+intpack.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+intpack.o: $(hdrdir)/ruby/internal/has/extension.h
+intpack.o: $(hdrdir)/ruby/internal/has/feature.h
+intpack.o: $(hdrdir)/ruby/internal/has/warning.h
+intpack.o: $(hdrdir)/ruby/internal/intern/array.h
+intpack.o: $(hdrdir)/ruby/internal/intern/bignum.h
+intpack.o: $(hdrdir)/ruby/internal/intern/class.h
+intpack.o: $(hdrdir)/ruby/internal/intern/compar.h
+intpack.o: $(hdrdir)/ruby/internal/intern/complex.h
+intpack.o: $(hdrdir)/ruby/internal/intern/cont.h
+intpack.o: $(hdrdir)/ruby/internal/intern/dir.h
+intpack.o: $(hdrdir)/ruby/internal/intern/enum.h
+intpack.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+intpack.o: $(hdrdir)/ruby/internal/intern/error.h
+intpack.o: $(hdrdir)/ruby/internal/intern/eval.h
+intpack.o: $(hdrdir)/ruby/internal/intern/file.h
+intpack.o: $(hdrdir)/ruby/internal/intern/gc.h
+intpack.o: $(hdrdir)/ruby/internal/intern/hash.h
+intpack.o: $(hdrdir)/ruby/internal/intern/io.h
+intpack.o: $(hdrdir)/ruby/internal/intern/load.h
+intpack.o: $(hdrdir)/ruby/internal/intern/marshal.h
+intpack.o: $(hdrdir)/ruby/internal/intern/numeric.h
+intpack.o: $(hdrdir)/ruby/internal/intern/object.h
+intpack.o: $(hdrdir)/ruby/internal/intern/parse.h
+intpack.o: $(hdrdir)/ruby/internal/intern/proc.h
+intpack.o: $(hdrdir)/ruby/internal/intern/process.h
+intpack.o: $(hdrdir)/ruby/internal/intern/random.h
+intpack.o: $(hdrdir)/ruby/internal/intern/range.h
+intpack.o: $(hdrdir)/ruby/internal/intern/rational.h
+intpack.o: $(hdrdir)/ruby/internal/intern/re.h
+intpack.o: $(hdrdir)/ruby/internal/intern/ruby.h
+intpack.o: $(hdrdir)/ruby/internal/intern/select.h
+intpack.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+intpack.o: $(hdrdir)/ruby/internal/intern/signal.h
+intpack.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+intpack.o: $(hdrdir)/ruby/internal/intern/string.h
+intpack.o: $(hdrdir)/ruby/internal/intern/struct.h
+intpack.o: $(hdrdir)/ruby/internal/intern/thread.h
+intpack.o: $(hdrdir)/ruby/internal/intern/time.h
+intpack.o: $(hdrdir)/ruby/internal/intern/variable.h
+intpack.o: $(hdrdir)/ruby/internal/intern/vm.h
+intpack.o: $(hdrdir)/ruby/internal/interpreter.h
+intpack.o: $(hdrdir)/ruby/internal/iterator.h
+intpack.o: $(hdrdir)/ruby/internal/memory.h
+intpack.o: $(hdrdir)/ruby/internal/method.h
+intpack.o: $(hdrdir)/ruby/internal/module.h
+intpack.o: $(hdrdir)/ruby/internal/newobj.h
+intpack.o: $(hdrdir)/ruby/internal/rgengc.h
+intpack.o: $(hdrdir)/ruby/internal/scan_args.h
+intpack.o: $(hdrdir)/ruby/internal/special_consts.h
+intpack.o: $(hdrdir)/ruby/internal/static_assert.h
+intpack.o: $(hdrdir)/ruby/internal/stdalign.h
+intpack.o: $(hdrdir)/ruby/internal/stdbool.h
+intpack.o: $(hdrdir)/ruby/internal/symbol.h
+intpack.o: $(hdrdir)/ruby/internal/token_paste.h
+intpack.o: $(hdrdir)/ruby/internal/value.h
+intpack.o: $(hdrdir)/ruby/internal/value_type.h
+intpack.o: $(hdrdir)/ruby/internal/variable.h
+intpack.o: $(hdrdir)/ruby/internal/warning_push.h
+intpack.o: $(hdrdir)/ruby/internal/xmalloc.h
+intpack.o: $(hdrdir)/ruby/assert.h
intpack.o: $(hdrdir)/ruby/backward.h
+intpack.o: $(hdrdir)/ruby/backward/2/assume.h
+intpack.o: $(hdrdir)/ruby/backward/2/attributes.h
+intpack.o: $(hdrdir)/ruby/backward/2/bool.h
+intpack.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+intpack.o: $(hdrdir)/ruby/backward/2/inttypes.h
+intpack.o: $(hdrdir)/ruby/backward/2/limits.h
+intpack.o: $(hdrdir)/ruby/backward/2/long_long.h
+intpack.o: $(hdrdir)/ruby/backward/2/stdalign.h
+intpack.o: $(hdrdir)/ruby/backward/2/stdarg.h
intpack.o: $(hdrdir)/ruby/defines.h
-intpack.o: $(hdrdir)/ruby/encoding.h
intpack.o: $(hdrdir)/ruby/intern.h
-intpack.o: $(hdrdir)/ruby/io.h
intpack.o: $(hdrdir)/ruby/missing.h
-intpack.o: $(hdrdir)/ruby/onigmo.h
-intpack.o: $(hdrdir)/ruby/oniguruma.h
intpack.o: $(hdrdir)/ruby/ruby.h
intpack.o: $(hdrdir)/ruby/st.h
intpack.o: $(hdrdir)/ruby/subst.h
-intpack.o: $(top_srcdir)/include/ruby.h
intpack.o: $(top_srcdir)/internal.h
+intpack.o: $(top_srcdir)/internal/bignum.h
intpack.o: intpack.c
mul.o: $(RUBY_EXTCONF_H)
mul.o: $(arch_hdrdir)/ruby/config.h
+mul.o: $(hdrdir)/ruby.h
+mul.o: $(hdrdir)/ruby/internal/anyargs.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+mul.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+mul.o: $(hdrdir)/ruby/internal/assume.h
+mul.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+mul.o: $(hdrdir)/ruby/internal/attr/artificial.h
+mul.o: $(hdrdir)/ruby/internal/attr/cold.h
+mul.o: $(hdrdir)/ruby/internal/attr/const.h
+mul.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+mul.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+mul.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+mul.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+mul.o: $(hdrdir)/ruby/internal/attr/error.h
+mul.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+mul.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+mul.o: $(hdrdir)/ruby/internal/attr/format.h
+mul.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+mul.o: $(hdrdir)/ruby/internal/attr/noalias.h
+mul.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+mul.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+mul.o: $(hdrdir)/ruby/internal/attr/noinline.h
+mul.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+mul.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+mul.o: $(hdrdir)/ruby/internal/attr/pure.h
+mul.o: $(hdrdir)/ruby/internal/attr/restrict.h
+mul.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+mul.o: $(hdrdir)/ruby/internal/attr/warning.h
+mul.o: $(hdrdir)/ruby/internal/attr/weakref.h
+mul.o: $(hdrdir)/ruby/internal/cast.h
+mul.o: $(hdrdir)/ruby/internal/compiler_is.h
+mul.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+mul.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+mul.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+mul.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+mul.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+mul.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+mul.o: $(hdrdir)/ruby/internal/compiler_since.h
+mul.o: $(hdrdir)/ruby/internal/config.h
+mul.o: $(hdrdir)/ruby/internal/constant_p.h
+mul.o: $(hdrdir)/ruby/internal/core.h
+mul.o: $(hdrdir)/ruby/internal/core/rarray.h
+mul.o: $(hdrdir)/ruby/internal/core/rbasic.h
+mul.o: $(hdrdir)/ruby/internal/core/rbignum.h
+mul.o: $(hdrdir)/ruby/internal/core/rclass.h
+mul.o: $(hdrdir)/ruby/internal/core/rdata.h
+mul.o: $(hdrdir)/ruby/internal/core/rfile.h
+mul.o: $(hdrdir)/ruby/internal/core/rhash.h
+mul.o: $(hdrdir)/ruby/internal/core/robject.h
+mul.o: $(hdrdir)/ruby/internal/core/rregexp.h
+mul.o: $(hdrdir)/ruby/internal/core/rstring.h
+mul.o: $(hdrdir)/ruby/internal/core/rstruct.h
+mul.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+mul.o: $(hdrdir)/ruby/internal/ctype.h
+mul.o: $(hdrdir)/ruby/internal/dllexport.h
+mul.o: $(hdrdir)/ruby/internal/dosish.h
+mul.o: $(hdrdir)/ruby/internal/error.h
+mul.o: $(hdrdir)/ruby/internal/eval.h
+mul.o: $(hdrdir)/ruby/internal/event.h
+mul.o: $(hdrdir)/ruby/internal/fl_type.h
+mul.o: $(hdrdir)/ruby/internal/gc.h
+mul.o: $(hdrdir)/ruby/internal/glob.h
+mul.o: $(hdrdir)/ruby/internal/globals.h
+mul.o: $(hdrdir)/ruby/internal/has/attribute.h
+mul.o: $(hdrdir)/ruby/internal/has/builtin.h
+mul.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+mul.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+mul.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+mul.o: $(hdrdir)/ruby/internal/has/extension.h
+mul.o: $(hdrdir)/ruby/internal/has/feature.h
+mul.o: $(hdrdir)/ruby/internal/has/warning.h
+mul.o: $(hdrdir)/ruby/internal/intern/array.h
+mul.o: $(hdrdir)/ruby/internal/intern/bignum.h
+mul.o: $(hdrdir)/ruby/internal/intern/class.h
+mul.o: $(hdrdir)/ruby/internal/intern/compar.h
+mul.o: $(hdrdir)/ruby/internal/intern/complex.h
+mul.o: $(hdrdir)/ruby/internal/intern/cont.h
+mul.o: $(hdrdir)/ruby/internal/intern/dir.h
+mul.o: $(hdrdir)/ruby/internal/intern/enum.h
+mul.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+mul.o: $(hdrdir)/ruby/internal/intern/error.h
+mul.o: $(hdrdir)/ruby/internal/intern/eval.h
+mul.o: $(hdrdir)/ruby/internal/intern/file.h
+mul.o: $(hdrdir)/ruby/internal/intern/gc.h
+mul.o: $(hdrdir)/ruby/internal/intern/hash.h
+mul.o: $(hdrdir)/ruby/internal/intern/io.h
+mul.o: $(hdrdir)/ruby/internal/intern/load.h
+mul.o: $(hdrdir)/ruby/internal/intern/marshal.h
+mul.o: $(hdrdir)/ruby/internal/intern/numeric.h
+mul.o: $(hdrdir)/ruby/internal/intern/object.h
+mul.o: $(hdrdir)/ruby/internal/intern/parse.h
+mul.o: $(hdrdir)/ruby/internal/intern/proc.h
+mul.o: $(hdrdir)/ruby/internal/intern/process.h
+mul.o: $(hdrdir)/ruby/internal/intern/random.h
+mul.o: $(hdrdir)/ruby/internal/intern/range.h
+mul.o: $(hdrdir)/ruby/internal/intern/rational.h
+mul.o: $(hdrdir)/ruby/internal/intern/re.h
+mul.o: $(hdrdir)/ruby/internal/intern/ruby.h
+mul.o: $(hdrdir)/ruby/internal/intern/select.h
+mul.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+mul.o: $(hdrdir)/ruby/internal/intern/signal.h
+mul.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+mul.o: $(hdrdir)/ruby/internal/intern/string.h
+mul.o: $(hdrdir)/ruby/internal/intern/struct.h
+mul.o: $(hdrdir)/ruby/internal/intern/thread.h
+mul.o: $(hdrdir)/ruby/internal/intern/time.h
+mul.o: $(hdrdir)/ruby/internal/intern/variable.h
+mul.o: $(hdrdir)/ruby/internal/intern/vm.h
+mul.o: $(hdrdir)/ruby/internal/interpreter.h
+mul.o: $(hdrdir)/ruby/internal/iterator.h
+mul.o: $(hdrdir)/ruby/internal/memory.h
+mul.o: $(hdrdir)/ruby/internal/method.h
+mul.o: $(hdrdir)/ruby/internal/module.h
+mul.o: $(hdrdir)/ruby/internal/newobj.h
+mul.o: $(hdrdir)/ruby/internal/rgengc.h
+mul.o: $(hdrdir)/ruby/internal/scan_args.h
+mul.o: $(hdrdir)/ruby/internal/special_consts.h
+mul.o: $(hdrdir)/ruby/internal/static_assert.h
+mul.o: $(hdrdir)/ruby/internal/stdalign.h
+mul.o: $(hdrdir)/ruby/internal/stdbool.h
+mul.o: $(hdrdir)/ruby/internal/symbol.h
+mul.o: $(hdrdir)/ruby/internal/token_paste.h
+mul.o: $(hdrdir)/ruby/internal/value.h
+mul.o: $(hdrdir)/ruby/internal/value_type.h
+mul.o: $(hdrdir)/ruby/internal/variable.h
+mul.o: $(hdrdir)/ruby/internal/warning_push.h
+mul.o: $(hdrdir)/ruby/internal/xmalloc.h
+mul.o: $(hdrdir)/ruby/assert.h
mul.o: $(hdrdir)/ruby/backward.h
+mul.o: $(hdrdir)/ruby/backward/2/assume.h
+mul.o: $(hdrdir)/ruby/backward/2/attributes.h
+mul.o: $(hdrdir)/ruby/backward/2/bool.h
+mul.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+mul.o: $(hdrdir)/ruby/backward/2/inttypes.h
+mul.o: $(hdrdir)/ruby/backward/2/limits.h
+mul.o: $(hdrdir)/ruby/backward/2/long_long.h
+mul.o: $(hdrdir)/ruby/backward/2/stdalign.h
+mul.o: $(hdrdir)/ruby/backward/2/stdarg.h
mul.o: $(hdrdir)/ruby/defines.h
-mul.o: $(hdrdir)/ruby/encoding.h
mul.o: $(hdrdir)/ruby/intern.h
-mul.o: $(hdrdir)/ruby/io.h
mul.o: $(hdrdir)/ruby/missing.h
-mul.o: $(hdrdir)/ruby/onigmo.h
-mul.o: $(hdrdir)/ruby/oniguruma.h
mul.o: $(hdrdir)/ruby/ruby.h
mul.o: $(hdrdir)/ruby/st.h
mul.o: $(hdrdir)/ruby/subst.h
-mul.o: $(top_srcdir)/include/ruby.h
mul.o: $(top_srcdir)/internal.h
+mul.o: $(top_srcdir)/internal/bignum.h
mul.o: mul.c
str2big.o: $(RUBY_EXTCONF_H)
str2big.o: $(arch_hdrdir)/ruby/config.h
+str2big.o: $(hdrdir)/ruby.h
+str2big.o: $(hdrdir)/ruby/internal/anyargs.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+str2big.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+str2big.o: $(hdrdir)/ruby/internal/assume.h
+str2big.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+str2big.o: $(hdrdir)/ruby/internal/attr/artificial.h
+str2big.o: $(hdrdir)/ruby/internal/attr/cold.h
+str2big.o: $(hdrdir)/ruby/internal/attr/const.h
+str2big.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+str2big.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+str2big.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+str2big.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+str2big.o: $(hdrdir)/ruby/internal/attr/error.h
+str2big.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+str2big.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+str2big.o: $(hdrdir)/ruby/internal/attr/format.h
+str2big.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+str2big.o: $(hdrdir)/ruby/internal/attr/noalias.h
+str2big.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+str2big.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+str2big.o: $(hdrdir)/ruby/internal/attr/noinline.h
+str2big.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+str2big.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+str2big.o: $(hdrdir)/ruby/internal/attr/pure.h
+str2big.o: $(hdrdir)/ruby/internal/attr/restrict.h
+str2big.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+str2big.o: $(hdrdir)/ruby/internal/attr/warning.h
+str2big.o: $(hdrdir)/ruby/internal/attr/weakref.h
+str2big.o: $(hdrdir)/ruby/internal/cast.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_is.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+str2big.o: $(hdrdir)/ruby/internal/compiler_since.h
+str2big.o: $(hdrdir)/ruby/internal/config.h
+str2big.o: $(hdrdir)/ruby/internal/constant_p.h
+str2big.o: $(hdrdir)/ruby/internal/core.h
+str2big.o: $(hdrdir)/ruby/internal/core/rarray.h
+str2big.o: $(hdrdir)/ruby/internal/core/rbasic.h
+str2big.o: $(hdrdir)/ruby/internal/core/rbignum.h
+str2big.o: $(hdrdir)/ruby/internal/core/rclass.h
+str2big.o: $(hdrdir)/ruby/internal/core/rdata.h
+str2big.o: $(hdrdir)/ruby/internal/core/rfile.h
+str2big.o: $(hdrdir)/ruby/internal/core/rhash.h
+str2big.o: $(hdrdir)/ruby/internal/core/robject.h
+str2big.o: $(hdrdir)/ruby/internal/core/rregexp.h
+str2big.o: $(hdrdir)/ruby/internal/core/rstring.h
+str2big.o: $(hdrdir)/ruby/internal/core/rstruct.h
+str2big.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+str2big.o: $(hdrdir)/ruby/internal/ctype.h
+str2big.o: $(hdrdir)/ruby/internal/dllexport.h
+str2big.o: $(hdrdir)/ruby/internal/dosish.h
+str2big.o: $(hdrdir)/ruby/internal/error.h
+str2big.o: $(hdrdir)/ruby/internal/eval.h
+str2big.o: $(hdrdir)/ruby/internal/event.h
+str2big.o: $(hdrdir)/ruby/internal/fl_type.h
+str2big.o: $(hdrdir)/ruby/internal/gc.h
+str2big.o: $(hdrdir)/ruby/internal/glob.h
+str2big.o: $(hdrdir)/ruby/internal/globals.h
+str2big.o: $(hdrdir)/ruby/internal/has/attribute.h
+str2big.o: $(hdrdir)/ruby/internal/has/builtin.h
+str2big.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+str2big.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+str2big.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+str2big.o: $(hdrdir)/ruby/internal/has/extension.h
+str2big.o: $(hdrdir)/ruby/internal/has/feature.h
+str2big.o: $(hdrdir)/ruby/internal/has/warning.h
+str2big.o: $(hdrdir)/ruby/internal/intern/array.h
+str2big.o: $(hdrdir)/ruby/internal/intern/bignum.h
+str2big.o: $(hdrdir)/ruby/internal/intern/class.h
+str2big.o: $(hdrdir)/ruby/internal/intern/compar.h
+str2big.o: $(hdrdir)/ruby/internal/intern/complex.h
+str2big.o: $(hdrdir)/ruby/internal/intern/cont.h
+str2big.o: $(hdrdir)/ruby/internal/intern/dir.h
+str2big.o: $(hdrdir)/ruby/internal/intern/enum.h
+str2big.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+str2big.o: $(hdrdir)/ruby/internal/intern/error.h
+str2big.o: $(hdrdir)/ruby/internal/intern/eval.h
+str2big.o: $(hdrdir)/ruby/internal/intern/file.h
+str2big.o: $(hdrdir)/ruby/internal/intern/gc.h
+str2big.o: $(hdrdir)/ruby/internal/intern/hash.h
+str2big.o: $(hdrdir)/ruby/internal/intern/io.h
+str2big.o: $(hdrdir)/ruby/internal/intern/load.h
+str2big.o: $(hdrdir)/ruby/internal/intern/marshal.h
+str2big.o: $(hdrdir)/ruby/internal/intern/numeric.h
+str2big.o: $(hdrdir)/ruby/internal/intern/object.h
+str2big.o: $(hdrdir)/ruby/internal/intern/parse.h
+str2big.o: $(hdrdir)/ruby/internal/intern/proc.h
+str2big.o: $(hdrdir)/ruby/internal/intern/process.h
+str2big.o: $(hdrdir)/ruby/internal/intern/random.h
+str2big.o: $(hdrdir)/ruby/internal/intern/range.h
+str2big.o: $(hdrdir)/ruby/internal/intern/rational.h
+str2big.o: $(hdrdir)/ruby/internal/intern/re.h
+str2big.o: $(hdrdir)/ruby/internal/intern/ruby.h
+str2big.o: $(hdrdir)/ruby/internal/intern/select.h
+str2big.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+str2big.o: $(hdrdir)/ruby/internal/intern/signal.h
+str2big.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+str2big.o: $(hdrdir)/ruby/internal/intern/string.h
+str2big.o: $(hdrdir)/ruby/internal/intern/struct.h
+str2big.o: $(hdrdir)/ruby/internal/intern/thread.h
+str2big.o: $(hdrdir)/ruby/internal/intern/time.h
+str2big.o: $(hdrdir)/ruby/internal/intern/variable.h
+str2big.o: $(hdrdir)/ruby/internal/intern/vm.h
+str2big.o: $(hdrdir)/ruby/internal/interpreter.h
+str2big.o: $(hdrdir)/ruby/internal/iterator.h
+str2big.o: $(hdrdir)/ruby/internal/memory.h
+str2big.o: $(hdrdir)/ruby/internal/method.h
+str2big.o: $(hdrdir)/ruby/internal/module.h
+str2big.o: $(hdrdir)/ruby/internal/newobj.h
+str2big.o: $(hdrdir)/ruby/internal/rgengc.h
+str2big.o: $(hdrdir)/ruby/internal/scan_args.h
+str2big.o: $(hdrdir)/ruby/internal/special_consts.h
+str2big.o: $(hdrdir)/ruby/internal/static_assert.h
+str2big.o: $(hdrdir)/ruby/internal/stdalign.h
+str2big.o: $(hdrdir)/ruby/internal/stdbool.h
+str2big.o: $(hdrdir)/ruby/internal/symbol.h
+str2big.o: $(hdrdir)/ruby/internal/token_paste.h
+str2big.o: $(hdrdir)/ruby/internal/value.h
+str2big.o: $(hdrdir)/ruby/internal/value_type.h
+str2big.o: $(hdrdir)/ruby/internal/variable.h
+str2big.o: $(hdrdir)/ruby/internal/warning_push.h
+str2big.o: $(hdrdir)/ruby/internal/xmalloc.h
+str2big.o: $(hdrdir)/ruby/assert.h
str2big.o: $(hdrdir)/ruby/backward.h
+str2big.o: $(hdrdir)/ruby/backward/2/assume.h
+str2big.o: $(hdrdir)/ruby/backward/2/attributes.h
+str2big.o: $(hdrdir)/ruby/backward/2/bool.h
+str2big.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+str2big.o: $(hdrdir)/ruby/backward/2/inttypes.h
+str2big.o: $(hdrdir)/ruby/backward/2/limits.h
+str2big.o: $(hdrdir)/ruby/backward/2/long_long.h
+str2big.o: $(hdrdir)/ruby/backward/2/stdalign.h
+str2big.o: $(hdrdir)/ruby/backward/2/stdarg.h
str2big.o: $(hdrdir)/ruby/defines.h
-str2big.o: $(hdrdir)/ruby/encoding.h
str2big.o: $(hdrdir)/ruby/intern.h
-str2big.o: $(hdrdir)/ruby/io.h
str2big.o: $(hdrdir)/ruby/missing.h
-str2big.o: $(hdrdir)/ruby/onigmo.h
-str2big.o: $(hdrdir)/ruby/oniguruma.h
str2big.o: $(hdrdir)/ruby/ruby.h
str2big.o: $(hdrdir)/ruby/st.h
str2big.o: $(hdrdir)/ruby/subst.h
-str2big.o: $(top_srcdir)/include/ruby.h
str2big.o: $(top_srcdir)/internal.h
+str2big.o: $(top_srcdir)/internal/bignum.h
str2big.o: str2big.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/bignum/div.c b/ext/-test-/bignum/div.c
index a1db21dc30..2be0d2d62a 100644
--- a/ext/-test-/bignum/div.c
+++ b/ext/-test-/bignum/div.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/bignum.h"
static VALUE
big(VALUE x)
diff --git a/ext/-test-/bignum/intpack.c b/ext/-test-/bignum/intpack.c
index 2d19442cf2..698362f96f 100644
--- a/ext/-test-/bignum/intpack.c
+++ b/ext/-test-/bignum/intpack.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/bignum.h"
static VALUE
rb_integer_pack_raw_m(VALUE val, VALUE buf, VALUE numwords_arg, VALUE wordsize_arg, VALUE nails, VALUE flags)
diff --git a/ext/-test-/bignum/mul.c b/ext/-test-/bignum/mul.c
index b922f34437..1b6eb911bd 100644
--- a/ext/-test-/bignum/mul.c
+++ b/ext/-test-/bignum/mul.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/bignum.h"
static VALUE
big(VALUE x)
diff --git a/ext/-test-/bignum/str2big.c b/ext/-test-/bignum/str2big.c
index bc79ef0329..7dd2da9a07 100644
--- a/ext/-test-/bignum/str2big.c
+++ b/ext/-test-/bignum/str2big.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/bignum.h"
static VALUE
str2big_poweroftwo(VALUE str, VALUE vbase, VALUE badcheck)
diff --git a/ext/-test-/bug-14834/bug-14384.c b/ext/-test-/bug-14834/bug-14384.c
new file mode 100644
index 0000000000..3a16a2d222
--- /dev/null
+++ b/ext/-test-/bug-14834/bug-14384.c
@@ -0,0 +1,39 @@
+#include <ruby/ruby.h>
+#include <ruby/debug.h>
+
+#ifndef MAYBE_UNUSED
+# define MAYBE_UNUSED(x) x
+#endif
+
+static NOINLINE(VALUE f(VALUE));
+static NOINLINE(void g(VALUE, void*));
+extern NOINLINE(void Init_bug_14384(void));
+
+void
+Init_bug_14834(void)
+{
+ VALUE q = rb_define_module("Bug");
+ rb_define_module_function(q, "bug_14834", f, 0);
+}
+
+VALUE
+f(VALUE q)
+{
+ int w[] = { 0, 1024 };
+ VALUE e = rb_tracepoint_new(Qnil, RUBY_INTERNAL_EVENT_NEWOBJ, g, w);
+
+ rb_tracepoint_enable(e);
+ return rb_ensure(rb_yield, q, rb_tracepoint_disable, e);
+}
+
+void
+g(MAYBE_UNUSED(VALUE q), void* w)
+{
+ const int *e = (const int *)w;
+ const int r = *e++;
+ const int t = *e++;
+ VALUE *y = ALLOCA_N(VALUE, t);
+ int *u = ALLOCA_N(int, t);
+
+ rb_profile_frames(r, t, y, u);
+}
diff --git a/ext/-test-/bug-14834/depend b/ext/-test-/bug-14834/depend
new file mode 100644
index 0000000000..dce5a8e5c5
--- /dev/null
+++ b/ext/-test-/bug-14834/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+bug-14384.o: $(RUBY_EXTCONF_H)
+bug-14384.o: $(arch_hdrdir)/ruby/config.h
+bug-14384.o: $(hdrdir)/ruby/internal/anyargs.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bug-14384.o: $(hdrdir)/ruby/internal/assume.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/cold.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/const.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/error.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/format.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/pure.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/warning.h
+bug-14384.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bug-14384.o: $(hdrdir)/ruby/internal/cast.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_is.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bug-14384.o: $(hdrdir)/ruby/internal/compiler_since.h
+bug-14384.o: $(hdrdir)/ruby/internal/config.h
+bug-14384.o: $(hdrdir)/ruby/internal/constant_p.h
+bug-14384.o: $(hdrdir)/ruby/internal/core.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rarray.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rclass.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rdata.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rfile.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rhash.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/robject.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rstring.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bug-14384.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bug-14384.o: $(hdrdir)/ruby/internal/ctype.h
+bug-14384.o: $(hdrdir)/ruby/internal/dllexport.h
+bug-14384.o: $(hdrdir)/ruby/internal/dosish.h
+bug-14384.o: $(hdrdir)/ruby/internal/error.h
+bug-14384.o: $(hdrdir)/ruby/internal/eval.h
+bug-14384.o: $(hdrdir)/ruby/internal/event.h
+bug-14384.o: $(hdrdir)/ruby/internal/fl_type.h
+bug-14384.o: $(hdrdir)/ruby/internal/gc.h
+bug-14384.o: $(hdrdir)/ruby/internal/glob.h
+bug-14384.o: $(hdrdir)/ruby/internal/globals.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/attribute.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/builtin.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/extension.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/feature.h
+bug-14384.o: $(hdrdir)/ruby/internal/has/warning.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/array.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/class.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/compar.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/complex.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/cont.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/dir.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/enum.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/error.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/eval.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/file.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/gc.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/hash.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/io.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/load.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/object.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/parse.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/proc.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/process.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/random.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/range.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/rational.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/re.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/select.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/signal.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/string.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/struct.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/thread.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/time.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/variable.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/vm.h
+bug-14384.o: $(hdrdir)/ruby/internal/interpreter.h
+bug-14384.o: $(hdrdir)/ruby/internal/iterator.h
+bug-14384.o: $(hdrdir)/ruby/internal/memory.h
+bug-14384.o: $(hdrdir)/ruby/internal/method.h
+bug-14384.o: $(hdrdir)/ruby/internal/module.h
+bug-14384.o: $(hdrdir)/ruby/internal/newobj.h
+bug-14384.o: $(hdrdir)/ruby/internal/rgengc.h
+bug-14384.o: $(hdrdir)/ruby/internal/scan_args.h
+bug-14384.o: $(hdrdir)/ruby/internal/special_consts.h
+bug-14384.o: $(hdrdir)/ruby/internal/static_assert.h
+bug-14384.o: $(hdrdir)/ruby/internal/stdalign.h
+bug-14384.o: $(hdrdir)/ruby/internal/stdbool.h
+bug-14384.o: $(hdrdir)/ruby/internal/symbol.h
+bug-14384.o: $(hdrdir)/ruby/internal/token_paste.h
+bug-14384.o: $(hdrdir)/ruby/internal/value.h
+bug-14384.o: $(hdrdir)/ruby/internal/value_type.h
+bug-14384.o: $(hdrdir)/ruby/internal/variable.h
+bug-14384.o: $(hdrdir)/ruby/internal/warning_push.h
+bug-14384.o: $(hdrdir)/ruby/internal/xmalloc.h
+bug-14384.o: $(hdrdir)/ruby/assert.h
+bug-14384.o: $(hdrdir)/ruby/backward.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/assume.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/attributes.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/bool.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/limits.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/long_long.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bug-14384.o: $(hdrdir)/ruby/backward/2/stdarg.h
+bug-14384.o: $(hdrdir)/ruby/debug.h
+bug-14384.o: $(hdrdir)/ruby/defines.h
+bug-14384.o: $(hdrdir)/ruby/intern.h
+bug-14384.o: $(hdrdir)/ruby/missing.h
+bug-14384.o: $(hdrdir)/ruby/ruby.h
+bug-14384.o: $(hdrdir)/ruby/st.h
+bug-14384.o: $(hdrdir)/ruby/subst.h
+bug-14384.o: bug-14384.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/bug-14834/extconf.rb b/ext/-test-/bug-14834/extconf.rb
new file mode 100644
index 0000000000..e8f3f1f437
--- /dev/null
+++ b/ext/-test-/bug-14834/extconf.rb
@@ -0,0 +1,2 @@
+# frozen_string_literal: true
+create_makefile("-test-/bug_14834")
diff --git a/ext/-test-/bug-3571/bug.c b/ext/-test-/bug-3571/bug.c
index a64f054740..dd3c85cd79 100644
--- a/ext/-test-/bug-3571/bug.c
+++ b/ext/-test-/bug-3571/bug.c
@@ -8,7 +8,7 @@ bug_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
}
static VALUE
-bug_start(VALUE self, VALUE hash)
+bug_start(VALUE self)
{
VALUE ary = rb_ary_new3(1, Qnil);
rb_block_call(ary, rb_intern("map"), 0, 0, bug_i, self);
diff --git a/ext/-test-/bug-3571/depend b/ext/-test-/bug-3571/depend
new file mode 100644
index 0000000000..a21935558d
--- /dev/null
+++ b/ext/-test-/bug-3571/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+bug.o: $(RUBY_EXTCONF_H)
+bug.o: $(arch_hdrdir)/ruby/config.h
+bug.o: $(hdrdir)/ruby.h
+bug.o: $(hdrdir)/ruby/internal/anyargs.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bug.o: $(hdrdir)/ruby/internal/assume.h
+bug.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bug.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bug.o: $(hdrdir)/ruby/internal/attr/cold.h
+bug.o: $(hdrdir)/ruby/internal/attr/const.h
+bug.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bug.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bug.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bug.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bug.o: $(hdrdir)/ruby/internal/attr/error.h
+bug.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bug.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bug.o: $(hdrdir)/ruby/internal/attr/format.h
+bug.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bug.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bug.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bug.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bug.o: $(hdrdir)/ruby/internal/attr/pure.h
+bug.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bug.o: $(hdrdir)/ruby/internal/attr/warning.h
+bug.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bug.o: $(hdrdir)/ruby/internal/cast.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bug.o: $(hdrdir)/ruby/internal/compiler_since.h
+bug.o: $(hdrdir)/ruby/internal/config.h
+bug.o: $(hdrdir)/ruby/internal/constant_p.h
+bug.o: $(hdrdir)/ruby/internal/core.h
+bug.o: $(hdrdir)/ruby/internal/core/rarray.h
+bug.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bug.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bug.o: $(hdrdir)/ruby/internal/core/rclass.h
+bug.o: $(hdrdir)/ruby/internal/core/rdata.h
+bug.o: $(hdrdir)/ruby/internal/core/rfile.h
+bug.o: $(hdrdir)/ruby/internal/core/rhash.h
+bug.o: $(hdrdir)/ruby/internal/core/robject.h
+bug.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bug.o: $(hdrdir)/ruby/internal/core/rstring.h
+bug.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bug.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bug.o: $(hdrdir)/ruby/internal/ctype.h
+bug.o: $(hdrdir)/ruby/internal/dllexport.h
+bug.o: $(hdrdir)/ruby/internal/dosish.h
+bug.o: $(hdrdir)/ruby/internal/error.h
+bug.o: $(hdrdir)/ruby/internal/eval.h
+bug.o: $(hdrdir)/ruby/internal/event.h
+bug.o: $(hdrdir)/ruby/internal/fl_type.h
+bug.o: $(hdrdir)/ruby/internal/gc.h
+bug.o: $(hdrdir)/ruby/internal/glob.h
+bug.o: $(hdrdir)/ruby/internal/globals.h
+bug.o: $(hdrdir)/ruby/internal/has/attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/builtin.h
+bug.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/extension.h
+bug.o: $(hdrdir)/ruby/internal/has/feature.h
+bug.o: $(hdrdir)/ruby/internal/has/warning.h
+bug.o: $(hdrdir)/ruby/internal/intern/array.h
+bug.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bug.o: $(hdrdir)/ruby/internal/intern/class.h
+bug.o: $(hdrdir)/ruby/internal/intern/compar.h
+bug.o: $(hdrdir)/ruby/internal/intern/complex.h
+bug.o: $(hdrdir)/ruby/internal/intern/cont.h
+bug.o: $(hdrdir)/ruby/internal/intern/dir.h
+bug.o: $(hdrdir)/ruby/internal/intern/enum.h
+bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bug.o: $(hdrdir)/ruby/internal/intern/error.h
+bug.o: $(hdrdir)/ruby/internal/intern/eval.h
+bug.o: $(hdrdir)/ruby/internal/intern/file.h
+bug.o: $(hdrdir)/ruby/internal/intern/gc.h
+bug.o: $(hdrdir)/ruby/internal/intern/hash.h
+bug.o: $(hdrdir)/ruby/internal/intern/io.h
+bug.o: $(hdrdir)/ruby/internal/intern/load.h
+bug.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bug.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bug.o: $(hdrdir)/ruby/internal/intern/object.h
+bug.o: $(hdrdir)/ruby/internal/intern/parse.h
+bug.o: $(hdrdir)/ruby/internal/intern/proc.h
+bug.o: $(hdrdir)/ruby/internal/intern/process.h
+bug.o: $(hdrdir)/ruby/internal/intern/random.h
+bug.o: $(hdrdir)/ruby/internal/intern/range.h
+bug.o: $(hdrdir)/ruby/internal/intern/rational.h
+bug.o: $(hdrdir)/ruby/internal/intern/re.h
+bug.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bug.o: $(hdrdir)/ruby/internal/intern/select.h
+bug.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bug.o: $(hdrdir)/ruby/internal/intern/signal.h
+bug.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bug.o: $(hdrdir)/ruby/internal/intern/string.h
+bug.o: $(hdrdir)/ruby/internal/intern/struct.h
+bug.o: $(hdrdir)/ruby/internal/intern/thread.h
+bug.o: $(hdrdir)/ruby/internal/intern/time.h
+bug.o: $(hdrdir)/ruby/internal/intern/variable.h
+bug.o: $(hdrdir)/ruby/internal/intern/vm.h
+bug.o: $(hdrdir)/ruby/internal/interpreter.h
+bug.o: $(hdrdir)/ruby/internal/iterator.h
+bug.o: $(hdrdir)/ruby/internal/memory.h
+bug.o: $(hdrdir)/ruby/internal/method.h
+bug.o: $(hdrdir)/ruby/internal/module.h
+bug.o: $(hdrdir)/ruby/internal/newobj.h
+bug.o: $(hdrdir)/ruby/internal/rgengc.h
+bug.o: $(hdrdir)/ruby/internal/scan_args.h
+bug.o: $(hdrdir)/ruby/internal/special_consts.h
+bug.o: $(hdrdir)/ruby/internal/static_assert.h
+bug.o: $(hdrdir)/ruby/internal/stdalign.h
+bug.o: $(hdrdir)/ruby/internal/stdbool.h
+bug.o: $(hdrdir)/ruby/internal/symbol.h
+bug.o: $(hdrdir)/ruby/internal/token_paste.h
+bug.o: $(hdrdir)/ruby/internal/value.h
+bug.o: $(hdrdir)/ruby/internal/value_type.h
+bug.o: $(hdrdir)/ruby/internal/variable.h
+bug.o: $(hdrdir)/ruby/internal/warning_push.h
+bug.o: $(hdrdir)/ruby/internal/xmalloc.h
+bug.o: $(hdrdir)/ruby/assert.h
+bug.o: $(hdrdir)/ruby/backward.h
+bug.o: $(hdrdir)/ruby/backward/2/assume.h
+bug.o: $(hdrdir)/ruby/backward/2/attributes.h
+bug.o: $(hdrdir)/ruby/backward/2/bool.h
+bug.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bug.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bug.o: $(hdrdir)/ruby/backward/2/limits.h
+bug.o: $(hdrdir)/ruby/backward/2/long_long.h
+bug.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bug.o: $(hdrdir)/ruby/backward/2/stdarg.h
+bug.o: $(hdrdir)/ruby/defines.h
+bug.o: $(hdrdir)/ruby/intern.h
+bug.o: $(hdrdir)/ruby/missing.h
+bug.o: $(hdrdir)/ruby/ruby.h
+bug.o: $(hdrdir)/ruby/st.h
+bug.o: $(hdrdir)/ruby/subst.h
+bug.o: bug.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/bug-5832/depend b/ext/-test-/bug-5832/depend
new file mode 100644
index 0000000000..a21935558d
--- /dev/null
+++ b/ext/-test-/bug-5832/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+bug.o: $(RUBY_EXTCONF_H)
+bug.o: $(arch_hdrdir)/ruby/config.h
+bug.o: $(hdrdir)/ruby.h
+bug.o: $(hdrdir)/ruby/internal/anyargs.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bug.o: $(hdrdir)/ruby/internal/assume.h
+bug.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bug.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bug.o: $(hdrdir)/ruby/internal/attr/cold.h
+bug.o: $(hdrdir)/ruby/internal/attr/const.h
+bug.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bug.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bug.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bug.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bug.o: $(hdrdir)/ruby/internal/attr/error.h
+bug.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bug.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bug.o: $(hdrdir)/ruby/internal/attr/format.h
+bug.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bug.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bug.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bug.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bug.o: $(hdrdir)/ruby/internal/attr/pure.h
+bug.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bug.o: $(hdrdir)/ruby/internal/attr/warning.h
+bug.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bug.o: $(hdrdir)/ruby/internal/cast.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bug.o: $(hdrdir)/ruby/internal/compiler_since.h
+bug.o: $(hdrdir)/ruby/internal/config.h
+bug.o: $(hdrdir)/ruby/internal/constant_p.h
+bug.o: $(hdrdir)/ruby/internal/core.h
+bug.o: $(hdrdir)/ruby/internal/core/rarray.h
+bug.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bug.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bug.o: $(hdrdir)/ruby/internal/core/rclass.h
+bug.o: $(hdrdir)/ruby/internal/core/rdata.h
+bug.o: $(hdrdir)/ruby/internal/core/rfile.h
+bug.o: $(hdrdir)/ruby/internal/core/rhash.h
+bug.o: $(hdrdir)/ruby/internal/core/robject.h
+bug.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bug.o: $(hdrdir)/ruby/internal/core/rstring.h
+bug.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bug.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bug.o: $(hdrdir)/ruby/internal/ctype.h
+bug.o: $(hdrdir)/ruby/internal/dllexport.h
+bug.o: $(hdrdir)/ruby/internal/dosish.h
+bug.o: $(hdrdir)/ruby/internal/error.h
+bug.o: $(hdrdir)/ruby/internal/eval.h
+bug.o: $(hdrdir)/ruby/internal/event.h
+bug.o: $(hdrdir)/ruby/internal/fl_type.h
+bug.o: $(hdrdir)/ruby/internal/gc.h
+bug.o: $(hdrdir)/ruby/internal/glob.h
+bug.o: $(hdrdir)/ruby/internal/globals.h
+bug.o: $(hdrdir)/ruby/internal/has/attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/builtin.h
+bug.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/extension.h
+bug.o: $(hdrdir)/ruby/internal/has/feature.h
+bug.o: $(hdrdir)/ruby/internal/has/warning.h
+bug.o: $(hdrdir)/ruby/internal/intern/array.h
+bug.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bug.o: $(hdrdir)/ruby/internal/intern/class.h
+bug.o: $(hdrdir)/ruby/internal/intern/compar.h
+bug.o: $(hdrdir)/ruby/internal/intern/complex.h
+bug.o: $(hdrdir)/ruby/internal/intern/cont.h
+bug.o: $(hdrdir)/ruby/internal/intern/dir.h
+bug.o: $(hdrdir)/ruby/internal/intern/enum.h
+bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bug.o: $(hdrdir)/ruby/internal/intern/error.h
+bug.o: $(hdrdir)/ruby/internal/intern/eval.h
+bug.o: $(hdrdir)/ruby/internal/intern/file.h
+bug.o: $(hdrdir)/ruby/internal/intern/gc.h
+bug.o: $(hdrdir)/ruby/internal/intern/hash.h
+bug.o: $(hdrdir)/ruby/internal/intern/io.h
+bug.o: $(hdrdir)/ruby/internal/intern/load.h
+bug.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bug.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bug.o: $(hdrdir)/ruby/internal/intern/object.h
+bug.o: $(hdrdir)/ruby/internal/intern/parse.h
+bug.o: $(hdrdir)/ruby/internal/intern/proc.h
+bug.o: $(hdrdir)/ruby/internal/intern/process.h
+bug.o: $(hdrdir)/ruby/internal/intern/random.h
+bug.o: $(hdrdir)/ruby/internal/intern/range.h
+bug.o: $(hdrdir)/ruby/internal/intern/rational.h
+bug.o: $(hdrdir)/ruby/internal/intern/re.h
+bug.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bug.o: $(hdrdir)/ruby/internal/intern/select.h
+bug.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bug.o: $(hdrdir)/ruby/internal/intern/signal.h
+bug.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bug.o: $(hdrdir)/ruby/internal/intern/string.h
+bug.o: $(hdrdir)/ruby/internal/intern/struct.h
+bug.o: $(hdrdir)/ruby/internal/intern/thread.h
+bug.o: $(hdrdir)/ruby/internal/intern/time.h
+bug.o: $(hdrdir)/ruby/internal/intern/variable.h
+bug.o: $(hdrdir)/ruby/internal/intern/vm.h
+bug.o: $(hdrdir)/ruby/internal/interpreter.h
+bug.o: $(hdrdir)/ruby/internal/iterator.h
+bug.o: $(hdrdir)/ruby/internal/memory.h
+bug.o: $(hdrdir)/ruby/internal/method.h
+bug.o: $(hdrdir)/ruby/internal/module.h
+bug.o: $(hdrdir)/ruby/internal/newobj.h
+bug.o: $(hdrdir)/ruby/internal/rgengc.h
+bug.o: $(hdrdir)/ruby/internal/scan_args.h
+bug.o: $(hdrdir)/ruby/internal/special_consts.h
+bug.o: $(hdrdir)/ruby/internal/static_assert.h
+bug.o: $(hdrdir)/ruby/internal/stdalign.h
+bug.o: $(hdrdir)/ruby/internal/stdbool.h
+bug.o: $(hdrdir)/ruby/internal/symbol.h
+bug.o: $(hdrdir)/ruby/internal/token_paste.h
+bug.o: $(hdrdir)/ruby/internal/value.h
+bug.o: $(hdrdir)/ruby/internal/value_type.h
+bug.o: $(hdrdir)/ruby/internal/variable.h
+bug.o: $(hdrdir)/ruby/internal/warning_push.h
+bug.o: $(hdrdir)/ruby/internal/xmalloc.h
+bug.o: $(hdrdir)/ruby/assert.h
+bug.o: $(hdrdir)/ruby/backward.h
+bug.o: $(hdrdir)/ruby/backward/2/assume.h
+bug.o: $(hdrdir)/ruby/backward/2/attributes.h
+bug.o: $(hdrdir)/ruby/backward/2/bool.h
+bug.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bug.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bug.o: $(hdrdir)/ruby/backward/2/limits.h
+bug.o: $(hdrdir)/ruby/backward/2/long_long.h
+bug.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bug.o: $(hdrdir)/ruby/backward/2/stdarg.h
+bug.o: $(hdrdir)/ruby/defines.h
+bug.o: $(hdrdir)/ruby/intern.h
+bug.o: $(hdrdir)/ruby/missing.h
+bug.o: $(hdrdir)/ruby/ruby.h
+bug.o: $(hdrdir)/ruby/st.h
+bug.o: $(hdrdir)/ruby/subst.h
+bug.o: bug.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/bug_reporter/depend b/ext/-test-/bug_reporter/depend
new file mode 100644
index 0000000000..f49b6147e6
--- /dev/null
+++ b/ext/-test-/bug_reporter/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+bug_reporter.o: $(RUBY_EXTCONF_H)
+bug_reporter.o: $(arch_hdrdir)/ruby/config.h
+bug_reporter.o: $(hdrdir)/ruby.h
+bug_reporter.o: $(hdrdir)/ruby/internal/anyargs.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bug_reporter.o: $(hdrdir)/ruby/internal/assume.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/cold.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/const.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/error.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/format.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/pure.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/warning.h
+bug_reporter.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bug_reporter.o: $(hdrdir)/ruby/internal/cast.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_is.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bug_reporter.o: $(hdrdir)/ruby/internal/compiler_since.h
+bug_reporter.o: $(hdrdir)/ruby/internal/config.h
+bug_reporter.o: $(hdrdir)/ruby/internal/constant_p.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rarray.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rclass.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rdata.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rfile.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rhash.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/robject.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rstring.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bug_reporter.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bug_reporter.o: $(hdrdir)/ruby/internal/ctype.h
+bug_reporter.o: $(hdrdir)/ruby/internal/dllexport.h
+bug_reporter.o: $(hdrdir)/ruby/internal/dosish.h
+bug_reporter.o: $(hdrdir)/ruby/internal/error.h
+bug_reporter.o: $(hdrdir)/ruby/internal/eval.h
+bug_reporter.o: $(hdrdir)/ruby/internal/event.h
+bug_reporter.o: $(hdrdir)/ruby/internal/fl_type.h
+bug_reporter.o: $(hdrdir)/ruby/internal/gc.h
+bug_reporter.o: $(hdrdir)/ruby/internal/glob.h
+bug_reporter.o: $(hdrdir)/ruby/internal/globals.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/attribute.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/builtin.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/extension.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/feature.h
+bug_reporter.o: $(hdrdir)/ruby/internal/has/warning.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/array.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/class.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/compar.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/complex.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/cont.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/dir.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/enum.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/error.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/eval.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/file.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/gc.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/hash.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/io.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/load.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/object.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/parse.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/proc.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/process.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/random.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/range.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/rational.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/re.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/select.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/signal.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/string.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/struct.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/thread.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/time.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/variable.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/vm.h
+bug_reporter.o: $(hdrdir)/ruby/internal/interpreter.h
+bug_reporter.o: $(hdrdir)/ruby/internal/iterator.h
+bug_reporter.o: $(hdrdir)/ruby/internal/memory.h
+bug_reporter.o: $(hdrdir)/ruby/internal/method.h
+bug_reporter.o: $(hdrdir)/ruby/internal/module.h
+bug_reporter.o: $(hdrdir)/ruby/internal/newobj.h
+bug_reporter.o: $(hdrdir)/ruby/internal/rgengc.h
+bug_reporter.o: $(hdrdir)/ruby/internal/scan_args.h
+bug_reporter.o: $(hdrdir)/ruby/internal/special_consts.h
+bug_reporter.o: $(hdrdir)/ruby/internal/static_assert.h
+bug_reporter.o: $(hdrdir)/ruby/internal/stdalign.h
+bug_reporter.o: $(hdrdir)/ruby/internal/stdbool.h
+bug_reporter.o: $(hdrdir)/ruby/internal/symbol.h
+bug_reporter.o: $(hdrdir)/ruby/internal/token_paste.h
+bug_reporter.o: $(hdrdir)/ruby/internal/value.h
+bug_reporter.o: $(hdrdir)/ruby/internal/value_type.h
+bug_reporter.o: $(hdrdir)/ruby/internal/variable.h
+bug_reporter.o: $(hdrdir)/ruby/internal/warning_push.h
+bug_reporter.o: $(hdrdir)/ruby/internal/xmalloc.h
+bug_reporter.o: $(hdrdir)/ruby/assert.h
+bug_reporter.o: $(hdrdir)/ruby/backward.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/assume.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/attributes.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/bool.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/limits.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/long_long.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bug_reporter.o: $(hdrdir)/ruby/backward/2/stdarg.h
+bug_reporter.o: $(hdrdir)/ruby/defines.h
+bug_reporter.o: $(hdrdir)/ruby/intern.h
+bug_reporter.o: $(hdrdir)/ruby/missing.h
+bug_reporter.o: $(hdrdir)/ruby/ruby.h
+bug_reporter.o: $(hdrdir)/ruby/st.h
+bug_reporter.o: $(hdrdir)/ruby/subst.h
+bug_reporter.o: bug_reporter.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/class/depend b/ext/-test-/class/depend
index 40f3d7ab6d..95199c5cf4 100644
--- a/ext/-test-/class/depend
+++ b/ext/-test-/class/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
class2name.o: $(RUBY_EXTCONF_H)
class2name.o: $(arch_hdrdir)/ruby/config.h
+class2name.o: $(hdrdir)/ruby/internal/anyargs.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+class2name.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+class2name.o: $(hdrdir)/ruby/internal/assume.h
+class2name.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+class2name.o: $(hdrdir)/ruby/internal/attr/artificial.h
+class2name.o: $(hdrdir)/ruby/internal/attr/cold.h
+class2name.o: $(hdrdir)/ruby/internal/attr/const.h
+class2name.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+class2name.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+class2name.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+class2name.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+class2name.o: $(hdrdir)/ruby/internal/attr/error.h
+class2name.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+class2name.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+class2name.o: $(hdrdir)/ruby/internal/attr/format.h
+class2name.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+class2name.o: $(hdrdir)/ruby/internal/attr/noalias.h
+class2name.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+class2name.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+class2name.o: $(hdrdir)/ruby/internal/attr/noinline.h
+class2name.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+class2name.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+class2name.o: $(hdrdir)/ruby/internal/attr/pure.h
+class2name.o: $(hdrdir)/ruby/internal/attr/restrict.h
+class2name.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+class2name.o: $(hdrdir)/ruby/internal/attr/warning.h
+class2name.o: $(hdrdir)/ruby/internal/attr/weakref.h
+class2name.o: $(hdrdir)/ruby/internal/cast.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_is.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+class2name.o: $(hdrdir)/ruby/internal/compiler_since.h
+class2name.o: $(hdrdir)/ruby/internal/config.h
+class2name.o: $(hdrdir)/ruby/internal/constant_p.h
+class2name.o: $(hdrdir)/ruby/internal/core.h
+class2name.o: $(hdrdir)/ruby/internal/core/rarray.h
+class2name.o: $(hdrdir)/ruby/internal/core/rbasic.h
+class2name.o: $(hdrdir)/ruby/internal/core/rbignum.h
+class2name.o: $(hdrdir)/ruby/internal/core/rclass.h
+class2name.o: $(hdrdir)/ruby/internal/core/rdata.h
+class2name.o: $(hdrdir)/ruby/internal/core/rfile.h
+class2name.o: $(hdrdir)/ruby/internal/core/rhash.h
+class2name.o: $(hdrdir)/ruby/internal/core/robject.h
+class2name.o: $(hdrdir)/ruby/internal/core/rregexp.h
+class2name.o: $(hdrdir)/ruby/internal/core/rstring.h
+class2name.o: $(hdrdir)/ruby/internal/core/rstruct.h
+class2name.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+class2name.o: $(hdrdir)/ruby/internal/ctype.h
+class2name.o: $(hdrdir)/ruby/internal/dllexport.h
+class2name.o: $(hdrdir)/ruby/internal/dosish.h
+class2name.o: $(hdrdir)/ruby/internal/error.h
+class2name.o: $(hdrdir)/ruby/internal/eval.h
+class2name.o: $(hdrdir)/ruby/internal/event.h
+class2name.o: $(hdrdir)/ruby/internal/fl_type.h
+class2name.o: $(hdrdir)/ruby/internal/gc.h
+class2name.o: $(hdrdir)/ruby/internal/glob.h
+class2name.o: $(hdrdir)/ruby/internal/globals.h
+class2name.o: $(hdrdir)/ruby/internal/has/attribute.h
+class2name.o: $(hdrdir)/ruby/internal/has/builtin.h
+class2name.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+class2name.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+class2name.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+class2name.o: $(hdrdir)/ruby/internal/has/extension.h
+class2name.o: $(hdrdir)/ruby/internal/has/feature.h
+class2name.o: $(hdrdir)/ruby/internal/has/warning.h
+class2name.o: $(hdrdir)/ruby/internal/intern/array.h
+class2name.o: $(hdrdir)/ruby/internal/intern/bignum.h
+class2name.o: $(hdrdir)/ruby/internal/intern/class.h
+class2name.o: $(hdrdir)/ruby/internal/intern/compar.h
+class2name.o: $(hdrdir)/ruby/internal/intern/complex.h
+class2name.o: $(hdrdir)/ruby/internal/intern/cont.h
+class2name.o: $(hdrdir)/ruby/internal/intern/dir.h
+class2name.o: $(hdrdir)/ruby/internal/intern/enum.h
+class2name.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+class2name.o: $(hdrdir)/ruby/internal/intern/error.h
+class2name.o: $(hdrdir)/ruby/internal/intern/eval.h
+class2name.o: $(hdrdir)/ruby/internal/intern/file.h
+class2name.o: $(hdrdir)/ruby/internal/intern/gc.h
+class2name.o: $(hdrdir)/ruby/internal/intern/hash.h
+class2name.o: $(hdrdir)/ruby/internal/intern/io.h
+class2name.o: $(hdrdir)/ruby/internal/intern/load.h
+class2name.o: $(hdrdir)/ruby/internal/intern/marshal.h
+class2name.o: $(hdrdir)/ruby/internal/intern/numeric.h
+class2name.o: $(hdrdir)/ruby/internal/intern/object.h
+class2name.o: $(hdrdir)/ruby/internal/intern/parse.h
+class2name.o: $(hdrdir)/ruby/internal/intern/proc.h
+class2name.o: $(hdrdir)/ruby/internal/intern/process.h
+class2name.o: $(hdrdir)/ruby/internal/intern/random.h
+class2name.o: $(hdrdir)/ruby/internal/intern/range.h
+class2name.o: $(hdrdir)/ruby/internal/intern/rational.h
+class2name.o: $(hdrdir)/ruby/internal/intern/re.h
+class2name.o: $(hdrdir)/ruby/internal/intern/ruby.h
+class2name.o: $(hdrdir)/ruby/internal/intern/select.h
+class2name.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+class2name.o: $(hdrdir)/ruby/internal/intern/signal.h
+class2name.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+class2name.o: $(hdrdir)/ruby/internal/intern/string.h
+class2name.o: $(hdrdir)/ruby/internal/intern/struct.h
+class2name.o: $(hdrdir)/ruby/internal/intern/thread.h
+class2name.o: $(hdrdir)/ruby/internal/intern/time.h
+class2name.o: $(hdrdir)/ruby/internal/intern/variable.h
+class2name.o: $(hdrdir)/ruby/internal/intern/vm.h
+class2name.o: $(hdrdir)/ruby/internal/interpreter.h
+class2name.o: $(hdrdir)/ruby/internal/iterator.h
+class2name.o: $(hdrdir)/ruby/internal/memory.h
+class2name.o: $(hdrdir)/ruby/internal/method.h
+class2name.o: $(hdrdir)/ruby/internal/module.h
+class2name.o: $(hdrdir)/ruby/internal/newobj.h
+class2name.o: $(hdrdir)/ruby/internal/rgengc.h
+class2name.o: $(hdrdir)/ruby/internal/scan_args.h
+class2name.o: $(hdrdir)/ruby/internal/special_consts.h
+class2name.o: $(hdrdir)/ruby/internal/static_assert.h
+class2name.o: $(hdrdir)/ruby/internal/stdalign.h
+class2name.o: $(hdrdir)/ruby/internal/stdbool.h
+class2name.o: $(hdrdir)/ruby/internal/symbol.h
+class2name.o: $(hdrdir)/ruby/internal/token_paste.h
+class2name.o: $(hdrdir)/ruby/internal/value.h
+class2name.o: $(hdrdir)/ruby/internal/value_type.h
+class2name.o: $(hdrdir)/ruby/internal/variable.h
+class2name.o: $(hdrdir)/ruby/internal/warning_push.h
+class2name.o: $(hdrdir)/ruby/internal/xmalloc.h
+class2name.o: $(hdrdir)/ruby/assert.h
class2name.o: $(hdrdir)/ruby/backward.h
+class2name.o: $(hdrdir)/ruby/backward/2/assume.h
+class2name.o: $(hdrdir)/ruby/backward/2/attributes.h
+class2name.o: $(hdrdir)/ruby/backward/2/bool.h
+class2name.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+class2name.o: $(hdrdir)/ruby/backward/2/inttypes.h
+class2name.o: $(hdrdir)/ruby/backward/2/limits.h
+class2name.o: $(hdrdir)/ruby/backward/2/long_long.h
+class2name.o: $(hdrdir)/ruby/backward/2/stdalign.h
+class2name.o: $(hdrdir)/ruby/backward/2/stdarg.h
class2name.o: $(hdrdir)/ruby/defines.h
class2name.o: $(hdrdir)/ruby/intern.h
class2name.o: $(hdrdir)/ruby/missing.h
@@ -11,13 +161,163 @@ class2name.o: $(hdrdir)/ruby/subst.h
class2name.o: class2name.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/cxxanyargs/cxxanyargs.cpp b/ext/-test-/cxxanyargs/cxxanyargs.cpp
new file mode 100644
index 0000000000..eded13e2ee
--- /dev/null
+++ b/ext/-test-/cxxanyargs/cxxanyargs.cpp
@@ -0,0 +1,961 @@
+#include <ruby/ruby.h>
+
+#if 0 // Warnings expected, should just suppress them
+
+#elif defined(_MSC_VER)
+#pragma warning(disable : 4996)
+
+#elif defined(__INTEL_COMPILER)
+#pragma warning(disable : 1786)
+
+#elif defined(__clang__)
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#elif defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+#elif defined(__SUNPRO_CC)
+#pragma error_messages (off,symdeprecated)
+
+#else
+// :FIXME: improve here for your compiler.
+
+#endif
+
+namespace test_rb_define_virtual_variable {
+ VALUE
+ getter(ID, VALUE *data)
+ {
+ return *data;
+ }
+
+ void
+ setter(VALUE val, ID, VALUE *data)
+ {
+ *data = val;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ rb_define_virtual_variable("test",
+ RUBY_METHOD_FUNC(getter),
+ reinterpret_cast<void(*)(ANYARGS)>(setter)); // old
+ rb_define_virtual_variable("test", getter, setter); // new
+
+#ifdef HAVE_NULLPTR
+ rb_define_virtual_variable("test", nullptr, reinterpret_cast<void(*)(ANYARGS)>(setter));
+ rb_define_virtual_variable("test", nullptr, setter);
+
+ rb_define_virtual_variable("test", RUBY_METHOD_FUNC(getter), nullptr);
+ rb_define_virtual_variable("test", getter, nullptr);
+
+ // It doesn't make any sense for both function pointers be nullptr at
+ // the same time.
+#endif
+
+ return self;
+ }
+}
+
+struct test_rb_define_hooked_variable {
+ static VALUE v;
+
+ static VALUE
+ getter(ID, VALUE *data)
+ {
+ return *data;
+ }
+
+ static void
+ setter(VALUE val, ID, VALUE *data)
+ {
+ *data = val;
+ }
+
+ static VALUE
+ test(VALUE self)
+ {
+ rb_define_hooked_variable("test", &v,
+ RUBY_METHOD_FUNC(getter),
+ reinterpret_cast<void(*)(ANYARGS)>(setter)); // old
+ rb_define_hooked_variable("test", &v, getter, setter); // new
+
+#ifdef HAVE_NULLPTR
+ rb_define_hooked_variable("test", &v, nullptr, reinterpret_cast<void(*)(ANYARGS)>(setter));
+ rb_define_hooked_variable("test", &v, nullptr, setter);
+
+ rb_define_hooked_variable("test", &v, RUBY_METHOD_FUNC(getter), nullptr);
+ rb_define_hooked_variable("test", &v, getter, nullptr);
+
+ // It doesn't make any sense for both function pointers be nullptr at
+ // the same time.
+#endif
+
+ return self;
+ }
+};
+VALUE test_rb_define_hooked_variable::v = Qundef;
+
+namespace test_rb_iterate {
+ VALUE
+ iter(VALUE self)
+ {
+ return rb_funcall(self, rb_intern("yield"), 0);
+ }
+
+ VALUE
+ block(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param))
+ {
+ return rb_funcall(arg, rb_intern("=="), 1, param);
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ rb_iterate(iter, self, nullptr, self);
+#endif
+
+ rb_iterate(iter, self, RUBY_METHOD_FUNC(block), self); // old
+ return rb_iterate(iter, self, block, self); // new
+ }
+}
+
+namespace test_rb_block_call {
+ VALUE
+ block(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param))
+ {
+ return rb_funcall(arg, rb_intern("=="), 1, param);
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ const ID mid = rb_intern("each");
+ const VALUE argv[] = { Qundef };
+
+#ifdef HAVE_NULLPTR
+ rb_block_call(self, mid, 0, argv, nullptr, self);
+#endif
+
+ rb_block_call(self, mid, 0, argv, RUBY_METHOD_FUNC(block), self); // old
+ return rb_block_call(self, mid, 0, argv, block, self); // new
+ }
+}
+
+namespace test_rb_rescue {
+ VALUE
+ begin(VALUE arg)
+ {
+ return arg;
+ }
+
+ VALUE
+ rescue(VALUE arg, VALUE exc)
+ {
+ return exc;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ rb_rescue(RUBY_METHOD_FUNC(begin), self, nullptr, self);
+ rb_rescue(begin, self, nullptr, self);
+#endif
+
+ rb_rescue(RUBY_METHOD_FUNC(begin), self, RUBY_METHOD_FUNC(rescue), self); // old
+ return rb_rescue(begin, self, rescue, self); // new
+ }
+}
+
+namespace test_rb_rescue2 {
+ VALUE
+ begin(VALUE arg)
+ {
+ return arg;
+ }
+
+ VALUE
+ rescue(VALUE arg, VALUE exc)
+ {
+ return exc;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ rb_rescue2(RUBY_METHOD_FUNC(begin), self, nullptr, self, rb_eStandardError, rb_eFatal, (VALUE)0);
+ rb_rescue2(begin, self, nullptr, self, rb_eStandardError, rb_eFatal, (VALUE)0);
+#endif
+
+ rb_rescue2(RUBY_METHOD_FUNC(begin), self, RUBY_METHOD_FUNC(rescue), self,
+ rb_eStandardError, rb_eFatal, (VALUE)0); // old
+ return rb_rescue2(begin, self, rescue, self, rb_eStandardError, rb_eFatal, (VALUE)0); // new
+ }
+}
+
+namespace test_rb_ensure {
+ VALUE
+ begin(VALUE arg)
+ {
+ return arg;
+ }
+
+ VALUE
+ ensure(VALUE arg)
+ {
+ return arg;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ rb_ensure(RUBY_METHOD_FUNC(begin), self, nullptr, self);
+ rb_ensure(begin, self, nullptr, self);
+#endif
+
+ rb_ensure(RUBY_METHOD_FUNC(begin), self, RUBY_METHOD_FUNC(ensure), self); // old
+ return rb_ensure(begin, self, ensure, self); // new
+ }
+}
+
+namespace test_rb_catch {
+ VALUE
+ catcher(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param))
+ {
+ return arg;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ static const char *zero = 0;
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a catcher.
+#endif
+
+ rb_catch(zero, RUBY_METHOD_FUNC(catcher), self); // old
+ return rb_catch(zero, catcher, self); // new
+ }
+}
+
+namespace test_rb_catch_obj {
+ VALUE
+ catcher(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param))
+ {
+ return arg;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a catcher.
+#endif
+
+ rb_catch_obj(self, RUBY_METHOD_FUNC(catcher), self); // old
+ return rb_catch_obj(self, catcher, self); // new
+ }
+}
+
+namespace test_rb_fiber_new {
+ VALUE
+ fiber(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param))
+ {
+ return arg;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a fiber.
+#endif
+
+ rb_fiber_new(RUBY_METHOD_FUNC(fiber), self); // old
+ return rb_fiber_new(fiber, self); // new
+ }
+}
+
+namespace test_rb_proc_new {
+ VALUE
+ proc(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param))
+ {
+ return arg;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a proc.
+#endif
+
+ rb_fiber_new(RUBY_METHOD_FUNC(proc), self); // old
+ return rb_fiber_new(proc, self); // new
+ }
+}
+
+struct test_rb_thread_create {
+ static VALUE v;
+
+ static VALUE
+ thread(void *ptr)
+ {
+ const VALUE *w = reinterpret_cast<const VALUE*>(ptr);
+ return *w;
+ }
+
+ static VALUE
+ test(VALUE self)
+ {
+ v = self;
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a thread.
+#endif
+
+ rb_thread_create(RUBY_METHOD_FUNC(thread), &v); // old
+ return rb_thread_create(thread, &v); // new
+ }
+};
+VALUE test_rb_thread_create::v = Qundef;
+
+namespace test_st_foreach {
+ static int
+ iter(st_data_t, st_data_t, st_data_t)
+ {
+ return ST_CONTINUE;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ st_data_t data = 0;
+ st_table *st = st_init_numtable();
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as an iterator.
+#endif
+
+ st_foreach(st, reinterpret_cast<int(*)(ANYARGS)>(iter), data); // old
+ st_foreach(st, iter, data); // new
+ return self;
+ }
+}
+
+namespace test_st_foreach_check {
+ static int
+ iter(st_data_t, st_data_t, st_data_t, int x)
+ {
+ return x ? ST_STOP : ST_CONTINUE;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ st_data_t data = 0;
+ st_table *st = st_init_numtable();
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as an iterator.
+#endif
+
+ st_foreach_check(st, reinterpret_cast<int(*)(ANYARGS)>(iter), data, data); // old
+ st_foreach_check(st, iter, data, data); // new
+ return self;
+ }
+}
+
+namespace test_st_foreach_safe {
+ static int
+ iter(st_data_t, st_data_t, st_data_t)
+ {
+ return ST_CONTINUE;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ st_data_t data = 0;
+ st_table *st = st_init_numtable();
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as an iterator.
+#endif
+
+ st_foreach_safe(st, reinterpret_cast<int(*)(ANYARGS)>(iter), data); // old
+ st_foreach_safe(st, iter, data); // new
+ return self;
+ }
+}
+
+namespace test_rb_hash_foreach {
+ static int
+ iter(VALUE, VALUE, VALUE)
+ {
+ return ST_CONTINUE;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ VALUE h = rb_hash_new();
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as an iterator.
+#endif
+
+ rb_hash_foreach(h, reinterpret_cast<int(*)(ANYARGS)>(iter), self); // old
+ rb_hash_foreach(h, iter, self); // new
+ return self;
+ }
+}
+
+namespace test_rb_ivar_foreach {
+ static int
+ iter(VALUE, VALUE, VALUE)
+ {
+ return ST_CONTINUE;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as an iterator.
+#endif
+
+ rb_ivar_foreach(self, reinterpret_cast<int(*)(ANYARGS)>(iter), self); // old
+ rb_ivar_foreach(self, iter, self); // new
+ return self;
+ }
+}
+
+namespace test_rb_define_method {
+ static VALUE
+ m1(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ m2(VALUE, VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ ma(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mv(int, VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mc(int, const VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ // No cast
+ rb_define_method(self, "m1", m1, 1);
+ rb_define_method(self, "m2", m2, 2);
+ rb_define_method(self, "ma", ma, -2);
+ rb_define_method(self, "mv", mv, -1);
+ rb_define_method(self, "mc", mc, -1);
+
+ // Cast by RUBY_METHOD_FUNC
+ rb_define_method(self, "m1", RUBY_METHOD_FUNC(m1), 1);
+ rb_define_method(self, "m2", RUBY_METHOD_FUNC(m2), 2);
+ rb_define_method(self, "ma", RUBY_METHOD_FUNC(ma), -2);
+ rb_define_method(self, "mv", RUBY_METHOD_FUNC(mv), -1);
+ rb_define_method(self, "mc", RUBY_METHOD_FUNC(mc), -1);
+
+ // Explicit cast instead of RUBY_METHOD_FUNC
+ rb_define_method(self, "m1", (VALUE (*)(...))(m1), 1);
+ rb_define_method(self, "m2", (VALUE (*)(...))(m2), 2);
+ rb_define_method(self, "ma", (VALUE (*)(...))(ma), -2);
+ rb_define_method(self, "mv", (VALUE (*)(...))(mv), -1);
+ rb_define_method(self, "mc", (VALUE (*)(...))(mc), -1);
+
+ // rb_f_notimplement
+ rb_define_method(self, "m1", rb_f_notimplement, 1);
+ rb_define_method(self, "m2", rb_f_notimplement, 2);
+ rb_define_method(self, "ma", rb_f_notimplement, -2);
+ rb_define_method(self, "mv", rb_f_notimplement, -1);
+ rb_define_method(self, "mc", rb_f_notimplement, -1);
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a method.
+#endif
+
+ return self;
+ }
+}
+
+namespace test_rb_define_method_id {
+ static VALUE
+ m1(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ m2(VALUE, VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ ma(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mv(int, VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mc(int, const VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ // No cast
+ rb_define_method_id(self, rb_intern("m1"), m1, 1);
+ rb_define_method_id(self, rb_intern("m2"), m2, 2);
+ rb_define_method_id(self, rb_intern("ma"), ma, -2);
+ rb_define_method_id(self, rb_intern("mv"), mv, -1);
+ rb_define_method_id(self, rb_intern("mc"), mc, -1);
+
+ // Cast by RUBY_METHOD_FUNC
+ rb_define_method_id(self, rb_intern("m1"), RUBY_METHOD_FUNC(m1), 1);
+ rb_define_method_id(self, rb_intern("m2"), RUBY_METHOD_FUNC(m2), 2);
+ rb_define_method_id(self, rb_intern("ma"), RUBY_METHOD_FUNC(ma), -2);
+ rb_define_method_id(self, rb_intern("mv"), RUBY_METHOD_FUNC(mv), -1);
+ rb_define_method_id(self, rb_intern("mc"), RUBY_METHOD_FUNC(mc), -1);
+
+ // Explicit cast instead of RUBY_METHOD_FUNC
+ rb_define_method_id(self, rb_intern("m1"), (VALUE (*)(...))(m1), 1);
+ rb_define_method_id(self, rb_intern("m2"), (VALUE (*)(...))(m2), 2);
+ rb_define_method_id(self, rb_intern("ma"), (VALUE (*)(...))(ma), -2);
+ rb_define_method_id(self, rb_intern("mv"), (VALUE (*)(...))(mv), -1);
+ rb_define_method_id(self, rb_intern("mc"), (VALUE (*)(...))(mc), -1);
+
+ // rb_f_notimplement
+ rb_define_method_id(self, rb_intern("m1"), rb_f_notimplement, 1);
+ rb_define_method_id(self, rb_intern("m2"), rb_f_notimplement, 2);
+ rb_define_method_id(self, rb_intern("ma"), rb_f_notimplement, -2);
+ rb_define_method_id(self, rb_intern("mv"), rb_f_notimplement, -1);
+ rb_define_method_id(self, rb_intern("mc"), rb_f_notimplement, -1);
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a method.
+#endif
+
+ return self;
+ }
+}
+
+namespace test_rb_define_module_function {
+ static VALUE
+ m1(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ m2(VALUE, VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ ma(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mv(int, VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mc(int, const VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ // No cast
+ rb_define_module_function(self, "m1", m1, 1);
+ rb_define_module_function(self, "m2", m2, 2);
+ rb_define_module_function(self, "ma", ma, -2);
+ rb_define_module_function(self, "mv", mv, -1);
+ rb_define_module_function(self, "mc", mc, -1);
+
+ // Cast by RUBY_METHOD_FUNC
+ rb_define_module_function(self, "m1", RUBY_METHOD_FUNC(m1), 1);
+ rb_define_module_function(self, "m2", RUBY_METHOD_FUNC(m2), 2);
+ rb_define_module_function(self, "ma", RUBY_METHOD_FUNC(ma), -2);
+ rb_define_module_function(self, "mv", RUBY_METHOD_FUNC(mv), -1);
+ rb_define_module_function(self, "mc", RUBY_METHOD_FUNC(mc), -1);
+
+ // Explicit cast instead of RUBY_METHOD_FUNC
+ rb_define_module_function(self, "m1", (VALUE (*)(...))(m1), 1);
+ rb_define_module_function(self, "m2", (VALUE (*)(...))(m2), 2);
+ rb_define_module_function(self, "ma", (VALUE (*)(...))(ma), -2);
+ rb_define_module_function(self, "mv", (VALUE (*)(...))(mv), -1);
+ rb_define_module_function(self, "mc", (VALUE (*)(...))(mc), -1);
+
+ // rb_f_notimplement
+ rb_define_module_function(self, "m1", rb_f_notimplement, 1);
+ rb_define_module_function(self, "m2", rb_f_notimplement, 2);
+ rb_define_module_function(self, "ma", rb_f_notimplement, -2);
+ rb_define_module_function(self, "mv", rb_f_notimplement, -1);
+ rb_define_module_function(self, "mc", rb_f_notimplement, -1);
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a method.
+#endif
+
+ return self;
+ }
+}
+
+namespace test_rb_define_singleton_method {
+ static VALUE
+ m1(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ m2(VALUE, VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ ma(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mv(int, VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mc(int, const VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ // No cast
+ rb_define_singleton_method(self, "m1", m1, 1);
+ rb_define_singleton_method(self, "m2", m2, 2);
+ rb_define_singleton_method(self, "ma", ma, -2);
+ rb_define_singleton_method(self, "mv", mv, -1);
+ rb_define_singleton_method(self, "mc", mc, -1);
+
+ // Cast by RUBY_METHOD_FUNC
+ rb_define_singleton_method(self, "m1", RUBY_METHOD_FUNC(m1), 1);
+ rb_define_singleton_method(self, "m2", RUBY_METHOD_FUNC(m2), 2);
+ rb_define_singleton_method(self, "ma", RUBY_METHOD_FUNC(ma), -2);
+ rb_define_singleton_method(self, "mv", RUBY_METHOD_FUNC(mv), -1);
+ rb_define_singleton_method(self, "mc", RUBY_METHOD_FUNC(mc), -1);
+
+ // Explicit cast instead of RUBY_METHOD_FUNC
+ rb_define_singleton_method(self, "m1", (VALUE (*)(...))(m1), 1);
+ rb_define_singleton_method(self, "m2", (VALUE (*)(...))(m2), 2);
+ rb_define_singleton_method(self, "ma", (VALUE (*)(...))(ma), -2);
+ rb_define_singleton_method(self, "mv", (VALUE (*)(...))(mv), -1);
+ rb_define_singleton_method(self, "mc", (VALUE (*)(...))(mc), -1);
+
+ // rb_f_notimplement
+ rb_define_singleton_method(self, "m1", rb_f_notimplement, 1);
+ rb_define_singleton_method(self, "m2", rb_f_notimplement, 2);
+ rb_define_singleton_method(self, "ma", rb_f_notimplement, -2);
+ rb_define_singleton_method(self, "mv", rb_f_notimplement, -1);
+ rb_define_singleton_method(self, "mc", rb_f_notimplement, -1);
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a method.
+#endif
+
+ return self;
+ }
+}
+
+namespace test_rb_define_protected_method {
+ static VALUE
+ m1(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ m2(VALUE, VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ ma(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mv(int, VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mc(int, const VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ // No cast
+ rb_define_protected_method(self, "m1", m1, 1);
+ rb_define_protected_method(self, "m2", m2, 2);
+ rb_define_protected_method(self, "ma", ma, -2);
+ rb_define_protected_method(self, "mv", mv, -1);
+ rb_define_protected_method(self, "mc", mc, -1);
+
+ // Cast by RUBY_METHOD_FUNC
+ rb_define_protected_method(self, "m1", RUBY_METHOD_FUNC(m1), 1);
+ rb_define_protected_method(self, "m2", RUBY_METHOD_FUNC(m2), 2);
+ rb_define_protected_method(self, "ma", RUBY_METHOD_FUNC(ma), -2);
+ rb_define_protected_method(self, "mv", RUBY_METHOD_FUNC(mv), -1);
+ rb_define_protected_method(self, "mc", RUBY_METHOD_FUNC(mc), -1);
+
+ // Explicit cast instead of RUBY_METHOD_FUNC
+ rb_define_protected_method(self, "m1", (VALUE (*)(...))(m1), 1);
+ rb_define_protected_method(self, "m2", (VALUE (*)(...))(m2), 2);
+ rb_define_protected_method(self, "ma", (VALUE (*)(...))(ma), -2);
+ rb_define_protected_method(self, "mv", (VALUE (*)(...))(mv), -1);
+ rb_define_protected_method(self, "mc", (VALUE (*)(...))(mc), -1);
+
+ // rb_f_notimplement
+ rb_define_protected_method(self, "m1", rb_f_notimplement, 1);
+ rb_define_protected_method(self, "m2", rb_f_notimplement, 2);
+ rb_define_protected_method(self, "ma", rb_f_notimplement, -2);
+ rb_define_protected_method(self, "mv", rb_f_notimplement, -1);
+ rb_define_protected_method(self, "mc", rb_f_notimplement, -1);
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a method.
+#endif
+
+ return self;
+ }
+}
+
+namespace test_rb_define_private_method {
+ static VALUE
+ m1(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ m2(VALUE, VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ ma(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mv(int, VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mc(int, const VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ // No cast
+ rb_define_private_method(self, "m1", m1, 1);
+ rb_define_private_method(self, "m2", m2, 2);
+ rb_define_private_method(self, "ma", ma, -2);
+ rb_define_private_method(self, "mv", mv, -1);
+ rb_define_private_method(self, "mc", mc, -1);
+
+ // Cast by RUBY_METHOD_FUNC
+ rb_define_private_method(self, "m1", RUBY_METHOD_FUNC(m1), 1);
+ rb_define_private_method(self, "m2", RUBY_METHOD_FUNC(m2), 2);
+ rb_define_private_method(self, "ma", RUBY_METHOD_FUNC(ma), -2);
+ rb_define_private_method(self, "mv", RUBY_METHOD_FUNC(mv), -1);
+ rb_define_private_method(self, "mc", RUBY_METHOD_FUNC(mc), -1);
+
+ // Explicit cast instead of RUBY_METHOD_FUNC
+ rb_define_private_method(self, "m1", (VALUE (*)(...))(m1), 1);
+ rb_define_private_method(self, "m2", (VALUE (*)(...))(m2), 2);
+ rb_define_private_method(self, "ma", (VALUE (*)(...))(ma), -2);
+ rb_define_private_method(self, "mv", (VALUE (*)(...))(mv), -1);
+ rb_define_private_method(self, "mc", (VALUE (*)(...))(mc), -1);
+
+ // rb_f_notimplement
+ rb_define_private_method(self, "m1", rb_f_notimplement, 1);
+ rb_define_private_method(self, "m2", rb_f_notimplement, 2);
+ rb_define_private_method(self, "ma", rb_f_notimplement, -2);
+ rb_define_private_method(self, "mv", rb_f_notimplement, -1);
+ rb_define_private_method(self, "mc", rb_f_notimplement, -1);
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a method.
+#endif
+
+ return self;
+ }
+}
+
+namespace test_rb_define_global_function {
+ static VALUE
+ m1(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ m2(VALUE, VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ ma(VALUE, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mv(int, VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ static VALUE
+ mc(int, const VALUE*, VALUE)
+ {
+ return Qnil;
+ }
+
+ VALUE
+ test(VALUE self)
+ {
+ // No cast
+ rb_define_global_function("m1", m1, 1);
+ rb_define_global_function("m2", m2, 2);
+ rb_define_global_function("ma", ma, -2);
+ rb_define_global_function("mv", mv, -1);
+ rb_define_global_function("mc", mc, -1);
+
+ // Cast by RUBY_METHOD_FUNC
+ rb_define_global_function("m1", RUBY_METHOD_FUNC(m1), 1);
+ rb_define_global_function("m2", RUBY_METHOD_FUNC(m2), 2);
+ rb_define_global_function("ma", RUBY_METHOD_FUNC(ma), -2);
+ rb_define_global_function("mv", RUBY_METHOD_FUNC(mv), -1);
+ rb_define_global_function("mc", RUBY_METHOD_FUNC(mc), -1);
+
+ // Explicit cast instead of RUBY_METHOD_FUNC
+ rb_define_global_function("m1", (VALUE (*)(...))(m1), 1);
+ rb_define_global_function("m2", (VALUE (*)(...))(m2), 2);
+ rb_define_global_function("ma", (VALUE (*)(...))(ma), -2);
+ rb_define_global_function("mv", (VALUE (*)(...))(mv), -1);
+ rb_define_global_function("mc", (VALUE (*)(...))(mc), -1);
+
+ // rb_f_notimplement
+ rb_define_global_function("m1", rb_f_notimplement, 1);
+ rb_define_global_function("m2", rb_f_notimplement, 2);
+ rb_define_global_function("ma", rb_f_notimplement, -2);
+ rb_define_global_function("mv", rb_f_notimplement, -1);
+ rb_define_global_function("mc", rb_f_notimplement, -1);
+
+#ifdef HAVE_NULLPTR
+ // It doesn't make any sense at all to pass nullptr as a method.
+#endif
+
+ return self;
+ }
+}
+
+extern "C" void
+Init_cxxanyargs(void)
+{
+ VALUE b = rb_define_module("Bug");
+#define test(sym) \
+ rb_define_module_function(b, #sym, RUBY_METHOD_FUNC(test_ ## sym::test), 0)
+
+ test(rb_define_virtual_variable);
+ test(rb_define_hooked_variable);
+ test(rb_iterate);
+ test(rb_block_call);
+ test(rb_rescue);
+ test(rb_rescue2);
+ test(rb_ensure);
+ test(rb_catch);
+ test(rb_catch_obj);
+ test(rb_fiber_new);
+ test(rb_proc_new);
+ test(rb_thread_create);
+ test(st_foreach);
+ test(st_foreach_check);
+ test(st_foreach_safe);
+ test(rb_hash_foreach);
+ test(rb_ivar_foreach);
+ test(rb_define_method);
+ test(rb_define_method_id);
+ test(rb_define_module_function);
+ test(rb_define_singleton_method);
+ test(rb_define_protected_method);
+ test(rb_define_private_method);
+ test(rb_define_global_function);
+}
diff --git a/ext/-test-/cxxanyargs/depend b/ext/-test-/cxxanyargs/depend
new file mode 100644
index 0000000000..ca821409a2
--- /dev/null
+++ b/ext/-test-/cxxanyargs/depend
@@ -0,0 +1,25 @@
+$(TARGET_SO) $(STATIC_LIB): $(FAILURES:.cpp=.failed)
+
+.SUFFIXES: .failed
+
+.cpp.failed:
+ $(Q)$(RUBY) -rfileutils \
+ -e "t = ARGV.shift" \
+ -e "err = IO.popen(ARGV, err:[:child, :out], &:read)" \
+ -e "abort err unless /rb_define_method/ =~ err.b" \
+ -e "File.write(t, err)" $@ $(MAKE) $(*F).o
+
+# AUTOGENERATED DEPENDENCIES START
+cxxanyargs.o: $(RUBY_EXTCONF_H)
+cxxanyargs.o: $(arch_hdrdir)/ruby/config.h
+cxxanyargs.o: $(hdrdir)/ruby/assert.h
+cxxanyargs.o: $(hdrdir)/ruby/backward.h
+cxxanyargs.o: $(hdrdir)/ruby/backward/cxxanyargs.hpp
+cxxanyargs.o: $(hdrdir)/ruby/defines.h
+cxxanyargs.o: $(hdrdir)/ruby/intern.h
+cxxanyargs.o: $(hdrdir)/ruby/missing.h
+cxxanyargs.o: $(hdrdir)/ruby/ruby.h
+cxxanyargs.o: $(hdrdir)/ruby/st.h
+cxxanyargs.o: $(hdrdir)/ruby/subst.h
+cxxanyargs.o: cxxanyargs.cpp
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/cxxanyargs/extconf.rb b/ext/-test-/cxxanyargs/extconf.rb
new file mode 100644
index 0000000000..d1d2469209
--- /dev/null
+++ b/ext/-test-/cxxanyargs/extconf.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: false
+
+cxx = MakeMakefile["C++"]
+
+# #### have_devel hack ####
+# cxx.try_compile tries to detect compilers, but the try_compile below is
+# trying to detect a compiler in a different way. We need to prevent the
+# default detection routine.
+
+cxx.instance_variable_set(:'@have_devel', true)
+
+ok = cxx.try_link(<<~'begin', "") do |x|
+ #include "ruby/config.h"
+
+ namespace {
+ typedef int conftest1[SIZEOF_LONG == sizeof(long) ? 1 : -1];
+ typedef int conftest2[SIZEOF_VOIDP == sizeof(void*) ? 1 : -1];
+ }
+
+ int
+ main(int argc, const char** argv)
+ {
+ return !!argv[argc];
+ }
+begin
+ # We are wiping ruby.h from the source because that header file is the
+ # subject we are going to test in this extension library.
+ x.sub! %<#include "ruby.h">, ''
+end
+
+cxx.instance_variable_set(:'@have_devel', ok)
+
+if ok
+ $srcs = %w[cxxanyargs.cpp]
+ failures = Dir.glob($srcdir + "/failure*.cpp").map {|n| File.basename(n)}
+ $cleanfiles << "$(FAILURES:.cpp=.failed)"
+ create_makefile("-test-/cxxanyargs") do |mk|
+ mk << "FAILURES #{['=', failures].join(' ')}\n"
+ mk << ".IGNORE: $(FAILURES:.cpp=.o)\n" unless $mswin
+ mk
+ end
+end
diff --git a/ext/-test-/cxxanyargs/failure.cpp b/ext/-test-/cxxanyargs/failure.cpp
new file mode 100644
index 0000000000..039beb1633
--- /dev/null
+++ b/ext/-test-/cxxanyargs/failure.cpp
@@ -0,0 +1,13 @@
+#include <ruby/ruby.h>
+
+static VALUE
+func_arg1(VALUE self, VALUE arg1)
+{
+ return arg1;
+}
+
+extern "C" void
+Init_failure(void)
+{
+ rb_define_method(rb_cObject, "arg1", func_arg1, 0);
+}
diff --git a/ext/-test-/cxxanyargs/failurem1.cpp b/ext/-test-/cxxanyargs/failurem1.cpp
new file mode 100644
index 0000000000..e58a0f4e0d
--- /dev/null
+++ b/ext/-test-/cxxanyargs/failurem1.cpp
@@ -0,0 +1,13 @@
+#include <ruby/ruby.h>
+
+static VALUE
+func_argm1(int argc, VALUE *argv, VALUE self)
+{
+ return argc > 0 ? argv[0] : Qnil;
+}
+
+extern "C" void
+Init_failure(void)
+{
+ rb_define_method(rb_cObject, "argm1", func_argm1, 0);
+}
diff --git a/ext/-test-/debug/depend b/ext/-test-/debug/depend
index 392677239a..dad22d46de 100644
--- a/ext/-test-/debug/depend
+++ b/ext/-test-/debug/depend
@@ -1,18 +1,318 @@
# AUTOGENERATED DEPENDENCIES START
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
inspector.o: $(RUBY_EXTCONF_H)
inspector.o: $(arch_hdrdir)/ruby/config.h
+inspector.o: $(hdrdir)/ruby/internal/anyargs.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+inspector.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+inspector.o: $(hdrdir)/ruby/internal/assume.h
+inspector.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+inspector.o: $(hdrdir)/ruby/internal/attr/artificial.h
+inspector.o: $(hdrdir)/ruby/internal/attr/cold.h
+inspector.o: $(hdrdir)/ruby/internal/attr/const.h
+inspector.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+inspector.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+inspector.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+inspector.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+inspector.o: $(hdrdir)/ruby/internal/attr/error.h
+inspector.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+inspector.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+inspector.o: $(hdrdir)/ruby/internal/attr/format.h
+inspector.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+inspector.o: $(hdrdir)/ruby/internal/attr/noalias.h
+inspector.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+inspector.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+inspector.o: $(hdrdir)/ruby/internal/attr/noinline.h
+inspector.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+inspector.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+inspector.o: $(hdrdir)/ruby/internal/attr/pure.h
+inspector.o: $(hdrdir)/ruby/internal/attr/restrict.h
+inspector.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+inspector.o: $(hdrdir)/ruby/internal/attr/warning.h
+inspector.o: $(hdrdir)/ruby/internal/attr/weakref.h
+inspector.o: $(hdrdir)/ruby/internal/cast.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_is.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+inspector.o: $(hdrdir)/ruby/internal/compiler_since.h
+inspector.o: $(hdrdir)/ruby/internal/config.h
+inspector.o: $(hdrdir)/ruby/internal/constant_p.h
+inspector.o: $(hdrdir)/ruby/internal/core.h
+inspector.o: $(hdrdir)/ruby/internal/core/rarray.h
+inspector.o: $(hdrdir)/ruby/internal/core/rbasic.h
+inspector.o: $(hdrdir)/ruby/internal/core/rbignum.h
+inspector.o: $(hdrdir)/ruby/internal/core/rclass.h
+inspector.o: $(hdrdir)/ruby/internal/core/rdata.h
+inspector.o: $(hdrdir)/ruby/internal/core/rfile.h
+inspector.o: $(hdrdir)/ruby/internal/core/rhash.h
+inspector.o: $(hdrdir)/ruby/internal/core/robject.h
+inspector.o: $(hdrdir)/ruby/internal/core/rregexp.h
+inspector.o: $(hdrdir)/ruby/internal/core/rstring.h
+inspector.o: $(hdrdir)/ruby/internal/core/rstruct.h
+inspector.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+inspector.o: $(hdrdir)/ruby/internal/ctype.h
+inspector.o: $(hdrdir)/ruby/internal/dllexport.h
+inspector.o: $(hdrdir)/ruby/internal/dosish.h
+inspector.o: $(hdrdir)/ruby/internal/error.h
+inspector.o: $(hdrdir)/ruby/internal/eval.h
+inspector.o: $(hdrdir)/ruby/internal/event.h
+inspector.o: $(hdrdir)/ruby/internal/fl_type.h
+inspector.o: $(hdrdir)/ruby/internal/gc.h
+inspector.o: $(hdrdir)/ruby/internal/glob.h
+inspector.o: $(hdrdir)/ruby/internal/globals.h
+inspector.o: $(hdrdir)/ruby/internal/has/attribute.h
+inspector.o: $(hdrdir)/ruby/internal/has/builtin.h
+inspector.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+inspector.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+inspector.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+inspector.o: $(hdrdir)/ruby/internal/has/extension.h
+inspector.o: $(hdrdir)/ruby/internal/has/feature.h
+inspector.o: $(hdrdir)/ruby/internal/has/warning.h
+inspector.o: $(hdrdir)/ruby/internal/intern/array.h
+inspector.o: $(hdrdir)/ruby/internal/intern/bignum.h
+inspector.o: $(hdrdir)/ruby/internal/intern/class.h
+inspector.o: $(hdrdir)/ruby/internal/intern/compar.h
+inspector.o: $(hdrdir)/ruby/internal/intern/complex.h
+inspector.o: $(hdrdir)/ruby/internal/intern/cont.h
+inspector.o: $(hdrdir)/ruby/internal/intern/dir.h
+inspector.o: $(hdrdir)/ruby/internal/intern/enum.h
+inspector.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+inspector.o: $(hdrdir)/ruby/internal/intern/error.h
+inspector.o: $(hdrdir)/ruby/internal/intern/eval.h
+inspector.o: $(hdrdir)/ruby/internal/intern/file.h
+inspector.o: $(hdrdir)/ruby/internal/intern/gc.h
+inspector.o: $(hdrdir)/ruby/internal/intern/hash.h
+inspector.o: $(hdrdir)/ruby/internal/intern/io.h
+inspector.o: $(hdrdir)/ruby/internal/intern/load.h
+inspector.o: $(hdrdir)/ruby/internal/intern/marshal.h
+inspector.o: $(hdrdir)/ruby/internal/intern/numeric.h
+inspector.o: $(hdrdir)/ruby/internal/intern/object.h
+inspector.o: $(hdrdir)/ruby/internal/intern/parse.h
+inspector.o: $(hdrdir)/ruby/internal/intern/proc.h
+inspector.o: $(hdrdir)/ruby/internal/intern/process.h
+inspector.o: $(hdrdir)/ruby/internal/intern/random.h
+inspector.o: $(hdrdir)/ruby/internal/intern/range.h
+inspector.o: $(hdrdir)/ruby/internal/intern/rational.h
+inspector.o: $(hdrdir)/ruby/internal/intern/re.h
+inspector.o: $(hdrdir)/ruby/internal/intern/ruby.h
+inspector.o: $(hdrdir)/ruby/internal/intern/select.h
+inspector.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+inspector.o: $(hdrdir)/ruby/internal/intern/signal.h
+inspector.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+inspector.o: $(hdrdir)/ruby/internal/intern/string.h
+inspector.o: $(hdrdir)/ruby/internal/intern/struct.h
+inspector.o: $(hdrdir)/ruby/internal/intern/thread.h
+inspector.o: $(hdrdir)/ruby/internal/intern/time.h
+inspector.o: $(hdrdir)/ruby/internal/intern/variable.h
+inspector.o: $(hdrdir)/ruby/internal/intern/vm.h
+inspector.o: $(hdrdir)/ruby/internal/interpreter.h
+inspector.o: $(hdrdir)/ruby/internal/iterator.h
+inspector.o: $(hdrdir)/ruby/internal/memory.h
+inspector.o: $(hdrdir)/ruby/internal/method.h
+inspector.o: $(hdrdir)/ruby/internal/module.h
+inspector.o: $(hdrdir)/ruby/internal/newobj.h
+inspector.o: $(hdrdir)/ruby/internal/rgengc.h
+inspector.o: $(hdrdir)/ruby/internal/scan_args.h
+inspector.o: $(hdrdir)/ruby/internal/special_consts.h
+inspector.o: $(hdrdir)/ruby/internal/static_assert.h
+inspector.o: $(hdrdir)/ruby/internal/stdalign.h
+inspector.o: $(hdrdir)/ruby/internal/stdbool.h
+inspector.o: $(hdrdir)/ruby/internal/symbol.h
+inspector.o: $(hdrdir)/ruby/internal/token_paste.h
+inspector.o: $(hdrdir)/ruby/internal/value.h
+inspector.o: $(hdrdir)/ruby/internal/value_type.h
+inspector.o: $(hdrdir)/ruby/internal/variable.h
+inspector.o: $(hdrdir)/ruby/internal/warning_push.h
+inspector.o: $(hdrdir)/ruby/internal/xmalloc.h
+inspector.o: $(hdrdir)/ruby/assert.h
inspector.o: $(hdrdir)/ruby/backward.h
+inspector.o: $(hdrdir)/ruby/backward/2/assume.h
+inspector.o: $(hdrdir)/ruby/backward/2/attributes.h
+inspector.o: $(hdrdir)/ruby/backward/2/bool.h
+inspector.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+inspector.o: $(hdrdir)/ruby/backward/2/inttypes.h
+inspector.o: $(hdrdir)/ruby/backward/2/limits.h
+inspector.o: $(hdrdir)/ruby/backward/2/long_long.h
+inspector.o: $(hdrdir)/ruby/backward/2/stdalign.h
+inspector.o: $(hdrdir)/ruby/backward/2/stdarg.h
inspector.o: $(hdrdir)/ruby/debug.h
inspector.o: $(hdrdir)/ruby/defines.h
inspector.o: $(hdrdir)/ruby/intern.h
@@ -23,7 +323,157 @@ inspector.o: $(hdrdir)/ruby/subst.h
inspector.o: inspector.c
profile_frames.o: $(RUBY_EXTCONF_H)
profile_frames.o: $(arch_hdrdir)/ruby/config.h
+profile_frames.o: $(hdrdir)/ruby/internal/anyargs.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+profile_frames.o: $(hdrdir)/ruby/internal/assume.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/artificial.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/cold.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/const.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/error.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/format.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/noalias.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/noinline.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/pure.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/restrict.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/warning.h
+profile_frames.o: $(hdrdir)/ruby/internal/attr/weakref.h
+profile_frames.o: $(hdrdir)/ruby/internal/cast.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_is.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+profile_frames.o: $(hdrdir)/ruby/internal/compiler_since.h
+profile_frames.o: $(hdrdir)/ruby/internal/config.h
+profile_frames.o: $(hdrdir)/ruby/internal/constant_p.h
+profile_frames.o: $(hdrdir)/ruby/internal/core.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rarray.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rbasic.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rbignum.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rclass.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rdata.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rfile.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rhash.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/robject.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rregexp.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rstring.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rstruct.h
+profile_frames.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+profile_frames.o: $(hdrdir)/ruby/internal/ctype.h
+profile_frames.o: $(hdrdir)/ruby/internal/dllexport.h
+profile_frames.o: $(hdrdir)/ruby/internal/dosish.h
+profile_frames.o: $(hdrdir)/ruby/internal/error.h
+profile_frames.o: $(hdrdir)/ruby/internal/eval.h
+profile_frames.o: $(hdrdir)/ruby/internal/event.h
+profile_frames.o: $(hdrdir)/ruby/internal/fl_type.h
+profile_frames.o: $(hdrdir)/ruby/internal/gc.h
+profile_frames.o: $(hdrdir)/ruby/internal/glob.h
+profile_frames.o: $(hdrdir)/ruby/internal/globals.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/attribute.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/builtin.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/extension.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/feature.h
+profile_frames.o: $(hdrdir)/ruby/internal/has/warning.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/array.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/bignum.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/class.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/compar.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/complex.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/cont.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/dir.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/enum.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/error.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/eval.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/file.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/gc.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/hash.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/io.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/load.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/marshal.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/numeric.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/object.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/parse.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/proc.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/process.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/random.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/range.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/rational.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/re.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/ruby.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/select.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/signal.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/string.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/struct.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/thread.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/time.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/variable.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/vm.h
+profile_frames.o: $(hdrdir)/ruby/internal/interpreter.h
+profile_frames.o: $(hdrdir)/ruby/internal/iterator.h
+profile_frames.o: $(hdrdir)/ruby/internal/memory.h
+profile_frames.o: $(hdrdir)/ruby/internal/method.h
+profile_frames.o: $(hdrdir)/ruby/internal/module.h
+profile_frames.o: $(hdrdir)/ruby/internal/newobj.h
+profile_frames.o: $(hdrdir)/ruby/internal/rgengc.h
+profile_frames.o: $(hdrdir)/ruby/internal/scan_args.h
+profile_frames.o: $(hdrdir)/ruby/internal/special_consts.h
+profile_frames.o: $(hdrdir)/ruby/internal/static_assert.h
+profile_frames.o: $(hdrdir)/ruby/internal/stdalign.h
+profile_frames.o: $(hdrdir)/ruby/internal/stdbool.h
+profile_frames.o: $(hdrdir)/ruby/internal/symbol.h
+profile_frames.o: $(hdrdir)/ruby/internal/token_paste.h
+profile_frames.o: $(hdrdir)/ruby/internal/value.h
+profile_frames.o: $(hdrdir)/ruby/internal/value_type.h
+profile_frames.o: $(hdrdir)/ruby/internal/variable.h
+profile_frames.o: $(hdrdir)/ruby/internal/warning_push.h
+profile_frames.o: $(hdrdir)/ruby/internal/xmalloc.h
+profile_frames.o: $(hdrdir)/ruby/assert.h
profile_frames.o: $(hdrdir)/ruby/backward.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/assume.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/attributes.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/bool.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/inttypes.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/limits.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/long_long.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/stdalign.h
+profile_frames.o: $(hdrdir)/ruby/backward/2/stdarg.h
profile_frames.o: $(hdrdir)/ruby/debug.h
profile_frames.o: $(hdrdir)/ruby/defines.h
profile_frames.o: $(hdrdir)/ruby/intern.h
diff --git a/ext/-test-/enumerator_kw/depend b/ext/-test-/enumerator_kw/depend
new file mode 100644
index 0000000000..4597e34027
--- /dev/null
+++ b/ext/-test-/enumerator_kw/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+enumerator_kw.o: $(RUBY_EXTCONF_H)
+enumerator_kw.o: $(arch_hdrdir)/ruby/config.h
+enumerator_kw.o: $(hdrdir)/ruby.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/anyargs.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/assume.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/artificial.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/cold.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/const.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/error.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/format.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noalias.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noinline.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/pure.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/restrict.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/warning.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/attr/weakref.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/cast.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_is.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/compiler_since.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/config.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/constant_p.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rarray.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rbasic.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rbignum.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rclass.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rdata.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rfile.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rhash.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/robject.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rregexp.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rstring.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rstruct.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/ctype.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/dllexport.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/dosish.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/error.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/eval.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/event.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/fl_type.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/gc.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/glob.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/globals.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/attribute.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/builtin.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/extension.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/feature.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/has/warning.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/array.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/bignum.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/class.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/compar.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/complex.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/cont.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/dir.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/enum.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/error.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/eval.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/file.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/gc.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/hash.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/io.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/load.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/marshal.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/numeric.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/object.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/parse.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/proc.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/process.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/random.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/range.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/rational.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/re.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/ruby.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/select.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/signal.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/string.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/struct.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/thread.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/time.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/variable.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/vm.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/interpreter.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/iterator.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/memory.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/method.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/module.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/newobj.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/rgengc.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/scan_args.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/special_consts.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/static_assert.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/stdalign.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/stdbool.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/symbol.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/token_paste.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/value.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/value_type.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/variable.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/warning_push.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/xmalloc.h
+enumerator_kw.o: $(hdrdir)/ruby/assert.h
+enumerator_kw.o: $(hdrdir)/ruby/backward.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/assume.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/attributes.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/bool.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/inttypes.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/limits.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/long_long.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/stdalign.h
+enumerator_kw.o: $(hdrdir)/ruby/backward/2/stdarg.h
+enumerator_kw.o: $(hdrdir)/ruby/defines.h
+enumerator_kw.o: $(hdrdir)/ruby/intern.h
+enumerator_kw.o: $(hdrdir)/ruby/missing.h
+enumerator_kw.o: $(hdrdir)/ruby/ruby.h
+enumerator_kw.o: $(hdrdir)/ruby/st.h
+enumerator_kw.o: $(hdrdir)/ruby/subst.h
+enumerator_kw.o: enumerator_kw.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/enumerator_kw/enumerator_kw.c b/ext/-test-/enumerator_kw/enumerator_kw.c
new file mode 100644
index 0000000000..947d2b37e6
--- /dev/null
+++ b/ext/-test-/enumerator_kw/enumerator_kw.c
@@ -0,0 +1,21 @@
+#include <ruby.h>
+
+static VALUE
+enumerator_kw(int argc, VALUE *argv, VALUE self)
+{
+ VALUE opt, enum_args[4];
+ enum_args[0] = Qnil;
+ enum_args[1] = Qnil;
+ rb_scan_args(argc, argv, "01*:", enum_args, enum_args+1, &opt);
+ enum_args[3] = self;
+ enum_args[2] = opt;
+ RETURN_SIZED_ENUMERATOR_KW(self, 4, enum_args, 0, RB_NO_KEYWORDS);
+ return rb_yield_values_kw(4, enum_args, RB_NO_KEYWORDS);
+}
+
+void
+Init_enumerator_kw(void) {
+ VALUE module = rb_define_module("Bug");
+ module = rb_define_module_under(module, "EnumeratorKw");
+ rb_define_method(module, "m", enumerator_kw, -1);
+}
diff --git a/ext/-test-/enumerator_kw/extconf.rb b/ext/-test-/enumerator_kw/extconf.rb
new file mode 100644
index 0000000000..ab2be73fa8
--- /dev/null
+++ b/ext/-test-/enumerator_kw/extconf.rb
@@ -0,0 +1 @@
+create_makefile("-test-/enumerator_kw")
diff --git a/ext/-test-/exception/depend b/ext/-test-/exception/depend
index 9e5ccff274..47f1ac6a6a 100644
--- a/ext/-test-/exception/depend
+++ b/ext/-test-/exception/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
dataerror.o: $(RUBY_EXTCONF_H)
dataerror.o: $(arch_hdrdir)/ruby/config.h
+dataerror.o: $(hdrdir)/ruby/internal/anyargs.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+dataerror.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+dataerror.o: $(hdrdir)/ruby/internal/assume.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/artificial.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/cold.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/const.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/error.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/format.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/noalias.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/noinline.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/pure.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/restrict.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/warning.h
+dataerror.o: $(hdrdir)/ruby/internal/attr/weakref.h
+dataerror.o: $(hdrdir)/ruby/internal/cast.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_is.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+dataerror.o: $(hdrdir)/ruby/internal/compiler_since.h
+dataerror.o: $(hdrdir)/ruby/internal/config.h
+dataerror.o: $(hdrdir)/ruby/internal/constant_p.h
+dataerror.o: $(hdrdir)/ruby/internal/core.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rarray.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rbasic.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rbignum.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rclass.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rdata.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rfile.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rhash.h
+dataerror.o: $(hdrdir)/ruby/internal/core/robject.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rregexp.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rstring.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rstruct.h
+dataerror.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+dataerror.o: $(hdrdir)/ruby/internal/ctype.h
+dataerror.o: $(hdrdir)/ruby/internal/dllexport.h
+dataerror.o: $(hdrdir)/ruby/internal/dosish.h
+dataerror.o: $(hdrdir)/ruby/internal/error.h
+dataerror.o: $(hdrdir)/ruby/internal/eval.h
+dataerror.o: $(hdrdir)/ruby/internal/event.h
+dataerror.o: $(hdrdir)/ruby/internal/fl_type.h
+dataerror.o: $(hdrdir)/ruby/internal/gc.h
+dataerror.o: $(hdrdir)/ruby/internal/glob.h
+dataerror.o: $(hdrdir)/ruby/internal/globals.h
+dataerror.o: $(hdrdir)/ruby/internal/has/attribute.h
+dataerror.o: $(hdrdir)/ruby/internal/has/builtin.h
+dataerror.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+dataerror.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+dataerror.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+dataerror.o: $(hdrdir)/ruby/internal/has/extension.h
+dataerror.o: $(hdrdir)/ruby/internal/has/feature.h
+dataerror.o: $(hdrdir)/ruby/internal/has/warning.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/array.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/bignum.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/class.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/compar.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/complex.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/cont.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/dir.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/enum.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/error.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/eval.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/file.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/gc.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/hash.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/io.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/load.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/marshal.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/numeric.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/object.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/parse.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/proc.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/process.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/random.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/range.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/rational.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/re.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/ruby.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/select.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/signal.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/string.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/struct.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/thread.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/time.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/variable.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/vm.h
+dataerror.o: $(hdrdir)/ruby/internal/interpreter.h
+dataerror.o: $(hdrdir)/ruby/internal/iterator.h
+dataerror.o: $(hdrdir)/ruby/internal/memory.h
+dataerror.o: $(hdrdir)/ruby/internal/method.h
+dataerror.o: $(hdrdir)/ruby/internal/module.h
+dataerror.o: $(hdrdir)/ruby/internal/newobj.h
+dataerror.o: $(hdrdir)/ruby/internal/rgengc.h
+dataerror.o: $(hdrdir)/ruby/internal/scan_args.h
+dataerror.o: $(hdrdir)/ruby/internal/special_consts.h
+dataerror.o: $(hdrdir)/ruby/internal/static_assert.h
+dataerror.o: $(hdrdir)/ruby/internal/stdalign.h
+dataerror.o: $(hdrdir)/ruby/internal/stdbool.h
+dataerror.o: $(hdrdir)/ruby/internal/symbol.h
+dataerror.o: $(hdrdir)/ruby/internal/token_paste.h
+dataerror.o: $(hdrdir)/ruby/internal/value.h
+dataerror.o: $(hdrdir)/ruby/internal/value_type.h
+dataerror.o: $(hdrdir)/ruby/internal/variable.h
+dataerror.o: $(hdrdir)/ruby/internal/warning_push.h
+dataerror.o: $(hdrdir)/ruby/internal/xmalloc.h
+dataerror.o: $(hdrdir)/ruby/assert.h
dataerror.o: $(hdrdir)/ruby/backward.h
+dataerror.o: $(hdrdir)/ruby/backward/2/assume.h
+dataerror.o: $(hdrdir)/ruby/backward/2/attributes.h
+dataerror.o: $(hdrdir)/ruby/backward/2/bool.h
+dataerror.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+dataerror.o: $(hdrdir)/ruby/backward/2/inttypes.h
+dataerror.o: $(hdrdir)/ruby/backward/2/limits.h
+dataerror.o: $(hdrdir)/ruby/backward/2/long_long.h
+dataerror.o: $(hdrdir)/ruby/backward/2/stdalign.h
+dataerror.o: $(hdrdir)/ruby/backward/2/stdarg.h
dataerror.o: $(hdrdir)/ruby/defines.h
dataerror.o: $(hdrdir)/ruby/intern.h
dataerror.o: $(hdrdir)/ruby/missing.h
@@ -11,7 +161,158 @@ dataerror.o: $(hdrdir)/ruby/subst.h
dataerror.o: dataerror.c
enc_raise.o: $(RUBY_EXTCONF_H)
enc_raise.o: $(arch_hdrdir)/ruby/config.h
+enc_raise.o: $(hdrdir)/ruby.h
+enc_raise.o: $(hdrdir)/ruby/internal/anyargs.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+enc_raise.o: $(hdrdir)/ruby/internal/assume.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/artificial.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/cold.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/const.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/error.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/format.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/noalias.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/noinline.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/pure.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/restrict.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/warning.h
+enc_raise.o: $(hdrdir)/ruby/internal/attr/weakref.h
+enc_raise.o: $(hdrdir)/ruby/internal/cast.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_is.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+enc_raise.o: $(hdrdir)/ruby/internal/compiler_since.h
+enc_raise.o: $(hdrdir)/ruby/internal/config.h
+enc_raise.o: $(hdrdir)/ruby/internal/constant_p.h
+enc_raise.o: $(hdrdir)/ruby/internal/core.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rarray.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rbasic.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rbignum.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rclass.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rdata.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rfile.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rhash.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/robject.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rregexp.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rstring.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rstruct.h
+enc_raise.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+enc_raise.o: $(hdrdir)/ruby/internal/ctype.h
+enc_raise.o: $(hdrdir)/ruby/internal/dllexport.h
+enc_raise.o: $(hdrdir)/ruby/internal/dosish.h
+enc_raise.o: $(hdrdir)/ruby/internal/error.h
+enc_raise.o: $(hdrdir)/ruby/internal/eval.h
+enc_raise.o: $(hdrdir)/ruby/internal/event.h
+enc_raise.o: $(hdrdir)/ruby/internal/fl_type.h
+enc_raise.o: $(hdrdir)/ruby/internal/gc.h
+enc_raise.o: $(hdrdir)/ruby/internal/glob.h
+enc_raise.o: $(hdrdir)/ruby/internal/globals.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/attribute.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/builtin.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/extension.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/feature.h
+enc_raise.o: $(hdrdir)/ruby/internal/has/warning.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/array.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/bignum.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/class.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/compar.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/complex.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/cont.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/dir.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/enum.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/error.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/eval.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/file.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/gc.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/hash.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/io.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/load.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/marshal.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/numeric.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/object.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/parse.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/proc.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/process.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/random.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/range.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/rational.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/re.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/ruby.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/select.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/signal.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/string.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/struct.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/thread.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/time.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/variable.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/vm.h
+enc_raise.o: $(hdrdir)/ruby/internal/interpreter.h
+enc_raise.o: $(hdrdir)/ruby/internal/iterator.h
+enc_raise.o: $(hdrdir)/ruby/internal/memory.h
+enc_raise.o: $(hdrdir)/ruby/internal/method.h
+enc_raise.o: $(hdrdir)/ruby/internal/module.h
+enc_raise.o: $(hdrdir)/ruby/internal/newobj.h
+enc_raise.o: $(hdrdir)/ruby/internal/rgengc.h
+enc_raise.o: $(hdrdir)/ruby/internal/scan_args.h
+enc_raise.o: $(hdrdir)/ruby/internal/special_consts.h
+enc_raise.o: $(hdrdir)/ruby/internal/static_assert.h
+enc_raise.o: $(hdrdir)/ruby/internal/stdalign.h
+enc_raise.o: $(hdrdir)/ruby/internal/stdbool.h
+enc_raise.o: $(hdrdir)/ruby/internal/symbol.h
+enc_raise.o: $(hdrdir)/ruby/internal/token_paste.h
+enc_raise.o: $(hdrdir)/ruby/internal/value.h
+enc_raise.o: $(hdrdir)/ruby/internal/value_type.h
+enc_raise.o: $(hdrdir)/ruby/internal/variable.h
+enc_raise.o: $(hdrdir)/ruby/internal/warning_push.h
+enc_raise.o: $(hdrdir)/ruby/internal/xmalloc.h
+enc_raise.o: $(hdrdir)/ruby/assert.h
enc_raise.o: $(hdrdir)/ruby/backward.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/assume.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/attributes.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/bool.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/inttypes.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/limits.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/long_long.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/stdalign.h
+enc_raise.o: $(hdrdir)/ruby/backward/2/stdarg.h
enc_raise.o: $(hdrdir)/ruby/defines.h
enc_raise.o: $(hdrdir)/ruby/encoding.h
enc_raise.o: $(hdrdir)/ruby/intern.h
@@ -21,28 +322,327 @@ enc_raise.o: $(hdrdir)/ruby/oniguruma.h
enc_raise.o: $(hdrdir)/ruby/ruby.h
enc_raise.o: $(hdrdir)/ruby/st.h
enc_raise.o: $(hdrdir)/ruby/subst.h
-enc_raise.o: $(top_srcdir)/include/ruby.h
enc_raise.o: enc_raise.c
ensured.o: $(RUBY_EXTCONF_H)
ensured.o: $(arch_hdrdir)/ruby/config.h
+ensured.o: $(hdrdir)/ruby.h
+ensured.o: $(hdrdir)/ruby/internal/anyargs.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ensured.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ensured.o: $(hdrdir)/ruby/internal/assume.h
+ensured.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ensured.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ensured.o: $(hdrdir)/ruby/internal/attr/cold.h
+ensured.o: $(hdrdir)/ruby/internal/attr/const.h
+ensured.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ensured.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ensured.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ensured.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ensured.o: $(hdrdir)/ruby/internal/attr/error.h
+ensured.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ensured.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ensured.o: $(hdrdir)/ruby/internal/attr/format.h
+ensured.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ensured.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ensured.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ensured.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ensured.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ensured.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ensured.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ensured.o: $(hdrdir)/ruby/internal/attr/pure.h
+ensured.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ensured.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ensured.o: $(hdrdir)/ruby/internal/attr/warning.h
+ensured.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ensured.o: $(hdrdir)/ruby/internal/cast.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_is.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ensured.o: $(hdrdir)/ruby/internal/compiler_since.h
+ensured.o: $(hdrdir)/ruby/internal/config.h
+ensured.o: $(hdrdir)/ruby/internal/constant_p.h
+ensured.o: $(hdrdir)/ruby/internal/core.h
+ensured.o: $(hdrdir)/ruby/internal/core/rarray.h
+ensured.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ensured.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ensured.o: $(hdrdir)/ruby/internal/core/rclass.h
+ensured.o: $(hdrdir)/ruby/internal/core/rdata.h
+ensured.o: $(hdrdir)/ruby/internal/core/rfile.h
+ensured.o: $(hdrdir)/ruby/internal/core/rhash.h
+ensured.o: $(hdrdir)/ruby/internal/core/robject.h
+ensured.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ensured.o: $(hdrdir)/ruby/internal/core/rstring.h
+ensured.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ensured.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ensured.o: $(hdrdir)/ruby/internal/ctype.h
+ensured.o: $(hdrdir)/ruby/internal/dllexport.h
+ensured.o: $(hdrdir)/ruby/internal/dosish.h
+ensured.o: $(hdrdir)/ruby/internal/error.h
+ensured.o: $(hdrdir)/ruby/internal/eval.h
+ensured.o: $(hdrdir)/ruby/internal/event.h
+ensured.o: $(hdrdir)/ruby/internal/fl_type.h
+ensured.o: $(hdrdir)/ruby/internal/gc.h
+ensured.o: $(hdrdir)/ruby/internal/glob.h
+ensured.o: $(hdrdir)/ruby/internal/globals.h
+ensured.o: $(hdrdir)/ruby/internal/has/attribute.h
+ensured.o: $(hdrdir)/ruby/internal/has/builtin.h
+ensured.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ensured.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ensured.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ensured.o: $(hdrdir)/ruby/internal/has/extension.h
+ensured.o: $(hdrdir)/ruby/internal/has/feature.h
+ensured.o: $(hdrdir)/ruby/internal/has/warning.h
+ensured.o: $(hdrdir)/ruby/internal/intern/array.h
+ensured.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ensured.o: $(hdrdir)/ruby/internal/intern/class.h
+ensured.o: $(hdrdir)/ruby/internal/intern/compar.h
+ensured.o: $(hdrdir)/ruby/internal/intern/complex.h
+ensured.o: $(hdrdir)/ruby/internal/intern/cont.h
+ensured.o: $(hdrdir)/ruby/internal/intern/dir.h
+ensured.o: $(hdrdir)/ruby/internal/intern/enum.h
+ensured.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ensured.o: $(hdrdir)/ruby/internal/intern/error.h
+ensured.o: $(hdrdir)/ruby/internal/intern/eval.h
+ensured.o: $(hdrdir)/ruby/internal/intern/file.h
+ensured.o: $(hdrdir)/ruby/internal/intern/gc.h
+ensured.o: $(hdrdir)/ruby/internal/intern/hash.h
+ensured.o: $(hdrdir)/ruby/internal/intern/io.h
+ensured.o: $(hdrdir)/ruby/internal/intern/load.h
+ensured.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ensured.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ensured.o: $(hdrdir)/ruby/internal/intern/object.h
+ensured.o: $(hdrdir)/ruby/internal/intern/parse.h
+ensured.o: $(hdrdir)/ruby/internal/intern/proc.h
+ensured.o: $(hdrdir)/ruby/internal/intern/process.h
+ensured.o: $(hdrdir)/ruby/internal/intern/random.h
+ensured.o: $(hdrdir)/ruby/internal/intern/range.h
+ensured.o: $(hdrdir)/ruby/internal/intern/rational.h
+ensured.o: $(hdrdir)/ruby/internal/intern/re.h
+ensured.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ensured.o: $(hdrdir)/ruby/internal/intern/select.h
+ensured.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ensured.o: $(hdrdir)/ruby/internal/intern/signal.h
+ensured.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ensured.o: $(hdrdir)/ruby/internal/intern/string.h
+ensured.o: $(hdrdir)/ruby/internal/intern/struct.h
+ensured.o: $(hdrdir)/ruby/internal/intern/thread.h
+ensured.o: $(hdrdir)/ruby/internal/intern/time.h
+ensured.o: $(hdrdir)/ruby/internal/intern/variable.h
+ensured.o: $(hdrdir)/ruby/internal/intern/vm.h
+ensured.o: $(hdrdir)/ruby/internal/interpreter.h
+ensured.o: $(hdrdir)/ruby/internal/iterator.h
+ensured.o: $(hdrdir)/ruby/internal/memory.h
+ensured.o: $(hdrdir)/ruby/internal/method.h
+ensured.o: $(hdrdir)/ruby/internal/module.h
+ensured.o: $(hdrdir)/ruby/internal/newobj.h
+ensured.o: $(hdrdir)/ruby/internal/rgengc.h
+ensured.o: $(hdrdir)/ruby/internal/scan_args.h
+ensured.o: $(hdrdir)/ruby/internal/special_consts.h
+ensured.o: $(hdrdir)/ruby/internal/static_assert.h
+ensured.o: $(hdrdir)/ruby/internal/stdalign.h
+ensured.o: $(hdrdir)/ruby/internal/stdbool.h
+ensured.o: $(hdrdir)/ruby/internal/symbol.h
+ensured.o: $(hdrdir)/ruby/internal/token_paste.h
+ensured.o: $(hdrdir)/ruby/internal/value.h
+ensured.o: $(hdrdir)/ruby/internal/value_type.h
+ensured.o: $(hdrdir)/ruby/internal/variable.h
+ensured.o: $(hdrdir)/ruby/internal/warning_push.h
+ensured.o: $(hdrdir)/ruby/internal/xmalloc.h
+ensured.o: $(hdrdir)/ruby/assert.h
ensured.o: $(hdrdir)/ruby/backward.h
+ensured.o: $(hdrdir)/ruby/backward/2/assume.h
+ensured.o: $(hdrdir)/ruby/backward/2/attributes.h
+ensured.o: $(hdrdir)/ruby/backward/2/bool.h
+ensured.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ensured.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ensured.o: $(hdrdir)/ruby/backward/2/limits.h
+ensured.o: $(hdrdir)/ruby/backward/2/long_long.h
+ensured.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ensured.o: $(hdrdir)/ruby/backward/2/stdarg.h
ensured.o: $(hdrdir)/ruby/defines.h
ensured.o: $(hdrdir)/ruby/intern.h
ensured.o: $(hdrdir)/ruby/missing.h
ensured.o: $(hdrdir)/ruby/ruby.h
ensured.o: $(hdrdir)/ruby/st.h
ensured.o: $(hdrdir)/ruby/subst.h
-ensured.o: $(top_srcdir)/include/ruby.h
ensured.o: ensured.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/exception/enc_raise.c b/ext/-test-/exception/enc_raise.c
index dc8a42cf3f..68d7b4ebc1 100644
--- a/ext/-test-/exception/enc_raise.c
+++ b/ext/-test-/exception/enc_raise.c
@@ -5,7 +5,7 @@ static VALUE
enc_raise(VALUE exc, VALUE encoding, VALUE mesg)
{
rb_enc_raise(rb_to_encoding(encoding), exc, "%s", StringValueCStr(mesg));
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
void
diff --git a/ext/-test-/fatal/depend b/ext/-test-/fatal/depend
new file mode 100644
index 0000000000..bb2e61a51f
--- /dev/null
+++ b/ext/-test-/fatal/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+rb_fatal.o: $(RUBY_EXTCONF_H)
+rb_fatal.o: $(arch_hdrdir)/ruby/config.h
+rb_fatal.o: $(hdrdir)/ruby.h
+rb_fatal.o: $(hdrdir)/ruby/internal/anyargs.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+rb_fatal.o: $(hdrdir)/ruby/internal/assume.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/artificial.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/cold.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/const.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/error.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/format.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/noalias.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/noinline.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/pure.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/restrict.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/warning.h
+rb_fatal.o: $(hdrdir)/ruby/internal/attr/weakref.h
+rb_fatal.o: $(hdrdir)/ruby/internal/cast.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_is.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+rb_fatal.o: $(hdrdir)/ruby/internal/compiler_since.h
+rb_fatal.o: $(hdrdir)/ruby/internal/config.h
+rb_fatal.o: $(hdrdir)/ruby/internal/constant_p.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rarray.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rbasic.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rbignum.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rclass.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rdata.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rfile.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rhash.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/robject.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rregexp.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rstring.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rstruct.h
+rb_fatal.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+rb_fatal.o: $(hdrdir)/ruby/internal/ctype.h
+rb_fatal.o: $(hdrdir)/ruby/internal/dllexport.h
+rb_fatal.o: $(hdrdir)/ruby/internal/dosish.h
+rb_fatal.o: $(hdrdir)/ruby/internal/error.h
+rb_fatal.o: $(hdrdir)/ruby/internal/eval.h
+rb_fatal.o: $(hdrdir)/ruby/internal/event.h
+rb_fatal.o: $(hdrdir)/ruby/internal/fl_type.h
+rb_fatal.o: $(hdrdir)/ruby/internal/gc.h
+rb_fatal.o: $(hdrdir)/ruby/internal/glob.h
+rb_fatal.o: $(hdrdir)/ruby/internal/globals.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/attribute.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/builtin.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/extension.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/feature.h
+rb_fatal.o: $(hdrdir)/ruby/internal/has/warning.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/array.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/bignum.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/class.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/compar.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/complex.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/cont.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/dir.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/enum.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/error.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/eval.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/gc.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/hash.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/io.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/load.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/marshal.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/numeric.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/object.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/parse.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/proc.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/process.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/random.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/range.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/rational.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/re.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/ruby.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/select.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/signal.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/string.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/struct.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/thread.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/time.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/variable.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/vm.h
+rb_fatal.o: $(hdrdir)/ruby/internal/interpreter.h
+rb_fatal.o: $(hdrdir)/ruby/internal/iterator.h
+rb_fatal.o: $(hdrdir)/ruby/internal/memory.h
+rb_fatal.o: $(hdrdir)/ruby/internal/method.h
+rb_fatal.o: $(hdrdir)/ruby/internal/module.h
+rb_fatal.o: $(hdrdir)/ruby/internal/newobj.h
+rb_fatal.o: $(hdrdir)/ruby/internal/rgengc.h
+rb_fatal.o: $(hdrdir)/ruby/internal/scan_args.h
+rb_fatal.o: $(hdrdir)/ruby/internal/special_consts.h
+rb_fatal.o: $(hdrdir)/ruby/internal/static_assert.h
+rb_fatal.o: $(hdrdir)/ruby/internal/stdalign.h
+rb_fatal.o: $(hdrdir)/ruby/internal/stdbool.h
+rb_fatal.o: $(hdrdir)/ruby/internal/symbol.h
+rb_fatal.o: $(hdrdir)/ruby/internal/token_paste.h
+rb_fatal.o: $(hdrdir)/ruby/internal/value.h
+rb_fatal.o: $(hdrdir)/ruby/internal/value_type.h
+rb_fatal.o: $(hdrdir)/ruby/internal/variable.h
+rb_fatal.o: $(hdrdir)/ruby/internal/warning_push.h
+rb_fatal.o: $(hdrdir)/ruby/internal/xmalloc.h
+rb_fatal.o: $(hdrdir)/ruby/assert.h
+rb_fatal.o: $(hdrdir)/ruby/backward.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/assume.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/attributes.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/bool.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/inttypes.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/limits.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/long_long.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/stdalign.h
+rb_fatal.o: $(hdrdir)/ruby/backward/2/stdarg.h
+rb_fatal.o: $(hdrdir)/ruby/defines.h
+rb_fatal.o: $(hdrdir)/ruby/intern.h
+rb_fatal.o: $(hdrdir)/ruby/missing.h
+rb_fatal.o: $(hdrdir)/ruby/ruby.h
+rb_fatal.o: $(hdrdir)/ruby/st.h
+rb_fatal.o: $(hdrdir)/ruby/subst.h
+rb_fatal.o: rb_fatal.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/file/depend b/ext/-test-/file/depend
index 0eea6063dd..12b0bbd825 100644
--- a/ext/-test-/file/depend
+++ b/ext/-test-/file/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
fs.o: $(RUBY_EXTCONF_H)
fs.o: $(arch_hdrdir)/ruby/config.h
+fs.o: $(hdrdir)/ruby/internal/anyargs.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+fs.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+fs.o: $(hdrdir)/ruby/internal/assume.h
+fs.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+fs.o: $(hdrdir)/ruby/internal/attr/artificial.h
+fs.o: $(hdrdir)/ruby/internal/attr/cold.h
+fs.o: $(hdrdir)/ruby/internal/attr/const.h
+fs.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+fs.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+fs.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+fs.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+fs.o: $(hdrdir)/ruby/internal/attr/error.h
+fs.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+fs.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+fs.o: $(hdrdir)/ruby/internal/attr/format.h
+fs.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+fs.o: $(hdrdir)/ruby/internal/attr/noalias.h
+fs.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+fs.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+fs.o: $(hdrdir)/ruby/internal/attr/noinline.h
+fs.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+fs.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+fs.o: $(hdrdir)/ruby/internal/attr/pure.h
+fs.o: $(hdrdir)/ruby/internal/attr/restrict.h
+fs.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+fs.o: $(hdrdir)/ruby/internal/attr/warning.h
+fs.o: $(hdrdir)/ruby/internal/attr/weakref.h
+fs.o: $(hdrdir)/ruby/internal/cast.h
+fs.o: $(hdrdir)/ruby/internal/compiler_is.h
+fs.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+fs.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+fs.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+fs.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+fs.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+fs.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+fs.o: $(hdrdir)/ruby/internal/compiler_since.h
+fs.o: $(hdrdir)/ruby/internal/config.h
+fs.o: $(hdrdir)/ruby/internal/constant_p.h
+fs.o: $(hdrdir)/ruby/internal/core.h
+fs.o: $(hdrdir)/ruby/internal/core/rarray.h
+fs.o: $(hdrdir)/ruby/internal/core/rbasic.h
+fs.o: $(hdrdir)/ruby/internal/core/rbignum.h
+fs.o: $(hdrdir)/ruby/internal/core/rclass.h
+fs.o: $(hdrdir)/ruby/internal/core/rdata.h
+fs.o: $(hdrdir)/ruby/internal/core/rfile.h
+fs.o: $(hdrdir)/ruby/internal/core/rhash.h
+fs.o: $(hdrdir)/ruby/internal/core/robject.h
+fs.o: $(hdrdir)/ruby/internal/core/rregexp.h
+fs.o: $(hdrdir)/ruby/internal/core/rstring.h
+fs.o: $(hdrdir)/ruby/internal/core/rstruct.h
+fs.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+fs.o: $(hdrdir)/ruby/internal/ctype.h
+fs.o: $(hdrdir)/ruby/internal/dllexport.h
+fs.o: $(hdrdir)/ruby/internal/dosish.h
+fs.o: $(hdrdir)/ruby/internal/error.h
+fs.o: $(hdrdir)/ruby/internal/eval.h
+fs.o: $(hdrdir)/ruby/internal/event.h
+fs.o: $(hdrdir)/ruby/internal/fl_type.h
+fs.o: $(hdrdir)/ruby/internal/gc.h
+fs.o: $(hdrdir)/ruby/internal/glob.h
+fs.o: $(hdrdir)/ruby/internal/globals.h
+fs.o: $(hdrdir)/ruby/internal/has/attribute.h
+fs.o: $(hdrdir)/ruby/internal/has/builtin.h
+fs.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+fs.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+fs.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+fs.o: $(hdrdir)/ruby/internal/has/extension.h
+fs.o: $(hdrdir)/ruby/internal/has/feature.h
+fs.o: $(hdrdir)/ruby/internal/has/warning.h
+fs.o: $(hdrdir)/ruby/internal/intern/array.h
+fs.o: $(hdrdir)/ruby/internal/intern/bignum.h
+fs.o: $(hdrdir)/ruby/internal/intern/class.h
+fs.o: $(hdrdir)/ruby/internal/intern/compar.h
+fs.o: $(hdrdir)/ruby/internal/intern/complex.h
+fs.o: $(hdrdir)/ruby/internal/intern/cont.h
+fs.o: $(hdrdir)/ruby/internal/intern/dir.h
+fs.o: $(hdrdir)/ruby/internal/intern/enum.h
+fs.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+fs.o: $(hdrdir)/ruby/internal/intern/error.h
+fs.o: $(hdrdir)/ruby/internal/intern/eval.h
+fs.o: $(hdrdir)/ruby/internal/intern/file.h
+fs.o: $(hdrdir)/ruby/internal/intern/gc.h
+fs.o: $(hdrdir)/ruby/internal/intern/hash.h
+fs.o: $(hdrdir)/ruby/internal/intern/io.h
+fs.o: $(hdrdir)/ruby/internal/intern/load.h
+fs.o: $(hdrdir)/ruby/internal/intern/marshal.h
+fs.o: $(hdrdir)/ruby/internal/intern/numeric.h
+fs.o: $(hdrdir)/ruby/internal/intern/object.h
+fs.o: $(hdrdir)/ruby/internal/intern/parse.h
+fs.o: $(hdrdir)/ruby/internal/intern/proc.h
+fs.o: $(hdrdir)/ruby/internal/intern/process.h
+fs.o: $(hdrdir)/ruby/internal/intern/random.h
+fs.o: $(hdrdir)/ruby/internal/intern/range.h
+fs.o: $(hdrdir)/ruby/internal/intern/rational.h
+fs.o: $(hdrdir)/ruby/internal/intern/re.h
+fs.o: $(hdrdir)/ruby/internal/intern/ruby.h
+fs.o: $(hdrdir)/ruby/internal/intern/select.h
+fs.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+fs.o: $(hdrdir)/ruby/internal/intern/signal.h
+fs.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+fs.o: $(hdrdir)/ruby/internal/intern/string.h
+fs.o: $(hdrdir)/ruby/internal/intern/struct.h
+fs.o: $(hdrdir)/ruby/internal/intern/thread.h
+fs.o: $(hdrdir)/ruby/internal/intern/time.h
+fs.o: $(hdrdir)/ruby/internal/intern/variable.h
+fs.o: $(hdrdir)/ruby/internal/intern/vm.h
+fs.o: $(hdrdir)/ruby/internal/interpreter.h
+fs.o: $(hdrdir)/ruby/internal/iterator.h
+fs.o: $(hdrdir)/ruby/internal/memory.h
+fs.o: $(hdrdir)/ruby/internal/method.h
+fs.o: $(hdrdir)/ruby/internal/module.h
+fs.o: $(hdrdir)/ruby/internal/newobj.h
+fs.o: $(hdrdir)/ruby/internal/rgengc.h
+fs.o: $(hdrdir)/ruby/internal/scan_args.h
+fs.o: $(hdrdir)/ruby/internal/special_consts.h
+fs.o: $(hdrdir)/ruby/internal/static_assert.h
+fs.o: $(hdrdir)/ruby/internal/stdalign.h
+fs.o: $(hdrdir)/ruby/internal/stdbool.h
+fs.o: $(hdrdir)/ruby/internal/symbol.h
+fs.o: $(hdrdir)/ruby/internal/token_paste.h
+fs.o: $(hdrdir)/ruby/internal/value.h
+fs.o: $(hdrdir)/ruby/internal/value_type.h
+fs.o: $(hdrdir)/ruby/internal/variable.h
+fs.o: $(hdrdir)/ruby/internal/warning_push.h
+fs.o: $(hdrdir)/ruby/internal/xmalloc.h
+fs.o: $(hdrdir)/ruby/assert.h
fs.o: $(hdrdir)/ruby/backward.h
+fs.o: $(hdrdir)/ruby/backward/2/assume.h
+fs.o: $(hdrdir)/ruby/backward/2/attributes.h
+fs.o: $(hdrdir)/ruby/backward/2/bool.h
+fs.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+fs.o: $(hdrdir)/ruby/backward/2/inttypes.h
+fs.o: $(hdrdir)/ruby/backward/2/limits.h
+fs.o: $(hdrdir)/ruby/backward/2/long_long.h
+fs.o: $(hdrdir)/ruby/backward/2/stdalign.h
+fs.o: $(hdrdir)/ruby/backward/2/stdarg.h
fs.o: $(hdrdir)/ruby/defines.h
fs.o: $(hdrdir)/ruby/encoding.h
fs.o: $(hdrdir)/ruby/intern.h
@@ -15,18 +165,318 @@ fs.o: $(hdrdir)/ruby/subst.h
fs.o: fs.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
stat.o: $(RUBY_EXTCONF_H)
stat.o: $(arch_hdrdir)/ruby/config.h
+stat.o: $(hdrdir)/ruby/internal/anyargs.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+stat.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+stat.o: $(hdrdir)/ruby/internal/assume.h
+stat.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+stat.o: $(hdrdir)/ruby/internal/attr/artificial.h
+stat.o: $(hdrdir)/ruby/internal/attr/cold.h
+stat.o: $(hdrdir)/ruby/internal/attr/const.h
+stat.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+stat.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+stat.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+stat.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+stat.o: $(hdrdir)/ruby/internal/attr/error.h
+stat.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+stat.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+stat.o: $(hdrdir)/ruby/internal/attr/format.h
+stat.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+stat.o: $(hdrdir)/ruby/internal/attr/noalias.h
+stat.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+stat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+stat.o: $(hdrdir)/ruby/internal/attr/noinline.h
+stat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+stat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+stat.o: $(hdrdir)/ruby/internal/attr/pure.h
+stat.o: $(hdrdir)/ruby/internal/attr/restrict.h
+stat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+stat.o: $(hdrdir)/ruby/internal/attr/warning.h
+stat.o: $(hdrdir)/ruby/internal/attr/weakref.h
+stat.o: $(hdrdir)/ruby/internal/cast.h
+stat.o: $(hdrdir)/ruby/internal/compiler_is.h
+stat.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+stat.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+stat.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+stat.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+stat.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+stat.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+stat.o: $(hdrdir)/ruby/internal/compiler_since.h
+stat.o: $(hdrdir)/ruby/internal/config.h
+stat.o: $(hdrdir)/ruby/internal/constant_p.h
+stat.o: $(hdrdir)/ruby/internal/core.h
+stat.o: $(hdrdir)/ruby/internal/core/rarray.h
+stat.o: $(hdrdir)/ruby/internal/core/rbasic.h
+stat.o: $(hdrdir)/ruby/internal/core/rbignum.h
+stat.o: $(hdrdir)/ruby/internal/core/rclass.h
+stat.o: $(hdrdir)/ruby/internal/core/rdata.h
+stat.o: $(hdrdir)/ruby/internal/core/rfile.h
+stat.o: $(hdrdir)/ruby/internal/core/rhash.h
+stat.o: $(hdrdir)/ruby/internal/core/robject.h
+stat.o: $(hdrdir)/ruby/internal/core/rregexp.h
+stat.o: $(hdrdir)/ruby/internal/core/rstring.h
+stat.o: $(hdrdir)/ruby/internal/core/rstruct.h
+stat.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+stat.o: $(hdrdir)/ruby/internal/ctype.h
+stat.o: $(hdrdir)/ruby/internal/dllexport.h
+stat.o: $(hdrdir)/ruby/internal/dosish.h
+stat.o: $(hdrdir)/ruby/internal/error.h
+stat.o: $(hdrdir)/ruby/internal/eval.h
+stat.o: $(hdrdir)/ruby/internal/event.h
+stat.o: $(hdrdir)/ruby/internal/fl_type.h
+stat.o: $(hdrdir)/ruby/internal/gc.h
+stat.o: $(hdrdir)/ruby/internal/glob.h
+stat.o: $(hdrdir)/ruby/internal/globals.h
+stat.o: $(hdrdir)/ruby/internal/has/attribute.h
+stat.o: $(hdrdir)/ruby/internal/has/builtin.h
+stat.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+stat.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+stat.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+stat.o: $(hdrdir)/ruby/internal/has/extension.h
+stat.o: $(hdrdir)/ruby/internal/has/feature.h
+stat.o: $(hdrdir)/ruby/internal/has/warning.h
+stat.o: $(hdrdir)/ruby/internal/intern/array.h
+stat.o: $(hdrdir)/ruby/internal/intern/bignum.h
+stat.o: $(hdrdir)/ruby/internal/intern/class.h
+stat.o: $(hdrdir)/ruby/internal/intern/compar.h
+stat.o: $(hdrdir)/ruby/internal/intern/complex.h
+stat.o: $(hdrdir)/ruby/internal/intern/cont.h
+stat.o: $(hdrdir)/ruby/internal/intern/dir.h
+stat.o: $(hdrdir)/ruby/internal/intern/enum.h
+stat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+stat.o: $(hdrdir)/ruby/internal/intern/error.h
+stat.o: $(hdrdir)/ruby/internal/intern/eval.h
+stat.o: $(hdrdir)/ruby/internal/intern/file.h
+stat.o: $(hdrdir)/ruby/internal/intern/gc.h
+stat.o: $(hdrdir)/ruby/internal/intern/hash.h
+stat.o: $(hdrdir)/ruby/internal/intern/io.h
+stat.o: $(hdrdir)/ruby/internal/intern/load.h
+stat.o: $(hdrdir)/ruby/internal/intern/marshal.h
+stat.o: $(hdrdir)/ruby/internal/intern/numeric.h
+stat.o: $(hdrdir)/ruby/internal/intern/object.h
+stat.o: $(hdrdir)/ruby/internal/intern/parse.h
+stat.o: $(hdrdir)/ruby/internal/intern/proc.h
+stat.o: $(hdrdir)/ruby/internal/intern/process.h
+stat.o: $(hdrdir)/ruby/internal/intern/random.h
+stat.o: $(hdrdir)/ruby/internal/intern/range.h
+stat.o: $(hdrdir)/ruby/internal/intern/rational.h
+stat.o: $(hdrdir)/ruby/internal/intern/re.h
+stat.o: $(hdrdir)/ruby/internal/intern/ruby.h
+stat.o: $(hdrdir)/ruby/internal/intern/select.h
+stat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+stat.o: $(hdrdir)/ruby/internal/intern/signal.h
+stat.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+stat.o: $(hdrdir)/ruby/internal/intern/string.h
+stat.o: $(hdrdir)/ruby/internal/intern/struct.h
+stat.o: $(hdrdir)/ruby/internal/intern/thread.h
+stat.o: $(hdrdir)/ruby/internal/intern/time.h
+stat.o: $(hdrdir)/ruby/internal/intern/variable.h
+stat.o: $(hdrdir)/ruby/internal/intern/vm.h
+stat.o: $(hdrdir)/ruby/internal/interpreter.h
+stat.o: $(hdrdir)/ruby/internal/iterator.h
+stat.o: $(hdrdir)/ruby/internal/memory.h
+stat.o: $(hdrdir)/ruby/internal/method.h
+stat.o: $(hdrdir)/ruby/internal/module.h
+stat.o: $(hdrdir)/ruby/internal/newobj.h
+stat.o: $(hdrdir)/ruby/internal/rgengc.h
+stat.o: $(hdrdir)/ruby/internal/scan_args.h
+stat.o: $(hdrdir)/ruby/internal/special_consts.h
+stat.o: $(hdrdir)/ruby/internal/static_assert.h
+stat.o: $(hdrdir)/ruby/internal/stdalign.h
+stat.o: $(hdrdir)/ruby/internal/stdbool.h
+stat.o: $(hdrdir)/ruby/internal/symbol.h
+stat.o: $(hdrdir)/ruby/internal/token_paste.h
+stat.o: $(hdrdir)/ruby/internal/value.h
+stat.o: $(hdrdir)/ruby/internal/value_type.h
+stat.o: $(hdrdir)/ruby/internal/variable.h
+stat.o: $(hdrdir)/ruby/internal/warning_push.h
+stat.o: $(hdrdir)/ruby/internal/xmalloc.h
+stat.o: $(hdrdir)/ruby/assert.h
stat.o: $(hdrdir)/ruby/backward.h
+stat.o: $(hdrdir)/ruby/backward/2/assume.h
+stat.o: $(hdrdir)/ruby/backward/2/attributes.h
+stat.o: $(hdrdir)/ruby/backward/2/bool.h
+stat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+stat.o: $(hdrdir)/ruby/backward/2/inttypes.h
+stat.o: $(hdrdir)/ruby/backward/2/limits.h
+stat.o: $(hdrdir)/ruby/backward/2/long_long.h
+stat.o: $(hdrdir)/ruby/backward/2/stdalign.h
+stat.o: $(hdrdir)/ruby/backward/2/stdarg.h
stat.o: $(hdrdir)/ruby/defines.h
stat.o: $(hdrdir)/ruby/encoding.h
stat.o: $(hdrdir)/ruby/intern.h
diff --git a/ext/-test-/file/fs.c b/ext/-test-/file/fs.c
index c9c3473257..63d2356d76 100644
--- a/ext/-test-/file/fs.c
+++ b/ext/-test-/file/fs.c
@@ -89,6 +89,9 @@ get_noatime_p(VALUE self, VALUE str)
rb_sys_fail_str(str);
}
# ifdef HAVE_STRUCT_STATFS_F_FLAGS
+# ifdef MNT_STRICTATIME
+ if (!(st.f_flags & MNT_STRICTATIME)) return Qtrue;
+# endif
# ifdef MNT_NOATIME
return st.f_flags & MNT_NOATIME ? Qtrue : Qfalse;
# elif defined(ST_NOATIME)
diff --git a/ext/-test-/float/depend b/ext/-test-/float/depend
index dff14550f7..066f008783 100644
--- a/ext/-test-/float/depend
+++ b/ext/-test-/float/depend
@@ -1,3 +1,328 @@
-$(OBJS): $(HDRS) $(ruby_headers)
-
+# for FreeBSD make
nextafter.o: nextafter.c $(top_srcdir)/missing/nextafter.c
+
+# AUTOGENERATED DEPENDENCIES START
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+nextafter.o: $(RUBY_EXTCONF_H)
+nextafter.o: $(arch_hdrdir)/ruby/config.h
+nextafter.o: $(hdrdir)/ruby.h
+nextafter.o: $(hdrdir)/ruby/internal/anyargs.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+nextafter.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+nextafter.o: $(hdrdir)/ruby/internal/assume.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/artificial.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/cold.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/const.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/error.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/format.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/noalias.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/noinline.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/pure.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/restrict.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/warning.h
+nextafter.o: $(hdrdir)/ruby/internal/attr/weakref.h
+nextafter.o: $(hdrdir)/ruby/internal/cast.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_is.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+nextafter.o: $(hdrdir)/ruby/internal/compiler_since.h
+nextafter.o: $(hdrdir)/ruby/internal/config.h
+nextafter.o: $(hdrdir)/ruby/internal/constant_p.h
+nextafter.o: $(hdrdir)/ruby/internal/core.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rarray.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rbasic.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rbignum.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rclass.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rdata.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rfile.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rhash.h
+nextafter.o: $(hdrdir)/ruby/internal/core/robject.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rregexp.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rstring.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rstruct.h
+nextafter.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+nextafter.o: $(hdrdir)/ruby/internal/ctype.h
+nextafter.o: $(hdrdir)/ruby/internal/dllexport.h
+nextafter.o: $(hdrdir)/ruby/internal/dosish.h
+nextafter.o: $(hdrdir)/ruby/internal/error.h
+nextafter.o: $(hdrdir)/ruby/internal/eval.h
+nextafter.o: $(hdrdir)/ruby/internal/event.h
+nextafter.o: $(hdrdir)/ruby/internal/fl_type.h
+nextafter.o: $(hdrdir)/ruby/internal/gc.h
+nextafter.o: $(hdrdir)/ruby/internal/glob.h
+nextafter.o: $(hdrdir)/ruby/internal/globals.h
+nextafter.o: $(hdrdir)/ruby/internal/has/attribute.h
+nextafter.o: $(hdrdir)/ruby/internal/has/builtin.h
+nextafter.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+nextafter.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+nextafter.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+nextafter.o: $(hdrdir)/ruby/internal/has/extension.h
+nextafter.o: $(hdrdir)/ruby/internal/has/feature.h
+nextafter.o: $(hdrdir)/ruby/internal/has/warning.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/array.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/bignum.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/class.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/compar.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/complex.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/cont.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/dir.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/enum.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/error.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/eval.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/file.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/gc.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/hash.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/io.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/load.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/marshal.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/numeric.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/object.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/parse.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/proc.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/process.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/random.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/range.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/rational.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/re.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/ruby.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/select.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/signal.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/string.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/struct.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/thread.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/time.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/variable.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/vm.h
+nextafter.o: $(hdrdir)/ruby/internal/interpreter.h
+nextafter.o: $(hdrdir)/ruby/internal/iterator.h
+nextafter.o: $(hdrdir)/ruby/internal/memory.h
+nextafter.o: $(hdrdir)/ruby/internal/method.h
+nextafter.o: $(hdrdir)/ruby/internal/module.h
+nextafter.o: $(hdrdir)/ruby/internal/newobj.h
+nextafter.o: $(hdrdir)/ruby/internal/rgengc.h
+nextafter.o: $(hdrdir)/ruby/internal/scan_args.h
+nextafter.o: $(hdrdir)/ruby/internal/special_consts.h
+nextafter.o: $(hdrdir)/ruby/internal/static_assert.h
+nextafter.o: $(hdrdir)/ruby/internal/stdalign.h
+nextafter.o: $(hdrdir)/ruby/internal/stdbool.h
+nextafter.o: $(hdrdir)/ruby/internal/symbol.h
+nextafter.o: $(hdrdir)/ruby/internal/token_paste.h
+nextafter.o: $(hdrdir)/ruby/internal/value.h
+nextafter.o: $(hdrdir)/ruby/internal/value_type.h
+nextafter.o: $(hdrdir)/ruby/internal/variable.h
+nextafter.o: $(hdrdir)/ruby/internal/warning_push.h
+nextafter.o: $(hdrdir)/ruby/internal/xmalloc.h
+nextafter.o: $(hdrdir)/ruby/assert.h
+nextafter.o: $(hdrdir)/ruby/backward.h
+nextafter.o: $(hdrdir)/ruby/backward/2/assume.h
+nextafter.o: $(hdrdir)/ruby/backward/2/attributes.h
+nextafter.o: $(hdrdir)/ruby/backward/2/bool.h
+nextafter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+nextafter.o: $(hdrdir)/ruby/backward/2/inttypes.h
+nextafter.o: $(hdrdir)/ruby/backward/2/limits.h
+nextafter.o: $(hdrdir)/ruby/backward/2/long_long.h
+nextafter.o: $(hdrdir)/ruby/backward/2/stdalign.h
+nextafter.o: $(hdrdir)/ruby/backward/2/stdarg.h
+nextafter.o: $(hdrdir)/ruby/defines.h
+nextafter.o: $(hdrdir)/ruby/intern.h
+nextafter.o: $(hdrdir)/ruby/missing.h
+nextafter.o: $(hdrdir)/ruby/ruby.h
+nextafter.o: $(hdrdir)/ruby/st.h
+nextafter.o: $(hdrdir)/ruby/subst.h
+nextafter.o: $(top_srcdir)/missing/nextafter.c
+nextafter.o: nextafter.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/funcall/depend b/ext/-test-/funcall/depend
new file mode 100644
index 0000000000..1fdf867fac
--- /dev/null
+++ b/ext/-test-/funcall/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+funcall.o: $(RUBY_EXTCONF_H)
+funcall.o: $(arch_hdrdir)/ruby/config.h
+funcall.o: $(hdrdir)/ruby.h
+funcall.o: $(hdrdir)/ruby/internal/anyargs.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+funcall.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+funcall.o: $(hdrdir)/ruby/internal/assume.h
+funcall.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+funcall.o: $(hdrdir)/ruby/internal/attr/artificial.h
+funcall.o: $(hdrdir)/ruby/internal/attr/cold.h
+funcall.o: $(hdrdir)/ruby/internal/attr/const.h
+funcall.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+funcall.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+funcall.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+funcall.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+funcall.o: $(hdrdir)/ruby/internal/attr/error.h
+funcall.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+funcall.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+funcall.o: $(hdrdir)/ruby/internal/attr/format.h
+funcall.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+funcall.o: $(hdrdir)/ruby/internal/attr/noalias.h
+funcall.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+funcall.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+funcall.o: $(hdrdir)/ruby/internal/attr/noinline.h
+funcall.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+funcall.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+funcall.o: $(hdrdir)/ruby/internal/attr/pure.h
+funcall.o: $(hdrdir)/ruby/internal/attr/restrict.h
+funcall.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+funcall.o: $(hdrdir)/ruby/internal/attr/warning.h
+funcall.o: $(hdrdir)/ruby/internal/attr/weakref.h
+funcall.o: $(hdrdir)/ruby/internal/cast.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_is.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+funcall.o: $(hdrdir)/ruby/internal/compiler_since.h
+funcall.o: $(hdrdir)/ruby/internal/config.h
+funcall.o: $(hdrdir)/ruby/internal/constant_p.h
+funcall.o: $(hdrdir)/ruby/internal/core.h
+funcall.o: $(hdrdir)/ruby/internal/core/rarray.h
+funcall.o: $(hdrdir)/ruby/internal/core/rbasic.h
+funcall.o: $(hdrdir)/ruby/internal/core/rbignum.h
+funcall.o: $(hdrdir)/ruby/internal/core/rclass.h
+funcall.o: $(hdrdir)/ruby/internal/core/rdata.h
+funcall.o: $(hdrdir)/ruby/internal/core/rfile.h
+funcall.o: $(hdrdir)/ruby/internal/core/rhash.h
+funcall.o: $(hdrdir)/ruby/internal/core/robject.h
+funcall.o: $(hdrdir)/ruby/internal/core/rregexp.h
+funcall.o: $(hdrdir)/ruby/internal/core/rstring.h
+funcall.o: $(hdrdir)/ruby/internal/core/rstruct.h
+funcall.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+funcall.o: $(hdrdir)/ruby/internal/ctype.h
+funcall.o: $(hdrdir)/ruby/internal/dllexport.h
+funcall.o: $(hdrdir)/ruby/internal/dosish.h
+funcall.o: $(hdrdir)/ruby/internal/error.h
+funcall.o: $(hdrdir)/ruby/internal/eval.h
+funcall.o: $(hdrdir)/ruby/internal/event.h
+funcall.o: $(hdrdir)/ruby/internal/fl_type.h
+funcall.o: $(hdrdir)/ruby/internal/gc.h
+funcall.o: $(hdrdir)/ruby/internal/glob.h
+funcall.o: $(hdrdir)/ruby/internal/globals.h
+funcall.o: $(hdrdir)/ruby/internal/has/attribute.h
+funcall.o: $(hdrdir)/ruby/internal/has/builtin.h
+funcall.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+funcall.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+funcall.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+funcall.o: $(hdrdir)/ruby/internal/has/extension.h
+funcall.o: $(hdrdir)/ruby/internal/has/feature.h
+funcall.o: $(hdrdir)/ruby/internal/has/warning.h
+funcall.o: $(hdrdir)/ruby/internal/intern/array.h
+funcall.o: $(hdrdir)/ruby/internal/intern/bignum.h
+funcall.o: $(hdrdir)/ruby/internal/intern/class.h
+funcall.o: $(hdrdir)/ruby/internal/intern/compar.h
+funcall.o: $(hdrdir)/ruby/internal/intern/complex.h
+funcall.o: $(hdrdir)/ruby/internal/intern/cont.h
+funcall.o: $(hdrdir)/ruby/internal/intern/dir.h
+funcall.o: $(hdrdir)/ruby/internal/intern/enum.h
+funcall.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+funcall.o: $(hdrdir)/ruby/internal/intern/error.h
+funcall.o: $(hdrdir)/ruby/internal/intern/eval.h
+funcall.o: $(hdrdir)/ruby/internal/intern/file.h
+funcall.o: $(hdrdir)/ruby/internal/intern/gc.h
+funcall.o: $(hdrdir)/ruby/internal/intern/hash.h
+funcall.o: $(hdrdir)/ruby/internal/intern/io.h
+funcall.o: $(hdrdir)/ruby/internal/intern/load.h
+funcall.o: $(hdrdir)/ruby/internal/intern/marshal.h
+funcall.o: $(hdrdir)/ruby/internal/intern/numeric.h
+funcall.o: $(hdrdir)/ruby/internal/intern/object.h
+funcall.o: $(hdrdir)/ruby/internal/intern/parse.h
+funcall.o: $(hdrdir)/ruby/internal/intern/proc.h
+funcall.o: $(hdrdir)/ruby/internal/intern/process.h
+funcall.o: $(hdrdir)/ruby/internal/intern/random.h
+funcall.o: $(hdrdir)/ruby/internal/intern/range.h
+funcall.o: $(hdrdir)/ruby/internal/intern/rational.h
+funcall.o: $(hdrdir)/ruby/internal/intern/re.h
+funcall.o: $(hdrdir)/ruby/internal/intern/ruby.h
+funcall.o: $(hdrdir)/ruby/internal/intern/select.h
+funcall.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+funcall.o: $(hdrdir)/ruby/internal/intern/signal.h
+funcall.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+funcall.o: $(hdrdir)/ruby/internal/intern/string.h
+funcall.o: $(hdrdir)/ruby/internal/intern/struct.h
+funcall.o: $(hdrdir)/ruby/internal/intern/thread.h
+funcall.o: $(hdrdir)/ruby/internal/intern/time.h
+funcall.o: $(hdrdir)/ruby/internal/intern/variable.h
+funcall.o: $(hdrdir)/ruby/internal/intern/vm.h
+funcall.o: $(hdrdir)/ruby/internal/interpreter.h
+funcall.o: $(hdrdir)/ruby/internal/iterator.h
+funcall.o: $(hdrdir)/ruby/internal/memory.h
+funcall.o: $(hdrdir)/ruby/internal/method.h
+funcall.o: $(hdrdir)/ruby/internal/module.h
+funcall.o: $(hdrdir)/ruby/internal/newobj.h
+funcall.o: $(hdrdir)/ruby/internal/rgengc.h
+funcall.o: $(hdrdir)/ruby/internal/scan_args.h
+funcall.o: $(hdrdir)/ruby/internal/special_consts.h
+funcall.o: $(hdrdir)/ruby/internal/static_assert.h
+funcall.o: $(hdrdir)/ruby/internal/stdalign.h
+funcall.o: $(hdrdir)/ruby/internal/stdbool.h
+funcall.o: $(hdrdir)/ruby/internal/symbol.h
+funcall.o: $(hdrdir)/ruby/internal/token_paste.h
+funcall.o: $(hdrdir)/ruby/internal/value.h
+funcall.o: $(hdrdir)/ruby/internal/value_type.h
+funcall.o: $(hdrdir)/ruby/internal/variable.h
+funcall.o: $(hdrdir)/ruby/internal/warning_push.h
+funcall.o: $(hdrdir)/ruby/internal/xmalloc.h
+funcall.o: $(hdrdir)/ruby/assert.h
+funcall.o: $(hdrdir)/ruby/backward.h
+funcall.o: $(hdrdir)/ruby/backward/2/assume.h
+funcall.o: $(hdrdir)/ruby/backward/2/attributes.h
+funcall.o: $(hdrdir)/ruby/backward/2/bool.h
+funcall.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+funcall.o: $(hdrdir)/ruby/backward/2/inttypes.h
+funcall.o: $(hdrdir)/ruby/backward/2/limits.h
+funcall.o: $(hdrdir)/ruby/backward/2/long_long.h
+funcall.o: $(hdrdir)/ruby/backward/2/stdalign.h
+funcall.o: $(hdrdir)/ruby/backward/2/stdarg.h
+funcall.o: $(hdrdir)/ruby/defines.h
+funcall.o: $(hdrdir)/ruby/intern.h
+funcall.o: $(hdrdir)/ruby/missing.h
+funcall.o: $(hdrdir)/ruby/ruby.h
+funcall.o: $(hdrdir)/ruby/st.h
+funcall.o: $(hdrdir)/ruby/subst.h
+funcall.o: funcall.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/funcall/funcall.c b/ext/-test-/funcall/funcall.c
new file mode 100644
index 0000000000..43521bf2e9
--- /dev/null
+++ b/ext/-test-/funcall/funcall.c
@@ -0,0 +1,72 @@
+#include "ruby.h"
+
+static VALUE
+with_funcall2(int argc, VALUE *argv, VALUE self)
+{
+ return rb_funcallv(self, rb_intern("target"), argc, argv);
+}
+
+static VALUE
+with_funcall_passing_block(int argc, VALUE *argv, VALUE self)
+{
+ return rb_funcall_passing_block(self, rb_intern("target"), argc, argv);
+}
+
+static VALUE
+with_funcall_passing_block_kw(int argc, VALUE *argv, VALUE self)
+{
+ return rb_funcall_passing_block_kw(self, rb_intern("target"), argc-1, argv+1, FIX2INT(argv[0]));
+}
+
+static VALUE
+with_funcallv_public_kw(int argc, VALUE *argv, VALUE self)
+{
+ return rb_funcallv_public_kw(argv[0], SYM2ID(argv[1]), argc-3, argv+3, FIX2INT(argv[2]));
+}
+
+static VALUE
+with_yield_splat_kw(int argc, VALUE *argv, VALUE self)
+{
+ return rb_yield_splat_kw(argv[1], FIX2INT(argv[0]));
+}
+
+static VALUE
+extra_args_name(VALUE self)
+{
+ /*
+ * at least clang 5.x gets tripped by the extra 0 arg
+ * [ruby-core:85266] [Bug #14425]
+ */
+ return rb_funcall(self, rb_intern("name"), 0, 0);
+}
+
+void
+Init_funcall(void)
+{
+ VALUE cTestFuncall = rb_path2class("TestFuncall");
+ VALUE cRelay = rb_define_module_under(cTestFuncall, "Relay");
+
+ rb_define_singleton_method(cRelay,
+ "with_funcall2",
+ with_funcall2,
+ -1);
+ rb_define_singleton_method(cRelay,
+ "with_funcall_passing_block_kw",
+ with_funcall_passing_block_kw,
+ -1);
+ rb_define_singleton_method(cRelay,
+ "with_funcall_passing_block",
+ with_funcall_passing_block,
+ -1);
+ rb_define_singleton_method(cRelay,
+ "with_funcallv_public_kw",
+ with_funcallv_public_kw,
+ -1);
+ rb_define_singleton_method(cRelay,
+ "with_yield_splat_kw",
+ with_yield_splat_kw,
+ -1);
+ rb_define_singleton_method(cTestFuncall, "extra_args_name",
+ extra_args_name,
+ 0);
+}
diff --git a/ext/-test-/funcall/passing_block.c b/ext/-test-/funcall/passing_block.c
deleted file mode 100644
index 70cb210831..0000000000
--- a/ext/-test-/funcall/passing_block.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "ruby.h"
-
-VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
-
-static VALUE
-with_funcall2(int argc, VALUE *argv, VALUE self)
-{
- return rb_funcallv(self, rb_intern("target"), argc, argv);
-}
-
-static VALUE
-with_funcall_passing_block(int argc, VALUE *argv, VALUE self)
-{
- return rb_funcall_passing_block(self, rb_intern("target"), argc, argv);
-}
-
-void
-Init_funcall(void)
-{
- VALUE cRelay = rb_path2class("TestFuncall::Relay");
-
- rb_define_singleton_method(cRelay,
- "with_funcall2",
- with_funcall2,
- -1);
- rb_define_singleton_method(cRelay,
- "with_funcall_passing_block",
- with_funcall_passing_block,
- -1);
-}
diff --git a/ext/-test-/gvl/call_without_gvl/call_without_gvl.c b/ext/-test-/gvl/call_without_gvl/call_without_gvl.c
index f3071d5768..d77c2f323e 100644
--- a/ext/-test-/gvl/call_without_gvl/call_without_gvl.c
+++ b/ext/-test-/gvl/call_without_gvl/call_without_gvl.c
@@ -27,8 +27,50 @@ thread_runnable_sleep(VALUE thread, VALUE timeout)
return thread;
}
+struct loop_ctl {
+ int notify_fd;
+ volatile int stop;
+};
+
+static void *
+do_loop(void *p)
+{
+ struct loop_ctl *ctl = p;
+
+ /* tell the waiting process they can interrupt us, now */
+ ssize_t err = write(ctl->notify_fd, "", 1);
+ if (err == -1) rb_bug("write error");
+
+ while (!ctl->stop) {
+ struct timeval tv = { 0, 10000 };
+ select(0, NULL, NULL, NULL, &tv);
+ }
+ return 0;
+}
+
+static void
+stop_set(void *p)
+{
+ struct loop_ctl *ctl = p;
+
+ ctl->stop = 1;
+}
+
+static VALUE
+thread_ubf_async_safe(VALUE thread, VALUE notify_fd)
+{
+ struct loop_ctl ctl;
+
+ ctl.notify_fd = NUM2INT(notify_fd);
+ ctl.stop = 0;
+
+ rb_nogvl(do_loop, &ctl, stop_set, &ctl, RB_NOGVL_UBF_ASYNC_SAFE);
+ return thread;
+}
+
void
Init_call_without_gvl(void)
{
rb_define_method(rb_cThread, "__runnable_sleep__", thread_runnable_sleep, 1);
+ rb_define_method(rb_cThread, "__ubf_async_safe__", thread_ubf_async_safe, 1);
}
diff --git a/ext/-test-/gvl/call_without_gvl/depend b/ext/-test-/gvl/call_without_gvl/depend
index 1f7443898d..8b606d2eb4 100644
--- a/ext/-test-/gvl/call_without_gvl/depend
+++ b/ext/-test-/gvl/call_without_gvl/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
call_without_gvl.o: $(RUBY_EXTCONF_H)
call_without_gvl.o: $(arch_hdrdir)/ruby/config.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/anyargs.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/assume.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/artificial.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/cold.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/const.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/error.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/format.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noalias.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noinline.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/pure.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/restrict.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/warning.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/attr/weakref.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/cast.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_is.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/compiler_since.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/config.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/constant_p.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rarray.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rbasic.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rbignum.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rclass.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rdata.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rfile.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rhash.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/robject.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rregexp.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rstring.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rstruct.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/ctype.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/dllexport.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/dosish.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/error.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/eval.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/event.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/fl_type.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/gc.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/glob.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/globals.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/attribute.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/builtin.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/extension.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/feature.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/has/warning.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/array.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/bignum.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/class.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/compar.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/complex.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/cont.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/dir.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/enum.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/error.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/eval.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/file.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/gc.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/hash.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/io.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/load.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/marshal.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/numeric.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/object.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/parse.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/proc.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/process.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/random.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/range.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/rational.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/re.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/ruby.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/select.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/signal.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/string.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/struct.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/thread.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/time.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/variable.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/vm.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/interpreter.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/iterator.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/memory.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/method.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/module.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/newobj.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/rgengc.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/scan_args.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/special_consts.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/static_assert.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/stdalign.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/stdbool.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/symbol.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/token_paste.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/value.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/value_type.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/variable.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/warning_push.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/xmalloc.h
+call_without_gvl.o: $(hdrdir)/ruby/assert.h
call_without_gvl.o: $(hdrdir)/ruby/backward.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/assume.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/attributes.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/bool.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/inttypes.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/limits.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/long_long.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/stdalign.h
+call_without_gvl.o: $(hdrdir)/ruby/backward/2/stdarg.h
call_without_gvl.o: $(hdrdir)/ruby/defines.h
call_without_gvl.o: $(hdrdir)/ruby/intern.h
call_without_gvl.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/-test-/hash/depend b/ext/-test-/hash/depend
new file mode 100644
index 0000000000..f4ea9ae5c3
--- /dev/null
+++ b/ext/-test-/hash/depend
@@ -0,0 +1,324 @@
+# AUTOGENERATED DEPENDENCIES START
+delete.o: $(RUBY_EXTCONF_H)
+delete.o: $(arch_hdrdir)/ruby/config.h
+delete.o: $(hdrdir)/ruby.h
+delete.o: $(hdrdir)/ruby/internal/anyargs.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+delete.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+delete.o: $(hdrdir)/ruby/internal/assume.h
+delete.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+delete.o: $(hdrdir)/ruby/internal/attr/artificial.h
+delete.o: $(hdrdir)/ruby/internal/attr/cold.h
+delete.o: $(hdrdir)/ruby/internal/attr/const.h
+delete.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+delete.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+delete.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+delete.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+delete.o: $(hdrdir)/ruby/internal/attr/error.h
+delete.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+delete.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+delete.o: $(hdrdir)/ruby/internal/attr/format.h
+delete.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+delete.o: $(hdrdir)/ruby/internal/attr/noalias.h
+delete.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+delete.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+delete.o: $(hdrdir)/ruby/internal/attr/noinline.h
+delete.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+delete.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+delete.o: $(hdrdir)/ruby/internal/attr/pure.h
+delete.o: $(hdrdir)/ruby/internal/attr/restrict.h
+delete.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+delete.o: $(hdrdir)/ruby/internal/attr/warning.h
+delete.o: $(hdrdir)/ruby/internal/attr/weakref.h
+delete.o: $(hdrdir)/ruby/internal/cast.h
+delete.o: $(hdrdir)/ruby/internal/compiler_is.h
+delete.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+delete.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+delete.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+delete.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+delete.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+delete.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+delete.o: $(hdrdir)/ruby/internal/compiler_since.h
+delete.o: $(hdrdir)/ruby/internal/config.h
+delete.o: $(hdrdir)/ruby/internal/constant_p.h
+delete.o: $(hdrdir)/ruby/internal/core.h
+delete.o: $(hdrdir)/ruby/internal/core/rarray.h
+delete.o: $(hdrdir)/ruby/internal/core/rbasic.h
+delete.o: $(hdrdir)/ruby/internal/core/rbignum.h
+delete.o: $(hdrdir)/ruby/internal/core/rclass.h
+delete.o: $(hdrdir)/ruby/internal/core/rdata.h
+delete.o: $(hdrdir)/ruby/internal/core/rfile.h
+delete.o: $(hdrdir)/ruby/internal/core/rhash.h
+delete.o: $(hdrdir)/ruby/internal/core/robject.h
+delete.o: $(hdrdir)/ruby/internal/core/rregexp.h
+delete.o: $(hdrdir)/ruby/internal/core/rstring.h
+delete.o: $(hdrdir)/ruby/internal/core/rstruct.h
+delete.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+delete.o: $(hdrdir)/ruby/internal/ctype.h
+delete.o: $(hdrdir)/ruby/internal/dllexport.h
+delete.o: $(hdrdir)/ruby/internal/dosish.h
+delete.o: $(hdrdir)/ruby/internal/error.h
+delete.o: $(hdrdir)/ruby/internal/eval.h
+delete.o: $(hdrdir)/ruby/internal/event.h
+delete.o: $(hdrdir)/ruby/internal/fl_type.h
+delete.o: $(hdrdir)/ruby/internal/gc.h
+delete.o: $(hdrdir)/ruby/internal/glob.h
+delete.o: $(hdrdir)/ruby/internal/globals.h
+delete.o: $(hdrdir)/ruby/internal/has/attribute.h
+delete.o: $(hdrdir)/ruby/internal/has/builtin.h
+delete.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+delete.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+delete.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+delete.o: $(hdrdir)/ruby/internal/has/extension.h
+delete.o: $(hdrdir)/ruby/internal/has/feature.h
+delete.o: $(hdrdir)/ruby/internal/has/warning.h
+delete.o: $(hdrdir)/ruby/internal/intern/array.h
+delete.o: $(hdrdir)/ruby/internal/intern/bignum.h
+delete.o: $(hdrdir)/ruby/internal/intern/class.h
+delete.o: $(hdrdir)/ruby/internal/intern/compar.h
+delete.o: $(hdrdir)/ruby/internal/intern/complex.h
+delete.o: $(hdrdir)/ruby/internal/intern/cont.h
+delete.o: $(hdrdir)/ruby/internal/intern/dir.h
+delete.o: $(hdrdir)/ruby/internal/intern/enum.h
+delete.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+delete.o: $(hdrdir)/ruby/internal/intern/error.h
+delete.o: $(hdrdir)/ruby/internal/intern/eval.h
+delete.o: $(hdrdir)/ruby/internal/intern/file.h
+delete.o: $(hdrdir)/ruby/internal/intern/gc.h
+delete.o: $(hdrdir)/ruby/internal/intern/hash.h
+delete.o: $(hdrdir)/ruby/internal/intern/io.h
+delete.o: $(hdrdir)/ruby/internal/intern/load.h
+delete.o: $(hdrdir)/ruby/internal/intern/marshal.h
+delete.o: $(hdrdir)/ruby/internal/intern/numeric.h
+delete.o: $(hdrdir)/ruby/internal/intern/object.h
+delete.o: $(hdrdir)/ruby/internal/intern/parse.h
+delete.o: $(hdrdir)/ruby/internal/intern/proc.h
+delete.o: $(hdrdir)/ruby/internal/intern/process.h
+delete.o: $(hdrdir)/ruby/internal/intern/random.h
+delete.o: $(hdrdir)/ruby/internal/intern/range.h
+delete.o: $(hdrdir)/ruby/internal/intern/rational.h
+delete.o: $(hdrdir)/ruby/internal/intern/re.h
+delete.o: $(hdrdir)/ruby/internal/intern/ruby.h
+delete.o: $(hdrdir)/ruby/internal/intern/select.h
+delete.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+delete.o: $(hdrdir)/ruby/internal/intern/signal.h
+delete.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+delete.o: $(hdrdir)/ruby/internal/intern/string.h
+delete.o: $(hdrdir)/ruby/internal/intern/struct.h
+delete.o: $(hdrdir)/ruby/internal/intern/thread.h
+delete.o: $(hdrdir)/ruby/internal/intern/time.h
+delete.o: $(hdrdir)/ruby/internal/intern/variable.h
+delete.o: $(hdrdir)/ruby/internal/intern/vm.h
+delete.o: $(hdrdir)/ruby/internal/interpreter.h
+delete.o: $(hdrdir)/ruby/internal/iterator.h
+delete.o: $(hdrdir)/ruby/internal/memory.h
+delete.o: $(hdrdir)/ruby/internal/method.h
+delete.o: $(hdrdir)/ruby/internal/module.h
+delete.o: $(hdrdir)/ruby/internal/newobj.h
+delete.o: $(hdrdir)/ruby/internal/rgengc.h
+delete.o: $(hdrdir)/ruby/internal/scan_args.h
+delete.o: $(hdrdir)/ruby/internal/special_consts.h
+delete.o: $(hdrdir)/ruby/internal/static_assert.h
+delete.o: $(hdrdir)/ruby/internal/stdalign.h
+delete.o: $(hdrdir)/ruby/internal/stdbool.h
+delete.o: $(hdrdir)/ruby/internal/symbol.h
+delete.o: $(hdrdir)/ruby/internal/token_paste.h
+delete.o: $(hdrdir)/ruby/internal/value.h
+delete.o: $(hdrdir)/ruby/internal/value_type.h
+delete.o: $(hdrdir)/ruby/internal/variable.h
+delete.o: $(hdrdir)/ruby/internal/warning_push.h
+delete.o: $(hdrdir)/ruby/internal/xmalloc.h
+delete.o: $(hdrdir)/ruby/assert.h
+delete.o: $(hdrdir)/ruby/backward.h
+delete.o: $(hdrdir)/ruby/backward/2/assume.h
+delete.o: $(hdrdir)/ruby/backward/2/attributes.h
+delete.o: $(hdrdir)/ruby/backward/2/bool.h
+delete.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+delete.o: $(hdrdir)/ruby/backward/2/inttypes.h
+delete.o: $(hdrdir)/ruby/backward/2/limits.h
+delete.o: $(hdrdir)/ruby/backward/2/long_long.h
+delete.o: $(hdrdir)/ruby/backward/2/stdalign.h
+delete.o: $(hdrdir)/ruby/backward/2/stdarg.h
+delete.o: $(hdrdir)/ruby/defines.h
+delete.o: $(hdrdir)/ruby/intern.h
+delete.o: $(hdrdir)/ruby/missing.h
+delete.o: $(hdrdir)/ruby/ruby.h
+delete.o: $(hdrdir)/ruby/st.h
+delete.o: $(hdrdir)/ruby/subst.h
+delete.o: delete.c
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/integer/core_ext.c b/ext/-test-/integer/core_ext.c
index 6d64cdb0c2..2062fa3afa 100644
--- a/ext/-test-/integer/core_ext.c
+++ b/ext/-test-/integer/core_ext.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/numeric.h"
static VALUE
int_bignum_p(VALUE self)
@@ -20,10 +20,17 @@ rb_int_to_bignum(VALUE x)
return x;
}
+static VALUE
+positive_pow(VALUE x, VALUE y)
+{
+ return rb_int_positive_pow(NUM2LONG(x), NUM2ULONG(y));
+}
+
void
Init_core_ext(VALUE klass)
{
rb_define_method(rb_cInteger, "bignum?", int_bignum_p, 0);
rb_define_method(rb_cInteger, "fixnum?", int_fixnum_p, 0);
rb_define_method(rb_cInteger, "to_bignum", rb_int_to_bignum, 0);
+ rb_define_method(rb_cInteger, "positive_pow", positive_pow, 1);
}
diff --git a/ext/-test-/integer/depend b/ext/-test-/integer/depend
index 48f04d9ca0..c68651d07c 100644
--- a/ext/-test-/integer/depend
+++ b/ext/-test-/integer/depend
@@ -1,40 +1,494 @@
# AUTOGENERATED DEPENDENCIES START
core_ext.o: $(RUBY_EXTCONF_H)
core_ext.o: $(arch_hdrdir)/ruby/config.h
+core_ext.o: $(hdrdir)/ruby.h
+core_ext.o: $(hdrdir)/ruby/internal/anyargs.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+core_ext.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+core_ext.o: $(hdrdir)/ruby/internal/assume.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/artificial.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/cold.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/const.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/error.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/format.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/noalias.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/noinline.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/pure.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/restrict.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/warning.h
+core_ext.o: $(hdrdir)/ruby/internal/attr/weakref.h
+core_ext.o: $(hdrdir)/ruby/internal/cast.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_is.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+core_ext.o: $(hdrdir)/ruby/internal/compiler_since.h
+core_ext.o: $(hdrdir)/ruby/internal/config.h
+core_ext.o: $(hdrdir)/ruby/internal/constant_p.h
+core_ext.o: $(hdrdir)/ruby/internal/core.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rarray.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rbasic.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rbignum.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rclass.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rdata.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rfile.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rhash.h
+core_ext.o: $(hdrdir)/ruby/internal/core/robject.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rregexp.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rstring.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rstruct.h
+core_ext.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+core_ext.o: $(hdrdir)/ruby/internal/ctype.h
+core_ext.o: $(hdrdir)/ruby/internal/dllexport.h
+core_ext.o: $(hdrdir)/ruby/internal/dosish.h
+core_ext.o: $(hdrdir)/ruby/internal/error.h
+core_ext.o: $(hdrdir)/ruby/internal/eval.h
+core_ext.o: $(hdrdir)/ruby/internal/event.h
+core_ext.o: $(hdrdir)/ruby/internal/fl_type.h
+core_ext.o: $(hdrdir)/ruby/internal/gc.h
+core_ext.o: $(hdrdir)/ruby/internal/glob.h
+core_ext.o: $(hdrdir)/ruby/internal/globals.h
+core_ext.o: $(hdrdir)/ruby/internal/has/attribute.h
+core_ext.o: $(hdrdir)/ruby/internal/has/builtin.h
+core_ext.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+core_ext.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+core_ext.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+core_ext.o: $(hdrdir)/ruby/internal/has/extension.h
+core_ext.o: $(hdrdir)/ruby/internal/has/feature.h
+core_ext.o: $(hdrdir)/ruby/internal/has/warning.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/array.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/bignum.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/class.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/compar.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/complex.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/cont.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/dir.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/enum.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/error.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/eval.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/file.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/gc.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/hash.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/io.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/load.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/marshal.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/numeric.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/object.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/parse.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/proc.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/process.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/random.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/range.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/rational.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/re.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/ruby.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/select.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/signal.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/string.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/struct.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/thread.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/time.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/variable.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/vm.h
+core_ext.o: $(hdrdir)/ruby/internal/interpreter.h
+core_ext.o: $(hdrdir)/ruby/internal/iterator.h
+core_ext.o: $(hdrdir)/ruby/internal/memory.h
+core_ext.o: $(hdrdir)/ruby/internal/method.h
+core_ext.o: $(hdrdir)/ruby/internal/module.h
+core_ext.o: $(hdrdir)/ruby/internal/newobj.h
+core_ext.o: $(hdrdir)/ruby/internal/rgengc.h
+core_ext.o: $(hdrdir)/ruby/internal/scan_args.h
+core_ext.o: $(hdrdir)/ruby/internal/special_consts.h
+core_ext.o: $(hdrdir)/ruby/internal/static_assert.h
+core_ext.o: $(hdrdir)/ruby/internal/stdalign.h
+core_ext.o: $(hdrdir)/ruby/internal/stdbool.h
+core_ext.o: $(hdrdir)/ruby/internal/symbol.h
+core_ext.o: $(hdrdir)/ruby/internal/token_paste.h
+core_ext.o: $(hdrdir)/ruby/internal/value.h
+core_ext.o: $(hdrdir)/ruby/internal/value_type.h
+core_ext.o: $(hdrdir)/ruby/internal/variable.h
+core_ext.o: $(hdrdir)/ruby/internal/warning_push.h
+core_ext.o: $(hdrdir)/ruby/internal/xmalloc.h
+core_ext.o: $(hdrdir)/ruby/assert.h
core_ext.o: $(hdrdir)/ruby/backward.h
+core_ext.o: $(hdrdir)/ruby/backward/2/assume.h
+core_ext.o: $(hdrdir)/ruby/backward/2/attributes.h
+core_ext.o: $(hdrdir)/ruby/backward/2/bool.h
+core_ext.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+core_ext.o: $(hdrdir)/ruby/backward/2/inttypes.h
+core_ext.o: $(hdrdir)/ruby/backward/2/limits.h
+core_ext.o: $(hdrdir)/ruby/backward/2/long_long.h
+core_ext.o: $(hdrdir)/ruby/backward/2/stdalign.h
+core_ext.o: $(hdrdir)/ruby/backward/2/stdarg.h
core_ext.o: $(hdrdir)/ruby/defines.h
-core_ext.o: $(hdrdir)/ruby/encoding.h
core_ext.o: $(hdrdir)/ruby/intern.h
-core_ext.o: $(hdrdir)/ruby/io.h
core_ext.o: $(hdrdir)/ruby/missing.h
-core_ext.o: $(hdrdir)/ruby/onigmo.h
-core_ext.o: $(hdrdir)/ruby/oniguruma.h
core_ext.o: $(hdrdir)/ruby/ruby.h
core_ext.o: $(hdrdir)/ruby/st.h
core_ext.o: $(hdrdir)/ruby/subst.h
-core_ext.o: $(top_srcdir)/include/ruby.h
core_ext.o: $(top_srcdir)/internal.h
+core_ext.o: $(top_srcdir)/internal/bignum.h
+core_ext.o: $(top_srcdir)/internal/bits.h
+core_ext.o: $(top_srcdir)/internal/compilers.h
+core_ext.o: $(top_srcdir)/internal/fixnum.h
+core_ext.o: $(top_srcdir)/internal/numeric.h
+core_ext.o: $(top_srcdir)/internal/serial.h
+core_ext.o: $(top_srcdir)/internal/static_assert.h
+core_ext.o: $(top_srcdir)/internal/vm.h
core_ext.o: core_ext.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
my_integer.o: $(RUBY_EXTCONF_H)
my_integer.o: $(arch_hdrdir)/ruby/config.h
+my_integer.o: $(hdrdir)/ruby.h
+my_integer.o: $(hdrdir)/ruby/internal/anyargs.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+my_integer.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+my_integer.o: $(hdrdir)/ruby/internal/assume.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/artificial.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/cold.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/const.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/error.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/format.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/noalias.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/noinline.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/pure.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/restrict.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/warning.h
+my_integer.o: $(hdrdir)/ruby/internal/attr/weakref.h
+my_integer.o: $(hdrdir)/ruby/internal/cast.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_is.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+my_integer.o: $(hdrdir)/ruby/internal/compiler_since.h
+my_integer.o: $(hdrdir)/ruby/internal/config.h
+my_integer.o: $(hdrdir)/ruby/internal/constant_p.h
+my_integer.o: $(hdrdir)/ruby/internal/core.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rarray.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rbasic.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rbignum.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rclass.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rdata.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rfile.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rhash.h
+my_integer.o: $(hdrdir)/ruby/internal/core/robject.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rregexp.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rstring.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rstruct.h
+my_integer.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+my_integer.o: $(hdrdir)/ruby/internal/ctype.h
+my_integer.o: $(hdrdir)/ruby/internal/dllexport.h
+my_integer.o: $(hdrdir)/ruby/internal/dosish.h
+my_integer.o: $(hdrdir)/ruby/internal/error.h
+my_integer.o: $(hdrdir)/ruby/internal/eval.h
+my_integer.o: $(hdrdir)/ruby/internal/event.h
+my_integer.o: $(hdrdir)/ruby/internal/fl_type.h
+my_integer.o: $(hdrdir)/ruby/internal/gc.h
+my_integer.o: $(hdrdir)/ruby/internal/glob.h
+my_integer.o: $(hdrdir)/ruby/internal/globals.h
+my_integer.o: $(hdrdir)/ruby/internal/has/attribute.h
+my_integer.o: $(hdrdir)/ruby/internal/has/builtin.h
+my_integer.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+my_integer.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+my_integer.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+my_integer.o: $(hdrdir)/ruby/internal/has/extension.h
+my_integer.o: $(hdrdir)/ruby/internal/has/feature.h
+my_integer.o: $(hdrdir)/ruby/internal/has/warning.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/array.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/bignum.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/class.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/compar.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/complex.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/cont.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/dir.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/enum.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/error.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/eval.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/file.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/gc.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/hash.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/io.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/load.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/marshal.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/numeric.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/object.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/parse.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/proc.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/process.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/random.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/range.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/rational.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/re.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/ruby.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/select.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/signal.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/string.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/struct.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/thread.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/time.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/variable.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/vm.h
+my_integer.o: $(hdrdir)/ruby/internal/interpreter.h
+my_integer.o: $(hdrdir)/ruby/internal/iterator.h
+my_integer.o: $(hdrdir)/ruby/internal/memory.h
+my_integer.o: $(hdrdir)/ruby/internal/method.h
+my_integer.o: $(hdrdir)/ruby/internal/module.h
+my_integer.o: $(hdrdir)/ruby/internal/newobj.h
+my_integer.o: $(hdrdir)/ruby/internal/rgengc.h
+my_integer.o: $(hdrdir)/ruby/internal/scan_args.h
+my_integer.o: $(hdrdir)/ruby/internal/special_consts.h
+my_integer.o: $(hdrdir)/ruby/internal/static_assert.h
+my_integer.o: $(hdrdir)/ruby/internal/stdalign.h
+my_integer.o: $(hdrdir)/ruby/internal/stdbool.h
+my_integer.o: $(hdrdir)/ruby/internal/symbol.h
+my_integer.o: $(hdrdir)/ruby/internal/token_paste.h
+my_integer.o: $(hdrdir)/ruby/internal/value.h
+my_integer.o: $(hdrdir)/ruby/internal/value_type.h
+my_integer.o: $(hdrdir)/ruby/internal/variable.h
+my_integer.o: $(hdrdir)/ruby/internal/warning_push.h
+my_integer.o: $(hdrdir)/ruby/internal/xmalloc.h
+my_integer.o: $(hdrdir)/ruby/assert.h
my_integer.o: $(hdrdir)/ruby/backward.h
+my_integer.o: $(hdrdir)/ruby/backward/2/assume.h
+my_integer.o: $(hdrdir)/ruby/backward/2/attributes.h
+my_integer.o: $(hdrdir)/ruby/backward/2/bool.h
+my_integer.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+my_integer.o: $(hdrdir)/ruby/backward/2/inttypes.h
+my_integer.o: $(hdrdir)/ruby/backward/2/limits.h
+my_integer.o: $(hdrdir)/ruby/backward/2/long_long.h
+my_integer.o: $(hdrdir)/ruby/backward/2/stdalign.h
+my_integer.o: $(hdrdir)/ruby/backward/2/stdarg.h
my_integer.o: $(hdrdir)/ruby/defines.h
my_integer.o: $(hdrdir)/ruby/intern.h
my_integer.o: $(hdrdir)/ruby/missing.h
my_integer.o: $(hdrdir)/ruby/ruby.h
my_integer.o: $(hdrdir)/ruby/st.h
my_integer.o: $(hdrdir)/ruby/subst.h
-my_integer.o: $(top_srcdir)/include/ruby.h
my_integer.o: my_integer.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/iseq_load/depend b/ext/-test-/iseq_load/depend
new file mode 100644
index 0000000000..007790a02e
--- /dev/null
+++ b/ext/-test-/iseq_load/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+iseq_load.o: $(RUBY_EXTCONF_H)
+iseq_load.o: $(arch_hdrdir)/ruby/config.h
+iseq_load.o: $(hdrdir)/ruby.h
+iseq_load.o: $(hdrdir)/ruby/internal/anyargs.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+iseq_load.o: $(hdrdir)/ruby/internal/assume.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/artificial.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/cold.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/const.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/error.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/format.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/noalias.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/noinline.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/pure.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/restrict.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/warning.h
+iseq_load.o: $(hdrdir)/ruby/internal/attr/weakref.h
+iseq_load.o: $(hdrdir)/ruby/internal/cast.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_is.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+iseq_load.o: $(hdrdir)/ruby/internal/compiler_since.h
+iseq_load.o: $(hdrdir)/ruby/internal/config.h
+iseq_load.o: $(hdrdir)/ruby/internal/constant_p.h
+iseq_load.o: $(hdrdir)/ruby/internal/core.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rarray.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rbasic.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rbignum.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rclass.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rdata.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rfile.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rhash.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/robject.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rregexp.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rstring.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rstruct.h
+iseq_load.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+iseq_load.o: $(hdrdir)/ruby/internal/ctype.h
+iseq_load.o: $(hdrdir)/ruby/internal/dllexport.h
+iseq_load.o: $(hdrdir)/ruby/internal/dosish.h
+iseq_load.o: $(hdrdir)/ruby/internal/error.h
+iseq_load.o: $(hdrdir)/ruby/internal/eval.h
+iseq_load.o: $(hdrdir)/ruby/internal/event.h
+iseq_load.o: $(hdrdir)/ruby/internal/fl_type.h
+iseq_load.o: $(hdrdir)/ruby/internal/gc.h
+iseq_load.o: $(hdrdir)/ruby/internal/glob.h
+iseq_load.o: $(hdrdir)/ruby/internal/globals.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/attribute.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/builtin.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/extension.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/feature.h
+iseq_load.o: $(hdrdir)/ruby/internal/has/warning.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/array.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/bignum.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/class.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/compar.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/complex.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/cont.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/dir.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/enum.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/error.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/eval.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/file.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/gc.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/hash.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/io.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/load.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/marshal.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/numeric.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/object.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/parse.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/proc.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/process.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/random.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/range.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/rational.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/re.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/ruby.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/select.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/signal.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/string.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/struct.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/thread.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/time.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/variable.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/vm.h
+iseq_load.o: $(hdrdir)/ruby/internal/interpreter.h
+iseq_load.o: $(hdrdir)/ruby/internal/iterator.h
+iseq_load.o: $(hdrdir)/ruby/internal/memory.h
+iseq_load.o: $(hdrdir)/ruby/internal/method.h
+iseq_load.o: $(hdrdir)/ruby/internal/module.h
+iseq_load.o: $(hdrdir)/ruby/internal/newobj.h
+iseq_load.o: $(hdrdir)/ruby/internal/rgengc.h
+iseq_load.o: $(hdrdir)/ruby/internal/scan_args.h
+iseq_load.o: $(hdrdir)/ruby/internal/special_consts.h
+iseq_load.o: $(hdrdir)/ruby/internal/static_assert.h
+iseq_load.o: $(hdrdir)/ruby/internal/stdalign.h
+iseq_load.o: $(hdrdir)/ruby/internal/stdbool.h
+iseq_load.o: $(hdrdir)/ruby/internal/symbol.h
+iseq_load.o: $(hdrdir)/ruby/internal/token_paste.h
+iseq_load.o: $(hdrdir)/ruby/internal/value.h
+iseq_load.o: $(hdrdir)/ruby/internal/value_type.h
+iseq_load.o: $(hdrdir)/ruby/internal/variable.h
+iseq_load.o: $(hdrdir)/ruby/internal/warning_push.h
+iseq_load.o: $(hdrdir)/ruby/internal/xmalloc.h
+iseq_load.o: $(hdrdir)/ruby/assert.h
+iseq_load.o: $(hdrdir)/ruby/backward.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/assume.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/attributes.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/bool.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/inttypes.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/limits.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/long_long.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/stdalign.h
+iseq_load.o: $(hdrdir)/ruby/backward/2/stdarg.h
+iseq_load.o: $(hdrdir)/ruby/defines.h
+iseq_load.o: $(hdrdir)/ruby/intern.h
+iseq_load.o: $(hdrdir)/ruby/missing.h
+iseq_load.o: $(hdrdir)/ruby/ruby.h
+iseq_load.o: $(hdrdir)/ruby/st.h
+iseq_load.o: $(hdrdir)/ruby/subst.h
+iseq_load.o: iseq_load.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/iter/break.c b/ext/-test-/iter/break.c
index 66ed26a9b8..4d43c5d0cf 100644
--- a/ext/-test-/iter/break.c
+++ b/ext/-test-/iter/break.c
@@ -5,7 +5,7 @@ iter_break(VALUE self)
{
rb_iter_break();
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
static VALUE
@@ -13,7 +13,7 @@ iter_break_value(VALUE self, VALUE val)
{
rb_iter_break_value(val);
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
void
diff --git a/ext/-test-/iter/depend b/ext/-test-/iter/depend
new file mode 100644
index 0000000000..d00638e78f
--- /dev/null
+++ b/ext/-test-/iter/depend
@@ -0,0 +1,485 @@
+# AUTOGENERATED DEPENDENCIES START
+break.o: $(RUBY_EXTCONF_H)
+break.o: $(arch_hdrdir)/ruby/config.h
+break.o: $(hdrdir)/ruby.h
+break.o: $(hdrdir)/ruby/internal/anyargs.h
+break.o: $(hdrdir)/ruby/internal/arithmetic.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+break.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+break.o: $(hdrdir)/ruby/internal/assume.h
+break.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+break.o: $(hdrdir)/ruby/internal/attr/artificial.h
+break.o: $(hdrdir)/ruby/internal/attr/cold.h
+break.o: $(hdrdir)/ruby/internal/attr/const.h
+break.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+break.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+break.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+break.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+break.o: $(hdrdir)/ruby/internal/attr/error.h
+break.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+break.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+break.o: $(hdrdir)/ruby/internal/attr/format.h
+break.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+break.o: $(hdrdir)/ruby/internal/attr/noalias.h
+break.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+break.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+break.o: $(hdrdir)/ruby/internal/attr/noinline.h
+break.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+break.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+break.o: $(hdrdir)/ruby/internal/attr/pure.h
+break.o: $(hdrdir)/ruby/internal/attr/restrict.h
+break.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+break.o: $(hdrdir)/ruby/internal/attr/warning.h
+break.o: $(hdrdir)/ruby/internal/attr/weakref.h
+break.o: $(hdrdir)/ruby/internal/cast.h
+break.o: $(hdrdir)/ruby/internal/compiler_is.h
+break.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+break.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+break.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+break.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+break.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+break.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+break.o: $(hdrdir)/ruby/internal/compiler_since.h
+break.o: $(hdrdir)/ruby/internal/config.h
+break.o: $(hdrdir)/ruby/internal/constant_p.h
+break.o: $(hdrdir)/ruby/internal/core.h
+break.o: $(hdrdir)/ruby/internal/core/rarray.h
+break.o: $(hdrdir)/ruby/internal/core/rbasic.h
+break.o: $(hdrdir)/ruby/internal/core/rbignum.h
+break.o: $(hdrdir)/ruby/internal/core/rclass.h
+break.o: $(hdrdir)/ruby/internal/core/rdata.h
+break.o: $(hdrdir)/ruby/internal/core/rfile.h
+break.o: $(hdrdir)/ruby/internal/core/rhash.h
+break.o: $(hdrdir)/ruby/internal/core/robject.h
+break.o: $(hdrdir)/ruby/internal/core/rregexp.h
+break.o: $(hdrdir)/ruby/internal/core/rstring.h
+break.o: $(hdrdir)/ruby/internal/core/rstruct.h
+break.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+break.o: $(hdrdir)/ruby/internal/ctype.h
+break.o: $(hdrdir)/ruby/internal/dllexport.h
+break.o: $(hdrdir)/ruby/internal/dosish.h
+break.o: $(hdrdir)/ruby/internal/error.h
+break.o: $(hdrdir)/ruby/internal/eval.h
+break.o: $(hdrdir)/ruby/internal/event.h
+break.o: $(hdrdir)/ruby/internal/fl_type.h
+break.o: $(hdrdir)/ruby/internal/gc.h
+break.o: $(hdrdir)/ruby/internal/glob.h
+break.o: $(hdrdir)/ruby/internal/globals.h
+break.o: $(hdrdir)/ruby/internal/has/attribute.h
+break.o: $(hdrdir)/ruby/internal/has/builtin.h
+break.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+break.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+break.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+break.o: $(hdrdir)/ruby/internal/has/extension.h
+break.o: $(hdrdir)/ruby/internal/has/feature.h
+break.o: $(hdrdir)/ruby/internal/has/warning.h
+break.o: $(hdrdir)/ruby/internal/intern/array.h
+break.o: $(hdrdir)/ruby/internal/intern/bignum.h
+break.o: $(hdrdir)/ruby/internal/intern/class.h
+break.o: $(hdrdir)/ruby/internal/intern/compar.h
+break.o: $(hdrdir)/ruby/internal/intern/complex.h
+break.o: $(hdrdir)/ruby/internal/intern/cont.h
+break.o: $(hdrdir)/ruby/internal/intern/dir.h
+break.o: $(hdrdir)/ruby/internal/intern/enum.h
+break.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+break.o: $(hdrdir)/ruby/internal/intern/error.h
+break.o: $(hdrdir)/ruby/internal/intern/eval.h
+break.o: $(hdrdir)/ruby/internal/intern/file.h
+break.o: $(hdrdir)/ruby/internal/intern/gc.h
+break.o: $(hdrdir)/ruby/internal/intern/hash.h
+break.o: $(hdrdir)/ruby/internal/intern/io.h
+break.o: $(hdrdir)/ruby/internal/intern/load.h
+break.o: $(hdrdir)/ruby/internal/intern/marshal.h
+break.o: $(hdrdir)/ruby/internal/intern/numeric.h
+break.o: $(hdrdir)/ruby/internal/intern/object.h
+break.o: $(hdrdir)/ruby/internal/intern/parse.h
+break.o: $(hdrdir)/ruby/internal/intern/proc.h
+break.o: $(hdrdir)/ruby/internal/intern/process.h
+break.o: $(hdrdir)/ruby/internal/intern/random.h
+break.o: $(hdrdir)/ruby/internal/intern/range.h
+break.o: $(hdrdir)/ruby/internal/intern/rational.h
+break.o: $(hdrdir)/ruby/internal/intern/re.h
+break.o: $(hdrdir)/ruby/internal/intern/ruby.h
+break.o: $(hdrdir)/ruby/internal/intern/select.h
+break.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+break.o: $(hdrdir)/ruby/internal/intern/signal.h
+break.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+break.o: $(hdrdir)/ruby/internal/intern/string.h
+break.o: $(hdrdir)/ruby/internal/intern/struct.h
+break.o: $(hdrdir)/ruby/internal/intern/thread.h
+break.o: $(hdrdir)/ruby/internal/intern/time.h
+break.o: $(hdrdir)/ruby/internal/intern/variable.h
+break.o: $(hdrdir)/ruby/internal/intern/vm.h
+break.o: $(hdrdir)/ruby/internal/interpreter.h
+break.o: $(hdrdir)/ruby/internal/iterator.h
+break.o: $(hdrdir)/ruby/internal/memory.h
+break.o: $(hdrdir)/ruby/internal/method.h
+break.o: $(hdrdir)/ruby/internal/module.h
+break.o: $(hdrdir)/ruby/internal/newobj.h
+break.o: $(hdrdir)/ruby/internal/rgengc.h
+break.o: $(hdrdir)/ruby/internal/scan_args.h
+break.o: $(hdrdir)/ruby/internal/special_consts.h
+break.o: $(hdrdir)/ruby/internal/static_assert.h
+break.o: $(hdrdir)/ruby/internal/stdalign.h
+break.o: $(hdrdir)/ruby/internal/stdbool.h
+break.o: $(hdrdir)/ruby/internal/symbol.h
+break.o: $(hdrdir)/ruby/internal/token_paste.h
+break.o: $(hdrdir)/ruby/internal/value.h
+break.o: $(hdrdir)/ruby/internal/value_type.h
+break.o: $(hdrdir)/ruby/internal/variable.h
+break.o: $(hdrdir)/ruby/internal/warning_push.h
+break.o: $(hdrdir)/ruby/internal/xmalloc.h
+break.o: $(hdrdir)/ruby/assert.h
+break.o: $(hdrdir)/ruby/backward.h
+break.o: $(hdrdir)/ruby/backward/2/assume.h
+break.o: $(hdrdir)/ruby/backward/2/attributes.h
+break.o: $(hdrdir)/ruby/backward/2/bool.h
+break.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+break.o: $(hdrdir)/ruby/backward/2/inttypes.h
+break.o: $(hdrdir)/ruby/backward/2/limits.h
+break.o: $(hdrdir)/ruby/backward/2/long_long.h
+break.o: $(hdrdir)/ruby/backward/2/stdalign.h
+break.o: $(hdrdir)/ruby/backward/2/stdarg.h
+break.o: $(hdrdir)/ruby/defines.h
+break.o: $(hdrdir)/ruby/intern.h
+break.o: $(hdrdir)/ruby/missing.h
+break.o: $(hdrdir)/ruby/ruby.h
+break.o: $(hdrdir)/ruby/st.h
+break.o: $(hdrdir)/ruby/subst.h
+break.o: break.c
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+yield.o: $(RUBY_EXTCONF_H)
+yield.o: $(arch_hdrdir)/ruby/config.h
+yield.o: $(hdrdir)/ruby.h
+yield.o: $(hdrdir)/ruby/internal/anyargs.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+yield.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+yield.o: $(hdrdir)/ruby/internal/assume.h
+yield.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+yield.o: $(hdrdir)/ruby/internal/attr/artificial.h
+yield.o: $(hdrdir)/ruby/internal/attr/cold.h
+yield.o: $(hdrdir)/ruby/internal/attr/const.h
+yield.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+yield.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+yield.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+yield.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+yield.o: $(hdrdir)/ruby/internal/attr/error.h
+yield.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+yield.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+yield.o: $(hdrdir)/ruby/internal/attr/format.h
+yield.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+yield.o: $(hdrdir)/ruby/internal/attr/noalias.h
+yield.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+yield.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+yield.o: $(hdrdir)/ruby/internal/attr/noinline.h
+yield.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+yield.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+yield.o: $(hdrdir)/ruby/internal/attr/pure.h
+yield.o: $(hdrdir)/ruby/internal/attr/restrict.h
+yield.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+yield.o: $(hdrdir)/ruby/internal/attr/warning.h
+yield.o: $(hdrdir)/ruby/internal/attr/weakref.h
+yield.o: $(hdrdir)/ruby/internal/cast.h
+yield.o: $(hdrdir)/ruby/internal/compiler_is.h
+yield.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+yield.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+yield.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+yield.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+yield.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+yield.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+yield.o: $(hdrdir)/ruby/internal/compiler_since.h
+yield.o: $(hdrdir)/ruby/internal/config.h
+yield.o: $(hdrdir)/ruby/internal/constant_p.h
+yield.o: $(hdrdir)/ruby/internal/core.h
+yield.o: $(hdrdir)/ruby/internal/core/rarray.h
+yield.o: $(hdrdir)/ruby/internal/core/rbasic.h
+yield.o: $(hdrdir)/ruby/internal/core/rbignum.h
+yield.o: $(hdrdir)/ruby/internal/core/rclass.h
+yield.o: $(hdrdir)/ruby/internal/core/rdata.h
+yield.o: $(hdrdir)/ruby/internal/core/rfile.h
+yield.o: $(hdrdir)/ruby/internal/core/rhash.h
+yield.o: $(hdrdir)/ruby/internal/core/robject.h
+yield.o: $(hdrdir)/ruby/internal/core/rregexp.h
+yield.o: $(hdrdir)/ruby/internal/core/rstring.h
+yield.o: $(hdrdir)/ruby/internal/core/rstruct.h
+yield.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+yield.o: $(hdrdir)/ruby/internal/ctype.h
+yield.o: $(hdrdir)/ruby/internal/dllexport.h
+yield.o: $(hdrdir)/ruby/internal/dosish.h
+yield.o: $(hdrdir)/ruby/internal/error.h
+yield.o: $(hdrdir)/ruby/internal/eval.h
+yield.o: $(hdrdir)/ruby/internal/event.h
+yield.o: $(hdrdir)/ruby/internal/fl_type.h
+yield.o: $(hdrdir)/ruby/internal/gc.h
+yield.o: $(hdrdir)/ruby/internal/glob.h
+yield.o: $(hdrdir)/ruby/internal/globals.h
+yield.o: $(hdrdir)/ruby/internal/has/attribute.h
+yield.o: $(hdrdir)/ruby/internal/has/builtin.h
+yield.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+yield.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+yield.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+yield.o: $(hdrdir)/ruby/internal/has/extension.h
+yield.o: $(hdrdir)/ruby/internal/has/feature.h
+yield.o: $(hdrdir)/ruby/internal/has/warning.h
+yield.o: $(hdrdir)/ruby/internal/intern/array.h
+yield.o: $(hdrdir)/ruby/internal/intern/bignum.h
+yield.o: $(hdrdir)/ruby/internal/intern/class.h
+yield.o: $(hdrdir)/ruby/internal/intern/compar.h
+yield.o: $(hdrdir)/ruby/internal/intern/complex.h
+yield.o: $(hdrdir)/ruby/internal/intern/cont.h
+yield.o: $(hdrdir)/ruby/internal/intern/dir.h
+yield.o: $(hdrdir)/ruby/internal/intern/enum.h
+yield.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+yield.o: $(hdrdir)/ruby/internal/intern/error.h
+yield.o: $(hdrdir)/ruby/internal/intern/eval.h
+yield.o: $(hdrdir)/ruby/internal/intern/file.h
+yield.o: $(hdrdir)/ruby/internal/intern/gc.h
+yield.o: $(hdrdir)/ruby/internal/intern/hash.h
+yield.o: $(hdrdir)/ruby/internal/intern/io.h
+yield.o: $(hdrdir)/ruby/internal/intern/load.h
+yield.o: $(hdrdir)/ruby/internal/intern/marshal.h
+yield.o: $(hdrdir)/ruby/internal/intern/numeric.h
+yield.o: $(hdrdir)/ruby/internal/intern/object.h
+yield.o: $(hdrdir)/ruby/internal/intern/parse.h
+yield.o: $(hdrdir)/ruby/internal/intern/proc.h
+yield.o: $(hdrdir)/ruby/internal/intern/process.h
+yield.o: $(hdrdir)/ruby/internal/intern/random.h
+yield.o: $(hdrdir)/ruby/internal/intern/range.h
+yield.o: $(hdrdir)/ruby/internal/intern/rational.h
+yield.o: $(hdrdir)/ruby/internal/intern/re.h
+yield.o: $(hdrdir)/ruby/internal/intern/ruby.h
+yield.o: $(hdrdir)/ruby/internal/intern/select.h
+yield.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+yield.o: $(hdrdir)/ruby/internal/intern/signal.h
+yield.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+yield.o: $(hdrdir)/ruby/internal/intern/string.h
+yield.o: $(hdrdir)/ruby/internal/intern/struct.h
+yield.o: $(hdrdir)/ruby/internal/intern/thread.h
+yield.o: $(hdrdir)/ruby/internal/intern/time.h
+yield.o: $(hdrdir)/ruby/internal/intern/variable.h
+yield.o: $(hdrdir)/ruby/internal/intern/vm.h
+yield.o: $(hdrdir)/ruby/internal/interpreter.h
+yield.o: $(hdrdir)/ruby/internal/iterator.h
+yield.o: $(hdrdir)/ruby/internal/memory.h
+yield.o: $(hdrdir)/ruby/internal/method.h
+yield.o: $(hdrdir)/ruby/internal/module.h
+yield.o: $(hdrdir)/ruby/internal/newobj.h
+yield.o: $(hdrdir)/ruby/internal/rgengc.h
+yield.o: $(hdrdir)/ruby/internal/scan_args.h
+yield.o: $(hdrdir)/ruby/internal/special_consts.h
+yield.o: $(hdrdir)/ruby/internal/static_assert.h
+yield.o: $(hdrdir)/ruby/internal/stdalign.h
+yield.o: $(hdrdir)/ruby/internal/stdbool.h
+yield.o: $(hdrdir)/ruby/internal/symbol.h
+yield.o: $(hdrdir)/ruby/internal/token_paste.h
+yield.o: $(hdrdir)/ruby/internal/value.h
+yield.o: $(hdrdir)/ruby/internal/value_type.h
+yield.o: $(hdrdir)/ruby/internal/variable.h
+yield.o: $(hdrdir)/ruby/internal/warning_push.h
+yield.o: $(hdrdir)/ruby/internal/xmalloc.h
+yield.o: $(hdrdir)/ruby/assert.h
+yield.o: $(hdrdir)/ruby/backward.h
+yield.o: $(hdrdir)/ruby/backward/2/assume.h
+yield.o: $(hdrdir)/ruby/backward/2/attributes.h
+yield.o: $(hdrdir)/ruby/backward/2/bool.h
+yield.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+yield.o: $(hdrdir)/ruby/backward/2/inttypes.h
+yield.o: $(hdrdir)/ruby/backward/2/limits.h
+yield.o: $(hdrdir)/ruby/backward/2/long_long.h
+yield.o: $(hdrdir)/ruby/backward/2/stdalign.h
+yield.o: $(hdrdir)/ruby/backward/2/stdarg.h
+yield.o: $(hdrdir)/ruby/defines.h
+yield.o: $(hdrdir)/ruby/intern.h
+yield.o: $(hdrdir)/ruby/missing.h
+yield.o: $(hdrdir)/ruby/ruby.h
+yield.o: $(hdrdir)/ruby/st.h
+yield.o: $(hdrdir)/ruby/subst.h
+yield.o: yield.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/iter/yield.c b/ext/-test-/iter/yield.c
index 3cd408a928..0f6f3e87eb 100644
--- a/ext/-test-/iter/yield.c
+++ b/ext/-test-/iter/yield.c
@@ -4,7 +4,7 @@ static VALUE
yield_block(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
- return rb_block_call(self, rb_to_id(argv[0]), argc-1, argv+1, rb_yield_block, 0);
+ return rb_block_call_kw(self, rb_to_id(argv[0]), argc-1, argv+1, rb_yield_block, 0, RB_PASS_CALLED_KEYWORDS);
}
void
diff --git a/ext/-test-/load/protect/depend b/ext/-test-/load/protect/depend
new file mode 100644
index 0000000000..99c02e1f25
--- /dev/null
+++ b/ext/-test-/load/protect/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+protect.o: $(RUBY_EXTCONF_H)
+protect.o: $(arch_hdrdir)/ruby/config.h
+protect.o: $(hdrdir)/ruby.h
+protect.o: $(hdrdir)/ruby/internal/anyargs.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+protect.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+protect.o: $(hdrdir)/ruby/internal/assume.h
+protect.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+protect.o: $(hdrdir)/ruby/internal/attr/artificial.h
+protect.o: $(hdrdir)/ruby/internal/attr/cold.h
+protect.o: $(hdrdir)/ruby/internal/attr/const.h
+protect.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+protect.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+protect.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+protect.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+protect.o: $(hdrdir)/ruby/internal/attr/error.h
+protect.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+protect.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+protect.o: $(hdrdir)/ruby/internal/attr/format.h
+protect.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+protect.o: $(hdrdir)/ruby/internal/attr/noalias.h
+protect.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+protect.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+protect.o: $(hdrdir)/ruby/internal/attr/noinline.h
+protect.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+protect.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+protect.o: $(hdrdir)/ruby/internal/attr/pure.h
+protect.o: $(hdrdir)/ruby/internal/attr/restrict.h
+protect.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+protect.o: $(hdrdir)/ruby/internal/attr/warning.h
+protect.o: $(hdrdir)/ruby/internal/attr/weakref.h
+protect.o: $(hdrdir)/ruby/internal/cast.h
+protect.o: $(hdrdir)/ruby/internal/compiler_is.h
+protect.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+protect.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+protect.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+protect.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+protect.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+protect.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+protect.o: $(hdrdir)/ruby/internal/compiler_since.h
+protect.o: $(hdrdir)/ruby/internal/config.h
+protect.o: $(hdrdir)/ruby/internal/constant_p.h
+protect.o: $(hdrdir)/ruby/internal/core.h
+protect.o: $(hdrdir)/ruby/internal/core/rarray.h
+protect.o: $(hdrdir)/ruby/internal/core/rbasic.h
+protect.o: $(hdrdir)/ruby/internal/core/rbignum.h
+protect.o: $(hdrdir)/ruby/internal/core/rclass.h
+protect.o: $(hdrdir)/ruby/internal/core/rdata.h
+protect.o: $(hdrdir)/ruby/internal/core/rfile.h
+protect.o: $(hdrdir)/ruby/internal/core/rhash.h
+protect.o: $(hdrdir)/ruby/internal/core/robject.h
+protect.o: $(hdrdir)/ruby/internal/core/rregexp.h
+protect.o: $(hdrdir)/ruby/internal/core/rstring.h
+protect.o: $(hdrdir)/ruby/internal/core/rstruct.h
+protect.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+protect.o: $(hdrdir)/ruby/internal/ctype.h
+protect.o: $(hdrdir)/ruby/internal/dllexport.h
+protect.o: $(hdrdir)/ruby/internal/dosish.h
+protect.o: $(hdrdir)/ruby/internal/error.h
+protect.o: $(hdrdir)/ruby/internal/eval.h
+protect.o: $(hdrdir)/ruby/internal/event.h
+protect.o: $(hdrdir)/ruby/internal/fl_type.h
+protect.o: $(hdrdir)/ruby/internal/gc.h
+protect.o: $(hdrdir)/ruby/internal/glob.h
+protect.o: $(hdrdir)/ruby/internal/globals.h
+protect.o: $(hdrdir)/ruby/internal/has/attribute.h
+protect.o: $(hdrdir)/ruby/internal/has/builtin.h
+protect.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+protect.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+protect.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+protect.o: $(hdrdir)/ruby/internal/has/extension.h
+protect.o: $(hdrdir)/ruby/internal/has/feature.h
+protect.o: $(hdrdir)/ruby/internal/has/warning.h
+protect.o: $(hdrdir)/ruby/internal/intern/array.h
+protect.o: $(hdrdir)/ruby/internal/intern/bignum.h
+protect.o: $(hdrdir)/ruby/internal/intern/class.h
+protect.o: $(hdrdir)/ruby/internal/intern/compar.h
+protect.o: $(hdrdir)/ruby/internal/intern/complex.h
+protect.o: $(hdrdir)/ruby/internal/intern/cont.h
+protect.o: $(hdrdir)/ruby/internal/intern/dir.h
+protect.o: $(hdrdir)/ruby/internal/intern/enum.h
+protect.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+protect.o: $(hdrdir)/ruby/internal/intern/error.h
+protect.o: $(hdrdir)/ruby/internal/intern/eval.h
+protect.o: $(hdrdir)/ruby/internal/intern/file.h
+protect.o: $(hdrdir)/ruby/internal/intern/gc.h
+protect.o: $(hdrdir)/ruby/internal/intern/hash.h
+protect.o: $(hdrdir)/ruby/internal/intern/io.h
+protect.o: $(hdrdir)/ruby/internal/intern/load.h
+protect.o: $(hdrdir)/ruby/internal/intern/marshal.h
+protect.o: $(hdrdir)/ruby/internal/intern/numeric.h
+protect.o: $(hdrdir)/ruby/internal/intern/object.h
+protect.o: $(hdrdir)/ruby/internal/intern/parse.h
+protect.o: $(hdrdir)/ruby/internal/intern/proc.h
+protect.o: $(hdrdir)/ruby/internal/intern/process.h
+protect.o: $(hdrdir)/ruby/internal/intern/random.h
+protect.o: $(hdrdir)/ruby/internal/intern/range.h
+protect.o: $(hdrdir)/ruby/internal/intern/rational.h
+protect.o: $(hdrdir)/ruby/internal/intern/re.h
+protect.o: $(hdrdir)/ruby/internal/intern/ruby.h
+protect.o: $(hdrdir)/ruby/internal/intern/select.h
+protect.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+protect.o: $(hdrdir)/ruby/internal/intern/signal.h
+protect.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+protect.o: $(hdrdir)/ruby/internal/intern/string.h
+protect.o: $(hdrdir)/ruby/internal/intern/struct.h
+protect.o: $(hdrdir)/ruby/internal/intern/thread.h
+protect.o: $(hdrdir)/ruby/internal/intern/time.h
+protect.o: $(hdrdir)/ruby/internal/intern/variable.h
+protect.o: $(hdrdir)/ruby/internal/intern/vm.h
+protect.o: $(hdrdir)/ruby/internal/interpreter.h
+protect.o: $(hdrdir)/ruby/internal/iterator.h
+protect.o: $(hdrdir)/ruby/internal/memory.h
+protect.o: $(hdrdir)/ruby/internal/method.h
+protect.o: $(hdrdir)/ruby/internal/module.h
+protect.o: $(hdrdir)/ruby/internal/newobj.h
+protect.o: $(hdrdir)/ruby/internal/rgengc.h
+protect.o: $(hdrdir)/ruby/internal/scan_args.h
+protect.o: $(hdrdir)/ruby/internal/special_consts.h
+protect.o: $(hdrdir)/ruby/internal/static_assert.h
+protect.o: $(hdrdir)/ruby/internal/stdalign.h
+protect.o: $(hdrdir)/ruby/internal/stdbool.h
+protect.o: $(hdrdir)/ruby/internal/symbol.h
+protect.o: $(hdrdir)/ruby/internal/token_paste.h
+protect.o: $(hdrdir)/ruby/internal/value.h
+protect.o: $(hdrdir)/ruby/internal/value_type.h
+protect.o: $(hdrdir)/ruby/internal/variable.h
+protect.o: $(hdrdir)/ruby/internal/warning_push.h
+protect.o: $(hdrdir)/ruby/internal/xmalloc.h
+protect.o: $(hdrdir)/ruby/assert.h
+protect.o: $(hdrdir)/ruby/backward.h
+protect.o: $(hdrdir)/ruby/backward/2/assume.h
+protect.o: $(hdrdir)/ruby/backward/2/attributes.h
+protect.o: $(hdrdir)/ruby/backward/2/bool.h
+protect.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+protect.o: $(hdrdir)/ruby/backward/2/inttypes.h
+protect.o: $(hdrdir)/ruby/backward/2/limits.h
+protect.o: $(hdrdir)/ruby/backward/2/long_long.h
+protect.o: $(hdrdir)/ruby/backward/2/stdalign.h
+protect.o: $(hdrdir)/ruby/backward/2/stdarg.h
+protect.o: $(hdrdir)/ruby/defines.h
+protect.o: $(hdrdir)/ruby/intern.h
+protect.o: $(hdrdir)/ruby/missing.h
+protect.o: $(hdrdir)/ruby/ruby.h
+protect.o: $(hdrdir)/ruby/st.h
+protect.o: $(hdrdir)/ruby/subst.h
+protect.o: protect.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/marshal/compat/depend b/ext/-test-/marshal/compat/depend
new file mode 100644
index 0000000000..017a555852
--- /dev/null
+++ b/ext/-test-/marshal/compat/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+usrcompat.o: $(RUBY_EXTCONF_H)
+usrcompat.o: $(arch_hdrdir)/ruby/config.h
+usrcompat.o: $(hdrdir)/ruby.h
+usrcompat.o: $(hdrdir)/ruby/internal/anyargs.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+usrcompat.o: $(hdrdir)/ruby/internal/assume.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/artificial.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/cold.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/const.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/error.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/format.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/noalias.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/noinline.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/pure.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/restrict.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/warning.h
+usrcompat.o: $(hdrdir)/ruby/internal/attr/weakref.h
+usrcompat.o: $(hdrdir)/ruby/internal/cast.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_is.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+usrcompat.o: $(hdrdir)/ruby/internal/compiler_since.h
+usrcompat.o: $(hdrdir)/ruby/internal/config.h
+usrcompat.o: $(hdrdir)/ruby/internal/constant_p.h
+usrcompat.o: $(hdrdir)/ruby/internal/core.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rarray.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rbasic.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rbignum.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rclass.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rdata.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rfile.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rhash.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/robject.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rregexp.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rstring.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rstruct.h
+usrcompat.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+usrcompat.o: $(hdrdir)/ruby/internal/ctype.h
+usrcompat.o: $(hdrdir)/ruby/internal/dllexport.h
+usrcompat.o: $(hdrdir)/ruby/internal/dosish.h
+usrcompat.o: $(hdrdir)/ruby/internal/error.h
+usrcompat.o: $(hdrdir)/ruby/internal/eval.h
+usrcompat.o: $(hdrdir)/ruby/internal/event.h
+usrcompat.o: $(hdrdir)/ruby/internal/fl_type.h
+usrcompat.o: $(hdrdir)/ruby/internal/gc.h
+usrcompat.o: $(hdrdir)/ruby/internal/glob.h
+usrcompat.o: $(hdrdir)/ruby/internal/globals.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/attribute.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/builtin.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/extension.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/feature.h
+usrcompat.o: $(hdrdir)/ruby/internal/has/warning.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/array.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/bignum.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/class.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/compar.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/complex.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/cont.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/dir.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/enum.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/error.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/eval.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/file.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/gc.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/hash.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/io.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/load.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/marshal.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/numeric.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/object.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/parse.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/proc.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/process.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/random.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/range.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/rational.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/re.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/ruby.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/select.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/signal.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/string.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/struct.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/thread.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/time.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/variable.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/vm.h
+usrcompat.o: $(hdrdir)/ruby/internal/interpreter.h
+usrcompat.o: $(hdrdir)/ruby/internal/iterator.h
+usrcompat.o: $(hdrdir)/ruby/internal/memory.h
+usrcompat.o: $(hdrdir)/ruby/internal/method.h
+usrcompat.o: $(hdrdir)/ruby/internal/module.h
+usrcompat.o: $(hdrdir)/ruby/internal/newobj.h
+usrcompat.o: $(hdrdir)/ruby/internal/rgengc.h
+usrcompat.o: $(hdrdir)/ruby/internal/scan_args.h
+usrcompat.o: $(hdrdir)/ruby/internal/special_consts.h
+usrcompat.o: $(hdrdir)/ruby/internal/static_assert.h
+usrcompat.o: $(hdrdir)/ruby/internal/stdalign.h
+usrcompat.o: $(hdrdir)/ruby/internal/stdbool.h
+usrcompat.o: $(hdrdir)/ruby/internal/symbol.h
+usrcompat.o: $(hdrdir)/ruby/internal/token_paste.h
+usrcompat.o: $(hdrdir)/ruby/internal/value.h
+usrcompat.o: $(hdrdir)/ruby/internal/value_type.h
+usrcompat.o: $(hdrdir)/ruby/internal/variable.h
+usrcompat.o: $(hdrdir)/ruby/internal/warning_push.h
+usrcompat.o: $(hdrdir)/ruby/internal/xmalloc.h
+usrcompat.o: $(hdrdir)/ruby/assert.h
+usrcompat.o: $(hdrdir)/ruby/backward.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/assume.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/attributes.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/bool.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/inttypes.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/limits.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/long_long.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/stdalign.h
+usrcompat.o: $(hdrdir)/ruby/backward/2/stdarg.h
+usrcompat.o: $(hdrdir)/ruby/defines.h
+usrcompat.o: $(hdrdir)/ruby/intern.h
+usrcompat.o: $(hdrdir)/ruby/missing.h
+usrcompat.o: $(hdrdir)/ruby/ruby.h
+usrcompat.o: $(hdrdir)/ruby/st.h
+usrcompat.o: $(hdrdir)/ruby/subst.h
+usrcompat.o: usrcompat.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/marshal/internal_ivar/depend b/ext/-test-/marshal/internal_ivar/depend
new file mode 100644
index 0000000000..73b76c9080
--- /dev/null
+++ b/ext/-test-/marshal/internal_ivar/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+internal_ivar.o: $(RUBY_EXTCONF_H)
+internal_ivar.o: $(arch_hdrdir)/ruby/config.h
+internal_ivar.o: $(hdrdir)/ruby.h
+internal_ivar.o: $(hdrdir)/ruby/internal/anyargs.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+internal_ivar.o: $(hdrdir)/ruby/internal/assume.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/artificial.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/cold.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/const.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/error.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/format.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/noalias.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/noinline.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/pure.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/restrict.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/warning.h
+internal_ivar.o: $(hdrdir)/ruby/internal/attr/weakref.h
+internal_ivar.o: $(hdrdir)/ruby/internal/cast.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_is.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+internal_ivar.o: $(hdrdir)/ruby/internal/compiler_since.h
+internal_ivar.o: $(hdrdir)/ruby/internal/config.h
+internal_ivar.o: $(hdrdir)/ruby/internal/constant_p.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rarray.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rbasic.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rbignum.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rclass.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rdata.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rfile.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rhash.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/robject.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rregexp.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rstring.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rstruct.h
+internal_ivar.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+internal_ivar.o: $(hdrdir)/ruby/internal/ctype.h
+internal_ivar.o: $(hdrdir)/ruby/internal/dllexport.h
+internal_ivar.o: $(hdrdir)/ruby/internal/dosish.h
+internal_ivar.o: $(hdrdir)/ruby/internal/error.h
+internal_ivar.o: $(hdrdir)/ruby/internal/eval.h
+internal_ivar.o: $(hdrdir)/ruby/internal/event.h
+internal_ivar.o: $(hdrdir)/ruby/internal/fl_type.h
+internal_ivar.o: $(hdrdir)/ruby/internal/gc.h
+internal_ivar.o: $(hdrdir)/ruby/internal/glob.h
+internal_ivar.o: $(hdrdir)/ruby/internal/globals.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/attribute.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/builtin.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/extension.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/feature.h
+internal_ivar.o: $(hdrdir)/ruby/internal/has/warning.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/array.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/bignum.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/class.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/compar.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/complex.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/cont.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/dir.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/enum.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/error.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/eval.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/file.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/gc.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/hash.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/io.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/load.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/marshal.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/numeric.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/object.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/parse.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/proc.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/process.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/random.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/range.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/rational.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/re.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/ruby.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/select.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/signal.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/string.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/struct.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/thread.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/time.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/variable.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/vm.h
+internal_ivar.o: $(hdrdir)/ruby/internal/interpreter.h
+internal_ivar.o: $(hdrdir)/ruby/internal/iterator.h
+internal_ivar.o: $(hdrdir)/ruby/internal/memory.h
+internal_ivar.o: $(hdrdir)/ruby/internal/method.h
+internal_ivar.o: $(hdrdir)/ruby/internal/module.h
+internal_ivar.o: $(hdrdir)/ruby/internal/newobj.h
+internal_ivar.o: $(hdrdir)/ruby/internal/rgengc.h
+internal_ivar.o: $(hdrdir)/ruby/internal/scan_args.h
+internal_ivar.o: $(hdrdir)/ruby/internal/special_consts.h
+internal_ivar.o: $(hdrdir)/ruby/internal/static_assert.h
+internal_ivar.o: $(hdrdir)/ruby/internal/stdalign.h
+internal_ivar.o: $(hdrdir)/ruby/internal/stdbool.h
+internal_ivar.o: $(hdrdir)/ruby/internal/symbol.h
+internal_ivar.o: $(hdrdir)/ruby/internal/token_paste.h
+internal_ivar.o: $(hdrdir)/ruby/internal/value.h
+internal_ivar.o: $(hdrdir)/ruby/internal/value_type.h
+internal_ivar.o: $(hdrdir)/ruby/internal/variable.h
+internal_ivar.o: $(hdrdir)/ruby/internal/warning_push.h
+internal_ivar.o: $(hdrdir)/ruby/internal/xmalloc.h
+internal_ivar.o: $(hdrdir)/ruby/assert.h
+internal_ivar.o: $(hdrdir)/ruby/backward.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/assume.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/attributes.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/bool.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/inttypes.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/limits.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/long_long.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/stdalign.h
+internal_ivar.o: $(hdrdir)/ruby/backward/2/stdarg.h
+internal_ivar.o: $(hdrdir)/ruby/defines.h
+internal_ivar.o: $(hdrdir)/ruby/intern.h
+internal_ivar.o: $(hdrdir)/ruby/missing.h
+internal_ivar.o: $(hdrdir)/ruby/ruby.h
+internal_ivar.o: $(hdrdir)/ruby/st.h
+internal_ivar.o: $(hdrdir)/ruby/subst.h
+internal_ivar.o: internal_ivar.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/marshal/internal_ivar/internal_ivar.c b/ext/-test-/marshal/internal_ivar/internal_ivar.c
index 299da27f23..de0cf711aa 100644
--- a/ext/-test-/marshal/internal_ivar/internal_ivar.c
+++ b/ext/-test-/marshal/internal_ivar/internal_ivar.c
@@ -1,12 +1,13 @@
#include <ruby.h>
-static ID id_normal_ivar, id_internal_ivar;
+static ID id_normal_ivar, id_internal_ivar, id_encoding_short;
static VALUE
-init(VALUE self, VALUE arg1, VALUE arg2)
+init(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3)
{
rb_ivar_set(self, id_normal_ivar, arg1);
rb_ivar_set(self, id_internal_ivar, arg2);
+ rb_ivar_set(self, id_encoding_short, arg3);
return self;
}
@@ -22,6 +23,12 @@ get_internal(VALUE self)
return rb_attr_get(self, id_internal_ivar);
}
+static VALUE
+get_encoding_short(VALUE self)
+{
+ return rb_attr_get(self, id_encoding_short);
+}
+
void
Init_internal_ivar(void)
{
@@ -33,7 +40,9 @@ Init_internal_ivar(void)
/* leave id_internal_ivar being 0 */
id_internal_ivar = rb_make_internal_id();
#endif
- rb_define_method(newclass, "initialize", init, 2);
+ id_encoding_short = rb_intern_const("E");
+ rb_define_method(newclass, "initialize", init, 3);
rb_define_method(newclass, "normal", get_normal, 0);
rb_define_method(newclass, "internal", get_internal, 0);
+ rb_define_method(newclass, "encoding_short", get_encoding_short, 0);
}
diff --git a/ext/-test-/marshal/usr/depend b/ext/-test-/marshal/usr/depend
new file mode 100644
index 0000000000..bf96e44d02
--- /dev/null
+++ b/ext/-test-/marshal/usr/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+usrmarshal.o: $(RUBY_EXTCONF_H)
+usrmarshal.o: $(arch_hdrdir)/ruby/config.h
+usrmarshal.o: $(hdrdir)/ruby.h
+usrmarshal.o: $(hdrdir)/ruby/internal/anyargs.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+usrmarshal.o: $(hdrdir)/ruby/internal/assume.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/artificial.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/cold.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/const.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/error.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/format.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/noalias.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/noinline.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/pure.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/restrict.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/warning.h
+usrmarshal.o: $(hdrdir)/ruby/internal/attr/weakref.h
+usrmarshal.o: $(hdrdir)/ruby/internal/cast.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_is.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+usrmarshal.o: $(hdrdir)/ruby/internal/compiler_since.h
+usrmarshal.o: $(hdrdir)/ruby/internal/config.h
+usrmarshal.o: $(hdrdir)/ruby/internal/constant_p.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rarray.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rbasic.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rbignum.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rclass.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rdata.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rfile.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rhash.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/robject.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rregexp.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rstring.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rstruct.h
+usrmarshal.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+usrmarshal.o: $(hdrdir)/ruby/internal/ctype.h
+usrmarshal.o: $(hdrdir)/ruby/internal/dllexport.h
+usrmarshal.o: $(hdrdir)/ruby/internal/dosish.h
+usrmarshal.o: $(hdrdir)/ruby/internal/error.h
+usrmarshal.o: $(hdrdir)/ruby/internal/eval.h
+usrmarshal.o: $(hdrdir)/ruby/internal/event.h
+usrmarshal.o: $(hdrdir)/ruby/internal/fl_type.h
+usrmarshal.o: $(hdrdir)/ruby/internal/gc.h
+usrmarshal.o: $(hdrdir)/ruby/internal/glob.h
+usrmarshal.o: $(hdrdir)/ruby/internal/globals.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/attribute.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/builtin.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/extension.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/feature.h
+usrmarshal.o: $(hdrdir)/ruby/internal/has/warning.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/array.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/bignum.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/class.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/compar.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/complex.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/cont.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/dir.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/enum.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/error.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/eval.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/file.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/gc.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/hash.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/io.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/load.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/marshal.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/numeric.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/object.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/parse.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/proc.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/process.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/random.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/range.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/rational.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/re.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/ruby.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/select.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/signal.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/string.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/struct.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/thread.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/time.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/variable.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/vm.h
+usrmarshal.o: $(hdrdir)/ruby/internal/interpreter.h
+usrmarshal.o: $(hdrdir)/ruby/internal/iterator.h
+usrmarshal.o: $(hdrdir)/ruby/internal/memory.h
+usrmarshal.o: $(hdrdir)/ruby/internal/method.h
+usrmarshal.o: $(hdrdir)/ruby/internal/module.h
+usrmarshal.o: $(hdrdir)/ruby/internal/newobj.h
+usrmarshal.o: $(hdrdir)/ruby/internal/rgengc.h
+usrmarshal.o: $(hdrdir)/ruby/internal/scan_args.h
+usrmarshal.o: $(hdrdir)/ruby/internal/special_consts.h
+usrmarshal.o: $(hdrdir)/ruby/internal/static_assert.h
+usrmarshal.o: $(hdrdir)/ruby/internal/stdalign.h
+usrmarshal.o: $(hdrdir)/ruby/internal/stdbool.h
+usrmarshal.o: $(hdrdir)/ruby/internal/symbol.h
+usrmarshal.o: $(hdrdir)/ruby/internal/token_paste.h
+usrmarshal.o: $(hdrdir)/ruby/internal/value.h
+usrmarshal.o: $(hdrdir)/ruby/internal/value_type.h
+usrmarshal.o: $(hdrdir)/ruby/internal/variable.h
+usrmarshal.o: $(hdrdir)/ruby/internal/warning_push.h
+usrmarshal.o: $(hdrdir)/ruby/internal/xmalloc.h
+usrmarshal.o: $(hdrdir)/ruby/assert.h
+usrmarshal.o: $(hdrdir)/ruby/backward.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/assume.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/attributes.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/bool.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/inttypes.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/limits.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/long_long.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/stdalign.h
+usrmarshal.o: $(hdrdir)/ruby/backward/2/stdarg.h
+usrmarshal.o: $(hdrdir)/ruby/defines.h
+usrmarshal.o: $(hdrdir)/ruby/intern.h
+usrmarshal.o: $(hdrdir)/ruby/missing.h
+usrmarshal.o: $(hdrdir)/ruby/ruby.h
+usrmarshal.o: $(hdrdir)/ruby/st.h
+usrmarshal.o: $(hdrdir)/ruby/subst.h
+usrmarshal.o: usrmarshal.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/memory_status/depend b/ext/-test-/memory_status/depend
new file mode 100644
index 0000000000..96a7821451
--- /dev/null
+++ b/ext/-test-/memory_status/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+memory_status.o: $(RUBY_EXTCONF_H)
+memory_status.o: $(arch_hdrdir)/ruby/config.h
+memory_status.o: $(hdrdir)/ruby.h
+memory_status.o: $(hdrdir)/ruby/assert.h
+memory_status.o: $(hdrdir)/ruby/backward.h
+memory_status.o: $(hdrdir)/ruby/backward/2/assume.h
+memory_status.o: $(hdrdir)/ruby/backward/2/attributes.h
+memory_status.o: $(hdrdir)/ruby/backward/2/bool.h
+memory_status.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+memory_status.o: $(hdrdir)/ruby/backward/2/inttypes.h
+memory_status.o: $(hdrdir)/ruby/backward/2/limits.h
+memory_status.o: $(hdrdir)/ruby/backward/2/long_long.h
+memory_status.o: $(hdrdir)/ruby/backward/2/stdalign.h
+memory_status.o: $(hdrdir)/ruby/backward/2/stdarg.h
+memory_status.o: $(hdrdir)/ruby/defines.h
+memory_status.o: $(hdrdir)/ruby/intern.h
+memory_status.o: $(hdrdir)/ruby/internal/anyargs.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+memory_status.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+memory_status.o: $(hdrdir)/ruby/internal/assume.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/artificial.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/cold.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/const.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/error.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/format.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/noalias.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/noinline.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/pure.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/restrict.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/warning.h
+memory_status.o: $(hdrdir)/ruby/internal/attr/weakref.h
+memory_status.o: $(hdrdir)/ruby/internal/cast.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_is.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+memory_status.o: $(hdrdir)/ruby/internal/compiler_since.h
+memory_status.o: $(hdrdir)/ruby/internal/config.h
+memory_status.o: $(hdrdir)/ruby/internal/constant_p.h
+memory_status.o: $(hdrdir)/ruby/internal/core.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rarray.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rbasic.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rbignum.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rclass.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rdata.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rfile.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rhash.h
+memory_status.o: $(hdrdir)/ruby/internal/core/robject.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rregexp.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rstring.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rstruct.h
+memory_status.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+memory_status.o: $(hdrdir)/ruby/internal/ctype.h
+memory_status.o: $(hdrdir)/ruby/internal/dllexport.h
+memory_status.o: $(hdrdir)/ruby/internal/dosish.h
+memory_status.o: $(hdrdir)/ruby/internal/error.h
+memory_status.o: $(hdrdir)/ruby/internal/eval.h
+memory_status.o: $(hdrdir)/ruby/internal/event.h
+memory_status.o: $(hdrdir)/ruby/internal/fl_type.h
+memory_status.o: $(hdrdir)/ruby/internal/gc.h
+memory_status.o: $(hdrdir)/ruby/internal/glob.h
+memory_status.o: $(hdrdir)/ruby/internal/globals.h
+memory_status.o: $(hdrdir)/ruby/internal/has/attribute.h
+memory_status.o: $(hdrdir)/ruby/internal/has/builtin.h
+memory_status.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+memory_status.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+memory_status.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+memory_status.o: $(hdrdir)/ruby/internal/has/extension.h
+memory_status.o: $(hdrdir)/ruby/internal/has/feature.h
+memory_status.o: $(hdrdir)/ruby/internal/has/warning.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/array.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/bignum.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/class.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/compar.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/complex.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/cont.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/dir.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/enum.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/error.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/eval.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/file.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/gc.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/hash.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/io.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/load.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/marshal.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/numeric.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/object.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/parse.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/proc.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/process.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/random.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/range.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/rational.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/re.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/ruby.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/select.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/signal.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/string.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/struct.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/thread.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/time.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/variable.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/vm.h
+memory_status.o: $(hdrdir)/ruby/internal/interpreter.h
+memory_status.o: $(hdrdir)/ruby/internal/iterator.h
+memory_status.o: $(hdrdir)/ruby/internal/memory.h
+memory_status.o: $(hdrdir)/ruby/internal/method.h
+memory_status.o: $(hdrdir)/ruby/internal/module.h
+memory_status.o: $(hdrdir)/ruby/internal/newobj.h
+memory_status.o: $(hdrdir)/ruby/internal/rgengc.h
+memory_status.o: $(hdrdir)/ruby/internal/scan_args.h
+memory_status.o: $(hdrdir)/ruby/internal/special_consts.h
+memory_status.o: $(hdrdir)/ruby/internal/static_assert.h
+memory_status.o: $(hdrdir)/ruby/internal/stdalign.h
+memory_status.o: $(hdrdir)/ruby/internal/stdbool.h
+memory_status.o: $(hdrdir)/ruby/internal/symbol.h
+memory_status.o: $(hdrdir)/ruby/internal/token_paste.h
+memory_status.o: $(hdrdir)/ruby/internal/value.h
+memory_status.o: $(hdrdir)/ruby/internal/value_type.h
+memory_status.o: $(hdrdir)/ruby/internal/variable.h
+memory_status.o: $(hdrdir)/ruby/internal/warning_push.h
+memory_status.o: $(hdrdir)/ruby/internal/xmalloc.h
+memory_status.o: $(hdrdir)/ruby/missing.h
+memory_status.o: $(hdrdir)/ruby/ruby.h
+memory_status.o: $(hdrdir)/ruby/st.h
+memory_status.o: $(hdrdir)/ruby/subst.h
+memory_status.o: memory_status.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/memory_status/memory_status.c b/ext/-test-/memory_status/memory_status.c
index 23c4806472..5775fa56f3 100644
--- a/ext/-test-/memory_status/memory_status.c
+++ b/ext/-test-/memory_status/memory_status.c
@@ -32,6 +32,10 @@ read_status(VALUE self)
error = task_info(mach_task_self(), flavor,
(task_info_t)&taskinfo, &out_count);
if (error != KERN_SUCCESS) return Qnil;
+#ifndef ULL2NUM
+/* "long long" does not exist here, use size_t instead. */
+#define ULL2NUM SIZET2NUM
+#endif
size = ULL2NUM(taskinfo.virtual_size);
rss = ULL2NUM(taskinfo.resident_size);
rb_struct_aset(self, INT2FIX(1), rss);
diff --git a/ext/-test-/memory_view/depend b/ext/-test-/memory_view/depend
new file mode 100644
index 0000000000..bcbd98d41f
--- /dev/null
+++ b/ext/-test-/memory_view/depend
@@ -0,0 +1,164 @@
+# AUTOGENERATED DEPENDENCIES START
+memory_view.o: $(RUBY_EXTCONF_H)
+memory_view.o: $(arch_hdrdir)/ruby/config.h
+memory_view.o: $(hdrdir)/ruby.h
+memory_view.o: $(hdrdir)/ruby/assert.h
+memory_view.o: $(hdrdir)/ruby/backward.h
+memory_view.o: $(hdrdir)/ruby/backward/2/assume.h
+memory_view.o: $(hdrdir)/ruby/backward/2/attributes.h
+memory_view.o: $(hdrdir)/ruby/backward/2/bool.h
+memory_view.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+memory_view.o: $(hdrdir)/ruby/backward/2/inttypes.h
+memory_view.o: $(hdrdir)/ruby/backward/2/limits.h
+memory_view.o: $(hdrdir)/ruby/backward/2/long_long.h
+memory_view.o: $(hdrdir)/ruby/backward/2/stdalign.h
+memory_view.o: $(hdrdir)/ruby/backward/2/stdarg.h
+memory_view.o: $(hdrdir)/ruby/defines.h
+memory_view.o: $(hdrdir)/ruby/intern.h
+memory_view.o: $(hdrdir)/ruby/internal/anyargs.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+memory_view.o: $(hdrdir)/ruby/internal/assume.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/artificial.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/cold.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/const.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/error.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/format.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noalias.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/warning.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/weakref.h
+memory_view.o: $(hdrdir)/ruby/internal/cast.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_since.h
+memory_view.o: $(hdrdir)/ruby/internal/config.h
+memory_view.o: $(hdrdir)/ruby/internal/constant_p.h
+memory_view.o: $(hdrdir)/ruby/internal/core.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rarray.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rbasic.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rbignum.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rclass.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rdata.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rfile.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rhash.h
+memory_view.o: $(hdrdir)/ruby/internal/core/robject.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rregexp.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rstring.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rstruct.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+memory_view.o: $(hdrdir)/ruby/internal/ctype.h
+memory_view.o: $(hdrdir)/ruby/internal/dllexport.h
+memory_view.o: $(hdrdir)/ruby/internal/dosish.h
+memory_view.o: $(hdrdir)/ruby/internal/error.h
+memory_view.o: $(hdrdir)/ruby/internal/eval.h
+memory_view.o: $(hdrdir)/ruby/internal/event.h
+memory_view.o: $(hdrdir)/ruby/internal/fl_type.h
+memory_view.o: $(hdrdir)/ruby/internal/gc.h
+memory_view.o: $(hdrdir)/ruby/internal/glob.h
+memory_view.o: $(hdrdir)/ruby/internal/globals.h
+memory_view.o: $(hdrdir)/ruby/internal/has/attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/builtin.h
+memory_view.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/extension.h
+memory_view.o: $(hdrdir)/ruby/internal/has/feature.h
+memory_view.o: $(hdrdir)/ruby/internal/has/warning.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/array.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/bignum.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/class.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/compar.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/complex.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/cont.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/dir.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/enum.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/error.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/file.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/io.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/load.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/marshal.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/numeric.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/object.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/parse.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/proc.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/process.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/random.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/range.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/rational.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/re.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/ruby.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/select.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/signal.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/string.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/struct.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/thread.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/time.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/variable.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/vm.h
+memory_view.o: $(hdrdir)/ruby/internal/interpreter.h
+memory_view.o: $(hdrdir)/ruby/internal/iterator.h
+memory_view.o: $(hdrdir)/ruby/internal/memory.h
+memory_view.o: $(hdrdir)/ruby/internal/method.h
+memory_view.o: $(hdrdir)/ruby/internal/module.h
+memory_view.o: $(hdrdir)/ruby/internal/newobj.h
+memory_view.o: $(hdrdir)/ruby/internal/rgengc.h
+memory_view.o: $(hdrdir)/ruby/internal/scan_args.h
+memory_view.o: $(hdrdir)/ruby/internal/special_consts.h
+memory_view.o: $(hdrdir)/ruby/internal/static_assert.h
+memory_view.o: $(hdrdir)/ruby/internal/stdalign.h
+memory_view.o: $(hdrdir)/ruby/internal/stdbool.h
+memory_view.o: $(hdrdir)/ruby/internal/symbol.h
+memory_view.o: $(hdrdir)/ruby/internal/token_paste.h
+memory_view.o: $(hdrdir)/ruby/internal/value.h
+memory_view.o: $(hdrdir)/ruby/internal/value_type.h
+memory_view.o: $(hdrdir)/ruby/internal/variable.h
+memory_view.o: $(hdrdir)/ruby/internal/warning_push.h
+memory_view.o: $(hdrdir)/ruby/internal/xmalloc.h
+memory_view.o: $(hdrdir)/ruby/memory_view.h
+memory_view.o: $(hdrdir)/ruby/missing.h
+memory_view.o: $(hdrdir)/ruby/ruby.h
+memory_view.o: $(hdrdir)/ruby/st.h
+memory_view.o: $(hdrdir)/ruby/subst.h
+memory_view.o: memory_view.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/memory_view/extconf.rb b/ext/-test-/memory_view/extconf.rb
new file mode 100644
index 0000000000..d786b15db9
--- /dev/null
+++ b/ext/-test-/memory_view/extconf.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: false
+require_relative "../auto_ext.rb"
+auto_ext(inc: true)
diff --git a/ext/-test-/memory_view/memory_view.c b/ext/-test-/memory_view/memory_view.c
new file mode 100644
index 0000000000..3156dd3101
--- /dev/null
+++ b/ext/-test-/memory_view/memory_view.c
@@ -0,0 +1,446 @@
+#include "ruby.h"
+#include "ruby/memory_view.h"
+
+#define STRUCT_ALIGNOF(T, result) do { \
+ (result) = RUBY_ALIGNOF(T); \
+} while(0)
+
+static ID id_str;
+static VALUE sym_format;
+static VALUE sym_native_size_p;
+static VALUE sym_offset;
+static VALUE sym_size;
+static VALUE sym_repeat;
+static VALUE sym_obj;
+static VALUE sym_byte_size;
+static VALUE sym_readonly;
+static VALUE sym_format;
+static VALUE sym_item_size;
+static VALUE sym_ndim;
+static VALUE sym_shape;
+static VALUE sym_strides;
+static VALUE sym_sub_offsets;
+static VALUE sym_endianness;
+static VALUE sym_little_endian;
+static VALUE sym_big_endian;
+
+static bool
+exportable_string_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
+{
+ VALUE str = rb_ivar_get(obj, id_str);
+ rb_memory_view_init_as_byte_array(view, obj, RSTRING_PTR(str), RSTRING_LEN(str), true);
+ return true;
+}
+
+static bool
+exportable_string_memory_view_available_p(VALUE obj)
+{
+ VALUE str = rb_ivar_get(obj, id_str);
+ return !NIL_P(str);
+}
+
+static const rb_memory_view_entry_t exportable_string_memory_view_entry = {
+ exportable_string_get_memory_view,
+ NULL,
+ exportable_string_memory_view_available_p
+};
+
+static VALUE
+memory_view_available_p(VALUE mod, VALUE obj)
+{
+ return rb_memory_view_available_p(obj) ? Qtrue : Qfalse;
+}
+
+static VALUE
+memory_view_register(VALUE mod, VALUE obj)
+{
+ return rb_memory_view_register(obj, &exportable_string_memory_view_entry) ? Qtrue : Qfalse;
+}
+
+static VALUE
+memory_view_item_size_from_format(VALUE mod, VALUE format)
+{
+ const char *c_str = NULL;
+ if (!NIL_P(format))
+ c_str = StringValueCStr(format);
+ const char *err = NULL;
+ ssize_t item_size = rb_memory_view_item_size_from_format(c_str, &err);
+ if (!err)
+ return rb_assoc_new(SSIZET2NUM(item_size), Qnil);
+ else
+ return rb_assoc_new(SSIZET2NUM(item_size), rb_str_new_cstr(err));
+}
+
+static VALUE
+memory_view_parse_item_format(VALUE mod, VALUE format)
+{
+ const char *c_str = NULL;
+ if (!NIL_P(format))
+ c_str = StringValueCStr(format);
+ const char *err = NULL;
+
+ rb_memory_view_item_component_t *members;
+ size_t n_members;
+ ssize_t item_size = rb_memory_view_parse_item_format(c_str, &members, &n_members, &err);
+
+ VALUE result = rb_ary_new_capa(3);
+ rb_ary_push(result, SSIZET2NUM(item_size));
+
+ if (!err) {
+ VALUE ary = rb_ary_new_capa((long)n_members);
+ size_t i;
+ for (i = 0; i < n_members; ++i) {
+ VALUE member = rb_hash_new();
+ rb_hash_aset(member, sym_format, rb_str_new(&members[i].format, 1));
+ rb_hash_aset(member, sym_native_size_p, members[i].native_size_p ? Qtrue : Qfalse);
+ rb_hash_aset(member, sym_endianness, members[i].little_endian_p ? sym_little_endian : sym_big_endian);
+ rb_hash_aset(member, sym_offset, SSIZET2NUM(members[i].offset));
+ rb_hash_aset(member, sym_size, SSIZET2NUM(members[i].size));
+ rb_hash_aset(member, sym_repeat, SSIZET2NUM(members[i].repeat));
+ rb_ary_push(ary, member);
+ }
+ xfree(members);
+ rb_ary_push(result, ary);
+ rb_ary_push(result, Qnil);
+ }
+ else {
+ rb_ary_push(result, Qnil); // members
+ rb_ary_push(result, rb_str_new_cstr(err));
+ }
+
+ return result;
+}
+
+static VALUE
+memory_view_get_memory_view_info(VALUE mod, VALUE obj)
+{
+ rb_memory_view_t view;
+
+ if (!rb_memory_view_get(obj, &view, 0)) {
+ return Qnil;
+ }
+
+ VALUE hash = rb_hash_new();
+ rb_hash_aset(hash, sym_obj, view.obj);
+ rb_hash_aset(hash, sym_byte_size, SSIZET2NUM(view.byte_size));
+ rb_hash_aset(hash, sym_readonly, view.readonly ? Qtrue : Qfalse);
+ rb_hash_aset(hash, sym_format, view.format ? rb_str_new_cstr(view.format) : Qnil);
+ rb_hash_aset(hash, sym_item_size, SSIZET2NUM(view.item_size));
+ rb_hash_aset(hash, sym_ndim, SSIZET2NUM(view.ndim));
+
+ if (view.shape) {
+ VALUE shape = rb_ary_new_capa(view.ndim);
+ rb_hash_aset(hash, sym_shape, shape);
+ }
+ else {
+ rb_hash_aset(hash, sym_shape, Qnil);
+ }
+
+ if (view.strides) {
+ VALUE strides = rb_ary_new_capa(view.ndim);
+ rb_hash_aset(hash, sym_strides, strides);
+ }
+ else {
+ rb_hash_aset(hash, sym_strides, Qnil);
+ }
+
+ if (view.sub_offsets) {
+ VALUE sub_offsets = rb_ary_new_capa(view.ndim);
+ rb_hash_aset(hash, sym_sub_offsets, sub_offsets);
+ }
+ else {
+ rb_hash_aset(hash, sym_sub_offsets, Qnil);
+ }
+
+ rb_memory_view_release(&view);
+
+ return hash;
+}
+
+static VALUE
+memory_view_fill_contiguous_strides(VALUE mod, VALUE ndim_v, VALUE item_size_v, VALUE shape_v, VALUE row_major_p)
+{
+ ssize_t i, ndim = NUM2SSIZET(ndim_v);
+
+ Check_Type(shape_v, T_ARRAY);
+ ssize_t *shape = ALLOC_N(ssize_t, ndim);
+ for (i = 0; i < ndim; ++i) {
+ shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i));
+ }
+
+ ssize_t *strides = ALLOC_N(ssize_t, ndim);
+ rb_memory_view_fill_contiguous_strides(ndim, NUM2SSIZET(item_size_v), shape, RTEST(row_major_p), strides);
+
+ VALUE result = rb_ary_new_capa(ndim);
+ for (i = 0; i < ndim; ++i) {
+ rb_ary_push(result, SSIZET2NUM(strides[i]));
+ }
+
+ xfree(strides);
+ xfree(shape);
+
+ return result;
+}
+
+static VALUE
+memory_view_get_ref_count(VALUE obj)
+{
+ extern VALUE rb_memory_view_exported_object_registry;
+ extern const rb_data_type_t rb_memory_view_exported_object_registry_data_type;
+
+ if (rb_memory_view_exported_object_registry == Qundef) {
+ return Qnil;
+ }
+
+ st_table *table;
+ TypedData_Get_Struct(rb_memory_view_exported_object_registry, st_table,
+ &rb_memory_view_exported_object_registry_data_type,
+ table);
+
+ st_data_t count;
+ if (st_lookup(table, (st_data_t)obj, &count)) {
+ return ULL2NUM(count);
+ }
+
+ return Qnil;
+}
+
+static VALUE
+memory_view_ref_count_while_exporting_i(VALUE obj, long n)
+{
+ if (n == 0) {
+ return memory_view_get_ref_count(obj);
+ }
+
+ rb_memory_view_t view;
+ if (!rb_memory_view_get(obj, &view, 0)) {
+ return Qnil;
+ }
+
+ VALUE ref_count = memory_view_ref_count_while_exporting_i(obj, n-1);
+ rb_memory_view_release(&view);
+
+ return ref_count;
+}
+
+static VALUE
+memory_view_ref_count_while_exporting(VALUE mod, VALUE obj, VALUE n)
+{
+ Check_Type(n, T_FIXNUM);
+ return memory_view_ref_count_while_exporting_i(obj, FIX2LONG(n));
+}
+
+static VALUE
+memory_view_extract_item_members(VALUE mod, VALUE str, VALUE format)
+{
+ StringValue(str);
+ StringValue(format);
+
+ rb_memory_view_item_component_t *members;
+ size_t n_members;
+ const char *err = NULL;
+ (void)rb_memory_view_parse_item_format(RSTRING_PTR(format), &members, &n_members, &err);
+ if (err != NULL) {
+ rb_raise(rb_eArgError, "Unable to parse item format");
+ }
+
+ VALUE item = rb_memory_view_extract_item_members(RSTRING_PTR(str), members, n_members);
+ xfree(members);
+
+ return item;
+}
+
+static VALUE
+expstr_initialize(VALUE obj, VALUE s)
+{
+ if (!NIL_P(s)) {
+ Check_Type(s, T_STRING);
+ }
+ rb_ivar_set(obj, id_str, s);
+ return Qnil;
+}
+
+static bool
+mdview_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
+{
+ VALUE buf_v = rb_ivar_get(obj, id_str);
+ VALUE format_v = rb_ivar_get(obj, SYM2ID(sym_format));
+ VALUE shape_v = rb_ivar_get(obj, SYM2ID(sym_shape));
+ VALUE strides_v = rb_ivar_get(obj, SYM2ID(sym_strides));
+
+ const char *err;
+ const ssize_t item_size = rb_memory_view_item_size_from_format(RSTRING_PTR(format_v), &err);
+ if (item_size < 0) {
+ return false;
+ }
+
+ ssize_t ndim = RARRAY_LEN(shape_v);
+ if (!NIL_P(strides_v) && RARRAY_LEN(strides_v) != ndim) {
+ rb_raise(rb_eArgError, "strides has an invalid dimension");
+ }
+
+ ssize_t *shape = ALLOC_N(ssize_t, ndim);
+ ssize_t *strides = ALLOC_N(ssize_t, ndim);
+ ssize_t i;
+ if (!NIL_P(strides_v)) {
+ for (i = 0; i < ndim; ++i) {
+ shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i));
+ strides[i] = NUM2SSIZET(RARRAY_AREF(strides_v, i));
+ }
+ }
+ else {
+ for (i = 0; i < ndim; ++i) {
+ shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i));
+ }
+
+ i = ndim - 1;
+ strides[i] = item_size;
+ for (; i > 0; --i) {
+ strides[i-1] = strides[i] * shape[i];
+ }
+ }
+
+ rb_memory_view_init_as_byte_array(view, obj, RSTRING_PTR(buf_v), RSTRING_LEN(buf_v), true);
+ view->format = RSTRING_PTR(format_v);
+ view->item_size = item_size;
+ view->ndim = ndim;
+ view->shape = shape;
+ view->strides = strides;
+ view->sub_offsets = NULL;
+
+ return true;
+}
+
+static bool
+mdview_release_memory_view(VALUE obj, rb_memory_view_t *view)
+{
+ if (view->shape) xfree((void *)view->shape);
+ if (view->strides) xfree((void *)view->strides);
+
+ return true;
+}
+
+static bool
+mdview_memory_view_available_p(VALUE obj)
+{
+ return true;
+}
+
+static const rb_memory_view_entry_t mdview_memory_view_entry = {
+ mdview_get_memory_view,
+ mdview_release_memory_view,
+ mdview_memory_view_available_p
+};
+
+static VALUE
+mdview_initialize(VALUE obj, VALUE buf, VALUE format, VALUE shape, VALUE strides)
+{
+ Check_Type(buf, T_STRING);
+ StringValue(format);
+ Check_Type(shape, T_ARRAY);
+ if (!NIL_P(strides)) Check_Type(strides, T_ARRAY);
+
+ rb_ivar_set(obj, id_str, buf);
+ rb_ivar_set(obj, SYM2ID(sym_format), format);
+ rb_ivar_set(obj, SYM2ID(sym_shape), shape);
+ rb_ivar_set(obj, SYM2ID(sym_strides), strides);
+ return Qnil;
+}
+
+static VALUE
+mdview_aref(VALUE obj, VALUE indices_v)
+{
+ Check_Type(indices_v, T_ARRAY);
+
+ rb_memory_view_t view;
+ if (!rb_memory_view_get(obj, &view, 0)) {
+ rb_raise(rb_eRuntimeError, "rb_memory_view_get: failed");
+ }
+
+ if (RARRAY_LEN(indices_v) != view.ndim) {
+ rb_raise(rb_eKeyError, "Indices has an invalid dimension");
+ }
+
+ VALUE buf_indices;
+ ssize_t *indices = ALLOCV_N(ssize_t, buf_indices, view.ndim);
+
+ ssize_t i;
+ for (i = 0; i < view.ndim; ++i) {
+ indices[i] = NUM2SSIZET(RARRAY_AREF(indices_v, i));
+ }
+
+ VALUE result = rb_memory_view_get_item(&view, indices);
+ ALLOCV_END(buf_indices);
+ rb_memory_view_release(&view);
+
+ return result;
+}
+
+void
+Init_memory_view(void)
+{
+ rb_ext_ractor_safe(true);
+ VALUE mMemoryViewTestUtils = rb_define_module("MemoryViewTestUtils");
+
+ rb_define_module_function(mMemoryViewTestUtils, "available?", memory_view_available_p, 1);
+ rb_define_module_function(mMemoryViewTestUtils, "register", memory_view_register, 1);
+ rb_define_module_function(mMemoryViewTestUtils, "item_size_from_format", memory_view_item_size_from_format, 1);
+ rb_define_module_function(mMemoryViewTestUtils, "parse_item_format", memory_view_parse_item_format, 1);
+ rb_define_module_function(mMemoryViewTestUtils, "get_memory_view_info", memory_view_get_memory_view_info, 1);
+ rb_define_module_function(mMemoryViewTestUtils, "fill_contiguous_strides", memory_view_fill_contiguous_strides, 4);
+ rb_define_module_function(mMemoryViewTestUtils, "ref_count_while_exporting", memory_view_ref_count_while_exporting, 2);
+ rb_define_module_function(mMemoryViewTestUtils, "extract_item_members", memory_view_extract_item_members, 2);
+
+ VALUE cExportableString = rb_define_class_under(mMemoryViewTestUtils, "ExportableString", rb_cObject);
+ rb_define_method(cExportableString, "initialize", expstr_initialize, 1);
+ rb_memory_view_register(cExportableString, &exportable_string_memory_view_entry);
+
+ VALUE cMDView = rb_define_class_under(mMemoryViewTestUtils, "MultiDimensionalView", rb_cObject);
+ rb_define_method(cMDView, "initialize", mdview_initialize, 4);
+ rb_define_method(cMDView, "[]", mdview_aref, 1);
+ rb_memory_view_register(cMDView, &mdview_memory_view_entry);
+
+ id_str = rb_intern_const("__str__");
+ sym_format = ID2SYM(rb_intern_const("format"));
+ sym_native_size_p = ID2SYM(rb_intern_const("native_size_p"));
+ sym_offset = ID2SYM(rb_intern_const("offset"));
+ sym_size = ID2SYM(rb_intern_const("size"));
+ sym_repeat = ID2SYM(rb_intern_const("repeat"));
+ sym_obj = ID2SYM(rb_intern_const("obj"));
+ sym_byte_size = ID2SYM(rb_intern_const("byte_size"));
+ sym_readonly = ID2SYM(rb_intern_const("readonly"));
+ sym_format = ID2SYM(rb_intern_const("format"));
+ sym_item_size = ID2SYM(rb_intern_const("item_size"));
+ sym_ndim = ID2SYM(rb_intern_const("ndim"));
+ sym_shape = ID2SYM(rb_intern_const("shape"));
+ sym_strides = ID2SYM(rb_intern_const("strides"));
+ sym_sub_offsets = ID2SYM(rb_intern_const("sub_offsets"));
+ sym_endianness = ID2SYM(rb_intern_const("endianness"));
+ sym_little_endian = ID2SYM(rb_intern_const("little_endian"));
+ sym_big_endian = ID2SYM(rb_intern_const("big_endian"));
+
+#ifdef WORDS_BIGENDIAN
+ rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_big_endian);
+#else
+ rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_little_endian);
+#endif
+
+#define DEF_ALIGNMENT_CONST(type, TYPE) do { \
+ int alignment; \
+ STRUCT_ALIGNOF(type, alignment); \
+ rb_const_set(mMemoryViewTestUtils, rb_intern_const(#TYPE "_ALIGNMENT"), INT2FIX(alignment)); \
+} while(0)
+
+ DEF_ALIGNMENT_CONST(short, SHORT);
+ DEF_ALIGNMENT_CONST(int, INT);
+ DEF_ALIGNMENT_CONST(long, LONG);
+ DEF_ALIGNMENT_CONST(LONG_LONG, LONG_LONG);
+ DEF_ALIGNMENT_CONST(int16_t, INT16);
+ DEF_ALIGNMENT_CONST(int32_t, INT32);
+ DEF_ALIGNMENT_CONST(int64_t, INT64);
+ DEF_ALIGNMENT_CONST(intptr_t, INTPTR);
+ DEF_ALIGNMENT_CONST(float, FLOAT);
+ DEF_ALIGNMENT_CONST(double, DOUBLE);
+
+#undef DEF_ALIGNMENT_CONST
+}
diff --git a/ext/-test-/method/depend b/ext/-test-/method/depend
new file mode 100644
index 0000000000..7fdf2bc929
--- /dev/null
+++ b/ext/-test-/method/depend
@@ -0,0 +1,324 @@
+# AUTOGENERATED DEPENDENCIES START
+arity.o: $(RUBY_EXTCONF_H)
+arity.o: $(arch_hdrdir)/ruby/config.h
+arity.o: $(hdrdir)/ruby.h
+arity.o: $(hdrdir)/ruby/internal/anyargs.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+arity.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+arity.o: $(hdrdir)/ruby/internal/assume.h
+arity.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+arity.o: $(hdrdir)/ruby/internal/attr/artificial.h
+arity.o: $(hdrdir)/ruby/internal/attr/cold.h
+arity.o: $(hdrdir)/ruby/internal/attr/const.h
+arity.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+arity.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+arity.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+arity.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+arity.o: $(hdrdir)/ruby/internal/attr/error.h
+arity.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+arity.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+arity.o: $(hdrdir)/ruby/internal/attr/format.h
+arity.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+arity.o: $(hdrdir)/ruby/internal/attr/noalias.h
+arity.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+arity.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+arity.o: $(hdrdir)/ruby/internal/attr/noinline.h
+arity.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+arity.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+arity.o: $(hdrdir)/ruby/internal/attr/pure.h
+arity.o: $(hdrdir)/ruby/internal/attr/restrict.h
+arity.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+arity.o: $(hdrdir)/ruby/internal/attr/warning.h
+arity.o: $(hdrdir)/ruby/internal/attr/weakref.h
+arity.o: $(hdrdir)/ruby/internal/cast.h
+arity.o: $(hdrdir)/ruby/internal/compiler_is.h
+arity.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+arity.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+arity.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+arity.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+arity.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+arity.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+arity.o: $(hdrdir)/ruby/internal/compiler_since.h
+arity.o: $(hdrdir)/ruby/internal/config.h
+arity.o: $(hdrdir)/ruby/internal/constant_p.h
+arity.o: $(hdrdir)/ruby/internal/core.h
+arity.o: $(hdrdir)/ruby/internal/core/rarray.h
+arity.o: $(hdrdir)/ruby/internal/core/rbasic.h
+arity.o: $(hdrdir)/ruby/internal/core/rbignum.h
+arity.o: $(hdrdir)/ruby/internal/core/rclass.h
+arity.o: $(hdrdir)/ruby/internal/core/rdata.h
+arity.o: $(hdrdir)/ruby/internal/core/rfile.h
+arity.o: $(hdrdir)/ruby/internal/core/rhash.h
+arity.o: $(hdrdir)/ruby/internal/core/robject.h
+arity.o: $(hdrdir)/ruby/internal/core/rregexp.h
+arity.o: $(hdrdir)/ruby/internal/core/rstring.h
+arity.o: $(hdrdir)/ruby/internal/core/rstruct.h
+arity.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+arity.o: $(hdrdir)/ruby/internal/ctype.h
+arity.o: $(hdrdir)/ruby/internal/dllexport.h
+arity.o: $(hdrdir)/ruby/internal/dosish.h
+arity.o: $(hdrdir)/ruby/internal/error.h
+arity.o: $(hdrdir)/ruby/internal/eval.h
+arity.o: $(hdrdir)/ruby/internal/event.h
+arity.o: $(hdrdir)/ruby/internal/fl_type.h
+arity.o: $(hdrdir)/ruby/internal/gc.h
+arity.o: $(hdrdir)/ruby/internal/glob.h
+arity.o: $(hdrdir)/ruby/internal/globals.h
+arity.o: $(hdrdir)/ruby/internal/has/attribute.h
+arity.o: $(hdrdir)/ruby/internal/has/builtin.h
+arity.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+arity.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+arity.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+arity.o: $(hdrdir)/ruby/internal/has/extension.h
+arity.o: $(hdrdir)/ruby/internal/has/feature.h
+arity.o: $(hdrdir)/ruby/internal/has/warning.h
+arity.o: $(hdrdir)/ruby/internal/intern/array.h
+arity.o: $(hdrdir)/ruby/internal/intern/bignum.h
+arity.o: $(hdrdir)/ruby/internal/intern/class.h
+arity.o: $(hdrdir)/ruby/internal/intern/compar.h
+arity.o: $(hdrdir)/ruby/internal/intern/complex.h
+arity.o: $(hdrdir)/ruby/internal/intern/cont.h
+arity.o: $(hdrdir)/ruby/internal/intern/dir.h
+arity.o: $(hdrdir)/ruby/internal/intern/enum.h
+arity.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+arity.o: $(hdrdir)/ruby/internal/intern/error.h
+arity.o: $(hdrdir)/ruby/internal/intern/eval.h
+arity.o: $(hdrdir)/ruby/internal/intern/file.h
+arity.o: $(hdrdir)/ruby/internal/intern/gc.h
+arity.o: $(hdrdir)/ruby/internal/intern/hash.h
+arity.o: $(hdrdir)/ruby/internal/intern/io.h
+arity.o: $(hdrdir)/ruby/internal/intern/load.h
+arity.o: $(hdrdir)/ruby/internal/intern/marshal.h
+arity.o: $(hdrdir)/ruby/internal/intern/numeric.h
+arity.o: $(hdrdir)/ruby/internal/intern/object.h
+arity.o: $(hdrdir)/ruby/internal/intern/parse.h
+arity.o: $(hdrdir)/ruby/internal/intern/proc.h
+arity.o: $(hdrdir)/ruby/internal/intern/process.h
+arity.o: $(hdrdir)/ruby/internal/intern/random.h
+arity.o: $(hdrdir)/ruby/internal/intern/range.h
+arity.o: $(hdrdir)/ruby/internal/intern/rational.h
+arity.o: $(hdrdir)/ruby/internal/intern/re.h
+arity.o: $(hdrdir)/ruby/internal/intern/ruby.h
+arity.o: $(hdrdir)/ruby/internal/intern/select.h
+arity.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+arity.o: $(hdrdir)/ruby/internal/intern/signal.h
+arity.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+arity.o: $(hdrdir)/ruby/internal/intern/string.h
+arity.o: $(hdrdir)/ruby/internal/intern/struct.h
+arity.o: $(hdrdir)/ruby/internal/intern/thread.h
+arity.o: $(hdrdir)/ruby/internal/intern/time.h
+arity.o: $(hdrdir)/ruby/internal/intern/variable.h
+arity.o: $(hdrdir)/ruby/internal/intern/vm.h
+arity.o: $(hdrdir)/ruby/internal/interpreter.h
+arity.o: $(hdrdir)/ruby/internal/iterator.h
+arity.o: $(hdrdir)/ruby/internal/memory.h
+arity.o: $(hdrdir)/ruby/internal/method.h
+arity.o: $(hdrdir)/ruby/internal/module.h
+arity.o: $(hdrdir)/ruby/internal/newobj.h
+arity.o: $(hdrdir)/ruby/internal/rgengc.h
+arity.o: $(hdrdir)/ruby/internal/scan_args.h
+arity.o: $(hdrdir)/ruby/internal/special_consts.h
+arity.o: $(hdrdir)/ruby/internal/static_assert.h
+arity.o: $(hdrdir)/ruby/internal/stdalign.h
+arity.o: $(hdrdir)/ruby/internal/stdbool.h
+arity.o: $(hdrdir)/ruby/internal/symbol.h
+arity.o: $(hdrdir)/ruby/internal/token_paste.h
+arity.o: $(hdrdir)/ruby/internal/value.h
+arity.o: $(hdrdir)/ruby/internal/value_type.h
+arity.o: $(hdrdir)/ruby/internal/variable.h
+arity.o: $(hdrdir)/ruby/internal/warning_push.h
+arity.o: $(hdrdir)/ruby/internal/xmalloc.h
+arity.o: $(hdrdir)/ruby/assert.h
+arity.o: $(hdrdir)/ruby/backward.h
+arity.o: $(hdrdir)/ruby/backward/2/assume.h
+arity.o: $(hdrdir)/ruby/backward/2/attributes.h
+arity.o: $(hdrdir)/ruby/backward/2/bool.h
+arity.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+arity.o: $(hdrdir)/ruby/backward/2/inttypes.h
+arity.o: $(hdrdir)/ruby/backward/2/limits.h
+arity.o: $(hdrdir)/ruby/backward/2/long_long.h
+arity.o: $(hdrdir)/ruby/backward/2/stdalign.h
+arity.o: $(hdrdir)/ruby/backward/2/stdarg.h
+arity.o: $(hdrdir)/ruby/defines.h
+arity.o: $(hdrdir)/ruby/intern.h
+arity.o: $(hdrdir)/ruby/missing.h
+arity.o: $(hdrdir)/ruby/ruby.h
+arity.o: $(hdrdir)/ruby/st.h
+arity.o: $(hdrdir)/ruby/subst.h
+arity.o: arity.c
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/notimplement/bug.c b/ext/-test-/notimplement/bug.c
index 8e9cae707a..82e243a81d 100644
--- a/ext/-test-/notimplement/bug.c
+++ b/ext/-test-/notimplement/bug.c
@@ -11,6 +11,8 @@ void
Init_notimplement(void)
{
VALUE mBug = rb_define_module("Bug");
+ VALUE klass = rb_define_class_under(mBug, "NotImplement", rb_cObject);
rb_define_module_function(mBug, "funcall", bug_funcall, -1);
rb_define_module_function(mBug, "notimplement", rb_f_notimplement, -1);
+ rb_define_method(klass, "notimplement", rb_f_notimplement, -1);
}
diff --git a/ext/-test-/notimplement/depend b/ext/-test-/notimplement/depend
new file mode 100644
index 0000000000..a21935558d
--- /dev/null
+++ b/ext/-test-/notimplement/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+bug.o: $(RUBY_EXTCONF_H)
+bug.o: $(arch_hdrdir)/ruby/config.h
+bug.o: $(hdrdir)/ruby.h
+bug.o: $(hdrdir)/ruby/internal/anyargs.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bug.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bug.o: $(hdrdir)/ruby/internal/assume.h
+bug.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bug.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bug.o: $(hdrdir)/ruby/internal/attr/cold.h
+bug.o: $(hdrdir)/ruby/internal/attr/const.h
+bug.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bug.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bug.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bug.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bug.o: $(hdrdir)/ruby/internal/attr/error.h
+bug.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bug.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bug.o: $(hdrdir)/ruby/internal/attr/format.h
+bug.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bug.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bug.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bug.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bug.o: $(hdrdir)/ruby/internal/attr/pure.h
+bug.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bug.o: $(hdrdir)/ruby/internal/attr/warning.h
+bug.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bug.o: $(hdrdir)/ruby/internal/cast.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bug.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bug.o: $(hdrdir)/ruby/internal/compiler_since.h
+bug.o: $(hdrdir)/ruby/internal/config.h
+bug.o: $(hdrdir)/ruby/internal/constant_p.h
+bug.o: $(hdrdir)/ruby/internal/core.h
+bug.o: $(hdrdir)/ruby/internal/core/rarray.h
+bug.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bug.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bug.o: $(hdrdir)/ruby/internal/core/rclass.h
+bug.o: $(hdrdir)/ruby/internal/core/rdata.h
+bug.o: $(hdrdir)/ruby/internal/core/rfile.h
+bug.o: $(hdrdir)/ruby/internal/core/rhash.h
+bug.o: $(hdrdir)/ruby/internal/core/robject.h
+bug.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bug.o: $(hdrdir)/ruby/internal/core/rstring.h
+bug.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bug.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bug.o: $(hdrdir)/ruby/internal/ctype.h
+bug.o: $(hdrdir)/ruby/internal/dllexport.h
+bug.o: $(hdrdir)/ruby/internal/dosish.h
+bug.o: $(hdrdir)/ruby/internal/error.h
+bug.o: $(hdrdir)/ruby/internal/eval.h
+bug.o: $(hdrdir)/ruby/internal/event.h
+bug.o: $(hdrdir)/ruby/internal/fl_type.h
+bug.o: $(hdrdir)/ruby/internal/gc.h
+bug.o: $(hdrdir)/ruby/internal/glob.h
+bug.o: $(hdrdir)/ruby/internal/globals.h
+bug.o: $(hdrdir)/ruby/internal/has/attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/builtin.h
+bug.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bug.o: $(hdrdir)/ruby/internal/has/extension.h
+bug.o: $(hdrdir)/ruby/internal/has/feature.h
+bug.o: $(hdrdir)/ruby/internal/has/warning.h
+bug.o: $(hdrdir)/ruby/internal/intern/array.h
+bug.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bug.o: $(hdrdir)/ruby/internal/intern/class.h
+bug.o: $(hdrdir)/ruby/internal/intern/compar.h
+bug.o: $(hdrdir)/ruby/internal/intern/complex.h
+bug.o: $(hdrdir)/ruby/internal/intern/cont.h
+bug.o: $(hdrdir)/ruby/internal/intern/dir.h
+bug.o: $(hdrdir)/ruby/internal/intern/enum.h
+bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bug.o: $(hdrdir)/ruby/internal/intern/error.h
+bug.o: $(hdrdir)/ruby/internal/intern/eval.h
+bug.o: $(hdrdir)/ruby/internal/intern/file.h
+bug.o: $(hdrdir)/ruby/internal/intern/gc.h
+bug.o: $(hdrdir)/ruby/internal/intern/hash.h
+bug.o: $(hdrdir)/ruby/internal/intern/io.h
+bug.o: $(hdrdir)/ruby/internal/intern/load.h
+bug.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bug.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bug.o: $(hdrdir)/ruby/internal/intern/object.h
+bug.o: $(hdrdir)/ruby/internal/intern/parse.h
+bug.o: $(hdrdir)/ruby/internal/intern/proc.h
+bug.o: $(hdrdir)/ruby/internal/intern/process.h
+bug.o: $(hdrdir)/ruby/internal/intern/random.h
+bug.o: $(hdrdir)/ruby/internal/intern/range.h
+bug.o: $(hdrdir)/ruby/internal/intern/rational.h
+bug.o: $(hdrdir)/ruby/internal/intern/re.h
+bug.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bug.o: $(hdrdir)/ruby/internal/intern/select.h
+bug.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bug.o: $(hdrdir)/ruby/internal/intern/signal.h
+bug.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bug.o: $(hdrdir)/ruby/internal/intern/string.h
+bug.o: $(hdrdir)/ruby/internal/intern/struct.h
+bug.o: $(hdrdir)/ruby/internal/intern/thread.h
+bug.o: $(hdrdir)/ruby/internal/intern/time.h
+bug.o: $(hdrdir)/ruby/internal/intern/variable.h
+bug.o: $(hdrdir)/ruby/internal/intern/vm.h
+bug.o: $(hdrdir)/ruby/internal/interpreter.h
+bug.o: $(hdrdir)/ruby/internal/iterator.h
+bug.o: $(hdrdir)/ruby/internal/memory.h
+bug.o: $(hdrdir)/ruby/internal/method.h
+bug.o: $(hdrdir)/ruby/internal/module.h
+bug.o: $(hdrdir)/ruby/internal/newobj.h
+bug.o: $(hdrdir)/ruby/internal/rgengc.h
+bug.o: $(hdrdir)/ruby/internal/scan_args.h
+bug.o: $(hdrdir)/ruby/internal/special_consts.h
+bug.o: $(hdrdir)/ruby/internal/static_assert.h
+bug.o: $(hdrdir)/ruby/internal/stdalign.h
+bug.o: $(hdrdir)/ruby/internal/stdbool.h
+bug.o: $(hdrdir)/ruby/internal/symbol.h
+bug.o: $(hdrdir)/ruby/internal/token_paste.h
+bug.o: $(hdrdir)/ruby/internal/value.h
+bug.o: $(hdrdir)/ruby/internal/value_type.h
+bug.o: $(hdrdir)/ruby/internal/variable.h
+bug.o: $(hdrdir)/ruby/internal/warning_push.h
+bug.o: $(hdrdir)/ruby/internal/xmalloc.h
+bug.o: $(hdrdir)/ruby/assert.h
+bug.o: $(hdrdir)/ruby/backward.h
+bug.o: $(hdrdir)/ruby/backward/2/assume.h
+bug.o: $(hdrdir)/ruby/backward/2/attributes.h
+bug.o: $(hdrdir)/ruby/backward/2/bool.h
+bug.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bug.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bug.o: $(hdrdir)/ruby/backward/2/limits.h
+bug.o: $(hdrdir)/ruby/backward/2/long_long.h
+bug.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bug.o: $(hdrdir)/ruby/backward/2/stdarg.h
+bug.o: $(hdrdir)/ruby/defines.h
+bug.o: $(hdrdir)/ruby/intern.h
+bug.o: $(hdrdir)/ruby/missing.h
+bug.o: $(hdrdir)/ruby/ruby.h
+bug.o: $(hdrdir)/ruby/st.h
+bug.o: $(hdrdir)/ruby/subst.h
+bug.o: bug.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/num2int/depend b/ext/-test-/num2int/depend
new file mode 100644
index 0000000000..4b455d12f6
--- /dev/null
+++ b/ext/-test-/num2int/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+num2int.o: $(RUBY_EXTCONF_H)
+num2int.o: $(arch_hdrdir)/ruby/config.h
+num2int.o: $(hdrdir)/ruby.h
+num2int.o: $(hdrdir)/ruby/internal/anyargs.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+num2int.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+num2int.o: $(hdrdir)/ruby/internal/assume.h
+num2int.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+num2int.o: $(hdrdir)/ruby/internal/attr/artificial.h
+num2int.o: $(hdrdir)/ruby/internal/attr/cold.h
+num2int.o: $(hdrdir)/ruby/internal/attr/const.h
+num2int.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+num2int.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+num2int.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+num2int.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+num2int.o: $(hdrdir)/ruby/internal/attr/error.h
+num2int.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+num2int.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+num2int.o: $(hdrdir)/ruby/internal/attr/format.h
+num2int.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+num2int.o: $(hdrdir)/ruby/internal/attr/noalias.h
+num2int.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+num2int.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+num2int.o: $(hdrdir)/ruby/internal/attr/noinline.h
+num2int.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+num2int.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+num2int.o: $(hdrdir)/ruby/internal/attr/pure.h
+num2int.o: $(hdrdir)/ruby/internal/attr/restrict.h
+num2int.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+num2int.o: $(hdrdir)/ruby/internal/attr/warning.h
+num2int.o: $(hdrdir)/ruby/internal/attr/weakref.h
+num2int.o: $(hdrdir)/ruby/internal/cast.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_is.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+num2int.o: $(hdrdir)/ruby/internal/compiler_since.h
+num2int.o: $(hdrdir)/ruby/internal/config.h
+num2int.o: $(hdrdir)/ruby/internal/constant_p.h
+num2int.o: $(hdrdir)/ruby/internal/core.h
+num2int.o: $(hdrdir)/ruby/internal/core/rarray.h
+num2int.o: $(hdrdir)/ruby/internal/core/rbasic.h
+num2int.o: $(hdrdir)/ruby/internal/core/rbignum.h
+num2int.o: $(hdrdir)/ruby/internal/core/rclass.h
+num2int.o: $(hdrdir)/ruby/internal/core/rdata.h
+num2int.o: $(hdrdir)/ruby/internal/core/rfile.h
+num2int.o: $(hdrdir)/ruby/internal/core/rhash.h
+num2int.o: $(hdrdir)/ruby/internal/core/robject.h
+num2int.o: $(hdrdir)/ruby/internal/core/rregexp.h
+num2int.o: $(hdrdir)/ruby/internal/core/rstring.h
+num2int.o: $(hdrdir)/ruby/internal/core/rstruct.h
+num2int.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+num2int.o: $(hdrdir)/ruby/internal/ctype.h
+num2int.o: $(hdrdir)/ruby/internal/dllexport.h
+num2int.o: $(hdrdir)/ruby/internal/dosish.h
+num2int.o: $(hdrdir)/ruby/internal/error.h
+num2int.o: $(hdrdir)/ruby/internal/eval.h
+num2int.o: $(hdrdir)/ruby/internal/event.h
+num2int.o: $(hdrdir)/ruby/internal/fl_type.h
+num2int.o: $(hdrdir)/ruby/internal/gc.h
+num2int.o: $(hdrdir)/ruby/internal/glob.h
+num2int.o: $(hdrdir)/ruby/internal/globals.h
+num2int.o: $(hdrdir)/ruby/internal/has/attribute.h
+num2int.o: $(hdrdir)/ruby/internal/has/builtin.h
+num2int.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+num2int.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+num2int.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+num2int.o: $(hdrdir)/ruby/internal/has/extension.h
+num2int.o: $(hdrdir)/ruby/internal/has/feature.h
+num2int.o: $(hdrdir)/ruby/internal/has/warning.h
+num2int.o: $(hdrdir)/ruby/internal/intern/array.h
+num2int.o: $(hdrdir)/ruby/internal/intern/bignum.h
+num2int.o: $(hdrdir)/ruby/internal/intern/class.h
+num2int.o: $(hdrdir)/ruby/internal/intern/compar.h
+num2int.o: $(hdrdir)/ruby/internal/intern/complex.h
+num2int.o: $(hdrdir)/ruby/internal/intern/cont.h
+num2int.o: $(hdrdir)/ruby/internal/intern/dir.h
+num2int.o: $(hdrdir)/ruby/internal/intern/enum.h
+num2int.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+num2int.o: $(hdrdir)/ruby/internal/intern/error.h
+num2int.o: $(hdrdir)/ruby/internal/intern/eval.h
+num2int.o: $(hdrdir)/ruby/internal/intern/file.h
+num2int.o: $(hdrdir)/ruby/internal/intern/gc.h
+num2int.o: $(hdrdir)/ruby/internal/intern/hash.h
+num2int.o: $(hdrdir)/ruby/internal/intern/io.h
+num2int.o: $(hdrdir)/ruby/internal/intern/load.h
+num2int.o: $(hdrdir)/ruby/internal/intern/marshal.h
+num2int.o: $(hdrdir)/ruby/internal/intern/numeric.h
+num2int.o: $(hdrdir)/ruby/internal/intern/object.h
+num2int.o: $(hdrdir)/ruby/internal/intern/parse.h
+num2int.o: $(hdrdir)/ruby/internal/intern/proc.h
+num2int.o: $(hdrdir)/ruby/internal/intern/process.h
+num2int.o: $(hdrdir)/ruby/internal/intern/random.h
+num2int.o: $(hdrdir)/ruby/internal/intern/range.h
+num2int.o: $(hdrdir)/ruby/internal/intern/rational.h
+num2int.o: $(hdrdir)/ruby/internal/intern/re.h
+num2int.o: $(hdrdir)/ruby/internal/intern/ruby.h
+num2int.o: $(hdrdir)/ruby/internal/intern/select.h
+num2int.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+num2int.o: $(hdrdir)/ruby/internal/intern/signal.h
+num2int.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+num2int.o: $(hdrdir)/ruby/internal/intern/string.h
+num2int.o: $(hdrdir)/ruby/internal/intern/struct.h
+num2int.o: $(hdrdir)/ruby/internal/intern/thread.h
+num2int.o: $(hdrdir)/ruby/internal/intern/time.h
+num2int.o: $(hdrdir)/ruby/internal/intern/variable.h
+num2int.o: $(hdrdir)/ruby/internal/intern/vm.h
+num2int.o: $(hdrdir)/ruby/internal/interpreter.h
+num2int.o: $(hdrdir)/ruby/internal/iterator.h
+num2int.o: $(hdrdir)/ruby/internal/memory.h
+num2int.o: $(hdrdir)/ruby/internal/method.h
+num2int.o: $(hdrdir)/ruby/internal/module.h
+num2int.o: $(hdrdir)/ruby/internal/newobj.h
+num2int.o: $(hdrdir)/ruby/internal/rgengc.h
+num2int.o: $(hdrdir)/ruby/internal/scan_args.h
+num2int.o: $(hdrdir)/ruby/internal/special_consts.h
+num2int.o: $(hdrdir)/ruby/internal/static_assert.h
+num2int.o: $(hdrdir)/ruby/internal/stdalign.h
+num2int.o: $(hdrdir)/ruby/internal/stdbool.h
+num2int.o: $(hdrdir)/ruby/internal/symbol.h
+num2int.o: $(hdrdir)/ruby/internal/token_paste.h
+num2int.o: $(hdrdir)/ruby/internal/value.h
+num2int.o: $(hdrdir)/ruby/internal/value_type.h
+num2int.o: $(hdrdir)/ruby/internal/variable.h
+num2int.o: $(hdrdir)/ruby/internal/warning_push.h
+num2int.o: $(hdrdir)/ruby/internal/xmalloc.h
+num2int.o: $(hdrdir)/ruby/assert.h
+num2int.o: $(hdrdir)/ruby/backward.h
+num2int.o: $(hdrdir)/ruby/backward/2/assume.h
+num2int.o: $(hdrdir)/ruby/backward/2/attributes.h
+num2int.o: $(hdrdir)/ruby/backward/2/bool.h
+num2int.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+num2int.o: $(hdrdir)/ruby/backward/2/inttypes.h
+num2int.o: $(hdrdir)/ruby/backward/2/limits.h
+num2int.o: $(hdrdir)/ruby/backward/2/long_long.h
+num2int.o: $(hdrdir)/ruby/backward/2/stdalign.h
+num2int.o: $(hdrdir)/ruby/backward/2/stdarg.h
+num2int.o: $(hdrdir)/ruby/defines.h
+num2int.o: $(hdrdir)/ruby/intern.h
+num2int.o: $(hdrdir)/ruby/missing.h
+num2int.o: $(hdrdir)/ruby/ruby.h
+num2int.o: $(hdrdir)/ruby/st.h
+num2int.o: $(hdrdir)/ruby/subst.h
+num2int.o: num2int.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/path_to_class/depend b/ext/-test-/path_to_class/depend
new file mode 100644
index 0000000000..b51619b905
--- /dev/null
+++ b/ext/-test-/path_to_class/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+path_to_class.o: $(RUBY_EXTCONF_H)
+path_to_class.o: $(arch_hdrdir)/ruby/config.h
+path_to_class.o: $(hdrdir)/ruby.h
+path_to_class.o: $(hdrdir)/ruby/internal/anyargs.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+path_to_class.o: $(hdrdir)/ruby/internal/assume.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/artificial.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/cold.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/const.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/error.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/format.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/noalias.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/noinline.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/pure.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/restrict.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/warning.h
+path_to_class.o: $(hdrdir)/ruby/internal/attr/weakref.h
+path_to_class.o: $(hdrdir)/ruby/internal/cast.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_is.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+path_to_class.o: $(hdrdir)/ruby/internal/compiler_since.h
+path_to_class.o: $(hdrdir)/ruby/internal/config.h
+path_to_class.o: $(hdrdir)/ruby/internal/constant_p.h
+path_to_class.o: $(hdrdir)/ruby/internal/core.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rarray.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rbasic.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rbignum.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rclass.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rdata.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rfile.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rhash.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/robject.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rregexp.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rstring.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rstruct.h
+path_to_class.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+path_to_class.o: $(hdrdir)/ruby/internal/ctype.h
+path_to_class.o: $(hdrdir)/ruby/internal/dllexport.h
+path_to_class.o: $(hdrdir)/ruby/internal/dosish.h
+path_to_class.o: $(hdrdir)/ruby/internal/error.h
+path_to_class.o: $(hdrdir)/ruby/internal/eval.h
+path_to_class.o: $(hdrdir)/ruby/internal/event.h
+path_to_class.o: $(hdrdir)/ruby/internal/fl_type.h
+path_to_class.o: $(hdrdir)/ruby/internal/gc.h
+path_to_class.o: $(hdrdir)/ruby/internal/glob.h
+path_to_class.o: $(hdrdir)/ruby/internal/globals.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/attribute.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/builtin.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/extension.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/feature.h
+path_to_class.o: $(hdrdir)/ruby/internal/has/warning.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/array.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/bignum.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/class.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/compar.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/complex.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/cont.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/dir.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/enum.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/error.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/eval.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/file.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/gc.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/hash.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/io.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/load.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/marshal.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/numeric.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/object.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/parse.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/proc.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/process.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/random.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/range.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/rational.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/re.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/ruby.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/select.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/signal.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/string.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/struct.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/thread.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/time.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/variable.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/vm.h
+path_to_class.o: $(hdrdir)/ruby/internal/interpreter.h
+path_to_class.o: $(hdrdir)/ruby/internal/iterator.h
+path_to_class.o: $(hdrdir)/ruby/internal/memory.h
+path_to_class.o: $(hdrdir)/ruby/internal/method.h
+path_to_class.o: $(hdrdir)/ruby/internal/module.h
+path_to_class.o: $(hdrdir)/ruby/internal/newobj.h
+path_to_class.o: $(hdrdir)/ruby/internal/rgengc.h
+path_to_class.o: $(hdrdir)/ruby/internal/scan_args.h
+path_to_class.o: $(hdrdir)/ruby/internal/special_consts.h
+path_to_class.o: $(hdrdir)/ruby/internal/static_assert.h
+path_to_class.o: $(hdrdir)/ruby/internal/stdalign.h
+path_to_class.o: $(hdrdir)/ruby/internal/stdbool.h
+path_to_class.o: $(hdrdir)/ruby/internal/symbol.h
+path_to_class.o: $(hdrdir)/ruby/internal/token_paste.h
+path_to_class.o: $(hdrdir)/ruby/internal/value.h
+path_to_class.o: $(hdrdir)/ruby/internal/value_type.h
+path_to_class.o: $(hdrdir)/ruby/internal/variable.h
+path_to_class.o: $(hdrdir)/ruby/internal/warning_push.h
+path_to_class.o: $(hdrdir)/ruby/internal/xmalloc.h
+path_to_class.o: $(hdrdir)/ruby/assert.h
+path_to_class.o: $(hdrdir)/ruby/backward.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/assume.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/attributes.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/bool.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/inttypes.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/limits.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/long_long.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/stdalign.h
+path_to_class.o: $(hdrdir)/ruby/backward/2/stdarg.h
+path_to_class.o: $(hdrdir)/ruby/defines.h
+path_to_class.o: $(hdrdir)/ruby/intern.h
+path_to_class.o: $(hdrdir)/ruby/missing.h
+path_to_class.o: $(hdrdir)/ruby/ruby.h
+path_to_class.o: $(hdrdir)/ruby/st.h
+path_to_class.o: $(hdrdir)/ruby/subst.h
+path_to_class.o: path_to_class.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/popen_deadlock/depend b/ext/-test-/popen_deadlock/depend
new file mode 100644
index 0000000000..316e2c6e04
--- /dev/null
+++ b/ext/-test-/popen_deadlock/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+infinite_loop_dlsym.o: $(RUBY_EXTCONF_H)
+infinite_loop_dlsym.o: $(arch_hdrdir)/ruby/config.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/anyargs.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/assume.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/artificial.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/cold.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/const.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/error.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/format.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noalias.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noinline.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/pure.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/restrict.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/warning.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/weakref.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/cast.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_is.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/compiler_since.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/config.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/constant_p.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rarray.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rbasic.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rbignum.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rclass.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rdata.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rfile.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rhash.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/robject.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rregexp.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rstring.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rstruct.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/ctype.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/dllexport.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/dosish.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/error.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/eval.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/event.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/fl_type.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/gc.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/glob.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/globals.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/attribute.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/builtin.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/extension.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/feature.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/has/warning.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/array.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/bignum.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/class.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/compar.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/complex.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/cont.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/dir.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/enum.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/error.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/eval.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/file.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/gc.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/hash.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/io.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/load.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/marshal.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/numeric.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/object.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/parse.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/proc.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/process.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/random.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/range.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/rational.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/re.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/ruby.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/select.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/signal.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/string.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/struct.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/thread.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/time.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/variable.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/vm.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/interpreter.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/iterator.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/memory.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/method.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/module.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/newobj.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/rgengc.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/scan_args.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/special_consts.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/static_assert.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/stdalign.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/stdbool.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/symbol.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/token_paste.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/value.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/value_type.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/variable.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/warning_push.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/xmalloc.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/assert.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/assume.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/attributes.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/bool.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/inttypes.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/limits.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/long_long.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/stdalign.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/stdarg.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/defines.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/intern.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/missing.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/ruby.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/st.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/subst.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/thread.h
+infinite_loop_dlsym.o: infinite_loop_dlsym.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/popen_deadlock/extconf.rb b/ext/-test-/popen_deadlock/extconf.rb
index 24a7d79931..6b6ee7a6b8 100644
--- a/ext/-test-/popen_deadlock/extconf.rb
+++ b/ext/-test-/popen_deadlock/extconf.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: false
case RUBY_PLATFORM
when /solaris/i, /linux/i
+ $LDFLAGS << " -ldl"
create_makefile("-test-/popen_deadlock/infinite_loop_dlsym")
end
diff --git a/ext/-test-/postponed_job/depend b/ext/-test-/postponed_job/depend
index d672e53f00..c76cf39089 100644
--- a/ext/-test-/postponed_job/depend
+++ b/ext/-test-/postponed_job/depend
@@ -1 +1,164 @@
-postponed_job.o: $(HDRS) $(ruby_headers) $(hdrdir)/ruby/debug.h
+# AUTOGENERATED DEPENDENCIES START
+postponed_job.o: $(RUBY_EXTCONF_H)
+postponed_job.o: $(arch_hdrdir)/ruby/config.h
+postponed_job.o: $(hdrdir)/ruby.h
+postponed_job.o: $(hdrdir)/ruby/internal/anyargs.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+postponed_job.o: $(hdrdir)/ruby/internal/assume.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/artificial.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/cold.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/const.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/error.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/format.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/noalias.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/noinline.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/pure.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/restrict.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/warning.h
+postponed_job.o: $(hdrdir)/ruby/internal/attr/weakref.h
+postponed_job.o: $(hdrdir)/ruby/internal/cast.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_is.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+postponed_job.o: $(hdrdir)/ruby/internal/compiler_since.h
+postponed_job.o: $(hdrdir)/ruby/internal/config.h
+postponed_job.o: $(hdrdir)/ruby/internal/constant_p.h
+postponed_job.o: $(hdrdir)/ruby/internal/core.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rarray.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rbasic.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rbignum.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rclass.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rdata.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rfile.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rhash.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/robject.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rregexp.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rstring.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rstruct.h
+postponed_job.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+postponed_job.o: $(hdrdir)/ruby/internal/ctype.h
+postponed_job.o: $(hdrdir)/ruby/internal/dllexport.h
+postponed_job.o: $(hdrdir)/ruby/internal/dosish.h
+postponed_job.o: $(hdrdir)/ruby/internal/error.h
+postponed_job.o: $(hdrdir)/ruby/internal/eval.h
+postponed_job.o: $(hdrdir)/ruby/internal/event.h
+postponed_job.o: $(hdrdir)/ruby/internal/fl_type.h
+postponed_job.o: $(hdrdir)/ruby/internal/gc.h
+postponed_job.o: $(hdrdir)/ruby/internal/glob.h
+postponed_job.o: $(hdrdir)/ruby/internal/globals.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/attribute.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/builtin.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/extension.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/feature.h
+postponed_job.o: $(hdrdir)/ruby/internal/has/warning.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/array.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/bignum.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/class.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/compar.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/complex.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/cont.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/dir.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/enum.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/error.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/eval.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/file.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/gc.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/hash.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/io.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/load.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/marshal.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/numeric.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/object.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/parse.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/proc.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/process.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/random.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/range.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/rational.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/re.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/ruby.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/select.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/signal.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/string.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/struct.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/thread.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/time.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/variable.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/vm.h
+postponed_job.o: $(hdrdir)/ruby/internal/interpreter.h
+postponed_job.o: $(hdrdir)/ruby/internal/iterator.h
+postponed_job.o: $(hdrdir)/ruby/internal/memory.h
+postponed_job.o: $(hdrdir)/ruby/internal/method.h
+postponed_job.o: $(hdrdir)/ruby/internal/module.h
+postponed_job.o: $(hdrdir)/ruby/internal/newobj.h
+postponed_job.o: $(hdrdir)/ruby/internal/rgengc.h
+postponed_job.o: $(hdrdir)/ruby/internal/scan_args.h
+postponed_job.o: $(hdrdir)/ruby/internal/special_consts.h
+postponed_job.o: $(hdrdir)/ruby/internal/static_assert.h
+postponed_job.o: $(hdrdir)/ruby/internal/stdalign.h
+postponed_job.o: $(hdrdir)/ruby/internal/stdbool.h
+postponed_job.o: $(hdrdir)/ruby/internal/symbol.h
+postponed_job.o: $(hdrdir)/ruby/internal/token_paste.h
+postponed_job.o: $(hdrdir)/ruby/internal/value.h
+postponed_job.o: $(hdrdir)/ruby/internal/value_type.h
+postponed_job.o: $(hdrdir)/ruby/internal/variable.h
+postponed_job.o: $(hdrdir)/ruby/internal/warning_push.h
+postponed_job.o: $(hdrdir)/ruby/internal/xmalloc.h
+postponed_job.o: $(hdrdir)/ruby/assert.h
+postponed_job.o: $(hdrdir)/ruby/backward.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/assume.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/attributes.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/bool.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/inttypes.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/limits.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/long_long.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/stdalign.h
+postponed_job.o: $(hdrdir)/ruby/backward/2/stdarg.h
+postponed_job.o: $(hdrdir)/ruby/debug.h
+postponed_job.o: $(hdrdir)/ruby/defines.h
+postponed_job.o: $(hdrdir)/ruby/intern.h
+postponed_job.o: $(hdrdir)/ruby/missing.h
+postponed_job.o: $(hdrdir)/ruby/ruby.h
+postponed_job.o: $(hdrdir)/ruby/st.h
+postponed_job.o: $(hdrdir)/ruby/subst.h
+postponed_job.o: postponed_job.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/postponed_job/postponed_job.c b/ext/-test-/postponed_job/postponed_job.c
index 157230e33b..fa57bef6f5 100644
--- a/ext/-test-/postponed_job/postponed_job.c
+++ b/ext/-test-/postponed_job/postponed_job.c
@@ -1,19 +1,28 @@
#include "ruby.h"
#include "ruby/debug.h"
+static int counter;
+
static void
pjob_callback(void *data)
{
VALUE ary = (VALUE)data;
Check_Type(ary, T_ARRAY);
- rb_ary_replace(ary, rb_funcall(Qnil, rb_intern("caller"), 0));
+ rb_ary_push(ary, INT2FIX(counter));
}
static VALUE
pjob_register(VALUE self, VALUE obj)
{
+ counter = 0;
rb_postponed_job_register(0, pjob_callback, (void *)obj);
+ rb_gc_start();
+ counter++;
+ rb_gc_start();
+ counter++;
+ rb_gc_start();
+ counter++;
return self;
}
@@ -38,10 +47,45 @@ pjob_register_one(VALUE self, VALUE obj)
static VALUE
pjob_call_direct(VALUE self, VALUE obj)
{
+ counter = 0;
pjob_callback((void *)obj);
+ rb_gc_start();
+ counter++;
+ rb_gc_start();
+ counter++;
+ rb_gc_start();
+ counter++;
return self;
}
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+
+static void *
+pjob_register_in_c_thread_i(void *obj)
+{
+ rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj);
+ rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj);
+ rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj);
+ return NULL;
+}
+
+static VALUE
+pjob_register_in_c_thread(VALUE self, VALUE obj)
+{
+ pthread_t thread;
+ if (pthread_create(&thread, NULL, pjob_register_in_c_thread_i, (void *)obj)) {
+ return Qfalse;
+ }
+
+ if (pthread_join(thread, NULL)) {
+ return Qfalse;
+ }
+
+ return Qtrue;
+}
+#endif
+
void
Init_postponed_job(VALUE self)
{
@@ -49,5 +93,8 @@ Init_postponed_job(VALUE self)
rb_define_module_function(mBug, "postponed_job_register", pjob_register, 1);
rb_define_module_function(mBug, "postponed_job_register_one", pjob_register_one, 1);
rb_define_module_function(mBug, "postponed_job_call_direct", pjob_call_direct, 1);
+#ifdef HAVE_PTHREAD_H
+ rb_define_module_function(mBug, "postponed_job_register_in_c_thread", pjob_register_in_c_thread, 1);
+#endif
}
diff --git a/ext/-test-/printf/depend b/ext/-test-/printf/depend
index 79b6c53f50..5f42702eaf 100644
--- a/ext/-test-/printf/depend
+++ b/ext/-test-/printf/depend
@@ -1,3 +1,166 @@
-$(OBJS): $(HDRS) $(ruby_headers) \
- $(hdrdir)/ruby/encoding.h \
- $(hdrdir)/ruby/oniguruma.h
+# AUTOGENERATED DEPENDENCIES START
+printf.o: $(RUBY_EXTCONF_H)
+printf.o: $(arch_hdrdir)/ruby/config.h
+printf.o: $(hdrdir)/ruby.h
+printf.o: $(hdrdir)/ruby/internal/anyargs.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+printf.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+printf.o: $(hdrdir)/ruby/internal/assume.h
+printf.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+printf.o: $(hdrdir)/ruby/internal/attr/artificial.h
+printf.o: $(hdrdir)/ruby/internal/attr/cold.h
+printf.o: $(hdrdir)/ruby/internal/attr/const.h
+printf.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+printf.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+printf.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+printf.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+printf.o: $(hdrdir)/ruby/internal/attr/error.h
+printf.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+printf.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+printf.o: $(hdrdir)/ruby/internal/attr/format.h
+printf.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+printf.o: $(hdrdir)/ruby/internal/attr/noalias.h
+printf.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+printf.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+printf.o: $(hdrdir)/ruby/internal/attr/noinline.h
+printf.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+printf.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+printf.o: $(hdrdir)/ruby/internal/attr/pure.h
+printf.o: $(hdrdir)/ruby/internal/attr/restrict.h
+printf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+printf.o: $(hdrdir)/ruby/internal/attr/warning.h
+printf.o: $(hdrdir)/ruby/internal/attr/weakref.h
+printf.o: $(hdrdir)/ruby/internal/cast.h
+printf.o: $(hdrdir)/ruby/internal/compiler_is.h
+printf.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+printf.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+printf.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+printf.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+printf.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+printf.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+printf.o: $(hdrdir)/ruby/internal/compiler_since.h
+printf.o: $(hdrdir)/ruby/internal/config.h
+printf.o: $(hdrdir)/ruby/internal/constant_p.h
+printf.o: $(hdrdir)/ruby/internal/core.h
+printf.o: $(hdrdir)/ruby/internal/core/rarray.h
+printf.o: $(hdrdir)/ruby/internal/core/rbasic.h
+printf.o: $(hdrdir)/ruby/internal/core/rbignum.h
+printf.o: $(hdrdir)/ruby/internal/core/rclass.h
+printf.o: $(hdrdir)/ruby/internal/core/rdata.h
+printf.o: $(hdrdir)/ruby/internal/core/rfile.h
+printf.o: $(hdrdir)/ruby/internal/core/rhash.h
+printf.o: $(hdrdir)/ruby/internal/core/robject.h
+printf.o: $(hdrdir)/ruby/internal/core/rregexp.h
+printf.o: $(hdrdir)/ruby/internal/core/rstring.h
+printf.o: $(hdrdir)/ruby/internal/core/rstruct.h
+printf.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+printf.o: $(hdrdir)/ruby/internal/ctype.h
+printf.o: $(hdrdir)/ruby/internal/dllexport.h
+printf.o: $(hdrdir)/ruby/internal/dosish.h
+printf.o: $(hdrdir)/ruby/internal/error.h
+printf.o: $(hdrdir)/ruby/internal/eval.h
+printf.o: $(hdrdir)/ruby/internal/event.h
+printf.o: $(hdrdir)/ruby/internal/fl_type.h
+printf.o: $(hdrdir)/ruby/internal/gc.h
+printf.o: $(hdrdir)/ruby/internal/glob.h
+printf.o: $(hdrdir)/ruby/internal/globals.h
+printf.o: $(hdrdir)/ruby/internal/has/attribute.h
+printf.o: $(hdrdir)/ruby/internal/has/builtin.h
+printf.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+printf.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+printf.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+printf.o: $(hdrdir)/ruby/internal/has/extension.h
+printf.o: $(hdrdir)/ruby/internal/has/feature.h
+printf.o: $(hdrdir)/ruby/internal/has/warning.h
+printf.o: $(hdrdir)/ruby/internal/intern/array.h
+printf.o: $(hdrdir)/ruby/internal/intern/bignum.h
+printf.o: $(hdrdir)/ruby/internal/intern/class.h
+printf.o: $(hdrdir)/ruby/internal/intern/compar.h
+printf.o: $(hdrdir)/ruby/internal/intern/complex.h
+printf.o: $(hdrdir)/ruby/internal/intern/cont.h
+printf.o: $(hdrdir)/ruby/internal/intern/dir.h
+printf.o: $(hdrdir)/ruby/internal/intern/enum.h
+printf.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+printf.o: $(hdrdir)/ruby/internal/intern/error.h
+printf.o: $(hdrdir)/ruby/internal/intern/eval.h
+printf.o: $(hdrdir)/ruby/internal/intern/file.h
+printf.o: $(hdrdir)/ruby/internal/intern/gc.h
+printf.o: $(hdrdir)/ruby/internal/intern/hash.h
+printf.o: $(hdrdir)/ruby/internal/intern/io.h
+printf.o: $(hdrdir)/ruby/internal/intern/load.h
+printf.o: $(hdrdir)/ruby/internal/intern/marshal.h
+printf.o: $(hdrdir)/ruby/internal/intern/numeric.h
+printf.o: $(hdrdir)/ruby/internal/intern/object.h
+printf.o: $(hdrdir)/ruby/internal/intern/parse.h
+printf.o: $(hdrdir)/ruby/internal/intern/proc.h
+printf.o: $(hdrdir)/ruby/internal/intern/process.h
+printf.o: $(hdrdir)/ruby/internal/intern/random.h
+printf.o: $(hdrdir)/ruby/internal/intern/range.h
+printf.o: $(hdrdir)/ruby/internal/intern/rational.h
+printf.o: $(hdrdir)/ruby/internal/intern/re.h
+printf.o: $(hdrdir)/ruby/internal/intern/ruby.h
+printf.o: $(hdrdir)/ruby/internal/intern/select.h
+printf.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+printf.o: $(hdrdir)/ruby/internal/intern/signal.h
+printf.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+printf.o: $(hdrdir)/ruby/internal/intern/string.h
+printf.o: $(hdrdir)/ruby/internal/intern/struct.h
+printf.o: $(hdrdir)/ruby/internal/intern/thread.h
+printf.o: $(hdrdir)/ruby/internal/intern/time.h
+printf.o: $(hdrdir)/ruby/internal/intern/variable.h
+printf.o: $(hdrdir)/ruby/internal/intern/vm.h
+printf.o: $(hdrdir)/ruby/internal/interpreter.h
+printf.o: $(hdrdir)/ruby/internal/iterator.h
+printf.o: $(hdrdir)/ruby/internal/memory.h
+printf.o: $(hdrdir)/ruby/internal/method.h
+printf.o: $(hdrdir)/ruby/internal/module.h
+printf.o: $(hdrdir)/ruby/internal/newobj.h
+printf.o: $(hdrdir)/ruby/internal/rgengc.h
+printf.o: $(hdrdir)/ruby/internal/scan_args.h
+printf.o: $(hdrdir)/ruby/internal/special_consts.h
+printf.o: $(hdrdir)/ruby/internal/static_assert.h
+printf.o: $(hdrdir)/ruby/internal/stdalign.h
+printf.o: $(hdrdir)/ruby/internal/stdbool.h
+printf.o: $(hdrdir)/ruby/internal/symbol.h
+printf.o: $(hdrdir)/ruby/internal/token_paste.h
+printf.o: $(hdrdir)/ruby/internal/value.h
+printf.o: $(hdrdir)/ruby/internal/value_type.h
+printf.o: $(hdrdir)/ruby/internal/variable.h
+printf.o: $(hdrdir)/ruby/internal/warning_push.h
+printf.o: $(hdrdir)/ruby/internal/xmalloc.h
+printf.o: $(hdrdir)/ruby/assert.h
+printf.o: $(hdrdir)/ruby/backward.h
+printf.o: $(hdrdir)/ruby/backward/2/assume.h
+printf.o: $(hdrdir)/ruby/backward/2/attributes.h
+printf.o: $(hdrdir)/ruby/backward/2/bool.h
+printf.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+printf.o: $(hdrdir)/ruby/backward/2/inttypes.h
+printf.o: $(hdrdir)/ruby/backward/2/limits.h
+printf.o: $(hdrdir)/ruby/backward/2/long_long.h
+printf.o: $(hdrdir)/ruby/backward/2/stdalign.h
+printf.o: $(hdrdir)/ruby/backward/2/stdarg.h
+printf.o: $(hdrdir)/ruby/defines.h
+printf.o: $(hdrdir)/ruby/encoding.h
+printf.o: $(hdrdir)/ruby/intern.h
+printf.o: $(hdrdir)/ruby/missing.h
+printf.o: $(hdrdir)/ruby/onigmo.h
+printf.o: $(hdrdir)/ruby/oniguruma.h
+printf.o: $(hdrdir)/ruby/ruby.h
+printf.o: $(hdrdir)/ruby/st.h
+printf.o: $(hdrdir)/ruby/subst.h
+printf.o: printf.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/proc/depend b/ext/-test-/proc/depend
new file mode 100644
index 0000000000..b72257f5e2
--- /dev/null
+++ b/ext/-test-/proc/depend
@@ -0,0 +1,485 @@
+# AUTOGENERATED DEPENDENCIES START
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+receiver.o: $(RUBY_EXTCONF_H)
+receiver.o: $(arch_hdrdir)/ruby/config.h
+receiver.o: $(hdrdir)/ruby.h
+receiver.o: $(hdrdir)/ruby/internal/anyargs.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+receiver.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+receiver.o: $(hdrdir)/ruby/internal/assume.h
+receiver.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+receiver.o: $(hdrdir)/ruby/internal/attr/artificial.h
+receiver.o: $(hdrdir)/ruby/internal/attr/cold.h
+receiver.o: $(hdrdir)/ruby/internal/attr/const.h
+receiver.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+receiver.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+receiver.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+receiver.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+receiver.o: $(hdrdir)/ruby/internal/attr/error.h
+receiver.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+receiver.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+receiver.o: $(hdrdir)/ruby/internal/attr/format.h
+receiver.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+receiver.o: $(hdrdir)/ruby/internal/attr/noalias.h
+receiver.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+receiver.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+receiver.o: $(hdrdir)/ruby/internal/attr/noinline.h
+receiver.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+receiver.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+receiver.o: $(hdrdir)/ruby/internal/attr/pure.h
+receiver.o: $(hdrdir)/ruby/internal/attr/restrict.h
+receiver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+receiver.o: $(hdrdir)/ruby/internal/attr/warning.h
+receiver.o: $(hdrdir)/ruby/internal/attr/weakref.h
+receiver.o: $(hdrdir)/ruby/internal/cast.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_is.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+receiver.o: $(hdrdir)/ruby/internal/compiler_since.h
+receiver.o: $(hdrdir)/ruby/internal/config.h
+receiver.o: $(hdrdir)/ruby/internal/constant_p.h
+receiver.o: $(hdrdir)/ruby/internal/core.h
+receiver.o: $(hdrdir)/ruby/internal/core/rarray.h
+receiver.o: $(hdrdir)/ruby/internal/core/rbasic.h
+receiver.o: $(hdrdir)/ruby/internal/core/rbignum.h
+receiver.o: $(hdrdir)/ruby/internal/core/rclass.h
+receiver.o: $(hdrdir)/ruby/internal/core/rdata.h
+receiver.o: $(hdrdir)/ruby/internal/core/rfile.h
+receiver.o: $(hdrdir)/ruby/internal/core/rhash.h
+receiver.o: $(hdrdir)/ruby/internal/core/robject.h
+receiver.o: $(hdrdir)/ruby/internal/core/rregexp.h
+receiver.o: $(hdrdir)/ruby/internal/core/rstring.h
+receiver.o: $(hdrdir)/ruby/internal/core/rstruct.h
+receiver.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+receiver.o: $(hdrdir)/ruby/internal/ctype.h
+receiver.o: $(hdrdir)/ruby/internal/dllexport.h
+receiver.o: $(hdrdir)/ruby/internal/dosish.h
+receiver.o: $(hdrdir)/ruby/internal/error.h
+receiver.o: $(hdrdir)/ruby/internal/eval.h
+receiver.o: $(hdrdir)/ruby/internal/event.h
+receiver.o: $(hdrdir)/ruby/internal/fl_type.h
+receiver.o: $(hdrdir)/ruby/internal/gc.h
+receiver.o: $(hdrdir)/ruby/internal/glob.h
+receiver.o: $(hdrdir)/ruby/internal/globals.h
+receiver.o: $(hdrdir)/ruby/internal/has/attribute.h
+receiver.o: $(hdrdir)/ruby/internal/has/builtin.h
+receiver.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+receiver.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+receiver.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+receiver.o: $(hdrdir)/ruby/internal/has/extension.h
+receiver.o: $(hdrdir)/ruby/internal/has/feature.h
+receiver.o: $(hdrdir)/ruby/internal/has/warning.h
+receiver.o: $(hdrdir)/ruby/internal/intern/array.h
+receiver.o: $(hdrdir)/ruby/internal/intern/bignum.h
+receiver.o: $(hdrdir)/ruby/internal/intern/class.h
+receiver.o: $(hdrdir)/ruby/internal/intern/compar.h
+receiver.o: $(hdrdir)/ruby/internal/intern/complex.h
+receiver.o: $(hdrdir)/ruby/internal/intern/cont.h
+receiver.o: $(hdrdir)/ruby/internal/intern/dir.h
+receiver.o: $(hdrdir)/ruby/internal/intern/enum.h
+receiver.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+receiver.o: $(hdrdir)/ruby/internal/intern/error.h
+receiver.o: $(hdrdir)/ruby/internal/intern/eval.h
+receiver.o: $(hdrdir)/ruby/internal/intern/file.h
+receiver.o: $(hdrdir)/ruby/internal/intern/gc.h
+receiver.o: $(hdrdir)/ruby/internal/intern/hash.h
+receiver.o: $(hdrdir)/ruby/internal/intern/io.h
+receiver.o: $(hdrdir)/ruby/internal/intern/load.h
+receiver.o: $(hdrdir)/ruby/internal/intern/marshal.h
+receiver.o: $(hdrdir)/ruby/internal/intern/numeric.h
+receiver.o: $(hdrdir)/ruby/internal/intern/object.h
+receiver.o: $(hdrdir)/ruby/internal/intern/parse.h
+receiver.o: $(hdrdir)/ruby/internal/intern/proc.h
+receiver.o: $(hdrdir)/ruby/internal/intern/process.h
+receiver.o: $(hdrdir)/ruby/internal/intern/random.h
+receiver.o: $(hdrdir)/ruby/internal/intern/range.h
+receiver.o: $(hdrdir)/ruby/internal/intern/rational.h
+receiver.o: $(hdrdir)/ruby/internal/intern/re.h
+receiver.o: $(hdrdir)/ruby/internal/intern/ruby.h
+receiver.o: $(hdrdir)/ruby/internal/intern/select.h
+receiver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+receiver.o: $(hdrdir)/ruby/internal/intern/signal.h
+receiver.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+receiver.o: $(hdrdir)/ruby/internal/intern/string.h
+receiver.o: $(hdrdir)/ruby/internal/intern/struct.h
+receiver.o: $(hdrdir)/ruby/internal/intern/thread.h
+receiver.o: $(hdrdir)/ruby/internal/intern/time.h
+receiver.o: $(hdrdir)/ruby/internal/intern/variable.h
+receiver.o: $(hdrdir)/ruby/internal/intern/vm.h
+receiver.o: $(hdrdir)/ruby/internal/interpreter.h
+receiver.o: $(hdrdir)/ruby/internal/iterator.h
+receiver.o: $(hdrdir)/ruby/internal/memory.h
+receiver.o: $(hdrdir)/ruby/internal/method.h
+receiver.o: $(hdrdir)/ruby/internal/module.h
+receiver.o: $(hdrdir)/ruby/internal/newobj.h
+receiver.o: $(hdrdir)/ruby/internal/rgengc.h
+receiver.o: $(hdrdir)/ruby/internal/scan_args.h
+receiver.o: $(hdrdir)/ruby/internal/special_consts.h
+receiver.o: $(hdrdir)/ruby/internal/static_assert.h
+receiver.o: $(hdrdir)/ruby/internal/stdalign.h
+receiver.o: $(hdrdir)/ruby/internal/stdbool.h
+receiver.o: $(hdrdir)/ruby/internal/symbol.h
+receiver.o: $(hdrdir)/ruby/internal/token_paste.h
+receiver.o: $(hdrdir)/ruby/internal/value.h
+receiver.o: $(hdrdir)/ruby/internal/value_type.h
+receiver.o: $(hdrdir)/ruby/internal/variable.h
+receiver.o: $(hdrdir)/ruby/internal/warning_push.h
+receiver.o: $(hdrdir)/ruby/internal/xmalloc.h
+receiver.o: $(hdrdir)/ruby/assert.h
+receiver.o: $(hdrdir)/ruby/backward.h
+receiver.o: $(hdrdir)/ruby/backward/2/assume.h
+receiver.o: $(hdrdir)/ruby/backward/2/attributes.h
+receiver.o: $(hdrdir)/ruby/backward/2/bool.h
+receiver.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+receiver.o: $(hdrdir)/ruby/backward/2/inttypes.h
+receiver.o: $(hdrdir)/ruby/backward/2/limits.h
+receiver.o: $(hdrdir)/ruby/backward/2/long_long.h
+receiver.o: $(hdrdir)/ruby/backward/2/stdalign.h
+receiver.o: $(hdrdir)/ruby/backward/2/stdarg.h
+receiver.o: $(hdrdir)/ruby/defines.h
+receiver.o: $(hdrdir)/ruby/intern.h
+receiver.o: $(hdrdir)/ruby/missing.h
+receiver.o: $(hdrdir)/ruby/ruby.h
+receiver.o: $(hdrdir)/ruby/st.h
+receiver.o: $(hdrdir)/ruby/subst.h
+receiver.o: receiver.c
+super.o: $(RUBY_EXTCONF_H)
+super.o: $(arch_hdrdir)/ruby/config.h
+super.o: $(hdrdir)/ruby.h
+super.o: $(hdrdir)/ruby/internal/anyargs.h
+super.o: $(hdrdir)/ruby/internal/arithmetic.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+super.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+super.o: $(hdrdir)/ruby/internal/assume.h
+super.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+super.o: $(hdrdir)/ruby/internal/attr/artificial.h
+super.o: $(hdrdir)/ruby/internal/attr/cold.h
+super.o: $(hdrdir)/ruby/internal/attr/const.h
+super.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+super.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+super.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+super.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+super.o: $(hdrdir)/ruby/internal/attr/error.h
+super.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+super.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+super.o: $(hdrdir)/ruby/internal/attr/format.h
+super.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+super.o: $(hdrdir)/ruby/internal/attr/noalias.h
+super.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+super.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+super.o: $(hdrdir)/ruby/internal/attr/noinline.h
+super.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+super.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+super.o: $(hdrdir)/ruby/internal/attr/pure.h
+super.o: $(hdrdir)/ruby/internal/attr/restrict.h
+super.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+super.o: $(hdrdir)/ruby/internal/attr/warning.h
+super.o: $(hdrdir)/ruby/internal/attr/weakref.h
+super.o: $(hdrdir)/ruby/internal/cast.h
+super.o: $(hdrdir)/ruby/internal/compiler_is.h
+super.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+super.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+super.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+super.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+super.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+super.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+super.o: $(hdrdir)/ruby/internal/compiler_since.h
+super.o: $(hdrdir)/ruby/internal/config.h
+super.o: $(hdrdir)/ruby/internal/constant_p.h
+super.o: $(hdrdir)/ruby/internal/core.h
+super.o: $(hdrdir)/ruby/internal/core/rarray.h
+super.o: $(hdrdir)/ruby/internal/core/rbasic.h
+super.o: $(hdrdir)/ruby/internal/core/rbignum.h
+super.o: $(hdrdir)/ruby/internal/core/rclass.h
+super.o: $(hdrdir)/ruby/internal/core/rdata.h
+super.o: $(hdrdir)/ruby/internal/core/rfile.h
+super.o: $(hdrdir)/ruby/internal/core/rhash.h
+super.o: $(hdrdir)/ruby/internal/core/robject.h
+super.o: $(hdrdir)/ruby/internal/core/rregexp.h
+super.o: $(hdrdir)/ruby/internal/core/rstring.h
+super.o: $(hdrdir)/ruby/internal/core/rstruct.h
+super.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+super.o: $(hdrdir)/ruby/internal/ctype.h
+super.o: $(hdrdir)/ruby/internal/dllexport.h
+super.o: $(hdrdir)/ruby/internal/dosish.h
+super.o: $(hdrdir)/ruby/internal/error.h
+super.o: $(hdrdir)/ruby/internal/eval.h
+super.o: $(hdrdir)/ruby/internal/event.h
+super.o: $(hdrdir)/ruby/internal/fl_type.h
+super.o: $(hdrdir)/ruby/internal/gc.h
+super.o: $(hdrdir)/ruby/internal/glob.h
+super.o: $(hdrdir)/ruby/internal/globals.h
+super.o: $(hdrdir)/ruby/internal/has/attribute.h
+super.o: $(hdrdir)/ruby/internal/has/builtin.h
+super.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+super.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+super.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+super.o: $(hdrdir)/ruby/internal/has/extension.h
+super.o: $(hdrdir)/ruby/internal/has/feature.h
+super.o: $(hdrdir)/ruby/internal/has/warning.h
+super.o: $(hdrdir)/ruby/internal/intern/array.h
+super.o: $(hdrdir)/ruby/internal/intern/bignum.h
+super.o: $(hdrdir)/ruby/internal/intern/class.h
+super.o: $(hdrdir)/ruby/internal/intern/compar.h
+super.o: $(hdrdir)/ruby/internal/intern/complex.h
+super.o: $(hdrdir)/ruby/internal/intern/cont.h
+super.o: $(hdrdir)/ruby/internal/intern/dir.h
+super.o: $(hdrdir)/ruby/internal/intern/enum.h
+super.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+super.o: $(hdrdir)/ruby/internal/intern/error.h
+super.o: $(hdrdir)/ruby/internal/intern/eval.h
+super.o: $(hdrdir)/ruby/internal/intern/file.h
+super.o: $(hdrdir)/ruby/internal/intern/gc.h
+super.o: $(hdrdir)/ruby/internal/intern/hash.h
+super.o: $(hdrdir)/ruby/internal/intern/io.h
+super.o: $(hdrdir)/ruby/internal/intern/load.h
+super.o: $(hdrdir)/ruby/internal/intern/marshal.h
+super.o: $(hdrdir)/ruby/internal/intern/numeric.h
+super.o: $(hdrdir)/ruby/internal/intern/object.h
+super.o: $(hdrdir)/ruby/internal/intern/parse.h
+super.o: $(hdrdir)/ruby/internal/intern/proc.h
+super.o: $(hdrdir)/ruby/internal/intern/process.h
+super.o: $(hdrdir)/ruby/internal/intern/random.h
+super.o: $(hdrdir)/ruby/internal/intern/range.h
+super.o: $(hdrdir)/ruby/internal/intern/rational.h
+super.o: $(hdrdir)/ruby/internal/intern/re.h
+super.o: $(hdrdir)/ruby/internal/intern/ruby.h
+super.o: $(hdrdir)/ruby/internal/intern/select.h
+super.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+super.o: $(hdrdir)/ruby/internal/intern/signal.h
+super.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+super.o: $(hdrdir)/ruby/internal/intern/string.h
+super.o: $(hdrdir)/ruby/internal/intern/struct.h
+super.o: $(hdrdir)/ruby/internal/intern/thread.h
+super.o: $(hdrdir)/ruby/internal/intern/time.h
+super.o: $(hdrdir)/ruby/internal/intern/variable.h
+super.o: $(hdrdir)/ruby/internal/intern/vm.h
+super.o: $(hdrdir)/ruby/internal/interpreter.h
+super.o: $(hdrdir)/ruby/internal/iterator.h
+super.o: $(hdrdir)/ruby/internal/memory.h
+super.o: $(hdrdir)/ruby/internal/method.h
+super.o: $(hdrdir)/ruby/internal/module.h
+super.o: $(hdrdir)/ruby/internal/newobj.h
+super.o: $(hdrdir)/ruby/internal/rgengc.h
+super.o: $(hdrdir)/ruby/internal/scan_args.h
+super.o: $(hdrdir)/ruby/internal/special_consts.h
+super.o: $(hdrdir)/ruby/internal/static_assert.h
+super.o: $(hdrdir)/ruby/internal/stdalign.h
+super.o: $(hdrdir)/ruby/internal/stdbool.h
+super.o: $(hdrdir)/ruby/internal/symbol.h
+super.o: $(hdrdir)/ruby/internal/token_paste.h
+super.o: $(hdrdir)/ruby/internal/value.h
+super.o: $(hdrdir)/ruby/internal/value_type.h
+super.o: $(hdrdir)/ruby/internal/variable.h
+super.o: $(hdrdir)/ruby/internal/warning_push.h
+super.o: $(hdrdir)/ruby/internal/xmalloc.h
+super.o: $(hdrdir)/ruby/assert.h
+super.o: $(hdrdir)/ruby/backward.h
+super.o: $(hdrdir)/ruby/backward/2/assume.h
+super.o: $(hdrdir)/ruby/backward/2/attributes.h
+super.o: $(hdrdir)/ruby/backward/2/bool.h
+super.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+super.o: $(hdrdir)/ruby/backward/2/inttypes.h
+super.o: $(hdrdir)/ruby/backward/2/limits.h
+super.o: $(hdrdir)/ruby/backward/2/long_long.h
+super.o: $(hdrdir)/ruby/backward/2/stdalign.h
+super.o: $(hdrdir)/ruby/backward/2/stdarg.h
+super.o: $(hdrdir)/ruby/defines.h
+super.o: $(hdrdir)/ruby/intern.h
+super.o: $(hdrdir)/ruby/missing.h
+super.o: $(hdrdir)/ruby/ruby.h
+super.o: $(hdrdir)/ruby/st.h
+super.o: $(hdrdir)/ruby/subst.h
+super.o: super.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/random/depend b/ext/-test-/random/depend
new file mode 100644
index 0000000000..4b4997d340
--- /dev/null
+++ b/ext/-test-/random/depend
@@ -0,0 +1,328 @@
+# AUTOGENERATED DEPENDENCIES START
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/r_cast.h
+init.o: $(hdrdir)/ruby/backward/2/rmodule.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+loop.o: $(RUBY_EXTCONF_H)
+loop.o: $(arch_hdrdir)/ruby/config.h
+loop.o: $(hdrdir)/ruby/assert.h
+loop.o: $(hdrdir)/ruby/backward.h
+loop.o: $(hdrdir)/ruby/backward/2/assume.h
+loop.o: $(hdrdir)/ruby/backward/2/attributes.h
+loop.o: $(hdrdir)/ruby/backward/2/bool.h
+loop.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+loop.o: $(hdrdir)/ruby/backward/2/inttypes.h
+loop.o: $(hdrdir)/ruby/backward/2/limits.h
+loop.o: $(hdrdir)/ruby/backward/2/long_long.h
+loop.o: $(hdrdir)/ruby/backward/2/r_cast.h
+loop.o: $(hdrdir)/ruby/backward/2/rmodule.h
+loop.o: $(hdrdir)/ruby/backward/2/stdalign.h
+loop.o: $(hdrdir)/ruby/backward/2/stdarg.h
+loop.o: $(hdrdir)/ruby/defines.h
+loop.o: $(hdrdir)/ruby/intern.h
+loop.o: $(hdrdir)/ruby/internal/anyargs.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+loop.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+loop.o: $(hdrdir)/ruby/internal/assume.h
+loop.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+loop.o: $(hdrdir)/ruby/internal/attr/artificial.h
+loop.o: $(hdrdir)/ruby/internal/attr/cold.h
+loop.o: $(hdrdir)/ruby/internal/attr/const.h
+loop.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+loop.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+loop.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+loop.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+loop.o: $(hdrdir)/ruby/internal/attr/error.h
+loop.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+loop.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+loop.o: $(hdrdir)/ruby/internal/attr/format.h
+loop.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+loop.o: $(hdrdir)/ruby/internal/attr/noalias.h
+loop.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+loop.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+loop.o: $(hdrdir)/ruby/internal/attr/noinline.h
+loop.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+loop.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+loop.o: $(hdrdir)/ruby/internal/attr/pure.h
+loop.o: $(hdrdir)/ruby/internal/attr/restrict.h
+loop.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+loop.o: $(hdrdir)/ruby/internal/attr/warning.h
+loop.o: $(hdrdir)/ruby/internal/attr/weakref.h
+loop.o: $(hdrdir)/ruby/internal/cast.h
+loop.o: $(hdrdir)/ruby/internal/compiler_is.h
+loop.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+loop.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+loop.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+loop.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+loop.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+loop.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+loop.o: $(hdrdir)/ruby/internal/compiler_since.h
+loop.o: $(hdrdir)/ruby/internal/config.h
+loop.o: $(hdrdir)/ruby/internal/constant_p.h
+loop.o: $(hdrdir)/ruby/internal/core.h
+loop.o: $(hdrdir)/ruby/internal/core/rarray.h
+loop.o: $(hdrdir)/ruby/internal/core/rbasic.h
+loop.o: $(hdrdir)/ruby/internal/core/rbignum.h
+loop.o: $(hdrdir)/ruby/internal/core/rclass.h
+loop.o: $(hdrdir)/ruby/internal/core/rdata.h
+loop.o: $(hdrdir)/ruby/internal/core/rfile.h
+loop.o: $(hdrdir)/ruby/internal/core/rhash.h
+loop.o: $(hdrdir)/ruby/internal/core/robject.h
+loop.o: $(hdrdir)/ruby/internal/core/rregexp.h
+loop.o: $(hdrdir)/ruby/internal/core/rstring.h
+loop.o: $(hdrdir)/ruby/internal/core/rstruct.h
+loop.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+loop.o: $(hdrdir)/ruby/internal/ctype.h
+loop.o: $(hdrdir)/ruby/internal/dllexport.h
+loop.o: $(hdrdir)/ruby/internal/dosish.h
+loop.o: $(hdrdir)/ruby/internal/error.h
+loop.o: $(hdrdir)/ruby/internal/eval.h
+loop.o: $(hdrdir)/ruby/internal/event.h
+loop.o: $(hdrdir)/ruby/internal/fl_type.h
+loop.o: $(hdrdir)/ruby/internal/gc.h
+loop.o: $(hdrdir)/ruby/internal/glob.h
+loop.o: $(hdrdir)/ruby/internal/globals.h
+loop.o: $(hdrdir)/ruby/internal/has/attribute.h
+loop.o: $(hdrdir)/ruby/internal/has/builtin.h
+loop.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+loop.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+loop.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+loop.o: $(hdrdir)/ruby/internal/has/extension.h
+loop.o: $(hdrdir)/ruby/internal/has/feature.h
+loop.o: $(hdrdir)/ruby/internal/has/warning.h
+loop.o: $(hdrdir)/ruby/internal/intern/array.h
+loop.o: $(hdrdir)/ruby/internal/intern/bignum.h
+loop.o: $(hdrdir)/ruby/internal/intern/class.h
+loop.o: $(hdrdir)/ruby/internal/intern/compar.h
+loop.o: $(hdrdir)/ruby/internal/intern/complex.h
+loop.o: $(hdrdir)/ruby/internal/intern/cont.h
+loop.o: $(hdrdir)/ruby/internal/intern/dir.h
+loop.o: $(hdrdir)/ruby/internal/intern/enum.h
+loop.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+loop.o: $(hdrdir)/ruby/internal/intern/error.h
+loop.o: $(hdrdir)/ruby/internal/intern/eval.h
+loop.o: $(hdrdir)/ruby/internal/intern/file.h
+loop.o: $(hdrdir)/ruby/internal/intern/gc.h
+loop.o: $(hdrdir)/ruby/internal/intern/hash.h
+loop.o: $(hdrdir)/ruby/internal/intern/io.h
+loop.o: $(hdrdir)/ruby/internal/intern/load.h
+loop.o: $(hdrdir)/ruby/internal/intern/marshal.h
+loop.o: $(hdrdir)/ruby/internal/intern/numeric.h
+loop.o: $(hdrdir)/ruby/internal/intern/object.h
+loop.o: $(hdrdir)/ruby/internal/intern/parse.h
+loop.o: $(hdrdir)/ruby/internal/intern/proc.h
+loop.o: $(hdrdir)/ruby/internal/intern/process.h
+loop.o: $(hdrdir)/ruby/internal/intern/random.h
+loop.o: $(hdrdir)/ruby/internal/intern/range.h
+loop.o: $(hdrdir)/ruby/internal/intern/rational.h
+loop.o: $(hdrdir)/ruby/internal/intern/re.h
+loop.o: $(hdrdir)/ruby/internal/intern/ruby.h
+loop.o: $(hdrdir)/ruby/internal/intern/select.h
+loop.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+loop.o: $(hdrdir)/ruby/internal/intern/signal.h
+loop.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+loop.o: $(hdrdir)/ruby/internal/intern/string.h
+loop.o: $(hdrdir)/ruby/internal/intern/struct.h
+loop.o: $(hdrdir)/ruby/internal/intern/thread.h
+loop.o: $(hdrdir)/ruby/internal/intern/time.h
+loop.o: $(hdrdir)/ruby/internal/intern/variable.h
+loop.o: $(hdrdir)/ruby/internal/intern/vm.h
+loop.o: $(hdrdir)/ruby/internal/interpreter.h
+loop.o: $(hdrdir)/ruby/internal/iterator.h
+loop.o: $(hdrdir)/ruby/internal/memory.h
+loop.o: $(hdrdir)/ruby/internal/method.h
+loop.o: $(hdrdir)/ruby/internal/module.h
+loop.o: $(hdrdir)/ruby/internal/newobj.h
+loop.o: $(hdrdir)/ruby/internal/rgengc.h
+loop.o: $(hdrdir)/ruby/internal/scan_args.h
+loop.o: $(hdrdir)/ruby/internal/special_consts.h
+loop.o: $(hdrdir)/ruby/internal/static_assert.h
+loop.o: $(hdrdir)/ruby/internal/stdalign.h
+loop.o: $(hdrdir)/ruby/internal/stdbool.h
+loop.o: $(hdrdir)/ruby/internal/symbol.h
+loop.o: $(hdrdir)/ruby/internal/token_paste.h
+loop.o: $(hdrdir)/ruby/internal/value.h
+loop.o: $(hdrdir)/ruby/internal/value_type.h
+loop.o: $(hdrdir)/ruby/internal/variable.h
+loop.o: $(hdrdir)/ruby/internal/warning_push.h
+loop.o: $(hdrdir)/ruby/internal/xmalloc.h
+loop.o: $(hdrdir)/ruby/missing.h
+loop.o: $(hdrdir)/ruby/random.h
+loop.o: $(hdrdir)/ruby/ruby.h
+loop.o: $(hdrdir)/ruby/st.h
+loop.o: $(hdrdir)/ruby/subst.h
+loop.o: loop.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/random/extconf.rb b/ext/-test-/random/extconf.rb
new file mode 100644
index 0000000000..d786b15db9
--- /dev/null
+++ b/ext/-test-/random/extconf.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: false
+require_relative "../auto_ext.rb"
+auto_ext(inc: true)
diff --git a/ext/-test-/random/init.c b/ext/-test-/random/init.c
new file mode 100644
index 0000000000..320cba0ad6
--- /dev/null
+++ b/ext/-test-/random/init.c
@@ -0,0 +1,11 @@
+#include "ruby.h"
+
+#define init(n) {void Init_random_##n(VALUE mod, VALUE base); Init_random_##n(mod, base);}
+
+void
+Init_random(void)
+{
+ VALUE base = rb_const_get(rb_cRandom, rb_intern_const("Base"));
+ VALUE mod = rb_define_module_under(rb_define_module("Bug"), "Random");
+ TEST_INIT_FUNCS(init);
+}
diff --git a/ext/-test-/random/loop.c b/ext/-test-/random/loop.c
new file mode 100644
index 0000000000..0572096403
--- /dev/null
+++ b/ext/-test-/random/loop.c
@@ -0,0 +1,110 @@
+#include "ruby/random.h"
+
+static const uint32_t max_seeds = 1024;
+
+typedef struct {
+ rb_random_t base;
+ uint32_t num, idx, *buf;
+} rand_loop_t;
+
+RB_RANDOM_INTERFACE_DECLARE_WITH_REAL(loop);
+static const rb_random_interface_t random_loop_if = {
+ 32,
+ RB_RANDOM_INTERFACE_DEFINE_WITH_REAL(loop)
+};
+
+static size_t
+random_loop_memsize(const void *ptr)
+{
+ const rand_loop_t *r = ptr;
+ return sizeof(*r) + r->num * sizeof(r->buf[0]);
+}
+
+static rb_random_data_type_t random_loop_type = {
+ "random/loop",
+ {
+ rb_random_mark,
+ RUBY_TYPED_DEFAULT_FREE,
+ random_loop_memsize,
+ },
+ RB_RANDOM_PARENT,
+ (void *)&random_loop_if,
+ RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+
+static VALUE
+loop_alloc(VALUE klass)
+{
+ rand_loop_t *rnd;
+ VALUE obj = TypedData_Make_Struct(klass, rand_loop_t, &random_loop_type, rnd);
+ rb_random_base_init(&rnd->base);
+ return obj;
+}
+
+static void
+loop_init(rb_random_t *rnd, const uint32_t *buf, size_t len)
+{
+ rand_loop_t *r = (rand_loop_t *)rnd;
+
+ if (len > max_seeds) len = max_seeds;
+
+ REALLOC_N(r->buf, uint32_t, len);
+ MEMCPY(r->buf, buf, uint32_t, (r->num = (uint32_t)len));
+}
+
+static void
+loop_get_bytes(rb_random_t *rnd, void *p, size_t n)
+{
+ uint8_t *buf = p;
+ while (n > 0) {
+ uint32_t x = loop_get_int32(rnd);
+ switch (n % 4) {
+ case 0:
+ *buf++ = (uint8_t)x;
+ n--;
+ /* FALLTHROUGH */
+ case 3:
+ *buf++ = (uint8_t)x;
+ n--;
+ /* FALLTHROUGH */
+ case 2:
+ *buf++ = (uint8_t)x;
+ n--;
+ /* FALLTHROUGH */
+ case 1:
+ *buf++ = (uint8_t)x;
+ n--;
+ }
+ }
+}
+
+static uint32_t
+loop_get_int32(rb_random_t *rnd)
+{
+ rand_loop_t *r = (rand_loop_t *)rnd;
+ if (r->idx < r->num) {
+ uint32_t x = r->buf[r->idx++];
+ if (r->idx >= r->num) r->idx = 0;
+ return x;
+ }
+ else if (r->num) {
+ return r->buf[r->idx = 0];
+ }
+ return 0;
+}
+
+static double
+loop_get_real(rb_random_t *rnd, int excl)
+{
+ uint32_t a = loop_get_int32(rnd);
+ return ldexp(a, -16);
+}
+
+void
+Init_random_loop(VALUE mod, VALUE base)
+{
+ VALUE c = rb_define_class_under(mod, "Loop", base);
+ rb_define_alloc_func(c, loop_alloc);
+ RB_RANDOM_DATA_INIT_PARENT(random_loop_type);
+}
diff --git a/ext/-test-/rational/depend b/ext/-test-/rational/depend
index 4f7c4e4900..c2ebddd093 100644
--- a/ext/-test-/rational/depend
+++ b/ext/-test-/rational/depend
@@ -5,18 +5,176 @@ rat.o: rat.c $(top_srcdir)/internal.h
# AUTOGENERATED DEPENDENCIES START
rat.o: $(RUBY_EXTCONF_H)
rat.o: $(arch_hdrdir)/ruby/config.h
+rat.o: $(hdrdir)/ruby.h
+rat.o: $(hdrdir)/ruby/internal/anyargs.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+rat.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+rat.o: $(hdrdir)/ruby/internal/assume.h
+rat.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+rat.o: $(hdrdir)/ruby/internal/attr/artificial.h
+rat.o: $(hdrdir)/ruby/internal/attr/cold.h
+rat.o: $(hdrdir)/ruby/internal/attr/const.h
+rat.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+rat.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+rat.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+rat.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+rat.o: $(hdrdir)/ruby/internal/attr/error.h
+rat.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+rat.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+rat.o: $(hdrdir)/ruby/internal/attr/format.h
+rat.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+rat.o: $(hdrdir)/ruby/internal/attr/noalias.h
+rat.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+rat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+rat.o: $(hdrdir)/ruby/internal/attr/noinline.h
+rat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+rat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+rat.o: $(hdrdir)/ruby/internal/attr/pure.h
+rat.o: $(hdrdir)/ruby/internal/attr/restrict.h
+rat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+rat.o: $(hdrdir)/ruby/internal/attr/warning.h
+rat.o: $(hdrdir)/ruby/internal/attr/weakref.h
+rat.o: $(hdrdir)/ruby/internal/cast.h
+rat.o: $(hdrdir)/ruby/internal/compiler_is.h
+rat.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+rat.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+rat.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+rat.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+rat.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+rat.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+rat.o: $(hdrdir)/ruby/internal/compiler_since.h
+rat.o: $(hdrdir)/ruby/internal/config.h
+rat.o: $(hdrdir)/ruby/internal/constant_p.h
+rat.o: $(hdrdir)/ruby/internal/core.h
+rat.o: $(hdrdir)/ruby/internal/core/rarray.h
+rat.o: $(hdrdir)/ruby/internal/core/rbasic.h
+rat.o: $(hdrdir)/ruby/internal/core/rbignum.h
+rat.o: $(hdrdir)/ruby/internal/core/rclass.h
+rat.o: $(hdrdir)/ruby/internal/core/rdata.h
+rat.o: $(hdrdir)/ruby/internal/core/rfile.h
+rat.o: $(hdrdir)/ruby/internal/core/rhash.h
+rat.o: $(hdrdir)/ruby/internal/core/robject.h
+rat.o: $(hdrdir)/ruby/internal/core/rregexp.h
+rat.o: $(hdrdir)/ruby/internal/core/rstring.h
+rat.o: $(hdrdir)/ruby/internal/core/rstruct.h
+rat.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+rat.o: $(hdrdir)/ruby/internal/ctype.h
+rat.o: $(hdrdir)/ruby/internal/dllexport.h
+rat.o: $(hdrdir)/ruby/internal/dosish.h
+rat.o: $(hdrdir)/ruby/internal/error.h
+rat.o: $(hdrdir)/ruby/internal/eval.h
+rat.o: $(hdrdir)/ruby/internal/event.h
+rat.o: $(hdrdir)/ruby/internal/fl_type.h
+rat.o: $(hdrdir)/ruby/internal/gc.h
+rat.o: $(hdrdir)/ruby/internal/glob.h
+rat.o: $(hdrdir)/ruby/internal/globals.h
+rat.o: $(hdrdir)/ruby/internal/has/attribute.h
+rat.o: $(hdrdir)/ruby/internal/has/builtin.h
+rat.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+rat.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+rat.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+rat.o: $(hdrdir)/ruby/internal/has/extension.h
+rat.o: $(hdrdir)/ruby/internal/has/feature.h
+rat.o: $(hdrdir)/ruby/internal/has/warning.h
+rat.o: $(hdrdir)/ruby/internal/intern/array.h
+rat.o: $(hdrdir)/ruby/internal/intern/bignum.h
+rat.o: $(hdrdir)/ruby/internal/intern/class.h
+rat.o: $(hdrdir)/ruby/internal/intern/compar.h
+rat.o: $(hdrdir)/ruby/internal/intern/complex.h
+rat.o: $(hdrdir)/ruby/internal/intern/cont.h
+rat.o: $(hdrdir)/ruby/internal/intern/dir.h
+rat.o: $(hdrdir)/ruby/internal/intern/enum.h
+rat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+rat.o: $(hdrdir)/ruby/internal/intern/error.h
+rat.o: $(hdrdir)/ruby/internal/intern/eval.h
+rat.o: $(hdrdir)/ruby/internal/intern/file.h
+rat.o: $(hdrdir)/ruby/internal/intern/gc.h
+rat.o: $(hdrdir)/ruby/internal/intern/hash.h
+rat.o: $(hdrdir)/ruby/internal/intern/io.h
+rat.o: $(hdrdir)/ruby/internal/intern/load.h
+rat.o: $(hdrdir)/ruby/internal/intern/marshal.h
+rat.o: $(hdrdir)/ruby/internal/intern/numeric.h
+rat.o: $(hdrdir)/ruby/internal/intern/object.h
+rat.o: $(hdrdir)/ruby/internal/intern/parse.h
+rat.o: $(hdrdir)/ruby/internal/intern/proc.h
+rat.o: $(hdrdir)/ruby/internal/intern/process.h
+rat.o: $(hdrdir)/ruby/internal/intern/random.h
+rat.o: $(hdrdir)/ruby/internal/intern/range.h
+rat.o: $(hdrdir)/ruby/internal/intern/rational.h
+rat.o: $(hdrdir)/ruby/internal/intern/re.h
+rat.o: $(hdrdir)/ruby/internal/intern/ruby.h
+rat.o: $(hdrdir)/ruby/internal/intern/select.h
+rat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+rat.o: $(hdrdir)/ruby/internal/intern/signal.h
+rat.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+rat.o: $(hdrdir)/ruby/internal/intern/string.h
+rat.o: $(hdrdir)/ruby/internal/intern/struct.h
+rat.o: $(hdrdir)/ruby/internal/intern/thread.h
+rat.o: $(hdrdir)/ruby/internal/intern/time.h
+rat.o: $(hdrdir)/ruby/internal/intern/variable.h
+rat.o: $(hdrdir)/ruby/internal/intern/vm.h
+rat.o: $(hdrdir)/ruby/internal/interpreter.h
+rat.o: $(hdrdir)/ruby/internal/iterator.h
+rat.o: $(hdrdir)/ruby/internal/memory.h
+rat.o: $(hdrdir)/ruby/internal/method.h
+rat.o: $(hdrdir)/ruby/internal/module.h
+rat.o: $(hdrdir)/ruby/internal/newobj.h
+rat.o: $(hdrdir)/ruby/internal/rgengc.h
+rat.o: $(hdrdir)/ruby/internal/scan_args.h
+rat.o: $(hdrdir)/ruby/internal/special_consts.h
+rat.o: $(hdrdir)/ruby/internal/static_assert.h
+rat.o: $(hdrdir)/ruby/internal/stdalign.h
+rat.o: $(hdrdir)/ruby/internal/stdbool.h
+rat.o: $(hdrdir)/ruby/internal/symbol.h
+rat.o: $(hdrdir)/ruby/internal/token_paste.h
+rat.o: $(hdrdir)/ruby/internal/value.h
+rat.o: $(hdrdir)/ruby/internal/value_type.h
+rat.o: $(hdrdir)/ruby/internal/variable.h
+rat.o: $(hdrdir)/ruby/internal/warning_push.h
+rat.o: $(hdrdir)/ruby/internal/xmalloc.h
+rat.o: $(hdrdir)/ruby/assert.h
rat.o: $(hdrdir)/ruby/backward.h
+rat.o: $(hdrdir)/ruby/backward/2/assume.h
+rat.o: $(hdrdir)/ruby/backward/2/attributes.h
+rat.o: $(hdrdir)/ruby/backward/2/bool.h
+rat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+rat.o: $(hdrdir)/ruby/backward/2/inttypes.h
+rat.o: $(hdrdir)/ruby/backward/2/limits.h
+rat.o: $(hdrdir)/ruby/backward/2/long_long.h
+rat.o: $(hdrdir)/ruby/backward/2/stdalign.h
+rat.o: $(hdrdir)/ruby/backward/2/stdarg.h
rat.o: $(hdrdir)/ruby/defines.h
-rat.o: $(hdrdir)/ruby/encoding.h
rat.o: $(hdrdir)/ruby/intern.h
-rat.o: $(hdrdir)/ruby/io.h
rat.o: $(hdrdir)/ruby/missing.h
-rat.o: $(hdrdir)/ruby/onigmo.h
-rat.o: $(hdrdir)/ruby/oniguruma.h
rat.o: $(hdrdir)/ruby/ruby.h
rat.o: $(hdrdir)/ruby/st.h
rat.o: $(hdrdir)/ruby/subst.h
-rat.o: $(top_srcdir)/include/ruby.h
rat.o: $(top_srcdir)/internal.h
+rat.o: $(top_srcdir)/internal/bignum.h
+rat.o: $(top_srcdir)/internal/bits.h
+rat.o: $(top_srcdir)/internal/compilers.h
+rat.o: $(top_srcdir)/internal/fixnum.h
+rat.o: $(top_srcdir)/internal/gc.h
+rat.o: $(top_srcdir)/internal/numeric.h
+rat.o: $(top_srcdir)/internal/rational.h
+rat.o: $(top_srcdir)/internal/serial.h
+rat.o: $(top_srcdir)/internal/static_assert.h
+rat.o: $(top_srcdir)/internal/vm.h
+rat.o: $(top_srcdir)/internal/warnings.h
+rat.o: $(top_srcdir)/ruby_assert.h
rat.o: rat.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/rational/rat.c b/ext/-test-/rational/rat.c
index 772546fca8..b1ffbda144 100644
--- a/ext/-test-/rational/rat.c
+++ b/ext/-test-/rational/rat.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/rational.h"
#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
static VALUE
@@ -29,9 +29,17 @@ gcd_gmp(VALUE x, VALUE y)
#define gcd_gmp rb_f_notimplement
#endif
+static VALUE
+s_rational_raw(VALUE klass, VALUE x, VALUE y)
+{
+ return rb_rational_raw(x, y);
+}
+
void
Init_rational(VALUE klass)
{
rb_define_method(rb_cInteger, "gcd_normal", gcd_normal, 1);
rb_define_method(rb_cInteger, "gcd_gmp", gcd_gmp, 1);
+
+ rb_define_singleton_method(rb_cRational, "raw", s_rational_raw, 2);
}
diff --git a/ext/-test-/rb_call_super_kw/depend b/ext/-test-/rb_call_super_kw/depend
new file mode 100644
index 0000000000..314e69fd0e
--- /dev/null
+++ b/ext/-test-/rb_call_super_kw/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+rb_call_super_kw.o: $(RUBY_EXTCONF_H)
+rb_call_super_kw.o: $(arch_hdrdir)/ruby/config.h
+rb_call_super_kw.o: $(hdrdir)/ruby.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/anyargs.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/assume.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/artificial.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/cold.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/const.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/error.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/format.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noalias.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noinline.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/pure.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/restrict.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/warning.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/weakref.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/cast.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_is.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/compiler_since.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/config.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/constant_p.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rarray.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rbasic.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rbignum.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rclass.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rdata.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rfile.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rhash.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/robject.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rregexp.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rstring.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rstruct.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/ctype.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/dllexport.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/dosish.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/error.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/eval.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/event.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/fl_type.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/gc.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/glob.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/globals.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/attribute.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/builtin.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/extension.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/feature.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/has/warning.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/array.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/bignum.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/class.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/compar.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/complex.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/cont.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/dir.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/enum.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/error.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/eval.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/gc.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/hash.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/io.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/load.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/marshal.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/numeric.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/object.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/parse.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/proc.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/process.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/random.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/range.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/rational.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/re.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/ruby.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/select.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/signal.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/string.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/struct.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/thread.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/time.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/variable.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/vm.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/interpreter.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/iterator.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/memory.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/method.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/module.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/newobj.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/rgengc.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/scan_args.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/special_consts.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/static_assert.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/stdalign.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/stdbool.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/symbol.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/token_paste.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/value.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/value_type.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/variable.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/warning_push.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/xmalloc.h
+rb_call_super_kw.o: $(hdrdir)/ruby/assert.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/assume.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/attributes.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/bool.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/inttypes.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/limits.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/long_long.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/stdalign.h
+rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/stdarg.h
+rb_call_super_kw.o: $(hdrdir)/ruby/defines.h
+rb_call_super_kw.o: $(hdrdir)/ruby/intern.h
+rb_call_super_kw.o: $(hdrdir)/ruby/missing.h
+rb_call_super_kw.o: $(hdrdir)/ruby/ruby.h
+rb_call_super_kw.o: $(hdrdir)/ruby/st.h
+rb_call_super_kw.o: $(hdrdir)/ruby/subst.h
+rb_call_super_kw.o: rb_call_super_kw.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/rb_call_super_kw/extconf.rb b/ext/-test-/rb_call_super_kw/extconf.rb
new file mode 100644
index 0000000000..c6a5c720d7
--- /dev/null
+++ b/ext/-test-/rb_call_super_kw/extconf.rb
@@ -0,0 +1 @@
+create_makefile("-test-/rb_call_super_kw")
diff --git a/ext/-test-/rb_call_super_kw/rb_call_super_kw.c b/ext/-test-/rb_call_super_kw/rb_call_super_kw.c
new file mode 100644
index 0000000000..7f094545d2
--- /dev/null
+++ b/ext/-test-/rb_call_super_kw/rb_call_super_kw.c
@@ -0,0 +1,14 @@
+#include <ruby.h>
+
+static VALUE
+rb_call_super_kw_m(int argc, VALUE *argv, VALUE self)
+{
+ return rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
+}
+
+void
+Init_rb_call_super_kw(void) {
+ VALUE module = rb_define_module("Bug");
+ module = rb_define_module_under(module, "RbCallSuperKw");
+ rb_define_method(module, "m", rb_call_super_kw_m, -1);
+}
diff --git a/ext/-test-/recursion/depend b/ext/-test-/recursion/depend
new file mode 100644
index 0000000000..c760e99c41
--- /dev/null
+++ b/ext/-test-/recursion/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+recursion.o: $(RUBY_EXTCONF_H)
+recursion.o: $(arch_hdrdir)/ruby/config.h
+recursion.o: $(hdrdir)/ruby.h
+recursion.o: $(hdrdir)/ruby/internal/anyargs.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+recursion.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+recursion.o: $(hdrdir)/ruby/internal/assume.h
+recursion.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+recursion.o: $(hdrdir)/ruby/internal/attr/artificial.h
+recursion.o: $(hdrdir)/ruby/internal/attr/cold.h
+recursion.o: $(hdrdir)/ruby/internal/attr/const.h
+recursion.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+recursion.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+recursion.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+recursion.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+recursion.o: $(hdrdir)/ruby/internal/attr/error.h
+recursion.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+recursion.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+recursion.o: $(hdrdir)/ruby/internal/attr/format.h
+recursion.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+recursion.o: $(hdrdir)/ruby/internal/attr/noalias.h
+recursion.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+recursion.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+recursion.o: $(hdrdir)/ruby/internal/attr/noinline.h
+recursion.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+recursion.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+recursion.o: $(hdrdir)/ruby/internal/attr/pure.h
+recursion.o: $(hdrdir)/ruby/internal/attr/restrict.h
+recursion.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+recursion.o: $(hdrdir)/ruby/internal/attr/warning.h
+recursion.o: $(hdrdir)/ruby/internal/attr/weakref.h
+recursion.o: $(hdrdir)/ruby/internal/cast.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_is.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+recursion.o: $(hdrdir)/ruby/internal/compiler_since.h
+recursion.o: $(hdrdir)/ruby/internal/config.h
+recursion.o: $(hdrdir)/ruby/internal/constant_p.h
+recursion.o: $(hdrdir)/ruby/internal/core.h
+recursion.o: $(hdrdir)/ruby/internal/core/rarray.h
+recursion.o: $(hdrdir)/ruby/internal/core/rbasic.h
+recursion.o: $(hdrdir)/ruby/internal/core/rbignum.h
+recursion.o: $(hdrdir)/ruby/internal/core/rclass.h
+recursion.o: $(hdrdir)/ruby/internal/core/rdata.h
+recursion.o: $(hdrdir)/ruby/internal/core/rfile.h
+recursion.o: $(hdrdir)/ruby/internal/core/rhash.h
+recursion.o: $(hdrdir)/ruby/internal/core/robject.h
+recursion.o: $(hdrdir)/ruby/internal/core/rregexp.h
+recursion.o: $(hdrdir)/ruby/internal/core/rstring.h
+recursion.o: $(hdrdir)/ruby/internal/core/rstruct.h
+recursion.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+recursion.o: $(hdrdir)/ruby/internal/ctype.h
+recursion.o: $(hdrdir)/ruby/internal/dllexport.h
+recursion.o: $(hdrdir)/ruby/internal/dosish.h
+recursion.o: $(hdrdir)/ruby/internal/error.h
+recursion.o: $(hdrdir)/ruby/internal/eval.h
+recursion.o: $(hdrdir)/ruby/internal/event.h
+recursion.o: $(hdrdir)/ruby/internal/fl_type.h
+recursion.o: $(hdrdir)/ruby/internal/gc.h
+recursion.o: $(hdrdir)/ruby/internal/glob.h
+recursion.o: $(hdrdir)/ruby/internal/globals.h
+recursion.o: $(hdrdir)/ruby/internal/has/attribute.h
+recursion.o: $(hdrdir)/ruby/internal/has/builtin.h
+recursion.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+recursion.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+recursion.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+recursion.o: $(hdrdir)/ruby/internal/has/extension.h
+recursion.o: $(hdrdir)/ruby/internal/has/feature.h
+recursion.o: $(hdrdir)/ruby/internal/has/warning.h
+recursion.o: $(hdrdir)/ruby/internal/intern/array.h
+recursion.o: $(hdrdir)/ruby/internal/intern/bignum.h
+recursion.o: $(hdrdir)/ruby/internal/intern/class.h
+recursion.o: $(hdrdir)/ruby/internal/intern/compar.h
+recursion.o: $(hdrdir)/ruby/internal/intern/complex.h
+recursion.o: $(hdrdir)/ruby/internal/intern/cont.h
+recursion.o: $(hdrdir)/ruby/internal/intern/dir.h
+recursion.o: $(hdrdir)/ruby/internal/intern/enum.h
+recursion.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+recursion.o: $(hdrdir)/ruby/internal/intern/error.h
+recursion.o: $(hdrdir)/ruby/internal/intern/eval.h
+recursion.o: $(hdrdir)/ruby/internal/intern/file.h
+recursion.o: $(hdrdir)/ruby/internal/intern/gc.h
+recursion.o: $(hdrdir)/ruby/internal/intern/hash.h
+recursion.o: $(hdrdir)/ruby/internal/intern/io.h
+recursion.o: $(hdrdir)/ruby/internal/intern/load.h
+recursion.o: $(hdrdir)/ruby/internal/intern/marshal.h
+recursion.o: $(hdrdir)/ruby/internal/intern/numeric.h
+recursion.o: $(hdrdir)/ruby/internal/intern/object.h
+recursion.o: $(hdrdir)/ruby/internal/intern/parse.h
+recursion.o: $(hdrdir)/ruby/internal/intern/proc.h
+recursion.o: $(hdrdir)/ruby/internal/intern/process.h
+recursion.o: $(hdrdir)/ruby/internal/intern/random.h
+recursion.o: $(hdrdir)/ruby/internal/intern/range.h
+recursion.o: $(hdrdir)/ruby/internal/intern/rational.h
+recursion.o: $(hdrdir)/ruby/internal/intern/re.h
+recursion.o: $(hdrdir)/ruby/internal/intern/ruby.h
+recursion.o: $(hdrdir)/ruby/internal/intern/select.h
+recursion.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+recursion.o: $(hdrdir)/ruby/internal/intern/signal.h
+recursion.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+recursion.o: $(hdrdir)/ruby/internal/intern/string.h
+recursion.o: $(hdrdir)/ruby/internal/intern/struct.h
+recursion.o: $(hdrdir)/ruby/internal/intern/thread.h
+recursion.o: $(hdrdir)/ruby/internal/intern/time.h
+recursion.o: $(hdrdir)/ruby/internal/intern/variable.h
+recursion.o: $(hdrdir)/ruby/internal/intern/vm.h
+recursion.o: $(hdrdir)/ruby/internal/interpreter.h
+recursion.o: $(hdrdir)/ruby/internal/iterator.h
+recursion.o: $(hdrdir)/ruby/internal/memory.h
+recursion.o: $(hdrdir)/ruby/internal/method.h
+recursion.o: $(hdrdir)/ruby/internal/module.h
+recursion.o: $(hdrdir)/ruby/internal/newobj.h
+recursion.o: $(hdrdir)/ruby/internal/rgengc.h
+recursion.o: $(hdrdir)/ruby/internal/scan_args.h
+recursion.o: $(hdrdir)/ruby/internal/special_consts.h
+recursion.o: $(hdrdir)/ruby/internal/static_assert.h
+recursion.o: $(hdrdir)/ruby/internal/stdalign.h
+recursion.o: $(hdrdir)/ruby/internal/stdbool.h
+recursion.o: $(hdrdir)/ruby/internal/symbol.h
+recursion.o: $(hdrdir)/ruby/internal/token_paste.h
+recursion.o: $(hdrdir)/ruby/internal/value.h
+recursion.o: $(hdrdir)/ruby/internal/value_type.h
+recursion.o: $(hdrdir)/ruby/internal/variable.h
+recursion.o: $(hdrdir)/ruby/internal/warning_push.h
+recursion.o: $(hdrdir)/ruby/internal/xmalloc.h
+recursion.o: $(hdrdir)/ruby/assert.h
+recursion.o: $(hdrdir)/ruby/backward.h
+recursion.o: $(hdrdir)/ruby/backward/2/assume.h
+recursion.o: $(hdrdir)/ruby/backward/2/attributes.h
+recursion.o: $(hdrdir)/ruby/backward/2/bool.h
+recursion.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+recursion.o: $(hdrdir)/ruby/backward/2/inttypes.h
+recursion.o: $(hdrdir)/ruby/backward/2/limits.h
+recursion.o: $(hdrdir)/ruby/backward/2/long_long.h
+recursion.o: $(hdrdir)/ruby/backward/2/stdalign.h
+recursion.o: $(hdrdir)/ruby/backward/2/stdarg.h
+recursion.o: $(hdrdir)/ruby/defines.h
+recursion.o: $(hdrdir)/ruby/intern.h
+recursion.o: $(hdrdir)/ruby/missing.h
+recursion.o: $(hdrdir)/ruby/ruby.h
+recursion.o: $(hdrdir)/ruby/st.h
+recursion.o: $(hdrdir)/ruby/subst.h
+recursion.o: recursion.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/regexp/depend b/ext/-test-/regexp/depend
new file mode 100644
index 0000000000..1b00ccd568
--- /dev/null
+++ b/ext/-test-/regexp/depend
@@ -0,0 +1,325 @@
+# AUTOGENERATED DEPENDENCIES START
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+parse_depth_limit.o: $(RUBY_EXTCONF_H)
+parse_depth_limit.o: $(arch_hdrdir)/ruby/config.h
+parse_depth_limit.o: $(hdrdir)/ruby.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/anyargs.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/assume.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/artificial.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/cold.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/const.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/error.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/format.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noalias.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noinline.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/pure.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/restrict.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/warning.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/weakref.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/cast.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_is.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/compiler_since.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/config.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/constant_p.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rarray.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rbasic.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rbignum.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rclass.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rdata.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rfile.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rhash.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/robject.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rregexp.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rstring.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rstruct.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/ctype.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/dllexport.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/dosish.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/error.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/eval.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/event.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/fl_type.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/gc.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/glob.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/globals.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/attribute.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/builtin.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/extension.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/feature.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/has/warning.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/array.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/bignum.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/class.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/compar.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/complex.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/cont.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/dir.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/enum.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/error.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/eval.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/file.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/gc.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/hash.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/io.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/load.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/marshal.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/numeric.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/object.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/parse.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/proc.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/process.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/random.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/range.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/rational.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/re.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/ruby.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/select.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/signal.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/string.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/struct.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/thread.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/time.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/variable.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/vm.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/interpreter.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/iterator.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/memory.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/method.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/module.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/newobj.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/rgengc.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/scan_args.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/special_consts.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/static_assert.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/stdalign.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/stdbool.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/symbol.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/token_paste.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/value.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/value_type.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/variable.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/warning_push.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/xmalloc.h
+parse_depth_limit.o: $(hdrdir)/ruby/assert.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/assume.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/attributes.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/bool.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/inttypes.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/limits.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/long_long.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/stdalign.h
+parse_depth_limit.o: $(hdrdir)/ruby/backward/2/stdarg.h
+parse_depth_limit.o: $(hdrdir)/ruby/defines.h
+parse_depth_limit.o: $(hdrdir)/ruby/intern.h
+parse_depth_limit.o: $(hdrdir)/ruby/missing.h
+parse_depth_limit.o: $(hdrdir)/ruby/onigmo.h
+parse_depth_limit.o: $(hdrdir)/ruby/ruby.h
+parse_depth_limit.o: $(hdrdir)/ruby/st.h
+parse_depth_limit.o: $(hdrdir)/ruby/subst.h
+parse_depth_limit.o: parse_depth_limit.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/scan_args/depend b/ext/-test-/scan_args/depend
new file mode 100644
index 0000000000..91bd8419d0
--- /dev/null
+++ b/ext/-test-/scan_args/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+scan_args.o: $(RUBY_EXTCONF_H)
+scan_args.o: $(arch_hdrdir)/ruby/config.h
+scan_args.o: $(hdrdir)/ruby.h
+scan_args.o: $(hdrdir)/ruby/internal/anyargs.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+scan_args.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+scan_args.o: $(hdrdir)/ruby/internal/assume.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/artificial.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/cold.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/const.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/error.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/format.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/noalias.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/noinline.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/pure.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/restrict.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/warning.h
+scan_args.o: $(hdrdir)/ruby/internal/attr/weakref.h
+scan_args.o: $(hdrdir)/ruby/internal/cast.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_is.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+scan_args.o: $(hdrdir)/ruby/internal/compiler_since.h
+scan_args.o: $(hdrdir)/ruby/internal/config.h
+scan_args.o: $(hdrdir)/ruby/internal/constant_p.h
+scan_args.o: $(hdrdir)/ruby/internal/core.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rarray.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rbasic.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rbignum.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rclass.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rdata.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rfile.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rhash.h
+scan_args.o: $(hdrdir)/ruby/internal/core/robject.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rregexp.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rstring.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rstruct.h
+scan_args.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+scan_args.o: $(hdrdir)/ruby/internal/ctype.h
+scan_args.o: $(hdrdir)/ruby/internal/dllexport.h
+scan_args.o: $(hdrdir)/ruby/internal/dosish.h
+scan_args.o: $(hdrdir)/ruby/internal/error.h
+scan_args.o: $(hdrdir)/ruby/internal/eval.h
+scan_args.o: $(hdrdir)/ruby/internal/event.h
+scan_args.o: $(hdrdir)/ruby/internal/fl_type.h
+scan_args.o: $(hdrdir)/ruby/internal/gc.h
+scan_args.o: $(hdrdir)/ruby/internal/glob.h
+scan_args.o: $(hdrdir)/ruby/internal/globals.h
+scan_args.o: $(hdrdir)/ruby/internal/has/attribute.h
+scan_args.o: $(hdrdir)/ruby/internal/has/builtin.h
+scan_args.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+scan_args.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+scan_args.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+scan_args.o: $(hdrdir)/ruby/internal/has/extension.h
+scan_args.o: $(hdrdir)/ruby/internal/has/feature.h
+scan_args.o: $(hdrdir)/ruby/internal/has/warning.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/array.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/bignum.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/class.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/compar.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/complex.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/cont.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/dir.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/enum.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/error.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/eval.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/file.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/gc.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/hash.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/io.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/load.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/marshal.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/numeric.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/object.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/parse.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/proc.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/process.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/random.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/range.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/rational.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/re.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/ruby.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/select.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/signal.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/string.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/struct.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/thread.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/time.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/variable.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/vm.h
+scan_args.o: $(hdrdir)/ruby/internal/interpreter.h
+scan_args.o: $(hdrdir)/ruby/internal/iterator.h
+scan_args.o: $(hdrdir)/ruby/internal/memory.h
+scan_args.o: $(hdrdir)/ruby/internal/method.h
+scan_args.o: $(hdrdir)/ruby/internal/module.h
+scan_args.o: $(hdrdir)/ruby/internal/newobj.h
+scan_args.o: $(hdrdir)/ruby/internal/rgengc.h
+scan_args.o: $(hdrdir)/ruby/internal/scan_args.h
+scan_args.o: $(hdrdir)/ruby/internal/special_consts.h
+scan_args.o: $(hdrdir)/ruby/internal/static_assert.h
+scan_args.o: $(hdrdir)/ruby/internal/stdalign.h
+scan_args.o: $(hdrdir)/ruby/internal/stdbool.h
+scan_args.o: $(hdrdir)/ruby/internal/symbol.h
+scan_args.o: $(hdrdir)/ruby/internal/token_paste.h
+scan_args.o: $(hdrdir)/ruby/internal/value.h
+scan_args.o: $(hdrdir)/ruby/internal/value_type.h
+scan_args.o: $(hdrdir)/ruby/internal/variable.h
+scan_args.o: $(hdrdir)/ruby/internal/warning_push.h
+scan_args.o: $(hdrdir)/ruby/internal/xmalloc.h
+scan_args.o: $(hdrdir)/ruby/assert.h
+scan_args.o: $(hdrdir)/ruby/backward.h
+scan_args.o: $(hdrdir)/ruby/backward/2/assume.h
+scan_args.o: $(hdrdir)/ruby/backward/2/attributes.h
+scan_args.o: $(hdrdir)/ruby/backward/2/bool.h
+scan_args.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+scan_args.o: $(hdrdir)/ruby/backward/2/inttypes.h
+scan_args.o: $(hdrdir)/ruby/backward/2/limits.h
+scan_args.o: $(hdrdir)/ruby/backward/2/long_long.h
+scan_args.o: $(hdrdir)/ruby/backward/2/stdalign.h
+scan_args.o: $(hdrdir)/ruby/backward/2/stdarg.h
+scan_args.o: $(hdrdir)/ruby/defines.h
+scan_args.o: $(hdrdir)/ruby/intern.h
+scan_args.o: $(hdrdir)/ruby/missing.h
+scan_args.o: $(hdrdir)/ruby/ruby.h
+scan_args.o: $(hdrdir)/ruby/st.h
+scan_args.o: $(hdrdir)/ruby/subst.h
+scan_args.o: scan_args.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/scan_args/extconf.rb b/ext/-test-/scan_args/extconf.rb
index 6cae9c2779..6cae9c2779 100755..100644
--- a/ext/-test-/scan_args/extconf.rb
+++ b/ext/-test-/scan_args/extconf.rb
diff --git a/ext/-test-/scan_args/scan_args.c b/ext/-test-/scan_args/scan_args.c
index dca353f643..8696aad3c7 100644
--- a/ext/-test-/scan_args/scan_args.c
+++ b/ext/-test-/scan_args/scan_args.c
@@ -250,6 +250,24 @@ scan_args_lead_opt_var_trail_hash(int argc, VALUE *argv, VALUE self)
return rb_ary_new_from_values(numberof(args), args);
}
+static VALUE
+scan_args_k_lead_opt_hash(int argc, VALUE *argv, VALUE self)
+{
+ VALUE args[4];
+ int n = rb_scan_args_kw(RB_SCAN_ARGS_KEYWORDS, argc, argv, "11:", args+1, args+2, args+3);
+ args[0] = INT2NUM(n);
+ return rb_ary_new_from_values(numberof(args), args);
+}
+
+static VALUE
+scan_args_n_lead_opt_hash(int argc, VALUE *argv, VALUE self)
+{
+ VALUE args[4];
+ int n = rb_scan_args_kw(RB_SCAN_ARGS_LAST_HASH_KEYWORDS, argc, argv, "11:", args+1, args+2, args+3);
+ args[0] = INT2NUM(n);
+ return rb_ary_new_from_values(numberof(args), args);
+}
+
void
Init_scan_args(void)
{
@@ -282,5 +300,6 @@ Init_scan_args(void)
rb_define_singleton_method(module, "lead_var_trail_hash", scan_args_lead_var_trail_hash, -1);
rb_define_singleton_method(module, "opt_var_trail_hash", scan_args_opt_var_trail_hash, -1);
rb_define_singleton_method(module, "lead_opt_var_trail_hash", scan_args_lead_opt_var_trail_hash, -1);
+ rb_define_singleton_method(module, "k_lead_opt_hash", scan_args_k_lead_opt_hash, -1);
+ rb_define_singleton_method(module, "n_lead_opt_hash", scan_args_n_lead_opt_hash, -1);
}
-
diff --git a/ext/-test-/st/foreach/depend b/ext/-test-/st/foreach/depend
new file mode 100644
index 0000000000..25381871f0
--- /dev/null
+++ b/ext/-test-/st/foreach/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+foreach.o: $(RUBY_EXTCONF_H)
+foreach.o: $(arch_hdrdir)/ruby/config.h
+foreach.o: $(hdrdir)/ruby.h
+foreach.o: $(hdrdir)/ruby/internal/anyargs.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+foreach.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+foreach.o: $(hdrdir)/ruby/internal/assume.h
+foreach.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+foreach.o: $(hdrdir)/ruby/internal/attr/artificial.h
+foreach.o: $(hdrdir)/ruby/internal/attr/cold.h
+foreach.o: $(hdrdir)/ruby/internal/attr/const.h
+foreach.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+foreach.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+foreach.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+foreach.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+foreach.o: $(hdrdir)/ruby/internal/attr/error.h
+foreach.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+foreach.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+foreach.o: $(hdrdir)/ruby/internal/attr/format.h
+foreach.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+foreach.o: $(hdrdir)/ruby/internal/attr/noalias.h
+foreach.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+foreach.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+foreach.o: $(hdrdir)/ruby/internal/attr/noinline.h
+foreach.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+foreach.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+foreach.o: $(hdrdir)/ruby/internal/attr/pure.h
+foreach.o: $(hdrdir)/ruby/internal/attr/restrict.h
+foreach.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+foreach.o: $(hdrdir)/ruby/internal/attr/warning.h
+foreach.o: $(hdrdir)/ruby/internal/attr/weakref.h
+foreach.o: $(hdrdir)/ruby/internal/cast.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_is.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+foreach.o: $(hdrdir)/ruby/internal/compiler_since.h
+foreach.o: $(hdrdir)/ruby/internal/config.h
+foreach.o: $(hdrdir)/ruby/internal/constant_p.h
+foreach.o: $(hdrdir)/ruby/internal/core.h
+foreach.o: $(hdrdir)/ruby/internal/core/rarray.h
+foreach.o: $(hdrdir)/ruby/internal/core/rbasic.h
+foreach.o: $(hdrdir)/ruby/internal/core/rbignum.h
+foreach.o: $(hdrdir)/ruby/internal/core/rclass.h
+foreach.o: $(hdrdir)/ruby/internal/core/rdata.h
+foreach.o: $(hdrdir)/ruby/internal/core/rfile.h
+foreach.o: $(hdrdir)/ruby/internal/core/rhash.h
+foreach.o: $(hdrdir)/ruby/internal/core/robject.h
+foreach.o: $(hdrdir)/ruby/internal/core/rregexp.h
+foreach.o: $(hdrdir)/ruby/internal/core/rstring.h
+foreach.o: $(hdrdir)/ruby/internal/core/rstruct.h
+foreach.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+foreach.o: $(hdrdir)/ruby/internal/ctype.h
+foreach.o: $(hdrdir)/ruby/internal/dllexport.h
+foreach.o: $(hdrdir)/ruby/internal/dosish.h
+foreach.o: $(hdrdir)/ruby/internal/error.h
+foreach.o: $(hdrdir)/ruby/internal/eval.h
+foreach.o: $(hdrdir)/ruby/internal/event.h
+foreach.o: $(hdrdir)/ruby/internal/fl_type.h
+foreach.o: $(hdrdir)/ruby/internal/gc.h
+foreach.o: $(hdrdir)/ruby/internal/glob.h
+foreach.o: $(hdrdir)/ruby/internal/globals.h
+foreach.o: $(hdrdir)/ruby/internal/has/attribute.h
+foreach.o: $(hdrdir)/ruby/internal/has/builtin.h
+foreach.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+foreach.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+foreach.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+foreach.o: $(hdrdir)/ruby/internal/has/extension.h
+foreach.o: $(hdrdir)/ruby/internal/has/feature.h
+foreach.o: $(hdrdir)/ruby/internal/has/warning.h
+foreach.o: $(hdrdir)/ruby/internal/intern/array.h
+foreach.o: $(hdrdir)/ruby/internal/intern/bignum.h
+foreach.o: $(hdrdir)/ruby/internal/intern/class.h
+foreach.o: $(hdrdir)/ruby/internal/intern/compar.h
+foreach.o: $(hdrdir)/ruby/internal/intern/complex.h
+foreach.o: $(hdrdir)/ruby/internal/intern/cont.h
+foreach.o: $(hdrdir)/ruby/internal/intern/dir.h
+foreach.o: $(hdrdir)/ruby/internal/intern/enum.h
+foreach.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+foreach.o: $(hdrdir)/ruby/internal/intern/error.h
+foreach.o: $(hdrdir)/ruby/internal/intern/eval.h
+foreach.o: $(hdrdir)/ruby/internal/intern/file.h
+foreach.o: $(hdrdir)/ruby/internal/intern/gc.h
+foreach.o: $(hdrdir)/ruby/internal/intern/hash.h
+foreach.o: $(hdrdir)/ruby/internal/intern/io.h
+foreach.o: $(hdrdir)/ruby/internal/intern/load.h
+foreach.o: $(hdrdir)/ruby/internal/intern/marshal.h
+foreach.o: $(hdrdir)/ruby/internal/intern/numeric.h
+foreach.o: $(hdrdir)/ruby/internal/intern/object.h
+foreach.o: $(hdrdir)/ruby/internal/intern/parse.h
+foreach.o: $(hdrdir)/ruby/internal/intern/proc.h
+foreach.o: $(hdrdir)/ruby/internal/intern/process.h
+foreach.o: $(hdrdir)/ruby/internal/intern/random.h
+foreach.o: $(hdrdir)/ruby/internal/intern/range.h
+foreach.o: $(hdrdir)/ruby/internal/intern/rational.h
+foreach.o: $(hdrdir)/ruby/internal/intern/re.h
+foreach.o: $(hdrdir)/ruby/internal/intern/ruby.h
+foreach.o: $(hdrdir)/ruby/internal/intern/select.h
+foreach.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+foreach.o: $(hdrdir)/ruby/internal/intern/signal.h
+foreach.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+foreach.o: $(hdrdir)/ruby/internal/intern/string.h
+foreach.o: $(hdrdir)/ruby/internal/intern/struct.h
+foreach.o: $(hdrdir)/ruby/internal/intern/thread.h
+foreach.o: $(hdrdir)/ruby/internal/intern/time.h
+foreach.o: $(hdrdir)/ruby/internal/intern/variable.h
+foreach.o: $(hdrdir)/ruby/internal/intern/vm.h
+foreach.o: $(hdrdir)/ruby/internal/interpreter.h
+foreach.o: $(hdrdir)/ruby/internal/iterator.h
+foreach.o: $(hdrdir)/ruby/internal/memory.h
+foreach.o: $(hdrdir)/ruby/internal/method.h
+foreach.o: $(hdrdir)/ruby/internal/module.h
+foreach.o: $(hdrdir)/ruby/internal/newobj.h
+foreach.o: $(hdrdir)/ruby/internal/rgengc.h
+foreach.o: $(hdrdir)/ruby/internal/scan_args.h
+foreach.o: $(hdrdir)/ruby/internal/special_consts.h
+foreach.o: $(hdrdir)/ruby/internal/static_assert.h
+foreach.o: $(hdrdir)/ruby/internal/stdalign.h
+foreach.o: $(hdrdir)/ruby/internal/stdbool.h
+foreach.o: $(hdrdir)/ruby/internal/symbol.h
+foreach.o: $(hdrdir)/ruby/internal/token_paste.h
+foreach.o: $(hdrdir)/ruby/internal/value.h
+foreach.o: $(hdrdir)/ruby/internal/value_type.h
+foreach.o: $(hdrdir)/ruby/internal/variable.h
+foreach.o: $(hdrdir)/ruby/internal/warning_push.h
+foreach.o: $(hdrdir)/ruby/internal/xmalloc.h
+foreach.o: $(hdrdir)/ruby/assert.h
+foreach.o: $(hdrdir)/ruby/backward.h
+foreach.o: $(hdrdir)/ruby/backward/2/assume.h
+foreach.o: $(hdrdir)/ruby/backward/2/attributes.h
+foreach.o: $(hdrdir)/ruby/backward/2/bool.h
+foreach.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+foreach.o: $(hdrdir)/ruby/backward/2/inttypes.h
+foreach.o: $(hdrdir)/ruby/backward/2/limits.h
+foreach.o: $(hdrdir)/ruby/backward/2/long_long.h
+foreach.o: $(hdrdir)/ruby/backward/2/stdalign.h
+foreach.o: $(hdrdir)/ruby/backward/2/stdarg.h
+foreach.o: $(hdrdir)/ruby/defines.h
+foreach.o: $(hdrdir)/ruby/intern.h
+foreach.o: $(hdrdir)/ruby/missing.h
+foreach.o: $(hdrdir)/ruby/ruby.h
+foreach.o: $(hdrdir)/ruby/st.h
+foreach.o: $(hdrdir)/ruby/subst.h
+foreach.o: foreach.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/st/foreach/foreach.c b/ext/-test-/st/foreach/foreach.c
index 209b535503..27ac18046f 100644
--- a/ext/-test-/st/foreach/foreach.c
+++ b/ext/-test-/st/foreach/foreach.c
@@ -106,7 +106,7 @@ unp_fec(VALUE self, VALUE test)
}
static int
-unp_fe_i(st_data_t key, st_data_t val, st_data_t args, int error)
+unp_fe_i(st_data_t key, st_data_t val, st_data_t args)
{
struct checker *c = (struct checker *)args;
diff --git a/ext/-test-/st/numhash/depend b/ext/-test-/st/numhash/depend
new file mode 100644
index 0000000000..8e0560e018
--- /dev/null
+++ b/ext/-test-/st/numhash/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+numhash.o: $(RUBY_EXTCONF_H)
+numhash.o: $(arch_hdrdir)/ruby/config.h
+numhash.o: $(hdrdir)/ruby.h
+numhash.o: $(hdrdir)/ruby/internal/anyargs.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+numhash.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+numhash.o: $(hdrdir)/ruby/internal/assume.h
+numhash.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+numhash.o: $(hdrdir)/ruby/internal/attr/artificial.h
+numhash.o: $(hdrdir)/ruby/internal/attr/cold.h
+numhash.o: $(hdrdir)/ruby/internal/attr/const.h
+numhash.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+numhash.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+numhash.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+numhash.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+numhash.o: $(hdrdir)/ruby/internal/attr/error.h
+numhash.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+numhash.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+numhash.o: $(hdrdir)/ruby/internal/attr/format.h
+numhash.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+numhash.o: $(hdrdir)/ruby/internal/attr/noalias.h
+numhash.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+numhash.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+numhash.o: $(hdrdir)/ruby/internal/attr/noinline.h
+numhash.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+numhash.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+numhash.o: $(hdrdir)/ruby/internal/attr/pure.h
+numhash.o: $(hdrdir)/ruby/internal/attr/restrict.h
+numhash.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+numhash.o: $(hdrdir)/ruby/internal/attr/warning.h
+numhash.o: $(hdrdir)/ruby/internal/attr/weakref.h
+numhash.o: $(hdrdir)/ruby/internal/cast.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_is.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+numhash.o: $(hdrdir)/ruby/internal/compiler_since.h
+numhash.o: $(hdrdir)/ruby/internal/config.h
+numhash.o: $(hdrdir)/ruby/internal/constant_p.h
+numhash.o: $(hdrdir)/ruby/internal/core.h
+numhash.o: $(hdrdir)/ruby/internal/core/rarray.h
+numhash.o: $(hdrdir)/ruby/internal/core/rbasic.h
+numhash.o: $(hdrdir)/ruby/internal/core/rbignum.h
+numhash.o: $(hdrdir)/ruby/internal/core/rclass.h
+numhash.o: $(hdrdir)/ruby/internal/core/rdata.h
+numhash.o: $(hdrdir)/ruby/internal/core/rfile.h
+numhash.o: $(hdrdir)/ruby/internal/core/rhash.h
+numhash.o: $(hdrdir)/ruby/internal/core/robject.h
+numhash.o: $(hdrdir)/ruby/internal/core/rregexp.h
+numhash.o: $(hdrdir)/ruby/internal/core/rstring.h
+numhash.o: $(hdrdir)/ruby/internal/core/rstruct.h
+numhash.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+numhash.o: $(hdrdir)/ruby/internal/ctype.h
+numhash.o: $(hdrdir)/ruby/internal/dllexport.h
+numhash.o: $(hdrdir)/ruby/internal/dosish.h
+numhash.o: $(hdrdir)/ruby/internal/error.h
+numhash.o: $(hdrdir)/ruby/internal/eval.h
+numhash.o: $(hdrdir)/ruby/internal/event.h
+numhash.o: $(hdrdir)/ruby/internal/fl_type.h
+numhash.o: $(hdrdir)/ruby/internal/gc.h
+numhash.o: $(hdrdir)/ruby/internal/glob.h
+numhash.o: $(hdrdir)/ruby/internal/globals.h
+numhash.o: $(hdrdir)/ruby/internal/has/attribute.h
+numhash.o: $(hdrdir)/ruby/internal/has/builtin.h
+numhash.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+numhash.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+numhash.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+numhash.o: $(hdrdir)/ruby/internal/has/extension.h
+numhash.o: $(hdrdir)/ruby/internal/has/feature.h
+numhash.o: $(hdrdir)/ruby/internal/has/warning.h
+numhash.o: $(hdrdir)/ruby/internal/intern/array.h
+numhash.o: $(hdrdir)/ruby/internal/intern/bignum.h
+numhash.o: $(hdrdir)/ruby/internal/intern/class.h
+numhash.o: $(hdrdir)/ruby/internal/intern/compar.h
+numhash.o: $(hdrdir)/ruby/internal/intern/complex.h
+numhash.o: $(hdrdir)/ruby/internal/intern/cont.h
+numhash.o: $(hdrdir)/ruby/internal/intern/dir.h
+numhash.o: $(hdrdir)/ruby/internal/intern/enum.h
+numhash.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+numhash.o: $(hdrdir)/ruby/internal/intern/error.h
+numhash.o: $(hdrdir)/ruby/internal/intern/eval.h
+numhash.o: $(hdrdir)/ruby/internal/intern/file.h
+numhash.o: $(hdrdir)/ruby/internal/intern/gc.h
+numhash.o: $(hdrdir)/ruby/internal/intern/hash.h
+numhash.o: $(hdrdir)/ruby/internal/intern/io.h
+numhash.o: $(hdrdir)/ruby/internal/intern/load.h
+numhash.o: $(hdrdir)/ruby/internal/intern/marshal.h
+numhash.o: $(hdrdir)/ruby/internal/intern/numeric.h
+numhash.o: $(hdrdir)/ruby/internal/intern/object.h
+numhash.o: $(hdrdir)/ruby/internal/intern/parse.h
+numhash.o: $(hdrdir)/ruby/internal/intern/proc.h
+numhash.o: $(hdrdir)/ruby/internal/intern/process.h
+numhash.o: $(hdrdir)/ruby/internal/intern/random.h
+numhash.o: $(hdrdir)/ruby/internal/intern/range.h
+numhash.o: $(hdrdir)/ruby/internal/intern/rational.h
+numhash.o: $(hdrdir)/ruby/internal/intern/re.h
+numhash.o: $(hdrdir)/ruby/internal/intern/ruby.h
+numhash.o: $(hdrdir)/ruby/internal/intern/select.h
+numhash.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+numhash.o: $(hdrdir)/ruby/internal/intern/signal.h
+numhash.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+numhash.o: $(hdrdir)/ruby/internal/intern/string.h
+numhash.o: $(hdrdir)/ruby/internal/intern/struct.h
+numhash.o: $(hdrdir)/ruby/internal/intern/thread.h
+numhash.o: $(hdrdir)/ruby/internal/intern/time.h
+numhash.o: $(hdrdir)/ruby/internal/intern/variable.h
+numhash.o: $(hdrdir)/ruby/internal/intern/vm.h
+numhash.o: $(hdrdir)/ruby/internal/interpreter.h
+numhash.o: $(hdrdir)/ruby/internal/iterator.h
+numhash.o: $(hdrdir)/ruby/internal/memory.h
+numhash.o: $(hdrdir)/ruby/internal/method.h
+numhash.o: $(hdrdir)/ruby/internal/module.h
+numhash.o: $(hdrdir)/ruby/internal/newobj.h
+numhash.o: $(hdrdir)/ruby/internal/rgengc.h
+numhash.o: $(hdrdir)/ruby/internal/scan_args.h
+numhash.o: $(hdrdir)/ruby/internal/special_consts.h
+numhash.o: $(hdrdir)/ruby/internal/static_assert.h
+numhash.o: $(hdrdir)/ruby/internal/stdalign.h
+numhash.o: $(hdrdir)/ruby/internal/stdbool.h
+numhash.o: $(hdrdir)/ruby/internal/symbol.h
+numhash.o: $(hdrdir)/ruby/internal/token_paste.h
+numhash.o: $(hdrdir)/ruby/internal/value.h
+numhash.o: $(hdrdir)/ruby/internal/value_type.h
+numhash.o: $(hdrdir)/ruby/internal/variable.h
+numhash.o: $(hdrdir)/ruby/internal/warning_push.h
+numhash.o: $(hdrdir)/ruby/internal/xmalloc.h
+numhash.o: $(hdrdir)/ruby/assert.h
+numhash.o: $(hdrdir)/ruby/backward.h
+numhash.o: $(hdrdir)/ruby/backward/2/assume.h
+numhash.o: $(hdrdir)/ruby/backward/2/attributes.h
+numhash.o: $(hdrdir)/ruby/backward/2/bool.h
+numhash.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+numhash.o: $(hdrdir)/ruby/backward/2/inttypes.h
+numhash.o: $(hdrdir)/ruby/backward/2/limits.h
+numhash.o: $(hdrdir)/ruby/backward/2/long_long.h
+numhash.o: $(hdrdir)/ruby/backward/2/stdalign.h
+numhash.o: $(hdrdir)/ruby/backward/2/stdarg.h
+numhash.o: $(hdrdir)/ruby/defines.h
+numhash.o: $(hdrdir)/ruby/intern.h
+numhash.o: $(hdrdir)/ruby/missing.h
+numhash.o: $(hdrdir)/ruby/ruby.h
+numhash.o: $(hdrdir)/ruby/st.h
+numhash.o: $(hdrdir)/ruby/subst.h
+numhash.o: numhash.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/st/numhash/numhash.c b/ext/-test-/st/numhash/numhash.c
index fc35f476cd..aa8015e86c 100644
--- a/ext/-test-/st/numhash/numhash.c
+++ b/ext/-test-/st/numhash/numhash.c
@@ -57,7 +57,7 @@ numhash_aset(VALUE self, VALUE key, VALUE data)
}
static int
-numhash_i(st_data_t key, st_data_t value, st_data_t arg)
+numhash_i(st_data_t key, st_data_t value, st_data_t arg, int _)
{
VALUE ret;
ret = rb_yield_values(3, (VALUE)key, (VALUE)value, (VALUE)arg);
@@ -125,7 +125,7 @@ numhash_delete_safe(VALUE self, VALUE key)
void
Init_numhash(void)
{
- VALUE st = rb_define_class_under(rb_define_module("Bug"), "StNumHash", rb_cData);
+ VALUE st = rb_define_class_under(rb_define_module("Bug"), "StNumHash", rb_cObject);
rb_define_alloc_func(st, numhash_alloc);
rb_define_method(st, "initialize", numhash_init, 0);
rb_define_method(st, "[]", numhash_aref, 1);
@@ -135,4 +135,3 @@ Init_numhash(void)
rb_define_method(st, "size", numhash_size, 0);
rb_define_method(st, "delete_safe", numhash_delete_safe, 1);
}
-
diff --git a/ext/-test-/st/update/depend b/ext/-test-/st/update/depend
new file mode 100644
index 0000000000..c11a5b14a7
--- /dev/null
+++ b/ext/-test-/st/update/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+update.o: $(RUBY_EXTCONF_H)
+update.o: $(arch_hdrdir)/ruby/config.h
+update.o: $(hdrdir)/ruby.h
+update.o: $(hdrdir)/ruby/internal/anyargs.h
+update.o: $(hdrdir)/ruby/internal/arithmetic.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+update.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+update.o: $(hdrdir)/ruby/internal/assume.h
+update.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+update.o: $(hdrdir)/ruby/internal/attr/artificial.h
+update.o: $(hdrdir)/ruby/internal/attr/cold.h
+update.o: $(hdrdir)/ruby/internal/attr/const.h
+update.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+update.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+update.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+update.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+update.o: $(hdrdir)/ruby/internal/attr/error.h
+update.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+update.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+update.o: $(hdrdir)/ruby/internal/attr/format.h
+update.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+update.o: $(hdrdir)/ruby/internal/attr/noalias.h
+update.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+update.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+update.o: $(hdrdir)/ruby/internal/attr/noinline.h
+update.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+update.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+update.o: $(hdrdir)/ruby/internal/attr/pure.h
+update.o: $(hdrdir)/ruby/internal/attr/restrict.h
+update.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+update.o: $(hdrdir)/ruby/internal/attr/warning.h
+update.o: $(hdrdir)/ruby/internal/attr/weakref.h
+update.o: $(hdrdir)/ruby/internal/cast.h
+update.o: $(hdrdir)/ruby/internal/compiler_is.h
+update.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+update.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+update.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+update.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+update.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+update.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+update.o: $(hdrdir)/ruby/internal/compiler_since.h
+update.o: $(hdrdir)/ruby/internal/config.h
+update.o: $(hdrdir)/ruby/internal/constant_p.h
+update.o: $(hdrdir)/ruby/internal/core.h
+update.o: $(hdrdir)/ruby/internal/core/rarray.h
+update.o: $(hdrdir)/ruby/internal/core/rbasic.h
+update.o: $(hdrdir)/ruby/internal/core/rbignum.h
+update.o: $(hdrdir)/ruby/internal/core/rclass.h
+update.o: $(hdrdir)/ruby/internal/core/rdata.h
+update.o: $(hdrdir)/ruby/internal/core/rfile.h
+update.o: $(hdrdir)/ruby/internal/core/rhash.h
+update.o: $(hdrdir)/ruby/internal/core/robject.h
+update.o: $(hdrdir)/ruby/internal/core/rregexp.h
+update.o: $(hdrdir)/ruby/internal/core/rstring.h
+update.o: $(hdrdir)/ruby/internal/core/rstruct.h
+update.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+update.o: $(hdrdir)/ruby/internal/ctype.h
+update.o: $(hdrdir)/ruby/internal/dllexport.h
+update.o: $(hdrdir)/ruby/internal/dosish.h
+update.o: $(hdrdir)/ruby/internal/error.h
+update.o: $(hdrdir)/ruby/internal/eval.h
+update.o: $(hdrdir)/ruby/internal/event.h
+update.o: $(hdrdir)/ruby/internal/fl_type.h
+update.o: $(hdrdir)/ruby/internal/gc.h
+update.o: $(hdrdir)/ruby/internal/glob.h
+update.o: $(hdrdir)/ruby/internal/globals.h
+update.o: $(hdrdir)/ruby/internal/has/attribute.h
+update.o: $(hdrdir)/ruby/internal/has/builtin.h
+update.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+update.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+update.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+update.o: $(hdrdir)/ruby/internal/has/extension.h
+update.o: $(hdrdir)/ruby/internal/has/feature.h
+update.o: $(hdrdir)/ruby/internal/has/warning.h
+update.o: $(hdrdir)/ruby/internal/intern/array.h
+update.o: $(hdrdir)/ruby/internal/intern/bignum.h
+update.o: $(hdrdir)/ruby/internal/intern/class.h
+update.o: $(hdrdir)/ruby/internal/intern/compar.h
+update.o: $(hdrdir)/ruby/internal/intern/complex.h
+update.o: $(hdrdir)/ruby/internal/intern/cont.h
+update.o: $(hdrdir)/ruby/internal/intern/dir.h
+update.o: $(hdrdir)/ruby/internal/intern/enum.h
+update.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+update.o: $(hdrdir)/ruby/internal/intern/error.h
+update.o: $(hdrdir)/ruby/internal/intern/eval.h
+update.o: $(hdrdir)/ruby/internal/intern/file.h
+update.o: $(hdrdir)/ruby/internal/intern/gc.h
+update.o: $(hdrdir)/ruby/internal/intern/hash.h
+update.o: $(hdrdir)/ruby/internal/intern/io.h
+update.o: $(hdrdir)/ruby/internal/intern/load.h
+update.o: $(hdrdir)/ruby/internal/intern/marshal.h
+update.o: $(hdrdir)/ruby/internal/intern/numeric.h
+update.o: $(hdrdir)/ruby/internal/intern/object.h
+update.o: $(hdrdir)/ruby/internal/intern/parse.h
+update.o: $(hdrdir)/ruby/internal/intern/proc.h
+update.o: $(hdrdir)/ruby/internal/intern/process.h
+update.o: $(hdrdir)/ruby/internal/intern/random.h
+update.o: $(hdrdir)/ruby/internal/intern/range.h
+update.o: $(hdrdir)/ruby/internal/intern/rational.h
+update.o: $(hdrdir)/ruby/internal/intern/re.h
+update.o: $(hdrdir)/ruby/internal/intern/ruby.h
+update.o: $(hdrdir)/ruby/internal/intern/select.h
+update.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+update.o: $(hdrdir)/ruby/internal/intern/signal.h
+update.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+update.o: $(hdrdir)/ruby/internal/intern/string.h
+update.o: $(hdrdir)/ruby/internal/intern/struct.h
+update.o: $(hdrdir)/ruby/internal/intern/thread.h
+update.o: $(hdrdir)/ruby/internal/intern/time.h
+update.o: $(hdrdir)/ruby/internal/intern/variable.h
+update.o: $(hdrdir)/ruby/internal/intern/vm.h
+update.o: $(hdrdir)/ruby/internal/interpreter.h
+update.o: $(hdrdir)/ruby/internal/iterator.h
+update.o: $(hdrdir)/ruby/internal/memory.h
+update.o: $(hdrdir)/ruby/internal/method.h
+update.o: $(hdrdir)/ruby/internal/module.h
+update.o: $(hdrdir)/ruby/internal/newobj.h
+update.o: $(hdrdir)/ruby/internal/rgengc.h
+update.o: $(hdrdir)/ruby/internal/scan_args.h
+update.o: $(hdrdir)/ruby/internal/special_consts.h
+update.o: $(hdrdir)/ruby/internal/static_assert.h
+update.o: $(hdrdir)/ruby/internal/stdalign.h
+update.o: $(hdrdir)/ruby/internal/stdbool.h
+update.o: $(hdrdir)/ruby/internal/symbol.h
+update.o: $(hdrdir)/ruby/internal/token_paste.h
+update.o: $(hdrdir)/ruby/internal/value.h
+update.o: $(hdrdir)/ruby/internal/value_type.h
+update.o: $(hdrdir)/ruby/internal/variable.h
+update.o: $(hdrdir)/ruby/internal/warning_push.h
+update.o: $(hdrdir)/ruby/internal/xmalloc.h
+update.o: $(hdrdir)/ruby/assert.h
+update.o: $(hdrdir)/ruby/backward.h
+update.o: $(hdrdir)/ruby/backward/2/assume.h
+update.o: $(hdrdir)/ruby/backward/2/attributes.h
+update.o: $(hdrdir)/ruby/backward/2/bool.h
+update.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+update.o: $(hdrdir)/ruby/backward/2/inttypes.h
+update.o: $(hdrdir)/ruby/backward/2/limits.h
+update.o: $(hdrdir)/ruby/backward/2/long_long.h
+update.o: $(hdrdir)/ruby/backward/2/stdalign.h
+update.o: $(hdrdir)/ruby/backward/2/stdarg.h
+update.o: $(hdrdir)/ruby/defines.h
+update.o: $(hdrdir)/ruby/intern.h
+update.o: $(hdrdir)/ruby/missing.h
+update.o: $(hdrdir)/ruby/ruby.h
+update.o: $(hdrdir)/ruby/st.h
+update.o: $(hdrdir)/ruby/subst.h
+update.o: update.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/string/capacity.c b/ext/-test-/string/capacity.c
index ba7fb85e9e..cb8d2c2b3a 100644
--- a/ext/-test-/string/capacity.c
+++ b/ext/-test-/string/capacity.c
@@ -1,5 +1,5 @@
#include "ruby.h"
-#include "internal.h"
+#include "internal/string.h"
static VALUE
bug_str_capacity(VALUE klass, VALUE str)
@@ -11,7 +11,7 @@ bug_str_capacity(VALUE klass, VALUE str)
}
void
-Init_capacity(VALUE klass)
+Init_string_capacity(VALUE klass)
{
rb_define_singleton_method(klass, "capacity", bug_str_capacity, 1);
}
diff --git a/ext/-test-/string/coderange.c b/ext/-test-/string/coderange.c
index b93172d72d..bc998ca372 100644
--- a/ext/-test-/string/coderange.c
+++ b/ext/-test-/string/coderange.c
@@ -17,7 +17,7 @@ coderange_int2sym(int coderange)
return sym_broken;
}
rb_bug("wrong condition of coderange");
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
/* return coderange without scan */
@@ -36,12 +36,12 @@ str_coderange_scan(VALUE str)
}
void
-Init_coderange(VALUE klass)
+Init_string_coderange(VALUE klass)
{
- sym_7bit = ID2SYM(rb_intern("7bit"));
- sym_valid = ID2SYM(rb_intern("valid"));
- sym_unknown = ID2SYM(rb_intern("unknown"));
- sym_broken = ID2SYM(rb_intern("broken"));
+ sym_7bit = ID2SYM(rb_intern_const("7bit"));
+ sym_valid = ID2SYM(rb_intern_const("valid"));
+ sym_unknown = ID2SYM(rb_intern_const("unknown"));
+ sym_broken = ID2SYM(rb_intern_const("broken"));
rb_define_method(klass, "coderange", str_coderange, 0);
rb_define_method(klass, "coderange_scan", str_coderange_scan, 0);
}
diff --git a/ext/-test-/string/cstr.c b/ext/-test-/string/cstr.c
index fc47d5206f..4f837998d7 100644
--- a/ext/-test-/string/cstr.c
+++ b/ext/-test-/string/cstr.c
@@ -1,4 +1,6 @@
#include "internal.h"
+#include "internal/string.h"
+#include "ruby/encoding.h"
static VALUE
bug_str_cstr_term(VALUE str)
@@ -131,7 +133,7 @@ bug_str_s_rb_str_new_frozen(VALUE self, VALUE str)
}
void
-Init_cstr(VALUE klass)
+Init_string_cstr(VALUE klass)
{
rb_define_method(klass, "cstr_term", bug_str_cstr_term, 0);
rb_define_method(klass, "cstr_unterm", bug_str_cstr_unterm, 1);
diff --git a/ext/-test-/string/depend b/ext/-test-/string/depend
index 1255380bb8..7db4465bf9 100644
--- a/ext/-test-/string/depend
+++ b/ext/-test-/string/depend
@@ -1,26 +1,327 @@
# AUTOGENERATED DEPENDENCIES START
capacity.o: $(RUBY_EXTCONF_H)
capacity.o: $(arch_hdrdir)/ruby/config.h
+capacity.o: $(hdrdir)/ruby.h
+capacity.o: $(hdrdir)/ruby/assert.h
capacity.o: $(hdrdir)/ruby/backward.h
+capacity.o: $(hdrdir)/ruby/backward/2/assume.h
+capacity.o: $(hdrdir)/ruby/backward/2/attributes.h
+capacity.o: $(hdrdir)/ruby/backward/2/bool.h
+capacity.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+capacity.o: $(hdrdir)/ruby/backward/2/inttypes.h
+capacity.o: $(hdrdir)/ruby/backward/2/limits.h
+capacity.o: $(hdrdir)/ruby/backward/2/long_long.h
+capacity.o: $(hdrdir)/ruby/backward/2/stdalign.h
+capacity.o: $(hdrdir)/ruby/backward/2/stdarg.h
capacity.o: $(hdrdir)/ruby/defines.h
capacity.o: $(hdrdir)/ruby/encoding.h
capacity.o: $(hdrdir)/ruby/intern.h
-capacity.o: $(hdrdir)/ruby/io.h
+capacity.o: $(hdrdir)/ruby/internal/anyargs.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+capacity.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+capacity.o: $(hdrdir)/ruby/internal/assume.h
+capacity.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+capacity.o: $(hdrdir)/ruby/internal/attr/artificial.h
+capacity.o: $(hdrdir)/ruby/internal/attr/cold.h
+capacity.o: $(hdrdir)/ruby/internal/attr/const.h
+capacity.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+capacity.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+capacity.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+capacity.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+capacity.o: $(hdrdir)/ruby/internal/attr/error.h
+capacity.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+capacity.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+capacity.o: $(hdrdir)/ruby/internal/attr/format.h
+capacity.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+capacity.o: $(hdrdir)/ruby/internal/attr/noalias.h
+capacity.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+capacity.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+capacity.o: $(hdrdir)/ruby/internal/attr/noinline.h
+capacity.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+capacity.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+capacity.o: $(hdrdir)/ruby/internal/attr/pure.h
+capacity.o: $(hdrdir)/ruby/internal/attr/restrict.h
+capacity.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+capacity.o: $(hdrdir)/ruby/internal/attr/warning.h
+capacity.o: $(hdrdir)/ruby/internal/attr/weakref.h
+capacity.o: $(hdrdir)/ruby/internal/cast.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_is.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+capacity.o: $(hdrdir)/ruby/internal/compiler_since.h
+capacity.o: $(hdrdir)/ruby/internal/config.h
+capacity.o: $(hdrdir)/ruby/internal/constant_p.h
+capacity.o: $(hdrdir)/ruby/internal/core.h
+capacity.o: $(hdrdir)/ruby/internal/core/rarray.h
+capacity.o: $(hdrdir)/ruby/internal/core/rbasic.h
+capacity.o: $(hdrdir)/ruby/internal/core/rbignum.h
+capacity.o: $(hdrdir)/ruby/internal/core/rclass.h
+capacity.o: $(hdrdir)/ruby/internal/core/rdata.h
+capacity.o: $(hdrdir)/ruby/internal/core/rfile.h
+capacity.o: $(hdrdir)/ruby/internal/core/rhash.h
+capacity.o: $(hdrdir)/ruby/internal/core/robject.h
+capacity.o: $(hdrdir)/ruby/internal/core/rregexp.h
+capacity.o: $(hdrdir)/ruby/internal/core/rstring.h
+capacity.o: $(hdrdir)/ruby/internal/core/rstruct.h
+capacity.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+capacity.o: $(hdrdir)/ruby/internal/ctype.h
+capacity.o: $(hdrdir)/ruby/internal/dllexport.h
+capacity.o: $(hdrdir)/ruby/internal/dosish.h
+capacity.o: $(hdrdir)/ruby/internal/error.h
+capacity.o: $(hdrdir)/ruby/internal/eval.h
+capacity.o: $(hdrdir)/ruby/internal/event.h
+capacity.o: $(hdrdir)/ruby/internal/fl_type.h
+capacity.o: $(hdrdir)/ruby/internal/gc.h
+capacity.o: $(hdrdir)/ruby/internal/glob.h
+capacity.o: $(hdrdir)/ruby/internal/globals.h
+capacity.o: $(hdrdir)/ruby/internal/has/attribute.h
+capacity.o: $(hdrdir)/ruby/internal/has/builtin.h
+capacity.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+capacity.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+capacity.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+capacity.o: $(hdrdir)/ruby/internal/has/extension.h
+capacity.o: $(hdrdir)/ruby/internal/has/feature.h
+capacity.o: $(hdrdir)/ruby/internal/has/warning.h
+capacity.o: $(hdrdir)/ruby/internal/intern/array.h
+capacity.o: $(hdrdir)/ruby/internal/intern/bignum.h
+capacity.o: $(hdrdir)/ruby/internal/intern/class.h
+capacity.o: $(hdrdir)/ruby/internal/intern/compar.h
+capacity.o: $(hdrdir)/ruby/internal/intern/complex.h
+capacity.o: $(hdrdir)/ruby/internal/intern/cont.h
+capacity.o: $(hdrdir)/ruby/internal/intern/dir.h
+capacity.o: $(hdrdir)/ruby/internal/intern/enum.h
+capacity.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+capacity.o: $(hdrdir)/ruby/internal/intern/error.h
+capacity.o: $(hdrdir)/ruby/internal/intern/eval.h
+capacity.o: $(hdrdir)/ruby/internal/intern/file.h
+capacity.o: $(hdrdir)/ruby/internal/intern/gc.h
+capacity.o: $(hdrdir)/ruby/internal/intern/hash.h
+capacity.o: $(hdrdir)/ruby/internal/intern/io.h
+capacity.o: $(hdrdir)/ruby/internal/intern/load.h
+capacity.o: $(hdrdir)/ruby/internal/intern/marshal.h
+capacity.o: $(hdrdir)/ruby/internal/intern/numeric.h
+capacity.o: $(hdrdir)/ruby/internal/intern/object.h
+capacity.o: $(hdrdir)/ruby/internal/intern/parse.h
+capacity.o: $(hdrdir)/ruby/internal/intern/proc.h
+capacity.o: $(hdrdir)/ruby/internal/intern/process.h
+capacity.o: $(hdrdir)/ruby/internal/intern/random.h
+capacity.o: $(hdrdir)/ruby/internal/intern/range.h
+capacity.o: $(hdrdir)/ruby/internal/intern/rational.h
+capacity.o: $(hdrdir)/ruby/internal/intern/re.h
+capacity.o: $(hdrdir)/ruby/internal/intern/ruby.h
+capacity.o: $(hdrdir)/ruby/internal/intern/select.h
+capacity.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+capacity.o: $(hdrdir)/ruby/internal/intern/signal.h
+capacity.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+capacity.o: $(hdrdir)/ruby/internal/intern/string.h
+capacity.o: $(hdrdir)/ruby/internal/intern/struct.h
+capacity.o: $(hdrdir)/ruby/internal/intern/thread.h
+capacity.o: $(hdrdir)/ruby/internal/intern/time.h
+capacity.o: $(hdrdir)/ruby/internal/intern/variable.h
+capacity.o: $(hdrdir)/ruby/internal/intern/vm.h
+capacity.o: $(hdrdir)/ruby/internal/interpreter.h
+capacity.o: $(hdrdir)/ruby/internal/iterator.h
+capacity.o: $(hdrdir)/ruby/internal/memory.h
+capacity.o: $(hdrdir)/ruby/internal/method.h
+capacity.o: $(hdrdir)/ruby/internal/module.h
+capacity.o: $(hdrdir)/ruby/internal/newobj.h
+capacity.o: $(hdrdir)/ruby/internal/rgengc.h
+capacity.o: $(hdrdir)/ruby/internal/scan_args.h
+capacity.o: $(hdrdir)/ruby/internal/special_consts.h
+capacity.o: $(hdrdir)/ruby/internal/static_assert.h
+capacity.o: $(hdrdir)/ruby/internal/stdalign.h
+capacity.o: $(hdrdir)/ruby/internal/stdbool.h
+capacity.o: $(hdrdir)/ruby/internal/symbol.h
+capacity.o: $(hdrdir)/ruby/internal/token_paste.h
+capacity.o: $(hdrdir)/ruby/internal/value.h
+capacity.o: $(hdrdir)/ruby/internal/value_type.h
+capacity.o: $(hdrdir)/ruby/internal/variable.h
+capacity.o: $(hdrdir)/ruby/internal/warning_push.h
+capacity.o: $(hdrdir)/ruby/internal/xmalloc.h
capacity.o: $(hdrdir)/ruby/missing.h
capacity.o: $(hdrdir)/ruby/onigmo.h
capacity.o: $(hdrdir)/ruby/oniguruma.h
capacity.o: $(hdrdir)/ruby/ruby.h
capacity.o: $(hdrdir)/ruby/st.h
capacity.o: $(hdrdir)/ruby/subst.h
-capacity.o: $(top_srcdir)/include/ruby.h
capacity.o: $(top_srcdir)/internal.h
+capacity.o: $(top_srcdir)/internal/compilers.h
+capacity.o: $(top_srcdir)/internal/string.h
capacity.o: capacity.c
coderange.o: $(RUBY_EXTCONF_H)
coderange.o: $(arch_hdrdir)/ruby/config.h
+coderange.o: $(hdrdir)/ruby/assert.h
coderange.o: $(hdrdir)/ruby/backward.h
+coderange.o: $(hdrdir)/ruby/backward/2/assume.h
+coderange.o: $(hdrdir)/ruby/backward/2/attributes.h
+coderange.o: $(hdrdir)/ruby/backward/2/bool.h
+coderange.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+coderange.o: $(hdrdir)/ruby/backward/2/inttypes.h
+coderange.o: $(hdrdir)/ruby/backward/2/limits.h
+coderange.o: $(hdrdir)/ruby/backward/2/long_long.h
+coderange.o: $(hdrdir)/ruby/backward/2/stdalign.h
+coderange.o: $(hdrdir)/ruby/backward/2/stdarg.h
coderange.o: $(hdrdir)/ruby/defines.h
coderange.o: $(hdrdir)/ruby/encoding.h
coderange.o: $(hdrdir)/ruby/intern.h
+coderange.o: $(hdrdir)/ruby/internal/anyargs.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+coderange.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+coderange.o: $(hdrdir)/ruby/internal/assume.h
+coderange.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+coderange.o: $(hdrdir)/ruby/internal/attr/artificial.h
+coderange.o: $(hdrdir)/ruby/internal/attr/cold.h
+coderange.o: $(hdrdir)/ruby/internal/attr/const.h
+coderange.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+coderange.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+coderange.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+coderange.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+coderange.o: $(hdrdir)/ruby/internal/attr/error.h
+coderange.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+coderange.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+coderange.o: $(hdrdir)/ruby/internal/attr/format.h
+coderange.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+coderange.o: $(hdrdir)/ruby/internal/attr/noalias.h
+coderange.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+coderange.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+coderange.o: $(hdrdir)/ruby/internal/attr/noinline.h
+coderange.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+coderange.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+coderange.o: $(hdrdir)/ruby/internal/attr/pure.h
+coderange.o: $(hdrdir)/ruby/internal/attr/restrict.h
+coderange.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+coderange.o: $(hdrdir)/ruby/internal/attr/warning.h
+coderange.o: $(hdrdir)/ruby/internal/attr/weakref.h
+coderange.o: $(hdrdir)/ruby/internal/cast.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_is.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+coderange.o: $(hdrdir)/ruby/internal/compiler_since.h
+coderange.o: $(hdrdir)/ruby/internal/config.h
+coderange.o: $(hdrdir)/ruby/internal/constant_p.h
+coderange.o: $(hdrdir)/ruby/internal/core.h
+coderange.o: $(hdrdir)/ruby/internal/core/rarray.h
+coderange.o: $(hdrdir)/ruby/internal/core/rbasic.h
+coderange.o: $(hdrdir)/ruby/internal/core/rbignum.h
+coderange.o: $(hdrdir)/ruby/internal/core/rclass.h
+coderange.o: $(hdrdir)/ruby/internal/core/rdata.h
+coderange.o: $(hdrdir)/ruby/internal/core/rfile.h
+coderange.o: $(hdrdir)/ruby/internal/core/rhash.h
+coderange.o: $(hdrdir)/ruby/internal/core/robject.h
+coderange.o: $(hdrdir)/ruby/internal/core/rregexp.h
+coderange.o: $(hdrdir)/ruby/internal/core/rstring.h
+coderange.o: $(hdrdir)/ruby/internal/core/rstruct.h
+coderange.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+coderange.o: $(hdrdir)/ruby/internal/ctype.h
+coderange.o: $(hdrdir)/ruby/internal/dllexport.h
+coderange.o: $(hdrdir)/ruby/internal/dosish.h
+coderange.o: $(hdrdir)/ruby/internal/error.h
+coderange.o: $(hdrdir)/ruby/internal/eval.h
+coderange.o: $(hdrdir)/ruby/internal/event.h
+coderange.o: $(hdrdir)/ruby/internal/fl_type.h
+coderange.o: $(hdrdir)/ruby/internal/gc.h
+coderange.o: $(hdrdir)/ruby/internal/glob.h
+coderange.o: $(hdrdir)/ruby/internal/globals.h
+coderange.o: $(hdrdir)/ruby/internal/has/attribute.h
+coderange.o: $(hdrdir)/ruby/internal/has/builtin.h
+coderange.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+coderange.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+coderange.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+coderange.o: $(hdrdir)/ruby/internal/has/extension.h
+coderange.o: $(hdrdir)/ruby/internal/has/feature.h
+coderange.o: $(hdrdir)/ruby/internal/has/warning.h
+coderange.o: $(hdrdir)/ruby/internal/intern/array.h
+coderange.o: $(hdrdir)/ruby/internal/intern/bignum.h
+coderange.o: $(hdrdir)/ruby/internal/intern/class.h
+coderange.o: $(hdrdir)/ruby/internal/intern/compar.h
+coderange.o: $(hdrdir)/ruby/internal/intern/complex.h
+coderange.o: $(hdrdir)/ruby/internal/intern/cont.h
+coderange.o: $(hdrdir)/ruby/internal/intern/dir.h
+coderange.o: $(hdrdir)/ruby/internal/intern/enum.h
+coderange.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+coderange.o: $(hdrdir)/ruby/internal/intern/error.h
+coderange.o: $(hdrdir)/ruby/internal/intern/eval.h
+coderange.o: $(hdrdir)/ruby/internal/intern/file.h
+coderange.o: $(hdrdir)/ruby/internal/intern/gc.h
+coderange.o: $(hdrdir)/ruby/internal/intern/hash.h
+coderange.o: $(hdrdir)/ruby/internal/intern/io.h
+coderange.o: $(hdrdir)/ruby/internal/intern/load.h
+coderange.o: $(hdrdir)/ruby/internal/intern/marshal.h
+coderange.o: $(hdrdir)/ruby/internal/intern/numeric.h
+coderange.o: $(hdrdir)/ruby/internal/intern/object.h
+coderange.o: $(hdrdir)/ruby/internal/intern/parse.h
+coderange.o: $(hdrdir)/ruby/internal/intern/proc.h
+coderange.o: $(hdrdir)/ruby/internal/intern/process.h
+coderange.o: $(hdrdir)/ruby/internal/intern/random.h
+coderange.o: $(hdrdir)/ruby/internal/intern/range.h
+coderange.o: $(hdrdir)/ruby/internal/intern/rational.h
+coderange.o: $(hdrdir)/ruby/internal/intern/re.h
+coderange.o: $(hdrdir)/ruby/internal/intern/ruby.h
+coderange.o: $(hdrdir)/ruby/internal/intern/select.h
+coderange.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+coderange.o: $(hdrdir)/ruby/internal/intern/signal.h
+coderange.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+coderange.o: $(hdrdir)/ruby/internal/intern/string.h
+coderange.o: $(hdrdir)/ruby/internal/intern/struct.h
+coderange.o: $(hdrdir)/ruby/internal/intern/thread.h
+coderange.o: $(hdrdir)/ruby/internal/intern/time.h
+coderange.o: $(hdrdir)/ruby/internal/intern/variable.h
+coderange.o: $(hdrdir)/ruby/internal/intern/vm.h
+coderange.o: $(hdrdir)/ruby/internal/interpreter.h
+coderange.o: $(hdrdir)/ruby/internal/iterator.h
+coderange.o: $(hdrdir)/ruby/internal/memory.h
+coderange.o: $(hdrdir)/ruby/internal/method.h
+coderange.o: $(hdrdir)/ruby/internal/module.h
+coderange.o: $(hdrdir)/ruby/internal/newobj.h
+coderange.o: $(hdrdir)/ruby/internal/rgengc.h
+coderange.o: $(hdrdir)/ruby/internal/scan_args.h
+coderange.o: $(hdrdir)/ruby/internal/special_consts.h
+coderange.o: $(hdrdir)/ruby/internal/static_assert.h
+coderange.o: $(hdrdir)/ruby/internal/stdalign.h
+coderange.o: $(hdrdir)/ruby/internal/stdbool.h
+coderange.o: $(hdrdir)/ruby/internal/symbol.h
+coderange.o: $(hdrdir)/ruby/internal/token_paste.h
+coderange.o: $(hdrdir)/ruby/internal/value.h
+coderange.o: $(hdrdir)/ruby/internal/value_type.h
+coderange.o: $(hdrdir)/ruby/internal/variable.h
+coderange.o: $(hdrdir)/ruby/internal/warning_push.h
+coderange.o: $(hdrdir)/ruby/internal/xmalloc.h
coderange.o: $(hdrdir)/ruby/missing.h
coderange.o: $(hdrdir)/ruby/onigmo.h
coderange.o: $(hdrdir)/ruby/oniguruma.h
@@ -30,51 +331,653 @@ coderange.o: $(hdrdir)/ruby/subst.h
coderange.o: coderange.c
cstr.o: $(RUBY_EXTCONF_H)
cstr.o: $(arch_hdrdir)/ruby/config.h
+cstr.o: $(hdrdir)/ruby.h
+cstr.o: $(hdrdir)/ruby/assert.h
cstr.o: $(hdrdir)/ruby/backward.h
+cstr.o: $(hdrdir)/ruby/backward/2/assume.h
+cstr.o: $(hdrdir)/ruby/backward/2/attributes.h
+cstr.o: $(hdrdir)/ruby/backward/2/bool.h
+cstr.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+cstr.o: $(hdrdir)/ruby/backward/2/inttypes.h
+cstr.o: $(hdrdir)/ruby/backward/2/limits.h
+cstr.o: $(hdrdir)/ruby/backward/2/long_long.h
+cstr.o: $(hdrdir)/ruby/backward/2/stdalign.h
+cstr.o: $(hdrdir)/ruby/backward/2/stdarg.h
cstr.o: $(hdrdir)/ruby/defines.h
cstr.o: $(hdrdir)/ruby/encoding.h
cstr.o: $(hdrdir)/ruby/intern.h
-cstr.o: $(hdrdir)/ruby/io.h
+cstr.o: $(hdrdir)/ruby/internal/anyargs.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+cstr.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+cstr.o: $(hdrdir)/ruby/internal/assume.h
+cstr.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+cstr.o: $(hdrdir)/ruby/internal/attr/artificial.h
+cstr.o: $(hdrdir)/ruby/internal/attr/cold.h
+cstr.o: $(hdrdir)/ruby/internal/attr/const.h
+cstr.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+cstr.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+cstr.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+cstr.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+cstr.o: $(hdrdir)/ruby/internal/attr/error.h
+cstr.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+cstr.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+cstr.o: $(hdrdir)/ruby/internal/attr/format.h
+cstr.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+cstr.o: $(hdrdir)/ruby/internal/attr/noalias.h
+cstr.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+cstr.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+cstr.o: $(hdrdir)/ruby/internal/attr/noinline.h
+cstr.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+cstr.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+cstr.o: $(hdrdir)/ruby/internal/attr/pure.h
+cstr.o: $(hdrdir)/ruby/internal/attr/restrict.h
+cstr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+cstr.o: $(hdrdir)/ruby/internal/attr/warning.h
+cstr.o: $(hdrdir)/ruby/internal/attr/weakref.h
+cstr.o: $(hdrdir)/ruby/internal/cast.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_is.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+cstr.o: $(hdrdir)/ruby/internal/compiler_since.h
+cstr.o: $(hdrdir)/ruby/internal/config.h
+cstr.o: $(hdrdir)/ruby/internal/constant_p.h
+cstr.o: $(hdrdir)/ruby/internal/core.h
+cstr.o: $(hdrdir)/ruby/internal/core/rarray.h
+cstr.o: $(hdrdir)/ruby/internal/core/rbasic.h
+cstr.o: $(hdrdir)/ruby/internal/core/rbignum.h
+cstr.o: $(hdrdir)/ruby/internal/core/rclass.h
+cstr.o: $(hdrdir)/ruby/internal/core/rdata.h
+cstr.o: $(hdrdir)/ruby/internal/core/rfile.h
+cstr.o: $(hdrdir)/ruby/internal/core/rhash.h
+cstr.o: $(hdrdir)/ruby/internal/core/robject.h
+cstr.o: $(hdrdir)/ruby/internal/core/rregexp.h
+cstr.o: $(hdrdir)/ruby/internal/core/rstring.h
+cstr.o: $(hdrdir)/ruby/internal/core/rstruct.h
+cstr.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+cstr.o: $(hdrdir)/ruby/internal/ctype.h
+cstr.o: $(hdrdir)/ruby/internal/dllexport.h
+cstr.o: $(hdrdir)/ruby/internal/dosish.h
+cstr.o: $(hdrdir)/ruby/internal/error.h
+cstr.o: $(hdrdir)/ruby/internal/eval.h
+cstr.o: $(hdrdir)/ruby/internal/event.h
+cstr.o: $(hdrdir)/ruby/internal/fl_type.h
+cstr.o: $(hdrdir)/ruby/internal/gc.h
+cstr.o: $(hdrdir)/ruby/internal/glob.h
+cstr.o: $(hdrdir)/ruby/internal/globals.h
+cstr.o: $(hdrdir)/ruby/internal/has/attribute.h
+cstr.o: $(hdrdir)/ruby/internal/has/builtin.h
+cstr.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+cstr.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+cstr.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+cstr.o: $(hdrdir)/ruby/internal/has/extension.h
+cstr.o: $(hdrdir)/ruby/internal/has/feature.h
+cstr.o: $(hdrdir)/ruby/internal/has/warning.h
+cstr.o: $(hdrdir)/ruby/internal/intern/array.h
+cstr.o: $(hdrdir)/ruby/internal/intern/bignum.h
+cstr.o: $(hdrdir)/ruby/internal/intern/class.h
+cstr.o: $(hdrdir)/ruby/internal/intern/compar.h
+cstr.o: $(hdrdir)/ruby/internal/intern/complex.h
+cstr.o: $(hdrdir)/ruby/internal/intern/cont.h
+cstr.o: $(hdrdir)/ruby/internal/intern/dir.h
+cstr.o: $(hdrdir)/ruby/internal/intern/enum.h
+cstr.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+cstr.o: $(hdrdir)/ruby/internal/intern/error.h
+cstr.o: $(hdrdir)/ruby/internal/intern/eval.h
+cstr.o: $(hdrdir)/ruby/internal/intern/file.h
+cstr.o: $(hdrdir)/ruby/internal/intern/gc.h
+cstr.o: $(hdrdir)/ruby/internal/intern/hash.h
+cstr.o: $(hdrdir)/ruby/internal/intern/io.h
+cstr.o: $(hdrdir)/ruby/internal/intern/load.h
+cstr.o: $(hdrdir)/ruby/internal/intern/marshal.h
+cstr.o: $(hdrdir)/ruby/internal/intern/numeric.h
+cstr.o: $(hdrdir)/ruby/internal/intern/object.h
+cstr.o: $(hdrdir)/ruby/internal/intern/parse.h
+cstr.o: $(hdrdir)/ruby/internal/intern/proc.h
+cstr.o: $(hdrdir)/ruby/internal/intern/process.h
+cstr.o: $(hdrdir)/ruby/internal/intern/random.h
+cstr.o: $(hdrdir)/ruby/internal/intern/range.h
+cstr.o: $(hdrdir)/ruby/internal/intern/rational.h
+cstr.o: $(hdrdir)/ruby/internal/intern/re.h
+cstr.o: $(hdrdir)/ruby/internal/intern/ruby.h
+cstr.o: $(hdrdir)/ruby/internal/intern/select.h
+cstr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+cstr.o: $(hdrdir)/ruby/internal/intern/signal.h
+cstr.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+cstr.o: $(hdrdir)/ruby/internal/intern/string.h
+cstr.o: $(hdrdir)/ruby/internal/intern/struct.h
+cstr.o: $(hdrdir)/ruby/internal/intern/thread.h
+cstr.o: $(hdrdir)/ruby/internal/intern/time.h
+cstr.o: $(hdrdir)/ruby/internal/intern/variable.h
+cstr.o: $(hdrdir)/ruby/internal/intern/vm.h
+cstr.o: $(hdrdir)/ruby/internal/interpreter.h
+cstr.o: $(hdrdir)/ruby/internal/iterator.h
+cstr.o: $(hdrdir)/ruby/internal/memory.h
+cstr.o: $(hdrdir)/ruby/internal/method.h
+cstr.o: $(hdrdir)/ruby/internal/module.h
+cstr.o: $(hdrdir)/ruby/internal/newobj.h
+cstr.o: $(hdrdir)/ruby/internal/rgengc.h
+cstr.o: $(hdrdir)/ruby/internal/scan_args.h
+cstr.o: $(hdrdir)/ruby/internal/special_consts.h
+cstr.o: $(hdrdir)/ruby/internal/static_assert.h
+cstr.o: $(hdrdir)/ruby/internal/stdalign.h
+cstr.o: $(hdrdir)/ruby/internal/stdbool.h
+cstr.o: $(hdrdir)/ruby/internal/symbol.h
+cstr.o: $(hdrdir)/ruby/internal/token_paste.h
+cstr.o: $(hdrdir)/ruby/internal/value.h
+cstr.o: $(hdrdir)/ruby/internal/value_type.h
+cstr.o: $(hdrdir)/ruby/internal/variable.h
+cstr.o: $(hdrdir)/ruby/internal/warning_push.h
+cstr.o: $(hdrdir)/ruby/internal/xmalloc.h
cstr.o: $(hdrdir)/ruby/missing.h
cstr.o: $(hdrdir)/ruby/onigmo.h
cstr.o: $(hdrdir)/ruby/oniguruma.h
cstr.o: $(hdrdir)/ruby/ruby.h
cstr.o: $(hdrdir)/ruby/st.h
cstr.o: $(hdrdir)/ruby/subst.h
-cstr.o: $(top_srcdir)/include/ruby.h
cstr.o: $(top_srcdir)/internal.h
+cstr.o: $(top_srcdir)/internal/compilers.h
+cstr.o: $(top_srcdir)/internal/error.h
+cstr.o: $(top_srcdir)/internal/string.h
cstr.o: cstr.c
ellipsize.o: $(RUBY_EXTCONF_H)
ellipsize.o: $(arch_hdrdir)/ruby/config.h
+ellipsize.o: $(hdrdir)/ruby.h
+ellipsize.o: $(hdrdir)/ruby/assert.h
ellipsize.o: $(hdrdir)/ruby/backward.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/assume.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/attributes.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/bool.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/limits.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/long_long.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ellipsize.o: $(hdrdir)/ruby/backward/2/stdarg.h
ellipsize.o: $(hdrdir)/ruby/defines.h
ellipsize.o: $(hdrdir)/ruby/intern.h
+ellipsize.o: $(hdrdir)/ruby/internal/anyargs.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ellipsize.o: $(hdrdir)/ruby/internal/assume.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/cold.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/const.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/error.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/format.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/pure.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/warning.h
+ellipsize.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ellipsize.o: $(hdrdir)/ruby/internal/cast.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_is.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ellipsize.o: $(hdrdir)/ruby/internal/compiler_since.h
+ellipsize.o: $(hdrdir)/ruby/internal/config.h
+ellipsize.o: $(hdrdir)/ruby/internal/constant_p.h
+ellipsize.o: $(hdrdir)/ruby/internal/core.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rarray.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rclass.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rdata.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rfile.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rhash.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/robject.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rstring.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ellipsize.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ellipsize.o: $(hdrdir)/ruby/internal/ctype.h
+ellipsize.o: $(hdrdir)/ruby/internal/dllexport.h
+ellipsize.o: $(hdrdir)/ruby/internal/dosish.h
+ellipsize.o: $(hdrdir)/ruby/internal/error.h
+ellipsize.o: $(hdrdir)/ruby/internal/eval.h
+ellipsize.o: $(hdrdir)/ruby/internal/event.h
+ellipsize.o: $(hdrdir)/ruby/internal/fl_type.h
+ellipsize.o: $(hdrdir)/ruby/internal/gc.h
+ellipsize.o: $(hdrdir)/ruby/internal/glob.h
+ellipsize.o: $(hdrdir)/ruby/internal/globals.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/attribute.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/builtin.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/extension.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/feature.h
+ellipsize.o: $(hdrdir)/ruby/internal/has/warning.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/array.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/class.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/compar.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/complex.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/cont.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/dir.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/enum.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/error.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/eval.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/file.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/gc.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/hash.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/io.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/load.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/object.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/parse.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/proc.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/process.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/random.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/range.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/rational.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/re.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/select.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/signal.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/string.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/struct.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/thread.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/time.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/variable.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/vm.h
+ellipsize.o: $(hdrdir)/ruby/internal/interpreter.h
+ellipsize.o: $(hdrdir)/ruby/internal/iterator.h
+ellipsize.o: $(hdrdir)/ruby/internal/memory.h
+ellipsize.o: $(hdrdir)/ruby/internal/method.h
+ellipsize.o: $(hdrdir)/ruby/internal/module.h
+ellipsize.o: $(hdrdir)/ruby/internal/newobj.h
+ellipsize.o: $(hdrdir)/ruby/internal/rgengc.h
+ellipsize.o: $(hdrdir)/ruby/internal/scan_args.h
+ellipsize.o: $(hdrdir)/ruby/internal/special_consts.h
+ellipsize.o: $(hdrdir)/ruby/internal/static_assert.h
+ellipsize.o: $(hdrdir)/ruby/internal/stdalign.h
+ellipsize.o: $(hdrdir)/ruby/internal/stdbool.h
+ellipsize.o: $(hdrdir)/ruby/internal/symbol.h
+ellipsize.o: $(hdrdir)/ruby/internal/token_paste.h
+ellipsize.o: $(hdrdir)/ruby/internal/value.h
+ellipsize.o: $(hdrdir)/ruby/internal/value_type.h
+ellipsize.o: $(hdrdir)/ruby/internal/variable.h
+ellipsize.o: $(hdrdir)/ruby/internal/warning_push.h
+ellipsize.o: $(hdrdir)/ruby/internal/xmalloc.h
ellipsize.o: $(hdrdir)/ruby/missing.h
ellipsize.o: $(hdrdir)/ruby/ruby.h
ellipsize.o: $(hdrdir)/ruby/st.h
ellipsize.o: $(hdrdir)/ruby/subst.h
-ellipsize.o: $(top_srcdir)/include/ruby.h
ellipsize.o: ellipsize.c
enc_associate.o: $(RUBY_EXTCONF_H)
enc_associate.o: $(arch_hdrdir)/ruby/config.h
+enc_associate.o: $(hdrdir)/ruby.h
+enc_associate.o: $(hdrdir)/ruby/assert.h
enc_associate.o: $(hdrdir)/ruby/backward.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/assume.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/attributes.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/bool.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/inttypes.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/limits.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/long_long.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/stdalign.h
+enc_associate.o: $(hdrdir)/ruby/backward/2/stdarg.h
enc_associate.o: $(hdrdir)/ruby/defines.h
enc_associate.o: $(hdrdir)/ruby/encoding.h
enc_associate.o: $(hdrdir)/ruby/intern.h
+enc_associate.o: $(hdrdir)/ruby/internal/anyargs.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+enc_associate.o: $(hdrdir)/ruby/internal/assume.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/artificial.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/cold.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/const.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/error.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/format.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/noalias.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/noinline.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/pure.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/restrict.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/warning.h
+enc_associate.o: $(hdrdir)/ruby/internal/attr/weakref.h
+enc_associate.o: $(hdrdir)/ruby/internal/cast.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_is.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+enc_associate.o: $(hdrdir)/ruby/internal/compiler_since.h
+enc_associate.o: $(hdrdir)/ruby/internal/config.h
+enc_associate.o: $(hdrdir)/ruby/internal/constant_p.h
+enc_associate.o: $(hdrdir)/ruby/internal/core.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rarray.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rbasic.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rbignum.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rclass.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rdata.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rfile.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rhash.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/robject.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rregexp.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rstring.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rstruct.h
+enc_associate.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+enc_associate.o: $(hdrdir)/ruby/internal/ctype.h
+enc_associate.o: $(hdrdir)/ruby/internal/dllexport.h
+enc_associate.o: $(hdrdir)/ruby/internal/dosish.h
+enc_associate.o: $(hdrdir)/ruby/internal/error.h
+enc_associate.o: $(hdrdir)/ruby/internal/eval.h
+enc_associate.o: $(hdrdir)/ruby/internal/event.h
+enc_associate.o: $(hdrdir)/ruby/internal/fl_type.h
+enc_associate.o: $(hdrdir)/ruby/internal/gc.h
+enc_associate.o: $(hdrdir)/ruby/internal/glob.h
+enc_associate.o: $(hdrdir)/ruby/internal/globals.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/attribute.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/builtin.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/extension.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/feature.h
+enc_associate.o: $(hdrdir)/ruby/internal/has/warning.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/array.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/bignum.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/class.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/compar.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/complex.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/cont.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/dir.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/enum.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/error.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/eval.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/file.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/gc.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/hash.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/io.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/load.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/marshal.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/numeric.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/object.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/parse.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/proc.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/process.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/random.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/range.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/rational.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/re.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/ruby.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/select.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/signal.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/string.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/struct.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/thread.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/time.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/variable.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/vm.h
+enc_associate.o: $(hdrdir)/ruby/internal/interpreter.h
+enc_associate.o: $(hdrdir)/ruby/internal/iterator.h
+enc_associate.o: $(hdrdir)/ruby/internal/memory.h
+enc_associate.o: $(hdrdir)/ruby/internal/method.h
+enc_associate.o: $(hdrdir)/ruby/internal/module.h
+enc_associate.o: $(hdrdir)/ruby/internal/newobj.h
+enc_associate.o: $(hdrdir)/ruby/internal/rgengc.h
+enc_associate.o: $(hdrdir)/ruby/internal/scan_args.h
+enc_associate.o: $(hdrdir)/ruby/internal/special_consts.h
+enc_associate.o: $(hdrdir)/ruby/internal/static_assert.h
+enc_associate.o: $(hdrdir)/ruby/internal/stdalign.h
+enc_associate.o: $(hdrdir)/ruby/internal/stdbool.h
+enc_associate.o: $(hdrdir)/ruby/internal/symbol.h
+enc_associate.o: $(hdrdir)/ruby/internal/token_paste.h
+enc_associate.o: $(hdrdir)/ruby/internal/value.h
+enc_associate.o: $(hdrdir)/ruby/internal/value_type.h
+enc_associate.o: $(hdrdir)/ruby/internal/variable.h
+enc_associate.o: $(hdrdir)/ruby/internal/warning_push.h
+enc_associate.o: $(hdrdir)/ruby/internal/xmalloc.h
enc_associate.o: $(hdrdir)/ruby/missing.h
enc_associate.o: $(hdrdir)/ruby/onigmo.h
enc_associate.o: $(hdrdir)/ruby/oniguruma.h
enc_associate.o: $(hdrdir)/ruby/ruby.h
enc_associate.o: $(hdrdir)/ruby/st.h
enc_associate.o: $(hdrdir)/ruby/subst.h
-enc_associate.o: $(top_srcdir)/include/ruby.h
enc_associate.o: enc_associate.c
enc_str_buf_cat.o: $(RUBY_EXTCONF_H)
enc_str_buf_cat.o: $(arch_hdrdir)/ruby/config.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/assert.h
enc_str_buf_cat.o: $(hdrdir)/ruby/backward.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/assume.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/attributes.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/bool.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/inttypes.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/limits.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/long_long.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/stdalign.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/stdarg.h
enc_str_buf_cat.o: $(hdrdir)/ruby/defines.h
enc_str_buf_cat.o: $(hdrdir)/ruby/encoding.h
enc_str_buf_cat.o: $(hdrdir)/ruby/intern.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/anyargs.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/assume.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/artificial.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/cold.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/const.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/error.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/format.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noalias.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noinline.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/pure.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/restrict.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/warning.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/weakref.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/cast.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_is.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/compiler_since.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/config.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/constant_p.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rarray.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rbasic.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rbignum.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rclass.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rdata.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rfile.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rhash.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/robject.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rregexp.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rstring.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rstruct.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/ctype.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/dllexport.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/dosish.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/error.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/eval.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/event.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/fl_type.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/gc.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/glob.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/globals.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/attribute.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/builtin.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/extension.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/feature.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/has/warning.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/array.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/bignum.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/class.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/compar.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/complex.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/cont.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/dir.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/enum.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/error.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/eval.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/file.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/gc.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/hash.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/io.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/load.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/marshal.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/numeric.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/object.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/parse.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/proc.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/process.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/random.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/range.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/rational.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/re.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/ruby.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/select.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/signal.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/string.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/struct.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/thread.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/time.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/variable.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/vm.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/interpreter.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/iterator.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/memory.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/method.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/module.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/newobj.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/rgengc.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/scan_args.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/special_consts.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/static_assert.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/stdalign.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/stdbool.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/symbol.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/token_paste.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/value.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/value_type.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/variable.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/warning_push.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/xmalloc.h
enc_str_buf_cat.o: $(hdrdir)/ruby/missing.h
enc_str_buf_cat.o: $(hdrdir)/ruby/onigmo.h
enc_str_buf_cat.o: $(hdrdir)/ruby/oniguruma.h
@@ -84,70 +987,1138 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/subst.h
enc_str_buf_cat.o: enc_str_buf_cat.c
fstring.o: $(RUBY_EXTCONF_H)
fstring.o: $(arch_hdrdir)/ruby/config.h
+fstring.o: $(hdrdir)/ruby.h
+fstring.o: $(hdrdir)/ruby/assert.h
fstring.o: $(hdrdir)/ruby/backward.h
+fstring.o: $(hdrdir)/ruby/backward/2/assume.h
+fstring.o: $(hdrdir)/ruby/backward/2/attributes.h
+fstring.o: $(hdrdir)/ruby/backward/2/bool.h
+fstring.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+fstring.o: $(hdrdir)/ruby/backward/2/inttypes.h
+fstring.o: $(hdrdir)/ruby/backward/2/limits.h
+fstring.o: $(hdrdir)/ruby/backward/2/long_long.h
+fstring.o: $(hdrdir)/ruby/backward/2/stdalign.h
+fstring.o: $(hdrdir)/ruby/backward/2/stdarg.h
fstring.o: $(hdrdir)/ruby/defines.h
+fstring.o: $(hdrdir)/ruby/encoding.h
fstring.o: $(hdrdir)/ruby/intern.h
+fstring.o: $(hdrdir)/ruby/internal/anyargs.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+fstring.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+fstring.o: $(hdrdir)/ruby/internal/assume.h
+fstring.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+fstring.o: $(hdrdir)/ruby/internal/attr/artificial.h
+fstring.o: $(hdrdir)/ruby/internal/attr/cold.h
+fstring.o: $(hdrdir)/ruby/internal/attr/const.h
+fstring.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+fstring.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+fstring.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+fstring.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+fstring.o: $(hdrdir)/ruby/internal/attr/error.h
+fstring.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+fstring.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+fstring.o: $(hdrdir)/ruby/internal/attr/format.h
+fstring.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+fstring.o: $(hdrdir)/ruby/internal/attr/noalias.h
+fstring.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+fstring.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+fstring.o: $(hdrdir)/ruby/internal/attr/noinline.h
+fstring.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+fstring.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+fstring.o: $(hdrdir)/ruby/internal/attr/pure.h
+fstring.o: $(hdrdir)/ruby/internal/attr/restrict.h
+fstring.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+fstring.o: $(hdrdir)/ruby/internal/attr/warning.h
+fstring.o: $(hdrdir)/ruby/internal/attr/weakref.h
+fstring.o: $(hdrdir)/ruby/internal/cast.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_is.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+fstring.o: $(hdrdir)/ruby/internal/compiler_since.h
+fstring.o: $(hdrdir)/ruby/internal/config.h
+fstring.o: $(hdrdir)/ruby/internal/constant_p.h
+fstring.o: $(hdrdir)/ruby/internal/core.h
+fstring.o: $(hdrdir)/ruby/internal/core/rarray.h
+fstring.o: $(hdrdir)/ruby/internal/core/rbasic.h
+fstring.o: $(hdrdir)/ruby/internal/core/rbignum.h
+fstring.o: $(hdrdir)/ruby/internal/core/rclass.h
+fstring.o: $(hdrdir)/ruby/internal/core/rdata.h
+fstring.o: $(hdrdir)/ruby/internal/core/rfile.h
+fstring.o: $(hdrdir)/ruby/internal/core/rhash.h
+fstring.o: $(hdrdir)/ruby/internal/core/robject.h
+fstring.o: $(hdrdir)/ruby/internal/core/rregexp.h
+fstring.o: $(hdrdir)/ruby/internal/core/rstring.h
+fstring.o: $(hdrdir)/ruby/internal/core/rstruct.h
+fstring.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+fstring.o: $(hdrdir)/ruby/internal/ctype.h
+fstring.o: $(hdrdir)/ruby/internal/dllexport.h
+fstring.o: $(hdrdir)/ruby/internal/dosish.h
+fstring.o: $(hdrdir)/ruby/internal/error.h
+fstring.o: $(hdrdir)/ruby/internal/eval.h
+fstring.o: $(hdrdir)/ruby/internal/event.h
+fstring.o: $(hdrdir)/ruby/internal/fl_type.h
+fstring.o: $(hdrdir)/ruby/internal/gc.h
+fstring.o: $(hdrdir)/ruby/internal/glob.h
+fstring.o: $(hdrdir)/ruby/internal/globals.h
+fstring.o: $(hdrdir)/ruby/internal/has/attribute.h
+fstring.o: $(hdrdir)/ruby/internal/has/builtin.h
+fstring.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+fstring.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+fstring.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+fstring.o: $(hdrdir)/ruby/internal/has/extension.h
+fstring.o: $(hdrdir)/ruby/internal/has/feature.h
+fstring.o: $(hdrdir)/ruby/internal/has/warning.h
+fstring.o: $(hdrdir)/ruby/internal/intern/array.h
+fstring.o: $(hdrdir)/ruby/internal/intern/bignum.h
+fstring.o: $(hdrdir)/ruby/internal/intern/class.h
+fstring.o: $(hdrdir)/ruby/internal/intern/compar.h
+fstring.o: $(hdrdir)/ruby/internal/intern/complex.h
+fstring.o: $(hdrdir)/ruby/internal/intern/cont.h
+fstring.o: $(hdrdir)/ruby/internal/intern/dir.h
+fstring.o: $(hdrdir)/ruby/internal/intern/enum.h
+fstring.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+fstring.o: $(hdrdir)/ruby/internal/intern/error.h
+fstring.o: $(hdrdir)/ruby/internal/intern/eval.h
+fstring.o: $(hdrdir)/ruby/internal/intern/file.h
+fstring.o: $(hdrdir)/ruby/internal/intern/gc.h
+fstring.o: $(hdrdir)/ruby/internal/intern/hash.h
+fstring.o: $(hdrdir)/ruby/internal/intern/io.h
+fstring.o: $(hdrdir)/ruby/internal/intern/load.h
+fstring.o: $(hdrdir)/ruby/internal/intern/marshal.h
+fstring.o: $(hdrdir)/ruby/internal/intern/numeric.h
+fstring.o: $(hdrdir)/ruby/internal/intern/object.h
+fstring.o: $(hdrdir)/ruby/internal/intern/parse.h
+fstring.o: $(hdrdir)/ruby/internal/intern/proc.h
+fstring.o: $(hdrdir)/ruby/internal/intern/process.h
+fstring.o: $(hdrdir)/ruby/internal/intern/random.h
+fstring.o: $(hdrdir)/ruby/internal/intern/range.h
+fstring.o: $(hdrdir)/ruby/internal/intern/rational.h
+fstring.o: $(hdrdir)/ruby/internal/intern/re.h
+fstring.o: $(hdrdir)/ruby/internal/intern/ruby.h
+fstring.o: $(hdrdir)/ruby/internal/intern/select.h
+fstring.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+fstring.o: $(hdrdir)/ruby/internal/intern/signal.h
+fstring.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+fstring.o: $(hdrdir)/ruby/internal/intern/string.h
+fstring.o: $(hdrdir)/ruby/internal/intern/struct.h
+fstring.o: $(hdrdir)/ruby/internal/intern/thread.h
+fstring.o: $(hdrdir)/ruby/internal/intern/time.h
+fstring.o: $(hdrdir)/ruby/internal/intern/variable.h
+fstring.o: $(hdrdir)/ruby/internal/intern/vm.h
+fstring.o: $(hdrdir)/ruby/internal/interpreter.h
+fstring.o: $(hdrdir)/ruby/internal/iterator.h
+fstring.o: $(hdrdir)/ruby/internal/memory.h
+fstring.o: $(hdrdir)/ruby/internal/method.h
+fstring.o: $(hdrdir)/ruby/internal/module.h
+fstring.o: $(hdrdir)/ruby/internal/newobj.h
+fstring.o: $(hdrdir)/ruby/internal/rgengc.h
+fstring.o: $(hdrdir)/ruby/internal/scan_args.h
+fstring.o: $(hdrdir)/ruby/internal/special_consts.h
+fstring.o: $(hdrdir)/ruby/internal/static_assert.h
+fstring.o: $(hdrdir)/ruby/internal/stdalign.h
+fstring.o: $(hdrdir)/ruby/internal/stdbool.h
+fstring.o: $(hdrdir)/ruby/internal/symbol.h
+fstring.o: $(hdrdir)/ruby/internal/token_paste.h
+fstring.o: $(hdrdir)/ruby/internal/value.h
+fstring.o: $(hdrdir)/ruby/internal/value_type.h
+fstring.o: $(hdrdir)/ruby/internal/variable.h
+fstring.o: $(hdrdir)/ruby/internal/warning_push.h
+fstring.o: $(hdrdir)/ruby/internal/xmalloc.h
fstring.o: $(hdrdir)/ruby/missing.h
+fstring.o: $(hdrdir)/ruby/onigmo.h
+fstring.o: $(hdrdir)/ruby/oniguruma.h
fstring.o: $(hdrdir)/ruby/ruby.h
fstring.o: $(hdrdir)/ruby/st.h
fstring.o: $(hdrdir)/ruby/subst.h
-fstring.o: $(top_srcdir)/include/ruby.h
fstring.o: fstring.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
modify.o: $(RUBY_EXTCONF_H)
modify.o: $(arch_hdrdir)/ruby/config.h
+modify.o: $(hdrdir)/ruby.h
+modify.o: $(hdrdir)/ruby/assert.h
modify.o: $(hdrdir)/ruby/backward.h
+modify.o: $(hdrdir)/ruby/backward/2/assume.h
+modify.o: $(hdrdir)/ruby/backward/2/attributes.h
+modify.o: $(hdrdir)/ruby/backward/2/bool.h
+modify.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+modify.o: $(hdrdir)/ruby/backward/2/inttypes.h
+modify.o: $(hdrdir)/ruby/backward/2/limits.h
+modify.o: $(hdrdir)/ruby/backward/2/long_long.h
+modify.o: $(hdrdir)/ruby/backward/2/stdalign.h
+modify.o: $(hdrdir)/ruby/backward/2/stdarg.h
modify.o: $(hdrdir)/ruby/defines.h
modify.o: $(hdrdir)/ruby/intern.h
+modify.o: $(hdrdir)/ruby/internal/anyargs.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+modify.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+modify.o: $(hdrdir)/ruby/internal/assume.h
+modify.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+modify.o: $(hdrdir)/ruby/internal/attr/artificial.h
+modify.o: $(hdrdir)/ruby/internal/attr/cold.h
+modify.o: $(hdrdir)/ruby/internal/attr/const.h
+modify.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+modify.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+modify.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+modify.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+modify.o: $(hdrdir)/ruby/internal/attr/error.h
+modify.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+modify.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+modify.o: $(hdrdir)/ruby/internal/attr/format.h
+modify.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+modify.o: $(hdrdir)/ruby/internal/attr/noalias.h
+modify.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+modify.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+modify.o: $(hdrdir)/ruby/internal/attr/noinline.h
+modify.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+modify.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+modify.o: $(hdrdir)/ruby/internal/attr/pure.h
+modify.o: $(hdrdir)/ruby/internal/attr/restrict.h
+modify.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+modify.o: $(hdrdir)/ruby/internal/attr/warning.h
+modify.o: $(hdrdir)/ruby/internal/attr/weakref.h
+modify.o: $(hdrdir)/ruby/internal/cast.h
+modify.o: $(hdrdir)/ruby/internal/compiler_is.h
+modify.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+modify.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+modify.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+modify.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+modify.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+modify.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+modify.o: $(hdrdir)/ruby/internal/compiler_since.h
+modify.o: $(hdrdir)/ruby/internal/config.h
+modify.o: $(hdrdir)/ruby/internal/constant_p.h
+modify.o: $(hdrdir)/ruby/internal/core.h
+modify.o: $(hdrdir)/ruby/internal/core/rarray.h
+modify.o: $(hdrdir)/ruby/internal/core/rbasic.h
+modify.o: $(hdrdir)/ruby/internal/core/rbignum.h
+modify.o: $(hdrdir)/ruby/internal/core/rclass.h
+modify.o: $(hdrdir)/ruby/internal/core/rdata.h
+modify.o: $(hdrdir)/ruby/internal/core/rfile.h
+modify.o: $(hdrdir)/ruby/internal/core/rhash.h
+modify.o: $(hdrdir)/ruby/internal/core/robject.h
+modify.o: $(hdrdir)/ruby/internal/core/rregexp.h
+modify.o: $(hdrdir)/ruby/internal/core/rstring.h
+modify.o: $(hdrdir)/ruby/internal/core/rstruct.h
+modify.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+modify.o: $(hdrdir)/ruby/internal/ctype.h
+modify.o: $(hdrdir)/ruby/internal/dllexport.h
+modify.o: $(hdrdir)/ruby/internal/dosish.h
+modify.o: $(hdrdir)/ruby/internal/error.h
+modify.o: $(hdrdir)/ruby/internal/eval.h
+modify.o: $(hdrdir)/ruby/internal/event.h
+modify.o: $(hdrdir)/ruby/internal/fl_type.h
+modify.o: $(hdrdir)/ruby/internal/gc.h
+modify.o: $(hdrdir)/ruby/internal/glob.h
+modify.o: $(hdrdir)/ruby/internal/globals.h
+modify.o: $(hdrdir)/ruby/internal/has/attribute.h
+modify.o: $(hdrdir)/ruby/internal/has/builtin.h
+modify.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+modify.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+modify.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+modify.o: $(hdrdir)/ruby/internal/has/extension.h
+modify.o: $(hdrdir)/ruby/internal/has/feature.h
+modify.o: $(hdrdir)/ruby/internal/has/warning.h
+modify.o: $(hdrdir)/ruby/internal/intern/array.h
+modify.o: $(hdrdir)/ruby/internal/intern/bignum.h
+modify.o: $(hdrdir)/ruby/internal/intern/class.h
+modify.o: $(hdrdir)/ruby/internal/intern/compar.h
+modify.o: $(hdrdir)/ruby/internal/intern/complex.h
+modify.o: $(hdrdir)/ruby/internal/intern/cont.h
+modify.o: $(hdrdir)/ruby/internal/intern/dir.h
+modify.o: $(hdrdir)/ruby/internal/intern/enum.h
+modify.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+modify.o: $(hdrdir)/ruby/internal/intern/error.h
+modify.o: $(hdrdir)/ruby/internal/intern/eval.h
+modify.o: $(hdrdir)/ruby/internal/intern/file.h
+modify.o: $(hdrdir)/ruby/internal/intern/gc.h
+modify.o: $(hdrdir)/ruby/internal/intern/hash.h
+modify.o: $(hdrdir)/ruby/internal/intern/io.h
+modify.o: $(hdrdir)/ruby/internal/intern/load.h
+modify.o: $(hdrdir)/ruby/internal/intern/marshal.h
+modify.o: $(hdrdir)/ruby/internal/intern/numeric.h
+modify.o: $(hdrdir)/ruby/internal/intern/object.h
+modify.o: $(hdrdir)/ruby/internal/intern/parse.h
+modify.o: $(hdrdir)/ruby/internal/intern/proc.h
+modify.o: $(hdrdir)/ruby/internal/intern/process.h
+modify.o: $(hdrdir)/ruby/internal/intern/random.h
+modify.o: $(hdrdir)/ruby/internal/intern/range.h
+modify.o: $(hdrdir)/ruby/internal/intern/rational.h
+modify.o: $(hdrdir)/ruby/internal/intern/re.h
+modify.o: $(hdrdir)/ruby/internal/intern/ruby.h
+modify.o: $(hdrdir)/ruby/internal/intern/select.h
+modify.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+modify.o: $(hdrdir)/ruby/internal/intern/signal.h
+modify.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+modify.o: $(hdrdir)/ruby/internal/intern/string.h
+modify.o: $(hdrdir)/ruby/internal/intern/struct.h
+modify.o: $(hdrdir)/ruby/internal/intern/thread.h
+modify.o: $(hdrdir)/ruby/internal/intern/time.h
+modify.o: $(hdrdir)/ruby/internal/intern/variable.h
+modify.o: $(hdrdir)/ruby/internal/intern/vm.h
+modify.o: $(hdrdir)/ruby/internal/interpreter.h
+modify.o: $(hdrdir)/ruby/internal/iterator.h
+modify.o: $(hdrdir)/ruby/internal/memory.h
+modify.o: $(hdrdir)/ruby/internal/method.h
+modify.o: $(hdrdir)/ruby/internal/module.h
+modify.o: $(hdrdir)/ruby/internal/newobj.h
+modify.o: $(hdrdir)/ruby/internal/rgengc.h
+modify.o: $(hdrdir)/ruby/internal/scan_args.h
+modify.o: $(hdrdir)/ruby/internal/special_consts.h
+modify.o: $(hdrdir)/ruby/internal/static_assert.h
+modify.o: $(hdrdir)/ruby/internal/stdalign.h
+modify.o: $(hdrdir)/ruby/internal/stdbool.h
+modify.o: $(hdrdir)/ruby/internal/symbol.h
+modify.o: $(hdrdir)/ruby/internal/token_paste.h
+modify.o: $(hdrdir)/ruby/internal/value.h
+modify.o: $(hdrdir)/ruby/internal/value_type.h
+modify.o: $(hdrdir)/ruby/internal/variable.h
+modify.o: $(hdrdir)/ruby/internal/warning_push.h
+modify.o: $(hdrdir)/ruby/internal/xmalloc.h
modify.o: $(hdrdir)/ruby/missing.h
modify.o: $(hdrdir)/ruby/ruby.h
modify.o: $(hdrdir)/ruby/st.h
modify.o: $(hdrdir)/ruby/subst.h
-modify.o: $(top_srcdir)/include/ruby.h
modify.o: modify.c
+new.o: $(RUBY_EXTCONF_H)
+new.o: $(arch_hdrdir)/ruby/config.h
+new.o: $(hdrdir)/ruby.h
+new.o: $(hdrdir)/ruby/assert.h
+new.o: $(hdrdir)/ruby/backward.h
+new.o: $(hdrdir)/ruby/backward/2/assume.h
+new.o: $(hdrdir)/ruby/backward/2/attributes.h
+new.o: $(hdrdir)/ruby/backward/2/bool.h
+new.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+new.o: $(hdrdir)/ruby/backward/2/inttypes.h
+new.o: $(hdrdir)/ruby/backward/2/limits.h
+new.o: $(hdrdir)/ruby/backward/2/long_long.h
+new.o: $(hdrdir)/ruby/backward/2/stdalign.h
+new.o: $(hdrdir)/ruby/backward/2/stdarg.h
+new.o: $(hdrdir)/ruby/defines.h
+new.o: $(hdrdir)/ruby/encoding.h
+new.o: $(hdrdir)/ruby/intern.h
+new.o: $(hdrdir)/ruby/internal/anyargs.h
+new.o: $(hdrdir)/ruby/internal/arithmetic.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+new.o: $(hdrdir)/ruby/internal/assume.h
+new.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+new.o: $(hdrdir)/ruby/internal/attr/artificial.h
+new.o: $(hdrdir)/ruby/internal/attr/cold.h
+new.o: $(hdrdir)/ruby/internal/attr/const.h
+new.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+new.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+new.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+new.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+new.o: $(hdrdir)/ruby/internal/attr/error.h
+new.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+new.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+new.o: $(hdrdir)/ruby/internal/attr/format.h
+new.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+new.o: $(hdrdir)/ruby/internal/attr/noalias.h
+new.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+new.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+new.o: $(hdrdir)/ruby/internal/attr/noinline.h
+new.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+new.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+new.o: $(hdrdir)/ruby/internal/attr/pure.h
+new.o: $(hdrdir)/ruby/internal/attr/restrict.h
+new.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+new.o: $(hdrdir)/ruby/internal/attr/warning.h
+new.o: $(hdrdir)/ruby/internal/attr/weakref.h
+new.o: $(hdrdir)/ruby/internal/cast.h
+new.o: $(hdrdir)/ruby/internal/compiler_is.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+new.o: $(hdrdir)/ruby/internal/compiler_since.h
+new.o: $(hdrdir)/ruby/internal/config.h
+new.o: $(hdrdir)/ruby/internal/constant_p.h
+new.o: $(hdrdir)/ruby/internal/core.h
+new.o: $(hdrdir)/ruby/internal/core/rarray.h
+new.o: $(hdrdir)/ruby/internal/core/rbasic.h
+new.o: $(hdrdir)/ruby/internal/core/rbignum.h
+new.o: $(hdrdir)/ruby/internal/core/rclass.h
+new.o: $(hdrdir)/ruby/internal/core/rdata.h
+new.o: $(hdrdir)/ruby/internal/core/rfile.h
+new.o: $(hdrdir)/ruby/internal/core/rhash.h
+new.o: $(hdrdir)/ruby/internal/core/robject.h
+new.o: $(hdrdir)/ruby/internal/core/rregexp.h
+new.o: $(hdrdir)/ruby/internal/core/rstring.h
+new.o: $(hdrdir)/ruby/internal/core/rstruct.h
+new.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+new.o: $(hdrdir)/ruby/internal/ctype.h
+new.o: $(hdrdir)/ruby/internal/dllexport.h
+new.o: $(hdrdir)/ruby/internal/dosish.h
+new.o: $(hdrdir)/ruby/internal/error.h
+new.o: $(hdrdir)/ruby/internal/eval.h
+new.o: $(hdrdir)/ruby/internal/event.h
+new.o: $(hdrdir)/ruby/internal/fl_type.h
+new.o: $(hdrdir)/ruby/internal/gc.h
+new.o: $(hdrdir)/ruby/internal/glob.h
+new.o: $(hdrdir)/ruby/internal/globals.h
+new.o: $(hdrdir)/ruby/internal/has/attribute.h
+new.o: $(hdrdir)/ruby/internal/has/builtin.h
+new.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+new.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+new.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+new.o: $(hdrdir)/ruby/internal/has/extension.h
+new.o: $(hdrdir)/ruby/internal/has/feature.h
+new.o: $(hdrdir)/ruby/internal/has/warning.h
+new.o: $(hdrdir)/ruby/internal/intern/array.h
+new.o: $(hdrdir)/ruby/internal/intern/bignum.h
+new.o: $(hdrdir)/ruby/internal/intern/class.h
+new.o: $(hdrdir)/ruby/internal/intern/compar.h
+new.o: $(hdrdir)/ruby/internal/intern/complex.h
+new.o: $(hdrdir)/ruby/internal/intern/cont.h
+new.o: $(hdrdir)/ruby/internal/intern/dir.h
+new.o: $(hdrdir)/ruby/internal/intern/enum.h
+new.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+new.o: $(hdrdir)/ruby/internal/intern/error.h
+new.o: $(hdrdir)/ruby/internal/intern/eval.h
+new.o: $(hdrdir)/ruby/internal/intern/file.h
+new.o: $(hdrdir)/ruby/internal/intern/gc.h
+new.o: $(hdrdir)/ruby/internal/intern/hash.h
+new.o: $(hdrdir)/ruby/internal/intern/io.h
+new.o: $(hdrdir)/ruby/internal/intern/load.h
+new.o: $(hdrdir)/ruby/internal/intern/marshal.h
+new.o: $(hdrdir)/ruby/internal/intern/numeric.h
+new.o: $(hdrdir)/ruby/internal/intern/object.h
+new.o: $(hdrdir)/ruby/internal/intern/parse.h
+new.o: $(hdrdir)/ruby/internal/intern/proc.h
+new.o: $(hdrdir)/ruby/internal/intern/process.h
+new.o: $(hdrdir)/ruby/internal/intern/random.h
+new.o: $(hdrdir)/ruby/internal/intern/range.h
+new.o: $(hdrdir)/ruby/internal/intern/rational.h
+new.o: $(hdrdir)/ruby/internal/intern/re.h
+new.o: $(hdrdir)/ruby/internal/intern/ruby.h
+new.o: $(hdrdir)/ruby/internal/intern/select.h
+new.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+new.o: $(hdrdir)/ruby/internal/intern/signal.h
+new.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+new.o: $(hdrdir)/ruby/internal/intern/string.h
+new.o: $(hdrdir)/ruby/internal/intern/struct.h
+new.o: $(hdrdir)/ruby/internal/intern/thread.h
+new.o: $(hdrdir)/ruby/internal/intern/time.h
+new.o: $(hdrdir)/ruby/internal/intern/variable.h
+new.o: $(hdrdir)/ruby/internal/intern/vm.h
+new.o: $(hdrdir)/ruby/internal/interpreter.h
+new.o: $(hdrdir)/ruby/internal/iterator.h
+new.o: $(hdrdir)/ruby/internal/memory.h
+new.o: $(hdrdir)/ruby/internal/method.h
+new.o: $(hdrdir)/ruby/internal/module.h
+new.o: $(hdrdir)/ruby/internal/newobj.h
+new.o: $(hdrdir)/ruby/internal/rgengc.h
+new.o: $(hdrdir)/ruby/internal/scan_args.h
+new.o: $(hdrdir)/ruby/internal/special_consts.h
+new.o: $(hdrdir)/ruby/internal/static_assert.h
+new.o: $(hdrdir)/ruby/internal/stdalign.h
+new.o: $(hdrdir)/ruby/internal/stdbool.h
+new.o: $(hdrdir)/ruby/internal/symbol.h
+new.o: $(hdrdir)/ruby/internal/token_paste.h
+new.o: $(hdrdir)/ruby/internal/value.h
+new.o: $(hdrdir)/ruby/internal/value_type.h
+new.o: $(hdrdir)/ruby/internal/variable.h
+new.o: $(hdrdir)/ruby/internal/warning_push.h
+new.o: $(hdrdir)/ruby/internal/xmalloc.h
+new.o: $(hdrdir)/ruby/missing.h
+new.o: $(hdrdir)/ruby/onigmo.h
+new.o: $(hdrdir)/ruby/oniguruma.h
+new.o: $(hdrdir)/ruby/ruby.h
+new.o: $(hdrdir)/ruby/st.h
+new.o: $(hdrdir)/ruby/subst.h
+new.o: new.c
nofree.o: $(RUBY_EXTCONF_H)
nofree.o: $(arch_hdrdir)/ruby/config.h
+nofree.o: $(hdrdir)/ruby.h
+nofree.o: $(hdrdir)/ruby/assert.h
nofree.o: $(hdrdir)/ruby/backward.h
+nofree.o: $(hdrdir)/ruby/backward/2/assume.h
+nofree.o: $(hdrdir)/ruby/backward/2/attributes.h
+nofree.o: $(hdrdir)/ruby/backward/2/bool.h
+nofree.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+nofree.o: $(hdrdir)/ruby/backward/2/inttypes.h
+nofree.o: $(hdrdir)/ruby/backward/2/limits.h
+nofree.o: $(hdrdir)/ruby/backward/2/long_long.h
+nofree.o: $(hdrdir)/ruby/backward/2/stdalign.h
+nofree.o: $(hdrdir)/ruby/backward/2/stdarg.h
nofree.o: $(hdrdir)/ruby/defines.h
nofree.o: $(hdrdir)/ruby/intern.h
+nofree.o: $(hdrdir)/ruby/internal/anyargs.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+nofree.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+nofree.o: $(hdrdir)/ruby/internal/assume.h
+nofree.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+nofree.o: $(hdrdir)/ruby/internal/attr/artificial.h
+nofree.o: $(hdrdir)/ruby/internal/attr/cold.h
+nofree.o: $(hdrdir)/ruby/internal/attr/const.h
+nofree.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+nofree.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+nofree.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+nofree.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+nofree.o: $(hdrdir)/ruby/internal/attr/error.h
+nofree.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+nofree.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+nofree.o: $(hdrdir)/ruby/internal/attr/format.h
+nofree.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+nofree.o: $(hdrdir)/ruby/internal/attr/noalias.h
+nofree.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+nofree.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+nofree.o: $(hdrdir)/ruby/internal/attr/noinline.h
+nofree.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+nofree.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+nofree.o: $(hdrdir)/ruby/internal/attr/pure.h
+nofree.o: $(hdrdir)/ruby/internal/attr/restrict.h
+nofree.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+nofree.o: $(hdrdir)/ruby/internal/attr/warning.h
+nofree.o: $(hdrdir)/ruby/internal/attr/weakref.h
+nofree.o: $(hdrdir)/ruby/internal/cast.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_is.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+nofree.o: $(hdrdir)/ruby/internal/compiler_since.h
+nofree.o: $(hdrdir)/ruby/internal/config.h
+nofree.o: $(hdrdir)/ruby/internal/constant_p.h
+nofree.o: $(hdrdir)/ruby/internal/core.h
+nofree.o: $(hdrdir)/ruby/internal/core/rarray.h
+nofree.o: $(hdrdir)/ruby/internal/core/rbasic.h
+nofree.o: $(hdrdir)/ruby/internal/core/rbignum.h
+nofree.o: $(hdrdir)/ruby/internal/core/rclass.h
+nofree.o: $(hdrdir)/ruby/internal/core/rdata.h
+nofree.o: $(hdrdir)/ruby/internal/core/rfile.h
+nofree.o: $(hdrdir)/ruby/internal/core/rhash.h
+nofree.o: $(hdrdir)/ruby/internal/core/robject.h
+nofree.o: $(hdrdir)/ruby/internal/core/rregexp.h
+nofree.o: $(hdrdir)/ruby/internal/core/rstring.h
+nofree.o: $(hdrdir)/ruby/internal/core/rstruct.h
+nofree.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+nofree.o: $(hdrdir)/ruby/internal/ctype.h
+nofree.o: $(hdrdir)/ruby/internal/dllexport.h
+nofree.o: $(hdrdir)/ruby/internal/dosish.h
+nofree.o: $(hdrdir)/ruby/internal/error.h
+nofree.o: $(hdrdir)/ruby/internal/eval.h
+nofree.o: $(hdrdir)/ruby/internal/event.h
+nofree.o: $(hdrdir)/ruby/internal/fl_type.h
+nofree.o: $(hdrdir)/ruby/internal/gc.h
+nofree.o: $(hdrdir)/ruby/internal/glob.h
+nofree.o: $(hdrdir)/ruby/internal/globals.h
+nofree.o: $(hdrdir)/ruby/internal/has/attribute.h
+nofree.o: $(hdrdir)/ruby/internal/has/builtin.h
+nofree.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+nofree.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+nofree.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+nofree.o: $(hdrdir)/ruby/internal/has/extension.h
+nofree.o: $(hdrdir)/ruby/internal/has/feature.h
+nofree.o: $(hdrdir)/ruby/internal/has/warning.h
+nofree.o: $(hdrdir)/ruby/internal/intern/array.h
+nofree.o: $(hdrdir)/ruby/internal/intern/bignum.h
+nofree.o: $(hdrdir)/ruby/internal/intern/class.h
+nofree.o: $(hdrdir)/ruby/internal/intern/compar.h
+nofree.o: $(hdrdir)/ruby/internal/intern/complex.h
+nofree.o: $(hdrdir)/ruby/internal/intern/cont.h
+nofree.o: $(hdrdir)/ruby/internal/intern/dir.h
+nofree.o: $(hdrdir)/ruby/internal/intern/enum.h
+nofree.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+nofree.o: $(hdrdir)/ruby/internal/intern/error.h
+nofree.o: $(hdrdir)/ruby/internal/intern/eval.h
+nofree.o: $(hdrdir)/ruby/internal/intern/file.h
+nofree.o: $(hdrdir)/ruby/internal/intern/gc.h
+nofree.o: $(hdrdir)/ruby/internal/intern/hash.h
+nofree.o: $(hdrdir)/ruby/internal/intern/io.h
+nofree.o: $(hdrdir)/ruby/internal/intern/load.h
+nofree.o: $(hdrdir)/ruby/internal/intern/marshal.h
+nofree.o: $(hdrdir)/ruby/internal/intern/numeric.h
+nofree.o: $(hdrdir)/ruby/internal/intern/object.h
+nofree.o: $(hdrdir)/ruby/internal/intern/parse.h
+nofree.o: $(hdrdir)/ruby/internal/intern/proc.h
+nofree.o: $(hdrdir)/ruby/internal/intern/process.h
+nofree.o: $(hdrdir)/ruby/internal/intern/random.h
+nofree.o: $(hdrdir)/ruby/internal/intern/range.h
+nofree.o: $(hdrdir)/ruby/internal/intern/rational.h
+nofree.o: $(hdrdir)/ruby/internal/intern/re.h
+nofree.o: $(hdrdir)/ruby/internal/intern/ruby.h
+nofree.o: $(hdrdir)/ruby/internal/intern/select.h
+nofree.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+nofree.o: $(hdrdir)/ruby/internal/intern/signal.h
+nofree.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+nofree.o: $(hdrdir)/ruby/internal/intern/string.h
+nofree.o: $(hdrdir)/ruby/internal/intern/struct.h
+nofree.o: $(hdrdir)/ruby/internal/intern/thread.h
+nofree.o: $(hdrdir)/ruby/internal/intern/time.h
+nofree.o: $(hdrdir)/ruby/internal/intern/variable.h
+nofree.o: $(hdrdir)/ruby/internal/intern/vm.h
+nofree.o: $(hdrdir)/ruby/internal/interpreter.h
+nofree.o: $(hdrdir)/ruby/internal/iterator.h
+nofree.o: $(hdrdir)/ruby/internal/memory.h
+nofree.o: $(hdrdir)/ruby/internal/method.h
+nofree.o: $(hdrdir)/ruby/internal/module.h
+nofree.o: $(hdrdir)/ruby/internal/newobj.h
+nofree.o: $(hdrdir)/ruby/internal/rgengc.h
+nofree.o: $(hdrdir)/ruby/internal/scan_args.h
+nofree.o: $(hdrdir)/ruby/internal/special_consts.h
+nofree.o: $(hdrdir)/ruby/internal/static_assert.h
+nofree.o: $(hdrdir)/ruby/internal/stdalign.h
+nofree.o: $(hdrdir)/ruby/internal/stdbool.h
+nofree.o: $(hdrdir)/ruby/internal/symbol.h
+nofree.o: $(hdrdir)/ruby/internal/token_paste.h
+nofree.o: $(hdrdir)/ruby/internal/value.h
+nofree.o: $(hdrdir)/ruby/internal/value_type.h
+nofree.o: $(hdrdir)/ruby/internal/variable.h
+nofree.o: $(hdrdir)/ruby/internal/warning_push.h
+nofree.o: $(hdrdir)/ruby/internal/xmalloc.h
nofree.o: $(hdrdir)/ruby/missing.h
nofree.o: $(hdrdir)/ruby/ruby.h
nofree.o: $(hdrdir)/ruby/st.h
nofree.o: $(hdrdir)/ruby/subst.h
-nofree.o: $(top_srcdir)/include/ruby.h
nofree.o: nofree.c
normalize.o: $(RUBY_EXTCONF_H)
normalize.o: $(arch_hdrdir)/ruby/config.h
+normalize.o: $(hdrdir)/ruby.h
+normalize.o: $(hdrdir)/ruby/assert.h
normalize.o: $(hdrdir)/ruby/backward.h
+normalize.o: $(hdrdir)/ruby/backward/2/assume.h
+normalize.o: $(hdrdir)/ruby/backward/2/attributes.h
+normalize.o: $(hdrdir)/ruby/backward/2/bool.h
+normalize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+normalize.o: $(hdrdir)/ruby/backward/2/inttypes.h
+normalize.o: $(hdrdir)/ruby/backward/2/limits.h
+normalize.o: $(hdrdir)/ruby/backward/2/long_long.h
+normalize.o: $(hdrdir)/ruby/backward/2/stdalign.h
+normalize.o: $(hdrdir)/ruby/backward/2/stdarg.h
normalize.o: $(hdrdir)/ruby/defines.h
normalize.o: $(hdrdir)/ruby/encoding.h
normalize.o: $(hdrdir)/ruby/intern.h
-normalize.o: $(hdrdir)/ruby/io.h
+normalize.o: $(hdrdir)/ruby/internal/anyargs.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+normalize.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+normalize.o: $(hdrdir)/ruby/internal/assume.h
+normalize.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+normalize.o: $(hdrdir)/ruby/internal/attr/artificial.h
+normalize.o: $(hdrdir)/ruby/internal/attr/cold.h
+normalize.o: $(hdrdir)/ruby/internal/attr/const.h
+normalize.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+normalize.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+normalize.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+normalize.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+normalize.o: $(hdrdir)/ruby/internal/attr/error.h
+normalize.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+normalize.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+normalize.o: $(hdrdir)/ruby/internal/attr/format.h
+normalize.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+normalize.o: $(hdrdir)/ruby/internal/attr/noalias.h
+normalize.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+normalize.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+normalize.o: $(hdrdir)/ruby/internal/attr/noinline.h
+normalize.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+normalize.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+normalize.o: $(hdrdir)/ruby/internal/attr/pure.h
+normalize.o: $(hdrdir)/ruby/internal/attr/restrict.h
+normalize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+normalize.o: $(hdrdir)/ruby/internal/attr/warning.h
+normalize.o: $(hdrdir)/ruby/internal/attr/weakref.h
+normalize.o: $(hdrdir)/ruby/internal/cast.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_is.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+normalize.o: $(hdrdir)/ruby/internal/compiler_since.h
+normalize.o: $(hdrdir)/ruby/internal/config.h
+normalize.o: $(hdrdir)/ruby/internal/constant_p.h
+normalize.o: $(hdrdir)/ruby/internal/core.h
+normalize.o: $(hdrdir)/ruby/internal/core/rarray.h
+normalize.o: $(hdrdir)/ruby/internal/core/rbasic.h
+normalize.o: $(hdrdir)/ruby/internal/core/rbignum.h
+normalize.o: $(hdrdir)/ruby/internal/core/rclass.h
+normalize.o: $(hdrdir)/ruby/internal/core/rdata.h
+normalize.o: $(hdrdir)/ruby/internal/core/rfile.h
+normalize.o: $(hdrdir)/ruby/internal/core/rhash.h
+normalize.o: $(hdrdir)/ruby/internal/core/robject.h
+normalize.o: $(hdrdir)/ruby/internal/core/rregexp.h
+normalize.o: $(hdrdir)/ruby/internal/core/rstring.h
+normalize.o: $(hdrdir)/ruby/internal/core/rstruct.h
+normalize.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+normalize.o: $(hdrdir)/ruby/internal/ctype.h
+normalize.o: $(hdrdir)/ruby/internal/dllexport.h
+normalize.o: $(hdrdir)/ruby/internal/dosish.h
+normalize.o: $(hdrdir)/ruby/internal/error.h
+normalize.o: $(hdrdir)/ruby/internal/eval.h
+normalize.o: $(hdrdir)/ruby/internal/event.h
+normalize.o: $(hdrdir)/ruby/internal/fl_type.h
+normalize.o: $(hdrdir)/ruby/internal/gc.h
+normalize.o: $(hdrdir)/ruby/internal/glob.h
+normalize.o: $(hdrdir)/ruby/internal/globals.h
+normalize.o: $(hdrdir)/ruby/internal/has/attribute.h
+normalize.o: $(hdrdir)/ruby/internal/has/builtin.h
+normalize.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+normalize.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+normalize.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+normalize.o: $(hdrdir)/ruby/internal/has/extension.h
+normalize.o: $(hdrdir)/ruby/internal/has/feature.h
+normalize.o: $(hdrdir)/ruby/internal/has/warning.h
+normalize.o: $(hdrdir)/ruby/internal/intern/array.h
+normalize.o: $(hdrdir)/ruby/internal/intern/bignum.h
+normalize.o: $(hdrdir)/ruby/internal/intern/class.h
+normalize.o: $(hdrdir)/ruby/internal/intern/compar.h
+normalize.o: $(hdrdir)/ruby/internal/intern/complex.h
+normalize.o: $(hdrdir)/ruby/internal/intern/cont.h
+normalize.o: $(hdrdir)/ruby/internal/intern/dir.h
+normalize.o: $(hdrdir)/ruby/internal/intern/enum.h
+normalize.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+normalize.o: $(hdrdir)/ruby/internal/intern/error.h
+normalize.o: $(hdrdir)/ruby/internal/intern/eval.h
+normalize.o: $(hdrdir)/ruby/internal/intern/file.h
+normalize.o: $(hdrdir)/ruby/internal/intern/gc.h
+normalize.o: $(hdrdir)/ruby/internal/intern/hash.h
+normalize.o: $(hdrdir)/ruby/internal/intern/io.h
+normalize.o: $(hdrdir)/ruby/internal/intern/load.h
+normalize.o: $(hdrdir)/ruby/internal/intern/marshal.h
+normalize.o: $(hdrdir)/ruby/internal/intern/numeric.h
+normalize.o: $(hdrdir)/ruby/internal/intern/object.h
+normalize.o: $(hdrdir)/ruby/internal/intern/parse.h
+normalize.o: $(hdrdir)/ruby/internal/intern/proc.h
+normalize.o: $(hdrdir)/ruby/internal/intern/process.h
+normalize.o: $(hdrdir)/ruby/internal/intern/random.h
+normalize.o: $(hdrdir)/ruby/internal/intern/range.h
+normalize.o: $(hdrdir)/ruby/internal/intern/rational.h
+normalize.o: $(hdrdir)/ruby/internal/intern/re.h
+normalize.o: $(hdrdir)/ruby/internal/intern/ruby.h
+normalize.o: $(hdrdir)/ruby/internal/intern/select.h
+normalize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+normalize.o: $(hdrdir)/ruby/internal/intern/signal.h
+normalize.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+normalize.o: $(hdrdir)/ruby/internal/intern/string.h
+normalize.o: $(hdrdir)/ruby/internal/intern/struct.h
+normalize.o: $(hdrdir)/ruby/internal/intern/thread.h
+normalize.o: $(hdrdir)/ruby/internal/intern/time.h
+normalize.o: $(hdrdir)/ruby/internal/intern/variable.h
+normalize.o: $(hdrdir)/ruby/internal/intern/vm.h
+normalize.o: $(hdrdir)/ruby/internal/interpreter.h
+normalize.o: $(hdrdir)/ruby/internal/iterator.h
+normalize.o: $(hdrdir)/ruby/internal/memory.h
+normalize.o: $(hdrdir)/ruby/internal/method.h
+normalize.o: $(hdrdir)/ruby/internal/module.h
+normalize.o: $(hdrdir)/ruby/internal/newobj.h
+normalize.o: $(hdrdir)/ruby/internal/rgengc.h
+normalize.o: $(hdrdir)/ruby/internal/scan_args.h
+normalize.o: $(hdrdir)/ruby/internal/special_consts.h
+normalize.o: $(hdrdir)/ruby/internal/static_assert.h
+normalize.o: $(hdrdir)/ruby/internal/stdalign.h
+normalize.o: $(hdrdir)/ruby/internal/stdbool.h
+normalize.o: $(hdrdir)/ruby/internal/symbol.h
+normalize.o: $(hdrdir)/ruby/internal/token_paste.h
+normalize.o: $(hdrdir)/ruby/internal/value.h
+normalize.o: $(hdrdir)/ruby/internal/value_type.h
+normalize.o: $(hdrdir)/ruby/internal/variable.h
+normalize.o: $(hdrdir)/ruby/internal/warning_push.h
+normalize.o: $(hdrdir)/ruby/internal/xmalloc.h
normalize.o: $(hdrdir)/ruby/missing.h
normalize.o: $(hdrdir)/ruby/onigmo.h
normalize.o: $(hdrdir)/ruby/oniguruma.h
normalize.o: $(hdrdir)/ruby/ruby.h
normalize.o: $(hdrdir)/ruby/st.h
normalize.o: $(hdrdir)/ruby/subst.h
-normalize.o: $(top_srcdir)/include/ruby.h
normalize.o: $(top_srcdir)/internal.h
+normalize.o: $(top_srcdir)/internal/file.h
normalize.o: normalize.c
qsort.o: $(RUBY_EXTCONF_H)
qsort.o: $(arch_hdrdir)/ruby/config.h
+qsort.o: $(hdrdir)/ruby.h
+qsort.o: $(hdrdir)/ruby/assert.h
qsort.o: $(hdrdir)/ruby/backward.h
+qsort.o: $(hdrdir)/ruby/backward/2/assume.h
+qsort.o: $(hdrdir)/ruby/backward/2/attributes.h
+qsort.o: $(hdrdir)/ruby/backward/2/bool.h
+qsort.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+qsort.o: $(hdrdir)/ruby/backward/2/inttypes.h
+qsort.o: $(hdrdir)/ruby/backward/2/limits.h
+qsort.o: $(hdrdir)/ruby/backward/2/long_long.h
+qsort.o: $(hdrdir)/ruby/backward/2/stdalign.h
+qsort.o: $(hdrdir)/ruby/backward/2/stdarg.h
qsort.o: $(hdrdir)/ruby/defines.h
qsort.o: $(hdrdir)/ruby/encoding.h
qsort.o: $(hdrdir)/ruby/intern.h
+qsort.o: $(hdrdir)/ruby/internal/anyargs.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+qsort.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+qsort.o: $(hdrdir)/ruby/internal/assume.h
+qsort.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+qsort.o: $(hdrdir)/ruby/internal/attr/artificial.h
+qsort.o: $(hdrdir)/ruby/internal/attr/cold.h
+qsort.o: $(hdrdir)/ruby/internal/attr/const.h
+qsort.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+qsort.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+qsort.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+qsort.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+qsort.o: $(hdrdir)/ruby/internal/attr/error.h
+qsort.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+qsort.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+qsort.o: $(hdrdir)/ruby/internal/attr/format.h
+qsort.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+qsort.o: $(hdrdir)/ruby/internal/attr/noalias.h
+qsort.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+qsort.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+qsort.o: $(hdrdir)/ruby/internal/attr/noinline.h
+qsort.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+qsort.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+qsort.o: $(hdrdir)/ruby/internal/attr/pure.h
+qsort.o: $(hdrdir)/ruby/internal/attr/restrict.h
+qsort.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+qsort.o: $(hdrdir)/ruby/internal/attr/warning.h
+qsort.o: $(hdrdir)/ruby/internal/attr/weakref.h
+qsort.o: $(hdrdir)/ruby/internal/cast.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_is.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+qsort.o: $(hdrdir)/ruby/internal/compiler_since.h
+qsort.o: $(hdrdir)/ruby/internal/config.h
+qsort.o: $(hdrdir)/ruby/internal/constant_p.h
+qsort.o: $(hdrdir)/ruby/internal/core.h
+qsort.o: $(hdrdir)/ruby/internal/core/rarray.h
+qsort.o: $(hdrdir)/ruby/internal/core/rbasic.h
+qsort.o: $(hdrdir)/ruby/internal/core/rbignum.h
+qsort.o: $(hdrdir)/ruby/internal/core/rclass.h
+qsort.o: $(hdrdir)/ruby/internal/core/rdata.h
+qsort.o: $(hdrdir)/ruby/internal/core/rfile.h
+qsort.o: $(hdrdir)/ruby/internal/core/rhash.h
+qsort.o: $(hdrdir)/ruby/internal/core/robject.h
+qsort.o: $(hdrdir)/ruby/internal/core/rregexp.h
+qsort.o: $(hdrdir)/ruby/internal/core/rstring.h
+qsort.o: $(hdrdir)/ruby/internal/core/rstruct.h
+qsort.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+qsort.o: $(hdrdir)/ruby/internal/ctype.h
+qsort.o: $(hdrdir)/ruby/internal/dllexport.h
+qsort.o: $(hdrdir)/ruby/internal/dosish.h
+qsort.o: $(hdrdir)/ruby/internal/error.h
+qsort.o: $(hdrdir)/ruby/internal/eval.h
+qsort.o: $(hdrdir)/ruby/internal/event.h
+qsort.o: $(hdrdir)/ruby/internal/fl_type.h
+qsort.o: $(hdrdir)/ruby/internal/gc.h
+qsort.o: $(hdrdir)/ruby/internal/glob.h
+qsort.o: $(hdrdir)/ruby/internal/globals.h
+qsort.o: $(hdrdir)/ruby/internal/has/attribute.h
+qsort.o: $(hdrdir)/ruby/internal/has/builtin.h
+qsort.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+qsort.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+qsort.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+qsort.o: $(hdrdir)/ruby/internal/has/extension.h
+qsort.o: $(hdrdir)/ruby/internal/has/feature.h
+qsort.o: $(hdrdir)/ruby/internal/has/warning.h
+qsort.o: $(hdrdir)/ruby/internal/intern/array.h
+qsort.o: $(hdrdir)/ruby/internal/intern/bignum.h
+qsort.o: $(hdrdir)/ruby/internal/intern/class.h
+qsort.o: $(hdrdir)/ruby/internal/intern/compar.h
+qsort.o: $(hdrdir)/ruby/internal/intern/complex.h
+qsort.o: $(hdrdir)/ruby/internal/intern/cont.h
+qsort.o: $(hdrdir)/ruby/internal/intern/dir.h
+qsort.o: $(hdrdir)/ruby/internal/intern/enum.h
+qsort.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+qsort.o: $(hdrdir)/ruby/internal/intern/error.h
+qsort.o: $(hdrdir)/ruby/internal/intern/eval.h
+qsort.o: $(hdrdir)/ruby/internal/intern/file.h
+qsort.o: $(hdrdir)/ruby/internal/intern/gc.h
+qsort.o: $(hdrdir)/ruby/internal/intern/hash.h
+qsort.o: $(hdrdir)/ruby/internal/intern/io.h
+qsort.o: $(hdrdir)/ruby/internal/intern/load.h
+qsort.o: $(hdrdir)/ruby/internal/intern/marshal.h
+qsort.o: $(hdrdir)/ruby/internal/intern/numeric.h
+qsort.o: $(hdrdir)/ruby/internal/intern/object.h
+qsort.o: $(hdrdir)/ruby/internal/intern/parse.h
+qsort.o: $(hdrdir)/ruby/internal/intern/proc.h
+qsort.o: $(hdrdir)/ruby/internal/intern/process.h
+qsort.o: $(hdrdir)/ruby/internal/intern/random.h
+qsort.o: $(hdrdir)/ruby/internal/intern/range.h
+qsort.o: $(hdrdir)/ruby/internal/intern/rational.h
+qsort.o: $(hdrdir)/ruby/internal/intern/re.h
+qsort.o: $(hdrdir)/ruby/internal/intern/ruby.h
+qsort.o: $(hdrdir)/ruby/internal/intern/select.h
+qsort.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+qsort.o: $(hdrdir)/ruby/internal/intern/signal.h
+qsort.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+qsort.o: $(hdrdir)/ruby/internal/intern/string.h
+qsort.o: $(hdrdir)/ruby/internal/intern/struct.h
+qsort.o: $(hdrdir)/ruby/internal/intern/thread.h
+qsort.o: $(hdrdir)/ruby/internal/intern/time.h
+qsort.o: $(hdrdir)/ruby/internal/intern/variable.h
+qsort.o: $(hdrdir)/ruby/internal/intern/vm.h
+qsort.o: $(hdrdir)/ruby/internal/interpreter.h
+qsort.o: $(hdrdir)/ruby/internal/iterator.h
+qsort.o: $(hdrdir)/ruby/internal/memory.h
+qsort.o: $(hdrdir)/ruby/internal/method.h
+qsort.o: $(hdrdir)/ruby/internal/module.h
+qsort.o: $(hdrdir)/ruby/internal/newobj.h
+qsort.o: $(hdrdir)/ruby/internal/rgengc.h
+qsort.o: $(hdrdir)/ruby/internal/scan_args.h
+qsort.o: $(hdrdir)/ruby/internal/special_consts.h
+qsort.o: $(hdrdir)/ruby/internal/static_assert.h
+qsort.o: $(hdrdir)/ruby/internal/stdalign.h
+qsort.o: $(hdrdir)/ruby/internal/stdbool.h
+qsort.o: $(hdrdir)/ruby/internal/symbol.h
+qsort.o: $(hdrdir)/ruby/internal/token_paste.h
+qsort.o: $(hdrdir)/ruby/internal/value.h
+qsort.o: $(hdrdir)/ruby/internal/value_type.h
+qsort.o: $(hdrdir)/ruby/internal/variable.h
+qsort.o: $(hdrdir)/ruby/internal/warning_push.h
+qsort.o: $(hdrdir)/ruby/internal/xmalloc.h
qsort.o: $(hdrdir)/ruby/missing.h
qsort.o: $(hdrdir)/ruby/onigmo.h
qsort.o: $(hdrdir)/ruby/oniguruma.h
@@ -155,17 +2126,488 @@ qsort.o: $(hdrdir)/ruby/ruby.h
qsort.o: $(hdrdir)/ruby/st.h
qsort.o: $(hdrdir)/ruby/subst.h
qsort.o: $(hdrdir)/ruby/util.h
-qsort.o: $(top_srcdir)/include/ruby.h
qsort.o: qsort.c
+rb_interned_str.o: $(RUBY_EXTCONF_H)
+rb_interned_str.o: $(arch_hdrdir)/ruby/config.h
+rb_interned_str.o: $(hdrdir)/ruby.h
+rb_interned_str.o: $(hdrdir)/ruby/assert.h
+rb_interned_str.o: $(hdrdir)/ruby/backward.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/assume.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/attributes.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/bool.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/inttypes.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/limits.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/long_long.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/stdalign.h
+rb_interned_str.o: $(hdrdir)/ruby/backward/2/stdarg.h
+rb_interned_str.o: $(hdrdir)/ruby/defines.h
+rb_interned_str.o: $(hdrdir)/ruby/intern.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/anyargs.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/assume.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/artificial.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/cold.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/const.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/error.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/format.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noalias.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noinline.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/pure.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/restrict.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/warning.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/attr/weakref.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/cast.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_is.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/compiler_since.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/config.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/constant_p.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rarray.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rbasic.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rbignum.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rclass.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rdata.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rfile.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rhash.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/robject.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rregexp.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rstring.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rstruct.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/ctype.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/dllexport.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/dosish.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/error.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/eval.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/event.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/fl_type.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/gc.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/glob.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/globals.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/attribute.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/builtin.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/extension.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/feature.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/has/warning.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/array.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/bignum.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/class.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/compar.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/complex.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/cont.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/dir.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/enum.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/error.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/eval.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/gc.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/hash.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/io.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/load.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/marshal.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/numeric.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/object.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/parse.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/proc.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/process.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/random.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/range.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/rational.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/re.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/ruby.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/select.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/signal.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/string.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/struct.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/thread.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/time.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/variable.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/vm.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/interpreter.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/iterator.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/memory.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/method.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/module.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/newobj.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/rgengc.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/scan_args.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/special_consts.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/static_assert.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/stdalign.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/stdbool.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/symbol.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/token_paste.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/value.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/value_type.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/variable.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/warning_push.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/xmalloc.h
+rb_interned_str.o: $(hdrdir)/ruby/missing.h
+rb_interned_str.o: $(hdrdir)/ruby/ruby.h
+rb_interned_str.o: $(hdrdir)/ruby/st.h
+rb_interned_str.o: $(hdrdir)/ruby/subst.h
+rb_interned_str.o: rb_interned_str.c
+rb_str_dup.o: $(RUBY_EXTCONF_H)
+rb_str_dup.o: $(arch_hdrdir)/ruby/config.h
+rb_str_dup.o: $(hdrdir)/ruby.h
+rb_str_dup.o: $(hdrdir)/ruby/assert.h
+rb_str_dup.o: $(hdrdir)/ruby/backward.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/assume.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/attributes.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/bool.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/inttypes.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/limits.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/long_long.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/stdalign.h
+rb_str_dup.o: $(hdrdir)/ruby/backward/2/stdarg.h
+rb_str_dup.o: $(hdrdir)/ruby/defines.h
+rb_str_dup.o: $(hdrdir)/ruby/intern.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/anyargs.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/assume.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/artificial.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/cold.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/const.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/error.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/format.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noalias.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noinline.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/pure.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/restrict.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/warning.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/attr/weakref.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/cast.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_is.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/compiler_since.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/config.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/constant_p.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rarray.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rbasic.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rbignum.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rclass.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rdata.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rfile.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rhash.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/robject.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rregexp.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rstring.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rstruct.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/ctype.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/dllexport.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/dosish.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/error.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/eval.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/event.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/fl_type.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/gc.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/glob.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/globals.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/attribute.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/builtin.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/extension.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/feature.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/has/warning.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/array.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/bignum.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/class.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/compar.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/complex.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/cont.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/dir.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/enum.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/error.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/eval.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/gc.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/hash.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/io.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/load.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/marshal.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/numeric.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/object.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/parse.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/proc.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/process.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/random.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/range.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/rational.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/re.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/ruby.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/select.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/signal.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/string.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/struct.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/thread.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/time.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/variable.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/vm.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/interpreter.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/iterator.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/memory.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/method.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/module.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/newobj.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/rgengc.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/scan_args.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/special_consts.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/static_assert.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/stdalign.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/stdbool.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/symbol.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/token_paste.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/value.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/value_type.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/variable.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/warning_push.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/xmalloc.h
+rb_str_dup.o: $(hdrdir)/ruby/missing.h
+rb_str_dup.o: $(hdrdir)/ruby/ruby.h
+rb_str_dup.o: $(hdrdir)/ruby/st.h
+rb_str_dup.o: $(hdrdir)/ruby/subst.h
+rb_str_dup.o: rb_str_dup.c
set_len.o: $(RUBY_EXTCONF_H)
set_len.o: $(arch_hdrdir)/ruby/config.h
+set_len.o: $(hdrdir)/ruby.h
+set_len.o: $(hdrdir)/ruby/assert.h
set_len.o: $(hdrdir)/ruby/backward.h
+set_len.o: $(hdrdir)/ruby/backward/2/assume.h
+set_len.o: $(hdrdir)/ruby/backward/2/attributes.h
+set_len.o: $(hdrdir)/ruby/backward/2/bool.h
+set_len.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+set_len.o: $(hdrdir)/ruby/backward/2/inttypes.h
+set_len.o: $(hdrdir)/ruby/backward/2/limits.h
+set_len.o: $(hdrdir)/ruby/backward/2/long_long.h
+set_len.o: $(hdrdir)/ruby/backward/2/stdalign.h
+set_len.o: $(hdrdir)/ruby/backward/2/stdarg.h
set_len.o: $(hdrdir)/ruby/defines.h
set_len.o: $(hdrdir)/ruby/intern.h
+set_len.o: $(hdrdir)/ruby/internal/anyargs.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+set_len.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+set_len.o: $(hdrdir)/ruby/internal/assume.h
+set_len.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+set_len.o: $(hdrdir)/ruby/internal/attr/artificial.h
+set_len.o: $(hdrdir)/ruby/internal/attr/cold.h
+set_len.o: $(hdrdir)/ruby/internal/attr/const.h
+set_len.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+set_len.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+set_len.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+set_len.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+set_len.o: $(hdrdir)/ruby/internal/attr/error.h
+set_len.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+set_len.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+set_len.o: $(hdrdir)/ruby/internal/attr/format.h
+set_len.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+set_len.o: $(hdrdir)/ruby/internal/attr/noalias.h
+set_len.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+set_len.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+set_len.o: $(hdrdir)/ruby/internal/attr/noinline.h
+set_len.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+set_len.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+set_len.o: $(hdrdir)/ruby/internal/attr/pure.h
+set_len.o: $(hdrdir)/ruby/internal/attr/restrict.h
+set_len.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+set_len.o: $(hdrdir)/ruby/internal/attr/warning.h
+set_len.o: $(hdrdir)/ruby/internal/attr/weakref.h
+set_len.o: $(hdrdir)/ruby/internal/cast.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_is.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+set_len.o: $(hdrdir)/ruby/internal/compiler_since.h
+set_len.o: $(hdrdir)/ruby/internal/config.h
+set_len.o: $(hdrdir)/ruby/internal/constant_p.h
+set_len.o: $(hdrdir)/ruby/internal/core.h
+set_len.o: $(hdrdir)/ruby/internal/core/rarray.h
+set_len.o: $(hdrdir)/ruby/internal/core/rbasic.h
+set_len.o: $(hdrdir)/ruby/internal/core/rbignum.h
+set_len.o: $(hdrdir)/ruby/internal/core/rclass.h
+set_len.o: $(hdrdir)/ruby/internal/core/rdata.h
+set_len.o: $(hdrdir)/ruby/internal/core/rfile.h
+set_len.o: $(hdrdir)/ruby/internal/core/rhash.h
+set_len.o: $(hdrdir)/ruby/internal/core/robject.h
+set_len.o: $(hdrdir)/ruby/internal/core/rregexp.h
+set_len.o: $(hdrdir)/ruby/internal/core/rstring.h
+set_len.o: $(hdrdir)/ruby/internal/core/rstruct.h
+set_len.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+set_len.o: $(hdrdir)/ruby/internal/ctype.h
+set_len.o: $(hdrdir)/ruby/internal/dllexport.h
+set_len.o: $(hdrdir)/ruby/internal/dosish.h
+set_len.o: $(hdrdir)/ruby/internal/error.h
+set_len.o: $(hdrdir)/ruby/internal/eval.h
+set_len.o: $(hdrdir)/ruby/internal/event.h
+set_len.o: $(hdrdir)/ruby/internal/fl_type.h
+set_len.o: $(hdrdir)/ruby/internal/gc.h
+set_len.o: $(hdrdir)/ruby/internal/glob.h
+set_len.o: $(hdrdir)/ruby/internal/globals.h
+set_len.o: $(hdrdir)/ruby/internal/has/attribute.h
+set_len.o: $(hdrdir)/ruby/internal/has/builtin.h
+set_len.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+set_len.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+set_len.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+set_len.o: $(hdrdir)/ruby/internal/has/extension.h
+set_len.o: $(hdrdir)/ruby/internal/has/feature.h
+set_len.o: $(hdrdir)/ruby/internal/has/warning.h
+set_len.o: $(hdrdir)/ruby/internal/intern/array.h
+set_len.o: $(hdrdir)/ruby/internal/intern/bignum.h
+set_len.o: $(hdrdir)/ruby/internal/intern/class.h
+set_len.o: $(hdrdir)/ruby/internal/intern/compar.h
+set_len.o: $(hdrdir)/ruby/internal/intern/complex.h
+set_len.o: $(hdrdir)/ruby/internal/intern/cont.h
+set_len.o: $(hdrdir)/ruby/internal/intern/dir.h
+set_len.o: $(hdrdir)/ruby/internal/intern/enum.h
+set_len.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+set_len.o: $(hdrdir)/ruby/internal/intern/error.h
+set_len.o: $(hdrdir)/ruby/internal/intern/eval.h
+set_len.o: $(hdrdir)/ruby/internal/intern/file.h
+set_len.o: $(hdrdir)/ruby/internal/intern/gc.h
+set_len.o: $(hdrdir)/ruby/internal/intern/hash.h
+set_len.o: $(hdrdir)/ruby/internal/intern/io.h
+set_len.o: $(hdrdir)/ruby/internal/intern/load.h
+set_len.o: $(hdrdir)/ruby/internal/intern/marshal.h
+set_len.o: $(hdrdir)/ruby/internal/intern/numeric.h
+set_len.o: $(hdrdir)/ruby/internal/intern/object.h
+set_len.o: $(hdrdir)/ruby/internal/intern/parse.h
+set_len.o: $(hdrdir)/ruby/internal/intern/proc.h
+set_len.o: $(hdrdir)/ruby/internal/intern/process.h
+set_len.o: $(hdrdir)/ruby/internal/intern/random.h
+set_len.o: $(hdrdir)/ruby/internal/intern/range.h
+set_len.o: $(hdrdir)/ruby/internal/intern/rational.h
+set_len.o: $(hdrdir)/ruby/internal/intern/re.h
+set_len.o: $(hdrdir)/ruby/internal/intern/ruby.h
+set_len.o: $(hdrdir)/ruby/internal/intern/select.h
+set_len.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+set_len.o: $(hdrdir)/ruby/internal/intern/signal.h
+set_len.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+set_len.o: $(hdrdir)/ruby/internal/intern/string.h
+set_len.o: $(hdrdir)/ruby/internal/intern/struct.h
+set_len.o: $(hdrdir)/ruby/internal/intern/thread.h
+set_len.o: $(hdrdir)/ruby/internal/intern/time.h
+set_len.o: $(hdrdir)/ruby/internal/intern/variable.h
+set_len.o: $(hdrdir)/ruby/internal/intern/vm.h
+set_len.o: $(hdrdir)/ruby/internal/interpreter.h
+set_len.o: $(hdrdir)/ruby/internal/iterator.h
+set_len.o: $(hdrdir)/ruby/internal/memory.h
+set_len.o: $(hdrdir)/ruby/internal/method.h
+set_len.o: $(hdrdir)/ruby/internal/module.h
+set_len.o: $(hdrdir)/ruby/internal/newobj.h
+set_len.o: $(hdrdir)/ruby/internal/rgengc.h
+set_len.o: $(hdrdir)/ruby/internal/scan_args.h
+set_len.o: $(hdrdir)/ruby/internal/special_consts.h
+set_len.o: $(hdrdir)/ruby/internal/static_assert.h
+set_len.o: $(hdrdir)/ruby/internal/stdalign.h
+set_len.o: $(hdrdir)/ruby/internal/stdbool.h
+set_len.o: $(hdrdir)/ruby/internal/symbol.h
+set_len.o: $(hdrdir)/ruby/internal/token_paste.h
+set_len.o: $(hdrdir)/ruby/internal/value.h
+set_len.o: $(hdrdir)/ruby/internal/value_type.h
+set_len.o: $(hdrdir)/ruby/internal/variable.h
+set_len.o: $(hdrdir)/ruby/internal/warning_push.h
+set_len.o: $(hdrdir)/ruby/internal/xmalloc.h
set_len.o: $(hdrdir)/ruby/missing.h
set_len.o: $(hdrdir)/ruby/ruby.h
set_len.o: $(hdrdir)/ruby/st.h
set_len.o: $(hdrdir)/ruby/subst.h
-set_len.o: $(top_srcdir)/include/ruby.h
set_len.o: set_len.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/string/ellipsize.c b/ext/-test-/string/ellipsize.c
index 0451519492..6034408724 100644
--- a/ext/-test-/string/ellipsize.c
+++ b/ext/-test-/string/ellipsize.c
@@ -7,7 +7,7 @@ bug_str_ellipsize(VALUE str, VALUE len)
}
void
-Init_ellipsize(VALUE klass)
+Init_string_ellipsize(VALUE klass)
{
rb_define_method(klass, "ellipsize", bug_str_ellipsize, 1);
}
diff --git a/ext/-test-/string/enc_associate.c b/ext/-test-/string/enc_associate.c
index 53811620a0..594d8a43a4 100644
--- a/ext/-test-/string/enc_associate.c
+++ b/ext/-test-/string/enc_associate.c
@@ -15,7 +15,7 @@ bug_str_encoding_index(VALUE self, VALUE str)
}
void
-Init_enc_associate(VALUE klass)
+Init_string_enc_associate(VALUE klass)
{
rb_define_method(klass, "associate_encoding!", bug_str_enc_associate, 1);
rb_define_singleton_method(klass, "encoding_index", bug_str_encoding_index, 1);
diff --git a/ext/-test-/string/enc_str_buf_cat.c b/ext/-test-/string/enc_str_buf_cat.c
index 5d583c65dc..4c1b262e1e 100644
--- a/ext/-test-/string/enc_str_buf_cat.c
+++ b/ext/-test-/string/enc_str_buf_cat.c
@@ -7,8 +7,22 @@ enc_str_buf_cat(VALUE str, VALUE str2)
return rb_enc_str_buf_cat(str, RSTRING_PTR(str2), RSTRING_LEN(str2), rb_enc_get(str2));
}
+static VALUE
+str_conv_enc_opts(VALUE str, VALUE from, VALUE to, VALUE ecflags, VALUE ecopts)
+{
+ rb_encoding *from_enc = NIL_P(from) ? NULL : rb_to_encoding(from);
+ rb_encoding *to_enc = NIL_P(to) ? NULL : rb_to_encoding(to);
+ int flags = NUM2INT(ecflags);
+ if (!NIL_P(ecopts)) {
+ Check_Type(ecopts, T_HASH);
+ OBJ_FREEZE(ecopts);
+ }
+ return rb_str_conv_enc_opts(str, from_enc, to_enc, flags, ecopts);
+}
+
void
-Init_enc_str_buf_cat(VALUE klass)
+Init_string_enc_str_buf_cat(VALUE klass)
{
rb_define_method(klass, "enc_str_buf_cat", enc_str_buf_cat, 1);
+ rb_define_method(klass, "str_conv_enc_opts", str_conv_enc_opts, 4);
}
diff --git a/ext/-test-/string/fstring.c b/ext/-test-/string/fstring.c
index b65c98ce6d..2374319fe3 100644
--- a/ext/-test-/string/fstring.c
+++ b/ext/-test-/string/fstring.c
@@ -1,4 +1,5 @@
#include "ruby.h"
+#include "ruby/encoding.h"
VALUE rb_fstring(VALUE str);
@@ -8,8 +9,22 @@ bug_s_fstring(VALUE self, VALUE str)
return rb_fstring(str);
}
+VALUE
+bug_s_rb_enc_interned_str(VALUE self, VALUE encoding)
+{
+ return rb_enc_interned_str("foo", 3, RDATA(encoding)->data);
+}
+
+VALUE
+bug_s_rb_enc_str_new(VALUE self, VALUE encoding)
+{
+ return rb_enc_str_new("foo", 3, RDATA(encoding)->data);
+}
+
void
-Init_fstring(VALUE klass)
+Init_string_fstring(VALUE klass)
{
rb_define_singleton_method(klass, "fstring", bug_s_fstring, 1);
+ rb_define_singleton_method(klass, "rb_enc_interned_str", bug_s_rb_enc_interned_str, 1);
+ rb_define_singleton_method(klass, "rb_enc_str_new", bug_s_rb_enc_str_new, 1);
}
diff --git a/ext/-test-/string/init.c b/ext/-test-/string/init.c
index 0b3e4a6ff2..a74245c8d7 100644
--- a/ext/-test-/string/init.c
+++ b/ext/-test-/string/init.c
@@ -1,6 +1,6 @@
#include "ruby.h"
-#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);}
+#define init(n) {void Init_string_##n(VALUE klass); Init_string_##n(klass);}
void
Init_string(void)
diff --git a/ext/-test-/string/modify.c b/ext/-test-/string/modify.c
index ddd2efd8f0..945febc7e3 100644
--- a/ext/-test-/string/modify.c
+++ b/ext/-test-/string/modify.c
@@ -15,7 +15,7 @@ bug_str_modify_expand(VALUE str, VALUE expand)
}
void
-Init_modify(VALUE klass)
+Init_string_modify(VALUE klass)
{
rb_define_method(klass, "modify!", bug_str_modify, 0);
rb_define_method(klass, "modify_expand!", bug_str_modify_expand, 1);
diff --git a/ext/-test-/string/new.c b/ext/-test-/string/new.c
new file mode 100644
index 0000000000..60625b8300
--- /dev/null
+++ b/ext/-test-/string/new.c
@@ -0,0 +1,21 @@
+#include "ruby.h"
+#include "ruby/encoding.h"
+
+static VALUE
+bug_str_buf_new(VALUE self, VALUE len)
+{
+ return rb_str_buf_new(NUM2LONG(len));
+}
+
+static VALUE
+bug_external_str_new(VALUE self, VALUE len, VALUE enc)
+{
+ return rb_external_str_new_with_enc(NULL, NUM2LONG(len), rb_to_encoding(enc));
+}
+
+void
+Init_string_new(VALUE klass)
+{
+ rb_define_singleton_method(klass, "buf_new", bug_str_buf_new, 1);
+ rb_define_singleton_method(klass, "external_new", bug_external_str_new, 2);
+}
diff --git a/ext/-test-/string/nofree.c b/ext/-test-/string/nofree.c
index d3d8071ff9..fdf810c741 100644
--- a/ext/-test-/string/nofree.c
+++ b/ext/-test-/string/nofree.c
@@ -7,7 +7,7 @@ bug_str_nofree(VALUE self)
}
void
-Init_nofree(VALUE klass)
+Init_string_nofree(VALUE klass)
{
rb_define_singleton_method(klass, "nofree", bug_str_nofree, 0);
}
diff --git a/ext/-test-/string/normalize.c b/ext/-test-/string/normalize.c
index 2e16a4616f..a069288ee8 100644
--- a/ext/-test-/string/normalize.c
+++ b/ext/-test-/string/normalize.c
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal/file.h"
#ifdef __APPLE__
static VALUE
@@ -11,7 +11,7 @@ normalize_ospath(VALUE str)
#endif
void
-Init_normalize(VALUE klass)
+Init_string_normalize(VALUE klass)
{
rb_define_method(klass, "normalize_ospath", normalize_ospath, 0);
}
diff --git a/ext/-test-/string/qsort.c b/ext/-test-/string/qsort.c
index 0b34936d38..fb7ea3d8cb 100644
--- a/ext/-test-/string/qsort.c
+++ b/ext/-test-/string/qsort.c
@@ -55,7 +55,7 @@ bug_str_qsort_bang(int argc, VALUE *argv, VALUE str)
}
void
-Init_qsort(VALUE klass)
+Init_string_qsort(VALUE klass)
{
rb_define_method(klass, "qsort!", bug_str_qsort_bang, -1);
}
diff --git a/ext/-test-/string/rb_interned_str.c b/ext/-test-/string/rb_interned_str.c
new file mode 100644
index 0000000000..47643ec249
--- /dev/null
+++ b/ext/-test-/string/rb_interned_str.c
@@ -0,0 +1,14 @@
+#include "ruby.h"
+
+static VALUE
+bug_rb_interned_str_dup(VALUE self, VALUE str)
+{
+ Check_Type(str, T_STRING);
+ return rb_interned_str(RSTRING_PTR(str), RSTRING_LEN(str));
+}
+
+void
+Init_string_rb_interned_str(VALUE klass)
+{
+ rb_define_singleton_method(klass, "rb_interned_str_dup", bug_rb_interned_str_dup, 1);
+}
diff --git a/ext/-test-/string/rb_str_dup.c b/ext/-test-/string/rb_str_dup.c
new file mode 100644
index 0000000000..a0bd65820f
--- /dev/null
+++ b/ext/-test-/string/rb_str_dup.c
@@ -0,0 +1,35 @@
+#include "ruby.h"
+
+VALUE rb_str_dup(VALUE str);
+
+static VALUE
+bug_rb_str_dup(VALUE self, VALUE str)
+{
+ rb_check_type(str, T_STRING);
+ return rb_str_dup(str);
+}
+
+static VALUE
+bug_shared_string_p(VALUE self, VALUE str)
+{
+ rb_check_type(str, T_STRING);
+ return RB_FL_TEST(str, RUBY_ELTS_SHARED) && RB_FL_TEST(str, RSTRING_NOEMBED) ? Qtrue : Qfalse;
+}
+
+static VALUE
+bug_sharing_with_shared_p(VALUE self, VALUE str)
+{
+ rb_check_type(str, T_STRING);
+ if (bug_shared_string_p(self, str)) {
+ return bug_shared_string_p(self, RSTRING(str)->as.heap.aux.shared);
+ }
+ return Qfalse;
+}
+
+void
+Init_string_rb_str_dup(VALUE klass)
+{
+ rb_define_singleton_method(klass, "rb_str_dup", bug_rb_str_dup, 1);
+ rb_define_singleton_method(klass, "shared_string?", bug_shared_string_p, 1);
+ rb_define_singleton_method(klass, "sharing_with_shared?", bug_sharing_with_shared_p, 1);
+}
diff --git a/ext/-test-/string/set_len.c b/ext/-test-/string/set_len.c
index 3c7d19d778..219cea404c 100644
--- a/ext/-test-/string/set_len.c
+++ b/ext/-test-/string/set_len.c
@@ -8,7 +8,7 @@ bug_str_set_len(VALUE str, VALUE len)
}
void
-Init_set_len(VALUE klass)
+Init_string_set_len(VALUE klass)
{
rb_define_method(klass, "set_len", bug_str_set_len, 1);
}
diff --git a/ext/-test-/struct/depend b/ext/-test-/struct/depend
index 58ededbff9..166fff21d9 100644
--- a/ext/-test-/struct/depend
+++ b/ext/-test-/struct/depend
@@ -1,46 +1,646 @@
# AUTOGENERATED DEPENDENCIES START
duplicate.o: $(RUBY_EXTCONF_H)
duplicate.o: $(arch_hdrdir)/ruby/config.h
+duplicate.o: $(hdrdir)/ruby.h
+duplicate.o: $(hdrdir)/ruby/internal/anyargs.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+duplicate.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+duplicate.o: $(hdrdir)/ruby/internal/assume.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/artificial.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/cold.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/const.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/error.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/format.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/noalias.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/noinline.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/pure.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/restrict.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/warning.h
+duplicate.o: $(hdrdir)/ruby/internal/attr/weakref.h
+duplicate.o: $(hdrdir)/ruby/internal/cast.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_is.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+duplicate.o: $(hdrdir)/ruby/internal/compiler_since.h
+duplicate.o: $(hdrdir)/ruby/internal/config.h
+duplicate.o: $(hdrdir)/ruby/internal/constant_p.h
+duplicate.o: $(hdrdir)/ruby/internal/core.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rarray.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rbasic.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rbignum.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rclass.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rdata.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rfile.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rhash.h
+duplicate.o: $(hdrdir)/ruby/internal/core/robject.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rregexp.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rstring.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rstruct.h
+duplicate.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+duplicate.o: $(hdrdir)/ruby/internal/ctype.h
+duplicate.o: $(hdrdir)/ruby/internal/dllexport.h
+duplicate.o: $(hdrdir)/ruby/internal/dosish.h
+duplicate.o: $(hdrdir)/ruby/internal/error.h
+duplicate.o: $(hdrdir)/ruby/internal/eval.h
+duplicate.o: $(hdrdir)/ruby/internal/event.h
+duplicate.o: $(hdrdir)/ruby/internal/fl_type.h
+duplicate.o: $(hdrdir)/ruby/internal/gc.h
+duplicate.o: $(hdrdir)/ruby/internal/glob.h
+duplicate.o: $(hdrdir)/ruby/internal/globals.h
+duplicate.o: $(hdrdir)/ruby/internal/has/attribute.h
+duplicate.o: $(hdrdir)/ruby/internal/has/builtin.h
+duplicate.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+duplicate.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+duplicate.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+duplicate.o: $(hdrdir)/ruby/internal/has/extension.h
+duplicate.o: $(hdrdir)/ruby/internal/has/feature.h
+duplicate.o: $(hdrdir)/ruby/internal/has/warning.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/array.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/bignum.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/class.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/compar.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/complex.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/cont.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/dir.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/enum.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/error.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/eval.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/file.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/gc.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/hash.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/io.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/load.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/marshal.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/numeric.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/object.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/parse.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/proc.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/process.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/random.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/range.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/rational.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/re.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/ruby.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/select.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/signal.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/string.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/struct.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/thread.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/time.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/variable.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/vm.h
+duplicate.o: $(hdrdir)/ruby/internal/interpreter.h
+duplicate.o: $(hdrdir)/ruby/internal/iterator.h
+duplicate.o: $(hdrdir)/ruby/internal/memory.h
+duplicate.o: $(hdrdir)/ruby/internal/method.h
+duplicate.o: $(hdrdir)/ruby/internal/module.h
+duplicate.o: $(hdrdir)/ruby/internal/newobj.h
+duplicate.o: $(hdrdir)/ruby/internal/rgengc.h
+duplicate.o: $(hdrdir)/ruby/internal/scan_args.h
+duplicate.o: $(hdrdir)/ruby/internal/special_consts.h
+duplicate.o: $(hdrdir)/ruby/internal/static_assert.h
+duplicate.o: $(hdrdir)/ruby/internal/stdalign.h
+duplicate.o: $(hdrdir)/ruby/internal/stdbool.h
+duplicate.o: $(hdrdir)/ruby/internal/symbol.h
+duplicate.o: $(hdrdir)/ruby/internal/token_paste.h
+duplicate.o: $(hdrdir)/ruby/internal/value.h
+duplicate.o: $(hdrdir)/ruby/internal/value_type.h
+duplicate.o: $(hdrdir)/ruby/internal/variable.h
+duplicate.o: $(hdrdir)/ruby/internal/warning_push.h
+duplicate.o: $(hdrdir)/ruby/internal/xmalloc.h
+duplicate.o: $(hdrdir)/ruby/assert.h
duplicate.o: $(hdrdir)/ruby/backward.h
+duplicate.o: $(hdrdir)/ruby/backward/2/assume.h
+duplicate.o: $(hdrdir)/ruby/backward/2/attributes.h
+duplicate.o: $(hdrdir)/ruby/backward/2/bool.h
+duplicate.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+duplicate.o: $(hdrdir)/ruby/backward/2/inttypes.h
+duplicate.o: $(hdrdir)/ruby/backward/2/limits.h
+duplicate.o: $(hdrdir)/ruby/backward/2/long_long.h
+duplicate.o: $(hdrdir)/ruby/backward/2/stdalign.h
+duplicate.o: $(hdrdir)/ruby/backward/2/stdarg.h
duplicate.o: $(hdrdir)/ruby/defines.h
duplicate.o: $(hdrdir)/ruby/intern.h
duplicate.o: $(hdrdir)/ruby/missing.h
duplicate.o: $(hdrdir)/ruby/ruby.h
duplicate.o: $(hdrdir)/ruby/st.h
duplicate.o: $(hdrdir)/ruby/subst.h
-duplicate.o: $(top_srcdir)/include/ruby.h
duplicate.o: duplicate.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/intern.h
init.o: $(hdrdir)/ruby/missing.h
init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: init.c
len.o: $(RUBY_EXTCONF_H)
len.o: $(arch_hdrdir)/ruby/config.h
+len.o: $(hdrdir)/ruby.h
+len.o: $(hdrdir)/ruby/internal/anyargs.h
+len.o: $(hdrdir)/ruby/internal/arithmetic.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+len.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+len.o: $(hdrdir)/ruby/internal/assume.h
+len.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+len.o: $(hdrdir)/ruby/internal/attr/artificial.h
+len.o: $(hdrdir)/ruby/internal/attr/cold.h
+len.o: $(hdrdir)/ruby/internal/attr/const.h
+len.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+len.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+len.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+len.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+len.o: $(hdrdir)/ruby/internal/attr/error.h
+len.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+len.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+len.o: $(hdrdir)/ruby/internal/attr/format.h
+len.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+len.o: $(hdrdir)/ruby/internal/attr/noalias.h
+len.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+len.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+len.o: $(hdrdir)/ruby/internal/attr/noinline.h
+len.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+len.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+len.o: $(hdrdir)/ruby/internal/attr/pure.h
+len.o: $(hdrdir)/ruby/internal/attr/restrict.h
+len.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+len.o: $(hdrdir)/ruby/internal/attr/warning.h
+len.o: $(hdrdir)/ruby/internal/attr/weakref.h
+len.o: $(hdrdir)/ruby/internal/cast.h
+len.o: $(hdrdir)/ruby/internal/compiler_is.h
+len.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+len.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+len.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+len.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+len.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+len.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+len.o: $(hdrdir)/ruby/internal/compiler_since.h
+len.o: $(hdrdir)/ruby/internal/config.h
+len.o: $(hdrdir)/ruby/internal/constant_p.h
+len.o: $(hdrdir)/ruby/internal/core.h
+len.o: $(hdrdir)/ruby/internal/core/rarray.h
+len.o: $(hdrdir)/ruby/internal/core/rbasic.h
+len.o: $(hdrdir)/ruby/internal/core/rbignum.h
+len.o: $(hdrdir)/ruby/internal/core/rclass.h
+len.o: $(hdrdir)/ruby/internal/core/rdata.h
+len.o: $(hdrdir)/ruby/internal/core/rfile.h
+len.o: $(hdrdir)/ruby/internal/core/rhash.h
+len.o: $(hdrdir)/ruby/internal/core/robject.h
+len.o: $(hdrdir)/ruby/internal/core/rregexp.h
+len.o: $(hdrdir)/ruby/internal/core/rstring.h
+len.o: $(hdrdir)/ruby/internal/core/rstruct.h
+len.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+len.o: $(hdrdir)/ruby/internal/ctype.h
+len.o: $(hdrdir)/ruby/internal/dllexport.h
+len.o: $(hdrdir)/ruby/internal/dosish.h
+len.o: $(hdrdir)/ruby/internal/error.h
+len.o: $(hdrdir)/ruby/internal/eval.h
+len.o: $(hdrdir)/ruby/internal/event.h
+len.o: $(hdrdir)/ruby/internal/fl_type.h
+len.o: $(hdrdir)/ruby/internal/gc.h
+len.o: $(hdrdir)/ruby/internal/glob.h
+len.o: $(hdrdir)/ruby/internal/globals.h
+len.o: $(hdrdir)/ruby/internal/has/attribute.h
+len.o: $(hdrdir)/ruby/internal/has/builtin.h
+len.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+len.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+len.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+len.o: $(hdrdir)/ruby/internal/has/extension.h
+len.o: $(hdrdir)/ruby/internal/has/feature.h
+len.o: $(hdrdir)/ruby/internal/has/warning.h
+len.o: $(hdrdir)/ruby/internal/intern/array.h
+len.o: $(hdrdir)/ruby/internal/intern/bignum.h
+len.o: $(hdrdir)/ruby/internal/intern/class.h
+len.o: $(hdrdir)/ruby/internal/intern/compar.h
+len.o: $(hdrdir)/ruby/internal/intern/complex.h
+len.o: $(hdrdir)/ruby/internal/intern/cont.h
+len.o: $(hdrdir)/ruby/internal/intern/dir.h
+len.o: $(hdrdir)/ruby/internal/intern/enum.h
+len.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+len.o: $(hdrdir)/ruby/internal/intern/error.h
+len.o: $(hdrdir)/ruby/internal/intern/eval.h
+len.o: $(hdrdir)/ruby/internal/intern/file.h
+len.o: $(hdrdir)/ruby/internal/intern/gc.h
+len.o: $(hdrdir)/ruby/internal/intern/hash.h
+len.o: $(hdrdir)/ruby/internal/intern/io.h
+len.o: $(hdrdir)/ruby/internal/intern/load.h
+len.o: $(hdrdir)/ruby/internal/intern/marshal.h
+len.o: $(hdrdir)/ruby/internal/intern/numeric.h
+len.o: $(hdrdir)/ruby/internal/intern/object.h
+len.o: $(hdrdir)/ruby/internal/intern/parse.h
+len.o: $(hdrdir)/ruby/internal/intern/proc.h
+len.o: $(hdrdir)/ruby/internal/intern/process.h
+len.o: $(hdrdir)/ruby/internal/intern/random.h
+len.o: $(hdrdir)/ruby/internal/intern/range.h
+len.o: $(hdrdir)/ruby/internal/intern/rational.h
+len.o: $(hdrdir)/ruby/internal/intern/re.h
+len.o: $(hdrdir)/ruby/internal/intern/ruby.h
+len.o: $(hdrdir)/ruby/internal/intern/select.h
+len.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+len.o: $(hdrdir)/ruby/internal/intern/signal.h
+len.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+len.o: $(hdrdir)/ruby/internal/intern/string.h
+len.o: $(hdrdir)/ruby/internal/intern/struct.h
+len.o: $(hdrdir)/ruby/internal/intern/thread.h
+len.o: $(hdrdir)/ruby/internal/intern/time.h
+len.o: $(hdrdir)/ruby/internal/intern/variable.h
+len.o: $(hdrdir)/ruby/internal/intern/vm.h
+len.o: $(hdrdir)/ruby/internal/interpreter.h
+len.o: $(hdrdir)/ruby/internal/iterator.h
+len.o: $(hdrdir)/ruby/internal/memory.h
+len.o: $(hdrdir)/ruby/internal/method.h
+len.o: $(hdrdir)/ruby/internal/module.h
+len.o: $(hdrdir)/ruby/internal/newobj.h
+len.o: $(hdrdir)/ruby/internal/rgengc.h
+len.o: $(hdrdir)/ruby/internal/scan_args.h
+len.o: $(hdrdir)/ruby/internal/special_consts.h
+len.o: $(hdrdir)/ruby/internal/static_assert.h
+len.o: $(hdrdir)/ruby/internal/stdalign.h
+len.o: $(hdrdir)/ruby/internal/stdbool.h
+len.o: $(hdrdir)/ruby/internal/symbol.h
+len.o: $(hdrdir)/ruby/internal/token_paste.h
+len.o: $(hdrdir)/ruby/internal/value.h
+len.o: $(hdrdir)/ruby/internal/value_type.h
+len.o: $(hdrdir)/ruby/internal/variable.h
+len.o: $(hdrdir)/ruby/internal/warning_push.h
+len.o: $(hdrdir)/ruby/internal/xmalloc.h
+len.o: $(hdrdir)/ruby/assert.h
len.o: $(hdrdir)/ruby/backward.h
+len.o: $(hdrdir)/ruby/backward/2/assume.h
+len.o: $(hdrdir)/ruby/backward/2/attributes.h
+len.o: $(hdrdir)/ruby/backward/2/bool.h
+len.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+len.o: $(hdrdir)/ruby/backward/2/inttypes.h
+len.o: $(hdrdir)/ruby/backward/2/limits.h
+len.o: $(hdrdir)/ruby/backward/2/long_long.h
+len.o: $(hdrdir)/ruby/backward/2/stdalign.h
+len.o: $(hdrdir)/ruby/backward/2/stdarg.h
len.o: $(hdrdir)/ruby/defines.h
len.o: $(hdrdir)/ruby/intern.h
len.o: $(hdrdir)/ruby/missing.h
len.o: $(hdrdir)/ruby/ruby.h
len.o: $(hdrdir)/ruby/st.h
len.o: $(hdrdir)/ruby/subst.h
-len.o: $(top_srcdir)/include/ruby.h
len.o: len.c
member.o: $(RUBY_EXTCONF_H)
member.o: $(arch_hdrdir)/ruby/config.h
+member.o: $(hdrdir)/ruby.h
+member.o: $(hdrdir)/ruby/internal/anyargs.h
+member.o: $(hdrdir)/ruby/internal/arithmetic.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+member.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+member.o: $(hdrdir)/ruby/internal/assume.h
+member.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+member.o: $(hdrdir)/ruby/internal/attr/artificial.h
+member.o: $(hdrdir)/ruby/internal/attr/cold.h
+member.o: $(hdrdir)/ruby/internal/attr/const.h
+member.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+member.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+member.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+member.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+member.o: $(hdrdir)/ruby/internal/attr/error.h
+member.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+member.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+member.o: $(hdrdir)/ruby/internal/attr/format.h
+member.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+member.o: $(hdrdir)/ruby/internal/attr/noalias.h
+member.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+member.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+member.o: $(hdrdir)/ruby/internal/attr/noinline.h
+member.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+member.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+member.o: $(hdrdir)/ruby/internal/attr/pure.h
+member.o: $(hdrdir)/ruby/internal/attr/restrict.h
+member.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+member.o: $(hdrdir)/ruby/internal/attr/warning.h
+member.o: $(hdrdir)/ruby/internal/attr/weakref.h
+member.o: $(hdrdir)/ruby/internal/cast.h
+member.o: $(hdrdir)/ruby/internal/compiler_is.h
+member.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+member.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+member.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+member.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+member.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+member.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+member.o: $(hdrdir)/ruby/internal/compiler_since.h
+member.o: $(hdrdir)/ruby/internal/config.h
+member.o: $(hdrdir)/ruby/internal/constant_p.h
+member.o: $(hdrdir)/ruby/internal/core.h
+member.o: $(hdrdir)/ruby/internal/core/rarray.h
+member.o: $(hdrdir)/ruby/internal/core/rbasic.h
+member.o: $(hdrdir)/ruby/internal/core/rbignum.h
+member.o: $(hdrdir)/ruby/internal/core/rclass.h
+member.o: $(hdrdir)/ruby/internal/core/rdata.h
+member.o: $(hdrdir)/ruby/internal/core/rfile.h
+member.o: $(hdrdir)/ruby/internal/core/rhash.h
+member.o: $(hdrdir)/ruby/internal/core/robject.h
+member.o: $(hdrdir)/ruby/internal/core/rregexp.h
+member.o: $(hdrdir)/ruby/internal/core/rstring.h
+member.o: $(hdrdir)/ruby/internal/core/rstruct.h
+member.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+member.o: $(hdrdir)/ruby/internal/ctype.h
+member.o: $(hdrdir)/ruby/internal/dllexport.h
+member.o: $(hdrdir)/ruby/internal/dosish.h
+member.o: $(hdrdir)/ruby/internal/error.h
+member.o: $(hdrdir)/ruby/internal/eval.h
+member.o: $(hdrdir)/ruby/internal/event.h
+member.o: $(hdrdir)/ruby/internal/fl_type.h
+member.o: $(hdrdir)/ruby/internal/gc.h
+member.o: $(hdrdir)/ruby/internal/glob.h
+member.o: $(hdrdir)/ruby/internal/globals.h
+member.o: $(hdrdir)/ruby/internal/has/attribute.h
+member.o: $(hdrdir)/ruby/internal/has/builtin.h
+member.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+member.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+member.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+member.o: $(hdrdir)/ruby/internal/has/extension.h
+member.o: $(hdrdir)/ruby/internal/has/feature.h
+member.o: $(hdrdir)/ruby/internal/has/warning.h
+member.o: $(hdrdir)/ruby/internal/intern/array.h
+member.o: $(hdrdir)/ruby/internal/intern/bignum.h
+member.o: $(hdrdir)/ruby/internal/intern/class.h
+member.o: $(hdrdir)/ruby/internal/intern/compar.h
+member.o: $(hdrdir)/ruby/internal/intern/complex.h
+member.o: $(hdrdir)/ruby/internal/intern/cont.h
+member.o: $(hdrdir)/ruby/internal/intern/dir.h
+member.o: $(hdrdir)/ruby/internal/intern/enum.h
+member.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+member.o: $(hdrdir)/ruby/internal/intern/error.h
+member.o: $(hdrdir)/ruby/internal/intern/eval.h
+member.o: $(hdrdir)/ruby/internal/intern/file.h
+member.o: $(hdrdir)/ruby/internal/intern/gc.h
+member.o: $(hdrdir)/ruby/internal/intern/hash.h
+member.o: $(hdrdir)/ruby/internal/intern/io.h
+member.o: $(hdrdir)/ruby/internal/intern/load.h
+member.o: $(hdrdir)/ruby/internal/intern/marshal.h
+member.o: $(hdrdir)/ruby/internal/intern/numeric.h
+member.o: $(hdrdir)/ruby/internal/intern/object.h
+member.o: $(hdrdir)/ruby/internal/intern/parse.h
+member.o: $(hdrdir)/ruby/internal/intern/proc.h
+member.o: $(hdrdir)/ruby/internal/intern/process.h
+member.o: $(hdrdir)/ruby/internal/intern/random.h
+member.o: $(hdrdir)/ruby/internal/intern/range.h
+member.o: $(hdrdir)/ruby/internal/intern/rational.h
+member.o: $(hdrdir)/ruby/internal/intern/re.h
+member.o: $(hdrdir)/ruby/internal/intern/ruby.h
+member.o: $(hdrdir)/ruby/internal/intern/select.h
+member.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+member.o: $(hdrdir)/ruby/internal/intern/signal.h
+member.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+member.o: $(hdrdir)/ruby/internal/intern/string.h
+member.o: $(hdrdir)/ruby/internal/intern/struct.h
+member.o: $(hdrdir)/ruby/internal/intern/thread.h
+member.o: $(hdrdir)/ruby/internal/intern/time.h
+member.o: $(hdrdir)/ruby/internal/intern/variable.h
+member.o: $(hdrdir)/ruby/internal/intern/vm.h
+member.o: $(hdrdir)/ruby/internal/interpreter.h
+member.o: $(hdrdir)/ruby/internal/iterator.h
+member.o: $(hdrdir)/ruby/internal/memory.h
+member.o: $(hdrdir)/ruby/internal/method.h
+member.o: $(hdrdir)/ruby/internal/module.h
+member.o: $(hdrdir)/ruby/internal/newobj.h
+member.o: $(hdrdir)/ruby/internal/rgengc.h
+member.o: $(hdrdir)/ruby/internal/scan_args.h
+member.o: $(hdrdir)/ruby/internal/special_consts.h
+member.o: $(hdrdir)/ruby/internal/static_assert.h
+member.o: $(hdrdir)/ruby/internal/stdalign.h
+member.o: $(hdrdir)/ruby/internal/stdbool.h
+member.o: $(hdrdir)/ruby/internal/symbol.h
+member.o: $(hdrdir)/ruby/internal/token_paste.h
+member.o: $(hdrdir)/ruby/internal/value.h
+member.o: $(hdrdir)/ruby/internal/value_type.h
+member.o: $(hdrdir)/ruby/internal/variable.h
+member.o: $(hdrdir)/ruby/internal/warning_push.h
+member.o: $(hdrdir)/ruby/internal/xmalloc.h
+member.o: $(hdrdir)/ruby/assert.h
member.o: $(hdrdir)/ruby/backward.h
+member.o: $(hdrdir)/ruby/backward/2/assume.h
+member.o: $(hdrdir)/ruby/backward/2/attributes.h
+member.o: $(hdrdir)/ruby/backward/2/bool.h
+member.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+member.o: $(hdrdir)/ruby/backward/2/inttypes.h
+member.o: $(hdrdir)/ruby/backward/2/limits.h
+member.o: $(hdrdir)/ruby/backward/2/long_long.h
+member.o: $(hdrdir)/ruby/backward/2/stdalign.h
+member.o: $(hdrdir)/ruby/backward/2/stdarg.h
member.o: $(hdrdir)/ruby/defines.h
member.o: $(hdrdir)/ruby/intern.h
member.o: $(hdrdir)/ruby/missing.h
member.o: $(hdrdir)/ruby/ruby.h
member.o: $(hdrdir)/ruby/st.h
member.o: $(hdrdir)/ruby/subst.h
-member.o: $(top_srcdir)/include/ruby.h
member.o: member.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/symbol/depend b/ext/-test-/symbol/depend
new file mode 100644
index 0000000000..22d8ca5d23
--- /dev/null
+++ b/ext/-test-/symbol/depend
@@ -0,0 +1,324 @@
+# AUTOGENERATED DEPENDENCIES START
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+type.o: $(RUBY_EXTCONF_H)
+type.o: $(arch_hdrdir)/ruby/config.h
+type.o: $(hdrdir)/ruby.h
+type.o: $(hdrdir)/ruby/internal/anyargs.h
+type.o: $(hdrdir)/ruby/internal/arithmetic.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+type.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+type.o: $(hdrdir)/ruby/internal/assume.h
+type.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+type.o: $(hdrdir)/ruby/internal/attr/artificial.h
+type.o: $(hdrdir)/ruby/internal/attr/cold.h
+type.o: $(hdrdir)/ruby/internal/attr/const.h
+type.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+type.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+type.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+type.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+type.o: $(hdrdir)/ruby/internal/attr/error.h
+type.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+type.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+type.o: $(hdrdir)/ruby/internal/attr/format.h
+type.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+type.o: $(hdrdir)/ruby/internal/attr/noalias.h
+type.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+type.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+type.o: $(hdrdir)/ruby/internal/attr/noinline.h
+type.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+type.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+type.o: $(hdrdir)/ruby/internal/attr/pure.h
+type.o: $(hdrdir)/ruby/internal/attr/restrict.h
+type.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+type.o: $(hdrdir)/ruby/internal/attr/warning.h
+type.o: $(hdrdir)/ruby/internal/attr/weakref.h
+type.o: $(hdrdir)/ruby/internal/cast.h
+type.o: $(hdrdir)/ruby/internal/compiler_is.h
+type.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+type.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+type.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+type.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+type.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+type.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+type.o: $(hdrdir)/ruby/internal/compiler_since.h
+type.o: $(hdrdir)/ruby/internal/config.h
+type.o: $(hdrdir)/ruby/internal/constant_p.h
+type.o: $(hdrdir)/ruby/internal/core.h
+type.o: $(hdrdir)/ruby/internal/core/rarray.h
+type.o: $(hdrdir)/ruby/internal/core/rbasic.h
+type.o: $(hdrdir)/ruby/internal/core/rbignum.h
+type.o: $(hdrdir)/ruby/internal/core/rclass.h
+type.o: $(hdrdir)/ruby/internal/core/rdata.h
+type.o: $(hdrdir)/ruby/internal/core/rfile.h
+type.o: $(hdrdir)/ruby/internal/core/rhash.h
+type.o: $(hdrdir)/ruby/internal/core/robject.h
+type.o: $(hdrdir)/ruby/internal/core/rregexp.h
+type.o: $(hdrdir)/ruby/internal/core/rstring.h
+type.o: $(hdrdir)/ruby/internal/core/rstruct.h
+type.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+type.o: $(hdrdir)/ruby/internal/ctype.h
+type.o: $(hdrdir)/ruby/internal/dllexport.h
+type.o: $(hdrdir)/ruby/internal/dosish.h
+type.o: $(hdrdir)/ruby/internal/error.h
+type.o: $(hdrdir)/ruby/internal/eval.h
+type.o: $(hdrdir)/ruby/internal/event.h
+type.o: $(hdrdir)/ruby/internal/fl_type.h
+type.o: $(hdrdir)/ruby/internal/gc.h
+type.o: $(hdrdir)/ruby/internal/glob.h
+type.o: $(hdrdir)/ruby/internal/globals.h
+type.o: $(hdrdir)/ruby/internal/has/attribute.h
+type.o: $(hdrdir)/ruby/internal/has/builtin.h
+type.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+type.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+type.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+type.o: $(hdrdir)/ruby/internal/has/extension.h
+type.o: $(hdrdir)/ruby/internal/has/feature.h
+type.o: $(hdrdir)/ruby/internal/has/warning.h
+type.o: $(hdrdir)/ruby/internal/intern/array.h
+type.o: $(hdrdir)/ruby/internal/intern/bignum.h
+type.o: $(hdrdir)/ruby/internal/intern/class.h
+type.o: $(hdrdir)/ruby/internal/intern/compar.h
+type.o: $(hdrdir)/ruby/internal/intern/complex.h
+type.o: $(hdrdir)/ruby/internal/intern/cont.h
+type.o: $(hdrdir)/ruby/internal/intern/dir.h
+type.o: $(hdrdir)/ruby/internal/intern/enum.h
+type.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+type.o: $(hdrdir)/ruby/internal/intern/error.h
+type.o: $(hdrdir)/ruby/internal/intern/eval.h
+type.o: $(hdrdir)/ruby/internal/intern/file.h
+type.o: $(hdrdir)/ruby/internal/intern/gc.h
+type.o: $(hdrdir)/ruby/internal/intern/hash.h
+type.o: $(hdrdir)/ruby/internal/intern/io.h
+type.o: $(hdrdir)/ruby/internal/intern/load.h
+type.o: $(hdrdir)/ruby/internal/intern/marshal.h
+type.o: $(hdrdir)/ruby/internal/intern/numeric.h
+type.o: $(hdrdir)/ruby/internal/intern/object.h
+type.o: $(hdrdir)/ruby/internal/intern/parse.h
+type.o: $(hdrdir)/ruby/internal/intern/proc.h
+type.o: $(hdrdir)/ruby/internal/intern/process.h
+type.o: $(hdrdir)/ruby/internal/intern/random.h
+type.o: $(hdrdir)/ruby/internal/intern/range.h
+type.o: $(hdrdir)/ruby/internal/intern/rational.h
+type.o: $(hdrdir)/ruby/internal/intern/re.h
+type.o: $(hdrdir)/ruby/internal/intern/ruby.h
+type.o: $(hdrdir)/ruby/internal/intern/select.h
+type.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+type.o: $(hdrdir)/ruby/internal/intern/signal.h
+type.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+type.o: $(hdrdir)/ruby/internal/intern/string.h
+type.o: $(hdrdir)/ruby/internal/intern/struct.h
+type.o: $(hdrdir)/ruby/internal/intern/thread.h
+type.o: $(hdrdir)/ruby/internal/intern/time.h
+type.o: $(hdrdir)/ruby/internal/intern/variable.h
+type.o: $(hdrdir)/ruby/internal/intern/vm.h
+type.o: $(hdrdir)/ruby/internal/interpreter.h
+type.o: $(hdrdir)/ruby/internal/iterator.h
+type.o: $(hdrdir)/ruby/internal/memory.h
+type.o: $(hdrdir)/ruby/internal/method.h
+type.o: $(hdrdir)/ruby/internal/module.h
+type.o: $(hdrdir)/ruby/internal/newobj.h
+type.o: $(hdrdir)/ruby/internal/rgengc.h
+type.o: $(hdrdir)/ruby/internal/scan_args.h
+type.o: $(hdrdir)/ruby/internal/special_consts.h
+type.o: $(hdrdir)/ruby/internal/static_assert.h
+type.o: $(hdrdir)/ruby/internal/stdalign.h
+type.o: $(hdrdir)/ruby/internal/stdbool.h
+type.o: $(hdrdir)/ruby/internal/symbol.h
+type.o: $(hdrdir)/ruby/internal/token_paste.h
+type.o: $(hdrdir)/ruby/internal/value.h
+type.o: $(hdrdir)/ruby/internal/value_type.h
+type.o: $(hdrdir)/ruby/internal/variable.h
+type.o: $(hdrdir)/ruby/internal/warning_push.h
+type.o: $(hdrdir)/ruby/internal/xmalloc.h
+type.o: $(hdrdir)/ruby/assert.h
+type.o: $(hdrdir)/ruby/backward.h
+type.o: $(hdrdir)/ruby/backward/2/assume.h
+type.o: $(hdrdir)/ruby/backward/2/attributes.h
+type.o: $(hdrdir)/ruby/backward/2/bool.h
+type.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+type.o: $(hdrdir)/ruby/backward/2/inttypes.h
+type.o: $(hdrdir)/ruby/backward/2/limits.h
+type.o: $(hdrdir)/ruby/backward/2/long_long.h
+type.o: $(hdrdir)/ruby/backward/2/stdalign.h
+type.o: $(hdrdir)/ruby/backward/2/stdarg.h
+type.o: $(hdrdir)/ruby/defines.h
+type.o: $(hdrdir)/ruby/intern.h
+type.o: $(hdrdir)/ruby/missing.h
+type.o: $(hdrdir)/ruby/ruby.h
+type.o: $(hdrdir)/ruby/st.h
+type.o: $(hdrdir)/ruby/subst.h
+type.o: type.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/symbol/init.c b/ext/-test-/symbol/init.c
index 20cf2fa079..4038701ac9 100644
--- a/ext/-test-/symbol/init.c
+++ b/ext/-test-/symbol/init.c
@@ -20,6 +20,13 @@ sym_pinneddown_p(VALUE dummy, VALUE sym)
#endif
}
+static VALUE
+sym_iv_get(VALUE dummy, VALUE obj, VALUE name)
+{
+ const char *n = StringValueCStr(name);
+ return rb_iv_get(obj, n);
+}
+
void
Init_symbol(void)
{
@@ -27,5 +34,6 @@ Init_symbol(void)
VALUE klass = rb_define_class_under(mBug, "Symbol", rb_cSymbol);
rb_define_singleton_method(klass, "find", sym_find, 1);
rb_define_singleton_method(klass, "pinneddown?", sym_pinneddown_p, 1);
+ rb_define_singleton_method(klass, "iv_get", sym_iv_get, 2);
TEST_INIT_FUNCS(init);
}
diff --git a/ext/-test-/thread_fd_close/depend b/ext/-test-/thread_fd_close/depend
index 7bc04c3db3..b04bfe7deb 100644
--- a/ext/-test-/thread_fd_close/depend
+++ b/ext/-test-/thread_fd_close/depend
@@ -1,14 +1,160 @@
# AUTOGENERATED DEPENDENCIES START
thread_fd_close.o: $(RUBY_EXTCONF_H)
thread_fd_close.o: $(arch_hdrdir)/ruby/config.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/anyargs.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/assume.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/artificial.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/cold.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/const.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/error.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/format.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/noalias.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/noinline.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/pure.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/restrict.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/warning.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/attr/weakref.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/cast.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_is.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/compiler_since.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/config.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/constant_p.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rarray.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rbasic.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rbignum.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rclass.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rdata.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rfile.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rhash.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/robject.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rregexp.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rstring.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rstruct.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/ctype.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/dllexport.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/dosish.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/error.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/eval.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/event.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/fl_type.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/gc.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/glob.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/globals.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/attribute.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/builtin.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/extension.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/feature.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/has/warning.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/array.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/bignum.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/class.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/compar.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/complex.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/cont.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/dir.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/enum.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/error.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/eval.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/file.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/gc.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/hash.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/io.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/load.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/marshal.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/numeric.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/object.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/parse.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/proc.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/process.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/random.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/range.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/rational.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/re.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/ruby.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/select.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/signal.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/string.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/struct.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/thread.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/time.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/variable.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/intern/vm.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/interpreter.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/iterator.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/memory.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/method.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/module.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/newobj.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/rgengc.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/scan_args.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/special_consts.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/static_assert.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/stdalign.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/stdbool.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/symbol.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/token_paste.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/value.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/value_type.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/variable.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/warning_push.h
+thread_fd_close.o: $(hdrdir)/ruby/internal/xmalloc.h
+thread_fd_close.o: $(hdrdir)/ruby/assert.h
thread_fd_close.o: $(hdrdir)/ruby/backward.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/assume.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/attributes.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/bool.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/inttypes.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/limits.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/long_long.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/stdalign.h
+thread_fd_close.o: $(hdrdir)/ruby/backward/2/stdarg.h
thread_fd_close.o: $(hdrdir)/ruby/defines.h
-thread_fd_close.o: $(hdrdir)/ruby/encoding.h
thread_fd_close.o: $(hdrdir)/ruby/intern.h
-thread_fd_close.o: $(hdrdir)/ruby/io.h
thread_fd_close.o: $(hdrdir)/ruby/missing.h
-thread_fd_close.o: $(hdrdir)/ruby/onigmo.h
-thread_fd_close.o: $(hdrdir)/ruby/oniguruma.h
thread_fd_close.o: $(hdrdir)/ruby/ruby.h
thread_fd_close.o: $(hdrdir)/ruby/st.h
thread_fd_close.o: $(hdrdir)/ruby/subst.h
diff --git a/ext/-test-/time/depend b/ext/-test-/time/depend
new file mode 100644
index 0000000000..a3f1ea235b
--- /dev/null
+++ b/ext/-test-/time/depend
@@ -0,0 +1,489 @@
+# AUTOGENERATED DEPENDENCIES START
+init.o: $(RUBY_EXTCONF_H)
+init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
+init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
+init.o: $(hdrdir)/ruby/defines.h
+init.o: $(hdrdir)/ruby/intern.h
+init.o: $(hdrdir)/ruby/missing.h
+init.o: $(hdrdir)/ruby/ruby.h
+init.o: $(hdrdir)/ruby/st.h
+init.o: $(hdrdir)/ruby/subst.h
+init.o: init.c
+leap_second.o: $(RUBY_EXTCONF_H)
+leap_second.o: $(arch_hdrdir)/ruby/config.h
+leap_second.o: $(hdrdir)/ruby.h
+leap_second.o: $(hdrdir)/ruby/internal/anyargs.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+leap_second.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+leap_second.o: $(hdrdir)/ruby/internal/assume.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/artificial.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/cold.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/const.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/error.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/format.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/noalias.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/noinline.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/pure.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/restrict.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/warning.h
+leap_second.o: $(hdrdir)/ruby/internal/attr/weakref.h
+leap_second.o: $(hdrdir)/ruby/internal/cast.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_is.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+leap_second.o: $(hdrdir)/ruby/internal/compiler_since.h
+leap_second.o: $(hdrdir)/ruby/internal/config.h
+leap_second.o: $(hdrdir)/ruby/internal/constant_p.h
+leap_second.o: $(hdrdir)/ruby/internal/core.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rarray.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rbasic.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rbignum.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rclass.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rdata.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rfile.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rhash.h
+leap_second.o: $(hdrdir)/ruby/internal/core/robject.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rregexp.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rstring.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rstruct.h
+leap_second.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+leap_second.o: $(hdrdir)/ruby/internal/ctype.h
+leap_second.o: $(hdrdir)/ruby/internal/dllexport.h
+leap_second.o: $(hdrdir)/ruby/internal/dosish.h
+leap_second.o: $(hdrdir)/ruby/internal/error.h
+leap_second.o: $(hdrdir)/ruby/internal/eval.h
+leap_second.o: $(hdrdir)/ruby/internal/event.h
+leap_second.o: $(hdrdir)/ruby/internal/fl_type.h
+leap_second.o: $(hdrdir)/ruby/internal/gc.h
+leap_second.o: $(hdrdir)/ruby/internal/glob.h
+leap_second.o: $(hdrdir)/ruby/internal/globals.h
+leap_second.o: $(hdrdir)/ruby/internal/has/attribute.h
+leap_second.o: $(hdrdir)/ruby/internal/has/builtin.h
+leap_second.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+leap_second.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+leap_second.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+leap_second.o: $(hdrdir)/ruby/internal/has/extension.h
+leap_second.o: $(hdrdir)/ruby/internal/has/feature.h
+leap_second.o: $(hdrdir)/ruby/internal/has/warning.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/array.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/bignum.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/class.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/compar.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/complex.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/cont.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/dir.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/enum.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/error.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/eval.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/file.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/gc.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/hash.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/io.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/load.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/marshal.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/numeric.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/object.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/parse.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/proc.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/process.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/random.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/range.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/rational.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/re.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/ruby.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/select.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/signal.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/string.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/struct.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/thread.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/time.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/variable.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/vm.h
+leap_second.o: $(hdrdir)/ruby/internal/interpreter.h
+leap_second.o: $(hdrdir)/ruby/internal/iterator.h
+leap_second.o: $(hdrdir)/ruby/internal/memory.h
+leap_second.o: $(hdrdir)/ruby/internal/method.h
+leap_second.o: $(hdrdir)/ruby/internal/module.h
+leap_second.o: $(hdrdir)/ruby/internal/newobj.h
+leap_second.o: $(hdrdir)/ruby/internal/rgengc.h
+leap_second.o: $(hdrdir)/ruby/internal/scan_args.h
+leap_second.o: $(hdrdir)/ruby/internal/special_consts.h
+leap_second.o: $(hdrdir)/ruby/internal/static_assert.h
+leap_second.o: $(hdrdir)/ruby/internal/stdalign.h
+leap_second.o: $(hdrdir)/ruby/internal/stdbool.h
+leap_second.o: $(hdrdir)/ruby/internal/symbol.h
+leap_second.o: $(hdrdir)/ruby/internal/token_paste.h
+leap_second.o: $(hdrdir)/ruby/internal/value.h
+leap_second.o: $(hdrdir)/ruby/internal/value_type.h
+leap_second.o: $(hdrdir)/ruby/internal/variable.h
+leap_second.o: $(hdrdir)/ruby/internal/warning_push.h
+leap_second.o: $(hdrdir)/ruby/internal/xmalloc.h
+leap_second.o: $(hdrdir)/ruby/assert.h
+leap_second.o: $(hdrdir)/ruby/backward.h
+leap_second.o: $(hdrdir)/ruby/backward/2/assume.h
+leap_second.o: $(hdrdir)/ruby/backward/2/attributes.h
+leap_second.o: $(hdrdir)/ruby/backward/2/bool.h
+leap_second.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+leap_second.o: $(hdrdir)/ruby/backward/2/inttypes.h
+leap_second.o: $(hdrdir)/ruby/backward/2/limits.h
+leap_second.o: $(hdrdir)/ruby/backward/2/long_long.h
+leap_second.o: $(hdrdir)/ruby/backward/2/stdalign.h
+leap_second.o: $(hdrdir)/ruby/backward/2/stdarg.h
+leap_second.o: $(hdrdir)/ruby/defines.h
+leap_second.o: $(hdrdir)/ruby/intern.h
+leap_second.o: $(hdrdir)/ruby/missing.h
+leap_second.o: $(hdrdir)/ruby/ruby.h
+leap_second.o: $(hdrdir)/ruby/st.h
+leap_second.o: $(hdrdir)/ruby/subst.h
+leap_second.o: $(top_srcdir)/internal/bits.h
+leap_second.o: $(top_srcdir)/internal/compilers.h
+leap_second.o: $(top_srcdir)/internal/static_assert.h
+leap_second.o: $(top_srcdir)/internal/time.h
+leap_second.o: leap_second.c
+new.o: $(RUBY_EXTCONF_H)
+new.o: $(arch_hdrdir)/ruby/config.h
+new.o: $(hdrdir)/ruby.h
+new.o: $(hdrdir)/ruby/internal/anyargs.h
+new.o: $(hdrdir)/ruby/internal/arithmetic.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+new.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+new.o: $(hdrdir)/ruby/internal/assume.h
+new.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+new.o: $(hdrdir)/ruby/internal/attr/artificial.h
+new.o: $(hdrdir)/ruby/internal/attr/cold.h
+new.o: $(hdrdir)/ruby/internal/attr/const.h
+new.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+new.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+new.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+new.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+new.o: $(hdrdir)/ruby/internal/attr/error.h
+new.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+new.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+new.o: $(hdrdir)/ruby/internal/attr/format.h
+new.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+new.o: $(hdrdir)/ruby/internal/attr/noalias.h
+new.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+new.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+new.o: $(hdrdir)/ruby/internal/attr/noinline.h
+new.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+new.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+new.o: $(hdrdir)/ruby/internal/attr/pure.h
+new.o: $(hdrdir)/ruby/internal/attr/restrict.h
+new.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+new.o: $(hdrdir)/ruby/internal/attr/warning.h
+new.o: $(hdrdir)/ruby/internal/attr/weakref.h
+new.o: $(hdrdir)/ruby/internal/cast.h
+new.o: $(hdrdir)/ruby/internal/compiler_is.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+new.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+new.o: $(hdrdir)/ruby/internal/compiler_since.h
+new.o: $(hdrdir)/ruby/internal/config.h
+new.o: $(hdrdir)/ruby/internal/constant_p.h
+new.o: $(hdrdir)/ruby/internal/core.h
+new.o: $(hdrdir)/ruby/internal/core/rarray.h
+new.o: $(hdrdir)/ruby/internal/core/rbasic.h
+new.o: $(hdrdir)/ruby/internal/core/rbignum.h
+new.o: $(hdrdir)/ruby/internal/core/rclass.h
+new.o: $(hdrdir)/ruby/internal/core/rdata.h
+new.o: $(hdrdir)/ruby/internal/core/rfile.h
+new.o: $(hdrdir)/ruby/internal/core/rhash.h
+new.o: $(hdrdir)/ruby/internal/core/robject.h
+new.o: $(hdrdir)/ruby/internal/core/rregexp.h
+new.o: $(hdrdir)/ruby/internal/core/rstring.h
+new.o: $(hdrdir)/ruby/internal/core/rstruct.h
+new.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+new.o: $(hdrdir)/ruby/internal/ctype.h
+new.o: $(hdrdir)/ruby/internal/dllexport.h
+new.o: $(hdrdir)/ruby/internal/dosish.h
+new.o: $(hdrdir)/ruby/internal/error.h
+new.o: $(hdrdir)/ruby/internal/eval.h
+new.o: $(hdrdir)/ruby/internal/event.h
+new.o: $(hdrdir)/ruby/internal/fl_type.h
+new.o: $(hdrdir)/ruby/internal/gc.h
+new.o: $(hdrdir)/ruby/internal/glob.h
+new.o: $(hdrdir)/ruby/internal/globals.h
+new.o: $(hdrdir)/ruby/internal/has/attribute.h
+new.o: $(hdrdir)/ruby/internal/has/builtin.h
+new.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+new.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+new.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+new.o: $(hdrdir)/ruby/internal/has/extension.h
+new.o: $(hdrdir)/ruby/internal/has/feature.h
+new.o: $(hdrdir)/ruby/internal/has/warning.h
+new.o: $(hdrdir)/ruby/internal/intern/array.h
+new.o: $(hdrdir)/ruby/internal/intern/bignum.h
+new.o: $(hdrdir)/ruby/internal/intern/class.h
+new.o: $(hdrdir)/ruby/internal/intern/compar.h
+new.o: $(hdrdir)/ruby/internal/intern/complex.h
+new.o: $(hdrdir)/ruby/internal/intern/cont.h
+new.o: $(hdrdir)/ruby/internal/intern/dir.h
+new.o: $(hdrdir)/ruby/internal/intern/enum.h
+new.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+new.o: $(hdrdir)/ruby/internal/intern/error.h
+new.o: $(hdrdir)/ruby/internal/intern/eval.h
+new.o: $(hdrdir)/ruby/internal/intern/file.h
+new.o: $(hdrdir)/ruby/internal/intern/gc.h
+new.o: $(hdrdir)/ruby/internal/intern/hash.h
+new.o: $(hdrdir)/ruby/internal/intern/io.h
+new.o: $(hdrdir)/ruby/internal/intern/load.h
+new.o: $(hdrdir)/ruby/internal/intern/marshal.h
+new.o: $(hdrdir)/ruby/internal/intern/numeric.h
+new.o: $(hdrdir)/ruby/internal/intern/object.h
+new.o: $(hdrdir)/ruby/internal/intern/parse.h
+new.o: $(hdrdir)/ruby/internal/intern/proc.h
+new.o: $(hdrdir)/ruby/internal/intern/process.h
+new.o: $(hdrdir)/ruby/internal/intern/random.h
+new.o: $(hdrdir)/ruby/internal/intern/range.h
+new.o: $(hdrdir)/ruby/internal/intern/rational.h
+new.o: $(hdrdir)/ruby/internal/intern/re.h
+new.o: $(hdrdir)/ruby/internal/intern/ruby.h
+new.o: $(hdrdir)/ruby/internal/intern/select.h
+new.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+new.o: $(hdrdir)/ruby/internal/intern/signal.h
+new.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+new.o: $(hdrdir)/ruby/internal/intern/string.h
+new.o: $(hdrdir)/ruby/internal/intern/struct.h
+new.o: $(hdrdir)/ruby/internal/intern/thread.h
+new.o: $(hdrdir)/ruby/internal/intern/time.h
+new.o: $(hdrdir)/ruby/internal/intern/variable.h
+new.o: $(hdrdir)/ruby/internal/intern/vm.h
+new.o: $(hdrdir)/ruby/internal/interpreter.h
+new.o: $(hdrdir)/ruby/internal/iterator.h
+new.o: $(hdrdir)/ruby/internal/memory.h
+new.o: $(hdrdir)/ruby/internal/method.h
+new.o: $(hdrdir)/ruby/internal/module.h
+new.o: $(hdrdir)/ruby/internal/newobj.h
+new.o: $(hdrdir)/ruby/internal/rgengc.h
+new.o: $(hdrdir)/ruby/internal/scan_args.h
+new.o: $(hdrdir)/ruby/internal/special_consts.h
+new.o: $(hdrdir)/ruby/internal/static_assert.h
+new.o: $(hdrdir)/ruby/internal/stdalign.h
+new.o: $(hdrdir)/ruby/internal/stdbool.h
+new.o: $(hdrdir)/ruby/internal/symbol.h
+new.o: $(hdrdir)/ruby/internal/token_paste.h
+new.o: $(hdrdir)/ruby/internal/value.h
+new.o: $(hdrdir)/ruby/internal/value_type.h
+new.o: $(hdrdir)/ruby/internal/variable.h
+new.o: $(hdrdir)/ruby/internal/warning_push.h
+new.o: $(hdrdir)/ruby/internal/xmalloc.h
+new.o: $(hdrdir)/ruby/assert.h
+new.o: $(hdrdir)/ruby/backward.h
+new.o: $(hdrdir)/ruby/backward/2/assume.h
+new.o: $(hdrdir)/ruby/backward/2/attributes.h
+new.o: $(hdrdir)/ruby/backward/2/bool.h
+new.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+new.o: $(hdrdir)/ruby/backward/2/inttypes.h
+new.o: $(hdrdir)/ruby/backward/2/limits.h
+new.o: $(hdrdir)/ruby/backward/2/long_long.h
+new.o: $(hdrdir)/ruby/backward/2/stdalign.h
+new.o: $(hdrdir)/ruby/backward/2/stdarg.h
+new.o: $(hdrdir)/ruby/defines.h
+new.o: $(hdrdir)/ruby/intern.h
+new.o: $(hdrdir)/ruby/missing.h
+new.o: $(hdrdir)/ruby/ruby.h
+new.o: $(hdrdir)/ruby/st.h
+new.o: $(hdrdir)/ruby/subst.h
+new.o: new.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/time/init.c b/ext/-test-/time/init.c
index 01a20b8b3d..91f8bf825b 100644
--- a/ext/-test-/time/init.c
+++ b/ext/-test-/time/init.c
@@ -1,6 +1,6 @@
#include "ruby.h"
-#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);}
+#define init(n) {void Init_time_##n(VALUE klass); Init_time_##n(klass);}
void
Init_time(void)
diff --git a/ext/-test-/time/leap_second.c b/ext/-test-/time/leap_second.c
new file mode 100644
index 0000000000..ccf38194f0
--- /dev/null
+++ b/ext/-test-/time/leap_second.c
@@ -0,0 +1,14 @@
+#include "internal/time.h"
+
+static VALUE
+bug_time_s_reset_leap_second_info(VALUE klass)
+{
+ ruby_reset_leap_second_info();
+ return Qnil;
+}
+
+void
+Init_time_leap_second(VALUE klass)
+{
+ rb_define_singleton_method(klass, "reset_leap_second_info", bug_time_s_reset_leap_second_info, 0);
+}
diff --git a/ext/-test-/time/new.c b/ext/-test-/time/new.c
index 0f71a5542b..6f894417b6 100644
--- a/ext/-test-/time/new.c
+++ b/ext/-test-/time/new.c
@@ -26,7 +26,7 @@ bug_time_s_timespec_now(VALUE klass)
}
void
-Init_new(VALUE klass)
+Init_time_new(VALUE klass)
{
rb_define_singleton_method(klass, "nano_new", bug_time_s_nano_new, 2);
rb_define_singleton_method(klass, "timespec_new", bug_time_s_timespec_new, 3);
diff --git a/ext/-test-/tracepoint/depend b/ext/-test-/tracepoint/depend
index 5b2b2f7369..ba409e88fe 100644
--- a/ext/-test-/tracepoint/depend
+++ b/ext/-test-/tracepoint/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
gc_hook.o: $(RUBY_EXTCONF_H)
gc_hook.o: $(arch_hdrdir)/ruby/config.h
+gc_hook.o: $(hdrdir)/ruby/internal/anyargs.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+gc_hook.o: $(hdrdir)/ruby/internal/assume.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/artificial.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/cold.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/const.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/error.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/format.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/noalias.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/noinline.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/pure.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/restrict.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/warning.h
+gc_hook.o: $(hdrdir)/ruby/internal/attr/weakref.h
+gc_hook.o: $(hdrdir)/ruby/internal/cast.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_is.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+gc_hook.o: $(hdrdir)/ruby/internal/compiler_since.h
+gc_hook.o: $(hdrdir)/ruby/internal/config.h
+gc_hook.o: $(hdrdir)/ruby/internal/constant_p.h
+gc_hook.o: $(hdrdir)/ruby/internal/core.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rarray.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rbasic.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rbignum.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rclass.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rdata.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rfile.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rhash.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/robject.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rregexp.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rstring.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rstruct.h
+gc_hook.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+gc_hook.o: $(hdrdir)/ruby/internal/ctype.h
+gc_hook.o: $(hdrdir)/ruby/internal/dllexport.h
+gc_hook.o: $(hdrdir)/ruby/internal/dosish.h
+gc_hook.o: $(hdrdir)/ruby/internal/error.h
+gc_hook.o: $(hdrdir)/ruby/internal/eval.h
+gc_hook.o: $(hdrdir)/ruby/internal/event.h
+gc_hook.o: $(hdrdir)/ruby/internal/fl_type.h
+gc_hook.o: $(hdrdir)/ruby/internal/gc.h
+gc_hook.o: $(hdrdir)/ruby/internal/glob.h
+gc_hook.o: $(hdrdir)/ruby/internal/globals.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/attribute.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/builtin.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/extension.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/feature.h
+gc_hook.o: $(hdrdir)/ruby/internal/has/warning.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/array.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/bignum.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/class.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/compar.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/complex.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/cont.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/dir.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/enum.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/error.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/eval.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/file.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/gc.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/hash.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/io.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/load.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/marshal.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/numeric.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/object.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/parse.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/proc.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/process.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/random.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/range.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/rational.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/re.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/ruby.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/select.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/signal.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/string.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/struct.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/thread.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/time.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/variable.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/vm.h
+gc_hook.o: $(hdrdir)/ruby/internal/interpreter.h
+gc_hook.o: $(hdrdir)/ruby/internal/iterator.h
+gc_hook.o: $(hdrdir)/ruby/internal/memory.h
+gc_hook.o: $(hdrdir)/ruby/internal/method.h
+gc_hook.o: $(hdrdir)/ruby/internal/module.h
+gc_hook.o: $(hdrdir)/ruby/internal/newobj.h
+gc_hook.o: $(hdrdir)/ruby/internal/rgengc.h
+gc_hook.o: $(hdrdir)/ruby/internal/scan_args.h
+gc_hook.o: $(hdrdir)/ruby/internal/special_consts.h
+gc_hook.o: $(hdrdir)/ruby/internal/static_assert.h
+gc_hook.o: $(hdrdir)/ruby/internal/stdalign.h
+gc_hook.o: $(hdrdir)/ruby/internal/stdbool.h
+gc_hook.o: $(hdrdir)/ruby/internal/symbol.h
+gc_hook.o: $(hdrdir)/ruby/internal/token_paste.h
+gc_hook.o: $(hdrdir)/ruby/internal/value.h
+gc_hook.o: $(hdrdir)/ruby/internal/value_type.h
+gc_hook.o: $(hdrdir)/ruby/internal/variable.h
+gc_hook.o: $(hdrdir)/ruby/internal/warning_push.h
+gc_hook.o: $(hdrdir)/ruby/internal/xmalloc.h
+gc_hook.o: $(hdrdir)/ruby/assert.h
gc_hook.o: $(hdrdir)/ruby/backward.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/assume.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/attributes.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/bool.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/inttypes.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/limits.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/long_long.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/stdalign.h
+gc_hook.o: $(hdrdir)/ruby/backward/2/stdarg.h
gc_hook.o: $(hdrdir)/ruby/debug.h
gc_hook.o: $(hdrdir)/ruby/defines.h
gc_hook.o: $(hdrdir)/ruby/intern.h
@@ -12,7 +162,157 @@ gc_hook.o: $(hdrdir)/ruby/subst.h
gc_hook.o: gc_hook.c
tracepoint.o: $(RUBY_EXTCONF_H)
tracepoint.o: $(arch_hdrdir)/ruby/config.h
+tracepoint.o: $(hdrdir)/ruby/internal/anyargs.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+tracepoint.o: $(hdrdir)/ruby/internal/assume.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/artificial.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/cold.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/const.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/error.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/format.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/noalias.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/noinline.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/pure.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/restrict.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/warning.h
+tracepoint.o: $(hdrdir)/ruby/internal/attr/weakref.h
+tracepoint.o: $(hdrdir)/ruby/internal/cast.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_is.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+tracepoint.o: $(hdrdir)/ruby/internal/compiler_since.h
+tracepoint.o: $(hdrdir)/ruby/internal/config.h
+tracepoint.o: $(hdrdir)/ruby/internal/constant_p.h
+tracepoint.o: $(hdrdir)/ruby/internal/core.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rarray.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rbasic.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rbignum.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rclass.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rdata.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rfile.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rhash.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/robject.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rregexp.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rstring.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rstruct.h
+tracepoint.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+tracepoint.o: $(hdrdir)/ruby/internal/ctype.h
+tracepoint.o: $(hdrdir)/ruby/internal/dllexport.h
+tracepoint.o: $(hdrdir)/ruby/internal/dosish.h
+tracepoint.o: $(hdrdir)/ruby/internal/error.h
+tracepoint.o: $(hdrdir)/ruby/internal/eval.h
+tracepoint.o: $(hdrdir)/ruby/internal/event.h
+tracepoint.o: $(hdrdir)/ruby/internal/fl_type.h
+tracepoint.o: $(hdrdir)/ruby/internal/gc.h
+tracepoint.o: $(hdrdir)/ruby/internal/glob.h
+tracepoint.o: $(hdrdir)/ruby/internal/globals.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/attribute.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/builtin.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/extension.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/feature.h
+tracepoint.o: $(hdrdir)/ruby/internal/has/warning.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/array.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/bignum.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/class.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/compar.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/complex.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/cont.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/dir.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/enum.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/error.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/eval.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/file.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/gc.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/hash.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/io.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/load.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/marshal.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/numeric.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/object.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/parse.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/proc.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/process.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/random.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/range.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/rational.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/re.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/ruby.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/select.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/signal.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/string.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/struct.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/thread.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/time.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/variable.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/vm.h
+tracepoint.o: $(hdrdir)/ruby/internal/interpreter.h
+tracepoint.o: $(hdrdir)/ruby/internal/iterator.h
+tracepoint.o: $(hdrdir)/ruby/internal/memory.h
+tracepoint.o: $(hdrdir)/ruby/internal/method.h
+tracepoint.o: $(hdrdir)/ruby/internal/module.h
+tracepoint.o: $(hdrdir)/ruby/internal/newobj.h
+tracepoint.o: $(hdrdir)/ruby/internal/rgengc.h
+tracepoint.o: $(hdrdir)/ruby/internal/scan_args.h
+tracepoint.o: $(hdrdir)/ruby/internal/special_consts.h
+tracepoint.o: $(hdrdir)/ruby/internal/static_assert.h
+tracepoint.o: $(hdrdir)/ruby/internal/stdalign.h
+tracepoint.o: $(hdrdir)/ruby/internal/stdbool.h
+tracepoint.o: $(hdrdir)/ruby/internal/symbol.h
+tracepoint.o: $(hdrdir)/ruby/internal/token_paste.h
+tracepoint.o: $(hdrdir)/ruby/internal/value.h
+tracepoint.o: $(hdrdir)/ruby/internal/value_type.h
+tracepoint.o: $(hdrdir)/ruby/internal/variable.h
+tracepoint.o: $(hdrdir)/ruby/internal/warning_push.h
+tracepoint.o: $(hdrdir)/ruby/internal/xmalloc.h
+tracepoint.o: $(hdrdir)/ruby/assert.h
tracepoint.o: $(hdrdir)/ruby/backward.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/assume.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/attributes.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/bool.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/inttypes.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/limits.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/long_long.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/stdalign.h
+tracepoint.o: $(hdrdir)/ruby/backward/2/stdarg.h
tracepoint.o: $(hdrdir)/ruby/debug.h
tracepoint.o: $(hdrdir)/ruby/defines.h
tracepoint.o: $(hdrdir)/ruby/intern.h
diff --git a/ext/-test-/tracepoint/gc_hook.c b/ext/-test-/tracepoint/gc_hook.c
index 6d8485ecb1..5fd46fa518 100644
--- a/ext/-test-/tracepoint/gc_hook.c
+++ b/ext/-test-/tracepoint/gc_hook.c
@@ -4,7 +4,7 @@
static int invoking; /* TODO: should not be global variable */
static VALUE
-invoke_proc_ensure(void *dmy)
+invoke_proc_ensure(VALUE _)
{
invoking = 0;
return Qnil;
@@ -42,14 +42,12 @@ set_gc_hook(VALUE module, VALUE proc, rb_event_flag_t event, const char *tp_str,
{
VALUE tpval;
ID tp_key = rb_intern(tp_str);
- ID proc_key = rb_intern(proc_str);
/* disable previous keys */
if (rb_ivar_defined(module, tp_key) != 0 &&
RTEST(tpval = rb_ivar_get(module, tp_key))) {
rb_tracepoint_disable(tpval);
rb_ivar_set(module, tp_key, Qnil);
- rb_ivar_set(module, proc_key, Qnil);
}
if (RTEST(proc)) {
@@ -59,7 +57,6 @@ set_gc_hook(VALUE module, VALUE proc, rb_event_flag_t event, const char *tp_str,
tpval = rb_tracepoint_new(0, event, gc_start_end_i, (void *)proc);
rb_ivar_set(module, tp_key, tpval);
- rb_ivar_set(module, proc_key, proc); /* GC guard */
rb_tracepoint_enable(tpval);
}
@@ -73,8 +70,16 @@ set_after_gc_start(VALUE module, VALUE proc)
"__set_after_gc_start_tpval__", "__set_after_gc_start_proc__");
}
+static VALUE
+start_after_gc_exit(VALUE module, VALUE proc)
+{
+ return set_gc_hook(module, proc, RUBY_INTERNAL_EVENT_GC_EXIT,
+ "__set_after_gc_exit_tpval__", "__set_after_gc_exit_proc__");
+}
+
void
Init_gc_hook(VALUE module)
{
rb_define_module_function(module, "after_gc_start_hook=", set_after_gc_start, 1);
+ rb_define_module_function(module, "after_gc_exit_hook=", start_after_gc_exit, 1);
}
diff --git a/ext/-test-/typeddata/depend b/ext/-test-/typeddata/depend
new file mode 100644
index 0000000000..8fe35a8192
--- /dev/null
+++ b/ext/-test-/typeddata/depend
@@ -0,0 +1,163 @@
+# AUTOGENERATED DEPENDENCIES START
+typeddata.o: $(RUBY_EXTCONF_H)
+typeddata.o: $(arch_hdrdir)/ruby/config.h
+typeddata.o: $(hdrdir)/ruby.h
+typeddata.o: $(hdrdir)/ruby/internal/anyargs.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+typeddata.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+typeddata.o: $(hdrdir)/ruby/internal/assume.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/artificial.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/cold.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/const.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/error.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/format.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/noalias.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/noinline.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/pure.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/restrict.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/warning.h
+typeddata.o: $(hdrdir)/ruby/internal/attr/weakref.h
+typeddata.o: $(hdrdir)/ruby/internal/cast.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_is.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+typeddata.o: $(hdrdir)/ruby/internal/compiler_since.h
+typeddata.o: $(hdrdir)/ruby/internal/config.h
+typeddata.o: $(hdrdir)/ruby/internal/constant_p.h
+typeddata.o: $(hdrdir)/ruby/internal/core.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rarray.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rbasic.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rbignum.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rclass.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rdata.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rfile.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rhash.h
+typeddata.o: $(hdrdir)/ruby/internal/core/robject.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rregexp.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rstring.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rstruct.h
+typeddata.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+typeddata.o: $(hdrdir)/ruby/internal/ctype.h
+typeddata.o: $(hdrdir)/ruby/internal/dllexport.h
+typeddata.o: $(hdrdir)/ruby/internal/dosish.h
+typeddata.o: $(hdrdir)/ruby/internal/error.h
+typeddata.o: $(hdrdir)/ruby/internal/eval.h
+typeddata.o: $(hdrdir)/ruby/internal/event.h
+typeddata.o: $(hdrdir)/ruby/internal/fl_type.h
+typeddata.o: $(hdrdir)/ruby/internal/gc.h
+typeddata.o: $(hdrdir)/ruby/internal/glob.h
+typeddata.o: $(hdrdir)/ruby/internal/globals.h
+typeddata.o: $(hdrdir)/ruby/internal/has/attribute.h
+typeddata.o: $(hdrdir)/ruby/internal/has/builtin.h
+typeddata.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+typeddata.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+typeddata.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+typeddata.o: $(hdrdir)/ruby/internal/has/extension.h
+typeddata.o: $(hdrdir)/ruby/internal/has/feature.h
+typeddata.o: $(hdrdir)/ruby/internal/has/warning.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/array.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/bignum.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/class.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/compar.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/complex.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/cont.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/dir.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/enum.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/error.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/eval.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/file.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/gc.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/hash.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/io.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/load.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/marshal.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/numeric.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/object.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/parse.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/proc.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/process.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/random.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/range.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/rational.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/re.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/ruby.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/select.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/signal.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/string.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/struct.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/thread.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/time.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/variable.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/vm.h
+typeddata.o: $(hdrdir)/ruby/internal/interpreter.h
+typeddata.o: $(hdrdir)/ruby/internal/iterator.h
+typeddata.o: $(hdrdir)/ruby/internal/memory.h
+typeddata.o: $(hdrdir)/ruby/internal/method.h
+typeddata.o: $(hdrdir)/ruby/internal/module.h
+typeddata.o: $(hdrdir)/ruby/internal/newobj.h
+typeddata.o: $(hdrdir)/ruby/internal/rgengc.h
+typeddata.o: $(hdrdir)/ruby/internal/scan_args.h
+typeddata.o: $(hdrdir)/ruby/internal/special_consts.h
+typeddata.o: $(hdrdir)/ruby/internal/static_assert.h
+typeddata.o: $(hdrdir)/ruby/internal/stdalign.h
+typeddata.o: $(hdrdir)/ruby/internal/stdbool.h
+typeddata.o: $(hdrdir)/ruby/internal/symbol.h
+typeddata.o: $(hdrdir)/ruby/internal/token_paste.h
+typeddata.o: $(hdrdir)/ruby/internal/value.h
+typeddata.o: $(hdrdir)/ruby/internal/value_type.h
+typeddata.o: $(hdrdir)/ruby/internal/variable.h
+typeddata.o: $(hdrdir)/ruby/internal/warning_push.h
+typeddata.o: $(hdrdir)/ruby/internal/xmalloc.h
+typeddata.o: $(hdrdir)/ruby/assert.h
+typeddata.o: $(hdrdir)/ruby/backward.h
+typeddata.o: $(hdrdir)/ruby/backward/2/assume.h
+typeddata.o: $(hdrdir)/ruby/backward/2/attributes.h
+typeddata.o: $(hdrdir)/ruby/backward/2/bool.h
+typeddata.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+typeddata.o: $(hdrdir)/ruby/backward/2/inttypes.h
+typeddata.o: $(hdrdir)/ruby/backward/2/limits.h
+typeddata.o: $(hdrdir)/ruby/backward/2/long_long.h
+typeddata.o: $(hdrdir)/ruby/backward/2/stdalign.h
+typeddata.o: $(hdrdir)/ruby/backward/2/stdarg.h
+typeddata.o: $(hdrdir)/ruby/defines.h
+typeddata.o: $(hdrdir)/ruby/intern.h
+typeddata.o: $(hdrdir)/ruby/missing.h
+typeddata.o: $(hdrdir)/ruby/ruby.h
+typeddata.o: $(hdrdir)/ruby/st.h
+typeddata.o: $(hdrdir)/ruby/subst.h
+typeddata.o: typeddata.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/typeddata/typeddata.c b/ext/-test-/typeddata/typeddata.c
index ae060960cd..2adfd56ae8 100644
--- a/ext/-test-/typeddata/typeddata.c
+++ b/ext/-test-/typeddata/typeddata.c
@@ -2,7 +2,7 @@
static const rb_data_type_t test_data = {
"typed_data",
- {NULL, ruby_xfree, NULL},
+ {0, ruby_xfree, 0},
NULL, NULL,
0/* deferred free */,
};
@@ -37,7 +37,7 @@ void
Init_typeddata(void)
{
VALUE mBug = rb_define_module("Bug");
- VALUE klass = rb_define_class_under(mBug, "TypedData", rb_cData);
+ VALUE klass = rb_define_class_under(mBug, "TypedData", rb_cObject);
rb_define_alloc_func(klass, test_alloc);
rb_define_singleton_method(klass, "check", test_check, 1);
rb_define_singleton_method(klass, "make", test_make, 1);
diff --git a/ext/-test-/vm/depend b/ext/-test-/vm/depend
index dd56dd0e0d..5800c3b464 100644
--- a/ext/-test-/vm/depend
+++ b/ext/-test-/vm/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
at_exit.o: $(RUBY_EXTCONF_H)
at_exit.o: $(arch_hdrdir)/ruby/config.h
+at_exit.o: $(hdrdir)/ruby/internal/anyargs.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+at_exit.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+at_exit.o: $(hdrdir)/ruby/internal/assume.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/artificial.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/cold.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/const.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/error.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/format.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/noalias.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/noinline.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/pure.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/restrict.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/warning.h
+at_exit.o: $(hdrdir)/ruby/internal/attr/weakref.h
+at_exit.o: $(hdrdir)/ruby/internal/cast.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_is.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+at_exit.o: $(hdrdir)/ruby/internal/compiler_since.h
+at_exit.o: $(hdrdir)/ruby/internal/config.h
+at_exit.o: $(hdrdir)/ruby/internal/constant_p.h
+at_exit.o: $(hdrdir)/ruby/internal/core.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rarray.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rbasic.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rbignum.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rclass.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rdata.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rfile.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rhash.h
+at_exit.o: $(hdrdir)/ruby/internal/core/robject.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rregexp.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rstring.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rstruct.h
+at_exit.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+at_exit.o: $(hdrdir)/ruby/internal/ctype.h
+at_exit.o: $(hdrdir)/ruby/internal/dllexport.h
+at_exit.o: $(hdrdir)/ruby/internal/dosish.h
+at_exit.o: $(hdrdir)/ruby/internal/error.h
+at_exit.o: $(hdrdir)/ruby/internal/eval.h
+at_exit.o: $(hdrdir)/ruby/internal/event.h
+at_exit.o: $(hdrdir)/ruby/internal/fl_type.h
+at_exit.o: $(hdrdir)/ruby/internal/gc.h
+at_exit.o: $(hdrdir)/ruby/internal/glob.h
+at_exit.o: $(hdrdir)/ruby/internal/globals.h
+at_exit.o: $(hdrdir)/ruby/internal/has/attribute.h
+at_exit.o: $(hdrdir)/ruby/internal/has/builtin.h
+at_exit.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+at_exit.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+at_exit.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+at_exit.o: $(hdrdir)/ruby/internal/has/extension.h
+at_exit.o: $(hdrdir)/ruby/internal/has/feature.h
+at_exit.o: $(hdrdir)/ruby/internal/has/warning.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/array.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/bignum.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/class.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/compar.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/complex.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/cont.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/dir.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/enum.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/error.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/eval.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/file.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/gc.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/hash.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/io.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/load.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/marshal.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/numeric.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/object.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/parse.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/proc.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/process.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/random.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/range.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/rational.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/re.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/ruby.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/select.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/signal.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/string.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/struct.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/thread.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/time.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/variable.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/vm.h
+at_exit.o: $(hdrdir)/ruby/internal/interpreter.h
+at_exit.o: $(hdrdir)/ruby/internal/iterator.h
+at_exit.o: $(hdrdir)/ruby/internal/memory.h
+at_exit.o: $(hdrdir)/ruby/internal/method.h
+at_exit.o: $(hdrdir)/ruby/internal/module.h
+at_exit.o: $(hdrdir)/ruby/internal/newobj.h
+at_exit.o: $(hdrdir)/ruby/internal/rgengc.h
+at_exit.o: $(hdrdir)/ruby/internal/scan_args.h
+at_exit.o: $(hdrdir)/ruby/internal/special_consts.h
+at_exit.o: $(hdrdir)/ruby/internal/static_assert.h
+at_exit.o: $(hdrdir)/ruby/internal/stdalign.h
+at_exit.o: $(hdrdir)/ruby/internal/stdbool.h
+at_exit.o: $(hdrdir)/ruby/internal/symbol.h
+at_exit.o: $(hdrdir)/ruby/internal/token_paste.h
+at_exit.o: $(hdrdir)/ruby/internal/value.h
+at_exit.o: $(hdrdir)/ruby/internal/value_type.h
+at_exit.o: $(hdrdir)/ruby/internal/variable.h
+at_exit.o: $(hdrdir)/ruby/internal/warning_push.h
+at_exit.o: $(hdrdir)/ruby/internal/xmalloc.h
+at_exit.o: $(hdrdir)/ruby/assert.h
at_exit.o: $(hdrdir)/ruby/backward.h
+at_exit.o: $(hdrdir)/ruby/backward/2/assume.h
+at_exit.o: $(hdrdir)/ruby/backward/2/attributes.h
+at_exit.o: $(hdrdir)/ruby/backward/2/bool.h
+at_exit.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+at_exit.o: $(hdrdir)/ruby/backward/2/inttypes.h
+at_exit.o: $(hdrdir)/ruby/backward/2/limits.h
+at_exit.o: $(hdrdir)/ruby/backward/2/long_long.h
+at_exit.o: $(hdrdir)/ruby/backward/2/stdalign.h
+at_exit.o: $(hdrdir)/ruby/backward/2/stdarg.h
at_exit.o: $(hdrdir)/ruby/defines.h
at_exit.o: $(hdrdir)/ruby/intern.h
at_exit.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/-test-/wait_for_single_fd/depend b/ext/-test-/wait_for_single_fd/depend
index edd2f88dcf..641e144017 100644
--- a/ext/-test-/wait_for_single_fd/depend
+++ b/ext/-test-/wait_for_single_fd/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
wait_for_single_fd.o: $(RUBY_EXTCONF_H)
wait_for_single_fd.o: $(arch_hdrdir)/ruby/config.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/anyargs.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/assume.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/artificial.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/cold.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/const.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/error.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/format.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noalias.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noinline.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/pure.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/restrict.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/warning.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/weakref.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/cast.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_since.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/config.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/constant_p.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rarray.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rbasic.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rbignum.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rclass.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rdata.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rfile.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rhash.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/robject.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rregexp.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rstring.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rstruct.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/ctype.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/dllexport.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/dosish.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/error.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/eval.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/event.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/fl_type.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/gc.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/glob.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/globals.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/attribute.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/builtin.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/extension.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/feature.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/warning.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/array.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/bignum.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/class.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/compar.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/complex.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/cont.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/dir.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/enum.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/error.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/eval.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/file.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/gc.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/hash.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/io.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/load.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/marshal.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/numeric.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/object.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/parse.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/proc.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/process.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/random.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/range.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/rational.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/re.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/ruby.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/select.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/signal.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/string.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/struct.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/thread.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/time.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/variable.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/vm.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/interpreter.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/iterator.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/memory.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/method.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/module.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/newobj.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/rgengc.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/scan_args.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/special_consts.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/static_assert.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/stdalign.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/stdbool.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/symbol.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/token_paste.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/value.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/value_type.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/variable.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/warning_push.h
+wait_for_single_fd.o: $(hdrdir)/ruby/internal/xmalloc.h
+wait_for_single_fd.o: $(hdrdir)/ruby/assert.h
wait_for_single_fd.o: $(hdrdir)/ruby/backward.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/assume.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/attributes.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/bool.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/inttypes.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/limits.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/long_long.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/stdalign.h
+wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/stdarg.h
wait_for_single_fd.o: $(hdrdir)/ruby/defines.h
wait_for_single_fd.o: $(hdrdir)/ruby/encoding.h
wait_for_single_fd.o: $(hdrdir)/ruby/intern.h
diff --git a/ext/-test-/wait_for_single_fd/extconf.rb b/ext/-test-/wait_for_single_fd/extconf.rb
index 931662c040..c27100fb42 100644
--- a/ext/-test-/wait_for_single_fd/extconf.rb
+++ b/ext/-test-/wait_for_single_fd/extconf.rb
@@ -1,2 +1,8 @@
# frozen_string_literal: false
+case RUBY_PLATFORM when /mingw/ then
+ # skip
+else
+ headers = %w(sys/types.h sys/time.h sys/event.h).select { |h| have_header(h) }
+ have_func('kqueue', headers)
+end
create_makefile("-test-/wait_for_single_fd")
diff --git a/ext/-test-/wait_for_single_fd/wait_for_single_fd.c b/ext/-test-/wait_for_single_fd/wait_for_single_fd.c
index d406724a3f..b8a33979bc 100644
--- a/ext/-test-/wait_for_single_fd/wait_for_single_fd.c
+++ b/ext/-test-/wait_for_single_fd/wait_for_single_fd.c
@@ -19,6 +19,67 @@ wait_for_single_fd(VALUE ign, VALUE fd, VALUE events, VALUE timeout)
return INT2NUM(rc);
}
+#ifdef HAVE_KQUEUE
+/* ensure rb_wait_for_single_fd works on kqueue descriptors */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/event.h>
+static VALUE
+kqueue_test_wait(VALUE klass)
+{
+ int kqfd = -1;
+ int p[2] = { -1, -1 };
+ struct timeval tv = { 0, 0 };
+ const struct timespec ts = { 1, 0 };
+ struct kevent kev;
+ const char *msg;
+ VALUE ret = Qfalse;
+ int e = 0;
+ int n;
+
+ msg = "pipe";
+ if (rb_cloexec_pipe(p) < 0) goto err;
+
+ msg = "kqueue";
+ kqfd = kqueue();
+ if (kqfd < 0) goto err;
+
+ n = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN, &tv);
+ if (n != 0) {
+ msg = "spurious wakeup";
+ errno = 0;
+ goto err;
+ }
+
+ msg = "write";
+ if (write(p[1], "", 1) < 0) goto err;
+
+ EV_SET(&kev, p[0], EVFILT_READ, EV_ADD, 0, 0, 0);
+
+ msg = "kevent";
+ n = kevent(kqfd, &kev, 1, &kev, 1, &ts);
+ if (n < 0) goto err;
+ msg = NULL;
+ if (n == 1) {
+ n = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN, &tv);
+ ret = INT2NUM(n);
+ }
+ else {
+ rb_warn("kevent did not return readiness");
+ }
+err:
+ if (msg) e = errno;
+ if (p[0] >= 0) close(p[0]);
+ if (p[1] >= 0) close(p[1]);
+ if (kqfd >= 0) close(kqfd);
+ if (msg) {
+ if (e) rb_syserr_fail(e, msg);
+ rb_raise(rb_eRuntimeError, "%s", msg);
+ }
+ return ret;
+}
+#endif /* HAVE_KQUEUE */
+
void
Init_wait_for_single_fd(void)
{
@@ -27,4 +88,7 @@ Init_wait_for_single_fd(void)
rb_define_const(rb_cObject, "RB_WAITFD_PRI", INT2NUM(RB_WAITFD_PRI));
rb_define_singleton_method(rb_cIO, "wait_for_single_fd",
wait_for_single_fd, 3);
+#ifdef HAVE_KQUEUE
+ rb_define_singleton_method(rb_cIO, "kqueue_test_wait", kqueue_test_wait, 0);
+#endif
}
diff --git a/ext/-test-/win32/console/attribute.c b/ext/-test-/win32/console/attribute.c
index 6d706fbfe7..a5f80fcaff 100644
--- a/ext/-test-/win32/console/attribute.c
+++ b/ext/-test-/win32/console/attribute.c
@@ -61,4 +61,9 @@ Init_attribute(VALUE m)
rb_define_const(m, "BACKGROUND_GREEN", INT2FIX(BACKGROUND_GREEN));
rb_define_const(m, "BACKGROUND_RED", INT2FIX(BACKGROUND_RED));
rb_define_const(m, "BACKGROUND_INTENSITY", INT2FIX(BACKGROUND_INTENSITY));
+
+#ifndef COMMON_LVB_REVERSE_VIDEO
+#define COMMON_LVB_REVERSE_VIDEO 0x4000
+#endif
+ rb_define_const(m, "REVERSE_VIDEO", INT2FIX(COMMON_LVB_REVERSE_VIDEO));
}
diff --git a/ext/.document b/ext/.document
index 6a491576a1..aeb40c60fb 100644
--- a/ext/.document
+++ b/ext/.document
@@ -2,9 +2,15 @@
bigdecimal/bigdecimal.c
bigdecimal/lib
+cgi/escape/escape.c
continuation/continuation.c
coverage/coverage.c
+coverage/lib
date/date_core.c
+date/date_parse.c
+date/date_strftime.c
+date/date_strptime.c
+date/lib
dbm/dbm.c
digest/bubblebabble/bubblebabble.c
digest/digest.c
@@ -13,6 +19,7 @@ digest/md5/md5init.c
digest/rmd160/rmd160init.c
digest/sha1/sha1init.c
digest/sha2/sha2init.c
+digest/sha2/lib
etc/etc.c
fcntl/fcntl.c
fiber/fiber.c
@@ -20,21 +27,26 @@ fiddle/closure.c
fiddle/conversions.c
fiddle/fiddle.c
fiddle/function.c
+fiddle/pinned.c
fiddle/pointer.c
fiddle/handle.c
fiddle/lib
gdbm/gdbm.c
io/console/console.c
+io/console/lib
io/nonblock/nonblock.c
io/wait/wait.c
json/generator/generator.c
json/lib
json/parser/parser.c
+monitor/lib
+monitor/monitor.c
nkf/lib
nkf/nkf.c
objspace/objspace.c
objspace/objspace_dump.c
objspace/object_tracing.c
+objspace/lib
openssl/lib
openssl/ossl.c
openssl/ossl_asn1.c
@@ -58,6 +70,7 @@ openssl/ossl_pkey_rsa.c
openssl/ossl_rand.c
openssl/ossl_ssl.c
openssl/ossl_ssl_session.c
+openssl/ossl_ts.c
openssl/ossl_x509.c
openssl/ossl_x509attr.c
openssl/ossl_x509cert.c
@@ -78,14 +91,16 @@ psych/psych_yaml_tree.c
pty/lib
pty/pty.c
racc/cparse/cparse.c
+rbconfig/sizeof/*.c
readline/readline.c
ripper/lib
-sdbm/init.c
socket
stringio/stringio.c
strscan/strscan.c
syslog/syslog.c
syslog/lib
+win32/lib
+win32/resolv/*.c
win32ole/lib
win32ole/*.c
zlib/zlib.c
diff --git a/ext/Setup b/ext/Setup
index ac79c86f84..0376e2fc6c 100644
--- a/ext/Setup
+++ b/ext/Setup
@@ -33,7 +33,6 @@
#rbconfig/sizeof
#readline
#ripper
-#sdbm
#socket
#stringio
#strscan
diff --git a/ext/Setup.atheos b/ext/Setup.atheos
index 90a7d01348..3f6263b1e2 100644
--- a/ext/Setup.atheos
+++ b/ext/Setup.atheos
@@ -20,7 +20,6 @@ pty
racc/parse
readline
ripper
-sdbm
socket
stringio
strscan
diff --git a/ext/Setup.nacl b/ext/Setup.nacl
deleted file mode 100644
index 79ca53da4b..0000000000
--- a/ext/Setup.nacl
+++ /dev/null
@@ -1,42 +0,0 @@
-# #option nodynamic
-#
-# #Win32API
-# bigdecimal
-# cgi/escape
-# continuation
-# coverage
-# date
-# #dbm
-# digest/bubblebabble
-# digest
-# digest/md5
-# digest/rmd160
-# digest/sha1
-# digest/sha2
-# etc
-# fcntl
-# fiber
-# #fiddle
-# #gdbm
-# #iconv
-# io/console
-# io/nonblock
-# io/wait
-# #json
-# json/generator
-# json/parser
-# nkf
-# objspace
-# #openssl
-# pathname
-# #psych
-# #pty
-# racc/cparse
-# #readline
-# ripper
-# #sdbm
-# #socket
-# stringio
-# strscan
-# #syslog
-# #zlib
diff --git a/ext/Setup.nt b/ext/Setup.nt
index fb5989b87f..dc36aa8688 100644
--- a/ext/Setup.nt
+++ b/ext/Setup.nt
@@ -21,7 +21,6 @@ nkf
racc/cparse
#readline
#ripper
-sdbm
socket
stringio
strscan
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index e9e6af7784..7fdf40126e 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -14,6 +14,7 @@
#include "ruby/util.h"
#ifndef BIGDECIMAL_DEBUG
+# undef NDEBUG
# define NDEBUG
#endif
#include <assert.h>
@@ -24,7 +25,6 @@
#include <string.h>
#include <errno.h>
#include <math.h>
-#include "math.h"
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
@@ -77,7 +77,7 @@ static ID id_half;
#define BASE1 (BASE/10)
#ifndef DBLE_FIG
-#define DBLE_FIG (DBL_DIG+1) /* figure of double */
+#define DBLE_FIG rmpd_double_figures() /* figure of double */
#endif
#ifndef RRATIONAL_ZERO_P
@@ -110,7 +110,7 @@ rb_rational_num(VALUE rat)
#ifdef HAVE_TYPE_STRUCT_RRATIONAL
return RRATIONAL(rat)->num;
#else
- return rb_funcall(rat, rb_intern("numerator"));
+ return rb_funcall(rat, rb_intern("numerator"), 0);
#endif
}
#endif
@@ -122,7 +122,31 @@ rb_rational_den(VALUE rat)
#ifdef HAVE_TYPE_STRUCT_RRATIONAL
return RRATIONAL(rat)->den;
#else
- return rb_funcall(rat, rb_intern("denominator"));
+ return rb_funcall(rat, rb_intern("denominator"), 0);
+#endif
+}
+#endif
+
+#ifndef HAVE_RB_COMPLEX_REAL
+static inline VALUE
+rb_complex_real(VALUE cmp)
+{
+#ifdef HAVE_TYPE_STRUCT_RCOMPLEX
+ return RCOMPLEX(cmp)->real;
+#else
+ return rb_funcall(cmp, rb_intern("real"), 0);
+#endif
+}
+#endif
+
+#ifndef HAVE_RB_COMPLEX_IMAG
+static inline VALUE
+rb_complex_imag(VALUE cmp)
+{
+#ifdef HAVE_TYPE_STRUCT_RCOMPLEX
+ return RCOMPLEX(cmp)->imag;
+#else
+ return rb_funcall(cmp, rb_intern("imag"), 0);
#endif
}
#endif
@@ -136,20 +160,6 @@ rb_rational_den(VALUE rat)
#define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f)
/*
- * Returns the BigDecimal version number.
- */
-static VALUE
-BigDecimal_version(VALUE self)
-{
- /*
- * 1.0.0: Ruby 1.8.0
- * 1.0.1: Ruby 1.8.1
- * 1.1.0: Ruby 1.9.3
- */
- return rb_str_new2("1.1.0");
-}
-
-/*
* VP routines used in BigDecimal part
*/
static unsigned short VpGetException(void);
@@ -179,11 +189,16 @@ BigDecimal_memsize(const void *ptr)
return (sizeof(*pv) + pv->MaxPrec * sizeof(BDIGIT));
}
+#ifndef HAVE_RB_EXT_RACTOR_SAFE
+# undef RUBY_TYPED_FROZEN_SHAREABLE
+# define RUBY_TYPED_FROZEN_SHAREABLE 0
+#endif
+
static const rb_data_type_t BigDecimal_data_type = {
"BigDecimal",
{ 0, BigDecimal_delete, BigDecimal_memsize, },
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE
#endif
};
@@ -242,7 +257,7 @@ again:
switch(TYPE(v)) {
case T_FLOAT:
if (prec < 0) goto unable_to_coerce_without_prec;
- if (prec > DBL_DIG+1) goto SomeOneMayDoIt;
+ if (prec > (long)DBLE_FIG) goto SomeOneMayDoIt;
d = RFLOAT_VALUE(v);
if (!isfinite(d)) {
pv = VpCreateRbObject(1, NULL);
@@ -290,7 +305,6 @@ again:
#ifdef ENABLE_NUMERIC_STRING
case T_STRING:
StringValueCStr(v);
- rb_check_safe_obj(v);
return VpCreateRbObject(RSTRING_LEN(v) + VpBaseFig() + 1,
RSTRING_PTR(v));
#endif /* ENABLE_NUMERIC_STRING */
@@ -341,11 +355,13 @@ BigDecimal_double_fig(VALUE self)
/* call-seq:
* big_decimal.precs -> array
*
- * Returns an Array of two Integer values.
+ * Returns an Array of two Integer values that represent platform-dependent
+ * internal storage properties.
*
- * The first value is the current number of significant digits in the
- * BigDecimal. The second value is the maximum number of significant digits
- * for the BigDecimal.
+ * This method is deprecated and will be removed in the future.
+ * Instead, use BigDecimal#n_significant_digits for obtaining the number of
+ * significant digits in scientific notation, and BigDecimal#precision for
+ * obtaining the number of digits in decimal notation.
*
* BigDecimal('5').precs #=> [9, 18]
*/
@@ -357,13 +373,110 @@ BigDecimal_prec(VALUE self)
Real *p;
VALUE obj;
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
+ "BigDecimal#precs is deprecated and will be removed in the future; "
+ "use BigDecimal#precision instead.");
+
GUARD_OBJ(p, GetVpValue(self, 1));
- obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()),
- INT2NUM(p->MaxPrec*VpBaseFig()));
+ obj = rb_assoc_new(SIZET2NUM(p->Prec*VpBaseFig()),
+ SIZET2NUM(p->MaxPrec*VpBaseFig()));
return obj;
}
/*
+ * call-seq:
+ * big_decimal.precision -> intreger
+ *
+ * Returns the number of decimal digits in this number.
+ *
+ * Example:
+ *
+ * BigDecimal("0").precision # => 0
+ * BigDecimal("1").precision # => 1
+ * BigDecimal("-1e20").precision # => 21
+ * BigDecimal("1e-20").precision # => 20
+ * BigDecimal("Infinity").precision # => 0
+ * BigDecimal("-Infinity").precision # => 0
+ * BigDecimal("NaN").precision # => 0
+ */
+static VALUE
+BigDecimal_precision(VALUE self)
+{
+ ENTER(1);
+
+ Real *p;
+ GUARD_OBJ(p, GetVpValue(self, 1));
+
+ /*
+ * The most significant digit is frac[0], and the least significant digit is frac[Prec-1].
+ * When the exponent is zero, the decimal point is located just before frac[0].
+ * When the exponent is negative, the decimal point moves to leftward.
+ * Conversely, when the exponent is positive, the decimal point moves to rightward.
+ *
+ * | frac[0] frac[1] frac[2] . frac[3] frac[4] ... frac[Prec-1]
+ * |------------------------> exponent == 3
+ */
+
+ ssize_t ex = p->exponent;
+ ssize_t precision = 0;
+ if (ex < 0) {
+ precision = (-ex + 1) * BASE_FIG; /* 1 is for p->frac[0] */
+ ex = 0;
+ }
+ else if (p->Prec > 0) {
+ BDIGIT x = p->frac[0];
+ for (precision = 0; x > 0; x /= 10) {
+ ++precision;
+ }
+ }
+
+ if (ex > (ssize_t)p->Prec) {
+ precision += (ex - 1) * BASE_FIG;
+ }
+ else if (p->Prec > 0) {
+ ssize_t n = (ssize_t)p->Prec - 1;
+ while (n > 0 && p->frac[n] == 0) --n;
+
+ precision += n * BASE_FIG;
+
+ if (ex < (ssize_t)p->Prec) {
+ BDIGIT x = p->frac[n];
+ for (; x > 0 && x % 10 == 0; x /= 10) {
+ --precision;
+ }
+ }
+ }
+
+ return SSIZET2NUM(precision);
+}
+
+static VALUE
+BigDecimal_n_significant_digits(VALUE self)
+{
+ ENTER(1);
+
+ Real *p;
+ GUARD_OBJ(p, GetVpValue(self, 1));
+
+ ssize_t n = p->Prec;
+ while (n > 0 && p->frac[n-1] == 0) --n;
+ if (n <= 0) {
+ return INT2FIX(0);
+ }
+
+ int nlz, ntz;
+
+ BDIGIT x = p->frac[0];
+ for (nlz = BASE_FIG; x > 0; x /= 10) --nlz;
+
+ x = p->frac[n-1];
+ for (ntz = 0; x > 0 && x % 10 == 0; x /= 10) ++ntz;
+
+ ssize_t n_digits = BASE_FIG * n - nlz - ntz;
+ return SSIZET2NUM(n_digits);
+}
+
+/*
* call-seq: hash
*
* Creates a hash for this BigDecimal.
@@ -393,7 +506,7 @@ BigDecimal_hash(VALUE self)
*
* Method used to provide marshalling support.
*
- * inf = BigDecimal.new('Infinity')
+ * inf = BigDecimal('Infinity')
* #=> Infinity
* BigDecimal._load(inf._dump)
* #=> Infinity
@@ -432,7 +545,6 @@ BigDecimal_load(VALUE self, VALUE str)
unsigned long m=0;
pch = (unsigned char *)StringValueCStr(str);
- rb_check_safe_obj(str);
/* First get max prec */
while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') {
if(!ISDIGIT(ch)) {
@@ -646,12 +758,12 @@ GetAddSubPrec(Real *a, Real *b)
}
static SIGNED_VALUE
-GetPositiveInt(VALUE v)
+GetPrecisionInt(VALUE v)
{
SIGNED_VALUE n;
n = NUM2INT(v);
if (n < 0) {
- rb_raise(rb_eArgError, "argument must be positive");
+ rb_raise(rb_eArgError, "negative precision");
}
return n;
}
@@ -660,9 +772,10 @@ VP_EXPORT Real *
VpNewRbClass(size_t mx, const char *str, VALUE klass)
{
VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0);
- Real *pv = VpAlloc(mx,str);
+ Real *pv = VpAlloc(mx, str, 1, 1);
RTYPEDDATA_DATA(obj) = pv;
pv->obj = obj;
+ RB_OBJ_FREEZE(obj);
return pv;
}
@@ -876,7 +989,7 @@ BigDecimal_to_r(VALUE self)
* be coerced into a BigDecimal value.
*
* e.g.
- * a = BigDecimal.new("1.0")
+ * a = BigDecimal("1.0")
* b = a / 2.0 #=> 0.5
*
* Note that coercing a String to a BigDecimal is not supported by default;
@@ -890,7 +1003,7 @@ BigDecimal_coerce(VALUE self, VALUE other)
Real *b;
if (RB_TYPE_P(other, T_FLOAT)) {
- GUARD_OBJ(b, GetVpValueWithPrec(other, DBL_DIG+1, 1));
+ GUARD_OBJ(b, GetVpValueWithPrec(other, DBLE_FIG, 1));
obj = rb_assoc_new(ToValue(b), self);
}
else {
@@ -948,7 +1061,7 @@ BigDecimal_add(VALUE self, VALUE r)
GUARD_OBJ(a, GetVpValue(self, 1));
if (RB_TYPE_P(r, T_FLOAT)) {
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
}
else if (RB_TYPE_P(r, T_RATIONAL)) {
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1006,7 +1119,7 @@ BigDecimal_sub(VALUE self, VALUE r)
GUARD_OBJ(a, GetVpValue(self,1));
if (RB_TYPE_P(r, T_FLOAT)) {
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
}
else if (RB_TYPE_P(r, T_RATIONAL)) {
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1056,7 +1169,7 @@ BigDecimalCmp(VALUE self, VALUE r,char op)
break;
case T_FLOAT:
- GUARD_OBJ(b, GetVpValueWithPrec(r, DBL_DIG+1, 0));
+ GUARD_OBJ(b, GetVpValueWithPrec(r, DBLE_FIG, 0));
break;
case T_RATIONAL:
@@ -1165,7 +1278,7 @@ BigDecimal_comp(VALUE self, VALUE r)
*
* Values may be coerced to perform the comparison:
*
- * BigDecimal.new('1.0') == 1.0 #=> true
+ * BigDecimal('1.0') == 1.0 #=> true
*/
static VALUE
BigDecimal_eq(VALUE self, VALUE r)
@@ -1269,7 +1382,7 @@ BigDecimal_mult(VALUE self, VALUE r)
GUARD_OBJ(a, GetVpValue(self, 1));
if (RB_TYPE_P(r, T_FLOAT)) {
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
}
else if (RB_TYPE_P(r, T_RATIONAL)) {
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1297,7 +1410,7 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
GUARD_OBJ(a, GetVpValue(self, 1));
if (RB_TYPE_P(r, T_FLOAT)) {
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
}
else if (RB_TYPE_P(r, T_RATIONAL)) {
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1363,7 +1476,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
GUARD_OBJ(a, GetVpValue(self, 1));
if (RB_TYPE_P(r, T_FLOAT)) {
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
}
else if (RB_TYPE_P(r, T_RATIONAL)) {
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1464,7 +1577,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
GUARD_OBJ(a, GetVpValue(self, 1));
if (RB_TYPE_P(r, T_FLOAT)) {
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
}
else if (RB_TYPE_P(r, T_RATIONAL)) {
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1527,8 +1640,8 @@ BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
*
* require 'bigdecimal'
*
- * a = BigDecimal.new("42")
- * b = BigDecimal.new("9")
+ * a = BigDecimal("42")
+ * b = BigDecimal("9")
*
* q, m = a.divmod(b)
*
@@ -1571,7 +1684,7 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
}
/* div in BigDecimal sense */
- ix = GetPositiveInt(n);
+ ix = GetPrecisionInt(n);
if (ix == 0) {
return BigDecimal_div(self, b);
}
@@ -1640,7 +1753,7 @@ BigDecimal_add2(VALUE self, VALUE b, VALUE n)
{
ENTER(2);
Real *cv;
- SIGNED_VALUE mx = GetPositiveInt(n);
+ SIGNED_VALUE mx = GetPrecisionInt(n);
if (mx == 0) return BigDecimal_add(self, b);
else {
size_t pl = VpSetPrecLimit(0);
@@ -1670,7 +1783,7 @@ BigDecimal_sub2(VALUE self, VALUE b, VALUE n)
{
ENTER(2);
Real *cv;
- SIGNED_VALUE mx = GetPositiveInt(n);
+ SIGNED_VALUE mx = GetPrecisionInt(n);
if (mx == 0) return BigDecimal_sub(self, b);
else {
size_t pl = VpSetPrecLimit(0);
@@ -1688,7 +1801,7 @@ BigDecimal_mult2(VALUE self, VALUE b, VALUE n)
{
ENTER(2);
Real *cv;
- SIGNED_VALUE mx = GetPositiveInt(n);
+ SIGNED_VALUE mx = GetPrecisionInt(n);
if (mx == 0) return BigDecimal_mult(self, b);
else {
size_t pl = VpSetPrecLimit(0);
@@ -1742,7 +1855,7 @@ BigDecimal_sqrt(VALUE self, VALUE nFig)
GUARD_OBJ(a, GetVpValue(self, 1));
mx = a->Prec * (VpBaseFig() + 1);
- n = GetPositiveInt(nFig) + VpDblFig() + BASE_FIG;
+ n = GetPrecisionInt(nFig) + VpDblFig() + BASE_FIG;
if (mx <= n) mx = n;
GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
VpSqrt(c, a);
@@ -1769,20 +1882,23 @@ BigDecimal_fix(VALUE self)
* round(n, mode)
*
* Round to the nearest integer (by default), returning the result as a
- * BigDecimal.
+ * BigDecimal if n is specified, or as an Integer if it isn't.
*
* BigDecimal('3.14159').round #=> 3
* BigDecimal('8.7').round #=> 9
* BigDecimal('-9.9').round #=> -10
*
+ * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal"
+ * BigDecimal('3.14159').round.class.name #=> "Integer"
+ *
* If n is specified and positive, the fractional part of the result has no
* more than that many digits.
*
* If n is specified and negative, at least that many digits to the left of the
- * decimal point will be 0 in the result.
+ * decimal point will be 0 in the result, and return value will be an Integer.
*
* BigDecimal('3.14159').round(3) #=> 3.142
- * BigDecimal('13345.234').round(-2) #=> 13300.0
+ * BigDecimal('13345.234').round(-2) #=> 13300
*
* The value of the optional mode argument can be used to determine how
* rounding is performed; see BigDecimal.mode.
@@ -1795,6 +1911,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
int iLoc = 0;
VALUE vLoc;
VALUE vRound;
+ int round_to_int = 0;
size_t mx, pl;
unsigned short sw = VpGetRoundMode();
@@ -1802,6 +1919,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) {
case 0:
iLoc = 0;
+ round_to_int = 1;
break;
case 1:
if (RB_TYPE_P(vLoc, T_HASH)) {
@@ -1809,6 +1927,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
}
else {
iLoc = NUM2INT(vLoc);
+ if (iLoc < 1) round_to_int = 1;
}
break;
case 2:
@@ -1830,7 +1949,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
VpSetPrecLimit(pl);
VpActiveRound(c, a, sw, iLoc);
- if (argc == 0) {
+ if (round_to_int) {
return BigDecimal_to_i(ToValue(c));
}
return ToValue(c);
@@ -2012,26 +2131,27 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
*
* Examples:
*
- * BigDecimal.new('-123.45678901234567890').to_s('5F')
+ * BigDecimal('-123.45678901234567890').to_s('5F')
* #=> '-123.45678 90123 45678 9'
*
- * BigDecimal.new('123.45678901234567890').to_s('+8F')
+ * BigDecimal('123.45678901234567890').to_s('+8F')
* #=> '+123.45678901 23456789'
*
- * BigDecimal.new('123.45678901234567890').to_s(' F')
+ * BigDecimal('123.45678901234567890').to_s(' F')
* #=> ' 123.4567890123456789'
*/
static VALUE
BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
{
ENTER(5);
- int fmt = 0; /* 0:E format */
- int fPlus = 0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */
+ int fmt = 0; /* 0: E format, 1: F format */
+ int fPlus = 0; /* 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
Real *vp;
volatile VALUE str;
char *psz;
char ch;
size_t nc, mc = 0;
+ SIGNED_VALUE m;
VALUE f;
GUARD_OBJ(vp, GetVpValue(self, 1));
@@ -2039,7 +2159,6 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
if (rb_scan_args(argc, argv, "01", &f) == 1) {
if (RB_TYPE_P(f, T_STRING)) {
psz = StringValueCStr(f);
- rb_check_safe_obj(f);
if (*psz == ' ') {
fPlus = 1;
psz++;
@@ -2062,7 +2181,11 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
}
}
else {
- mc = (size_t)GetPositiveInt(f);
+ m = NUM2INT(f);
+ if (m <= 0) {
+ rb_raise(rb_eArgError, "argument must be positive");
+ }
+ mc = (size_t)m;
}
}
if (fmt) {
@@ -2075,7 +2198,7 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
nc += (nc + mc - 1) / mc + 1;
}
- str = rb_str_new(0, nc);
+ str = rb_usascii_str_new(0, nc);
psz = RSTRING_PTR(str);
if (fmt) {
@@ -2140,7 +2263,7 @@ BigDecimal_split(VALUE self)
rb_ary_push(obj, str);
rb_str_resize(str, strlen(psz1));
rb_ary_push(obj, INT2FIX(10));
- rb_ary_push(obj, INT2NUM(e));
+ rb_ary_push(obj, SSIZET2NUM(e));
return obj;
}
@@ -2153,18 +2276,13 @@ static VALUE
BigDecimal_exponent(VALUE self)
{
ssize_t e = VpExponent10(GetVpValue(self, 1));
- return INT2NUM(e);
+ return SSIZET2NUM(e);
}
-/* Returns debugging information about the value as a string of comma-separated
- * values in angle brackets with a leading #:
+/* Returns a string representation of self.
*
- * BigDecimal.new("1234.5678").inspect
+ * BigDecimal("1234.5678").inspect
* #=> "0.12345678e4"
- *
- * The first part is the address, the second is the value as a string, and
- * the final part ss(mm) is the current number of significant digits and the
- * maximum number of significant digits, respectively.
*/
static VALUE
BigDecimal_inspect(VALUE self)
@@ -2326,7 +2444,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec);
if (VpIsNaN(x)) {
- y = VpCreateRbObject(n, "0#");
+ y = VpCreateRbObject(n, "0");
RB_GC_GUARD(y->obj);
VpSetNaN(y);
return ToValue(y);
@@ -2351,7 +2469,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
}
goto retry;
}
- exp = GetVpValueWithPrec(vexp, DBL_DIG+1, 1);
+ if (NIL_P(prec)) {
+ n += DBLE_FIG;
+ }
+ exp = GetVpValueWithPrec(vexp, DBLE_FIG, 1);
break;
case T_RATIONAL:
@@ -2366,6 +2487,9 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
goto retry;
}
exp = GetVpValueWithPrec(vexp, n, 1);
+ if (NIL_P(prec)) {
+ n += n;
+ }
break;
case T_DATA:
@@ -2376,6 +2500,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
vexp = BigDecimal_to_i(vexp);
goto retry;
}
+ if (NIL_P(prec)) {
+ GUARD_OBJ(y, GetVpValue(vexp, 1));
+ n += y->Prec*VpBaseFig();
+ }
exp = DATA_PTR(vexp);
break;
}
@@ -2450,7 +2578,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
}
}
else {
- y = VpCreateRbObject(n, "0#");
+ y = VpCreateRbObject(n, "0");
if (BIGDECIMAL_NEGATIVE_P(x)) {
if (is_integer(vexp)) {
if (is_even(vexp)) {
@@ -2483,7 +2611,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
}
else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) {
if (is_negative(vexp)) {
- y = VpCreateRbObject(n, "0#");
+ y = VpCreateRbObject(n, "0");
if (is_even(vexp)) {
VpSetInf(y, VpGetSign(x));
}
@@ -2501,7 +2629,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
}
else {
if (is_positive(vexp)) {
- y = VpCreateRbObject(n, "0#");
+ y = VpCreateRbObject(n, "0");
if (is_even(vexp)) {
VpSetInf(y, VpGetSign(x));
}
@@ -2551,65 +2679,6 @@ BigDecimal_power_op(VALUE self, VALUE exp)
return BigDecimal_power(1, &exp, self);
}
-static VALUE
-BigDecimal_s_allocate(VALUE klass)
-{
- return VpNewRbClass(0, NULL, klass)->obj;
-}
-
-static Real *BigDecimal_new(int argc, VALUE *argv);
-
-/* call-seq:
- * new(initial, digits)
- *
- * Create a new BigDecimal object.
- *
- * initial:: The initial value, as an Integer, a Float, a Rational,
- * a BigDecimal, or a String.
- *
- * If it is a String, spaces are ignored and unrecognized characters
- * terminate the value.
- *
- * digits:: The number of significant digits, as an Integer. If omitted or 0,
- * the number of significant digits is determined from the initial
- * value.
- *
- * The actual number of significant digits used in computation is usually
- * larger than the specified number.
- *
- * ==== Exceptions
- *
- * TypeError:: If the +initial+ type is neither Integer, Float,
- * Rational, nor BigDecimal, this exception is raised.
- *
- * TypeError:: If the +digits+ is not an Integer, this exception is raised.
- *
- * ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
- * Float::DIG + 1, this exception is raised.
- *
- * ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
- * value is omitted, this exception is raised.
- */
-static VALUE
-BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
-{
- ENTER(1);
- Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
- Real *x;
-
- GUARD_OBJ(x, BigDecimal_new(argc, argv));
- if (ToValue(x)) {
- pv = VpCopy(pv, x);
- }
- else {
- VpFree(pv);
- pv = x;
- }
- DATA_PTR(self) = pv;
- pv->obj = self;
- return self;
-}
-
/* :nodoc:
*
* private method for dup and clone the provided BigDecimal +other+
@@ -2626,21 +2695,81 @@ BigDecimal_initialize_copy(VALUE self, VALUE other)
return self;
}
+static VALUE
+BigDecimal_clone(VALUE self)
+{
+ return self;
+}
+
+#ifdef HAVE_RB_OPTS_EXCEPTION_P
+int rb_opts_exception_p(VALUE opts, int default_value);
+#define opts_exception_p(opts) rb_opts_exception_p((opts), 1)
+#else
+static int
+opts_exception_p(VALUE opts)
+{
+ static ID kwds[1];
+ VALUE exception;
+ if (!kwds[0]) {
+ kwds[0] = rb_intern_const("exception");
+ }
+ if (!rb_get_kwargs(opts, kwds, 0, 1, &exception)) return 1;
+ switch (exception) {
+ case Qtrue: case Qfalse:
+ break;
+ default:
+ rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE,
+ exception);
+ }
+ return exception != Qfalse;
+}
+#endif
+
static Real *
-BigDecimal_new(int argc, VALUE *argv)
+VpNewVarArg(int argc, VALUE *argv)
{
size_t mf;
+ VALUE opts = Qnil;
VALUE nFig;
VALUE iniValue;
double d;
+ int exc;
- if (rb_scan_args(argc, argv, "11", &iniValue, &nFig) == 1) {
+ argc = rb_scan_args(argc, argv, "11:", &iniValue, &nFig, &opts);
+ exc = opts_exception_p(opts);
+
+ if (argc == 1) {
mf = 0;
}
else {
- mf = GetPositiveInt(nFig);
+ /* expand GetPrecisionInt for exception suppression */
+ ssize_t n = NUM2INT(nFig);
+ if (n < 0) {
+ if (!exc) {
+ return NULL;
+ }
+ rb_raise(rb_eArgError, "negative precision");
+ }
+ mf = (size_t)n;
+ }
+
+ if (SPECIAL_CONST_P(iniValue)) {
+ switch (iniValue) {
+ case Qnil:
+ if (!exc) return NULL;
+ rb_raise(rb_eTypeError, "can't convert nil into BigDecimal");
+ case Qtrue:
+ if (!exc) return NULL;
+ rb_raise(rb_eTypeError, "can't convert true into BigDecimal");
+ case Qfalse:
+ if (!exc) return NULL;
+ rb_raise(rb_eTypeError, "can't convert false into BigDecimal");
+ default:
+ break;
+ }
}
+ retry:
switch (TYPE(iniValue)) {
case T_DATA:
if (is_kind_of_BigDecimal(iniValue)) {
@@ -2660,42 +2789,120 @@ BigDecimal_new(int argc, VALUE *argv)
VpDtoV(pv, d);
return pv;
}
- if (mf > DBL_DIG+1) {
+ if (mf > DBLE_FIG) {
+ if (!exc) {
+ return NULL;
+ }
rb_raise(rb_eArgError, "precision too large.");
}
/* fall through */
case T_RATIONAL:
if (NIL_P(nFig)) {
+ if (!exc) {
+ return NULL;
+ }
rb_raise(rb_eArgError,
"can't omit precision for a %"PRIsVALUE".",
RB_OBJ_CLASSNAME(iniValue));
}
return GetVpValueWithPrec(iniValue, mf, 1);
+ case T_COMPLEX:
+ {
+ VALUE im;
+ im = rb_complex_imag(iniValue);
+ if (!is_zero(im)) {
+ rb_raise(rb_eArgError,
+ "Unable to make a BigDecimal from non-zero imaginary number");
+ }
+ iniValue = rb_complex_real(iniValue);
+ goto retry;
+ }
+
case T_STRING:
/* fall through */
default:
break;
}
+ /* TODO: support to_d */
+ if (!exc) {
+ iniValue = rb_check_convert_type(iniValue, T_STRING, "String", "to_str");
+ if (NIL_P(iniValue)) return NULL;
+ }
StringValueCStr(iniValue);
- return VpAlloc(mf, RSTRING_PTR(iniValue));
+ return VpAlloc(mf, RSTRING_PTR(iniValue), 1, exc);
}
-/* See also BigDecimal.new */
+/* call-seq:
+ * BigDecimal(initial, digits, exception: true)
+ *
+ * Create a new BigDecimal object.
+ *
+ * initial:: The initial value, as an Integer, a Float, a Rational,
+ * a BigDecimal, or a String.
+ *
+ * If it is a String, spaces are ignored and unrecognized characters
+ * terminate the value.
+ *
+ * digits:: The number of significant digits, as an Integer. If omitted or 0,
+ * the number of significant digits is determined from the initial
+ * value.
+ *
+ * The actual number of significant digits used in computation is
+ * usually larger than the specified number.
+ *
+ * exception:: Whether an exception should be raised on invalid arguments.
+ * +true+ by default, if passed +false+, just returns +nil+
+ * for invalid.
+ *
+ *
+ * ==== Exceptions
+ *
+ * TypeError:: If the +initial+ type is neither Integer, Float,
+ * Rational, nor BigDecimal, this exception is raised.
+ *
+ * TypeError:: If the +digits+ is not an Integer, this exception is raised.
+ *
+ * ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
+ * Float::DIG + 1, this exception is raised.
+ *
+ * ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
+ * value is omitted, this exception is raised.
+ */
static VALUE
-BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
+f_BigDecimal(int argc, VALUE *argv, VALUE self)
{
ENTER(1);
Real *pv;
VALUE obj;
+ if (argc > 0 && CLASS_OF(argv[0]) == rb_cBigDecimal) {
+ if (argc == 1 || (argc == 2 && RB_TYPE_P(argv[1], T_HASH))) return argv[0];
+ }
obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
- GUARD_OBJ(pv, BigDecimal_new(argc, argv));
+ pv = VpNewVarArg(argc, argv);
+ if (pv == NULL) return Qnil;
+ SAVE(pv);
if (ToValue(pv)) pv = VpCopy(NULL, pv);
RTYPEDDATA_DATA(obj) = pv;
+ RB_OBJ_FREEZE(obj);
return pv->obj = obj;
}
+static VALUE
+BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
+{
+ ENTER(1);
+ char const *c_str;
+ Real *pv;
+
+ c_str = StringValueCStr(str);
+ GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1));
+ pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv);
+ RB_OBJ_FREEZE(pv->obj);
+ return pv->obj;
+}
+
/* call-seq:
* BigDecimal.limit(digits)
*
@@ -2712,7 +2919,7 @@ static VALUE
BigDecimal_limit(int argc, VALUE *argv, VALUE self)
{
VALUE nFig;
- VALUE nCur = INT2NUM(VpGetPrecLimit());
+ VALUE nCur = SIZET2NUM(VpGetPrecLimit());
if (rb_scan_args(argc, argv, "01", &nFig) == 1) {
int nf;
@@ -2758,9 +2965,9 @@ BigDecimal_sign(VALUE self)
* BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
* BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
*
- * BigDecimal.new(BigDecimal('Infinity'))
- * BigDecimal.new(BigDecimal('-Infinity'))
- * BigDecimal(BigDecimal.new('NaN'))
+ * BigDecimal(BigDecimal('Infinity'))
+ * BigDecimal(BigDecimal('-Infinity'))
+ * BigDecimal(BigDecimal('NaN'))
* end
*
* For use with the BigDecimal::EXCEPTION_*
@@ -2877,7 +3084,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
infinite = isinf(flo);
nan = isnan(flo);
if (!infinite && !nan) {
- vx = GetVpValueWithPrec(x, DBL_DIG+1, 0);
+ vx = GetVpValueWithPrec(x, DBLE_FIG, 0);
}
break;
@@ -2915,6 +3122,10 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
n = prec + rmpd_double_figures();
negative = BIGDECIMAL_NEGATIVE_P(vx);
if (negative) {
+ VALUE x_zero = INT2NUM(1);
+ VALUE x_copy = f_BigDecimal(1, &x_zero, klass);
+ x = BigDecimal_initialize_copy(x_copy, x);
+ vx = DATA_PTR(x);
VpSetSign(vx, 1);
}
@@ -3026,7 +3237,7 @@ get_vp_value:
infinite = isinf(flo);
nan = isnan(flo);
if (!zero && !negative && !infinite && !nan) {
- vx = GetVpValueWithPrec(x, DBL_DIG+1, 1);
+ vx = GetVpValueWithPrec(x, DBLE_FIG, 1);
}
break;
@@ -3147,15 +3358,15 @@ get_vp_value:
*
* require 'bigdecimal'
*
- * sum = BigDecimal.new("0")
+ * sum = BigDecimal("0")
* 10_000.times do
- * sum = sum + BigDecimal.new("0.0001")
+ * sum = sum + BigDecimal("0.0001")
* end
* print sum #=> 0.1E1
*
* Similarly:
*
- * (BigDecimal.new("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true
+ * (BigDecimal("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true
*
* (1.2 - 1.0) == 0.2 #=> false
*
@@ -3169,8 +3380,8 @@ get_vp_value:
* BigDecimal sometimes needs to return infinity, for example if you divide
* a value by zero.
*
- * BigDecimal.new("1.0") / BigDecimal.new("0.0") #=> Infinity
- * BigDecimal.new("-1.0") / BigDecimal.new("0.0") #=> -Infinity
+ * BigDecimal("1.0") / BigDecimal("0.0") #=> Infinity
+ * BigDecimal("-1.0") / BigDecimal("0.0") #=> -Infinity
*
* You can represent infinite numbers to BigDecimal using the strings
* <code>'Infinity'</code>, <code>'+Infinity'</code> and
@@ -3183,13 +3394,13 @@ get_vp_value:
*
* Example:
*
- * BigDecimal.new("0.0") / BigDecimal.new("0.0") #=> NaN
+ * BigDecimal("0.0") / BigDecimal("0.0") #=> NaN
*
* You can also create undefined values.
*
* NaN is never considered to be the same as any other value, even NaN itself:
*
- * n = BigDecimal.new('NaN')
+ * n = BigDecimal('NaN')
* n == 0.0 #=> false
* n == n #=> false
*
@@ -3202,11 +3413,11 @@ get_vp_value:
* If the value which is too small to be represented is negative, a BigDecimal
* value of negative zero is returned.
*
- * BigDecimal.new("1.0") / BigDecimal.new("-Infinity") #=> -0.0
+ * BigDecimal("1.0") / BigDecimal("-Infinity") #=> -0.0
*
* If the value is positive, a value of positive zero is returned.
*
- * BigDecimal.new("1.0") / BigDecimal.new("Infinity") #=> 0.0
+ * BigDecimal("1.0") / BigDecimal("Infinity") #=> 0.0
*
* (See BigDecimal.mode for how to specify limits of precision.)
*
@@ -3244,6 +3455,9 @@ get_vp_value:
void
Init_bigdecimal(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
VALUE arg;
id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode");
@@ -3255,17 +3469,18 @@ Init_bigdecimal(void)
/* Class and method registration */
rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric);
- rb_define_alloc_func(rb_cBigDecimal, BigDecimal_s_allocate);
/* Global function */
- rb_define_global_function("BigDecimal", BigDecimal_global_new, -1);
+ rb_define_global_function("BigDecimal", f_BigDecimal, -1);
/* Class methods */
+ rb_undef_alloc_func(rb_cBigDecimal);
+ rb_undef_method(CLASS_OF(rb_cBigDecimal), "new");
+ rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1);
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1);
- rb_define_singleton_method(rb_cBigDecimal, "ver", BigDecimal_version, 0);
rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0);
rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0);
@@ -3273,6 +3488,14 @@ Init_bigdecimal(void)
/* Constants definition */
+#ifndef RUBY_BIGDECIMAL_VERSION
+# error RUBY_BIGDECIMAL_VERSION is not defined
+#endif
+ /*
+ * The version of bigdecimal library
+ */
+ rb_define_const(rb_cBigDecimal, "VERSION", rb_str_new2(RUBY_BIGDECIMAL_VERSION));
+
/*
* Base value used in internal calculations. On a 32 bit system, BASE
* is 10000, indicating that calculation is done in groups of 4 digits.
@@ -3377,16 +3600,16 @@ Init_bigdecimal(void)
arg = rb_str_new2("+Infinity");
/* Positive infinity value. */
- rb_define_const(rb_cBigDecimal, "INFINITY", BigDecimal_global_new(1, &arg, rb_cBigDecimal));
+ rb_define_const(rb_cBigDecimal, "INFINITY", f_BigDecimal(1, &arg, rb_cBigDecimal));
arg = rb_str_new2("NaN");
/* 'Not a Number' value. */
- rb_define_const(rb_cBigDecimal, "NAN", BigDecimal_global_new(1, &arg, rb_cBigDecimal));
+ rb_define_const(rb_cBigDecimal, "NAN", f_BigDecimal(1, &arg, rb_cBigDecimal));
/* instance methods */
- rb_define_method(rb_cBigDecimal, "initialize", BigDecimal_initialize, -1);
- rb_define_method(rb_cBigDecimal, "initialize_copy", BigDecimal_initialize_copy, 1);
rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
+ rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0);
+ rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0);
rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2);
@@ -3409,7 +3632,8 @@ Init_bigdecimal(void)
rb_define_method(rb_cBigDecimal, "modulo", BigDecimal_mod, 1);
rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1);
rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1);
- /* rb_define_method(rb_cBigDecimal, "dup", BigDecimal_dup, 0); */
+ rb_define_method(rb_cBigDecimal, "clone", BigDecimal_clone, 0);
+ rb_define_method(rb_cBigDecimal, "dup", BigDecimal_clone, 0);
rb_define_method(rb_cBigDecimal, "to_f", BigDecimal_to_f, 0);
rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0);
rb_define_method(rb_cBigDecimal, "sqrt", BigDecimal_sqrt, 1);
@@ -3502,6 +3726,9 @@ static void VpFormatSt(char *psz, size_t fFmt);
static int VpRdup(Real *m, size_t ind_m);
#ifdef BIGDECIMAL_DEBUG
+# ifdef HAVE_RB_EXT_RACTOR_SAFE
+# error Need to make rewiting gnAlloc atomic
+# endif
static int gnAlloc = 0; /* Memory allocation counter */
#endif /* BIGDECIMAL_DEBUG */
@@ -3682,13 +3909,7 @@ VpSetRoundMode(unsigned short n)
* (to let the compiler know they may be changed in outside
* (... but not actually..)).
*/
-volatile const double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
-static double
-Zero(void)
-{
- return gZero_ABCED9B1_CE73__00400511F31D;
-}
static double
One(void)
@@ -3713,25 +3934,19 @@ One(void)
VP_EXPORT double
VpGetDoubleNaN(void) /* Returns the value of NaN */
{
- static double fNaN = 0.0;
- if (fNaN == 0.0) fNaN = Zero()/Zero();
- return fNaN;
+ return nan("");
}
VP_EXPORT double
VpGetDoublePosInf(void) /* Returns the value of +Infinity */
{
- static double fInf = 0.0;
- if (fInf == 0.0) fInf = One()/Zero();
- return fInf;
+ return HUGE_VAL;
}
VP_EXPORT double
VpGetDoubleNegInf(void) /* Returns the value of -Infinity */
{
- static double fInf = 0.0;
- if (fInf == 0.0) fInf = -(One()/Zero());
- return fInf;
+ return -HUGE_VAL;
}
VP_EXPORT double
@@ -3920,20 +4135,17 @@ VpNumOfChars(Real *vp,const char *pszFmt)
* by one BDIGIT word in the computer used.
*
* [Returns]
- * 1+DBL_DIG ... OK
+ * DBLE_FIG ... OK
*/
VP_EXPORT size_t
VpInit(BDIGIT BaseVal)
{
/* Setup +/- Inf NaN -0 */
- VpGetDoubleNaN();
- VpGetDoublePosInf();
- VpGetDoubleNegInf();
VpGetDoubleNegZero();
/* Allocates Vp constants. */
- VpConstOne = VpAlloc(1UL, "1");
- VpPt5 = VpAlloc(1UL, ".5");
+ VpConstOne = VpAlloc(1UL, "1", 1, 1);
+ VpPt5 = VpAlloc(1UL, ".5", 1, 1);
#ifdef BIGDECIMAL_DEBUG
gnAlloc = 0;
@@ -3997,6 +4209,52 @@ overflow:
return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0);
}
+Real *
+rmpd_parse_special_string(const char *str)
+{
+ static const struct {
+ const char *str;
+ size_t len;
+ int sign;
+ } table[] = {
+ { SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE },
+ { SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE },
+ { SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE },
+ { SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN }
+ };
+ static const size_t table_length = sizeof(table) / sizeof(table[0]);
+ size_t i;
+
+ for (i = 0; i < table_length; ++i) {
+ const char *p;
+ if (strncmp(str, table[i].str, table[i].len) != 0) {
+ continue;
+ }
+
+ p = str + table[i].len;
+ while (*p && ISSPACE(*p)) ++p;
+ if (*p == '\0') {
+ Real *vp = VpAllocReal(1);
+ vp->MaxPrec = 1;
+ switch (table[i].sign) {
+ default:
+ UNREACHABLE; break;
+ case VP_SIGN_POSITIVE_INFINITE:
+ VpSetPosInf(vp);
+ return vp;
+ case VP_SIGN_NEGATIVE_INFINITE:
+ VpSetNegInf(vp);
+ return vp;
+ case VP_SIGN_NaN:
+ VpSetNaN(vp);
+ return vp;
+ }
+ }
+ }
+
+ return NULL;
+}
+
/*
* Allocates variable.
* [Input]
@@ -4011,10 +4269,10 @@ overflow:
* NULL be returned if memory allocation is failed,or any error.
*/
VP_EXPORT Real *
-VpAlloc(size_t mx, const char *szVal)
+VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
{
const char *orig_szVal = szVal;
- size_t i, ni, ipn, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
+ size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
char v, *psz;
int sign=1;
Real *vp = NULL;
@@ -4025,7 +4283,10 @@ VpAlloc(size_t mx, const char *szVal)
if (mx == 0) ++mx;
if (szVal) {
+ /* Skipping leading spaces */
while (ISSPACE(*szVal)) szVal++;
+
+ /* Processing the leading one `#` */
if (*szVal != '#') {
if (mf) {
mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */
@@ -4039,115 +4300,179 @@ VpAlloc(size_t mx, const char *szVal)
}
}
else {
+ return_zero:
/* necessary to be able to store */
/* at least mx digits. */
/* szVal==NULL ==> allocate zero value. */
vp = VpAllocReal(mx);
- /* xmalloc() alway returns(or throw interruption) */
+ /* xmalloc() always returns(or throw interruption) */
vp->MaxPrec = mx; /* set max precision */
VpSetZero(vp, 1); /* initialize vp to zero. */
return vp;
}
- /* Skip all '_' after digit: 2006-6-30 */
- ni = 0;
+ /* Check on Inf & NaN */
+ if ((vp = rmpd_parse_special_string(szVal)) != NULL) {
+ return vp;
+ }
+
+ /* Scanning digits */
+
+ /* A buffer for keeping scanned digits */
buf = rb_str_tmp_new(strlen(szVal) + 1);
psz = RSTRING_PTR(buf);
- i = 0;
- ipn = 0;
- while ((psz[i] = szVal[ipn]) != 0) {
- if (ISSPACE(psz[i])) {
- psz[i] = 0;
+
+ /* cursor: i for psz, and j for szVal */
+ i = j = 0;
+
+ /* Scanning: sign part */
+ v = psz[i] = szVal[j];
+ if ((v == '-') || (v == '+')) {
+ sign = -(v == '-');
+ ++i;
+ ++j;
+ }
+
+ /* Scanning: integer part */
+ ni = 0; /* number of digits in the integer part */
+ while ((v = psz[i] = szVal[j]) != '\0') {
+ if (!strict_p && ISSPACE(v)) {
+ v = psz[i] = '\0';
break;
}
- if (ISDIGIT(psz[i])) ++ni;
- if (psz[i] == '_') {
+ if (v == '_') {
if (ni > 0) {
- ipn++;
- continue;
+ v = szVal[j+1];
+ if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) {
+ ++j;
+ continue;
+ }
+ if (!strict_p) {
+ v = psz[i] = '\0';
+ break;
+ }
}
- psz[i] = 0;
+ goto invalid_value;
+ }
+ if (!ISDIGIT(v)) {
break;
}
+ ++ni;
++i;
- ++ipn;
- }
- szVal = psz;
-
- /* Check on Inf & NaN */
- if (StrCmp(szVal, SZ_PINF) == 0 || StrCmp(szVal, SZ_INF) == 0 ) {
- vp = VpAllocReal(1);
- vp->MaxPrec = 1; /* set max precision */
- VpSetPosInf(vp);
- return vp;
- }
- if (StrCmp(szVal, SZ_NINF) == 0) {
- vp = VpAllocReal(1);
- vp->MaxPrec = 1; /* set max precision */
- VpSetNegInf(vp);
- return vp;
- }
- if (StrCmp(szVal, SZ_NaN) == 0) {
- vp = VpAllocReal(1);
- vp->MaxPrec = 1; /* set max precision */
- VpSetNaN(vp);
- return vp;
+ ++j;
}
- /* check on number szVal[] */
- ipn = i = 0;
- if (szVal[i] == '-') { sign=-1; ++i; }
- else if (szVal[i] == '+') ++i;
- /* Skip digits */
- ni = 0; /* digits in mantissa */
- while ((v = szVal[i]) != 0) {
- if (!ISDIGIT(v)) break;
- ++i;
- ++ni;
- }
- nf = 0;
- ipf = 0;
- ipe = 0;
- ne = 0;
+ /* Scanning: fractional part */
+ nf = 0; /* number of digits in the fractional part */
+ ne = 0; /* number of digits in the exponential part */
+ ipf = 0; /* index of the beginning of the fractional part */
+ ipe = 0; /* index of the beginning of the exponential part */
dot_seen = 0;
exp_seen = 0;
- if (v) {
- /* other than digit nor \0 */
- if (szVal[i] == '.') { /* xxx. */
+
+ if (v != '\0') {
+ /* Scanning fractional part */
+ if ((psz[i] = szVal[j]) == '.') {
dot_seen = 1;
++i;
+ ++j;
ipf = i;
- while ((v = szVal[i]) != 0) { /* get fraction part. */
+ while ((v = psz[i] = szVal[j]) != '\0') {
+ if (!strict_p && ISSPACE(v)) {
+ v = psz[i] = '\0';
+ break;
+ }
+ if (v == '_') {
+ if (nf > 0 && ISDIGIT(szVal[j+1])) {
+ ++j;
+ continue;
+ }
+ if (!strict_p) {
+ v = psz[i] = '\0';
+ if (nf == 0) {
+ dot_seen = 0;
+ }
+ break;
+ }
+ goto invalid_value;
+ }
if (!ISDIGIT(v)) break;
++i;
+ ++j;
++nf;
}
}
- ipe = 0; /* Exponent */
-
- switch (szVal[i]) {
- case '\0':
- break;
- case 'e': case 'E':
- case 'd': case 'D':
- exp_seen = 1;
- ++i;
- ipe = i;
- v = szVal[i];
- if ((v == '-') || (v == '+')) ++i;
- while ((v=szVal[i]) != 0) {
- if (!ISDIGIT(v)) break;
+
+ /* Scanning exponential part */
+ if (v != '\0') {
+ switch ((psz[i] = szVal[j])) {
+ case '\0':
+ break;
+ case 'e': case 'E':
+ case 'd': case 'D':
+ exp_seen = 1;
++i;
- ++ne;
- }
- break;
- default:
- break;
+ ++j;
+ ipe = i;
+ v = psz[i] = szVal[j];
+ if ((v == '-') || (v == '+')) {
+ ++i;
+ ++j;
+ }
+ while ((v = psz[i] = szVal[j]) != '\0') {
+ if (!strict_p && ISSPACE(v)) {
+ v = psz[i] = '\0';
+ break;
+ }
+ if (v == '_') {
+ if (ne > 0 && ISDIGIT(szVal[j+1])) {
+ ++j;
+ continue;
+ }
+ if (!strict_p) {
+ v = psz[i] = '\0';
+ if (ne == 0) {
+ exp_seen = 0;
+ }
+ break;
+ }
+ goto invalid_value;
+ }
+ if (!ISDIGIT(v)) break;
+ ++i;
+ ++j;
+ ++ne;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (v != '\0') {
+ /* Scanning trailing spaces */
+ while (ISSPACE(szVal[j])) ++j;
+
+ /* Invalid character */
+ if (szVal[j] && strict_p) {
+ goto invalid_value;
+ }
}
}
- if (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0)) {
- VALUE str = rb_str_new2(orig_szVal);
- rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
+
+ psz[i] = '\0';
+
+ if (strict_p && (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0))) {
+ VALUE str;
+ invalid_value:
+ if (!strict_p) {
+ goto return_zero;
+ }
+ if (!exc) {
+ return NULL;
+ }
+ str = rb_str_new2(orig_szVal);
+ rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
}
nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */
@@ -4156,10 +4481,10 @@ VpAlloc(size_t mx, const char *szVal)
nalloc = Max(nalloc, mx);
mx = nalloc;
vp = VpAllocReal(mx);
- /* xmalloc() alway returns(or throw interruption) */
+ /* xmalloc() always returns(or throw interruption) */
vp->MaxPrec = mx; /* set max precision */
VpSetZero(vp, sign);
- VpCtoV(vp, &szVal[ipn], ni, &szVal[ipf], nf, &szVal[ipe], ne);
+ VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne);
rb_str_resize(buf, 0);
return vp;
}
@@ -4722,7 +5047,7 @@ VpMult(Real *c, Real *a, Real *b)
if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */
w = c;
- c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0");
+ c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0", 1, 1);
MxIndC = MxIndAB;
}
@@ -5348,7 +5673,7 @@ VpSzMantissa(Real *a,char *psz)
VP_EXPORT int
VpToSpecialString(Real *a,char *psz,int fPlus)
- /* fPlus =0:default, =1: set ' ' before digits , =2: set '+' before digits. */
+/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
{
if (VpIsNaN(a)) {
sprintf(psz,SZ_NaN);
@@ -5383,7 +5708,7 @@ VpToSpecialString(Real *a,char *psz,int fPlus)
VP_EXPORT void
VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
-/* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */
+/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
{
size_t i, n, ZeroSup;
BDIGIT shift, m, e, nn;
@@ -5431,7 +5756,7 @@ VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
VP_EXPORT void
VpToFString(Real *a, char *psz, size_t fFmt, int fPlus)
-/* fPlus =0:default,=1: set ' ' before digits ,set '+' before digits. */
+/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
{
size_t i, n;
BDIGIT m, e, nn;
@@ -5890,8 +6215,8 @@ VpSqrt(Real *y, Real *x)
if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec;
/* allocate temporally variables */
- f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1");
- r = VpAlloc((n + n) * (BASE_FIG + 2), "#1");
+ f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1", 1, 1);
+ r = VpAlloc((n + n) * (BASE_FIG + 2), "#1", 1, 1);
nr = 0;
y_prec = y->MaxPrec;
@@ -6343,8 +6668,8 @@ VpPower(Real *y, Real *x, SIGNED_VALUE n)
/* Allocate working variables */
- w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0");
- w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0");
+ w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0", 1, 1);
+ w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0", 1, 1);
/* calculation start */
VpAsgn(y, x, 1);
diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec
index 4efe438fbd..7e5388d8e0 100644
--- a/ext/bigdecimal/bigdecimal.gemspec
+++ b/ext/bigdecimal/bigdecimal.gemspec
@@ -1,16 +1,17 @@
# coding: utf-8
-_VERSION = '1.3.2'
+
+bigdecimal_version = '3.0.0'
Gem::Specification.new do |s|
s.name = "bigdecimal"
- s.version = _VERSION
+ s.version = bigdecimal_version
s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"]
s.email = ["mrkn@mrkn.jp"]
s.summary = "Arbitrary-precision decimal floating-point number library."
s.description = "This library provides arbitrary-precision decimal floating-point number class."
s.homepage = "https://github.com/ruby/bigdecimal"
- s.license = "ruby"
+ s.license = "Ruby"
s.require_paths = %w[lib]
s.extensions = %w[ext/bigdecimal/extconf.rb]
@@ -18,8 +19,7 @@ Gem::Specification.new do |s|
bigdecimal.gemspec
ext/bigdecimal/bigdecimal.c
ext/bigdecimal/bigdecimal.h
- ext/bigdecimal/depend
- ext/bigdecimal/extconf.rb
+ lib/bigdecimal.rb
lib/bigdecimal/jacobian.rb
lib/bigdecimal/ludcmp.rb
lib/bigdecimal/math.rb
@@ -30,8 +30,10 @@ Gem::Specification.new do |s|
sample/pi.rb
]
- s.add_development_dependency "rake", "~> 10.0"
- s.add_development_dependency "rake-compiler", "~> 0.9"
- s.add_development_dependency "minitest", "~> 4.7.5"
+ s.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
+
+ s.add_development_dependency "rake", ">= 12.3.3"
+ s.add_development_dependency "rake-compiler", ">= 0.9"
+ s.add_development_dependency "minitest", "< 5.0.0"
s.add_development_dependency "pry"
end
diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h
index 6182ae2374..28f3363b3c 100644
--- a/ext/bigdecimal/bigdecimal.h
+++ b/ext/bigdecimal/bigdecimal.h
@@ -142,6 +142,12 @@ rb_sym2str(VALUE sym)
}
#endif
+#ifndef ST2FIX
+# undef RB_ST2FIX
+# define RB_ST2FIX(h) LONG2FIX((long)(h))
+# define ST2FIX(h) RB_ST2FIX(h)
+#endif
+
#ifdef vabs
# undef vabs
#endif
@@ -153,6 +159,10 @@ rb_sym2str(VALUE sym)
# define vabs llabs
#endif
+#if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED)
+# define rb_category_warn(category, ...) rb_warn(__VA_ARGS__)
+#endif
+
extern VALUE rb_cBigDecimal;
#if 0 || SIZEOF_BDIGITS >= 16
@@ -221,7 +231,9 @@ extern VALUE rb_cBigDecimal;
#define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */
#define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */
-#ifdef __GNUC__
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+#define FLEXIBLE_ARRAY_SIZE /* */
+#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define FLEXIBLE_ARRAY_SIZE 0
#else
#define FLEXIBLE_ARRAY_SIZE 1
@@ -300,7 +312,7 @@ VP_EXPORT size_t VpInit(BDIGIT BaseVal);
VP_EXPORT void *VpMemAlloc(size_t mb);
VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb);
VP_EXPORT void VpFree(Real *pv);
-VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal);
+VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal, int strict_p, int exc);
VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation);
VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b);
diff --git a/ext/bigdecimal/depend b/ext/bigdecimal/depend
index 6783192b30..d607a71dfe 100644
--- a/ext/bigdecimal/depend
+++ b/ext/bigdecimal/depend
@@ -1,6 +1,159 @@
+extconf.h: $(srcdir)/$(GEMSPEC)
+Makefile: $(BIGDECIMAL_RB)
+
# AUTOGENERATED DEPENDENCIES START
bigdecimal.o: $(RUBY_EXTCONF_H)
bigdecimal.o: $(arch_hdrdir)/ruby/config.h
+bigdecimal.o: $(hdrdir)/ruby/internal/anyargs.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bigdecimal.o: $(hdrdir)/ruby/internal/assume.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/cold.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/const.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/error.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/format.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/pure.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/warning.h
+bigdecimal.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bigdecimal.o: $(hdrdir)/ruby/internal/cast.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bigdecimal.o: $(hdrdir)/ruby/internal/compiler_since.h
+bigdecimal.o: $(hdrdir)/ruby/internal/config.h
+bigdecimal.o: $(hdrdir)/ruby/internal/constant_p.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rarray.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rclass.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rdata.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rfile.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rhash.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/robject.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rstring.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bigdecimal.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bigdecimal.o: $(hdrdir)/ruby/internal/ctype.h
+bigdecimal.o: $(hdrdir)/ruby/internal/dllexport.h
+bigdecimal.o: $(hdrdir)/ruby/internal/dosish.h
+bigdecimal.o: $(hdrdir)/ruby/internal/error.h
+bigdecimal.o: $(hdrdir)/ruby/internal/eval.h
+bigdecimal.o: $(hdrdir)/ruby/internal/event.h
+bigdecimal.o: $(hdrdir)/ruby/internal/fl_type.h
+bigdecimal.o: $(hdrdir)/ruby/internal/gc.h
+bigdecimal.o: $(hdrdir)/ruby/internal/glob.h
+bigdecimal.o: $(hdrdir)/ruby/internal/globals.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/attribute.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/builtin.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/extension.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/feature.h
+bigdecimal.o: $(hdrdir)/ruby/internal/has/warning.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/array.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/class.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/compar.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/complex.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/cont.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/dir.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/enum.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/error.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/eval.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/file.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/gc.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/hash.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/io.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/load.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/object.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/parse.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/proc.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/process.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/random.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/range.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/rational.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/re.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/select.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/signal.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/string.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/struct.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/thread.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/time.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/variable.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/vm.h
+bigdecimal.o: $(hdrdir)/ruby/internal/interpreter.h
+bigdecimal.o: $(hdrdir)/ruby/internal/iterator.h
+bigdecimal.o: $(hdrdir)/ruby/internal/memory.h
+bigdecimal.o: $(hdrdir)/ruby/internal/method.h
+bigdecimal.o: $(hdrdir)/ruby/internal/module.h
+bigdecimal.o: $(hdrdir)/ruby/internal/newobj.h
+bigdecimal.o: $(hdrdir)/ruby/internal/rgengc.h
+bigdecimal.o: $(hdrdir)/ruby/internal/scan_args.h
+bigdecimal.o: $(hdrdir)/ruby/internal/special_consts.h
+bigdecimal.o: $(hdrdir)/ruby/internal/static_assert.h
+bigdecimal.o: $(hdrdir)/ruby/internal/stdalign.h
+bigdecimal.o: $(hdrdir)/ruby/internal/stdbool.h
+bigdecimal.o: $(hdrdir)/ruby/internal/symbol.h
+bigdecimal.o: $(hdrdir)/ruby/internal/token_paste.h
+bigdecimal.o: $(hdrdir)/ruby/internal/value.h
+bigdecimal.o: $(hdrdir)/ruby/internal/value_type.h
+bigdecimal.o: $(hdrdir)/ruby/internal/variable.h
+bigdecimal.o: $(hdrdir)/ruby/internal/warning_push.h
+bigdecimal.o: $(hdrdir)/ruby/internal/xmalloc.h
+bigdecimal.o: $(hdrdir)/ruby/assert.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/assume.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/attributes.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/bool.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/limits.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/long_long.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bigdecimal.o: $(hdrdir)/ruby/backward/2/stdarg.h
bigdecimal.o: $(hdrdir)/ruby/defines.h
bigdecimal.o: $(hdrdir)/ruby/intern.h
bigdecimal.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/bigdecimal/extconf.rb b/ext/bigdecimal/extconf.rb
index dccf2d2d83..63123e2892 100644
--- a/ext/bigdecimal/extconf.rb
+++ b/ext/bigdecimal/extconf.rb
@@ -1,7 +1,32 @@
# frozen_string_literal: false
require 'mkmf'
-alias __have_macro__ have_macro
+def check_bigdecimal_version(gemspec_path)
+ message "checking RUBY_BIGDECIMAL_VERSION... "
+
+ bigdecimal_version =
+ IO.readlines(gemspec_path)
+ .grep(/\Abigdecimal_version\s+=\s+/)[0][/\'([^\']+)\'/, 1]
+
+ version_components = bigdecimal_version.split('.')
+ bigdecimal_version = version_components[0, 3].join('.')
+ bigdecimal_version << "-#{version_components[3]}" if version_components[3]
+ $defs << %Q[-DRUBY_BIGDECIMAL_VERSION=\\"#{bigdecimal_version}\\"]
+
+ message "#{bigdecimal_version}\n"
+end
+
+gemspec_name = gemspec_path = nil
+unless ['', '../../'].any? {|dir|
+ gemspec_name = "#{dir}bigdecimal.gemspec"
+ gemspec_path = File.expand_path("../#{gemspec_name}", __FILE__)
+ File.file?(gemspec_path)
+ }
+ $stderr.puts "Unable to find bigdecimal.gemspec"
+ abort
+end
+
+check_bigdecimal_version(gemspec_path)
have_func("labs", "stdlib.h")
have_func("llabs", "stdlib.h")
@@ -11,7 +36,22 @@ have_func("isfinite", "math.h")
have_type("struct RRational", "ruby.h")
have_func("rb_rational_num", "ruby.h")
have_func("rb_rational_den", "ruby.h")
+have_type("struct RComplex", "ruby.h")
+have_func("rb_complex_real", "ruby.h")
+have_func("rb_complex_imag", "ruby.h")
have_func("rb_array_const_ptr", "ruby.h")
have_func("rb_sym2str", "ruby.h")
+have_func("rb_opts_exception_p", "ruby.h")
+have_func("rb_category_warn", "ruby.h")
+have_const("RB_WARN_CATEGORY_DEPRECATED", "ruby.h")
+
+if File.file?(File.expand_path('../lib/bigdecimal.rb', __FILE__))
+ bigdecimal_rb = "$(srcdir)/lib/bigdecimal.rb"
+else
+ bigdecimal_rb = "$(srcdir)/../../lib/bigdecimal.rb"
+end
-create_makefile('bigdecimal')
+create_makefile('bigdecimal') {|mf|
+ mf << "GEMSPEC = #{gemspec_name}\n"
+ mf << "BIGDECIMAL_RB = #{bigdecimal_rb}\n"
+}
diff --git a/ext/bigdecimal/lib/bigdecimal.rb b/ext/bigdecimal/lib/bigdecimal.rb
new file mode 100644
index 0000000000..8fd2587c84
--- /dev/null
+++ b/ext/bigdecimal/lib/bigdecimal.rb
@@ -0,0 +1 @@
+require 'bigdecimal.so'
diff --git a/ext/bigdecimal/lib/bigdecimal/jacobian.rb b/ext/bigdecimal/lib/bigdecimal/jacobian.rb
index 9cad06c09b..5e29304299 100644
--- a/ext/bigdecimal/lib/bigdecimal/jacobian.rb
+++ b/ext/bigdecimal/lib/bigdecimal/jacobian.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: false
-#
+
+require 'bigdecimal'
+
# require 'bigdecimal/jacobian'
#
# Provides methods to compute the Jacobian matrix of a set of equations at a
diff --git a/ext/bigdecimal/lib/bigdecimal/math.rb b/ext/bigdecimal/lib/bigdecimal/math.rb
index ef1a02b38f..0b9d0648bb 100644
--- a/ext/bigdecimal/lib/bigdecimal/math.rb
+++ b/ext/bigdecimal/lib/bigdecimal/math.rb
@@ -37,7 +37,7 @@ module BigMath
# Computes the square root of +decimal+ to the specified number of digits of
# precision, +numeric+.
#
- # BigMath.sqrt(BigDecimal.new('2'), 16).to_s
+ # BigMath.sqrt(BigDecimal('2'), 16).to_s
# #=> "0.1414213562373095048801688724e1"
#
def sqrt(x, prec)
@@ -140,7 +140,7 @@ module BigMath
#
# If +decimal+ is NaN, returns NaN.
#
- # BigMath.atan(BigDecimal.new('-1'), 16).to_s
+ # BigMath.atan(BigDecimal('-1'), 16).to_s
# #=> "-0.785398163397448309615660845819878471907514682065e0"
#
def atan(x, prec)
diff --git a/ext/bigdecimal/lib/bigdecimal/util.rb b/ext/bigdecimal/lib/bigdecimal/util.rb
index d32eaf561a..00a3e967bd 100644
--- a/ext/bigdecimal/lib/bigdecimal/util.rb
+++ b/ext/bigdecimal/lib/bigdecimal/util.rb
@@ -5,6 +5,7 @@
# and provides BigDecimal#to_d and BigDecimal#to_digits.
#++
+require 'bigdecimal'
class Integer < Numeric
# call-seq:
@@ -42,8 +43,8 @@ class Float < Numeric
#
# See also BigDecimal::new.
#
- def to_d(precision=nil)
- BigDecimal(self, precision || Float::DIG)
+ def to_d(precision=Float::DIG+1)
+ BigDecimal(self, precision)
end
end
@@ -65,11 +66,7 @@ class String
# See also BigDecimal::new.
#
def to_d
- begin
- BigDecimal(self)
- rescue ArgumentError
- BigDecimal(0)
- end
+ BigDecimal.interpret_loosely(self)
end
end
@@ -83,7 +80,7 @@ class BigDecimal < Numeric
#
# require 'bigdecimal/util'
#
- # d = BigDecimal.new("3.14")
+ # d = BigDecimal("3.14")
# d.to_digits # => "3.14"
#
def to_digits
@@ -103,7 +100,7 @@ class BigDecimal < Numeric
#
# require 'bigdecimal/util'
#
- # d = BigDecimal.new("3.14")
+ # d = BigDecimal("3.14")
# d.to_d # => 0.314e1
#
def to_d
@@ -132,3 +129,53 @@ class Rational < Numeric
BigDecimal(self, precision)
end
end
+
+
+class Complex < Numeric
+ # call-seq:
+ # cmp.to_d -> bigdecimal
+ # cmp.to_d(precision) -> bigdecimal
+ #
+ # Returns the value as a BigDecimal.
+ #
+ # The +precision+ parameter is required for a rational complex number.
+ # This parameter is used to determine the number of significant digits
+ # for the result.
+ #
+ # require 'bigdecimal'
+ # require 'bigdecimal/util'
+ #
+ # Complex(0.1234567, 0).to_d(4) # => 0.1235e0
+ # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1
+ #
+ # See also BigDecimal::new.
+ #
+ def to_d(*args)
+ BigDecimal(self) unless self.imag.zero? # to raise eerror
+
+ if args.length == 0
+ case self.real
+ when Rational
+ BigDecimal(self.real) # to raise error
+ end
+ end
+ self.real.to_d(*args)
+ end
+end
+
+
+class NilClass
+ # call-seq:
+ # nil.to_d -> bigdecimal
+ #
+ # Returns nil represented as a BigDecimal.
+ #
+ # require 'bigdecimal'
+ # require 'bigdecimal/util'
+ #
+ # nil.to_d # => 0.0
+ #
+ def to_d
+ BigDecimal(0)
+ end
+end
diff --git a/ext/bigdecimal/sample/linear.rb b/ext/bigdecimal/sample/linear.rb
index 3b23269f8a..516c2473be 100644
--- a/ext/bigdecimal/sample/linear.rb
+++ b/ext/bigdecimal/sample/linear.rb
@@ -28,8 +28,8 @@ def rd_order(na)
end
na = ARGV.size
-zero = BigDecimal.new("0.0")
-one = BigDecimal.new("1.0")
+zero = BigDecimal("0.0")
+one = BigDecimal("1.0")
while (n=rd_order(na))>0
a = []
@@ -37,27 +37,28 @@ while (n=rd_order(na))>0
b = []
if na <= 0
# Read data from console.
- printf("\nEnter coefficient matrix element A[i,j]\n");
+ printf("\nEnter coefficient matrix element A[i,j]\n")
for i in 0...n do
for j in 0...n do
printf("A[%d,%d]? ",i,j); s = ARGF.gets
- a << BigDecimal.new(s);
- as << BigDecimal.new(s);
+ a << BigDecimal(s)
+ as << BigDecimal(s)
end
- printf("Contatant vector element b[%d] ? ",i); b << BigDecimal.new(ARGF.gets);
+ printf("Contatant vector element b[%d] ? ",i)
+ b << BigDecimal(ARGF.gets)
end
else
# Read data from specified file.
- printf("Coefficient matrix and constant vector.\n");
+ printf("Coefficient matrix and constant vector.\n")
for i in 0...n do
s = ARGF.gets
printf("%d) %s",i,s)
s = s.split
for j in 0...n do
- a << BigDecimal.new(s[j]);
- as << BigDecimal.new(s[j]);
+ a << BigDecimal(s[j])
+ as << BigDecimal(s[j])
end
- b << BigDecimal.new(s[n]);
+ b << BigDecimal(s[n])
end
end
x = lusolve(a,b,ludecomp(a,n,zero,one),zero)
diff --git a/ext/bigdecimal/sample/nlsolve.rb b/ext/bigdecimal/sample/nlsolve.rb
index b1dd08e0a3..c2227dac73 100644
--- a/ext/bigdecimal/sample/nlsolve.rb
+++ b/ext/bigdecimal/sample/nlsolve.rb
@@ -12,11 +12,11 @@ include Newton
class Function # :nodoc: all
def initialize()
- @zero = BigDecimal.new("0.0")
- @one = BigDecimal.new("1.0")
- @two = BigDecimal.new("2.0")
- @ten = BigDecimal.new("10.0")
- @eps = BigDecimal.new("1.0e-16")
+ @zero = BigDecimal("0.0")
+ @one = BigDecimal("1.0")
+ @two = BigDecimal("2.0")
+ @ten = BigDecimal("10.0")
+ @eps = BigDecimal("1.0e-16")
end
def zero;@zero;end
def one ;@one ;end
diff --git a/ext/cgi/escape/depend b/ext/cgi/escape/depend
index 099bb3f14b..fc3875d151 100644
--- a/ext/cgi/escape/depend
+++ b/ext/cgi/escape/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
escape.o: $(RUBY_EXTCONF_H)
escape.o: $(arch_hdrdir)/ruby/config.h
+escape.o: $(hdrdir)/ruby.h
+escape.o: $(hdrdir)/ruby/internal/anyargs.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+escape.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+escape.o: $(hdrdir)/ruby/internal/assume.h
+escape.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+escape.o: $(hdrdir)/ruby/internal/attr/artificial.h
+escape.o: $(hdrdir)/ruby/internal/attr/cold.h
+escape.o: $(hdrdir)/ruby/internal/attr/const.h
+escape.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+escape.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+escape.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+escape.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+escape.o: $(hdrdir)/ruby/internal/attr/error.h
+escape.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+escape.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+escape.o: $(hdrdir)/ruby/internal/attr/format.h
+escape.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+escape.o: $(hdrdir)/ruby/internal/attr/noalias.h
+escape.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+escape.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+escape.o: $(hdrdir)/ruby/internal/attr/noinline.h
+escape.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+escape.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+escape.o: $(hdrdir)/ruby/internal/attr/pure.h
+escape.o: $(hdrdir)/ruby/internal/attr/restrict.h
+escape.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+escape.o: $(hdrdir)/ruby/internal/attr/warning.h
+escape.o: $(hdrdir)/ruby/internal/attr/weakref.h
+escape.o: $(hdrdir)/ruby/internal/cast.h
+escape.o: $(hdrdir)/ruby/internal/compiler_is.h
+escape.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+escape.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+escape.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+escape.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+escape.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+escape.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+escape.o: $(hdrdir)/ruby/internal/compiler_since.h
+escape.o: $(hdrdir)/ruby/internal/config.h
+escape.o: $(hdrdir)/ruby/internal/constant_p.h
+escape.o: $(hdrdir)/ruby/internal/core.h
+escape.o: $(hdrdir)/ruby/internal/core/rarray.h
+escape.o: $(hdrdir)/ruby/internal/core/rbasic.h
+escape.o: $(hdrdir)/ruby/internal/core/rbignum.h
+escape.o: $(hdrdir)/ruby/internal/core/rclass.h
+escape.o: $(hdrdir)/ruby/internal/core/rdata.h
+escape.o: $(hdrdir)/ruby/internal/core/rfile.h
+escape.o: $(hdrdir)/ruby/internal/core/rhash.h
+escape.o: $(hdrdir)/ruby/internal/core/robject.h
+escape.o: $(hdrdir)/ruby/internal/core/rregexp.h
+escape.o: $(hdrdir)/ruby/internal/core/rstring.h
+escape.o: $(hdrdir)/ruby/internal/core/rstruct.h
+escape.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+escape.o: $(hdrdir)/ruby/internal/ctype.h
+escape.o: $(hdrdir)/ruby/internal/dllexport.h
+escape.o: $(hdrdir)/ruby/internal/dosish.h
+escape.o: $(hdrdir)/ruby/internal/error.h
+escape.o: $(hdrdir)/ruby/internal/eval.h
+escape.o: $(hdrdir)/ruby/internal/event.h
+escape.o: $(hdrdir)/ruby/internal/fl_type.h
+escape.o: $(hdrdir)/ruby/internal/gc.h
+escape.o: $(hdrdir)/ruby/internal/glob.h
+escape.o: $(hdrdir)/ruby/internal/globals.h
+escape.o: $(hdrdir)/ruby/internal/has/attribute.h
+escape.o: $(hdrdir)/ruby/internal/has/builtin.h
+escape.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+escape.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+escape.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+escape.o: $(hdrdir)/ruby/internal/has/extension.h
+escape.o: $(hdrdir)/ruby/internal/has/feature.h
+escape.o: $(hdrdir)/ruby/internal/has/warning.h
+escape.o: $(hdrdir)/ruby/internal/intern/array.h
+escape.o: $(hdrdir)/ruby/internal/intern/bignum.h
+escape.o: $(hdrdir)/ruby/internal/intern/class.h
+escape.o: $(hdrdir)/ruby/internal/intern/compar.h
+escape.o: $(hdrdir)/ruby/internal/intern/complex.h
+escape.o: $(hdrdir)/ruby/internal/intern/cont.h
+escape.o: $(hdrdir)/ruby/internal/intern/dir.h
+escape.o: $(hdrdir)/ruby/internal/intern/enum.h
+escape.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+escape.o: $(hdrdir)/ruby/internal/intern/error.h
+escape.o: $(hdrdir)/ruby/internal/intern/eval.h
+escape.o: $(hdrdir)/ruby/internal/intern/file.h
+escape.o: $(hdrdir)/ruby/internal/intern/gc.h
+escape.o: $(hdrdir)/ruby/internal/intern/hash.h
+escape.o: $(hdrdir)/ruby/internal/intern/io.h
+escape.o: $(hdrdir)/ruby/internal/intern/load.h
+escape.o: $(hdrdir)/ruby/internal/intern/marshal.h
+escape.o: $(hdrdir)/ruby/internal/intern/numeric.h
+escape.o: $(hdrdir)/ruby/internal/intern/object.h
+escape.o: $(hdrdir)/ruby/internal/intern/parse.h
+escape.o: $(hdrdir)/ruby/internal/intern/proc.h
+escape.o: $(hdrdir)/ruby/internal/intern/process.h
+escape.o: $(hdrdir)/ruby/internal/intern/random.h
+escape.o: $(hdrdir)/ruby/internal/intern/range.h
+escape.o: $(hdrdir)/ruby/internal/intern/rational.h
+escape.o: $(hdrdir)/ruby/internal/intern/re.h
+escape.o: $(hdrdir)/ruby/internal/intern/ruby.h
+escape.o: $(hdrdir)/ruby/internal/intern/select.h
+escape.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+escape.o: $(hdrdir)/ruby/internal/intern/signal.h
+escape.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+escape.o: $(hdrdir)/ruby/internal/intern/string.h
+escape.o: $(hdrdir)/ruby/internal/intern/struct.h
+escape.o: $(hdrdir)/ruby/internal/intern/thread.h
+escape.o: $(hdrdir)/ruby/internal/intern/time.h
+escape.o: $(hdrdir)/ruby/internal/intern/variable.h
+escape.o: $(hdrdir)/ruby/internal/intern/vm.h
+escape.o: $(hdrdir)/ruby/internal/interpreter.h
+escape.o: $(hdrdir)/ruby/internal/iterator.h
+escape.o: $(hdrdir)/ruby/internal/memory.h
+escape.o: $(hdrdir)/ruby/internal/method.h
+escape.o: $(hdrdir)/ruby/internal/module.h
+escape.o: $(hdrdir)/ruby/internal/newobj.h
+escape.o: $(hdrdir)/ruby/internal/rgengc.h
+escape.o: $(hdrdir)/ruby/internal/scan_args.h
+escape.o: $(hdrdir)/ruby/internal/special_consts.h
+escape.o: $(hdrdir)/ruby/internal/static_assert.h
+escape.o: $(hdrdir)/ruby/internal/stdalign.h
+escape.o: $(hdrdir)/ruby/internal/stdbool.h
+escape.o: $(hdrdir)/ruby/internal/symbol.h
+escape.o: $(hdrdir)/ruby/internal/token_paste.h
+escape.o: $(hdrdir)/ruby/internal/value.h
+escape.o: $(hdrdir)/ruby/internal/value_type.h
+escape.o: $(hdrdir)/ruby/internal/variable.h
+escape.o: $(hdrdir)/ruby/internal/warning_push.h
+escape.o: $(hdrdir)/ruby/internal/xmalloc.h
+escape.o: $(hdrdir)/ruby/assert.h
escape.o: $(hdrdir)/ruby/backward.h
+escape.o: $(hdrdir)/ruby/backward/2/assume.h
+escape.o: $(hdrdir)/ruby/backward/2/attributes.h
+escape.o: $(hdrdir)/ruby/backward/2/bool.h
+escape.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+escape.o: $(hdrdir)/ruby/backward/2/inttypes.h
+escape.o: $(hdrdir)/ruby/backward/2/limits.h
+escape.o: $(hdrdir)/ruby/backward/2/long_long.h
+escape.o: $(hdrdir)/ruby/backward/2/stdalign.h
+escape.o: $(hdrdir)/ruby/backward/2/stdarg.h
escape.o: $(hdrdir)/ruby/defines.h
escape.o: $(hdrdir)/ruby/encoding.h
escape.o: $(hdrdir)/ruby/intern.h
@@ -11,6 +162,5 @@ escape.o: $(hdrdir)/ruby/oniguruma.h
escape.o: $(hdrdir)/ruby/ruby.h
escape.o: $(hdrdir)/ruby/st.h
escape.o: $(hdrdir)/ruby/subst.h
-escape.o: $(top_srcdir)/include/ruby.h
escape.o: escape.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/cgi/escape/escape.c b/ext/cgi/escape/escape.c
index ced1b182eb..809f95ef4c 100644
--- a/ext/cgi/escape/escape.c
+++ b/ext/cgi/escape/escape.c
@@ -11,73 +11,59 @@ RUBY_EXTERN const signed char ruby_digit36_to_number_table[];
static VALUE rb_cCGI, rb_mUtil, rb_mEscape;
static ID id_accept_charset;
-static void
-html_escaped_cat(VALUE str, char c)
-{
- switch (c) {
- case '\'':
- rb_str_cat_cstr(str, "&#39;");
- break;
- case '&':
- rb_str_cat_cstr(str, "&amp;");
- break;
- case '"':
- rb_str_cat_cstr(str, "&quot;");
- break;
- case '<':
- rb_str_cat_cstr(str, "&lt;");
- break;
- case '>':
- rb_str_cat_cstr(str, "&gt;");
- break;
- }
-}
+#define HTML_ESCAPE_MAX_LEN 6
+
+static const struct {
+ uint8_t len;
+ char str[HTML_ESCAPE_MAX_LEN+1];
+} html_escape_table[UCHAR_MAX+1] = {
+#define HTML_ESCAPE(c, str) [c] = {rb_strlen_lit(str), str}
+ HTML_ESCAPE('\'', "&#39;"),
+ HTML_ESCAPE('&', "&amp;"),
+ HTML_ESCAPE('"', "&quot;"),
+ HTML_ESCAPE('<', "&lt;"),
+ HTML_ESCAPE('>', "&gt;"),
+#undef HTML_ESCAPE
+};
static inline void
preserve_original_state(VALUE orig, VALUE dest)
{
rb_enc_associate(dest, rb_enc_get(orig));
-
- RB_OBJ_INFECT_RAW(dest, orig);
}
static VALUE
optimized_escape_html(VALUE str)
{
- long i, len, beg = 0;
- VALUE dest = 0;
- const char *cstr;
-
- len = RSTRING_LEN(str);
- cstr = RSTRING_PTR(str);
-
- for (i = 0; i < len; i++) {
- switch (cstr[i]) {
- case '\'':
- case '&':
- case '"':
- case '<':
- case '>':
- if (!dest) {
- dest = rb_str_buf_new(len);
- }
-
- rb_str_cat(dest, cstr + beg, i - beg);
- beg = i + 1;
-
- html_escaped_cat(dest, cstr[i]);
- break;
- }
+ VALUE vbuf;
+ typedef char escape_buf[HTML_ESCAPE_MAX_LEN];
+ char *buf = *ALLOCV_N(escape_buf, vbuf, RSTRING_LEN(str));
+ const char *cstr = RSTRING_PTR(str);
+ const char *end = cstr + RSTRING_LEN(str);
+
+ char *dest = buf;
+ while (cstr < end) {
+ const unsigned char c = *cstr++;
+ uint8_t len = html_escape_table[c].len;
+ if (len) {
+ memcpy(dest, html_escape_table[c].str, len);
+ dest += len;
+ }
+ else {
+ *dest++ = c;
+ }
}
- if (dest) {
- rb_str_cat(dest, cstr + beg, len - beg);
- preserve_original_state(str, dest);
- return dest;
+ VALUE escaped;
+ if (RSTRING_LEN(str) < (dest - buf)) {
+ escaped = rb_str_new(buf, dest - buf);
+ preserve_original_state(str, escaped);
}
else {
- return rb_str_dup(str);
+ escaped = rb_str_dup(str);
}
+ ALLOCV_END(vbuf);
+ return escaped;
}
static VALUE
@@ -403,6 +389,10 @@ cgiesc_unescape(int argc, VALUE *argv, VALUE self)
void
Init_escape(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
id_accept_charset = rb_intern_const("@@accept_charset");
InitVM(escape);
}
diff --git a/ext/continuation/depend b/ext/continuation/depend
index 9e47f27f3a..6e9e4f0122 100644
--- a/ext/continuation/depend
+++ b/ext/continuation/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
continuation.o: $(RUBY_EXTCONF_H)
continuation.o: $(arch_hdrdir)/ruby/config.h
+continuation.o: $(hdrdir)/ruby/internal/anyargs.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+continuation.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+continuation.o: $(hdrdir)/ruby/internal/assume.h
+continuation.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+continuation.o: $(hdrdir)/ruby/internal/attr/artificial.h
+continuation.o: $(hdrdir)/ruby/internal/attr/cold.h
+continuation.o: $(hdrdir)/ruby/internal/attr/const.h
+continuation.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+continuation.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+continuation.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+continuation.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+continuation.o: $(hdrdir)/ruby/internal/attr/error.h
+continuation.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+continuation.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+continuation.o: $(hdrdir)/ruby/internal/attr/format.h
+continuation.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+continuation.o: $(hdrdir)/ruby/internal/attr/noalias.h
+continuation.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+continuation.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+continuation.o: $(hdrdir)/ruby/internal/attr/noinline.h
+continuation.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+continuation.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+continuation.o: $(hdrdir)/ruby/internal/attr/pure.h
+continuation.o: $(hdrdir)/ruby/internal/attr/restrict.h
+continuation.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+continuation.o: $(hdrdir)/ruby/internal/attr/warning.h
+continuation.o: $(hdrdir)/ruby/internal/attr/weakref.h
+continuation.o: $(hdrdir)/ruby/internal/cast.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_is.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+continuation.o: $(hdrdir)/ruby/internal/compiler_since.h
+continuation.o: $(hdrdir)/ruby/internal/config.h
+continuation.o: $(hdrdir)/ruby/internal/constant_p.h
+continuation.o: $(hdrdir)/ruby/internal/core.h
+continuation.o: $(hdrdir)/ruby/internal/core/rarray.h
+continuation.o: $(hdrdir)/ruby/internal/core/rbasic.h
+continuation.o: $(hdrdir)/ruby/internal/core/rbignum.h
+continuation.o: $(hdrdir)/ruby/internal/core/rclass.h
+continuation.o: $(hdrdir)/ruby/internal/core/rdata.h
+continuation.o: $(hdrdir)/ruby/internal/core/rfile.h
+continuation.o: $(hdrdir)/ruby/internal/core/rhash.h
+continuation.o: $(hdrdir)/ruby/internal/core/robject.h
+continuation.o: $(hdrdir)/ruby/internal/core/rregexp.h
+continuation.o: $(hdrdir)/ruby/internal/core/rstring.h
+continuation.o: $(hdrdir)/ruby/internal/core/rstruct.h
+continuation.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+continuation.o: $(hdrdir)/ruby/internal/ctype.h
+continuation.o: $(hdrdir)/ruby/internal/dllexport.h
+continuation.o: $(hdrdir)/ruby/internal/dosish.h
+continuation.o: $(hdrdir)/ruby/internal/error.h
+continuation.o: $(hdrdir)/ruby/internal/eval.h
+continuation.o: $(hdrdir)/ruby/internal/event.h
+continuation.o: $(hdrdir)/ruby/internal/fl_type.h
+continuation.o: $(hdrdir)/ruby/internal/gc.h
+continuation.o: $(hdrdir)/ruby/internal/glob.h
+continuation.o: $(hdrdir)/ruby/internal/globals.h
+continuation.o: $(hdrdir)/ruby/internal/has/attribute.h
+continuation.o: $(hdrdir)/ruby/internal/has/builtin.h
+continuation.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+continuation.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+continuation.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+continuation.o: $(hdrdir)/ruby/internal/has/extension.h
+continuation.o: $(hdrdir)/ruby/internal/has/feature.h
+continuation.o: $(hdrdir)/ruby/internal/has/warning.h
+continuation.o: $(hdrdir)/ruby/internal/intern/array.h
+continuation.o: $(hdrdir)/ruby/internal/intern/bignum.h
+continuation.o: $(hdrdir)/ruby/internal/intern/class.h
+continuation.o: $(hdrdir)/ruby/internal/intern/compar.h
+continuation.o: $(hdrdir)/ruby/internal/intern/complex.h
+continuation.o: $(hdrdir)/ruby/internal/intern/cont.h
+continuation.o: $(hdrdir)/ruby/internal/intern/dir.h
+continuation.o: $(hdrdir)/ruby/internal/intern/enum.h
+continuation.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+continuation.o: $(hdrdir)/ruby/internal/intern/error.h
+continuation.o: $(hdrdir)/ruby/internal/intern/eval.h
+continuation.o: $(hdrdir)/ruby/internal/intern/file.h
+continuation.o: $(hdrdir)/ruby/internal/intern/gc.h
+continuation.o: $(hdrdir)/ruby/internal/intern/hash.h
+continuation.o: $(hdrdir)/ruby/internal/intern/io.h
+continuation.o: $(hdrdir)/ruby/internal/intern/load.h
+continuation.o: $(hdrdir)/ruby/internal/intern/marshal.h
+continuation.o: $(hdrdir)/ruby/internal/intern/numeric.h
+continuation.o: $(hdrdir)/ruby/internal/intern/object.h
+continuation.o: $(hdrdir)/ruby/internal/intern/parse.h
+continuation.o: $(hdrdir)/ruby/internal/intern/proc.h
+continuation.o: $(hdrdir)/ruby/internal/intern/process.h
+continuation.o: $(hdrdir)/ruby/internal/intern/random.h
+continuation.o: $(hdrdir)/ruby/internal/intern/range.h
+continuation.o: $(hdrdir)/ruby/internal/intern/rational.h
+continuation.o: $(hdrdir)/ruby/internal/intern/re.h
+continuation.o: $(hdrdir)/ruby/internal/intern/ruby.h
+continuation.o: $(hdrdir)/ruby/internal/intern/select.h
+continuation.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+continuation.o: $(hdrdir)/ruby/internal/intern/signal.h
+continuation.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+continuation.o: $(hdrdir)/ruby/internal/intern/string.h
+continuation.o: $(hdrdir)/ruby/internal/intern/struct.h
+continuation.o: $(hdrdir)/ruby/internal/intern/thread.h
+continuation.o: $(hdrdir)/ruby/internal/intern/time.h
+continuation.o: $(hdrdir)/ruby/internal/intern/variable.h
+continuation.o: $(hdrdir)/ruby/internal/intern/vm.h
+continuation.o: $(hdrdir)/ruby/internal/interpreter.h
+continuation.o: $(hdrdir)/ruby/internal/iterator.h
+continuation.o: $(hdrdir)/ruby/internal/memory.h
+continuation.o: $(hdrdir)/ruby/internal/method.h
+continuation.o: $(hdrdir)/ruby/internal/module.h
+continuation.o: $(hdrdir)/ruby/internal/newobj.h
+continuation.o: $(hdrdir)/ruby/internal/rgengc.h
+continuation.o: $(hdrdir)/ruby/internal/scan_args.h
+continuation.o: $(hdrdir)/ruby/internal/special_consts.h
+continuation.o: $(hdrdir)/ruby/internal/static_assert.h
+continuation.o: $(hdrdir)/ruby/internal/stdalign.h
+continuation.o: $(hdrdir)/ruby/internal/stdbool.h
+continuation.o: $(hdrdir)/ruby/internal/symbol.h
+continuation.o: $(hdrdir)/ruby/internal/token_paste.h
+continuation.o: $(hdrdir)/ruby/internal/value.h
+continuation.o: $(hdrdir)/ruby/internal/value_type.h
+continuation.o: $(hdrdir)/ruby/internal/variable.h
+continuation.o: $(hdrdir)/ruby/internal/warning_push.h
+continuation.o: $(hdrdir)/ruby/internal/xmalloc.h
+continuation.o: $(hdrdir)/ruby/assert.h
continuation.o: $(hdrdir)/ruby/backward.h
+continuation.o: $(hdrdir)/ruby/backward/2/assume.h
+continuation.o: $(hdrdir)/ruby/backward/2/attributes.h
+continuation.o: $(hdrdir)/ruby/backward/2/bool.h
+continuation.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+continuation.o: $(hdrdir)/ruby/backward/2/inttypes.h
+continuation.o: $(hdrdir)/ruby/backward/2/limits.h
+continuation.o: $(hdrdir)/ruby/backward/2/long_long.h
+continuation.o: $(hdrdir)/ruby/backward/2/stdalign.h
+continuation.o: $(hdrdir)/ruby/backward/2/stdarg.h
continuation.o: $(hdrdir)/ruby/defines.h
continuation.o: $(hdrdir)/ruby/intern.h
continuation.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/coverage/coverage.c b/ext/coverage/coverage.c
index c2ccd343d0..0af5579ffc 100644
--- a/ext/coverage/coverage.c
+++ b/ext/coverage/coverage.c
@@ -8,10 +8,15 @@
************************************************/
+#include "gc.h"
+#include "internal/hash.h"
+#include "internal/thread.h"
+#include "internal/sanitizers.h"
#include "ruby.h"
#include "vm_core.h"
static int current_mode;
+static VALUE me2counter = Qnil;
/*
* call-seq:
@@ -23,15 +28,8 @@ static VALUE
rb_coverage_start(int argc, VALUE *argv, VALUE klass)
{
VALUE coverages, opt;
- int mode, experimental_mode_enabled = 1;
+ int mode;
- {
- const char *e = getenv("COVERAGE_EXPERIMENTAL_MODE");
- if (!e || !*e) experimental_mode_enabled = 0;
- }
-
- if (!experimental_mode_enabled && argc != 0)
- rb_error_arity(argc, 0, 0);
rb_scan_args(argc, argv, "01", &opt);
if (argc == 0) {
@@ -50,9 +48,19 @@ rb_coverage_start(int argc, VALUE *argv, VALUE klass)
mode |= COVERAGE_TARGET_BRANCHES;
if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("methods")))))
mode |= COVERAGE_TARGET_METHODS;
- if (mode == 0) {
- rb_raise(rb_eRuntimeError, "no measuring target is specified");
- }
+ if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("oneshot_lines"))))) {
+ if (mode & COVERAGE_TARGET_LINES)
+ rb_raise(rb_eRuntimeError, "cannot enable lines and oneshot_lines simultaneously");
+ mode |= COVERAGE_TARGET_LINES;
+ mode |= COVERAGE_TARGET_ONESHOT_LINES;
+ }
+ }
+
+ if (mode & COVERAGE_TARGET_METHODS) {
+ me2counter = rb_ident_hash_new();
+ }
+ else {
+ me2counter = Qnil;
}
coverages = rb_get_coverages();
@@ -61,7 +69,7 @@ rb_coverage_start(int argc, VALUE *argv, VALUE klass)
rb_obj_hide(coverages);
current_mode = mode;
if (mode == 0) mode = COVERAGE_TARGET_LINES;
- rb_set_coverages(coverages, mode);
+ rb_set_coverages(coverages, mode, me2counter);
}
else if (current_mode != mode) {
rb_raise(rb_eRuntimeError, "cannot change the measuring target during coverage measurement");
@@ -69,47 +77,128 @@ rb_coverage_start(int argc, VALUE *argv, VALUE klass)
return Qnil;
}
+struct branch_coverage_result_builder
+{
+ int id;
+ VALUE result;
+ VALUE children;
+ VALUE counters;
+};
+
+static int
+branch_coverage_ii(VALUE _key, VALUE branch, VALUE v)
+{
+ struct branch_coverage_result_builder *b = (struct branch_coverage_result_builder *) v;
+
+ VALUE target_label = RARRAY_AREF(branch, 0);
+ VALUE target_first_lineno = RARRAY_AREF(branch, 1);
+ VALUE target_first_column = RARRAY_AREF(branch, 2);
+ VALUE target_last_lineno = RARRAY_AREF(branch, 3);
+ VALUE target_last_column = RARRAY_AREF(branch, 4);
+ long counter_idx = FIX2LONG(RARRAY_AREF(branch, 5));
+ rb_hash_aset(b->children, rb_ary_new_from_args(6, target_label, LONG2FIX(b->id++), target_first_lineno, target_first_column, target_last_lineno, target_last_column), RARRAY_AREF(b->counters, counter_idx));
+
+ return ST_CONTINUE;
+}
+
+static int
+branch_coverage_i(VALUE _key, VALUE branch_base, VALUE v)
+{
+ struct branch_coverage_result_builder *b = (struct branch_coverage_result_builder *) v;
+
+ VALUE base_type = RARRAY_AREF(branch_base, 0);
+ VALUE base_first_lineno = RARRAY_AREF(branch_base, 1);
+ VALUE base_first_column = RARRAY_AREF(branch_base, 2);
+ VALUE base_last_lineno = RARRAY_AREF(branch_base, 3);
+ VALUE base_last_column = RARRAY_AREF(branch_base, 4);
+ VALUE branches = RARRAY_AREF(branch_base, 5);
+ VALUE children = rb_hash_new();
+ rb_hash_aset(b->result, rb_ary_new_from_args(6, base_type, LONG2FIX(b->id++), base_first_lineno, base_first_column, base_last_lineno, base_last_column), children);
+ b->children = children;
+ rb_hash_foreach(branches, branch_coverage_ii, v);
+
+ return ST_CONTINUE;
+}
+
static VALUE
branch_coverage(VALUE branches)
{
- VALUE ret = rb_hash_new();
- VALUE structure = rb_ary_dup(RARRAY_AREF(branches, 0));
- VALUE counters = rb_ary_dup(RARRAY_AREF(branches, 1));
- int i, j;
- long id = 0;
-
- for (i = 0; i < RARRAY_LEN(structure); i++) {
- VALUE branches = RARRAY_AREF(structure, i);
- VALUE base_type = RARRAY_AREF(branches, 0);
- VALUE base_lineno = RARRAY_AREF(branches, 1);
- VALUE children = rb_hash_new();
- rb_hash_aset(ret, rb_ary_new_from_args(3, base_type, LONG2FIX(id++), base_lineno), children);
- for (j = 2; j < RARRAY_LEN(branches); j += 3) {
- VALUE target_label = RARRAY_AREF(branches, j);
- VALUE target_lineno = RARRAY_AREF(branches, j + 1);
- int idx = FIX2INT(RARRAY_AREF(branches, j + 2));
- rb_hash_aset(children, rb_ary_new_from_args(3, target_label, LONG2FIX(id++), target_lineno), RARRAY_AREF(counters, idx));
- }
- }
+ VALUE structure = RARRAY_AREF(branches, 0);
+
+ struct branch_coverage_result_builder b;
+ b.id = 0;
+ b.result = rb_hash_new();
+ b.counters = RARRAY_AREF(branches, 1);
+
+ rb_hash_foreach(structure, branch_coverage_i, (VALUE)&b);
- return ret;
+ return b.result;
}
-static VALUE
-method_coverage(VALUE methods)
+static int
+method_coverage_i(void *vstart, void *vend, size_t stride, void *data)
{
- VALUE ret = rb_hash_new();
- int i;
- long id = 0;
+ /*
+ * ObjectSpace.each_object(Module){|mod|
+ * mod.instance_methods.each{|mid|
+ * m = mod.instance_method(mid)
+ * if loc = m.source_location
+ * p [m.name, loc, $g_method_cov_counts[m]]
+ * end
+ * }
+ * }
+ */
+ VALUE ncoverages = *(VALUE*)data, v;
- for (i = 0; i < RARRAY_LEN(methods); ) {
- VALUE method_name = RARRAY_AREF(methods, i++);
- VALUE lineno = RARRAY_AREF(methods, i++);
- VALUE counter = RARRAY_AREF(methods, i++);
- rb_hash_aset(ret, rb_ary_new_from_args(3, method_name, LONG2FIX(id++), lineno), counter);
- }
+ for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) {
+ void *poisoned = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
- return ret;
+ if (RB_TYPE_P(v, T_IMEMO) && imemo_type(v) == imemo_ment) {
+ const rb_method_entry_t *me = (rb_method_entry_t *) v;
+ VALUE path, first_lineno, first_column, last_lineno, last_column;
+ VALUE data[5], ncoverage, methods;
+ VALUE methods_id = ID2SYM(rb_intern("methods"));
+ VALUE klass;
+ const rb_method_entry_t *me2 = rb_resolve_me_location(me, data);
+ if (me != me2) continue;
+ klass = me->owner;
+ if (RB_TYPE_P(klass, T_ICLASS)) {
+ rb_bug("T_ICLASS");
+ }
+ path = data[0];
+ first_lineno = data[1];
+ first_column = data[2];
+ last_lineno = data[3];
+ last_column = data[4];
+ if (FIX2LONG(first_lineno) <= 0) continue;
+ ncoverage = rb_hash_aref(ncoverages, path);
+ if (NIL_P(ncoverage)) continue;
+ methods = rb_hash_aref(ncoverage, methods_id);
+
+ {
+ VALUE method_id = ID2SYM(me->def->original_id);
+ VALUE rcount = rb_hash_aref(me2counter, (VALUE) me);
+ VALUE key = rb_ary_new_from_args(6, klass, method_id, first_lineno, first_column, last_lineno, last_column);
+ VALUE rcount2 = rb_hash_aref(methods, key);
+
+ if (NIL_P(rcount)) rcount = LONG2FIX(0);
+ if (NIL_P(rcount2)) rcount2 = LONG2FIX(0);
+ if (!POSFIXABLE(FIX2LONG(rcount) + FIX2LONG(rcount2))) {
+ rcount = LONG2FIX(FIXNUM_MAX);
+ }
+ else {
+ rcount = LONG2FIX(FIX2LONG(rcount) + FIX2LONG(rcount2));
+ }
+ rb_hash_aset(methods, key, rcount);
+ }
+ }
+
+ if (poisoned) {
+ asan_poison_object(v);
+ }
+ }
+ return 0;
}
static int
@@ -126,25 +215,24 @@ coverage_peek_result_i(st_data_t key, st_data_t val, st_data_t h)
}
else {
VALUE h = rb_hash_new();
- VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
- VALUE branches = RARRAY_AREF(coverage, COVERAGE_INDEX_BRANCHES);
- VALUE methods = RARRAY_AREF(coverage, COVERAGE_INDEX_METHODS);
- if (lines) {
+ if (current_mode & COVERAGE_TARGET_LINES) {
+ VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
+ const char *kw = (current_mode & COVERAGE_TARGET_ONESHOT_LINES) ? "oneshot_lines" : "lines";
lines = rb_ary_dup(lines);
rb_ary_freeze(lines);
- rb_hash_aset(h, ID2SYM(rb_intern("lines")), lines);
+ rb_hash_aset(h, ID2SYM(rb_intern(kw)), lines);
}
- if (branches) {
+ if (current_mode & COVERAGE_TARGET_BRANCHES) {
+ VALUE branches = RARRAY_AREF(coverage, COVERAGE_INDEX_BRANCHES);
rb_hash_aset(h, ID2SYM(rb_intern("branches")), branch_coverage(branches));
}
- if (methods) {
- rb_hash_aset(h, ID2SYM(rb_intern("methods")), method_coverage(methods));
+ if (current_mode & COVERAGE_TARGET_METHODS) {
+ rb_hash_aset(h, ID2SYM(rb_intern("methods")), rb_hash_new());
}
- rb_hash_freeze(h);
coverage = h;
}
@@ -157,6 +245,7 @@ coverage_peek_result_i(st_data_t key, st_data_t val, st_data_t h)
* Coverage.peek_result => hash
*
* Returns a hash that contains filename as key and coverage array as value.
+ * This is the same as `Coverage.result(stop: false, clear: false)`.
*
* {
* "file.rb" => [1, 2, nil],
@@ -171,26 +260,65 @@ rb_coverage_peek_result(VALUE klass)
if (!RTEST(coverages)) {
rb_raise(rb_eRuntimeError, "coverage measurement is not enabled");
}
- st_foreach(RHASH_TBL(coverages), coverage_peek_result_i, ncoverages);
+ OBJ_WB_UNPROTECT(coverages);
+ st_foreach(RHASH_TBL_RAW(coverages), coverage_peek_result_i, ncoverages);
+
+ if (current_mode & COVERAGE_TARGET_METHODS) {
+ rb_objspace_each_objects(method_coverage_i, &ncoverages);
+ }
+
rb_hash_freeze(ncoverages);
return ncoverages;
}
+
+static int
+clear_me2counter_i(VALUE key, VALUE value, VALUE unused)
+{
+ rb_hash_aset(me2counter, key, INT2FIX(0));
+ return ST_CONTINUE;
+}
+
/*
* call-seq:
- * Coverage.result => hash
+ * Coverage.result(stop: true, clear: true) => hash
*
- * Returns a hash that contains filename as key and coverage array as value
- * and disables coverage measurement.
+ * Returns a hash that contains filename as key and coverage array as value.
+ * If +clear+ is true, it clears the counters to zero.
+ * If +stop+ is true, it disables coverage measurement.
*/
static VALUE
-rb_coverage_result(VALUE klass)
+rb_coverage_result(int argc, VALUE *argv, VALUE klass)
{
- VALUE ncoverages = rb_coverage_peek_result(klass);
- rb_reset_coverages();
+ VALUE ncoverages;
+ VALUE opt;
+ int stop = 1, clear = 1;
+
+ rb_scan_args(argc, argv, "01", &opt);
+
+ if (argc == 1) {
+ opt = rb_convert_type(opt, T_HASH, "Hash", "to_hash");
+ stop = RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("stop"))));
+ clear = RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("clear"))));
+ }
+
+ ncoverages = rb_coverage_peek_result(klass);
+ if (stop && !clear) {
+ rb_warn("stop implies clear");
+ clear = 1;
+ }
+ if (clear) {
+ rb_clear_coverages();
+ if (!NIL_P(me2counter)) rb_hash_foreach(me2counter, clear_me2counter_i, Qnil);
+ }
+ if (stop) {
+ rb_reset_coverages();
+ me2counter = Qnil;
+ }
return ncoverages;
}
+
/*
* call-seq:
* Coverage.running? => bool
@@ -218,7 +346,7 @@ rb_coverage_running(VALUE klass)
* number of line execution by the interpreter. A +nil+ value means
* coverage is disabled for this line (lines like +else+ and +end+).
*
- * = Example
+ * = Examples
*
* [foo.rb]
* s = 0
@@ -237,13 +365,124 @@ rb_coverage_running(VALUE klass)
* Coverage.start
* require "foo.rb"
* p Coverage.result #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}
+ *
+ * == Lines Coverage
+ *
+ * If a coverage mode is not explicitly specified when starting coverage, lines
+ * coverage is what will run. It reports the number of line executions for each
+ * line.
+ *
+ * require "coverage"
+ * Coverage.start(lines: true)
+ * require "foo.rb"
+ * p Coverage.result #=> {"foo.rb"=>{:lines=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}}
+ *
+ * The value of the lines coverage result is an array containing how many times
+ * each line was executed. Order in this array is important. For example, the
+ * first item in this array, at index 0, reports how many times line 1 of this
+ * file was executed while coverage was run (which, in this example, is one
+ * time).
+ *
+ * A +nil+ value means coverage is disabled for this line (lines like +else+
+ * and +end+).
+ *
+ * == Oneshot Lines Coverage
+ *
+ * Oneshot lines coverage tracks and reports on the executed lines while
+ * coverage is running. It will not report how many times a line was executed,
+ * only that it was executed.
+ *
+ * require "coverage"
+ * Coverage.start(oneshot_lines: true)
+ * require "foo.rb"
+ * p Coverage.result #=> {"foo.rb"=>{:oneshot_lines=>[1, 2, 3, 6, 7]}}
+ *
+ * The value of the oneshot lines coverage result is an array containing the
+ * line numbers that were executed.
+ *
+ * == Branches Coverage
+ *
+ * Branches coverage reports how many times each branch within each conditional
+ * was executed.
+ *
+ * require "coverage"
+ * Coverage.start(branches: true)
+ * require "foo.rb"
+ * p Coverage.result #=> {"foo.rb"=>{:branches=>{[:if, 0, 6, 0, 10, 3]=>{[:then, 1, 7, 2, 7, 7]=>1, [:else, 2, 9, 2, 9, 7]=>0}}}}
+ *
+ * Each entry within the branches hash is a conditional, the value of which is
+ * another hash where each entry is a branch in that conditional. The values
+ * are the number of times the method was executed, and the keys are identifying
+ * information about the branch.
+ *
+ * The information that makes up each key identifying branches or conditionals
+ * is the following, from left to right:
+ *
+ * 1. A label for the type of branch or conditional.
+ * 2. A unique identifier.
+ * 3. The starting line number it appears on in the file.
+ * 4. The starting column number it appears on in the file.
+ * 5. The ending line number it appears on in the file.
+ * 6. The ending column number it appears on in the file.
+ *
+ * == Methods Coverage
+ *
+ * Methods coverage reports how many times each method was executed.
+ *
+ * [foo_method.rb]
+ * class Greeter
+ * def greet
+ * "welcome!"
+ * end
+ * end
+ *
+ * def hello
+ * "Hi"
+ * end
+ *
+ * hello()
+ * Greeter.new.greet()
+ * [EOF]
+ *
+ * require "coverage"
+ * Coverage.start(methods: true)
+ * require "foo_method.rb"
+ * p Coverage.result #=> {"foo_method.rb"=>{:methods=>{[Object, :hello, 7, 0, 9, 3]=>1, [Greeter, :greet, 2, 2, 4, 5]=>1}}}
+ *
+ * Each entry within the methods hash represents a method. The values in this
+ * hash are the number of times the method was executed, and the keys are
+ * identifying information about the method.
+ *
+ * The information that makes up each key identifying a method is the following,
+ * from left to right:
+ *
+ * 1. The class.
+ * 2. The method name.
+ * 3. The starting line number the method appears on in the file.
+ * 4. The starting column number the method appears on in the file.
+ * 5. The ending line number the method appears on in the file.
+ * 6. The ending column number the method appears on in the file.
+ *
+ * == All Coverage Modes
+ *
+ * You can also run all modes of coverage simultaneously with this shortcut.
+ * Note that running all coverage modes does not run both lines and oneshot
+ * lines. Those modes cannot be run simultaneously. Lines coverage is run in
+ * this case, because you can still use it to determine whether or not a line
+ * was executed.
+ *
+ * require "coverage"
+ * Coverage.start(:all)
+ * require "foo.rb"
+ * p Coverage.result #=> {"foo.rb"=>{:lines=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil], :branches=>{[:if, 0, 6, 0, 10, 3]=>{[:then, 1, 7, 2, 7, 7]=>1, [:else, 2, 9, 2, 9, 7]=>0}}, :methods=>{}}}
*/
void
Init_coverage(void)
{
VALUE rb_mCoverage = rb_define_module("Coverage");
rb_define_module_function(rb_mCoverage, "start", rb_coverage_start, -1);
- rb_define_module_function(rb_mCoverage, "result", rb_coverage_result, 0);
+ rb_define_module_function(rb_mCoverage, "result", rb_coverage_result, -1);
rb_define_module_function(rb_mCoverage, "peek_result", rb_coverage_peek_result, 0);
rb_define_module_function(rb_mCoverage, "running?", rb_coverage_running, 0);
+ rb_global_variable(&me2counter);
}
diff --git a/ext/coverage/depend b/ext/coverage/depend
index b6871fc9cb..650b480b9b 100644
--- a/ext/coverage/depend
+++ b/ext/coverage/depend
@@ -1,26 +1,162 @@
-$(OBJS): $(HDRS) $(ruby_headers) \
- $(top_srcdir)/vm_core.h \
- $(top_srcdir)/node.h \
- $(top_srcdir)/vm_debug.h \
- $(top_srcdir)/vm_opts.h \
- {$(VPATH)}id.h \
- $(top_srcdir)/method.h \
- $(top_srcdir)/ruby_atomic.h \
- $(top_srcdir)/thread_pthread.h \
- $(top_srcdir)/internal.h \
- $(top_srcdir)/include/ruby/thread_native.h
-
# AUTOGENERATED DEPENDENCIES START
coverage.o: $(RUBY_EXTCONF_H)
coverage.o: $(arch_hdrdir)/ruby/config.h
+coverage.o: $(hdrdir)/ruby.h
+coverage.o: $(hdrdir)/ruby/assert.h
+coverage.o: $(hdrdir)/ruby/atomic.h
coverage.o: $(hdrdir)/ruby/backward.h
+coverage.o: $(hdrdir)/ruby/backward/2/assume.h
+coverage.o: $(hdrdir)/ruby/backward/2/attributes.h
+coverage.o: $(hdrdir)/ruby/backward/2/bool.h
+coverage.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+coverage.o: $(hdrdir)/ruby/backward/2/inttypes.h
+coverage.o: $(hdrdir)/ruby/backward/2/limits.h
+coverage.o: $(hdrdir)/ruby/backward/2/long_long.h
+coverage.o: $(hdrdir)/ruby/backward/2/stdalign.h
+coverage.o: $(hdrdir)/ruby/backward/2/stdarg.h
coverage.o: $(hdrdir)/ruby/defines.h
-coverage.o: $(hdrdir)/ruby/encoding.h
coverage.o: $(hdrdir)/ruby/intern.h
-coverage.o: $(hdrdir)/ruby/io.h
+coverage.o: $(hdrdir)/ruby/internal/anyargs.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+coverage.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+coverage.o: $(hdrdir)/ruby/internal/assume.h
+coverage.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+coverage.o: $(hdrdir)/ruby/internal/attr/artificial.h
+coverage.o: $(hdrdir)/ruby/internal/attr/cold.h
+coverage.o: $(hdrdir)/ruby/internal/attr/const.h
+coverage.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+coverage.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+coverage.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+coverage.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+coverage.o: $(hdrdir)/ruby/internal/attr/error.h
+coverage.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+coverage.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+coverage.o: $(hdrdir)/ruby/internal/attr/format.h
+coverage.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+coverage.o: $(hdrdir)/ruby/internal/attr/noalias.h
+coverage.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+coverage.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+coverage.o: $(hdrdir)/ruby/internal/attr/noinline.h
+coverage.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+coverage.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+coverage.o: $(hdrdir)/ruby/internal/attr/pure.h
+coverage.o: $(hdrdir)/ruby/internal/attr/restrict.h
+coverage.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+coverage.o: $(hdrdir)/ruby/internal/attr/warning.h
+coverage.o: $(hdrdir)/ruby/internal/attr/weakref.h
+coverage.o: $(hdrdir)/ruby/internal/cast.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_is.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+coverage.o: $(hdrdir)/ruby/internal/compiler_since.h
+coverage.o: $(hdrdir)/ruby/internal/config.h
+coverage.o: $(hdrdir)/ruby/internal/constant_p.h
+coverage.o: $(hdrdir)/ruby/internal/core.h
+coverage.o: $(hdrdir)/ruby/internal/core/rarray.h
+coverage.o: $(hdrdir)/ruby/internal/core/rbasic.h
+coverage.o: $(hdrdir)/ruby/internal/core/rbignum.h
+coverage.o: $(hdrdir)/ruby/internal/core/rclass.h
+coverage.o: $(hdrdir)/ruby/internal/core/rdata.h
+coverage.o: $(hdrdir)/ruby/internal/core/rfile.h
+coverage.o: $(hdrdir)/ruby/internal/core/rhash.h
+coverage.o: $(hdrdir)/ruby/internal/core/robject.h
+coverage.o: $(hdrdir)/ruby/internal/core/rregexp.h
+coverage.o: $(hdrdir)/ruby/internal/core/rstring.h
+coverage.o: $(hdrdir)/ruby/internal/core/rstruct.h
+coverage.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+coverage.o: $(hdrdir)/ruby/internal/ctype.h
+coverage.o: $(hdrdir)/ruby/internal/dllexport.h
+coverage.o: $(hdrdir)/ruby/internal/dosish.h
+coverage.o: $(hdrdir)/ruby/internal/error.h
+coverage.o: $(hdrdir)/ruby/internal/eval.h
+coverage.o: $(hdrdir)/ruby/internal/event.h
+coverage.o: $(hdrdir)/ruby/internal/fl_type.h
+coverage.o: $(hdrdir)/ruby/internal/gc.h
+coverage.o: $(hdrdir)/ruby/internal/glob.h
+coverage.o: $(hdrdir)/ruby/internal/globals.h
+coverage.o: $(hdrdir)/ruby/internal/has/attribute.h
+coverage.o: $(hdrdir)/ruby/internal/has/builtin.h
+coverage.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+coverage.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+coverage.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+coverage.o: $(hdrdir)/ruby/internal/has/extension.h
+coverage.o: $(hdrdir)/ruby/internal/has/feature.h
+coverage.o: $(hdrdir)/ruby/internal/has/warning.h
+coverage.o: $(hdrdir)/ruby/internal/intern/array.h
+coverage.o: $(hdrdir)/ruby/internal/intern/bignum.h
+coverage.o: $(hdrdir)/ruby/internal/intern/class.h
+coverage.o: $(hdrdir)/ruby/internal/intern/compar.h
+coverage.o: $(hdrdir)/ruby/internal/intern/complex.h
+coverage.o: $(hdrdir)/ruby/internal/intern/cont.h
+coverage.o: $(hdrdir)/ruby/internal/intern/dir.h
+coverage.o: $(hdrdir)/ruby/internal/intern/enum.h
+coverage.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+coverage.o: $(hdrdir)/ruby/internal/intern/error.h
+coverage.o: $(hdrdir)/ruby/internal/intern/eval.h
+coverage.o: $(hdrdir)/ruby/internal/intern/file.h
+coverage.o: $(hdrdir)/ruby/internal/intern/gc.h
+coverage.o: $(hdrdir)/ruby/internal/intern/hash.h
+coverage.o: $(hdrdir)/ruby/internal/intern/io.h
+coverage.o: $(hdrdir)/ruby/internal/intern/load.h
+coverage.o: $(hdrdir)/ruby/internal/intern/marshal.h
+coverage.o: $(hdrdir)/ruby/internal/intern/numeric.h
+coverage.o: $(hdrdir)/ruby/internal/intern/object.h
+coverage.o: $(hdrdir)/ruby/internal/intern/parse.h
+coverage.o: $(hdrdir)/ruby/internal/intern/proc.h
+coverage.o: $(hdrdir)/ruby/internal/intern/process.h
+coverage.o: $(hdrdir)/ruby/internal/intern/random.h
+coverage.o: $(hdrdir)/ruby/internal/intern/range.h
+coverage.o: $(hdrdir)/ruby/internal/intern/rational.h
+coverage.o: $(hdrdir)/ruby/internal/intern/re.h
+coverage.o: $(hdrdir)/ruby/internal/intern/ruby.h
+coverage.o: $(hdrdir)/ruby/internal/intern/select.h
+coverage.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+coverage.o: $(hdrdir)/ruby/internal/intern/signal.h
+coverage.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+coverage.o: $(hdrdir)/ruby/internal/intern/string.h
+coverage.o: $(hdrdir)/ruby/internal/intern/struct.h
+coverage.o: $(hdrdir)/ruby/internal/intern/thread.h
+coverage.o: $(hdrdir)/ruby/internal/intern/time.h
+coverage.o: $(hdrdir)/ruby/internal/intern/variable.h
+coverage.o: $(hdrdir)/ruby/internal/intern/vm.h
+coverage.o: $(hdrdir)/ruby/internal/interpreter.h
+coverage.o: $(hdrdir)/ruby/internal/iterator.h
+coverage.o: $(hdrdir)/ruby/internal/memory.h
+coverage.o: $(hdrdir)/ruby/internal/method.h
+coverage.o: $(hdrdir)/ruby/internal/module.h
+coverage.o: $(hdrdir)/ruby/internal/newobj.h
+coverage.o: $(hdrdir)/ruby/internal/rgengc.h
+coverage.o: $(hdrdir)/ruby/internal/scan_args.h
+coverage.o: $(hdrdir)/ruby/internal/special_consts.h
+coverage.o: $(hdrdir)/ruby/internal/static_assert.h
+coverage.o: $(hdrdir)/ruby/internal/stdalign.h
+coverage.o: $(hdrdir)/ruby/internal/stdbool.h
+coverage.o: $(hdrdir)/ruby/internal/symbol.h
+coverage.o: $(hdrdir)/ruby/internal/token_paste.h
+coverage.o: $(hdrdir)/ruby/internal/value.h
+coverage.o: $(hdrdir)/ruby/internal/value_type.h
+coverage.o: $(hdrdir)/ruby/internal/variable.h
+coverage.o: $(hdrdir)/ruby/internal/warning_push.h
+coverage.o: $(hdrdir)/ruby/internal/xmalloc.h
coverage.o: $(hdrdir)/ruby/missing.h
-coverage.o: $(hdrdir)/ruby/onigmo.h
-coverage.o: $(hdrdir)/ruby/oniguruma.h
coverage.o: $(hdrdir)/ruby/ruby.h
coverage.o: $(hdrdir)/ruby/st.h
coverage.o: $(hdrdir)/ruby/subst.h
@@ -29,15 +165,25 @@ coverage.o: $(top_srcdir)/ccan/check_type/check_type.h
coverage.o: $(top_srcdir)/ccan/container_of/container_of.h
coverage.o: $(top_srcdir)/ccan/list/list.h
coverage.o: $(top_srcdir)/ccan/str/str.h
-coverage.o: $(top_srcdir)/include/ruby.h
+coverage.o: $(top_srcdir)/gc.h
coverage.o: $(top_srcdir)/internal.h
+coverage.o: $(top_srcdir)/internal/array.h
+coverage.o: $(top_srcdir)/internal/compilers.h
+coverage.o: $(top_srcdir)/internal/gc.h
+coverage.o: $(top_srcdir)/internal/hash.h
+coverage.o: $(top_srcdir)/internal/imemo.h
+coverage.o: $(top_srcdir)/internal/sanitizers.h
+coverage.o: $(top_srcdir)/internal/serial.h
+coverage.o: $(top_srcdir)/internal/static_assert.h
+coverage.o: $(top_srcdir)/internal/thread.h
+coverage.o: $(top_srcdir)/internal/vm.h
+coverage.o: $(top_srcdir)/internal/warnings.h
coverage.o: $(top_srcdir)/method.h
coverage.o: $(top_srcdir)/node.h
coverage.o: $(top_srcdir)/ruby_assert.h
coverage.o: $(top_srcdir)/ruby_atomic.h
coverage.o: $(top_srcdir)/thread_pthread.h
coverage.o: $(top_srcdir)/vm_core.h
-coverage.o: $(top_srcdir)/vm_debug.h
coverage.o: $(top_srcdir)/vm_opts.h
coverage.o: coverage.c
coverage.o: {$(VPATH)}id.h
diff --git a/ext/coverage/lib/coverage.rb b/ext/coverage/lib/coverage.rb
new file mode 100644
index 0000000000..f1923ef366
--- /dev/null
+++ b/ext/coverage/lib/coverage.rb
@@ -0,0 +1,14 @@
+require "coverage.so"
+
+module Coverage
+ def self.line_stub(file)
+ lines = File.foreach(file).map { nil }
+ iseqs = [RubyVM::InstructionSequence.compile_file(file)]
+ until iseqs.empty?
+ iseq = iseqs.pop
+ iseq.trace_points.each {|n, type| lines[n - 1] = 0 if type == :line }
+ iseq.each_child {|child| iseqs << child }
+ end
+ lines
+ end
+end
diff --git a/ext/date/date.gemspec b/ext/date/date.gemspec
index ab5f0bf399..cf07696976 100644
--- a/ext/date/date.gemspec
+++ b/ext/date/date.gemspec
@@ -1,8 +1,12 @@
# frozen_string_literal: true
+
+version = File.foreach(File.expand_path("../lib/date.rb", __FILE__)).find do |line|
+ /^\s*VERSION\s*=\s*["'](.*)["']/ =~ line and break $1
+end
+
Gem::Specification.new do |s|
s.name = "date"
- s.version = '0.0.1'
- s.date = '2017-02-02'
+ s.version = version
s.summary = "A subclass of Object includes Comparable module for handling dates."
s.description = "A subclass of Object includes Comparable module for handling dates."
@@ -13,12 +17,10 @@ Gem::Specification.new do |s|
"ext/date/zonetab.h", "ext/date/zonetab.list"
]
s.extensions = "ext/date/extconf.rb"
- s.required_ruby_version = ">= 2.5.0dev"
+ s.required_ruby_version = ">= 2.4.0"
s.authors = ["Tadayoshi Funaba"]
s.email = [nil]
s.homepage = "https://github.com/ruby/date"
- s.license = "BSD-2-Clause"
-
- s.add_development_dependency "rake-compiler"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
end
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
index 3b18bbd5b1..66ec0aa92a 100644
--- a/ext/date/date_core.c
+++ b/ext/date/date_core.c
@@ -11,6 +11,7 @@
#include <sys/time.h>
#endif
+#undef NDEBUG
#define NDEBUG
#include <assert.h>
@@ -22,6 +23,7 @@
static ID id_cmp, id_le_p, id_ge_p, id_eqeq_p;
static VALUE cDate, cDateTime;
+static VALUE eDateError;
static VALUE half_days_in_day, day_in_nanoseconds;
static double positive_inf, negative_inf;
@@ -51,18 +53,31 @@ static double positive_inf, negative_inf;
#define f_add3(x,y,z) f_add(f_add(x, y), z)
#define f_sub3(x,y,z) f_sub(f_sub(x, y), z)
-inline static VALUE
+#define f_frozen_ary(...) rb_obj_freeze(rb_ary_new3(__VA_ARGS__))
+
+static VALUE date_initialize(int argc, VALUE *argv, VALUE self);
+static VALUE datetime_initialize(int argc, VALUE *argv, VALUE self);
+
+#define RETURN_FALSE_UNLESS_NUMERIC(obj) if(!RTEST(rb_obj_is_kind_of((obj), rb_cNumeric))) return Qfalse
+inline static void
+check_numeric(VALUE obj, const char* field) {
+ if(!RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) {
+ rb_raise(rb_eTypeError, "invalid %s (not numeric)", field);
+ }
+}
+
+inline static int
f_cmp(VALUE x, VALUE y)
{
if (FIXNUM_P(x) && FIXNUM_P(y)) {
long c = FIX2LONG(x) - FIX2LONG(y);
if (c > 0)
- c = 1;
+ return 1;
else if (c < 0)
- c = -1;
- return INT2FIX(c);
+ return -1;
+ return 0;
}
- return rb_funcall(x, id_cmp, 1, y);
+ return rb_cmpint(rb_funcallv(x, id_cmp, 1, &y), x, y);
}
inline static VALUE
@@ -94,7 +109,7 @@ f_ge_p(VALUE x, VALUE y)
{
if (FIXNUM_P(x) && FIXNUM_P(y))
return f_boolcast(FIX2LONG(x) >= FIX2LONG(y));
- return rb_funcall(x, rb_intern(">="), 1, y);
+ return rb_funcall(x, id_ge_p, 1, y);
}
inline static VALUE
@@ -102,7 +117,7 @@ f_eqeq_p(VALUE x, VALUE y)
{
if (FIXNUM_P(x) && FIXNUM_P(y))
return f_boolcast(FIX2LONG(x) == FIX2LONG(y));
- return rb_funcall(x, rb_intern("=="), 1, y);
+ return rb_funcall(x, id_eqeq_p, 1, y);
}
inline static VALUE
@@ -236,11 +251,8 @@ f_negative_p(VALUE x)
struct SimpleDateData
{
unsigned flags;
- VALUE nth; /* not always canonicalized */
int jd; /* as utc */
- /* df is zero */
- /* sf is zero */
- /* of is zero */
+ VALUE nth; /* not always canonicalized */
date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */
/* decoded as utc=local */
int year; /* truncated */
@@ -259,11 +271,8 @@ struct SimpleDateData
struct ComplexDateData
{
unsigned flags;
- VALUE nth; /* not always canonicalized */
int jd; /* as utc */
- int df; /* as utc, in secs */
- VALUE sf; /* in nano secs */
- int of; /* in secs */
+ VALUE nth; /* not always canonicalized */
date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */
/* decoded as local */
int year; /* truncated */
@@ -277,6 +286,9 @@ struct ComplexDateData
/* packed civil */
unsigned pc;
#endif
+ int df; /* as utc, in secs */
+ int of; /* in secs */
+ VALUE sf; /* in nano secs */
};
union DateData {
@@ -315,31 +327,31 @@ canon(VALUE x)
#ifndef USE_PACK
#define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \
(x)->jd = _jd;\
(x)->sg = (date_sg_t)(_sg);\
(x)->year = _year;\
(x)->mon = _mon;\
(x)->mday = _mday;\
- (x)->flags = _flags;\
-}
+ (x)->flags = (_flags) & ~COMPLEX_DAT;\
+} while (0)
#else
#define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \
(x)->jd = _jd;\
(x)->sg = (date_sg_t)(_sg);\
(x)->year = _year;\
(x)->pc = PACK2(_mon, _mday);\
- (x)->flags = _flags;\
-}
+ (x)->flags = (_flags) & ~COMPLEX_DAT;\
+} while (0)
#endif
#ifndef USE_PACK
#define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\
_year, _mon, _mday, _hour, _min, _sec, _flags) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\
(x)->jd = _jd;\
(x)->df = _df;\
@@ -352,12 +364,12 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
(x)->hour = _hour;\
(x)->min = _min;\
(x)->sec = _sec;\
- (x)->flags = _flags;\
-}
+ (x)->flags = (_flags) | COMPLEX_DAT;\
+} while (0)
#else
#define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\
_year, _mon, _mday, _hour, _min, _sec, _flags) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\
(x)->jd = _jd;\
(x)->df = _df;\
@@ -366,13 +378,13 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
(x)->sg = (date_sg_t)(_sg);\
(x)->year = _year;\
(x)->pc = PACK5(_mon, _mday, _hour, _min, _sec);\
- (x)->flags = _flags;\
-}
+ (x)->flags = (_flags) | COMPLEX_DAT;\
+} while (0)
#endif
#ifndef USE_PACK
#define copy_simple_to_complex(obj, x, y) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
(x)->jd = (y)->jd;\
(x)->df = 0;\
@@ -386,10 +398,10 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
(x)->min = 0;\
(x)->sec = 0;\
(x)->flags = (y)->flags;\
-}
+} while (0)
#else
#define copy_simple_to_complex(obj, x, y) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
(x)->jd = (y)->jd;\
(x)->df = 0;\
@@ -399,12 +411,12 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
(x)->year = (y)->year;\
(x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\
(x)->flags = (y)->flags;\
-}
+} while (0)
#endif
#ifndef USE_PACK
#define copy_complex_to_simple(obj, x, y) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
(x)->jd = (y)->jd;\
(x)->sg = (date_sg_t)((y)->sg);\
@@ -412,17 +424,17 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
(x)->mon = (y)->mon;\
(x)->mday = (y)->mday;\
(x)->flags = (y)->flags;\
-}
+} while (0)
#else
#define copy_complex_to_simple(obj, x, y) \
-{\
+do {\
RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
(x)->jd = (y)->jd;\
(x)->sg = (date_sg_t)((y)->sg);\
(x)->year = (y)->year;\
(x)->pc = PACK2(EX_MON((y)->pc), EX_MDAY((y)->pc));\
(x)->flags = (y)->flags;\
-}
+} while (0)
#endif
/* base */
@@ -1109,7 +1121,7 @@ m_virtual_sg(union DateData *x)
}
#define canonicalize_jd(_nth, _jd) \
-{\
+do {\
if (_jd < 0) {\
_nth = f_sub(_nth, INT2FIX(1));\
_jd += CM_PERIOD;\
@@ -1118,7 +1130,7 @@ m_virtual_sg(union DateData *x)
_nth = f_add(_nth, INT2FIX(1));\
_jd -= CM_PERIOD;\
}\
-}
+} while (0)
inline static void
canonicalize_s_jd(VALUE obj, union DateData *x)
@@ -1928,13 +1940,13 @@ m_sec(union DateData *x)
}
#define decode_offset(of,s,h,m)\
-{\
+do {\
int a;\
s = (of < 0) ? '-' : '+';\
a = (of < 0) ? -of : of;\
h = a / HOUR_IN_SECONDS;\
m = a % HOUR_IN_SECONDS / MINUTE_IN_SECONDS;\
-}
+} while (0)
static VALUE
of2str(int of)
@@ -2333,6 +2345,9 @@ VALUE date_zone_to_diff(VALUE);
static int
offset_to_sec(VALUE vof, int *rof)
{
+ int try_rational = 1;
+
+ again:
switch (TYPE(vof)) {
case T_FIXNUM:
{
@@ -2359,10 +2374,11 @@ offset_to_sec(VALUE vof, int *rof)
default:
expect_numeric(vof);
vof = f_to_r(vof);
-#ifdef CANONICALIZATION_FOR_MATHN
- if (!k_rational_p(vof))
- return offset_to_sec(vof, rof);
-#endif
+ if (!k_rational_p(vof)) {
+ if (!try_rational) Check_Type(vof, T_RATIONAL);
+ try_rational = 0;
+ goto again;
+ }
/* fall through */
case T_RATIONAL:
{
@@ -2371,17 +2387,10 @@ offset_to_sec(VALUE vof, int *rof)
vs = day_to_sec(vof);
-#ifdef CANONICALIZATION_FOR_MATHN
if (!k_rational_p(vs)) {
- if (!FIXNUM_P(vs))
- return 0;
- n = FIX2LONG(vs);
- if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS)
- return 0;
- *rof = (int)n;
- return 1;
+ vn = vs;
+ goto rounded;
}
-#endif
vn = rb_rational_num(vs);
vd = rb_rational_den(vs);
@@ -2391,6 +2400,7 @@ offset_to_sec(VALUE vof, int *rof)
vn = f_round(vs);
if (!f_eqeq_p(vn, vs))
rb_warning("fraction of offset is ignored");
+ rounded:
if (!FIXNUM_P(vn))
return 0;
n = FIX2LONG(vn);
@@ -2420,12 +2430,12 @@ offset_to_sec(VALUE vof, int *rof)
/* date */
#define valid_sg(sg) \
-{\
+do {\
if (!c_valid_start_p(sg)) {\
sg = 0;\
rb_warning("invalid start is ignored");\
}\
-}
+} while (0)
static VALUE
valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
@@ -2472,6 +2482,7 @@ date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass)
rb_scan_args(argc, argv, "11", &vjd, &vsg);
+ RETURN_FALSE_UNLESS_NUMERIC(vjd);
argv2[0] = vjd;
if (argc < 2)
argv2[1] = INT2FIX(DEFAULT_SG);
@@ -2547,9 +2558,12 @@ date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
* Date.valid_date?(year, month, mday[, start=Date::ITALY]) -> bool
*
* Returns true if the given calendar date is valid, and false if not.
+ * Valid in this context is whether the arguments passed to this
+ * method would be accepted by ::new.
*
* Date.valid_date?(2001,2,3) #=> true
* Date.valid_date?(2001,2,29) #=> false
+ * Date.valid_date?(2001,2,-1) #=> true
*
* See also ::jd and ::civil.
*/
@@ -2561,6 +2575,9 @@ date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg);
+ RETURN_FALSE_UNLESS_NUMERIC(vy);
+ RETURN_FALSE_UNLESS_NUMERIC(vm);
+ RETURN_FALSE_UNLESS_NUMERIC(vd);
argv2[0] = vy;
argv2[1] = vm;
argv2[2] = vd;
@@ -2642,6 +2659,8 @@ date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
rb_scan_args(argc, argv, "21", &vy, &vd, &vsg);
+ RETURN_FALSE_UNLESS_NUMERIC(vy);
+ RETURN_FALSE_UNLESS_NUMERIC(vd);
argv2[0] = vy;
argv2[1] = vd;
if (argc < 3)
@@ -2724,6 +2743,9 @@ date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
rb_scan_args(argc, argv, "31", &vy, &vw, &vd, &vsg);
+ RETURN_FALSE_UNLESS_NUMERIC(vy);
+ RETURN_FALSE_UNLESS_NUMERIC(vw);
+ RETURN_FALSE_UNLESS_NUMERIC(vd);
argv2[0] = vy;
argv2[1] = vw;
argv2[2] = vd;
@@ -2905,6 +2927,7 @@ date_s_julian_leap_p(VALUE klass, VALUE y)
VALUE nth;
int ry;
+ check_numeric(y, "year");
decode_year(y, +1, &nth, &ry);
return f_boolcast(c_julian_leap_p(ry));
}
@@ -2926,6 +2949,7 @@ date_s_gregorian_leap_p(VALUE klass, VALUE y)
VALUE nth;
int ry;
+ check_numeric(y, "year");
decode_year(y, -1, &nth, &ry);
return f_boolcast(c_gregorian_leap_p(ry));
}
@@ -2949,11 +2973,15 @@ d_lite_memsize(const void *ptr)
return complex_dat_p(dat) ? sizeof(struct ComplexDateData) : sizeof(struct SimpleDateData);
}
+#ifndef HAVE_RB_EXT_RACTOR_SAFE
+# define RUBY_TYPED_FROZEN_SHAREABLE 0
+#endif
+
static const rb_data_type_t d_lite_type = {
"Date",
{d_lite_gc_mark, RUBY_TYPED_DEFAULT_FREE, d_lite_memsize,},
0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED,
+ RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED|RUBY_TYPED_FROZEN_SHAREABLE,
};
inline static VALUE
@@ -2968,7 +2996,7 @@ d_simple_new_internal(VALUE klass,
obj = TypedData_Make_Struct(klass, struct SimpleDateData,
&d_lite_type, dat);
- set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags & ~COMPLEX_DAT);
+ set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags);
assert(have_jd_p(dat) || have_civil_p(dat));
@@ -2990,7 +3018,7 @@ d_complex_new_internal(VALUE klass,
obj = TypedData_Make_Struct(klass, struct ComplexDateData,
&d_lite_type, dat);
set_to_complex(obj, dat, nth, jd, df, sf, of, sg,
- y, m, d, h, min, s, flags | COMPLEX_DAT);
+ y, m, d, h, min, s, flags);
assert(have_jd_p(dat) || have_civil_p(dat));
assert(have_df_p(dat) || have_time_p(dat));
@@ -3049,7 +3077,7 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg,
*rsg = NUM2DBL(sg);
if (*rdf < 0 || *rdf >= DAY_IN_SECONDS)
- rb_raise(rb_eArgError, "invalid day fraction");
+ rb_raise(eDateError, "invalid day fraction");
if (f_lt_p(*rsf, INT2FIX(0)) ||
f_ge_p(*rsf, INT2FIX(SECOND_IN_NANOSECONDS)))
@@ -3207,47 +3235,47 @@ s_trunc(VALUE s, VALUE *fr)
}
#define num2num_with_frac(s,n) \
-{\
+do {\
s = s##_trunc(v##s, &fr);\
if (f_nonzero_p(fr)) {\
if (argc > n)\
- rb_raise(rb_eArgError, "invalid fraction");\
+ rb_raise(eDateError, "invalid fraction");\
fr2 = fr;\
}\
-}
+} while (0)
#define num2int_with_frac(s,n) \
-{\
+do {\
s = NUM2INT(s##_trunc(v##s, &fr));\
if (f_nonzero_p(fr)) {\
if (argc > n)\
- rb_raise(rb_eArgError, "invalid fraction");\
+ rb_raise(eDateError, "invalid fraction");\
fr2 = fr;\
}\
-}
+} while (0)
#define canon24oc() \
-{\
+do {\
if (rh == 24) {\
rh = 0;\
fr2 = f_add(fr2, INT2FIX(1));\
}\
-}
+} while (0)
#define add_frac() \
-{\
+do {\
if (f_nonzero_p(fr2))\
ret = d_lite_plus(ret, fr2);\
-}
+} while (0)
#define val2sg(vsg,dsg) \
-{\
+do {\
dsg = NUM2DBL(vsg);\
if (!c_valid_start_p(dsg)) {\
dsg = DEFAULT_SG;\
rb_warning("invalid start is ignored");\
}\
-}
+} while (0)
static VALUE d_lite_plus(VALUE, VALUE);
@@ -3280,6 +3308,7 @@ date_s_jd(int argc, VALUE *argv, VALUE klass)
case 2:
val2sg(vsg, sg);
case 1:
+ check_numeric(vjd, "jd");
num2num_with_frac(jd, positive_inf);
}
@@ -3332,8 +3361,10 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
case 3:
val2sg(vsg, sg);
case 2:
+ check_numeric(vd, "yday");
num2int_with_frac(d, positive_inf);
case 1:
+ check_numeric(vy, "year");
y = vy;
}
@@ -3345,7 +3376,7 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
@@ -3385,9 +3416,20 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
static VALUE
date_s_civil(int argc, VALUE *argv, VALUE klass)
{
+ return date_initialize(argc, argv, d_lite_s_alloc_simple(klass));
+}
+
+static VALUE
+date_initialize(int argc, VALUE *argv, VALUE self)
+{
VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
int m, d;
double sg;
+ struct SimpleDateData *dat = rb_check_typeddata(self, &d_lite_type);
+
+ if (!simple_dat_p(dat)) {
+ rb_raise(rb_eTypeError, "Date expected");
+ }
rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg);
@@ -3401,10 +3443,13 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
case 4:
val2sg(vsg, sg);
case 3:
+ check_numeric(vd, "day");
num2int_with_frac(d, positive_inf);
case 2:
+ check_numeric(vm, "month");
m = NUM2INT(vm);
case 1:
+ check_numeric(vy, "year");
y = vy;
}
@@ -3415,13 +3460,9 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
if (!valid_gregorian_p(y, m, d,
&nth, &ry,
&rm, &rd))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
- ret = d_simple_new_internal(klass,
- nth, 0,
- sg,
- ry, rm, rd,
- HAVE_CIVIL);
+ set_to_simple(self, dat, nth, 0, sg, ry, rm, rd, HAVE_CIVIL);
}
else {
VALUE nth;
@@ -3431,14 +3472,11 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rm, &rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
- ret = d_simple_new_internal(klass,
- nth, rjd,
- sg,
- ry, rm, rd,
- HAVE_JD | HAVE_CIVIL);
+ set_to_simple(self, dat, nth, rjd, sg, ry, rm, rd, HAVE_JD | HAVE_CIVIL);
}
+ ret = self;
add_frac();
return ret;
}
@@ -3478,10 +3516,13 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass)
case 4:
val2sg(vsg, sg);
case 3:
+ check_numeric(vd, "cwday");
num2int_with_frac(d, positive_inf);
case 2:
+ check_numeric(vw, "cweek");
w = NUM2INT(vw);
case 1:
+ check_numeric(vy, "year");
y = vy;
}
@@ -3493,7 +3534,7 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rw, &rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
@@ -3543,7 +3584,7 @@ date_s_weeknum(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rw, &rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
@@ -3592,7 +3633,7 @@ date_s_nth_kday(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rm, &rn, &rk, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
@@ -3679,16 +3720,18 @@ date_s_today(int argc, VALUE *argv, VALUE klass)
#define ref_hash0(k) rb_hash_aref(hash, k)
#define del_hash0(k) rb_hash_delete(hash, k)
-#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
-#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
-#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
+#define sym(x) ID2SYM(rb_intern(x""))
+
+#define set_hash(k,v) set_hash0(sym(k), v)
+#define ref_hash(k) ref_hash0(sym(k))
+#define del_hash(k) del_hash0(sym(k))
static VALUE
rt_rewrite_frags(VALUE hash)
{
VALUE seconds;
- seconds = ref_hash("seconds");
+ seconds = del_hash("seconds");
if (!NIL_P(seconds)) {
VALUE offset, d, h, min, s, fr;
@@ -3713,13 +3756,10 @@ rt_rewrite_frags(VALUE hash)
set_hash("min", min);
set_hash("sec", s);
set_hash("sec_fraction", fr);
- del_hash("seconds");
}
return hash;
}
-#define sym(x) ID2SYM(rb_intern(x))
-
static VALUE d_lite_year(VALUE);
static VALUE d_lite_wday(VALUE);
static VALUE d_lite_jd(VALUE);
@@ -3733,89 +3773,89 @@ rt_complete_frags(VALUE klass, VALUE hash)
VALUE k, a, d;
if (NIL_P(tab)) {
- tab = rb_ary_new3(11,
- rb_ary_new3(2,
+ tab = f_frozen_ary(11,
+ f_frozen_ary(2,
sym("time"),
- rb_ary_new3(3,
+ f_frozen_ary(3,
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
Qnil,
- rb_ary_new3(1,
+ f_frozen_ary(1,
sym("jd"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
sym("ordinal"),
- rb_ary_new3(5,
+ f_frozen_ary(5,
sym("year"),
sym("yday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
sym("civil"),
- rb_ary_new3(6,
+ f_frozen_ary(6,
sym("year"),
sym("mon"),
sym("mday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
sym("commercial"),
- rb_ary_new3(6,
+ f_frozen_ary(6,
sym("cwyear"),
sym("cweek"),
sym("cwday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
sym("wday"),
- rb_ary_new3(4,
+ f_frozen_ary(4,
sym("wday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
sym("wnum0"),
- rb_ary_new3(6,
+ f_frozen_ary(6,
sym("year"),
sym("wnum0"),
sym("wday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
sym("wnum1"),
- rb_ary_new3(6,
+ f_frozen_ary(6,
sym("year"),
sym("wnum1"),
sym("wday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
Qnil,
- rb_ary_new3(6,
+ f_frozen_ary(6,
sym("cwyear"),
sym("cweek"),
sym("wday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
Qnil,
- rb_ary_new3(6,
+ f_frozen_ary(6,
sym("year"),
sym("wnum0"),
sym("cwday"),
sym("hour"),
sym("min"),
sym("sec"))),
- rb_ary_new3(2,
+ f_frozen_ary(2,
Qnil,
- rb_ary_new3(6,
+ f_frozen_ary(6,
sym("year"),
sym("wnum1"),
sym("cwday"),
@@ -4140,7 +4180,7 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
}
if (NIL_P(hash))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (NIL_P(ref_hash("jd")) &&
NIL_P(ref_hash("yday")) &&
@@ -4157,7 +4197,7 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
}
if (NIL_P(jd))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
{
VALUE nth;
int rjd;
@@ -4212,12 +4252,10 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
if (!NIL_P(zone)) {
rb_enc_copy(zone, vstr);
- OBJ_INFECT(zone, vstr);
set_hash("zone", zone);
}
if (!NIL_P(left)) {
rb_enc_copy(left, vstr);
- OBJ_INFECT(left, vstr);
set_hash("leftover", left);
}
}
@@ -4290,12 +4328,40 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
VALUE date__parse(VALUE str, VALUE comp);
+static size_t
+get_limit(VALUE opt)
+{
+ if (!NIL_P(opt)) {
+ VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit")));
+ if (NIL_P(limit)) return SIZE_MAX;
+ return NUM2SIZET(limit);
+ }
+ return 128;
+}
+
+static void
+check_limit(VALUE str, VALUE opt)
+{
+ if (NIL_P(str)) return;
+ if (SYMBOL_P(str)) str = rb_sym2str(str);
+
+ StringValue(str);
+ size_t slen = RSTRING_LEN(str);
+ size_t limit = get_limit(opt);
+ if (slen > limit) {
+ rb_raise(rb_eArgError,
+ "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
+ }
+}
+
static VALUE
date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
{
- VALUE vstr, vcomp, hash;
+ VALUE vstr, vcomp, hash, opt;
- rb_scan_args(argc, argv, "11", &vstr, &vcomp);
+ rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt);
+ if (!NIL_P(opt)) argc--;
+ check_limit(vstr, opt);
StringValue(vstr);
if (!rb_enc_str_asciicompat_p(vstr))
rb_raise(rb_eArgError,
@@ -4305,32 +4371,30 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
hash = date__parse(vstr, vcomp);
- {
- VALUE zone = ref_hash("zone");
-
- if (!NIL_P(zone)) {
- rb_enc_copy(zone, vstr);
- OBJ_INFECT(zone, vstr);
- set_hash("zone", zone);
- }
- }
-
return hash;
}
/*
* call-seq:
- * Date._parse(string[, comp=true]) -> hash
+ * Date._parse(string[, comp=true], limit: 128) -> hash
*
* Parses the given representation of date and time, and returns a
- * hash of parsed elements. This method does not function as a
- * validator.
+ * hash of parsed elements.
+ *
+ * This method **does not** function as a validator. If the input
+ * string does not match valid formats strictly, you may get a cryptic
+ * result. Should consider to use `Date._strptime` or
+ * `DateTime._strptime` instead of this method as possible.
*
* If the optional second argument is true and the detected year is in
* the range "00" to "99", considers the year a 2-digit form and makes
* it full.
*
* Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s__parse(int argc, VALUE *argv, VALUE klass)
@@ -4340,10 +4404,15 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]]) -> date
+ * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]], limit: 128) -> date
*
* Parses the given representation of date and time, and creates a
- * date object. This method does not function as a validator.
+ * date object.
+ *
+ * This method **does not** function as a validator. If the input
+ * string does not match valid formats strictly, you may get a cryptic
+ * result. Should consider to use `Date.strptime` instead of this
+ * method as possible.
*
* If the optional second argument is true and the detected year is in
* the range "00" to "99", considers the year a 2-digit form and makes
@@ -4352,13 +4421,18 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
* Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...>
* Date.parse('20010203') #=> #<Date: 2001-02-03 ...>
* Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_parse(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, comp, sg;
+ VALUE str, comp, sg, opt;
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4370,11 +4444,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE argv2[2], hash;
-
- argv2[0] = str;
- argv2[1] = comp;
- hash = date_s__parse(2, argv2, klass);
+ int argc2 = 2;
+ VALUE argv2[3];
+ argv2[0] = str;
+ argv2[1] = comp;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__parse(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
@@ -4388,19 +4463,28 @@ VALUE date__jisx0301(VALUE);
/*
* call-seq:
- * Date._iso8601(string) -> hash
+ * Date._iso8601(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__iso8601(VALUE klass, VALUE str)
+date_s__iso8601(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__iso8601(str);
}
/*
* call-seq:
- * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY]) -> date
+ * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical ISO 8601 formats.
@@ -4408,13 +4492,18 @@ date_s__iso8601(VALUE klass, VALUE str)
* Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...>
* Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...>
* Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4424,38 +4513,56 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__iso8601(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__iso8601(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._rfc3339(string) -> hash
+ * Date._rfc3339(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__rfc3339(VALUE klass, VALUE str)
+date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__rfc3339(str);
}
/*
* call-seq:
- * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> date
+ * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical RFC 3339 formats.
*
* Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4465,38 +4572,56 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc3339(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__rfc3339(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._xmlschema(string) -> hash
+ * Date._xmlschema(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__xmlschema(VALUE klass, VALUE str)
+date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__xmlschema(str);
}
/*
* call-seq:
- * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY]) -> date
+ * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical XML Schema formats.
*
* Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4506,41 +4631,58 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__xmlschema(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__xmlschema(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._rfc2822(string) -> hash
- * Date._rfc822(string) -> hash
+ * Date._rfc2822(string, limit: 128) -> hash
+ * Date._rfc822(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__rfc2822(VALUE klass, VALUE str)
+date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__rfc2822(str);
}
/*
* call-seq:
- * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
- * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
+ * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
+ * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical RFC 2822 formats.
*
* Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
* #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
@@ -4550,39 +4692,56 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc2822(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__rfc2822(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._httpdate(string) -> hash
+ * Date._httpdate(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__httpdate(VALUE klass, VALUE str)
+date_s__httpdate(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__httpdate(str);
}
/*
* call-seq:
- * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) -> date
+ * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some RFC 2616 format.
*
* Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
* #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
@@ -4592,38 +4751,60 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__httpdate(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__httpdate(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._jisx0301(string) -> hash
+ * Date._jisx0301(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__jisx0301(VALUE klass, VALUE str)
+date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__jisx0301(str);
}
/*
* call-seq:
- * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY]) -> date
+ * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical JIS X 0301 formats.
*
* Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
+ *
+ * For no-era year, legacy format, Heisei is assumed.
+ *
+ * Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4633,7 +4814,11 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__jisx0301(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__jisx0301(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
@@ -4691,14 +4876,14 @@ dup_obj_as_complex(VALUE self)
}
#define val2off(vof,iof) \
-{\
+do {\
if (!offset_to_sec(vof, &iof)) {\
iof = 0;\
rb_warning("invalid offset is ignored");\
}\
-}
+} while (0)
-#ifndef NDEBUG
+#if 0
static VALUE
d_lite_initialize(int argc, VALUE *argv, VALUE self)
{
@@ -4707,7 +4892,6 @@ d_lite_initialize(int argc, VALUE *argv, VALUE self)
double sg;
rb_check_frozen(self);
- rb_check_trusted(self);
rb_scan_args(argc, argv, "05", &vjd, &vdf, &vsf, &vof, &vsg);
@@ -4726,11 +4910,11 @@ d_lite_initialize(int argc, VALUE *argv, VALUE self)
sf = vsf;
if (f_lt_p(sf, INT2FIX(0)) ||
f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS)))
- rb_raise(rb_eArgError, "invalid second fraction");
+ rb_raise(eDateError, "invalid second fraction");
case 2:
df = NUM2INT(vdf);
if (df < 0 || df >= DAY_IN_SECONDS)
- rb_raise(rb_eArgError, "invalid day fraction");
+ rb_raise(eDateError, "invalid day fraction");
case 1:
jd = vjd;
}
@@ -4751,7 +4935,7 @@ d_lite_initialize(int argc, VALUE *argv, VALUE self)
"cannot load complex into simple");
set_to_complex(self, &dat->c, nth, rjd, df, sf, of, sg,
- 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF | COMPLEX_DAT);
+ 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF);
}
}
return self;
@@ -4763,15 +4947,34 @@ static VALUE
d_lite_initialize_copy(VALUE copy, VALUE date)
{
rb_check_frozen(copy);
- rb_check_trusted(copy);
if (copy == date)
return copy;
{
get_d2(copy, date);
if (simple_dat_p(bdat)) {
- adat->s = bdat->s;
- adat->s.flags &= ~COMPLEX_DAT;
+ if (simple_dat_p(adat)) {
+ adat->s = bdat->s;
+ }
+ else {
+ adat->c.flags = bdat->s.flags | COMPLEX_DAT;
+ adat->c.nth = bdat->s.nth;
+ adat->c.jd = bdat->s.jd;
+ adat->c.df = 0;
+ adat->c.sf = INT2FIX(0);
+ adat->c.of = 0;
+ adat->c.sg = bdat->s.sg;
+ adat->c.year = bdat->s.year;
+#ifndef USE_PACK
+ adat->c.mon = bdat->s.mon;
+ adat->c.mday = bdat->s.mday;
+ adat->c.hour = bdat->s.hour;
+ adat->c.min = bdat->s.min;
+ adat->c.sec = bdat->s.sec;
+#else
+ adat->c.pc = bdat->s.pc;
+#endif
+ }
}
else {
if (!complex_dat_p(adat))
@@ -4779,7 +4982,6 @@ d_lite_initialize_copy(VALUE copy, VALUE date)
"cannot load complex into simple");
adat->c = bdat->c;
- adat->c.flags |= COMPLEX_DAT;
}
}
return copy;
@@ -5513,8 +5715,10 @@ d_lite_new_offset(int argc, VALUE *argv, VALUE self)
static VALUE
d_lite_plus(VALUE self, VALUE other)
{
+ int try_rational = 1;
get_d1(self);
+ again:
switch (TYPE(other)) {
case T_FIXNUM:
{
@@ -5724,18 +5928,21 @@ d_lite_plus(VALUE self, VALUE other)
default:
expect_numeric(other);
other = f_to_r(other);
-#ifdef CANONICALIZATION_FOR_MATHN
- if (!k_rational_p(other))
- return d_lite_plus(self, other);
-#endif
+ if (!k_rational_p(other)) {
+ if (!try_rational) Check_Type(other, T_RATIONAL);
+ try_rational = 0;
+ goto again;
+ }
/* fall through */
case T_RATIONAL:
{
VALUE nth, sf, t;
int jd, df, s;
- if (wholenum_p(other))
- return d_lite_plus(self, rb_rational_num(other));
+ if (wholenum_p(other)) {
+ other = rb_rational_num(other);
+ goto again;
+ }
if (f_positive_p(other))
s = +1;
@@ -6017,7 +6224,7 @@ d_lite_rshift(VALUE self, VALUE other)
&rm, &rd, &rjd, &ns))
break;
if (--d < 1)
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
}
encode_jd(nth, rjd, &rjd2);
return d_lite_plus(self, f_sub(rjd2, m_real_local_jd(dat)));
@@ -6154,6 +6361,7 @@ static VALUE
d_lite_step(int argc, VALUE *argv, VALUE self)
{
VALUE limit, step, date;
+ int c;
rb_scan_args(argc, argv, "11", &limit, &step);
@@ -6168,25 +6376,22 @@ d_lite_step(int argc, VALUE *argv, VALUE self)
RETURN_ENUMERATOR(self, argc, argv);
date = self;
- switch (FIX2INT(f_cmp(step, INT2FIX(0)))) {
- case -1:
+ c = f_cmp(step, INT2FIX(0));
+ if (c < 0) {
while (FIX2INT(d_lite_cmp(date, limit)) >= 0) {
rb_yield(date);
date = d_lite_plus(date, step);
}
- break;
- case 0:
+ }
+ else if (c == 0) {
while (1)
rb_yield(date);
- break;
- case 1:
+ }
+ else /* if (c > 0) */ {
while (FIX2INT(d_lite_cmp(date, limit)) <= 0) {
rb_yield(date);
date = d_lite_plus(date, step);
}
- break;
- default:
- abort();
}
return self;
}
@@ -6241,10 +6446,10 @@ cmp_gen(VALUE self, VALUE other)
get_d1(self);
if (k_numeric_p(other))
- return f_cmp(m_ajd(dat), other);
+ return INT2FIX(f_cmp(m_ajd(dat), other));
else if (k_date_p(other))
- return f_cmp(m_ajd(dat), f_ajd(other));
- return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
+ return INT2FIX(f_cmp(m_ajd(dat), f_ajd(other)));
+ return rb_num_coerce_cmp(self, other, id_cmp);
}
static VALUE
@@ -6373,7 +6578,7 @@ equal_gen(VALUE self, VALUE other)
return f_eqeq_p(m_real_local_jd(dat), other);
else if (k_date_p(other))
return f_eqeq_p(m_real_local_jd(dat), f_jd(other));
- return rb_num_coerce_cmp(self, other, rb_intern("=="));
+ return rb_num_coerce_cmp(self, other, id_eqeq_p);
}
/*
@@ -6471,7 +6676,7 @@ d_lite_to_s(VALUE self)
static VALUE
mk_inspect_raw(union DateData *x, VALUE klass)
{
- char flags[5];
+ char flags[6];
flags[0] = (x->flags & COMPLEX_DAT) ? 'C' : 'S';
flags[1] = (x->flags & HAVE_JD) ? 'j' : '-';
@@ -6543,9 +6748,9 @@ mk_inspect(union DateData *x, VALUE klass, VALUE to_s)
* Returns the value as a string for inspection.
*
* Date.new(2001,2,3).inspect
- * #=> "#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>"
+ * #=> "#<Date: 2001-02-03>"
* DateTime.new(2001,2,3,4,5,6,'-7').inspect
- * #=> "#<DateTime: 2001-02-03T04:05:06-07:00 ((2451944j,39906s,0n),-25200s,2299161j)>"
+ * #=> "#<DateTime: 2001-02-03T04:05:06-07:00>"
*/
static VALUE
d_lite_inspect(VALUE self)
@@ -6637,7 +6842,9 @@ tmx_m_of(union DateData *x)
static char *
tmx_m_zone(union DateData *x)
{
- return RSTRING_PTR(m_zone(x));
+ VALUE zone = m_zone(x);
+ /* TODO: fix potential dangling pointer */
+ return RSTRING_PTR(zone);
}
static const struct tmx_funcs tmx_funcs = {
@@ -6712,7 +6919,6 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
if (p > fmt) rb_str_cat(str, fmt, p - fmt);
}
rb_enc_copy(str, vfmt);
- OBJ_INFECT(str, vfmt);
return str;
}
else
@@ -6721,7 +6927,6 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
str = rb_str_new(buf, len);
if (buf != buffer) xfree(buf);
rb_enc_copy(str, vfmt);
- OBJ_INFECT(str, vfmt);
return str;
}
@@ -6787,7 +6992,7 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
*
* %M - Minute of the hour (00..59)
*
- * %S - Second of the minute (00..59)
+ * %S - Second of the minute (00..60)
*
* %L - Millisecond of the second (000..999)
* %N - Fractional seconds digits, default is 9 digits (nanosecond)
@@ -7020,10 +7225,14 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y)
c = 'S';
s = 1925;
}
- else {
+ else if (d < 2458605) {
c = 'H';
s = 1988;
}
+ else {
+ c = 'R';
+ s = 2018;
+ }
snprintf(fmt, size, "%c%02ld" ".%%m.%%d", c, FIX2INT(y) - s);
return fmt;
}
@@ -7101,10 +7310,13 @@ d_lite_marshal_dump(VALUE self)
static VALUE
d_lite_marshal_load(VALUE self, VALUE a)
{
+ VALUE nth, sf;
+ int jd, df, of;
+ double sg;
+
get_d1(self);
rb_check_frozen(self);
- rb_check_trusted(self);
if (!RB_TYPE_P(a, T_ARRAY))
rb_raise(rb_eTypeError, "expected an array");
@@ -7113,63 +7325,33 @@ d_lite_marshal_load(VALUE self, VALUE a)
case 2: /* 1.6.x */
case 3: /* 1.8.x, 1.9.2 */
{
- VALUE ajd, of, sg, nth, sf;
- int jd, df, rof;
- double rsg;
-
+ VALUE ajd, vof, vsg;
if (RARRAY_LEN(a) == 2) {
ajd = f_sub(RARRAY_AREF(a, 0), half_days_in_day);
- of = INT2FIX(0);
- sg = RARRAY_AREF(a, 1);
- if (!k_numeric_p(sg))
- sg = DBL2NUM(RTEST(sg) ? GREGORIAN : JULIAN);
+ vof = INT2FIX(0);
+ vsg = RARRAY_AREF(a, 1);
+ if (!k_numeric_p(vsg))
+ vsg = DBL2NUM(RTEST(vsg) ? GREGORIAN : JULIAN);
}
else {
ajd = RARRAY_AREF(a, 0);
- of = RARRAY_AREF(a, 1);
- sg = RARRAY_AREF(a, 2);
+ vof = RARRAY_AREF(a, 1);
+ vsg = RARRAY_AREF(a, 2);
}
- old_to_new(ajd, of, sg,
- &nth, &jd, &df, &sf, &rof, &rsg);
-
- if (!df && f_zero_p(sf) && !rof) {
- set_to_simple(self, &dat->s, nth, jd, rsg, 0, 0, 0, HAVE_JD);
- } else {
- if (!complex_dat_p(dat))
- rb_raise(rb_eArgError,
- "cannot load complex into simple");
-
- set_to_complex(self, &dat->c, nth, jd, df, sf, rof, rsg,
- 0, 0, 0, 0, 0, 0,
- HAVE_JD | HAVE_DF | COMPLEX_DAT);
- }
+ old_to_new(ajd, vof, vsg,
+ &nth, &jd, &df, &sf, &of, &sg);
}
break;
case 6:
{
- VALUE nth, sf;
- int jd, df, of;
- double sg;
-
nth = RARRAY_AREF(a, 0);
jd = NUM2INT(RARRAY_AREF(a, 1));
df = NUM2INT(RARRAY_AREF(a, 2));
sf = RARRAY_AREF(a, 3);
of = NUM2INT(RARRAY_AREF(a, 4));
sg = NUM2DBL(RARRAY_AREF(a, 5));
- if (!df && f_zero_p(sf) && !of) {
- set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
- } else {
- if (!complex_dat_p(dat))
- rb_raise(rb_eArgError,
- "cannot load complex into simple");
-
- set_to_complex(self, &dat->c, nth, jd, df, sf, of, sg,
- 0, 0, 0, 0, 0, 0,
- HAVE_JD | HAVE_DF | COMPLEX_DAT);
- }
}
break;
default:
@@ -7177,6 +7359,21 @@ d_lite_marshal_load(VALUE self, VALUE a)
break;
}
+ if (simple_dat_p(dat)) {
+ if (df || !f_zero_p(sf) || of) {
+ /* loading a fractional date; promote to complex */
+ dat = ruby_xrealloc(dat, sizeof(struct ComplexDateData));
+ RTYPEDDATA(self)->data = dat;
+ goto complex_data;
+ }
+ set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
+ } else {
+ complex_data:
+ set_to_complex(self, &dat->c, nth, jd, df, sf, of, sg,
+ 0, 0, 0, 0, 0, 0,
+ HAVE_JD | HAVE_DF);
+ }
+
if (FL_TEST(a, FL_EXIVAR)) {
rb_copy_generic_ivar(self, a);
FL_SET(self, FL_EXIVAR);
@@ -7232,12 +7429,16 @@ datetime_s_jd(int argc, VALUE *argv, VALUE klass)
case 5:
val2off(vof, rof);
case 4:
+ check_numeric(vs, "second");
num2int_with_frac(s, positive_inf);
case 3:
+ check_numeric(vmin, "minute");
num2int_with_frac(min, 3);
case 2:
+ check_numeric(vh, "hour");
num2int_with_frac(h, 2);
case 1:
+ check_numeric(vjd, "jd");
num2num_with_frac(jd, 1);
}
@@ -7246,7 +7447,7 @@ datetime_s_jd(int argc, VALUE *argv, VALUE klass)
int rh, rmin, rs, rjd, rjd2;
if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
canon24oc();
decode_jd(jd, &nth, &rjd);
@@ -7301,14 +7502,19 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
case 6:
val2off(vof, rof);
case 5:
+ check_numeric(vs, "second");
num2int_with_frac(s, positive_inf);
case 4:
+ check_numeric(vmin, "minute");
num2int_with_frac(min, 4);
case 3:
+ check_numeric(vh, "hour");
num2int_with_frac(h, 3);
case 2:
+ check_numeric(vd, "yday");
num2int_with_frac(d, 2);
case 1:
+ check_numeric(vy, "year");
y = vy;
}
@@ -7320,9 +7526,9 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
canon24oc();
rjd2 = jd_local_to_utc(rjd,
@@ -7357,9 +7563,20 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
+ return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
+}
+
+static VALUE
+datetime_initialize(int argc, VALUE *argv, VALUE self)
+{
VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
int m, d, h, min, s, rof;
double sg;
+ struct ComplexDateData *dat = rb_check_typeddata(self, &d_lite_type);
+
+ if (!complex_dat_p(dat)) {
+ rb_raise(rb_eTypeError, "DateTime expected");
+ }
rb_scan_args(argc, argv, "08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);
@@ -7378,16 +7595,22 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
case 7:
val2off(vof, rof);
case 6:
+ check_numeric(vs, "second");
num2int_with_frac(s, positive_inf);
case 5:
+ check_numeric(vmin, "minute");
num2int_with_frac(min, 5);
case 4:
+ check_numeric(vh, "hour");
num2int_with_frac(h, 4);
case 3:
+ check_numeric(vd, "day");
num2int_with_frac(d, 3);
case 2:
+ check_numeric(vm, "month");
m = NUM2INT(vm);
case 1:
+ check_numeric(vy, "year");
y = vy;
}
@@ -7398,18 +7621,18 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
if (!valid_gregorian_p(y, m, d,
&nth, &ry,
&rm, &rd))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
canon24oc();
- ret = d_complex_new_internal(klass,
- nth, 0,
- 0, INT2FIX(0),
- rof, sg,
- ry, rm, rd,
- rh, rmin, rs,
- HAVE_CIVIL | HAVE_TIME);
+ set_to_complex(self, dat,
+ nth, 0,
+ 0, INT2FIX(0),
+ rof, sg,
+ ry, rm, rd,
+ rh, rmin, rs,
+ HAVE_CIVIL | HAVE_TIME);
}
else {
VALUE nth;
@@ -7419,23 +7642,24 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rm, &rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
canon24oc();
rjd2 = jd_local_to_utc(rjd,
time_to_df(rh, rmin, rs),
rof);
- ret = d_complex_new_internal(klass,
- nth, rjd2,
- 0, INT2FIX(0),
- rof, sg,
- ry, rm, rd,
- rh, rmin, rs,
- HAVE_JD | HAVE_CIVIL | HAVE_TIME);
+ set_to_complex(self, dat,
+ nth, rjd2,
+ 0, INT2FIX(0),
+ rof, sg,
+ ry, rm, rd,
+ rh, rmin, rs,
+ HAVE_JD | HAVE_CIVIL | HAVE_TIME);
}
+ ret = self;
add_frac();
return ret;
}
@@ -7475,16 +7699,22 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
case 7:
val2off(vof, rof);
case 6:
+ check_numeric(vs, "second");
num2int_with_frac(s, positive_inf);
case 5:
+ check_numeric(vmin, "minute");
num2int_with_frac(min, 5);
case 4:
+ check_numeric(vh, "hour");
num2int_with_frac(h, 4);
case 3:
+ check_numeric(vd, "cwday");
num2int_with_frac(d, 3);
case 2:
+ check_numeric(vw, "cweek");
w = NUM2INT(vw);
case 1:
+ check_numeric(vy, "year");
y = vy;
}
@@ -7496,9 +7726,9 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rw, &rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
canon24oc();
rjd2 = jd_local_to_utc(rjd,
@@ -7567,9 +7797,9 @@ datetime_s_weeknum(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rw, &rd, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
canon24oc();
rjd2 = jd_local_to_utc(rjd,
@@ -7636,9 +7866,9 @@ datetime_s_nth_kday(int argc, VALUE *argv, VALUE klass)
&nth, &ry,
&rm, &rn, &rk, &rjd,
&ns))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
canon24oc();
rjd2 = jd_local_to_utc(rjd,
@@ -7781,7 +8011,7 @@ dt_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
}
if (NIL_P(hash))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
if (NIL_P(ref_hash("jd")) &&
NIL_P(ref_hash("yday")) &&
@@ -7808,7 +8038,7 @@ dt_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
}
if (NIL_P(jd))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
{
int rh, rmin, rs;
@@ -7817,7 +8047,7 @@ dt_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
NUM2INT(ref_hash("min")),
NUM2INT(ref_hash("sec")),
&rh, &rmin, &rs))
- rb_raise(rb_eArgError, "invalid date");
+ rb_raise(eDateError, "invalid date");
df = time_to_df(rh, rmin, rs);
}
@@ -7927,10 +8157,15 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]]) -> datetime
+ * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) -> datetime
*
* Parses the given representation of date and time, and creates a
- * DateTime object. This method does not function as a validator.
+ * DateTime object.
+ *
+ * This method **does not** function as a validator. If the input
+ * string does not match valid formats strictly, you may get a cryptic
+ * result. Should consider to use `DateTime.strptime` instead of this
+ * method as possible.
*
* If the optional second argument is true and the detected year is in
* the range "00" to "99", makes it full.
@@ -7941,13 +8176,18 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
* DateTime.parse('3rd Feb 2001 04:05:06 PM')
* #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_parse(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, comp, sg;
+ VALUE str, comp, sg, opt;
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -7959,18 +8199,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE argv2[2], hash;
-
- argv2[0] = str;
- argv2[1] = comp;
- hash = date_s__parse(2, argv2, klass);
+ int argc2 = 2;
+ VALUE argv2[3];
+ argv2[0] = str;
+ argv2[1] = comp;
+ argv2[2] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__parse(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical ISO 8601 formats.
@@ -7981,13 +8223,18 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
* DateTime.iso8601('2001-W05-6T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -7997,27 +8244,37 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__iso8601(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2--;
+ VALUE hash = date_s__iso8601(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical RFC 3339 formats.
*
* DateTime.rfc3339('2001-02-03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8027,27 +8284,37 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc3339(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__rfc3339(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical XML Schema formats.
*
* DateTime.xmlschema('2001-02-03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8057,28 +8324,38 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__xmlschema(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__xmlschema(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
- * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
+ * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
+ * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical RFC 2822 formats.
*
* DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8088,7 +8365,12 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc2822(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__rfc2822(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
@@ -8102,13 +8384,18 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
*
* DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
* #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8118,27 +8405,42 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__httpdate(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__httpdate(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical JIS X 0301 formats.
*
* DateTime.jisx0301('H13.02.03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * For no-era year, legacy format, Heisei is assumed.
+ *
+ * DateTime.jisx0301('13.02.03T04:05:06+07:00')
+ * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8148,7 +8450,12 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__jisx0301(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__jisx0301(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
@@ -8232,7 +8539,7 @@ dt_lite_to_s(VALUE self)
*
* %M - Minute of the hour (00..59)
*
- * %S - Second of the minute (00..59)
+ * %S - Second of the minute (00..60)
*
* %L - Millisecond of the second (000..999)
* %N - Fractional seconds digits, default is 9 digits (nanosecond)
@@ -8526,17 +8833,24 @@ time_to_datetime(VALUE self)
* call-seq:
* d.to_time -> time
*
- * Returns a Time object which denotes self.
+ * Returns a Time object which denotes self. If self is a julian date,
+ * convert it to a gregorian date before converting it to Time.
*/
static VALUE
date_to_time(VALUE self)
{
- get_d1(self);
+ get_d1a(self);
+
+ if (m_julian_p(adat)) {
+ VALUE tmp = d_lite_gregorian(self);
+ get_d1b(tmp);
+ adat = bdat;
+ }
return f_local3(rb_cTime,
- m_real_year(dat),
- INT2FIX(m_mon(dat)),
- INT2FIX(m_mday(dat)));
+ m_real_year(adat),
+ INT2FIX(m_mon(adat)),
+ INT2FIX(m_mday(adat)));
}
/*
@@ -8645,7 +8959,7 @@ datetime_to_date(VALUE self)
VALUE new = d_lite_s_alloc_simple(cDate);
{
get_d1b(new);
- copy_complex_to_simple(new, &bdat->s, &adat->c)
+ copy_complex_to_simple(new, &bdat->s, &adat->c);
bdat->s.jd = m_local_jd(adat);
bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT);
return new;
@@ -9010,18 +9324,22 @@ mk_ary_of_str(long len, const char *a[])
return o;
}
+static VALUE
+d_lite_zero(VALUE x)
+{
+ return INT2FIX(0);
+}
+
void
Init_date_core(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
- assert(fprintf(stderr, "assert() is now active\n"));
-
- id_cmp = rb_intern("<=>");
- id_le_p = rb_intern("<=");
- id_ge_p = rb_intern(">=");
- id_eqeq_p = rb_intern("==");
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
+ RB_EXT_RACTOR_SAFE(true);
+ #endif
+ id_cmp = rb_intern_const("<=>");
+ id_le_p = rb_intern_const("<=");
+ id_ge_p = rb_intern_const(">=");
+ id_eqeq_p = rb_intern_const("==");
half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2));
@@ -9189,6 +9507,7 @@ Init_date_core(void)
*
*/
cDate = rb_define_class("Date", rb_cObject);
+ eDateError = rb_define_class_under(cDate, "Error", rb_eArgError);
rb_include_module(cDate, rb_mComparable);
@@ -9233,23 +9552,22 @@ Init_date_core(void)
*/
rb_define_const(cDate, "GREGORIAN", DBL2NUM(GREGORIAN));
- rb_define_alloc_func(cDate, d_lite_s_alloc);
+ rb_define_alloc_func(cDate, d_lite_s_alloc_simple);
#ifndef NDEBUG
-#define de_define_private_method rb_define_private_method
- de_define_private_method(CLASS_OF(cDate), "_valid_jd?",
+ rb_define_private_method(CLASS_OF(cDate), "_valid_jd?",
date_s__valid_jd_p, -1);
- de_define_private_method(CLASS_OF(cDate), "_valid_ordinal?",
+ rb_define_private_method(CLASS_OF(cDate), "_valid_ordinal?",
date_s__valid_ordinal_p, -1);
- de_define_private_method(CLASS_OF(cDate), "_valid_civil?",
+ rb_define_private_method(CLASS_OF(cDate), "_valid_civil?",
date_s__valid_civil_p, -1);
- de_define_private_method(CLASS_OF(cDate), "_valid_date?",
+ rb_define_private_method(CLASS_OF(cDate), "_valid_date?",
date_s__valid_civil_p, -1);
- de_define_private_method(CLASS_OF(cDate), "_valid_commercial?",
+ rb_define_private_method(CLASS_OF(cDate), "_valid_commercial?",
date_s__valid_commercial_p, -1);
- de_define_private_method(CLASS_OF(cDate), "_valid_weeknum?",
+ rb_define_private_method(CLASS_OF(cDate), "_valid_weeknum?",
date_s__valid_weeknum_p, -1);
- de_define_private_method(CLASS_OF(cDate), "_valid_nth_kday?",
+ rb_define_private_method(CLASS_OF(cDate), "_valid_nth_kday?",
date_s__valid_nth_kday_p, -1);
#endif
@@ -9262,11 +9580,11 @@ Init_date_core(void)
date_s_valid_commercial_p, -1);
#ifndef NDEBUG
- de_define_private_method(CLASS_OF(cDate), "valid_weeknum?",
+ rb_define_private_method(CLASS_OF(cDate), "valid_weeknum?",
date_s_valid_weeknum_p, -1);
- de_define_private_method(CLASS_OF(cDate), "valid_nth_kday?",
+ rb_define_private_method(CLASS_OF(cDate), "valid_nth_kday?",
date_s_valid_nth_kday_p, -1);
- de_define_private_method(CLASS_OF(cDate), "zone_to_diff",
+ rb_define_private_method(CLASS_OF(cDate), "zone_to_diff",
date_s_zone_to_diff, 1);
#endif
@@ -9277,21 +9595,18 @@ Init_date_core(void)
date_s_gregorian_leap_p, 1);
#ifndef NDEBUG
-#define de_define_singleton_method rb_define_singleton_method
-#define de_define_alias rb_define_alias
- de_define_singleton_method(cDate, "new!", date_s_new_bang, -1);
- de_define_alias(rb_singleton_class(cDate), "new_l!", "new");
+ rb_define_singleton_method(cDate, "new!", date_s_new_bang, -1);
+ rb_define_alias(rb_singleton_class(cDate), "new_l!", "new");
#endif
rb_define_singleton_method(cDate, "jd", date_s_jd, -1);
rb_define_singleton_method(cDate, "ordinal", date_s_ordinal, -1);
rb_define_singleton_method(cDate, "civil", date_s_civil, -1);
- rb_define_singleton_method(cDate, "new", date_s_civil, -1);
rb_define_singleton_method(cDate, "commercial", date_s_commercial, -1);
#ifndef NDEBUG
- de_define_singleton_method(cDate, "weeknum", date_s_weeknum, -1);
- de_define_singleton_method(cDate, "nth_kday", date_s_nth_kday, -1);
+ rb_define_singleton_method(cDate, "weeknum", date_s_weeknum, -1);
+ rb_define_singleton_method(cDate, "nth_kday", date_s_nth_kday, -1);
#endif
rb_define_singleton_method(cDate, "today", date_s_today, -1);
@@ -9299,29 +9614,26 @@ Init_date_core(void)
rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1);
rb_define_singleton_method(cDate, "_parse", date_s__parse, -1);
rb_define_singleton_method(cDate, "parse", date_s_parse, -1);
- rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1);
+ rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1);
rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1);
- rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1);
+ rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1);
rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1);
- rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1);
+ rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1);
rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1);
- rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1);
- rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1);
+ rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1);
+ rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1);
rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1);
rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1);
- rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1);
+ rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1);
rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1);
- rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1);
+ rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1);
rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1);
-#ifndef NDEBUG
-#define de_define_method rb_define_method
- de_define_method(cDate, "initialize", d_lite_initialize, -1);
-#endif
+ rb_define_method(cDate, "initialize", date_initialize, -1);
rb_define_method(cDate, "initialize_copy", d_lite_initialize_copy, 1);
#ifndef NDEBUG
- de_define_method(cDate, "fill", d_lite_fill, 0);
+ rb_define_method(cDate, "fill", d_lite_fill, 0);
#endif
rb_define_method(cDate, "ajd", d_lite_ajd, 0);
@@ -9343,8 +9655,8 @@ Init_date_core(void)
rb_define_method(cDate, "cwday", d_lite_cwday, 0);
#ifndef NDEBUG
- de_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
- de_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
+ rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
+ rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
#endif
rb_define_method(cDate, "wday", d_lite_wday, 0);
@@ -9358,18 +9670,14 @@ Init_date_core(void)
rb_define_method(cDate, "saturday?", d_lite_saturday_p, 0);
#ifndef NDEBUG
- de_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
+ rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
#endif
- rb_define_private_method(cDate, "hour", d_lite_hour, 0);
- rb_define_private_method(cDate, "min", d_lite_min, 0);
- rb_define_private_method(cDate, "minute", d_lite_min, 0);
- rb_define_private_method(cDate, "sec", d_lite_sec, 0);
- rb_define_private_method(cDate, "second", d_lite_sec, 0);
- rb_define_private_method(cDate, "sec_fraction", d_lite_sec_fraction, 0);
- rb_define_private_method(cDate, "second_fraction", d_lite_sec_fraction, 0);
- rb_define_private_method(cDate, "offset", d_lite_offset, 0);
- rb_define_private_method(cDate, "zone", d_lite_zone, 0);
+ rb_define_private_method(cDate, "hour", d_lite_zero, 0);
+ rb_define_private_method(cDate, "min", d_lite_zero, 0);
+ rb_define_private_method(cDate, "minute", d_lite_zero, 0);
+ rb_define_private_method(cDate, "sec", d_lite_zero, 0);
+ rb_define_private_method(cDate, "second", d_lite_zero, 0);
rb_define_method(cDate, "julian?", d_lite_julian_p, 0);
rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0);
@@ -9382,8 +9690,6 @@ Init_date_core(void)
rb_define_method(cDate, "julian", d_lite_julian, 0);
rb_define_method(cDate, "gregorian", d_lite_gregorian, 0);
- rb_define_private_method(cDate, "new_offset", d_lite_new_offset, -1);
-
rb_define_method(cDate, "+", d_lite_plus, 1);
rb_define_method(cDate, "-", d_lite_minus, 1);
@@ -9411,7 +9717,7 @@ Init_date_core(void)
rb_define_method(cDate, "to_s", d_lite_to_s, 0);
#ifndef NDEBUG
- de_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0);
+ rb_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0);
#endif
rb_define_method(cDate, "inspect", d_lite_inspect, 0);
@@ -9428,7 +9734,7 @@ Init_date_core(void)
rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0);
#ifndef NDEBUG
- de_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
+ rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
#endif
rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0);
rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1);
@@ -9440,6 +9746,8 @@ Init_date_core(void)
* A subclass of Date that easily handles date, hour, minute, second,
* and offset.
*
+ * DateTime class is considered deprecated. Use Time class.
+ *
* DateTime does not consider any leap seconds, does not track
* any summer time rules.
*
@@ -9500,18 +9808,18 @@ Init_date_core(void)
* === When should you use DateTime and when should you use Time?
*
* It's a common misconception that
- * {William Shakespeare}[http://en.wikipedia.org/wiki/William_Shakespeare]
+ * {William Shakespeare}[https://en.wikipedia.org/wiki/William_Shakespeare]
* and
- * {Miguel de Cervantes}[http://en.wikipedia.org/wiki/Miguel_de_Cervantes]
+ * {Miguel de Cervantes}[https://en.wikipedia.org/wiki/Miguel_de_Cervantes]
* died on the same day in history -
* so much so that UNESCO named April 23 as
- * {World Book Day because of this fact}[http://en.wikipedia.org/wiki/World_Book_Day].
+ * {World Book Day because of this fact}[https://en.wikipedia.org/wiki/World_Book_Day].
* However, because England hadn't yet adopted the
- * {Gregorian Calendar Reform}[http://en.wikipedia.org/wiki/Gregorian_calendar#Gregorian_reform]
- * (and wouldn't until {1752}[http://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750])
+ * {Gregorian Calendar Reform}[https://en.wikipedia.org/wiki/Gregorian_calendar#Gregorian_reform]
+ * (and wouldn't until {1752}[https://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750])
* their deaths are actually 10 days apart.
* Since Ruby's Time class implements a
- * {proleptic Gregorian calendar}[http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar]
+ * {proleptic Gregorian calendar}[https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar]
* and has no concept of calendar reform there's no way
* to express this with Time objects. This is where DateTime steps in:
*
@@ -9555,7 +9863,7 @@ Init_date_core(void)
* #=> Fri, 04 May 1753 00:00:00 +0000
*
* As you can see, if we're accurately tracking the number of
- * {solar years}[http://en.wikipedia.org/wiki/Tropical_year]
+ * {solar years}[https://en.wikipedia.org/wiki/Tropical_year]
* since Shakespeare's birthday then the correct anniversary date
* would be the 4th May and not the 23rd April.
*
@@ -9567,14 +9875,15 @@ Init_date_core(void)
* making the same mistakes as UNESCO. If you also have to deal
* with timezones then best of luck - just bear in mind that
* you'll probably be dealing with
- * {local solar times}[http://en.wikipedia.org/wiki/Solar_time],
+ * {local solar times}[https://en.wikipedia.org/wiki/Solar_time],
* since it wasn't until the 19th century that the introduction
* of the railways necessitated the need for
- * {Standard Time}[http://en.wikipedia.org/wiki/Standard_time#Great_Britain]
+ * {Standard Time}[https://en.wikipedia.org/wiki/Standard_time#Great_Britain]
* and eventually timezones.
*/
cDateTime = rb_define_class("DateTime", cDate);
+ rb_define_alloc_func(cDateTime, d_lite_s_alloc_complex);
rb_define_singleton_method(cDateTime, "jd", datetime_s_jd, -1);
rb_define_singleton_method(cDateTime, "ordinal", datetime_s_ordinal, -1);
@@ -9584,9 +9893,9 @@ Init_date_core(void)
datetime_s_commercial, -1);
#ifndef NDEBUG
- de_define_singleton_method(cDateTime, "weeknum",
+ rb_define_singleton_method(cDateTime, "weeknum",
datetime_s_weeknum, -1);
- de_define_singleton_method(cDateTime, "nth_kday",
+ rb_define_singleton_method(cDateTime, "nth_kday",
datetime_s_nth_kday, -1);
#endif
@@ -9614,19 +9923,16 @@ Init_date_core(void)
rb_define_singleton_method(cDateTime, "jisx0301",
datetime_s_jisx0301, -1);
-#define f_public(m,s) rb_funcall(m, rb_intern("public"), 1,\
- ID2SYM(rb_intern(s)))
-
- f_public(cDateTime, "hour");
- f_public(cDateTime, "min");
- f_public(cDateTime, "minute");
- f_public(cDateTime, "sec");
- f_public(cDateTime, "second");
- f_public(cDateTime, "sec_fraction");
- f_public(cDateTime, "second_fraction");
- f_public(cDateTime, "offset");
- f_public(cDateTime, "zone");
- f_public(cDateTime, "new_offset");
+ rb_define_method(cDateTime, "hour", d_lite_hour, 0);
+ rb_define_method(cDateTime, "min", d_lite_min, 0);
+ rb_define_method(cDateTime, "minute", d_lite_min, 0);
+ rb_define_method(cDateTime, "sec", d_lite_sec, 0);
+ rb_define_method(cDateTime, "second", d_lite_sec, 0);
+ rb_define_method(cDateTime, "sec_fraction", d_lite_sec_fraction, 0);
+ rb_define_method(cDateTime, "second_fraction", d_lite_sec_fraction, 0);
+ rb_define_method(cDateTime, "offset", d_lite_offset, 0);
+ rb_define_method(cDateTime, "zone", d_lite_zone, 0);
+ rb_define_method(cDateTime, "new_offset", d_lite_new_offset, -1);
rb_define_method(cDateTime, "to_s", dt_lite_to_s, 0);
@@ -9654,15 +9960,15 @@ Init_date_core(void)
#ifndef NDEBUG
/* tests */
- de_define_singleton_method(cDate, "test_civil", date_s_test_civil, 0);
- de_define_singleton_method(cDate, "test_ordinal", date_s_test_ordinal, 0);
- de_define_singleton_method(cDate, "test_commercial",
+ rb_define_singleton_method(cDate, "test_civil", date_s_test_civil, 0);
+ rb_define_singleton_method(cDate, "test_ordinal", date_s_test_ordinal, 0);
+ rb_define_singleton_method(cDate, "test_commercial",
date_s_test_commercial, 0);
- de_define_singleton_method(cDate, "test_weeknum", date_s_test_weeknum, 0);
- de_define_singleton_method(cDate, "test_nth_kday", date_s_test_nth_kday, 0);
- de_define_singleton_method(cDate, "test_unit_conv",
+ rb_define_singleton_method(cDate, "test_weeknum", date_s_test_weeknum, 0);
+ rb_define_singleton_method(cDate, "test_nth_kday", date_s_test_nth_kday, 0);
+ rb_define_singleton_method(cDate, "test_unit_conv",
date_s_test_unit_conv, 0);
- de_define_singleton_method(cDate, "test_all", date_s_test_all, 0);
+ rb_define_singleton_method(cDate, "test_all", date_s_test_all, 0);
#endif
}
diff --git a/ext/date/date_parse.c b/ext/date/date_parse.c
index b74230d291..5fa036ed72 100644
--- a/ext/date/date_parse.c
+++ b/ext/date/date_parse.c
@@ -40,9 +40,9 @@ RUBY_EXTERN unsigned long ruby_scan_digits(const char *str, ssize_t len, int bas
#define f_sub_bang(s,r,x) rb_funcall(s, rb_intern("sub!"), 2, r, x)
#define f_gsub_bang(s,r,x) rb_funcall(s, rb_intern("gsub!"), 2, r, x)
-#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
-#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
-#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
+#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k"")), v)
+#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k"")))
+#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k"")))
#define cstr2num(s) rb_cstr_to_inum(s, 10, 0)
#define str2num(s) rb_str_to_inum(s, 10, 0)
@@ -66,7 +66,13 @@ static const char abbr_months[][4] = {
#define asubt_string() rb_str_new("\024", 1)
#endif
-#define DECDIGIT "0123456789"
+static size_t
+digit_span(const char *s, const char *e)
+{
+ size_t i = 0;
+ while (s + i < e && isdigit((unsigned char)s[i])) i++;
+ return i;
+}
static void
s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
@@ -92,7 +98,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
y = d;
d = Qnil;
}
- if (!NIL_P(d) && *RSTRING_PTR(d) == '\'') {
+ if (!NIL_P(d) && RSTRING_LEN(d) > 0 && *RSTRING_PTR(d) == '\'') {
y = d;
d = Qnil;
}
@@ -103,17 +109,20 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
size_t l;
s = RSTRING_PTR(y);
- while (!issign((unsigned char)*s) && !isdigit((unsigned char)*s))
+ ep = RSTRING_END(y);
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
s++;
+ if (s >= ep) goto no_date;
bp = s;
if (issign((unsigned char)*s))
s++;
- l = strspn(s, DECDIGIT);
+ l = digit_span(s, ep);
ep = s + l;
if (*ep) {
y = d;
d = rb_str_new(bp, ep - bp);
}
+ no_date:;
}
if (!NIL_P(m)) {
@@ -152,8 +161,10 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
VALUE iy;
s = RSTRING_PTR(y);
- while (!issign((unsigned char)*s) && !isdigit((unsigned char)*s))
+ ep = RSTRING_END(y);
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
s++;
+ if (s >= ep) goto no_year;
bp = s;
if (issign(*s)) {
s++;
@@ -161,7 +172,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
}
if (sign)
c = Qfalse;
- l = strspn(s, DECDIGIT);
+ l = digit_span(s, ep);
ep = s + l;
if (l > 2)
c = Qfalse;
@@ -175,6 +186,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
ALLOCV_END(vbuf);
}
set_hash("year", iy);
+ no_year:;
}
if (bc)
@@ -186,10 +198,12 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
VALUE im;
s = RSTRING_PTR(m);
- while (!isdigit((unsigned char)*s))
+ ep = RSTRING_END(m);
+ while (s < ep && !isdigit((unsigned char)*s))
s++;
+ if (s >= ep) goto no_month;
bp = s;
- l = strspn(s, DECDIGIT);
+ l = digit_span(s, ep);
ep = s + l;
{
char *buf;
@@ -201,6 +215,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
ALLOCV_END(vbuf);
}
set_hash("mon", im);
+ no_month:;
}
if (!NIL_P(d)) {
@@ -209,10 +224,12 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
VALUE id;
s = RSTRING_PTR(d);
- while (!isdigit((unsigned char)*s))
+ ep = RSTRING_END(d);
+ while (s < ep && !isdigit((unsigned char)*s))
s++;
+ if (s >= ep) goto no_mday;
bp = s;
- l = strspn(s, DECDIGIT);
+ l = digit_span(s, ep);
ep = s + l;
{
char *buf;
@@ -224,6 +241,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
ALLOCV_END(vbuf);
}
set_hash("mday", id);
+ no_mday:;
}
if (!NIL_P(c))
@@ -258,23 +276,24 @@ regcomp(const char *source, long len, int opt)
VALUE pat;
pat = rb_reg_new(source, len, opt);
+ rb_obj_freeze(pat);
rb_gc_register_mark_object(pat);
return pat;
}
#define REGCOMP(pat,opt) \
-{ \
+do { \
if (NIL_P(pat)) \
pat = regcomp(pat##_source, sizeof pat##_source - 1, opt); \
-}
+} while (0)
#define REGCOMP_0(pat) REGCOMP(pat, 0)
#define REGCOMP_I(pat) REGCOMP(pat, ONIG_OPTION_IGNORECASE)
#define MATCH(s,p,c) \
-{ \
+do { \
return match(s, p, hash, c); \
-}
+} while (0)
static int
match(VALUE str, VALUE pat, VALUE hash, int (*cb)(VALUE, VALUE))
@@ -314,95 +333,119 @@ subx(VALUE str, VALUE rep, VALUE pat, VALUE hash, int (*cb)(VALUE, VALUE))
}
#define SUBS(s,p,c) \
-{ \
+do { \
return subx(s, asp_string(), p, hash, c); \
-}
+} while (0)
#ifdef TIGHT_PARSER
#define SUBA(s,p,c) \
-{ \
+do { \
return subx(s, asuba_string(), p, hash, c); \
-}
+} while (0)
#define SUBB(s,p,c) \
-{ \
+do { \
return subx(s, asubb_string(), p, hash, c); \
-}
+} while (0)
#define SUBW(s,p,c) \
-{ \
+do { \
return subx(s, asubw_string(), p, hash, c); \
-}
+} while (0)
#define SUBT(s,p,c) \
-{ \
+do { \
return subx(s, asubt_string(), p, hash, c); \
-}
+} while (0)
#endif
#include "zonetab.h"
static int
-str_end_with(const char *s, long l, const char *w)
+str_end_with_word(const char *s, long l, const char *w)
{
int n = (int)strlen(w);
- return (l >= n && strncmp(s - n, w, n) == 0);
+ if (l <= n || !isspace((unsigned char)s[l - n - 1])) return 0;
+ if (strncasecmp(&s[l - n], w, n)) return 0;
+ do ++n; while (l > n && isspace((unsigned char)s[l - n - 1]));
+ return n;
}
-VALUE
-date_zone_to_diff(VALUE str)
+static long
+shrunk_size(const char *s, long l)
{
- VALUE offset = Qnil;
- VALUE vbuf = 0;
-
- long l, i;
- char *s, *dest, *d;
- int sp = 1;
-
- l = RSTRING_LEN(str);
- s = RSTRING_PTR(str);
-
- dest = d = ALLOCV_N(char, vbuf, l + 1);
-
- for (i = 0; i < l; i++) {
- if (isspace((unsigned char)s[i]) || s[i] == '\0') {
- if (!sp)
- *d++ = ' ';
- sp = 1;
+ long i, ni;
+ int sp = 0;
+ for (i = ni = 0; i < l; ++i) {
+ if (!isspace((unsigned char)s[i])) {
+ if (sp) ni++;
+ sp = 0;
+ ni++;
}
else {
- if (isalpha((unsigned char)s[i]))
- *d++ = tolower((unsigned char)s[i]);
- else
- *d++ = s[i];
- sp = 0;
+ sp = 1;
}
}
- if (d > dest) {
- if (*(d - 1) == ' ')
- --d;
- *d = '\0';
+ return ni < l ? ni : 0;
+}
+
+static long
+shrink_space(char *d, const char *s, long l)
+{
+ long i, ni;
+ int sp = 0;
+ for (i = ni = 0; i < l; ++i) {
+ if (!isspace((unsigned char)s[i])) {
+ if (sp) d[ni++] = ' ';
+ sp = 0;
+ d[ni++] = s[i];
+ }
+ else {
+ sp = 1;
+ }
}
- l = d - dest;
- s = dest;
+ return ni;
+}
+
+VALUE
+date_zone_to_diff(VALUE str)
+{
+ VALUE offset = Qnil;
+ VALUE vbuf = 0;
+ long l = RSTRING_LEN(str);
+ const char *s = RSTRING_PTR(str);
+
{
- static const char STD[] = " standard time";
- static const char DST1[] = " daylight time";
- static const char DST2[] = " dst";
int dst = 0;
+ int w;
- if (str_end_with(d, l, STD)) {
- l -= sizeof(STD) - 1;
- }
- else if (str_end_with(d, l, DST1)) {
- l -= sizeof(DST1) - 1;
- dst = 1;
+ if ((w = str_end_with_word(s, l, "time")) > 0) {
+ int wtime = w;
+ l -= w;
+ if ((w = str_end_with_word(s, l, "standard")) > 0) {
+ l -= w;
+ }
+ else if ((w = str_end_with_word(s, l, "daylight")) > 0) {
+ l -= w;
+ dst = 1;
+ }
+ else {
+ l += wtime;
+ }
}
- else if (str_end_with(d, l, DST2)) {
- l -= sizeof(DST2) - 1;
+ else if ((w = str_end_with_word(s, l, "dst")) > 0) {
+ l -= w;
dst = 1;
}
{
+ long sl = shrunk_size(s, l);
+ if (sl > 0 && sl <= MAX_WORD_LENGTH) {
+ char *d = ALLOCV_N(char, vbuf, sl);
+ l = shrink_space(d, s, l);
+ s = d;
+ }
+ }
+ if (l > 0 && l <= MAX_WORD_LENGTH) {
const struct zone *z = zonetab(s, (unsigned int)l);
if (z) {
int d = z->offset;
@@ -418,8 +461,8 @@ date_zone_to_diff(VALUE str)
long hour = 0, min = 0, sec = 0;
if (l > 3 &&
- (strncmp(s, "gmt", 3) == 0 ||
- strncmp(s, "utc", 3) == 0)) {
+ (strncasecmp(s, "gmt", 3) == 0 ||
+ strncasecmp(s, "utc", 3) == 0)) {
s += 3;
l -= 3;
}
@@ -706,16 +749,14 @@ parse_era(VALUE str, VALUE hash)
static int
check_year_width(VALUE y)
{
- char *s;
- size_t l;
+ const char *s;
+ long l;
+ l = RSTRING_LEN(y);
+ if (l < 2) return 0;
s = RSTRING_PTR(y);
- l = strcspn(s, DECDIGIT);
- s += l;
- l = strspn(s, DECDIGIT);
- if (l != 2)
- return 0;
- return 1;
+ if (!isdigit((unsigned char)s[1])) return 0;
+ return (l == 2 || !isdigit((unsigned char)s[2]));
}
static int
@@ -1196,6 +1237,9 @@ parse_iso2(VALUE str, VALUE hash)
return 1;
}
+#define JISX0301_ERA_INITIALS "mtshr"
+#define JISX0301_DEFAULT_ERA 'H' /* obsolete */
+
static int
gengo(int c)
{
@@ -1206,6 +1250,7 @@ gengo(int c)
case 'T': case 't': e = 1911; break;
case 'S': case 's': e = 1925; break;
case 'H': case 'h': e = 1988; break;
+ case 'R': case 'r': e = 2018; break;
default: e = 0; break;
}
return e;
@@ -1236,11 +1281,11 @@ parse_jis(VALUE str, VALUE hash)
{
static const char pat_source[] =
#ifndef TIGHT_PARSER
- "\\b([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
+ "\\b([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
#else
BOS
FPW_COM FPT_COM
- "([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
+ "([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
TEE_FPT COM_FPW
EOS
#endif
@@ -1843,30 +1888,26 @@ parse_ddd_cb(VALUE m, VALUE hash)
set_hash("zone", s5);
if (*cs5 == '[') {
- VALUE vbuf = 0;
- char *buf = ALLOCV_N(char, vbuf, l5 + 1);
- char *s1, *s2, *s3;
+ const char *s1, *s2;
VALUE zone;
- memcpy(buf, cs5, l5);
- buf[l5 - 1] = '\0';
-
- s1 = buf + 1;
- s2 = strchr(buf, ':');
+ l5 -= 2;
+ s1 = cs5 + 1;
+ s2 = memchr(s1, ':', l5);
if (s2) {
- *s2 = '\0';
s2++;
+ zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1));
+ s5 = rb_str_subseq(s5, 1, s2 - s1);
}
- if (s2)
- s3 = s2;
- else
- s3 = s1;
- zone = rb_str_new2(s3);
+ else {
+ zone = rb_str_subseq(s5, 1, l5);
+ if (isdigit((unsigned char)*s1))
+ s5 = rb_str_append(rb_str_new_cstr("+"), zone);
+ else
+ s5 = zone;
+ }
set_hash("zone", zone);
- if (isdigit((unsigned char)*s1))
- *--s1 = '+';
- set_hash("offset", date_zone_to_diff(rb_str_new2(s1)));
- ALLOCV_END(vbuf);
+ set_hash("offset", date_zone_to_diff(s5));
}
RB_GC_GUARD(s5);
}
@@ -2159,7 +2200,7 @@ date__parse(VALUE str, VALUE comp)
#endif
{
- if (RTEST(ref_hash("_bc"))) {
+ if (RTEST(del_hash("_bc"))) {
VALUE y;
y = ref_hash("cwyear");
@@ -2174,7 +2215,7 @@ date__parse(VALUE str, VALUE comp)
}
}
- if (RTEST(ref_hash("_comp"))) {
+ if (RTEST(del_hash("_comp"))) {
VALUE y;
y = ref_hash("cwyear");
@@ -2197,9 +2238,6 @@ date__parse(VALUE str, VALUE comp)
}
- del_hash("_bc");
- del_hash("_comp");
-
{
VALUE zone = ref_hash("zone");
if (!NIL_P(zone) && NIL_P(ref_hash("offset")))
@@ -2249,8 +2287,8 @@ iso8601_ext_datetime_cb(VALUE m, VALUE hash)
s[i] = rb_reg_nth_match(i, m);
}
- if (!NIL_P(s[3])) {
- set_hash("mday", str2num(s[3]));
+ if (!NIL_P(s[1])) {
+ if (!NIL_P(s[3])) set_hash("mday", str2num(s[3]));
if (strcmp(RSTRING_PTR(s[1]), "-") != 0) {
y = str2num(s[1]);
if (RSTRING_LEN(s[1]) < 4)
@@ -2307,7 +2345,7 @@ static int
iso8601_ext_datetime(VALUE str, VALUE hash)
{
static const char pat_source[] =
- "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?-(\\d{2})|"
+ "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?(?:-(\\d{2}))?|"
"([-+]?\\d{2,})?-(\\d{3})|"
"(\\d{4}|\\d{2})?-w(\\d{2})-(\\d)|"
"-w-(\\d))"
@@ -2938,7 +2976,7 @@ jisx0301_cb(VALUE m, VALUE hash)
s[i] = rb_reg_nth_match(i, m);
}
- ep = gengo(NIL_P(s[1]) ? 'h' : *RSTRING_PTR(s[1]));
+ ep = gengo(NIL_P(s[1]) ? JISX0301_DEFAULT_ERA : *RSTRING_PTR(s[1]));
set_hash("year", f_add(str2num(s[2]), INT2FIX(ep)));
set_hash("mon", str2num(s[3]));
set_hash("mday", str2num(s[4]));
@@ -2963,7 +3001,7 @@ static int
jisx0301(VALUE str, VALUE hash)
{
static const char pat_source[] =
- "\\A\\s*([mtsh])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
+ "\\A\\s*([" JISX0301_ERA_INITIALS "])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
"(?:t"
"(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?"
"(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z";
diff --git a/ext/date/date_strptime.c b/ext/date/date_strptime.c
index 4f93219317..7b06a31471 100644
--- a/ext/date/date_strptime.c
+++ b/ext/date/date_strptime.c
@@ -79,14 +79,17 @@ read_digits(const char *s, VALUE *n, size_t width)
{
size_t l;
- l = strspn(s, "0123456789");
+ if (!width)
+ return 0;
+
+ l = 0;
+ while (ISDIGIT(s[l])) {
+ if (++l == width) break;
+ }
if (l == 0)
return 0;
- if (width < l)
- l = width;
-
if ((4 * l * sizeof(char)) <= (sizeof(long)*CHAR_BIT)) {
const char *os = s;
long v;
@@ -113,26 +116,26 @@ read_digits(const char *s, VALUE *n, size_t width)
}
}
-#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
-#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
-#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
+#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k"")), v)
+#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k"")))
+#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k"")))
#define fail() \
-{ \
+do { \
set_hash("_fail", Qtrue); \
return 0; \
-}
+} while (0)
#define fail_p() (!NIL_P(ref_hash("_fail")))
#define READ_DIGITS(n,w) \
-{ \
+do { \
size_t l; \
l = read_digits(&str[si], &n, w); \
if (l == 0) \
fail(); \
si += l; \
-}
+} while (0)
#define READ_DIGITS_MAX(n) READ_DIGITS(n, LONG_MAX)
@@ -147,14 +150,14 @@ valid_range_p(VALUE v, int a, int b)
}
#define recur(fmt) \
-{ \
+do { \
size_t l; \
l = date__strptime_internal(&str[si], slen - si, \
fmt, sizeof fmt - 1, hash); \
if (fail_p()) \
return 0; \
si += l; \
-}
+} while (0)
VALUE date_zone_to_diff(VALUE);
@@ -237,9 +240,9 @@ date__strptime_internal(const char *str, size_t slen,
VALUE n;
if (NUM_PATTERN_P())
- READ_DIGITS(n, 2)
+ READ_DIGITS(n, 2);
else
- READ_DIGITS_MAX(n)
+ READ_DIGITS_MAX(n);
set_hash("_cent", n);
goto matched;
}
@@ -278,9 +281,9 @@ date__strptime_internal(const char *str, size_t slen,
VALUE n;
if (NUM_PATTERN_P())
- READ_DIGITS(n, 4)
+ READ_DIGITS(n, 4);
else
- READ_DIGITS_MAX(n)
+ READ_DIGITS_MAX(n);
set_hash("cwyear", n);
goto matched;
}
@@ -358,9 +361,9 @@ date__strptime_internal(const char *str, size_t slen,
}
osi = si;
if (NUM_PATTERN_P())
- READ_DIGITS(n, c == 'L' ? 3 : 9)
+ READ_DIGITS(n, c == 'L' ? 3 : 9);
else
- READ_DIGITS_MAX(n)
+ READ_DIGITS_MAX(n);
if (sign == -1)
n = f_negate(n);
set_hash("sec_fraction",
@@ -426,9 +429,7 @@ date__strptime_internal(const char *str, size_t slen,
if (sign == -1)
n = f_negate(n);
set_hash("seconds",
- rb_rational_new2(n,
- f_expt(INT2FIX(10),
- INT2FIX(3))));
+ rb_rational_new2(n, INT2FIX(1000)));
goto matched;
}
@@ -529,24 +530,24 @@ date__strptime_internal(const char *str, size_t slen,
goto matched;
case 'Y':
- {
- VALUE n;
- int sign = 1;
-
- if (issign(str[si])) {
- if (str[si] == '-')
- sign = -1;
- si++;
- }
- if (NUM_PATTERN_P())
- READ_DIGITS(n, 4)
- else
- READ_DIGITS_MAX(n)
+ {
+ VALUE n;
+ int sign = 1;
+
+ if (issign(str[si])) {
+ if (str[si] == '-')
+ sign = -1;
+ si++;
+ }
+ if (NUM_PATTERN_P())
+ READ_DIGITS(n, 4);
+ else
+ READ_DIGITS_MAX(n);
if (sign == -1)
n = f_negate(n);
- set_hash("year", n);
- goto matched;
- }
+ set_hash("year", n);
+ goto matched;
+ }
case 'y':
{
@@ -580,6 +581,7 @@ date__strptime_internal(const char *str, size_t slen,
if (NIL_P(pat)) {
pat = rb_reg_new(pat_source, sizeof pat_source - 1,
ONIG_OPTION_IGNORECASE);
+ rb_obj_freeze(pat);
rb_gc_register_mark_object(pat);
}
@@ -668,7 +670,7 @@ date__strptime(const char *str, size_t slen,
if (fail_p())
return Qnil;
- cent = ref_hash("_cent");
+ cent = del_hash("_cent");
if (!NIL_P(cent)) {
VALUE year;
@@ -678,10 +680,9 @@ date__strptime(const char *str, size_t slen,
year = ref_hash("year");
if (!NIL_P(year))
set_hash("year", f_add(year, f_mul(cent, INT2FIX(100))));
- del_hash("_cent");
}
- merid = ref_hash("_merid");
+ merid = del_hash("_merid");
if (!NIL_P(merid)) {
VALUE hour;
@@ -690,7 +691,6 @@ date__strptime(const char *str, size_t slen,
hour = f_mod(hour, INT2FIX(12));
set_hash("hour", f_add(hour, merid));
}
- del_hash("_merid");
}
return hash;
diff --git a/ext/date/depend b/ext/date/depend
index 864fcc5302..c686530c70 100644
--- a/ext/date/depend
+++ b/ext/date/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
date_core.o: $(RUBY_EXTCONF_H)
date_core.o: $(arch_hdrdir)/ruby/config.h
+date_core.o: $(hdrdir)/ruby.h
+date_core.o: $(hdrdir)/ruby/internal/anyargs.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+date_core.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+date_core.o: $(hdrdir)/ruby/internal/assume.h
+date_core.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+date_core.o: $(hdrdir)/ruby/internal/attr/artificial.h
+date_core.o: $(hdrdir)/ruby/internal/attr/cold.h
+date_core.o: $(hdrdir)/ruby/internal/attr/const.h
+date_core.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+date_core.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+date_core.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+date_core.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+date_core.o: $(hdrdir)/ruby/internal/attr/error.h
+date_core.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+date_core.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+date_core.o: $(hdrdir)/ruby/internal/attr/format.h
+date_core.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+date_core.o: $(hdrdir)/ruby/internal/attr/noalias.h
+date_core.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+date_core.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+date_core.o: $(hdrdir)/ruby/internal/attr/noinline.h
+date_core.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+date_core.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+date_core.o: $(hdrdir)/ruby/internal/attr/pure.h
+date_core.o: $(hdrdir)/ruby/internal/attr/restrict.h
+date_core.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+date_core.o: $(hdrdir)/ruby/internal/attr/warning.h
+date_core.o: $(hdrdir)/ruby/internal/attr/weakref.h
+date_core.o: $(hdrdir)/ruby/internal/cast.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_is.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+date_core.o: $(hdrdir)/ruby/internal/compiler_since.h
+date_core.o: $(hdrdir)/ruby/internal/config.h
+date_core.o: $(hdrdir)/ruby/internal/constant_p.h
+date_core.o: $(hdrdir)/ruby/internal/core.h
+date_core.o: $(hdrdir)/ruby/internal/core/rarray.h
+date_core.o: $(hdrdir)/ruby/internal/core/rbasic.h
+date_core.o: $(hdrdir)/ruby/internal/core/rbignum.h
+date_core.o: $(hdrdir)/ruby/internal/core/rclass.h
+date_core.o: $(hdrdir)/ruby/internal/core/rdata.h
+date_core.o: $(hdrdir)/ruby/internal/core/rfile.h
+date_core.o: $(hdrdir)/ruby/internal/core/rhash.h
+date_core.o: $(hdrdir)/ruby/internal/core/robject.h
+date_core.o: $(hdrdir)/ruby/internal/core/rregexp.h
+date_core.o: $(hdrdir)/ruby/internal/core/rstring.h
+date_core.o: $(hdrdir)/ruby/internal/core/rstruct.h
+date_core.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+date_core.o: $(hdrdir)/ruby/internal/ctype.h
+date_core.o: $(hdrdir)/ruby/internal/dllexport.h
+date_core.o: $(hdrdir)/ruby/internal/dosish.h
+date_core.o: $(hdrdir)/ruby/internal/error.h
+date_core.o: $(hdrdir)/ruby/internal/eval.h
+date_core.o: $(hdrdir)/ruby/internal/event.h
+date_core.o: $(hdrdir)/ruby/internal/fl_type.h
+date_core.o: $(hdrdir)/ruby/internal/gc.h
+date_core.o: $(hdrdir)/ruby/internal/glob.h
+date_core.o: $(hdrdir)/ruby/internal/globals.h
+date_core.o: $(hdrdir)/ruby/internal/has/attribute.h
+date_core.o: $(hdrdir)/ruby/internal/has/builtin.h
+date_core.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+date_core.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+date_core.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+date_core.o: $(hdrdir)/ruby/internal/has/extension.h
+date_core.o: $(hdrdir)/ruby/internal/has/feature.h
+date_core.o: $(hdrdir)/ruby/internal/has/warning.h
+date_core.o: $(hdrdir)/ruby/internal/intern/array.h
+date_core.o: $(hdrdir)/ruby/internal/intern/bignum.h
+date_core.o: $(hdrdir)/ruby/internal/intern/class.h
+date_core.o: $(hdrdir)/ruby/internal/intern/compar.h
+date_core.o: $(hdrdir)/ruby/internal/intern/complex.h
+date_core.o: $(hdrdir)/ruby/internal/intern/cont.h
+date_core.o: $(hdrdir)/ruby/internal/intern/dir.h
+date_core.o: $(hdrdir)/ruby/internal/intern/enum.h
+date_core.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+date_core.o: $(hdrdir)/ruby/internal/intern/error.h
+date_core.o: $(hdrdir)/ruby/internal/intern/eval.h
+date_core.o: $(hdrdir)/ruby/internal/intern/file.h
+date_core.o: $(hdrdir)/ruby/internal/intern/gc.h
+date_core.o: $(hdrdir)/ruby/internal/intern/hash.h
+date_core.o: $(hdrdir)/ruby/internal/intern/io.h
+date_core.o: $(hdrdir)/ruby/internal/intern/load.h
+date_core.o: $(hdrdir)/ruby/internal/intern/marshal.h
+date_core.o: $(hdrdir)/ruby/internal/intern/numeric.h
+date_core.o: $(hdrdir)/ruby/internal/intern/object.h
+date_core.o: $(hdrdir)/ruby/internal/intern/parse.h
+date_core.o: $(hdrdir)/ruby/internal/intern/proc.h
+date_core.o: $(hdrdir)/ruby/internal/intern/process.h
+date_core.o: $(hdrdir)/ruby/internal/intern/random.h
+date_core.o: $(hdrdir)/ruby/internal/intern/range.h
+date_core.o: $(hdrdir)/ruby/internal/intern/rational.h
+date_core.o: $(hdrdir)/ruby/internal/intern/re.h
+date_core.o: $(hdrdir)/ruby/internal/intern/ruby.h
+date_core.o: $(hdrdir)/ruby/internal/intern/select.h
+date_core.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+date_core.o: $(hdrdir)/ruby/internal/intern/signal.h
+date_core.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+date_core.o: $(hdrdir)/ruby/internal/intern/string.h
+date_core.o: $(hdrdir)/ruby/internal/intern/struct.h
+date_core.o: $(hdrdir)/ruby/internal/intern/thread.h
+date_core.o: $(hdrdir)/ruby/internal/intern/time.h
+date_core.o: $(hdrdir)/ruby/internal/intern/variable.h
+date_core.o: $(hdrdir)/ruby/internal/intern/vm.h
+date_core.o: $(hdrdir)/ruby/internal/interpreter.h
+date_core.o: $(hdrdir)/ruby/internal/iterator.h
+date_core.o: $(hdrdir)/ruby/internal/memory.h
+date_core.o: $(hdrdir)/ruby/internal/method.h
+date_core.o: $(hdrdir)/ruby/internal/module.h
+date_core.o: $(hdrdir)/ruby/internal/newobj.h
+date_core.o: $(hdrdir)/ruby/internal/rgengc.h
+date_core.o: $(hdrdir)/ruby/internal/scan_args.h
+date_core.o: $(hdrdir)/ruby/internal/special_consts.h
+date_core.o: $(hdrdir)/ruby/internal/static_assert.h
+date_core.o: $(hdrdir)/ruby/internal/stdalign.h
+date_core.o: $(hdrdir)/ruby/internal/stdbool.h
+date_core.o: $(hdrdir)/ruby/internal/symbol.h
+date_core.o: $(hdrdir)/ruby/internal/token_paste.h
+date_core.o: $(hdrdir)/ruby/internal/value.h
+date_core.o: $(hdrdir)/ruby/internal/value_type.h
+date_core.o: $(hdrdir)/ruby/internal/variable.h
+date_core.o: $(hdrdir)/ruby/internal/warning_push.h
+date_core.o: $(hdrdir)/ruby/internal/xmalloc.h
+date_core.o: $(hdrdir)/ruby/assert.h
date_core.o: $(hdrdir)/ruby/backward.h
+date_core.o: $(hdrdir)/ruby/backward/2/assume.h
+date_core.o: $(hdrdir)/ruby/backward/2/attributes.h
+date_core.o: $(hdrdir)/ruby/backward/2/bool.h
+date_core.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+date_core.o: $(hdrdir)/ruby/backward/2/inttypes.h
+date_core.o: $(hdrdir)/ruby/backward/2/limits.h
+date_core.o: $(hdrdir)/ruby/backward/2/long_long.h
+date_core.o: $(hdrdir)/ruby/backward/2/stdalign.h
+date_core.o: $(hdrdir)/ruby/backward/2/stdarg.h
date_core.o: $(hdrdir)/ruby/defines.h
date_core.o: $(hdrdir)/ruby/encoding.h
date_core.o: $(hdrdir)/ruby/intern.h
@@ -12,12 +163,163 @@ date_core.o: $(hdrdir)/ruby/ruby.h
date_core.o: $(hdrdir)/ruby/st.h
date_core.o: $(hdrdir)/ruby/subst.h
date_core.o: $(hdrdir)/ruby/util.h
-date_core.o: $(top_srcdir)/include/ruby.h
date_core.o: date_core.c
date_core.o: date_tmx.h
date_parse.o: $(RUBY_EXTCONF_H)
date_parse.o: $(arch_hdrdir)/ruby/config.h
+date_parse.o: $(hdrdir)/ruby.h
+date_parse.o: $(hdrdir)/ruby/internal/anyargs.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+date_parse.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+date_parse.o: $(hdrdir)/ruby/internal/assume.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/artificial.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/cold.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/const.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/error.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/format.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/noalias.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/noinline.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/pure.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/restrict.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/warning.h
+date_parse.o: $(hdrdir)/ruby/internal/attr/weakref.h
+date_parse.o: $(hdrdir)/ruby/internal/cast.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_is.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+date_parse.o: $(hdrdir)/ruby/internal/compiler_since.h
+date_parse.o: $(hdrdir)/ruby/internal/config.h
+date_parse.o: $(hdrdir)/ruby/internal/constant_p.h
+date_parse.o: $(hdrdir)/ruby/internal/core.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rarray.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rbasic.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rbignum.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rclass.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rdata.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rfile.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rhash.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rmatch.h
+date_parse.o: $(hdrdir)/ruby/internal/core/robject.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rregexp.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rstring.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rstruct.h
+date_parse.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+date_parse.o: $(hdrdir)/ruby/internal/ctype.h
+date_parse.o: $(hdrdir)/ruby/internal/dllexport.h
+date_parse.o: $(hdrdir)/ruby/internal/dosish.h
+date_parse.o: $(hdrdir)/ruby/internal/error.h
+date_parse.o: $(hdrdir)/ruby/internal/eval.h
+date_parse.o: $(hdrdir)/ruby/internal/event.h
+date_parse.o: $(hdrdir)/ruby/internal/fl_type.h
+date_parse.o: $(hdrdir)/ruby/internal/gc.h
+date_parse.o: $(hdrdir)/ruby/internal/glob.h
+date_parse.o: $(hdrdir)/ruby/internal/globals.h
+date_parse.o: $(hdrdir)/ruby/internal/has/attribute.h
+date_parse.o: $(hdrdir)/ruby/internal/has/builtin.h
+date_parse.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+date_parse.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+date_parse.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+date_parse.o: $(hdrdir)/ruby/internal/has/extension.h
+date_parse.o: $(hdrdir)/ruby/internal/has/feature.h
+date_parse.o: $(hdrdir)/ruby/internal/has/warning.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/array.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/bignum.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/class.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/compar.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/complex.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/cont.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/dir.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/enum.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/error.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/eval.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/file.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/gc.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/hash.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/io.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/load.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/marshal.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/numeric.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/object.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/parse.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/proc.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/process.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/random.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/range.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/rational.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/re.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/ruby.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/select.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/signal.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/string.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/struct.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/thread.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/time.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/variable.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/vm.h
+date_parse.o: $(hdrdir)/ruby/internal/interpreter.h
+date_parse.o: $(hdrdir)/ruby/internal/iterator.h
+date_parse.o: $(hdrdir)/ruby/internal/memory.h
+date_parse.o: $(hdrdir)/ruby/internal/method.h
+date_parse.o: $(hdrdir)/ruby/internal/module.h
+date_parse.o: $(hdrdir)/ruby/internal/newobj.h
+date_parse.o: $(hdrdir)/ruby/internal/rgengc.h
+date_parse.o: $(hdrdir)/ruby/internal/scan_args.h
+date_parse.o: $(hdrdir)/ruby/internal/special_consts.h
+date_parse.o: $(hdrdir)/ruby/internal/static_assert.h
+date_parse.o: $(hdrdir)/ruby/internal/stdalign.h
+date_parse.o: $(hdrdir)/ruby/internal/stdbool.h
+date_parse.o: $(hdrdir)/ruby/internal/symbol.h
+date_parse.o: $(hdrdir)/ruby/internal/token_paste.h
+date_parse.o: $(hdrdir)/ruby/internal/value.h
+date_parse.o: $(hdrdir)/ruby/internal/value_type.h
+date_parse.o: $(hdrdir)/ruby/internal/variable.h
+date_parse.o: $(hdrdir)/ruby/internal/warning_push.h
+date_parse.o: $(hdrdir)/ruby/internal/xmalloc.h
+date_parse.o: $(hdrdir)/ruby/assert.h
date_parse.o: $(hdrdir)/ruby/backward.h
+date_parse.o: $(hdrdir)/ruby/backward/2/assume.h
+date_parse.o: $(hdrdir)/ruby/backward/2/attributes.h
+date_parse.o: $(hdrdir)/ruby/backward/2/bool.h
+date_parse.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+date_parse.o: $(hdrdir)/ruby/backward/2/inttypes.h
+date_parse.o: $(hdrdir)/ruby/backward/2/limits.h
+date_parse.o: $(hdrdir)/ruby/backward/2/long_long.h
+date_parse.o: $(hdrdir)/ruby/backward/2/stdalign.h
+date_parse.o: $(hdrdir)/ruby/backward/2/stdarg.h
date_parse.o: $(hdrdir)/ruby/defines.h
date_parse.o: $(hdrdir)/ruby/encoding.h
date_parse.o: $(hdrdir)/ruby/intern.h
@@ -29,13 +331,162 @@ date_parse.o: $(hdrdir)/ruby/regex.h
date_parse.o: $(hdrdir)/ruby/ruby.h
date_parse.o: $(hdrdir)/ruby/st.h
date_parse.o: $(hdrdir)/ruby/subst.h
-date_parse.o: $(top_srcdir)/include/ruby.h
date_parse.o: date_parse.c
date_parse.o: zonetab.h
date_parse.o: zonetab.list
date_strftime.o: $(RUBY_EXTCONF_H)
date_strftime.o: $(arch_hdrdir)/ruby/config.h
+date_strftime.o: $(hdrdir)/ruby/internal/anyargs.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+date_strftime.o: $(hdrdir)/ruby/internal/assume.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/artificial.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/cold.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/const.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/error.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/format.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/noalias.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/noinline.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/pure.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/restrict.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/warning.h
+date_strftime.o: $(hdrdir)/ruby/internal/attr/weakref.h
+date_strftime.o: $(hdrdir)/ruby/internal/cast.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_is.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+date_strftime.o: $(hdrdir)/ruby/internal/compiler_since.h
+date_strftime.o: $(hdrdir)/ruby/internal/config.h
+date_strftime.o: $(hdrdir)/ruby/internal/constant_p.h
+date_strftime.o: $(hdrdir)/ruby/internal/core.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rarray.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rbasic.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rbignum.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rclass.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rdata.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rfile.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rhash.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/robject.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rregexp.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rstring.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rstruct.h
+date_strftime.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+date_strftime.o: $(hdrdir)/ruby/internal/ctype.h
+date_strftime.o: $(hdrdir)/ruby/internal/dllexport.h
+date_strftime.o: $(hdrdir)/ruby/internal/dosish.h
+date_strftime.o: $(hdrdir)/ruby/internal/error.h
+date_strftime.o: $(hdrdir)/ruby/internal/eval.h
+date_strftime.o: $(hdrdir)/ruby/internal/event.h
+date_strftime.o: $(hdrdir)/ruby/internal/fl_type.h
+date_strftime.o: $(hdrdir)/ruby/internal/gc.h
+date_strftime.o: $(hdrdir)/ruby/internal/glob.h
+date_strftime.o: $(hdrdir)/ruby/internal/globals.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/attribute.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/builtin.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/extension.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/feature.h
+date_strftime.o: $(hdrdir)/ruby/internal/has/warning.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/array.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/bignum.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/class.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/compar.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/complex.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/cont.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/dir.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/enum.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/error.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/eval.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/file.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/gc.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/hash.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/io.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/load.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/marshal.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/numeric.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/object.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/parse.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/proc.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/process.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/random.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/range.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/rational.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/re.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/ruby.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/select.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/signal.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/string.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/struct.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/thread.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/time.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/variable.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/vm.h
+date_strftime.o: $(hdrdir)/ruby/internal/interpreter.h
+date_strftime.o: $(hdrdir)/ruby/internal/iterator.h
+date_strftime.o: $(hdrdir)/ruby/internal/memory.h
+date_strftime.o: $(hdrdir)/ruby/internal/method.h
+date_strftime.o: $(hdrdir)/ruby/internal/module.h
+date_strftime.o: $(hdrdir)/ruby/internal/newobj.h
+date_strftime.o: $(hdrdir)/ruby/internal/rgengc.h
+date_strftime.o: $(hdrdir)/ruby/internal/scan_args.h
+date_strftime.o: $(hdrdir)/ruby/internal/special_consts.h
+date_strftime.o: $(hdrdir)/ruby/internal/static_assert.h
+date_strftime.o: $(hdrdir)/ruby/internal/stdalign.h
+date_strftime.o: $(hdrdir)/ruby/internal/stdbool.h
+date_strftime.o: $(hdrdir)/ruby/internal/symbol.h
+date_strftime.o: $(hdrdir)/ruby/internal/token_paste.h
+date_strftime.o: $(hdrdir)/ruby/internal/value.h
+date_strftime.o: $(hdrdir)/ruby/internal/value_type.h
+date_strftime.o: $(hdrdir)/ruby/internal/variable.h
+date_strftime.o: $(hdrdir)/ruby/internal/warning_push.h
+date_strftime.o: $(hdrdir)/ruby/internal/xmalloc.h
+date_strftime.o: $(hdrdir)/ruby/assert.h
date_strftime.o: $(hdrdir)/ruby/backward.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/assume.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/attributes.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/bool.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/inttypes.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/limits.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/long_long.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/stdalign.h
+date_strftime.o: $(hdrdir)/ruby/backward/2/stdarg.h
date_strftime.o: $(hdrdir)/ruby/defines.h
date_strftime.o: $(hdrdir)/ruby/intern.h
date_strftime.o: $(hdrdir)/ruby/missing.h
@@ -46,7 +497,159 @@ date_strftime.o: date_strftime.c
date_strftime.o: date_tmx.h
date_strptime.o: $(RUBY_EXTCONF_H)
date_strptime.o: $(arch_hdrdir)/ruby/config.h
+date_strptime.o: $(hdrdir)/ruby.h
+date_strptime.o: $(hdrdir)/ruby/internal/anyargs.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+date_strptime.o: $(hdrdir)/ruby/internal/assume.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/artificial.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/cold.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/const.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/error.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/format.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/noalias.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/noinline.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/pure.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/restrict.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/warning.h
+date_strptime.o: $(hdrdir)/ruby/internal/attr/weakref.h
+date_strptime.o: $(hdrdir)/ruby/internal/cast.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_is.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+date_strptime.o: $(hdrdir)/ruby/internal/compiler_since.h
+date_strptime.o: $(hdrdir)/ruby/internal/config.h
+date_strptime.o: $(hdrdir)/ruby/internal/constant_p.h
+date_strptime.o: $(hdrdir)/ruby/internal/core.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rarray.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rbasic.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rbignum.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rclass.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rdata.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rfile.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rhash.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rmatch.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/robject.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rregexp.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rstring.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rstruct.h
+date_strptime.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+date_strptime.o: $(hdrdir)/ruby/internal/ctype.h
+date_strptime.o: $(hdrdir)/ruby/internal/dllexport.h
+date_strptime.o: $(hdrdir)/ruby/internal/dosish.h
+date_strptime.o: $(hdrdir)/ruby/internal/error.h
+date_strptime.o: $(hdrdir)/ruby/internal/eval.h
+date_strptime.o: $(hdrdir)/ruby/internal/event.h
+date_strptime.o: $(hdrdir)/ruby/internal/fl_type.h
+date_strptime.o: $(hdrdir)/ruby/internal/gc.h
+date_strptime.o: $(hdrdir)/ruby/internal/glob.h
+date_strptime.o: $(hdrdir)/ruby/internal/globals.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/attribute.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/builtin.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/extension.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/feature.h
+date_strptime.o: $(hdrdir)/ruby/internal/has/warning.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/array.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/bignum.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/class.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/compar.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/complex.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/cont.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/dir.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/enum.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/error.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/eval.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/file.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/gc.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/hash.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/io.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/load.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/marshal.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/numeric.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/object.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/parse.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/proc.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/process.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/random.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/range.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/rational.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/re.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/ruby.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/select.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/signal.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/string.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/struct.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/thread.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/time.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/variable.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/vm.h
+date_strptime.o: $(hdrdir)/ruby/internal/interpreter.h
+date_strptime.o: $(hdrdir)/ruby/internal/iterator.h
+date_strptime.o: $(hdrdir)/ruby/internal/memory.h
+date_strptime.o: $(hdrdir)/ruby/internal/method.h
+date_strptime.o: $(hdrdir)/ruby/internal/module.h
+date_strptime.o: $(hdrdir)/ruby/internal/newobj.h
+date_strptime.o: $(hdrdir)/ruby/internal/rgengc.h
+date_strptime.o: $(hdrdir)/ruby/internal/scan_args.h
+date_strptime.o: $(hdrdir)/ruby/internal/special_consts.h
+date_strptime.o: $(hdrdir)/ruby/internal/static_assert.h
+date_strptime.o: $(hdrdir)/ruby/internal/stdalign.h
+date_strptime.o: $(hdrdir)/ruby/internal/stdbool.h
+date_strptime.o: $(hdrdir)/ruby/internal/symbol.h
+date_strptime.o: $(hdrdir)/ruby/internal/token_paste.h
+date_strptime.o: $(hdrdir)/ruby/internal/value.h
+date_strptime.o: $(hdrdir)/ruby/internal/value_type.h
+date_strptime.o: $(hdrdir)/ruby/internal/variable.h
+date_strptime.o: $(hdrdir)/ruby/internal/warning_push.h
+date_strptime.o: $(hdrdir)/ruby/internal/xmalloc.h
+date_strptime.o: $(hdrdir)/ruby/assert.h
date_strptime.o: $(hdrdir)/ruby/backward.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/assume.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/attributes.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/bool.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/inttypes.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/limits.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/long_long.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/stdalign.h
+date_strptime.o: $(hdrdir)/ruby/backward/2/stdarg.h
date_strptime.o: $(hdrdir)/ruby/defines.h
date_strptime.o: $(hdrdir)/ruby/encoding.h
date_strptime.o: $(hdrdir)/ruby/intern.h
@@ -58,6 +661,5 @@ date_strptime.o: $(hdrdir)/ruby/regex.h
date_strptime.o: $(hdrdir)/ruby/ruby.h
date_strptime.o: $(hdrdir)/ruby/st.h
date_strptime.o: $(hdrdir)/ruby/subst.h
-date_strptime.o: $(top_srcdir)/include/ruby.h
date_strptime.o: date_strptime.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/date/lib/date.rb b/ext/date/lib/date.rb
index 9170a99ae9..0a49076ab6 100644
--- a/ext/date/lib/date.rb
+++ b/ext/date/lib/date.rb
@@ -4,10 +4,13 @@
require 'date_core'
class Date
+ VERSION = '3.1.3' # :nodoc:
- class Infinity < Numeric # :nodoc:
+ def infinite?
+ false
+ end
- include Comparable
+ class Infinity < Numeric # :nodoc:
def initialize(d=1) @d = d <=> 0 end
diff --git a/ext/date/prereq.mk b/ext/date/prereq.mk
index a0a5a2bff3..eb71e55e71 100644
--- a/ext/date/prereq.mk
+++ b/ext/date/prereq.mk
@@ -1,8 +1,12 @@
.SUFFIXES: .list
.list.h:
- gperf -E -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \
- | sed 's/(int)(long)&((\(struct stringpool_t\) *\*)0)->\(stringpool_[a-z0-9]*\)/offsetof(\1, \2)/g' \
+ gperf --ignore-case -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \
+ | sed -f $(top_srcdir)/tool/gperf.sed \
> $(@F)
zonetab.h: zonetab.list
+
+.PHONY: update-zonetab
+update-zonetab:
+ $(RUBY) -C $(srcdir) update-abbr
diff --git a/ext/date/update-abbr b/ext/date/update-abbr
new file mode 100644
index 0000000000..7fe9734e6d
--- /dev/null
+++ b/ext/date/update-abbr
@@ -0,0 +1,52 @@
+# -*- mode: ruby -*-
+require 'nokogiri'
+require 'open-uri'
+
+doc = Nokogiri::HTML(URI.open(ARGV[0] || 'https://www.timeanddate.com/time/zones/'))
+
+h = {}
+
+doc.css('#tz-abb tbody tr').each do |tr|
+ tds = tr.css('td')
+ abbr = tds[0].text.strip.downcase
+ offset = tds[3].text.strip.gsub(/UTC\s*/, '')
+ next if offset.include?('/') # skip ambiguous timezones
+ next if offset.empty?
+
+
+ hour, min = offset.split(':', 2)
+ offset = (Integer(hour) * 60 + (Integer(min || 0)))*60
+ if h.has_key?(abbr)
+ h[abbr] = false
+ else
+ h[abbr] = offset
+ end
+end
+
+h.delete_if{|_,v| !v}
+
+lines = File.readlines('zonetab.list')
+lines.map! do |l|
+ if (sep = /^%%/ =~ l)...(sep = /^%%/ =~ l) and !sep
+ z, o = l.split(/,\s*/, 2)
+ o.strip!
+ if ho = h.delete(z) and ho != eval(o)
+ warn "offset of #{z}: #{o} -> #{ho}"
+ l = l.sub(/,\s*\K.*/) {
+ if o.include?("*")
+ o1, o2 = ho.abs.divmod(3600)
+ o1 = "#{o1}*3600"
+ o1 = "(#{o1}+#{o2})" if o2 != 0
+ ho < 0 ? "-#{o1}" : o1
+ else
+ ho.to_s
+ end
+ }
+ end
+ end
+ l
+end
+
+lines.insert(-2, h.sort.map{|k,v| "#{k},#{v}\n"})
+lines.flatten!
+File.write('zonetab.list', lines.join)
diff --git a/ext/date/zonetab.h b/ext/date/zonetab.h
index fa86e7991a..379f78e1b8 100644
--- a/ext/date/zonetab.h
+++ b/ext/date/zonetab.h
@@ -1,6 +1,6 @@
-/* C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -E -C -c -P -p -j1 -i 1 -g -o -t -N zonetab zonetab.list */
-/* Computed positions: -k'1-4,$' */
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf --ignore-case -C -c -P -p -j1 -i 1 -g -o -t -N zonetab zonetab.list */
+/* Computed positions: -k'1-4,9' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -26,9 +26,10 @@
&& ('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
+#define gperf_offsetof(s, n) (short)offsetof(struct s##_t, s##_str##n)
#line 1 "zonetab.list"
struct zone {
@@ -38,865 +39,1524 @@ struct zone {
static const struct zone *zonetab();
#line 9 "zonetab.list"
struct zone;
-/* maximum key range = 434, duplicates = 0 */
-#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || defined(__GNUC_STDC_INLINE__)
-inline
-#elif defined(__GNUC__)
+#define TOTAL_KEYWORDS 316
+#define MIN_WORD_LENGTH 1
+#define MAX_WORD_LENGTH 17
+#define MIN_HASH_VALUE 2
+#define MAX_HASH_VALUE 619
+/* maximum key range = 618, duplicates = 0 */
+
+#ifndef GPERF_DOWNCASE
+#define GPERF_DOWNCASE 1
+static unsigned char gperf_downcase[256] =
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
+ 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
+ 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+ 255
+ };
+#endif
+
+#ifndef GPERF_CASE_STRNCMP
+#define GPERF_CASE_STRNCMP 1
+static int
+gperf_case_strncmp (register const char *s1, register const char *s2, register size_t n)
+{
+ for (; n > 0;)
+ {
+ unsigned char c1 = gperf_downcase[(unsigned char)*s1++];
+ unsigned char c2 = gperf_downcase[(unsigned char)*s2++];
+ if (c1 != 0 && c1 == c2)
+ {
+ n--;
+ continue;
+ }
+ return (int)c1 - (int)c2;
+ }
+ return 0;
+}
+#endif
+
+#ifdef __GNUC__
__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
#endif
static unsigned int
-hash (str, len)
- register const char *str;
- register unsigned int len;
+hash (register const char *str, register size_t len)
{
static const unsigned short asso_values[] =
{
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 19, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 2, 4, 439, 439, 439,
- 439, 439, 8, 6, 3, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 7, 63, 53,
- 2, 4, 32, 110, 88, 78, 90, 68, 47, 108,
- 10, 73, 81, 124, 3, 1, 4, 77, 116, 88,
- 15, 96, 45, 5, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 17, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 3, 2, 620, 620, 620,
+ 620, 620, 70, 8, 3, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 39, 176, 207, 70, 168,
+ 1, 5, 18, 74, 218, 2, 117, 130, 48, 88,
+ 125, 225, 92, 1, 1, 12, 54, 30, 36, 13,
+ 48, 168, 263, 59, 114, 166, 109, 39, 176, 207,
+ 70, 168, 1, 5, 18, 74, 218, 2, 117, 130,
+ 48, 88, 125, 225, 92, 1, 1, 12, 54, 30,
+ 36, 13, 48, 168, 263, 59, 114, 166, 109, 27,
+ 104, 1, 9, 4, 309, 190, 188, 177, 255, 108,
+ 2, 341, 3, 620, 620, 620, 620, 620, 620, 12,
+ 54, 30, 36, 13, 48, 168, 263, 59, 114, 166,
+ 109, 27, 104, 1, 9, 4, 309, 190, 188, 177,
+ 255, 108, 2, 341, 3, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 620
};
- register int hval = len;
+ register unsigned int hval = (unsigned int)len;
switch (hval)
{
default:
+ hval += asso_values[(unsigned char)str[8]];
+ /*FALLTHROUGH*/
+ case 8:
+ case 7:
+ case 6:
+ case 5:
+ case 4:
hval += asso_values[(unsigned char)str[3]];
/*FALLTHROUGH*/
case 3:
hval += asso_values[(unsigned char)str[2]];
/*FALLTHROUGH*/
case 2:
- hval += asso_values[(unsigned char)str[1]];
+ hval += asso_values[(unsigned char)str[1]+6];
/*FALLTHROUGH*/
case 1:
- hval += asso_values[(unsigned char)str[0]+1];
+ hval += asso_values[(unsigned char)str[0]+52];
break;
}
- return hval + asso_values[(unsigned char)str[len - 1]];
+ return (unsigned int)hval;
}
struct stringpool_t
{
- char stringpool_str5[sizeof("r")];
- char stringpool_str6[sizeof("s")];
- char stringpool_str7[sizeof("d")];
- char stringpool_str14[sizeof("cst")];
- char stringpool_str15[sizeof("cdt")];
- char stringpool_str16[sizeof("sst")];
- char stringpool_str17[sizeof("cet")];
- char stringpool_str18[sizeof("msd")];
- char stringpool_str19[sizeof("cest")];
- char stringpool_str20[sizeof("cat")];
- char stringpool_str22[sizeof("mst")];
- char stringpool_str23[sizeof("mdt")];
- char stringpool_str24[sizeof("sast")];
- char stringpool_str25[sizeof("met")];
- char stringpool_str27[sizeof("mest")];
- char stringpool_str30[sizeof("wet")];
- char stringpool_str31[sizeof("dateline")];
- char stringpool_str32[sizeof("west")];
- char stringpool_str33[sizeof("wat")];
- char stringpool_str35[sizeof("wast")];
- char stringpool_str36[sizeof("wadt")];
- char stringpool_str37[sizeof("e")];
- char stringpool_str38[sizeof("central europe")];
- char stringpool_str39[sizeof("central asia")];
- char stringpool_str40[sizeof("west asia")];
- char stringpool_str41[sizeof("cen. australia")];
- char stringpool_str42[sizeof("central america")];
- char stringpool_str44[sizeof("est")];
- char stringpool_str45[sizeof("edt")];
- char stringpool_str46[sizeof("central european")];
- char stringpool_str47[sizeof("eet")];
- char stringpool_str48[sizeof("se asia")];
- char stringpool_str49[sizeof("eest")];
- char stringpool_str50[sizeof("eat")];
- char stringpool_str51[sizeof("z")];
- char stringpool_str52[sizeof("east")];
- char stringpool_str53[sizeof("eadt")];
- char stringpool_str54[sizeof("sa eastern")];
- char stringpool_str55[sizeof("w. europe")];
- char stringpool_str56[sizeof("c")];
- char stringpool_str57[sizeof("yst")];
- char stringpool_str58[sizeof("ydt")];
- char stringpool_str59[sizeof("kst")];
- char stringpool_str60[sizeof("clt")];
- char stringpool_str61[sizeof("eastern")];
- char stringpool_str62[sizeof("clst")];
- char stringpool_str63[sizeof("bt")];
- char stringpool_str64[sizeof("w. australia")];
- char stringpool_str65[sizeof("bst")];
- char stringpool_str66[sizeof("cct")];
- char stringpool_str67[sizeof("brt")];
- char stringpool_str69[sizeof("brst")];
- char stringpool_str71[sizeof("a")];
- char stringpool_str72[sizeof("e. europe")];
- char stringpool_str73[sizeof("at")];
- char stringpool_str74[sizeof("central")];
- char stringpool_str75[sizeof("ast")];
- char stringpool_str76[sizeof("adt")];
- char stringpool_str77[sizeof("art")];
- char stringpool_str78[sizeof("e. africa")];
- char stringpool_str79[sizeof("e. south america")];
- char stringpool_str80[sizeof("jst")];
- char stringpool_str81[sizeof("e. australia")];
- char stringpool_str82[sizeof("t")];
- char stringpool_str83[sizeof("nt")];
- char stringpool_str84[sizeof("n")];
- char stringpool_str85[sizeof("nst")];
- char stringpool_str86[sizeof("ndt")];
- char stringpool_str87[sizeof("canada central")];
- char stringpool_str88[sizeof("central pacific")];
- char stringpool_str89[sizeof("west pacific")];
- char stringpool_str90[sizeof("hst")];
- char stringpool_str91[sizeof("hdt")];
- char stringpool_str93[sizeof("malay peninsula")];
- char stringpool_str95[sizeof("zp6")];
- char stringpool_str97[sizeof("russian")];
- char stringpool_str98[sizeof("hast")];
- char stringpool_str99[sizeof("hadt")];
- char stringpool_str100[sizeof("gst")];
- char stringpool_str101[sizeof("zp5")];
- char stringpool_str102[sizeof("ist")];
- char stringpool_str103[sizeof("swt")];
- char stringpool_str104[sizeof("w")];
- char stringpool_str105[sizeof("zp4")];
- char stringpool_str107[sizeof("mez")];
- char stringpool_str108[sizeof("cape verde")];
- char stringpool_str109[sizeof("mesz")];
- char stringpool_str110[sizeof("greenland")];
- char stringpool_str112[sizeof("x")];
- char stringpool_str114[sizeof("mewt")];
- char stringpool_str115[sizeof("w. central africa")];
- char stringpool_str116[sizeof("k")];
- char stringpool_str117[sizeof("b")];
- char stringpool_str119[sizeof("m")];
- char stringpool_str120[sizeof("sri lanka")];
- char stringpool_str122[sizeof("fst")];
- char stringpool_str124[sizeof("iran")];
- char stringpool_str125[sizeof("sgt")];
- char stringpool_str126[sizeof("ut")];
- char stringpool_str128[sizeof("q")];
- char stringpool_str129[sizeof("nzt")];
- char stringpool_str131[sizeof("nzst")];
- char stringpool_str132[sizeof("nzdt")];
- char stringpool_str133[sizeof("myanmar")];
- char stringpool_str135[sizeof("alaskan")];
- char stringpool_str136[sizeof("pst")];
- char stringpool_str137[sizeof("pdt")];
- char stringpool_str138[sizeof("sa western")];
- char stringpool_str139[sizeof("korea")];
- char stringpool_str142[sizeof("y")];
- char stringpool_str143[sizeof("f")];
- char stringpool_str144[sizeof("akst")];
- char stringpool_str145[sizeof("akdt")];
- char stringpool_str148[sizeof("caucasus")];
- char stringpool_str150[sizeof("msk")];
- char stringpool_str151[sizeof("idle")];
- char stringpool_str153[sizeof("arabian")];
- char stringpool_str155[sizeof("o")];
- char stringpool_str156[sizeof("l")];
- char stringpool_str157[sizeof("mid-atlantic")];
- char stringpool_str160[sizeof("us eastern")];
- char stringpool_str164[sizeof("ahst")];
- char stringpool_str167[sizeof("h")];
- char stringpool_str168[sizeof("fle")];
- char stringpool_str169[sizeof("i")];
- char stringpool_str170[sizeof("north asia")];
- char stringpool_str171[sizeof("n. central asia")];
- char stringpool_str172[sizeof("north asia east")];
- char stringpool_str174[sizeof("sa pacific")];
- char stringpool_str177[sizeof("south africa")];
- char stringpool_str181[sizeof("aus eastern")];
- char stringpool_str182[sizeof("atlantic")];
- char stringpool_str186[sizeof("mexico")];
- char stringpool_str188[sizeof("mountain")];
- char stringpool_str190[sizeof("china")];
- char stringpool_str191[sizeof("azores")];
- char stringpool_str192[sizeof("india")];
- char stringpool_str194[sizeof("u")];
- char stringpool_str195[sizeof("arabic")];
- char stringpool_str196[sizeof("greenwich")];
- char stringpool_str197[sizeof("new zealand")];
- char stringpool_str198[sizeof("hawaiian")];
- char stringpool_str199[sizeof("g")];
- char stringpool_str200[sizeof("romance")];
- char stringpool_str203[sizeof("arab")];
- char stringpool_str204[sizeof("samoa")];
- char stringpool_str205[sizeof("v")];
- char stringpool_str206[sizeof("p")];
- char stringpool_str207[sizeof("gmt")];
- char stringpool_str208[sizeof("tasmania")];
- char stringpool_str209[sizeof("fwt")];
- char stringpool_str211[sizeof("newfoundland")];
- char stringpool_str217[sizeof("nepal")];
- char stringpool_str218[sizeof("aus central")];
- char stringpool_str221[sizeof("gtb")];
- char stringpool_str223[sizeof("vladivostok")];
- char stringpool_str229[sizeof("utc")];
- char stringpool_str233[sizeof("ekaterinburg")];
- char stringpool_str265[sizeof("us mountain")];
- char stringpool_str269[sizeof("jerusalem")];
- char stringpool_str272[sizeof("yakutsk")];
- char stringpool_str279[sizeof("pacific sa")];
- char stringpool_str282[sizeof("tonga")];
- char stringpool_str314[sizeof("afghanistan")];
- char stringpool_str319[sizeof("idlw")];
- char stringpool_str322[sizeof("pacific")];
- char stringpool_str327[sizeof("taipei")];
- char stringpool_str328[sizeof("egypt")];
- char stringpool_str392[sizeof("tokyo")];
- char stringpool_str438[sizeof("fiji")];
+ char stringpool_str2[sizeof("o")];
+ char stringpool_str3[sizeof("x")];
+ char stringpool_str4[sizeof("z")];
+ char stringpool_str5[sizeof("q")];
+ char stringpool_str8[sizeof("omst")];
+ char stringpool_str9[sizeof("omsst")];
+ char stringpool_str10[sizeof("p")];
+ char stringpool_str13[sizeof("a")];
+ char stringpool_str14[sizeof("e")];
+ char stringpool_str15[sizeof("pet")];
+ char stringpool_str16[sizeof("pmst")];
+ char stringpool_str17[sizeof("pett")];
+ char stringpool_str18[sizeof("petst")];
+ char stringpool_str19[sizeof("eet")];
+ char stringpool_str20[sizeof("aest")];
+ char stringpool_str21[sizeof("eest")];
+ char stringpool_str22[sizeof("eat")];
+ char stringpool_str24[sizeof("east")];
+ char stringpool_str25[sizeof("easst")];
+ char stringpool_str26[sizeof("pst")];
+ char stringpool_str27[sizeof("eastern")];
+ char stringpool_str28[sizeof("m")];
+ char stringpool_str29[sizeof("ast")];
+ char stringpool_str30[sizeof("est")];
+ char stringpool_str31[sizeof("c")];
+ char stringpool_str32[sizeof("mmt")];
+ char stringpool_str33[sizeof("met")];
+ char stringpool_str35[sizeof("mest")];
+ char stringpool_str36[sizeof("cet")];
+ char stringpool_str37[sizeof("d")];
+ char stringpool_str38[sizeof("cest")];
+ char stringpool_str39[sizeof("cat")];
+ char stringpool_str41[sizeof("cast")];
+ char stringpool_str42[sizeof("magt")];
+ char stringpool_str43[sizeof("magst")];
+ char stringpool_str44[sizeof("mst")];
+ char stringpool_str45[sizeof("msk")];
+ char stringpool_str46[sizeof("cot")];
+ char stringpool_str47[sizeof("cst")];
+ char stringpool_str48[sizeof("aqtt")];
+ char stringpool_str49[sizeof("f")];
+ char stringpool_str52[sizeof("art")];
+ char stringpool_str53[sizeof("fnt")];
+ char stringpool_str54[sizeof("fet")];
+ char stringpool_str55[sizeof("b")];
+ char stringpool_str57[sizeof("anat")];
+ char stringpool_str58[sizeof("anast")];
+ char stringpool_str59[sizeof("bnt")];
+ char stringpool_str60[sizeof("i")];
+ char stringpool_str61[sizeof("pht")];
+ char stringpool_str62[sizeof("at")];
+ char stringpool_str63[sizeof("zp6")];
+ char stringpool_str64[sizeof("mewt")];
+ char stringpool_str65[sizeof("fst")];
+ char stringpool_str66[sizeof("ahst")];
+ char stringpool_str67[sizeof("mawt")];
+ char stringpool_str68[sizeof("zp5")];
+ char stringpool_str70[sizeof("bot")];
+ char stringpool_str71[sizeof("bst")];
+ char stringpool_str72[sizeof("pwt")];
+ char stringpool_str74[sizeof("pont")];
+ char stringpool_str75[sizeof("iot")];
+ char stringpool_str76[sizeof("ist")];
+ char stringpool_str77[sizeof("awst")];
+ char stringpool_str79[sizeof("mht")];
+ char stringpool_str80[sizeof("mez")];
+ char stringpool_str81[sizeof("orat")];
+ char stringpool_str82[sizeof("mesz")];
+ char stringpool_str84[sizeof("chst")];
+ char stringpool_str85[sizeof("pmdt")];
+ char stringpool_str88[sizeof("central")];
+ char stringpool_str89[sizeof("aedt")];
+ char stringpool_str90[sizeof("act")];
+ char stringpool_str91[sizeof("ect")];
+ char stringpool_str92[sizeof("acst")];
+ char stringpool_str93[sizeof("eadt")];
+ char stringpool_str94[sizeof("brt")];
+ char stringpool_str95[sizeof("chut")];
+ char stringpool_str96[sizeof("brst")];
+ char stringpool_str97[sizeof("cen. australia")];
+ char stringpool_str100[sizeof("davt")];
+ char stringpool_str101[sizeof("irst")];
+ char stringpool_str102[sizeof("irkt")];
+ char stringpool_str103[sizeof("irkst")];
+ char stringpool_str104[sizeof("bt")];
+ char stringpool_str105[sizeof("n")];
+ char stringpool_str106[sizeof("btt")];
+ char stringpool_str107[sizeof("mountain")];
+ char stringpool_str108[sizeof("cct")];
+ char stringpool_str109[sizeof("w")];
+ char stringpool_str110[sizeof("l")];
+ char stringpool_str111[sizeof("fwt")];
+ char stringpool_str113[sizeof("msd")];
+ char stringpool_str114[sizeof("wet")];
+ char stringpool_str116[sizeof("west")];
+ char stringpool_str117[sizeof("wat")];
+ char stringpool_str119[sizeof("wast")];
+ char stringpool_str120[sizeof("wakt")];
+ char stringpool_str121[sizeof("nst")];
+ char stringpool_str122[sizeof("acwst")];
+ char stringpool_str123[sizeof("chast")];
+ char stringpool_str124[sizeof("cist")];
+ char stringpool_str125[sizeof("azt")];
+ char stringpool_str126[sizeof("clt")];
+ char stringpool_str127[sizeof("azst")];
+ char stringpool_str128[sizeof("clst")];
+ char stringpool_str129[sizeof("mart")];
+ char stringpool_str130[sizeof("zp4")];
+ char stringpool_str131[sizeof("jst")];
+ char stringpool_str132[sizeof("central asia")];
+ char stringpool_str133[sizeof("aft")];
+ char stringpool_str134[sizeof("e. south america")];
+ char stringpool_str135[sizeof("central america")];
+ char stringpool_str137[sizeof("ict")];
+ char stringpool_str143[sizeof("pgt")];
+ char stringpool_str144[sizeof("nrt")];
+ char stringpool_str145[sizeof("mexico")];
+ char stringpool_str146[sizeof("awdt")];
+ char stringpool_str147[sizeof("egt")];
+ char stringpool_str148[sizeof("cxt")];
+ char stringpool_str149[sizeof("egst")];
+ char stringpool_str150[sizeof("phot")];
+ char stringpool_str151[sizeof("alaskan")];
+ char stringpool_str154[sizeof("nt")];
+ char stringpool_str158[sizeof("wt")];
+ char stringpool_str160[sizeof("west asia")];
+ char stringpool_str161[sizeof("acdt")];
+ char stringpool_str162[sizeof("npt")];
+ char stringpool_str163[sizeof("lhst")];
+ char stringpool_str164[sizeof("afghanistan")];
+ char stringpool_str167[sizeof("k")];
+ char stringpool_str169[sizeof("g")];
+ char stringpool_str170[sizeof("irdt")];
+ char stringpool_str171[sizeof("chot")];
+ char stringpool_str172[sizeof("chost")];
+ char stringpool_str173[sizeof("gmt")];
+ char stringpool_str174[sizeof("get")];
+ char stringpool_str175[sizeof("novt")];
+ char stringpool_str176[sizeof("novst")];
+ char stringpool_str177[sizeof("fjt")];
+ char stringpool_str178[sizeof("u")];
+ char stringpool_str179[sizeof("fjst")];
+ char stringpool_str181[sizeof("pyst")];
+ char stringpool_str182[sizeof("nct")];
+ char stringpool_str183[sizeof("kst")];
+ char stringpool_str184[sizeof("kost")];
+ char stringpool_str185[sizeof("gst")];
+ char stringpool_str186[sizeof("iran")];
+ char stringpool_str187[sizeof("e. africa")];
+ char stringpool_str188[sizeof("wadt")];
+ char stringpool_str189[sizeof("t")];
+ char stringpool_str190[sizeof("e. australia")];
+ char stringpool_str191[sizeof("s")];
+ char stringpool_str192[sizeof("chadt")];
+ char stringpool_str193[sizeof("tmt")];
+ char stringpool_str194[sizeof("cidst")];
+ char stringpool_str195[sizeof("aoe")];
+ char stringpool_str197[sizeof("myt")];
+ char stringpool_str198[sizeof("west pacific")];
+ char stringpool_str199[sizeof("mut")];
+ char stringpool_str200[sizeof("wit")];
+ char stringpool_str201[sizeof("sast")];
+ char stringpool_str202[sizeof("sakt")];
+ char stringpool_str203[sizeof("new zealand")];
+ char stringpool_str204[sizeof("tot")];
+ char stringpool_str205[sizeof("china")];
+ char stringpool_str206[sizeof("tost")];
+ char stringpool_str207[sizeof("sst")];
+ char stringpool_str209[sizeof("india")];
+ char stringpool_str211[sizeof("warst")];
+ char stringpool_str212[sizeof("sbt")];
+ char stringpool_str214[sizeof("azot")];
+ char stringpool_str215[sizeof("azost")];
+ char stringpool_str216[sizeof("taht")];
+ char stringpool_str217[sizeof("nzt")];
+ char stringpool_str218[sizeof("dateline")];
+ char stringpool_str219[sizeof("nzst")];
+ char stringpool_str220[sizeof("tokyo")];
+ char stringpool_str221[sizeof("central pacific")];
+ char stringpool_str223[sizeof("qyzt")];
+ char stringpool_str224[sizeof("atlantic")];
+ char stringpool_str225[sizeof("nft")];
+ char stringpool_str227[sizeof("ut")];
+ char stringpool_str228[sizeof("trt")];
+ char stringpool_str229[sizeof("wft")];
+ char stringpool_str230[sizeof("srt")];
+ char stringpool_str231[sizeof("pdt")];
+ char stringpool_str232[sizeof("lhdt")];
+ char stringpool_str234[sizeof("adt")];
+ char stringpool_str235[sizeof("edt")];
+ char stringpool_str238[sizeof("pkt")];
+ char stringpool_str239[sizeof("almt")];
+ char stringpool_str240[sizeof("wita")];
+ char stringpool_str242[sizeof("wgt")];
+ char stringpool_str243[sizeof("akst")];
+ char stringpool_str244[sizeof("wgst")];
+ char stringpool_str246[sizeof("krat")];
+ char stringpool_str247[sizeof("krast")];
+ char stringpool_str248[sizeof("mid-atlantic")];
+ char stringpool_str249[sizeof("mdt")];
+ char stringpool_str250[sizeof("lint")];
+ char stringpool_str251[sizeof("malay peninsula")];
+ char stringpool_str252[sizeof("cdt")];
+ char stringpool_str253[sizeof("swt")];
+ char stringpool_str255[sizeof("se asia")];
+ char stringpool_str256[sizeof("v")];
+ char stringpool_str258[sizeof("tonga")];
+ char stringpool_str259[sizeof("ckt")];
+ char stringpool_str261[sizeof("vet")];
+ char stringpool_str262[sizeof("caucasus")];
+ char stringpool_str263[sizeof("central europe")];
+ char stringpool_str264[sizeof("h")];
+ char stringpool_str265[sizeof("central european")];
+ char stringpool_str266[sizeof("newfoundland")];
+ char stringpool_str267[sizeof("arab")];
+ char stringpool_str268[sizeof("sct")];
+ char stringpool_str269[sizeof("arabic")];
+ char stringpool_str270[sizeof("arabian")];
+ char stringpool_str271[sizeof("ddut")];
+ char stringpool_str273[sizeof("vost")];
+ char stringpool_str274[sizeof("hast")];
+ char stringpool_str275[sizeof("nepal")];
+ char stringpool_str276[sizeof("nut")];
+ char stringpool_str277[sizeof("fkt")];
+ char stringpool_str279[sizeof("fkst")];
+ char stringpool_str280[sizeof("hst")];
+ char stringpool_str281[sizeof("idt")];
+ char stringpool_str284[sizeof("tlt")];
+ char stringpool_str285[sizeof("w. australia")];
+ char stringpool_str286[sizeof("egypt")];
+ char stringpool_str287[sizeof("myanmar")];
+ char stringpool_str288[sizeof("nzdt")];
+ char stringpool_str289[sizeof("gft")];
+ char stringpool_str290[sizeof("uzt")];
+ char stringpool_str293[sizeof("north asia")];
+ char stringpool_str294[sizeof("mvt")];
+ char stringpool_str295[sizeof("galt")];
+ char stringpool_str296[sizeof("nfdt")];
+ char stringpool_str297[sizeof("cvt")];
+ char stringpool_str298[sizeof("north asia east")];
+ char stringpool_str300[sizeof("kgt")];
+ char stringpool_str301[sizeof("aus central")];
+ char stringpool_str302[sizeof("pacific")];
+ char stringpool_str304[sizeof("canada central")];
+ char stringpool_str306[sizeof("pacific sa")];
+ char stringpool_str307[sizeof("azores")];
+ char stringpool_str308[sizeof("gamt")];
+ char stringpool_str309[sizeof("tft")];
+ char stringpool_str310[sizeof("r")];
+ char stringpool_str311[sizeof("fle")];
+ char stringpool_str312[sizeof("akdt")];
+ char stringpool_str313[sizeof("ulat")];
+ char stringpool_str314[sizeof("ulast")];
+ char stringpool_str315[sizeof("ret")];
+ char stringpool_str317[sizeof("tjt")];
+ char stringpool_str319[sizeof("south africa")];
+ char stringpool_str324[sizeof("sgt")];
+ char stringpool_str326[sizeof("ndt")];
+ char stringpool_str327[sizeof("rott")];
+ char stringpool_str330[sizeof("samt")];
+ char stringpool_str332[sizeof("tasmania")];
+ char stringpool_str334[sizeof("hovt")];
+ char stringpool_str335[sizeof("hovst")];
+ char stringpool_str338[sizeof("gyt")];
+ char stringpool_str342[sizeof("y")];
+ char stringpool_str343[sizeof("hadt")];
+ char stringpool_str344[sizeof("sa western")];
+ char stringpool_str345[sizeof("hawaiian")];
+ char stringpool_str347[sizeof("uyt")];
+ char stringpool_str349[sizeof("uyst")];
+ char stringpool_str350[sizeof("yekt")];
+ char stringpool_str351[sizeof("yekst")];
+ char stringpool_str352[sizeof("kuyt")];
+ char stringpool_str353[sizeof("yakt")];
+ char stringpool_str354[sizeof("yakst")];
+ char stringpool_str358[sizeof("yst")];
+ char stringpool_str359[sizeof("jerusalem")];
+ char stringpool_str365[sizeof("sri lanka")];
+ char stringpool_str367[sizeof("yakutsk")];
+ char stringpool_str375[sizeof("wib")];
+ char stringpool_str377[sizeof("aus eastern")];
+ char stringpool_str378[sizeof("gilt")];
+ char stringpool_str387[sizeof("us mountain")];
+ char stringpool_str391[sizeof("vlat")];
+ char stringpool_str392[sizeof("vlast")];
+ char stringpool_str395[sizeof("gtb")];
+ char stringpool_str398[sizeof("taipei")];
+ char stringpool_str399[sizeof("sret")];
+ char stringpool_str408[sizeof("cape verde")];
+ char stringpool_str417[sizeof("tkt")];
+ char stringpool_str418[sizeof("samoa")];
+ char stringpool_str421[sizeof("sa pacific")];
+ char stringpool_str427[sizeof("vut")];
+ char stringpool_str428[sizeof("idlw")];
+ char stringpool_str432[sizeof("fiji")];
+ char stringpool_str435[sizeof("utc")];
+ char stringpool_str443[sizeof("korea")];
+ char stringpool_str445[sizeof("e. europe")];
+ char stringpool_str449[sizeof("syot")];
+ char stringpool_str452[sizeof("n. central asia")];
+ char stringpool_str455[sizeof("tvt")];
+ char stringpool_str458[sizeof("w. central africa")];
+ char stringpool_str466[sizeof("ekaterinburg")];
+ char stringpool_str468[sizeof("vladivostok")];
+ char stringpool_str476[sizeof("yapt")];
+ char stringpool_str477[sizeof("us eastern")];
+ char stringpool_str482[sizeof("sa eastern")];
+ char stringpool_str485[sizeof("hdt")];
+ char stringpool_str486[sizeof("russian")];
+ char stringpool_str492[sizeof("hkt")];
+ char stringpool_str497[sizeof("romance")];
+ char stringpool_str540[sizeof("w. europe")];
+ char stringpool_str563[sizeof("ydt")];
+ char stringpool_str566[sizeof("idle")];
+ char stringpool_str567[sizeof("greenwich")];
+ char stringpool_str619[sizeof("greenland")];
};
static const struct stringpool_t stringpool_contents =
{
- "r",
- "s",
- "d",
- "cst",
- "cdt",
- "sst",
- "cet",
- "msd",
- "cest",
- "cat",
- "mst",
- "mdt",
- "sast",
- "met",
- "mest",
- "wet",
- "dateline",
- "west",
- "wat",
- "wast",
- "wadt",
+ "o",
+ "x",
+ "z",
+ "q",
+ "omst",
+ "omsst",
+ "p",
+ "a",
"e",
- "central europe",
- "central asia",
- "west asia",
- "cen. australia",
- "central america",
- "est",
- "edt",
- "central european",
+ "pet",
+ "pmst",
+ "pett",
+ "petst",
"eet",
- "se asia",
+ "aest",
"eest",
"eat",
- "z",
"east",
- "eadt",
- "sa eastern",
- "w. europe",
- "c",
- "yst",
- "ydt",
- "kst",
- "clt",
+ "easst",
+ "pst",
"eastern",
- "clst",
- "bt",
- "w. australia",
- "bst",
- "cct",
- "brt",
- "brst",
- "a",
- "e. europe",
- "at",
- "central",
+ "m",
"ast",
- "adt",
+ "est",
+ "c",
+ "mmt",
+ "met",
+ "mest",
+ "cet",
+ "d",
+ "cest",
+ "cat",
+ "cast",
+ "magt",
+ "magst",
+ "mst",
+ "msk",
+ "cot",
+ "cst",
+ "aqtt",
+ "f",
"art",
- "e. africa",
- "e. south america",
- "jst",
- "e. australia",
- "t",
- "nt",
- "n",
- "nst",
- "ndt",
- "canada central",
- "central pacific",
- "west pacific",
- "hst",
- "hdt",
- "malay peninsula",
+ "fnt",
+ "fet",
+ "b",
+ "anat",
+ "anast",
+ "bnt",
+ "i",
+ "pht",
+ "at",
"zp6",
- "russian",
- "hast",
- "hadt",
- "gst",
+ "mewt",
+ "fst",
+ "ahst",
+ "mawt",
"zp5",
+ "bot",
+ "bst",
+ "pwt",
+ "pont",
+ "iot",
"ist",
- "swt",
- "w",
- "zp4",
+ "awst",
+ "mht",
"mez",
- "cape verde",
+ "orat",
"mesz",
- "greenland",
- "x",
- "mewt",
- "w. central africa",
+ "chst",
+ "pmdt",
+ "central",
+ "aedt",
+ "act",
+ "ect",
+ "acst",
+ "eadt",
+ "brt",
+ "chut",
+ "brst",
+ "cen. australia",
+ "davt",
+ "irst",
+ "irkt",
+ "irkst",
+ "bt",
+ "n",
+ "btt",
+ "mountain",
+ "cct",
+ "w",
+ "l",
+ "fwt",
+ "msd",
+ "wet",
+ "west",
+ "wat",
+ "wast",
+ "wakt",
+ "nst",
+ "acwst",
+ "chast",
+ "cist",
+ "azt",
+ "clt",
+ "azst",
+ "clst",
+ "mart",
+ "zp4",
+ "jst",
+ "central asia",
+ "aft",
+ "e. south america",
+ "central america",
+ "ict",
+ "pgt",
+ "nrt",
+ "mexico",
+ "awdt",
+ "egt",
+ "cxt",
+ "egst",
+ "phot",
+ "alaskan",
+ "nt",
+ "wt",
+ "west asia",
+ "acdt",
+ "npt",
+ "lhst",
+ "afghanistan",
"k",
- "b",
- "m",
- "sri lanka",
- "fst",
+ "g",
+ "irdt",
+ "chot",
+ "chost",
+ "gmt",
+ "get",
+ "novt",
+ "novst",
+ "fjt",
+ "u",
+ "fjst",
+ "pyst",
+ "nct",
+ "kst",
+ "kost",
+ "gst",
"iran",
- "sgt",
- "ut",
- "q",
+ "e. africa",
+ "wadt",
+ "t",
+ "e. australia",
+ "s",
+ "chadt",
+ "tmt",
+ "cidst",
+ "aoe",
+ "myt",
+ "west pacific",
+ "mut",
+ "wit",
+ "sast",
+ "sakt",
+ "new zealand",
+ "tot",
+ "china",
+ "tost",
+ "sst",
+ "india",
+ "warst",
+ "sbt",
+ "azot",
+ "azost",
+ "taht",
"nzt",
+ "dateline",
"nzst",
- "nzdt",
- "myanmar",
- "alaskan",
- "pst",
+ "tokyo",
+ "central pacific",
+ "qyzt",
+ "atlantic",
+ "nft",
+ "ut",
+ "trt",
+ "wft",
+ "srt",
"pdt",
- "sa western",
- "korea",
- "y",
- "f",
+ "lhdt",
+ "adt",
+ "edt",
+ "pkt",
+ "almt",
+ "wita",
+ "wgt",
"akst",
- "akdt",
- "caucasus",
- "msk",
- "idle",
- "arabian",
- "o",
- "l",
+ "wgst",
+ "krat",
+ "krast",
"mid-atlantic",
- "us eastern",
- "ahst",
+ "mdt",
+ "lint",
+ "malay peninsula",
+ "cdt",
+ "swt",
+ "se asia",
+ "v",
+ "tonga",
+ "ckt",
+ "vet",
+ "caucasus",
+ "central europe",
"h",
- "fle",
- "i",
+ "central european",
+ "newfoundland",
+ "arab",
+ "sct",
+ "arabic",
+ "arabian",
+ "ddut",
+ "vost",
+ "hast",
+ "nepal",
+ "nut",
+ "fkt",
+ "fkst",
+ "hst",
+ "idt",
+ "tlt",
+ "w. australia",
+ "egypt",
+ "myanmar",
+ "nzdt",
+ "gft",
+ "uzt",
"north asia",
- "n. central asia",
+ "mvt",
+ "galt",
+ "nfdt",
+ "cvt",
"north asia east",
- "sa pacific",
- "south africa",
- "aus eastern",
- "atlantic",
- "mexico",
- "mountain",
- "china",
+ "kgt",
+ "aus central",
+ "pacific",
+ "canada central",
+ "pacific sa",
"azores",
- "india",
- "u",
- "arabic",
- "greenwich",
- "new zealand",
- "hawaiian",
- "g",
- "romance",
- "arab",
- "samoa",
- "v",
- "p",
- "gmt",
+ "gamt",
+ "tft",
+ "r",
+ "fle",
+ "akdt",
+ "ulat",
+ "ulast",
+ "ret",
+ "tjt",
+ "south africa",
+ "sgt",
+ "ndt",
+ "rott",
+ "samt",
"tasmania",
- "fwt",
- "newfoundland",
- "nepal",
- "aus central",
- "gtb",
- "vladivostok",
- "utc",
- "ekaterinburg",
- "us mountain",
+ "hovt",
+ "hovst",
+ "gyt",
+ "y",
+ "hadt",
+ "sa western",
+ "hawaiian",
+ "uyt",
+ "uyst",
+ "yekt",
+ "yekst",
+ "kuyt",
+ "yakt",
+ "yakst",
+ "yst",
"jerusalem",
+ "sri lanka",
"yakutsk",
- "pacific sa",
- "tonga",
- "afghanistan",
- "idlw",
- "pacific",
+ "wib",
+ "aus eastern",
+ "gilt",
+ "us mountain",
+ "vlat",
+ "vlast",
+ "gtb",
"taipei",
- "egypt",
- "tokyo",
- "fiji"
+ "sret",
+ "cape verde",
+ "tkt",
+ "samoa",
+ "sa pacific",
+ "vut",
+ "idlw",
+ "fiji",
+ "utc",
+ "korea",
+ "e. europe",
+ "syot",
+ "n. central asia",
+ "tvt",
+ "w. central africa",
+ "ekaterinburg",
+ "vladivostok",
+ "yapt",
+ "us eastern",
+ "sa eastern",
+ "hdt",
+ "russian",
+ "hkt",
+ "romance",
+ "w. europe",
+ "ydt",
+ "idle",
+ "greenwich",
+ "greenland"
};
#define stringpool ((const char *) &stringpool_contents)
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct zone *
-zonetab (str, len)
- register const char *str;
- register unsigned int len;
+zonetab (register const char *str, register size_t len)
{
- enum
- {
- TOTAL_KEYWORDS = 170,
- MIN_WORD_LENGTH = 1,
- MAX_WORD_LENGTH = 17,
- MIN_HASH_VALUE = 5,
- MAX_HASH_VALUE = 438
- };
-
static const struct zone wordlist[] =
{
- {-1}, {-1}, {-1}, {-1}, {-1},
-#line 37 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str5), -5*3600},
-#line 38 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str6), -6*3600},
-#line 24 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str7), 4*3600},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#line 15 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str14), -6*3600},
-#line 16 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str15), -5*3600},
-#line 85 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str16), 2*3600},
-#line 71 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str17), 1*3600},
-#line 90 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str18), 4*3600},
-#line 79 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str19), 2*3600},
-#line 65 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str20),-10*3600},
- {-1},
-#line 17 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str22), -7*3600},
-#line 18 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str23), -6*3600},
-#line 84 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str24), 2*3600},
-#line 73 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str25), 1*3600},
- {-1},
-#line 82 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str27), 2*3600},
{-1}, {-1},
-#line 47 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str30), 0*3600},
-#line 128 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str31), -43200},
-#line 78 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str32), 1*3600},
-#line 77 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str33), 1*3600},
- {-1},
-#line 95 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str35), 7*3600},
-#line 98 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str36), 8*3600},
+#line 34 "zonetab.list"
+ {gperf_offsetof(stringpool, 2), -2*3600},
+#line 43 "zonetab.list"
+ {gperf_offsetof(stringpool, 3), -11*3600},
+#line 45 "zonetab.list"
+ {gperf_offsetof(stringpool, 4), 0*3600},
+#line 36 "zonetab.list"
+ {gperf_offsetof(stringpool, 5), -4*3600},
+ {-1}, {-1},
+#line 269 "zonetab.list"
+ {gperf_offsetof(stringpool, 8),21600},
+#line 268 "zonetab.list"
+ {gperf_offsetof(stringpool, 9),25200},
+#line 35 "zonetab.list"
+ {gperf_offsetof(stringpool, 10), -3*3600},
+ {-1}, {-1},
+#line 21 "zonetab.list"
+ {gperf_offsetof(stringpool, 13), 1*3600},
#line 25 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str37), 5*3600},
-#line 123 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str38), 3600},
-#line 122 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str39), 21600},
-#line 178 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str40), 18000},
-#line 120 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str41), 34200},
-#line 121 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str42), -21600},
- {-1},
-#line 13 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str44), -5*3600},
-#line 14 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str45), -4*3600},
-#line 124 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str46), 3600},
+ {gperf_offsetof(stringpool, 14), 5*3600},
+#line 271 "zonetab.list"
+ {gperf_offsetof(stringpool, 15),-18000},
+#line 279 "zonetab.list"
+ {gperf_offsetof(stringpool, 16),-10800},
+#line 273 "zonetab.list"
+ {gperf_offsetof(stringpool, 17),43200},
+#line 272 "zonetab.list"
+ {gperf_offsetof(stringpool, 18),43200},
#line 80 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str47), 2*3600},
-#line 164 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str48), 25200},
+ {gperf_offsetof(stringpool, 19), 2*3600},
+#line 186 "zonetab.list"
+ {gperf_offsetof(stringpool, 20),36000},
#line 88 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str49), 3*3600},
+ {gperf_offsetof(stringpool, 21), 3*3600},
#line 87 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str50), 3*3600},
-#line 45 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str51), 0*3600},
+ {gperf_offsetof(stringpool, 22), 3*3600},
+ {-1},
#line 101 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str52),10*3600},
-#line 103 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str53),11*3600},
-#line 160 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str54), -10800},
-#line 177 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str55), 3600},
-#line 23 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str56), 3*3600},
-#line 63 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str57), -9*3600},
-#line 59 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str58), -8*3600},
-#line 100 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str59), 9*3600},
-#line 57 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str60), -4*3600},
+ {gperf_offsetof(stringpool, 24),10*3600},
+#line 217 "zonetab.list"
+ {gperf_offsetof(stringpool, 25),-18000},
+#line 19 "zonetab.list"
+ {gperf_offsetof(stringpool, 26), -8*3600},
#line 133 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str61), -18000},
-#line 54 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str62),-3*3600},
-#line 86 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str63), 3*3600},
-#line 175 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str64), 28800},
-#line 70 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str65), 1*3600},
-#line 96 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str66), 8*3600},
-#line 53 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str67), -3*3600},
+ {gperf_offsetof(stringpool, 27), -18000},
+#line 32 "zonetab.list"
+ {gperf_offsetof(stringpool, 28), 12*3600},
+#line 56 "zonetab.list"
+ {gperf_offsetof(stringpool, 29), -4*3600},
+#line 13 "zonetab.list"
+ {gperf_offsetof(stringpool, 30), -5*3600},
+#line 23 "zonetab.list"
+ {gperf_offsetof(stringpool, 31), 3*3600},
+#line 256 "zonetab.list"
+ {gperf_offsetof(stringpool, 32),23400},
+#line 73 "zonetab.list"
+ {gperf_offsetof(stringpool, 33), 1*3600},
{-1},
-#line 49 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str69),-2*3600},
+#line 82 "zonetab.list"
+ {gperf_offsetof(stringpool, 35), 2*3600},
+#line 71 "zonetab.list"
+ {gperf_offsetof(stringpool, 36), 1*3600},
+#line 24 "zonetab.list"
+ {gperf_offsetof(stringpool, 37), 4*3600},
+#line 79 "zonetab.list"
+ {gperf_offsetof(stringpool, 38), 2*3600},
+#line 65 "zonetab.list"
+ {gperf_offsetof(stringpool, 39),-10*3600},
{-1},
-#line 21 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str71), 1*3600},
-#line 131 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str72), 7200},
-#line 48 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str73), -2*3600},
-#line 126 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str74), -21600},
-#line 56 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str75), -4*3600},
-#line 52 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str76), -3*3600},
+#line 202 "zonetab.list"
+ {gperf_offsetof(stringpool, 41),28800},
+#line 252 "zonetab.list"
+ {gperf_offsetof(stringpool, 42),39600},
+#line 251 "zonetab.list"
+ {gperf_offsetof(stringpool, 43),43200},
+#line 17 "zonetab.list"
+ {gperf_offsetof(stringpool, 44), -7*3600},
+#line 89 "zonetab.list"
+ {gperf_offsetof(stringpool, 45), 3*3600},
+#line 212 "zonetab.list"
+ {gperf_offsetof(stringpool, 46),-18000},
+#line 15 "zonetab.list"
+ {gperf_offsetof(stringpool, 47), -6*3600},
+#line 192 "zonetab.list"
+ {gperf_offsetof(stringpool, 48),18000},
+#line 26 "zonetab.list"
+ {gperf_offsetof(stringpool, 49), 6*3600},
+ {-1}, {-1},
#line 51 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str77), -3*3600},
-#line 129 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str78), 10800},
-#line 132 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str79), -10800},
-#line 99 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str80), 9*3600},
-#line 130 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str81), 36000},
-#line 39 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str82), -7*3600},
-#line 68 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str83), -11*3600},
-#line 33 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str84), -1*3600},
-#line 55 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str85), -(3*3600+1800)},
-#line 50 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str86), -(2*3600+1800)},
-#line 117 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str87), -21600},
-#line 125 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str88), 39600},
-#line 179 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str89), 36000},
-#line 67 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str90),-10*3600},
-#line 62 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str91), -9*3600},
- {-1},
-#line 165 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str93), 28800},
+ {gperf_offsetof(stringpool, 52), -3*3600},
+#line 226 "zonetab.list"
+ {gperf_offsetof(stringpool, 53),-7200},
+#line 221 "zonetab.list"
+ {gperf_offsetof(stringpool, 54),10800},
+#line 22 "zonetab.list"
+ {gperf_offsetof(stringpool, 55), 2*3600},
{-1},
+#line 190 "zonetab.list"
+ {gperf_offsetof(stringpool, 57),43200},
+#line 189 "zonetab.list"
+ {gperf_offsetof(stringpool, 58),43200},
+#line 199 "zonetab.list"
+ {gperf_offsetof(stringpool, 59),28800},
+#line 29 "zonetab.list"
+ {gperf_offsetof(stringpool, 60), 9*3600},
+#line 276 "zonetab.list"
+ {gperf_offsetof(stringpool, 61),28800},
+#line 48 "zonetab.list"
+ {gperf_offsetof(stringpool, 62), -2*3600},
#line 94 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str95), 6*3600},
- {-1},
-#line 159 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str97), 10800},
-#line 66 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str98),-10*3600},
-#line 61 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str99),-9*3600},
-#line 102 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str100), 10*3600},
+ {gperf_offsetof(stringpool, 63), 6*3600},
+#line 74 "zonetab.list"
+ {gperf_offsetof(stringpool, 64), 1*3600},
+#line 81 "zonetab.list"
+ {gperf_offsetof(stringpool, 65), 2*3600},
+#line 64 "zonetab.list"
+ {gperf_offsetof(stringpool, 66),-10*3600},
+#line 254 "zonetab.list"
+ {gperf_offsetof(stringpool, 67),18000},
#line 92 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str101), 5*3600},
+ {gperf_offsetof(stringpool, 68), 5*3600},
+ {-1},
+#line 200 "zonetab.list"
+ {gperf_offsetof(stringpool, 70),-14400},
+#line 70 "zonetab.list"
+ {gperf_offsetof(stringpool, 71), 1*3600},
+#line 281 "zonetab.list"
+ {gperf_offsetof(stringpool, 72),32400},
+ {-1},
+#line 280 "zonetab.list"
+ {gperf_offsetof(stringpool, 74),39600},
+#line 238 "zonetab.list"
+ {gperf_offsetof(stringpool, 75),21600},
#line 93 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str102), (5*3600+1800)},
-#line 76 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str103), 1*3600},
-#line 42 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str104), -10*3600},
-#line 91 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str105), 4*3600},
+ {gperf_offsetof(stringpool, 76), (5*3600+1800)},
+#line 194 "zonetab.list"
+ {gperf_offsetof(stringpool, 77),28800},
{-1},
+#line 255 "zonetab.list"
+ {gperf_offsetof(stringpool, 79),43200},
#line 75 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str107), 1*3600},
-#line 118 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str108), -3600},
+ {gperf_offsetof(stringpool, 80), 1*3600},
+#line 270 "zonetab.list"
+ {gperf_offsetof(stringpool, 81),18000},
#line 83 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str109), 2*3600},
-#line 138 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str110), -10800},
+ {gperf_offsetof(stringpool, 82), 2*3600},
{-1},
-#line 43 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str112), -11*3600},
+#line 207 "zonetab.list"
+ {gperf_offsetof(stringpool, 84),36000},
+#line 278 "zonetab.list"
+ {gperf_offsetof(stringpool, 85),-7200},
+ {-1}, {-1},
+#line 126 "zonetab.list"
+ {gperf_offsetof(stringpool, 88), -21600},
+#line 185 "zonetab.list"
+ {gperf_offsetof(stringpool, 89),39600},
+#line 183 "zonetab.list"
+ {gperf_offsetof(stringpool, 90),-18000},
+#line 218 "zonetab.list"
+ {gperf_offsetof(stringpool, 91),-18000},
+#line 182 "zonetab.list"
+ {gperf_offsetof(stringpool, 92),34200},
+#line 103 "zonetab.list"
+ {gperf_offsetof(stringpool, 93),11*3600},
+#line 53 "zonetab.list"
+ {gperf_offsetof(stringpool, 94), -3*3600},
+#line 208 "zonetab.list"
+ {gperf_offsetof(stringpool, 95),36000},
+#line 49 "zonetab.list"
+ {gperf_offsetof(stringpool, 96),-2*3600},
+#line 120 "zonetab.list"
+ {gperf_offsetof(stringpool, 97), 34200},
+ {-1}, {-1},
+#line 215 "zonetab.list"
+ {gperf_offsetof(stringpool, 100),25200},
+#line 242 "zonetab.list"
+ {gperf_offsetof(stringpool, 101),12600},
+#line 241 "zonetab.list"
+ {gperf_offsetof(stringpool, 102),28800},
+#line 240 "zonetab.list"
+ {gperf_offsetof(stringpool, 103),32400},
+#line 86 "zonetab.list"
+ {gperf_offsetof(stringpool, 104), 3*3600},
+#line 33 "zonetab.list"
+ {gperf_offsetof(stringpool, 105), -1*3600},
+#line 201 "zonetab.list"
+ {gperf_offsetof(stringpool, 106),21600},
+#line 148 "zonetab.list"
+ {gperf_offsetof(stringpool, 107), -25200},
+#line 96 "zonetab.list"
+ {gperf_offsetof(stringpool, 108), 8*3600},
+#line 42 "zonetab.list"
+ {gperf_offsetof(stringpool, 109), -10*3600},
+#line 31 "zonetab.list"
+ {gperf_offsetof(stringpool, 110), 11*3600},
+#line 72 "zonetab.list"
+ {gperf_offsetof(stringpool, 111), 1*3600},
{-1},
-#line 74 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str114), 1*3600},
-#line 176 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str115), 3600},
-#line 30 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str116), 10*3600},
-#line 22 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str117), 2*3600},
+#line 90 "zonetab.list"
+ {gperf_offsetof(stringpool, 113), 4*3600},
+#line 47 "zonetab.list"
+ {gperf_offsetof(stringpool, 114), 0*3600},
{-1},
-#line 32 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str119), 12*3600},
-#line 167 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str120), 21600},
+#line 78 "zonetab.list"
+ {gperf_offsetof(stringpool, 116), 1*3600},
+#line 77 "zonetab.list"
+ {gperf_offsetof(stringpool, 117), 1*3600},
{-1},
-#line 81 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str122), 2*3600},
+#line 95 "zonetab.list"
+ {gperf_offsetof(stringpool, 119), 7*3600},
+#line 313 "zonetab.list"
+ {gperf_offsetof(stringpool, 120),43200},
+#line 55 "zonetab.list"
+ {gperf_offsetof(stringpool, 121), -(3*3600+1800)},
+#line 184 "zonetab.list"
+ {gperf_offsetof(stringpool, 122),31500},
+#line 204 "zonetab.list"
+ {gperf_offsetof(stringpool, 123),45900},
+#line 210 "zonetab.list"
+ {gperf_offsetof(stringpool, 124),-18000},
+#line 198 "zonetab.list"
+ {gperf_offsetof(stringpool, 125),14400},
+#line 57 "zonetab.list"
+ {gperf_offsetof(stringpool, 126), -4*3600},
+#line 197 "zonetab.list"
+ {gperf_offsetof(stringpool, 127),18000},
+#line 54 "zonetab.list"
+ {gperf_offsetof(stringpool, 128),-3*3600},
+#line 253 "zonetab.list"
+ {gperf_offsetof(stringpool, 129),-30600},
+#line 91 "zonetab.list"
+ {gperf_offsetof(stringpool, 130), 4*3600},
+#line 99 "zonetab.list"
+ {gperf_offsetof(stringpool, 131), 9*3600},
+#line 122 "zonetab.list"
+ {gperf_offsetof(stringpool, 132), 21600},
+#line 187 "zonetab.list"
+ {gperf_offsetof(stringpool, 133),16200},
+#line 132 "zonetab.list"
+ {gperf_offsetof(stringpool, 134), -10800},
+#line 121 "zonetab.list"
+ {gperf_offsetof(stringpool, 135), -21600},
+ {-1},
+#line 236 "zonetab.list"
+ {gperf_offsetof(stringpool, 137),25200},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+#line 274 "zonetab.list"
+ {gperf_offsetof(stringpool, 143),36000},
+#line 266 "zonetab.list"
+ {gperf_offsetof(stringpool, 144),43200},
+#line 146 "zonetab.list"
+ {gperf_offsetof(stringpool, 145), -21600},
+#line 193 "zonetab.list"
+ {gperf_offsetof(stringpool, 146),32400},
+#line 220 "zonetab.list"
+ {gperf_offsetof(stringpool, 147),-3600},
+#line 214 "zonetab.list"
+ {gperf_offsetof(stringpool, 148),25200},
+#line 219 "zonetab.list"
+ {gperf_offsetof(stringpool, 149),0},
+#line 275 "zonetab.list"
+ {gperf_offsetof(stringpool, 150),46800},
+#line 109 "zonetab.list"
+ {gperf_offsetof(stringpool, 151), -32400},
+ {-1}, {-1},
+#line 68 "zonetab.list"
+ {gperf_offsetof(stringpool, 154), -11*3600},
+ {-1}, {-1}, {-1},
+#line 321 "zonetab.list"
+ {gperf_offsetof(stringpool, 158),0},
{-1},
+#line 178 "zonetab.list"
+ {gperf_offsetof(stringpool, 160), 18000},
+#line 181 "zonetab.list"
+ {gperf_offsetof(stringpool, 161),37800},
+#line 265 "zonetab.list"
+ {gperf_offsetof(stringpool, 162),20700},
+#line 249 "zonetab.list"
+ {gperf_offsetof(stringpool, 163),37800},
+#line 108 "zonetab.list"
+ {gperf_offsetof(stringpool, 164), 16200},
+ {-1}, {-1},
+#line 30 "zonetab.list"
+ {gperf_offsetof(stringpool, 167), 10*3600},
+ {-1},
+#line 27 "zonetab.list"
+ {gperf_offsetof(stringpool, 169), 7*3600},
+#line 239 "zonetab.list"
+ {gperf_offsetof(stringpool, 170),16200},
+#line 206 "zonetab.list"
+ {gperf_offsetof(stringpool, 171),28800},
+#line 205 "zonetab.list"
+ {gperf_offsetof(stringpool, 172),32400},
+#line 12 "zonetab.list"
+ {gperf_offsetof(stringpool, 173), 0*3600},
+#line 229 "zonetab.list"
+ {gperf_offsetof(stringpool, 174),14400},
+#line 264 "zonetab.list"
+ {gperf_offsetof(stringpool, 175),25200},
+#line 263 "zonetab.list"
+ {gperf_offsetof(stringpool, 176),25200},
+#line 223 "zonetab.list"
+ {gperf_offsetof(stringpool, 177),43200},
+#line 40 "zonetab.list"
+ {gperf_offsetof(stringpool, 178), -8*3600},
+#line 222 "zonetab.list"
+ {gperf_offsetof(stringpool, 179),46800},
+ {-1},
+#line 282 "zonetab.list"
+ {gperf_offsetof(stringpool, 181),-10800},
+#line 260 "zonetab.list"
+ {gperf_offsetof(stringpool, 182),39600},
+#line 100 "zonetab.list"
+ {gperf_offsetof(stringpool, 183), 9*3600},
+#line 244 "zonetab.list"
+ {gperf_offsetof(stringpool, 184),39600},
+#line 102 "zonetab.list"
+ {gperf_offsetof(stringpool, 185), 10*3600},
#line 143 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str124), 12600},
-#line 97 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str125), 8*3600},
-#line 11 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str126), 0*3600},
+ {gperf_offsetof(stringpool, 186), 12600},
+#line 129 "zonetab.list"
+ {gperf_offsetof(stringpool, 187), 10800},
+#line 98 "zonetab.list"
+ {gperf_offsetof(stringpool, 188), 8*3600},
+#line 39 "zonetab.list"
+ {gperf_offsetof(stringpool, 189), -7*3600},
+#line 130 "zonetab.list"
+ {gperf_offsetof(stringpool, 190), 36000},
+#line 38 "zonetab.list"
+ {gperf_offsetof(stringpool, 191), -6*3600},
+#line 203 "zonetab.list"
+ {gperf_offsetof(stringpool, 192),49500},
+#line 298 "zonetab.list"
+ {gperf_offsetof(stringpool, 193),18000},
+#line 209 "zonetab.list"
+ {gperf_offsetof(stringpool, 194),-14400},
+#line 191 "zonetab.list"
+ {gperf_offsetof(stringpool, 195),-43200},
{-1},
-#line 36 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str128), -4*3600},
-#line 106 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str129), 12*3600},
+#line 259 "zonetab.list"
+ {gperf_offsetof(stringpool, 197),28800},
+#line 179 "zonetab.list"
+ {gperf_offsetof(stringpool, 198), 36000},
+#line 257 "zonetab.list"
+ {gperf_offsetof(stringpool, 199),14400},
+#line 319 "zonetab.list"
+ {gperf_offsetof(stringpool, 200),32400},
+#line 84 "zonetab.list"
+ {gperf_offsetof(stringpool, 201), 2*3600},
+#line 286 "zonetab.list"
+ {gperf_offsetof(stringpool, 202),39600},
+#line 152 "zonetab.list"
+ {gperf_offsetof(stringpool, 203), 43200},
+#line 300 "zonetab.list"
+ {gperf_offsetof(stringpool, 204),46800},
+#line 127 "zonetab.list"
+ {gperf_offsetof(stringpool, 205), 28800},
+#line 299 "zonetab.list"
+ {gperf_offsetof(stringpool, 206),50400},
+#line 85 "zonetab.list"
+ {gperf_offsetof(stringpool, 207), 2*3600},
+ {-1},
+#line 142 "zonetab.list"
+ {gperf_offsetof(stringpool, 209), 19800},
{-1},
+#line 314 "zonetab.list"
+ {gperf_offsetof(stringpool, 211),-10800},
+#line 288 "zonetab.list"
+ {gperf_offsetof(stringpool, 212),39600},
+ {-1},
+#line 196 "zonetab.list"
+ {gperf_offsetof(stringpool, 214),-3600},
+#line 195 "zonetab.list"
+ {gperf_offsetof(stringpool, 215),0},
+#line 293 "zonetab.list"
+ {gperf_offsetof(stringpool, 216),-36000},
+#line 106 "zonetab.list"
+ {gperf_offsetof(stringpool, 217), 12*3600},
+#line 128 "zonetab.list"
+ {gperf_offsetof(stringpool, 218), -43200},
#line 105 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str131),12*3600},
-#line 107 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str132),13*3600},
-#line 149 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str133), 23400},
+ {gperf_offsetof(stringpool, 219),12*3600},
+#line 170 "zonetab.list"
+ {gperf_offsetof(stringpool, 220), 32400},
+#line 125 "zonetab.list"
+ {gperf_offsetof(stringpool, 221), 39600},
{-1},
-#line 109 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str135), -32400},
-#line 19 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str136), -8*3600},
+#line 283 "zonetab.list"
+ {gperf_offsetof(stringpool, 223),21600},
+#line 113 "zonetab.list"
+ {gperf_offsetof(stringpool, 224), -14400},
+#line 262 "zonetab.list"
+ {gperf_offsetof(stringpool, 225),39600},
+ {-1},
+#line 11 "zonetab.list"
+ {gperf_offsetof(stringpool, 227), 0*3600},
+#line 301 "zonetab.list"
+ {gperf_offsetof(stringpool, 228),10800},
+#line 315 "zonetab.list"
+ {gperf_offsetof(stringpool, 229),43200},
+#line 291 "zonetab.list"
+ {gperf_offsetof(stringpool, 230),-10800},
#line 20 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str137), -7*3600},
-#line 162 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str138), -14400},
-#line 145 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str139), 32400},
+ {gperf_offsetof(stringpool, 231), -7*3600},
+#line 248 "zonetab.list"
+ {gperf_offsetof(stringpool, 232),39600},
+ {-1},
+#line 52 "zonetab.list"
+ {gperf_offsetof(stringpool, 234), -3*3600},
+#line 14 "zonetab.list"
+ {gperf_offsetof(stringpool, 235), -4*3600},
{-1}, {-1},
-#line 44 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str142), -12*3600},
-#line 26 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str143), 6*3600},
+#line 277 "zonetab.list"
+ {gperf_offsetof(stringpool, 238),18000},
+#line 188 "zonetab.list"
+ {gperf_offsetof(stringpool, 239),21600},
+#line 320 "zonetab.list"
+ {gperf_offsetof(stringpool, 240),28800},
+ {-1},
+#line 317 "zonetab.list"
+ {gperf_offsetof(stringpool, 242),-10800},
#line 60 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str144),-9*3600},
-#line 58 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str145),-8*3600},
- {-1}, {-1},
-#line 119 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str148), 14400},
+ {gperf_offsetof(stringpool, 243),-9*3600},
+#line 316 "zonetab.list"
+ {gperf_offsetof(stringpool, 244),-7200},
{-1},
-#line 89 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str150), 3*3600},
-#line 104 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str151),12*3600},
+#line 246 "zonetab.list"
+ {gperf_offsetof(stringpool, 246),25200},
+#line 245 "zonetab.list"
+ {gperf_offsetof(stringpool, 247),28800},
+#line 147 "zonetab.list"
+ {gperf_offsetof(stringpool, 248), -7200},
+#line 18 "zonetab.list"
+ {gperf_offsetof(stringpool, 249), -6*3600},
+#line 250 "zonetab.list"
+ {gperf_offsetof(stringpool, 250),50400},
+#line 165 "zonetab.list"
+ {gperf_offsetof(stringpool, 251), 28800},
+#line 16 "zonetab.list"
+ {gperf_offsetof(stringpool, 252), -5*3600},
+#line 76 "zonetab.list"
+ {gperf_offsetof(stringpool, 253), 1*3600},
+ {-1},
+#line 164 "zonetab.list"
+ {gperf_offsetof(stringpool, 255), 25200},
+#line 41 "zonetab.list"
+ {gperf_offsetof(stringpool, 256), -9*3600},
{-1},
+#line 171 "zonetab.list"
+ {gperf_offsetof(stringpool, 258), 46800},
+#line 211 "zonetab.list"
+ {gperf_offsetof(stringpool, 259),-36000},
+ {-1},
+#line 308 "zonetab.list"
+ {gperf_offsetof(stringpool, 261),-14400},
+#line 119 "zonetab.list"
+ {gperf_offsetof(stringpool, 262), 14400},
+#line 123 "zonetab.list"
+ {gperf_offsetof(stringpool, 263), 3600},
+#line 28 "zonetab.list"
+ {gperf_offsetof(stringpool, 264), 8*3600},
+#line 124 "zonetab.list"
+ {gperf_offsetof(stringpool, 265), 3600},
+#line 153 "zonetab.list"
+ {gperf_offsetof(stringpool, 266), -12600},
+#line 110 "zonetab.list"
+ {gperf_offsetof(stringpool, 267), 10800},
+#line 289 "zonetab.list"
+ {gperf_offsetof(stringpool, 268),14400},
+#line 112 "zonetab.list"
+ {gperf_offsetof(stringpool, 269), 10800},
#line 111 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str153), 14400},
+ {gperf_offsetof(stringpool, 270), 14400},
+#line 216 "zonetab.list"
+ {gperf_offsetof(stringpool, 271),36000},
{-1},
-#line 34 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str155), -2*3600},
-#line 31 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str156), 11*3600},
-#line 147 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str157), -7200},
+#line 311 "zonetab.list"
+ {gperf_offsetof(stringpool, 273),21600},
+#line 66 "zonetab.list"
+ {gperf_offsetof(stringpool, 274),-10*3600},
+#line 151 "zonetab.list"
+ {gperf_offsetof(stringpool, 275), 20700},
+#line 267 "zonetab.list"
+ {gperf_offsetof(stringpool, 276),-39600},
+#line 225 "zonetab.list"
+ {gperf_offsetof(stringpool, 277),-14400},
+ {-1},
+#line 224 "zonetab.list"
+ {gperf_offsetof(stringpool, 279),-10800},
+#line 67 "zonetab.list"
+ {gperf_offsetof(stringpool, 280),-10*3600},
+#line 237 "zonetab.list"
+ {gperf_offsetof(stringpool, 281),10800},
{-1}, {-1},
-#line 172 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str160), -18000},
- {-1}, {-1}, {-1},
-#line 64 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str164),-10*3600},
+#line 297 "zonetab.list"
+ {gperf_offsetof(stringpool, 284),32400},
+#line 175 "zonetab.list"
+ {gperf_offsetof(stringpool, 285), 28800},
+#line 134 "zonetab.list"
+ {gperf_offsetof(stringpool, 286), 7200},
+#line 149 "zonetab.list"
+ {gperf_offsetof(stringpool, 287), 23400},
+#line 107 "zonetab.list"
+ {gperf_offsetof(stringpool, 288),13*3600},
+#line 230 "zonetab.list"
+ {gperf_offsetof(stringpool, 289),-10800},
+#line 307 "zonetab.list"
+ {gperf_offsetof(stringpool, 290),18000},
{-1}, {-1},
-#line 28 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str167), 8*3600},
-#line 137 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str168), 7200},
-#line 29 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str169), 9*3600},
#line 155 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str170), 25200},
-#line 150 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str171), 21600},
+ {gperf_offsetof(stringpool, 293), 25200},
+#line 258 "zonetab.list"
+ {gperf_offsetof(stringpool, 294),18000},
+#line 227 "zonetab.list"
+ {gperf_offsetof(stringpool, 295),-21600},
+#line 261 "zonetab.list"
+ {gperf_offsetof(stringpool, 296),43200},
+#line 213 "zonetab.list"
+ {gperf_offsetof(stringpool, 297),-3600},
#line 154 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str172), 28800},
+ {gperf_offsetof(stringpool, 298), 28800},
{-1},
-#line 161 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str174), -18000},
- {-1}, {-1},
-#line 166 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str177), 7200},
- {-1}, {-1}, {-1},
-#line 115 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str181), 36000},
-#line 113 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str182), -14400},
- {-1}, {-1}, {-1},
-#line 146 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str186), -21600},
+#line 243 "zonetab.list"
+ {gperf_offsetof(stringpool, 300),21600},
+#line 114 "zonetab.list"
+ {gperf_offsetof(stringpool, 301), 34200},
+#line 157 "zonetab.list"
+ {gperf_offsetof(stringpool, 302), -28800},
{-1},
-#line 148 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str188), -25200},
+#line 117 "zonetab.list"
+ {gperf_offsetof(stringpool, 304), -21600},
{-1},
-#line 127 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str190), 28800},
+#line 156 "zonetab.list"
+ {gperf_offsetof(stringpool, 306), -14400},
#line 116 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str191), -3600},
-#line 142 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str192), 19800},
+ {gperf_offsetof(stringpool, 307), -3600},
+#line 228 "zonetab.list"
+ {gperf_offsetof(stringpool, 308),-32400},
+#line 294 "zonetab.list"
+ {gperf_offsetof(stringpool, 309),18000},
+#line 37 "zonetab.list"
+ {gperf_offsetof(stringpool, 310), -5*3600},
+#line 137 "zonetab.list"
+ {gperf_offsetof(stringpool, 311), 7200},
+#line 58 "zonetab.list"
+ {gperf_offsetof(stringpool, 312),-8*3600},
+#line 304 "zonetab.list"
+ {gperf_offsetof(stringpool, 313),28800},
+#line 303 "zonetab.list"
+ {gperf_offsetof(stringpool, 314),32400},
+#line 284 "zonetab.list"
+ {gperf_offsetof(stringpool, 315),14400},
{-1},
-#line 40 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str194), -8*3600},
-#line 112 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str195), 10800},
-#line 139 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str196), 0},
-#line 152 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str197), 43200},
-#line 141 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str198), -36000},
-#line 27 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str199), 7*3600},
-#line 158 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str200), 3600},
+#line 295 "zonetab.list"
+ {gperf_offsetof(stringpool, 317),18000},
+ {-1},
+#line 166 "zonetab.list"
+ {gperf_offsetof(stringpool, 319), 7200},
+ {-1}, {-1}, {-1}, {-1},
+#line 97 "zonetab.list"
+ {gperf_offsetof(stringpool, 324), 8*3600},
+ {-1},
+#line 50 "zonetab.list"
+ {gperf_offsetof(stringpool, 326), -(2*3600+1800)},
+#line 285 "zonetab.list"
+ {gperf_offsetof(stringpool, 327),-10800},
{-1}, {-1},
-#line 110 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str203), 10800},
-#line 163 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str204), -39600},
-#line 41 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str205), -9*3600},
-#line 35 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str206), -3*3600},
-#line 12 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str207), 0*3600},
+#line 287 "zonetab.list"
+ {gperf_offsetof(stringpool, 330),14400},
+ {-1},
#line 169 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str208), 36000},
-#line 72 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str209), 1*3600},
+ {gperf_offsetof(stringpool, 332), 36000},
{-1},
-#line 153 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str211), -12600},
+#line 235 "zonetab.list"
+ {gperf_offsetof(stringpool, 334),25200},
+#line 234 "zonetab.list"
+ {gperf_offsetof(stringpool, 335),28800},
+ {-1}, {-1},
+#line 232 "zonetab.list"
+ {gperf_offsetof(stringpool, 338),-14400},
+ {-1}, {-1}, {-1},
+#line 44 "zonetab.list"
+ {gperf_offsetof(stringpool, 342), -12*3600},
+#line 61 "zonetab.list"
+ {gperf_offsetof(stringpool, 343),-9*3600},
+#line 162 "zonetab.list"
+ {gperf_offsetof(stringpool, 344), -14400},
+#line 141 "zonetab.list"
+ {gperf_offsetof(stringpool, 345), -36000},
+ {-1},
+#line 306 "zonetab.list"
+ {gperf_offsetof(stringpool, 347),-10800},
+ {-1},
+#line 305 "zonetab.list"
+ {gperf_offsetof(stringpool, 349),-7200},
+#line 326 "zonetab.list"
+ {gperf_offsetof(stringpool, 350),18000},
+#line 325 "zonetab.list"
+ {gperf_offsetof(stringpool, 351),21600},
+#line 247 "zonetab.list"
+ {gperf_offsetof(stringpool, 352),14400},
+#line 323 "zonetab.list"
+ {gperf_offsetof(stringpool, 353),32400},
+#line 322 "zonetab.list"
+ {gperf_offsetof(stringpool, 354),36000},
+ {-1}, {-1}, {-1},
+#line 63 "zonetab.list"
+ {gperf_offsetof(stringpool, 358), -9*3600},
+#line 144 "zonetab.list"
+ {gperf_offsetof(stringpool, 359), 7200},
{-1}, {-1}, {-1}, {-1}, {-1},
-#line 151 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str217), 20700},
-#line 114 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str218), 34200},
+#line 167 "zonetab.list"
+ {gperf_offsetof(stringpool, 365), 21600},
+ {-1},
+#line 180 "zonetab.list"
+ {gperf_offsetof(stringpool, 367), 32400},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 318 "zonetab.list"
+ {gperf_offsetof(stringpool, 375),25200},
+ {-1},
+#line 115 "zonetab.list"
+ {gperf_offsetof(stringpool, 377), 36000},
+#line 231 "zonetab.list"
+ {gperf_offsetof(stringpool, 378),43200},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 173 "zonetab.list"
+ {gperf_offsetof(stringpool, 387), -25200},
+ {-1}, {-1}, {-1},
+#line 310 "zonetab.list"
+ {gperf_offsetof(stringpool, 391),36000},
+#line 309 "zonetab.list"
+ {gperf_offsetof(stringpool, 392),39600},
{-1}, {-1},
#line 140 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str221), 7200},
- {-1},
-#line 174 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str223), 36000},
+ {gperf_offsetof(stringpool, 395), 7200},
+ {-1}, {-1},
+#line 168 "zonetab.list"
+ {gperf_offsetof(stringpool, 398), 28800},
+#line 290 "zonetab.list"
+ {gperf_offsetof(stringpool, 399),39600},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 118 "zonetab.list"
+ {gperf_offsetof(stringpool, 408), -3600},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 296 "zonetab.list"
+ {gperf_offsetof(stringpool, 417),46800},
+#line 163 "zonetab.list"
+ {gperf_offsetof(stringpool, 418), -39600},
+ {-1}, {-1},
+#line 161 "zonetab.list"
+ {gperf_offsetof(stringpool, 421), -18000},
{-1}, {-1}, {-1}, {-1}, {-1},
-#line 46 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str229), 0*3600},
+#line 312 "zonetab.list"
+ {gperf_offsetof(stringpool, 427),39600},
+#line 69 "zonetab.list"
+ {gperf_offsetof(stringpool, 428),-12*3600},
{-1}, {-1}, {-1},
-#line 135 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str233), 18000},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
-#line 173 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str265), -25200},
+#line 136 "zonetab.list"
+ {gperf_offsetof(stringpool, 432), 43200},
+ {-1}, {-1},
+#line 46 "zonetab.list"
+ {gperf_offsetof(stringpool, 435), 0*3600},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 145 "zonetab.list"
+ {gperf_offsetof(stringpool, 443), 32400},
+ {-1},
+#line 131 "zonetab.list"
+ {gperf_offsetof(stringpool, 445), 7200},
{-1}, {-1}, {-1},
-#line 144 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str269), 7200},
+#line 292 "zonetab.list"
+ {gperf_offsetof(stringpool, 449),10800},
{-1}, {-1},
-#line 180 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str272), 32400},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#line 156 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str279), -14400},
+#line 150 "zonetab.list"
+ {gperf_offsetof(stringpool, 452), 21600},
{-1}, {-1},
-#line 171 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str282), 46800},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1},
-#line 108 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str314), 16200},
+#line 302 "zonetab.list"
+ {gperf_offsetof(stringpool, 455),43200},
+ {-1}, {-1},
+#line 176 "zonetab.list"
+ {gperf_offsetof(stringpool, 458), 3600},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 135 "zonetab.list"
+ {gperf_offsetof(stringpool, 466), 18000},
+ {-1},
+#line 174 "zonetab.list"
+ {gperf_offsetof(stringpool, 468), 36000},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 324 "zonetab.list"
+ {gperf_offsetof(stringpool, 476),36000},
+#line 172 "zonetab.list"
+ {gperf_offsetof(stringpool, 477), -18000},
{-1}, {-1}, {-1}, {-1},
-#line 69 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str319),-12*3600},
+#line 160 "zonetab.list"
+ {gperf_offsetof(stringpool, 482), -10800},
{-1}, {-1},
-#line 157 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str322), -28800},
+#line 62 "zonetab.list"
+ {gperf_offsetof(stringpool, 485), -9*3600},
+#line 159 "zonetab.list"
+ {gperf_offsetof(stringpool, 486), 10800},
+ {-1}, {-1}, {-1}, {-1}, {-1},
+#line 233 "zonetab.list"
+ {gperf_offsetof(stringpool, 492),28800},
{-1}, {-1}, {-1}, {-1},
-#line 168 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str327), 28800},
-#line 134 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str328), 7200},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 158 "zonetab.list"
+ {gperf_offsetof(stringpool, 497), 3600},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 177 "zonetab.list"
+ {gperf_offsetof(stringpool, 540), 3600},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#line 170 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str392), 32400},
+ {-1}, {-1}, {-1}, {-1},
+#line 59 "zonetab.list"
+ {gperf_offsetof(stringpool, 563), -8*3600},
+ {-1}, {-1},
+#line 104 "zonetab.list"
+ {gperf_offsetof(stringpool, 566),12*3600},
+#line 139 "zonetab.list"
+ {gperf_offsetof(stringpool, 567), 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},
-#line 136 "zonetab.list"
- {offsetof(struct stringpool_t, stringpool_str438), 43200}
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 138 "zonetab.list"
+ {gperf_offsetof(stringpool, 619), -10800}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = hash (str, len);
+ register unsigned int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register int o = wordlist[key].name;
if (o >= 0)
{
register const char *s = o + stringpool;
- if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0')
return &wordlist[key];
}
}
}
return 0;
}
-#line 181 "zonetab.list"
+#line 327 "zonetab.list"
diff --git a/ext/date/zonetab.list b/ext/date/zonetab.list
index 3a4d121d2e..d2f902d2d5 100644
--- a/ext/date/zonetab.list
+++ b/ext/date/zonetab.list
@@ -47,12 +47,12 @@ utc, 0*3600
wet, 0*3600
at, -2*3600
brst,-2*3600
-ndt, -(2*3600+1800)
+ndt, -(1*3600+1800)
art, -3*3600
adt, -3*3600
brt, -3*3600
clst,-3*3600
-nst, -(3*3600+1800)
+nst, -(2*3600+1800)
ast, -4*3600
clt, -4*3600
akdt,-8*3600
@@ -62,7 +62,7 @@ hadt,-9*3600
hdt, -9*3600
yst, -9*3600
ahst,-10*3600
-cat,-10*3600
+cat,2*3600
hast,-10*3600
hst,-10*3600
nt, -11*3600
@@ -82,7 +82,7 @@ fst, 2*3600
mest, 2*3600
mesz, 2*3600
sast, 2*3600
-sst, 2*3600
+sst, -11*3600
bt, 3*3600
eat, 3*3600
eest, 3*3600
@@ -92,13 +92,13 @@ zp4, 4*3600
zp5, 5*3600
ist, (5*3600+1800)
zp6, 6*3600
-wast, 7*3600
-cct, 8*3600
+wast, 2*3600
+cct, (6*3600+1800)
sgt, 8*3600
wadt, 8*3600
jst, 9*3600
kst, 9*3600
-east,10*3600
+east,-6*3600
gst, 10*3600
eadt,11*3600
idle,12*3600
@@ -178,4 +178,150 @@ w. europe, 3600
west asia, 18000
west pacific, 36000
yakutsk, 32400
+acdt,37800
+acst,34200
+act,-18000
+acwst,31500
+aedt,39600
+aest,36000
+aft,16200
+almt,21600
+anast,43200
+anat,43200
+aoe,-43200
+aqtt,18000
+awdt,32400
+awst,28800
+azost,0
+azot,-3600
+azst,18000
+azt,14400
+bnt,28800
+bot,-14400
+btt,21600
+cast,28800
+chadt,49500
+chast,45900
+chost,32400
+chot,28800
+chst,36000
+chut,36000
+cidst,-14400
+cist,-18000
+ckt,-36000
+cot,-18000
+cvt,-3600
+cxt,25200
+davt,25200
+ddut,36000
+easst,-18000
+ect,-18000
+egst,0
+egt,-3600
+fet,10800
+fjst,46800
+fjt,43200
+fkst,-10800
+fkt,-14400
+fnt,-7200
+galt,-21600
+gamt,-32400
+get,14400
+gft,-10800
+gilt,43200
+gyt,-14400
+hkt,28800
+hovst,28800
+hovt,25200
+ict,25200
+idt,10800
+iot,21600
+irdt,16200
+irkst,32400
+irkt,28800
+irst,12600
+kgt,21600
+kost,39600
+krast,28800
+krat,25200
+kuyt,14400
+lhdt,39600
+lhst,37800
+lint,50400
+magst,43200
+magt,39600
+mart,-30600
+mawt,18000
+mht,43200
+mmt,23400
+mut,14400
+mvt,18000
+myt,28800
+nct,39600
+nfdt,43200
+nft,39600
+novst,25200
+novt,25200
+npt,20700
+nrt,43200
+nut,-39600
+omsst,25200
+omst,21600
+orat,18000
+pet,-18000
+petst,43200
+pett,43200
+pgt,36000
+phot,46800
+pht,28800
+pkt,18000
+pmdt,-7200
+pmst,-10800
+pont,39600
+pwt,32400
+pyst,-10800
+qyzt,21600
+ret,14400
+rott,-10800
+sakt,39600
+samt,14400
+sbt,39600
+sct,14400
+sret,39600
+srt,-10800
+syot,10800
+taht,-36000
+tft,18000
+tjt,18000
+tkt,46800
+tlt,32400
+tmt,18000
+tost,50400
+tot,46800
+trt,10800
+tvt,43200
+ulast,32400
+ulat,28800
+uyst,-7200
+uyt,-10800
+uzt,18000
+vet,-14400
+vlast,39600
+vlat,36000
+vost,21600
+vut,39600
+wakt,43200
+warst,-10800
+wft,43200
+wgst,-7200
+wgt,-10800
+wib,25200
+wit,32400
+wita,28800
+wt,0
+yakst,36000
+yakt,32400
+yapt,36000
+yekst,21600
+yekt,18000
%%
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index fec06a0dac..de7536651c 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -39,6 +39,8 @@ struct dbmdata {
DBM *di_dbm;
};
+NORETURN(static void closed_dbm(void));
+
static void
closed_dbm(void)
{
@@ -47,7 +49,6 @@ closed_dbm(void)
#define GetDBM(obj, dbmp) do {\
TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\
- if ((dbmp) == 0) closed_dbm();\
if ((dbmp)->di_dbm == 0) closed_dbm();\
} while (0)
@@ -60,21 +61,18 @@ static void
free_dbm(void *ptr)
{
struct dbmdata *dbmp = ptr;
- if (dbmp) {
- if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
- xfree(dbmp);
- }
+ if (dbmp->di_dbm)
+ dbm_close(dbmp->di_dbm);
+ xfree(dbmp);
}
static size_t
memsize_dbm(const void *ptr)
{
- size_t size = 0;
const struct dbmdata *dbmp = ptr;
- if (dbmp) {
- size += sizeof(*dbmp);
- if (dbmp->di_dbm) size += DBM_SIZEOF_DBM;
- }
+ size_t size = sizeof(*dbmp);
+ if (dbmp->di_dbm)
+ size += DBM_SIZEOF_DBM;
return size;
}
@@ -115,8 +113,6 @@ fdbm_closed(VALUE obj)
struct dbmdata *dbmp;
TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
- if (dbmp == 0)
- return Qtrue;
if (dbmp->di_dbm == 0)
return Qtrue;
@@ -126,7 +122,9 @@ fdbm_closed(VALUE obj)
static VALUE
fdbm_alloc(VALUE klass)
{
- return TypedData_Wrap_Struct(klass, &dbm_type, 0);
+ struct dbmdata *dbmp;
+
+ return TypedData_Make_Struct(klass, struct dbmdata, &dbm_type, dbmp);
}
/*
@@ -150,6 +148,7 @@ fdbm_initialize(int argc, VALUE *argv, VALUE obj)
struct dbmdata *dbmp;
int mode, flags = 0;
+ TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
mode = 0666; /* default value */
}
@@ -228,8 +227,8 @@ fdbm_initialize(int argc, VALUE *argv, VALUE obj)
rb_sys_fail_str(file);
}
- dbmp = ALLOC(struct dbmdata);
- DATA_PTR(obj) = dbmp;
+ if (dbmp->di_dbm)
+ dbm_close(dbmp->di_dbm);
dbmp->di_dbm = dbm;
dbmp->di_size = -1;
@@ -280,12 +279,11 @@ fdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
not_found:
if (NIL_P(ifnone) && rb_block_given_p()) {
keystr = rb_str_dup(keystr);
- OBJ_TAINT(keystr);
return rb_yield(keystr);
}
return ifnone;
}
- return rb_tainted_str_new(value.dptr, value.dsize);
+ return rb_str_new(value.dptr, value.dsize);
}
/*
@@ -345,7 +343,7 @@ fdbm_key(VALUE obj, VALUE valstr)
val = dbm_fetch(dbm, key);
if ((long)val.dsize == RSTRING_LEN(valstr) &&
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0) {
- return rb_tainted_str_new(key.dptr, key.dsize);
+ return rb_str_new(key.dptr, key.dsize);
}
}
return Qnil;
@@ -378,8 +376,8 @@ fdbm_select(VALUE obj)
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
VALUE assoc, v;
val = dbm_fetch(dbm, key);
- assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
- rb_tainted_str_new(val.dptr, val.dsize));
+ assoc = rb_assoc_new(rb_str_new(key.dptr, key.dsize),
+ rb_str_new(val.dptr, val.dsize));
v = rb_yield(assoc);
if (RTEST(v)) {
rb_ary_push(new, assoc);
@@ -447,7 +445,7 @@ fdbm_delete(VALUE obj, VALUE keystr)
}
/* need to save value before dbm_delete() */
- valstr = rb_tainted_str_new(value.dptr, value.dsize);
+ valstr = rb_str_new(value.dptr, value.dsize);
if (dbm_delete(dbm, key)) {
dbmp->di_size = -1;
@@ -482,8 +480,8 @@ fdbm_shift(VALUE obj)
key = dbm_firstkey(dbm);
if (!key.dptr) return Qnil;
val = dbm_fetch(dbm, key);
- keystr = rb_tainted_str_new(key.dptr, key.dsize);
- valstr = rb_tainted_str_new(val.dptr, val.dsize);
+ keystr = rb_str_new(key.dptr, key.dsize);
+ valstr = rb_str_new(val.dptr, val.dsize);
dbm_delete(dbm, key);
return rb_assoc_new(keystr, valstr);
@@ -515,9 +513,9 @@ fdbm_delete_if(VALUE obj)
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- keystr = rb_tainted_str_new(key.dptr, key.dsize);
+ keystr = rb_str_new(key.dptr, key.dsize);
OBJ_FREEZE(keystr);
- valstr = rb_tainted_str_new(val.dptr, val.dsize);
+ valstr = rb_str_new(val.dptr, val.dsize);
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
if (status != 0) break;
if (RTEST(ret)) rb_ary_push(ary, keystr);
@@ -584,8 +582,8 @@ fdbm_invert(VALUE obj)
GetDBM2(obj, dbmp, dbm);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- keystr = rb_tainted_str_new(key.dptr, key.dsize);
- valstr = rb_tainted_str_new(val.dptr, val.dsize);
+ keystr = rb_str_new(key.dptr, key.dsize);
+ valstr = rb_str_new(val.dptr, val.dsize);
rb_hash_aset(hash, valstr, keystr);
}
return hash;
@@ -745,7 +743,7 @@ fdbm_each_value(VALUE obj)
GetDBM2(obj, dbmp, dbm);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
+ rb_yield(rb_str_new(val.dptr, val.dsize));
GetDBM2(obj, dbmp, dbm);
}
return obj;
@@ -768,7 +766,7 @@ fdbm_each_key(VALUE obj)
GetDBM2(obj, dbmp, dbm);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
- rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
+ rb_yield(rb_str_new(key.dptr, key.dsize));
GetDBM2(obj, dbmp, dbm);
}
return obj;
@@ -795,8 +793,8 @@ fdbm_each_pair(VALUE obj)
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- keystr = rb_tainted_str_new(key.dptr, key.dsize);
- valstr = rb_tainted_str_new(val.dptr, val.dsize);
+ keystr = rb_str_new(key.dptr, key.dsize);
+ valstr = rb_str_new(val.dptr, val.dsize);
rb_yield(rb_assoc_new(keystr, valstr));
GetDBM2(obj, dbmp, dbm);
}
@@ -822,7 +820,7 @@ fdbm_keys(VALUE obj)
ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
- rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
+ rb_ary_push(ary, rb_str_new(key.dptr, key.dsize));
}
return ary;
@@ -846,7 +844,7 @@ fdbm_values(VALUE obj)
ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
+ rb_ary_push(ary, rb_str_new(val.dptr, val.dsize));
}
return ary;
@@ -932,8 +930,8 @@ fdbm_to_a(VALUE obj)
ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
- rb_tainted_str_new(val.dptr, val.dsize)));
+ rb_ary_push(ary, rb_assoc_new(rb_str_new(key.dptr, key.dsize),
+ rb_str_new(val.dptr, val.dsize)));
}
return ary;
@@ -958,8 +956,8 @@ fdbm_to_hash(VALUE obj)
hash = rb_hash_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
- rb_tainted_str_new(val.dptr, val.dsize));
+ rb_hash_aset(hash, rb_str_new(key.dptr, key.dsize),
+ rb_str_new(val.dptr, val.dsize));
}
return hash;
@@ -982,7 +980,7 @@ fdbm_reject(VALUE obj)
* == Introduction
*
* The DBM class provides a wrapper to a Unix-style
- * {dbm}[http://en.wikipedia.org/wiki/Dbm] or Database Manager library.
+ * {dbm}[https://en.wikipedia.org/wiki/Dbm] or Database Manager library.
*
* Dbm databases do not have tables or columns; they are simple key-value
* data stores, like a Ruby Hash except not resident in RAM. Keys and values
@@ -994,8 +992,8 @@ fdbm_reject(VALUE obj)
* - The original ndbm library is released in 4.3BSD.
* It is based on dbm library in Unix Version 7 but has different API to
* support multiple databases in a process.
- * - {Berkeley DB}[http://en.wikipedia.org/wiki/Berkeley_DB] versions
- * 1 thru 5, also known as BDB and Sleepycat DB, now owned by Oracle
+ * - {Berkeley DB}[https://en.wikipedia.org/wiki/Berkeley_DB] versions
+ * 1 thru 6, also known as BDB and Sleepycat DB, now owned by Oracle
* Corporation.
* - Berkeley DB 1.x, still found in 4.4BSD derivatives (FreeBSD, OpenBSD, etc).
* - {gdbm}[http://www.gnu.org/software/gdbm/], the GNU implementation of dbm.
diff --git a/ext/dbm/dbm.gemspec b/ext/dbm/dbm.gemspec
index 235466380b..0ff036f712 100644
--- a/ext/dbm/dbm.gemspec
+++ b/ext/dbm/dbm.gemspec
@@ -1,21 +1,21 @@
# frozen_string_literal: true
Gem::Specification.new do |s|
s.name = "dbm"
- s.version = '1.0.0.beta1'
- s.date = '2017-02-08'
+ s.version = '1.1.0'
s.summary = "Provides a wrapper for the UNIX-style Database Manager Library"
s.description = "Provides a wrapper for the UNIX-style Database Manager Library"
s.require_path = %w{lib}
s.files = %w{ext/dbm/extconf.rb ext/dbm/dbm.c}
s.extensions = %w{ext/dbm/extconf.rb}
- s.required_ruby_version = ">= 2.5.0dev"
+ s.required_ruby_version = ">= 2.3.0"
s.authors = ["Yukihiro Matsumoto"]
s.email = ["matz@ruby-lang.org"]
s.homepage = "https://github.com/ruby/dbm"
- s.license = "BSD-2-Clause"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
s.add_development_dependency "rake-compiler"
s.add_development_dependency "test-unit"
+ s.metadata["msys2_mingw_dependencies"] = "gdbm"
end
diff --git a/ext/dbm/depend b/ext/dbm/depend
index b0de2ae2ee..414bb58a0e 100644
--- a/ext/dbm/depend
+++ b/ext/dbm/depend
@@ -1,13 +1,163 @@
# AUTOGENERATED DEPENDENCIES START
dbm.o: $(RUBY_EXTCONF_H)
dbm.o: $(arch_hdrdir)/ruby/config.h
+dbm.o: $(hdrdir)/ruby.h
+dbm.o: $(hdrdir)/ruby/internal/anyargs.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+dbm.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+dbm.o: $(hdrdir)/ruby/internal/assume.h
+dbm.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+dbm.o: $(hdrdir)/ruby/internal/attr/artificial.h
+dbm.o: $(hdrdir)/ruby/internal/attr/cold.h
+dbm.o: $(hdrdir)/ruby/internal/attr/const.h
+dbm.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+dbm.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+dbm.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+dbm.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+dbm.o: $(hdrdir)/ruby/internal/attr/error.h
+dbm.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+dbm.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+dbm.o: $(hdrdir)/ruby/internal/attr/format.h
+dbm.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+dbm.o: $(hdrdir)/ruby/internal/attr/noalias.h
+dbm.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+dbm.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+dbm.o: $(hdrdir)/ruby/internal/attr/noinline.h
+dbm.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+dbm.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+dbm.o: $(hdrdir)/ruby/internal/attr/pure.h
+dbm.o: $(hdrdir)/ruby/internal/attr/restrict.h
+dbm.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+dbm.o: $(hdrdir)/ruby/internal/attr/warning.h
+dbm.o: $(hdrdir)/ruby/internal/attr/weakref.h
+dbm.o: $(hdrdir)/ruby/internal/cast.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_is.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+dbm.o: $(hdrdir)/ruby/internal/compiler_since.h
+dbm.o: $(hdrdir)/ruby/internal/config.h
+dbm.o: $(hdrdir)/ruby/internal/constant_p.h
+dbm.o: $(hdrdir)/ruby/internal/core.h
+dbm.o: $(hdrdir)/ruby/internal/core/rarray.h
+dbm.o: $(hdrdir)/ruby/internal/core/rbasic.h
+dbm.o: $(hdrdir)/ruby/internal/core/rbignum.h
+dbm.o: $(hdrdir)/ruby/internal/core/rclass.h
+dbm.o: $(hdrdir)/ruby/internal/core/rdata.h
+dbm.o: $(hdrdir)/ruby/internal/core/rfile.h
+dbm.o: $(hdrdir)/ruby/internal/core/rhash.h
+dbm.o: $(hdrdir)/ruby/internal/core/robject.h
+dbm.o: $(hdrdir)/ruby/internal/core/rregexp.h
+dbm.o: $(hdrdir)/ruby/internal/core/rstring.h
+dbm.o: $(hdrdir)/ruby/internal/core/rstruct.h
+dbm.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+dbm.o: $(hdrdir)/ruby/internal/ctype.h
+dbm.o: $(hdrdir)/ruby/internal/dllexport.h
+dbm.o: $(hdrdir)/ruby/internal/dosish.h
+dbm.o: $(hdrdir)/ruby/internal/error.h
+dbm.o: $(hdrdir)/ruby/internal/eval.h
+dbm.o: $(hdrdir)/ruby/internal/event.h
+dbm.o: $(hdrdir)/ruby/internal/fl_type.h
+dbm.o: $(hdrdir)/ruby/internal/gc.h
+dbm.o: $(hdrdir)/ruby/internal/glob.h
+dbm.o: $(hdrdir)/ruby/internal/globals.h
+dbm.o: $(hdrdir)/ruby/internal/has/attribute.h
+dbm.o: $(hdrdir)/ruby/internal/has/builtin.h
+dbm.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+dbm.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+dbm.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+dbm.o: $(hdrdir)/ruby/internal/has/extension.h
+dbm.o: $(hdrdir)/ruby/internal/has/feature.h
+dbm.o: $(hdrdir)/ruby/internal/has/warning.h
+dbm.o: $(hdrdir)/ruby/internal/intern/array.h
+dbm.o: $(hdrdir)/ruby/internal/intern/bignum.h
+dbm.o: $(hdrdir)/ruby/internal/intern/class.h
+dbm.o: $(hdrdir)/ruby/internal/intern/compar.h
+dbm.o: $(hdrdir)/ruby/internal/intern/complex.h
+dbm.o: $(hdrdir)/ruby/internal/intern/cont.h
+dbm.o: $(hdrdir)/ruby/internal/intern/dir.h
+dbm.o: $(hdrdir)/ruby/internal/intern/enum.h
+dbm.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+dbm.o: $(hdrdir)/ruby/internal/intern/error.h
+dbm.o: $(hdrdir)/ruby/internal/intern/eval.h
+dbm.o: $(hdrdir)/ruby/internal/intern/file.h
+dbm.o: $(hdrdir)/ruby/internal/intern/gc.h
+dbm.o: $(hdrdir)/ruby/internal/intern/hash.h
+dbm.o: $(hdrdir)/ruby/internal/intern/io.h
+dbm.o: $(hdrdir)/ruby/internal/intern/load.h
+dbm.o: $(hdrdir)/ruby/internal/intern/marshal.h
+dbm.o: $(hdrdir)/ruby/internal/intern/numeric.h
+dbm.o: $(hdrdir)/ruby/internal/intern/object.h
+dbm.o: $(hdrdir)/ruby/internal/intern/parse.h
+dbm.o: $(hdrdir)/ruby/internal/intern/proc.h
+dbm.o: $(hdrdir)/ruby/internal/intern/process.h
+dbm.o: $(hdrdir)/ruby/internal/intern/random.h
+dbm.o: $(hdrdir)/ruby/internal/intern/range.h
+dbm.o: $(hdrdir)/ruby/internal/intern/rational.h
+dbm.o: $(hdrdir)/ruby/internal/intern/re.h
+dbm.o: $(hdrdir)/ruby/internal/intern/ruby.h
+dbm.o: $(hdrdir)/ruby/internal/intern/select.h
+dbm.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+dbm.o: $(hdrdir)/ruby/internal/intern/signal.h
+dbm.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+dbm.o: $(hdrdir)/ruby/internal/intern/string.h
+dbm.o: $(hdrdir)/ruby/internal/intern/struct.h
+dbm.o: $(hdrdir)/ruby/internal/intern/thread.h
+dbm.o: $(hdrdir)/ruby/internal/intern/time.h
+dbm.o: $(hdrdir)/ruby/internal/intern/variable.h
+dbm.o: $(hdrdir)/ruby/internal/intern/vm.h
+dbm.o: $(hdrdir)/ruby/internal/interpreter.h
+dbm.o: $(hdrdir)/ruby/internal/iterator.h
+dbm.o: $(hdrdir)/ruby/internal/memory.h
+dbm.o: $(hdrdir)/ruby/internal/method.h
+dbm.o: $(hdrdir)/ruby/internal/module.h
+dbm.o: $(hdrdir)/ruby/internal/newobj.h
+dbm.o: $(hdrdir)/ruby/internal/rgengc.h
+dbm.o: $(hdrdir)/ruby/internal/scan_args.h
+dbm.o: $(hdrdir)/ruby/internal/special_consts.h
+dbm.o: $(hdrdir)/ruby/internal/static_assert.h
+dbm.o: $(hdrdir)/ruby/internal/stdalign.h
+dbm.o: $(hdrdir)/ruby/internal/stdbool.h
+dbm.o: $(hdrdir)/ruby/internal/symbol.h
+dbm.o: $(hdrdir)/ruby/internal/token_paste.h
+dbm.o: $(hdrdir)/ruby/internal/value.h
+dbm.o: $(hdrdir)/ruby/internal/value_type.h
+dbm.o: $(hdrdir)/ruby/internal/variable.h
+dbm.o: $(hdrdir)/ruby/internal/warning_push.h
+dbm.o: $(hdrdir)/ruby/internal/xmalloc.h
+dbm.o: $(hdrdir)/ruby/assert.h
dbm.o: $(hdrdir)/ruby/backward.h
+dbm.o: $(hdrdir)/ruby/backward/2/assume.h
+dbm.o: $(hdrdir)/ruby/backward/2/attributes.h
+dbm.o: $(hdrdir)/ruby/backward/2/bool.h
+dbm.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+dbm.o: $(hdrdir)/ruby/backward/2/inttypes.h
+dbm.o: $(hdrdir)/ruby/backward/2/limits.h
+dbm.o: $(hdrdir)/ruby/backward/2/long_long.h
+dbm.o: $(hdrdir)/ruby/backward/2/stdalign.h
+dbm.o: $(hdrdir)/ruby/backward/2/stdarg.h
dbm.o: $(hdrdir)/ruby/defines.h
dbm.o: $(hdrdir)/ruby/intern.h
dbm.o: $(hdrdir)/ruby/missing.h
dbm.o: $(hdrdir)/ruby/ruby.h
dbm.o: $(hdrdir)/ruby/st.h
dbm.o: $(hdrdir)/ruby/subst.h
-dbm.o: $(top_srcdir)/include/ruby.h
dbm.o: dbm.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/dbm/extconf.rb b/ext/dbm/extconf.rb
index 514aa3f8b0..c9a5518bf6 100644
--- a/ext/dbm/extconf.rb
+++ b/ext/dbm/extconf.rb
@@ -7,6 +7,7 @@
# db Berkeley DB (libdb)
# db2 Berkeley DB (libdb2)
# db1 Berkeley DB (libdb1)
+# db6 Berkeley DB (libdb6)
# db5 Berkeley DB (libdb5)
# db4 Berkeley DB (libdb4)
# db3 Berkeley DB (libdb3)
@@ -23,7 +24,7 @@ dir_config("dbm")
if dblib = with_config("dbm-type", nil)
dblib = dblib.split(/[ ,]+/)
else
- dblib = %w(libc db db2 db1 db5 db4 db3 gdbm_compat gdbm qdbm)
+ dblib = %w(libc db db2 db1 db6 db5 db4 db3 gdbm_compat gdbm qdbm)
end
headers = {
@@ -34,6 +35,7 @@ headers = {
"db3" => ["db3/db.h", "db3.h", "db.h"],
"db4" => ["db4/db.h", "db4.h", "db.h"],
"db5" => ["db5/db.h", "db5.h", "db.h"],
+ "db6" => ["db6/db.h", "db6.h", "db.h"],
"gdbm_compat" => ["gdbm-ndbm.h", "gdbm/ndbm.h", "ndbm.h"], # GDBM since 1.8.1
"gdbm" => ["gdbm-ndbm.h", "gdbm/ndbm.h", "ndbm.h"], # GDBM until 1.8.0
"qdbm" => ["qdbm/relic.h", "relic.h"],
@@ -131,7 +133,7 @@ def headers.db_check2(db, hdr)
hsearch = nil
case db
- when /^db[2-5]?$/
+ when /^db[2-6]?$/
hsearch = "-DDB_DBM_HSEARCH"
when "gdbm_compat"
have_library("gdbm") or return false
diff --git a/ext/digest/bubblebabble/bubblebabble.c b/ext/digest/bubblebabble/bubblebabble.c
index 8f436908d3..6557e43c9d 100644
--- a/ext/digest/bubblebabble/bubblebabble.c
+++ b/ext/digest/bubblebabble/bubblebabble.c
@@ -124,6 +124,7 @@ rb_digest_instance_bubblebabble(VALUE self)
void
Init_bubblebabble(void)
{
+#undef rb_intern
VALUE rb_mDigest, rb_mDigest_Instance, rb_cDigest_Class;
rb_require("digest");
diff --git a/ext/digest/bubblebabble/depend b/ext/digest/bubblebabble/depend
index c0550f3180..6dcd5fe55c 100644
--- a/ext/digest/bubblebabble/depend
+++ b/ext/digest/bubblebabble/depend
@@ -1,14 +1,164 @@
# AUTOGENERATED DEPENDENCIES START
bubblebabble.o: $(RUBY_EXTCONF_H)
bubblebabble.o: $(arch_hdrdir)/ruby/config.h
+bubblebabble.o: $(hdrdir)/ruby.h
+bubblebabble.o: $(hdrdir)/ruby/internal/anyargs.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+bubblebabble.o: $(hdrdir)/ruby/internal/assume.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/artificial.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/cold.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/const.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/error.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/format.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/noalias.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/noinline.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/pure.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/restrict.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/warning.h
+bubblebabble.o: $(hdrdir)/ruby/internal/attr/weakref.h
+bubblebabble.o: $(hdrdir)/ruby/internal/cast.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_is.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+bubblebabble.o: $(hdrdir)/ruby/internal/compiler_since.h
+bubblebabble.o: $(hdrdir)/ruby/internal/config.h
+bubblebabble.o: $(hdrdir)/ruby/internal/constant_p.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rarray.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rbasic.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rbignum.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rclass.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rdata.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rfile.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rhash.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/robject.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rregexp.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rstring.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rstruct.h
+bubblebabble.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+bubblebabble.o: $(hdrdir)/ruby/internal/ctype.h
+bubblebabble.o: $(hdrdir)/ruby/internal/dllexport.h
+bubblebabble.o: $(hdrdir)/ruby/internal/dosish.h
+bubblebabble.o: $(hdrdir)/ruby/internal/error.h
+bubblebabble.o: $(hdrdir)/ruby/internal/eval.h
+bubblebabble.o: $(hdrdir)/ruby/internal/event.h
+bubblebabble.o: $(hdrdir)/ruby/internal/fl_type.h
+bubblebabble.o: $(hdrdir)/ruby/internal/gc.h
+bubblebabble.o: $(hdrdir)/ruby/internal/glob.h
+bubblebabble.o: $(hdrdir)/ruby/internal/globals.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/attribute.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/builtin.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/extension.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/feature.h
+bubblebabble.o: $(hdrdir)/ruby/internal/has/warning.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/array.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/bignum.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/class.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/compar.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/complex.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/cont.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/dir.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/enum.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/error.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/eval.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/file.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/gc.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/hash.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/io.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/load.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/marshal.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/numeric.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/object.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/parse.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/proc.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/process.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/random.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/range.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/rational.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/re.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/ruby.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/select.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/signal.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/string.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/struct.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/thread.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/time.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/variable.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/vm.h
+bubblebabble.o: $(hdrdir)/ruby/internal/interpreter.h
+bubblebabble.o: $(hdrdir)/ruby/internal/iterator.h
+bubblebabble.o: $(hdrdir)/ruby/internal/memory.h
+bubblebabble.o: $(hdrdir)/ruby/internal/method.h
+bubblebabble.o: $(hdrdir)/ruby/internal/module.h
+bubblebabble.o: $(hdrdir)/ruby/internal/newobj.h
+bubblebabble.o: $(hdrdir)/ruby/internal/rgengc.h
+bubblebabble.o: $(hdrdir)/ruby/internal/scan_args.h
+bubblebabble.o: $(hdrdir)/ruby/internal/special_consts.h
+bubblebabble.o: $(hdrdir)/ruby/internal/static_assert.h
+bubblebabble.o: $(hdrdir)/ruby/internal/stdalign.h
+bubblebabble.o: $(hdrdir)/ruby/internal/stdbool.h
+bubblebabble.o: $(hdrdir)/ruby/internal/symbol.h
+bubblebabble.o: $(hdrdir)/ruby/internal/token_paste.h
+bubblebabble.o: $(hdrdir)/ruby/internal/value.h
+bubblebabble.o: $(hdrdir)/ruby/internal/value_type.h
+bubblebabble.o: $(hdrdir)/ruby/internal/variable.h
+bubblebabble.o: $(hdrdir)/ruby/internal/warning_push.h
+bubblebabble.o: $(hdrdir)/ruby/internal/xmalloc.h
+bubblebabble.o: $(hdrdir)/ruby/assert.h
bubblebabble.o: $(hdrdir)/ruby/backward.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/assume.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/attributes.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/bool.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/inttypes.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/limits.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/long_long.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/stdalign.h
+bubblebabble.o: $(hdrdir)/ruby/backward/2/stdarg.h
bubblebabble.o: $(hdrdir)/ruby/defines.h
bubblebabble.o: $(hdrdir)/ruby/intern.h
bubblebabble.o: $(hdrdir)/ruby/missing.h
bubblebabble.o: $(hdrdir)/ruby/ruby.h
bubblebabble.o: $(hdrdir)/ruby/st.h
bubblebabble.o: $(hdrdir)/ruby/subst.h
-bubblebabble.o: $(top_srcdir)/ext/digest/digest.h
-bubblebabble.o: $(top_srcdir)/include/ruby.h
+bubblebabble.o: $(srcdir)/../digest.h
bubblebabble.o: bubblebabble.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/digest/depend b/ext/digest/depend
index 8e3b4691e8..ac01d970dc 100644
--- a/ext/digest/depend
+++ b/ext/digest/depend
@@ -1,14 +1,164 @@
# AUTOGENERATED DEPENDENCIES START
digest.o: $(RUBY_EXTCONF_H)
digest.o: $(arch_hdrdir)/ruby/config.h
+digest.o: $(hdrdir)/ruby.h
+digest.o: $(hdrdir)/ruby/internal/anyargs.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+digest.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+digest.o: $(hdrdir)/ruby/internal/assume.h
+digest.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+digest.o: $(hdrdir)/ruby/internal/attr/artificial.h
+digest.o: $(hdrdir)/ruby/internal/attr/cold.h
+digest.o: $(hdrdir)/ruby/internal/attr/const.h
+digest.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+digest.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+digest.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+digest.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+digest.o: $(hdrdir)/ruby/internal/attr/error.h
+digest.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+digest.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+digest.o: $(hdrdir)/ruby/internal/attr/format.h
+digest.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+digest.o: $(hdrdir)/ruby/internal/attr/noalias.h
+digest.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+digest.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+digest.o: $(hdrdir)/ruby/internal/attr/noinline.h
+digest.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+digest.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+digest.o: $(hdrdir)/ruby/internal/attr/pure.h
+digest.o: $(hdrdir)/ruby/internal/attr/restrict.h
+digest.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+digest.o: $(hdrdir)/ruby/internal/attr/warning.h
+digest.o: $(hdrdir)/ruby/internal/attr/weakref.h
+digest.o: $(hdrdir)/ruby/internal/cast.h
+digest.o: $(hdrdir)/ruby/internal/compiler_is.h
+digest.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+digest.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+digest.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+digest.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+digest.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+digest.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+digest.o: $(hdrdir)/ruby/internal/compiler_since.h
+digest.o: $(hdrdir)/ruby/internal/config.h
+digest.o: $(hdrdir)/ruby/internal/constant_p.h
+digest.o: $(hdrdir)/ruby/internal/core.h
+digest.o: $(hdrdir)/ruby/internal/core/rarray.h
+digest.o: $(hdrdir)/ruby/internal/core/rbasic.h
+digest.o: $(hdrdir)/ruby/internal/core/rbignum.h
+digest.o: $(hdrdir)/ruby/internal/core/rclass.h
+digest.o: $(hdrdir)/ruby/internal/core/rdata.h
+digest.o: $(hdrdir)/ruby/internal/core/rfile.h
+digest.o: $(hdrdir)/ruby/internal/core/rhash.h
+digest.o: $(hdrdir)/ruby/internal/core/robject.h
+digest.o: $(hdrdir)/ruby/internal/core/rregexp.h
+digest.o: $(hdrdir)/ruby/internal/core/rstring.h
+digest.o: $(hdrdir)/ruby/internal/core/rstruct.h
+digest.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+digest.o: $(hdrdir)/ruby/internal/ctype.h
+digest.o: $(hdrdir)/ruby/internal/dllexport.h
+digest.o: $(hdrdir)/ruby/internal/dosish.h
+digest.o: $(hdrdir)/ruby/internal/error.h
+digest.o: $(hdrdir)/ruby/internal/eval.h
+digest.o: $(hdrdir)/ruby/internal/event.h
+digest.o: $(hdrdir)/ruby/internal/fl_type.h
+digest.o: $(hdrdir)/ruby/internal/gc.h
+digest.o: $(hdrdir)/ruby/internal/glob.h
+digest.o: $(hdrdir)/ruby/internal/globals.h
+digest.o: $(hdrdir)/ruby/internal/has/attribute.h
+digest.o: $(hdrdir)/ruby/internal/has/builtin.h
+digest.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+digest.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+digest.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+digest.o: $(hdrdir)/ruby/internal/has/extension.h
+digest.o: $(hdrdir)/ruby/internal/has/feature.h
+digest.o: $(hdrdir)/ruby/internal/has/warning.h
+digest.o: $(hdrdir)/ruby/internal/intern/array.h
+digest.o: $(hdrdir)/ruby/internal/intern/bignum.h
+digest.o: $(hdrdir)/ruby/internal/intern/class.h
+digest.o: $(hdrdir)/ruby/internal/intern/compar.h
+digest.o: $(hdrdir)/ruby/internal/intern/complex.h
+digest.o: $(hdrdir)/ruby/internal/intern/cont.h
+digest.o: $(hdrdir)/ruby/internal/intern/dir.h
+digest.o: $(hdrdir)/ruby/internal/intern/enum.h
+digest.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+digest.o: $(hdrdir)/ruby/internal/intern/error.h
+digest.o: $(hdrdir)/ruby/internal/intern/eval.h
+digest.o: $(hdrdir)/ruby/internal/intern/file.h
+digest.o: $(hdrdir)/ruby/internal/intern/gc.h
+digest.o: $(hdrdir)/ruby/internal/intern/hash.h
+digest.o: $(hdrdir)/ruby/internal/intern/io.h
+digest.o: $(hdrdir)/ruby/internal/intern/load.h
+digest.o: $(hdrdir)/ruby/internal/intern/marshal.h
+digest.o: $(hdrdir)/ruby/internal/intern/numeric.h
+digest.o: $(hdrdir)/ruby/internal/intern/object.h
+digest.o: $(hdrdir)/ruby/internal/intern/parse.h
+digest.o: $(hdrdir)/ruby/internal/intern/proc.h
+digest.o: $(hdrdir)/ruby/internal/intern/process.h
+digest.o: $(hdrdir)/ruby/internal/intern/random.h
+digest.o: $(hdrdir)/ruby/internal/intern/range.h
+digest.o: $(hdrdir)/ruby/internal/intern/rational.h
+digest.o: $(hdrdir)/ruby/internal/intern/re.h
+digest.o: $(hdrdir)/ruby/internal/intern/ruby.h
+digest.o: $(hdrdir)/ruby/internal/intern/select.h
+digest.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+digest.o: $(hdrdir)/ruby/internal/intern/signal.h
+digest.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+digest.o: $(hdrdir)/ruby/internal/intern/string.h
+digest.o: $(hdrdir)/ruby/internal/intern/struct.h
+digest.o: $(hdrdir)/ruby/internal/intern/thread.h
+digest.o: $(hdrdir)/ruby/internal/intern/time.h
+digest.o: $(hdrdir)/ruby/internal/intern/variable.h
+digest.o: $(hdrdir)/ruby/internal/intern/vm.h
+digest.o: $(hdrdir)/ruby/internal/interpreter.h
+digest.o: $(hdrdir)/ruby/internal/iterator.h
+digest.o: $(hdrdir)/ruby/internal/memory.h
+digest.o: $(hdrdir)/ruby/internal/method.h
+digest.o: $(hdrdir)/ruby/internal/module.h
+digest.o: $(hdrdir)/ruby/internal/newobj.h
+digest.o: $(hdrdir)/ruby/internal/rgengc.h
+digest.o: $(hdrdir)/ruby/internal/scan_args.h
+digest.o: $(hdrdir)/ruby/internal/special_consts.h
+digest.o: $(hdrdir)/ruby/internal/static_assert.h
+digest.o: $(hdrdir)/ruby/internal/stdalign.h
+digest.o: $(hdrdir)/ruby/internal/stdbool.h
+digest.o: $(hdrdir)/ruby/internal/symbol.h
+digest.o: $(hdrdir)/ruby/internal/token_paste.h
+digest.o: $(hdrdir)/ruby/internal/value.h
+digest.o: $(hdrdir)/ruby/internal/value_type.h
+digest.o: $(hdrdir)/ruby/internal/variable.h
+digest.o: $(hdrdir)/ruby/internal/warning_push.h
+digest.o: $(hdrdir)/ruby/internal/xmalloc.h
+digest.o: $(hdrdir)/ruby/assert.h
digest.o: $(hdrdir)/ruby/backward.h
+digest.o: $(hdrdir)/ruby/backward/2/assume.h
+digest.o: $(hdrdir)/ruby/backward/2/attributes.h
+digest.o: $(hdrdir)/ruby/backward/2/bool.h
+digest.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+digest.o: $(hdrdir)/ruby/backward/2/inttypes.h
+digest.o: $(hdrdir)/ruby/backward/2/limits.h
+digest.o: $(hdrdir)/ruby/backward/2/long_long.h
+digest.o: $(hdrdir)/ruby/backward/2/stdalign.h
+digest.o: $(hdrdir)/ruby/backward/2/stdarg.h
digest.o: $(hdrdir)/ruby/defines.h
digest.o: $(hdrdir)/ruby/intern.h
digest.o: $(hdrdir)/ruby/missing.h
digest.o: $(hdrdir)/ruby/ruby.h
digest.o: $(hdrdir)/ruby/st.h
digest.o: $(hdrdir)/ruby/subst.h
-digest.o: $(top_srcdir)/include/ruby.h
digest.o: digest.c
digest.o: digest.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/digest/digest.c b/ext/digest/digest.c
index 9838ed33de..83f4ee42fc 100644
--- a/ext/digest/digest.c
+++ b/ext/digest/digest.c
@@ -406,7 +406,7 @@ rb_digest_instance_digest_length(VALUE self)
/* never blindly assume that #digest() returns a string */
StringValue(digest);
- return INT2NUM(RSTRING_LEN(digest));
+ return LONG2NUM(RSTRING_LEN(digest));
}
/*
@@ -554,10 +554,22 @@ get_digest_base_metadata(VALUE klass)
if (NIL_P(p))
rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby");
+ if (!RB_TYPE_P(obj, T_DATA) || RTYPEDDATA_P(obj)) {
+ wrong:
+ if (p == klass)
+ rb_raise(rb_eTypeError, "%"PRIsVALUE"::metadata is not initialized properly",
+ klass);
+ else
+ rb_raise(rb_eTypeError, "%"PRIsVALUE"(%"PRIsVALUE")::metadata is not initialized properly",
+ klass, p);
+ }
+
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
Data_Get_Struct(obj, rb_digest_metadata_t, algo);
+ if (!algo) goto wrong;
+
switch (algo->api_version) {
case 3:
break;
@@ -573,6 +585,12 @@ get_digest_base_metadata(VALUE klass)
return algo;
}
+static rb_digest_metadata_t *
+get_digest_obj_metadata(VALUE obj)
+{
+ return get_digest_base_metadata(rb_obj_class(obj));
+}
+
static const rb_data_type_t digest_type = {
"digest",
{0, RUBY_TYPED_DEFAULT_FREE, 0,},
@@ -619,8 +637,8 @@ rb_digest_base_copy(VALUE copy, VALUE obj)
rb_check_frozen(copy);
- algo = get_digest_base_metadata(rb_obj_class(copy));
- if (algo != get_digest_base_metadata(rb_obj_class(obj)))
+ algo = get_digest_obj_metadata(copy);
+ if (algo != get_digest_obj_metadata(obj))
rb_raise(rb_eTypeError, "different algorithms");
TypedData_Get_Struct(obj, void, &digest_type, pctx1);
@@ -641,7 +659,7 @@ rb_digest_base_reset(VALUE self)
rb_digest_metadata_t *algo;
void *pctx;
- algo = get_digest_base_metadata(rb_obj_class(self));
+ algo = get_digest_obj_metadata(self);
TypedData_Get_Struct(self, void, &digest_type, pctx);
@@ -663,7 +681,7 @@ rb_digest_base_update(VALUE self, VALUE str)
rb_digest_metadata_t *algo;
void *pctx;
- algo = get_digest_base_metadata(rb_obj_class(self));
+ algo = get_digest_obj_metadata(self);
TypedData_Get_Struct(self, void, &digest_type, pctx);
@@ -682,7 +700,7 @@ rb_digest_base_finish(VALUE self)
void *pctx;
VALUE str;
- algo = get_digest_base_metadata(rb_obj_class(self));
+ algo = get_digest_obj_metadata(self);
TypedData_Get_Struct(self, void, &digest_type, pctx);
@@ -705,9 +723,9 @@ rb_digest_base_digest_length(VALUE self)
{
rb_digest_metadata_t *algo;
- algo = get_digest_base_metadata(rb_obj_class(self));
+ algo = get_digest_obj_metadata(self);
- return INT2NUM(algo->digest_len);
+ return SIZET2NUM(algo->digest_len);
}
/*
@@ -720,26 +738,37 @@ rb_digest_base_block_length(VALUE self)
{
rb_digest_metadata_t *algo;
- algo = get_digest_base_metadata(rb_obj_class(self));
+ algo = get_digest_obj_metadata(self);
- return INT2NUM(algo->block_len);
+ return SIZET2NUM(algo->block_len);
}
void
Init_digest(void)
{
+#undef rb_intern
id_reset = rb_intern("reset");
id_update = rb_intern("update");
id_finish = rb_intern("finish");
id_digest = rb_intern("digest");
id_hexdigest = rb_intern("hexdigest");
id_digest_length = rb_intern("digest_length");
+ id_metadata = rb_id_metadata();
+ InitVM(digest);
+}
+void
+InitVM_digest(void)
+{
/*
* module Digest
*/
rb_mDigest = rb_define_module("Digest");
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
/* module functions */
rb_define_module_function(rb_mDigest, "hexencode", rb_digest_s_hexencode, 1);
@@ -781,8 +810,6 @@ Init_digest(void)
rb_define_singleton_method(rb_cDigest_Class, "digest", rb_digest_class_s_digest, -1);
rb_define_singleton_method(rb_cDigest_Class, "hexdigest", rb_digest_class_s_hexdigest, -1);
- id_metadata = rb_intern("metadata");
-
/* class Digest::Base < Digest::Class */
rb_cDigest_Base = rb_define_class_under(rb_mDigest, "Base", rb_cDigest_Class);
diff --git a/ext/digest/digest.gemspec b/ext/digest/digest.gemspec
index 06da1c711b..6f3bf8b05f 100644
--- a/ext/digest/digest.gemspec
+++ b/ext/digest/digest.gemspec
@@ -3,30 +3,43 @@
Gem::Specification.new do |spec|
spec.name = "digest"
- spec.version = "0.1.0"
+ spec.version = "3.0.0"
spec.authors = ["Akinori MUSHA"]
spec.email = ["knu@idaemons.org"]
spec.summary = %q{Provides a framework for message digest libraries.}
spec.description = %q{Provides a framework for message digest libraries.}
spec.homepage = "https://github.com/ruby/digest"
- spec.license = "BSD-2-Clause"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.files = [
- ".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup",
- "digest.gemspec", "ext/digest/bubblebabble/bubblebabble.c", "ext/digest/bubblebabble/extconf.rb", "ext/digest/defs.h",
+ "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "digest.gemspec",
+ "ext/digest/bubblebabble/bubblebabble.c", "ext/digest/bubblebabble/extconf.rb", "ext/digest/defs.h",
"ext/digest/digest.c", "ext/digest/digest.h", "ext/digest/digest_conf.rb", "ext/digest/extconf.rb",
"ext/digest/md5/extconf.rb", "ext/digest/md5/md5.c", "ext/digest/md5/md5.h", "ext/digest/md5/md5cc.h",
- "ext/digest/md5/md5init.c", "ext/digest/md5/md5ossl.h", "ext/digest/rmd160/extconf.rb", "ext/digest/rmd160/rmd160.c",
- "ext/digest/rmd160/rmd160.h", "ext/digest/rmd160/rmd160init.c", "ext/digest/rmd160/rmd160ossl.h",
- "ext/digest/sha1/extconf.rb", "ext/digest/sha1/sha1.c", "ext/digest/sha1/sha1.h", "ext/digest/sha1/sha1cc.h",
- "ext/digest/sha1/sha1init.c", "ext/digest/sha1/sha1ossl.h", "ext/digest/sha2/extconf.rb", "ext/digest/sha2/lib/sha2.rb",
- "ext/digest/sha2/sha2.c", "ext/digest/sha2/sha2.h", "ext/digest/sha2/sha2cc.h", "ext/digest/sha2/sha2init.c",
- "ext/digest/sha2/sha2ossl.h", "ext/digest/test.sh", "ext/openssl/deprecation.rb", "lib/digest.rb"
+ "ext/digest/md5/md5init.c", "ext/digest/rmd160/extconf.rb", "ext/digest/rmd160/rmd160.c",
+ "ext/digest/rmd160/rmd160.h", "ext/digest/rmd160/rmd160init.c", "ext/digest/sha1/extconf.rb",
+ "ext/digest/sha1/sha1.c", "ext/digest/sha1/sha1.h", "ext/digest/sha1/sha1cc.h",
+ "ext/digest/sha1/sha1init.c", "ext/digest/sha2/extconf.rb", "ext/digest/sha2/lib/sha2.rb",
+ "ext/digest/sha2/sha2.c", "ext/digest/sha2/sha2.h", "ext/digest/sha2/sha2cc.h",
+ "ext/digest/sha2/sha2init.c", "ext/digest/test.sh", "ext/openssl/deprecation.rb",
+ "lib/digest.rb"
]
+
+ spec.required_ruby_version = ">= 2.3.0"
+
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
+ spec.extensions = %w[
+ ext/digest/extconf.rb
+ ext/digest/bubblebabble/extconf.rb
+ ext/digest/md5/extconf.rb
+ ext/digest/rmd160/extconf.rb
+ ext/digest/sha1/extconf.rb
+ ext/digest/sha2/extconf.rb
+ ]
+ spec.metadata["msys2_mingw_dependencies"] = "openssl"
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
diff --git a/ext/digest/digest.h b/ext/digest/digest.h
index 30359ad348..0d4f0e7cc2 100644
--- a/ext/digest/digest.h
+++ b/ext/digest/digest.h
@@ -49,3 +49,24 @@ rb_digest_##name##_finish(void *ctx, unsigned char *ptr) \
{ \
return name##_Final(ptr, ctx); \
}
+
+static inline VALUE
+rb_digest_namespace(void)
+{
+ rb_require("digest");
+ return rb_path2class("Digest");
+}
+
+static inline ID
+rb_id_metadata(void)
+{
+ return rb_intern_const("metadata");
+}
+
+static inline VALUE
+rb_digest_make_metadata(const rb_digest_metadata_t *meta)
+{
+#undef RUBY_UNTYPED_DATA_WARNING
+#define RUBY_UNTYPED_DATA_WARNING 0
+ return rb_obj_freeze(Data_Wrap_Struct(0, 0, 0, (void *)meta));
+}
diff --git a/ext/digest/digest_conf.rb b/ext/digest/digest_conf.rb
index 915b61877f..1b929d8732 100644
--- a/ext/digest/digest_conf.rb
+++ b/ext/digest/digest_conf.rb
@@ -1,57 +1,6 @@
# frozen_string_literal: false
-# Copy from ext/openssl/extconf.rb
-def find_openssl_library
- if $mswin || $mingw
- # required for static OpenSSL libraries
- have_library("gdi32") # OpenSSL <= 1.0.2 (for RAND_screen())
- have_library("crypt32")
- end
-
- return false unless have_header("openssl/ssl.h")
-
- ret = have_library("crypto", "CRYPTO_malloc") &&
- have_library("ssl", "SSL_new")
- return ret if ret
-
- if $mswin
- # OpenSSL >= 1.1.0: libcrypto.lib and libssl.lib.
- if have_library("libcrypto", "CRYPTO_malloc") &&
- have_library("libssl", "SSL_new")
- return true
- end
-
- # OpenSSL <= 1.0.2: libeay32.lib and ssleay32.lib.
- if have_library("libeay32", "CRYPTO_malloc") &&
- have_library("ssleay32", "SSL_new")
- return true
- end
-
- # LibreSSL: libcrypto-##.lib and libssl-##.lib, where ## is the ABI version
- # number. We have to find the version number out by scanning libpath.
- libpath = $LIBPATH.dup
- libpath |= ENV["LIB"].split(File::PATH_SEPARATOR)
- libpath.map! { |d| d.tr(File::ALT_SEPARATOR, File::SEPARATOR) }
-
- ret = [
- ["crypto", "CRYPTO_malloc"],
- ["ssl", "SSL_new"]
- ].all? do |base, func|
- result = false
- libs = ["lib#{base}-[0-9][0-9]", "lib#{base}-[0-9][0-9][0-9]"]
- libs = Dir.glob(libs.map{|l| libpath.map{|d| File.join(d, l + ".*")}}.flatten).map{|path| File.basename(path, ".*")}.uniq
- libs.each do |lib|
- result = have_library(lib, func)
- break if result
- end
- result
- end
- return ret if ret
- end
- return false
-end
-
-def digest_conf(name, hdr = name, funcs = nil, types = nil)
+def digest_conf(name)
unless with_config("bundled-#{name}")
cc = with_config("common-digest")
if cc == true or /\b#{name}\b/ =~ cc
@@ -62,22 +11,6 @@ def digest_conf(name, hdr = name, funcs = nil, types = nil)
return :commondigest
end
end
-
- dir_config("openssl")
- pkg_config("openssl")
- require File.expand_path('../../openssl/deprecation', __FILE__)
- if find_openssl_library
- funcs ||= name.upcase
- funcs = Array(funcs)
- types ||= funcs
- hdr = "openssl/#{hdr}.h"
- if funcs.all? {|func| OpenSSL.check_func("#{func}_Transform", hdr)} &&
- types.all? {|type| have_type("#{type}_CTX", hdr)}
- $defs << "-D#{name.upcase}_USE_OPENSSL"
- $headers << "#{name}ossl.h"
- return :ossl
- end
- end
end
$objs << "#{name}.#{$OBJEXT}"
return
diff --git a/ext/digest/md5/depend b/ext/digest/md5/depend
index 03c4cc8640..987ebcc12d 100644
--- a/ext/digest/md5/depend
+++ b/ext/digest/md5/depend
@@ -2,17 +2,331 @@ md5.o: md5.c md5.h $(srcdir)/../defs.h
md5init.o: $(LOCAL_HDRS)
# AUTOGENERATED DEPENDENCIES START
+md5.o: $(RUBY_EXTCONF_H)
+md5.o: $(arch_hdrdir)/ruby/config.h
+md5.o: $(hdrdir)/ruby.h
+md5.o: $(hdrdir)/ruby/assert.h
+md5.o: $(hdrdir)/ruby/backward.h
+md5.o: $(hdrdir)/ruby/backward/2/assume.h
+md5.o: $(hdrdir)/ruby/backward/2/attributes.h
+md5.o: $(hdrdir)/ruby/backward/2/bool.h
+md5.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+md5.o: $(hdrdir)/ruby/backward/2/inttypes.h
+md5.o: $(hdrdir)/ruby/backward/2/limits.h
+md5.o: $(hdrdir)/ruby/backward/2/long_long.h
+md5.o: $(hdrdir)/ruby/backward/2/stdalign.h
+md5.o: $(hdrdir)/ruby/backward/2/stdarg.h
+md5.o: $(hdrdir)/ruby/defines.h
+md5.o: $(hdrdir)/ruby/intern.h
+md5.o: $(hdrdir)/ruby/internal/anyargs.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+md5.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+md5.o: $(hdrdir)/ruby/internal/assume.h
+md5.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+md5.o: $(hdrdir)/ruby/internal/attr/artificial.h
+md5.o: $(hdrdir)/ruby/internal/attr/cold.h
+md5.o: $(hdrdir)/ruby/internal/attr/const.h
+md5.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+md5.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+md5.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+md5.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+md5.o: $(hdrdir)/ruby/internal/attr/error.h
+md5.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+md5.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+md5.o: $(hdrdir)/ruby/internal/attr/format.h
+md5.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+md5.o: $(hdrdir)/ruby/internal/attr/noalias.h
+md5.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+md5.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+md5.o: $(hdrdir)/ruby/internal/attr/noinline.h
+md5.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+md5.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+md5.o: $(hdrdir)/ruby/internal/attr/pure.h
+md5.o: $(hdrdir)/ruby/internal/attr/restrict.h
+md5.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+md5.o: $(hdrdir)/ruby/internal/attr/warning.h
+md5.o: $(hdrdir)/ruby/internal/attr/weakref.h
+md5.o: $(hdrdir)/ruby/internal/cast.h
+md5.o: $(hdrdir)/ruby/internal/compiler_is.h
+md5.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+md5.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+md5.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+md5.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+md5.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+md5.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+md5.o: $(hdrdir)/ruby/internal/compiler_since.h
+md5.o: $(hdrdir)/ruby/internal/config.h
+md5.o: $(hdrdir)/ruby/internal/constant_p.h
+md5.o: $(hdrdir)/ruby/internal/core.h
+md5.o: $(hdrdir)/ruby/internal/core/rarray.h
+md5.o: $(hdrdir)/ruby/internal/core/rbasic.h
+md5.o: $(hdrdir)/ruby/internal/core/rbignum.h
+md5.o: $(hdrdir)/ruby/internal/core/rclass.h
+md5.o: $(hdrdir)/ruby/internal/core/rdata.h
+md5.o: $(hdrdir)/ruby/internal/core/rfile.h
+md5.o: $(hdrdir)/ruby/internal/core/rhash.h
+md5.o: $(hdrdir)/ruby/internal/core/robject.h
+md5.o: $(hdrdir)/ruby/internal/core/rregexp.h
+md5.o: $(hdrdir)/ruby/internal/core/rstring.h
+md5.o: $(hdrdir)/ruby/internal/core/rstruct.h
+md5.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+md5.o: $(hdrdir)/ruby/internal/ctype.h
+md5.o: $(hdrdir)/ruby/internal/dllexport.h
+md5.o: $(hdrdir)/ruby/internal/dosish.h
+md5.o: $(hdrdir)/ruby/internal/error.h
+md5.o: $(hdrdir)/ruby/internal/eval.h
+md5.o: $(hdrdir)/ruby/internal/event.h
+md5.o: $(hdrdir)/ruby/internal/fl_type.h
+md5.o: $(hdrdir)/ruby/internal/gc.h
+md5.o: $(hdrdir)/ruby/internal/glob.h
+md5.o: $(hdrdir)/ruby/internal/globals.h
+md5.o: $(hdrdir)/ruby/internal/has/attribute.h
+md5.o: $(hdrdir)/ruby/internal/has/builtin.h
+md5.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+md5.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+md5.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+md5.o: $(hdrdir)/ruby/internal/has/extension.h
+md5.o: $(hdrdir)/ruby/internal/has/feature.h
+md5.o: $(hdrdir)/ruby/internal/has/warning.h
+md5.o: $(hdrdir)/ruby/internal/intern/array.h
+md5.o: $(hdrdir)/ruby/internal/intern/bignum.h
+md5.o: $(hdrdir)/ruby/internal/intern/class.h
+md5.o: $(hdrdir)/ruby/internal/intern/compar.h
+md5.o: $(hdrdir)/ruby/internal/intern/complex.h
+md5.o: $(hdrdir)/ruby/internal/intern/cont.h
+md5.o: $(hdrdir)/ruby/internal/intern/dir.h
+md5.o: $(hdrdir)/ruby/internal/intern/enum.h
+md5.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+md5.o: $(hdrdir)/ruby/internal/intern/error.h
+md5.o: $(hdrdir)/ruby/internal/intern/eval.h
+md5.o: $(hdrdir)/ruby/internal/intern/file.h
+md5.o: $(hdrdir)/ruby/internal/intern/gc.h
+md5.o: $(hdrdir)/ruby/internal/intern/hash.h
+md5.o: $(hdrdir)/ruby/internal/intern/io.h
+md5.o: $(hdrdir)/ruby/internal/intern/load.h
+md5.o: $(hdrdir)/ruby/internal/intern/marshal.h
+md5.o: $(hdrdir)/ruby/internal/intern/numeric.h
+md5.o: $(hdrdir)/ruby/internal/intern/object.h
+md5.o: $(hdrdir)/ruby/internal/intern/parse.h
+md5.o: $(hdrdir)/ruby/internal/intern/proc.h
+md5.o: $(hdrdir)/ruby/internal/intern/process.h
+md5.o: $(hdrdir)/ruby/internal/intern/random.h
+md5.o: $(hdrdir)/ruby/internal/intern/range.h
+md5.o: $(hdrdir)/ruby/internal/intern/rational.h
+md5.o: $(hdrdir)/ruby/internal/intern/re.h
+md5.o: $(hdrdir)/ruby/internal/intern/ruby.h
+md5.o: $(hdrdir)/ruby/internal/intern/select.h
+md5.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+md5.o: $(hdrdir)/ruby/internal/intern/signal.h
+md5.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+md5.o: $(hdrdir)/ruby/internal/intern/string.h
+md5.o: $(hdrdir)/ruby/internal/intern/struct.h
+md5.o: $(hdrdir)/ruby/internal/intern/thread.h
+md5.o: $(hdrdir)/ruby/internal/intern/time.h
+md5.o: $(hdrdir)/ruby/internal/intern/variable.h
+md5.o: $(hdrdir)/ruby/internal/intern/vm.h
+md5.o: $(hdrdir)/ruby/internal/interpreter.h
+md5.o: $(hdrdir)/ruby/internal/iterator.h
+md5.o: $(hdrdir)/ruby/internal/memory.h
+md5.o: $(hdrdir)/ruby/internal/method.h
+md5.o: $(hdrdir)/ruby/internal/module.h
+md5.o: $(hdrdir)/ruby/internal/newobj.h
+md5.o: $(hdrdir)/ruby/internal/rgengc.h
+md5.o: $(hdrdir)/ruby/internal/scan_args.h
+md5.o: $(hdrdir)/ruby/internal/special_consts.h
+md5.o: $(hdrdir)/ruby/internal/static_assert.h
+md5.o: $(hdrdir)/ruby/internal/stdalign.h
+md5.o: $(hdrdir)/ruby/internal/stdbool.h
+md5.o: $(hdrdir)/ruby/internal/symbol.h
+md5.o: $(hdrdir)/ruby/internal/token_paste.h
+md5.o: $(hdrdir)/ruby/internal/value.h
+md5.o: $(hdrdir)/ruby/internal/value_type.h
+md5.o: $(hdrdir)/ruby/internal/variable.h
+md5.o: $(hdrdir)/ruby/internal/warning_push.h
+md5.o: $(hdrdir)/ruby/internal/xmalloc.h
+md5.o: $(hdrdir)/ruby/missing.h
+md5.o: $(hdrdir)/ruby/ruby.h
+md5.o: $(hdrdir)/ruby/st.h
+md5.o: $(hdrdir)/ruby/subst.h
+md5.o: $(srcdir)/../defs.h
+md5.o: md5.c
+md5.o: md5.h
md5init.o: $(RUBY_EXTCONF_H)
md5init.o: $(arch_hdrdir)/ruby/config.h
+md5init.o: $(hdrdir)/ruby.h
+md5init.o: $(hdrdir)/ruby/assert.h
md5init.o: $(hdrdir)/ruby/backward.h
+md5init.o: $(hdrdir)/ruby/backward/2/assume.h
+md5init.o: $(hdrdir)/ruby/backward/2/attributes.h
+md5init.o: $(hdrdir)/ruby/backward/2/bool.h
+md5init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+md5init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+md5init.o: $(hdrdir)/ruby/backward/2/limits.h
+md5init.o: $(hdrdir)/ruby/backward/2/long_long.h
+md5init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+md5init.o: $(hdrdir)/ruby/backward/2/stdarg.h
md5init.o: $(hdrdir)/ruby/defines.h
md5init.o: $(hdrdir)/ruby/intern.h
+md5init.o: $(hdrdir)/ruby/internal/anyargs.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+md5init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+md5init.o: $(hdrdir)/ruby/internal/assume.h
+md5init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+md5init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+md5init.o: $(hdrdir)/ruby/internal/attr/cold.h
+md5init.o: $(hdrdir)/ruby/internal/attr/const.h
+md5init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+md5init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+md5init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+md5init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+md5init.o: $(hdrdir)/ruby/internal/attr/error.h
+md5init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+md5init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+md5init.o: $(hdrdir)/ruby/internal/attr/format.h
+md5init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+md5init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+md5init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+md5init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+md5init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+md5init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+md5init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+md5init.o: $(hdrdir)/ruby/internal/attr/pure.h
+md5init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+md5init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+md5init.o: $(hdrdir)/ruby/internal/attr/warning.h
+md5init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+md5init.o: $(hdrdir)/ruby/internal/cast.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_is.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+md5init.o: $(hdrdir)/ruby/internal/compiler_since.h
+md5init.o: $(hdrdir)/ruby/internal/config.h
+md5init.o: $(hdrdir)/ruby/internal/constant_p.h
+md5init.o: $(hdrdir)/ruby/internal/core.h
+md5init.o: $(hdrdir)/ruby/internal/core/rarray.h
+md5init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+md5init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+md5init.o: $(hdrdir)/ruby/internal/core/rclass.h
+md5init.o: $(hdrdir)/ruby/internal/core/rdata.h
+md5init.o: $(hdrdir)/ruby/internal/core/rfile.h
+md5init.o: $(hdrdir)/ruby/internal/core/rhash.h
+md5init.o: $(hdrdir)/ruby/internal/core/robject.h
+md5init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+md5init.o: $(hdrdir)/ruby/internal/core/rstring.h
+md5init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+md5init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+md5init.o: $(hdrdir)/ruby/internal/ctype.h
+md5init.o: $(hdrdir)/ruby/internal/dllexport.h
+md5init.o: $(hdrdir)/ruby/internal/dosish.h
+md5init.o: $(hdrdir)/ruby/internal/error.h
+md5init.o: $(hdrdir)/ruby/internal/eval.h
+md5init.o: $(hdrdir)/ruby/internal/event.h
+md5init.o: $(hdrdir)/ruby/internal/fl_type.h
+md5init.o: $(hdrdir)/ruby/internal/gc.h
+md5init.o: $(hdrdir)/ruby/internal/glob.h
+md5init.o: $(hdrdir)/ruby/internal/globals.h
+md5init.o: $(hdrdir)/ruby/internal/has/attribute.h
+md5init.o: $(hdrdir)/ruby/internal/has/builtin.h
+md5init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+md5init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+md5init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+md5init.o: $(hdrdir)/ruby/internal/has/extension.h
+md5init.o: $(hdrdir)/ruby/internal/has/feature.h
+md5init.o: $(hdrdir)/ruby/internal/has/warning.h
+md5init.o: $(hdrdir)/ruby/internal/intern/array.h
+md5init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+md5init.o: $(hdrdir)/ruby/internal/intern/class.h
+md5init.o: $(hdrdir)/ruby/internal/intern/compar.h
+md5init.o: $(hdrdir)/ruby/internal/intern/complex.h
+md5init.o: $(hdrdir)/ruby/internal/intern/cont.h
+md5init.o: $(hdrdir)/ruby/internal/intern/dir.h
+md5init.o: $(hdrdir)/ruby/internal/intern/enum.h
+md5init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+md5init.o: $(hdrdir)/ruby/internal/intern/error.h
+md5init.o: $(hdrdir)/ruby/internal/intern/eval.h
+md5init.o: $(hdrdir)/ruby/internal/intern/file.h
+md5init.o: $(hdrdir)/ruby/internal/intern/gc.h
+md5init.o: $(hdrdir)/ruby/internal/intern/hash.h
+md5init.o: $(hdrdir)/ruby/internal/intern/io.h
+md5init.o: $(hdrdir)/ruby/internal/intern/load.h
+md5init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+md5init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+md5init.o: $(hdrdir)/ruby/internal/intern/object.h
+md5init.o: $(hdrdir)/ruby/internal/intern/parse.h
+md5init.o: $(hdrdir)/ruby/internal/intern/proc.h
+md5init.o: $(hdrdir)/ruby/internal/intern/process.h
+md5init.o: $(hdrdir)/ruby/internal/intern/random.h
+md5init.o: $(hdrdir)/ruby/internal/intern/range.h
+md5init.o: $(hdrdir)/ruby/internal/intern/rational.h
+md5init.o: $(hdrdir)/ruby/internal/intern/re.h
+md5init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+md5init.o: $(hdrdir)/ruby/internal/intern/select.h
+md5init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+md5init.o: $(hdrdir)/ruby/internal/intern/signal.h
+md5init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+md5init.o: $(hdrdir)/ruby/internal/intern/string.h
+md5init.o: $(hdrdir)/ruby/internal/intern/struct.h
+md5init.o: $(hdrdir)/ruby/internal/intern/thread.h
+md5init.o: $(hdrdir)/ruby/internal/intern/time.h
+md5init.o: $(hdrdir)/ruby/internal/intern/variable.h
+md5init.o: $(hdrdir)/ruby/internal/intern/vm.h
+md5init.o: $(hdrdir)/ruby/internal/interpreter.h
+md5init.o: $(hdrdir)/ruby/internal/iterator.h
+md5init.o: $(hdrdir)/ruby/internal/memory.h
+md5init.o: $(hdrdir)/ruby/internal/method.h
+md5init.o: $(hdrdir)/ruby/internal/module.h
+md5init.o: $(hdrdir)/ruby/internal/newobj.h
+md5init.o: $(hdrdir)/ruby/internal/rgengc.h
+md5init.o: $(hdrdir)/ruby/internal/scan_args.h
+md5init.o: $(hdrdir)/ruby/internal/special_consts.h
+md5init.o: $(hdrdir)/ruby/internal/static_assert.h
+md5init.o: $(hdrdir)/ruby/internal/stdalign.h
+md5init.o: $(hdrdir)/ruby/internal/stdbool.h
+md5init.o: $(hdrdir)/ruby/internal/symbol.h
+md5init.o: $(hdrdir)/ruby/internal/token_paste.h
+md5init.o: $(hdrdir)/ruby/internal/value.h
+md5init.o: $(hdrdir)/ruby/internal/value_type.h
+md5init.o: $(hdrdir)/ruby/internal/variable.h
+md5init.o: $(hdrdir)/ruby/internal/warning_push.h
+md5init.o: $(hdrdir)/ruby/internal/xmalloc.h
md5init.o: $(hdrdir)/ruby/missing.h
md5init.o: $(hdrdir)/ruby/ruby.h
md5init.o: $(hdrdir)/ruby/st.h
md5init.o: $(hdrdir)/ruby/subst.h
-md5init.o: $(top_srcdir)/ext/digest/digest.h
-md5init.o: $(top_srcdir)/include/ruby.h
+md5init.o: $(srcdir)/../defs.h
+md5init.o: $(srcdir)/../digest.h
+md5init.o: md5.h
md5init.o: md5init.c
-md5init.o: md5ossl.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/digest/md5/md5cc.h b/ext/digest/md5/md5cc.h
index 35652eac6a..e34d7d5c11 100644
--- a/ext/digest/md5/md5cc.h
+++ b/ext/digest/md5/md5cc.h
@@ -1,6 +1,13 @@
#define COMMON_DIGEST_FOR_OPENSSL 1
#include <CommonCrypto/CommonDigest.h>
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Wdeprecated-declarations"
+/* Suppress deprecation warnings of MD5 from Xcode 11.1 */
+/* Although we know MD5 is deprecated too, provide just for backward
+ * compatibility, as well as Apple does. */
+#endif
+
#define MD5_BLOCK_LENGTH CC_MD5_BLOCK_BYTES
static DEFINE_UPDATE_FUNC_FOR_UINT(MD5)
diff --git a/ext/digest/md5/md5init.c b/ext/digest/md5/md5init.c
index fdd8b36c5d..52cba78bf1 100644
--- a/ext/digest/md5/md5init.c
+++ b/ext/digest/md5/md5init.c
@@ -3,9 +3,7 @@
#include <ruby/ruby.h>
#include "../digest.h"
-#if defined(MD5_USE_OPENSSL)
-#include "md5ossl.h"
-#elif defined(MD5_USE_COMMONDIGEST)
+#if defined(MD5_USE_COMMONDIGEST)
#include "md5cc.h"
#else
#include "md5.h"
@@ -51,18 +49,13 @@ Init_md5(void)
{
VALUE mDigest, cDigest_Base, cDigest_MD5;
- rb_require("digest");
-
#if 0
mDigest = rb_define_module("Digest"); /* let rdoc know */
#endif
- mDigest = rb_path2class("Digest");
+ mDigest = rb_digest_namespace();
cDigest_Base = rb_path2class("Digest::Base");
cDigest_MD5 = rb_define_class_under(mDigest, "MD5", cDigest_Base);
-#undef RUBY_UNTYPED_DATA_WARNING
-#define RUBY_UNTYPED_DATA_WARNING 0
- rb_iv_set(cDigest_MD5, "metadata",
- Data_Wrap_Struct(0, 0, 0, (void *)&md5));
+ rb_iv_set(cDigest_MD5, "metadata", rb_digest_make_metadata(&md5));
}
diff --git a/ext/digest/md5/md5ossl.h b/ext/digest/md5/md5ossl.h
deleted file mode 100644
index 94aa7ae77b..0000000000
--- a/ext/digest/md5/md5ossl.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id$ */
-
-#ifndef MD5OSSL_H_INCLUDED
-#define MD5OSSL_H_INCLUDED
-
-#include <stddef.h>
-#include <openssl/md5.h>
-
-#define MD5_BLOCK_LENGTH MD5_CBLOCK
-
-static DEFINE_FINISH_FUNC_FROM_FINAL(MD5)
-#undef MD5_Finish
-#define MD5_Finish rb_digest_MD5_finish
-
-#endif
diff --git a/ext/digest/rmd160/depend b/ext/digest/rmd160/depend
index 2dfeecf034..ce5dcdb871 100644
--- a/ext/digest/rmd160/depend
+++ b/ext/digest/rmd160/depend
@@ -2,17 +2,331 @@ rmd160.o: rmd160.c rmd160.h $(srcdir)/../defs.h
rmd160init.o: $(LOCAL_HDRS)
# AUTOGENERATED DEPENDENCIES START
+rmd160.o: $(RUBY_EXTCONF_H)
+rmd160.o: $(arch_hdrdir)/ruby/config.h
+rmd160.o: $(hdrdir)/ruby.h
+rmd160.o: $(hdrdir)/ruby/assert.h
+rmd160.o: $(hdrdir)/ruby/backward.h
+rmd160.o: $(hdrdir)/ruby/backward/2/assume.h
+rmd160.o: $(hdrdir)/ruby/backward/2/attributes.h
+rmd160.o: $(hdrdir)/ruby/backward/2/bool.h
+rmd160.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+rmd160.o: $(hdrdir)/ruby/backward/2/inttypes.h
+rmd160.o: $(hdrdir)/ruby/backward/2/limits.h
+rmd160.o: $(hdrdir)/ruby/backward/2/long_long.h
+rmd160.o: $(hdrdir)/ruby/backward/2/stdalign.h
+rmd160.o: $(hdrdir)/ruby/backward/2/stdarg.h
+rmd160.o: $(hdrdir)/ruby/defines.h
+rmd160.o: $(hdrdir)/ruby/intern.h
+rmd160.o: $(hdrdir)/ruby/internal/anyargs.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+rmd160.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+rmd160.o: $(hdrdir)/ruby/internal/assume.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/artificial.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/cold.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/const.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/error.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/format.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/noalias.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/noinline.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/pure.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/restrict.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/warning.h
+rmd160.o: $(hdrdir)/ruby/internal/attr/weakref.h
+rmd160.o: $(hdrdir)/ruby/internal/cast.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_is.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+rmd160.o: $(hdrdir)/ruby/internal/compiler_since.h
+rmd160.o: $(hdrdir)/ruby/internal/config.h
+rmd160.o: $(hdrdir)/ruby/internal/constant_p.h
+rmd160.o: $(hdrdir)/ruby/internal/core.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rarray.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rbasic.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rbignum.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rclass.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rdata.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rfile.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rhash.h
+rmd160.o: $(hdrdir)/ruby/internal/core/robject.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rregexp.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rstring.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rstruct.h
+rmd160.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+rmd160.o: $(hdrdir)/ruby/internal/ctype.h
+rmd160.o: $(hdrdir)/ruby/internal/dllexport.h
+rmd160.o: $(hdrdir)/ruby/internal/dosish.h
+rmd160.o: $(hdrdir)/ruby/internal/error.h
+rmd160.o: $(hdrdir)/ruby/internal/eval.h
+rmd160.o: $(hdrdir)/ruby/internal/event.h
+rmd160.o: $(hdrdir)/ruby/internal/fl_type.h
+rmd160.o: $(hdrdir)/ruby/internal/gc.h
+rmd160.o: $(hdrdir)/ruby/internal/glob.h
+rmd160.o: $(hdrdir)/ruby/internal/globals.h
+rmd160.o: $(hdrdir)/ruby/internal/has/attribute.h
+rmd160.o: $(hdrdir)/ruby/internal/has/builtin.h
+rmd160.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+rmd160.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+rmd160.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+rmd160.o: $(hdrdir)/ruby/internal/has/extension.h
+rmd160.o: $(hdrdir)/ruby/internal/has/feature.h
+rmd160.o: $(hdrdir)/ruby/internal/has/warning.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/array.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/bignum.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/class.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/compar.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/complex.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/cont.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/dir.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/enum.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/error.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/eval.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/file.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/gc.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/hash.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/io.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/load.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/marshal.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/numeric.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/object.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/parse.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/proc.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/process.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/random.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/range.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/rational.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/re.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/ruby.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/select.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/signal.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/string.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/struct.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/thread.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/time.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/variable.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/vm.h
+rmd160.o: $(hdrdir)/ruby/internal/interpreter.h
+rmd160.o: $(hdrdir)/ruby/internal/iterator.h
+rmd160.o: $(hdrdir)/ruby/internal/memory.h
+rmd160.o: $(hdrdir)/ruby/internal/method.h
+rmd160.o: $(hdrdir)/ruby/internal/module.h
+rmd160.o: $(hdrdir)/ruby/internal/newobj.h
+rmd160.o: $(hdrdir)/ruby/internal/rgengc.h
+rmd160.o: $(hdrdir)/ruby/internal/scan_args.h
+rmd160.o: $(hdrdir)/ruby/internal/special_consts.h
+rmd160.o: $(hdrdir)/ruby/internal/static_assert.h
+rmd160.o: $(hdrdir)/ruby/internal/stdalign.h
+rmd160.o: $(hdrdir)/ruby/internal/stdbool.h
+rmd160.o: $(hdrdir)/ruby/internal/symbol.h
+rmd160.o: $(hdrdir)/ruby/internal/token_paste.h
+rmd160.o: $(hdrdir)/ruby/internal/value.h
+rmd160.o: $(hdrdir)/ruby/internal/value_type.h
+rmd160.o: $(hdrdir)/ruby/internal/variable.h
+rmd160.o: $(hdrdir)/ruby/internal/warning_push.h
+rmd160.o: $(hdrdir)/ruby/internal/xmalloc.h
+rmd160.o: $(hdrdir)/ruby/missing.h
+rmd160.o: $(hdrdir)/ruby/ruby.h
+rmd160.o: $(hdrdir)/ruby/st.h
+rmd160.o: $(hdrdir)/ruby/subst.h
+rmd160.o: $(srcdir)/../defs.h
+rmd160.o: rmd160.c
+rmd160.o: rmd160.h
rmd160init.o: $(RUBY_EXTCONF_H)
rmd160init.o: $(arch_hdrdir)/ruby/config.h
+rmd160init.o: $(hdrdir)/ruby.h
+rmd160init.o: $(hdrdir)/ruby/assert.h
rmd160init.o: $(hdrdir)/ruby/backward.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/assume.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/attributes.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/bool.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/limits.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/long_long.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+rmd160init.o: $(hdrdir)/ruby/backward/2/stdarg.h
rmd160init.o: $(hdrdir)/ruby/defines.h
rmd160init.o: $(hdrdir)/ruby/intern.h
+rmd160init.o: $(hdrdir)/ruby/internal/anyargs.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+rmd160init.o: $(hdrdir)/ruby/internal/assume.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/cold.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/const.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/error.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/format.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/pure.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/warning.h
+rmd160init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+rmd160init.o: $(hdrdir)/ruby/internal/cast.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_is.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+rmd160init.o: $(hdrdir)/ruby/internal/compiler_since.h
+rmd160init.o: $(hdrdir)/ruby/internal/config.h
+rmd160init.o: $(hdrdir)/ruby/internal/constant_p.h
+rmd160init.o: $(hdrdir)/ruby/internal/core.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rarray.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rclass.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rdata.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rfile.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rhash.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/robject.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rstring.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+rmd160init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+rmd160init.o: $(hdrdir)/ruby/internal/ctype.h
+rmd160init.o: $(hdrdir)/ruby/internal/dllexport.h
+rmd160init.o: $(hdrdir)/ruby/internal/dosish.h
+rmd160init.o: $(hdrdir)/ruby/internal/error.h
+rmd160init.o: $(hdrdir)/ruby/internal/eval.h
+rmd160init.o: $(hdrdir)/ruby/internal/event.h
+rmd160init.o: $(hdrdir)/ruby/internal/fl_type.h
+rmd160init.o: $(hdrdir)/ruby/internal/gc.h
+rmd160init.o: $(hdrdir)/ruby/internal/glob.h
+rmd160init.o: $(hdrdir)/ruby/internal/globals.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/attribute.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/builtin.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/extension.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/feature.h
+rmd160init.o: $(hdrdir)/ruby/internal/has/warning.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/array.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/class.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/compar.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/complex.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/cont.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/dir.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/enum.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/error.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/eval.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/file.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/gc.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/hash.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/io.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/load.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/object.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/parse.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/proc.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/process.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/random.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/range.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/rational.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/re.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/select.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/signal.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/string.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/struct.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/thread.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/time.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/variable.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/vm.h
+rmd160init.o: $(hdrdir)/ruby/internal/interpreter.h
+rmd160init.o: $(hdrdir)/ruby/internal/iterator.h
+rmd160init.o: $(hdrdir)/ruby/internal/memory.h
+rmd160init.o: $(hdrdir)/ruby/internal/method.h
+rmd160init.o: $(hdrdir)/ruby/internal/module.h
+rmd160init.o: $(hdrdir)/ruby/internal/newobj.h
+rmd160init.o: $(hdrdir)/ruby/internal/rgengc.h
+rmd160init.o: $(hdrdir)/ruby/internal/scan_args.h
+rmd160init.o: $(hdrdir)/ruby/internal/special_consts.h
+rmd160init.o: $(hdrdir)/ruby/internal/static_assert.h
+rmd160init.o: $(hdrdir)/ruby/internal/stdalign.h
+rmd160init.o: $(hdrdir)/ruby/internal/stdbool.h
+rmd160init.o: $(hdrdir)/ruby/internal/symbol.h
+rmd160init.o: $(hdrdir)/ruby/internal/token_paste.h
+rmd160init.o: $(hdrdir)/ruby/internal/value.h
+rmd160init.o: $(hdrdir)/ruby/internal/value_type.h
+rmd160init.o: $(hdrdir)/ruby/internal/variable.h
+rmd160init.o: $(hdrdir)/ruby/internal/warning_push.h
+rmd160init.o: $(hdrdir)/ruby/internal/xmalloc.h
rmd160init.o: $(hdrdir)/ruby/missing.h
rmd160init.o: $(hdrdir)/ruby/ruby.h
rmd160init.o: $(hdrdir)/ruby/st.h
rmd160init.o: $(hdrdir)/ruby/subst.h
-rmd160init.o: $(top_srcdir)/ext/digest/digest.h
-rmd160init.o: $(top_srcdir)/include/ruby.h
+rmd160init.o: $(srcdir)/../defs.h
+rmd160init.o: $(srcdir)/../digest.h
+rmd160init.o: rmd160.h
rmd160init.o: rmd160init.c
-rmd160init.o: rmd160ossl.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/digest/rmd160/extconf.rb b/ext/digest/rmd160/extconf.rb
index a02ba56169..ffa70ee803 100644
--- a/ext/digest/rmd160/extconf.rb
+++ b/ext/digest/rmd160/extconf.rb
@@ -10,7 +10,7 @@ $defs << "-DNDEBUG" << "-DHAVE_CONFIG_H"
$objs = [ "rmd160init.#{$OBJEXT}" ]
-digest_conf("rmd160", "ripemd", "RIPEMD160")
+digest_conf("rmd160")
have_header("sys/cdefs.h")
diff --git a/ext/digest/rmd160/rmd160init.c b/ext/digest/rmd160/rmd160init.c
index 10d9370163..2ae81ec4d6 100644
--- a/ext/digest/rmd160/rmd160init.c
+++ b/ext/digest/rmd160/rmd160init.c
@@ -3,11 +3,7 @@
#include <ruby/ruby.h>
#include "../digest.h"
-#if defined(RMD160_USE_OPENSSL)
-#include "rmd160ossl.h"
-#else
#include "rmd160.h"
-#endif
static const rb_digest_metadata_t rmd160 = {
RUBY_DIGEST_API_VERSION,
@@ -49,18 +45,13 @@ Init_rmd160(void)
{
VALUE mDigest, cDigest_Base, cDigest_RMD160;
- rb_require("digest");
-
#if 0
mDigest = rb_define_module("Digest"); /* let rdoc know */
#endif
- mDigest = rb_path2class("Digest");
+ mDigest = rb_digest_namespace();
cDigest_Base = rb_path2class("Digest::Base");
cDigest_RMD160 = rb_define_class_under(mDigest, "RMD160", cDigest_Base);
-#undef RUBY_UNTYPED_DATA_WARNING
-#define RUBY_UNTYPED_DATA_WARNING 0
- rb_iv_set(cDigest_RMD160, "metadata",
- Data_Wrap_Struct(0, 0, 0, (void *)&rmd160));
+ rb_iv_set(cDigest_RMD160, "metadata", rb_digest_make_metadata(&rmd160));
}
diff --git a/ext/digest/rmd160/rmd160ossl.h b/ext/digest/rmd160/rmd160ossl.h
deleted file mode 100644
index e6bf5ea8d0..0000000000
--- a/ext/digest/rmd160/rmd160ossl.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* $Id$ */
-
-#ifndef RMD160OSSL_H_INCLUDED
-#define RMD160OSSL_H_INCLUDED
-
-#include <stddef.h>
-#include <openssl/ripemd.h>
-
-#define RMD160_CTX RIPEMD160_CTX
-
-#define RMD160_Init RIPEMD160_Init
-#define RMD160_Update RIPEMD160_Update
-
-#define RMD160_BLOCK_LENGTH RIPEMD160_CBLOCK
-#define RMD160_DIGEST_LENGTH RIPEMD160_DIGEST_LENGTH
-
-static DEFINE_FINISH_FUNC_FROM_FINAL(RIPEMD160)
-#define RMD160_Finish rb_digest_RIPEMD160_finish
-
-#endif
diff --git a/ext/digest/sha1/depend b/ext/digest/sha1/depend
index 5139f44ff4..3daf84a137 100644
--- a/ext/digest/sha1/depend
+++ b/ext/digest/sha1/depend
@@ -2,17 +2,331 @@ sha1.o: sha1.c sha1.h $(srcdir)/../defs.h
sha1init.o: $(LOCAL_HDRS)
# AUTOGENERATED DEPENDENCIES START
+sha1.o: $(RUBY_EXTCONF_H)
+sha1.o: $(arch_hdrdir)/ruby/config.h
+sha1.o: $(hdrdir)/ruby.h
+sha1.o: $(hdrdir)/ruby/assert.h
+sha1.o: $(hdrdir)/ruby/backward.h
+sha1.o: $(hdrdir)/ruby/backward/2/assume.h
+sha1.o: $(hdrdir)/ruby/backward/2/attributes.h
+sha1.o: $(hdrdir)/ruby/backward/2/bool.h
+sha1.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+sha1.o: $(hdrdir)/ruby/backward/2/inttypes.h
+sha1.o: $(hdrdir)/ruby/backward/2/limits.h
+sha1.o: $(hdrdir)/ruby/backward/2/long_long.h
+sha1.o: $(hdrdir)/ruby/backward/2/stdalign.h
+sha1.o: $(hdrdir)/ruby/backward/2/stdarg.h
+sha1.o: $(hdrdir)/ruby/defines.h
+sha1.o: $(hdrdir)/ruby/intern.h
+sha1.o: $(hdrdir)/ruby/internal/anyargs.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+sha1.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+sha1.o: $(hdrdir)/ruby/internal/assume.h
+sha1.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+sha1.o: $(hdrdir)/ruby/internal/attr/artificial.h
+sha1.o: $(hdrdir)/ruby/internal/attr/cold.h
+sha1.o: $(hdrdir)/ruby/internal/attr/const.h
+sha1.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+sha1.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+sha1.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+sha1.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+sha1.o: $(hdrdir)/ruby/internal/attr/error.h
+sha1.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+sha1.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+sha1.o: $(hdrdir)/ruby/internal/attr/format.h
+sha1.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+sha1.o: $(hdrdir)/ruby/internal/attr/noalias.h
+sha1.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+sha1.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+sha1.o: $(hdrdir)/ruby/internal/attr/noinline.h
+sha1.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+sha1.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+sha1.o: $(hdrdir)/ruby/internal/attr/pure.h
+sha1.o: $(hdrdir)/ruby/internal/attr/restrict.h
+sha1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+sha1.o: $(hdrdir)/ruby/internal/attr/warning.h
+sha1.o: $(hdrdir)/ruby/internal/attr/weakref.h
+sha1.o: $(hdrdir)/ruby/internal/cast.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_is.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+sha1.o: $(hdrdir)/ruby/internal/compiler_since.h
+sha1.o: $(hdrdir)/ruby/internal/config.h
+sha1.o: $(hdrdir)/ruby/internal/constant_p.h
+sha1.o: $(hdrdir)/ruby/internal/core.h
+sha1.o: $(hdrdir)/ruby/internal/core/rarray.h
+sha1.o: $(hdrdir)/ruby/internal/core/rbasic.h
+sha1.o: $(hdrdir)/ruby/internal/core/rbignum.h
+sha1.o: $(hdrdir)/ruby/internal/core/rclass.h
+sha1.o: $(hdrdir)/ruby/internal/core/rdata.h
+sha1.o: $(hdrdir)/ruby/internal/core/rfile.h
+sha1.o: $(hdrdir)/ruby/internal/core/rhash.h
+sha1.o: $(hdrdir)/ruby/internal/core/robject.h
+sha1.o: $(hdrdir)/ruby/internal/core/rregexp.h
+sha1.o: $(hdrdir)/ruby/internal/core/rstring.h
+sha1.o: $(hdrdir)/ruby/internal/core/rstruct.h
+sha1.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+sha1.o: $(hdrdir)/ruby/internal/ctype.h
+sha1.o: $(hdrdir)/ruby/internal/dllexport.h
+sha1.o: $(hdrdir)/ruby/internal/dosish.h
+sha1.o: $(hdrdir)/ruby/internal/error.h
+sha1.o: $(hdrdir)/ruby/internal/eval.h
+sha1.o: $(hdrdir)/ruby/internal/event.h
+sha1.o: $(hdrdir)/ruby/internal/fl_type.h
+sha1.o: $(hdrdir)/ruby/internal/gc.h
+sha1.o: $(hdrdir)/ruby/internal/glob.h
+sha1.o: $(hdrdir)/ruby/internal/globals.h
+sha1.o: $(hdrdir)/ruby/internal/has/attribute.h
+sha1.o: $(hdrdir)/ruby/internal/has/builtin.h
+sha1.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+sha1.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+sha1.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+sha1.o: $(hdrdir)/ruby/internal/has/extension.h
+sha1.o: $(hdrdir)/ruby/internal/has/feature.h
+sha1.o: $(hdrdir)/ruby/internal/has/warning.h
+sha1.o: $(hdrdir)/ruby/internal/intern/array.h
+sha1.o: $(hdrdir)/ruby/internal/intern/bignum.h
+sha1.o: $(hdrdir)/ruby/internal/intern/class.h
+sha1.o: $(hdrdir)/ruby/internal/intern/compar.h
+sha1.o: $(hdrdir)/ruby/internal/intern/complex.h
+sha1.o: $(hdrdir)/ruby/internal/intern/cont.h
+sha1.o: $(hdrdir)/ruby/internal/intern/dir.h
+sha1.o: $(hdrdir)/ruby/internal/intern/enum.h
+sha1.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+sha1.o: $(hdrdir)/ruby/internal/intern/error.h
+sha1.o: $(hdrdir)/ruby/internal/intern/eval.h
+sha1.o: $(hdrdir)/ruby/internal/intern/file.h
+sha1.o: $(hdrdir)/ruby/internal/intern/gc.h
+sha1.o: $(hdrdir)/ruby/internal/intern/hash.h
+sha1.o: $(hdrdir)/ruby/internal/intern/io.h
+sha1.o: $(hdrdir)/ruby/internal/intern/load.h
+sha1.o: $(hdrdir)/ruby/internal/intern/marshal.h
+sha1.o: $(hdrdir)/ruby/internal/intern/numeric.h
+sha1.o: $(hdrdir)/ruby/internal/intern/object.h
+sha1.o: $(hdrdir)/ruby/internal/intern/parse.h
+sha1.o: $(hdrdir)/ruby/internal/intern/proc.h
+sha1.o: $(hdrdir)/ruby/internal/intern/process.h
+sha1.o: $(hdrdir)/ruby/internal/intern/random.h
+sha1.o: $(hdrdir)/ruby/internal/intern/range.h
+sha1.o: $(hdrdir)/ruby/internal/intern/rational.h
+sha1.o: $(hdrdir)/ruby/internal/intern/re.h
+sha1.o: $(hdrdir)/ruby/internal/intern/ruby.h
+sha1.o: $(hdrdir)/ruby/internal/intern/select.h
+sha1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+sha1.o: $(hdrdir)/ruby/internal/intern/signal.h
+sha1.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+sha1.o: $(hdrdir)/ruby/internal/intern/string.h
+sha1.o: $(hdrdir)/ruby/internal/intern/struct.h
+sha1.o: $(hdrdir)/ruby/internal/intern/thread.h
+sha1.o: $(hdrdir)/ruby/internal/intern/time.h
+sha1.o: $(hdrdir)/ruby/internal/intern/variable.h
+sha1.o: $(hdrdir)/ruby/internal/intern/vm.h
+sha1.o: $(hdrdir)/ruby/internal/interpreter.h
+sha1.o: $(hdrdir)/ruby/internal/iterator.h
+sha1.o: $(hdrdir)/ruby/internal/memory.h
+sha1.o: $(hdrdir)/ruby/internal/method.h
+sha1.o: $(hdrdir)/ruby/internal/module.h
+sha1.o: $(hdrdir)/ruby/internal/newobj.h
+sha1.o: $(hdrdir)/ruby/internal/rgengc.h
+sha1.o: $(hdrdir)/ruby/internal/scan_args.h
+sha1.o: $(hdrdir)/ruby/internal/special_consts.h
+sha1.o: $(hdrdir)/ruby/internal/static_assert.h
+sha1.o: $(hdrdir)/ruby/internal/stdalign.h
+sha1.o: $(hdrdir)/ruby/internal/stdbool.h
+sha1.o: $(hdrdir)/ruby/internal/symbol.h
+sha1.o: $(hdrdir)/ruby/internal/token_paste.h
+sha1.o: $(hdrdir)/ruby/internal/value.h
+sha1.o: $(hdrdir)/ruby/internal/value_type.h
+sha1.o: $(hdrdir)/ruby/internal/variable.h
+sha1.o: $(hdrdir)/ruby/internal/warning_push.h
+sha1.o: $(hdrdir)/ruby/internal/xmalloc.h
+sha1.o: $(hdrdir)/ruby/missing.h
+sha1.o: $(hdrdir)/ruby/ruby.h
+sha1.o: $(hdrdir)/ruby/st.h
+sha1.o: $(hdrdir)/ruby/subst.h
+sha1.o: $(srcdir)/../defs.h
+sha1.o: sha1.c
+sha1.o: sha1.h
sha1init.o: $(RUBY_EXTCONF_H)
sha1init.o: $(arch_hdrdir)/ruby/config.h
+sha1init.o: $(hdrdir)/ruby.h
+sha1init.o: $(hdrdir)/ruby/assert.h
sha1init.o: $(hdrdir)/ruby/backward.h
+sha1init.o: $(hdrdir)/ruby/backward/2/assume.h
+sha1init.o: $(hdrdir)/ruby/backward/2/attributes.h
+sha1init.o: $(hdrdir)/ruby/backward/2/bool.h
+sha1init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+sha1init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+sha1init.o: $(hdrdir)/ruby/backward/2/limits.h
+sha1init.o: $(hdrdir)/ruby/backward/2/long_long.h
+sha1init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+sha1init.o: $(hdrdir)/ruby/backward/2/stdarg.h
sha1init.o: $(hdrdir)/ruby/defines.h
sha1init.o: $(hdrdir)/ruby/intern.h
+sha1init.o: $(hdrdir)/ruby/internal/anyargs.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+sha1init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+sha1init.o: $(hdrdir)/ruby/internal/assume.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/cold.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/const.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/error.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/format.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/pure.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/warning.h
+sha1init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+sha1init.o: $(hdrdir)/ruby/internal/cast.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_is.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+sha1init.o: $(hdrdir)/ruby/internal/compiler_since.h
+sha1init.o: $(hdrdir)/ruby/internal/config.h
+sha1init.o: $(hdrdir)/ruby/internal/constant_p.h
+sha1init.o: $(hdrdir)/ruby/internal/core.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rarray.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rclass.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rdata.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rfile.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rhash.h
+sha1init.o: $(hdrdir)/ruby/internal/core/robject.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rstring.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+sha1init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+sha1init.o: $(hdrdir)/ruby/internal/ctype.h
+sha1init.o: $(hdrdir)/ruby/internal/dllexport.h
+sha1init.o: $(hdrdir)/ruby/internal/dosish.h
+sha1init.o: $(hdrdir)/ruby/internal/error.h
+sha1init.o: $(hdrdir)/ruby/internal/eval.h
+sha1init.o: $(hdrdir)/ruby/internal/event.h
+sha1init.o: $(hdrdir)/ruby/internal/fl_type.h
+sha1init.o: $(hdrdir)/ruby/internal/gc.h
+sha1init.o: $(hdrdir)/ruby/internal/glob.h
+sha1init.o: $(hdrdir)/ruby/internal/globals.h
+sha1init.o: $(hdrdir)/ruby/internal/has/attribute.h
+sha1init.o: $(hdrdir)/ruby/internal/has/builtin.h
+sha1init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+sha1init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+sha1init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+sha1init.o: $(hdrdir)/ruby/internal/has/extension.h
+sha1init.o: $(hdrdir)/ruby/internal/has/feature.h
+sha1init.o: $(hdrdir)/ruby/internal/has/warning.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/array.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/class.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/compar.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/complex.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/cont.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/dir.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/enum.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/error.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/eval.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/file.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/gc.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/hash.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/io.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/load.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/object.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/parse.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/proc.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/process.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/random.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/range.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/rational.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/re.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/select.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/signal.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/string.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/struct.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/thread.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/time.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/variable.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/vm.h
+sha1init.o: $(hdrdir)/ruby/internal/interpreter.h
+sha1init.o: $(hdrdir)/ruby/internal/iterator.h
+sha1init.o: $(hdrdir)/ruby/internal/memory.h
+sha1init.o: $(hdrdir)/ruby/internal/method.h
+sha1init.o: $(hdrdir)/ruby/internal/module.h
+sha1init.o: $(hdrdir)/ruby/internal/newobj.h
+sha1init.o: $(hdrdir)/ruby/internal/rgengc.h
+sha1init.o: $(hdrdir)/ruby/internal/scan_args.h
+sha1init.o: $(hdrdir)/ruby/internal/special_consts.h
+sha1init.o: $(hdrdir)/ruby/internal/static_assert.h
+sha1init.o: $(hdrdir)/ruby/internal/stdalign.h
+sha1init.o: $(hdrdir)/ruby/internal/stdbool.h
+sha1init.o: $(hdrdir)/ruby/internal/symbol.h
+sha1init.o: $(hdrdir)/ruby/internal/token_paste.h
+sha1init.o: $(hdrdir)/ruby/internal/value.h
+sha1init.o: $(hdrdir)/ruby/internal/value_type.h
+sha1init.o: $(hdrdir)/ruby/internal/variable.h
+sha1init.o: $(hdrdir)/ruby/internal/warning_push.h
+sha1init.o: $(hdrdir)/ruby/internal/xmalloc.h
sha1init.o: $(hdrdir)/ruby/missing.h
sha1init.o: $(hdrdir)/ruby/ruby.h
sha1init.o: $(hdrdir)/ruby/st.h
sha1init.o: $(hdrdir)/ruby/subst.h
-sha1init.o: $(top_srcdir)/ext/digest/digest.h
-sha1init.o: $(top_srcdir)/include/ruby.h
+sha1init.o: $(srcdir)/../defs.h
+sha1init.o: $(srcdir)/../digest.h
+sha1init.o: sha1.h
sha1init.o: sha1init.c
-sha1init.o: sha1ossl.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/digest/sha1/extconf.rb b/ext/digest/sha1/extconf.rb
index 0ff4158bef..1e94ba3ef9 100644
--- a/ext/digest/sha1/extconf.rb
+++ b/ext/digest/sha1/extconf.rb
@@ -10,7 +10,7 @@ $defs << "-DHAVE_CONFIG_H"
$objs = [ "sha1init.#{$OBJEXT}" ]
-digest_conf("sha1", "sha", nil, %w[SHA])
+digest_conf("sha1")
have_header("sys/cdefs.h")
diff --git a/ext/digest/sha1/sha1init.c b/ext/digest/sha1/sha1init.c
index e12d297699..f7047bc6d3 100644
--- a/ext/digest/sha1/sha1init.c
+++ b/ext/digest/sha1/sha1init.c
@@ -3,9 +3,7 @@
#include <ruby/ruby.h>
#include "../digest.h"
-#if defined(SHA1_USE_OPENSSL)
-#include "sha1ossl.h"
-#elif defined(SHA1_USE_COMMONDIGEST)
+#if defined(SHA1_USE_COMMONDIGEST)
#include "sha1cc.h"
#else
#include "sha1.h"
@@ -53,18 +51,13 @@ Init_sha1(void)
{
VALUE mDigest, cDigest_Base, cDigest_SHA1;
- rb_require("digest");
-
#if 0
mDigest = rb_define_module("Digest"); /* let rdoc know */
#endif
- mDigest = rb_path2class("Digest");
+ mDigest = rb_digest_namespace();
cDigest_Base = rb_path2class("Digest::Base");
cDigest_SHA1 = rb_define_class_under(mDigest, "SHA1", cDigest_Base);
-#undef RUBY_UNTYPED_DATA_WARNING
-#define RUBY_UNTYPED_DATA_WARNING 0
- rb_iv_set(cDigest_SHA1, "metadata",
- Data_Wrap_Struct(0, 0, 0, (void *)&sha1));
+ rb_iv_set(cDigest_SHA1, "metadata", rb_digest_make_metadata(&sha1));
}
diff --git a/ext/digest/sha1/sha1ossl.h b/ext/digest/sha1/sha1ossl.h
deleted file mode 100644
index 599efe9a2f..0000000000
--- a/ext/digest/sha1/sha1ossl.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* $Id$ */
-
-#ifndef SHA1OSSL_H_INCLUDED
-#define SHA1OSSL_H_INCLUDED
-
-#include <stddef.h>
-#include <openssl/sha.h>
-
-#define SHA1_CTX SHA_CTX
-
-#ifdef SHA_BLOCK_LENGTH
-#define SHA1_BLOCK_LENGTH SHA_BLOCK_LENGTH
-#else
-#define SHA1_BLOCK_LENGTH SHA_CBLOCK
-#endif
-#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
-
-static DEFINE_FINISH_FUNC_FROM_FINAL(SHA1)
-#undef SHA1_Finish
-#define SHA1_Finish rb_digest_SHA1_finish
-
-#endif
diff --git a/ext/digest/sha2/depend b/ext/digest/sha2/depend
index 1152fe4dac..d8d265c1ef 100644
--- a/ext/digest/sha2/depend
+++ b/ext/digest/sha2/depend
@@ -2,17 +2,330 @@ sha2.o: sha2.c sha2.h $(srcdir)/../defs.h
sha2init.o: $(LOCAL_HDRS)
# AUTOGENERATED DEPENDENCIES START
+sha2.o: $(RUBY_EXTCONF_H)
+sha2.o: $(arch_hdrdir)/ruby/config.h
+sha2.o: $(hdrdir)/ruby.h
+sha2.o: $(hdrdir)/ruby/assert.h
+sha2.o: $(hdrdir)/ruby/backward.h
+sha2.o: $(hdrdir)/ruby/backward/2/assume.h
+sha2.o: $(hdrdir)/ruby/backward/2/attributes.h
+sha2.o: $(hdrdir)/ruby/backward/2/bool.h
+sha2.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+sha2.o: $(hdrdir)/ruby/backward/2/inttypes.h
+sha2.o: $(hdrdir)/ruby/backward/2/limits.h
+sha2.o: $(hdrdir)/ruby/backward/2/long_long.h
+sha2.o: $(hdrdir)/ruby/backward/2/stdalign.h
+sha2.o: $(hdrdir)/ruby/backward/2/stdarg.h
+sha2.o: $(hdrdir)/ruby/defines.h
+sha2.o: $(hdrdir)/ruby/intern.h
+sha2.o: $(hdrdir)/ruby/internal/anyargs.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+sha2.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+sha2.o: $(hdrdir)/ruby/internal/assume.h
+sha2.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+sha2.o: $(hdrdir)/ruby/internal/attr/artificial.h
+sha2.o: $(hdrdir)/ruby/internal/attr/cold.h
+sha2.o: $(hdrdir)/ruby/internal/attr/const.h
+sha2.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+sha2.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+sha2.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+sha2.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+sha2.o: $(hdrdir)/ruby/internal/attr/error.h
+sha2.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+sha2.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+sha2.o: $(hdrdir)/ruby/internal/attr/format.h
+sha2.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+sha2.o: $(hdrdir)/ruby/internal/attr/noalias.h
+sha2.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+sha2.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+sha2.o: $(hdrdir)/ruby/internal/attr/noinline.h
+sha2.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+sha2.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+sha2.o: $(hdrdir)/ruby/internal/attr/pure.h
+sha2.o: $(hdrdir)/ruby/internal/attr/restrict.h
+sha2.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+sha2.o: $(hdrdir)/ruby/internal/attr/warning.h
+sha2.o: $(hdrdir)/ruby/internal/attr/weakref.h
+sha2.o: $(hdrdir)/ruby/internal/cast.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_is.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+sha2.o: $(hdrdir)/ruby/internal/compiler_since.h
+sha2.o: $(hdrdir)/ruby/internal/config.h
+sha2.o: $(hdrdir)/ruby/internal/constant_p.h
+sha2.o: $(hdrdir)/ruby/internal/core.h
+sha2.o: $(hdrdir)/ruby/internal/core/rarray.h
+sha2.o: $(hdrdir)/ruby/internal/core/rbasic.h
+sha2.o: $(hdrdir)/ruby/internal/core/rbignum.h
+sha2.o: $(hdrdir)/ruby/internal/core/rclass.h
+sha2.o: $(hdrdir)/ruby/internal/core/rdata.h
+sha2.o: $(hdrdir)/ruby/internal/core/rfile.h
+sha2.o: $(hdrdir)/ruby/internal/core/rhash.h
+sha2.o: $(hdrdir)/ruby/internal/core/robject.h
+sha2.o: $(hdrdir)/ruby/internal/core/rregexp.h
+sha2.o: $(hdrdir)/ruby/internal/core/rstring.h
+sha2.o: $(hdrdir)/ruby/internal/core/rstruct.h
+sha2.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+sha2.o: $(hdrdir)/ruby/internal/ctype.h
+sha2.o: $(hdrdir)/ruby/internal/dllexport.h
+sha2.o: $(hdrdir)/ruby/internal/dosish.h
+sha2.o: $(hdrdir)/ruby/internal/error.h
+sha2.o: $(hdrdir)/ruby/internal/eval.h
+sha2.o: $(hdrdir)/ruby/internal/event.h
+sha2.o: $(hdrdir)/ruby/internal/fl_type.h
+sha2.o: $(hdrdir)/ruby/internal/gc.h
+sha2.o: $(hdrdir)/ruby/internal/glob.h
+sha2.o: $(hdrdir)/ruby/internal/globals.h
+sha2.o: $(hdrdir)/ruby/internal/has/attribute.h
+sha2.o: $(hdrdir)/ruby/internal/has/builtin.h
+sha2.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+sha2.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+sha2.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+sha2.o: $(hdrdir)/ruby/internal/has/extension.h
+sha2.o: $(hdrdir)/ruby/internal/has/feature.h
+sha2.o: $(hdrdir)/ruby/internal/has/warning.h
+sha2.o: $(hdrdir)/ruby/internal/intern/array.h
+sha2.o: $(hdrdir)/ruby/internal/intern/bignum.h
+sha2.o: $(hdrdir)/ruby/internal/intern/class.h
+sha2.o: $(hdrdir)/ruby/internal/intern/compar.h
+sha2.o: $(hdrdir)/ruby/internal/intern/complex.h
+sha2.o: $(hdrdir)/ruby/internal/intern/cont.h
+sha2.o: $(hdrdir)/ruby/internal/intern/dir.h
+sha2.o: $(hdrdir)/ruby/internal/intern/enum.h
+sha2.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+sha2.o: $(hdrdir)/ruby/internal/intern/error.h
+sha2.o: $(hdrdir)/ruby/internal/intern/eval.h
+sha2.o: $(hdrdir)/ruby/internal/intern/file.h
+sha2.o: $(hdrdir)/ruby/internal/intern/gc.h
+sha2.o: $(hdrdir)/ruby/internal/intern/hash.h
+sha2.o: $(hdrdir)/ruby/internal/intern/io.h
+sha2.o: $(hdrdir)/ruby/internal/intern/load.h
+sha2.o: $(hdrdir)/ruby/internal/intern/marshal.h
+sha2.o: $(hdrdir)/ruby/internal/intern/numeric.h
+sha2.o: $(hdrdir)/ruby/internal/intern/object.h
+sha2.o: $(hdrdir)/ruby/internal/intern/parse.h
+sha2.o: $(hdrdir)/ruby/internal/intern/proc.h
+sha2.o: $(hdrdir)/ruby/internal/intern/process.h
+sha2.o: $(hdrdir)/ruby/internal/intern/random.h
+sha2.o: $(hdrdir)/ruby/internal/intern/range.h
+sha2.o: $(hdrdir)/ruby/internal/intern/rational.h
+sha2.o: $(hdrdir)/ruby/internal/intern/re.h
+sha2.o: $(hdrdir)/ruby/internal/intern/ruby.h
+sha2.o: $(hdrdir)/ruby/internal/intern/select.h
+sha2.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+sha2.o: $(hdrdir)/ruby/internal/intern/signal.h
+sha2.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+sha2.o: $(hdrdir)/ruby/internal/intern/string.h
+sha2.o: $(hdrdir)/ruby/internal/intern/struct.h
+sha2.o: $(hdrdir)/ruby/internal/intern/thread.h
+sha2.o: $(hdrdir)/ruby/internal/intern/time.h
+sha2.o: $(hdrdir)/ruby/internal/intern/variable.h
+sha2.o: $(hdrdir)/ruby/internal/intern/vm.h
+sha2.o: $(hdrdir)/ruby/internal/interpreter.h
+sha2.o: $(hdrdir)/ruby/internal/iterator.h
+sha2.o: $(hdrdir)/ruby/internal/memory.h
+sha2.o: $(hdrdir)/ruby/internal/method.h
+sha2.o: $(hdrdir)/ruby/internal/module.h
+sha2.o: $(hdrdir)/ruby/internal/newobj.h
+sha2.o: $(hdrdir)/ruby/internal/rgengc.h
+sha2.o: $(hdrdir)/ruby/internal/scan_args.h
+sha2.o: $(hdrdir)/ruby/internal/special_consts.h
+sha2.o: $(hdrdir)/ruby/internal/static_assert.h
+sha2.o: $(hdrdir)/ruby/internal/stdalign.h
+sha2.o: $(hdrdir)/ruby/internal/stdbool.h
+sha2.o: $(hdrdir)/ruby/internal/symbol.h
+sha2.o: $(hdrdir)/ruby/internal/token_paste.h
+sha2.o: $(hdrdir)/ruby/internal/value.h
+sha2.o: $(hdrdir)/ruby/internal/value_type.h
+sha2.o: $(hdrdir)/ruby/internal/variable.h
+sha2.o: $(hdrdir)/ruby/internal/warning_push.h
+sha2.o: $(hdrdir)/ruby/internal/xmalloc.h
+sha2.o: $(hdrdir)/ruby/missing.h
+sha2.o: $(hdrdir)/ruby/ruby.h
+sha2.o: $(hdrdir)/ruby/st.h
+sha2.o: $(hdrdir)/ruby/subst.h
+sha2.o: $(srcdir)/../defs.h
+sha2.o: sha2.c
+sha2.o: sha2.h
sha2init.o: $(RUBY_EXTCONF_H)
sha2init.o: $(arch_hdrdir)/ruby/config.h
+sha2init.o: $(hdrdir)/ruby.h
+sha2init.o: $(hdrdir)/ruby/assert.h
sha2init.o: $(hdrdir)/ruby/backward.h
+sha2init.o: $(hdrdir)/ruby/backward/2/assume.h
+sha2init.o: $(hdrdir)/ruby/backward/2/attributes.h
+sha2init.o: $(hdrdir)/ruby/backward/2/bool.h
+sha2init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+sha2init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+sha2init.o: $(hdrdir)/ruby/backward/2/limits.h
+sha2init.o: $(hdrdir)/ruby/backward/2/long_long.h
+sha2init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+sha2init.o: $(hdrdir)/ruby/backward/2/stdarg.h
sha2init.o: $(hdrdir)/ruby/defines.h
sha2init.o: $(hdrdir)/ruby/intern.h
+sha2init.o: $(hdrdir)/ruby/internal/anyargs.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+sha2init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+sha2init.o: $(hdrdir)/ruby/internal/assume.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/cold.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/const.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/error.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/format.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/pure.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/warning.h
+sha2init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+sha2init.o: $(hdrdir)/ruby/internal/cast.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_is.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+sha2init.o: $(hdrdir)/ruby/internal/compiler_since.h
+sha2init.o: $(hdrdir)/ruby/internal/config.h
+sha2init.o: $(hdrdir)/ruby/internal/constant_p.h
+sha2init.o: $(hdrdir)/ruby/internal/core.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rarray.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rclass.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rdata.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rfile.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rhash.h
+sha2init.o: $(hdrdir)/ruby/internal/core/robject.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rstring.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+sha2init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+sha2init.o: $(hdrdir)/ruby/internal/ctype.h
+sha2init.o: $(hdrdir)/ruby/internal/dllexport.h
+sha2init.o: $(hdrdir)/ruby/internal/dosish.h
+sha2init.o: $(hdrdir)/ruby/internal/error.h
+sha2init.o: $(hdrdir)/ruby/internal/eval.h
+sha2init.o: $(hdrdir)/ruby/internal/event.h
+sha2init.o: $(hdrdir)/ruby/internal/fl_type.h
+sha2init.o: $(hdrdir)/ruby/internal/gc.h
+sha2init.o: $(hdrdir)/ruby/internal/glob.h
+sha2init.o: $(hdrdir)/ruby/internal/globals.h
+sha2init.o: $(hdrdir)/ruby/internal/has/attribute.h
+sha2init.o: $(hdrdir)/ruby/internal/has/builtin.h
+sha2init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+sha2init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+sha2init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+sha2init.o: $(hdrdir)/ruby/internal/has/extension.h
+sha2init.o: $(hdrdir)/ruby/internal/has/feature.h
+sha2init.o: $(hdrdir)/ruby/internal/has/warning.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/array.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/class.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/compar.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/complex.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/cont.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/dir.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/enum.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/error.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/eval.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/file.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/gc.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/hash.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/io.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/load.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/object.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/parse.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/proc.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/process.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/random.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/range.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/rational.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/re.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/select.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/signal.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/string.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/struct.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/thread.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/time.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/variable.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/vm.h
+sha2init.o: $(hdrdir)/ruby/internal/interpreter.h
+sha2init.o: $(hdrdir)/ruby/internal/iterator.h
+sha2init.o: $(hdrdir)/ruby/internal/memory.h
+sha2init.o: $(hdrdir)/ruby/internal/method.h
+sha2init.o: $(hdrdir)/ruby/internal/module.h
+sha2init.o: $(hdrdir)/ruby/internal/newobj.h
+sha2init.o: $(hdrdir)/ruby/internal/rgengc.h
+sha2init.o: $(hdrdir)/ruby/internal/scan_args.h
+sha2init.o: $(hdrdir)/ruby/internal/special_consts.h
+sha2init.o: $(hdrdir)/ruby/internal/static_assert.h
+sha2init.o: $(hdrdir)/ruby/internal/stdalign.h
+sha2init.o: $(hdrdir)/ruby/internal/stdbool.h
+sha2init.o: $(hdrdir)/ruby/internal/symbol.h
+sha2init.o: $(hdrdir)/ruby/internal/token_paste.h
+sha2init.o: $(hdrdir)/ruby/internal/value.h
+sha2init.o: $(hdrdir)/ruby/internal/value_type.h
+sha2init.o: $(hdrdir)/ruby/internal/variable.h
+sha2init.o: $(hdrdir)/ruby/internal/warning_push.h
+sha2init.o: $(hdrdir)/ruby/internal/xmalloc.h
sha2init.o: $(hdrdir)/ruby/missing.h
sha2init.o: $(hdrdir)/ruby/ruby.h
sha2init.o: $(hdrdir)/ruby/st.h
sha2init.o: $(hdrdir)/ruby/subst.h
-sha2init.o: $(top_srcdir)/ext/digest/digest.h
-sha2init.o: $(top_srcdir)/include/ruby.h
+sha2init.o: $(srcdir)/../digest.h
+sha2init.o: sha2.h
sha2init.o: sha2init.c
-sha2init.o: sha2ossl.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/digest/sha2/extconf.rb b/ext/digest/sha2/extconf.rb
index 5c7f76c7f3..8bf28111b6 100644
--- a/ext/digest/sha2/extconf.rb
+++ b/ext/digest/sha2/extconf.rb
@@ -10,7 +10,7 @@ $defs << "-DHAVE_CONFIG_H"
$objs = [ "sha2init.#{$OBJEXT}" ]
-unless digest_conf("sha2", "sha", %w[SHA256 SHA512])
+unless digest_conf("sha2")
have_type("u_int8_t")
end
diff --git a/ext/digest/sha2/sha2init.c b/ext/digest/sha2/sha2init.c
index 9fd8ece7fe..6ed275eb71 100644
--- a/ext/digest/sha2/sha2init.c
+++ b/ext/digest/sha2/sha2init.c
@@ -3,9 +3,7 @@
#include <ruby/ruby.h>
#include "../digest.h"
-#if defined(SHA2_USE_OPENSSL)
-#include "sha2ossl.h"
-#elif defined(SHA2_USE_COMMONDIGEST)
+#if defined(SHA2_USE_COMMONDIGEST)
#include "sha2cc.h"
#else
#include "sha2.h"
@@ -35,27 +33,21 @@ void
Init_sha2(void)
{
VALUE mDigest, cDigest_Base;
- ID id_metadata;
+ ID id_metadata = rb_id_metadata();
#define DECLARE_ALGO_CLASS(bitlen) \
VALUE cDigest_SHA##bitlen;
FOREACH_BITLEN(DECLARE_ALGO_CLASS)
- rb_require("digest");
-
- id_metadata = rb_intern_const("metadata");
-
- mDigest = rb_path2class("Digest");
+ mDigest = rb_digest_namespace();
cDigest_Base = rb_path2class("Digest::Base");
#define DEFINE_ALGO_CLASS(bitlen) \
cDigest_SHA##bitlen = rb_define_class_under(mDigest, "SHA" #bitlen, cDigest_Base); \
\
rb_ivar_set(cDigest_SHA##bitlen, id_metadata, \
- Data_Wrap_Struct(0, 0, 0, (void *)&sha##bitlen));
+ rb_digest_make_metadata(&sha##bitlen));
-#undef RUBY_UNTYPED_DATA_WARNING
-#define RUBY_UNTYPED_DATA_WARNING 0
FOREACH_BITLEN(DEFINE_ALGO_CLASS)
}
diff --git a/ext/digest/sha2/sha2ossl.h b/ext/digest/sha2/sha2ossl.h
deleted file mode 100644
index 8dd0530107..0000000000
--- a/ext/digest/sha2/sha2ossl.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef SHA2OSSL_H_INCLUDED
-#define SHA2OSSL_H_INCLUDED
-
-#include <stddef.h>
-#include <openssl/sha.h>
-
-#define SHA256_BLOCK_LENGTH SHA256_CBLOCK
-#define SHA384_BLOCK_LENGTH SHA512_CBLOCK
-#define SHA512_BLOCK_LENGTH SHA512_CBLOCK
-
-#ifndef __DragonFly__
-#define SHA384_Final SHA512_Final
-#endif
-
-typedef SHA512_CTX SHA384_CTX;
-
-#undef SHA256_Finish
-#undef SHA384_Finish
-#undef SHA512_Finish
-#define SHA256_Finish rb_digest_SHA256_finish
-#define SHA384_Finish rb_digest_SHA384_finish
-#define SHA512_Finish rb_digest_SHA512_finish
-static DEFINE_FINISH_FUNC_FROM_FINAL(SHA256)
-static DEFINE_FINISH_FUNC_FROM_FINAL(SHA384)
-static DEFINE_FINISH_FUNC_FROM_FINAL(SHA512)
-
-#endif
diff --git a/ext/etc/depend b/ext/etc/depend
index 2d986c5913..67d9be582f 100644
--- a/ext/etc/depend
+++ b/ext/etc/depend
@@ -5,10 +5,162 @@ constdefs.h : $(srcdir)/mkconstants.rb
# AUTOGENERATED DEPENDENCIES START
etc.o: $(RUBY_EXTCONF_H)
etc.o: $(arch_hdrdir)/ruby/config.h
+etc.o: $(hdrdir)/ruby.h
+etc.o: $(hdrdir)/ruby/assert.h
+etc.o: $(hdrdir)/ruby/atomic.h
etc.o: $(hdrdir)/ruby/backward.h
+etc.o: $(hdrdir)/ruby/backward/2/assume.h
+etc.o: $(hdrdir)/ruby/backward/2/attributes.h
+etc.o: $(hdrdir)/ruby/backward/2/bool.h
+etc.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+etc.o: $(hdrdir)/ruby/backward/2/inttypes.h
+etc.o: $(hdrdir)/ruby/backward/2/limits.h
+etc.o: $(hdrdir)/ruby/backward/2/long_long.h
+etc.o: $(hdrdir)/ruby/backward/2/stdalign.h
+etc.o: $(hdrdir)/ruby/backward/2/stdarg.h
etc.o: $(hdrdir)/ruby/defines.h
etc.o: $(hdrdir)/ruby/encoding.h
etc.o: $(hdrdir)/ruby/intern.h
+etc.o: $(hdrdir)/ruby/internal/anyargs.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+etc.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+etc.o: $(hdrdir)/ruby/internal/assume.h
+etc.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+etc.o: $(hdrdir)/ruby/internal/attr/artificial.h
+etc.o: $(hdrdir)/ruby/internal/attr/cold.h
+etc.o: $(hdrdir)/ruby/internal/attr/const.h
+etc.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+etc.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+etc.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+etc.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+etc.o: $(hdrdir)/ruby/internal/attr/error.h
+etc.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+etc.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+etc.o: $(hdrdir)/ruby/internal/attr/format.h
+etc.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+etc.o: $(hdrdir)/ruby/internal/attr/noalias.h
+etc.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+etc.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+etc.o: $(hdrdir)/ruby/internal/attr/noinline.h
+etc.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+etc.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+etc.o: $(hdrdir)/ruby/internal/attr/pure.h
+etc.o: $(hdrdir)/ruby/internal/attr/restrict.h
+etc.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+etc.o: $(hdrdir)/ruby/internal/attr/warning.h
+etc.o: $(hdrdir)/ruby/internal/attr/weakref.h
+etc.o: $(hdrdir)/ruby/internal/cast.h
+etc.o: $(hdrdir)/ruby/internal/compiler_is.h
+etc.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+etc.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+etc.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+etc.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+etc.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+etc.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+etc.o: $(hdrdir)/ruby/internal/compiler_since.h
+etc.o: $(hdrdir)/ruby/internal/config.h
+etc.o: $(hdrdir)/ruby/internal/constant_p.h
+etc.o: $(hdrdir)/ruby/internal/core.h
+etc.o: $(hdrdir)/ruby/internal/core/rarray.h
+etc.o: $(hdrdir)/ruby/internal/core/rbasic.h
+etc.o: $(hdrdir)/ruby/internal/core/rbignum.h
+etc.o: $(hdrdir)/ruby/internal/core/rclass.h
+etc.o: $(hdrdir)/ruby/internal/core/rdata.h
+etc.o: $(hdrdir)/ruby/internal/core/rfile.h
+etc.o: $(hdrdir)/ruby/internal/core/rhash.h
+etc.o: $(hdrdir)/ruby/internal/core/robject.h
+etc.o: $(hdrdir)/ruby/internal/core/rregexp.h
+etc.o: $(hdrdir)/ruby/internal/core/rstring.h
+etc.o: $(hdrdir)/ruby/internal/core/rstruct.h
+etc.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+etc.o: $(hdrdir)/ruby/internal/ctype.h
+etc.o: $(hdrdir)/ruby/internal/dllexport.h
+etc.o: $(hdrdir)/ruby/internal/dosish.h
+etc.o: $(hdrdir)/ruby/internal/error.h
+etc.o: $(hdrdir)/ruby/internal/eval.h
+etc.o: $(hdrdir)/ruby/internal/event.h
+etc.o: $(hdrdir)/ruby/internal/fl_type.h
+etc.o: $(hdrdir)/ruby/internal/gc.h
+etc.o: $(hdrdir)/ruby/internal/glob.h
+etc.o: $(hdrdir)/ruby/internal/globals.h
+etc.o: $(hdrdir)/ruby/internal/has/attribute.h
+etc.o: $(hdrdir)/ruby/internal/has/builtin.h
+etc.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+etc.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+etc.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+etc.o: $(hdrdir)/ruby/internal/has/extension.h
+etc.o: $(hdrdir)/ruby/internal/has/feature.h
+etc.o: $(hdrdir)/ruby/internal/has/warning.h
+etc.o: $(hdrdir)/ruby/internal/intern/array.h
+etc.o: $(hdrdir)/ruby/internal/intern/bignum.h
+etc.o: $(hdrdir)/ruby/internal/intern/class.h
+etc.o: $(hdrdir)/ruby/internal/intern/compar.h
+etc.o: $(hdrdir)/ruby/internal/intern/complex.h
+etc.o: $(hdrdir)/ruby/internal/intern/cont.h
+etc.o: $(hdrdir)/ruby/internal/intern/dir.h
+etc.o: $(hdrdir)/ruby/internal/intern/enum.h
+etc.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+etc.o: $(hdrdir)/ruby/internal/intern/error.h
+etc.o: $(hdrdir)/ruby/internal/intern/eval.h
+etc.o: $(hdrdir)/ruby/internal/intern/file.h
+etc.o: $(hdrdir)/ruby/internal/intern/gc.h
+etc.o: $(hdrdir)/ruby/internal/intern/hash.h
+etc.o: $(hdrdir)/ruby/internal/intern/io.h
+etc.o: $(hdrdir)/ruby/internal/intern/load.h
+etc.o: $(hdrdir)/ruby/internal/intern/marshal.h
+etc.o: $(hdrdir)/ruby/internal/intern/numeric.h
+etc.o: $(hdrdir)/ruby/internal/intern/object.h
+etc.o: $(hdrdir)/ruby/internal/intern/parse.h
+etc.o: $(hdrdir)/ruby/internal/intern/proc.h
+etc.o: $(hdrdir)/ruby/internal/intern/process.h
+etc.o: $(hdrdir)/ruby/internal/intern/random.h
+etc.o: $(hdrdir)/ruby/internal/intern/range.h
+etc.o: $(hdrdir)/ruby/internal/intern/rational.h
+etc.o: $(hdrdir)/ruby/internal/intern/re.h
+etc.o: $(hdrdir)/ruby/internal/intern/ruby.h
+etc.o: $(hdrdir)/ruby/internal/intern/select.h
+etc.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+etc.o: $(hdrdir)/ruby/internal/intern/signal.h
+etc.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+etc.o: $(hdrdir)/ruby/internal/intern/string.h
+etc.o: $(hdrdir)/ruby/internal/intern/struct.h
+etc.o: $(hdrdir)/ruby/internal/intern/thread.h
+etc.o: $(hdrdir)/ruby/internal/intern/time.h
+etc.o: $(hdrdir)/ruby/internal/intern/variable.h
+etc.o: $(hdrdir)/ruby/internal/intern/vm.h
+etc.o: $(hdrdir)/ruby/internal/interpreter.h
+etc.o: $(hdrdir)/ruby/internal/iterator.h
+etc.o: $(hdrdir)/ruby/internal/memory.h
+etc.o: $(hdrdir)/ruby/internal/method.h
+etc.o: $(hdrdir)/ruby/internal/module.h
+etc.o: $(hdrdir)/ruby/internal/newobj.h
+etc.o: $(hdrdir)/ruby/internal/rgengc.h
+etc.o: $(hdrdir)/ruby/internal/scan_args.h
+etc.o: $(hdrdir)/ruby/internal/special_consts.h
+etc.o: $(hdrdir)/ruby/internal/static_assert.h
+etc.o: $(hdrdir)/ruby/internal/stdalign.h
+etc.o: $(hdrdir)/ruby/internal/stdbool.h
+etc.o: $(hdrdir)/ruby/internal/symbol.h
+etc.o: $(hdrdir)/ruby/internal/token_paste.h
+etc.o: $(hdrdir)/ruby/internal/value.h
+etc.o: $(hdrdir)/ruby/internal/value_type.h
+etc.o: $(hdrdir)/ruby/internal/variable.h
+etc.o: $(hdrdir)/ruby/internal/warning_push.h
+etc.o: $(hdrdir)/ruby/internal/xmalloc.h
etc.o: $(hdrdir)/ruby/io.h
etc.o: $(hdrdir)/ruby/missing.h
etc.o: $(hdrdir)/ruby/onigmo.h
@@ -16,7 +168,6 @@ etc.o: $(hdrdir)/ruby/oniguruma.h
etc.o: $(hdrdir)/ruby/ruby.h
etc.o: $(hdrdir)/ruby/st.h
etc.o: $(hdrdir)/ruby/subst.h
-etc.o: $(top_srcdir)/include/ruby.h
etc.o: constdefs.h
etc.o: etc.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index 46857c62c7..737d295abc 100644
--- a/ext/etc/etc.c
+++ b/ext/etc/etc.c
@@ -52,8 +52,33 @@ char *getenv();
#endif
char *getlogin();
+#define RUBY_ETC_VERSION "1.3.0"
+
+#ifdef HAVE_RB_DEPRECATE_CONSTANT
+void rb_deprecate_constant(VALUE mod, const char *name);
+#else
+# define rb_deprecate_constant(mod,name) ((void)(mod),(void)(name))
+#endif
+
#include "constdefs.h"
+#ifdef HAVE_RUBY_ATOMIC_H
+# include "ruby/atomic.h"
+#else
+typedef int rb_atomic_t;
+# define RUBY_ATOMIC_CAS(var, oldval, newval) \
+ ((var) == (oldval) ? ((var) = (newval), (oldval)) : (var))
+# define RUBY_ATOMIC_EXCHANGE(var, newval) \
+ atomic_exchange(&var, newval)
+static inline rb_atomic_t
+atomic_exchange(volatile rb_atomic_t *var, rb_atomic_t newval)
+{
+ rb_atomic_t oldval = *var;
+ *var = newval;
+ return oldval;
+}
+#endif
+
/* call-seq:
* getlogin -> String
*
@@ -98,7 +123,7 @@ static VALUE
safe_setup_str(const char *str)
{
if (str == 0) str = "";
- return rb_tainted_str_new2(str);
+ return rb_str_new2(str);
}
static VALUE
@@ -117,6 +142,12 @@ safe_setup_filesystem_str(const char *str)
#endif
#ifdef HAVE_GETPWENT
+# ifdef __APPLE__
+# define PW_TIME2VAL(t) INT2NUM((int)(t))
+# else
+# define PW_TIME2VAL(t) TIMET2NUM(t)
+# endif
+
static VALUE
setup_passwd(struct passwd *pwd)
{
@@ -134,7 +165,7 @@ setup_passwd(struct passwd *pwd)
safe_setup_filesystem_str(pwd->pw_dir),
safe_setup_filesystem_str(pwd->pw_shell),
#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
- INT2NUM(pwd->pw_change),
+ PW_TIME2VAL(pwd->pw_change),
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_QUOTA
INT2NUM(pwd->pw_quota),
@@ -149,7 +180,7 @@ setup_passwd(struct passwd *pwd)
safe_setup_locale_str(pwd->pw_comment),
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
- INT2NUM(pwd->pw_expire),
+ PW_TIME2VAL(pwd->pw_expire),
#endif
0 /*dummy*/
);
@@ -217,7 +248,6 @@ etc_getpwnam(VALUE obj, VALUE nam)
struct passwd *pwd;
const char *p = StringValueCStr(nam);
- rb_check_safe_obj(nam);
pwd = getpwnam(p);
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam);
return setup_passwd(pwd);
@@ -227,17 +257,19 @@ etc_getpwnam(VALUE obj, VALUE nam)
}
#ifdef HAVE_GETPWENT
-static int passwd_blocking = 0;
+static rb_atomic_t passwd_blocking;
static VALUE
-passwd_ensure(void)
+passwd_ensure(VALUE _)
{
endpwent();
- passwd_blocking = (int)Qfalse;
+ if (RUBY_ATOMIC_EXCHANGE(passwd_blocking, 0) != 1) {
+ rb_raise(rb_eRuntimeError, "unexpected passwd_blocking");
+ }
return Qnil;
}
static VALUE
-passwd_iterate(void)
+passwd_iterate(VALUE _)
{
struct passwd *pw;
@@ -251,10 +283,9 @@ passwd_iterate(void)
static void
each_passwd(void)
{
- if (passwd_blocking) {
+ if (RUBY_ATOMIC_CAS(passwd_blocking, 0, 1)) {
rb_raise(rb_eRuntimeError, "parallel passwd iteration");
}
- passwd_blocking = (int)Qtrue;
rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
}
#endif
@@ -461,7 +492,6 @@ etc_getgrnam(VALUE obj, VALUE nam)
struct group *grp;
const char *p = StringValueCStr(nam);
- rb_check_safe_obj(nam);
grp = getgrnam(p);
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam);
return setup_group(grp);
@@ -471,18 +501,20 @@ etc_getgrnam(VALUE obj, VALUE nam)
}
#ifdef HAVE_GETGRENT
-static int group_blocking = 0;
+static rb_atomic_t group_blocking;
static VALUE
-group_ensure(void)
+group_ensure(VALUE _)
{
endgrent();
- group_blocking = (int)Qfalse;
+ if (RUBY_ATOMIC_EXCHANGE(group_blocking, 0) != 1) {
+ rb_raise(rb_eRuntimeError, "unexpected group_blocking");
+ }
return Qnil;
}
static VALUE
-group_iterate(void)
+group_iterate(VALUE _)
{
struct group *pw;
@@ -496,10 +528,9 @@ group_iterate(void)
static void
each_group(void)
{
- if (group_blocking) {
+ if (RUBY_ATOMIC_CAS(group_blocking, 0, 1)) {
rb_raise(rb_eRuntimeError, "parallel group iteration");
}
- group_blocking = (int)Qtrue;
rb_ensure(group_iterate, 0, group_ensure, 0);
}
#endif
@@ -627,8 +658,9 @@ VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
* Returns system configuration directory.
*
* This is typically "/etc", but is modified by the prefix used when Ruby was
- * compiled. For example, if Ruby is built and installed in /usr/local, returns
- * "/usr/local/etc".
+ * compiled. For example, if Ruby is built and installed in /usr/local,
+ * returns "/usr/local/etc" on other platforms than Windows.
+ * On Windows, this always returns the directory provided by the system.
*/
static VALUE
etc_sysconfdir(VALUE obj)
@@ -644,7 +676,7 @@ etc_sysconfdir(VALUE obj)
* Returns system temporary directory; typically "/tmp".
*/
static VALUE
-etc_systmpdir(void)
+etc_systmpdir(VALUE _)
{
VALUE tmpdir;
#ifdef _WIN32
@@ -676,7 +708,10 @@ etc_systmpdir(void)
}
# endif
#endif
+#ifndef RB_PASS_KEYWORDS
+ /* untaint on Ruby < 2.7 */
FL_UNSET(tmpdir, FL_TAINT);
+#endif
return tmpdir;
}
@@ -753,9 +788,6 @@ etc_uname(VALUE obj)
# ifndef PROCESSOR_ARCHITECTURE_AMD64
# define PROCESSOR_ARCHITECTURE_AMD64 9
# endif
-# ifndef PROCESSOR_ARCHITECTURE_IA64
-# define PROCESSOR_ARCHITECTURE_IA64 6
-# endif
# ifndef PROCESSOR_ARCHITECTURE_INTEL
# define PROCESSOR_ARCHITECTURE_INTEL 0
# endif
@@ -767,9 +799,6 @@ etc_uname(VALUE obj)
case PROCESSOR_ARCHITECTURE_ARM:
mach = "ARM";
break;
- case PROCESSOR_ARCHITECTURE_IA64:
- mach = "IA64";
- break;
case PROCESSOR_ARCHITECTURE_INTEL:
mach = "x86";
break;
@@ -928,11 +957,13 @@ io_pathconf(VALUE io, VALUE arg)
static int
etc_nprocessors_affin(void)
{
- cpu_set_t *cpuset;
+ cpu_set_t *cpuset, cpuset_buff[1024 / sizeof(cpu_set_t)];
size_t size;
int ret;
int n;
+ CPU_ZERO_S(sizeof(cpuset_buff), cpuset_buff);
+
/*
* XXX:
* man page says CPU_ALLOC takes number of cpus. But it is not accurate
@@ -951,13 +982,12 @@ etc_nprocessors_affin(void)
*/
for (n=64; n <= 16384; n *= 2) {
size = CPU_ALLOC_SIZE(n);
- if (size >= 1024) {
+ if (size >= sizeof(cpuset_buff)) {
cpuset = xcalloc(1, size);
if (!cpuset)
return -1;
} else {
- cpuset = alloca(size);
- CPU_ZERO_S(size, cpuset);
+ cpuset = cpuset_buff;
}
ret = sched_getaffinity(0, size, cpuset);
@@ -966,10 +996,10 @@ etc_nprocessors_affin(void)
ret = CPU_COUNT_S(size, cpuset);
}
- if (size >= 1024) {
+ if (size >= sizeof(cpuset_buff)) {
xfree(cpuset);
}
- if (ret > 0) {
+ if (ret > 0 || errno != EINVAL) {
return ret;
}
}
@@ -1066,7 +1096,11 @@ Init_etc(void)
{
VALUE mEtc;
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
+ RB_EXT_RACTOR_SAFE(true);
+ #endif
mEtc = rb_define_module("Etc");
+ rb_define_const(mEtc, "VERSION", rb_str_new_cstr(RUBY_ETC_VERSION));
init_constants(mEtc);
rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);
@@ -1166,9 +1200,9 @@ Init_etc(void)
rb_define_const(mEtc, "Passwd", sPasswd);
#endif
rb_define_const(rb_cStruct, "Passwd", sPasswd); /* deprecated name */
+ rb_deprecate_constant(rb_cStruct, "Passwd");
rb_extend_object(sPasswd, rb_mEnumerable);
rb_define_singleton_method(sPasswd, "each", etc_each_passwd, 0);
-
#ifdef HAVE_GETGRENT
sGroup = rb_struct_define_under(mEtc, "Group", "name",
#ifdef HAVE_STRUCT_GROUP_GR_PASSWD
@@ -1201,6 +1235,7 @@ Init_etc(void)
rb_define_const(mEtc, "Group", sGroup);
#endif
rb_define_const(rb_cStruct, "Group", sGroup); /* deprecated name */
+ rb_deprecate_constant(rb_cStruct, "Group");
rb_extend_object(sGroup, rb_mEnumerable);
rb_define_singleton_method(sGroup, "each", etc_each_group, 0);
#endif
diff --git a/ext/etc/etc.gemspec b/ext/etc/etc.gemspec
index 5bbaf0e017..7d687e3b99 100644
--- a/ext/etc/etc.gemspec
+++ b/ext/etc/etc.gemspec
@@ -1,39 +1,41 @@
-# coding: utf-8
# frozen_string_literal: true
+version = ["", "ext/etc/"].find do |dir|
+ begin
+ break File.open(File.expand_path("../#{dir}/etc.c", __FILE__)) do |f|
+ f.gets "\n#define RUBY_ETC_VERSION "
+ f.gets[/"(.+)"/, 1]
+ end
+ rescue
+ next
+ end
+end
+
Gem::Specification.new do |spec|
spec.name = "etc"
- spec.version = "0.2.1"
- spec.date = '2017-02-27'
+ spec.version = version
spec.authors = ["Yukihiro Matsumoto"]
spec.email = ["matz@ruby-lang.org"]
spec.summary = %q{Provides access to information typically stored in UNIX /etc directory.}
- spec.description = %q{Provides access to information typically stored in UNIX /etc directory.}
+ spec.description = spec.summary
spec.homepage = "https://github.com/ruby/etc"
- spec.license = "BSD-2-Clause"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.files = %w[
- .gitignore
- .travis.yml
- Gemfile
LICENSE.txt
README.md
- Rakefile
- bin/console
- bin/setup
- etc.gemspec
+ ext/etc/constdefs.h
ext/etc/etc.c
ext/etc/extconf.rb
ext/etc/mkconstants.rb
test/etc/test_etc.rb
]
spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.extensions = %w{ext/etc/extconf.rb}
- spec.required_ruby_version = ">= 2.5.0dev"
+ spec.required_ruby_version = ">= 2.3.0"
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
diff --git a/ext/etc/extconf.rb b/ext/etc/extconf.rb
index 1e679b5d0b..6e7810a5e8 100644
--- a/ext/etc/extconf.rb
+++ b/ext/etc/extconf.rb
@@ -12,8 +12,10 @@ have_func("uname((struct utsname *)NULL)", headers)
have_func("getlogin")
have_func("getpwent")
have_func("getgrent")
-sysconfdir = RbConfig.expand(RbConfig::CONFIG["sysconfdir"].dup, "prefix"=>"", "DESTDIR"=>"")
-$defs.push("-DSYSCONFDIR=#{Shellwords.escape(sysconfdir.dump)}")
+if (sysconfdir = RbConfig::CONFIG["sysconfdir"] and
+ !RbConfig.expand(sysconfdir.dup, "prefix"=>"", "DESTDIR"=>"").empty?)
+ $defs.push("-DSYSCONFDIR=#{Shellwords.escape(sysconfdir.dump)}")
+end
have_func("sysconf")
have_func("confstr")
@@ -39,6 +41,14 @@ have_struct_member('struct passwd', 'pw_expire', 'pwd.h')
have_struct_member('struct passwd', 'pw_passwd', 'pwd.h')
have_struct_member('struct group', 'gr_passwd', 'grp.h')
+# for https://github.com/ruby/etc
+srcdir = File.expand_path("..", __FILE__)
+if !File.exist?("#{srcdir}/depend")
+ %x[#{RbConfig.ruby} #{srcdir}/mkconstants.rb -o #{srcdir}/constdefs.h]
+end
+
+have_func('rb_deprecate_constant(Qnil, "None")')
+
$distcleanfiles << "constdefs.h"
create_makefile("etc")
diff --git a/ext/etc/mkconstants.rb b/ext/etc/mkconstants.rb
index 18f34c9875..a752d64519 100644
--- a/ext/etc/mkconstants.rb
+++ b/ext/etc/mkconstants.rb
@@ -66,7 +66,15 @@ def each_name(pat)
}
end
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
+erb_new = lambda do |src, safe, trim|
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
+ ERB.new(src, trim_mode: trim)
+ else
+ ERB.new(src, safe, trim)
+ end
+end
+
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
% each_const {|name, default_value|
#if !defined(<%=name%>)
# if defined(HAVE_CONST_<%=name.upcase%>)
@@ -80,7 +88,7 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
% }
EOS
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
% each_const {|name, default_value|
#if defined(<%=name%>)
% if comment = COMMENTS[name]
@@ -91,13 +99,13 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
% }
EOS
-header_result = ERB.new(<<'EOS', nil, '%').result(binding)
+header_result = erb_new.call(<<'EOS', nil, '%').result(binding)
/* autogenerated file */
<%= gen_const_decls %>
EOS
-result = ERB.new(<<'EOS', nil, '%').result(binding)
+result = erb_new.call(<<'EOS', nil, '%').result(binding)
/* autogenerated file */
#ifdef HAVE_LONG_LONG
diff --git a/ext/extmk.rb b/ext/extmk.rb
index e83a0e5d8c..97f1ad9c39 100755
--- a/ext/extmk.rb
+++ b/ext/extmk.rb
@@ -408,8 +408,10 @@ if CROSS_COMPILING
$ruby = $mflags.defined?("MINIRUBY") || CONFIG['MINIRUBY']
elsif sep = config_string('BUILD_FILE_SEPARATOR')
$ruby = "$(topdir:/=#{sep})#{sep}miniruby" + EXEEXT
-else
+elsif CONFIG['EXTSTATIC']
$ruby = '$(topdir)/miniruby' + EXEEXT
+else
+ $ruby = '$(topdir)/ruby' + EXEEXT
end
$ruby = [$ruby]
$ruby << "-I'$(topdir)'"
@@ -421,6 +423,7 @@ end
topruby = $ruby
$ruby = topruby.join(' ')
$mflags << "ruby=#$ruby"
+$builtruby = '$(topdir)/miniruby' + EXEEXT # Must be an executable path
MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)}
@@ -463,7 +466,11 @@ end unless $extstatic
if ARGV[0]
ext_prefix, exts = ARGV.shift.split('/', 2)
$extension = [exts] if exts
- @gemname = exts if ext_prefix == 'gems'
+ if ext_prefix == 'gems'
+ @gemname = exts
+ elsif exts
+ $static_ext.delete_if {|t, *| !File.fnmatch(t, exts)}
+ end
end
ext_prefix = "#{$top_srcdir}/#{ext_prefix || 'ext'}"
exts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t}
@@ -496,13 +503,17 @@ cond = proc {|ext, *|
}
($extension || %w[*]).each do |e|
e = e.sub(/\A(?:\.\/)+/, '')
- exts |= Dir.glob("#{ext_prefix}/#{e}/**/extconf.rb").collect {|d|
+ incl, excl = Dir.glob("#{ext_prefix}/#{e}/**/extconf.rb").collect {|d|
d = File.dirname(d)
d.slice!(0, ext_prefix.length + 1)
d
- }.find_all {|ext|
+ }.partition {|ext|
with_config(ext, &cond)
- }.sort
+ }
+ incl.sort!
+ excl.sort!.collect! {|d| d+"/"}
+ nil while incl.reject! {|d| excl << d+"/" if excl.any? {|x| d.start_with?(x)}}
+ exts |= incl
if $LIBRUBYARG_SHARED.empty? and CONFIG["EXTSTATIC"] == "static"
exts.delete_if {|d| File.fnmatch?("-*", d)}
end
@@ -684,8 +695,8 @@ begin
submakeopts << 'UPDATE_LIBRARIES="$(UPDATE_LIBRARIES)"'
submakeopts << 'SHOWFLAGS='
mf.macro "SUBMAKEOPTS", submakeopts
- mf.macro "NOTE_MESG", %w[$(RUBY) $(top_srcdir)/tool/colorize.rb skip]
- mf.macro "NOTE_NAME", %w[$(RUBY) $(top_srcdir)/tool/colorize.rb fail]
+ mf.macro "NOTE_MESG", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb skip]
+ mf.macro "NOTE_NAME", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb fail]
mf.puts
targets = %w[all install static install-so install-rb clean distclean realclean]
targets.each do |tgt|
@@ -718,7 +729,16 @@ begin
end
targets.each do |tgt|
exts.each do |d|
- mf.puts "#{d[0..-2]}#{tgt}:\n\t$(Q)#{submake} $(MFLAGS) V=$(V) $(@F)"
+ d = d[0..-2]
+ t = "#{d}#{tgt}"
+ if /^(dist|real)?clean$/ =~ tgt
+ deps = exts.select {|e|e.start_with?(d)}.map {|e|"#{e[0..-2]}#{tgt}"} - [t]
+ pd = ' ' + deps.join(' ') unless deps.empty?
+ else
+ pext = File.dirname(d)
+ pd = " #{pext}/#{tgt}" if exts.include?("#{pext}/.")
+ end
+ mf.puts "#{t}:#{pd}\n\t$(Q)#{submake} $(MFLAGS) V=$(V) $(@F)"
end
end
mf.puts "\n""extso:\n"
diff --git a/ext/fcntl/depend b/ext/fcntl/depend
index 61d7dc20ee..cdaa3aa582 100644
--- a/ext/fcntl/depend
+++ b/ext/fcntl/depend
@@ -1,13 +1,163 @@
# AUTOGENERATED DEPENDENCIES START
fcntl.o: $(RUBY_EXTCONF_H)
fcntl.o: $(arch_hdrdir)/ruby/config.h
+fcntl.o: $(hdrdir)/ruby.h
+fcntl.o: $(hdrdir)/ruby/internal/anyargs.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+fcntl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+fcntl.o: $(hdrdir)/ruby/internal/assume.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/artificial.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/cold.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/const.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/error.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/format.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/noalias.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/noinline.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/pure.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/restrict.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/warning.h
+fcntl.o: $(hdrdir)/ruby/internal/attr/weakref.h
+fcntl.o: $(hdrdir)/ruby/internal/cast.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_is.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+fcntl.o: $(hdrdir)/ruby/internal/compiler_since.h
+fcntl.o: $(hdrdir)/ruby/internal/config.h
+fcntl.o: $(hdrdir)/ruby/internal/constant_p.h
+fcntl.o: $(hdrdir)/ruby/internal/core.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rarray.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rbasic.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rbignum.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rclass.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rdata.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rfile.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rhash.h
+fcntl.o: $(hdrdir)/ruby/internal/core/robject.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rregexp.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rstring.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rstruct.h
+fcntl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+fcntl.o: $(hdrdir)/ruby/internal/ctype.h
+fcntl.o: $(hdrdir)/ruby/internal/dllexport.h
+fcntl.o: $(hdrdir)/ruby/internal/dosish.h
+fcntl.o: $(hdrdir)/ruby/internal/error.h
+fcntl.o: $(hdrdir)/ruby/internal/eval.h
+fcntl.o: $(hdrdir)/ruby/internal/event.h
+fcntl.o: $(hdrdir)/ruby/internal/fl_type.h
+fcntl.o: $(hdrdir)/ruby/internal/gc.h
+fcntl.o: $(hdrdir)/ruby/internal/glob.h
+fcntl.o: $(hdrdir)/ruby/internal/globals.h
+fcntl.o: $(hdrdir)/ruby/internal/has/attribute.h
+fcntl.o: $(hdrdir)/ruby/internal/has/builtin.h
+fcntl.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+fcntl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+fcntl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+fcntl.o: $(hdrdir)/ruby/internal/has/extension.h
+fcntl.o: $(hdrdir)/ruby/internal/has/feature.h
+fcntl.o: $(hdrdir)/ruby/internal/has/warning.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/array.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/bignum.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/class.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/compar.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/complex.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/cont.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/dir.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/enum.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/error.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/eval.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/file.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/gc.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/hash.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/io.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/load.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/marshal.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/numeric.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/object.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/parse.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/proc.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/process.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/random.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/range.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/rational.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/re.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/ruby.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/select.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/signal.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/string.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/struct.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/thread.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/time.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/variable.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/vm.h
+fcntl.o: $(hdrdir)/ruby/internal/interpreter.h
+fcntl.o: $(hdrdir)/ruby/internal/iterator.h
+fcntl.o: $(hdrdir)/ruby/internal/memory.h
+fcntl.o: $(hdrdir)/ruby/internal/method.h
+fcntl.o: $(hdrdir)/ruby/internal/module.h
+fcntl.o: $(hdrdir)/ruby/internal/newobj.h
+fcntl.o: $(hdrdir)/ruby/internal/rgengc.h
+fcntl.o: $(hdrdir)/ruby/internal/scan_args.h
+fcntl.o: $(hdrdir)/ruby/internal/special_consts.h
+fcntl.o: $(hdrdir)/ruby/internal/static_assert.h
+fcntl.o: $(hdrdir)/ruby/internal/stdalign.h
+fcntl.o: $(hdrdir)/ruby/internal/stdbool.h
+fcntl.o: $(hdrdir)/ruby/internal/symbol.h
+fcntl.o: $(hdrdir)/ruby/internal/token_paste.h
+fcntl.o: $(hdrdir)/ruby/internal/value.h
+fcntl.o: $(hdrdir)/ruby/internal/value_type.h
+fcntl.o: $(hdrdir)/ruby/internal/variable.h
+fcntl.o: $(hdrdir)/ruby/internal/warning_push.h
+fcntl.o: $(hdrdir)/ruby/internal/xmalloc.h
+fcntl.o: $(hdrdir)/ruby/assert.h
fcntl.o: $(hdrdir)/ruby/backward.h
+fcntl.o: $(hdrdir)/ruby/backward/2/assume.h
+fcntl.o: $(hdrdir)/ruby/backward/2/attributes.h
+fcntl.o: $(hdrdir)/ruby/backward/2/bool.h
+fcntl.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+fcntl.o: $(hdrdir)/ruby/backward/2/inttypes.h
+fcntl.o: $(hdrdir)/ruby/backward/2/limits.h
+fcntl.o: $(hdrdir)/ruby/backward/2/long_long.h
+fcntl.o: $(hdrdir)/ruby/backward/2/stdalign.h
+fcntl.o: $(hdrdir)/ruby/backward/2/stdarg.h
fcntl.o: $(hdrdir)/ruby/defines.h
fcntl.o: $(hdrdir)/ruby/intern.h
fcntl.o: $(hdrdir)/ruby/missing.h
fcntl.o: $(hdrdir)/ruby/ruby.h
fcntl.o: $(hdrdir)/ruby/st.h
fcntl.o: $(hdrdir)/ruby/subst.h
-fcntl.o: $(top_srcdir)/include/ruby.h
fcntl.o: fcntl.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/fcntl/fcntl.c b/ext/fcntl/fcntl.c
index 62780b78c0..ee42d2abe5 100644
--- a/ext/fcntl/fcntl.c
+++ b/ext/fcntl/fcntl.c
@@ -68,7 +68,7 @@ Init_fcntl(void)
#ifdef F_DUPFD
/* Document-const: F_DUPFD
*
- * Duplicate a file descriptor to the mimimum unused file descriptor
+ * Duplicate a file descriptor to the minimum unused file descriptor
* greater than or equal to the argument.
*
* The close-on-exec flag of the duplicated file descriptor is set.
@@ -159,6 +159,20 @@ Init_fcntl(void)
*/
rb_define_const(mFcntl, "F_WRLCK", INT2NUM(F_WRLCK));
#endif
+#ifdef F_SETPIPE_SZ
+ /* Document-const: F_SETPIPE_SZ
+ *
+ * Change the capacity of the pipe referred to by fd to be at least arg bytes.
+ */
+ rb_define_const(mFcntl, "F_SETPIPE_SZ", INT2NUM(F_SETPIPE_SZ));
+#endif
+#ifdef F_GETPIPE_SZ
+ /* Document-const: F_GETPIPE_SZ
+ *
+ * Return (as the function result) the capacity of the pipe referred to by fd.
+ */
+ rb_define_const(mFcntl, "F_GETPIPE_SZ", INT2NUM(F_GETPIPE_SZ));
+#endif
#ifdef O_CREAT
/* Document-const: O_CREAT
*
diff --git a/ext/fcntl/fcntl.gemspec b/ext/fcntl/fcntl.gemspec
index 07922e1c25..048e101aa5 100644
--- a/ext/fcntl/fcntl.gemspec
+++ b/ext/fcntl/fcntl.gemspec
@@ -3,24 +3,19 @@
Gem::Specification.new do |spec|
spec.name = "fcntl"
- spec.version = "0.0.1"
- spec.date = '2017-02-10'
+ spec.version = "1.0.1"
spec.authors = ["Yukihiro Matsumoto"]
spec.email = ["matz@ruby-lang.org"]
spec.summary = "Loads constants defined in the OS fcntl.h C header file"
spec.description = "Loads constants defined in the OS fcntl.h C header file"
spec.homepage = "https://github.com/ruby/fcntl"
- spec.license = "BSD-2-Clause"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.files = ["ext/fcntl/extconf.rb", "ext/fcntl/fcntl.c"]
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.extensions = "ext/fcntl/extconf.rb"
- spec.required_ruby_version = ">= 2.5.0dev"
-
- spec.add_development_dependency "bundler", "~> 1.14"
- spec.add_development_dependency "rake", "~> 12"
- spec.add_development_dependency "rake-compiler"
+ spec.required_ruby_version = ">= 2.3.0"
end
diff --git a/ext/fiber/depend b/ext/fiber/depend
index 85cac2f03c..675263b95c 100644
--- a/ext/fiber/depend
+++ b/ext/fiber/depend
@@ -1 +1,3 @@
+# AUTOGENERATED DEPENDENCIES START
fiber.o: fiber.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
index 1a80b2b02a..3679e5c9ad 100644
--- a/ext/fiddle/closure.c
+++ b/ext/fiddle/closure.c
@@ -13,11 +13,12 @@ typedef struct {
ffi_type **argv;
} fiddle_closure;
-#if defined(USE_FFI_CLOSURE_ALLOC)
-#elif defined(__OpenBSD__) || defined(__APPLE__) || defined(__linux__)
+#if defined(__OpenBSD__)
# define USE_FFI_CLOSURE_ALLOC 0
-#elif defined(RUBY_LIBFFI_MODVERSION) && RUBY_LIBFFI_MODVERSION < 3000005 && \
- (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64))
+#endif
+
+#if defined(USE_FFI_CLOSURE_ALLOC)
+#elif !defined(HAVE_FFI_CLOSURE_ALLOC)
# define USE_FFI_CLOSURE_ALLOC 0
#else
# define USE_FFI_CLOSURE_ALLOC 1
@@ -129,6 +130,10 @@ with_gvl_callback(void *ptr)
rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i]));
break;
#endif
+ case TYPE_CONST_STRING:
+ rb_ary_push(params,
+ rb_str_new_cstr(*((const char **)(x->args[i]))));
+ break;
default:
rb_raise(rb_eRuntimeError, "closure args: %d", type);
}
@@ -174,6 +179,10 @@ with_gvl_callback(void *ptr)
*(unsigned LONG_LONG *)x->resp = NUM2ULL(ret);
break;
#endif
+ case TYPE_CONST_STRING:
+ /* Dangerous. Callback must keep reference of the String. */
+ *((const char **)(x->resp)) = StringValueCStr(ret);
+ break;
default:
rb_raise(rb_eRuntimeError, "closure retval: %d", type);
}
@@ -220,6 +229,7 @@ initialize(int rbargc, VALUE argv[], VALUE self)
{
VALUE ret;
VALUE args;
+ VALUE normalized_args;
VALUE abi;
fiddle_closure * cl;
ffi_cif * cif;
@@ -238,21 +248,26 @@ initialize(int rbargc, VALUE argv[], VALUE self)
cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
+ normalized_args = rb_ary_new_capa(argc);
for (i = 0; i < argc; i++) {
- int type = NUM2INT(RARRAY_AREF(args, i));
- cl->argv[i] = INT2FFI_TYPE(type);
+ VALUE arg = rb_fiddle_type_ensure(RARRAY_AREF(args, i));
+ rb_ary_push(normalized_args, arg);
+ cl->argv[i] = rb_fiddle_int_to_ffi_type(NUM2INT(arg));
}
cl->argv[argc] = NULL;
+ ret = rb_fiddle_type_ensure(ret);
rb_iv_set(self, "@ctype", ret);
- rb_iv_set(self, "@args", args);
+ rb_iv_set(self, "@args", normalized_args);
cif = &cl->cif;
pcl = cl->pcl;
- result = ffi_prep_cif(cif, NUM2INT(abi), argc,
- INT2FFI_TYPE(NUM2INT(ret)),
- cl->argv);
+ result = ffi_prep_cif(cif,
+ NUM2INT(abi),
+ argc,
+ rb_fiddle_int_to_ffi_type(NUM2INT(ret)),
+ cl->argv);
if (FFI_OK != result)
rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c
index d40ddc1f38..6e0ce36378 100644
--- a/ext/fiddle/conversions.c
+++ b/ext/fiddle/conversions.c
@@ -1,7 +1,159 @@
#include <fiddle.h>
+VALUE
+rb_fiddle_type_ensure(VALUE type)
+{
+ VALUE original_type = type;
+
+ if (!RB_SYMBOL_P(type)) {
+ VALUE type_string = rb_check_string_type(type);
+ if (!NIL_P(type_string)) {
+ type = rb_to_symbol(type_string);
+ }
+ }
+
+ if (RB_SYMBOL_P(type)) {
+ ID type_id = rb_sym2id(type);
+ ID void_id;
+ ID voidp_id;
+ ID char_id;
+ ID short_id;
+ ID int_id;
+ ID long_id;
+#ifdef TYPE_LONG_LONG
+ ID long_long_id;
+#endif
+#ifdef TYPE_INT8_T
+ ID int8_t_id;
+#endif
+#ifdef TYPE_INT16_T
+ ID int16_t_id;
+#endif
+#ifdef TYPE_INT32_T
+ ID int32_t_id;
+#endif
+#ifdef TYPE_INT64_T
+ ID int64_t_id;
+#endif
+ ID float_id;
+ ID double_id;
+ ID variadic_id;
+ ID const_string_id;
+ ID size_t_id;
+ ID ssize_t_id;
+ ID ptrdiff_t_id;
+ ID intptr_t_id;
+ ID uintptr_t_id;
+ RUBY_CONST_ID(void_id, "void");
+ RUBY_CONST_ID(voidp_id, "voidp");
+ RUBY_CONST_ID(char_id, "char");
+ RUBY_CONST_ID(short_id, "short");
+ RUBY_CONST_ID(int_id, "int");
+ RUBY_CONST_ID(long_id, "long");
+#ifdef TYPE_LONG_LONG
+ RUBY_CONST_ID(long_long_id, "long_long");
+#endif
+#ifdef TYPE_INT8_T
+ RUBY_CONST_ID(int8_t_id, "int8_t");
+#endif
+#ifdef TYPE_INT16_T
+ RUBY_CONST_ID(int16_t_id, "int16_t");
+#endif
+#ifdef TYPE_INT32_T
+ RUBY_CONST_ID(int32_t_id, "int32_t");
+#endif
+#ifdef TYPE_INT64_T
+ RUBY_CONST_ID(int64_t_id, "int64_t");
+#endif
+ RUBY_CONST_ID(float_id, "float");
+ RUBY_CONST_ID(double_id, "double");
+ RUBY_CONST_ID(variadic_id, "variadic");
+ RUBY_CONST_ID(const_string_id, "const_string");
+ RUBY_CONST_ID(size_t_id, "size_t");
+ RUBY_CONST_ID(ssize_t_id, "ssize_t");
+ RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
+ RUBY_CONST_ID(intptr_t_id, "intptr_t");
+ RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
+ if (type_id == void_id) {
+ return INT2NUM(TYPE_VOID);
+ }
+ else if (type_id == voidp_id) {
+ return INT2NUM(TYPE_VOIDP);
+ }
+ else if (type_id == char_id) {
+ return INT2NUM(TYPE_CHAR);
+ }
+ else if (type_id == short_id) {
+ return INT2NUM(TYPE_SHORT);
+ }
+ else if (type_id == int_id) {
+ return INT2NUM(TYPE_INT);
+ }
+ else if (type_id == long_id) {
+ return INT2NUM(TYPE_LONG);
+ }
+#ifdef TYPE_LONG_LONG
+ else if (type_id == long_long_id) {
+ return INT2NUM(TYPE_LONG_LONG);
+ }
+#endif
+#ifdef TYPE_INT8_T
+ else if (type_id == int8_t_id) {
+ return INT2NUM(TYPE_INT8_T);
+ }
+#endif
+#ifdef TYPE_INT16_T
+ else if (type_id == int16_t_id) {
+ return INT2NUM(TYPE_INT16_T);
+ }
+#endif
+#ifdef TYPE_INT32_T
+ else if (type_id == int32_t_id) {
+ return INT2NUM(TYPE_INT32_T);
+ }
+#endif
+#ifdef TYPE_INT64_T
+ else if (type_id == int64_t_id) {
+ return INT2NUM(TYPE_INT64_T);
+ }
+#endif
+ else if (type_id == float_id) {
+ return INT2NUM(TYPE_FLOAT);
+ }
+ else if (type_id == double_id) {
+ return INT2NUM(TYPE_DOUBLE);
+ }
+ else if (type_id == variadic_id) {
+ return INT2NUM(TYPE_VARIADIC);
+ }
+ else if (type_id == const_string_id) {
+ return INT2NUM(TYPE_CONST_STRING);
+ }
+ else if (type_id == size_t_id) {
+ return INT2NUM(TYPE_SIZE_T);
+ }
+ else if (type_id == ssize_t_id) {
+ return INT2NUM(TYPE_SSIZE_T);
+ }
+ else if (type_id == ptrdiff_t_id) {
+ return INT2NUM(TYPE_PTRDIFF_T);
+ }
+ else if (type_id == intptr_t_id) {
+ return INT2NUM(TYPE_INTPTR_T);
+ }
+ else if (type_id == uintptr_t_id) {
+ return INT2NUM(TYPE_UINTPTR_T);
+ }
+ else {
+ type = original_type;
+ }
+ }
+
+ return rb_to_int(type);
+}
+
ffi_type *
-int_to_ffi_type(int type)
+rb_fiddle_int_to_ffi_type(int type)
{
int signed_p = 1;
@@ -33,66 +185,90 @@ int_to_ffi_type(int type)
return &ffi_type_float;
case TYPE_DOUBLE:
return &ffi_type_double;
+ case TYPE_CONST_STRING:
+ return &ffi_type_pointer;
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
return &ffi_type_pointer;
}
+ffi_type *
+int_to_ffi_type(int type)
+{
+ return rb_fiddle_int_to_ffi_type(type);
+}
+
void
-value_to_generic(int type, VALUE src, fiddle_generic * dst)
+rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
{
switch (type) {
case TYPE_VOID:
break;
case TYPE_VOIDP:
- dst->pointer = NUM2PTR(rb_Integer(src));
+ dst->pointer = NUM2PTR(rb_Integer(*src));
break;
case TYPE_CHAR:
- dst->schar = (signed char)NUM2INT(src);
+ dst->schar = (signed char)NUM2INT(*src);
break;
case -TYPE_CHAR:
- dst->uchar = (unsigned char)NUM2UINT(src);
+ dst->uchar = (unsigned char)NUM2UINT(*src);
break;
case TYPE_SHORT:
- dst->sshort = (unsigned short)NUM2INT(src);
+ dst->sshort = (unsigned short)NUM2INT(*src);
break;
case -TYPE_SHORT:
- dst->sshort = (signed short)NUM2UINT(src);
+ dst->sshort = (signed short)NUM2UINT(*src);
break;
case TYPE_INT:
- dst->sint = NUM2INT(src);
+ dst->sint = NUM2INT(*src);
break;
case -TYPE_INT:
- dst->uint = NUM2UINT(src);
+ dst->uint = NUM2UINT(*src);
break;
case TYPE_LONG:
- dst->slong = NUM2LONG(src);
+ dst->slong = NUM2LONG(*src);
break;
case -TYPE_LONG:
- dst->ulong = NUM2ULONG(src);
+ dst->ulong = NUM2ULONG(*src);
break;
#if HAVE_LONG_LONG
case TYPE_LONG_LONG:
- dst->slong_long = NUM2LL(src);
+ dst->slong_long = NUM2LL(*src);
break;
case -TYPE_LONG_LONG:
- dst->ulong_long = NUM2ULL(src);
+ dst->ulong_long = NUM2ULL(*src);
break;
#endif
case TYPE_FLOAT:
- dst->ffloat = (float)NUM2DBL(src);
+ dst->ffloat = (float)NUM2DBL(*src);
break;
case TYPE_DOUBLE:
- dst->ddouble = NUM2DBL(src);
+ dst->ddouble = NUM2DBL(*src);
+ break;
+ case TYPE_CONST_STRING:
+ if (NIL_P(*src)) {
+ dst->pointer = NULL;
+ }
+ else {
+ dst->pointer = rb_string_value_cstr(src);
+ }
break;
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
}
+void
+value_to_generic(int type, VALUE src, fiddle_generic *dst)
+{
+ /* src isn't safe from GC when type is TYPE_CONST_STRING and src
+ * isn't String. */
+ rb_fiddle_value_to_generic(type, &src, dst);
+}
+
VALUE
-generic_to_value(VALUE rettype, fiddle_generic retval)
+rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
{
int type = NUM2INT(rettype);
VALUE cPointer;
@@ -131,6 +307,13 @@ generic_to_value(VALUE rettype, fiddle_generic retval)
return rb_float_new(retval.ffloat);
case TYPE_DOUBLE:
return rb_float_new(retval.ddouble);
+ case TYPE_CONST_STRING:
+ if (retval.pointer) {
+ return rb_str_new_cstr(retval.pointer);
+ }
+ else {
+ return Qnil;
+ }
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
@@ -138,4 +321,10 @@ generic_to_value(VALUE rettype, fiddle_generic retval)
UNREACHABLE;
}
+VALUE
+generic_to_value(VALUE rettype, fiddle_generic retval)
+{
+ return rb_fiddle_generic_to_value(rettype, retval);
+}
+
/* vim: set noet sw=4 sts=4 */
diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h
index cbc610bad2..c7c12a9234 100644
--- a/ext/fiddle/conversions.h
+++ b/ext/fiddle/conversions.h
@@ -24,13 +24,22 @@ typedef union
void * pointer; /* ffi_type_pointer */
} fiddle_generic;
+VALUE rb_fiddle_type_ensure(VALUE type);
+ffi_type * rb_fiddle_int_to_ffi_type(int type);
+void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
+VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval);
+
+/* Deprecated. Use rb_fiddle_*() version. */
ffi_type * int_to_ffi_type(int type);
-void value_to_generic(int type, VALUE src, fiddle_generic * dst);
+void value_to_generic(int type, VALUE src, fiddle_generic *dst);
VALUE generic_to_value(VALUE rettype, fiddle_generic retval);
-#define VALUE2GENERIC(_type, _src, _dst) value_to_generic((_type), (_src), (_dst))
-#define INT2FFI_TYPE(_type) int_to_ffi_type(_type)
-#define GENERIC2VALUE(_type, _retval) generic_to_value((_type), (_retval))
+#define VALUE2GENERIC(_type, _src, _dst) \
+ rb_fiddle_value_to_generic((_type), &(_src), (_dst))
+#define INT2FFI_TYPE(_type) \
+ rb_fiddle_int_to_ffi_type(_type)
+#define GENERIC2VALUE(_type, _retval) \
+ rb_fiddle_generic_to_value((_type), (_retval))
#if SIZEOF_VOIDP == SIZEOF_LONG
# define PTR2NUM(x) (LONG2NUM((long)(x)))
diff --git a/ext/fiddle/depend b/ext/fiddle/depend
index 7209469260..6afc09dd67 100644
--- a/ext/fiddle/depend
+++ b/ext/fiddle/depend
@@ -54,20 +54,165 @@ realclean: realclean-$(LIBFFI_CLEAN)
# AUTOGENERATED DEPENDENCIES START
closure.o: $(RUBY_EXTCONF_H)
closure.o: $(arch_hdrdir)/ruby/config.h
+closure.o: $(hdrdir)/ruby.h
+closure.o: $(hdrdir)/ruby/assert.h
closure.o: $(hdrdir)/ruby/backward.h
+closure.o: $(hdrdir)/ruby/backward/2/assume.h
+closure.o: $(hdrdir)/ruby/backward/2/attributes.h
+closure.o: $(hdrdir)/ruby/backward/2/bool.h
+closure.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+closure.o: $(hdrdir)/ruby/backward/2/inttypes.h
+closure.o: $(hdrdir)/ruby/backward/2/limits.h
+closure.o: $(hdrdir)/ruby/backward/2/long_long.h
+closure.o: $(hdrdir)/ruby/backward/2/stdalign.h
+closure.o: $(hdrdir)/ruby/backward/2/stdarg.h
closure.o: $(hdrdir)/ruby/defines.h
-closure.o: $(hdrdir)/ruby/encoding.h
closure.o: $(hdrdir)/ruby/intern.h
-closure.o: $(hdrdir)/ruby/io.h
+closure.o: $(hdrdir)/ruby/internal/anyargs.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+closure.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+closure.o: $(hdrdir)/ruby/internal/assume.h
+closure.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+closure.o: $(hdrdir)/ruby/internal/attr/artificial.h
+closure.o: $(hdrdir)/ruby/internal/attr/cold.h
+closure.o: $(hdrdir)/ruby/internal/attr/const.h
+closure.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+closure.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+closure.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+closure.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+closure.o: $(hdrdir)/ruby/internal/attr/error.h
+closure.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+closure.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+closure.o: $(hdrdir)/ruby/internal/attr/format.h
+closure.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+closure.o: $(hdrdir)/ruby/internal/attr/noalias.h
+closure.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+closure.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+closure.o: $(hdrdir)/ruby/internal/attr/noinline.h
+closure.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+closure.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+closure.o: $(hdrdir)/ruby/internal/attr/pure.h
+closure.o: $(hdrdir)/ruby/internal/attr/restrict.h
+closure.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+closure.o: $(hdrdir)/ruby/internal/attr/warning.h
+closure.o: $(hdrdir)/ruby/internal/attr/weakref.h
+closure.o: $(hdrdir)/ruby/internal/cast.h
+closure.o: $(hdrdir)/ruby/internal/compiler_is.h
+closure.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+closure.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+closure.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+closure.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+closure.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+closure.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+closure.o: $(hdrdir)/ruby/internal/compiler_since.h
+closure.o: $(hdrdir)/ruby/internal/config.h
+closure.o: $(hdrdir)/ruby/internal/constant_p.h
+closure.o: $(hdrdir)/ruby/internal/core.h
+closure.o: $(hdrdir)/ruby/internal/core/rarray.h
+closure.o: $(hdrdir)/ruby/internal/core/rbasic.h
+closure.o: $(hdrdir)/ruby/internal/core/rbignum.h
+closure.o: $(hdrdir)/ruby/internal/core/rclass.h
+closure.o: $(hdrdir)/ruby/internal/core/rdata.h
+closure.o: $(hdrdir)/ruby/internal/core/rfile.h
+closure.o: $(hdrdir)/ruby/internal/core/rhash.h
+closure.o: $(hdrdir)/ruby/internal/core/robject.h
+closure.o: $(hdrdir)/ruby/internal/core/rregexp.h
+closure.o: $(hdrdir)/ruby/internal/core/rstring.h
+closure.o: $(hdrdir)/ruby/internal/core/rstruct.h
+closure.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+closure.o: $(hdrdir)/ruby/internal/ctype.h
+closure.o: $(hdrdir)/ruby/internal/dllexport.h
+closure.o: $(hdrdir)/ruby/internal/dosish.h
+closure.o: $(hdrdir)/ruby/internal/error.h
+closure.o: $(hdrdir)/ruby/internal/eval.h
+closure.o: $(hdrdir)/ruby/internal/event.h
+closure.o: $(hdrdir)/ruby/internal/fl_type.h
+closure.o: $(hdrdir)/ruby/internal/gc.h
+closure.o: $(hdrdir)/ruby/internal/glob.h
+closure.o: $(hdrdir)/ruby/internal/globals.h
+closure.o: $(hdrdir)/ruby/internal/has/attribute.h
+closure.o: $(hdrdir)/ruby/internal/has/builtin.h
+closure.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+closure.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+closure.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+closure.o: $(hdrdir)/ruby/internal/has/extension.h
+closure.o: $(hdrdir)/ruby/internal/has/feature.h
+closure.o: $(hdrdir)/ruby/internal/has/warning.h
+closure.o: $(hdrdir)/ruby/internal/intern/array.h
+closure.o: $(hdrdir)/ruby/internal/intern/bignum.h
+closure.o: $(hdrdir)/ruby/internal/intern/class.h
+closure.o: $(hdrdir)/ruby/internal/intern/compar.h
+closure.o: $(hdrdir)/ruby/internal/intern/complex.h
+closure.o: $(hdrdir)/ruby/internal/intern/cont.h
+closure.o: $(hdrdir)/ruby/internal/intern/dir.h
+closure.o: $(hdrdir)/ruby/internal/intern/enum.h
+closure.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+closure.o: $(hdrdir)/ruby/internal/intern/error.h
+closure.o: $(hdrdir)/ruby/internal/intern/eval.h
+closure.o: $(hdrdir)/ruby/internal/intern/file.h
+closure.o: $(hdrdir)/ruby/internal/intern/gc.h
+closure.o: $(hdrdir)/ruby/internal/intern/hash.h
+closure.o: $(hdrdir)/ruby/internal/intern/io.h
+closure.o: $(hdrdir)/ruby/internal/intern/load.h
+closure.o: $(hdrdir)/ruby/internal/intern/marshal.h
+closure.o: $(hdrdir)/ruby/internal/intern/numeric.h
+closure.o: $(hdrdir)/ruby/internal/intern/object.h
+closure.o: $(hdrdir)/ruby/internal/intern/parse.h
+closure.o: $(hdrdir)/ruby/internal/intern/proc.h
+closure.o: $(hdrdir)/ruby/internal/intern/process.h
+closure.o: $(hdrdir)/ruby/internal/intern/random.h
+closure.o: $(hdrdir)/ruby/internal/intern/range.h
+closure.o: $(hdrdir)/ruby/internal/intern/rational.h
+closure.o: $(hdrdir)/ruby/internal/intern/re.h
+closure.o: $(hdrdir)/ruby/internal/intern/ruby.h
+closure.o: $(hdrdir)/ruby/internal/intern/select.h
+closure.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+closure.o: $(hdrdir)/ruby/internal/intern/signal.h
+closure.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+closure.o: $(hdrdir)/ruby/internal/intern/string.h
+closure.o: $(hdrdir)/ruby/internal/intern/struct.h
+closure.o: $(hdrdir)/ruby/internal/intern/thread.h
+closure.o: $(hdrdir)/ruby/internal/intern/time.h
+closure.o: $(hdrdir)/ruby/internal/intern/variable.h
+closure.o: $(hdrdir)/ruby/internal/intern/vm.h
+closure.o: $(hdrdir)/ruby/internal/interpreter.h
+closure.o: $(hdrdir)/ruby/internal/iterator.h
+closure.o: $(hdrdir)/ruby/internal/memory.h
+closure.o: $(hdrdir)/ruby/internal/method.h
+closure.o: $(hdrdir)/ruby/internal/module.h
+closure.o: $(hdrdir)/ruby/internal/newobj.h
+closure.o: $(hdrdir)/ruby/internal/rgengc.h
+closure.o: $(hdrdir)/ruby/internal/scan_args.h
+closure.o: $(hdrdir)/ruby/internal/special_consts.h
+closure.o: $(hdrdir)/ruby/internal/static_assert.h
+closure.o: $(hdrdir)/ruby/internal/stdalign.h
+closure.o: $(hdrdir)/ruby/internal/stdbool.h
+closure.o: $(hdrdir)/ruby/internal/symbol.h
+closure.o: $(hdrdir)/ruby/internal/token_paste.h
+closure.o: $(hdrdir)/ruby/internal/value.h
+closure.o: $(hdrdir)/ruby/internal/value_type.h
+closure.o: $(hdrdir)/ruby/internal/variable.h
+closure.o: $(hdrdir)/ruby/internal/warning_push.h
+closure.o: $(hdrdir)/ruby/internal/xmalloc.h
closure.o: $(hdrdir)/ruby/missing.h
-closure.o: $(hdrdir)/ruby/onigmo.h
-closure.o: $(hdrdir)/ruby/oniguruma.h
closure.o: $(hdrdir)/ruby/ruby.h
closure.o: $(hdrdir)/ruby/st.h
closure.o: $(hdrdir)/ruby/subst.h
closure.o: $(hdrdir)/ruby/thread.h
-closure.o: $(top_srcdir)/include/ruby.h
-closure.o: $(top_srcdir)/internal.h
closure.o: closure.c
closure.o: closure.h
closure.o: conversions.h
@@ -75,14 +220,164 @@ closure.o: fiddle.h
closure.o: function.h
conversions.o: $(RUBY_EXTCONF_H)
conversions.o: $(arch_hdrdir)/ruby/config.h
+conversions.o: $(hdrdir)/ruby.h
+conversions.o: $(hdrdir)/ruby/assert.h
conversions.o: $(hdrdir)/ruby/backward.h
+conversions.o: $(hdrdir)/ruby/backward/2/assume.h
+conversions.o: $(hdrdir)/ruby/backward/2/attributes.h
+conversions.o: $(hdrdir)/ruby/backward/2/bool.h
+conversions.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+conversions.o: $(hdrdir)/ruby/backward/2/inttypes.h
+conversions.o: $(hdrdir)/ruby/backward/2/limits.h
+conversions.o: $(hdrdir)/ruby/backward/2/long_long.h
+conversions.o: $(hdrdir)/ruby/backward/2/stdalign.h
+conversions.o: $(hdrdir)/ruby/backward/2/stdarg.h
conversions.o: $(hdrdir)/ruby/defines.h
conversions.o: $(hdrdir)/ruby/intern.h
+conversions.o: $(hdrdir)/ruby/internal/anyargs.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+conversions.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+conversions.o: $(hdrdir)/ruby/internal/assume.h
+conversions.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+conversions.o: $(hdrdir)/ruby/internal/attr/artificial.h
+conversions.o: $(hdrdir)/ruby/internal/attr/cold.h
+conversions.o: $(hdrdir)/ruby/internal/attr/const.h
+conversions.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+conversions.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+conversions.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+conversions.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+conversions.o: $(hdrdir)/ruby/internal/attr/error.h
+conversions.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+conversions.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+conversions.o: $(hdrdir)/ruby/internal/attr/format.h
+conversions.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+conversions.o: $(hdrdir)/ruby/internal/attr/noalias.h
+conversions.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+conversions.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+conversions.o: $(hdrdir)/ruby/internal/attr/noinline.h
+conversions.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+conversions.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+conversions.o: $(hdrdir)/ruby/internal/attr/pure.h
+conversions.o: $(hdrdir)/ruby/internal/attr/restrict.h
+conversions.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+conversions.o: $(hdrdir)/ruby/internal/attr/warning.h
+conversions.o: $(hdrdir)/ruby/internal/attr/weakref.h
+conversions.o: $(hdrdir)/ruby/internal/cast.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_is.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+conversions.o: $(hdrdir)/ruby/internal/compiler_since.h
+conversions.o: $(hdrdir)/ruby/internal/config.h
+conversions.o: $(hdrdir)/ruby/internal/constant_p.h
+conversions.o: $(hdrdir)/ruby/internal/core.h
+conversions.o: $(hdrdir)/ruby/internal/core/rarray.h
+conversions.o: $(hdrdir)/ruby/internal/core/rbasic.h
+conversions.o: $(hdrdir)/ruby/internal/core/rbignum.h
+conversions.o: $(hdrdir)/ruby/internal/core/rclass.h
+conversions.o: $(hdrdir)/ruby/internal/core/rdata.h
+conversions.o: $(hdrdir)/ruby/internal/core/rfile.h
+conversions.o: $(hdrdir)/ruby/internal/core/rhash.h
+conversions.o: $(hdrdir)/ruby/internal/core/robject.h
+conversions.o: $(hdrdir)/ruby/internal/core/rregexp.h
+conversions.o: $(hdrdir)/ruby/internal/core/rstring.h
+conversions.o: $(hdrdir)/ruby/internal/core/rstruct.h
+conversions.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+conversions.o: $(hdrdir)/ruby/internal/ctype.h
+conversions.o: $(hdrdir)/ruby/internal/dllexport.h
+conversions.o: $(hdrdir)/ruby/internal/dosish.h
+conversions.o: $(hdrdir)/ruby/internal/error.h
+conversions.o: $(hdrdir)/ruby/internal/eval.h
+conversions.o: $(hdrdir)/ruby/internal/event.h
+conversions.o: $(hdrdir)/ruby/internal/fl_type.h
+conversions.o: $(hdrdir)/ruby/internal/gc.h
+conversions.o: $(hdrdir)/ruby/internal/glob.h
+conversions.o: $(hdrdir)/ruby/internal/globals.h
+conversions.o: $(hdrdir)/ruby/internal/has/attribute.h
+conversions.o: $(hdrdir)/ruby/internal/has/builtin.h
+conversions.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+conversions.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+conversions.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+conversions.o: $(hdrdir)/ruby/internal/has/extension.h
+conversions.o: $(hdrdir)/ruby/internal/has/feature.h
+conversions.o: $(hdrdir)/ruby/internal/has/warning.h
+conversions.o: $(hdrdir)/ruby/internal/intern/array.h
+conversions.o: $(hdrdir)/ruby/internal/intern/bignum.h
+conversions.o: $(hdrdir)/ruby/internal/intern/class.h
+conversions.o: $(hdrdir)/ruby/internal/intern/compar.h
+conversions.o: $(hdrdir)/ruby/internal/intern/complex.h
+conversions.o: $(hdrdir)/ruby/internal/intern/cont.h
+conversions.o: $(hdrdir)/ruby/internal/intern/dir.h
+conversions.o: $(hdrdir)/ruby/internal/intern/enum.h
+conversions.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+conversions.o: $(hdrdir)/ruby/internal/intern/error.h
+conversions.o: $(hdrdir)/ruby/internal/intern/eval.h
+conversions.o: $(hdrdir)/ruby/internal/intern/file.h
+conversions.o: $(hdrdir)/ruby/internal/intern/gc.h
+conversions.o: $(hdrdir)/ruby/internal/intern/hash.h
+conversions.o: $(hdrdir)/ruby/internal/intern/io.h
+conversions.o: $(hdrdir)/ruby/internal/intern/load.h
+conversions.o: $(hdrdir)/ruby/internal/intern/marshal.h
+conversions.o: $(hdrdir)/ruby/internal/intern/numeric.h
+conversions.o: $(hdrdir)/ruby/internal/intern/object.h
+conversions.o: $(hdrdir)/ruby/internal/intern/parse.h
+conversions.o: $(hdrdir)/ruby/internal/intern/proc.h
+conversions.o: $(hdrdir)/ruby/internal/intern/process.h
+conversions.o: $(hdrdir)/ruby/internal/intern/random.h
+conversions.o: $(hdrdir)/ruby/internal/intern/range.h
+conversions.o: $(hdrdir)/ruby/internal/intern/rational.h
+conversions.o: $(hdrdir)/ruby/internal/intern/re.h
+conversions.o: $(hdrdir)/ruby/internal/intern/ruby.h
+conversions.o: $(hdrdir)/ruby/internal/intern/select.h
+conversions.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+conversions.o: $(hdrdir)/ruby/internal/intern/signal.h
+conversions.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+conversions.o: $(hdrdir)/ruby/internal/intern/string.h
+conversions.o: $(hdrdir)/ruby/internal/intern/struct.h
+conversions.o: $(hdrdir)/ruby/internal/intern/thread.h
+conversions.o: $(hdrdir)/ruby/internal/intern/time.h
+conversions.o: $(hdrdir)/ruby/internal/intern/variable.h
+conversions.o: $(hdrdir)/ruby/internal/intern/vm.h
+conversions.o: $(hdrdir)/ruby/internal/interpreter.h
+conversions.o: $(hdrdir)/ruby/internal/iterator.h
+conversions.o: $(hdrdir)/ruby/internal/memory.h
+conversions.o: $(hdrdir)/ruby/internal/method.h
+conversions.o: $(hdrdir)/ruby/internal/module.h
+conversions.o: $(hdrdir)/ruby/internal/newobj.h
+conversions.o: $(hdrdir)/ruby/internal/rgengc.h
+conversions.o: $(hdrdir)/ruby/internal/scan_args.h
+conversions.o: $(hdrdir)/ruby/internal/special_consts.h
+conversions.o: $(hdrdir)/ruby/internal/static_assert.h
+conversions.o: $(hdrdir)/ruby/internal/stdalign.h
+conversions.o: $(hdrdir)/ruby/internal/stdbool.h
+conversions.o: $(hdrdir)/ruby/internal/symbol.h
+conversions.o: $(hdrdir)/ruby/internal/token_paste.h
+conversions.o: $(hdrdir)/ruby/internal/value.h
+conversions.o: $(hdrdir)/ruby/internal/value_type.h
+conversions.o: $(hdrdir)/ruby/internal/variable.h
+conversions.o: $(hdrdir)/ruby/internal/warning_push.h
+conversions.o: $(hdrdir)/ruby/internal/xmalloc.h
conversions.o: $(hdrdir)/ruby/missing.h
conversions.o: $(hdrdir)/ruby/ruby.h
conversions.o: $(hdrdir)/ruby/st.h
conversions.o: $(hdrdir)/ruby/subst.h
-conversions.o: $(top_srcdir)/include/ruby.h
conversions.o: closure.h
conversions.o: conversions.c
conversions.o: conversions.h
@@ -90,14 +385,164 @@ conversions.o: fiddle.h
conversions.o: function.h
fiddle.o: $(RUBY_EXTCONF_H)
fiddle.o: $(arch_hdrdir)/ruby/config.h
+fiddle.o: $(hdrdir)/ruby.h
+fiddle.o: $(hdrdir)/ruby/assert.h
fiddle.o: $(hdrdir)/ruby/backward.h
+fiddle.o: $(hdrdir)/ruby/backward/2/assume.h
+fiddle.o: $(hdrdir)/ruby/backward/2/attributes.h
+fiddle.o: $(hdrdir)/ruby/backward/2/bool.h
+fiddle.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+fiddle.o: $(hdrdir)/ruby/backward/2/inttypes.h
+fiddle.o: $(hdrdir)/ruby/backward/2/limits.h
+fiddle.o: $(hdrdir)/ruby/backward/2/long_long.h
+fiddle.o: $(hdrdir)/ruby/backward/2/stdalign.h
+fiddle.o: $(hdrdir)/ruby/backward/2/stdarg.h
fiddle.o: $(hdrdir)/ruby/defines.h
fiddle.o: $(hdrdir)/ruby/intern.h
+fiddle.o: $(hdrdir)/ruby/internal/anyargs.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+fiddle.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+fiddle.o: $(hdrdir)/ruby/internal/assume.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/artificial.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/cold.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/const.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/error.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/format.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/noalias.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/noinline.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/pure.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/restrict.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/warning.h
+fiddle.o: $(hdrdir)/ruby/internal/attr/weakref.h
+fiddle.o: $(hdrdir)/ruby/internal/cast.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_is.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+fiddle.o: $(hdrdir)/ruby/internal/compiler_since.h
+fiddle.o: $(hdrdir)/ruby/internal/config.h
+fiddle.o: $(hdrdir)/ruby/internal/constant_p.h
+fiddle.o: $(hdrdir)/ruby/internal/core.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rarray.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rbasic.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rbignum.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rclass.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rdata.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rfile.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rhash.h
+fiddle.o: $(hdrdir)/ruby/internal/core/robject.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rregexp.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rstring.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rstruct.h
+fiddle.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+fiddle.o: $(hdrdir)/ruby/internal/ctype.h
+fiddle.o: $(hdrdir)/ruby/internal/dllexport.h
+fiddle.o: $(hdrdir)/ruby/internal/dosish.h
+fiddle.o: $(hdrdir)/ruby/internal/error.h
+fiddle.o: $(hdrdir)/ruby/internal/eval.h
+fiddle.o: $(hdrdir)/ruby/internal/event.h
+fiddle.o: $(hdrdir)/ruby/internal/fl_type.h
+fiddle.o: $(hdrdir)/ruby/internal/gc.h
+fiddle.o: $(hdrdir)/ruby/internal/glob.h
+fiddle.o: $(hdrdir)/ruby/internal/globals.h
+fiddle.o: $(hdrdir)/ruby/internal/has/attribute.h
+fiddle.o: $(hdrdir)/ruby/internal/has/builtin.h
+fiddle.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+fiddle.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+fiddle.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+fiddle.o: $(hdrdir)/ruby/internal/has/extension.h
+fiddle.o: $(hdrdir)/ruby/internal/has/feature.h
+fiddle.o: $(hdrdir)/ruby/internal/has/warning.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/array.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/bignum.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/class.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/compar.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/complex.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/cont.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/dir.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/enum.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/error.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/eval.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/file.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/gc.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/hash.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/io.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/load.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/marshal.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/numeric.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/object.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/parse.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/proc.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/process.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/random.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/range.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/rational.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/re.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/ruby.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/select.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/signal.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/string.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/struct.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/thread.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/time.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/variable.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/vm.h
+fiddle.o: $(hdrdir)/ruby/internal/interpreter.h
+fiddle.o: $(hdrdir)/ruby/internal/iterator.h
+fiddle.o: $(hdrdir)/ruby/internal/memory.h
+fiddle.o: $(hdrdir)/ruby/internal/method.h
+fiddle.o: $(hdrdir)/ruby/internal/module.h
+fiddle.o: $(hdrdir)/ruby/internal/newobj.h
+fiddle.o: $(hdrdir)/ruby/internal/rgengc.h
+fiddle.o: $(hdrdir)/ruby/internal/scan_args.h
+fiddle.o: $(hdrdir)/ruby/internal/special_consts.h
+fiddle.o: $(hdrdir)/ruby/internal/static_assert.h
+fiddle.o: $(hdrdir)/ruby/internal/stdalign.h
+fiddle.o: $(hdrdir)/ruby/internal/stdbool.h
+fiddle.o: $(hdrdir)/ruby/internal/symbol.h
+fiddle.o: $(hdrdir)/ruby/internal/token_paste.h
+fiddle.o: $(hdrdir)/ruby/internal/value.h
+fiddle.o: $(hdrdir)/ruby/internal/value_type.h
+fiddle.o: $(hdrdir)/ruby/internal/variable.h
+fiddle.o: $(hdrdir)/ruby/internal/warning_push.h
+fiddle.o: $(hdrdir)/ruby/internal/xmalloc.h
fiddle.o: $(hdrdir)/ruby/missing.h
fiddle.o: $(hdrdir)/ruby/ruby.h
fiddle.o: $(hdrdir)/ruby/st.h
fiddle.o: $(hdrdir)/ruby/subst.h
-fiddle.o: $(top_srcdir)/include/ruby.h
fiddle.o: closure.h
fiddle.o: conversions.h
fiddle.o: fiddle.c
@@ -105,15 +550,165 @@ fiddle.o: fiddle.h
fiddle.o: function.h
function.o: $(RUBY_EXTCONF_H)
function.o: $(arch_hdrdir)/ruby/config.h
+function.o: $(hdrdir)/ruby.h
+function.o: $(hdrdir)/ruby/assert.h
function.o: $(hdrdir)/ruby/backward.h
+function.o: $(hdrdir)/ruby/backward/2/assume.h
+function.o: $(hdrdir)/ruby/backward/2/attributes.h
+function.o: $(hdrdir)/ruby/backward/2/bool.h
+function.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+function.o: $(hdrdir)/ruby/backward/2/inttypes.h
+function.o: $(hdrdir)/ruby/backward/2/limits.h
+function.o: $(hdrdir)/ruby/backward/2/long_long.h
+function.o: $(hdrdir)/ruby/backward/2/stdalign.h
+function.o: $(hdrdir)/ruby/backward/2/stdarg.h
function.o: $(hdrdir)/ruby/defines.h
function.o: $(hdrdir)/ruby/intern.h
+function.o: $(hdrdir)/ruby/internal/anyargs.h
+function.o: $(hdrdir)/ruby/internal/arithmetic.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+function.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+function.o: $(hdrdir)/ruby/internal/assume.h
+function.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+function.o: $(hdrdir)/ruby/internal/attr/artificial.h
+function.o: $(hdrdir)/ruby/internal/attr/cold.h
+function.o: $(hdrdir)/ruby/internal/attr/const.h
+function.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+function.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+function.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+function.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+function.o: $(hdrdir)/ruby/internal/attr/error.h
+function.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+function.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+function.o: $(hdrdir)/ruby/internal/attr/format.h
+function.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+function.o: $(hdrdir)/ruby/internal/attr/noalias.h
+function.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+function.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+function.o: $(hdrdir)/ruby/internal/attr/noinline.h
+function.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+function.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+function.o: $(hdrdir)/ruby/internal/attr/pure.h
+function.o: $(hdrdir)/ruby/internal/attr/restrict.h
+function.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+function.o: $(hdrdir)/ruby/internal/attr/warning.h
+function.o: $(hdrdir)/ruby/internal/attr/weakref.h
+function.o: $(hdrdir)/ruby/internal/cast.h
+function.o: $(hdrdir)/ruby/internal/compiler_is.h
+function.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+function.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+function.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+function.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+function.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+function.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+function.o: $(hdrdir)/ruby/internal/compiler_since.h
+function.o: $(hdrdir)/ruby/internal/config.h
+function.o: $(hdrdir)/ruby/internal/constant_p.h
+function.o: $(hdrdir)/ruby/internal/core.h
+function.o: $(hdrdir)/ruby/internal/core/rarray.h
+function.o: $(hdrdir)/ruby/internal/core/rbasic.h
+function.o: $(hdrdir)/ruby/internal/core/rbignum.h
+function.o: $(hdrdir)/ruby/internal/core/rclass.h
+function.o: $(hdrdir)/ruby/internal/core/rdata.h
+function.o: $(hdrdir)/ruby/internal/core/rfile.h
+function.o: $(hdrdir)/ruby/internal/core/rhash.h
+function.o: $(hdrdir)/ruby/internal/core/robject.h
+function.o: $(hdrdir)/ruby/internal/core/rregexp.h
+function.o: $(hdrdir)/ruby/internal/core/rstring.h
+function.o: $(hdrdir)/ruby/internal/core/rstruct.h
+function.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+function.o: $(hdrdir)/ruby/internal/ctype.h
+function.o: $(hdrdir)/ruby/internal/dllexport.h
+function.o: $(hdrdir)/ruby/internal/dosish.h
+function.o: $(hdrdir)/ruby/internal/error.h
+function.o: $(hdrdir)/ruby/internal/eval.h
+function.o: $(hdrdir)/ruby/internal/event.h
+function.o: $(hdrdir)/ruby/internal/fl_type.h
+function.o: $(hdrdir)/ruby/internal/gc.h
+function.o: $(hdrdir)/ruby/internal/glob.h
+function.o: $(hdrdir)/ruby/internal/globals.h
+function.o: $(hdrdir)/ruby/internal/has/attribute.h
+function.o: $(hdrdir)/ruby/internal/has/builtin.h
+function.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+function.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+function.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+function.o: $(hdrdir)/ruby/internal/has/extension.h
+function.o: $(hdrdir)/ruby/internal/has/feature.h
+function.o: $(hdrdir)/ruby/internal/has/warning.h
+function.o: $(hdrdir)/ruby/internal/intern/array.h
+function.o: $(hdrdir)/ruby/internal/intern/bignum.h
+function.o: $(hdrdir)/ruby/internal/intern/class.h
+function.o: $(hdrdir)/ruby/internal/intern/compar.h
+function.o: $(hdrdir)/ruby/internal/intern/complex.h
+function.o: $(hdrdir)/ruby/internal/intern/cont.h
+function.o: $(hdrdir)/ruby/internal/intern/dir.h
+function.o: $(hdrdir)/ruby/internal/intern/enum.h
+function.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+function.o: $(hdrdir)/ruby/internal/intern/error.h
+function.o: $(hdrdir)/ruby/internal/intern/eval.h
+function.o: $(hdrdir)/ruby/internal/intern/file.h
+function.o: $(hdrdir)/ruby/internal/intern/gc.h
+function.o: $(hdrdir)/ruby/internal/intern/hash.h
+function.o: $(hdrdir)/ruby/internal/intern/io.h
+function.o: $(hdrdir)/ruby/internal/intern/load.h
+function.o: $(hdrdir)/ruby/internal/intern/marshal.h
+function.o: $(hdrdir)/ruby/internal/intern/numeric.h
+function.o: $(hdrdir)/ruby/internal/intern/object.h
+function.o: $(hdrdir)/ruby/internal/intern/parse.h
+function.o: $(hdrdir)/ruby/internal/intern/proc.h
+function.o: $(hdrdir)/ruby/internal/intern/process.h
+function.o: $(hdrdir)/ruby/internal/intern/random.h
+function.o: $(hdrdir)/ruby/internal/intern/range.h
+function.o: $(hdrdir)/ruby/internal/intern/rational.h
+function.o: $(hdrdir)/ruby/internal/intern/re.h
+function.o: $(hdrdir)/ruby/internal/intern/ruby.h
+function.o: $(hdrdir)/ruby/internal/intern/select.h
+function.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+function.o: $(hdrdir)/ruby/internal/intern/signal.h
+function.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+function.o: $(hdrdir)/ruby/internal/intern/string.h
+function.o: $(hdrdir)/ruby/internal/intern/struct.h
+function.o: $(hdrdir)/ruby/internal/intern/thread.h
+function.o: $(hdrdir)/ruby/internal/intern/time.h
+function.o: $(hdrdir)/ruby/internal/intern/variable.h
+function.o: $(hdrdir)/ruby/internal/intern/vm.h
+function.o: $(hdrdir)/ruby/internal/interpreter.h
+function.o: $(hdrdir)/ruby/internal/iterator.h
+function.o: $(hdrdir)/ruby/internal/memory.h
+function.o: $(hdrdir)/ruby/internal/method.h
+function.o: $(hdrdir)/ruby/internal/module.h
+function.o: $(hdrdir)/ruby/internal/newobj.h
+function.o: $(hdrdir)/ruby/internal/rgengc.h
+function.o: $(hdrdir)/ruby/internal/scan_args.h
+function.o: $(hdrdir)/ruby/internal/special_consts.h
+function.o: $(hdrdir)/ruby/internal/static_assert.h
+function.o: $(hdrdir)/ruby/internal/stdalign.h
+function.o: $(hdrdir)/ruby/internal/stdbool.h
+function.o: $(hdrdir)/ruby/internal/symbol.h
+function.o: $(hdrdir)/ruby/internal/token_paste.h
+function.o: $(hdrdir)/ruby/internal/value.h
+function.o: $(hdrdir)/ruby/internal/value_type.h
+function.o: $(hdrdir)/ruby/internal/variable.h
+function.o: $(hdrdir)/ruby/internal/warning_push.h
+function.o: $(hdrdir)/ruby/internal/xmalloc.h
function.o: $(hdrdir)/ruby/missing.h
function.o: $(hdrdir)/ruby/ruby.h
function.o: $(hdrdir)/ruby/st.h
function.o: $(hdrdir)/ruby/subst.h
function.o: $(hdrdir)/ruby/thread.h
-function.o: $(top_srcdir)/include/ruby.h
function.o: closure.h
function.o: conversions.h
function.o: fiddle.h
@@ -121,33 +716,665 @@ function.o: function.c
function.o: function.h
handle.o: $(RUBY_EXTCONF_H)
handle.o: $(arch_hdrdir)/ruby/config.h
+handle.o: $(hdrdir)/ruby.h
+handle.o: $(hdrdir)/ruby/assert.h
handle.o: $(hdrdir)/ruby/backward.h
+handle.o: $(hdrdir)/ruby/backward/2/assume.h
+handle.o: $(hdrdir)/ruby/backward/2/attributes.h
+handle.o: $(hdrdir)/ruby/backward/2/bool.h
+handle.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+handle.o: $(hdrdir)/ruby/backward/2/inttypes.h
+handle.o: $(hdrdir)/ruby/backward/2/limits.h
+handle.o: $(hdrdir)/ruby/backward/2/long_long.h
+handle.o: $(hdrdir)/ruby/backward/2/stdalign.h
+handle.o: $(hdrdir)/ruby/backward/2/stdarg.h
handle.o: $(hdrdir)/ruby/defines.h
handle.o: $(hdrdir)/ruby/intern.h
+handle.o: $(hdrdir)/ruby/internal/anyargs.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+handle.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+handle.o: $(hdrdir)/ruby/internal/assume.h
+handle.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+handle.o: $(hdrdir)/ruby/internal/attr/artificial.h
+handle.o: $(hdrdir)/ruby/internal/attr/cold.h
+handle.o: $(hdrdir)/ruby/internal/attr/const.h
+handle.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+handle.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+handle.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+handle.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+handle.o: $(hdrdir)/ruby/internal/attr/error.h
+handle.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+handle.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+handle.o: $(hdrdir)/ruby/internal/attr/format.h
+handle.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+handle.o: $(hdrdir)/ruby/internal/attr/noalias.h
+handle.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+handle.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+handle.o: $(hdrdir)/ruby/internal/attr/noinline.h
+handle.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+handle.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+handle.o: $(hdrdir)/ruby/internal/attr/pure.h
+handle.o: $(hdrdir)/ruby/internal/attr/restrict.h
+handle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+handle.o: $(hdrdir)/ruby/internal/attr/warning.h
+handle.o: $(hdrdir)/ruby/internal/attr/weakref.h
+handle.o: $(hdrdir)/ruby/internal/cast.h
+handle.o: $(hdrdir)/ruby/internal/compiler_is.h
+handle.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+handle.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+handle.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+handle.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+handle.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+handle.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+handle.o: $(hdrdir)/ruby/internal/compiler_since.h
+handle.o: $(hdrdir)/ruby/internal/config.h
+handle.o: $(hdrdir)/ruby/internal/constant_p.h
+handle.o: $(hdrdir)/ruby/internal/core.h
+handle.o: $(hdrdir)/ruby/internal/core/rarray.h
+handle.o: $(hdrdir)/ruby/internal/core/rbasic.h
+handle.o: $(hdrdir)/ruby/internal/core/rbignum.h
+handle.o: $(hdrdir)/ruby/internal/core/rclass.h
+handle.o: $(hdrdir)/ruby/internal/core/rdata.h
+handle.o: $(hdrdir)/ruby/internal/core/rfile.h
+handle.o: $(hdrdir)/ruby/internal/core/rhash.h
+handle.o: $(hdrdir)/ruby/internal/core/robject.h
+handle.o: $(hdrdir)/ruby/internal/core/rregexp.h
+handle.o: $(hdrdir)/ruby/internal/core/rstring.h
+handle.o: $(hdrdir)/ruby/internal/core/rstruct.h
+handle.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+handle.o: $(hdrdir)/ruby/internal/ctype.h
+handle.o: $(hdrdir)/ruby/internal/dllexport.h
+handle.o: $(hdrdir)/ruby/internal/dosish.h
+handle.o: $(hdrdir)/ruby/internal/error.h
+handle.o: $(hdrdir)/ruby/internal/eval.h
+handle.o: $(hdrdir)/ruby/internal/event.h
+handle.o: $(hdrdir)/ruby/internal/fl_type.h
+handle.o: $(hdrdir)/ruby/internal/gc.h
+handle.o: $(hdrdir)/ruby/internal/glob.h
+handle.o: $(hdrdir)/ruby/internal/globals.h
+handle.o: $(hdrdir)/ruby/internal/has/attribute.h
+handle.o: $(hdrdir)/ruby/internal/has/builtin.h
+handle.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+handle.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+handle.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+handle.o: $(hdrdir)/ruby/internal/has/extension.h
+handle.o: $(hdrdir)/ruby/internal/has/feature.h
+handle.o: $(hdrdir)/ruby/internal/has/warning.h
+handle.o: $(hdrdir)/ruby/internal/intern/array.h
+handle.o: $(hdrdir)/ruby/internal/intern/bignum.h
+handle.o: $(hdrdir)/ruby/internal/intern/class.h
+handle.o: $(hdrdir)/ruby/internal/intern/compar.h
+handle.o: $(hdrdir)/ruby/internal/intern/complex.h
+handle.o: $(hdrdir)/ruby/internal/intern/cont.h
+handle.o: $(hdrdir)/ruby/internal/intern/dir.h
+handle.o: $(hdrdir)/ruby/internal/intern/enum.h
+handle.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+handle.o: $(hdrdir)/ruby/internal/intern/error.h
+handle.o: $(hdrdir)/ruby/internal/intern/eval.h
+handle.o: $(hdrdir)/ruby/internal/intern/file.h
+handle.o: $(hdrdir)/ruby/internal/intern/gc.h
+handle.o: $(hdrdir)/ruby/internal/intern/hash.h
+handle.o: $(hdrdir)/ruby/internal/intern/io.h
+handle.o: $(hdrdir)/ruby/internal/intern/load.h
+handle.o: $(hdrdir)/ruby/internal/intern/marshal.h
+handle.o: $(hdrdir)/ruby/internal/intern/numeric.h
+handle.o: $(hdrdir)/ruby/internal/intern/object.h
+handle.o: $(hdrdir)/ruby/internal/intern/parse.h
+handle.o: $(hdrdir)/ruby/internal/intern/proc.h
+handle.o: $(hdrdir)/ruby/internal/intern/process.h
+handle.o: $(hdrdir)/ruby/internal/intern/random.h
+handle.o: $(hdrdir)/ruby/internal/intern/range.h
+handle.o: $(hdrdir)/ruby/internal/intern/rational.h
+handle.o: $(hdrdir)/ruby/internal/intern/re.h
+handle.o: $(hdrdir)/ruby/internal/intern/ruby.h
+handle.o: $(hdrdir)/ruby/internal/intern/select.h
+handle.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+handle.o: $(hdrdir)/ruby/internal/intern/signal.h
+handle.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+handle.o: $(hdrdir)/ruby/internal/intern/string.h
+handle.o: $(hdrdir)/ruby/internal/intern/struct.h
+handle.o: $(hdrdir)/ruby/internal/intern/thread.h
+handle.o: $(hdrdir)/ruby/internal/intern/time.h
+handle.o: $(hdrdir)/ruby/internal/intern/variable.h
+handle.o: $(hdrdir)/ruby/internal/intern/vm.h
+handle.o: $(hdrdir)/ruby/internal/interpreter.h
+handle.o: $(hdrdir)/ruby/internal/iterator.h
+handle.o: $(hdrdir)/ruby/internal/memory.h
+handle.o: $(hdrdir)/ruby/internal/method.h
+handle.o: $(hdrdir)/ruby/internal/module.h
+handle.o: $(hdrdir)/ruby/internal/newobj.h
+handle.o: $(hdrdir)/ruby/internal/rgengc.h
+handle.o: $(hdrdir)/ruby/internal/scan_args.h
+handle.o: $(hdrdir)/ruby/internal/special_consts.h
+handle.o: $(hdrdir)/ruby/internal/static_assert.h
+handle.o: $(hdrdir)/ruby/internal/stdalign.h
+handle.o: $(hdrdir)/ruby/internal/stdbool.h
+handle.o: $(hdrdir)/ruby/internal/symbol.h
+handle.o: $(hdrdir)/ruby/internal/token_paste.h
+handle.o: $(hdrdir)/ruby/internal/value.h
+handle.o: $(hdrdir)/ruby/internal/value_type.h
+handle.o: $(hdrdir)/ruby/internal/variable.h
+handle.o: $(hdrdir)/ruby/internal/warning_push.h
+handle.o: $(hdrdir)/ruby/internal/xmalloc.h
handle.o: $(hdrdir)/ruby/missing.h
handle.o: $(hdrdir)/ruby/ruby.h
handle.o: $(hdrdir)/ruby/st.h
handle.o: $(hdrdir)/ruby/subst.h
-handle.o: $(top_srcdir)/include/ruby.h
handle.o: closure.h
handle.o: conversions.h
handle.o: fiddle.h
handle.o: function.h
handle.o: handle.c
+memory_view.o: $(RUBY_EXTCONF_H)
+memory_view.o: $(arch_hdrdir)/ruby/config.h
+memory_view.o: $(hdrdir)/ruby.h
+memory_view.o: $(hdrdir)/ruby/assert.h
+memory_view.o: $(hdrdir)/ruby/backward.h
+memory_view.o: $(hdrdir)/ruby/backward/2/assume.h
+memory_view.o: $(hdrdir)/ruby/backward/2/attributes.h
+memory_view.o: $(hdrdir)/ruby/backward/2/bool.h
+memory_view.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+memory_view.o: $(hdrdir)/ruby/backward/2/inttypes.h
+memory_view.o: $(hdrdir)/ruby/backward/2/limits.h
+memory_view.o: $(hdrdir)/ruby/backward/2/long_long.h
+memory_view.o: $(hdrdir)/ruby/backward/2/stdalign.h
+memory_view.o: $(hdrdir)/ruby/backward/2/stdarg.h
+memory_view.o: $(hdrdir)/ruby/defines.h
+memory_view.o: $(hdrdir)/ruby/intern.h
+memory_view.o: $(hdrdir)/ruby/internal/anyargs.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+memory_view.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+memory_view.o: $(hdrdir)/ruby/internal/assume.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/artificial.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/cold.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/const.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/error.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/format.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noalias.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/warning.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/weakref.h
+memory_view.o: $(hdrdir)/ruby/internal/cast.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+memory_view.o: $(hdrdir)/ruby/internal/compiler_since.h
+memory_view.o: $(hdrdir)/ruby/internal/config.h
+memory_view.o: $(hdrdir)/ruby/internal/constant_p.h
+memory_view.o: $(hdrdir)/ruby/internal/core.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rarray.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rbasic.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rbignum.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rclass.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rdata.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rfile.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rhash.h
+memory_view.o: $(hdrdir)/ruby/internal/core/robject.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rregexp.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rstring.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rstruct.h
+memory_view.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+memory_view.o: $(hdrdir)/ruby/internal/ctype.h
+memory_view.o: $(hdrdir)/ruby/internal/dllexport.h
+memory_view.o: $(hdrdir)/ruby/internal/dosish.h
+memory_view.o: $(hdrdir)/ruby/internal/error.h
+memory_view.o: $(hdrdir)/ruby/internal/eval.h
+memory_view.o: $(hdrdir)/ruby/internal/event.h
+memory_view.o: $(hdrdir)/ruby/internal/fl_type.h
+memory_view.o: $(hdrdir)/ruby/internal/gc.h
+memory_view.o: $(hdrdir)/ruby/internal/glob.h
+memory_view.o: $(hdrdir)/ruby/internal/globals.h
+memory_view.o: $(hdrdir)/ruby/internal/has/attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/builtin.h
+memory_view.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+memory_view.o: $(hdrdir)/ruby/internal/has/extension.h
+memory_view.o: $(hdrdir)/ruby/internal/has/feature.h
+memory_view.o: $(hdrdir)/ruby/internal/has/warning.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/array.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/bignum.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/class.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/compar.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/complex.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/cont.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/dir.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/enum.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/error.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/file.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/io.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/load.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/marshal.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/numeric.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/object.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/parse.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/proc.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/process.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/random.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/range.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/rational.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/re.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/ruby.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/select.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/signal.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/string.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/struct.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/thread.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/time.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/variable.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/vm.h
+memory_view.o: $(hdrdir)/ruby/internal/interpreter.h
+memory_view.o: $(hdrdir)/ruby/internal/iterator.h
+memory_view.o: $(hdrdir)/ruby/internal/memory.h
+memory_view.o: $(hdrdir)/ruby/internal/method.h
+memory_view.o: $(hdrdir)/ruby/internal/module.h
+memory_view.o: $(hdrdir)/ruby/internal/newobj.h
+memory_view.o: $(hdrdir)/ruby/internal/rgengc.h
+memory_view.o: $(hdrdir)/ruby/internal/scan_args.h
+memory_view.o: $(hdrdir)/ruby/internal/special_consts.h
+memory_view.o: $(hdrdir)/ruby/internal/static_assert.h
+memory_view.o: $(hdrdir)/ruby/internal/stdalign.h
+memory_view.o: $(hdrdir)/ruby/internal/stdbool.h
+memory_view.o: $(hdrdir)/ruby/internal/symbol.h
+memory_view.o: $(hdrdir)/ruby/internal/token_paste.h
+memory_view.o: $(hdrdir)/ruby/internal/value.h
+memory_view.o: $(hdrdir)/ruby/internal/value_type.h
+memory_view.o: $(hdrdir)/ruby/internal/variable.h
+memory_view.o: $(hdrdir)/ruby/internal/warning_push.h
+memory_view.o: $(hdrdir)/ruby/internal/xmalloc.h
+memory_view.o: $(hdrdir)/ruby/memory_view.h
+memory_view.o: $(hdrdir)/ruby/missing.h
+memory_view.o: $(hdrdir)/ruby/ruby.h
+memory_view.o: $(hdrdir)/ruby/st.h
+memory_view.o: $(hdrdir)/ruby/subst.h
+memory_view.o: closure.h
+memory_view.o: conversions.h
+memory_view.o: fiddle.h
+memory_view.o: function.h
+memory_view.o: memory_view.c
+pinned.o: $(RUBY_EXTCONF_H)
+pinned.o: $(arch_hdrdir)/ruby/config.h
+pinned.o: $(hdrdir)/ruby.h
+pinned.o: $(hdrdir)/ruby/assert.h
+pinned.o: $(hdrdir)/ruby/backward.h
+pinned.o: $(hdrdir)/ruby/backward/2/assume.h
+pinned.o: $(hdrdir)/ruby/backward/2/attributes.h
+pinned.o: $(hdrdir)/ruby/backward/2/bool.h
+pinned.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+pinned.o: $(hdrdir)/ruby/backward/2/inttypes.h
+pinned.o: $(hdrdir)/ruby/backward/2/limits.h
+pinned.o: $(hdrdir)/ruby/backward/2/long_long.h
+pinned.o: $(hdrdir)/ruby/backward/2/stdalign.h
+pinned.o: $(hdrdir)/ruby/backward/2/stdarg.h
+pinned.o: $(hdrdir)/ruby/defines.h
+pinned.o: $(hdrdir)/ruby/intern.h
+pinned.o: $(hdrdir)/ruby/internal/anyargs.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+pinned.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+pinned.o: $(hdrdir)/ruby/internal/assume.h
+pinned.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+pinned.o: $(hdrdir)/ruby/internal/attr/artificial.h
+pinned.o: $(hdrdir)/ruby/internal/attr/cold.h
+pinned.o: $(hdrdir)/ruby/internal/attr/const.h
+pinned.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+pinned.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+pinned.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+pinned.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+pinned.o: $(hdrdir)/ruby/internal/attr/error.h
+pinned.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+pinned.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+pinned.o: $(hdrdir)/ruby/internal/attr/format.h
+pinned.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+pinned.o: $(hdrdir)/ruby/internal/attr/noalias.h
+pinned.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+pinned.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+pinned.o: $(hdrdir)/ruby/internal/attr/noinline.h
+pinned.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+pinned.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+pinned.o: $(hdrdir)/ruby/internal/attr/pure.h
+pinned.o: $(hdrdir)/ruby/internal/attr/restrict.h
+pinned.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+pinned.o: $(hdrdir)/ruby/internal/attr/warning.h
+pinned.o: $(hdrdir)/ruby/internal/attr/weakref.h
+pinned.o: $(hdrdir)/ruby/internal/cast.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_is.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+pinned.o: $(hdrdir)/ruby/internal/compiler_since.h
+pinned.o: $(hdrdir)/ruby/internal/config.h
+pinned.o: $(hdrdir)/ruby/internal/constant_p.h
+pinned.o: $(hdrdir)/ruby/internal/core.h
+pinned.o: $(hdrdir)/ruby/internal/core/rarray.h
+pinned.o: $(hdrdir)/ruby/internal/core/rbasic.h
+pinned.o: $(hdrdir)/ruby/internal/core/rbignum.h
+pinned.o: $(hdrdir)/ruby/internal/core/rclass.h
+pinned.o: $(hdrdir)/ruby/internal/core/rdata.h
+pinned.o: $(hdrdir)/ruby/internal/core/rfile.h
+pinned.o: $(hdrdir)/ruby/internal/core/rhash.h
+pinned.o: $(hdrdir)/ruby/internal/core/robject.h
+pinned.o: $(hdrdir)/ruby/internal/core/rregexp.h
+pinned.o: $(hdrdir)/ruby/internal/core/rstring.h
+pinned.o: $(hdrdir)/ruby/internal/core/rstruct.h
+pinned.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+pinned.o: $(hdrdir)/ruby/internal/ctype.h
+pinned.o: $(hdrdir)/ruby/internal/dllexport.h
+pinned.o: $(hdrdir)/ruby/internal/dosish.h
+pinned.o: $(hdrdir)/ruby/internal/error.h
+pinned.o: $(hdrdir)/ruby/internal/eval.h
+pinned.o: $(hdrdir)/ruby/internal/event.h
+pinned.o: $(hdrdir)/ruby/internal/fl_type.h
+pinned.o: $(hdrdir)/ruby/internal/gc.h
+pinned.o: $(hdrdir)/ruby/internal/glob.h
+pinned.o: $(hdrdir)/ruby/internal/globals.h
+pinned.o: $(hdrdir)/ruby/internal/has/attribute.h
+pinned.o: $(hdrdir)/ruby/internal/has/builtin.h
+pinned.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+pinned.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+pinned.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+pinned.o: $(hdrdir)/ruby/internal/has/extension.h
+pinned.o: $(hdrdir)/ruby/internal/has/feature.h
+pinned.o: $(hdrdir)/ruby/internal/has/warning.h
+pinned.o: $(hdrdir)/ruby/internal/intern/array.h
+pinned.o: $(hdrdir)/ruby/internal/intern/bignum.h
+pinned.o: $(hdrdir)/ruby/internal/intern/class.h
+pinned.o: $(hdrdir)/ruby/internal/intern/compar.h
+pinned.o: $(hdrdir)/ruby/internal/intern/complex.h
+pinned.o: $(hdrdir)/ruby/internal/intern/cont.h
+pinned.o: $(hdrdir)/ruby/internal/intern/dir.h
+pinned.o: $(hdrdir)/ruby/internal/intern/enum.h
+pinned.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+pinned.o: $(hdrdir)/ruby/internal/intern/error.h
+pinned.o: $(hdrdir)/ruby/internal/intern/eval.h
+pinned.o: $(hdrdir)/ruby/internal/intern/file.h
+pinned.o: $(hdrdir)/ruby/internal/intern/gc.h
+pinned.o: $(hdrdir)/ruby/internal/intern/hash.h
+pinned.o: $(hdrdir)/ruby/internal/intern/io.h
+pinned.o: $(hdrdir)/ruby/internal/intern/load.h
+pinned.o: $(hdrdir)/ruby/internal/intern/marshal.h
+pinned.o: $(hdrdir)/ruby/internal/intern/numeric.h
+pinned.o: $(hdrdir)/ruby/internal/intern/object.h
+pinned.o: $(hdrdir)/ruby/internal/intern/parse.h
+pinned.o: $(hdrdir)/ruby/internal/intern/proc.h
+pinned.o: $(hdrdir)/ruby/internal/intern/process.h
+pinned.o: $(hdrdir)/ruby/internal/intern/random.h
+pinned.o: $(hdrdir)/ruby/internal/intern/range.h
+pinned.o: $(hdrdir)/ruby/internal/intern/rational.h
+pinned.o: $(hdrdir)/ruby/internal/intern/re.h
+pinned.o: $(hdrdir)/ruby/internal/intern/ruby.h
+pinned.o: $(hdrdir)/ruby/internal/intern/select.h
+pinned.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+pinned.o: $(hdrdir)/ruby/internal/intern/signal.h
+pinned.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+pinned.o: $(hdrdir)/ruby/internal/intern/string.h
+pinned.o: $(hdrdir)/ruby/internal/intern/struct.h
+pinned.o: $(hdrdir)/ruby/internal/intern/thread.h
+pinned.o: $(hdrdir)/ruby/internal/intern/time.h
+pinned.o: $(hdrdir)/ruby/internal/intern/variable.h
+pinned.o: $(hdrdir)/ruby/internal/intern/vm.h
+pinned.o: $(hdrdir)/ruby/internal/interpreter.h
+pinned.o: $(hdrdir)/ruby/internal/iterator.h
+pinned.o: $(hdrdir)/ruby/internal/memory.h
+pinned.o: $(hdrdir)/ruby/internal/method.h
+pinned.o: $(hdrdir)/ruby/internal/module.h
+pinned.o: $(hdrdir)/ruby/internal/newobj.h
+pinned.o: $(hdrdir)/ruby/internal/rgengc.h
+pinned.o: $(hdrdir)/ruby/internal/scan_args.h
+pinned.o: $(hdrdir)/ruby/internal/special_consts.h
+pinned.o: $(hdrdir)/ruby/internal/static_assert.h
+pinned.o: $(hdrdir)/ruby/internal/stdalign.h
+pinned.o: $(hdrdir)/ruby/internal/stdbool.h
+pinned.o: $(hdrdir)/ruby/internal/symbol.h
+pinned.o: $(hdrdir)/ruby/internal/token_paste.h
+pinned.o: $(hdrdir)/ruby/internal/value.h
+pinned.o: $(hdrdir)/ruby/internal/value_type.h
+pinned.o: $(hdrdir)/ruby/internal/variable.h
+pinned.o: $(hdrdir)/ruby/internal/warning_push.h
+pinned.o: $(hdrdir)/ruby/internal/xmalloc.h
+pinned.o: $(hdrdir)/ruby/missing.h
+pinned.o: $(hdrdir)/ruby/ruby.h
+pinned.o: $(hdrdir)/ruby/st.h
+pinned.o: $(hdrdir)/ruby/subst.h
+pinned.o: closure.h
+pinned.o: conversions.h
+pinned.o: fiddle.h
+pinned.o: function.h
+pinned.o: pinned.c
pointer.o: $(RUBY_EXTCONF_H)
pointer.o: $(arch_hdrdir)/ruby/config.h
+pointer.o: $(hdrdir)/ruby.h
+pointer.o: $(hdrdir)/ruby/assert.h
pointer.o: $(hdrdir)/ruby/backward.h
+pointer.o: $(hdrdir)/ruby/backward/2/assume.h
+pointer.o: $(hdrdir)/ruby/backward/2/attributes.h
+pointer.o: $(hdrdir)/ruby/backward/2/bool.h
+pointer.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+pointer.o: $(hdrdir)/ruby/backward/2/inttypes.h
+pointer.o: $(hdrdir)/ruby/backward/2/limits.h
+pointer.o: $(hdrdir)/ruby/backward/2/long_long.h
+pointer.o: $(hdrdir)/ruby/backward/2/stdalign.h
+pointer.o: $(hdrdir)/ruby/backward/2/stdarg.h
pointer.o: $(hdrdir)/ruby/defines.h
pointer.o: $(hdrdir)/ruby/encoding.h
pointer.o: $(hdrdir)/ruby/intern.h
+pointer.o: $(hdrdir)/ruby/internal/anyargs.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+pointer.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+pointer.o: $(hdrdir)/ruby/internal/assume.h
+pointer.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+pointer.o: $(hdrdir)/ruby/internal/attr/artificial.h
+pointer.o: $(hdrdir)/ruby/internal/attr/cold.h
+pointer.o: $(hdrdir)/ruby/internal/attr/const.h
+pointer.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+pointer.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+pointer.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+pointer.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+pointer.o: $(hdrdir)/ruby/internal/attr/error.h
+pointer.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+pointer.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+pointer.o: $(hdrdir)/ruby/internal/attr/format.h
+pointer.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+pointer.o: $(hdrdir)/ruby/internal/attr/noalias.h
+pointer.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+pointer.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+pointer.o: $(hdrdir)/ruby/internal/attr/noinline.h
+pointer.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+pointer.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+pointer.o: $(hdrdir)/ruby/internal/attr/pure.h
+pointer.o: $(hdrdir)/ruby/internal/attr/restrict.h
+pointer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+pointer.o: $(hdrdir)/ruby/internal/attr/warning.h
+pointer.o: $(hdrdir)/ruby/internal/attr/weakref.h
+pointer.o: $(hdrdir)/ruby/internal/cast.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_is.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+pointer.o: $(hdrdir)/ruby/internal/compiler_since.h
+pointer.o: $(hdrdir)/ruby/internal/config.h
+pointer.o: $(hdrdir)/ruby/internal/constant_p.h
+pointer.o: $(hdrdir)/ruby/internal/core.h
+pointer.o: $(hdrdir)/ruby/internal/core/rarray.h
+pointer.o: $(hdrdir)/ruby/internal/core/rbasic.h
+pointer.o: $(hdrdir)/ruby/internal/core/rbignum.h
+pointer.o: $(hdrdir)/ruby/internal/core/rclass.h
+pointer.o: $(hdrdir)/ruby/internal/core/rdata.h
+pointer.o: $(hdrdir)/ruby/internal/core/rfile.h
+pointer.o: $(hdrdir)/ruby/internal/core/rhash.h
+pointer.o: $(hdrdir)/ruby/internal/core/robject.h
+pointer.o: $(hdrdir)/ruby/internal/core/rregexp.h
+pointer.o: $(hdrdir)/ruby/internal/core/rstring.h
+pointer.o: $(hdrdir)/ruby/internal/core/rstruct.h
+pointer.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+pointer.o: $(hdrdir)/ruby/internal/ctype.h
+pointer.o: $(hdrdir)/ruby/internal/dllexport.h
+pointer.o: $(hdrdir)/ruby/internal/dosish.h
+pointer.o: $(hdrdir)/ruby/internal/error.h
+pointer.o: $(hdrdir)/ruby/internal/eval.h
+pointer.o: $(hdrdir)/ruby/internal/event.h
+pointer.o: $(hdrdir)/ruby/internal/fl_type.h
+pointer.o: $(hdrdir)/ruby/internal/gc.h
+pointer.o: $(hdrdir)/ruby/internal/glob.h
+pointer.o: $(hdrdir)/ruby/internal/globals.h
+pointer.o: $(hdrdir)/ruby/internal/has/attribute.h
+pointer.o: $(hdrdir)/ruby/internal/has/builtin.h
+pointer.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+pointer.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+pointer.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+pointer.o: $(hdrdir)/ruby/internal/has/extension.h
+pointer.o: $(hdrdir)/ruby/internal/has/feature.h
+pointer.o: $(hdrdir)/ruby/internal/has/warning.h
+pointer.o: $(hdrdir)/ruby/internal/intern/array.h
+pointer.o: $(hdrdir)/ruby/internal/intern/bignum.h
+pointer.o: $(hdrdir)/ruby/internal/intern/class.h
+pointer.o: $(hdrdir)/ruby/internal/intern/compar.h
+pointer.o: $(hdrdir)/ruby/internal/intern/complex.h
+pointer.o: $(hdrdir)/ruby/internal/intern/cont.h
+pointer.o: $(hdrdir)/ruby/internal/intern/dir.h
+pointer.o: $(hdrdir)/ruby/internal/intern/enum.h
+pointer.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+pointer.o: $(hdrdir)/ruby/internal/intern/error.h
+pointer.o: $(hdrdir)/ruby/internal/intern/eval.h
+pointer.o: $(hdrdir)/ruby/internal/intern/file.h
+pointer.o: $(hdrdir)/ruby/internal/intern/gc.h
+pointer.o: $(hdrdir)/ruby/internal/intern/hash.h
+pointer.o: $(hdrdir)/ruby/internal/intern/io.h
+pointer.o: $(hdrdir)/ruby/internal/intern/load.h
+pointer.o: $(hdrdir)/ruby/internal/intern/marshal.h
+pointer.o: $(hdrdir)/ruby/internal/intern/numeric.h
+pointer.o: $(hdrdir)/ruby/internal/intern/object.h
+pointer.o: $(hdrdir)/ruby/internal/intern/parse.h
+pointer.o: $(hdrdir)/ruby/internal/intern/proc.h
+pointer.o: $(hdrdir)/ruby/internal/intern/process.h
+pointer.o: $(hdrdir)/ruby/internal/intern/random.h
+pointer.o: $(hdrdir)/ruby/internal/intern/range.h
+pointer.o: $(hdrdir)/ruby/internal/intern/rational.h
+pointer.o: $(hdrdir)/ruby/internal/intern/re.h
+pointer.o: $(hdrdir)/ruby/internal/intern/ruby.h
+pointer.o: $(hdrdir)/ruby/internal/intern/select.h
+pointer.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+pointer.o: $(hdrdir)/ruby/internal/intern/signal.h
+pointer.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+pointer.o: $(hdrdir)/ruby/internal/intern/string.h
+pointer.o: $(hdrdir)/ruby/internal/intern/struct.h
+pointer.o: $(hdrdir)/ruby/internal/intern/thread.h
+pointer.o: $(hdrdir)/ruby/internal/intern/time.h
+pointer.o: $(hdrdir)/ruby/internal/intern/variable.h
+pointer.o: $(hdrdir)/ruby/internal/intern/vm.h
+pointer.o: $(hdrdir)/ruby/internal/interpreter.h
+pointer.o: $(hdrdir)/ruby/internal/iterator.h
+pointer.o: $(hdrdir)/ruby/internal/memory.h
+pointer.o: $(hdrdir)/ruby/internal/method.h
+pointer.o: $(hdrdir)/ruby/internal/module.h
+pointer.o: $(hdrdir)/ruby/internal/newobj.h
+pointer.o: $(hdrdir)/ruby/internal/rgengc.h
+pointer.o: $(hdrdir)/ruby/internal/scan_args.h
+pointer.o: $(hdrdir)/ruby/internal/special_consts.h
+pointer.o: $(hdrdir)/ruby/internal/static_assert.h
+pointer.o: $(hdrdir)/ruby/internal/stdalign.h
+pointer.o: $(hdrdir)/ruby/internal/stdbool.h
+pointer.o: $(hdrdir)/ruby/internal/symbol.h
+pointer.o: $(hdrdir)/ruby/internal/token_paste.h
+pointer.o: $(hdrdir)/ruby/internal/value.h
+pointer.o: $(hdrdir)/ruby/internal/value_type.h
+pointer.o: $(hdrdir)/ruby/internal/variable.h
+pointer.o: $(hdrdir)/ruby/internal/warning_push.h
+pointer.o: $(hdrdir)/ruby/internal/xmalloc.h
pointer.o: $(hdrdir)/ruby/io.h
+pointer.o: $(hdrdir)/ruby/memory_view.h
pointer.o: $(hdrdir)/ruby/missing.h
pointer.o: $(hdrdir)/ruby/onigmo.h
pointer.o: $(hdrdir)/ruby/oniguruma.h
pointer.o: $(hdrdir)/ruby/ruby.h
pointer.o: $(hdrdir)/ruby/st.h
pointer.o: $(hdrdir)/ruby/subst.h
-pointer.o: $(top_srcdir)/include/ruby.h
pointer.o: closure.h
pointer.o: conversions.h
pointer.o: fiddle.h
diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb
index 2c333001e5..6ca685317e 100644
--- a/ext/fiddle/extconf.rb
+++ b/ext/fiddle/extconf.rb
@@ -3,46 +3,107 @@ require 'mkmf'
# :stopdoc:
+def gcc?
+ RbConfig::CONFIG["GCC"] == "yes"
+end
+
+def disable_optimization_build_flag(flags)
+ if gcc?
+ expanded_flags = RbConfig.expand(flags.dup)
+ optimization_option_pattern = /(^|\s)?-O\d(\s|$)?/
+ if optimization_option_pattern.match?(expanded_flags)
+ expanded_flags.gsub(optimization_option_pattern, '\\1-Og\\2')
+ else
+ flags + " -Og"
+ end
+ else
+ flags
+ end
+end
+
+def enable_debug_build_flag(flags)
+ if gcc?
+ expanded_flags = RbConfig.expand(flags.dup)
+ debug_option_pattern = /(^|\s)-g(?:gdb)?\d?(\s|$)/
+ if debug_option_pattern.match?(expanded_flags)
+ expanded_flags.gsub(debug_option_pattern, '\\1-ggdb3\\2')
+ else
+ flags + " -ggdb3"
+ end
+ else
+ flags
+ end
+end
+
+checking_for(checking_message("--enable-debug-build option")) do
+ enable_debug_build = enable_config("debug-build", false)
+ if enable_debug_build
+ $CFLAGS = disable_optimization_build_flag($CFLAGS)
+ $CFLAGS = enable_debug_build_flag($CFLAGS)
+ end
+ enable_debug_build
+end
+
+libffi_version = nil
+have_libffi = false
bundle = enable_config('bundled-libffi')
-if ! bundle
+unless bundle
dir_config 'libffi'
- pkg_config("libffi") and
- ver = pkg_config("libffi", "modversion")
+ if pkg_config("libffi")
+ libffi_version = pkg_config("libffi", "modversion")
+ end
+ have_ffi_header = false
if have_header(ffi_header = 'ffi.h')
- true
+ have_ffi_header = true
elsif have_header(ffi_header = 'ffi/ffi.h')
- $defs.push(format('-DUSE_HEADER_HACKS'))
- true
- end and (have_library('ffi') || have_library('libffi'))
-end or
-begin
- ver = bundle != false &&
- Dir.glob("#{$srcdir}/libffi-*/")
- .map {|n| File.basename(n)}
- .max_by {|n| n.scan(/\d+/).map(&:to_i)}
- unless ver
+ $defs.push('-DUSE_HEADER_HACKS')
+ have_ffi_header = true
+ end
+ if have_ffi_header && (have_library('ffi') || have_library('libffi'))
+ have_libffi = true
+ end
+end
+
+unless have_libffi
+ # for https://github.com/ruby/fiddle
+ extlibs_rb = File.expand_path("../../bin/extlibs.rb", $srcdir)
+ if bundle && File.exist?(extlibs_rb)
+ require "fileutils"
+ require_relative "../../bin/extlibs"
+ extlibs = ExtLibs.new
+ cache_dir = File.expand_path("../../tmp/.download_cache", $srcdir)
+ ext_dir = File.expand_path("../../ext", $srcdir)
+ Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)}
+ extlibs.run(["--cache=#{cache_dir}", ext_dir])
+ end
+ if bundle != false
+ libffi_package_name = Dir.glob("#{$srcdir}/libffi-*/")
+ .map {|n| File.basename(n)}
+ .max_by {|n| n.scan(/\d+/).map(&:to_i)}
+ end
+ unless libffi_package_name
raise "missing libffi. Please install libffi."
end
- srcdir = "#{$srcdir}/#{ver}"
+ libffi_srcdir = "#{$srcdir}/#{libffi_package_name}"
ffi_header = 'ffi.h'
libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
- libffi.dir = ver
+ libffi.dir = libffi_package_name
if $srcdir == "."
- libffi.builddir = "#{ver}/#{RUBY_PLATFORM}"
+ libffi.builddir = libffi_package_name
libffi.srcdir = "."
else
libffi.builddir = libffi.dir
- libffi.srcdir = relative_from(srcdir, "..")
+ libffi.srcdir = relative_from(libffi_srcdir, "..")
end
libffi.include = "#{libffi.builddir}/include"
libffi.lib = "#{libffi.builddir}/.libs"
libffi.a = "#{libffi.lib}/libffi_convenience.#{$LIBEXT}"
nowarn = CONFIG.merge("warnflags"=>"")
libffi.cflags = RbConfig.expand("$(CFLAGS)".dup, nowarn)
- ver = ver[/libffi-(.*)/, 1]
+ libffi_version = libffi_package_name[/libffi-(.*)/, 1]
FileUtils.mkdir_p(libffi.dir)
libffi.opt = CONFIG['configure_args'][/'(-C)'/, 1]
@@ -71,7 +132,6 @@ begin
args.concat %W[
--srcdir=#{libffi.srcdir}
--host=#{libffi.arch}
- --enable-builddir=#{RUBY_PLATFORM}
]
args << ($enable_shared || !$static ? '--enable-shared' : '--enable-static')
args << libffi.opt if libffi.opt
@@ -88,7 +148,7 @@ begin
begin
IO.copy_stream(libffi.dir + "/config.log", Logging.instance_variable_get(:@logfile))
rescue SystemCallError => e
- Logfile.message("%s\n", e.message)
+ Logging.message("%s\n", e.message)
end
raise "failed to configure libffi. Please install libffi."
end
@@ -97,15 +157,33 @@ begin
FileUtils.rm_f("#{libffi.include}/ffitarget.h")
end
unless File.file?("#{libffi.include}/ffitarget.h")
- FileUtils.cp("#{srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true)
+ FileUtils.cp("#{libffi_srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true)
end
$INCFLAGS << " -I" << libffi.include
end
-if ver
- ver = ver.gsub(/-rc\d+/, '') # If ver contains rc version, just ignored.
- ver = (ver.split('.') + [0,0])[0,3]
- $defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % ver }})
+if libffi_version
+ # If libffi_version contains rc version, just ignored.
+ libffi_version = libffi_version.gsub(/-rc\d+/, '')
+ libffi_version = (libffi_version.split('.').map(&:to_i) + [0,0])[0,3]
+ $defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % libffi_version }})
+ warn "libffi_version: #{libffi_version.join('.')}"
+end
+
+case
+when $mswin, $mingw, (libffi_version && (libffi_version <=> [3, 2]) >= 0)
+ $defs << "-DUSE_FFI_CLOSURE_ALLOC=1"
+when (libffi_version && (libffi_version <=> [3, 2]) < 0)
+else
+ have_func('ffi_closure_alloc', ffi_header)
+end
+
+if libffi_version
+ if (libffi_version <=> [3, 0, 11]) >= 0
+ $defs << "-DHAVE_FFI_PREP_CIF_VAR"
+ end
+else
+ have_func('ffi_prep_cif_var', ffi_header)
end
have_header 'sys/mman.h'
@@ -122,6 +200,8 @@ elsif have_header "windows.h"
%w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
abort "missing function #{func}" unless have_func(func)
end
+
+ have_library "ws2_32"
end
have_const('FFI_STDCALL', ffi_header)
@@ -132,19 +212,24 @@ types.each do |type, signed|
if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config
if size = $2 and size != 'VOIDP'
size = types.fetch(size) {size}
- $defs << format("-DTYPE_%s=TYPE_%s", signed||type, size)
+ $defs << "-DTYPE_#{signed||type}=TYPE_#{size}"
end
if signed
check_signedness(type.downcase, "stddef.h")
end
+ else
+ check_signedness(type.downcase, "stddef.h")
end
end
+if have_header("ruby/memory_view.h")
+ have_type("rb_memory_view_t", ["ruby/memory_view.h"])
+end
+
if libffi
$LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk
$INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
end
-$INCFLAGS << " -I$(top_srcdir)"
create_makefile 'fiddle' do |conf|
if !libffi
next conf << "LIBFFI_CLEAN = none\n"
diff --git a/ext/fiddle/extlibs b/ext/fiddle/extlibs
index 290b814590..68dac46a95 100644
--- a/ext/fiddle/extlibs
+++ b/ext/fiddle/extlibs
@@ -1,5 +1,13 @@
-http://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz \
+ver = 3.2.1
+pkg = libffi-$(ver)
+
+https://ftp.osuosl.org/pub/blfs/conglomeration/libffi/$(pkg).tar.gz \
md5:83b89587607e3eb65c70d361f13bab43 \
sha512:980ca30a8d76f963fca722432b1fe5af77d7a4e4d2eac5144fbc5374d4c596609a293440573f4294207e1bdd9fda80ad1e1cafb2ffb543df5a275bc3bd546483 \
#
- win32/libffi-3.2.1-mswin.patch -p0
+ win32/$(pkg)-mswin.patch -p0
+
+$(pkg)/config.guess -> /tool/config.guess
+$(pkg)/config.sub -> /tool/config.sub
+
+! chdir: $(pkg)| autoconf || exit 0
diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c
index 9f3d1537d6..dd819a298c 100644
--- a/ext/fiddle/fiddle.c
+++ b/ext/fiddle/fiddle.c
@@ -1,41 +1,15 @@
#include <fiddle.h>
VALUE mFiddle;
+VALUE rb_eFiddleDLError;
VALUE rb_eFiddleError;
-#ifndef TYPE_SSIZE_T
-# if SIZEOF_SIZE_T == SIZEOF_INT
-# define TYPE_SSIZE_T TYPE_INT
-# elif SIZEOF_SIZE_T == SIZEOF_LONG
-# define TYPE_SSIZE_T TYPE_LONG
-# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
-# define TYPE_SSIZE_T TYPE_LONG_LONG
-# endif
-#endif
-#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
-
-#ifndef TYPE_PTRDIFF_T
-# if SIZEOF_PTRDIFF_T == SIZEOF_INT
-# define TYPE_PTRDIFF_T TYPE_INT
-# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
-# define TYPE_PTRDIFF_T TYPE_LONG
-# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
-# define TYPE_PTRDIFF_T TYPE_LONG_LONG
-# endif
-#endif
+void Init_fiddle_pointer(void);
+void Init_fiddle_pinned(void);
-#ifndef TYPE_INTPTR_T
-# if SIZEOF_INTPTR_T == SIZEOF_INT
-# define TYPE_INTPTR_T TYPE_INT
-# elif SIZEOF_INTPTR_T == SIZEOF_LONG
-# define TYPE_INTPTR_T TYPE_LONG
-# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
-# define TYPE_INTPTR_T TYPE_LONG_LONG
-# endif
+#ifdef FIDDLE_MEMORY_VIEW
+void Init_fiddle_memory_view(void);
#endif
-#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
-
-void Init_fiddle_pointer(void);
/*
* call-seq: Fiddle.malloc(size)
@@ -47,8 +21,7 @@ static VALUE
rb_fiddle_malloc(VALUE self, VALUE size)
{
void *ptr;
-
- ptr = (void*)ruby_xmalloc(NUM2SIZET(size));
+ ptr = (void*)ruby_xcalloc(1, NUM2SIZET(size));
return PTR2NUM(ptr);
}
@@ -164,11 +137,32 @@ Init_fiddle(void)
mFiddle = rb_define_module("Fiddle");
/*
+ * Document-class: Fiddle::Error
+ *
+ * Generic error class for Fiddle
+ */
+ rb_eFiddleError = rb_define_class_under(mFiddle, "Error", rb_eStandardError);
+
+ /*
+ * Ruby installed by RubyInstaller for Windows always require
+ * bundled Fiddle because ruby_installer/runtime/dll_directory.rb
+ * requires Fiddle. It's used by
+ * rubygems/defaults/operating_system.rb. It means that the
+ * bundled Fiddle is always required on initialization.
+ *
+ * We just remove existing Fiddle::DLError here to override
+ * the bundled Fiddle.
+ */
+ if (rb_const_defined(mFiddle, rb_intern("DLError"))) {
+ rb_const_remove(mFiddle, rb_intern("DLError"));
+ }
+
+ /*
* Document-class: Fiddle::DLError
*
* standard dynamic load exception
*/
- rb_eFiddleError = rb_define_class_under(mFiddle, "DLError", rb_eStandardError);
+ rb_eFiddleDLError = rb_define_class_under(mFiddle, "DLError", rb_eFiddleError);
/* Document-const: TYPE_VOID
*
@@ -214,6 +208,38 @@ Init_fiddle(void)
rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
#endif
+#ifdef TYPE_INT8_T
+ /* Document-const: TYPE_INT8_T
+ *
+ * C type - int8_t
+ */
+ rb_define_const(mFiddle, "TYPE_INT8_T", INT2NUM(TYPE_INT8_T));
+#endif
+
+#ifdef TYPE_INT16_T
+ /* Document-const: TYPE_INT16_T
+ *
+ * C type - int16_t
+ */
+ rb_define_const(mFiddle, "TYPE_INT16_T", INT2NUM(TYPE_INT16_T));
+#endif
+
+#ifdef TYPE_INT32_T
+ /* Document-const: TYPE_INT32_T
+ *
+ * C type - int32_t
+ */
+ rb_define_const(mFiddle, "TYPE_INT32_T", INT2NUM(TYPE_INT32_T));
+#endif
+
+#ifdef TYPE_INT64_T
+ /* Document-const: TYPE_INT64_T
+ *
+ * C type - int64_t
+ */
+ rb_define_const(mFiddle, "TYPE_INT64_T", INT2NUM(TYPE_INT64_T));
+#endif
+
/* Document-const: TYPE_FLOAT
*
* C type - float
@@ -226,6 +252,20 @@ Init_fiddle(void)
*/
rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE));
+#ifdef HAVE_FFI_PREP_CIF_VAR
+ /* Document-const: TYPE_VARIADIC
+ *
+ * C type - ...
+ */
+ rb_define_const(mFiddle, "TYPE_VARIADIC", INT2NUM(TYPE_VARIADIC));
+#endif
+
+ /* Document-const: TYPE_CONST_STRING
+ *
+ * C type - const char* ('\0' terminated const char*)
+ */
+ rb_define_const(mFiddle, "TYPE_CONST_STRING", INT2NUM(TYPE_CONST_STRING));
+
/* Document-const: TYPE_SIZE_T
*
* C type - size_t
@@ -294,6 +334,30 @@ Init_fiddle(void)
rb_define_const(mFiddle, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
#endif
+ /* Document-const: ALIGN_INT8_T
+ *
+ * The alignment size of a int8_t
+ */
+ rb_define_const(mFiddle, "ALIGN_INT8_T", INT2NUM(ALIGN_INT8_T));
+
+ /* Document-const: ALIGN_INT16_T
+ *
+ * The alignment size of a int16_t
+ */
+ rb_define_const(mFiddle, "ALIGN_INT16_T", INT2NUM(ALIGN_INT16_T));
+
+ /* Document-const: ALIGN_INT32_T
+ *
+ * The alignment size of a int32_t
+ */
+ rb_define_const(mFiddle, "ALIGN_INT32_T", INT2NUM(ALIGN_INT32_T));
+
+ /* Document-const: ALIGN_INT64_T
+ *
+ * The alignment size of a int64_t
+ */
+ rb_define_const(mFiddle, "ALIGN_INT64_T", INT2NUM(ALIGN_INT64_T));
+
/* Document-const: ALIGN_FLOAT
*
* The alignment size of a float
@@ -384,6 +448,30 @@ Init_fiddle(void)
rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
#endif
+ /* Document-const: SIZEOF_INT8_T
+ *
+ * size of a int8_t
+ */
+ rb_define_const(mFiddle, "SIZEOF_INT8_T", INT2NUM(sizeof(int8_t)));
+
+ /* Document-const: SIZEOF_INT16_T
+ *
+ * size of a int16_t
+ */
+ rb_define_const(mFiddle, "SIZEOF_INT16_T", INT2NUM(sizeof(int16_t)));
+
+ /* Document-const: SIZEOF_INT32_T
+ *
+ * size of a int32_t
+ */
+ rb_define_const(mFiddle, "SIZEOF_INT32_T", INT2NUM(sizeof(int32_t)));
+
+ /* Document-const: SIZEOF_INT64_T
+ *
+ * size of a int64_t
+ */
+ rb_define_const(mFiddle, "SIZEOF_INT64_T", INT2NUM(sizeof(int64_t)));
+
/* Document-const: SIZEOF_FLOAT
*
* size of a float
@@ -426,6 +514,12 @@ Init_fiddle(void)
*/
rb_define_const(mFiddle, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t)));
+ /* Document-const: SIZEOF_CONST_STRING
+ *
+ * size of a const char*
+ */
+ rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*)));
+
/* Document-const: RUBY_FREE
*
* Address of the ruby_xfree() function
@@ -450,5 +544,10 @@ Init_fiddle(void)
Init_fiddle_closure();
Init_fiddle_handle();
Init_fiddle_pointer();
+ Init_fiddle_pinned();
+
+#ifdef FIDDLE_MEMORY_VIEW
+ Init_fiddle_memory_view();
+#endif
}
/* vim: set noet sws=4 sw=4: */
diff --git a/ext/fiddle/fiddle.gemspec b/ext/fiddle/fiddle.gemspec
index 054d7c06ec..a47f795f59 100644
--- a/ext/fiddle/fiddle.gemspec
+++ b/ext/fiddle/fiddle.gemspec
@@ -1,21 +1,66 @@
# frozen_string_literal: true
+
+version_module = Module.new do
+ version_rb = File.join(__dir__, "lib/fiddle/version.rb")
+ module_eval(File.read(version_rb), version_rb, __LINE__)
+end
+
Gem::Specification.new do |spec|
spec.name = "fiddle"
- spec.version = '1.0.0.beta2'
+ spec.version = version_module::Fiddle::VERSION
spec.authors = ["Aaron Patterson", "SHIBATA Hiroshi"]
spec.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org"]
spec.summary = %q{A libffi wrapper for Ruby.}
spec.description = %q{A libffi wrapper for Ruby.}
spec.homepage = "https://github.com/ruby/fiddle"
- spec.license = "BSD-2-Clause"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "ext/fiddle/closure.c", "ext/fiddle/closure.h", "ext/fiddle/conversions.c", "ext/fiddle/conversions.h", "ext/fiddle/extconf.rb", "ext/fiddle/extlibs", "ext/fiddle/fiddle.c", "ext/fiddle/fiddle.h", "ext/fiddle/function.c", "ext/fiddle/function.h", "ext/fiddle/handle.c", "ext/fiddle/pointer.c", "ext/fiddle/win32/fficonfig.h", "ext/fiddle/win32/libffi-3.2.1-mswin.patch", "ext/fiddle/win32/libffi-config.rb", "ext/fiddle/win32/libffi.mk.tmpl", "fiddle.gemspec", "lib/fiddle.rb", "lib/fiddle/closure.rb", "lib/fiddle/cparser.rb", "lib/fiddle/function.rb", "lib/fiddle/import.rb", "lib/fiddle/pack.rb", "lib/fiddle/struct.rb", "lib/fiddle/types.rb", "lib/fiddle/value.rb"]
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.files = [
+ "LICENSE.txt",
+ "README.md",
+ "Rakefile",
+ "bin/downloader.rb",
+ "bin/extlibs.rb",
+ "ext/fiddle/closure.c",
+ "ext/fiddle/closure.h",
+ "ext/fiddle/conversions.c",
+ "ext/fiddle/conversions.h",
+ "ext/fiddle/depend",
+ "ext/fiddle/extconf.rb",
+ "ext/fiddle/extlibs",
+ "ext/fiddle/fiddle.c",
+ "ext/fiddle/fiddle.h",
+ "ext/fiddle/function.c",
+ "ext/fiddle/function.h",
+ "ext/fiddle/handle.c",
+ "ext/fiddle/memory_view.c",
+ "ext/fiddle/pinned.c",
+ "ext/fiddle/pointer.c",
+ "ext/fiddle/win32/fficonfig.h",
+ "ext/fiddle/win32/libffi-3.2.1-mswin.patch",
+ "ext/fiddle/win32/libffi-config.rb",
+ "ext/fiddle/win32/libffi.mk.tmpl",
+ "fiddle.gemspec",
+ "lib/fiddle.rb",
+ "lib/fiddle/closure.rb",
+ "lib/fiddle/cparser.rb",
+ "lib/fiddle/function.rb",
+ "lib/fiddle/import.rb",
+ "lib/fiddle/pack.rb",
+ "lib/fiddle/struct.rb",
+ "lib/fiddle/types.rb",
+ "lib/fiddle/value.rb",
+ "lib/fiddle/version.rb",
+ ]
spec.require_paths = ["lib"]
+ spec.extensions = ["ext/fiddle/extconf.rb"]
+
+ spec.required_ruby_version = ">= 2.3.0"
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
spec.add_development_dependency "rake-compiler"
+
+ spec.metadata["msys2_mingw_dependencies"] = "libffi"
end
diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h
index d2583c1cbf..dbad910d07 100644
--- a/ext/fiddle/fiddle.h
+++ b/ext/fiddle/fiddle.h
@@ -58,38 +58,38 @@
# error "CHAR_BIT not supported"
#endif
-# if SIZEOF_SHORT == 2
-# define ffi_type_ushort ffi_type_uint16
-# define ffi_type_sshort ffi_type_sint16
-# elif SIZEOF_SHORT == 4
-# define ffi_type_ushort ffi_type_uint32
-# define ffi_type_sshort ffi_type_sint32
-# else
-# error "short size not supported"
-# endif
+#if SIZEOF_SHORT == 2
+# define ffi_type_ushort ffi_type_uint16
+# define ffi_type_sshort ffi_type_sint16
+#elif SIZEOF_SHORT == 4
+# define ffi_type_ushort ffi_type_uint32
+# define ffi_type_sshort ffi_type_sint32
+#else
+# error "short size not supported"
+#endif
-# if SIZEOF_INT == 2
-# define ffi_type_uint ffi_type_uint16
-# define ffi_type_sint ffi_type_sint16
-# elif SIZEOF_INT == 4
-# define ffi_type_uint ffi_type_uint32
-# define ffi_type_sint ffi_type_sint32
-# elif SIZEOF_INT == 8
-# define ffi_type_uint ffi_type_uint64
-# define ffi_type_sint ffi_type_sint64
-# else
-# error "int size not supported"
-# endif
+#if SIZEOF_INT == 2
+# define ffi_type_uint ffi_type_uint16
+# define ffi_type_sint ffi_type_sint16
+#elif SIZEOF_INT == 4
+# define ffi_type_uint ffi_type_uint32
+# define ffi_type_sint ffi_type_sint32
+#elif SIZEOF_INT == 8
+# define ffi_type_uint ffi_type_uint64
+# define ffi_type_sint ffi_type_sint64
+#else
+# error "int size not supported"
+#endif
-# if SIZEOF_LONG == 4
-# define ffi_type_ulong ffi_type_uint32
-# define ffi_type_slong ffi_type_sint32
-# elif SIZEOF_LONG == 8
-# define ffi_type_ulong ffi_type_uint64
-# define ffi_type_slong ffi_type_sint64
-# else
-# error "long size not supported"
-# endif
+#if SIZEOF_LONG == 4
+# define ffi_type_ulong ffi_type_uint32
+# define ffi_type_slong ffi_type_sint32
+#elif SIZEOF_LONG == 8
+# define ffi_type_ulong ffi_type_uint64
+# define ffi_type_slong ffi_type_sint64
+#else
+# error "long size not supported"
+#endif
#if HAVE_LONG_LONG
# if SIZEOF_LONG_LONG == 8
@@ -115,12 +115,67 @@
#endif
#define TYPE_FLOAT 7
#define TYPE_DOUBLE 8
+#define TYPE_VARIADIC 9
+#define TYPE_CONST_STRING 10
+
+#define TYPE_INT8_T TYPE_CHAR
+#if SIZEOF_SHORT == 2
+# define TYPE_INT16_T TYPE_SHORT
+#elif SIZEOF_INT == 2
+# define TYPE_INT16_T TYPE_INT
+#endif
+#if SIZEOF_SHORT == 4
+# define TYPE_INT32_T TYPE_SHORT
+#elif SIZEOF_INT == 4
+# define TYPE_INT32_T TYPE_INT
+#elif SIZEOF_LONG == 4
+# define TYPE_INT32_T TYPE_LONG
+#endif
+#if SIZEOF_INT == 8
+# define TYPE_INT64_T TYPE_INT
+#elif SIZEOF_LONG == 8
+# define TYPE_INT64_T TYPE_LONG
+#elif defined(TYPE_LONG_LONG)
+# define TYPE_INT64_T TYPE_LONG_LONG
+#endif
+
+#ifndef TYPE_SSIZE_T
+# if SIZEOF_SIZE_T == SIZEOF_INT
+# define TYPE_SSIZE_T TYPE_INT
+# elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define TYPE_SSIZE_T TYPE_LONG
+# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define TYPE_SSIZE_T TYPE_LONG_LONG
+# endif
+#endif
+#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
+
+#ifndef TYPE_PTRDIFF_T
+# if SIZEOF_PTRDIFF_T == SIZEOF_INT
+# define TYPE_PTRDIFF_T TYPE_INT
+# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
+# define TYPE_PTRDIFF_T TYPE_LONG
+# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
+# define TYPE_PTRDIFF_T TYPE_LONG_LONG
+# endif
+#endif
+
+#ifndef TYPE_INTPTR_T
+# if SIZEOF_INTPTR_T == SIZEOF_INT
+# define TYPE_INTPTR_T TYPE_INT
+# elif SIZEOF_INTPTR_T == SIZEOF_LONG
+# define TYPE_INTPTR_T TYPE_LONG
+# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
+# define TYPE_INTPTR_T TYPE_LONG_LONG
+# endif
+#endif
+#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
#define ALIGN_VOIDP ALIGN_OF(void*)
-#define ALIGN_SHORT ALIGN_OF(short)
#define ALIGN_CHAR ALIGN_OF(char)
+#define ALIGN_SHORT ALIGN_OF(short)
#define ALIGN_INT ALIGN_OF(int)
#define ALIGN_LONG ALIGN_OF(long)
#if HAVE_LONG_LONG
@@ -129,8 +184,17 @@
#define ALIGN_FLOAT ALIGN_OF(float)
#define ALIGN_DOUBLE ALIGN_OF(double)
+#define ALIGN_INT8_T ALIGN_OF(int8_t)
+#define ALIGN_INT16_T ALIGN_OF(int16_t)
+#define ALIGN_INT32_T ALIGN_OF(int32_t)
+#define ALIGN_INT64_T ALIGN_OF(int64_t)
+
+#ifdef HAVE_TYPE_RB_MEMORY_VIEW_T
+# define FIDDLE_MEMORY_VIEW
+#endif
+
extern VALUE mFiddle;
-extern VALUE rb_eFiddleError;
+extern VALUE rb_eFiddleDLError;
VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type);
diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c
index 8e280567db..d15a54bfa6 100644
--- a/ext/fiddle/function.c
+++ b/ext/fiddle/function.c
@@ -1,6 +1,8 @@
#include <fiddle.h>
#include <ruby/thread.h>
+#include <stdbool.h>
+
#ifdef PRIsVALUE
# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
# define RB_OBJ_STRING(obj) (obj)
@@ -19,21 +21,21 @@ VALUE cFiddleFunction;
#define Check_Max_Args_Long(name, len) \
Check_Max_Args_(name, len, "l")
#define Check_Max_Args_(name, len, fmt) \
- if ((size_t)(len) < MAX_ARGS) { \
- /* OK */ \
- } \
- else { \
- rb_raise(rb_eTypeError, \
- name" is so large that it can cause integer overflow (%"fmt"d)", \
- (len)); \
- }
+ do { \
+ if ((size_t)(len) >= MAX_ARGS) { \
+ rb_raise(rb_eTypeError, \
+ "%s is so large " \
+ "that it can cause integer overflow (%"fmt"d)", \
+ (name), (len)); \
+ } \
+ } while (0)
static void
deallocate(void *p)
{
- ffi_cif *ptr = p;
- if (ptr->arg_types) xfree(ptr->arg_types);
- xfree(ptr);
+ ffi_cif *cif = p;
+ if (cif->arg_types) xfree(cif->arg_types);
+ xfree(cif);
}
static size_t
@@ -75,72 +77,114 @@ rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type)
return rb_class_new_instance(3, argv, cFiddleFunction);
}
-static int
-parse_keyword_arg_i(VALUE key, VALUE value, VALUE self)
+static VALUE
+normalize_argument_types(const char *name,
+ VALUE arg_types,
+ bool *is_variadic)
{
- if (key == ID2SYM(rb_intern("name"))) {
- rb_iv_set(self, "@name", value);
- } else {
- rb_raise(rb_eArgError, "unknown keyword: %"PRIsVALUE,
- RB_OBJ_STRING(key));
+ VALUE normalized_arg_types;
+ int i;
+ int n_arg_types;
+ *is_variadic = false;
+
+ Check_Type(arg_types, T_ARRAY);
+ n_arg_types = RARRAY_LENINT(arg_types);
+ Check_Max_Args(name, n_arg_types);
+
+ normalized_arg_types = rb_ary_new_capa(n_arg_types);
+ for (i = 0; i < n_arg_types; i++) {
+ VALUE arg_type = RARRAY_AREF(arg_types, i);
+ int c_arg_type;
+ arg_type = rb_fiddle_type_ensure(arg_type);
+ c_arg_type = NUM2INT(arg_type);
+ if (c_arg_type == TYPE_VARIADIC) {
+ if (i != n_arg_types - 1) {
+ rb_raise(rb_eArgError,
+ "Fiddle::TYPE_VARIADIC must be the last argument type: "
+ "%"PRIsVALUE,
+ arg_types);
+ }
+ *is_variadic = true;
+ break;
+ }
+ else {
+ (void)INT2FFI_TYPE(c_arg_type); /* raise */
+ }
+ rb_ary_push(normalized_arg_types, INT2FIX(c_arg_type));
}
- return ST_CONTINUE;
+
+ /* freeze to prevent inconsistency at calling #to_int later */
+ OBJ_FREEZE(normalized_arg_types);
+ return normalized_arg_types;
}
static VALUE
initialize(int argc, VALUE argv[], VALUE self)
{
ffi_cif * cif;
- ffi_type **arg_types, *rtype;
- ffi_status result;
- VALUE ptr, args, ret_type, abi, kwds, ary;
- int i, len;
- int nabi;
+ VALUE ptr, arg_types, ret_type, abi, kwargs;
+ VALUE name = Qnil;
+ VALUE need_gvl = Qfalse;
+ int c_ret_type;
+ bool is_variadic = false;
+ ffi_abi c_ffi_abi;
void *cfunc;
- rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds);
+ rb_scan_args(argc, argv, "31:", &ptr, &arg_types, &ret_type, &abi, &kwargs);
+ rb_iv_set(self, "@closure", ptr);
+
+ if (!NIL_P(kwargs)) {
+ enum {
+ kw_name,
+ kw_need_gvl,
+ kw_max_,
+ };
+ static ID kw[kw_max_];
+ VALUE args[kw_max_];
+ if (!kw[0]) {
+ kw[kw_name] = rb_intern_const("name");
+ kw[kw_need_gvl] = rb_intern_const("need_gvl");
+ }
+ rb_get_kwargs(kwargs, kw, 0, kw_max_, args);
+ if (args[kw_name] != Qundef) {
+ name = args[kw_name];
+ }
+ if (args[kw_need_gvl] != Qundef) {
+ need_gvl = args[kw_need_gvl];
+ }
+ }
+ rb_iv_set(self, "@name", name);
+ rb_iv_set(self, "@need_gvl", need_gvl);
+
ptr = rb_Integer(ptr);
cfunc = NUM2PTR(ptr);
PTR2NUM(cfunc);
- nabi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
- abi = INT2FIX(nabi);
- i = NUM2INT(ret_type);
- rtype = INT2FFI_TYPE(i);
- ret_type = INT2FIX(i);
-
- Check_Type(args, T_ARRAY);
- len = RARRAY_LENINT(args);
- Check_Max_Args("args", len);
- ary = rb_ary_subseq(args, 0, len);
- for (i = 0; i < RARRAY_LEN(args); i++) {
- VALUE a = RARRAY_PTR(args)[i];
- int type = NUM2INT(a);
- (void)INT2FFI_TYPE(type); /* raise */
- if (INT2FIX(type) != a) rb_ary_store(ary, i, INT2FIX(type));
+ c_ffi_abi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
+ abi = INT2FIX(c_ffi_abi);
+ ret_type = rb_fiddle_type_ensure(ret_type);
+ c_ret_type = NUM2INT(ret_type);
+ (void)INT2FFI_TYPE(c_ret_type); /* raise */
+ ret_type = INT2FIX(c_ret_type);
+
+ arg_types = normalize_argument_types("argument types",
+ arg_types,
+ &is_variadic);
+#ifndef HAVE_FFI_PREP_CIF_VAR
+ if (is_variadic) {
+ rb_raise(rb_eNotImpError,
+ "ffi_prep_cif_var() is required in libffi "
+ "for variadic arguments");
}
- OBJ_FREEZE(ary);
+#endif
rb_iv_set(self, "@ptr", ptr);
- rb_iv_set(self, "@args", args);
+ rb_iv_set(self, "@argument_types", arg_types);
rb_iv_set(self, "@return_type", ret_type);
rb_iv_set(self, "@abi", abi);
-
- if (!NIL_P(kwds)) rb_hash_foreach(kwds, parse_keyword_arg_i, self);
+ rb_iv_set(self, "@is_variadic", is_variadic ? Qtrue : Qfalse);
TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);
-
- arg_types = xcalloc(len + 1, sizeof(ffi_type *));
-
- for (i = 0; i < RARRAY_LEN(args); i++) {
- int type = NUM2INT(RARRAY_AREF(args, i));
- arg_types[i] = INT2FFI_TYPE(type);
- }
- arg_types[len] = NULL;
-
- result = ffi_prep_cif(cif, nabi, len, rtype, arg_types);
-
- if (result)
- rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
+ cif->arg_types = NULL;
return self;
}
@@ -167,61 +211,181 @@ function_call(int argc, VALUE argv[], VALUE self)
{
struct nogvl_ffi_call_args args = { 0 };
fiddle_generic *generic_args;
- VALUE cfunc, types, cPointer;
+ VALUE cfunc;
+ VALUE abi;
+ VALUE arg_types;
+ VALUE cPointer;
+ VALUE is_variadic;
+ VALUE need_gvl;
+ int n_arg_types;
+ int n_fixed_args = 0;
+ int n_call_args = 0;
int i;
+ int i_call;
+ VALUE converted_args = Qnil;
VALUE alloc_buffer = 0;
cfunc = rb_iv_get(self, "@ptr");
- types = rb_iv_get(self, "@args");
+ abi = rb_iv_get(self, "@abi");
+ arg_types = rb_iv_get(self, "@argument_types");
cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
-
- Check_Max_Args("number of arguments", argc);
- if (argc != (i = RARRAY_LENINT(types))) {
- rb_error_arity(argc, i, i);
+ is_variadic = rb_iv_get(self, "@is_variadic");
+ need_gvl = rb_iv_get(self, "@need_gvl");
+
+ n_arg_types = RARRAY_LENINT(arg_types);
+ n_fixed_args = n_arg_types;
+ if (RTEST(is_variadic)) {
+ if (argc < n_arg_types) {
+ rb_error_arity(argc, n_arg_types, UNLIMITED_ARGUMENTS);
+ }
+ if (((argc - n_arg_types) % 2) != 0) {
+ rb_raise(rb_eArgError,
+ "variadic arguments must be type and value pairs: "
+ "%"PRIsVALUE,
+ rb_ary_new_from_values(argc, argv));
+ }
+ n_call_args = n_arg_types + ((argc - n_arg_types) / 2);
}
+ else {
+ if (argc != n_arg_types) {
+ rb_error_arity(argc, n_arg_types, n_arg_types);
+ }
+ n_call_args = n_arg_types;
+ }
+ Check_Max_Args("the number of arguments", n_call_args);
TypedData_Get_Struct(self, ffi_cif, &function_data_type, args.cif);
- if (rb_safe_level() >= 1) {
- for (i = 0; i < argc; i++) {
- VALUE src = argv[i];
- if (OBJ_TAINTED(src)) {
- rb_raise(rb_eSecurityError, "tainted parameter not allowed");
- }
- }
+ if (is_variadic && args.cif->arg_types) {
+ xfree(args.cif->arg_types);
+ args.cif->arg_types = NULL;
+ }
+
+ if (!args.cif->arg_types) {
+ VALUE fixed_arg_types = arg_types;
+ VALUE return_type;
+ int c_return_type;
+ ffi_type *ffi_return_type;
+ ffi_type **ffi_arg_types;
+ ffi_status result;
+
+ arg_types = rb_ary_dup(fixed_arg_types);
+ for (i = n_fixed_args; i < argc; i += 2) {
+ VALUE arg_type = argv[i];
+ int c_arg_type;
+ arg_type = rb_fiddle_type_ensure(arg_type);
+ c_arg_type = NUM2INT(arg_type);
+ (void)INT2FFI_TYPE(c_arg_type); /* raise */
+ rb_ary_push(arg_types, INT2FIX(c_arg_type));
+ }
+
+ return_type = rb_iv_get(self, "@return_type");
+ c_return_type = FIX2INT(return_type);
+ ffi_return_type = INT2FFI_TYPE(c_return_type);
+
+ ffi_arg_types = xcalloc(n_call_args + 1, sizeof(ffi_type *));
+ for (i_call = 0; i_call < n_call_args; i_call++) {
+ VALUE arg_type;
+ int c_arg_type;
+ arg_type = RARRAY_AREF(arg_types, i_call);
+ c_arg_type = FIX2INT(arg_type);
+ ffi_arg_types[i_call] = INT2FFI_TYPE(c_arg_type);
+ }
+ ffi_arg_types[i_call] = NULL;
+
+ if (is_variadic) {
+#ifdef HAVE_FFI_PREP_CIF_VAR
+ result = ffi_prep_cif_var(args.cif,
+ FIX2INT(abi),
+ n_fixed_args,
+ n_call_args,
+ ffi_return_type,
+ ffi_arg_types);
+#else
+ /* This code is never used because ffi_prep_cif_var()
+ * availability check is done in #initialize. */
+ result = FFI_BAD_TYPEDEF;
+#endif
+ }
+ else {
+ result = ffi_prep_cif(args.cif,
+ FIX2INT(abi),
+ n_call_args,
+ ffi_return_type,
+ ffi_arg_types);
+ }
+ if (result != FFI_OK) {
+ xfree(ffi_arg_types);
+ args.cif->arg_types = NULL;
+ rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
+ }
}
generic_args = ALLOCV(alloc_buffer,
- (size_t)(argc + 1) * sizeof(void *) + (size_t)argc * sizeof(fiddle_generic));
+ sizeof(fiddle_generic) * n_call_args +
+ sizeof(void *) * (n_call_args + 1));
args.values = (void **)((char *)generic_args +
- (size_t)argc * sizeof(fiddle_generic));
-
- for (i = 0; i < argc; i++) {
- VALUE type = RARRAY_AREF(types, i);
- VALUE src = argv[i];
- int argtype = FIX2INT(type);
-
- if (argtype == TYPE_VOIDP) {
- if(NIL_P(src)) {
- src = INT2FIX(0);
- } else if(cPointer != CLASS_OF(src)) {
- src = rb_funcall(cPointer, rb_intern("[]"), 1, src);
- }
- src = rb_Integer(src);
- }
-
- VALUE2GENERIC(argtype, src, &generic_args[i]);
- args.values[i] = (void *)&generic_args[i];
+ sizeof(fiddle_generic) * n_call_args);
+
+ for (i = 0, i_call = 0;
+ i < argc && i_call < n_call_args;
+ i++, i_call++) {
+ VALUE arg_type;
+ int c_arg_type;
+ VALUE original_src;
+ VALUE src;
+ arg_type = RARRAY_AREF(arg_types, i_call);
+ c_arg_type = FIX2INT(arg_type);
+ if (i >= n_fixed_args) {
+ i++;
+ }
+ src = argv[i];
+
+ if (c_arg_type == TYPE_VOIDP) {
+ if (NIL_P(src)) {
+ src = INT2FIX(0);
+ }
+ else if (cPointer != CLASS_OF(src)) {
+ src = rb_funcall(cPointer, rb_intern("[]"), 1, src);
+ if (NIL_P(converted_args)) {
+ converted_args = rb_ary_new();
+ }
+ rb_ary_push(converted_args, src);
+ }
+ src = rb_Integer(src);
+ }
+
+ original_src = src;
+ VALUE2GENERIC(c_arg_type, src, &generic_args[i_call]);
+ if (src != original_src) {
+ if (NIL_P(converted_args)) {
+ converted_args = rb_ary_new();
+ }
+ rb_ary_push(converted_args, src);
+ }
+ args.values[i_call] = (void *)&generic_args[i_call];
}
- args.values[argc] = NULL;
- args.fn = NUM2PTR(cfunc);
+ args.values[i_call] = NULL;
+ args.fn = (void(*)(void))NUM2PTR(cfunc);
- (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);
+ if (RTEST(need_gvl)) {
+ ffi_call(args.cif, args.fn, &(args.retval), args.values);
+ }
+ else {
+ (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);
+ }
- rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno));
+ {
+ int errno_keep = errno;
#if defined(_WIN32)
- rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno));
+ int socket_error = WSAGetLastError();
+ rb_funcall(mFiddle, rb_intern("win32_last_error="), 1,
+ INT2NUM(errno_keep));
+ rb_funcall(mFiddle, rb_intern("win32_last_socket_error="), 1,
+ INT2NUM(socket_error));
#endif
+ rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno_keep));
+ }
ALLOCV_END(alloc_buffer);
@@ -294,6 +458,10 @@ Init_fiddle_function(void)
* Caller must ensure the underlying function is called in a
* thread-safe manner if running in a multi-threaded process.
*
+ * Note that it is not thread-safe to use this method to
+ * directly or indirectly call many Ruby C-extension APIs unless
+ * you don't pass +need_gvl: true+ to Fiddle::Function#new.
+ *
* For an example see Fiddle::Function
*
*/
@@ -301,13 +469,20 @@ Init_fiddle_function(void)
/*
* Document-method: new
- * call-seq: new(ptr, args, ret_type, abi = DEFAULT)
+ * call-seq: new(ptr,
+ * args,
+ * ret_type,
+ * abi = DEFAULT,
+ * name: nil,
+ * need_gvl: false)
*
* Constructs a Function object.
* * +ptr+ is a referenced function, of a Fiddle::Handle
* * +args+ is an Array of arguments, passed to the +ptr+ function
* * +ret_type+ is the return type of the function
* * +abi+ is the ABI of the function
+ * * +name+ is the name of the function
+ * * +need_gvl+ is whether GVL is needed to call the function
*
*/
rb_define_method(cFiddleFunction, "initialize", initialize, -1);
diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c
index e727ccfd00..c1b2db557a 100644
--- a/ext/fiddle/handle.c
+++ b/ext/fiddle/handle.c
@@ -1,8 +1,6 @@
#include <ruby.h>
#include <fiddle.h>
-#define SafeStringValueCStr(v) (rb_check_safe_obj(rb_string_value(&v)), StringValueCStr(v))
-
VALUE rb_cHandle;
struct dl_handle {
@@ -76,14 +74,14 @@ rb_fiddle_handle_close(VALUE self)
/* Check dlclose for successful return value */
if(ret) {
#if defined(HAVE_DLERROR)
- rb_raise(rb_eFiddleError, "%s", dlerror());
+ rb_raise(rb_eFiddleDLError, "%s", dlerror());
#else
- rb_raise(rb_eFiddleError, "could not close handle");
+ rb_raise(rb_eFiddleDLError, "could not close handle");
#endif
}
return INT2NUM(ret);
}
- rb_raise(rb_eFiddleError, "dlclose() called too many times");
+ rb_raise(rb_eFiddleDLError, "dlclose() called too many times");
UNREACHABLE;
}
@@ -145,11 +143,11 @@ rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self)
cflag = RTLD_LAZY | RTLD_GLOBAL;
break;
case 1:
- clib = NIL_P(lib) ? NULL : SafeStringValueCStr(lib);
+ clib = NIL_P(lib) ? NULL : StringValueCStr(lib);
cflag = RTLD_LAZY | RTLD_GLOBAL;
break;
case 2:
- clib = NIL_P(lib) ? NULL : SafeStringValueCStr(lib);
+ clib = NIL_P(lib) ? NULL : StringValueCStr(lib);
cflag = NUM2INT(flag);
break;
default:
@@ -179,12 +177,12 @@ rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self)
ptr = dlopen(clib, cflag);
#if defined(HAVE_DLERROR)
if( !ptr && (err = dlerror()) ){
- rb_raise(rb_eFiddleError, "%s", err);
+ rb_raise(rb_eFiddleDLError, "%s", err);
}
#else
if( !ptr ){
err = dlerror();
- rb_raise(rb_eFiddleError, "%s", err);
+ rb_raise(rb_eFiddleDLError, "%s", err);
}
#endif
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
@@ -280,7 +278,7 @@ rb_fiddle_handle_sym(VALUE self, VALUE sym)
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
if( ! fiddle_handle->open ){
- rb_raise(rb_eFiddleError, "closed handle");
+ rb_raise(rb_eFiddleDLError, "closed handle");
}
return fiddle_handle_sym(fiddle_handle->ptr, sym);
@@ -319,7 +317,7 @@ fiddle_handle_sym(void *handle, VALUE symbol)
# define CHECK_DLERROR
#endif
void (*func)();
- const char *name = SafeStringValueCStr(symbol);
+ const char *name = StringValueCStr(symbol);
#ifdef HAVE_DLERROR
dlerror();
@@ -368,7 +366,7 @@ fiddle_handle_sym(void *handle, VALUE symbol)
}
#endif
if( !func ){
- rb_raise(rb_eFiddleError, "unknown symbol \"%"PRIsVALUE"\"", symbol);
+ rb_raise(rb_eFiddleDLError, "unknown symbol \"%"PRIsVALUE"\"", symbol);
}
return PTR2NUM(func);
diff --git a/ext/fiddle/lib/fiddle.rb b/ext/fiddle/lib/fiddle.rb
index e9aa7e50ae..4512989310 100644
--- a/ext/fiddle/lib/fiddle.rb
+++ b/ext/fiddle/lib/fiddle.rb
@@ -1,7 +1,9 @@
# frozen_string_literal: true
+
require 'fiddle.so'
-require 'fiddle/function'
require 'fiddle/closure'
+require 'fiddle/function'
+require 'fiddle/version'
module Fiddle
if WINDOWS
@@ -15,6 +17,18 @@ module Fiddle
def self.win32_last_error= error
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
end
+
+ # Returns the last win32 socket +Error+ of the current executing
+ # +Thread+ or nil if none
+ def self.win32_last_socket_error
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__]
+ end
+
+ # Sets the last win32 socket +Error+ of the current executing
+ # +Thread+ to +error+
+ def self.win32_last_socket_error= error
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error
+ end
end
# Returns the last +Error+ of the current executing +Thread+ or nil if none
diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb
index d3b450b85f..93a05513c9 100644
--- a/ext/fiddle/lib/fiddle/cparser.rb
+++ b/ext/fiddle/lib/fiddle/cparser.rb
@@ -21,6 +21,7 @@ module Fiddle
# Parses a C struct's members
#
# Example:
+ # require 'fiddle/import'
#
# include Fiddle::CParser
# #=> Object
@@ -34,12 +35,37 @@ module Fiddle
def parse_struct_signature(signature, tymap=nil)
if signature.is_a?(String)
signature = split_arguments(signature, /[,;]/)
+ elsif signature.is_a?(Hash)
+ signature = [signature]
end
mems = []
tys = []
signature.each{|msig|
- msig = compact(msig)
+ msig = compact(msig) if msig.is_a?(String)
case msig
+ when Hash
+ msig.each do |struct_name, struct_signature|
+ struct_name = struct_name.to_s if struct_name.is_a?(Symbol)
+ struct_name = compact(struct_name)
+ struct_count = nil
+ if struct_name =~ /^([\w\*\s]+)\[(\d+)\]$/
+ struct_count = $2.to_i
+ struct_name = $1
+ end
+ if struct_signature.respond_to?(:entity_class)
+ struct_type = struct_signature
+ else
+ parsed_struct = parse_struct_signature(struct_signature, tymap)
+ struct_type = CStructBuilder.create(CStruct, *parsed_struct)
+ end
+ if struct_count
+ ty = [struct_type, struct_count]
+ else
+ ty = struct_type
+ end
+ mems.push([struct_name, struct_type.members])
+ tys.push(ty)
+ end
when /^[\w\*\s]+[\*\s](\w+)$/
mems.push($1)
tys.push(parse_ctype(msig, tymap))
@@ -66,6 +92,7 @@ module Fiddle
# be looked up.
#
# Example:
+ # require 'fiddle/import'
#
# include Fiddle::CParser
# #=> Object
@@ -102,6 +129,7 @@ module Fiddle
# value will be the C type to be looked up.
#
# Example:
+ # require 'fiddle/import'
#
# include Fiddle::CParser
# #=> Object
@@ -120,55 +148,97 @@ module Fiddle
#
def parse_ctype(ty, tymap=nil)
tymap ||= {}
- case ty
- when Array
+ if ty.is_a?(Array)
return [parse_ctype(ty[0], tymap), ty[1]]
+ end
+ ty = ty.gsub(/\Aconst\s+/, "")
+ case ty
when 'void'
return TYPE_VOID
- when /^(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?$/
- if( defined?(TYPE_LONG_LONG) )
- return TYPE_LONG_LONG
- else
+ when /\A(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_LONG_LONG)
raise(RuntimeError, "unsupported type: #{ty}")
end
- when /^(?:unsigned\s+long\s+long(?:\s+int\s+)?|uint64_t)(?:\s+\w+)?$/
- if( defined?(TYPE_LONG_LONG) )
- return -TYPE_LONG_LONG
- else
+ return TYPE_LONG_LONG
+ when /\A(?:unsigned\s+long\s+long(?:\s+int\s+)?|uint64_t)(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_LONG_LONG)
raise(RuntimeError, "unsupported type: #{ty}")
end
- when /^(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?$/
+ return -TYPE_LONG_LONG
+ when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/
return TYPE_LONG
- when /^unsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?$/
+ when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/
return -TYPE_LONG
- when /^(?:signed\s+)?int(?:\s+\w+)?$/
+ when /\A(?:signed\s+)?int(?:\s+\w+)?\z/
return TYPE_INT
- when /^(?:unsigned\s+int|uint)(?:\s+\w+)?$/
+ when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/
return -TYPE_INT
- when /^(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?$/
+ when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/
return TYPE_SHORT
- when /^unsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?$/
+ when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/
return -TYPE_SHORT
- when /^(?:signed\s+)?char(?:\s+\w+)?$/
+ when /\A(?:signed\s+)?char(?:\s+\w+)?\z/
return TYPE_CHAR
- when /^unsigned\s+char(?:\s+\w+)?$/
+ when /\Aunsigned\s+char(?:\s+\w+)?\z/
return -TYPE_CHAR
- when /^float(?:\s+\w+)?$/
+ when /\Aint8_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT8_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return TYPE_INT8_T
+ when /\Auint8_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT8_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return -TYPE_INT8_T
+ when /\Aint16_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT16_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return TYPE_INT16_T
+ when /\Auint16_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT16_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return -TYPE_INT16_T
+ when /\Aint32_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT32_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return TYPE_INT32_T
+ when /\Auint32_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT32_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return -TYPE_INT32_T
+ when /\Aint64_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT64_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return TYPE_INT64_T
+ when /\Auint64_t(?:\s+\w+)?\z/
+ unless Fiddle.const_defined?(:TYPE_INT64_T)
+ raise(RuntimeError, "unsupported type: #{ty}")
+ end
+ return -TYPE_INT64_T
+ when /\Afloat(?:\s+\w+)?\z/
return TYPE_FLOAT
- when /^double(?:\s+\w+)?$/
+ when /\Adouble(?:\s+\w+)?\z/
return TYPE_DOUBLE
- when /^size_t(?:\s+\w+)?$/
+ when /\Asize_t(?:\s+\w+)?\z/
return TYPE_SIZE_T
- when /^ssize_t(?:\s+\w+)?$/
+ when /\Assize_t(?:\s+\w+)?\z/
return TYPE_SSIZE_T
- when /^ptrdiff_t(?:\s+\w+)?$/
+ when /\Aptrdiff_t(?:\s+\w+)?\z/
return TYPE_PTRDIFF_T
- when /^intptr_t(?:\s+\w+)?$/
+ when /\Aintptr_t(?:\s+\w+)?\z/
return TYPE_INTPTR_T
- when /^uintptr_t(?:\s+\w+)?$/
+ when /\Auintptr_t(?:\s+\w+)?\z/
return TYPE_UINTPTR_T
when /\*/, /\[[\s\d]*\]/
return TYPE_VOIDP
+ when "..."
+ return TYPE_VARIADIC
else
ty = ty.split(' ', 2)[0]
if( tymap[ty] )
@@ -183,7 +253,7 @@ module Fiddle
def split_arguments(arguments, sep=',')
return [] if arguments.strip == 'void'
- arguments.scan(/([\w\*\s]+\(\*\w*\)\(.*?\)|[\w\*\s\[\]]+)(?:#{sep}\s*|$)/).collect {|m| m[0]}
+ arguments.scan(/([\w\*\s]+\(\*\w*\)\(.*?\)|[\w\*\s\[\]]+|\.\.\.)(?:#{sep}\s*|\z)/).collect {|m| m[0]}
end
def compact(signature)
diff --git a/ext/fiddle/lib/fiddle/function.rb b/ext/fiddle/lib/fiddle/function.rb
index dd5e04e417..0f9913adeb 100644
--- a/ext/fiddle/lib/fiddle/function.rb
+++ b/ext/fiddle/lib/fiddle/function.rb
@@ -10,6 +10,11 @@ module Fiddle
# The name of this function
attr_reader :name
+ # Whether GVL is needed to call this function
+ def need_gvl?
+ @need_gvl
+ end
+
# The integer memory location of this function
def to_i
ptr.to_i
diff --git a/ext/fiddle/lib/fiddle/import.rb b/ext/fiddle/lib/fiddle/import.rb
index 59ab3ee6f7..09ffcef544 100644
--- a/ext/fiddle/lib/fiddle/import.rb
+++ b/ext/fiddle/lib/fiddle/import.rb
@@ -83,11 +83,7 @@ module Fiddle
when Importer
lib.handlers
else
- begin
- Fiddle.dlopen(lib)
- rescue DLError
- raise(DLError, "can't load #{lib}")
- end
+ Fiddle.dlopen(lib)
end
}.flatten()
@handler = CompositeHandler.new(handles)
@@ -115,16 +111,21 @@ module Fiddle
return SIZEOF_INT
when TYPE_LONG
return SIZEOF_LONG
- when TYPE_LONG_LONG
- return SIZEOF_LONG_LONG
when TYPE_FLOAT
return SIZEOF_FLOAT
when TYPE_DOUBLE
return SIZEOF_DOUBLE
when TYPE_VOIDP
return SIZEOF_VOIDP
+ when TYPE_CONST_STRING
+ return SIZEOF_CONST_STRING
else
- raise(DLError, "unknown type: #{ty}")
+ if defined?(TYPE_LONG_LONG) and
+ ty == TYPE_LONG_LONG
+ return SIZEOF_LONG_LONG
+ else
+ raise(DLError, "unknown type: #{ty}")
+ end
end
when Class
if( ty.instance_methods().include?(:to_ptr) )
@@ -154,7 +155,8 @@ module Fiddle
# :stopdoc:
CALL_TYPE_TO_ABI = Hash.new { |h, k|
raise RuntimeError, "unsupported call type: #{k}"
- }.merge({ :stdcall => (Function::STDCALL rescue Function::DEFAULT),
+ }.merge({ :stdcall => Function.const_defined?(:STDCALL) ? Function::STDCALL :
+ Function::DEFAULT,
:cdecl => Function::DEFAULT,
nil => Function::DEFAULT
}).freeze
diff --git a/ext/fiddle/lib/fiddle/pack.rb b/ext/fiddle/lib/fiddle/pack.rb
index 3c9e3c8ad7..22eccedb76 100644
--- a/ext/fiddle/lib/fiddle/pack.rb
+++ b/ext/fiddle/lib/fiddle/pack.rb
@@ -18,7 +18,7 @@ module Fiddle
}
PACK_MAP = {
- TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG) ? "q" : "l!"),
+ TYPE_VOIDP => "l!",
TYPE_CHAR => "c",
TYPE_SHORT => "s!",
TYPE_INT => "i!",
@@ -48,6 +48,7 @@ module Fiddle
ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[-TYPE_LONG_LONG] = ALIGN_LONG_LONG
PACK_MAP[TYPE_LONG_LONG] = PACK_MAP[-TYPE_LONG_LONG] = "q"
SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[-TYPE_LONG_LONG] = SIZEOF_LONG_LONG
+ PACK_MAP[TYPE_VOIDP] = "q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
end
def align(addr, align)
@@ -80,10 +81,13 @@ module Fiddle
case SIZEOF_VOIDP
when SIZEOF_LONG
ary.pack(@template)
- when SIZEOF_LONG_LONG
- ary.pack(@template)
else
- raise(RuntimeError, "sizeof(void*)?")
+ if defined?(TYPE_LONG_LONG) and
+ SIZEOF_VOIDP == SIZEOF_LONG_LONG
+ ary.pack(@template)
+ else
+ raise(RuntimeError, "sizeof(void*)?")
+ end
end
end
@@ -91,10 +95,13 @@ module Fiddle
case SIZEOF_VOIDP
when SIZEOF_LONG
ary.join().unpack(@template)
- when SIZEOF_LONG_LONG
- ary.join().unpack(@template)
else
- raise(RuntimeError, "sizeof(void*)?")
+ if defined?(TYPE_LONG_LONG) and
+ SIZEOF_VOIDP == SIZEOF_LONG_LONG
+ ary.join().unpack(@template)
+ else
+ raise(RuntimeError, "sizeof(void*)?")
+ end
end
end
diff --git a/ext/fiddle/lib/fiddle/struct.rb b/ext/fiddle/lib/fiddle/struct.rb
index 7c0dedb39f..a766eba83b 100644
--- a/ext/fiddle/lib/fiddle/struct.rb
+++ b/ext/fiddle/lib/fiddle/struct.rb
@@ -4,15 +4,72 @@ require 'fiddle/value'
require 'fiddle/pack'
module Fiddle
- # C struct shell
+ # A base class for objects representing a C structure
class CStruct
+ include Enumerable
+
# accessor to Fiddle::CStructEntity
def CStruct.entity_class
CStructEntity
end
+
+ def each
+ return enum_for(__function__) unless block_given?
+
+ self.class.members.each do |name,|
+ yield(self[name])
+ end
+ end
+
+ def each_pair
+ return enum_for(__function__) unless block_given?
+
+ self.class.members.each do |name,|
+ yield(name, self[name])
+ end
+ end
+
+ def to_h
+ hash = {}
+ each_pair do |name, value|
+ hash[name] = unstruct(value)
+ end
+ hash
+ end
+
+ def replace(another)
+ if another.nil?
+ self.class.members.each do |name,|
+ self[name] = nil
+ end
+ elsif another.respond_to?(:each_pair)
+ another.each_pair do |name, value|
+ self[name] = value
+ end
+ else
+ another.each do |name, value|
+ self[name] = value
+ end
+ end
+ self
+ end
+
+ private
+ def unstruct(value)
+ case value
+ when CStruct
+ value.to_h
+ when Array
+ value.collect do |v|
+ unstruct(v)
+ end
+ else
+ value
+ end
+ end
end
- # C union shell
+ # A base class for objects representing a C union
class CUnion
# accessor to Fiddle::CUnionEntity
def CUnion.entity_class
@@ -20,6 +77,41 @@ module Fiddle
end
end
+ # Wrapper for arrays within a struct
+ class StructArray < Array
+ include ValueUtil
+
+ def initialize(ptr, type, initial_values)
+ @ptr = ptr
+ @type = type
+ @is_struct = @type.respond_to?(:entity_class)
+ if @is_struct
+ super(initial_values)
+ else
+ @size = Fiddle::PackInfo::SIZE_MAP[type]
+ @pack_format = Fiddle::PackInfo::PACK_MAP[type]
+ super(initial_values.collect { |v| unsigned_value(v, type) })
+ end
+ end
+
+ def to_ptr
+ @ptr
+ end
+
+ def []=(index, value)
+ if index < 0 || index >= size
+ raise IndexError, 'index %d outside of array bounds 0...%d' % [index, size]
+ end
+
+ if @is_struct
+ self[index].replace(value)
+ else
+ to_ptr[index * @size, @size] = [value].pack(@pack_format)
+ super(index, value)
+ end
+ end
+ end
+
# Used to construct C classes (CUnion, CStruct, etc)
#
# Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an
@@ -35,7 +127,7 @@ module Fiddle
# Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an
# easy-to-use manner.
#
- # Example:
+ # Examples:
#
# require 'fiddle/struct'
# require 'fiddle/cparser'
@@ -46,47 +138,98 @@ module Fiddle
#
# MyStruct = Fiddle::CStructBuilder.create(Fiddle::CUnion, types, members)
#
- # obj = MyStruct.allocate
+ # MyStruct.malloc(Fiddle::RUBY_FREE) do |obj|
+ # ...
+ # end
+ #
+ # obj = MyStruct.malloc(Fiddle::RUBY_FREE)
+ # begin
+ # ...
+ # ensure
+ # obj.call_free
+ # end
+ #
+ # obj = MyStruct.malloc
+ # begin
+ # ...
+ # ensure
+ # Fiddle.free obj.to_ptr
+ # end
#
def create(klass, types, members)
new_class = Class.new(klass){
- define_method(:initialize){|addr|
- @entity = klass.entity_class.new(addr, types)
+ define_method(:initialize){|addr, func = nil|
+ if addr.is_a?(self.class.entity_class)
+ @entity = addr
+ else
+ @entity = self.class.entity_class.new(addr, types, func)
+ end
@entity.assign_names(members)
}
+ define_method(:[]) { |*args| @entity.send(:[], *args) }
+ define_method(:[]=) { |*args| @entity.send(:[]=, *args) }
define_method(:to_ptr){ @entity }
define_method(:to_i){ @entity.to_i }
+ define_singleton_method(:types) { types }
+ define_singleton_method(:members) { members }
members.each{|name|
+ name = name[0] if name.is_a?(Array) # name is a nested struct
+ next if method_defined?(name)
define_method(name){ @entity[name] }
define_method(name + "="){|val| @entity[name] = val }
}
- }
- size = klass.entity_class.size(types)
- new_class.module_eval(<<-EOS, __FILE__, __LINE__+1)
- def new_class.size()
- #{size}
+ entity_class = klass.entity_class
+ alignment = entity_class.alignment(types)
+ size = entity_class.size(types)
+ define_singleton_method(:alignment) { alignment }
+ define_singleton_method(:size) { size }
+ define_singleton_method(:malloc) do |func=nil, &block|
+ if block
+ entity_class.malloc(types, func, size) do |entity|
+ block.call(new(entity))
+ end
+ else
+ new(entity_class.malloc(types, func, size))
+ end
end
- def new_class.malloc()
- addr = Fiddle.malloc(#{size})
- new(addr)
- end
- EOS
+ }
return new_class
end
module_function :create
end
- # A C struct wrapper
+ # A pointer to a C structure
class CStructEntity < Fiddle::Pointer
include PackInfo
include ValueUtil
+ def CStructEntity.alignment(types)
+ max = 1
+ types.each do |type, count = 1|
+ if type.respond_to?(:entity_class)
+ n = type.alignment
+ else
+ n = ALIGN_MAP[type]
+ end
+ max = n if n > max
+ end
+ max
+ end
+
# Allocates a C struct with the +types+ provided.
#
- # When the instance is garbage collected, the C function +func+ is called.
- def CStructEntity.malloc(types, func = nil)
- addr = Fiddle.malloc(CStructEntity.size(types))
- CStructEntity.new(addr, types, func)
+ # See Fiddle::Pointer.malloc for memory management issues.
+ def CStructEntity.malloc(types, func = nil, size = size(types), &block)
+ if block_given?
+ super(size, func) do |struct|
+ struct.set_ctypes types
+ yield struct
+ end
+ else
+ struct = super(size, func)
+ struct.set_ctypes types
+ struct
+ end
end
# Returns the offset for the packed sizes for the given +types+.
@@ -102,9 +245,15 @@ module Fiddle
max_align = types.map { |type, count = 1|
last_offset = offset
- align = PackInfo::ALIGN_MAP[type]
+ if type.respond_to?(:entity_class)
+ align = type.alignment
+ type_size = type.size
+ else
+ align = PackInfo::ALIGN_MAP[type]
+ type_size = PackInfo::SIZE_MAP[type]
+ end
offset = PackInfo.align(last_offset, align) +
- (PackInfo::SIZE_MAP[type] * count)
+ (type_size * count)
align
}.max
@@ -118,13 +267,37 @@ module Fiddle
#
# See also Fiddle::Pointer.new
def initialize(addr, types, func = nil)
+ if func && addr.is_a?(Pointer) && addr.free
+ raise ArgumentError, 'free function specified on both underlying struct Pointer and when creating a CStructEntity - who do you want to free this?'
+ end
set_ctypes(types)
super(addr, @size, func)
end
# Set the names of the +members+ in this C struct
def assign_names(members)
- @members = members
+ @members = []
+ @nested_structs = {}
+ members.each_with_index do |member, index|
+ if member.is_a?(Array) # nested struct
+ member_name = member[0]
+ struct_type, struct_count = @ctypes[index]
+ if struct_count.nil?
+ struct = struct_type.new(to_i + @offset[index])
+ else
+ structs = struct_count.times.map do |i|
+ struct_type.new(to_i + @offset[index] + i * struct_type.size)
+ end
+ struct = StructArray.new(to_i + @offset[index],
+ struct_type,
+ structs)
+ end
+ @nested_structs[member_name] = struct
+ else
+ member_name = member
+ end
+ @members << member_name
+ end
end
# Calculates the offsets and sizes for the given +types+ in the struct.
@@ -135,12 +308,18 @@ module Fiddle
max_align = types.map { |type, count = 1|
orig_offset = offset
- align = ALIGN_MAP[type]
+ if type.respond_to?(:entity_class)
+ align = type.alignment
+ type_size = type.size
+ else
+ align = ALIGN_MAP[type]
+ type_size = SIZE_MAP[type]
+ end
offset = PackInfo.align(orig_offset, align)
@offset << offset
- offset += (SIZE_MAP[type] * count)
+ offset += (type_size * count)
align
}.max
@@ -148,15 +327,34 @@ module Fiddle
@size = PackInfo.align(offset, max_align)
end
- # Fetch struct member +name+
- def [](name)
+ # Fetch struct member +name+ if only one argument is specified. If two
+ # arguments are specified, the first is an offset and the second is a
+ # length and this method returns the string of +length+ bytes beginning at
+ # +offset+.
+ #
+ # Examples:
+ #
+ # my_struct = struct(['int id']).malloc
+ # my_struct.id = 1
+ # my_struct['id'] # => 1
+ # my_struct[0, 4] # => "\x01\x00\x00\x00".b
+ #
+ def [](*args)
+ return super(*args) if args.size > 1
+ name = args[0]
idx = @members.index(name)
if( idx.nil? )
raise(ArgumentError, "no such member: #{name}")
end
ty = @ctypes[idx]
if( ty.is_a?(Array) )
- r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1])
+ if ty.first.respond_to?(:entity_class)
+ return @nested_structs[name]
+ else
+ r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1])
+ end
+ elsif ty.respond_to?(:entity_class)
+ return @nested_structs[name]
else
r = super(@offset[idx], SIZE_MAP[ty.abs])
end
@@ -176,14 +374,44 @@ module Fiddle
if( ty.is_a?(Integer) && (ty < 0) )
return unsigned_value(val, ty)
elsif( ty.is_a?(Array) && (ty[0] < 0) )
- return val.collect{|v| unsigned_value(v,ty[0])}
+ return StructArray.new(self + @offset[idx], ty[0], val)
else
return val
end
end
- # Set struct member +name+, to value +val+
- def []=(name, val)
+ # Set struct member +name+, to value +val+. If more arguments are
+ # specified, writes the string of bytes to the memory at the given
+ # +offset+ and +length+.
+ #
+ # Examples:
+ #
+ # my_struct = struct(['int id']).malloc
+ # my_struct['id'] = 1
+ # my_struct[0, 4] = "\x01\x00\x00\x00".b
+ # my_struct.id # => 1
+ #
+ def []=(*args)
+ return super(*args) if args.size > 2
+ name, val = *args
+ name = name.to_s if name.is_a?(Symbol)
+ nested_struct = @nested_structs[name]
+ if nested_struct
+ if nested_struct.is_a?(StructArray)
+ if val.nil?
+ nested_struct.each do |s|
+ s.replace(nil)
+ end
+ else
+ val.each_with_index do |v, i|
+ nested_struct[i] = v
+ end
+ end
+ else
+ nested_struct.replace(val)
+ end
+ return val
+ end
idx = @members.index(name)
if( idx.nil? )
raise(ArgumentError, "no such member: #{name}")
@@ -202,23 +430,16 @@ module Fiddle
end
end
+ undef_method :size=
def to_s() # :nodoc:
super(@size)
end
end
- # A C union wrapper
+ # A pointer to a C union
class CUnionEntity < CStructEntity
include PackInfo
- # Allocates a C union the +types+ provided.
- #
- # When the instance is garbage collected, the C function +func+ is called.
- def CUnionEntity.malloc(types, func=nil)
- addr = Fiddle.malloc(CUnionEntity.size(types))
- CUnionEntity.new(addr, types, func)
- end
-
# Returns the size needed for the union with the given +types+.
#
# Fiddle::CUnionEntity.size(
@@ -228,7 +449,11 @@ module Fiddle
# Fiddle::TYPE_VOIDP ]) #=> 8
def CUnionEntity.size(types)
types.map { |type, count = 1|
- PackInfo::SIZE_MAP[type] * count
+ if type.respond_to?(:entity_class)
+ type.size * count
+ else
+ PackInfo::SIZE_MAP[type] * count
+ end
}.max
end
@@ -241,4 +466,3 @@ module Fiddle
end
end
end
-
diff --git a/ext/fiddle/lib/fiddle/types.rb b/ext/fiddle/lib/fiddle/types.rb
index 8dc811d3e4..7baf31ec9e 100644
--- a/ext/fiddle/lib/fiddle/types.rb
+++ b/ext/fiddle/lib/fiddle/types.rb
@@ -27,28 +27,29 @@ module Fiddle
# * WORD
module Win32Types
def included(m) # :nodoc:
+ # https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
m.module_eval{
- typealias "DWORD", "unsigned long"
- typealias "PDWORD", "unsigned long *"
- typealias "DWORD32", "unsigned long"
- typealias "DWORD64", "unsigned long long"
- typealias "WORD", "unsigned short"
- typealias "PWORD", "unsigned short *"
+ typealias "ATOM", "WORD"
typealias "BOOL", "int"
- typealias "ATOM", "int"
typealias "BYTE", "unsigned char"
- typealias "PBYTE", "unsigned char *"
+ typealias "DWORD", "unsigned long"
+ typealias "DWORD32", "uint32_t"
+ typealias "DWORD64", "uint64_t"
+ typealias "HANDLE", "PVOID"
+ typealias "HDC", "HANDLE"
+ typealias "HINSTANCE", "HANDLE"
+ typealias "HWND", "HANDLE"
+ typealias "LPCSTR", "const char *"
+ typealias "LPSTR", "char *"
+ typealias "PBYTE", "BYTE *"
+ typealias "PDWORD", "DWORD *"
+ typealias "PHANDLE", "HANDLE *"
+ typealias "PVOID", "void *"
+ typealias "PWORD", "WORD *"
+ typealias "UCHAR", "unsigned char"
typealias "UINT", "unsigned int"
typealias "ULONG", "unsigned long"
- typealias "UCHAR", "unsigned char"
- typealias "HANDLE", "uintptr_t"
- typealias "PHANDLE", "void*"
- typealias "PVOID", "void*"
- typealias "LPCSTR", "char*"
- typealias "LPSTR", "char*"
- typealias "HINSTANCE", "unsigned int"
- typealias "HDC", "unsigned int"
- typealias "HWND", "unsigned int"
+ typealias "WORD", "unsigned short"
}
end
module_function :included
diff --git a/ext/fiddle/lib/fiddle/value.rb b/ext/fiddle/lib/fiddle/value.rb
index a043b9b066..01fec1c206 100644
--- a/ext/fiddle/lib/fiddle/value.rb
+++ b/ext/fiddle/lib/fiddle/value.rb
@@ -13,10 +13,13 @@ module Fiddle
[val].pack("i!").unpack("I!")[0]
when TYPE_LONG
[val].pack("l!").unpack("L!")[0]
- when TYPE_LONG_LONG
- [val].pack("q").unpack("Q")[0]
else
- val
+ if defined?(TYPE_LONG_LONG) and
+ ty.abs == TYPE_LONG_LONG
+ [val].pack("q").unpack("Q")[0]
+ else
+ val
+ end
end
end
@@ -30,10 +33,13 @@ module Fiddle
[val].pack("I!").unpack("i!")[0]
when TYPE_LONG
[val].pack("L!").unpack("l!")[0]
- when TYPE_LONG_LONG
- [val].pack("Q").unpack("q")[0]
else
- val
+ if defined?(TYPE_LONG_LONG) and
+ ty.abs == TYPE_LONG_LONG
+ [val].pack("Q").unpack("q")[0]
+ else
+ val
+ end
end
end
@@ -75,10 +81,13 @@ module Fiddle
case SIZEOF_VOIDP
when SIZEOF_LONG
return [arg].pack("p").unpack("l!")[0]
- when SIZEOF_LONG_LONG
- return [arg].pack("p").unpack("q")[0]
else
- raise(RuntimeError, "sizeof(void*)?")
+ if defined?(SIZEOF_LONG_LONG) and
+ SIZEOF_VOIDP == SIZEOF_LONG_LONG
+ return [arg].pack("p").unpack("q")[0]
+ else
+ raise(RuntimeError, "sizeof(void*)?")
+ end
end
end
when Float, Integer
diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb
new file mode 100644
index 0000000000..a699371ee4
--- /dev/null
+++ b/ext/fiddle/lib/fiddle/version.rb
@@ -0,0 +1,3 @@
+module Fiddle
+ VERSION = "1.0.8"
+end
diff --git a/ext/fiddle/memory_view.c b/ext/fiddle/memory_view.c
new file mode 100644
index 0000000000..172b1f18fc
--- /dev/null
+++ b/ext/fiddle/memory_view.c
@@ -0,0 +1,254 @@
+#include <stdbool.h>
+#include <ruby/ruby.h>
+
+#ifdef HAVE_RUBY_MEMORY_VIEW_H
+# include <ruby/memory_view.h>
+#endif
+
+#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
+# define INTPTR2NUM LL2NUM
+# define UINTPTR2NUM ULL2NUM
+#elif SIZEOF_INTPTR_T == SIZEOF_LONG
+# define INTPTR2NUM LONG2NUM
+# define UINTPTR2NUM ULONG2NUM
+#else
+# define INTPTR2NUM INT2NUM
+# define UINTPTR2NUM UINT2NUM
+#endif
+
+#include <fiddle.h>
+
+#ifdef FIDDLE_MEMORY_VIEW
+VALUE rb_cMemoryView = Qnil;
+
+struct memview_data {
+ rb_memory_view_t view;
+ rb_memory_view_item_component_t *members;
+ size_t n_members;
+};
+
+static void
+fiddle_memview_mark(void *ptr)
+{
+ const struct memview_data *data = ptr;
+ rb_gc_mark(data->view.obj);
+}
+
+static void
+fiddle_memview_free(void *ptr)
+{
+ struct memview_data *data = ptr;
+ rb_memory_view_release(&data->view);
+ if (data->members)
+ xfree(data->members);
+ xfree(ptr);
+}
+
+static size_t
+fiddle_memview_memsize(const void *ptr)
+{
+ const struct memview_data *data = ptr;
+ return sizeof(*data) + sizeof(rb_memory_view_item_component_t)*data->n_members + (size_t)data->view.byte_size;
+}
+
+static const rb_data_type_t fiddle_memview_data_type = {
+ "fiddle/memory_view",
+ {fiddle_memview_mark, fiddle_memview_free, fiddle_memview_memsize,},
+};
+
+static VALUE
+rb_fiddle_memview_s_allocate(VALUE klass)
+{
+ struct memview_data *data;
+ VALUE obj = TypedData_Make_Struct(klass, struct memview_data, &fiddle_memview_data_type, data);
+ data->view.obj = Qnil;
+ data->members = NULL;
+ data->n_members = 0;
+ return obj;
+}
+
+static VALUE
+rb_fiddle_memview_initialize(VALUE obj, VALUE target)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (!rb_memory_view_get(target, &data->view, 0)) {
+ rb_raise(rb_eArgError, "Unable to get a memory view from %+"PRIsVALUE, target);
+ }
+
+ return Qnil;
+}
+
+static VALUE
+rb_fiddle_memview_get_obj(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ return data->view.obj;
+}
+
+static VALUE
+rb_fiddle_memview_get_byte_size(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ return SSIZET2NUM(data->view.byte_size);
+}
+
+static VALUE
+rb_fiddle_memview_get_readonly(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ return data->view.readonly ? Qtrue : Qfalse;
+}
+
+static VALUE
+rb_fiddle_memview_get_format(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ return data->view.format == NULL ? Qnil : rb_str_new_cstr(data->view.format);
+}
+
+static VALUE
+rb_fiddle_memview_get_item_size(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ return SSIZET2NUM(data->view.item_size);
+}
+
+static VALUE
+rb_fiddle_memview_get_ndim(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ return SSIZET2NUM(data->view.ndim);
+}
+
+static VALUE
+rb_fiddle_memview_get_shape(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ if (data->view.shape == NULL) return Qnil;
+
+ const ssize_t ndim = data->view.ndim;
+ VALUE shape = rb_ary_new_capa(ndim);
+ ssize_t i;
+ for (i = 0; i < ndim; ++i) {
+ rb_ary_push(shape, SSIZET2NUM(data->view.shape[i]));
+ }
+ return shape;
+}
+
+static VALUE
+rb_fiddle_memview_get_strides(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ if (data->view.strides == NULL) return Qnil;
+
+ const ssize_t ndim = data->view.ndim;
+ VALUE strides = rb_ary_new_capa(ndim);
+ ssize_t i;
+ for (i = 0; i < ndim; ++i) {
+ rb_ary_push(strides, SSIZET2NUM(data->view.strides[i]));
+ }
+ return strides;
+}
+
+static VALUE
+rb_fiddle_memview_get_sub_offsets(VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+ if (data->view.sub_offsets == NULL) return Qnil;
+
+ const ssize_t ndim = data->view.ndim;
+ VALUE sub_offsets = rb_ary_new_capa(ndim);
+ ssize_t i;
+ for (i = 0; i < ndim; ++i) {
+ rb_ary_push(sub_offsets, SSIZET2NUM(data->view.sub_offsets[i]));
+ }
+ return sub_offsets;
+}
+
+static VALUE
+rb_fiddle_memview_aref(int argc, VALUE *argv, VALUE obj)
+{
+ struct memview_data *data;
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
+
+ if (NIL_P(data->view.obj)) return Qnil;
+
+ const ssize_t ndim = data->view.ndim;
+ if (argc != ndim) {
+ rb_raise(rb_eIndexError, "wrong number of index (%d for %"PRIdSIZE")", argc, ndim);
+ }
+
+ VALUE indices_v = 0;
+ ssize_t *indices = ALLOCV_N(ssize_t, indices_v, ndim);
+
+ ssize_t i;
+ for (i = 0; i < ndim; ++i) {
+ ssize_t x = NUM2SSIZET(argv[i]);
+ indices[i] = x;
+ }
+
+ uint8_t *ptr = rb_memory_view_get_item_pointer(&data->view, indices);
+ ALLOCV_END(indices_v);
+
+ if (data->view.format == NULL) {
+ return INT2FIX(*ptr);
+ }
+
+ if (!data->members) {
+ const char *err;
+ if (rb_memory_view_parse_item_format(data->view.format, &data->members, &data->n_members, &err) < 0) {
+ rb_raise(rb_eRuntimeError, "Unable to recognize item format at %"PRIdSIZE" in \"%s\"",
+ err - data->view.format, data->view.format);
+ }
+ }
+
+ return rb_memory_view_extract_item_members(ptr, data->members, data->n_members);
+}
+
+void
+Init_fiddle_memory_view(void)
+{
+ rb_cMemoryView = rb_define_class_under(mFiddle, "MemoryView", rb_cObject);
+ rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate);
+ rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1);
+ rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0);
+ rb_define_method(rb_cMemoryView, "byte_size", rb_fiddle_memview_get_byte_size, 0);
+ rb_define_method(rb_cMemoryView, "readonly?", rb_fiddle_memview_get_readonly, 0);
+ rb_define_method(rb_cMemoryView, "format", rb_fiddle_memview_get_format, 0);
+ rb_define_method(rb_cMemoryView, "item_size", rb_fiddle_memview_get_item_size, 0);
+ rb_define_method(rb_cMemoryView, "ndim", rb_fiddle_memview_get_ndim, 0);
+ rb_define_method(rb_cMemoryView, "shape", rb_fiddle_memview_get_shape, 0);
+ rb_define_method(rb_cMemoryView, "strides", rb_fiddle_memview_get_strides, 0);
+ rb_define_method(rb_cMemoryView, "sub_offsets", rb_fiddle_memview_get_sub_offsets, 0);
+ rb_define_method(rb_cMemoryView, "[]", rb_fiddle_memview_aref, -1);
+}
+
+#endif /* FIDDLE_MEMORY_VIEW */
diff --git a/ext/fiddle/pinned.c b/ext/fiddle/pinned.c
new file mode 100644
index 0000000000..019a3020e2
--- /dev/null
+++ b/ext/fiddle/pinned.c
@@ -0,0 +1,123 @@
+#include <fiddle.h>
+
+VALUE rb_cPinned;
+VALUE rb_eFiddleClearedReferenceError;
+
+struct pinned_data {
+ VALUE ptr;
+};
+
+static void
+pinned_mark(void *ptr)
+{
+ struct pinned_data *data = (struct pinned_data*)ptr;
+ /* Ensure reference is pinned */
+ if (data->ptr) {
+ rb_gc_mark(data->ptr);
+ }
+}
+
+static size_t
+pinned_memsize(const void *ptr)
+{
+ return sizeof(struct pinned_data);
+}
+
+static const rb_data_type_t pinned_data_type = {
+ "fiddle/pinned",
+ {pinned_mark, xfree, pinned_memsize, },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
+};
+
+static VALUE
+allocate(VALUE klass)
+{
+ struct pinned_data *data;
+ VALUE obj = TypedData_Make_Struct(klass, struct pinned_data, &pinned_data_type, data);
+ data->ptr = 0;
+ return obj;
+}
+
+/*
+ * call-seq:
+ * Fiddle::Pinned.new(object) => pinned_object
+ *
+ * Create a new pinned object reference. The Fiddle::Pinned instance will
+ * prevent the GC from moving +object+.
+ */
+static VALUE
+initialize(VALUE self, VALUE ref)
+{
+ struct pinned_data *data;
+ TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
+ RB_OBJ_WRITE(self, &data->ptr, ref);
+ return self;
+}
+
+/*
+ * call-seq: ref
+ *
+ * Return the object that this pinned instance references.
+ */
+static VALUE
+ref(VALUE self)
+{
+ struct pinned_data *data;
+ TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
+ if (data->ptr) {
+ return data->ptr;
+ } else {
+ rb_raise(rb_eFiddleClearedReferenceError, "`ref` called on a cleared object");
+ }
+}
+
+/*
+ * call-seq: clear
+ *
+ * Clear the reference to the object this is pinning.
+ */
+static VALUE
+clear(VALUE self)
+{
+ struct pinned_data *data;
+ TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
+ data->ptr = 0;
+ return self;
+}
+
+/*
+ * call-seq: cleared?
+ *
+ * Returns true if the reference has been cleared, otherwise returns false.
+ */
+static VALUE
+cleared_p(VALUE self)
+{
+ struct pinned_data *data;
+ TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
+ if (data->ptr) {
+ return Qfalse;
+ } else {
+ return Qtrue;
+ }
+}
+
+extern VALUE rb_eFiddleError;
+
+void
+Init_fiddle_pinned(void)
+{
+ rb_cPinned = rb_define_class_under(mFiddle, "Pinned", rb_cObject);
+ rb_define_alloc_func(rb_cPinned, allocate);
+ rb_define_method(rb_cPinned, "initialize", initialize, 1);
+ rb_define_method(rb_cPinned, "ref", ref, 0);
+ rb_define_method(rb_cPinned, "clear", clear, 0);
+ rb_define_method(rb_cPinned, "cleared?", cleared_p, 0);
+
+ /*
+ * Document-class: Fiddle::ClearedReferenceError
+ *
+ * Cleared reference exception
+ */
+ rb_eFiddleClearedReferenceError = rb_define_class_under(mFiddle, "ClearedReferenceError", rb_eFiddleError);
+}
diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c
index 932bc576c5..c5fb442aec 100644
--- a/ext/fiddle/pointer.c
+++ b/ext/fiddle/pointer.c
@@ -2,8 +2,14 @@
* $Id$
*/
+#include <stdbool.h>
#include <ruby/ruby.h>
#include <ruby/io.h>
+
+#ifdef HAVE_RUBY_MEMORY_VIEW_H
+# include <ruby/memory_view.h>
+#endif
+
#include <ctype.h>
#include <fiddle.h>
@@ -24,6 +30,7 @@ struct ptr_data {
void *ptr;
long size;
freefunc_t free;
+ bool freed;
VALUE wrap[2];
};
@@ -57,14 +64,19 @@ fiddle_ptr_mark(void *ptr)
}
static void
-fiddle_ptr_free(void *ptr)
+fiddle_ptr_free_ptr(void *ptr)
{
struct ptr_data *data = ptr;
- if (data->ptr) {
- if (data->free) {
- (*(data->free))(data->ptr);
- }
+ if (data->ptr && data->free && !data->freed) {
+ data->freed = true;
+ (*(data->free))(data->ptr);
}
+}
+
+static void
+fiddle_ptr_free(void *ptr)
+{
+ fiddle_ptr_free_ptr(ptr);
xfree(ptr);
}
@@ -80,6 +92,38 @@ static const rb_data_type_t fiddle_ptr_data_type = {
{fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,},
};
+#ifdef FIDDLE_MEMORY_VIEW
+static struct ptr_data *
+fiddle_ptr_check_memory_view(VALUE obj)
+{
+ struct ptr_data *data;
+ TypedData_Get_Struct(obj, struct ptr_data, &fiddle_ptr_data_type, data);
+ if (data->ptr == NULL || data->size == 0) return NULL;
+ return data;
+}
+
+static bool
+fiddle_ptr_memory_view_available_p(VALUE obj)
+{
+ return fiddle_ptr_check_memory_view(obj) != NULL;
+}
+
+static bool
+fiddle_ptr_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
+{
+ struct ptr_data *data = fiddle_ptr_check_memory_view(obj);
+ rb_memory_view_init_as_byte_array(view, obj, data->ptr, data->size, true);
+
+ return true;
+}
+
+static const rb_memory_view_entry_t fiddle_ptr_memory_view_entry = {
+ fiddle_ptr_get_memory_view,
+ NULL,
+ fiddle_ptr_memory_view_available_p
+};
+#endif
+
static VALUE
rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
{
@@ -89,8 +133,8 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
val = TypedData_Make_Struct(klass, struct ptr_data, &fiddle_ptr_data_type, data);
data->ptr = ptr;
data->free = func;
+ data->freed = false;
data->size = size;
- OBJ_TAINT(val);
return val;
}
@@ -102,13 +146,13 @@ rb_fiddle_ptr_new(void *ptr, long size, freefunc_t func)
}
static VALUE
-rb_fiddle_ptr_malloc(long size, freefunc_t func)
+rb_fiddle_ptr_malloc(VALUE klass, long size, freefunc_t func)
{
void *ptr;
ptr = ruby_xmalloc((size_t)size);
memset(ptr,0,(size_t)size);
- return rb_fiddle_ptr_new(ptr, size, func);
+ return rb_fiddle_ptr_new2(klass, ptr, size, func);
}
static void *
@@ -141,6 +185,7 @@ rb_fiddle_ptr_s_allocate(VALUE klass)
data->ptr = 0;
data->size = 0;
data->free = 0;
+ data->freed = false;
return obj;
}
@@ -192,16 +237,53 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
return Qnil;
}
+static VALUE
+rb_fiddle_ptr_call_free(VALUE self);
+
/*
* call-seq:
- *
* Fiddle::Pointer.malloc(size, freefunc = nil) => fiddle pointer instance
+ * Fiddle::Pointer.malloc(size, freefunc) { |pointer| ... } => ...
+ *
+ * == Examples
+ *
+ * # Automatically freeing the pointer when the block is exited - recommended
+ * Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) do |pointer|
+ * ...
+ * end
+ *
+ * # Manually freeing but relying on the garbage collector otherwise
+ * pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
+ * ...
+ * pointer.call_free
+ *
+ * # Relying on the garbage collector - may lead to unlimited memory allocated before freeing any, but safe
+ * pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
+ * ...
+ *
+ * # Only manually freeing
+ * pointer = Fiddle::Pointer.malloc(size)
+ * begin
+ * ...
+ * ensure
+ * Fiddle.free pointer
+ * end
+ *
+ * # No free function and no call to free - the native memory will leak if the pointer is garbage collected
+ * pointer = Fiddle::Pointer.malloc(size)
+ * ...
*
* Allocate +size+ bytes of memory and associate it with an optional
- * +freefunc+ that will be called when the pointer is garbage collected.
+ * +freefunc+.
+ *
+ * If a block is supplied, the pointer will be yielded to the block instead of
+ * being returned, and the return value of the block will be returned. A
+ * +freefunc+ must be supplied if a block is.
*
- * +freefunc+ must be an address pointing to a function or an instance of
- * Fiddle::Function
+ * If a +freefunc+ is supplied it will be called once, when the pointer is
+ * garbage collected or when the block is left if a block is supplied or
+ * when the user calls +call_free+, whichever happens first. +freefunc+ must be
+ * an address pointing to a function or an instance of +Fiddle::Function+.
*/
static VALUE
rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
@@ -223,10 +305,17 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
rb_bug("rb_fiddle_ptr_s_malloc");
}
- obj = rb_fiddle_ptr_malloc(s,f);
+ obj = rb_fiddle_ptr_malloc(klass, s,f);
if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
- return obj;
+ if (rb_block_given_p()) {
+ if (!f) {
+ rb_raise(rb_eArgError, "a free function must be supplied to Fiddle::Pointer.malloc when it is called with a block");
+ }
+ return rb_ensure(rb_yield, obj, rb_fiddle_ptr_call_free, obj);
+ } else {
+ return obj;
+ }
}
/*
@@ -352,6 +441,34 @@ rb_fiddle_ptr_free_get(VALUE self)
}
/*
+ * call-seq: call_free => nil
+ *
+ * Call the free function for this pointer. Calling more than once will do
+ * nothing. Does nothing if there is no free function attached.
+ */
+static VALUE
+rb_fiddle_ptr_call_free(VALUE self)
+{
+ struct ptr_data *pdata;
+ TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata);
+ fiddle_ptr_free_ptr(pdata);
+ return Qnil;
+}
+
+/*
+ * call-seq: freed? => bool
+ *
+ * Returns if the free function for this pointer has been called.
+ */
+static VALUE
+rb_fiddle_ptr_freed_p(VALUE self)
+{
+ struct ptr_data *pdata;
+ TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata);
+ return pdata->freed ? Qtrue : Qfalse;
+}
+
+/*
* call-seq:
*
* ptr.to_s => string
@@ -376,11 +493,11 @@ rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self)
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
switch (rb_scan_args(argc, argv, "01", &arg1)) {
case 0:
- val = rb_tainted_str_new2((char*)(data->ptr));
+ val = rb_str_new2((char*)(data->ptr));
break;
case 1:
len = NUM2INT(arg1);
- val = rb_tainted_str_new((char*)(data->ptr), len);
+ val = rb_str_new((char*)(data->ptr), len);
break;
default:
rb_bug("rb_fiddle_ptr_to_s");
@@ -414,11 +531,11 @@ rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self)
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
switch (rb_scan_args(argc, argv, "01", &arg1)) {
case 0:
- val = rb_tainted_str_new((char*)(data->ptr),data->size);
+ val = rb_str_new((char*)(data->ptr),data->size);
break;
case 1:
len = NUM2INT(arg1);
- val = rb_tainted_str_new((char*)(data->ptr), len);
+ val = rb_str_new((char*)(data->ptr), len);
break;
default:
rb_bug("rb_fiddle_ptr_to_str");
@@ -440,7 +557,7 @@ rb_fiddle_ptr_inspect(VALUE self)
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>",
- RB_OBJ_CLASSNAME(self), data, data->ptr, data->size, data->free);
+ RB_OBJ_CLASSNAME(self), (void *)data, data->ptr, data->size, (void *)data->free);
}
/*
@@ -542,7 +659,7 @@ rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
- if (!data->ptr) rb_raise(rb_eFiddleError, "NULL pointer dereference");
+ if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference");
switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){
case 1:
offset = NUM2ULONG(arg0);
@@ -551,7 +668,7 @@ rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
case 2:
offset = NUM2ULONG(arg0);
len = NUM2ULONG(arg1);
- retval = rb_tainted_str_new((char *)data->ptr + offset, len);
+ retval = rb_str_new((char *)data->ptr + offset, len);
break;
default:
rb_bug("rb_fiddle_ptr_aref()");
@@ -580,7 +697,7 @@ rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self)
struct ptr_data *data;
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
- if (!data->ptr) rb_raise(rb_eFiddleError, "NULL pointer dereference");
+ if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference");
switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){
case 2:
offset = NUM2ULONG(arg0);
@@ -661,7 +778,7 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
wrap = 0;
}
else{
- rb_raise(rb_eFiddleError, "to_ptr should return a Fiddle::Pointer object");
+ rb_raise(rb_eFiddleDLError, "to_ptr should return a Fiddle::Pointer object");
}
}
else{
@@ -669,7 +786,6 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
if (num == val) wrap = 0;
ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
}
- OBJ_INFECT(ptr, val);
if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
return ptr;
}
@@ -677,6 +793,7 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
void
Init_fiddle_pointer(void)
{
+#undef rb_intern
id_to_ptr = rb_intern("to_ptr");
/* Document-class: Fiddle::Pointer
@@ -692,6 +809,8 @@ Init_fiddle_pointer(void)
rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1);
rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1);
rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0);
+ rb_define_method(rb_cPointer, "call_free", rb_fiddle_ptr_call_free, 0);
+ rb_define_method(rb_cPointer, "freed?", rb_fiddle_ptr_freed_p, 0);
rb_define_method(rb_cPointer, "to_i", rb_fiddle_ptr_to_i, 0);
rb_define_method(rb_cPointer, "to_int", rb_fiddle_ptr_to_i, 0);
rb_define_method(rb_cPointer, "to_value", rb_fiddle_ptr_to_value, 0);
@@ -713,6 +832,10 @@ Init_fiddle_pointer(void)
rb_define_method(rb_cPointer, "size", rb_fiddle_ptr_size_get, 0);
rb_define_method(rb_cPointer, "size=", rb_fiddle_ptr_size_set, 1);
+#ifdef FIDDLE_MEMORY_VIEW
+ rb_memory_view_register(rb_cPointer, &fiddle_ptr_memory_view_entry);
+#endif
+
/* Document-const: NULL
*
* A NULL pointer
diff --git a/ext/fiddle/win32/fficonfig.h b/ext/fiddle/win32/fficonfig.h
index 776808159c..776808159c 100755..100644
--- a/ext/fiddle/win32/fficonfig.h
+++ b/ext/fiddle/win32/fficonfig.h
diff --git a/ext/fiddle/win32/libffi-config.rb b/ext/fiddle/win32/libffi-config.rb
index 6abc9b2c02..985fc29d36 100755
--- a/ext/fiddle/win32/libffi-config.rb
+++ b/ext/fiddle/win32/libffi-config.rb
@@ -32,7 +32,7 @@ IO.foreach("#{srcdir}/configure.ac") do |line|
end
end
-builddir = srcdir == "." ? enable['builddir'] : "."
+builddir = srcdir == "." ? (enable['builddir'] || ".") : "."
conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32"
FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"])
diff --git a/ext/fiddle/win32/libffi.mk.tmpl b/ext/fiddle/win32/libffi.mk.tmpl
index 2a16e8efec..2a16e8efec 100755..100644
--- a/ext/fiddle/win32/libffi.mk.tmpl
+++ b/ext/fiddle/win32/libffi.mk.tmpl
diff --git a/ext/gdbm/depend b/ext/gdbm/depend
index 98def40879..c3730c0953 100644
--- a/ext/gdbm/depend
+++ b/ext/gdbm/depend
@@ -1,13 +1,163 @@
# AUTOGENERATED DEPENDENCIES START
gdbm.o: $(RUBY_EXTCONF_H)
gdbm.o: $(arch_hdrdir)/ruby/config.h
+gdbm.o: $(hdrdir)/ruby.h
+gdbm.o: $(hdrdir)/ruby/internal/anyargs.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+gdbm.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+gdbm.o: $(hdrdir)/ruby/internal/assume.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/artificial.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/cold.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/const.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/error.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/format.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/noalias.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/noinline.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/pure.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/restrict.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/warning.h
+gdbm.o: $(hdrdir)/ruby/internal/attr/weakref.h
+gdbm.o: $(hdrdir)/ruby/internal/cast.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_is.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+gdbm.o: $(hdrdir)/ruby/internal/compiler_since.h
+gdbm.o: $(hdrdir)/ruby/internal/config.h
+gdbm.o: $(hdrdir)/ruby/internal/constant_p.h
+gdbm.o: $(hdrdir)/ruby/internal/core.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rarray.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rbasic.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rbignum.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rclass.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rdata.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rfile.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rhash.h
+gdbm.o: $(hdrdir)/ruby/internal/core/robject.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rregexp.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rstring.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rstruct.h
+gdbm.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+gdbm.o: $(hdrdir)/ruby/internal/ctype.h
+gdbm.o: $(hdrdir)/ruby/internal/dllexport.h
+gdbm.o: $(hdrdir)/ruby/internal/dosish.h
+gdbm.o: $(hdrdir)/ruby/internal/error.h
+gdbm.o: $(hdrdir)/ruby/internal/eval.h
+gdbm.o: $(hdrdir)/ruby/internal/event.h
+gdbm.o: $(hdrdir)/ruby/internal/fl_type.h
+gdbm.o: $(hdrdir)/ruby/internal/gc.h
+gdbm.o: $(hdrdir)/ruby/internal/glob.h
+gdbm.o: $(hdrdir)/ruby/internal/globals.h
+gdbm.o: $(hdrdir)/ruby/internal/has/attribute.h
+gdbm.o: $(hdrdir)/ruby/internal/has/builtin.h
+gdbm.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+gdbm.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+gdbm.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+gdbm.o: $(hdrdir)/ruby/internal/has/extension.h
+gdbm.o: $(hdrdir)/ruby/internal/has/feature.h
+gdbm.o: $(hdrdir)/ruby/internal/has/warning.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/array.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/bignum.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/class.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/compar.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/complex.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/cont.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/dir.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/enum.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/error.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/eval.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/file.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/gc.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/hash.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/io.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/load.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/marshal.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/numeric.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/object.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/parse.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/proc.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/process.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/random.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/range.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/rational.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/re.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/ruby.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/select.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/signal.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/string.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/struct.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/thread.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/time.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/variable.h
+gdbm.o: $(hdrdir)/ruby/internal/intern/vm.h
+gdbm.o: $(hdrdir)/ruby/internal/interpreter.h
+gdbm.o: $(hdrdir)/ruby/internal/iterator.h
+gdbm.o: $(hdrdir)/ruby/internal/memory.h
+gdbm.o: $(hdrdir)/ruby/internal/method.h
+gdbm.o: $(hdrdir)/ruby/internal/module.h
+gdbm.o: $(hdrdir)/ruby/internal/newobj.h
+gdbm.o: $(hdrdir)/ruby/internal/rgengc.h
+gdbm.o: $(hdrdir)/ruby/internal/scan_args.h
+gdbm.o: $(hdrdir)/ruby/internal/special_consts.h
+gdbm.o: $(hdrdir)/ruby/internal/static_assert.h
+gdbm.o: $(hdrdir)/ruby/internal/stdalign.h
+gdbm.o: $(hdrdir)/ruby/internal/stdbool.h
+gdbm.o: $(hdrdir)/ruby/internal/symbol.h
+gdbm.o: $(hdrdir)/ruby/internal/token_paste.h
+gdbm.o: $(hdrdir)/ruby/internal/value.h
+gdbm.o: $(hdrdir)/ruby/internal/value_type.h
+gdbm.o: $(hdrdir)/ruby/internal/variable.h
+gdbm.o: $(hdrdir)/ruby/internal/warning_push.h
+gdbm.o: $(hdrdir)/ruby/internal/xmalloc.h
+gdbm.o: $(hdrdir)/ruby/assert.h
gdbm.o: $(hdrdir)/ruby/backward.h
+gdbm.o: $(hdrdir)/ruby/backward/2/assume.h
+gdbm.o: $(hdrdir)/ruby/backward/2/attributes.h
+gdbm.o: $(hdrdir)/ruby/backward/2/bool.h
+gdbm.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+gdbm.o: $(hdrdir)/ruby/backward/2/inttypes.h
+gdbm.o: $(hdrdir)/ruby/backward/2/limits.h
+gdbm.o: $(hdrdir)/ruby/backward/2/long_long.h
+gdbm.o: $(hdrdir)/ruby/backward/2/stdalign.h
+gdbm.o: $(hdrdir)/ruby/backward/2/stdarg.h
gdbm.o: $(hdrdir)/ruby/defines.h
gdbm.o: $(hdrdir)/ruby/intern.h
gdbm.o: $(hdrdir)/ruby/missing.h
gdbm.o: $(hdrdir)/ruby/ruby.h
gdbm.o: $(hdrdir)/ruby/st.h
gdbm.o: $(hdrdir)/ruby/subst.h
-gdbm.o: $(top_srcdir)/include/ruby.h
gdbm.o: gdbm.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/gdbm/gdbm.c b/ext/gdbm/gdbm.c
index 5cd9f145d0..4a6377b685 100644
--- a/ext/gdbm/gdbm.c
+++ b/ext/gdbm/gdbm.c
@@ -83,6 +83,10 @@ static VALUE rb_cGDBM, rb_eGDBMError, rb_eGDBMFatalError;
#define MY_BLOCK_SIZE (2048)
#define MY_FATAL_FUNC rb_gdbm_fatal
+
+NORETURN(static void rb_gdbm_fatal(const char *msg));
+NORETURN(static void closed_dbm(void));
+
static void
rb_gdbm_fatal(const char *msg)
{
@@ -102,7 +106,6 @@ closed_dbm(void)
#define GetDBM(obj, dbmp) do {\
TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\
- if ((dbmp) == 0) closed_dbm();\
if ((dbmp)->di_dbm == 0) closed_dbm();\
} while (0)
@@ -115,21 +118,18 @@ static void
free_dbm(void *ptr)
{
struct dbmdata *dbmp = ptr;
- if (dbmp) {
- if (dbmp->di_dbm) gdbm_close(dbmp->di_dbm);
- xfree(dbmp);
- }
+ if (dbmp->di_dbm)
+ gdbm_close(dbmp->di_dbm);
+ xfree(dbmp);
}
static size_t
memsize_dbm(const void *ptr)
{
- size_t size = 0;
const struct dbmdata *dbmp = ptr;
- if (dbmp) {
- size += sizeof(*dbmp);
- if (dbmp->di_dbm) size += DBM_SIZEOF_DBM;
- }
+ size_t size = sizeof(*dbmp);
+ if (dbmp->di_dbm)
+ size += DBM_SIZEOF_DBM;
return size;
}
@@ -170,8 +170,6 @@ fgdbm_closed(VALUE obj)
struct dbmdata *dbmp;
TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
- if (dbmp == 0)
- return Qtrue;
if (dbmp->di_dbm == 0)
return Qtrue;
@@ -181,7 +179,9 @@ fgdbm_closed(VALUE obj)
static VALUE
fgdbm_s_alloc(VALUE klass)
{
- return TypedData_Wrap_Struct(klass, &dbm_type, 0);
+ struct dbmdata *dbmp;
+
+ return TypedData_Make_Struct(klass, struct dbmdata, &dbm_type, dbmp);
}
/*
@@ -215,6 +215,7 @@ fgdbm_initialize(int argc, VALUE *argv, VALUE obj)
struct dbmdata *dbmp;
int mode, flags = 0;
+ TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
mode = 0666; /* default value */
}
@@ -268,9 +269,8 @@ fgdbm_initialize(int argc, VALUE *argv, VALUE obj)
rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
}
- dbmp = ALLOC(struct dbmdata);
- free_dbm(DATA_PTR(obj));
- DATA_PTR(obj) = dbmp;
+ if (dbmp->di_dbm)
+ gdbm_close(dbmp->di_dbm);
dbmp->di_dbm = dbm;
dbmp->di_size = -1;
@@ -324,7 +324,6 @@ rb_gdbm_fetch(GDBM_FILE dbm, datum key)
str = rb_str_new(val.dptr, val.dsize);
free(val.dptr);
- OBJ_TAINT(str);
return str;
}
@@ -365,7 +364,6 @@ rb_gdbm_firstkey(GDBM_FILE dbm)
str = rb_str_new(key.dptr, key.dsize);
free(key.dptr);
- OBJ_TAINT(str);
return str;
}
@@ -386,7 +384,6 @@ rb_gdbm_nextkey(GDBM_FILE dbm, VALUE keystr)
str = rb_str_new(key2.dptr, key2.dsize);
free(key2.dptr);
- OBJ_TAINT(str);
return str;
}
diff --git a/ext/gdbm/gdbm.gemspec b/ext/gdbm/gdbm.gemspec
index 485346c09b..3ecb3121fe 100644
--- a/ext/gdbm/gdbm.gemspec
+++ b/ext/gdbm/gdbm.gemspec
@@ -3,25 +3,19 @@
Gem::Specification.new do |spec|
spec.name = "gdbm"
- spec.version = "2.0.0.beta1"
- spec.date = '2017-04-28'
+ spec.version = "2.1.0"
spec.authors = ["Yukihiro Matsumoto"]
spec.email = ["matz@ruby-lang.org"]
spec.summary = "Ruby extension for GNU dbm."
spec.description = "Ruby extension for GNU dbm."
spec.homepage = "https://github.com/ruby/gdbm"
- spec.license = "BSD-2-Clause"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.files = ["ext/gdbm/extconf.rb", "ext/gdbm/gdbm.c"]
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.extensions = ["ext/gdbm/extconf.rb"]
- spec.required_ruby_version = ">= 2.5.0dev"
-
- spec.add_development_dependency "bundler", "~> 1.14"
- spec.add_development_dependency "rake", "~> 10.0"
- spec.add_development_dependency "rake-compiler"
- spec.add_development_dependency "test-unit"
+ spec.required_ruby_version = ">= 2.3.0"
end
diff --git a/ext/io/console/console.c b/ext/io/console/console.c
index e09213d383..2e2467036d 100644
--- a/ext/io/console/console.c
+++ b/ext/io/console/console.c
@@ -1,9 +1,10 @@
-/* -*- c-file-style: "ruby" -*- */
+/* -*- c-file-style: "ruby"; indent-tabs-mode: t -*- */
/*
* console IO module
*/
#include "ruby.h"
#include "ruby/io.h"
+#include "ruby/thread.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -14,12 +15,6 @@
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
-#ifndef RARRAY_CONST_PTR
-# define RARRAY_CONST_PTR(ary) RARRAY_PTR(ary)
-#endif
-#ifndef HAVE_RB_FUNCALLV
-# define rb_funcallv rb_funcall2
-#endif
#if defined HAVE_TERMIOS_H
# include <termios.h>
@@ -28,7 +23,7 @@ typedef struct termios conmode;
static int
setattr(int fd, conmode *t)
{
- while (tcsetattr(fd, TCSAFLUSH, t)) {
+ while (tcsetattr(fd, TCSANOW, t)) {
if (errno != EINTR) return 0;
}
return 1;
@@ -54,6 +49,7 @@ typedef struct sgttyb conmode;
# endif
#elif defined _WIN32
#include <winioctl.h>
+#include <conio.h>
typedef DWORD conmode;
#define LAST_ERROR rb_w32_map_errno(GetLastError())
@@ -79,11 +75,17 @@ getattr(int fd, conmode *t)
#define SET_LAST_ERROR (0)
#endif
-static ID id_getc, id_console, id_close, id_min, id_time;
+static ID id_getc, id_console, id_close, id_min, id_time, id_intr;
#if ENABLE_IO_GETPASS
-static ID id_gets;
+static ID id_gets, id_chomp_bang;
#endif
+#ifdef HAVE_RB_SCHEDULER_TIMEOUT
+extern VALUE rb_scheduler_timeout(struct timeval *timeout);
+#endif
+
+#define sys_fail_fptr(fptr) rb_sys_fail_str((fptr)->pathv)
+
#ifndef HAVE_RB_F_SEND
static ID id___send__;
@@ -103,27 +105,40 @@ rb_f_send(int argc, VALUE *argv, VALUE recv)
}
#endif
-#ifndef HAVE_RB_SYM2STR
-# define rb_sym2str(sym) rb_id2str(SYM2ID(sym))
-#endif
-
typedef struct {
int vmin;
int vtime;
+ int intr;
} rawmode_arg_t;
static rawmode_arg_t *
-rawmode_opt(int argc, VALUE *argv, rawmode_arg_t *opts)
+rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *opts)
{
+ int argc = *argcp;
rawmode_arg_t *optp = NULL;
- VALUE vopts;
- rb_scan_args(argc, argv, "0:", &vopts);
+ VALUE vopts = Qnil;
+#ifdef RB_SCAN_ARGS_PASS_CALLED_KEYWORDS
+ argc = rb_scan_args(argc, argv, "*:", NULL, &vopts);
+#else
+ if (argc > min_argc) {
+ vopts = rb_check_hash_type(argv[argc-1]);
+ if (!NIL_P(vopts)) {
+ argv[argc-1] = vopts;
+ vopts = rb_extract_keywords(&argv[argc-1]);
+ if (!argv[argc-1]) *argcp = --argc;
+ if (!vopts) vopts = Qnil;
+ }
+ }
+#endif
+ rb_check_arity(argc, min_argc, max_argc);
if (!NIL_P(vopts)) {
VALUE vmin = rb_hash_aref(vopts, ID2SYM(id_min));
VALUE vtime = rb_hash_aref(vopts, ID2SYM(id_time));
+ VALUE intr = rb_hash_aref(vopts, ID2SYM(id_intr));
/* default values by `stty raw` */
opts->vmin = 1;
opts->vtime = 0;
+ opts->intr = 0;
if (!NIL_P(vmin)) {
opts->vmin = NUM2INT(vmin);
optp = opts;
@@ -134,6 +149,21 @@ rawmode_opt(int argc, VALUE *argv, rawmode_arg_t *opts)
opts->vtime = NUM2INT(vtime);
optp = opts;
}
+ switch (intr) {
+ case Qtrue:
+ opts->intr = 1;
+ optp = opts;
+ break;
+ case Qfalse:
+ opts->intr = 0;
+ optp = opts;
+ break;
+ case Qnil:
+ break;
+ default:
+ rb_raise(rb_eArgError, "true or false expected as intr: %"PRIsVALUE,
+ intr);
+ }
}
return optp;
}
@@ -145,24 +175,36 @@ set_rawmode(conmode *t, void *arg)
cfmakeraw(t);
t->c_lflag &= ~(ECHOE|ECHOK);
#elif defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
- t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+ t->c_iflag &= ~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF|IXANY|IMAXBEL);
t->c_oflag &= ~OPOST;
- t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN);
+ t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|XCASE);
t->c_cflag &= ~(CSIZE|PARENB);
t->c_cflag |= CS8;
+ t->c_cc[VMIN] = 1;
+ t->c_cc[VTIME] = 0;
#elif defined HAVE_SGTTY_H
t->sg_flags &= ~ECHO;
t->sg_flags |= RAW;
#elif defined _WIN32
*t = 0;
#endif
-#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
if (arg) {
const rawmode_arg_t *r = arg;
+#ifdef VMIN
if (r->vmin >= 0) t->c_cc[VMIN] = r->vmin;
+#endif
+#ifdef VTIME
if (r->vtime >= 0) t->c_cc[VTIME] = r->vtime;
- }
#endif
+#ifdef ISIG
+ if (r->intr) {
+ t->c_iflag |= BRKINT;
+ t->c_lflag |= ISIG;
+ t->c_oflag |= OPOST;
+ }
+#endif
+ (void)r;
+ }
}
static void
@@ -242,7 +284,7 @@ get_write_fd(const rb_io_t *fptr)
#define FD_PER_IO 2
static VALUE
-ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void *arg)
+ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg)
{
rb_io_t *fptr;
int status = -1;
@@ -273,7 +315,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void
}
}
if (status == 0) {
- result = rb_protect(func, io, &status);
+ result = rb_protect(func, farg, &status);
}
GetOpenFile(io, fptr);
if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) {
@@ -297,32 +339,70 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void
return result;
}
+#if !defined _WIN32
+struct ttymode_callback_args {
+ VALUE (*func)(VALUE, VALUE);
+ VALUE io;
+ VALUE farg;
+};
+
+static VALUE
+ttymode_callback(VALUE args)
+{
+ struct ttymode_callback_args *argp = (struct ttymode_callback_args *)args;
+ return argp->func(argp->io, argp->farg);
+}
+
+static VALUE
+ttymode_with_io(VALUE io, VALUE (*func)(VALUE, VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg)
+{
+ struct ttymode_callback_args cargs;
+ cargs.func = func;
+ cargs.io = io;
+ cargs.farg = farg;
+ return ttymode(io, ttymode_callback, (VALUE)&cargs, setter, arg);
+}
+#endif
+
/*
* call-seq:
- * io.raw(min: nil, time: nil) {|io| }
+ * io.raw(min: nil, time: nil, intr: nil) {|io| }
*
- * Yields +self+ within raw mode.
+ * Yields +self+ within raw mode, and returns the result of the block.
*
* STDIN.raw(&:gets)
*
* will read and return a line without echo back and line editing.
*
+ * The parameter +min+ specifies the minimum number of bytes that
+ * should be received when a read operation is performed. (default: 1)
+ *
+ * The parameter +time+ specifies the timeout in _seconds_ with a
+ * precision of 1/10 of a second. (default: 0)
+ *
+ * If the parameter +intr+ is +true+, enables break, interrupt, quit,
+ * and suspend special characters.
+ *
+ * Refer to the manual page of termios for further details.
+ *
* You must require 'io/console' to use this method.
*/
static VALUE
console_raw(int argc, VALUE *argv, VALUE io)
{
- rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
- return ttymode(io, rb_yield, set_rawmode, optp);
+ rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
+ return ttymode(io, rb_yield, io, set_rawmode, optp);
}
/*
* call-seq:
- * io.raw!(min: nil, time: nil)
+ * io.raw!(min: nil, time: nil, intr: nil) -> io
+ *
+ * Enables raw mode, and returns +io+.
*
- * Enables raw mode.
+ * If the terminal mode needs to be back, use <code>io.raw { ... }</code>.
*
- * If the terminal mode needs to be back, use io.raw { ... }.
+ * See IO#raw for details on the parameters.
*
* You must require 'io/console' to use this method.
*/
@@ -332,13 +412,13 @@ console_set_raw(int argc, VALUE *argv, VALUE io)
conmode t;
rb_io_t *fptr;
int fd;
- rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
+ rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
GetOpenFile(io, fptr);
fd = GetReadFD(fptr);
- if (!getattr(fd, &t)) rb_sys_fail(0);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
set_rawmode(&t, optp);
- if (!setattr(fd, &t)) rb_sys_fail(0);
+ if (!setattr(fd, &t)) sys_fail_fptr(fptr);
return io;
}
@@ -357,7 +437,7 @@ console_set_raw(int argc, VALUE *argv, VALUE io)
static VALUE
console_cooked(VALUE io)
{
- return ttymode(io, rb_yield, set_cookedmode, NULL);
+ return ttymode(io, rb_yield, io, set_cookedmode, NULL);
}
/*
@@ -379,31 +459,126 @@ console_set_cooked(VALUE io)
GetOpenFile(io, fptr);
fd = GetReadFD(fptr);
- if (!getattr(fd, &t)) rb_sys_fail(0);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
set_cookedmode(&t, NULL);
- if (!setattr(fd, &t)) rb_sys_fail(0);
+ if (!setattr(fd, &t)) sys_fail_fptr(fptr);
return io;
}
+#ifndef _WIN32
static VALUE
getc_call(VALUE io)
{
return rb_funcallv(io, id_getc, 0, 0);
}
+#else
+static void *
+nogvl_getch(void *p)
+{
+ int len = 0;
+ wint_t *buf = p, c = _getwch();
+
+ switch (c) {
+ case WEOF:
+ break;
+ case 0x00:
+ case 0xe0:
+ buf[len++] = c;
+ c = _getwch();
+ /* fall through */
+ default:
+ buf[len++] = c;
+ break;
+ }
+ return (void *)(VALUE)len;
+}
+#endif
/*
* call-seq:
- * io.getch(min: nil, time: nil) -> char
+ * io.getch(min: nil, time: nil, intr: nil) -> char
*
* Reads and returns a character in raw mode.
*
+ * See IO#raw for details on the parameters.
+ *
* You must require 'io/console' to use this method.
*/
static VALUE
console_getch(int argc, VALUE *argv, VALUE io)
{
- rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
- return ttymode(io, getc_call, set_rawmode, optp);
+ rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
+#ifndef _WIN32
+ return ttymode(io, getc_call, io, set_rawmode, optp);
+#else
+ rb_io_t *fptr;
+ VALUE str;
+ wint_t c;
+ int len;
+ char buf[8];
+ wint_t wbuf[2];
+# ifndef HAVE_RB_IO_WAIT
+ struct timeval *to = NULL, tv;
+# else
+ VALUE timeout = Qnil;
+# endif
+
+ GetOpenFile(io, fptr);
+ if (optp) {
+ if (optp->vtime) {
+# ifndef HAVE_RB_IO_WAIT
+ to = &tv;
+# else
+ struct timeval tv;
+# endif
+ tv.tv_sec = optp->vtime / 10;
+ tv.tv_usec = (optp->vtime % 10) * 100000;
+# ifdef HAVE_RB_IO_WAIT
+ timeout = rb_scheduler_timeout(&tv);
+# endif
+ }
+ switch (optp->vmin) {
+ case 1: /* default */
+ break;
+ case 0: /* return nil when timed out */
+ if (optp->vtime) break;
+ /* fallthru */
+ default:
+ rb_warning("min option larger than 1 ignored");
+ }
+ if (optp->intr) {
+# ifndef HAVE_RB_IO_WAIT
+ int w = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, to);
+ if (w < 0) rb_eof_error();
+ if (!(w & RB_WAITFD_IN)) return Qnil;
+# else
+ VALUE result = rb_io_wait(io, RUBY_IO_READABLE, timeout);
+ if (result == Qfalse) return Qnil;
+# endif
+ }
+ else if (optp->vtime) {
+ rb_warning("Non-zero vtime option ignored if intr flag is unset");
+ }
+ }
+ len = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getch, wbuf, RUBY_UBF_IO, 0);
+ switch (len) {
+ case 0:
+ return Qnil;
+ case 2:
+ buf[0] = (char)wbuf[0];
+ c = wbuf[1];
+ len = 1;
+ do {
+ buf[len++] = (unsigned char)c;
+ } while ((c >>= CHAR_BIT) && len < (int)sizeof(buf));
+ return rb_str_new(buf, len);
+ default:
+ c = wbuf[0];
+ len = rb_uv_to_utf8(buf, c);
+ str = rb_utf8_str_new(buf, len);
+ return rb_str_conv_enc(str, NULL, rb_default_external_encoding());
+ }
+#endif
}
/*
@@ -421,7 +596,7 @@ console_getch(int argc, VALUE *argv, VALUE io)
static VALUE
console_noecho(VALUE io)
{
- return ttymode(io, rb_yield, set_noecho, NULL);
+ return ttymode(io, rb_yield, io, set_noecho, NULL);
}
/*
@@ -443,12 +618,12 @@ console_set_echo(VALUE io, VALUE f)
GetOpenFile(io, fptr);
fd = GetReadFD(fptr);
- if (!getattr(fd, &t)) rb_sys_fail(0);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
if (RTEST(f))
set_echo(&t, NULL);
else
set_noecho(&t, NULL);
- if (!setattr(fd, &t)) rb_sys_fail(0);
+ if (!setattr(fd, &t)) sys_fail_fptr(fptr);
return io;
}
@@ -469,10 +644,119 @@ console_echo_p(VALUE io)
GetOpenFile(io, fptr);
fd = GetReadFD(fptr);
- if (!getattr(fd, &t)) rb_sys_fail(0);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
return echo_p(&t) ? Qtrue : Qfalse;
}
+static const rb_data_type_t conmode_type = {
+ "console-mode",
+ {0, RUBY_TYPED_DEFAULT_FREE,},
+ 0, 0,
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+};
+static VALUE cConmode;
+
+static VALUE
+conmode_alloc(VALUE klass)
+{
+ return rb_data_typed_object_zalloc(klass, sizeof(conmode), &conmode_type);
+}
+
+static VALUE
+conmode_new(VALUE klass, const conmode *t)
+{
+ VALUE obj = conmode_alloc(klass);
+ *(conmode *)DATA_PTR(obj) = *t;
+ return obj;
+}
+
+static VALUE
+conmode_init_copy(VALUE obj, VALUE obj2)
+{
+ conmode *t = rb_check_typeddata(obj, &conmode_type);
+ conmode *t2 = rb_check_typeddata(obj2, &conmode_type);
+ *t = *t2;
+ return obj;
+}
+
+static VALUE
+conmode_set_echo(VALUE obj, VALUE f)
+{
+ conmode *t = rb_check_typeddata(obj, &conmode_type);
+ if (RTEST(f))
+ set_echo(t, NULL);
+ else
+ set_noecho(t, NULL);
+ return obj;
+}
+
+static VALUE
+conmode_set_raw(int argc, VALUE *argv, VALUE obj)
+{
+ conmode *t = rb_check_typeddata(obj, &conmode_type);
+ rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
+
+ set_rawmode(t, optp);
+ return obj;
+}
+
+static VALUE
+conmode_raw_new(int argc, VALUE *argv, VALUE obj)
+{
+ conmode *r = rb_check_typeddata(obj, &conmode_type);
+ conmode t = *r;
+ rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
+
+ set_rawmode(&t, optp);
+ return conmode_new(rb_obj_class(obj), &t);
+}
+
+/*
+ * call-seq:
+ * io.console_mode -> mode
+ *
+ * Returns a data represents the current console mode.
+ *
+ * You must require 'io/console' to use this method.
+ */
+static VALUE
+console_conmode_get(VALUE io)
+{
+ conmode t;
+ rb_io_t *fptr;
+ int fd;
+
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
+
+ return conmode_new(cConmode, &t);
+}
+
+/*
+ * call-seq:
+ * io.console_mode = mode
+ *
+ * Sets the console mode to +mode+.
+ *
+ * You must require 'io/console' to use this method.
+ */
+static VALUE
+console_conmode_set(VALUE io, VALUE mode)
+{
+ conmode *t, r;
+ rb_io_t *fptr;
+ int fd;
+
+ TypedData_Get_Struct(mode, conmode, &conmode_type, t);
+ r = *t;
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!setattr(fd, &r)) sys_fail_fptr(fptr);
+
+ return mode;
+}
+
#if defined TIOCGWINSZ
typedef struct winsize rb_console_size_t;
#define getwinsize(fd, buf) (ioctl((fd), TIOCGWINSZ, (buf)) == 0)
@@ -510,7 +794,7 @@ console_winsize(VALUE io)
GetOpenFile(io, fptr);
fd = GetWriteFD(fptr);
- if (!getwinsize(fd, &ws)) rb_sys_fail(0);
+ if (!getwinsize(fd, &ws)) sys_fail_fptr(fptr);
return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
}
@@ -557,7 +841,7 @@ console_set_winsize(VALUE io, VALUE size)
SET(xpixel);
SET(ypixel);
#undef SET
- if (!setwinsize(fd, &ws)) rb_sys_fail(0);
+ if (!setwinsize(fd, &ws)) sys_fail_fptr(fptr);
#elif defined _WIN32
wh = (HANDLE)rb_w32_get_osfhandle(fd);
#define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
@@ -591,6 +875,30 @@ console_set_winsize(VALUE io, VALUE size)
}
#endif
+#ifdef _WIN32
+static VALUE
+console_check_winsize_changed(VALUE io)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ DWORD num;
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr));
+ while (GetNumberOfConsoleInputEvents(h, &num) && num > 0) {
+ INPUT_RECORD rec;
+ if (ReadConsoleInput(h, &rec, 1, &num)) {
+ if (rec.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+ rb_yield(Qnil);
+ }
+ }
+ }
+ return io;
+}
+#else
+#define console_check_winsize_changed rb_f_notimplement
+#endif
+
/*
* call-seq:
* io.iflush
@@ -608,7 +916,7 @@ console_iflush(VALUE io)
GetOpenFile(io, fptr);
fd = GetReadFD(fptr);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
- if (tcflush(fd, TCIFLUSH)) rb_sys_fail(0);
+ if (tcflush(fd, TCIFLUSH)) sys_fail_fptr(fptr);
#endif
(void)fd;
return io;
@@ -631,7 +939,7 @@ console_oflush(VALUE io)
GetOpenFile(io, fptr);
fd = GetWriteFD(fptr);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
- if (tcflush(fd, TCOFLUSH)) rb_sys_fail(0);
+ if (tcflush(fd, TCOFLUSH)) sys_fail_fptr(fptr);
#endif
(void)fd;
return io;
@@ -658,11 +966,11 @@ console_ioflush(VALUE io)
fd1 = GetReadFD(fptr);
fd2 = GetWriteFD(fptr);
if (fd2 != -1 && fd1 != fd2) {
- if (tcflush(fd1, TCIFLUSH)) rb_sys_fail(0);
- if (tcflush(fd2, TCOFLUSH)) rb_sys_fail(0);
+ if (tcflush(fd1, TCIFLUSH)) sys_fail_fptr(fptr);
+ if (tcflush(fd2, TCOFLUSH)) sys_fail_fptr(fptr);
}
else {
- if (tcflush(fd1, TCIOFLUSH)) rb_sys_fail(0);
+ if (tcflush(fd1, TCIOFLUSH)) sys_fail_fptr(fptr);
}
#endif
return io;
@@ -681,14 +989,29 @@ console_beep(VALUE io)
MessageBeep(0);
#else
if (write(fd, "\a", 1) < 0)
- rb_sys_fail(0);
+ sys_fail_fptr(fptr);
#endif
return io;
}
+static int
+mode_in_range(VALUE val, int high, const char *modename)
+{
+ int mode;
+ if (NIL_P(val)) return 0;
+ if (!RB_INTEGER_TYPE_P(val)) {
+ wrong_value:
+ rb_raise(rb_eArgError, "wrong %s mode: %"PRIsVALUE, modename, val);
+ }
+ if ((mode = NUM2INT(val)) < 0 || mode > high) {
+ goto wrong_value;
+ }
+ return mode;
+}
+
#if defined _WIN32
static VALUE
-console_goto(VALUE io, VALUE x, VALUE y)
+console_goto(VALUE io, VALUE y, VALUE x)
{
rb_io_t *fptr;
int fd;
@@ -716,15 +1039,159 @@ console_cursor_pos(VALUE io)
if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
- return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.X), UINT2NUM(ws.dwCursorPosition.Y));
+ return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X));
}
static VALUE
-console_cursor_set(VALUE io, VALUE cpos)
+console_move(VALUE io, int y, int x)
{
- cpos = rb_convert_type(cpos, T_ARRAY, "Array", "to_ary");
- if (RARRAY_LEN(cpos) != 2) rb_raise(rb_eArgError, "expected 2D coordinate");
- return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1));
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ pos->X += x;
+ pos->Y += y;
+ if (!SetConsoleCursorPosition(h, *pos)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ return io;
+}
+
+static VALUE
+console_goto_column(VALUE io, VALUE val)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ pos->X = NUM2INT(val);
+ if (!SetConsoleCursorPosition(h, *pos)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ return io;
+}
+
+static void
+constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos)
+{
+ DWORD written;
+
+ FillConsoleOutputAttribute(handle, attr, len, pos, &written);
+ FillConsoleOutputCharacterW(handle, L' ', len, pos, &written);
+}
+
+static VALUE
+console_erase_line(VALUE io, VALUE val)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+ DWORD w;
+ int mode = mode_in_range(val, 2, "line erase");
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ w = winsize_col(&ws);
+ switch (mode) {
+ case 0: /* after cursor */
+ w -= pos->X;
+ break;
+ case 1: /* before *and* cursor */
+ w = pos->X + 1;
+ pos->X = 0;
+ break;
+ case 2: /* entire line */
+ pos->X = 0;
+ break;
+ }
+ constat_clear(h, ws.wAttributes, w, *pos);
+ return io;
+}
+
+static VALUE
+console_erase_screen(VALUE io, VALUE val)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+ DWORD w;
+ int mode = mode_in_range(val, 3, "screen erase");
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ w = winsize_col(&ws);
+ switch (mode) {
+ case 0: /* erase after cursor */
+ w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X);
+ break;
+ case 1: /* erase before *and* cursor */
+ w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1);
+ pos->X = 0;
+ pos->Y = ws.srWindow.Top;
+ break;
+ case 2: /* erase entire screen */
+ w = (w * winsize_row(&ws));
+ pos->X = 0;
+ pos->Y = ws.srWindow.Top;
+ break;
+ case 3: /* erase entire screen */
+ w = (w * ws.dwSize.Y);
+ pos->X = 0;
+ pos->Y = 0;
+ break;
+ }
+ constat_clear(h, ws.wAttributes, w, *pos);
+ return io;
+}
+
+static VALUE
+console_scroll(VALUE io, int line)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ if (line) {
+ SMALL_RECT scroll;
+ COORD destination;
+ CHAR_INFO fill;
+ scroll.Left = 0;
+ scroll.Top = line > 0 ? line : 0;
+ scroll.Right = winsize_col(&ws) - 1;
+ scroll.Bottom = winsize_row(&ws) - 1 + (line < 0 ? line : 0);
+ destination.X = 0;
+ destination.Y = line < 0 ? -line : 0;
+ fill.Char.UnicodeChar = L' ';
+ fill.Attributes = ws.wAttributes;
+
+ ScrollConsoleScreenBuffer(h, &scroll, NULL, destination, &fill);
+ }
+ return io;
}
#include "win32_vk.inc"
@@ -755,12 +1222,210 @@ console_key_pressed_p(VALUE io, VALUE k)
return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse;
}
#else
-# define console_goto rb_f_notimplement
-# define console_cursor_pos rb_f_notimplement
-# define console_cursor_set rb_f_notimplement
+struct query_args {
+ char qstr[6];
+ unsigned char opt;
+};
+
+static int
+direct_query(VALUE io, const struct query_args *query)
+{
+ if (RB_TYPE_P(io, T_FILE)) {
+ rb_io_t *fptr;
+ VALUE wio;
+ GetOpenFile(io, fptr);
+ wio = fptr->tied_io_for_writing;
+ if (wio) {
+ VALUE s = rb_str_new_cstr(query->qstr);
+ rb_io_write(wio, s);
+ rb_io_flush(wio);
+ return 1;
+ }
+ if (write(fptr->fd, query->qstr, strlen(query->qstr)) != -1) {
+ return 1;
+ }
+ if (fptr->fd == 0 &&
+ write(1, query->qstr, strlen(query->qstr)) != -1) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static VALUE
+read_vt_response(VALUE io, VALUE query)
+{
+ struct query_args *qargs = (struct query_args *)query;
+ VALUE result, b;
+ int opt = 0;
+ int num = 0;
+ if (qargs) {
+ opt = qargs->opt;
+ if (!direct_query(io, qargs)) return Qnil;
+ }
+ if (rb_io_getbyte(io) != INT2FIX(0x1b)) return Qnil;
+ if (rb_io_getbyte(io) != INT2FIX('[')) return Qnil;
+ result = rb_ary_new();
+ while (!NIL_P(b = rb_io_getbyte(io))) {
+ int c = NUM2UINT(b);
+ if (c == ';') {
+ rb_ary_push(result, INT2NUM(num));
+ num = 0;
+ }
+ else if (ISDIGIT(c)) {
+ num = num * 10 + c - '0';
+ }
+ else if (opt && c == opt) {
+ opt = 0;
+ }
+ else {
+ char last = (char)c;
+ rb_ary_push(result, INT2NUM(num));
+ b = rb_str_new(&last, 1);
+ break;
+ }
+ }
+ return rb_ary_push(result, b);
+}
+
+static VALUE
+console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qargs)
+{
+ rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 1, &opts);
+ VALUE query = (VALUE)qargs;
+ VALUE ret = ttymode_with_io(io, read_vt_response, query, set_rawmode, optp);
+ return ret;
+}
+
+static VALUE
+console_cursor_pos(VALUE io)
+{
+ static const struct query_args query = {"\033[6n", 0};
+ VALUE resp = console_vt_response(0, 0, io, &query);
+ VALUE row, column, term;
+ unsigned int r, c;
+ if (!RB_TYPE_P(resp, T_ARRAY) || RARRAY_LEN(resp) != 3) return Qnil;
+ term = RARRAY_AREF(resp, 2);
+ if (!RB_TYPE_P(term, T_STRING) || RSTRING_LEN(term) != 1) return Qnil;
+ if (RSTRING_PTR(term)[0] != 'R') return Qnil;
+ row = RARRAY_AREF(resp, 0);
+ column = RARRAY_AREF(resp, 1);
+ rb_ary_resize(resp, 2);
+ r = NUM2UINT(row) - 1;
+ c = NUM2UINT(column) - 1;
+ RARRAY_ASET(resp, 0, INT2NUM(r));
+ RARRAY_ASET(resp, 1, INT2NUM(c));
+ return resp;
+}
+
+static VALUE
+console_goto(VALUE io, VALUE y, VALUE x)
+{
+ rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1));
+ return io;
+}
+
+static VALUE
+console_move(VALUE io, int y, int x)
+{
+ if (x || y) {
+ VALUE s = rb_str_new_cstr("");
+ if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B');
+ if (x) rb_str_catf(s, "\x1b[%d%c", x < 0 ? -x : x, x < 0 ? 'D' : 'C');
+ rb_io_write(io, s);
+ rb_io_flush(io);
+ }
+ return io;
+}
+
+static VALUE
+console_goto_column(VALUE io, VALUE val)
+{
+ rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1));
+ return io;
+}
+
+static VALUE
+console_erase_line(VALUE io, VALUE val)
+{
+ int mode = mode_in_range(val, 2, "line erase");
+ rb_io_write(io, rb_sprintf("\x1b[%dK", mode));
+ return io;
+}
+
+static VALUE
+console_erase_screen(VALUE io, VALUE val)
+{
+ int mode = mode_in_range(val, 3, "screen erase");
+ rb_io_write(io, rb_sprintf("\x1b[%dJ", mode));
+ return io;
+}
+
+static VALUE
+console_scroll(VALUE io, int line)
+{
+ if (line) {
+ VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line,
+ line < 0 ? 'T' : 'S');
+ rb_io_write(io, s);
+ }
+ return io;
+}
# define console_key_pressed_p rb_f_notimplement
#endif
+static VALUE
+console_cursor_set(VALUE io, VALUE cpos)
+{
+ cpos = rb_convert_type(cpos, T_ARRAY, "Array", "to_ary");
+ if (RARRAY_LEN(cpos) != 2) rb_raise(rb_eArgError, "expected 2D coordinate");
+ return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1));
+}
+
+static VALUE
+console_cursor_up(VALUE io, VALUE val)
+{
+ return console_move(io, -NUM2INT(val), 0);
+}
+
+static VALUE
+console_cursor_down(VALUE io, VALUE val)
+{
+ return console_move(io, +NUM2INT(val), 0);
+}
+
+static VALUE
+console_cursor_left(VALUE io, VALUE val)
+{
+ return console_move(io, 0, -NUM2INT(val));
+}
+
+static VALUE
+console_cursor_right(VALUE io, VALUE val)
+{
+ return console_move(io, 0, +NUM2INT(val));
+}
+
+static VALUE
+console_scroll_forward(VALUE io, VALUE val)
+{
+ return console_scroll(io, +NUM2INT(val));
+}
+
+static VALUE
+console_scroll_backward(VALUE io, VALUE val)
+{
+ return console_scroll(io, -NUM2INT(val));
+}
+
+static VALUE
+console_clear_screen(VALUE io)
+{
+ console_erase_screen(io, INT2FIX(2));
+ console_goto(io, INT2FIX(0), INT2FIX(0));
+ return io;
+}
+
/*
* call-seq:
* IO.console -> #<File:/dev/tty>
@@ -860,7 +1525,7 @@ console_dev(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * io.getch(min: nil, time: nil) -> char
+ * io.getch(min: nil, time: nil, intr: nil) -> char
*
* See IO#getch.
*/
@@ -880,7 +1545,7 @@ puts_call(VALUE io)
static VALUE
getpass_call(VALUE io)
{
- return ttymode(io, rb_io_gets, set_noecho, NULL);
+ return ttymode(io, rb_io_gets, io, set_noecho, NULL);
}
static void
@@ -889,7 +1554,6 @@ prompt(int argc, VALUE *argv, VALUE io)
if (argc > 0 && !NIL_P(argv[0])) {
VALUE str = argv[0];
StringValueCStr(str);
- rb_check_safe_obj(str);
rb_io_write(io, str);
}
}
@@ -898,7 +1562,7 @@ static VALUE
str_chomp(VALUE str)
{
if (!NIL_P(str)) {
- str = rb_funcallv(str, rb_intern("chomp!"), 0, 0);
+ rb_funcallv(str, id_chomp_bang, 0, 0);
}
return str;
}
@@ -910,6 +1574,10 @@ str_chomp(VALUE str)
* Reads and returns a line without echo back.
* Prints +prompt+ unless it is +nil+.
*
+ * The newline character that terminates the
+ * read line is removed from the returned string,
+ * see String#chomp!.
+ *
* You must require 'io/console' to use this method.
*/
static VALUE
@@ -954,11 +1622,13 @@ Init_console(void)
id_getc = rb_intern("getc");
#if ENABLE_IO_GETPASS
id_gets = rb_intern("gets");
+ id_chomp_bang = rb_intern("chomp!");
#endif
id_console = rb_intern("console");
id_close = rb_intern("close");
id_min = rb_intern("min");
id_time = rb_intern("time");
+ id_intr = rb_intern("intr");
#ifndef HAVE_RB_F_SEND
id___send__ = rb_intern("__send__");
#endif
@@ -975,6 +1645,8 @@ InitVM_console(void)
rb_define_method(rb_cIO, "getch", console_getch, -1);
rb_define_method(rb_cIO, "echo=", console_set_echo, 1);
rb_define_method(rb_cIO, "echo?", console_echo_p, 0);
+ rb_define_method(rb_cIO, "console_mode", console_conmode_get, 0);
+ rb_define_method(rb_cIO, "console_mode=", console_conmode_set, 1);
rb_define_method(rb_cIO, "noecho", console_noecho, 0);
rb_define_method(rb_cIO, "winsize", console_winsize, 0);
rb_define_method(rb_cIO, "winsize=", console_set_winsize, 1);
@@ -985,7 +1657,18 @@ InitVM_console(void)
rb_define_method(rb_cIO, "goto", console_goto, 2);
rb_define_method(rb_cIO, "cursor", console_cursor_pos, 0);
rb_define_method(rb_cIO, "cursor=", console_cursor_set, 1);
+ rb_define_method(rb_cIO, "cursor_up", console_cursor_up, 1);
+ rb_define_method(rb_cIO, "cursor_down", console_cursor_down, 1);
+ rb_define_method(rb_cIO, "cursor_left", console_cursor_left, 1);
+ rb_define_method(rb_cIO, "cursor_right", console_cursor_right, 1);
+ rb_define_method(rb_cIO, "goto_column", console_goto_column, 1);
+ rb_define_method(rb_cIO, "erase_line", console_erase_line, 1);
+ rb_define_method(rb_cIO, "erase_screen", console_erase_screen, 1);
+ rb_define_method(rb_cIO, "scroll_forward", console_scroll_forward, 1);
+ rb_define_method(rb_cIO, "scroll_backward", console_scroll_backward, 1);
+ rb_define_method(rb_cIO, "clear_screen", console_clear_screen, 0);
rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1);
+ rb_define_method(rb_cIO, "check_winsize_changed", console_check_winsize_changed, 0);
#if ENABLE_IO_GETPASS
rb_define_method(rb_cIO, "getpass", console_getpass, -1);
#endif
@@ -997,4 +1680,15 @@ InitVM_console(void)
rb_define_method(mReadable, "getpass", io_getpass, -1);
#endif
}
+ {
+ /* :stopdoc: */
+ cConmode = rb_define_class_under(rb_cIO, "ConsoleMode", rb_cObject);
+ rb_define_alloc_func(cConmode, conmode_alloc);
+ rb_undef_method(cConmode, "initialize");
+ rb_define_method(cConmode, "initialize_copy", conmode_init_copy, 1);
+ rb_define_method(cConmode, "echo=", conmode_set_echo, 1);
+ rb_define_method(cConmode, "raw!", conmode_set_raw, -1);
+ rb_define_method(cConmode, "raw", conmode_raw_new, -1);
+ /* :startdoc: */
+ }
}
diff --git a/ext/io/console/depend b/ext/io/console/depend
index d69a0b3aef..43c280d8ff 100644
--- a/ext/io/console/depend
+++ b/ext/io/console/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
console.o: $(RUBY_EXTCONF_H)
console.o: $(arch_hdrdir)/ruby/config.h
+console.o: $(hdrdir)/ruby.h
+console.o: $(hdrdir)/ruby/internal/anyargs.h
+console.o: $(hdrdir)/ruby/internal/arithmetic.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+console.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+console.o: $(hdrdir)/ruby/internal/assume.h
+console.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+console.o: $(hdrdir)/ruby/internal/attr/artificial.h
+console.o: $(hdrdir)/ruby/internal/attr/cold.h
+console.o: $(hdrdir)/ruby/internal/attr/const.h
+console.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+console.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+console.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+console.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+console.o: $(hdrdir)/ruby/internal/attr/error.h
+console.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+console.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+console.o: $(hdrdir)/ruby/internal/attr/format.h
+console.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+console.o: $(hdrdir)/ruby/internal/attr/noalias.h
+console.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+console.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+console.o: $(hdrdir)/ruby/internal/attr/noinline.h
+console.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+console.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+console.o: $(hdrdir)/ruby/internal/attr/pure.h
+console.o: $(hdrdir)/ruby/internal/attr/restrict.h
+console.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+console.o: $(hdrdir)/ruby/internal/attr/warning.h
+console.o: $(hdrdir)/ruby/internal/attr/weakref.h
+console.o: $(hdrdir)/ruby/internal/cast.h
+console.o: $(hdrdir)/ruby/internal/compiler_is.h
+console.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+console.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+console.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+console.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+console.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+console.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+console.o: $(hdrdir)/ruby/internal/compiler_since.h
+console.o: $(hdrdir)/ruby/internal/config.h
+console.o: $(hdrdir)/ruby/internal/constant_p.h
+console.o: $(hdrdir)/ruby/internal/core.h
+console.o: $(hdrdir)/ruby/internal/core/rarray.h
+console.o: $(hdrdir)/ruby/internal/core/rbasic.h
+console.o: $(hdrdir)/ruby/internal/core/rbignum.h
+console.o: $(hdrdir)/ruby/internal/core/rclass.h
+console.o: $(hdrdir)/ruby/internal/core/rdata.h
+console.o: $(hdrdir)/ruby/internal/core/rfile.h
+console.o: $(hdrdir)/ruby/internal/core/rhash.h
+console.o: $(hdrdir)/ruby/internal/core/robject.h
+console.o: $(hdrdir)/ruby/internal/core/rregexp.h
+console.o: $(hdrdir)/ruby/internal/core/rstring.h
+console.o: $(hdrdir)/ruby/internal/core/rstruct.h
+console.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+console.o: $(hdrdir)/ruby/internal/ctype.h
+console.o: $(hdrdir)/ruby/internal/dllexport.h
+console.o: $(hdrdir)/ruby/internal/dosish.h
+console.o: $(hdrdir)/ruby/internal/error.h
+console.o: $(hdrdir)/ruby/internal/eval.h
+console.o: $(hdrdir)/ruby/internal/event.h
+console.o: $(hdrdir)/ruby/internal/fl_type.h
+console.o: $(hdrdir)/ruby/internal/gc.h
+console.o: $(hdrdir)/ruby/internal/glob.h
+console.o: $(hdrdir)/ruby/internal/globals.h
+console.o: $(hdrdir)/ruby/internal/has/attribute.h
+console.o: $(hdrdir)/ruby/internal/has/builtin.h
+console.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+console.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+console.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+console.o: $(hdrdir)/ruby/internal/has/extension.h
+console.o: $(hdrdir)/ruby/internal/has/feature.h
+console.o: $(hdrdir)/ruby/internal/has/warning.h
+console.o: $(hdrdir)/ruby/internal/intern/array.h
+console.o: $(hdrdir)/ruby/internal/intern/bignum.h
+console.o: $(hdrdir)/ruby/internal/intern/class.h
+console.o: $(hdrdir)/ruby/internal/intern/compar.h
+console.o: $(hdrdir)/ruby/internal/intern/complex.h
+console.o: $(hdrdir)/ruby/internal/intern/cont.h
+console.o: $(hdrdir)/ruby/internal/intern/dir.h
+console.o: $(hdrdir)/ruby/internal/intern/enum.h
+console.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+console.o: $(hdrdir)/ruby/internal/intern/error.h
+console.o: $(hdrdir)/ruby/internal/intern/eval.h
+console.o: $(hdrdir)/ruby/internal/intern/file.h
+console.o: $(hdrdir)/ruby/internal/intern/gc.h
+console.o: $(hdrdir)/ruby/internal/intern/hash.h
+console.o: $(hdrdir)/ruby/internal/intern/io.h
+console.o: $(hdrdir)/ruby/internal/intern/load.h
+console.o: $(hdrdir)/ruby/internal/intern/marshal.h
+console.o: $(hdrdir)/ruby/internal/intern/numeric.h
+console.o: $(hdrdir)/ruby/internal/intern/object.h
+console.o: $(hdrdir)/ruby/internal/intern/parse.h
+console.o: $(hdrdir)/ruby/internal/intern/proc.h
+console.o: $(hdrdir)/ruby/internal/intern/process.h
+console.o: $(hdrdir)/ruby/internal/intern/random.h
+console.o: $(hdrdir)/ruby/internal/intern/range.h
+console.o: $(hdrdir)/ruby/internal/intern/rational.h
+console.o: $(hdrdir)/ruby/internal/intern/re.h
+console.o: $(hdrdir)/ruby/internal/intern/ruby.h
+console.o: $(hdrdir)/ruby/internal/intern/select.h
+console.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+console.o: $(hdrdir)/ruby/internal/intern/signal.h
+console.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+console.o: $(hdrdir)/ruby/internal/intern/string.h
+console.o: $(hdrdir)/ruby/internal/intern/struct.h
+console.o: $(hdrdir)/ruby/internal/intern/thread.h
+console.o: $(hdrdir)/ruby/internal/intern/time.h
+console.o: $(hdrdir)/ruby/internal/intern/variable.h
+console.o: $(hdrdir)/ruby/internal/intern/vm.h
+console.o: $(hdrdir)/ruby/internal/interpreter.h
+console.o: $(hdrdir)/ruby/internal/iterator.h
+console.o: $(hdrdir)/ruby/internal/memory.h
+console.o: $(hdrdir)/ruby/internal/method.h
+console.o: $(hdrdir)/ruby/internal/module.h
+console.o: $(hdrdir)/ruby/internal/newobj.h
+console.o: $(hdrdir)/ruby/internal/rgengc.h
+console.o: $(hdrdir)/ruby/internal/scan_args.h
+console.o: $(hdrdir)/ruby/internal/special_consts.h
+console.o: $(hdrdir)/ruby/internal/static_assert.h
+console.o: $(hdrdir)/ruby/internal/stdalign.h
+console.o: $(hdrdir)/ruby/internal/stdbool.h
+console.o: $(hdrdir)/ruby/internal/symbol.h
+console.o: $(hdrdir)/ruby/internal/token_paste.h
+console.o: $(hdrdir)/ruby/internal/value.h
+console.o: $(hdrdir)/ruby/internal/value_type.h
+console.o: $(hdrdir)/ruby/internal/variable.h
+console.o: $(hdrdir)/ruby/internal/warning_push.h
+console.o: $(hdrdir)/ruby/internal/xmalloc.h
+console.o: $(hdrdir)/ruby/assert.h
console.o: $(hdrdir)/ruby/backward.h
+console.o: $(hdrdir)/ruby/backward/2/assume.h
+console.o: $(hdrdir)/ruby/backward/2/attributes.h
+console.o: $(hdrdir)/ruby/backward/2/bool.h
+console.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+console.o: $(hdrdir)/ruby/backward/2/inttypes.h
+console.o: $(hdrdir)/ruby/backward/2/limits.h
+console.o: $(hdrdir)/ruby/backward/2/long_long.h
+console.o: $(hdrdir)/ruby/backward/2/stdalign.h
+console.o: $(hdrdir)/ruby/backward/2/stdarg.h
console.o: $(hdrdir)/ruby/defines.h
console.o: $(hdrdir)/ruby/encoding.h
console.o: $(hdrdir)/ruby/intern.h
@@ -12,7 +163,7 @@ console.o: $(hdrdir)/ruby/oniguruma.h
console.o: $(hdrdir)/ruby/ruby.h
console.o: $(hdrdir)/ruby/st.h
console.o: $(hdrdir)/ruby/subst.h
-console.o: $(top_srcdir)/include/ruby.h
+console.o: $(hdrdir)/ruby/thread.h
console.o: console.c
# AUTOGENERATED DEPENDENCIES END
@@ -26,7 +177,7 @@ win32_vk.inc: win32_vk.list
-e 'puts(%[#ifndef #{n}\n# define #{n} UNDEFINED_VK\n#endif])' \
$< && \
gperf --ignore-case -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k* $< \
- | sed 's/(int)(long)&((\(struct stringpool_t\) *\*)0)->\(stringpool_[a-z0-9]*\)/offsetof(\1, \2)/g' \
+ | sed -f $(top_srcdir)/tool/gperf.sed \
) > $(@F)
.SUFFIXES: .chksum .list .inc
diff --git a/ext/io/console/extconf.rb b/ext/io/console/extconf.rb
index be536dff9f..3efdd6e092 100644
--- a/ext/io/console/extconf.rb
+++ b/ext/io/console/extconf.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require 'mkmf'
-ok = true
+ok = true if RUBY_ENGINE == "ruby"
hdr = nil
case
when macro_defined?("_WIN32", "")
@@ -14,16 +14,23 @@ when have_header(hdr = "sgtty.h")
%w"stty gtty".each {|f| have_func(f, hdr)}
else
ok = false
-end
-if ok
+end if ok
+case ok
+when true
have_header("sys/ioctl.h") if hdr
- have_func("rb_funcallv")
- have_func("rb_sym2str")
# rb_check_hash_type: 1.9.3
# rb_io_get_write_io: 1.9.1
# rb_cloexec_open: 2.0.0
+ # rb_funcallv: 2.1.0
+ # RARRAY_CONST_PTR: 2.1.0
+ # rb_sym2str: 2.2.0
+ if have_func("rb_scheduler_timeout")
+ have_func("rb_io_wait")
+ end
$defs << "-D""ENABLE_IO_GETPASS=1"
create_makefile("io/console") {|conf|
conf << "\n""VK_HEADER = #{vk_header}\n"
}
+when nil
+ File.write("Makefile", dummy_makefile($srcdir).join(""))
end
diff --git a/ext/io/console/io-console.gemspec b/ext/io/console/io-console.gemspec
index 1256162468..8a0df83b2c 100644
--- a/ext/io/console/io-console.gemspec
+++ b/ext/io/console/io-console.gemspec
@@ -1,24 +1,25 @@
# -*- ruby -*-
-_VERSION = "0.4.6"
-date = %w$Date:: $[1]
+_VERSION = "0.5.7"
Gem::Specification.new do |s|
s.name = "io-console"
s.version = _VERSION
- s.date = date
s.summary = "Console interface"
s.email = "nobu@ruby-lang.org"
s.description = "add console capabilities to IO instances."
- s.required_ruby_version = ">= 2.0.0"
+ s.required_ruby_version = ">= 2.4.0"
s.homepage = "https://github.com/ruby/io-console"
+ s.metadata["source_code_url"] = s.homepage
s.authors = ["Nobu Nakada"]
s.require_path = %[lib]
- s.files = %w[ext/io/console/console.c ext/io/console/extconf.rb lib/console/size.rb ext/io/console/win32_vk.inc]
+ s.files = %w[
+ LICENSE.txt
+ README.md
+ ext/io/console/console.c
+ ext/io/console/extconf.rb
+ ext/io/console/win32_vk.inc
+ lib/io/console/size.rb
+ ]
s.extensions = %w[ext/io/console/extconf.rb]
- s.license = "BSD-2-Clause"
- s.cert_chain = %w[certs/nobu.pem]
- s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
-
- s.add_development_dependency 'rake-compiler'
- s.add_development_dependency 'rake-compiler-dock', ">= 0.6.1"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
end
diff --git a/ext/io/console/win32_vk.inc b/ext/io/console/win32_vk.inc
index a098158e27..cbec7bef15 100644
--- a/ext/io/console/win32_vk.inc
+++ b/ext/io/console/win32_vk.inc
@@ -479,7 +479,7 @@
#ifndef VK_OEM_CLEAR
# define VK_OEM_CLEAR UNDEFINED_VK
#endif
-/* C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
/* Command-line: gperf --ignore-case -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k'*' win32_vk.list */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -506,13 +506,14 @@
&& ('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
+#define gperf_offsetof(s, n) (short)offsetof(struct s##_t, s##_str##n)
#line 1 "win32_vk.list"
struct vktable {short ofs; unsigned short vk;};
-static const struct vktable *console_win32_vk(const char *, unsigned int);
+static const struct vktable *console_win32_vk(/*const char *, unsigned int*/);
#line 5 "win32_vk.list"
struct vktable;
/* maximum key range = 245, duplicates = 0 */
@@ -545,9 +546,7 @@ static unsigned char gperf_downcase[256] =
#ifndef GPERF_CASE_STRCMP
#define GPERF_CASE_STRCMP 1
static int
-gperf_case_strcmp (s1, s2)
- register const char *s1;
- register const char *s2;
+gperf_case_strcmp (register const char *s1, register const char *s2)
{
for (;;)
{
@@ -560,15 +559,15 @@ gperf_case_strcmp (s1, s2)
}
#endif
-#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || defined(__GNUC_STDC_INLINE__)
-inline
-#elif defined(__GNUC__)
+#ifdef __GNUC__
__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
#endif
static unsigned int
-hash (str, len)
- register const char *str;
- register unsigned int len;
+hash (register const char *str, register size_t len)
{
static const unsigned short asso_values[] =
{
@@ -599,7 +598,7 @@ hash (str, len)
257, 257, 257, 257, 257, 257, 257, 257, 257, 257,
257, 257, 257, 257, 257, 257, 257, 257
};
- register int hval = len;
+ register unsigned int hval = (unsigned int)len;
switch (hval)
{
@@ -661,7 +660,7 @@ hash (str, len)
hval += asso_values[(unsigned char)str[0]];
break;
}
- return hval;
+ return (unsigned int)hval;
}
struct stringpool_t
@@ -991,16 +990,8 @@ static const struct stringpool_t stringpool_contents =
"DIVIDE"
};
#define stringpool ((const char *) &stringpool_contents)
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct vktable *
-console_win32_vk (str, len)
- register const char *str;
- register unsigned int len;
+console_win32_vk (register const char *str, register size_t len)
{
enum
{
@@ -1016,375 +1007,375 @@ console_win32_vk (str, len)
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1},
#line 40 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str12), VK_UP},
+ {gperf_offsetof(stringpool, 12), VK_UP},
#line 52 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str13), VK_APPS},
+ {gperf_offsetof(stringpool, 13), VK_APPS},
#line 159 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str14), VK_CRSEL},
+ {gperf_offsetof(stringpool, 14), VK_CRSEL},
#line 34 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str15), VK_SPACE},
+ {gperf_offsetof(stringpool, 15), VK_SPACE},
#line 95 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str16), VK_SCROLL},
+ {gperf_offsetof(stringpool, 16), VK_SCROLL},
#line 29 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str17), VK_ESCAPE},
+ {gperf_offsetof(stringpool, 17), VK_ESCAPE},
#line 9 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str18), VK_CANCEL},
+ {gperf_offsetof(stringpool, 18), VK_CANCEL},
#line 32 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str19), VK_ACCEPT},
+ {gperf_offsetof(stringpool, 19), VK_ACCEPT},
#line 66 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str20), VK_SEPARATOR},
+ {gperf_offsetof(stringpool, 20), VK_SEPARATOR},
#line 43 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str21), VK_SELECT},
+ {gperf_offsetof(stringpool, 21), VK_SELECT},
#line 18 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str22), VK_CONTROL},
+ {gperf_offsetof(stringpool, 22), VK_CONTROL},
#line 166 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str23), VK_OEM_CLEAR},
+ {gperf_offsetof(stringpool, 23), VK_OEM_CLEAR},
#line 145 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str24), VK_OEM_RESET},
+ {gperf_offsetof(stringpool, 24), VK_OEM_RESET},
#line 155 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str25), VK_OEM_AUTO},
+ {gperf_offsetof(stringpool, 25), VK_OEM_AUTO},
#line 151 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str26), VK_OEM_CUSEL},
+ {gperf_offsetof(stringpool, 26), VK_OEM_CUSEL},
{-1},
#line 22 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str28), VK_KANA},
+ {gperf_offsetof(stringpool, 28), VK_KANA},
#line 127 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str29), VK_OEM_PLUS},
+ {gperf_offsetof(stringpool, 29), VK_OEM_PLUS},
#line 35 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str30), VK_PRIOR},
+ {gperf_offsetof(stringpool, 30), VK_PRIOR},
#line 152 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str31), VK_OEM_ATTN},
+ {gperf_offsetof(stringpool, 31), VK_OEM_ATTN},
#line 20 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str32), VK_PAUSE},
+ {gperf_offsetof(stringpool, 32), VK_PAUSE},
#line 13 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str33), VK_BACK},
+ {gperf_offsetof(stringpool, 33), VK_BACK},
#line 144 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str34), VK_PACKET},
+ {gperf_offsetof(stringpool, 34), VK_PACKET},
#line 105 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str35), VK_RCONTROL},
+ {gperf_offsetof(stringpool, 35), VK_RCONTROL},
#line 104 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str36), VK_LCONTROL},
+ {gperf_offsetof(stringpool, 36), VK_LCONTROL},
#line 37 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str37), VK_END},
+ {gperf_offsetof(stringpool, 37), VK_END},
#line 38 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str38), VK_HOME},
+ {gperf_offsetof(stringpool, 38), VK_HOME},
#line 44 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str39), VK_PRINT},
+ {gperf_offsetof(stringpool, 39), VK_PRINT},
#line 94 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str40), VK_NUMLOCK},
+ {gperf_offsetof(stringpool, 40), VK_NUMLOCK},
#line 39 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str41), VK_LEFT},
+ {gperf_offsetof(stringpool, 41), VK_LEFT},
#line 25 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str42), VK_JUNJA},
+ {gperf_offsetof(stringpool, 42), VK_JUNJA},
#line 19 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str43), VK_MENU},
+ {gperf_offsetof(stringpool, 43), VK_MENU},
#line 150 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str44), VK_OEM_WSCTRL},
+ {gperf_offsetof(stringpool, 44), VK_OEM_WSCTRL},
#line 156 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str45), VK_OEM_ENLW},
+ {gperf_offsetof(stringpool, 45), VK_OEM_ENLW},
#line 36 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str46), VK_NEXT},
+ {gperf_offsetof(stringpool, 46), VK_NEXT},
#line 51 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str47), VK_RWIN},
+ {gperf_offsetof(stringpool, 47), VK_RWIN},
#line 50 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str48), VK_LWIN},
+ {gperf_offsetof(stringpool, 48), VK_LWIN},
#line 21 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str49), VK_CAPITAL},
+ {gperf_offsetof(stringpool, 49), VK_CAPITAL},
#line 49 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str50), VK_HELP},
+ {gperf_offsetof(stringpool, 50), VK_HELP},
#line 164 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str51), VK_NONAME},
+ {gperf_offsetof(stringpool, 51), VK_NONAME},
#line 8 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str52), VK_RBUTTON},
+ {gperf_offsetof(stringpool, 52), VK_RBUTTON},
#line 7 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str53), VK_LBUTTON},
+ {gperf_offsetof(stringpool, 53), VK_LBUTTON},
#line 96 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str54), VK_OEM_NEC_EQUAL},
+ {gperf_offsetof(stringpool, 54), VK_OEM_NEC_EQUAL},
{-1},
#line 47 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str56), VK_INSERT},
+ {gperf_offsetof(stringpool, 56), VK_INSERT},
#line 27 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str57), VK_HANJA},
+ {gperf_offsetof(stringpool, 57), VK_HANJA},
{-1}, {-1},
#line 46 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str60), VK_SNAPSHOT},
+ {gperf_offsetof(stringpool, 60), VK_SNAPSHOT},
#line 158 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str61), VK_ATTN},
+ {gperf_offsetof(stringpool, 61), VK_ATTN},
#line 14 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str62), VK_TAB},
+ {gperf_offsetof(stringpool, 62), VK_TAB},
#line 157 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str63), VK_OEM_BACKTAB},
+ {gperf_offsetof(stringpool, 63), VK_OEM_BACKTAB},
#line 143 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str64), VK_ICO_CLEAR},
+ {gperf_offsetof(stringpool, 64), VK_ICO_CLEAR},
#line 30 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str65), VK_CONVERT},
+ {gperf_offsetof(stringpool, 65), VK_CONVERT},
#line 16 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str66), VK_RETURN},
+ {gperf_offsetof(stringpool, 66), VK_RETURN},
#line 146 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str67), VK_OEM_JUMP},
+ {gperf_offsetof(stringpool, 67), VK_OEM_JUMP},
{-1}, {-1}, {-1},
#line 111 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str71), VK_BROWSER_STOP},
+ {gperf_offsetof(stringpool, 71), VK_BROWSER_STOP},
#line 26 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str72), VK_FINAL},
+ {gperf_offsetof(stringpool, 72), VK_FINAL},
#line 163 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str73), VK_ZOOM},
+ {gperf_offsetof(stringpool, 73), VK_ZOOM},
#line 28 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str74), VK_KANJI},
+ {gperf_offsetof(stringpool, 74), VK_KANJI},
#line 48 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str75), VK_DELETE},
+ {gperf_offsetof(stringpool, 75), VK_DELETE},
#line 128 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str76), VK_OEM_COMMA},
+ {gperf_offsetof(stringpool, 76), VK_OEM_COMMA},
#line 67 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str77), VK_SUBTRACT},
+ {gperf_offsetof(stringpool, 77), VK_SUBTRACT},
{-1},
#line 10 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str79), VK_MBUTTON},
+ {gperf_offsetof(stringpool, 79), VK_MBUTTON},
#line 78 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str80), VK_F9},
+ {gperf_offsetof(stringpool, 80), VK_F9},
#line 17 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str81), VK_SHIFT},
+ {gperf_offsetof(stringpool, 81), VK_SHIFT},
#line 103 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str82), VK_RSHIFT},
+ {gperf_offsetof(stringpool, 82), VK_RSHIFT},
#line 102 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str83), VK_LSHIFT},
+ {gperf_offsetof(stringpool, 83), VK_LSHIFT},
#line 65 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str84), VK_ADD},
+ {gperf_offsetof(stringpool, 84), VK_ADD},
#line 31 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str85), VK_NONCONVERT},
+ {gperf_offsetof(stringpool, 85), VK_NONCONVERT},
#line 160 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str86), VK_EXSEL},
+ {gperf_offsetof(stringpool, 86), VK_EXSEL},
#line 126 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str87), VK_OEM_1},
+ {gperf_offsetof(stringpool, 87), VK_OEM_1},
#line 138 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str88), VK_OEM_AX},
+ {gperf_offsetof(stringpool, 88), VK_OEM_AX},
#line 108 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str89), VK_BROWSER_BACK},
+ {gperf_offsetof(stringpool, 89), VK_BROWSER_BACK},
#line 137 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str90), VK_OEM_8},
+ {gperf_offsetof(stringpool, 90), VK_OEM_8},
#line 129 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str91), VK_OEM_MINUS},
+ {gperf_offsetof(stringpool, 91), VK_OEM_MINUS},
#line 162 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str92), VK_PLAY},
+ {gperf_offsetof(stringpool, 92), VK_PLAY},
#line 131 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str93), VK_OEM_2},
+ {gperf_offsetof(stringpool, 93), VK_OEM_2},
#line 15 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str94), VK_CLEAR},
+ {gperf_offsetof(stringpool, 94), VK_CLEAR},
#line 99 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str95), VK_OEM_FJ_TOUROKU},
+ {gperf_offsetof(stringpool, 95), VK_OEM_FJ_TOUROKU},
#line 147 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str96), VK_OEM_PA1},
+ {gperf_offsetof(stringpool, 96), VK_OEM_PA1},
#line 140 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str97), VK_ICO_HELP},
+ {gperf_offsetof(stringpool, 97), VK_ICO_HELP},
#line 112 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str98), VK_BROWSER_SEARCH},
+ {gperf_offsetof(stringpool, 98), VK_BROWSER_SEARCH},
#line 53 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str99), VK_SLEEP},
+ {gperf_offsetof(stringpool, 99), VK_SLEEP},
{-1},
#line 70 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str101), VK_F1},
+ {gperf_offsetof(stringpool, 101), VK_F1},
#line 148 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str102), VK_OEM_PA2},
+ {gperf_offsetof(stringpool, 102), VK_OEM_PA2},
#line 154 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str103), VK_OEM_COPY},
+ {gperf_offsetof(stringpool, 103), VK_OEM_COPY},
#line 77 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str104), VK_F8},
+ {gperf_offsetof(stringpool, 104), VK_F8},
#line 88 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str105), VK_F19},
+ {gperf_offsetof(stringpool, 105), VK_F19},
#line 41 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str106), VK_RIGHT},
+ {gperf_offsetof(stringpool, 106), VK_RIGHT},
#line 71 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str107), VK_F2},
+ {gperf_offsetof(stringpool, 107), VK_F2},
#line 135 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str108), VK_OEM_6},
+ {gperf_offsetof(stringpool, 108), VK_OEM_6},
#line 87 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str109), VK_F18},
+ {gperf_offsetof(stringpool, 109), VK_F18},
{-1},
#line 117 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str111), VK_VOLUME_UP},
+ {gperf_offsetof(stringpool, 111), VK_VOLUME_UP},
{-1}, {-1},
#line 120 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str114), VK_MEDIA_STOP},
+ {gperf_offsetof(stringpool, 114), VK_MEDIA_STOP},
#line 130 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str115), VK_OEM_PERIOD},
+ {gperf_offsetof(stringpool, 115), VK_OEM_PERIOD},
{-1},
#line 161 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str117), VK_EREOF},
+ {gperf_offsetof(stringpool, 117), VK_EREOF},
{-1}, {-1}, {-1},
#line 114 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str121), VK_BROWSER_HOME},
+ {gperf_offsetof(stringpool, 121), VK_BROWSER_HOME},
#line 75 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str122), VK_F6},
+ {gperf_offsetof(stringpool, 122), VK_F6},
{-1},
#line 110 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str124), VK_BROWSER_REFRESH},
+ {gperf_offsetof(stringpool, 124), VK_BROWSER_REFRESH},
{-1},
#line 165 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str126), VK_PA1},
+ {gperf_offsetof(stringpool, 126), VK_PA1},
#line 142 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str127), VK_PROCESSKEY},
+ {gperf_offsetof(stringpool, 127), VK_PROCESSKEY},
#line 68 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str128), VK_DECIMAL},
+ {gperf_offsetof(stringpool, 128), VK_DECIMAL},
#line 132 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str129), VK_OEM_3},
+ {gperf_offsetof(stringpool, 129), VK_OEM_3},
#line 107 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str130), VK_RMENU},
+ {gperf_offsetof(stringpool, 130), VK_RMENU},
#line 106 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str131), VK_LMENU},
+ {gperf_offsetof(stringpool, 131), VK_LMENU},
#line 98 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str132), VK_OEM_FJ_MASSHOU},
+ {gperf_offsetof(stringpool, 132), VK_OEM_FJ_MASSHOU},
#line 54 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str133), VK_NUMPAD0},
+ {gperf_offsetof(stringpool, 133), VK_NUMPAD0},
#line 24 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str134), VK_HANGUL},
+ {gperf_offsetof(stringpool, 134), VK_HANGUL},
#line 63 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str135), VK_NUMPAD9},
+ {gperf_offsetof(stringpool, 135), VK_NUMPAD9},
#line 23 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str136), VK_HANGEUL},
+ {gperf_offsetof(stringpool, 136), VK_HANGEUL},
#line 134 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str137), VK_OEM_5},
+ {gperf_offsetof(stringpool, 137), VK_OEM_5},
#line 149 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str138), VK_OEM_PA3},
+ {gperf_offsetof(stringpool, 138), VK_OEM_PA3},
#line 115 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str139), VK_VOLUME_MUTE},
+ {gperf_offsetof(stringpool, 139), VK_VOLUME_MUTE},
#line 133 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str140), VK_OEM_4},
+ {gperf_offsetof(stringpool, 140), VK_OEM_4},
#line 122 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str141), VK_LAUNCH_MAIL},
+ {gperf_offsetof(stringpool, 141), VK_LAUNCH_MAIL},
#line 97 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str142), VK_OEM_FJ_JISHO},
+ {gperf_offsetof(stringpool, 142), VK_OEM_FJ_JISHO},
#line 72 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str143), VK_F3},
+ {gperf_offsetof(stringpool, 143), VK_F3},
#line 101 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str144), VK_OEM_FJ_ROYA},
+ {gperf_offsetof(stringpool, 144), VK_OEM_FJ_ROYA},
#line 100 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str145), VK_OEM_FJ_LOYA},
+ {gperf_offsetof(stringpool, 145), VK_OEM_FJ_LOYA},
{-1},
#line 42 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str147), VK_DOWN},
+ {gperf_offsetof(stringpool, 147), VK_DOWN},
{-1},
#line 153 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str149), VK_OEM_FINISH},
+ {gperf_offsetof(stringpool, 149), VK_OEM_FINISH},
{-1},
#line 74 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str151), VK_F5},
+ {gperf_offsetof(stringpool, 151), VK_F5},
{-1},
#line 136 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str153), VK_OEM_7},
+ {gperf_offsetof(stringpool, 153), VK_OEM_7},
#line 73 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str154), VK_F4},
+ {gperf_offsetof(stringpool, 154), VK_F4},
#line 86 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str155), VK_F17},
+ {gperf_offsetof(stringpool, 155), VK_F17},
#line 55 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str156), VK_NUMPAD1},
+ {gperf_offsetof(stringpool, 156), VK_NUMPAD1},
#line 141 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str157), VK_ICO_00},
+ {gperf_offsetof(stringpool, 157), VK_ICO_00},
{-1},
#line 62 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str159), VK_NUMPAD8},
+ {gperf_offsetof(stringpool, 159), VK_NUMPAD8},
{-1}, {-1},
#line 56 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str162), VK_NUMPAD2},
+ {gperf_offsetof(stringpool, 162), VK_NUMPAD2},
{-1},
#line 124 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str164), VK_LAUNCH_APP1},
+ {gperf_offsetof(stringpool, 164), VK_LAUNCH_APP1},
#line 109 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str165), VK_BROWSER_FORWARD},
+ {gperf_offsetof(stringpool, 165), VK_BROWSER_FORWARD},
{-1},
#line 76 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str167), VK_F7},
+ {gperf_offsetof(stringpool, 167), VK_F7},
{-1}, {-1},
#line 125 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str170), VK_LAUNCH_APP2},
+ {gperf_offsetof(stringpool, 170), VK_LAUNCH_APP2},
#line 64 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str171), VK_MULTIPLY},
+ {gperf_offsetof(stringpool, 171), VK_MULTIPLY},
{-1}, {-1},
#line 45 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str174), VK_EXECUTE},
+ {gperf_offsetof(stringpool, 174), VK_EXECUTE},
{-1},
#line 113 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str176), VK_BROWSER_FAVORITES},
+ {gperf_offsetof(stringpool, 176), VK_BROWSER_FAVORITES},
#line 60 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str177), VK_NUMPAD6},
+ {gperf_offsetof(stringpool, 177), VK_NUMPAD6},
{-1},
#line 85 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str179), VK_F16},
+ {gperf_offsetof(stringpool, 179), VK_F16},
{-1}, {-1},
#line 79 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str182), VK_F10},
+ {gperf_offsetof(stringpool, 182), VK_F10},
{-1}, {-1},
#line 116 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str185), VK_VOLUME_DOWN},
+ {gperf_offsetof(stringpool, 185), VK_VOLUME_DOWN},
{-1}, {-1},
#line 89 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str188), VK_F20},
+ {gperf_offsetof(stringpool, 188), VK_F20},
#line 119 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str189), VK_MEDIA_PREV_TRACK},
+ {gperf_offsetof(stringpool, 189), VK_MEDIA_PREV_TRACK},
{-1},
#line 33 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str191), VK_MODECHANGE},
+ {gperf_offsetof(stringpool, 191), VK_MODECHANGE},
{-1}, {-1}, {-1}, {-1}, {-1},
#line 83 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str197), VK_F14},
+ {gperf_offsetof(stringpool, 197), VK_F14},
#line 57 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str198), VK_NUMPAD3},
+ {gperf_offsetof(stringpool, 198), VK_NUMPAD3},
#line 11 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str199), VK_XBUTTON1},
+ {gperf_offsetof(stringpool, 199), VK_XBUTTON1},
{-1}, {-1}, {-1},
#line 93 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str203), VK_F24},
+ {gperf_offsetof(stringpool, 203), VK_F24},
{-1},
#line 12 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str205), VK_XBUTTON2},
+ {gperf_offsetof(stringpool, 205), VK_XBUTTON2},
#line 59 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str206), VK_NUMPAD5},
+ {gperf_offsetof(stringpool, 206), VK_NUMPAD5},
{-1}, {-1},
#line 58 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str209), VK_NUMPAD4},
+ {gperf_offsetof(stringpool, 209), VK_NUMPAD4},
{-1}, {-1}, {-1}, {-1}, {-1},
#line 121 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str215), VK_MEDIA_PLAY_PAUSE},
+ {gperf_offsetof(stringpool, 215), VK_MEDIA_PLAY_PAUSE},
{-1},
#line 123 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str217), VK_LAUNCH_MEDIA_SELECT},
+ {gperf_offsetof(stringpool, 217), VK_LAUNCH_MEDIA_SELECT},
#line 80 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str218), VK_F11},
+ {gperf_offsetof(stringpool, 218), VK_F11},
{-1},
#line 139 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str220), VK_OEM_102},
+ {gperf_offsetof(stringpool, 220), VK_OEM_102},
#line 118 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str221), VK_MEDIA_NEXT_TRACK},
+ {gperf_offsetof(stringpool, 221), VK_MEDIA_NEXT_TRACK},
#line 61 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str222), VK_NUMPAD7},
+ {gperf_offsetof(stringpool, 222), VK_NUMPAD7},
{-1},
#line 90 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str224), VK_F21},
+ {gperf_offsetof(stringpool, 224), VK_F21},
{-1},
#line 82 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str226), VK_F13},
+ {gperf_offsetof(stringpool, 226), VK_F13},
{-1}, {-1},
#line 81 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str229), VK_F12},
+ {gperf_offsetof(stringpool, 229), VK_F12},
{-1}, {-1},
#line 92 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str232), VK_F23},
+ {gperf_offsetof(stringpool, 232), VK_F23},
{-1}, {-1},
#line 91 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str235), VK_F22},
+ {gperf_offsetof(stringpool, 235), VK_F22},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1},
#line 84 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str242), VK_F15},
+ {gperf_offsetof(stringpool, 242), VK_F15},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1}, {-1},
#line 69 "win32_vk.list"
- {offsetof(struct stringpool_t, stringpool_str256), VK_DIVIDE}
+ {gperf_offsetof(stringpool, 256), VK_DIVIDE}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = hash (str, len);
+ register unsigned int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register int o = wordlist[key].ofs;
if (o >= 0)
diff --git a/ext/io/console/win32_vk.list b/ext/io/console/win32_vk.list
index 28bc9545ec..7909a4d1f0 100644
--- a/ext/io/console/win32_vk.list
+++ b/ext/io/console/win32_vk.list
@@ -1,6 +1,6 @@
%{
struct vktable {short ofs; unsigned short vk;};
-static const struct vktable *console_win32_vk(const char *, unsigned int);
+static const struct vktable *console_win32_vk(/*!ANSI{*/const char *, unsigned int/*}!ANSI*/);
%}
struct vktable
%%
diff --git a/ext/io/nonblock/depend b/ext/io/nonblock/depend
index 4402898de6..673f4161a7 100644
--- a/ext/io/nonblock/depend
+++ b/ext/io/nonblock/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
nonblock.o: $(RUBY_EXTCONF_H)
nonblock.o: $(arch_hdrdir)/ruby/config.h
+nonblock.o: $(hdrdir)/ruby.h
+nonblock.o: $(hdrdir)/ruby/internal/anyargs.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+nonblock.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+nonblock.o: $(hdrdir)/ruby/internal/assume.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/artificial.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/cold.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/const.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/error.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/format.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/noalias.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/noinline.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/pure.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/restrict.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/warning.h
+nonblock.o: $(hdrdir)/ruby/internal/attr/weakref.h
+nonblock.o: $(hdrdir)/ruby/internal/cast.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_is.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+nonblock.o: $(hdrdir)/ruby/internal/compiler_since.h
+nonblock.o: $(hdrdir)/ruby/internal/config.h
+nonblock.o: $(hdrdir)/ruby/internal/constant_p.h
+nonblock.o: $(hdrdir)/ruby/internal/core.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rarray.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rbasic.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rbignum.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rclass.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rdata.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rfile.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rhash.h
+nonblock.o: $(hdrdir)/ruby/internal/core/robject.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rregexp.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rstring.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rstruct.h
+nonblock.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+nonblock.o: $(hdrdir)/ruby/internal/ctype.h
+nonblock.o: $(hdrdir)/ruby/internal/dllexport.h
+nonblock.o: $(hdrdir)/ruby/internal/dosish.h
+nonblock.o: $(hdrdir)/ruby/internal/error.h
+nonblock.o: $(hdrdir)/ruby/internal/eval.h
+nonblock.o: $(hdrdir)/ruby/internal/event.h
+nonblock.o: $(hdrdir)/ruby/internal/fl_type.h
+nonblock.o: $(hdrdir)/ruby/internal/gc.h
+nonblock.o: $(hdrdir)/ruby/internal/glob.h
+nonblock.o: $(hdrdir)/ruby/internal/globals.h
+nonblock.o: $(hdrdir)/ruby/internal/has/attribute.h
+nonblock.o: $(hdrdir)/ruby/internal/has/builtin.h
+nonblock.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+nonblock.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+nonblock.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+nonblock.o: $(hdrdir)/ruby/internal/has/extension.h
+nonblock.o: $(hdrdir)/ruby/internal/has/feature.h
+nonblock.o: $(hdrdir)/ruby/internal/has/warning.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/array.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/bignum.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/class.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/compar.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/complex.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/cont.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/dir.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/enum.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/error.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/eval.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/file.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/gc.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/hash.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/io.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/load.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/marshal.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/numeric.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/object.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/parse.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/proc.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/process.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/random.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/range.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/rational.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/re.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/ruby.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/select.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/signal.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/string.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/struct.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/thread.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/time.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/variable.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/vm.h
+nonblock.o: $(hdrdir)/ruby/internal/interpreter.h
+nonblock.o: $(hdrdir)/ruby/internal/iterator.h
+nonblock.o: $(hdrdir)/ruby/internal/memory.h
+nonblock.o: $(hdrdir)/ruby/internal/method.h
+nonblock.o: $(hdrdir)/ruby/internal/module.h
+nonblock.o: $(hdrdir)/ruby/internal/newobj.h
+nonblock.o: $(hdrdir)/ruby/internal/rgengc.h
+nonblock.o: $(hdrdir)/ruby/internal/scan_args.h
+nonblock.o: $(hdrdir)/ruby/internal/special_consts.h
+nonblock.o: $(hdrdir)/ruby/internal/static_assert.h
+nonblock.o: $(hdrdir)/ruby/internal/stdalign.h
+nonblock.o: $(hdrdir)/ruby/internal/stdbool.h
+nonblock.o: $(hdrdir)/ruby/internal/symbol.h
+nonblock.o: $(hdrdir)/ruby/internal/token_paste.h
+nonblock.o: $(hdrdir)/ruby/internal/value.h
+nonblock.o: $(hdrdir)/ruby/internal/value_type.h
+nonblock.o: $(hdrdir)/ruby/internal/variable.h
+nonblock.o: $(hdrdir)/ruby/internal/warning_push.h
+nonblock.o: $(hdrdir)/ruby/internal/xmalloc.h
+nonblock.o: $(hdrdir)/ruby/assert.h
nonblock.o: $(hdrdir)/ruby/backward.h
+nonblock.o: $(hdrdir)/ruby/backward/2/assume.h
+nonblock.o: $(hdrdir)/ruby/backward/2/attributes.h
+nonblock.o: $(hdrdir)/ruby/backward/2/bool.h
+nonblock.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+nonblock.o: $(hdrdir)/ruby/backward/2/inttypes.h
+nonblock.o: $(hdrdir)/ruby/backward/2/limits.h
+nonblock.o: $(hdrdir)/ruby/backward/2/long_long.h
+nonblock.o: $(hdrdir)/ruby/backward/2/stdalign.h
+nonblock.o: $(hdrdir)/ruby/backward/2/stdarg.h
nonblock.o: $(hdrdir)/ruby/defines.h
nonblock.o: $(hdrdir)/ruby/encoding.h
nonblock.o: $(hdrdir)/ruby/intern.h
@@ -12,6 +163,5 @@ nonblock.o: $(hdrdir)/ruby/oniguruma.h
nonblock.o: $(hdrdir)/ruby/ruby.h
nonblock.o: $(hdrdir)/ruby/st.h
nonblock.o: $(hdrdir)/ruby/subst.h
-nonblock.o: $(top_srcdir)/include/ruby.h
nonblock.o: nonblock.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/io/nonblock/io-nonblock.gemspec b/ext/io/nonblock/io-nonblock.gemspec
new file mode 100644
index 0000000000..34d736650b
--- /dev/null
+++ b/ext/io/nonblock/io-nonblock.gemspec
@@ -0,0 +1,25 @@
+Gem::Specification.new do |spec|
+ spec.name = "io-nonblock"
+ spec.version = "0.1.0"
+ spec.authors = ["Nobu Nakada"]
+ spec.email = ["nobu@ruby-lang.org"]
+
+ spec.summary = %q{Enables non-blocking mode with IO class}
+ spec.description = %q{Enables non-blocking mode with IO class}
+ spec.homepage = "https://github.com/ruby/io-nonblock"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ %x[git ls-files -z].split("\x0").reject do |f|
+ f.match(%r{\A(?:test|spec|features)/|\A\.(?:git|travis)})
+ end
+ end
+ spec.extensions = %w[ext/io/nonblock/extconf.rb]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/ext/io/wait/depend b/ext/io/wait/depend
index f509dcd8a4..af227a8f19 100644
--- a/ext/io/wait/depend
+++ b/ext/io/wait/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
wait.o: $(RUBY_EXTCONF_H)
wait.o: $(arch_hdrdir)/ruby/config.h
+wait.o: $(hdrdir)/ruby.h
+wait.o: $(hdrdir)/ruby/internal/anyargs.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+wait.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+wait.o: $(hdrdir)/ruby/internal/assume.h
+wait.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+wait.o: $(hdrdir)/ruby/internal/attr/artificial.h
+wait.o: $(hdrdir)/ruby/internal/attr/cold.h
+wait.o: $(hdrdir)/ruby/internal/attr/const.h
+wait.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+wait.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+wait.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+wait.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+wait.o: $(hdrdir)/ruby/internal/attr/error.h
+wait.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+wait.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+wait.o: $(hdrdir)/ruby/internal/attr/format.h
+wait.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+wait.o: $(hdrdir)/ruby/internal/attr/noalias.h
+wait.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+wait.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+wait.o: $(hdrdir)/ruby/internal/attr/noinline.h
+wait.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+wait.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+wait.o: $(hdrdir)/ruby/internal/attr/pure.h
+wait.o: $(hdrdir)/ruby/internal/attr/restrict.h
+wait.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+wait.o: $(hdrdir)/ruby/internal/attr/warning.h
+wait.o: $(hdrdir)/ruby/internal/attr/weakref.h
+wait.o: $(hdrdir)/ruby/internal/cast.h
+wait.o: $(hdrdir)/ruby/internal/compiler_is.h
+wait.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+wait.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+wait.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+wait.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+wait.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+wait.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+wait.o: $(hdrdir)/ruby/internal/compiler_since.h
+wait.o: $(hdrdir)/ruby/internal/config.h
+wait.o: $(hdrdir)/ruby/internal/constant_p.h
+wait.o: $(hdrdir)/ruby/internal/core.h
+wait.o: $(hdrdir)/ruby/internal/core/rarray.h
+wait.o: $(hdrdir)/ruby/internal/core/rbasic.h
+wait.o: $(hdrdir)/ruby/internal/core/rbignum.h
+wait.o: $(hdrdir)/ruby/internal/core/rclass.h
+wait.o: $(hdrdir)/ruby/internal/core/rdata.h
+wait.o: $(hdrdir)/ruby/internal/core/rfile.h
+wait.o: $(hdrdir)/ruby/internal/core/rhash.h
+wait.o: $(hdrdir)/ruby/internal/core/robject.h
+wait.o: $(hdrdir)/ruby/internal/core/rregexp.h
+wait.o: $(hdrdir)/ruby/internal/core/rstring.h
+wait.o: $(hdrdir)/ruby/internal/core/rstruct.h
+wait.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+wait.o: $(hdrdir)/ruby/internal/ctype.h
+wait.o: $(hdrdir)/ruby/internal/dllexport.h
+wait.o: $(hdrdir)/ruby/internal/dosish.h
+wait.o: $(hdrdir)/ruby/internal/error.h
+wait.o: $(hdrdir)/ruby/internal/eval.h
+wait.o: $(hdrdir)/ruby/internal/event.h
+wait.o: $(hdrdir)/ruby/internal/fl_type.h
+wait.o: $(hdrdir)/ruby/internal/gc.h
+wait.o: $(hdrdir)/ruby/internal/glob.h
+wait.o: $(hdrdir)/ruby/internal/globals.h
+wait.o: $(hdrdir)/ruby/internal/has/attribute.h
+wait.o: $(hdrdir)/ruby/internal/has/builtin.h
+wait.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+wait.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+wait.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+wait.o: $(hdrdir)/ruby/internal/has/extension.h
+wait.o: $(hdrdir)/ruby/internal/has/feature.h
+wait.o: $(hdrdir)/ruby/internal/has/warning.h
+wait.o: $(hdrdir)/ruby/internal/intern/array.h
+wait.o: $(hdrdir)/ruby/internal/intern/bignum.h
+wait.o: $(hdrdir)/ruby/internal/intern/class.h
+wait.o: $(hdrdir)/ruby/internal/intern/compar.h
+wait.o: $(hdrdir)/ruby/internal/intern/complex.h
+wait.o: $(hdrdir)/ruby/internal/intern/cont.h
+wait.o: $(hdrdir)/ruby/internal/intern/dir.h
+wait.o: $(hdrdir)/ruby/internal/intern/enum.h
+wait.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+wait.o: $(hdrdir)/ruby/internal/intern/error.h
+wait.o: $(hdrdir)/ruby/internal/intern/eval.h
+wait.o: $(hdrdir)/ruby/internal/intern/file.h
+wait.o: $(hdrdir)/ruby/internal/intern/gc.h
+wait.o: $(hdrdir)/ruby/internal/intern/hash.h
+wait.o: $(hdrdir)/ruby/internal/intern/io.h
+wait.o: $(hdrdir)/ruby/internal/intern/load.h
+wait.o: $(hdrdir)/ruby/internal/intern/marshal.h
+wait.o: $(hdrdir)/ruby/internal/intern/numeric.h
+wait.o: $(hdrdir)/ruby/internal/intern/object.h
+wait.o: $(hdrdir)/ruby/internal/intern/parse.h
+wait.o: $(hdrdir)/ruby/internal/intern/proc.h
+wait.o: $(hdrdir)/ruby/internal/intern/process.h
+wait.o: $(hdrdir)/ruby/internal/intern/random.h
+wait.o: $(hdrdir)/ruby/internal/intern/range.h
+wait.o: $(hdrdir)/ruby/internal/intern/rational.h
+wait.o: $(hdrdir)/ruby/internal/intern/re.h
+wait.o: $(hdrdir)/ruby/internal/intern/ruby.h
+wait.o: $(hdrdir)/ruby/internal/intern/select.h
+wait.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+wait.o: $(hdrdir)/ruby/internal/intern/signal.h
+wait.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+wait.o: $(hdrdir)/ruby/internal/intern/string.h
+wait.o: $(hdrdir)/ruby/internal/intern/struct.h
+wait.o: $(hdrdir)/ruby/internal/intern/thread.h
+wait.o: $(hdrdir)/ruby/internal/intern/time.h
+wait.o: $(hdrdir)/ruby/internal/intern/variable.h
+wait.o: $(hdrdir)/ruby/internal/intern/vm.h
+wait.o: $(hdrdir)/ruby/internal/interpreter.h
+wait.o: $(hdrdir)/ruby/internal/iterator.h
+wait.o: $(hdrdir)/ruby/internal/memory.h
+wait.o: $(hdrdir)/ruby/internal/method.h
+wait.o: $(hdrdir)/ruby/internal/module.h
+wait.o: $(hdrdir)/ruby/internal/newobj.h
+wait.o: $(hdrdir)/ruby/internal/rgengc.h
+wait.o: $(hdrdir)/ruby/internal/scan_args.h
+wait.o: $(hdrdir)/ruby/internal/special_consts.h
+wait.o: $(hdrdir)/ruby/internal/static_assert.h
+wait.o: $(hdrdir)/ruby/internal/stdalign.h
+wait.o: $(hdrdir)/ruby/internal/stdbool.h
+wait.o: $(hdrdir)/ruby/internal/symbol.h
+wait.o: $(hdrdir)/ruby/internal/token_paste.h
+wait.o: $(hdrdir)/ruby/internal/value.h
+wait.o: $(hdrdir)/ruby/internal/value_type.h
+wait.o: $(hdrdir)/ruby/internal/variable.h
+wait.o: $(hdrdir)/ruby/internal/warning_push.h
+wait.o: $(hdrdir)/ruby/internal/xmalloc.h
+wait.o: $(hdrdir)/ruby/assert.h
wait.o: $(hdrdir)/ruby/backward.h
+wait.o: $(hdrdir)/ruby/backward/2/assume.h
+wait.o: $(hdrdir)/ruby/backward/2/attributes.h
+wait.o: $(hdrdir)/ruby/backward/2/bool.h
+wait.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+wait.o: $(hdrdir)/ruby/backward/2/inttypes.h
+wait.o: $(hdrdir)/ruby/backward/2/limits.h
+wait.o: $(hdrdir)/ruby/backward/2/long_long.h
+wait.o: $(hdrdir)/ruby/backward/2/stdalign.h
+wait.o: $(hdrdir)/ruby/backward/2/stdarg.h
wait.o: $(hdrdir)/ruby/defines.h
wait.o: $(hdrdir)/ruby/encoding.h
wait.o: $(hdrdir)/ruby/intern.h
@@ -12,6 +163,5 @@ wait.o: $(hdrdir)/ruby/oniguruma.h
wait.o: $(hdrdir)/ruby/ruby.h
wait.o: $(hdrdir)/ruby/st.h
wait.o: $(hdrdir)/ruby/subst.h
-wait.o: $(top_srcdir)/include/ruby.h
wait.o: wait.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/io/wait/io-wait.gemspec b/ext/io/wait/io-wait.gemspec
new file mode 100644
index 0000000000..ec23699def
--- /dev/null
+++ b/ext/io/wait/io-wait.gemspec
@@ -0,0 +1,27 @@
+_VERSION = "0.2.0"
+
+Gem::Specification.new do |spec|
+ spec.name = "io-wait"
+ spec.version = _VERSION
+ spec.authors = ["Nobu Nakada"]
+ spec.email = ["nobu@ruby-lang.org"]
+
+ spec.summary = %q{Waits until IO is readable or writable without blocking.}
+ spec.description = %q{Waits until IO is readable or writable without blocking.}
+ spec.homepage = "https://github.com/ruby/io-wait"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject do |f|
+ f.match(%r{\A(?:test|spec|features)/|\A\.(?:git|travis)})
+ end
+ end
+ spec.extensions = %w[ext/io/wait/extconf.rb]
+ spec.bindir = "exe"
+ spec.executables = []
+ spec.require_paths = ["lib"]
+end
diff --git a/ext/io/wait/wait.c b/ext/io/wait/wait.c
index f7a7508eeb..512e4f6a80 100644
--- a/ext/io/wait/wait.c
+++ b/ext/io/wait/wait.c
@@ -1,3 +1,4 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: t -*- */
/**********************************************************************
io/wait.c -
@@ -39,35 +40,6 @@
#define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue)
#endif
-static VALUE io_ready_p _((VALUE io));
-static VALUE io_wait_readable _((int argc, VALUE *argv, VALUE io));
-static VALUE io_wait_writable _((int argc, VALUE *argv, VALUE io));
-void Init_wait _((void));
-
-static struct timeval *
-get_timeout(int argc, VALUE *argv, struct timeval *timerec)
-{
- VALUE timeout = Qnil;
- rb_check_arity(argc, 0, 1);
- if (!argc || NIL_P(timeout = argv[0])) {
- return NULL;
- }
- else {
- *timerec = rb_time_interval(timeout);
- return timerec;
- }
-}
-
-static int
-wait_for_single_fd(rb_io_t *fptr, int events, struct timeval *tv)
-{
- int i = rb_wait_for_single_fd(fptr->fd, events, tv);
- if (i < 0)
- rb_sys_fail(0);
- rb_io_check_closed(fptr);
- return (i & events);
-}
-
/*
* call-seq:
* io.nread -> int
@@ -79,13 +51,12 @@ wait_for_single_fd(rb_io_t *fptr, int events, struct timeval *tv)
static VALUE
io_nread(VALUE io)
{
- rb_io_t *fptr;
- int len;
+ rb_io_t *fptr = NULL;
ioctl_arg n;
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
- len = rb_io_read_pending(fptr);
+ int len = rb_io_read_pending(fptr);
if (len > 0) return INT2FIX(len);
if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
@@ -93,77 +64,114 @@ io_nread(VALUE io)
return INT2FIX(0);
}
+static VALUE
+io_wait_event(VALUE io, int event, VALUE timeout)
+{
+ VALUE result = rb_io_wait(io, RB_INT2NUM(event), timeout);
+
+ if (!RB_TEST(result)) {
+ return Qnil;
+ }
+
+ int mask = RB_NUM2INT(result);
+
+ if (mask & event) {
+ return io;
+ }
+ else {
+ return Qfalse;
+ }
+}
+
/*
* call-seq:
- * io.ready? -> true, false or nil
+ * io.ready? -> true or false
*
- * Returns true if input available without blocking, or false.
- * Returns nil if no information available.
+ * Returns +true+ if input available without blocking, or +false+.
*/
static VALUE
io_ready_p(VALUE io)
{
rb_io_t *fptr;
- struct timeval tv = {0, 0};
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
if (rb_io_read_pending(fptr)) return Qtrue;
- if (wait_for_single_fd(fptr, RB_WAITFD_IN, &tv))
- return Qtrue;
- return Qfalse;
+
+ return io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0));
}
/*
* call-seq:
- * io.wait_readable -> IO, true or nil
- * io.wait_readable(timeout) -> IO, true or nil
+ * io.wait_readable -> true or false
+ * io.wait_readable(timeout) -> true or false
*
- * Waits until IO is readable without blocking and returns +self+, or
- * +nil+ when times out.
+ * Waits until IO is readable and returns +true+, or
+ * +false+ when times out.
* Returns +true+ immediately when buffered data is available.
*/
static VALUE
io_wait_readable(int argc, VALUE *argv, VALUE io)
{
- rb_io_t *fptr;
- struct timeval timerec;
- struct timeval *tv;
+ rb_io_t *fptr = NULL;
- GetOpenFile(io, fptr);
+ RB_IO_POINTER(io, fptr);
rb_io_check_readable(fptr);
- tv = get_timeout(argc, argv, &timerec);
+
if (rb_io_read_pending(fptr)) return Qtrue;
- if (wait_for_single_fd(fptr, RB_WAITFD_IN, tv)) {
- return io;
- }
- return Qnil;
+
+ rb_check_arity(argc, 0, 1);
+ VALUE timeout = (argc == 1 ? argv[0] : Qnil);
+
+ return io_wait_event(io, RUBY_IO_READABLE, timeout);
}
/*
* call-seq:
- * io.wait_writable -> IO
- * io.wait_writable(timeout) -> IO or nil
+ * io.wait_writable -> true or false
+ * io.wait_writable(timeout) -> true or false
*
- * Waits until IO is writable without blocking and returns +self+ or
- * +nil+ when times out.
+ * Waits until IO is writable and returns +true+ or
+ * +false+ when times out.
*/
static VALUE
io_wait_writable(int argc, VALUE *argv, VALUE io)
{
- rb_io_t *fptr;
- struct timeval timerec;
- struct timeval *tv;
+ rb_io_t *fptr = NULL;
- GetOpenFile(io, fptr);
+ RB_IO_POINTER(io, fptr);
rb_io_check_writable(fptr);
- tv = get_timeout(argc, argv, &timerec);
- if (wait_for_single_fd(fptr, RB_WAITFD_OUT, tv)) {
- return io;
- }
- return Qnil;
+
+ rb_check_arity(argc, 0, 1);
+ VALUE timeout = (argc == 1 ? argv[0] : Qnil);
+
+ return io_wait_event(io, RUBY_IO_WRITABLE, timeout);
+}
+
+/*
+ * call-seq:
+ * io.wait_priority -> true or false
+ * io.wait_priority(timeout) -> true or false
+ *
+ * Waits until IO is priority and returns +true+ or
+ * +false+ when times out.
+ */
+static VALUE
+io_wait_priority(int argc, VALUE *argv, VALUE io)
+{
+ rb_io_t *fptr = NULL;
+
+ RB_IO_POINTER(io, fptr);
+ rb_io_check_readable(fptr);
+
+ if (rb_io_read_pending(fptr)) return Qtrue;
+
+ rb_check_arity(argc, 0, 1);
+ VALUE timeout = argc == 1 ? argv[0] : Qnil;
+
+ return io_wait_event(io, RUBY_IO_PRIORITY, timeout);
}
static int
@@ -202,41 +210,60 @@ wait_mode_sym(VALUE mode)
/*
* call-seq:
- * io.wait(timeout = nil, mode = :read) -> IO, true or nil
+ * io.wait(events, timeout) -> event mask or false.
+ * io.wait(timeout = nil, mode = :read) -> event mask or false.
+ *
+ * Waits until the IO becomes ready for the specified events and returns the
+ * subset of events that become ready, or +false+ when times out.
+ *
+ * The events can be a bit mask of +IO::READABLE+, +IO::WRITABLE+ or
+ * +IO::PRIORITY+.
*
- * Waits until IO is readable or writable without blocking and returns
- * +self+, or +nil+ when times out.
* Returns +true+ immediately when buffered data is available.
+ *
* Optional parameter +mode+ is one of +:read+, +:write+, or
* +:read_write+.
*/
static VALUE
-io_wait_readwrite(int argc, VALUE *argv, VALUE io)
+io_wait(int argc, VALUE *argv, VALUE io)
{
- rb_io_t *fptr;
- struct timeval timerec;
- struct timeval *tv = NULL;
- int event = 0;
- int i;
+ VALUE timeout = Qundef;
+ rb_io_event_t events = 0;
- GetOpenFile(io, fptr);
- for (i = 0; i < argc; ++i) {
- if (SYMBOL_P(argv[i])) {
- event |= wait_mode_sym(argv[i]);
+ if (argc != 2 || (RB_SYMBOL_P(argv[0]) || RB_SYMBOL_P(argv[1]))) {
+ for (int i = 0; i < argc; i += 1) {
+ if (RB_SYMBOL_P(argv[i])) {
+ events |= wait_mode_sym(argv[i]);
+ }
+ else if (timeout == Qundef) {
+ rb_time_interval(timeout = argv[i]);
+ }
+ else {
+ rb_raise(rb_eArgError, "timeout given more than once");
+ }
}
- else {
- *(tv = &timerec) = rb_time_interval(argv[i]);
+ if (timeout == Qundef) timeout = Qnil;
+ }
+ else /* argc == 2 */ {
+ events = RB_NUM2UINT(argv[0]);
+ timeout = argv[1];
+ }
+
+ if (events == 0) {
+ events = RUBY_IO_READABLE;
+ }
+
+ if (events & RUBY_IO_READABLE) {
+ rb_io_t *fptr = NULL;
+ RB_IO_POINTER(io, fptr);
+
+ if (rb_io_read_pending(fptr)) {
+ return Qtrue;
}
}
- /* rb_time_interval() and might_mode() might convert the argument */
- rb_io_check_closed(fptr);
- if (!event) event = RB_WAITFD_IN;
- if ((event & RB_WAITFD_IN) && rb_io_read_pending(fptr))
- return Qtrue;
- if (wait_for_single_fd(fptr, event, tv))
- return io;
- return Qnil;
+
+ return io_wait_event(io, events, timeout);
}
/*
@@ -246,9 +273,16 @@ io_wait_readwrite(int argc, VALUE *argv, VALUE io)
void
Init_wait(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ RB_EXT_RACTOR_SAFE(true);
+#endif
+
rb_define_method(rb_cIO, "nread", io_nread, 0);
rb_define_method(rb_cIO, "ready?", io_ready_p, 0);
- rb_define_method(rb_cIO, "wait", io_wait_readwrite, -1);
+
+ rb_define_method(rb_cIO, "wait", io_wait, -1);
+
rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1);
rb_define_method(rb_cIO, "wait_writable", io_wait_writable, -1);
+ rb_define_method(rb_cIO, "wait_priority", io_wait_priority, -1);
}
diff --git a/ext/json/VERSION b/ext/json/VERSION
new file mode 100644
index 0000000000..73462a5a13
--- /dev/null
+++ b/ext/json/VERSION
@@ -0,0 +1 @@
+2.5.1
diff --git a/ext/json/depend b/ext/json/depend
new file mode 100644
index 0000000000..0301ce074c
--- /dev/null
+++ b/ext/json/depend
@@ -0,0 +1,2 @@
+# AUTOGENERATED DEPENDENCIES START
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/json/extconf.rb b/ext/json/extconf.rb
index 7595d58a98..8a99b6a5c8 100644
--- a/ext/json/extconf.rb
+++ b/ext/json/extconf.rb
@@ -1,2 +1,3 @@
require 'mkmf'
+
create_makefile('json')
diff --git a/ext/json/generator/depend b/ext/json/generator/depend
index 54e8ae3eb4..89e43dbfab 100644
--- a/ext/json/generator/depend
+++ b/ext/json/generator/depend
@@ -4,7 +4,159 @@ generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h
# AUTOGENERATED DEPENDENCIES START
generator.o: $(RUBY_EXTCONF_H)
generator.o: $(arch_hdrdir)/ruby/config.h
+generator.o: $(hdrdir)/ruby.h
+generator.o: $(hdrdir)/ruby/internal/anyargs.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+generator.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+generator.o: $(hdrdir)/ruby/internal/assume.h
+generator.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+generator.o: $(hdrdir)/ruby/internal/attr/artificial.h
+generator.o: $(hdrdir)/ruby/internal/attr/cold.h
+generator.o: $(hdrdir)/ruby/internal/attr/const.h
+generator.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+generator.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+generator.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+generator.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+generator.o: $(hdrdir)/ruby/internal/attr/error.h
+generator.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+generator.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+generator.o: $(hdrdir)/ruby/internal/attr/format.h
+generator.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+generator.o: $(hdrdir)/ruby/internal/attr/noalias.h
+generator.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+generator.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+generator.o: $(hdrdir)/ruby/internal/attr/noinline.h
+generator.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+generator.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+generator.o: $(hdrdir)/ruby/internal/attr/pure.h
+generator.o: $(hdrdir)/ruby/internal/attr/restrict.h
+generator.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+generator.o: $(hdrdir)/ruby/internal/attr/warning.h
+generator.o: $(hdrdir)/ruby/internal/attr/weakref.h
+generator.o: $(hdrdir)/ruby/internal/cast.h
+generator.o: $(hdrdir)/ruby/internal/compiler_is.h
+generator.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+generator.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+generator.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+generator.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+generator.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+generator.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+generator.o: $(hdrdir)/ruby/internal/compiler_since.h
+generator.o: $(hdrdir)/ruby/internal/config.h
+generator.o: $(hdrdir)/ruby/internal/constant_p.h
+generator.o: $(hdrdir)/ruby/internal/core.h
+generator.o: $(hdrdir)/ruby/internal/core/rarray.h
+generator.o: $(hdrdir)/ruby/internal/core/rbasic.h
+generator.o: $(hdrdir)/ruby/internal/core/rbignum.h
+generator.o: $(hdrdir)/ruby/internal/core/rclass.h
+generator.o: $(hdrdir)/ruby/internal/core/rdata.h
+generator.o: $(hdrdir)/ruby/internal/core/rfile.h
+generator.o: $(hdrdir)/ruby/internal/core/rhash.h
+generator.o: $(hdrdir)/ruby/internal/core/rmatch.h
+generator.o: $(hdrdir)/ruby/internal/core/robject.h
+generator.o: $(hdrdir)/ruby/internal/core/rregexp.h
+generator.o: $(hdrdir)/ruby/internal/core/rstring.h
+generator.o: $(hdrdir)/ruby/internal/core/rstruct.h
+generator.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+generator.o: $(hdrdir)/ruby/internal/ctype.h
+generator.o: $(hdrdir)/ruby/internal/dllexport.h
+generator.o: $(hdrdir)/ruby/internal/dosish.h
+generator.o: $(hdrdir)/ruby/internal/error.h
+generator.o: $(hdrdir)/ruby/internal/eval.h
+generator.o: $(hdrdir)/ruby/internal/event.h
+generator.o: $(hdrdir)/ruby/internal/fl_type.h
+generator.o: $(hdrdir)/ruby/internal/gc.h
+generator.o: $(hdrdir)/ruby/internal/glob.h
+generator.o: $(hdrdir)/ruby/internal/globals.h
+generator.o: $(hdrdir)/ruby/internal/has/attribute.h
+generator.o: $(hdrdir)/ruby/internal/has/builtin.h
+generator.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+generator.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+generator.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+generator.o: $(hdrdir)/ruby/internal/has/extension.h
+generator.o: $(hdrdir)/ruby/internal/has/feature.h
+generator.o: $(hdrdir)/ruby/internal/has/warning.h
+generator.o: $(hdrdir)/ruby/internal/intern/array.h
+generator.o: $(hdrdir)/ruby/internal/intern/bignum.h
+generator.o: $(hdrdir)/ruby/internal/intern/class.h
+generator.o: $(hdrdir)/ruby/internal/intern/compar.h
+generator.o: $(hdrdir)/ruby/internal/intern/complex.h
+generator.o: $(hdrdir)/ruby/internal/intern/cont.h
+generator.o: $(hdrdir)/ruby/internal/intern/dir.h
+generator.o: $(hdrdir)/ruby/internal/intern/enum.h
+generator.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+generator.o: $(hdrdir)/ruby/internal/intern/error.h
+generator.o: $(hdrdir)/ruby/internal/intern/eval.h
+generator.o: $(hdrdir)/ruby/internal/intern/file.h
+generator.o: $(hdrdir)/ruby/internal/intern/gc.h
+generator.o: $(hdrdir)/ruby/internal/intern/hash.h
+generator.o: $(hdrdir)/ruby/internal/intern/io.h
+generator.o: $(hdrdir)/ruby/internal/intern/load.h
+generator.o: $(hdrdir)/ruby/internal/intern/marshal.h
+generator.o: $(hdrdir)/ruby/internal/intern/numeric.h
+generator.o: $(hdrdir)/ruby/internal/intern/object.h
+generator.o: $(hdrdir)/ruby/internal/intern/parse.h
+generator.o: $(hdrdir)/ruby/internal/intern/proc.h
+generator.o: $(hdrdir)/ruby/internal/intern/process.h
+generator.o: $(hdrdir)/ruby/internal/intern/random.h
+generator.o: $(hdrdir)/ruby/internal/intern/range.h
+generator.o: $(hdrdir)/ruby/internal/intern/rational.h
+generator.o: $(hdrdir)/ruby/internal/intern/re.h
+generator.o: $(hdrdir)/ruby/internal/intern/ruby.h
+generator.o: $(hdrdir)/ruby/internal/intern/select.h
+generator.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+generator.o: $(hdrdir)/ruby/internal/intern/signal.h
+generator.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+generator.o: $(hdrdir)/ruby/internal/intern/string.h
+generator.o: $(hdrdir)/ruby/internal/intern/struct.h
+generator.o: $(hdrdir)/ruby/internal/intern/thread.h
+generator.o: $(hdrdir)/ruby/internal/intern/time.h
+generator.o: $(hdrdir)/ruby/internal/intern/variable.h
+generator.o: $(hdrdir)/ruby/internal/intern/vm.h
+generator.o: $(hdrdir)/ruby/internal/interpreter.h
+generator.o: $(hdrdir)/ruby/internal/iterator.h
+generator.o: $(hdrdir)/ruby/internal/memory.h
+generator.o: $(hdrdir)/ruby/internal/method.h
+generator.o: $(hdrdir)/ruby/internal/module.h
+generator.o: $(hdrdir)/ruby/internal/newobj.h
+generator.o: $(hdrdir)/ruby/internal/rgengc.h
+generator.o: $(hdrdir)/ruby/internal/scan_args.h
+generator.o: $(hdrdir)/ruby/internal/special_consts.h
+generator.o: $(hdrdir)/ruby/internal/static_assert.h
+generator.o: $(hdrdir)/ruby/internal/stdalign.h
+generator.o: $(hdrdir)/ruby/internal/stdbool.h
+generator.o: $(hdrdir)/ruby/internal/symbol.h
+generator.o: $(hdrdir)/ruby/internal/token_paste.h
+generator.o: $(hdrdir)/ruby/internal/value.h
+generator.o: $(hdrdir)/ruby/internal/value_type.h
+generator.o: $(hdrdir)/ruby/internal/variable.h
+generator.o: $(hdrdir)/ruby/internal/warning_push.h
+generator.o: $(hdrdir)/ruby/internal/xmalloc.h
+generator.o: $(hdrdir)/ruby/assert.h
generator.o: $(hdrdir)/ruby/backward.h
+generator.o: $(hdrdir)/ruby/backward/2/assume.h
+generator.o: $(hdrdir)/ruby/backward/2/attributes.h
+generator.o: $(hdrdir)/ruby/backward/2/bool.h
+generator.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+generator.o: $(hdrdir)/ruby/backward/2/inttypes.h
+generator.o: $(hdrdir)/ruby/backward/2/limits.h
+generator.o: $(hdrdir)/ruby/backward/2/long_long.h
+generator.o: $(hdrdir)/ruby/backward/2/stdalign.h
+generator.o: $(hdrdir)/ruby/backward/2/stdarg.h
generator.o: $(hdrdir)/ruby/defines.h
generator.o: $(hdrdir)/ruby/encoding.h
generator.o: $(hdrdir)/ruby/intern.h
@@ -16,8 +168,7 @@ generator.o: $(hdrdir)/ruby/regex.h
generator.o: $(hdrdir)/ruby/ruby.h
generator.o: $(hdrdir)/ruby/st.h
generator.o: $(hdrdir)/ruby/subst.h
-generator.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h
-generator.o: $(top_srcdir)/include/ruby.h
+generator.o: $(srcdir)/../fbuffer/fbuffer.h
generator.o: generator.c
generator.o: generator.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index 2bf8074562..407c1af4a6 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/generator/generator.c
@@ -15,14 +15,13 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
#endif
mFloat, mString, mString_Extend,
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
- eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE,
- i_SAFE_STATE_PROTOTYPE;
+ eNestingError;
static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
i_pack, i_unpack, i_create_id, i_extend, i_key_p,
i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
- i_buffer_initial_length, i_dup;
+ i_buffer_initial_length, i_dup, i_escape_slash;
/*
* Copyright 2001-2004 Unicode, Inc.
@@ -130,7 +129,7 @@ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16
/* Converts string to a JSON string in FBuffer buffer, where all but the ASCII
* and control characters are JSON escaped. */
-static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
+static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash)
{
const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
const UTF8 *sourceEnd = source + RSTRING_LEN(string);
@@ -180,6 +179,11 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
case '"':
fbuffer_append(buffer, "\\\"", 2);
break;
+ case '/':
+ if(escape_slash) {
+ fbuffer_append(buffer, "\\/", 2);
+ break;
+ }
default:
fbuffer_append_char(buffer, (char)ch);
break;
@@ -229,7 +233,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
* characters required by the JSON standard are JSON escaped. The remaining
* characters (should be UTF8) are just passed through and appended to the
* result. */
-static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
+static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash)
{
const char *ptr = RSTRING_PTR(string), *p;
unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
@@ -237,6 +241,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
int escape_len;
unsigned char c;
char buf[6] = { '\\', 'u' };
+ int ascii_only = rb_enc_str_asciionly_p(string);
for (start = 0, end = 0; end < len;) {
p = ptr + end;
@@ -279,16 +284,25 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
escape = "\\\"";
escape_len = 2;
break;
+ case '/':
+ if(escape_slash) {
+ escape = "\\/";
+ escape_len = 2;
+ break;
+ }
default:
{
- unsigned short clen = trailingBytesForUTF8[c] + 1;
- if (end + clen > len) {
- rb_raise(rb_path2class("JSON::GeneratorError"),
- "partial character in source, but hit end");
- }
- if (!isLegalUTF8((UTF8 *) p, clen)) {
- rb_raise(rb_path2class("JSON::GeneratorError"),
- "source sequence is illegal/malformed utf-8");
+ unsigned short clen = 1;
+ if (!ascii_only) {
+ clen += trailingBytesForUTF8[c];
+ if (end + clen > len) {
+ rb_raise(rb_path2class("JSON::GeneratorError"),
+ "partial character in source, but hit end");
+ }
+ if (!isLegalUTF8((UTF8 *) p, clen)) {
+ rb_raise(rb_path2class("JSON::GeneratorError"),
+ "source sequence is illegal/malformed utf-8");
+ }
}
end += clen;
}
@@ -324,6 +338,76 @@ static char *fstrndup(const char *ptr, unsigned long len) {
*
*/
+/* Explanation of the following: that's the only way to not pollute
+ * standard library's docs with GeneratorMethods::<ClassName> which
+ * are uninformative and take a large place in a list of classes
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Array
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Float
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Hash
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Integer
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Object
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::String
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend
+ * :nodoc:
+ */
+
+/*
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass
+ * :nodoc:
+ */
+
/*
* call-seq: to_json(state = nil)
*
@@ -535,13 +619,18 @@ static size_t State_memsize(const void *ptr)
return size;
}
+#ifndef HAVE_RB_EXT_RACTOR_SAFE
+# undef RUBY_TYPED_FROZEN_SHAREABLE
+# define RUBY_TYPED_FROZEN_SHAREABLE 0
+#endif
+
#ifdef NEW_TYPEDDATA_WRAPPER
static const rb_data_type_t JSON_Generator_State_type = {
"JSON/Generator/State",
{NULL, State_free, State_memsize,},
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY,
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE,
#endif
};
#endif
@@ -642,6 +731,8 @@ static VALUE cState_configure(VALUE self, VALUE opts)
state->allow_nan = RTEST(tmp);
tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
state->ascii_only = RTEST(tmp);
+ tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash));
+ state->escape_slash = RTEST(tmp);
return self;
}
@@ -676,6 +767,7 @@ static VALUE cState_to_h(VALUE self)
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
+ rb_hash_aset(result, ID2SYM(i_escape_slash), state->escape_slash ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
return result;
@@ -692,7 +784,7 @@ static VALUE cState_aref(VALUE self, VALUE name)
if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
return rb_funcall(self, i_send, 1, name);
} else {
- return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
+ return rb_attr_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
}
}
@@ -715,43 +807,83 @@ static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
return Qnil;
}
-static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
+struct hash_foreach_arg {
+ FBuffer *buffer;
+ JSON_Generator_State *state;
+ VALUE Vstate;
+ int iter;
+};
+
+static int
+json_object_i(VALUE key, VALUE val, VALUE _arg)
{
+ struct hash_foreach_arg *arg = (struct hash_foreach_arg *)_arg;
+ FBuffer *buffer = arg->buffer;
+ JSON_Generator_State *state = arg->state;
+ VALUE Vstate = arg->Vstate;
+
char *object_nl = state->object_nl;
long object_nl_len = state->object_nl_len;
char *indent = state->indent;
long indent_len = state->indent_len;
- long max_nesting = state->max_nesting;
char *delim = FBUFFER_PTR(state->object_delim);
long delim_len = FBUFFER_LEN(state->object_delim);
char *delim2 = FBUFFER_PTR(state->object_delim2);
long delim2_len = FBUFFER_LEN(state->object_delim2);
+ long depth = state->depth;
+ int j;
+ VALUE klass, key_to_s;
+
+ if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len);
+ if (object_nl) {
+ fbuffer_append(buffer, object_nl, object_nl_len);
+ }
+ if (indent) {
+ for (j = 0; j < depth; j++) {
+ fbuffer_append(buffer, indent, indent_len);
+ }
+ }
+
+ klass = CLASS_OF(key);
+ if (klass == rb_cString) {
+ key_to_s = key;
+ } else if (klass == rb_cSymbol) {
+ key_to_s = rb_id2str(SYM2ID(key));
+ } else {
+ key_to_s = rb_funcall(key, i_to_s, 0);
+ }
+ Check_Type(key_to_s, T_STRING);
+ generate_json(buffer, Vstate, state, key_to_s);
+ fbuffer_append(buffer, delim2, delim2_len);
+ generate_json(buffer, Vstate, state, val);
+
+ arg->iter++;
+ return ST_CONTINUE;
+}
+
+static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
+{
+ char *object_nl = state->object_nl;
+ long object_nl_len = state->object_nl_len;
+ char *indent = state->indent;
+ long indent_len = state->indent_len;
+ long max_nesting = state->max_nesting;
long depth = ++state->depth;
- int i, j;
- VALUE key, key_to_s, keys;
+ int j;
+ struct hash_foreach_arg arg;
+
if (max_nesting != 0 && depth > max_nesting) {
fbuffer_free(buffer);
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
}
fbuffer_append_char(buffer, '{');
- keys = rb_funcall(obj, i_keys, 0);
- for(i = 0; i < RARRAY_LEN(keys); i++) {
- if (i > 0) fbuffer_append(buffer, delim, delim_len);
- if (object_nl) {
- fbuffer_append(buffer, object_nl, object_nl_len);
- }
- if (indent) {
- for (j = 0; j < depth; j++) {
- fbuffer_append(buffer, indent, indent_len);
- }
- }
- key = rb_ary_entry(keys, i);
- key_to_s = rb_funcall(key, i_to_s, 0);
- Check_Type(key_to_s, T_STRING);
- generate_json(buffer, Vstate, state, key_to_s);
- fbuffer_append(buffer, delim2, delim2_len);
- generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
- }
+
+ arg.buffer = buffer;
+ arg.state = state;
+ arg.Vstate = Vstate;
+ arg.iter = 0;
+ rb_hash_foreach(obj, json_object_i, (VALUE)&arg);
+
depth = --state->depth;
if (object_nl) {
fbuffer_append(buffer, object_nl, object_nl_len);
@@ -802,16 +934,27 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
fbuffer_append_char(buffer, ']');
}
+#ifdef HAVE_RUBY_ENCODING_H
+static int enc_utf8_compatible_p(rb_encoding *enc)
+{
+ if (enc == rb_usascii_encoding()) return 1;
+ if (enc == rb_utf8_encoding()) return 1;
+ return 0;
+}
+#endif
+
static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
{
fbuffer_append_char(buffer, '"');
#ifdef HAVE_RUBY_ENCODING_H
- obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
+ if (!enc_utf8_compatible_p(rb_enc_get(obj))) {
+ obj = rb_str_encode(obj, CEncoding_UTF_8, 0, Qnil);
+ }
#endif
if (state->ascii_only) {
- convert_UTF8_to_JSON_ASCII(buffer, obj);
+ convert_UTF8_to_JSON_ASCII(buffer, obj, state->escape_slash);
} else {
- convert_UTF8_to_JSON(buffer, obj);
+ convert_UTF8_to_JSON(buffer, obj, state->escape_slash);
}
fbuffer_append_char(buffer, '"');
}
@@ -970,6 +1113,8 @@ static VALUE cState_generate(VALUE self, VALUE obj)
* * *allow_nan*: true if NaN, Infinity, and -Infinity should be
* generated, otherwise an exception is thrown, if these values are
* encountered. This options defaults to false.
+ * * *ascii_only*: true if only ASCII characters should be generated. This
+ * option defaults to false.
* * *buffer_initial_length*: sets the initial length of the generator's
* internal buffer.
*/
@@ -1025,10 +1170,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
} else if (rb_obj_is_kind_of(opts, rb_cHash)) {
return rb_funcall(self, i_new, 1, opts);
} else {
- if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
- CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
- }
- return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
+ return rb_class_new_instance(0, NULL, cState);
}
}
@@ -1253,6 +1395,31 @@ static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
}
/*
+ * call-seq: escape_slash
+ *
+ * If this boolean is true, the forward slashes will be escaped in
+ * the json output.
+ */
+static VALUE cState_escape_slash(VALUE self)
+{
+ GET_STATE(self);
+ return state->escape_slash ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq: escape_slash=(depth)
+ *
+ * This sets whether or not the forward slashes will be escaped in
+ * the json output.
+ */
+static VALUE cState_escape_slash_set(VALUE self, VALUE enable)
+{
+ GET_STATE(self);
+ state->escape_slash = RTEST(enable);
+ return Qnil;
+}
+
+/*
* call-seq: allow_nan?
*
* Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
@@ -1267,7 +1434,7 @@ static VALUE cState_allow_nan_p(VALUE self)
/*
* call-seq: ascii_only?
*
- * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
+ * Returns true, if only ASCII characters should be generated. Otherwise
* returns false.
*/
static VALUE cState_ascii_only_p(VALUE self)
@@ -1335,6 +1502,11 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l
*/
void Init_generator(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+#undef rb_intern
rb_require("json/common");
mJSON = rb_define_module("JSON");
@@ -1343,6 +1515,8 @@ void Init_generator(void)
eGeneratorError = rb_path2class("JSON::GeneratorError");
eNestingError = rb_path2class("JSON::NestingError");
+ rb_gc_register_mark_object(eGeneratorError);
+ rb_gc_register_mark_object(eNestingError);
cState = rb_define_class_under(mGenerator, "State", rb_cObject);
rb_define_alloc_func(cState, cState_s_allocate);
@@ -1361,6 +1535,9 @@ void Init_generator(void)
rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
+ rb_define_method(cState, "escape_slash", cState_escape_slash, 0);
+ rb_define_method(cState, "escape_slash?", cState_escape_slash, 0);
+ rb_define_method(cState, "escape_slash=", cState_escape_slash_set, 1);
rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
@@ -1408,7 +1585,6 @@ void Init_generator(void)
mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
- CRegexp_MULTILINE = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
i_to_s = rb_intern("to_s");
i_to_json = rb_intern("to_json");
i_new = rb_intern("new");
@@ -1418,6 +1594,7 @@ void Init_generator(void)
i_object_nl = rb_intern("object_nl");
i_array_nl = rb_intern("array_nl");
i_max_nesting = rb_intern("max_nesting");
+ i_escape_slash = rb_intern("escape_slash");
i_allow_nan = rb_intern("allow_nan");
i_ascii_only = rb_intern("ascii_only");
i_depth = rb_intern("depth");
@@ -1438,6 +1615,4 @@ void Init_generator(void)
i_encoding = rb_intern("encoding");
i_encode = rb_intern("encode");
#endif
- i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
- CJSON_SAFE_STATE_PROTOTYPE = Qnil;
}
diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h
index c367a6209a..3ebd622554 100644
--- a/ext/json/generator/generator.h
+++ b/ext/json/generator/generator.h
@@ -49,8 +49,8 @@ static const UTF32 halfMask = 0x3FFUL;
static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length);
static void unicode_escape(char *buf, UTF16 character);
static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
-static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
-static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string);
+static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash);
+static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash);
static char *fstrndup(const char *ptr, unsigned long len);
/* ruby api and some helpers */
@@ -72,6 +72,7 @@ typedef struct JSON_Generator_StateStruct {
long max_nesting;
char allow_nan;
char ascii_only;
+ char escape_slash;
long depth;
long buffer_initial_length;
} JSON_Generator_State;
@@ -150,6 +151,8 @@ static VALUE cState_allow_nan_p(VALUE self);
static VALUE cState_ascii_only_p(VALUE self);
static VALUE cState_depth(VALUE self);
static VALUE cState_depth_set(VALUE self, VALUE depth);
+static VALUE cState_escape_slash(VALUE self);
+static VALUE cState_escape_slash_set(VALUE self, VALUE depth);
static FBuffer *cState_prepare_buffer(VALUE self);
#ifndef ZALLOC
#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
diff --git a/ext/json/json.gemspec b/ext/json/json.gemspec
index b8f3009a9c..d5f0a4de1d 100644
--- a/ext/json/json.gemspec
+++ b/ext/json/json.gemspec
Binary files differ
diff --git a/ext/json/lib/json.rb b/ext/json/lib/json.rb
index b5a6912415..aeb9774ee9 100644
--- a/ext/json/lib/json.rb
+++ b/ext/json/lib/json.rb
@@ -2,55 +2,575 @@
require 'json/common'
##
-# = JavaScript Object Notation (JSON)
+# = JavaScript \Object Notation (\JSON)
#
-# JSON is a lightweight data-interchange format. It is easy for us
-# humans to read and write. Plus, equally simple for machines to generate or parse.
-# JSON is completely language agnostic, making it the ideal interchange format.
+# \JSON is a lightweight data-interchange format.
#
-# Built on two universally available structures:
-# 1. A collection of name/value pairs. Often referred to as an _object_, hash table, record, struct, keyed list, or associative array.
-# 2. An ordered list of values. More commonly called an _array_, vector, sequence or list.
+# A \JSON value is one of the following:
+# - Double-quoted text: <tt>"foo"</tt>.
+# - Number: +1+, +1.0+, +2.0e2+.
+# - Boolean: +true+, +false+.
+# - Null: +null+.
+# - \Array: an ordered list of values, enclosed by square brackets:
+# ["foo", 1, 1.0, 2.0e2, true, false, null]
#
-# To read more about JSON visit: http://json.org
+# - \Object: a collection of name/value pairs, enclosed by curly braces;
+# each name is double-quoted text;
+# the values may be any \JSON values:
+# {"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}
#
-# == Parsing JSON
+# A \JSON array or object may contain nested arrays, objects, and scalars
+# to any depth:
+# {"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}
+# [{"foo": 0, "bar": 1}, ["baz", 2]]
#
-# To parse a JSON string received by another application or generated within
-# your existing application:
+# == Using \Module \JSON
#
+# To make module \JSON available in your code, begin with:
# require 'json'
#
-# my_hash = JSON.parse('{"hello": "goodbye"}')
-# puts my_hash["hello"] => "goodbye"
+# All examples here assume that this has been done.
#
-# Notice the extra quotes <tt>''</tt> around the hash notation. Ruby expects
-# the argument to be a string and can't convert objects like a hash or array.
+# === Parsing \JSON
#
-# Ruby converts your string into a hash
+# You can parse a \String containing \JSON data using
+# either of two methods:
+# - <tt>JSON.parse(source, opts)</tt>
+# - <tt>JSON.parse!(source, opts)</tt>
#
-# == Generating JSON
+# where
+# - +source+ is a Ruby object.
+# - +opts+ is a \Hash object containing options
+# that control both input allowed and output formatting.
#
-# Creating a JSON string for communication or serialization is
-# just as simple.
+# The difference between the two methods
+# is that JSON.parse! omits some checks
+# and may not be safe for some +source+ data;
+# use it only for data from trusted sources.
+# Use the safer method JSON.parse for less trusted sources.
#
-# require 'json'
+# ==== Parsing \JSON Arrays
#
-# my_hash = {:hello => "goodbye"}
-# puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}"
+# When +source+ is a \JSON array, JSON.parse by default returns a Ruby \Array:
+# json = '["foo", 1, 1.0, 2.0e2, true, false, null]'
+# ruby = JSON.parse(json)
+# ruby # => ["foo", 1, 1.0, 200.0, true, false, nil]
+# ruby.class # => Array
#
-# Or an alternative way:
+# The \JSON array may contain nested arrays, objects, and scalars
+# to any depth:
+# json = '[{"foo": 0, "bar": 1}, ["baz", 2]]'
+# JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]]
#
-# require 'json'
-# puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}"
+# ==== Parsing \JSON \Objects
+#
+# When the source is a \JSON object, JSON.parse by default returns a Ruby \Hash:
+# json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}'
+# ruby = JSON.parse(json)
+# ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil}
+# ruby.class # => Hash
+#
+# The \JSON object may contain nested arrays, objects, and scalars
+# to any depth:
+# json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}'
+# JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}
+#
+# ==== Parsing \JSON Scalars
+#
+# When the source is a \JSON scalar (not an array or object),
+# JSON.parse returns a Ruby scalar.
+#
+# \String:
+# ruby = JSON.parse('"foo"')
+# ruby # => 'foo'
+# ruby.class # => String
+# \Integer:
+# ruby = JSON.parse('1')
+# ruby # => 1
+# ruby.class # => Integer
+# \Float:
+# ruby = JSON.parse('1.0')
+# ruby # => 1.0
+# ruby.class # => Float
+# ruby = JSON.parse('2.0e2')
+# ruby # => 200
+# ruby.class # => Float
+# Boolean:
+# ruby = JSON.parse('true')
+# ruby # => true
+# ruby.class # => TrueClass
+# ruby = JSON.parse('false')
+# ruby # => false
+# ruby.class # => FalseClass
+# Null:
+# ruby = JSON.parse('null')
+# ruby # => nil
+# ruby.class # => NilClass
+#
+# ==== Parsing Options
+#
+# ====== Input Options
+#
+# Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed;
+# defaults to +100+; specify +false+ to disable depth checking.
+#
+# With the default, +false+:
+# source = '[0, [1, [2, [3]]]]'
+# ruby = JSON.parse(source)
+# ruby # => [0, [1, [2, [3]]]]
+# Too deep:
+# # Raises JSON::NestingError (nesting of 2 is too deep):
+# JSON.parse(source, {max_nesting: 1})
+# Bad value:
+# # Raises TypeError (wrong argument type Symbol (expected Fixnum)):
+# JSON.parse(source, {max_nesting: :foo})
+#
+# ---
+#
+# Option +allow_nan+ (boolean) specifies whether to allow
+# NaN, Infinity, and MinusInfinity in +source+;
+# defaults to +false+.
+#
+# With the default, +false+:
+# # Raises JSON::ParserError (225: unexpected token at '[NaN]'):
+# JSON.parse('[NaN]')
+# # Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
+# JSON.parse('[Infinity]')
+# # Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
+# JSON.parse('[-Infinity]')
+# Allow:
+# source = '[NaN, Infinity, -Infinity]'
+# ruby = JSON.parse(source, {allow_nan: true})
+# ruby # => [NaN, Infinity, -Infinity]
+#
+# ====== Output Options
+#
+# Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
+# should be Symbols;
+# defaults to +false+ (use Strings).
+#
+# With the default, +false+:
+# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
+# ruby = JSON.parse(source)
+# ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
+# Use Symbols:
+# ruby = JSON.parse(source, {symbolize_names: true})
+# ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}
+#
+# ---
+#
+# Option +object_class+ (\Class) specifies the Ruby class to be used
+# for each \JSON object;
+# defaults to \Hash.
+#
+# With the default, \Hash:
+# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
+# ruby = JSON.parse(source)
+# ruby.class # => Hash
+# Use class \OpenStruct:
+# ruby = JSON.parse(source, {object_class: OpenStruct})
+# ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>
+#
+# ---
+#
+# Option +array_class+ (\Class) specifies the Ruby class to be used
+# for each \JSON array;
+# defaults to \Array.
+#
+# With the default, \Array:
+# source = '["foo", 1.0, true, false, null]'
+# ruby = JSON.parse(source)
+# ruby.class # => Array
+# Use class \Set:
+# ruby = JSON.parse(source, {array_class: Set})
+# ruby # => #<Set: {"foo", 1.0, true, false, nil}>
+#
+# ---
+#
+# Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing.
+# See {\JSON Additions}[#module-JSON-label-JSON+Additions].
+#
+# === Generating \JSON
+#
+# To generate a Ruby \String containing \JSON data,
+# use method <tt>JSON.generate(source, opts)</tt>, where
+# - +source+ is a Ruby object.
+# - +opts+ is a \Hash object containing options
+# that control both input allowed and output formatting.
+#
+# ==== Generating \JSON from Arrays
+#
+# When the source is a Ruby \Array, JSON.generate returns
+# a \String containing a \JSON array:
+# ruby = [0, 's', :foo]
+# json = JSON.generate(ruby)
+# json # => '[0,"s","foo"]'
+#
+# The Ruby \Array array may contain nested arrays, hashes, and scalars
+# to any depth:
+# ruby = [0, [1, 2], {foo: 3, bar: 4}]
+# json = JSON.generate(ruby)
+# json # => '[0,[1,2],{"foo":3,"bar":4}]'
+#
+# ==== Generating \JSON from Hashes
+#
+# When the source is a Ruby \Hash, JSON.generate returns
+# a \String containing a \JSON object:
+# ruby = {foo: 0, bar: 's', baz: :bat}
+# json = JSON.generate(ruby)
+# json # => '{"foo":0,"bar":"s","baz":"bat"}'
+#
+# The Ruby \Hash array may contain nested arrays, hashes, and scalars
+# to any depth:
+# ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
+# json = JSON.generate(ruby)
+# json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}'
+#
+# ==== Generating \JSON from Other Objects
+#
+# When the source is neither an \Array nor a \Hash,
+# the generated \JSON data depends on the class of the source.
+#
+# When the source is a Ruby \Integer or \Float, JSON.generate returns
+# a \String containing a \JSON number:
+# JSON.generate(42) # => '42'
+# JSON.generate(0.42) # => '0.42'
+#
+# When the source is a Ruby \String, JSON.generate returns
+# a \String containing a \JSON string (with double-quotes):
+# JSON.generate('A string') # => '"A string"'
+#
+# When the source is +true+, +false+ or +nil+, JSON.generate returns
+# a \String containing the corresponding \JSON token:
+# JSON.generate(true) # => 'true'
+# JSON.generate(false) # => 'false'
+# JSON.generate(nil) # => 'null'
+#
+# When the source is none of the above, JSON.generate returns
+# a \String containing a \JSON string representation of the source:
+# JSON.generate(:foo) # => '"foo"'
+# JSON.generate(Complex(0, 0)) # => '"0+0i"'
+# JSON.generate(Dir.new('.')) # => '"#<Dir>"'
+#
+# ==== Generating Options
+#
+# ====== Input Options
#
-# <tt>JSON.generate</tt> only allows objects or arrays to be converted
-# to JSON syntax. <tt>to_json</tt>, however, accepts many Ruby classes
-# even though it acts only as a method for serialization:
+# Option +allow_nan+ (boolean) specifies whether
+# +NaN+, +Infinity+, and <tt>-Infinity</tt> may be generated;
+# defaults to +false+.
#
+# With the default, +false+:
+# # Raises JSON::GeneratorError (920: NaN not allowed in JSON):
+# JSON.generate(JSON::NaN)
+# # Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
+# JSON.generate(JSON::Infinity)
+# # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
+# JSON.generate(JSON::MinusInfinity)
+#
+# Allow:
+# ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
+# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
+#
+# ---
+#
+# Option +max_nesting+ (\Integer) specifies the maximum nesting depth
+# in +obj+; defaults to +100+.
+#
+# With the default, +100+:
+# obj = [[[[[[0]]]]]]
+# JSON.generate(obj) # => '[[[[[[0]]]]]]'
+#
+# Too deep:
+# # Raises JSON::NestingError (nesting of 2 is too deep):
+# JSON.generate(obj, max_nesting: 2)
+#
+# ====== Output Options
+#
+# The default formatting options generate the most compact
+# \JSON data, all on one line and with no whitespace.
+#
+# You can use these formatting options to generate
+# \JSON data in a more open format, using whitespace.
+# See also JSON.pretty_generate.
+#
+# - Option +array_nl+ (\String) specifies a string (usually a newline)
+# to be inserted after each \JSON array; defaults to the empty \String, <tt>''</tt>.
+# - Option +object_nl+ (\String) specifies a string (usually a newline)
+# to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
+# - Option +indent+ (\String) specifies the string (usually spaces) to be
+# used for indentation; defaults to the empty \String, <tt>''</tt>;
+# defaults to the empty \String, <tt>''</tt>;
+# has no effect unless options +array_nl+ or +object_nl+ specify newlines.
+# - Option +space+ (\String) specifies a string (usually a space) to be
+# inserted after the colon in each \JSON object's pair;
+# defaults to the empty \String, <tt>''</tt>.
+# - Option +space_before+ (\String) specifies a string (usually a space) to be
+# inserted before the colon in each \JSON object's pair;
+# defaults to the empty \String, <tt>''</tt>.
+#
+# In this example, +obj+ is used first to generate the shortest
+# \JSON data (no whitespace), then again with all formatting options
+# specified:
+#
+# obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
+# json = JSON.generate(obj)
+# puts 'Compact:', json
+# opts = {
+# array_nl: "\n",
+# object_nl: "\n",
+# indent: ' ',
+# space_before: ' ',
+# space: ' '
+# }
+# puts 'Open:', JSON.generate(obj, opts)
+#
+# Output:
+# Compact:
+# {"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
+# Open:
+# {
+# "foo" : [
+# "bar",
+# "baz"
+# ],
+# "bat" : {
+# "bam" : 0,
+# "bad" : 1
+# }
+# }
+#
+# == \JSON Additions
+#
+# When you "round trip" a non-\String object from Ruby to \JSON and back,
+# you have a new \String, instead of the object you began with:
+# ruby0 = Range.new(0, 2)
+# json = JSON.generate(ruby0)
+# json # => '0..2"'
+# ruby1 = JSON.parse(json)
+# ruby1 # => '0..2'
+# ruby1.class # => String
+#
+# You can use \JSON _additions_ to preserve the original object.
+# The addition is an extension of a ruby class, so that:
+# - \JSON.generate stores more information in the \JSON string.
+# - \JSON.parse, called with option +create_additions+,
+# uses that information to create a proper Ruby object.
+#
+# This example shows a \Range being generated into \JSON
+# and parsed back into Ruby, both without and with
+# the addition for \Range:
+# ruby = Range.new(0, 2)
+# # This passage does not use the addition for Range.
+# json0 = JSON.generate(ruby)
+# ruby0 = JSON.parse(json0)
+# # This passage uses the addition for Range.
+# require 'json/add/range'
+# json1 = JSON.generate(ruby)
+# ruby1 = JSON.parse(json1, create_additions: true)
+# # Make a nice display.
+# display = <<EOT
+# Generated JSON:
+# Without addition: #{json0} (#{json0.class})
+# With addition: #{json1} (#{json1.class})
+# Parsed JSON:
+# Without addition: #{ruby0.inspect} (#{ruby0.class})
+# With addition: #{ruby1.inspect} (#{ruby1.class})
+# EOT
+# puts display
+#
+# This output shows the different results:
+# Generated JSON:
+# Without addition: "0..2" (String)
+# With addition: {"json_class":"Range","a":[0,2,false]} (String)
+# Parsed JSON:
+# Without addition: "0..2" (String)
+# With addition: 0..2 (Range)
+#
+# The \JSON module includes additions for certain classes.
+# You can also craft custom additions.
+# See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions].
+#
+# === Built-in Additions
+#
+# The \JSON module includes additions for certain classes.
+# To use an addition, +require+ its source:
+# - BigDecimal: <tt>require 'json/add/bigdecimal'</tt>
+# - Complex: <tt>require 'json/add/complex'</tt>
+# - Date: <tt>require 'json/add/date'</tt>
+# - DateTime: <tt>require 'json/add/date_time'</tt>
+# - Exception: <tt>require 'json/add/exception'</tt>
+# - OpenStruct: <tt>require 'json/add/ostruct'</tt>
+# - Range: <tt>require 'json/add/range'</tt>
+# - Rational: <tt>require 'json/add/rational'</tt>
+# - Regexp: <tt>require 'json/add/regexp'</tt>
+# - Set: <tt>require 'json/add/set'</tt>
+# - Struct: <tt>require 'json/add/struct'</tt>
+# - Symbol: <tt>require 'json/add/symbol'</tt>
+# - Time: <tt>require 'json/add/time'</tt>
+#
+# To reduce punctuation clutter, the examples below
+# show the generated \JSON via +puts+, rather than the usual +inspect+,
+#
+# \BigDecimal:
+# require 'json/add/bigdecimal'
+# ruby0 = BigDecimal(0) # 0.0
+# json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
+# ruby1 = JSON.parse(json, create_additions: true) # 0.0
+# ruby1.class # => BigDecimal
+#
+# \Complex:
+# require 'json/add/complex'
+# ruby0 = Complex(1+0i) # 1+0i
+# json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
+# ruby1 = JSON.parse(json, create_additions: true) # 1+0i
+# ruby1.class # Complex
+#
+# \Date:
+# require 'json/add/date'
+# ruby0 = Date.today # 2020-05-02
+# json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
+# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
+# ruby1.class # Date
+#
+# \DateTime:
+# require 'json/add/date_time'
+# ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
+# json = JSON.generate(ruby0) # {"json_class":"DateTime","y":2020,"m":5,"d":2,"H":10,"M":38,"S":13,"of":"-5/24","sg":2299161.0}
+# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
+# ruby1.class # DateTime
+#
+# \Exception (and its subclasses including \RuntimeError):
+# require 'json/add/exception'
+# ruby0 = Exception.new('A message') # A message
+# json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
+# ruby1 = JSON.parse(json, create_additions: true) # A message
+# ruby1.class # Exception
+# ruby0 = RuntimeError.new('Another message') # Another message
+# json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
+# ruby1 = JSON.parse(json, create_additions: true) # Another message
+# ruby1.class # RuntimeError
+#
+# \OpenStruct:
+# require 'json/add/ostruct'
+# ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
+# json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
+# ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
+# ruby1.class # OpenStruct
+#
+# \Range:
+# require 'json/add/range'
+# ruby0 = Range.new(0, 2) # 0..2
+# json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
+# ruby1 = JSON.parse(json, create_additions: true) # 0..2
+# ruby1.class # Range
+#
+# \Rational:
+# require 'json/add/rational'
+# ruby0 = Rational(1, 3) # 1/3
+# json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
+# ruby1 = JSON.parse(json, create_additions: true) # 1/3
+# ruby1.class # Rational
+#
+# \Regexp:
+# require 'json/add/regexp'
+# ruby0 = Regexp.new('foo') # (?-mix:foo)
+# json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
+# ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
+# ruby1.class # Regexp
+#
+# \Set:
+# require 'json/add/set'
+# ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
+# json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
+# ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
+# ruby1.class # Set
+#
+# \Struct:
+# require 'json/add/struct'
+# Customer = Struct.new(:name, :address) # Customer
+# ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
+# json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
+# ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
+# ruby1.class # Customer
+ #
+# \Symbol:
+# require 'json/add/symbol'
+# ruby0 = :foo # foo
+# json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
+# ruby1 = JSON.parse(json, create_additions: true) # foo
+# ruby1.class # Symbol
+#
+# \Time:
+# require 'json/add/time'
+# ruby0 = Time.now # 2020-05-02 11:28:26 -0500
+# json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
+# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
+# ruby1.class # Time
+#
+#
+# === Custom \JSON Additions
+#
+# In addition to the \JSON additions provided,
+# you can craft \JSON additions of your own,
+# either for Ruby built-in classes or for user-defined classes.
+#
+# Here's a user-defined class +Foo+:
+# class Foo
+# attr_accessor :bar, :baz
+# def initialize(bar, baz)
+# self.bar = bar
+# self.baz = baz
+# end
+# end
+#
+# Here's the \JSON addition for it:
+# # Extend class Foo with JSON addition.
+# class Foo
+# # Serialize Foo object with its class name and arguments
+# def to_json(*args)
+# {
+# JSON.create_id => self.class.name,
+# 'a' => [ bar, baz ]
+# }.to_json(*args)
+# end
+# # Deserialize JSON string by constructing new Foo object with arguments.
+# def self.json_create(object)
+# new(*object['a'])
+# end
+# end
+#
+# Demonstration:
# require 'json'
+# # This Foo object has no custom addition.
+# foo0 = Foo.new(0, 1)
+# json0 = JSON.generate(foo0)
+# obj0 = JSON.parse(json0)
+# # Lood the custom addition.
+# require_relative 'foo_addition'
+# # This foo has the custom addition.
+# foo1 = Foo.new(0, 1)
+# json1 = JSON.generate(foo1)
+# obj1 = JSON.parse(json1, create_additions: true)
+# # Make a nice display.
+# display = <<EOT
+# Generated JSON:
+# Without custom addition: #{json0} (#{json0.class})
+# With custom addition: #{json1} (#{json1.class})
+# Parsed JSON:
+# Without custom addition: #{obj0.inspect} (#{obj0.class})
+# With custom addition: #{obj1.inspect} (#{obj1.class})
+# EOT
+# puts display
+#
+# Output:
#
-# 1.to_json => "1"
+# Generated JSON:
+# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
+# With custom addition: {"json_class":"Foo","a":[0,1]} (String)
+# Parsed JSON:
+# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
+# With custom addition: #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)
#
module JSON
require 'json/version'
diff --git a/ext/json/lib/json/add/bigdecimal.rb b/ext/json/lib/json/add/bigdecimal.rb
index 539daeeaf5..c8b4f567cb 100644
--- a/ext/json/lib/json/add/bigdecimal.rb
+++ b/ext/json/lib/json/add/bigdecimal.rb
@@ -23,7 +23,7 @@ class BigDecimal
end
# return the JSON value
- def to_json(*)
- as_json.to_json
+ def to_json(*args)
+ as_json.to_json(*args)
end
end
diff --git a/ext/json/lib/json/add/complex.rb b/ext/json/lib/json/add/complex.rb
index 28ef734daf..e63e29fd22 100644
--- a/ext/json/lib/json/add/complex.rb
+++ b/ext/json/lib/json/add/complex.rb
@@ -2,7 +2,6 @@
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
require 'json'
end
-defined?(::Complex) or require 'complex'
class Complex
@@ -23,7 +22,7 @@ class Complex
end
# Stores class name (Complex) along with real value <tt>r</tt> and imaginary value <tt>i</tt> as JSON string
- def to_json(*)
- as_json.to_json
+ def to_json(*args)
+ as_json.to_json(*args)
end
end
diff --git a/ext/json/lib/json/add/ostruct.rb b/ext/json/lib/json/add/ostruct.rb
index e064c85ff4..686cf0025d 100644
--- a/ext/json/lib/json/add/ostruct.rb
+++ b/ext/json/lib/json/add/ostruct.rb
@@ -23,7 +23,7 @@ class OpenStruct
}
end
- # Stores class name (OpenStruct) with this struct's values <tt>v</tt> as a
+ # Stores class name (OpenStruct) with this struct's values <tt>t</tt> as a
# JSON string.
def to_json(*args)
as_json.to_json(*args)
diff --git a/ext/json/lib/json/add/rational.rb b/ext/json/lib/json/add/rational.rb
index 356940b225..f776226046 100644
--- a/ext/json/lib/json/add/rational.rb
+++ b/ext/json/lib/json/add/rational.rb
@@ -2,7 +2,6 @@
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
require 'json'
end
-defined?(::Rational) or require 'rational'
class Rational
# Deserializes JSON string by converting numerator value <tt>n</tt>,
@@ -22,7 +21,7 @@ class Rational
end
# Stores class name (Rational) along with numerator value <tt>n</tt> and denominator value <tt>d</tt> as JSON string
- def to_json(*)
- as_json.to_json
+ def to_json(*args)
+ as_json.to_json(*args)
end
end
diff --git a/ext/json/lib/json/add/regexp.rb b/ext/json/lib/json/add/regexp.rb
index a93866b05a..39d69fede7 100644
--- a/ext/json/lib/json/add/regexp.rb
+++ b/ext/json/lib/json/add/regexp.rb
@@ -24,7 +24,7 @@ class Regexp
# Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt>
# (Regexp or String) as JSON string
- def to_json(*)
- as_json.to_json
+ def to_json(*args)
+ as_json.to_json(*args)
end
end
diff --git a/ext/json/lib/json/add/set.rb b/ext/json/lib/json/add/set.rb
new file mode 100644
index 0000000000..71e2a0ac8b
--- /dev/null
+++ b/ext/json/lib/json/add/set.rb
@@ -0,0 +1,29 @@
+unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
+ require 'json'
+end
+defined?(::Set) or require 'set'
+
+class Set
+ # Import a JSON Marshalled object.
+ #
+ # method used for JSON marshalling support.
+ def self.json_create(object)
+ new object['a']
+ end
+
+ # Marshal the object to JSON.
+ #
+ # method used for JSON marshalling support.
+ def as_json(*)
+ {
+ JSON.create_id => self.class.name,
+ 'a' => to_a,
+ }
+ end
+
+ # return the JSON value
+ def to_json(*args)
+ as_json.to_json(*args)
+ end
+end
+
diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb
index 7cc852916c..ea46896fcc 100644
--- a/ext/json/lib/json/common.rb
+++ b/ext/json/lib/json/common.rb
@@ -4,12 +4,17 @@ require 'json/generic_object'
module JSON
class << self
- # If _object_ is string-like, parse the string and return the parsed
- # result as a Ruby data structure. Otherwise generate a JSON text from the
- # Ruby data structure object and return it.
+ # :call-seq:
+ # JSON[object] -> new_array or new_string
#
- # The _opts_ argument is passed through to generate/parse respectively.
- # See generate and parse for their documentation.
+ # If +object+ is a \String,
+ # calls JSON.parse with +object+ and +opts+ (see method #parse):
+ # json = '[0, 1, null]'
+ # JSON[json]# => [0, 1, nil]
+ #
+ # Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate):
+ # ruby = [0, 1, nil]
+ # JSON[ruby] # => '[0,1,null]'
def [](object, opts = {})
if object.respond_to? :to_str
JSON.parse(object.to_str, opts)
@@ -19,7 +24,8 @@ module JSON
end
# Returns the JSON parser class that is used by JSON. This is either
- # JSON::Ext::Parser or JSON::Pure::Parser.
+ # JSON::Ext::Parser or JSON::Pure::Parser:
+ # JSON.parser # => JSON::Ext::Parser
attr_reader :parser
# Set the JSON parser class _parser_ to be used by JSON.
@@ -65,37 +71,61 @@ module JSON
end
self.state = generator::State
const_set :State, self.state
- const_set :SAFE_STATE_PROTOTYPE, State.new
- const_set :FAST_STATE_PROTOTYPE, State.new(
+ const_set :SAFE_STATE_PROTOTYPE, State.new # for JRuby
+ const_set :FAST_STATE_PROTOTYPE, create_fast_state
+ const_set :PRETTY_STATE_PROTOTYPE, create_pretty_state
+ ensure
+ $VERBOSE = old
+ end
+
+ def create_fast_state
+ State.new(
:indent => '',
:space => '',
:object_nl => "",
:array_nl => "",
:max_nesting => false
)
- const_set :PRETTY_STATE_PROTOTYPE, State.new(
+ end
+
+ def create_pretty_state
+ State.new(
:indent => ' ',
:space => ' ',
:object_nl => "\n",
:array_nl => "\n"
)
- ensure
- $VERBOSE = old
end
# Returns the JSON generator module that is used by JSON. This is
- # either JSON::Ext::Generator or JSON::Pure::Generator.
+ # either JSON::Ext::Generator or JSON::Pure::Generator:
+ # JSON.generator # => JSON::Ext::Generator
attr_reader :generator
- # Returns the JSON generator state class that is used by JSON. This is
- # either JSON::Ext::Generator::State or JSON::Pure::Generator::State.
+ # Sets or Returns the JSON generator state class that is used by JSON. This is
+ # either JSON::Ext::Generator::State or JSON::Pure::Generator::State:
+ # JSON.state # => JSON::Ext::Generator::State
attr_accessor :state
+ end
+
+ DEFAULT_CREATE_ID = 'json_class'.freeze
+ private_constant :DEFAULT_CREATE_ID
+
+ CREATE_ID_TLS_KEY = "JSON.create_id".freeze
+ private_constant :CREATE_ID_TLS_KEY
+
+ # Sets create identifier, which is used to decide if the _json_create_
+ # hook of a class should be called; initial value is +json_class+:
+ # JSON.create_id # => 'json_class'
+ def self.create_id=(new_value)
+ Thread.current[CREATE_ID_TLS_KEY] = new_value.dup.freeze
+ end
- # This is create identifier, which is used to decide if the _json_create_
- # hook of a class should be called. It defaults to 'json_class'.
- attr_accessor :create_id
+ # Returns the current create identifier.
+ # See also JSON.create_id=.
+ def self.create_id
+ Thread.current[CREATE_ID_TLS_KEY] || DEFAULT_CREATE_ID
end
- self.create_id = 'json_class'
NaN = 0.0/0
@@ -126,7 +156,7 @@ module JSON
# This exception is raised if a generator or unparser error occurs.
class GeneratorError < JSONError; end
# For backwards compatibility
- UnparserError = GeneratorError
+ UnparserError = GeneratorError # :nodoc:
# This exception is raised if the required unicode support is missing on the
# system. Usually this means that the iconv library is not installed.
@@ -134,82 +164,140 @@ module JSON
module_function
- # Parse the JSON document _source_ into a Ruby data structure and return it.
- #
- # _opts_ can have the following
- # keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Disable depth checking with :max_nesting => false. It
- # defaults to 100.
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
- # defiance of RFC 7159 to be parsed by the Parser. This option defaults
- # to false.
- # * *symbolize_names*: If set to true, returns symbols for the names
- # (keys) in a JSON object. Otherwise strings are returned. Strings are
- # the default.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matching class and create_id was found. This option
- # defaults to false.
- # * *object_class*: Defaults to Hash
- # * *array_class*: Defaults to Array
+ # :call-seq:
+ # JSON.parse(source, opts) -> object
+ #
+ # Returns the Ruby objects created by parsing the given +source+.
+ #
+ # Argument +source+ contains the \String to be parsed.
+ #
+ # Argument +opts+, if given, contains a \Hash of options for the parsing.
+ # See {Parsing Options}[#module-JSON-label-Parsing+Options].
+ #
+ # ---
+ #
+ # When +source+ is a \JSON array, returns a Ruby \Array:
+ # source = '["foo", 1.0, true, false, null]'
+ # ruby = JSON.parse(source)
+ # ruby # => ["foo", 1.0, true, false, nil]
+ # ruby.class # => Array
+ #
+ # When +source+ is a \JSON object, returns a Ruby \Hash:
+ # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
+ # ruby = JSON.parse(source)
+ # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
+ # ruby.class # => Hash
+ #
+ # For examples of parsing for all \JSON data types, see
+ # {Parsing \JSON}[#module-JSON-label-Parsing+JSON].
+ #
+ # Parses nested JSON objects:
+ # source = <<-EOT
+ # {
+ # "name": "Dave",
+ # "age" :40,
+ # "hats": [
+ # "Cattleman's",
+ # "Panama",
+ # "Tophat"
+ # ]
+ # }
+ # EOT
+ # ruby = JSON.parse(source)
+ # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
+ #
+ # ---
+ #
+ # Raises an exception if +source+ is not valid JSON:
+ # # Raises JSON::ParserError (783: unexpected token at ''):
+ # JSON.parse('')
+ #
def parse(source, opts = {})
- Parser.new(source, opts).parse
+ Parser.new(source, **(opts||{})).parse
end
- # Parse the JSON document _source_ into a Ruby data structure and return it.
- # The bang version of the parse method defaults to the more dangerous values
- # for the _opts_ hash, so be sure only to parse trusted _source_ documents.
- #
- # _opts_ can have the following keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Enable depth checking with :max_nesting => anInteger. The
- # parse! methods defaults to not doing max depth checking: This can be
- # dangerous if someone wants to fill up your stack.
- # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in
- # defiance of RFC 7159 to be parsed by the Parser. This option defaults
- # to true.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matching class and create_id was found. This option
- # defaults to false.
+ # :call-seq:
+ # JSON.parse!(source, opts) -> object
+ #
+ # Calls
+ # parse(source, opts)
+ # with +source+ and possibly modified +opts+.
+ #
+ # Differences from JSON.parse:
+ # - Option +max_nesting+, if not provided, defaults to +false+,
+ # which disables checking for nesting depth.
+ # - Option +allow_nan+, if not provided, defaults to +true+.
def parse!(source, opts = {})
opts = {
:max_nesting => false,
:allow_nan => true
}.merge(opts)
- Parser.new(source, opts).parse
+ Parser.new(source, **(opts||{})).parse
+ end
+
+ # :call-seq:
+ # JSON.load_file(path, opts={}) -> object
+ #
+ # Calls:
+ # parse(File.read(path), opts)
+ #
+ # See method #parse.
+ def load_file(filespec, opts = {})
+ parse(File.read(filespec), opts)
end
- # Generate a JSON document from the Ruby data structure _obj_ and return
- # it. _state_ is * a JSON::State object,
- # * or a Hash like object (responding to to_hash),
- # * an object convertible into a hash by a to_h method,
- # that is used as or to configure a State object.
- #
- # It defaults to a state object, that creates the shortest possible JSON text
- # in one line, checks for circular data structures and doesn't allow NaN,
- # Infinity, and -Infinity.
- #
- # A _state_ hash can have the following keys:
- # * *indent*: a string used to indent levels (default: ''),
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
- # generated, otherwise an exception is thrown if these values are
- # encountered. This options defaults to false.
- # * *max_nesting*: The maximum depth of nesting allowed in the data
- # structures from which JSON is to be generated. Disable depth checking
- # with :max_nesting => false, it defaults to 100.
- #
- # See also the fast_generate for the fastest creation method with the least
- # amount of sanity checks, and the pretty_generate method for some
- # defaults for pretty output.
+ # :call-seq:
+ # JSON.load_file!(path, opts = {})
+ #
+ # Calls:
+ # JSON.parse!(File.read(path, opts))
+ #
+ # See method #parse!
+ def load_file!(filespec, opts = {})
+ parse!(File.read(filespec), opts)
+ end
+
+ # :call-seq:
+ # JSON.generate(obj, opts = nil) -> new_string
+ #
+ # Returns a \String containing the generated \JSON data.
+ #
+ # See also JSON.fast_generate, JSON.pretty_generate.
+ #
+ # Argument +obj+ is the Ruby object to be converted to \JSON.
+ #
+ # Argument +opts+, if given, contains a \Hash of options for the generation.
+ # See {Generating Options}[#module-JSON-label-Generating+Options].
+ #
+ # ---
+ #
+ # When +obj+ is an \Array, returns a \String containing a \JSON array:
+ # obj = ["foo", 1.0, true, false, nil]
+ # json = JSON.generate(obj)
+ # json # => '["foo",1.0,true,false,null]'
+ #
+ # When +obj+ is a \Hash, returns a \String containing a \JSON object:
+ # obj = {foo: 0, bar: 's', baz: :bat}
+ # json = JSON.generate(obj)
+ # json # => '{"foo":0,"bar":"s","baz":"bat"}'
+ #
+ # For examples of generating from other Ruby objects, see
+ # {Generating \JSON from Other Objects}[#module-JSON-label-Generating+JSON+from+Other+Objects].
+ #
+ # ---
+ #
+ # Raises an exception if any formatting option is not a \String.
+ #
+ # Raises an exception if +obj+ contains circular references:
+ # a = []; b = []; a.push(b); b.push(a)
+ # # Raises JSON::NestingError (nesting of 100 is too deep):
+ # JSON.generate(a)
+ #
def generate(obj, opts = nil)
if State === opts
state, opts = opts, nil
else
- state = SAFE_STATE_PROTOTYPE.dup
+ state = State.new
end
if opts
if opts.respond_to? :to_hash
@@ -231,16 +319,24 @@ module JSON
module_function :unparse
# :startdoc:
- # Generate a JSON document from the Ruby data structure _obj_ and return it.
- # This method disables the checks for circles in Ruby objects.
+ # :call-seq:
+ # JSON.fast_generate(obj, opts) -> new_string
+ #
+ # Arguments +obj+ and +opts+ here are the same as
+ # arguments +obj+ and +opts+ in JSON.generate.
+ #
+ # By default, generates \JSON data without checking
+ # for circular references in +obj+ (option +max_nesting+ set to +false+, disabled).
#
- # *WARNING*: Be careful not to pass any Ruby data structures with circles as
- # _obj_ argument because this will cause JSON to go into an infinite loop.
+ # Raises an exception if +obj+ contains circular references:
+ # a = []; b = []; a.push(b); b.push(a)
+ # # Raises SystemStackError (stack level too deep):
+ # JSON.fast_generate(a)
def fast_generate(obj, opts = nil)
if State === opts
state, opts = opts, nil
else
- state = FAST_STATE_PROTOTYPE.dup
+ state = JSON.create_fast_state
end
if opts
if opts.respond_to? :to_hash
@@ -261,17 +357,41 @@ module JSON
module_function :fast_unparse
# :startdoc:
- # Generate a JSON document from the Ruby data structure _obj_ and return it.
- # The returned document is a prettier form of the document returned by
- # #unparse.
+ # :call-seq:
+ # JSON.pretty_generate(obj, opts = nil) -> new_string
+ #
+ # Arguments +obj+ and +opts+ here are the same as
+ # arguments +obj+ and +opts+ in JSON.generate.
+ #
+ # Default options are:
+ # {
+ # indent: ' ', # Two spaces
+ # space: ' ', # One space
+ # array_nl: "\n", # Newline
+ # object_nl: "\n" # Newline
+ # }
+ #
+ # Example:
+ # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
+ # json = JSON.pretty_generate(obj)
+ # puts json
+ # Output:
+ # {
+ # "foo": [
+ # "bar",
+ # "baz"
+ # ],
+ # "bat": {
+ # "bam": 0,
+ # "bad": 1
+ # }
+ # }
#
- # The _opts_ argument can be used to configure the generator. See the
- # generate method for a more detailed explanation.
def pretty_generate(obj, opts = nil)
if State === opts
state, opts = opts, nil
else
- state = PRETTY_STATE_PROTOTYPE.dup
+ state = JSON.create_pretty_state
end
if opts
if opts.respond_to? :to_hash
@@ -293,10 +413,10 @@ module JSON
# :startdoc:
class << self
- # The global default options for the JSON.load method:
- # :max_nesting: false
- # :allow_nan: true
- # :allow_blank: true
+ # Sets or returns default options for the JSON.load method.
+ # Initially:
+ # opts = JSON.load_default_options
+ # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
attr_accessor :load_default_options
end
self.load_default_options = {
@@ -306,20 +426,134 @@ module JSON
:create_additions => true,
}
- # Load a ruby data structure from a JSON _source_ and return it. A source can
- # either be a string-like object, an IO-like object, or an object responding
- # to the read method. If _proc_ was given, it will be called with any nested
- # Ruby object as an argument recursively in depth first order. To modify the
- # default options pass in the optional _options_ argument as well.
+ # :call-seq:
+ # JSON.load(source, proc = nil, options = {}) -> object
+ #
+ # Returns the Ruby objects created by parsing the given +source+.
+ #
+ # - Argument +source+ must be, or be convertible to, a \String:
+ # - If +source+ responds to instance method +to_str+,
+ # <tt>source.to_str</tt> becomes the source.
+ # - If +source+ responds to instance method +to_io+,
+ # <tt>source.to_io.read</tt> becomes the source.
+ # - If +source+ responds to instance method +read+,
+ # <tt>source.read</tt> becomes the source.
+ # - If both of the following are true, source becomes the \String <tt>'null'</tt>:
+ # - Option +allow_blank+ specifies a truthy value.
+ # - The source, as defined above, is +nil+ or the empty \String <tt>''</tt>.
+ # - Otherwise, +source+ remains the source.
+ # - Argument +proc+, if given, must be a \Proc that accepts one argument.
+ # It will be called recursively with each result (depth-first order).
+ # See details below.
+ # BEWARE: This method is meant to serialise data from trusted user input,
+ # like from your own database server or clients under your control, it could
+ # be dangerous to allow untrusted users to pass JSON sources into it.
+ # - Argument +opts+, if given, contains a \Hash of options for the parsing.
+ # See {Parsing Options}[#module-JSON-label-Parsing+Options].
+ # The default options can be changed via method JSON.load_default_options=.
+ #
+ # ---
+ #
+ # When no +proc+ is given, modifies +source+ as above and returns the result of
+ # <tt>parse(source, opts)</tt>; see #parse.
+ #
+ # Source for following examples:
+ # source = <<-EOT
+ # {
+ # "name": "Dave",
+ # "age" :40,
+ # "hats": [
+ # "Cattleman's",
+ # "Panama",
+ # "Tophat"
+ # ]
+ # }
+ # EOT
#
- # BEWARE: This method is meant to serialise data from trusted user input,
- # like from your own database server or clients under your control, it could
- # be dangerous to allow untrusted users to pass JSON sources into it. The
- # default options for the parser can be changed via the load_default_options
- # method.
+ # Load a \String:
+ # ruby = JSON.load(source)
+ # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
+ #
+ # Load an \IO object:
+ # require 'stringio'
+ # object = JSON.load(StringIO.new(source))
+ # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
+ #
+ # Load a \File object:
+ # path = 't.json'
+ # File.write(path, source)
+ # File.open(path) do |file|
+ # JSON.load(file)
+ # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
+ #
+ # ---
+ #
+ # When +proc+ is given:
+ # - Modifies +source+ as above.
+ # - Gets the +result+ from calling <tt>parse(source, opts)</tt>.
+ # - Recursively calls <tt>proc(result)</tt>.
+ # - Returns the final result.
+ #
+ # Example:
+ # require 'json'
+ #
+ # # Some classes for the example.
+ # class Base
+ # def initialize(attributes)
+ # @attributes = attributes
+ # end
+ # end
+ # class User < Base; end
+ # class Account < Base; end
+ # class Admin < Base; end
+ # # The JSON source.
+ # json = <<-EOF
+ # {
+ # "users": [
+ # {"type": "User", "username": "jane", "email": "jane@example.com"},
+ # {"type": "User", "username": "john", "email": "john@example.com"}
+ # ],
+ # "accounts": [
+ # {"account": {"type": "Account", "paid": true, "account_id": "1234"}},
+ # {"account": {"type": "Account", "paid": false, "account_id": "1235"}}
+ # ],
+ # "admins": {"type": "Admin", "password": "0wn3d"}
+ # }
+ # EOF
+ # # Deserializer method.
+ # def deserialize_obj(obj, safe_types = %w(User Account Admin))
+ # type = obj.is_a?(Hash) && obj["type"]
+ # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
+ # end
+ # # Call to JSON.load
+ # ruby = JSON.load(json, proc {|obj|
+ # case obj
+ # when Hash
+ # obj.each {|k, v| obj[k] = deserialize_obj v }
+ # when Array
+ # obj.map! {|v| deserialize_obj v }
+ # end
+ # })
+ # pp ruby
+ # Output:
+ # {"users"=>
+ # [#<User:0x00000000064c4c98
+ # @attributes=
+ # {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
+ # #<User:0x00000000064c4bd0
+ # @attributes=
+ # {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
+ # "accounts"=>
+ # [{"account"=>
+ # #<Account:0x00000000064c4928
+ # @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
+ # {"account"=>
+ # #<Account:0x00000000064c4680
+ # @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
+ # "admins"=>
+ # #<Admin:0x00000000064c41f8
+ # @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
#
- # This method is part of the implementation of the load/dump interface of
- # Marshal and YAML.
def load(source, proc = nil, options = {})
opts = load_default_options.merge options
if source.respond_to? :to_str
@@ -338,7 +572,7 @@ module JSON
end
# Recursively calls passed _Proc_ if the parsed data structure is an _Array_ or _Hash_
- def recurse_proc(result, &proc)
+ def recurse_proc(result, &proc) # :nodoc:
case result
when Array
result.each { |x| recurse_proc x, &proc }
@@ -355,32 +589,45 @@ module JSON
module_function :restore
class << self
- # The global default options for the JSON.dump method:
- # :max_nesting: false
- # :allow_nan: true
- # :allow_blank: true
+ # Sets or returns the default options for the JSON.dump method.
+ # Initially:
+ # opts = JSON.dump_default_options
+ # opts # => {:max_nesting=>false, :allow_nan=>true, :escape_slash=>false}
attr_accessor :dump_default_options
end
self.dump_default_options = {
:max_nesting => false,
:allow_nan => true,
+ :escape_slash => false,
}
- # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns
- # the result.
+ # :call-seq:
+ # JSON.dump(obj, io = nil, limit = nil)
+ #
+ # Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result.
+ #
+ # The default options can be changed via method JSON.dump_default_options.
#
- # If anIO (an IO-like object or an object that responds to the write method)
- # was given, the resulting JSON is written to it.
+ # - Argument +io+, if given, should respond to method +write+;
+ # the \JSON \String is written to +io+, and +io+ is returned.
+ # If +io+ is not given, the \JSON \String is returned.
+ # - Argument +limit+, if given, is passed to JSON.generate as option +max_nesting+.
#
- # If the number of nested arrays or objects exceeds _limit_, an ArgumentError
- # exception is raised. This argument is similar (but not exactly the
- # same!) to the _limit_ argument in Marshal.dump.
+ # ---
#
- # The default options for the generator can be changed via the
- # dump_default_options method.
+ # When argument +io+ is not given, returns the \JSON \String generated from +obj+:
+ # obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
+ # json = JSON.dump(obj)
+ # json # => "{\"foo\":[0,1],\"bar\":{\"baz\":2,\"bat\":3},\"bam\":\"bad\"}"
#
- # This method is part of the implementation of the load/dump interface of
- # Marshal and YAML.
+ # When argument +io+ is given, writes the \JSON \String to +io+ and returns +io+:
+ # path = 't.json'
+ # File.open(path, 'w') do |file|
+ # JSON.dump(obj, file)
+ # end # => #<File:t.json (closed)>
+ # puts File.read(path)
+ # Output:
+ # {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
def dump(obj, anIO = nil, limit = nil)
if anIO and limit.nil?
anIO = anIO.to_io if anIO.respond_to?(:to_io)
@@ -402,7 +649,7 @@ module JSON
raise ArgumentError, "exceed depth limit"
end
- # Encodes string using Ruby's _String.encode_
+ # Encodes string using String.encode.
def self.iconv(to, from, string)
string.encode(to, from)
end
diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb
index b65ed87f98..7a72272bd0 100644
--- a/ext/json/lib/json/version.rb
+++ b/ext/json/lib/json/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module JSON
# JSON version
- VERSION = '2.1.0'
+ VERSION = '2.5.1'
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
diff --git a/ext/json/parser/depend b/ext/json/parser/depend
index 2ffd904475..23d704ac85 100644
--- a/ext/json/parser/depend
+++ b/ext/json/parser/depend
@@ -4,7 +4,158 @@ parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h
# AUTOGENERATED DEPENDENCIES START
parser.o: $(RUBY_EXTCONF_H)
parser.o: $(arch_hdrdir)/ruby/config.h
+parser.o: $(hdrdir)/ruby.h
+parser.o: $(hdrdir)/ruby/internal/anyargs.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+parser.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+parser.o: $(hdrdir)/ruby/internal/assume.h
+parser.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+parser.o: $(hdrdir)/ruby/internal/attr/artificial.h
+parser.o: $(hdrdir)/ruby/internal/attr/cold.h
+parser.o: $(hdrdir)/ruby/internal/attr/const.h
+parser.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+parser.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+parser.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+parser.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+parser.o: $(hdrdir)/ruby/internal/attr/error.h
+parser.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+parser.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+parser.o: $(hdrdir)/ruby/internal/attr/format.h
+parser.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+parser.o: $(hdrdir)/ruby/internal/attr/noalias.h
+parser.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+parser.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+parser.o: $(hdrdir)/ruby/internal/attr/noinline.h
+parser.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+parser.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+parser.o: $(hdrdir)/ruby/internal/attr/pure.h
+parser.o: $(hdrdir)/ruby/internal/attr/restrict.h
+parser.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+parser.o: $(hdrdir)/ruby/internal/attr/warning.h
+parser.o: $(hdrdir)/ruby/internal/attr/weakref.h
+parser.o: $(hdrdir)/ruby/internal/cast.h
+parser.o: $(hdrdir)/ruby/internal/compiler_is.h
+parser.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+parser.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+parser.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+parser.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+parser.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+parser.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+parser.o: $(hdrdir)/ruby/internal/compiler_since.h
+parser.o: $(hdrdir)/ruby/internal/config.h
+parser.o: $(hdrdir)/ruby/internal/constant_p.h
+parser.o: $(hdrdir)/ruby/internal/core.h
+parser.o: $(hdrdir)/ruby/internal/core/rarray.h
+parser.o: $(hdrdir)/ruby/internal/core/rbasic.h
+parser.o: $(hdrdir)/ruby/internal/core/rbignum.h
+parser.o: $(hdrdir)/ruby/internal/core/rclass.h
+parser.o: $(hdrdir)/ruby/internal/core/rdata.h
+parser.o: $(hdrdir)/ruby/internal/core/rfile.h
+parser.o: $(hdrdir)/ruby/internal/core/rhash.h
+parser.o: $(hdrdir)/ruby/internal/core/robject.h
+parser.o: $(hdrdir)/ruby/internal/core/rregexp.h
+parser.o: $(hdrdir)/ruby/internal/core/rstring.h
+parser.o: $(hdrdir)/ruby/internal/core/rstruct.h
+parser.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+parser.o: $(hdrdir)/ruby/internal/ctype.h
+parser.o: $(hdrdir)/ruby/internal/dllexport.h
+parser.o: $(hdrdir)/ruby/internal/dosish.h
+parser.o: $(hdrdir)/ruby/internal/error.h
+parser.o: $(hdrdir)/ruby/internal/eval.h
+parser.o: $(hdrdir)/ruby/internal/event.h
+parser.o: $(hdrdir)/ruby/internal/fl_type.h
+parser.o: $(hdrdir)/ruby/internal/gc.h
+parser.o: $(hdrdir)/ruby/internal/glob.h
+parser.o: $(hdrdir)/ruby/internal/globals.h
+parser.o: $(hdrdir)/ruby/internal/has/attribute.h
+parser.o: $(hdrdir)/ruby/internal/has/builtin.h
+parser.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+parser.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+parser.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+parser.o: $(hdrdir)/ruby/internal/has/extension.h
+parser.o: $(hdrdir)/ruby/internal/has/feature.h
+parser.o: $(hdrdir)/ruby/internal/has/warning.h
+parser.o: $(hdrdir)/ruby/internal/intern/array.h
+parser.o: $(hdrdir)/ruby/internal/intern/bignum.h
+parser.o: $(hdrdir)/ruby/internal/intern/class.h
+parser.o: $(hdrdir)/ruby/internal/intern/compar.h
+parser.o: $(hdrdir)/ruby/internal/intern/complex.h
+parser.o: $(hdrdir)/ruby/internal/intern/cont.h
+parser.o: $(hdrdir)/ruby/internal/intern/dir.h
+parser.o: $(hdrdir)/ruby/internal/intern/enum.h
+parser.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+parser.o: $(hdrdir)/ruby/internal/intern/error.h
+parser.o: $(hdrdir)/ruby/internal/intern/eval.h
+parser.o: $(hdrdir)/ruby/internal/intern/file.h
+parser.o: $(hdrdir)/ruby/internal/intern/gc.h
+parser.o: $(hdrdir)/ruby/internal/intern/hash.h
+parser.o: $(hdrdir)/ruby/internal/intern/io.h
+parser.o: $(hdrdir)/ruby/internal/intern/load.h
+parser.o: $(hdrdir)/ruby/internal/intern/marshal.h
+parser.o: $(hdrdir)/ruby/internal/intern/numeric.h
+parser.o: $(hdrdir)/ruby/internal/intern/object.h
+parser.o: $(hdrdir)/ruby/internal/intern/parse.h
+parser.o: $(hdrdir)/ruby/internal/intern/proc.h
+parser.o: $(hdrdir)/ruby/internal/intern/process.h
+parser.o: $(hdrdir)/ruby/internal/intern/random.h
+parser.o: $(hdrdir)/ruby/internal/intern/range.h
+parser.o: $(hdrdir)/ruby/internal/intern/rational.h
+parser.o: $(hdrdir)/ruby/internal/intern/re.h
+parser.o: $(hdrdir)/ruby/internal/intern/ruby.h
+parser.o: $(hdrdir)/ruby/internal/intern/select.h
+parser.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+parser.o: $(hdrdir)/ruby/internal/intern/signal.h
+parser.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+parser.o: $(hdrdir)/ruby/internal/intern/string.h
+parser.o: $(hdrdir)/ruby/internal/intern/struct.h
+parser.o: $(hdrdir)/ruby/internal/intern/thread.h
+parser.o: $(hdrdir)/ruby/internal/intern/time.h
+parser.o: $(hdrdir)/ruby/internal/intern/variable.h
+parser.o: $(hdrdir)/ruby/internal/intern/vm.h
+parser.o: $(hdrdir)/ruby/internal/interpreter.h
+parser.o: $(hdrdir)/ruby/internal/iterator.h
+parser.o: $(hdrdir)/ruby/internal/memory.h
+parser.o: $(hdrdir)/ruby/internal/method.h
+parser.o: $(hdrdir)/ruby/internal/module.h
+parser.o: $(hdrdir)/ruby/internal/newobj.h
+parser.o: $(hdrdir)/ruby/internal/rgengc.h
+parser.o: $(hdrdir)/ruby/internal/scan_args.h
+parser.o: $(hdrdir)/ruby/internal/special_consts.h
+parser.o: $(hdrdir)/ruby/internal/static_assert.h
+parser.o: $(hdrdir)/ruby/internal/stdalign.h
+parser.o: $(hdrdir)/ruby/internal/stdbool.h
+parser.o: $(hdrdir)/ruby/internal/symbol.h
+parser.o: $(hdrdir)/ruby/internal/token_paste.h
+parser.o: $(hdrdir)/ruby/internal/value.h
+parser.o: $(hdrdir)/ruby/internal/value_type.h
+parser.o: $(hdrdir)/ruby/internal/variable.h
+parser.o: $(hdrdir)/ruby/internal/warning_push.h
+parser.o: $(hdrdir)/ruby/internal/xmalloc.h
+parser.o: $(hdrdir)/ruby/assert.h
parser.o: $(hdrdir)/ruby/backward.h
+parser.o: $(hdrdir)/ruby/backward/2/assume.h
+parser.o: $(hdrdir)/ruby/backward/2/attributes.h
+parser.o: $(hdrdir)/ruby/backward/2/bool.h
+parser.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+parser.o: $(hdrdir)/ruby/backward/2/inttypes.h
+parser.o: $(hdrdir)/ruby/backward/2/limits.h
+parser.o: $(hdrdir)/ruby/backward/2/long_long.h
+parser.o: $(hdrdir)/ruby/backward/2/stdalign.h
+parser.o: $(hdrdir)/ruby/backward/2/stdarg.h
parser.o: $(hdrdir)/ruby/defines.h
parser.o: $(hdrdir)/ruby/encoding.h
parser.o: $(hdrdir)/ruby/intern.h
@@ -14,8 +165,7 @@ parser.o: $(hdrdir)/ruby/oniguruma.h
parser.o: $(hdrdir)/ruby/ruby.h
parser.o: $(hdrdir)/ruby/st.h
parser.o: $(hdrdir)/ruby/subst.h
-parser.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h
-parser.o: $(top_srcdir)/include/ruby.h
+parser.o: $(srcdir)/../fbuffer/fbuffer.h
parser.o: parser.c
parser.o: parser.h
parser.o: parser.rl
diff --git a/ext/json/parser/extconf.rb b/ext/json/parser/extconf.rb
index f7360d46b2..f832b56a61 100644
--- a/ext/json/parser/extconf.rb
+++ b/ext/json/parser/extconf.rb
@@ -3,4 +3,29 @@ require 'mkmf'
have_func("rb_enc_raise", "ruby.h")
+# checking if String#-@ (str_uminus) dedupes... '
+begin
+ a = -(%w(t e s t).join)
+ b = -(%w(t e s t).join)
+ if a.equal?(b)
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
+ else
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
+ end
+rescue NoMethodError
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
+end
+
+# checking if String#-@ (str_uminus) directly interns frozen strings... '
+begin
+ s = rand.to_s.freeze
+ if (-s).equal?(s) && (-s.dup).equal?(s)
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 '
+ else
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
+ end
+rescue NoMethodError
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
+end
+
create_makefile 'json/ext/parser'
diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c
index d2e4eb6686..29b5674d96 100644
--- a/ext/json/parser/parser.c
+++ b/ext/json/parser/parser.c
@@ -1,4 +1,4 @@
-
+/* This file is automatically generated from parser.rl by using ragel */
#line 1 "parser.rl"
#include "../fbuffer/fbuffer.h"
#include "parser.h"
@@ -27,7 +27,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
/* unicode */
-static const char digit_values[256] = {
+static const signed char digit_values[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -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, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -46,7 +46,7 @@ static const char digit_values[256] = {
static UTF32 unescape_unicode(const unsigned char *p)
{
- char b;
+ signed char b;
UTF32 result = 0;
b = digit_values[p[0]];
if (b < 0) return UNI_REPLACEMENT_CHAR;
@@ -96,14 +96,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
i_object_class, i_array_class, i_decimal_class, i_key_p,
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
- i_leftshift, i_new;
+ i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
-#line 125 "parser.rl"
+#line 126 "parser.rl"
-#line 107 "parser.c"
+#line 108 "parser.c"
enum {JSON_object_start = 1};
enum {JSON_object_first_final = 27};
enum {JSON_object_error = 0};
@@ -111,7 +111,7 @@ enum {JSON_object_error = 0};
enum {JSON_object_en_main = 1};
-#line 166 "parser.rl"
+#line 168 "parser.rl"
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -127,14 +127,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
-#line 131 "parser.c"
+#line 132 "parser.c"
{
cs = JSON_object_start;
}
-#line 181 "parser.rl"
+#line 183 "parser.rl"
-#line 138 "parser.c"
+#line 139 "parser.c"
{
if ( p == pe )
goto _test_eof;
@@ -162,7 +162,7 @@ case 2:
goto st2;
goto st0;
tr2:
-#line 148 "parser.rl"
+#line 150 "parser.rl"
{
char *np;
json->parsing_name = 1;
@@ -175,7 +175,7 @@ st3:
if ( ++p == pe )
goto _test_eof3;
case 3:
-#line 179 "parser.c"
+#line 180 "parser.c"
switch( (*p) ) {
case 13: goto st3;
case 32: goto st3;
@@ -242,7 +242,7 @@ case 8:
goto st8;
goto st0;
tr11:
-#line 133 "parser.rl"
+#line 134 "parser.rl"
{
VALUE v = Qnil;
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
@@ -250,6 +250,7 @@ tr11:
p--; {p++; cs = 9; goto _out;}
} else {
if (NIL_P(json->object_class)) {
+ OBJ_FREEZE(last_name);
rb_hash_aset(*result, last_name, v);
} else {
rb_funcall(*result, i_aset, 2, last_name, v);
@@ -262,7 +263,7 @@ st9:
if ( ++p == pe )
goto _test_eof9;
case 9:
-#line 266 "parser.c"
+#line 268 "parser.c"
switch( (*p) ) {
case 13: goto st9;
case 32: goto st9;
@@ -351,14 +352,14 @@ case 18:
goto st9;
goto st18;
tr4:
-#line 156 "parser.rl"
+#line 158 "parser.rl"
{ p--; {p++; cs = 27; goto _out;} }
goto st27;
st27:
if ( ++p == pe )
goto _test_eof27;
case 27:
-#line 362 "parser.c"
+#line 364 "parser.c"
goto st0;
st19:
if ( ++p == pe )
@@ -456,7 +457,7 @@ case 26:
_out: {}
}
-#line 182 "parser.rl"
+#line 184 "parser.rl"
if (cs >= JSON_object_first_final) {
if (json->create_additions) {
@@ -481,7 +482,7 @@ case 26:
-#line 485 "parser.c"
+#line 487 "parser.c"
enum {JSON_value_start = 1};
enum {JSON_value_first_final = 29};
enum {JSON_value_error = 0};
@@ -489,7 +490,7 @@ enum {JSON_value_error = 0};
enum {JSON_value_en_main = 1};
-#line 282 "parser.rl"
+#line 284 "parser.rl"
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -497,14 +498,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
int cs = EVIL;
-#line 501 "parser.c"
+#line 503 "parser.c"
{
cs = JSON_value_start;
}
-#line 289 "parser.rl"
+#line 291 "parser.rl"
-#line 508 "parser.c"
+#line 510 "parser.c"
{
if ( p == pe )
goto _test_eof;
@@ -538,14 +539,14 @@ st0:
cs = 0;
goto _out;
tr2:
-#line 234 "parser.rl"
+#line 236 "parser.rl"
{
char *np = JSON_parse_string(json, p, pe, result);
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
}
goto st29;
tr3:
-#line 239 "parser.rl"
+#line 241 "parser.rl"
{
char *np;
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
@@ -565,7 +566,7 @@ tr3:
}
goto st29;
tr7:
-#line 257 "parser.rl"
+#line 259 "parser.rl"
{
char *np;
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
@@ -573,7 +574,7 @@ tr7:
}
goto st29;
tr11:
-#line 263 "parser.rl"
+#line 265 "parser.rl"
{
char *np;
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
@@ -581,7 +582,7 @@ tr11:
}
goto st29;
tr25:
-#line 227 "parser.rl"
+#line 229 "parser.rl"
{
if (json->allow_nan) {
*result = CInfinity;
@@ -591,7 +592,7 @@ tr25:
}
goto st29;
tr27:
-#line 220 "parser.rl"
+#line 222 "parser.rl"
{
if (json->allow_nan) {
*result = CNaN;
@@ -601,19 +602,19 @@ tr27:
}
goto st29;
tr31:
-#line 214 "parser.rl"
+#line 216 "parser.rl"
{
*result = Qfalse;
}
goto st29;
tr34:
-#line 211 "parser.rl"
+#line 213 "parser.rl"
{
*result = Qnil;
}
goto st29;
tr37:
-#line 217 "parser.rl"
+#line 219 "parser.rl"
{
*result = Qtrue;
}
@@ -622,9 +623,9 @@ st29:
if ( ++p == pe )
goto _test_eof29;
case 29:
-#line 269 "parser.rl"
+#line 271 "parser.rl"
{ p--; {p++; cs = 29; goto _out;} }
-#line 628 "parser.c"
+#line 630 "parser.c"
switch( (*p) ) {
case 13: goto st29;
case 32: goto st29;
@@ -865,7 +866,11 @@ case 28:
_out: {}
}
-#line 290 "parser.rl"
+#line 292 "parser.rl"
+
+ if (json->freeze) {
+ OBJ_FREEZE(*result);
+ }
if (cs >= JSON_value_first_final) {
return p;
@@ -875,7 +880,7 @@ case 28:
}
-#line 879 "parser.c"
+#line 885 "parser.c"
enum {JSON_integer_start = 1};
enum {JSON_integer_first_final = 3};
enum {JSON_integer_error = 0};
@@ -883,7 +888,7 @@ enum {JSON_integer_error = 0};
enum {JSON_integer_en_main = 1};
-#line 306 "parser.rl"
+#line 312 "parser.rl"
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -891,15 +896,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
int cs = EVIL;
-#line 895 "parser.c"
+#line 901 "parser.c"
{
cs = JSON_integer_start;
}
-#line 313 "parser.rl"
+#line 319 "parser.rl"
json->memo = p;
-#line 903 "parser.c"
+#line 909 "parser.c"
{
if ( p == pe )
goto _test_eof;
@@ -933,14 +938,14 @@ case 3:
goto st0;
goto tr4;
tr4:
-#line 303 "parser.rl"
+#line 309 "parser.rl"
{ p--; {p++; cs = 4; goto _out;} }
goto st4;
st4:
if ( ++p == pe )
goto _test_eof4;
case 4:
-#line 944 "parser.c"
+#line 950 "parser.c"
goto st0;
st5:
if ( ++p == pe )
@@ -959,7 +964,7 @@ case 5:
_out: {}
}
-#line 315 "parser.rl"
+#line 321 "parser.rl"
if (cs >= JSON_integer_first_final) {
long len = p - json->memo;
@@ -974,7 +979,7 @@ case 5:
}
-#line 978 "parser.c"
+#line 984 "parser.c"
enum {JSON_float_start = 1};
enum {JSON_float_first_final = 8};
enum {JSON_float_error = 0};
@@ -982,7 +987,7 @@ enum {JSON_float_error = 0};
enum {JSON_float_en_main = 1};
-#line 340 "parser.rl"
+#line 346 "parser.rl"
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -990,15 +995,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
int cs = EVIL;
-#line 994 "parser.c"
+#line 1013 "parser.c"
{
cs = JSON_float_start;
}
-#line 347 "parser.rl"
+#line 366 "parser.rl"
json->memo = p;
-#line 1002 "parser.c"
+#line 1021 "parser.c"
{
if ( p == pe )
goto _test_eof;
@@ -1056,14 +1061,14 @@ case 8:
goto st0;
goto tr9;
tr9:
-#line 334 "parser.rl"
+#line 340 "parser.rl"
{ p--; {p++; cs = 9; goto _out;} }
goto st9;
st9:
if ( ++p == pe )
goto _test_eof9;
case 9:
-#line 1067 "parser.c"
+#line 1086 "parser.c"
goto st0;
st5:
if ( ++p == pe )
@@ -1124,20 +1129,49 @@ case 7:
_out: {}
}
-#line 349 "parser.rl"
+#line 368 "parser.rl"
if (cs >= JSON_float_first_final) {
+ VALUE mod = Qnil;
+ ID method_id = 0;
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
+ mod = json->decimal_class;
+ method_id = i_try_convert;
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
+ mod = json->decimal_class;
+ method_id = i_new;
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
+ VALUE name = rb_class_name(json->decimal_class);
+ const char *name_cstr = RSTRING_PTR(name);
+ const char *last_colon = strrchr(name_cstr, ':');
+ if (last_colon) {
+ const char *mod_path_end = last_colon - 1;
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
+ mod = rb_path_to_class(mod_path);
+
+ const char *method_name_beg = last_colon + 1;
+ long before_len = method_name_beg - name_cstr;
+ long len = RSTRING_LEN(name) - before_len;
+ VALUE method_name = rb_str_substr(name, before_len, len);
+ method_id = SYM2ID(rb_str_intern(method_name));
+ } else {
+ mod = rb_mKernel;
+ method_id = SYM2ID(rb_str_intern(name));
+ }
+ }
+
long len = p - json->memo;
fbuffer_clear(json->fbuffer);
fbuffer_append(json->fbuffer, json->memo, len);
fbuffer_append_char(json->fbuffer, '\0');
- if (NIL_P(json->decimal_class)) {
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
+
+ if (method_id) {
+ VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
+ *result = rb_funcallv(mod, method_id, 1, &text);
} else {
- VALUE text;
- text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
- *result = rb_funcall(json->decimal_class, i_new, 1, text);
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
}
+
return p + 1;
} else {
return NULL;
@@ -1146,7 +1180,7 @@ case 7:
-#line 1150 "parser.c"
+#line 1173 "parser.c"
enum {JSON_array_start = 1};
enum {JSON_array_first_final = 17};
enum {JSON_array_error = 0};
@@ -1154,7 +1188,7 @@ enum {JSON_array_error = 0};
enum {JSON_array_en_main = 1};
-#line 398 "parser.rl"
+#line 421 "parser.rl"
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -1168,14 +1202,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
-#line 1172 "parser.c"
+#line 1195 "parser.c"
{
cs = JSON_array_start;
}
-#line 411 "parser.rl"
+#line 434 "parser.rl"
-#line 1179 "parser.c"
+#line 1202 "parser.c"
{
if ( p == pe )
goto _test_eof;
@@ -1214,7 +1248,7 @@ case 2:
goto st2;
goto st0;
tr2:
-#line 375 "parser.rl"
+#line 398 "parser.rl"
{
VALUE v = Qnil;
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
@@ -1234,7 +1268,7 @@ st3:
if ( ++p == pe )
goto _test_eof3;
case 3:
-#line 1238 "parser.c"
+#line 1261 "parser.c"
switch( (*p) ) {
case 13: goto st3;
case 32: goto st3;
@@ -1334,14 +1368,14 @@ case 12:
goto st3;
goto st12;
tr4:
-#line 390 "parser.rl"
+#line 413 "parser.rl"
{ p--; {p++; cs = 17; goto _out;} }
goto st17;
st17:
if ( ++p == pe )
goto _test_eof17;
case 17:
-#line 1345 "parser.c"
+#line 1368 "parser.c"
goto st0;
st13:
if ( ++p == pe )
@@ -1397,7 +1431,7 @@ case 16:
_out: {}
}
-#line 412 "parser.rl"
+#line 435 "parser.rl"
if(cs >= JSON_array_first_final) {
return p + 1;
@@ -1486,7 +1520,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
}
-#line 1490 "parser.c"
+#line 1513 "parser.c"
enum {JSON_string_start = 1};
enum {JSON_string_first_final = 8};
enum {JSON_string_error = 0};
@@ -1494,7 +1528,7 @@ enum {JSON_string_error = 0};
enum {JSON_string_en_main = 1};
-#line 519 "parser.rl"
+#line 542 "parser.rl"
static int
@@ -1516,15 +1550,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
*result = rb_str_buf_new(0);
-#line 1520 "parser.c"
+#line 1543 "parser.c"
{
cs = JSON_string_start;
}
-#line 540 "parser.rl"
+#line 563 "parser.rl"
json->memo = p;
-#line 1528 "parser.c"
+#line 1551 "parser.c"
{
if ( p == pe )
goto _test_eof;
@@ -1545,11 +1579,11 @@ case 2:
case 34: goto tr2;
case 92: goto st3;
}
- if ( 0 <= (*p) && (*p) <= 31 )
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
goto st0;
goto st2;
tr2:
-#line 505 "parser.rl"
+#line 528 "parser.rl"
{
*result = json_string_unescape(*result, json->memo + 1, p);
if (NIL_P(*result)) {
@@ -1560,14 +1594,14 @@ tr2:
{p = (( p + 1))-1;}
}
}
-#line 516 "parser.rl"
+#line 539 "parser.rl"
{ p--; {p++; cs = 8; goto _out;} }
goto st8;
st8:
if ( ++p == pe )
goto _test_eof8;
case 8:
-#line 1571 "parser.c"
+#line 1594 "parser.c"
goto st0;
st3:
if ( ++p == pe )
@@ -1575,7 +1609,7 @@ st3:
case 3:
if ( (*p) == 117 )
goto st4;
- if ( 0 <= (*p) && (*p) <= 31 )
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
goto st0;
goto st2;
st4:
@@ -1643,7 +1677,7 @@ case 7:
_out: {}
}
-#line 542 "parser.rl"
+#line 565 "parser.rl"
if (json->create_additions && RTEST(match_string = json->match_string)) {
VALUE klass;
@@ -1658,8 +1692,23 @@ case 7:
if (json->symbolize_names && json->parsing_name) {
*result = rb_str_intern(*result);
- } else {
+ } else if (RB_TYPE_P(*result, T_STRING)) {
+# if STR_UMINUS_DEDUPE_FROZEN
+ if (json->freeze) {
+ // Starting from MRI 2.8 it is preferable to freeze the string
+ // before deduplication so that it can be interned directly
+ // otherwise it would be duplicated first which is wasteful.
+ *result = rb_funcall(rb_str_freeze(*result), i_uminus, 0);
+ }
+# elif STR_UMINUS_DEDUPE
+ if (json->freeze) {
+ // MRI 2.5 and older do not deduplicate strings that are already
+ // frozen.
+ *result = rb_funcall(*result, i_uminus, 0);
+ }
+# else
rb_str_resize(*result, RSTRING_LEN(*result));
+# endif
}
if (cs >= JSON_string_first_final) {
return p + 1;
@@ -1767,6 +1816,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
} else {
json->symbolize_names = 0;
}
+ tmp = ID2SYM(i_freeze);
+ if (option_given_p(opts, tmp)) {
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->freeze = 0;
+ }
tmp = ID2SYM(i_create_additions);
if (option_given_p(opts, tmp)) {
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
@@ -1815,7 +1870,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
} else {
json->max_nesting = 100;
json->allow_nan = 0;
- json->create_additions = 1;
+ json->create_additions = 0;
json->create_id = rb_funcall(mJSON, i_create_id, 0);
json->object_class = Qnil;
json->array_class = Qnil;
@@ -1830,7 +1885,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
}
-#line 1834 "parser.c"
+#line 1878 "parser.c"
enum {JSON_start = 1};
enum {JSON_first_final = 10};
enum {JSON_error = 0};
@@ -1838,7 +1893,7 @@ enum {JSON_error = 0};
enum {JSON_en_main = 1};
-#line 742 "parser.rl"
+#line 786 "parser.rl"
/*
@@ -1855,16 +1910,16 @@ static VALUE cParser_parse(VALUE self)
GET_PARSER;
-#line 1859 "parser.c"
+#line 1903 "parser.c"
{
cs = JSON_start;
}
-#line 758 "parser.rl"
+#line 802 "parser.rl"
p = json->source;
pe = p + json->len;
-#line 1868 "parser.c"
+#line 1912 "parser.c"
{
if ( p == pe )
goto _test_eof;
@@ -1898,7 +1953,7 @@ st0:
cs = 0;
goto _out;
tr2:
-#line 734 "parser.rl"
+#line 778 "parser.rl"
{
char *np = JSON_parse_value(json, p, pe, &result, 0);
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -1908,7 +1963,7 @@ st10:
if ( ++p == pe )
goto _test_eof10;
case 10:
-#line 1912 "parser.c"
+#line 1956 "parser.c"
switch( (*p) ) {
case 13: goto st10;
case 32: goto st10;
@@ -1997,7 +2052,7 @@ case 9:
_out: {}
}
-#line 761 "parser.rl"
+#line 805 "parser.rl"
if (cs >= JSON_first_final && p == pe) {
return result;
@@ -2064,20 +2119,32 @@ static VALUE cParser_source(VALUE self)
void Init_parser(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+#undef rb_intern
rb_require("json/common");
mJSON = rb_define_module("JSON");
mExt = rb_define_module_under(mJSON, "Ext");
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
eParserError = rb_path2class("JSON::ParserError");
eNestingError = rb_path2class("JSON::NestingError");
+ rb_gc_register_mark_object(eParserError);
+ rb_gc_register_mark_object(eNestingError);
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
rb_define_method(cParser, "initialize", cParser_initialize, -1);
rb_define_method(cParser, "parse", cParser_parse, 0);
rb_define_method(cParser, "source", cParser_source, 0);
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
+ rb_gc_register_mark_object(CNaN);
+
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
+ rb_gc_register_mark_object(CInfinity);
+
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
+ rb_gc_register_mark_object(CMinusInfinity);
i_json_creatable_p = rb_intern("json_creatable?");
i_json_create = rb_intern("json_create");
@@ -2098,6 +2165,9 @@ void Init_parser(void)
i_aref = rb_intern("[]");
i_leftshift = rb_intern("<<");
i_new = rb_intern("new");
+ i_try_convert = rb_intern("try_convert");
+ i_freeze = rb_intern("freeze");
+ i_uminus = rb_intern("-@");
}
/*
diff --git a/ext/json/parser/parser.h b/ext/json/parser/parser.h
index e6cf779024..e3eb920cc6 100644
--- a/ext/json/parser/parser.h
+++ b/ext/json/parser/parser.h
@@ -37,6 +37,7 @@ typedef struct JSON_ParserStruct {
int allow_nan;
int parsing_name;
int symbolize_names;
+ int freeze;
VALUE object_class;
VALUE array_class;
VALUE decimal_class;
diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl
index 29900a4a4a..1da70c544c 100644
--- a/ext/json/parser/parser.rl
+++ b/ext/json/parser/parser.rl
@@ -25,7 +25,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
/* unicode */
-static const char digit_values[256] = {
+static const signed char digit_values[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -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, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -44,7 +44,7 @@ static const char digit_values[256] = {
static UTF32 unescape_unicode(const unsigned char *p)
{
- char b;
+ signed char b;
UTF32 result = 0;
b = digit_values[p[0]];
if (b < 0) return UNI_REPLACEMENT_CHAR;
@@ -94,7 +94,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
i_object_class, i_array_class, i_decimal_class, i_key_p,
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
- i_leftshift, i_new;
+ i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
%%{
machine JSON_common;
@@ -137,6 +137,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
fhold; fbreak;
} else {
if (NIL_P(json->object_class)) {
+ OBJ_FREEZE(last_name);
rb_hash_aset(*result, last_name, v);
} else {
rb_funcall(*result, i_aset, 2, last_name, v);
@@ -288,6 +289,10 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
%% write init;
%% write exec;
+ if (json->freeze) {
+ OBJ_FREEZE(*result);
+ }
+
if (cs >= JSON_value_first_final) {
return p;
} else {
@@ -348,17 +353,46 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
%% write exec;
if (cs >= JSON_float_first_final) {
+ VALUE mod = Qnil;
+ ID method_id = 0;
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
+ mod = json->decimal_class;
+ method_id = i_try_convert;
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
+ mod = json->decimal_class;
+ method_id = i_new;
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
+ VALUE name = rb_class_name(json->decimal_class);
+ const char *name_cstr = RSTRING_PTR(name);
+ const char *last_colon = strrchr(name_cstr, ':');
+ if (last_colon) {
+ const char *mod_path_end = last_colon - 1;
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
+ mod = rb_path_to_class(mod_path);
+
+ const char *method_name_beg = last_colon + 1;
+ long before_len = method_name_beg - name_cstr;
+ long len = RSTRING_LEN(name) - before_len;
+ VALUE method_name = rb_str_substr(name, before_len, len);
+ method_id = SYM2ID(rb_str_intern(method_name));
+ } else {
+ mod = rb_mKernel;
+ method_id = SYM2ID(rb_str_intern(name));
+ }
+ }
+
long len = p - json->memo;
fbuffer_clear(json->fbuffer);
fbuffer_append(json->fbuffer, json->memo, len);
fbuffer_append_char(json->fbuffer, '\0');
- if (NIL_P(json->decimal_class)) {
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
+
+ if (method_id) {
+ VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
+ *result = rb_funcallv(mod, method_id, 1, &text);
} else {
- VALUE text;
- text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
- *result = rb_funcall(json->decimal_class, i_new, 1, text);
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
}
+
return p + 1;
} else {
return NULL;
@@ -553,8 +587,23 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
if (json->symbolize_names && json->parsing_name) {
*result = rb_str_intern(*result);
- } else {
+ } else if (RB_TYPE_P(*result, T_STRING)) {
+# if STR_UMINUS_DEDUPE_FROZEN
+ if (json->freeze) {
+ // Starting from MRI 2.8 it is preferable to freeze the string
+ // before deduplication so that it can be interned directly
+ // otherwise it would be duplicated first which is wasteful.
+ *result = rb_funcall(rb_str_freeze(*result), i_uminus, 0);
+ }
+# elif STR_UMINUS_DEDUPE
+ if (json->freeze) {
+ // MRI 2.5 and older do not deduplicate strings that are already
+ // frozen.
+ *result = rb_funcall(*result, i_uminus, 0);
+ }
+# else
rb_str_resize(*result, RSTRING_LEN(*result));
+# endif
}
if (cs >= JSON_string_first_final) {
return p + 1;
@@ -662,6 +711,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
} else {
json->symbolize_names = 0;
}
+ tmp = ID2SYM(i_freeze);
+ if (option_given_p(opts, tmp)) {
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->freeze = 0;
+ }
tmp = ID2SYM(i_create_additions);
if (option_given_p(opts, tmp)) {
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
@@ -710,7 +765,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
} else {
json->max_nesting = 100;
json->allow_nan = 0;
- json->create_additions = 1;
+ json->create_additions = 0;
json->create_id = rb_funcall(mJSON, i_create_id, 0);
json->object_class = Qnil;
json->array_class = Qnil;
@@ -824,20 +879,32 @@ static VALUE cParser_source(VALUE self)
void Init_parser(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+#undef rb_intern
rb_require("json/common");
mJSON = rb_define_module("JSON");
mExt = rb_define_module_under(mJSON, "Ext");
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
eParserError = rb_path2class("JSON::ParserError");
eNestingError = rb_path2class("JSON::NestingError");
+ rb_gc_register_mark_object(eParserError);
+ rb_gc_register_mark_object(eNestingError);
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
rb_define_method(cParser, "initialize", cParser_initialize, -1);
rb_define_method(cParser, "parse", cParser_parse, 0);
rb_define_method(cParser, "source", cParser_source, 0);
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
+ rb_gc_register_mark_object(CNaN);
+
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
+ rb_gc_register_mark_object(CInfinity);
+
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
+ rb_gc_register_mark_object(CMinusInfinity);
i_json_creatable_p = rb_intern("json_creatable?");
i_json_create = rb_intern("json_create");
@@ -858,6 +925,9 @@ void Init_parser(void)
i_aref = rb_intern("[]");
i_leftshift = rb_intern("<<");
i_new = rb_intern("new");
+ i_try_convert = rb_intern("try_convert");
+ i_freeze = rb_intern("freeze");
+ i_uminus = rb_intern("-@");
}
/*
diff --git a/ext/json/parser/prereq.mk b/ext/json/parser/prereq.mk
index be7bcb4319..9111431ab8 100644
--- a/ext/json/parser/prereq.mk
+++ b/ext/json/parser/prereq.mk
@@ -5,6 +5,8 @@ RAGEL = ragel
.rl.c:
$(RAGEL) -G2 $<
$(BASERUBY) -pli -e '$$_.sub!(/[ \t]+$$/, "")' \
- -e '$$_.sub!(/^static const int (JSON_.*=.*);$$/, "enum {\\1};")' $@
+ -e '$$_.sub!(/^static const int (JSON_.*=.*);$$/, "enum {\\1};")' \
+ -e '$$_.sub!(/0 <= \(\*p\) && \(\*p\) <= 31/, "0 <= (signed char)(*p) && (*p) <= 31")' \
+ -e '$$_ = "/* This file is automatically generated from parser.rl by using ragel */" + $$_ if $$. == 1' $@
parser.c:
diff --git a/ext/monitor/depend b/ext/monitor/depend
new file mode 100644
index 0000000000..fe9ec68806
--- /dev/null
+++ b/ext/monitor/depend
@@ -0,0 +1,162 @@
+# AUTOGENERATED DEPENDENCIES START
+monitor.o: $(RUBY_EXTCONF_H)
+monitor.o: $(arch_hdrdir)/ruby/config.h
+monitor.o: $(hdrdir)/ruby/internal/anyargs.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+monitor.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+monitor.o: $(hdrdir)/ruby/internal/assume.h
+monitor.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+monitor.o: $(hdrdir)/ruby/internal/attr/artificial.h
+monitor.o: $(hdrdir)/ruby/internal/attr/cold.h
+monitor.o: $(hdrdir)/ruby/internal/attr/const.h
+monitor.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+monitor.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+monitor.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+monitor.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+monitor.o: $(hdrdir)/ruby/internal/attr/error.h
+monitor.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+monitor.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+monitor.o: $(hdrdir)/ruby/internal/attr/format.h
+monitor.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+monitor.o: $(hdrdir)/ruby/internal/attr/noalias.h
+monitor.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+monitor.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+monitor.o: $(hdrdir)/ruby/internal/attr/noinline.h
+monitor.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+monitor.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+monitor.o: $(hdrdir)/ruby/internal/attr/pure.h
+monitor.o: $(hdrdir)/ruby/internal/attr/restrict.h
+monitor.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+monitor.o: $(hdrdir)/ruby/internal/attr/warning.h
+monitor.o: $(hdrdir)/ruby/internal/attr/weakref.h
+monitor.o: $(hdrdir)/ruby/internal/cast.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_is.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+monitor.o: $(hdrdir)/ruby/internal/compiler_since.h
+monitor.o: $(hdrdir)/ruby/internal/config.h
+monitor.o: $(hdrdir)/ruby/internal/constant_p.h
+monitor.o: $(hdrdir)/ruby/internal/core.h
+monitor.o: $(hdrdir)/ruby/internal/core/rarray.h
+monitor.o: $(hdrdir)/ruby/internal/core/rbasic.h
+monitor.o: $(hdrdir)/ruby/internal/core/rbignum.h
+monitor.o: $(hdrdir)/ruby/internal/core/rclass.h
+monitor.o: $(hdrdir)/ruby/internal/core/rdata.h
+monitor.o: $(hdrdir)/ruby/internal/core/rfile.h
+monitor.o: $(hdrdir)/ruby/internal/core/rhash.h
+monitor.o: $(hdrdir)/ruby/internal/core/robject.h
+monitor.o: $(hdrdir)/ruby/internal/core/rregexp.h
+monitor.o: $(hdrdir)/ruby/internal/core/rstring.h
+monitor.o: $(hdrdir)/ruby/internal/core/rstruct.h
+monitor.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+monitor.o: $(hdrdir)/ruby/internal/ctype.h
+monitor.o: $(hdrdir)/ruby/internal/dllexport.h
+monitor.o: $(hdrdir)/ruby/internal/dosish.h
+monitor.o: $(hdrdir)/ruby/internal/error.h
+monitor.o: $(hdrdir)/ruby/internal/eval.h
+monitor.o: $(hdrdir)/ruby/internal/event.h
+monitor.o: $(hdrdir)/ruby/internal/fl_type.h
+monitor.o: $(hdrdir)/ruby/internal/gc.h
+monitor.o: $(hdrdir)/ruby/internal/glob.h
+monitor.o: $(hdrdir)/ruby/internal/globals.h
+monitor.o: $(hdrdir)/ruby/internal/has/attribute.h
+monitor.o: $(hdrdir)/ruby/internal/has/builtin.h
+monitor.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+monitor.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+monitor.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+monitor.o: $(hdrdir)/ruby/internal/has/extension.h
+monitor.o: $(hdrdir)/ruby/internal/has/feature.h
+monitor.o: $(hdrdir)/ruby/internal/has/warning.h
+monitor.o: $(hdrdir)/ruby/internal/intern/array.h
+monitor.o: $(hdrdir)/ruby/internal/intern/bignum.h
+monitor.o: $(hdrdir)/ruby/internal/intern/class.h
+monitor.o: $(hdrdir)/ruby/internal/intern/compar.h
+monitor.o: $(hdrdir)/ruby/internal/intern/complex.h
+monitor.o: $(hdrdir)/ruby/internal/intern/cont.h
+monitor.o: $(hdrdir)/ruby/internal/intern/dir.h
+monitor.o: $(hdrdir)/ruby/internal/intern/enum.h
+monitor.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+monitor.o: $(hdrdir)/ruby/internal/intern/error.h
+monitor.o: $(hdrdir)/ruby/internal/intern/eval.h
+monitor.o: $(hdrdir)/ruby/internal/intern/file.h
+monitor.o: $(hdrdir)/ruby/internal/intern/gc.h
+monitor.o: $(hdrdir)/ruby/internal/intern/hash.h
+monitor.o: $(hdrdir)/ruby/internal/intern/io.h
+monitor.o: $(hdrdir)/ruby/internal/intern/load.h
+monitor.o: $(hdrdir)/ruby/internal/intern/marshal.h
+monitor.o: $(hdrdir)/ruby/internal/intern/numeric.h
+monitor.o: $(hdrdir)/ruby/internal/intern/object.h
+monitor.o: $(hdrdir)/ruby/internal/intern/parse.h
+monitor.o: $(hdrdir)/ruby/internal/intern/proc.h
+monitor.o: $(hdrdir)/ruby/internal/intern/process.h
+monitor.o: $(hdrdir)/ruby/internal/intern/random.h
+monitor.o: $(hdrdir)/ruby/internal/intern/range.h
+monitor.o: $(hdrdir)/ruby/internal/intern/rational.h
+monitor.o: $(hdrdir)/ruby/internal/intern/re.h
+monitor.o: $(hdrdir)/ruby/internal/intern/ruby.h
+monitor.o: $(hdrdir)/ruby/internal/intern/select.h
+monitor.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+monitor.o: $(hdrdir)/ruby/internal/intern/signal.h
+monitor.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+monitor.o: $(hdrdir)/ruby/internal/intern/string.h
+monitor.o: $(hdrdir)/ruby/internal/intern/struct.h
+monitor.o: $(hdrdir)/ruby/internal/intern/thread.h
+monitor.o: $(hdrdir)/ruby/internal/intern/time.h
+monitor.o: $(hdrdir)/ruby/internal/intern/variable.h
+monitor.o: $(hdrdir)/ruby/internal/intern/vm.h
+monitor.o: $(hdrdir)/ruby/internal/interpreter.h
+monitor.o: $(hdrdir)/ruby/internal/iterator.h
+monitor.o: $(hdrdir)/ruby/internal/memory.h
+monitor.o: $(hdrdir)/ruby/internal/method.h
+monitor.o: $(hdrdir)/ruby/internal/module.h
+monitor.o: $(hdrdir)/ruby/internal/newobj.h
+monitor.o: $(hdrdir)/ruby/internal/rgengc.h
+monitor.o: $(hdrdir)/ruby/internal/scan_args.h
+monitor.o: $(hdrdir)/ruby/internal/special_consts.h
+monitor.o: $(hdrdir)/ruby/internal/static_assert.h
+monitor.o: $(hdrdir)/ruby/internal/stdalign.h
+monitor.o: $(hdrdir)/ruby/internal/stdbool.h
+monitor.o: $(hdrdir)/ruby/internal/symbol.h
+monitor.o: $(hdrdir)/ruby/internal/token_paste.h
+monitor.o: $(hdrdir)/ruby/internal/value.h
+monitor.o: $(hdrdir)/ruby/internal/value_type.h
+monitor.o: $(hdrdir)/ruby/internal/variable.h
+monitor.o: $(hdrdir)/ruby/internal/warning_push.h
+monitor.o: $(hdrdir)/ruby/internal/xmalloc.h
+monitor.o: $(hdrdir)/ruby/assert.h
+monitor.o: $(hdrdir)/ruby/backward.h
+monitor.o: $(hdrdir)/ruby/backward/2/assume.h
+monitor.o: $(hdrdir)/ruby/backward/2/attributes.h
+monitor.o: $(hdrdir)/ruby/backward/2/bool.h
+monitor.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+monitor.o: $(hdrdir)/ruby/backward/2/inttypes.h
+monitor.o: $(hdrdir)/ruby/backward/2/limits.h
+monitor.o: $(hdrdir)/ruby/backward/2/long_long.h
+monitor.o: $(hdrdir)/ruby/backward/2/stdalign.h
+monitor.o: $(hdrdir)/ruby/backward/2/stdarg.h
+monitor.o: $(hdrdir)/ruby/defines.h
+monitor.o: $(hdrdir)/ruby/intern.h
+monitor.o: $(hdrdir)/ruby/missing.h
+monitor.o: $(hdrdir)/ruby/ruby.h
+monitor.o: $(hdrdir)/ruby/st.h
+monitor.o: $(hdrdir)/ruby/subst.h
+monitor.o: monitor.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/monitor/extconf.rb b/ext/monitor/extconf.rb
new file mode 100644
index 0000000000..78c53fa0c5
--- /dev/null
+++ b/ext/monitor/extconf.rb
@@ -0,0 +1,2 @@
+require 'mkmf'
+create_makefile('monitor')
diff --git a/ext/monitor/lib/monitor.rb b/ext/monitor/lib/monitor.rb
new file mode 100644
index 0000000000..11c5ac17d9
--- /dev/null
+++ b/ext/monitor/lib/monitor.rb
@@ -0,0 +1,284 @@
+# frozen_string_literal: false
+# = monitor.rb
+#
+# Copyright (C) 2001 Shugo Maeda <shugo@ruby-lang.org>
+#
+# This library is distributed under the terms of the Ruby license.
+# You can freely distribute/modify this library.
+#
+
+#
+# In concurrent programming, a monitor is an object or module intended to be
+# used safely by more than one thread. The defining characteristic of a
+# monitor is that its methods are executed with mutual exclusion. That is, at
+# each point in time, at most one thread may be executing any of its methods.
+# This mutual exclusion greatly simplifies reasoning about the implementation
+# of monitors compared to reasoning about parallel code that updates a data
+# structure.
+#
+# You can read more about the general principles on the Wikipedia page for
+# Monitors[https://en.wikipedia.org/wiki/Monitor_%28synchronization%29]
+#
+# == Examples
+#
+# === Simple object.extend
+#
+# require 'monitor.rb'
+#
+# buf = []
+# buf.extend(MonitorMixin)
+# empty_cond = buf.new_cond
+#
+# # consumer
+# Thread.start do
+# loop do
+# buf.synchronize do
+# empty_cond.wait_while { buf.empty? }
+# print buf.shift
+# end
+# end
+# end
+#
+# # producer
+# while line = ARGF.gets
+# buf.synchronize do
+# buf.push(line)
+# empty_cond.signal
+# end
+# end
+#
+# The consumer thread waits for the producer thread to push a line to buf
+# while <tt>buf.empty?</tt>. The producer thread (main thread) reads a
+# line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt>
+# to notify the consumer thread of new data.
+#
+# === Simple Class include
+#
+# require 'monitor'
+#
+# class SynchronizedArray < Array
+#
+# include MonitorMixin
+#
+# def initialize(*args)
+# super(*args)
+# end
+#
+# alias :old_shift :shift
+# alias :old_unshift :unshift
+#
+# def shift(n=1)
+# self.synchronize do
+# self.old_shift(n)
+# end
+# end
+#
+# def unshift(item)
+# self.synchronize do
+# self.old_unshift(item)
+# end
+# end
+#
+# # other methods ...
+# end
+#
+# +SynchronizedArray+ implements an Array with synchronized access to items.
+# This Class is implemented as subclass of Array which includes the
+# MonitorMixin module.
+#
+
+require 'monitor.so'
+
+module MonitorMixin
+ #
+ # FIXME: This isn't documented in Nutshell.
+ #
+ # Since MonitorMixin.new_cond returns a ConditionVariable, and the example
+ # above calls while_wait and signal, this class should be documented.
+ #
+ class ConditionVariable
+ #
+ # Releases the lock held in the associated monitor and waits; reacquires the lock on wakeup.
+ #
+ # If +timeout+ is given, this method returns after +timeout+ seconds passed,
+ # even if no other thread doesn't signal.
+ #
+ def wait(timeout = nil)
+ @monitor.mon_check_owner
+ @monitor.wait_for_cond(@cond, timeout)
+ end
+
+ #
+ # Calls wait repeatedly while the given block yields a truthy value.
+ #
+ def wait_while
+ while yield
+ wait
+ end
+ end
+
+ #
+ # Calls wait repeatedly until the given block yields a truthy value.
+ #
+ def wait_until
+ until yield
+ wait
+ end
+ end
+
+ #
+ # Wakes up the first thread in line waiting for this lock.
+ #
+ def signal
+ @monitor.mon_check_owner
+ @cond.signal
+ end
+
+ #
+ # Wakes up all threads waiting for this lock.
+ #
+ def broadcast
+ @monitor.mon_check_owner
+ @cond.broadcast
+ end
+
+ private
+
+ def initialize(monitor)
+ @monitor = monitor
+ @cond = Thread::ConditionVariable.new
+ end
+ end
+
+ def self.extend_object(obj)
+ super(obj)
+ obj.__send__(:mon_initialize)
+ end
+
+ #
+ # Attempts to enter exclusive section. Returns +false+ if lock fails.
+ #
+ def mon_try_enter
+ @mon_data.try_enter
+ end
+ # For backward compatibility
+ alias try_mon_enter mon_try_enter
+
+ #
+ # Enters exclusive section.
+ #
+ def mon_enter
+ @mon_data.enter
+ end
+
+ #
+ # Leaves exclusive section.
+ #
+ def mon_exit
+ mon_check_owner
+ @mon_data.exit
+ end
+
+ #
+ # Returns true if this monitor is locked by any thread
+ #
+ def mon_locked?
+ @mon_data.mon_locked?
+ end
+
+ #
+ # Returns true if this monitor is locked by current thread.
+ #
+ def mon_owned?
+ @mon_data.mon_owned?
+ end
+
+ #
+ # Enters exclusive section and executes the block. Leaves the exclusive
+ # section automatically when the block exits. See example under
+ # +MonitorMixin+.
+ #
+ def mon_synchronize(&b)
+ @mon_data.synchronize(&b)
+ end
+ alias synchronize mon_synchronize
+
+ #
+ # Creates a new MonitorMixin::ConditionVariable associated with the
+ # Monitor object.
+ #
+ def new_cond
+ unless defined?(@mon_data)
+ mon_initialize
+ @mon_initialized_by_new_cond = true
+ end
+ return ConditionVariable.new(@mon_data)
+ end
+
+ private
+
+ # Use <tt>extend MonitorMixin</tt> or <tt>include MonitorMixin</tt> instead
+ # of this constructor. Have look at the examples above to understand how to
+ # use this module.
+ def initialize(...)
+ super
+ mon_initialize
+ end
+
+ # Initializes the MonitorMixin after being included in a class or when an
+ # object has been extended with the MonitorMixin
+ def mon_initialize
+ if defined?(@mon_data)
+ if defined?(@mon_initialized_by_new_cond)
+ return # already initialized.
+ elsif @mon_data_owner_object_id == self.object_id
+ raise ThreadError, "already initialized"
+ end
+ end
+ @mon_data = ::Monitor.new
+ @mon_data_owner_object_id = self.object_id
+ end
+
+ def mon_check_owner
+ @mon_data.mon_check_owner
+ end
+end
+
+# Use the Monitor class when you want to have a lock object for blocks with
+# mutual exclusion.
+#
+# require 'monitor'
+#
+# lock = Monitor.new
+# lock.synchronize do
+# # exclusive access
+# end
+#
+class Monitor
+ def new_cond
+ ::MonitorMixin::ConditionVariable.new(self)
+ end
+
+ # for compatibility
+ alias try_mon_enter try_enter
+ alias mon_try_enter try_enter
+ alias mon_enter enter
+ alias mon_exit exit
+ alias mon_synchronize synchronize
+end
+
+# Documentation comments:
+# - All documentation comes from Nutshell.
+# - MonitorMixin.new_cond appears in the example, but is not documented in
+# Nutshell.
+# - All the internals (internal modules Accessible and Initializable, class
+# ConditionVariable) appear in RDoc. It might be good to hide them, by
+# making them private, or marking them :nodoc:, etc.
+# - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but
+# not synchronize.
+# - mon_owner is in Nutshell, but appears as an accessor in a separate module
+# here, so is hard/impossible to RDoc. Some other useful accessors
+# (mon_count and some queue stuff) are also in this module, and don't appear
+# directly in the RDoc output.
+# - in short, it may be worth changing the code layout in this file to make the
+# documentation easier
diff --git a/ext/monitor/monitor.c b/ext/monitor/monitor.c
new file mode 100644
index 0000000000..a3efe96bb3
--- /dev/null
+++ b/ext/monitor/monitor.c
@@ -0,0 +1,225 @@
+#include "ruby/ruby.h"
+
+/* Thread::Monitor */
+
+struct rb_monitor {
+ long count;
+ const VALUE owner;
+ const VALUE mutex;
+};
+
+static void
+monitor_mark(void *ptr)
+{
+ struct rb_monitor *mc = ptr;
+ rb_gc_mark(mc->owner);
+ rb_gc_mark(mc->mutex);
+}
+
+static size_t
+monitor_memsize(const void *ptr)
+{
+ return sizeof(struct rb_monitor);
+}
+
+static const rb_data_type_t monitor_data_type = {
+ "monitor",
+ {monitor_mark, RUBY_TYPED_DEFAULT_FREE, monitor_memsize,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
+};
+
+static VALUE
+monitor_alloc(VALUE klass)
+{
+ struct rb_monitor *mc;
+ VALUE obj;
+
+ obj = TypedData_Make_Struct(klass, struct rb_monitor, &monitor_data_type, mc);
+ RB_OBJ_WRITE(obj, &mc->mutex, rb_mutex_new());
+ RB_OBJ_WRITE(obj, &mc->owner, Qnil);
+ mc->count = 0;
+
+ return obj;
+}
+
+static struct rb_monitor *
+monitor_ptr(VALUE monitor)
+{
+ struct rb_monitor *mc;
+ TypedData_Get_Struct(monitor, struct rb_monitor, &monitor_data_type, mc);
+ return mc;
+}
+
+static int
+mc_owner_p(struct rb_monitor *mc)
+{
+ return mc->owner == rb_fiber_current();
+}
+
+static VALUE
+monitor_try_enter(VALUE monitor)
+{
+ struct rb_monitor *mc = monitor_ptr(monitor);
+
+ if (!mc_owner_p(mc)) {
+ if (!rb_mutex_trylock(mc->mutex)) {
+ return Qfalse;
+ }
+ RB_OBJ_WRITE(monitor, &mc->owner, rb_fiber_current());
+ mc->count = 0;
+ }
+ mc->count += 1;
+ return Qtrue;
+}
+
+static VALUE
+monitor_enter(VALUE monitor)
+{
+ struct rb_monitor *mc = monitor_ptr(monitor);
+ if (!mc_owner_p(mc)) {
+ rb_mutex_lock(mc->mutex);
+ RB_OBJ_WRITE(monitor, &mc->owner, rb_fiber_current());
+ mc->count = 0;
+ }
+ mc->count++;
+ return Qnil;
+}
+
+static VALUE
+monitor_check_owner(VALUE monitor)
+{
+ struct rb_monitor *mc = monitor_ptr(monitor);
+ if (!mc_owner_p(mc)) {
+ rb_raise(rb_eThreadError, "current fiber not owner");
+ }
+ return Qnil;
+}
+
+static VALUE
+monitor_exit(VALUE monitor)
+{
+ monitor_check_owner(monitor);
+
+ struct rb_monitor *mc = monitor_ptr(monitor);
+
+ if (mc->count <= 0) rb_bug("monitor_exit: count:%d\n", (int)mc->count);
+ mc->count--;
+
+ if (mc->count == 0) {
+ RB_OBJ_WRITE(monitor, &mc->owner, Qnil);
+ rb_mutex_unlock(mc->mutex);
+ }
+ return Qnil;
+}
+
+static VALUE
+monitor_locked_p(VALUE monitor)
+{
+ struct rb_monitor *mc = monitor_ptr(monitor);
+ return rb_mutex_locked_p(mc->mutex);
+}
+
+static VALUE
+monitor_owned_p(VALUE monitor)
+{
+ struct rb_monitor *mc = monitor_ptr(monitor);
+ return (rb_mutex_locked_p(mc->mutex) && mc_owner_p(mc)) ? Qtrue : Qfalse;
+}
+
+static VALUE
+monitor_exit_for_cond(VALUE monitor)
+{
+ struct rb_monitor *mc = monitor_ptr(monitor);
+ long cnt = mc->count;
+ RB_OBJ_WRITE(monitor, &mc->owner, Qnil);
+ mc->count = 0;
+ return LONG2NUM(cnt);
+}
+
+struct wait_for_cond_data {
+ VALUE monitor;
+ VALUE cond;
+ VALUE timeout;
+ VALUE count;
+};
+
+static VALUE
+monitor_wait_for_cond_body(VALUE v)
+{
+ struct wait_for_cond_data *data = (struct wait_for_cond_data *)v;
+ struct rb_monitor *mc = monitor_ptr(data->monitor);
+ // cond.wait(monitor.mutex, timeout)
+ rb_funcall(data->cond, rb_intern("wait"), 2, mc->mutex, data->timeout);
+ return Qtrue;
+}
+
+static VALUE
+monitor_enter_for_cond(VALUE v)
+{
+ // assert(rb_mutex_owned_p(mc->mutex) == Qtrue)
+ // but rb_mutex_owned_p is not exported...
+
+ struct wait_for_cond_data *data = (struct wait_for_cond_data *)v;
+ struct rb_monitor *mc = monitor_ptr(data->monitor);
+ RB_OBJ_WRITE(data->monitor, &mc->owner, rb_fiber_current());
+ mc->count = NUM2LONG(data->count);
+ return Qnil;
+}
+
+static VALUE
+monitor_wait_for_cond(VALUE monitor, VALUE cond, VALUE timeout)
+{
+ VALUE count = monitor_exit_for_cond(monitor);
+ struct wait_for_cond_data data = {
+ monitor,
+ cond,
+ timeout,
+ count,
+ };
+
+ return rb_ensure(monitor_wait_for_cond_body, (VALUE)&data,
+ monitor_enter_for_cond, (VALUE)&data);
+}
+
+static VALUE
+monitor_sync_body(VALUE monitor)
+{
+ return rb_yield_values(0);
+}
+
+static VALUE
+monitor_sync_ensure(VALUE monitor)
+{
+ return monitor_exit(monitor);
+}
+
+static VALUE
+monitor_synchronize(VALUE monitor)
+{
+ monitor_enter(monitor);
+ return rb_ensure(monitor_sync_body, monitor, monitor_sync_ensure, monitor);
+}
+
+void
+Init_monitor(void)
+{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+ VALUE rb_cMonitor = rb_define_class("Monitor", rb_cObject);
+ rb_define_alloc_func(rb_cMonitor, monitor_alloc);
+
+ rb_define_method(rb_cMonitor, "try_enter", monitor_try_enter, 0);
+ rb_define_method(rb_cMonitor, "enter", monitor_enter, 0);
+ rb_define_method(rb_cMonitor, "exit", monitor_exit, 0);
+ rb_define_method(rb_cMonitor, "synchronize", monitor_synchronize, 0);
+
+ /* internal methods for MonitorMixin */
+ rb_define_method(rb_cMonitor, "mon_locked?", monitor_locked_p, 0);
+ rb_define_method(rb_cMonitor, "mon_check_owner", monitor_check_owner, 0);
+ rb_define_method(rb_cMonitor, "mon_owned?", monitor_owned_p, 0);
+
+ /* internal methods for MonitorMixin::ConditionalVariable */
+ rb_define_method(rb_cMonitor, "wait_for_cond", monitor_wait_for_cond, 2);
+}
diff --git a/ext/nkf/depend b/ext/nkf/depend
index 4ea8544a95..caaee22ea4 100644
--- a/ext/nkf/depend
+++ b/ext/nkf/depend
@@ -5,7 +5,157 @@ nkf.o: nkf.c
# AUTOGENERATED DEPENDENCIES START
nkf.o: $(RUBY_EXTCONF_H)
nkf.o: $(arch_hdrdir)/ruby/config.h
+nkf.o: $(hdrdir)/ruby/internal/anyargs.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+nkf.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+nkf.o: $(hdrdir)/ruby/internal/assume.h
+nkf.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+nkf.o: $(hdrdir)/ruby/internal/attr/artificial.h
+nkf.o: $(hdrdir)/ruby/internal/attr/cold.h
+nkf.o: $(hdrdir)/ruby/internal/attr/const.h
+nkf.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+nkf.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+nkf.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+nkf.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+nkf.o: $(hdrdir)/ruby/internal/attr/error.h
+nkf.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+nkf.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+nkf.o: $(hdrdir)/ruby/internal/attr/format.h
+nkf.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+nkf.o: $(hdrdir)/ruby/internal/attr/noalias.h
+nkf.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+nkf.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+nkf.o: $(hdrdir)/ruby/internal/attr/noinline.h
+nkf.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+nkf.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+nkf.o: $(hdrdir)/ruby/internal/attr/pure.h
+nkf.o: $(hdrdir)/ruby/internal/attr/restrict.h
+nkf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+nkf.o: $(hdrdir)/ruby/internal/attr/warning.h
+nkf.o: $(hdrdir)/ruby/internal/attr/weakref.h
+nkf.o: $(hdrdir)/ruby/internal/cast.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_is.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+nkf.o: $(hdrdir)/ruby/internal/compiler_since.h
+nkf.o: $(hdrdir)/ruby/internal/config.h
+nkf.o: $(hdrdir)/ruby/internal/constant_p.h
+nkf.o: $(hdrdir)/ruby/internal/core.h
+nkf.o: $(hdrdir)/ruby/internal/core/rarray.h
+nkf.o: $(hdrdir)/ruby/internal/core/rbasic.h
+nkf.o: $(hdrdir)/ruby/internal/core/rbignum.h
+nkf.o: $(hdrdir)/ruby/internal/core/rclass.h
+nkf.o: $(hdrdir)/ruby/internal/core/rdata.h
+nkf.o: $(hdrdir)/ruby/internal/core/rfile.h
+nkf.o: $(hdrdir)/ruby/internal/core/rhash.h
+nkf.o: $(hdrdir)/ruby/internal/core/robject.h
+nkf.o: $(hdrdir)/ruby/internal/core/rregexp.h
+nkf.o: $(hdrdir)/ruby/internal/core/rstring.h
+nkf.o: $(hdrdir)/ruby/internal/core/rstruct.h
+nkf.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+nkf.o: $(hdrdir)/ruby/internal/ctype.h
+nkf.o: $(hdrdir)/ruby/internal/dllexport.h
+nkf.o: $(hdrdir)/ruby/internal/dosish.h
+nkf.o: $(hdrdir)/ruby/internal/error.h
+nkf.o: $(hdrdir)/ruby/internal/eval.h
+nkf.o: $(hdrdir)/ruby/internal/event.h
+nkf.o: $(hdrdir)/ruby/internal/fl_type.h
+nkf.o: $(hdrdir)/ruby/internal/gc.h
+nkf.o: $(hdrdir)/ruby/internal/glob.h
+nkf.o: $(hdrdir)/ruby/internal/globals.h
+nkf.o: $(hdrdir)/ruby/internal/has/attribute.h
+nkf.o: $(hdrdir)/ruby/internal/has/builtin.h
+nkf.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+nkf.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+nkf.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+nkf.o: $(hdrdir)/ruby/internal/has/extension.h
+nkf.o: $(hdrdir)/ruby/internal/has/feature.h
+nkf.o: $(hdrdir)/ruby/internal/has/warning.h
+nkf.o: $(hdrdir)/ruby/internal/intern/array.h
+nkf.o: $(hdrdir)/ruby/internal/intern/bignum.h
+nkf.o: $(hdrdir)/ruby/internal/intern/class.h
+nkf.o: $(hdrdir)/ruby/internal/intern/compar.h
+nkf.o: $(hdrdir)/ruby/internal/intern/complex.h
+nkf.o: $(hdrdir)/ruby/internal/intern/cont.h
+nkf.o: $(hdrdir)/ruby/internal/intern/dir.h
+nkf.o: $(hdrdir)/ruby/internal/intern/enum.h
+nkf.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+nkf.o: $(hdrdir)/ruby/internal/intern/error.h
+nkf.o: $(hdrdir)/ruby/internal/intern/eval.h
+nkf.o: $(hdrdir)/ruby/internal/intern/file.h
+nkf.o: $(hdrdir)/ruby/internal/intern/gc.h
+nkf.o: $(hdrdir)/ruby/internal/intern/hash.h
+nkf.o: $(hdrdir)/ruby/internal/intern/io.h
+nkf.o: $(hdrdir)/ruby/internal/intern/load.h
+nkf.o: $(hdrdir)/ruby/internal/intern/marshal.h
+nkf.o: $(hdrdir)/ruby/internal/intern/numeric.h
+nkf.o: $(hdrdir)/ruby/internal/intern/object.h
+nkf.o: $(hdrdir)/ruby/internal/intern/parse.h
+nkf.o: $(hdrdir)/ruby/internal/intern/proc.h
+nkf.o: $(hdrdir)/ruby/internal/intern/process.h
+nkf.o: $(hdrdir)/ruby/internal/intern/random.h
+nkf.o: $(hdrdir)/ruby/internal/intern/range.h
+nkf.o: $(hdrdir)/ruby/internal/intern/rational.h
+nkf.o: $(hdrdir)/ruby/internal/intern/re.h
+nkf.o: $(hdrdir)/ruby/internal/intern/ruby.h
+nkf.o: $(hdrdir)/ruby/internal/intern/select.h
+nkf.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+nkf.o: $(hdrdir)/ruby/internal/intern/signal.h
+nkf.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+nkf.o: $(hdrdir)/ruby/internal/intern/string.h
+nkf.o: $(hdrdir)/ruby/internal/intern/struct.h
+nkf.o: $(hdrdir)/ruby/internal/intern/thread.h
+nkf.o: $(hdrdir)/ruby/internal/intern/time.h
+nkf.o: $(hdrdir)/ruby/internal/intern/variable.h
+nkf.o: $(hdrdir)/ruby/internal/intern/vm.h
+nkf.o: $(hdrdir)/ruby/internal/interpreter.h
+nkf.o: $(hdrdir)/ruby/internal/iterator.h
+nkf.o: $(hdrdir)/ruby/internal/memory.h
+nkf.o: $(hdrdir)/ruby/internal/method.h
+nkf.o: $(hdrdir)/ruby/internal/module.h
+nkf.o: $(hdrdir)/ruby/internal/newobj.h
+nkf.o: $(hdrdir)/ruby/internal/rgengc.h
+nkf.o: $(hdrdir)/ruby/internal/scan_args.h
+nkf.o: $(hdrdir)/ruby/internal/special_consts.h
+nkf.o: $(hdrdir)/ruby/internal/static_assert.h
+nkf.o: $(hdrdir)/ruby/internal/stdalign.h
+nkf.o: $(hdrdir)/ruby/internal/stdbool.h
+nkf.o: $(hdrdir)/ruby/internal/symbol.h
+nkf.o: $(hdrdir)/ruby/internal/token_paste.h
+nkf.o: $(hdrdir)/ruby/internal/value.h
+nkf.o: $(hdrdir)/ruby/internal/value_type.h
+nkf.o: $(hdrdir)/ruby/internal/variable.h
+nkf.o: $(hdrdir)/ruby/internal/warning_push.h
+nkf.o: $(hdrdir)/ruby/internal/xmalloc.h
+nkf.o: $(hdrdir)/ruby/assert.h
nkf.o: $(hdrdir)/ruby/backward.h
+nkf.o: $(hdrdir)/ruby/backward/2/assume.h
+nkf.o: $(hdrdir)/ruby/backward/2/attributes.h
+nkf.o: $(hdrdir)/ruby/backward/2/bool.h
+nkf.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+nkf.o: $(hdrdir)/ruby/backward/2/inttypes.h
+nkf.o: $(hdrdir)/ruby/backward/2/limits.h
+nkf.o: $(hdrdir)/ruby/backward/2/long_long.h
+nkf.o: $(hdrdir)/ruby/backward/2/stdalign.h
+nkf.o: $(hdrdir)/ruby/backward/2/stdarg.h
nkf.o: $(hdrdir)/ruby/defines.h
nkf.o: $(hdrdir)/ruby/encoding.h
nkf.o: $(hdrdir)/ruby/intern.h
diff --git a/ext/nkf/nkf-utf8/nkf.c b/ext/nkf/nkf-utf8/nkf.c
index b58c437d3c..cc438a50d6 100644
--- a/ext/nkf/nkf-utf8/nkf.c
+++ b/ext/nkf/nkf-utf8/nkf.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1987, Fujitsu LTD. (Itaru ICHIKAWA).
- * Copyright (c) 1996-2013, The nkf Project.
+ * Copyright (c) 1996-2018, The nkf Project.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -20,11 +20,11 @@
*
* 3. This notice may not be removed or altered from any source distribution.
*/
-#define NKF_VERSION "2.1.4"
-#define NKF_RELEASE_DATE "2015-12-12"
+#define NKF_VERSION "2.1.5"
+#define NKF_RELEASE_DATE "2018-12-15"
#define COPY_RIGHT \
"Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).\n" \
- "Copyright (C) 1996-2015, The nkf Project."
+ "Copyright (C) 1996-2018, The nkf Project."
#include "config.h"
#include "nkf.h"
@@ -1111,18 +1111,26 @@ encode_fallback_java(nkf_char c)
(*oconv)(0, '\\');
c &= VALUE_MASK;
if(!nkf_char_unicode_bmp_p(c)){
- (*oconv)(0, 'U');
- (*oconv)(0, '0');
- (*oconv)(0, '0');
- (*oconv)(0, bin2hex(c>>20));
- (*oconv)(0, bin2hex(c>>16));
+ int high = (c >> 10) + NKF_INT32_C(0xD7C0); /* high surrogate */
+ int low = (c & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */
+ (*oconv)(0, 'u');
+ (*oconv)(0, bin2hex(high>>12));
+ (*oconv)(0, bin2hex(high>> 8));
+ (*oconv)(0, bin2hex(high>> 4));
+ (*oconv)(0, bin2hex(high ));
+ (*oconv)(0, '\\');
+ (*oconv)(0, 'u');
+ (*oconv)(0, bin2hex(low>>12));
+ (*oconv)(0, bin2hex(low>> 8));
+ (*oconv)(0, bin2hex(low>> 4));
+ (*oconv)(0, bin2hex(low ));
}else{
(*oconv)(0, 'u');
+ (*oconv)(0, bin2hex(c>>12));
+ (*oconv)(0, bin2hex(c>> 8));
+ (*oconv)(0, bin2hex(c>> 4));
+ (*oconv)(0, bin2hex(c ));
}
- (*oconv)(0, bin2hex(c>>12));
- (*oconv)(0, bin2hex(c>> 8));
- (*oconv)(0, bin2hex(c>> 4));
- (*oconv)(0, bin2hex(c ));
return;
}
@@ -1947,12 +1955,17 @@ unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_c
ret = unicode_to_jis_common2(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1);
}else return -1;
#ifdef SHIFTJIS_CP932
- if (!ret && !cp932inv_f && is_eucg3(*p2)) {
- nkf_char s2, s1;
- if (e2s_conv(*p2, *p1, &s2, &s1) == 0) {
- s2e_conv(s2, s1, p2, p1);
- }else{
- ret = 1;
+ if (!ret&& is_eucg3(*p2)) {
+ if (cp932inv_f) {
+ if (encode_fallback) ret = 1;
+ }
+ else {
+ nkf_char s2, s1;
+ if (e2s_conv(*p2, *p1, &s2, &s1) == 0) {
+ s2e_conv(s2, s1, p2, p1);
+ }else{
+ ret = 1;
+ }
}
}
#endif
diff --git a/ext/nkf/nkf-utf8/utf8tbl.c b/ext/nkf/nkf-utf8/utf8tbl.c
index 3821c59468..a31e4e7805 100644
--- a/ext/nkf/nkf-utf8/utf8tbl.c
+++ b/ext/nkf/nkf-utf8/utf8tbl.c
@@ -5445,7 +5445,7 @@ static const unsigned short utf8_to_euc_E4BB_x0213[] = {
0xB047, 0x2E28, 0xB049, 0x4265, 0x4E61, 0x304A, 0, 0,
0xB04A, 0, 0, 0xA13B, 0, 0x5041, 0x323E, 0xB04B,
0x3644, 0xA13D, 0x4367, 0xB04D, 0, 0xA13E, 0x376F, 0x5043,
- 0, 0, 0, 0x4724, 0xF42F, 0x2E29, 0xB050, 0x2E2A,
+ 0, 0, 0, 0x4724, 0, 0x2E29, 0xB050, 0x2E2A,
};
static const unsigned short utf8_to_euc_E4BC[] = {
0xB052, 0x346B, 0xB053, 0xB054, 0, 0, 0, 0,
@@ -5465,7 +5465,7 @@ static const unsigned short utf8_to_euc_E4BC_x0213[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0xB05D, 0x476C,
0x5046, 0xB05E, 0, 0xB060, 0x483C, 0xB061, 0x4E62, 0xA142,
- 0x3F2D, 0xB063, 0x3B47, 0xB064, 0x3B77, 0x3240, 0xA143, 0,
+ 0x3F2D, 0, 0x3B47, 0xB064, 0x3B77, 0x3240, 0xA143, 0,
};
static const unsigned short utf8_to_euc_E4BD[] = {
0xB066, 0, 0xB067, 0x4451, 0, 0, 0x4322, 0x504A,
@@ -5519,13 +5519,13 @@ static const unsigned short utf8_to_euc_E4BF[] = {
};
static const unsigned short utf8_to_euc_E4BF_x0213[] = {
0xB136, 0xB137, 0x3738, 0x4225, 0x3264, 0xA152, 0xB139, 0,
- 0xB13A, 0x2E39, 0x3D53, 0xA153, 0xB13D, 0xB13E, 0x5059, 0xA154,
+ 0xB13A, 0x2E39, 0x3D53, 0xA153, 0xB13D, 0, 0x5059, 0xA154,
0x505E, 0x505C, 0xA155, 0, 0x5057, 0, 0, 0x422F,
0x505A, 0, 0x505D, 0x505B, 0xB141, 0x4A5D, 0, 0x5058,
0x2E3A, 0x3F2E, 0xB143, 0x4B73, 0x505F, 0x5060, 0xA14F, 0,
0, 0, 0, 0, 0, 0, 0x3D24, 0x506D,
0xB144, 0x2E21, 0xA157, 0x4750, 0, 0x4936, 0x5068, 0,
- 0x4A70, 0, 0x3236, 0, 0xB146, 0xB147, 0x506C, 0xB148,
+ 0x4A70, 0, 0x3236, 0, 0xB146, 0xB147, 0x506C, 0,
};
static const unsigned short utf8_to_euc_E580[] = {
0xB149, 0xB14A, 0, 0, 0xB14B, 0x5066, 0x506F, 0xB14C,
@@ -5601,10 +5601,10 @@ static const unsigned short utf8_to_euc_E583_x0213[] = {
0xB232, 0, 0x5124, 0xB233, 0xA174, 0x364F, 0, 0xA175,
0, 0x5121, 0x5122, 0, 0x2E45, 0x462F, 0xA178, 0x417C,
0x2E47, 0x3623, 0, 0xB239, 0xA17A, 0x4B4D, 0x5125, 0,
- 0xB23B, 0xA17B, 0x4E3D, 0, 0xB23C, 0xB23D, 0x5126, 0xB23E,
+ 0, 0xA17B, 0x4E3D, 0, 0xB23C, 0xB23D, 0x5126, 0xB23E,
0, 0xA17C, 0xB23F, 0x5129, 0xB240, 0x5127, 0x2E48, 0x414E,
0xB242, 0xA17D, 0, 0, 0, 0x5128, 0x512A, 0xB244,
- 0, 0xB245, 0x2E46, 0xA176, 0xF430, 0x512C, 0xB246, 0,
+ 0, 0xB245, 0x2E46, 0xA176, 0, 0x512C, 0xB246, 0,
0, 0x512B, 0xB247, 0x4A48, 0, 0, 0xB248, 0,
};
static const unsigned short utf8_to_euc_E584[] = {
@@ -5642,7 +5642,7 @@ static const unsigned short utf8_to_euc_E585_x0213[] = {
0x4068, 0x3877, 0x2E4F, 0x396E, 0x513C, 0x4C48, 0x4546, 0xB267,
0x3B79, 0, 0x513B, 0xB268, 0x513D, 0x2E51, 0, 0x2E52,
0xB26B, 0, 0x455E, 0, 0x3375, 0, 0, 0xB26C,
- 0xA326, 0, 0x513E, 0, 0xB26D, 0x467E, 0xB26E, 0,
+ 0xA326, 0, 0x513E, 0, 0, 0x467E, 0xB26E, 0,
0x4134, 0x5140, 0x5141, 0x482C, 0x3878, 0x4F3B, 0x5142, 0,
0, 0x3626, 0, 0xA328, 0, 0x4A3C, 0x4236, 0x3671,
0x4535, 0, 0, 0xF474, 0x3773, 0, 0xB26F, 0,
@@ -5665,7 +5665,7 @@ static const unsigned short utf8_to_euc_E586_x0213[] = {
0x3427, 0xB276, 0x514F, 0xA32D, 0x514D, 0x4C3D, 0x514E, 0,
0x495A, 0x5150, 0x5151, 0x5152, 0x455F, 0xA32E, 0, 0,
0x5156, 0x5154, 0x5155, 0x5153, 0x3A63, 0x5157, 0x4C6A, 0x4E64,
- 0xB279, 0, 0xB27A, 0, 0xA330, 0x5158, 0xB27C, 0xB27D,
+ 0xB279, 0, 0xB27A, 0, 0xA330, 0x5158, 0, 0xB27D,
};
static const unsigned short utf8_to_euc_E587[] = {
0, 0, 0xB27E, 0, 0x4028, 0x5159, 0x3D5A, 0,
@@ -5683,7 +5683,7 @@ static const unsigned short utf8_to_euc_E587_x0213[] = {
0, 0xB323, 0xB324, 0xB325, 0, 0xB326, 0x5245, 0,
0xB327, 0, 0, 0x515B, 0x7425, 0x3645, 0x2E57, 0,
0x515C, 0x4B5E, 0x2E58, 0, 0, 0xB32A, 0x3D68, 0x427C,
- 0, 0x515E, 0x4664, 0, 0xF431, 0x515F, 0x2E59, 0,
+ 0, 0x515E, 0x4664, 0, 0, 0x515F, 0x2E59, 0,
0x5160, 0x332E, 0xB32C, 0xA333, 0xA334, 0x5161, 0x3627, 0xB32F,
0x464C, 0x317A, 0x3D50, 0, 0, 0x4821, 0x5162, 0,
};
@@ -5741,7 +5741,7 @@ static const unsigned short utf8_to_euc_E58A_x0213[] = {
0xB34D, 0, 0xA33E, 0x3344, 0xA33D, 0xB34F, 0, 0x3760,
0x517C, 0x4E2D, 0xB350, 0, 0xB351, 0x5178, 0, 0,
0, 0x517D, 0x517A, 0x2E61, 0x5179, 0xB353, 0xB354, 0xB355,
- 0xA340, 0, 0xB357, 0x4E4F, 0xB358, 0, 0, 0x3879,
+ 0xA340, 0, 0xB357, 0x4E4F, 0, 0, 0, 0x3879,
0x3243, 0, 0, 0x4E74, 0xA342, 0xB35A, 0xA343, 0xB35C,
0, 0x3D75, 0x4558, 0x3965, 0x5222, 0x5223, 0, 0xA344,
0xB35E, 0x4E65, 0, 0, 0x4F2B, 0x5225, 0xB35F, 0xB360,
@@ -5758,7 +5758,7 @@ static const unsigned short utf8_to_euc_E58B[] = {
0x5230, 0x5231, 0x3C5B, 0, 0, 0, 0x387B, 0x4C5E,
};
static const unsigned short utf8_to_euc_E58B_x0213[] = {
- 0xB365, 0x5226, 0, 0x4B56, 0xB366, 0x443C, 0xB367, 0x4D26,
+ 0, 0x5226, 0, 0x4B56, 0xB366, 0x443C, 0xB367, 0x4D26,
0x2E62, 0x4A59, 0xA347, 0, 0x2E64, 0x5227, 0, 0xB36A,
0x2E65, 0xA349, 0x7055, 0, 0xB36C, 0x4630, 0x2E66, 0x5228,
0x342A, 0x4C33, 0, 0x2E67, 0xB36F, 0x3E21, 0x5229, 0x4A67,
@@ -5804,7 +5804,7 @@ static const unsigned short utf8_to_euc_E58D_x0213[] = {
0x4331, 0xB439, 0x476E, 0xB43A, 0x4B4E, 0, 0x5246, 0,
0x406A, 0x2E6F, 0, 0x2E70, 0, 0xB43D, 0x3735, 0xA354,
0, 0x5247, 0, 0, 0xA355, 0xB43F, 0x5248, 0x312C,
- 0x3075, 0x346D, 0xB440, 0x4228, 0x3551, 0x4D71, 0, 0x524B,
+ 0x3075, 0x346D, 0, 0x4228, 0x3551, 0x4D71, 0, 0x524B,
0x3237, 0xB441, 0xA356, 0x524A, 0, 0x2E71, 0xB442, 0x362A,
};
static const unsigned short utf8_to_euc_E58E[] = {
@@ -5841,7 +5841,7 @@ static const unsigned short utf8_to_euc_E58F_x0213[] = {
0xA35B, 0, 0x3B32, 0x5254, 0, 0xB458, 0, 0,
0x4B74, 0x3A35, 0x355A, 0x4D27, 0x4150, 0x483F, 0x3C7D, 0xB459,
0, 0, 0xB45A, 0xB45B, 0x3D47, 0xA35F, 0x3C68, 0x3C75,
- 0, 0x3D76, 0xA360, 0x4840, 0, 0xB45E, 0xB45F, 0x5257,
+ 0, 0x3D76, 0xA360, 0x4840, 0, 0, 0xB45F, 0x5257,
0xB460, 0x3143, 0x4151, 0x387D, 0x3845, 0x3667, 0xB461, 0xB462,
0x525B, 0x4321, 0x427E, 0x362B, 0x3E24, 0x525C, 0x525A, 0x3244,
0x4266, 0x3C38, 0x3B4B, 0x3126, 0xA362, 0xA363, 0x3370, 0x3966,
@@ -6121,8 +6121,8 @@ static const unsigned short utf8_to_euc_E59D_x0213[] = {
0x542E, 0, 0x3A64, 0, 0, 0xA45F, 0xA460, 0x3651,
0, 0, 0x4B37, 0, 0xA461, 0xA462, 0x542C, 0x542F,
0x3A41, 0x3923, 0xB740, 0, 0, 0, 0, 0,
- 0, 0xF436, 0, 0, 0, 0, 0, 0,
- 0, 0x5433, 0xB741, 0, 0x3A25, 0xB742, 0x4333, 0xB743,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x5433, 0xB741, 0, 0x3A25, 0, 0x4333, 0xB743,
0xA464, 0x5430, 0x445A, 0xB745, 0, 0xB746, 0xB747, 0xA465,
0x2F47, 0xB74A, 0, 0xA466, 0xA467, 0xA468, 0, 0x2F48,
0, 0xB74F, 0xB750, 0xA469, 0x2F49, 0, 0xB753, 0x5434,
@@ -6224,7 +6224,7 @@ static const unsigned short utf8_to_euc_E5A2_x0213[] = {
0, 0, 0, 0, 0x4446, 0xA52F, 0x2F5D, 0x5452,
0xB848, 0xB849, 0xB84A, 0, 0, 0, 0xB84B, 0,
0x4B4F, 0x2F5F, 0xA530, 0x5453, 0, 0, 0x5458, 0,
- 0, 0xA531, 0xB84E, 0x4A2F, 0, 0, 0, 0,
+ 0, 0xA531, 0, 0x4A2F, 0, 0, 0, 0,
0x5457, 0x5451, 0x5454, 0x5456, 0xB850, 0, 0x3A26, 0,
};
static const unsigned short utf8_to_euc_E5A3[] = {
@@ -6280,9 +6280,9 @@ static const unsigned short utf8_to_euc_E5A5[] = {
static const unsigned short utf8_to_euc_E5A5_x0213[] = {
0, 0, 0, 0xB872, 0x3162, 0, 0xA542, 0x3471,
0x4660, 0x4A74, 0, 0, 0, 0, 0x5477, 0x4155,
- 0x5476, 0x3740, 0xB874, 0xB875, 0x4B5B, 0x5475, 0, 0x4565,
+ 0x5476, 0x3740, 0xB874, 0, 0x4B5B, 0x5475, 0, 0x4565,
0x5479, 0xB876, 0x5478, 0xA545, 0, 0x2F69, 0xB879, 0xA546,
- 0x547B, 0xB87B, 0x547A, 0xB87C, 0, 0x317C, 0, 0x547C,
+ 0x547B, 0xB87B, 0x547A, 0, 0, 0x317C, 0, 0x547C,
0x3E29, 0x547E, 0x4325, 0xB87D, 0x547D, 0x2F6A, 0x4A33, 0xB921,
0, 0, 0xB922, 0x3D77, 0x455B, 0xA548, 0xA549, 0,
0x5521, 0xB925, 0, 0xB926, 0xA54A, 0x3925, 0, 0,
@@ -6305,7 +6305,7 @@ static const unsigned short utf8_to_euc_E5A6_x0213[] = {
0, 0, 0, 0x5526, 0x2F6D, 0x4245, 0, 0xB930,
0x4B38, 0, 0, 0, 0x454A, 0xB931, 0xA54C, 0xB933,
0xB934, 0, 0x5527, 0xB935, 0, 0, 0, 0xB936,
- 0, 0x4B65, 0xB937, 0x3A4A, 0xA54D, 0, 0x3E2A, 0,
+ 0, 0x4B65, 0, 0x3A4A, 0xA54D, 0, 0x3E2A, 0,
};
static const unsigned short utf8_to_euc_E5A7[] = {
0, 0xB939, 0, 0xB93A, 0xB93B, 0, 0x5528, 0,
@@ -6564,7 +6564,7 @@ static const unsigned short utf8_to_euc_E5B3_x0213[] = {
0, 0x5635, 0, 0, 0, 0xBB3C, 0, 0,
0x463D, 0x362E, 0, 0, 0, 0, 0, 0,
0x3265, 0x5636, 0x563B, 0, 0, 0x5639, 0xBB3E, 0x4A77,
- 0x4A76, 0xBB3F, 0xBB40, 0, 0x4F6D, 0xF43B, 0x4567, 0,
+ 0x4A76, 0xBB3F, 0xBB40, 0, 0x4F6D, 0, 0x4567, 0,
0, 0, 0x5638, 0x3D54, 0, 0x5637, 0, 0,
};
static const unsigned short utf8_to_euc_E5B4[] = {
@@ -6640,7 +6640,7 @@ static const unsigned short utf8_to_euc_E5B7[] = {
static const unsigned short utf8_to_euc_E5B7_x0213[] = {
0, 0, 0, 0xBB76, 0, 0, 0, 0xBB77,
0, 0x565A, 0, 0x4F7D, 0x3460, 0x565B, 0xBB7A, 0,
- 0xBB79, 0xA868, 0x565D, 0x565C, 0, 0, 0x565E, 0xA869,
+ 0, 0xA868, 0x565D, 0x565C, 0, 0, 0x565E, 0xA869,
0xA86A, 0xBB7C, 0, 0x565F, 0, 0x406E, 0x3D23, 0,
0xA86B, 0x3D64, 0x7428, 0x4163, 0xA86D, 0x3929, 0x3A38, 0x392A,
0x3570, 0xA86E, 0, 0x5660, 0, 0, 0x3A39, 0,
@@ -6742,7 +6742,7 @@ static const unsigned short utf8_to_euc_E5BC_x0213[] = {
0xAC2D, 0x5732, 0x4A40, 0x5735, 0x5021, 0x5031, 0xAC2E, 0x3C30,
0x4675, 0x5736, 0, 0x355D, 0x4424, 0x307A, 0x5737, 0x4A26,
0x3930, 0xBC61, 0, 0x4350, 0xAC2F, 0x7434, 0xAC31, 0x446F,
- 0, 0xBC64, 0xBC65, 0x7435, 0xBC67, 0x4C6F, 0x3839, 0x384C,
+ 0, 0, 0xBC65, 0x7435, 0xBC67, 0x4C6F, 0x3839, 0x384C,
0xBC68, 0x5738, 0, 0xBC69, 0xBC6A, 0x5739, 0xBC6B, 0x573F,
0xBC6C, 0x3C65, 0, 0, 0x7436, 0x4425, 0x7437, 0x362F,
0x573A, 0, 0, 0xBC6F, 0x492B, 0x7438, 0x4346, 0xBC71,
@@ -6841,7 +6841,7 @@ static const unsigned short utf8_to_euc_E681_x0213[] = {
0xBD5E, 0x576C, 0x5776, 0x5774, 0, 0, 0x5771, 0x744F,
0xBD60, 0xBD61, 0x5770, 0x4E78, 0xAC4B, 0x5772, 0, 0,
0x3632, 0xBD63, 0x3931, 0, 0xBD64, 0x3D7A, 0xBD65, 0xBD66,
- 0, 0x5779, 0x576B, 0, 0, 0xBD67, 0, 0x576F,
+ 0, 0x5779, 0x576B, 0, 0, 0, 0, 0x576F,
0x575F, 0xBD68, 0x327A, 0x5773, 0x5775, 0x4351, 0, 0xBD69,
0x3A28, 0x3238, 0x576D, 0x5778, 0x5777, 0x3633, 0, 0x4229,
0x3366, 0xBD6A, 0, 0, 0, 0x3743, 0, 0x576E,
@@ -6858,7 +6858,7 @@ static const unsigned short utf8_to_euc_E682[] = {
0x5829, 0, 0, 0xBE21, 0x4569, 0x582E, 0xBE22, 0,
};
static const unsigned short utf8_to_euc_E682_x0213[] = {
- 0, 0x577A, 0xBD6D, 0x577D, 0x5821, 0xF43F, 0xBD6E, 0,
+ 0, 0x577A, 0xBD6D, 0x577D, 0x5821, 0, 0xBD6E, 0,
0xBD6F, 0x3C3D, 0xAC4D, 0x5827, 0x4470, 0x577B, 0xBD71, 0,
0, 0xBD72, 0x5825, 0xBD73, 0x3279, 0xAC4E, 0x5823, 0x5824,
0xBD75, 0, 0x577E, 0x5822, 0, 0x7451, 0x7452, 0x3867,
@@ -6881,7 +6881,7 @@ static const unsigned short utf8_to_euc_E683_x0213[] = {
0, 0, 0xBE23, 0, 0xBE24, 0x3E70, 0x582F, 0x4657,
0xAC54, 0xBE26, 0xBE27, 0x7453, 0, 0, 0xBE29, 0xBE2A,
0, 0x4F47, 0, 0x582B, 0x7454, 0x7455, 0, 0,
- 0x5831, 0xAC55, 0x397B, 0xAC56, 0x404B, 0x7456, 0xBE30, 0x3054,
+ 0x5831, 0xAC55, 0x397B, 0xAC56, 0x404B, 0x7456, 0, 0x3054,
0x582A, 0x5828, 0xBE31, 0x415A, 0, 0xBE32, 0, 0x577C,
0x3B34, 0, 0, 0, 0, 0, 0xAC57, 0,
0x4246, 0x583D, 0xAC58, 0x415B, 0x5838, 0xAC59, 0x5835, 0x5836,
@@ -6900,9 +6900,9 @@ static const unsigned short utf8_to_euc_E684[] = {
static const unsigned short utf8_to_euc_E684_x0213[] = {
0x5837, 0x3D25, 0xBE38, 0x583A, 0, 0, 0x5834, 0xBE39,
0x4C7C, 0x4C7B, 0xBE3A, 0, 0xBE3B, 0x583E, 0x583F, 0x3055,
- 0xAC5A, 0xBE3D, 0xAC5B, 0xAC5C, 0xBE40, 0x5833, 0xBE41, 0xBE42,
+ 0xAC5A, 0, 0xAC5B, 0xAC5C, 0xBE40, 0x5833, 0xBE41, 0xBE42,
0, 0xAC5D, 0x3672, 0x3026, 0x7458, 0, 0xAC5E, 0x3436,
- 0xF440, 0x583B, 0xBE46, 0, 0, 0, 0, 0x5843,
+ 0, 0x583B, 0xBE46, 0, 0, 0, 0, 0x5843,
0x5842, 0, 0xBE47, 0x7459, 0x5847, 0, 0, 0,
0x745A, 0xBE4A, 0, 0, 0x5848, 0xBE4B, 0xBE4C, 0x745B,
0, 0xBE4E, 0xAC5F, 0, 0x5846, 0x5849, 0x5841, 0x5845,
@@ -6980,7 +6980,7 @@ static const unsigned short utf8_to_euc_E688[] = {
static const unsigned short utf8_to_euc_E688_x0213[] = {
0x5878, 0xBF24, 0, 0xBF25, 0xBF26, 0, 0, 0xBF27,
0x5879, 0x587A, 0x4A6A, 0, 0x587C, 0x587B, 0x3D3F, 0,
- 0x402E, 0x3266, 0x327C, 0xBF28, 0x587D, 0xAC73, 0x303F, 0,
+ 0x402E, 0x3266, 0x327C, 0, 0x587D, 0xAC73, 0x303F, 0,
0, 0, 0x404C, 0x587E, 0xBF2A, 0x6C43, 0x5921, 0x3761,
0xBF2B, 0x5922, 0x7462, 0xAC74, 0, 0, 0x406F, 0xBF2E,
0, 0xAC75, 0x5923, 0xBF30, 0, 0, 0x5924, 0x353A,
@@ -7239,7 +7239,7 @@ static const unsigned short utf8_to_euc_E695[] = {
};
static const unsigned short utf8_to_euc_E695_x0213[] = {
0, 0, 0, 0xC14A, 0xAD62, 0x384E, 0, 0xC14B,
- 0x5A43, 0xC14C, 0, 0, 0, 0x5A46, 0xF441, 0x4952,
+ 0x5A43, 0xC14C, 0, 0, 0, 0x5A46, 0, 0x4952,
0xC14D, 0x355F, 0xC14E, 0, 0xAD63, 0x5A45, 0x5A44, 0x4754,
0x5A47, 0x3635, 0, 0, 0, 0x5A49, 0x5A48, 0xC150,
0xC151, 0, 0x343A, 0x3B36, 0, 0, 0x4658, 0x7529,
@@ -7303,9 +7303,9 @@ static const unsigned short utf8_to_euc_E698_x0213[] = {
0, 0xC17A, 0xC17B, 0x3057, 0x404E, 0x752E, 0xC17D, 0,
0, 0, 0, 0, 0x5A66, 0xC17E, 0x752F, 0x4031,
0x3147, 0xAD77, 0x7531, 0xC224, 0x7532, 0x3D55, 0xC226, 0x4B66,
- 0x3A72, 0xC227, 0xAD78, 0x7533, 0xC22A, 0x3E3C, 0xC22B, 0x4027,
+ 0x3A72, 0xC227, 0xAD78, 0x7533, 0xC22A, 0x3E3C, 0, 0x4027,
0x7534, 0x7535, 0, 0x7536, 0x5A65, 0x5A63, 0x5A64, 0xC230,
- 0, 0xC22F, 0x7530, 0xF442, 0x436B, 0, 0, 0x5B26,
+ 0, 0xC22F, 0x7530, 0, 0x436B, 0, 0, 0x5B26,
};
static const unsigned short utf8_to_euc_E699[] = {
0xC231, 0x5A6A, 0x3B7E, 0x3938, 0x5A68, 0xC232, 0xC233, 0,
@@ -7379,7 +7379,7 @@ static const unsigned short utf8_to_euc_E69C[] = {
};
static const unsigned short utf8_to_euc_E69C_x0213[] = {
0x3A47, 0xAE37, 0, 0x5072, 0, 0xAE38, 0, 0xC26F,
- 0x376E, 0x4D2D, 0, 0x4A7E, 0, 0x497E, 0xC270, 0x5B2C,
+ 0x376E, 0x4D2D, 0, 0x4A7E, 0, 0x497E, 0, 0x5B2C,
0, 0, 0xAE39, 0x754D, 0x3A73, 0x443F, 0x5B2D, 0x4F2F,
0, 0xAE3B, 0, 0x4B3E, 0xC273, 0x442B, 0x5B2E, 0x347C,
0xC274, 0, 0xC275, 0, 0, 0, 0x5B2F, 0x5B30,
@@ -7682,7 +7682,7 @@ static const unsigned short utf8_to_euc_E6AB_x0213[] = {
0xC54D, 0xC54C, 0, 0, 0xC54E, 0, 0, 0,
0xAF66, 0x5D2A, 0, 0x4F26, 0xAF65, 0xC551, 0xC552, 0,
0, 0, 0x5D2D, 0x367B, 0xAF67, 0xAF68, 0x5D29, 0x5D2B,
- 0, 0, 0xF44A, 0, 0x7638, 0, 0, 0x7639,
+ 0, 0, 0, 0, 0x7638, 0, 0, 0x7639,
0x4827, 0, 0x5D2E, 0, 0xAF6B, 0, 0, 0,
0xC558, 0xAF6C, 0xAF6D, 0xAF6E, 0, 0, 0, 0,
0, 0, 0x5D32, 0x5D2F, 0xC55B, 0xAF6F, 0, 0,
@@ -7803,7 +7803,7 @@ static const unsigned short utf8_to_euc_E6B1_x0213[] = {
0x3C2E, 0, 0xC65C, 0, 0xC65D, 0x5D68, 0, 0x3440,
0, 0x7651, 0x3178, 0xEE37, 0x7652, 0x4672, 0x5D67, 0x393E,
0x4353, 0, 0x5D69, 0, 0, 0, 0, 0xEE4F,
- 0x5D71, 0, 0x5D6A, 0xC661, 0, 0xEE38, 0, 0xC663,
+ 0x5D71, 0, 0x5D6A, 0xC661, 0, 0xEE38, 0, 0,
0x4241, 0, 0x3562, 0x5D72, 0x7654, 0, 0x7655, 0,
0xC666, 0xC667, 0x3768, 0xC668, 0, 0x3525, 0x5D70, 0,
};
@@ -7883,7 +7883,7 @@ static const unsigned short utf8_to_euc_E6B5_x0213[] = {
0, 0, 0, 0, 0, 0, 0, 0xC73D,
0x7667, 0x5E36, 0x5E34, 0xEE52, 0x494D, 0, 0xEE53, 0xC73F,
0xEE54, 0xC740, 0, 0x5E31, 0x5E33, 0x7668, 0x313A, 0xC742,
- 0, 0x3940, 0x4F32, 0, 0x333D, 0, 0x4962, 0xC743,
+ 0, 0x3940, 0x4F32, 0, 0x333D, 0, 0x4962, 0,
0xEE55, 0, 0, 0, 0x4D61, 0, 0, 0x3324,
0x3F3B, 0x5E35, 0, 0, 0xC745, 0, 0, 0,
};
@@ -7900,7 +7900,7 @@ static const unsigned short utf8_to_euc_E6B6[] = {
static const unsigned short utf8_to_euc_E6B6_x0213[] = {
0xEE56, 0xEE57, 0x766A, 0, 0, 0x5E3A, 0, 0x766B,
0x3E43, 0x766C, 0xEE58, 0, 0x4D30, 0xEE59, 0x5E37, 0,
- 0, 0xEE5A, 0xC749, 0x5E32, 0x766D, 0x5E38, 0xC74B, 0xC74C,
+ 0, 0xEE5A, 0xC749, 0x5E32, 0x766D, 0x5E38, 0, 0xC74C,
0xEE5B, 0x4E5E, 0, 0x4573, 0x4642, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0x766E, 0xEE61, 0x766F, 0, 0xEE62, 0x3336,
@@ -7924,8 +7924,8 @@ static const unsigned short utf8_to_euc_E6B7_x0213[] = {
0x4571, 0x5E4A, 0x7673, 0x7674, 0, 0x7675, 0x5E44, 0xEE6A,
0xC75E, 0x4338, 0xC75F, 0, 0x5E4B, 0xC760, 0x5E40, 0,
0x5E46, 0xEE6B, 0x5E4D, 0x307C, 0x5E43, 0, 0x5E4E, 0xC762,
- 0xC763, 0x3F3C, 0xF44C, 0x3D5F, 0xC764, 0x4A25, 0xEE6C, 0x3A2E,
- 0xF44B, 0x5E3B, 0x5E49, 0x453A, 0x7676, 0, 0, 0,
+ 0xC763, 0x3F3C, 0, 0x3D5F, 0xC764, 0x4A25, 0xEE6C, 0x3A2E,
+ 0, 0x5E3B, 0x5E49, 0x453A, 0x7676, 0, 0, 0,
};
static const unsigned short utf8_to_euc_E6B8[] = {
0xC767, 0, 0, 0, 0xC768, 0x4036, 0, 0x3369,
@@ -7945,7 +7945,7 @@ static const unsigned short utf8_to_euc_E6B8_x0213[] = {
0x3574, 0x454F, 0xEE6F, 0x5E56, 0x5E5F, 0x302F, 0x3132, 0xEE70,
0, 0x3239, 0, 0x5E58, 0x422C, 0x5E4F, 0x5E51, 0x3941,
0, 0, 0xEE72, 0, 0x7678, 0, 0xEE6D, 0,
- 0x5E62, 0xC76E, 0x5E5D, 0xC76F, 0xEE73, 0, 0x5E55, 0,
+ 0x5E62, 0, 0x5E5D, 0xC76F, 0xEE73, 0, 0x5E55, 0,
};
static const unsigned short utf8_to_euc_E6B9[] = {
0, 0, 0, 0x5E5C, 0xC771, 0xC772, 0, 0,
@@ -8342,7 +8342,7 @@ static const unsigned short utf8_to_euc_E78C_x0213[] = {
0, 0, 0x6049, 0xCB26, 0, 0xCB27, 0, 0,
0, 0, 0xF046, 0xCB29, 0, 0, 0x604B, 0x6048,
0xF047, 0xF048, 0, 0x4C54, 0x604A, 0x604C, 0xCB2C, 0x4E44,
- 0, 0, 0xCB2D, 0, 0xCB2E, 0x6050, 0, 0x776D,
+ 0, 0, 0xCB2D, 0, 0, 0x6050, 0, 0x776D,
0x776E, 0x604F, 0x4376, 0x472D, 0xF04B, 0, 0x3825, 0x604E,
0, 0xF04C, 0xCB33, 0xF04D, 0x604D, 0xCB34, 0x4D31, 0x4D32,
0, 0xF04A, 0xCB35, 0xCB36, 0, 0xF04E, 0x6051, 0x316E,
@@ -8385,7 +8385,7 @@ static const unsigned short utf8_to_euc_E78E_x0213[] = {
0x7775, 0, 0x7776, 0, 0, 0xF05F, 0x7777, 0,
0xF060, 0x3461, 0xCB5F, 0x7778, 0, 0xCB61, 0, 0,
0, 0, 0x4E68, 0x605E, 0, 0xF061, 0, 0xF062,
- 0, 0xF063, 0, 0x6060, 0xF064, 0xCB66, 0, 0xF065,
+ 0, 0xF063, 0, 0x6060, 0xF064, 0, 0, 0xF065,
};
static const unsigned short utf8_to_euc_E78F[] = {
0x6061, 0, 0x3251, 0, 0, 0xCB68, 0xCB69, 0,
@@ -8400,11 +8400,11 @@ static const unsigned short utf8_to_euc_E78F[] = {
static const unsigned short utf8_to_euc_E78F_x0213[] = {
0x6061, 0, 0x3251, 0, 0, 0xF066, 0xCB69, 0,
0x605D, 0x7779, 0x3B39, 0xF067, 0xCB6C, 0x4441, 0x605F, 0x777A,
- 0, 0, 0xCB6E, 0xCB6F, 0, 0, 0x777B, 0,
+ 0, 0, 0, 0xCB6F, 0, 0, 0x777B, 0,
0, 0x777C, 0, 0, 0, 0xCB72, 0x6064, 0,
0x3C6E, 0xF068, 0, 0x777D, 0, 0x6062, 0xCB75, 0xF069,
0, 0x777E, 0x373E, 0, 0, 0x4849, 0x6063, 0,
- 0, 0x607E, 0, 0, 0xCB78, 0xCB79, 0, 0xCB7A,
+ 0, 0x607E, 0, 0, 0xCB78, 0, 0, 0xCB7A,
0x6069, 0xF06A, 0xF06C, 0xCB7D, 0, 0xCB7E, 0x383D, 0xCC21,
};
static const unsigned short utf8_to_euc_E790[] = {
@@ -8423,7 +8423,7 @@ static const unsigned short utf8_to_euc_E790_x0213[] = {
0, 0xCC27, 0, 0xF06B, 0, 0, 0, 0,
0, 0, 0x7823, 0x7824, 0, 0, 0, 0,
0, 0, 0x4276, 0, 0xF06E, 0x6068, 0x7826, 0,
- 0x7827, 0xCC2D, 0x7828, 0x7829, 0x782A, 0xCC31, 0x782B, 0x782C,
+ 0x7827, 0, 0x7828, 0x7829, 0x782A, 0xCC31, 0x782B, 0x782C,
0x782D, 0xF06F, 0x606A, 0x4E56, 0x3657, 0x487C, 0x474A, 0,
0, 0xF070, 0x606B, 0, 0, 0, 0, 0x606D,
};
@@ -8618,7 +8618,7 @@ static const unsigned short utf8_to_euc_E79A[] = {
0x6230, 0x6231, 0x6232, 0, 0, 0xCE48, 0, 0x3B2E,
};
static const unsigned short utf8_to_euc_E79A_x0213[] = {
- 0x6225, 0x7860, 0xF451, 0x6226, 0x452A, 0xCE36, 0x3327, 0x3944,
+ 0x6225, 0x7860, 0, 0x6226, 0x452A, 0xCE36, 0x3327, 0x3944,
0x6227, 0, 0, 0x6228, 0xCE37, 0xCE38, 0x6229, 0,
0x3B29, 0, 0, 0x622B, 0, 0xF16E, 0x622A, 0,
0, 0x622C, 0x622D, 0x7861, 0xF16F, 0x7862, 0x7863, 0xCE3D,
@@ -8765,7 +8765,7 @@ static const unsigned short utf8_to_euc_E7A1_x0213[] = {
0xCF66, 0xCF67, 0, 0xCF68, 0xF246, 0, 0, 0,
0x7925, 0, 0xF247, 0x4E32, 0x3945, 0, 0x7926, 0x3827,
0, 0, 0x4823, 0, 0x626D, 0, 0, 0,
- 0, 0, 0xCF6D, 0, 0x626F, 0, 0xCF6E, 0,
+ 0, 0, 0, 0, 0x626F, 0, 0xCF6E, 0,
};
static const unsigned short utf8_to_euc_E7A2[] = {
0, 0x386B, 0, 0, 0, 0, 0x626E, 0x4476,
@@ -9322,7 +9322,7 @@ static const unsigned short utf8_to_euc_E7BE_x0213[] = {
0x6633, 0, 0x4D53, 0xD526, 0x6635, 0xD527, 0x487E, 0xD528,
0xF473, 0x7A3B, 0, 0, 0x6636, 0, 0xF476, 0x7A3C,
0, 0, 0x6639, 0, 0xF477, 0x6638, 0x6637, 0,
- 0, 0xD52E, 0xD52F, 0x663A, 0x3732, 0, 0xD530, 0,
+ 0, 0, 0xD52F, 0x663A, 0x3732, 0, 0xD530, 0,
0x4122, 0x3541, 0xD531, 0, 0, 0xF478, 0x663E, 0x663B,
0, 0, 0x663C, 0, 0xD533, 0, 0x663F, 0,
0x6640, 0x663D, 0, 0, 0xD534, 0x3129, 0, 0x7A3D,
@@ -9664,7 +9664,7 @@ static const unsigned short utf8_to_euc_E88F_x0213[] = {
0x6845, 0, 0, 0, 0x3A5A, 0xF63E, 0, 0x4551,
0x684A, 0x7B22, 0, 0, 0, 0xF63F, 0, 0,
0xD83F, 0x4A6E, 0x7B23, 0x6841, 0, 0, 0, 0x325A,
- 0x3856, 0x4929, 0x684B, 0, 0x683F, 0, 0xD841, 0x6848,
+ 0x3856, 0x4929, 0x684B, 0, 0x683F, 0, 0, 0x6848,
0xD842, 0xF640, 0, 0x6852, 0xD844, 0x6843, 0, 0,
};
static const unsigned short utf8_to_euc_E890[] = {
@@ -9783,7 +9783,7 @@ static const unsigned short utf8_to_euc_E895_x0213[] = {
0xD943, 0xF670, 0xD945, 0xF671, 0, 0x6924, 0xD947, 0x4979,
0x687D, 0x7B38, 0x6856, 0, 0xD949, 0xD94A, 0xF672, 0xD94C,
0xD94D, 0xF673, 0xF674, 0x687C, 0x7B39, 0, 0, 0,
- 0x4F4F, 0x4622, 0x4973, 0xD951, 0, 0x692B, 0, 0xF66C,
+ 0x4F4F, 0x4622, 0x4973, 0, 0, 0x692B, 0, 0xF66C,
0, 0, 0, 0, 0, 0, 0, 0x6931,
0, 0xD953, 0x7B3C, 0xF676, 0, 0xF677, 0x6932, 0xF678,
};
@@ -9998,7 +9998,7 @@ static const unsigned short utf8_to_euc_E8A0[] = {
0, 0x6A45, 0xDC21, 0x6A47, 0xDC22, 0, 0, 0,
};
static const unsigned short utf8_to_euc_E8A0_x0213[] = {
- 0, 0xF77A, 0, 0xF77B, 0, 0x6A24, 0x7B63, 0xF464,
+ 0, 0xF77A, 0, 0xF77B, 0, 0x6A24, 0x7B63, 0,
0, 0xDB6B, 0x7B64, 0xF77C, 0, 0x6A38, 0x6A3C, 0x6A37,
0x7B65, 0x6A3E, 0xDB70, 0xF77D, 0x7B66, 0x6A40, 0x6A3F, 0,
0xDB73, 0xDB6F, 0xDB74, 0xDB75, 0xDB76, 0, 0xDB77, 0x7B67,
@@ -10260,7 +10260,7 @@ static const unsigned short utf8_to_euc_E8AD[] = {
static const unsigned short utf8_to_euc_E8AD_x0213[] = {
0, 0x6B76, 0xDE44, 0xF86A, 0xDE46, 0xDE47, 0x7C31, 0,
0xDE49, 0x6B7A, 0, 0, 0x6B77, 0xDE4E, 0x6B79, 0x6B78,
- 0, 0xF86C, 0xDE4A, 0xDE4B, 0x7C32, 0, 0x6B7B, 0,
+ 0, 0xF86C, 0xDE4A, 0, 0x7C32, 0, 0x6B7B, 0,
0x3C31, 0x7C33, 0x6B7D, 0x6B7C, 0x4968, 0, 0xF86D, 0x6C21,
0, 0, 0, 0xDE50, 0, 0, 0x3759, 0,
0, 0x7C34, 0, 0x6B7E, 0x6C22, 0xDE51, 0, 0x6C23,
@@ -10404,7 +10404,7 @@ static const unsigned short utf8_to_euc_E8B5_x0213[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x4056, 0xDF46, 0x3C4F, 0x6C5F,
0, 0xDF47, 0, 0x3352, 0xF935, 0x6C60, 0xDF49, 0,
- 0x4176, 0x6C61, 0, 0x6C62, 0x496B, 0, 0xF468, 0x352F,
+ 0x4176, 0x6C61, 0, 0x6C62, 0x496B, 0, 0, 0x352F,
0, 0, 0, 0, 0, 0, 0, 0xDF4A,
};
static const unsigned short utf8_to_euc_E8B6[] = {
@@ -10519,7 +10519,7 @@ static const unsigned short utf8_to_euc_E8BB[] = {
};
static const unsigned short utf8_to_euc_E8BB_x0213[] = {
0x7C4A, 0xE055, 0, 0xE056, 0xE057, 0x6D40, 0x6D3D, 0xE058,
- 0x6D41, 0, 0x3C56, 0x6D42, 0x3530, 0x3733, 0, 0xE059,
+ 0x6D41, 0, 0x3C56, 0x6D42, 0x3530, 0x3733, 0, 0,
0, 0xF95A, 0x382E, 0, 0xF95B, 0, 0, 0,
0, 0, 0, 0x6D43, 0xE05C, 0, 0, 0x4670,
0, 0, 0x453E, 0x6D44, 0, 0, 0, 0,
@@ -10642,7 +10642,7 @@ static const unsigned short utf8_to_euc_E981_x0213[] = {
0, 0x6E26, 0x4D37, 0x313F, 0xE15D, 0x4A57, 0x3261, 0x6E21,
0x6E22, 0x6E23, 0x6E24, 0x463B, 0x4323, 0x3063, 0x6E28, 0,
0x6E29, 0x7423, 0, 0xE15E, 0x423D, 0xF97D, 0x6E2A, 0,
- 0x3173, 0x414C, 0xE160, 0x382F, 0, 0x4D5A, 0xE161, 0xE162,
+ 0x3173, 0x414C, 0xE160, 0x382F, 0, 0x4D5A, 0xE161, 0,
0x6E2B, 0x452C, 0, 0, 0xE163, 0x4178, 0x3C57, 0x6E2C,
0xE164, 0, 0x6E2F, 0, 0xE165, 0x3D65, 0x6E2D, 0x412B,
0x412A, 0xE166, 0x3064, 0, 0x4E4B, 0x6E31, 0, 0x4872,
@@ -10761,7 +10761,7 @@ static const unsigned short utf8_to_euc_E987_x0213[] = {
0x6E56, 0x6E57, 0xE321, 0xFA4C, 0xFA4D, 0xE323, 0x4850, 0x3A53,
0x3C61, 0x6E58, 0, 0x6E59, 0x4E24, 0x3D45, 0x4C6E, 0x4E4C,
0x6E5A, 0x3662, 0, 0xE324, 0xE325, 0, 0x6E5B, 0x7C7C,
- 0x4523, 0xE327, 0xFA4E, 0x6E5E, 0x3378, 0x3F4B, 0xE329, 0x6E5C,
+ 0x4523, 0xE327, 0xFA4E, 0x6E5E, 0x3378, 0x3F4B, 0, 0x6E5C,
0, 0x6E5D, 0, 0x4460, 0x7C7E, 0x7D21, 0x4B55, 0x367C,
0, 0xE32C, 0xE32D, 0, 0xFA51, 0x7D22, 0xFA52, 0xE331,
0xE332, 0x7D23, 0, 0, 0, 0x6E60, 0x6E61, 0xE334,
@@ -10778,7 +10778,7 @@ static const unsigned short utf8_to_euc_E988[] = {
0xE353, 0xE354, 0xE355, 0, 0xE356, 0, 0xE357, 0x6E6F,
};
static const unsigned short utf8_to_euc_E988_x0213[] = {
- 0xE338, 0xFA53, 0, 0, 0xE33A, 0xE33B, 0xE33C, 0x7D24,
+ 0xE338, 0xFA53, 0, 0, 0xE33A, 0xE33B, 0, 0x7D24,
0, 0xE33E, 0xFA54, 0, 0xE340, 0x465F, 0x3343, 0,
0x7D25, 0x6E67, 0xE342, 0xE343, 0x6E64, 0x6E66, 0xFA55, 0xFA56,
0xE345, 0, 0, 0, 0xE346, 0xE347, 0x6E62, 0,
@@ -10804,7 +10804,7 @@ static const unsigned short utf8_to_euc_E989_x0213[] = {
0xE362, 0xFA5F, 0x6E76, 0x3174, 0xE364, 0xE365, 0x6E68, 0,
0xFA60, 0xFA61, 0x482D, 0, 0x6E6C, 0xFA62, 0x3E60, 0xFA63,
0xFA64, 0xE36B, 0, 0, 0, 0, 0xE36C, 0xE36D,
- 0xE36E, 0x395B, 0, 0, 0, 0xE36F, 0xE370, 0xE371,
+ 0xE36E, 0x395B, 0, 0, 0, 0xE36F, 0xE370, 0,
0x7D2D, 0xE373, 0, 0xE374, 0xFA67, 0xFA68, 0x4B48, 0xFA69,
};
static const unsigned short utf8_to_euc_E98A[] = {
@@ -10840,7 +10840,7 @@ static const unsigned short utf8_to_euc_E98B[] = {
static const unsigned short utf8_to_euc_E98B_x0213[] = {
0xFA75, 0xE433, 0x7D2F, 0xE435, 0, 0xE436, 0xFA76, 0xE438,
0xE439, 0, 0, 0x7D30, 0x7D31, 0xE43C, 0xFA77, 0x6E77,
- 0xFA78, 0, 0x4B2F, 0x7D32, 0, 0xE440, 0, 0xFA79,
+ 0xFA78, 0, 0x4B2F, 0x7D32, 0, 0, 0, 0xFA79,
0xE442, 0xFA7A, 0, 0, 0xE444, 0xE445, 0, 0xE446,
0x7D33, 0xE448, 0, 0xE449, 0x3D7B, 0xFA7B, 0, 0xFA7C,
0xE44C, 0x6E7A, 0x4A5F, 0, 0xE44D, 0x3154, 0xE44E, 0,
@@ -10902,7 +10902,7 @@ static const unsigned short utf8_to_euc_E98E_x0213[] = {
0xFB38, 0, 0xE528, 0xFB39, 0x3379, 0xE52A, 0, 0xFB3A,
0, 0, 0xE52C, 0, 0x6F30, 0xE52D, 0x3A3F, 0x4179,
0xE52E, 0, 0x444A, 0x7D40, 0, 0, 0xFB3B, 0,
- 0, 0xFB35, 0, 0x7D41, 0xE533, 0, 0xE534, 0x333B,
+ 0, 0xFB35, 0, 0x7D41, 0, 0, 0xE534, 0x333B,
0xE535, 0xE53B, 0, 0xE536, 0x6F2E, 0x6F2F, 0x4443, 0,
0x6F2D, 0, 0, 0, 0xE537, 0xE538, 0xE539, 0,
0, 0x6F31, 0x7D42, 0, 0, 0, 0, 0,
@@ -10925,7 +10925,7 @@ static const unsigned short utf8_to_euc_E98F_x0213[] = {
0, 0x3640, 0xFB43, 0, 0x6F3B, 0x6F35, 0xE54C, 0xFB44,
0x6F34, 0, 0, 0, 0, 0, 0, 0,
0, 0xFB3F, 0, 0, 0, 0xFB3C, 0, 0xE54F,
- 0xE550, 0xE54E, 0xE551, 0xFB49, 0, 0x7D47, 0, 0,
+ 0, 0xE54E, 0xE551, 0xFB49, 0, 0x7D47, 0, 0,
};
static const unsigned short utf8_to_euc_E990[] = {
0, 0xE554, 0xE555, 0x6F3F, 0xE556, 0, 0, 0x6F40,
@@ -10944,7 +10944,7 @@ static const unsigned short utf8_to_euc_E990_x0213[] = {
0x3E62, 0x462A, 0x6F3C, 0, 0, 0, 0, 0xE55F,
0, 0x6F45, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0x6F43, 0, 0, 0xE560, 0xE561,
- 0, 0xE562, 0xFB4A, 0x7D48, 0xFB4B, 0x6F44, 0x6F42, 0,
+ 0, 0, 0xFB4A, 0x7D48, 0xFB4B, 0x6F44, 0x6F42, 0,
0x4278, 0, 0x6F46, 0xFB4C, 0, 0xE568, 0, 0xE567,
};
static const unsigned short utf8_to_euc_E991[] = {
@@ -10959,7 +10959,7 @@ static const unsigned short utf8_to_euc_E991[] = {
};
static const unsigned short utf8_to_euc_E991_x0213[] = {
0, 0x6F47, 0, 0xE569, 0x6F49, 0xFB4D, 0, 0,
- 0xE56B, 0, 0x7D49, 0, 0xE56D, 0, 0, 0,
+ 0, 0, 0x7D49, 0, 0xE56D, 0, 0, 0,
0, 0x3455, 0x6F48, 0x4C7A, 0, 0xE56E, 0, 0,
0, 0xE56F, 0x6F54, 0x6F4A, 0xE570, 0, 0x6F4D, 0xE571,
0x6F4B, 0xE572, 0x6F4C, 0x7D4A, 0, 0, 0, 0,
@@ -11010,7 +11010,7 @@ static const unsigned short utf8_to_euc_E996[] = {
static const unsigned short utf8_to_euc_E996_x0213[] = {
0x4C67, 0, 0x6F59, 0x412E, 0xE622, 0, 0xFB54, 0x6F5A,
0xE623, 0x4A44, 0x6F5B, 0x332B, 0xFB55, 0xFB56, 0x7D4E, 0x313C,
- 0, 0x3457, 0xF471, 0x3456, 0x6F5C, 0, 0x6F5D, 0,
+ 0, 0x3457, 0, 0x3456, 0x6F5C, 0, 0x6F5D, 0,
0x6F5E, 0x6F5F, 0, 0, 0, 0xE627, 0xE628, 0x7D4F,
0x6F60, 0xE62A, 0x3458, 0x3355, 0x395E, 0x4836, 0x7D50, 0x6F62,
0x6F61, 0x7D51, 0, 0xFB58, 0x7D52, 0x6F63, 0, 0,
@@ -11148,9 +11148,9 @@ static const unsigned short utf8_to_euc_E99D[] = {
0xE73E, 0x7058, 0x705C, 0xE73F, 0x705A, 0xE740, 0, 0xE741,
};
static const unsigned short utf8_to_euc_E99D_x0213[] = {
- 0, 0xFB7A, 0x704E, 0xE72E, 0x704B, 0, 0x704C, 0xFB7B,
+ 0, 0xFB7A, 0x704E, 0, 0x704B, 0, 0x704C, 0xFB7B,
0x704D, 0x704F, 0xE72F, 0, 0, 0x7D68, 0x7D69, 0x7D6A,
- 0, 0xF476, 0x4044, 0, 0, 0xFB7C, 0x4C77, 0xFB7D,
+ 0, 0, 0x4044, 0, 0, 0xFB7C, 0x4C77, 0xFB7D,
0xE734, 0x4045, 0x7D6B, 0xFB7E, 0x7050, 0, 0x4873, 0,
0x7051, 0x7353, 0x4C4C, 0xE737, 0x7052, 0, 0x7053, 0xE738,
0x7054, 0x3357, 0xFC21, 0x7056, 0, 0x3F59, 0x7D6C, 0,
@@ -11292,7 +11292,7 @@ static const unsigned short utf8_to_euc_E9A4_x0213[] = {
0xFC54, 0x712E, 0x4D5C, 0, 0x3142, 0, 0, 0,
0x3B41, 0xE853, 0x712F, 0x326E, 0x7130, 0xE854, 0xFC57, 0xFC58,
0x7131, 0, 0xFC5A, 0xFC5B, 0xFC5C, 0x7133, 0x7134, 0xE85A,
- 0x7136, 0x7132, 0xE85B, 0, 0x7135, 0, 0xE85C, 0xE85D,
+ 0x7136, 0x7132, 0xE85B, 0, 0x7135, 0, 0xE85C, 0,
0x345B, 0, 0, 0xE85E, 0x7137, 0, 0x7138, 0,
0, 0xFC5E, 0xFC5F, 0xFC60, 0xE862, 0xE863, 0, 0,
0, 0xE864, 0xFC61, 0xFC62, 0xFC63, 0x7139, 0x713A, 0,
@@ -11431,7 +11431,7 @@ static const unsigned short utf8_to_euc_E9AB_x0213[] = {
0x716F, 0x7E36, 0, 0x7E37, 0x3F71, 0, 0xFD2D, 0,
0xE965, 0, 0, 0, 0, 0, 0x7E38, 0x7170,
0xFD2E, 0x7171, 0xFD2F, 0x7172, 0x7173, 0xFD30, 0x7E39, 0xE96B,
- 0x3962, 0xF47B, 0, 0xE96C, 0xFD32, 0, 0x7174, 0x7175,
+ 0x3962, 0, 0, 0xE96C, 0xFD32, 0, 0x7174, 0x7175,
0xFD33, 0, 0x7176, 0x7177, 0xE96F, 0xFD34, 0x7178, 0xE971,
0, 0xFD35, 0x4831, 0x717A, 0xE973, 0x4926, 0x717B, 0x7179,
0, 0x717D, 0xE974, 0xE975, 0x717C, 0xE976, 0, 0x717E,
@@ -11495,7 +11495,7 @@ static const unsigned short utf8_to_euc_E9AE_x0213[] = {
0x723E, 0, 0, 0, 0, 0, 0xFD48, 0x7E49,
0x723F, 0xEA63, 0x4B6E, 0x3B2D, 0xFD49, 0x3A7A, 0x412F, 0,
0xEA65, 0xFD4A, 0xFD4D, 0, 0x7240, 0, 0, 0xEA68,
- 0xFD4E, 0x7243, 0, 0xEA6A, 0xEA6B, 0, 0xFD4F, 0xEA6D,
+ 0xFD4E, 0x7243, 0, 0, 0xEA6B, 0, 0xFD4F, 0xEA6D,
};
static const unsigned short utf8_to_euc_E9AF[] = {
0x7241, 0xEA6E, 0, 0, 0, 0, 0x7244, 0xEA6F,
@@ -11859,11 +11859,11 @@ static const unsigned short utf8_to_euc_EFA8[] = {
};
static const unsigned short utf8_to_euc_EFA8_x0213[] = {
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0xF434, 0x2F4B,
- 0x2F57, 0x4F72, 0xF444, 0xAE79, 0x757A, 0x775A, 0x776F, 0xF453,
- 0xF455, 0x793C, 0x793D, 0x7941, 0xF45A, 0xF45B, 0xF45E, 0x7B3A,
- 0xF738, 0xF745, 0x7C2E, 0xF469, 0xF96E, 0xF46B, 0x7C6A, 0xF46F,
- 0xF470, 0xF473, 0xF477, 0xF478, 0xF479, 0xF47D, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x2F4B,
+ 0x2F57, 0x4F72, 0, 0xAE79, 0x757A, 0x775A, 0x776F, 0,
+ 0, 0x793C, 0x793D, 0x7941, 0, 0, 0, 0x7B3A,
+ 0xF738, 0xF745, 0x7C2E, 0, 0xF96E, 0, 0x7C6A, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
0x2E38, 0x2E49, 0x2E50, 0x2E63, 0x2E68, 0x2E6E, 0x2F2C, 0x2F2F,
0x2F36, 0x2F5A, 0x2F5E, 0x4F61, 0x4F62, 0x7450, 0x745C, 0x745E,
};
@@ -11957,6 +11957,16 @@ static const unsigned short utf8_to_euc_EFBF[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
+static const unsigned short utf8_to_euc_EFBF_x0213[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0x2131, 0, 0x216F, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
static const unsigned short *const utf8_to_euc_E1_x0213[] = {
0, 0, 0, 0,
0, 0, 0, 0,
@@ -12405,7 +12415,7 @@ static const unsigned short *const utf8_to_euc_EF_x0213[] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, utf8_to_euc_EFB9_x0213, 0, 0,
- utf8_to_euc_EFBC_x0213, utf8_to_euc_EFBD_x0213, utf8_to_euc_EFBE, utf8_to_euc_EFBF,
+ utf8_to_euc_EFBC_x0213, utf8_to_euc_EFBD_x0213, utf8_to_euc_EFBE, utf8_to_euc_EFBF_x0213,
};
const unsigned short *const utf8_to_euc_2bytes[] = {
0, 0, 0, 0,
diff --git a/ext/nkf/nkf.c b/ext/nkf/nkf.c
index c958c91753..37717e4799 100644
--- a/ext/nkf/nkf.c
+++ b/ext/nkf/nkf.c
@@ -168,7 +168,6 @@ rb_nkf_convert(VALUE obj, VALUE opt, VALUE src)
/* use _result_ end */
rb_str_set_len(tmp, output_ctr);
- OBJ_INFECT(tmp, src);
if (mimeout_f)
rb_enc_associate(tmp, rb_usascii_encoding());
diff --git a/ext/nkf/nkf.gemspec b/ext/nkf/nkf.gemspec
new file mode 100644
index 0000000000..23f1dcdbaf
--- /dev/null
+++ b/ext/nkf/nkf.gemspec
@@ -0,0 +1,24 @@
+Gem::Specification.new do |spec|
+ spec.name = "nkf"
+ spec.version = "0.1.0"
+ spec.authors = ["NARUSE Yui"]
+ spec.email = ["naruse@airemix.jp"]
+
+ spec.summary = %q{Ruby extension for Network Kanji Filter}
+ spec.description = %q{Ruby extension for Network Kanji Filter}
+ spec.homepage = "https://github.com/ruby/nkf"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/ext/objspace/depend b/ext/objspace/depend
index 642265618c..d3a702007e 100644
--- a/ext/objspace/depend
+++ b/ext/objspace/depend
@@ -1,28 +1,330 @@
# AUTOGENERATED DEPENDENCIES START
object_tracing.o: $(RUBY_EXTCONF_H)
object_tracing.o: $(arch_hdrdir)/ruby/config.h
+object_tracing.o: $(hdrdir)/ruby.h
+object_tracing.o: $(hdrdir)/ruby/assert.h
object_tracing.o: $(hdrdir)/ruby/backward.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/assume.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/attributes.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/bool.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/inttypes.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/limits.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/long_long.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/r_cast.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/rmodule.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/stdalign.h
+object_tracing.o: $(hdrdir)/ruby/backward/2/stdarg.h
object_tracing.o: $(hdrdir)/ruby/debug.h
object_tracing.o: $(hdrdir)/ruby/defines.h
-object_tracing.o: $(hdrdir)/ruby/encoding.h
object_tracing.o: $(hdrdir)/ruby/intern.h
-object_tracing.o: $(hdrdir)/ruby/io.h
+object_tracing.o: $(hdrdir)/ruby/internal/anyargs.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+object_tracing.o: $(hdrdir)/ruby/internal/assume.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/artificial.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/cold.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/const.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/error.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/format.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/noalias.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/noinline.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/pure.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/restrict.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/warning.h
+object_tracing.o: $(hdrdir)/ruby/internal/attr/weakref.h
+object_tracing.o: $(hdrdir)/ruby/internal/cast.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_is.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+object_tracing.o: $(hdrdir)/ruby/internal/compiler_since.h
+object_tracing.o: $(hdrdir)/ruby/internal/config.h
+object_tracing.o: $(hdrdir)/ruby/internal/constant_p.h
+object_tracing.o: $(hdrdir)/ruby/internal/core.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rarray.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rbasic.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rbignum.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rclass.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rdata.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rfile.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rhash.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/robject.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rregexp.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rstring.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rstruct.h
+object_tracing.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+object_tracing.o: $(hdrdir)/ruby/internal/ctype.h
+object_tracing.o: $(hdrdir)/ruby/internal/dllexport.h
+object_tracing.o: $(hdrdir)/ruby/internal/dosish.h
+object_tracing.o: $(hdrdir)/ruby/internal/error.h
+object_tracing.o: $(hdrdir)/ruby/internal/eval.h
+object_tracing.o: $(hdrdir)/ruby/internal/event.h
+object_tracing.o: $(hdrdir)/ruby/internal/fl_type.h
+object_tracing.o: $(hdrdir)/ruby/internal/gc.h
+object_tracing.o: $(hdrdir)/ruby/internal/glob.h
+object_tracing.o: $(hdrdir)/ruby/internal/globals.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/attribute.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/builtin.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/extension.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/feature.h
+object_tracing.o: $(hdrdir)/ruby/internal/has/warning.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/array.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/bignum.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/class.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/compar.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/complex.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/cont.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/dir.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/enum.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/error.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/eval.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/file.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/gc.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/hash.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/io.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/load.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/marshal.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/numeric.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/object.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/parse.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/proc.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/process.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/random.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/range.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/rational.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/re.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/ruby.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/select.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/signal.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/string.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/struct.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/thread.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/time.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/variable.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/vm.h
+object_tracing.o: $(hdrdir)/ruby/internal/interpreter.h
+object_tracing.o: $(hdrdir)/ruby/internal/iterator.h
+object_tracing.o: $(hdrdir)/ruby/internal/memory.h
+object_tracing.o: $(hdrdir)/ruby/internal/method.h
+object_tracing.o: $(hdrdir)/ruby/internal/module.h
+object_tracing.o: $(hdrdir)/ruby/internal/newobj.h
+object_tracing.o: $(hdrdir)/ruby/internal/rgengc.h
+object_tracing.o: $(hdrdir)/ruby/internal/scan_args.h
+object_tracing.o: $(hdrdir)/ruby/internal/special_consts.h
+object_tracing.o: $(hdrdir)/ruby/internal/static_assert.h
+object_tracing.o: $(hdrdir)/ruby/internal/stdalign.h
+object_tracing.o: $(hdrdir)/ruby/internal/stdbool.h
+object_tracing.o: $(hdrdir)/ruby/internal/symbol.h
+object_tracing.o: $(hdrdir)/ruby/internal/token_paste.h
+object_tracing.o: $(hdrdir)/ruby/internal/value.h
+object_tracing.o: $(hdrdir)/ruby/internal/value_type.h
+object_tracing.o: $(hdrdir)/ruby/internal/variable.h
+object_tracing.o: $(hdrdir)/ruby/internal/warning_push.h
+object_tracing.o: $(hdrdir)/ruby/internal/xmalloc.h
object_tracing.o: $(hdrdir)/ruby/missing.h
-object_tracing.o: $(hdrdir)/ruby/onigmo.h
-object_tracing.o: $(hdrdir)/ruby/oniguruma.h
object_tracing.o: $(hdrdir)/ruby/ruby.h
object_tracing.o: $(hdrdir)/ruby/st.h
object_tracing.o: $(hdrdir)/ruby/subst.h
-object_tracing.o: $(top_srcdir)/include/ruby.h
object_tracing.o: $(top_srcdir)/internal.h
object_tracing.o: object_tracing.c
object_tracing.o: objspace.h
objspace.o: $(RUBY_EXTCONF_H)
objspace.o: $(arch_hdrdir)/ruby/config.h
+objspace.o: $(hdrdir)/ruby.h
+objspace.o: $(hdrdir)/ruby/assert.h
objspace.o: $(hdrdir)/ruby/backward.h
+objspace.o: $(hdrdir)/ruby/backward/2/assume.h
+objspace.o: $(hdrdir)/ruby/backward/2/attributes.h
+objspace.o: $(hdrdir)/ruby/backward/2/bool.h
+objspace.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+objspace.o: $(hdrdir)/ruby/backward/2/inttypes.h
+objspace.o: $(hdrdir)/ruby/backward/2/limits.h
+objspace.o: $(hdrdir)/ruby/backward/2/long_long.h
+objspace.o: $(hdrdir)/ruby/backward/2/r_cast.h
+objspace.o: $(hdrdir)/ruby/backward/2/rmodule.h
+objspace.o: $(hdrdir)/ruby/backward/2/stdalign.h
+objspace.o: $(hdrdir)/ruby/backward/2/stdarg.h
objspace.o: $(hdrdir)/ruby/defines.h
objspace.o: $(hdrdir)/ruby/encoding.h
objspace.o: $(hdrdir)/ruby/intern.h
+objspace.o: $(hdrdir)/ruby/internal/anyargs.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+objspace.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+objspace.o: $(hdrdir)/ruby/internal/assume.h
+objspace.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+objspace.o: $(hdrdir)/ruby/internal/attr/artificial.h
+objspace.o: $(hdrdir)/ruby/internal/attr/cold.h
+objspace.o: $(hdrdir)/ruby/internal/attr/const.h
+objspace.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+objspace.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+objspace.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+objspace.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+objspace.o: $(hdrdir)/ruby/internal/attr/error.h
+objspace.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+objspace.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+objspace.o: $(hdrdir)/ruby/internal/attr/format.h
+objspace.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+objspace.o: $(hdrdir)/ruby/internal/attr/noalias.h
+objspace.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+objspace.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+objspace.o: $(hdrdir)/ruby/internal/attr/noinline.h
+objspace.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+objspace.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+objspace.o: $(hdrdir)/ruby/internal/attr/pure.h
+objspace.o: $(hdrdir)/ruby/internal/attr/restrict.h
+objspace.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+objspace.o: $(hdrdir)/ruby/internal/attr/warning.h
+objspace.o: $(hdrdir)/ruby/internal/attr/weakref.h
+objspace.o: $(hdrdir)/ruby/internal/cast.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_is.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+objspace.o: $(hdrdir)/ruby/internal/compiler_since.h
+objspace.o: $(hdrdir)/ruby/internal/config.h
+objspace.o: $(hdrdir)/ruby/internal/constant_p.h
+objspace.o: $(hdrdir)/ruby/internal/core.h
+objspace.o: $(hdrdir)/ruby/internal/core/rarray.h
+objspace.o: $(hdrdir)/ruby/internal/core/rbasic.h
+objspace.o: $(hdrdir)/ruby/internal/core/rbignum.h
+objspace.o: $(hdrdir)/ruby/internal/core/rclass.h
+objspace.o: $(hdrdir)/ruby/internal/core/rdata.h
+objspace.o: $(hdrdir)/ruby/internal/core/rfile.h
+objspace.o: $(hdrdir)/ruby/internal/core/rhash.h
+objspace.o: $(hdrdir)/ruby/internal/core/rmatch.h
+objspace.o: $(hdrdir)/ruby/internal/core/robject.h
+objspace.o: $(hdrdir)/ruby/internal/core/rregexp.h
+objspace.o: $(hdrdir)/ruby/internal/core/rstring.h
+objspace.o: $(hdrdir)/ruby/internal/core/rstruct.h
+objspace.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+objspace.o: $(hdrdir)/ruby/internal/ctype.h
+objspace.o: $(hdrdir)/ruby/internal/dllexport.h
+objspace.o: $(hdrdir)/ruby/internal/dosish.h
+objspace.o: $(hdrdir)/ruby/internal/error.h
+objspace.o: $(hdrdir)/ruby/internal/eval.h
+objspace.o: $(hdrdir)/ruby/internal/event.h
+objspace.o: $(hdrdir)/ruby/internal/fl_type.h
+objspace.o: $(hdrdir)/ruby/internal/gc.h
+objspace.o: $(hdrdir)/ruby/internal/glob.h
+objspace.o: $(hdrdir)/ruby/internal/globals.h
+objspace.o: $(hdrdir)/ruby/internal/has/attribute.h
+objspace.o: $(hdrdir)/ruby/internal/has/builtin.h
+objspace.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+objspace.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+objspace.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+objspace.o: $(hdrdir)/ruby/internal/has/extension.h
+objspace.o: $(hdrdir)/ruby/internal/has/feature.h
+objspace.o: $(hdrdir)/ruby/internal/has/warning.h
+objspace.o: $(hdrdir)/ruby/internal/intern/array.h
+objspace.o: $(hdrdir)/ruby/internal/intern/bignum.h
+objspace.o: $(hdrdir)/ruby/internal/intern/class.h
+objspace.o: $(hdrdir)/ruby/internal/intern/compar.h
+objspace.o: $(hdrdir)/ruby/internal/intern/complex.h
+objspace.o: $(hdrdir)/ruby/internal/intern/cont.h
+objspace.o: $(hdrdir)/ruby/internal/intern/dir.h
+objspace.o: $(hdrdir)/ruby/internal/intern/enum.h
+objspace.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+objspace.o: $(hdrdir)/ruby/internal/intern/error.h
+objspace.o: $(hdrdir)/ruby/internal/intern/eval.h
+objspace.o: $(hdrdir)/ruby/internal/intern/file.h
+objspace.o: $(hdrdir)/ruby/internal/intern/gc.h
+objspace.o: $(hdrdir)/ruby/internal/intern/hash.h
+objspace.o: $(hdrdir)/ruby/internal/intern/io.h
+objspace.o: $(hdrdir)/ruby/internal/intern/load.h
+objspace.o: $(hdrdir)/ruby/internal/intern/marshal.h
+objspace.o: $(hdrdir)/ruby/internal/intern/numeric.h
+objspace.o: $(hdrdir)/ruby/internal/intern/object.h
+objspace.o: $(hdrdir)/ruby/internal/intern/parse.h
+objspace.o: $(hdrdir)/ruby/internal/intern/proc.h
+objspace.o: $(hdrdir)/ruby/internal/intern/process.h
+objspace.o: $(hdrdir)/ruby/internal/intern/random.h
+objspace.o: $(hdrdir)/ruby/internal/intern/range.h
+objspace.o: $(hdrdir)/ruby/internal/intern/rational.h
+objspace.o: $(hdrdir)/ruby/internal/intern/re.h
+objspace.o: $(hdrdir)/ruby/internal/intern/ruby.h
+objspace.o: $(hdrdir)/ruby/internal/intern/select.h
+objspace.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+objspace.o: $(hdrdir)/ruby/internal/intern/signal.h
+objspace.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+objspace.o: $(hdrdir)/ruby/internal/intern/string.h
+objspace.o: $(hdrdir)/ruby/internal/intern/struct.h
+objspace.o: $(hdrdir)/ruby/internal/intern/thread.h
+objspace.o: $(hdrdir)/ruby/internal/intern/time.h
+objspace.o: $(hdrdir)/ruby/internal/intern/variable.h
+objspace.o: $(hdrdir)/ruby/internal/intern/vm.h
+objspace.o: $(hdrdir)/ruby/internal/interpreter.h
+objspace.o: $(hdrdir)/ruby/internal/iterator.h
+objspace.o: $(hdrdir)/ruby/internal/memory.h
+objspace.o: $(hdrdir)/ruby/internal/method.h
+objspace.o: $(hdrdir)/ruby/internal/module.h
+objspace.o: $(hdrdir)/ruby/internal/newobj.h
+objspace.o: $(hdrdir)/ruby/internal/rgengc.h
+objspace.o: $(hdrdir)/ruby/internal/scan_args.h
+objspace.o: $(hdrdir)/ruby/internal/special_consts.h
+objspace.o: $(hdrdir)/ruby/internal/static_assert.h
+objspace.o: $(hdrdir)/ruby/internal/stdalign.h
+objspace.o: $(hdrdir)/ruby/internal/stdbool.h
+objspace.o: $(hdrdir)/ruby/internal/symbol.h
+objspace.o: $(hdrdir)/ruby/internal/token_paste.h
+objspace.o: $(hdrdir)/ruby/internal/value.h
+objspace.o: $(hdrdir)/ruby/internal/value_type.h
+objspace.o: $(hdrdir)/ruby/internal/variable.h
+objspace.o: $(hdrdir)/ruby/internal/warning_push.h
+objspace.o: $(hdrdir)/ruby/internal/xmalloc.h
objspace.o: $(hdrdir)/ruby/io.h
objspace.o: $(hdrdir)/ruby/missing.h
objspace.o: $(hdrdir)/ruby/onigmo.h
@@ -33,19 +335,183 @@ objspace.o: $(hdrdir)/ruby/ruby.h
objspace.o: $(hdrdir)/ruby/st.h
objspace.o: $(hdrdir)/ruby/subst.h
objspace.o: $(top_srcdir)/gc.h
-objspace.o: $(top_srcdir)/include/ruby.h
+objspace.o: $(top_srcdir)/id_table.h
objspace.o: $(top_srcdir)/internal.h
+objspace.o: $(top_srcdir)/internal/array.h
+objspace.o: $(top_srcdir)/internal/class.h
+objspace.o: $(top_srcdir)/internal/compilers.h
+objspace.o: $(top_srcdir)/internal/gc.h
+objspace.o: $(top_srcdir)/internal/hash.h
+objspace.o: $(top_srcdir)/internal/imemo.h
+objspace.o: $(top_srcdir)/internal/sanitizers.h
+objspace.o: $(top_srcdir)/internal/serial.h
+objspace.o: $(top_srcdir)/internal/static_assert.h
+objspace.o: $(top_srcdir)/internal/warnings.h
objspace.o: $(top_srcdir)/node.h
objspace.o: $(top_srcdir)/symbol.h
objspace.o: objspace.c
objspace.o: {$(VPATH)}id.h
objspace_dump.o: $(RUBY_EXTCONF_H)
objspace_dump.o: $(arch_hdrdir)/ruby/config.h
+objspace_dump.o: $(hdrdir)/ruby.h
+objspace_dump.o: $(hdrdir)/ruby/assert.h
+objspace_dump.o: $(hdrdir)/ruby/atomic.h
objspace_dump.o: $(hdrdir)/ruby/backward.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/assume.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/attributes.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/bool.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/inttypes.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/limits.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/long_long.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/r_cast.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/rmodule.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/stdalign.h
+objspace_dump.o: $(hdrdir)/ruby/backward/2/stdarg.h
objspace_dump.o: $(hdrdir)/ruby/debug.h
objspace_dump.o: $(hdrdir)/ruby/defines.h
objspace_dump.o: $(hdrdir)/ruby/encoding.h
objspace_dump.o: $(hdrdir)/ruby/intern.h
+objspace_dump.o: $(hdrdir)/ruby/internal/anyargs.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+objspace_dump.o: $(hdrdir)/ruby/internal/assume.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/artificial.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/cold.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/const.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/error.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/format.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/noalias.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/noinline.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/pure.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/restrict.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/warning.h
+objspace_dump.o: $(hdrdir)/ruby/internal/attr/weakref.h
+objspace_dump.o: $(hdrdir)/ruby/internal/cast.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_is.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+objspace_dump.o: $(hdrdir)/ruby/internal/compiler_since.h
+objspace_dump.o: $(hdrdir)/ruby/internal/config.h
+objspace_dump.o: $(hdrdir)/ruby/internal/constant_p.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rarray.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rbasic.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rbignum.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rclass.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rdata.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rfile.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rhash.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/robject.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rregexp.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rstring.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rstruct.h
+objspace_dump.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+objspace_dump.o: $(hdrdir)/ruby/internal/ctype.h
+objspace_dump.o: $(hdrdir)/ruby/internal/dllexport.h
+objspace_dump.o: $(hdrdir)/ruby/internal/dosish.h
+objspace_dump.o: $(hdrdir)/ruby/internal/error.h
+objspace_dump.o: $(hdrdir)/ruby/internal/eval.h
+objspace_dump.o: $(hdrdir)/ruby/internal/event.h
+objspace_dump.o: $(hdrdir)/ruby/internal/fl_type.h
+objspace_dump.o: $(hdrdir)/ruby/internal/gc.h
+objspace_dump.o: $(hdrdir)/ruby/internal/glob.h
+objspace_dump.o: $(hdrdir)/ruby/internal/globals.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/attribute.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/builtin.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/extension.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/feature.h
+objspace_dump.o: $(hdrdir)/ruby/internal/has/warning.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/array.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/bignum.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/class.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/compar.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/complex.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/cont.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/dir.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/enum.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/error.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/eval.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/file.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/gc.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/hash.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/io.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/load.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/marshal.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/numeric.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/object.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/parse.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/proc.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/process.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/random.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/range.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/rational.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/re.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/ruby.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/select.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/signal.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/string.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/struct.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/thread.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/time.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/variable.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/vm.h
+objspace_dump.o: $(hdrdir)/ruby/internal/interpreter.h
+objspace_dump.o: $(hdrdir)/ruby/internal/iterator.h
+objspace_dump.o: $(hdrdir)/ruby/internal/memory.h
+objspace_dump.o: $(hdrdir)/ruby/internal/method.h
+objspace_dump.o: $(hdrdir)/ruby/internal/module.h
+objspace_dump.o: $(hdrdir)/ruby/internal/newobj.h
+objspace_dump.o: $(hdrdir)/ruby/internal/rgengc.h
+objspace_dump.o: $(hdrdir)/ruby/internal/scan_args.h
+objspace_dump.o: $(hdrdir)/ruby/internal/special_consts.h
+objspace_dump.o: $(hdrdir)/ruby/internal/static_assert.h
+objspace_dump.o: $(hdrdir)/ruby/internal/stdalign.h
+objspace_dump.o: $(hdrdir)/ruby/internal/stdbool.h
+objspace_dump.o: $(hdrdir)/ruby/internal/symbol.h
+objspace_dump.o: $(hdrdir)/ruby/internal/token_paste.h
+objspace_dump.o: $(hdrdir)/ruby/internal/value.h
+objspace_dump.o: $(hdrdir)/ruby/internal/value_type.h
+objspace_dump.o: $(hdrdir)/ruby/internal/variable.h
+objspace_dump.o: $(hdrdir)/ruby/internal/warning_push.h
+objspace_dump.o: $(hdrdir)/ruby/internal/xmalloc.h
objspace_dump.o: $(hdrdir)/ruby/io.h
objspace_dump.o: $(hdrdir)/ruby/missing.h
objspace_dump.o: $(hdrdir)/ruby/onigmo.h
@@ -54,20 +520,30 @@ objspace_dump.o: $(hdrdir)/ruby/ruby.h
objspace_dump.o: $(hdrdir)/ruby/st.h
objspace_dump.o: $(hdrdir)/ruby/subst.h
objspace_dump.o: $(hdrdir)/ruby/thread_native.h
+objspace_dump.o: $(hdrdir)/ruby/util.h
objspace_dump.o: $(top_srcdir)/ccan/check_type/check_type.h
objspace_dump.o: $(top_srcdir)/ccan/container_of/container_of.h
objspace_dump.o: $(top_srcdir)/ccan/list/list.h
objspace_dump.o: $(top_srcdir)/ccan/str/str.h
objspace_dump.o: $(top_srcdir)/gc.h
-objspace_dump.o: $(top_srcdir)/include/ruby.h
objspace_dump.o: $(top_srcdir)/internal.h
+objspace_dump.o: $(top_srcdir)/internal/array.h
+objspace_dump.o: $(top_srcdir)/internal/compilers.h
+objspace_dump.o: $(top_srcdir)/internal/gc.h
+objspace_dump.o: $(top_srcdir)/internal/hash.h
+objspace_dump.o: $(top_srcdir)/internal/imemo.h
+objspace_dump.o: $(top_srcdir)/internal/sanitizers.h
+objspace_dump.o: $(top_srcdir)/internal/serial.h
+objspace_dump.o: $(top_srcdir)/internal/static_assert.h
+objspace_dump.o: $(top_srcdir)/internal/string.h
+objspace_dump.o: $(top_srcdir)/internal/vm.h
+objspace_dump.o: $(top_srcdir)/internal/warnings.h
objspace_dump.o: $(top_srcdir)/method.h
objspace_dump.o: $(top_srcdir)/node.h
objspace_dump.o: $(top_srcdir)/ruby_assert.h
objspace_dump.o: $(top_srcdir)/ruby_atomic.h
objspace_dump.o: $(top_srcdir)/thread_pthread.h
objspace_dump.o: $(top_srcdir)/vm_core.h
-objspace_dump.o: $(top_srcdir)/vm_debug.h
objspace_dump.o: $(top_srcdir)/vm_opts.h
objspace_dump.o: objspace.h
objspace_dump.o: objspace_dump.c
diff --git a/ext/objspace/lib/objspace.rb b/ext/objspace/lib/objspace.rb
new file mode 100644
index 0000000000..0298b0646c
--- /dev/null
+++ b/ext/objspace/lib/objspace.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'objspace.so'
+
+module ObjectSpace
+ class << self
+ private :_dump
+ private :_dump_all
+ end
+
+ module_function
+
+ # call-seq:
+ # ObjectSpace.dump(obj[, output: :string]) # => "{ ... }"
+ # ObjectSpace.dump(obj, output: :file) # => #<File:/tmp/rubyobj20131125-88733-1xkfmpv.json>
+ # ObjectSpace.dump(obj, output: :stdout) # => nil
+ #
+ # Dump the contents of a ruby object as JSON.
+ #
+ # This method is only expected to work with C Ruby.
+ # This is an experimental method and is subject to change.
+ # In particular, the function signature and output format are
+ # not guaranteed to be compatible in future versions of ruby.
+ def dump(obj, output: :string)
+ out = case output
+ when :file, nil
+ require 'tempfile'
+ Tempfile.create(%w(rubyobj .json))
+ when :stdout
+ STDOUT
+ when :string
+ +''
+ when IO
+ output
+ else
+ raise ArgumentError, "wrong output option: #{output.inspect}"
+ end
+
+ ret = _dump(obj, out)
+ return nil if output == :stdout
+ ret
+ end
+
+
+ # call-seq:
+ # ObjectSpace.dump_all([output: :file]) # => #<File:/tmp/rubyheap20131125-88469-laoj3v.json>
+ # ObjectSpace.dump_all(output: :stdout) # => nil
+ # ObjectSpace.dump_all(output: :string) # => "{...}\n{...}\n..."
+ # ObjectSpace.dump_all(output:
+ # File.open('heap.json','w')) # => #<File:heap.json>
+ # ObjectSpace.dump_all(output: :string,
+ # since: 42) # => "{...}\n{...}\n..."
+ #
+ # Dump the contents of the ruby heap as JSON.
+ #
+ # _since_ must be a non-negative integer or +nil+.
+ #
+ # If _since_ is a positive integer, only objects of that generation and
+ # newer generations are dumped. The current generation can be accessed using
+ # GC::count.
+ #
+ # Objects that were allocated without object allocation tracing enabled
+ # are ignored. See ::trace_object_allocations for more information and
+ # examples.
+ #
+ # If _since_ is omitted or is +nil+, all objects are dumped.
+ #
+ # This method is only expected to work with C Ruby.
+ # This is an experimental method and is subject to change.
+ # In particular, the function signature and output format are
+ # not guaranteed to be compatible in future versions of ruby.
+ def dump_all(output: :file, full: false, since: nil)
+ out = case output
+ when :file, nil
+ require 'tempfile'
+ Tempfile.create(%w(rubyheap .json))
+ when :stdout
+ STDOUT
+ when :string
+ +''
+ when IO
+ output
+ else
+ raise ArgumentError, "wrong output option: #{output.inspect}"
+ end
+
+ ret = _dump_all(out, full, since)
+ return nil if output == :stdout
+ ret
+ end
+end
diff --git a/ext/objspace/object_tracing.c b/ext/objspace/object_tracing.c
index 611d059b9e..66d6baa491 100644
--- a/ext/objspace/object_tracing.c
+++ b/ext/objspace/object_tracing.c
@@ -39,7 +39,8 @@ make_unique_str(st_table *tbl, const char *str, long len)
if (st_lookup(tbl, (st_data_t)str, &n)) {
st_insert(tbl, (st_data_t)str, n+1);
- st_get_key(tbl, (st_data_t)str, (st_data_t *)&result);
+ st_get_key(tbl, (st_data_t)str, &n);
+ result = (char *)n;
}
else {
result = (char *)ruby_xmalloc(len+1);
@@ -59,8 +60,9 @@ delete_unique_str(st_table *tbl, const char *str)
st_lookup(tbl, (st_data_t)str, &n);
if (n == 1) {
- st_delete(tbl, (st_data_t *)&str, 0);
- ruby_xfree((char *)str);
+ n = (st_data_t)str;
+ st_delete(tbl, &n, 0);
+ ruby_xfree((char *)n);
}
else {
st_insert(tbl, (st_data_t)str, n-1);
@@ -82,8 +84,10 @@ newobj_i(VALUE tpval, void *data)
const char *path_cstr = RTEST(path) ? make_unique_str(arg->str_table, RSTRING_PTR(path), RSTRING_LEN(path)) : 0;
VALUE class_path = (RTEST(klass) && !OBJ_FROZEN(klass)) ? rb_class_path_cached(klass) : Qnil;
const char *class_path_cstr = RTEST(class_path) ? make_unique_str(arg->str_table, RSTRING_PTR(class_path), RSTRING_LEN(class_path)) : 0;
+ st_data_t v;
- if (st_lookup(arg->object_table, (st_data_t)obj, (st_data_t *)&info)) {
+ if (st_lookup(arg->object_table, (st_data_t)obj, &v)) {
+ info = (struct allocation_info *)v;
if (arg->keep_remains) {
if (info->living) {
/* do nothing. there is possibility to keep living if FREEOBJ events while suppressing tracing */
@@ -113,15 +117,19 @@ freeobj_i(VALUE tpval, void *data)
{
struct traceobj_arg *arg = (struct traceobj_arg *)data;
rb_trace_arg_t *tparg = rb_tracearg_from_tracepoint(tpval);
- VALUE obj = rb_tracearg_object(tparg);
+ st_data_t obj = (st_data_t)rb_tracearg_object(tparg);
+ st_data_t v;
struct allocation_info *info;
- if (st_lookup(arg->object_table, (st_data_t)obj, (st_data_t *)&info)) {
- if (arg->keep_remains) {
+ if (arg->keep_remains) {
+ if (st_lookup(arg->object_table, obj, &v)) {
+ info = (struct allocation_info *)v;
info->living = 0;
}
- else {
- st_delete(arg->object_table, (st_data_t *)&obj, (st_data_t *)&info);
+ }
+ else {
+ if (st_delete(arg->object_table, &obj, &v)) {
+ info = (struct allocation_info *)v;
delete_unique_str(arg->str_table, info->path);
delete_unique_str(arg->str_table, info->class_path);
ruby_xfree(info);
@@ -130,19 +138,94 @@ freeobj_i(VALUE tpval, void *data)
}
static int
-free_keys_i(st_data_t key, st_data_t value, void *data)
+free_keys_i(st_data_t key, st_data_t value, st_data_t data)
{
ruby_xfree((void *)key);
return ST_CONTINUE;
}
static int
-free_values_i(st_data_t key, st_data_t value, void *data)
+free_values_i(st_data_t key, st_data_t value, st_data_t data)
{
ruby_xfree((void *)value);
return ST_CONTINUE;
}
+static void
+allocation_info_tracer_mark(void *ptr)
+{
+ struct traceobj_arg *trace_arg = (struct traceobj_arg *)ptr;
+ rb_gc_mark(trace_arg->newobj_trace);
+ rb_gc_mark(trace_arg->freeobj_trace);
+}
+
+static void
+allocation_info_tracer_free(void *ptr)
+{
+ struct traceobj_arg *arg = (struct traceobj_arg *)ptr;
+ /* clear tables */
+ st_foreach(arg->object_table, free_values_i, 0);
+ st_free_table(arg->object_table);
+ st_foreach(arg->str_table, free_keys_i, 0);
+ st_free_table(arg->str_table);
+ xfree(arg);
+}
+
+static size_t
+allocation_info_tracer_memsize(const void *ptr)
+{
+ size_t size;
+ struct traceobj_arg *trace_arg = (struct traceobj_arg *)ptr;
+ size = sizeof(*trace_arg);
+ size += st_memsize(trace_arg->object_table);
+ size += st_memsize(trace_arg->str_table);
+ return size;
+}
+
+static int
+hash_foreach_should_replace_key(st_data_t key, st_data_t value, st_data_t argp, int error)
+{
+ VALUE allocated_object;
+
+ allocated_object = (VALUE)value;
+ if (allocated_object != rb_gc_location(allocated_object)) {
+ return ST_REPLACE;
+ }
+
+ return ST_CONTINUE;
+}
+
+static int
+hash_replace_key(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
+{
+ *key = rb_gc_location((VALUE)*key);
+
+ return ST_CONTINUE;
+}
+
+static void
+allocation_info_tracer_compact(void *ptr)
+{
+ struct traceobj_arg *trace_arg = (struct traceobj_arg *)ptr;
+
+ if (trace_arg->object_table &&
+ st_foreach_with_replace(trace_arg->object_table, hash_foreach_should_replace_key, hash_replace_key, 0)) {
+ rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ }
+}
+
+static const rb_data_type_t allocation_info_tracer_type = {
+ "ObjectTracing/allocation_info_tracer",
+ {
+ allocation_info_tracer_mark,
+ allocation_info_tracer_free, /* Never called because global */
+ allocation_info_tracer_memsize,
+ allocation_info_tracer_compact,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static VALUE traceobj_arg;
static struct traceobj_arg *tmp_trace_arg; /* TODO: Do not use global variables */
static int tmp_keep_remains; /* TODO: Do not use global variables */
@@ -150,7 +233,9 @@ static struct traceobj_arg *
get_traceobj_arg(void)
{
if (tmp_trace_arg == 0) {
- tmp_trace_arg = ALLOC_N(struct traceobj_arg, 1);
+ VALUE obj = TypedData_Make_Struct(rb_cObject, struct traceobj_arg, &allocation_info_tracer_type, tmp_trace_arg);
+ traceobj_arg = obj;
+ rb_gc_register_mark_object(traceobj_arg);
tmp_trace_arg->running = 0;
tmp_trace_arg->keep_remains = tmp_keep_remains;
tmp_trace_arg->newobj_trace = 0;
@@ -206,10 +291,12 @@ trace_object_allocations_stop(VALUE self)
}
if (arg->running == 0) {
- rb_tracepoint_disable(arg->newobj_trace);
- rb_tracepoint_disable(arg->freeobj_trace);
- arg->newobj_trace = 0;
- arg->freeobj_trace = 0;
+ if (arg->newobj_trace != 0) {
+ rb_tracepoint_disable(arg->newobj_trace);
+ }
+ if (arg->freeobj_trace != 0) {
+ rb_tracepoint_disable(arg->freeobj_trace);
+ }
}
return Qnil;
@@ -321,9 +408,9 @@ static struct allocation_info *
lookup_allocation_info(VALUE obj)
{
if (tmp_trace_arg) {
- struct allocation_info *info;
- if (st_lookup(tmp_trace_arg->object_table, obj, (st_data_t *)&info)) {
- return info;
+ st_data_t info;
+ if (st_lookup(tmp_trace_arg->object_table, obj, &info)) {
+ return (struct allocation_info *)info;
}
}
return NULL;
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index ee76367b44..3fa4fd279b 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -12,19 +12,28 @@
**********************************************************************/
+#include "gc.h"
#include "internal.h"
-#include <ruby/st.h>
-#include <ruby/io.h>
-#include <ruby/re.h>
+#include "internal/class.h"
+#include "internal/compilers.h"
+#include "internal/hash.h"
+#include "internal/imemo.h"
+#include "internal/sanitizers.h"
#include "node.h"
-#include "gc.h"
+#include "ruby/io.h"
+#include "ruby/re.h"
+#include "ruby/st.h"
#include "symbol.h"
+#undef rb_funcall
+
+#include "ruby/ruby.h"
+
/*
* call-seq:
* ObjectSpace.memsize_of(obj) -> Integer
*
- * Return consuming memory size of obj.
+ * Return consuming memory size of obj in bytes.
*
* Note that the return size is incomplete. You need to deal with this
* information as only a *HINT*. Especially, the size of +T_DATA+ may not be
@@ -47,37 +56,68 @@ struct total_data {
VALUE klass;
};
+static void
+total_i(VALUE v, void *ptr)
+{
+ struct total_data *data = (struct total_data *)ptr;
+
+ switch (BUILTIN_TYPE(v)) {
+ case T_NONE:
+ case T_IMEMO:
+ case T_ICLASS:
+ case T_NODE:
+ case T_ZOMBIE:
+ return;
+ default:
+ if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) {
+ data->total += rb_obj_memsize_of(v);
+ }
+ }
+}
+
+typedef void (*each_obj_with_flags)(VALUE, void*);
+
+struct obj_itr {
+ each_obj_with_flags cb;
+ void *data;
+};
+
static int
-total_i(void *vstart, void *vend, size_t stride, void *ptr)
+heap_iter(void *vstart, void *vend, size_t stride, void *ptr)
{
+ struct obj_itr * ctx = (struct obj_itr *)ptr;
VALUE v;
- struct total_data *data = (struct total_data *)ptr;
for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) {
- if (RBASIC(v)->flags) {
- switch (BUILTIN_TYPE(v)) {
- case T_NONE:
- case T_IMEMO:
- case T_ICLASS:
- case T_NODE:
- case T_ZOMBIE:
- continue;
- default:
- if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) {
- data->total += rb_obj_memsize_of(v);
- }
- }
- }
+ void *poisoned = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
+ if (RBASIC(v)->flags) {
+ (*ctx->cb)(v, ctx->data);
+ }
+
+ if (poisoned) {
+ asan_poison_object(v);
+ }
}
return 0;
}
+static void
+each_object_with_flags(each_obj_with_flags cb, void *ctx)
+{
+ struct obj_itr data;
+ data.cb = cb;
+ data.data = ctx;
+ rb_objspace_each_objects(heap_iter, &data);
+}
+
/*
* call-seq:
* ObjectSpace.memsize_of_all([klass]) -> Integer
*
- * Return consuming memory size of all living objects.
+ * Return consuming memory size of all living objects in bytes.
*
* If +klass+ (should be Class object) is given, return the total memory size
* of instances of the given class.
@@ -110,7 +150,7 @@ memsize_of_all_m(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "01", &data.klass);
}
- rb_objspace_each_objects(total_i, &data);
+ each_object_with_flags(total_i, &data);
return SIZET2NUM(data.total);
}
@@ -137,24 +177,18 @@ setup_hash(int argc, VALUE *argv)
hash = rb_hash_new();
}
else if (!RHASH_EMPTY_P(hash)) {
- st_foreach(RHASH_TBL(hash), set_zero_i, hash);
+ /* WB: no new reference */
+ st_foreach(RHASH_TBL_RAW(hash), set_zero_i, hash);
}
return hash;
}
-static int
-cos_i(void *vstart, void *vend, size_t stride, void *data)
+static void
+cos_i(VALUE v, void *data)
{
size_t *counts = (size_t *)data;
- VALUE v = (VALUE)vstart;
-
- for (;v != (VALUE)vend; v += stride) {
- if (RBASIC(v)->flags) {
- counts[BUILTIN_TYPE(v)] += rb_obj_memsize_of(v);
- }
- }
- return 0;
+ counts[BUILTIN_TYPE(v)] += rb_obj_memsize_of(v);
}
static VALUE
@@ -188,6 +222,7 @@ type2sym(enum ruby_value_type i)
CASE_TYPE(T_IMEMO);
CASE_TYPE(T_NODE);
CASE_TYPE(T_ICLASS);
+ CASE_TYPE(T_MOVED);
CASE_TYPE(T_ZOMBIE);
#undef CASE_TYPE
default: rb_bug("type2sym: unknown type (%d)", i);
@@ -230,7 +265,7 @@ count_objects_size(int argc, VALUE *argv, VALUE os)
counts[i] = 0;
}
- rb_objspace_each_objects(cos_i, &counts[0]);
+ each_object_with_flags(cos_i, &counts[0]);
for (i = 0; i <= T_MASK; i++) {
if (counts[i]) {
@@ -248,25 +283,20 @@ struct dynamic_symbol_counts {
size_t immortal;
};
-static int
-cs_i(void *vstart, void *vend, size_t stride, void *n)
+static void
+cs_i(VALUE v, void *n)
{
struct dynamic_symbol_counts *counts = (struct dynamic_symbol_counts *)n;
- VALUE v = (VALUE)vstart;
- for (; v != (VALUE)vend; v += stride) {
- if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_SYMBOL) {
- ID id = RSYMBOL(v)->id;
- if ((id & ~ID_SCOPE_MASK) == 0) {
- counts->mortal++;
- }
- else {
- counts->immortal++;
- }
- }
+ if (BUILTIN_TYPE(v) == T_SYMBOL) {
+ ID id = RSYMBOL(v)->id;
+ if ((id & ~ID_SCOPE_MASK) == 0) {
+ counts->mortal++;
+ }
+ else {
+ counts->immortal++;
+ }
}
-
- return 0;
}
size_t rb_sym_immortal_count(void);
@@ -304,7 +334,7 @@ count_symbols(int argc, VALUE *argv, VALUE os)
VALUE hash = setup_hash(argc, argv);
size_t immortal_symbols = rb_sym_immortal_count();
- rb_objspace_each_objects(cs_i, &dynamic_counts);
+ each_object_with_flags(cs_i, &dynamic_counts);
rb_hash_aset(hash, ID2SYM(rb_intern("mortal_dynamic_symbol")), SIZET2NUM(dynamic_counts.mortal));
rb_hash_aset(hash, ID2SYM(rb_intern("immortal_dynamic_symbol")), SIZET2NUM(dynamic_counts.immortal));
@@ -314,20 +344,15 @@ count_symbols(int argc, VALUE *argv, VALUE os)
return hash;
}
-static int
-cn_i(void *vstart, void *vend, size_t stride, void *n)
+static void
+cn_i(VALUE v, void *n)
{
size_t *nodes = (size_t *)n;
- VALUE v = (VALUE)vstart;
- for (; v != (VALUE)vend; v += stride) {
- if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_NODE) {
- size_t s = nd_type((NODE *)v);
- nodes[s]++;
- }
+ if (BUILTIN_TYPE(v) == T_NODE) {
+ size_t s = nd_type((NODE *)v);
+ nodes[s]++;
}
-
- return 0;
}
/*
@@ -357,30 +382,34 @@ static VALUE
count_nodes(int argc, VALUE *argv, VALUE os)
{
size_t nodes[NODE_LAST+1];
- size_t i;
+ enum node_type i;
VALUE hash = setup_hash(argc, argv);
for (i = 0; i <= NODE_LAST; i++) {
nodes[i] = 0;
}
- rb_objspace_each_objects(cn_i, &nodes[0]);
+ each_object_with_flags(cn_i, &nodes[0]);
for (i=0; i<NODE_LAST; i++) {
if (nodes[i] != 0) {
VALUE node;
switch (i) {
-#define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); break;
+#define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); goto set
COUNT_NODE(NODE_SCOPE);
COUNT_NODE(NODE_BLOCK);
COUNT_NODE(NODE_IF);
+ COUNT_NODE(NODE_UNLESS);
COUNT_NODE(NODE_CASE);
+ COUNT_NODE(NODE_CASE2);
+ COUNT_NODE(NODE_CASE3);
COUNT_NODE(NODE_WHEN);
- COUNT_NODE(NODE_OPT_N);
+ COUNT_NODE(NODE_IN);
COUNT_NODE(NODE_WHILE);
COUNT_NODE(NODE_UNTIL);
COUNT_NODE(NODE_ITER);
COUNT_NODE(NODE_FOR);
+ COUNT_NODE(NODE_FOR_MASGN);
COUNT_NODE(NODE_BREAK);
COUNT_NODE(NODE_NEXT);
COUNT_NODE(NODE_REDO);
@@ -397,22 +426,22 @@ count_nodes(int argc, VALUE *argv, VALUE os)
COUNT_NODE(NODE_DASGN_CURR);
COUNT_NODE(NODE_GASGN);
COUNT_NODE(NODE_IASGN);
- COUNT_NODE(NODE_IASGN2);
COUNT_NODE(NODE_CDECL);
COUNT_NODE(NODE_CVASGN);
- COUNT_NODE(NODE_CVDECL);
COUNT_NODE(NODE_OP_ASGN1);
COUNT_NODE(NODE_OP_ASGN2);
COUNT_NODE(NODE_OP_ASGN_AND);
COUNT_NODE(NODE_OP_ASGN_OR);
COUNT_NODE(NODE_OP_CDECL);
COUNT_NODE(NODE_CALL);
+ COUNT_NODE(NODE_OPCALL);
COUNT_NODE(NODE_FCALL);
COUNT_NODE(NODE_VCALL);
+ COUNT_NODE(NODE_QCALL);
COUNT_NODE(NODE_SUPER);
COUNT_NODE(NODE_ZSUPER);
- COUNT_NODE(NODE_ARRAY);
- COUNT_NODE(NODE_ZARRAY);
+ COUNT_NODE(NODE_LIST);
+ COUNT_NODE(NODE_ZLIST);
COUNT_NODE(NODE_VALUES);
COUNT_NODE(NODE_HASH);
COUNT_NODE(NODE_RETURN);
@@ -435,7 +464,7 @@ count_nodes(int argc, VALUE *argv, VALUE os)
COUNT_NODE(NODE_DXSTR);
COUNT_NODE(NODE_EVSTR);
COUNT_NODE(NODE_DREGX);
- COUNT_NODE(NODE_DREGX_ONCE);
+ COUNT_NODE(NODE_ONCE);
COUNT_NODE(NODE_ARGS);
COUNT_NODE(NODE_ARGS_AUX);
COUNT_NODE(NODE_OPT_ARG);
@@ -444,8 +473,6 @@ count_nodes(int argc, VALUE *argv, VALUE os)
COUNT_NODE(NODE_ARGSCAT);
COUNT_NODE(NODE_ARGSPUSH);
COUNT_NODE(NODE_SPLAT);
- COUNT_NODE(NODE_TO_ARY);
- COUNT_NODE(NODE_BLOCK_ARG);
COUNT_NODE(NODE_BLOCK_PASS);
COUNT_NODE(NODE_DEFN);
COUNT_NODE(NODE_DEFS);
@@ -468,51 +495,48 @@ count_nodes(int argc, VALUE *argv, VALUE os)
COUNT_NODE(NODE_ERRINFO);
COUNT_NODE(NODE_DEFINED);
COUNT_NODE(NODE_POSTEXE);
- COUNT_NODE(NODE_ALLOCA);
- COUNT_NODE(NODE_BMETHOD);
COUNT_NODE(NODE_DSYM);
COUNT_NODE(NODE_ATTRASGN);
- COUNT_NODE(NODE_PRELUDE);
COUNT_NODE(NODE_LAMBDA);
+ COUNT_NODE(NODE_ARYPTN);
+ COUNT_NODE(NODE_FNDPTN);
+ COUNT_NODE(NODE_HSHPTN);
#undef COUNT_NODE
- default: node = INT2FIX(i);
+ case NODE_LAST: break;
}
+ UNREACHABLE;
+ set:
rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
}
}
return hash;
}
-static int
-cto_i(void *vstart, void *vend, size_t stride, void *data)
+static void
+cto_i(VALUE v, void *data)
{
VALUE hash = (VALUE)data;
- VALUE v = (VALUE)vstart;
-
- for (; v != (VALUE)vend; v += stride) {
- if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_DATA) {
- VALUE counter;
- VALUE key = RBASIC(v)->klass;
-
- if (key == 0) {
- const char *name = rb_objspace_data_type_name(v);
- if (name == 0) name = "unknown";
- key = ID2SYM(rb_intern(name));
- }
- counter = rb_hash_aref(hash, key);
- if (NIL_P(counter)) {
- counter = INT2FIX(1);
- }
- else {
- counter = INT2FIX(FIX2INT(counter) + 1);
- }
-
- rb_hash_aset(hash, key, counter);
- }
+ if (BUILTIN_TYPE(v) == T_DATA) {
+ VALUE counter;
+ VALUE key = RBASIC(v)->klass;
+
+ if (key == 0) {
+ const char *name = rb_objspace_data_type_name(v);
+ if (name == 0) name = "unknown";
+ key = ID2SYM(rb_intern(name));
+ }
+
+ counter = rb_hash_aref(hash, key);
+ if (NIL_P(counter)) {
+ counter = INT2FIX(1);
+ }
+ else {
+ counter = INT2FIX(FIX2INT(counter) + 1);
+ }
+
+ rb_hash_aset(hash, key, counter);
}
-
- return 0;
}
/*
@@ -551,37 +575,32 @@ static VALUE
count_tdata_objects(int argc, VALUE *argv, VALUE self)
{
VALUE hash = setup_hash(argc, argv);
- rb_objspace_each_objects(cto_i, (void *)hash);
+ each_object_with_flags(cto_i, (void *)hash);
return hash;
}
-static ID imemo_type_ids[imemo_mask+1];
+static ID imemo_type_ids[IMEMO_MASK+1];
-static int
-count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data)
+static void
+count_imemo_objects_i(VALUE v, void *data)
{
VALUE hash = (VALUE)data;
- VALUE v = (VALUE)vstart;
- for (; v != (VALUE)vend; v += stride) {
- if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_IMEMO) {
- VALUE counter;
- VALUE key = ID2SYM(imemo_type_ids[imemo_type(v)]);
+ if (BUILTIN_TYPE(v) == T_IMEMO) {
+ VALUE counter;
+ VALUE key = ID2SYM(imemo_type_ids[imemo_type(v)]);
- counter = rb_hash_aref(hash, key);
+ counter = rb_hash_aref(hash, key);
- if (NIL_P(counter)) {
- counter = INT2FIX(1);
- }
- else {
- counter = INT2FIX(FIX2INT(counter) + 1);
- }
+ if (NIL_P(counter)) {
+ counter = INT2FIX(1);
+ }
+ else {
+ counter = INT2FIX(FIX2INT(counter) + 1);
+ }
- rb_hash_aset(hash, key, counter);
- }
+ rb_hash_aset(hash, key, counter);
}
-
- return 0;
}
/*
@@ -618,7 +637,7 @@ count_imemo_objects(int argc, VALUE *argv, VALUE self)
VALUE hash = setup_hash(argc, argv);
if (imemo_type_ids[0] == 0) {
- imemo_type_ids[0] = rb_intern("imemo_none");
+ imemo_type_ids[0] = rb_intern("imemo_env");
imemo_type_ids[1] = rb_intern("imemo_cref");
imemo_type_ids[2] = rb_intern("imemo_svar");
imemo_type_ids[3] = rb_intern("imemo_throw_data");
@@ -626,9 +645,15 @@ count_imemo_objects(int argc, VALUE *argv, VALUE self)
imemo_type_ids[5] = rb_intern("imemo_memo");
imemo_type_ids[6] = rb_intern("imemo_ment");
imemo_type_ids[7] = rb_intern("imemo_iseq");
+ imemo_type_ids[8] = rb_intern("imemo_tmpbuf");
+ imemo_type_ids[9] = rb_intern("imemo_ast");
+ imemo_type_ids[10] = rb_intern("imemo_parser_strterm");
+ imemo_type_ids[11] = rb_intern("imemo_callinfo");
+ imemo_type_ids[12] = rb_intern("imemo_callcache");
+ imemo_type_ids[13] = rb_intern("imemo_constcache");
}
- rb_objspace_each_objects(count_imemo_objects_i, (void *)hash);
+ each_object_with_flags(count_imemo_objects_i, (void *)hash);
return hash;
}
@@ -652,12 +677,12 @@ static const rb_data_type_t iow_data_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
-static VALUE rb_mInternalObjectWrapper;
+static VALUE rb_cInternalObjectWrapper;
static VALUE
iow_newobj(VALUE obj)
{
- return TypedData_Wrap_Struct(rb_mInternalObjectWrapper, &iow_data_type, (void *)obj);
+ return TypedData_Wrap_Struct(rb_cInternalObjectWrapper, &iow_data_type, (void *)obj);
}
/* Returns the type of the internal object. */
@@ -687,7 +712,7 @@ iow_internal_object_id(VALUE self)
}
struct rof_data {
- st_table *refs;
+ VALUE refs;
VALUE internals;
};
@@ -703,7 +728,7 @@ reachable_object_from_i(VALUE obj, void *data_ptr)
val = iow_newobj(obj);
rb_ary_push(data->internals, val);
}
- st_insert(data->refs, key, val);
+ rb_hash_aset(data->refs, key, val);
}
}
@@ -761,20 +786,18 @@ static VALUE
reachable_objects_from(VALUE self, VALUE obj)
{
if (rb_objspace_markable_object_p(obj)) {
- VALUE ret = rb_ary_new();
struct rof_data data;
if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
obj = (VALUE)DATA_PTR(obj);
}
- data.refs = st_init_numtable();
+ data.refs = rb_ident_hash_new();
data.internals = rb_ary_new();
rb_objspace_reachable_objects_from(obj, reachable_object_from_i, &data);
- st_foreach(data.refs, collect_values, (st_data_t)ret);
- return ret;
+ return rb_funcall(data.refs, rb_intern("values"), 0);
}
else {
return Qnil;
@@ -823,7 +846,7 @@ static int
collect_values_of_values(VALUE category, VALUE category_objects, VALUE categories)
{
VALUE ary = rb_ary_new();
- st_foreach(rb_hash_tbl(category_objects), collect_values, ary);
+ rb_hash_foreach(category_objects, collect_values, ary);
rb_hash_aset(categories, category, ary);
return ST_CONTINUE;
}
@@ -853,7 +876,8 @@ wrap_klass_iow(VALUE klass)
if (!RTEST(klass)) {
return Qnil;
}
- else if (RB_TYPE_P(klass, T_ICLASS)) {
+ else if (RB_TYPE_P(klass, T_ICLASS) ||
+ CLASS_OF(klass) == Qfalse /* hidden object */) {
return iow_newobj(klass);
}
else {
@@ -879,8 +903,13 @@ objspace_internal_class_of(VALUE self, VALUE obj)
obj = (VALUE)DATA_PTR(obj);
}
- klass = CLASS_OF(obj);
- return wrap_klass_iow(klass);
+ if (RB_TYPE_P(obj, T_IMEMO)) {
+ return Qnil;
+ }
+ else {
+ klass = CLASS_OF(obj);
+ return wrap_klass_iow(klass);
+ }
}
/*
@@ -935,6 +964,7 @@ void Init_objspace_dump(VALUE rb_mObjSpace);
void
Init_objspace(void)
{
+#undef rb_intern
VALUE rb_mObjSpace;
#if 0
rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */
@@ -965,10 +995,11 @@ Init_objspace(void)
*
* You can use the #type method to check the type of the internal object.
*/
- rb_mInternalObjectWrapper = rb_define_class_under(rb_mObjSpace, "InternalObjectWrapper", rb_cObject);
- rb_define_method(rb_mInternalObjectWrapper, "type", iow_type, 0);
- rb_define_method(rb_mInternalObjectWrapper, "inspect", iow_inspect, 0);
- rb_define_method(rb_mInternalObjectWrapper, "internal_object_id", iow_internal_object_id, 0);
+ rb_cInternalObjectWrapper = rb_define_class_under(rb_mObjSpace, "InternalObjectWrapper", rb_cObject);
+ rb_undef_alloc_func(rb_cInternalObjectWrapper);
+ rb_define_method(rb_cInternalObjectWrapper, "type", iow_type, 0);
+ rb_define_method(rb_cInternalObjectWrapper, "inspect", iow_inspect, 0);
+ rb_define_method(rb_cInternalObjectWrapper, "internal_object_id", iow_internal_object_id, 0);
Init_object_tracing(rb_mObjSpace);
Init_objspace_dump(rb_mObjSpace);
diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c
index f9dda1ac1a..544d11e254 100644
--- a/ext/objspace/objspace_dump.c
+++ b/ext/objspace/objspace_dump.c
@@ -12,43 +12,169 @@
**********************************************************************/
+#include "gc.h"
#include "internal.h"
+#include "internal/hash.h"
+#include "internal/string.h"
+#include "internal/sanitizers.h"
+#include "node.h"
+#include "objspace.h"
#include "ruby/debug.h"
+#include "ruby/util.h"
#include "ruby/io.h"
-#include "gc.h"
-#include "node.h"
#include "vm_core.h"
-#include "objspace.h"
-static VALUE sym_output, sym_stdout, sym_string, sym_file;
-static VALUE sym_full;
+RUBY_EXTERN const char ruby_hexdigits[];
+
+#define BUFFER_CAPACITY 4096
struct dump_config {
VALUE type;
- FILE *stream;
+ VALUE stream;
VALUE string;
- int roots;
const char *root_category;
VALUE cur_obj;
VALUE cur_obj_klass;
size_t cur_obj_references;
- int full_heap;
+ unsigned int roots: 1;
+ unsigned int full_heap: 1;
+ unsigned int partial_dump;
+ size_t since;
+ unsigned long buffer_len;
+ char buffer[BUFFER_CAPACITY];
};
-PRINTF_ARGS(static void dump_append(struct dump_config *, const char *, ...), 2, 3);
static void
-dump_append(struct dump_config *dc, const char *format, ...)
+dump_flush(struct dump_config *dc)
+{
+ if (dc->buffer_len) {
+ if (dc->stream) {
+ size_t written = rb_io_bufwrite(dc->stream, dc->buffer, dc->buffer_len);
+ if (written < dc->buffer_len) {
+ MEMMOVE(dc->buffer, dc->buffer + written, char, dc->buffer_len - written);
+ dc->buffer_len -= written;
+ return;
+ }
+ }
+ else if (dc->string) {
+ rb_str_cat(dc->string, dc->buffer, dc->buffer_len);
+ }
+ dc->buffer_len = 0;
+ }
+}
+
+static inline void
+buffer_ensure_capa(struct dump_config *dc, unsigned long requested)
+{
+ RUBY_ASSERT(requested <= BUFFER_CAPACITY);
+ if (requested + dc->buffer_len >= BUFFER_CAPACITY) {
+ dump_flush(dc);
+ if (requested + dc->buffer_len >= BUFFER_CAPACITY) {
+ rb_raise(rb_eIOError, "full buffer");
+ }
+ }
+}
+
+static void buffer_append(struct dump_config *dc, const char *cstr, unsigned long len)
+{
+ if (LIKELY(len > 0)) {
+ buffer_ensure_capa(dc, len);
+ MEMCPY(dc->buffer + dc->buffer_len, cstr, char, len);
+ dc->buffer_len += len;
+ }
+}
+
+# define dump_append(dc, str) buffer_append(dc, (str), (long)strlen(str))
+
+static void
+dump_append_ld(struct dump_config *dc, const long number)
+{
+ const int width = DECIMAL_SIZE_OF_BITS(sizeof(number) * CHAR_BIT - 1) + 2;
+ buffer_ensure_capa(dc, width);
+ unsigned long required = snprintf(dc->buffer + dc->buffer_len, width, "%ld", number);
+ RUBY_ASSERT(required <= width);
+ dc->buffer_len += required;
+}
+
+static void
+dump_append_lu(struct dump_config *dc, const unsigned long number)
+{
+ const int width = DECIMAL_SIZE_OF_BITS(sizeof(number) * CHAR_BIT) + 1;
+ buffer_ensure_capa(dc, width);
+ unsigned long required = snprintf(dc->buffer + dc->buffer_len, width, "%lu", number);
+ RUBY_ASSERT(required <= width);
+ dc->buffer_len += required;
+}
+
+static void
+dump_append_g(struct dump_config *dc, const double number)
{
- va_list vl;
- va_start(vl, format);
+ unsigned long capa_left = BUFFER_CAPACITY - dc->buffer_len;
+ unsigned long required = snprintf(dc->buffer + dc->buffer_len, capa_left, "%#g", number);
- if (dc->stream) {
- vfprintf(dc->stream, format, vl);
+ if (required >= capa_left) {
+ buffer_ensure_capa(dc, required);
+ capa_left = BUFFER_CAPACITY - dc->buffer_len;
+ snprintf(dc->buffer + dc->buffer_len, capa_left, "%#g", number);
}
- else if (dc->string)
- rb_str_vcatf(dc->string, format, vl);
+ dc->buffer_len += required;
+}
+
+static void
+dump_append_d(struct dump_config *dc, const int number)
+{
+ const int width = DECIMAL_SIZE_OF_BITS(sizeof(number) * CHAR_BIT - 1) + 2;
+ buffer_ensure_capa(dc, width);
+ unsigned long required = snprintf(dc->buffer + dc->buffer_len, width, "%d", number);
+ RUBY_ASSERT(required <= width);
+ dc->buffer_len += required;
+}
+
+static void
+dump_append_sizet(struct dump_config *dc, const size_t number)
+{
+ const int width = DECIMAL_SIZE_OF_BITS(sizeof(number) * CHAR_BIT) + 1;
+ buffer_ensure_capa(dc, width);
+ unsigned long required = snprintf(dc->buffer + dc->buffer_len, width, "%"PRIuSIZE, number);
+ RUBY_ASSERT(required <= width);
+ dc->buffer_len += required;
+}
- va_end(vl);
+static void
+dump_append_c(struct dump_config *dc, char c)
+{
+ if (c <= 0x1f) {
+ const int width = (sizeof(c) * CHAR_BIT / 4) + 5;
+ buffer_ensure_capa(dc, width);
+ unsigned long required = snprintf(dc->buffer + dc->buffer_len, width, "\\u00%02x", c);
+ RUBY_ASSERT(required <= width);
+ dc->buffer_len += required;
+ }
+ else {
+ buffer_ensure_capa(dc, 1);
+ dc->buffer[dc->buffer_len] = c;
+ dc->buffer_len++;
+ }
+}
+
+static void
+dump_append_ref(struct dump_config *dc, VALUE ref)
+{
+ RUBY_ASSERT(ref > 0);
+
+ char buffer[((sizeof(VALUE) * CHAR_BIT + 3) / 4) + 4];
+ char *buffer_start, *buffer_end;
+
+ buffer_start = buffer_end = &buffer[sizeof(buffer)];
+ *--buffer_start = '"';
+ while (ref) {
+ *--buffer_start = ruby_hexdigits[ref & 0xF];
+ ref >>= 4;
+ }
+ *--buffer_start = 'x';
+ *--buffer_start = '0';
+ *--buffer_start = '"';
+ buffer_append(dc, buffer_start, buffer_end - buffer_start);
}
static void
@@ -60,35 +186,37 @@ dump_append_string_value(struct dump_config *dc, VALUE obj)
dump_append(dc, "\"");
for (i = 0, value = RSTRING_PTR(obj); i < RSTRING_LEN(obj); i++) {
- switch ((c = value[i])) {
- case '\\':
- case '"':
- dump_append(dc, "\\%c", c);
- break;
- case '\0':
- dump_append(dc, "\\u0000");
- break;
- case '\b':
- dump_append(dc, "\\b");
- break;
- case '\t':
- dump_append(dc, "\\t");
- break;
- case '\f':
- dump_append(dc, "\\f");
- break;
- case '\n':
- dump_append(dc, "\\n");
- break;
- case '\r':
- dump_append(dc, "\\r");
- break;
- default:
- if (c <= 0x1f)
- dump_append(dc, "\\u%04d", c);
- else
- dump_append(dc, "%c", c);
- }
+ switch ((c = value[i])) {
+ case '\\':
+ dump_append(dc, "\\\\");
+ break;
+ case '"':
+ dump_append(dc, "\\\"");
+ break;
+ case '\0':
+ dump_append(dc, "\\u0000");
+ break;
+ case '\b':
+ dump_append(dc, "\\b");
+ break;
+ case '\t':
+ dump_append(dc, "\\t");
+ break;
+ case '\f':
+ dump_append(dc, "\\f");
+ break;
+ case '\n':
+ dump_append(dc, "\\n");
+ break;
+ case '\r':
+ dump_append(dc, "\\r");
+ break;
+ case '\177':
+ dump_append(dc, "\\u007f");
+ break;
+ default:
+ dump_append_c(dc, c);
+ }
}
dump_append(dc, "\"");
}
@@ -133,6 +261,7 @@ obj_type(VALUE obj)
CASE_TYPE(NODE);
CASE_TYPE(ZOMBIE);
#undef CASE_TYPE
+ default: break;
}
return "UNKNOWN";
}
@@ -141,25 +270,25 @@ static void
dump_append_special_const(struct dump_config *dc, VALUE value)
{
if (value == Qtrue) {
- dump_append(dc, "true");
+ dump_append(dc, "true");
}
else if (value == Qfalse) {
- dump_append(dc, "false");
+ dump_append(dc, "false");
}
else if (value == Qnil) {
- dump_append(dc, "null");
+ dump_append(dc, "null");
}
else if (FIXNUM_P(value)) {
- dump_append(dc, "%ld", FIX2LONG(value));
+ dump_append_ld(dc, FIX2LONG(value));
}
else if (FLONUM_P(value)) {
- dump_append(dc, "%#g", RFLOAT_VALUE(value));
+ dump_append_g(dc, RFLOAT_VALUE(value));
}
else if (SYMBOL_P(value)) {
- dump_append_symbol_value(dc, value);
+ dump_append_symbol_value(dc, value);
}
else {
- dump_append(dc, "{}");
+ dump_append(dc, "{}");
}
}
@@ -169,12 +298,16 @@ reachable_object_i(VALUE ref, void *data)
struct dump_config *dc = (struct dump_config *)data;
if (dc->cur_obj_klass == ref)
- return;
+ return;
- if (dc->cur_obj_references == 0)
- dump_append(dc, ", \"references\":[\"%p\"", (void *)ref);
- else
- dump_append(dc, ", \"%p\"", (void *)ref);
+ if (dc->cur_obj_references == 0) {
+ dump_append(dc, ", \"references\":[");
+ dump_append_ref(dc, ref);
+ }
+ else {
+ dump_append(dc, ", ");
+ dump_append_ref(dc, ref);
+ }
dc->cur_obj_references++;
}
@@ -182,32 +315,16 @@ reachable_object_i(VALUE ref, void *data)
static void
dump_append_string_content(struct dump_config *dc, VALUE obj)
{
- dump_append(dc, ", \"bytesize\":%ld", RSTRING_LEN(obj));
- if (!STR_EMBED_P(obj) && !STR_SHARED_P(obj) && (long)rb_str_capacity(obj) != RSTRING_LEN(obj))
- dump_append(dc, ", \"capacity\":%"PRIuSIZE, rb_str_capacity(obj));
-
- if (is_ascii_string(obj)) {
- dump_append(dc, ", \"value\":");
- dump_append_string_value(dc, obj);
+ dump_append(dc, ", \"bytesize\":");
+ dump_append_ld(dc, RSTRING_LEN(obj));
+ if (!STR_EMBED_P(obj) && !STR_SHARED_P(obj) && (long)rb_str_capacity(obj) != RSTRING_LEN(obj)) {
+ dump_append(dc, ", \"capacity\":");
+ dump_append_sizet(dc, rb_str_capacity(obj));
}
-}
-static const char *
-imemo_name(int imemo)
-{
- switch(imemo) {
-#define TYPE_STR(t) case(imemo_##t): return #t
- TYPE_STR(env);
- TYPE_STR(cref);
- TYPE_STR(svar);
- TYPE_STR(throw_data);
- TYPE_STR(ifunc);
- TYPE_STR(memo);
- TYPE_STR(ment);
- TYPE_STR(iseq);
- default:
- return "unknown";
-#undef TYPE_STR
+ if (is_ascii_string(obj)) {
+ dump_append(dc, ", \"value\":");
+ dump_append_string_value(dc, obj);
}
}
@@ -215,130 +332,177 @@ static void
dump_object(VALUE obj, struct dump_config *dc)
{
size_t memsize;
- struct allocation_info *ainfo;
+ struct allocation_info *ainfo = objspace_lookup_allocation_info(obj);
rb_io_t *fptr;
ID flags[RB_OBJ_GC_FLAGS_MAX];
size_t n, i;
if (SPECIAL_CONST_P(obj)) {
- dump_append_special_const(dc, obj);
- return;
+ dump_append_special_const(dc, obj);
+ return;
}
dc->cur_obj = obj;
dc->cur_obj_references = 0;
dc->cur_obj_klass = BUILTIN_TYPE(obj) == T_NODE ? 0 : RBASIC_CLASS(obj);
+ if (dc->partial_dump && (!ainfo || ainfo->generation < dc->since)) {
+ return;
+ }
+
if (dc->cur_obj == dc->string)
- return;
+ return;
+
+ dump_append(dc, "{\"address\":");
+ dump_append_ref(dc, obj);
- dump_append(dc, "{\"address\":\"%p\", \"type\":\"%s\"", (void *)obj, obj_type(obj));
+ dump_append(dc, ", \"type\":\"");
+ dump_append(dc, obj_type(obj));
+ dump_append(dc, "\"");
- if (dc->cur_obj_klass)
- dump_append(dc, ", \"class\":\"%p\"", (void *)dc->cur_obj_klass);
+ if (dc->cur_obj_klass) {
+ dump_append(dc, ", \"class\":");
+ dump_append_ref(dc, dc->cur_obj_klass);
+ }
if (rb_obj_frozen_p(obj))
- dump_append(dc, ", \"frozen\":true");
+ dump_append(dc, ", \"frozen\":true");
switch (BUILTIN_TYPE(obj)) {
case T_NONE:
- dump_append(dc, "}\n");
- return;
-
- case T_NODE:
- dump_append(dc, ", \"node_type\":\"%s\"", ruby_node_name(nd_type(obj)));
- break;
+ dump_append(dc, "}\n");
+ return;
case T_IMEMO:
- dump_append(dc, ", \"imemo_type\":\"%s\"", imemo_name(imemo_type(obj)));
- break;
+ dump_append(dc, ", \"imemo_type\":\"");
+ dump_append(dc, rb_imemo_name(imemo_type(obj)));
+ dump_append(dc, "\"");
+ break;
case T_SYMBOL:
- dump_append_string_content(dc, rb_sym2str(obj));
- break;
+ dump_append_string_content(dc, rb_sym2str(obj));
+ break;
case T_STRING:
- if (STR_EMBED_P(obj))
- dump_append(dc, ", \"embedded\":true");
- if (is_broken_string(obj))
- dump_append(dc, ", \"broken\":true");
- if (FL_TEST(obj, RSTRING_FSTR))
- dump_append(dc, ", \"fstring\":true");
- if (STR_SHARED_P(obj))
- dump_append(dc, ", \"shared\":true");
- else
- dump_append_string_content(dc, obj);
-
- if (!ENCODING_IS_ASCII8BIT(obj))
- dump_append(dc, ", \"encoding\":\"%s\"", rb_enc_name(rb_enc_from_index(ENCODING_GET(obj))));
- break;
+ if (STR_EMBED_P(obj))
+ dump_append(dc, ", \"embedded\":true");
+ if (is_broken_string(obj))
+ dump_append(dc, ", \"broken\":true");
+ if (FL_TEST(obj, RSTRING_FSTR))
+ dump_append(dc, ", \"fstring\":true");
+ if (STR_SHARED_P(obj))
+ dump_append(dc, ", \"shared\":true");
+ else
+ dump_append_string_content(dc, obj);
+
+ if (!ENCODING_IS_ASCII8BIT(obj)) {
+ dump_append(dc, ", \"encoding\":\"");
+ dump_append(dc, rb_enc_name(rb_enc_from_index(ENCODING_GET(obj))));
+ dump_append(dc, "\"");
+ }
+ break;
case T_HASH:
- dump_append(dc, ", \"size\":%"PRIuSIZE, (size_t)RHASH_SIZE(obj));
- if (FL_TEST(obj, HASH_PROC_DEFAULT))
- dump_append(dc, ", \"default\":\"%p\"", (void *)RHASH_IFNONE(obj));
- break;
+ dump_append(dc, ", \"size\":");
+ dump_append_sizet(dc, (size_t)RHASH_SIZE(obj));
+ if (FL_TEST(obj, RHASH_PROC_DEFAULT)) {
+ dump_append(dc, ", \"default\":");
+ dump_append_ref(dc, RHASH_IFNONE(obj));
+ }
+ break;
case T_ARRAY:
- dump_append(dc, ", \"length\":%ld", RARRAY_LEN(obj));
- if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, ELTS_SHARED))
- dump_append(dc, ", \"shared\":true");
- if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, RARRAY_EMBED_FLAG))
- dump_append(dc, ", \"embedded\":true");
- break;
+ dump_append(dc, ", \"length\":");
+ dump_append_ld(dc, RARRAY_LEN(obj));
+ if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, ELTS_SHARED))
+ dump_append(dc, ", \"shared\":true");
+ if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, RARRAY_EMBED_FLAG))
+ dump_append(dc, ", \"embedded\":true");
+ break;
case T_CLASS:
case T_MODULE:
- if (dc->cur_obj_klass)
- dump_append(dc, ", \"name\":\"%s\"", rb_class2name(obj));
- break;
+ if (dc->cur_obj_klass) {
+ VALUE mod_name = rb_mod_name(obj);
+ if (!NIL_P(mod_name)) {
+ dump_append(dc, ", \"name\":\"");
+ dump_append(dc, RSTRING_PTR(mod_name));
+ dump_append(dc, "\"");
+ }
+ }
+ break;
case T_DATA:
- if (RTYPEDDATA_P(obj))
- dump_append(dc, ", \"struct\":\"%s\"", RTYPEDDATA_TYPE(obj)->wrap_struct_name);
- break;
+ if (RTYPEDDATA_P(obj)) {
+ dump_append(dc, ", \"struct\":\"");
+ dump_append(dc, RTYPEDDATA_TYPE(obj)->wrap_struct_name);
+ dump_append(dc, "\"");
+ }
+ break;
case T_FLOAT:
- dump_append(dc, ", \"value\":\"%g\"", RFLOAT_VALUE(obj));
- break;
+ dump_append(dc, ", \"value\":\"");
+ dump_append_g(dc, RFLOAT_VALUE(obj));
+ dump_append(dc, "\"");
+ break;
case T_OBJECT:
- dump_append(dc, ", \"ivars\":%u", ROBJECT_NUMIV(obj));
- break;
+ dump_append(dc, ", \"ivars\":");
+ dump_append_lu(dc, ROBJECT_NUMIV(obj));
+ break;
case T_FILE:
- fptr = RFILE(obj)->fptr;
- if (fptr)
- dump_append(dc, ", \"fd\":%d", fptr->fd);
- break;
+ fptr = RFILE(obj)->fptr;
+ if (fptr) {
+ dump_append(dc, ", \"fd\":");
+ dump_append_d(dc, fptr->fd);
+ }
+ break;
case T_ZOMBIE:
- dump_append(dc, "}\n");
- return;
+ dump_append(dc, "}\n");
+ return;
+
+ default:
+ break;
}
rb_objspace_reachable_objects_from(obj, reachable_object_i, dc);
if (dc->cur_obj_references > 0)
- dump_append(dc, "]");
-
- if ((ainfo = objspace_lookup_allocation_info(obj))) {
- dump_append(dc, ", \"file\":\"%s\", \"line\":%lu", ainfo->path, ainfo->line);
- if (RTEST(ainfo->mid)) {
- VALUE m = rb_sym2str(ainfo->mid);
- dump_append(dc, ", \"method\":\"%s\"", RSTRING_PTR(m));
- }
- dump_append(dc, ", \"generation\":%"PRIuSIZE, ainfo->generation);
+ dump_append(dc, "]");
+
+ if (ainfo) {
+ if (ainfo->path) {
+ dump_append(dc, ", \"file\":\"");
+ dump_append(dc, ainfo->path);
+ dump_append(dc, "\"");
+ }
+ if (ainfo->line) {
+ dump_append(dc, ", \"line\":");
+ dump_append_lu(dc, ainfo->line);
+ }
+ if (RTEST(ainfo->mid)) {
+ VALUE m = rb_sym2str(ainfo->mid);
+ dump_append(dc, ", \"method\":");
+ dump_append_string_value(dc, m);
+ }
+ dump_append(dc, ", \"generation\":");
+ dump_append_sizet(dc, ainfo->generation);
}
- if ((memsize = rb_obj_memsize_of(obj)) > 0)
- dump_append(dc, ", \"memsize\":%"PRIuSIZE, memsize);
+ if ((memsize = rb_obj_memsize_of(obj)) > 0) {
+ dump_append(dc, ", \"memsize\":");
+ dump_append_sizet(dc, memsize);
+ }
if ((n = rb_obj_gc_flags(obj, flags, sizeof(flags))) > 0) {
- dump_append(dc, ", \"flags\":{");
- for (i=0; i<n; i++) {
- dump_append(dc, "\"%s\":true", rb_id2name(flags[i]));
- if (i != n-1) dump_append(dc, ", ");
- }
- dump_append(dc, "}");
+ dump_append(dc, ", \"flags\":{");
+ for (i=0; i<n; i++) {
+ dump_append(dc, "\"");
+ dump_append(dc, rb_id2name(flags[i]));
+ dump_append(dc, "\":true");
+ if (i != n-1) dump_append(dc, ", ");
+ }
+ dump_append(dc, "}");
}
dump_append(dc, "}\n");
@@ -350,8 +514,15 @@ heap_i(void *vstart, void *vend, size_t stride, void *data)
struct dump_config *dc = (struct dump_config *)data;
VALUE v = (VALUE)vstart;
for (; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
if (dc->full_heap || RBASIC(v)->flags)
dump_object(v, dc);
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
}
return 0;
}
@@ -362,155 +533,101 @@ root_obj_i(const char *category, VALUE obj, void *data)
struct dump_config *dc = (struct dump_config *)data;
if (dc->root_category != NULL && category != dc->root_category)
- dump_append(dc, "]}\n");
- if (dc->root_category == NULL || category != dc->root_category)
- dump_append(dc, "{\"type\":\"ROOT\", \"root\":\"%s\", \"references\":[\"%p\"", category, (void *)obj);
- else
- dump_append(dc, ", \"%p\"", (void *)obj);
+ dump_append(dc, "]}\n");
+ if (dc->root_category == NULL || category != dc->root_category) {
+ dump_append(dc, "{\"type\":\"ROOT\", \"root\":\"");
+ dump_append(dc, category);
+ dump_append(dc, "\", \"references\":[");
+ dump_append_ref(dc, obj);
+ }
+ else {
+ dump_append(dc, ", ");
+ dump_append_ref(dc, obj);
+ }
dc->root_category = category;
- dc->roots++;
+ dc->roots = 1;
}
-static VALUE
-dump_output(struct dump_config *dc, VALUE opts, VALUE output, const char *filename)
+static void
+dump_output(struct dump_config *dc, VALUE output, VALUE full, VALUE since)
{
- VALUE tmp;
dc->full_heap = 0;
-
- if (RTEST(opts)) {
- output = rb_hash_aref(opts, sym_output);
-
- if (Qtrue == rb_hash_lookup2(opts, sym_full, Qfalse))
- dc->full_heap = 1;
+ dc->buffer_len = 0;
+
+ if (TYPE(output) == T_STRING) {
+ dc->stream = Qfalse;
+ dc->string = output;
+ } else {
+ dc->stream = output;
+ dc->string = Qfalse;
}
- if (output == sym_stdout) {
- dc->stream = stdout;
- dc->string = Qnil;
+ if (full == Qtrue) {
+ dc->full_heap = 1;
}
- else if (output == sym_file) {
- rb_io_t *fptr;
- rb_require("tempfile");
- tmp = rb_assoc_new(rb_str_new_cstr(filename), rb_str_new_cstr(".json"));
- tmp = rb_funcallv(rb_path2class("Tempfile"), rb_intern("create"), 1, &tmp);
- io:
- dc->string = rb_io_get_write_io(tmp);
- rb_io_flush(dc->string);
- GetOpenFile(dc->string, fptr);
- dc->stream = rb_io_stdio_file(fptr);
- }
- else if (output == sym_string) {
- dc->string = rb_str_new_cstr("");
- }
- else if (!NIL_P(tmp = rb_io_check_io(output))) {
- output = sym_file;
- goto io;
- }
- else {
- rb_raise(rb_eArgError, "wrong output option: %"PRIsVALUE, output);
+
+ if (RTEST(since)) {
+ dc->partial_dump = 1;
+ dc->since = NUM2SIZET(since);
+ } else {
+ dc->partial_dump = 0;
}
- return output;
}
static VALUE
-dump_result(struct dump_config *dc, VALUE output)
+dump_result(struct dump_config *dc)
{
- if (output == sym_string) {
- return rb_str_resurrect(dc->string);
- }
- else if (output == sym_file) {
- rb_io_flush(dc->string);
- return dc->string;
- }
- else {
- return Qnil;
+ dump_flush(dc);
+
+ if (dc->string) {
+ return dc->string;
+ } else {
+ rb_io_flush(dc->stream);
+ return dc->stream;
}
}
-/*
- * call-seq:
- * ObjectSpace.dump(obj[, output: :string]) # => "{ ... }"
- * ObjectSpace.dump(obj, output: :file) # => #<File:/tmp/rubyobj20131125-88733-1xkfmpv.json>
- * ObjectSpace.dump(obj, output: :stdout) # => nil
- *
- * Dump the contents of a ruby object as JSON.
- *
- * This method is only expected to work with C Ruby.
- * This is an experimental method and is subject to change.
- * In particular, the function signature and output format are
- * not guaranteed to be compatible in future versions of ruby.
- */
-
static VALUE
-objspace_dump(int argc, VALUE *argv, VALUE os)
+objspace_dump(VALUE os, VALUE obj, VALUE output)
{
- static const char filename[] = "rubyobj";
- VALUE obj = Qnil, opts = Qnil, output;
struct dump_config dc = {0,};
-
- rb_scan_args(argc, argv, "1:", &obj, &opts);
-
- output = dump_output(&dc, opts, sym_string, filename);
+ dump_output(&dc, output, Qnil, Qnil);
dump_object(obj, &dc);
- return dump_result(&dc, output);
+ return dump_result(&dc);
}
-/*
- * call-seq:
- * ObjectSpace.dump_all([output: :file]) # => #<File:/tmp/rubyheap20131125-88469-laoj3v.json>
- * ObjectSpace.dump_all(output: :stdout) # => nil
- * ObjectSpace.dump_all(output: :string) # => "{...}\n{...}\n..."
- * ObjectSpace.dump_all(output:
- * File.open('heap.json','w')) # => #<File:heap.json>
- *
- * Dump the contents of the ruby heap as JSON.
- *
- * This method is only expected to work with C Ruby.
- * This is an experimental method and is subject to change.
- * In particular, the function signature and output format are
- * not guaranteed to be compatible in future versions of ruby.
- */
-
static VALUE
-objspace_dump_all(int argc, VALUE *argv, VALUE os)
+objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since)
{
- static const char filename[] = "rubyheap";
- VALUE opts = Qnil, output;
struct dump_config dc = {0,};
+ dump_output(&dc, output, full, since);
- rb_scan_args(argc, argv, "0:", &opts);
-
- output = dump_output(&dc, opts, sym_file, filename);
-
- /* dump roots */
- rb_objspace_reachable_objects_from_root(root_obj_i, &dc);
- if (dc.roots) dump_append(&dc, "]}\n");
+ if (!dc.partial_dump || dc.since == 0) {
+ /* dump roots */
+ rb_objspace_reachable_objects_from_root(root_obj_i, &dc);
+ if (dc.roots) dump_append(&dc, "]}\n");
+ }
/* dump all objects */
rb_objspace_each_objects(heap_i, &dc);
- return dump_result(&dc, output);
+ return dump_result(&dc);
}
void
Init_objspace_dump(VALUE rb_mObjSpace)
{
+#undef rb_intern
#if 0
rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */
#endif
- rb_define_module_function(rb_mObjSpace, "dump", objspace_dump, -1);
- rb_define_module_function(rb_mObjSpace, "dump_all", objspace_dump_all, -1);
-
- sym_output = ID2SYM(rb_intern("output"));
- sym_stdout = ID2SYM(rb_intern("stdout"));
- sym_string = ID2SYM(rb_intern("string"));
- sym_file = ID2SYM(rb_intern("file"));
- sym_full = ID2SYM(rb_intern("full"));
+ rb_define_module_function(rb_mObjSpace, "_dump", objspace_dump, 2);
+ rb_define_module_function(rb_mObjSpace, "_dump_all", objspace_dump_all, 3);
/* force create static IDs */
rb_obj_gc_flags(rb_mObjSpace, 0, 0);
diff --git a/ext/openssl/History.md b/ext/openssl/History.md
index 4e12682c64..60b9dd8825 100644
--- a/ext/openssl/History.md
+++ b/ext/openssl/History.md
@@ -1,18 +1,179 @@
-Version 2.1.0.beta1
-===================
+Version 2.2.2
+=============
+
+Merged changes in 2.1.4.
+
+
+Version 2.2.1
+=============
+
+Merged changes in 2.1.3. Additionally, the following issues are fixed by this
+release.
+
+Bug fixes
+---------
+
+* Fix crash in `OpenSSL::Timestamp::{Request,Response,TokenInfo}.new` when
+ invalid arguments are given.
+ [[GitHub #407]](https://github.com/ruby/openssl/pull/407)
+* Fix `OpenSSL::Timestamp::Factory#create_timestamp` with LibreSSL on platforms
+ where `time_t` has a different size from `long`.
+ [[GitHub #454]](https://github.com/ruby/openssl/pull/454)
+
+
+Version 2.2.0
+=============
+
+Compatibility notes
+-------------------
+
+* Remove unsupported MDC2, DSS, DSS1, and SHA algorithms.
+* Remove `OpenSSL::PKCS7::SignerInfo#name` alias for `#issuer`.
+ [[GitHub #266]](https://github.com/ruby/openssl/pull/266)
+* Deprecate `OpenSSL::Config#add_value` and `#[]=` for future removal.
+ [[GitHub #322]](https://github.com/ruby/openssl/pull/322)
+
+
+Notable changes
+---------------
+
+* Change default `OpenSSL::SSL::SSLServer#listen` backlog argument from
+ 5 to `Socket::SOMAXCONN`.
+ [[GitHub #286]](https://github.com/ruby/openssl/issues/286)
+* Make `OpenSSL::HMAC#==` use a timing safe string comparison.
+ [[GitHub #284]](https://github.com/ruby/openssl/pull/284)
+* Add support for SHA3 and BLAKE digests.
+ [[GitHub #282]](https://github.com/ruby/openssl/pull/282)
+* Add `OpenSSL::SSL::SSLSocket.open` for opening a `TCPSocket` and
+ returning an `OpenSSL::SSL::SSLSocket` for it.
+ [[GitHub #225]](https://github.com/ruby/openssl/issues/225)
+* Support marshalling of `OpenSSL::X509` and `OpenSSL::PKey` objects.
+ [[GitHub #281]](https://github.com/ruby/openssl/pull/281)
+ [[GitHub #363]](https://github.com/ruby/openssl/pull/363)
+* Add `OpenSSL.secure_compare` for timing safe string comparison for
+ strings of possibly unequal length.
+ [[GitHub #280]](https://github.com/ruby/openssl/pull/280)
+* Add `OpenSSL.fixed_length_secure_compare` for timing safe string
+ comparison for strings of equal length.
+ [[GitHub #269]](https://github.com/ruby/openssl/pull/269)
+* Add `OpenSSL::SSL::SSLSocket#{finished_message,peer_finished_message}`
+ for last finished message sent and received.
+ [[GitHub #250]](https://github.com/ruby/openssl/pull/250)
+* Add `OpenSSL::Timestamp` module for handing timestamp requests and
+ responses.
+ [[GitHub #204]](https://github.com/ruby/openssl/pull/204)
+* Add helper methods for `OpenSSL::X509::Certificate`:
+ `find_extension`, `subject_key_identifier`,
+ `authority_key_identifier`, `crl_uris`, `ca_issuer_uris` and
+ `ocsp_uris`, and for `OpenSSL::X509::CRL`:
+ `find_extension` and `subject_key_identifier`.
+ [[GitHub #260]](https://github.com/ruby/openssl/pull/260)
+ [[GitHub #275]](https://github.com/ruby/openssl/pull/275)
+ [[GitHub #293]](https://github.com/ruby/openssl/pull/293)
+* Add `OpenSSL::ECPoint#add` for performing elliptic curve point addition.
+ [[GitHub #261]](https://github.com/ruby/openssl/pull/261)
+* Make `OpenSSL::PKey::RSA#{export,to_der}` check `key`, `factors`, and
+ `crt_params` to do proper private key serialization.
+ [[GitHub #258]](https://github.com/ruby/openssl/pull/258)
+* Add `OpenSSL::SSL::{SSLSocket,SSLServer}#fileno`, returning the
+ underlying socket file descriptor number.
+ [[GitHub #247]](https://github.com/ruby/openssl/pull/247)
+* Support client certificates with TLS 1.3, and support post-handshake
+ authentication with OpenSSL 1.1.1+.
+ [[GitHub #239]](https://github.com/ruby/openssl/pull/239)
+* Add `OpenSSL::ASN1::ObjectId#==` for equality testing.
+* Add `OpenSSL::X509::Extension#value_der` for the raw value of
+ the extension.
+ [[GitHub #234]](https://github.com/ruby/openssl/pull/234)
+* Significantly reduce allocated memory in `OpenSSL::Buffering#do_write`.
+ [[GitHub #212]](https://github.com/ruby/openssl/pull/212)
+* Ensure all valid IPv6 addresses are considered valid as elements
+ of subjectAlternativeName in certificates.
+ [[GitHub #185]](https://github.com/ruby/openssl/pull/185)
+* Allow recipient's certificate to be omitted in PCKS7#decrypt.
+ [[GitHub #183]](https://github.com/ruby/openssl/pull/183)
+* Add support for reading keys in PKCS #8 format and export via instance methods
+ added to `OpenSSL::PKey` classes: `private_to_der`, `private_to_pem`,
+ `public_to_der` and `public_to_pem`.
+ [[GitHub #297]](https://github.com/ruby/openssl/pull/297)
+
+
+Version 2.1.4
+=============
+
+Bug fixes
+---------
+
+* Do not use pkg-config if --with-openssl-dir option is specified.
+ [[GitHub #486]](https://github.com/ruby/openssl/pull/486)
+
+
+Version 2.1.3
+=============
+
+Bug fixes
+---------
+
+* Fix deprecation warnings on Ruby 3.0.
+* Add ".include" directive support in `OpenSSL::Config`.
+ [[GitHub #216]](https://github.com/ruby/openssl/pull/216)
+* Fix handling of IPv6 address SANs.
+ [[GitHub #185]](https://github.com/ruby/openssl/pull/185)
+* Hostname verification failure with `OpenSSL::SSL::SSLContext#verify_hostname=`
+ sets a proper error code.
+ [[GitHub #350]](https://github.com/ruby/openssl/pull/350)
+* Fix crash with `OpenSSL::BN.new(nil, 2)`.
+ [[Bug #15760]](https://bugs.ruby-lang.org/issues/15760)
+* `OpenSSL::SSL::SSLSocket#sys{read,write}` prevent internal string buffers from
+ being modified by another thread.
+ [[GitHub #453]](https://github.com/ruby/openssl/pull/453)
+* Fix misuse of input record separator in `OpenSSL::Buffering` where it was
+ for output.
+* Fix wrong interger casting in `OpenSSL::PKey::EC#dsa_verify_asn1`.
+ [[GitHub #460]](https://github.com/ruby/openssl/pull/460)
+* `extconf.rb` explicitly checks that OpenSSL's version number is 1.0.1 or
+ newer but also less than 3.0. Ruby/OpenSSL v2.1.x and v2.2.x will not support
+ OpenSSL 3.0 API.
+ [[GitHub #458]](https://github.com/ruby/openssl/pull/458)
+* Activate `digest` gem correctly. `digest` library could go into an
+ inconsistent state if there are multiple versions of `digest` is installed
+ and `openssl` is `require`d before `digest`.
+ [[GitHub #463]](https://github.com/ruby/openssl/pull/463)
+* Fix GC.compact compatibility.
+ [[GitHub #464]](https://github.com/ruby/openssl/issues/464)
+ [[GitHub #465]](https://github.com/ruby/openssl/pull/465)
+
+
+Version 2.1.2
+=============
+
+Merged changes in 2.0.9.
+
+
+Version 2.1.1
+=============
+
+Merged changes in 2.0.8.
+
+
+Version 2.1.0
+=============
Notable changes
---------------
-* Support for OpenSSL versions before 1.0.1 is removed.
+* Support for OpenSSL versions before 1.0.1 and LibreSSL versions before 2.5
+ is removed.
[[GitHub #86]](https://github.com/ruby/openssl/pull/86)
* OpenSSL::BN#negative?, #+@, and #-@ are added.
* OpenSSL::SSL::SSLSocket#connect raises a more informative exception when
certificate verification fails.
[[GitHub #99]](https://github.com/ruby/openssl/pull/99)
-* OpenSSL::KDF module is newly added. Support for scrypt is added.
+* OpenSSL::KDF module is newly added. In addition to PBKDF2-HMAC that has moved
+ from OpenSSL::PKCS5, scrypt and HKDF are supported.
[[GitHub #109]](https://github.com/ruby/openssl/pull/109)
-* OpenSSL.fips_mode is added. We have had the setter, but not the getter.
+ [[GitHub #173]](https://github.com/ruby/openssl/pull/173)
+* OpenSSL.fips_mode is added. We had the setter, but not the getter.
[[GitHub #125]](https://github.com/ruby/openssl/pull/125)
* OpenSSL::OCSP::Request#signed? is added.
* OpenSSL::ASN1 handles the indefinite length form better. OpenSSL::ASN1.decode
@@ -22,11 +183,86 @@ Notable changes
* OpenSSL::X509::Name#add_entry now accepts two additional keyword arguments
'loc' and 'set'.
[[GitHub #94]](https://github.com/ruby/openssl/issues/94)
-* OpenSSL::SSL::SSLContext#min_version= and #max_version= are added.
+* OpenSSL::SSL::SSLContext#min_version= and #max_version= are added to replace
+ #ssl_version= that was built on top of the deprecated OpenSSL C API. Use of
+ that method and the constant OpenSSL::SSL::SSLContext::METHODS is now
+ deprecated.
[[GitHub #142]](https://github.com/ruby/openssl/pull/142)
* OpenSSL::X509::Name#to_utf8 is added.
[[GitHub #26]](https://github.com/ruby/openssl/issues/26)
[[GitHub #143]](https://github.com/ruby/openssl/pull/143)
+* OpenSSL::X509::{Extension,Attribute,Certificate,CRL,Revoked,Request} can be
+ compared with == operator.
+ [[GitHub #161]](https://github.com/ruby/openssl/pull/161)
+* TLS Fallback Signaling Cipher Suite Value (SCSV) support is added.
+ [[GitHub #165]](https://github.com/ruby/openssl/pull/165)
+* Build failure with OpenSSL 1.1 built with no-deprecated is fixed.
+ [[GitHub #160]](https://github.com/ruby/openssl/pull/160)
+* OpenSSL::Buffering#write accepts an arbitrary number of arguments.
+ [[Feature #9323]](https://bugs.ruby-lang.org/issues/9323)
+ [[GitHub #162]](https://github.com/ruby/openssl/pull/162)
+* OpenSSL::PKey::RSA#sign_pss and #verify_pss are added. They perform RSA-PSS
+ signature and verification.
+ [[GitHub #75]](https://github.com/ruby/openssl/issues/75)
+ [[GitHub #76]](https://github.com/ruby/openssl/pull/76)
+ [[GitHub #169]](https://github.com/ruby/openssl/pull/169)
+* OpenSSL::SSL::SSLContext#add_certificate is added.
+ [[GitHub #167]](https://github.com/ruby/openssl/pull/167)
+* OpenSSL::PKey::EC::Point#to_octet_string is added.
+ OpenSSL::PKey::EC::Point.new can now take String as the second argument.
+ [[GitHub #177]](https://github.com/ruby/openssl/pull/177)
+
+
+Version 2.0.9
+=============
+
+Security fixes
+--------------
+
+* OpenSSL::X509::Name#<=> could incorrectly return 0 (= equal) for non-equal
+ objects. CVE-2018-16395 is assigned for this issue.
+ https://hackerone.com/reports/387250
+
+Bug fixes
+---------
+
+* Fixed OpenSSL::PKey::*.{new,generate} immediately aborting if the thread is
+ interrupted.
+ [[Bug #14882]](https://bugs.ruby-lang.org/issues/14882)
+ [[GitHub #205]](https://github.com/ruby/openssl/pull/205)
+* Fixed OpenSSL::X509::Name#to_s failing with OpenSSL::X509::NameError if
+ called against an empty instance.
+ [[GitHub #200]](https://github.com/ruby/openssl/issues/200)
+ [[GitHub #211]](https://github.com/ruby/openssl/pull/211)
+
+
+Version 2.0.8
+=============
+
+Bug fixes
+---------
+
+* OpenSSL::Cipher#pkcs5_keyivgen raises an error when a negative iteration
+ count is given.
+ [[GitHub #184]](https://github.com/ruby/openssl/pull/184)
+* Fixed build with LibreSSL 2.7.
+ [[GitHub #192]](https://github.com/ruby/openssl/issues/192)
+ [[GitHub #193]](https://github.com/ruby/openssl/pull/193)
+
+
+Version 2.0.7
+=============
+
+Bug fixes
+---------
+
+* OpenSSL::Cipher#auth_data= could segfault if called against a non-AEAD cipher.
+ [[Bug #14024]](https://bugs.ruby-lang.org/issues/14024)
+* OpenSSL::X509::Certificate#public_key= (and similar methods) could segfault
+ when an instance of OpenSSL::PKey::PKey with no public key components is
+ passed.
+ [[Bug #14087]](https://bugs.ruby-lang.org/issues/14087)
+ [[GitHub #168]](https://github.com/ruby/openssl/pull/168)
Version 2.0.6
@@ -201,7 +437,7 @@ Notable changes
- A new option 'verify_hostname' is added to OpenSSL::SSL::SSLContext. When it
is enabled, and the SNI hostname is also set, the hostname verification on
the server certificate is automatically performed. It is now enabled by
- OpenSSL::SSL::Context#set_params.
+ OpenSSL::SSL::SSLContext#set_params.
[[GH ruby/openssl#60]](https://github.com/ruby/openssl/pull/60)
Removals
diff --git a/ext/openssl/depend b/ext/openssl/depend
index 021c6d99a8..92825ba0e9 100644
--- a/ext/openssl/depend
+++ b/ext/openssl/depend
@@ -5,10 +5,161 @@ openssl_missing.o: openssl_missing.c
openssl_missing.o: openssl_missing.h
ossl.o: $(RUBY_EXTCONF_H)
ossl.o: $(arch_hdrdir)/ruby/config.h
+ossl.o: $(hdrdir)/ruby.h
+ossl.o: $(hdrdir)/ruby/assert.h
ossl.o: $(hdrdir)/ruby/backward.h
+ossl.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl.o: $(hdrdir)/ruby/defines.h
ossl.o: $(hdrdir)/ruby/encoding.h
ossl.o: $(hdrdir)/ruby/intern.h
+ossl.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl.o: $(hdrdir)/ruby/internal/assume.h
+ossl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl.o: $(hdrdir)/ruby/internal/cast.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl.o: $(hdrdir)/ruby/internal/config.h
+ossl.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl.o: $(hdrdir)/ruby/internal/core.h
+ossl.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl.o: $(hdrdir)/ruby/internal/ctype.h
+ossl.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl.o: $(hdrdir)/ruby/internal/dosish.h
+ossl.o: $(hdrdir)/ruby/internal/error.h
+ossl.o: $(hdrdir)/ruby/internal/eval.h
+ossl.o: $(hdrdir)/ruby/internal/event.h
+ossl.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl.o: $(hdrdir)/ruby/internal/gc.h
+ossl.o: $(hdrdir)/ruby/internal/glob.h
+ossl.o: $(hdrdir)/ruby/internal/globals.h
+ossl.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl.o: $(hdrdir)/ruby/internal/iterator.h
+ossl.o: $(hdrdir)/ruby/internal/memory.h
+ossl.o: $(hdrdir)/ruby/internal/method.h
+ossl.o: $(hdrdir)/ruby/internal/module.h
+ossl.o: $(hdrdir)/ruby/internal/newobj.h
+ossl.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl.o: $(hdrdir)/ruby/internal/symbol.h
+ossl.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl.o: $(hdrdir)/ruby/internal/value.h
+ossl.o: $(hdrdir)/ruby/internal/value_type.h
+ossl.o: $(hdrdir)/ruby/internal/variable.h
+ossl.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl.o: $(hdrdir)/ruby/io.h
ossl.o: $(hdrdir)/ruby/missing.h
ossl.o: $(hdrdir)/ruby/onigmo.h
@@ -18,7 +169,6 @@ ossl.o: $(hdrdir)/ruby/st.h
ossl.o: $(hdrdir)/ruby/subst.h
ossl.o: $(hdrdir)/ruby/thread.h
ossl.o: $(hdrdir)/ruby/thread_native.h
-ossl.o: $(top_srcdir)/include/ruby.h
ossl.o: openssl_missing.h
ossl.o: ossl.c
ossl.o: ossl.h
@@ -38,15 +188,166 @@ ossl.o: ossl_pkcs7.h
ossl.o: ossl_pkey.h
ossl.o: ossl_rand.h
ossl.o: ossl_ssl.h
-ossl.o: ossl_version.h
+ossl.o: ossl_ts.h
ossl.o: ossl_x509.h
ossl.o: ruby_missing.h
ossl_asn1.o: $(RUBY_EXTCONF_H)
ossl_asn1.o: $(arch_hdrdir)/ruby/config.h
+ossl_asn1.o: $(hdrdir)/ruby.h
+ossl_asn1.o: $(hdrdir)/ruby/assert.h
ossl_asn1.o: $(hdrdir)/ruby/backward.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_asn1.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_asn1.o: $(hdrdir)/ruby/defines.h
ossl_asn1.o: $(hdrdir)/ruby/encoding.h
ossl_asn1.o: $(hdrdir)/ruby/intern.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/assume.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/cast.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/config.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/error.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/eval.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/event.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/gc.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/glob.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/globals.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/memory.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/method.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/module.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/value.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/variable.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_asn1.o: $(hdrdir)/ruby/io.h
ossl_asn1.o: $(hdrdir)/ruby/missing.h
ossl_asn1.o: $(hdrdir)/ruby/onigmo.h
@@ -55,7 +356,6 @@ ossl_asn1.o: $(hdrdir)/ruby/ruby.h
ossl_asn1.o: $(hdrdir)/ruby/st.h
ossl_asn1.o: $(hdrdir)/ruby/subst.h
ossl_asn1.o: $(hdrdir)/ruby/thread.h
-ossl_asn1.o: $(top_srcdir)/include/ruby.h
ossl_asn1.o: openssl_missing.h
ossl_asn1.o: ossl.h
ossl_asn1.o: ossl_asn1.c
@@ -75,15 +375,166 @@ ossl_asn1.o: ossl_pkcs7.h
ossl_asn1.o: ossl_pkey.h
ossl_asn1.o: ossl_rand.h
ossl_asn1.o: ossl_ssl.h
-ossl_asn1.o: ossl_version.h
+ossl_asn1.o: ossl_ts.h
ossl_asn1.o: ossl_x509.h
ossl_asn1.o: ruby_missing.h
ossl_bio.o: $(RUBY_EXTCONF_H)
ossl_bio.o: $(arch_hdrdir)/ruby/config.h
+ossl_bio.o: $(hdrdir)/ruby.h
+ossl_bio.o: $(hdrdir)/ruby/assert.h
ossl_bio.o: $(hdrdir)/ruby/backward.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_bio.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_bio.o: $(hdrdir)/ruby/defines.h
ossl_bio.o: $(hdrdir)/ruby/encoding.h
ossl_bio.o: $(hdrdir)/ruby/intern.h
+ossl_bio.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_bio.o: $(hdrdir)/ruby/internal/assume.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_bio.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_bio.o: $(hdrdir)/ruby/internal/cast.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_bio.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_bio.o: $(hdrdir)/ruby/internal/config.h
+ossl_bio.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_bio.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_bio.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_bio.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_bio.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_bio.o: $(hdrdir)/ruby/internal/error.h
+ossl_bio.o: $(hdrdir)/ruby/internal/eval.h
+ossl_bio.o: $(hdrdir)/ruby/internal/event.h
+ossl_bio.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_bio.o: $(hdrdir)/ruby/internal/gc.h
+ossl_bio.o: $(hdrdir)/ruby/internal/glob.h
+ossl_bio.o: $(hdrdir)/ruby/internal/globals.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_bio.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_bio.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_bio.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_bio.o: $(hdrdir)/ruby/internal/memory.h
+ossl_bio.o: $(hdrdir)/ruby/internal/method.h
+ossl_bio.o: $(hdrdir)/ruby/internal/module.h
+ossl_bio.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_bio.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_bio.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_bio.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_bio.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_bio.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_bio.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_bio.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_bio.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_bio.o: $(hdrdir)/ruby/internal/value.h
+ossl_bio.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_bio.o: $(hdrdir)/ruby/internal/variable.h
+ossl_bio.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_bio.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_bio.o: $(hdrdir)/ruby/io.h
ossl_bio.o: $(hdrdir)/ruby/missing.h
ossl_bio.o: $(hdrdir)/ruby/onigmo.h
@@ -92,7 +543,6 @@ ossl_bio.o: $(hdrdir)/ruby/ruby.h
ossl_bio.o: $(hdrdir)/ruby/st.h
ossl_bio.o: $(hdrdir)/ruby/subst.h
ossl_bio.o: $(hdrdir)/ruby/thread.h
-ossl_bio.o: $(top_srcdir)/include/ruby.h
ossl_bio.o: openssl_missing.h
ossl_bio.o: ossl.h
ossl_bio.o: ossl_asn1.h
@@ -112,24 +562,175 @@ ossl_bio.o: ossl_pkcs7.h
ossl_bio.o: ossl_pkey.h
ossl_bio.o: ossl_rand.h
ossl_bio.o: ossl_ssl.h
-ossl_bio.o: ossl_version.h
+ossl_bio.o: ossl_ts.h
ossl_bio.o: ossl_x509.h
ossl_bio.o: ruby_missing.h
ossl_bn.o: $(RUBY_EXTCONF_H)
ossl_bn.o: $(arch_hdrdir)/ruby/config.h
+ossl_bn.o: $(hdrdir)/ruby.h
+ossl_bn.o: $(hdrdir)/ruby/assert.h
ossl_bn.o: $(hdrdir)/ruby/backward.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_bn.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_bn.o: $(hdrdir)/ruby/defines.h
ossl_bn.o: $(hdrdir)/ruby/encoding.h
ossl_bn.o: $(hdrdir)/ruby/intern.h
+ossl_bn.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_bn.o: $(hdrdir)/ruby/internal/assume.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_bn.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_bn.o: $(hdrdir)/ruby/internal/cast.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_bn.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_bn.o: $(hdrdir)/ruby/internal/config.h
+ossl_bn.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_bn.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_bn.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_bn.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_bn.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_bn.o: $(hdrdir)/ruby/internal/error.h
+ossl_bn.o: $(hdrdir)/ruby/internal/eval.h
+ossl_bn.o: $(hdrdir)/ruby/internal/event.h
+ossl_bn.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_bn.o: $(hdrdir)/ruby/internal/gc.h
+ossl_bn.o: $(hdrdir)/ruby/internal/glob.h
+ossl_bn.o: $(hdrdir)/ruby/internal/globals.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_bn.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_bn.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_bn.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_bn.o: $(hdrdir)/ruby/internal/memory.h
+ossl_bn.o: $(hdrdir)/ruby/internal/method.h
+ossl_bn.o: $(hdrdir)/ruby/internal/module.h
+ossl_bn.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_bn.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_bn.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_bn.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_bn.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_bn.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_bn.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_bn.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_bn.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_bn.o: $(hdrdir)/ruby/internal/value.h
+ossl_bn.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_bn.o: $(hdrdir)/ruby/internal/variable.h
+ossl_bn.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_bn.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_bn.o: $(hdrdir)/ruby/io.h
ossl_bn.o: $(hdrdir)/ruby/missing.h
ossl_bn.o: $(hdrdir)/ruby/onigmo.h
ossl_bn.o: $(hdrdir)/ruby/oniguruma.h
+ossl_bn.o: $(hdrdir)/ruby/ractor.h
ossl_bn.o: $(hdrdir)/ruby/ruby.h
ossl_bn.o: $(hdrdir)/ruby/st.h
ossl_bn.o: $(hdrdir)/ruby/subst.h
ossl_bn.o: $(hdrdir)/ruby/thread.h
-ossl_bn.o: $(top_srcdir)/include/ruby.h
ossl_bn.o: openssl_missing.h
ossl_bn.o: ossl.h
ossl_bn.o: ossl_asn1.h
@@ -149,15 +750,166 @@ ossl_bn.o: ossl_pkcs7.h
ossl_bn.o: ossl_pkey.h
ossl_bn.o: ossl_rand.h
ossl_bn.o: ossl_ssl.h
-ossl_bn.o: ossl_version.h
+ossl_bn.o: ossl_ts.h
ossl_bn.o: ossl_x509.h
ossl_bn.o: ruby_missing.h
ossl_cipher.o: $(RUBY_EXTCONF_H)
ossl_cipher.o: $(arch_hdrdir)/ruby/config.h
+ossl_cipher.o: $(hdrdir)/ruby.h
+ossl_cipher.o: $(hdrdir)/ruby/assert.h
ossl_cipher.o: $(hdrdir)/ruby/backward.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_cipher.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_cipher.o: $(hdrdir)/ruby/defines.h
ossl_cipher.o: $(hdrdir)/ruby/encoding.h
ossl_cipher.o: $(hdrdir)/ruby/intern.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/assume.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/cast.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/config.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/error.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/eval.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/event.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/gc.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/glob.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/globals.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/memory.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/method.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/module.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/value.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/variable.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_cipher.o: $(hdrdir)/ruby/io.h
ossl_cipher.o: $(hdrdir)/ruby/missing.h
ossl_cipher.o: $(hdrdir)/ruby/onigmo.h
@@ -166,7 +918,6 @@ ossl_cipher.o: $(hdrdir)/ruby/ruby.h
ossl_cipher.o: $(hdrdir)/ruby/st.h
ossl_cipher.o: $(hdrdir)/ruby/subst.h
ossl_cipher.o: $(hdrdir)/ruby/thread.h
-ossl_cipher.o: $(top_srcdir)/include/ruby.h
ossl_cipher.o: openssl_missing.h
ossl_cipher.o: ossl.h
ossl_cipher.o: ossl_asn1.h
@@ -186,15 +937,166 @@ ossl_cipher.o: ossl_pkcs7.h
ossl_cipher.o: ossl_pkey.h
ossl_cipher.o: ossl_rand.h
ossl_cipher.o: ossl_ssl.h
-ossl_cipher.o: ossl_version.h
+ossl_cipher.o: ossl_ts.h
ossl_cipher.o: ossl_x509.h
ossl_cipher.o: ruby_missing.h
ossl_config.o: $(RUBY_EXTCONF_H)
ossl_config.o: $(arch_hdrdir)/ruby/config.h
+ossl_config.o: $(hdrdir)/ruby.h
+ossl_config.o: $(hdrdir)/ruby/assert.h
ossl_config.o: $(hdrdir)/ruby/backward.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_config.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_config.o: $(hdrdir)/ruby/defines.h
ossl_config.o: $(hdrdir)/ruby/encoding.h
ossl_config.o: $(hdrdir)/ruby/intern.h
+ossl_config.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_config.o: $(hdrdir)/ruby/internal/assume.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_config.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_config.o: $(hdrdir)/ruby/internal/cast.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_config.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_config.o: $(hdrdir)/ruby/internal/config.h
+ossl_config.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_config.o: $(hdrdir)/ruby/internal/core.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_config.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_config.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_config.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_config.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_config.o: $(hdrdir)/ruby/internal/error.h
+ossl_config.o: $(hdrdir)/ruby/internal/eval.h
+ossl_config.o: $(hdrdir)/ruby/internal/event.h
+ossl_config.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_config.o: $(hdrdir)/ruby/internal/gc.h
+ossl_config.o: $(hdrdir)/ruby/internal/glob.h
+ossl_config.o: $(hdrdir)/ruby/internal/globals.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_config.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_config.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_config.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_config.o: $(hdrdir)/ruby/internal/memory.h
+ossl_config.o: $(hdrdir)/ruby/internal/method.h
+ossl_config.o: $(hdrdir)/ruby/internal/module.h
+ossl_config.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_config.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_config.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_config.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_config.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_config.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_config.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_config.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_config.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_config.o: $(hdrdir)/ruby/internal/value.h
+ossl_config.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_config.o: $(hdrdir)/ruby/internal/variable.h
+ossl_config.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_config.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_config.o: $(hdrdir)/ruby/io.h
ossl_config.o: $(hdrdir)/ruby/missing.h
ossl_config.o: $(hdrdir)/ruby/onigmo.h
@@ -203,7 +1105,6 @@ ossl_config.o: $(hdrdir)/ruby/ruby.h
ossl_config.o: $(hdrdir)/ruby/st.h
ossl_config.o: $(hdrdir)/ruby/subst.h
ossl_config.o: $(hdrdir)/ruby/thread.h
-ossl_config.o: $(top_srcdir)/include/ruby.h
ossl_config.o: openssl_missing.h
ossl_config.o: ossl.h
ossl_config.o: ossl_asn1.h
@@ -223,15 +1124,166 @@ ossl_config.o: ossl_pkcs7.h
ossl_config.o: ossl_pkey.h
ossl_config.o: ossl_rand.h
ossl_config.o: ossl_ssl.h
-ossl_config.o: ossl_version.h
+ossl_config.o: ossl_ts.h
ossl_config.o: ossl_x509.h
ossl_config.o: ruby_missing.h
ossl_digest.o: $(RUBY_EXTCONF_H)
ossl_digest.o: $(arch_hdrdir)/ruby/config.h
+ossl_digest.o: $(hdrdir)/ruby.h
+ossl_digest.o: $(hdrdir)/ruby/assert.h
ossl_digest.o: $(hdrdir)/ruby/backward.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_digest.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_digest.o: $(hdrdir)/ruby/defines.h
ossl_digest.o: $(hdrdir)/ruby/encoding.h
ossl_digest.o: $(hdrdir)/ruby/intern.h
+ossl_digest.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_digest.o: $(hdrdir)/ruby/internal/assume.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_digest.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_digest.o: $(hdrdir)/ruby/internal/cast.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_digest.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_digest.o: $(hdrdir)/ruby/internal/config.h
+ossl_digest.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_digest.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_digest.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_digest.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_digest.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_digest.o: $(hdrdir)/ruby/internal/error.h
+ossl_digest.o: $(hdrdir)/ruby/internal/eval.h
+ossl_digest.o: $(hdrdir)/ruby/internal/event.h
+ossl_digest.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_digest.o: $(hdrdir)/ruby/internal/gc.h
+ossl_digest.o: $(hdrdir)/ruby/internal/glob.h
+ossl_digest.o: $(hdrdir)/ruby/internal/globals.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_digest.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_digest.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_digest.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_digest.o: $(hdrdir)/ruby/internal/memory.h
+ossl_digest.o: $(hdrdir)/ruby/internal/method.h
+ossl_digest.o: $(hdrdir)/ruby/internal/module.h
+ossl_digest.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_digest.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_digest.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_digest.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_digest.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_digest.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_digest.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_digest.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_digest.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_digest.o: $(hdrdir)/ruby/internal/value.h
+ossl_digest.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_digest.o: $(hdrdir)/ruby/internal/variable.h
+ossl_digest.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_digest.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_digest.o: $(hdrdir)/ruby/io.h
ossl_digest.o: $(hdrdir)/ruby/missing.h
ossl_digest.o: $(hdrdir)/ruby/onigmo.h
@@ -240,7 +1292,6 @@ ossl_digest.o: $(hdrdir)/ruby/ruby.h
ossl_digest.o: $(hdrdir)/ruby/st.h
ossl_digest.o: $(hdrdir)/ruby/subst.h
ossl_digest.o: $(hdrdir)/ruby/thread.h
-ossl_digest.o: $(top_srcdir)/include/ruby.h
ossl_digest.o: openssl_missing.h
ossl_digest.o: ossl.h
ossl_digest.o: ossl_asn1.h
@@ -260,15 +1311,166 @@ ossl_digest.o: ossl_pkcs7.h
ossl_digest.o: ossl_pkey.h
ossl_digest.o: ossl_rand.h
ossl_digest.o: ossl_ssl.h
-ossl_digest.o: ossl_version.h
+ossl_digest.o: ossl_ts.h
ossl_digest.o: ossl_x509.h
ossl_digest.o: ruby_missing.h
ossl_engine.o: $(RUBY_EXTCONF_H)
ossl_engine.o: $(arch_hdrdir)/ruby/config.h
+ossl_engine.o: $(hdrdir)/ruby.h
+ossl_engine.o: $(hdrdir)/ruby/assert.h
ossl_engine.o: $(hdrdir)/ruby/backward.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_engine.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_engine.o: $(hdrdir)/ruby/defines.h
ossl_engine.o: $(hdrdir)/ruby/encoding.h
ossl_engine.o: $(hdrdir)/ruby/intern.h
+ossl_engine.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_engine.o: $(hdrdir)/ruby/internal/assume.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_engine.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_engine.o: $(hdrdir)/ruby/internal/cast.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_engine.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_engine.o: $(hdrdir)/ruby/internal/config.h
+ossl_engine.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_engine.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_engine.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_engine.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_engine.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_engine.o: $(hdrdir)/ruby/internal/error.h
+ossl_engine.o: $(hdrdir)/ruby/internal/eval.h
+ossl_engine.o: $(hdrdir)/ruby/internal/event.h
+ossl_engine.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_engine.o: $(hdrdir)/ruby/internal/gc.h
+ossl_engine.o: $(hdrdir)/ruby/internal/glob.h
+ossl_engine.o: $(hdrdir)/ruby/internal/globals.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_engine.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_engine.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_engine.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_engine.o: $(hdrdir)/ruby/internal/memory.h
+ossl_engine.o: $(hdrdir)/ruby/internal/method.h
+ossl_engine.o: $(hdrdir)/ruby/internal/module.h
+ossl_engine.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_engine.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_engine.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_engine.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_engine.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_engine.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_engine.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_engine.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_engine.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_engine.o: $(hdrdir)/ruby/internal/value.h
+ossl_engine.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_engine.o: $(hdrdir)/ruby/internal/variable.h
+ossl_engine.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_engine.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_engine.o: $(hdrdir)/ruby/io.h
ossl_engine.o: $(hdrdir)/ruby/missing.h
ossl_engine.o: $(hdrdir)/ruby/onigmo.h
@@ -277,7 +1479,6 @@ ossl_engine.o: $(hdrdir)/ruby/ruby.h
ossl_engine.o: $(hdrdir)/ruby/st.h
ossl_engine.o: $(hdrdir)/ruby/subst.h
ossl_engine.o: $(hdrdir)/ruby/thread.h
-ossl_engine.o: $(top_srcdir)/include/ruby.h
ossl_engine.o: openssl_missing.h
ossl_engine.o: ossl.h
ossl_engine.o: ossl_asn1.h
@@ -297,15 +1498,166 @@ ossl_engine.o: ossl_pkcs7.h
ossl_engine.o: ossl_pkey.h
ossl_engine.o: ossl_rand.h
ossl_engine.o: ossl_ssl.h
-ossl_engine.o: ossl_version.h
+ossl_engine.o: ossl_ts.h
ossl_engine.o: ossl_x509.h
ossl_engine.o: ruby_missing.h
ossl_hmac.o: $(RUBY_EXTCONF_H)
ossl_hmac.o: $(arch_hdrdir)/ruby/config.h
+ossl_hmac.o: $(hdrdir)/ruby.h
+ossl_hmac.o: $(hdrdir)/ruby/assert.h
ossl_hmac.o: $(hdrdir)/ruby/backward.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_hmac.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_hmac.o: $(hdrdir)/ruby/defines.h
ossl_hmac.o: $(hdrdir)/ruby/encoding.h
ossl_hmac.o: $(hdrdir)/ruby/intern.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/assume.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/cast.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/config.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/error.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/eval.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/event.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/gc.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/glob.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/globals.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/memory.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/method.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/module.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/value.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/variable.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_hmac.o: $(hdrdir)/ruby/io.h
ossl_hmac.o: $(hdrdir)/ruby/missing.h
ossl_hmac.o: $(hdrdir)/ruby/onigmo.h
@@ -314,7 +1666,6 @@ ossl_hmac.o: $(hdrdir)/ruby/ruby.h
ossl_hmac.o: $(hdrdir)/ruby/st.h
ossl_hmac.o: $(hdrdir)/ruby/subst.h
ossl_hmac.o: $(hdrdir)/ruby/thread.h
-ossl_hmac.o: $(top_srcdir)/include/ruby.h
ossl_hmac.o: openssl_missing.h
ossl_hmac.o: ossl.h
ossl_hmac.o: ossl_asn1.h
@@ -334,15 +1685,166 @@ ossl_hmac.o: ossl_pkcs7.h
ossl_hmac.o: ossl_pkey.h
ossl_hmac.o: ossl_rand.h
ossl_hmac.o: ossl_ssl.h
-ossl_hmac.o: ossl_version.h
+ossl_hmac.o: ossl_ts.h
ossl_hmac.o: ossl_x509.h
ossl_hmac.o: ruby_missing.h
ossl_kdf.o: $(RUBY_EXTCONF_H)
ossl_kdf.o: $(arch_hdrdir)/ruby/config.h
+ossl_kdf.o: $(hdrdir)/ruby.h
+ossl_kdf.o: $(hdrdir)/ruby/assert.h
ossl_kdf.o: $(hdrdir)/ruby/backward.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_kdf.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_kdf.o: $(hdrdir)/ruby/defines.h
ossl_kdf.o: $(hdrdir)/ruby/encoding.h
ossl_kdf.o: $(hdrdir)/ruby/intern.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/assume.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/cast.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/config.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/error.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/eval.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/event.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/gc.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/glob.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/globals.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/memory.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/method.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/module.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/value.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/variable.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_kdf.o: $(hdrdir)/ruby/io.h
ossl_kdf.o: $(hdrdir)/ruby/missing.h
ossl_kdf.o: $(hdrdir)/ruby/onigmo.h
@@ -351,7 +1853,6 @@ ossl_kdf.o: $(hdrdir)/ruby/ruby.h
ossl_kdf.o: $(hdrdir)/ruby/st.h
ossl_kdf.o: $(hdrdir)/ruby/subst.h
ossl_kdf.o: $(hdrdir)/ruby/thread.h
-ossl_kdf.o: $(top_srcdir)/include/ruby.h
ossl_kdf.o: openssl_missing.h
ossl_kdf.o: ossl.h
ossl_kdf.o: ossl_asn1.h
@@ -371,15 +1872,166 @@ ossl_kdf.o: ossl_pkcs7.h
ossl_kdf.o: ossl_pkey.h
ossl_kdf.o: ossl_rand.h
ossl_kdf.o: ossl_ssl.h
-ossl_kdf.o: ossl_version.h
+ossl_kdf.o: ossl_ts.h
ossl_kdf.o: ossl_x509.h
ossl_kdf.o: ruby_missing.h
ossl_ns_spki.o: $(RUBY_EXTCONF_H)
ossl_ns_spki.o: $(arch_hdrdir)/ruby/config.h
+ossl_ns_spki.o: $(hdrdir)/ruby.h
+ossl_ns_spki.o: $(hdrdir)/ruby/assert.h
ossl_ns_spki.o: $(hdrdir)/ruby/backward.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_ns_spki.o: $(hdrdir)/ruby/defines.h
ossl_ns_spki.o: $(hdrdir)/ruby/encoding.h
ossl_ns_spki.o: $(hdrdir)/ruby/intern.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/assume.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/cast.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/config.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/error.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/eval.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/event.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/gc.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/glob.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/globals.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/memory.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/method.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/module.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/value.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/variable.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_ns_spki.o: $(hdrdir)/ruby/io.h
ossl_ns_spki.o: $(hdrdir)/ruby/missing.h
ossl_ns_spki.o: $(hdrdir)/ruby/onigmo.h
@@ -388,7 +2040,6 @@ ossl_ns_spki.o: $(hdrdir)/ruby/ruby.h
ossl_ns_spki.o: $(hdrdir)/ruby/st.h
ossl_ns_spki.o: $(hdrdir)/ruby/subst.h
ossl_ns_spki.o: $(hdrdir)/ruby/thread.h
-ossl_ns_spki.o: $(top_srcdir)/include/ruby.h
ossl_ns_spki.o: openssl_missing.h
ossl_ns_spki.o: ossl.h
ossl_ns_spki.o: ossl_asn1.h
@@ -408,15 +2059,166 @@ ossl_ns_spki.o: ossl_pkcs7.h
ossl_ns_spki.o: ossl_pkey.h
ossl_ns_spki.o: ossl_rand.h
ossl_ns_spki.o: ossl_ssl.h
-ossl_ns_spki.o: ossl_version.h
+ossl_ns_spki.o: ossl_ts.h
ossl_ns_spki.o: ossl_x509.h
ossl_ns_spki.o: ruby_missing.h
ossl_ocsp.o: $(RUBY_EXTCONF_H)
ossl_ocsp.o: $(arch_hdrdir)/ruby/config.h
+ossl_ocsp.o: $(hdrdir)/ruby.h
+ossl_ocsp.o: $(hdrdir)/ruby/assert.h
ossl_ocsp.o: $(hdrdir)/ruby/backward.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_ocsp.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_ocsp.o: $(hdrdir)/ruby/defines.h
ossl_ocsp.o: $(hdrdir)/ruby/encoding.h
ossl_ocsp.o: $(hdrdir)/ruby/intern.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/assume.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/cast.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/config.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/error.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/eval.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/event.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/gc.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/glob.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/globals.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/memory.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/method.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/module.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/value.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/variable.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_ocsp.o: $(hdrdir)/ruby/io.h
ossl_ocsp.o: $(hdrdir)/ruby/missing.h
ossl_ocsp.o: $(hdrdir)/ruby/onigmo.h
@@ -425,7 +2227,6 @@ ossl_ocsp.o: $(hdrdir)/ruby/ruby.h
ossl_ocsp.o: $(hdrdir)/ruby/st.h
ossl_ocsp.o: $(hdrdir)/ruby/subst.h
ossl_ocsp.o: $(hdrdir)/ruby/thread.h
-ossl_ocsp.o: $(top_srcdir)/include/ruby.h
ossl_ocsp.o: openssl_missing.h
ossl_ocsp.o: ossl.h
ossl_ocsp.o: ossl_asn1.h
@@ -445,15 +2246,166 @@ ossl_ocsp.o: ossl_pkcs7.h
ossl_ocsp.o: ossl_pkey.h
ossl_ocsp.o: ossl_rand.h
ossl_ocsp.o: ossl_ssl.h
-ossl_ocsp.o: ossl_version.h
+ossl_ocsp.o: ossl_ts.h
ossl_ocsp.o: ossl_x509.h
ossl_ocsp.o: ruby_missing.h
ossl_pkcs12.o: $(RUBY_EXTCONF_H)
ossl_pkcs12.o: $(arch_hdrdir)/ruby/config.h
+ossl_pkcs12.o: $(hdrdir)/ruby.h
+ossl_pkcs12.o: $(hdrdir)/ruby/assert.h
ossl_pkcs12.o: $(hdrdir)/ruby/backward.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_pkcs12.o: $(hdrdir)/ruby/defines.h
ossl_pkcs12.o: $(hdrdir)/ruby/encoding.h
ossl_pkcs12.o: $(hdrdir)/ruby/intern.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/assume.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/cast.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/config.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/error.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/eval.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/event.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/gc.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/glob.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/globals.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/memory.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/method.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/module.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/value.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/variable.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_pkcs12.o: $(hdrdir)/ruby/io.h
ossl_pkcs12.o: $(hdrdir)/ruby/missing.h
ossl_pkcs12.o: $(hdrdir)/ruby/onigmo.h
@@ -462,7 +2414,6 @@ ossl_pkcs12.o: $(hdrdir)/ruby/ruby.h
ossl_pkcs12.o: $(hdrdir)/ruby/st.h
ossl_pkcs12.o: $(hdrdir)/ruby/subst.h
ossl_pkcs12.o: $(hdrdir)/ruby/thread.h
-ossl_pkcs12.o: $(top_srcdir)/include/ruby.h
ossl_pkcs12.o: openssl_missing.h
ossl_pkcs12.o: ossl.h
ossl_pkcs12.o: ossl_asn1.h
@@ -482,15 +2433,166 @@ ossl_pkcs12.o: ossl_pkcs7.h
ossl_pkcs12.o: ossl_pkey.h
ossl_pkcs12.o: ossl_rand.h
ossl_pkcs12.o: ossl_ssl.h
-ossl_pkcs12.o: ossl_version.h
+ossl_pkcs12.o: ossl_ts.h
ossl_pkcs12.o: ossl_x509.h
ossl_pkcs12.o: ruby_missing.h
ossl_pkcs7.o: $(RUBY_EXTCONF_H)
ossl_pkcs7.o: $(arch_hdrdir)/ruby/config.h
+ossl_pkcs7.o: $(hdrdir)/ruby.h
+ossl_pkcs7.o: $(hdrdir)/ruby/assert.h
ossl_pkcs7.o: $(hdrdir)/ruby/backward.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_pkcs7.o: $(hdrdir)/ruby/defines.h
ossl_pkcs7.o: $(hdrdir)/ruby/encoding.h
ossl_pkcs7.o: $(hdrdir)/ruby/intern.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/assume.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/cast.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/config.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/error.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/eval.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/event.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/gc.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/glob.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/globals.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/memory.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/method.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/module.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/value.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/variable.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_pkcs7.o: $(hdrdir)/ruby/io.h
ossl_pkcs7.o: $(hdrdir)/ruby/missing.h
ossl_pkcs7.o: $(hdrdir)/ruby/onigmo.h
@@ -499,7 +2601,6 @@ ossl_pkcs7.o: $(hdrdir)/ruby/ruby.h
ossl_pkcs7.o: $(hdrdir)/ruby/st.h
ossl_pkcs7.o: $(hdrdir)/ruby/subst.h
ossl_pkcs7.o: $(hdrdir)/ruby/thread.h
-ossl_pkcs7.o: $(top_srcdir)/include/ruby.h
ossl_pkcs7.o: openssl_missing.h
ossl_pkcs7.o: ossl.h
ossl_pkcs7.o: ossl_asn1.h
@@ -519,15 +2620,166 @@ ossl_pkcs7.o: ossl_pkcs7.h
ossl_pkcs7.o: ossl_pkey.h
ossl_pkcs7.o: ossl_rand.h
ossl_pkcs7.o: ossl_ssl.h
-ossl_pkcs7.o: ossl_version.h
+ossl_pkcs7.o: ossl_ts.h
ossl_pkcs7.o: ossl_x509.h
ossl_pkcs7.o: ruby_missing.h
ossl_pkey.o: $(RUBY_EXTCONF_H)
ossl_pkey.o: $(arch_hdrdir)/ruby/config.h
+ossl_pkey.o: $(hdrdir)/ruby.h
+ossl_pkey.o: $(hdrdir)/ruby/assert.h
ossl_pkey.o: $(hdrdir)/ruby/backward.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_pkey.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_pkey.o: $(hdrdir)/ruby/defines.h
ossl_pkey.o: $(hdrdir)/ruby/encoding.h
ossl_pkey.o: $(hdrdir)/ruby/intern.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/assume.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/cast.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/config.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/error.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/eval.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/event.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/gc.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/glob.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/globals.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/memory.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/method.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/module.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/value.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/variable.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_pkey.o: $(hdrdir)/ruby/io.h
ossl_pkey.o: $(hdrdir)/ruby/missing.h
ossl_pkey.o: $(hdrdir)/ruby/onigmo.h
@@ -536,7 +2788,6 @@ ossl_pkey.o: $(hdrdir)/ruby/ruby.h
ossl_pkey.o: $(hdrdir)/ruby/st.h
ossl_pkey.o: $(hdrdir)/ruby/subst.h
ossl_pkey.o: $(hdrdir)/ruby/thread.h
-ossl_pkey.o: $(top_srcdir)/include/ruby.h
ossl_pkey.o: openssl_missing.h
ossl_pkey.o: ossl.h
ossl_pkey.o: ossl_asn1.h
@@ -556,15 +2807,166 @@ ossl_pkey.o: ossl_pkey.c
ossl_pkey.o: ossl_pkey.h
ossl_pkey.o: ossl_rand.h
ossl_pkey.o: ossl_ssl.h
-ossl_pkey.o: ossl_version.h
+ossl_pkey.o: ossl_ts.h
ossl_pkey.o: ossl_x509.h
ossl_pkey.o: ruby_missing.h
ossl_pkey_dh.o: $(RUBY_EXTCONF_H)
ossl_pkey_dh.o: $(arch_hdrdir)/ruby/config.h
+ossl_pkey_dh.o: $(hdrdir)/ruby.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/assert.h
ossl_pkey_dh.o: $(hdrdir)/ruby/backward.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_pkey_dh.o: $(hdrdir)/ruby/defines.h
ossl_pkey_dh.o: $(hdrdir)/ruby/encoding.h
ossl_pkey_dh.o: $(hdrdir)/ruby/intern.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/assume.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/cast.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/config.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/error.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/eval.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/event.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/gc.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/glob.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/globals.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/memory.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/method.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/module.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/value.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/variable.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_pkey_dh.o: $(hdrdir)/ruby/io.h
ossl_pkey_dh.o: $(hdrdir)/ruby/missing.h
ossl_pkey_dh.o: $(hdrdir)/ruby/onigmo.h
@@ -573,7 +2975,6 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/ruby.h
ossl_pkey_dh.o: $(hdrdir)/ruby/st.h
ossl_pkey_dh.o: $(hdrdir)/ruby/subst.h
ossl_pkey_dh.o: $(hdrdir)/ruby/thread.h
-ossl_pkey_dh.o: $(top_srcdir)/include/ruby.h
ossl_pkey_dh.o: openssl_missing.h
ossl_pkey_dh.o: ossl.h
ossl_pkey_dh.o: ossl_asn1.h
@@ -593,15 +2994,166 @@ ossl_pkey_dh.o: ossl_pkey.h
ossl_pkey_dh.o: ossl_pkey_dh.c
ossl_pkey_dh.o: ossl_rand.h
ossl_pkey_dh.o: ossl_ssl.h
-ossl_pkey_dh.o: ossl_version.h
+ossl_pkey_dh.o: ossl_ts.h
ossl_pkey_dh.o: ossl_x509.h
ossl_pkey_dh.o: ruby_missing.h
ossl_pkey_dsa.o: $(RUBY_EXTCONF_H)
ossl_pkey_dsa.o: $(arch_hdrdir)/ruby/config.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/assert.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/backward.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/defines.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/encoding.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/intern.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/assume.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/cast.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/config.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/error.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/eval.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/event.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/gc.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/glob.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/globals.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/memory.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/method.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/module.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/value.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/variable.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/io.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/missing.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/onigmo.h
@@ -610,7 +3162,6 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/ruby.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/st.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/subst.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/thread.h
-ossl_pkey_dsa.o: $(top_srcdir)/include/ruby.h
ossl_pkey_dsa.o: openssl_missing.h
ossl_pkey_dsa.o: ossl.h
ossl_pkey_dsa.o: ossl_asn1.h
@@ -630,15 +3181,166 @@ ossl_pkey_dsa.o: ossl_pkey.h
ossl_pkey_dsa.o: ossl_pkey_dsa.c
ossl_pkey_dsa.o: ossl_rand.h
ossl_pkey_dsa.o: ossl_ssl.h
-ossl_pkey_dsa.o: ossl_version.h
+ossl_pkey_dsa.o: ossl_ts.h
ossl_pkey_dsa.o: ossl_x509.h
ossl_pkey_dsa.o: ruby_missing.h
ossl_pkey_ec.o: $(RUBY_EXTCONF_H)
ossl_pkey_ec.o: $(arch_hdrdir)/ruby/config.h
+ossl_pkey_ec.o: $(hdrdir)/ruby.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/assert.h
ossl_pkey_ec.o: $(hdrdir)/ruby/backward.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_pkey_ec.o: $(hdrdir)/ruby/defines.h
ossl_pkey_ec.o: $(hdrdir)/ruby/encoding.h
ossl_pkey_ec.o: $(hdrdir)/ruby/intern.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/assume.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/cast.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/config.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/error.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/eval.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/event.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/gc.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/glob.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/globals.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/memory.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/method.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/module.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/value.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/variable.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_pkey_ec.o: $(hdrdir)/ruby/io.h
ossl_pkey_ec.o: $(hdrdir)/ruby/missing.h
ossl_pkey_ec.o: $(hdrdir)/ruby/onigmo.h
@@ -647,7 +3349,6 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/ruby.h
ossl_pkey_ec.o: $(hdrdir)/ruby/st.h
ossl_pkey_ec.o: $(hdrdir)/ruby/subst.h
ossl_pkey_ec.o: $(hdrdir)/ruby/thread.h
-ossl_pkey_ec.o: $(top_srcdir)/include/ruby.h
ossl_pkey_ec.o: openssl_missing.h
ossl_pkey_ec.o: ossl.h
ossl_pkey_ec.o: ossl_asn1.h
@@ -667,15 +3368,166 @@ ossl_pkey_ec.o: ossl_pkey.h
ossl_pkey_ec.o: ossl_pkey_ec.c
ossl_pkey_ec.o: ossl_rand.h
ossl_pkey_ec.o: ossl_ssl.h
-ossl_pkey_ec.o: ossl_version.h
+ossl_pkey_ec.o: ossl_ts.h
ossl_pkey_ec.o: ossl_x509.h
ossl_pkey_ec.o: ruby_missing.h
ossl_pkey_rsa.o: $(RUBY_EXTCONF_H)
ossl_pkey_rsa.o: $(arch_hdrdir)/ruby/config.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/assert.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/backward.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/defines.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/encoding.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/intern.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/assume.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/cast.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/config.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/error.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/eval.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/event.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/gc.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/glob.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/globals.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/memory.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/method.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/module.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/value.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/variable.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/io.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/missing.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/onigmo.h
@@ -684,7 +3536,6 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/ruby.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/st.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/subst.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/thread.h
-ossl_pkey_rsa.o: $(top_srcdir)/include/ruby.h
ossl_pkey_rsa.o: openssl_missing.h
ossl_pkey_rsa.o: ossl.h
ossl_pkey_rsa.o: ossl_asn1.h
@@ -704,15 +3555,166 @@ ossl_pkey_rsa.o: ossl_pkey.h
ossl_pkey_rsa.o: ossl_pkey_rsa.c
ossl_pkey_rsa.o: ossl_rand.h
ossl_pkey_rsa.o: ossl_ssl.h
-ossl_pkey_rsa.o: ossl_version.h
+ossl_pkey_rsa.o: ossl_ts.h
ossl_pkey_rsa.o: ossl_x509.h
ossl_pkey_rsa.o: ruby_missing.h
ossl_rand.o: $(RUBY_EXTCONF_H)
ossl_rand.o: $(arch_hdrdir)/ruby/config.h
+ossl_rand.o: $(hdrdir)/ruby.h
+ossl_rand.o: $(hdrdir)/ruby/assert.h
ossl_rand.o: $(hdrdir)/ruby/backward.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_rand.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_rand.o: $(hdrdir)/ruby/defines.h
ossl_rand.o: $(hdrdir)/ruby/encoding.h
ossl_rand.o: $(hdrdir)/ruby/intern.h
+ossl_rand.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_rand.o: $(hdrdir)/ruby/internal/assume.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_rand.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_rand.o: $(hdrdir)/ruby/internal/cast.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_rand.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_rand.o: $(hdrdir)/ruby/internal/config.h
+ossl_rand.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_rand.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_rand.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_rand.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_rand.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_rand.o: $(hdrdir)/ruby/internal/error.h
+ossl_rand.o: $(hdrdir)/ruby/internal/eval.h
+ossl_rand.o: $(hdrdir)/ruby/internal/event.h
+ossl_rand.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_rand.o: $(hdrdir)/ruby/internal/gc.h
+ossl_rand.o: $(hdrdir)/ruby/internal/glob.h
+ossl_rand.o: $(hdrdir)/ruby/internal/globals.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_rand.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_rand.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_rand.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_rand.o: $(hdrdir)/ruby/internal/memory.h
+ossl_rand.o: $(hdrdir)/ruby/internal/method.h
+ossl_rand.o: $(hdrdir)/ruby/internal/module.h
+ossl_rand.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_rand.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_rand.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_rand.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_rand.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_rand.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_rand.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_rand.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_rand.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_rand.o: $(hdrdir)/ruby/internal/value.h
+ossl_rand.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_rand.o: $(hdrdir)/ruby/internal/variable.h
+ossl_rand.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_rand.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_rand.o: $(hdrdir)/ruby/io.h
ossl_rand.o: $(hdrdir)/ruby/missing.h
ossl_rand.o: $(hdrdir)/ruby/onigmo.h
@@ -721,7 +3723,6 @@ ossl_rand.o: $(hdrdir)/ruby/ruby.h
ossl_rand.o: $(hdrdir)/ruby/st.h
ossl_rand.o: $(hdrdir)/ruby/subst.h
ossl_rand.o: $(hdrdir)/ruby/thread.h
-ossl_rand.o: $(top_srcdir)/include/ruby.h
ossl_rand.o: openssl_missing.h
ossl_rand.o: ossl.h
ossl_rand.o: ossl_asn1.h
@@ -741,15 +3742,166 @@ ossl_rand.o: ossl_pkey.h
ossl_rand.o: ossl_rand.c
ossl_rand.o: ossl_rand.h
ossl_rand.o: ossl_ssl.h
-ossl_rand.o: ossl_version.h
+ossl_rand.o: ossl_ts.h
ossl_rand.o: ossl_x509.h
ossl_rand.o: ruby_missing.h
ossl_ssl.o: $(RUBY_EXTCONF_H)
ossl_ssl.o: $(arch_hdrdir)/ruby/config.h
+ossl_ssl.o: $(hdrdir)/ruby.h
+ossl_ssl.o: $(hdrdir)/ruby/assert.h
ossl_ssl.o: $(hdrdir)/ruby/backward.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_ssl.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_ssl.o: $(hdrdir)/ruby/defines.h
ossl_ssl.o: $(hdrdir)/ruby/encoding.h
ossl_ssl.o: $(hdrdir)/ruby/intern.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/assume.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/cast.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/config.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/error.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/eval.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/event.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/gc.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/glob.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/globals.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/memory.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/method.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/module.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/value.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/variable.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_ssl.o: $(hdrdir)/ruby/io.h
ossl_ssl.o: $(hdrdir)/ruby/missing.h
ossl_ssl.o: $(hdrdir)/ruby/onigmo.h
@@ -758,7 +3910,6 @@ ossl_ssl.o: $(hdrdir)/ruby/ruby.h
ossl_ssl.o: $(hdrdir)/ruby/st.h
ossl_ssl.o: $(hdrdir)/ruby/subst.h
ossl_ssl.o: $(hdrdir)/ruby/thread.h
-ossl_ssl.o: $(top_srcdir)/include/ruby.h
ossl_ssl.o: openssl_missing.h
ossl_ssl.o: ossl.h
ossl_ssl.o: ossl_asn1.h
@@ -778,15 +3929,166 @@ ossl_ssl.o: ossl_pkey.h
ossl_ssl.o: ossl_rand.h
ossl_ssl.o: ossl_ssl.c
ossl_ssl.o: ossl_ssl.h
-ossl_ssl.o: ossl_version.h
+ossl_ssl.o: ossl_ts.h
ossl_ssl.o: ossl_x509.h
ossl_ssl.o: ruby_missing.h
ossl_ssl_session.o: $(RUBY_EXTCONF_H)
ossl_ssl_session.o: $(arch_hdrdir)/ruby/config.h
+ossl_ssl_session.o: $(hdrdir)/ruby.h
+ossl_ssl_session.o: $(hdrdir)/ruby/assert.h
ossl_ssl_session.o: $(hdrdir)/ruby/backward.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_ssl_session.o: $(hdrdir)/ruby/defines.h
ossl_ssl_session.o: $(hdrdir)/ruby/encoding.h
ossl_ssl_session.o: $(hdrdir)/ruby/intern.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/assume.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/cast.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/config.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/error.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/eval.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/event.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/gc.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/glob.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/globals.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/memory.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/method.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/module.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/value.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/variable.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_ssl_session.o: $(hdrdir)/ruby/io.h
ossl_ssl_session.o: $(hdrdir)/ruby/missing.h
ossl_ssl_session.o: $(hdrdir)/ruby/onigmo.h
@@ -795,7 +4097,6 @@ ossl_ssl_session.o: $(hdrdir)/ruby/ruby.h
ossl_ssl_session.o: $(hdrdir)/ruby/st.h
ossl_ssl_session.o: $(hdrdir)/ruby/subst.h
ossl_ssl_session.o: $(hdrdir)/ruby/thread.h
-ossl_ssl_session.o: $(top_srcdir)/include/ruby.h
ossl_ssl_session.o: openssl_missing.h
ossl_ssl_session.o: ossl.h
ossl_ssl_session.o: ossl_asn1.h
@@ -815,15 +4116,353 @@ ossl_ssl_session.o: ossl_pkey.h
ossl_ssl_session.o: ossl_rand.h
ossl_ssl_session.o: ossl_ssl.h
ossl_ssl_session.o: ossl_ssl_session.c
-ossl_ssl_session.o: ossl_version.h
+ossl_ssl_session.o: ossl_ts.h
ossl_ssl_session.o: ossl_x509.h
ossl_ssl_session.o: ruby_missing.h
+ossl_ts.o: $(RUBY_EXTCONF_H)
+ossl_ts.o: $(arch_hdrdir)/ruby/config.h
+ossl_ts.o: $(hdrdir)/ruby.h
+ossl_ts.o: $(hdrdir)/ruby/assert.h
+ossl_ts.o: $(hdrdir)/ruby/backward.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_ts.o: $(hdrdir)/ruby/backward/2/stdarg.h
+ossl_ts.o: $(hdrdir)/ruby/defines.h
+ossl_ts.o: $(hdrdir)/ruby/encoding.h
+ossl_ts.o: $(hdrdir)/ruby/intern.h
+ossl_ts.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_ts.o: $(hdrdir)/ruby/internal/assume.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_ts.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_ts.o: $(hdrdir)/ruby/internal/cast.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_ts.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_ts.o: $(hdrdir)/ruby/internal/config.h
+ossl_ts.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_ts.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_ts.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_ts.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_ts.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_ts.o: $(hdrdir)/ruby/internal/error.h
+ossl_ts.o: $(hdrdir)/ruby/internal/eval.h
+ossl_ts.o: $(hdrdir)/ruby/internal/event.h
+ossl_ts.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_ts.o: $(hdrdir)/ruby/internal/gc.h
+ossl_ts.o: $(hdrdir)/ruby/internal/glob.h
+ossl_ts.o: $(hdrdir)/ruby/internal/globals.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_ts.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_ts.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_ts.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_ts.o: $(hdrdir)/ruby/internal/memory.h
+ossl_ts.o: $(hdrdir)/ruby/internal/method.h
+ossl_ts.o: $(hdrdir)/ruby/internal/module.h
+ossl_ts.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ts.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_ts.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_ts.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_ts.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_ts.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_ts.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_ts.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_ts.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_ts.o: $(hdrdir)/ruby/internal/value.h
+ossl_ts.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_ts.o: $(hdrdir)/ruby/internal/variable.h
+ossl_ts.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_ts.o: $(hdrdir)/ruby/internal/xmalloc.h
+ossl_ts.o: $(hdrdir)/ruby/io.h
+ossl_ts.o: $(hdrdir)/ruby/missing.h
+ossl_ts.o: $(hdrdir)/ruby/onigmo.h
+ossl_ts.o: $(hdrdir)/ruby/oniguruma.h
+ossl_ts.o: $(hdrdir)/ruby/ruby.h
+ossl_ts.o: $(hdrdir)/ruby/st.h
+ossl_ts.o: $(hdrdir)/ruby/subst.h
+ossl_ts.o: $(hdrdir)/ruby/thread.h
+ossl_ts.o: openssl_missing.h
+ossl_ts.o: ossl.h
+ossl_ts.o: ossl_asn1.h
+ossl_ts.o: ossl_bio.h
+ossl_ts.o: ossl_bn.h
+ossl_ts.o: ossl_cipher.h
+ossl_ts.o: ossl_config.h
+ossl_ts.o: ossl_digest.h
+ossl_ts.o: ossl_engine.h
+ossl_ts.o: ossl_hmac.h
+ossl_ts.o: ossl_kdf.h
+ossl_ts.o: ossl_ns_spki.h
+ossl_ts.o: ossl_ocsp.h
+ossl_ts.o: ossl_pkcs12.h
+ossl_ts.o: ossl_pkcs7.h
+ossl_ts.o: ossl_pkey.h
+ossl_ts.o: ossl_rand.h
+ossl_ts.o: ossl_ssl.h
+ossl_ts.o: ossl_ts.c
+ossl_ts.o: ossl_ts.h
+ossl_ts.o: ossl_x509.h
+ossl_ts.o: ruby_missing.h
ossl_x509.o: $(RUBY_EXTCONF_H)
ossl_x509.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509.o: $(hdrdir)/ruby.h
+ossl_x509.o: $(hdrdir)/ruby/assert.h
ossl_x509.o: $(hdrdir)/ruby/backward.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509.o: $(hdrdir)/ruby/defines.h
ossl_x509.o: $(hdrdir)/ruby/encoding.h
ossl_x509.o: $(hdrdir)/ruby/intern.h
+ossl_x509.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509.o: $(hdrdir)/ruby/io.h
ossl_x509.o: $(hdrdir)/ruby/missing.h
ossl_x509.o: $(hdrdir)/ruby/onigmo.h
@@ -832,7 +4471,6 @@ ossl_x509.o: $(hdrdir)/ruby/ruby.h
ossl_x509.o: $(hdrdir)/ruby/st.h
ossl_x509.o: $(hdrdir)/ruby/subst.h
ossl_x509.o: $(hdrdir)/ruby/thread.h
-ossl_x509.o: $(top_srcdir)/include/ruby.h
ossl_x509.o: openssl_missing.h
ossl_x509.o: ossl.h
ossl_x509.o: ossl_asn1.h
@@ -851,16 +4489,167 @@ ossl_x509.o: ossl_pkcs7.h
ossl_x509.o: ossl_pkey.h
ossl_x509.o: ossl_rand.h
ossl_x509.o: ossl_ssl.h
-ossl_x509.o: ossl_version.h
+ossl_x509.o: ossl_ts.h
ossl_x509.o: ossl_x509.c
ossl_x509.o: ossl_x509.h
ossl_x509.o: ruby_missing.h
ossl_x509attr.o: $(RUBY_EXTCONF_H)
ossl_x509attr.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509attr.o: $(hdrdir)/ruby.h
+ossl_x509attr.o: $(hdrdir)/ruby/assert.h
ossl_x509attr.o: $(hdrdir)/ruby/backward.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509attr.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509attr.o: $(hdrdir)/ruby/defines.h
ossl_x509attr.o: $(hdrdir)/ruby/encoding.h
ossl_x509attr.o: $(hdrdir)/ruby/intern.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509attr.o: $(hdrdir)/ruby/io.h
ossl_x509attr.o: $(hdrdir)/ruby/missing.h
ossl_x509attr.o: $(hdrdir)/ruby/onigmo.h
@@ -869,7 +4658,6 @@ ossl_x509attr.o: $(hdrdir)/ruby/ruby.h
ossl_x509attr.o: $(hdrdir)/ruby/st.h
ossl_x509attr.o: $(hdrdir)/ruby/subst.h
ossl_x509attr.o: $(hdrdir)/ruby/thread.h
-ossl_x509attr.o: $(top_srcdir)/include/ruby.h
ossl_x509attr.o: openssl_missing.h
ossl_x509attr.o: ossl.h
ossl_x509attr.o: ossl_asn1.h
@@ -888,16 +4676,167 @@ ossl_x509attr.o: ossl_pkcs7.h
ossl_x509attr.o: ossl_pkey.h
ossl_x509attr.o: ossl_rand.h
ossl_x509attr.o: ossl_ssl.h
-ossl_x509attr.o: ossl_version.h
+ossl_x509attr.o: ossl_ts.h
ossl_x509attr.o: ossl_x509.h
ossl_x509attr.o: ossl_x509attr.c
ossl_x509attr.o: ruby_missing.h
ossl_x509cert.o: $(RUBY_EXTCONF_H)
ossl_x509cert.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509cert.o: $(hdrdir)/ruby.h
+ossl_x509cert.o: $(hdrdir)/ruby/assert.h
ossl_x509cert.o: $(hdrdir)/ruby/backward.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509cert.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509cert.o: $(hdrdir)/ruby/defines.h
ossl_x509cert.o: $(hdrdir)/ruby/encoding.h
ossl_x509cert.o: $(hdrdir)/ruby/intern.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509cert.o: $(hdrdir)/ruby/io.h
ossl_x509cert.o: $(hdrdir)/ruby/missing.h
ossl_x509cert.o: $(hdrdir)/ruby/onigmo.h
@@ -906,7 +4845,6 @@ ossl_x509cert.o: $(hdrdir)/ruby/ruby.h
ossl_x509cert.o: $(hdrdir)/ruby/st.h
ossl_x509cert.o: $(hdrdir)/ruby/subst.h
ossl_x509cert.o: $(hdrdir)/ruby/thread.h
-ossl_x509cert.o: $(top_srcdir)/include/ruby.h
ossl_x509cert.o: openssl_missing.h
ossl_x509cert.o: ossl.h
ossl_x509cert.o: ossl_asn1.h
@@ -925,16 +4863,167 @@ ossl_x509cert.o: ossl_pkcs7.h
ossl_x509cert.o: ossl_pkey.h
ossl_x509cert.o: ossl_rand.h
ossl_x509cert.o: ossl_ssl.h
-ossl_x509cert.o: ossl_version.h
+ossl_x509cert.o: ossl_ts.h
ossl_x509cert.o: ossl_x509.h
ossl_x509cert.o: ossl_x509cert.c
ossl_x509cert.o: ruby_missing.h
ossl_x509crl.o: $(RUBY_EXTCONF_H)
ossl_x509crl.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509crl.o: $(hdrdir)/ruby.h
+ossl_x509crl.o: $(hdrdir)/ruby/assert.h
ossl_x509crl.o: $(hdrdir)/ruby/backward.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509crl.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509crl.o: $(hdrdir)/ruby/defines.h
ossl_x509crl.o: $(hdrdir)/ruby/encoding.h
ossl_x509crl.o: $(hdrdir)/ruby/intern.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509crl.o: $(hdrdir)/ruby/io.h
ossl_x509crl.o: $(hdrdir)/ruby/missing.h
ossl_x509crl.o: $(hdrdir)/ruby/onigmo.h
@@ -943,7 +5032,6 @@ ossl_x509crl.o: $(hdrdir)/ruby/ruby.h
ossl_x509crl.o: $(hdrdir)/ruby/st.h
ossl_x509crl.o: $(hdrdir)/ruby/subst.h
ossl_x509crl.o: $(hdrdir)/ruby/thread.h
-ossl_x509crl.o: $(top_srcdir)/include/ruby.h
ossl_x509crl.o: openssl_missing.h
ossl_x509crl.o: ossl.h
ossl_x509crl.o: ossl_asn1.h
@@ -962,16 +5050,167 @@ ossl_x509crl.o: ossl_pkcs7.h
ossl_x509crl.o: ossl_pkey.h
ossl_x509crl.o: ossl_rand.h
ossl_x509crl.o: ossl_ssl.h
-ossl_x509crl.o: ossl_version.h
+ossl_x509crl.o: ossl_ts.h
ossl_x509crl.o: ossl_x509.h
ossl_x509crl.o: ossl_x509crl.c
ossl_x509crl.o: ruby_missing.h
ossl_x509ext.o: $(RUBY_EXTCONF_H)
ossl_x509ext.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509ext.o: $(hdrdir)/ruby.h
+ossl_x509ext.o: $(hdrdir)/ruby/assert.h
ossl_x509ext.o: $(hdrdir)/ruby/backward.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509ext.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509ext.o: $(hdrdir)/ruby/defines.h
ossl_x509ext.o: $(hdrdir)/ruby/encoding.h
ossl_x509ext.o: $(hdrdir)/ruby/intern.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509ext.o: $(hdrdir)/ruby/io.h
ossl_x509ext.o: $(hdrdir)/ruby/missing.h
ossl_x509ext.o: $(hdrdir)/ruby/onigmo.h
@@ -980,7 +5219,6 @@ ossl_x509ext.o: $(hdrdir)/ruby/ruby.h
ossl_x509ext.o: $(hdrdir)/ruby/st.h
ossl_x509ext.o: $(hdrdir)/ruby/subst.h
ossl_x509ext.o: $(hdrdir)/ruby/thread.h
-ossl_x509ext.o: $(top_srcdir)/include/ruby.h
ossl_x509ext.o: openssl_missing.h
ossl_x509ext.o: ossl.h
ossl_x509ext.o: ossl_asn1.h
@@ -999,16 +5237,167 @@ ossl_x509ext.o: ossl_pkcs7.h
ossl_x509ext.o: ossl_pkey.h
ossl_x509ext.o: ossl_rand.h
ossl_x509ext.o: ossl_ssl.h
-ossl_x509ext.o: ossl_version.h
+ossl_x509ext.o: ossl_ts.h
ossl_x509ext.o: ossl_x509.h
ossl_x509ext.o: ossl_x509ext.c
ossl_x509ext.o: ruby_missing.h
ossl_x509name.o: $(RUBY_EXTCONF_H)
ossl_x509name.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509name.o: $(hdrdir)/ruby.h
+ossl_x509name.o: $(hdrdir)/ruby/assert.h
ossl_x509name.o: $(hdrdir)/ruby/backward.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509name.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509name.o: $(hdrdir)/ruby/defines.h
ossl_x509name.o: $(hdrdir)/ruby/encoding.h
ossl_x509name.o: $(hdrdir)/ruby/intern.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509name.o: $(hdrdir)/ruby/io.h
ossl_x509name.o: $(hdrdir)/ruby/missing.h
ossl_x509name.o: $(hdrdir)/ruby/onigmo.h
@@ -1017,7 +5406,6 @@ ossl_x509name.o: $(hdrdir)/ruby/ruby.h
ossl_x509name.o: $(hdrdir)/ruby/st.h
ossl_x509name.o: $(hdrdir)/ruby/subst.h
ossl_x509name.o: $(hdrdir)/ruby/thread.h
-ossl_x509name.o: $(top_srcdir)/include/ruby.h
ossl_x509name.o: openssl_missing.h
ossl_x509name.o: ossl.h
ossl_x509name.o: ossl_asn1.h
@@ -1036,16 +5424,167 @@ ossl_x509name.o: ossl_pkcs7.h
ossl_x509name.o: ossl_pkey.h
ossl_x509name.o: ossl_rand.h
ossl_x509name.o: ossl_ssl.h
-ossl_x509name.o: ossl_version.h
+ossl_x509name.o: ossl_ts.h
ossl_x509name.o: ossl_x509.h
ossl_x509name.o: ossl_x509name.c
ossl_x509name.o: ruby_missing.h
ossl_x509req.o: $(RUBY_EXTCONF_H)
ossl_x509req.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509req.o: $(hdrdir)/ruby.h
+ossl_x509req.o: $(hdrdir)/ruby/assert.h
ossl_x509req.o: $(hdrdir)/ruby/backward.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509req.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509req.o: $(hdrdir)/ruby/defines.h
ossl_x509req.o: $(hdrdir)/ruby/encoding.h
ossl_x509req.o: $(hdrdir)/ruby/intern.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509req.o: $(hdrdir)/ruby/io.h
ossl_x509req.o: $(hdrdir)/ruby/missing.h
ossl_x509req.o: $(hdrdir)/ruby/onigmo.h
@@ -1054,7 +5593,6 @@ ossl_x509req.o: $(hdrdir)/ruby/ruby.h
ossl_x509req.o: $(hdrdir)/ruby/st.h
ossl_x509req.o: $(hdrdir)/ruby/subst.h
ossl_x509req.o: $(hdrdir)/ruby/thread.h
-ossl_x509req.o: $(top_srcdir)/include/ruby.h
ossl_x509req.o: openssl_missing.h
ossl_x509req.o: ossl.h
ossl_x509req.o: ossl_asn1.h
@@ -1073,16 +5611,167 @@ ossl_x509req.o: ossl_pkcs7.h
ossl_x509req.o: ossl_pkey.h
ossl_x509req.o: ossl_rand.h
ossl_x509req.o: ossl_ssl.h
-ossl_x509req.o: ossl_version.h
+ossl_x509req.o: ossl_ts.h
ossl_x509req.o: ossl_x509.h
ossl_x509req.o: ossl_x509req.c
ossl_x509req.o: ruby_missing.h
ossl_x509revoked.o: $(RUBY_EXTCONF_H)
ossl_x509revoked.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509revoked.o: $(hdrdir)/ruby.h
+ossl_x509revoked.o: $(hdrdir)/ruby/assert.h
ossl_x509revoked.o: $(hdrdir)/ruby/backward.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509revoked.o: $(hdrdir)/ruby/defines.h
ossl_x509revoked.o: $(hdrdir)/ruby/encoding.h
ossl_x509revoked.o: $(hdrdir)/ruby/intern.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509revoked.o: $(hdrdir)/ruby/io.h
ossl_x509revoked.o: $(hdrdir)/ruby/missing.h
ossl_x509revoked.o: $(hdrdir)/ruby/onigmo.h
@@ -1091,7 +5780,6 @@ ossl_x509revoked.o: $(hdrdir)/ruby/ruby.h
ossl_x509revoked.o: $(hdrdir)/ruby/st.h
ossl_x509revoked.o: $(hdrdir)/ruby/subst.h
ossl_x509revoked.o: $(hdrdir)/ruby/thread.h
-ossl_x509revoked.o: $(top_srcdir)/include/ruby.h
ossl_x509revoked.o: openssl_missing.h
ossl_x509revoked.o: ossl.h
ossl_x509revoked.o: ossl_asn1.h
@@ -1110,16 +5798,167 @@ ossl_x509revoked.o: ossl_pkcs7.h
ossl_x509revoked.o: ossl_pkey.h
ossl_x509revoked.o: ossl_rand.h
ossl_x509revoked.o: ossl_ssl.h
-ossl_x509revoked.o: ossl_version.h
+ossl_x509revoked.o: ossl_ts.h
ossl_x509revoked.o: ossl_x509.h
ossl_x509revoked.o: ossl_x509revoked.c
ossl_x509revoked.o: ruby_missing.h
ossl_x509store.o: $(RUBY_EXTCONF_H)
ossl_x509store.o: $(arch_hdrdir)/ruby/config.h
+ossl_x509store.o: $(hdrdir)/ruby.h
+ossl_x509store.o: $(hdrdir)/ruby/assert.h
ossl_x509store.o: $(hdrdir)/ruby/backward.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/assume.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/attributes.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/bool.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/limits.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/long_long.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ossl_x509store.o: $(hdrdir)/ruby/backward/2/stdarg.h
ossl_x509store.o: $(hdrdir)/ruby/defines.h
ossl_x509store.o: $(hdrdir)/ruby/encoding.h
ossl_x509store.o: $(hdrdir)/ruby/intern.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/anyargs.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/assume.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/cold.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/const.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/error.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/format.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/pure.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/warning.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/cast.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_since.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/config.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/constant_p.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rarray.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rclass.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rdata.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rfile.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rhash.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/robject.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rstring.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/ctype.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/dllexport.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/dosish.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/error.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/eval.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/event.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/fl_type.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/gc.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/glob.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/globals.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/attribute.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/builtin.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/extension.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/feature.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/has/warning.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/array.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/class.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/compar.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/complex.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/cont.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/dir.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/enum.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/error.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/eval.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/gc.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/hash.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/io.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/load.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/object.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/parse.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/proc.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/process.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/random.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/range.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/rational.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/re.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/select.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/signal.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/string.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/struct.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/thread.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/time.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/variable.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/vm.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/interpreter.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/iterator.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/memory.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/method.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/module.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/rgengc.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/scan_args.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/special_consts.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/static_assert.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/stdalign.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/stdbool.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/symbol.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/token_paste.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/value.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/value_type.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/variable.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/warning_push.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/xmalloc.h
ossl_x509store.o: $(hdrdir)/ruby/io.h
ossl_x509store.o: $(hdrdir)/ruby/missing.h
ossl_x509store.o: $(hdrdir)/ruby/onigmo.h
@@ -1128,7 +5967,6 @@ ossl_x509store.o: $(hdrdir)/ruby/ruby.h
ossl_x509store.o: $(hdrdir)/ruby/st.h
ossl_x509store.o: $(hdrdir)/ruby/subst.h
ossl_x509store.o: $(hdrdir)/ruby/thread.h
-ossl_x509store.o: $(top_srcdir)/include/ruby.h
ossl_x509store.o: openssl_missing.h
ossl_x509store.o: ossl.h
ossl_x509store.o: ossl_asn1.h
@@ -1147,7 +5985,7 @@ ossl_x509store.o: ossl_pkcs7.h
ossl_x509store.o: ossl_pkey.h
ossl_x509store.o: ossl_rand.h
ossl_x509store.o: ossl_ssl.h
-ossl_x509store.o: ossl_version.h
+ossl_x509store.o: ossl_ts.h
ossl_x509store.o: ossl_x509.h
ossl_x509store.o: ossl_x509store.c
ossl_x509store.o: ruby_missing.h
diff --git a/ext/openssl/deprecation.rb b/ext/openssl/deprecation.rb
deleted file mode 100644
index 1d51d065a9..0000000000
--- a/ext/openssl/deprecation.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: false
-module OpenSSL
- def self.deprecated_warning_flag
- unless flag = (@deprecated_warning_flag ||= nil)
- if try_compile("", flag = "-Werror=deprecated-declarations")
- $warnflags << " #{flag}"
- else
- flag = ""
- end
- @deprecated_warning_flag = flag
- end
- flag
- end
-
- def self.check_func(func, header)
- have_func(func, header, deprecated_warning_flag)
- end
-
- def self.check_func_or_macro(func, header)
- check_func(func, header) or
- have_macro(func, header) && $defs.push("-DHAVE_#{func.upcase}")
- end
-end
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 5212903b9a..0dc1a5eb43 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -1,5 +1,5 @@
# -*- coding: us-ascii -*-
-# frozen_string_literal: false
+# frozen_string_literal: true
=begin
= Info
'OpenSSL for Ruby 2' project
@@ -12,16 +12,12 @@
=end
require "mkmf"
-require File.expand_path('../deprecation', __FILE__)
-dir_config("openssl")
+dir_config_given = dir_config("openssl").any?
dir_config("kerberos")
Logging::message "=== OpenSSL for Ruby configurator ===\n"
-# Add -Werror=deprecated-declarations to $warnflags if available
-OpenSSL.deprecated_warning_flag
-
##
# Adds -DOSSL_DEBUG for compilation and some more targets when GCC is used
# To turn it on, use: --with-debug or --enable-debug
@@ -33,9 +29,15 @@ end
Logging::message "=== Checking for system dependent stuff... ===\n"
have_library("nsl", "t_open")
have_library("socket", "socket")
+if $mswin || $mingw
+ have_library("ws2_32")
+end
-Logging::message "=== Checking for required stuff... ===\n"
-result = pkg_config("openssl") && have_header("openssl/ssl.h")
+if $mingw
+ append_cflags '-D_FORTIFY_SOURCE=2'
+ append_ldflags '-fstack-protector'
+ have_library 'ssp'
+end
def find_openssl_library
if $mswin || $mingw
@@ -87,28 +89,42 @@ def find_openssl_library
return false
end
-unless result
- unless find_openssl_library
- Logging::message "=== Checking for required stuff failed. ===\n"
- Logging::message "Makefile wasn't created. Fix the errors above.\n"
- raise "OpenSSL library could not be found. You might want to use " \
- "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \
- "is installed."
- end
+Logging::message "=== Checking for required stuff... ===\n"
+pkg_config_found = !dir_config_given && pkg_config("openssl") && have_header("openssl/ssl.h")
+
+if !pkg_config_found && !find_openssl_library
+ Logging::message "=== Checking for required stuff failed. ===\n"
+ Logging::message "Makefile wasn't created. Fix the errors above.\n"
+ raise "OpenSSL library could not be found. You might want to use " \
+ "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \
+ "is installed."
end
-unless checking_for("OpenSSL version is 1.0.1 or later") {
- try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") }
- raise "OpenSSL >= 1.0.1 or LibreSSL is required"
+version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h")
+ is_libressl = true
+ checking_for("LibreSSL version >= 2.5.0") {
+ try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x20500000L", "openssl/opensslv.h") }
+else
+ checking_for("OpenSSL version >= 1.0.1 and < 3.0.0") {
+ try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") &&
+ !try_static_assert("OPENSSL_VERSION_MAJOR >= 3", "openssl/opensslv.h") }
+end
+unless version_ok
+ raise "OpenSSL >= 1.0.1, < 3.0.0 or LibreSSL >= 2.5.0 is required"
+end
+
+# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h
+if is_libressl && ($mswin || $mingw)
+ $defs.push("-DNOCRYPT")
end
Logging::message "=== Checking for OpenSSL features... ===\n"
# compile options
have_func("RAND_egd")
-engines = %w{builtin_engines openbsd_dev_crypto dynamic 4758cca aep atalla chil
- cswift nuron sureware ubsec padlock capi gmp gost cryptodev aesni}
+engines = %w{dynamic 4758cca aep atalla chil
+ cswift nuron sureware ubsec padlock capi gmp gost cryptodev}
engines.each { |name|
- OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h")
+ have_func("ENGINE_load_#{name}()", "openssl/engine.h")
}
# added in 1.0.2
@@ -116,14 +132,17 @@ have_func("EC_curve_nist2nid")
have_func("X509_REVOKED_dup")
have_func("X509_STORE_CTX_get0_store")
have_func("SSL_CTX_set_alpn_select_cb")
-OpenSSL.check_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h")
-OpenSSL.check_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h")
-OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h")
+have_func("SSL_CTX_set1_curves_list(NULL, NULL)", "openssl/ssl.h")
+have_func("SSL_CTX_set_ecdh_auto(NULL, 0)", "openssl/ssl.h")
+have_func("SSL_get_server_tmp_key(NULL, NULL)", "openssl/ssl.h")
have_func("SSL_is_server")
# added in 1.1.0
+if !have_struct_member("SSL", "ctx", "openssl/ssl.h") ||
+ try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x2070000fL", "openssl/opensslv.h")
+ $defs.push("-DHAVE_OPAQUE_OPENSSL")
+end
have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API")
-have_struct_member("SSL", "ctx", "openssl/ssl.h") || $defs.push("-DHAVE_OPAQUE_OPENSSL")
have_func("BN_GENCB_new")
have_func("BN_GENCB_free")
have_func("BN_GENCB_get_arg")
@@ -131,9 +150,9 @@ have_func("EVP_MD_CTX_new")
have_func("EVP_MD_CTX_free")
have_func("HMAC_CTX_new")
have_func("HMAC_CTX_free")
-OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated
have_func("X509_STORE_get_ex_data")
have_func("X509_STORE_set_ex_data")
+have_func("X509_STORE_get_ex_new_index")
have_func("X509_CRL_get0_signature")
have_func("X509_REQ_get0_signature")
have_func("X509_REVOKED_get0_serialNumber")
@@ -149,12 +168,20 @@ have_func("X509_CRL_up_ref")
have_func("X509_STORE_up_ref")
have_func("SSL_SESSION_up_ref")
have_func("EVP_PKEY_up_ref")
-OpenSSL.check_func_or_macro("SSL_CTX_set_tmp_ecdh_callback", "openssl/ssl.h") # removed
-OpenSSL.check_func_or_macro("SSL_CTX_set_min_proto_version", "openssl/ssl.h")
+have_func("SSL_CTX_set_tmp_ecdh_callback(NULL, NULL)", "openssl/ssl.h") # removed
+have_func("SSL_CTX_set_min_proto_version(NULL, 0)", "openssl/ssl.h")
have_func("SSL_CTX_get_security_level")
have_func("X509_get0_notBefore")
have_func("SSL_SESSION_get_protocol_version")
+have_func("TS_STATUS_INFO_get0_status")
+have_func("TS_STATUS_INFO_get0_text")
+have_func("TS_STATUS_INFO_get0_failure_info")
+have_func("TS_VERIFY_CTS_set_certs")
+have_func("TS_VERIFY_CTX_set_store")
+have_func("TS_VERIFY_CTX_add_flags")
+have_func("TS_RESP_CTX_set_time_cb")
have_func("EVP_PBE_scrypt")
+have_func("SSL_CTX_set_post_handshake_auth")
Logging::message "=== Checking done. ===\n"
diff --git a/ext/openssl/lib/openssl.rb b/ext/openssl/lib/openssl.rb
index 0914282920..b047485785 100644
--- a/ext/openssl/lib/openssl.rb
+++ b/ext/openssl/lib/openssl.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
=begin
= Info
'OpenSSL for Ruby 2' project
@@ -12,11 +12,27 @@
require 'openssl.so'
-require 'openssl/bn'
-require 'openssl/pkey'
-require 'openssl/cipher'
-require 'openssl/config'
-require 'openssl/digest'
-require 'openssl/x509'
-require 'openssl/ssl'
-require 'openssl/pkcs5'
+require_relative 'openssl/bn'
+require_relative 'openssl/pkey'
+require_relative 'openssl/cipher'
+require_relative 'openssl/config'
+require_relative 'openssl/digest'
+require_relative 'openssl/hmac'
+require_relative 'openssl/x509'
+require_relative 'openssl/ssl'
+require_relative 'openssl/pkcs5'
+require_relative 'openssl/version'
+
+module OpenSSL
+ # call-seq:
+ # OpenSSL.secure_compare(string, string) -> boolean
+ #
+ # Constant time memory comparison. Inputs are hashed using SHA-256 to mask
+ # the length of the secret. Returns +true+ if the strings are identical,
+ # +false+ otherwise.
+ def self.secure_compare(a, b)
+ hashed_a = OpenSSL::Digest.digest('SHA256', a)
+ hashed_b = OpenSSL::Digest.digest('SHA256', b)
+ OpenSSL.fixed_length_secure_compare(hashed_a, hashed_b) && a == b
+ end
+end
diff --git a/ext/openssl/lib/openssl/bn.rb b/ext/openssl/lib/openssl/bn.rb
index 8d1ebefb6e..0a5e11b4c2 100644
--- a/ext/openssl/lib/openssl/bn.rb
+++ b/ext/openssl/lib/openssl/bn.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
#
# = Ruby-space definitions that completes C-space funcs for BN
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb
index 8b5dd9da57..32e04b4896 100644
--- a/ext/openssl/lib/openssl/buffering.rb
+++ b/ext/openssl/lib/openssl/buffering.rb
@@ -1,5 +1,5 @@
# coding: binary
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
#= Info
# 'OpenSSL for Ruby 2' project
@@ -22,6 +22,29 @@
module OpenSSL::Buffering
include Enumerable
+ # A buffer which will retain binary encoding.
+ class Buffer < String
+ BINARY = Encoding::BINARY
+
+ def initialize
+ super
+
+ force_encoding(BINARY)
+ end
+
+ def << string
+ if string.encoding == BINARY
+ super(string)
+ else
+ super(string.b)
+ end
+
+ return self
+ end
+
+ alias concat <<
+ end
+
##
# The "sync mode" of the SSLSocket.
#
@@ -40,7 +63,7 @@ module OpenSSL::Buffering
def initialize(*)
super
@eof = false
- @rbuffer = ""
+ @rbuffer = Buffer.new
@sync = @io.sync
end
@@ -312,24 +335,19 @@ module OpenSSL::Buffering
# buffer is flushed to the underlying socket.
def do_write(s)
- @wbuffer = "" unless defined? @wbuffer
+ @wbuffer = Buffer.new unless defined? @wbuffer
@wbuffer << s
@wbuffer.force_encoding(Encoding::BINARY)
@sync ||= false
- if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)
- remain = idx ? idx + $/.size : @wbuffer.length
- nwritten = 0
- while remain > 0
- str = @wbuffer[nwritten,remain]
+ if @sync or @wbuffer.size > BLOCK_SIZE
+ until @wbuffer.empty?
begin
- nwrote = syswrite(str)
+ nwrote = syswrite(@wbuffer)
rescue Errno::EAGAIN
retry
end
- remain -= nwrote
- nwritten += nwrote
+ @wbuffer[0, nwrote] = ""
end
- @wbuffer[0,nwritten] = ""
end
end
@@ -339,9 +357,11 @@ module OpenSSL::Buffering
# Writes _s_ to the stream. If the argument is not a String it will be
# converted using +.to_s+ method. Returns the number of bytes written.
- def write(s)
- do_write(s)
- s.bytesize
+ def write(*s)
+ s.inject(0) do |written, str|
+ do_write(str)
+ written + str.bytesize
+ end
end
##
@@ -401,15 +421,13 @@ module OpenSSL::Buffering
# See IO#puts for full details.
def puts(*args)
- s = ""
+ s = Buffer.new
if args.empty?
s << "\n"
end
args.each{|arg|
s << arg.to_s
- if $/ && /\n\z/ !~ s
- s << "\n"
- end
+ s.sub!(/(?<!\n)\z/, "\n")
}
do_write(s)
nil
@@ -421,7 +439,7 @@ module OpenSSL::Buffering
# See IO#print for full details.
def print(*args)
- s = ""
+ s = Buffer.new
args.each{ |arg| s << arg.to_s }
do_write(s)
nil
diff --git a/ext/openssl/lib/openssl/cipher.rb b/ext/openssl/lib/openssl/cipher.rb
index af721b3a80..8ad8c35dd3 100644
--- a/ext/openssl/lib/openssl/cipher.rb
+++ b/ext/openssl/lib/openssl/cipher.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
# = Ruby-space predefined Cipher subclasses
#
diff --git a/ext/openssl/lib/openssl/config.rb b/ext/openssl/lib/openssl/config.rb
index 48d8be0069..9a0b787420 100644
--- a/ext/openssl/lib/openssl/config.rb
+++ b/ext/openssl/lib/openssl/config.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
=begin
= Ruby-space definitions that completes C-space funcs for Config
@@ -37,7 +37,7 @@ module OpenSSL
def parse(string)
c = new()
parse_config(StringIO.new(string)).each do |section, hash|
- c[section] = hash
+ c.set_section(section, hash)
end
c
end
@@ -53,9 +53,8 @@ module OpenSSL
def parse_config(io)
begin
parse_config_lines(io)
- rescue ConfigError => e
- e.message.replace("error in line #{io.lineno}: " + e.message)
- raise
+ rescue => error
+ raise ConfigError, "error in line #{io.lineno}: " + error.message
end
end
@@ -77,29 +76,44 @@ module OpenSSL
def parse_config_lines(io)
section = 'default'
data = {section => {}}
- while definition = get_definition(io)
+ io_stack = [io]
+ while definition = get_definition(io_stack)
definition = clear_comments(definition)
next if definition.empty?
- if definition[0] == ?[
+ case definition
+ when /\A\[/
if /\[([^\]]*)\]/ =~ definition
section = $1.strip
data[section] ||= {}
else
raise ConfigError, "missing close square bracket"
end
- else
- if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
- if $2
- section = $1
- key = $2
- else
- key = $1
+ when /\A\.include (\s*=\s*)?(.+)\z/
+ path = $2
+ if File.directory?(path)
+ files = Dir.glob(File.join(path, "*.{cnf,conf}"), File::FNM_EXTGLOB)
+ else
+ files = [path]
+ end
+
+ files.each do |filename|
+ begin
+ io_stack << StringIO.new(File.read(filename))
+ rescue
+ raise ConfigError, "could not include file '%s'" % filename
end
- value = unescape_value(data, section, $3)
- (data[section] ||= {})[key] = value.strip
+ end
+ when /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/
+ if $2
+ section = $1
+ key = $2
else
- raise ConfigError, "missing equal sign"
+ key = $1
end
+ value = unescape_value(data, section, $3)
+ (data[section] ||= {})[key] = value.strip
+ else
+ raise ConfigError, "missing equal sign"
end
end
data
@@ -212,10 +226,10 @@ module OpenSSL
scanned.join
end
- def get_definition(io)
- if line = get_line(io)
+ def get_definition(io_stack)
+ if line = get_line(io_stack)
while /[^\\]\\\z/ =~ line
- if extra = get_line(io)
+ if extra = get_line(io_stack)
line += extra
else
break
@@ -225,9 +239,12 @@ module OpenSSL
end
end
- def get_line(io)
- if line = io.gets
- line.gsub(/[\r\n]*/, '')
+ def get_line(io_stack)
+ while io = io_stack.last
+ if line = io.gets
+ return line.gsub(/[\r\n]*/, '')
+ end
+ io_stack.pop
end
end
end
@@ -249,7 +266,7 @@ module OpenSSL
if filename
File.open(filename.to_s) do |file|
Config.parse_config(file).each do |section, hash|
- self[section] = hash
+ set_section(section, hash)
end
end
end
@@ -298,6 +315,8 @@ module OpenSSL
end
##
+ # *Deprecated in v2.2.0*. This method will be removed in a future release.
+ #
# Set the target _key_ with a given _value_ under a specific _section_.
#
# Given the following configurating file being loaded:
@@ -352,6 +371,8 @@ module OpenSSL
end
##
+ # *Deprecated in v2.2.0*. This method will be removed in a future release.
+ #
# Sets a specific _section_ name with a Hash _pairs_.
#
# Given the following configuration being created:
@@ -377,9 +398,13 @@ module OpenSSL
#
def []=(section, pairs)
check_modify
- @data[section] ||= {}
+ set_section(section, pairs)
+ end
+
+ def set_section(section, pairs) # :nodoc:
+ hash = @data[section] ||= {}
pairs.each do |key, value|
- self.add_value(section, key, value)
+ hash[key] = value
end
end
@@ -464,6 +489,8 @@ module OpenSSL
end
def check_modify
+ warn "#{caller(2, 1)[0]}: warning: do not modify OpenSSL::Config; this " \
+ "method is deprecated and will be removed in a future release."
raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
end
diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb
index b6744de6bd..2ff8398e44 100644
--- a/ext/openssl/lib/openssl/digest.rb
+++ b/ext/openssl/lib/openssl/digest.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
# = Ruby-space predefined Digest subclasses
#
@@ -15,11 +15,6 @@
module OpenSSL
class Digest
- alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
- if OPENSSL_VERSION_NUMBER < 0x10100000
- alg += %w(DSS DSS1 SHA)
- end
-
# Return the hash value computed with _name_ Digest. _name_ is either the
# long name or short name of a supported digest algorithm.
#
@@ -29,23 +24,26 @@ module OpenSSL
#
# which is equivalent to:
#
- # OpenSSL::Digest::SHA256.digest("abc")
+ # OpenSSL::Digest.digest('SHA256', "abc")
def self.digest(name, data)
super(data, name)
end
- alg.each{|name|
+ %w(MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512).each do |name|
klass = Class.new(self) {
define_method(:initialize, ->(data = nil) {super(name, data)})
}
+
singleton = (class << klass; self; end)
+
singleton.class_eval{
- define_method(:digest){|data| new.digest(data) }
- define_method(:hexdigest){|data| new.hexdigest(data) }
+ define_method(:digest) {|data| new.digest(data)}
+ define_method(:hexdigest) {|data| new.hexdigest(data)}
}
- const_set(name, klass)
- }
+
+ const_set(name.tr('-', '_'), klass)
+ end
# Deprecated.
#
diff --git a/ext/openssl/lib/openssl/hmac.rb b/ext/openssl/lib/openssl/hmac.rb
new file mode 100644
index 0000000000..3d4427611d
--- /dev/null
+++ b/ext/openssl/lib/openssl/hmac.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module OpenSSL
+ class HMAC
+ # Securely compare with another HMAC instance in constant time.
+ def ==(other)
+ return false unless HMAC === other
+ return false unless self.digest.bytesize == other.digest.bytesize
+
+ OpenSSL.fixed_length_secure_compare(self.digest, other.digest)
+ end
+ end
+end
diff --git a/ext/openssl/lib/openssl/marshal.rb b/ext/openssl/lib/openssl/marshal.rb
new file mode 100644
index 0000000000..af5647192a
--- /dev/null
+++ b/ext/openssl/lib/openssl/marshal.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+#--
+# = Ruby-space definitions to add DER (de)serialization to classes
+#
+# = Info
+# 'OpenSSL for Ruby 2' project
+# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
+# All rights reserved.
+#
+# = Licence
+# This program is licensed under the same licence as Ruby.
+# (See the file 'LICENCE'.)
+#++
+module OpenSSL
+ module Marshal
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def _load(string)
+ new(string)
+ end
+ end
+
+ def _dump(_level)
+ to_der
+ end
+ end
+end
diff --git a/ext/openssl/lib/openssl/pkcs5.rb b/ext/openssl/lib/openssl/pkcs5.rb
index 959447df5e..8dedc4beef 100644
--- a/ext/openssl/lib/openssl/pkcs5.rb
+++ b/ext/openssl/lib/openssl/pkcs5.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
# Ruby/OpenSSL Project
# Copyright (C) 2017 Ruby/OpenSSL Project Authors
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index dcedd849a0..9cc3276356 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -1,3 +1,42 @@
-# frozen_string_literal: false
-module OpenSSL
+# frozen_string_literal: true
+#--
+# Ruby/OpenSSL Project
+# Copyright (C) 2017 Ruby/OpenSSL Project Authors
+#++
+
+require_relative 'marshal'
+
+module OpenSSL::PKey
+ class DH
+ include OpenSSL::Marshal
+ end
+
+ class DSA
+ include OpenSSL::Marshal
+ end
+
+ if defined?(EC)
+ class EC
+ include OpenSSL::Marshal
+ end
+ class EC::Point
+ # :call-seq:
+ # point.to_bn([conversion_form]) -> OpenSSL::BN
+ #
+ # Returns the octet string representation of the EC point as an instance of
+ # OpenSSL::BN.
+ #
+ # If _conversion_form_ is not given, the _point_conversion_form_ attribute
+ # set to the group is used.
+ #
+ # See #to_octet_string for more information.
+ def to_bn(conversion_form = group.point_conversion_form)
+ OpenSSL::BN.new(to_octet_string(conversion_form), 2)
+ end
+ end
+ end
+
+ class RSA
+ include OpenSSL::Marshal
+ end
end
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index a628648e71..8e12007383 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
=begin
= Info
'OpenSSL for Ruby 2' project
@@ -12,6 +12,8 @@
require "openssl/buffering"
require "io/nonblock"
+require "ipaddr"
+require "socket"
module OpenSSL
module SSL
@@ -136,6 +138,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
# used.
def set_params(params={})
params = DEFAULT_PARAMS.merge(params)
+ self.options = params.delete(:options) # set before min_version/max_version
params.each{|name, value| self.__send__("#{name}=", value) }
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
unless self.ca_file or self.ca_path or self.cert_store
@@ -201,7 +204,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
if /(?<type>_client|_server)\z/ =~ meth
meth = $`
if $VERBOSE
- warn "#{caller(1)[0]}: method type #{type.inspect} is ignored"
+ warn "#{caller(1, 1)[0]}: method type #{type.inspect} is ignored"
end
end
version = METHODS_MAP[meth.intern] or
@@ -229,6 +232,11 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
end
module SocketForwarder
+ # The file descriptor for the socket.
+ def fileno
+ to_io.fileno
+ end
+
def addr
to_io.addr
end
@@ -271,11 +279,11 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
return true if verify_hostname(hostname, san.value)
when 7 # iPAddress in GeneralName (RFC5280)
should_verify_common_name = false
- # follows GENERAL_NAME_print() in x509v3/v3_alt.c
- if san.value.size == 4
- return true if san.value.unpack('C*').join('.') == hostname
- elsif san.value.size == 16
- return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
+ if san.value.size == 4 || san.value.size == 16
+ begin
+ return true if san.value == IPAddr.new(hostname).hton
+ rescue IPAddr::InvalidAddressError
+ end
end
end
}
@@ -433,6 +441,38 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
def session_get_cb
@context.session_get_cb
end
+
+ class << self
+
+ # call-seq:
+ # open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil)
+ #
+ # Creates a new instance of SSLSocket.
+ # _remote\_host_ and _remote\_port_ are used to open TCPSocket.
+ # If _local\_host_ and _local\_port_ are specified,
+ # then those parameters are used on the local end to establish the connection.
+ # If _context_ is provided,
+ # the SSL Sockets initial params will be taken from the context.
+ #
+ # === Examples
+ #
+ # sock = OpenSSL::SSL::SSLSocket.open('localhost', 443)
+ # sock.connect # Initiates a connection to localhost:443
+ #
+ # with SSLContext:
+ #
+ # ctx = OpenSSL::SSL::SSLContext.new
+ # sock = OpenSSL::SSL::SSLSocket.open('localhost', 443, context: ctx)
+ # sock.connect # Initiates a connection to localhost:443 with SSLContext
+ def open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil)
+ sock = ::TCPSocket.open(remote_host, remote_port, local_host, local_port)
+ if context.nil?
+ return OpenSSL::SSL::SSLSocket.new(sock)
+ else
+ return OpenSSL::SSL::SSLSocket.new(sock, context)
+ end
+ end
+ end
end
##
@@ -463,7 +503,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
end
# See TCPServer#listen for details.
- def listen(backlog=5)
+ def listen(backlog=Socket::SOMAXCONN)
@svr.listen(backlog)
end
diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb
new file mode 100644
index 0000000000..89e052069e
--- /dev/null
+++ b/ext/openssl/lib/openssl/version.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module OpenSSL
+ VERSION = "2.2.2"
+end
diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb
index 6d31b98c68..6771b90c1a 100644
--- a/ext/openssl/lib/openssl/x509.rb
+++ b/ext/openssl/lib/openssl/x509.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
# = Ruby-space definitions that completes C-space funcs for X509 and subclasses
#
@@ -12,6 +12,8 @@
# (See the file 'LICENCE'.)
#++
+require_relative 'marshal'
+
module OpenSSL
module X509
class ExtensionFactory
@@ -41,6 +43,13 @@ module OpenSSL
end
class Extension
+ include OpenSSL::Marshal
+
+ def ==(other)
+ return false unless Extension === other
+ to_der == other.to_der
+ end
+
def to_s # "oid = critical, value"
str = self.oid
str << " = "
@@ -55,9 +64,146 @@ module OpenSSL
def to_a
[ self.oid, self.value, self.critical? ]
end
+
+ module Helpers
+ def find_extension(oid)
+ extensions.find { |e| e.oid == oid }
+ end
+ end
+
+ module SubjectKeyIdentifier
+ include Helpers
+
+ # Get the subject's key identifier from the subjectKeyIdentifier
+ # exteension, as described in RFC5280 Section 4.2.1.2.
+ #
+ # Returns the binary String key identifier or nil or raises
+ # ASN1::ASN1Error.
+ def subject_key_identifier
+ ext = find_extension("subjectKeyIdentifier")
+ return nil if ext.nil?
+
+ ski_asn1 = ASN1.decode(ext.value_der)
+ if ext.critical? || ski_asn1.tag_class != :UNIVERSAL || ski_asn1.tag != ASN1::OCTET_STRING
+ raise ASN1::ASN1Error, "invalid extension"
+ end
+
+ ski_asn1.value
+ end
+ end
+
+ module AuthorityKeyIdentifier
+ include Helpers
+
+ # Get the issuing certificate's key identifier from the
+ # authorityKeyIdentifier extension, as described in RFC5280
+ # Section 4.2.1.1
+ #
+ # Returns the binary String keyIdentifier or nil or raises
+ # ASN1::ASN1Error.
+ def authority_key_identifier
+ ext = find_extension("authorityKeyIdentifier")
+ return nil if ext.nil?
+
+ aki_asn1 = ASN1.decode(ext.value_der)
+ if ext.critical? || aki_asn1.tag_class != :UNIVERSAL || aki_asn1.tag != ASN1::SEQUENCE
+ raise ASN1::ASN1Error, "invalid extension"
+ end
+
+ key_id = aki_asn1.value.find do |v|
+ v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
+ end
+
+ key_id.nil? ? nil : key_id.value
+ end
+ end
+
+ module CRLDistributionPoints
+ include Helpers
+
+ # Get the distributionPoint fullName URI from the certificate's CRL
+ # distribution points extension, as described in RFC5280 Section
+ # 4.2.1.13
+ #
+ # Returns an array of strings or nil or raises ASN1::ASN1Error.
+ def crl_uris
+ ext = find_extension("crlDistributionPoints")
+ return nil if ext.nil?
+
+ cdp_asn1 = ASN1.decode(ext.value_der)
+ if cdp_asn1.tag_class != :UNIVERSAL || cdp_asn1.tag != ASN1::SEQUENCE
+ raise ASN1::ASN1Error, "invalid extension"
+ end
+
+ crl_uris = cdp_asn1.map do |crl_distribution_point|
+ distribution_point = crl_distribution_point.value.find do |v|
+ v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
+ end
+ full_name = distribution_point&.value&.find do |v|
+ v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
+ end
+ full_name&.value&.find do |v|
+ v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier
+ end
+ end
+
+ crl_uris&.map(&:value)
+ end
+ end
+
+ module AuthorityInfoAccess
+ include Helpers
+
+ # Get the information and services for the issuer from the certificate's
+ # authority information access extension exteension, as described in RFC5280
+ # Section 4.2.2.1.
+ #
+ # Returns an array of strings or nil or raises ASN1::ASN1Error.
+ def ca_issuer_uris
+ aia_asn1 = parse_aia_asn1
+ return nil if aia_asn1.nil?
+
+ ca_issuer = aia_asn1.value.select do |authority_info_access|
+ authority_info_access.value.first.value == "caIssuers"
+ end
+
+ ca_issuer&.map(&:value)&.map(&:last)&.map(&:value)
+ end
+
+ # Get the URIs for OCSP from the certificate's authority information access
+ # extension exteension, as described in RFC5280 Section 4.2.2.1.
+ #
+ # Returns an array of strings or nil or raises ASN1::ASN1Error.
+ def ocsp_uris
+ aia_asn1 = parse_aia_asn1
+ return nil if aia_asn1.nil?
+
+ ocsp = aia_asn1.value.select do |authority_info_access|
+ authority_info_access.value.first.value == "OCSP"
+ end
+
+ ocsp&.map(&:value)&.map(&:last)&.map(&:value)
+ end
+
+ private
+
+ def parse_aia_asn1
+ ext = find_extension("authorityInfoAccess")
+ return nil if ext.nil?
+
+ aia_asn1 = ASN1.decode(ext.value_der)
+ if ext.critical? || aia_asn1.tag_class != :UNIVERSAL || aia_asn1.tag != ASN1::SEQUENCE
+ raise ASN1::ASN1Error, "invalid extension"
+ end
+
+ aia_asn1
+ end
+ end
end
class Name
+ include OpenSSL::Marshal
+
module RFC2253DN
Special = ',=+<>#;'
HexChar = /[0-9a-fA-F]/
@@ -160,6 +306,15 @@ module OpenSSL
end
end
+ class Attribute
+ include OpenSSL::Marshal
+
+ def ==(other)
+ return false unless Attribute === other
+ to_der == other.to_der
+ end
+ end
+
class StoreContext
def cleanup
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
@@ -167,6 +322,12 @@ module OpenSSL
end
class Certificate
+ include OpenSSL::Marshal
+ include Extension::SubjectKeyIdentifier
+ include Extension::AuthorityKeyIdentifier
+ include Extension::CRLDistributionPoints
+ include Extension::AuthorityInfoAccess
+
def pretty_print(q)
q.object_group(self) {
q.breakable
@@ -178,5 +339,31 @@ module OpenSSL
}
end
end
+
+ class CRL
+ include OpenSSL::Marshal
+ include Extension::AuthorityKeyIdentifier
+
+ def ==(other)
+ return false unless CRL === other
+ to_der == other.to_der
+ end
+ end
+
+ class Revoked
+ def ==(other)
+ return false unless Revoked === other
+ to_der == other.to_der
+ end
+ end
+
+ class Request
+ include OpenSSL::Marshal
+
+ def ==(other)
+ return false unless Request === other
+ to_der == other.to_der
+ end
+ end
end
end
diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec
index a8b21a561b..c8e3cc3fc3 100644
--- a/ext/openssl/openssl.gemspec
+++ b/ext/openssl/openssl.gemspec
@@ -1,46 +1,27 @@
-# -*- encoding: utf-8 -*-
-# stub: openssl 2.1.0.beta1 ruby lib
-# stub: ext/openssl/extconf.rb
+Gem::Specification.new do |spec|
+ spec.name = "openssl"
+ spec.version = "2.2.2"
+ spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"]
+ spec.email = ["ruby-core@ruby-lang.org"]
+ spec.summary = %q{OpenSSL provides SSL, TLS and general purpose cryptography.}
+ spec.description = %q{It wraps the OpenSSL library.}
+ spec.homepage = "https://github.com/ruby/openssl"
+ spec.license = "Ruby"
-Gem::Specification.new do |s|
- s.name = "openssl".freeze
- s.version = "2.1.0.beta1"
+ spec.files = Dir["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md", "BSDL", "LICENSE.txt"]
+ spec.require_paths = ["lib"]
+ spec.extensions = ["ext/openssl/extconf.rb"]
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
- s.metadata = { "msys2_mingw_dependencies" => "openssl" } if s.respond_to? :metadata=
- s.require_paths = ["lib".freeze]
- s.authors = ["Martin Bosslet".freeze, "SHIBATA Hiroshi".freeze, "Zachary Scott".freeze, "Kazuki Yamaguchi".freeze]
- s.date = "2017-09-24"
- s.description = "It wraps the OpenSSL library.".freeze
- s.email = ["ruby-core@ruby-lang.org".freeze]
- s.extensions = ["ext/openssl/extconf.rb".freeze]
- s.extra_rdoc_files = ["CONTRIBUTING.md".freeze, "History.md".freeze, "README.md".freeze]
- s.files = ["BSDL".freeze, "CONTRIBUTING.md".freeze, "History.md".freeze, "LICENSE.txt".freeze, "README.md".freeze, "ext/openssl/deprecation.rb".freeze, "ext/openssl/extconf.rb".freeze, "ext/openssl/openssl_missing.c".freeze, "ext/openssl/openssl_missing.h".freeze, "ext/openssl/ossl.c".freeze, "ext/openssl/ossl.h".freeze, "ext/openssl/ossl_asn1.c".freeze, "ext/openssl/ossl_asn1.h".freeze, "ext/openssl/ossl_bio.c".freeze, "ext/openssl/ossl_bio.h".freeze, "ext/openssl/ossl_bn.c".freeze, "ext/openssl/ossl_bn.h".freeze, "ext/openssl/ossl_cipher.c".freeze, "ext/openssl/ossl_cipher.h".freeze, "ext/openssl/ossl_config.c".freeze, "ext/openssl/ossl_config.h".freeze, "ext/openssl/ossl_digest.c".freeze, "ext/openssl/ossl_digest.h".freeze, "ext/openssl/ossl_engine.c".freeze, "ext/openssl/ossl_engine.h".freeze, "ext/openssl/ossl_hmac.c".freeze, "ext/openssl/ossl_hmac.h".freeze, "ext/openssl/ossl_kdf.c".freeze, "ext/openssl/ossl_kdf.h".freeze, "ext/openssl/ossl_ns_spki.c".freeze, "ext/openssl/ossl_ns_spki.h".freeze, "ext/openssl/ossl_ocsp.c".freeze, "ext/openssl/ossl_ocsp.h".freeze, "ext/openssl/ossl_pkcs12.c".freeze, "ext/openssl/ossl_pkcs12.h".freeze, "ext/openssl/ossl_pkcs7.c".freeze, "ext/openssl/ossl_pkcs7.h".freeze, "ext/openssl/ossl_pkey.c".freeze, "ext/openssl/ossl_pkey.h".freeze, "ext/openssl/ossl_pkey_dh.c".freeze, "ext/openssl/ossl_pkey_dsa.c".freeze, "ext/openssl/ossl_pkey_ec.c".freeze, "ext/openssl/ossl_pkey_rsa.c".freeze, "ext/openssl/ossl_rand.c".freeze, "ext/openssl/ossl_rand.h".freeze, "ext/openssl/ossl_ssl.c".freeze, "ext/openssl/ossl_ssl.h".freeze, "ext/openssl/ossl_ssl_session.c".freeze, "ext/openssl/ossl_version.h".freeze, "ext/openssl/ossl_x509.c".freeze, "ext/openssl/ossl_x509.h".freeze, "ext/openssl/ossl_x509attr.c".freeze, "ext/openssl/ossl_x509cert.c".freeze, "ext/openssl/ossl_x509crl.c".freeze, "ext/openssl/ossl_x509ext.c".freeze, "ext/openssl/ossl_x509name.c".freeze, "ext/openssl/ossl_x509req.c".freeze, "ext/openssl/ossl_x509revoked.c".freeze, "ext/openssl/ossl_x509store.c".freeze, "ext/openssl/ruby_missing.h".freeze, "lib/openssl.rb".freeze, "lib/openssl/bn.rb".freeze, "lib/openssl/buffering.rb".freeze, "lib/openssl/cipher.rb".freeze, "lib/openssl/config.rb".freeze, "lib/openssl/digest.rb".freeze, "lib/openssl/pkcs5.rb".freeze, "lib/openssl/pkey.rb".freeze, "lib/openssl/ssl.rb".freeze, "lib/openssl/x509.rb".freeze]
- s.homepage = "https://github.com/ruby/openssl".freeze
- s.licenses = ["Ruby".freeze]
- s.rdoc_options = ["--main".freeze, "README.md".freeze]
- s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze)
- s.rubygems_version = "2.6.13".freeze
- s.summary = "OpenSSL provides SSL, TLS and general purpose cryptography.".freeze
+ spec.extra_rdoc_files = Dir["*.md"]
+ spec.rdoc_options = ["--main", "README.md"]
- if s.respond_to? :specification_version then
- s.specification_version = 4
+ spec.required_ruby_version = ">= 2.3.0"
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
- s.add_development_dependency(%q<rake>.freeze, [">= 0"])
- s.add_development_dependency(%q<rake-compiler>.freeze, [">= 0"])
- s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.0"])
- s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
- else
- s.add_dependency(%q<rake>.freeze, [">= 0"])
- s.add_dependency(%q<rake-compiler>.freeze, [">= 0"])
- s.add_dependency(%q<test-unit>.freeze, ["~> 3.0"])
- s.add_dependency(%q<rdoc>.freeze, [">= 0"])
- end
- else
- s.add_dependency(%q<rake>.freeze, [">= 0"])
- s.add_dependency(%q<rake-compiler>.freeze, [">= 0"])
- s.add_dependency(%q<test-unit>.freeze, ["~> 3.0"])
- s.add_dependency(%q<rdoc>.freeze, [">= 0"])
- end
+ spec.add_runtime_dependency "ipaddr"
+ spec.add_development_dependency "rake", ">= 11.2.0"
+ spec.add_development_dependency "rake-compiler"
+ spec.add_development_dependency "test-unit", "~> 3.0"
+ spec.add_development_dependency "rdoc"
+
+ spec.metadata["msys2_mingw_dependencies"] = "openssl"
end
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
index cc31f6ace7..7d218f86f5 100644
--- a/ext/openssl/openssl_missing.h
+++ b/ext/openssl/openssl_missing.h
@@ -72,6 +72,9 @@ void ossl_HMAC_CTX_free(HMAC_CTX *);
#if !defined(HAVE_X509_STORE_SET_EX_DATA)
# define X509_STORE_set_ex_data(x, idx, data) \
CRYPTO_set_ex_data(&(x)->ex_data, (idx), (data))
+#endif
+
+#if !defined(HAVE_X509_STORE_GET_EX_NEW_INDEX) && !defined(X509_STORE_get_ex_new_index)
# define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \
CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \
(newf), (dupf), (freef))
@@ -144,12 +147,13 @@ void ossl_X509_REQ_get0_signature(const X509_REQ *, const ASN1_BIT_STRING **, co
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY);
#endif
-#if !defined(HAVE_OPAQUE_OPENSSL)
+#if !defined(HAVE_OPAQUE_OPENSSL) && \
+ (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2070000fL)
#define IMPL_PKEY_GETTER(_type, _name) \
static inline _type *EVP_PKEY_get0_##_type(EVP_PKEY *pkey) { \
return pkey->pkey._name; }
#define IMPL_KEY_ACCESSOR2(_type, _group, a1, a2, _fail_cond) \
-static inline void _type##_get0_##_group(_type *obj, const BIGNUM **a1, const BIGNUM **a2) { \
+static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2) { \
if (a1) *a1 = obj->a1; \
if (a2) *a2 = obj->a2; } \
static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2) { \
@@ -158,7 +162,7 @@ static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2) { \
BN_clear_free(obj->a2); obj->a2 = a2; \
return 1; }
#define IMPL_KEY_ACCESSOR3(_type, _group, a1, a2, a3, _fail_cond) \
-static inline void _type##_get0_##_group(_type *obj, const BIGNUM **a1, const BIGNUM **a2, const BIGNUM **a3) { \
+static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2, const BIGNUM **a3) { \
if (a1) *a1 = obj->a1; \
if (a2) *a2 = obj->a2; \
if (a3) *a3 = obj->a3; } \
@@ -185,7 +189,7 @@ IMPL_KEY_ACCESSOR3(DSA, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g
#if !defined(OPENSSL_NO_DH)
IMPL_PKEY_GETTER(DH, dh)
IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key)))
-IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || obj->q && q == obj->q || g == obj->g))
+IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || (obj->q && q == obj->q) || g == obj->g))
static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; }
#endif
@@ -209,10 +213,45 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
# define X509_get0_notAfter(x) X509_get_notAfter(x)
# define X509_CRL_get0_lastUpdate(x) X509_CRL_get_lastUpdate(x)
# define X509_CRL_get0_nextUpdate(x) X509_CRL_get_nextUpdate(x)
+# define X509_set1_notBefore(x, t) X509_set_notBefore(x, t)
+# define X509_set1_notAfter(x, t) X509_set_notAfter(x, t)
+# define X509_CRL_set1_lastUpdate(x, t) X509_CRL_set_lastUpdate(x, t)
+# define X509_CRL_set1_nextUpdate(x, t) X509_CRL_set_nextUpdate(x, t)
#endif
#if !defined(HAVE_SSL_SESSION_GET_PROTOCOL_VERSION)
# define SSL_SESSION_get_protocol_version(s) ((s)->ssl_version)
#endif
+#if !defined(HAVE_TS_STATUS_INFO_GET0_STATUS)
+# define TS_STATUS_INFO_get0_status(a) ((a)->status)
+#endif
+
+#if !defined(HAVE_TS_STATUS_INFO_GET0_TEXT)
+# define TS_STATUS_INFO_get0_text(a) ((a)->text)
+#endif
+
+#if !defined(HAVE_TS_STATUS_INFO_GET0_FAILURE_INFO)
+# define TS_STATUS_INFO_get0_failure_info(a) ((a)->failure_info)
+#endif
+
+#if !defined(HAVE_TS_VERIFY_CTS_SET_CERTS)
+# define TS_VERIFY_CTS_set_certs(ctx, crts) ((ctx)->certs=(crts))
+#endif
+
+#if !defined(HAVE_TS_VERIFY_CTX_SET_STORE)
+# define TS_VERIFY_CTX_set_store(ctx, str) ((ctx)->store=(str))
+#endif
+
+#if !defined(HAVE_TS_VERIFY_CTX_ADD_FLAGS)
+# define TS_VERIFY_CTX_add_flags(ctx, f) ((ctx)->flags |= (f))
+#endif
+
+#if !defined(HAVE_TS_RESP_CTX_SET_TIME_CB)
+# define TS_RESP_CTX_set_time_cb(ctx, callback, dta) do { \
+ (ctx)->time_cb = (callback); \
+ (ctx)->time_cb_data = (dta); \
+ } while (0)
+#endif
+
#endif /* _OSSL_OPENSSL_MISSING_H_ */
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index 93ecc7d414..ce02efd983 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -338,7 +338,7 @@ ossl_clear_error(void)
* implementation.
*/
VALUE
-ossl_get_errors(void)
+ossl_get_errors(VALUE _)
{
VALUE ary;
long e;
@@ -398,7 +398,7 @@ ossl_debug_set(VALUE self, VALUE val)
}
/*
- * call-seq
+ * call-seq:
* OpenSSL.fips_mode -> true | false
*/
static VALUE
@@ -497,8 +497,11 @@ print_mem_leaks(VALUE self)
int ret;
#endif
- BN_CTX_free(ossl_bn_ctx);
- ossl_bn_ctx = NULL;
+#ifndef HAVE_RB_EXT_RACTOR_SAFE
+ // for Ruby 2.x
+ void ossl_bn_ctx_free(void); // ossl_bn.c
+ ossl_bn_ctx_free();
+#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000
ret = CRYPTO_mem_leaks_fp(stderr);
@@ -605,6 +608,35 @@ static void Init_ossl_locks(void)
#endif /* !HAVE_OPENSSL_110_THREADING_API */
/*
+ * call-seq:
+ * OpenSSL.fixed_length_secure_compare(string, string) -> boolean
+ *
+ * Constant time memory comparison for fixed length strings, such as results
+ * of HMAC calculations.
+ *
+ * Returns +true+ if the strings are identical, +false+ if they are of the same
+ * length but not identical. If the length is different, +ArgumentError+ is
+ * raised.
+ */
+static VALUE
+ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
+{
+ const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
+ const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
+ long len1 = RSTRING_LEN(str1);
+ long len2 = RSTRING_LEN(str2);
+
+ if (len1 != len2) {
+ ossl_raise(rb_eArgError, "inputs must be of equal length");
+ }
+
+ switch (CRYPTO_memcmp(p1, p2, len1)) {
+ case 0: return Qtrue;
+ default: return Qfalse;
+ }
+}
+
+/*
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
* OpenSSL[https://www.openssl.org/] library.
*
@@ -635,7 +667,7 @@ static void Init_ossl_locks(void)
* ahold of the key may use it unless it is encrypted. In order to securely
* export a key you may export it with a pass phrase.
*
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
+ * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
* pass_phrase = 'my secure pass phrase goes here'
*
* key_secure = key.export cipher, pass_phrase
@@ -710,16 +742,14 @@ static void Init_ossl_locks(void)
* To sign a document, a cryptographically secure hash of the document is
* computed first, which is then signed using the private key.
*
- * digest = OpenSSL::Digest::SHA256.new
- * signature = key.sign digest, document
+ * signature = key.sign 'SHA256', document
*
* To validate the signature, again a hash of the document is computed and
* the signature is decrypted using the public key. The result is then
* compared to the hash just computed, if they are equal the signature was
* valid.
*
- * digest = OpenSSL::Digest::SHA256.new
- * if key.verify digest, signature, document
+ * if key.verify 'SHA256', signature, document
* puts 'Valid'
* else
* puts 'Invalid'
@@ -745,7 +775,7 @@ static void Init_ossl_locks(void)
* using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
* the number of iterations largely depends on the hardware being used.
*
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
+ * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
* cipher.encrypt
* iv = cipher.random_iv
*
@@ -753,7 +783,7 @@ static void Init_ossl_locks(void)
* salt = OpenSSL::Random.random_bytes 16
* iter = 20000
* key_len = cipher.key_len
- * digest = OpenSSL::Digest::SHA256.new
+ * digest = OpenSSL::Digest.new('SHA256')
*
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
* cipher.key = key
@@ -768,7 +798,7 @@ static void Init_ossl_locks(void)
* Use the same steps as before to derive the symmetric AES key, this time
* setting the Cipher up for decryption.
*
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
+ * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
* cipher.decrypt
* cipher.iv = iv # the one generated with #random_iv
*
@@ -776,7 +806,7 @@ static void Init_ossl_locks(void)
* salt = ... # the one generated above
* iter = 20000
* key_len = cipher.key_len
- * digest = OpenSSL::Digest::SHA256.new
+ * digest = OpenSSL::Digest.new('SHA256')
*
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
* cipher.key = key
@@ -803,7 +833,7 @@ static void Init_ossl_locks(void)
*
* First set up the cipher for encryption
*
- * encryptor = OpenSSL::Cipher.new 'AES-128-CBC'
+ * encryptor = OpenSSL::Cipher.new 'AES-256-CBC'
* encryptor.encrypt
* encryptor.pkcs5_keyivgen pass_phrase, salt
*
@@ -816,7 +846,7 @@ static void Init_ossl_locks(void)
*
* Use a new Cipher instance set up for decryption
*
- * decryptor = OpenSSL::Cipher.new 'AES-128-CBC'
+ * decryptor = OpenSSL::Cipher.new 'AES-256-CBC'
* decryptor.decrypt
* decryptor.pkcs5_keyivgen pass_phrase, salt
*
@@ -833,7 +863,7 @@ static void Init_ossl_locks(void)
* signature.
*
* key = OpenSSL::PKey::RSA.new 2048
- * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
+ * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
*
* cert = OpenSSL::X509::Certificate.new
* cert.version = 2
@@ -872,7 +902,7 @@ static void Init_ossl_locks(void)
* certificate.
*
* cert.issuer = name
- * cert.sign key, OpenSSL::Digest::SHA1.new
+ * cert.sign key, OpenSSL::Digest.new('SHA1')
*
* open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
*
@@ -904,7 +934,7 @@ static void Init_ossl_locks(void)
* ca_key = OpenSSL::PKey::RSA.new 2048
* pass_phrase = 'my secure pass phrase goes here'
*
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
+ * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
*
* open 'ca_key.pem', 'w', 0400 do |io|
* io.write ca_key.export(cipher, pass_phrase)
@@ -915,7 +945,7 @@ static void Init_ossl_locks(void)
* A CA certificate is created the same way we created a certificate above, but
* with different extensions.
*
- * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
+ * ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
*
* ca_cert = OpenSSL::X509::Certificate.new
* ca_cert.serial = 0
@@ -948,7 +978,7 @@ static void Init_ossl_locks(void)
*
* Root CA certificates are self-signed.
*
- * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
+ * ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
*
* The CA certificate is saved to disk so it may be distributed to all the
* users of the keys this CA will sign.
@@ -966,7 +996,7 @@ static void Init_ossl_locks(void)
* csr.version = 0
* csr.subject = name
* csr.public_key = key.public_key
- * csr.sign key, OpenSSL::Digest::SHA1.new
+ * csr.sign key, OpenSSL::Digest.new('SHA1')
*
* A CSR is saved to disk and sent to the CA for signing.
*
@@ -1010,7 +1040,7 @@ static void Init_ossl_locks(void)
* csr_cert.add_extension \
* extension_factory.create_extension('subjectKeyIdentifier', 'hash')
*
- * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
+ * csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
*
* open 'csr_cert.pem', 'w' do |io|
* io.write csr_cert.to_pem
@@ -1099,6 +1129,11 @@ static void Init_ossl_locks(void)
void
Init_openssl(void)
{
+#if HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+#undef rb_intern
/*
* Init timezone info
*/
@@ -1109,25 +1144,14 @@ Init_openssl(void)
/*
* Init all digests, ciphers
*/
- /* CRYPTO_malloc_init(); */
- /* ENGINE_load_builtin_engines(); */
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
+ if (!OPENSSL_init_ssl(0, NULL))
+ rb_raise(rb_eRuntimeError, "OPENSSL_init_ssl");
+#else
OpenSSL_add_ssl_algorithms();
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
SSL_load_error_strings();
-
- /*
- * FIXME:
- * On unload do:
- */
-#if 0
- CONF_modules_unload(1);
- destroy_ui_method();
- EVP_cleanup();
- ENGINE_cleanup();
- CRYPTO_cleanup_all_ex_data();
- ERR_remove_state(0);
- ERR_free_strings();
#endif
/*
@@ -1135,11 +1159,7 @@ Init_openssl(void)
*/
mOSSL = rb_define_module("OpenSSL");
rb_global_variable(&mOSSL);
-
- /*
- * OpenSSL ruby extension version
- */
- rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
+ rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
/*
* Version of OpenSSL the ruby OpenSSL extension was built with
@@ -1149,7 +1169,11 @@ Init_openssl(void)
/*
* Version of OpenSSL the ruby OpenSSL extension is running with
*/
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
+ rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
+#else
rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
+#endif
/*
* Version number of OpenSSL the ruby OpenSSL extension was built with
@@ -1211,6 +1235,9 @@ Init_openssl(void)
Init_ossl_pkey();
Init_ossl_rand();
Init_ossl_ssl();
+#ifndef OPENSSL_NO_TS
+ Init_ossl_ts();
+#endif
Init_ossl_x509();
Init_ossl_ocsp();
Init_ossl_engine();
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
index f08889b22e..c20f506bda 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -13,8 +13,8 @@
#include RUBY_EXTCONF_H
#include <assert.h>
-#include <errno.h>
#include <ruby.h>
+#include <errno.h>
#include <ruby/io.h>
#include <ruby/thread.h>
#include <openssl/opensslv.h>
@@ -27,7 +27,9 @@
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <openssl/conf.h>
-#include <openssl/conf_api.h>
+#ifndef OPENSSL_NO_TS
+ #include <openssl/ts.h>
+#endif
#include <openssl/crypto.h>
#if !defined(OPENSSL_NO_ENGINE)
# include <openssl/engine.h>
@@ -35,6 +37,11 @@
#if !defined(OPENSSL_NO_OCSP)
# include <openssl/ocsp.h>
#endif
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/evp.h>
+#include <openssl/dh.h>
/*
* Common Module
@@ -81,9 +88,8 @@ VALUE ossl_buf2str(char *buf, int len);
VALUE ossl_str_new(const char *, long, int *);
#define ossl_str_adjust(str, p) \
do{\
- long len = RSTRING_LEN(str);\
long newlen = (long)((p) - (unsigned char*)RSTRING_PTR(str));\
- assert(newlen <= len);\
+ assert(newlen <= RSTRING_LEN(str));\
rb_str_set_len((str), newlen);\
}while(0)
/*
@@ -163,7 +169,9 @@ void ossl_debug(const char *, ...);
#include "ossl_pkey.h"
#include "ossl_rand.h"
#include "ossl_ssl.h"
-#include "ossl_version.h"
+#ifndef OPENSSL_NO_TS
+ #include "ossl_ts.h"
+#endif
#include "ossl_x509.h"
#include "ossl_engine.h"
#include "ossl_kdf.h"
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c
index efa6b78742..9eb1826f02 100644
--- a/ext/openssl/ossl_asn1.c
+++ b/ext/openssl/ossl_asn1.c
@@ -1285,6 +1285,30 @@ ossl_asn1obj_get_ln(VALUE self)
return ret;
}
+/*
+ * call-seq:
+ * oid == other_oid => true or false
+ *
+ * Returns +true+ if _other_oid_ is the same as _oid_
+ */
+static VALUE
+ossl_asn1obj_eq(VALUE self, VALUE other)
+{
+ VALUE valSelf, valOther;
+ int nidSelf, nidOther;
+
+ valSelf = ossl_asn1_get_value(self);
+ valOther = ossl_asn1_get_value(other);
+
+ if ((nidSelf = OBJ_txt2nid(StringValueCStr(valSelf))) == NID_undef)
+ ossl_raise(eASN1Error, "OBJ_txt2nid");
+
+ if ((nidOther = OBJ_txt2nid(StringValueCStr(valOther))) == NID_undef)
+ ossl_raise(eASN1Error, "OBJ_txt2nid");
+
+ return nidSelf == nidOther ? Qtrue : Qfalse;
+}
+
static VALUE
asn1obj_get_oid_i(VALUE vobj)
{
@@ -1360,6 +1384,7 @@ OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)
void
Init_ossl_asn1(void)
{
+#undef rb_intern
VALUE ary;
int i;
@@ -1665,12 +1690,12 @@ Init_ossl_asn1(void)
* == Primitive sub-classes and their mapping to Ruby classes
* * OpenSSL::ASN1::EndOfContent <=> _value_ is always +nil+
* * OpenSSL::ASN1::Boolean <=> _value_ is +true+ or +false+
- * * OpenSSL::ASN1::Integer <=> _value_ is an Integer
+ * * OpenSSL::ASN1::Integer <=> _value_ is an OpenSSL::BN
* * OpenSSL::ASN1::BitString <=> _value_ is a String
* * OpenSSL::ASN1::OctetString <=> _value_ is a String
* * OpenSSL::ASN1::Null <=> _value_ is always +nil+
* * OpenSSL::ASN1::Object <=> _value_ is a String
- * * OpenSSL::ASN1::Enumerated <=> _value_ is an Integer
+ * * OpenSSL::ASN1::Enumerated <=> _value_ is an OpenSSL::BN
* * OpenSSL::ASN1::UTF8String <=> _value_ is a String
* * OpenSSL::ASN1::NumericString <=> _value_ is a String
* * OpenSSL::ASN1::PrintableString <=> _value_ is a String
@@ -1817,12 +1842,14 @@ do{\
rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0);
rb_define_alias(cASN1ObjectId, "short_name", "sn");
rb_define_alias(cASN1ObjectId, "long_name", "ln");
+ rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1);
rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
class_tag_map = rb_hash_new();
+ rb_gc_register_mark_object(class_tag_map);
rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
@@ -1846,7 +1873,6 @@ do{\
rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
- rb_global_variable(&class_tag_map);
id_each = rb_intern_const("each");
}
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index d337d50961..bec37299f7 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -10,6 +10,10 @@
/* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
#include "ossl.h"
+#if HAVE_RB_EXT_RACTOR_SAFE
+#include <ruby/ractor.h>
+#endif
+
#define NewBN(klass) \
TypedData_Wrap_Struct((klass), &ossl_bn_type, 0)
#define SetBN(obj, bn) do { \
@@ -150,12 +154,58 @@ ossl_bn_value_ptr(volatile VALUE *ptr)
/*
* Private
*/
-/*
- * BN_CTX - is used in more difficult math. ops
- * (Why just 1? Because Ruby itself isn't thread safe,
- * we don't need to care about threads)
- */
-BN_CTX *ossl_bn_ctx;
+
+#if HAVE_RB_EXT_RACTOR_SAFE
+void
+ossl_bn_ctx_free(void *ptr)
+{
+ BN_CTX *ctx = (BN_CTX *)ptr;
+ BN_CTX_free(ctx);
+}
+
+struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = {
+ NULL, // mark
+ ossl_bn_ctx_free,
+};
+
+rb_ractor_local_key_t ossl_bn_ctx_key;
+
+BN_CTX *
+ossl_bn_ctx_get(void)
+{
+ // stored in ractor local storage
+
+ BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key);
+ if (!ctx) {
+ if (!(ctx = BN_CTX_new())) {
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
+ }
+ rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx);
+ }
+ return ctx;
+}
+#else
+// for ruby 2.x
+static BN_CTX *gv_ossl_bn_ctx;
+
+BN_CTX *
+ossl_bn_ctx_get(void)
+{
+ if (gv_ossl_bn_ctx == NULL) {
+ if (!(gv_ossl_bn_ctx = BN_CTX_new())) {
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
+ }
+ }
+ return gv_ossl_bn_ctx;
+}
+
+void
+ossl_bn_ctx_free(void)
+{
+ BN_CTX_free(gv_ossl_bn_ctx);
+ gv_ossl_bn_ctx = NULL;
+}
+#endif
static VALUE
ossl_bn_alloc(VALUE klass)
@@ -173,7 +223,6 @@ ossl_bn_alloc(VALUE klass)
/*
* call-seq:
- * OpenSSL::BN.new => aBN
* OpenSSL::BN.new(bn) => aBN
* OpenSSL::BN.new(integer) => aBN
* OpenSSL::BN.new(string) => aBN
@@ -187,11 +236,16 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
BIGNUM *bn;
VALUE str, bs;
int base = 10;
+ char *ptr;
if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
base = NUM2INT(bs);
}
+ if (NIL_P(str)) {
+ ossl_raise(rb_eArgError, "invalid argument");
+ }
+
if (RB_INTEGER_TYPE_P(str)) {
GetBN(self, bn);
integer_to_bnptr(str, bn);
@@ -213,12 +267,14 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
GetBN(self, bn);
switch (base) {
case 0:
- if (!BN_mpi2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
+ ptr = StringValuePtr(str);
+ if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
ossl_raise(eBNError, NULL);
}
break;
case 2:
- if (!BN_bin2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
+ ptr = StringValuePtr(str);
+ if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
ossl_raise(eBNError, NULL);
}
break;
@@ -397,7 +453,7 @@ ossl_bn_is_negative(VALUE self)
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
- if (!BN_##func(result, bn, ossl_bn_ctx)) { \
+ if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \
BN_free(result); \
ossl_raise(eBNError, NULL); \
} \
@@ -423,7 +479,7 @@ BIGNUM_1c(sqr)
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
- if (!BN_##func(result, bn1, bn2)) { \
+ if (BN_##func(result, bn1, bn2) <= 0) { \
BN_free(result); \
ossl_raise(eBNError, NULL); \
} \
@@ -456,7 +512,7 @@ BIGNUM_2(sub)
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
- if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
+ if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \
BN_free(result); \
ossl_raise(eBNError, NULL); \
} \
@@ -500,11 +556,21 @@ BIGNUM_2c(gcd)
BIGNUM_2c(mod_sqr)
/*
- * Document-method: OpenSSL::BN#mod_inverse
* call-seq:
- * bn.mod_inverse(bn2) => aBN
+ * bn.mod_inverse(bn2) => aBN
*/
-BIGNUM_2c(mod_inverse)
+static VALUE
+ossl_bn_mod_inverse(VALUE self, VALUE other)
+{
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
+ VALUE obj;
+ GetBN(self, bn1);
+ obj = NewBN(rb_obj_class(self));
+ if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
+ ossl_raise(eBNError, "BN_mod_inverse");
+ SetBN(obj, result);
+ return obj;
+}
/*
* call-seq:
@@ -553,7 +619,7 @@ ossl_bn_div(VALUE self, VALUE other)
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
- if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
+ if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
BN_free(result); \
ossl_raise(eBNError, NULL); \
} \
@@ -595,7 +661,7 @@ BIGNUM_3c(mod_exp)
{ \
BIGNUM *bn; \
GetBN(self, bn); \
- if (!BN_##func(bn, NUM2INT(bit))) { \
+ if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
ossl_raise(eBNError, NULL); \
} \
return self; \
@@ -655,7 +721,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
- if (!BN_##func(result, bn, b)) { \
+ if (BN_##func(result, bn, b) <= 0) { \
BN_free(result); \
ossl_raise(eBNError, NULL); \
} \
@@ -685,7 +751,7 @@ BIGNUM_SHIFT(rshift)
int b; \
b = NUM2INT(bits); \
GetBN(self, bn); \
- if (!BN_##func(bn, bn, b)) \
+ if (BN_##func(bn, bn, b) <= 0) \
ossl_raise(eBNError, NULL); \
return self; \
}
@@ -724,7 +790,7 @@ BIGNUM_SELF_SHIFT(rshift)
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
- if (!BN_##func(result, b, top, bottom)) { \
+ if (BN_##func(result, b, top, bottom) <= 0) { \
BN_free(result); \
ossl_raise(eBNError, NULL); \
} \
@@ -753,7 +819,7 @@ BIGNUM_RAND(pseudo_rand)
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
- if (!BN_##func##_range(result, bn)) { \
+ if (BN_##func##_range(result, bn) <= 0) { \
BN_free(result); \
ossl_raise(eBNError, NULL); \
} \
@@ -979,20 +1045,20 @@ static VALUE
ossl_bn_hash(VALUE self)
{
BIGNUM *bn;
- VALUE hash;
+ VALUE tmp, hash;
unsigned char *buf;
int len;
GetBN(self, bn);
len = BN_num_bytes(bn);
- buf = xmalloc(len);
+ buf = ALLOCV(tmp, len);
if (BN_bn2bin(bn, buf) != len) {
- xfree(buf);
- ossl_raise(eBNError, NULL);
+ ALLOCV_END(tmp);
+ ossl_raise(eBNError, "BN_bn2bin");
}
hash = ST2FIX(rb_memhash(buf, len));
- xfree(buf);
+ ALLOCV_END(tmp);
return hash;
}
@@ -1086,9 +1152,11 @@ Init_ossl_bn(void)
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
#endif
- if (!(ossl_bn_ctx = BN_CTX_new())) {
- ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
- }
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type);
+#else
+ ossl_bn_ctx_get();
+#endif
eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
diff --git a/ext/openssl/ossl_bn.h b/ext/openssl/ossl_bn.h
index a19ba19487..1cc041fc22 100644
--- a/ext/openssl/ossl_bn.h
+++ b/ext/openssl/ossl_bn.h
@@ -13,7 +13,8 @@
extern VALUE cBN;
extern VALUE eBNError;
-extern BN_CTX *ossl_bn_ctx;
+BN_CTX *ossl_bn_ctx_get(void);
+#define ossl_bn_ctx ossl_bn_ctx_get()
#define GetBNPtr(obj) ossl_bn_value_ptr(&(obj))
diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c
index bfa76c1aab..5b92fc39f0 100644
--- a/ext/openssl/ossl_cipher.c
+++ b/ext/openssl/ossl_cipher.c
@@ -104,7 +104,7 @@ ossl_cipher_alloc(VALUE klass)
* call-seq:
* Cipher.new(string) -> cipher
*
- * The string must be a valid cipher name like "AES-128-CBC" or "3DES".
+ * The string must contain a valid cipher name like "AES-256-CBC".
*
* A list of cipher names is available by calling OpenSSL::Cipher.ciphers.
*/
@@ -237,8 +237,7 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
ossl_raise(eCipherError, NULL);
}
- if (p_key)
- rb_ivar_set(self, id_key_set, Qtrue);
+ rb_ivar_set(self, id_key_set, p_key ? Qtrue : Qfalse);
return self;
}
@@ -317,6 +316,8 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
salt = (unsigned char *)RSTRING_PTR(vsalt);
}
iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
+ if (iter <= 0)
+ rb_raise(rb_eArgError, "iterations must be a positive integer");
digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_get_digestbyname(vdigest);
GetCipher(self, ctx);
EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
@@ -508,7 +509,7 @@ ossl_cipher_set_iv(VALUE self, VALUE iv)
StringValue(iv);
GetCipher(self, ctx);
- if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
if (!iv_len)
iv_len = EVP_CIPHER_CTX_iv_length(ctx);
@@ -535,7 +536,7 @@ ossl_cipher_is_authenticated(VALUE self)
GetCipher(self, ctx);
- return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
+ return (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
}
/*
@@ -569,6 +570,8 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data)
in_len = RSTRING_LEN(data);
GetCipher(self, ctx);
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
+ ossl_raise(eCipherError, "AEAD not supported by this cipher");
if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len))
ossl_raise(eCipherError, "couldn't set additional authenticated data");
@@ -606,7 +609,7 @@ ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self)
GetCipher(self, ctx);
- if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "authentication tag not supported by this cipher");
ret = rb_str_new(NULL, tag_len);
@@ -641,7 +644,7 @@ ossl_cipher_set_auth_tag(VALUE self, VALUE vtag)
tag_len = RSTRING_LENINT(vtag);
GetCipher(self, ctx);
- if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "authentication tag not supported by this cipher");
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag))
@@ -668,7 +671,7 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen)
EVP_CIPHER_CTX *ctx;
GetCipher(self, ctx);
- if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "AEAD not supported by this cipher");
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, NULL))
@@ -695,7 +698,7 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
EVP_CIPHER_CTX *ctx;
GetCipher(self, ctx);
- if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "cipher does not support AEAD");
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL))
@@ -786,7 +789,7 @@ ossl_cipher_iv_length(VALUE self)
int len = 0;
GetCipher(self, ctx);
- if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
if (!len)
len = EVP_CIPHER_CTX_iv_length(ctx);
@@ -811,6 +814,31 @@ ossl_cipher_block_size(VALUE self)
}
/*
+ * call-seq:
+ * cipher.ccm_data_len = integer -> integer
+ *
+ * Sets the length of the plaintext / ciphertext message that will be
+ * processed in CCM mode. Make sure to call this method after #key= and
+ * #iv= have been set, and before #auth_data=.
+ *
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
+ */
+static VALUE
+ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len)
+{
+ int in_len, out_len;
+ EVP_CIPHER_CTX *ctx;
+
+ in_len = NUM2INT(data_len);
+
+ GetCipher(self, ctx);
+ if (EVP_CipherUpdate(ctx, NULL, &out_len, NULL, in_len) != 1)
+ ossl_raise(eCipherError, NULL);
+
+ return data_len;
+}
+
+/*
* INIT
*/
void
@@ -848,22 +876,6 @@ Init_ossl_cipher(void)
*
* cipher = OpenSSL::Cipher.new('AES-128-CBC')
*
- * For each algorithm supported, there is a class defined under the
- * Cipher class that goes by the name of the cipher, e.g. to obtain an
- * instance of AES, you could also use
- *
- * # these are equivalent
- * cipher = OpenSSL::Cipher::AES.new(128, :CBC)
- * cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
- * cipher = OpenSSL::Cipher::AES.new('128-CBC')
- *
- * Finally, due to its wide-spread use, there are also extra classes
- * defined for the different key sizes of AES
- *
- * cipher = OpenSSL::Cipher::AES128.new(:CBC)
- * cipher = OpenSSL::Cipher::AES192.new(:CBC)
- * cipher = OpenSSL::Cipher::AES256.new(:CBC)
- *
* === Choosing either encryption or decryption mode
*
* Encryption and decryption are often very similar operations for
@@ -892,7 +904,7 @@ Init_ossl_cipher(void)
* without processing the password further. A simple and secure way to
* create a key for a particular Cipher is
*
- * cipher = OpenSSL::AES256.new(:CFB)
+ * cipher = OpenSSL::Cipher.new('AES-256-CFB')
* cipher.encrypt
* key = cipher.random_key # also sets the generated key on the Cipher
*
@@ -960,14 +972,14 @@ Init_ossl_cipher(void)
*
* data = "Very, very confidential data"
*
- * cipher = OpenSSL::Cipher::AES.new(128, :CBC)
+ * cipher = OpenSSL::Cipher.new('AES-128-CBC')
* cipher.encrypt
* key = cipher.random_key
* iv = cipher.random_iv
*
* encrypted = cipher.update(data) + cipher.final
* ...
- * decipher = OpenSSL::Cipher::AES.new(128, :CBC)
+ * decipher = OpenSSL::Cipher.new('AES-128-CBC')
* decipher.decrypt
* decipher.key = key
* decipher.iv = iv
@@ -1003,7 +1015,7 @@ Init_ossl_cipher(void)
* not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the
* security guarantees of GCM mode.
*
- * cipher = OpenSSL::Cipher::AES.new(128, :GCM).encrypt
+ * cipher = OpenSSL::Cipher.new('AES-128-GCM').encrypt
* cipher.key = key
* cipher.iv = nonce
* cipher.auth_data = auth_data
@@ -1019,7 +1031,7 @@ Init_ossl_cipher(void)
* ciphertext with a probability of 1/256.
*
* raise "tag is truncated!" unless tag.bytesize == 16
- * decipher = OpenSSL::Cipher::AES.new(128, :GCM).decrypt
+ * decipher = OpenSSL::Cipher.new('AES-128-GCM').decrypt
* decipher.key = key
* decipher.iv = nonce
* decipher.auth_tag = tag
@@ -1056,6 +1068,7 @@ Init_ossl_cipher(void)
rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
+ rb_define_method(cCipher, "ccm_data_len=", ossl_cipher_set_ccm_data_len, 1);
id_auth_tag_len = rb_intern_const("auth_tag_len");
id_key_set = rb_intern_const("key_set");
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c
index 112ce33647..6294fa2acf 100644
--- a/ext/openssl/ossl_digest.c
+++ b/ext/openssl/ossl_digest.c
@@ -192,7 +192,7 @@ ossl_digest_reset(VALUE self)
* be passed individually to the Digest instance.
*
* === Example
- * digest = OpenSSL::Digest::SHA256.new
+ * digest = OpenSSL::Digest.new('SHA256')
* digest.update('First input')
* digest << 'Second input' # equivalent to digest.update('Second input')
* result = digest.digest
@@ -248,7 +248,7 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self)
* Returns the sn of this Digest algorithm.
*
* === Example
- * digest = OpenSSL::Digest::SHA512.new
+ * digest = OpenSSL::Digest.new('SHA512')
* puts digest.name # => SHA512
*
*/
@@ -270,7 +270,7 @@ ossl_digest_name(VALUE self)
* final message digest result.
*
* === Example
- * digest = OpenSSL::Digest::SHA1.new
+ * digest = OpenSSL::Digest.new('SHA1')
* puts digest.digest_length # => 20
*
*/
@@ -294,7 +294,7 @@ ossl_digest_size(VALUE self)
* consecutively.
*
* === Example
- * digest = OpenSSL::Digest::SHA1.new
+ * digest = OpenSSL::Digest.new('SHA1')
* puts digest.block_length # => 64
*/
static VALUE
@@ -313,8 +313,6 @@ ossl_digest_block_length(VALUE self)
void
Init_ossl_digest(void)
{
- rb_require("digest");
-
#if 0
mOSSL = rb_define_module("OpenSSL");
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -348,54 +346,19 @@ Init_ossl_digest(void)
* the integrity of a signed document, it suffices to re-compute the hash
* and verify that it is equal to that in the signature.
*
- * Among the supported message digest algorithms are:
- * * SHA, SHA1, SHA224, SHA256, SHA384 and SHA512
- * * MD2, MD4, MDC2 and MD5
- * * RIPEMD160
- * * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is
- * equal to SHA and DSS1 is equal to SHA1)
+ * You can get a list of all digest algorithms supported on your system by
+ * running this command in your terminal:
*
- * For each of these algorithms, there is a sub-class of Digest that
- * can be instantiated as simply as e.g.
+ * openssl list -digest-algorithms
*
- * digest = OpenSSL::Digest::SHA1.new
+ * Among the OpenSSL 1.1.1 supported message digest algorithms are:
+ * * SHA224, SHA256, SHA384, SHA512, SHA512-224 and SHA512-256
+ * * SHA3-224, SHA3-256, SHA3-384 and SHA3-512
+ * * BLAKE2s256 and BLAKE2b512
*
- * === Mapping between Digest class and sn/ln
+ * Each of these algorithms can be instantiated using the name:
*
- * The sn (short names) and ln (long names) are defined in
- * <openssl/object.h> and <openssl/obj_mac.h>. They are textual
- * representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest
- * algorithm has an OBJECT IDENTIFIER associated to it and those again
- * have short/long names assigned to them.
- * E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its
- * sn is "SHA1" and its ln is "sha1".
- * ==== MD2
- * * sn: MD2
- * * ln: md2
- * ==== MD4
- * * sn: MD4
- * * ln: md4
- * ==== MD5
- * * sn: MD5
- * * ln: md5
- * ==== SHA
- * * sn: SHA
- * * ln: SHA
- * ==== SHA-1
- * * sn: SHA1
- * * ln: sha1
- * ==== SHA-224
- * * sn: SHA224
- * * ln: sha224
- * ==== SHA-256
- * * sn: SHA256
- * * ln: sha256
- * ==== SHA-384
- * * sn: SHA384
- * * ln: sha384
- * ==== SHA-512
- * * sn: SHA512
- * * ln: sha512
+ * digest = OpenSSL::Digest.new('SHA256')
*
* "Breaking" a message digest algorithm means defying its one-way
* function characteristics, i.e. producing a collision or finding a way
@@ -408,7 +371,7 @@ Init_ossl_digest(void)
* === Hashing a file
*
* data = File.read('document')
- * sha256 = OpenSSL::Digest::SHA256.new
+ * sha256 = OpenSSL::Digest.new('SHA256')
* digest = sha256.digest(data)
*
* === Hashing several pieces of data at once
@@ -416,7 +379,7 @@ Init_ossl_digest(void)
* data1 = File.read('file1')
* data2 = File.read('file2')
* data3 = File.read('file3')
- * sha256 = OpenSSL::Digest::SHA256.new
+ * sha256 = OpenSSL::Digest.new('SHA256')
* sha256 << data1
* sha256 << data2
* sha256 << data3
@@ -425,7 +388,7 @@ Init_ossl_digest(void)
* === Reuse a Digest instance
*
* data1 = File.read('file1')
- * sha256 = OpenSSL::Digest::SHA256.new
+ * sha256 = OpenSSL::Digest.new('SHA256')
* digest1 = sha256.digest(data1)
*
* data2 = File.read('file2')
@@ -433,6 +396,12 @@ Init_ossl_digest(void)
* digest2 = sha256.digest(data2)
*
*/
+
+ /*
+ * Digest::Class is defined by the digest library. rb_require() cannot be
+ * used here because it bypasses RubyGems.
+ */
+ rb_funcall(Qnil, rb_intern_const("require"), 1, rb_str_new_cstr("digest"));
cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
/* Document-class: OpenSSL::Digest::DigestError
*
diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c
index d69b5dcac5..90546934d1 100644
--- a/ext/openssl/ossl_engine.c
+++ b/ext/openssl/ossl_engine.c
@@ -46,13 +46,25 @@ VALUE eEngineError;
/*
* Private
*/
-#define OSSL_ENGINE_LOAD_IF_MATCH(x) \
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
+#define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \
do{\
- if(!strcmp(#x, RSTRING_PTR(name))){\
- ENGINE_load_##x();\
+ if(!strcmp(#engine_name, RSTRING_PTR(name))){\
+ if (OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_##x, NULL))\
+ return Qtrue;\
+ else\
+ ossl_raise(eEngineError, "OPENSSL_init_crypto"); \
+ }\
+}while(0)
+#else
+#define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \
+do{\
+ if(!strcmp(#engine_name, RSTRING_PTR(name))){\
+ ENGINE_load_##engine_name();\
return Qtrue;\
}\
}while(0)
+#endif
static void
ossl_engine_free(void *engine)
@@ -81,9 +93,6 @@ static const rb_data_type_t ossl_engine_type = {
static VALUE
ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
{
-#if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES)
- return Qnil;
-#else
VALUE name;
rb_scan_args(argc, argv, "01", &name);
@@ -92,60 +101,53 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
return Qtrue;
}
StringValueCStr(name);
-#ifndef OPENSSL_NO_STATIC_ENGINE
#if HAVE_ENGINE_LOAD_DYNAMIC
- OSSL_ENGINE_LOAD_IF_MATCH(dynamic);
+ OSSL_ENGINE_LOAD_IF_MATCH(dynamic, DYNAMIC);
#endif
+#ifndef OPENSSL_NO_STATIC_ENGINE
#if HAVE_ENGINE_LOAD_4758CCA
- OSSL_ENGINE_LOAD_IF_MATCH(4758cca);
+ OSSL_ENGINE_LOAD_IF_MATCH(4758cca, 4758CCA);
#endif
#if HAVE_ENGINE_LOAD_AEP
- OSSL_ENGINE_LOAD_IF_MATCH(aep);
+ OSSL_ENGINE_LOAD_IF_MATCH(aep, AEP);
#endif
#if HAVE_ENGINE_LOAD_ATALLA
- OSSL_ENGINE_LOAD_IF_MATCH(atalla);
+ OSSL_ENGINE_LOAD_IF_MATCH(atalla, ATALLA);
#endif
#if HAVE_ENGINE_LOAD_CHIL
- OSSL_ENGINE_LOAD_IF_MATCH(chil);
+ OSSL_ENGINE_LOAD_IF_MATCH(chil, CHIL);
#endif
#if HAVE_ENGINE_LOAD_CSWIFT
- OSSL_ENGINE_LOAD_IF_MATCH(cswift);
+ OSSL_ENGINE_LOAD_IF_MATCH(cswift, CSWIFT);
#endif
#if HAVE_ENGINE_LOAD_NURON
- OSSL_ENGINE_LOAD_IF_MATCH(nuron);
+ OSSL_ENGINE_LOAD_IF_MATCH(nuron, NURON);
#endif
#if HAVE_ENGINE_LOAD_SUREWARE
- OSSL_ENGINE_LOAD_IF_MATCH(sureware);
+ OSSL_ENGINE_LOAD_IF_MATCH(sureware, SUREWARE);
#endif
#if HAVE_ENGINE_LOAD_UBSEC
- OSSL_ENGINE_LOAD_IF_MATCH(ubsec);
+ OSSL_ENGINE_LOAD_IF_MATCH(ubsec, UBSEC);
#endif
#if HAVE_ENGINE_LOAD_PADLOCK
- OSSL_ENGINE_LOAD_IF_MATCH(padlock);
+ OSSL_ENGINE_LOAD_IF_MATCH(padlock, PADLOCK);
#endif
#if HAVE_ENGINE_LOAD_CAPI
- OSSL_ENGINE_LOAD_IF_MATCH(capi);
+ OSSL_ENGINE_LOAD_IF_MATCH(capi, CAPI);
#endif
#if HAVE_ENGINE_LOAD_GMP
- OSSL_ENGINE_LOAD_IF_MATCH(gmp);
+ OSSL_ENGINE_LOAD_IF_MATCH(gmp, GMP);
#endif
#if HAVE_ENGINE_LOAD_GOST
- OSSL_ENGINE_LOAD_IF_MATCH(gost);
-#endif
-#if HAVE_ENGINE_LOAD_CRYPTODEV
- OSSL_ENGINE_LOAD_IF_MATCH(cryptodev);
+ OSSL_ENGINE_LOAD_IF_MATCH(gost, GOST);
#endif
-#if HAVE_ENGINE_LOAD_AESNI
- OSSL_ENGINE_LOAD_IF_MATCH(aesni);
#endif
+#if HAVE_ENGINE_LOAD_CRYPTODEV
+ OSSL_ENGINE_LOAD_IF_MATCH(cryptodev, CRYPTODEV);
#endif
-#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
- OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);
-#endif
- OSSL_ENGINE_LOAD_IF_MATCH(openssl);
+ OSSL_ENGINE_LOAD_IF_MATCH(openssl, OPENSSL);
rb_warning("no such builtin loader for `%"PRIsVALUE"'", name);
return Qnil;
-#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
}
/*
@@ -160,7 +162,9 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
static VALUE
ossl_engine_s_cleanup(VALUE self)
{
+#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000
ENGINE_cleanup();
+#endif
return Qnil;
}
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
index 564dcab522..e831cff519 100644
--- a/ext/openssl/ossl_hmac.c
+++ b/ext/openssl/ossl_hmac.c
@@ -84,18 +84,12 @@ ossl_hmac_alloc(VALUE klass)
*
* === A note about comparisons
*
- * Two instances won't be equal when they're compared, even if they have the
- * same value. Use #to_s or #hexdigest to return the authentication code that
- * the instance represents. For example:
+ * Two instances can be securely compared with #== in constant time:
*
* other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
- * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
- * instance
- * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
- * instance == other_instance
- * #=> false
- * instance.to_s == other_instance.to_s
- * #=> true
+ * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
+ * instance == other_instance
+ * #=> true
*
*/
static VALUE
@@ -359,7 +353,7 @@ Init_ossl_hmac(void)
* data1 = File.read("file1")
* data2 = File.read("file2")
* key = "key"
- * digest = OpenSSL::Digest::SHA256.new
+ * digest = OpenSSL::Digest.new('SHA256')
* hmac = OpenSSL::HMAC.new(key, digest)
* hmac << data1
* hmac << data2
diff --git a/ext/openssl/ossl_kdf.c b/ext/openssl/ossl_kdf.c
index 9fa42e174a..486e789458 100644
--- a/ext/openssl/ossl_kdf.c
+++ b/ext/openssl/ossl_kdf.c
@@ -3,6 +3,9 @@
* Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors
*/
#include "ossl.h"
+#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+# include <openssl/kdf.h>
+#endif
static VALUE mKDF, eKDF;
@@ -138,6 +141,97 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self)
}
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+/*
+ * call-seq:
+ * KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String
+ *
+ * HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as specified in
+ * {RFC 5869}[https://tools.ietf.org/html/rfc5869].
+ *
+ * New in OpenSSL 1.1.0.
+ *
+ * === Parameters
+ * _ikm_::
+ * The input keying material.
+ * _salt_::
+ * The salt.
+ * _info_::
+ * The context and application specific information.
+ * _length_::
+ * The output length in octets. Must be <= <tt>255 * HashLen</tt>, where
+ * HashLen is the length of the hash function output in octets.
+ * _hash_::
+ * The hash function.
+ */
+static VALUE
+kdf_hkdf(int argc, VALUE *argv, VALUE self)
+{
+ VALUE ikm, salt, info, opts, kwargs[4], str;
+ static ID kwargs_ids[4];
+ int saltlen, ikmlen, infolen;
+ size_t len;
+ const EVP_MD *md;
+ EVP_PKEY_CTX *pctx;
+
+ if (!kwargs_ids[0]) {
+ kwargs_ids[0] = rb_intern_const("salt");
+ kwargs_ids[1] = rb_intern_const("info");
+ kwargs_ids[2] = rb_intern_const("length");
+ kwargs_ids[3] = rb_intern_const("hash");
+ }
+ rb_scan_args(argc, argv, "1:", &ikm, &opts);
+ rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs);
+
+ StringValue(ikm);
+ ikmlen = RSTRING_LENINT(ikm);
+ salt = StringValue(kwargs[0]);
+ saltlen = RSTRING_LENINT(salt);
+ info = StringValue(kwargs[1]);
+ infolen = RSTRING_LENINT(info);
+ len = (size_t)NUM2LONG(kwargs[2]);
+ if (len > LONG_MAX)
+ rb_raise(rb_eArgError, "length must be non-negative");
+ md = ossl_evp_get_digestbyname(kwargs[3]);
+
+ str = rb_str_new(NULL, (long)len);
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
+ if (!pctx)
+ ossl_raise(eKDF, "EVP_PKEY_CTX_new_id");
+ if (EVP_PKEY_derive_init(pctx) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
+ ossl_raise(eKDF, "EVP_PKEY_derive_init");
+ }
+ if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
+ ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_md");
+ }
+ if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, (unsigned char *)RSTRING_PTR(salt),
+ saltlen) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
+ ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_salt");
+ }
+ if (EVP_PKEY_CTX_set1_hkdf_key(pctx, (unsigned char *)RSTRING_PTR(ikm),
+ ikmlen) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
+ ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_key");
+ }
+ if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (unsigned char *)RSTRING_PTR(info),
+ infolen) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
+ ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_info");
+ }
+ if (EVP_PKEY_derive(pctx, (unsigned char *)RSTRING_PTR(str), &len) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
+ ossl_raise(eKDF, "EVP_PKEY_derive");
+ }
+ rb_str_set_len(str, (long)len);
+ EVP_PKEY_CTX_free(pctx);
+
+ return str;
+}
+#endif
+
void
Init_ossl_kdf(void)
{
@@ -162,6 +256,7 @@ Init_ossl_kdf(void)
* * PKCS #5 PBKDF2 (Password-Based Key Derivation Function 2) in
* combination with HMAC
* * scrypt
+ * * HKDF
*
* == Examples
* === Generating a 128 bit key for a Cipher (e.g. AES)
@@ -177,7 +272,7 @@ Init_ossl_kdf(void)
* # store this with the generated value
* salt = OpenSSL::Random.random_bytes(16)
* iter = 20_000
- * hash = OpenSSL::Digest::SHA256.new
+ * hash = OpenSSL::Digest.new('SHA256')
* len = hash.digest_length
* # the final value to be stored
* value = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
@@ -189,24 +284,8 @@ Init_ossl_kdf(void)
* Typically, "==" short-circuits on evaluation, and is therefore
* vulnerable to timing attacks. The proper way is to use a method that
* always takes the same amount of time when comparing two values, thus
- * not leaking any information to potential attackers. To compare two
- * values, the following could be used:
- *
- * def eql_time_cmp(a, b)
- * unless a.length == b.length
- * return false
- * end
- * cmp = b.bytes
- * result = 0
- * a.bytes.each_with_index {|c,i|
- * result |= c ^ cmp[i]
- * }
- * result == 0
- * end
- *
- * Please note that the premature return in case of differing lengths
- * typically does not leak valuable information - when using PBKDF2, the
- * length of the values to be compared is of fixed size.
+ * not leaking any information to potential attackers. To do this, use
+ * +OpenSSL.fixed_length_secure_compare+.
*/
mKDF = rb_define_module_under(mOSSL, "KDF");
/*
@@ -218,4 +297,7 @@ Init_ossl_kdf(void)
#if defined(HAVE_EVP_PBE_SCRYPT)
rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+ rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1);
+#endif
}
diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c
index f17b9509c6..9b1147367a 100644
--- a/ext/openssl/ossl_ns_spki.c
+++ b/ext/openssl/ossl_ns_spki.c
@@ -208,12 +208,13 @@ static VALUE
ossl_spki_set_public_key(VALUE self, VALUE key)
{
NETSCAPE_SPKI *spki;
+ EVP_PKEY *pkey;
GetSPKI(self, spki);
- if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
- ossl_raise(eSPKIError, NULL);
- }
-
+ pkey = GetPKeyPtr(key);
+ ossl_pkey_check_public_key(pkey);
+ if (!NETSCAPE_SPKI_set_pubkey(spki, pkey))
+ ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey");
return key;
}
@@ -307,17 +308,20 @@ static VALUE
ossl_spki_verify(VALUE self, VALUE key)
{
NETSCAPE_SPKI *spki;
+ EVP_PKEY *pkey;
GetSPKI(self, spki);
- switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
- case 0:
+ pkey = GetPKeyPtr(key);
+ ossl_pkey_check_public_key(pkey);
+ switch (NETSCAPE_SPKI_verify(spki, pkey)) {
+ case 0:
+ ossl_clear_error();
return Qfalse;
- case 1:
+ case 1:
return Qtrue;
- default:
- ossl_raise(eSPKIError, NULL);
+ default:
+ ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify");
}
- return Qnil; /* dummy */
}
/* Document-class: OpenSSL::Netscape::SPKI
@@ -346,7 +350,7 @@ ossl_spki_verify(VALUE self, VALUE key)
* spki = OpenSSL::Netscape::SPKI.new
* spki.challenge = "RandomChallenge"
* spki.public_key = key.public_key
- * spki.sign(key, OpenSSL::Digest::SHA256.new)
+ * spki.sign(key, OpenSSL::Digest.new('SHA256'))
* #send a request containing this to a server generating a certificate
* === Verifying an SPKI request
* request = #...
diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c
index c0237791da..7a92e5df68 100644
--- a/ext/openssl/ossl_ocsp.c
+++ b/ext/openssl/ossl_ocsp.c
@@ -1489,13 +1489,15 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
* call-seq:
* OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
* OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id
+ * OpenSSL::OCSP::CertificateId.new(obj) -> certificate_id
*
* Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and
* _issuer_ X509 certificates. The _digest_ is a digest algorithm that is used
* to compute the hash values. This defaults to SHA-1.
*
* If only one argument is given, decodes it as DER representation of a
- * certificate ID.
+ * certificate ID or generates certificate ID from the object that responds to
+ * the to_der method.
*/
static VALUE
ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
@@ -1717,7 +1719,7 @@ Init_ossl_ocsp(void)
* subject certificate so the CA knows which certificate we are asking
* about:
*
- * digest = OpenSSL::Digest::SHA1.new
+ * digest = OpenSSL::Digest.new('SHA1')
* certificate_id =
* OpenSSL::OCSP::CertificateId.new subject, issuer, digest
*
@@ -1734,18 +1736,11 @@ Init_ossl_ocsp(void)
* To submit the request to the CA for verification we need to extract the
* OCSP URI from the subject certificate:
*
- * authority_info_access = subject.extensions.find do |extension|
- * extension.oid == 'authorityInfoAccess'
- * end
- *
- * descriptions = authority_info_access.value.split "\n"
- * ocsp = descriptions.find do |description|
- * description.start_with? 'OCSP'
- * end
+ * ocsp_uris = subject.ocsp_uris
*
* require 'uri'
*
- * ocsp_uri = URI ocsp[/URI:(.*)/, 1]
+ * ocsp_uri = URI ocsp_uris[0]
*
* To submit the request we'll POST the request to the OCSP URI (per RFC
* 2560). Note that we only handle HTTP requests and don't handle any
diff --git a/ext/openssl/ossl_ocsp.h b/ext/openssl/ossl_ocsp.h
index 21e2c99a2e..6d2aac8657 100644
--- a/ext/openssl/ossl_ocsp.h
+++ b/ext/openssl/ossl_ocsp.h
@@ -13,9 +13,9 @@
#if !defined(OPENSSL_NO_OCSP)
extern VALUE mOCSP;
-extern VALUE cOPCSReq;
-extern VALUE cOPCSRes;
-extern VALUE cOPCSBasicRes;
+extern VALUE cOCSPReq;
+extern VALUE cOCSPRes;
+extern VALUE cOCSPBasicRes;
#endif
void Init_ossl_ocsp(void);
diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c
index ddb7d939cf..4566334481 100644
--- a/ext/openssl/ossl_pkcs12.c
+++ b/ext/openssl/ossl_pkcs12.c
@@ -232,6 +232,7 @@ ossl_pkcs12_to_der(VALUE self)
void
Init_ossl_pkcs12(void)
{
+#undef rb_intern
#if 0
mOSSL = rb_define_module("OpenSSL");
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c
index 6395fa6f5c..ea8e92d1bc 100644
--- a/ext/openssl/ossl_pkcs7.c
+++ b/ext/openssl/ossl_pkcs7.c
@@ -9,21 +9,6 @@
*/
#include "ossl.h"
-#define NewPKCS7(klass) \
- TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
-#define SetPKCS7(obj, pkcs7) do { \
- if (!(pkcs7)) { \
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
- } \
- RTYPEDDATA_DATA(obj) = (pkcs7); \
-} while (0)
-#define GetPKCS7(obj, pkcs7) do { \
- TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
- if (!(pkcs7)) { \
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
- } \
-} while (0)
-
#define NewPKCS7si(klass) \
TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0)
#define SetPKCS7si(obj, p7si) do { \
@@ -75,7 +60,7 @@ ossl_pkcs7_free(void *ptr)
PKCS7_free(ptr);
}
-static const rb_data_type_t ossl_pkcs7_type = {
+const rb_data_type_t ossl_pkcs7_type = {
"OpenSSL/PKCS7",
{
0, ossl_pkcs7_free,
@@ -803,9 +788,9 @@ ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self)
BIO *out;
VALUE str;
- rb_scan_args(argc, argv, "21", &pkey, &cert, &flags);
+ rb_scan_args(argc, argv, "12", &pkey, &cert, &flags);
key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */
- x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
+ x509 = NIL_P(cert) ? NULL : GetX509CertPtr(cert); /* NO NEED TO DUP */
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
GetPKCS7(self, p7);
if(!(out = BIO_new(BIO_s_mem())))
@@ -1042,6 +1027,7 @@ ossl_pkcs7ri_get_enc_key(VALUE self)
void
Init_ossl_pkcs7(void)
{
+#undef rb_intern
#if 0
mOSSL = rb_define_module("OpenSSL");
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -1087,7 +1073,6 @@ Init_ossl_pkcs7(void)
rb_define_alloc_func(cPKCS7Signer, ossl_pkcs7si_alloc);
rb_define_method(cPKCS7Signer, "initialize", ossl_pkcs7si_initialize,3);
rb_define_method(cPKCS7Signer, "issuer", ossl_pkcs7si_get_issuer, 0);
- rb_define_alias(cPKCS7Signer, "name", "issuer");
rb_define_method(cPKCS7Signer, "serial", ossl_pkcs7si_get_serial,0);
rb_define_method(cPKCS7Signer,"signed_time",ossl_pkcs7si_get_signed_time,0);
diff --git a/ext/openssl/ossl_pkcs7.h b/ext/openssl/ossl_pkcs7.h
index 139e00d640..3e1b094670 100644
--- a/ext/openssl/ossl_pkcs7.h
+++ b/ext/openssl/ossl_pkcs7.h
@@ -10,6 +10,22 @@
#if !defined(_OSSL_PKCS7_H_)
#define _OSSL_PKCS7_H_
+#define NewPKCS7(klass) \
+ TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
+#define SetPKCS7(obj, pkcs7) do { \
+ if (!(pkcs7)) { \
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
+ } \
+ RTYPEDDATA_DATA(obj) = (pkcs7); \
+} while (0)
+#define GetPKCS7(obj, pkcs7) do { \
+ TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
+ if (!(pkcs7)) { \
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
+ } \
+} while (0)
+
+extern const rb_data_type_t ossl_pkcs7_type;
extern VALUE cPKCS7;
extern VALUE cPKCS7Signer;
extern VALUE cPKCS7Recipient;
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 23e2115409..23204087ac 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -20,6 +20,21 @@ static ID id_private_q;
/*
* callback for generating keys
*/
+static VALUE
+call_check_ints0(VALUE arg)
+{
+ rb_thread_check_ints();
+ return Qnil;
+}
+
+static void *
+call_check_ints(void *arg)
+{
+ int state;
+ rb_protect(call_check_ints0, Qnil, &state);
+ return (void *)(VALUE)state;
+}
+
int
ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
{
@@ -38,11 +53,18 @@ ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
*/
rb_protect(rb_yield, ary, &state);
if (state) {
- arg->stop = 1;
arg->state = state;
+ return 0;
+ }
+ }
+ if (arg->interrupted) {
+ arg->interrupted = 0;
+ state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL);
+ if (state) {
+ arg->state = state;
+ return 0;
}
}
- if (arg->stop) return 0;
return 1;
}
@@ -50,7 +72,7 @@ void
ossl_generate_cb_stop(void *ptr)
{
struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
- arg->stop = 1;
+ arg->interrupted = 1;
}
static void
@@ -145,26 +167,32 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
pass = ossl_pem_passwd_value(pass);
bio = ossl_obj2bio(&data);
- if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
- OSSL_BIO_reset(bio);
- if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) {
- OSSL_BIO_reset(bio);
- if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
- OSSL_BIO_reset(bio);
- pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, (void *)pass);
- }
- }
- }
+ if ((pkey = d2i_PrivateKey_bio(bio, NULL)))
+ goto ok;
+ OSSL_BIO_reset(bio);
+ if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, (void *)pass)))
+ goto ok;
+ OSSL_BIO_reset(bio);
+ if ((pkey = d2i_PUBKEY_bio(bio, NULL)))
+ goto ok;
+ OSSL_BIO_reset(bio);
+ /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */
+ if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass)))
+ goto ok;
+ OSSL_BIO_reset(bio);
+ if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)))
+ goto ok;
BIO_free(bio);
- if (!pkey)
- ossl_raise(ePKeyError, "Could not parse PKey");
+ ossl_raise(ePKeyError, "Could not parse PKey");
+ok:
+ BIO_free(bio);
return ossl_pkey_new(pkey);
}
-static void
-pkey_check_public_key(EVP_PKEY *pkey)
+void
+ossl_pkey_check_public_key(const EVP_PKEY *pkey)
{
void *ptr;
const BIGNUM *n, *e, *pubkey;
@@ -172,7 +200,8 @@ pkey_check_public_key(EVP_PKEY *pkey)
if (EVP_PKEY_missing_parameters(pkey))
ossl_raise(ePKeyError, "parameters missing");
- ptr = EVP_PKEY_get0(pkey);
+ /* OpenSSL < 1.1.0 takes non-const pointer */
+ ptr = EVP_PKEY_get0((EVP_PKEY *)pkey);
switch (EVP_PKEY_base_id(pkey)) {
case EVP_PKEY_RSA:
RSA_get0_key(ptr, &n, &e, NULL);
@@ -271,6 +300,160 @@ ossl_pkey_initialize(VALUE self)
}
/*
+ * call-seq:
+ * pkey.oid -> string
+ *
+ * Returns the short name of the OID associated with _pkey_.
+ */
+static VALUE
+ossl_pkey_oid(VALUE self)
+{
+ EVP_PKEY *pkey;
+ int nid;
+
+ GetPKey(self, pkey);
+ nid = EVP_PKEY_id(pkey);
+ return rb_str_new_cstr(OBJ_nid2sn(nid));
+}
+
+/*
+ * call-seq:
+ * pkey.inspect -> string
+ *
+ * Returns a string describing the PKey object.
+ */
+static VALUE
+ossl_pkey_inspect(VALUE self)
+{
+ EVP_PKEY *pkey;
+ int nid;
+
+ GetPKey(self, pkey);
+ nid = EVP_PKEY_id(pkey);
+ return rb_sprintf("#<%"PRIsVALUE":%p oid=%s>",
+ rb_class_name(CLASS_OF(self)), (void *)self,
+ OBJ_nid2sn(nid));
+}
+
+static VALUE
+do_pkcs8_export(int argc, VALUE *argv, VALUE self, int to_der)
+{
+ EVP_PKEY *pkey;
+ VALUE cipher, pass;
+ const EVP_CIPHER *enc = NULL;
+ BIO *bio;
+
+ GetPKey(self, pkey);
+ rb_scan_args(argc, argv, "02", &cipher, &pass);
+ if (argc > 0) {
+ /*
+ * TODO: EncryptedPrivateKeyInfo actually has more options.
+ * Should they be exposed?
+ */
+ enc = ossl_evp_get_cipherbyname(cipher);
+ pass = ossl_pem_passwd_value(pass);
+ }
+
+ bio = BIO_new(BIO_s_mem());
+ if (!bio)
+ ossl_raise(ePKeyError, "BIO_new");
+ if (to_der) {
+ if (!i2d_PKCS8PrivateKey_bio(bio, pkey, enc, NULL, 0,
+ ossl_pem_passwd_cb, (void *)pass)) {
+ BIO_free(bio);
+ ossl_raise(ePKeyError, "i2d_PKCS8PrivateKey_bio");
+ }
+ }
+ else {
+ if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey, enc, NULL, 0,
+ ossl_pem_passwd_cb, (void *)pass)) {
+ BIO_free(bio);
+ ossl_raise(ePKeyError, "PEM_write_bio_PKCS8PrivateKey");
+ }
+ }
+ return ossl_membio2str(bio);
+}
+
+/*
+ * call-seq:
+ * pkey.private_to_der -> string
+ * pkey.private_to_der(cipher, password) -> string
+ *
+ * Serializes the private key to DER-encoded PKCS #8 format. If called without
+ * arguments, unencrypted PKCS #8 PrivateKeyInfo format is used. If called with
+ * a cipher name and a password, PKCS #8 EncryptedPrivateKeyInfo format with
+ * PBES2 encryption scheme is used.
+ */
+static VALUE
+ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self)
+{
+ return do_pkcs8_export(argc, argv, self, 1);
+}
+
+/*
+ * call-seq:
+ * pkey.private_to_pem -> string
+ * pkey.private_to_pem(cipher, password) -> string
+ *
+ * Serializes the private key to PEM-encoded PKCS #8 format. See #private_to_der
+ * for more details.
+ */
+static VALUE
+ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
+{
+ return do_pkcs8_export(argc, argv, self, 0);
+}
+
+static VALUE
+do_spki_export(VALUE self, int to_der)
+{
+ EVP_PKEY *pkey;
+ BIO *bio;
+
+ GetPKey(self, pkey);
+ bio = BIO_new(BIO_s_mem());
+ if (!bio)
+ ossl_raise(ePKeyError, "BIO_new");
+ if (to_der) {
+ if (!i2d_PUBKEY_bio(bio, pkey)) {
+ BIO_free(bio);
+ ossl_raise(ePKeyError, "i2d_PUBKEY_bio");
+ }
+ }
+ else {
+ if (!PEM_write_bio_PUBKEY(bio, pkey)) {
+ BIO_free(bio);
+ ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY");
+ }
+ }
+ return ossl_membio2str(bio);
+}
+
+/*
+ * call-seq:
+ * pkey.public_to_der -> string
+ *
+ * Serializes the public key to DER-encoded X.509 SubjectPublicKeyInfo format.
+ */
+static VALUE
+ossl_pkey_public_to_der(VALUE self)
+{
+ return do_spki_export(self, 1);
+}
+
+/*
+ * call-seq:
+ * pkey.public_to_pem -> string
+ *
+ * Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format.
+ */
+static VALUE
+ossl_pkey_public_to_pem(VALUE self)
+{
+ return do_spki_export(self, 0);
+}
+
+/*
* call-seq:
* pkey.sign(digest, data) -> String
*
@@ -283,7 +466,7 @@ ossl_pkey_initialize(VALUE self)
*
* == Example
* data = 'Sign me!'
- * digest = OpenSSL::Digest::SHA256.new
+ * digest = OpenSSL::Digest.new('SHA256')
* pkey = OpenSSL::PKey::RSA.new(2048)
* signature = pkey.sign(digest, data)
*/
@@ -337,7 +520,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
*
* == Example
* data = 'Sign me!'
- * digest = OpenSSL::Digest::SHA256.new
+ * digest = OpenSSL::Digest.new('SHA256')
* pkey = OpenSSL::PKey::RSA.new(2048)
* signature = pkey.sign(digest, data)
* pub_key = pkey.public_key
@@ -352,7 +535,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
int siglen, result;
GetPKey(self, pkey);
- pkey_check_public_key(pkey);
+ ossl_pkey_check_public_key(pkey);
md = ossl_evp_get_digestbyname(digest);
StringValue(sig);
siglen = RSTRING_LENINT(sig);
@@ -388,6 +571,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
void
Init_ossl_pkey(void)
{
+#undef rb_intern
#if 0
mOSSL = rb_define_module("OpenSSL");
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -467,6 +651,12 @@ Init_ossl_pkey(void)
rb_define_alloc_func(cPKey, ossl_pkey_alloc);
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
+ rb_define_method(cPKey, "oid", ossl_pkey_oid, 0);
+ rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0);
+ rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1);
+ rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
+ rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
+ rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
index a87472ad09..0db59305f7 100644
--- a/ext/openssl/ossl_pkey.h
+++ b/ext/openssl/ossl_pkey.h
@@ -37,13 +37,14 @@ extern const rb_data_type_t ossl_evp_pkey_type;
struct ossl_generate_cb_arg {
int yield;
- int stop;
+ int interrupted;
int state;
};
int ossl_generate_cb_2(int p, int n, BN_GENCB *cb);
void ossl_generate_cb_stop(void *ptr);
VALUE ossl_pkey_new(EVP_PKEY *);
+void ossl_pkey_check_public_key(const EVP_PKEY *);
EVP_PKEY *GetPKeyPtr(VALUE);
EVP_PKEY *DupPKeyPtr(VALUE);
EVP_PKEY *GetPrivPKeyPtr(VALUE);
@@ -132,9 +133,9 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALU
BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\
\
Get##_type(self, obj); \
- if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
- orig_bn2 && !(bn2 = BN_dup(orig_bn2)) || \
- orig_bn3 && !(bn3 = BN_dup(orig_bn3))) { \
+ if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \
+ (orig_bn2 && !(bn2 = BN_dup(orig_bn2))) || \
+ (orig_bn3 && !(bn3 = BN_dup(orig_bn3)))) { \
BN_clear_free(bn1); \
BN_clear_free(bn2); \
BN_clear_free(bn3); \
@@ -162,8 +163,8 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \
BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\
\
Get##_type(self, obj); \
- if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
- orig_bn2 && !(bn2 = BN_dup(orig_bn2))) { \
+ if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \
+ (orig_bn2 && !(bn2 = BN_dup(orig_bn2)))) { \
BN_clear_free(bn1); \
BN_clear_free(bn2); \
ossl_raise(eBNError, NULL); \
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 31f3b8e726..bf4e3f9322 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -262,7 +262,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
BIGNUM *pub2 = BN_dup(pub);
BIGNUM *priv2 = BN_dup(priv);
- if (!pub2 || priv && !priv2) {
+ if (!pub2 || (priv && !priv2)) {
BN_clear_free(pub2);
BN_clear_free(priv2);
ossl_raise(eDHError, "BN_dup");
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index 56cc9dd4f1..431c20e05c 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -513,7 +513,7 @@ ossl_dsa_to_public_key(VALUE self)
* === Example
* dsa = OpenSSL::PKey::DSA.new(2048)
* doc = "Sign me"
- * digest = OpenSSL::Digest::SHA1.digest(doc)
+ * digest = OpenSSL::Digest.digest('SHA1', doc)
* sig = dsa.syssign(digest)
*
*
@@ -558,7 +558,7 @@ ossl_dsa_sign(VALUE self, VALUE data)
* === Example
* dsa = OpenSSL::PKey::DSA.new(2048)
* doc = "Sign me"
- * digest = OpenSSL::Digest::SHA1.digest(doc)
+ * digest = OpenSSL::Digest.digest('SHA1', doc)
* sig = dsa.syssign(digest)
* puts dsa.sysverify(digest, sig) # => true
*
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index 9c406931a9..1d105abd35 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -653,15 +653,15 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
StringValue(data);
StringValue(sig);
- switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
- case 1: return Qtrue;
- case 0: return Qfalse;
- default: break;
+ switch (ECDSA_verify(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
+ (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) {
+ case 1:
+ return Qtrue;
+ case 0:
+ return Qfalse;
+ default:
+ ossl_raise(eECError, "ECDSA_verify");
}
-
- ossl_raise(eECError, "ECDSA_verify");
-
- UNREACHABLE;
}
/*
@@ -1319,76 +1319,61 @@ ec_point_new(const EC_POINT *point, const EC_GROUP *group)
return obj;
}
+static VALUE ossl_ec_point_initialize_copy(VALUE, VALUE);
/*
* call-seq:
* OpenSSL::PKey::EC::Point.new(point)
- * OpenSSL::PKey::EC::Point.new(group)
- * OpenSSL::PKey::EC::Point.new(group, bn)
+ * OpenSSL::PKey::EC::Point.new(group [, encoded_point])
*
- * See the OpenSSL documentation for EC_POINT_*
+ * Creates a new instance of OpenSSL::PKey::EC::Point. If the only argument is
+ * an instance of EC::Point, a copy is returned. Otherwise, creates a point
+ * that belongs to _group_.
+ *
+ * _encoded_point_ is the octet string representation of the point. This
+ * must be either a String or an OpenSSL::BN.
*/
static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
{
EC_POINT *point;
- VALUE arg1, arg2;
- VALUE group_v = Qnil;
- const EC_GROUP *group = NULL;
+ VALUE group_v, arg2;
+ const EC_GROUP *group;
TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point);
if (point)
- ossl_raise(eEC_POINT, "EC_POINT already initialized");
-
- switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
- case 1:
- if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
- const EC_POINT *arg_point;
+ rb_raise(eEC_POINT, "EC_POINT already initialized");
- group_v = rb_attr_get(arg1, id_i_group);
- GetECGroup(group_v, group);
- GetECPoint(arg1, arg_point);
-
- point = EC_POINT_dup(arg_point, group);
- } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
- group_v = arg1;
- GetECGroup(group_v, group);
-
- point = EC_POINT_new(group);
- } else {
- ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
- }
-
- break;
- case 2:
- if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
- ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
- group_v = arg1;
- GetECGroup(group_v, group);
-
- if (rb_obj_is_kind_of(arg2, cBN)) {
- const BIGNUM *bn = GetBNPtr(arg2);
-
- point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
- } else {
- BIO *in = ossl_obj2bio(&arg1);
-
-/* BUG: finish me */
-
- BIO_free(in);
-
- if (point == NULL) {
- ossl_raise(eEC_POINT, "unknown type for 2nd arg");
- }
- }
- break;
- default:
- ossl_raise(rb_eArgError, "wrong number of arguments");
+ rb_scan_args(argc, argv, "11", &group_v, &arg2);
+ if (rb_obj_is_kind_of(group_v, cEC_POINT)) {
+ if (argc != 1)
+ rb_raise(rb_eArgError, "invalid second argument");
+ return ossl_ec_point_initialize_copy(self, group_v);
}
- if (point == NULL)
- ossl_raise(eEC_POINT, NULL);
-
- if (NIL_P(group_v))
- ossl_raise(rb_eRuntimeError, "missing group (internal error)");
+ GetECGroup(group_v, group);
+ if (argc == 1) {
+ point = EC_POINT_new(group);
+ if (!point)
+ ossl_raise(eEC_POINT, "EC_POINT_new");
+ }
+ else {
+ if (rb_obj_is_kind_of(arg2, cBN)) {
+ point = EC_POINT_bn2point(group, GetBNPtr(arg2), NULL, ossl_bn_ctx);
+ if (!point)
+ ossl_raise(eEC_POINT, "EC_POINT_bn2point");
+ }
+ else {
+ StringValue(arg2);
+ point = EC_POINT_new(group);
+ if (!point)
+ ossl_raise(eEC_POINT, "EC_POINT_new");
+ if (!EC_POINT_oct2point(group, point,
+ (unsigned char *)RSTRING_PTR(arg2),
+ RSTRING_LEN(arg2), ossl_bn_ctx)) {
+ EC_POINT_free(point);
+ ossl_raise(eEC_POINT, "EC_POINT_oct2point");
+ }
+ }
+ }
RTYPEDDATA_DATA(self) = point;
rb_ivar_set(self, id_i_group, group_v);
@@ -1543,38 +1528,66 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
/*
* call-seq:
- * point.to_bn(conversion_form = nil) => OpenSSL::BN
+ * point.to_octet_string(conversion_form) -> String
+ *
+ * Returns the octet string representation of the elliptic curve point.
*
- * Convert the EC point into an octet string and store in an OpenSSL::BN. If
- * _conversion_form_ is given, the point data is converted using the specified
- * form. If not given, the default form set in the EC::Group object is used.
+ * _conversion_form_ specifies how the point is converted. Possible values are:
*
- * See also EC::Point#point_conversion_form=.
+ * - +:compressed+
+ * - +:uncompressed+
+ * - +:hybrid+
*/
static VALUE
-ossl_ec_point_to_bn(int argc, VALUE *argv, VALUE self)
+ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form)
{
EC_POINT *point;
- VALUE form_obj, bn_obj;
const EC_GROUP *group;
point_conversion_form_t form;
- BIGNUM *bn;
+ VALUE str;
+ size_t len;
GetECPoint(self, point);
GetECPointGroup(self, group);
- rb_scan_args(argc, argv, "01", &form_obj);
- if (NIL_P(form_obj))
- form = EC_GROUP_get_point_conversion_form(group);
- else
- form = parse_point_conversion_form_symbol(form_obj);
+ form = parse_point_conversion_form_symbol(conversion_form);
+
+ len = EC_POINT_point2oct(group, point, form, NULL, 0, ossl_bn_ctx);
+ if (!len)
+ ossl_raise(eEC_POINT, "EC_POINT_point2oct");
+ str = rb_str_new(NULL, (long)len);
+ if (!EC_POINT_point2oct(group, point, form,
+ (unsigned char *)RSTRING_PTR(str), len,
+ ossl_bn_ctx))
+ ossl_raise(eEC_POINT, "EC_POINT_point2oct");
+ return str;
+}
- bn_obj = rb_obj_alloc(cBN);
- bn = GetBNPtr(bn_obj);
+/*
+ * call-seq:
+ * point.add(point) => point
+ *
+ * Performs elliptic curve point addition.
+ */
+static VALUE ossl_ec_point_add(VALUE self, VALUE other)
+{
+ EC_POINT *point_self, *point_other, *point_result;
+ const EC_GROUP *group;
+ VALUE group_v = rb_attr_get(self, id_i_group);
+ VALUE result;
- if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL)
- ossl_raise(eEC_POINT, "EC_POINT_point2bn");
+ GetECPoint(self, point_self);
+ GetECPoint(other, point_other);
+ GetECGroup(group_v, group);
- return bn_obj;
+ result = rb_obj_alloc(cEC_POINT);
+ ossl_ec_point_initialize(1, &group_v, result);
+ GetECPoint(result, point_result);
+
+ if (EC_POINT_add(group, point_result, point_self, point_other, ossl_bn_ctx) != 1) {
+ ossl_raise(eEC_POINT, "EC_POINT_add");
+ }
+
+ return result;
}
/*
@@ -1664,6 +1677,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
void Init_ossl_ec(void)
{
+#undef rb_intern
#if 0
mPKey = rb_define_module_under(mOSSL, "PKey");
cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
@@ -1799,7 +1813,8 @@ void Init_ossl_ec(void)
rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0);
/* all the other methods */
- rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, -1);
+ rb_define_method(cEC_POINT, "to_octet_string", ossl_ec_point_to_octet_string, 1);
+ rb_define_method(cEC_POINT, "add", ossl_ec_point_add, 1);
rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
id_i_group = rb_intern("@group");
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 26397bd021..761866c66a 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -26,10 +26,10 @@
static inline int
RSA_HAS_PRIVATE(RSA *rsa)
{
- const BIGNUM *p, *q;
+ const BIGNUM *e, *d;
- RSA_get0_factors(rsa, &p, &q);
- return p && q; /* d? why? */
+ RSA_get0_key(rsa, NULL, &e, &d);
+ return e && d;
}
static inline int
@@ -341,6 +341,7 @@ static VALUE
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
{
RSA *rsa;
+ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
BIO *out;
const EVP_CIPHER *ciph = NULL;
VALUE cipher, pass, str;
@@ -356,7 +357,10 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eRSAError, NULL);
}
- if (RSA_HAS_PRIVATE(rsa)) {
+ RSA_get0_key(rsa, &n, &e, &d);
+ RSA_get0_factors(rsa, &p, &q);
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+ if (n && e && d && p && q && dmp1 && dmq1 && iqmp) {
if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
ossl_pem_passwd_cb, (void *)pass)) {
BIO_free(out);
@@ -383,23 +387,27 @@ static VALUE
ossl_rsa_to_der(VALUE self)
{
RSA *rsa;
+ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
int (*i2d_func)(const RSA *, unsigned char **);
- unsigned char *p;
+ unsigned char *ptr;
long len;
VALUE str;
GetRSA(self, rsa);
- if (RSA_HAS_PRIVATE(rsa))
+ RSA_get0_key(rsa, &n, &e, &d);
+ RSA_get0_factors(rsa, &p, &q);
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+ if (n && e && d && p && q && dmp1 && dmq1 && iqmp)
i2d_func = i2d_RSAPrivateKey;
else
i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY;
if((len = i2d_func(rsa, NULL)) <= 0)
ossl_raise(eRSAError, NULL);
str = rb_str_new(0, len);
- p = (unsigned char *)RSTRING_PTR(str);
- if(i2d_func(rsa, &p) < 0)
+ ptr = (unsigned char *)RSTRING_PTR(str);
+ if(i2d_func(rsa, &ptr) < 0)
ossl_raise(eRSAError, NULL);
- ossl_str_adjust(str, p);
+ ossl_str_adjust(str, ptr);
return str;
}
@@ -538,6 +546,196 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
/*
* call-seq:
+ * rsa.sign_pss(digest, data, salt_length:, mgf1_hash:) -> String
+ *
+ * Signs _data_ using the Probabilistic Signature Scheme (RSA-PSS) and returns
+ * the calculated signature.
+ *
+ * RSAError will be raised if an error occurs.
+ *
+ * See #verify_pss for the verification operation.
+ *
+ * === Parameters
+ * _digest_::
+ * A String containing the message digest algorithm name.
+ * _data_::
+ * A String. The data to be signed.
+ * _salt_length_::
+ * The length in octets of the salt. Two special values are reserved:
+ * +:digest+ means the digest length, and +:max+ means the maximum possible
+ * length for the combination of the private key and the selected message
+ * digest algorithm.
+ * _mgf1_hash_::
+ * The hash algorithm used in MGF1 (the currently supported mask generation
+ * function (MGF)).
+ *
+ * === Example
+ * data = "Sign me!"
+ * pkey = OpenSSL::PKey::RSA.new(2048)
+ * signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
+ * pub_key = pkey.public_key
+ * puts pub_key.verify_pss("SHA256", signature, data,
+ * salt_length: :auto, mgf1_hash: "SHA256") # => true
+ */
+static VALUE
+ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self)
+{
+ VALUE digest, data, options, kwargs[2], signature;
+ static ID kwargs_ids[2];
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pkey_ctx;
+ const EVP_MD *md, *mgf1md;
+ EVP_MD_CTX *md_ctx;
+ size_t buf_len;
+ int salt_len;
+
+ if (!kwargs_ids[0]) {
+ kwargs_ids[0] = rb_intern_const("salt_length");
+ kwargs_ids[1] = rb_intern_const("mgf1_hash");
+ }
+ rb_scan_args(argc, argv, "2:", &digest, &data, &options);
+ rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
+ if (kwargs[0] == ID2SYM(rb_intern("max")))
+ salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */
+ else if (kwargs[0] == ID2SYM(rb_intern("digest")))
+ salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
+ else
+ salt_len = NUM2INT(kwargs[0]);
+ mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
+
+ pkey = GetPrivPKeyPtr(self);
+ buf_len = EVP_PKEY_size(pkey);
+ md = ossl_evp_get_digestbyname(digest);
+ StringValue(data);
+ signature = rb_str_new(NULL, (long)buf_len);
+
+ md_ctx = EVP_MD_CTX_new();
+ if (!md_ctx)
+ goto err;
+
+ if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
+ goto err;
+
+ if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
+ goto err;
+
+ if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1)
+ goto err;
+
+ rb_str_set_len(signature, (long)buf_len);
+
+ EVP_MD_CTX_free(md_ctx);
+ return signature;
+
+ err:
+ EVP_MD_CTX_free(md_ctx);
+ ossl_raise(eRSAError, NULL);
+}
+
+/*
+ * call-seq:
+ * rsa.verify_pss(digest, signature, data, salt_length:, mgf1_hash:) -> true | false
+ *
+ * Verifies _data_ using the Probabilistic Signature Scheme (RSA-PSS).
+ *
+ * The return value is +true+ if the signature is valid, +false+ otherwise.
+ * RSAError will be raised if an error occurs.
+ *
+ * See #sign_pss for the signing operation and an example code.
+ *
+ * === Parameters
+ * _digest_::
+ * A String containing the message digest algorithm name.
+ * _data_::
+ * A String. The data to be signed.
+ * _salt_length_::
+ * The length in octets of the salt. Two special values are reserved:
+ * +:digest+ means the digest length, and +:auto+ means automatically
+ * determining the length based on the signature.
+ * _mgf1_hash_::
+ * The hash algorithm used in MGF1.
+ */
+static VALUE
+ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
+{
+ VALUE digest, signature, data, options, kwargs[2];
+ static ID kwargs_ids[2];
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pkey_ctx;
+ const EVP_MD *md, *mgf1md;
+ EVP_MD_CTX *md_ctx;
+ int result, salt_len;
+
+ if (!kwargs_ids[0]) {
+ kwargs_ids[0] = rb_intern_const("salt_length");
+ kwargs_ids[1] = rb_intern_const("mgf1_hash");
+ }
+ rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options);
+ rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
+ if (kwargs[0] == ID2SYM(rb_intern("auto")))
+ salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */
+ else if (kwargs[0] == ID2SYM(rb_intern("digest")))
+ salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
+ else
+ salt_len = NUM2INT(kwargs[0]);
+ mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
+
+ GetPKey(self, pkey);
+ md = ossl_evp_get_digestbyname(digest);
+ StringValue(signature);
+ StringValue(data);
+
+ md_ctx = EVP_MD_CTX_new();
+ if (!md_ctx)
+ goto err;
+
+ if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
+ goto err;
+
+ if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
+ goto err;
+
+ result = EVP_DigestVerifyFinal(md_ctx,
+ (unsigned char *)RSTRING_PTR(signature),
+ RSTRING_LEN(signature));
+
+ switch (result) {
+ case 0:
+ ossl_clear_error();
+ EVP_MD_CTX_free(md_ctx);
+ return Qfalse;
+ case 1:
+ EVP_MD_CTX_free(md_ctx);
+ return Qtrue;
+ default:
+ goto err;
+ }
+
+ err:
+ EVP_MD_CTX_free(md_ctx);
+ ossl_raise(eRSAError, NULL);
+}
+
+/*
+ * call-seq:
* rsa.params => hash
*
* THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
@@ -731,6 +929,8 @@ Init_ossl_rsa(void)
rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
+ rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1);
+ rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1);
DEF_OSSL_PKEY_BN(cRSA, rsa, n);
DEF_OSSL_PKEY_BN(cRSA, rsa, e);
diff --git a/ext/openssl/ossl_rand.c b/ext/openssl/ossl_rand.c
index c95857060a..659dc818b6 100644
--- a/ext/openssl/ossl_rand.c
+++ b/ext/openssl/ossl_rand.c
@@ -67,8 +67,6 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
static VALUE
ossl_rand_load_file(VALUE self, VALUE filename)
{
- rb_check_safe_obj(filename);
-
if(!RAND_load_file(StringValueCStr(filename), -1)) {
ossl_raise(eRandomError, NULL);
}
@@ -86,8 +84,6 @@ ossl_rand_load_file(VALUE self, VALUE filename)
static VALUE
ossl_rand_write_file(VALUE self, VALUE filename)
{
- rb_check_safe_obj(filename);
-
if (RAND_write_file(StringValueCStr(filename)) == -1) {
ossl_raise(eRandomError, NULL);
}
@@ -124,36 +120,6 @@ ossl_rand_bytes(VALUE self, VALUE len)
return str;
}
-#if defined(HAVE_RAND_PSEUDO_BYTES)
-/*
- * call-seq:
- * pseudo_bytes(length) -> string
- *
- * Generates a String with _length_ number of pseudo-random bytes.
- *
- * Pseudo-random byte sequences generated by ::pseudo_bytes will be unique if
- * they are of sufficient length, but are not necessarily unpredictable.
- *
- * === Example
- *
- * OpenSSL::Random.pseudo_bytes(12)
- * #=> "..."
- */
-static VALUE
-ossl_rand_pseudo_bytes(VALUE self, VALUE len)
-{
- VALUE str;
- int n = NUM2INT(len);
-
- str = rb_str_new(0, n);
- if (RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n) < 1) {
- ossl_raise(eRandomError, NULL);
- }
-
- return str;
-}
-#endif
-
#ifdef HAVE_RAND_EGD
/*
* call-seq:
@@ -164,8 +130,6 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
static VALUE
ossl_rand_egd(VALUE self, VALUE filename)
{
- rb_check_safe_obj(filename);
-
if (RAND_egd(StringValueCStr(filename)) == -1) {
ossl_raise(eRandomError, NULL);
}
@@ -186,8 +150,6 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
{
int n = NUM2INT(len);
- rb_check_safe_obj(filename);
-
if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) {
ossl_raise(eRandomError, NULL);
}
@@ -227,8 +189,8 @@ Init_ossl_rand(void)
rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1);
rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1);
rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1);
-#if defined(HAVE_RAND_PSEUDO_BYTES)
- rb_define_module_function(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1);
+#if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
+ rb_define_alias(rb_singleton_class(mRandom), "pseudo_bytes", "random_bytes");
#endif
#ifdef HAVE_RAND_EGD
rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1);
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 93fc497e7e..7654be12ee 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -13,6 +13,12 @@
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
+#if !defined(TLS1_3_VERSION) && \
+ defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER >= 0x3020000fL
+# define TLS1_3_VERSION 0x0304
+#endif
+
#ifdef _WIN32
# define TO_SOCKET(s) _get_osfhandle(s)
#else
@@ -32,8 +38,8 @@ VALUE cSSLSocket;
static VALUE eSSLErrorWaitReadable;
static VALUE eSSLErrorWaitWritable;
-static ID ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
- id_npn_protocols_encoded;
+static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
+ id_npn_protocols_encoded, id_each;
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
@@ -54,6 +60,13 @@ static int ossl_sslctx_ex_store_p;
#endif
static void
+ossl_sslctx_mark(void *ptr)
+{
+ SSL_CTX *ctx = ptr;
+ rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
+}
+
+static void
ossl_sslctx_free(void *ptr)
{
SSL_CTX *ctx = ptr;
@@ -67,7 +80,7 @@ ossl_sslctx_free(void *ptr)
static const rb_data_type_t ossl_sslctx_type = {
"OpenSSL/SSL/CTX",
{
- 0, ossl_sslctx_free,
+ ossl_sslctx_mark, ossl_sslctx_free,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
@@ -184,8 +197,10 @@ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
for (i = 0; i < numberof(options_map); i++) {
sum |= options_map[i].opts;
- if (min && min > options_map[i].ver || max && max < options_map[i].ver)
+ if ((min && min > options_map[i].ver) ||
+ (max && max < options_map[i].ver)) {
opts |= options_map[i].opts;
+ }
}
SSL_CTX_clear_options(ctx, sum);
SSL_CTX_set_options(ctx, opts);
@@ -205,7 +220,7 @@ ossl_call_client_cert_cb(VALUE obj)
if (NIL_P(cb))
return Qnil;
- ary = rb_funcall(cb, rb_intern("call"), 1, obj);
+ ary = rb_funcallv(cb, id_call, 1, &obj);
Check_Type(ary, T_ARRAY);
GetX509CertPtr(cert = rb_ary_entry(ary, 0));
GetPrivPKeyPtr(key = rb_ary_entry(ary, 1));
@@ -248,8 +263,8 @@ ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args)
cb = rb_funcall(args->ssl_obj, args->id, 0);
if (NIL_P(cb))
return NULL;
- dh = rb_funcall(cb, rb_intern("call"), 3,
- args->ssl_obj, INT2NUM(args->is_export), INT2NUM(args->keylength));
+ dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
+ INT2NUM(args->keylength));
pkey = GetPKeyPtr(dh);
if (EVP_PKEY_base_id(pkey) != args->type)
return NULL;
@@ -357,7 +372,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
return 0;
}
- preverify_ok = ret == Qtrue;
+ if (ret != Qtrue) {
+ preverify_ok = 0;
+#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
+#else
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
+#endif
+ }
}
return ossl_verify_cb_call(cb, preverify_ok, ctx);
@@ -374,12 +396,11 @@ ossl_call_session_get_cb(VALUE ary)
cb = rb_funcall(ssl_obj, rb_intern("session_get_cb"), 0);
if (NIL_P(cb)) return Qnil;
- return rb_funcall(cb, rb_intern("call"), 1, ary);
+ return rb_funcallv(cb, id_call, 1, &ary);
}
-/* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */
static SSL_SESSION *
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+#if (!defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x10100000 : LIBRESSL_VERSION_NUMBER >= 0x2080000f)
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
#else
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
@@ -420,7 +441,7 @@ ossl_call_session_new_cb(VALUE ary)
cb = rb_funcall(ssl_obj, rb_intern("session_new_cb"), 0);
if (NIL_P(cb)) return Qnil;
- return rb_funcall(cb, rb_intern("call"), 1, ary);
+ return rb_funcallv(cb, id_call, 1, &ary);
}
/* return 1 normal. return 0 removes the session */
@@ -467,7 +488,7 @@ ossl_call_session_remove_cb(VALUE ary)
cb = rb_attr_get(sslctx_obj, id_i_session_remove_cb);
if (NIL_P(cb)) return Qnil;
- return rb_funcall(cb, rb_intern("call"), 1, ary);
+ return rb_funcallv(cb, id_call, 1, &ary);
}
static void
@@ -533,7 +554,7 @@ ossl_call_servername_cb(VALUE ary)
cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
if (NIL_P(cb)) return Qnil;
- ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary);
+ ret_obj = rb_funcallv(cb, id_call, 1, &ary);
if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
SSL *ssl;
SSL_CTX *ctx2;
@@ -585,13 +606,13 @@ ssl_renegotiation_cb(const SSL *ssl)
cb = rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
if (NIL_P(cb)) return;
- (void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
+ rb_funcallv(cb, id_call, 1, &ssl_obj);
}
#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
static VALUE
-ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
+ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
{
int len = RSTRING_LENINT(cur);
char len_byte;
@@ -608,7 +629,7 @@ static VALUE
ssl_encode_npn_protocols(VALUE protocols)
{
VALUE encoded = rb_str_new(NULL, 0);
- rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
+ rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
return encoded;
}
@@ -635,7 +656,7 @@ npn_select_cb_common_i(VALUE tmp)
in += l;
}
- selected = rb_funcall(args->cb, rb_intern("call"), 1, protocols);
+ selected = rb_funcallv(args->cb, id_call, 1, &protocols);
StringValue(selected);
len = RSTRING_LEN(selected);
if (len < 1 || len >= 256) {
@@ -678,7 +699,7 @@ static int
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
void *arg)
{
- VALUE protocols = (VALUE)arg;
+ VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
*out = (const unsigned char *) RSTRING_PTR(protocols);
*outlen = RSTRING_LENINT(protocols);
@@ -809,6 +830,10 @@ ossl_sslctx_setup(VALUE self)
}
#endif /* OPENSSL_NO_EC */
+#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
+ SSL_CTX_set_post_handshake_auth(ctx, 1);
+#endif
+
val = rb_attr_get(self, id_i_cert_store);
if (!NIL_P(val)) {
X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
@@ -896,7 +921,7 @@ ossl_sslctx_setup(VALUE self)
if (!NIL_P(val)) {
VALUE encoded = ssl_encode_npn_protocols(val);
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
OSSL_Debug("SSL NPN advertise callback added");
}
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
@@ -1035,10 +1060,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
}
GetSSLCTX(self, ctx);
- if(!ctx){
- ossl_raise(eSSLError, "SSL_CTX is not initialized.");
- return Qnil;
- }
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
}
@@ -1193,6 +1214,134 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value)
return value;
}
+#ifdef SSL_MODE_SEND_FALLBACK_SCSV
+/*
+ * call-seq:
+ * ctx.enable_fallback_scsv() => nil
+ *
+ * Activate TLS_FALLBACK_SCSV for this context.
+ * See RFC 7507.
+ */
+static VALUE
+ossl_sslctx_enable_fallback_scsv(VALUE self)
+{
+ SSL_CTX *ctx;
+
+ GetSSLCTX(self, ctx);
+ SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);
+
+ return Qnil;
+}
+#endif
+
+/*
+ * call-seq:
+ * ctx.add_certificate(certiticate, pkey [, extra_certs]) -> self
+ *
+ * Adds a certificate to the context. _pkey_ must be a corresponding private
+ * key with _certificate_.
+ *
+ * Multiple certificates with different public key type can be added by
+ * repeated calls of this method, and OpenSSL will choose the most appropriate
+ * certificate during the handshake.
+ *
+ * #cert=, #key=, and #extra_chain_cert= are old accessor methods for setting
+ * certificate and internally call this method.
+ *
+ * === Parameters
+ * _certificate_::
+ * A certificate. An instance of OpenSSL::X509::Certificate.
+ * _pkey_::
+ * The private key for _certificate_. An instance of OpenSSL::PKey::PKey.
+ * _extra_certs_::
+ * Optional. An array of OpenSSL::X509::Certificate. When sending a
+ * certificate chain, the certificates specified by this are sent following
+ * _certificate_, in the order in the array.
+ *
+ * === Example
+ * rsa_cert = OpenSSL::X509::Certificate.new(...)
+ * rsa_pkey = OpenSSL::PKey.read(...)
+ * ca_intermediate_cert = OpenSSL::X509::Certificate.new(...)
+ * ctx.add_certificate(rsa_cert, rsa_pkey, [ca_intermediate_cert])
+ *
+ * ecdsa_cert = ...
+ * ecdsa_pkey = ...
+ * another_ca_cert = ...
+ * ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
+ *
+ * === Note
+ * OpenSSL before the version 1.0.2 could handle only one extra chain across
+ * all key types. Calling this method discards the chain set previously.
+ */
+static VALUE
+ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
+{
+ VALUE cert, key, extra_chain_ary;
+ SSL_CTX *ctx;
+ X509 *x509;
+ STACK_OF(X509) *extra_chain = NULL;
+ EVP_PKEY *pkey, *pub_pkey;
+
+ GetSSLCTX(self, ctx);
+ rb_scan_args(argc, argv, "21", &cert, &key, &extra_chain_ary);
+ rb_check_frozen(self);
+ x509 = GetX509CertPtr(cert);
+ pkey = GetPrivPKeyPtr(key);
+
+ /*
+ * The reference counter is bumped, and decremented immediately.
+ * X509_get0_pubkey() is only available in OpenSSL >= 1.1.0.
+ */
+ pub_pkey = X509_get_pubkey(x509);
+ EVP_PKEY_free(pub_pkey);
+ if (!pub_pkey)
+ rb_raise(rb_eArgError, "certificate does not contain public key");
+ if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
+ rb_raise(rb_eArgError, "public key mismatch");
+
+ if (argc >= 3)
+ extra_chain = ossl_x509_ary2sk(extra_chain_ary);
+
+ if (!SSL_CTX_use_certificate(ctx, x509)) {
+ sk_X509_pop_free(extra_chain, X509_free);
+ ossl_raise(eSSLError, "SSL_CTX_use_certificate");
+ }
+ if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
+ sk_X509_pop_free(extra_chain, X509_free);
+ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
+ }
+
+ if (extra_chain) {
+#if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
+ if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
+ sk_X509_pop_free(extra_chain, X509_free);
+ ossl_raise(eSSLError, "SSL_CTX_set0_chain");
+ }
+#else
+ STACK_OF(X509) *orig_extra_chain;
+ X509 *x509_tmp;
+
+ /* First, clear the existing chain */
+ SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
+ if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
+ rb_warning("SSL_CTX_set0_chain() is not available; " \
+ "clearing previously set certificate chain");
+ SSL_CTX_clear_extra_chain_certs(ctx);
+ }
+ while ((x509_tmp = sk_X509_shift(extra_chain))) {
+ /* Transfers ownership */
+ if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
+ X509_free(x509_tmp);
+ sk_X509_pop_free(extra_chain, X509_free);
+ ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
+ }
+ }
+ sk_X509_free(extra_chain);
+#endif
+ }
+ return self;
+}
+
/*
* call-seq:
* ctx.session_add(session) -> true | false
@@ -1391,6 +1540,14 @@ ssl_started(SSL *ssl)
}
static void
+ossl_ssl_mark(void *ptr)
+{
+ SSL *ssl = ptr;
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
+}
+
+static void
ossl_ssl_free(void *ssl)
{
SSL_free(ssl);
@@ -1399,7 +1556,7 @@ ossl_ssl_free(void *ssl)
const rb_data_type_t ossl_ssl_type = {
"OpenSSL/SSL",
{
- 0, ossl_ssl_free,
+ ossl_ssl_mark, ossl_ssl_free,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
@@ -1555,6 +1712,11 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
rb_io_wait_readable(fptr->fd);
continue;
case SSL_ERROR_SYSCALL:
+#ifdef __APPLE__
+ /* See ossl_ssl_write_internal() */
+ if (errno == EPROTOTYPE)
+ continue;
+#endif
if (errno) rb_sys_fail(funcname);
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
@@ -1703,7 +1865,6 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
else
rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
}
- OBJ_TAINT(str);
rb_str_set_len(str, 0);
if (ilen == 0)
return str;
@@ -1712,26 +1873,36 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
io = rb_attr_get(self, id_i_io);
GetOpenFile(io, fptr);
if (ssl_started(ssl)) {
- for (;;){
+ rb_str_locktmp(str);
+ for (;;) {
nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
switch(ssl_get_error(ssl, nread)){
case SSL_ERROR_NONE:
+ rb_str_unlocktmp(str);
goto end;
case SSL_ERROR_ZERO_RETURN:
+ rb_str_unlocktmp(str);
if (no_exception_p(opts)) { return Qnil; }
rb_eof_error();
case SSL_ERROR_WANT_WRITE:
- if (no_exception_p(opts)) { return sym_wait_writable; }
- write_would_block(nonblock);
+ if (nonblock) {
+ rb_str_unlocktmp(str);
+ if (no_exception_p(opts)) { return sym_wait_writable; }
+ write_would_block(nonblock);
+ }
rb_io_wait_writable(fptr->fd);
continue;
case SSL_ERROR_WANT_READ:
- if (no_exception_p(opts)) { return sym_wait_readable; }
- read_would_block(nonblock);
+ if (nonblock) {
+ rb_str_unlocktmp(str);
+ if (no_exception_p(opts)) { return sym_wait_readable; }
+ read_would_block(nonblock);
+ }
rb_io_wait_readable(fptr->fd);
continue;
case SSL_ERROR_SYSCALL:
if (!ERR_peek_error()) {
+ rb_str_unlocktmp(str);
if (errno)
rb_sys_fail(0);
else {
@@ -1746,19 +1917,32 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
rb_eof_error();
}
}
+ /* fall through */
default:
+ rb_str_unlocktmp(str);
ossl_raise(eSSLError, "SSL_read");
}
}
}
else {
- ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
-
- rb_warning("SSL session is not started yet.");
- if (nonblock)
- return rb_funcall(io, meth, 3, len, str, opts);
- else
- return rb_funcall(io, meth, 2, len, str);
+ ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
+
+ rb_warning("SSL session is not started yet.");
+#if defined(RB_PASS_KEYWORDS)
+ if (nonblock) {
+ VALUE argv[3];
+ argv[0] = len;
+ argv[1] = str;
+ argv[2] = opts;
+ return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS);
+ }
+#else
+ if (nonblock) {
+ return rb_funcall(io, meth, 3, len, str, opts);
+ }
+#endif
+ else
+ return rb_funcall(io, meth, 2, len, str);
}
end:
@@ -1806,21 +1990,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
int nwrite = 0;
rb_io_t *fptr;
int nonblock = opts != Qfalse;
- VALUE io;
+ VALUE tmp, io;
- StringValue(str);
+ tmp = rb_str_new_frozen(StringValue(str));
GetSSL(self, ssl);
io = rb_attr_get(self, id_i_io);
GetOpenFile(io, fptr);
if (ssl_started(ssl)) {
- for (;;){
- int num = RSTRING_LENINT(str);
+ for (;;) {
+ int num = RSTRING_LENINT(tmp);
/* SSL_write(3ssl) manpage states num == 0 is undefined */
if (num == 0)
goto end;
- nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
+ nwrite = SSL_write(ssl, RSTRING_PTR(tmp), num);
switch(ssl_get_error(ssl, nwrite)){
case SSL_ERROR_NONE:
goto end;
@@ -1835,6 +2019,16 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
rb_io_wait_readable(fptr->fd);
continue;
case SSL_ERROR_SYSCALL:
+#ifdef __APPLE__
+ /*
+ * It appears that send syscall can return EPROTOTYPE if the
+ * socket is being torn down. Retry to get a proper errno to
+ * make the error handling in line with the socket library.
+ * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
+ */
+ if (errno == EPROTOTYPE)
+ continue;
+#endif
if (errno) rb_sys_fail(0);
default:
ossl_raise(eSSLError, "SSL_write");
@@ -1845,11 +2039,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
ID meth = nonblock ?
rb_intern("write_nonblock") : rb_intern("syswrite");
- rb_warning("SSL session is not started yet.");
- if (nonblock)
- return rb_funcall(io, meth, 2, str, opts);
- else
- return rb_funcall(io, meth, 1, str);
+ rb_warning("SSL session is not started yet.");
+#if defined(RB_PASS_KEYWORDS)
+ if (nonblock) {
+ VALUE argv[2];
+ argv[0] = str;
+ argv[1] = opts;
+ return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
+ }
+#else
+ if (nonblock) {
+ return rb_funcall(io, meth, 2, str, opts);
+ }
+#endif
+ else
+ return rb_funcall(io, meth, 1, str);
}
end:
@@ -2152,7 +2356,57 @@ ossl_ssl_get_verify_result(VALUE self)
GetSSL(self, ssl);
- return INT2NUM(SSL_get_verify_result(ssl));
+ return LONG2NUM(SSL_get_verify_result(ssl));
+}
+
+/*
+ * call-seq:
+ * ssl.finished_message => "finished message"
+ *
+ * Returns the last *Finished* message sent
+ *
+ */
+static VALUE
+ossl_ssl_get_finished(VALUE self)
+{
+ SSL *ssl;
+ char sizer[1], *buf;
+ size_t len;
+
+ GetSSL(self, ssl);
+
+ len = SSL_get_finished(ssl, sizer, 0);
+ if (len == 0)
+ return Qnil;
+
+ buf = ALLOCA_N(char, len);
+ SSL_get_finished(ssl, buf, len);
+ return rb_str_new(buf, len);
+}
+
+/*
+ * call-seq:
+ * ssl.peer_finished_message => "peer finished message"
+ *
+ * Returns the last *Finished* message received
+ *
+ */
+static VALUE
+ossl_ssl_get_peer_finished(VALUE self)
+{
+ SSL *ssl;
+ char sizer[1], *buf;
+ size_t len;
+
+ GetSSL(self, ssl);
+
+ len = SSL_get_peer_finished(ssl, sizer, 0);
+ if (len == 0)
+ return Qnil;
+
+ buf = ALLOCA_N(char, len);
+ SSL_get_peer_finished(ssl, buf, len);
+ return rb_str_new(buf, len);
}
/*
@@ -2249,8 +2503,6 @@ ossl_ssl_tmp_key(VALUE self)
# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
#endif /* !defined(OPENSSL_NO_SOCK) */
-#undef rb_intern
-#define rb_intern(s) rb_intern_const(s)
void
Init_ossl_ssl(void)
{
@@ -2261,7 +2513,8 @@ Init_ossl_ssl(void)
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
#endif
- ID_callback_state = rb_intern("callback_state");
+ id_call = rb_intern_const("call");
+ ID_callback_state = rb_intern_const("callback_state");
ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
if (ossl_ssl_ex_vcb_idx < 0)
@@ -2324,35 +2577,41 @@ Init_ossl_ssl(void)
/*
* Context certificate
+ *
+ * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
+ * It is recommended to use #add_certificate instead.
*/
- rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse);
/*
* Context private key
+ *
+ * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
+ * It is recommended to use #add_certificate instead.
*/
- rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse);
/*
* A certificate or Array of certificates that will be sent to the client.
*/
- rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse);
/*
* The path to a file containing a PEM-format CA certificate
*/
- rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse);
/*
* The path to a directory containing CA certificates in PEM format.
*
* Files are looked up by subject's X509 name's hash value.
*/
- rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse);
/*
* Maximum session lifetime in seconds.
*/
- rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse);
/*
* Session verification mode.
@@ -2365,12 +2624,12 @@ Init_ossl_ssl(void)
*
* See SSL_CTX_set_verify(3) for details.
*/
- rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse);
/*
* Number of CA certificates to walk when verifying a certificate chain.
*/
- rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse);
/*
* A callback for additional certificate verification. The callback is
@@ -2384,7 +2643,7 @@ Init_ossl_ssl(void)
* If the callback returns +false+, the chain verification is immediately
* stopped and a bad_certificate alert is then sent.
*/
- rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse);
/*
* Whether to check the server certificate is valid for the hostname.
@@ -2392,18 +2651,21 @@ Init_ossl_ssl(void)
* In order to make this work, verify_mode must be set to VERIFY_PEER and
* the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
*/
- rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse);
/*
* An OpenSSL::X509::Store used for certificate verification.
*/
- rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse);
/*
* An Array of extra X509 certificates to be added to the certificate
* chain.
+ *
+ * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
+ * It is recommended to use #add_certificate instead.
*/
- rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse);
/*
* A callback invoked when a client certificate is requested by a server
@@ -2413,7 +2675,7 @@ Init_ossl_ssl(void)
* containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
* other value is returned the handshake is suspended.
*/
- rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
/*
@@ -2426,7 +2688,7 @@ Init_ossl_ssl(void)
* The callback is deprecated. This does not work with recent versions of
* OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
*/
- rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("tmp_ecdh_callback"), 1, 1, Qfalse);
#endif
/*
@@ -2434,7 +2696,7 @@ Init_ossl_ssl(void)
* sessions for multiple applications to be distinguished, for example, by
* name.
*/
- rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse);
/*
* A callback invoked on a server when a session is proposed by the client
@@ -2443,7 +2705,7 @@ Init_ossl_ssl(void)
* The callback is invoked with the SSLSocket and session id. The
* callback may return a Session from an external cache.
*/
- rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse);
/*
* A callback invoked when a new session was negotiated.
@@ -2451,25 +2713,29 @@ Init_ossl_ssl(void)
* The callback is invoked with an SSLSocket. If +false+ is returned the
* session will be removed from the internal cache.
*/
- rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse);
/*
* A callback invoked when a session is removed from the internal cache.
*
* The callback is invoked with an SSLContext and a Session.
+ *
+ * IMPORTANT NOTE: It is currently not possible to use this safely in a
+ * multi-threaded application. The callback is called inside a global lock
+ * and it can randomly cause deadlock on Ruby thread switching.
*/
- rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
/*
- * A callback invoked whenever a new handshake is initiated. May be used
- * to disable renegotiation entirely.
+ * A callback invoked whenever a new handshake is initiated on an
+ * established connection. May be used to disable renegotiation entirely.
*
* The callback is invoked with the active SSLSocket. The callback's
- * return value is irrelevant, normal return indicates "approval" of the
+ * return value is ignored. A normal return indicates "approval" of the
* renegotiation and will continue the process. To forbid renegotiation
- * and to cancel the process, an Error may be raised within the callback.
+ * and to cancel the process, raise an exception within the callback.
*
* === Disable client renegotiation
*
@@ -2477,13 +2743,11 @@ Init_ossl_ssl(void)
* renegotiation entirely. You may use a callback as follows to implement
* this feature:
*
- * num_handshakes = 0
* ctx.renegotiation_cb = lambda do |ssl|
- * num_handshakes += 1
- * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
+ * raise RuntimeError, "Client renegotiation disabled"
* end
*/
- rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* An Enumerable of Strings. Each String represents a protocol to be
@@ -2496,7 +2760,7 @@ Init_ossl_ssl(void)
*
* ctx.npn_protocols = ["http/1.1", "spdy/2"]
*/
- rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse);
/*
* A callback invoked on the client side when the client needs to select
* a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
@@ -2513,7 +2777,7 @@ Init_ossl_ssl(void)
* protocols.first
* end
*/
- rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
#endif
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
@@ -2528,7 +2792,7 @@ Init_ossl_ssl(void)
*
* ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
*/
- rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse);
/*
* A callback invoked on the server side when the server needs to select
* a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
@@ -2545,7 +2809,7 @@ Init_ossl_ssl(void)
* protocols.first
* end
*/
- rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
#endif
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
@@ -2557,6 +2821,10 @@ Init_ossl_ssl(void)
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
+#ifdef SSL_MODE_SEND_FALLBACK_SCSV
+ rb_define_method(cSSLContext, "enable_fallback_scsv", ossl_sslctx_enable_fallback_scsv, 0);
+#endif
+ rb_define_method(cSSLContext, "add_certificate", ossl_sslctx_add_certificate, -1);
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
rb_define_alias(cSSLContext, "freeze", "setup");
@@ -2654,6 +2922,8 @@ Init_ossl_ssl(void)
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
/* #hostname is defined in lib/openssl/ssl.rb */
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
+ rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
+ rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
# endif
@@ -2767,16 +3037,17 @@ Init_ossl_ssl(void)
#endif
- sym_exception = ID2SYM(rb_intern("exception"));
- sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
- sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
+ sym_exception = ID2SYM(rb_intern_const("exception"));
+ sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
+ sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
- id_tmp_dh_callback = rb_intern("tmp_dh_callback");
- id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
- id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
+ id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
+ id_tmp_ecdh_callback = rb_intern_const("tmp_ecdh_callback");
+ id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
+ id_each = rb_intern_const("each");
#define DefIVarID(name) do \
- id_i_##name = rb_intern("@"#name); while (0)
+ id_i_##name = rb_intern_const("@"#name); while (0)
DefIVarID(cert_store);
DefIVarID(ca_file);
diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c
new file mode 100644
index 0000000000..cff9b7bfff
--- /dev/null
+++ b/ext/openssl/ossl_ts.c
@@ -0,0 +1,1524 @@
+/*
+ *
+ * Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com>
+ * All rights reserved.
+ */
+/*
+ * This program is licenced under the same licence as Ruby.
+ * (See the file 'LICENCE'.)
+ */
+#include "ossl.h"
+
+#ifndef OPENSSL_NO_TS
+
+#define NewTSRequest(klass) \
+ TypedData_Wrap_Struct((klass), &ossl_ts_req_type, 0)
+#define SetTSRequest(obj, req) do { \
+ if (!(req)) { \
+ ossl_raise(rb_eRuntimeError, "TS_REQ wasn't initialized."); \
+ } \
+ RTYPEDDATA_DATA(obj) = (req); \
+} while (0)
+#define GetTSRequest(obj, req) do { \
+ TypedData_Get_Struct((obj), TS_REQ, &ossl_ts_req_type, (req)); \
+ if (!(req)) { \
+ ossl_raise(rb_eRuntimeError, "TS_REQ wasn't initialized."); \
+ } \
+} while (0)
+
+#define NewTSResponse(klass) \
+ TypedData_Wrap_Struct((klass), &ossl_ts_resp_type, 0)
+#define SetTSResponse(obj, resp) do { \
+ if (!(resp)) { \
+ ossl_raise(rb_eRuntimeError, "TS_RESP wasn't initialized."); \
+ } \
+ RTYPEDDATA_DATA(obj) = (resp); \
+} while (0)
+#define GetTSResponse(obj, resp) do { \
+ TypedData_Get_Struct((obj), TS_RESP, &ossl_ts_resp_type, (resp)); \
+ if (!(resp)) { \
+ ossl_raise(rb_eRuntimeError, "TS_RESP wasn't initialized."); \
+ } \
+} while (0)
+
+#define NewTSTokenInfo(klass) \
+ TypedData_Wrap_Struct((klass), &ossl_ts_token_info_type, 0)
+#define SetTSTokenInfo(obj, info) do { \
+ if (!(info)) { \
+ ossl_raise(rb_eRuntimeError, "TS_TST_INFO wasn't initialized."); \
+ } \
+ RTYPEDDATA_DATA(obj) = (info); \
+} while (0)
+#define GetTSTokenInfo(obj, info) do { \
+ TypedData_Get_Struct((obj), TS_TST_INFO, &ossl_ts_token_info_type, (info)); \
+ if (!(info)) { \
+ ossl_raise(rb_eRuntimeError, "TS_TST_INFO wasn't initialized."); \
+ } \
+} while (0)
+
+#define ossl_tsfac_get_default_policy_id(o) rb_attr_get((o),rb_intern("@default_policy_id"))
+#define ossl_tsfac_get_serial_number(o) rb_attr_get((o),rb_intern("@serial_number"))
+#define ossl_tsfac_get_gen_time(o) rb_attr_get((o),rb_intern("@gen_time"))
+#define ossl_tsfac_get_additional_certs(o) rb_attr_get((o),rb_intern("@additional_certs"))
+#define ossl_tsfac_get_allowed_digests(o) rb_attr_get((o),rb_intern("@allowed_digests"))
+
+static VALUE mTimestamp;
+static VALUE eTimestampError;
+static VALUE cTimestampRequest;
+static VALUE cTimestampResponse;
+static VALUE cTimestampTokenInfo;
+static VALUE cTimestampFactory;
+static VALUE sBAD_ALG, sBAD_REQUEST, sBAD_DATA_FORMAT, sTIME_NOT_AVAILABLE;
+static VALUE sUNACCEPTED_POLICY, sUNACCEPTED_EXTENSION, sADD_INFO_NOT_AVAILABLE;
+static VALUE sSYSTEM_FAILURE;
+
+static void
+ossl_ts_req_free(void *ptr)
+{
+ TS_REQ_free(ptr);
+}
+
+static const rb_data_type_t ossl_ts_req_type = {
+ "OpenSSL/Timestamp/Request",
+ {
+ 0, ossl_ts_req_free,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
+};
+
+static void
+ossl_ts_resp_free(void *ptr)
+{
+ TS_RESP_free(ptr);
+}
+
+static const rb_data_type_t ossl_ts_resp_type = {
+ "OpenSSL/Timestamp/Response",
+ {
+ 0, ossl_ts_resp_free,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
+};
+
+static void
+ossl_ts_token_info_free(void *ptr)
+{
+ TS_TST_INFO_free(ptr);
+}
+
+static const rb_data_type_t ossl_ts_token_info_type = {
+ "OpenSSL/Timestamp/TokenInfo",
+ {
+ 0, ossl_ts_token_info_free,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
+};
+
+static VALUE
+asn1_to_der(void *template, int (*i2d)(void *template, unsigned char **pp))
+{
+ VALUE str;
+ int len;
+ unsigned char *p;
+
+ if((len = i2d(template, NULL)) <= 0)
+ ossl_raise(eTimestampError, "Error when encoding to DER");
+ str = rb_str_new(0, len);
+ p = (unsigned char *)RSTRING_PTR(str);
+ if(i2d(template, &p) <= 0)
+ ossl_raise(eTimestampError, "Error when encoding to DER");
+ rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str));
+
+ return str;
+}
+
+static ASN1_OBJECT*
+obj_to_asn1obj(VALUE obj)
+{
+ ASN1_OBJECT *a1obj;
+
+ StringValue(obj);
+ a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0);
+ if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1);
+ if(!a1obj) ossl_raise(eASN1Error, "invalid OBJECT ID");
+
+ return a1obj;
+}
+
+static VALUE
+get_asn1obj(ASN1_OBJECT *obj)
+{
+ BIO *out;
+ VALUE ret;
+ int nid;
+ if ((nid = OBJ_obj2nid(obj)) != NID_undef)
+ ret = rb_str_new2(OBJ_nid2sn(nid));
+ else{
+ if (!(out = BIO_new(BIO_s_mem())))
+ ossl_raise(eX509AttrError, NULL);
+ i2a_ASN1_OBJECT(out, obj);
+ ret = ossl_membio2str(out);
+ }
+
+ return ret;
+}
+
+static VALUE
+ossl_ts_req_alloc(VALUE klass)
+{
+ TS_REQ *req;
+ VALUE obj;
+
+ obj = NewTSRequest(klass);
+ if (!(req = TS_REQ_new()))
+ ossl_raise(eTimestampError, NULL);
+ SetTSRequest(obj, req);
+
+ /* Defaults */
+ TS_REQ_set_version(req, 1);
+ TS_REQ_set_cert_req(req, 1);
+
+ return obj;
+}
+
+/*
+ * When creating a Request with the +File+ or +string+ parameter, the
+ * corresponding +File+ or +string+ must be DER-encoded.
+ *
+ * call-seq:
+ * OpenSSL::Timestamp::Request.new(file) -> request
+ * OpenSSL::Timestamp::Request.new(string) -> request
+ * OpenSSL::Timestamp::Request.new -> empty request
+ */
+static VALUE
+ossl_ts_req_initialize(int argc, VALUE *argv, VALUE self)
+{
+ TS_REQ *ts_req = DATA_PTR(self);
+ BIO *in;
+ VALUE arg;
+
+ if(rb_scan_args(argc, argv, "01", &arg) == 0) {
+ return self;
+ }
+
+ arg = ossl_to_der_if_possible(arg);
+ in = ossl_obj2bio(&arg);
+ ts_req = d2i_TS_REQ_bio(in, &ts_req);
+ BIO_free(in);
+ if (!ts_req) {
+ DATA_PTR(self) = NULL;
+ ossl_raise(eTimestampError, "Error when decoding the timestamp request");
+ }
+ DATA_PTR(self) = ts_req;
+
+ return self;
+}
+
+/*
+ * Returns the 'short name' of the object identifier that represents the
+ * algorithm that was used to create the message imprint digest.
+ *
+ * call-seq:
+ * request.algorithm -> string
+ */
+static VALUE
+ossl_ts_req_get_algorithm(VALUE self)
+{
+ TS_REQ *req;
+ TS_MSG_IMPRINT *mi;
+ X509_ALGOR *algor;
+
+ GetTSRequest(self, req);
+ mi = TS_REQ_get_msg_imprint(req);
+ algor = TS_MSG_IMPRINT_get_algo(mi);
+ return get_asn1obj(algor->algorithm);
+}
+
+/*
+ * Allows to set the object identifier or the 'short name' of the
+ * algorithm that was used to create the message imprint digest.
+ *
+ * ===Example:
+ * request.algorithm = "SHA1"
+ *
+ * call-seq:
+ * request.algorithm = "string" -> string
+ */
+static VALUE
+ossl_ts_req_set_algorithm(VALUE self, VALUE algo)
+{
+ TS_REQ *req;
+ TS_MSG_IMPRINT *mi;
+ ASN1_OBJECT *obj;
+ X509_ALGOR *algor;
+
+ GetTSRequest(self, req);
+ obj = obj_to_asn1obj(algo);
+ mi = TS_REQ_get_msg_imprint(req);
+ algor = TS_MSG_IMPRINT_get_algo(mi);
+ if (!X509_ALGOR_set0(algor, obj, V_ASN1_NULL, NULL)) {
+ ASN1_OBJECT_free(obj);
+ ossl_raise(eTimestampError, "X509_ALGOR_set0");
+ }
+
+ return algo;
+}
+
+/*
+ * Returns the message imprint (digest) of the data to be timestamped.
+ *
+ * call-seq:
+ * request.message_imprint -> string or nil
+ */
+static VALUE
+ossl_ts_req_get_msg_imprint(VALUE self)
+{
+ TS_REQ *req;
+ TS_MSG_IMPRINT *mi;
+ ASN1_OCTET_STRING *hashed_msg;
+ VALUE ret;
+
+ GetTSRequest(self, req);
+ mi = TS_REQ_get_msg_imprint(req);
+ hashed_msg = TS_MSG_IMPRINT_get_msg(mi);
+
+ ret = rb_str_new((const char *)hashed_msg->data, hashed_msg->length);
+
+ return ret;
+}
+
+/*
+ * Set the message imprint digest.
+ *
+ * call-seq:
+ * request.message_imprint = "string" -> string
+ */
+static VALUE
+ossl_ts_req_set_msg_imprint(VALUE self, VALUE hash)
+{
+ TS_REQ *req;
+ TS_MSG_IMPRINT *mi;
+ StringValue(hash);
+
+ GetTSRequest(self, req);
+ mi = TS_REQ_get_msg_imprint(req);
+ if (!TS_MSG_IMPRINT_set_msg(mi, (unsigned char *)RSTRING_PTR(hash), RSTRING_LENINT(hash)))
+ ossl_raise(eTimestampError, "TS_MSG_IMPRINT_set_msg");
+
+ return hash;
+}
+
+/*
+ * Returns the version of this request. +1+ is the default value.
+ *
+ * call-seq:
+ * request.version -> Integer
+ */
+static VALUE
+ossl_ts_req_get_version(VALUE self)
+{
+ TS_REQ *req;
+
+ GetTSRequest(self, req);
+ return LONG2NUM(TS_REQ_get_version(req));
+}
+
+/*
+ * Sets the version number for this Request. This should be +1+ for compliant
+ * servers.
+ *
+ * call-seq:
+ * request.version = number -> Integer
+ */
+static VALUE
+ossl_ts_req_set_version(VALUE self, VALUE version)
+{
+ TS_REQ *req;
+ long ver;
+
+ if ((ver = NUM2LONG(version)) < 0)
+ ossl_raise(eTimestampError, "version must be >= 0!");
+ GetTSRequest(self, req);
+ if (!TS_REQ_set_version(req, ver))
+ ossl_raise(eTimestampError, "TS_REQ_set_version");
+
+ return version;
+}
+
+/*
+ * Returns the 'short name' of the object identifier that represents the
+ * timestamp policy under which the server shall create the timestamp.
+ *
+ * call-seq:
+ * request.policy_id -> string or nil
+ */
+static VALUE
+ossl_ts_req_get_policy_id(VALUE self)
+{
+ TS_REQ *req;
+
+ GetTSRequest(self, req);
+ if (!TS_REQ_get_policy_id(req))
+ return Qnil;
+ return get_asn1obj(TS_REQ_get_policy_id(req));
+}
+
+/*
+ * Allows to set the object identifier that represents the
+ * timestamp policy under which the server shall create the timestamp. This
+ * may be left +nil+, implying that the timestamp server will issue the
+ * timestamp using some default policy.
+ *
+ * ===Example:
+ * request.policy_id = "1.2.3.4.5"
+ *
+ * call-seq:
+ * request.policy_id = "string" -> string
+ */
+static VALUE
+ossl_ts_req_set_policy_id(VALUE self, VALUE oid)
+{
+ TS_REQ *req;
+ ASN1_OBJECT *obj;
+ int ok;
+
+ GetTSRequest(self, req);
+ obj = obj_to_asn1obj(oid);
+ ok = TS_REQ_set_policy_id(req, obj);
+ ASN1_OBJECT_free(obj);
+ if (!ok)
+ ossl_raise(eTimestampError, "TS_REQ_set_policy_id");
+
+ return oid;
+}
+
+/*
+ * Returns the nonce (number used once) that the server shall include in its
+ * response.
+ *
+ * call-seq:
+ * request.nonce -> BN or nil
+ */
+static VALUE
+ossl_ts_req_get_nonce(VALUE self)
+{
+ TS_REQ *req;
+ const ASN1_INTEGER * nonce;
+
+ GetTSRequest(self, req);
+ if (!(nonce = TS_REQ_get_nonce(req)))
+ return Qnil;
+ return asn1integer_to_num(nonce);
+}
+
+/*
+ * Sets the nonce (number used once) that the server shall include in its
+ * response. If the nonce is set, the server must return the same nonce value in
+ * a valid Response.
+ *
+ * call-seq:
+ * request.nonce = number -> BN
+ */
+static VALUE
+ossl_ts_req_set_nonce(VALUE self, VALUE num)
+{
+ TS_REQ *req;
+ ASN1_INTEGER *nonce;
+ int ok;
+
+ GetTSRequest(self, req);
+ nonce = num_to_asn1integer(num, NULL);
+ ok = TS_REQ_set_nonce(req, nonce);
+ ASN1_INTEGER_free(nonce);
+ if (!ok)
+ ossl_raise(eTimestampError, NULL);
+ return num;
+}
+
+/*
+ * Indicates whether the response shall contain the timestamp authority's
+ * certificate or not.
+ *
+ * call-seq:
+ * request.cert_requested? -> true or false
+ */
+static VALUE
+ossl_ts_req_get_cert_requested(VALUE self)
+{
+ TS_REQ *req;
+
+ GetTSRequest(self, req);
+ return TS_REQ_get_cert_req(req) ? Qtrue: Qfalse;
+}
+
+/*
+ * Specify whether the response shall contain the timestamp authority's
+ * certificate or not. The default value is +true+.
+ *
+ * call-seq:
+ * request.cert_requested = boolean -> true or false
+ */
+static VALUE
+ossl_ts_req_set_cert_requested(VALUE self, VALUE requested)
+{
+ TS_REQ *req;
+
+ GetTSRequest(self, req);
+ TS_REQ_set_cert_req(req, RTEST(requested));
+
+ return requested;
+}
+
+/*
+ * DER-encodes this Request.
+ *
+ * call-seq:
+ * request.to_der -> DER-encoded string
+ */
+static VALUE
+ossl_ts_req_to_der(VALUE self)
+{
+ TS_REQ *req;
+ TS_MSG_IMPRINT *mi;
+ X509_ALGOR *algo;
+ ASN1_OCTET_STRING *hashed_msg;
+
+ GetTSRequest(self, req);
+ mi = TS_REQ_get_msg_imprint(req);
+
+ algo = TS_MSG_IMPRINT_get_algo(mi);
+ if (OBJ_obj2nid(algo->algorithm) == NID_undef)
+ ossl_raise(eTimestampError, "Message imprint missing algorithm");
+
+ hashed_msg = TS_MSG_IMPRINT_get_msg(mi);
+ if (!hashed_msg->length)
+ ossl_raise(eTimestampError, "Message imprint missing hashed message");
+
+ return asn1_to_der((void *)req, (int (*)(void *, unsigned char **))i2d_TS_REQ);
+}
+
+static VALUE
+ossl_ts_resp_alloc(VALUE klass)
+{
+ TS_RESP *resp;
+ VALUE obj;
+
+ obj = NewTSResponse(klass);
+ if (!(resp = TS_RESP_new()))
+ ossl_raise(eTimestampError, NULL);
+ SetTSResponse(obj, resp);
+
+ return obj;
+}
+
+/*
+ * Creates a Response from a +File+ or +string+ parameter, the
+ * corresponding +File+ or +string+ must be DER-encoded. Please note
+ * that Response is an immutable read-only class. If you'd like to create
+ * timestamps please refer to Factory instead.
+ *
+ * call-seq:
+ * OpenSSL::Timestamp::Response.new(file) -> response
+ * OpenSSL::Timestamp::Response.new(string) -> response
+ */
+static VALUE
+ossl_ts_resp_initialize(VALUE self, VALUE der)
+{
+ TS_RESP *ts_resp = DATA_PTR(self);
+ BIO *in;
+
+ der = ossl_to_der_if_possible(der);
+ in = ossl_obj2bio(&der);
+ ts_resp = d2i_TS_RESP_bio(in, &ts_resp);
+ BIO_free(in);
+ if (!ts_resp) {
+ DATA_PTR(self) = NULL;
+ ossl_raise(eTimestampError, "Error when decoding the timestamp response");
+ }
+ DATA_PTR(self) = ts_resp;
+
+ return self;
+}
+
+/*
+ * Returns one of GRANTED, GRANTED_WITH_MODS, REJECTION, WAITING,
+ * REVOCATION_WARNING or REVOCATION_NOTIFICATION. A timestamp token has
+ * been created only in case +status+ is equal to GRANTED or GRANTED_WITH_MODS.
+ *
+ * call-seq:
+ * response.status -> BN (never nil)
+ */
+static VALUE
+ossl_ts_resp_get_status(VALUE self)
+{
+ TS_RESP *resp;
+ TS_STATUS_INFO *si;
+ const ASN1_INTEGER *st;
+
+ GetTSResponse(self, resp);
+ si = TS_RESP_get_status_info(resp);
+ st = TS_STATUS_INFO_get0_status(si);
+
+ return asn1integer_to_num(st);
+}
+
+/*
+ * In cases no timestamp token has been created, this field contains further
+ * info about the reason why response creation failed. The method returns either
+ * nil (the request was successful and a timestamp token was created) or one of
+ * the following:
+ * * :BAD_ALG - Indicates that the timestamp server rejects the message
+ * imprint algorithm used in the Request
+ * * :BAD_REQUEST - Indicates that the timestamp server was not able to process
+ * the Request properly
+ * * :BAD_DATA_FORMAT - Indicates that the timestamp server was not able to
+ * parse certain data in the Request
+ * * :TIME_NOT_AVAILABLE - Indicates that the server could not access its time
+ * source
+ * * :UNACCEPTED_POLICY - Indicates that the requested policy identifier is not
+ * recognized or supported by the timestamp server
+ * * :UNACCEPTED_EXTENSIION - Indicates that an extension in the Request is
+ * not supported by the timestamp server
+ * * :ADD_INFO_NOT_AVAILABLE -Indicates that additional information requested
+ * is either not understood or currently not available
+ * * :SYSTEM_FAILURE - Timestamp creation failed due to an internal error that
+ * occurred on the timestamp server
+ *
+ * call-seq:
+ * response.failure_info -> nil or symbol
+ */
+static VALUE
+ossl_ts_resp_get_failure_info(VALUE self)
+{
+ TS_RESP *resp;
+ TS_STATUS_INFO *si;
+
+ /* The ASN1_BIT_STRING_get_bit changed from 1.0.0. to 1.1.0, making this
+ * const. */
+ #if defined(HAVE_TS_STATUS_INFO_GET0_FAILURE_INFO)
+ const ASN1_BIT_STRING *fi;
+ #else
+ ASN1_BIT_STRING *fi;
+ #endif
+
+ GetTSResponse(self, resp);
+ si = TS_RESP_get_status_info(resp);
+ fi = TS_STATUS_INFO_get0_failure_info(si);
+ if (!fi)
+ return Qnil;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_ALG))
+ return sBAD_ALG;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_REQUEST))
+ return sBAD_REQUEST;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_DATA_FORMAT))
+ return sBAD_DATA_FORMAT;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_TIME_NOT_AVAILABLE))
+ return sTIME_NOT_AVAILABLE;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_UNACCEPTED_POLICY))
+ return sUNACCEPTED_POLICY;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_UNACCEPTED_EXTENSION))
+ return sUNACCEPTED_EXTENSION;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_ADD_INFO_NOT_AVAILABLE))
+ return sADD_INFO_NOT_AVAILABLE;
+ if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_SYSTEM_FAILURE))
+ return sSYSTEM_FAILURE;
+
+ ossl_raise(eTimestampError, "Unrecognized failure info.");
+}
+
+/*
+ * In cases of failure this field may contain an array of strings further
+ * describing the origin of the failure.
+ *
+ * call-seq:
+ * response.status_text -> Array of strings or nil
+ */
+static VALUE
+ossl_ts_resp_get_status_text(VALUE self)
+{
+ TS_RESP *resp;
+ TS_STATUS_INFO *si;
+ const STACK_OF(ASN1_UTF8STRING) *text;
+ ASN1_UTF8STRING *current;
+ int i;
+ VALUE ret = rb_ary_new();
+
+ GetTSResponse(self, resp);
+ si = TS_RESP_get_status_info(resp);
+ if ((text = TS_STATUS_INFO_get0_text(si))) {
+ for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) {
+ current = sk_ASN1_UTF8STRING_value(text, i);
+ rb_ary_push(ret, asn1str_to_str(current));
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * If a timestamp token is present, this returns it in the form of a
+ * OpenSSL::PKCS7.
+ *
+ * call-seq:
+ * response.token -> nil or OpenSSL::PKCS7
+ */
+static VALUE
+ossl_ts_resp_get_token(VALUE self)
+{
+ TS_RESP *resp;
+ PKCS7 *p7, *copy;
+ VALUE obj;
+
+ GetTSResponse(self, resp);
+ if (!(p7 = TS_RESP_get_token(resp)))
+ return Qnil;
+
+ obj = NewPKCS7(cPKCS7);
+
+ if (!(copy = PKCS7_dup(p7)))
+ ossl_raise(eTimestampError, NULL);
+
+ SetPKCS7(obj, copy);
+
+ return obj;
+}
+
+/*
+ * Get the response's token info if present.
+ *
+ * call-seq:
+ * response.token_info -> nil or OpenSSL::Timestamp::TokenInfo
+ */
+static VALUE
+ossl_ts_resp_get_token_info(VALUE self)
+{
+ TS_RESP *resp;
+ TS_TST_INFO *info, *copy;
+ VALUE obj;
+
+ GetTSResponse(self, resp);
+ if (!(info = TS_RESP_get_tst_info(resp)))
+ return Qnil;
+
+ obj = NewTSTokenInfo(cTimestampTokenInfo);
+
+ if (!(copy = TS_TST_INFO_dup(info)))
+ ossl_raise(eTimestampError, NULL);
+
+ SetTSTokenInfo(obj, copy);
+
+ return obj;
+}
+
+/*
+ * If the Request specified to request the TSA certificate
+ * (Request#cert_requested = true), then this field contains the
+ * certificate of the timestamp authority.
+ *
+ * call-seq:
+ * response.tsa_certificate -> OpenSSL::X509::Certificate or nil
+ */
+static VALUE
+ossl_ts_resp_get_tsa_certificate(VALUE self)
+{
+ TS_RESP *resp;
+ PKCS7 *p7;
+ PKCS7_SIGNER_INFO *ts_info;
+ X509 *cert;
+
+ GetTSResponse(self, resp);
+ if (!(p7 = TS_RESP_get_token(resp)))
+ return Qnil;
+ ts_info = sk_PKCS7_SIGNER_INFO_value(p7->d.sign->signer_info, 0);
+ cert = PKCS7_cert_from_signer_info(p7, ts_info);
+ if (!cert)
+ return Qnil;
+ return ossl_x509_new(cert);
+}
+
+/*
+ * Returns the Response in DER-encoded form.
+ *
+ * call-seq:
+ * response.to_der -> string
+ */
+static VALUE
+ossl_ts_resp_to_der(VALUE self)
+{
+ TS_RESP *resp;
+
+ GetTSResponse(self, resp);
+ return asn1_to_der((void *)resp, (int (*)(void *, unsigned char **))i2d_TS_RESP);
+}
+
+/*
+ * Verifies a timestamp token by checking the signature, validating the
+ * certificate chain implied by tsa_certificate and by checking conformance to
+ * a given Request. Mandatory parameters are the Request associated to this
+ * Response, and an OpenSSL::X509::Store of trusted roots.
+ *
+ * Intermediate certificates can optionally be supplied for creating the
+ * certificate chain. These intermediate certificates must all be
+ * instances of OpenSSL::X509::Certificate.
+ *
+ * If validation fails, several kinds of exceptions can be raised:
+ * * TypeError if types don't fit
+ * * TimestampError if something is wrong with the timestamp token itself, if
+ * it is not conformant to the Request, or if validation of the timestamp
+ * certificate chain fails.
+ *
+ * call-seq:
+ * response.verify(Request, root_store) -> Response
+ * response.verify(Request, root_store, [intermediate_cert]) -> Response
+ */
+static VALUE
+ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self)
+{
+ VALUE ts_req, store, intermediates;
+ TS_RESP *resp;
+ TS_REQ *req;
+ X509_STORE *x509st;
+ TS_VERIFY_CTX *ctx;
+ STACK_OF(X509) *x509inter = NULL;
+ PKCS7* p7;
+ X509 *cert;
+ int status, i, ok;
+
+ rb_scan_args(argc, argv, "21", &ts_req, &store, &intermediates);
+
+ GetTSResponse(self, resp);
+ GetTSRequest(ts_req, req);
+ x509st = GetX509StorePtr(store);
+
+ if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL))) {
+ ossl_raise(eTimestampError, "Error when creating the verification context.");
+ }
+
+ if (!NIL_P(intermediates)) {
+ x509inter = ossl_protect_x509_ary2sk(intermediates, &status);
+ if (status) {
+ TS_VERIFY_CTX_free(ctx);
+ rb_jump_tag(status);
+ }
+ } else if (!(x509inter = sk_X509_new_null())) {
+ TS_VERIFY_CTX_free(ctx);
+ ossl_raise(eTimestampError, "sk_X509_new_null");
+ }
+
+ if (!(p7 = TS_RESP_get_token(resp))) {
+ TS_VERIFY_CTX_free(ctx);
+ sk_X509_pop_free(x509inter, X509_free);
+ ossl_raise(eTimestampError, "TS_RESP_get_token");
+ }
+ for (i=0; i < sk_X509_num(p7->d.sign->cert); i++) {
+ cert = sk_X509_value(p7->d.sign->cert, i);
+ if (!sk_X509_push(x509inter, cert)) {
+ sk_X509_pop_free(x509inter, X509_free);
+ TS_VERIFY_CTX_free(ctx);
+ ossl_raise(eTimestampError, "sk_X509_push");
+ }
+ X509_up_ref(cert);
+ }
+
+ TS_VERIFY_CTS_set_certs(ctx, x509inter);
+ TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE);
+ TS_VERIFY_CTX_set_store(ctx, x509st);
+
+ ok = TS_RESP_verify_response(ctx, resp);
+
+ /* WORKAROUND:
+ * X509_STORE can count references, but X509_STORE_free() doesn't check
+ * this. To prevent our X509_STORE from being freed with our
+ * TS_VERIFY_CTX we set the store to NULL first.
+ * Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2)
+ */
+ TS_VERIFY_CTX_set_store(ctx, NULL);
+ TS_VERIFY_CTX_free(ctx);
+
+ if (!ok)
+ ossl_raise(eTimestampError, "TS_RESP_verify_response");
+
+ return self;
+}
+
+static VALUE
+ossl_ts_token_info_alloc(VALUE klass)
+{
+ TS_TST_INFO *info;
+ VALUE obj;
+
+ obj = NewTSTokenInfo(klass);
+ if (!(info = TS_TST_INFO_new()))
+ ossl_raise(eTimestampError, NULL);
+ SetTSTokenInfo(obj, info);
+
+ return obj;
+}
+
+/*
+ * Creates a TokenInfo from a +File+ or +string+ parameter, the
+ * corresponding +File+ or +string+ must be DER-encoded. Please note
+ * that TokenInfo is an immutable read-only class. If you'd like to create
+ * timestamps please refer to Factory instead.
+ *
+ * call-seq:
+ * OpenSSL::Timestamp::TokenInfo.new(file) -> token-info
+ * OpenSSL::Timestamp::TokenInfo.new(string) -> token-info
+ */
+static VALUE
+ossl_ts_token_info_initialize(VALUE self, VALUE der)
+{
+ TS_TST_INFO *info = DATA_PTR(self);
+ BIO *in;
+
+ der = ossl_to_der_if_possible(der);
+ in = ossl_obj2bio(&der);
+ info = d2i_TS_TST_INFO_bio(in, &info);
+ BIO_free(in);
+ if (!info) {
+ DATA_PTR(self) = NULL;
+ ossl_raise(eTimestampError, "Error when decoding the timestamp token info");
+ }
+ DATA_PTR(self) = info;
+
+ return self;
+}
+
+/*
+ * Returns the version number of the token info. With compliant servers,
+ * this value should be +1+ if present. If status is GRANTED or
+ * GRANTED_WITH_MODS.
+ *
+ * call-seq:
+ * token_info.version -> Integer or nil
+ */
+static VALUE
+ossl_ts_token_info_get_version(VALUE self)
+{
+ TS_TST_INFO *info;
+
+ GetTSTokenInfo(self, info);
+ return LONG2NUM(TS_TST_INFO_get_version(info));
+}
+
+/*
+ * Returns the timestamp policy object identifier of the policy this timestamp
+ * was created under. If status is GRANTED or GRANTED_WITH_MODS, this is never
+ * +nil+.
+ *
+ * ===Example:
+ * id = token_info.policy_id
+ * puts id -> "1.2.3.4.5"
+ *
+ * call-seq:
+ * token_info.policy_id -> string or nil
+ */
+static VALUE
+ossl_ts_token_info_get_policy_id(VALUE self)
+{
+ TS_TST_INFO *info;
+
+ GetTSTokenInfo(self, info);
+ return get_asn1obj(TS_TST_INFO_get_policy_id(info));
+}
+
+/*
+ * Returns the 'short name' of the object identifier representing the algorithm
+ * that was used to derive the message imprint digest. For valid timestamps,
+ * this is the same value that was already given in the Request. If status is
+ * GRANTED or GRANTED_WITH_MODS, this is never +nil+.
+ *
+ * ===Example:
+ * algo = token_info.algorithm
+ * puts algo -> "SHA1"
+ *
+ * call-seq:
+ * token_info.algorithm -> string or nil
+ */
+static VALUE
+ossl_ts_token_info_get_algorithm(VALUE self)
+{
+ TS_TST_INFO *info;
+ TS_MSG_IMPRINT *mi;
+ X509_ALGOR *algo;
+
+ GetTSTokenInfo(self, info);
+ mi = TS_TST_INFO_get_msg_imprint(info);
+ algo = TS_MSG_IMPRINT_get_algo(mi);
+ return get_asn1obj(algo->algorithm);
+}
+
+/*
+ * Returns the message imprint digest. For valid timestamps,
+ * this is the same value that was already given in the Request.
+ * If status is GRANTED or GRANTED_WITH_MODS, this is never +nil+.
+ *
+ * ===Example:
+ * mi = token_info.msg_imprint
+ * puts mi -> "DEADBEEF"
+ *
+ * call-seq:
+ * token_info.msg_imprint -> string.
+ */
+static VALUE
+ossl_ts_token_info_get_msg_imprint(VALUE self)
+{
+ TS_TST_INFO *info;
+ TS_MSG_IMPRINT *mi;
+ ASN1_OCTET_STRING *hashed_msg;
+ VALUE ret;
+
+ GetTSTokenInfo(self, info);
+ mi = TS_TST_INFO_get_msg_imprint(info);
+ hashed_msg = TS_MSG_IMPRINT_get_msg(mi);
+ ret = rb_str_new((const char *)hashed_msg->data, hashed_msg->length);
+
+ return ret;
+}
+
+/*
+ * Returns serial number of the timestamp token. This value shall never be the
+ * same for two timestamp tokens issued by a dedicated timestamp authority.
+ * If status is GRANTED or GRANTED_WITH_MODS, this is never +nil+.
+ *
+ * call-seq:
+ * token_info.serial_number -> BN or nil
+ */
+static VALUE
+ossl_ts_token_info_get_serial_number(VALUE self)
+{
+ TS_TST_INFO *info;
+
+ GetTSTokenInfo(self, info);
+ return asn1integer_to_num(TS_TST_INFO_get_serial(info));
+}
+
+/*
+ * Returns time when this timestamp token was created. If status is GRANTED or
+ * GRANTED_WITH_MODS, this is never +nil+.
+ *
+ * call-seq:
+ * token_info.gen_time -> Time
+ */
+static VALUE
+ossl_ts_token_info_get_gen_time(VALUE self)
+{
+ TS_TST_INFO *info;
+
+ GetTSTokenInfo(self, info);
+ return asn1time_to_time(TS_TST_INFO_get_time(info));
+}
+
+/*
+ * If the ordering field is missing, or if the ordering field is present
+ * and set to false, then the genTime field only indicates the time at
+ * which the time-stamp token has been created by the TSA. In such a
+ * case, the ordering of time-stamp tokens issued by the same TSA or
+ * different TSAs is only possible when the difference between the
+ * genTime of the first time-stamp token and the genTime of the second
+ * time-stamp token is greater than the sum of the accuracies of the
+ * genTime for each time-stamp token.
+ *
+ * If the ordering field is present and set to true, every time-stamp
+ * token from the same TSA can always be ordered based on the genTime
+ * field, regardless of the genTime accuracy.
+ *
+ * call-seq:
+ * token_info.ordering -> true, falses or nil
+ */
+static VALUE
+ossl_ts_token_info_get_ordering(VALUE self)
+{
+ TS_TST_INFO *info;
+
+ GetTSTokenInfo(self, info);
+ return TS_TST_INFO_get_ordering(info) ? Qtrue : Qfalse;
+}
+
+/*
+ * If the timestamp token is valid then this field contains the same nonce that
+ * was passed to the timestamp server in the initial Request.
+ *
+ * call-seq:
+ * token_info.nonce -> BN or nil
+ */
+static VALUE
+ossl_ts_token_info_get_nonce(VALUE self)
+{
+ TS_TST_INFO *info;
+ const ASN1_INTEGER *nonce;
+
+ GetTSTokenInfo(self, info);
+ if (!(nonce = TS_TST_INFO_get_nonce(info)))
+ return Qnil;
+
+ return asn1integer_to_num(nonce);
+}
+
+/*
+ * Returns the TokenInfo in DER-encoded form.
+ *
+ * call-seq:
+ * token_info.to_der -> string
+ */
+static VALUE
+ossl_ts_token_info_to_der(VALUE self)
+{
+ TS_TST_INFO *info;
+
+ GetTSTokenInfo(self, info);
+ return asn1_to_der((void *)info, (int (*)(void *, unsigned char **))i2d_TS_TST_INFO);
+}
+
+static ASN1_INTEGER *
+ossl_tsfac_serial_cb(struct TS_resp_ctx *ctx, void *data)
+{
+ ASN1_INTEGER **snptr = (ASN1_INTEGER **)data;
+ ASN1_INTEGER *sn = *snptr;
+ *snptr = NULL;
+ return sn;
+}
+
+static int
+#if !defined(LIBRESSL_VERSION_NUMBER)
+ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, long *sec, long *usec)
+#else
+ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec)
+#endif
+{
+ *sec = *((long *)data);
+ *usec = 0;
+ return 1;
+}
+
+/*
+ * Creates a Response with the help of an OpenSSL::PKey, an
+ * OpenSSL::X509::Certificate and a Request.
+ *
+ * Mandatory parameters for timestamp creation that need to be set in the
+ * Request:
+ *
+ * * Request#algorithm
+ * * Request#message_imprint
+ *
+ * Mandatory parameters that need to be set in the Factory:
+ * * Factory#serial_number
+ * * Factory#gen_time
+ * * Factory#allowed_digests
+ *
+ * In addition one of either Request#policy_id or Factory#default_policy_id
+ * must be set.
+ *
+ * Raises a TimestampError if creation fails, though successfully created error
+ * responses may be returned.
+ *
+ * call-seq:
+ * factory.create_timestamp(key, certificate, request) -> Response
+ */
+static VALUE
+ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request)
+{
+ VALUE serial_number, def_policy_id, gen_time, additional_certs, allowed_digests;
+ VALUE str;
+ STACK_OF(X509) *inter_certs;
+ VALUE tsresp, ret = Qnil;
+ EVP_PKEY *sign_key;
+ X509 *tsa_cert;
+ TS_REQ *req;
+ TS_RESP *response = NULL;
+ TS_RESP_CTX *ctx = NULL;
+ BIO *req_bio;
+ ASN1_INTEGER *asn1_serial = NULL;
+ ASN1_OBJECT *def_policy_id_obj = NULL;
+ long lgen_time;
+ const char * err_msg = NULL;
+ int status = 0;
+
+ tsresp = NewTSResponse(cTimestampResponse);
+ tsa_cert = GetX509CertPtr(certificate);
+ sign_key = GetPrivPKeyPtr(key);
+ GetTSRequest(request, req);
+
+ gen_time = ossl_tsfac_get_gen_time(self);
+ if (!rb_obj_is_instance_of(gen_time, rb_cTime)) {
+ err_msg = "@gen_time must be a Time.";
+ goto end;
+ }
+ lgen_time = NUM2LONG(rb_funcall(gen_time, rb_intern("to_i"), 0));
+
+ serial_number = ossl_tsfac_get_serial_number(self);
+ if (NIL_P(serial_number)) {
+ err_msg = "@serial_number must be set.";
+ goto end;
+ }
+ asn1_serial = num_to_asn1integer(serial_number, NULL);
+
+ def_policy_id = ossl_tsfac_get_default_policy_id(self);
+ if (NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) {
+ err_msg = "No policy id in the request and no default policy set";
+ goto end;
+ }
+ if (!NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) {
+ def_policy_id_obj = (ASN1_OBJECT*)rb_protect((VALUE (*)(VALUE))obj_to_asn1obj, (VALUE)def_policy_id, &status);
+ if (status)
+ goto end;
+ }
+
+ if (!(ctx = TS_RESP_CTX_new())) {
+ err_msg = "Memory allocation failed.";
+ goto end;
+ }
+
+ TS_RESP_CTX_set_serial_cb(ctx, ossl_tsfac_serial_cb, &asn1_serial);
+ if (!TS_RESP_CTX_set_signer_cert(ctx, tsa_cert)) {
+ err_msg = "Certificate does not contain the timestamping extension";
+ goto end;
+ }
+
+ additional_certs = ossl_tsfac_get_additional_certs(self);
+ if (rb_obj_is_kind_of(additional_certs, rb_cArray)) {
+ inter_certs = ossl_protect_x509_ary2sk(additional_certs, &status);
+ if (status)
+ goto end;
+
+ /* this dups the sk_X509 and ups each cert's ref count */
+ TS_RESP_CTX_set_certs(ctx, inter_certs);
+ sk_X509_pop_free(inter_certs, X509_free);
+ }
+
+ TS_RESP_CTX_set_signer_key(ctx, sign_key);
+ if (!NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req))
+ TS_RESP_CTX_set_def_policy(ctx, def_policy_id_obj);
+ if (TS_REQ_get_policy_id(req))
+ TS_RESP_CTX_set_def_policy(ctx, TS_REQ_get_policy_id(req));
+ TS_RESP_CTX_set_time_cb(ctx, ossl_tsfac_time_cb, &lgen_time);
+
+ allowed_digests = ossl_tsfac_get_allowed_digests(self);
+ if (rb_obj_is_kind_of(allowed_digests, rb_cArray)) {
+ int i;
+ VALUE rbmd;
+ const EVP_MD *md;
+
+ for (i = 0; i < RARRAY_LEN(allowed_digests); i++) {
+ rbmd = rb_ary_entry(allowed_digests, i);
+ md = (const EVP_MD *)rb_protect((VALUE (*)(VALUE))ossl_evp_get_digestbyname, rbmd, &status);
+ if (status)
+ goto end;
+ TS_RESP_CTX_add_md(ctx, md);
+ }
+ }
+
+ str = rb_protect(ossl_to_der, request, &status);
+ if (status)
+ goto end;
+
+ req_bio = (BIO*)rb_protect((VALUE (*)(VALUE))ossl_obj2bio, (VALUE)&str, &status);
+ if (status)
+ goto end;
+
+ response = TS_RESP_create_response(ctx, req_bio);
+ BIO_free(req_bio);
+
+ if (!response) {
+ err_msg = "Error during response generation";
+ goto end;
+ }
+
+ /* bad responses aren't exceptional, but openssl still sets error
+ * information. */
+ ossl_clear_error();
+
+ SetTSResponse(tsresp, response);
+ ret = tsresp;
+
+end:
+ ASN1_INTEGER_free(asn1_serial);
+ ASN1_OBJECT_free(def_policy_id_obj);
+ TS_RESP_CTX_free(ctx);
+ if (err_msg)
+ ossl_raise(eTimestampError, err_msg);
+ if (status)
+ rb_jump_tag(status);
+ return ret;
+}
+
+/*
+ * INIT
+ */
+void
+Init_ossl_ts(void)
+{
+ #if 0
+ mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
+ #endif
+
+ /*
+ * Possible return value for +Response#failure_info+. Indicates that the
+ * timestamp server rejects the message imprint algorithm used in the
+ * +Request+
+ */
+ sBAD_ALG = ID2SYM(rb_intern_const("BAD_ALG"));
+
+ /*
+ * Possible return value for +Response#failure_info+. Indicates that the
+ * timestamp server was not able to process the +Request+ properly.
+ */
+ sBAD_REQUEST = ID2SYM(rb_intern_const("BAD_REQUEST"));
+ /*
+ * Possible return value for +Response#failure_info+. Indicates that the
+ * timestamp server was not able to parse certain data in the +Request+.
+ */
+ sBAD_DATA_FORMAT = ID2SYM(rb_intern_const("BAD_DATA_FORMAT"));
+
+ sTIME_NOT_AVAILABLE = ID2SYM(rb_intern_const("TIME_NOT_AVAILABLE"));
+ sUNACCEPTED_POLICY = ID2SYM(rb_intern_const("UNACCEPTED_POLICY"));
+ sUNACCEPTED_EXTENSION = ID2SYM(rb_intern_const("UNACCEPTED_EXTENSION"));
+ sADD_INFO_NOT_AVAILABLE = ID2SYM(rb_intern_const("ADD_INFO_NOT_AVAILABLE"));
+ sSYSTEM_FAILURE = ID2SYM(rb_intern_const("SYSTEM_FAILURE"));
+
+ /* Document-class: OpenSSL::Timestamp
+ * Provides classes and methods to request, create and validate
+ * {RFC3161-compliant}[http://www.ietf.org/rfc/rfc3161.txt] timestamps.
+ * Request may be used to either create requests from scratch or to parse
+ * existing requests that again can be used to request timestamps from a
+ * timestamp server, e.g. via the net/http. The resulting timestamp
+ * response may be parsed using Response.
+ *
+ * Please note that Response is read-only and immutable. To create a
+ * Response, an instance of Factory as well as a valid Request are needed.
+ *
+ * ===Create a Response:
+ * #Assumes ts.p12 is a PKCS#12-compatible file with a private key
+ * #and a certificate that has an extended key usage of 'timeStamping'
+ * p12 = OpenSSL::PKCS12.new(File.open('ts.p12', 'rb'), 'pwd')
+ * md = OpenSSL::Digest.new('SHA1')
+ * hash = md.digest(data) #some binary data to be timestamped
+ * req = OpenSSL::Timestamp::Request.new
+ * req.algorithm = 'SHA1'
+ * req.message_imprint = hash
+ * req.policy_id = "1.2.3.4.5"
+ * req.nonce = 42
+ * fac = OpenSSL::Timestamp::Factory.new
+ * fac.gen_time = Time.now
+ * fac.serial_number = 1
+ * timestamp = fac.create_timestamp(p12.key, p12.certificate, req)
+ *
+ * ===Verify a timestamp response:
+ * #Assume we have a timestamp token in a file called ts.der
+ * ts = OpenSSL::Timestamp::Response.new(File.open('ts.der', 'rb')
+ * #Assume we have the Request for this token in a file called req.der
+ * req = OpenSSL::Timestamp::Request.new(File.open('req.der', 'rb')
+ * # Assume the associated root CA certificate is contained in a
+ * # DER-encoded file named root.cer
+ * root = OpenSSL::X509::Certificate.new(File.open('root.cer', 'rb')
+ * # get the necessary intermediate certificates, available in
+ * # DER-encoded form in inter1.cer and inter2.cer
+ * inter1 = OpenSSL::X509::Certificate.new(File.open('inter1.cer', 'rb')
+ * inter2 = OpenSSL::X509::Certificate.new(File.open('inter2.cer', 'rb')
+ * ts.verify(req, root, inter1, inter2) -> ts or raises an exception if validation fails
+ *
+ */
+ mTimestamp = rb_define_module_under(mOSSL, "Timestamp");
+
+ /* Document-class: OpenSSL::Timestamp::TimestampError
+ * Generic exception class of the Timestamp module.
+ */
+ eTimestampError = rb_define_class_under(mTimestamp, "TimestampError", eOSSLError);
+
+ /* Document-class: OpenSSL::Timestamp::Response
+ * Immutable and read-only representation of a timestamp response returned
+ * from a timestamp server after receiving an associated Request. Allows
+ * access to specific information about the response but also allows to
+ * verify the Response.
+ */
+ cTimestampResponse = rb_define_class_under(mTimestamp, "Response", rb_cObject);
+ rb_define_alloc_func(cTimestampResponse, ossl_ts_resp_alloc);
+ rb_define_method(cTimestampResponse, "initialize", ossl_ts_resp_initialize, 1);
+ rb_define_method(cTimestampResponse, "status", ossl_ts_resp_get_status, 0);
+ rb_define_method(cTimestampResponse, "failure_info", ossl_ts_resp_get_failure_info, 0);
+ rb_define_method(cTimestampResponse, "status_text", ossl_ts_resp_get_status_text, 0);
+ rb_define_method(cTimestampResponse, "token", ossl_ts_resp_get_token, 0);
+ rb_define_method(cTimestampResponse, "token_info", ossl_ts_resp_get_token_info, 0);
+ rb_define_method(cTimestampResponse, "tsa_certificate", ossl_ts_resp_get_tsa_certificate, 0);
+ rb_define_method(cTimestampResponse, "to_der", ossl_ts_resp_to_der, 0);
+ rb_define_method(cTimestampResponse, "verify", ossl_ts_resp_verify, -1);
+
+ /* Document-class: OpenSSL::Timestamp::TokenInfo
+ * Immutable and read-only representation of a timestamp token info from a
+ * Response.
+ */
+ cTimestampTokenInfo = rb_define_class_under(mTimestamp, "TokenInfo", rb_cObject);
+ rb_define_alloc_func(cTimestampTokenInfo, ossl_ts_token_info_alloc);
+ rb_define_method(cTimestampTokenInfo, "initialize", ossl_ts_token_info_initialize, 1);
+ rb_define_method(cTimestampTokenInfo, "version", ossl_ts_token_info_get_version, 0);
+ rb_define_method(cTimestampTokenInfo, "policy_id", ossl_ts_token_info_get_policy_id, 0);
+ rb_define_method(cTimestampTokenInfo, "algorithm", ossl_ts_token_info_get_algorithm, 0);
+ rb_define_method(cTimestampTokenInfo, "message_imprint", ossl_ts_token_info_get_msg_imprint, 0);
+ rb_define_method(cTimestampTokenInfo, "serial_number", ossl_ts_token_info_get_serial_number, 0);
+ rb_define_method(cTimestampTokenInfo, "gen_time", ossl_ts_token_info_get_gen_time, 0);
+ rb_define_method(cTimestampTokenInfo, "ordering", ossl_ts_token_info_get_ordering, 0);
+ rb_define_method(cTimestampTokenInfo, "nonce", ossl_ts_token_info_get_nonce, 0);
+ rb_define_method(cTimestampTokenInfo, "to_der", ossl_ts_token_info_to_der, 0);
+
+ /* Document-class: OpenSSL::Timestamp::Request
+ * Allows to create timestamp requests or parse existing ones. A Request is
+ * also needed for creating timestamps from scratch with Factory. When
+ * created from scratch, some default values are set:
+ * * version is set to +1+
+ * * cert_requested is set to +true+
+ * * algorithm, message_imprint, policy_id, and nonce are set to +false+
+ */
+ cTimestampRequest = rb_define_class_under(mTimestamp, "Request", rb_cObject);
+ rb_define_alloc_func(cTimestampRequest, ossl_ts_req_alloc);
+ rb_define_method(cTimestampRequest, "initialize", ossl_ts_req_initialize, -1);
+ rb_define_method(cTimestampRequest, "version=", ossl_ts_req_set_version, 1);
+ rb_define_method(cTimestampRequest, "version", ossl_ts_req_get_version, 0);
+ rb_define_method(cTimestampRequest, "algorithm=", ossl_ts_req_set_algorithm, 1);
+ rb_define_method(cTimestampRequest, "algorithm", ossl_ts_req_get_algorithm, 0);
+ rb_define_method(cTimestampRequest, "message_imprint=", ossl_ts_req_set_msg_imprint, 1);
+ rb_define_method(cTimestampRequest, "message_imprint", ossl_ts_req_get_msg_imprint, 0);
+ rb_define_method(cTimestampRequest, "policy_id=", ossl_ts_req_set_policy_id, 1);
+ rb_define_method(cTimestampRequest, "policy_id", ossl_ts_req_get_policy_id, 0);
+ rb_define_method(cTimestampRequest, "nonce=", ossl_ts_req_set_nonce, 1);
+ rb_define_method(cTimestampRequest, "nonce", ossl_ts_req_get_nonce, 0);
+ rb_define_method(cTimestampRequest, "cert_requested=", ossl_ts_req_set_cert_requested, 1);
+ rb_define_method(cTimestampRequest, "cert_requested?", ossl_ts_req_get_cert_requested, 0);
+ rb_define_method(cTimestampRequest, "to_der", ossl_ts_req_to_der, 0);
+
+ /*
+ * Indicates a successful response. Equal to +0+.
+ */
+ rb_define_const(cTimestampResponse, "GRANTED", INT2NUM(TS_STATUS_GRANTED));
+ /*
+ * Indicates a successful response that probably contains modifications
+ * from the initial request. Equal to +1+.
+ */
+ rb_define_const(cTimestampResponse, "GRANTED_WITH_MODS", INT2NUM(TS_STATUS_GRANTED_WITH_MODS));
+ /*
+ * Indicates a failure. No timestamp token was created. Equal to +2+.
+ */
+ rb_define_const(cTimestampResponse, "REJECTION", INT2NUM(TS_STATUS_REJECTION));
+ /*
+ * Indicates a failure. No timestamp token was created. Equal to +3+.
+ */
+ rb_define_const(cTimestampResponse, "WAITING", INT2NUM(TS_STATUS_WAITING));
+ /*
+ * Indicates a failure. No timestamp token was created. Revocation of a
+ * certificate is imminent. Equal to +4+.
+ */
+ rb_define_const(cTimestampResponse, "REVOCATION_WARNING", INT2NUM(TS_STATUS_REVOCATION_WARNING));
+ /*
+ * Indicates a failure. No timestamp token was created. A certificate
+ * has been revoked. Equal to +5+.
+ */
+ rb_define_const(cTimestampResponse, "REVOCATION_NOTIFICATION", INT2NUM(TS_STATUS_REVOCATION_NOTIFICATION));
+
+ /* Document-class: OpenSSL::Timestamp::Factory
+ *
+ * Used to generate a Response from scratch.
+ *
+ * Please bear in mind that the implementation will always apply and prefer
+ * the policy object identifier given in the request over the default policy
+ * id specified in the Factory. As a consequence, +default_policy_id+ will
+ * only be applied if no Request#policy_id was given. But this also means
+ * that one needs to check the policy identifier in the request manually
+ * before creating the Response, e.g. to check whether it complies to a
+ * specific set of acceptable policies.
+ *
+ * There exists also the possibility to add certificates (instances of
+ * OpenSSL::X509::Certificate) besides the timestamping certificate
+ * that will be included in the resulting timestamp token if
+ * Request#cert_requested? is +true+. Ideally, one would also include any
+ * intermediate certificates (the root certificate can be left out - in
+ * order to trust it any verifying party will have to be in its possession
+ * anyway). This simplifies validation of the timestamp since these
+ * intermediate certificates are "already there" and need not be passed as
+ * external parameters to Response#verify anymore, thus minimizing external
+ * resources needed for verification.
+ *
+ * ===Example: Inclusion of (untrusted) intermediate certificates
+ *
+ * Assume we received a timestamp request that has set Request#policy_id to
+ * +nil+ and Request#cert_requested? to true. The raw request bytes are
+ * stored in a variable called +req_raw+. We'd still like to integrate
+ * the necessary intermediate certificates (in +inter1.cer+ and
+ * +inter2.cer+) to simplify validation of the resulting Response. +ts.p12+
+ * is a PKCS#12-compatible file including the private key and the
+ * timestamping certificate.
+ *
+ * req = OpenSSL::Timestamp::Request.new(raw_bytes)
+ * p12 = OpenSSL::PKCS12.new(File.open('ts.p12', 'rb'), 'pwd')
+ * inter1 = OpenSSL::X509::Certificate.new(File.open('inter1.cer', 'rb')
+ * inter2 = OpenSSL::X509::Certificate.new(File.open('inter2.cer', 'rb')
+ * fac = OpenSSL::Timestamp::Factory.new
+ * fac.gen_time = Time.now
+ * fac.serial_number = 1
+ * fac.allowed_digests = ["sha256", "sha384", "sha512"]
+ * #needed because the Request contained no policy identifier
+ * fac.default_policy_id = '1.2.3.4.5'
+ * fac.additional_certificates = [ inter1, inter2 ]
+ * timestamp = fac.create_timestamp(p12.key, p12.certificate, req)
+ *
+ * ==Attributes
+ *
+ * ===default_policy_id
+ *
+ * Request#policy_id will always be preferred over this if present in the
+ * Request, only if Request#policy_id is nil default_policy will be used.
+ * If none of both is present, a TimestampError will be raised when trying
+ * to create a Response.
+ *
+ * call-seq:
+ * factory.default_policy_id = "string" -> string
+ * factory.default_policy_id -> string or nil
+ *
+ * ===serial_number
+ *
+ * Sets or retrieves the serial number to be used for timestamp creation.
+ * Must be present for timestamp creation.
+ *
+ * call-seq:
+ * factory.serial_number = number -> number
+ * factory.serial_number -> number or nil
+ *
+ * ===gen_time
+ *
+ * Sets or retrieves the Time value to be used in the Response. Must be
+ * present for timestamp creation.
+ *
+ * call-seq:
+ * factory.gen_time = Time -> Time
+ * factory.gen_time -> Time or nil
+ *
+ * ===additional_certs
+ *
+ * Sets or retrieves additional certificates apart from the timestamp
+ * certificate (e.g. intermediate certificates) to be added to the Response.
+ * Must be an Array of OpenSSL::X509::Certificate.
+ *
+ * call-seq:
+ * factory.additional_certs = [cert1, cert2] -> [ cert1, cert2 ]
+ * factory.additional_certs -> array or nil
+ *
+ * ===allowed_digests
+ *
+ * Sets or retrieves the digest algorithms that the factory is allowed
+ * create timestamps for. Known vulnerable or weak algorithms should not be
+ * allowed where possible.
+ * Must be an Array of String or OpenSSL::Digest subclass instances.
+ *
+ * call-seq:
+ * factory.allowed_digests = ["sha1", OpenSSL::Digest.new('SHA256').new] -> [ "sha1", OpenSSL::Digest) ]
+ * factory.allowed_digests -> array or nil
+ *
+ */
+ cTimestampFactory = rb_define_class_under(mTimestamp, "Factory", rb_cObject);
+ rb_attr(cTimestampFactory, rb_intern_const("allowed_digests"), 1, 1, 0);
+ rb_attr(cTimestampFactory, rb_intern_const("default_policy_id"), 1, 1, 0);
+ rb_attr(cTimestampFactory, rb_intern_const("serial_number"), 1, 1, 0);
+ rb_attr(cTimestampFactory, rb_intern_const("gen_time"), 1, 1, 0);
+ rb_attr(cTimestampFactory, rb_intern_const("additional_certs"), 1, 1, 0);
+ rb_define_method(cTimestampFactory, "create_timestamp", ossl_tsfac_create_ts, 3);
+}
+
+#endif
diff --git a/ext/openssl/ossl_ts.h b/ext/openssl/ossl_ts.h
new file mode 100644
index 0000000000..25fb0e1d64
--- /dev/null
+++ b/ext/openssl/ossl_ts.h
@@ -0,0 +1,16 @@
+/*
+ *
+ * Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com>
+ * All rights reserved.
+ */
+/*
+ * This program is licenced under the same licence as Ruby.
+ * (See the file 'LICENCE'.)
+ */
+
+#if !defined(_OSSL_TS_H_)
+#define _OSSL_TS_H_
+
+void Init_ossl_ts(void);
+
+#endif
diff --git a/ext/openssl/ossl_version.h b/ext/openssl/ossl_version.h
deleted file mode 100644
index 4167c9c83d..0000000000
--- a/ext/openssl/ossl_version.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * 'OpenSSL for Ruby' project
- * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
- * All rights reserved.
- */
-/*
- * This program is licensed under the same licence as Ruby.
- * (See the file 'LICENCE'.)
- */
-#if !defined(_OSSL_VERSION_H_)
-#define _OSSL_VERSION_H_
-
-#define OSSL_VERSION "2.1.0"
-
-#endif /* _OSSL_VERSION_H_ */
diff --git a/ext/openssl/ossl_x509.c b/ext/openssl/ossl_x509.c
index 8a061b0687..4fc0648614 100644
--- a/ext/openssl/ossl_x509.c
+++ b/ext/openssl/ossl_x509.c
@@ -44,7 +44,13 @@ Init_ossl_x509(void)
Init_ossl_x509revoked();
Init_ossl_x509store();
+ /* Constants are up-to-date with 1.1.1. */
+
+ /* Certificate verification error code */
DefX509Const(V_OK);
+#if defined(X509_V_ERR_UNSPECIFIED) /* 1.0.1r, 1.0.2f, 1.1.0 */
+ DefX509Const(V_ERR_UNSPECIFIED);
+#endif
DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT);
DefX509Const(V_ERR_UNABLE_TO_GET_CRL);
DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
@@ -76,8 +82,73 @@ Init_ossl_x509(void)
DefX509Const(V_ERR_AKID_SKID_MISMATCH);
DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN);
+ DefX509Const(V_ERR_UNABLE_TO_GET_CRL_ISSUER);
+ DefX509Const(V_ERR_UNHANDLED_CRITICAL_EXTENSION);
+ DefX509Const(V_ERR_KEYUSAGE_NO_CRL_SIGN);
+ DefX509Const(V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
+ DefX509Const(V_ERR_INVALID_NON_CA);
+ DefX509Const(V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
+ DefX509Const(V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
+ DefX509Const(V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
+ DefX509Const(V_ERR_INVALID_EXTENSION);
+ DefX509Const(V_ERR_INVALID_POLICY_EXTENSION);
+ DefX509Const(V_ERR_NO_EXPLICIT_POLICY);
+ DefX509Const(V_ERR_DIFFERENT_CRL_SCOPE);
+ DefX509Const(V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
+ DefX509Const(V_ERR_UNNESTED_RESOURCE);
+ DefX509Const(V_ERR_PERMITTED_VIOLATION);
+ DefX509Const(V_ERR_EXCLUDED_VIOLATION);
+ DefX509Const(V_ERR_SUBTREE_MINMAX);
DefX509Const(V_ERR_APPLICATION_VERIFICATION);
+ DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
+ DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
+ DefX509Const(V_ERR_UNSUPPORTED_NAME_SYNTAX);
+ DefX509Const(V_ERR_CRL_PATH_VALIDATION_ERROR);
+#if defined(X509_V_ERR_PATH_LOOP)
+ DefX509Const(V_ERR_PATH_LOOP);
+#endif
+#if defined(X509_V_ERR_SUITE_B_INVALID_VERSION)
+ DefX509Const(V_ERR_SUITE_B_INVALID_VERSION);
+ DefX509Const(V_ERR_SUITE_B_INVALID_ALGORITHM);
+ DefX509Const(V_ERR_SUITE_B_INVALID_CURVE);
+ DefX509Const(V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM);
+ DefX509Const(V_ERR_SUITE_B_LOS_NOT_ALLOWED);
+ DefX509Const(V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
+#endif
+#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
+ DefX509Const(V_ERR_HOSTNAME_MISMATCH);
+ DefX509Const(V_ERR_EMAIL_MISMATCH);
+ DefX509Const(V_ERR_IP_ADDRESS_MISMATCH);
+#endif
+#if defined(X509_V_ERR_DANE_NO_MATCH)
+ DefX509Const(V_ERR_DANE_NO_MATCH);
+#endif
+#if defined(X509_V_ERR_EE_KEY_TOO_SMALL)
+ DefX509Const(V_ERR_EE_KEY_TOO_SMALL);
+ DefX509Const(V_ERR_CA_KEY_TOO_SMALL);
+ DefX509Const(V_ERR_CA_MD_TOO_WEAK);
+#endif
+#if defined(X509_V_ERR_INVALID_CALL)
+ DefX509Const(V_ERR_INVALID_CALL);
+#endif
+#if defined(X509_V_ERR_STORE_LOOKUP)
+ DefX509Const(V_ERR_STORE_LOOKUP);
+#endif
+#if defined(X509_V_ERR_NO_VALID_SCTS)
+ DefX509Const(V_ERR_NO_VALID_SCTS);
+#endif
+#if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION)
+ DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION);
+#endif
+#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED)
+ DefX509Const(V_ERR_OCSP_VERIFY_NEEDED);
+ DefX509Const(V_ERR_OCSP_VERIFY_FAILED);
+ DefX509Const(V_ERR_OCSP_CERT_UNKNOWN);
+#endif
+ /* Certificate verify flags */
+ /* Set by Store#flags= and StoreContext#flags=. */
+ DefX509Const(V_FLAG_USE_CHECK_TIME);
/* Set by Store#flags= and StoreContext#flags=. Enables CRL checking for the
* certificate chain leaf. */
DefX509Const(V_FLAG_CRL_CHECK);
@@ -122,6 +193,26 @@ Init_ossl_x509(void)
* Enabled by default in OpenSSL >= 1.1.0. */
DefX509Const(V_FLAG_TRUSTED_FIRST);
#endif
+#if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY)
+ /* Set by Store#flags= and StoreContext#flags=.
+ * Enables Suite B 128 bit only mode. */
+ DefX509Const(V_FLAG_SUITEB_128_LOS_ONLY);
+#endif
+#if defined(X509_V_FLAG_SUITEB_192_LOS)
+ /* Set by Store#flags= and StoreContext#flags=.
+ * Enables Suite B 192 bit only mode. */
+ DefX509Const(V_FLAG_SUITEB_192_LOS);
+#endif
+#if defined(X509_V_FLAG_SUITEB_128_LOS)
+ /* Set by Store#flags= and StoreContext#flags=.
+ * Enables Suite B 128 bit mode allowing 192 bit algorithms. */
+ DefX509Const(V_FLAG_SUITEB_128_LOS);
+#endif
+#if defined(X509_V_FLAG_PARTIAL_CHAIN)
+ /* Set by Store#flags= and StoreContext#flags=.
+ * Allows partial chains if at least one certificate is in trusted store. */
+ DefX509Const(V_FLAG_PARTIAL_CHAIN);
+#endif
#if defined(X509_V_FLAG_NO_ALT_CHAINS)
/* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
* a alternative chain. No effect in OpenSSL >= 1.1.0. */
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
index 003a9c1949..e3766b1b16 100644
--- a/ext/openssl/ossl_x509cert.c
+++ b/ext/openssl/ossl_x509cert.c
@@ -440,7 +440,7 @@ ossl_x509_set_not_before(VALUE self, VALUE time)
GetX509(self, x509);
asn1time = ossl_x509_time_adjust(NULL, time);
- if (!X509_set_notBefore(x509, asn1time)) {
+ if (!X509_set1_notBefore(x509, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CertError, "X509_set_notBefore");
}
@@ -479,7 +479,7 @@ ossl_x509_set_not_after(VALUE self, VALUE time)
GetX509(self, x509);
asn1time = ossl_x509_time_adjust(NULL, time);
- if (!X509_set_notAfter(x509, asn1time)) {
+ if (!X509_set1_notAfter(x509, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CertError, "X509_set_notAfter");
}
@@ -508,18 +508,19 @@ ossl_x509_get_public_key(VALUE self)
/*
* call-seq:
- * cert.public_key = key => key
+ * cert.public_key = key
*/
static VALUE
ossl_x509_set_public_key(VALUE self, VALUE key)
{
X509 *x509;
+ EVP_PKEY *pkey;
GetX509(self, x509);
- if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */
- ossl_raise(eX509CertError, NULL);
- }
-
+ pkey = GetPKeyPtr(key);
+ ossl_pkey_check_public_key(pkey);
+ if (!X509_set_pubkey(x509, pkey))
+ ossl_raise(eX509CertError, "X509_set_pubkey");
return key;
}
@@ -557,9 +558,9 @@ ossl_x509_verify(VALUE self, VALUE key)
X509 *x509;
EVP_PKEY *pkey;
- pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
GetX509(self, x509);
-
+ pkey = GetPKeyPtr(key);
+ ossl_pkey_check_public_key(pkey);
switch (X509_verify(x509, pkey)) {
case 1:
return Qtrue;
@@ -684,6 +685,26 @@ ossl_x509_inspect(VALUE self)
}
/*
+ * call-seq:
+ * cert1 == cert2 -> true | false
+ *
+ * Compares the two certificates. Note that this takes into account all fields,
+ * not just the issuer name and the serial number.
+ */
+static VALUE
+ossl_x509_eq(VALUE self, VALUE other)
+{
+ X509 *a, *b;
+
+ GetX509(self, a);
+ if (!rb_obj_is_kind_of(other, cX509Cert))
+ return Qfalse;
+ GetX509(other, b);
+
+ return !X509_cmp(a, b) ? Qtrue : Qfalse;
+}
+
+/*
* INIT
*/
void
@@ -767,7 +788,7 @@ Init_ossl_x509cert(void)
* root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
* root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
* root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
- * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
+ * root_ca.sign(root_key, OpenSSL::Digest.new('SHA256'))
*
* The next step is to create the end-entity certificate using the root CA
* certificate.
@@ -786,7 +807,7 @@ Init_ossl_x509cert(void)
* ef.issuer_certificate = root_ca
* cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
* cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
- * cert.sign(root_key, OpenSSL::Digest::SHA256.new)
+ * cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
*
*/
cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
@@ -821,4 +842,5 @@ Init_ossl_x509cert(void)
rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1);
rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
+ rb_define_method(cX509Cert, "==", ossl_x509_eq, 1);
}
diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c
index 5ecd7ea0b2..b0badf45c4 100644
--- a/ext/openssl/ossl_x509crl.c
+++ b/ext/openssl/ossl_x509crl.c
@@ -226,7 +226,7 @@ ossl_x509crl_set_last_update(VALUE self, VALUE time)
GetX509CRL(self, crl);
asn1time = ossl_x509_time_adjust(NULL, time);
- if (!X509_CRL_set_lastUpdate(crl, asn1time)) {
+ if (!X509_CRL_set1_lastUpdate(crl, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CRLError, "X509_CRL_set_lastUpdate");
}
@@ -257,7 +257,7 @@ ossl_x509crl_set_next_update(VALUE self, VALUE time)
GetX509CRL(self, crl);
asn1time = ossl_x509_time_adjust(NULL, time);
- if (!X509_CRL_set_nextUpdate(crl, asn1time)) {
+ if (!X509_CRL_set1_nextUpdate(crl, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CRLError, "X509_CRL_set_nextUpdate");
}
@@ -359,9 +359,12 @@ static VALUE
ossl_x509crl_verify(VALUE self, VALUE key)
{
X509_CRL *crl;
+ EVP_PKEY *pkey;
GetX509CRL(self, crl);
- switch (X509_CRL_verify(crl, GetPKeyPtr(key))) {
+ pkey = GetPKeyPtr(key);
+ ossl_pkey_check_public_key(pkey);
+ switch (X509_CRL_verify(crl, pkey)) {
case 1:
return Qtrue;
case 0:
diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c
index 2d9a7a31e8..5eb9bd759f 100644
--- a/ext/openssl/ossl_x509ext.c
+++ b/ext/openssl/ossl_x509ext.c
@@ -403,6 +403,19 @@ ossl_x509ext_get_value(VALUE obj)
}
static VALUE
+ossl_x509ext_get_value_der(VALUE obj)
+{
+ X509_EXTENSION *ext;
+ ASN1_OCTET_STRING *value;
+
+ GetX509Ext(obj, ext);
+ if ((value = X509_EXTENSION_get_data(ext)) == NULL)
+ ossl_raise(eX509ExtError, NULL);
+
+ return rb_str_new((const char *)value->data, value->length);
+}
+
+static VALUE
ossl_x509ext_get_critical(VALUE obj)
{
X509_EXTENSION *ext;
@@ -437,6 +450,7 @@ ossl_x509ext_to_der(VALUE obj)
void
Init_ossl_x509ext(void)
{
+#undef rb_intern
#if 0
mOSSL = rb_define_module("OpenSSL");
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -471,6 +485,7 @@ Init_ossl_x509ext(void)
rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1);
rb_define_method(cX509Ext, "oid", ossl_x509ext_get_oid, 0);
rb_define_method(cX509Ext, "value", ossl_x509ext_get_value, 0);
+ rb_define_method(cX509Ext, "value_der", ossl_x509ext_get_value_der, 0);
rb_define_method(cX509Ext, "critical?", ossl_x509ext_get_critical, 0);
rb_define_method(cX509Ext, "to_der", ossl_x509ext_to_der, 0);
}
diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c
index c900bcbe68..1522c3d897 100644
--- a/ext/openssl/ossl_x509name.c
+++ b/ext/openssl/ossl_x509name.c
@@ -250,14 +250,12 @@ ossl_x509name_to_s_old(VALUE self)
{
X509_NAME *name;
char *buf;
- VALUE str;
GetX509Name(self, name);
buf = X509_NAME_oneline(name, NULL, 0);
- str = rb_str_new2(buf);
- OPENSSL_free(buf);
-
- return str;
+ if (!buf)
+ ossl_raise(eX509NameError, "X509_NAME_oneline");
+ return ossl_buf2str(buf, rb_long2int(strlen(buf)));
}
static VALUE
@@ -265,12 +263,14 @@ x509name_print(VALUE self, unsigned long iflag)
{
X509_NAME *name;
BIO *out;
+ int ret;
GetX509Name(self, name);
out = BIO_new(BIO_s_mem());
if (!out)
ossl_raise(eX509NameError, NULL);
- if (!X509_NAME_print_ex(out, name, 0, iflag)) {
+ ret = X509_NAME_print_ex(out, name, 0, iflag);
+ if (ret < 0 || (iflag == XN_FLAG_COMPAT && ret == 0)) {
BIO_free(out);
ossl_raise(eX509NameError, "X509_NAME_print_ex");
}
@@ -387,20 +387,24 @@ ossl_x509name_cmp0(VALUE self, VALUE other)
/*
* call-seq:
- * name.cmp(other) -> -1 | 0 | 1
- * name <=> other -> -1 | 0 | 1
+ * name.cmp(other) -> -1 | 0 | 1 | nil
+ * name <=> other -> -1 | 0 | 1 | nil
*
* Compares this Name with _other_ and returns +0+ if they are the same and +-1+
* or ++1+ if they are greater or less than each other respectively.
+ * Returns +nil+ if they are not comparable (i.e. different types).
*/
static VALUE
ossl_x509name_cmp(VALUE self, VALUE other)
{
int result;
+ if (!rb_obj_is_kind_of(other, cX509Name))
+ return Qnil;
+
result = ossl_x509name_cmp0(self, other);
if (result < 0) return INT2FIX(-1);
- if (result > 1) return INT2FIX(1);
+ if (result > 0) return INT2FIX(1);
return INT2FIX(0);
}
@@ -494,7 +498,7 @@ ossl_x509name_to_der(VALUE self)
* You can create a Name by parsing a distinguished name String or by
* supplying the distinguished name as an Array.
*
- * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
+ * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
*
* name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
*/
@@ -502,6 +506,7 @@ ossl_x509name_to_der(VALUE self)
void
Init_ossl_x509name(void)
{
+#undef rb_intern
VALUE utf8str, ptrstr, ia5str, hash;
#if 0
diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c
index 9f20dba311..2c20042a92 100644
--- a/ext/openssl/ossl_x509req.c
+++ b/ext/openssl/ossl_x509req.c
@@ -293,11 +293,10 @@ ossl_x509req_set_public_key(VALUE self, VALUE key)
EVP_PKEY *pkey;
GetX509Req(self, req);
- pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
- if (!X509_REQ_set_pubkey(req, pkey)) {
- ossl_raise(eX509ReqError, NULL);
- }
-
+ pkey = GetPKeyPtr(key);
+ ossl_pkey_check_public_key(pkey);
+ if (!X509_REQ_set_pubkey(req, pkey))
+ ossl_raise(eX509ReqError, "X509_REQ_set_pubkey");
return key;
}
@@ -328,7 +327,8 @@ ossl_x509req_verify(VALUE self, VALUE key)
EVP_PKEY *pkey;
GetX509Req(self, req);
- pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
+ pkey = GetPKeyPtr(key);
+ ossl_pkey_check_public_key(pkey);
switch (X509_REQ_verify(req, pkey)) {
case 1:
return Qtrue;
diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c
index 85489efdb2..5fe6853430 100644
--- a/ext/openssl/ossl_x509revoked.c
+++ b/ext/openssl/ossl_x509revoked.c
@@ -249,6 +249,26 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext)
return ext;
}
+static VALUE
+ossl_x509revoked_to_der(VALUE self)
+{
+ X509_REVOKED *rev;
+ VALUE str;
+ int len;
+ unsigned char *p;
+
+ GetX509Rev(self, rev);
+ len = i2d_X509_REVOKED(rev, NULL);
+ if (len <= 0)
+ ossl_raise(eX509RevError, "i2d_X509_REVOKED");
+ str = rb_str_new(NULL, len);
+ p = (unsigned char *)RSTRING_PTR(str);
+ if (i2d_X509_REVOKED(rev, &p) <= 0)
+ ossl_raise(eX509RevError, "i2d_X509_REVOKED");
+ ossl_str_adjust(str, p);
+ return str;
+}
+
/*
* INIT
*/
@@ -276,4 +296,5 @@ Init_ossl_x509revoked(void)
rb_define_method(cX509Rev, "extensions", ossl_x509revoked_get_extensions, 0);
rb_define_method(cX509Rev, "extensions=", ossl_x509revoked_set_extensions, 1);
rb_define_method(cX509Rev, "add_extension", ossl_x509revoked_add_extension, 1);
+ rb_define_method(cX509Rev, "to_der", ossl_x509revoked_to_der, 0);
}
diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c
index c6cf67ad5d..9035a70aa9 100644
--- a/ext/openssl/ossl_x509store.c
+++ b/ext/openssl/ossl_x509store.c
@@ -106,6 +106,13 @@ VALUE cX509StoreContext;
VALUE eX509StoreError;
static void
+ossl_x509store_mark(void *ptr)
+{
+ X509_STORE *store = ptr;
+ rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
+}
+
+static void
ossl_x509store_free(void *ptr)
{
X509_STORE_free(ptr);
@@ -114,7 +121,7 @@ ossl_x509store_free(void *ptr)
static const rb_data_type_t ossl_x509store_type = {
"OpenSSL/X509/STORE",
{
- 0, ossl_x509store_free,
+ ossl_x509store_mark, ossl_x509store_free,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
@@ -304,7 +311,6 @@ ossl_x509store_add_file(VALUE self, VALUE file)
char *path = NULL;
if(file != Qnil){
- rb_check_safe_obj(file);
path = StringValueCStr(file);
}
GetX509Store(self, store);
@@ -340,7 +346,6 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
char *path = NULL;
if(dir != Qnil){
- rb_check_safe_obj(dir);
path = StringValueCStr(dir);
}
GetX509Store(self, store);
@@ -459,23 +464,16 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
}
/*
- * Public Functions
- */
-static void ossl_x509stctx_free(void*);
-
-
-static const rb_data_type_t ossl_x509stctx_type = {
- "OpenSSL/X509/STORE_CTX",
- {
- 0, ossl_x509stctx_free,
- },
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
-};
-
-/*
* Private functions
*/
static void
+ossl_x509stctx_mark(void *ptr)
+{
+ X509_STORE_CTX *ctx = ptr;
+ rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
+}
+
+static void
ossl_x509stctx_free(void *ptr)
{
X509_STORE_CTX *ctx = ptr;
@@ -486,6 +484,14 @@ ossl_x509stctx_free(void *ptr)
X509_STORE_CTX_free(ctx);
}
+static const rb_data_type_t ossl_x509stctx_type = {
+ "OpenSSL/X509/STORE_CTX",
+ {
+ ossl_x509stctx_mark, ossl_x509stctx_free,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
+};
+
static VALUE
ossl_x509stctx_alloc(VALUE klass)
{
@@ -519,7 +525,9 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
/*
* call-seq:
- * StoreContext.new(store, cert = nil, chain = nil)
+ * StoreContext.new(store, cert = nil, untrusted = nil)
+ *
+ * Sets up a StoreContext for a verification of the X.509 certificate _cert_.
*/
static VALUE
ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
@@ -529,15 +537,24 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
X509_STORE *x509st;
X509 *x509 = NULL;
STACK_OF(X509) *x509s = NULL;
+ int state;
rb_scan_args(argc, argv, "12", &store, &cert, &chain);
GetX509StCtx(self, ctx);
GetX509Store(store, x509st);
- if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
- if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
- if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
+ if (!NIL_P(cert))
+ x509 = DupX509CertPtr(cert); /* NEED TO DUP */
+ if (!NIL_P(chain)) {
+ x509s = ossl_protect_x509_ary2sk(chain, &state);
+ if (state) {
+ X509_free(x509);
+ rb_jump_tag(state);
+ }
+ }
+ if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
+ X509_free(x509);
sk_X509_pop_free(x509s, X509_free);
- ossl_raise(eX509StoreError, NULL);
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_init");
}
if (!NIL_P(t = rb_iv_get(store, "@time")))
ossl_x509stctx_set_time(self, t);
@@ -771,6 +788,7 @@ ossl_x509stctx_set_time(VALUE self, VALUE time)
void
Init_ossl_x509store(void)
{
+#undef rb_intern
#if 0
mOSSL = rb_define_module("OpenSSL");
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
diff --git a/ext/pathname/depend b/ext/pathname/depend
index 42abd32130..9df2ba8e18 100644
--- a/ext/pathname/depend
+++ b/ext/pathname/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
pathname.o: $(RUBY_EXTCONF_H)
pathname.o: $(arch_hdrdir)/ruby/config.h
+pathname.o: $(hdrdir)/ruby.h
+pathname.o: $(hdrdir)/ruby/internal/anyargs.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+pathname.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+pathname.o: $(hdrdir)/ruby/internal/assume.h
+pathname.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+pathname.o: $(hdrdir)/ruby/internal/attr/artificial.h
+pathname.o: $(hdrdir)/ruby/internal/attr/cold.h
+pathname.o: $(hdrdir)/ruby/internal/attr/const.h
+pathname.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+pathname.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+pathname.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+pathname.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+pathname.o: $(hdrdir)/ruby/internal/attr/error.h
+pathname.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+pathname.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+pathname.o: $(hdrdir)/ruby/internal/attr/format.h
+pathname.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+pathname.o: $(hdrdir)/ruby/internal/attr/noalias.h
+pathname.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+pathname.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+pathname.o: $(hdrdir)/ruby/internal/attr/noinline.h
+pathname.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+pathname.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+pathname.o: $(hdrdir)/ruby/internal/attr/pure.h
+pathname.o: $(hdrdir)/ruby/internal/attr/restrict.h
+pathname.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+pathname.o: $(hdrdir)/ruby/internal/attr/warning.h
+pathname.o: $(hdrdir)/ruby/internal/attr/weakref.h
+pathname.o: $(hdrdir)/ruby/internal/cast.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_is.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+pathname.o: $(hdrdir)/ruby/internal/compiler_since.h
+pathname.o: $(hdrdir)/ruby/internal/config.h
+pathname.o: $(hdrdir)/ruby/internal/constant_p.h
+pathname.o: $(hdrdir)/ruby/internal/core.h
+pathname.o: $(hdrdir)/ruby/internal/core/rarray.h
+pathname.o: $(hdrdir)/ruby/internal/core/rbasic.h
+pathname.o: $(hdrdir)/ruby/internal/core/rbignum.h
+pathname.o: $(hdrdir)/ruby/internal/core/rclass.h
+pathname.o: $(hdrdir)/ruby/internal/core/rdata.h
+pathname.o: $(hdrdir)/ruby/internal/core/rfile.h
+pathname.o: $(hdrdir)/ruby/internal/core/rhash.h
+pathname.o: $(hdrdir)/ruby/internal/core/robject.h
+pathname.o: $(hdrdir)/ruby/internal/core/rregexp.h
+pathname.o: $(hdrdir)/ruby/internal/core/rstring.h
+pathname.o: $(hdrdir)/ruby/internal/core/rstruct.h
+pathname.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+pathname.o: $(hdrdir)/ruby/internal/ctype.h
+pathname.o: $(hdrdir)/ruby/internal/dllexport.h
+pathname.o: $(hdrdir)/ruby/internal/dosish.h
+pathname.o: $(hdrdir)/ruby/internal/error.h
+pathname.o: $(hdrdir)/ruby/internal/eval.h
+pathname.o: $(hdrdir)/ruby/internal/event.h
+pathname.o: $(hdrdir)/ruby/internal/fl_type.h
+pathname.o: $(hdrdir)/ruby/internal/gc.h
+pathname.o: $(hdrdir)/ruby/internal/glob.h
+pathname.o: $(hdrdir)/ruby/internal/globals.h
+pathname.o: $(hdrdir)/ruby/internal/has/attribute.h
+pathname.o: $(hdrdir)/ruby/internal/has/builtin.h
+pathname.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+pathname.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+pathname.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+pathname.o: $(hdrdir)/ruby/internal/has/extension.h
+pathname.o: $(hdrdir)/ruby/internal/has/feature.h
+pathname.o: $(hdrdir)/ruby/internal/has/warning.h
+pathname.o: $(hdrdir)/ruby/internal/intern/array.h
+pathname.o: $(hdrdir)/ruby/internal/intern/bignum.h
+pathname.o: $(hdrdir)/ruby/internal/intern/class.h
+pathname.o: $(hdrdir)/ruby/internal/intern/compar.h
+pathname.o: $(hdrdir)/ruby/internal/intern/complex.h
+pathname.o: $(hdrdir)/ruby/internal/intern/cont.h
+pathname.o: $(hdrdir)/ruby/internal/intern/dir.h
+pathname.o: $(hdrdir)/ruby/internal/intern/enum.h
+pathname.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+pathname.o: $(hdrdir)/ruby/internal/intern/error.h
+pathname.o: $(hdrdir)/ruby/internal/intern/eval.h
+pathname.o: $(hdrdir)/ruby/internal/intern/file.h
+pathname.o: $(hdrdir)/ruby/internal/intern/gc.h
+pathname.o: $(hdrdir)/ruby/internal/intern/hash.h
+pathname.o: $(hdrdir)/ruby/internal/intern/io.h
+pathname.o: $(hdrdir)/ruby/internal/intern/load.h
+pathname.o: $(hdrdir)/ruby/internal/intern/marshal.h
+pathname.o: $(hdrdir)/ruby/internal/intern/numeric.h
+pathname.o: $(hdrdir)/ruby/internal/intern/object.h
+pathname.o: $(hdrdir)/ruby/internal/intern/parse.h
+pathname.o: $(hdrdir)/ruby/internal/intern/proc.h
+pathname.o: $(hdrdir)/ruby/internal/intern/process.h
+pathname.o: $(hdrdir)/ruby/internal/intern/random.h
+pathname.o: $(hdrdir)/ruby/internal/intern/range.h
+pathname.o: $(hdrdir)/ruby/internal/intern/rational.h
+pathname.o: $(hdrdir)/ruby/internal/intern/re.h
+pathname.o: $(hdrdir)/ruby/internal/intern/ruby.h
+pathname.o: $(hdrdir)/ruby/internal/intern/select.h
+pathname.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+pathname.o: $(hdrdir)/ruby/internal/intern/signal.h
+pathname.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+pathname.o: $(hdrdir)/ruby/internal/intern/string.h
+pathname.o: $(hdrdir)/ruby/internal/intern/struct.h
+pathname.o: $(hdrdir)/ruby/internal/intern/thread.h
+pathname.o: $(hdrdir)/ruby/internal/intern/time.h
+pathname.o: $(hdrdir)/ruby/internal/intern/variable.h
+pathname.o: $(hdrdir)/ruby/internal/intern/vm.h
+pathname.o: $(hdrdir)/ruby/internal/interpreter.h
+pathname.o: $(hdrdir)/ruby/internal/iterator.h
+pathname.o: $(hdrdir)/ruby/internal/memory.h
+pathname.o: $(hdrdir)/ruby/internal/method.h
+pathname.o: $(hdrdir)/ruby/internal/module.h
+pathname.o: $(hdrdir)/ruby/internal/newobj.h
+pathname.o: $(hdrdir)/ruby/internal/rgengc.h
+pathname.o: $(hdrdir)/ruby/internal/scan_args.h
+pathname.o: $(hdrdir)/ruby/internal/special_consts.h
+pathname.o: $(hdrdir)/ruby/internal/static_assert.h
+pathname.o: $(hdrdir)/ruby/internal/stdalign.h
+pathname.o: $(hdrdir)/ruby/internal/stdbool.h
+pathname.o: $(hdrdir)/ruby/internal/symbol.h
+pathname.o: $(hdrdir)/ruby/internal/token_paste.h
+pathname.o: $(hdrdir)/ruby/internal/value.h
+pathname.o: $(hdrdir)/ruby/internal/value_type.h
+pathname.o: $(hdrdir)/ruby/internal/variable.h
+pathname.o: $(hdrdir)/ruby/internal/warning_push.h
+pathname.o: $(hdrdir)/ruby/internal/xmalloc.h
+pathname.o: $(hdrdir)/ruby/assert.h
pathname.o: $(hdrdir)/ruby/backward.h
+pathname.o: $(hdrdir)/ruby/backward/2/assume.h
+pathname.o: $(hdrdir)/ruby/backward/2/attributes.h
+pathname.o: $(hdrdir)/ruby/backward/2/bool.h
+pathname.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+pathname.o: $(hdrdir)/ruby/backward/2/inttypes.h
+pathname.o: $(hdrdir)/ruby/backward/2/limits.h
+pathname.o: $(hdrdir)/ruby/backward/2/long_long.h
+pathname.o: $(hdrdir)/ruby/backward/2/stdalign.h
+pathname.o: $(hdrdir)/ruby/backward/2/stdarg.h
pathname.o: $(hdrdir)/ruby/defines.h
pathname.o: $(hdrdir)/ruby/encoding.h
pathname.o: $(hdrdir)/ruby/intern.h
@@ -11,6 +162,5 @@ pathname.o: $(hdrdir)/ruby/oniguruma.h
pathname.o: $(hdrdir)/ruby/ruby.h
pathname.o: $(hdrdir)/ruby/st.h
pathname.o: $(hdrdir)/ruby/subst.h
-pathname.o: $(top_srcdir)/include/ruby.h
pathname.o: pathname.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/pathname/extconf.rb b/ext/pathname/extconf.rb
index c9133bc153..84e68277aa 100644
--- a/ext/pathname/extconf.rb
+++ b/ext/pathname/extconf.rb
@@ -1,4 +1,4 @@
# frozen_string_literal: false
require 'mkmf'
-have_struct_member("struct stat", "st_birthtimespec", "sys/stat.h")
+have_func("rb_file_s_birthtime")
create_makefile('pathname')
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb
index ed7d8c791b..e6fb90277d 100644
--- a/ext/pathname/lib/pathname.rb
+++ b/ext/pathname/lib/pathname.rb
@@ -35,12 +35,19 @@ class Pathname
SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/
end
+ if File.dirname('A:') == 'A:.' # DOSish drive letter
+ ABSOLUTE_PATH = /\A(?:[A-Za-z]:|#{SEPARATOR_PAT})/o
+ else
+ ABSOLUTE_PATH = /\A#{SEPARATOR_PAT}/o
+ end
+ private_constant :ABSOLUTE_PATH
+
# :startdoc:
# chop_basename(path) -> [pre-basename, basename] or nil
def chop_basename(path) # :nodoc:
base = File.basename(path)
- if /\A#{SEPARATOR_PAT}?\z/o =~ base
+ if /\A#{SEPARATOR_PAT}?\z/o.match?(base)
return nil
else
return path[0, path.rindex(base)], base
@@ -62,7 +69,7 @@ class Pathname
def prepend_prefix(prefix, relpath) # :nodoc:
if relpath.empty?
File.dirname(prefix)
- elsif /#{SEPARATOR_PAT}/o =~ prefix
+ elsif /#{SEPARATOR_PAT}/o.match?(prefix)
prefix = File.dirname(prefix)
prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a'
prefix + relpath
@@ -113,7 +120,7 @@ class Pathname
end
end
pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
- if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
+ if /#{SEPARATOR_PAT}/o.match?(File.basename(pre))
names.shift while names[0] == '..'
end
self.class.new(prepend_prefix(pre, File.join(*names)))
@@ -162,7 +169,7 @@ class Pathname
names.unshift base if base != '.'
end
pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
- if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
+ if /#{SEPARATOR_PAT}/o.match?(File.basename(pre))
names.shift while names[0] == '..'
end
if names.empty?
@@ -193,8 +200,7 @@ class Pathname
begin
stat1 = self.lstat
stat2 = self.parent.lstat
- stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
- stat1.dev != stat2.dev
+ stat1.dev != stat2.dev || stat1.ino == stat2.ino
rescue Errno::ENOENT
false
end
@@ -208,7 +214,7 @@ class Pathname
# pathnames which points to roots such as <tt>/usr/..</tt>.
#
def root?
- !!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path)
+ chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o.match?(@path)
end
# Predicate method for testing whether a path is absolute.
@@ -223,7 +229,7 @@ class Pathname
# p.absolute?
# #=> false
def absolute?
- !relative?
+ ABSOLUTE_PATH.match? @path
end
# The opposite of Pathname#absolute?
@@ -238,11 +244,7 @@ class Pathname
# p.relative?
# #=> true
def relative?
- path = @path
- while r = chop_basename(path)
- path, = r
- end
- path == ''
+ !absolute?
end
#
@@ -380,7 +382,7 @@ class Pathname
basename_list2.shift
end
r1 = chop_basename(prefix1)
- if !r1 && (r1 = /#{SEPARATOR_PAT}/o =~ File.basename(prefix1))
+ if !r1 && (r1 = /#{SEPARATOR_PAT}/o.match?(File.basename(prefix1)))
while !basename_list2.empty? && basename_list2.first == '..'
index_list2.shift
basename_list2.shift
@@ -503,7 +505,11 @@ class Pathname
#
# ArgumentError is raised when it cannot find a relative path.
#
+ # Note that this method does not handle situations where the case sensitivity
+ # of the filesystem in use differs from the operating system default.
+ #
def relative_path_from(base_directory)
+ base_directory = Pathname.new(base_directory) unless base_directory.is_a? Pathname
dest_directory = self.cleanpath.to_s
base_directory = base_directory.cleanpath.to_s
dest_prefix = dest_directory
diff --git a/ext/pathname/pathname.c b/ext/pathname/pathname.c
index 56a7b85884..55577d7da7 100644
--- a/ext/pathname/pathname.c
+++ b/ext/pathname/pathname.c
@@ -2,21 +2,75 @@
#include "ruby/encoding.h"
static VALUE rb_cPathname;
-static ID id_at_path, id_to_path;
-static ID id_ENOTDIR, id_atime, id_basename, id_binread, id_binwrite,
- id_birthtime, id_blockdev_p, id_chardev_p, id_chmod, id_chown,
- id_ctime, id_directory_p, id_dirname, id_empty_p, id_entries,
- id_executable_p, id_executable_real_p, id_exist_p, id_expand_path,
- id_extname, id_file_p, id_fnmatch, id_foreach, id_ftype, id_getwd,
- id_glob, id_grpowned_p, id_lchmod, id_lchown, id_link, id_lstat,
- id_mkdir, id_mtime, id_open, id_owned_p, id_pipe_p, id_read,
- id_readable_p, id_readable_real_p, id_readlines, id_readlink,
- id_realdirpath, id_realpath, id_rename, id_rmdir, id_setgid_p,
- id_setuid_p, id_size, id_size_p, id_socket_p, id_split, id_stat,
- id_sticky_p, id_sub, id_symlink, id_symlink_p, id_sysopen,
- id_truncate, id_unlink, id_utime, id_world_readable_p,
- id_world_writable_p, id_writable_p, id_writable_real_p, id_write,
- id_zero_p;
+static ID id_ENOTDIR;
+static ID id_at_path;
+static ID id_atime;
+static ID id_base;
+static ID id_basename;
+static ID id_binread;
+static ID id_binwrite;
+static ID id_birthtime;
+static ID id_blockdev_p;
+static ID id_chardev_p;
+static ID id_chmod;
+static ID id_chown;
+static ID id_ctime;
+static ID id_directory_p;
+static ID id_dirname;
+static ID id_empty_p;
+static ID id_entries;
+static ID id_executable_p;
+static ID id_executable_real_p;
+static ID id_exist_p;
+static ID id_expand_path;
+static ID id_extname;
+static ID id_file_p;
+static ID id_fnmatch;
+static ID id_foreach;
+static ID id_ftype;
+static ID id_getwd;
+static ID id_glob;
+static ID id_grpowned_p;
+static ID id_lchmod;
+static ID id_lchown;
+static ID id_link;
+static ID id_lstat;
+static ID id_mkdir;
+static ID id_mtime;
+static ID id_open;
+static ID id_owned_p;
+static ID id_pipe_p;
+static ID id_read;
+static ID id_readable_p;
+static ID id_readable_real_p;
+static ID id_readlines;
+static ID id_readlink;
+static ID id_realdirpath;
+static ID id_realpath;
+static ID id_rename;
+static ID id_rmdir;
+static ID id_setgid_p;
+static ID id_setuid_p;
+static ID id_size;
+static ID id_size_p;
+static ID id_socket_p;
+static ID id_split;
+static ID id_stat;
+static ID id_sticky_p;
+static ID id_sub;
+static ID id_symlink;
+static ID id_symlink_p;
+static ID id_sysopen;
+static ID id_to_path;
+static ID id_truncate;
+static ID id_unlink;
+static ID id_utime;
+static ID id_world_readable_p;
+static ID id_world_writable_p;
+static ID id_writable_p;
+static ID id_writable_real_p;
+static ID id_write;
+static ID id_zero_p;
static VALUE
get_strpath(VALUE obj)
@@ -56,7 +110,6 @@ path_initialize(VALUE self, VALUE arg)
str = rb_obj_dup(str);
set_strpath(self, str);
- OBJ_INFECT(self, str);
return self;
}
@@ -80,15 +133,12 @@ path_freeze(VALUE self)
* call-seq:
* pathname.taint -> obj
*
- * Taints this Pathname.
- *
- * See Object.taint.
+ * Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
*/
static VALUE
path_taint(VALUE self)
{
- rb_call_super(0, 0);
- rb_obj_taint(get_strpath(self));
+ rb_warn("Pathname#taint is deprecated and will be removed in Ruby 3.2.");
return self;
}
@@ -96,15 +146,12 @@ path_taint(VALUE self)
* call-seq:
* pathname.untaint -> obj
*
- * Untaints this Pathname.
- *
- * See Object.untaint.
+ * Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
*/
static VALUE
path_untaint(VALUE self)
{
- rb_call_super(0, 0);
- rb_obj_untaint(get_strpath(self));
+ rb_warn("Pathname#untaint is deprecated and will be removed in Ruby 3.2.");
return self;
}
@@ -254,7 +301,6 @@ path_sub_ext(VALUE self, VALUE repl)
}
str2 = rb_str_subseq(str, 0, ext-p);
rb_str_append(str2, repl);
- OBJ_INFECT(str2, str);
return rb_class_new_instance(1, &str2, rb_obj_class(self));
}
@@ -314,10 +360,10 @@ path_each_line(int argc, VALUE *argv, VALUE self)
args[0] = get_strpath(self);
n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
if (rb_block_given_p()) {
- return rb_block_call(rb_cIO, id_foreach, 1+n, args, 0, 0);
+ return rb_block_call_kw(rb_cFile, id_foreach, 1+n, args, 0, 0, RB_PASS_CALLED_KEYWORDS);
}
else {
- return rb_funcallv(rb_cIO, id_foreach, 1+n, args);
+ return rb_funcallv_kw(rb_cFile, id_foreach, 1+n, args, RB_PASS_CALLED_KEYWORDS);
}
}
@@ -328,7 +374,7 @@ path_each_line(int argc, VALUE *argv, VALUE self)
*
* Returns all data from the file, or the first +N+ bytes if specified.
*
- * See IO.read.
+ * See File.read.
*
*/
static VALUE
@@ -339,7 +385,7 @@ path_read(int argc, VALUE *argv, VALUE self)
args[0] = get_strpath(self);
n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
- return rb_funcallv(rb_cIO, id_read, 1+n, args);
+ return rb_funcallv_kw(rb_cFile, id_read, 1+n, args, RB_PASS_CALLED_KEYWORDS);
}
/*
@@ -348,7 +394,7 @@ path_read(int argc, VALUE *argv, VALUE self)
*
* Returns all the bytes from the file, or the first +N+ if specified.
*
- * See IO.binread.
+ * See File.binread.
*
*/
static VALUE
@@ -359,7 +405,7 @@ path_binread(int argc, VALUE *argv, VALUE self)
args[0] = get_strpath(self);
n = rb_scan_args(argc, argv, "02", &args[1], &args[2]);
- return rb_funcallv(rb_cIO, id_binread, 1+n, args);
+ return rb_funcallv(rb_cFile, id_binread, 1+n, args);
}
/*
@@ -369,7 +415,7 @@ path_binread(int argc, VALUE *argv, VALUE self)
*
* Writes +contents+ to the file.
*
- * See IO.write.
+ * See File.write.
*
*/
static VALUE
@@ -380,7 +426,7 @@ path_write(int argc, VALUE *argv, VALUE self)
args[0] = get_strpath(self);
n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
- return rb_funcallv(rb_cIO, id_write, 1+n, args);
+ return rb_funcallv_kw(rb_cFile, id_write, 1+n, args, RB_PASS_CALLED_KEYWORDS);
}
/*
@@ -390,7 +436,7 @@ path_write(int argc, VALUE *argv, VALUE self)
*
* Writes +contents+ to the file, opening it in binary mode.
*
- * See IO.binwrite.
+ * See File.binwrite.
*
*/
static VALUE
@@ -401,7 +447,7 @@ path_binwrite(int argc, VALUE *argv, VALUE self)
args[0] = get_strpath(self);
n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
- return rb_funcallv(rb_cIO, id_binwrite, 1+n, args);
+ return rb_funcallv_kw(rb_cFile, id_binwrite, 1+n, args, RB_PASS_CALLED_KEYWORDS);
}
/*
@@ -412,7 +458,7 @@ path_binwrite(int argc, VALUE *argv, VALUE self)
*
* Returns all the lines from the file.
*
- * See IO.readlines.
+ * See File.readlines.
*
*/
static VALUE
@@ -423,7 +469,7 @@ path_readlines(int argc, VALUE *argv, VALUE self)
args[0] = get_strpath(self);
n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
- return rb_funcallv(rb_cIO, id_readlines, 1+n, args);
+ return rb_funcallv_kw(rb_cFile, id_readlines, 1+n, args, RB_PASS_CALLED_KEYWORDS);
}
/*
@@ -458,7 +504,7 @@ path_atime(VALUE self)
return rb_funcall(rb_cFile, id_atime, 1, get_strpath(self));
}
-#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) || defined(_WIN32)
+#if defined(HAVE_RB_FILE_S_BIRTHTIME)
/*
* call-seq:
* pathname.birthtime -> time
@@ -474,6 +520,7 @@ path_birthtime(VALUE self)
return rb_funcall(rb_cFile, id_birthtime, 1, get_strpath(self));
}
#else
+/* check at compilation time for `respond_to?` */
# define path_birthtime rb_f_notimplement
#endif
@@ -507,7 +554,7 @@ path_mtime(VALUE self)
/*
* call-seq:
- * pathname.chmod -> integer
+ * pathname.chmod(mode_int) -> integer
*
* Changes file permissions.
*
@@ -521,7 +568,7 @@ path_chmod(VALUE self, VALUE mode)
/*
* call-seq:
- * pathname.lchmod -> integer
+ * pathname.lchmod(mode_int) -> integer
*
* Same as Pathname.chmod, but does not follow symbolic links.
*
@@ -535,7 +582,7 @@ path_lchmod(VALUE self, VALUE mode)
/*
* call-seq:
- * pathname.chown -> integer
+ * pathname.chown(owner_int, group_int) -> integer
*
* Change owner and group of the file.
*
@@ -549,7 +596,7 @@ path_chown(VALUE self, VALUE owner, VALUE group)
/*
* call-seq:
- * pathname.lchown -> integer
+ * pathname.lchown(owner_int, group_int) -> integer
*
* Same as Pathname.chown, but does not follow symbolic links.
*
@@ -563,8 +610,8 @@ path_lchown(VALUE self, VALUE owner, VALUE group)
/*
* call-seq:
- * pathname.fnmatch(pattern, [flags]) -> string
- * pathname.fnmatch?(pattern, [flags]) -> string
+ * pathname.fnmatch(pattern, [flags]) -> true or false
+ * pathname.fnmatch?(pattern, [flags]) -> true or false
*
* Return +true+ if the receiver matches the given pattern.
*
@@ -610,6 +657,13 @@ path_make_link(VALUE self, VALUE old)
}
/*
+ * call-seq:
+ * pathname.open()
+ * pathname.open(mode="r" [, opt]) -> file
+ * pathname.open([mode [, perm]] [, opt]) -> file
+ * pathname.open(mode="r" [, opt]) {|file| block } -> obj
+ * pathname.open([mode [, perm]] [, opt]) {|file| block } -> obj
+ *
* Opens the file for reading or writing.
*
* See File.open.
@@ -623,10 +677,10 @@ path_open(int argc, VALUE *argv, VALUE self)
args[0] = get_strpath(self);
n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
if (rb_block_given_p()) {
- return rb_block_call(rb_cFile, id_open, 1+n, args, 0, 0);
+ return rb_block_call_kw(rb_cFile, id_open, 1+n, args, 0, 0, RB_PASS_CALLED_KEYWORDS);
}
else {
- return rb_funcallv(rb_cFile, id_open, 1+n, args);
+ return rb_funcallv_kw(rb_cFile, id_open, 1+n, args, RB_PASS_CALLED_KEYWORDS);
}
}
@@ -1021,7 +1075,7 @@ path_empty_p(VALUE self)
}
static VALUE
-glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, klass))
+s_glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, klass))
{
return rb_yield(rb_class_new_instance(1, &elt, klass));
}
@@ -1029,25 +1083,25 @@ glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, klass))
/*
* Returns or yields Pathname objects.
*
- * Pathname.glob("config/" "*.rb")
- * #=> [#<Pathname:config/environment.rb>, #<Pathname:config/routes.rb>, ..]
+ * Pathname.glob("lib/i*.rb")
+ * #=> [#<Pathname:lib/ipaddr.rb>, #<Pathname:lib/irb.rb>]
*
* See Dir.glob.
*/
static VALUE
path_s_glob(int argc, VALUE *argv, VALUE klass)
{
- VALUE args[2];
+ VALUE args[3];
int n;
- n = rb_scan_args(argc, argv, "11", &args[0], &args[1]);
+ n = rb_scan_args(argc, argv, "12", &args[0], &args[1], &args[2]);
if (rb_block_given_p()) {
- return rb_block_call(rb_cDir, id_glob, n, args, glob_i, klass);
+ return rb_block_call_kw(rb_cDir, id_glob, n, args, s_glob_i, klass, RB_PASS_CALLED_KEYWORDS);
}
else {
VALUE ary;
long i;
- ary = rb_funcallv(rb_cDir, id_glob, n, args);
+ ary = rb_funcallv_kw(rb_cDir, id_glob, n, args, RB_PASS_CALLED_KEYWORDS);
ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
for (i = 0; i < RARRAY_LEN(ary); i++) {
VALUE elt = RARRAY_AREF(ary, i);
@@ -1058,6 +1112,54 @@ path_s_glob(int argc, VALUE *argv, VALUE klass)
}
}
+static VALUE
+glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, self))
+{
+ elt = rb_funcall(self, '+', 1, elt);
+ return rb_yield(elt);
+}
+
+/*
+ * Returns or yields Pathname objects.
+ *
+ * Pathname("ruby-2.4.2").glob("R*.md")
+ * #=> [#<Pathname:ruby-2.4.2/README.md>, #<Pathname:ruby-2.4.2/README.ja.md>]
+ *
+ * See Dir.glob.
+ * This method uses the +base+ keyword argument of Dir.glob.
+ */
+static VALUE
+path_glob(int argc, VALUE *argv, VALUE self)
+{
+ VALUE args[3];
+ int n;
+
+ n = rb_scan_args(argc, argv, "11", &args[0], &args[1]);
+ if (n == 1)
+ args[1] = INT2FIX(0);
+
+ args[2] = rb_hash_new();
+ rb_hash_aset(args[2], ID2SYM(id_base), get_strpath(self));
+
+ n = 3;
+
+ if (rb_block_given_p()) {
+ return rb_block_call_kw(rb_cDir, id_glob, n, args, glob_i, self, RB_PASS_KEYWORDS);
+ }
+ else {
+ VALUE ary;
+ long i;
+ ary = rb_funcallv_kw(rb_cDir, id_glob, n, args, RB_PASS_KEYWORDS);
+ ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE elt = RARRAY_AREF(ary, i);
+ elt = rb_funcall(self, '+', 1, elt);
+ rb_ary_store(ary, i, elt);
+ }
+ return ary;
+ }
+}
+
/*
* Returns the current working directory as a Pathname.
*
@@ -1220,6 +1322,8 @@ path_unlink(VALUE self)
static VALUE
path_f_pathname(VALUE self, VALUE str)
{
+ if (CLASS_OF(str) == rb_cPathname)
+ return str;
return rb_class_new_instance(1, &str, rb_cPathname);
}
@@ -1385,6 +1489,8 @@ path_f_pathname(VALUE self, VALUE str)
* - #binread(*args)
* - #readlines(*args)
* - #sysopen(*args)
+ * - #write(*args)
+ * - #binwrite(*args)
*
* === Utilities
*
@@ -1406,6 +1512,10 @@ path_f_pathname(VALUE self, VALUE str)
void
Init_pathname(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
InitVM(pathname);
rb_cPathname = rb_define_class("Pathname", rb_cObject);
@@ -1485,6 +1595,7 @@ Init_pathname(void)
rb_define_singleton_method(rb_cPathname, "glob", path_s_glob, -1);
rb_define_singleton_method(rb_cPathname, "getwd", path_s_getwd, 0);
rb_define_singleton_method(rb_cPathname, "pwd", path_s_getwd, 0);
+ rb_define_method(rb_cPathname, "glob", path_glob, -1);
rb_define_method(rb_cPathname, "entries", path_entries, 0);
rb_define_method(rb_cPathname, "mkdir", path_mkdir, -1);
rb_define_method(rb_cPathname, "rmdir", path_rmdir, 0);
@@ -1505,6 +1616,7 @@ InitVM_pathname(void)
id_ENOTDIR = rb_intern("ENOTDIR");
id_atime = rb_intern("atime");
id_basename = rb_intern("basename");
+ id_base = rb_intern("base");
id_binread = rb_intern("binread");
id_binwrite = rb_intern("binwrite");
id_birthtime = rb_intern("birthtime");
diff --git a/ext/pathname/pathname.gemspec b/ext/pathname/pathname.gemspec
new file mode 100644
index 0000000000..8593f9e9c7
--- /dev/null
+++ b/ext/pathname/pathname.gemspec
@@ -0,0 +1,25 @@
+Gem::Specification.new do |spec|
+ spec.name = "pathname"
+ spec.version = "0.1.0"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Representation of the name of a file or directory on the filesystem}
+ spec.description = %q{Representation of the name of a file or directory on the filesystem}
+ spec.homepage = "https://github.com/ruby/pathname"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+ spec.extensions = %w[ext/pathname/extconf.rb]
+end
diff --git a/ext/psych/.gitignore b/ext/psych/.gitignore
deleted file mode 100644
index 836058c169..0000000000
--- a/ext/psych/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-/api.c
-/config.h
-/dumper.c
-/emitter.c
-/loader.c
-/parser.c
-/reader.c
-/scanner.c
-/writer.c
-/yaml.h
-/yaml_private.h
diff --git a/ext/psych/depend b/ext/psych/depend
index c5ca1f6b13..2017319fd1 100644
--- a/ext/psych/depend
+++ b/ext/psych/depend
@@ -1,7 +1,160 @@
+$(OBJS): $(YAML_H)
+
# AUTOGENERATED DEPENDENCIES START
psych.o: $(RUBY_EXTCONF_H)
psych.o: $(arch_hdrdir)/ruby/config.h
+psych.o: $(hdrdir)/ruby.h
+psych.o: $(hdrdir)/ruby/internal/anyargs.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+psych.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+psych.o: $(hdrdir)/ruby/internal/assume.h
+psych.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+psych.o: $(hdrdir)/ruby/internal/attr/artificial.h
+psych.o: $(hdrdir)/ruby/internal/attr/cold.h
+psych.o: $(hdrdir)/ruby/internal/attr/const.h
+psych.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+psych.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+psych.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+psych.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+psych.o: $(hdrdir)/ruby/internal/attr/error.h
+psych.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+psych.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+psych.o: $(hdrdir)/ruby/internal/attr/format.h
+psych.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+psych.o: $(hdrdir)/ruby/internal/attr/noalias.h
+psych.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+psych.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+psych.o: $(hdrdir)/ruby/internal/attr/noinline.h
+psych.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+psych.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+psych.o: $(hdrdir)/ruby/internal/attr/pure.h
+psych.o: $(hdrdir)/ruby/internal/attr/restrict.h
+psych.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+psych.o: $(hdrdir)/ruby/internal/attr/warning.h
+psych.o: $(hdrdir)/ruby/internal/attr/weakref.h
+psych.o: $(hdrdir)/ruby/internal/cast.h
+psych.o: $(hdrdir)/ruby/internal/compiler_is.h
+psych.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+psych.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+psych.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+psych.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+psych.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+psych.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+psych.o: $(hdrdir)/ruby/internal/compiler_since.h
+psych.o: $(hdrdir)/ruby/internal/config.h
+psych.o: $(hdrdir)/ruby/internal/constant_p.h
+psych.o: $(hdrdir)/ruby/internal/core.h
+psych.o: $(hdrdir)/ruby/internal/core/rarray.h
+psych.o: $(hdrdir)/ruby/internal/core/rbasic.h
+psych.o: $(hdrdir)/ruby/internal/core/rbignum.h
+psych.o: $(hdrdir)/ruby/internal/core/rclass.h
+psych.o: $(hdrdir)/ruby/internal/core/rdata.h
+psych.o: $(hdrdir)/ruby/internal/core/rfile.h
+psych.o: $(hdrdir)/ruby/internal/core/rhash.h
+psych.o: $(hdrdir)/ruby/internal/core/robject.h
+psych.o: $(hdrdir)/ruby/internal/core/rregexp.h
+psych.o: $(hdrdir)/ruby/internal/core/rstring.h
+psych.o: $(hdrdir)/ruby/internal/core/rstruct.h
+psych.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+psych.o: $(hdrdir)/ruby/internal/ctype.h
+psych.o: $(hdrdir)/ruby/internal/dllexport.h
+psych.o: $(hdrdir)/ruby/internal/dosish.h
+psych.o: $(hdrdir)/ruby/internal/error.h
+psych.o: $(hdrdir)/ruby/internal/eval.h
+psych.o: $(hdrdir)/ruby/internal/event.h
+psych.o: $(hdrdir)/ruby/internal/fl_type.h
+psych.o: $(hdrdir)/ruby/internal/gc.h
+psych.o: $(hdrdir)/ruby/internal/glob.h
+psych.o: $(hdrdir)/ruby/internal/globals.h
+psych.o: $(hdrdir)/ruby/internal/has/attribute.h
+psych.o: $(hdrdir)/ruby/internal/has/builtin.h
+psych.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+psych.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+psych.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+psych.o: $(hdrdir)/ruby/internal/has/extension.h
+psych.o: $(hdrdir)/ruby/internal/has/feature.h
+psych.o: $(hdrdir)/ruby/internal/has/warning.h
+psych.o: $(hdrdir)/ruby/internal/intern/array.h
+psych.o: $(hdrdir)/ruby/internal/intern/bignum.h
+psych.o: $(hdrdir)/ruby/internal/intern/class.h
+psych.o: $(hdrdir)/ruby/internal/intern/compar.h
+psych.o: $(hdrdir)/ruby/internal/intern/complex.h
+psych.o: $(hdrdir)/ruby/internal/intern/cont.h
+psych.o: $(hdrdir)/ruby/internal/intern/dir.h
+psych.o: $(hdrdir)/ruby/internal/intern/enum.h
+psych.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+psych.o: $(hdrdir)/ruby/internal/intern/error.h
+psych.o: $(hdrdir)/ruby/internal/intern/eval.h
+psych.o: $(hdrdir)/ruby/internal/intern/file.h
+psych.o: $(hdrdir)/ruby/internal/intern/gc.h
+psych.o: $(hdrdir)/ruby/internal/intern/hash.h
+psych.o: $(hdrdir)/ruby/internal/intern/io.h
+psych.o: $(hdrdir)/ruby/internal/intern/load.h
+psych.o: $(hdrdir)/ruby/internal/intern/marshal.h
+psych.o: $(hdrdir)/ruby/internal/intern/numeric.h
+psych.o: $(hdrdir)/ruby/internal/intern/object.h
+psych.o: $(hdrdir)/ruby/internal/intern/parse.h
+psych.o: $(hdrdir)/ruby/internal/intern/proc.h
+psych.o: $(hdrdir)/ruby/internal/intern/process.h
+psych.o: $(hdrdir)/ruby/internal/intern/random.h
+psych.o: $(hdrdir)/ruby/internal/intern/range.h
+psych.o: $(hdrdir)/ruby/internal/intern/rational.h
+psych.o: $(hdrdir)/ruby/internal/intern/re.h
+psych.o: $(hdrdir)/ruby/internal/intern/ruby.h
+psych.o: $(hdrdir)/ruby/internal/intern/select.h
+psych.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+psych.o: $(hdrdir)/ruby/internal/intern/signal.h
+psych.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+psych.o: $(hdrdir)/ruby/internal/intern/string.h
+psych.o: $(hdrdir)/ruby/internal/intern/struct.h
+psych.o: $(hdrdir)/ruby/internal/intern/thread.h
+psych.o: $(hdrdir)/ruby/internal/intern/time.h
+psych.o: $(hdrdir)/ruby/internal/intern/variable.h
+psych.o: $(hdrdir)/ruby/internal/intern/vm.h
+psych.o: $(hdrdir)/ruby/internal/interpreter.h
+psych.o: $(hdrdir)/ruby/internal/iterator.h
+psych.o: $(hdrdir)/ruby/internal/memory.h
+psych.o: $(hdrdir)/ruby/internal/method.h
+psych.o: $(hdrdir)/ruby/internal/module.h
+psych.o: $(hdrdir)/ruby/internal/newobj.h
+psych.o: $(hdrdir)/ruby/internal/rgengc.h
+psych.o: $(hdrdir)/ruby/internal/scan_args.h
+psych.o: $(hdrdir)/ruby/internal/special_consts.h
+psych.o: $(hdrdir)/ruby/internal/static_assert.h
+psych.o: $(hdrdir)/ruby/internal/stdalign.h
+psych.o: $(hdrdir)/ruby/internal/stdbool.h
+psych.o: $(hdrdir)/ruby/internal/symbol.h
+psych.o: $(hdrdir)/ruby/internal/token_paste.h
+psych.o: $(hdrdir)/ruby/internal/value.h
+psych.o: $(hdrdir)/ruby/internal/value_type.h
+psych.o: $(hdrdir)/ruby/internal/variable.h
+psych.o: $(hdrdir)/ruby/internal/warning_push.h
+psych.o: $(hdrdir)/ruby/internal/xmalloc.h
+psych.o: $(hdrdir)/ruby/assert.h
psych.o: $(hdrdir)/ruby/backward.h
+psych.o: $(hdrdir)/ruby/backward/2/assume.h
+psych.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych.o: $(hdrdir)/ruby/backward/2/bool.h
+psych.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych.o: $(hdrdir)/ruby/backward/2/limits.h
+psych.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych.o: $(hdrdir)/ruby/backward/2/stdarg.h
psych.o: $(hdrdir)/ruby/defines.h
psych.o: $(hdrdir)/ruby/encoding.h
psych.o: $(hdrdir)/ruby/intern.h
@@ -11,7 +164,6 @@ psych.o: $(hdrdir)/ruby/oniguruma.h
psych.o: $(hdrdir)/ruby/ruby.h
psych.o: $(hdrdir)/ruby/st.h
psych.o: $(hdrdir)/ruby/subst.h
-psych.o: $(top_srcdir)/include/ruby.h
psych.o: psych.c
psych.o: psych.h
psych.o: psych_emitter.h
@@ -20,7 +172,158 @@ psych.o: psych_to_ruby.h
psych.o: psych_yaml_tree.h
psych_emitter.o: $(RUBY_EXTCONF_H)
psych_emitter.o: $(arch_hdrdir)/ruby/config.h
+psych_emitter.o: $(hdrdir)/ruby.h
+psych_emitter.o: $(hdrdir)/ruby/internal/anyargs.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+psych_emitter.o: $(hdrdir)/ruby/internal/assume.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/artificial.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/cold.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/const.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/error.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/format.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/noalias.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/noinline.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/pure.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/restrict.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/warning.h
+psych_emitter.o: $(hdrdir)/ruby/internal/attr/weakref.h
+psych_emitter.o: $(hdrdir)/ruby/internal/cast.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_is.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+psych_emitter.o: $(hdrdir)/ruby/internal/compiler_since.h
+psych_emitter.o: $(hdrdir)/ruby/internal/config.h
+psych_emitter.o: $(hdrdir)/ruby/internal/constant_p.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rarray.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rbasic.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rbignum.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rclass.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rdata.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rfile.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rhash.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/robject.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rregexp.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rstring.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rstruct.h
+psych_emitter.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+psych_emitter.o: $(hdrdir)/ruby/internal/ctype.h
+psych_emitter.o: $(hdrdir)/ruby/internal/dllexport.h
+psych_emitter.o: $(hdrdir)/ruby/internal/dosish.h
+psych_emitter.o: $(hdrdir)/ruby/internal/error.h
+psych_emitter.o: $(hdrdir)/ruby/internal/eval.h
+psych_emitter.o: $(hdrdir)/ruby/internal/event.h
+psych_emitter.o: $(hdrdir)/ruby/internal/fl_type.h
+psych_emitter.o: $(hdrdir)/ruby/internal/gc.h
+psych_emitter.o: $(hdrdir)/ruby/internal/glob.h
+psych_emitter.o: $(hdrdir)/ruby/internal/globals.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/attribute.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/builtin.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/extension.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/feature.h
+psych_emitter.o: $(hdrdir)/ruby/internal/has/warning.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/array.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/bignum.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/class.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/compar.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/complex.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/cont.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/dir.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/enum.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/error.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/eval.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/gc.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/hash.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/io.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/load.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/marshal.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/numeric.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/object.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/parse.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/proc.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/process.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/random.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/range.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/rational.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/re.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/ruby.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/select.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/signal.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/string.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/struct.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/thread.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/time.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/variable.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/vm.h
+psych_emitter.o: $(hdrdir)/ruby/internal/interpreter.h
+psych_emitter.o: $(hdrdir)/ruby/internal/iterator.h
+psych_emitter.o: $(hdrdir)/ruby/internal/memory.h
+psych_emitter.o: $(hdrdir)/ruby/internal/method.h
+psych_emitter.o: $(hdrdir)/ruby/internal/module.h
+psych_emitter.o: $(hdrdir)/ruby/internal/newobj.h
+psych_emitter.o: $(hdrdir)/ruby/internal/rgengc.h
+psych_emitter.o: $(hdrdir)/ruby/internal/scan_args.h
+psych_emitter.o: $(hdrdir)/ruby/internal/special_consts.h
+psych_emitter.o: $(hdrdir)/ruby/internal/static_assert.h
+psych_emitter.o: $(hdrdir)/ruby/internal/stdalign.h
+psych_emitter.o: $(hdrdir)/ruby/internal/stdbool.h
+psych_emitter.o: $(hdrdir)/ruby/internal/symbol.h
+psych_emitter.o: $(hdrdir)/ruby/internal/token_paste.h
+psych_emitter.o: $(hdrdir)/ruby/internal/value.h
+psych_emitter.o: $(hdrdir)/ruby/internal/value_type.h
+psych_emitter.o: $(hdrdir)/ruby/internal/variable.h
+psych_emitter.o: $(hdrdir)/ruby/internal/warning_push.h
+psych_emitter.o: $(hdrdir)/ruby/internal/xmalloc.h
+psych_emitter.o: $(hdrdir)/ruby/assert.h
psych_emitter.o: $(hdrdir)/ruby/backward.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_emitter.o: $(hdrdir)/ruby/backward/2/stdarg.h
psych_emitter.o: $(hdrdir)/ruby/defines.h
psych_emitter.o: $(hdrdir)/ruby/encoding.h
psych_emitter.o: $(hdrdir)/ruby/intern.h
@@ -30,7 +333,6 @@ psych_emitter.o: $(hdrdir)/ruby/oniguruma.h
psych_emitter.o: $(hdrdir)/ruby/ruby.h
psych_emitter.o: $(hdrdir)/ruby/st.h
psych_emitter.o: $(hdrdir)/ruby/subst.h
-psych_emitter.o: $(top_srcdir)/include/ruby.h
psych_emitter.o: psych.h
psych_emitter.o: psych_emitter.c
psych_emitter.o: psych_emitter.h
@@ -39,7 +341,158 @@ psych_emitter.o: psych_to_ruby.h
psych_emitter.o: psych_yaml_tree.h
psych_parser.o: $(RUBY_EXTCONF_H)
psych_parser.o: $(arch_hdrdir)/ruby/config.h
+psych_parser.o: $(hdrdir)/ruby.h
+psych_parser.o: $(hdrdir)/ruby/internal/anyargs.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+psych_parser.o: $(hdrdir)/ruby/internal/assume.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/artificial.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/cold.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/const.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/error.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/format.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/noalias.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/noinline.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/pure.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/restrict.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/warning.h
+psych_parser.o: $(hdrdir)/ruby/internal/attr/weakref.h
+psych_parser.o: $(hdrdir)/ruby/internal/cast.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_is.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+psych_parser.o: $(hdrdir)/ruby/internal/compiler_since.h
+psych_parser.o: $(hdrdir)/ruby/internal/config.h
+psych_parser.o: $(hdrdir)/ruby/internal/constant_p.h
+psych_parser.o: $(hdrdir)/ruby/internal/core.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rarray.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rbasic.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rbignum.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rclass.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rdata.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rfile.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rhash.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/robject.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rregexp.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rstring.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rstruct.h
+psych_parser.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+psych_parser.o: $(hdrdir)/ruby/internal/ctype.h
+psych_parser.o: $(hdrdir)/ruby/internal/dllexport.h
+psych_parser.o: $(hdrdir)/ruby/internal/dosish.h
+psych_parser.o: $(hdrdir)/ruby/internal/error.h
+psych_parser.o: $(hdrdir)/ruby/internal/eval.h
+psych_parser.o: $(hdrdir)/ruby/internal/event.h
+psych_parser.o: $(hdrdir)/ruby/internal/fl_type.h
+psych_parser.o: $(hdrdir)/ruby/internal/gc.h
+psych_parser.o: $(hdrdir)/ruby/internal/glob.h
+psych_parser.o: $(hdrdir)/ruby/internal/globals.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/attribute.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/builtin.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/extension.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/feature.h
+psych_parser.o: $(hdrdir)/ruby/internal/has/warning.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/array.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/bignum.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/class.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/compar.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/complex.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/cont.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/dir.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/enum.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/error.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/eval.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/gc.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/hash.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/io.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/load.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/marshal.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/numeric.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/object.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/parse.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/proc.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/process.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/random.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/range.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/rational.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/re.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/ruby.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/select.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/signal.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/string.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/struct.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/thread.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/time.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/variable.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/vm.h
+psych_parser.o: $(hdrdir)/ruby/internal/interpreter.h
+psych_parser.o: $(hdrdir)/ruby/internal/iterator.h
+psych_parser.o: $(hdrdir)/ruby/internal/memory.h
+psych_parser.o: $(hdrdir)/ruby/internal/method.h
+psych_parser.o: $(hdrdir)/ruby/internal/module.h
+psych_parser.o: $(hdrdir)/ruby/internal/newobj.h
+psych_parser.o: $(hdrdir)/ruby/internal/rgengc.h
+psych_parser.o: $(hdrdir)/ruby/internal/scan_args.h
+psych_parser.o: $(hdrdir)/ruby/internal/special_consts.h
+psych_parser.o: $(hdrdir)/ruby/internal/static_assert.h
+psych_parser.o: $(hdrdir)/ruby/internal/stdalign.h
+psych_parser.o: $(hdrdir)/ruby/internal/stdbool.h
+psych_parser.o: $(hdrdir)/ruby/internal/symbol.h
+psych_parser.o: $(hdrdir)/ruby/internal/token_paste.h
+psych_parser.o: $(hdrdir)/ruby/internal/value.h
+psych_parser.o: $(hdrdir)/ruby/internal/value_type.h
+psych_parser.o: $(hdrdir)/ruby/internal/variable.h
+psych_parser.o: $(hdrdir)/ruby/internal/warning_push.h
+psych_parser.o: $(hdrdir)/ruby/internal/xmalloc.h
+psych_parser.o: $(hdrdir)/ruby/assert.h
psych_parser.o: $(hdrdir)/ruby/backward.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_parser.o: $(hdrdir)/ruby/backward/2/stdarg.h
psych_parser.o: $(hdrdir)/ruby/defines.h
psych_parser.o: $(hdrdir)/ruby/encoding.h
psych_parser.o: $(hdrdir)/ruby/intern.h
@@ -49,7 +502,6 @@ psych_parser.o: $(hdrdir)/ruby/oniguruma.h
psych_parser.o: $(hdrdir)/ruby/ruby.h
psych_parser.o: $(hdrdir)/ruby/st.h
psych_parser.o: $(hdrdir)/ruby/subst.h
-psych_parser.o: $(top_srcdir)/include/ruby.h
psych_parser.o: psych.h
psych_parser.o: psych_emitter.h
psych_parser.o: psych_parser.c
@@ -58,7 +510,158 @@ psych_parser.o: psych_to_ruby.h
psych_parser.o: psych_yaml_tree.h
psych_to_ruby.o: $(RUBY_EXTCONF_H)
psych_to_ruby.o: $(arch_hdrdir)/ruby/config.h
+psych_to_ruby.o: $(hdrdir)/ruby.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/anyargs.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/assume.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/artificial.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/cold.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/const.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/error.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/format.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noalias.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noinline.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/pure.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/restrict.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/warning.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/weakref.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/cast.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_is.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/compiler_since.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/config.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/constant_p.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rarray.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rbasic.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rbignum.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rclass.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rdata.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rfile.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rhash.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/robject.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rregexp.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rstring.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rstruct.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/ctype.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/dllexport.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/dosish.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/error.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/eval.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/event.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/fl_type.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/gc.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/glob.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/globals.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/attribute.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/builtin.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/extension.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/feature.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/has/warning.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/array.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/bignum.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/class.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/compar.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/complex.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/cont.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/dir.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/enum.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/error.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/eval.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/gc.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/hash.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/io.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/load.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/marshal.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/numeric.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/object.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/parse.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/proc.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/process.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/random.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/range.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/rational.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/re.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/ruby.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/select.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/signal.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/string.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/struct.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/thread.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/time.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/variable.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/vm.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/interpreter.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/iterator.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/memory.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/method.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/module.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/newobj.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/rgengc.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/scan_args.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/special_consts.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/static_assert.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/stdalign.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/stdbool.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/symbol.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/token_paste.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/value.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/value_type.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/variable.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/warning_push.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/xmalloc.h
+psych_to_ruby.o: $(hdrdir)/ruby/assert.h
psych_to_ruby.o: $(hdrdir)/ruby/backward.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_to_ruby.o: $(hdrdir)/ruby/backward/2/stdarg.h
psych_to_ruby.o: $(hdrdir)/ruby/defines.h
psych_to_ruby.o: $(hdrdir)/ruby/encoding.h
psych_to_ruby.o: $(hdrdir)/ruby/intern.h
@@ -68,7 +671,6 @@ psych_to_ruby.o: $(hdrdir)/ruby/oniguruma.h
psych_to_ruby.o: $(hdrdir)/ruby/ruby.h
psych_to_ruby.o: $(hdrdir)/ruby/st.h
psych_to_ruby.o: $(hdrdir)/ruby/subst.h
-psych_to_ruby.o: $(top_srcdir)/include/ruby.h
psych_to_ruby.o: psych.h
psych_to_ruby.o: psych_emitter.h
psych_to_ruby.o: psych_parser.h
@@ -77,7 +679,158 @@ psych_to_ruby.o: psych_to_ruby.h
psych_to_ruby.o: psych_yaml_tree.h
psych_yaml_tree.o: $(RUBY_EXTCONF_H)
psych_yaml_tree.o: $(arch_hdrdir)/ruby/config.h
+psych_yaml_tree.o: $(hdrdir)/ruby.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/anyargs.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/assume.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/artificial.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/cold.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/const.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/error.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/format.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noalias.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noinline.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/pure.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/restrict.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/warning.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/weakref.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/cast.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_is.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/compiler_since.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/config.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/constant_p.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rarray.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rbasic.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rbignum.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rclass.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rdata.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rfile.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rhash.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/robject.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rregexp.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rstring.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rstruct.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/ctype.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/dllexport.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/dosish.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/error.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/eval.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/event.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/fl_type.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/gc.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/glob.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/globals.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/attribute.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/builtin.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/extension.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/feature.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/has/warning.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/array.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/bignum.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/class.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/compar.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/complex.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/cont.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/dir.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/enum.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/error.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/eval.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/gc.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/hash.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/io.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/load.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/marshal.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/numeric.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/object.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/parse.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/proc.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/process.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/random.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/range.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/rational.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/re.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/ruby.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/select.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/signal.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/string.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/struct.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/thread.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/time.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/variable.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/vm.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/interpreter.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/iterator.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/memory.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/method.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/module.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/newobj.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/rgengc.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/scan_args.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/special_consts.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/static_assert.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/stdalign.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/stdbool.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/symbol.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/token_paste.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/value.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/value_type.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/variable.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/warning_push.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/xmalloc.h
+psych_yaml_tree.o: $(hdrdir)/ruby/assert.h
psych_yaml_tree.o: $(hdrdir)/ruby/backward.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/assume.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/attributes.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/bool.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/inttypes.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/limits.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/long_long.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/stdalign.h
+psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/stdarg.h
psych_yaml_tree.o: $(hdrdir)/ruby/defines.h
psych_yaml_tree.o: $(hdrdir)/ruby/encoding.h
psych_yaml_tree.o: $(hdrdir)/ruby/intern.h
@@ -87,7 +840,6 @@ psych_yaml_tree.o: $(hdrdir)/ruby/oniguruma.h
psych_yaml_tree.o: $(hdrdir)/ruby/ruby.h
psych_yaml_tree.o: $(hdrdir)/ruby/st.h
psych_yaml_tree.o: $(hdrdir)/ruby/subst.h
-psych_yaml_tree.o: $(top_srcdir)/include/ruby.h
psych_yaml_tree.o: psych.h
psych_yaml_tree.o: psych_emitter.h
psych_yaml_tree.o: psych_parser.h
diff --git a/ext/psych/extconf.rb b/ext/psych/extconf.rb
index 6d8390ebe5..857f8e68c4 100644
--- a/ext/psych/extconf.rb
+++ b/ext/psych/extconf.rb
@@ -13,8 +13,10 @@ if enable_config("bundled-libyaml", false) || !(find_header('yaml.h') && find_li
$VPATH << "$(srcdir)/yaml"
$INCFLAGS << " -I$(srcdir)/yaml"
- $srcs = Dir.glob("#{$srcdir}/{,yaml/}*.c").map {|n| File.basename(n)}
+ $srcs = Dir.glob("#{$srcdir}/{,yaml/}*.c").map {|n| File.basename(n)}.sort
+ header = 'yaml/yaml.h'
+ header = "{$(VPATH)}#{header}" if $nmake
if have_macro("_WIN32")
$CPPFLAGS << " -DYAML_DECLARE_STATIC -DHAVE_CONFIG_H"
end
@@ -34,6 +36,8 @@ if enable_config("bundled-libyaml", false) || !(find_header('yaml.h') && find_li
have_header 'config.h'
end
-create_makefile 'psych'
+create_makefile 'psych' do |mk|
+ mk << "YAML_H = #{header}".strip << "\n"
+end
# :startdoc:
diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb
index e93ac8f406..34d2218549 100644
--- a/ext/psych/lib/psych.rb
+++ b/ext/psych/lib/psych.rb
@@ -3,13 +3,14 @@ require 'psych/versions'
case RUBY_ENGINE
when 'jruby'
require 'psych_jars'
- org.jruby.ext.psych.PsychLibrary.new.load(JRuby.runtime, false)
-else
- begin
- require "#{RUBY_VERSION[/\d+\.\d+/]}/psych.so"
- rescue LoadError
- require 'psych.so'
+ if JRuby::Util.respond_to?(:load_ext)
+ JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary')
+ else
+ require 'java'; require 'jruby'
+ org.jruby.ext.psych.PsychLibrary.new.load(JRuby.runtime, false)
end
+else
+ require 'psych.so'
end
require 'psych/nodes'
require 'psych/streaming'
@@ -31,7 +32,7 @@ require 'psych/class_loader'
# = Overview
#
# Psych is a YAML parser and emitter.
-# Psych leverages libyaml [Home page: http://pyyaml.org/wiki/LibYAML]
+# Psych leverages libyaml [Home page: https://pyyaml.org/wiki/LibYAML]
# or [HG repo: https://bitbucket.org/xi/libyaml] for its YAML parsing
# and emitting capabilities. In addition to wrapping libyaml, Psych also
# knows how to serialize and de-serialize most Ruby objects to and from
@@ -73,12 +74,15 @@ require 'psych/class_loader'
#
# ==== Reading from a string
#
-# Psych.load("--- a") # => 'a'
-# Psych.load("---\n - a\n - b") # => ['a', 'b']
+# Psych.safe_load("--- a") # => 'a'
+# Psych.safe_load("---\n - a\n - b") # => ['a', 'b']
+# # From a trusted string:
+# Psych.load("--- !ruby/range\nbegin: 0\nend: 42\nexcl: false\n") # => 0..42
#
# ==== Reading from a file
#
-# Psych.load_file("database.yml")
+# Psych.safe_load_file("data.yml", permitted_classes: [Date])
+# Psych.load_file("trusted_database.yml")
#
# ==== Exception handling
#
@@ -198,12 +202,13 @@ require 'psych/class_loader'
#
# ==== Receiving an events stream
#
-# parser = Psych::Parser.new(Psych::Handlers::Recorder.new)
+# recorder = Psych::Handlers::Recorder.new
+# parser = Psych::Parser.new(recorder)
#
# parser.parse("---\n - a\n - b")
-# parser.events # => [list of [event, args] lists]
-# # event is one of: Psych::Handler::EVENTS
-# # args are the arguments passed to the event
+# recorder.events # => [list of [event, args] lists]
+# # event is one of: Psych::Handler::EVENTS
+# # args are the arguments passed to the event
#
# === Emitting
#
@@ -228,15 +233,17 @@ require 'psych/class_loader'
module Psych
# The version of libyaml Psych is using
- LIBYAML_VERSION = Psych.libyaml_version.join '.'
-
- FALLBACK = Struct.new :to_ruby # :nodoc:
+ LIBYAML_VERSION = Psych.libyaml_version.join('.').freeze
+ # Deprecation guard
+ NOT_GIVEN = Object.new.freeze
+ private_constant :NOT_GIVEN
###
# Load +yaml+ in to a Ruby data structure. If multiple documents are
# provided, the object contained in the first document will be returned.
- # +filename+ will be used in the exception message if any exception is raised
- # while parsing.
+ # +filename+ will be used in the exception message if any exception
+ # is raised while parsing. If +yaml+ is empty, it returns
+ # the specified +fallback+ return value, which defaults to +false+.
#
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
#
@@ -246,15 +253,35 @@ module Psych
# Psych.load("---\n - a\n - b") # => ['a', 'b']
#
# begin
- # Psych.load("--- `", "file.txt")
+ # Psych.load("--- `", filename: "file.txt")
# rescue Psych::SyntaxError => ex
# ex.file # => 'file.txt'
# ex.message # => "(file.txt): found character that cannot start any token"
# end
- def self.load yaml, filename = nil, fallback = false
- result = parse(yaml, filename, fallback)
- result ? result.to_ruby : result
+ #
+ # When the optional +symbolize_names+ keyword argument is set to a
+ # true value, returns symbols for keys in Hash objects (default: strings).
+ #
+ # Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
+ # Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
+ #
+ # Raises a TypeError when `yaml` parameter is NilClass
+ #
+ # NOTE: This method *should not* be used to parse untrusted documents, such as
+ # YAML documents that are supplied via user input. Instead, please use the
+ # safe_load method.
+ #
+ def self.unsafe_load yaml, legacy_filename = NOT_GIVEN, filename: nil, fallback: false, symbolize_names: false, freeze: false
+ if legacy_filename != NOT_GIVEN
+ warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load is deprecated. Use keyword argument like Psych.load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
+ filename = legacy_filename
+ end
+
+ result = parse(yaml, filename: filename)
+ return fallback unless result
+ result.to_ruby(symbolize_names: symbolize_names, freeze: freeze)
end
+ class << self; alias :load :unsafe_load; end
###
# Safely load the yaml string in +yaml+. By default, only the following
@@ -269,40 +296,71 @@ module Psych
# * Hash
#
# Recursive data structures are not allowed by default. Arbitrary classes
- # can be allowed by adding those classes to the +whitelist+. They are
+ # can be allowed by adding those classes to the +permitted_classes+ keyword argument. They are
# additive. For example, to allow Date deserialization:
#
- # Psych.safe_load(yaml, [Date])
+ # Psych.safe_load(yaml, permitted_classes: [Date])
#
# Now the Date class can be loaded in addition to the classes listed above.
#
- # Aliases can be explicitly allowed by changing the +aliases+ parameter.
+ # Aliases can be explicitly allowed by changing the +aliases+ keyword argument.
# For example:
#
# x = []
# x << x
# yaml = Psych.dump x
# Psych.safe_load yaml # => raises an exception
- # Psych.safe_load yaml, [], [], true # => loads the aliases
+ # Psych.safe_load yaml, aliases: true # => loads the aliases
#
# A Psych::DisallowedClass exception will be raised if the yaml contains a
- # class that isn't in the whitelist.
+ # class that isn't in the +permitted_classes+ list.
#
# A Psych::BadAlias exception will be raised if the yaml contains aliases
- # but the +aliases+ parameter is set to false.
- def self.safe_load yaml, whitelist_classes = [], whitelist_symbols = [], aliases = false, filename = nil
- result = parse(yaml, filename)
- return unless result
+ # but the +aliases+ keyword argument is set to false.
+ #
+ # +filename+ will be used in the exception message if any exception is raised
+ # while parsing.
+ #
+ # When the optional +symbolize_names+ keyword argument is set to a
+ # true value, returns symbols for keys in Hash objects (default: strings).
+ #
+ # Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"}
+ # Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
+ #
+ def self.safe_load yaml, legacy_permitted_classes = NOT_GIVEN, legacy_permitted_symbols = NOT_GIVEN, legacy_aliases = NOT_GIVEN, legacy_filename = NOT_GIVEN, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false
+ if legacy_permitted_classes != NOT_GIVEN
+ warn_with_uplevel 'Passing permitted_classes with the 2nd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_classes: ...) instead.', uplevel: 1 if $VERBOSE
+ permitted_classes = legacy_permitted_classes
+ end
- class_loader = ClassLoader::Restricted.new(whitelist_classes.map(&:to_s),
- whitelist_symbols.map(&:to_s))
- scanner = ScalarScanner.new class_loader
- if aliases
- visitor = Visitors::ToRuby.new scanner, class_loader
- else
- visitor = Visitors::NoAliasRuby.new scanner, class_loader
+ if legacy_permitted_symbols != NOT_GIVEN
+ warn_with_uplevel 'Passing permitted_symbols with the 3rd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_symbols: ...) instead.', uplevel: 1 if $VERBOSE
+ permitted_symbols = legacy_permitted_symbols
+ end
+
+ if legacy_aliases != NOT_GIVEN
+ warn_with_uplevel 'Passing aliases with the 4th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, aliases: ...) instead.', uplevel: 1 if $VERBOSE
+ aliases = legacy_aliases
+ end
+
+ if legacy_filename != NOT_GIVEN
+ warn_with_uplevel 'Passing filename with the 5th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
+ filename = legacy_filename
end
- visitor.accept result
+
+ result = parse(yaml, filename: filename)
+ return fallback unless result
+
+ class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s),
+ permitted_symbols.map(&:to_s))
+ scanner = ScalarScanner.new class_loader
+ visitor = if aliases
+ Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
+ else
+ Visitors::NoAliasRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
+ end
+ result = visitor.accept result
+ result
end
###
@@ -317,28 +375,40 @@ module Psych
# Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Document:0x00>
#
# begin
- # Psych.parse("--- `", "file.txt")
+ # Psych.parse("--- `", filename: "file.txt")
# rescue Psych::SyntaxError => ex
# ex.file # => 'file.txt'
# ex.message # => "(file.txt): found character that cannot start any token"
# end
#
# See Psych::Nodes for more information about YAML AST.
- def self.parse yaml, filename = nil, fallback = false
- parse_stream(yaml, filename) do |node|
+ def self.parse yaml, legacy_filename = NOT_GIVEN, filename: nil, fallback: NOT_GIVEN
+ if legacy_filename != NOT_GIVEN
+ warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse is deprecated. Use keyword argument like Psych.parse(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
+ filename = legacy_filename
+ end
+
+ parse_stream(yaml, filename: filename) do |node|
return node
end
- fallback
+
+ if fallback != NOT_GIVEN
+ warn_with_uplevel 'Passing the `fallback` keyword argument of Psych.parse is deprecated.', uplevel: 1 if $VERBOSE
+ fallback
+ else
+ false
+ end
end
###
# Parse a file at +filename+. Returns the Psych::Nodes::Document.
#
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
- def self.parse_file filename
- File.open filename, 'r:bom|utf-8' do |f|
- parse f, filename
+ def self.parse_file filename, fallback: false
+ result = File.open filename, 'r:bom|utf-8' do |f|
+ parse f, filename: filename
end
+ result || fallback
end
###
@@ -367,14 +437,21 @@ module Psych
# end
#
# begin
- # Psych.parse_stream("--- `", "file.txt")
+ # Psych.parse_stream("--- `", filename: "file.txt")
# rescue Psych::SyntaxError => ex
# ex.file # => 'file.txt'
# ex.message # => "(file.txt): found character that cannot start any token"
# end
#
+ # Raises a TypeError when NilClass is passed.
+ #
# See Psych::Nodes for more information about YAML AST.
- def self.parse_stream yaml, filename = nil, &block
+ def self.parse_stream yaml, legacy_filename = NOT_GIVEN, filename: nil, &block
+ if legacy_filename != NOT_GIVEN
+ warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse_stream is deprecated. Use keyword argument like Psych.parse_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
+ filename = legacy_filename
+ end
+
if block_given?
parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
parser.parse yaml, filename
@@ -396,6 +473,24 @@ module Psych
# to control the output format. If an IO object is passed in, the YAML will
# be dumped to that IO object.
#
+ # Currently supported options are:
+ #
+ # [<tt>:indentation</tt>] Number of space characters used to indent.
+ # Acceptable value should be in <tt>0..9</tt> range,
+ # otherwise option is ignored.
+ #
+ # Default: <tt>2</tt>.
+ # [<tt>:line_width</tt>] Max character to wrap line at.
+ #
+ # Default: <tt>0</tt> (meaning "wrap at 81").
+ # [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
+ # strictly formal).
+ #
+ # Default: <tt>false</tt>.
+ # [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
+ #
+ # Default: <tt>false</tt>.
+ #
# Example:
#
# # Dump an array, get back a YAML string
@@ -405,10 +500,10 @@ module Psych
# Psych.dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
#
# # Dump an array with indentation set
- # Psych.dump(['a', ['b']], :indentation => 3) # => "---\n- a\n- - b\n"
+ # Psych.dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
#
# # Dump an array to an IO with indentation set
- # Psych.dump(['a', ['b']], StringIO.new, :indentation => 3)
+ # Psych.dump(['a', ['b']], StringIO.new, indentation: 3)
def self.dump o, io = nil, options = {}
if Hash === io
options = io
@@ -457,55 +552,114 @@ module Psych
# end
# list # => ['foo', 'bar']
#
- def self.load_stream yaml, filename = nil
- if block_given?
- parse_stream(yaml, filename) do |node|
- yield node.to_ruby
- end
- else
- parse_stream(yaml, filename).children.map { |child| child.to_ruby }
+ def self.load_stream yaml, legacy_filename = NOT_GIVEN, filename: nil, fallback: [], **kwargs
+ if legacy_filename != NOT_GIVEN
+ warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load_stream is deprecated. Use keyword argument like Psych.load_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
+ filename = legacy_filename
end
+
+ result = if block_given?
+ parse_stream(yaml, filename: filename) do |node|
+ yield node.to_ruby(**kwargs)
+ end
+ else
+ parse_stream(yaml, filename: filename).children.map { |node| node.to_ruby(**kwargs) }
+ end
+
+ return fallback if result.is_a?(Array) && result.empty?
+ result
end
###
# Load the document contained in +filename+. Returns the yaml contained in
# +filename+ as a Ruby object, or if the file is empty, it returns
- # the specified default return value, which defaults to an empty Hash
- def self.load_file filename, fallback = false
+ # the specified +fallback+ return value, which defaults to +false+.
+ #
+ # NOTE: This method *should not* be used to parse untrusted documents, such as
+ # YAML documents that are supplied via user input. Instead, please use the
+ # safe_load_file method.
+ def self.unsafe_load_file filename, **kwargs
File.open(filename, 'r:bom|utf-8') { |f|
- self.load f, filename, FALLBACK.new(fallback)
+ self.unsafe_load f, filename: filename, **kwargs
+ }
+ end
+ class << self; alias :load_file :unsafe_load_file; end
+
+ ###
+ # Safely loads the document contained in +filename+. Returns the yaml contained in
+ # +filename+ as a Ruby object, or if the file is empty, it returns
+ # the specified +fallback+ return value, which defaults to +false+.
+ # See safe_load for options.
+ def self.safe_load_file filename, **kwargs
+ File.open(filename, 'r:bom|utf-8') { |f|
+ self.safe_load f, filename: filename, **kwargs
}
end
# :stopdoc:
- @domain_types = {}
def self.add_domain_type domain, type_tag, &block
key = ['tag', domain, type_tag].join ':'
- @domain_types[key] = [key, block]
- @domain_types["tag:#{type_tag}"] = [key, block]
+ domain_types[key] = [key, block]
+ domain_types["tag:#{type_tag}"] = [key, block]
end
def self.add_builtin_type type_tag, &block
domain = 'yaml.org,2002'
key = ['tag', domain, type_tag].join ':'
- @domain_types[key] = [key, block]
+ domain_types[key] = [key, block]
end
def self.remove_type type_tag
- @domain_types.delete type_tag
+ domain_types.delete type_tag
end
- @load_tags = {}
- @dump_tags = {}
def self.add_tag tag, klass
- @load_tags[tag] = klass.name
- @dump_tags[klass] = tag
+ load_tags[tag] = klass.name
+ dump_tags[klass] = tag
+ end
+
+ # Workaround for emulating `warn '...', uplevel: 1` in Ruby 2.4 or lower.
+ def self.warn_with_uplevel(message, uplevel: 1)
+ at = parse_caller(caller[uplevel]).join(':')
+ warn "#{at}: #{message}"
+ end
+
+ def self.parse_caller(at)
+ if /^(.+?):(\d+)(?::in `.*')?/ =~ at
+ file = $1
+ line = $2.to_i
+ [file, line]
+ end
end
+ private_class_method :warn_with_uplevel, :parse_caller
class << self
- attr_accessor :load_tags
- attr_accessor :dump_tags
- attr_accessor :domain_types
+ if defined?(Ractor)
+ require 'forwardable'
+ extend Forwardable
+
+ class Config
+ attr_accessor :load_tags, :dump_tags, :domain_types
+ def initialize
+ @load_tags = {}
+ @dump_tags = {}
+ @domain_types = {}
+ end
+ end
+
+ def config
+ Ractor.current[:PsychConfig] ||= Config.new
+ end
+
+ def_delegators :config, :load_tags, :dump_tags, :domain_types, :load_tags=, :dump_tags=, :domain_types=
+ else
+ attr_accessor :load_tags
+ attr_accessor :dump_tags
+ attr_accessor :domain_types
+ end
end
+ self.load_tags = {}
+ self.dump_tags = {}
+ self.domain_types = {}
# :startdoc:
end
diff --git a/ext/psych/lib/psych/class_loader.rb b/ext/psych/lib/psych/class_loader.rb
index cfca86845a..a5d1a7a4a9 100644
--- a/ext/psych/lib/psych/class_loader.rb
+++ b/ext/psych/lib/psych/class_loader.rb
@@ -35,9 +35,11 @@ module Psych
constants.each do |const|
konst = const_get const
- define_method(const.to_s.downcase) do
- load konst
- end
+ class_eval <<~RUBY
+ def #{const.to_s.downcase}
+ load #{konst.inspect}
+ end
+ RUBY
end
private
@@ -69,7 +71,7 @@ module Psych
rescue
nil
end
- }.compact]
+ }.compact].freeze
class Restricted < ClassLoader
def initialize classes, symbols
diff --git a/ext/psych/lib/psych/handler.rb b/ext/psych/lib/psych/handler.rb
index 1074c18f9e..ad7249ff77 100644
--- a/ext/psych/lib/psych/handler.rb
+++ b/ext/psych/lib/psych/handler.rb
@@ -105,7 +105,7 @@ module Psych
# - first element
# - *ponies
#
- # &ponies is the achor, *ponies is the alias. In this case, alias is
+ # &ponies is the anchor, *ponies is the alias. In this case, alias is
# called with "ponies".
def alias anchor
end
@@ -119,7 +119,7 @@ module Psych
# +tag+ is an associated tag or nil
# +plain+ is a boolean value
# +quoted+ is a boolean value
- # +style+ is an integer idicating the string style
+ # +style+ is an integer indicating the string style
#
# See the constants in Psych::Nodes::Scalar for the possible values of
# +style+
@@ -242,6 +242,11 @@ module Psych
end
###
+ # Called before each event with line/column information.
+ def event_location(start_line, start_column, end_line, end_column)
+ end
+
+ ###
# Is this handler a streaming handler?
def streaming?
false
diff --git a/ext/psych/lib/psych/nodes/alias.rb b/ext/psych/lib/psych/nodes/alias.rb
index 8131a4befb..6da655f0fd 100644
--- a/ext/psych/lib/psych/nodes/alias.rb
+++ b/ext/psych/lib/psych/nodes/alias.rb
@@ -14,6 +14,8 @@ module Psych
def initialize anchor
@anchor = anchor
end
+
+ def alias?; true; end
end
end
end
diff --git a/ext/psych/lib/psych/nodes/document.rb b/ext/psych/lib/psych/nodes/document.rb
index 3cd418eaf3..f57410d636 100644
--- a/ext/psych/lib/psych/nodes/document.rb
+++ b/ext/psych/lib/psych/nodes/document.rb
@@ -56,6 +56,8 @@ module Psych
def root
children.first
end
+
+ def document?; true; end
end
end
end
diff --git a/ext/psych/lib/psych/nodes/mapping.rb b/ext/psych/lib/psych/nodes/mapping.rb
index b921ddc862..d49678cb0e 100644
--- a/ext/psych/lib/psych/nodes/mapping.rb
+++ b/ext/psych/lib/psych/nodes/mapping.rb
@@ -52,6 +52,8 @@ module Psych
@implicit = implicit
@style = style
end
+
+ def mapping?; true; end
end
end
end
diff --git a/ext/psych/lib/psych/nodes/node.rb b/ext/psych/lib/psych/nodes/node.rb
index 1c7672164d..05cb08dac0 100644
--- a/ext/psych/lib/psych/nodes/node.rb
+++ b/ext/psych/lib/psych/nodes/node.rb
@@ -17,6 +17,18 @@ module Psych
# An associated tag
attr_reader :tag
+ # The line number where this node start
+ attr_accessor :start_line
+
+ # The column number where this node start
+ attr_accessor :start_column
+
+ # The line number where this node ends
+ attr_accessor :end_line
+
+ # The column number where this node ends
+ attr_accessor :end_column
+
# Create a new Psych::Nodes::Node
def initialize
@children = []
@@ -34,8 +46,8 @@ module Psych
# Convert this node to Ruby.
#
# See also Psych::Visitors::ToRuby
- def to_ruby
- Visitors::ToRuby.create.accept(self)
+ def to_ruby(symbolize_names: false, freeze: false)
+ Visitors::ToRuby.create(symbolize_names: symbolize_names, freeze: freeze).accept(self)
end
alias :transform :to_ruby
@@ -51,6 +63,13 @@ module Psych
io
end
alias :to_yaml :yaml
+
+ def alias?; false; end
+ def document?; false; end
+ def mapping?; false; end
+ def scalar?; false; end
+ def sequence?; false; end
+ def stream?; false; end
end
end
end
diff --git a/ext/psych/lib/psych/nodes/scalar.rb b/ext/psych/lib/psych/nodes/scalar.rb
index b448858831..5550b616a3 100644
--- a/ext/psych/lib/psych/nodes/scalar.rb
+++ b/ext/psych/lib/psych/nodes/scalar.rb
@@ -50,7 +50,7 @@ module Psych
# +tag+ is an associated tag or nil
# +plain+ is a boolean value
# +quoted+ is a boolean value
- # +style+ is an integer idicating the string style
+ # +style+ is an integer indicating the string style
#
# == See Also
#
@@ -63,6 +63,8 @@ module Psych
@quoted = quoted
@style = style
end
+
+ def scalar?; true; end
end
end
end
diff --git a/ext/psych/lib/psych/nodes/sequence.rb b/ext/psych/lib/psych/nodes/sequence.rb
index 77c2c602b9..740f1938a4 100644
--- a/ext/psych/lib/psych/nodes/sequence.rb
+++ b/ext/psych/lib/psych/nodes/sequence.rb
@@ -77,6 +77,8 @@ module Psych
@implicit = implicit
@style = style
end
+
+ def sequence?; true; end
end
end
end
diff --git a/ext/psych/lib/psych/nodes/stream.rb b/ext/psych/lib/psych/nodes/stream.rb
index 2474fe62c4..b525217821 100644
--- a/ext/psych/lib/psych/nodes/stream.rb
+++ b/ext/psych/lib/psych/nodes/stream.rb
@@ -33,6 +33,8 @@ module Psych
super()
@encoding = encoding
end
+
+ def stream?; true; end
end
end
end
diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb
index 29c156c212..d565a336e8 100644
--- a/ext/psych/lib/psych/scalar_scanner.rb
+++ b/ext/psych/lib/psych/scalar_scanner.rb
@@ -14,16 +14,15 @@ module Psych
|\.(nan|NaN|NAN)(?# not a number))$/x
# Taken from http://yaml.org/type/int.html
- INTEGER = /^(?:[-+]?0b[0-1_]+ (?# base 2)
- |[-+]?0[0-7_]+ (?# base 8)
- |[-+]?(?:0|[1-9][0-9_]*) (?# base 10)
- |[-+]?0x[0-9a-fA-F_]+ (?# base 16))$/x
+ INTEGER = /^(?:[-+]?0b[0-1_,]+ (?# base 2)
+ |[-+]?0[0-7_,]+ (?# base 8)
+ |[-+]?(?:0|[1-9][0-9_,]*) (?# base 10)
+ |[-+]?0x[0-9a-fA-F_,]+ (?# base 16))$/x
attr_reader :class_loader
# Create a new scanner
def initialize class_loader
- @string_cache = {}
@symbol_cache = {}
@class_loader = class_loader
end
@@ -31,81 +30,70 @@ module Psych
# Tokenize +string+ returning the Ruby object
def tokenize string
return nil if string.empty?
- return string if @string_cache.key?(string)
return @symbol_cache[string] if @symbol_cache.key?(string)
- case string
# Check for a String type, being careful not to get caught by hash keys, hex values, and
# special floats (e.g., -.inf).
- when /^[^\d\.:-]?[A-Za-z_\s!@#\$%\^&\*\(\)\{\}\<\>\|\/\\~;=]+/, /\n/
- if string.length > 5
- @string_cache[string] = true
- return string
- end
+ if string.match?(/^[^\d\.:-]?[A-Za-z_\s!@#\$%\^&\*\(\)\{\}\<\>\|\/\\~;=]+/) || string.match?(/\n/)
+ return string if string.length > 5
- case string
- when /^[^ytonf~]/i
- @string_cache[string] = true
+ if string.match?(/^[^ytonf~]/i)
string
- when '~', /^null$/i
+ elsif string == '~' || string.match?(/^null$/i)
nil
- when /^(yes|true|on)$/i
+ elsif string.match?(/^(yes|true|on)$/i)
true
- when /^(no|false|off)$/i
+ elsif string.match?(/^(no|false|off)$/i)
false
else
- @string_cache[string] = true
string
end
- when TIME
+ elsif string.match?(TIME)
begin
parse_time string
rescue ArgumentError
string
end
- when /^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/
+ elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/)
require 'date'
begin
class_loader.date.strptime(string, '%Y-%m-%d')
rescue ArgumentError
string
end
- when /^\.inf$/i
+ elsif string.match?(/^\.inf$/i)
Float::INFINITY
- when /^-\.inf$/i
+ elsif string.match?(/^-\.inf$/i)
-Float::INFINITY
- when /^\.nan$/i
+ elsif string.match?(/^\.nan$/i)
Float::NAN
- when /^:./
+ elsif string.match?(/^:./)
if string =~ /^:(["'])(.*)\1/
@symbol_cache[string] = class_loader.symbolize($2.sub(/^:/, ''))
else
@symbol_cache[string] = class_loader.symbolize(string.sub(/^:/, ''))
end
- when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}$/
+ elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}$/)
i = 0
string.split(':').each_with_index do |n,e|
i += (n.to_i * 60 ** (e - 2).abs)
end
i
- when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}\.[0-9_]*$/
+ elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}\.[0-9_]*$/)
i = 0
string.split(':').each_with_index do |n,e|
i += (n.to_f * 60 ** (e - 2).abs)
end
i
- when FLOAT
- if string =~ /\A[-+]?\.\Z/
- @string_cache[string] = true
+ elsif string.match?(FLOAT)
+ if string.match?(/\A[-+]?\.\Z/)
string
else
Float(string.gsub(/[,_]|\.([Ee]|$)/, '\1'))
end
+ elsif string.match?(INTEGER)
+ parse_int string
else
- int = parse_int string.gsub(/[,_]/, '')
- return int if int
-
- @string_cache[string] = true
string
end
end
@@ -113,8 +101,7 @@ module Psych
###
# Parse and return an int from +string+
def parse_int string
- return unless INTEGER === string
- Integer(string)
+ Integer(string.gsub(/[,_]/, ''))
end
###
diff --git a/ext/psych/lib/psych/tree_builder.rb b/ext/psych/lib/psych/tree_builder.rb
index b10fd5c5cd..47a1695643 100644
--- a/ext/psych/lib/psych/tree_builder.rb
+++ b/ext/psych/lib/psych/tree_builder.rb
@@ -23,6 +23,18 @@ module Psych
@stack = []
@last = nil
@root = nil
+
+ @start_line = nil
+ @start_column = nil
+ @end_line = nil
+ @end_column = nil
+ end
+
+ def event_location(start_line, start_column, end_line, end_column)
+ @start_line = start_line
+ @start_column = start_column
+ @end_line = end_line
+ @end_column = end_column
end
%w{
@@ -32,12 +44,15 @@ module Psych
class_eval %{
def start_#{node.downcase}(anchor, tag, implicit, style)
n = Nodes::#{node}.new(anchor, tag, implicit, style)
+ set_start_location(n)
@last.children << n
push n
end
def end_#{node.downcase}
- pop
+ n = pop
+ set_end_location(n)
+ n
end
}
end
@@ -49,6 +64,7 @@ module Psych
# See Psych::Handler#start_document
def start_document version, tag_directives, implicit
n = Nodes::Document.new version, tag_directives, implicit
+ set_start_location(n)
@last.children << n
push n
end
@@ -60,26 +76,35 @@ module Psych
# See Psych::Handler#start_document
def end_document implicit_end = !streaming?
@last.implicit_end = implicit_end
- pop
+ n = pop
+ set_end_location(n)
+ n
end
def start_stream encoding
@root = Nodes::Stream.new(encoding)
+ set_start_location(@root)
push @root
end
def end_stream
- pop
+ n = pop
+ set_end_location(n)
+ n
end
def scalar value, anchor, tag, plain, quoted, style
s = Nodes::Scalar.new(value,anchor,tag,plain,quoted,style)
+ set_location(s)
@last.children << s
s
end
def alias anchor
- @last.children << Nodes::Alias.new(anchor)
+ a = Nodes::Alias.new(anchor)
+ set_location(a)
+ @last.children << a
+ a
end
private
@@ -93,5 +118,20 @@ module Psych
@last = @stack.last
x
end
+
+ def set_location(node)
+ set_start_location(node)
+ set_end_location(node)
+ end
+
+ def set_start_location(node)
+ node.start_line = @start_line
+ node.start_column = @start_column
+ end
+
+ def set_end_location(node)
+ node.end_line = @end_line
+ node.end_column = @end_column
+ end
end
end
diff --git a/ext/psych/lib/psych/versions.rb b/ext/psych/lib/psych/versions.rb
index 34a2c2607b..acb21336c4 100644
--- a/ext/psych/lib/psych/versions.rb
+++ b/ext/psych/lib/psych/versions.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
+
module Psych
- # The version is Psych you're using
- VERSION = '3.0.0.beta3'
+ # The version of Psych you are using
+ VERSION = '3.3.2'
if RUBY_ENGINE == 'jruby'
- DEFAULT_SNAKEYAML_VERSION = '1.18'.freeze
+ DEFAULT_SNAKEYAML_VERSION = '1.28'.freeze
end
end
diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb
index 74a52df866..4de7f80d33 100644
--- a/ext/psych/lib/psych/visitors/to_ruby.rb
+++ b/ext/psych/lib/psych/visitors/to_ruby.rb
@@ -12,39 +12,44 @@ module Psych
###
# This class walks a YAML AST, converting each node to Ruby
class ToRuby < Psych::Visitors::Visitor
- def self.create
+ def self.create(symbolize_names: false, freeze: false)
class_loader = ClassLoader.new
scanner = ScalarScanner.new class_loader
- new(scanner, class_loader)
+ new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze)
end
attr_reader :class_loader
- def initialize ss, class_loader
+ def initialize ss, class_loader, symbolize_names: false, freeze: false
super()
@st = {}
@ss = ss
+ @load_tags = Psych.load_tags
@domain_types = Psych.domain_types
@class_loader = class_loader
+ @symbolize_names = symbolize_names
+ @freeze = freeze
end
def accept target
result = super
- return result if @domain_types.empty? || !target.tag
- key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
- key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/
+ unless @domain_types.empty? || !target.tag
+ key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
+ key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/
- if @domain_types.key? key
- value, block = @domain_types[key]
- return block.call value, result
+ if @domain_types.key? key
+ value, block = @domain_types[key]
+ result = block.call value, result
+ end
end
+ result = deduplicate(result).freeze if @freeze
result
end
def deserialize o
- if klass = resolve_class(Psych.load_tags[o.tag])
+ if klass = resolve_class(@load_tags[o.tag])
instance = klass.allocate
if instance.respond_to?(:init_with)
@@ -124,7 +129,7 @@ module Psych
end
def visit_Psych_Nodes_Sequence o
- if klass = resolve_class(Psych.load_tags[o.tag])
+ if klass = resolve_class(@load_tags[o.tag])
instance = klass.allocate
if instance.respond_to?(:init_with)
@@ -156,8 +161,8 @@ module Psych
end
def visit_Psych_Nodes_Mapping o
- if Psych.load_tags[o.tag]
- return revive(resolve_class(Psych.load_tags[o.tag]), o)
+ if @load_tags[o.tag]
+ return revive(resolve_class(@load_tags[o.tag]), o)
end
return revive_hash(register(o, {}), o) unless o.tag
@@ -252,6 +257,8 @@ module Psych
e = build_exception((resolve_class($1) || class_loader.exception),
h.delete('message'))
+
+ e.set_backtrace h.delete('backtrace') if h.key? 'backtrace'
init_with(e, h, o)
when '!set', 'tag:yaml.org,2002:set'
@@ -320,6 +327,7 @@ module Psych
end
private
+
def register node, object
@st[node.anchor] = object if node.anchor
object
@@ -331,13 +339,12 @@ module Psych
list
end
- SHOVEL = '<<'
- def revive_hash hash, o
+ def revive_hash hash, o, tagged= false
o.children.each_slice(2) { |k,v|
key = accept(k)
val = accept(v)
- if key == SHOVEL && k.tag != "tag:yaml.org,2002:str"
+ if key == '<<' && k.tag != "tag:yaml.org,2002:str"
case v
when Nodes::Alias, Nodes::Mapping
begin
@@ -359,6 +366,12 @@ module Psych
hash[key] = val
end
else
+ if !tagged && @symbolize_names && key.is_a?(String)
+ key = key.to_sym
+ elsif !@freeze
+ key = deduplicate(key)
+ end
+
hash[key] = val
end
@@ -366,12 +379,32 @@ module Psych
hash
end
+ if RUBY_VERSION < '2.7'
+ def deduplicate key
+ if key.is_a?(String)
+ # It is important to untaint the string, otherwise it won't
+ # be deduplicated into an fstring, but simply frozen.
+ -(key.untaint)
+ else
+ key
+ end
+ end
+ else
+ def deduplicate key
+ if key.is_a?(String)
+ -key
+ else
+ key
+ end
+ end
+ end
+
def merge_key hash, key, val
end
def revive klass, node
s = register(node, klass.allocate)
- init_with(s, revive_hash({}, node), node)
+ init_with(s, revive_hash({}, node, true), node)
end
def init_with o, h, node
diff --git a/ext/psych/lib/psych/visitors/visitor.rb b/ext/psych/lib/psych/visitors/visitor.rb
index 3f4ba64e57..21052aa66f 100644
--- a/ext/psych/lib/psych/visitors/visitor.rb
+++ b/ext/psych/lib/psych/visitors/visitor.rb
@@ -8,12 +8,26 @@ module Psych
private
- DISPATCH = Hash.new do |hash, klass|
- hash[klass] = "visit_#{klass.name.gsub('::', '_')}"
+ # @api private
+ def self.dispatch_cache
+ Hash.new do |hash, klass|
+ hash[klass] = :"visit_#{klass.name.gsub('::', '_')}"
+ end.compare_by_identity
+ end
+
+ if defined?(Ractor)
+ def dispatch
+ @dispatch_cache ||= (Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache)
+ end
+ else
+ DISPATCH = dispatch_cache
+ def dispatch
+ DISPATCH
+ end
end
def visit target
- send DISPATCH[target.class], target
+ send dispatch[target.class], target
end
end
end
diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb
index cfed8f1814..bf7c0bb8ca 100644
--- a/ext/psych/lib/psych/visitors/yaml_tree.rb
+++ b/ext/psych/lib/psych/visitors/yaml_tree.rb
@@ -80,7 +80,7 @@ module Psych
raise(TypeError, "Can't dump #{target.class}") unless method
h[klass] = method
- end
+ end.compare_by_identity
end
def start encoding = Nodes::Stream::UTF8
@@ -181,41 +181,11 @@ module Psych
end
def visit_Exception o
- tag = ['!ruby/exception', o.class.name].join ':'
-
- @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
-
- {
- 'message' => private_iv_get(o, 'mesg'),
- 'backtrace' => private_iv_get(o, 'backtrace'),
- }.each do |k,v|
- next unless v
- @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
- accept v
- end
-
- dump_ivars o
-
- @emitter.end_mapping
+ dump_exception o, o.message.to_s
end
def visit_NameError o
- tag = ['!ruby/exception', o.class.name].join ':'
-
- @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
-
- {
- 'message' => o.message.to_s,
- 'backtrace' => private_iv_get(o, 'backtrace'),
- }.each do |k,v|
- next unless v
- @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
- accept v
- end
-
- dump_ivars o
-
- @emitter.end_mapping
+ dump_exception o, o.message.to_s
end
def visit_Regexp o
@@ -458,15 +428,6 @@ module Psych
node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
register(o, node)
- # Dump the elements
- accept 'elements'
- @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
- o.each do |k,v|
- accept k
- accept v
- end
- @emitter.end_mapping
-
# Dump the ivars
accept 'ivars'
@emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
@@ -476,6 +437,15 @@ module Psych
end
@emitter.end_mapping
+ # Dump the elements
+ accept 'elements'
+ @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
+ o.each do |k,v|
+ accept k
+ accept v
+ end
+ @emitter.end_mapping
+
@emitter.end_mapping
else
tag = "!ruby/hash:#{o.class}"
@@ -492,6 +462,24 @@ module Psych
def dump_list o
end
+ def dump_exception o, msg
+ tag = ['!ruby/exception', o.class.name].join ':'
+
+ @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
+
+ if msg
+ @emitter.scalar 'message', nil, nil, true, false, Nodes::Scalar::ANY
+ accept msg
+ end
+
+ @emitter.scalar 'backtrace', nil, nil, true, false, Nodes::Scalar::ANY
+ accept o.backtrace
+
+ dump_ivars o
+
+ @emitter.end_mapping
+ end
+
def format_time time
if time.utc?
time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
@@ -521,9 +509,9 @@ module Psych
def emit_coder c, o
case c.type
when :scalar
- @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY
+ @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
when :seq
- @emitter.start_sequence nil, c.tag, c.tag.nil?, Nodes::Sequence::BLOCK
+ @emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
c.seq.each do |thing|
accept thing
end
diff --git a/ext/psych/psych.c b/ext/psych/psych.c
index 3bb59bfc11..8af0bb6a5a 100644
--- a/ext/psych/psych.c
+++ b/ext/psych/psych.c
@@ -11,9 +11,9 @@ static VALUE libyaml_version(VALUE module)
yaml_get_version(&major, &minor, &patch);
- list[0] = INT2NUM((long)major);
- list[1] = INT2NUM((long)minor);
- list[2] = INT2NUM((long)patch);
+ list[0] = INT2NUM(major);
+ list[1] = INT2NUM(minor);
+ list[2] = INT2NUM(patch);
return rb_ary_new4((long)3, list);
}
@@ -22,6 +22,9 @@ VALUE mPsych;
void Init_psych(void)
{
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
+ RB_EXT_RACTOR_SAFE(true);
+ #endif
mPsych = rb_define_module("Psych");
rb_define_singleton_method(mPsych, "libyaml_version", libyaml_version, 0);
diff --git a/ext/psych/psych.gemspec b/ext/psych/psych.gemspec
index 054f209893..e9e36e6633 100644
--- a/ext/psych/psych.gemspec
+++ b/ext/psych/psych.gemspec
@@ -1,15 +1,19 @@
# -*- encoding: utf-8 -*-
# frozen_string_literal: true
+version_module = Module.new do
+ version_rb = File.join(__dir__, "lib/psych/versions.rb")
+ module_eval(File.read(version_rb), version_rb)
+end
+
Gem::Specification.new do |s|
s.name = "psych"
- s.version = "3.0.0.beta3"
+ s.version = version_module::Psych::VERSION
s.authors = ["Aaron Patterson", "SHIBATA Hiroshi", "Charles Oliver Nutter"]
s.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org", "headius@headius.com"]
- s.date = "2017-06-16"
s.summary = "Psych is a YAML parser and emitter"
s.description = <<-DESCRIPTION
-Psych is a YAML parser and emitter. Psych leverages libyaml[http://pyyaml.org/wiki/LibYAML]
+Psych is a YAML parser and emitter. Psych leverages libyaml[https://pyyaml.org/wiki/LibYAML]
for its YAML parsing and emitting capabilities. In addition to wrapping libyaml,
Psych also knows how to serialize and de-serialize most Ruby objects to and from the YAML format.
DESCRIPTION
@@ -19,8 +23,8 @@ DESCRIPTION
# for ruby core repository. It was generated by `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
s.files = [
- ".gitignore", ".travis.yml", "CHANGELOG.rdoc", "Gemfile", "Mavenfile", "README.md", "Rakefile", "bin/console",
- "bin/setup", "ext/psych/.gitignore", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h",
+ ".gitignore", "Gemfile", "LICENSE", "Mavenfile", "README.md", "Rakefile", "bin/console",
+ "bin/setup", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h",
"ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", "ext/psych/psych_parser.c", "ext/psych/psych_parser.h",
"ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h", "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h",
"ext/psych/yaml/LICENSE", "ext/psych/yaml/api.c", "ext/psych/yaml/config.h", "ext/psych/yaml/dumper.c",
@@ -39,26 +43,25 @@ DESCRIPTION
]
s.rdoc_options = ["--main", "README.md"]
- s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.md"]
+ s.extra_rdoc_files = ["README.md"]
- s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
- s.rubygems_version = "2.5.1"
+ s.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
s.required_rubygems_version = Gem::Requirement.new(">= 0")
- s.add_development_dependency 'rake-compiler', ">= 0.4.1"
- s.add_development_dependency 'minitest', "~> 5.0"
-
if RUBY_ENGINE == 'jruby'
s.platform = 'java'
s.files.concat [
- "ext/java/PsychEmitter.java", "ext/java/PsychLibrary.java", "ext/java/PsychParser.java", "ext/java/PsychToRuby.java",
- "ext/java/PsychYamlTree.java", "lib/psych_jars.rb", "lib/psych.jar"
+ "ext/java/org/jruby/ext/psych/PsychEmitter.java",
+ "ext/java/org/jruby/ext/psych/PsychLibrary.java",
+ "ext/java/org/jruby/ext/psych/PsychParser.java",
+ "ext/java/org/jruby/ext/psych/PsychToRuby.java",
+ "ext/java/org/jruby/ext/psych/PsychYamlTree.java",
+ "lib/psych_jars.rb",
+ "lib/psych.jar"
]
- s.requirements = "jar org.yaml:snakeyaml, 1.18"
+ s.requirements = "jar org.yaml:snakeyaml, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
s.add_dependency 'jar-dependencies', '>= 0.1.7'
- s.add_development_dependency 'ruby-maven'
else
s.extensions = ["ext/psych/extconf.rb"]
- s.add_development_dependency 'rake-compiler-dock', ">= 0.6.1"
end
end
diff --git a/ext/psych/psych_emitter.c b/ext/psych/psych_emitter.c
index bb4c4b226b..022ffa0946 100644
--- a/ext/psych/psych_emitter.c
+++ b/ext/psych/psych_emitter.c
@@ -272,8 +272,8 @@ static VALUE scalar(
yaml_scalar_event_initialize(
&event,
- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)),
- (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)),
+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
+ (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
(yaml_char_t*)StringValuePtr(value),
(int)RSTRING_LEN(value),
plain ? 1 : 0,
@@ -319,8 +319,8 @@ static VALUE start_sequence(
yaml_sequence_start_event_initialize(
&event,
- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)),
- (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)),
+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
+ (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
implicit ? 1 : 0,
(yaml_sequence_style_t)NUM2INT(style)
);
@@ -383,8 +383,8 @@ static VALUE start_mapping(
yaml_mapping_start_event_initialize(
&event,
- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)),
- (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)),
+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
+ (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
implicit ? 1 : 0,
(yaml_mapping_style_t)NUM2INT(style)
);
@@ -432,7 +432,7 @@ static VALUE alias(VALUE self, VALUE anchor)
yaml_alias_event_initialize(
&event,
- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor))
+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor))
);
emit(emitter, &event);
@@ -521,6 +521,7 @@ static VALUE set_line_width(VALUE self, VALUE width)
void Init_psych_emitter(void)
{
+#undef rb_intern
VALUE psych = rb_define_module("Psych");
VALUE handler = rb_define_class_under(psych, "Handler", rb_cObject);
cPsychEmitter = rb_define_class_under(psych, "Emitter", handler);
diff --git a/ext/psych/psych_parser.c b/ext/psych/psych_parser.c
index 47ed8744b6..fd550b671a 100644
--- a/ext/psych/psych_parser.c
+++ b/ext/psych/psych_parser.c
@@ -1,7 +1,6 @@
#include <psych.h>
VALUE cPsychParser;
-VALUE ePsychSyntaxError;
static ID id_read;
static ID id_path;
@@ -16,6 +15,7 @@ static ID id_start_sequence;
static ID id_end_sequence;
static ID id_start_mapping;
static ID id_end_mapping;
+static ID id_event_location;
#define PSYCH_TRANSCODE(_str, _yaml_enc, _internal_enc) \
do { \
@@ -27,7 +27,7 @@ static ID id_end_mapping;
static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read)
{
VALUE io = (VALUE)data;
- VALUE string = rb_funcall(io, id_read, 1, INT2NUM(size));
+ VALUE string = rb_funcall(io, id_read, 1, SIZET2NUM(size));
*read = 0;
@@ -80,15 +80,18 @@ static VALUE allocate(VALUE klass)
static VALUE make_exception(yaml_parser_t * parser, VALUE path)
{
size_t line, column;
+ VALUE ePsychSyntaxError;
line = parser->context_mark.line + 1;
column = parser->context_mark.column + 1;
+ ePsychSyntaxError = rb_const_get(mPsych, rb_intern("SyntaxError"));
+
return rb_funcall(ePsychSyntaxError, rb_intern("new"), 6,
path,
- INT2NUM(line),
- INT2NUM(column),
- INT2NUM(parser->problem_offset),
+ SIZET2NUM(line),
+ SIZET2NUM(column),
+ SIZET2NUM(parser->problem_offset),
parser->problem ? rb_usascii_str_new2(parser->problem) : Qnil,
parser->context ? rb_usascii_str_new2(parser->context) : Qnil);
}
@@ -232,6 +235,12 @@ static VALUE protected_end_stream(VALUE handler)
return rb_funcall(handler, id_end_stream, 0);
}
+static VALUE protected_event_location(VALUE pointer)
+{
+ VALUE *args = (VALUE *)pointer;
+ return rb_funcall3(args[0], id_event_location, 4, args + 1);
+}
+
/*
* call-seq:
* parser.parse(yaml)
@@ -247,7 +256,6 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
yaml_parser_t * parser;
yaml_event_t event;
int done = 0;
- int tainted = 0;
int state = 0;
int parser_encoding = YAML_ANY_ENCODING;
int encoding = rb_utf8_encindex();
@@ -266,13 +274,10 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
yaml_parser_delete(parser);
yaml_parser_initialize(parser);
- if (OBJ_TAINTED(yaml)) tainted = 1;
-
if (rb_respond_to(yaml, id_read)) {
yaml = transcode_io(yaml, &parser_encoding);
yaml_parser_set_encoding(parser, parser_encoding);
yaml_parser_set_input(parser, io_reader, (void *)yaml);
- if (RTEST(rb_obj_is_kind_of(yaml, rb_cIO))) tainted = 1;
} else {
StringValue(yaml);
yaml = transcode_string(yaml, &parser_encoding);
@@ -285,6 +290,9 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
}
while(!done) {
+ VALUE event_args[5];
+ VALUE start_line, start_column, end_line, end_column;
+
if(!yaml_parser_parse(parser, &event)) {
VALUE exception;
@@ -295,13 +303,25 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
rb_exc_raise(exception);
}
+ start_line = SIZET2NUM(event.start_mark.line);
+ start_column = SIZET2NUM(event.start_mark.column);
+ end_line = SIZET2NUM(event.end_mark.line);
+ end_column = SIZET2NUM(event.end_mark.column);
+
+ event_args[0] = handler;
+ event_args[1] = start_line;
+ event_args[2] = start_column;
+ event_args[3] = end_line;
+ event_args[4] = end_column;
+ rb_protect(protected_event_location, (VALUE)event_args, &state);
+
switch(event.type) {
case YAML_STREAM_START_EVENT:
{
VALUE args[2];
args[0] = handler;
- args[1] = INT2NUM((long)event.data.stream_start.encoding);
+ args[1] = INT2NUM(event.data.stream_start.encoding);
rb_protect(protected_start_stream, (VALUE)args, &state);
}
break;
@@ -314,8 +334,8 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
VALUE version = event.data.document_start.version_directive ?
rb_ary_new3(
(long)2,
- INT2NUM((long)event.data.document_start.version_directive->major),
- INT2NUM((long)event.data.document_start.version_directive->minor)
+ INT2NUM(event.data.document_start.version_directive->major),
+ INT2NUM(event.data.document_start.version_directive->minor)
) : rb_ary_new();
if(event.data.document_start.tag_directives.start) {
@@ -328,13 +348,11 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
VALUE prefix = Qnil;
if(start->handle) {
handle = rb_str_new2((const char *)start->handle);
- if (tainted) OBJ_TAINT(handle);
PSYCH_TRANSCODE(handle, encoding, internal_enc);
}
if(start->prefix) {
prefix = rb_str_new2((const char *)start->prefix);
- if (tainted) OBJ_TAINT(prefix);
PSYCH_TRANSCODE(prefix, encoding, internal_enc);
}
@@ -363,7 +381,6 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
VALUE alias = Qnil;
if(event.data.alias.anchor) {
alias = rb_str_new2((const char *)event.data.alias.anchor);
- if (tainted) OBJ_TAINT(alias);
PSYCH_TRANSCODE(alias, encoding, internal_enc);
}
@@ -382,19 +399,16 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
(const char *)event.data.scalar.value,
(long)event.data.scalar.length
);
- if (tainted) OBJ_TAINT(val);
PSYCH_TRANSCODE(val, encoding, internal_enc);
if(event.data.scalar.anchor) {
anchor = rb_str_new2((const char *)event.data.scalar.anchor);
- if (tainted) OBJ_TAINT(anchor);
PSYCH_TRANSCODE(anchor, encoding, internal_enc);
}
if(event.data.scalar.tag) {
tag = rb_str_new2((const char *)event.data.scalar.tag);
- if (tainted) OBJ_TAINT(tag);
PSYCH_TRANSCODE(tag, encoding, internal_enc);
}
@@ -404,7 +418,7 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
quoted_implicit =
event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue;
- style = INT2NUM((long)event.data.scalar.style);
+ style = INT2NUM(event.data.scalar.style);
args[0] = handler;
args[1] = val;
@@ -424,21 +438,19 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
VALUE implicit, style;
if(event.data.sequence_start.anchor) {
anchor = rb_str_new2((const char *)event.data.sequence_start.anchor);
- if (tainted) OBJ_TAINT(anchor);
PSYCH_TRANSCODE(anchor, encoding, internal_enc);
}
tag = Qnil;
if(event.data.sequence_start.tag) {
tag = rb_str_new2((const char *)event.data.sequence_start.tag);
- if (tainted) OBJ_TAINT(tag);
PSYCH_TRANSCODE(tag, encoding, internal_enc);
}
implicit =
event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue;
- style = INT2NUM((long)event.data.sequence_start.style);
+ style = INT2NUM(event.data.sequence_start.style);
args[0] = handler;
args[1] = anchor;
@@ -460,20 +472,18 @@ static VALUE parse(int argc, VALUE *argv, VALUE self)
VALUE implicit, style;
if(event.data.mapping_start.anchor) {
anchor = rb_str_new2((const char *)event.data.mapping_start.anchor);
- if (tainted) OBJ_TAINT(anchor);
PSYCH_TRANSCODE(anchor, encoding, internal_enc);
}
if(event.data.mapping_start.tag) {
tag = rb_str_new2((const char *)event.data.mapping_start.tag);
- if (tainted) OBJ_TAINT(tag);
PSYCH_TRANSCODE(tag, encoding, internal_enc);
}
implicit =
event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue;
- style = INT2NUM((long)event.data.mapping_start.style);
+ style = INT2NUM(event.data.mapping_start.style);
args[0] = handler;
args[1] = anchor;
@@ -517,15 +527,16 @@ static VALUE mark(VALUE self)
TypedData_Get_Struct(self, yaml_parser_t, &psych_parser_type, parser);
mark_klass = rb_const_get_at(cPsychParser, rb_intern("Mark"));
- args[0] = INT2NUM(parser->mark.index);
- args[1] = INT2NUM(parser->mark.line);
- args[2] = INT2NUM(parser->mark.column);
+ args[0] = SIZET2NUM(parser->mark.index);
+ args[1] = SIZET2NUM(parser->mark.line);
+ args[2] = SIZET2NUM(parser->mark.column);
return rb_class_new_instance(3, args, mark_klass);
}
void Init_psych_parser(void)
{
+#undef rb_intern
#if 0
mPsych = rb_define_module("Psych");
#endif
@@ -546,23 +557,23 @@ void Init_psych_parser(void)
rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING));
rb_require("psych/syntax_error");
- ePsychSyntaxError = rb_const_get(mPsych, rb_intern("SyntaxError"));
rb_define_method(cPsychParser, "parse", parse, -1);
rb_define_method(cPsychParser, "mark", mark, 0);
- id_read = rb_intern("read");
- id_path = rb_intern("path");
- id_empty = rb_intern("empty");
- id_start_stream = rb_intern("start_stream");
- id_end_stream = rb_intern("end_stream");
- id_start_document = rb_intern("start_document");
- id_end_document = rb_intern("end_document");
- id_alias = rb_intern("alias");
- id_scalar = rb_intern("scalar");
- id_start_sequence = rb_intern("start_sequence");
- id_end_sequence = rb_intern("end_sequence");
- id_start_mapping = rb_intern("start_mapping");
- id_end_mapping = rb_intern("end_mapping");
+ id_read = rb_intern("read");
+ id_path = rb_intern("path");
+ id_empty = rb_intern("empty");
+ id_start_stream = rb_intern("start_stream");
+ id_end_stream = rb_intern("end_stream");
+ id_start_document = rb_intern("start_document");
+ id_end_document = rb_intern("end_document");
+ id_alias = rb_intern("alias");
+ id_scalar = rb_intern("scalar");
+ id_start_sequence = rb_intern("start_sequence");
+ id_end_sequence = rb_intern("end_sequence");
+ id_start_mapping = rb_intern("start_mapping");
+ id_end_mapping = rb_intern("end_mapping");
+ id_event_location = rb_intern("event_location");
}
/* vim: set noet sws=4 sw=4: */
diff --git a/ext/psych/psych_yaml_tree.c b/ext/psych/psych_yaml_tree.c
index bcf24d2070..225655d127 100644
--- a/ext/psych/psych_yaml_tree.c
+++ b/ext/psych/psych_yaml_tree.c
@@ -2,23 +2,11 @@
VALUE cPsychVisitorsYamlTree;
-/*
- * call-seq: private_iv_get(target, prop)
- *
- * Get the private instance variable +prop+ from +target+
- */
-static VALUE private_iv_get(VALUE self, VALUE target, VALUE prop)
-{
- return rb_attr_get(target, rb_intern(StringValuePtr(prop)));
-}
-
void Init_psych_yaml_tree(void)
{
VALUE psych = rb_define_module("Psych");
VALUE visitors = rb_define_module_under(psych, "Visitors");
VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject);
cPsychVisitorsYamlTree = rb_define_class_under(visitors, "YAMLTree", visitor);
-
- rb_define_private_method(cPsychVisitorsYamlTree, "private_iv_get", private_iv_get, 2);
}
/* vim: set noet sws=4 sw=4: */
diff --git a/ext/psych/yaml/api.c b/ext/psych/yaml/api.c
index b1a8da0bda..6add8b2661 100644
--- a/ext/psych/yaml/api.c
+++ b/ext/psych/yaml/api.c
@@ -74,7 +74,7 @@ YAML_DECLARE(int)
yaml_string_extend(yaml_char_t **start,
yaml_char_t **pointer, yaml_char_t **end)
{
- yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
+ yaml_char_t *new_start = (yaml_char_t *)yaml_realloc((void*)*start, (*end - *start)*2);
if (!new_start) return 0;
@@ -94,8 +94,9 @@ yaml_string_extend(yaml_char_t **start,
YAML_DECLARE(int)
yaml_string_join(
yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
- yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
+ yaml_char_t **b_start, yaml_char_t **b_pointer, SHIM(yaml_char_t **b_end))
{
+ UNUSED_PARAM(b_end)
if (*b_start == *b_pointer)
return 1;
@@ -117,7 +118,12 @@ yaml_string_join(
YAML_DECLARE(int)
yaml_stack_extend(void **start, void **top, void **end)
{
- void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
+ void *new_start;
+
+ if ((char *)*end - (char *)*start >= INT_MAX / 2)
+ return 0;
+
+ new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
if (!new_start) return 0;
@@ -177,17 +183,17 @@ yaml_parser_initialize(yaml_parser_t *parser)
goto error;
if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
goto error;
- if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
+ if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE, yaml_token_t*))
goto error;
- if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, parser->indents, int*))
goto error;
- if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, parser->simple_keys, yaml_simple_key_t*))
goto error;
- if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, parser->states, yaml_parser_state_t*))
goto error;
- if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, parser->marks, yaml_mark_t*))
goto error;
- if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, parser->tag_directives, yaml_tag_directive_t*))
goto error;
return 1;
@@ -243,7 +249,7 @@ static int
yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
size_t *size_read)
{
- yaml_parser_t *parser = data;
+ yaml_parser_t *parser = (yaml_parser_t *)data;
if (parser->input.string.current == parser->input.string.end) {
*size_read = 0;
@@ -269,7 +275,7 @@ static int
yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
size_t *size_read)
{
- yaml_parser_t *parser = data;
+ yaml_parser_t *parser = (yaml_parser_t *)data;
*size_read = fread(buffer, 1, size, parser->input.file);
return !ferror(parser->input.file);
@@ -355,13 +361,13 @@ yaml_emitter_initialize(yaml_emitter_t *emitter)
goto error;
if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
goto error;
- if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(emitter, emitter->states, yaml_emitter_state_t*))
goto error;
- if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
+ if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE, yaml_event_t*))
goto error;
- if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(emitter, emitter->indents, int*))
goto error;
- if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(emitter, emitter->tag_directives, yaml_tag_directive_t*))
goto error;
return 1;
@@ -413,7 +419,7 @@ yaml_emitter_delete(yaml_emitter_t *emitter)
static int
yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
{
- yaml_emitter_t *emitter = data;
+ yaml_emitter_t *emitter = (yaml_emitter_t *)data;
if (emitter->output.string.size - *emitter->output.string.size_written
< size) {
@@ -439,7 +445,7 @@ yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
static int
yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
{
- yaml_emitter_t *emitter = data;
+ yaml_emitter_t *emitter = (yaml_emitter_t *)data;
return (fwrite(buffer, 1, size, emitter->output.file) == size);
}
@@ -617,10 +623,10 @@ yaml_token_delete(yaml_token_t *token)
*/
static int
-yaml_check_utf8(yaml_char_t *start, size_t length)
+yaml_check_utf8(const yaml_char_t *start, size_t length)
{
- yaml_char_t *end = start+length;
- yaml_char_t *pointer = start;
+ const yaml_char_t *end = start+length;
+ const yaml_char_t *pointer = start;
while (pointer < end) {
unsigned char octet;
@@ -717,7 +723,7 @@ yaml_document_start_event_initialize(yaml_event_t *event,
/* Valid tag directives are expected. */
if (version_directive) {
- version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
+ version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
if (!version_directive_copy) goto error;
version_directive_copy->major = version_directive->major;
version_directive_copy->minor = version_directive->minor;
@@ -725,7 +731,7 @@ yaml_document_start_event_initialize(yaml_event_t *event,
if (tag_directives_start != tag_directives_end) {
yaml_tag_directive_t *tag_directive;
- if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
goto error;
for (tag_directive = tag_directives_start;
tag_directive != tag_directives_end; tag_directive ++) {
@@ -788,7 +794,7 @@ yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
*/
YAML_DECLARE(int)
-yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
+yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor)
{
yaml_mark_t mark = { 0, 0, 0 };
yaml_char_t *anchor_copy = NULL;
@@ -813,8 +819,8 @@ yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
YAML_DECLARE(int)
yaml_scalar_event_initialize(yaml_event_t *event,
- yaml_char_t *anchor, yaml_char_t *tag,
- yaml_char_t *value, int length,
+ const yaml_char_t *anchor, const yaml_char_t *tag,
+ const yaml_char_t *value, int length,
int plain_implicit, int quoted_implicit,
yaml_scalar_style_t style)
{
@@ -839,11 +845,11 @@ yaml_scalar_event_initialize(yaml_event_t *event,
}
if (length < 0) {
- length = strlen((char *)value);
+ length = (int)strlen((char *)value);
}
if (!yaml_check_utf8(value, length)) goto error;
- value_copy = yaml_malloc(length+1);
+ value_copy = YAML_MALLOC(length+1);
if (!value_copy) goto error;
memcpy(value_copy, value, length);
value_copy[length] = '\0';
@@ -867,7 +873,7 @@ error:
YAML_DECLARE(int)
yaml_sequence_start_event_initialize(yaml_event_t *event,
- yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_sequence_style_t style)
{
yaml_mark_t mark = { 0, 0, 0 };
@@ -922,7 +928,7 @@ yaml_sequence_end_event_initialize(yaml_event_t *event)
YAML_DECLARE(int)
yaml_mapping_start_event_initialize(yaml_event_t *event,
- yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_mapping_style_t style)
{
yaml_mark_t mark = { 0, 0, 0 };
@@ -1055,10 +1061,10 @@ yaml_document_initialize(yaml_document_t *document,
(tag_directives_start == tag_directives_end));
/* Valid tag directives are expected. */
- if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
+ if (!STACK_INIT(&context, nodes, yaml_node_t*)) goto error;
if (version_directive) {
- version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
+ version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
if (!version_directive_copy) goto error;
version_directive_copy->major = version_directive->major;
version_directive_copy->minor = version_directive->minor;
@@ -1066,7 +1072,7 @@ yaml_document_initialize(yaml_document_t *document,
if (tag_directives_start != tag_directives_end) {
yaml_tag_directive_t *tag_directive;
- if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
goto error;
for (tag_directive = tag_directives_start;
tag_directive != tag_directives_end; tag_directive ++) {
@@ -1116,13 +1122,8 @@ error:
YAML_DECLARE(void)
yaml_document_delete(yaml_document_t *document)
{
- struct {
- yaml_error_type_t error;
- } context;
yaml_tag_directive_t *tag_directive;
- context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */
-
assert(document); /* Non-NULL document object is expected. */
while (!STACK_EMPTY(&context, document->nodes)) {
@@ -1192,7 +1193,7 @@ yaml_document_get_root_node(yaml_document_t *document)
YAML_DECLARE(int)
yaml_document_add_scalar(yaml_document_t *document,
- yaml_char_t *tag, yaml_char_t *value, int length,
+ const yaml_char_t *tag, const yaml_char_t *value, int length,
yaml_scalar_style_t style)
{
struct {
@@ -1215,11 +1216,11 @@ yaml_document_add_scalar(yaml_document_t *document,
if (!tag_copy) goto error;
if (length < 0) {
- length = strlen((char *)value);
+ length = (int)strlen((char *)value);
}
if (!yaml_check_utf8(value, length)) goto error;
- value_copy = yaml_malloc(length+1);
+ value_copy = YAML_MALLOC(length+1);
if (!value_copy) goto error;
memcpy(value_copy, value, length);
value_copy[length] = '\0';
@@ -1227,7 +1228,7 @@ yaml_document_add_scalar(yaml_document_t *document,
SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
if (!PUSH(&context, document->nodes, node)) goto error;
- return document->nodes.top - document->nodes.start;
+ return (int)(document->nodes.top - document->nodes.start);
error:
yaml_free(tag_copy);
@@ -1242,7 +1243,7 @@ error:
YAML_DECLARE(int)
yaml_document_add_sequence(yaml_document_t *document,
- yaml_char_t *tag, yaml_sequence_style_t style)
+ const yaml_char_t *tag, yaml_sequence_style_t style)
{
struct {
yaml_error_type_t error;
@@ -1266,13 +1267,13 @@ yaml_document_add_sequence(yaml_document_t *document,
tag_copy = yaml_strdup(tag);
if (!tag_copy) goto error;
- if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
+ if (!STACK_INIT(&context, items, yaml_node_item_t*)) goto error;
SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
style, mark, mark);
if (!PUSH(&context, document->nodes, node)) goto error;
- return document->nodes.top - document->nodes.start;
+ return (int)(document->nodes.top - document->nodes.start);
error:
STACK_DEL(&context, items);
@@ -1287,7 +1288,7 @@ error:
YAML_DECLARE(int)
yaml_document_add_mapping(yaml_document_t *document,
- yaml_char_t *tag, yaml_mapping_style_t style)
+ const yaml_char_t *tag, yaml_mapping_style_t style)
{
struct {
yaml_error_type_t error;
@@ -1311,13 +1312,13 @@ yaml_document_add_mapping(yaml_document_t *document,
tag_copy = yaml_strdup(tag);
if (!tag_copy) goto error;
- if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
+ if (!STACK_INIT(&context, pairs, yaml_node_pair_t*)) goto error;
MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
style, mark, mark);
if (!PUSH(&context, document->nodes, node)) goto error;
- return document->nodes.top - document->nodes.start;
+ return (int)(document->nodes.top - document->nodes.start);
error:
STACK_DEL(&context, pairs);
diff --git a/ext/psych/yaml/config.h b/ext/psych/yaml/config.h
index 79e8501f4f..4b1150f5e4 100644
--- a/ext/psych/yaml/config.h
+++ b/ext/psych/yaml/config.h
@@ -1,10 +1,80 @@
+/* include/config.h. Generated from config.h.in by configure. */
+/* include/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "yaml"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://github.com/yaml/libyaml/issues/new"
+
+/* Define to the full name of this package. */
#define PACKAGE_NAME "yaml"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "yaml 0.2.5"
+
+/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "yaml"
-#define PACKAGE_VERSION "0.1.7"
-#define PACKAGE_STRING "yaml 0.1.7"
-#define PACKAGE_BUGREPORT "https://github.com/yaml/libyaml/issues"
-#define PACKAGE_URL "https://github.com/yaml/libyaml"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.2.5"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.2.5"
+
+/* Define the major version number. */
#define YAML_VERSION_MAJOR 0
-#define YAML_VERSION_MINOR 1
-#define YAML_VERSION_PATCH 7
-#define YAML_VERSION_STRING "0.1.7"
+
+/* Define the minor version number. */
+#define YAML_VERSION_MINOR 2
+
+/* Define the patch version number. */
+#define YAML_VERSION_PATCH 5
+
+/* Define the version string. */
+#define YAML_VERSION_STRING "0.2.5"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/ext/psych/yaml/dumper.c b/ext/psych/yaml/dumper.c
index 203c6a709c..1fe940b674 100644
--- a/ext/psych/yaml/dumper.c
+++ b/ext/psych/yaml/dumper.c
@@ -131,7 +131,7 @@ yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
assert(emitter->opened); /* Emitter should be opened. */
- emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors))
+ emitter->anchors = (yaml_anchors_t*)yaml_malloc(sizeof(*(emitter->anchors))
* (document->nodes.top - document->nodes.start));
if (!emitter->anchors) goto error;
memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
@@ -245,9 +245,9 @@ yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
#define ANCHOR_TEMPLATE_LENGTH 16
static yaml_char_t *
-yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id)
+yaml_emitter_generate_anchor(SHIM(yaml_emitter_t *emitter), int anchor_id)
{
- yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH);
+ yaml_char_t *anchor = YAML_MALLOC(ANCHOR_TEMPLATE_LENGTH);
if (!anchor) return NULL;
diff --git a/ext/psych/yaml/emitter.c b/ext/psych/yaml/emitter.c
index 5adcbdeb32..796294ccdf 100644
--- a/ext/psych/yaml/emitter.c
+++ b/ext/psych/yaml/emitter.c
@@ -16,7 +16,7 @@
#define PUT(emitter,value) \
(FLUSH(emitter) \
&& (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
- emitter->column ++, \
+ emitter->column++, \
1))
/*
@@ -24,8 +24,8 @@
*/
#define PUT_BREAK(emitter) \
- (FLUSH(emitter) \
- && ((emitter->line_break == YAML_CR_BREAK ? \
+ (FLUSH(emitter) ? \
+ ((emitter->line_break == YAML_CR_BREAK ? \
(*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \
emitter->line_break == YAML_LN_BREAK ? \
(*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \
@@ -34,7 +34,7 @@
*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \
emitter->column = 0, \
emitter->line ++, \
- 1))
+ 1) : 0)
/*
* Copy a character from a string into buffer.
@@ -221,7 +221,7 @@ yaml_emitter_write_indent(yaml_emitter_t *emitter);
static int
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
- char *indicator, int need_whitespace,
+ const char *indicator, int need_whitespace,
int is_whitespace, int is_indention);
static int
@@ -495,6 +495,7 @@ static int
yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
yaml_event_t *event)
{
+ emitter->open_ended = 0;
if (event->type == YAML_STREAM_START_EVENT)
{
if (!emitter->encoding) {
@@ -597,13 +598,20 @@ yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
if (!yaml_emitter_write_indent(emitter))
return 0;
}
+ emitter->open_ended = 0;
if (event->data.document_start.version_directive) {
implicit = 0;
if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
return 0;
- if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
- return 0;
+ if (event->data.document_start.version_directive->minor == 1) {
+ if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
+ return 0;
+ }
+ else {
+ if (!yaml_emitter_write_indicator(emitter, "1.2", 1, 0, 0))
+ return 0;
+ }
if (!yaml_emitter_write_indent(emitter))
return 0;
}
@@ -644,19 +652,25 @@ yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
+ emitter->open_ended = 0;
return 1;
}
else if (event->type == YAML_STREAM_END_EVENT)
{
- if (emitter->open_ended)
+
+ /**
+ * This can happen if a block scalar with trailing empty lines
+ * is at the end of the stream
+ */
+ if (emitter->open_ended == 2)
{
if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
return 0;
+ emitter->open_ended = 0;
if (!yaml_emitter_write_indent(emitter))
return 0;
}
-
if (!yaml_emitter_flush(emitter))
return 0;
@@ -698,9 +712,12 @@ yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
if (!event->data.document_end.implicit) {
if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
return 0;
+ emitter->open_ended = 0;
if (!yaml_emitter_write_indent(emitter))
return 0;
}
+ else if (!emitter->open_ended)
+ emitter->open_ended = 1;
if (!yaml_emitter_flush(emitter))
return 0;
@@ -1002,10 +1019,12 @@ yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
*/
static int
-yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
+yaml_emitter_emit_alias(yaml_emitter_t *emitter, SHIM(yaml_event_t *event))
{
if (!yaml_emitter_process_anchor(emitter))
return 0;
+ if (emitter->simple_key_context)
+ if (!PUT(emitter, ' ')) return 0;
emitter->state = POP(emitter, emitter->states);
return 1;
@@ -1087,7 +1106,7 @@ yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
*/
static int
-yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
+yaml_emitter_check_empty_document(SHIM(yaml_emitter_t *emitter))
{
return 0;
}
@@ -1234,7 +1253,7 @@ yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
}
/*
- * Write an achor.
+ * Write an anchor.
*/
static int
@@ -1333,7 +1352,10 @@ static int
yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
yaml_version_directive_t version_directive)
{
- if (version_directive.major != 1 || version_directive.minor != 1) {
+ if (version_directive.major != 1 || (
+ version_directive.minor != 1
+ && version_directive.minor != 2
+ )) {
return yaml_emitter_set_emitter_error(emitter,
"incompatible %YAML directive");
}
@@ -1784,7 +1806,7 @@ yaml_emitter_write_indent(yaml_emitter_t *emitter)
static int
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
- char *indicator, int need_whitespace,
+ const char *indicator, int need_whitespace,
int is_whitespace, int is_indention)
{
size_t indicator_length;
@@ -1803,7 +1825,6 @@ yaml_emitter_write_indicator(yaml_emitter_t *emitter,
emitter->whitespace = is_whitespace;
emitter->indention = (emitter->indention && is_indention);
- emitter->open_ended = 0;
return 1;
}
@@ -1904,7 +1925,17 @@ yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
STRING_ASSIGN(string, value, length);
- if (!emitter->whitespace) {
+ /**
+ * Avoid trailing spaces for empty values in block mode.
+ * In flow mode, we still want the space to prevent ambiguous things
+ * like {a:}.
+ * Currently, the emitter forbids any plain empty scalar in flow mode
+ * (e.g. it outputs {a: ''} instead), so emitter->flow_level will
+ * never be true here.
+ * But if the emitter is ever changed to allow emitting empty values,
+ * the check for flow_level is already here.
+ */
+ if (!emitter->whitespace && (length || emitter->flow_level)) {
if (!PUT(emitter, ' ')) return 0;
}
@@ -1946,10 +1977,6 @@ yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
emitter->whitespace = 0;
emitter->indention = 0;
- if (emitter->root_context)
- {
- emitter->open_ended = 1;
- }
return 1;
}
@@ -2008,6 +2035,9 @@ yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
}
}
+ if (breaks)
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+
if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
return 0;
@@ -2178,7 +2208,7 @@ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
yaml_string_t string)
{
char indent_hint[2];
- char *chomp_hint = NULL;
+ const char *chomp_hint = NULL;
if (IS_SPACE(string) || IS_BREAK(string))
{
@@ -2207,7 +2237,7 @@ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
else if (string.start == string.pointer)
{
chomp_hint = "+";
- emitter->open_ended = 1;
+ emitter->open_ended = 2;
}
else
{
@@ -2217,7 +2247,7 @@ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
if (IS_BREAK(string))
{
chomp_hint = "+";
- emitter->open_ended = 1;
+ emitter->open_ended = 2;
}
}
}
@@ -2326,4 +2356,3 @@ yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
return 1;
}
-
diff --git a/ext/psych/yaml/loader.c b/ext/psych/yaml/loader.c
index 3ba99f087e..bcf3aee8cb 100644
--- a/ext/psych/yaml/loader.c
+++ b/ext/psych/yaml/loader.c
@@ -38,26 +38,46 @@ static void
yaml_parser_delete_aliases(yaml_parser_t *parser);
/*
+ * Document loading context.
+ */
+struct loader_ctx {
+ int *start;
+ int *end;
+ int *top;
+};
+
+/*
* Composer functions.
*/
+static int
+yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx);
+
+static int
+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event);
static int
-yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
+yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
+yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
/*
* Load the next document of the stream.
@@ -72,7 +92,7 @@ yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
assert(document); /* Non-NULL document object is expected. */
memset(document, 0, sizeof(yaml_document_t));
- if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
goto error;
if (!parser->stream_start_produced) {
@@ -90,7 +110,7 @@ yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
return 1;
}
- if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
goto error;
parser->document = document;
@@ -162,59 +182,78 @@ yaml_parser_delete_aliases(yaml_parser_t *parser)
*/
static int
-yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event)
{
- yaml_event_t event;
+ struct loader_ctx ctx = { NULL, NULL, NULL };
- assert(first_event->type == YAML_DOCUMENT_START_EVENT);
+ assert(event->type == YAML_DOCUMENT_START_EVENT);
/* DOCUMENT-START is expected. */
parser->document->version_directive
- = first_event->data.document_start.version_directive;
+ = event->data.document_start.version_directive;
parser->document->tag_directives.start
- = first_event->data.document_start.tag_directives.start;
+ = event->data.document_start.tag_directives.start;
parser->document->tag_directives.end
- = first_event->data.document_start.tag_directives.end;
+ = event->data.document_start.tag_directives.end;
parser->document->start_implicit
- = first_event->data.document_start.implicit;
- parser->document->start_mark = first_event->start_mark;
-
- if (!yaml_parser_parse(parser, &event)) return 0;
-
- if (!yaml_parser_load_node(parser, &event)) return 0;
-
- if (!yaml_parser_parse(parser, &event)) return 0;
- assert(event.type == YAML_DOCUMENT_END_EVENT);
- /* DOCUMENT-END is expected. */
+ = event->data.document_start.implicit;
+ parser->document->start_mark = event->start_mark;
- parser->document->end_implicit = event.data.document_end.implicit;
- parser->document->end_mark = event.end_mark;
+ if (!STACK_INIT(parser, ctx, int*)) return 0;
+ if (!yaml_parser_load_nodes(parser, &ctx)) {
+ STACK_DEL(parser, ctx);
+ return 0;
+ }
+ STACK_DEL(parser, ctx);
return 1;
}
/*
- * Compose a node.
+ * Compose a node tree.
*/
static int
-yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
+yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx)
{
- switch (first_event->type) {
- case YAML_ALIAS_EVENT:
- return yaml_parser_load_alias(parser, first_event);
- case YAML_SCALAR_EVENT:
- return yaml_parser_load_scalar(parser, first_event);
- case YAML_SEQUENCE_START_EVENT:
- return yaml_parser_load_sequence(parser, first_event);
- case YAML_MAPPING_START_EVENT:
- return yaml_parser_load_mapping(parser, first_event);
- default:
- assert(0); /* Could not happen. */
- return 0;
- }
+ yaml_event_t event;
- return 0;
+ do {
+ if (!yaml_parser_parse(parser, &event)) return 0;
+
+ switch (event.type) {
+ case YAML_ALIAS_EVENT:
+ if (!yaml_parser_load_alias(parser, &event, ctx)) return 0;
+ break;
+ case YAML_SCALAR_EVENT:
+ if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0;
+ break;
+ case YAML_SEQUENCE_START_EVENT:
+ if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0;
+ break;
+ case YAML_SEQUENCE_END_EVENT:
+ if (!yaml_parser_load_sequence_end(parser, &event, ctx))
+ return 0;
+ break;
+ case YAML_MAPPING_START_EVENT:
+ if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0;
+ break;
+ case YAML_MAPPING_END_EVENT:
+ if (!yaml_parser_load_mapping_end(parser, &event, ctx))
+ return 0;
+ break;
+ default:
+ assert(0); /* Could not happen. */
+ return 0;
+ case YAML_DOCUMENT_END_EVENT:
+ break;
+ }
+ } while (event.type != YAML_DOCUMENT_END_EVENT);
+
+ parser->document->end_implicit = event.data.document_end.implicit;
+ parser->document->end_mark = event.end_mark;
+
+ return 1;
}
/*
@@ -253,26 +292,79 @@ yaml_parser_register_anchor(yaml_parser_t *parser,
}
/*
+ * Compose node into its parent in the stree.
+ */
+
+static int
+yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx,
+ int index)
+{
+ struct yaml_node_s *parent;
+ int parent_index;
+
+ if (STACK_EMPTY(parser, *ctx)) {
+ /* This is the root node, there's no tree to add it to. */
+ return 1;
+ }
+
+ parent_index = *((*ctx).top - 1);
+ parent = &parser->document->nodes.start[parent_index-1];
+
+ switch (parent->type) {
+ case YAML_SEQUENCE_NODE:
+ if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1))
+ return 0;
+ if (!PUSH(parser, parent->data.sequence.items, index))
+ return 0;
+ break;
+ case YAML_MAPPING_NODE: {
+ yaml_node_pair_t pair;
+ if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) {
+ yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1;
+ if (p->key != 0 && p->value == 0) {
+ p->value = index;
+ break;
+ }
+ }
+
+ pair.key = index;
+ pair.value = 0;
+ if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1))
+ return 0;
+ if (!PUSH(parser, parent->data.mapping.pairs, pair))
+ return 0;
+
+ break;
+ }
+ default:
+ assert(0); /* Could not happen. */
+ return 0;
+ }
+ return 1;
+}
+
+/*
* Compose a node corresponding to an alias.
*/
static int
-yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
- yaml_char_t *anchor = first_event->data.alias.anchor;
+ yaml_char_t *anchor = event->data.alias.anchor;
yaml_alias_data_t *alias_data;
for (alias_data = parser->aliases.start;
alias_data != parser->aliases.top; alias_data ++) {
if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
yaml_free(anchor);
- return alias_data->index;
+ return yaml_parser_load_node_add(parser, ctx, alias_data->index);
}
}
yaml_free(anchor);
return yaml_parser_set_composer_error(parser, "found undefined alias",
- first_event->start_mark);
+ event->start_mark);
}
/*
@@ -280,11 +372,12 @@ yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
*/
static int
-yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
yaml_node_t node;
int index;
- yaml_char_t *tag = first_event->data.scalar.tag;
+ yaml_char_t *tag = event->data.scalar.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
@@ -294,23 +387,23 @@ yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
if (!tag) goto error;
}
- SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
- first_event->data.scalar.length, first_event->data.scalar.style,
- first_event->start_mark, first_event->end_mark);
+ SCALAR_NODE_INIT(node, tag, event->data.scalar.value,
+ event->data.scalar.length, event->data.scalar.style,
+ event->start_mark, event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
- index = parser->document->nodes.top - parser->document->nodes.start;
+ index = (int)(parser->document->nodes.top - parser->document->nodes.start);
if (!yaml_parser_register_anchor(parser, index,
- first_event->data.scalar.anchor)) return 0;
+ event->data.scalar.anchor)) return 0;
- return index;
+ return yaml_parser_load_node_add(parser, ctx, index);
error:
yaml_free(tag);
- yaml_free(first_event->data.scalar.anchor);
- yaml_free(first_event->data.scalar.value);
+ yaml_free(event->data.scalar.anchor);
+ yaml_free(event->data.scalar.value);
return 0;
}
@@ -319,17 +412,17 @@ error:
*/
static int
-yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
- yaml_event_t event;
yaml_node_t node;
struct {
yaml_node_item_t *start;
yaml_node_item_t *end;
yaml_node_item_t *top;
} items = { NULL, NULL, NULL };
- int index, item_index;
- yaml_char_t *tag = first_event->data.sequence_start.tag;
+ int index;
+ yaml_char_t *tag = event->data.sequence_start.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
@@ -339,51 +432,57 @@ yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
if (!tag) goto error;
}
- if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
+ if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
- first_event->data.sequence_start.style,
- first_event->start_mark, first_event->end_mark);
+ event->data.sequence_start.style,
+ event->start_mark, event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
- index = parser->document->nodes.top - parser->document->nodes.start;
+ index = (int)(parser->document->nodes.top - parser->document->nodes.start);
if (!yaml_parser_register_anchor(parser, index,
- first_event->data.sequence_start.anchor)) return 0;
-
- if (!yaml_parser_parse(parser, &event)) return 0;
-
- while (event.type != YAML_SEQUENCE_END_EVENT) {
- if (!STACK_LIMIT(parser,
- parser->document->nodes.start[index-1].data.sequence.items,
- INT_MAX-1)) return 0;
- item_index = yaml_parser_load_node(parser, &event);
- if (!item_index) return 0;
- if (!PUSH(parser,
- parser->document->nodes.start[index-1].data.sequence.items,
- item_index)) return 0;
- if (!yaml_parser_parse(parser, &event)) return 0;
- }
+ event->data.sequence_start.anchor)) return 0;
- parser->document->nodes.start[index-1].end_mark = event.end_mark;
+ if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
- return index;
+ if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
+ if (!PUSH(parser, *ctx, index)) return 0;
+
+ return 1;
error:
yaml_free(tag);
- yaml_free(first_event->data.sequence_start.anchor);
+ yaml_free(event->data.sequence_start.anchor);
return 0;
}
+static int
+yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
+{
+ int index;
+
+ assert(((*ctx).top - (*ctx).start) > 0);
+
+ index = *((*ctx).top - 1);
+ assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE);
+ parser->document->nodes.start[index-1].end_mark = event->end_mark;
+
+ (void)POP(parser, *ctx);
+
+ return 1;
+}
+
/*
* Compose a mapping node.
*/
static int
-yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
- yaml_event_t event;
yaml_node_t node;
struct {
yaml_node_pair_t *start;
@@ -391,8 +490,7 @@ yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
yaml_node_pair_t *top;
} pairs = { NULL, NULL, NULL };
int index;
- yaml_node_pair_t pair;
- yaml_char_t *tag = first_event->data.mapping_start.tag;
+ yaml_char_t *tag = event->data.mapping_start.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
@@ -402,43 +500,45 @@ yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
if (!tag) goto error;
}
- if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
+ if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
- first_event->data.mapping_start.style,
- first_event->start_mark, first_event->end_mark);
+ event->data.mapping_start.style,
+ event->start_mark, event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
- index = parser->document->nodes.top - parser->document->nodes.start;
+ index = (int)(parser->document->nodes.top - parser->document->nodes.start);
if (!yaml_parser_register_anchor(parser, index,
- first_event->data.mapping_start.anchor)) return 0;
+ event->data.mapping_start.anchor)) return 0;
- if (!yaml_parser_parse(parser, &event)) return 0;
+ if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
- while (event.type != YAML_MAPPING_END_EVENT) {
- if (!STACK_LIMIT(parser,
- parser->document->nodes.start[index-1].data.mapping.pairs,
- INT_MAX-1)) return 0;
- pair.key = yaml_parser_load_node(parser, &event);
- if (!pair.key) return 0;
- if (!yaml_parser_parse(parser, &event)) return 0;
- pair.value = yaml_parser_load_node(parser, &event);
- if (!pair.value) return 0;
- if (!PUSH(parser,
- parser->document->nodes.start[index-1].data.mapping.pairs,
- pair)) return 0;
- if (!yaml_parser_parse(parser, &event)) return 0;
- }
+ if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
+ if (!PUSH(parser, *ctx, index)) return 0;
- parser->document->nodes.start[index-1].end_mark = event.end_mark;
-
- return index;
+ return 1;
error:
yaml_free(tag);
- yaml_free(first_event->data.mapping_start.anchor);
+ yaml_free(event->data.mapping_start.anchor);
return 0;
}
+static int
+yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
+{
+ int index;
+
+ assert(((*ctx).top - (*ctx).start) > 0);
+
+ index = *((*ctx).top - 1);
+ assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE);
+ parser->document->nodes.start[index-1].end_mark = event->end_mark;
+
+ (void)POP(parser, *ctx);
+
+ return 1;
+}
diff --git a/ext/psych/yaml/parser.c b/ext/psych/yaml/parser.c
index dc5430b09f..ec2f8d3e05 100644
--- a/ext/psych/yaml/parser.c
+++ b/ext/psych/yaml/parser.c
@@ -605,7 +605,7 @@ yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
size_t prefix_len = strlen((char *)tag_directive->prefix);
size_t suffix_len = strlen((char *)tag_suffix);
- tag = yaml_malloc(prefix_len+suffix_len+1);
+ tag = YAML_MALLOC(prefix_len+suffix_len+1);
if (!tag) {
parser->error = YAML_MEMORY_ERROR;
goto error;
@@ -685,7 +685,7 @@ yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
return 1;
}
else if (anchor || tag) {
- yaml_char_t *value = yaml_malloc(1);
+ yaml_char_t *value = YAML_MALLOC(1);
if (!value) {
parser->error = YAML_MEMORY_ERROR;
goto error;
@@ -759,9 +759,8 @@ yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
else if (token->type == YAML_BLOCK_END_TOKEN)
{
- yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
parser->state = POP(parser, parser->states);
- dummy_mark = POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -869,9 +868,8 @@ yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
else if (token->type == YAML_BLOCK_END_TOKEN)
{
- yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
parser->state = POP(parser, parser->states);
- dummy_mark = POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -952,7 +950,6 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
yaml_event_t *event, int first)
{
yaml_token_t *token;
- yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
if (first) {
token = PEEK_TOKEN(parser);
@@ -997,7 +994,7 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
}
parser->state = POP(parser, parser->states);
- dummy_mark = POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -1104,7 +1101,6 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
yaml_event_t *event, int first)
{
yaml_token_t *token;
- yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
if (first) {
token = PEEK_TOKEN(parser);
@@ -1158,7 +1154,7 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
}
parser->state = POP(parser, parser->states);
- dummy_mark = POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -1212,7 +1208,7 @@ yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
{
yaml_char_t *value;
- value = yaml_malloc(1);
+ value = YAML_MALLOC(1);
if (!value) {
parser->error = YAML_MEMORY_ERROR;
return 0;
@@ -1249,7 +1245,7 @@ yaml_parser_process_directives(yaml_parser_t *parser,
} tag_directives = { NULL, NULL, NULL };
yaml_token_t *token;
- if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
+ if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
goto error;
token = PEEK_TOKEN(parser);
@@ -1265,12 +1261,15 @@ yaml_parser_process_directives(yaml_parser_t *parser,
goto error;
}
if (token->data.version_directive.major != 1
- || token->data.version_directive.minor != 1) {
+ || (
+ token->data.version_directive.minor != 1
+ && token->data.version_directive.minor != 2
+ )) {
yaml_parser_set_parser_error(parser,
"found incompatible YAML document", token->start_mark);
goto error;
}
- version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
+ version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
if (!version_directive) {
parser->error = YAML_MEMORY_ERROR;
goto error;
@@ -1320,6 +1319,8 @@ yaml_parser_process_directives(yaml_parser_t *parser,
STACK_DEL(parser, tag_directives);
}
+ if (!version_directive_ref)
+ yaml_free(version_directive);
return 1;
error:
diff --git a/ext/psych/yaml/reader.c b/ext/psych/yaml/reader.c
index f1a06deb9d..f3ac54c251 100644
--- a/ext/psych/yaml/reader.c
+++ b/ext/psych/yaml/reader.c
@@ -460,10 +460,10 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
}
- if (parser->offset >= PTRDIFF_MAX)
+ if (parser->offset >= MAX_FILE_SIZE) {
return yaml_parser_set_reader_error(parser, "input is too long",
- PTRDIFF_MAX, -1);
+ parser->offset, -1);
+ }
return 1;
}
-
diff --git a/ext/psych/yaml/scanner.c b/ext/psych/yaml/scanner.c
index 3ef90dc66b..bb5d201274 100644
--- a/ext/psych/yaml/scanner.c
+++ b/ext/psych/yaml/scanner.c
@@ -38,8 +38,8 @@
* BLOCK-END # Indentation decrease.
* FLOW-SEQUENCE-START # '['
* FLOW-SEQUENCE-END # ']'
- * BLOCK-SEQUENCE-START # '{'
- * BLOCK-SEQUENCE-END # '}'
+ * FLOW-MAPPING-START # '{'
+ * FLOW-MAPPING-END # '}'
* BLOCK-ENTRY # '-'
* FLOW-ENTRY # ','
* KEY # '?' or nothing (simple keys).
@@ -273,7 +273,7 @@
* The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
* increase that precedes a block collection (cf. the INDENT token in Python).
* The token BLOCK-END denote indentation decrease that ends a block collection
- * (cf. the DEDENT token in Python). However YAML has some syntax pecularities
+ * (cf. the DEDENT token in Python). However YAML has some syntax peculiarities
* that makes detections of these tokens more complex.
*
* The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
@@ -348,6 +348,7 @@
* SCALAR("another value",plain)
* KEY
* SCALAR("a mapping",plain)
+ * VALUE
* BLOCK-MAPPING-START
* KEY
* SCALAR("key 1",plain)
@@ -711,7 +712,7 @@ yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
yaml_mark_t start_mark, yaml_char_t **handle);
static int
-yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri);
static int
@@ -1186,11 +1187,9 @@ yaml_parser_increase_flow_level(yaml_parser_t *parser)
static int
yaml_parser_decrease_flow_level(yaml_parser_t *parser)
{
- yaml_simple_key_t dummy_key; /* Used to eliminate a compiler warning. */
-
if (parser->flow_level) {
parser->flow_level --;
- dummy_key = POP(parser, parser->simple_keys);
+ (void)POP(parser, parser->simple_keys);
}
return 1;
@@ -1229,7 +1228,7 @@ yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column,
return 0;
}
- parser->indent = column;
+ parser->indent = (int)column;
/* Create a token and insert it into the queue. */
@@ -1638,7 +1637,7 @@ yaml_parser_fetch_key(yaml_parser_t *parser)
if (!parser->flow_level)
{
- /* Check if we are allowed to start a new key (not nessesary simple). */
+ /* Check if we are allowed to start a new key (not necessary simple). */
if (!parser->simple_key_allowed) {
return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
@@ -2294,7 +2293,7 @@ yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
/* Scan a prefix. */
- if (!yaml_parser_scan_tag_uri(parser, 1, NULL, start_mark, &prefix_value))
+ if (!yaml_parser_scan_tag_uri(parser, 1, 1, NULL, start_mark, &prefix_value))
goto error;
/* Expect a whitespace or line break. */
@@ -2401,7 +2400,7 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
{
/* Set the handle to '' */
- handle = yaml_malloc(1);
+ handle = YAML_MALLOC(1);
if (!handle) goto error;
handle[0] = '\0';
@@ -2412,7 +2411,7 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
/* Consume the tag value. */
- if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
+ if (!yaml_parser_scan_tag_uri(parser, 1, 0, NULL, start_mark, &suffix))
goto error;
/* Check for '>' and eat it. */
@@ -2440,20 +2439,20 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
{
/* Scan the suffix now. */
- if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
+ if (!yaml_parser_scan_tag_uri(parser, 0, 0, NULL, start_mark, &suffix))
goto error;
}
else
{
/* It wasn't a handle after all. Scan the rest of the tag. */
- if (!yaml_parser_scan_tag_uri(parser, 0, handle, start_mark, &suffix))
+ if (!yaml_parser_scan_tag_uri(parser, 0, 0, handle, start_mark, &suffix))
goto error;
/* Set the handle to '!'. */
yaml_free(handle);
- handle = yaml_malloc(2);
+ handle = YAML_MALLOC(2);
if (!handle) goto error;
handle[0] = '!';
handle[1] = '\0';
@@ -2476,9 +2475,11 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
if (!CACHE(parser, 1)) goto error;
if (!IS_BLANKZ(parser->buffer)) {
- yaml_parser_set_scanner_error(parser, "while scanning a tag",
- start_mark, "did not find expected whitespace or line break");
- goto error;
+ if (!parser->flow_level || !CHECK(parser->buffer, ',') ) {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find expected whitespace or line break");
+ goto error;
+ }
}
end_mark = parser->mark;
@@ -2567,7 +2568,7 @@ error:
*/
static int
-yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
{
size_t length = head ? strlen((char *)head) : 0;
@@ -2603,8 +2604,11 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
* The set of characters that may appear in URI is as follows:
*
* '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
- * '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
- * '%'.
+ * '=', '+', '$', '.', '!', '~', '*', '\'', '(', ')', '%'.
+ *
+ * If we are inside a verbatim tag <...> (parameter uri_char is true)
+ * then also the following flow indicators are allowed:
+ * ',', '[', ']'
*/
while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';')
@@ -2612,12 +2616,15 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
|| CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@')
|| CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=')
|| CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$')
- || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.')
+ || CHECK(parser->buffer, '.') || CHECK(parser->buffer, '%')
|| CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~')
|| CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'')
|| CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')')
- || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
- || CHECK(parser->buffer, '%'))
+ || (uri_char && (
+ CHECK(parser->buffer, ',')
+ || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
+ )
+ ))
{
/* Check if it is a URI-escape sequence. */
@@ -2862,7 +2869,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
if (!CACHE(parser, 1)) goto error;
- while ((int)parser->mark.column == indent && !IS_Z(parser->buffer))
+ while ((int)parser->mark.column == indent && !(IS_Z(parser->buffer)))
{
/*
* We are at the beginning of a non-empty line.
@@ -3162,8 +3169,8 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
*(string.pointer++) = '"';
break;
- case '\'':
- *(string.pointer++) = '\'';
+ case '/':
+ *(string.pointer++) = '/';
break;
case '\\':
@@ -3280,6 +3287,11 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
/* Check if we are at the end of the scalar. */
+ /* Fix for crash uninitialized value crash
+ * Credit for the bug and input is to OSS Fuzz
+ * Credit for the fix to Alex Gaynor
+ */
+ if (!CACHE(parser, 1)) goto error;
if (CHECK(parser->buffer, single ? '\'' : '"'))
break;
@@ -3427,11 +3439,22 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
while (!IS_BLANKZ(parser->buffer))
{
- /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
+ /* Check for "x:" + one of ',?[]{}' in the flow context. TODO: Fix the test "spec-08-13".
+ * This is not completely according to the spec
+ * See http://yaml.org/spec/1.1/#id907281 9.1.3. Plain
+ */
if (parser->flow_level
&& CHECK(parser->buffer, ':')
- && !IS_BLANKZ_AT(parser->buffer, 1)) {
+ && (
+ CHECK_AT(parser->buffer, ',', 1)
+ || CHECK_AT(parser->buffer, '?', 1)
+ || CHECK_AT(parser->buffer, '[', 1)
+ || CHECK_AT(parser->buffer, ']', 1)
+ || CHECK_AT(parser->buffer, '{', 1)
+ || CHECK_AT(parser->buffer, '}', 1)
+ )
+ ) {
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
start_mark, "found unexpected ':'");
goto error;
@@ -3441,8 +3464,8 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
|| (parser->flow_level &&
- (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':')
- || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[')
+ (CHECK(parser->buffer, ',')
+ || CHECK(parser->buffer, '[')
|| CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
|| CHECK(parser->buffer, '}'))))
break;
@@ -3573,4 +3596,3 @@ error:
return 0;
}
-
diff --git a/ext/psych/yaml/yaml.h b/ext/psych/yaml/yaml.h
index f33a152594..f1b7bfde20 100644
--- a/ext/psych/yaml/yaml.h
+++ b/ext/psych/yaml/yaml.h
@@ -26,7 +26,9 @@ extern "C" {
/** The public API declaration. */
-#ifdef _WIN32
+#if defined(__MINGW32__)
+# define YAML_DECLARE(type) type
+#elif defined(_WIN32)
# if defined(YAML_DECLARE_STATIC)
# define YAML_DECLARE(type) type
# elif defined(YAML_DECLARE_EXPORT)
@@ -230,7 +232,7 @@ typedef enum yaml_token_type_e {
/** A BLOCK-SEQUENCE-START token. */
YAML_BLOCK_SEQUENCE_START_TOKEN,
- /** A BLOCK-SEQUENCE-END token. */
+ /** A BLOCK-MAPPING-START token. */
YAML_BLOCK_MAPPING_START_TOKEN,
/** A BLOCK-END token. */
YAML_BLOCK_END_TOKEN,
@@ -550,7 +552,7 @@ yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
*/
YAML_DECLARE(int)
-yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
+yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor);
/**
* Create a SCALAR event.
@@ -576,8 +578,8 @@ yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
YAML_DECLARE(int)
yaml_scalar_event_initialize(yaml_event_t *event,
- yaml_char_t *anchor, yaml_char_t *tag,
- yaml_char_t *value, int length,
+ const yaml_char_t *anchor, const yaml_char_t *tag,
+ const yaml_char_t *value, int length,
int plain_implicit, int quoted_implicit,
yaml_scalar_style_t style);
@@ -599,7 +601,7 @@ yaml_scalar_event_initialize(yaml_event_t *event,
YAML_DECLARE(int)
yaml_sequence_start_event_initialize(yaml_event_t *event,
- yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_sequence_style_t style);
/**
@@ -631,7 +633,7 @@ yaml_sequence_end_event_initialize(yaml_event_t *event);
YAML_DECLARE(int)
yaml_mapping_start_event_initialize(yaml_event_t *event,
- yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_mapping_style_t style);
/**
@@ -663,7 +665,7 @@ yaml_event_delete(yaml_event_t *event);
/** The tag @c !!null with the only possible value: @c null. */
#define YAML_NULL_TAG "tag:yaml.org,2002:null"
-/** The tag @c !!bool with the values: @c true and @c falce. */
+/** The tag @c !!bool with the values: @c true and @c false. */
#define YAML_BOOL_TAG "tag:yaml.org,2002:bool"
/** The tag @c !!str for string values. */
#define YAML_STR_TAG "tag:yaml.org,2002:str"
@@ -894,7 +896,7 @@ yaml_document_get_root_node(yaml_document_t *document);
YAML_DECLARE(int)
yaml_document_add_scalar(yaml_document_t *document,
- yaml_char_t *tag, yaml_char_t *value, int length,
+ const yaml_char_t *tag, const yaml_char_t *value, int length,
yaml_scalar_style_t style);
/**
@@ -911,7 +913,7 @@ yaml_document_add_scalar(yaml_document_t *document,
YAML_DECLARE(int)
yaml_document_add_sequence(yaml_document_t *document,
- yaml_char_t *tag, yaml_sequence_style_t style);
+ const yaml_char_t *tag, yaml_sequence_style_t style);
/**
* Create a MAPPING node and attach it to the document.
@@ -927,7 +929,7 @@ yaml_document_add_sequence(yaml_document_t *document,
YAML_DECLARE(int)
yaml_document_add_mapping(yaml_document_t *document,
- yaml_char_t *tag, yaml_mapping_style_t style);
+ const yaml_char_t *tag, yaml_mapping_style_t style);
/**
* Add an item to a SEQUENCE node.
@@ -935,7 +937,7 @@ yaml_document_add_mapping(yaml_document_t *document,
* @param[in,out] document A document object.
* @param[in] sequence The sequence node id.
* @param[in] item The item node id.
-*
+ *
* @returns @c 1 if the function succeeded, @c 0 on error.
*/
@@ -950,7 +952,7 @@ yaml_document_append_sequence_item(yaml_document_t *document,
* @param[in] mapping The mapping node id.
* @param[in] key The key node id.
* @param[in] value The value node id.
-*
+ *
* @returns @c 1 if the function succeeded, @c 0 on error.
*/
@@ -1018,6 +1020,7 @@ typedef enum yaml_parser_state_e {
YAML_PARSE_DOCUMENT_CONTENT_STATE,
/** Expect DOCUMENT-END. */
YAML_PARSE_DOCUMENT_END_STATE,
+
/** Expect a block node. */
YAML_PARSE_BLOCK_NODE_STATE,
/** Expect a block node or indentless sequence. */
@@ -1028,6 +1031,7 @@ typedef enum yaml_parser_state_e {
YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE,
/** Expect an entry of a block sequence. */
YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE,
+
/** Expect an entry of an indentless sequence. */
YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE,
/** Expect the first key of a block mapping. */
@@ -1038,6 +1042,7 @@ typedef enum yaml_parser_state_e {
YAML_PARSE_BLOCK_MAPPING_VALUE_STATE,
/** Expect the first entry of a flow sequence. */
YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE,
+
/** Expect an entry of a flow sequence. */
YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE,
/** Expect a key of an ordered mapping. */
@@ -1049,6 +1054,7 @@ typedef enum yaml_parser_state_e {
/** Expect the first key of a flow mapping. */
YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
/** Expect a key of a flow mapping. */
+
YAML_PARSE_FLOW_MAPPING_KEY_STATE,
/** Expect a value of a flow mapping. */
YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
@@ -1203,7 +1209,7 @@ typedef struct yaml_parser_s {
/** The number of tokens fetched from the queue. */
size_t tokens_parsed;
- /* Does the tokens queue contain a token ready for dequeueing. */
+ /** Does the tokens queue contain a token ready for dequeueing. */
int token_available;
/** The indentation levels stack. */
@@ -1329,7 +1335,7 @@ yaml_parser_delete(yaml_parser_t *parser);
* Set a string input.
*
* Note that the @a input pointer must be valid while the @a parser object
- * exists. The application is responsible for destroing @a input after
+ * exists. The application is responsible for destroying @a input after
* destroying the @a parser.
*
* @param[in,out] parser A parser object.
@@ -1444,7 +1450,7 @@ yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
* @param[in,out] parser A parser object.
* @param[out] document An empty document object.
*
- * @return @c 1 if the function succeeded, @c 0 on error.
+ * @returns @c 1 if the function succeeded, @c 0 on error.
*/
YAML_DECLARE(int)
@@ -1487,6 +1493,7 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_DOCUMENT_CONTENT_STATE,
/** Expect DOCUMENT-END. */
YAML_EMIT_DOCUMENT_END_STATE,
+
/** Expect the first item of a flow sequence. */
YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
/** Expect an item of a flow sequence. */
@@ -1497,6 +1504,7 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_FLOW_MAPPING_KEY_STATE,
/** Expect a value for a simple key of a flow mapping. */
YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
+
/** Expect a value of a flow mapping. */
YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
/** Expect the first item of a block sequence. */
@@ -1507,6 +1515,7 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
/** Expect the key of a block mapping. */
YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
+
/** Expect a value for a simple key of a block mapping. */
YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
/** Expect a value of a block mapping. */
@@ -1515,6 +1524,18 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_END_STATE
} yaml_emitter_state_t;
+
+/* This is needed for C++ */
+
+typedef struct yaml_anchors_s {
+ /** The number of references. */
+ int references;
+ /** The anchor id. */
+ int anchor;
+ /** If the node has been emitted? */
+ int serialized;
+} yaml_anchors_t;
+
/**
* The emitter structure.
*
@@ -1546,7 +1567,7 @@ typedef struct yaml_emitter_s {
/** Write handler. */
yaml_write_handler_t *write_handler;
- /** A pointer for passing to the white handler. */
+ /** A pointer for passing to the write handler. */
void *write_handler_data;
/** Standard (string or file) output data. */
@@ -1713,7 +1734,7 @@ typedef struct yaml_emitter_s {
size_t length;
/** Does the scalar contain line breaks? */
int multiline;
- /** Can the scalar be expessed in the flow plain style? */
+ /** Can the scalar be expressed in the flow plain style? */
int flow_plain_allowed;
/** Can the scalar be expressed in the block plain style? */
int block_plain_allowed;
@@ -1740,14 +1761,7 @@ typedef struct yaml_emitter_s {
int closed;
/** The information associated with the document nodes. */
- struct {
- /** The number of references. */
- int references;
- /** The anchor id. */
- int anchor;
- /** If the node has been emitted? */
- int serialized;
- } *anchors;
+ yaml_anchors_t *anchors;
/** The last assigned anchor id. */
int last_anchor_id;
@@ -1936,10 +1950,10 @@ yaml_emitter_close(yaml_emitter_t *emitter);
/**
* Emit a YAML document.
*
- * The documen object may be generated using the yaml_parser_load() function
+ * The document object may be generated using the yaml_parser_load() function
* or the yaml_document_initialize() function. The emitter takes the
- * responsibility for the document object and destoys its content after
- * it is emitted. The document object is destroyedeven if the function fails.
+ * responsibility for the document object and destroys its content after
+ * it is emitted. The document object is destroyed even if the function fails.
*
* @param[in,out] emitter An emitter object.
* @param[in,out] document A document object.
diff --git a/ext/psych/yaml/yaml_private.h b/ext/psych/yaml/yaml_private.h
index ce262d3086..266a6bd3a7 100644
--- a/ext/psych/yaml/yaml_private.h
+++ b/ext/psych/yaml/yaml_private.h
@@ -2,8 +2,8 @@
#include RUBY_EXTCONF_H
#endif
-#if HAVE_CONFIG_H
-#include <config.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
#endif
#include <yaml.h>
@@ -12,16 +12,6 @@
#include <limits.h>
#include <stddef.h>
-#ifndef _MSC_VER
-#include <stdint.h>
-#else
-#ifdef _WIN64
-#define PTRDIFF_MAX _I64_MAX
-#else
-#define PTRDIFF_MAX INT_MAX
-#endif
-#endif
-
/*
* Memory management.
*/
@@ -81,6 +71,17 @@ yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
/*
+ * The maximum size of a YAML input file.
+ * This used to be PTRDIFF_MAX, but that's not entirely portable
+ * because stdint.h isn't available on all platforms.
+ * It is not entirely clear why this isn't the maximum value
+ * that can fit into the parser->offset field.
+ */
+
+#define MAX_FILE_SIZE (~(size_t)0 / 2)
+
+
+/*
* The size of other stacks and queues.
*/
@@ -93,7 +94,7 @@ yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
*/
#define BUFFER_INIT(context,buffer,size) \
- (((buffer).start = yaml_malloc(size)) ? \
+ (((buffer).start = (yaml_char_t *)yaml_malloc(size)) ? \
((buffer).last = (buffer).pointer = (buffer).start, \
(buffer).end = (buffer).start+(size), \
1) : \
@@ -133,7 +134,7 @@ yaml_string_join(
(value).pointer = (string))
#define STRING_INIT(context,string,size) \
- (((string).start = yaml_malloc(size)) ? \
+ (((string).start = YAML_MALLOC(size)) ? \
((string).pointer = (string).start, \
(string).end = (string).start+(size), \
memset((string).start, 0, (size)), \
@@ -174,14 +175,14 @@ yaml_string_join(
* Check the octet at the specified position.
*/
-#define CHECK_AT(string,octet,offset) \
+#define CHECK_AT(string,octet,offset) \
((string).pointer[offset] == (yaml_char_t)(octet))
/*
* Check the current octet in the buffer.
*/
-#define CHECK(string,octet) CHECK_AT((string),(octet),0)
+#define CHECK(string,octet) (CHECK_AT((string),(octet),0))
/*
* Check if the character at the specified position is an alphabetical
@@ -423,10 +424,10 @@ yaml_stack_extend(void **start, void **top, void **end);
YAML_DECLARE(int)
yaml_queue_extend(void **start, void **head, void **tail, void **end);
-#define STACK_INIT(context,stack,size) \
- (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \
+#define STACK_INIT(context,stack,type) \
+ (((stack).start = (type)yaml_malloc(INITIAL_STACK_SIZE*sizeof(*(stack).start))) ? \
((stack).top = (stack).start, \
- (stack).end = (stack).start+(size), \
+ (stack).end = (stack).start+INITIAL_STACK_SIZE, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
@@ -456,8 +457,8 @@ yaml_queue_extend(void **start, void **head, void **tail, void **end);
#define POP(context,stack) \
(*(--(stack).top))
-#define QUEUE_INIT(context,queue,size) \
- (((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \
+#define QUEUE_INIT(context,queue,size,type) \
+ (((queue).start = (type)yaml_malloc((size)*sizeof(*(queue).start))) ? \
((queue).head = (queue).tail = (queue).start, \
(queue).end = (queue).start+(size), \
1) : \
@@ -660,3 +661,28 @@ yaml_queue_extend(void **start, void **head, void **tail, void **end);
(node).data.mapping.pairs.end = (node_pairs_end), \
(node).data.mapping.pairs.top = (node_pairs_start), \
(node).data.mapping.style = (node_style))
+
+/* Strict C compiler warning helpers */
+
+#if defined(__clang__) || defined(__GNUC__)
+# define HASATTRIBUTE_UNUSED
+#endif
+#ifdef HASATTRIBUTE_UNUSED
+# define __attribute__unused__ __attribute__((__unused__))
+#else
+# define __attribute__unused__
+#endif
+
+/* Shim arguments are arguments that must be included in your function,
+ * but serve no purpose inside. Silence compiler warnings. */
+#define SHIM(a) /*@unused@*/ a __attribute__unused__
+
+/* UNUSED_PARAM() marks a shim argument in the body to silence compiler warnings */
+#ifdef __clang__
+# define UNUSED_PARAM(a) (void)(a);
+#else
+# define UNUSED_PARAM(a) /*@-noeffect*/if (0) (void)(a)/*@=noeffect*/;
+#endif
+
+#define YAML_MALLOC_STATIC(type) (type*)yaml_malloc(sizeof(type))
+#define YAML_MALLOC(size) (yaml_char_t *)yaml_malloc(size)
diff --git a/ext/pty/depend b/ext/pty/depend
index 4f0595c99d..23d6e6e329 100644
--- a/ext/pty/depend
+++ b/ext/pty/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
pty.o: $(RUBY_EXTCONF_H)
pty.o: $(arch_hdrdir)/ruby/config.h
+pty.o: $(hdrdir)/ruby.h
+pty.o: $(hdrdir)/ruby/internal/anyargs.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+pty.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+pty.o: $(hdrdir)/ruby/internal/assume.h
+pty.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+pty.o: $(hdrdir)/ruby/internal/attr/artificial.h
+pty.o: $(hdrdir)/ruby/internal/attr/cold.h
+pty.o: $(hdrdir)/ruby/internal/attr/const.h
+pty.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+pty.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+pty.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+pty.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+pty.o: $(hdrdir)/ruby/internal/attr/error.h
+pty.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+pty.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+pty.o: $(hdrdir)/ruby/internal/attr/format.h
+pty.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+pty.o: $(hdrdir)/ruby/internal/attr/noalias.h
+pty.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+pty.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+pty.o: $(hdrdir)/ruby/internal/attr/noinline.h
+pty.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+pty.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+pty.o: $(hdrdir)/ruby/internal/attr/pure.h
+pty.o: $(hdrdir)/ruby/internal/attr/restrict.h
+pty.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+pty.o: $(hdrdir)/ruby/internal/attr/warning.h
+pty.o: $(hdrdir)/ruby/internal/attr/weakref.h
+pty.o: $(hdrdir)/ruby/internal/cast.h
+pty.o: $(hdrdir)/ruby/internal/compiler_is.h
+pty.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+pty.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+pty.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+pty.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+pty.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+pty.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+pty.o: $(hdrdir)/ruby/internal/compiler_since.h
+pty.o: $(hdrdir)/ruby/internal/config.h
+pty.o: $(hdrdir)/ruby/internal/constant_p.h
+pty.o: $(hdrdir)/ruby/internal/core.h
+pty.o: $(hdrdir)/ruby/internal/core/rarray.h
+pty.o: $(hdrdir)/ruby/internal/core/rbasic.h
+pty.o: $(hdrdir)/ruby/internal/core/rbignum.h
+pty.o: $(hdrdir)/ruby/internal/core/rclass.h
+pty.o: $(hdrdir)/ruby/internal/core/rdata.h
+pty.o: $(hdrdir)/ruby/internal/core/rfile.h
+pty.o: $(hdrdir)/ruby/internal/core/rhash.h
+pty.o: $(hdrdir)/ruby/internal/core/robject.h
+pty.o: $(hdrdir)/ruby/internal/core/rregexp.h
+pty.o: $(hdrdir)/ruby/internal/core/rstring.h
+pty.o: $(hdrdir)/ruby/internal/core/rstruct.h
+pty.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+pty.o: $(hdrdir)/ruby/internal/ctype.h
+pty.o: $(hdrdir)/ruby/internal/dllexport.h
+pty.o: $(hdrdir)/ruby/internal/dosish.h
+pty.o: $(hdrdir)/ruby/internal/error.h
+pty.o: $(hdrdir)/ruby/internal/eval.h
+pty.o: $(hdrdir)/ruby/internal/event.h
+pty.o: $(hdrdir)/ruby/internal/fl_type.h
+pty.o: $(hdrdir)/ruby/internal/gc.h
+pty.o: $(hdrdir)/ruby/internal/glob.h
+pty.o: $(hdrdir)/ruby/internal/globals.h
+pty.o: $(hdrdir)/ruby/internal/has/attribute.h
+pty.o: $(hdrdir)/ruby/internal/has/builtin.h
+pty.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+pty.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+pty.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+pty.o: $(hdrdir)/ruby/internal/has/extension.h
+pty.o: $(hdrdir)/ruby/internal/has/feature.h
+pty.o: $(hdrdir)/ruby/internal/has/warning.h
+pty.o: $(hdrdir)/ruby/internal/intern/array.h
+pty.o: $(hdrdir)/ruby/internal/intern/bignum.h
+pty.o: $(hdrdir)/ruby/internal/intern/class.h
+pty.o: $(hdrdir)/ruby/internal/intern/compar.h
+pty.o: $(hdrdir)/ruby/internal/intern/complex.h
+pty.o: $(hdrdir)/ruby/internal/intern/cont.h
+pty.o: $(hdrdir)/ruby/internal/intern/dir.h
+pty.o: $(hdrdir)/ruby/internal/intern/enum.h
+pty.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+pty.o: $(hdrdir)/ruby/internal/intern/error.h
+pty.o: $(hdrdir)/ruby/internal/intern/eval.h
+pty.o: $(hdrdir)/ruby/internal/intern/file.h
+pty.o: $(hdrdir)/ruby/internal/intern/gc.h
+pty.o: $(hdrdir)/ruby/internal/intern/hash.h
+pty.o: $(hdrdir)/ruby/internal/intern/io.h
+pty.o: $(hdrdir)/ruby/internal/intern/load.h
+pty.o: $(hdrdir)/ruby/internal/intern/marshal.h
+pty.o: $(hdrdir)/ruby/internal/intern/numeric.h
+pty.o: $(hdrdir)/ruby/internal/intern/object.h
+pty.o: $(hdrdir)/ruby/internal/intern/parse.h
+pty.o: $(hdrdir)/ruby/internal/intern/proc.h
+pty.o: $(hdrdir)/ruby/internal/intern/process.h
+pty.o: $(hdrdir)/ruby/internal/intern/random.h
+pty.o: $(hdrdir)/ruby/internal/intern/range.h
+pty.o: $(hdrdir)/ruby/internal/intern/rational.h
+pty.o: $(hdrdir)/ruby/internal/intern/re.h
+pty.o: $(hdrdir)/ruby/internal/intern/ruby.h
+pty.o: $(hdrdir)/ruby/internal/intern/select.h
+pty.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+pty.o: $(hdrdir)/ruby/internal/intern/signal.h
+pty.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+pty.o: $(hdrdir)/ruby/internal/intern/string.h
+pty.o: $(hdrdir)/ruby/internal/intern/struct.h
+pty.o: $(hdrdir)/ruby/internal/intern/thread.h
+pty.o: $(hdrdir)/ruby/internal/intern/time.h
+pty.o: $(hdrdir)/ruby/internal/intern/variable.h
+pty.o: $(hdrdir)/ruby/internal/intern/vm.h
+pty.o: $(hdrdir)/ruby/internal/interpreter.h
+pty.o: $(hdrdir)/ruby/internal/iterator.h
+pty.o: $(hdrdir)/ruby/internal/memory.h
+pty.o: $(hdrdir)/ruby/internal/method.h
+pty.o: $(hdrdir)/ruby/internal/module.h
+pty.o: $(hdrdir)/ruby/internal/newobj.h
+pty.o: $(hdrdir)/ruby/internal/rgengc.h
+pty.o: $(hdrdir)/ruby/internal/scan_args.h
+pty.o: $(hdrdir)/ruby/internal/special_consts.h
+pty.o: $(hdrdir)/ruby/internal/static_assert.h
+pty.o: $(hdrdir)/ruby/internal/stdalign.h
+pty.o: $(hdrdir)/ruby/internal/stdbool.h
+pty.o: $(hdrdir)/ruby/internal/symbol.h
+pty.o: $(hdrdir)/ruby/internal/token_paste.h
+pty.o: $(hdrdir)/ruby/internal/value.h
+pty.o: $(hdrdir)/ruby/internal/value_type.h
+pty.o: $(hdrdir)/ruby/internal/variable.h
+pty.o: $(hdrdir)/ruby/internal/warning_push.h
+pty.o: $(hdrdir)/ruby/internal/xmalloc.h
+pty.o: $(hdrdir)/ruby/assert.h
pty.o: $(hdrdir)/ruby/backward.h
+pty.o: $(hdrdir)/ruby/backward/2/assume.h
+pty.o: $(hdrdir)/ruby/backward/2/attributes.h
+pty.o: $(hdrdir)/ruby/backward/2/bool.h
+pty.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+pty.o: $(hdrdir)/ruby/backward/2/inttypes.h
+pty.o: $(hdrdir)/ruby/backward/2/limits.h
+pty.o: $(hdrdir)/ruby/backward/2/long_long.h
+pty.o: $(hdrdir)/ruby/backward/2/stdalign.h
+pty.o: $(hdrdir)/ruby/backward/2/stdarg.h
pty.o: $(hdrdir)/ruby/defines.h
pty.o: $(hdrdir)/ruby/encoding.h
pty.o: $(hdrdir)/ruby/intern.h
@@ -13,7 +164,14 @@ pty.o: $(hdrdir)/ruby/ruby.h
pty.o: $(hdrdir)/ruby/st.h
pty.o: $(hdrdir)/ruby/subst.h
pty.o: $(hdrdir)/ruby/util.h
-pty.o: $(top_srcdir)/include/ruby.h
pty.o: $(top_srcdir)/internal.h
+pty.o: $(top_srcdir)/internal/array.h
+pty.o: $(top_srcdir)/internal/compilers.h
+pty.o: $(top_srcdir)/internal/gc.h
+pty.o: $(top_srcdir)/internal/imemo.h
+pty.o: $(top_srcdir)/internal/process.h
+pty.o: $(top_srcdir)/internal/signal.h
+pty.o: $(top_srcdir)/internal/static_assert.h
+pty.o: $(top_srcdir)/internal/warnings.h
pty.o: pty.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/pty/extconf.rb b/ext/pty/extconf.rb
index 4379177755..038bdf4d2c 100644
--- a/ext/pty/extconf.rb
+++ b/ext/pty/extconf.rb
@@ -3,16 +3,16 @@ require 'mkmf'
$INCFLAGS << " -I$(topdir) -I$(top_srcdir)"
-if /mswin|mingw|bccwin|nacl/ !~ RUBY_PLATFORM
+if /mswin|mingw|bccwin/ !~ RUBY_PLATFORM
have_header("sys/stropts.h")
have_func("setresuid")
have_header("libutil.h")
have_header("util.h") # OpenBSD openpty
have_header("pty.h")
have_header("pwd.h")
- have_library("util", "openpty")
+ util = have_library("util", "openpty")
if have_func("posix_openpt") or
- have_func("openpty") or
+ (util or have_func("openpty")) or
have_func("_getpty") or
have_func("ptsname") or
have_func("ioctl")
diff --git a/ext/pty/lib/expect.rb b/ext/pty/lib/expect.rb
index eaa6ccac94..5dbfa09ae9 100644
--- a/ext/pty/lib/expect.rb
+++ b/ext/pty/lib/expect.rb
@@ -43,13 +43,13 @@ class IO
@unusedBuf ||= ''
while true
if not @unusedBuf.empty?
- c = @unusedBuf.slice!(0).chr
+ c = @unusedBuf.slice!(0)
elsif !IO.select([self],nil,nil,timeout) or eof? then
result = nil
@unusedBuf = buf
break
else
- c = getc.chr
+ c = getc
end
buf << c
if $expect_verbose
@@ -57,7 +57,7 @@ class IO
STDOUT.flush
end
if mat=e_pat.match(buf) then
- result = [buf,*mat.to_a[1..-1]]
+ result = [buf,*mat.captures]
break
end
end
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 7726f154eb..e53871ede5 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -1,45 +1,51 @@
-#include "ruby/config.h"
+#include "ruby/config.h"
+
#ifdef RUBY_EXTCONF_H
-#include RUBY_EXTCONF_H
+# include RUBY_EXTCONF_H
#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <errno.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <fcntl.h>
+
#ifdef HAVE_PWD_H
-#include <pwd.h>
+# include <pwd.h>
#endif
+
#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
+# include <sys/ioctl.h>
#endif
+
#ifdef HAVE_LIBUTIL_H
-#include <libutil.h>
+# include <libutil.h>
#endif
+
#ifdef HAVE_UTIL_H
-#include <util.h>
+# include <util.h>
#endif
+
#ifdef HAVE_PTY_H
-#include <pty.h>
+# include <pty.h>
#endif
+
#if defined(HAVE_SYS_PARAM_H)
- /* for __FreeBSD_version */
+ /* for __FreeBSD_version */
# include <sys/param.h>
#endif
+
#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
+# include <sys/wait.h>
#else
-#define WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
+# define WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
#endif
-#include <ctype.h>
-#include "internal.h"
-#include "ruby/io.h"
-#include "ruby/util.h"
-
-#include <signal.h>
#ifdef HAVE_SYS_STROPTS_H
#include <sys/stropts.h>
#endif
@@ -48,6 +54,12 @@
#include <unistd.h>
#endif
+#include "internal.h"
+#include "internal/process.h"
+#include "internal/signal.h"
+#include "ruby/io.h"
+#include "ruby/util.h"
+
#define DEVICELEN 16
#ifndef HAVE_SETEUID
@@ -143,7 +155,7 @@ chfunc(void *data, char *errbuf, size_t errbuf_len)
dup2(slave,0);
dup2(slave,1);
dup2(slave,2);
- close(slave);
+ if (slave < 0 || slave > 2) (void)!close(slave);
#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID)
if (seteuid(getuid())) ERROR_EXIT("seteuid()");
#endif
@@ -182,7 +194,7 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
argv = &v;
}
- carg.execarg_obj = rb_execarg_new(argc, argv, 1);
+ carg.execarg_obj = rb_execarg_new(argc, argv, 1, 0);
carg.eargp = rb_execarg_get(carg.execarg_obj);
rb_execarg_parent_start(carg.execarg_obj);
@@ -224,6 +236,21 @@ no_mesg(char *slavedevice, int nomesg)
}
#endif
+#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
+static inline int
+ioctl_I_PUSH(int fd, const char *const name)
+{
+ int ret = 0;
+# if defined(I_FIND)
+ ret = ioctl(fd, I_FIND, name);
+# endif
+ if (ret == 0) {
+ ret = ioctl(fd, I_PUSH, name);
+ }
+ return ret;
+}
+#endif
+
static int
get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, int fail)
{
@@ -231,19 +258,13 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
/* Unix98 PTY */
int masterfd = -1, slavefd = -1;
char *slavedevice;
- struct sigaction dfl, old;
-
- dfl.sa_handler = SIG_DFL;
- dfl.sa_flags = 0;
- sigemptyset(&dfl.sa_mask);
-#if defined(__sun) || (defined(__FreeBSD__) && __FreeBSD_version < 902000)
+#if defined(__sun) || defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD_version < 902000)
/* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
/* FreeBSD 9.2 or later supports O_CLOEXEC
* http://www.freebsd.org/cgi/query-pr.cgi?pr=162374 */
if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
- if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
- if (grantpt(masterfd) == -1) goto grantpt_error;
+ if (rb_grantpt(masterfd) == -1) goto error;
rb_fd_fix_cloexec(masterfd);
#else
{
@@ -257,10 +278,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
if ((masterfd = posix_openpt(flags)) == -1) goto error;
}
rb_fd_fix_cloexec(masterfd);
- if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
- if (grantpt(masterfd) == -1) goto grantpt_error;
+ if (rb_grantpt(masterfd) == -1) goto error;
#endif
- if (sigaction(SIGCHLD, &old, NULL) == -1) goto error;
if (unlockpt(masterfd) == -1) goto error;
if ((slavedevice = ptsname(masterfd)) == NULL) goto error;
if (no_mesg(slavedevice, nomesg) == -1) goto error;
@@ -268,9 +287,9 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
rb_update_max_fd(slavefd);
#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
- if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
- if (ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
- if (ioctl(slavefd, I_PUSH, "ttcompat") == -1) goto error;
+ if (ioctl_I_PUSH(slavefd, "ptem") == -1) goto error;
+ if (ioctl_I_PUSH(slavefd, "ldterm") == -1) goto error;
+ if (ioctl_I_PUSH(slavefd, "ttcompat") == -1) goto error;
#endif
*master = masterfd;
@@ -278,8 +297,6 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
strlcpy(SlaveName, slavedevice, DEVICELEN);
return 0;
- grantpt_error:
- sigaction(SIGCHLD, &old, NULL);
error:
if (slavefd != -1) close(slavefd);
if (masterfd != -1) close(masterfd);
@@ -331,30 +348,26 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
extern char *ptsname(int);
extern int unlockpt(int);
- extern int grantpt(int);
#if defined(__sun)
/* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
- s = signal(SIGCHLD, SIG_DFL);
- if(grantpt(masterfd) == -1) goto error;
+ if(rb_grantpt(masterfd) == -1) goto error;
rb_fd_fix_cloexec(masterfd);
#else
if((masterfd = rb_cloexec_open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
rb_update_max_fd(masterfd);
- s = signal(SIGCHLD, SIG_DFL);
- if(grantpt(masterfd) == -1) goto error;
+ if(rb_grantpt(masterfd) == -1) goto error;
#endif
- signal(SIGCHLD, s);
if(unlockpt(masterfd) == -1) goto error;
if((slavedevice = ptsname(masterfd)) == NULL) goto error;
if (no_mesg(slavedevice, nomesg) == -1) goto error;
if((slavefd = rb_cloexec_open(slavedevice, O_RDWR, 0)) == -1) goto error;
rb_update_max_fd(slavefd);
#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
- if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
- if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
- ioctl(slavefd, I_PUSH, "ttcompat");
+ if(ioctl_I_PUSH(slavefd, "ptem") == -1) goto error;
+ if(ioctl_I_PUSH(slavefd, "ldterm") == -1) goto error;
+ ioctl_I_PUSH(slavefd, "ttcompat");
#endif
*master = masterfd;
*slave = slavefd;
@@ -451,11 +464,11 @@ pty_close_pty(VALUE assoc)
/*
* call-seq:
* PTY.open => [master_io, slave_file]
- * PTY.open {|master_io, slave_file| ... } => block value
+ * PTY.open {|(master_io, slave_file)| ... } => block value
*
* Allocates a pty (pseudo-terminal).
*
- * In the block form, yields two arguments <tt>master_io, slave_file</tt>
+ * In the block form, yields an array of two elements (<tt>master_io, slave_file</tt>)
* and the value of the block is returned from +open+.
*
* The IO and File are both closed after the block completes if they haven't
@@ -519,8 +532,9 @@ pty_open(VALUE klass)
}
static VALUE
-pty_detach_process(struct pty_info *info)
+pty_detach_process(VALUE v)
{
+ struct pty_info *info = (void *)v;
#ifdef WNOHANG
int st;
if (rb_waitpid(info->child_pid, &st, WNOHANG) <= 0)
@@ -664,7 +678,7 @@ pty_check(int argc, VALUE *argv, VALUE self)
if (!RTEST(exc)) return rb_last_status_get();
raise_from_check(cpid, status);
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
static VALUE cPTY;
@@ -679,8 +693,8 @@ static VALUE cPTY;
/*
* Document-class: PTY
*
- * Creates and managed pseudo terminals (PTYs). See also
- * http://en.wikipedia.org/wiki/Pseudo_terminal
+ * Creates and manages pseudo terminals (PTYs). See also
+ * https://en.wikipedia.org/wiki/Pseudo_terminal
*
* PTY allows you to allocate new terminals using ::open or ::spawn a new
* terminal with a specific command.
diff --git a/ext/racc/cparse/README b/ext/racc/cparse/README
index 7771108b84..550e8d49fe 100644
--- a/ext/racc/cparse/README
+++ b/ext/racc/cparse/README
@@ -7,5 +7,5 @@ your own parser, you must get Racc full package.
Get it from:
- http://i.loveruby.net/en/projects/racc
- - https://github.com/tenderlove/racc
+ - https://github.com/ruby/racc
diff --git a/ext/racc/cparse/cparse.c b/ext/racc/cparse/cparse.c
index b4429ed5f3..f71ed2bba9 100644
--- a/ext/racc/cparse/cparse.c
+++ b/ext/racc/cparse/cparse.c
@@ -11,7 +11,7 @@
*/
-#include "ruby/ruby.h"
+#include <ruby.h>
#ifndef FALSE
#define FALSE 0
@@ -24,7 +24,7 @@
Important Constants
----------------------------------------------------------------------- */
-#define RACC_VERSION "1.4.5"
+#define RACC_VERSION "1.4.15"
#define DEFAULT_TOKEN -1
#define ERROR_TOKEN 1
@@ -72,6 +72,10 @@ static ID id_d_e_pop;
# define LONG2NUM(i) INT2NUM(i)
#endif
+#ifndef HAVE_RB_ARY_SUBSEQ
+# define rb_ary_subseq(ary, beg, len) rb_ary_new4(len, RARRAY_PTR(ary) + beg)
+#endif
+
static ID value_to_id _((VALUE v));
static inline long num_to_long _((VALUE n));
@@ -208,7 +212,7 @@ static void extract_user_token _((struct cparse_params *v,
VALUE block_args, VALUE *tok, VALUE *val));
static void shift _((struct cparse_params* v, long act, VALUE tok, VALUE val));
static int reduce _((struct cparse_params* v, long act));
-static VALUE reduce0 _((VALUE block_args, VALUE data, VALUE self));
+static rb_block_call_func reduce0;
#ifdef DEBUG
# define D_puts(msg) if (v->sys_debug) puts(msg)
@@ -601,7 +605,7 @@ parse_main(struct cparse_params *v, VALUE tok, VALUE val, int resume)
user_yyerror:
if (v->errstatus == 3) {
if (v->t == vFINAL_TOKEN) {
- v->retval = Qfalse;
+ v->retval = Qnil;
v->fin = CP_FIN_EOT;
return;
}
@@ -704,7 +708,7 @@ reduce(struct cparse_params *v, long act)
}
static VALUE
-reduce0(VALUE val, VALUE data, VALUE self)
+reduce0(RB_BLOCK_CALL_FUNC_ARGLIST(_, data))
{
struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type);
VALUE reduce_to, reduce_len, method_id;
@@ -815,14 +819,16 @@ reduce0(VALUE val, VALUE data, VALUE self)
void
Init_cparse(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
VALUE Racc, Parser;
- ID id_racc = rb_intern("Racc");
+ ID id_racc = rb_intern_const("Racc");
if (rb_const_defined(rb_cObject, id_racc)) {
Racc = rb_const_get(rb_cObject, id_racc);
- Parser = rb_const_get_at(Racc, rb_intern("Parser"));
+ Parser = rb_const_get_at(Racc, rb_intern_const("Parser"));
}
else {
Racc = rb_define_module("Racc");
@@ -842,16 +848,16 @@ Init_cparse(void)
RaccBug = rb_eRuntimeError;
- id_yydebug = rb_intern("@yydebug");
- id_nexttoken = rb_intern("next_token");
- id_onerror = rb_intern("on_error");
- id_noreduce = rb_intern("_reduce_none");
- id_errstatus = rb_intern("@racc_error_status");
-
- id_d_shift = rb_intern("racc_shift");
- id_d_reduce = rb_intern("racc_reduce");
- id_d_accept = rb_intern("racc_accept");
- id_d_read_token = rb_intern("racc_read_token");
- id_d_next_state = rb_intern("racc_next_state");
- id_d_e_pop = rb_intern("racc_e_pop");
+ id_yydebug = rb_intern_const("@yydebug");
+ id_nexttoken = rb_intern_const("next_token");
+ id_onerror = rb_intern_const("on_error");
+ id_noreduce = rb_intern_const("_reduce_none");
+ id_errstatus = rb_intern_const("@racc_error_status");
+
+ id_d_shift = rb_intern_const("racc_shift");
+ id_d_reduce = rb_intern_const("racc_reduce");
+ id_d_accept = rb_intern_const("racc_accept");
+ id_d_read_token = rb_intern_const("racc_read_token");
+ id_d_next_state = rb_intern_const("racc_next_state");
+ id_d_e_pop = rb_intern_const("racc_e_pop");
}
diff --git a/ext/racc/cparse/depend b/ext/racc/cparse/depend
index 441d4df0f7..97d8445764 100644
--- a/ext/racc/cparse/depend
+++ b/ext/racc/cparse/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
cparse.o: $(RUBY_EXTCONF_H)
cparse.o: $(arch_hdrdir)/ruby/config.h
+cparse.o: $(hdrdir)/ruby.h
+cparse.o: $(hdrdir)/ruby/internal/anyargs.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+cparse.o: $(hdrdir)/ruby/internal/assume.h
+cparse.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+cparse.o: $(hdrdir)/ruby/internal/attr/artificial.h
+cparse.o: $(hdrdir)/ruby/internal/attr/cold.h
+cparse.o: $(hdrdir)/ruby/internal/attr/const.h
+cparse.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+cparse.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+cparse.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+cparse.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+cparse.o: $(hdrdir)/ruby/internal/attr/error.h
+cparse.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+cparse.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+cparse.o: $(hdrdir)/ruby/internal/attr/format.h
+cparse.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noalias.h
+cparse.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noinline.h
+cparse.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+cparse.o: $(hdrdir)/ruby/internal/attr/pure.h
+cparse.o: $(hdrdir)/ruby/internal/attr/restrict.h
+cparse.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+cparse.o: $(hdrdir)/ruby/internal/attr/warning.h
+cparse.o: $(hdrdir)/ruby/internal/attr/weakref.h
+cparse.o: $(hdrdir)/ruby/internal/cast.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_since.h
+cparse.o: $(hdrdir)/ruby/internal/config.h
+cparse.o: $(hdrdir)/ruby/internal/constant_p.h
+cparse.o: $(hdrdir)/ruby/internal/core.h
+cparse.o: $(hdrdir)/ruby/internal/core/rarray.h
+cparse.o: $(hdrdir)/ruby/internal/core/rbasic.h
+cparse.o: $(hdrdir)/ruby/internal/core/rbignum.h
+cparse.o: $(hdrdir)/ruby/internal/core/rclass.h
+cparse.o: $(hdrdir)/ruby/internal/core/rdata.h
+cparse.o: $(hdrdir)/ruby/internal/core/rfile.h
+cparse.o: $(hdrdir)/ruby/internal/core/rhash.h
+cparse.o: $(hdrdir)/ruby/internal/core/robject.h
+cparse.o: $(hdrdir)/ruby/internal/core/rregexp.h
+cparse.o: $(hdrdir)/ruby/internal/core/rstring.h
+cparse.o: $(hdrdir)/ruby/internal/core/rstruct.h
+cparse.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+cparse.o: $(hdrdir)/ruby/internal/ctype.h
+cparse.o: $(hdrdir)/ruby/internal/dllexport.h
+cparse.o: $(hdrdir)/ruby/internal/dosish.h
+cparse.o: $(hdrdir)/ruby/internal/error.h
+cparse.o: $(hdrdir)/ruby/internal/eval.h
+cparse.o: $(hdrdir)/ruby/internal/event.h
+cparse.o: $(hdrdir)/ruby/internal/fl_type.h
+cparse.o: $(hdrdir)/ruby/internal/gc.h
+cparse.o: $(hdrdir)/ruby/internal/glob.h
+cparse.o: $(hdrdir)/ruby/internal/globals.h
+cparse.o: $(hdrdir)/ruby/internal/has/attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/builtin.h
+cparse.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/extension.h
+cparse.o: $(hdrdir)/ruby/internal/has/feature.h
+cparse.o: $(hdrdir)/ruby/internal/has/warning.h
+cparse.o: $(hdrdir)/ruby/internal/intern/array.h
+cparse.o: $(hdrdir)/ruby/internal/intern/bignum.h
+cparse.o: $(hdrdir)/ruby/internal/intern/class.h
+cparse.o: $(hdrdir)/ruby/internal/intern/compar.h
+cparse.o: $(hdrdir)/ruby/internal/intern/complex.h
+cparse.o: $(hdrdir)/ruby/internal/intern/cont.h
+cparse.o: $(hdrdir)/ruby/internal/intern/dir.h
+cparse.o: $(hdrdir)/ruby/internal/intern/enum.h
+cparse.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+cparse.o: $(hdrdir)/ruby/internal/intern/error.h
+cparse.o: $(hdrdir)/ruby/internal/intern/eval.h
+cparse.o: $(hdrdir)/ruby/internal/intern/file.h
+cparse.o: $(hdrdir)/ruby/internal/intern/gc.h
+cparse.o: $(hdrdir)/ruby/internal/intern/hash.h
+cparse.o: $(hdrdir)/ruby/internal/intern/io.h
+cparse.o: $(hdrdir)/ruby/internal/intern/load.h
+cparse.o: $(hdrdir)/ruby/internal/intern/marshal.h
+cparse.o: $(hdrdir)/ruby/internal/intern/numeric.h
+cparse.o: $(hdrdir)/ruby/internal/intern/object.h
+cparse.o: $(hdrdir)/ruby/internal/intern/parse.h
+cparse.o: $(hdrdir)/ruby/internal/intern/proc.h
+cparse.o: $(hdrdir)/ruby/internal/intern/process.h
+cparse.o: $(hdrdir)/ruby/internal/intern/random.h
+cparse.o: $(hdrdir)/ruby/internal/intern/range.h
+cparse.o: $(hdrdir)/ruby/internal/intern/rational.h
+cparse.o: $(hdrdir)/ruby/internal/intern/re.h
+cparse.o: $(hdrdir)/ruby/internal/intern/ruby.h
+cparse.o: $(hdrdir)/ruby/internal/intern/select.h
+cparse.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+cparse.o: $(hdrdir)/ruby/internal/intern/signal.h
+cparse.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+cparse.o: $(hdrdir)/ruby/internal/intern/string.h
+cparse.o: $(hdrdir)/ruby/internal/intern/struct.h
+cparse.o: $(hdrdir)/ruby/internal/intern/thread.h
+cparse.o: $(hdrdir)/ruby/internal/intern/time.h
+cparse.o: $(hdrdir)/ruby/internal/intern/variable.h
+cparse.o: $(hdrdir)/ruby/internal/intern/vm.h
+cparse.o: $(hdrdir)/ruby/internal/interpreter.h
+cparse.o: $(hdrdir)/ruby/internal/iterator.h
+cparse.o: $(hdrdir)/ruby/internal/memory.h
+cparse.o: $(hdrdir)/ruby/internal/method.h
+cparse.o: $(hdrdir)/ruby/internal/module.h
+cparse.o: $(hdrdir)/ruby/internal/newobj.h
+cparse.o: $(hdrdir)/ruby/internal/rgengc.h
+cparse.o: $(hdrdir)/ruby/internal/scan_args.h
+cparse.o: $(hdrdir)/ruby/internal/special_consts.h
+cparse.o: $(hdrdir)/ruby/internal/static_assert.h
+cparse.o: $(hdrdir)/ruby/internal/stdalign.h
+cparse.o: $(hdrdir)/ruby/internal/stdbool.h
+cparse.o: $(hdrdir)/ruby/internal/symbol.h
+cparse.o: $(hdrdir)/ruby/internal/token_paste.h
+cparse.o: $(hdrdir)/ruby/internal/value.h
+cparse.o: $(hdrdir)/ruby/internal/value_type.h
+cparse.o: $(hdrdir)/ruby/internal/variable.h
+cparse.o: $(hdrdir)/ruby/internal/warning_push.h
+cparse.o: $(hdrdir)/ruby/internal/xmalloc.h
+cparse.o: $(hdrdir)/ruby/assert.h
cparse.o: $(hdrdir)/ruby/backward.h
+cparse.o: $(hdrdir)/ruby/backward/2/assume.h
+cparse.o: $(hdrdir)/ruby/backward/2/attributes.h
+cparse.o: $(hdrdir)/ruby/backward/2/bool.h
+cparse.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+cparse.o: $(hdrdir)/ruby/backward/2/inttypes.h
+cparse.o: $(hdrdir)/ruby/backward/2/limits.h
+cparse.o: $(hdrdir)/ruby/backward/2/long_long.h
+cparse.o: $(hdrdir)/ruby/backward/2/stdalign.h
+cparse.o: $(hdrdir)/ruby/backward/2/stdarg.h
cparse.o: $(hdrdir)/ruby/defines.h
cparse.o: $(hdrdir)/ruby/intern.h
cparse.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/racc/cparse/extconf.rb b/ext/racc/cparse/extconf.rb
index dfddf57111..3b4f594b9d 100644
--- a/ext/racc/cparse/extconf.rb
+++ b/ext/racc/cparse/extconf.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: false
-# $Id$
+#
require 'mkmf'
-have_func('rb_block_call', 'ruby/ruby.h')
+
+have_func('rb_ary_subseq')
+
create_makefile 'racc/cparse'
diff --git a/ext/rbconfig/sizeof/depend b/ext/rbconfig/sizeof/depend
index 143cbb0ee5..09b62961c0 100644
--- a/ext/rbconfig/sizeof/depend
+++ b/ext/rbconfig/sizeof/depend
@@ -16,7 +16,157 @@ sizes.c: $(top_srcdir)/tool/generic_erb.rb \
# AUTOGENERATED DEPENDENCIES START
limits.o: $(RUBY_EXTCONF_H)
limits.o: $(arch_hdrdir)/ruby/config.h
+limits.o: $(hdrdir)/ruby/internal/anyargs.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+limits.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+limits.o: $(hdrdir)/ruby/internal/assume.h
+limits.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+limits.o: $(hdrdir)/ruby/internal/attr/artificial.h
+limits.o: $(hdrdir)/ruby/internal/attr/cold.h
+limits.o: $(hdrdir)/ruby/internal/attr/const.h
+limits.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+limits.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+limits.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+limits.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+limits.o: $(hdrdir)/ruby/internal/attr/error.h
+limits.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+limits.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+limits.o: $(hdrdir)/ruby/internal/attr/format.h
+limits.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+limits.o: $(hdrdir)/ruby/internal/attr/noalias.h
+limits.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+limits.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+limits.o: $(hdrdir)/ruby/internal/attr/noinline.h
+limits.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+limits.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+limits.o: $(hdrdir)/ruby/internal/attr/pure.h
+limits.o: $(hdrdir)/ruby/internal/attr/restrict.h
+limits.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+limits.o: $(hdrdir)/ruby/internal/attr/warning.h
+limits.o: $(hdrdir)/ruby/internal/attr/weakref.h
+limits.o: $(hdrdir)/ruby/internal/cast.h
+limits.o: $(hdrdir)/ruby/internal/compiler_is.h
+limits.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+limits.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+limits.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+limits.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+limits.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+limits.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+limits.o: $(hdrdir)/ruby/internal/compiler_since.h
+limits.o: $(hdrdir)/ruby/internal/config.h
+limits.o: $(hdrdir)/ruby/internal/constant_p.h
+limits.o: $(hdrdir)/ruby/internal/core.h
+limits.o: $(hdrdir)/ruby/internal/core/rarray.h
+limits.o: $(hdrdir)/ruby/internal/core/rbasic.h
+limits.o: $(hdrdir)/ruby/internal/core/rbignum.h
+limits.o: $(hdrdir)/ruby/internal/core/rclass.h
+limits.o: $(hdrdir)/ruby/internal/core/rdata.h
+limits.o: $(hdrdir)/ruby/internal/core/rfile.h
+limits.o: $(hdrdir)/ruby/internal/core/rhash.h
+limits.o: $(hdrdir)/ruby/internal/core/robject.h
+limits.o: $(hdrdir)/ruby/internal/core/rregexp.h
+limits.o: $(hdrdir)/ruby/internal/core/rstring.h
+limits.o: $(hdrdir)/ruby/internal/core/rstruct.h
+limits.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+limits.o: $(hdrdir)/ruby/internal/ctype.h
+limits.o: $(hdrdir)/ruby/internal/dllexport.h
+limits.o: $(hdrdir)/ruby/internal/dosish.h
+limits.o: $(hdrdir)/ruby/internal/error.h
+limits.o: $(hdrdir)/ruby/internal/eval.h
+limits.o: $(hdrdir)/ruby/internal/event.h
+limits.o: $(hdrdir)/ruby/internal/fl_type.h
+limits.o: $(hdrdir)/ruby/internal/gc.h
+limits.o: $(hdrdir)/ruby/internal/glob.h
+limits.o: $(hdrdir)/ruby/internal/globals.h
+limits.o: $(hdrdir)/ruby/internal/has/attribute.h
+limits.o: $(hdrdir)/ruby/internal/has/builtin.h
+limits.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+limits.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+limits.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+limits.o: $(hdrdir)/ruby/internal/has/extension.h
+limits.o: $(hdrdir)/ruby/internal/has/feature.h
+limits.o: $(hdrdir)/ruby/internal/has/warning.h
+limits.o: $(hdrdir)/ruby/internal/intern/array.h
+limits.o: $(hdrdir)/ruby/internal/intern/bignum.h
+limits.o: $(hdrdir)/ruby/internal/intern/class.h
+limits.o: $(hdrdir)/ruby/internal/intern/compar.h
+limits.o: $(hdrdir)/ruby/internal/intern/complex.h
+limits.o: $(hdrdir)/ruby/internal/intern/cont.h
+limits.o: $(hdrdir)/ruby/internal/intern/dir.h
+limits.o: $(hdrdir)/ruby/internal/intern/enum.h
+limits.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+limits.o: $(hdrdir)/ruby/internal/intern/error.h
+limits.o: $(hdrdir)/ruby/internal/intern/eval.h
+limits.o: $(hdrdir)/ruby/internal/intern/file.h
+limits.o: $(hdrdir)/ruby/internal/intern/gc.h
+limits.o: $(hdrdir)/ruby/internal/intern/hash.h
+limits.o: $(hdrdir)/ruby/internal/intern/io.h
+limits.o: $(hdrdir)/ruby/internal/intern/load.h
+limits.o: $(hdrdir)/ruby/internal/intern/marshal.h
+limits.o: $(hdrdir)/ruby/internal/intern/numeric.h
+limits.o: $(hdrdir)/ruby/internal/intern/object.h
+limits.o: $(hdrdir)/ruby/internal/intern/parse.h
+limits.o: $(hdrdir)/ruby/internal/intern/proc.h
+limits.o: $(hdrdir)/ruby/internal/intern/process.h
+limits.o: $(hdrdir)/ruby/internal/intern/random.h
+limits.o: $(hdrdir)/ruby/internal/intern/range.h
+limits.o: $(hdrdir)/ruby/internal/intern/rational.h
+limits.o: $(hdrdir)/ruby/internal/intern/re.h
+limits.o: $(hdrdir)/ruby/internal/intern/ruby.h
+limits.o: $(hdrdir)/ruby/internal/intern/select.h
+limits.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+limits.o: $(hdrdir)/ruby/internal/intern/signal.h
+limits.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+limits.o: $(hdrdir)/ruby/internal/intern/string.h
+limits.o: $(hdrdir)/ruby/internal/intern/struct.h
+limits.o: $(hdrdir)/ruby/internal/intern/thread.h
+limits.o: $(hdrdir)/ruby/internal/intern/time.h
+limits.o: $(hdrdir)/ruby/internal/intern/variable.h
+limits.o: $(hdrdir)/ruby/internal/intern/vm.h
+limits.o: $(hdrdir)/ruby/internal/interpreter.h
+limits.o: $(hdrdir)/ruby/internal/iterator.h
+limits.o: $(hdrdir)/ruby/internal/memory.h
+limits.o: $(hdrdir)/ruby/internal/method.h
+limits.o: $(hdrdir)/ruby/internal/module.h
+limits.o: $(hdrdir)/ruby/internal/newobj.h
+limits.o: $(hdrdir)/ruby/internal/rgengc.h
+limits.o: $(hdrdir)/ruby/internal/scan_args.h
+limits.o: $(hdrdir)/ruby/internal/special_consts.h
+limits.o: $(hdrdir)/ruby/internal/static_assert.h
+limits.o: $(hdrdir)/ruby/internal/stdalign.h
+limits.o: $(hdrdir)/ruby/internal/stdbool.h
+limits.o: $(hdrdir)/ruby/internal/symbol.h
+limits.o: $(hdrdir)/ruby/internal/token_paste.h
+limits.o: $(hdrdir)/ruby/internal/value.h
+limits.o: $(hdrdir)/ruby/internal/value_type.h
+limits.o: $(hdrdir)/ruby/internal/variable.h
+limits.o: $(hdrdir)/ruby/internal/warning_push.h
+limits.o: $(hdrdir)/ruby/internal/xmalloc.h
+limits.o: $(hdrdir)/ruby/assert.h
limits.o: $(hdrdir)/ruby/backward.h
+limits.o: $(hdrdir)/ruby/backward/2/assume.h
+limits.o: $(hdrdir)/ruby/backward/2/attributes.h
+limits.o: $(hdrdir)/ruby/backward/2/bool.h
+limits.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+limits.o: $(hdrdir)/ruby/backward/2/inttypes.h
+limits.o: $(hdrdir)/ruby/backward/2/limits.h
+limits.o: $(hdrdir)/ruby/backward/2/long_long.h
+limits.o: $(hdrdir)/ruby/backward/2/stdalign.h
+limits.o: $(hdrdir)/ruby/backward/2/stdarg.h
limits.o: $(hdrdir)/ruby/defines.h
limits.o: $(hdrdir)/ruby/intern.h
limits.o: $(hdrdir)/ruby/missing.h
@@ -26,7 +176,157 @@ limits.o: $(hdrdir)/ruby/subst.h
limits.o: limits.c
sizes.o: $(RUBY_EXTCONF_H)
sizes.o: $(arch_hdrdir)/ruby/config.h
+sizes.o: $(hdrdir)/ruby/internal/anyargs.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+sizes.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+sizes.o: $(hdrdir)/ruby/internal/assume.h
+sizes.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+sizes.o: $(hdrdir)/ruby/internal/attr/artificial.h
+sizes.o: $(hdrdir)/ruby/internal/attr/cold.h
+sizes.o: $(hdrdir)/ruby/internal/attr/const.h
+sizes.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+sizes.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+sizes.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+sizes.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+sizes.o: $(hdrdir)/ruby/internal/attr/error.h
+sizes.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+sizes.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+sizes.o: $(hdrdir)/ruby/internal/attr/format.h
+sizes.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+sizes.o: $(hdrdir)/ruby/internal/attr/noalias.h
+sizes.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+sizes.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+sizes.o: $(hdrdir)/ruby/internal/attr/noinline.h
+sizes.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+sizes.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+sizes.o: $(hdrdir)/ruby/internal/attr/pure.h
+sizes.o: $(hdrdir)/ruby/internal/attr/restrict.h
+sizes.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+sizes.o: $(hdrdir)/ruby/internal/attr/warning.h
+sizes.o: $(hdrdir)/ruby/internal/attr/weakref.h
+sizes.o: $(hdrdir)/ruby/internal/cast.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_is.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+sizes.o: $(hdrdir)/ruby/internal/compiler_since.h
+sizes.o: $(hdrdir)/ruby/internal/config.h
+sizes.o: $(hdrdir)/ruby/internal/constant_p.h
+sizes.o: $(hdrdir)/ruby/internal/core.h
+sizes.o: $(hdrdir)/ruby/internal/core/rarray.h
+sizes.o: $(hdrdir)/ruby/internal/core/rbasic.h
+sizes.o: $(hdrdir)/ruby/internal/core/rbignum.h
+sizes.o: $(hdrdir)/ruby/internal/core/rclass.h
+sizes.o: $(hdrdir)/ruby/internal/core/rdata.h
+sizes.o: $(hdrdir)/ruby/internal/core/rfile.h
+sizes.o: $(hdrdir)/ruby/internal/core/rhash.h
+sizes.o: $(hdrdir)/ruby/internal/core/robject.h
+sizes.o: $(hdrdir)/ruby/internal/core/rregexp.h
+sizes.o: $(hdrdir)/ruby/internal/core/rstring.h
+sizes.o: $(hdrdir)/ruby/internal/core/rstruct.h
+sizes.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+sizes.o: $(hdrdir)/ruby/internal/ctype.h
+sizes.o: $(hdrdir)/ruby/internal/dllexport.h
+sizes.o: $(hdrdir)/ruby/internal/dosish.h
+sizes.o: $(hdrdir)/ruby/internal/error.h
+sizes.o: $(hdrdir)/ruby/internal/eval.h
+sizes.o: $(hdrdir)/ruby/internal/event.h
+sizes.o: $(hdrdir)/ruby/internal/fl_type.h
+sizes.o: $(hdrdir)/ruby/internal/gc.h
+sizes.o: $(hdrdir)/ruby/internal/glob.h
+sizes.o: $(hdrdir)/ruby/internal/globals.h
+sizes.o: $(hdrdir)/ruby/internal/has/attribute.h
+sizes.o: $(hdrdir)/ruby/internal/has/builtin.h
+sizes.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+sizes.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+sizes.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+sizes.o: $(hdrdir)/ruby/internal/has/extension.h
+sizes.o: $(hdrdir)/ruby/internal/has/feature.h
+sizes.o: $(hdrdir)/ruby/internal/has/warning.h
+sizes.o: $(hdrdir)/ruby/internal/intern/array.h
+sizes.o: $(hdrdir)/ruby/internal/intern/bignum.h
+sizes.o: $(hdrdir)/ruby/internal/intern/class.h
+sizes.o: $(hdrdir)/ruby/internal/intern/compar.h
+sizes.o: $(hdrdir)/ruby/internal/intern/complex.h
+sizes.o: $(hdrdir)/ruby/internal/intern/cont.h
+sizes.o: $(hdrdir)/ruby/internal/intern/dir.h
+sizes.o: $(hdrdir)/ruby/internal/intern/enum.h
+sizes.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+sizes.o: $(hdrdir)/ruby/internal/intern/error.h
+sizes.o: $(hdrdir)/ruby/internal/intern/eval.h
+sizes.o: $(hdrdir)/ruby/internal/intern/file.h
+sizes.o: $(hdrdir)/ruby/internal/intern/gc.h
+sizes.o: $(hdrdir)/ruby/internal/intern/hash.h
+sizes.o: $(hdrdir)/ruby/internal/intern/io.h
+sizes.o: $(hdrdir)/ruby/internal/intern/load.h
+sizes.o: $(hdrdir)/ruby/internal/intern/marshal.h
+sizes.o: $(hdrdir)/ruby/internal/intern/numeric.h
+sizes.o: $(hdrdir)/ruby/internal/intern/object.h
+sizes.o: $(hdrdir)/ruby/internal/intern/parse.h
+sizes.o: $(hdrdir)/ruby/internal/intern/proc.h
+sizes.o: $(hdrdir)/ruby/internal/intern/process.h
+sizes.o: $(hdrdir)/ruby/internal/intern/random.h
+sizes.o: $(hdrdir)/ruby/internal/intern/range.h
+sizes.o: $(hdrdir)/ruby/internal/intern/rational.h
+sizes.o: $(hdrdir)/ruby/internal/intern/re.h
+sizes.o: $(hdrdir)/ruby/internal/intern/ruby.h
+sizes.o: $(hdrdir)/ruby/internal/intern/select.h
+sizes.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+sizes.o: $(hdrdir)/ruby/internal/intern/signal.h
+sizes.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+sizes.o: $(hdrdir)/ruby/internal/intern/string.h
+sizes.o: $(hdrdir)/ruby/internal/intern/struct.h
+sizes.o: $(hdrdir)/ruby/internal/intern/thread.h
+sizes.o: $(hdrdir)/ruby/internal/intern/time.h
+sizes.o: $(hdrdir)/ruby/internal/intern/variable.h
+sizes.o: $(hdrdir)/ruby/internal/intern/vm.h
+sizes.o: $(hdrdir)/ruby/internal/interpreter.h
+sizes.o: $(hdrdir)/ruby/internal/iterator.h
+sizes.o: $(hdrdir)/ruby/internal/memory.h
+sizes.o: $(hdrdir)/ruby/internal/method.h
+sizes.o: $(hdrdir)/ruby/internal/module.h
+sizes.o: $(hdrdir)/ruby/internal/newobj.h
+sizes.o: $(hdrdir)/ruby/internal/rgengc.h
+sizes.o: $(hdrdir)/ruby/internal/scan_args.h
+sizes.o: $(hdrdir)/ruby/internal/special_consts.h
+sizes.o: $(hdrdir)/ruby/internal/static_assert.h
+sizes.o: $(hdrdir)/ruby/internal/stdalign.h
+sizes.o: $(hdrdir)/ruby/internal/stdbool.h
+sizes.o: $(hdrdir)/ruby/internal/symbol.h
+sizes.o: $(hdrdir)/ruby/internal/token_paste.h
+sizes.o: $(hdrdir)/ruby/internal/value.h
+sizes.o: $(hdrdir)/ruby/internal/value_type.h
+sizes.o: $(hdrdir)/ruby/internal/variable.h
+sizes.o: $(hdrdir)/ruby/internal/warning_push.h
+sizes.o: $(hdrdir)/ruby/internal/xmalloc.h
+sizes.o: $(hdrdir)/ruby/assert.h
sizes.o: $(hdrdir)/ruby/backward.h
+sizes.o: $(hdrdir)/ruby/backward/2/assume.h
+sizes.o: $(hdrdir)/ruby/backward/2/attributes.h
+sizes.o: $(hdrdir)/ruby/backward/2/bool.h
+sizes.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+sizes.o: $(hdrdir)/ruby/backward/2/inttypes.h
+sizes.o: $(hdrdir)/ruby/backward/2/limits.h
+sizes.o: $(hdrdir)/ruby/backward/2/long_long.h
+sizes.o: $(hdrdir)/ruby/backward/2/stdalign.h
+sizes.o: $(hdrdir)/ruby/backward/2/stdarg.h
sizes.o: $(hdrdir)/ruby/defines.h
sizes.o: $(hdrdir)/ruby/intern.h
sizes.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/readline/.gitignore b/ext/readline/.gitignore
new file mode 100644
index 0000000000..3d372989ae
--- /dev/null
+++ b/ext/readline/.gitignore
@@ -0,0 +1 @@
+/readline-[1-9]*.*
diff --git a/ext/readline/depend b/ext/readline/depend
index eb7a047473..a6ad681cd0 100644
--- a/ext/readline/depend
+++ b/ext/readline/depend
@@ -1,10 +1,160 @@
# AUTOGENERATED DEPENDENCIES START
readline.o: $(RUBY_EXTCONF_H)
readline.o: $(arch_hdrdir)/ruby/config.h
+readline.o: $(hdrdir)/ruby/assert.h
readline.o: $(hdrdir)/ruby/backward.h
+readline.o: $(hdrdir)/ruby/backward/2/assume.h
+readline.o: $(hdrdir)/ruby/backward/2/attributes.h
+readline.o: $(hdrdir)/ruby/backward/2/bool.h
+readline.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+readline.o: $(hdrdir)/ruby/backward/2/inttypes.h
+readline.o: $(hdrdir)/ruby/backward/2/limits.h
+readline.o: $(hdrdir)/ruby/backward/2/long_long.h
+readline.o: $(hdrdir)/ruby/backward/2/stdalign.h
+readline.o: $(hdrdir)/ruby/backward/2/stdarg.h
readline.o: $(hdrdir)/ruby/defines.h
readline.o: $(hdrdir)/ruby/encoding.h
readline.o: $(hdrdir)/ruby/intern.h
+readline.o: $(hdrdir)/ruby/internal/anyargs.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+readline.o: $(hdrdir)/ruby/internal/assume.h
+readline.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+readline.o: $(hdrdir)/ruby/internal/attr/artificial.h
+readline.o: $(hdrdir)/ruby/internal/attr/cold.h
+readline.o: $(hdrdir)/ruby/internal/attr/const.h
+readline.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+readline.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+readline.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+readline.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+readline.o: $(hdrdir)/ruby/internal/attr/error.h
+readline.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+readline.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+readline.o: $(hdrdir)/ruby/internal/attr/format.h
+readline.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+readline.o: $(hdrdir)/ruby/internal/attr/noalias.h
+readline.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+readline.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+readline.o: $(hdrdir)/ruby/internal/attr/noinline.h
+readline.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+readline.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+readline.o: $(hdrdir)/ruby/internal/attr/pure.h
+readline.o: $(hdrdir)/ruby/internal/attr/restrict.h
+readline.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+readline.o: $(hdrdir)/ruby/internal/attr/warning.h
+readline.o: $(hdrdir)/ruby/internal/attr/weakref.h
+readline.o: $(hdrdir)/ruby/internal/cast.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+readline.o: $(hdrdir)/ruby/internal/compiler_since.h
+readline.o: $(hdrdir)/ruby/internal/config.h
+readline.o: $(hdrdir)/ruby/internal/constant_p.h
+readline.o: $(hdrdir)/ruby/internal/core.h
+readline.o: $(hdrdir)/ruby/internal/core/rarray.h
+readline.o: $(hdrdir)/ruby/internal/core/rbasic.h
+readline.o: $(hdrdir)/ruby/internal/core/rbignum.h
+readline.o: $(hdrdir)/ruby/internal/core/rclass.h
+readline.o: $(hdrdir)/ruby/internal/core/rdata.h
+readline.o: $(hdrdir)/ruby/internal/core/rfile.h
+readline.o: $(hdrdir)/ruby/internal/core/rhash.h
+readline.o: $(hdrdir)/ruby/internal/core/robject.h
+readline.o: $(hdrdir)/ruby/internal/core/rregexp.h
+readline.o: $(hdrdir)/ruby/internal/core/rstring.h
+readline.o: $(hdrdir)/ruby/internal/core/rstruct.h
+readline.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+readline.o: $(hdrdir)/ruby/internal/ctype.h
+readline.o: $(hdrdir)/ruby/internal/dllexport.h
+readline.o: $(hdrdir)/ruby/internal/dosish.h
+readline.o: $(hdrdir)/ruby/internal/error.h
+readline.o: $(hdrdir)/ruby/internal/eval.h
+readline.o: $(hdrdir)/ruby/internal/event.h
+readline.o: $(hdrdir)/ruby/internal/fl_type.h
+readline.o: $(hdrdir)/ruby/internal/gc.h
+readline.o: $(hdrdir)/ruby/internal/glob.h
+readline.o: $(hdrdir)/ruby/internal/globals.h
+readline.o: $(hdrdir)/ruby/internal/has/attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/builtin.h
+readline.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/extension.h
+readline.o: $(hdrdir)/ruby/internal/has/feature.h
+readline.o: $(hdrdir)/ruby/internal/has/warning.h
+readline.o: $(hdrdir)/ruby/internal/intern/array.h
+readline.o: $(hdrdir)/ruby/internal/intern/bignum.h
+readline.o: $(hdrdir)/ruby/internal/intern/class.h
+readline.o: $(hdrdir)/ruby/internal/intern/compar.h
+readline.o: $(hdrdir)/ruby/internal/intern/complex.h
+readline.o: $(hdrdir)/ruby/internal/intern/cont.h
+readline.o: $(hdrdir)/ruby/internal/intern/dir.h
+readline.o: $(hdrdir)/ruby/internal/intern/enum.h
+readline.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+readline.o: $(hdrdir)/ruby/internal/intern/error.h
+readline.o: $(hdrdir)/ruby/internal/intern/eval.h
+readline.o: $(hdrdir)/ruby/internal/intern/file.h
+readline.o: $(hdrdir)/ruby/internal/intern/gc.h
+readline.o: $(hdrdir)/ruby/internal/intern/hash.h
+readline.o: $(hdrdir)/ruby/internal/intern/io.h
+readline.o: $(hdrdir)/ruby/internal/intern/load.h
+readline.o: $(hdrdir)/ruby/internal/intern/marshal.h
+readline.o: $(hdrdir)/ruby/internal/intern/numeric.h
+readline.o: $(hdrdir)/ruby/internal/intern/object.h
+readline.o: $(hdrdir)/ruby/internal/intern/parse.h
+readline.o: $(hdrdir)/ruby/internal/intern/proc.h
+readline.o: $(hdrdir)/ruby/internal/intern/process.h
+readline.o: $(hdrdir)/ruby/internal/intern/random.h
+readline.o: $(hdrdir)/ruby/internal/intern/range.h
+readline.o: $(hdrdir)/ruby/internal/intern/rational.h
+readline.o: $(hdrdir)/ruby/internal/intern/re.h
+readline.o: $(hdrdir)/ruby/internal/intern/ruby.h
+readline.o: $(hdrdir)/ruby/internal/intern/select.h
+readline.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+readline.o: $(hdrdir)/ruby/internal/intern/signal.h
+readline.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+readline.o: $(hdrdir)/ruby/internal/intern/string.h
+readline.o: $(hdrdir)/ruby/internal/intern/struct.h
+readline.o: $(hdrdir)/ruby/internal/intern/thread.h
+readline.o: $(hdrdir)/ruby/internal/intern/time.h
+readline.o: $(hdrdir)/ruby/internal/intern/variable.h
+readline.o: $(hdrdir)/ruby/internal/intern/vm.h
+readline.o: $(hdrdir)/ruby/internal/interpreter.h
+readline.o: $(hdrdir)/ruby/internal/iterator.h
+readline.o: $(hdrdir)/ruby/internal/memory.h
+readline.o: $(hdrdir)/ruby/internal/method.h
+readline.o: $(hdrdir)/ruby/internal/module.h
+readline.o: $(hdrdir)/ruby/internal/newobj.h
+readline.o: $(hdrdir)/ruby/internal/rgengc.h
+readline.o: $(hdrdir)/ruby/internal/scan_args.h
+readline.o: $(hdrdir)/ruby/internal/special_consts.h
+readline.o: $(hdrdir)/ruby/internal/static_assert.h
+readline.o: $(hdrdir)/ruby/internal/stdalign.h
+readline.o: $(hdrdir)/ruby/internal/stdbool.h
+readline.o: $(hdrdir)/ruby/internal/symbol.h
+readline.o: $(hdrdir)/ruby/internal/token_paste.h
+readline.o: $(hdrdir)/ruby/internal/value.h
+readline.o: $(hdrdir)/ruby/internal/value_type.h
+readline.o: $(hdrdir)/ruby/internal/variable.h
+readline.o: $(hdrdir)/ruby/internal/warning_push.h
+readline.o: $(hdrdir)/ruby/internal/xmalloc.h
readline.o: $(hdrdir)/ruby/io.h
readline.o: $(hdrdir)/ruby/missing.h
readline.o: $(hdrdir)/ruby/onigmo.h
@@ -13,6 +163,5 @@ readline.o: $(hdrdir)/ruby/ruby.h
readline.o: $(hdrdir)/ruby/st.h
readline.o: $(hdrdir)/ruby/subst.h
readline.o: $(hdrdir)/ruby/thread.h
-readline.o: $(top_srcdir)/include/ruby.h
readline.o: readline.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/readline/depend-gem b/ext/readline/depend-gem
new file mode 100644
index 0000000000..df01bd2a86
--- /dev/null
+++ b/ext/readline/depend-gem
@@ -0,0 +1,4 @@
+# AUTOGENERATED DEPENDENCIES START
+readline.o: $(RUBY_EXTCONF_H)
+readline.o: readline.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb
index 7bba386540..d3e7872e65 100644
--- a/ext/readline/extconf.rb
+++ b/ext/readline/extconf.rb
@@ -71,6 +71,7 @@ readline.have_func("rl_completion_matches")
readline.have_func("rl_refresh_line")
readline.have_var("rl_deprep_term_function")
readline.have_var("rl_completion_append_character")
+readline.have_var("rl_completion_quote_character")
readline.have_var("rl_basic_word_break_characters")
readline.have_var("rl_completer_word_break_characters")
readline.have_var("rl_basic_quote_characters")
@@ -83,9 +84,9 @@ readline.have_var("rl_line_buffer")
readline.have_var("rl_point")
readline.have_var("rl_char_is_quoted_p")
# workaround for native windows.
-/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && readline.have_var("rl_event_hook")
-/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_sigwinch")
-/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_signals")
+/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_event_hook")
+/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_sigwinch")
+/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_signals")
readline.have_var("rl_pre_input_hook")
readline.have_var("rl_special_prefixes")
readline.have_func("rl_cleanup_after_signal")
@@ -108,5 +109,4 @@ unless readline.have_type("rl_hook_func_t*")
$defs << "-Drl_hook_func_t=Function"
end
-$INCFLAGS << " -I$(top_srcdir)"
create_makefile("readline")
diff --git a/ext/readline/readline-ext.gemspec b/ext/readline/readline-ext.gemspec
new file mode 100644
index 0000000000..55dd591e1a
--- /dev/null
+++ b/ext/readline/readline-ext.gemspec
@@ -0,0 +1,26 @@
+Gem::Specification.new do |spec|
+ spec.name = "readline-ext"
+ spec.version = "0.1.1"
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Provides an interface for GNU Readline and Edit Line (libedit).}
+ spec.description = %q{Provides an interface for GNU Readline and Edit Line (libedit).}
+ spec.homepage = "https://github.com/ruby/readline-ext"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.extensions = %w[ext/readline/extconf.rb]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_development_dependency "bundler"
+ spec.add_development_dependency "rake"
+ spec.add_development_dependency "rake-compiler"
+end
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 5b52422563..9f76f90e41 100644
--- a/ext/readline/readline.c
+++ b/ext/readline/readline.c
@@ -77,6 +77,8 @@ static ID id_special_prefixes;
#endif
#ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
# define rl_username_completion_function username_completion_function
+#else
+RUBY_EXTERN char *rl_username_completion_function(const char *, int);
#endif
#ifndef HAVE_RL_COMPLETION_MATCHES
# define rl_completion_matches completion_matches
@@ -93,7 +95,6 @@ static char **readline_attempted_completion_function(const char *text,
#define OutputStringValue(str) do {\
StringValueCStr(str);\
- rb_check_safe_obj(str);\
(str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
} while (0)\
@@ -688,6 +689,7 @@ readline_s_insert_text(VALUE self, VALUE str)
#endif
#if defined(HAVE_RL_DELETE_TEXT)
+RUBY_EXTERN int rl_delete_text(int, int);
static const char *
str_subpos(const char *ptr, const char *end, long beg, long *sublen, rb_encoding *enc)
{
@@ -820,7 +822,7 @@ readline_s_redisplay(VALUE self)
*
* When working with auto-complete there are some strategies that work well.
* To get some ideas you can take a look at the
- * completion.rb[http://svn.ruby-lang.org/repos/ruby/trunk/lib/irb/completion.rb]
+ * completion.rb[https://git.ruby-lang.org/ruby.git/tree/lib/irb/completion.rb]
* file for irb.
*
* The common strategy is to take a list of possible completions and filter it
@@ -1146,6 +1148,7 @@ readline_s_get_screen_size(VALUE self)
#endif
#ifdef HAVE_RL_VI_EDITING_MODE
+RUBY_EXTERN int rl_vi_editing_mode(int, int);
/*
* call-seq:
* Readline.vi_editing_mode -> nil
@@ -1184,6 +1187,7 @@ readline_s_vi_editing_mode_p(VALUE self)
#endif
#ifdef HAVE_RL_EMACS_EDITING_MODE
+RUBY_EXTERN int rl_emacs_editing_mode(int, int);
/*
* call-seq:
* Readline.emacs_editing_mode -> nil
@@ -1303,6 +1307,35 @@ readline_s_get_completion_append_character(VALUE self)
#define readline_s_get_completion_append_character rb_f_notimplement
#endif
+#ifdef HAVE_RL_COMPLETION_QUOTE_CHARACTER
+/*
+ * call-seq:
+ * Readline.completion_quote_character -> char
+ *
+ * When called during a completion (e.g. from within your completion_proc),
+ * it will return a string containing the character used to quote the
+ * argument being completed, or nil if the argument is unquoted.
+ *
+ * When called at other times, it will always return nil.
+ *
+ * Note that Readline.completer_quote_characters must be set,
+ * or this method will always return nil.
+ */
+static VALUE
+readline_s_get_completion_quote_character(VALUE self)
+{
+ char buf[1];
+
+ if (rl_completion_quote_character == '\0')
+ return Qnil;
+
+ buf[0] = (char) rl_completion_quote_character;
+ return rb_locale_str_new(buf, 1);
+}
+#else
+#define readline_s_get_completion_quote_character rb_f_notimplement
+#endif
+
#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
/*
* call-seq:
@@ -1348,7 +1381,7 @@ readline_s_set_basic_word_break_characters(VALUE self, VALUE str)
* Raises NotImplementedError if the using readline library does not support.
*/
static VALUE
-readline_s_get_basic_word_break_characters(VALUE self, VALUE str)
+readline_s_get_basic_word_break_characters(VALUE self)
{
if (rl_basic_word_break_characters == NULL)
return Qnil;
@@ -1403,7 +1436,7 @@ readline_s_set_completer_word_break_characters(VALUE self, VALUE str)
* Raises NotImplementedError if the using readline library does not support.
*/
static VALUE
-readline_s_get_completer_word_break_characters(VALUE self, VALUE str)
+readline_s_get_completer_word_break_characters(VALUE self)
{
if (rl_completer_word_break_characters == NULL)
return Qnil;
@@ -1518,7 +1551,7 @@ readline_s_set_basic_quote_characters(VALUE self, VALUE str)
* Raises NotImplementedError if the using readline library does not support.
*/
static VALUE
-readline_s_get_basic_quote_characters(VALUE self, VALUE str)
+readline_s_get_basic_quote_characters(VALUE self)
{
if (rl_basic_quote_characters == NULL)
return Qnil;
@@ -1574,7 +1607,7 @@ readline_s_set_completer_quote_characters(VALUE self, VALUE str)
* Raises NotImplementedError if the using readline library does not support.
*/
static VALUE
-readline_s_get_completer_quote_characters(VALUE self, VALUE str)
+readline_s_get_completer_quote_characters(VALUE self)
{
if (rl_completer_quote_characters == NULL)
return Qnil;
@@ -1628,7 +1661,7 @@ readline_s_set_filename_quote_characters(VALUE self, VALUE str)
* Raises NotImplementedError if the using readline library does not support.
*/
static VALUE
-readline_s_get_filename_quote_characters(VALUE self, VALUE str)
+readline_s_get_filename_quote_characters(VALUE self)
{
if (rl_filename_quote_characters == NULL)
return Qnil;
@@ -1639,6 +1672,7 @@ readline_s_get_filename_quote_characters(VALUE self, VALUE str)
#endif
#ifdef HAVE_RL_REFRESH_LINE
+RUBY_EXTERN int rl_refresh_line(int, int);
/*
* call-seq:
* Readline.refresh_line -> nil
@@ -1756,7 +1790,7 @@ rb_remove_history(int index)
#else
rb_notimplement();
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
#endif
}
@@ -1884,6 +1918,10 @@ username_completion_proc_call(VALUE self, VALUE str)
return result;
}
+#ifdef HAVE_RL_CLEAR_SIGNALS
+RUBY_EXTERN int rl_clear_signals(void);
+#endif
+
#undef rb_intern
void
Init_readline(void)
@@ -1958,6 +1996,8 @@ Init_readline(void)
readline_s_set_completion_append_character, 1);
rb_define_singleton_method(mReadline, "completion_append_character",
readline_s_get_completion_append_character, 0);
+ rb_define_singleton_method(mReadline, "completion_quote_character",
+ readline_s_get_completion_quote_character, 0);
rb_define_singleton_method(mReadline, "basic_word_break_characters=",
readline_s_set_basic_word_break_characters, 1);
rb_define_singleton_method(mReadline, "basic_word_break_characters",
@@ -1996,8 +2036,8 @@ Init_readline(void)
readline_s_get_special_prefixes, 0);
#if USE_INSERT_IGNORE_ESCAPE
- CONST_ID(id_orig_prompt, "orig_prompt");
- CONST_ID(id_last_prompt, "last_prompt");
+ id_orig_prompt = rb_intern("orig_prompt");
+ id_last_prompt = rb_intern("last_prompt");
#endif
history = rb_obj_alloc(rb_cObject);
@@ -2020,7 +2060,7 @@ Init_readline(void)
* The history buffer. It extends Enumerable module, so it behaves
* just like an array.
* For example, gets the fifth content that the user input by
- * HISTORY[4].
+ * <code>HISTORY[4]</code>.
*/
rb_define_const(mReadline, "HISTORY", history);
diff --git a/ext/ripper/depend b/ext/ripper/depend
index 5d3bce4ec3..4ce522fbc3 100644
--- a/ext/ripper/depend
+++ b/ext/ripper/depend
@@ -1,7 +1,6 @@
GEN = $(srcdir)/tools/generate.rb
SRC1 = $(top_srcdir)/parse.y
SRC2 = $(srcdir)/eventids2.c
-BISON = bison
.SUFFIXES: .y
@@ -18,10 +17,12 @@ ripper.o: ripper.c
all: check
static: check
-ripper.y: $(srcdir)/tools/preproc.rb $(top_srcdir)/parse.y
+ripper.y: $(srcdir)/tools/preproc.rb $(srcdir)/tools/dsl.rb $(top_srcdir)/parse.y {$(VPATH)}id.h
$(ECHO) extracting $@ from $(top_srcdir)/parse.y
$(Q) $(RUBY) $(top_srcdir)/tool/id2token.rb --path-separator=.$(PATH_SEPARATOR)./ \
--vpath=$(VPATH)$(PATH_SEPARATOR)$(top_srcdir) id.h $(top_srcdir)/parse.y > ripper.tmp.y
+ $(Q) $(RUBY) $(top_srcdir)/tool/pure_parser.rb ripper.tmp.y $(BISON)
+ $(Q) $(RM) ripper.tmp.y.bak
$(Q) $(RUBY) $(srcdir)/tools/preproc.rb ripper.tmp.y --output=$@
$(Q) $(RM) ripper.tmp.y
@@ -32,11 +33,11 @@ check: .eventids2-check
$(Q) $(RUBY) $(GEN) --mode=check --ids1src=$(SRC1) --ids2src=$(SRC2)
@exit > $@
-eventids1.c: $(srcdir)/tools/generate.rb $(SRC1)
+eventids1.c: $(GEN) $(srcdir)/tools/dsl.rb $(SRC1)
$(ECHO) generating $@ from $(SRC1)
$(Q) $(RUBY) $(GEN) --mode=eventids1 --ids1src=$(SRC1) --output=$@
-eventids2table.c: $(srcdir)/tools/generate.rb $(SRC2)
+eventids2table.c: $(GEN) $(srcdir)/tools/dsl.rb $(SRC2)
$(ECHO) generating $@ from $(SRC2)
$(Q) $(RUBY) $(GEN) --mode=eventids2table --ids2src=$(SRC2) --output=$@
@@ -50,23 +51,202 @@ ripper.E: ripper.c
# AUTOGENERATED DEPENDENCIES START
ripper.o: $(RUBY_EXTCONF_H)
ripper.o: $(arch_hdrdir)/ruby/config.h
+ripper.o: $(hdrdir)/ruby.h
+ripper.o: $(hdrdir)/ruby/assert.h
ripper.o: $(hdrdir)/ruby/backward.h
+ripper.o: $(hdrdir)/ruby/backward/2/assume.h
+ripper.o: $(hdrdir)/ruby/backward/2/attributes.h
+ripper.o: $(hdrdir)/ruby/backward/2/bool.h
+ripper.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ripper.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ripper.o: $(hdrdir)/ruby/backward/2/limits.h
+ripper.o: $(hdrdir)/ruby/backward/2/long_long.h
+ripper.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ripper.o: $(hdrdir)/ruby/backward/2/stdarg.h
ripper.o: $(hdrdir)/ruby/defines.h
ripper.o: $(hdrdir)/ruby/encoding.h
ripper.o: $(hdrdir)/ruby/intern.h
+ripper.o: $(hdrdir)/ruby/internal/anyargs.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ripper.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ripper.o: $(hdrdir)/ruby/internal/assume.h
+ripper.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ripper.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ripper.o: $(hdrdir)/ruby/internal/attr/cold.h
+ripper.o: $(hdrdir)/ruby/internal/attr/const.h
+ripper.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ripper.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ripper.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ripper.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ripper.o: $(hdrdir)/ruby/internal/attr/error.h
+ripper.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ripper.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ripper.o: $(hdrdir)/ruby/internal/attr/format.h
+ripper.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ripper.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ripper.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ripper.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ripper.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ripper.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ripper.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ripper.o: $(hdrdir)/ruby/internal/attr/pure.h
+ripper.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ripper.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ripper.o: $(hdrdir)/ruby/internal/attr/warning.h
+ripper.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ripper.o: $(hdrdir)/ruby/internal/cast.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_is.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ripper.o: $(hdrdir)/ruby/internal/compiler_since.h
+ripper.o: $(hdrdir)/ruby/internal/config.h
+ripper.o: $(hdrdir)/ruby/internal/constant_p.h
+ripper.o: $(hdrdir)/ruby/internal/core.h
+ripper.o: $(hdrdir)/ruby/internal/core/rarray.h
+ripper.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ripper.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ripper.o: $(hdrdir)/ruby/internal/core/rclass.h
+ripper.o: $(hdrdir)/ruby/internal/core/rdata.h
+ripper.o: $(hdrdir)/ruby/internal/core/rfile.h
+ripper.o: $(hdrdir)/ruby/internal/core/rhash.h
+ripper.o: $(hdrdir)/ruby/internal/core/robject.h
+ripper.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ripper.o: $(hdrdir)/ruby/internal/core/rstring.h
+ripper.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ripper.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ripper.o: $(hdrdir)/ruby/internal/ctype.h
+ripper.o: $(hdrdir)/ruby/internal/dllexport.h
+ripper.o: $(hdrdir)/ruby/internal/dosish.h
+ripper.o: $(hdrdir)/ruby/internal/error.h
+ripper.o: $(hdrdir)/ruby/internal/eval.h
+ripper.o: $(hdrdir)/ruby/internal/event.h
+ripper.o: $(hdrdir)/ruby/internal/fl_type.h
+ripper.o: $(hdrdir)/ruby/internal/gc.h
+ripper.o: $(hdrdir)/ruby/internal/glob.h
+ripper.o: $(hdrdir)/ruby/internal/globals.h
+ripper.o: $(hdrdir)/ruby/internal/has/attribute.h
+ripper.o: $(hdrdir)/ruby/internal/has/builtin.h
+ripper.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ripper.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ripper.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ripper.o: $(hdrdir)/ruby/internal/has/extension.h
+ripper.o: $(hdrdir)/ruby/internal/has/feature.h
+ripper.o: $(hdrdir)/ruby/internal/has/warning.h
+ripper.o: $(hdrdir)/ruby/internal/intern/array.h
+ripper.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ripper.o: $(hdrdir)/ruby/internal/intern/class.h
+ripper.o: $(hdrdir)/ruby/internal/intern/compar.h
+ripper.o: $(hdrdir)/ruby/internal/intern/complex.h
+ripper.o: $(hdrdir)/ruby/internal/intern/cont.h
+ripper.o: $(hdrdir)/ruby/internal/intern/dir.h
+ripper.o: $(hdrdir)/ruby/internal/intern/enum.h
+ripper.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ripper.o: $(hdrdir)/ruby/internal/intern/error.h
+ripper.o: $(hdrdir)/ruby/internal/intern/eval.h
+ripper.o: $(hdrdir)/ruby/internal/intern/file.h
+ripper.o: $(hdrdir)/ruby/internal/intern/gc.h
+ripper.o: $(hdrdir)/ruby/internal/intern/hash.h
+ripper.o: $(hdrdir)/ruby/internal/intern/io.h
+ripper.o: $(hdrdir)/ruby/internal/intern/load.h
+ripper.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ripper.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ripper.o: $(hdrdir)/ruby/internal/intern/object.h
+ripper.o: $(hdrdir)/ruby/internal/intern/parse.h
+ripper.o: $(hdrdir)/ruby/internal/intern/proc.h
+ripper.o: $(hdrdir)/ruby/internal/intern/process.h
+ripper.o: $(hdrdir)/ruby/internal/intern/random.h
+ripper.o: $(hdrdir)/ruby/internal/intern/range.h
+ripper.o: $(hdrdir)/ruby/internal/intern/rational.h
+ripper.o: $(hdrdir)/ruby/internal/intern/re.h
+ripper.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ripper.o: $(hdrdir)/ruby/internal/intern/select.h
+ripper.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ripper.o: $(hdrdir)/ruby/internal/intern/signal.h
+ripper.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ripper.o: $(hdrdir)/ruby/internal/intern/string.h
+ripper.o: $(hdrdir)/ruby/internal/intern/struct.h
+ripper.o: $(hdrdir)/ruby/internal/intern/thread.h
+ripper.o: $(hdrdir)/ruby/internal/intern/time.h
+ripper.o: $(hdrdir)/ruby/internal/intern/variable.h
+ripper.o: $(hdrdir)/ruby/internal/intern/vm.h
+ripper.o: $(hdrdir)/ruby/internal/interpreter.h
+ripper.o: $(hdrdir)/ruby/internal/iterator.h
+ripper.o: $(hdrdir)/ruby/internal/memory.h
+ripper.o: $(hdrdir)/ruby/internal/method.h
+ripper.o: $(hdrdir)/ruby/internal/module.h
+ripper.o: $(hdrdir)/ruby/internal/newobj.h
+ripper.o: $(hdrdir)/ruby/internal/rgengc.h
+ripper.o: $(hdrdir)/ruby/internal/scan_args.h
+ripper.o: $(hdrdir)/ruby/internal/special_consts.h
+ripper.o: $(hdrdir)/ruby/internal/static_assert.h
+ripper.o: $(hdrdir)/ruby/internal/stdalign.h
+ripper.o: $(hdrdir)/ruby/internal/stdbool.h
+ripper.o: $(hdrdir)/ruby/internal/symbol.h
+ripper.o: $(hdrdir)/ruby/internal/token_paste.h
+ripper.o: $(hdrdir)/ruby/internal/value.h
+ripper.o: $(hdrdir)/ruby/internal/value_type.h
+ripper.o: $(hdrdir)/ruby/internal/variable.h
+ripper.o: $(hdrdir)/ruby/internal/warning_push.h
+ripper.o: $(hdrdir)/ruby/internal/xmalloc.h
ripper.o: $(hdrdir)/ruby/io.h
ripper.o: $(hdrdir)/ruby/missing.h
ripper.o: $(hdrdir)/ruby/onigmo.h
ripper.o: $(hdrdir)/ruby/oniguruma.h
+ripper.o: $(hdrdir)/ruby/ractor.h
ripper.o: $(hdrdir)/ruby/regex.h
ripper.o: $(hdrdir)/ruby/ruby.h
ripper.o: $(hdrdir)/ruby/st.h
ripper.o: $(hdrdir)/ruby/subst.h
ripper.o: $(hdrdir)/ruby/util.h
-ripper.o: $(top_srcdir)/include/ruby.h
+ripper.o: $(top_srcdir)/constant.h
+ripper.o: $(top_srcdir)/id_table.h
ripper.o: $(top_srcdir)/internal.h
+ripper.o: $(top_srcdir)/internal/array.h
+ripper.o: $(top_srcdir)/internal/bignum.h
+ripper.o: $(top_srcdir)/internal/bits.h
+ripper.o: $(top_srcdir)/internal/compile.h
+ripper.o: $(top_srcdir)/internal/compilers.h
+ripper.o: $(top_srcdir)/internal/complex.h
+ripper.o: $(top_srcdir)/internal/error.h
+ripper.o: $(top_srcdir)/internal/fixnum.h
+ripper.o: $(top_srcdir)/internal/gc.h
+ripper.o: $(top_srcdir)/internal/hash.h
+ripper.o: $(top_srcdir)/internal/imemo.h
+ripper.o: $(top_srcdir)/internal/io.h
+ripper.o: $(top_srcdir)/internal/numeric.h
+ripper.o: $(top_srcdir)/internal/parse.h
+ripper.o: $(top_srcdir)/internal/rational.h
+ripper.o: $(top_srcdir)/internal/re.h
+ripper.o: $(top_srcdir)/internal/serial.h
+ripper.o: $(top_srcdir)/internal/static_assert.h
+ripper.o: $(top_srcdir)/internal/string.h
+ripper.o: $(top_srcdir)/internal/symbol.h
+ripper.o: $(top_srcdir)/internal/thread.h
+ripper.o: $(top_srcdir)/internal/util.h
+ripper.o: $(top_srcdir)/internal/variable.h
+ripper.o: $(top_srcdir)/internal/vm.h
+ripper.o: $(top_srcdir)/internal/warnings.h
ripper.o: $(top_srcdir)/node.h
ripper.o: $(top_srcdir)/regenc.h
+ripper.o: $(top_srcdir)/ruby_assert.h
ripper.o: $(top_srcdir)/symbol.h
ripper.o: ../../probes.h
ripper.o: eventids2.c
diff --git a/ext/ripper/eventids2.c b/ext/ripper/eventids2.c
index 04a40e0da7..ac38663f2d 100644
--- a/ext/ripper/eventids2.c
+++ b/ext/ripper/eventids2.c
@@ -1,12 +1,21 @@
-#define tIGNORED_NL (tLAST_TOKEN + 1)
-#define tCOMMENT (tLAST_TOKEN + 2)
-#define tEMBDOC_BEG (tLAST_TOKEN + 3)
-#define tEMBDOC (tLAST_TOKEN + 4)
-#define tEMBDOC_END (tLAST_TOKEN + 5)
-#define tSP (tLAST_TOKEN + 6)
-#define tHEREDOC_BEG (tLAST_TOKEN + 7)
-#define tHEREDOC_END (tLAST_TOKEN + 8)
-#define k__END__ (tLAST_TOKEN + 9)
+enum {
+ tIGNORED_NL = tLAST_TOKEN + 1,
+# define tIGNORED_NL ((enum yytokentype)tIGNORED_NL)
+ tCOMMENT,
+# define tCOMMENT ((enum yytokentype)tCOMMENT)
+ tEMBDOC_BEG,
+# define tEMBDOC_BEG ((enum yytokentype)tEMBDOC_BEG)
+ tEMBDOC,
+# define tEMBDOC ((enum yytokentype)tEMBDOC)
+ tEMBDOC_END,
+# define tEMBDOC_END ((enum yytokentype)tEMBDOC_END)
+ tHEREDOC_BEG,
+# define tHEREDOC_BEG ((enum yytokentype)tHEREDOC_BEG)
+ tHEREDOC_END,
+# define tHEREDOC_END ((enum yytokentype)tHEREDOC_END)
+ k__END__,
+# define k__END__ ((enum yytokentype)k__END__)
+};
typedef struct {
ID ripper_id_backref;
@@ -127,180 +136,178 @@ ripper_init_eventids2(void)
STATIC_ASSERT(k__END___range, k__END__ < SHRT_MAX);
STATIC_ASSERT(ripper_scanner_ids_size, sizeof(ripper_scanner_ids) < SHRT_MAX);
-#define O(member) (int)offsetof(ripper_scanner_ids_t, ripper_id_##member)
-
-static const struct token_assoc {
- unsigned short token;
- unsigned short id_offset;
-} token_to_eventid[] = {
- {' ', O(words_sep)},
- {'!', O(op)},
- {'%', O(op)},
- {'&', O(op)},
- {'*', O(op)},
- {'+', O(op)},
- {'-', O(op)},
- {'/', O(op)},
- {'<', O(op)},
- {'=', O(op)},
- {'>', O(op)},
- {'?', O(op)},
- {'^', O(op)},
- {'|', O(op)},
- {'~', O(op)},
- {':', O(op)},
- {',', O(comma)},
- {'.', O(period)},
- {';', O(semicolon)},
- {'`', O(backtick)},
- {'\n', O(nl)},
- {keyword_alias, O(kw)},
- {keyword_and, O(kw)},
- {keyword_begin, O(kw)},
- {keyword_break, O(kw)},
- {keyword_case, O(kw)},
- {keyword_class, O(kw)},
- {keyword_def, O(kw)},
- {keyword_defined, O(kw)},
- {keyword_do, O(kw)},
- {keyword_do_block, O(kw)},
- {keyword_do_cond, O(kw)},
- {keyword_else, O(kw)},
- {keyword_elsif, O(kw)},
- {keyword_end, O(kw)},
- {keyword_ensure, O(kw)},
- {keyword_false, O(kw)},
- {keyword_for, O(kw)},
- {keyword_if, O(kw)},
- {modifier_if, O(kw)},
- {keyword_in, O(kw)},
- {keyword_module, O(kw)},
- {keyword_next, O(kw)},
- {keyword_nil, O(kw)},
- {keyword_not, O(kw)},
- {keyword_or, O(kw)},
- {keyword_redo, O(kw)},
- {keyword_rescue, O(kw)},
- {modifier_rescue, O(kw)},
- {keyword_retry, O(kw)},
- {keyword_return, O(kw)},
- {keyword_self, O(kw)},
- {keyword_super, O(kw)},
- {keyword_then, O(kw)},
- {keyword_true, O(kw)},
- {keyword_undef, O(kw)},
- {keyword_unless, O(kw)},
- {modifier_unless, O(kw)},
- {keyword_until, O(kw)},
- {modifier_until, O(kw)},
- {keyword_when, O(kw)},
- {keyword_while, O(kw)},
- {modifier_while, O(kw)},
- {keyword_yield, O(kw)},
- {keyword__FILE__, O(kw)},
- {keyword__LINE__, O(kw)},
- {keyword__ENCODING__, O(kw)},
- {keyword_BEGIN, O(kw)},
- {keyword_END, O(kw)},
- {keyword_do_LAMBDA, O(kw)},
- {tAMPER, O(op)},
- {tANDOP, O(op)},
- {tAREF, O(op)},
- {tASET, O(op)},
- {tASSOC, O(op)},
- {tBACK_REF, O(backref)},
- {tCHAR, O(CHAR)},
- {tCMP, O(op)},
- {tCOLON2, O(op)},
- {tCOLON3, O(op)},
- {tCONSTANT, O(const)},
- {tCVAR, O(cvar)},
- {tDOT2, O(op)},
- {tDOT3, O(op)},
- {tEQ, O(op)},
- {tEQQ, O(op)},
- {tFID, O(ident)},
- {tFLOAT, O(float)},
- {tGEQ, O(op)},
- {tGVAR, O(gvar)},
- {tIDENTIFIER, O(ident)},
- {tIMAGINARY, O(imaginary)},
- {tINTEGER, O(int)},
- {tIVAR, O(ivar)},
- {tLBRACE, O(lbrace)},
- {tLBRACE_ARG, O(lbrace)},
- {'{', O(lbrace)},
- {'}', O(rbrace)},
- {tLBRACK, O(lbracket)},
- {'[', O(lbracket)},
- {']', O(rbracket)},
- {tLEQ, O(op)},
- {tLPAREN, O(lparen)},
- {tLPAREN_ARG, O(lparen)},
- {'(', O(lparen)},
- {')', O(rparen)},
- {tLSHFT, O(op)},
- {tMATCH, O(op)},
- {tNEQ, O(op)},
- {tNMATCH, O(op)},
- {tNTH_REF, O(backref)},
- {tOP_ASGN, O(op)},
- {tOROP, O(op)},
- {tPOW, O(op)},
- {tQWORDS_BEG, O(qwords_beg)},
- {tQSYMBOLS_BEG, O(qsymbols_beg)},
- {tSYMBOLS_BEG, O(symbols_beg)},
- {tRATIONAL, O(rational)},
- {tREGEXP_BEG, O(regexp_beg)},
- {tREGEXP_END, O(regexp_end)},
- {tRPAREN, O(rparen)},
- {tRSHFT, O(op)},
- {tSTAR, O(op)},
- {tDSTAR, O(op)},
- {tANDDOT, O(op)},
- {tSTRING_BEG, O(tstring_beg)},
- {tSTRING_CONTENT, O(tstring_content)},
- {tSTRING_DBEG, O(embexpr_beg)},
- {tSTRING_DEND, O(embexpr_end)},
- {tSTRING_DVAR, O(embvar)},
- {tSTRING_END, O(tstring_end)},
- {tSYMBEG, O(symbeg)},
- {tUMINUS, O(op)},
- {tUMINUS_NUM, O(op)},
- {tUPLUS, O(op)},
- {tWORDS_BEG, O(words_beg)},
- {tXSTRING_BEG, O(backtick)},
- {tLABEL, O(label)},
- {tLABEL_END, O(label_end)},
- {tLAMBDA, O(tlambda)},
- {tLAMBEG, O(tlambeg)},
-
- /* ripper specific tokens */
- {tIGNORED_NL, O(ignored_nl)},
- {tCOMMENT, O(comment)},
- {tEMBDOC_BEG, O(embdoc_beg)},
- {tEMBDOC, O(embdoc)},
- {tEMBDOC_END, O(embdoc_end)},
- {tSP, O(sp)},
- {tHEREDOC_BEG, O(heredoc_beg)},
- {tHEREDOC_END, O(heredoc_end)},
- {k__END__, O(__end__)},
-};
static ID
-ripper_token2eventid(int tok)
+ripper_token2eventid(enum yytokentype tok)
{
- int i;
+#define O(member) (int)offsetof(ripper_scanner_ids_t, ripper_id_##member)+1
+ static const unsigned short offsets[] = {
+ [' '] = O(words_sep),
+ ['!'] = O(op),
+ ['%'] = O(op),
+ ['&'] = O(op),
+ ['*'] = O(op),
+ ['+'] = O(op),
+ ['-'] = O(op),
+ ['/'] = O(op),
+ ['<'] = O(op),
+ ['='] = O(op),
+ ['>'] = O(op),
+ ['?'] = O(op),
+ ['^'] = O(op),
+ ['|'] = O(op),
+ ['~'] = O(op),
+ [':'] = O(op),
+ [','] = O(comma),
+ ['.'] = O(period),
+ [';'] = O(semicolon),
+ ['`'] = O(backtick),
+ ['\n'] = O(nl),
+ [keyword_alias] = O(kw),
+ [keyword_and] = O(kw),
+ [keyword_begin] = O(kw),
+ [keyword_break] = O(kw),
+ [keyword_case] = O(kw),
+ [keyword_class] = O(kw),
+ [keyword_def] = O(kw),
+ [keyword_defined] = O(kw),
+ [keyword_do] = O(kw),
+ [keyword_do_block] = O(kw),
+ [keyword_do_cond] = O(kw),
+ [keyword_else] = O(kw),
+ [keyword_elsif] = O(kw),
+ [keyword_end] = O(kw),
+ [keyword_ensure] = O(kw),
+ [keyword_false] = O(kw),
+ [keyword_for] = O(kw),
+ [keyword_if] = O(kw),
+ [modifier_if] = O(kw),
+ [keyword_in] = O(kw),
+ [keyword_module] = O(kw),
+ [keyword_next] = O(kw),
+ [keyword_nil] = O(kw),
+ [keyword_not] = O(kw),
+ [keyword_or] = O(kw),
+ [keyword_redo] = O(kw),
+ [keyword_rescue] = O(kw),
+ [modifier_rescue] = O(kw),
+ [keyword_retry] = O(kw),
+ [keyword_return] = O(kw),
+ [keyword_self] = O(kw),
+ [keyword_super] = O(kw),
+ [keyword_then] = O(kw),
+ [keyword_true] = O(kw),
+ [keyword_undef] = O(kw),
+ [keyword_unless] = O(kw),
+ [modifier_unless] = O(kw),
+ [keyword_until] = O(kw),
+ [modifier_until] = O(kw),
+ [keyword_when] = O(kw),
+ [keyword_while] = O(kw),
+ [modifier_while] = O(kw),
+ [keyword_yield] = O(kw),
+ [keyword__FILE__] = O(kw),
+ [keyword__LINE__] = O(kw),
+ [keyword__ENCODING__] = O(kw),
+ [keyword_BEGIN] = O(kw),
+ [keyword_END] = O(kw),
+ [keyword_do_LAMBDA] = O(kw),
+ [tAMPER] = O(op),
+ [tANDOP] = O(op),
+ [tAREF] = O(op),
+ [tASET] = O(op),
+ [tASSOC] = O(op),
+ [tBACK_REF] = O(backref),
+ [tCHAR] = O(CHAR),
+ [tCMP] = O(op),
+ [tCOLON2] = O(op),
+ [tCOLON3] = O(op),
+ [tCONSTANT] = O(const),
+ [tCVAR] = O(cvar),
+ [tDOT2] = O(op),
+ [tDOT3] = O(op),
+ [tBDOT2] = O(op),
+ [tBDOT3] = O(op),
+ [tEQ] = O(op),
+ [tEQQ] = O(op),
+ [tFID] = O(ident),
+ [tFLOAT] = O(float),
+ [tGEQ] = O(op),
+ [tGVAR] = O(gvar),
+ [tIDENTIFIER] = O(ident),
+ [tIMAGINARY] = O(imaginary),
+ [tINTEGER] = O(int),
+ [tIVAR] = O(ivar),
+ [tLBRACE] = O(lbrace),
+ [tLBRACE_ARG] = O(lbrace),
+ ['{'] = O(lbrace),
+ ['}'] = O(rbrace),
+ [tLBRACK] = O(lbracket),
+ ['['] = O(lbracket),
+ [']'] = O(rbracket),
+ [tLEQ] = O(op),
+ [tLPAREN] = O(lparen),
+ [tLPAREN_ARG] = O(lparen),
+ ['('] = O(lparen),
+ [')'] = O(rparen),
+ [tLSHFT] = O(op),
+ [tMATCH] = O(op),
+ [tNEQ] = O(op),
+ [tNMATCH] = O(op),
+ [tNTH_REF] = O(backref),
+ [tOP_ASGN] = O(op),
+ [tOROP] = O(op),
+ [tPOW] = O(op),
+ [tQWORDS_BEG] = O(qwords_beg),
+ [tQSYMBOLS_BEG] = O(qsymbols_beg),
+ [tSYMBOLS_BEG] = O(symbols_beg),
+ [tRATIONAL] = O(rational),
+ [tREGEXP_BEG] = O(regexp_beg),
+ [tREGEXP_END] = O(regexp_end),
+ [tRPAREN] = O(rparen),
+ [tRSHFT] = O(op),
+ [tSTAR] = O(op),
+ [tDSTAR] = O(op),
+ [tANDDOT] = O(op),
+ [tSTRING_BEG] = O(tstring_beg),
+ [tSTRING_CONTENT] = O(tstring_content),
+ [tSTRING_DBEG] = O(embexpr_beg),
+ [tSTRING_DEND] = O(embexpr_end),
+ [tSTRING_DVAR] = O(embvar),
+ [tSTRING_END] = O(tstring_end),
+ [tSYMBEG] = O(symbeg),
+ [tUMINUS] = O(op),
+ [tUMINUS_NUM] = O(op),
+ [tUPLUS] = O(op),
+ [tWORDS_BEG] = O(words_beg),
+ [tXSTRING_BEG] = O(backtick),
+ [tLABEL] = O(label),
+ [tLABEL_END] = O(label_end),
+ [tLAMBDA] = O(tlambda),
+ [tLAMBEG] = O(tlambeg),
+
+ /* ripper specific tokens */
+ [tIGNORED_NL] = O(ignored_nl),
+ [tCOMMENT] = O(comment),
+ [tEMBDOC_BEG] = O(embdoc_beg),
+ [tEMBDOC] = O(embdoc),
+ [tEMBDOC_END] = O(embdoc_end),
+ [tSP] = O(sp),
+ [tHEREDOC_BEG] = O(heredoc_beg),
+ [tHEREDOC_END] = O(heredoc_end),
+ [k__END__] = O(__end__),
+ };
+#undef O
- for (i = 0; i < numberof(token_to_eventid); i++) {
- const struct token_assoc *const a = &token_to_eventid[i];
- if (a->token == tok)
- return *(const ID *)((const char *)&ripper_scanner_ids + a->id_offset);
+ int i = (int)tok;
+ if (i >= 0 && i < numberof(offsets) && (i = offsets[i]) > 0) {
+ return *(const ID *)((const char *)&ripper_scanner_ids-1+i);
}
- if (tok < 256) {
+ /* 128..256 are used as operator tokens */
+ if (tok < 128) {
return ripper_scanner_ids.ripper_id_CHAR;
}
rb_raise(rb_eRuntimeError, "[Ripper FATAL] unknown token %d", tok);
- UNREACHABLE;
+ UNREACHABLE_RETURN(0);
}
diff --git a/ext/ripper/extconf.rb b/ext/ripper/extconf.rb
index 89b46abcfd..2dde565bd9 100644
--- a/ext/ripper/extconf.rb
+++ b/ext/ripper/extconf.rb
@@ -5,7 +5,9 @@ require 'mkmf'
require 'rbconfig'
def main
- unless find_executable('bison')
+ yacc = ENV["YACC"] || "bison"
+
+ unless find_executable(yacc)
unless File.exist?('ripper.c') or File.exist?("#{$srcdir}/ripper.c")
raise 'missing bison; abort'
end
@@ -16,7 +18,9 @@ def main
$defs << '-DRIPPER_DEBUG' if $debug
$VPATH << '$(topdir)' << '$(top_srcdir)'
$INCFLAGS << ' -I$(topdir) -I$(top_srcdir)'
- create_makefile 'ripper'
+ create_makefile 'ripper' do |conf|
+ conf << "BISON = #{yacc}"
+ end
end
main
diff --git a/ext/ripper/lib/ripper/core.rb b/ext/ripper/lib/ripper/core.rb
index cdbaf7dd34..fa075da5b9 100644
--- a/ext/ripper/lib/ripper/core.rb
+++ b/ext/ripper/lib/ripper/core.rb
@@ -30,6 +30,7 @@ class Ripper
private
+ # :stopdoc:
def _dispatch_0() nil end
def _dispatch_1(a) a end
def _dispatch_2(a, b) a end
@@ -38,6 +39,7 @@ class Ripper
def _dispatch_5(a, b, c, d, e) a end
def _dispatch_6(a, b, c, d, e, f) a end
def _dispatch_7(a, b, c, d, e, f, g) a end
+ # :startdoc:
#
# Parser Events
diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb
index bb5908025d..1df1c022c7 100644
--- a/ext/ripper/lib/ripper/lexer.rb
+++ b/ext/ripper/lib/ripper/lexer.rb
@@ -14,91 +14,146 @@ require 'ripper/core'
class Ripper
# Tokenizes the Ruby program and returns an array of strings.
+ # The +filename+ and +lineno+ arguments are mostly ignored, since the
+ # return value is just the tokenized input.
+ # By default, this method does not handle syntax errors in +src+,
+ # use the +raise_errors+ keyword to raise a SyntaxError for an error in +src+.
#
# p Ripper.tokenize("def m(a) nil end")
# # => ["def", " ", "m", "(", "a", ")", " ", "nil", " ", "end"]
#
- def Ripper.tokenize(src, filename = '-', lineno = 1)
- Lexer.new(src, filename, lineno).tokenize
+ def Ripper.tokenize(src, filename = '-', lineno = 1, **kw)
+ Lexer.new(src, filename, lineno).tokenize(**kw)
end
# Tokenizes the Ruby program and returns an array of an array,
# which is formatted like
# <code>[[lineno, column], type, token, state]</code>.
+ # The +filename+ argument is mostly ignored.
+ # By default, this method does not handle syntax errors in +src+,
+ # use the +raise_errors+ keyword to raise a SyntaxError for an error in +src+.
#
# require 'ripper'
# require 'pp'
#
# pp Ripper.lex("def m(a) nil end")
- # #=> [[[1, 0], :on_kw, "def", Ripper::EXPR_FNAME ],
- # [[1, 3], :on_sp, " ", Ripper::EXPR_FNAME ],
- # [[1, 4], :on_ident, "m", Ripper::EXPR_ENDFN ],
- # [[1, 5], :on_lparen, "(", Ripper::EXPR_LABEL | Ripper::EXPR_BEG],
- # [[1, 6], :on_ident, "a", Ripper::EXPR_ARG ],
- # [[1, 7], :on_rparen, ")", Ripper::EXPR_ENDFN ],
- # [[1, 8], :on_sp, " ", Ripper::EXPR_BEG ],
- # [[1, 9], :on_kw, "nil", Ripper::EXPR_END ],
- # [[1, 12], :on_sp, " ", Ripper::EXPR_END ],
- # [[1, 13], :on_kw, "end", Ripper::EXPR_END ]]
+ # #=> [[[1, 0], :on_kw, "def", FNAME ],
+ # [[1, 3], :on_sp, " ", FNAME ],
+ # [[1, 4], :on_ident, "m", ENDFN ],
+ # [[1, 5], :on_lparen, "(", BEG|LABEL],
+ # [[1, 6], :on_ident, "a", ARG ],
+ # [[1, 7], :on_rparen, ")", ENDFN ],
+ # [[1, 8], :on_sp, " ", BEG ],
+ # [[1, 9], :on_kw, "nil", END ],
+ # [[1, 12], :on_sp, " ", END ],
+ # [[1, 13], :on_kw, "end", END ]]
#
- def Ripper.lex(src, filename = '-', lineno = 1)
- Lexer.new(src, filename, lineno).lex
+ def Ripper.lex(src, filename = '-', lineno = 1, **kw)
+ Lexer.new(src, filename, lineno).lex(**kw)
end
class Lexer < ::Ripper #:nodoc: internal use only
- Elem = Struct.new(:pos, :event, :tok, :state)
- class Elem
- class List < ::Array
- def inspect
- super.sub!(/\d+(?=\]\z)/, Ripper.lex_state_name(self[3]))
- end
+ State = Struct.new(:to_int, :to_s) do
+ alias to_i to_int
+ def initialize(i) super(i, Ripper.lex_state_name(i)).freeze end
+ # def inspect; "#<#{self.class}: #{self}>" end
+ alias inspect to_s
+ def pretty_print(q) q.text(to_s) end
+ def ==(i) super or to_int == i end
+ def &(i) self.class.new(to_int & i) end
+ def |(i) self.class.new(to_int | i) end
+ def allbits?(i) to_int.allbits?(i) end
+ def anybits?(i) to_int.anybits?(i) end
+ def nobits?(i) to_int.nobits?(i) end
+ end
- def pretty_print(q) # :nodoc:
- pos, event, tok, state = self
- q.group(1, '[', ']') {
- q.pp pos
- q.comma_breakable
- q.pp event
- q.comma_breakable
- q.pp tok
- q.comma_breakable
- q.text(Ripper.lex_state_name(state))
- }
- end
+ Elem = Struct.new(:pos, :event, :tok, :state, :message) do
+ def initialize(pos, event, tok, state, message = nil)
+ super(pos, event, tok, State.new(state), message)
+ end
- def pretty_print_cycle(q) # :nodoc:
- q.text('[...]')
- end
+ def inspect
+ "#<#{self.class}: #{event}@#{pos[0]}:#{pos[1]}:#{state}: #{tok.inspect}#{": " if message}#{message}>"
+ end
+
+ def pretty_print(q)
+ q.group(2, "#<#{self.class}:", ">") {
+ q.breakable
+ q.text("#{event}@#{pos[0]}:#{pos[1]}")
+ q.breakable
+ q.text(state)
+ q.breakable
+ q.text("token: ")
+ tok.pretty_print(q)
+ if message
+ q.breakable
+ q.text("message: ")
+ q.text(message)
+ end
+ }
end
def to_a
- List[*values]
+ a = super
+ a.pop unless a.last
+ a
end
end
- def tokenize
- parse().sort_by(&:pos).map(&:tok)
+ attr_reader :errors
+
+ def tokenize(**kw)
+ parse(**kw).sort_by(&:pos).map(&:tok)
end
- def lex
- parse().sort_by(&:pos).map(&:to_a)
+ def lex(**kw)
+ parse(**kw).sort_by(&:pos).map(&:to_a)
end
- def parse
+ # parse the code and returns elements including errors.
+ def scan(**kw)
+ result = (parse(**kw) + errors + @stack.flatten).uniq.sort_by {|e| [*e.pos, (e.message ? -1 : 0)]}
+ result.each_with_index do |e, i|
+ if e.event == :on_parse_error and e.tok.empty? and (pre = result[i-1]) and
+ pre.pos[0] == e.pos[0] and (pre.pos[1] + pre.tok.size) == e.pos[1]
+ e.tok = pre.tok
+ e.pos[1] = pre.pos[1]
+ result[i-1] = e
+ result[i] = pre
+ end
+ end
+ result
+ end
+
+ def parse(raise_errors: false)
+ @errors = []
@buf = []
@stack = []
- super
+ super()
+ @buf = @stack.pop unless @stack.empty?
+ if raise_errors and !@errors.empty?
+ raise SyntaxError, @errors.map(&:message).join(' ;')
+ end
@buf.flatten!
- @buf
+ unless (result = @buf).empty?
+ result.concat(@buf) until (@buf = []; super(); @buf.flatten!; @buf.empty?)
+ end
+ result
end
private
+ unless SCANNER_EVENT_TABLE.key?(:ignored_sp)
+ SCANNER_EVENT_TABLE[:ignored_sp] = 1
+ SCANNER_EVENTS << :ignored_sp
+ EVENTS << :ignored_sp
+ end
+
def on_heredoc_dedent(v, w)
ignored_sp = []
heredoc = @buf.last
heredoc.each_with_index do |e, i|
- if Elem === e and e.event == :on_tstring_content
+ if Elem === e and e.event == :on_tstring_content and e.pos[1].zero?
tok = e.tok.dup if w > 0 and /\A\s/ =~ e.tok
if (n = dedent_string(e.tok, w)) > 0
if e.tok.empty?
@@ -120,7 +175,7 @@ class Ripper
def on_heredoc_beg(tok)
@stack.push @buf
buf = []
- @buf << buf
+ @buf.push buf
@buf = buf
@buf.push Elem.new([lineno(), column()], __callee__, tok, state())
end
@@ -131,8 +186,23 @@ class Ripper
end
def _push_token(tok)
- @buf.push Elem.new([lineno(), column()], __callee__, tok, state())
+ e = Elem.new([lineno(), column()], __callee__, tok, state())
+ @buf.push(e)
+ e
+ end
+
+ def on_error1(mesg)
+ @errors.push Elem.new([lineno(), column()], __callee__, token(), state(), mesg)
+ end
+
+ def on_error2(mesg, elem)
+ @errors.push Elem.new(elem.pos, __callee__, elem.tok, elem.state, mesg)
+ end
+ PARSER_EVENTS.grep(/_error\z/) do |e|
+ arity = PARSER_EVENT_TABLE.fetch(e)
+ alias_method "on_#{e}", "on_error#{arity}"
end
+ alias compile_error on_error1
(SCANNER_EVENTS.map {|event|:"on_#{event}"} - private_instance_methods(false)).each do |event|
alias_method event, :_push_token
@@ -197,7 +267,7 @@ class Ripper
if m = /[^\w\s$()\[\]{}?*+\.]/.match(pattern)
raise CompileError, "invalid char in pattern: #{m[0].inspect}"
end
- buf = ''
+ buf = +''
pattern.scan(/(?:\w+|\$\(|[()\[\]\{\}?*+\.]+)/) do |tok|
case tok
when /\w/
@@ -218,14 +288,14 @@ class Ripper
end
def map_tokens(tokens)
- tokens.map {|pos,type,str| map_token(type.to_s.sub(/\Aon_/,'')) }.join
+ tokens.map {|pos,type,str| map_token(type.to_s.delete_prefix('on_')) }.join
end
MAP = {}
seed = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
SCANNER_EVENT_TABLE.each do |ev, |
raise CompileError, "[RIPPER FATAL] too many system token" if seed.empty?
- MAP[ev.to_s.sub(/\Aon_/,'')] = seed.shift
+ MAP[ev.to_s.delete_prefix('on_')] = seed.shift
end
def map_token(tok)
diff --git a/ext/ripper/lib/ripper/sexp.rb b/ext/ripper/lib/ripper/sexp.rb
index b52dd30ddc..b1d553b1da 100644
--- a/ext/ripper/lib/ripper/sexp.rb
+++ b/ext/ripper/lib/ripper/sexp.rb
@@ -17,6 +17,10 @@ class Ripper
# Parses +src+ and create S-exp tree.
# Returns more readable tree rather than Ripper.sexp_raw.
# This method is mainly for developer use.
+ # The +filename+ argument is mostly ignored.
+ # By default, this method does not handle syntax errors in +src+,
+ # returning +nil+ in such cases. Use the +raise_errors+ keyword
+ # to raise a SyntaxError for an error in +src+.
#
# require 'ripper'
# require 'pp'
@@ -25,18 +29,28 @@ class Ripper
# #=> [:program,
# [[:def,
# [:@ident, "m", [1, 4]],
- # [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil, nil]],
+ # [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil, nil, nil, nil]],
# [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]
#
- def Ripper.sexp(src, filename = '-', lineno = 1)
+ def Ripper.sexp(src, filename = '-', lineno = 1, raise_errors: false)
builder = SexpBuilderPP.new(src, filename, lineno)
sexp = builder.parse
- sexp unless builder.error?
+ if builder.error?
+ if raise_errors
+ raise SyntaxError, builder.error
+ end
+ else
+ sexp
+ end
end
# [EXPERIMENTAL]
# Parses +src+ and create S-exp tree.
# This method is mainly for developer use.
+ # The +filename+ argument is mostly ignored.
+ # By default, this method does not handle syntax errors in +src+,
+ # returning +nil+ in such cases. Use the +raise_errors+ keyword
+ # to raise a SyntaxError for an error in +src+.
#
# require 'ripper'
# require 'pp'
@@ -54,13 +68,21 @@ class Ripper
# nil,
# nil]]]]
#
- def Ripper.sexp_raw(src, filename = '-', lineno = 1)
+ def Ripper.sexp_raw(src, filename = '-', lineno = 1, raise_errors: false)
builder = SexpBuilder.new(src, filename, lineno)
sexp = builder.parse
- sexp unless builder.error?
+ if builder.error?
+ if raise_errors
+ raise SyntaxError, builder.error
+ end
+ else
+ sexp
+ end
end
class SexpBuilder < ::Ripper #:nodoc:
+ attr_reader :error
+
private
def dedent_element(e, width)
@@ -107,6 +129,13 @@ class Ripper
end
End
end
+
+ def on_error(mesg)
+ @error = mesg
+ end
+ remove_method :on_parse_error
+ alias on_parse_error on_error
+ alias compile_error on_error
end
class SexpBuilderPP < SexpBuilder #:nodoc:
diff --git a/ext/ripper/tools/dsl.rb b/ext/ripper/tools/dsl.rb
new file mode 100644
index 0000000000..49ff51711f
--- /dev/null
+++ b/ext/ripper/tools/dsl.rb
@@ -0,0 +1,88 @@
+# Simple DSL implementation for Ripper code generation
+#
+# input: /*% ripper: stmts_add(stmts_new, void_stmt) %*/
+# output:
+# VALUE v1, v2;
+# v1 = dispatch0(stmts_new);
+# v2 = dispatch0(void_stmt);
+# $$ = dispatch2(stmts_add, v1, v2);
+
+$dollar = "$$"
+alias $$ $dollar
+
+class DSL
+ def initialize(code, options)
+ @events = {}
+ @error = options.include?("error")
+ @brace = options.include?("brace")
+ if options.include?("final")
+ @final = "p->result"
+ else
+ @final = (options.grep(/\A\$(?:\$|\d+)\z/)[0] || "$$")
+ end
+ @vars = 0
+
+ # create $1 == "$1", $2 == "$2", ...
+ s = (1..20).map {|n| "$#{n}"}
+ re = Array.new(s.size, "([^\0]+)")
+ /#{re.join("\0")}/ =~ s.join("\0")
+
+ # struct parser_params *p
+ p = p = "p"
+
+ @code = ""
+ @last_value = eval(code)
+ end
+
+ attr_reader :events
+
+ undef lambda
+ undef hash
+ undef class
+
+ def generate
+ s = "#@code#@final=#@last_value;"
+ s = "{VALUE #{ (1..@vars).map {|v| "v#{ v }" }.join(",") };#{ s }}" if @vars > 0
+ s << "ripper_error(p);" if @error
+ s = "{#{ s }}" if @brace
+ "\t\t\t#{s}"
+ end
+
+ def new_var
+ "v#{ @vars += 1 }"
+ end
+
+ def opt_event(event, default, addend)
+ add_event(event, [default, addend], true)
+ end
+
+ def add_event(event, args, qundef_check = false)
+ event = event.to_s.sub(/!\z/, "")
+ @events[event] = args.size
+ vars = []
+ args.each do |arg|
+ vars << v = new_var
+ @code << "#{ v }=#{ arg };"
+ end
+ v = new_var
+ d = "dispatch#{ args.size }(#{ [event, *vars].join(",") })"
+ d = "#{ vars.last }==Qundef ? #{ vars.first } : #{ d }" if qundef_check
+ @code << "#{ v }=#{ d };"
+ v
+ end
+
+ def method_missing(event, *args)
+ if event.to_s =~ /!\z/
+ add_event(event, args)
+ elsif args.empty? and /\Aid[A-Z_]/ =~ event.to_s
+ event
+ else
+ "#{ event }(#{ args.join(", ") })"
+ end
+ end
+
+ def self.const_missing(name)
+ name
+ end
+end
+
diff --git a/ext/ripper/tools/generate-param-macros.rb b/ext/ripper/tools/generate-param-macros.rb
index f0de55a5f2..f0de55a5f2 100755..100644
--- a/ext/ripper/tools/generate-param-macros.rb
+++ b/ext/ripper/tools/generate-param-macros.rb
diff --git a/ext/ripper/tools/generate.rb b/ext/ripper/tools/generate.rb
index cf24f1398d..883e6ef2df 100755..100644
--- a/ext/ripper/tools/generate.rb
+++ b/ext/ripper/tools/generate.rb
@@ -135,6 +135,8 @@ def check_arity(h)
abort if invalid
end
+require_relative "dsl"
+
def read_ids1_with_locations(path)
h = {}
File.open(path) {|f|
@@ -144,6 +146,13 @@ def read_ids1_with_locations(path)
line.scan(/\bdispatch(\d)\((\w+)/) do |arity, event|
(h[event] ||= []).push [f.lineno, arity.to_i]
end
+ if line =~ %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/>
+ gen = DSL.new($2, ($1 || "").split(","))
+ gen.generate
+ gen.events.each do |event, arity|
+ (h[event] ||= []).push [f.lineno, arity.to_i]
+ end
+ end
end
}
h
diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb
index 8b68579164..b838a78db7 100755..100644
--- a/ext/ripper/tools/preproc.rb
+++ b/ext/ripper/tools/preproc.rb
@@ -41,52 +41,53 @@ end
def prelude(f, out)
@exprs = {}
+ lex_state_def = false
while line = f.gets
case line
- when %r</\*%%%\*/>
- out << '/*' << $/
- when %r</\*%>
- out << '*/' << $/
- when %r<%\*/>
- out << $/
when /\A%%/
- out << '%%' << $/
+ out << "%%\n"
return
when /\A%token/
out << line.sub(/<\w+>/, '<val>')
when /\A%type/
out << line.sub(/<\w+>/, '<val>')
+ when /^enum lex_state_(?:bits|e) \{/
+ lex_state_def = true
+ out << line
+ when /^\}/
+ lex_state_def = false
+ out << line
else
- if (/^enum lex_state_(?:bits|e) \{/ =~ line)..(/^\}/ =~ line)
- case line
- when /^\s*(EXPR_\w+),\s+\/\*(.+)\*\//
- @exprs[$1.chomp("_bit")] = $2.strip
- when /^\s*(EXPR_\w+)\s+=\s+(.+)$/
- name = $1
- val = $2.chomp(",")
- @exprs[name] = "equals to " + (val.start_with?("(") ? "<tt>#{val}</tt>" : "+#{val}+")
- end
- end
out << line
end
+ if lex_state_def
+ case line
+ when /^\s*(EXPR_\w+),\s+\/\*(.+)\*\//
+ @exprs[$1.chomp("_bit")] = $2.strip
+ when /^\s*(EXPR_\w+)\s+=\s+(.+)$/
+ name = $1
+ val = $2.chomp(",")
+ @exprs[name] = "equals to " + (val.start_with?("(") ? "<tt>#{val}</tt>" : "+#{val}+")
+ end
+ end
end
end
+require_relative "dsl"
+
def grammar(f, out)
while line = f.gets
case line
+ when %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/>
+ out << DSL.new($2, ($1 || "").split(",")).generate << "\n"
when %r</\*%%%\*/>
- out << '#if 0' << $/
- when %r</\*%c%\*/>
- out << '/*' << $/
- when %r</\*%c>
- out << '*/' << $/
+ out << "#if 0\n"
when %r</\*%>
- out << '#endif' << $/
+ out << "#endif\n"
when %r<%\*/>
- out << $/
+ out << "\n"
when /\A%%/
- out << '%%' << $/
+ out << "%%\n"
return
else
out << line
diff --git a/ext/ripper/tools/strip.rb b/ext/ripper/tools/strip.rb
index 23102f797a..23102f797a 100755..100644
--- a/ext/ripper/tools/strip.rb
+++ b/ext/ripper/tools/strip.rb
diff --git a/ext/rubyvm/depend b/ext/rubyvm/depend
new file mode 100644
index 0000000000..0301ce074c
--- /dev/null
+++ b/ext/rubyvm/depend
@@ -0,0 +1,2 @@
+# AUTOGENERATED DEPENDENCIES START
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/rubyvm/lib/forwardable/impl.rb b/ext/rubyvm/lib/forwardable/impl.rb
index e9ada26e74..e9bde2f299 100644
--- a/ext/rubyvm/lib/forwardable/impl.rb
+++ b/ext/rubyvm/lib/forwardable/impl.rb
@@ -1,7 +1,5 @@
# :stopdoc:
module Forwardable
- FILTER_EXCEPTION = ""
-
def self._valid_method?(method)
iseq = RubyVM::InstructionSequence.compile("().#{method}", nil, nil, 0, false)
rescue SyntaxError
@@ -12,8 +10,7 @@ module Forwardable
def self._compile_method(src, file, line)
RubyVM::InstructionSequence.compile(src, file, file, line,
- trace_instruction: false,
- tailcall_optimization: true)
+ trace_instruction: false)
.eval
end
end
diff --git a/ext/sdbm/_sdbm.c b/ext/sdbm/_sdbm.c
deleted file mode 100644
index 3a42b0e569..0000000000
--- a/ext/sdbm/_sdbm.c
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain.
- *
- * core routines
- */
-
-#include "ruby/ruby.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "sdbm.h"
-
-/*
- * sdbm - ndbm work-alike hashed database library
- * tuning and portability constructs [not nearly enough]
- * author: oz@nexus.yorku.ca
- */
-
-#define BYTESIZ 8
-
-#ifdef BSD42
-#define SEEK_SET L_SET
-#define memset(s,c,n) bzero((s), (n)) /* only when c is zero */
-#define memcpy(s1,s2,n) bcopy((s2), (s1), (n))
-#define memcmp(s1,s2,n) bcmp((s1),(s2),(n))
-#endif
-
-/*
- * important tuning parms (hah)
- */
-
-#ifndef SEEDUPS
-#define SEEDUPS 1 /* always detect duplicates */
-#endif
-#ifndef BADMESS
-#define BADMESS 1 /* generate a message for worst case:
- cannot make room after SPLTMAX splits */
-#endif
-
-/*
- * misc
- */
-#ifdef DEBUG
-#define debug(x) printf x
-#else
-#define debug(x)
-#endif
-
-#ifdef BIG_E
-#define GET_SHORT(p, i) (((unsigned)((unsigned char *)(p))[(i)*2] << 8) + (((unsigned char *)(p))[(i)*2 + 1]))
-#define PUT_SHORT(p, i, s) (((unsigned char *)(p))[(i)*2] = (unsigned char)((s) >> 8), ((unsigned char *)(p))[(i)*2 + 1] = (unsigned char)(s))
-#else
-#define GET_SHORT(p, i) ((p)[(i)])
-#define PUT_SHORT(p, i, s) ((p)[(i)] = (s))
-#endif
-
-/*#include "pair.h"*/
-static int fitpair proto((char *, int));
-static void putpair proto((char *, datum, datum));
-static datum getpair proto((char *, datum));
-static int delpair proto((char *, datum));
-static int chkpage proto((char *));
-static datum getnkey proto((char *, int));
-static void splpage proto((char *, char *, long));
-#if SEEDUPS
-static int duppair proto((char *, datum));
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef DOSISH
-#include <io.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef BSD42
-#include <sys/file.h>
-#else
-#include <fcntl.h>
-/*#include <memory.h>*/
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#include <errno.h>
-#ifndef EPERM
-#define EPERM EACCES
-#endif
-#include <string.h>
-
-#ifdef __STDC__
-#include <stddef.h>
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/*
- * externals
- */
-#if !defined(__sun) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(errno)
-extern int errno;
-#endif
-
-/*
- * forward
- */
-static int getdbit proto((DBM *, long));
-static int setdbit proto((DBM *, long));
-static int getpage proto((DBM *, long));
-static datum getnext proto((DBM *));
-static int makroom proto((DBM *, long, int));
-
-/*
- * useful macros
- */
-#define bad(x) ((x).dptr == NULL || (x).dsize < 0)
-#define exhash(item) sdbm_hash((item).dptr, (item).dsize)
-#define ioerr(db) ((db)->flags |= DBM_IOERR)
-
-#define OFF_PAG(off) (long) (off) * PBLKSIZ
-#define OFF_DIR(off) (long) (off) * DBLKSIZ
-
-static long masks[] = {
- 000000000000L, 000000000001L, 000000000003L,
- 000000000007L, 000000000017L, 000000000037L,
- 000000000077L, 000000000177L, 000000000377L,
- 000000000777L, 000000001777L, 000000003777L,
- 000000007777L, 000000017777L, 000000037777L,
- 000000077777L, 000000177777L, 000000377777L,
- 000000777777L, 000001777777L, 000003777777L,
- 000007777777L, 000017777777L, 000037777777L,
- 000077777777L, 000177777777L, 000377777777L,
- 000777777777L, 001777777777L, 003777777777L,
- 007777777777L, 017777777777L
-};
-
-datum nullitem = {NULL, 0};
-
-DBM *
-sdbm_open(register char *file, register int flags, register int mode)
-{
- register DBM *db;
- register char *dirname;
- register char *pagname;
- register size_t n;
-
- if (file == NULL || !*file)
- return errno = EINVAL, (DBM *) NULL;
-/*
- * need space for two separate filenames
- */
- n = strlen(file) * 2 + strlen(DIRFEXT) + strlen(PAGFEXT) + 2;
-
- if ((dirname = malloc(n)) == NULL)
- return errno = ENOMEM, (DBM *) NULL;
-/*
- * build the file names
- */
- dirname = strcat(strcpy(dirname, file), DIRFEXT);
- pagname = strcpy(dirname + strlen(dirname) + 1, file);
- pagname = strcat(pagname, PAGFEXT);
-
- db = sdbm_prep(dirname, pagname, flags, mode);
- free((char *) dirname);
- return db;
-}
-
-static int
-fd_set_cloexec(int fd)
-{
- /* MinGW don't have F_GETFD and FD_CLOEXEC. [ruby-core:40281] */
-#ifdef F_GETFD
- int flags, ret;
- flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */
- if (flags == -1) {
- return -1;
- }
- if (2 < fd) {
- if (!(flags & FD_CLOEXEC)) {
- flags |= FD_CLOEXEC;
- ret = fcntl(fd, F_SETFD, flags);
- if (ret == -1) {
- return -1;
- }
- }
- }
-#endif
- return 0;
-}
-
-DBM *
-sdbm_prep(char *dirname, char *pagname, int flags, int mode)
-{
- register DBM *db;
- struct stat dstat;
-
- if ((db = (DBM *) malloc(sizeof(DBM))) == NULL)
- return errno = ENOMEM, (DBM *) NULL;
-
- db->pagf = -1;
- db->dirf = -1;
- db->flags = 0;
- db->hmask = 0;
- db->blkptr = 0;
- db->keyptr = 0;
-/*
- * adjust user flags so that WRONLY becomes RDWR,
- * as required by this package. Also set our internal
- * flag for RDONLY.
- */
- if (flags & O_WRONLY)
- flags = (flags & ~O_WRONLY) | O_RDWR;
- if (flags & O_RDONLY)
- db->flags = DBM_RDONLY;
-/*
- * open the files in sequence, and stat the dirfile.
- * If we fail anywhere, undo everything, return NULL.
- */
- flags |= O_BINARY;
-#ifdef O_CLOEXEC
- flags |= O_CLOEXEC;
-#endif
-
- if ((db->pagf = open(pagname, flags, mode)) == -1) goto err;
- if (fd_set_cloexec(db->pagf) == -1) goto err;
- if ((db->dirf = open(dirname, flags, mode)) == -1) goto err;
- if (fd_set_cloexec(db->dirf) == -1) goto err;
-/*
- * need the dirfile size to establish max bit number.
- */
- if (fstat(db->dirf, &dstat) == -1) goto err;
-/*
- * zero size: either a fresh database, or one with a single,
- * unsplit data page: dirpage is all zeros.
- */
- db->dirbno = (!dstat.st_size) ? 0 : -1;
- db->pagbno = -1;
- db->maxbno = dstat.st_size * (long) BYTESIZ;
-
- (void) memset(db->pagbuf, 0, PBLKSIZ);
- (void) memset(db->dirbuf, 0, DBLKSIZ);
-/*
- * success
- */
- return db;
-
- err:
- if (db->pagf != -1)
- (void) close(db->pagf);
- if (db->dirf != -1)
- (void) close(db->dirf);
- free((char *) db);
- return (DBM *) NULL;
-}
-
-void
-sdbm_close(register DBM *db)
-{
- if (db == NULL)
- errno = EINVAL;
- else {
- (void) close(db->dirf);
- (void) close(db->pagf);
- free((char *) db);
- }
-}
-
-datum
-sdbm_fetch(register DBM *db, datum key)
-{
- if (db == NULL || bad(key))
- return errno = EINVAL, nullitem;
-
- if (getpage(db, exhash(key)))
- return getpair(db->pagbuf, key);
-
- return ioerr(db), nullitem;
-}
-
-int
-sdbm_delete(register DBM *db, datum key)
-{
- if (db == NULL || bad(key))
- return errno = EINVAL, -1;
- if (sdbm_rdonly(db))
- return errno = EPERM, -1;
-
- if (getpage(db, exhash(key))) {
- if (!delpair(db->pagbuf, key))
- return -1;
-/*
- * update the page file
- */
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return ioerr(db), -1;
-
- return 0;
- }
-
- return ioerr(db), -1;
-}
-
-int
-sdbm_store(register DBM *db, datum key, datum val, int flags)
-{
- int need;
- register long hash;
-
- if (db == NULL || bad(key))
- return errno = EINVAL, -1;
- if (sdbm_rdonly(db))
- return errno = EPERM, -1;
-
- need = key.dsize + val.dsize;
-/*
- * is the pair too big (or too small) for this database ??
- */
- if (need < 0 || need > PAIRMAX)
- return errno = EINVAL, -1;
-
- if (getpage(db, (hash = exhash(key)))) {
-/*
- * if we need to replace, delete the key/data pair
- * first. If it is not there, ignore.
- */
- if (flags == DBM_REPLACE)
- (void) delpair(db->pagbuf, key);
-#if SEEDUPS
- else if (duppair(db->pagbuf, key))
- return 1;
-#endif
-/*
- * if we do not have enough room, we have to split.
- */
- if (!fitpair(db->pagbuf, need))
- if (!makroom(db, hash, need))
- return ioerr(db), -1;
-/*
- * we have enough room or split is successful. insert the key,
- * and update the page file.
- */
- (void) putpair(db->pagbuf, key, val);
-
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return ioerr(db), -1;
- /*
- * success
- */
- return 0;
- }
-
- return ioerr(db), -1;
-}
-
-/*
- * makroom - make room by splitting the overfull page
- * this routine will attempt to make room for SPLTMAX times before
- * giving up.
- */
-static int
-makroom(register DBM *db, long int hash, int need)
-{
- long newp;
- char twin[PBLKSIZ];
-#if defined _WIN32
- char zer[PBLKSIZ];
- long oldtail;
-#endif
- char *pag = db->pagbuf;
- char *new = twin;
- register int smax = SPLTMAX;
-
- do {
-/*
- * split the current page
- */
- (void) splpage(pag, new, db->hmask + 1);
-/*
- * address of the new page
- */
- newp = (hash & db->hmask) | (db->hmask + 1);
- debug(("newp: %ld\n", newp));
-/*
- * write delay, read avoidance/cache shuffle:
- * select the page for incoming pair: if key is to go to the new page,
- * write out the previous one, and copy the new one over, thus making
- * it the current page. If not, simply write the new page, and we are
- * still looking at the page of interest. current page is not updated
- * here, as sdbm_store will do so, after it inserts the incoming pair.
- */
-
-#if defined _WIN32
- /*
- * Fill hole with 0 if made it.
- * (hole is NOT read as 0)
- */
- oldtail = lseek(db->pagf, 0L, SEEK_END);
- memset(zer, 0, PBLKSIZ);
- while (OFF_PAG(newp) > oldtail) {
- if (lseek(db->pagf, 0L, SEEK_END) < 0 ||
- write(db->pagf, zer, PBLKSIZ) < 0) {
-
- return 0;
- }
- oldtail += PBLKSIZ;
- }
-#endif
-
- if (hash & (db->hmask + 1)) {
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return 0;
- db->pagbno = newp;
- (void) memcpy(pag, new, PBLKSIZ);
- }
- else if (lseek(db->pagf, OFF_PAG(newp), SEEK_SET) < 0
- || write(db->pagf, new, PBLKSIZ) < 0)
- return 0;
-
- if (!setdbit(db, db->curbit))
- return 0;
-/*
- * see if we have enough room now
- */
- if (fitpair(pag, need))
- return 1;
-/*
- * try again... update curbit and hmask as getpage would have
- * done. because of our update of the current page, we do not
- * need to read in anything. BUT we have to write the current
- * [deferred] page out, as the window of failure is too great.
- */
- db->curbit = 2 * db->curbit +
- ((hash & (db->hmask + 1)) ? 2 : 1);
- db->hmask |= (db->hmask + 1);
-
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return 0;
-
- } while (--smax);
-/*
- * if we are here, this is real bad news. After SPLTMAX splits,
- * we still cannot fit the key. say goodnight.
- */
-#if BADMESS
- (void) (write(2, "sdbm: cannot insert after SPLTMAX attempts.\n", 44) < 0);
-#endif
- return 0;
-
-}
-
-/*
- * the following two routines will break if
- * deletions aren't taken into account. (ndbm bug)
- */
-datum
-sdbm_firstkey(register DBM *db)
-{
- if (db == NULL)
- return errno = EINVAL, nullitem;
-/*
- * start at page 0
- */
- (void) memset(db->pagbuf, 0, PBLKSIZ);
- if (lseek(db->pagf, OFF_PAG(0), SEEK_SET) < 0
- || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return ioerr(db), nullitem;
- db->pagbno = 0;
- db->blkptr = 0;
- db->keyptr = 0;
-
- return getnext(db);
-}
-
-datum
-sdbm_nextkey(register DBM *db)
-{
- if (db == NULL)
- return errno = EINVAL, nullitem;
- return getnext(db);
-}
-
-/*
- * all important binary trie traversal
- */
-static int
-getpage(register DBM *db, register long int hash)
-{
- register int hbit;
- register long dbit;
- register long pagb;
-
- dbit = 0;
- hbit = 0;
- while (dbit < db->maxbno && getdbit(db, dbit))
- dbit = 2 * dbit + ((hash & ((long) 1 << hbit++)) ? 2 : 1);
-
- debug(("dbit: %ld...", dbit));
-
- db->curbit = dbit;
- db->hmask = masks[hbit];
-
- pagb = hash & db->hmask;
-/*
- * see if the block we need is already in memory.
- * note: this lookaside cache has about 10% hit rate.
- */
- if (pagb != db->pagbno) {
-/*
- * note: here, we assume a "hole" is read as 0s.
- * if not, must zero pagbuf first.
- */
- (void) memset(db->pagbuf, 0, PBLKSIZ);
-
- if (lseek(db->pagf, OFF_PAG(pagb), SEEK_SET) < 0
- || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return 0;
- if (!chkpage(db->pagbuf)) {
- return 0;
- }
- db->pagbno = pagb;
-
- debug(("pag read: %ld\n", pagb));
- }
- return 1;
-}
-
-static int
-getdbit(register DBM *db, register long int dbit)
-{
- register long c;
- register long dirb;
-
- c = dbit / BYTESIZ;
- dirb = c / DBLKSIZ;
-
- if (dirb != db->dirbno) {
- if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
- || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
- return 0;
- db->dirbno = dirb;
-
- debug(("dir read: %ld\n", dirb));
- }
-
- return db->dirbuf[c % DBLKSIZ] & (1 << (dbit % BYTESIZ));
-}
-
-static int
-setdbit(register DBM *db, register long int dbit)
-{
- register long c;
- register long dirb;
-
- c = dbit / BYTESIZ;
- dirb = c / DBLKSIZ;
-
- if (dirb != db->dirbno) {
- if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
- || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
- return 0;
- db->dirbno = dirb;
-
- debug(("dir read: %ld\n", dirb));
- }
-
- db->dirbuf[c % DBLKSIZ] |= (1 << (dbit % BYTESIZ));
-
- if (dbit >= db->maxbno)
- db->maxbno += (long) DBLKSIZ * BYTESIZ;
-
- if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
- || write(db->dirf, db->dirbuf, DBLKSIZ) < 0)
- return 0;
-
- return 1;
-}
-
-/*
- * getnext - get the next key in the page, and if done with
- * the page, try the next page in sequence
- */
-static datum
-getnext(register DBM *db)
-{
- datum key;
-
- for (;;) {
- db->keyptr++;
- key = getnkey(db->pagbuf, db->keyptr);
- if (key.dptr != NULL)
- return key;
-/*
- * we either run out, or there is nothing on this page..
- * try the next one... If we lost our position on the
- * file, we will have to seek.
- */
- db->keyptr = 0;
- if (db->pagbno != db->blkptr++)
- if (lseek(db->pagf, OFF_PAG(db->blkptr), SEEK_SET) < 0)
- break;
- db->pagbno = db->blkptr;
- if (read(db->pagf, db->pagbuf, PBLKSIZ) <= 0)
- break;
- if (!chkpage(db->pagbuf)) {
- break;
- }
- }
-
- return ioerr(db), nullitem;
-}
-
-/* pair.c */
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain.
- *
- * page-level routines
- */
-
-#ifndef BSD42
-/*#include <memory.h>*/
-#endif
-
-#define exhash(item) sdbm_hash((item).dptr, (item).dsize)
-
-/*
- * forward
- */
-static int seepair proto((char *, int, char *, int));
-
-/*
- * page format:
- * +------------------------------+
- * ino | n | keyoff | datoff | keyoff |
- * +------------+--------+--------+
- * | datoff | - - - ----> |
- * +--------+---------------------+
- * | F R E E A R E A |
- * +--------------+---------------+
- * | <---- - - - | data |
- * +--------+-----+----+----------+
- * | key | data | key |
- * +--------+----------+----------+
- *
- * calculating the offsets for free area: if the number
- * of entries (ino[0]) is zero, the offset to the END of
- * the free area is the block size. Otherwise, it is the
- * nth (ino[ino[0]]) entry's offset.
- */
-
-static int
-fitpair(char *pag, int need)
-{
- register int n;
- register int off;
- register int free;
- register short *ino = (short *) pag;
-
- off = ((n = GET_SHORT(ino,0)) > 0) ? GET_SHORT(ino,n) : PBLKSIZ;
- free = off - (n + 1) * (int)sizeof(short);
- need += 2 * (int)sizeof(short);
-
- debug(("free %d need %d\n", free, need));
-
- return need <= free;
-}
-
-static void
-putpair(char *pag, datum key, datum val)
-{
- register int n;
- register int off;
- register short *ino = (short *) pag;
-
- off = ((n = GET_SHORT(ino,0)) > 0) ? GET_SHORT(ino,n) : PBLKSIZ;
-/*
- * enter the key first
- */
- off -= key.dsize;
- if (key.dsize)
- (void) memcpy(pag + off, key.dptr, key.dsize);
- PUT_SHORT(ino,n + 1,off);
-/*
- * now the data
- */
- off -= val.dsize;
- if (val.dsize)
- (void) memcpy(pag + off, val.dptr, val.dsize);
- PUT_SHORT(ino,n + 2,off);
-/*
- * adjust item count
- */
- PUT_SHORT(ino,0,GET_SHORT(ino,0) + 2);
-}
-
-static datum
-getpair(char *pag, datum key)
-{
- register int i;
- register int n;
- datum val;
- register short *ino = (short *) pag;
-
- if ((n = GET_SHORT(ino,0)) == 0)
- return nullitem;
-
- if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
- return nullitem;
-
- val.dptr = pag + GET_SHORT(ino,i + 1);
- val.dsize = GET_SHORT(ino,i) - GET_SHORT(ino,i + 1);
- return val;
-}
-
-#if SEEDUPS
-static int
-duppair(char *pag, datum key)
-{
- register short *ino = (short *) pag;
- return GET_SHORT(ino,0) > 0 &&
- seepair(pag, GET_SHORT(ino,0), key.dptr, key.dsize) > 0;
-}
-#endif
-
-static datum
-getnkey(char *pag, int num)
-{
- datum key;
- register int off;
- register short *ino = (short *) pag;
-
- num = num * 2 - 1;
- if (GET_SHORT(ino,0) == 0 || num > GET_SHORT(ino,0))
- return nullitem;
-
- off = (num > 1) ? GET_SHORT(ino,num - 1) : PBLKSIZ;
-
- key.dptr = pag + GET_SHORT(ino,num);
- key.dsize = off - GET_SHORT(ino,num);
-
- return key;
-}
-
-static int
-delpair(char *pag, datum key)
-{
- register int n;
- register int i;
- register short *ino = (short *) pag;
-
- if ((n = GET_SHORT(ino,0)) == 0)
- return 0;
-
- if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
- return 0;
-/*
- * found the key. if it is the last entry
- * [i.e. i == n - 1] we just adjust the entry count.
- * hard case: move all data down onto the deleted pair,
- * shift offsets onto deleted offsets, and adjust them.
- * [note: 0 < i < n]
- */
- if (i < n - 1) {
- register int m;
- register char *dst = pag + (i == 1 ? PBLKSIZ : GET_SHORT(ino,i - 1));
- register char *src = pag + GET_SHORT(ino,i + 1);
- register ptrdiff_t zoo = dst - src;
-
- debug(("free-up %"PRIdPTRDIFF" ", zoo));
-/*
- * shift data/keys down
- */
- m = GET_SHORT(ino,i + 1) - GET_SHORT(ino,n);
-#ifdef DUFF
-#define MOVB *--dst = *--src
-
- if (m > 0) {
- register int loop = (m + 8 - 1) >> 3;
-
- switch (m & (8 - 1)) {
- case 0: do {
- MOVB; case 7: MOVB;
- case 6: MOVB; case 5: MOVB;
- case 4: MOVB; case 3: MOVB;
- case 2: MOVB; case 1: MOVB;
- } while (--loop);
- }
- }
-#else
-#ifdef MEMMOVE
- memmove(dst-m, src-m, m);
-#else
- while (m--)
- *--dst = *--src;
-#endif
-#endif
-/*
- * adjust offset index up
- */
- while (i < n - 1) {
- PUT_SHORT(ino,i, GET_SHORT(ino,i + 2) + zoo);
- i++;
- }
- }
- PUT_SHORT(ino, 0, GET_SHORT(ino, 0) - 2);
- return 1;
-}
-
-/*
- * search for the key in the page.
- * return offset index in the range 0 < i < n.
- * return 0 if not found.
- */
-static int
-seepair(char *pag, register int n, register char *key, register int siz)
-{
- register int i;
- register int off = PBLKSIZ;
- register short *ino = (short *) pag;
-
- for (i = 1; i < n; i += 2) {
- if (siz == off - GET_SHORT(ino,i) &&
- memcmp(key, pag + GET_SHORT(ino,i), siz) == 0)
- return i;
- off = GET_SHORT(ino,i + 1);
- }
- return 0;
-}
-
-static void
-splpage(char *pag, char *new, long int sbit)
-{
- datum key;
- datum val;
-
- register int n;
- register int off = PBLKSIZ;
- char cur[PBLKSIZ];
- register short *ino = (short *) cur;
-
- (void) memcpy(cur, pag, PBLKSIZ);
- (void) memset(pag, 0, PBLKSIZ);
- (void) memset(new, 0, PBLKSIZ);
-
- n = GET_SHORT(ino,0);
- for (ino++; n > 0; ino += 2) {
- key.dptr = cur + GET_SHORT(ino,0);
- key.dsize = off - GET_SHORT(ino,0);
- val.dptr = cur + GET_SHORT(ino,1);
- val.dsize = GET_SHORT(ino,0) - GET_SHORT(ino,1);
-/*
- * select the page pointer (by looking at sbit) and insert
- */
- (void) putpair((exhash(key) & sbit) ? new : pag, key, val);
-
- off = GET_SHORT(ino,1);
- n -= 2;
- }
-
- debug(("%d split %d/%d\n", ((short *) cur)[0] / 2,
- ((short *) new)[0] / 2,
- ((short *) pag)[0] / 2));
-}
-
-/*
- * check page sanity:
- * number of entries should be something
- * reasonable, and all offsets in the index should be in order.
- * this could be made more rigorous.
- */
-static int
-chkpage(char *pag)
-{
- register int n;
- register int off;
- register short *ino = (short *) pag;
-
- if ((n = GET_SHORT(ino,0)) < 0 || n > PBLKSIZ / (int)sizeof(short))
- return 0;
-
- if (n > 0) {
- off = PBLKSIZ;
- for (ino++; n > 0; ino += 2) {
- if (GET_SHORT(ino,0) > off || GET_SHORT(ino,1) > off ||
- GET_SHORT(ino,1) > GET_SHORT(ino,0))
- return 0;
- off = GET_SHORT(ino,1);
- n -= 2;
- }
- }
- return 1;
-}
-
-/* hash.c */
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain. keep it that way.
- *
- * hashing routine
- */
-
-/*
- * polynomial conversion ignoring overflows
- * [this seems to work remarkably well, in fact better
- * then the ndbm hash function. Replace at your own risk]
- * use: 65599 nice.
- * 65587 even better.
- */
-long
-sdbm_hash(register char *str, register int len)
-{
- register unsigned long n = 0;
-
-#ifdef DUFF
-
-#define HASHC n = *str++ + 65599 * n
-
- if (len > 0) {
- register int loop = (len + 8 - 1) >> 3;
-
- switch(len & (8 - 1)) {
- case 0: do {
- HASHC; case 7: HASHC;
- case 6: HASHC; case 5: HASHC;
- case 4: HASHC; case 3: HASHC;
- case 2: HASHC; case 1: HASHC;
- } while (--loop);
- }
-
- }
-#else
- while (len--)
- n = ((*str++) & 255) + 65587L * n;
-#endif
- return n;
-}
diff --git a/ext/sdbm/depend b/ext/sdbm/depend
deleted file mode 100644
index aeb2099e18..0000000000
--- a/ext/sdbm/depend
+++ /dev/null
@@ -1,25 +0,0 @@
-# AUTOGENERATED DEPENDENCIES START
-_sdbm.o: $(RUBY_EXTCONF_H)
-_sdbm.o: $(arch_hdrdir)/ruby/config.h
-_sdbm.o: $(hdrdir)/ruby/backward.h
-_sdbm.o: $(hdrdir)/ruby/defines.h
-_sdbm.o: $(hdrdir)/ruby/intern.h
-_sdbm.o: $(hdrdir)/ruby/missing.h
-_sdbm.o: $(hdrdir)/ruby/ruby.h
-_sdbm.o: $(hdrdir)/ruby/st.h
-_sdbm.o: $(hdrdir)/ruby/subst.h
-_sdbm.o: _sdbm.c
-_sdbm.o: sdbm.h
-init.o: $(RUBY_EXTCONF_H)
-init.o: $(arch_hdrdir)/ruby/config.h
-init.o: $(hdrdir)/ruby/backward.h
-init.o: $(hdrdir)/ruby/defines.h
-init.o: $(hdrdir)/ruby/intern.h
-init.o: $(hdrdir)/ruby/missing.h
-init.o: $(hdrdir)/ruby/ruby.h
-init.o: $(hdrdir)/ruby/st.h
-init.o: $(hdrdir)/ruby/subst.h
-init.o: $(top_srcdir)/include/ruby.h
-init.o: init.c
-init.o: sdbm.h
-# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/sdbm/extconf.rb b/ext/sdbm/extconf.rb
deleted file mode 100644
index bdf3e299e6..0000000000
--- a/ext/sdbm/extconf.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: false
-require 'mkmf'
-
-$defs << "-D""BADMESS=0"
-create_makefile("sdbm")
diff --git a/ext/sdbm/init.c b/ext/sdbm/init.c
deleted file mode 100644
index 684f31b98f..0000000000
--- a/ext/sdbm/init.c
+++ /dev/null
@@ -1,1067 +0,0 @@
-/************************************************
-
- sdbminit.c -
-
- $Author$
- created at: Fri May 7 08:34:24 JST 1999
-
- Copyright (C) 1995-2001 Yukihiro Matsumoto
-
-************************************************/
-
-#include "ruby.h"
-
-#include "sdbm.h"
-#include <fcntl.h>
-#include <errno.h>
-
-/*
- * Document-class: SDBM
- *
- * SDBM provides a simple file-based key-value store, which can only store
- * String keys and values.
- *
- * Note that Ruby comes with the source code for SDBM, while the DBM and GDBM
- * standard libraries rely on external libraries and headers.
- *
- * === Examples
- *
- * Insert values:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db['apple'] = 'fruit'
- * db['pear'] = 'fruit'
- * db['carrot'] = 'vegetable'
- * db['tomato'] = 'vegetable'
- * end
- *
- * Bulk update:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.update('peach' => 'fruit', 'tomato' => 'fruit')
- * end
- *
- * Retrieve values:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.each do |key, value|
- * puts "Key: #{key}, Value: #{value}"
- * end
- * end
- *
- * Outputs:
- *
- * Key: apple, Value: fruit
- * Key: pear, Value: fruit
- * Key: carrot, Value: vegetable
- * Key: peach, Value: fruit
- * Key: tomato, Value: fruit
- */
-
-static VALUE rb_cDBM, rb_eDBMError;
-
-struct dbmdata {
- int di_size;
- DBM *di_dbm;
-};
-
-static void
-closed_sdbm(void)
-{
- rb_raise(rb_eDBMError, "closed SDBM file");
-}
-
-#define GetDBM(obj, dbmp) do {\
- TypedData_Get_Struct((obj), struct dbmdata, &sdbm_type, (dbmp));\
- if ((dbmp) == 0) closed_sdbm();\
- if ((dbmp)->di_dbm == 0) closed_sdbm();\
-} while (0)
-
-#define GetDBM2(obj, dbmp, dbm) do {\
- GetDBM((obj), (dbmp));\
- (dbm) = (dbmp)->di_dbm;\
-} while (0)
-
-static void
-free_sdbm(void *ptr)
-{
- struct dbmdata *dbmp = ptr;
-
- if (dbmp->di_dbm) sdbm_close(dbmp->di_dbm);
- ruby_xfree(dbmp);
-}
-
-static size_t
-memsize_dbm(const void *ptr)
-{
- size_t size = 0;
- const struct dbmdata *dbmp = ptr;
- if (dbmp) {
- size += sizeof(*dbmp);
- if (dbmp->di_dbm) size += sizeof(DBM);
- }
- return size;
-}
-
-static const rb_data_type_t sdbm_type = {
- "sdbm",
- {0, free_sdbm, memsize_dbm,},
- 0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY,
-};
-
-/*
- * call-seq:
- * sdbm.close -> nil
- *
- * Closes the database file.
- *
- * Raises SDBMError if the database is already closed.
- */
-static VALUE
-fsdbm_close(VALUE obj)
-{
- struct dbmdata *dbmp;
-
- GetDBM(obj, dbmp);
- sdbm_close(dbmp->di_dbm);
- dbmp->di_dbm = 0;
-
- return Qnil;
-}
-
-/*
- * call-seq:
- * sdbm.closed? -> true or false
- *
- * Returns +true+ if the database is closed.
- */
-static VALUE
-fsdbm_closed(VALUE obj)
-{
- struct dbmdata *dbmp;
-
- TypedData_Get_Struct(obj, struct dbmdata, &sdbm_type, dbmp);
- if (dbmp == 0)
- return Qtrue;
- if (dbmp->di_dbm == 0)
- return Qtrue;
-
- return Qfalse;
-}
-
-static VALUE
-fsdbm_alloc(VALUE klass)
-{
- return TypedData_Wrap_Struct(klass, &sdbm_type, 0);
-}
-/*
- * call-seq:
- * SDBM.new(filename, mode = 0666)
- *
- * Creates a new database handle by opening the given +filename+. SDBM actually
- * uses two physical files, with extensions '.dir' and '.pag'. These extensions
- * will automatically be appended to the +filename+.
- *
- * If the file does not exist, a new file will be created using the given
- * +mode+, unless +mode+ is explicitly set to nil. In the latter case, no
- * database will be created.
- *
- * If the file exists, it will be opened in read/write mode. If this fails, it
- * will be opened in read-only mode.
- */
-static VALUE
-fsdbm_initialize(int argc, VALUE *argv, VALUE obj)
-{
- VALUE file, vmode;
- DBM *dbm;
- struct dbmdata *dbmp;
- int mode;
-
- if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
- mode = 0666; /* default value */
- }
- else if (NIL_P(vmode)) {
- mode = -1; /* return nil if DB not exist */
- }
- else {
- mode = NUM2INT(vmode);
- }
- FilePathValue(file);
-
- dbm = 0;
- if (mode >= 0)
- dbm = sdbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
- if (!dbm)
- dbm = sdbm_open(RSTRING_PTR(file), O_RDWR, 0);
- if (!dbm)
- dbm = sdbm_open(RSTRING_PTR(file), O_RDONLY, 0);
-
- if (!dbm) {
- if (mode == -1) return Qnil;
- rb_sys_fail_str(file);
- }
-
- dbmp = ALLOC(struct dbmdata);
- DATA_PTR(obj) = dbmp;
- dbmp->di_dbm = dbm;
- dbmp->di_size = -1;
-
- return obj;
-}
-
-/*
- * call-seq:
- * SDBM.open(filename, mode = 0666)
- * SDBM.open(filename, mode = 0666) { |sdbm| ... }
- *
- * If called without a block, this is the same as SDBM.new.
- *
- * If a block is given, the new database will be passed to the block and
- * will be safely closed after the block has executed.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open('my_database') do |db|
- * db['hello'] = 'world'
- * end
- */
-static VALUE
-fsdbm_s_open(int argc, VALUE *argv, VALUE klass)
-{
- VALUE obj = fsdbm_alloc(klass);
-
- if (NIL_P(fsdbm_initialize(argc, argv, obj))) {
- return Qnil;
- }
-
- if (rb_block_given_p()) {
- return rb_ensure(rb_yield, obj, fsdbm_close, obj);
- }
-
- return obj;
-}
-
-static VALUE
-fsdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
-{
- datum key, value;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- GetDBM2(obj, dbmp, dbm);
- value = sdbm_fetch(dbm, key);
- if (value.dptr == 0) {
- if (ifnone == Qnil && rb_block_given_p())
- return rb_yield(rb_external_str_new(key.dptr, key.dsize));
- return ifnone;
- }
- return rb_external_str_new(value.dptr, value.dsize);
-}
-
-/*
- * call-seq:
- * sdbm[key] -> value or nil
- *
- * Returns the +value+ in the database associated with the given +key+ string.
- *
- * If no value is found, returns +nil+.
- */
-static VALUE
-fsdbm_aref(VALUE obj, VALUE keystr)
-{
- return fsdbm_fetch(obj, keystr, Qnil);
-}
-
-/*
- * call-seq:
- * sdbm.fetch(key) -> value or nil
- * sdbm.fetch(key) { |key| ... }
- *
- * Returns the +value+ in the database associated with the given +key+ string.
- *
- * If a block is provided, the block will be called when there is no
- * +value+ associated with the given +key+. The +key+ will be passed in as an
- * argument to the block.
- *
- * If no block is provided and no value is associated with the given +key+,
- * then an IndexError will be raised.
- */
-static VALUE
-fsdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
-{
- VALUE keystr, valstr, ifnone;
-
- rb_scan_args(argc, argv, "11", &keystr, &ifnone);
- valstr = fsdbm_fetch(obj, keystr, ifnone);
- if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
- rb_raise(rb_eIndexError, "key not found");
-
- return valstr;
-}
-
-/*
- * call-seq:
- * sdbm.key(value) -> key
- *
- * Returns the +key+ associated with the given +value+. If more than one
- * +key+ corresponds to the given +value+, then the first key to be found
- * will be returned. If no keys are found, +nil+ will be returned.
- */
-static VALUE
-fsdbm_key(VALUE obj, VALUE valstr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(valstr);
- val.dptr = RSTRING_PTR(valstr);
- val.dsize = RSTRING_LENINT(valstr);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- if (val.dsize == RSTRING_LEN(valstr) &&
- memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
- return rb_external_str_new(key.dptr, key.dsize);
- }
- return Qnil;
-}
-
-/*
- * :nodoc:
- */
-static VALUE
-fsdbm_index(VALUE hash, VALUE value)
-{
- rb_warn("SDBM#index is deprecated; use SDBM#key");
- return fsdbm_key(hash, value);
-}
-
-/* call-seq:
- * sdbm.select { |key, value| ... } -> Array
- *
- * Returns a new Array of key-value pairs for which the block returns +true+.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db['apple'] = 'fruit'
- * db['pear'] = 'fruit'
- * db['spinach'] = 'vegetable'
- *
- * veggies = db.select do |key, value|
- * value == 'vegetable'
- * end #=> [["apple", "fruit"], ["pear", "fruit"]]
- * end
- */
-static VALUE
-fsdbm_select(VALUE obj)
-{
- VALUE new = rb_ary_new();
- datum key, val;
- DBM *dbm;
- struct dbmdata *dbmp;
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- VALUE assoc, v;
- val = sdbm_fetch(dbm, key);
- assoc = rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
- rb_external_str_new(val.dptr, val.dsize));
- v = rb_yield(assoc);
- if (RTEST(v)) {
- rb_ary_push(new, assoc);
- }
- GetDBM2(obj, dbmp, dbm);
- }
-
- return new;
-}
-
-/* call-seq:
- * sdbm.values_at(key, ...) -> Array
- *
- * Returns an Array of values corresponding to the given keys.
- */
-static VALUE
-fsdbm_values_at(int argc, VALUE *argv, VALUE obj)
-{
- VALUE new = rb_ary_new2(argc);
- int i;
-
- for (i=0; i<argc; i++) {
- rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));
- }
-
- return new;
-}
-
-static void
-fdbm_modify(VALUE obj)
-{
- if (OBJ_FROZEN(obj)) rb_error_frozen("SDBM");
-}
-
-/*
- * call-seq:
- * sdbm.delete(key) -> value or nil
- * sdbm.delete(key) { |key, value| ... }
- *
- * Deletes the key-value pair corresponding to the given +key+. If the
- * +key+ exists, the deleted value will be returned, otherwise +nil+.
- *
- * If a block is provided, the deleted +key+ and +value+ will be passed to
- * the block as arguments. If the +key+ does not exist in the database, the
- * value will be +nil+.
- */
-static VALUE
-fsdbm_delete(VALUE obj, VALUE keystr)
-{
- datum key, value;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE valstr;
-
- fdbm_modify(obj);
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- GetDBM2(obj, dbmp, dbm);
- dbmp->di_size = -1;
-
- value = sdbm_fetch(dbm, key);
- if (value.dptr == 0) {
- if (rb_block_given_p()) return rb_yield(keystr);
- return Qnil;
- }
-
- /* need to save value before sdbm_delete() */
- valstr = rb_external_str_new(value.dptr, value.dsize);
-
- if (sdbm_delete(dbm, key)) {
- dbmp->di_size = -1;
- rb_raise(rb_eDBMError, "dbm_delete failed");
- }
- else if (dbmp->di_size >= 0) {
- dbmp->di_size--;
- }
- return valstr;
-}
-
-/*
- * call-seq:
- * sdbm.shift -> Array or nil
- *
- * Removes a key-value pair from the database and returns them as an
- * Array. If the database is empty, returns +nil+.
- */
-static VALUE
-fsdbm_shift(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE keystr, valstr;
-
- fdbm_modify(obj);
- GetDBM2(obj, dbmp, dbm);
- key = sdbm_firstkey(dbm);
- if (!key.dptr) return Qnil;
- val = sdbm_fetch(dbm, key);
- keystr = rb_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- sdbm_delete(dbm, key);
- if (dbmp->di_size >= 0) {
- dbmp->di_size--;
- }
-
- return rb_assoc_new(keystr, valstr);
-}
-
-/*
- * call-seq:
- * sdbm.delete_if { |key, value| ... } -> self
- * sdbm.reject! { |key, value| ... } -> self
- *
- * Iterates over the key-value pairs in the database, deleting those for
- * which the block returns +true+.
- */
-static VALUE
-fsdbm_delete_if(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE keystr, valstr;
- VALUE ret, ary = rb_ary_new();
- long i;
- int status = 0, n;
-
- fdbm_modify(obj);
- GetDBM2(obj, dbmp, dbm);
- n = dbmp->di_size;
- dbmp->di_size = -1;
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- keystr = rb_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
- if (status != 0) break;
- if (RTEST(ret)) rb_ary_push(ary, keystr);
- GetDBM2(obj, dbmp, dbm);
- }
-
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- keystr = RARRAY_AREF(ary, i);
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
- if (sdbm_delete(dbm, key)) {
- rb_raise(rb_eDBMError, "sdbm_delete failed");
- }
- }
- if (status) rb_jump_tag(status);
- if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);
-
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.clear -> self
- *
- * Deletes all data from the database.
- */
-static VALUE
-fsdbm_clear(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- fdbm_modify(obj);
- GetDBM2(obj, dbmp, dbm);
- dbmp->di_size = -1;
- while (key = sdbm_firstkey(dbm), key.dptr) {
- if (sdbm_delete(dbm, key)) {
- rb_raise(rb_eDBMError, "sdbm_delete failed");
- }
- }
- dbmp->di_size = 0;
-
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.invert -> Hash
- *
- * Returns a Hash in which the key-value pairs have been inverted.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.update('apple' => 'fruit', 'spinach' => 'vegetable')
- *
- * db.invert #=> {"fruit" => "apple", "vegetable" => "spinach"}
- * end
- */
-static VALUE
-fsdbm_invert(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE keystr, valstr;
- VALUE hash = rb_hash_new();
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- keystr = rb_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- rb_hash_aset(hash, valstr, keystr);
- }
- return hash;
-}
-
-/*
- * call-seq:
- * sdbm[key] = value -> value
- * sdbm.store(key, value) -> value
- *
- * Stores a new +value+ in the database with the given +key+ as an index.
- *
- * If the +key+ already exists, this will update the +value+ associated with
- * the +key+.
- *
- * Returns the given +value+.
- */
-static VALUE
-fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- if (valstr == Qnil) {
- fsdbm_delete(obj, keystr);
- return Qnil;
- }
-
- fdbm_modify(obj);
- ExportStringValue(keystr);
- ExportStringValue(valstr);
-
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- val.dptr = RSTRING_PTR(valstr);
- val.dsize = RSTRING_LENINT(valstr);
-
- GetDBM2(obj, dbmp, dbm);
- dbmp->di_size = -1;
- if (sdbm_store(dbm, key, val, DBM_REPLACE)) {
-#ifdef HAVE_DBM_CLAERERR
- sdbm_clearerr(dbm);
-#endif
- if (errno == EPERM) rb_sys_fail(0);
- rb_raise(rb_eDBMError, "sdbm_store failed");
- }
-
- return valstr;
-}
-
-static VALUE
-update_i(RB_BLOCK_CALL_FUNC_ARGLIST(pair, dbm))
-{
- const VALUE *ptr;
- Check_Type(pair, T_ARRAY);
- if (RARRAY_LEN(pair) < 2) {
- rb_raise(rb_eArgError, "pair must be [key, value]");
- }
- ptr = RARRAY_CONST_PTR(pair);
- fsdbm_store(dbm, ptr[0], ptr[1]);
- return Qnil;
-}
-
-/*
- * call-seq:
- * sdbm.update(pairs) -> self
- *
- * Insert or update key-value pairs.
- *
- * This method will work with any object which implements an each_pair
- * method, such as a Hash.
- */
-static VALUE
-fsdbm_update(VALUE obj, VALUE other)
-{
- rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.replace(pairs) -> self
- *
- * Empties the database, then inserts the given key-value pairs.
- *
- * This method will work with any object which implements an each_pair
- * method, such as a Hash.
- */
-static VALUE
-fsdbm_replace(VALUE obj, VALUE other)
-{
- fsdbm_clear(obj);
- rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.length -> integer
- * sdbm.size -> integer
- *
- * Returns the number of keys in the database.
- */
-static VALUE
-fsdbm_length(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
- int i = 0;
-
- GetDBM2(obj, dbmp, dbm);
- if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
-
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- i++;
- }
- dbmp->di_size = i;
-
- return INT2FIX(i);
-}
-
-/*
- * call-seq:
- * sdbm.empty? -> true or false
- *
- * Returns +true+ if the database is empty.
- */
-static VALUE
-fsdbm_empty_p(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- GetDBM(obj, dbmp);
- if (dbmp->di_size < 0) {
- dbm = dbmp->di_dbm;
-
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- return Qfalse;
- }
- }
- else {
- if (dbmp->di_size)
- return Qfalse;
- }
- return Qtrue;
-}
-
-/*
- * call-seq:
- * sdbm.each_value
- * sdbm.each_value { |value| ... }
- *
- * Iterates over each +value+ in the database.
- *
- * If no block is given, returns an Enumerator.
- */
-static VALUE
-fsdbm_each_value(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- RETURN_ENUMERATOR(obj, 0, 0);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_yield(rb_external_str_new(val.dptr, val.dsize));
- GetDBM2(obj, dbmp, dbm);
- }
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.each_key
- * sdbm.each_key { |key| ... }
- *
- * Iterates over each +key+ in the database.
- *
- * If no block is given, returns an Enumerator.
- */
-static VALUE
-fsdbm_each_key(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- RETURN_ENUMERATOR(obj, 0, 0);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- rb_yield(rb_external_str_new(key.dptr, key.dsize));
- GetDBM2(obj, dbmp, dbm);
- }
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.each
- * sdbm.each { |key, value| ... }
- * sdbm.each_pair
- * sdbm.each_pair { |key, value| ... }
- *
- * Iterates over each key-value pair in the database.
- *
- * If no block is given, returns an Enumerator.
- */
-static VALUE
-fsdbm_each_pair(VALUE obj)
-{
- datum key, val;
- DBM *dbm;
- struct dbmdata *dbmp;
- VALUE keystr, valstr;
-
- RETURN_ENUMERATOR(obj, 0, 0);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- keystr = rb_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- rb_yield(rb_assoc_new(keystr, valstr));
- GetDBM2(obj, dbmp, dbm);
- }
-
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.keys -> Array
- *
- * Returns a new Array containing the keys in the database.
- */
-static VALUE
-fsdbm_keys(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE ary;
-
- GetDBM2(obj, dbmp, dbm);
- ary = rb_ary_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- rb_ary_push(ary, rb_external_str_new(key.dptr, key.dsize));
- }
-
- return ary;
-}
-
-/*
- * call-seq:
- * sdbm.values -> Array
- *
- * Returns a new Array containing the values in the database.
- */
-static VALUE
-fsdbm_values(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE ary;
-
- GetDBM2(obj, dbmp, dbm);
- ary = rb_ary_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_ary_push(ary, rb_external_str_new(val.dptr, val.dsize));
- }
-
- return ary;
-}
-
-/*
- * call-seq:
- * sdbm.include?(key) -> true or false
- * sdbm.key?(key) -> true or false
- * sdbm.member?(key) -> true or false
- * sdbm.has_key?(key) -> true or false
- *
- * Returns +true+ if the database contains the given +key+.
- */
-static VALUE
-fsdbm_has_key(VALUE obj, VALUE keystr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- GetDBM2(obj, dbmp, dbm);
- val = sdbm_fetch(dbm, key);
- if (val.dptr) return Qtrue;
- return Qfalse;
-}
-
-/*
- * call-seq:
- * sdbm.value?(key) -> true or false
- * sdbm.has_value?(key) -> true or false
- *
- * Returns +true+ if the database contains the given +value+.
- */
-static VALUE
-fsdbm_has_value(VALUE obj, VALUE valstr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(valstr);
- val.dptr = RSTRING_PTR(valstr);
- val.dsize = RSTRING_LENINT(valstr);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- if (val.dsize == RSTRING_LENINT(valstr) &&
- memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
- return Qtrue;
- }
- return Qfalse;
-}
-
-/*
- * call-seq:
- * sdbm.to_a -> Array
- *
- * Returns a new Array containing each key-value pair in the database.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.update('apple' => 'fruit', 'spinach' => 'vegetable')
- *
- * db.to_a #=> [["apple", "fruit"], ["spinach", "vegetable"]]
- * end
- */
-static VALUE
-fsdbm_to_a(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE ary;
-
- GetDBM2(obj, dbmp, dbm);
- ary = rb_ary_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_ary_push(ary, rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
- rb_external_str_new(val.dptr, val.dsize)));
- }
-
- return ary;
-}
-
-/*
- * call-seq:
- * sdbm.to_hash -> Hash
- *
- * Returns a new Hash containing each key-value pair in the database.
- */
-static VALUE
-fsdbm_to_hash(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE hash;
-
- GetDBM2(obj, dbmp, dbm);
- hash = rb_hash_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_hash_aset(hash, rb_external_str_new(key.dptr, key.dsize),
- rb_external_str_new(val.dptr, val.dsize));
- }
-
- return hash;
-}
-
-/*
- * call-seq:
- * sdbm.reject { |key, value| ... } -> Hash
- *
- * Creates a new Hash using the key-value pairs from the database, then
- * calls Hash#reject with the given block, which returns a Hash with
- * only the key-value pairs for which the block returns +false+.
- */
-static VALUE
-fsdbm_reject(VALUE obj)
-{
- return rb_hash_delete_if(fsdbm_to_hash(obj));
-}
-
-void
-Init_sdbm(void)
-{
- rb_cDBM = rb_define_class("SDBM", rb_cObject);
- rb_eDBMError = rb_define_class("SDBMError", rb_eStandardError);
- /* Document-class: SDBMError
- * Exception class used to return errors from the sdbm library.
- */
- rb_include_module(rb_cDBM, rb_mEnumerable);
-
- rb_define_alloc_func(rb_cDBM, fsdbm_alloc);
- rb_define_singleton_method(rb_cDBM, "open", fsdbm_s_open, -1);
-
- rb_define_method(rb_cDBM, "initialize", fsdbm_initialize, -1);
- rb_define_method(rb_cDBM, "close", fsdbm_close, 0);
- rb_define_method(rb_cDBM, "closed?", fsdbm_closed, 0);
- rb_define_method(rb_cDBM, "[]", fsdbm_aref, 1);
- rb_define_method(rb_cDBM, "fetch", fsdbm_fetch_m, -1);
- rb_define_method(rb_cDBM, "[]=", fsdbm_store, 2);
- rb_define_method(rb_cDBM, "store", fsdbm_store, 2);
- rb_define_method(rb_cDBM, "index", fsdbm_index, 1);
- rb_define_method(rb_cDBM, "key", fsdbm_key, 1);
- rb_define_method(rb_cDBM, "select", fsdbm_select, 0);
- rb_define_method(rb_cDBM, "values_at", fsdbm_values_at, -1);
- rb_define_method(rb_cDBM, "length", fsdbm_length, 0);
- rb_define_method(rb_cDBM, "size", fsdbm_length, 0);
- rb_define_method(rb_cDBM, "empty?", fsdbm_empty_p, 0);
- rb_define_method(rb_cDBM, "each", fsdbm_each_pair, 0);
- rb_define_method(rb_cDBM, "each_value", fsdbm_each_value, 0);
- rb_define_method(rb_cDBM, "each_key", fsdbm_each_key, 0);
- rb_define_method(rb_cDBM, "each_pair", fsdbm_each_pair, 0);
- rb_define_method(rb_cDBM, "keys", fsdbm_keys, 0);
- rb_define_method(rb_cDBM, "values", fsdbm_values, 0);
- rb_define_method(rb_cDBM, "shift", fsdbm_shift, 0);
- rb_define_method(rb_cDBM, "delete", fsdbm_delete, 1);
- rb_define_method(rb_cDBM, "delete_if", fsdbm_delete_if, 0);
- rb_define_method(rb_cDBM, "reject!", fsdbm_delete_if, 0);
- rb_define_method(rb_cDBM, "reject", fsdbm_reject, 0);
- rb_define_method(rb_cDBM, "clear", fsdbm_clear, 0);
- rb_define_method(rb_cDBM,"invert", fsdbm_invert, 0);
- rb_define_method(rb_cDBM,"update", fsdbm_update, 1);
- rb_define_method(rb_cDBM,"replace", fsdbm_replace, 1);
-
- rb_define_method(rb_cDBM, "has_key?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "include?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "key?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "member?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "has_value?", fsdbm_has_value, 1);
- rb_define_method(rb_cDBM, "value?", fsdbm_has_value, 1);
-
- rb_define_method(rb_cDBM, "to_a", fsdbm_to_a, 0);
- rb_define_method(rb_cDBM, "to_hash", fsdbm_to_hash, 0);
-}
diff --git a/ext/sdbm/sdbm.gemspec b/ext/sdbm/sdbm.gemspec
deleted file mode 100644
index 54ff21f1f6..0000000000
--- a/ext/sdbm/sdbm.gemspec
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-Gem::Specification.new do |s|
- s.name = "sdbm"
- s.version = '0.0.1'
- s.date = '2017-02-28'
- s.summary = "Provides a simple file-based key-value store with String keys and values."
- s.description = "Provides a simple file-based key-value store with String keys and values."
-
- s.require_path = %w{lib}
- s.files = %w{ext/sdbm/_sdbm.c ext/sdbm/depend ext/sdbm/extconf.rb ext/sdbm/init.c ext/sdbm/sdbm.h}
- s.extensions = ["ext/sdbm/extconf.rb"]
- s.required_ruby_version = ">= 2.5.0dev"
-
- s.authors = ["Yukihiro Matsumoto"]
- s.email = ["matz@ruby-lang.org"]
- s.homepage = "https://github.com/ruby/sdbm"
- s.license = "BSD-2-Clause"
-
- s.add_development_dependency "test-unit"
- s.add_development_dependency "rake-compiler"
-end
diff --git a/ext/sdbm/sdbm.h b/ext/sdbm/sdbm.h
deleted file mode 100644
index c3b53c4a8f..0000000000
--- a/ext/sdbm/sdbm.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain.
- */
-#ifndef _SDBM_H_
-#define _SDBM_H_
-
-#include <stdio.h>
-
-#define DBLKSIZ 4096
-#define PBLKSIZ 1024
-#define PAIRMAX 1008 /* arbitrary on PBLKSIZ-N */
-#define SPLTMAX 10 /* maximum allowed splits */
- /* for a single insertion */
-#define DIRFEXT ".dir"
-#define PAGFEXT ".pag"
-
-typedef struct {
- int dirf; /* directory file descriptor */
- int pagf; /* page file descriptor */
- int flags; /* status/error flags, see below */
- int keyptr; /* current key for nextkey */
- off_t maxbno; /* size of dirfile in bits */
- long curbit; /* current bit number */
- long hmask; /* current hash mask */
- long blkptr; /* current block for nextkey */
- long blkno; /* current page to read/write */
- long pagbno; /* current page in pagbuf */
- char pagbuf[PBLKSIZ]; /* page file block buffer */
- long dirbno; /* current block in dirbuf */
- char dirbuf[DBLKSIZ]; /* directory file block buffer */
-} DBM;
-
-#define DBM_RDONLY 0x1 /* data base open read-only */
-#define DBM_IOERR 0x2 /* data base I/O error */
-
-/*
- * utility macros
- */
-#define sdbm_rdonly(db) ((db)->flags & DBM_RDONLY)
-#define sdbm_error(db) ((db)->flags & DBM_IOERR)
-
-#define sdbm_clearerr(db) ((db)->flags &= ~DBM_IOERR) /* ouch */
-
-#define sdbm_dirfno(db) ((db)->dirf)
-#define sdbm_pagfno(db) ((db)->pagf)
-
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
-
-extern datum nullitem;
-
-#if defined(__STDC__)
-#define proto(p) p
-#else
-#define proto(p) ()
-#endif
-
-/*
- * flags to sdbm_store
- */
-#define DBM_INSERT 0
-#define DBM_REPLACE 1
-
-/*
- * ndbm interface
- */
-extern DBM *sdbm_open proto((char *, int, int));
-extern void sdbm_close proto((DBM *));
-extern datum sdbm_fetch proto((DBM *, datum));
-extern int sdbm_delete proto((DBM *, datum));
-extern int sdbm_store proto((DBM *, datum, datum, int));
-extern datum sdbm_firstkey proto((DBM *));
-extern datum sdbm_nextkey proto((DBM *));
-
-/*
- * other
- */
-extern DBM *sdbm_prep proto((char *, char *, int, int));
-extern long sdbm_hash proto((char *, int));
-
-#endif /* _SDBM_H_ */
diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c
index f5451c9569..546a971760 100644
--- a/ext/socket/ancdata.c
+++ b/ext/socket/ancdata.c
@@ -2,7 +2,6 @@
#include <time.h>
-int rsock_cmsg_cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
static VALUE sym_wait_readable, sym_wait_writable;
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
@@ -89,9 +88,9 @@ ancillary_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE vtype, VALUE
static VALUE
ancdata_new(int family, int level, int type, VALUE data)
{
- NEWOBJ_OF(obj, struct RObject, rb_cAncillaryData, T_OBJECT);
+ VALUE obj = rb_obj_alloc(rb_cAncillaryData);
StringValue(data);
- ancillary_initialize((VALUE)obj, INT2NUM(family), INT2NUM(level), INT2NUM(type), data);
+ ancillary_initialize(obj, INT2NUM(family), INT2NUM(level), INT2NUM(type), data);
return (VALUE)obj;
}
@@ -1137,6 +1136,7 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags,
rb_io_t *fptr;
struct msghdr mh;
struct iovec iov;
+ VALUE tmp;
int controls_num;
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
VALUE controls_str = 0;
@@ -1151,6 +1151,7 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags,
#endif
StringValue(data);
+ tmp = rb_str_tmp_frozen_acquire(data);
if (!RB_TYPE_P(controls, T_ARRAY)) {
controls = rb_ary_new();
@@ -1261,8 +1262,8 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags,
}
mh.msg_iovlen = 1;
mh.msg_iov = &iov;
- iov.iov_base = RSTRING_PTR(data);
- iov.iov_len = RSTRING_LEN(data);
+ iov.iov_base = RSTRING_PTR(tmp);
+ iov.iov_len = RSTRING_LEN(tmp);
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
if (controls_str) {
mh.msg_control = RSTRING_PTR(controls_str);
@@ -1295,6 +1296,7 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags,
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
RB_GC_GUARD(controls_str);
#endif
+ rb_str_tmp_frozen_release(data, tmp);
return SSIZET2NUM(ss);
}
@@ -1426,10 +1428,7 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end)
if (fstat(fd, &stbuf) == -1)
rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS");
rb_update_max_fd(fd);
- if (rsock_cmsg_cloexec_state < 0)
- rsock_cmsg_cloexec_state = rsock_detect_cloexec(fd);
- if (rsock_cmsg_cloexec_state == 0 || fd <= 2)
- rb_maygvl_fd_fix_cloexec(fd);
+ rb_maygvl_fd_fix_cloexec(fd);
if (S_ISSOCK(stbuf.st_mode))
io = rsock_init_sock(rb_obj_alloc(rb_cSocket), fd);
else
@@ -1628,10 +1627,9 @@ bsock_recvmsg_internal(VALUE sock,
}
if (NIL_P(dat_str))
- dat_str = rb_tainted_str_new(datbuf, ss);
+ dat_str = rb_str_new(datbuf, ss);
else {
rb_str_resize(dat_str, ss);
- OBJ_TAINT(dat_str);
rb_obj_reveal(dat_str, rb_cString);
}
@@ -1657,7 +1655,7 @@ bsock_recvmsg_internal(VALUE sock,
}
ctl_end = (char*)cmh + cmh->cmsg_len;
clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh);
- ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_tainted_str_new((char*)CMSG_DATA(cmh), clen));
+ ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_str_new((char*)CMSG_DATA(cmh), clen));
if (request_scm_rights)
make_io_for_unix_rights(ctl, cmh, msg_end);
else
diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c
index 2937e31960..fb5beed81a 100644
--- a/ext/socket/basicsocket.c
+++ b/ext/socket/basicsocket.c
@@ -314,6 +314,18 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
level = rsock_level_arg(family, lev);
option = rsock_optname_arg(family, level, optname);
len = 256;
+#ifdef _AIX
+ switch (option) {
+ case SO_DEBUG:
+ case SO_REUSEADDR:
+ case SO_KEEPALIVE:
+ case SO_DONTROUTE:
+ case SO_BROADCAST:
+ case SO_OOBINLINE:
+ /* AIX doesn't set len for boolean options */
+ len = sizeof(int);
+ }
+#endif
buf = ALLOCA_N(char,len);
rb_io_check_closed(fptr);
@@ -660,7 +672,7 @@ bsock_recv_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex)
* BasicSocket.do_not_reverse_lookup #=> false
*/
static VALUE
-bsock_do_not_rev_lookup(void)
+bsock_do_not_rev_lookup(VALUE _)
{
return rsock_do_not_reverse_lookup?Qtrue:Qfalse;
}
@@ -725,6 +737,13 @@ rsock_init_basicsocket(void)
rb_define_private_method(rb_cBasicSocket,
"__recv_nonblock", bsock_recv_nonblock, 4);
+#if MSG_DONTWAIT_RELIABLE
+ rb_define_private_method(rb_cBasicSocket,
+ "__read_nonblock", rsock_read_nonblock, 3);
+ rb_define_private_method(rb_cBasicSocket,
+ "__write_nonblock", rsock_write_nonblock, 2);
+#endif
+
/* in ancdata.c */
rb_define_private_method(rb_cBasicSocket, "__sendmsg",
rsock_bsock_sendmsg, 4);
diff --git a/ext/socket/constants.c b/ext/socket/constants.c
index 6fc862777e..1bbb53b173 100644
--- a/ext/socket/constants.c
+++ b/ext/socket/constants.c
@@ -28,7 +28,6 @@ constant_arg(VALUE arg, int (*str_to_int)(const char*, long, int*), const char *
else if (!NIL_P(tmp = rb_check_string_type(arg))) {
arg = tmp;
str:
- rb_check_safe_obj(arg);
ptr = RSTRING_PTR(arg);
if (str_to_int(ptr, RSTRING_LEN(arg), &ret) == -1)
rb_raise(rb_eSocket, "%s: %s", errmsg, ptr);
diff --git a/ext/socket/depend b/ext/socket/depend
index 41b00406a4..14cf6ab4f6 100644
--- a/ext/socket/depend
+++ b/ext/socket/depend
@@ -12,7 +12,158 @@ constdefs.c: constdefs.h
# AUTOGENERATED DEPENDENCIES START
ancdata.o: $(RUBY_EXTCONF_H)
ancdata.o: $(arch_hdrdir)/ruby/config.h
+ancdata.o: $(hdrdir)/ruby.h
+ancdata.o: $(hdrdir)/ruby/internal/anyargs.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ancdata.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ancdata.o: $(hdrdir)/ruby/internal/assume.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/cold.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/const.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/error.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/format.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/pure.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/warning.h
+ancdata.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ancdata.o: $(hdrdir)/ruby/internal/cast.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_is.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ancdata.o: $(hdrdir)/ruby/internal/compiler_since.h
+ancdata.o: $(hdrdir)/ruby/internal/config.h
+ancdata.o: $(hdrdir)/ruby/internal/constant_p.h
+ancdata.o: $(hdrdir)/ruby/internal/core.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rarray.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rclass.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rdata.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rfile.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rhash.h
+ancdata.o: $(hdrdir)/ruby/internal/core/robject.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rstring.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ancdata.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ancdata.o: $(hdrdir)/ruby/internal/ctype.h
+ancdata.o: $(hdrdir)/ruby/internal/dllexport.h
+ancdata.o: $(hdrdir)/ruby/internal/dosish.h
+ancdata.o: $(hdrdir)/ruby/internal/error.h
+ancdata.o: $(hdrdir)/ruby/internal/eval.h
+ancdata.o: $(hdrdir)/ruby/internal/event.h
+ancdata.o: $(hdrdir)/ruby/internal/fl_type.h
+ancdata.o: $(hdrdir)/ruby/internal/gc.h
+ancdata.o: $(hdrdir)/ruby/internal/glob.h
+ancdata.o: $(hdrdir)/ruby/internal/globals.h
+ancdata.o: $(hdrdir)/ruby/internal/has/attribute.h
+ancdata.o: $(hdrdir)/ruby/internal/has/builtin.h
+ancdata.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ancdata.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ancdata.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ancdata.o: $(hdrdir)/ruby/internal/has/extension.h
+ancdata.o: $(hdrdir)/ruby/internal/has/feature.h
+ancdata.o: $(hdrdir)/ruby/internal/has/warning.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/array.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/class.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/compar.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/complex.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/cont.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/dir.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/enum.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/error.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/eval.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/file.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/gc.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/hash.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/io.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/load.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/object.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/parse.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/proc.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/process.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/random.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/range.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/rational.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/re.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/select.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/signal.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/string.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/struct.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/thread.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/time.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/variable.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/vm.h
+ancdata.o: $(hdrdir)/ruby/internal/interpreter.h
+ancdata.o: $(hdrdir)/ruby/internal/iterator.h
+ancdata.o: $(hdrdir)/ruby/internal/memory.h
+ancdata.o: $(hdrdir)/ruby/internal/method.h
+ancdata.o: $(hdrdir)/ruby/internal/module.h
+ancdata.o: $(hdrdir)/ruby/internal/newobj.h
+ancdata.o: $(hdrdir)/ruby/internal/rgengc.h
+ancdata.o: $(hdrdir)/ruby/internal/scan_args.h
+ancdata.o: $(hdrdir)/ruby/internal/special_consts.h
+ancdata.o: $(hdrdir)/ruby/internal/static_assert.h
+ancdata.o: $(hdrdir)/ruby/internal/stdalign.h
+ancdata.o: $(hdrdir)/ruby/internal/stdbool.h
+ancdata.o: $(hdrdir)/ruby/internal/symbol.h
+ancdata.o: $(hdrdir)/ruby/internal/token_paste.h
+ancdata.o: $(hdrdir)/ruby/internal/value.h
+ancdata.o: $(hdrdir)/ruby/internal/value_type.h
+ancdata.o: $(hdrdir)/ruby/internal/variable.h
+ancdata.o: $(hdrdir)/ruby/internal/warning_push.h
+ancdata.o: $(hdrdir)/ruby/internal/xmalloc.h
+ancdata.o: $(hdrdir)/ruby/assert.h
ancdata.o: $(hdrdir)/ruby/backward.h
+ancdata.o: $(hdrdir)/ruby/backward/2/assume.h
+ancdata.o: $(hdrdir)/ruby/backward/2/attributes.h
+ancdata.o: $(hdrdir)/ruby/backward/2/bool.h
+ancdata.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ancdata.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ancdata.o: $(hdrdir)/ruby/backward/2/limits.h
+ancdata.o: $(hdrdir)/ruby/backward/2/long_long.h
+ancdata.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ancdata.o: $(hdrdir)/ruby/backward/2/stdarg.h
ancdata.o: $(hdrdir)/ruby/defines.h
ancdata.o: $(hdrdir)/ruby/encoding.h
ancdata.o: $(hdrdir)/ruby/intern.h
@@ -25,15 +176,176 @@ ancdata.o: $(hdrdir)/ruby/st.h
ancdata.o: $(hdrdir)/ruby/subst.h
ancdata.o: $(hdrdir)/ruby/thread.h
ancdata.o: $(hdrdir)/ruby/util.h
-ancdata.o: $(top_srcdir)/include/ruby.h
ancdata.o: $(top_srcdir)/internal.h
+ancdata.o: $(top_srcdir)/internal/array.h
+ancdata.o: $(top_srcdir)/internal/compilers.h
+ancdata.o: $(top_srcdir)/internal/error.h
+ancdata.o: $(top_srcdir)/internal/gc.h
+ancdata.o: $(top_srcdir)/internal/io.h
+ancdata.o: $(top_srcdir)/internal/serial.h
+ancdata.o: $(top_srcdir)/internal/static_assert.h
+ancdata.o: $(top_srcdir)/internal/string.h
+ancdata.o: $(top_srcdir)/internal/thread.h
+ancdata.o: $(top_srcdir)/internal/vm.h
+ancdata.o: $(top_srcdir)/internal/warnings.h
ancdata.o: ancdata.c
ancdata.o: constdefs.h
ancdata.o: rubysocket.h
ancdata.o: sockport.h
basicsocket.o: $(RUBY_EXTCONF_H)
basicsocket.o: $(arch_hdrdir)/ruby/config.h
+basicsocket.o: $(hdrdir)/ruby.h
+basicsocket.o: $(hdrdir)/ruby/internal/anyargs.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+basicsocket.o: $(hdrdir)/ruby/internal/assume.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/cold.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/const.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/error.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/format.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/warning.h
+basicsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h
+basicsocket.o: $(hdrdir)/ruby/internal/cast.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_is.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+basicsocket.o: $(hdrdir)/ruby/internal/compiler_since.h
+basicsocket.o: $(hdrdir)/ruby/internal/config.h
+basicsocket.o: $(hdrdir)/ruby/internal/constant_p.h
+basicsocket.o: $(hdrdir)/ruby/internal/core.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rarray.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rclass.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rdata.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rfile.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rhash.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/robject.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rstring.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h
+basicsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+basicsocket.o: $(hdrdir)/ruby/internal/ctype.h
+basicsocket.o: $(hdrdir)/ruby/internal/dllexport.h
+basicsocket.o: $(hdrdir)/ruby/internal/dosish.h
+basicsocket.o: $(hdrdir)/ruby/internal/error.h
+basicsocket.o: $(hdrdir)/ruby/internal/eval.h
+basicsocket.o: $(hdrdir)/ruby/internal/event.h
+basicsocket.o: $(hdrdir)/ruby/internal/fl_type.h
+basicsocket.o: $(hdrdir)/ruby/internal/gc.h
+basicsocket.o: $(hdrdir)/ruby/internal/glob.h
+basicsocket.o: $(hdrdir)/ruby/internal/globals.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/attribute.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/builtin.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/extension.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/feature.h
+basicsocket.o: $(hdrdir)/ruby/internal/has/warning.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/array.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/class.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/compar.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/complex.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/cont.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/dir.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/enum.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/error.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/io.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/load.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/object.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/parse.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/proc.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/process.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/random.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/range.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/rational.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/re.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/select.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/signal.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/string.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/struct.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/thread.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/time.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/variable.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/vm.h
+basicsocket.o: $(hdrdir)/ruby/internal/interpreter.h
+basicsocket.o: $(hdrdir)/ruby/internal/iterator.h
+basicsocket.o: $(hdrdir)/ruby/internal/memory.h
+basicsocket.o: $(hdrdir)/ruby/internal/method.h
+basicsocket.o: $(hdrdir)/ruby/internal/module.h
+basicsocket.o: $(hdrdir)/ruby/internal/newobj.h
+basicsocket.o: $(hdrdir)/ruby/internal/rgengc.h
+basicsocket.o: $(hdrdir)/ruby/internal/scan_args.h
+basicsocket.o: $(hdrdir)/ruby/internal/special_consts.h
+basicsocket.o: $(hdrdir)/ruby/internal/static_assert.h
+basicsocket.o: $(hdrdir)/ruby/internal/stdalign.h
+basicsocket.o: $(hdrdir)/ruby/internal/stdbool.h
+basicsocket.o: $(hdrdir)/ruby/internal/symbol.h
+basicsocket.o: $(hdrdir)/ruby/internal/token_paste.h
+basicsocket.o: $(hdrdir)/ruby/internal/value.h
+basicsocket.o: $(hdrdir)/ruby/internal/value_type.h
+basicsocket.o: $(hdrdir)/ruby/internal/variable.h
+basicsocket.o: $(hdrdir)/ruby/internal/warning_push.h
+basicsocket.o: $(hdrdir)/ruby/internal/xmalloc.h
+basicsocket.o: $(hdrdir)/ruby/assert.h
basicsocket.o: $(hdrdir)/ruby/backward.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/assume.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/bool.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/limits.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/long_long.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h
+basicsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h
basicsocket.o: $(hdrdir)/ruby/defines.h
basicsocket.o: $(hdrdir)/ruby/encoding.h
basicsocket.o: $(hdrdir)/ruby/intern.h
@@ -46,15 +358,176 @@ basicsocket.o: $(hdrdir)/ruby/st.h
basicsocket.o: $(hdrdir)/ruby/subst.h
basicsocket.o: $(hdrdir)/ruby/thread.h
basicsocket.o: $(hdrdir)/ruby/util.h
-basicsocket.o: $(top_srcdir)/include/ruby.h
basicsocket.o: $(top_srcdir)/internal.h
+basicsocket.o: $(top_srcdir)/internal/array.h
+basicsocket.o: $(top_srcdir)/internal/compilers.h
+basicsocket.o: $(top_srcdir)/internal/error.h
+basicsocket.o: $(top_srcdir)/internal/gc.h
+basicsocket.o: $(top_srcdir)/internal/io.h
+basicsocket.o: $(top_srcdir)/internal/serial.h
+basicsocket.o: $(top_srcdir)/internal/static_assert.h
+basicsocket.o: $(top_srcdir)/internal/string.h
+basicsocket.o: $(top_srcdir)/internal/thread.h
+basicsocket.o: $(top_srcdir)/internal/vm.h
+basicsocket.o: $(top_srcdir)/internal/warnings.h
basicsocket.o: basicsocket.c
basicsocket.o: constdefs.h
basicsocket.o: rubysocket.h
basicsocket.o: sockport.h
constants.o: $(RUBY_EXTCONF_H)
constants.o: $(arch_hdrdir)/ruby/config.h
+constants.o: $(hdrdir)/ruby.h
+constants.o: $(hdrdir)/ruby/internal/anyargs.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+constants.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+constants.o: $(hdrdir)/ruby/internal/assume.h
+constants.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+constants.o: $(hdrdir)/ruby/internal/attr/artificial.h
+constants.o: $(hdrdir)/ruby/internal/attr/cold.h
+constants.o: $(hdrdir)/ruby/internal/attr/const.h
+constants.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+constants.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+constants.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+constants.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+constants.o: $(hdrdir)/ruby/internal/attr/error.h
+constants.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+constants.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+constants.o: $(hdrdir)/ruby/internal/attr/format.h
+constants.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+constants.o: $(hdrdir)/ruby/internal/attr/noalias.h
+constants.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+constants.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+constants.o: $(hdrdir)/ruby/internal/attr/noinline.h
+constants.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+constants.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+constants.o: $(hdrdir)/ruby/internal/attr/pure.h
+constants.o: $(hdrdir)/ruby/internal/attr/restrict.h
+constants.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+constants.o: $(hdrdir)/ruby/internal/attr/warning.h
+constants.o: $(hdrdir)/ruby/internal/attr/weakref.h
+constants.o: $(hdrdir)/ruby/internal/cast.h
+constants.o: $(hdrdir)/ruby/internal/compiler_is.h
+constants.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+constants.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+constants.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+constants.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+constants.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+constants.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+constants.o: $(hdrdir)/ruby/internal/compiler_since.h
+constants.o: $(hdrdir)/ruby/internal/config.h
+constants.o: $(hdrdir)/ruby/internal/constant_p.h
+constants.o: $(hdrdir)/ruby/internal/core.h
+constants.o: $(hdrdir)/ruby/internal/core/rarray.h
+constants.o: $(hdrdir)/ruby/internal/core/rbasic.h
+constants.o: $(hdrdir)/ruby/internal/core/rbignum.h
+constants.o: $(hdrdir)/ruby/internal/core/rclass.h
+constants.o: $(hdrdir)/ruby/internal/core/rdata.h
+constants.o: $(hdrdir)/ruby/internal/core/rfile.h
+constants.o: $(hdrdir)/ruby/internal/core/rhash.h
+constants.o: $(hdrdir)/ruby/internal/core/robject.h
+constants.o: $(hdrdir)/ruby/internal/core/rregexp.h
+constants.o: $(hdrdir)/ruby/internal/core/rstring.h
+constants.o: $(hdrdir)/ruby/internal/core/rstruct.h
+constants.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+constants.o: $(hdrdir)/ruby/internal/ctype.h
+constants.o: $(hdrdir)/ruby/internal/dllexport.h
+constants.o: $(hdrdir)/ruby/internal/dosish.h
+constants.o: $(hdrdir)/ruby/internal/error.h
+constants.o: $(hdrdir)/ruby/internal/eval.h
+constants.o: $(hdrdir)/ruby/internal/event.h
+constants.o: $(hdrdir)/ruby/internal/fl_type.h
+constants.o: $(hdrdir)/ruby/internal/gc.h
+constants.o: $(hdrdir)/ruby/internal/glob.h
+constants.o: $(hdrdir)/ruby/internal/globals.h
+constants.o: $(hdrdir)/ruby/internal/has/attribute.h
+constants.o: $(hdrdir)/ruby/internal/has/builtin.h
+constants.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+constants.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+constants.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+constants.o: $(hdrdir)/ruby/internal/has/extension.h
+constants.o: $(hdrdir)/ruby/internal/has/feature.h
+constants.o: $(hdrdir)/ruby/internal/has/warning.h
+constants.o: $(hdrdir)/ruby/internal/intern/array.h
+constants.o: $(hdrdir)/ruby/internal/intern/bignum.h
+constants.o: $(hdrdir)/ruby/internal/intern/class.h
+constants.o: $(hdrdir)/ruby/internal/intern/compar.h
+constants.o: $(hdrdir)/ruby/internal/intern/complex.h
+constants.o: $(hdrdir)/ruby/internal/intern/cont.h
+constants.o: $(hdrdir)/ruby/internal/intern/dir.h
+constants.o: $(hdrdir)/ruby/internal/intern/enum.h
+constants.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+constants.o: $(hdrdir)/ruby/internal/intern/error.h
+constants.o: $(hdrdir)/ruby/internal/intern/eval.h
+constants.o: $(hdrdir)/ruby/internal/intern/file.h
+constants.o: $(hdrdir)/ruby/internal/intern/gc.h
+constants.o: $(hdrdir)/ruby/internal/intern/hash.h
+constants.o: $(hdrdir)/ruby/internal/intern/io.h
+constants.o: $(hdrdir)/ruby/internal/intern/load.h
+constants.o: $(hdrdir)/ruby/internal/intern/marshal.h
+constants.o: $(hdrdir)/ruby/internal/intern/numeric.h
+constants.o: $(hdrdir)/ruby/internal/intern/object.h
+constants.o: $(hdrdir)/ruby/internal/intern/parse.h
+constants.o: $(hdrdir)/ruby/internal/intern/proc.h
+constants.o: $(hdrdir)/ruby/internal/intern/process.h
+constants.o: $(hdrdir)/ruby/internal/intern/random.h
+constants.o: $(hdrdir)/ruby/internal/intern/range.h
+constants.o: $(hdrdir)/ruby/internal/intern/rational.h
+constants.o: $(hdrdir)/ruby/internal/intern/re.h
+constants.o: $(hdrdir)/ruby/internal/intern/ruby.h
+constants.o: $(hdrdir)/ruby/internal/intern/select.h
+constants.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+constants.o: $(hdrdir)/ruby/internal/intern/signal.h
+constants.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+constants.o: $(hdrdir)/ruby/internal/intern/string.h
+constants.o: $(hdrdir)/ruby/internal/intern/struct.h
+constants.o: $(hdrdir)/ruby/internal/intern/thread.h
+constants.o: $(hdrdir)/ruby/internal/intern/time.h
+constants.o: $(hdrdir)/ruby/internal/intern/variable.h
+constants.o: $(hdrdir)/ruby/internal/intern/vm.h
+constants.o: $(hdrdir)/ruby/internal/interpreter.h
+constants.o: $(hdrdir)/ruby/internal/iterator.h
+constants.o: $(hdrdir)/ruby/internal/memory.h
+constants.o: $(hdrdir)/ruby/internal/method.h
+constants.o: $(hdrdir)/ruby/internal/module.h
+constants.o: $(hdrdir)/ruby/internal/newobj.h
+constants.o: $(hdrdir)/ruby/internal/rgengc.h
+constants.o: $(hdrdir)/ruby/internal/scan_args.h
+constants.o: $(hdrdir)/ruby/internal/special_consts.h
+constants.o: $(hdrdir)/ruby/internal/static_assert.h
+constants.o: $(hdrdir)/ruby/internal/stdalign.h
+constants.o: $(hdrdir)/ruby/internal/stdbool.h
+constants.o: $(hdrdir)/ruby/internal/symbol.h
+constants.o: $(hdrdir)/ruby/internal/token_paste.h
+constants.o: $(hdrdir)/ruby/internal/value.h
+constants.o: $(hdrdir)/ruby/internal/value_type.h
+constants.o: $(hdrdir)/ruby/internal/variable.h
+constants.o: $(hdrdir)/ruby/internal/warning_push.h
+constants.o: $(hdrdir)/ruby/internal/xmalloc.h
+constants.o: $(hdrdir)/ruby/assert.h
constants.o: $(hdrdir)/ruby/backward.h
+constants.o: $(hdrdir)/ruby/backward/2/assume.h
+constants.o: $(hdrdir)/ruby/backward/2/attributes.h
+constants.o: $(hdrdir)/ruby/backward/2/bool.h
+constants.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+constants.o: $(hdrdir)/ruby/backward/2/inttypes.h
+constants.o: $(hdrdir)/ruby/backward/2/limits.h
+constants.o: $(hdrdir)/ruby/backward/2/long_long.h
+constants.o: $(hdrdir)/ruby/backward/2/stdalign.h
+constants.o: $(hdrdir)/ruby/backward/2/stdarg.h
constants.o: $(hdrdir)/ruby/defines.h
constants.o: $(hdrdir)/ruby/encoding.h
constants.o: $(hdrdir)/ruby/intern.h
@@ -67,8 +540,18 @@ constants.o: $(hdrdir)/ruby/st.h
constants.o: $(hdrdir)/ruby/subst.h
constants.o: $(hdrdir)/ruby/thread.h
constants.o: $(hdrdir)/ruby/util.h
-constants.o: $(top_srcdir)/include/ruby.h
constants.o: $(top_srcdir)/internal.h
+constants.o: $(top_srcdir)/internal/array.h
+constants.o: $(top_srcdir)/internal/compilers.h
+constants.o: $(top_srcdir)/internal/error.h
+constants.o: $(top_srcdir)/internal/gc.h
+constants.o: $(top_srcdir)/internal/io.h
+constants.o: $(top_srcdir)/internal/serial.h
+constants.o: $(top_srcdir)/internal/static_assert.h
+constants.o: $(top_srcdir)/internal/string.h
+constants.o: $(top_srcdir)/internal/thread.h
+constants.o: $(top_srcdir)/internal/vm.h
+constants.o: $(top_srcdir)/internal/warnings.h
constants.o: constants.c
constants.o: constdefs.c
constants.o: constdefs.h
@@ -76,7 +559,158 @@ constants.o: rubysocket.h
constants.o: sockport.h
ifaddr.o: $(RUBY_EXTCONF_H)
ifaddr.o: $(arch_hdrdir)/ruby/config.h
+ifaddr.o: $(hdrdir)/ruby.h
+ifaddr.o: $(hdrdir)/ruby/internal/anyargs.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ifaddr.o: $(hdrdir)/ruby/internal/assume.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/cold.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/const.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/error.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/format.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/pure.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/warning.h
+ifaddr.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ifaddr.o: $(hdrdir)/ruby/internal/cast.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_is.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ifaddr.o: $(hdrdir)/ruby/internal/compiler_since.h
+ifaddr.o: $(hdrdir)/ruby/internal/config.h
+ifaddr.o: $(hdrdir)/ruby/internal/constant_p.h
+ifaddr.o: $(hdrdir)/ruby/internal/core.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rarray.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rclass.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rdata.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rfile.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rhash.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/robject.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rstring.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ifaddr.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ifaddr.o: $(hdrdir)/ruby/internal/ctype.h
+ifaddr.o: $(hdrdir)/ruby/internal/dllexport.h
+ifaddr.o: $(hdrdir)/ruby/internal/dosish.h
+ifaddr.o: $(hdrdir)/ruby/internal/error.h
+ifaddr.o: $(hdrdir)/ruby/internal/eval.h
+ifaddr.o: $(hdrdir)/ruby/internal/event.h
+ifaddr.o: $(hdrdir)/ruby/internal/fl_type.h
+ifaddr.o: $(hdrdir)/ruby/internal/gc.h
+ifaddr.o: $(hdrdir)/ruby/internal/glob.h
+ifaddr.o: $(hdrdir)/ruby/internal/globals.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/attribute.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/builtin.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/extension.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/feature.h
+ifaddr.o: $(hdrdir)/ruby/internal/has/warning.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/array.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/class.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/compar.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/complex.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/cont.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/dir.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/enum.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/error.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/eval.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/file.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/gc.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/hash.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/io.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/load.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/object.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/parse.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/proc.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/process.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/random.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/range.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/rational.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/re.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/select.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/signal.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/string.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/struct.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/thread.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/time.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/variable.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/vm.h
+ifaddr.o: $(hdrdir)/ruby/internal/interpreter.h
+ifaddr.o: $(hdrdir)/ruby/internal/iterator.h
+ifaddr.o: $(hdrdir)/ruby/internal/memory.h
+ifaddr.o: $(hdrdir)/ruby/internal/method.h
+ifaddr.o: $(hdrdir)/ruby/internal/module.h
+ifaddr.o: $(hdrdir)/ruby/internal/newobj.h
+ifaddr.o: $(hdrdir)/ruby/internal/rgengc.h
+ifaddr.o: $(hdrdir)/ruby/internal/scan_args.h
+ifaddr.o: $(hdrdir)/ruby/internal/special_consts.h
+ifaddr.o: $(hdrdir)/ruby/internal/static_assert.h
+ifaddr.o: $(hdrdir)/ruby/internal/stdalign.h
+ifaddr.o: $(hdrdir)/ruby/internal/stdbool.h
+ifaddr.o: $(hdrdir)/ruby/internal/symbol.h
+ifaddr.o: $(hdrdir)/ruby/internal/token_paste.h
+ifaddr.o: $(hdrdir)/ruby/internal/value.h
+ifaddr.o: $(hdrdir)/ruby/internal/value_type.h
+ifaddr.o: $(hdrdir)/ruby/internal/variable.h
+ifaddr.o: $(hdrdir)/ruby/internal/warning_push.h
+ifaddr.o: $(hdrdir)/ruby/internal/xmalloc.h
+ifaddr.o: $(hdrdir)/ruby/assert.h
ifaddr.o: $(hdrdir)/ruby/backward.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/assume.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/attributes.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/bool.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/limits.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/long_long.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ifaddr.o: $(hdrdir)/ruby/backward/2/stdarg.h
ifaddr.o: $(hdrdir)/ruby/defines.h
ifaddr.o: $(hdrdir)/ruby/encoding.h
ifaddr.o: $(hdrdir)/ruby/intern.h
@@ -89,15 +723,176 @@ ifaddr.o: $(hdrdir)/ruby/st.h
ifaddr.o: $(hdrdir)/ruby/subst.h
ifaddr.o: $(hdrdir)/ruby/thread.h
ifaddr.o: $(hdrdir)/ruby/util.h
-ifaddr.o: $(top_srcdir)/include/ruby.h
ifaddr.o: $(top_srcdir)/internal.h
+ifaddr.o: $(top_srcdir)/internal/array.h
+ifaddr.o: $(top_srcdir)/internal/compilers.h
+ifaddr.o: $(top_srcdir)/internal/error.h
+ifaddr.o: $(top_srcdir)/internal/gc.h
+ifaddr.o: $(top_srcdir)/internal/io.h
+ifaddr.o: $(top_srcdir)/internal/serial.h
+ifaddr.o: $(top_srcdir)/internal/static_assert.h
+ifaddr.o: $(top_srcdir)/internal/string.h
+ifaddr.o: $(top_srcdir)/internal/thread.h
+ifaddr.o: $(top_srcdir)/internal/vm.h
+ifaddr.o: $(top_srcdir)/internal/warnings.h
ifaddr.o: constdefs.h
ifaddr.o: ifaddr.c
ifaddr.o: rubysocket.h
ifaddr.o: sockport.h
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
+init.o: $(hdrdir)/ruby.h
+init.o: $(hdrdir)/ruby/internal/anyargs.h
+init.o: $(hdrdir)/ruby/internal/arithmetic.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+init.o: $(hdrdir)/ruby/internal/assume.h
+init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+init.o: $(hdrdir)/ruby/internal/attr/artificial.h
+init.o: $(hdrdir)/ruby/internal/attr/cold.h
+init.o: $(hdrdir)/ruby/internal/attr/const.h
+init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+init.o: $(hdrdir)/ruby/internal/attr/error.h
+init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+init.o: $(hdrdir)/ruby/internal/attr/format.h
+init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+init.o: $(hdrdir)/ruby/internal/attr/noalias.h
+init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+init.o: $(hdrdir)/ruby/internal/attr/noinline.h
+init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+init.o: $(hdrdir)/ruby/internal/attr/pure.h
+init.o: $(hdrdir)/ruby/internal/attr/restrict.h
+init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+init.o: $(hdrdir)/ruby/internal/attr/warning.h
+init.o: $(hdrdir)/ruby/internal/attr/weakref.h
+init.o: $(hdrdir)/ruby/internal/cast.h
+init.o: $(hdrdir)/ruby/internal/compiler_is.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+init.o: $(hdrdir)/ruby/internal/compiler_since.h
+init.o: $(hdrdir)/ruby/internal/config.h
+init.o: $(hdrdir)/ruby/internal/constant_p.h
+init.o: $(hdrdir)/ruby/internal/core.h
+init.o: $(hdrdir)/ruby/internal/core/rarray.h
+init.o: $(hdrdir)/ruby/internal/core/rbasic.h
+init.o: $(hdrdir)/ruby/internal/core/rbignum.h
+init.o: $(hdrdir)/ruby/internal/core/rclass.h
+init.o: $(hdrdir)/ruby/internal/core/rdata.h
+init.o: $(hdrdir)/ruby/internal/core/rfile.h
+init.o: $(hdrdir)/ruby/internal/core/rhash.h
+init.o: $(hdrdir)/ruby/internal/core/robject.h
+init.o: $(hdrdir)/ruby/internal/core/rregexp.h
+init.o: $(hdrdir)/ruby/internal/core/rstring.h
+init.o: $(hdrdir)/ruby/internal/core/rstruct.h
+init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+init.o: $(hdrdir)/ruby/internal/ctype.h
+init.o: $(hdrdir)/ruby/internal/dllexport.h
+init.o: $(hdrdir)/ruby/internal/dosish.h
+init.o: $(hdrdir)/ruby/internal/error.h
+init.o: $(hdrdir)/ruby/internal/eval.h
+init.o: $(hdrdir)/ruby/internal/event.h
+init.o: $(hdrdir)/ruby/internal/fl_type.h
+init.o: $(hdrdir)/ruby/internal/gc.h
+init.o: $(hdrdir)/ruby/internal/glob.h
+init.o: $(hdrdir)/ruby/internal/globals.h
+init.o: $(hdrdir)/ruby/internal/has/attribute.h
+init.o: $(hdrdir)/ruby/internal/has/builtin.h
+init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+init.o: $(hdrdir)/ruby/internal/has/extension.h
+init.o: $(hdrdir)/ruby/internal/has/feature.h
+init.o: $(hdrdir)/ruby/internal/has/warning.h
+init.o: $(hdrdir)/ruby/internal/intern/array.h
+init.o: $(hdrdir)/ruby/internal/intern/bignum.h
+init.o: $(hdrdir)/ruby/internal/intern/class.h
+init.o: $(hdrdir)/ruby/internal/intern/compar.h
+init.o: $(hdrdir)/ruby/internal/intern/complex.h
+init.o: $(hdrdir)/ruby/internal/intern/cont.h
+init.o: $(hdrdir)/ruby/internal/intern/dir.h
+init.o: $(hdrdir)/ruby/internal/intern/enum.h
+init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+init.o: $(hdrdir)/ruby/internal/intern/error.h
+init.o: $(hdrdir)/ruby/internal/intern/eval.h
+init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
+init.o: $(hdrdir)/ruby/internal/intern/hash.h
+init.o: $(hdrdir)/ruby/internal/intern/io.h
+init.o: $(hdrdir)/ruby/internal/intern/load.h
+init.o: $(hdrdir)/ruby/internal/intern/marshal.h
+init.o: $(hdrdir)/ruby/internal/intern/numeric.h
+init.o: $(hdrdir)/ruby/internal/intern/object.h
+init.o: $(hdrdir)/ruby/internal/intern/parse.h
+init.o: $(hdrdir)/ruby/internal/intern/proc.h
+init.o: $(hdrdir)/ruby/internal/intern/process.h
+init.o: $(hdrdir)/ruby/internal/intern/random.h
+init.o: $(hdrdir)/ruby/internal/intern/range.h
+init.o: $(hdrdir)/ruby/internal/intern/rational.h
+init.o: $(hdrdir)/ruby/internal/intern/re.h
+init.o: $(hdrdir)/ruby/internal/intern/ruby.h
+init.o: $(hdrdir)/ruby/internal/intern/select.h
+init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+init.o: $(hdrdir)/ruby/internal/intern/signal.h
+init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+init.o: $(hdrdir)/ruby/internal/intern/string.h
+init.o: $(hdrdir)/ruby/internal/intern/struct.h
+init.o: $(hdrdir)/ruby/internal/intern/thread.h
+init.o: $(hdrdir)/ruby/internal/intern/time.h
+init.o: $(hdrdir)/ruby/internal/intern/variable.h
+init.o: $(hdrdir)/ruby/internal/intern/vm.h
+init.o: $(hdrdir)/ruby/internal/interpreter.h
+init.o: $(hdrdir)/ruby/internal/iterator.h
+init.o: $(hdrdir)/ruby/internal/memory.h
+init.o: $(hdrdir)/ruby/internal/method.h
+init.o: $(hdrdir)/ruby/internal/module.h
+init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
+init.o: $(hdrdir)/ruby/internal/scan_args.h
+init.o: $(hdrdir)/ruby/internal/special_consts.h
+init.o: $(hdrdir)/ruby/internal/static_assert.h
+init.o: $(hdrdir)/ruby/internal/stdalign.h
+init.o: $(hdrdir)/ruby/internal/stdbool.h
+init.o: $(hdrdir)/ruby/internal/symbol.h
+init.o: $(hdrdir)/ruby/internal/token_paste.h
+init.o: $(hdrdir)/ruby/internal/value.h
+init.o: $(hdrdir)/ruby/internal/value_type.h
+init.o: $(hdrdir)/ruby/internal/variable.h
+init.o: $(hdrdir)/ruby/internal/warning_push.h
+init.o: $(hdrdir)/ruby/internal/xmalloc.h
+init.o: $(hdrdir)/ruby/assert.h
init.o: $(hdrdir)/ruby/backward.h
+init.o: $(hdrdir)/ruby/backward/2/assume.h
+init.o: $(hdrdir)/ruby/backward/2/attributes.h
+init.o: $(hdrdir)/ruby/backward/2/bool.h
+init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+init.o: $(hdrdir)/ruby/backward/2/inttypes.h
+init.o: $(hdrdir)/ruby/backward/2/limits.h
+init.o: $(hdrdir)/ruby/backward/2/long_long.h
+init.o: $(hdrdir)/ruby/backward/2/stdalign.h
+init.o: $(hdrdir)/ruby/backward/2/stdarg.h
init.o: $(hdrdir)/ruby/defines.h
init.o: $(hdrdir)/ruby/encoding.h
init.o: $(hdrdir)/ruby/intern.h
@@ -110,15 +905,176 @@ init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
init.o: $(hdrdir)/ruby/thread.h
init.o: $(hdrdir)/ruby/util.h
-init.o: $(top_srcdir)/include/ruby.h
init.o: $(top_srcdir)/internal.h
+init.o: $(top_srcdir)/internal/array.h
+init.o: $(top_srcdir)/internal/compilers.h
+init.o: $(top_srcdir)/internal/error.h
+init.o: $(top_srcdir)/internal/gc.h
+init.o: $(top_srcdir)/internal/io.h
+init.o: $(top_srcdir)/internal/serial.h
+init.o: $(top_srcdir)/internal/static_assert.h
+init.o: $(top_srcdir)/internal/string.h
+init.o: $(top_srcdir)/internal/thread.h
+init.o: $(top_srcdir)/internal/vm.h
+init.o: $(top_srcdir)/internal/warnings.h
init.o: constdefs.h
init.o: init.c
init.o: rubysocket.h
init.o: sockport.h
ipsocket.o: $(RUBY_EXTCONF_H)
ipsocket.o: $(arch_hdrdir)/ruby/config.h
+ipsocket.o: $(hdrdir)/ruby.h
+ipsocket.o: $(hdrdir)/ruby/internal/anyargs.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+ipsocket.o: $(hdrdir)/ruby/internal/assume.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/cold.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/const.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/error.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/format.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/warning.h
+ipsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h
+ipsocket.o: $(hdrdir)/ruby/internal/cast.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_is.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+ipsocket.o: $(hdrdir)/ruby/internal/compiler_since.h
+ipsocket.o: $(hdrdir)/ruby/internal/config.h
+ipsocket.o: $(hdrdir)/ruby/internal/constant_p.h
+ipsocket.o: $(hdrdir)/ruby/internal/core.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rarray.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rclass.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rdata.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rfile.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rhash.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/robject.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rstring.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h
+ipsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+ipsocket.o: $(hdrdir)/ruby/internal/ctype.h
+ipsocket.o: $(hdrdir)/ruby/internal/dllexport.h
+ipsocket.o: $(hdrdir)/ruby/internal/dosish.h
+ipsocket.o: $(hdrdir)/ruby/internal/error.h
+ipsocket.o: $(hdrdir)/ruby/internal/eval.h
+ipsocket.o: $(hdrdir)/ruby/internal/event.h
+ipsocket.o: $(hdrdir)/ruby/internal/fl_type.h
+ipsocket.o: $(hdrdir)/ruby/internal/gc.h
+ipsocket.o: $(hdrdir)/ruby/internal/glob.h
+ipsocket.o: $(hdrdir)/ruby/internal/globals.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/attribute.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/builtin.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/extension.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/feature.h
+ipsocket.o: $(hdrdir)/ruby/internal/has/warning.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/array.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/class.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/compar.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/complex.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/cont.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/dir.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/enum.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/error.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/io.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/load.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/object.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/parse.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/proc.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/process.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/random.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/range.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/rational.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/re.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/select.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/signal.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/string.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/struct.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/thread.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/time.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/variable.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/vm.h
+ipsocket.o: $(hdrdir)/ruby/internal/interpreter.h
+ipsocket.o: $(hdrdir)/ruby/internal/iterator.h
+ipsocket.o: $(hdrdir)/ruby/internal/memory.h
+ipsocket.o: $(hdrdir)/ruby/internal/method.h
+ipsocket.o: $(hdrdir)/ruby/internal/module.h
+ipsocket.o: $(hdrdir)/ruby/internal/newobj.h
+ipsocket.o: $(hdrdir)/ruby/internal/rgengc.h
+ipsocket.o: $(hdrdir)/ruby/internal/scan_args.h
+ipsocket.o: $(hdrdir)/ruby/internal/special_consts.h
+ipsocket.o: $(hdrdir)/ruby/internal/static_assert.h
+ipsocket.o: $(hdrdir)/ruby/internal/stdalign.h
+ipsocket.o: $(hdrdir)/ruby/internal/stdbool.h
+ipsocket.o: $(hdrdir)/ruby/internal/symbol.h
+ipsocket.o: $(hdrdir)/ruby/internal/token_paste.h
+ipsocket.o: $(hdrdir)/ruby/internal/value.h
+ipsocket.o: $(hdrdir)/ruby/internal/value_type.h
+ipsocket.o: $(hdrdir)/ruby/internal/variable.h
+ipsocket.o: $(hdrdir)/ruby/internal/warning_push.h
+ipsocket.o: $(hdrdir)/ruby/internal/xmalloc.h
+ipsocket.o: $(hdrdir)/ruby/assert.h
ipsocket.o: $(hdrdir)/ruby/backward.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/assume.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/bool.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/limits.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/long_long.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h
+ipsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h
ipsocket.o: $(hdrdir)/ruby/defines.h
ipsocket.o: $(hdrdir)/ruby/encoding.h
ipsocket.o: $(hdrdir)/ruby/intern.h
@@ -131,15 +1087,176 @@ ipsocket.o: $(hdrdir)/ruby/st.h
ipsocket.o: $(hdrdir)/ruby/subst.h
ipsocket.o: $(hdrdir)/ruby/thread.h
ipsocket.o: $(hdrdir)/ruby/util.h
-ipsocket.o: $(top_srcdir)/include/ruby.h
ipsocket.o: $(top_srcdir)/internal.h
+ipsocket.o: $(top_srcdir)/internal/array.h
+ipsocket.o: $(top_srcdir)/internal/compilers.h
+ipsocket.o: $(top_srcdir)/internal/error.h
+ipsocket.o: $(top_srcdir)/internal/gc.h
+ipsocket.o: $(top_srcdir)/internal/io.h
+ipsocket.o: $(top_srcdir)/internal/serial.h
+ipsocket.o: $(top_srcdir)/internal/static_assert.h
+ipsocket.o: $(top_srcdir)/internal/string.h
+ipsocket.o: $(top_srcdir)/internal/thread.h
+ipsocket.o: $(top_srcdir)/internal/vm.h
+ipsocket.o: $(top_srcdir)/internal/warnings.h
ipsocket.o: constdefs.h
ipsocket.o: ipsocket.c
ipsocket.o: rubysocket.h
ipsocket.o: sockport.h
option.o: $(RUBY_EXTCONF_H)
option.o: $(arch_hdrdir)/ruby/config.h
+option.o: $(hdrdir)/ruby.h
+option.o: $(hdrdir)/ruby/internal/anyargs.h
+option.o: $(hdrdir)/ruby/internal/arithmetic.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+option.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+option.o: $(hdrdir)/ruby/internal/assume.h
+option.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+option.o: $(hdrdir)/ruby/internal/attr/artificial.h
+option.o: $(hdrdir)/ruby/internal/attr/cold.h
+option.o: $(hdrdir)/ruby/internal/attr/const.h
+option.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+option.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+option.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+option.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+option.o: $(hdrdir)/ruby/internal/attr/error.h
+option.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+option.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+option.o: $(hdrdir)/ruby/internal/attr/format.h
+option.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+option.o: $(hdrdir)/ruby/internal/attr/noalias.h
+option.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+option.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+option.o: $(hdrdir)/ruby/internal/attr/noinline.h
+option.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+option.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+option.o: $(hdrdir)/ruby/internal/attr/pure.h
+option.o: $(hdrdir)/ruby/internal/attr/restrict.h
+option.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+option.o: $(hdrdir)/ruby/internal/attr/warning.h
+option.o: $(hdrdir)/ruby/internal/attr/weakref.h
+option.o: $(hdrdir)/ruby/internal/cast.h
+option.o: $(hdrdir)/ruby/internal/compiler_is.h
+option.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+option.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+option.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+option.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+option.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+option.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+option.o: $(hdrdir)/ruby/internal/compiler_since.h
+option.o: $(hdrdir)/ruby/internal/config.h
+option.o: $(hdrdir)/ruby/internal/constant_p.h
+option.o: $(hdrdir)/ruby/internal/core.h
+option.o: $(hdrdir)/ruby/internal/core/rarray.h
+option.o: $(hdrdir)/ruby/internal/core/rbasic.h
+option.o: $(hdrdir)/ruby/internal/core/rbignum.h
+option.o: $(hdrdir)/ruby/internal/core/rclass.h
+option.o: $(hdrdir)/ruby/internal/core/rdata.h
+option.o: $(hdrdir)/ruby/internal/core/rfile.h
+option.o: $(hdrdir)/ruby/internal/core/rhash.h
+option.o: $(hdrdir)/ruby/internal/core/robject.h
+option.o: $(hdrdir)/ruby/internal/core/rregexp.h
+option.o: $(hdrdir)/ruby/internal/core/rstring.h
+option.o: $(hdrdir)/ruby/internal/core/rstruct.h
+option.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+option.o: $(hdrdir)/ruby/internal/ctype.h
+option.o: $(hdrdir)/ruby/internal/dllexport.h
+option.o: $(hdrdir)/ruby/internal/dosish.h
+option.o: $(hdrdir)/ruby/internal/error.h
+option.o: $(hdrdir)/ruby/internal/eval.h
+option.o: $(hdrdir)/ruby/internal/event.h
+option.o: $(hdrdir)/ruby/internal/fl_type.h
+option.o: $(hdrdir)/ruby/internal/gc.h
+option.o: $(hdrdir)/ruby/internal/glob.h
+option.o: $(hdrdir)/ruby/internal/globals.h
+option.o: $(hdrdir)/ruby/internal/has/attribute.h
+option.o: $(hdrdir)/ruby/internal/has/builtin.h
+option.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+option.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+option.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+option.o: $(hdrdir)/ruby/internal/has/extension.h
+option.o: $(hdrdir)/ruby/internal/has/feature.h
+option.o: $(hdrdir)/ruby/internal/has/warning.h
+option.o: $(hdrdir)/ruby/internal/intern/array.h
+option.o: $(hdrdir)/ruby/internal/intern/bignum.h
+option.o: $(hdrdir)/ruby/internal/intern/class.h
+option.o: $(hdrdir)/ruby/internal/intern/compar.h
+option.o: $(hdrdir)/ruby/internal/intern/complex.h
+option.o: $(hdrdir)/ruby/internal/intern/cont.h
+option.o: $(hdrdir)/ruby/internal/intern/dir.h
+option.o: $(hdrdir)/ruby/internal/intern/enum.h
+option.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+option.o: $(hdrdir)/ruby/internal/intern/error.h
+option.o: $(hdrdir)/ruby/internal/intern/eval.h
+option.o: $(hdrdir)/ruby/internal/intern/file.h
+option.o: $(hdrdir)/ruby/internal/intern/gc.h
+option.o: $(hdrdir)/ruby/internal/intern/hash.h
+option.o: $(hdrdir)/ruby/internal/intern/io.h
+option.o: $(hdrdir)/ruby/internal/intern/load.h
+option.o: $(hdrdir)/ruby/internal/intern/marshal.h
+option.o: $(hdrdir)/ruby/internal/intern/numeric.h
+option.o: $(hdrdir)/ruby/internal/intern/object.h
+option.o: $(hdrdir)/ruby/internal/intern/parse.h
+option.o: $(hdrdir)/ruby/internal/intern/proc.h
+option.o: $(hdrdir)/ruby/internal/intern/process.h
+option.o: $(hdrdir)/ruby/internal/intern/random.h
+option.o: $(hdrdir)/ruby/internal/intern/range.h
+option.o: $(hdrdir)/ruby/internal/intern/rational.h
+option.o: $(hdrdir)/ruby/internal/intern/re.h
+option.o: $(hdrdir)/ruby/internal/intern/ruby.h
+option.o: $(hdrdir)/ruby/internal/intern/select.h
+option.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+option.o: $(hdrdir)/ruby/internal/intern/signal.h
+option.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+option.o: $(hdrdir)/ruby/internal/intern/string.h
+option.o: $(hdrdir)/ruby/internal/intern/struct.h
+option.o: $(hdrdir)/ruby/internal/intern/thread.h
+option.o: $(hdrdir)/ruby/internal/intern/time.h
+option.o: $(hdrdir)/ruby/internal/intern/variable.h
+option.o: $(hdrdir)/ruby/internal/intern/vm.h
+option.o: $(hdrdir)/ruby/internal/interpreter.h
+option.o: $(hdrdir)/ruby/internal/iterator.h
+option.o: $(hdrdir)/ruby/internal/memory.h
+option.o: $(hdrdir)/ruby/internal/method.h
+option.o: $(hdrdir)/ruby/internal/module.h
+option.o: $(hdrdir)/ruby/internal/newobj.h
+option.o: $(hdrdir)/ruby/internal/rgengc.h
+option.o: $(hdrdir)/ruby/internal/scan_args.h
+option.o: $(hdrdir)/ruby/internal/special_consts.h
+option.o: $(hdrdir)/ruby/internal/static_assert.h
+option.o: $(hdrdir)/ruby/internal/stdalign.h
+option.o: $(hdrdir)/ruby/internal/stdbool.h
+option.o: $(hdrdir)/ruby/internal/symbol.h
+option.o: $(hdrdir)/ruby/internal/token_paste.h
+option.o: $(hdrdir)/ruby/internal/value.h
+option.o: $(hdrdir)/ruby/internal/value_type.h
+option.o: $(hdrdir)/ruby/internal/variable.h
+option.o: $(hdrdir)/ruby/internal/warning_push.h
+option.o: $(hdrdir)/ruby/internal/xmalloc.h
+option.o: $(hdrdir)/ruby/assert.h
option.o: $(hdrdir)/ruby/backward.h
+option.o: $(hdrdir)/ruby/backward/2/assume.h
+option.o: $(hdrdir)/ruby/backward/2/attributes.h
+option.o: $(hdrdir)/ruby/backward/2/bool.h
+option.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+option.o: $(hdrdir)/ruby/backward/2/inttypes.h
+option.o: $(hdrdir)/ruby/backward/2/limits.h
+option.o: $(hdrdir)/ruby/backward/2/long_long.h
+option.o: $(hdrdir)/ruby/backward/2/stdalign.h
+option.o: $(hdrdir)/ruby/backward/2/stdarg.h
option.o: $(hdrdir)/ruby/defines.h
option.o: $(hdrdir)/ruby/encoding.h
option.o: $(hdrdir)/ruby/intern.h
@@ -152,15 +1269,176 @@ option.o: $(hdrdir)/ruby/st.h
option.o: $(hdrdir)/ruby/subst.h
option.o: $(hdrdir)/ruby/thread.h
option.o: $(hdrdir)/ruby/util.h
-option.o: $(top_srcdir)/include/ruby.h
option.o: $(top_srcdir)/internal.h
+option.o: $(top_srcdir)/internal/array.h
+option.o: $(top_srcdir)/internal/compilers.h
+option.o: $(top_srcdir)/internal/error.h
+option.o: $(top_srcdir)/internal/gc.h
+option.o: $(top_srcdir)/internal/io.h
+option.o: $(top_srcdir)/internal/serial.h
+option.o: $(top_srcdir)/internal/static_assert.h
+option.o: $(top_srcdir)/internal/string.h
+option.o: $(top_srcdir)/internal/thread.h
+option.o: $(top_srcdir)/internal/vm.h
+option.o: $(top_srcdir)/internal/warnings.h
option.o: constdefs.h
option.o: option.c
option.o: rubysocket.h
option.o: sockport.h
raddrinfo.o: $(RUBY_EXTCONF_H)
raddrinfo.o: $(arch_hdrdir)/ruby/config.h
+raddrinfo.o: $(hdrdir)/ruby.h
+raddrinfo.o: $(hdrdir)/ruby/internal/anyargs.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+raddrinfo.o: $(hdrdir)/ruby/internal/assume.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/artificial.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/cold.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/const.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/error.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/format.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/noalias.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/noinline.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/pure.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/restrict.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/warning.h
+raddrinfo.o: $(hdrdir)/ruby/internal/attr/weakref.h
+raddrinfo.o: $(hdrdir)/ruby/internal/cast.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+raddrinfo.o: $(hdrdir)/ruby/internal/compiler_since.h
+raddrinfo.o: $(hdrdir)/ruby/internal/config.h
+raddrinfo.o: $(hdrdir)/ruby/internal/constant_p.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rarray.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rbasic.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rbignum.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rclass.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rdata.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rfile.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rhash.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/robject.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rregexp.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rstring.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rstruct.h
+raddrinfo.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+raddrinfo.o: $(hdrdir)/ruby/internal/ctype.h
+raddrinfo.o: $(hdrdir)/ruby/internal/dllexport.h
+raddrinfo.o: $(hdrdir)/ruby/internal/dosish.h
+raddrinfo.o: $(hdrdir)/ruby/internal/error.h
+raddrinfo.o: $(hdrdir)/ruby/internal/eval.h
+raddrinfo.o: $(hdrdir)/ruby/internal/event.h
+raddrinfo.o: $(hdrdir)/ruby/internal/fl_type.h
+raddrinfo.o: $(hdrdir)/ruby/internal/gc.h
+raddrinfo.o: $(hdrdir)/ruby/internal/glob.h
+raddrinfo.o: $(hdrdir)/ruby/internal/globals.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/attribute.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/builtin.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/extension.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/feature.h
+raddrinfo.o: $(hdrdir)/ruby/internal/has/warning.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/array.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/bignum.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/class.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/compar.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/complex.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/cont.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/dir.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/enum.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/error.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/eval.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/file.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/gc.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/hash.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/io.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/load.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/marshal.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/numeric.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/object.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/parse.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/proc.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/process.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/random.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/range.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/rational.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/re.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/ruby.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/select.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/signal.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/string.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/struct.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/thread.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/time.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/variable.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/vm.h
+raddrinfo.o: $(hdrdir)/ruby/internal/interpreter.h
+raddrinfo.o: $(hdrdir)/ruby/internal/iterator.h
+raddrinfo.o: $(hdrdir)/ruby/internal/memory.h
+raddrinfo.o: $(hdrdir)/ruby/internal/method.h
+raddrinfo.o: $(hdrdir)/ruby/internal/module.h
+raddrinfo.o: $(hdrdir)/ruby/internal/newobj.h
+raddrinfo.o: $(hdrdir)/ruby/internal/rgengc.h
+raddrinfo.o: $(hdrdir)/ruby/internal/scan_args.h
+raddrinfo.o: $(hdrdir)/ruby/internal/special_consts.h
+raddrinfo.o: $(hdrdir)/ruby/internal/static_assert.h
+raddrinfo.o: $(hdrdir)/ruby/internal/stdalign.h
+raddrinfo.o: $(hdrdir)/ruby/internal/stdbool.h
+raddrinfo.o: $(hdrdir)/ruby/internal/symbol.h
+raddrinfo.o: $(hdrdir)/ruby/internal/token_paste.h
+raddrinfo.o: $(hdrdir)/ruby/internal/value.h
+raddrinfo.o: $(hdrdir)/ruby/internal/value_type.h
+raddrinfo.o: $(hdrdir)/ruby/internal/variable.h
+raddrinfo.o: $(hdrdir)/ruby/internal/warning_push.h
+raddrinfo.o: $(hdrdir)/ruby/internal/xmalloc.h
+raddrinfo.o: $(hdrdir)/ruby/assert.h
raddrinfo.o: $(hdrdir)/ruby/backward.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/assume.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/attributes.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/bool.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/inttypes.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/limits.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/long_long.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/stdalign.h
+raddrinfo.o: $(hdrdir)/ruby/backward/2/stdarg.h
raddrinfo.o: $(hdrdir)/ruby/defines.h
raddrinfo.o: $(hdrdir)/ruby/encoding.h
raddrinfo.o: $(hdrdir)/ruby/intern.h
@@ -173,15 +1451,176 @@ raddrinfo.o: $(hdrdir)/ruby/st.h
raddrinfo.o: $(hdrdir)/ruby/subst.h
raddrinfo.o: $(hdrdir)/ruby/thread.h
raddrinfo.o: $(hdrdir)/ruby/util.h
-raddrinfo.o: $(top_srcdir)/include/ruby.h
raddrinfo.o: $(top_srcdir)/internal.h
+raddrinfo.o: $(top_srcdir)/internal/array.h
+raddrinfo.o: $(top_srcdir)/internal/compilers.h
+raddrinfo.o: $(top_srcdir)/internal/error.h
+raddrinfo.o: $(top_srcdir)/internal/gc.h
+raddrinfo.o: $(top_srcdir)/internal/io.h
+raddrinfo.o: $(top_srcdir)/internal/serial.h
+raddrinfo.o: $(top_srcdir)/internal/static_assert.h
+raddrinfo.o: $(top_srcdir)/internal/string.h
+raddrinfo.o: $(top_srcdir)/internal/thread.h
+raddrinfo.o: $(top_srcdir)/internal/vm.h
+raddrinfo.o: $(top_srcdir)/internal/warnings.h
raddrinfo.o: constdefs.h
raddrinfo.o: raddrinfo.c
raddrinfo.o: rubysocket.h
raddrinfo.o: sockport.h
socket.o: $(RUBY_EXTCONF_H)
socket.o: $(arch_hdrdir)/ruby/config.h
+socket.o: $(hdrdir)/ruby.h
+socket.o: $(hdrdir)/ruby/internal/anyargs.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+socket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+socket.o: $(hdrdir)/ruby/internal/assume.h
+socket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+socket.o: $(hdrdir)/ruby/internal/attr/artificial.h
+socket.o: $(hdrdir)/ruby/internal/attr/cold.h
+socket.o: $(hdrdir)/ruby/internal/attr/const.h
+socket.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+socket.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+socket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+socket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+socket.o: $(hdrdir)/ruby/internal/attr/error.h
+socket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+socket.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+socket.o: $(hdrdir)/ruby/internal/attr/format.h
+socket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+socket.o: $(hdrdir)/ruby/internal/attr/noalias.h
+socket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+socket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+socket.o: $(hdrdir)/ruby/internal/attr/noinline.h
+socket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+socket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+socket.o: $(hdrdir)/ruby/internal/attr/pure.h
+socket.o: $(hdrdir)/ruby/internal/attr/restrict.h
+socket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+socket.o: $(hdrdir)/ruby/internal/attr/warning.h
+socket.o: $(hdrdir)/ruby/internal/attr/weakref.h
+socket.o: $(hdrdir)/ruby/internal/cast.h
+socket.o: $(hdrdir)/ruby/internal/compiler_is.h
+socket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+socket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+socket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+socket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+socket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+socket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+socket.o: $(hdrdir)/ruby/internal/compiler_since.h
+socket.o: $(hdrdir)/ruby/internal/config.h
+socket.o: $(hdrdir)/ruby/internal/constant_p.h
+socket.o: $(hdrdir)/ruby/internal/core.h
+socket.o: $(hdrdir)/ruby/internal/core/rarray.h
+socket.o: $(hdrdir)/ruby/internal/core/rbasic.h
+socket.o: $(hdrdir)/ruby/internal/core/rbignum.h
+socket.o: $(hdrdir)/ruby/internal/core/rclass.h
+socket.o: $(hdrdir)/ruby/internal/core/rdata.h
+socket.o: $(hdrdir)/ruby/internal/core/rfile.h
+socket.o: $(hdrdir)/ruby/internal/core/rhash.h
+socket.o: $(hdrdir)/ruby/internal/core/robject.h
+socket.o: $(hdrdir)/ruby/internal/core/rregexp.h
+socket.o: $(hdrdir)/ruby/internal/core/rstring.h
+socket.o: $(hdrdir)/ruby/internal/core/rstruct.h
+socket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+socket.o: $(hdrdir)/ruby/internal/ctype.h
+socket.o: $(hdrdir)/ruby/internal/dllexport.h
+socket.o: $(hdrdir)/ruby/internal/dosish.h
+socket.o: $(hdrdir)/ruby/internal/error.h
+socket.o: $(hdrdir)/ruby/internal/eval.h
+socket.o: $(hdrdir)/ruby/internal/event.h
+socket.o: $(hdrdir)/ruby/internal/fl_type.h
+socket.o: $(hdrdir)/ruby/internal/gc.h
+socket.o: $(hdrdir)/ruby/internal/glob.h
+socket.o: $(hdrdir)/ruby/internal/globals.h
+socket.o: $(hdrdir)/ruby/internal/has/attribute.h
+socket.o: $(hdrdir)/ruby/internal/has/builtin.h
+socket.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+socket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+socket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+socket.o: $(hdrdir)/ruby/internal/has/extension.h
+socket.o: $(hdrdir)/ruby/internal/has/feature.h
+socket.o: $(hdrdir)/ruby/internal/has/warning.h
+socket.o: $(hdrdir)/ruby/internal/intern/array.h
+socket.o: $(hdrdir)/ruby/internal/intern/bignum.h
+socket.o: $(hdrdir)/ruby/internal/intern/class.h
+socket.o: $(hdrdir)/ruby/internal/intern/compar.h
+socket.o: $(hdrdir)/ruby/internal/intern/complex.h
+socket.o: $(hdrdir)/ruby/internal/intern/cont.h
+socket.o: $(hdrdir)/ruby/internal/intern/dir.h
+socket.o: $(hdrdir)/ruby/internal/intern/enum.h
+socket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+socket.o: $(hdrdir)/ruby/internal/intern/error.h
+socket.o: $(hdrdir)/ruby/internal/intern/eval.h
+socket.o: $(hdrdir)/ruby/internal/intern/file.h
+socket.o: $(hdrdir)/ruby/internal/intern/gc.h
+socket.o: $(hdrdir)/ruby/internal/intern/hash.h
+socket.o: $(hdrdir)/ruby/internal/intern/io.h
+socket.o: $(hdrdir)/ruby/internal/intern/load.h
+socket.o: $(hdrdir)/ruby/internal/intern/marshal.h
+socket.o: $(hdrdir)/ruby/internal/intern/numeric.h
+socket.o: $(hdrdir)/ruby/internal/intern/object.h
+socket.o: $(hdrdir)/ruby/internal/intern/parse.h
+socket.o: $(hdrdir)/ruby/internal/intern/proc.h
+socket.o: $(hdrdir)/ruby/internal/intern/process.h
+socket.o: $(hdrdir)/ruby/internal/intern/random.h
+socket.o: $(hdrdir)/ruby/internal/intern/range.h
+socket.o: $(hdrdir)/ruby/internal/intern/rational.h
+socket.o: $(hdrdir)/ruby/internal/intern/re.h
+socket.o: $(hdrdir)/ruby/internal/intern/ruby.h
+socket.o: $(hdrdir)/ruby/internal/intern/select.h
+socket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+socket.o: $(hdrdir)/ruby/internal/intern/signal.h
+socket.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+socket.o: $(hdrdir)/ruby/internal/intern/string.h
+socket.o: $(hdrdir)/ruby/internal/intern/struct.h
+socket.o: $(hdrdir)/ruby/internal/intern/thread.h
+socket.o: $(hdrdir)/ruby/internal/intern/time.h
+socket.o: $(hdrdir)/ruby/internal/intern/variable.h
+socket.o: $(hdrdir)/ruby/internal/intern/vm.h
+socket.o: $(hdrdir)/ruby/internal/interpreter.h
+socket.o: $(hdrdir)/ruby/internal/iterator.h
+socket.o: $(hdrdir)/ruby/internal/memory.h
+socket.o: $(hdrdir)/ruby/internal/method.h
+socket.o: $(hdrdir)/ruby/internal/module.h
+socket.o: $(hdrdir)/ruby/internal/newobj.h
+socket.o: $(hdrdir)/ruby/internal/rgengc.h
+socket.o: $(hdrdir)/ruby/internal/scan_args.h
+socket.o: $(hdrdir)/ruby/internal/special_consts.h
+socket.o: $(hdrdir)/ruby/internal/static_assert.h
+socket.o: $(hdrdir)/ruby/internal/stdalign.h
+socket.o: $(hdrdir)/ruby/internal/stdbool.h
+socket.o: $(hdrdir)/ruby/internal/symbol.h
+socket.o: $(hdrdir)/ruby/internal/token_paste.h
+socket.o: $(hdrdir)/ruby/internal/value.h
+socket.o: $(hdrdir)/ruby/internal/value_type.h
+socket.o: $(hdrdir)/ruby/internal/variable.h
+socket.o: $(hdrdir)/ruby/internal/warning_push.h
+socket.o: $(hdrdir)/ruby/internal/xmalloc.h
+socket.o: $(hdrdir)/ruby/assert.h
socket.o: $(hdrdir)/ruby/backward.h
+socket.o: $(hdrdir)/ruby/backward/2/assume.h
+socket.o: $(hdrdir)/ruby/backward/2/attributes.h
+socket.o: $(hdrdir)/ruby/backward/2/bool.h
+socket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+socket.o: $(hdrdir)/ruby/backward/2/inttypes.h
+socket.o: $(hdrdir)/ruby/backward/2/limits.h
+socket.o: $(hdrdir)/ruby/backward/2/long_long.h
+socket.o: $(hdrdir)/ruby/backward/2/stdalign.h
+socket.o: $(hdrdir)/ruby/backward/2/stdarg.h
socket.o: $(hdrdir)/ruby/defines.h
socket.o: $(hdrdir)/ruby/encoding.h
socket.o: $(hdrdir)/ruby/intern.h
@@ -194,15 +1633,176 @@ socket.o: $(hdrdir)/ruby/st.h
socket.o: $(hdrdir)/ruby/subst.h
socket.o: $(hdrdir)/ruby/thread.h
socket.o: $(hdrdir)/ruby/util.h
-socket.o: $(top_srcdir)/include/ruby.h
socket.o: $(top_srcdir)/internal.h
+socket.o: $(top_srcdir)/internal/array.h
+socket.o: $(top_srcdir)/internal/compilers.h
+socket.o: $(top_srcdir)/internal/error.h
+socket.o: $(top_srcdir)/internal/gc.h
+socket.o: $(top_srcdir)/internal/io.h
+socket.o: $(top_srcdir)/internal/serial.h
+socket.o: $(top_srcdir)/internal/static_assert.h
+socket.o: $(top_srcdir)/internal/string.h
+socket.o: $(top_srcdir)/internal/thread.h
+socket.o: $(top_srcdir)/internal/vm.h
+socket.o: $(top_srcdir)/internal/warnings.h
socket.o: constdefs.h
socket.o: rubysocket.h
socket.o: socket.c
socket.o: sockport.h
sockssocket.o: $(RUBY_EXTCONF_H)
sockssocket.o: $(arch_hdrdir)/ruby/config.h
+sockssocket.o: $(hdrdir)/ruby.h
+sockssocket.o: $(hdrdir)/ruby/internal/anyargs.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+sockssocket.o: $(hdrdir)/ruby/internal/assume.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/artificial.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/cold.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/const.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/error.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/format.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/noalias.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/pure.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/warning.h
+sockssocket.o: $(hdrdir)/ruby/internal/attr/weakref.h
+sockssocket.o: $(hdrdir)/ruby/internal/cast.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_is.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+sockssocket.o: $(hdrdir)/ruby/internal/compiler_since.h
+sockssocket.o: $(hdrdir)/ruby/internal/config.h
+sockssocket.o: $(hdrdir)/ruby/internal/constant_p.h
+sockssocket.o: $(hdrdir)/ruby/internal/core.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rarray.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rbasic.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rbignum.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rclass.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rdata.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rfile.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rhash.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/robject.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rregexp.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rstring.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rstruct.h
+sockssocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+sockssocket.o: $(hdrdir)/ruby/internal/ctype.h
+sockssocket.o: $(hdrdir)/ruby/internal/dllexport.h
+sockssocket.o: $(hdrdir)/ruby/internal/dosish.h
+sockssocket.o: $(hdrdir)/ruby/internal/error.h
+sockssocket.o: $(hdrdir)/ruby/internal/eval.h
+sockssocket.o: $(hdrdir)/ruby/internal/event.h
+sockssocket.o: $(hdrdir)/ruby/internal/fl_type.h
+sockssocket.o: $(hdrdir)/ruby/internal/gc.h
+sockssocket.o: $(hdrdir)/ruby/internal/glob.h
+sockssocket.o: $(hdrdir)/ruby/internal/globals.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/attribute.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/builtin.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/extension.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/feature.h
+sockssocket.o: $(hdrdir)/ruby/internal/has/warning.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/array.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/bignum.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/class.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/compar.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/complex.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/cont.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/dir.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/enum.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/error.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/eval.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/file.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/gc.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/hash.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/io.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/load.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/marshal.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/numeric.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/object.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/parse.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/proc.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/process.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/random.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/range.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/rational.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/re.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/ruby.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/select.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/signal.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/string.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/struct.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/thread.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/time.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/variable.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/vm.h
+sockssocket.o: $(hdrdir)/ruby/internal/interpreter.h
+sockssocket.o: $(hdrdir)/ruby/internal/iterator.h
+sockssocket.o: $(hdrdir)/ruby/internal/memory.h
+sockssocket.o: $(hdrdir)/ruby/internal/method.h
+sockssocket.o: $(hdrdir)/ruby/internal/module.h
+sockssocket.o: $(hdrdir)/ruby/internal/newobj.h
+sockssocket.o: $(hdrdir)/ruby/internal/rgengc.h
+sockssocket.o: $(hdrdir)/ruby/internal/scan_args.h
+sockssocket.o: $(hdrdir)/ruby/internal/special_consts.h
+sockssocket.o: $(hdrdir)/ruby/internal/static_assert.h
+sockssocket.o: $(hdrdir)/ruby/internal/stdalign.h
+sockssocket.o: $(hdrdir)/ruby/internal/stdbool.h
+sockssocket.o: $(hdrdir)/ruby/internal/symbol.h
+sockssocket.o: $(hdrdir)/ruby/internal/token_paste.h
+sockssocket.o: $(hdrdir)/ruby/internal/value.h
+sockssocket.o: $(hdrdir)/ruby/internal/value_type.h
+sockssocket.o: $(hdrdir)/ruby/internal/variable.h
+sockssocket.o: $(hdrdir)/ruby/internal/warning_push.h
+sockssocket.o: $(hdrdir)/ruby/internal/xmalloc.h
+sockssocket.o: $(hdrdir)/ruby/assert.h
sockssocket.o: $(hdrdir)/ruby/backward.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/assume.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/attributes.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/bool.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/inttypes.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/limits.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/long_long.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/stdalign.h
+sockssocket.o: $(hdrdir)/ruby/backward/2/stdarg.h
sockssocket.o: $(hdrdir)/ruby/defines.h
sockssocket.o: $(hdrdir)/ruby/encoding.h
sockssocket.o: $(hdrdir)/ruby/intern.h
@@ -215,15 +1815,176 @@ sockssocket.o: $(hdrdir)/ruby/st.h
sockssocket.o: $(hdrdir)/ruby/subst.h
sockssocket.o: $(hdrdir)/ruby/thread.h
sockssocket.o: $(hdrdir)/ruby/util.h
-sockssocket.o: $(top_srcdir)/include/ruby.h
sockssocket.o: $(top_srcdir)/internal.h
+sockssocket.o: $(top_srcdir)/internal/array.h
+sockssocket.o: $(top_srcdir)/internal/compilers.h
+sockssocket.o: $(top_srcdir)/internal/error.h
+sockssocket.o: $(top_srcdir)/internal/gc.h
+sockssocket.o: $(top_srcdir)/internal/io.h
+sockssocket.o: $(top_srcdir)/internal/serial.h
+sockssocket.o: $(top_srcdir)/internal/static_assert.h
+sockssocket.o: $(top_srcdir)/internal/string.h
+sockssocket.o: $(top_srcdir)/internal/thread.h
+sockssocket.o: $(top_srcdir)/internal/vm.h
+sockssocket.o: $(top_srcdir)/internal/warnings.h
sockssocket.o: constdefs.h
sockssocket.o: rubysocket.h
sockssocket.o: sockport.h
sockssocket.o: sockssocket.c
tcpserver.o: $(RUBY_EXTCONF_H)
tcpserver.o: $(arch_hdrdir)/ruby/config.h
+tcpserver.o: $(hdrdir)/ruby.h
+tcpserver.o: $(hdrdir)/ruby/internal/anyargs.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+tcpserver.o: $(hdrdir)/ruby/internal/assume.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/artificial.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/cold.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/const.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/error.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/format.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/noalias.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/noinline.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/pure.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/restrict.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/warning.h
+tcpserver.o: $(hdrdir)/ruby/internal/attr/weakref.h
+tcpserver.o: $(hdrdir)/ruby/internal/cast.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_is.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+tcpserver.o: $(hdrdir)/ruby/internal/compiler_since.h
+tcpserver.o: $(hdrdir)/ruby/internal/config.h
+tcpserver.o: $(hdrdir)/ruby/internal/constant_p.h
+tcpserver.o: $(hdrdir)/ruby/internal/core.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rarray.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rbasic.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rbignum.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rclass.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rdata.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rfile.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rhash.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/robject.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rregexp.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rstring.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rstruct.h
+tcpserver.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+tcpserver.o: $(hdrdir)/ruby/internal/ctype.h
+tcpserver.o: $(hdrdir)/ruby/internal/dllexport.h
+tcpserver.o: $(hdrdir)/ruby/internal/dosish.h
+tcpserver.o: $(hdrdir)/ruby/internal/error.h
+tcpserver.o: $(hdrdir)/ruby/internal/eval.h
+tcpserver.o: $(hdrdir)/ruby/internal/event.h
+tcpserver.o: $(hdrdir)/ruby/internal/fl_type.h
+tcpserver.o: $(hdrdir)/ruby/internal/gc.h
+tcpserver.o: $(hdrdir)/ruby/internal/glob.h
+tcpserver.o: $(hdrdir)/ruby/internal/globals.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/attribute.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/builtin.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/extension.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/feature.h
+tcpserver.o: $(hdrdir)/ruby/internal/has/warning.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/array.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/bignum.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/class.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/compar.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/complex.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/cont.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/dir.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/enum.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/error.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/eval.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/file.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/gc.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/hash.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/io.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/load.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/marshal.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/numeric.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/object.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/parse.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/proc.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/process.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/random.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/range.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/rational.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/re.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/ruby.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/select.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/signal.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/string.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/struct.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/thread.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/time.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/variable.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/vm.h
+tcpserver.o: $(hdrdir)/ruby/internal/interpreter.h
+tcpserver.o: $(hdrdir)/ruby/internal/iterator.h
+tcpserver.o: $(hdrdir)/ruby/internal/memory.h
+tcpserver.o: $(hdrdir)/ruby/internal/method.h
+tcpserver.o: $(hdrdir)/ruby/internal/module.h
+tcpserver.o: $(hdrdir)/ruby/internal/newobj.h
+tcpserver.o: $(hdrdir)/ruby/internal/rgengc.h
+tcpserver.o: $(hdrdir)/ruby/internal/scan_args.h
+tcpserver.o: $(hdrdir)/ruby/internal/special_consts.h
+tcpserver.o: $(hdrdir)/ruby/internal/static_assert.h
+tcpserver.o: $(hdrdir)/ruby/internal/stdalign.h
+tcpserver.o: $(hdrdir)/ruby/internal/stdbool.h
+tcpserver.o: $(hdrdir)/ruby/internal/symbol.h
+tcpserver.o: $(hdrdir)/ruby/internal/token_paste.h
+tcpserver.o: $(hdrdir)/ruby/internal/value.h
+tcpserver.o: $(hdrdir)/ruby/internal/value_type.h
+tcpserver.o: $(hdrdir)/ruby/internal/variable.h
+tcpserver.o: $(hdrdir)/ruby/internal/warning_push.h
+tcpserver.o: $(hdrdir)/ruby/internal/xmalloc.h
+tcpserver.o: $(hdrdir)/ruby/assert.h
tcpserver.o: $(hdrdir)/ruby/backward.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/assume.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/attributes.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/bool.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/inttypes.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/limits.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/long_long.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/stdalign.h
+tcpserver.o: $(hdrdir)/ruby/backward/2/stdarg.h
tcpserver.o: $(hdrdir)/ruby/defines.h
tcpserver.o: $(hdrdir)/ruby/encoding.h
tcpserver.o: $(hdrdir)/ruby/intern.h
@@ -236,15 +1997,176 @@ tcpserver.o: $(hdrdir)/ruby/st.h
tcpserver.o: $(hdrdir)/ruby/subst.h
tcpserver.o: $(hdrdir)/ruby/thread.h
tcpserver.o: $(hdrdir)/ruby/util.h
-tcpserver.o: $(top_srcdir)/include/ruby.h
tcpserver.o: $(top_srcdir)/internal.h
+tcpserver.o: $(top_srcdir)/internal/array.h
+tcpserver.o: $(top_srcdir)/internal/compilers.h
+tcpserver.o: $(top_srcdir)/internal/error.h
+tcpserver.o: $(top_srcdir)/internal/gc.h
+tcpserver.o: $(top_srcdir)/internal/io.h
+tcpserver.o: $(top_srcdir)/internal/serial.h
+tcpserver.o: $(top_srcdir)/internal/static_assert.h
+tcpserver.o: $(top_srcdir)/internal/string.h
+tcpserver.o: $(top_srcdir)/internal/thread.h
+tcpserver.o: $(top_srcdir)/internal/vm.h
+tcpserver.o: $(top_srcdir)/internal/warnings.h
tcpserver.o: constdefs.h
tcpserver.o: rubysocket.h
tcpserver.o: sockport.h
tcpserver.o: tcpserver.c
tcpsocket.o: $(RUBY_EXTCONF_H)
tcpsocket.o: $(arch_hdrdir)/ruby/config.h
+tcpsocket.o: $(hdrdir)/ruby.h
+tcpsocket.o: $(hdrdir)/ruby/internal/anyargs.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+tcpsocket.o: $(hdrdir)/ruby/internal/assume.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/cold.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/const.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/error.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/format.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/warning.h
+tcpsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h
+tcpsocket.o: $(hdrdir)/ruby/internal/cast.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+tcpsocket.o: $(hdrdir)/ruby/internal/compiler_since.h
+tcpsocket.o: $(hdrdir)/ruby/internal/config.h
+tcpsocket.o: $(hdrdir)/ruby/internal/constant_p.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rarray.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rclass.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rdata.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rfile.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rhash.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/robject.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rstring.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h
+tcpsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+tcpsocket.o: $(hdrdir)/ruby/internal/ctype.h
+tcpsocket.o: $(hdrdir)/ruby/internal/dllexport.h
+tcpsocket.o: $(hdrdir)/ruby/internal/dosish.h
+tcpsocket.o: $(hdrdir)/ruby/internal/error.h
+tcpsocket.o: $(hdrdir)/ruby/internal/eval.h
+tcpsocket.o: $(hdrdir)/ruby/internal/event.h
+tcpsocket.o: $(hdrdir)/ruby/internal/fl_type.h
+tcpsocket.o: $(hdrdir)/ruby/internal/gc.h
+tcpsocket.o: $(hdrdir)/ruby/internal/glob.h
+tcpsocket.o: $(hdrdir)/ruby/internal/globals.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/attribute.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/builtin.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/extension.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/feature.h
+tcpsocket.o: $(hdrdir)/ruby/internal/has/warning.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/array.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/class.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/compar.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/complex.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/cont.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/dir.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/enum.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/error.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/io.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/load.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/object.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/parse.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/proc.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/process.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/random.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/range.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/rational.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/re.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/select.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/signal.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/string.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/struct.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/thread.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/time.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/variable.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/vm.h
+tcpsocket.o: $(hdrdir)/ruby/internal/interpreter.h
+tcpsocket.o: $(hdrdir)/ruby/internal/iterator.h
+tcpsocket.o: $(hdrdir)/ruby/internal/memory.h
+tcpsocket.o: $(hdrdir)/ruby/internal/method.h
+tcpsocket.o: $(hdrdir)/ruby/internal/module.h
+tcpsocket.o: $(hdrdir)/ruby/internal/newobj.h
+tcpsocket.o: $(hdrdir)/ruby/internal/rgengc.h
+tcpsocket.o: $(hdrdir)/ruby/internal/scan_args.h
+tcpsocket.o: $(hdrdir)/ruby/internal/special_consts.h
+tcpsocket.o: $(hdrdir)/ruby/internal/static_assert.h
+tcpsocket.o: $(hdrdir)/ruby/internal/stdalign.h
+tcpsocket.o: $(hdrdir)/ruby/internal/stdbool.h
+tcpsocket.o: $(hdrdir)/ruby/internal/symbol.h
+tcpsocket.o: $(hdrdir)/ruby/internal/token_paste.h
+tcpsocket.o: $(hdrdir)/ruby/internal/value.h
+tcpsocket.o: $(hdrdir)/ruby/internal/value_type.h
+tcpsocket.o: $(hdrdir)/ruby/internal/variable.h
+tcpsocket.o: $(hdrdir)/ruby/internal/warning_push.h
+tcpsocket.o: $(hdrdir)/ruby/internal/xmalloc.h
+tcpsocket.o: $(hdrdir)/ruby/assert.h
tcpsocket.o: $(hdrdir)/ruby/backward.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/assume.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/bool.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/limits.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/long_long.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h
+tcpsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h
tcpsocket.o: $(hdrdir)/ruby/defines.h
tcpsocket.o: $(hdrdir)/ruby/encoding.h
tcpsocket.o: $(hdrdir)/ruby/intern.h
@@ -257,15 +2179,176 @@ tcpsocket.o: $(hdrdir)/ruby/st.h
tcpsocket.o: $(hdrdir)/ruby/subst.h
tcpsocket.o: $(hdrdir)/ruby/thread.h
tcpsocket.o: $(hdrdir)/ruby/util.h
-tcpsocket.o: $(top_srcdir)/include/ruby.h
tcpsocket.o: $(top_srcdir)/internal.h
+tcpsocket.o: $(top_srcdir)/internal/array.h
+tcpsocket.o: $(top_srcdir)/internal/compilers.h
+tcpsocket.o: $(top_srcdir)/internal/error.h
+tcpsocket.o: $(top_srcdir)/internal/gc.h
+tcpsocket.o: $(top_srcdir)/internal/io.h
+tcpsocket.o: $(top_srcdir)/internal/serial.h
+tcpsocket.o: $(top_srcdir)/internal/static_assert.h
+tcpsocket.o: $(top_srcdir)/internal/string.h
+tcpsocket.o: $(top_srcdir)/internal/thread.h
+tcpsocket.o: $(top_srcdir)/internal/vm.h
+tcpsocket.o: $(top_srcdir)/internal/warnings.h
tcpsocket.o: constdefs.h
tcpsocket.o: rubysocket.h
tcpsocket.o: sockport.h
tcpsocket.o: tcpsocket.c
udpsocket.o: $(RUBY_EXTCONF_H)
udpsocket.o: $(arch_hdrdir)/ruby/config.h
+udpsocket.o: $(hdrdir)/ruby.h
+udpsocket.o: $(hdrdir)/ruby/internal/anyargs.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+udpsocket.o: $(hdrdir)/ruby/internal/assume.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/cold.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/const.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/error.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/format.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/warning.h
+udpsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h
+udpsocket.o: $(hdrdir)/ruby/internal/cast.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_is.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+udpsocket.o: $(hdrdir)/ruby/internal/compiler_since.h
+udpsocket.o: $(hdrdir)/ruby/internal/config.h
+udpsocket.o: $(hdrdir)/ruby/internal/constant_p.h
+udpsocket.o: $(hdrdir)/ruby/internal/core.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rarray.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rclass.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rdata.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rfile.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rhash.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/robject.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rstring.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h
+udpsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+udpsocket.o: $(hdrdir)/ruby/internal/ctype.h
+udpsocket.o: $(hdrdir)/ruby/internal/dllexport.h
+udpsocket.o: $(hdrdir)/ruby/internal/dosish.h
+udpsocket.o: $(hdrdir)/ruby/internal/error.h
+udpsocket.o: $(hdrdir)/ruby/internal/eval.h
+udpsocket.o: $(hdrdir)/ruby/internal/event.h
+udpsocket.o: $(hdrdir)/ruby/internal/fl_type.h
+udpsocket.o: $(hdrdir)/ruby/internal/gc.h
+udpsocket.o: $(hdrdir)/ruby/internal/glob.h
+udpsocket.o: $(hdrdir)/ruby/internal/globals.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/attribute.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/builtin.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/extension.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/feature.h
+udpsocket.o: $(hdrdir)/ruby/internal/has/warning.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/array.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/class.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/compar.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/complex.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/cont.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/dir.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/enum.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/error.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/io.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/load.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/object.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/parse.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/proc.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/process.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/random.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/range.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/rational.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/re.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/select.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/signal.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/string.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/struct.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/thread.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/time.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/variable.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/vm.h
+udpsocket.o: $(hdrdir)/ruby/internal/interpreter.h
+udpsocket.o: $(hdrdir)/ruby/internal/iterator.h
+udpsocket.o: $(hdrdir)/ruby/internal/memory.h
+udpsocket.o: $(hdrdir)/ruby/internal/method.h
+udpsocket.o: $(hdrdir)/ruby/internal/module.h
+udpsocket.o: $(hdrdir)/ruby/internal/newobj.h
+udpsocket.o: $(hdrdir)/ruby/internal/rgengc.h
+udpsocket.o: $(hdrdir)/ruby/internal/scan_args.h
+udpsocket.o: $(hdrdir)/ruby/internal/special_consts.h
+udpsocket.o: $(hdrdir)/ruby/internal/static_assert.h
+udpsocket.o: $(hdrdir)/ruby/internal/stdalign.h
+udpsocket.o: $(hdrdir)/ruby/internal/stdbool.h
+udpsocket.o: $(hdrdir)/ruby/internal/symbol.h
+udpsocket.o: $(hdrdir)/ruby/internal/token_paste.h
+udpsocket.o: $(hdrdir)/ruby/internal/value.h
+udpsocket.o: $(hdrdir)/ruby/internal/value_type.h
+udpsocket.o: $(hdrdir)/ruby/internal/variable.h
+udpsocket.o: $(hdrdir)/ruby/internal/warning_push.h
+udpsocket.o: $(hdrdir)/ruby/internal/xmalloc.h
+udpsocket.o: $(hdrdir)/ruby/assert.h
udpsocket.o: $(hdrdir)/ruby/backward.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/assume.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/bool.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/limits.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/long_long.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h
+udpsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h
udpsocket.o: $(hdrdir)/ruby/defines.h
udpsocket.o: $(hdrdir)/ruby/encoding.h
udpsocket.o: $(hdrdir)/ruby/intern.h
@@ -278,15 +2361,176 @@ udpsocket.o: $(hdrdir)/ruby/st.h
udpsocket.o: $(hdrdir)/ruby/subst.h
udpsocket.o: $(hdrdir)/ruby/thread.h
udpsocket.o: $(hdrdir)/ruby/util.h
-udpsocket.o: $(top_srcdir)/include/ruby.h
udpsocket.o: $(top_srcdir)/internal.h
+udpsocket.o: $(top_srcdir)/internal/array.h
+udpsocket.o: $(top_srcdir)/internal/compilers.h
+udpsocket.o: $(top_srcdir)/internal/error.h
+udpsocket.o: $(top_srcdir)/internal/gc.h
+udpsocket.o: $(top_srcdir)/internal/io.h
+udpsocket.o: $(top_srcdir)/internal/serial.h
+udpsocket.o: $(top_srcdir)/internal/static_assert.h
+udpsocket.o: $(top_srcdir)/internal/string.h
+udpsocket.o: $(top_srcdir)/internal/thread.h
+udpsocket.o: $(top_srcdir)/internal/vm.h
+udpsocket.o: $(top_srcdir)/internal/warnings.h
udpsocket.o: constdefs.h
udpsocket.o: rubysocket.h
udpsocket.o: sockport.h
udpsocket.o: udpsocket.c
unixserver.o: $(RUBY_EXTCONF_H)
unixserver.o: $(arch_hdrdir)/ruby/config.h
+unixserver.o: $(hdrdir)/ruby.h
+unixserver.o: $(hdrdir)/ruby/internal/anyargs.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+unixserver.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+unixserver.o: $(hdrdir)/ruby/internal/assume.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/artificial.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/cold.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/const.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/error.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/format.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/noalias.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/noinline.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/pure.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/restrict.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/warning.h
+unixserver.o: $(hdrdir)/ruby/internal/attr/weakref.h
+unixserver.o: $(hdrdir)/ruby/internal/cast.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_is.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+unixserver.o: $(hdrdir)/ruby/internal/compiler_since.h
+unixserver.o: $(hdrdir)/ruby/internal/config.h
+unixserver.o: $(hdrdir)/ruby/internal/constant_p.h
+unixserver.o: $(hdrdir)/ruby/internal/core.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rarray.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rbasic.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rbignum.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rclass.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rdata.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rfile.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rhash.h
+unixserver.o: $(hdrdir)/ruby/internal/core/robject.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rregexp.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rstring.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rstruct.h
+unixserver.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+unixserver.o: $(hdrdir)/ruby/internal/ctype.h
+unixserver.o: $(hdrdir)/ruby/internal/dllexport.h
+unixserver.o: $(hdrdir)/ruby/internal/dosish.h
+unixserver.o: $(hdrdir)/ruby/internal/error.h
+unixserver.o: $(hdrdir)/ruby/internal/eval.h
+unixserver.o: $(hdrdir)/ruby/internal/event.h
+unixserver.o: $(hdrdir)/ruby/internal/fl_type.h
+unixserver.o: $(hdrdir)/ruby/internal/gc.h
+unixserver.o: $(hdrdir)/ruby/internal/glob.h
+unixserver.o: $(hdrdir)/ruby/internal/globals.h
+unixserver.o: $(hdrdir)/ruby/internal/has/attribute.h
+unixserver.o: $(hdrdir)/ruby/internal/has/builtin.h
+unixserver.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+unixserver.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+unixserver.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+unixserver.o: $(hdrdir)/ruby/internal/has/extension.h
+unixserver.o: $(hdrdir)/ruby/internal/has/feature.h
+unixserver.o: $(hdrdir)/ruby/internal/has/warning.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/array.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/bignum.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/class.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/compar.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/complex.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/cont.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/dir.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/enum.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/error.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/eval.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/file.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/gc.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/hash.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/io.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/load.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/marshal.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/numeric.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/object.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/parse.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/proc.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/process.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/random.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/range.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/rational.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/re.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/ruby.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/select.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/signal.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/string.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/struct.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/thread.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/time.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/variable.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/vm.h
+unixserver.o: $(hdrdir)/ruby/internal/interpreter.h
+unixserver.o: $(hdrdir)/ruby/internal/iterator.h
+unixserver.o: $(hdrdir)/ruby/internal/memory.h
+unixserver.o: $(hdrdir)/ruby/internal/method.h
+unixserver.o: $(hdrdir)/ruby/internal/module.h
+unixserver.o: $(hdrdir)/ruby/internal/newobj.h
+unixserver.o: $(hdrdir)/ruby/internal/rgengc.h
+unixserver.o: $(hdrdir)/ruby/internal/scan_args.h
+unixserver.o: $(hdrdir)/ruby/internal/special_consts.h
+unixserver.o: $(hdrdir)/ruby/internal/static_assert.h
+unixserver.o: $(hdrdir)/ruby/internal/stdalign.h
+unixserver.o: $(hdrdir)/ruby/internal/stdbool.h
+unixserver.o: $(hdrdir)/ruby/internal/symbol.h
+unixserver.o: $(hdrdir)/ruby/internal/token_paste.h
+unixserver.o: $(hdrdir)/ruby/internal/value.h
+unixserver.o: $(hdrdir)/ruby/internal/value_type.h
+unixserver.o: $(hdrdir)/ruby/internal/variable.h
+unixserver.o: $(hdrdir)/ruby/internal/warning_push.h
+unixserver.o: $(hdrdir)/ruby/internal/xmalloc.h
+unixserver.o: $(hdrdir)/ruby/assert.h
unixserver.o: $(hdrdir)/ruby/backward.h
+unixserver.o: $(hdrdir)/ruby/backward/2/assume.h
+unixserver.o: $(hdrdir)/ruby/backward/2/attributes.h
+unixserver.o: $(hdrdir)/ruby/backward/2/bool.h
+unixserver.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+unixserver.o: $(hdrdir)/ruby/backward/2/inttypes.h
+unixserver.o: $(hdrdir)/ruby/backward/2/limits.h
+unixserver.o: $(hdrdir)/ruby/backward/2/long_long.h
+unixserver.o: $(hdrdir)/ruby/backward/2/stdalign.h
+unixserver.o: $(hdrdir)/ruby/backward/2/stdarg.h
unixserver.o: $(hdrdir)/ruby/defines.h
unixserver.o: $(hdrdir)/ruby/encoding.h
unixserver.o: $(hdrdir)/ruby/intern.h
@@ -299,15 +2543,176 @@ unixserver.o: $(hdrdir)/ruby/st.h
unixserver.o: $(hdrdir)/ruby/subst.h
unixserver.o: $(hdrdir)/ruby/thread.h
unixserver.o: $(hdrdir)/ruby/util.h
-unixserver.o: $(top_srcdir)/include/ruby.h
unixserver.o: $(top_srcdir)/internal.h
+unixserver.o: $(top_srcdir)/internal/array.h
+unixserver.o: $(top_srcdir)/internal/compilers.h
+unixserver.o: $(top_srcdir)/internal/error.h
+unixserver.o: $(top_srcdir)/internal/gc.h
+unixserver.o: $(top_srcdir)/internal/io.h
+unixserver.o: $(top_srcdir)/internal/serial.h
+unixserver.o: $(top_srcdir)/internal/static_assert.h
+unixserver.o: $(top_srcdir)/internal/string.h
+unixserver.o: $(top_srcdir)/internal/thread.h
+unixserver.o: $(top_srcdir)/internal/vm.h
+unixserver.o: $(top_srcdir)/internal/warnings.h
unixserver.o: constdefs.h
unixserver.o: rubysocket.h
unixserver.o: sockport.h
unixserver.o: unixserver.c
unixsocket.o: $(RUBY_EXTCONF_H)
unixsocket.o: $(arch_hdrdir)/ruby/config.h
+unixsocket.o: $(hdrdir)/ruby.h
+unixsocket.o: $(hdrdir)/ruby/internal/anyargs.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+unixsocket.o: $(hdrdir)/ruby/internal/assume.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/cold.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/const.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/error.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/format.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/warning.h
+unixsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h
+unixsocket.o: $(hdrdir)/ruby/internal/cast.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_is.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+unixsocket.o: $(hdrdir)/ruby/internal/compiler_since.h
+unixsocket.o: $(hdrdir)/ruby/internal/config.h
+unixsocket.o: $(hdrdir)/ruby/internal/constant_p.h
+unixsocket.o: $(hdrdir)/ruby/internal/core.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rarray.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rclass.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rdata.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rfile.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rhash.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/robject.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rstring.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h
+unixsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+unixsocket.o: $(hdrdir)/ruby/internal/ctype.h
+unixsocket.o: $(hdrdir)/ruby/internal/dllexport.h
+unixsocket.o: $(hdrdir)/ruby/internal/dosish.h
+unixsocket.o: $(hdrdir)/ruby/internal/error.h
+unixsocket.o: $(hdrdir)/ruby/internal/eval.h
+unixsocket.o: $(hdrdir)/ruby/internal/event.h
+unixsocket.o: $(hdrdir)/ruby/internal/fl_type.h
+unixsocket.o: $(hdrdir)/ruby/internal/gc.h
+unixsocket.o: $(hdrdir)/ruby/internal/glob.h
+unixsocket.o: $(hdrdir)/ruby/internal/globals.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/attribute.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/builtin.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/extension.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/feature.h
+unixsocket.o: $(hdrdir)/ruby/internal/has/warning.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/array.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/class.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/compar.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/complex.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/cont.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/dir.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/enum.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/error.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/io.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/load.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/object.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/parse.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/proc.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/process.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/random.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/range.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/rational.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/re.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/select.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/signal.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/string.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/struct.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/thread.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/time.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/variable.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/vm.h
+unixsocket.o: $(hdrdir)/ruby/internal/interpreter.h
+unixsocket.o: $(hdrdir)/ruby/internal/iterator.h
+unixsocket.o: $(hdrdir)/ruby/internal/memory.h
+unixsocket.o: $(hdrdir)/ruby/internal/method.h
+unixsocket.o: $(hdrdir)/ruby/internal/module.h
+unixsocket.o: $(hdrdir)/ruby/internal/newobj.h
+unixsocket.o: $(hdrdir)/ruby/internal/rgengc.h
+unixsocket.o: $(hdrdir)/ruby/internal/scan_args.h
+unixsocket.o: $(hdrdir)/ruby/internal/special_consts.h
+unixsocket.o: $(hdrdir)/ruby/internal/static_assert.h
+unixsocket.o: $(hdrdir)/ruby/internal/stdalign.h
+unixsocket.o: $(hdrdir)/ruby/internal/stdbool.h
+unixsocket.o: $(hdrdir)/ruby/internal/symbol.h
+unixsocket.o: $(hdrdir)/ruby/internal/token_paste.h
+unixsocket.o: $(hdrdir)/ruby/internal/value.h
+unixsocket.o: $(hdrdir)/ruby/internal/value_type.h
+unixsocket.o: $(hdrdir)/ruby/internal/variable.h
+unixsocket.o: $(hdrdir)/ruby/internal/warning_push.h
+unixsocket.o: $(hdrdir)/ruby/internal/xmalloc.h
+unixsocket.o: $(hdrdir)/ruby/assert.h
unixsocket.o: $(hdrdir)/ruby/backward.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/assume.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/bool.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/limits.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/long_long.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h
+unixsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h
unixsocket.o: $(hdrdir)/ruby/defines.h
unixsocket.o: $(hdrdir)/ruby/encoding.h
unixsocket.o: $(hdrdir)/ruby/intern.h
@@ -320,8 +2725,18 @@ unixsocket.o: $(hdrdir)/ruby/st.h
unixsocket.o: $(hdrdir)/ruby/subst.h
unixsocket.o: $(hdrdir)/ruby/thread.h
unixsocket.o: $(hdrdir)/ruby/util.h
-unixsocket.o: $(top_srcdir)/include/ruby.h
unixsocket.o: $(top_srcdir)/internal.h
+unixsocket.o: $(top_srcdir)/internal/array.h
+unixsocket.o: $(top_srcdir)/internal/compilers.h
+unixsocket.o: $(top_srcdir)/internal/error.h
+unixsocket.o: $(top_srcdir)/internal/gc.h
+unixsocket.o: $(top_srcdir)/internal/io.h
+unixsocket.o: $(top_srcdir)/internal/serial.h
+unixsocket.o: $(top_srcdir)/internal/static_assert.h
+unixsocket.o: $(top_srcdir)/internal/string.h
+unixsocket.o: $(top_srcdir)/internal/thread.h
+unixsocket.o: $(top_srcdir)/internal/vm.h
+unixsocket.o: $(top_srcdir)/internal/warnings.h
unixsocket.o: constdefs.h
unixsocket.o: rubysocket.h
unixsocket.o: sockport.h
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index ec89bed7c2..c86cc8f8c0 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -433,6 +433,7 @@ end
case RUBY_PLATFORM
when /mswin(32|64)|mingw/
test_func = "WSACleanup"
+ have_library("iphlpapi")
have_library("ws2_32", "WSACleanup", headers)
when /cygwin/
test_func = "socket(0,0,0)"
@@ -645,7 +646,7 @@ EOS
if enable_config("socks", ENV["SOCKS_SERVER"])
if have_library("socks5", "SOCKSinit")
$defs << "-DSOCKS5" << "-DSOCKS"
- elsif have_library("socks", "Rconnect")
+ elsif have_library("socksd", "Rconnect") || have_library("socks", "Rconnect")
$defs << "-DSOCKS"
end
end
diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c
index b01f1cb82e..ce6dc40478 100644
--- a/ext/socket/getaddrinfo.c
+++ b/ext/socket/getaddrinfo.c
@@ -149,6 +149,7 @@ static int get_addr __P((const char *, int, struct addrinfo **,
struct addrinfo *, int));
static int str_isnumber __P((const char *));
+#ifndef HAVE_GAI_STRERROR
static const char *const ai_errlist[] = {
"success.",
"address family for hostname not supported.", /* EAI_ADDRFAMILY */
@@ -166,6 +167,7 @@ static const char *const ai_errlist[] = {
"resolved protocol is unknown.", /* EAI_PROTOCOL */
"unknown error.", /* EAI_MAX */
};
+#endif
#define GET_CANONNAME(ai, str) \
if (pai->ai_flags & AI_CANONNAME) {\
diff --git a/ext/socket/ifaddr.c b/ext/socket/ifaddr.c
index 4e2fc065c0..1da259bd6f 100644
--- a/ext/socket/ifaddr.c
+++ b/ext/socket/ifaddr.c
@@ -24,7 +24,6 @@ typedef struct rb_ifaddr_root_tag rb_ifaddr_root_t;
struct rb_ifaddr_tag {
int ord;
struct ifaddrs *ifaddr;
- rb_ifaddr_root_t *root;
};
struct rb_ifaddr_root_tag {
@@ -55,11 +54,12 @@ ifaddr_free(void *ptr)
static size_t
ifaddr_memsize(const void *ptr)
{
+ size_t size = offsetof(rb_ifaddr_root_t, ary);
const rb_ifaddr_t *ifaddr;
- const rb_ifaddr_root_t *root;
ifaddr = ptr;
- root = get_root(ifaddr);
- return sizeof(rb_ifaddr_root_t) + (root->numifaddrs - 1) * sizeof(rb_ifaddr_t);
+ if (ifaddr->ord == 0) size = sizeof(rb_ifaddr_root_t);
+ size += sizeof(struct ifaddrs);
+ return size;
}
static const rb_data_type_t ifaddr_type = {
@@ -84,6 +84,12 @@ get_ifaddr(VALUE self)
return rifaddr;
}
+static struct ifaddrs *
+get_ifaddrs(VALUE self)
+{
+ return get_ifaddr(self)->ifaddr;
+}
+
static VALUE
rsock_getifaddrs(void)
{
@@ -106,7 +112,7 @@ rsock_getifaddrs(void)
numifaddrs++;
addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, 0);
- root = xmalloc(sizeof(rb_ifaddr_root_t) + (numifaddrs-1) * sizeof(rb_ifaddr_t));
+ root = xmalloc(offsetof(rb_ifaddr_root_t, ary) + numifaddrs * sizeof(rb_ifaddr_t));
root->refcount = 0;
root->numifaddrs = numifaddrs;
@@ -114,7 +120,6 @@ rsock_getifaddrs(void)
for (i = 0; i < numifaddrs; i++) {
root->ary[i].ord = i;
root->ary[i].ifaddr = ifa;
- root->ary[i].root = root;
ifa = ifa->ifa_next;
}
RTYPEDDATA_DATA(addr) = &root->ary[0];
@@ -141,8 +146,7 @@ rsock_getifaddrs(void)
static VALUE
ifaddr_name(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
return rb_str_new_cstr(ifa->ifa_name);
}
@@ -157,8 +161,7 @@ ifaddr_name(VALUE self)
static VALUE
ifaddr_ifindex(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
unsigned int ifindex = if_nametoindex(ifa->ifa_name);
if (ifindex == 0) {
rb_raise(rb_eArgError, "invalid interface name: %s", ifa->ifa_name);
@@ -179,8 +182,7 @@ ifaddr_ifindex(VALUE self)
static VALUE
ifaddr_flags(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
return IFAFLAGS2NUM(ifa->ifa_flags);
}
@@ -195,8 +197,7 @@ ifaddr_flags(VALUE self)
static VALUE
ifaddr_addr(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if (ifa->ifa_addr)
return rsock_sockaddr_obj(ifa->ifa_addr, rsock_sockaddr_len(ifa->ifa_addr));
return Qnil;
@@ -213,8 +214,7 @@ ifaddr_addr(VALUE self)
static VALUE
ifaddr_netmask(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if (ifa->ifa_netmask)
return rsock_sockaddr_obj(ifa->ifa_netmask, rsock_sockaddr_len(ifa->ifa_netmask));
return Qnil;
@@ -231,8 +231,7 @@ ifaddr_netmask(VALUE self)
static VALUE
ifaddr_broadaddr(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if ((ifa->ifa_flags & IFF_BROADCAST) && ifa->ifa_broadaddr)
return rsock_sockaddr_obj(ifa->ifa_broadaddr, rsock_sockaddr_len(ifa->ifa_broadaddr));
return Qnil;
@@ -249,8 +248,7 @@ ifaddr_broadaddr(VALUE self)
static VALUE
ifaddr_dstaddr(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if ((ifa->ifa_flags & IFF_POINTOPOINT) && ifa->ifa_dstaddr)
return rsock_sockaddr_obj(ifa->ifa_dstaddr, rsock_sockaddr_len(ifa->ifa_dstaddr));
return Qnil;
@@ -262,14 +260,13 @@ ifaddr_dstaddr(VALUE self)
* ifaddr.vhid => Integer
*
* Returns the vhid address of _ifaddr_.
- * nil is returned if there is no vhid
+ * nil is returned if there is no vhid.
*/
static VALUE
ifaddr_vhid(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if (ifa->ifa_data)
return (INT2FIX(((struct if_data*)ifa->ifa_data)->ifi_vhid));
else
@@ -359,12 +356,9 @@ ifaddr_inspect_flags(ifa_flags_t flags, VALUE result)
static VALUE
ifaddr_inspect(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa;
+ struct ifaddrs *ifa = get_ifaddrs(self);
VALUE result;
- ifa = rifaddr->ifaddr;
-
result = rb_str_new_cstr("#<");
rb_str_append(result, rb_class_name(CLASS_OF(self)));
@@ -465,7 +459,8 @@ rsock_init_sockifaddr(void)
*
* Socket::Ifaddr represents a result of getifaddrs() function.
*/
- rb_cSockIfaddr = rb_define_class_under(rb_cSocket, "Ifaddr", rb_cData);
+ rb_cSockIfaddr = rb_define_class_under(rb_cSocket, "Ifaddr", rb_cObject);
+ rb_undef_alloc_func(rb_cSockIfaddr);
rb_define_method(rb_cSockIfaddr, "inspect", ifaddr_inspect, 0);
rb_define_method(rb_cSockIfaddr, "name", ifaddr_name, 0);
rb_define_method(rb_cSockIfaddr, "ifindex", ifaddr_ifindex, 0);
diff --git a/ext/socket/init.c b/ext/socket/init.c
index 1ecd4fe352..af46b8edaa 100644
--- a/ext/socket/init.c
+++ b/ext/socket/init.c
@@ -10,6 +10,10 @@
#include "rubysocket.h"
+#ifdef _WIN32
+VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
+#endif
+
VALUE rb_cBasicSocket;
VALUE rb_cIPSocket;
VALUE rb_cTCPSocket;
@@ -39,7 +43,15 @@ rsock_raise_socket_error(const char *reason, int error)
if (error == EAI_SYSTEM && (e = errno) != 0)
rb_syserr_fail(e, reason);
#endif
+#ifdef _WIN32
+ rb_encoding *enc = rb_default_internal_encoding();
+ VALUE msg = rb_sprintf("%s: ", reason);
+ if (!enc) enc = rb_default_internal_encoding();
+ rb_str_concat(msg, rb_w32_conv_from_wchar(gai_strerrorW(error), enc));
+ rb_exc_raise(rb_exc_new_str(rb_eSocket, msg));
+#else
rb_raise(rb_eSocket, "%s: %s", reason, gai_strerror(error));
+#endif
}
#ifdef _WIN32
@@ -56,6 +68,12 @@ is_socket(int fd)
}
#endif
+#if defined __APPLE__
+# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE)
+#else
+# define do_write_retry(code) ret = code
+#endif
+
VALUE
rsock_init_sock(VALUE sock, int fd)
{
@@ -83,8 +101,10 @@ rsock_sendto_blocking(void *data)
{
struct rsock_send_arg *arg = data;
VALUE mesg = arg->mesg;
- return (VALUE)sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
- arg->flags, arg->to, arg->tolen);
+ ssize_t ret;
+ do_write_retry(sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
+ arg->flags, arg->to, arg->tolen));
+ return (VALUE)ret;
}
VALUE
@@ -92,13 +112,16 @@ rsock_send_blocking(void *data)
{
struct rsock_send_arg *arg = data;
VALUE mesg = arg->mesg;
- return (VALUE)send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
- arg->flags);
+ ssize_t ret;
+ do_write_retry(send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
+ arg->flags));
+ return (VALUE)ret;
}
struct recvfrom_arg {
int fd, flags;
VALUE str;
+ size_t length;
socklen_t alen;
union_sockaddr buf;
};
@@ -109,10 +132,11 @@ recvfrom_blocking(void *data)
struct recvfrom_arg *arg = data;
socklen_t len0 = arg->alen;
ssize_t ret;
- ret = recvfrom(arg->fd, RSTRING_PTR(arg->str), RSTRING_LEN(arg->str),
+ ret = recvfrom(arg->fd, RSTRING_PTR(arg->str), arg->length,
arg->flags, &arg->buf.addr, &arg->alen);
if (ret != -1 && len0 < arg->alen)
arg->alen = len0;
+
return (VALUE)ret;
}
@@ -121,7 +145,7 @@ rsock_strbuf(VALUE str, long buflen)
{
long len;
- if (NIL_P(str)) return rb_tainted_str_new(0, buflen);
+ if (NIL_P(str)) return rb_str_new(0, buflen);
StringValue(str);
len = RSTRING_LEN(str);
@@ -130,7 +154,6 @@ rsock_strbuf(VALUE str, long buflen)
} else {
rb_str_modify_expand(str, buflen - len);
}
- rb_str_set_len(str, buflen);
return str;
}
@@ -166,6 +189,7 @@ rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
arg.fd = fptr->fd;
arg.alen = (socklen_t)sizeof(arg.buf);
arg.str = str;
+ arg.length = buflen;
while (rb_io_check_closed(fptr),
rsock_maybe_wait_fd(arg.fd),
@@ -176,10 +200,8 @@ rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
}
}
- if (slen != RSTRING_LEN(str)) {
- rb_str_set_len(str, slen);
- }
- rb_obj_taint(str);
+ /* Resize the string to the amount of data received */
+ rb_str_set_len(str, slen);
switch (from) {
case RECV_RECV:
return str;
@@ -260,7 +282,6 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
if (slen != RSTRING_LEN(str)) {
rb_str_set_len(str, slen);
}
- rb_obj_taint(str);
switch (from) {
case RECV_RECV:
return str;
@@ -280,78 +301,137 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
return rb_assoc_new(str, addr);
}
-/* returns true if SOCK_CLOEXEC is supported */
-int rsock_detect_cloexec(int fd)
+#if MSG_DONTWAIT_RELIABLE
+static VALUE sym_wait_writable;
+
+/* copied from io.c :< */
+static long
+read_buffered_data(char *ptr, long len, rb_io_t *fptr)
{
-#ifdef SOCK_CLOEXEC
- int flags = fcntl(fd, F_GETFD);
+ int n = fptr->rbuf.len;
+
+ if (n <= 0) return 0;
+ if (n > len) n = (int)len;
+ MEMMOVE(ptr, fptr->rbuf.ptr+fptr->rbuf.off, char, n);
+ fptr->rbuf.off += n;
+ fptr->rbuf.len -= n;
+ return n;
+}
+
+/* :nodoc: */
+VALUE
+rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex)
+{
+ rb_io_t *fptr;
+ long n;
+ long len = NUM2LONG(length);
+ VALUE str = rsock_strbuf(buf, len);
+ char *ptr;
- if (flags == -1)
- rb_bug("rsock_detect_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno));
+ GetOpenFile(sock, fptr);
- if (flags & FD_CLOEXEC)
- return 1;
-#endif
- return 0;
+ if (len == 0) {
+ rb_str_set_len(str, 0);
+ return str;
+ }
+
+ ptr = RSTRING_PTR(str);
+ n = read_buffered_data(ptr, len, fptr);
+ if (n <= 0) {
+ n = (long)recv(fptr->fd, ptr, len, MSG_DONTWAIT);
+ if (n < 0) {
+ int e = errno;
+ if ((e == EWOULDBLOCK || e == EAGAIN)) {
+ if (ex == Qfalse) return sym_wait_readable;
+ rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE,
+ e, "read would block");
+ }
+ rb_syserr_fail_path(e, fptr->pathv);
+ }
+ }
+ if (n != RSTRING_LEN(str)) {
+ rb_str_modify(str);
+ rb_str_set_len(str, n);
+ }
+ if (n == 0) {
+ if (ex == Qfalse) return Qnil;
+ rb_eof_error();
+ }
+
+ return str;
}
-#ifdef SOCK_CLOEXEC
-static int
-rsock_socket0(int domain, int type, int proto)
+/* :nodoc: */
+VALUE
+rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex)
{
- int ret;
- static int cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
-
- if (cloexec_state > 0) { /* common path, if SOCK_CLOEXEC is defined */
- ret = socket(domain, type|SOCK_CLOEXEC, proto);
- if (ret >= 0) {
- if (ret <= 2)
- goto fix_cloexec;
- goto update_max_fd;
- }
- }
- else if (cloexec_state < 0) { /* usually runs once only for detection */
- ret = socket(domain, type|SOCK_CLOEXEC, proto);
- if (ret >= 0) {
- cloexec_state = rsock_detect_cloexec(ret);
- if (cloexec_state == 0 || ret <= 2)
- goto fix_cloexec;
- goto update_max_fd;
- }
- else if (ret == -1 && errno == EINVAL) {
- /* SOCK_CLOEXEC is available since Linux 2.6.27. Linux 2.6.18 fails with EINVAL */
- ret = socket(domain, type, proto);
- if (ret != -1) {
- cloexec_state = 0;
- /* fall through to fix_cloexec */
- }
- }
+ rb_io_t *fptr;
+ long n;
+
+ if (!RB_TYPE_P(str, T_STRING))
+ str = rb_obj_as_string(str);
+
+ sock = rb_io_get_write_io(sock);
+ GetOpenFile(sock, fptr);
+ rb_io_check_writable(fptr);
+
+ /*
+ * As with IO#write_nonblock, we may block if somebody is relying on
+ * buffered I/O; but nobody actually hits this because pipes and sockets
+ * are not userspace-buffered in Ruby by default.
+ */
+ if (fptr->wbuf.len > 0) {
+ rb_io_flush(sock);
}
- else { /* cloexec_state == 0 */
- ret = socket(domain, type, proto);
+
+#ifdef __APPLE__
+ again:
+#endif
+ n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT);
+ if (n < 0) {
+ int e = errno;
+
+#ifdef __APPLE__
+ if (e == EPROTOTYPE) {
+ goto again;
+ }
+#endif
+ if (e == EWOULDBLOCK || e == EAGAIN) {
+ if (ex == Qfalse) return sym_wait_writable;
+ rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e,
+ "write would block");
+ }
+ rb_syserr_fail_path(e, fptr->pathv);
}
- if (ret == -1)
- return -1;
-fix_cloexec:
- rb_maygvl_fd_fix_cloexec(ret);
-update_max_fd:
- rb_update_max_fd(ret);
- return ret;
+ return LONG2FIX(n);
}
-#else /* !SOCK_CLOEXEC */
+#endif /* MSG_DONTWAIT_RELIABLE */
+
static int
rsock_socket0(int domain, int type, int proto)
{
- int ret = socket(domain, type, proto);
+#ifdef SOCK_CLOEXEC
+ type |= SOCK_CLOEXEC;
+#endif
+
+#ifdef SOCK_NONBLOCK
+ type |= SOCK_NONBLOCK;
+#endif
- if (ret == -1)
+ int result = socket(domain, type, proto);
+
+ if (result == -1)
return -1;
- rb_fd_fix_cloexec(ret);
- return ret;
+ rb_fd_fix_cloexec(result);
+
+#ifndef SOCK_NONBLOCK
+ rsock_make_fd_nonblock(result);
+#endif
+
+ return result;
}
-#endif /* !SOCK_CLOEXEC */
int
rsock_socket(int domain, int type, int proto)
@@ -371,16 +451,35 @@ rsock_socket(int domain, int type, int proto)
/* emulate blocking connect behavior on EINTR or non-blocking socket */
static int
-wait_connectable(int fd)
+wait_connectable(int fd, struct timeval *timeout)
{
int sockerr, revents;
socklen_t sockerrlen;
- /* only to clear pending error */
sockerrlen = (socklen_t)sizeof(sockerr);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen) < 0)
return -1;
+ /* necessary for non-blocking sockets (at least ECONNREFUSED) */
+ switch (sockerr) {
+ case 0:
+ break;
+#ifdef EALREADY
+ case EALREADY:
+#endif
+#ifdef EISCONN
+ case EISCONN:
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED:
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH:
+#endif
+ errno = sockerr;
+ return -1;
+ }
+
/*
* Stevens book says, successful finish turn on RB_WAITFD_OUT and
* failure finish turn on both RB_WAITFD_IN and RB_WAITFD_OUT.
@@ -389,7 +488,7 @@ wait_connectable(int fd)
*
* Note: rb_wait_for_single_fd already retries on EINTR/ERESTART
*/
- revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, NULL);
+ revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, timeout);
if (revents < 0)
return -1;
@@ -404,6 +503,12 @@ wait_connectable(int fd)
* be defensive in case some platforms set SO_ERROR on the original,
* interrupted connect()
*/
+
+ /* when the connection timed out, no errno is set and revents is 0. */
+ if (timeout && revents == 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
case EINTR:
#ifdef ERESTART
case ERESTART:
@@ -451,7 +556,7 @@ socks_connect_blocking(void *data)
#endif
int
-rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
+rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout)
{
int status;
rb_blocking_function_t *func = connect_blocking;
@@ -475,15 +580,19 @@ rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
#ifdef EINPROGRESS
case EINPROGRESS:
#endif
- return wait_connectable(fd);
+ return wait_connectable(fd, timeout);
}
}
return status;
}
-static void
-make_fd_nonblock(int fd)
+void
+rsock_make_fd_nonblock(int fd)
{
+#ifdef _WIN32
+ return;
+#endif
+
int flags;
#ifdef F_GETFL
flags = fcntl(fd, F_GETFL);
@@ -500,53 +609,34 @@ make_fd_nonblock(int fd)
}
static int
-cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len,
- int nonblock)
+cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)
{
- int ret;
socklen_t len0 = 0;
-#ifdef HAVE_ACCEPT4
- static int try_accept4 = 1;
-#endif
if (address_len) len0 = *address_len;
+
#ifdef HAVE_ACCEPT4
- if (try_accept4) {
- int flags = 0;
-#ifdef SOCK_CLOEXEC
- flags |= SOCK_CLOEXEC;
-#endif
+ int flags = SOCK_CLOEXEC;
+
#ifdef SOCK_NONBLOCK
- if (nonblock) {
- flags |= SOCK_NONBLOCK;
- }
+ flags |= SOCK_NONBLOCK;
#endif
- ret = accept4(socket, address, address_len, flags);
- /* accept4 is available since Linux 2.6.28, glibc 2.10. */
- if (ret != -1) {
- if (ret <= 2)
- rb_maygvl_fd_fix_cloexec(ret);
+
+ int result = accept4(socket, address, address_len, flags);
+ if (result == -1) return -1;
+
#ifndef SOCK_NONBLOCK
- if (nonblock) {
- make_fd_nonblock(ret);
- }
+ rsock_make_fd_nonblock(result);
#endif
- if (address_len && len0 < *address_len) *address_len = len0;
- return ret;
- }
- if (errno != ENOSYS) {
- return -1;
- }
- try_accept4 = 0;
- }
+#else
+ int result = accept(socket, address, address_len);
+ if (result == -1) return -1;
+
+ rb_maygvl_fd_fix_cloexec(result);
+ rsock_make_fd_nonblock(result);
#endif
- ret = accept(socket, address, address_len);
- if (ret == -1) return -1;
+
if (address_len && len0 < *address_len) *address_len = len0;
- rb_maygvl_fd_fix_cloexec(ret);
- if (nonblock) {
- make_fd_nonblock(ret);
- }
- return ret;
+ return result;
}
VALUE
@@ -556,7 +646,7 @@ rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr,
int fd2;
rb_io_set_nonblock(fptr);
- fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len, 1);
+ fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len);
if (fd2 < 0) {
int e = errno;
switch (e) {
@@ -588,7 +678,7 @@ static VALUE
accept_blocking(void *data)
{
struct accept_arg *arg = data;
- return (VALUE)cloexec_accept(arg->fd, arg->sockaddr, arg->len, 0);
+ return (VALUE)cloexec_accept(arg->fd, arg->sockaddr, arg->len);
}
VALUE
@@ -680,4 +770,8 @@ rsock_init_socket_init(void)
#undef rb_intern
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
+
+#if MSG_DONTWAIT_RELIABLE
+ sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
+#endif
}
diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c
index dadf10f6a5..72fea789a5 100644
--- a/ext/socket/ipsocket.c
+++ b/ext/socket/ipsocket.c
@@ -19,11 +19,14 @@ struct inetsock_arg
} remote, local;
int type;
int fd;
+ VALUE resolv_timeout;
+ VALUE connect_timeout;
};
static VALUE
-inetsock_cleanup(struct inetsock_arg *arg)
+inetsock_cleanup(VALUE v)
{
+ struct inetsock_arg *arg = (void *)v;
if (arg->remote.res) {
rb_freeaddrinfo(arg->remote.res);
arg->remote.res = 0;
@@ -39,18 +42,29 @@ inetsock_cleanup(struct inetsock_arg *arg)
}
static VALUE
-init_inetsock_internal(struct inetsock_arg *arg)
+init_inetsock_internal(VALUE v)
{
+ struct inetsock_arg *arg = (void *)v;
int error = 0;
int type = arg->type;
struct addrinfo *res, *lres;
int fd, status = 0, local = 0;
int family = AF_UNSPEC;
const char *syscall = 0;
+ VALUE connect_timeout = arg->connect_timeout;
+ struct timeval tv_storage;
+ struct timeval *tv = NULL;
+
+ if (!NIL_P(connect_timeout)) {
+ tv_storage = rb_time_interval(connect_timeout);
+ tv = &tv_storage;
+ }
arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv,
family, SOCK_STREAM,
(type == INET_SERVER) ? AI_PASSIVE : 0);
+
+
/*
* Maybe also accept a local address
*/
@@ -99,6 +113,11 @@ init_inetsock_internal(struct inetsock_arg *arg)
}
else {
if (lres) {
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+ status = 1;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+ (char*)&status, (socklen_t)sizeof(status));
+#endif
status = bind(fd, lres->ai_addr, lres->ai_addrlen);
local = status;
syscall = "bind(2)";
@@ -106,7 +125,7 @@ init_inetsock_internal(struct inetsock_arg *arg)
if (status >= 0) {
status = rsock_connect(fd, res->ai_addr, res->ai_addrlen,
- (type == INET_SOCKS));
+ (type == INET_SOCKS), tv);
syscall = "connect(2)";
}
}
@@ -150,7 +169,8 @@ init_inetsock_internal(struct inetsock_arg *arg)
VALUE
rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv,
- VALUE local_host, VALUE local_serv, int type)
+ VALUE local_host, VALUE local_serv, int type,
+ VALUE resolv_timeout, VALUE connect_timeout)
{
struct inetsock_arg arg;
arg.sock = sock;
@@ -162,6 +182,8 @@ rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv,
arg.local.res = 0;
arg.type = type;
arg.fd = -1;
+ arg.resolv_timeout = resolv_timeout;
+ arg.connect_timeout = connect_timeout;
return rb_ensure(init_inetsock_internal, (VALUE)&arg,
inetsock_cleanup, (VALUE)&arg);
}
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb
index 8127009fff..d756a32a5a 100644
--- a/ext/socket/lib/socket.rb
+++ b/ext/socket/lib/socket.rb
@@ -77,7 +77,7 @@ class Addrinfo
sock
end
end
- private :connect_internal
+ protected :connect_internal
# :call-seq:
# addrinfo.connect_from([local_addr_args], [opts]) {|socket| ... }
@@ -158,7 +158,7 @@ class Addrinfo
#
def connect_to(*args, timeout: nil, &block)
remote_addrinfo = family_addrinfo(*args)
- remote_addrinfo.send(:connect_internal, self, timeout, &block)
+ remote_addrinfo.connect_internal(self, timeout, &block)
end
# creates a socket bound to self.
@@ -223,8 +223,8 @@ class Addrinfo
# # #<Addrinfo: [::1]:80 TCP (:80)>
# # #<Addrinfo: [::1]:80 UDP (:80)>
#
- def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, &block)
- Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags).each(&block)
+ def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block)
+ Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags, timeout: timeout).each(&block)
end
end
@@ -336,6 +336,7 @@ class BasicSocket < IO
# === Parameters
# * +maxlen+ - the number of bytes to receive from the socket
# * +flags+ - zero or more of the +MSG_+ options
+ # * +buf+ - destination String buffer
# * +options+ - keyword hash, supporting `exception: false`
#
# === Example
@@ -445,19 +446,14 @@ class BasicSocket < IO
# Linux-specific optimizations to avoid fcntl for IO#read_nonblock
# and IO#write_nonblock using MSG_DONTWAIT
- # Do other platforms suport MSG_DONTWAIT reliably?
+ # Do other platforms support MSG_DONTWAIT reliably?
if RUBY_PLATFORM =~ /linux/ && Socket.const_defined?(:MSG_DONTWAIT)
def read_nonblock(len, str = nil, exception: true) # :nodoc:
- case rv = __recv_nonblock(len, 0, str, exception)
- when '' # recv_nonblock returns empty string on EOF
- exception ? raise(EOFError, 'end of file reached') : nil
- else
- rv
- end
+ __read_nonblock(len, str, exception)
end
def write_nonblock(buf, exception: true) # :nodoc:
- __sendmsg_nonblock(buf, 0, nil, nil, exception)
+ __write_nonblock(buf, exception)
end
end
end
@@ -610,6 +606,7 @@ class Socket < BasicSocket
# _opts_ may have following options:
#
# [:connect_timeout] specify the timeout in seconds.
+ # [:resolv_timeout] specify the name resolution timeout in seconds.
#
# If a block is given, the block is called with the socket.
# The value of the block is returned.
@@ -623,7 +620,7 @@ class Socket < BasicSocket
# puts sock.read
# }
#
- def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil) # :yield: socket
+ def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil) # :yield: socket
last_error = nil
ret = nil
@@ -632,7 +629,7 @@ class Socket < BasicSocket
local_addr_list = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, nil)
end
- Addrinfo.foreach(host, port, nil, :STREAM) {|ai|
+ Addrinfo.foreach(host, port, nil, :STREAM, timeout: resolv_timeout) {|ai|
if local_addr_list
local_addr = local_addr_list.find {|local_ai| local_ai.afamily == ai.afamily }
next unless local_addr
diff --git a/ext/socket/mkconstants.rb b/ext/socket/mkconstants.rb
index 0ebf628b46..620a5f60ff 100644
--- a/ext/socket/mkconstants.rb
+++ b/ext/socket/mkconstants.rb
@@ -73,7 +73,15 @@ def each_name(pat)
}
end
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
+erb_new = lambda do |src, safe, trim|
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
+ ERB.new(src, trim_mode: trim)
+ else
+ ERB.new(src, safe, trim)
+ end
+end
+
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
% each_const {|guard, name, default_value|
#if !defined(<%=name%>)
# if defined(HAVE_CONST_<%=name.upcase%>)
@@ -87,7 +95,7 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
% }
EOS
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name, default_value)")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name, default_value)")
#if defined(<%=name%>)
/* <%= COMMENTS[name] %> */
rb_define_const(rb_cSocket, <%=c_str name%>, INTEGER2NUM(<%=name%>));
@@ -96,7 +104,7 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name, def
#endif
EOS
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
% each_const {|guard, name, default_value|
% if guard
#if <%=guard%>
@@ -146,7 +154,7 @@ def each_names_with_len(pat, prefix_optional=nil)
}
end
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)")
%if guard
#ifdef <%=guard%>
int <%=funcname%>(const char *str, long len, int *valp);
@@ -156,7 +164,7 @@ int <%=funcname%>(const char *str, long len, int *valp);
%end
EOS
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)")
int
<%=funcname%>(const char *str, long len, int *valp)
{
@@ -172,12 +180,13 @@ int
% }
default:
+ if (!str || !valp) {/* wrong argument */}
return -1;
}
}
EOS
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)")
%if guard
#ifdef <%=guard%>
<%=gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard)%>
@@ -206,7 +215,7 @@ def reverse_each_name_with_prefix_optional(pat, prefix_pat)
end
end
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)")
<%=hash_var%> = st_init_numtable();
% reverse_each_name_with_prefix_optional(pat, prefix_pat) {|n,s|
#ifdef <%=n%>
@@ -215,7 +224,7 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pa
% }
EOS
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)")
ID
<%=func_name%>(int val)
{
@@ -226,7 +235,7 @@ ID
}
EOS
-ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)")
+erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)")
ID <%=func_name%>(int val);
EOS
@@ -275,7 +284,7 @@ def_intern('rsock_intern_udp_optname', /\AUDP_/, "UDP_")
def_intern('rsock_intern_scm_optname', /\ASCM_/, "SCM_")
def_intern('rsock_intern_local_optname', /\ALOCAL_/, "LOCAL_")
-result = ERB.new(<<'EOS', nil, '%').result(binding)
+result = erb_new.call(<<'EOS', nil, '%').result(binding)
/* autogenerated file */
<%= INTERN_DEFS.map {|vardef, gen_hash, decl, func| vardef }.join("\n") %>
@@ -318,7 +327,7 @@ init_constants(void)
EOS
-header_result = ERB.new(<<'EOS', nil, '%').result(binding)
+header_result = erb_new.call(<<'EOS', nil, '%').result(binding)
/* autogenerated file */
<%= gen_const_decls %>
<%= NAME_TO_INT_DEFS.map {|decl, func| decl }.join("\n") %>
diff --git a/ext/socket/option.c b/ext/socket/option.c
index bf3af171a2..4b33b3f1d3 100644
--- a/ext/socket/option.c
+++ b/ext/socket/option.c
@@ -106,9 +106,9 @@ sockopt_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE voptname, VALU
VALUE
rsock_sockopt_new(int family, int level, int optname, VALUE data)
{
- NEWOBJ_OF(obj, struct RObject, rb_cSockOpt, T_OBJECT);
+ VALUE obj = rb_obj_alloc(rb_cSockOpt);
StringValue(data);
- sockopt_initialize((VALUE)obj, INT2NUM(family), INT2NUM(level), INT2NUM(optname), data);
+ sockopt_initialize(obj, INT2NUM(family), INT2NUM(level), INT2NUM(optname), data);
return (VALUE)obj;
}
@@ -424,7 +424,7 @@ sockopt_ipv4_multicast_loop(VALUE self)
}
#endif
rb_raise(rb_eTypeError, "ipv4_multicast_loop socket option expected");
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
#define inspect_ipv4_multicast_loop(a,b,c,d) \
@@ -475,7 +475,7 @@ sockopt_ipv4_multicast_ttl(VALUE self)
}
#endif
rb_raise(rb_eTypeError, "ipv4_multicast_ttl socket option expected");
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
#define inspect_ipv4_multicast_ttl(a,b,c,d) \
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index dcabb2022e..d99edfe057 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -145,15 +145,6 @@ ruby_getaddrinfo__darwin(const char *nodename, const char *servname,
#define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__darwin((node),(serv),(hints),(res))
#endif
-#ifndef GETADDRINFO_EMU
-struct getaddrinfo_arg
-{
- const char *node;
- const char *service;
- const struct addrinfo *hints;
- struct addrinfo **res;
-};
-
#ifdef HAVE_INET_PTON
static int
parse_numeric_port(const char *service, int *portp)
@@ -182,6 +173,15 @@ parse_numeric_port(const char *service, int *portp)
}
#endif
+#ifndef GETADDRINFO_EMU
+struct getaddrinfo_arg
+{
+ const char *node;
+ const char *service;
+ const struct addrinfo *hints;
+ struct addrinfo **res;
+};
+
static void *
nogvl_getaddrinfo(void *arg)
{
@@ -417,22 +417,18 @@ str_is_number(const char *p)
char *ep;
if (!p || *p == '\0')
- return 0;
+ return 0;
ep = NULL;
(void)STRTOUL(p, &ep, 10);
if (ep && *ep == '\0')
- return 1;
+ return 1;
else
- return 0;
+ return 0;
}
#define str_equal(ptr, len, name) \
((ptr)[0] == name[0] && \
rb_strlen_lit(name) == (len) && memcmp(ptr, name, len) == 0)
-#define SafeStringValueCStr(v) do {\
- StringValueCStr(v);\
- rb_check_safe_obj(v);\
-} while(0)
static char*
host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr)
@@ -451,7 +447,7 @@ host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr)
const char *name;
size_t len;
- SafeStringValueCStr(host);
+ StringValueCStr(host);
RSTRING_GETMEM(host, name, len);
if (!len || str_equal(name, len, "<any>")) {
make_inetaddr(INADDR_ANY, hbuf, hbuflen);
@@ -490,7 +486,7 @@ port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr)
const char *serv;
size_t len;
- SafeStringValueCStr(port);
+ StringValueCStr(port);
RSTRING_GETMEM(port, serv, len);
if (len >= pbuflen) {
rb_raise(rb_eArgError, "service name too long (%"PRIuSIZE")",
@@ -515,7 +511,7 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h
portp = port_str(port, pbuf, sizeof(pbuf), &additional_flags);
if (socktype_hack && hints->ai_socktype == 0 && str_is_number(portp)) {
- hints->ai_socktype = SOCK_DGRAM;
+ hints->ai_socktype = SOCK_DGRAM;
}
hints->ai_flags |= additional_flags;
@@ -597,16 +593,21 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup)
}
#ifdef HAVE_SYS_UN_H
-VALUE
-rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len)
+static long
+unixsocket_len(const struct sockaddr_un *su, socklen_t socklen)
{
- char *s, *e;
- s = sockaddr->sun_path;
- e = (char *)sockaddr + len;
+ const char *s = su->sun_path, *e = (const char*)su + socklen;
while (s < e && *(e-1) == '\0')
e--;
- if (s <= e)
- return rb_str_new(s, e-s);
+ return e - s;
+}
+
+VALUE
+rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len)
+{
+ long n = unixsocket_len(sockaddr, len);
+ if (n >= 0)
+ return rb_str_new(sockaddr->sun_path, n);
else
return rb_str_new2("");
}
@@ -649,8 +650,9 @@ struct hostent_arg {
};
static VALUE
-make_hostent_internal(struct hostent_arg *arg)
+make_hostent_internal(VALUE v)
{
+ struct hostent_arg *arg = (void *)v;
VALUE host = arg->host;
struct addrinfo* addr = arg->addr->ai;
VALUE (*ipaddr)(struct sockaddr*, socklen_t) = arg->ipaddr;
@@ -811,7 +813,7 @@ rsock_addrinfo_new(struct sockaddr *addr, socklen_t len,
static struct rb_addrinfo *
call_getaddrinfo(VALUE node, VALUE service,
VALUE family, VALUE socktype, VALUE protocol, VALUE flags,
- int socktype_hack)
+ int socktype_hack, VALUE timeout)
{
struct addrinfo hints;
struct rb_addrinfo *res;
@@ -828,6 +830,7 @@ call_getaddrinfo(VALUE node, VALUE service,
if (!NIL_P(flags)) {
hints.ai_flags = NUM2INT(flags);
}
+
res = rsock_getaddrinfo(node, service, &hints, socktype_hack);
if (res == NULL)
@@ -842,13 +845,13 @@ init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service,
VALUE family, VALUE socktype, VALUE protocol, VALUE flags,
VALUE inspectnode, VALUE inspectservice)
{
- struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 1);
+ struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 1, Qnil);
VALUE canonname;
VALUE inspectname = rb_str_equal(node, inspectnode) ? Qnil : make_inspectname(inspectnode, inspectservice, res->ai);
canonname = Qnil;
if (res->ai->ai_canonname) {
- canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname);
+ canonname = rb_str_new_cstr(res->ai->ai_canonname);
OBJ_FREEZE(canonname);
}
@@ -898,8 +901,6 @@ make_inspectname(VALUE node, VALUE service, struct addrinfo *res)
rb_str_catf(inspectname, ":%d", FIX2INT(service));
}
if (!NIL_P(inspectname)) {
- OBJ_INFECT(inspectname, node);
- OBJ_INFECT(inspectname, service);
OBJ_FREEZE(inspectname);
}
return inspectname;
@@ -912,13 +913,13 @@ addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype,
VALUE canonname;
VALUE inspectname;
- struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0);
+ struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0, Qnil);
inspectname = make_inspectname(node, service, res->ai);
canonname = Qnil;
if (res->ai->ai_canonname) {
- canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname);
+ canonname = rb_str_new_cstr(res->ai->ai_canonname);
OBJ_FREEZE(canonname);
}
@@ -932,13 +933,13 @@ addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype,
}
static VALUE
-addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags)
+addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, VALUE timeout)
{
VALUE ret;
struct addrinfo *r;
VALUE inspectname;
- struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0);
+ struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0, timeout);
inspectname = make_inspectname(node, service, res->ai);
@@ -948,7 +949,7 @@ addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE
VALUE canonname = Qnil;
if (r->ai_canonname) {
- canonname = rb_tainted_str_new_cstr(r->ai_canonname);
+ canonname = rb_str_new_cstr(r->ai_canonname);
OBJ_FREEZE(canonname);
}
@@ -985,6 +986,12 @@ init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype)
init_addrinfo(rai, (struct sockaddr *)&un, len,
PF_UNIX, socktype, 0, Qnil, Qnil);
}
+
+static long
+rai_unixsocket_len(const rb_addrinfo_t *rai)
+{
+ return unixsocket_len(&rai->addr.un, rai->sockaddr_len);
+}
#endif
/*
@@ -1114,16 +1121,16 @@ addrinfo_initialize(int argc, VALUE *argv, VALUE self)
}
static int
-get_afamily(struct sockaddr *addr, socklen_t len)
+get_afamily(const struct sockaddr *addr, socklen_t len)
{
- if ((socklen_t)((char*)&addr->sa_family + sizeof(addr->sa_family) - (char*)addr) <= len)
+ if ((socklen_t)((const char*)&addr->sa_family + sizeof(addr->sa_family) - (char*)addr) <= len)
return addr->sa_family;
else
return AF_UNSPEC;
}
static int
-ai_get_afamily(rb_addrinfo_t *rai)
+ai_get_afamily(const rb_addrinfo_t *rai)
{
return get_afamily(&rai->addr.addr, rai->sockaddr_len);
}
@@ -1232,16 +1239,15 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r
{
struct sockaddr_un *addr = &sockaddr->un;
char *p, *s, *e;
+ long len = unixsocket_len(addr, socklen);
s = addr->sun_path;
- e = (char*)addr + socklen;
- while (s < e && *(e-1) == '\0')
- e--;
- if (e < s)
+ if (len < 0)
rb_str_cat2(ret, "too-short-AF_UNIX-sockaddr");
- else if (s == e)
+ else if (len == 0)
rb_str_cat2(ret, "empty-path-AF_UNIX-sockaddr");
else {
int printable_only = 1;
+ e = s + len;
p = s;
while (p < e) {
printable_only = printable_only && ISPRINT(*p) && !ISSPACE(*p);
@@ -1567,13 +1573,7 @@ addrinfo_mdump(VALUE self)
#ifdef HAVE_SYS_UN_H
case AF_UNIX:
{
- struct sockaddr_un *su = &rai->addr.un;
- char *s, *e;
- s = su->sun_path;
- e = (char*)su + rai->sockaddr_len;
- while (s < e && *(e-1) == '\0')
- e--;
- sockaddr = rb_str_new(s, e-s);
+ sockaddr = rb_str_new(rai->addr.un.sun_path, rai_unixsocket_len(rai));
break;
}
#endif
@@ -1691,7 +1691,7 @@ addrinfo_mload(VALUE self, VALUE ary)
#endif
res = call_getaddrinfo(rb_ary_entry(pair, 0), rb_ary_entry(pair, 1),
INT2NUM(pfamily), INT2NUM(socktype), INT2NUM(protocol),
- INT2NUM(flags), 1);
+ INT2NUM(flags), 1, Qnil);
len = res->ai->ai_addrlen;
memcpy(&ss, res->ai->ai_addr, res->ai->ai_addrlen);
@@ -1788,7 +1788,6 @@ addrinfo_to_sockaddr(VALUE self)
rb_addrinfo_t *rai = get_addrinfo(self);
VALUE ret;
ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len);
- OBJ_INFECT(ret, self);
return ret;
}
@@ -1796,7 +1795,7 @@ addrinfo_to_sockaddr(VALUE self)
* call-seq:
* addrinfo.canonname => string or nil
*
- * returns the canonical name as an string.
+ * returns the canonical name as a string.
*
* nil is returned if no canonical name.
*
@@ -2307,28 +2306,27 @@ addrinfo_unix_path(VALUE self)
rb_addrinfo_t *rai = get_addrinfo(self);
int family = ai_get_afamily(rai);
struct sockaddr_un *addr;
- char *s, *e;
+ long n;
if (family != AF_UNIX)
rb_raise(rb_eSocket, "need AF_UNIX address");
addr = &rai->addr.un;
- s = addr->sun_path;
- e = (char*)addr + rai->sockaddr_len;
- if (e < s)
+ n = rai_unixsocket_len(rai);
+ if (n < 0)
rb_raise(rb_eSocket, "too short AF_UNIX address: %"PRIuSIZE" bytes given for minimum %"PRIuSIZE" bytes.",
- (size_t)rai->sockaddr_len, (size_t)(s - (char *)addr));
- if (addr->sun_path + sizeof(addr->sun_path) < e)
+ (size_t)rai->sockaddr_len, offsetof(struct sockaddr_un, sun_path));
+ if ((long)sizeof(addr->sun_path) < n)
rb_raise(rb_eSocket,
"too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
- (size_t)(e - addr->sun_path), sizeof(addr->sun_path));
- while (s < e && *(e-1) == '\0')
- e--;
- return rb_str_new(s, e-s);
+ (size_t)n, sizeof(addr->sun_path));
+ return rb_str_new(addr->sun_path, n);
}
#endif
+static ID id_timeout;
+
/*
* call-seq:
* Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags) => [addrinfo, ...]
@@ -2375,10 +2373,16 @@ addrinfo_unix_path(VALUE self)
static VALUE
addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self)
{
- VALUE node, service, family, socktype, protocol, flags;
+ VALUE node, service, family, socktype, protocol, flags, opts, timeout;
+
+ rb_scan_args(argc, argv, "24:", &node, &service, &family, &socktype,
+ &protocol, &flags, &opts);
+ rb_get_kwargs(opts, &id_timeout, 0, 1, &timeout);
+ if (timeout == Qundef) {
+ timeout = Qnil;
+ }
- rb_scan_args(argc, argv, "24", &node, &service, &family, &socktype, &protocol, &flags);
- return addrinfo_list_new(node, service, family, socktype, protocol, flags);
+ return addrinfo_list_new(node, service, family, socktype, protocol, flags, timeout);
}
/*
@@ -2466,7 +2470,6 @@ addrinfo_s_unix(int argc, VALUE *argv, VALUE self)
addr = addrinfo_s_allocate(rb_cAddrinfo);
DATA_PTR(addr) = rai = alloc_addrinfo();
init_unix_addrinfo(rai, path, socktype);
- OBJ_INFECT(addr, path);
return addr;
}
@@ -2550,7 +2553,7 @@ rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
rb_raise(rb_eTypeError, "neither IO nor file descriptor");
}
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
/*
@@ -2563,7 +2566,9 @@ rsock_init_addrinfo(void)
* The Addrinfo class maps <tt>struct addrinfo</tt> to ruby. This
* structure identifies an Internet host and a service.
*/
- rb_cAddrinfo = rb_define_class("Addrinfo", rb_cData);
+ id_timeout = rb_intern("timeout");
+
+ rb_cAddrinfo = rb_define_class("Addrinfo", rb_cObject);
rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate);
rb_define_method(rb_cAddrinfo, "initialize", addrinfo_initialize, -1);
rb_define_method(rb_cAddrinfo, "inspect", addrinfo_inspect, 0);
diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h
index 352da8c56e..f0e4f3a4a0 100644
--- a/ext/socket/rubysocket.h
+++ b/ext/socket/rubysocket.h
@@ -1,12 +1,22 @@
#ifndef RUBY_SOCKET_H
#define RUBY_SOCKET_H 1
-#include "ruby/ruby.h"
-#include "ruby/io.h"
-#include "ruby/thread.h"
-#include "ruby/util.h"
-#include "internal.h"
+#include "ruby/config.h"
+#include RUBY_EXTCONF_H
+
+#if defined(__sun) || defined(_AIX)
+/* (Recent?) Solaris' <nfs/nfs.h> have conflicting definition of T_DATA. Let
+ * us honour system definition by undefining ours.
+ *
+ * See also [ruby-core:4261]
+ */
+# include "ruby/ruby.h"
+# undef T_DATA
+#endif
+
+#include <errno.h>
#include <stdio.h>
+
#include <sys/types.h>
#include <sys/stat.h>
@@ -50,12 +60,11 @@
#ifdef HAVE_NETPACKET_PACKET_H
# include <netpacket/packet.h>
#endif
+
#ifdef HAVE_NET_ETHERNET_H
# include <net/ethernet.h>
#endif
-#include <errno.h>
-
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
@@ -81,12 +90,15 @@
# endif
# include <ifaddrs.h>
#endif
+
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
+
#ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
#endif
+
#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif
@@ -94,16 +106,40 @@
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
+
#ifdef HAVE_SYS_UCRED_H
# include <sys/ucred.h>
#endif
+
#ifdef HAVE_UCRED_H
# include <ucred.h>
#endif
+
#ifdef HAVE_NET_IF_DL_H
# include <net/if_dl.h>
#endif
+#ifdef SOCKS5
+# include <socks.h>
+#endif
+
+#ifndef HAVE_GETADDRINFO
+# include "addrinfo.h"
+#endif
+
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/error.h"
+#include "internal/gc.h"
+#include "internal/io.h"
+#include "internal/thread.h"
+#include "internal/vm.h"
+#include "ruby/io.h"
+#include "ruby/ruby.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+#include "sockport.h"
+
#ifndef HAVE_TYPE_SOCKLEN_T
typedef int socklen_t;
#endif
@@ -137,11 +173,6 @@ unsigned int if_nametoindex(const char *);
*/
#define pseudo_AF_FTIP pseudo_AF_RTIP
-#ifndef HAVE_GETADDRINFO
-# include "addrinfo.h"
-#endif
-
-#include "sockport.h"
#ifndef NI_MAXHOST
# define NI_MAXHOST 1025
@@ -223,7 +254,6 @@ typedef union {
#define INET_SOCKS 2
extern int rsock_do_not_reverse_lookup;
-extern int rsock_cmsg_cloexec_state;
#define FMODE_NOREVLOOKUP 0x100
/* common socket families only */
@@ -249,9 +279,7 @@ extern VALUE rb_eSocket;
#ifdef SOCKS
extern VALUE rb_cSOCKSSocket;
-# ifdef SOCKS5
-# include <socks.h>
-# else
+# ifndef SOCKS5
void SOCKSinit();
int Rconnect();
# endif
@@ -292,6 +320,7 @@ int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_
int rsock_fd_family(int fd);
struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags);
struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack);
+
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len);
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len);
@@ -317,7 +346,7 @@ int rsock_socket(int domain, int type, int proto);
int rsock_detect_cloexec(int fd);
VALUE rsock_init_sock(VALUE sock, int fd);
VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass);
-VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type);
+VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type, VALUE resolv_timeout, VALUE connect_timeout);
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server);
struct rsock_send_arg {
@@ -342,7 +371,7 @@ VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
VALUE ex, enum sock_recv_type from);
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from);
-int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks);
+int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout);
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr,
@@ -408,7 +437,7 @@ NORETURN(void rsock_sys_fail_raddrinfo_or_sockaddr(const char *, VALUE addr, VAL
* all cases. For some syscalls (e.g. accept/accept4), blocking on the
* syscall instead of relying on select/poll allows the kernel to use
* "wake-one" behavior and avoid the thundering herd problem.
- * This is likely safe on all other *nix-like systems, so this whitelist
+ * This is likely safe on all other *nix-like systems, so this safe list
* can be expanded by interested parties.
*/
#if defined(__linux__)
@@ -430,6 +459,11 @@ static inline void rsock_maybe_wait_fd(int fd) { }
# define MSG_DONTWAIT_RELIABLE 0
#endif
+VALUE rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex);
+VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex);
+
+void rsock_make_fd_nonblock(int fd);
+
#if !defined HAVE_INET_NTOP && ! defined _WIN32
const char *inet_ntop(int, const void *, char *, size_t);
#elif defined __MINGW32__
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 14e069bb8d..3d8c65032c 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -168,84 +168,47 @@ pair_yield(VALUE pair)
#endif
#if defined HAVE_SOCKETPAIR
-
-#ifdef SOCK_CLOEXEC
static int
-rsock_socketpair0(int domain, int type, int protocol, int sv[2])
+rsock_socketpair0(int domain, int type, int protocol, int descriptors[2])
{
- int ret;
- static int cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
+#ifdef SOCK_CLOEXEC
+ type |= SOCK_CLOEXEC;
+#endif
- if (cloexec_state > 0) { /* common path, if SOCK_CLOEXEC is defined */
- ret = socketpair(domain, type|SOCK_CLOEXEC, protocol, sv);
- if (ret == 0 && (sv[0] <= 2 || sv[1] <= 2)) {
- goto fix_cloexec; /* highly unlikely */
- }
- goto update_max_fd;
- }
- else if (cloexec_state < 0) { /* usually runs once only for detection */
- ret = socketpair(domain, type|SOCK_CLOEXEC, protocol, sv);
- if (ret == 0) {
- cloexec_state = rsock_detect_cloexec(sv[0]);
- if ((cloexec_state == 0) || (sv[0] <= 2 || sv[1] <= 2))
- goto fix_cloexec;
- goto update_max_fd;
- }
- else if (ret == -1 && errno == EINVAL) {
- /* SOCK_CLOEXEC is available since Linux 2.6.27. Linux 2.6.18 fails with EINVAL */
- ret = socketpair(domain, type, protocol, sv);
- if (ret != -1) {
- /* The reason of EINVAL may be other than SOCK_CLOEXEC.
- * So disable SOCK_CLOEXEC only if socketpair() succeeds without SOCK_CLOEXEC.
- * Ex. Socket.pair(:UNIX, 0xff) fails with EINVAL.
- */
- cloexec_state = 0;
- }
- }
- }
- else { /* cloexec_state == 0 */
- ret = socketpair(domain, type, protocol, sv);
- }
- if (ret == -1) {
- return -1;
- }
+#ifdef SOCK_NONBLOCK
+ type |= SOCK_NONBLOCK;
+#endif
-fix_cloexec:
- rb_maygvl_fd_fix_cloexec(sv[0]);
- rb_maygvl_fd_fix_cloexec(sv[1]);
+ int result = socketpair(domain, type, protocol, descriptors);
-update_max_fd:
- rb_update_max_fd(sv[0]);
- rb_update_max_fd(sv[1]);
+ if (result == -1)
+ return -1;
- return ret;
-}
-#else /* !SOCK_CLOEXEC */
-static int
-rsock_socketpair0(int domain, int type, int protocol, int sv[2])
-{
- int ret = socketpair(domain, type, protocol, sv);
+#ifndef SOCK_CLOEXEC
+ rb_fd_fix_cloexec(descriptors[0]);
+ rb_fd_fix_cloexec(descriptors[1]);
+#endif
- if (ret == -1)
- return -1;
+#ifndef SOCK_NONBLOCK
+ rsock_make_fd_nonblock(descriptors[0]);
+ rsock_make_fd_nonblock(descriptors[1]);
+#endif
- rb_fd_fix_cloexec(sv[0]);
- rb_fd_fix_cloexec(sv[1]);
- return ret;
+ return result;
}
-#endif /* !SOCK_CLOEXEC */
static int
-rsock_socketpair(int domain, int type, int protocol, int sv[2])
+rsock_socketpair(int domain, int type, int protocol, int descriptors[2])
{
- int ret;
+ int result;
+
+ result = rsock_socketpair0(domain, type, protocol, descriptors);
- ret = rsock_socketpair0(domain, type, protocol, sv);
- if (ret < 0 && rb_gc_for_fd(errno)) {
- ret = rsock_socketpair0(domain, type, protocol, sv);
+ if (result < 0 && rb_gc_for_fd(errno)) {
+ result = rsock_socketpair0(domain, type, protocol, descriptors);
}
- return ret;
+ return result;
}
/*
@@ -430,7 +393,7 @@ sock_connect(VALUE sock, VALUE addr)
addr = rb_str_new4(addr);
GetOpenFile(sock, fptr);
fd = fptr->fd;
- n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0);
+ n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, NULL);
if (n < 0) {
rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai);
}
@@ -983,7 +946,18 @@ sock_sockaddr(struct sockaddr *addr, socklen_t len)
* call-seq:
* Socket.gethostbyname(hostname) => [official_hostname, alias_hostnames, address_family, *address_list]
*
- * Obtains the host information for _hostname_.
+ * Use Addrinfo.getaddrinfo instead.
+ * This method is deprecated for the following reasons:
+ *
+ * - The 3rd element of the result is the address family of the first address.
+ * The address families of the rest of the addresses are not returned.
+ * - Uncommon address representation:
+ * 4/16-bytes binary string to represent IPv4/IPv6 address.
+ * - gethostbyname() may take a long time and it may block other threads.
+ * (GVL cannot be released since gethostbyname() is not thread safe.)
+ * - This method uses gethostbyname() function already removed from POSIX.
+ *
+ * This method obtains the host information for _hostname_.
*
* p Socket.gethostbyname("hal") #=> ["localhost", ["hal"], 2, "\x7F\x00\x00\x01"]
*
@@ -991,6 +965,7 @@ sock_sockaddr(struct sockaddr *addr, socklen_t len)
static VALUE
sock_s_gethostbyname(VALUE obj, VALUE host)
{
+ rb_warn("Socket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead.");
struct rb_addrinfo *res =
rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME);
return rsock_make_hostent(host, res, sock_sockaddr);
@@ -1000,13 +975,29 @@ sock_s_gethostbyname(VALUE obj, VALUE host)
* call-seq:
* Socket.gethostbyaddr(address_string [, address_family]) => hostent
*
- * Obtains the host information for _address_.
+ * Use Addrinfo#getnameinfo instead.
+ * This method is deprecated for the following reasons:
+ *
+ * - Uncommon address representation:
+ * 4/16-bytes binary string to represent IPv4/IPv6 address.
+ * - gethostbyaddr() may take a long time and it may block other threads.
+ * (GVL cannot be released since gethostbyname() is not thread safe.)
+ * - This method uses gethostbyname() function already removed from POSIX.
+ *
+ * This method obtains the host information for _address_.
*
* p Socket.gethostbyaddr([221,186,184,68].pack("CCCC"))
* #=> ["carbon.ruby-lang.org", [], 2, "\xDD\xBA\xB8D"]
+ *
+ * p Socket.gethostbyaddr([127,0,0,1].pack("CCCC"))
+ * ["localhost", [], 2, "\x7F\x00\x00\x01"]
+ * p Socket.gethostbyaddr(([0]*15+[1]).pack("C"*16))
+ * #=> ["localhost", ["ip6-localhost", "ip6-loopback"], 10,
+ * "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"]
+ *
*/
static VALUE
-sock_s_gethostbyaddr(int argc, VALUE *argv)
+sock_s_gethostbyaddr(int argc, VALUE *argv, VALUE _)
{
VALUE addr, family;
struct hostent *h;
@@ -1014,6 +1005,8 @@ sock_s_gethostbyaddr(int argc, VALUE *argv)
VALUE ary, names;
int t = AF_INET;
+ rb_warn("Socket.gethostbyaddr is deprecated; use Addrinfo#getnameinfo instead.");
+
rb_scan_args(argc, argv, "11", &addr, &family);
StringValue(addr);
if (!NIL_P(family)) {
@@ -1068,7 +1061,7 @@ sock_s_gethostbyaddr(int argc, VALUE *argv)
* Socket.getservbyname("syslog", "udp") #=> 514
*/
static VALUE
-sock_s_getservbyname(int argc, VALUE *argv)
+sock_s_getservbyname(int argc, VALUE *argv, VALUE _)
{
VALUE service, proto;
struct servent *sp;
@@ -1109,7 +1102,7 @@ sock_s_getservbyname(int argc, VALUE *argv)
*
*/
static VALUE
-sock_s_getservbyport(int argc, VALUE *argv)
+sock_s_getservbyport(int argc, VALUE *argv, VALUE _)
{
VALUE port, proto;
struct servent *sp;
@@ -1128,7 +1121,7 @@ sock_s_getservbyport(int argc, VALUE *argv)
if (!sp) {
rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname);
}
- return rb_tainted_str_new2(sp->s_name);
+ return rb_str_new2(sp->s_name);
}
/*
@@ -1137,6 +1130,9 @@ sock_s_getservbyport(int argc, VALUE *argv)
*
* Obtains address information for _nodename_:_servname_.
*
+ * Note that Addrinfo.getaddrinfo provides the same functionality in
+ * an object oriented style.
+ *
* _family_ should be an address family such as: :INET, :INET6, etc.
*
* _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
@@ -1164,7 +1160,7 @@ sock_s_getservbyport(int argc, VALUE *argv)
* If Addrinfo object is preferred, use Addrinfo.getaddrinfo.
*/
static VALUE
-sock_s_getaddrinfo(int argc, VALUE *argv)
+sock_s_getaddrinfo(int argc, VALUE *argv, VALUE _)
{
VALUE host, port, family, socktype, protocol, flags, ret, revlookup;
struct addrinfo hints;
@@ -1188,6 +1184,7 @@ sock_s_getaddrinfo(int argc, VALUE *argv)
if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) {
norevlookup = rsock_do_not_reverse_lookup;
}
+
res = rsock_getaddrinfo(host, port, &hints, 0);
ret = make_addrinfo(res, norevlookup);
@@ -1218,7 +1215,7 @@ sock_s_getaddrinfo(int argc, VALUE *argv)
* If Addrinfo object is preferred, use Addrinfo#getnameinfo.
*/
static VALUE
-sock_s_getnameinfo(int argc, VALUE *argv)
+sock_s_getnameinfo(int argc, VALUE *argv, VALUE _)
{
VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags, tmp;
char *hptr, *pptr;
@@ -1287,7 +1284,7 @@ sock_s_getnameinfo(int argc, VALUE *argv)
hptr = NULL;
}
else {
- strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
+ strncpy(hbuf, StringValueCStr(host), sizeof(hbuf));
hbuf[sizeof(hbuf) - 1] = '\0';
hptr = hbuf;
}
@@ -1301,7 +1298,7 @@ sock_s_getnameinfo(int argc, VALUE *argv)
pptr = pbuf;
}
else {
- strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
+ strncpy(pbuf, StringValueCStr(port), sizeof(pbuf));
pbuf[sizeof(pbuf) - 1] = '\0';
pptr = pbuf;
}
@@ -1351,7 +1348,7 @@ sock_s_getnameinfo(int argc, VALUE *argv)
errno = saved_errno;
rsock_raise_socket_error("getnameinfo", error);
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
/*
@@ -1375,8 +1372,6 @@ sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host)
VALUE addr = rb_str_new((char*)res->ai->ai_addr, res->ai->ai_addrlen);
rb_freeaddrinfo(res);
- OBJ_INFECT(addr, port);
- OBJ_INFECT(addr, host);
return addr;
}
@@ -1418,7 +1413,6 @@ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr)
#endif
}
host = rsock_make_ipaddr((struct sockaddr*)sockaddr, RSTRING_SOCKLEN(addr));
- OBJ_INFECT(host, addr);
return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host);
}
@@ -1448,7 +1442,6 @@ sock_s_pack_sockaddr_un(VALUE self, VALUE path)
}
memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
addr = rb_str_new((char*)&sockaddr, rsock_unix_sockaddr_len(path));
- OBJ_INFECT(addr, path);
return addr;
}
@@ -1485,7 +1478,6 @@ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr)
RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un));
}
path = rsock_unixpath_str(sockaddr, RSTRING_SOCKLEN(addr));
- OBJ_INFECT(path, addr);
return path;
}
#endif
@@ -1902,6 +1894,8 @@ socket_s_ip_address_list(VALUE self)
void
Init_socket(void)
{
+ rb_ext_ractor_safe(true);
+
rsock_init_basicsocket();
/*
diff --git a/ext/socket/sockssocket.c b/ext/socket/sockssocket.c
index 81f77a67c5..b8b7e12998 100644
--- a/ext/socket/sockssocket.c
+++ b/ext/socket/sockssocket.c
@@ -13,13 +13,19 @@
#ifdef SOCKS
/*
* call-seq:
- * SOCKSSocket.new(host, serv) => socket
+ * SOCKSSocket.new(host, port) => socket
*
- * Opens a SOCKS connection to +host+ via the SOCKS server +serv+.
+ * Opens a SOCKS connection to +host+ via the SOCKS server.
+ *
+ * The SOCKS server configuration varies by implementation
+ *
+ * When using the Dante libsocks/libsocksd implementation it is configured as SOCKS_SERVER env var.
+ *
+ * See: https://manpages.debian.org/testing/dante-client/socksify.1.en.html for full env variable support.
*
*/
static VALUE
-socks_init(VALUE sock, VALUE host, VALUE serv)
+socks_init(VALUE sock, VALUE host, VALUE port)
{
static int init = 0;
@@ -28,7 +34,7 @@ socks_init(VALUE sock, VALUE host, VALUE serv)
init = 1;
}
- return rsock_init_inetsock(sock, host, serv, Qnil, Qnil, INET_SOCKS);
+ return rsock_init_inetsock(sock, host, port, Qnil, Qnil, INET_SOCKS, Qnil, Qnil);
}
#ifdef SOCKS5
diff --git a/ext/socket/tcpserver.c b/ext/socket/tcpserver.c
index 1bbb31adcf..7634420e38 100644
--- a/ext/socket/tcpserver.c
+++ b/ext/socket/tcpserver.c
@@ -36,7 +36,7 @@ tcp_svr_init(int argc, VALUE *argv, VALUE sock)
VALUE hostname, port;
rb_scan_args(argc, argv, "011", &hostname, &port);
- return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER);
+ return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER, Qnil, Qnil);
}
/*
diff --git a/ext/socket/tcpsocket.c b/ext/socket/tcpsocket.c
index a7a82fd880..51e77a0de9 100644
--- a/ext/socket/tcpsocket.c
+++ b/ext/socket/tcpsocket.c
@@ -12,23 +12,42 @@
/*
* call-seq:
- * TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil)
+ * TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil, connect_timeout: nil)
*
* Opens a TCP connection to +remote_host+ on +remote_port+. If +local_host+
* and +local_port+ are specified, then those parameters are used on the local
* end to establish the connection.
+ *
+ * [:connect_timeout] specify the timeout in seconds.
*/
static VALUE
tcp_init(int argc, VALUE *argv, VALUE sock)
{
VALUE remote_host, remote_serv;
VALUE local_host, local_serv;
+ VALUE opt;
+ static ID keyword_ids[2];
+ VALUE kwargs[2];
+ VALUE resolv_timeout = Qnil;
+ VALUE connect_timeout = Qnil;
+
+ if (!keyword_ids[0]) {
+ CONST_ID(keyword_ids[0], "resolv_timeout");
+ CONST_ID(keyword_ids[1], "connect_timeout");
+ }
+
+ rb_scan_args(argc, argv, "22:", &remote_host, &remote_serv,
+ &local_host, &local_serv, &opt);
- rb_scan_args(argc, argv, "22", &remote_host, &remote_serv,
- &local_host, &local_serv);
+ if (!NIL_P(opt)) {
+ rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs);
+ if (kwargs[0] != Qundef) { resolv_timeout = kwargs[0]; }
+ if (kwargs[1] != Qundef) { connect_timeout = kwargs[1]; }
+ }
return rsock_init_inetsock(sock, remote_host, remote_serv,
- local_host, local_serv, INET_CLIENT);
+ local_host, local_serv, INET_CLIENT,
+ resolv_timeout, connect_timeout);
}
static VALUE
@@ -41,7 +60,16 @@ tcp_sockaddr(struct sockaddr *addr, socklen_t len)
* call-seq:
* TCPSocket.gethostbyname(hostname) => [official_hostname, alias_hostnames, address_family, *address_list]
*
- * Lookups host information by _hostname_.
+ * Use Addrinfo.getaddrinfo instead.
+ * This method is deprecated for the following reasons:
+ *
+ * - The 3rd element of the result is the address family of the first address.
+ * The address families of the rest of the addresses are not returned.
+ * - gethostbyname() may take a long time and it may block other threads.
+ * (GVL cannot be released since gethostbyname() is not thread safe.)
+ * - This method uses gethostbyname() function already removed from POSIX.
+ *
+ * This method lookups host information by _hostname_.
*
* TCPSocket.gethostbyname("localhost")
* #=> ["localhost", ["hal"], 2, "127.0.0.1"]
@@ -50,6 +78,7 @@ tcp_sockaddr(struct sockaddr *addr, socklen_t len)
static VALUE
tcp_s_gethostbyname(VALUE obj, VALUE host)
{
+ rb_warn("TCPSocket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead.");
struct rb_addrinfo *res =
rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME);
return rsock_make_hostent(host, res, tcp_sockaddr);
diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c
index c2e273c2a3..593f05522d 100644
--- a/ext/socket/udpsocket.c
+++ b/ext/socket/udpsocket.c
@@ -50,8 +50,9 @@ struct udp_arg
};
static VALUE
-udp_connect_internal(struct udp_arg *arg)
+udp_connect_internal(VALUE v)
{
+ struct udp_arg *arg = (void *)v;
rb_io_t *fptr;
int fd;
struct addrinfo *res;
@@ -59,7 +60,7 @@ udp_connect_internal(struct udp_arg *arg)
rb_io_check_closed(fptr = arg->fptr);
fd = fptr->fd;
for (res = arg->res->ai; res; res = res->ai_next) {
- if (rsock_connect(fd, res->ai_addr, res->ai_addrlen, 0) >= 0) {
+ if (rsock_connect(fd, res->ai_addr, res->ai_addrlen, 0, NULL) >= 0) {
return Qtrue;
}
}
@@ -97,8 +98,9 @@ udp_connect(VALUE sock, VALUE host, VALUE port)
}
static VALUE
-udp_bind_internal(struct udp_arg *arg)
+udp_bind_internal(VALUE v)
{
+ struct udp_arg *arg = (void *)v;
rb_io_t *fptr;
int fd;
struct addrinfo *res;
@@ -147,8 +149,9 @@ struct udp_send_arg {
};
static VALUE
-udp_send_internal(struct udp_send_arg *arg)
+udp_send_internal(VALUE v)
{
+ struct udp_send_arg *arg = (void *)v;
rb_io_t *fptr;
int n;
struct addrinfo *res;
diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c
index 5a44b552f8..857cfa6002 100644
--- a/ext/socket/unixsocket.c
+++ b/ext/socket/unixsocket.c
@@ -22,7 +22,28 @@ unixsock_connect_internal(VALUE a)
{
struct unixsock_arg *arg = (struct unixsock_arg *)a;
return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr,
- arg->sockaddrlen, 0);
+ arg->sockaddrlen, 0, NULL);
+}
+
+static VALUE
+unixsock_path_value(VALUE path)
+{
+#ifdef __linux__
+#define TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE 0
+
+ VALUE name = path;
+#if TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE
+ const int isstr = !NIL_P(name = rb_check_string_type(name));
+#else
+ const int isstr = RB_TYPE_P(name, T_STRING);
+#endif
+ if (isstr) {
+ if (RSTRING_LEN(name) == 0 || RSTRING_PTR(name)[0] == '\0') {
+ return name; /* ignore encoding */
+ }
+ }
+#endif
+ return rb_get_path(path);
}
VALUE
@@ -33,7 +54,7 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server)
int fd, status;
rb_io_t *fptr;
- SafeStringValue(path);
+ path = unixsock_path_value(path);
INIT_SOCKADDR_UN(&sockaddr, sizeof(struct sockaddr_un));
if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) {
@@ -317,6 +338,12 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
struct iomsg_arg arg;
struct iovec vec[2];
char buf[1];
+ unsigned int gc_reason = 0;
+ enum {
+ GC_REASON_EMSGSIZE = 0x1,
+ GC_REASON_TRUNCATE = 0x2,
+ GC_REASON_ENOMEM = 0x4
+ };
int fd;
#if FD_PASSING_BY_MSG_CONTROL
@@ -332,6 +359,7 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
if (argc <= 1)
mode = Qnil;
+retry:
GetOpenFile(sock, fptr);
arg.msg.msg_name = NULL;
@@ -359,12 +387,31 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
arg.fd = fptr->fd;
while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) {
+ int e = errno;
+ if (e == EMSGSIZE && !(gc_reason & GC_REASON_EMSGSIZE)) {
+ /* FreeBSD gets here when we're out of FDs */
+ gc_reason |= GC_REASON_EMSGSIZE;
+ rb_gc_for_fd(EMFILE);
+ goto retry;
+ }
+ else if (e == ENOMEM && !(gc_reason & GC_REASON_ENOMEM)) {
+ /* ENOMEM is documented in recvmsg manpages */
+ gc_reason |= GC_REASON_ENOMEM;
+ rb_gc_for_fd(e);
+ goto retry;
+ }
if (!rb_io_wait_readable(arg.fd))
- rsock_sys_fail_path("recvmsg(2)", fptr->pathv);
+ rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv);
}
#if FD_PASSING_BY_MSG_CONTROL
if (arg.msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr)) {
+ /* FreeBSD and Linux both get here when we're out of FDs */
+ if (!(gc_reason & GC_REASON_TRUNCATE)) {
+ gc_reason |= GC_REASON_TRUNCATE;
+ rb_gc_for_fd(EMFILE);
+ goto retry;
+ }
rb_raise(rb_eSocket,
"file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
(int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr));
@@ -408,11 +455,7 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
#endif
rb_update_max_fd(fd);
-
- if (rsock_cmsg_cloexec_state < 0)
- rsock_cmsg_cloexec_state = rsock_detect_cloexec(fd);
- if (rsock_cmsg_cloexec_state == 0 || fd <= 2)
- rb_maygvl_fd_fix_cloexec(fd);
+ rb_maygvl_fd_fix_cloexec(fd);
if (klass == Qnil)
return INT2FIX(fd);
diff --git a/ext/stringio/depend b/ext/stringio/depend
index 852146f503..5f4b0b53c0 100644
--- a/ext/stringio/depend
+++ b/ext/stringio/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
stringio.o: $(RUBY_EXTCONF_H)
stringio.o: $(arch_hdrdir)/ruby/config.h
+stringio.o: $(hdrdir)/ruby.h
+stringio.o: $(hdrdir)/ruby/internal/anyargs.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+stringio.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+stringio.o: $(hdrdir)/ruby/internal/assume.h
+stringio.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+stringio.o: $(hdrdir)/ruby/internal/attr/artificial.h
+stringio.o: $(hdrdir)/ruby/internal/attr/cold.h
+stringio.o: $(hdrdir)/ruby/internal/attr/const.h
+stringio.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+stringio.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+stringio.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+stringio.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+stringio.o: $(hdrdir)/ruby/internal/attr/error.h
+stringio.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+stringio.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+stringio.o: $(hdrdir)/ruby/internal/attr/format.h
+stringio.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+stringio.o: $(hdrdir)/ruby/internal/attr/noalias.h
+stringio.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+stringio.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+stringio.o: $(hdrdir)/ruby/internal/attr/noinline.h
+stringio.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+stringio.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+stringio.o: $(hdrdir)/ruby/internal/attr/pure.h
+stringio.o: $(hdrdir)/ruby/internal/attr/restrict.h
+stringio.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+stringio.o: $(hdrdir)/ruby/internal/attr/warning.h
+stringio.o: $(hdrdir)/ruby/internal/attr/weakref.h
+stringio.o: $(hdrdir)/ruby/internal/cast.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_is.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+stringio.o: $(hdrdir)/ruby/internal/compiler_since.h
+stringio.o: $(hdrdir)/ruby/internal/config.h
+stringio.o: $(hdrdir)/ruby/internal/constant_p.h
+stringio.o: $(hdrdir)/ruby/internal/core.h
+stringio.o: $(hdrdir)/ruby/internal/core/rarray.h
+stringio.o: $(hdrdir)/ruby/internal/core/rbasic.h
+stringio.o: $(hdrdir)/ruby/internal/core/rbignum.h
+stringio.o: $(hdrdir)/ruby/internal/core/rclass.h
+stringio.o: $(hdrdir)/ruby/internal/core/rdata.h
+stringio.o: $(hdrdir)/ruby/internal/core/rfile.h
+stringio.o: $(hdrdir)/ruby/internal/core/rhash.h
+stringio.o: $(hdrdir)/ruby/internal/core/robject.h
+stringio.o: $(hdrdir)/ruby/internal/core/rregexp.h
+stringio.o: $(hdrdir)/ruby/internal/core/rstring.h
+stringio.o: $(hdrdir)/ruby/internal/core/rstruct.h
+stringio.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+stringio.o: $(hdrdir)/ruby/internal/ctype.h
+stringio.o: $(hdrdir)/ruby/internal/dllexport.h
+stringio.o: $(hdrdir)/ruby/internal/dosish.h
+stringio.o: $(hdrdir)/ruby/internal/error.h
+stringio.o: $(hdrdir)/ruby/internal/eval.h
+stringio.o: $(hdrdir)/ruby/internal/event.h
+stringio.o: $(hdrdir)/ruby/internal/fl_type.h
+stringio.o: $(hdrdir)/ruby/internal/gc.h
+stringio.o: $(hdrdir)/ruby/internal/glob.h
+stringio.o: $(hdrdir)/ruby/internal/globals.h
+stringio.o: $(hdrdir)/ruby/internal/has/attribute.h
+stringio.o: $(hdrdir)/ruby/internal/has/builtin.h
+stringio.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+stringio.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+stringio.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+stringio.o: $(hdrdir)/ruby/internal/has/extension.h
+stringio.o: $(hdrdir)/ruby/internal/has/feature.h
+stringio.o: $(hdrdir)/ruby/internal/has/warning.h
+stringio.o: $(hdrdir)/ruby/internal/intern/array.h
+stringio.o: $(hdrdir)/ruby/internal/intern/bignum.h
+stringio.o: $(hdrdir)/ruby/internal/intern/class.h
+stringio.o: $(hdrdir)/ruby/internal/intern/compar.h
+stringio.o: $(hdrdir)/ruby/internal/intern/complex.h
+stringio.o: $(hdrdir)/ruby/internal/intern/cont.h
+stringio.o: $(hdrdir)/ruby/internal/intern/dir.h
+stringio.o: $(hdrdir)/ruby/internal/intern/enum.h
+stringio.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+stringio.o: $(hdrdir)/ruby/internal/intern/error.h
+stringio.o: $(hdrdir)/ruby/internal/intern/eval.h
+stringio.o: $(hdrdir)/ruby/internal/intern/file.h
+stringio.o: $(hdrdir)/ruby/internal/intern/gc.h
+stringio.o: $(hdrdir)/ruby/internal/intern/hash.h
+stringio.o: $(hdrdir)/ruby/internal/intern/io.h
+stringio.o: $(hdrdir)/ruby/internal/intern/load.h
+stringio.o: $(hdrdir)/ruby/internal/intern/marshal.h
+stringio.o: $(hdrdir)/ruby/internal/intern/numeric.h
+stringio.o: $(hdrdir)/ruby/internal/intern/object.h
+stringio.o: $(hdrdir)/ruby/internal/intern/parse.h
+stringio.o: $(hdrdir)/ruby/internal/intern/proc.h
+stringio.o: $(hdrdir)/ruby/internal/intern/process.h
+stringio.o: $(hdrdir)/ruby/internal/intern/random.h
+stringio.o: $(hdrdir)/ruby/internal/intern/range.h
+stringio.o: $(hdrdir)/ruby/internal/intern/rational.h
+stringio.o: $(hdrdir)/ruby/internal/intern/re.h
+stringio.o: $(hdrdir)/ruby/internal/intern/ruby.h
+stringio.o: $(hdrdir)/ruby/internal/intern/select.h
+stringio.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+stringio.o: $(hdrdir)/ruby/internal/intern/signal.h
+stringio.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+stringio.o: $(hdrdir)/ruby/internal/intern/string.h
+stringio.o: $(hdrdir)/ruby/internal/intern/struct.h
+stringio.o: $(hdrdir)/ruby/internal/intern/thread.h
+stringio.o: $(hdrdir)/ruby/internal/intern/time.h
+stringio.o: $(hdrdir)/ruby/internal/intern/variable.h
+stringio.o: $(hdrdir)/ruby/internal/intern/vm.h
+stringio.o: $(hdrdir)/ruby/internal/interpreter.h
+stringio.o: $(hdrdir)/ruby/internal/iterator.h
+stringio.o: $(hdrdir)/ruby/internal/memory.h
+stringio.o: $(hdrdir)/ruby/internal/method.h
+stringio.o: $(hdrdir)/ruby/internal/module.h
+stringio.o: $(hdrdir)/ruby/internal/newobj.h
+stringio.o: $(hdrdir)/ruby/internal/rgengc.h
+stringio.o: $(hdrdir)/ruby/internal/scan_args.h
+stringio.o: $(hdrdir)/ruby/internal/special_consts.h
+stringio.o: $(hdrdir)/ruby/internal/static_assert.h
+stringio.o: $(hdrdir)/ruby/internal/stdalign.h
+stringio.o: $(hdrdir)/ruby/internal/stdbool.h
+stringio.o: $(hdrdir)/ruby/internal/symbol.h
+stringio.o: $(hdrdir)/ruby/internal/token_paste.h
+stringio.o: $(hdrdir)/ruby/internal/value.h
+stringio.o: $(hdrdir)/ruby/internal/value_type.h
+stringio.o: $(hdrdir)/ruby/internal/variable.h
+stringio.o: $(hdrdir)/ruby/internal/warning_push.h
+stringio.o: $(hdrdir)/ruby/internal/xmalloc.h
+stringio.o: $(hdrdir)/ruby/assert.h
stringio.o: $(hdrdir)/ruby/backward.h
+stringio.o: $(hdrdir)/ruby/backward/2/assume.h
+stringio.o: $(hdrdir)/ruby/backward/2/attributes.h
+stringio.o: $(hdrdir)/ruby/backward/2/bool.h
+stringio.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+stringio.o: $(hdrdir)/ruby/backward/2/inttypes.h
+stringio.o: $(hdrdir)/ruby/backward/2/limits.h
+stringio.o: $(hdrdir)/ruby/backward/2/long_long.h
+stringio.o: $(hdrdir)/ruby/backward/2/stdalign.h
+stringio.o: $(hdrdir)/ruby/backward/2/stdarg.h
stringio.o: $(hdrdir)/ruby/defines.h
stringio.o: $(hdrdir)/ruby/encoding.h
stringio.o: $(hdrdir)/ruby/intern.h
@@ -12,6 +163,5 @@ stringio.o: $(hdrdir)/ruby/oniguruma.h
stringio.o: $(hdrdir)/ruby/ruby.h
stringio.o: $(hdrdir)/ruby/st.h
stringio.o: $(hdrdir)/ruby/subst.h
-stringio.o: $(top_srcdir)/include/ruby.h
stringio.o: stringio.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/stringio/extconf.rb b/ext/stringio/extconf.rb
index ad8650dce2..a933159766 100644
--- a/ext/stringio/extconf.rb
+++ b/ext/stringio/extconf.rb
@@ -1,3 +1,4 @@
# frozen_string_literal: false
require 'mkmf'
+have_func("rb_io_extract_modeenc", "ruby/io.h")
create_makefile('stringio')
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index 761ec8e4d1..12930b3575 100644
--- a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -1,3 +1,4 @@
+/* -*- mode: c; indent-tabs-mode: t -*- */
/**********************************************************************
stringio.c -
@@ -11,6 +12,8 @@
**********************************************************************/
+#define STRINGIO_VERSION "3.0.1.1"
+
#include "ruby.h"
#include "ruby/io.h"
#include "ruby/encoding.h"
@@ -24,6 +27,86 @@
# define RB_INTEGER_TYPE_P(c) (FIXNUM_P(c) || RB_TYPE_P(c, T_BIGNUM))
#endif
+#ifndef RB_PASS_CALLED_KEYWORDS
+# define rb_funcallv_kw(recv, mid, arg, argv, kw_splat) rb_funcallv(recv, mid, arg, argv)
+# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
+#endif
+
+#ifndef HAVE_RB_IO_EXTRACT_MODEENC
+#define rb_io_extract_modeenc strio_extract_modeenc
+static void
+strio_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
+ int *oflags_p, int *fmode_p, struct rb_io_enc_t *convconfig_p)
+{
+ VALUE mode = *vmode_p;
+ VALUE intmode;
+ int fmode;
+ int has_enc = 0, has_vmode = 0;
+
+ convconfig_p->enc = convconfig_p->enc2 = 0;
+
+ vmode_handle:
+ if (NIL_P(mode)) {
+ fmode = FMODE_READABLE;
+ }
+ else if (!NIL_P(intmode = rb_check_to_integer(mode, "to_int"))) {
+ int flags = NUM2INT(intmode);
+ fmode = rb_io_oflags_fmode(flags);
+ }
+ else {
+ const char *m = StringValueCStr(mode), *n, *e;
+ fmode = rb_io_modestr_fmode(m);
+ n = strchr(m, ':');
+ if (n) {
+ long len;
+ char encname[ENCODING_MAXNAMELEN+1];
+ has_enc = 1;
+ if (fmode & FMODE_SETENC_BY_BOM) {
+ n = strchr(n, '|');
+ }
+ e = strchr(++n, ':');
+ len = e ? e - n : (long)strlen(n);
+ if (len > 0 && len <= ENCODING_MAXNAMELEN) {
+ if (e) {
+ memcpy(encname, n, len);
+ encname[len] = '\0';
+ n = encname;
+ }
+ convconfig_p->enc = rb_enc_find(n);
+ }
+ if (e && (len = strlen(++e)) > 0 && len <= ENCODING_MAXNAMELEN) {
+ convconfig_p->enc2 = rb_enc_find(e);
+ }
+ }
+ }
+
+ if (!NIL_P(opthash)) {
+ rb_encoding *extenc = 0, *intenc = 0;
+ VALUE v;
+ if (!has_vmode) {
+ ID id_mode;
+ CONST_ID(id_mode, "mode");
+ v = rb_hash_aref(opthash, ID2SYM(id_mode));
+ if (!NIL_P(v)) {
+ if (!NIL_P(mode)) {
+ rb_raise(rb_eArgError, "mode specified twice");
+ }
+ has_vmode = 1;
+ mode = v;
+ goto vmode_handle;
+ }
+ }
+
+ if (rb_io_extract_encoding_option(opthash, &extenc, &intenc, &fmode)) {
+ if (has_enc) {
+ rb_raise(rb_eArgError, "encoding specified twice");
+ }
+ }
+ }
+ *fmode_p = fmode;
+}
+#endif
+
struct StringIO {
VALUE string;
rb_encoding *enc;
@@ -35,6 +118,7 @@ struct StringIO {
static VALUE strio_init(int, VALUE *, struct StringIO *, VALUE);
static VALUE strio_unget_bytes(struct StringIO *, const char *, long);
+static long strio_write(VALUE self, VALUE str);
#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
#define error_inval(msg) (rb_syserr_fail(EINVAL, msg))
@@ -184,45 +268,111 @@ strio_initialize(int argc, VALUE *argv, VALUE self)
return strio_init(argc, argv, ptr, self);
}
-static VALUE
-strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
+static int
+detect_bom(VALUE str, int *bomlen)
{
- VALUE string, mode;
- int trunc = 0;
+ const char *p;
+ long len;
- switch (rb_scan_args(argc, argv, "02", &string, &mode)) {
- case 2:
- if (FIXNUM_P(mode)) {
- int flags = FIX2INT(mode);
- ptr->flags = rb_io_oflags_fmode(flags);
- trunc = flags & O_TRUNC;
+ RSTRING_GETMEM(str, p, len);
+ if (len < 1) return 0;
+ switch ((unsigned char)p[0]) {
+ case 0xEF:
+ if (len < 2) break;
+ if ((unsigned char)p[1] == 0xBB && len > 2) {
+ if ((unsigned char)p[2] == 0xBF) {
+ *bomlen = 3;
+ return rb_utf8_encindex();
+ }
}
- else {
- const char *m = StringValueCStr(mode);
- ptr->flags = rb_io_modestr_fmode(m);
- trunc = *m == 'w';
+ break;
+
+ case 0xFE:
+ if (len < 2) break;
+ if ((unsigned char)p[1] == 0xFF) {
+ *bomlen = 2;
+ return rb_enc_find_index("UTF-16BE");
}
- StringValue(string);
- if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
- rb_syserr_fail(EACCES, 0);
+ break;
+
+ case 0xFF:
+ if (len < 2) break;
+ if ((unsigned char)p[1] == 0xFE) {
+ if (len >= 4 && (unsigned char)p[2] == 0 && (unsigned char)p[3] == 0) {
+ *bomlen = 4;
+ return rb_enc_find_index("UTF-32LE");
+ }
+ *bomlen = 2;
+ return rb_enc_find_index("UTF-16LE");
}
- if (trunc) {
- rb_str_resize(string, 0);
+ break;
+
+ case 0:
+ if (len < 4) break;
+ if ((unsigned char)p[1] == 0 && (unsigned char)p[2] == 0xFE && (unsigned char)p[3] == 0xFF) {
+ *bomlen = 4;
+ return rb_enc_find_index("UTF-32BE");
}
break;
- case 1:
+ }
+ return 0;
+}
+
+static rb_encoding *
+set_encoding_by_bom(struct StringIO *ptr)
+{
+ int bomlen, idx = detect_bom(ptr->string, &bomlen);
+ rb_encoding *extenc = NULL;
+
+ if (idx) {
+ extenc = rb_enc_from_index(idx);
+ ptr->pos = bomlen;
+ if (ptr->flags & FMODE_WRITABLE) {
+ rb_enc_associate_index(ptr->string, idx);
+ }
+ }
+ ptr->enc = extenc;
+ return extenc;
+}
+
+static VALUE
+strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
+{
+ VALUE string, vmode, opt;
+ int oflags;
+ struct rb_io_enc_t convconfig;
+
+ argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
+ rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
+ if (argc) {
StringValue(string);
- ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
- break;
- case 0:
+ }
+ else {
string = rb_enc_str_new("", 0, rb_default_external_encoding());
- ptr->flags = FMODE_READWRITE;
- break;
+ }
+ if (OBJ_FROZEN_RAW(string)) {
+ if (ptr->flags & FMODE_WRITABLE) {
+ rb_syserr_fail(EACCES, 0);
+ }
+ }
+ else {
+ if (NIL_P(vmode)) {
+ ptr->flags |= FMODE_WRITABLE;
+ }
+ }
+ if (ptr->flags & FMODE_TRUNC) {
+ rb_str_resize(string, 0);
}
ptr->string = string;
- ptr->enc = 0;
+ if (argc == 1) {
+ ptr->enc = rb_enc_get(string);
+ }
+ else {
+ ptr->enc = convconfig.enc;
+ }
ptr->pos = 0;
ptr->lineno = 0;
+ if (ptr->flags & FMODE_SETENC_BY_BOM) set_encoding_by_bom(ptr);
RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
return self;
}
@@ -246,7 +396,7 @@ strio_finalize(VALUE self)
static VALUE
strio_s_open(int argc, VALUE *argv, VALUE klass)
{
- VALUE obj = rb_class_new_instance(argc, argv, klass);
+ VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
if (!rb_block_given_p()) return obj;
return rb_ensure(rb_yield, obj, strio_finalize, obj);
}
@@ -261,7 +411,7 @@ strio_s_new(int argc, VALUE *argv, VALUE klass)
rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
cname, cname);
}
- return rb_class_new_instance(argc, argv, klass);
+ return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
}
/*
@@ -285,7 +435,7 @@ strio_nil(VALUE self)
}
/*
- * Returns *strio* itself. Just for compatibility to IO.
+ * Returns an object itself. Just for compatibility to IO.
*/
static VALUE
strio_self(VALUE self)
@@ -361,7 +511,7 @@ strio_set_string(VALUE self, VALUE string)
* call-seq:
* strio.close -> nil
*
- * Closes strio. The *strio* is unavailable for any further data
+ * Closes a StringIO. The stream is unavailable for any further data
* operations; an +IOError+ is raised if such an attempt is made.
*/
static VALUE
@@ -377,7 +527,7 @@ strio_close(VALUE self)
* strio.close_read -> nil
*
* Closes the read end of a StringIO. Will raise an +IOError+ if the
- * *strio* is not readable.
+ * receiver is not readable.
*/
static VALUE
strio_close_read(VALUE self)
@@ -395,7 +545,7 @@ strio_close_read(VALUE self)
* strio.close_write -> nil
*
* Closes the write end of a StringIO. Will raise an +IOError+ if the
- * *strio* is not writeable.
+ * receiver is not writeable.
*/
static VALUE
strio_close_write(VALUE self)
@@ -412,7 +562,7 @@ strio_close_write(VALUE self)
* call-seq:
* strio.closed? -> true or false
*
- * Returns +true+ if *strio* is completely closed, +false+ otherwise.
+ * Returns +true+ if the stream is completely closed, +false+ otherwise.
*/
static VALUE
strio_closed(VALUE self)
@@ -426,7 +576,7 @@ strio_closed(VALUE self)
* call-seq:
* strio.closed_read? -> true or false
*
- * Returns +true+ if *strio* is not readable, +false+ otherwise.
+ * Returns +true+ if the stream is not readable, +false+ otherwise.
*/
static VALUE
strio_closed_read(VALUE self)
@@ -440,7 +590,7 @@ strio_closed_read(VALUE self)
* call-seq:
* strio.closed_write? -> true or false
*
- * Returns +true+ if *strio* is not writable, +false+ otherwise.
+ * Returns +true+ if the stream is not writable, +false+ otherwise.
*/
static VALUE
strio_closed_write(VALUE self)
@@ -450,19 +600,26 @@ strio_closed_write(VALUE self)
return Qtrue;
}
+static struct StringIO *
+strio_to_read(VALUE self)
+{
+ struct StringIO *ptr = readable(self);
+ if (ptr->pos < RSTRING_LEN(ptr->string)) return ptr;
+ return NULL;
+}
+
/*
* call-seq:
* strio.eof -> true or false
* strio.eof? -> true or false
*
- * Returns true if *strio* is at end of file. The stringio must be
- * opened for reading or an +IOError+ will be raised.
+ * Returns true if the stream is at the end of the data (underlying string).
+ * The stream must be opened for reading or an +IOError+ will be raised.
*/
static VALUE
strio_eof(VALUE self)
{
- struct StringIO *ptr = readable(self);
- if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
+ if (strio_to_read(self)) return Qfalse;
return Qtrue;
}
@@ -479,7 +636,6 @@ strio_copy(VALUE copy, VALUE orig)
strio_free(DATA_PTR(copy));
}
DATA_PTR(copy) = ptr;
- OBJ_INFECT(copy, orig);
RBASIC(copy)->flags &= ~STRIO_READWRITE;
RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
++ptr->count;
@@ -490,7 +646,7 @@ strio_copy(VALUE copy, VALUE orig)
* call-seq:
* strio.lineno -> integer
*
- * Returns the current line number in *strio*. The stringio must be
+ * Returns the current line number. The stream must be
* opened for reading. +lineno+ counts the number of times +gets+ is
* called, rather than the number of newlines encountered. The two
* values will differ if +gets+ is called with a separator other than
@@ -516,6 +672,13 @@ strio_set_lineno(VALUE self, VALUE lineno)
return lineno;
}
+/*
+ * call-seq:
+ * strio.binmode -> stringio
+ *
+ * Puts stream into binary mode. See IO#binmode.
+ *
+ */
static VALUE
strio_binmode(VALUE self)
{
@@ -540,7 +703,7 @@ strio_binmode(VALUE self)
* strio.reopen(other_StrIO) -> strio
* strio.reopen(string, mode) -> strio
*
- * Reinitializes *strio* with the given <i>other_StrIO</i> or _string_
+ * Reinitializes the stream with the given <i>other_StrIO</i> or _string_
* and _mode_ (see StringIO#new).
*/
static VALUE
@@ -558,7 +721,7 @@ strio_reopen(int argc, VALUE *argv, VALUE self)
* strio.pos -> integer
* strio.tell -> integer
*
- * Returns the current offset (in bytes) of *strio*.
+ * Returns the current offset (in bytes).
*/
static VALUE
strio_get_pos(VALUE self)
@@ -570,7 +733,7 @@ strio_get_pos(VALUE self)
* call-seq:
* strio.pos = integer -> integer
*
- * Seeks to the given position (in bytes) in *strio*.
+ * Seeks to the given position (in bytes).
*/
static VALUE
strio_set_pos(VALUE self, VALUE pos)
@@ -588,7 +751,7 @@ strio_set_pos(VALUE self, VALUE pos)
* call-seq:
* strio.rewind -> 0
*
- * Positions *strio* to the beginning of input, resetting
+ * Positions the stream to the beginning of input, resetting
* +lineno+ to zero.
*/
static VALUE
@@ -666,11 +829,11 @@ strio_get_sync(VALUE self)
static VALUE
strio_each_byte(VALUE self)
{
- struct StringIO *ptr = readable(self);
+ struct StringIO *ptr;
RETURN_ENUMERATOR(self, 0, 0);
- while (ptr->pos < RSTRING_LEN(ptr->string)) {
+ while ((ptr = strio_to_read(self)) != NULL) {
char c = RSTRING_PTR(ptr->string)[ptr->pos++];
rb_yield(CHR2FIX(c));
}
@@ -678,18 +841,6 @@ strio_each_byte(VALUE self)
}
/*
- * This is a deprecated alias for #each_byte.
- */
-static VALUE
-strio_bytes(VALUE self)
-{
- rb_warn("StringIO#bytes is deprecated; use #each_byte instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(self, ID2SYM(rb_intern("each_byte")), 0, 0);
- return strio_each_byte(self);
-}
-
-/*
* call-seq:
* strio.getc -> string or nil
*
@@ -756,7 +907,7 @@ strio_extend(struct StringIO *ptr, long pos, long len)
* call-seq:
* strio.ungetc(string) -> nil
*
- * Pushes back one character (passed as a parameter) onto *strio*
+ * Pushes back one character (passed as a parameter)
* such that a subsequent buffered read will return it. There is no
* limitation for multiple pushbacks including pushing back behind the
* beginning of the buffer string.
@@ -802,24 +953,25 @@ static VALUE
strio_ungetbyte(VALUE self, VALUE c)
{
struct StringIO *ptr = readable(self);
- char buf[1], *cp = buf;
- long cl = 1;
check_modifiable(ptr);
if (NIL_P(c)) return Qnil;
- if (FIXNUM_P(c)) {
- buf[0] = (char)FIX2INT(c);
- return strio_unget_bytes(ptr, buf, 1);
+ if (RB_INTEGER_TYPE_P(c)) {
+ /* rb_int_and() not visible from exts */
+ VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
+ const char cc = NUM2INT(v) & 0xFF;
+ strio_unget_bytes(ptr, &cc, 1);
}
else {
+ long cl;
SafeStringValue(c);
- cp = RSTRING_PTR(c);
cl = RSTRING_LEN(c);
- if (cl == 0) return Qnil;
- strio_unget_bytes(ptr, cp, cl);
- RB_GC_GUARD(c);
- return Qnil;
+ if (cl > 0) {
+ strio_unget_bytes(ptr, RSTRING_PTR(c), cl);
+ RB_GC_GUARD(c);
+ }
}
+ return Qnil;
}
static VALUE
@@ -832,7 +984,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
len = RSTRING_LEN(str);
rest = pos - len;
if (cl > pos) {
- long ex = (rest < 0 ? cl-pos : cl+rest);
+ long ex = cl - (rest < 0 ? pos : len);
rb_str_modify_expand(str, ex);
rb_str_set_len(str, len + ex);
s = RSTRING_PTR(str);
@@ -862,7 +1014,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
static VALUE
strio_readchar(VALUE self)
{
- VALUE c = rb_funcall2(self, rb_intern("getc"), 0, 0);
+ VALUE c = rb_funcallv(self, rb_intern("getc"), 0, 0);
if (NIL_P(c)) rb_eof_error();
return c;
}
@@ -876,7 +1028,7 @@ strio_readchar(VALUE self)
static VALUE
strio_readbyte(VALUE self)
{
- VALUE c = rb_funcall2(self, rb_intern("getbyte"), 0, 0);
+ VALUE c = rb_funcallv(self, rb_intern("getbyte"), 0, 0);
if (NIL_P(c)) rb_eof_error();
return c;
}
@@ -902,18 +1054,6 @@ strio_each_char(VALUE self)
}
/*
- * This is a deprecated alias for <code>each_char</code>.
- */
-static VALUE
-strio_chars(VALUE self)
-{
- rb_warn("StringIO#chars is deprecated; use #each_char instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(self, ID2SYM(rb_intern("each_char")), 0, 0);
- return strio_each_char(self);
-}
-
-/*
* call-seq:
* strio.each_codepoint {|c| block } -> strio
* strio.each_codepoint -> anEnumerator
@@ -932,31 +1072,15 @@ strio_each_codepoint(VALUE self)
ptr = readable(self);
enc = get_enc(ptr);
- for (;;) {
- if (ptr->pos >= RSTRING_LEN(ptr->string)) {
- return self;
- }
-
+ while ((ptr = strio_to_read(self)) != NULL) {
c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
RSTRING_END(ptr->string), &n, enc);
- rb_yield(UINT2NUM(c));
ptr->pos += n;
+ rb_yield(UINT2NUM(c));
}
return self;
}
-/*
- * This is a deprecated alias for <code>each_codepoint</code>.
- */
-static VALUE
-strio_codepoints(VALUE self)
-{
- rb_warn("StringIO#codepoints is deprecated; use #each_codepoint instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(self, ID2SYM(rb_intern("each_codepoint")), 0, 0);
- return strio_each_codepoint(self);
-}
-
/* Boyer-Moore search: copied from regex.c */
static void
bm_init_skip(long *skip, const char *pat, long m)
@@ -1136,9 +1260,9 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
/*
* call-seq:
- * strio.gets(sep=$/) -> string or nil
- * strio.gets(limit) -> string or nil
- * strio.gets(sep, limit) -> string or nil
+ * strio.gets(sep=$/, chomp: false) -> string or nil
+ * strio.gets(limit, chomp: false) -> string or nil
+ * strio.gets(sep, limit, chomp: false) -> string or nil
*
* See IO#gets.
*/
@@ -1160,31 +1284,31 @@ strio_gets(int argc, VALUE *argv, VALUE self)
/*
* call-seq:
- * strio.readline(sep=$/) -> string
- * strio.readline(limit) -> string or nil
- * strio.readline(sep, limit) -> string or nil
+ * strio.readline(sep=$/, chomp: false) -> string
+ * strio.readline(limit, chomp: false) -> string or nil
+ * strio.readline(sep, limit, chomp: false) -> string or nil
*
* See IO#readline.
*/
static VALUE
strio_readline(int argc, VALUE *argv, VALUE self)
{
- VALUE line = rb_funcall2(self, rb_intern("gets"), argc, argv);
+ VALUE line = rb_funcallv_kw(self, rb_intern("gets"), argc, argv, RB_PASS_CALLED_KEYWORDS);
if (NIL_P(line)) rb_eof_error();
return line;
}
/*
* call-seq:
- * strio.each(sep=$/) {|line| block } -> strio
- * strio.each(limit) {|line| block } -> strio
- * strio.each(sep, limit) {|line| block } -> strio
- * strio.each(...) -> anEnumerator
+ * strio.each(sep=$/, chomp: false) {|line| block } -> strio
+ * strio.each(limit, chomp: false) {|line| block } -> strio
+ * strio.each(sep, limit, chomp: false) {|line| block } -> strio
+ * strio.each(...) -> anEnumerator
*
- * strio.each_line(sep=$/) {|line| block } -> strio
- * strio.each_line(limit) {|line| block } -> strio
- * strio.each_line(sep,limit) {|line| block } -> strio
- * strio.each_line(...) -> anEnumerator
+ * strio.each_line(sep=$/, chomp: false) {|line| block } -> strio
+ * strio.each_line(limit, chomp: false) {|line| block } -> strio
+ * strio.each_line(sep, limit, chomp: false) {|line| block } -> strio
+ * strio.each_line(...) -> anEnumerator
*
* See IO#each.
*/
@@ -1208,22 +1332,10 @@ strio_each(int argc, VALUE *argv, VALUE self)
}
/*
- * This is a deprecated alias for <code>each_line</code>.
- */
-static VALUE
-strio_lines(int argc, VALUE *argv, VALUE self)
-{
- rb_warn("StringIO#lines is deprecated; use #each_line instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(self, ID2SYM(rb_intern("each_line")), argc, argv);
- return strio_each(argc, argv, self);
-}
-
-/*
* call-seq:
- * strio.readlines(sep=$/) -> array
- * strio.readlines(limit) -> array
- * strio.readlines(sep,limit) -> array
+ * strio.readlines(sep=$/, chomp: false) -> array
+ * strio.readlines(limit, chomp: false) -> array
+ * strio.readlines(sep, limit, chomp: false) -> array
*
* See IO#readlines.
*/
@@ -1247,31 +1359,47 @@ strio_readlines(int argc, VALUE *argv, VALUE self)
/*
* call-seq:
- * strio.write(string) -> integer
- * strio.syswrite(string) -> integer
+ * strio.write(string, ...) -> integer
+ * strio.syswrite(string) -> integer
*
- * Appends the given string to the underlying buffer string of *strio*.
+ * Appends the given string to the underlying buffer string.
* The stream must be opened for writing. If the argument is not a
* string, it will be converted to a string using <code>to_s</code>.
* Returns the number of bytes written. See IO#write.
*/
static VALUE
+strio_write_m(int argc, VALUE *argv, VALUE self)
+{
+ long len = 0;
+ while (argc-- > 0) {
+ /* StringIO can't exceed long limit */
+ len += strio_write(self, *argv++);
+ }
+ return LONG2NUM(len);
+}
+
+static long
strio_write(VALUE self, VALUE str)
{
struct StringIO *ptr = writable(self);
long len, olen;
rb_encoding *enc, *enc2;
rb_encoding *const ascii8bit = rb_ascii8bit_encoding();
+ rb_encoding *usascii = 0;
if (!RB_TYPE_P(str, T_STRING))
str = rb_obj_as_string(str);
enc = get_enc(ptr);
enc2 = rb_enc_get(str);
- if (enc != enc2 && enc != ascii8bit) {
- str = rb_str_conv_enc(str, enc2, enc);
+ if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding())) {
+ VALUE converted = rb_str_conv_enc(str, enc2, enc);
+ if (converted == str && enc2 != ascii8bit && enc2 != usascii) { /* conversion failed */
+ rb_enc_check(rb_enc_from_encoding(enc), str);
+ }
+ str = converted;
}
len = RSTRING_LEN(str);
- if (len == 0) return INT2FIX(0);
+ if (len == 0) return 0;
check_modifiable(ptr);
olen = RSTRING_LEN(ptr->string);
if (ptr->flags & FMODE_APPEND) {
@@ -1280,7 +1408,6 @@ strio_write(VALUE self, VALUE str)
if (ptr->pos == olen) {
if (enc == ascii8bit || enc2 == ascii8bit) {
rb_enc_str_buf_cat(ptr->string, RSTRING_PTR(str), len, enc);
- OBJ_INFECT(ptr->string, str);
}
else {
rb_str_buf_append(ptr->string, str);
@@ -1289,12 +1416,10 @@ strio_write(VALUE self, VALUE str)
else {
strio_extend(ptr, ptr->pos, len);
memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
- OBJ_INFECT(ptr->string, str);
}
- OBJ_INFECT(ptr->string, self);
RB_GC_GUARD(str);
ptr->pos += len;
- return LONG2NUM(len);
+ return len;
}
/*
@@ -1368,7 +1493,6 @@ strio_read(int argc, VALUE *argv, VALUE self)
long len;
int binary = 0;
- rb_check_arity(argc, 0, 2);
switch (argc) {
case 2:
str = argv[1];
@@ -1394,7 +1518,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
case 0:
len = RSTRING_LEN(ptr->string);
if (len <= ptr->pos) {
- rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
+ rb_encoding *enc = get_enc(ptr);
if (NIL_P(str)) {
str = rb_str_new(0, 0);
}
@@ -1408,6 +1532,8 @@ strio_read(int argc, VALUE *argv, VALUE self)
len -= ptr->pos;
}
break;
+ default:
+ rb_error_arity(argc, 0, 2);
}
if (NIL_P(str)) {
rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
@@ -1438,7 +1564,7 @@ strio_read(int argc, VALUE *argv, VALUE self)
static VALUE
strio_sysread(int argc, VALUE *argv, VALUE self)
{
- VALUE val = rb_funcall2(self, rb_intern("read"), argc, argv);
+ VALUE val = rb_funcallv_kw(self, rb_intern("read"), argc, argv, RB_PASS_CALLED_KEYWORDS);
if (NIL_P(val)) {
rb_eof_error();
}
@@ -1513,7 +1639,7 @@ strio_size(VALUE self)
* call-seq:
* strio.truncate(integer) -> 0
*
- * Truncates the buffer string to at most _integer_ bytes. The *strio*
+ * Truncates the buffer string to at most _integer_ bytes. The stream
* must be opened for writing.
*/
static VALUE
@@ -1537,7 +1663,8 @@ strio_truncate(VALUE self, VALUE len)
* strio.external_encoding => encoding
*
* Returns the Encoding object that represents the encoding of the file.
- * If strio is write mode and no encoding is specified, returns <code>nil</code>.
+ * If the stream is write mode and no encoding is specified, returns
+ * +nil+.
*/
static VALUE
@@ -1552,7 +1679,7 @@ strio_external_encoding(VALUE self)
* strio.internal_encoding => encoding
*
* Returns the Encoding of the internal string if conversion is
- * specified. Otherwise returns nil.
+ * specified. Otherwise returns +nil+.
*/
static VALUE
@@ -1594,23 +1721,47 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
return self;
}
+static VALUE
+strio_set_encoding_by_bom(VALUE self)
+{
+ struct StringIO *ptr = StringIO(self);
+
+ if (!set_encoding_by_bom(ptr)) return Qnil;
+ return rb_enc_from_encoding(ptr->enc);
+}
+
/*
- * Pseudo I/O on String object.
+ * Pseudo I/O on String object, with interface corresponding to IO.
*
- * Commonly used to simulate `$stdio` or `$stderr`
+ * Commonly used to simulate <code>$stdio</code> or <code>$stderr</code>
*
* === Examples
*
* require 'stringio'
*
+ * # Writing stream emulation
* io = StringIO.new
* io.puts "Hello World"
* io.string #=> "Hello World\n"
+ *
+ * # Reading stream emulation
+ * io = StringIO.new "first\nsecond\nlast\n"
+ * io.getc #=> "f"
+ * io.gets #=> "irst\n"
+ * io.read #=> "second\nlast\n"
*/
void
Init_stringio(void)
{
- VALUE StringIO = rb_define_class("StringIO", rb_cData);
+#undef rb_intern
+
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+ VALUE StringIO = rb_define_class("StringIO", rb_cObject);
+
+ rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION));
rb_include_module(StringIO, rb_mEnumerable);
rb_define_alloc_func(StringIO, strio_s_allocate);
@@ -1653,13 +1804,9 @@ Init_stringio(void)
rb_define_method(StringIO, "each", strio_each, -1);
rb_define_method(StringIO, "each_line", strio_each, -1);
- rb_define_method(StringIO, "lines", strio_lines, -1);
rb_define_method(StringIO, "each_byte", strio_each_byte, 0);
- rb_define_method(StringIO, "bytes", strio_bytes, 0);
rb_define_method(StringIO, "each_char", strio_each_char, 0);
- rb_define_method(StringIO, "chars", strio_chars, 0);
rb_define_method(StringIO, "each_codepoint", strio_each_codepoint, 0);
- rb_define_method(StringIO, "codepoints", strio_codepoints, 0);
rb_define_method(StringIO, "getc", strio_getc, 0);
rb_define_method(StringIO, "ungetc", strio_ungetc, 1);
rb_define_method(StringIO, "ungetbyte", strio_ungetbyte, 1);
@@ -1668,7 +1815,7 @@ Init_stringio(void)
rb_define_method(StringIO, "readlines", strio_readlines, -1);
rb_define_method(StringIO, "read", strio_read, -1);
- rb_define_method(StringIO, "write", strio_write, 1);
+ rb_define_method(StringIO, "write", strio_write_m, -1);
rb_define_method(StringIO, "putc", strio_putc, 1);
/*
@@ -1692,6 +1839,7 @@ Init_stringio(void)
rb_define_method(StringIO, "external_encoding", strio_external_encoding, 0);
rb_define_method(StringIO, "internal_encoding", strio_internal_encoding, 0);
rb_define_method(StringIO, "set_encoding", strio_set_encoding, -1);
+ rb_define_method(StringIO, "set_encoding_by_bom", strio_set_encoding_by_bom, 0);
{
VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
diff --git a/ext/stringio/stringio.gemspec b/ext/stringio/stringio.gemspec
index fa1e767f5f..524d976cfb 100644
--- a/ext/stringio/stringio.gemspec
+++ b/ext/stringio/stringio.gemspec
@@ -1,27 +1,31 @@
# -*- encoding: utf-8 -*-
# frozen_string_literal: true
-# stub: stringio 0.0.0 ruby lib
-# stub: extconf.rb
+source_version = ["", "ext/stringio/"].find do |dir|
+ begin
+ break File.open(File.join(__dir__, "#{dir}stringio.c")) {|f|
+ f.gets("\n#define STRINGIO_VERSION ")
+ f.gets[/\s*"(.+)"/, 1]
+ }
+ rescue Errno::ENOENT
+ end
+end
Gem::Specification.new do |s|
- s.name = "stringio".freeze
- s.version = "0.0.1"
+ s.name = "stringio"
+ s.version = source_version
- s.required_rubygems_version = Gem::Requirement.new(">= 2.6".freeze)
- s.require_paths = ["lib".freeze]
- s.authors = ["Nobu Nakada".freeze]
- s.date = "2016-06-09"
- s.description = "Pseudo `IO` class from/to `String`.".freeze
- s.email = "nobu@ruby-lang.org".freeze
- s.extensions = ["extconf.rb".freeze]
- s.files = ["README.md".freeze, "depend".freeze, "extconf.rb".freeze, "stringio.c".freeze]
- s.homepage = "https://github.com/ruby/stringio".freeze
- s.licenses = ["BSD-2-Clause".freeze]
- s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze)
- s.rubygems_version = "2.6.11".freeze
- s.summary = "Pseudo IO on String".freeze
- s.cert_chain = %w[certs/nobu.pem]
- s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
+ s.required_rubygems_version = Gem::Requirement.new(">= 2.6")
+ s.require_paths = ["lib"]
+ s.authors = ["Nobu Nakada"]
+ s.description = "Pseudo `IO` class from/to `String`."
+ s.email = "nobu@ruby-lang.org"
+ s.extensions = ["ext/stringio/extconf.rb"]
+ s.files = ["README.md", "ext/stringio/extconf.rb", "ext/stringio/stringio.c"]
+ s.homepage = "https://github.com/ruby/stringio"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
+ s.required_ruby_version = ">= 2.5"
+ s.summary = "Pseudo IO on String"
- s.add_development_dependency 'rake-compiler'
+ # s.cert_chain = %w[certs/nobu.pem]
+ # s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
end
diff --git a/ext/strscan/depend b/ext/strscan/depend
index 1c396b00cf..f297134d3b 100644
--- a/ext/strscan/depend
+++ b/ext/strscan/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
strscan.o: $(RUBY_EXTCONF_H)
strscan.o: $(arch_hdrdir)/ruby/config.h
+strscan.o: $(hdrdir)/ruby/internal/anyargs.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+strscan.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+strscan.o: $(hdrdir)/ruby/internal/assume.h
+strscan.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+strscan.o: $(hdrdir)/ruby/internal/attr/artificial.h
+strscan.o: $(hdrdir)/ruby/internal/attr/cold.h
+strscan.o: $(hdrdir)/ruby/internal/attr/const.h
+strscan.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+strscan.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+strscan.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+strscan.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+strscan.o: $(hdrdir)/ruby/internal/attr/error.h
+strscan.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+strscan.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+strscan.o: $(hdrdir)/ruby/internal/attr/format.h
+strscan.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+strscan.o: $(hdrdir)/ruby/internal/attr/noalias.h
+strscan.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+strscan.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+strscan.o: $(hdrdir)/ruby/internal/attr/noinline.h
+strscan.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+strscan.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+strscan.o: $(hdrdir)/ruby/internal/attr/pure.h
+strscan.o: $(hdrdir)/ruby/internal/attr/restrict.h
+strscan.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+strscan.o: $(hdrdir)/ruby/internal/attr/warning.h
+strscan.o: $(hdrdir)/ruby/internal/attr/weakref.h
+strscan.o: $(hdrdir)/ruby/internal/cast.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_is.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+strscan.o: $(hdrdir)/ruby/internal/compiler_since.h
+strscan.o: $(hdrdir)/ruby/internal/config.h
+strscan.o: $(hdrdir)/ruby/internal/constant_p.h
+strscan.o: $(hdrdir)/ruby/internal/core.h
+strscan.o: $(hdrdir)/ruby/internal/core/rarray.h
+strscan.o: $(hdrdir)/ruby/internal/core/rbasic.h
+strscan.o: $(hdrdir)/ruby/internal/core/rbignum.h
+strscan.o: $(hdrdir)/ruby/internal/core/rclass.h
+strscan.o: $(hdrdir)/ruby/internal/core/rdata.h
+strscan.o: $(hdrdir)/ruby/internal/core/rfile.h
+strscan.o: $(hdrdir)/ruby/internal/core/rhash.h
+strscan.o: $(hdrdir)/ruby/internal/core/rmatch.h
+strscan.o: $(hdrdir)/ruby/internal/core/robject.h
+strscan.o: $(hdrdir)/ruby/internal/core/rregexp.h
+strscan.o: $(hdrdir)/ruby/internal/core/rstring.h
+strscan.o: $(hdrdir)/ruby/internal/core/rstruct.h
+strscan.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+strscan.o: $(hdrdir)/ruby/internal/ctype.h
+strscan.o: $(hdrdir)/ruby/internal/dllexport.h
+strscan.o: $(hdrdir)/ruby/internal/dosish.h
+strscan.o: $(hdrdir)/ruby/internal/error.h
+strscan.o: $(hdrdir)/ruby/internal/eval.h
+strscan.o: $(hdrdir)/ruby/internal/event.h
+strscan.o: $(hdrdir)/ruby/internal/fl_type.h
+strscan.o: $(hdrdir)/ruby/internal/gc.h
+strscan.o: $(hdrdir)/ruby/internal/glob.h
+strscan.o: $(hdrdir)/ruby/internal/globals.h
+strscan.o: $(hdrdir)/ruby/internal/has/attribute.h
+strscan.o: $(hdrdir)/ruby/internal/has/builtin.h
+strscan.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+strscan.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+strscan.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+strscan.o: $(hdrdir)/ruby/internal/has/extension.h
+strscan.o: $(hdrdir)/ruby/internal/has/feature.h
+strscan.o: $(hdrdir)/ruby/internal/has/warning.h
+strscan.o: $(hdrdir)/ruby/internal/intern/array.h
+strscan.o: $(hdrdir)/ruby/internal/intern/bignum.h
+strscan.o: $(hdrdir)/ruby/internal/intern/class.h
+strscan.o: $(hdrdir)/ruby/internal/intern/compar.h
+strscan.o: $(hdrdir)/ruby/internal/intern/complex.h
+strscan.o: $(hdrdir)/ruby/internal/intern/cont.h
+strscan.o: $(hdrdir)/ruby/internal/intern/dir.h
+strscan.o: $(hdrdir)/ruby/internal/intern/enum.h
+strscan.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+strscan.o: $(hdrdir)/ruby/internal/intern/error.h
+strscan.o: $(hdrdir)/ruby/internal/intern/eval.h
+strscan.o: $(hdrdir)/ruby/internal/intern/file.h
+strscan.o: $(hdrdir)/ruby/internal/intern/gc.h
+strscan.o: $(hdrdir)/ruby/internal/intern/hash.h
+strscan.o: $(hdrdir)/ruby/internal/intern/io.h
+strscan.o: $(hdrdir)/ruby/internal/intern/load.h
+strscan.o: $(hdrdir)/ruby/internal/intern/marshal.h
+strscan.o: $(hdrdir)/ruby/internal/intern/numeric.h
+strscan.o: $(hdrdir)/ruby/internal/intern/object.h
+strscan.o: $(hdrdir)/ruby/internal/intern/parse.h
+strscan.o: $(hdrdir)/ruby/internal/intern/proc.h
+strscan.o: $(hdrdir)/ruby/internal/intern/process.h
+strscan.o: $(hdrdir)/ruby/internal/intern/random.h
+strscan.o: $(hdrdir)/ruby/internal/intern/range.h
+strscan.o: $(hdrdir)/ruby/internal/intern/rational.h
+strscan.o: $(hdrdir)/ruby/internal/intern/re.h
+strscan.o: $(hdrdir)/ruby/internal/intern/ruby.h
+strscan.o: $(hdrdir)/ruby/internal/intern/select.h
+strscan.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+strscan.o: $(hdrdir)/ruby/internal/intern/signal.h
+strscan.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+strscan.o: $(hdrdir)/ruby/internal/intern/string.h
+strscan.o: $(hdrdir)/ruby/internal/intern/struct.h
+strscan.o: $(hdrdir)/ruby/internal/intern/thread.h
+strscan.o: $(hdrdir)/ruby/internal/intern/time.h
+strscan.o: $(hdrdir)/ruby/internal/intern/variable.h
+strscan.o: $(hdrdir)/ruby/internal/intern/vm.h
+strscan.o: $(hdrdir)/ruby/internal/interpreter.h
+strscan.o: $(hdrdir)/ruby/internal/iterator.h
+strscan.o: $(hdrdir)/ruby/internal/memory.h
+strscan.o: $(hdrdir)/ruby/internal/method.h
+strscan.o: $(hdrdir)/ruby/internal/module.h
+strscan.o: $(hdrdir)/ruby/internal/newobj.h
+strscan.o: $(hdrdir)/ruby/internal/rgengc.h
+strscan.o: $(hdrdir)/ruby/internal/scan_args.h
+strscan.o: $(hdrdir)/ruby/internal/special_consts.h
+strscan.o: $(hdrdir)/ruby/internal/static_assert.h
+strscan.o: $(hdrdir)/ruby/internal/stdalign.h
+strscan.o: $(hdrdir)/ruby/internal/stdbool.h
+strscan.o: $(hdrdir)/ruby/internal/symbol.h
+strscan.o: $(hdrdir)/ruby/internal/token_paste.h
+strscan.o: $(hdrdir)/ruby/internal/value.h
+strscan.o: $(hdrdir)/ruby/internal/value_type.h
+strscan.o: $(hdrdir)/ruby/internal/variable.h
+strscan.o: $(hdrdir)/ruby/internal/warning_push.h
+strscan.o: $(hdrdir)/ruby/internal/xmalloc.h
+strscan.o: $(hdrdir)/ruby/assert.h
strscan.o: $(hdrdir)/ruby/backward.h
+strscan.o: $(hdrdir)/ruby/backward/2/assume.h
+strscan.o: $(hdrdir)/ruby/backward/2/attributes.h
+strscan.o: $(hdrdir)/ruby/backward/2/bool.h
+strscan.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+strscan.o: $(hdrdir)/ruby/backward/2/inttypes.h
+strscan.o: $(hdrdir)/ruby/backward/2/limits.h
+strscan.o: $(hdrdir)/ruby/backward/2/long_long.h
+strscan.o: $(hdrdir)/ruby/backward/2/stdalign.h
+strscan.o: $(hdrdir)/ruby/backward/2/stdarg.h
strscan.o: $(hdrdir)/ruby/defines.h
strscan.o: $(hdrdir)/ruby/encoding.h
strscan.o: $(hdrdir)/ruby/intern.h
@@ -13,7 +164,5 @@ strscan.o: $(hdrdir)/ruby/regex.h
strscan.o: $(hdrdir)/ruby/ruby.h
strscan.o: $(hdrdir)/ruby/st.h
strscan.o: $(hdrdir)/ruby/subst.h
-strscan.o: $(top_srcdir)/regenc.h
-strscan.o: $(top_srcdir)/regint.h
strscan.o: strscan.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/strscan/extconf.rb b/ext/strscan/extconf.rb
index 714fa99fae..f0ecbf85d8 100644
--- a/ext/strscan/extconf.rb
+++ b/ext/strscan/extconf.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'mkmf'
-$INCFLAGS << " -I$(top_srcdir)"
+$INCFLAGS << " -I$(top_srcdir)" if $extmk
+have_func("onig_region_memsize", "ruby.h")
create_makefile 'strscan'
diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c
index 75cff3716f..e1426380b4 100644
--- a/ext/strscan/strscan.c
+++ b/ext/strscan/strscan.c
@@ -4,16 +4,25 @@
Copyright (c) 1999-2006 Minero Aoki
This program is free software.
- You can distribute/modify this program under the terms of
- the Ruby License. For details, see the file COPYING.
+ You can redistribute this program under the terms of the Ruby's or 2-clause
+ BSD License. For details, see the COPYING and LICENSE.txt files.
*/
#include "ruby/ruby.h"
#include "ruby/re.h"
#include "ruby/encoding.h"
-#include "regint.h"
-#define STRSCAN_VERSION "0.7.0"
+#ifdef RUBY_EXTCONF_H
+# include RUBY_EXTCONF_H
+#endif
+
+#ifdef HAVE_ONIG_REGION_MEMSIZE
+extern size_t onig_region_memsize(const struct re_registers *regs);
+#endif
+
+#include <stdbool.h>
+
+#define STRSCAN_VERSION "3.0.1"
/* =======================================================================
Data Type Definitions
@@ -41,6 +50,9 @@ struct strscanner
/* regexp used for last scan */
VALUE regex;
+
+ /* anchor mode */
+ bool fixed_anchor_p;
};
#define MATCHED_P(s) ((s)->flags & FLAG_MATCHED)
@@ -65,7 +77,6 @@ struct strscanner
======================================================================= */
static inline long minl _((const long n, const long x));
-static VALUE infect _((VALUE str, struct strscanner *p));
static VALUE extract_range _((struct strscanner *p, long beg_i, long end_i));
static VALUE extract_beg_len _((struct strscanner *p, long beg_i, long len));
@@ -127,13 +138,6 @@ static VALUE inspect2 _((struct strscanner *p));
======================================================================= */
static VALUE
-infect(VALUE str, struct strscanner *p)
-{
- OBJ_INFECT(str, p->str);
- return str;
-}
-
-static VALUE
str_new(struct strscanner *p, const char *ptr, long len)
{
VALUE str = rb_str_new(ptr, len);
@@ -152,7 +156,7 @@ extract_range(struct strscanner *p, long beg_i, long end_i)
{
if (beg_i > S_LEN(p)) return Qnil;
end_i = minl(end_i, S_LEN(p));
- return infect(str_new(p, S_PBEG(p) + beg_i, end_i - beg_i), p);
+ return str_new(p, S_PBEG(p) + beg_i, end_i - beg_i);
}
static VALUE
@@ -160,7 +164,7 @@ extract_beg_len(struct strscanner *p, long beg_i, long len)
{
if (beg_i > S_LEN(p)) return Qnil;
len = minl(len, S_LEN(p) - beg_i);
- return infect(str_new(p, S_PBEG(p) + beg_i, len), p);
+ return str_new(p, S_PBEG(p) + beg_i, len);
}
/* =======================================================================
@@ -172,6 +176,7 @@ strscan_mark(void *ptr)
{
struct strscanner *p = ptr;
rb_gc_mark(p->str);
+ rb_gc_mark(p->regex);
}
static void
@@ -186,7 +191,11 @@ static size_t
strscan_memsize(const void *ptr)
{
const struct strscanner *p = ptr;
- return sizeof(*p) - sizeof(p->regs) + onig_region_memsize(&p->regs);
+ size_t size = sizeof(*p) - sizeof(p->regs);
+#ifdef HAVE_ONIG_REGION_MEMSIZE
+ size += onig_region_memsize(&p->regs);
+#endif
+ return size;
}
static const rb_data_type_t strscanner_type = {
@@ -204,23 +213,46 @@ strscan_s_allocate(VALUE klass)
CLEAR_MATCH_STATUS(p);
onig_region_init(&(p->regs));
p->str = Qnil;
+ p->regex = Qnil;
return obj;
}
/*
- * call-seq: StringScanner.new(string, dup = false)
+ * call-seq:
+ * StringScanner.new(string, fixed_anchor: false)
+ * StringScanner.new(string, dup = false)
*
* Creates a new StringScanner object to scan over the given +string+.
+ *
+ * If +fixed_anchor+ is +true+, +\A+ always matches the beginning of
+ * the string. Otherwise, +\A+ always matches the current position.
+ *
* +dup+ argument is obsolete and not used now.
*/
static VALUE
strscan_initialize(int argc, VALUE *argv, VALUE self)
{
struct strscanner *p;
- VALUE str, need_dup;
+ VALUE str, options;
p = check_strscan(self);
- rb_scan_args(argc, argv, "11", &str, &need_dup);
+ rb_scan_args(argc, argv, "11", &str, &options);
+ options = rb_check_hash_type(options);
+ if (!NIL_P(options)) {
+ VALUE fixed_anchor;
+ ID keyword_ids[1];
+ keyword_ids[0] = rb_intern("fixed_anchor");
+ rb_get_kwargs(options, keyword_ids, 0, 1, &fixed_anchor);
+ if (fixed_anchor == Qundef) {
+ p->fixed_anchor_p = false;
+ }
+ else {
+ p->fixed_anchor_p = RTEST(fixed_anchor);
+ }
+ }
+ else {
+ p->fixed_anchor_p = false;
+ }
StringValue(str);
p->str = str;
@@ -294,7 +326,7 @@ strscan_reset(VALUE self)
* terminate
* clear
*
- * Set the scan pointer to the end of the string and clear matching data.
+ * Sets the scan pointer to the end of the string and clear matching data.
*/
static VALUE
strscan_terminate(VALUE self)
@@ -413,19 +445,16 @@ static VALUE
strscan_get_charpos(VALUE self)
{
struct strscanner *p;
- VALUE substr;
GET_SCANNER(self, p);
- substr = rb_funcall(p->str, id_byteslice, 2, INT2FIX(0), INT2NUM(p->curr));
-
- return rb_str_length(substr);
+ return LONG2NUM(rb_enc_strlen(S_PBEG(p), CURPTR(p), rb_enc_get(p->str)));
}
/*
* call-seq: pos=(n)
*
- * Set the byte position of the scan pointer.
+ * Sets the byte position of the scan pointer.
*
* s = StringScanner.new('test string')
* s.pos = 7 # -> 7
@@ -443,19 +472,86 @@ strscan_set_pos(VALUE self, VALUE v)
if (i < 0) rb_raise(rb_eRangeError, "index out of range");
if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range");
p->curr = i;
- return INT2NUM(i);
+ return LONG2NUM(i);
+}
+
+static inline UChar *
+match_target(struct strscanner *p)
+{
+ if (p->fixed_anchor_p) {
+ return (UChar *)S_PBEG(p);
+ }
+ else
+ {
+ return (UChar *)CURPTR(p);
+ }
+}
+
+static inline void
+set_registers(struct strscanner *p, size_t length)
+{
+ const int at = 0;
+ OnigRegion *regs = &(p->regs);
+ onig_region_clear(regs);
+ if (onig_region_set(regs, at, 0, 0)) return;
+ if (p->fixed_anchor_p) {
+ regs->beg[at] = p->curr;
+ regs->end[at] = p->curr + length;
+ }
+ else
+ {
+ regs->end[at] = length;
+ }
+}
+
+static inline void
+succ(struct strscanner *p)
+{
+ if (p->fixed_anchor_p) {
+ p->curr = p->regs.end[0];
+ }
+ else
+ {
+ p->curr += p->regs.end[0];
+ }
+}
+
+static inline long
+last_match_length(struct strscanner *p)
+{
+ if (p->fixed_anchor_p) {
+ return p->regs.end[0] - p->prev;
+ }
+ else
+ {
+ return p->regs.end[0];
+ }
+}
+
+static inline long
+adjust_register_position(struct strscanner *p, long position)
+{
+ if (p->fixed_anchor_p) {
+ return position;
+ }
+ else {
+ return p->prev + position;
+ }
}
static VALUE
-strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
+strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly)
{
- regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
struct strscanner *p;
- regex_t *re;
- long ret;
- int tmpreg;
- Check_Type(regex, T_REGEXP);
+ if (headonly) {
+ if (!RB_TYPE_P(pattern, T_REGEXP)) {
+ StringValue(pattern);
+ }
+ }
+ else {
+ Check_Type(pattern, T_REGEXP);
+ }
GET_SCANNER(self, p);
CLEAR_MATCH_STATUS(p);
@@ -463,49 +559,76 @@ strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
return Qnil;
}
- p->regex = regex;
- re = rb_reg_prepare_re(regex, p->str);
- tmpreg = re != RREGEXP_PTR(regex);
- if (!tmpreg) RREGEXP(regex)->usecnt++;
+ if (RB_TYPE_P(pattern, T_REGEXP)) {
+ regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
+ regex_t *re;
+ long ret;
+ int tmpreg;
+
+ p->regex = pattern;
+ re = rb_reg_prepare_re(pattern, p->str);
+ tmpreg = re != RREGEXP_PTR(pattern);
+ if (!tmpreg) RREGEXP(pattern)->usecnt++;
+
+ if (headonly) {
+ ret = onig_match(re,
+ match_target(p),
+ (UChar* )(CURPTR(p) + S_RESTLEN(p)),
+ (UChar* )CURPTR(p),
+ &(p->regs),
+ ONIG_OPTION_NONE);
+ }
+ else {
+ ret = onig_search(re,
+ match_target(p),
+ (UChar* )(CURPTR(p) + S_RESTLEN(p)),
+ (UChar* )CURPTR(p),
+ (UChar* )(CURPTR(p) + S_RESTLEN(p)),
+ &(p->regs),
+ ONIG_OPTION_NONE);
+ }
+ if (!tmpreg) RREGEXP(pattern)->usecnt--;
+ if (tmpreg) {
+ if (RREGEXP(pattern)->usecnt) {
+ onig_free(re);
+ }
+ else {
+ onig_free(RREGEXP_PTR(pattern));
+ RREGEXP_PTR(pattern) = re;
+ }
+ }
- if (headonly) {
- ret = onig_match(re, (UChar* )CURPTR(p),
- (UChar* )(CURPTR(p) + S_RESTLEN(p)),
- (UChar* )CURPTR(p), &(p->regs), ONIG_OPTION_NONE);
+ if (ret == -2) rb_raise(ScanError, "regexp buffer overflow");
+ if (ret < 0) {
+ /* not matched */
+ return Qnil;
+ }
}
else {
- ret = onig_search(re,
- (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
- (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
- &(p->regs), ONIG_OPTION_NONE);
- }
- if (!tmpreg) RREGEXP(regex)->usecnt--;
- if (tmpreg) {
- if (RREGEXP(regex)->usecnt) {
- onig_free(re);
+ rb_enc_check(p->str, pattern);
+ if (S_RESTLEN(p) < RSTRING_LEN(pattern)) {
+ return Qnil;
}
- else {
- onig_free(RREGEXP_PTR(regex));
- RREGEXP_PTR(regex) = re;
+ if (memcmp(CURPTR(p), RSTRING_PTR(pattern), RSTRING_LEN(pattern)) != 0) {
+ return Qnil;
}
- }
-
- if (ret == -2) rb_raise(ScanError, "regexp buffer overflow");
- if (ret < 0) {
- /* not matched */
- return Qnil;
+ set_registers(p, RSTRING_LEN(pattern));
}
MATCHED(p);
p->prev = p->curr;
+
if (succptr) {
- p->curr += p->regs.end[0];
+ succ(p);
}
- if (getstr) {
- return extract_beg_len(p, p->prev, p->regs.end[0]);
- }
- else {
- return INT2FIX(p->regs.end[0]);
+ {
+ const long length = last_match_length(p);
+ if (getstr) {
+ return extract_beg_len(p, p->prev, length);
+ }
+ else {
+ return INT2FIX(length);
+ }
}
}
@@ -520,7 +643,8 @@ strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
* p s.scan(/\w+/) # -> "test"
* p s.scan(/\w+/) # -> nil
* p s.scan(/\s+/) # -> " "
- * p s.scan(/\w+/) # -> "string"
+ * p s.scan("str") # -> "str"
+ * p s.scan(/\w+/) # -> "ing"
* p s.scan(/./) # -> nil
*
*/
@@ -539,6 +663,7 @@ strscan_scan(VALUE self, VALUE re)
* s = StringScanner.new('test string')
* p s.match?(/\w+/) # -> 4
* p s.match?(/\w+/) # -> 4
+ * p s.match?("test") # -> 4
* p s.match?(/\s+/) # -> nil
*/
static VALUE
@@ -560,7 +685,8 @@ strscan_match_p(VALUE self, VALUE re)
* p s.skip(/\w+/) # -> 4
* p s.skip(/\w+/) # -> nil
* p s.skip(/\s+/) # -> 1
- * p s.skip(/\w+/) # -> 6
+ * p s.skip("st") # -> 2
+ * p s.skip(/\w+/) # -> 4
* p s.skip(/./) # -> nil
*
*/
@@ -704,7 +830,12 @@ static void
adjust_registers_to_matched(struct strscanner *p)
{
onig_region_clear(&(p->regs));
- onig_region_set(&(p->regs), 0, 0, (int)(p->curr - p->prev));
+ if (p->fixed_anchor_p) {
+ onig_region_set(&(p->regs), 0, (int)p->prev, (int)p->curr);
+ }
+ else {
+ onig_region_set(&(p->regs), 0, 0, (int)(p->curr - p->prev));
+ }
}
/*
@@ -716,9 +847,8 @@ adjust_registers_to_matched(struct strscanner *p)
* s.getch # => "b"
* s.getch # => nil
*
- * $KCODE = 'EUC'
- * s = StringScanner.new("\244\242")
- * s.getch # => "\244\242" # Japanese hira-kana "A" in EUC-JP
+ * s = StringScanner.new("\244\242".force_encoding("euc-jp"))
+ * s.getch # => "\x{A4A2}" # Japanese hira-kana "A" in EUC-JP
* s.getch # => nil
*/
static VALUE
@@ -738,8 +868,9 @@ strscan_getch(VALUE self)
p->curr += len;
MATCHED(p);
adjust_registers_to_matched(p);
- return extract_range(p, p->prev + p->regs.beg[0],
- p->prev + p->regs.end[0]);
+ return extract_range(p,
+ adjust_register_position(p, p->regs.beg[0]),
+ adjust_register_position(p, p->regs.end[0]));
}
/*
@@ -752,10 +883,9 @@ strscan_getch(VALUE self)
* s.get_byte # => "b"
* s.get_byte # => nil
*
- * $KCODE = 'EUC'
- * s = StringScanner.new("\244\242")
- * s.get_byte # => "\244"
- * s.get_byte # => "\242"
+ * s = StringScanner.new("\244\242".force_encoding("euc-jp"))
+ * s.get_byte # => "\xA4"
+ * s.get_byte # => "\xA2"
* s.get_byte # => nil
*/
static VALUE
@@ -772,8 +902,9 @@ strscan_get_byte(VALUE self)
p->curr++;
MATCHED(p);
adjust_registers_to_matched(p);
- return extract_range(p, p->prev + p->regs.beg[0],
- p->prev + p->regs.end[0]);
+ return extract_range(p,
+ adjust_register_position(p, p->regs.beg[0]),
+ adjust_register_position(p, p->regs.end[0]));
}
/*
@@ -808,7 +939,7 @@ strscan_peek(VALUE self, VALUE vlen)
len = NUM2LONG(vlen);
if (EOS_P(p))
- return infect(str_new(p, "", 0), p);
+ return str_new(p, "", 0);
len = minl(len, S_RESTLEN(p));
return extract_beg_len(p, p->curr, len);
@@ -826,7 +957,7 @@ strscan_peep(VALUE self, VALUE vlen)
}
/*
- * Set the scan pointer to the previous position. Only one previous position is
+ * Sets the scan pointer to the previous position. Only one previous position is
* remembered, and it changes with each scanning operation.
*
* s = StringScanner.new('test string')
@@ -850,7 +981,7 @@ strscan_unscan(VALUE self)
}
/*
- * Returns +true+ iff the scan pointer is at the beginning of the line.
+ * Returns +true+ if and only if the scan pointer is at the beginning of the line.
*
* s = StringScanner.new("test\ntest\n")
* s.bol? # => true
@@ -903,7 +1034,7 @@ strscan_empty_p(VALUE self)
}
/*
- * Returns true iff there is more data in the string. See #eos?.
+ * Returns true if and only if there is more data in the string. See #eos?.
* This method is obsolete; use #eos? instead.
*
* s = StringScanner.new('test string')
@@ -920,7 +1051,7 @@ strscan_rest_p(VALUE self)
}
/*
- * Returns +true+ iff the last match was successful.
+ * Returns +true+ if and only if the last match was successful.
*
* s = StringScanner.new('test string')
* s.match?(/\w+/) # => 4
@@ -951,13 +1082,15 @@ strscan_matched(VALUE self)
GET_SCANNER(self, p);
if (! MATCHED_P(p)) return Qnil;
- return extract_range(p, p->prev + p->regs.beg[0],
- p->prev + p->regs.end[0]);
+ return extract_range(p,
+ adjust_register_position(p, p->regs.beg[0]),
+ adjust_register_position(p, p->regs.end[0]));
}
/*
- * Returns the size of the most recent match (see #matched), or +nil+ if there
- * was no recent match.
+ * Returns the size of the most recent match in bytes, or +nil+ if there
+ * was no recent match. This is different than <tt>matched.size</tt>,
+ * which will return the size in characters.
*
* s = StringScanner.new('test string')
* s.check /\w+/ # -> "test"
@@ -972,7 +1105,7 @@ strscan_matched_size(VALUE self)
GET_SCANNER(self, p);
if (! MATCHED_P(p)) return Qnil;
- return INT2NUM(p->regs.end[0] - p->regs.beg[0]);
+ return LONG2NUM(p->regs.end[0] - p->regs.beg[0]);
}
static int
@@ -996,7 +1129,7 @@ name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name
/*
* call-seq: [](n)
*
- * Return the n-th subgroup in the most recent match.
+ * Returns the n-th subgroup in the most recent match.
*
* s = StringScanner.new("Fri Dec 12 1975 14:39")
* s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
@@ -1034,7 +1167,7 @@ strscan_aref(VALUE self, VALUE idx)
idx = rb_sym2str(idx);
/* fall through */
case T_STRING:
- if (!p->regex) return Qnil;
+ if (!RTEST(p->regex)) return Qnil;
RSTRING_GETMEM(idx, name, i);
i = name_to_backref_number(&(p->regs), p->regex, name, name + i, rb_enc_get(idx));
break;
@@ -1048,12 +1181,100 @@ strscan_aref(VALUE self, VALUE idx)
if (i >= p->regs.num_regs) return Qnil;
if (p->regs.beg[i] == -1) return Qnil;
- return extract_range(p, p->prev + p->regs.beg[i],
- p->prev + p->regs.end[i]);
+ return extract_range(p,
+ adjust_register_position(p, p->regs.beg[i]),
+ adjust_register_position(p, p->regs.end[i]));
}
/*
- * Return the <i><b>pre</b>-match</i> (in the regular expression sense) of the last scan.
+ * call-seq: size
+ *
+ * Returns the amount of subgroups in the most recent match.
+ * The full match counts as a subgroup.
+ *
+ * s = StringScanner.new("Fri Dec 12 1975 14:39")
+ * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
+ * s.size # -> 4
+ */
+static VALUE
+strscan_size(VALUE self)
+{
+ struct strscanner *p;
+
+ GET_SCANNER(self, p);
+ if (! MATCHED_P(p)) return Qnil;
+ return INT2FIX(p->regs.num_regs);
+}
+
+/*
+ * call-seq: captures
+ *
+ * Returns the subgroups in the most recent match (not including the full match).
+ * If nothing was priorly matched, it returns nil.
+ *
+ * s = StringScanner.new("Fri Dec 12 1975 14:39")
+ * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
+ * s.captures # -> ["Fri", "Dec", "12"]
+ * s.scan(/(\w+) (\w+) (\d+) /) # -> nil
+ * s.captures # -> nil
+ */
+static VALUE
+strscan_captures(VALUE self)
+{
+ struct strscanner *p;
+ int i, num_regs;
+ VALUE new_ary;
+
+ GET_SCANNER(self, p);
+ if (! MATCHED_P(p)) return Qnil;
+
+ num_regs = p->regs.num_regs;
+ new_ary = rb_ary_new2(num_regs);
+
+ for (i = 1; i < num_regs; i++) {
+ VALUE str = extract_range(p,
+ adjust_register_position(p, p->regs.beg[i]),
+ adjust_register_position(p, p->regs.end[i]));
+ rb_ary_push(new_ary, str);
+ }
+
+ return new_ary;
+}
+
+/*
+ * call-seq:
+ * scanner.values_at( i1, i2, ... iN ) -> an_array
+ *
+ * Returns the subgroups in the most recent match at the given indices.
+ * If nothing was priorly matched, it returns nil.
+ *
+ * s = StringScanner.new("Fri Dec 12 1975 14:39")
+ * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
+ * s.values_at 0, -1, 5, 2 # -> ["Fri Dec 12 ", "12", nil, "Dec"]
+ * s.scan(/(\w+) (\w+) (\d+) /) # -> nil
+ * s.values_at 0, -1, 5, 2 # -> nil
+ */
+
+static VALUE
+strscan_values_at(int argc, VALUE *argv, VALUE self)
+{
+ struct strscanner *p;
+ long i;
+ VALUE new_ary;
+
+ GET_SCANNER(self, p);
+ if (! MATCHED_P(p)) return Qnil;
+
+ new_ary = rb_ary_new2(argc);
+ for (i = 0; i<argc; i++) {
+ rb_ary_push(new_ary, strscan_aref(self, argv[i]));
+ }
+
+ return new_ary;
+}
+
+/*
+ * Returns the <i><b>pre</b>-match</i> (in the regular expression sense) of the last scan.
*
* s = StringScanner.new('test string')
* s.scan(/\w+/) # -> "test"
@@ -1068,11 +1289,13 @@ strscan_pre_match(VALUE self)
GET_SCANNER(self, p);
if (! MATCHED_P(p)) return Qnil;
- return extract_range(p, 0, p->prev + p->regs.beg[0]);
+ return extract_range(p,
+ 0,
+ adjust_register_position(p, p->regs.beg[0]));
}
/*
- * Return the <i><b>post</b>-match</i> (in the regular expression sense) of the last scan.
+ * Returns the <i><b>post</b>-match</i> (in the regular expression sense) of the last scan.
*
* s = StringScanner.new('test string')
* s.scan(/\w+/) # -> "test"
@@ -1087,7 +1310,9 @@ strscan_post_match(VALUE self)
GET_SCANNER(self, p);
if (! MATCHED_P(p)) return Qnil;
- return extract_range(p, p->prev + p->regs.end[0], S_LEN(p));
+ return extract_range(p,
+ adjust_register_position(p, p->regs.end[0]),
+ S_LEN(p));
}
/*
@@ -1101,7 +1326,7 @@ strscan_rest(VALUE self)
GET_SCANNER(self, p);
if (EOS_P(p)) {
- return infect(str_new(p, "", 0), p);
+ return str_new(p, "", 0);
}
return extract_range(p, p->curr, S_LEN(p));
}
@@ -1156,11 +1381,11 @@ strscan_inspect(VALUE self)
p = check_strscan(self);
if (NIL_P(p->str)) {
a = rb_sprintf("#<%"PRIsVALUE" (uninitialized)>", rb_obj_class(self));
- return infect(a, p);
+ return a;
}
if (EOS_P(p)) {
a = rb_sprintf("#<%"PRIsVALUE" fin>", rb_obj_class(self));
- return infect(a, p);
+ return a;
}
if (p->curr == 0) {
b = inspect2(p);
@@ -1168,7 +1393,7 @@ strscan_inspect(VALUE self)
rb_obj_class(self),
p->curr, S_LEN(p),
b);
- return infect(a, p);
+ return a;
}
a = inspect1(p);
b = inspect2(p);
@@ -1176,7 +1401,7 @@ strscan_inspect(VALUE self)
rb_obj_class(self),
p->curr, S_LEN(p),
a, b);
- return infect(a, p);
+ return a;
}
static VALUE
@@ -1216,6 +1441,23 @@ inspect2(struct strscanner *p)
return rb_str_dump(str);
}
+/*
+ * call-seq:
+ * scanner.fixed_anchor? -> true or false
+ *
+ * Whether +scanner+ uses fixed anchor mode or not.
+ *
+ * If fixed anchor mode is used, +\A+ always matches the beginning of
+ * the string. Otherwise, +\A+ always matches the current position.
+ */
+static VALUE
+strscan_fixed_anchor_p(VALUE self)
+{
+ struct strscanner *p;
+ p = check_strscan(self);
+ return p->fixed_anchor_p ? Qtrue : Qfalse;
+}
+
/* =======================================================================
Ruby Interface
======================================================================= */
@@ -1292,7 +1534,7 @@ inspect2(struct strscanner *p)
*
* === Finding Where we Are
*
- * - #beginning_of_line? (#bol?)
+ * - #beginning_of_line? (<tt>#bol?</tt>)
* - #eos?
* - #rest?
* - #rest_size
@@ -1309,13 +1551,13 @@ inspect2(struct strscanner *p)
* - #matched
* - #matched?
* - #matched_size
- * - []
+ * - <tt>#[]</tt>
* - #pre_match
* - #post_match
*
* === Miscellaneous
*
- * - <<
+ * - <tt><<</tt>
* - #concat
* - #string
* - #string=
@@ -1326,6 +1568,11 @@ inspect2(struct strscanner *p)
void
Init_strscan(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+#undef rb_intern
ID id_scanerr = rb_intern("ScanError");
VALUE tmp;
@@ -1392,10 +1639,15 @@ Init_strscan(void)
rb_define_method(StringScanner, "[]", strscan_aref, 1);
rb_define_method(StringScanner, "pre_match", strscan_pre_match, 0);
rb_define_method(StringScanner, "post_match", strscan_post_match, 0);
+ rb_define_method(StringScanner, "size", strscan_size, 0);
+ rb_define_method(StringScanner, "captures", strscan_captures, 0);
+ rb_define_method(StringScanner, "values_at", strscan_values_at, -1);
rb_define_method(StringScanner, "rest", strscan_rest, 0);
rb_define_method(StringScanner, "rest_size", strscan_rest_size, 0);
rb_define_method(StringScanner, "restsize", strscan_restsize, 0);
rb_define_method(StringScanner, "inspect", strscan_inspect, 0);
+
+ rb_define_method(StringScanner, "fixed_anchor?", strscan_fixed_anchor_p, 0);
}
diff --git a/ext/strscan/strscan.gemspec b/ext/strscan/strscan.gemspec
index f5dd550ea6..5d8119ea4c 100644
--- a/ext/strscan/strscan.gemspec
+++ b/ext/strscan/strscan.gemspec
@@ -1,20 +1,28 @@
# frozen_string_literal: true
+#
+source_version = ["", "ext/strscan/"].find do |dir|
+ begin
+ break File.open(File.join(__dir__, "#{dir}strscan.c")) {|f|
+ f.gets("\n#define STRSCAN_VERSION ")
+ f.gets[/\s*"(.+)"/, 1]
+ }
+ rescue Errno::ENOENT
+ end
+end
+
Gem::Specification.new do |s|
s.name = "strscan"
- s.version = '0.0.1'
- s.date = '2017-02-07'
+ s.version = source_version
s.summary = "Provides lexical scanning operations on a String."
s.description = "Provides lexical scanning operations on a String."
s.require_path = %w{lib}
- s.files = %w{ext/strscan/extconf.rb ext/strscan/strscan.c ext/strscan/regenc.h ext/strscan/regint.h}
- s.extensions = %w{extconf.rb}
- s.required_ruby_version = ">= 2.5.0dev"
+ s.files = %w{ext/strscan/extconf.rb ext/strscan/strscan.c}
+ s.extensions = %w{ext/strscan/extconf.rb}
+ s.required_ruby_version = ">= 2.4.0"
- s.authors = ["Minero Aoki"]
- s.email = [nil]
+ s.authors = ["Minero Aoki", "Sutou Kouhei"]
+ s.email = [nil, "kou@cozmixng.org"]
s.homepage = "https://github.com/ruby/strscan"
- s.license = "BSD-2-Clause"
-
- s.add_development_dependency "rake-compiler"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
end
diff --git a/ext/syslog/depend b/ext/syslog/depend
index ee2ad79052..4c0ef0ebac 100644
--- a/ext/syslog/depend
+++ b/ext/syslog/depend
@@ -1,7 +1,157 @@
# AUTOGENERATED DEPENDENCIES START
syslog.o: $(RUBY_EXTCONF_H)
syslog.o: $(arch_hdrdir)/ruby/config.h
+syslog.o: $(hdrdir)/ruby/internal/anyargs.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+syslog.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+syslog.o: $(hdrdir)/ruby/internal/assume.h
+syslog.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+syslog.o: $(hdrdir)/ruby/internal/attr/artificial.h
+syslog.o: $(hdrdir)/ruby/internal/attr/cold.h
+syslog.o: $(hdrdir)/ruby/internal/attr/const.h
+syslog.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+syslog.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+syslog.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+syslog.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+syslog.o: $(hdrdir)/ruby/internal/attr/error.h
+syslog.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+syslog.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+syslog.o: $(hdrdir)/ruby/internal/attr/format.h
+syslog.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+syslog.o: $(hdrdir)/ruby/internal/attr/noalias.h
+syslog.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+syslog.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+syslog.o: $(hdrdir)/ruby/internal/attr/noinline.h
+syslog.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+syslog.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+syslog.o: $(hdrdir)/ruby/internal/attr/pure.h
+syslog.o: $(hdrdir)/ruby/internal/attr/restrict.h
+syslog.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+syslog.o: $(hdrdir)/ruby/internal/attr/warning.h
+syslog.o: $(hdrdir)/ruby/internal/attr/weakref.h
+syslog.o: $(hdrdir)/ruby/internal/cast.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_is.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+syslog.o: $(hdrdir)/ruby/internal/compiler_since.h
+syslog.o: $(hdrdir)/ruby/internal/config.h
+syslog.o: $(hdrdir)/ruby/internal/constant_p.h
+syslog.o: $(hdrdir)/ruby/internal/core.h
+syslog.o: $(hdrdir)/ruby/internal/core/rarray.h
+syslog.o: $(hdrdir)/ruby/internal/core/rbasic.h
+syslog.o: $(hdrdir)/ruby/internal/core/rbignum.h
+syslog.o: $(hdrdir)/ruby/internal/core/rclass.h
+syslog.o: $(hdrdir)/ruby/internal/core/rdata.h
+syslog.o: $(hdrdir)/ruby/internal/core/rfile.h
+syslog.o: $(hdrdir)/ruby/internal/core/rhash.h
+syslog.o: $(hdrdir)/ruby/internal/core/robject.h
+syslog.o: $(hdrdir)/ruby/internal/core/rregexp.h
+syslog.o: $(hdrdir)/ruby/internal/core/rstring.h
+syslog.o: $(hdrdir)/ruby/internal/core/rstruct.h
+syslog.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+syslog.o: $(hdrdir)/ruby/internal/ctype.h
+syslog.o: $(hdrdir)/ruby/internal/dllexport.h
+syslog.o: $(hdrdir)/ruby/internal/dosish.h
+syslog.o: $(hdrdir)/ruby/internal/error.h
+syslog.o: $(hdrdir)/ruby/internal/eval.h
+syslog.o: $(hdrdir)/ruby/internal/event.h
+syslog.o: $(hdrdir)/ruby/internal/fl_type.h
+syslog.o: $(hdrdir)/ruby/internal/gc.h
+syslog.o: $(hdrdir)/ruby/internal/glob.h
+syslog.o: $(hdrdir)/ruby/internal/globals.h
+syslog.o: $(hdrdir)/ruby/internal/has/attribute.h
+syslog.o: $(hdrdir)/ruby/internal/has/builtin.h
+syslog.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+syslog.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+syslog.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+syslog.o: $(hdrdir)/ruby/internal/has/extension.h
+syslog.o: $(hdrdir)/ruby/internal/has/feature.h
+syslog.o: $(hdrdir)/ruby/internal/has/warning.h
+syslog.o: $(hdrdir)/ruby/internal/intern/array.h
+syslog.o: $(hdrdir)/ruby/internal/intern/bignum.h
+syslog.o: $(hdrdir)/ruby/internal/intern/class.h
+syslog.o: $(hdrdir)/ruby/internal/intern/compar.h
+syslog.o: $(hdrdir)/ruby/internal/intern/complex.h
+syslog.o: $(hdrdir)/ruby/internal/intern/cont.h
+syslog.o: $(hdrdir)/ruby/internal/intern/dir.h
+syslog.o: $(hdrdir)/ruby/internal/intern/enum.h
+syslog.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+syslog.o: $(hdrdir)/ruby/internal/intern/error.h
+syslog.o: $(hdrdir)/ruby/internal/intern/eval.h
+syslog.o: $(hdrdir)/ruby/internal/intern/file.h
+syslog.o: $(hdrdir)/ruby/internal/intern/gc.h
+syslog.o: $(hdrdir)/ruby/internal/intern/hash.h
+syslog.o: $(hdrdir)/ruby/internal/intern/io.h
+syslog.o: $(hdrdir)/ruby/internal/intern/load.h
+syslog.o: $(hdrdir)/ruby/internal/intern/marshal.h
+syslog.o: $(hdrdir)/ruby/internal/intern/numeric.h
+syslog.o: $(hdrdir)/ruby/internal/intern/object.h
+syslog.o: $(hdrdir)/ruby/internal/intern/parse.h
+syslog.o: $(hdrdir)/ruby/internal/intern/proc.h
+syslog.o: $(hdrdir)/ruby/internal/intern/process.h
+syslog.o: $(hdrdir)/ruby/internal/intern/random.h
+syslog.o: $(hdrdir)/ruby/internal/intern/range.h
+syslog.o: $(hdrdir)/ruby/internal/intern/rational.h
+syslog.o: $(hdrdir)/ruby/internal/intern/re.h
+syslog.o: $(hdrdir)/ruby/internal/intern/ruby.h
+syslog.o: $(hdrdir)/ruby/internal/intern/select.h
+syslog.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+syslog.o: $(hdrdir)/ruby/internal/intern/signal.h
+syslog.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+syslog.o: $(hdrdir)/ruby/internal/intern/string.h
+syslog.o: $(hdrdir)/ruby/internal/intern/struct.h
+syslog.o: $(hdrdir)/ruby/internal/intern/thread.h
+syslog.o: $(hdrdir)/ruby/internal/intern/time.h
+syslog.o: $(hdrdir)/ruby/internal/intern/variable.h
+syslog.o: $(hdrdir)/ruby/internal/intern/vm.h
+syslog.o: $(hdrdir)/ruby/internal/interpreter.h
+syslog.o: $(hdrdir)/ruby/internal/iterator.h
+syslog.o: $(hdrdir)/ruby/internal/memory.h
+syslog.o: $(hdrdir)/ruby/internal/method.h
+syslog.o: $(hdrdir)/ruby/internal/module.h
+syslog.o: $(hdrdir)/ruby/internal/newobj.h
+syslog.o: $(hdrdir)/ruby/internal/rgengc.h
+syslog.o: $(hdrdir)/ruby/internal/scan_args.h
+syslog.o: $(hdrdir)/ruby/internal/special_consts.h
+syslog.o: $(hdrdir)/ruby/internal/static_assert.h
+syslog.o: $(hdrdir)/ruby/internal/stdalign.h
+syslog.o: $(hdrdir)/ruby/internal/stdbool.h
+syslog.o: $(hdrdir)/ruby/internal/symbol.h
+syslog.o: $(hdrdir)/ruby/internal/token_paste.h
+syslog.o: $(hdrdir)/ruby/internal/value.h
+syslog.o: $(hdrdir)/ruby/internal/value_type.h
+syslog.o: $(hdrdir)/ruby/internal/variable.h
+syslog.o: $(hdrdir)/ruby/internal/warning_push.h
+syslog.o: $(hdrdir)/ruby/internal/xmalloc.h
+syslog.o: $(hdrdir)/ruby/assert.h
syslog.o: $(hdrdir)/ruby/backward.h
+syslog.o: $(hdrdir)/ruby/backward/2/assume.h
+syslog.o: $(hdrdir)/ruby/backward/2/attributes.h
+syslog.o: $(hdrdir)/ruby/backward/2/bool.h
+syslog.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+syslog.o: $(hdrdir)/ruby/backward/2/inttypes.h
+syslog.o: $(hdrdir)/ruby/backward/2/limits.h
+syslog.o: $(hdrdir)/ruby/backward/2/long_long.h
+syslog.o: $(hdrdir)/ruby/backward/2/stdalign.h
+syslog.o: $(hdrdir)/ruby/backward/2/stdarg.h
syslog.o: $(hdrdir)/ruby/defines.h
syslog.o: $(hdrdir)/ruby/intern.h
syslog.o: $(hdrdir)/ruby/missing.h
diff --git a/ext/syslog/extconf.rb b/ext/syslog/extconf.rb
index 3bfea1fa73..1230a4d52e 100644
--- a/ext/syslog/extconf.rb
+++ b/ext/syslog/extconf.rb
@@ -4,6 +4,8 @@
require 'mkmf'
+have_library("log") # for Android
+
have_header("syslog.h") &&
have_func("openlog") &&
have_func("setlogmask") &&
diff --git a/ext/syslog/lib/syslog/logger.rb b/ext/syslog/lib/syslog/logger.rb
index 06cbe5b19d..453ca2785c 100644
--- a/ext/syslog/lib/syslog/logger.rb
+++ b/ext/syslog/lib/syslog/logger.rb
@@ -112,7 +112,7 @@ class Syslog::Logger
end
def #{meth}?
- @level <= #{level}
+ level <= #{level}
end
EOM
end
@@ -202,7 +202,7 @@ class Syslog::Logger
def add severity, message = nil, progname = nil, &block
severity ||= ::Logger::UNKNOWN
- @level <= severity and
+ level <= severity and
@@syslog.log( (LEVEL_MAP[severity] | @facility), '%s', formatter.call(severity, Time.now, progname, (message || block.call)) )
true
end
diff --git a/ext/syslog/syslog.c b/ext/syslog/syslog.c
index 317607eeef..4c540fc9c7 100644
--- a/ext/syslog/syslog.c
+++ b/ext/syslog/syslog.c
@@ -162,7 +162,6 @@ static VALUE mSyslog_open(int argc, VALUE *argv, VALUE self)
ident = rb_gv_get("$0");
}
ident_ptr = StringValueCStr(ident);
- rb_check_safe_obj(ident);
syslog_ident = strdup(ident_ptr);
if (NIL_P(opt)) {
@@ -297,10 +296,6 @@ static VALUE mSyslog_set_mask(VALUE self, VALUE mask)
* Syslog.log(Syslog::LOG_ALERT, "Out of memory")
* Syslog.alert("Out of memory")
*
- * Format strings are as for printf/sprintf, except that in addition %m is
- * replaced with the error message string that would be returned by
- * strerror(errno).
- *
*/
static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)
{
@@ -420,6 +415,7 @@ static VALUE mSyslogMacros_included(VALUE mod, VALUE target)
*/
void Init_syslog(void)
{
+#undef rb_intern
mSyslog = rb_define_module("Syslog");
mSyslogConstants = rb_define_module_under(mSyslog, "Constants");
diff --git a/ext/syslog/syslog.gemspec b/ext/syslog/syslog.gemspec
new file mode 100644
index 0000000000..8f73f5ad0d
--- /dev/null
+++ b/ext/syslog/syslog.gemspec
@@ -0,0 +1,23 @@
+Gem::Specification.new do |spec|
+ spec.name = "syslog"
+ spec.version = "0.1.0"
+ spec.authors = ["Akinori MUSHA"]
+ spec.email = ["knu@idaemons.org"]
+
+ spec.summary = %q{Ruby interface for the POSIX system logging facility.}
+ spec.description = %q{Ruby interface for the POSIX system logging facility.}
+ spec.homepage = "https://github.com/ruby/syslog"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.extensions = ["ext/syslog/extconf.rb"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/ext/win32/depend b/ext/win32/depend
new file mode 100644
index 0000000000..0301ce074c
--- /dev/null
+++ b/ext/win32/depend
@@ -0,0 +1,2 @@
+# AUTOGENERATED DEPENDENCIES START
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/win32/lib/Win32API.rb b/ext/win32/lib/Win32API.rb
deleted file mode 100644
index d03ecc1c46..0000000000
--- a/ext/win32/lib/Win32API.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- ruby -*-
-# frozen_string_literal: true
-
-# for backward compatibility
-warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: Win32API is deprecated after Ruby 1.9.1; use fiddle directly instead" if $VERBOSE
-
-require 'fiddle/import'
-
-class Win32API
- DLL = {}
- TYPEMAP = {"0" => Fiddle::TYPE_VOID, "S" => Fiddle::TYPE_VOIDP, "I" => Fiddle::TYPE_LONG}
- POINTER_TYPE = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
-
- WIN32_TYPES = "VPpNnLlIi"
- DL_TYPES = "0SSI"
-
- def initialize(dllname, func, import, export = "0", calltype = :stdcall)
- @proto = [import].join.tr(WIN32_TYPES, DL_TYPES).sub(/^(.)0*$/, '\1')
- import = @proto.chars.map {|win_type| TYPEMAP[win_type.tr(WIN32_TYPES, DL_TYPES)]}
- export = TYPEMAP[export.tr(WIN32_TYPES, DL_TYPES)]
- calltype = Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[calltype]
-
- handle = DLL[dllname] ||=
- begin
- Fiddle.dlopen(dllname)
- rescue Fiddle::DLError
- raise unless File.extname(dllname).empty?
- Fiddle.dlopen(dllname + ".dll")
- end
-
- @func = Fiddle::Function.new(handle[func], import, export, calltype)
- rescue Fiddle::DLError => e
- raise LoadError, e.message, e.backtrace
- end
-
- def call(*args)
- import = @proto.split("")
- args.each_with_index do |x, i|
- args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
- args[i], = [x].pack("I").unpack("i") if import[i] == "I"
- end
- ret, = @func.call(*args)
- return ret || 0
- end
-
- alias Call call
-end
diff --git a/ext/win32/lib/win32/importer.rb b/ext/win32/lib/win32/importer.rb
deleted file mode 100644
index 2bef016c29..0000000000
--- a/ext/win32/lib/win32/importer.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: false
-require 'fiddle/import'
-
-module Win32
-end
-
-Win32.module_eval do
- Importer = Fiddle::Importer
-end
diff --git a/ext/win32/lib/win32/registry.rb b/ext/win32/lib/win32/registry.rb
index a88d7e63d0..ffc2979179 100644
--- a/ext/win32/lib/win32/registry.rb
+++ b/ext/win32/lib/win32/registry.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: false
-require 'win32/importer'
+require 'fiddle/import'
module Win32
@@ -169,7 +169,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
#
class Error < ::StandardError
module Kernel32
- extend Importer
+ extend Fiddle::Importer
dlload "kernel32.dll"
end
FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall
@@ -225,7 +225,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
#
module API
include Constants
- extend Importer
+ extend Fiddle::Importer
dlload "advapi32.dll"
[
"long RegOpenKeyExW(void *, void *, long, long, void *)",
@@ -575,9 +575,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
begin
type, data = read(subkey)
rescue Error
- next
+ else
+ yield subkey, type, data
end
- yield subkey, type, data
index += 1
end
index
@@ -635,7 +635,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
# Array of String
# :REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD
# Integer
- # :REG_BINARY
+ # :REG_BINARY, REG_NONE
# String (contains binary data)
#
# When rtype is specified, the value type must be included by
@@ -652,7 +652,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
[ type, data.encode(name.encoding, WCHAR).chop ]
when REG_MULTI_SZ
[ type, data.encode(name.encoding, WCHAR).split(/\0/) ]
- when REG_BINARY
+ when REG_BINARY, REG_NONE
[ type, data ]
when REG_DWORD
[ type, API.unpackdw(data) ]
@@ -748,7 +748,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
when REG_MULTI_SZ
data = data.to_a.map {|s| s.encode(WCHAR)}.join(WCHAR_NUL) << WCHAR_NUL
termsize = WCHAR_SIZE
- when REG_BINARY
+ when REG_BINARY, REG_NONE
data = data.to_s
when REG_DWORD
data = API.packdw(data.to_i)
diff --git a/ext/win32/lib/win32/resolv.rb b/ext/win32/lib/win32/resolv.rb
index 340a9b9d2b..d06658f0aa 100644
--- a/ext/win32/lib/win32/resolv.rb
+++ b/ext/win32/lib/win32/resolv.rb
@@ -42,19 +42,6 @@ begin
rescue LoadError
end
-nt = Module.new do
- break true if [nil].pack("p").size > 4
- extend Importer
- dlload "kernel32.dll"
- getv = extern "int GetVersionExA(void *)", :stdcall
- info = [ 148, 0, 0, 0, 0 ].pack('V5') + "\0" * 128
- getv.call(info)
- break info.unpack('V5')[4] == 2 # VER_PLATFORM_WIN32_NT
-end
-if not nt
- require_relative 'resolv9x'
- # return # does not work yet
-else
module Win32
#====================================================================
# Windows NT
@@ -146,4 +133,3 @@ module Win32
end
end
end
-end
diff --git a/ext/win32/lib/win32/resolv9x.rb b/ext/win32/lib/win32/resolv9x.rb
deleted file mode 100644
index a409d59c0c..0000000000
--- a/ext/win32/lib/win32/resolv9x.rb
+++ /dev/null
@@ -1,253 +0,0 @@
-#====================================================================
-# Windows 9x
-#====================================================================
-module Win32
- module Resolv
- TCPIP_9X = 'SYSTEM\CurrentControlSet\Services\VxD\MSTCP'
- DHCP_9X = 'SYSTEM\CurrentControlSet\Services\VxD\DHCP'
- WINDOWS = 'Software\Microsoft\Windows\CurrentVersion'
-
- class << self
- # private
-
- def get_hosts_dir
- Registry::HKEY_LOCAL_MACHINE.open(WINDOWS) do |reg|
- reg.read_s_expand('SystemRoot')
- end
- end
-
- def get_info
- search = []
- nameserver = []
- begin
- Registry::HKEY_LOCAL_MACHINE.open(TCPIP_9X) do |reg|
- if reg.read_s("EnableDNS") == "1"
- domain = reg.read_s("Domain")
- ns = reg.read_s("NameServer")
- slist = reg.read_s("SearchList")
- search << domain unless domain.empty?
- search.concat(slist.split(/,\s*/))
- nameserver.concat(ns.split(/[,\s]\s*/))
- end
- end
- rescue Registry::Error
- end
-
- dhcpinfo = get_dhcpinfo
- search.concat(dhcpinfo[0])
- nameserver.concat(dhcpinfo[1])
- [ search, nameserver ]
- end
-
- def get_dhcpinfo
- macaddrs = {}
- ipaddrs = {}
- WsControl.get_iflist.each do |index, macaddr, *ipaddr|
- macaddrs[macaddr] = 1
- ipaddr.each { |ipaddr| ipaddrs[ipaddr] = 1 }
- end
- iflist = [ macaddrs, ipaddrs ]
-
- search = []
- nameserver = []
- version = -1
- Registry::HKEY_LOCAL_MACHINE.open(DHCP_9X) do |reg|
- begin
- version = API.unpackdw(reg.read_bin("Version"))
- rescue Registry::Error
- end
-
- reg.each_key do |key, |
- catch(:not_used) do
- reg.open(key) do |regdi|
- dom, ns = get_dhcpinfo_key(version, regdi, iflist)
- search << dom if dom
- nameserver.concat(ns) if ns
- end
- end
- end
- end
- [ search, nameserver ]
- end
-
- def get_dhcpinfo_95(reg)
- dhcp = reg.read_bin("DhcpInfo")
- [
- API.unpackdw(dhcp[4..7]),
- API.unpackdw(dhcp[8..11]),
- 1,
- dhcp[45..50],
- reg.read_bin("OptionInfo"),
- ]
- end
-
- def get_dhcpinfo_98(reg)
- [
- API.unpackdw(reg.read_bin("DhcpIPAddress")),
- API.unpackdw(reg.read_bin("DhcpSubnetMask")),
- API.unpackdw(reg.read_bin("HardwareType")),
- reg.read_bin("HardwareAddress"),
- reg.read_bin("OptionInfo"),
- ]
- end
-
- def get_dhcpinfo_key(version, reg, iflist)
- info = case version
- when 1
- get_dhcpinfo_95(reg)
- when 2
- get_dhcpinfo_98(reg)
- else
- begin
- get_dhcpinfo_98(reg)
- rescue Registry::Error
- get_dhcpinfo_95(reg)
- end
- end
- ipaddr, netmask, hwtype, macaddr, opt = info
- throw :not_used unless
- ipaddr and ipaddr != 0 and
- netmask and netmask != 0 and
- macaddr and macaddr.size == 6 and
- hwtype == 1 and
- iflist[0][macaddr] and iflist[1][ipaddr]
-
- size = opt.size
- idx = 0
- while idx <= size
- opttype = opt[idx]
- optsize = opt[idx + 1]
- optval = opt[idx + 2, optsize]
- case opttype
- when 0xFF ## term
- break
- when 0x0F ## domain
- domain = optval.chomp("\0")
- when 0x06 ## dns
- nameserver = optval.scan(/..../).collect { |addr|
- "%d.%d.%d.%d" % addr.unpack('C4')
- }
- end
- idx += optsize + 2
- end
- [ domain, nameserver ]
- rescue Registry::Error
- throw :not_used
- end
- end
-
- module WsControl
- module WSock32
- extend Importer
- dlload "wsock32.dll"
- end
- WsControl = WSock32.extern "int WsControl(int, int, void *, void *, void *, void *)", :stdcall
- WSAGetLastError = WSock32.extern "int WSAGetLastError(void)", :stdcall
-
- MAX_TDI_ENTITIES = 512
- IPPROTO_TCP = 6
- WSCTL_TCP_QUERY_INFORMATION = 0
- INFO_CLASS_GENERIC = 0x100
- INFO_CLASS_PROTOCOL = 0x200
- INFO_TYPE_PROVIDER = 0x100
- ENTITY_LIST_ID = 0
- GENERIC_ENTITY = 0
- CL_NL_ENTITY = 0x301
- IF_ENTITY = 0x200
- ENTITY_TYPE_ID = 1
- CL_NL_IP = 0x303
- IF_MIB = 0x202
- IF_MIB_STATS_ID = 1
- IP_MIB_ADDRTABLE_ENTRY_ID = 0x102
-
- def self.wsctl(tei_entity, tei_instance,
- toi_class, toi_type, toi_id,
- buffsize)
- reqinfo = [
- ## TDIEntityID
- tei_entity, tei_instance,
- ## TDIObjectID
- toi_class, toi_type, toi_id,
- ## TCP_REQUEST_INFORMATION_EX
- ""
- ].pack('VVVVVa16')
- reqsize = API.packdw(reqinfo.size)
- buff = "\0" * buffsize
- buffsize = API.packdw(buffsize)
- result = WsControl.call(
- IPPROTO_TCP,
- WSCTL_TCP_QUERY_INFORMATION,
- reqinfo, reqsize,
- buff, buffsize)
- if result != 0
- raise RuntimeError, "WsControl failed.(#{result})"
- end
- [ buff, API.unpackdw(buffsize) ]
- end
- private_class_method :wsctl
-
- def self.get_iflist
- # Get TDI Entity List
- entities, size =
- wsctl(GENERIC_ENTITY, 0,
- INFO_CLASS_GENERIC,
- INFO_TYPE_PROVIDER,
- ENTITY_LIST_ID,
- MAX_TDI_ENTITIES * 8) # sizeof(TDIEntityID)
- entities = entities[0, size].
- scan(/.{8}/).
- collect { |e| e.unpack('VV') }
-
- # Get MIB Interface List
- iflist = []
- ifcount = 0
- entities.each do |entity, instance|
- if( (entity & IF_ENTITY)>0 )
- ifcount += 1
- etype, = wsctl(entity, instance,
- INFO_CLASS_GENERIC,
- INFO_TYPE_PROVIDER,
- ENTITY_TYPE_ID,
- 4)
- if( (API.unpackdw(etype) & IF_MIB)==IF_MIB )
- ifentry, = wsctl(entity, instance,
- INFO_CLASS_PROTOCOL,
- INFO_TYPE_PROVIDER,
- IF_MIB_STATS_ID,
- 21 * 4 + 8 + 130) # sizeof(IFEntry)
- iflist << [
- API.unpackdw(ifentry[0,4]),
- ifentry[20, 6]
- ]
- end
- end
- end
-
- # Get IP Addresses
- entities.each do |entity, instance|
- if entity == CL_NL_ENTITY
- etype, = wsctl(entity, instance,
- INFO_CLASS_GENERIC,
- INFO_TYPE_PROVIDER,
- ENTITY_TYPE_ID,
- 4)
- if API.unpackdw(etype) == CL_NL_IP
- ipentries, = wsctl(entity, instance,
- INFO_CLASS_PROTOCOL,
- INFO_TYPE_PROVIDER,
- IP_MIB_ADDRTABLE_ENTRY_ID,
- 24 * (ifcount+1)) # sizeof(IPAddrEntry)
- ipentries.scan(/.{24}/) do |ipentry|
- ipaddr, index = ipentry.unpack('VV')
- if ifitem = iflist.assoc(index)
- ifitem << ipaddr
- end
- end
- end
- end
- end
- iflist
- end
- end
- end
-end
diff --git a/ext/win32/lib/win32/sspi.rb b/ext/win32/lib/win32/sspi.rb
index 20441b389c..a73819f24e 100644
--- a/ext/win32/lib/win32/sspi.rb
+++ b/ext/win32/lib/win32/sspi.rb
@@ -11,321 +11,328 @@
# Ruby Distribution License or GNU General Public License.
#
-require 'Win32API'
+require 'fiddle/import'
# Implements bindings to Win32 SSPI functions, focused on authentication to a proxy server over HTTP.
module Win32
- module SSPI
- # Specifies how credential structure requested will be used. Only SECPKG_CRED_OUTBOUND is used
- # here.
- SECPKG_CRED_INBOUND = 0x00000001
- SECPKG_CRED_OUTBOUND = 0x00000002
- SECPKG_CRED_BOTH = 0x00000003
-
- # Format of token. NETWORK format is used here.
- SECURITY_NATIVE_DREP = 0x00000010
- SECURITY_NETWORK_DREP = 0x00000000
-
- # InitializeSecurityContext Requirement flags
- ISC_REQ_REPLAY_DETECT = 0x00000004
- ISC_REQ_SEQUENCE_DETECT = 0x00000008
- ISC_REQ_CONFIDENTIALITY = 0x00000010
- ISC_REQ_USE_SESSION_KEY = 0x00000020
- ISC_REQ_PROMPT_FOR_CREDS = 0x00000040
- ISC_REQ_CONNECTION = 0x00000800
-
- # Win32 API Functions. Uses Win32API to bind methods to constants contained in class.
- module API
- # Can be called with AcquireCredentialsHandle.call()
- AcquireCredentialsHandle = Win32API.new("secur32", "AcquireCredentialsHandle", 'ppLpppppp', 'L')
- # Can be called with InitializeSecurityContext.call()
- InitializeSecurityContext = Win32API.new("secur32", "InitializeSecurityContext", 'pppLLLpLpppp', 'L')
- # Can be called with DeleteSecurityContext.call()
- DeleteSecurityContext = Win32API.new("secur32", "DeleteSecurityContext", 'P', 'L')
- # Can be called with FreeCredentialsHandle.call()
- FreeCredentialsHandle = Win32API.new("secur32", "FreeCredentialsHandle", 'P', 'L')
- end
-
- # SecHandle struct
- class SecurityHandle
- def upper
- @struct.unpack("LL")[1]
- end
-
- def lower
- @struct.unpack("LL")[0]
- end
-
- def to_p
- @struct ||= "\0" * 8
- end
- end
-
- # Some familiar aliases for the SecHandle structure
- CredHandle = CtxtHandle = SecurityHandle
-
- # TimeStamp struct
- class TimeStamp
- attr_reader :struct
-
- def to_p
- @struct ||= "\0" * 8
- end
- end
-
- # Creates binary representaiton of a SecBufferDesc structure,
- # including the SecBuffer contained inside.
- class SecurityBuffer
-
- SECBUFFER_TOKEN = 2 # Security token
-
- TOKENBUFSIZE = 12288
- SECBUFFER_VERSION = 0
-
- def initialize(buffer = nil)
- @buffer = buffer || "\0" * TOKENBUFSIZE
- @bufferSize = @buffer.length
- @type = SECBUFFER_TOKEN
- end
-
- def bufferSize
- unpack
- @bufferSize
- end
-
- def bufferType
- unpack
- @type
- end
-
- def token
- unpack
- @buffer
- end
-
- def to_p
- # Assumption is that when to_p is called we are going to get a packed structure. Therefore,
- # set @unpacked back to nil so we know to unpack when accessors are next accessed.
- @unpacked = nil
- # Assignment of inner structure to variable is very important here. Without it,
- # will not be able to unpack changes to the structure. Alternative, nested unpacks,
- # does not work (i.e. @struct.unpack("LLP12")[2].unpack("LLP12") results in "no associated pointer")
- @sec_buffer ||= [@bufferSize, @type, @buffer].pack("LLP")
- @struct ||= [SECBUFFER_VERSION, 1, @sec_buffer].pack("LLP")
- end
-
- private
-
- # Unpacks the SecurityBufferDesc structure into member variables. We
- # only want to do this once per struct, so the struct is deleted
- # after unpacking.
- def unpack
- if ! @unpacked && @sec_buffer && @struct
- @bufferSize, @type = @sec_buffer.unpack("LL")
- @buffer = @sec_buffer.unpack("LLP#{@bufferSize}")[2]
- @struct = nil
- @sec_buffer = nil
- @unpacked = true
- end
- end
- end
-
- # SEC_WINNT_AUTH_IDENTITY structure
- class Identity
- SEC_WINNT_AUTH_IDENTITY_ANSI = 0x1
-
- attr_accessor :user, :domain, :password
-
- def initialize(user = nil, domain = nil, password = nil)
- @user = user
- @domain = domain
- @password = password
- @flags = SEC_WINNT_AUTH_IDENTITY_ANSI
- end
-
- def to_p
- [@user, @user ? @user.length : 0,
- @domain, @domain ? @domain.length : 0,
- @password, @password ? @password.length : 0,
- @flags].pack("PLPLPLL")
- end
- end
-
- # Takes a return result from an SSPI function and interprets the value.
- class SSPIResult
- # Good results
- SEC_E_OK = 0x00000000
- SEC_I_CONTINUE_NEEDED = 0x00090312
-
- # These are generally returned by InitializeSecurityContext
- SEC_E_INSUFFICIENT_MEMORY = 0x80090300
- SEC_E_INTERNAL_ERROR = 0x80090304
- SEC_E_INVALID_HANDLE = 0x80090301
- SEC_E_INVALID_TOKEN = 0x80090308
- SEC_E_LOGON_DENIED = 0x8009030C
- SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311
- SEC_E_NO_CREDENTIALS = 0x8009030E
- SEC_E_TARGET_UNKNOWN = 0x80090303
- SEC_E_UNSUPPORTED_FUNCTION = 0x80090302
- SEC_E_WRONG_PRINCIPAL = 0x80090322
-
- # These are generally returned by AcquireCredentialsHandle
- SEC_E_NOT_OWNER = 0x80090306
- SEC_E_SECPKG_NOT_FOUND = 0x80090305
- SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D
-
- @@map = {}
- constants.each { |v| @@map[self.const_get(v.to_s)] = v }
-
- attr_reader :value
-
- def initialize(value)
- # convert to unsigned long
- value = [value].pack("L").unpack("L").first
- raise "#{value.to_s(16)} is not a recognized result" unless @@map.has_key? value
- @value = value
- end
-
- def to_s
- @@map[@value].to_s
- end
-
- def ok?
- @value == SEC_I_CONTINUE_NEEDED || @value == SEC_E_OK
- end
-
- def ==(other)
- if other.is_a?(SSPIResult)
- @value == other.value
- elsif other.is_a?(Fixnum)
- @value == @@map[other]
- else
- false
- end
- end
- end
-
- # Handles "Negotiate" type authentication. Geared towards authenticating with a proxy server over HTTP
- class NegotiateAuth
- attr_accessor :credentials, :context, :contextAttributes, :user, :domain
-
- # Default request flags for SSPI functions
- REQUEST_FLAGS = ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION
-
- # NTLM tokens start with this header always. Encoding alone adds "==" and newline, so remove those
+ module SSPI
+ # Specifies how credential structure requested will be used. Only SECPKG_CRED_OUTBOUND is used
+ # here.
+ SECPKG_CRED_INBOUND = 0x00000001
+ SECPKG_CRED_OUTBOUND = 0x00000002
+ SECPKG_CRED_BOTH = 0x00000003
+
+ # Format of token. NETWORK format is used here.
+ SECURITY_NATIVE_DREP = 0x00000010
+ SECURITY_NETWORK_DREP = 0x00000000
+
+ # InitializeSecurityContext Requirement flags
+ ISC_REQ_REPLAY_DETECT = 0x00000004
+ ISC_REQ_SEQUENCE_DETECT = 0x00000008
+ ISC_REQ_CONFIDENTIALITY = 0x00000010
+ ISC_REQ_USE_SESSION_KEY = 0x00000020
+ ISC_REQ_PROMPT_FOR_CREDS = 0x00000040
+ ISC_REQ_CONNECTION = 0x00000800
+
+ # Win32 API Functions. Uses Win32API to bind methods to constants contained in class.
+ module API
+ extend Fiddle::Importer
+ dlload "secur32.dll"
+ [
+ # Can be called with AcquireCredentialsHandleA.call()
+ "unsigned long AcquireCredentialsHandleA(void *, void *, unsigned long, void *, void *, void *, void *, void *, void *)",
+ # Can be called with InitializeSecurityContextA.call()
+ "unsigned long InitializeSecurityContextA(void *, void *, void *, unsigned long, unsigned long, unsigned long, void *, unsigned long, void *, void *, void *, void *)",
+ # Can be called with DeleteSecurityContext.call()
+ "unsigned long DeleteSecurityContext(void *)",
+ # Can be called with FreeCredentialsHandle.call()
+ "unsigned long FreeCredentialsHandle(void *)"
+ ].each do |fn|
+ cfunc = extern fn, :stdcall
+ const_set cfunc.name.intern, cfunc
+ end
+ end
+
+ # SecHandle struct
+ class SecurityHandle
+ def upper
+ @struct.unpack("LL")[1]
+ end
+
+ def lower
+ @struct.unpack("LL")[0]
+ end
+
+ def to_p
+ @struct ||= "\0" * 8
+ end
+ end
+
+ # Some familiar aliases for the SecHandle structure
+ CredHandle = CtxtHandle = SecurityHandle
+
+ # TimeStamp struct
+ class TimeStamp
+ attr_reader :struct
+
+ def to_p
+ @struct ||= "\0" * 8
+ end
+ end
+
+ # Creates binary representations of a SecBufferDesc structure,
+ # including the SecBuffer contained inside.
+ class SecurityBuffer
+
+ SECBUFFER_TOKEN = 2 # Security token
+
+ TOKENBUFSIZE = 12288
+ SECBUFFER_VERSION = 0
+
+ def initialize(buffer = nil)
+ @buffer = buffer || "\0" * TOKENBUFSIZE
+ @bufferSize = @buffer.length
+ @type = SECBUFFER_TOKEN
+ end
+
+ def bufferSize
+ unpack
+ @bufferSize
+ end
+
+ def bufferType
+ unpack
+ @type
+ end
+
+ def token
+ unpack
+ @buffer
+ end
+
+ def to_p
+ # Assumption is that when to_p is called we are going to get a packed structure. Therefore,
+ # set @unpacked back to nil so we know to unpack when accessors are next accessed.
+ @unpacked = nil
+ # Assignment of inner structure to variable is very important here. Without it,
+ # will not be able to unpack changes to the structure. Alternative, nested unpacks,
+ # does not work (i.e. @struct.unpack("LLP12")[2].unpack("LLP12") results in "no associated pointer")
+ @sec_buffer ||= [@bufferSize, @type, @buffer].pack("LLP")
+ @struct ||= [SECBUFFER_VERSION, 1, @sec_buffer].pack("LLP")
+ end
+
+ private
+
+ # Unpacks the SecurityBufferDesc structure into member variables. We
+ # only want to do this once per struct, so the struct is deleted
+ # after unpacking.
+ def unpack
+ if ! @unpacked && @sec_buffer && @struct
+ @bufferSize, @type = @sec_buffer.unpack("LL")
+ @buffer = @sec_buffer.unpack("LLP#{@bufferSize}")[2]
+ @struct = nil
+ @sec_buffer = nil
+ @unpacked = true
+ end
+ end
+ end
+
+ # SEC_WINNT_AUTH_IDENTITY structure
+ class Identity
+ SEC_WINNT_AUTH_IDENTITY_ANSI = 0x1
+
+ attr_accessor :user, :domain, :password
+
+ def initialize(user = nil, domain = nil, password = nil)
+ @user = user
+ @domain = domain
+ @password = password
+ @flags = SEC_WINNT_AUTH_IDENTITY_ANSI
+ end
+
+ def to_p
+ [@user, @user ? @user.length : 0,
+ @domain, @domain ? @domain.length : 0,
+ @password, @password ? @password.length : 0,
+ @flags].pack("PLPLPLL")
+ end
+ end
+
+ # Takes a return result from an SSPI function and interprets the value.
+ class SSPIResult
+ # Good results
+ SEC_E_OK = 0x00000000
+ SEC_I_CONTINUE_NEEDED = 0x00090312
+
+ # These are generally returned by InitializeSecurityContext
+ SEC_E_INSUFFICIENT_MEMORY = 0x80090300
+ SEC_E_INTERNAL_ERROR = 0x80090304
+ SEC_E_INVALID_HANDLE = 0x80090301
+ SEC_E_INVALID_TOKEN = 0x80090308
+ SEC_E_LOGON_DENIED = 0x8009030C
+ SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311
+ SEC_E_NO_CREDENTIALS = 0x8009030E
+ SEC_E_TARGET_UNKNOWN = 0x80090303
+ SEC_E_UNSUPPORTED_FUNCTION = 0x80090302
+ SEC_E_WRONG_PRINCIPAL = 0x80090322
+
+ # These are generally returned by AcquireCredentialsHandle
+ SEC_E_NOT_OWNER = 0x80090306
+ SEC_E_SECPKG_NOT_FOUND = 0x80090305
+ SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D
+
+ @@map = {}
+ constants.each { |v| @@map[self.const_get(v.to_s)] = v }
+
+ attr_reader :value
+
+ def initialize(value)
+ # convert to unsigned long
+ value = [value].pack("L").unpack("L").first
+ raise "#{value.to_s(16)} is not a recognized result" unless @@map.has_key? value
+ @value = value
+ end
+
+ def to_s
+ @@map[@value].to_s
+ end
+
+ def ok?
+ @value == SEC_I_CONTINUE_NEEDED || @value == SEC_E_OK
+ end
+
+ def ==(other)
+ if other.is_a?(SSPIResult)
+ @value == other.value
+ elsif other.is_a?(Fixnum)
+ @value == @@map[other]
+ else
+ false
+ end
+ end
+ end
+
+ # Handles "Negotiate" type authentication. Geared towards authenticating with a proxy server over HTTP
+ class NegotiateAuth
+ attr_accessor :credentials, :context, :contextAttributes, :user, :domain
+
+ # Default request flags for SSPI functions
+ REQUEST_FLAGS = ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION
+
+ # NTLM tokens start with this header always. Encoding alone adds "==" and newline, so remove those
B64_TOKEN_PREFIX = ["NTLMSSP"].pack("m").delete("=\n")
- # Given a connection and a request path, performs authentication as the current user and returns
- # the response from a GET request. The connnection should be a Net::HTTP object, and it should
- # have been constructed using the Net::HTTP.Proxy method, but anything that responds to "get" will work.
- # If a user and domain are given, will authenticate as the given user.
- # Returns the response received from the get method (usually Net::HTTPResponse)
- def NegotiateAuth.proxy_auth_get(http, path, user = nil, domain = nil)
- raise "http must respond to :get" unless http.respond_to?(:get)
- nego_auth = self.new user, domain
-
- resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.get_initial_token }
- if resp["Proxy-Authenticate"]
- resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.complete_authentication(resp["Proxy-Authenticate"].split(" ").last.strip) }
- end
-
- resp
- end
-
- # Creates a new instance ready for authentication as the given user in the given domain.
- # Defaults to current user and domain as defined by ENV["USERDOMAIN"] and ENV["USERNAME"] if
- # no arguments are supplied.
- def initialize(user = nil, domain = nil)
- if user.nil? && domain.nil? && ENV["USERNAME"].nil? && ENV["USERDOMAIN"].nil?
- raise "A username or domain must be supplied since they cannot be retrieved from the environment"
- end
-
- @user = user || ENV["USERNAME"]
- @domain = domain || ENV["USERDOMAIN"]
- end
-
- # Gets the initial Negotiate token. Returns it as a base64 encoded string suitable for use in HTTP. Can
- # be easily decoded, however.
- def get_initial_token
- raise "This object is no longer usable because its resources have been freed." if @cleaned_up
- get_credentials
-
- outputBuffer = SecurityBuffer.new
- @context = CtxtHandle.new
- @contextAttributes = "\0" * 4
-
- result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, nil, nil,
- REQUEST_FLAGS,0, SECURITY_NETWORK_DREP, nil, 0, @context.to_p, outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))
-
- if result.ok? then
- return encode_token(outputBuffer.token)
- else
- raise "Error: #{result.to_s}"
- end
- end
-
- # Takes a token and gets the next token in the Negotiate authentication chain. Token can be Base64 encoded or not.
- # The token can include the "Negotiate" header and it will be stripped.
- # Does not indicate if SEC_I_CONTINUE or SEC_E_OK was returned.
- # Token returned is Base64 encoded w/ all new lines removed.
- def complete_authentication(token)
- raise "This object is no longer usable because its resources have been freed." if @cleaned_up
-
- # Nil token OK, just set it to empty string
- token = "" if token.nil?
-
- if token.include? "Negotiate"
- # If the Negotiate prefix is passed in, assume we are seeing "Negotiate <token>" and get the token.
- token = token.split(" ").last
- end
-
- if token.include? B64_TOKEN_PREFIX
- # indicates base64 encoded token
+ # Given a connection and a request path, performs authentication as the current user and returns
+ # the response from a GET request. The connnection should be a Net::HTTP object, and it should
+ # have been constructed using the Net::HTTP.Proxy method, but anything that responds to "get" will work.
+ # If a user and domain are given, will authenticate as the given user.
+ # Returns the response received from the get method (usually Net::HTTPResponse)
+ def NegotiateAuth.proxy_auth_get(http, path, user = nil, domain = nil)
+ raise "http must respond to :get" unless http.respond_to?(:get)
+ nego_auth = self.new user, domain
+
+ resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.get_initial_token }
+ if resp["Proxy-Authenticate"]
+ resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.complete_authentication(resp["Proxy-Authenticate"].split(" ").last.strip) }
+ end
+
+ resp
+ end
+
+ # Creates a new instance ready for authentication as the given user in the given domain.
+ # Defaults to current user and domain as defined by ENV["USERDOMAIN"] and ENV["USERNAME"] if
+ # no arguments are supplied.
+ def initialize(user = nil, domain = nil)
+ if user.nil? && domain.nil? && ENV["USERNAME"].nil? && ENV["USERDOMAIN"].nil?
+ raise "A username or domain must be supplied since they cannot be retrieved from the environment"
+ end
+
+ @user = user || ENV["USERNAME"]
+ @domain = domain || ENV["USERDOMAIN"]
+ end
+
+ # Gets the initial Negotiate token. Returns it as a base64 encoded string suitable for use in HTTP. Can
+ # be easily decoded, however.
+ def get_initial_token
+ raise "This object is no longer usable because its resources have been freed." if @cleaned_up
+ get_credentials
+
+ outputBuffer = SecurityBuffer.new
+ @context = CtxtHandle.new
+ @contextAttributes = "\0" * 4
+
+ result = SSPIResult.new(API::InitializeSecurityContextA.call(@credentials.to_p, nil, nil,
+ REQUEST_FLAGS,0, SECURITY_NETWORK_DREP, nil, 0, @context.to_p, outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))
+
+ if result.ok? then
+ return encode_token(outputBuffer.token)
+ else
+ raise "Error: #{result.to_s}"
+ end
+ end
+
+ # Takes a token and gets the next token in the Negotiate authentication chain. Token can be Base64 encoded or not.
+ # The token can include the "Negotiate" header and it will be stripped.
+ # Does not indicate if SEC_I_CONTINUE or SEC_E_OK was returned.
+ # Token returned is Base64 encoded w/ all new lines removed.
+ def complete_authentication(token)
+ raise "This object is no longer usable because its resources have been freed." if @cleaned_up
+
+ # Nil token OK, just set it to empty string
+ token = "" if token.nil?
+
+ if token.include? "Negotiate"
+ # If the Negotiate prefix is passed in, assume we are seeing "Negotiate <token>" and get the token.
+ token = token.split(" ").last
+ end
+
+ if token.include? B64_TOKEN_PREFIX
+ # indicates base64 encoded token
token = token.strip.unpack("m")[0]
- end
-
- outputBuffer = SecurityBuffer.new
- result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, @context.to_p, nil,
- REQUEST_FLAGS, 0, SECURITY_NETWORK_DREP, SecurityBuffer.new(token).to_p, 0,
- @context.to_p,
- outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))
-
- if result.ok? then
- return encode_token(outputBuffer.token)
- else
- raise "Error: #{result.to_s}"
- end
- ensure
- # need to make sure we don't clean up if we've already cleaned up.
- clean_up unless @cleaned_up
- end
-
- private
-
- def clean_up
- # free structures allocated
- @cleaned_up = true
- API::FreeCredentialsHandle.call(@credentials.to_p)
- API::DeleteSecurityContext.call(@context.to_p)
- @context = nil
- @credentials = nil
- @contextAttributes = nil
- end
-
- # Gets credentials based on user, domain or both. If both are nil, an error occurs
- def get_credentials
- @credentials = CredHandle.new
- ts = TimeStamp.new
- @identity = Identity.new @user, @domain
- result = SSPIResult.new(API::AcquireCredentialsHandle.call(nil, "Negotiate", SECPKG_CRED_OUTBOUND, nil, @identity.to_p,
- nil, nil, @credentials.to_p, ts.to_p))
- raise "Error acquire credentials: #{result}" unless result.ok?
- end
-
- def encode_token(t)
- # encode64 will add newlines every 60 characters so we need to remove those.
+ end
+
+ outputBuffer = SecurityBuffer.new
+ result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, @context.to_p, nil,
+ REQUEST_FLAGS, 0, SECURITY_NETWORK_DREP, SecurityBuffer.new(token).to_p, 0,
+ @context.to_p,
+ outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))
+
+ if result.ok? then
+ return encode_token(outputBuffer.token)
+ else
+ raise "Error: #{result.to_s}"
+ end
+ ensure
+ # need to make sure we don't clean up if we've already cleaned up.
+ clean_up unless @cleaned_up
+ end
+
+ private
+
+ def clean_up
+ # free structures allocated
+ @cleaned_up = true
+ API::FreeCredentialsHandle.call(@credentials.to_p)
+ API::DeleteSecurityContext.call(@context.to_p)
+ @context = nil
+ @credentials = nil
+ @contextAttributes = nil
+ end
+
+ # Gets credentials based on user, domain or both. If both are nil, an error occurs
+ def get_credentials
+ @credentials = CredHandle.new
+ ts = TimeStamp.new
+ @identity = Identity.new @user, @domain
+ result = SSPIResult.new(API::AcquireCredentialsHandleA.call(nil, "Negotiate", SECPKG_CRED_OUTBOUND, nil, @identity.to_p,
+ nil, nil, @credentials.to_p, ts.to_p))
+ raise "Error acquire credentials: #{result}" unless result.ok?
+ end
+
+ def encode_token(t)
+ # encode64 will add newlines every 60 characters so we need to remove those.
[t].pack("m").delete("\n")
- end
- end
- end
+ end
+ end
+ end
end
diff --git a/ext/win32/resolv/depend b/ext/win32/resolv/depend
new file mode 100644
index 0000000000..a6d24c3738
--- /dev/null
+++ b/ext/win32/resolv/depend
@@ -0,0 +1,17 @@
+# AUTOGENERATED DEPENDENCIES START
+resolv.o: $(RUBY_EXTCONF_H)
+resolv.o: $(arch_hdrdir)/ruby/config.h
+resolv.o: $(hdrdir)/ruby.h
+resolv.o: $(hdrdir)/ruby/assert.h
+resolv.o: $(hdrdir)/ruby/backward.h
+resolv.o: $(hdrdir)/ruby/defines.h
+resolv.o: $(hdrdir)/ruby/encoding.h
+resolv.o: $(hdrdir)/ruby/intern.h
+resolv.o: $(hdrdir)/ruby/missing.h
+resolv.o: $(hdrdir)/ruby/onigmo.h
+resolv.o: $(hdrdir)/ruby/oniguruma.h
+resolv.o: $(hdrdir)/ruby/ruby.h
+resolv.o: $(hdrdir)/ruby/st.h
+resolv.o: $(hdrdir)/ruby/subst.h
+resolv.o: resolv.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/win32ole/lib/win32ole.rb b/ext/win32ole/lib/win32ole.rb
new file mode 100644
index 0000000000..d7034f7845
--- /dev/null
+++ b/ext/win32ole/lib/win32ole.rb
@@ -0,0 +1,33 @@
+begin
+ require 'win32ole.so'
+rescue LoadError
+ # do nothing
+end
+
+if defined?(WIN32OLE)
+ # WIN32OLE
+ class WIN32OLE
+
+ #
+ # By overriding Object#methods, WIN32OLE might
+ # work well with did_you_mean gem.
+ # This is experimental.
+ #
+ # require 'win32ole'
+ # dict = WIN32OLE.new('Scripting.Dictionary')
+ # dict.Ade('a', 1)
+ # #=> Did you mean? Add
+ #
+ def methods(*args)
+ super + ole_methods_safely.map(&:name).map(&:to_sym)
+ end
+
+ private
+
+ def ole_methods_safely
+ ole_methods
+ rescue WIN32OLEQueryInterfaceError
+ []
+ end
+ end
+end
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index 84bb0ba819..59bae0e774 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -1,6 +1,7 @@
/*
* (c) 1995 Microsoft Corporation. All rights reserved.
- * Developed by ActiveWare Internet Corp., http://www.ActiveWare.com
+ * Developed by ActiveWare Internet Corp., now known as
+ * ActiveState Tool Corp., http://www.ActiveState.com
*
* Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy
* <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>
@@ -26,7 +27,7 @@
const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
#endif
-#define WIN32OLE_VERSION "1.8.6"
+#define WIN32OLE_VERSION "1.8.8"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@@ -506,6 +507,7 @@ static UINT ole_encoding2cp(rb_encoding *enc)
ENC_MACHING_CP(enc, "GB2312", 20936);
ENC_MACHING_CP(enc, "GBK", 936);
ENC_MACHING_CP(enc, "IBM437", 437);
+ ENC_MACHING_CP(enc, "IBM720", 720);
ENC_MACHING_CP(enc, "IBM737", 737);
ENC_MACHING_CP(enc, "IBM775", 775);
ENC_MACHING_CP(enc, "IBM852", 852);
@@ -1809,7 +1811,9 @@ ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self)
*pName = toupper((int)*pName);
id = rb_intern(pName);
if (rb_is_const_id(id)) {
- rb_define_const(klass, pName, val);
+ if(!rb_const_defined_at(klass, id)) {
+ rb_define_const(klass, pName, val);
+ }
}
else {
rb_hash_aset(constant, rb_str_new2(pName), val);
@@ -1982,10 +1986,6 @@ fole_s_connect(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "1*", &svr_name, &others);
StringValue(svr_name);
- if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
- rb_raise(rb_eSecurityError, "insecure connection - `%s'",
- StringValuePtr(svr_name));
- }
/* get CLSID from OLE server name */
pBuf = ole_vstr2wc(svr_name);
@@ -2071,12 +2071,12 @@ fole_s_const_load(int argc, VALUE *argv, VALUE self)
hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
0, lcid, &pTypeInfo);
if(FAILED(hr)) {
- ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
}
hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
if(FAILED(hr)) {
OLE_RELEASE(pTypeInfo);
- ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetContainingTypeLib");
}
OLE_RELEASE(pTypeInfo);
if(!RB_TYPE_P(klass, T_NIL)) {
@@ -2475,16 +2475,8 @@ fole_initialize(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "11*:", &svr_name, &host, &others, &opts);
StringValue(svr_name);
- if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
- rb_raise(rb_eSecurityError, "insecure object creation - `%s'",
- StringValuePtr(svr_name));
- }
if (!NIL_P(host)) {
StringValue(host);
- if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
- rb_raise(rb_eSecurityError, "insecure object creation - `%s'",
- StringValuePtr(host));
- }
return ole_create_dcom(self, svr_name, host, others);
}
@@ -2646,9 +2638,7 @@ ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
&wcmdname, 1, lcid, &DispID);
SysFreeString(wcmdname);
if(FAILED(hr)) {
- ole_raise(hr, rb_eNoMethodError,
- "unknown property or method: `%s'",
- StringValuePtr(cmd));
+ return rb_eNoMethodError;
}
}
@@ -2662,7 +2652,7 @@ ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
/*------------------------------------------
hash object ==> named dispatch parameters
--------------------------------------------*/
- cNamedArgs = rb_long2int(RHASH_SIZE(param));
+ cNamedArgs = rb_long2int((long)RHASH_SIZE(param));
op.dp.cArgs = cNamedArgs + argc - 2;
op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
@@ -2850,7 +2840,11 @@ ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
static VALUE
fole_invoke(int argc, VALUE *argv, VALUE self)
{
- return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
+ VALUE v = ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
+ if (v == rb_eNoMethodError) {
+ return rb_call_super(argc, argv);
+ }
+ return v;
}
static VALUE
@@ -2863,8 +2857,7 @@ ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind)
VARIANT result;
DISPPARAMS dispParams;
VARIANTARG* realargs = NULL;
- int i, j;
- VALUE obj = Qnil;
+ int i, j; VALUE obj = Qnil;
VALUE tp, param;
VALUE v;
VARTYPE vt;
@@ -3118,7 +3111,11 @@ fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
static VALUE
fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
- return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
+ VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
+ if (v == rb_eNoMethodError) {
+ return rb_call_super(argc, argv);
+ }
+ return v;
}
/*
@@ -3137,7 +3134,11 @@ fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
static VALUE
fole_setproperty(int argc, VALUE *argv, VALUE self)
{
- return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
+ VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
+ if (v == rb_eNoMethodError) {
+ return rb_call_super(argc, argv);
+ }
+ return v;
}
/*
@@ -3159,7 +3160,11 @@ fole_setproperty(int argc, VALUE *argv, VALUE self)
static VALUE
fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
- return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
+ VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
+ if (v == rb_eNoMethodError) {
+ return rb_call_super(argc, argv);
+ }
+ return v;
}
static VALUE
@@ -3309,7 +3314,7 @@ fole_each(VALUE self)
if (FAILED(hr)) {
VariantClear(&result);
- ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get IEnum Interface");
}
if (V_VT(&result) == VT_UNKNOWN) {
@@ -3325,7 +3330,7 @@ fole_each(VALUE self)
}
if (FAILED(hr) || !pEnum) {
VariantClear(&result);
- ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get IEnum Interface");
}
VariantClear(&result);
@@ -3342,11 +3347,11 @@ fole_each(VALUE self)
static VALUE
fole_missing(int argc, VALUE *argv, VALUE self)
{
- VALUE mid, sym;
+ VALUE mid, org_mid, sym, v;
const char* mname;
long n;
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
- mid = argv[0];
+ mid = org_mid = argv[0];
sym = rb_check_symbol(&mid);
if (!NIL_P(sym)) mid = rb_sym2str(sym);
mname = StringValueCStr(mid);
@@ -3362,7 +3367,12 @@ fole_missing(int argc, VALUE *argv, VALUE self)
}
else {
argv[0] = rb_enc_associate(rb_str_dup(mid), cWIN32OLE_enc);
- return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
+ v = ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
+ if (v == rb_eNoMethodError) {
+ argv[0] = org_mid;
+ return rb_call_super(argc, argv);
+ }
+ return v;
}
}
@@ -3379,7 +3389,7 @@ typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti)
HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
0, lcid, &pTypeInfo);
if(FAILED(hr)) {
- ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
}
hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
-1,
@@ -3389,7 +3399,7 @@ typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti)
hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
OLE_RELEASE(pTypeInfo);
if (FAILED(hr)) {
- ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetContainingTypeLib");
}
count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
for (i = 0; i < count; i++) {
@@ -3514,7 +3524,7 @@ fole_type(VALUE self)
hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
if(FAILED(hr)) {
- ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
}
type = ole_type_from_itypeinfo(pTypeInfo);
OLE_RELEASE(pTypeInfo);
@@ -3548,7 +3558,7 @@ fole_typelib(VALUE self)
hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
0, lcid, &pTypeInfo);
if(FAILED(hr)) {
- ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
}
vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
OLE_RELEASE(pTypeInfo);
@@ -3595,7 +3605,7 @@ fole_query_interface(VALUE self, VALUE str_iid)
hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
&p);
if(FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError,
+ ole_raise(hr, eWIN32OLEQueryInterfaceError,
"failed to get interface `%s'",
StringValuePtr(str_iid));
}
@@ -3836,7 +3846,7 @@ fole_method_help(VALUE self, VALUE cmdname)
pole = oledata_get_struct(self);
hr = typeinfo_from_ole(pole, &pTypeInfo);
if(FAILED(hr))
- ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get ITypeInfo");
obj = create_win32ole_method(pTypeInfo, cmdname);
@@ -3953,6 +3963,7 @@ check_nano_server(void)
}
}
+LCID cWIN32OLE_lcid;
void
Init_win32ole(void)
@@ -3976,11 +3987,11 @@ Init_win32ole(void)
message_filter.RetryRejectedCall = mf_RetryRejectedCall;
message_filter.MessagePending = mf_MessagePending;
- enc2cp_hash = TypedData_Wrap_Struct(rb_cData, &win32ole_hash_datatype, 0);
+ enc2cp_hash = TypedData_Wrap_Struct(0, &win32ole_hash_datatype, 0);
RTYPEDDATA_DATA(enc2cp_hash) = st_init_numtable();
rb_gc_register_mark_object(enc2cp_hash);
- com_hash = TypedData_Wrap_Struct(rb_cData, &win32ole_hash_datatype, 0);
+ com_hash = TypedData_Wrap_Struct(0, &win32ole_hash_datatype, 0);
RTYPEDDATA_DATA(com_hash) = st_init_numtable();
rb_gc_register_mark_object(com_hash);
diff --git a/ext/win32ole/win32ole.gemspec b/ext/win32ole/win32ole.gemspec
new file mode 100644
index 0000000000..021625e44e
--- /dev/null
+++ b/ext/win32ole/win32ole.gemspec
@@ -0,0 +1,21 @@
+Gem::Specification.new do |spec|
+ spec.name = "win32ole"
+ spec.version = "1.8.8"
+ spec.authors = ["Masaki Suketa"]
+ spec.email = ["suke@ruby-lang.org"]
+
+ spec.summary = %q{Provides an interface for OLE Automation in Ruby}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/win32ole"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/ext/win32ole/win32ole.h b/ext/win32ole/win32ole.h
index c019930397..cd627ef765 100644
--- a/ext/win32ole/win32ole.h
+++ b/ext/win32ole/win32ole.h
@@ -112,8 +112,8 @@ struct oledata {
IDispatch *pDispatch;
};
-VALUE cWIN32OLE;
-LCID cWIN32OLE_lcid;
+extern VALUE cWIN32OLE;
+extern LCID cWIN32OLE_lcid;
struct oledata *oledata_get_struct(VALUE obj);
LPWSTR ole_vstr2wc(VALUE vstr);
diff --git a/ext/win32ole/win32ole_error.c b/ext/win32ole/win32ole_error.c
index 62e69b186c..2bb5156263 100644
--- a/ext/win32ole/win32ole_error.c
+++ b/ext/win32ole/win32ole_error.c
@@ -60,6 +60,9 @@ ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...)
rb_exc_raise(rb_exc_new_str(ecs, msg));
}
+VALUE eWIN32OLERuntimeError;
+VALUE eWIN32OLEQueryInterfaceError;
+
void
Init_win32ole_error(void)
{
@@ -80,4 +83,5 @@ Init_win32ole_error(void)
*
*/
eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
+ eWIN32OLEQueryInterfaceError = rb_define_class("WIN32OLEQueryInterfaceError", eWIN32OLERuntimeError);
}
diff --git a/ext/win32ole/win32ole_error.h b/ext/win32ole/win32ole_error.h
index e0eee0ecf9..a2f329856f 100644
--- a/ext/win32ole/win32ole_error.h
+++ b/ext/win32ole/win32ole_error.h
@@ -1,7 +1,8 @@
#ifndef WIN32OLE_ERROR_H
#define WIN32OLE_ERROR_H 1
-VALUE eWIN32OLERuntimeError;
+extern VALUE eWIN32OLERuntimeError;
+extern VALUE eWIN32OLEQueryInterfaceError;
NORETURN(PRINTF_ARGS(void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...), 3, 4));
void Init_win32ole_error(void);
diff --git a/ext/win32ole/win32ole_event.c b/ext/win32ole/win32ole_event.c
index 6de31cb137..041639af6c 100644
--- a/ext/win32ole/win32ole_event.c
+++ b/ext/win32ole/win32ole_event.c
@@ -922,10 +922,6 @@ ev_advise(int argc, VALUE *argv, VALUE self)
if(!RB_TYPE_P(itf, T_NIL)) {
pitf = StringValuePtr(itf);
- if (rb_safe_level() > 0 && OBJ_TAINTED(itf)) {
- rb_raise(rb_eSecurityError, "insecure event creation - `%s'",
- StringValuePtr(itf));
- }
hr = find_iid(ole, pitf, &iid, &pTypeInfo);
}
else {
@@ -942,7 +938,7 @@ ev_advise(int argc, VALUE *argv, VALUE self)
&p);
if (FAILED(hr)) {
OLE_RELEASE(pTypeInfo);
- ole_raise(hr, rb_eRuntimeError,
+ ole_raise(hr, eWIN32OLEQueryInterfaceError,
"failed to query IConnectionPointContainer");
}
pContainer = p;
@@ -953,7 +949,7 @@ ev_advise(int argc, VALUE *argv, VALUE self)
OLE_RELEASE(pContainer);
if (FAILED(hr)) {
OLE_RELEASE(pTypeInfo);
- ole_raise(hr, rb_eRuntimeError, "failed to query IConnectionPoint");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to query IConnectionPoint");
}
pIEV = EVENTSINK_Constructor();
pIEV->m_iid = iid;
@@ -961,7 +957,7 @@ ev_advise(int argc, VALUE *argv, VALUE self)
(IUnknown*)pIEV,
&dwCookie);
if (FAILED(hr)) {
- ole_raise(hr, rb_eRuntimeError, "Advise Error");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "Advise Error");
}
TypedData_Get_Struct(self, struct oleeventdata, &oleevent_datatype, poleev);
@@ -1264,6 +1260,7 @@ fev_get_handler(VALUE self)
void
Init_win32ole_event(void)
{
+#undef rb_intern
ary_ole_event = rb_ary_new();
rb_gc_register_mark_object(ary_ole_event);
id_events = rb_intern("events");
diff --git a/ext/win32ole/win32ole_method.c b/ext/win32ole/win32ole_method.c
index 381c1cbbd3..bf668300c2 100644
--- a/ext/win32ole/win32ole_method.c
+++ b/ext/win32ole/win32ole_method.c
@@ -83,7 +83,7 @@ ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALU
VALUE method = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
@@ -119,7 +119,7 @@ ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
VALUE methods = rb_ary_new();
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
ole_methods_sub(0, pTypeInfo, methods, mask);
@@ -148,7 +148,7 @@ olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
VALUE method = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
method = ole_method_sub(self, 0, pTypeInfo, name);
if (method != Qnil) {
@@ -179,7 +179,7 @@ ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods,
WORD i;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
for(i = 0; i < pTypeAttr->cFuncs; i++) {
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
@@ -283,7 +283,7 @@ folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
}
/*
- * call-seq
+ * call-seq:
* WIN32OLE_METHOD#name
*
* Returns the name of the method.
@@ -308,7 +308,7 @@ ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index)
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
- ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
+ ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetFuncDesc");
type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
@@ -923,6 +923,8 @@ folemethod_inspect(VALUE self)
return default_inspect(self, "WIN32OLE_METHOD");
}
+VALUE cWIN32OLE_METHOD;
+
void Init_win32ole_method(void)
{
cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
diff --git a/ext/win32ole/win32ole_method.h b/ext/win32ole/win32ole_method.h
index ff2898ebeb..ef907d2fac 100644
--- a/ext/win32ole/win32ole_method.h
+++ b/ext/win32ole/win32ole_method.h
@@ -7,7 +7,7 @@ struct olemethoddata {
UINT index;
};
-VALUE cWIN32OLE_METHOD;
+extern VALUE cWIN32OLE_METHOD;
VALUE folemethod_s_allocate(VALUE klass);
VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask);
VALUE create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name);
diff --git a/ext/win32ole/win32ole_record.c b/ext/win32ole/win32ole_record.c
index e8838832a7..03523bc47d 100644
--- a/ext/win32ole/win32ole_record.c
+++ b/ext/win32ole/win32ole_record.c
@@ -589,6 +589,8 @@ folerecord_inspect(VALUE self)
field);
}
+VALUE cWIN32OLE_RECORD;
+
void
Init_win32ole_record(void)
{
diff --git a/ext/win32ole/win32ole_record.h b/ext/win32ole/win32ole_record.h
index ea431e91f7..ab1df0ee7f 100644
--- a/ext/win32ole/win32ole_record.h
+++ b/ext/win32ole/win32ole_record.h
@@ -1,7 +1,7 @@
#ifndef WIN32OLE_RECORD_H
#define WIN32OLE_RECORD_H 1
-VALUE cWIN32OLE_RECORD;
+extern VALUE cWIN32OLE_RECORD;
void ole_rec2variant(VALUE rec, VARIANT *var);
void olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec);
VALUE create_win32ole_record(IRecordInfo *pri, void *prec);
diff --git a/ext/win32ole/win32ole_type.c b/ext/win32ole/win32ole_type.c
index e6ac402ecf..fa39bf3696 100644
--- a/ext/win32ole/win32ole_type.c
+++ b/ext/win32ole/win32ole_type.c
@@ -883,6 +883,8 @@ foletype_inspect(VALUE self)
return default_inspect(self, "WIN32OLE_TYPE");
}
+VALUE cWIN32OLE_TYPE;
+
void Init_win32ole_type(void)
{
cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject);
diff --git a/ext/win32ole/win32ole_type.h b/ext/win32ole/win32ole_type.h
index a26bf3e043..87b551e502 100644
--- a/ext/win32ole/win32ole_type.h
+++ b/ext/win32ole/win32ole_type.h
@@ -1,6 +1,6 @@
#ifndef WIN32OLE_TYPE_H
#define WIN32OLE_TYPE_H 1
-VALUE cWIN32OLE_TYPE;
+extern VALUE cWIN32OLE_TYPE;
VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name);
ITypeInfo *itypeinfo(VALUE self);
VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo);
diff --git a/ext/win32ole/win32ole_typelib.c b/ext/win32ole/win32ole_typelib.c
index 35376c644b..d89f181e07 100644
--- a/ext/win32ole/win32ole_typelib.c
+++ b/ext/win32ole/win32ole_typelib.c
@@ -822,6 +822,8 @@ foletypelib_inspect(VALUE self)
return default_inspect(self, "WIN32OLE_TYPELIB");
}
+VALUE cWIN32OLE_TYPELIB;
+
void
Init_win32ole_typelib(void)
{
diff --git a/ext/win32ole/win32ole_typelib.h b/ext/win32ole/win32ole_typelib.h
index 9fc117fcb4..2c2730bb58 100644
--- a/ext/win32ole/win32ole_typelib.h
+++ b/ext/win32ole/win32ole_typelib.h
@@ -1,7 +1,7 @@
#ifndef WIN32OLE_TYPELIB_H
#define WIN32OLE_TYPELIB_H 1
-VALUE cWIN32OLE_TYPELIB;
+extern VALUE cWIN32OLE_TYPELIB;
void Init_win32ole_typelib(void);
ITypeLib * itypelib(VALUE self);
diff --git a/ext/win32ole/win32ole_variable.c b/ext/win32ole/win32ole_variable.c
index 3dc9972ee7..803083156c 100644
--- a/ext/win32ole/win32ole_variable.c
+++ b/ext/win32ole/win32ole_variable.c
@@ -365,6 +365,8 @@ folevariable_inspect(VALUE self)
return make_inspect("WIN32OLE_VARIABLE", detail);
}
+VALUE cWIN32OLE_VARIABLE;
+
void Init_win32ole_variable(void)
{
cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
diff --git a/ext/win32ole/win32ole_variable.h b/ext/win32ole/win32ole_variable.h
index 704dc13508..209613fd44 100644
--- a/ext/win32ole/win32ole_variable.h
+++ b/ext/win32ole/win32ole_variable.h
@@ -1,7 +1,7 @@
#ifndef WIN32OLE_VARIABLE_H
#define WIN32OLE_VARIABLE_H 1
-VALUE cWIN32OLE_VARIABLE;
+extern VALUE cWIN32OLE_VARIABLE;
VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name);
void Init_win32ole_variable(void);
diff --git a/ext/win32ole/win32ole_variant.c b/ext/win32ole/win32ole_variant.c
index eb0a463f93..93f0636593 100644
--- a/ext/win32ole/win32ole_variant.c
+++ b/ext/win32ole/win32ole_variant.c
@@ -689,9 +689,12 @@ ole_variant2variant(VALUE val, VARIANT *var)
VariantCopy(var, &(pvar->var));
}
+VALUE cWIN32OLE_VARIANT;
+
void
Init_win32ole_variant(void)
{
+#undef rb_intern
cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject);
rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate);
rb_define_singleton_method(cWIN32OLE_VARIANT, "array", folevariant_s_array, 2);
diff --git a/ext/win32ole/win32ole_variant.h b/ext/win32ole/win32ole_variant.h
index efe7ea8bef..4bd3b0aeea 100644
--- a/ext/win32ole/win32ole_variant.h
+++ b/ext/win32ole/win32ole_variant.h
@@ -1,7 +1,7 @@
#ifndef WIN32OLE_VARIANT_H
#define WIN32OLE_VARIANT_H 1
-VALUE cWIN32OLE_VARIANT;
+extern VALUE cWIN32OLE_VARIANT;
void ole_variant2variant(VALUE val, VARIANT *var);
void Init_win32ole_variant(void);
diff --git a/ext/win32ole/win32ole_variant_m.c b/ext/win32ole/win32ole_variant_m.c
index 4d76fdc790..145c08a16e 100644
--- a/ext/win32ole/win32ole_variant_m.c
+++ b/ext/win32ole/win32ole_variant_m.c
@@ -1,5 +1,7 @@
#include "win32ole.h"
+VALUE mWIN32OLE_VARIANT;
+
void Init_win32ole_variant_m(void)
{
/*
diff --git a/ext/win32ole/win32ole_variant_m.h b/ext/win32ole/win32ole_variant_m.h
index afbef30218..6272a6578f 100644
--- a/ext/win32ole/win32ole_variant_m.h
+++ b/ext/win32ole/win32ole_variant_m.h
@@ -1,7 +1,7 @@
#ifndef WIN32OLE_VARIANT_M_H
#define WIN32OLE_VARIANT_M_H 1
-VALUE mWIN32OLE_VARIANT;
+extern VALUE mWIN32OLE_VARIANT;
void Init_win32ole_variant_m(void);
#endif
diff --git a/ext/zlib/.gitignore b/ext/zlib/.gitignore
new file mode 100644
index 0000000000..069491b4b4
--- /dev/null
+++ b/ext/zlib/.gitignore
@@ -0,0 +1 @@
+/zlib-[1-9]*.*.*
diff --git a/ext/zlib/depend b/ext/zlib/depend
index bfba309dae..5433affc69 100644
--- a/ext/zlib/depend
+++ b/ext/zlib/depend
@@ -1,7 +1,158 @@
# AUTOGENERATED DEPENDENCIES START
zlib.o: $(RUBY_EXTCONF_H)
zlib.o: $(arch_hdrdir)/ruby/config.h
+zlib.o: $(hdrdir)/ruby.h
+zlib.o: $(hdrdir)/ruby/internal/anyargs.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+zlib.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+zlib.o: $(hdrdir)/ruby/internal/assume.h
+zlib.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+zlib.o: $(hdrdir)/ruby/internal/attr/artificial.h
+zlib.o: $(hdrdir)/ruby/internal/attr/cold.h
+zlib.o: $(hdrdir)/ruby/internal/attr/const.h
+zlib.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+zlib.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+zlib.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+zlib.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+zlib.o: $(hdrdir)/ruby/internal/attr/error.h
+zlib.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+zlib.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+zlib.o: $(hdrdir)/ruby/internal/attr/format.h
+zlib.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+zlib.o: $(hdrdir)/ruby/internal/attr/noalias.h
+zlib.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+zlib.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+zlib.o: $(hdrdir)/ruby/internal/attr/noinline.h
+zlib.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+zlib.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+zlib.o: $(hdrdir)/ruby/internal/attr/pure.h
+zlib.o: $(hdrdir)/ruby/internal/attr/restrict.h
+zlib.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+zlib.o: $(hdrdir)/ruby/internal/attr/warning.h
+zlib.o: $(hdrdir)/ruby/internal/attr/weakref.h
+zlib.o: $(hdrdir)/ruby/internal/cast.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_is.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+zlib.o: $(hdrdir)/ruby/internal/compiler_since.h
+zlib.o: $(hdrdir)/ruby/internal/config.h
+zlib.o: $(hdrdir)/ruby/internal/constant_p.h
+zlib.o: $(hdrdir)/ruby/internal/core.h
+zlib.o: $(hdrdir)/ruby/internal/core/rarray.h
+zlib.o: $(hdrdir)/ruby/internal/core/rbasic.h
+zlib.o: $(hdrdir)/ruby/internal/core/rbignum.h
+zlib.o: $(hdrdir)/ruby/internal/core/rclass.h
+zlib.o: $(hdrdir)/ruby/internal/core/rdata.h
+zlib.o: $(hdrdir)/ruby/internal/core/rfile.h
+zlib.o: $(hdrdir)/ruby/internal/core/rhash.h
+zlib.o: $(hdrdir)/ruby/internal/core/robject.h
+zlib.o: $(hdrdir)/ruby/internal/core/rregexp.h
+zlib.o: $(hdrdir)/ruby/internal/core/rstring.h
+zlib.o: $(hdrdir)/ruby/internal/core/rstruct.h
+zlib.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+zlib.o: $(hdrdir)/ruby/internal/ctype.h
+zlib.o: $(hdrdir)/ruby/internal/dllexport.h
+zlib.o: $(hdrdir)/ruby/internal/dosish.h
+zlib.o: $(hdrdir)/ruby/internal/error.h
+zlib.o: $(hdrdir)/ruby/internal/eval.h
+zlib.o: $(hdrdir)/ruby/internal/event.h
+zlib.o: $(hdrdir)/ruby/internal/fl_type.h
+zlib.o: $(hdrdir)/ruby/internal/gc.h
+zlib.o: $(hdrdir)/ruby/internal/glob.h
+zlib.o: $(hdrdir)/ruby/internal/globals.h
+zlib.o: $(hdrdir)/ruby/internal/has/attribute.h
+zlib.o: $(hdrdir)/ruby/internal/has/builtin.h
+zlib.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+zlib.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+zlib.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+zlib.o: $(hdrdir)/ruby/internal/has/extension.h
+zlib.o: $(hdrdir)/ruby/internal/has/feature.h
+zlib.o: $(hdrdir)/ruby/internal/has/warning.h
+zlib.o: $(hdrdir)/ruby/internal/intern/array.h
+zlib.o: $(hdrdir)/ruby/internal/intern/bignum.h
+zlib.o: $(hdrdir)/ruby/internal/intern/class.h
+zlib.o: $(hdrdir)/ruby/internal/intern/compar.h
+zlib.o: $(hdrdir)/ruby/internal/intern/complex.h
+zlib.o: $(hdrdir)/ruby/internal/intern/cont.h
+zlib.o: $(hdrdir)/ruby/internal/intern/dir.h
+zlib.o: $(hdrdir)/ruby/internal/intern/enum.h
+zlib.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+zlib.o: $(hdrdir)/ruby/internal/intern/error.h
+zlib.o: $(hdrdir)/ruby/internal/intern/eval.h
+zlib.o: $(hdrdir)/ruby/internal/intern/file.h
+zlib.o: $(hdrdir)/ruby/internal/intern/gc.h
+zlib.o: $(hdrdir)/ruby/internal/intern/hash.h
+zlib.o: $(hdrdir)/ruby/internal/intern/io.h
+zlib.o: $(hdrdir)/ruby/internal/intern/load.h
+zlib.o: $(hdrdir)/ruby/internal/intern/marshal.h
+zlib.o: $(hdrdir)/ruby/internal/intern/numeric.h
+zlib.o: $(hdrdir)/ruby/internal/intern/object.h
+zlib.o: $(hdrdir)/ruby/internal/intern/parse.h
+zlib.o: $(hdrdir)/ruby/internal/intern/proc.h
+zlib.o: $(hdrdir)/ruby/internal/intern/process.h
+zlib.o: $(hdrdir)/ruby/internal/intern/random.h
+zlib.o: $(hdrdir)/ruby/internal/intern/range.h
+zlib.o: $(hdrdir)/ruby/internal/intern/rational.h
+zlib.o: $(hdrdir)/ruby/internal/intern/re.h
+zlib.o: $(hdrdir)/ruby/internal/intern/ruby.h
+zlib.o: $(hdrdir)/ruby/internal/intern/select.h
+zlib.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+zlib.o: $(hdrdir)/ruby/internal/intern/signal.h
+zlib.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+zlib.o: $(hdrdir)/ruby/internal/intern/string.h
+zlib.o: $(hdrdir)/ruby/internal/intern/struct.h
+zlib.o: $(hdrdir)/ruby/internal/intern/thread.h
+zlib.o: $(hdrdir)/ruby/internal/intern/time.h
+zlib.o: $(hdrdir)/ruby/internal/intern/variable.h
+zlib.o: $(hdrdir)/ruby/internal/intern/vm.h
+zlib.o: $(hdrdir)/ruby/internal/interpreter.h
+zlib.o: $(hdrdir)/ruby/internal/iterator.h
+zlib.o: $(hdrdir)/ruby/internal/memory.h
+zlib.o: $(hdrdir)/ruby/internal/method.h
+zlib.o: $(hdrdir)/ruby/internal/module.h
+zlib.o: $(hdrdir)/ruby/internal/newobj.h
+zlib.o: $(hdrdir)/ruby/internal/rgengc.h
+zlib.o: $(hdrdir)/ruby/internal/scan_args.h
+zlib.o: $(hdrdir)/ruby/internal/special_consts.h
+zlib.o: $(hdrdir)/ruby/internal/static_assert.h
+zlib.o: $(hdrdir)/ruby/internal/stdalign.h
+zlib.o: $(hdrdir)/ruby/internal/stdbool.h
+zlib.o: $(hdrdir)/ruby/internal/symbol.h
+zlib.o: $(hdrdir)/ruby/internal/token_paste.h
+zlib.o: $(hdrdir)/ruby/internal/value.h
+zlib.o: $(hdrdir)/ruby/internal/value_type.h
+zlib.o: $(hdrdir)/ruby/internal/variable.h
+zlib.o: $(hdrdir)/ruby/internal/warning_push.h
+zlib.o: $(hdrdir)/ruby/internal/xmalloc.h
+zlib.o: $(hdrdir)/ruby/assert.h
zlib.o: $(hdrdir)/ruby/backward.h
+zlib.o: $(hdrdir)/ruby/backward/2/assume.h
+zlib.o: $(hdrdir)/ruby/backward/2/attributes.h
+zlib.o: $(hdrdir)/ruby/backward/2/bool.h
+zlib.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
+zlib.o: $(hdrdir)/ruby/backward/2/inttypes.h
+zlib.o: $(hdrdir)/ruby/backward/2/limits.h
+zlib.o: $(hdrdir)/ruby/backward/2/long_long.h
+zlib.o: $(hdrdir)/ruby/backward/2/stdalign.h
+zlib.o: $(hdrdir)/ruby/backward/2/stdarg.h
zlib.o: $(hdrdir)/ruby/defines.h
zlib.o: $(hdrdir)/ruby/encoding.h
zlib.o: $(hdrdir)/ruby/intern.h
@@ -13,6 +164,5 @@ zlib.o: $(hdrdir)/ruby/ruby.h
zlib.o: $(hdrdir)/ruby/st.h
zlib.o: $(hdrdir)/ruby/subst.h
zlib.o: $(hdrdir)/ruby/thread.h
-zlib.o: $(top_srcdir)/include/ruby.h
zlib.o: zlib.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/zlib/extconf.rb b/ext/zlib/extconf.rb
index fd2f168522..76cd34582e 100644
--- a/ext/zlib/extconf.rb
+++ b/ext/zlib/extconf.rb
@@ -31,9 +31,12 @@ else
$extso << dll
$cleanfiles << "$(topdir)/#{dll}" << "$(ZIMPLIB)"
zmk = "\t$(MAKE) -f $(ZMKFILE) TOP=$(ZSRC)"
+ zopts = []
if $nmake
zmkfile = "$(ZSRC)/win32/Makefile.msc"
m = "#{zsrc}/win32/Makefile.msc"
+ # zopts << "USE_ASM=1"
+ zopts << "ARCH=#{RbConfig::CONFIG['target_cpu']}"
else
zmkfile = "$(ZSRC)/win32/Makefile.gcc"
m = "#{zsrc}/win32/Makefile.gcc"
@@ -55,9 +58,10 @@ else
addconf.push(
"ZMKFILE = #{zmkfile}\n",
"ZIMPLIB = #{zimplib}\n",
+ "ZOPTS = #{zopts.join(' ')}\n",
"$(TARGET_SO): $(ZIMPLIB)\n",
"$(ZIMPLIB):\n",
- "#{zmk} $@\n",
+ "#{zmk} $(ZOPTS) $@\n",
"install-so: $(topdir)/#{dll}",
"$(topdir)/#{dll}: $(ZIMPLIB)\n",
"\t$(Q) $(COPY) #{dll} $(@D)\n",
diff --git a/ext/zlib/extlibs b/ext/zlib/extlibs
new file mode 100644
index 0000000000..556d1f4a6f
--- /dev/null
+++ b/ext/zlib/extlibs
@@ -0,0 +1,6 @@
+ver = 1.2.13
+pkg = zlib-$(ver)
+
+https://github.com/madler/zlib/releases/download/v$(ver)/$(pkg).tar.gz \
+ sha256:b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30 \
+ #
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index fde85befab..5dbeba6943 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -25,7 +25,11 @@
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
#endif
-#define RUBY_ZLIB_VERSION "0.6.0"
+#define RUBY_ZLIB_VERSION "2.0.0"
+
+#ifndef RB_PASS_CALLED_KEYWORDS
+# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
+#endif
#ifndef GZIP_SUPPORT
#define GZIP_SUPPORT 1
@@ -52,7 +56,10 @@ max_uint(long n)
#define MAX_UINT(n) (uInt)(n)
#endif
-static ID id_dictionaries;
+#define OPTHASH_GIVEN_P(opts) \
+ (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
+
+static ID id_dictionaries, id_read, id_buffer;
/*--------- Prototypes --------*/
@@ -85,6 +92,7 @@ static void zstream_passthrough_input(struct zstream*);
static VALUE zstream_detach_input(struct zstream*);
static void zstream_reset(struct zstream*);
static VALUE zstream_end(struct zstream*);
+static VALUE zstream_ensure_end(VALUE v);
static void zstream_run(struct zstream*, Bytef*, long, int);
static VALUE zstream_sync(struct zstream*, Bytef*, long);
static void zstream_mark(void*);
@@ -125,7 +133,7 @@ static VALUE rb_inflate_s_allocate(VALUE);
static VALUE rb_inflate_initialize(int, VALUE*, VALUE);
static VALUE rb_inflate_s_inflate(VALUE, VALUE);
static void do_inflate(struct zstream*, VALUE);
-static VALUE rb_inflate_inflate(VALUE, VALUE);
+static VALUE rb_inflate_inflate(int, VALUE*, VALUE);
static VALUE rb_inflate_addstr(VALUE, VALUE);
static VALUE rb_inflate_sync(VALUE, VALUE);
static VALUE rb_inflate_sync_point_p(VALUE);
@@ -140,19 +148,19 @@ static void gzfile_reset(struct gzfile*);
static void gzfile_close(struct gzfile*, int);
static void gzfile_write_raw(struct gzfile*);
static VALUE gzfile_read_raw_partial(VALUE);
-static VALUE gzfile_read_raw_rescue(VALUE);
-static VALUE gzfile_read_raw(struct gzfile*);
-static int gzfile_read_raw_ensure(struct gzfile*, long);
+static VALUE gzfile_read_raw_rescue(VALUE,VALUE);
+static VALUE gzfile_read_raw(struct gzfile*, VALUE outbuf);
+static int gzfile_read_raw_ensure(struct gzfile*, long, VALUE outbuf);
static char *gzfile_read_raw_until_zero(struct gzfile*, long);
static unsigned int gzfile_get16(const unsigned char*);
static unsigned long gzfile_get32(const unsigned char*);
static void gzfile_set32(unsigned long n, unsigned char*);
static void gzfile_make_header(struct gzfile*);
static void gzfile_make_footer(struct gzfile*);
-static void gzfile_read_header(struct gzfile*);
-static void gzfile_check_footer(struct gzfile*);
+static void gzfile_read_header(struct gzfile*, VALUE outbuf);
+static void gzfile_check_footer(struct gzfile*, VALUE outbuf);
static void gzfile_write(struct gzfile*, Bytef*, long);
-static long gzfile_read_more(struct gzfile*);
+static long gzfile_read_more(struct gzfile*, VALUE outbuf);
static void gzfile_calc_crc(struct gzfile*, VALUE);
static VALUE gzfile_read(struct gzfile*, long);
static VALUE gzfile_read_all(struct gzfile*);
@@ -197,7 +205,7 @@ static VALUE rb_gzwriter_s_allocate(VALUE);
static VALUE rb_gzwriter_s_open(int, VALUE*, VALUE);
static VALUE rb_gzwriter_initialize(int, VALUE*, VALUE);
static VALUE rb_gzwriter_flush(int, VALUE*, VALUE);
-static VALUE rb_gzwriter_write(VALUE, VALUE);
+static VALUE rb_gzwriter_write(int, VALUE*, VALUE);
static VALUE rb_gzwriter_putc(VALUE, VALUE);
static VALUE rb_gzreader_s_allocate(VALUE);
@@ -280,6 +288,7 @@ static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
* - Zlib::MemError
* - Zlib::BufError
* - Zlib::VersionError
+ * - Zlib::InProgressError
*
* (if you have GZIP_SUPPORT)
* - Zlib::GzipReader
@@ -296,7 +305,7 @@ void Init_zlib(void);
/*--------- Exceptions --------*/
static VALUE cZError, cStreamEnd, cNeedDict;
-static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;
+static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError, cInProgressError;
static void
raise_zlib_error(int err, const char *msg)
@@ -360,11 +369,7 @@ finalizer_warn(const char *msg)
static VALUE
rb_zlib_version(VALUE klass)
{
- VALUE str;
-
- str = rb_str_new2(zlibVersion());
- OBJ_TAINT(str); /* for safe */
- return str;
+ return rb_str_new2(zlibVersion());
}
#if SIZEOF_LONG > SIZEOF_INT
@@ -406,6 +411,15 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt))
if (NIL_P(str)) {
sum = func(sum, Z_NULL, 0);
}
+ else if (rb_obj_is_kind_of(str, rb_cIO)) {
+ VALUE buf;
+ VALUE buflen = INT2NUM(8192);
+
+ while (!NIL_P(buf = rb_funcall(str, id_read, 1, buflen))) {
+ StringValue(buf);
+ sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(buf), RSTRING_LEN(buf));
+ }
+ }
else {
StringValue(str);
sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
@@ -421,6 +435,8 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt))
* Calculates Adler-32 checksum for +string+, and returns updated value of
* +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If
* +adler+ is omitted, it assumes that the initial value is given to +adler+.
+ * If +string+ is an IO instance, reads from the IO until the IO returns nil
+ * and returns Adler-32 of all read data.
*
* Example usage:
*
@@ -465,7 +481,9 @@ rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
*
* Calculates CRC checksum for +string+, and returns updated value of +crc+. If
* +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it
- * assumes that the initial value is given to +crc+.
+ * assumes that the initial value is given to +crc+. If +string+ is an IO instance,
+ * reads from the IO until the IO returns nil and returns CRC checksum of all read
+ * data.
*
* FIXME: expression.
*/
@@ -529,6 +547,7 @@ struct zstream {
unsigned long flags;
VALUE buf;
VALUE input;
+ VALUE mutex;
z_stream stream;
const struct zstream_funcs {
int (*reset)(z_streamp);
@@ -537,13 +556,15 @@ struct zstream {
} *func;
};
-#define ZSTREAM_FLAG_READY 0x1
-#define ZSTREAM_FLAG_IN_STREAM 0x2
-#define ZSTREAM_FLAG_FINISHED 0x4
-#define ZSTREAM_FLAG_CLOSING 0x8
-#define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for
+#define ZSTREAM_FLAG_READY (1 << 0)
+#define ZSTREAM_FLAG_IN_STREAM (1 << 1)
+#define ZSTREAM_FLAG_FINISHED (1 << 2)
+#define ZSTREAM_FLAG_CLOSING (1 << 3)
+#define ZSTREAM_FLAG_GZFILE (1 << 4) /* disallows yield from expand_buffer for
gzip*/
-#define ZSTREAM_FLAG_UNUSED 0x20
+#define ZSTREAM_REUSE_BUFFER (1 << 5)
+#define ZSTREAM_IN_PROGRESS (1 << 6)
+#define ZSTREAM_FLAG_UNUSED (1 << 7)
#define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
#define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
@@ -552,6 +573,8 @@ struct zstream {
#define ZSTREAM_IS_GZFILE(z) ((z)->flags & ZSTREAM_FLAG_GZFILE)
#define ZSTREAM_BUF_FILLED(z) (NIL_P((z)->buf) ? 0 : RSTRING_LEN((z)->buf))
+#define ZSTREAM_REUSE_BUFFER_P(z) ((z)->flags & ZSTREAM_REUSE_BUFFER)
+
#define ZSTREAM_EXPAND_BUFFER_OK 0
/* I think that more better value should be found,
@@ -570,7 +593,9 @@ static const struct zstream_funcs inflate_funcs = {
};
struct zstream_run_args {
- struct zstream * z;
+ struct zstream *const z;
+ Bytef *src;
+ long len;
int flush; /* stream flush value for inflate() or deflate() */
int interrupt; /* stop processing the stream and return to ruby */
int jump_state; /* for buffer expansion block break or exception */
@@ -601,6 +626,7 @@ zstream_init(struct zstream *z, const struct zstream_funcs *func)
z->flags = 0;
z->buf = Qnil;
z->input = Qnil;
+ z->mutex = rb_mutex_new();
z->stream.zalloc = zlib_mem_alloc;
z->stream.zfree = zlib_mem_free;
z->stream.opaque = Z_NULL;
@@ -627,14 +653,22 @@ zstream_expand_buffer(struct zstream *z)
long buf_filled = ZSTREAM_BUF_FILLED(z);
if (buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
int state = 0;
- VALUE self = (VALUE)z->stream.opaque;
- rb_obj_reveal(z->buf, rb_cString);
- OBJ_INFECT(z->buf, self);
+ if (!ZSTREAM_REUSE_BUFFER_P(z)) {
+ rb_obj_reveal(z->buf, rb_cString);
+ }
+ rb_mutex_unlock(z->mutex);
rb_protect(rb_yield, z->buf, &state);
-
- z->buf = Qnil;
+ rb_mutex_lock(z->mutex);
+
+ if (ZSTREAM_REUSE_BUFFER_P(z)) {
+ rb_str_modify(z->buf);
+ rb_str_set_len(z->buf, 0);
+ }
+ else {
+ z->buf = Qnil;
+ }
zstream_expand_buffer_into(z, ZSTREAM_AVAIL_OUT_STEP_MAX);
if (state)
@@ -738,7 +772,7 @@ zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
static VALUE
zstream_detach_buffer(struct zstream *z)
{
- VALUE dst, self = (VALUE)z->stream.opaque;
+ VALUE dst;
if (!ZSTREAM_IS_FINISHED(z) && !ZSTREAM_IS_GZFILE(z) &&
rb_block_given_p()) {
@@ -752,11 +786,11 @@ zstream_detach_buffer(struct zstream *z)
}
else {
dst = z->buf;
- rb_obj_reveal(dst, rb_cString);
+ if (!ZSTREAM_REUSE_BUFFER_P(z)) {
+ rb_obj_reveal(dst, rb_cString);
+ }
}
- OBJ_INFECT(dst, self);
-
z->buf = Qnil;
z->stream.next_out = 0;
z->stream.avail_out = 0;
@@ -845,19 +879,50 @@ zstream_append_input(struct zstream *z, const Bytef *src, long len)
static void
zstream_discard_input(struct zstream *z, long len)
{
- if (NIL_P(z->input) || RSTRING_LEN(z->input) <= len) {
- z->input = Qnil;
+ if (NIL_P(z->input)) {
}
- else {
- z->input = rb_str_substr(z->input, len,
- RSTRING_LEN(z->input) - len);
+ else if (RBASIC_CLASS(z->input) == 0) {
+ /* hidden, we created z->input and have complete control */
+ char *ptr;
+ long oldlen, newlen;
+
+ RSTRING_GETMEM(z->input, ptr, oldlen);
+ newlen = oldlen - len;
+ if (newlen > 0) {
+ memmove(ptr, ptr + len, newlen);
+ }
+ if (newlen < 0) {
+ newlen = 0;
+ }
+ rb_str_resize(z->input, newlen);
+ if (newlen == 0) {
+ rb_gc_force_recycle(z->input);
+ z->input = Qnil;
+ }
+ else {
+ rb_str_set_len(z->input, newlen);
+ }
+ }
+ else { /* do not mangle user-provided data */
+ if (RSTRING_LEN(z->input) <= len) {
+ z->input = Qnil;
+ }
+ else {
+ z->input = rb_str_substr(z->input, len,
+ RSTRING_LEN(z->input) - len);
+ }
}
}
static void
zstream_reset_input(struct zstream *z)
{
- z->input = Qnil;
+ if (!NIL_P(z->input) && RBASIC_CLASS(z->input) == 0) {
+ rb_str_resize(z->input, 0);
+ }
+ else {
+ z->input = Qnil;
+ }
}
static void
@@ -882,7 +947,6 @@ zstream_detach_input(struct zstream *z)
rb_obj_reveal(dst, rb_cString);
}
z->input = Qnil;
- rb_obj_reveal(dst, rb_cString);
return dst;
}
@@ -925,6 +989,12 @@ zstream_end(struct zstream *z)
return Qnil;
}
+static VALUE
+zstream_ensure_end(VALUE v)
+{
+ return zstream_end((struct zstream *)v);
+}
+
static void *
zstream_run_func(void *ptr)
{
@@ -981,6 +1051,7 @@ zstream_run_func(void *ptr)
/*
* There is no safe way to interrupt z->run->func().
+ * async-signal-safe
*/
static void
zstream_unblock_func(void *ptr)
@@ -990,18 +1061,17 @@ zstream_unblock_func(void *ptr)
args->interrupt = 1;
}
-static void
-zstream_run(struct zstream *z, Bytef *src, long len, int flush)
+static VALUE
+zstream_run_try(VALUE value_arg)
{
- struct zstream_run_args args;
- int err;
- VALUE guard = Qnil;
+ struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
+ struct zstream *z = args->z;
+ Bytef *src = args->src;
+ long len = args->len;
+ int flush = args->flush;
- args.z = z;
- args.flush = flush;
- args.interrupt = 0;
- args.jump_state = 0;
- args.stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p();
+ int err;
+ VALUE old_input = Qnil;
if (NIL_P(z->input) && len == 0) {
z->stream.next_in = (Bytef*)"";
@@ -1009,12 +1079,13 @@ zstream_run(struct zstream *z, Bytef *src, long len, int flush)
}
else {
zstream_append_input(z, src, len);
- z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
- z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
/* keep reference to `z->input' so as not to be garbage collected
after zstream_reset_input() and prevent `z->stream.next_in'
from dangling. */
- guard = z->input;
+ old_input = zstream_detach_input(z);
+ rb_obj_hide(old_input); /* for GVL release and later recycle */
+ z->stream.next_in = (Bytef*)RSTRING_PTR(old_input);
+ z->stream.avail_in = MAX_UINT(RSTRING_LEN(old_input));
}
if (z->stream.avail_out == 0) {
@@ -1022,8 +1093,20 @@ zstream_run(struct zstream *z, Bytef *src, long len, int flush)
}
loop:
- err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args,
- zstream_unblock_func, (void *)&args);
+#ifndef RB_NOGVL_UBF_ASYNC_SAFE
+ err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)args,
+ zstream_unblock_func, (void *)args);
+#else
+ err = (int)(VALUE)rb_nogvl(zstream_run_func, (void *)args,
+ zstream_unblock_func, (void *)args,
+ RB_NOGVL_UBF_ASYNC_SAFE);
+#endif
+
+ /* retry if no exception is thrown */
+ if (err == Z_OK && args->interrupt) {
+ args->interrupt = 0;
+ goto loop;
+ }
if (flush != Z_FINISH && err == Z_BUF_ERROR
&& z->stream.avail_out > 0) {
@@ -1052,11 +1135,58 @@ loop:
if (z->stream.avail_in > 0) {
zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
- RB_GC_GUARD(guard); /* prevent tail call to make guard effective */
}
+ if (!NIL_P(old_input)) {
+ rb_str_resize(old_input, 0);
+ rb_gc_force_recycle(old_input);
+ }
+
+ if (args->jump_state)
+ rb_jump_tag(args->jump_state);
- if (args.jump_state)
- rb_jump_tag(args.jump_state);
+ return Qnil;
+}
+
+static VALUE
+zstream_run_ensure(VALUE value_arg)
+{
+ struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
+
+ /* Remove ZSTREAM_IN_PROGRESS flag to signal that this zstream is not in use. */
+ args->z->flags &= ~ZSTREAM_IN_PROGRESS;
+
+ return Qnil;
+}
+
+static VALUE
+zstream_run_synchronized(VALUE value_arg)
+{
+ struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
+
+ /* Cannot start zstream while it is in progress. */
+ if (args->z->flags & ZSTREAM_IN_PROGRESS) {
+ rb_raise(cInProgressError, "zlib stream is in progress");
+ }
+ args->z->flags |= ZSTREAM_IN_PROGRESS;
+
+ rb_ensure(zstream_run_try, value_arg, zstream_run_ensure, value_arg);
+
+ return Qnil;
+}
+
+static void
+zstream_run(struct zstream *z, Bytef *src, long len, int flush)
+{
+ struct zstream_run_args args = {
+ .z = z,
+ .src = src,
+ .len = len,
+ .flush = flush,
+ .interrupt = 0,
+ .jump_state = 0,
+ .stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p(),
+ };
+ rb_mutex_synchronize(z->mutex, zstream_run_synchronized, (VALUE)&args);
}
static VALUE
@@ -1104,6 +1234,7 @@ zstream_mark(void *p)
struct zstream *z = p;
rb_gc_mark(z->buf);
rb_gc_mark(z->input);
+ rb_gc_mark(z->mutex);
}
static void
@@ -1285,7 +1416,6 @@ rb_zstream_flush_next_in(VALUE obj)
TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
dst = zstream_detach_input(z);
- OBJ_INFECT(dst, obj);
return dst;
}
@@ -1604,9 +1734,8 @@ rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
args[0] = (VALUE)&z;
args[1] = src;
- dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);
+ dst = rb_ensure(deflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);
- OBJ_INFECT(dst, src);
return dst;
}
@@ -1656,7 +1785,6 @@ rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
VALUE src, flush;
rb_scan_args(argc, argv, "11", &src, &flush);
- OBJ_INFECT(obj, src);
do_deflate(z, src, ARG_FLUSH(flush));
return zstream_detach_buffer(z);
@@ -1674,7 +1802,6 @@ rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
static VALUE
rb_deflate_addstr(VALUE obj, VALUE src)
{
- OBJ_INFECT(obj, src);
do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
return obj;
}
@@ -1774,7 +1901,6 @@ rb_deflate_set_dictionary(VALUE obj, VALUE dic)
VALUE src = dic;
int err;
- OBJ_INFECT(obj, dic);
StringValue(src);
err = deflateSetDictionary(&z->stream,
(Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
@@ -1919,9 +2045,8 @@ rb_inflate_s_inflate(VALUE obj, VALUE src)
args[0] = (VALUE)&z;
args[1] = src;
- dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);
+ dst = rb_ensure(inflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);
- OBJ_INFECT(dst, src);
return dst;
}
@@ -1962,8 +2087,8 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
* Document-method: Zlib::Inflate#inflate
*
* call-seq:
- * inflate(deflate_string) -> String
- * inflate(deflate_string) { |chunk| ... } -> nil
+ * inflate(deflate_string, buffer: nil) -> String
+ * inflate(deflate_string, buffer: nil) { |chunk| ... } -> nil
*
* Inputs +deflate_string+ into the inflate stream and returns the output from
* the stream. Calling this method, both the input and the output buffer of
@@ -1973,6 +2098,15 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
* If a block is given consecutive inflated chunks from the +deflate_string+
* are yielded to the block and +nil+ is returned.
*
+ * If a :buffer keyword argument is given and not nil:
+ *
+ * * The :buffer keyword should be a String, and will used as the output buffer.
+ * Using this option can reuse the memory required during inflation.
+ * * When not passing a block, the return value will be the same object as the
+ * :buffer keyword argument.
+ * * When passing a block, the yielded chunks will be the same value as the
+ * :buffer keyword argument.
+ *
* Raises a Zlib::NeedDict exception if a preset dictionary is needed to
* decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
* call this method again with an empty string to flush the stream:
@@ -1996,12 +2130,37 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
* See also Zlib::Inflate.new
*/
static VALUE
-rb_inflate_inflate(VALUE obj, VALUE src)
+rb_inflate_inflate(int argc, VALUE* argv, VALUE obj)
{
struct zstream *z = get_zstream(obj);
- VALUE dst;
+ VALUE dst, src, opts, buffer = Qnil;
- OBJ_INFECT(obj, src);
+ if (OPTHASH_GIVEN_P(opts)) {
+ VALUE buf;
+ rb_get_kwargs(opts, &id_buffer, 0, 1, &buf);
+ if (buf != Qundef && buf != Qnil) {
+ buffer = StringValue(buf);
+ }
+ }
+ if (buffer != Qnil) {
+ if (!(ZSTREAM_REUSE_BUFFER_P(z) && z->buf == buffer)) {
+ long len = RSTRING_LEN(buffer);
+ if (len >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
+ rb_str_modify(buffer);
+ }
+ else {
+ len = ZSTREAM_AVAIL_OUT_STEP_MAX - len;
+ rb_str_modify_expand(buffer, len);
+ }
+ rb_str_set_len(buffer, 0);
+ z->flags |= ZSTREAM_REUSE_BUFFER;
+ z->buf = buffer;
+ }
+ } else if (ZSTREAM_REUSE_BUFFER_P(z)) {
+ z->flags &= ~ZSTREAM_REUSE_BUFFER;
+ z->buf = Qnil;
+ }
+ rb_scan_args(argc, argv, "10", &src);
if (ZSTREAM_IS_FINISHED(z)) {
if (NIL_P(src)) {
@@ -2010,8 +2169,11 @@ rb_inflate_inflate(VALUE obj, VALUE src)
else {
StringValue(src);
zstream_append_buffer2(z, src);
- dst = rb_str_new(0, 0);
- OBJ_INFECT(dst, obj);
+ if (ZSTREAM_REUSE_BUFFER_P(z)) {
+ dst = rb_str_resize(buffer, 0);
+ } else {
+ dst = rb_str_new(0, 0);
+ }
}
}
else {
@@ -2037,8 +2199,6 @@ rb_inflate_addstr(VALUE obj, VALUE src)
{
struct zstream *z = get_zstream(obj);
- OBJ_INFECT(obj, src);
-
if (ZSTREAM_IS_FINISHED(z)) {
if (!NIL_P(src)) {
StringValue(src);
@@ -2068,7 +2228,6 @@ rb_inflate_sync(VALUE obj, VALUE src)
{
struct zstream *z = get_zstream(obj);
- OBJ_INFECT(obj, src);
StringValue(src);
return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
}
@@ -2110,7 +2269,6 @@ rb_inflate_set_dictionary(VALUE obj, VALUE dic)
VALUE src = dic;
int err;
- OBJ_INFECT(obj, dic);
StringValue(src);
err = inflateSetDictionary(&z->stream,
(Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
@@ -2167,7 +2325,7 @@ rb_inflate_set_dictionary(VALUE obj, VALUE dic)
#define OS_CODE OS_UNIX
#endif
-static ID id_write, id_read, id_readpartial, id_flush, id_seek, id_close, id_path, id_input;
+static ID id_write, id_readpartial, id_flush, id_seek, id_close, id_path, id_input;
static VALUE cGzError, cNoFooter, cCRCError, cLengthError;
@@ -2191,7 +2349,6 @@ struct gzfile {
rb_encoding *enc2;
rb_econv_t *ec;
VALUE ecopts;
- char *cbuf;
VALUE path;
};
#define GZFILE_CBUF_CAPA 10
@@ -2199,12 +2356,23 @@ struct gzfile {
#define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
#define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
#define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
+#define GZFILE_FLAG_MTIME_IS_SET (ZSTREAM_FLAG_UNUSED << 3)
#define GZFILE_IS_FINISHED(gz) \
(ZSTREAM_IS_FINISHED(&(gz)->z) && ZSTREAM_BUF_FILLED(&(gz)->z) == 0)
#define GZFILE_READ_SIZE 2048
+struct read_raw_arg {
+ VALUE io;
+ union {
+ const VALUE argv[2]; /* for rb_funcallv */
+ struct {
+ VALUE len;
+ VALUE buf;
+ } in;
+ } as;
+};
static void
gzfile_mark(void *p)
@@ -2231,22 +2399,13 @@ gzfile_free(void *p)
}
zstream_finalize(z);
}
- if (gz->cbuf) {
- xfree(gz->cbuf);
- }
xfree(gz);
}
static size_t
gzfile_memsize(const void *p)
{
- const struct gzfile *gz = p;
- size_t size = sizeof(struct gzfile);
-
- if (gz->cbuf)
- size += GZFILE_CBUF_CAPA;
-
- return size;
+ return sizeof(struct gzfile);
}
static const rb_data_type_t gzfile_data_type = {
@@ -2275,7 +2434,6 @@ gzfile_init(struct gzfile *gz, const struct zstream_funcs *funcs, void (*endfunc
gz->ec = NULL;
gz->ecflags = 0;
gz->ecopts = Qnil;
- gz->cbuf = 0;
gz->path = Qnil;
}
@@ -2329,7 +2487,6 @@ gzfile_write_raw(struct gzfile *gz)
if (ZSTREAM_BUF_FILLED(&gz->z) > 0) {
str = zstream_detach_buffer(&gz->z);
- OBJ_TAINT(str); /* for safe */
rb_funcall(gz->io, id_write, 1, str);
if ((gz->z.flags & GZFILE_FLAG_SYNC)
&& rb_respond_to(gz->io, id_flush))
@@ -2340,21 +2497,23 @@ gzfile_write_raw(struct gzfile *gz)
static VALUE
gzfile_read_raw_partial(VALUE arg)
{
- struct gzfile *gz = (struct gzfile*)arg;
+ struct read_raw_arg *ra = (struct read_raw_arg *)arg;
VALUE str;
+ int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
- str = rb_funcall(gz->io, id_readpartial, 1, INT2FIX(GZFILE_READ_SIZE));
+ str = rb_funcallv(ra->io, id_readpartial, argc, ra->as.argv);
Check_Type(str, T_STRING);
return str;
}
static VALUE
-gzfile_read_raw_rescue(VALUE arg)
+gzfile_read_raw_rescue(VALUE arg, VALUE _)
{
- struct gzfile *gz = (struct gzfile*)arg;
+ struct read_raw_arg *ra = (struct read_raw_arg *)arg;
VALUE str = Qnil;
if (rb_obj_is_kind_of(rb_errinfo(), rb_eNoMethodError)) {
- str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));
+ int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
+ str = rb_funcallv(ra->io, id_read, argc, ra->as.argv);
if (!NIL_P(str)) {
Check_Type(str, T_STRING);
}
@@ -2363,15 +2522,21 @@ gzfile_read_raw_rescue(VALUE arg)
}
static VALUE
-gzfile_read_raw(struct gzfile *gz)
+gzfile_read_raw(struct gzfile *gz, VALUE outbuf)
{
- return rb_rescue2(gzfile_read_raw_partial, (VALUE)gz,
- gzfile_read_raw_rescue, (VALUE)gz,
+ struct read_raw_arg ra;
+
+ ra.io = gz->io;
+ ra.as.in.len = INT2FIX(GZFILE_READ_SIZE);
+ ra.as.in.buf = outbuf;
+
+ return rb_rescue2(gzfile_read_raw_partial, (VALUE)&ra,
+ gzfile_read_raw_rescue, (VALUE)&ra,
rb_eEOFError, rb_eNoMethodError, (VALUE)0);
}
static int
-gzfile_read_raw_ensure(struct gzfile *gz, long size)
+gzfile_read_raw_ensure(struct gzfile *gz, long size, VALUE outbuf)
{
VALUE str;
@@ -2380,7 +2545,7 @@ gzfile_read_raw_ensure(struct gzfile *gz, long size)
rb_raise(cGzError, "unexpected end of string");
}
while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
- str = gzfile_read_raw(gz);
+ str = gzfile_read_raw(gz, outbuf);
if (NIL_P(str)) return 0;
zstream_append_input2(&gz->z, str);
}
@@ -2397,7 +2562,7 @@ gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
RSTRING_LEN(gz->z.input) - offset);
if (p) break;
- str = gzfile_read_raw(gz);
+ str = gzfile_read_raw(gz, Qnil);
if (NIL_P(str)) {
rb_raise(cGzError, "unexpected end of file");
}
@@ -2478,7 +2643,7 @@ gzfile_make_header(struct gzfile *gz)
if (!NIL_P(gz->comment)) {
flags |= GZ_FLAG_COMMENT;
}
- if (gz->mtime == 0) {
+ if (!(gz->z.flags & GZFILE_FLAG_MTIME_IS_SET)) {
gz->mtime = time(0);
}
@@ -2522,13 +2687,14 @@ gzfile_make_footer(struct gzfile *gz)
}
static void
-gzfile_read_header(struct gzfile *gz)
+gzfile_read_header(struct gzfile *gz, VALUE outbuf)
{
const unsigned char *head;
long len;
char flags, *p;
- if (!gzfile_read_raw_ensure(gz, 10)) { /* 10 is the size of gzip header */
+ /* 10 is the size of gzip header */
+ if (!gzfile_read_raw_ensure(gz, 10, outbuf)) {
gzfile_raise(gz, cGzError, "not in gzip format");
}
@@ -2567,33 +2733,31 @@ gzfile_read_header(struct gzfile *gz)
zstream_discard_input(&gz->z, 10);
if (flags & GZ_FLAG_EXTRA) {
- if (!gzfile_read_raw_ensure(gz, 2)) {
+ if (!gzfile_read_raw_ensure(gz, 2, outbuf)) {
rb_raise(cGzError, "unexpected end of file");
}
len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
- if (!gzfile_read_raw_ensure(gz, 2 + len)) {
+ if (!gzfile_read_raw_ensure(gz, 2 + len, outbuf)) {
rb_raise(cGzError, "unexpected end of file");
}
zstream_discard_input(&gz->z, 2 + len);
}
if (flags & GZ_FLAG_ORIG_NAME) {
- if (!gzfile_read_raw_ensure(gz, 1)) {
+ if (!gzfile_read_raw_ensure(gz, 1, outbuf)) {
rb_raise(cGzError, "unexpected end of file");
}
p = gzfile_read_raw_until_zero(gz, 0);
len = p - RSTRING_PTR(gz->z.input);
gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
- OBJ_TAINT(gz->orig_name); /* for safe */
zstream_discard_input(&gz->z, len + 1);
}
if (flags & GZ_FLAG_COMMENT) {
- if (!gzfile_read_raw_ensure(gz, 1)) {
+ if (!gzfile_read_raw_ensure(gz, 1, outbuf)) {
rb_raise(cGzError, "unexpected end of file");
}
p = gzfile_read_raw_until_zero(gz, 0);
len = p - RSTRING_PTR(gz->z.input);
gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
- OBJ_TAINT(gz->comment); /* for safe */
zstream_discard_input(&gz->z, len + 1);
}
@@ -2603,13 +2767,14 @@ gzfile_read_header(struct gzfile *gz)
}
static void
-gzfile_check_footer(struct gzfile *gz)
+gzfile_check_footer(struct gzfile *gz, VALUE outbuf)
{
unsigned long crc, length;
gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
- if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */
+ /* 8 is the size of gzip footer */
+ if (!gzfile_read_raw_ensure(gz, 8, outbuf)) {
gzfile_raise(gz, cNoFooter, "footer is not found");
}
@@ -2643,12 +2808,12 @@ gzfile_write(struct gzfile *gz, Bytef *str, long len)
}
static long
-gzfile_read_more(struct gzfile *gz)
+gzfile_read_more(struct gzfile *gz, VALUE outbuf)
{
VALUE str;
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
- str = gzfile_read_raw(gz);
+ str = gzfile_read_raw(gz, outbuf);
if (NIL_P(str)) {
if (!ZSTREAM_IS_FINISHED(&gz->z)) {
rb_raise(cGzError, "unexpected end of file");
@@ -2683,13 +2848,11 @@ gzfile_newstr(struct gzfile *gz, VALUE str)
{
if (!gz->enc2) {
rb_enc_associate(str, gz->enc);
- OBJ_TAINT(str); /* for safe */
return str;
}
if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
rb_enc_associate(str, gz->enc);
- OBJ_TAINT(str);
return str;
}
return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
@@ -2704,11 +2867,11 @@ gzfile_fill(struct gzfile *gz, long len)
if (len == 0)
return 0;
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) {
- gzfile_read_more(gz);
+ gzfile_read_more(gz, Qnil);
}
if (GZFILE_IS_FINISHED(gz)) {
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
- gzfile_check_footer(gz);
+ gzfile_check_footer(gz, Qnil);
}
return -1;
}
@@ -2736,9 +2899,6 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
if (len < 0)
rb_raise(rb_eArgError, "negative length %ld given", len);
- if (!NIL_P(outbuf))
- OBJ_TAINT(outbuf);
-
if (len == 0) {
if (NIL_P(outbuf))
return rb_str_new(0, 0);
@@ -2748,11 +2908,11 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
}
}
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
- gzfile_read_more(gz);
+ gzfile_read_more(gz, outbuf);
}
if (GZFILE_IS_FINISHED(gz)) {
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
- gzfile_check_footer(gz);
+ gzfile_check_footer(gz, outbuf);
}
if (!NIL_P(outbuf))
rb_str_resize(outbuf, 0);
@@ -2765,10 +2925,10 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
if (!NIL_P(outbuf)) {
rb_str_resize(outbuf, RSTRING_LEN(dst));
memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
- RB_GC_GUARD(dst);
+ rb_str_resize(dst, 0);
+ rb_gc_force_recycle(dst);
dst = outbuf;
}
- OBJ_TAINT(dst); /* for safe */
return dst;
}
@@ -2778,11 +2938,11 @@ gzfile_read_all(struct gzfile *gz)
VALUE dst;
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
- gzfile_read_more(gz);
+ gzfile_read_more(gz, Qnil);
}
if (GZFILE_IS_FINISHED(gz)) {
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
- gzfile_check_footer(gz);
+ gzfile_check_footer(gz, Qnil);
}
return rb_str_new(0, 0);
}
@@ -2790,7 +2950,6 @@ gzfile_read_all(struct gzfile *gz)
dst = zstream_detach_buffer(&gz->z);
if (NIL_P(dst)) return dst;
gzfile_calc_crc(gz, dst);
- OBJ_TAINT(dst);
return gzfile_newstr(gz, dst);
}
@@ -2802,11 +2961,11 @@ gzfile_getc(struct gzfile *gz)
len = rb_enc_mbmaxlen(gz->enc);
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) {
- gzfile_read_more(gz);
+ gzfile_read_more(gz, Qnil);
}
if (GZFILE_IS_FINISHED(gz)) {
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
- gzfile_check_footer(gz);
+ gzfile_check_footer(gz, Qnil);
}
return Qnil;
}
@@ -2814,22 +2973,18 @@ gzfile_getc(struct gzfile *gz)
if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
const unsigned char *ss, *sp, *se;
unsigned char *ds, *dp, *de;
+ VALUE cbuf = rb_enc_str_new(0, GZFILE_CBUF_CAPA, gz->enc);
- if (!gz->cbuf) {
- gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
- }
ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
se = sp + ZSTREAM_BUF_FILLED(&gz->z);
- ds = dp = (unsigned char *)gz->cbuf;
+ ds = dp = (unsigned char *)RSTRING_PTR(cbuf);
de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
(void)rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
rb_econv_check_error(gz->ec);
dst = zstream_shift_buffer(&gz->z, sp - ss);
gzfile_calc_crc(gz, dst);
- dst = rb_str_new(gz->cbuf, dp - ds);
- rb_enc_associate(dst, gz->enc);
- OBJ_TAINT(dst);
- return dst;
+ rb_str_resize(cbuf, dp - ds);
+ return cbuf;
}
else {
buf = gz->z.buf;
@@ -2876,7 +3031,7 @@ gzfile_writer_end(struct gzfile *gz)
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
- rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
+ rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_ensure_end, (VALUE)&gz->z);
}
static VALUE
@@ -2886,7 +3041,7 @@ gzfile_reader_end_run(VALUE arg)
if (GZFILE_IS_FINISHED(gz)
&& !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
- gzfile_check_footer(gz);
+ gzfile_check_footer(gz, Qnil);
}
return Qnil;
@@ -2898,7 +3053,7 @@ gzfile_reader_end(struct gzfile *gz)
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
- rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
+ rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_ensure_end, (VALUE)&gz->z);
}
static void
@@ -2923,12 +3078,11 @@ gzfile_reader_get_unused(struct gzfile *gz)
if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
if (!GZFILE_IS_FINISHED(gz)) return Qnil;
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
- gzfile_check_footer(gz);
+ gzfile_check_footer(gz, Qnil);
}
if (NIL_P(gz->z.input)) return Qnil;
str = rb_str_resurrect(gz->z.input);
- OBJ_TAINT(str); /* for safe */
return str;
}
@@ -2995,7 +3149,7 @@ static VALUE
new_wrap(VALUE tmp)
{
new_wrap_arg_t *arg = (new_wrap_arg_t *)tmp;
- return rb_class_new_instance(arg->argc, arg->argv, arg->klass);
+ return rb_class_new_instance_kw(arg->argc, arg->argv, arg->klass, RB_PASS_CALLED_KEYWORDS);
}
static VALUE
@@ -3028,7 +3182,7 @@ gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
}
}
else {
- obj = rb_class_new_instance(argc, argv, klass);
+ obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
}
if (rb_block_given_p()) {
@@ -3145,7 +3299,6 @@ rb_gzfile_orig_name(VALUE obj)
if (!NIL_P(str)) {
str = rb_str_dup(str);
}
- OBJ_TAINT(str); /* for safe */
return str;
}
@@ -3162,7 +3315,6 @@ rb_gzfile_comment(VALUE obj)
if (!NIL_P(str)) {
str = rb_str_dup(str);
}
- OBJ_TAINT(str); /* for safe */
return str;
}
@@ -3221,6 +3373,7 @@ rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
val = rb_Integer(mtime);
gz->mtime = NUM2UINT(val);
+ gz->z.flags |= GZFILE_FLAG_MTIME_IS_SET;
return mtime;
}
@@ -3419,6 +3572,16 @@ rb_gzfile_path(VALUE obj)
return gz->path;
}
+static VALUE
+gzfile_initialize_path_partial(VALUE obj)
+{
+ struct gzfile* gz;
+ TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
+ gz->path = rb_funcall(gz->io, id_path, 0);
+ rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
+ return Qnil;
+}
+
static void
rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
{
@@ -3527,8 +3690,8 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
rb_gzfile_ecopts(gz, opt);
if (rb_respond_to(io, id_path)) {
- gz->path = rb_funcall(gz->io, id_path, 0);
- rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
+ /* File#path may raise IOError in case when a path is unavailable */
+ rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
}
return obj;
@@ -3566,18 +3729,23 @@ rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
* Same as IO.
*/
static VALUE
-rb_gzwriter_write(VALUE obj, VALUE str)
+rb_gzwriter_write(int argc, VALUE *argv, VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
-
- if (!RB_TYPE_P(str, T_STRING))
- str = rb_obj_as_string(str);
- if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
- str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
+ size_t total = 0;
+
+ while (argc-- > 0) {
+ VALUE str = *argv++;
+ if (!RB_TYPE_P(str, T_STRING))
+ str = rb_obj_as_string(str);
+ if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
+ str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
+ }
+ gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
+ total += RSTRING_LEN(str);
+ RB_GC_GUARD(str);
}
- gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
- RB_GC_GUARD(str);
- return INT2FIX(RSTRING_LEN(str));
+ return SIZET2NUM(total);
}
/*
@@ -3693,6 +3861,60 @@ rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
}
/*
+ * Document-method: Zlib::GzipReader.zcat
+ *
+ * call-seq:
+ * Zlib::GzipReader.zcat(io, options = {}, &block) => nil
+ * Zlib::GzipReader.zcat(io, options = {}) => string
+ *
+ * Decompresses all gzip data in the +io+, handling multiple gzip
+ * streams until the end of the +io+. There should not be any non-gzip
+ * data after the gzip streams.
+ *
+ * If a block is given, it is yielded strings of uncompressed data,
+ * and the method returns +nil+.
+ * If a block is not given, the method returns the concatenation of
+ * all uncompressed data in all gzip streams.
+ */
+static VALUE
+rb_gzreader_s_zcat(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE io, unused, obj, buf=0, tmpbuf;
+ long pos;
+
+ rb_check_arity(argc, 1, 2);
+ io = argv[0];
+
+ do {
+ obj = rb_funcallv(klass, rb_intern("new"), argc, argv);
+ if (rb_block_given_p()) {
+ rb_gzreader_each(0, 0, obj);
+ }
+ else {
+ if (!buf) {
+ buf = rb_str_new(0, 0);
+ }
+ tmpbuf = gzfile_read_all(get_gzfile(obj));
+ rb_str_cat(buf, RSTRING_PTR(tmpbuf), RSTRING_LEN(tmpbuf));
+ }
+
+ rb_gzreader_read(0, 0, obj);
+ pos = NUM2LONG(rb_funcall(io, rb_intern("pos"), 0));
+ unused = rb_gzreader_unused(obj);
+ rb_gzfile_finish(obj);
+ if (!NIL_P(unused)) {
+ pos -= NUM2LONG(rb_funcall(unused, rb_intern("length"), 0));
+ rb_funcall(io, rb_intern("pos="), 1, LONG2NUM(pos));
+ }
+ } while (pos < NUM2LONG(rb_funcall(io, rb_intern("size"), 0)));
+
+ if (rb_block_given_p()) {
+ return Qnil;
+ }
+ return buf;
+}
+
+/*
* Document-method: Zlib::GzipReader.new
*
* call-seq:
@@ -3726,12 +3948,12 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
}
gz->io = io;
ZSTREAM_READY(&gz->z);
- gzfile_read_header(gz);
+ gzfile_read_header(gz, Qnil);
rb_gzfile_ecopts(gz, opt);
if (rb_respond_to(io, id_path)) {
- gz->path = rb_funcall(gz->io, id_path, 0);
- rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
+ /* File#path may raise IOError in case when a path is unavailable */
+ rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
}
return obj;
@@ -3919,20 +4141,6 @@ rb_gzreader_each_byte(VALUE obj)
}
/*
- * Document-method: Zlib::GzipReader#bytes
- *
- * This is a deprecated alias for <code>each_byte</code>.
- */
-static VALUE
-rb_gzreader_bytes(VALUE obj)
-{
- rb_warn("Zlib::GzipReader#bytes is deprecated; use #each_byte instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(obj, ID2SYM(rb_intern("each_byte")), 0, 0);
- return rb_gzreader_each_byte(obj);
-}
-
-/*
* Document-method: Zlib::GzipReader#ungetc
*
* See Zlib::GzipReader documentation for a description.
@@ -3976,7 +4184,7 @@ gzreader_skip_linebreaks(struct gzfile *gz)
while (ZSTREAM_BUF_FILLED(&gz->z) == 0) {
if (GZFILE_IS_FINISHED(gz)) return;
- gzfile_read_more(gz);
+ gzfile_read_more(gz, Qnil);
}
n = 0;
p = RSTRING_PTR(gz->z.buf);
@@ -3987,7 +4195,7 @@ gzreader_skip_linebreaks(struct gzfile *gz)
gzfile_calc_crc(gz, str);
while (ZSTREAM_BUF_FILLED(&gz->z) == 0) {
if (GZFILE_IS_FINISHED(gz)) return;
- gzfile_read_more(gz);
+ gzfile_read_more(gz, Qnil);
}
n = 0;
p = RSTRING_PTR(gz->z.buf);
@@ -4109,7 +4317,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
if (ZSTREAM_BUF_FILLED(&gz->z) > 0) gz->lineno++;
return gzfile_read(gz, rslen);
}
- gzfile_read_more(gz);
+ gzfile_read_more(gz, Qnil);
}
p = RSTRING_PTR(gz->z.buf);
@@ -4118,7 +4326,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
long filled;
if (n > ZSTREAM_BUF_FILLED(&gz->z)) {
if (ZSTREAM_IS_FINISHED(&gz->z)) break;
- gzfile_read_more(gz);
+ gzfile_read_more(gz, Qnil);
p = RSTRING_PTR(gz->z.buf) + n - rslen;
}
if (!rspara) rscheck(rsptr, rslen, rs);
@@ -4158,6 +4366,8 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
* Document-method: Zlib::GzipReader#gets
*
* See Zlib::GzipReader documentation for a description.
+ * However, note that this method can return +nil+ even if
+ * #eof? returns false, unlike the behavior of File#gets.
*/
static VALUE
rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
@@ -4205,20 +4415,6 @@ rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
}
/*
- * Document-method: Zlib::GzipReader#lines
- *
- * This is a deprecated alias for <code>each_line</code>.
- */
-static VALUE
-rb_gzreader_lines(int argc, VALUE *argv, VALUE obj)
-{
- rb_warn("Zlib::GzipReader#lines is deprecated; use #each_line instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(obj, ID2SYM(rb_intern("each_line")), argc, argv);
- return rb_gzreader_each(argc, argv, obj);
-}
-
-/*
* Document-method: Zlib::GzipReader#readlines
*
* See Zlib::GzipReader documentation for a description.
@@ -4246,13 +4442,19 @@ rb_gzreader_external_encoding(VALUE self)
}
static VALUE
-zlib_gzip_ensure(VALUE arg)
+zlib_gzip_end_rescue(VALUE arg)
{
struct gzfile *gz = (struct gzfile *)arg;
- rb_rescue((VALUE(*)())gz->end, arg, NULL, Qnil);
+ gz->end(gz);
return Qnil;
}
+static VALUE
+zlib_gzip_ensure(VALUE arg)
+{
+ return rb_rescue(zlib_gzip_end_rescue, arg, NULL, Qnil);
+}
+
static void
zlib_gzip_end(struct gzfile *gz)
{
@@ -4262,8 +4464,6 @@ zlib_gzip_end(struct gzfile *gz)
zstream_end(&gz->z);
}
-#define OPTHASH_GIVEN_P(opts) \
- (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
static ID id_level, id_strategy;
static VALUE zlib_gzip_run(VALUE arg);
@@ -4398,7 +4598,7 @@ zlib_gunzip_run(VALUE arg)
struct gzfile *gz = (struct gzfile *)arg;
VALUE dst;
- gzfile_read_header(gz);
+ gzfile_read_header(gz, Qnil);
dst = zstream_detach_buffer(&gz->z);
gzfile_calc_crc(gz, dst);
if (!ZSTREAM_IS_FINISHED(&gz->z)) {
@@ -4407,7 +4607,7 @@ zlib_gunzip_run(VALUE arg)
if (NIL_P(gz->z.input)) {
rb_raise(cNoFooter, "footer is not found");
}
- gzfile_check_footer(gz);
+ gzfile_check_footer(gz, Qnil);
return dst;
}
@@ -4416,6 +4616,11 @@ zlib_gunzip_run(VALUE arg)
void
Init_zlib(void)
{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+#undef rb_intern
VALUE mZlib, cZStream, cDeflate, cInflate;
#if GZIP_SUPPORT
VALUE cGzipFile, cGzipWriter, cGzipReader;
@@ -4433,6 +4638,7 @@ Init_zlib(void)
cMemError = rb_define_class_under(mZlib, "MemError", cZError);
cBufError = rb_define_class_under(mZlib, "BufError", cZError);
cVersionError = rb_define_class_under(mZlib, "VersionError", cZError);
+ cInProgressError = rb_define_class_under(mZlib, "InProgressError", cZError);
rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0);
rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1);
@@ -4509,7 +4715,7 @@ Init_zlib(void)
rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
rb_define_method(cInflate, "add_dictionary", rb_inflate_add_dictionary, 1);
- rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
+ rb_define_method(cInflate, "inflate", rb_inflate_inflate, -1);
rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
@@ -4650,7 +4856,7 @@ Init_zlib(void)
rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate);
rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1);
rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1);
- rb_define_method(cGzipWriter, "write", rb_gzwriter_write, 1);
+ rb_define_method(cGzipWriter, "write", rb_gzwriter_write, -1);
rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1);
rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1);
rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1);
@@ -4658,6 +4864,7 @@ Init_zlib(void)
rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);
rb_define_singleton_method(cGzipReader, "open", rb_gzreader_s_open,-1);
+ rb_define_singleton_method(cGzipReader, "zcat", rb_gzreader_s_zcat, -1);
rb_define_alloc_func(cGzipReader, rb_gzreader_s_allocate);
rb_define_method(cGzipReader, "initialize", rb_gzreader_initialize, -1);
rb_define_method(cGzipReader, "rewind", rb_gzreader_rewind, 0);
@@ -4670,14 +4877,12 @@ Init_zlib(void)
rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
- rb_define_method(cGzipReader, "bytes", rb_gzreader_bytes, 0);
rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
- rb_define_method(cGzipReader, "lines", rb_gzreader_lines, -1);
rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
rb_define_method(cGzipReader, "external_encoding", rb_gzreader_external_encoding, 0);
@@ -4719,6 +4924,7 @@ Init_zlib(void)
id_level = rb_intern("level");
id_strategy = rb_intern("strategy");
+ id_buffer = rb_intern("buffer");
#endif /* GZIP_SUPPORT */
}
@@ -4740,6 +4946,7 @@ Init_zlib(void)
* - Zlib::MemError
* - Zlib::BufError
* - Zlib::VersionError
+ * - Zlib::InProgressError
*
*/
@@ -4815,6 +5022,20 @@ Init_zlib(void)
*/
/*
+ * Document-class: Zlib::InProgressError
+ *
+ * Subclass of Zlib::Error. This error is raised when the zlib
+ * stream is currently in progress.
+ *
+ * For example:
+ *
+ * inflater = Zlib::Inflate.new
+ * inflater.inflate(compressed) do
+ * inflater.inflate(compressed) # Raises Zlib::InProgressError
+ * end
+ */
+
+/*
* Document-class: Zlib::GzipFile::Error
*
* Base class of errors that occur when processing GZIP files.
@@ -4839,5 +5060,3 @@ Init_zlib(void)
* Raised when the data length recorded in the gzip file footer is not equivalent
* to the length of the actual uncompressed data.
*/
-
-
diff --git a/ext/zlib/zlib.gemspec b/ext/zlib/zlib.gemspec
index a0ac8fa423..1d35065921 100644
--- a/ext/zlib/zlib.gemspec
+++ b/ext/zlib/zlib.gemspec
@@ -1,23 +1,33 @@
# coding: utf-8
# frozen_string_literal: true
+
+source_version = ["", "ext/zlib/"].find do |dir|
+ begin
+ break File.open(File.join(__dir__, "#{dir}zlib.c")) {|f|
+ f.gets("\n#define RUBY_ZLIB_VERSION ")
+ f.gets[/\s*"(.+)"/, 1]
+ }
+ rescue Errno::ENOENT
+ end
+end
+
Gem::Specification.new do |spec|
spec.name = "zlib"
- spec.version = "0.1.0"
- spec.date = '2017-09-13'
+ spec.version = source_version
spec.authors = ["Yukihiro Matsumoto", "UENO Katsuhiro"]
spec.email = ["matz@ruby-lang.org", nil]
spec.summary = %q{Ruby interface for the zlib compression/decompression library}
spec.description = %q{Ruby interface for the zlib compression/decompression library}
spec.homepage = "https://github.com/ruby/zlib"
- spec.license = "BSD-2-Clause"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "ext/zlib/extconf.rb", "ext/zlib/zlib.c", "zlib.gemspec"]
+ spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "ext/zlib/extconf.rb", "ext/zlib/zlib.c", "zlib.gemspec"]
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.extensions = "ext/zlib/extconf.rb"
- spec.required_ruby_version = ">= 2.5.0dev"
+ spec.required_ruby_version = ">= 2.3.0"
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
diff --git a/file.c b/file.c
index 7fad74508a..dc832a8d9c 100644
--- a/file.c
+++ b/file.c
@@ -11,29 +11,38 @@
**********************************************************************/
+#include "ruby/internal/config.h"
+
#ifdef _WIN32
-#include "missing/file.h"
+# include "missing/file.h"
+# include "ruby.h"
#endif
+
+#include <ctype.h>
+#include <time.h>
+
#ifdef __CYGWIN__
-#include <windows.h>
-#include <sys/cygwin.h>
-#include <wchar.h>
+# include <windows.h>
+# include <sys/cygwin.h>
+# include <wchar.h>
#endif
+
#ifdef __APPLE__
-#include <CoreFoundation/CFString.h>
+# if !(defined(__has_feature) && defined(__has_attribute))
+/* Maybe a bug in SDK of Xcode 10.2.1 */
+/* In this condition, <os/availability.h> does not define
+ * API_AVAILABLE and similar, but __API_AVAILABLE and similar which
+ * are defined in <Availability.h> */
+# define API_AVAILABLE(...)
+# define API_DEPRECATED(...)
+# endif
+# include <CoreFoundation/CFString.h>
#endif
-#include "id.h"
-#include "internal.h"
-#include "ruby/io.h"
-#include "ruby/util.h"
-#include "ruby/thread.h"
-#include "dln.h"
-#include "encindex.h"
-
#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+# include <unistd.h>
#endif
+
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
@@ -51,81 +60,73 @@ int flock(int, int);
# define MAXPATHLEN 1024
#endif
-#include <ctype.h>
-
-#include <time.h>
-
#ifdef HAVE_UTIME_H
-#include <utime.h>
+# include <utime.h>
#elif defined HAVE_SYS_UTIME_H
-#include <sys/utime.h>
+# include <sys/utime.h>
#endif
#ifdef HAVE_PWD_H
-#include <pwd.h>
+# include <pwd.h>
#endif
#ifdef HAVE_SYS_SYSMACROS_H
-#include <sys/sysmacros.h>
+# include <sys/sysmacros.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
-#if defined(__native_client__)
-# if defined(NACL_NEWLIB)
-# include "nacl/utime.h"
-# include "nacl/stat.h"
-# include "nacl/unistd.h"
-# else
-# undef HAVE_UTIMENSAT
-# endif
-#endif
-
#ifdef HAVE_SYS_MKDEV_H
-#include <sys/mkdev.h>
+# include <sys/mkdev.h>
#endif
#if defined(HAVE_FCNTL_H)
-#include <fcntl.h>
+# include <fcntl.h>
#endif
#if defined(HAVE_SYS_TIME_H)
-#include <sys/time.h>
+# include <sys/time.h>
#endif
#if !defined HAVE_LSTAT && !defined lstat
-#define lstat stat
+# define lstat stat
#endif
/* define system APIs */
#ifdef _WIN32
-#include "win32/file.h"
-#define STAT(p, s) rb_w32_ustati64((p), (s))
-#undef lstat
-#define lstat(p, s) rb_w32_ulstati64((p), (s))
-#undef access
-#define access(p, m) rb_w32_uaccess((p), (m))
-#undef truncate
-#define truncate(p, n) rb_w32_utruncate((p), (n))
-#undef chmod
-#define chmod(p, m) rb_w32_uchmod((p), (m))
-#undef chown
-#define chown(p, o, g) rb_w32_uchown((p), (o), (g))
-#undef lchown
-#define lchown(p, o, g) rb_w32_ulchown((p), (o), (g))
-#undef utime
-#define utime(p, t) rb_w32_uutime((p), (t))
-#undef link
-#define link(f, t) rb_w32_ulink((f), (t))
-#undef unlink
-#define unlink(p) rb_w32_uunlink(p)
-#undef rename
-#define rename(f, t) rb_w32_urename((f), (t))
-#undef symlink
-#define symlink(s, l) rb_w32_usymlink((s), (l))
+# include "win32/file.h"
+# define STAT(p, s) rb_w32_ustati128((p), (s))
+# undef lstat
+# define lstat(p, s) rb_w32_ulstati128((p), (s))
+# undef access
+# define access(p, m) rb_w32_uaccess((p), (m))
+# undef truncate
+# define truncate(p, n) rb_w32_utruncate((p), (n))
+# undef chmod
+# define chmod(p, m) rb_w32_uchmod((p), (m))
+# undef chown
+# define chown(p, o, g) rb_w32_uchown((p), (o), (g))
+# undef lchown
+# define lchown(p, o, g) rb_w32_ulchown((p), (o), (g))
+# undef utimensat
+# define utimensat(s, p, t, f) rb_w32_uutimensat((s), (p), (t), (f))
+# undef link
+# define link(f, t) rb_w32_ulink((f), (t))
+# undef unlink
+# define unlink(p) rb_w32_uunlink(p)
+# undef rename
+# define rename(f, t) rb_w32_urename((f), (t))
+# undef symlink
+# define symlink(s, l) rb_w32_usymlink((s), (l))
+
+# ifdef HAVE_REALPATH
+/* Don't use native realpath(3) on Windows, as the check for
+ absolute paths does not work for drive letters. */
+# undef HAVE_REALPATH
+# endif
#else
-#define STAT(p, s) stat((p), (s))
+# define STAT(p, s) stat((p), (s))
#endif
#if defined _WIN32 || defined __APPLE__
@@ -136,12 +137,44 @@ int flock(int, int);
# define TO_OSPATH(str) (str)
#endif
+/* utime may fail if time is out-of-range for the FS [ruby-dev:38277] */
+#if defined DOSISH || defined __CYGWIN__
+# define UTIME_EINVAL
+#endif
+
+/* Solaris 10 realpath(3) doesn't support File.realpath */
+#if defined HAVE_REALPATH && defined __sun && defined __SVR4
+#undef HAVE_REALPATH
+#endif
+
+#ifdef HAVE_REALPATH
+# include <limits.h>
+# include <stdlib.h>
+#endif
+
+#include "dln.h"
+#include "encindex.h"
+#include "id.h"
+#include "internal.h"
+#include "internal/compilers.h"
+#include "internal/dir.h"
+#include "internal/error.h"
+#include "internal/file.h"
+#include "internal/io.h"
+#include "internal/load.h"
+#include "internal/object.h"
+#include "internal/process.h"
+#include "internal/thread.h"
+#include "internal/vm.h"
+#include "ruby/encoding.h"
+#include "ruby/io.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+
VALUE rb_cFile;
VALUE rb_mFileTest;
VALUE rb_cStat;
-#define insecure_obj_p(obj, level) ((level) > 0 && OBJ_TAINTED(obj))
-
static VALUE
file_path_convert(VALUE name)
{
@@ -175,15 +208,11 @@ check_path_encoding(VALUE str)
}
VALUE
-rb_get_path_check_to_string(VALUE obj, int level)
+rb_get_path_check_to_string(VALUE obj)
{
VALUE tmp;
ID to_path;
- if (insecure_obj_p(obj, level)) {
- rb_insecure_operation();
- }
-
if (RB_TYPE_P(obj, T_STRING)) {
return obj;
}
@@ -194,38 +223,28 @@ rb_get_path_check_to_string(VALUE obj, int level)
}
VALUE
-rb_get_path_check_convert(VALUE obj, VALUE tmp, int level)
+rb_get_path_check_convert(VALUE obj)
{
- tmp = file_path_convert(tmp);
- if (obj != tmp && insecure_obj_p(tmp, level)) {
- rb_insecure_operation();
- }
+ obj = file_path_convert(obj);
- check_path_encoding(tmp);
- if (!rb_str_to_cstr(tmp)) {
+ check_path_encoding(obj);
+ if (!rb_str_to_cstr(obj)) {
rb_raise(rb_eArgError, "path name contains null byte");
}
- return rb_str_new4(tmp);
-}
-
-VALUE
-rb_get_path_check(VALUE obj, int level)
-{
- VALUE tmp = rb_get_path_check_to_string(obj, level);
- return rb_get_path_check_convert(obj, tmp, level);
+ return rb_str_new4(obj);
}
VALUE
rb_get_path_no_checksafe(VALUE obj)
{
- return rb_get_path_check(obj, 0);
+ return rb_get_path(obj);
}
VALUE
rb_get_path(VALUE obj)
{
- return rb_get_path_check(obj, rb_safe_level());
+ return rb_get_path_check_convert(rb_get_path_check_to_string(obj));
}
VALUE
@@ -233,12 +252,12 @@ rb_str_encode_ospath(VALUE path)
{
#if USE_OSPATH
int encidx = ENCODING_GET(path);
-#ifdef _WIN32
+#if 0 && defined _WIN32
if (encidx == ENCINDEX_ASCII) {
encidx = rb_filesystem_encindex();
}
#endif
- if (encidx != ENCINDEX_UTF_8) {
+ if (encidx != ENCINDEX_ASCII && encidx != ENCINDEX_UTF_8) {
rb_encoding *enc = rb_enc_from_index(encidx);
rb_encoding *utf8 = rb_utf8_encoding();
path = rb_str_conv_enc(path, enc, utf8);
@@ -249,6 +268,46 @@ rb_str_encode_ospath(VALUE path)
#ifdef __APPLE__
# define NORMALIZE_UTF8PATH 1
+
+# ifdef HAVE_WORKING_FORK
+static void
+rb_CFString_class_initialize_before_fork(void)
+{
+ /*
+ * Since macOS 13, CFString family API used in
+ * rb_str_append_normalized_ospath may internally use Objective-C classes
+ * (NSTaggedPointerString and NSPlaceholderMutableString) for small strings.
+ *
+ * On the other hand, Objective-C classes should not be used for the first
+ * time in a fork()'ed but not exec()'ed process. Violations for this rule
+ * can result deadlock during class initialization, so Objective-C runtime
+ * conservatively crashes on such cases by default.
+ *
+ * Therefore, we need to use CFString API to initialize Objective-C classes
+ * used internally *before* fork().
+ *
+ * For future changes, please note that this initialization process cannot
+ * be done in ctor because NSTaggedPointerString in CoreFoundation is enabled
+ * after CFStringInitializeTaggedStrings(), which is called during loading
+ * Objective-C runtime after ctor.
+ * For more details, see https://bugs.ruby-lang.org/issues/18912
+ */
+
+ /* Enough small but non-empty ASCII string to fit in NSTaggedPointerString. */
+ const char small_str[] = "/";
+ long len = sizeof(small_str) - 1;
+
+ const CFAllocatorRef alloc = kCFAllocatorDefault;
+ CFStringRef s = CFStringCreateWithBytesNoCopy(alloc,
+ (const UInt8 *)small_str,
+ len, kCFStringEncodingUTF8,
+ FALSE, kCFAllocatorNull);
+ CFMutableStringRef m = CFStringCreateMutableCopy(alloc, len, s);
+ CFRelease(m);
+ CFRelease(s);
+}
+# endif
+
static VALUE
rb_str_append_normalized_ospath(VALUE str, const char *ptr, long len)
{
@@ -354,20 +413,72 @@ ignored_char_p(const char *p, const char *e, rb_encoding *enc)
#define apply2args(n) (rb_check_arity(argc, n, UNLIMITED_ARGUMENTS), argc-=n)
+struct apply_filename {
+ const char *ptr;
+ VALUE path;
+};
+
+struct apply_arg {
+ int i;
+ int argc;
+ int errnum;
+ int (*func)(const char *, void *);
+ void *arg;
+ struct apply_filename fn[FLEX_ARY_LEN];
+};
+
+static void *
+no_gvl_apply2files(void *ptr)
+{
+ struct apply_arg *aa = ptr;
+
+ for (aa->i = 0; aa->i < aa->argc; aa->i++) {
+ if (aa->func(aa->fn[aa->i].ptr, aa->arg) < 0) {
+ aa->errnum = errno;
+ break;
+ }
+ }
+ return 0;
+}
+
+#ifdef UTIME_EINVAL
+NORETURN(static void utime_failed(struct apply_arg *));
+static int utime_internal(const char *, void *);
+#endif
+
static VALUE
-apply2files(void (*func)(const char *, VALUE, void *), int argc, VALUE *argv, void *arg)
+apply2files(int (*func)(const char *, void *), int argc, VALUE *argv, void *arg)
{
- long i;
- VALUE path;
+ VALUE v;
+ const size_t size = sizeof(struct apply_filename);
+ const long len = (long)(offsetof(struct apply_arg, fn) + (size * argc));
+ struct apply_arg *aa = ALLOCV(v, len);
+
+ aa->errnum = 0;
+ aa->argc = argc;
+ aa->arg = arg;
+ aa->func = func;
+
+ for (aa->i = 0; aa->i < argc; aa->i++) {
+ VALUE path = rb_get_path(argv[aa->i]);
- for (i=0; i<argc; i++) {
- const char *s;
- path = rb_get_path(argv[i]);
path = rb_str_encode_ospath(path);
- s = RSTRING_PTR(path);
- (*func)(s, path, arg);
+ aa->fn[aa->i].ptr = RSTRING_PTR(path);
+ aa->fn[aa->i].path = path;
}
+ rb_thread_call_without_gvl(no_gvl_apply2files, aa, RUBY_UBF_IO, 0);
+ if (aa->errnum) {
+#ifdef UTIME_EINVAL
+ if (func == utime_internal) {
+ utime_failed(aa);
+ }
+#endif
+ rb_syserr_fail_path(aa->errnum, aa->fn[aa->i].path);
+ }
+ if (v) {
+ ALLOCV_END(v);
+ }
return LONG2FIX(argc);
}
@@ -379,11 +490,12 @@ apply2files(void (*func)(const char *, VALUE, void *), int argc, VALUE *argv, vo
* Returns the pathname used to create <i>file</i> as a string. Does
* not normalize the name.
*
- * The pathname may not point the file corresponding to <i>file</i>.
- * For instance, pathname becomes inaccurate when file has been moved or deleted.
+ * The pathname may not point to the file corresponding to <i>file</i>.
+ * For instance, the pathname becomes void when the file has been
+ * moved or deleted.
*
- * This method raises <code>IOError</code> for a <i>file</i> created using
- * <code>File::Constants::TMPFILE</code> because they don't have a pathname.
+ * This method raises IOError for a <i>file</i> created using
+ * File::Constants::TMPFILE because they don't have a pathname.
*
* File.new("testfile").path #=> "testfile"
* File.new("/tmp/../tmp/xxx", "w").path #=> "/tmp/../tmp/xxx"
@@ -402,7 +514,7 @@ rb_file_path(VALUE obj)
rb_raise(rb_eIOError, "File is unnamed (TMPFILE?)");
}
- return rb_obj_taint(rb_str_dup(fptr->pathv));
+ return rb_str_dup(fptr->pathv);
}
static size_t
@@ -446,7 +558,7 @@ get_stat(VALUE self)
return st;
}
-static struct timespec stat_mtimespec(struct stat *st);
+static struct timespec stat_mtimespec(const struct stat *st);
/*
* call-seq:
@@ -523,7 +635,7 @@ static VALUE
rb_stat_dev_major(VALUE self)
{
#if defined(major)
- return DEVT2NUM(major(get_stat(self)->st_dev));
+ return UINT2NUM(major(get_stat(self)->st_dev));
#else
return Qnil;
#endif
@@ -544,7 +656,7 @@ static VALUE
rb_stat_dev_minor(VALUE self)
{
#if defined(minor)
- return DEVT2NUM(minor(get_stat(self)->st_dev));
+ return UINT2NUM(minor(get_stat(self)->st_dev));
#else
return Qnil;
#endif
@@ -563,17 +675,12 @@ rb_stat_dev_minor(VALUE self)
static VALUE
rb_stat_ino(VALUE self)
{
-#ifdef _WIN32
- struct stat *st = get_stat(self);
- unsigned short *p2 = (unsigned short *)st;
- unsigned int *p4 = (unsigned int *)st;
- uint64_t r;
- r = p2[2];
- r <<= 16;
- r |= p2[7];
- r <<= 32;
- r |= p4[5];
- return ULL2NUM(r);
+#ifdef HAVE_STRUCT_STAT_ST_INOHIGH
+ /* assume INTEGER_PACK_LSWORD_FIRST and st_inohigh is just next of st_ino */
+ return rb_integer_unpack(&get_stat(self)->st_ino, 2,
+ SIZEOF_STRUCT_STAT_ST_INO, 0,
+ INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
+ INTEGER_PACK_2COMP);
#elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
return ULL2NUM(get_stat(self)->st_ino);
#else
@@ -615,7 +722,21 @@ rb_stat_mode(VALUE self)
static VALUE
rb_stat_nlink(VALUE self)
{
- return UINT2NUM(get_stat(self)->st_nlink);
+ /* struct stat::st_nlink is nlink_t in POSIX. Not the case for Windows. */
+ const struct stat *ptr = get_stat(self);
+
+ if (sizeof(ptr->st_nlink) <= sizeof(int)) {
+ return UINT2NUM((unsigned)ptr->st_nlink);
+ }
+ else if (sizeof(ptr->st_nlink) == sizeof(long)) {
+ return ULONG2NUM((unsigned long)ptr->st_nlink);
+ }
+ else if (sizeof(ptr->st_nlink) == sizeof(LONG_LONG)) {
+ return ULL2NUM((unsigned LONG_LONG)ptr->st_nlink);
+ }
+ else {
+ rb_bug(":FIXME: don't know what to do");
+ }
}
/*
@@ -687,7 +808,7 @@ static VALUE
rb_stat_rdev_major(VALUE self)
{
#if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(major)
- return DEVT2NUM(major(get_stat(self)->st_rdev));
+ return UINT2NUM(major(get_stat(self)->st_rdev));
#else
return Qnil;
#endif
@@ -708,7 +829,7 @@ static VALUE
rb_stat_rdev_minor(VALUE self)
{
#if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(minor)
- return DEVT2NUM(minor(get_stat(self)->st_rdev));
+ return UINT2NUM(minor(get_stat(self)->st_rdev));
#else
return Qnil;
#endif
@@ -776,7 +897,7 @@ rb_stat_blocks(VALUE self)
}
static struct timespec
-stat_atimespec(struct stat *st)
+stat_atimespec(const struct stat *st)
{
struct timespec ts;
ts.tv_sec = st->st_atime;
@@ -793,14 +914,14 @@ stat_atimespec(struct stat *st)
}
static VALUE
-stat_atime(struct stat *st)
+stat_atime(const struct stat *st)
{
struct timespec ts = stat_atimespec(st);
return rb_time_nano_new(ts.tv_sec, ts.tv_nsec);
}
static struct timespec
-stat_mtimespec(struct stat *st)
+stat_mtimespec(const struct stat *st)
{
struct timespec ts;
ts.tv_sec = st->st_mtime;
@@ -817,14 +938,14 @@ stat_mtimespec(struct stat *st)
}
static VALUE
-stat_mtime(struct stat *st)
+stat_mtime(const struct stat *st)
{
struct timespec ts = stat_mtimespec(st);
return rb_time_nano_new(ts.tv_sec, ts.tv_nsec);
}
static struct timespec
-stat_ctimespec(struct stat *st)
+stat_ctimespec(const struct stat *st)
{
struct timespec ts;
ts.tv_sec = st->st_ctime;
@@ -841,7 +962,7 @@ stat_ctimespec(struct stat *st)
}
static VALUE
-stat_ctime(struct stat *st)
+stat_ctime(const struct stat *st)
{
struct timespec ts = stat_ctimespec(st);
return rb_time_nano_new(ts.tv_sec, ts.tv_nsec);
@@ -849,13 +970,15 @@ stat_ctime(struct stat *st)
#define HAVE_STAT_BIRTHTIME
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
+typedef struct stat statx_data;
static VALUE
-stat_birthtime(struct stat *st)
+stat_birthtime(const struct stat *st)
{
- struct timespec *ts = &st->st_birthtimespec;
+ const struct timespec *ts = &st->st_birthtimespec;
return rb_time_nano_new(ts->tv_sec, ts->tv_nsec);
}
#elif defined(_WIN32)
+typedef struct stat statx_data;
# define stat_birthtime stat_ctime
#else
# undef HAVE_STAT_BIRTHTIME
@@ -866,7 +989,7 @@ stat_birthtime(struct stat *st)
* stat.atime -> time
*
* Returns the last access time for this file as an object of class
- * <code>Time</code>.
+ * Time.
*
* File.stat("testfile").atime #=> Wed Dec 31 18:00:00 CST 1969
*
@@ -1018,7 +1141,6 @@ rb_stat_inspect(VALUE self)
}
}
rb_str_buf_cat2(str, ">");
- OBJ_INFECT(str, self);
return str;
}
@@ -1038,6 +1160,17 @@ no_gvl_fstat(void *data)
return (VALUE)fstat(arg->file.fd, arg->st);
}
+static int
+fstat_without_gvl(int fd, struct stat *st)
+{
+ no_gvl_stat_data data;
+
+ data.file.fd = fd;
+ data.st = st;
+
+ return (int)(VALUE)rb_thread_io_blocking_region(no_gvl_fstat, &data, fd);
+}
+
static void *
no_gvl_stat(void * data)
{
@@ -1046,96 +1179,164 @@ no_gvl_stat(void * data)
}
static int
-rb_stat(VALUE file, struct stat *st)
+stat_without_gvl(const char *path, struct stat *st)
{
- VALUE tmp;
- VALUE result;
no_gvl_stat_data data;
+ data.file.path = path;
data.st = st;
- tmp = rb_check_convert_type_with_id(file, T_FILE, "IO", idTo_io);
- if (!NIL_P(tmp)) {
- rb_io_t *fptr;
- GetOpenFile(tmp, fptr);
- data.file.fd = fptr->fd;
- result = rb_thread_io_blocking_region(no_gvl_fstat, &data, fptr->fd);
- return (int)result;
- }
- FilePathValue(file);
- file = rb_str_encode_ospath(file);
- data.file.path = StringValueCStr(file);
- result = (VALUE)rb_thread_call_without_gvl(no_gvl_stat, &data, RUBY_UBF_IO, NULL);
- return (int)result;
+ return (int)(VALUE)rb_thread_call_without_gvl(no_gvl_stat, &data,
+ RUBY_UBF_IO, NULL);
}
-#ifdef _WIN32
-static HANDLE
-w32_io_info(VALUE *file, BY_HANDLE_FILE_INFORMATION *st)
+#if !defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) && \
+ defined(HAVE_STRUCT_STATX_STX_BTIME)
+
+# ifndef HAVE_STATX
+# ifdef HAVE_SYSCALL_H
+# include <syscall.h>
+# elif defined HAVE_SYS_SYSCALL_H
+# include <sys/syscall.h>
+# endif
+# if defined __linux__
+# include <linux/stat.h>
+static inline int
+statx(int dirfd, const char *pathname, int flags,
+ unsigned int mask, struct statx *statxbuf)
+{
+ return (int)syscall(__NR_statx, dirfd, pathname, flags, mask, statxbuf);
+}
+# endif
+# endif
+
+typedef struct no_gvl_statx_data {
+ struct statx *stx;
+ int fd;
+ const char *path;
+ int flags;
+ unsigned int mask;
+} no_gvl_statx_data;
+
+static VALUE
+io_blocking_statx(void *data)
+{
+ no_gvl_statx_data *arg = data;
+ return (VALUE)statx(arg->fd, arg->path, arg->flags, arg->mask, arg->stx);
+}
+
+static void *
+no_gvl_statx(void *data)
+{
+ return (void *)io_blocking_statx(data);
+}
+
+static int
+statx_without_gvl(const char *path, struct statx *stx, unsigned int mask)
+{
+ no_gvl_statx_data data = {stx, AT_FDCWD, path, 0, mask};
+
+ /* call statx(2) with pathname */
+ return (int)(VALUE)rb_thread_call_without_gvl(no_gvl_statx, &data,
+ RUBY_UBF_IO, NULL);
+}
+
+static int
+fstatx_without_gvl(int fd, struct statx *stx, unsigned int mask)
+{
+ no_gvl_statx_data data = {stx, fd, "", AT_EMPTY_PATH, mask};
+
+ /* call statx(2) with fd */
+ return (int)rb_thread_io_blocking_region(io_blocking_statx, &data, fd);
+}
+
+static int
+rb_statx(VALUE file, struct statx *stx, unsigned int mask)
{
VALUE tmp;
- HANDLE f, ret = 0;
+ int result;
- tmp = rb_check_convert_type_with_id(*file, T_FILE, "IO", idTo_io);
+ tmp = rb_check_convert_type_with_id(file, T_FILE, "IO", idTo_io);
if (!NIL_P(tmp)) {
- rb_io_t *fptr;
-
- GetOpenFile(tmp, fptr);
- f = (HANDLE)rb_w32_get_osfhandle(fptr->fd);
- if (f == (HANDLE)-1) return INVALID_HANDLE_VALUE;
+ rb_io_t *fptr;
+ GetOpenFile(tmp, fptr);
+ result = fstatx_without_gvl(fptr->fd, stx, mask);
+ file = tmp;
}
else {
- VALUE tmp;
- WCHAR *ptr;
- int len;
- VALUE v;
-
- FilePathValue(*file);
- tmp = rb_str_encode_ospath(*file);
- len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(tmp), -1, NULL, 0);
- ptr = ALLOCV_N(WCHAR, v, len);
- MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(tmp), -1, ptr, len);
- f = CreateFileW(ptr, 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, NULL);
- ALLOCV_END(v);
- if (f == INVALID_HANDLE_VALUE) return f;
- ret = f;
- }
- if (GetFileType(f) == FILE_TYPE_DISK) {
- ZeroMemory(st, sizeof(*st));
- if (GetFileInformationByHandle(f, st)) return ret;
+ FilePathValue(file);
+ file = rb_str_encode_ospath(file);
+ result = statx_without_gvl(RSTRING_PTR(file), stx, mask);
}
- if (ret) CloseHandle(ret);
- return INVALID_HANDLE_VALUE;
+ RB_GC_GUARD(file);
+ return result;
}
-static VALUE
-close_handle(VALUE h)
+# define statx_has_birthtime(st) ((st)->stx_mask & STATX_BTIME)
+
+NORETURN(static void statx_notimplement(const char *field_name));
+
+/* rb_notimplement() shows "function is unimplemented on this machine".
+ It is not applicable to statx which behavior depends on the filesystem. */
+static void
+statx_notimplement(const char *field_name)
{
- CloseHandle((HANDLE)h);
- return Qfalse;
+ rb_raise(rb_eNotImpError,
+ "%s is unimplemented on this filesystem",
+ field_name);
}
-struct w32_io_info_args {
- VALUE *fname;
- BY_HANDLE_FILE_INFORMATION *st;
-};
-
static VALUE
-call_w32_io_info(VALUE arg)
+statx_birthtime(const struct statx *stx, VALUE fname)
{
- struct w32_io_info_args *p = (void *)arg;
- return (VALUE)w32_io_info(p->fname, p->st);
+ if (!statx_has_birthtime(stx)) {
+ /* birthtime is not supported on the filesystem */
+ statx_notimplement("birthtime");
+ }
+ return rb_time_nano_new((time_t)stx->stx_btime.tv_sec, stx->stx_btime.tv_nsec);
}
+
+typedef struct statx statx_data;
+# define HAVE_STAT_BIRTHTIME
+
+#elif defined(HAVE_STAT_BIRTHTIME)
+# define statx_without_gvl(path, st, mask) stat_without_gvl(path, st)
+# define fstatx_without_gvl(fd, st, mask) fstat_without_gvl(fd, st)
+# define statx_birthtime(st, fname) stat_birthtime(st)
+# define statx_has_birthtime(st) 1
+# define rb_statx(file, st, mask) rb_stat(file, st)
+#else
+# define statx_has_birthtime(st) 0
#endif
+static int
+rb_stat(VALUE file, struct stat *st)
+{
+ VALUE tmp;
+ int result;
+
+ tmp = rb_check_convert_type_with_id(file, T_FILE, "IO", idTo_io);
+ if (!NIL_P(tmp)) {
+ rb_io_t *fptr;
+
+ GetOpenFile(tmp, fptr);
+ result = fstat_without_gvl(fptr->fd, st);
+ file = tmp;
+ }
+ else {
+ FilePathValue(file);
+ file = rb_str_encode_ospath(file);
+ result = stat_without_gvl(RSTRING_PTR(file), st);
+ }
+ RB_GC_GUARD(file);
+ return result;
+}
+
/*
* call-seq:
* File.stat(file_name) -> stat
*
- * Returns a <code>File::Stat</code> object for the named file (see
- * <code>File::Stat</code>).
+ * Returns a File::Stat object for the named file (see File::Stat).
*
* File.stat("testfile").mtime #=> Tue Apr 08 12:58:04 CDT 2003
*
@@ -1147,7 +1348,8 @@ rb_file_s_stat(VALUE klass, VALUE fname)
struct stat st;
FilePathValue(fname);
- if (rb_stat(fname, &st) < 0) {
+ fname = rb_str_encode_ospath(fname);
+ if (stat_without_gvl(RSTRING_PTR(fname), &st) < 0) {
rb_sys_fail_path(fname);
}
return rb_stat_new(&st);
@@ -1158,7 +1360,7 @@ rb_file_s_stat(VALUE klass, VALUE fname)
* ios.stat -> stat
*
* Returns status information for <em>ios</em> as an object of type
- * <code>File::Stat</code>.
+ * File::Stat.
*
* f = File.new("testfile")
* s = f.stat
@@ -1206,8 +1408,8 @@ lstat_without_gvl(const char *path, struct stat *st)
* call-seq:
* File.lstat(file_name) -> stat
*
- * Same as <code>File::stat</code>, but does not follow the last symbolic
- * link. Instead, reports on the link itself.
+ * Same as File::stat, but does not follow the last symbolic link.
+ * Instead, reports on the link itself.
*
* File.symlink("testfile", "link2test") #=> 0
* File.stat("testfile").size #=> 66
@@ -1237,8 +1439,8 @@ rb_file_s_lstat(VALUE klass, VALUE fname)
* call-seq:
* file.lstat -> stat
*
- * Same as <code>IO#stat</code>, but does not follow the last symbolic
- * link. Instead, reports on the link itself.
+ * Same as IO#stat, but does not follow the last symbolic link.
+ * Instead, reports on the link itself.
*
* File.symlink("testfile", "link2test") #=> 0
* File.stat("testfile").size #=> 66
@@ -1322,15 +1524,6 @@ rb_group_member(GETGROUPS_T gid)
#define USE_GETEUID 1
#endif
-#ifdef __native_client__
-// Although the NaCl toolchain contain eaccess() is it not yet
-// overridden by nacl_io.
-// TODO(sbc): Remove this once eaccess() is wired up correctly
-// in NaCl.
-# undef HAVE_EACCESS
-# undef USE_GETEUID
-#endif
-
#ifndef HAVE_EACCESS
int
eaccess(const char *path, int mode)
@@ -1375,14 +1568,62 @@ eaccess(const char *path, int mode)
}
#endif
+struct access_arg {
+ const char *path;
+ int mode;
+};
+
+static void *
+nogvl_eaccess(void *ptr)
+{
+ struct access_arg *aa = ptr;
+
+ return (void *)(VALUE)eaccess(aa->path, aa->mode);
+}
+
+static int
+rb_eaccess(VALUE fname, int mode)
+{
+ struct access_arg aa;
+
+ FilePathValue(fname);
+ fname = rb_str_encode_ospath(fname);
+ aa.path = StringValueCStr(fname);
+ aa.mode = mode;
+
+ return (int)(VALUE)rb_thread_call_without_gvl(nogvl_eaccess, &aa,
+ RUBY_UBF_IO, 0);
+}
+
+static void *
+nogvl_access(void *ptr)
+{
+ struct access_arg *aa = ptr;
+
+ return (void *)(VALUE)access(aa->path, aa->mode);
+}
+
+static int
+rb_access(VALUE fname, int mode)
+{
+ struct access_arg aa;
+
+ FilePathValue(fname);
+ fname = rb_str_encode_ospath(fname);
+ aa.path = StringValueCStr(fname);
+ aa.mode = mode;
+
+ return (int)(VALUE)rb_thread_call_without_gvl(nogvl_access, &aa,
+ RUBY_UBF_IO, 0);
+}
/*
* Document-class: FileTest
*
- * <code>FileTest</code> implements file test operations similar to
- * those used in <code>File::Stat</code>. It exists as a standalone
- * module, and its methods are also insinuated into the <code>File</code>
- * class. (Note that this is not done by inclusion: the interpreter cheats).
+ * FileTest implements file test operations similar to those used in
+ * File::Stat. It exists as a standalone module, and its methods are
+ * also insinuated into the File class. (Note that this is not done
+ * by inclusion: the interpreter cheats).
*
*/
@@ -1586,25 +1827,20 @@ rb_file_exist_p(VALUE obj, VALUE fname)
return Qtrue;
}
-/*
- * call-seq:
- * File.exists?(file_name) -> true or false
- *
- * Deprecated method. Don't use.
- */
+/* :nodoc: */
static VALUE
rb_file_exists_p(VALUE obj, VALUE fname)
{
- const char *s = "FileTest#";
+ const char *s = "FileTest#exist?";
if (obj == rb_mFileTest) {
- s = "FileTest.";
+ s = "FileTest.exist?";
}
else if (obj == rb_cFile ||
(RB_TYPE_P(obj, T_CLASS) &&
RTEST(rb_class_inherited_p(obj, rb_cFile)))) {
- s = "File.";
+ s = "File.exist?";
}
- rb_warning("%sexists? is a deprecated name, use %sexist? instead", s, s);
+ rb_warn_deprecated("%.*ss?", s, (int)(strlen(s)-1), s);
return rb_file_exist_p(obj, fname);
}
@@ -1614,14 +1850,15 @@ rb_file_exists_p(VALUE obj, VALUE fname)
*
* Returns <code>true</code> if the named file is readable by the effective
* user and group id of this process. See eaccess(3).
+ *
+ * Note that some OS-level security features may cause this to return true
+ * even though the file is not readable by the effective user/group.
*/
static VALUE
rb_file_readable_p(VALUE obj, VALUE fname)
{
- FilePathValue(fname);
- fname = rb_str_encode_ospath(fname);
- if (eaccess(StringValueCStr(fname), R_OK) < 0) return Qfalse;
+ if (rb_eaccess(fname, R_OK) < 0) return Qfalse;
return Qtrue;
}
@@ -1631,14 +1868,15 @@ rb_file_readable_p(VALUE obj, VALUE fname)
*
* Returns <code>true</code> if the named file is readable by the real
* user and group id of this process. See access(3).
+ *
+ * Note that some OS-level security features may cause this to return true
+ * even though the file is not readable by the real user/group.
*/
static VALUE
rb_file_readable_real_p(VALUE obj, VALUE fname)
{
- FilePathValue(fname);
- fname = rb_str_encode_ospath(fname);
- if (access(StringValueCStr(fname), R_OK) < 0) return Qfalse;
+ if (rb_access(fname, R_OK) < 0) return Qfalse;
return Qtrue;
}
@@ -1686,14 +1924,15 @@ rb_file_world_readable_p(VALUE obj, VALUE fname)
*
* Returns <code>true</code> if the named file is writable by the effective
* user and group id of this process. See eaccess(3).
+ *
+ * Note that some OS-level security features may cause this to return true
+ * even though the file is not writable by the effective user/group.
*/
static VALUE
rb_file_writable_p(VALUE obj, VALUE fname)
{
- FilePathValue(fname);
- fname = rb_str_encode_ospath(fname);
- if (eaccess(StringValueCStr(fname), W_OK) < 0) return Qfalse;
+ if (rb_eaccess(fname, W_OK) < 0) return Qfalse;
return Qtrue;
}
@@ -1702,15 +1941,16 @@ rb_file_writable_p(VALUE obj, VALUE fname)
* File.writable_real?(file_name) -> true or false
*
* Returns <code>true</code> if the named file is writable by the real
- * user and group id of this process. See access(3)
+ * user and group id of this process. See access(3).
+ *
+ * Note that some OS-level security features may cause this to return true
+ * even though the file is not writable by the real user/group.
*/
static VALUE
rb_file_writable_real_p(VALUE obj, VALUE fname)
{
- FilePathValue(fname);
- fname = rb_str_encode_ospath(fname);
- if (access(StringValueCStr(fname), W_OK) < 0) return Qfalse;
+ if (rb_access(fname, W_OK) < 0) return Qfalse;
return Qtrue;
}
@@ -1750,14 +1990,19 @@ rb_file_world_writable_p(VALUE obj, VALUE fname)
*
* Returns <code>true</code> if the named file is executable by the effective
* user and group id of this process. See eaccess(3).
+ *
+ * Windows does not support execute permissions separately from read
+ * permissions. On Windows, a file is only considered executable if it ends in
+ * .bat, .cmd, .com, or .exe.
+ *
+ * Note that some OS-level security features may cause this to return true
+ * even though the file is not executable by the effective user/group.
*/
static VALUE
rb_file_executable_p(VALUE obj, VALUE fname)
{
- FilePathValue(fname);
- fname = rb_str_encode_ospath(fname);
- if (eaccess(StringValueCStr(fname), X_OK) < 0) return Qfalse;
+ if (rb_eaccess(fname, X_OK) < 0) return Qfalse;
return Qtrue;
}
@@ -1767,14 +2012,19 @@ rb_file_executable_p(VALUE obj, VALUE fname)
*
* Returns <code>true</code> if the named file is executable by the real
* user and group id of this process. See access(3).
+ *
+ * Windows does not support execute permissions separately from read
+ * permissions. On Windows, a file is only considered executable if it ends in
+ * .bat, .cmd, .com, or .exe.
+ *
+ * Note that some OS-level security features may cause this to return true
+ * even though the file is not executable by the real user/group.
*/
static VALUE
rb_file_executable_real_p(VALUE obj, VALUE fname)
{
- FilePathValue(fname);
- fname = rb_str_encode_ospath(fname);
- if (access(StringValueCStr(fname), X_OK) < 0) return Qfalse;
+ if (rb_access(fname, X_OK) < 0) return Qfalse;
return Qtrue;
}
@@ -1915,6 +2165,8 @@ check3rdbyte(VALUE fname, int mode)
* File.setuid?(file_name) -> true or false
*
* Returns <code>true</code> if the named file has the setuid bit set.
+ *
+ * _file_name_ can be an IO object.
*/
static VALUE
@@ -1932,6 +2184,8 @@ rb_file_suid_p(VALUE obj, VALUE fname)
* File.setgid?(file_name) -> true or false
*
* Returns <code>true</code> if the named file has the setgid bit set.
+ *
+ * _file_name_ can be an IO object.
*/
static VALUE
@@ -1949,6 +2203,8 @@ rb_file_sgid_p(VALUE obj, VALUE fname)
* File.sticky?(file_name) -> true or false
*
* Returns <code>true</code> if the named file has the sticky bit set.
+ *
+ * _file_name_ can be an IO object.
*/
static VALUE
@@ -1957,7 +2213,7 @@ rb_file_sticky_p(VALUE obj, VALUE fname)
#ifdef S_ISVTX
return check3rdbyte(fname, S_ISVTX);
#else
- return Qnil;
+ return Qfalse;
#endif
}
@@ -1992,28 +2248,8 @@ rb_file_identical_p(VALUE obj, VALUE fname1, VALUE fname2)
if (st1.st_ino != st2.st_ino) return Qfalse;
return Qtrue;
#else
- BY_HANDLE_FILE_INFORMATION st1, st2;
- HANDLE f1 = 0, f2 = 0;
-
- f1 = w32_io_info(&fname1, &st1);
- if (f1 == INVALID_HANDLE_VALUE) return Qfalse;
- if (f1) {
- struct w32_io_info_args arg;
- arg.fname = &fname2;
- arg.st = &st2;
- f2 = (HANDLE)rb_ensure(call_w32_io_info, (VALUE)&arg, close_handle, (VALUE)f1);
- }
- else {
- f2 = w32_io_info(&fname2, &st2);
- }
- if (f2 == INVALID_HANDLE_VALUE) return Qfalse;
- if (f2) CloseHandle(f2);
-
- if (st1.dwVolumeSerialNumber == st2.dwVolumeSerialNumber &&
- st1.nFileIndexHigh == st2.nFileIndexHigh &&
- st1.nFileIndexLow == st2.nFileIndexLow)
- return Qtrue;
- return Qfalse;
+ extern VALUE rb_w32_file_identical_p(VALUE, VALUE);
+ return rb_w32_file_identical_p(fname1, fname2);
#endif
}
@@ -2113,7 +2349,7 @@ rb_file_s_ftype(VALUE klass, VALUE fname)
* call-seq:
* File.atime(file_name) -> time
*
- * Returns the last access time for the named file as a Time object).
+ * Returns the last access time for the named file as a Time object.
*
* _file_name_ can be an IO object.
*
@@ -2138,8 +2374,8 @@ rb_file_s_atime(VALUE klass, VALUE fname)
* call-seq:
* file.atime -> time
*
- * Returns the last access time (a <code>Time</code> object)
- * for <i>file</i>, or epoch if <i>file</i> has not been accessed.
+ * Returns the last access time (a Time object) for <i>file</i>, or
+ * epoch if <i>file</i> has not been accessed.
*
* File.new("testfile").atime #=> Wed Dec 31 18:00:00 CST 1969
*
@@ -2261,7 +2497,6 @@ rb_file_ctime(VALUE obj)
return stat_ctime(&st);
}
-#if defined(HAVE_STAT_BIRTHTIME)
/*
* call-seq:
* File.birthtime(file_name) -> time
@@ -2276,17 +2511,18 @@ rb_file_ctime(VALUE obj)
*
*/
-static VALUE
+#if defined(HAVE_STAT_BIRTHTIME)
+RUBY_FUNC_EXPORTED VALUE
rb_file_s_birthtime(VALUE klass, VALUE fname)
{
- struct stat st;
+ statx_data st;
- if (rb_stat(fname, &st) < 0) {
+ if (rb_statx(fname, &st, STATX_BTIME) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
- return stat_birthtime(&st);
+ return statx_birthtime(&st, fname);
}
#else
# define rb_file_s_birthtime rb_f_notimplement
@@ -2309,13 +2545,13 @@ static VALUE
rb_file_birthtime(VALUE obj)
{
rb_io_t *fptr;
- struct stat st;
+ statx_data st;
GetOpenFile(obj, fptr);
- if (fstat(fptr->fd, &st) == -1) {
+ if (fstatx_without_gvl(fptr->fd, &st, STATX_BTIME) == -1) {
rb_sys_fail_path(fptr->pathv);
}
- return stat_birthtime(&st);
+ return statx_birthtime(&st, fptr->pathv);
}
#else
# define rb_file_birthtime rb_f_notimplement
@@ -2347,11 +2583,10 @@ rb_file_size(VALUE obj)
return OFFT2NUM(st.st_size);
}
-static void
-chmod_internal(const char *path, VALUE pathv, void *mode)
+static int
+chmod_internal(const char *path, void *mode)
{
- if (chmod(path, *(int *)mode) < 0)
- rb_sys_fail_path(pathv);
+ return chmod(path, *(mode_t *)mode);
}
/*
@@ -2368,12 +2603,12 @@ chmod_internal(const char *path, VALUE pathv, void *mode)
*/
static VALUE
-rb_file_s_chmod(int argc, VALUE *argv)
+rb_file_s_chmod(int argc, VALUE *argv, VALUE _)
{
- int mode;
+ mode_t mode;
apply2args(1);
- mode = NUM2INT(*argv++);
+ mode = NUM2MODET(*argv++);
return apply2files(chmod_internal, argc, argv, &mode);
}
@@ -2385,7 +2620,7 @@ rb_file_s_chmod(int argc, VALUE *argv)
* Changes permission bits on <i>file</i> to the bit pattern
* represented by <i>mode_int</i>. Actual effects are platform
* dependent; on Unix systems, see <code>chmod(2)</code> for details.
- * Follows symbolic links. Also see <code>File#lchmod</code>.
+ * Follows symbolic links. Also see File#lchmod.
*
* f = File.new("out", "w");
* f.chmod(0644) #=> 0
@@ -2395,12 +2630,12 @@ static VALUE
rb_file_chmod(VALUE obj, VALUE vmode)
{
rb_io_t *fptr;
- int mode;
+ mode_t mode;
#if !defined HAVE_FCHMOD || !HAVE_FCHMOD
VALUE path;
#endif
- mode = NUM2INT(vmode);
+ mode = NUM2MODET(vmode);
GetOpenFile(obj, fptr);
#ifdef HAVE_FCHMOD
@@ -2423,32 +2658,31 @@ rb_file_chmod(VALUE obj, VALUE vmode)
}
#if defined(HAVE_LCHMOD)
-static void
-lchmod_internal(const char *path, VALUE pathv, void *mode)
+static int
+lchmod_internal(const char *path, void *mode)
{
- if (lchmod(path, (int)(VALUE)mode) < 0)
- rb_sys_fail_path(pathv);
+ return lchmod(path, *(mode_t *)mode);
}
/*
* call-seq:
* File.lchmod(mode_int, file_name, ...) -> integer
*
- * Equivalent to <code>File::chmod</code>, but does not follow symbolic
- * links (so it will change the permissions associated with the link,
- * not the file referenced by the link). Often not available.
+ * Equivalent to File::chmod, but does not follow symbolic links (so
+ * it will change the permissions associated with the link, not the
+ * file referenced by the link). Often not available.
*
*/
static VALUE
-rb_file_s_lchmod(int argc, VALUE *argv)
+rb_file_s_lchmod(int argc, VALUE *argv, VALUE _)
{
- long mode;
+ mode_t mode;
apply2args(1);
- mode = NUM2INT(*argv++);
+ mode = NUM2MODET(*argv++);
- return apply2files(lchmod_internal, argc, argv, (void *)(long)mode);
+ return apply2files(lchmod_internal, argc, argv, &mode);
}
#else
#define rb_file_s_lchmod rb_f_notimplement
@@ -2477,17 +2711,16 @@ struct chown_args {
rb_gid_t group;
};
-static void
-chown_internal(const char *path, VALUE pathv, void *arg)
+static int
+chown_internal(const char *path, void *arg)
{
struct chown_args *args = arg;
- if (chown(path, args->owner, args->group) < 0)
- rb_sys_fail_path(pathv);
+ return chown(path, args->owner, args->group);
}
/*
* call-seq:
- * File.chown(owner_int, group_int, file_name,... ) -> integer
+ * File.chown(owner_int, group_int, file_name, ...) -> integer
*
* Changes the owner and group of the named file(s) to the given
* numeric owner and group id's. Only a process with superuser
@@ -2501,7 +2734,7 @@ chown_internal(const char *path, VALUE pathv, void *arg)
*/
static VALUE
-rb_file_s_chown(int argc, VALUE *argv)
+rb_file_s_chown(int argc, VALUE *argv, VALUE _)
{
struct chown_args arg;
@@ -2521,7 +2754,7 @@ rb_file_s_chown(int argc, VALUE *argv)
* change the owner of a file. The current owner of a file may change
* the file's group to any group to which the owner belongs. A
* <code>nil</code> or -1 owner or group id is ignored. Follows
- * symbolic links. See also <code>File#lchown</code>.
+ * symbolic links. See also File#lchown.
*
* File.new("testfile").chown(502, 1000)
*
@@ -2554,19 +2787,18 @@ rb_file_chown(VALUE obj, VALUE owner, VALUE group)
}
#if defined(HAVE_LCHOWN)
-static void
-lchown_internal(const char *path, VALUE pathv, void *arg)
+static int
+lchown_internal(const char *path, void *arg)
{
struct chown_args *args = arg;
- if (lchown(path, args->owner, args->group) < 0)
- rb_sys_fail_path(pathv);
+ return lchown(path, args->owner, args->group);
}
/*
* call-seq:
* File.lchown(owner_int, group_int, file_name,..) -> integer
*
- * Equivalent to <code>File::chown</code>, but does not follow symbolic
+ * Equivalent to File::chown, but does not follow symbolic
* links (so it will change the owner associated with the link, not the
* file referenced by the link). Often not available. Returns number
* of files in the argument list.
@@ -2574,7 +2806,7 @@ lchown_internal(const char *path, VALUE pathv, void *arg)
*/
static VALUE
-rb_file_s_lchown(int argc, VALUE *argv)
+rb_file_s_lchown(int argc, VALUE *argv, VALUE _)
{
struct chown_args arg;
@@ -2591,18 +2823,25 @@ rb_file_s_lchown(int argc, VALUE *argv)
struct utime_args {
const struct timespec* tsp;
VALUE atime, mtime;
+ int follow; /* Whether to act on symlinks (1) or their referent (0) */
};
-#if defined DOSISH || defined __CYGWIN__
-NORETURN(static void utime_failed(VALUE, const struct timespec *, VALUE, VALUE));
+#ifdef UTIME_EINVAL
+NORETURN(static void utime_failed(struct apply_arg *));
static void
-utime_failed(VALUE path, const struct timespec *tsp, VALUE atime, VALUE mtime)
+utime_failed(struct apply_arg *aa)
{
- int e = errno;
- if (tsp && e == EINVAL) {
+ int e = aa->errnum;
+ VALUE path = aa->fn[aa->i].path;
+ struct utime_args *ua = aa->arg;
+
+ if (ua->tsp && e == EINVAL) {
VALUE e[2], a = Qnil, m = Qnil;
int d = 0;
+ VALUE atime = ua->atime;
+ VALUE mtime = ua->mtime;
+
if (!NIL_P(atime)) {
a = rb_inspect(atime);
}
@@ -2627,14 +2866,12 @@ utime_failed(VALUE path, const struct timespec *tsp, VALUE atime, VALUE mtime)
}
rb_syserr_fail_path(e, path);
}
-#else
-#define utime_failed(path, tsp, atime, mtime) rb_sys_fail_path(path)
#endif
#if defined(HAVE_UTIMES)
-static void
-utime_internal(const char *path, VALUE pathv, void *arg)
+static int
+utime_internal(const char *path, void *arg)
{
struct utime_args *v = arg;
const struct timespec *tsp = v->tsp;
@@ -2642,16 +2879,32 @@ utime_internal(const char *path, VALUE pathv, void *arg)
#if defined(HAVE_UTIMENSAT)
static int try_utimensat = 1;
+# ifdef AT_SYMLINK_NOFOLLOW
+ static int try_utimensat_follow = 1;
+# else
+ const int try_utimensat_follow = 0;
+# endif
+ int flags = 0;
+
+ if (v->follow ? try_utimensat_follow : try_utimensat) {
+# ifdef AT_SYMLINK_NOFOLLOW
+ if (v->follow) {
+ flags = AT_SYMLINK_NOFOLLOW;
+ }
+# endif
- if (try_utimensat) {
- if (utimensat(AT_FDCWD, path, tsp, 0) < 0) {
+ if (utimensat(AT_FDCWD, path, tsp, flags) < 0) {
if (errno == ENOSYS) {
- try_utimensat = 0;
+# ifdef AT_SYMLINK_NOFOLLOW
+ try_utimensat_follow = 0;
+# endif
+ if (!v->follow)
+ try_utimensat = 0;
goto no_utimensat;
}
- utime_failed(pathv, tsp, v->atime, v->mtime);
+ return -1; /* calls utime_failed */
}
- return;
+ return 0;
}
no_utimensat:
#endif
@@ -2663,8 +2916,10 @@ no_utimensat:
tvbuf[1].tv_usec = (int)(tsp[1].tv_nsec / 1000);
tvp = tvbuf;
}
- if (utimes(path, tvp) < 0)
- utime_failed(pathv, tsp, v->atime, v->mtime);
+#ifdef HAVE_LUTIMES
+ if (v->follow) return lutimes(path, tvp);
+#endif
+ return utimes(path, tvp);
}
#else
@@ -2676,8 +2931,8 @@ struct utimbuf {
};
#endif
-static void
-utime_internal(const char *path, VALUE pathv, void *arg)
+static int
+utime_internal(const char *path, void *arg)
{
struct utime_args *v = arg;
const struct timespec *tsp = v->tsp;
@@ -2687,23 +2942,13 @@ utime_internal(const char *path, VALUE pathv, void *arg)
utbuf.modtime = tsp[1].tv_sec;
utp = &utbuf;
}
- if (utime(path, utp) < 0)
- utime_failed(pathv, tsp, v->atime, v->mtime);
+ return utime(path, utp);
}
#endif
-/*
- * call-seq:
- * File.utime(atime, mtime, file_name,...) -> integer
- *
- * Sets the access and modification times of each
- * named file to the first two arguments. Returns
- * the number of file names in the argument list.
- */
-
static VALUE
-rb_file_s_utime(int argc, VALUE *argv)
+utime_internal_i(int argc, VALUE *argv, int follow)
{
struct utime_args args;
struct timespec tss[2], *tsp = NULL;
@@ -2712,6 +2957,8 @@ rb_file_s_utime(int argc, VALUE *argv)
args.atime = *argv++;
args.mtime = *argv++;
+ args.follow = follow;
+
if (!NIL_P(args.atime) || !NIL_P(args.mtime)) {
tsp = tss;
tsp[0] = rb_time_timespec(args.atime);
@@ -2725,6 +2972,45 @@ rb_file_s_utime(int argc, VALUE *argv)
return apply2files(utime_internal, argc, argv, &args);
}
+/*
+ * call-seq:
+ * File.utime(atime, mtime, file_name, ...) -> integer
+ *
+ * Sets the access and modification times of each named file to the
+ * first two arguments. If a file is a symlink, this method acts upon
+ * its referent rather than the link itself; for the inverse
+ * behavior see File.lutime. Returns the number of file
+ * names in the argument list.
+ */
+
+static VALUE
+rb_file_s_utime(int argc, VALUE *argv, VALUE _)
+{
+ return utime_internal_i(argc, argv, FALSE);
+}
+
+#if defined(HAVE_UTIMES) && (defined(HAVE_LUTIMES) || (defined(HAVE_UTIMENSAT) && defined(AT_SYMLINK_NOFOLLOW)))
+
+/*
+ * call-seq:
+ * File.lutime(atime, mtime, file_name, ...) -> integer
+ *
+ * Sets the access and modification times of each named file to the
+ * first two arguments. If a file is a symlink, this method acts upon
+ * the link itself as opposed to its referent; for the inverse
+ * behavior, see File.utime. Returns the number of file
+ * names in the argument list.
+ */
+
+static VALUE
+rb_file_s_lutime(int argc, VALUE *argv, VALUE _)
+{
+ return utime_internal_i(argc, argv, TRUE);
+}
+#else
+#define rb_file_s_lutime rb_f_notimplement
+#endif
+
#ifdef RUBY_FUNCTION_NAME_STRING
# define syserr_fail2(e, s1, s2) syserr_fail2_in(RUBY_FUNCTION_NAME_STRING, e, s1, s2)
#else
@@ -2764,7 +3050,7 @@ syserr_fail2_in(const char *func, int e, VALUE s1, VALUE s2)
*
* Creates a new name for an existing file using a hard link. Will not
* overwrite <i>new_name</i> if it already exists (raising a subclass
- * of <code>SystemCallError</code>). Not available on all platforms.
+ * of SystemCallError). Not available on all platforms.
*
* File.link("testfile", ".testfile") #=> 0
* IO.readlines(".testfile")[0] #=> "This is line one\n"
@@ -2793,7 +3079,7 @@ rb_file_s_link(VALUE klass, VALUE from, VALUE to)
* File.symlink(old_name, new_name) -> 0
*
* Creates a symbolic link called <i>new_name</i> for the existing file
- * <i>old_name</i>. Raises a <code>NotImplemented</code> exception on
+ * <i>old_name</i>. Raises a NotImplemented exception on
* platforms that do not support symbolic links.
*
* File.symlink("testfile", "link2test") #=> 0
@@ -2836,6 +3122,33 @@ rb_file_s_readlink(VALUE klass, VALUE path)
}
#ifndef _WIN32
+struct readlink_arg {
+ const char *path;
+ char *buf;
+ size_t size;
+};
+
+static void *
+nogvl_readlink(void *ptr)
+{
+ struct readlink_arg *ra = ptr;
+
+ return (void *)(VALUE)readlink(ra->path, ra->buf, ra->size);
+}
+
+static ssize_t
+readlink_without_gvl(VALUE path, VALUE buf, size_t size)
+{
+ struct readlink_arg ra;
+
+ ra.path = RSTRING_PTR(path);
+ ra.buf = RSTRING_PTR(buf);
+ ra.size = size;
+
+ return (ssize_t)rb_thread_call_without_gvl(nogvl_readlink, &ra,
+ RUBY_UBF_IO, 0);
+}
+
VALUE
rb_readlink(VALUE path, rb_encoding *enc)
{
@@ -2846,7 +3159,7 @@ rb_readlink(VALUE path, rb_encoding *enc)
FilePathValue(path);
path = rb_str_encode_ospath(path);
v = rb_enc_str_new(0, size, enc);
- while ((rv = readlink(RSTRING_PTR(path), RSTRING_PTR(v), size)) == size
+ while ((rv = readlink_without_gvl(path, v, size)) == size
#ifdef _AIX
|| (rv < 0 && errno == ERANGE) /* quirky behavior of GPFS */
#endif
@@ -2869,11 +3182,10 @@ rb_readlink(VALUE path, rb_encoding *enc)
#define rb_file_s_readlink rb_f_notimplement
#endif
-static void
-unlink_internal(const char *path, VALUE pathv, void *arg)
+static int
+unlink_internal(const char *path, void *arg)
{
- if (unlink(path) < 0)
- rb_sys_fail_path(pathv);
+ return unlink(path);
}
/*
@@ -2883,7 +3195,13 @@ unlink_internal(const char *path, VALUE pathv, void *arg)
*
* Deletes the named files, returning the number of names
* passed as arguments. Raises an exception on any error.
- * See also <code>Dir::rmdir</code>.
+ * Since the underlying implementation relies on the
+ * <code>unlink(2)</code> system call, the type of
+ * exception raised depends on its error type (see
+ * https://linux.die.net/man/2/unlink) and has the form of
+ * e.g. Errno::ENOENT.
+ *
+ * See also Dir::rmdir.
*/
static VALUE
@@ -2909,8 +3227,8 @@ no_gvl_rename(void *ptr)
* call-seq:
* File.rename(old_name, new_name) -> 0
*
- * Renames the given file to the new name. Raises a
- * <code>SystemCallError</code> if the file cannot be renamed.
+ * Renames the given file to the new name. Raises a SystemCallError
+ * if the file cannot be renamed.
*
* File.rename("afile", "afile.bak") #=> 0
*/
@@ -2964,21 +3282,22 @@ rb_file_s_rename(VALUE klass, VALUE from, VALUE to)
*/
static VALUE
-rb_file_s_umask(int argc, VALUE *argv)
+rb_file_s_umask(int argc, VALUE *argv, VALUE _)
{
- int omask = 0;
+ mode_t omask = 0;
- if (argc == 0) {
+ switch (argc) {
+ case 0:
omask = umask(0);
umask(omask);
+ break;
+ case 1:
+ omask = umask(NUM2MODET(argv[0]));
+ break;
+ default:
+ rb_error_arity(argc, 0, 1);
}
- else if (argc == 1) {
- omask = umask(NUM2INT(argv[0]));
- }
- else {
- rb_check_arity(argc, 0, 1);
- }
- return INT2FIX(omask);
+ return MODET2NUM(omask);
}
#ifdef __CYGWIN__
@@ -2991,7 +3310,9 @@ rb_file_s_umask(int argc, VALUE *argv)
#endif
#ifdef FILE_ALT_SEPARATOR
#define isdirsep(x) ((x) == '/' || (x) == FILE_ALT_SEPARATOR)
+# ifdef DOSISH
static const char file_alt_separator[] = {FILE_ALT_SEPARATOR, '\0'};
+# endif
#else
#define isdirsep(x) ((x) == '/')
#endif
@@ -3058,9 +3379,9 @@ getcwdofdrv(int drv)
of a particular drive is to change chdir() to that drive,
so save the old cwd before chdir()
*/
- oldcwd = my_getcwd();
+ oldcwd = ruby_getcwd();
if (chdir(drive) == 0) {
- drvcwd = my_getcwd();
+ drvcwd = ruby_getcwd();
chdir(oldcwd);
xfree(oldcwd);
}
@@ -3322,21 +3643,42 @@ rb_default_home_dir(VALUE result)
#if defined HAVE_PWD_H
if (!dir) {
- const char *login = getlogin();
- if (login) {
- struct passwd *pw = getpwnam(login);
- if (pw) {
- copy_home_path(result, pw->pw_dir);
- endpwent();
- return result;
- }
- endpwent();
- rb_raise(rb_eArgError, "couldn't find HOME for login `%s' -- expanding `~'",
- login);
- }
- else {
- rb_raise(rb_eArgError, "couldn't find login name -- expanding `~'");
- }
+ /* We'll look up the user's default home dir in the password db by
+ * login name, if possible, and failing that will fall back to looking
+ * the information up by uid (as would be needed for processes that
+ * are not a descendant of login(1) or a work-alike).
+ *
+ * While the lookup by uid is more likely to succeed (since we always
+ * have a uid, but may or may not have a login name), we prefer first
+ * looking up by name to accommodate the possibility of multiple login
+ * names (each with its own record in the password database, so each
+ * with a potentially different home directory) being mapped to the
+ * same uid (as explicitly allowed for by POSIX; see getlogin(3posix)).
+ */
+ VALUE login_name = rb_getlogin();
+
+# if !defined(HAVE_GETPWUID_R) && !defined(HAVE_GETPWUID)
+ /* This is a corner case, but for backward compatibility reasons we
+ * want to emit this error if neither the lookup by login name nor
+ * lookup by getuid() has a chance of succeeding.
+ */
+ if (NIL_P(login_name)) {
+ rb_raise(rb_eArgError, "couldn't find login name -- expanding `~'");
+ }
+# endif
+
+ VALUE pw_dir = rb_getpwdirnam_for_login(login_name);
+ if (NIL_P(pw_dir)) {
+ pw_dir = rb_getpwdiruid();
+ if (NIL_P(pw_dir)) {
+ rb_raise(rb_eArgError, "couldn't find home for uid `%ld'", (long)getuid());
+ }
+ }
+
+ /* found it */
+ copy_home_path(result, RSTRING_PTR(pw_dir));
+ rb_str_resize(pw_dir, 0);
+ return result;
}
#endif
if (!dir) {
@@ -3391,18 +3733,15 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
const char *s, *b, *fend;
char *buf, *p, *pend, *root;
size_t buflen, bdiff;
- int tainted;
rb_encoding *enc, *fsenc = rb_filesystem_encoding();
s = StringValuePtr(fname);
fend = s + RSTRING_LEN(fname);
enc = rb_enc_get(fname);
BUFINIT();
- tainted = OBJ_TAINTED(fname);
if (s[0] == '~' && abs_mode == 0) { /* execute only if NOT absolute_path() */
long userlen = 0;
- tainted = 1;
if (isdirsep(s[1]) || s[1] == '\0') {
buf = 0;
b = 0;
@@ -3460,7 +3799,6 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
if (!same) {
char *e = append_fspath(result, fname, getcwdofdrv(*s), &enc, fsenc);
- tainted = 1;
BUFINIT();
p = e;
}
@@ -3481,8 +3819,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
p = pend;
}
else {
- char *e = append_fspath(result, fname, my_getcwd(), &enc, fsenc);
- tainted = 1;
+ char *e = append_fspath(result, fname, ruby_getcwd(), &enc, fsenc);
BUFINIT();
p = e;
}
@@ -3733,7 +4070,6 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
#endif
- if (tainted) OBJ_TAINT(result);
rb_str_set_len(result, p - buf);
rb_enc_check(fname, result);
ENC_CODERANGE_CLEAR(result);
@@ -3776,6 +4112,13 @@ rb_file_expand_path_fast(VALUE fname, VALUE dname)
return expand_path(fname, dname, 0, 0, EXPAND_PATH_BUFFER());
}
+VALUE
+rb_file_s_expand_path(int argc, const VALUE *argv)
+{
+ rb_check_arity(argc, 1, 2);
+ return rb_file_expand_path(argv[0], argc > 1 ? argv[1] : Qnil);
+}
+
/*
* call-seq:
* File.expand_path(file_name [, dir_string] ) -> abs_file_name
@@ -3804,11 +4147,10 @@ rb_file_expand_path_fast(VALUE fname, VALUE dname)
* parent, the root of the project and appends +lib/mygem.rb+.
*/
-VALUE
-rb_file_s_expand_path(int argc, const VALUE *argv)
+static VALUE
+s_expand_path(int c, const VALUE * v, VALUE _)
{
- rb_check_arity(argc, 1, 2);
- return rb_file_expand_path(argv[0], argc > 1 ? argv[1] : Qnil);
+ return rb_file_s_expand_path(c, v);
}
VALUE
@@ -3818,6 +4160,13 @@ rb_file_absolute_path(VALUE fname, VALUE dname)
return expand_path(fname, dname, 1, 1, EXPAND_PATH_BUFFER());
}
+VALUE
+rb_file_s_absolute_path(int argc, const VALUE *argv)
+{
+ rb_check_arity(argc, 1, 2);
+ return rb_file_absolute_path(argv[0], argc > 1 ? argv[1] : Qnil);
+}
+
/*
* call-seq:
* File.absolute_path(file_name [, dir_string] ) -> abs_file_name
@@ -3831,26 +4180,31 @@ rb_file_absolute_path(VALUE fname, VALUE dname)
* File.absolute_path("~oracle/bin") #=> "<relative_path>/~oracle/bin"
*/
-VALUE
-rb_file_s_absolute_path(int argc, const VALUE *argv)
+static VALUE
+s_absolute_path(int c, const VALUE * v, VALUE _)
{
- rb_check_arity(argc, 1, 2);
- return rb_file_absolute_path(argv[0], argc > 1 ? argv[1] : Qnil);
+ return rb_file_s_absolute_path(c, v);
}
-#ifdef __native_client__
-VALUE
-rb_realpath_internal(VALUE basedir, VALUE path, int strict)
-{
- return path;
-}
+/*
+ * call-seq:
+ * File.absolute_path?(file_name) -> true or false
+ *
+ * Returns <code>true</code> if +file_name+ is an absolute path, and
+ * <code>false</code> otherwise.
+ *
+ * File.absolute_path?("c:/foo") #=> false (on Linux), true (on Windows)
+ */
-VALUE
-rb_check_realpath(VALUE basedir, VALUE path)
+static VALUE
+s_absolute_path_p(VALUE klass, VALUE fname)
{
- return path;
+ VALUE path = rb_get_path(fname);
+
+ if (!rb_is_absolute_path(RSTRING_PTR(path))) return Qfalse;
+ return Qtrue;
}
-#else
+
enum rb_realpath_mode {
RB_REALPATH_CHECK,
RB_REALPATH_DIR,
@@ -3859,7 +4213,7 @@ enum rb_realpath_mode {
};
static int
-realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
+realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE fallback,
VALUE loopcheck, enum rb_realpath_mode mode, int last)
{
const char *pend = unresolved + strlen(unresolved);
@@ -3914,13 +4268,15 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
else {
struct stat sbuf;
int ret;
-#ifdef __native_client__
- ret = stat(RSTRING_PTR(testpath), &sbuf);
-#else
ret = lstat_without_gvl(RSTRING_PTR(testpath), &sbuf);
-#endif
if (ret == -1) {
int e = errno;
+ if (e == ENOENT && !NIL_P(fallback)) {
+ if (stat_without_gvl(RSTRING_PTR(fallback), &sbuf) == 0) {
+ rb_str_replace(*resolvedp, fallback);
+ return 0;
+ }
+ }
if (mode == RB_REALPATH_CHECK) return -1;
if (e == ENOENT) {
if (mode == RB_REALPATH_STRICT || !last || *unresolved_firstsep)
@@ -3944,15 +4300,15 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
link_names = skipprefixroot(link_prefix, link_prefix + RSTRING_LEN(link), rb_enc_get(link));
link_prefixlen = link_names - link_prefix;
if (link_prefixlen > 0) {
- rb_encoding *enc, *linkenc = rb_enc_get(link);
+ rb_encoding *tmpenc, *linkenc = rb_enc_get(link);
link_orig = link;
link = rb_str_subseq(link, 0, link_prefixlen);
- enc = rb_enc_check(*resolvedp, link);
- if (enc != linkenc) link = rb_str_conv_enc(link, linkenc, enc);
+ tmpenc = rb_enc_check(*resolvedp, link);
+ if (tmpenc != linkenc) link = rb_str_conv_enc(link, linkenc, tmpenc);
*resolvedp = link;
*prefixlenp = link_prefixlen;
}
- if (realpath_rec(prefixlenp, resolvedp, link_names,
+ if (realpath_rec(prefixlenp, resolvedp, link_names, testpath,
loopcheck, mode, !*unresolved_firstsep))
return -1;
RB_GC_GUARD(link_orig);
@@ -3972,7 +4328,7 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
}
static VALUE
-rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode)
+rb_check_realpath_emulate(VALUE basedir, VALUE path, rb_encoding *origenc, enum rb_realpath_mode mode)
{
long prefixlen;
VALUE resolved;
@@ -3980,7 +4336,7 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
VALUE loopcheck;
VALUE curdir = Qnil;
- rb_encoding *enc, *origenc;
+ rb_encoding *enc;
char *path_names = NULL, *basedir_names = NULL, *curdir_names = NULL;
char *ptr, *prefixptr = NULL, *pend;
long len;
@@ -3993,7 +4349,6 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
}
enc = rb_enc_get(unresolved_path);
- origenc = enc;
unresolved_path = TO_OSPATH(unresolved_path);
RSTRING_GETMEM(unresolved_path, ptr, len);
path_names = skipprefixroot(ptr, ptr + len, rb_enc_get(unresolved_path));
@@ -4041,17 +4396,17 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
loopcheck = rb_hash_new();
if (curdir_names) {
- if (realpath_rec(&prefixlen, &resolved, curdir_names, loopcheck, mode, 0))
+ if (realpath_rec(&prefixlen, &resolved, curdir_names, Qnil, loopcheck, mode, 0))
return Qnil;
}
if (basedir_names) {
- if (realpath_rec(&prefixlen, &resolved, basedir_names, loopcheck, mode, 0))
+ if (realpath_rec(&prefixlen, &resolved, basedir_names, Qnil, loopcheck, mode, 0))
return Qnil;
}
- if (realpath_rec(&prefixlen, &resolved, path_names, loopcheck, mode, 1))
+ if (realpath_rec(&prefixlen, &resolved, path_names, Qnil, loopcheck, mode, 1))
return Qnil;
- if (origenc != rb_enc_get(resolved)) {
+ if (origenc && origenc != rb_enc_get(resolved)) {
if (rb_enc_str_asciionly_p(resolved)) {
rb_enc_associate(resolved, origenc);
}
@@ -4060,26 +4415,96 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
}
}
- OBJ_TAINT(resolved);
RB_GC_GUARD(unresolved_path);
RB_GC_GUARD(curdir);
return resolved;
}
+static VALUE rb_file_join(VALUE ary);
+
+static VALUE
+rb_check_realpath_internal(VALUE basedir, VALUE path, rb_encoding *origenc, enum rb_realpath_mode mode)
+{
+#ifdef HAVE_REALPATH
+ VALUE unresolved_path;
+ char *resolved_ptr = NULL;
+ VALUE resolved;
+
+ if (mode == RB_REALPATH_DIR) {
+ return rb_check_realpath_emulate(basedir, path, origenc, mode);
+ }
+
+ unresolved_path = rb_str_dup_frozen(path);
+ if (*RSTRING_PTR(unresolved_path) != '/' && !NIL_P(basedir)) {
+ unresolved_path = rb_file_join(rb_assoc_new(basedir, unresolved_path));
+ }
+ if (origenc) unresolved_path = TO_OSPATH(unresolved_path);
+
+ if ((resolved_ptr = realpath(RSTRING_PTR(unresolved_path), NULL)) == NULL) {
+ /* glibc realpath(3) does not allow /path/to/file.rb/../other_file.rb,
+ returning ENOTDIR in that case.
+ glibc realpath(3) can also return ENOENT for paths that exist,
+ such as /dev/fd/5.
+ Fallback to the emulated approach in either of those cases. */
+ if (errno == ENOTDIR ||
+ (errno == ENOENT && rb_file_exist_p(0, unresolved_path))) {
+ return rb_check_realpath_emulate(basedir, path, origenc, mode);
+
+ }
+ if (mode == RB_REALPATH_CHECK) {
+ return Qnil;
+ }
+ rb_sys_fail_path(unresolved_path);
+ }
+ resolved = ospath_new(resolved_ptr, strlen(resolved_ptr), rb_filesystem_encoding());
+ free(resolved_ptr);
+
+# if !defined(__LINUX__) && !defined(__APPLE__)
+ /* As `resolved` is a String in the filesystem encoding, no
+ * conversion is needed */
+ struct stat st;
+ if (stat_without_gvl(RSTRING_PTR(resolved), &st) < 0) {
+ if (mode == RB_REALPATH_CHECK) {
+ return Qnil;
+ }
+ rb_sys_fail_path(unresolved_path);
+ }
+# endif
+
+ if (origenc && origenc != rb_enc_get(resolved)) {
+ if (!rb_enc_str_asciionly_p(resolved)) {
+ resolved = rb_str_conv_enc(resolved, NULL, origenc);
+ }
+ rb_enc_associate(resolved, origenc);
+ }
+
+ if (rb_enc_str_coderange(resolved) == ENC_CODERANGE_BROKEN) {
+ rb_enc_associate(resolved, rb_filesystem_encoding());
+ if (rb_enc_str_coderange(resolved) == ENC_CODERANGE_BROKEN) {
+ rb_enc_associate(resolved, rb_ascii8bit_encoding());
+ }
+ }
+
+ RB_GC_GUARD(unresolved_path);
+ return resolved;
+#else
+ return rb_check_realpath_emulate(basedir, path, origenc, mode);
+#endif /* HAVE_REALPATH */
+}
+
VALUE
rb_realpath_internal(VALUE basedir, VALUE path, int strict)
{
const enum rb_realpath_mode mode =
strict ? RB_REALPATH_STRICT : RB_REALPATH_DIR;
- return rb_check_realpath_internal(basedir, path, mode);
+ return rb_check_realpath_internal(basedir, path, rb_enc_get(path), mode);
}
VALUE
-rb_check_realpath(VALUE basedir, VALUE path)
+rb_check_realpath(VALUE basedir, VALUE path, rb_encoding *enc)
{
- return rb_check_realpath_internal(basedir, path, RB_REALPATH_CHECK);
+ return rb_check_realpath_internal(basedir, path, enc, RB_REALPATH_CHECK);
}
-#endif
/*
* call-seq:
@@ -4229,12 +4654,11 @@ ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encodin
*
* Returns the last component of the filename given in
* <i>file_name</i> (after first stripping trailing separators),
- * which can be formed using both <code>File::SEPARATOR</code> and
- * <code>File::ALT_SEPARATOR</code> as the separator when
- * <code>File::ALT_SEPARATOR</code> is not <code>nil</code>. If
- * <i>suffix</i> is given and present at the end of <i>file_name</i>,
- * it is removed. If <i>suffix</i> is ".*", any extension will be
- * removed.
+ * which can be formed using both File::SEPARATOR and
+ * File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is
+ * not <code>nil</code>. If <i>suffix</i> is given and present at the
+ * end of <i>file_name</i>, it is removed. If <i>suffix</i> is ".*",
+ * any extension will be removed.
*
* File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb"
* File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby"
@@ -4242,7 +4666,7 @@ ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encodin
*/
static VALUE
-rb_file_s_basename(int argc, VALUE *argv)
+rb_file_s_basename(int argc, VALUE *argv, VALUE _)
{
VALUE fname, fext, basename;
const char *name, *p;
@@ -4282,7 +4706,6 @@ rb_file_s_basename(int argc, VALUE *argv)
basename = rb_str_new(p, f);
rb_enc_copy(basename, fname);
- OBJ_INFECT(basename, fname);
return basename;
}
@@ -4292,9 +4715,9 @@ rb_file_s_basename(int argc, VALUE *argv)
*
* Returns all components of the filename given in <i>file_name</i>
* except the last one (after first stripping trailing separators).
- * The filename can be formed using both <code>File::SEPARATOR</code>
- * and <code>File::ALT_SEPARATOR</code> as the separator when
- * <code>File::ALT_SEPARATOR</code> is not <code>nil</code>.
+ * The filename can be formed using both File::SEPARATOR and
+ * File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is
+ * not <code>nil</code>.
*
* File.dirname("/home/gumby/work/ruby.rb") #=> "/home/gumby/work"
*/
@@ -4344,7 +4767,6 @@ rb_file_dirname(VALUE fname)
rb_str_cat(dirname, ".", 1);
#endif
rb_enc_copy(dirname, fname);
- OBJ_INFECT(dirname, fname);
return dirname;
}
@@ -4426,10 +4848,13 @@ ruby_enc_find_extname(const char *name, long *len, rb_encoding *enc)
* An empty string will also be returned when the period is the last character
* in +path+.
*
+ * On Windows, trailing dots are truncated.
+ *
* File.extname("test.rb") #=> ".rb"
* File.extname("a/b/d/test.rb") #=> ".rb"
* File.extname(".a/b/d/test.rb") #=> ".rb"
- * File.extname("foo.") #=> ""
+ * File.extname("foo.") #=> "" on Windows
+ * File.extname("foo.") #=> "." on non-Windows
* File.extname("test") #=> ""
* File.extname(".profile") #=> ""
* File.extname(".profile.sh") #=> ".sh"
@@ -4447,10 +4872,9 @@ rb_file_s_extname(VALUE klass, VALUE fname)
name = StringValueCStr(fname);
len = RSTRING_LEN(fname);
e = ruby_enc_find_extname(name, &len, rb_enc_get(fname));
- if (len <= 1)
+ if (len < 1)
return rb_str_new(0, 0);
extname = rb_str_subseq(fname, e - name, len); /* keep the dot, too! */
- OBJ_INFECT(extname, fname);
return extname;
}
@@ -4476,8 +4900,8 @@ rb_file_s_path(VALUE klass, VALUE fname)
* File.split(file_name) -> array
*
* Splits the given string into a directory and a file component and
- * returns them in a two-element array. See also
- * <code>File::dirname</code> and <code>File::basename</code>.
+ * returns them in a two-element array. See also File::dirname and
+ * File::basename.
*
* File.split("/home/gumby/.profile") #=> ["/home/gumby", ".profile"]
*/
@@ -4486,11 +4910,9 @@ static VALUE
rb_file_s_split(VALUE klass, VALUE path)
{
FilePathStringValue(path); /* get rid of converting twice */
- return rb_assoc_new(rb_file_dirname(path), rb_file_s_basename(1,&path));
+ return rb_assoc_new(rb_file_dirname(path), rb_file_s_basename(1,&path,Qundef));
}
-static VALUE rb_file_join(VALUE ary);
-
static VALUE
file_inspect_join(VALUE ary, VALUE arg, int recur)
{
@@ -4523,7 +4945,6 @@ rb_file_join(VALUE ary)
len += RARRAY_LEN(ary) - 1;
result = rb_str_buf_new(len);
RBASIC_CLEAR_CLASS(result);
- OBJ_INFECT(result, ary);
for (i=0; i<RARRAY_LEN(ary); i++) {
tmp = RARRAY_AREF(ary, i);
switch (OBJ_BUILTIN_TYPE(tmp)) {
@@ -4583,6 +5004,42 @@ rb_file_s_join(VALUE klass, VALUE args)
}
#if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE)
+struct truncate_arg {
+ const char *path;
+#if defined(HAVE_TRUNCATE)
+#define NUM2POS(n) NUM2OFFT(n)
+ off_t pos;
+#else
+#define NUM2POS(n) NUM2LONG(n)
+ long pos;
+#endif
+};
+
+static void *
+nogvl_truncate(void *ptr)
+{
+ struct truncate_arg *ta = ptr;
+#ifdef HAVE_TRUNCATE
+ return (void *)(VALUE)truncate(ta->path, ta->pos);
+#else /* defined(HAVE_CHSIZE) */
+ {
+ int tmpfd = rb_cloexec_open(ta->path, 0, 0);
+
+ if (tmpfd < 0)
+ return (void *)-1;
+ rb_update_max_fd(tmpfd);
+ if (chsize(tmpfd, ta->pos) < 0) {
+ int e = errno;
+ close(tmpfd);
+ errno = e;
+ return (void *)-1;
+ }
+ close(tmpfd);
+ return 0;
+ }
+#endif
+}
+
/*
* call-seq:
* File.truncate(file_name, integer) -> 0
@@ -4601,36 +5058,18 @@ rb_file_s_join(VALUE klass, VALUE args)
static VALUE
rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
{
-#ifdef HAVE_TRUNCATE
-#define NUM2POS(n) NUM2OFFT(n)
- off_t pos;
-#else
-#define NUM2POS(n) NUM2LONG(n)
- long pos;
-#endif
+ struct truncate_arg ta;
+ int r;
- pos = NUM2POS(len);
+ ta.pos = NUM2POS(len);
FilePathValue(path);
path = rb_str_encode_ospath(path);
-#ifdef HAVE_TRUNCATE
- if (truncate(StringValueCStr(path), pos) < 0)
- rb_sys_fail_path(path);
-#else /* defined(HAVE_CHSIZE) */
- {
- int tmpfd;
+ ta.path = StringValueCStr(path);
- if ((tmpfd = rb_cloexec_open(StringValueCStr(path), 0, 0)) < 0) {
- rb_sys_fail_path(path);
- }
- rb_update_max_fd(tmpfd);
- if (chsize(tmpfd, pos) < 0) {
- int e = errno;
- close(tmpfd);
- rb_syserr_fail_path(e, path);
- }
- close(tmpfd);
- }
-#endif
+ r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_truncate, &ta,
+ RUBY_UBF_IO, NULL);
+ if (r < 0)
+ rb_sys_fail_path(path);
return INT2FIX(0);
#undef NUM2POS
}
@@ -4639,6 +5078,29 @@ rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
#endif
#if defined(HAVE_FTRUNCATE) || defined(HAVE_CHSIZE)
+struct ftruncate_arg {
+ int fd;
+#if defined(HAVE_FTRUNCATE)
+#define NUM2POS(n) NUM2OFFT(n)
+ off_t pos;
+#else
+#define NUM2POS(n) NUM2LONG(n)
+ long pos;
+#endif
+};
+
+static VALUE
+nogvl_ftruncate(void *ptr)
+{
+ struct ftruncate_arg *fa = ptr;
+
+#ifdef HAVE_FTRUNCATE
+ return (VALUE)ftruncate(fa->fd, fa->pos);
+#else /* defined(HAVE_CHSIZE) */
+ return (VALUE)chsize(fa->fd, fa->pos);
+#endif
+}
+
/*
* call-seq:
* file.truncate(integer) -> 0
@@ -4657,27 +5119,18 @@ static VALUE
rb_file_truncate(VALUE obj, VALUE len)
{
rb_io_t *fptr;
-#if defined(HAVE_FTRUNCATE)
-#define NUM2POS(n) NUM2OFFT(n)
- off_t pos;
-#else
-#define NUM2POS(n) NUM2LONG(n)
- long pos;
-#endif
+ struct ftruncate_arg fa;
- pos = NUM2POS(len);
+ fa.pos = NUM2POS(len);
GetOpenFile(obj, fptr);
if (!(fptr->mode & FMODE_WRITABLE)) {
rb_raise(rb_eIOError, "not opened for writing");
}
rb_io_flush_raw(obj, 0);
-#ifdef HAVE_FTRUNCATE
- if (ftruncate(fptr->fd, pos) < 0)
- rb_sys_fail_path(fptr->pathv);
-#else /* defined(HAVE_CHSIZE) */
- if (chsize(fptr->fd, pos) < 0)
+ fa.fd = fptr->fd;
+ if ((int)rb_thread_io_blocking_region(nogvl_ftruncate, &fa, fa.fd) < 0) {
rb_sys_fail_path(fptr->pathv);
-#endif
+ }
return INT2FIX(0);
#undef NUM2POS
}
@@ -4725,9 +5178,9 @@ rb_thread_flock(void *data)
*
* Locks or unlocks a file according to <i>locking_constant</i> (a
* logical <em>or</em> of the values in the table below).
- * Returns <code>false</code> if <code>File::LOCK_NB</code> is
- * specified and the operation would otherwise have blocked. Not
- * available on all platforms.
+ * Returns <code>false</code> if File::LOCK_NB is specified and the
+ * operation would otherwise have blocked. Not available on all
+ * platforms.
*
* Locking constants (in class File):
*
@@ -4881,21 +5334,14 @@ test_check(int n, int argc, VALUE *argv)
*/
static VALUE
-rb_f_test(int argc, VALUE *argv)
+rb_f_test(int argc, VALUE *argv, VALUE _)
{
int cmd;
if (argc == 0) rb_check_arity(argc, 2, 3);
cmd = NUM2CHR(argv[0]);
if (cmd == 0) {
- unknown:
- /* unknown command */
- if (ISPRINT(cmd)) {
- rb_raise(rb_eArgError, "unknown command '%s%c'", cmd == '\'' || cmd == '\\' ? "\\" : "", cmd);
- }
- else {
- rb_raise(rb_eArgError, "unknown command \"\\x%02X\"", cmd);
- }
+ goto unknown;
}
if (strchr("bcdefgGkloOprRsSuwWxXz", cmd)) {
CHECK(1);
@@ -5021,22 +5467,28 @@ rb_f_test(int argc, VALUE *argv)
return Qfalse;
}
}
- goto unknown;
+ unknown:
+ /* unknown command */
+ if (ISPRINT(cmd)) {
+ rb_raise(rb_eArgError, "unknown command '%s%c'", cmd == '\'' || cmd == '\\' ? "\\" : "", cmd);
+ }
+ else {
+ rb_raise(rb_eArgError, "unknown command \"\\x%02X\"", cmd);
+ }
+ UNREACHABLE_RETURN(Qundef);
}
/*
* Document-class: File::Stat
*
- * Objects of class <code>File::Stat</code> encapsulate common status
- * information for <code>File</code> objects. The information is
- * recorded at the moment the <code>File::Stat</code> object is
- * created; changes made to the file after that point will not be
- * reflected. <code>File::Stat</code> objects are returned by
- * <code>IO#stat</code>, <code>File::stat</code>,
- * <code>File#lstat</code>, and <code>File::lstat</code>. Many of these
+ * Objects of class File::Stat encapsulate common status information
+ * for File objects. The information is recorded at the moment the
+ * File::Stat object is created; changes made to the file after that
+ * point will not be reflected. File::Stat objects are returned by
+ * IO#stat, File::stat, File#lstat, and File::lstat. Many of these
* methods return platform-specific values, and not all values are
- * meaningful on all systems. See also <code>Kernel#test</code>.
+ * meaningful on all systems. See also Kernel#test.
*/
static VALUE
@@ -5157,10 +5609,9 @@ rb_stat_p(VALUE obj)
*
* Returns <code>true</code> if <i>stat</i> is a symbolic link,
* <code>false</code> if it isn't or if the operating system doesn't
- * support this feature. As <code>File::stat</code> automatically
- * follows symbolic links, <code>symlink?</code> will always be
- * <code>false</code> for an object returned by
- * <code>File::stat</code>.
+ * support this feature. As File::stat automatically follows symbolic
+ * links, #symlink? will always be <code>false</code> for an object
+ * returned by File::stat.
*
* File.symlink("testfile", "alink") #=> 0
* File.stat("alink").symlink? #=> false
@@ -5667,6 +6118,19 @@ rb_stat_sticky(VALUE obj)
#endif
#ifdef HAVE_MKFIFO
+struct mkfifo_arg {
+ const char *path;
+ mode_t mode;
+};
+
+static void *
+nogvl_mkfifo(void *ptr)
+{
+ struct mkfifo_arg *ma = ptr;
+
+ return (void *)(VALUE)mkfifo(ma->path, ma->mode);
+}
+
/*
* call-seq:
* File.mkfifo(file_name, mode=0666) => 0
@@ -5678,19 +6142,21 @@ rb_stat_sticky(VALUE obj)
*/
static VALUE
-rb_file_s_mkfifo(int argc, VALUE *argv)
+rb_file_s_mkfifo(int argc, VALUE *argv, VALUE _)
{
VALUE path;
- int mode = 0666;
+ struct mkfifo_arg ma;
+ ma.mode = 0666;
rb_check_arity(argc, 1, 2);
if (argc > 1) {
- mode = NUM2INT(argv[1]);
+ ma.mode = NUM2MODET(argv[1]);
}
path = argv[0];
FilePathValue(path);
path = rb_str_encode_ospath(path);
- if (mkfifo(RSTRING_PTR(path), mode)) {
+ ma.path = RSTRING_PTR(path);
+ if (rb_thread_call_without_gvl(nogvl_mkfifo, &ma, RUBY_UBF_IO, 0)) {
rb_sys_fail_path(path);
}
return INT2FIX(0);
@@ -5699,7 +6165,7 @@ rb_file_s_mkfifo(int argc, VALUE *argv)
#define rb_file_s_mkfifo rb_f_notimplement
#endif
-VALUE rb_mFConst;
+static VALUE rb_mFConst;
void
rb_file_const(const char *name, VALUE value)
@@ -5732,7 +6198,7 @@ rb_is_absolute_path(const char *path)
#if ENABLE_PATH_CHECK
static int
-path_check_0(VALUE path, int execpath)
+path_check_0(VALUE path)
{
struct stat st;
const char *p0 = StringValueCStr(path);
@@ -5741,7 +6207,7 @@ path_check_0(VALUE path, int execpath)
char *p = 0, *s;
if (!rb_is_absolute_path(p0)) {
- char *buf = my_getcwd();
+ char *buf = ruby_getcwd();
VALUE newpath;
newpath = rb_str_new2(buf);
@@ -5760,12 +6226,12 @@ path_check_0(VALUE path, int execpath)
#endif
if (STAT(p0, &st) == 0 && S_ISDIR(st.st_mode) && (st.st_mode & S_IWOTH)
#ifdef S_ISVTX
- && !(p && execpath && (st.st_mode & S_ISVTX))
+ && !(p && (st.st_mode & S_ISVTX))
#endif
&& !access(p0, W_OK)) {
- rb_enc_warn(enc, "Insecure world writable dir %s in %sPATH, mode 0%"
+ rb_enc_warn(enc, "Insecure world writable dir %s in PATH, mode 0%"
PRI_MODET_PREFIX"o",
- p0, (execpath ? "" : "LOAD_"), st.st_mode);
+ p0, st.st_mode);
if (p) *p = '/';
RB_GC_GUARD(path);
return 0;
@@ -5780,12 +6246,6 @@ path_check_0(VALUE path, int execpath)
}
#endif
-#if ENABLE_PATH_CHECK
-#define fpath_check(path) path_check_0((path), FALSE)
-#else
-#define fpath_check(path) 1
-#endif
-
int
rb_path_check(const char *path)
{
@@ -5801,7 +6261,7 @@ rb_path_check(const char *path)
if (!p) p = pend;
for (;;) {
- if (!path_check_0(rb_str_new(p0, p - p0), TRUE)) {
+ if (!path_check_0(rb_str_new(p0, p - p0))) {
return 0; /* not safe */
}
p0 = p + 1;
@@ -5827,7 +6287,7 @@ ruby_is_fd_loadable(int fd)
if (S_ISREG(st.st_mode))
return 1;
- if (S_ISFIFO(st.st_mode))
+ if (S_ISFIFO(st.st_mode) || S_ISCHR(st.st_mode))
return -1;
if (S_ISDIR(st.st_mode))
@@ -5884,12 +6344,6 @@ copy_path_class(VALUE path, VALUE orig)
int
rb_find_file_ext(VALUE *filep, const char *const *ext)
{
- return rb_find_file_ext_safe(filep, ext, rb_safe_level());
-}
-
-int
-rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
-{
const char *f = StringValueCStr(*filep);
VALUE fname = *filep, load_path, tmp;
long i, j, fnlen;
@@ -5899,18 +6353,12 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
if (f[0] == '~') {
fname = file_expand_path_1(fname);
- if (safe_level >= 1 && OBJ_TAINTED(fname)) {
- rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
- }
f = RSTRING_PTR(fname);
*filep = fname;
expanded = 1;
}
if (expanded || rb_is_absolute_path(f) || is_explicit_relative(f)) {
- if (safe_level >= 1 && !fpath_check(fname)) {
- rb_raise(rb_eSecurityError, "loading from unsafe path %s", f);
- }
if (!expanded) fname = file_expand_path_1(fname);
fnlen = RSTRING_LEN(fname);
for (i=0; ext[i]; i++) {
@@ -5937,14 +6385,13 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
for (i = 0; i < RARRAY_LEN(load_path); i++) {
VALUE str = RARRAY_AREF(load_path, i);
- RB_GC_GUARD(str) = rb_get_path_check(str, safe_level);
+ RB_GC_GUARD(str) = rb_get_path(str);
if (RSTRING_LEN(str) == 0) continue;
rb_file_expand_path_internal(fname, str, 0, 0, tmp);
if (rb_file_load_ok(RSTRING_PTR(tmp))) {
*filep = copy_path_class(tmp, *filep);
return (int)(j+1);
}
- FL_UNSET(tmp, FL_TAINT);
}
rb_str_set_len(fname, fnlen);
}
@@ -5956,30 +6403,18 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
VALUE
rb_find_file(VALUE path)
{
- return rb_find_file_safe(path, rb_safe_level());
-}
-
-VALUE
-rb_find_file_safe(VALUE path, int safe_level)
-{
VALUE tmp, load_path;
const char *f = StringValueCStr(path);
int expanded = 0;
if (f[0] == '~') {
tmp = file_expand_path_1(path);
- if (safe_level >= 1 && OBJ_TAINTED(tmp)) {
- rb_raise(rb_eSecurityError, "loading from unsafe file %"PRIsVALUE, tmp);
- }
path = copy_path_class(tmp, path);
f = RSTRING_PTR(path);
expanded = 1;
}
if (expanded || rb_is_absolute_path(f) || is_explicit_relative(f)) {
- if (safe_level >= 1 && !fpath_check(path)) {
- rb_raise(rb_eSecurityError, "loading from unsafe path %"PRIsVALUE, path);
- }
if (!rb_file_load_ok(f)) return 0;
if (!expanded)
path = copy_path_class(file_expand_path_1(path), path);
@@ -5994,7 +6429,7 @@ rb_find_file_safe(VALUE path, int safe_level)
rb_enc_associate_index(tmp, rb_usascii_encindex());
for (i = 0; i < RARRAY_LEN(load_path); i++) {
VALUE str = RARRAY_AREF(load_path, i);
- RB_GC_GUARD(str) = rb_get_path_check(str, safe_level);
+ RB_GC_GUARD(str) = rb_get_path(str);
if (RSTRING_LEN(str) > 0) {
rb_file_expand_path_internal(path, str, 0, 0, tmp);
f = RSTRING_PTR(tmp);
@@ -6009,10 +6444,6 @@ rb_find_file_safe(VALUE path, int safe_level)
}
found:
- if (safe_level >= 1 && !fpath_check(tmp)) {
- rb_raise(rb_eSecurityError, "loading from unsafe file %"PRIsVALUE, tmp);
- }
-
return copy_path_class(tmp, path);
}
@@ -6023,7 +6454,7 @@ define_filetest_function(const char *name, VALUE (*func)(ANYARGS), int argc)
rb_define_singleton_method(rb_cFile, name, func, argc);
}
-static const char null_device[] =
+const char ruby_null_device[] =
#if defined DOSISH
"NUL"
#elif defined AMIGA || defined __amigaos__
@@ -6036,11 +6467,10 @@ static const char null_device[] =
;
/*
- * A <code>File</code> is an abstraction of any file object accessible
- * by the program and is closely associated with class <code>IO</code>.
- * <code>File</code> includes the methods of module
- * <code>FileTest</code> as class methods, allowing you to write (for
- * example) <code>File.exist?("foo")</code>.
+ * A File is an abstraction of any file object accessible by the
+ * program and is closely associated with class IO. File includes
+ * the methods of module FileTest as class methods, allowing you to
+ * write (for example) <code>File.exist?("foo")</code>.
*
* In the description of File methods,
* <em>permission bits</em> are a platform-specific
@@ -6072,6 +6502,10 @@ static const char null_device[] =
void
Init_File(void)
{
+#if defined(__APPLE__) && defined(HAVE_WORKING_FORK)
+ rb_CFString_class_initialize_before_fork();
+#endif
+
VALUE separator;
rb_mFileTest = rb_define_module("FileTest");
@@ -6123,6 +6557,7 @@ Init_File(void)
rb_define_singleton_method(rb_cFile, "chown", rb_file_s_chown, -1);
rb_define_singleton_method(rb_cFile, "lchmod", rb_file_s_lchmod, -1);
rb_define_singleton_method(rb_cFile, "lchown", rb_file_s_lchown, -1);
+ rb_define_singleton_method(rb_cFile, "lutime", rb_file_s_lutime, -1);
rb_define_singleton_method(rb_cFile, "link", rb_file_s_link, 2);
rb_define_singleton_method(rb_cFile, "symlink", rb_file_s_symlink, 2);
@@ -6134,8 +6569,9 @@ Init_File(void)
rb_define_singleton_method(rb_cFile, "umask", rb_file_s_umask, -1);
rb_define_singleton_method(rb_cFile, "truncate", rb_file_s_truncate, 2);
rb_define_singleton_method(rb_cFile, "mkfifo", rb_file_s_mkfifo, -1);
- rb_define_singleton_method(rb_cFile, "expand_path", rb_file_s_expand_path, -1);
- rb_define_singleton_method(rb_cFile, "absolute_path", rb_file_s_absolute_path, -1);
+ rb_define_singleton_method(rb_cFile, "expand_path", s_expand_path, -1);
+ rb_define_singleton_method(rb_cFile, "absolute_path", s_absolute_path, -1);
+ rb_define_singleton_method(rb_cFile, "absolute_path?", s_absolute_path_p, 1);
rb_define_singleton_method(rb_cFile, "realpath", rb_file_s_realpath, -1);
rb_define_singleton_method(rb_cFile, "realdirpath", rb_file_s_realdirpath, -1);
rb_define_singleton_method(rb_cFile, "basename", rb_file_s_basename, -1);
@@ -6143,9 +6579,10 @@ Init_File(void)
rb_define_singleton_method(rb_cFile, "extname", rb_file_s_extname, 1);
rb_define_singleton_method(rb_cFile, "path", rb_file_s_path, 1);
- separator = rb_fstring_cstr("/");
+ separator = rb_fstring_lit("/");
/* separates directory parts in path */
rb_define_const(rb_cFile, "Separator", separator);
+ /* separates directory parts in path */
rb_define_const(rb_cFile, "SEPARATOR", separator);
rb_define_singleton_method(rb_cFile, "split", rb_file_s_split, 1);
rb_define_singleton_method(rb_cFile, "join", rb_file_s_join, -2);
@@ -6264,7 +6701,7 @@ Init_File(void)
rb_define_const(rb_mFConst, "LOCK_NB", INT2FIX(LOCK_NB));
/* Name of the null device */
- rb_define_const(rb_mFConst, "NULL", rb_fstring_cstr(null_device));
+ rb_define_const(rb_mFConst, "NULL", rb_fstring_cstr(ruby_null_device));
rb_define_method(rb_cFile, "path", rb_file_path, 0);
rb_define_method(rb_cFile, "to_path", rb_file_path, 0);
diff --git a/gc.c b/gc.c
index 3a27e4ee67..5d0c342206 100644
--- a/gc.c
+++ b/gc.c
@@ -14,40 +14,38 @@
#define rb_data_object_alloc rb_data_object_alloc
#define rb_data_typed_object_alloc rb_data_typed_object_alloc
-#include "internal.h"
-#include "ruby/st.h"
-#include "ruby/re.h"
-#include "ruby/io.h"
-#include "ruby/thread.h"
-#include "ruby/util.h"
-#include "ruby/debug.h"
-#include "eval_intern.h"
-#include "vm_core.h"
-#include "gc.h"
-#include "constant.h"
-#include "ruby_atomic.h"
-#include "probes.h"
-#include "id_table.h"
-#include <stdio.h>
-#include <stdarg.h>
-#include <setjmp.h>
-#include <sys/types.h>
-#include "ruby_assert.h"
-#include "debug_counter.h"
+#include "ruby/internal/config.h"
+#ifdef _WIN32
+# include "ruby/ruby.h"
+#endif
-#undef rb_data_object_wrap
+#include <signal.h>
+
+#define sighandler_t ruby_sighandler_t
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stdio.h>
#ifndef HAVE_MALLOC_USABLE_SIZE
# ifdef _WIN32
-# define HAVE_MALLOC_USABLE_SIZE
-# define malloc_usable_size(a) _msize(a)
+# define HAVE_MALLOC_USABLE_SIZE
+# define malloc_usable_size(a) _msize(a)
# elif defined HAVE_MALLOC_SIZE
-# define HAVE_MALLOC_USABLE_SIZE
-# define malloc_usable_size(a) malloc_size(a)
+# define HAVE_MALLOC_USABLE_SIZE
+# define malloc_usable_size(a) malloc_size(a)
# endif
#endif
+
#ifdef HAVE_MALLOC_USABLE_SIZE
-# ifdef HAVE_MALLOC_H
+# ifdef RUBY_ALTERNATIVE_MALLOC_HEADER
+# include RUBY_ALTERNATIVE_MALLOC_HEADER
+# elif HAVE_MALLOC_H
# include <malloc.h>
# elif defined(HAVE_MALLOC_NP_H)
# include <malloc_np.h>
@@ -56,39 +54,190 @@
# endif
#endif
-#if /* is ASAN enabled? */ \
- __has_feature(address_sanitizer) /* Clang */ || \
- defined(__SANITIZE_ADDRESS__) /* GCC 4.8.x */
- #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \
- __attribute__((no_address_safety_analysis)) \
- __attribute__((noinline))
-#else
- #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
-#endif
-
#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+# include <sys/time.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-#if defined(__native_client__) && defined(NACL_NEWLIB)
-# include "nacl/resource.h"
-# undef HAVE_POSIX_MEMALIGN
-# undef HAVE_MEMALIGN
-
+# include <sys/resource.h>
#endif
#if defined _WIN32 || defined __CYGWIN__
-#include <windows.h>
+# include <windows.h>
#elif defined(HAVE_POSIX_MEMALIGN)
#elif defined(HAVE_MEMALIGN)
-#include <malloc.h>
+# include <malloc.h>
#endif
+#include <sys/types.h>
+
+#include "constant.h"
+#include "debug_counter.h"
+#include "eval_intern.h"
+#include "gc.h"
+#include "id_table.h"
+#include "internal.h"
+#include "internal/class.h"
+#include "internal/complex.h"
+#include "internal/cont.h"
+#include "internal/error.h"
+#include "internal/eval.h"
+#include "internal/gc.h"
+#include "internal/hash.h"
+#include "internal/imemo.h"
+#include "internal/io.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/proc.h"
+#include "internal/rational.h"
+#include "internal/sanitizers.h"
+#include "internal/struct.h"
+#include "internal/symbol.h"
+#include "internal/thread.h"
+#include "internal/variable.h"
+#include "internal/warnings.h"
+#include "mjit.h"
+#include "probes.h"
+#include "regint.h"
+#include "ruby/debug.h"
+#include "ruby/io.h"
+#include "ruby/re.h"
+#include "ruby/st.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+#include "ruby_assert.h"
+#include "ruby_atomic.h"
+#include "symbol.h"
+#include "transient_heap.h"
+#include "vm_core.h"
+#include "vm_sync.h"
+#include "vm_callinfo.h"
+#include "ractor_core.h"
+
+#include "builtin.h"
+
#define rb_setjmp(env) RUBY_SETJMP(env)
#define rb_jmp_buf rb_jmpbuf_t
+#undef rb_data_object_wrap
+
+static inline struct rbimpl_size_mul_overflow_tag
+size_add_overflow(size_t x, size_t y)
+{
+ size_t z;
+ bool p;
+#if 0
+
+#elif __has_builtin(__builtin_add_overflow)
+ p = __builtin_add_overflow(x, y, &z);
+
+#elif defined(DSIZE_T)
+ RB_GNUC_EXTENSION DSIZE_T dx = x;
+ RB_GNUC_EXTENSION DSIZE_T dy = y;
+ RB_GNUC_EXTENSION DSIZE_T dz = dx + dy;
+ p = dz > SIZE_MAX;
+ z = (size_t)dz;
+
+#else
+ z = x + y;
+ p = z < y;
+
+#endif
+ return (struct rbimpl_size_mul_overflow_tag) { p, z, };
+}
+
+static inline struct rbimpl_size_mul_overflow_tag
+size_mul_add_overflow(size_t x, size_t y, size_t z) /* x * y + z */
+{
+ struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y);
+ struct rbimpl_size_mul_overflow_tag u = size_add_overflow(t.right, z);
+ return (struct rbimpl_size_mul_overflow_tag) { t.left || u.left, u.right };
+}
+
+static inline struct rbimpl_size_mul_overflow_tag
+size_mul_add_mul_overflow(size_t x, size_t y, size_t z, size_t w) /* x * y + z * w */
+{
+ struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y);
+ struct rbimpl_size_mul_overflow_tag u = rbimpl_size_mul_overflow(z, w);
+ struct rbimpl_size_mul_overflow_tag v = size_add_overflow(t.right, u.right);
+ return (struct rbimpl_size_mul_overflow_tag) { t.left || u.left || v.left, v.right };
+}
+
+PRINTF_ARGS(NORETURN(static void gc_raise(VALUE, const char*, ...)), 2, 3);
+
+static inline size_t
+size_mul_or_raise(size_t x, size_t y, VALUE exc)
+{
+ struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y);
+ if (LIKELY(!t.left)) {
+ return t.right;
+ }
+ else if (rb_during_gc()) {
+ rb_memerror(); /* or...? */
+ }
+ else {
+ gc_raise(
+ exc,
+ "integer overflow: %"PRIuSIZE
+ " * %"PRIuSIZE
+ " > %"PRIuSIZE,
+ x, y, SIZE_MAX);
+ }
+}
+
+size_t
+rb_size_mul_or_raise(size_t x, size_t y, VALUE exc)
+{
+ return size_mul_or_raise(x, y, exc);
+}
+
+static inline size_t
+size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc)
+{
+ struct rbimpl_size_mul_overflow_tag t = size_mul_add_overflow(x, y, z);
+ if (LIKELY(!t.left)) {
+ return t.right;
+ }
+ else if (rb_during_gc()) {
+ rb_memerror(); /* or...? */
+ }
+ else {
+ gc_raise(
+ exc,
+ "integer overflow: %"PRIuSIZE
+ " * %"PRIuSIZE
+ " + %"PRIuSIZE
+ " > %"PRIuSIZE,
+ x, y, z, SIZE_MAX);
+ }
+}
+
+size_t
+rb_size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc)
+{
+ return size_mul_add_or_raise(x, y, z, exc);
+}
+
+static inline size_t
+size_mul_add_mul_or_raise(size_t x, size_t y, size_t z, size_t w, VALUE exc)
+{
+ struct rbimpl_size_mul_overflow_tag t = size_mul_add_mul_overflow(x, y, z, w);
+ if (LIKELY(!t.left)) {
+ return t.right;
+ }
+ else if (rb_during_gc()) {
+ rb_memerror(); /* or...? */
+ }
+ else {
+ gc_raise(
+ exc,
+ "integer overflow: %"PRIdSIZE
+ " * %"PRIdSIZE
+ " + %"PRIdSIZE
+ " * %"PRIdSIZE
+ " > %"PRIdSIZE,
+ x, y, z, w, SIZE_MAX);
+ }
+}
#if defined(HAVE_RB_GC_GUARDED_PTR_VAL) && HAVE_RB_GC_GUARDED_PTR_VAL
/* trick the compiler into thinking a external signal handler uses this */
@@ -212,7 +361,6 @@ static ruby_gc_params_t gc_params = {
#define GC_DEBUG 0
#endif
-#if USE_RGENGC
/* RGENGC_DEBUG:
* 1: basic information
* 2: remember set operation
@@ -230,7 +378,7 @@ static ruby_gc_params_t gc_params = {
#if RGENGC_DEBUG < 0 && !defined(_MSC_VER)
# define RGENGC_DEBUG_ENABLED(level) (-(RGENGC_DEBUG) >= (level) && ruby_rgengc_debug >= (level))
#else
-# define RGENGC_DEBUG_ENABLED(level) ((RGENGC_DEBUG) >= (level))
+# define RGENGC_DEBUG_ENABLED(level) 0
#endif
int ruby_rgengc_debug;
@@ -246,11 +394,8 @@ int ruby_rgengc_debug;
#define RGENGC_CHECK_MODE 0
#endif
-#if RGENGC_CHECK_MODE > 0
+// Note: using RUBY_ASSERT_WHEN() extend a macro in expr (info by nobu).
#define GC_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(RGENGC_CHECK_MODE > 0, expr, #expr)
-#else
-#define GC_ASSERT(expr) ((void)0)
-#endif
/* RGENGC_OLD_NEWOBJ_CHECK
* 0: disable all assertions
@@ -288,22 +433,6 @@ int ruby_rgengc_debug;
#define RGENGC_FORCE_MAJOR_GC 0
#endif
-#else /* USE_RGENGC */
-
-#ifdef RGENGC_DEBUG
-#undef RGENGC_DEBUG
-#endif
-#define RGENGC_DEBUG 0
-#ifdef RGENGC_CHECK_MODE
-#undef RGENGC_CHECK_MODE
-#endif
-#define RGENGC_CHECK_MODE 0
-#define RGENGC_PROFILE 0
-#define RGENGC_ESTIMATE_OLDMALLOC 0
-#define RGENGC_FORCE_MAJOR_GC 0
-
-#endif /* USE_RGENGC */
-
#ifndef GC_PROFILE_MORE_DETAIL
#define GC_PROFILE_MORE_DETAIL 0
#endif
@@ -317,7 +446,7 @@ int ruby_rgengc_debug;
#define GC_ENABLE_LAZY_SWEEP 1
#endif
#ifndef CALC_EXACT_MALLOC_SIZE
-#define CALC_EXACT_MALLOC_SIZE 0
+#define CALC_EXACT_MALLOC_SIZE USE_GC_MALLOC_OBJ_INFO_DETAILS
#endif
#if defined(HAVE_MALLOC_USABLE_SIZE) || CALC_EXACT_MALLOC_SIZE > 0
#ifndef MALLOC_ALLOCATED_SIZE
@@ -359,7 +488,14 @@ typedef enum {
/* others */
GPR_FLAG_IMMEDIATE_SWEEP = 0x2000,
- GPR_FLAG_HAVE_FINALIZE = 0x4000
+ GPR_FLAG_HAVE_FINALIZE = 0x4000,
+ GPR_FLAG_IMMEDIATE_MARK = 0x8000,
+ GPR_FLAG_FULL_MARK = 0x10000,
+ GPR_FLAG_COMPACT = 0x20000,
+
+ GPR_DEFAULT_REASON =
+ (GPR_FLAG_FULL_MARK | GPR_FLAG_IMMEDIATE_MARK |
+ GPR_FLAG_IMMEDIATE_SWEEP | GPR_FLAG_CAPI),
} gc_profile_record_flag;
typedef struct gc_profile_record {
@@ -371,6 +507,7 @@ typedef struct gc_profile_record {
size_t heap_total_objects;
size_t heap_use_size;
size_t heap_total_size;
+ size_t moved_objects;
#if GC_PROFILE_MORE_DETAIL
double gc_mark_time;
@@ -403,6 +540,16 @@ typedef struct gc_profile_record {
#endif
} gc_profile_record;
+#define FL_FROM_FREELIST FL_USER0
+
+struct RMoved {
+ VALUE flags;
+ VALUE dummy;
+ VALUE destination;
+};
+
+#define RMOVED(obj) ((struct RMoved *)(obj))
+
#if defined(_MSC_VER) || defined(__CYGWIN__)
#pragma pack(push, 1) /* magic for reducing sizeof(RVALUE): 24 -> 20 */
#endif
@@ -413,6 +560,7 @@ typedef struct RVALUE {
VALUE flags; /* always 0 for freed obj */
struct RVALUE *next;
} free;
+ struct RMoved moved;
struct RBasic basic;
struct RObject object;
struct RClass klass;
@@ -426,7 +574,6 @@ typedef struct RVALUE {
struct RStruct rstruct;
struct RBignum bignum;
struct RFile file;
- struct RNode node;
struct RMatch match;
struct RRational rational;
struct RComplex complex;
@@ -439,6 +586,8 @@ typedef struct RVALUE {
struct rb_method_entry_struct ment;
const rb_iseq_t iseq;
rb_env_t env;
+ struct rb_imemo_tmpbuf_struct alloc;
+ rb_ast_t ast;
} imemo;
struct {
struct RBasic basic;
@@ -462,6 +611,7 @@ enum {
BITS_SIZE = sizeof(bits_t),
BITS_BITLENGTH = ( BITS_SIZE * CHAR_BIT )
};
+#define popcount_bits rb_popcount_intptr
struct heap_page_header {
struct heap_page *page;
@@ -495,12 +645,11 @@ typedef struct mark_stack {
} mark_stack_t;
typedef struct rb_heap_struct {
- RVALUE *freelist;
-
struct heap_page *free_pages;
- struct heap_page *using_page;
- struct heap_page *pages;
- struct heap_page *sweep_pages;
+ struct list_head pages;
+ struct heap_page *sweeping_page; /* iterator for .pages */
+ struct heap_page *compact_cursor;
+ size_t compact_cursor_index;
#if GC_ENABLE_INCREMENTAL_MARK
struct heap_page *pooled_pages;
#endif
@@ -530,11 +679,10 @@ typedef struct rb_objspace {
unsigned int dont_gc : 1;
unsigned int dont_incremental : 1;
unsigned int during_gc : 1;
+ unsigned int during_compacting : 1;
unsigned int gc_stressful: 1;
unsigned int has_hook: 1;
-#if USE_RGENGC
unsigned int during_minor_gc : 1;
-#endif
#if GC_ENABLE_INCREMENTAL_MARK
unsigned int during_incremental_marking : 1;
#endif
@@ -542,6 +690,7 @@ typedef struct rb_objspace {
rb_event_flag_t hook_events;
size_t total_allocated_objects;
+ VALUE next_object_id;
rb_heap_t eden_heap;
rb_heap_t tomb_heap; /* heap for zombies and ghosts */
@@ -550,11 +699,6 @@ typedef struct rb_objspace {
rb_atomic_t finalizing;
} atomic_flags;
- struct mark_func_data_struct {
- void *data;
- void (*mark_func)(VALUE v, void *data);
- } *mark_func_data;
-
mark_stack_t mark_stack;
size_t marked_slots;
@@ -586,9 +730,10 @@ typedef struct rb_objspace {
#endif
double invoke_time;
-#if USE_RGENGC
size_t minor_gc_count;
size_t major_gc_count;
+ size_t compact_count;
+ size_t read_barrier_faults;
#if RGENGC_PROFILE > 0
size_t total_generated_normal_object_count;
size_t total_generated_shady_object_count;
@@ -606,7 +751,6 @@ typedef struct rb_objspace {
size_t remembered_shady_object_count_types[RUBY_T_MASK];
#endif
#endif /* RGENGC_PROFILE */
-#endif /* USE_RGENGC */
/* temporary profiling space */
double gc_sweep_start_time;
@@ -623,7 +767,6 @@ typedef struct rb_objspace {
VALUE gc_stress_mode;
-#if USE_RGENGC
struct {
VALUE parent_object;
int need_major_gc;
@@ -643,13 +786,22 @@ typedef struct rb_objspace {
size_t error_count;
#endif
} rgengc;
+
+ struct {
+ size_t considered_count_table[T_MASK];
+ size_t moved_count_table[T_MASK];
+ size_t total_moved;
+ } rcompactor;
+
#if GC_ENABLE_INCREMENTAL_MARK
struct {
size_t pooled_slots;
size_t step_slots;
} rincgc;
#endif
-#endif /* USE_RGENGC */
+
+ st_table *id_to_obj_tbl;
+ st_table *obj_to_id_tbl;
#if GC_DEBUG_STRESS_TO_CLASS
VALUE stress_to_class;
@@ -657,26 +809,23 @@ typedef struct rb_objspace {
} rb_objspace_t;
-#ifndef HEAP_PAGE_ALIGN_LOG
/* default tiny heap size: 16KB */
#define HEAP_PAGE_ALIGN_LOG 14
-#endif
#define CEILDIV(i, mod) (((i) + (mod) - 1)/(mod))
enum {
HEAP_PAGE_ALIGN = (1UL << HEAP_PAGE_ALIGN_LOG),
HEAP_PAGE_ALIGN_MASK = (~(~0UL << HEAP_PAGE_ALIGN_LOG)),
- REQUIRED_SIZE_BY_MALLOC = (sizeof(size_t) * 5),
- HEAP_PAGE_SIZE = (HEAP_PAGE_ALIGN - REQUIRED_SIZE_BY_MALLOC),
+ HEAP_PAGE_SIZE = HEAP_PAGE_ALIGN,
HEAP_PAGE_OBJ_LIMIT = (unsigned int)((HEAP_PAGE_SIZE - sizeof(struct heap_page_header))/sizeof(struct RVALUE)),
HEAP_PAGE_BITMAP_LIMIT = CEILDIV(CEILDIV(HEAP_PAGE_SIZE, sizeof(struct RVALUE)), BITS_BITLENGTH),
HEAP_PAGE_BITMAP_SIZE = (BITS_SIZE * HEAP_PAGE_BITMAP_LIMIT),
- HEAP_PAGE_BITMAP_PLANES = USE_RGENGC ? 4 : 1 /* RGENGC: mark, unprotected, uncollectible, marking */
+ HEAP_PAGE_BITMAP_PLANES = 4 /* RGENGC: mark, unprotected, uncollectible, marking */
};
struct heap_page {
- struct heap_page *prev;
short total_slots;
short free_slots;
+ short pinned_slots;
short final_slots;
struct {
unsigned int before_sweep : 1;
@@ -688,17 +837,16 @@ struct heap_page {
struct heap_page *free_next;
RVALUE *start;
RVALUE *freelist;
- struct heap_page *next;
+ struct list_node page_node;
-#if USE_RGENGC
bits_t wb_unprotected_bits[HEAP_PAGE_BITMAP_LIMIT];
-#endif
/* the following three bitmaps are cleared at the beginning of full GC */
bits_t mark_bits[HEAP_PAGE_BITMAP_LIMIT];
-#if USE_RGENGC
bits_t uncollectible_bits[HEAP_PAGE_BITMAP_LIMIT];
bits_t marking_bits[HEAP_PAGE_BITMAP_LIMIT];
-#endif
+
+ /* If set, the object is not movable */
+ bits_t pinned_bits[HEAP_PAGE_BITMAP_LIMIT];
};
#define GET_PAGE_BODY(x) ((struct heap_page_body *)((bits_t)(x) & ~(HEAP_PAGE_ALIGN_MASK)))
@@ -717,20 +865,14 @@ struct heap_page {
/* getting bitmap */
#define GET_HEAP_MARK_BITS(x) (&GET_HEAP_PAGE(x)->mark_bits[0])
-#if USE_RGENGC
+#define GET_HEAP_PINNED_BITS(x) (&GET_HEAP_PAGE(x)->pinned_bits[0])
#define GET_HEAP_UNCOLLECTIBLE_BITS(x) (&GET_HEAP_PAGE(x)->uncollectible_bits[0])
#define GET_HEAP_WB_UNPROTECTED_BITS(x) (&GET_HEAP_PAGE(x)->wb_unprotected_bits[0])
#define GET_HEAP_MARKING_BITS(x) (&GET_HEAP_PAGE(x)->marking_bits[0])
-#endif
/* Aliases */
-#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
#define rb_objspace (*rb_objspace_of(GET_VM()))
#define rb_objspace_of(vm) ((vm)->objspace)
-#else
-static rb_objspace_t rb_objspace = {{GC_MALLOC_LIMIT_MIN}};
-#define rb_objspace_of(vm) (&rb_objspace)
-#endif
#define ruby_initial_gc_stress gc_params.gc_stress
@@ -750,7 +892,6 @@ VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress;
#define heap_pages_deferred_final objspace->heap_pages.deferred_final
#define heap_eden (&objspace->eden_heap)
#define heap_tomb (&objspace->tomb_heap)
-#define dont_gc objspace->flags.dont_gc
#define during_gc objspace->flags.during_gc
#define finalizing objspace->atomic_flags.finalizing
#define finalizer_table objspace->finalizer_table
@@ -763,6 +904,18 @@ VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress;
#define stress_to_class 0
#endif
+#if 0
+#define dont_gc_on() (fprintf(stderr, "dont_gc_on@%s:%d\n", __FILE__, __LINE__), objspace->flags.dont_gc = 1)
+#define dont_gc_off() (fprintf(stderr, "dont_gc_off@%s:%d\n", __FILE__, __LINE__), objspace->flags.dont_gc = 0)
+#define dont_gc_set(b) (fprintf(stderr, "dont_gc_set(%d)@%s:%d\n", __FILE__, __LINE__), (int)b), objspace->flags.dont_gc = (b))
+#define dont_gc_val() (objspace->flags.dont_gc)
+#else
+#define dont_gc_on() (objspace->flags.dont_gc = 1)
+#define dont_gc_off() (objspace->flags.dont_gc = 0)
+#define dont_gc_set(b) (((int)b), objspace->flags.dont_gc = (b))
+#define dont_gc_val() (objspace->flags.dont_gc)
+#endif
+
static inline enum gc_mode
gc_mode_verify(enum gc_mode mode)
{
@@ -784,11 +937,7 @@ gc_mode_verify(enum gc_mode mode)
#define is_marking(objspace) (gc_mode(objspace) == gc_mode_marking)
#define is_sweeping(objspace) (gc_mode(objspace) == gc_mode_sweeping)
-#if USE_RGENGC
#define is_full_marking(objspace) ((objspace)->flags.during_minor_gc == FALSE)
-#else
-#define is_full_marking(objspace) TRUE
-#endif
#if GC_ENABLE_INCREMENTAL_MARK
#define is_incremental_marking(objspace) ((objspace)->flags.during_incremental_marking != FALSE)
#else
@@ -799,7 +948,7 @@ gc_mode_verify(enum gc_mode mode)
#else
#define will_be_incremental_marking(objspace) FALSE
#endif
-#define has_sweeping_pages(heap) ((heap)->sweep_pages != 0)
+#define has_sweeping_pages(heap) ((heap)->sweeping_page != 0)
#define is_lazy_sweeping(heap) (GC_ENABLE_LAZY_SWEEP && has_sweeping_pages(heap))
#if SIZEOF_LONG == SIZEOF_VOIDP
@@ -826,54 +975,67 @@ struct RZombie {
#define nomem_error GET_VM()->special_exceptions[ruby_error_nomemory]
+#if RUBY_MARK_FREE_DEBUG
int ruby_gc_debug_indent = 0;
+#endif
VALUE rb_mGC;
int ruby_disable_gc = 0;
+int ruby_enable_autocompact = 0;
void rb_iseq_mark(const rb_iseq_t *iseq);
+void rb_iseq_update_references(rb_iseq_t *iseq);
void rb_iseq_free(const rb_iseq_t *iseq);
+size_t rb_iseq_memsize(const rb_iseq_t *iseq);
+void rb_vm_update_references(void *ptr);
void rb_gcdebug_print_obj_condition(VALUE obj);
-static void rb_objspace_call_finalizer(rb_objspace_t *objspace);
static VALUE define_final0(VALUE obj, VALUE block);
-static void negative_size_allocation_error(const char *);
-static void *aligned_malloc(size_t, size_t);
-static void aligned_free(void *);
+NORETURN(static void *gc_vraise(void *ptr));
+NORETURN(static void gc_raise(VALUE exc, const char *fmt, ...));
+NORETURN(static void negative_size_allocation_error(const char *));
static void init_mark_stack(mark_stack_t *stack);
static int ready_to_gc(rb_objspace_t *objspace);
-static int garbage_collect(rb_objspace_t *, int full_mark, int immediate_mark, int immediate_sweep, int reason);
+static int garbage_collect(rb_objspace_t *, int reason);
-static int gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark, const unsigned int immediate_sweep, int reason);
+static int gc_start(rb_objspace_t *objspace, int reason);
static void gc_rest(rb_objspace_t *objspace);
-static inline void gc_enter(rb_objspace_t *objspace, const char *event);
-static inline void gc_exit(rb_objspace_t *objspace, const char *event);
+
+enum gc_enter_event {
+ gc_enter_event_start,
+ gc_enter_event_mark_continue,
+ gc_enter_event_sweep_continue,
+ gc_enter_event_rest,
+ gc_enter_event_finalizer,
+ gc_enter_event_rb_memerror,
+};
+
+static inline void gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev);
+static inline void gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev);
static void gc_marks(rb_objspace_t *objspace, int full_mark);
static void gc_marks_start(rb_objspace_t *objspace, int full);
static int gc_marks_finish(rb_objspace_t *objspace);
static void gc_marks_rest(rb_objspace_t *objspace);
-#if GC_ENABLE_INCREMENTAL_MARK
-static void gc_marks_step(rb_objspace_t *objspace, int slots);
+static void gc_marks_step(rb_objspace_t *objspace, size_t slots);
static void gc_marks_continue(rb_objspace_t *objspace, rb_heap_t *heap);
-#endif
static void gc_sweep(rb_objspace_t *objspace);
static void gc_sweep_start(rb_objspace_t *objspace);
static void gc_sweep_finish(rb_objspace_t *objspace);
static int gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap);
static void gc_sweep_rest(rb_objspace_t *objspace);
-#if GC_ENABLE_LAZY_SWEEP
static void gc_sweep_continue(rb_objspace_t *objspace, rb_heap_t *heap);
-#endif
static inline void gc_mark(rb_objspace_t *objspace, VALUE ptr);
+static inline void gc_pin(rb_objspace_t *objspace, VALUE ptr);
+static inline void gc_mark_and_pin(rb_objspace_t *objspace, VALUE ptr);
static void gc_mark_ptr(rb_objspace_t *objspace, VALUE ptr);
-static void gc_mark_maybe(rb_objspace_t *objspace, VALUE ptr);
+NO_SANITIZE("memory", static void gc_mark_maybe(rb_objspace_t *objspace, VALUE ptr));
static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr);
static int gc_mark_stacked_objects_incremental(rb_objspace_t *, size_t count);
@@ -881,7 +1043,7 @@ static int gc_mark_stacked_objects_all(rb_objspace_t *);
static void gc_grey(rb_objspace_t *objspace, VALUE ptr);
static inline int gc_mark_set(rb_objspace_t *objspace, VALUE obj);
-static inline int is_pointer_to_heap(rb_objspace_t *objspace, void *ptr);
+NO_SANITIZE("memory", static inline int is_pointer_to_heap(rb_objspace_t *objspace, void *ptr));
static void push_mark_stack(mark_stack_t *, VALUE);
static int pop_mark_stack(mark_stack_t *, VALUE *);
@@ -889,11 +1051,12 @@ static size_t mark_stack_size(mark_stack_t *stack);
static void shrink_stack_chunk_cache(mark_stack_t *stack);
static size_t obj_memsize_of(VALUE obj, int use_all_types);
-static VALUE gc_verify_internal_consistency(VALUE self);
+static void gc_verify_internal_consistency(rb_objspace_t *objspace);
static int gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj);
static int gc_verify_heap_pages(rb_objspace_t *objspace);
static void gc_stress_set(rb_objspace_t *objspace, VALUE flag);
+static VALUE gc_disable_no_rest(rb_objspace_t *);
static double getrusage_time(void);
static inline void gc_prof_setup_new_record(rb_objspace_t *objspace, int reason);
@@ -906,6 +1069,14 @@ static inline void gc_prof_sweep_timer_stop(rb_objspace_t *);
static inline void gc_prof_set_malloc_info(rb_objspace_t *);
static inline void gc_prof_set_heap_info(rb_objspace_t *);
+#define TYPED_UPDATE_IF_MOVED(_objspace, _type, _thing) do { \
+ if (gc_object_moved_p(_objspace, (VALUE)_thing)) { \
+ *((_type *)(&_thing)) = (_type)RMOVED((_thing))->destination; \
+ } \
+} while (0)
+
+#define UPDATE_IF_MOVED(_objspace, _thing) TYPED_UPDATE_IF_MOVED(_objspace, VALUE, _thing)
+
#define gc_prof_record(objspace) (objspace)->profile.current_record
#define gc_prof_enabled(objspace) ((objspace)->profile.run && (objspace)->profile.current_record)
@@ -917,12 +1088,7 @@ static inline void gc_prof_set_heap_info(rb_objspace_t *);
#endif
PRINTF_ARGS(static void gc_report_body(int level, rb_objspace_t *objspace, const char *fmt, ...), 3, 4);
static const char *obj_info(VALUE obj);
-
-#define PUSH_MARK_FUNC_DATA(v) do { \
- struct mark_func_data_struct *prev_mark_func_data = objspace->mark_func_data; \
- objspace->mark_func_data = (v);
-
-#define POP_MARK_FUNC_DATA() objspace->mark_func_data = prev_mark_func_data;} while (0)
+static const char *obj_type_name(VALUE obj);
/*
* 1 - TSC (H/W Time Stamp Counter)
@@ -976,6 +1142,19 @@ tick(void)
return val;
}
+#elif defined(__aarch64__) && defined(__GNUC__)
+typedef unsigned long tick_t;
+#define PRItick "lu"
+
+static __inline__ tick_t
+tick(void)
+{
+ unsigned long val;
+ __asm__ __volatile__ ("mrs %0, cntvct_el0", : "=r" (val));
+ return val;
+}
+
+
#elif defined(_WIN32) && defined(_MSC_VER)
#include <intrin.h>
typedef unsigned __int64 tick_t;
@@ -1023,6 +1202,14 @@ tick(void)
#define MEASURE_LINE(expr) expr
#endif /* USE_TICK_T */
+static inline void *
+asan_unpoison_object_temporary(VALUE obj)
+{
+ void *ptr = asan_poisoned_object_p(obj);
+ asan_unpoison_object(obj, false);
+ return ptr;
+}
+
#define FL_CHECK2(name, x, pred) \
((RGENGC_CHECK_MODE && SPECIAL_CONST_P(x)) ? \
(rb_bug(name": SPECIAL_CONST (%p)", (void *)(x)), 0) : (pred))
@@ -1031,9 +1218,9 @@ tick(void)
#define FL_UNSET2(x,f) FL_CHECK2("FL_UNSET2", x, RBASIC(x)->flags &= ~(f))
#define RVALUE_MARK_BITMAP(obj) MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), (obj))
+#define RVALUE_PIN_BITMAP(obj) MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), (obj))
#define RVALUE_PAGE_MARKED(page, obj) MARKED_IN_BITMAP((page)->mark_bits, (obj))
-#if USE_RGENGC
#define RVALUE_WB_UNPROTECTED_BITMAP(obj) MARKED_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), (obj))
#define RVALUE_UNCOLLECTIBLE_BITMAP(obj) MARKED_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS(obj), (obj))
#define RVALUE_MARKING_BITMAP(obj) MARKED_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), (obj))
@@ -1046,6 +1233,7 @@ tick(void)
#define RVALUE_AGE_SHIFT 5 /* FL_PROMOTED0 bit */
static int rgengc_remembered(rb_objspace_t *objspace, VALUE obj);
+static int rgengc_remembered_sweep(rb_objspace_t *objspace, VALUE obj);
static int rgengc_remember(rb_objspace_t *objspace, VALUE obj);
static void rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap);
static void rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap);
@@ -1056,8 +1244,107 @@ RVALUE_FLAGS_AGE(VALUE flags)
return (int)((flags & (FL_PROMOTED0 | FL_PROMOTED1)) >> RVALUE_AGE_SHIFT);
}
-#endif /* USE_RGENGC */
+static int
+check_rvalue_consistency_force(const VALUE obj, int terminate)
+{
+ int err = 0;
+ rb_objspace_t *objspace = &rb_objspace;
+ RB_VM_LOCK_ENTER_NO_BARRIER();
+ {
+ if (SPECIAL_CONST_P(obj)) {
+ fprintf(stderr, "check_rvalue_consistency: %p is a special const.\n", (void *)obj);
+ err++;
+ }
+ else if (!is_pointer_to_heap(objspace, (void *)obj)) {
+ /* check if it is in tomb_pages */
+ struct heap_page *page = NULL;
+ list_for_each(&heap_tomb->pages, page, page_node) {
+ if (&page->start[0] <= (RVALUE *)obj &&
+ (RVALUE *)obj < &page->start[page->total_slots]) {
+ fprintf(stderr, "check_rvalue_consistency: %p is in a tomb_heap (%p).\n",
+ (void *)obj, (void *)page);
+ err++;
+ goto skip;
+ }
+ }
+ bp();
+ fprintf(stderr, "check_rvalue_consistency: %p is not a Ruby object.\n", (void *)obj);
+ err++;
+ skip:
+ ;
+ }
+ else {
+ const int wb_unprotected_bit = RVALUE_WB_UNPROTECTED_BITMAP(obj) != 0;
+ const int uncollectible_bit = RVALUE_UNCOLLECTIBLE_BITMAP(obj) != 0;
+ const int mark_bit = RVALUE_MARK_BITMAP(obj) != 0;
+ const int marking_bit = RVALUE_MARKING_BITMAP(obj) != 0, remembered_bit = marking_bit;
+ const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
+
+ if (GET_HEAP_PAGE(obj)->flags.in_tomb) {
+ fprintf(stderr, "check_rvalue_consistency: %s is in tomb page.\n", obj_info(obj));
+ err++;
+ }
+ if (BUILTIN_TYPE(obj) == T_NONE) {
+ fprintf(stderr, "check_rvalue_consistency: %s is T_NONE.\n", obj_info(obj));
+ err++;
+ }
+ if (BUILTIN_TYPE(obj) == T_ZOMBIE) {
+ fprintf(stderr, "check_rvalue_consistency: %s is T_ZOMBIE.\n", obj_info(obj));
+ err++;
+ }
+
+ obj_memsize_of((VALUE)obj, FALSE);
+
+ /* check generation
+ *
+ * OLD == age == 3 && old-bitmap && mark-bit (except incremental marking)
+ */
+ if (age > 0 && wb_unprotected_bit) {
+ fprintf(stderr, "check_rvalue_consistency: %s is not WB protected, but age is %d > 0.\n", obj_info(obj), age);
+ err++;
+ }
+
+ if (!is_marking(objspace) && uncollectible_bit && !mark_bit) {
+ fprintf(stderr, "check_rvalue_consistency: %s is uncollectible, but is not marked while !gc.\n", obj_info(obj));
+ err++;
+ }
+
+ if (!is_full_marking(objspace)) {
+ if (uncollectible_bit && age != RVALUE_OLD_AGE && !wb_unprotected_bit) {
+ fprintf(stderr, "check_rvalue_consistency: %s is uncollectible, but not old (age: %d) and not WB unprotected.\n",
+ obj_info(obj), age);
+ err++;
+ }
+ if (remembered_bit && age != RVALUE_OLD_AGE) {
+ fprintf(stderr, "check_rvalue_consistency: %s is remembered, but not old (age: %d).\n",
+ obj_info(obj), age);
+ err++;
+ }
+ }
+
+ /*
+ * check coloring
+ *
+ * marking:false marking:true
+ * marked:false white *invalid*
+ * marked:true black grey
+ */
+ if (is_incremental_marking(objspace) && marking_bit) {
+ if (!is_marking(objspace) && !mark_bit) {
+ fprintf(stderr, "check_rvalue_consistency: %s is marking, but not marked.\n", obj_info(obj));
+ err++;
+ }
+ }
+ }
+ }
+ RB_VM_LOCK_LEAVE_NO_BARRIER();
+
+ if (err > 0 && terminate) {
+ rb_bug("check_rvalue_consistency_force: there is %d errors.", err);
+ }
+ return err;
+}
#if RGENGC_CHECK_MODE == 0
static inline VALUE
@@ -1069,60 +1356,30 @@ check_rvalue_consistency(const VALUE obj)
static VALUE
check_rvalue_consistency(const VALUE obj)
{
- rb_objspace_t *objspace = &rb_objspace;
+ check_rvalue_consistency_force(obj, TRUE);
+ return obj;
+}
+#endif
- if (SPECIAL_CONST_P(obj)) {
- rb_bug("check_rvalue_consistency: %p is a special const.", (void *)obj);
- }
- else if (!is_pointer_to_heap(objspace, (void *)obj)) {
- rb_bug("check_rvalue_consistency: %p is not a Ruby object.", (void *)obj);
+static inline int
+gc_object_moved_p(rb_objspace_t * objspace, VALUE obj)
+{
+ if (RB_SPECIAL_CONST_P(obj)) {
+ return FALSE;
}
else {
- const int wb_unprotected_bit = RVALUE_WB_UNPROTECTED_BITMAP(obj) != 0;
- const int uncollectible_bit = RVALUE_UNCOLLECTIBLE_BITMAP(obj) != 0;
- const int mark_bit = RVALUE_MARK_BITMAP(obj) != 0;
- const int marking_bit = RVALUE_MARKING_BITMAP(obj) != 0, remembered_bit = marking_bit;
- const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
-
- if (BUILTIN_TYPE(obj) == T_NONE) rb_bug("check_rvalue_consistency: %s is T_NONE", obj_info(obj));
- if (BUILTIN_TYPE(obj) == T_ZOMBIE) rb_bug("check_rvalue_consistency: %s is T_ZOMBIE", obj_info(obj));
- obj_memsize_of((VALUE)obj, FALSE);
-
- /* check generation
- *
- * OLD == age == 3 && old-bitmap && mark-bit (except incremental marking)
- */
- if (age > 0 && wb_unprotected_bit) {
- rb_bug("check_rvalue_consistency: %s is not WB protected, but age is %d > 0.", obj_info(obj), age);
- }
-
- if (!is_marking(objspace) && uncollectible_bit && !mark_bit) {
- rb_bug("check_rvalue_consistency: %s is uncollectible, but is not marked while !gc.", obj_info(obj));
- }
-
- if (!is_full_marking(objspace)) {
- if (uncollectible_bit && age != RVALUE_OLD_AGE && !wb_unprotected_bit) {
- rb_bug("check_rvalue_consistency: %s is uncollectible, but not old (age: %d) and not WB unprotected.", obj_info(obj), age);
- }
- if (remembered_bit && age != RVALUE_OLD_AGE) {
- rb_bug("check_rvalue_consistency: %s is rememberd, but not old (age: %d).", obj_info(obj), age);
- }
- }
-
- /*
- * check coloring
- *
- * marking:false marking:true
- * marked:false white *invalid*
- * marked:true black grey
- */
- if (is_incremental_marking(objspace) && marking_bit) {
- if (!is_marking(objspace) && !mark_bit) rb_bug("check_rvalue_consistency: %s is marking, but not marked.", obj_info(obj));
- }
+ void *poisoned = asan_poisoned_object_p(obj);
+ asan_unpoison_object(obj, false);
+
+ int ret = BUILTIN_TYPE(obj) == T_MOVED;
+ /* Re-poison slot if it's not the one we want */
+ if (poisoned) {
+ GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE);
+ asan_poison_object(obj);
+ }
+ return ret;
}
- return obj;
}
-#endif
static inline int
RVALUE_MARKED(VALUE obj)
@@ -1131,7 +1388,13 @@ RVALUE_MARKED(VALUE obj)
return RVALUE_MARK_BITMAP(obj) != 0;
}
-#if USE_RGENGC
+static inline int
+RVALUE_PINNED(VALUE obj)
+{
+ check_rvalue_consistency(obj);
+ return RVALUE_PIN_BITMAP(obj) != 0;
+}
+
static inline int
RVALUE_WB_UNPROTECTED(VALUE obj)
{
@@ -1188,6 +1451,7 @@ RVALUE_PAGE_OLD_UNCOLLECTIBLE_SET(rb_objspace_t *objspace, struct heap_page *pag
{
MARK_IN_BITMAP(&page->uncollectible_bits[0], obj);
objspace->rgengc.old_objects++;
+ rb_transient_heap_promote(obj);
#if RGENGC_PROFILE >= 2
objspace->profile.total_promoted_count++;
@@ -1198,6 +1462,7 @@ RVALUE_PAGE_OLD_UNCOLLECTIBLE_SET(rb_objspace_t *objspace, struct heap_page *pag
static inline void
RVALUE_OLD_UNCOLLECTIBLE_SET(rb_objspace_t *objspace, VALUE obj)
{
+ RB_DEBUG_COUNTER_INC(obj_promote);
RVALUE_PAGE_OLD_UNCOLLECTIBLE_SET(objspace, GET_HEAP_PAGE(obj), obj);
}
@@ -1316,21 +1581,24 @@ RVALUE_WHITE_P(VALUE obj)
return RVALUE_MARKED(obj) == FALSE;
}
-#endif /* USE_RGENGC */
-
/*
--------------------------- ObjectSpace -----------------------------
*/
+static inline void *
+calloc1(size_t n)
+{
+ return calloc(1, n);
+}
+
rb_objspace_t *
rb_objspace_alloc(void)
{
-#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
- rb_objspace_t *objspace = calloc(1, sizeof(rb_objspace_t));
-#else
- rb_objspace_t *objspace = &rb_objspace;
-#endif
+ rb_objspace_t *objspace = calloc1(sizeof(rb_objspace_t));
malloc_limit = gc_params.malloc_limit_min;
+ list_head_init(&objspace->eden_heap.pages);
+ list_head_init(&objspace->tomb_heap.pages);
+ dont_gc_on();
return objspace;
}
@@ -1369,12 +1637,10 @@ rb_objspace_free(rb_objspace_t *objspace)
objspace->eden_heap.total_pages = 0;
objspace->eden_heap.total_slots = 0;
- objspace->eden_heap.pages = NULL;
}
+ st_free_table(objspace->id_to_obj_tbl);
+ st_free_table(objspace->obj_to_id_tbl);
free_stack_chunks(&objspace->mark_stack);
-#if !(defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE)
- if (objspace == &rb_objspace) return;
-#endif
free(objspace);
}
@@ -1382,9 +1648,10 @@ static void
heap_pages_expand_sorted_to(rb_objspace_t *objspace, size_t next_length)
{
struct heap_page **sorted;
- size_t size = next_length * sizeof(struct heap_page *);
+ size_t size = size_mul_or_raise(next_length, sizeof(struct heap_page *), rb_eRuntimeError);
- gc_report(3, objspace, "heap_pages_expand_sorted: next_length: %d, size: %d\n", (int)next_length, (int)size);
+ gc_report(3, objspace, "heap_pages_expand_sorted: next_length: %"PRIdSIZE", size: %"PRIdSIZE"\n",
+ next_length, size);
if (heap_pages_sorted_length > 0) {
sorted = (struct heap_page **)realloc(heap_pages_sorted, size);
@@ -1405,8 +1672,8 @@ static void
heap_pages_expand_sorted(rb_objspace_t *objspace)
{
/* usually heap_allocatable_pages + heap_eden->total_pages == heap_pages_sorted_length
- * beacuse heap_allocatable_pages contains heap_tomb->total_pages (recycle heap_tomb pages).
- * howerver, if there are pages which do not have empty slots, then try to create new pages
+ * because heap_allocatable_pages contains heap_tomb->total_pages (recycle heap_tomb pages).
+ * however, if there are pages which do not have empty slots, then try to create new pages
* so that the additional allocatable_pages counts (heap_tomb->total_pages) are added.
*/
size_t next_length = heap_allocatable_pages;
@@ -1428,65 +1695,79 @@ heap_allocatable_pages_set(rb_objspace_t *objspace, size_t s)
heap_pages_expand_sorted(objspace);
}
-
static inline void
heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj)
{
+ ASSERT_vm_locking();
+
RVALUE *p = (RVALUE *)obj;
+
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
+
p->as.free.flags = 0;
p->as.free.next = page->freelist;
page->freelist = p;
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
- if (RGENGC_CHECK_MODE && !is_pointer_to_heap(objspace, p)) {
- rb_bug("heap_page_add_freeobj: %p is not rvalue.", p);
+ if (RGENGC_CHECK_MODE &&
+ /* obj should belong to page */
+ !(&page->start[0] <= (RVALUE *)obj &&
+ (RVALUE *)obj < &page->start[page->total_slots] &&
+ obj % sizeof(RVALUE) == 0)) {
+ rb_bug("heap_page_add_freeobj: %p is not rvalue.", (void *)p);
}
+ asan_poison_object(obj);
gc_report(3, objspace, "heap_page_add_freeobj: add %p to freelist\n", (void *)obj);
}
static inline void
-heap_add_freepage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
+heap_add_freepage(rb_heap_t *heap, struct heap_page *page)
{
- if (page->freelist) {
- page->free_next = heap->free_pages;
- heap->free_pages = page;
- }
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
+ GC_ASSERT(page->free_slots != 0);
+ GC_ASSERT(page->freelist != NULL);
+
+ page->free_next = heap->free_pages;
+ heap->free_pages = page;
+
+ RUBY_DEBUG_LOG("page:%p freelist:%p", page, page->freelist);
+
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
}
#if GC_ENABLE_INCREMENTAL_MARK
-static inline int
+static inline void
heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
{
- if (page->freelist) {
- page->free_next = heap->pooled_pages;
- heap->pooled_pages = page;
- objspace->rincgc.pooled_slots += page->free_slots;
- return TRUE;
- }
- else {
- return FALSE;
- }
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
+ GC_ASSERT(page->free_slots != 0);
+ GC_ASSERT(page->freelist != NULL);
+
+ page->free_next = heap->pooled_pages;
+ heap->pooled_pages = page;
+ objspace->rincgc.pooled_slots += page->free_slots;
+
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
}
#endif
static void
heap_unlink_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
{
- if (page->prev) page->prev->next = page->next;
- if (page->next) page->next->prev = page->prev;
- if (heap->pages == page) heap->pages = page->next;
- page->prev = NULL;
- page->next = NULL;
+ list_del(&page->page_node);
heap->total_pages--;
heap->total_slots -= page->total_slots;
}
+static void rb_aligned_free(void *ptr);
+
static void
heap_page_free(rb_objspace_t *objspace, struct heap_page *page)
{
heap_allocated_pages--;
objspace->profile.total_freed_pages++;
- aligned_free(GET_PAGE_BODY(page->start));
+ rb_aligned_free(GET_PAGE_BODY(page->start));
free(page);
}
@@ -1495,7 +1776,7 @@ heap_pages_free_unused_pages(rb_objspace_t *objspace)
{
size_t i, j;
- if (heap_tomb->pages) {
+ if (!list_empty(&heap_tomb->pages)) {
for (i = j = 1; j < heap_allocated_pages; i++) {
struct heap_page *page = heap_pages_sorted[i];
@@ -1510,6 +1791,12 @@ heap_pages_free_unused_pages(rb_objspace_t *objspace)
j++;
}
}
+
+ struct heap_page *hipage = heap_pages_sorted[heap_allocated_pages - 1];
+ RVALUE *himem = hipage->start + hipage->total_slots;
+ GC_ASSERT(himem <= heap_pages_himem);
+ heap_pages_himem = himem;
+
GC_ASSERT(j == heap_allocated_pages);
}
}
@@ -1524,15 +1811,15 @@ heap_page_allocate(rb_objspace_t *objspace)
int limit = HEAP_PAGE_OBJ_LIMIT;
/* assign heap_page body (contains heap_page_header and RVALUEs) */
- page_body = (struct heap_page_body *)aligned_malloc(HEAP_PAGE_ALIGN, HEAP_PAGE_SIZE);
+ page_body = (struct heap_page_body *)rb_aligned_malloc(HEAP_PAGE_ALIGN, HEAP_PAGE_SIZE);
if (page_body == 0) {
rb_memerror();
}
/* assign heap_page entry */
- page = (struct heap_page *)calloc(1, sizeof(struct heap_page));
+ page = calloc1(sizeof(struct heap_page));
if (page == 0) {
- aligned_free(page_body);
+ rb_aligned_free(page_body);
rb_memerror();
}
@@ -1591,29 +1878,29 @@ heap_page_allocate(rb_objspace_t *objspace)
page_body->header.page = page;
for (p = start; p != end; p++) {
- gc_report(3, objspace, "assign_heap_page: %p is added to freelist\n", p);
+ gc_report(3, objspace, "assign_heap_page: %p is added to freelist\n", (void *)p);
heap_page_add_freeobj(objspace, page, (VALUE)p);
}
page->free_slots = limit;
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
return page;
}
static struct heap_page *
heap_page_resurrect(rb_objspace_t *objspace)
{
- struct heap_page *page = heap_tomb->pages;
+ struct heap_page *page = 0, *next;
- while (page) {
+ list_for_each_safe(&heap_tomb->pages, page, next, page_node) {
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
if (page->freelist != NULL) {
heap_unlink_page(objspace, heap_tomb, page);
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
return page;
}
- page = page->next;
}
-
-
return NULL;
}
@@ -1631,18 +1918,21 @@ heap_page_create(rb_objspace_t *objspace)
page = heap_page_allocate(objspace);
method = "allocate";
}
- if (0) fprintf(stderr, "heap_page_create: %s - %p, heap_allocated_pages: %d, heap_allocated_pages: %d, tomb->total_pages: %d\n",
- method, page, (int)heap_pages_sorted_length, (int)heap_allocated_pages, (int)heap_tomb->total_pages);
+ if (0) fprintf(stderr, "heap_page_create: %s - %p, "
+ "heap_allocated_pages: %"PRIdSIZE", "
+ "heap_allocated_pages: %"PRIdSIZE", "
+ "tomb->total_pages: %"PRIdSIZE"\n",
+ method, (void *)page, heap_pages_sorted_length, heap_allocated_pages, heap_tomb->total_pages);
return page;
}
static void
heap_add_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
{
+ /* Adding to eden heap during incremental sweeping is forbidden */
+ GC_ASSERT(!(heap == heap_eden && heap->sweeping_page));
page->flags.in_tomb = (heap == heap_tomb);
- page->next = heap->pages;
- if (heap->pages) heap->pages->prev = page;
- heap->pages = page;
+ list_add_tail(&heap->pages, &page->page_node);
heap->total_pages++;
heap->total_slots += page->total_slots;
}
@@ -1652,7 +1942,7 @@ heap_assign_page(rb_objspace_t *objspace, rb_heap_t *heap)
{
struct heap_page *page = heap_page_create(objspace);
heap_add_page(objspace, heap, page);
- heap_add_freepage(objspace, heap, page);
+ heap_add_freepage(heap, page);
}
static void
@@ -1718,15 +2008,17 @@ heap_set_increment(rb_objspace_t *objspace, size_t additional_pages)
heap_allocatable_pages_set(objspace, next_used_limit - used);
- gc_report(1, objspace, "heap_set_increment: heap_allocatable_pages is %d\n", (int)heap_allocatable_pages);
+ gc_report(1, objspace, "heap_set_increment: heap_allocatable_pages is %"PRIdSIZE"\n",
+ heap_allocatable_pages);
}
static int
heap_increment(rb_objspace_t *objspace, rb_heap_t *heap)
{
if (heap_allocatable_pages > 0) {
- gc_report(1, objspace, "heap_increment: heap_pages_sorted_length: %d, heap_pages_inc: %d, heap->total_pages: %d\n",
- (int)heap_pages_sorted_length, (int)heap_allocatable_pages, (int)heap->total_pages);
+ gc_report(1, objspace, "heap_increment: heap_pages_sorted_length: %"PRIdSIZE", "
+ "heap_pages_inc: %"PRIdSIZE", heap->total_pages: %"PRIdSIZE"\n",
+ heap_pages_sorted_length, heap_allocatable_pages, heap->total_pages);
GC_ASSERT(heap_allocatable_pages + heap_eden->total_pages <= heap_pages_sorted_length);
GC_ASSERT(heap_allocated_pages <= heap_pages_sorted_length);
@@ -1742,70 +2034,20 @@ heap_prepare(rb_objspace_t *objspace, rb_heap_t *heap)
{
GC_ASSERT(heap->free_pages == NULL);
-#if GC_ENABLE_LAZY_SWEEP
if (is_lazy_sweeping(heap)) {
gc_sweep_continue(objspace, heap);
}
-#endif
-#if GC_ENABLE_INCREMENTAL_MARK
else if (is_incremental_marking(objspace)) {
gc_marks_continue(objspace, heap);
}
-#endif
if (heap->free_pages == NULL &&
(will_be_incremental_marking(objspace) || heap_increment(objspace, heap) == FALSE) &&
- gc_start(objspace, FALSE, FALSE, FALSE, GPR_FLAG_NEWOBJ) == FALSE) {
+ gc_start(objspace, GPR_FLAG_NEWOBJ) == FALSE) {
rb_memerror();
}
}
-static RVALUE *
-heap_get_freeobj_from_next_freepage(rb_objspace_t *objspace, rb_heap_t *heap)
-{
- struct heap_page *page;
- RVALUE *p;
-
- while (heap->free_pages == NULL) {
- heap_prepare(objspace, heap);
- }
- page = heap->free_pages;
- heap->free_pages = page->free_next;
- heap->using_page = page;
-
- GC_ASSERT(page->free_slots != 0);
- p = page->freelist;
- page->freelist = NULL;
- page->free_slots = 0;
- return p;
-}
-
-static inline VALUE
-heap_get_freeobj_head(rb_objspace_t *objspace, rb_heap_t *heap)
-{
- RVALUE *p = heap->freelist;
- if (LIKELY(p != NULL)) {
- heap->freelist = p->as.free.next;
- }
- return (VALUE)p;
-}
-
-static inline VALUE
-heap_get_freeobj(rb_objspace_t *objspace, rb_heap_t *heap)
-{
- RVALUE *p = heap->freelist;
-
- while (1) {
- if (LIKELY(p != NULL)) {
- heap->freelist = p->as.free.next;
- return (VALUE)p;
- }
- else {
- p = heap_get_freeobj_from_next_freepage(objspace, heap);
- }
- }
-}
-
void
rb_objspace_set_event_hook(const rb_event_flag_t event)
{
@@ -1815,166 +2057,285 @@ rb_objspace_set_event_hook(const rb_event_flag_t event)
}
static void
-gc_event_hook_body(rb_thread_t *th, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data)
+gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data)
{
- EXEC_EVENT_HOOK(th, event, th->ec.cfp->self, 0, 0, 0, data);
+ const VALUE *pc = ec->cfp->pc;
+ if (pc && VM_FRAME_RUBYFRAME_P(ec->cfp)) {
+ /* increment PC because source line is calculated with PC-1 */
+ ec->cfp->pc++;
+ }
+ EXEC_EVENT_HOOK(ec, event, ec->cfp->self, 0, 0, 0, data);
+ ec->cfp->pc = pc;
}
#define gc_event_hook_available_p(objspace) ((objspace)->flags.has_hook)
#define gc_event_hook_needed_p(objspace, event) ((objspace)->hook_events & (event))
-#define gc_event_hook(objspace, event, data) do { \
+#define gc_event_hook_prep(objspace, event, data, prep) do { \
if (UNLIKELY(gc_event_hook_needed_p(objspace, event))) { \
- gc_event_hook_body(GET_THREAD(), (objspace), (event), (data)); \
+ prep; \
+ gc_event_hook_body(GET_EC(), (objspace), (event), (data)); \
} \
} while (0)
+#define gc_event_hook(objspace, event, data) gc_event_hook_prep(objspace, event, data, (void)0)
+
static inline VALUE
-newobj_init(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected, rb_objspace_t *objspace, VALUE obj)
+newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace, VALUE obj)
{
+#if !__has_feature(memory_sanitizer)
GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE);
GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
+#endif
+ RVALUE *p = RANY(obj);
+ p->as.basic.flags = flags;
+ *((VALUE *)&p->as.basic.klass) = klass;
- /* OBJSETUP */
- RBASIC(obj)->flags = flags;
- RBASIC_SET_CLASS_RAW(obj, klass);
- RANY(obj)->as.values.v1 = v1;
- RANY(obj)->as.values.v2 = v2;
- RANY(obj)->as.values.v3 = v3;
+#if RACTOR_CHECK_MODE
+ rb_ractor_setup_belonging(obj);
+#endif
#if RGENGC_CHECK_MODE
- GC_ASSERT(RVALUE_MARKED(obj) == FALSE);
- GC_ASSERT(RVALUE_MARKING(obj) == FALSE);
- GC_ASSERT(RVALUE_OLD_P(obj) == FALSE);
- GC_ASSERT(RVALUE_WB_UNPROTECTED(obj) == FALSE);
+ p->as.values.v1 = p->as.values.v2 = p->as.values.v3 = 0;
- if (flags & FL_PROMOTED1) {
- if (RVALUE_AGE(obj) != 2) rb_bug("newobj: %s of age (%d) != 2.", obj_info(obj), RVALUE_AGE(obj));
- }
- else {
- if (RVALUE_AGE(obj) > 0) rb_bug("newobj: %s of age (%d) > 0.", obj_info(obj), RVALUE_AGE(obj));
+ RB_VM_LOCK_ENTER_NO_BARRIER();
+ {
+ check_rvalue_consistency(obj);
+
+ GC_ASSERT(RVALUE_MARKED(obj) == FALSE);
+ GC_ASSERT(RVALUE_MARKING(obj) == FALSE);
+ GC_ASSERT(RVALUE_OLD_P(obj) == FALSE);
+ GC_ASSERT(RVALUE_WB_UNPROTECTED(obj) == FALSE);
+
+ if (flags & FL_PROMOTED1) {
+ if (RVALUE_AGE(obj) != 2) rb_bug("newobj: %s of age (%d) != 2.", obj_info(obj), RVALUE_AGE(obj));
+ }
+ else {
+ if (RVALUE_AGE(obj) > 0) rb_bug("newobj: %s of age (%d) > 0.", obj_info(obj), RVALUE_AGE(obj));
+ }
+ if (rgengc_remembered(objspace, (VALUE)obj)) rb_bug("newobj: %s is remembered.", obj_info(obj));
}
- if (rgengc_remembered(objspace, (VALUE)obj)) rb_bug("newobj: %s is remembered.", obj_info(obj));
+ RB_VM_LOCK_LEAVE_NO_BARRIER();
#endif
-#if USE_RGENGC
if (UNLIKELY(wb_protected == FALSE)) {
- MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
+ ASSERT_vm_locking();
+ MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
}
-#endif
+
+ // TODO: make it atomic, or ractor local
+ objspace->total_allocated_objects++;
#if RGENGC_PROFILE
if (wb_protected) {
- objspace->profile.total_generated_normal_object_count++;
+ objspace->profile.total_generated_normal_object_count++;
#if RGENGC_PROFILE >= 2
- objspace->profile.generated_normal_object_count_types[BUILTIN_TYPE(obj)]++;
+ objspace->profile.generated_normal_object_count_types[BUILTIN_TYPE(obj)]++;
#endif
}
else {
- objspace->profile.total_generated_shady_object_count++;
+ objspace->profile.total_generated_shady_object_count++;
#if RGENGC_PROFILE >= 2
- objspace->profile.generated_shady_object_count_types[BUILTIN_TYPE(obj)]++;
+ objspace->profile.generated_shady_object_count_types[BUILTIN_TYPE(obj)]++;
#endif
}
#endif
#if GC_DEBUG
- RANY(obj)->file = rb_source_loc(&RANY(obj)->line);
+ RANY(obj)->file = rb_source_location_cstr(&RANY(obj)->line);
GC_ASSERT(!SPECIAL_CONST_P(obj)); /* check alignment */
#endif
- objspace->total_allocated_objects++;
-
gc_report(5, objspace, "newobj: %s\n", obj_info(obj));
#if RGENGC_OLD_NEWOBJ_CHECK > 0
{
- static int newobj_cnt = RGENGC_OLD_NEWOBJ_CHECK;
+ static int newobj_cnt = RGENGC_OLD_NEWOBJ_CHECK;
- if (!is_incremental_marking(objspace) &&
- flags & FL_WB_PROTECTED && /* do not promote WB unprotected objects */
- ! RB_TYPE_P(obj, T_ARRAY)) { /* array.c assumes that allocated objects are new */
- if (--newobj_cnt == 0) {
- newobj_cnt = RGENGC_OLD_NEWOBJ_CHECK;
+ if (!is_incremental_marking(objspace) &&
+ flags & FL_WB_PROTECTED && /* do not promote WB unprotected objects */
+ ! RB_TYPE_P(obj, T_ARRAY)) { /* array.c assumes that allocated objects are new */
+ if (--newobj_cnt == 0) {
+ newobj_cnt = RGENGC_OLD_NEWOBJ_CHECK;
- gc_mark_set(objspace, obj);
- RVALUE_AGE_SET_OLD(objspace, obj);
+ gc_mark_set(objspace, obj);
+ RVALUE_AGE_SET_OLD(objspace, obj);
- rb_gc_writebarrier_remember(obj);
- }
- }
+ rb_gc_writebarrier_remember(obj);
+ }
+ }
}
#endif
- check_rvalue_consistency(obj);
+ // RUBY_DEBUG_LOG("obj:%p (%s)", (void *)obj, obj_type_name(obj));
+ return obj;
+}
+
+static inline VALUE
+ractor_cached_freeobj(rb_objspace_t *objspace, rb_ractor_t *cr)
+{
+ RVALUE *p = cr->newobj_cache.freelist;
+
+ if (p) {
+ VALUE obj = (VALUE)p;
+ cr->newobj_cache.freelist = p->as.free.next;
+ asan_unpoison_object(obj, true);
+ return obj;
+ }
+ else {
+ return Qfalse;
+ }
+}
+
+static struct heap_page *
+heap_next_freepage(rb_objspace_t *objspace, rb_heap_t *heap)
+{
+ ASSERT_vm_locking();
+
+ struct heap_page *page;
+
+ while (heap->free_pages == NULL) {
+ heap_prepare(objspace, heap);
+ }
+ page = heap->free_pages;
+ heap->free_pages = page->free_next;
+
+ GC_ASSERT(page->free_slots != 0);
+ RUBY_DEBUG_LOG("page:%p freelist:%p cnt:%d", page, page->freelist, page->free_slots);
+
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
+
+ return page;
+}
+
+static inline void
+ractor_cache_slots(rb_objspace_t *objspace, rb_ractor_t *cr)
+{
+ ASSERT_vm_locking();
+ GC_ASSERT(cr->newobj_cache.freelist == NULL);
+
+ struct heap_page *page = heap_next_freepage(objspace, heap_eden);
+
+ cr->newobj_cache.using_page = page;
+ cr->newobj_cache.freelist = page->freelist;
+ page->free_slots = 0;
+ page->freelist = NULL;
+
+ GC_ASSERT(RB_TYPE_P((VALUE)cr->newobj_cache.freelist, T_NONE));
+}
+
+static inline VALUE
+newobj_fill(VALUE obj, VALUE v1, VALUE v2, VALUE v3)
+{
+ RVALUE *p = (RVALUE *)obj;
+ p->as.values.v1 = v1;
+ p->as.values.v2 = v2;
+ p->as.values.v3 = v3;
return obj;
}
+ALWAYS_INLINE(static VALUE newobj_slowpath(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_t *cr, int wb_protected));
+
static inline VALUE
-newobj_slowpath(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace, int wb_protected)
+newobj_slowpath(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_t *cr, int wb_protected)
{
VALUE obj;
+ unsigned int lev;
- if (UNLIKELY(during_gc || ruby_gc_stressful)) {
- if (during_gc) {
- dont_gc = 1;
- during_gc = 0;
- rb_bug("object allocation during garbage collection phase");
- }
+ RB_VM_LOCK_ENTER_CR_LEV(cr, &lev);
+ {
+ if (UNLIKELY(during_gc || ruby_gc_stressful)) {
+ if (during_gc) {
+ dont_gc_on();
+ during_gc = 0;
+ rb_bug("object allocation during garbage collection phase");
+ }
- if (ruby_gc_stressful) {
- if (!garbage_collect(objspace, FALSE, FALSE, FALSE, GPR_FLAG_NEWOBJ)) {
- rb_memerror();
- }
- }
+ if (ruby_gc_stressful) {
+ if (!garbage_collect(objspace, GPR_FLAG_NEWOBJ)) {
+ rb_memerror();
+ }
+ }
+ }
+
+ // allocate new slot
+ while ((obj = ractor_cached_freeobj(objspace, cr)) == Qfalse) {
+ ractor_cache_slots(objspace, cr);
+ }
+ GC_ASSERT(obj != 0);
+ newobj_init(klass, flags, wb_protected, objspace, obj);
+ gc_event_hook_prep(objspace, RUBY_INTERNAL_EVENT_NEWOBJ, obj, newobj_fill(obj, 0, 0, 0));
}
+ RB_VM_LOCK_LEAVE_CR_LEV(cr, &lev);
- obj = heap_get_freeobj(objspace, heap_eden);
- newobj_init(klass, flags, v1, v2, v3, wb_protected, objspace, obj);
- gc_event_hook(objspace, RUBY_INTERNAL_EVENT_NEWOBJ, obj);
return obj;
}
-NOINLINE(static VALUE newobj_slowpath_wb_protected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace));
-NOINLINE(static VALUE newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace));
+NOINLINE(static VALUE newobj_slowpath_wb_protected(VALUE klass, VALUE flags,
+ rb_objspace_t *objspace, rb_ractor_t *cr));
+NOINLINE(static VALUE newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags,
+ rb_objspace_t *objspace, rb_ractor_t *cr));
static VALUE
-newobj_slowpath_wb_protected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace)
+newobj_slowpath_wb_protected(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_t *cr)
{
- return newobj_slowpath(klass, flags, v1, v2, v3, objspace, TRUE);
+ return newobj_slowpath(klass, flags, objspace, cr, TRUE);
}
static VALUE
-newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace)
+newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_t *cr)
{
- return newobj_slowpath(klass, flags, v1, v2, v3, objspace, FALSE);
+ return newobj_slowpath(klass, flags, objspace, cr, FALSE);
}
static inline VALUE
-newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected)
+newobj_of0(VALUE klass, VALUE flags, int wb_protected, rb_ractor_t *cr)
{
- rb_objspace_t *objspace = &rb_objspace;
VALUE obj;
+ rb_objspace_t *objspace = &rb_objspace;
+
+ RB_DEBUG_COUNTER_INC(obj_newobj);
+ (void)RB_DEBUG_COUNTER_INC_IF(obj_newobj_wb_unprotected, !wb_protected);
#if GC_DEBUG_STRESS_TO_CLASS
if (UNLIKELY(stress_to_class)) {
- long i, cnt = RARRAY_LEN(stress_to_class);
- const VALUE *ptr = RARRAY_CONST_PTR(stress_to_class);
- for (i = 0; i < cnt; ++i) {
- if (klass == ptr[i]) rb_memerror();
- }
+ long i, cnt = RARRAY_LEN(stress_to_class);
+ for (i = 0; i < cnt; ++i) {
+ if (klass == RARRAY_AREF(stress_to_class, i)) rb_memerror();
+ }
}
#endif
- if (!(during_gc ||
- ruby_gc_stressful ||
- gc_event_hook_available_p(objspace)) &&
- (obj = heap_get_freeobj_head(objspace, heap_eden)) != Qfalse) {
- return newobj_init(klass, flags, v1, v2, v3, wb_protected, objspace, obj);
+
+ if ((!UNLIKELY(during_gc ||
+ ruby_gc_stressful ||
+ gc_event_hook_available_p(objspace)) &&
+ wb_protected &&
+ (obj = ractor_cached_freeobj(objspace, cr)) != Qfalse)) {
+
+ newobj_init(klass, flags, wb_protected, objspace, obj);
}
else {
- return wb_protected ?
- newobj_slowpath_wb_protected(klass, flags, v1, v2, v3, objspace) :
- newobj_slowpath_wb_unprotected(klass, flags, v1, v2, v3, objspace);
+ RB_DEBUG_COUNTER_INC(obj_newobj_slowpath);
+
+ obj = wb_protected ?
+ newobj_slowpath_wb_protected(klass, flags, objspace, cr) :
+ newobj_slowpath_wb_unprotected(klass, flags, objspace, cr);
}
+
+ return obj;
+}
+
+static inline VALUE
+newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected)
+{
+ VALUE obj = newobj_of0(klass, flags, wb_protected, GET_RACTOR());
+ return newobj_fill(obj, v1, v2, v3);
+}
+
+static inline VALUE
+newobj_of_cr(rb_ractor_t *cr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected)
+{
+ VALUE obj = newobj_of0(klass, flags, wb_protected, cr);
+ return newobj_fill(obj, v1, v2, v3);
}
VALUE
@@ -1991,6 +2352,13 @@ rb_wb_protected_newobj_of(VALUE klass, VALUE flags)
return newobj_of(klass, flags, 0, 0, 0, TRUE);
}
+VALUE
+rb_ec_wb_protected_newobj_of(rb_execution_context_t *ec, VALUE klass, VALUE flags)
+{
+ GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
+ return newobj_of_cr(rb_ec_ractor_ptr(ec), klass, flags, 0, 0, 0, TRUE);
+}
+
/* for compatibility */
VALUE
@@ -2002,15 +2370,40 @@ rb_newobj(void)
VALUE
rb_newobj_of(VALUE klass, VALUE flags)
{
- return newobj_of(klass, flags & ~FL_WB_PROTECTED, 0, 0, 0, flags & FL_WB_PROTECTED);
+ if ((flags & RUBY_T_MASK) == T_OBJECT) {
+ return newobj_of(klass, (flags | ROBJECT_EMBED) & ~FL_WB_PROTECTED , Qundef, Qundef, Qundef, flags & FL_WB_PROTECTED);
+ } else {
+ return newobj_of(klass, flags & ~FL_WB_PROTECTED, 0, 0, 0, flags & FL_WB_PROTECTED);
+ }
}
-NODE*
-rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2)
+#define UNEXPECTED_NODE(func) \
+ rb_bug(#func"(): GC does not handle T_NODE 0x%x(%p) 0x%"PRIxVALUE, \
+ BUILTIN_TYPE(obj), (void*)(obj), RBASIC(obj)->flags)
+
+const char *
+rb_imemo_name(enum imemo_type type)
{
- NODE *n = (NODE *)newobj_of(0, T_NODE, a0, a1, a2, FALSE); /* TODO: node also should be wb protected */
- nd_set_type(n, type);
- return n;
+ // put no default case to get a warning if an imemo type is missing
+ switch (type) {
+#define IMEMO_NAME(x) case imemo_##x: return #x;
+ IMEMO_NAME(env);
+ IMEMO_NAME(cref);
+ IMEMO_NAME(svar);
+ IMEMO_NAME(throw_data);
+ IMEMO_NAME(ifunc);
+ IMEMO_NAME(memo);
+ IMEMO_NAME(ment);
+ IMEMO_NAME(iseq);
+ IMEMO_NAME(tmpbuf);
+ IMEMO_NAME(ast);
+ IMEMO_NAME(parser_strterm);
+ IMEMO_NAME(callinfo);
+ IMEMO_NAME(callcache);
+ IMEMO_NAME(constcache);
+#undef IMEMO_NAME
+ }
+ return "unknown";
}
#undef rb_imemo_new
@@ -2022,29 +2415,84 @@ rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
return newobj_of(v0, flags, v1, v2, v3, TRUE);
}
+static VALUE
+rb_imemo_tmpbuf_new(VALUE v1, VALUE v2, VALUE v3, VALUE v0)
+{
+ VALUE flags = T_IMEMO | (imemo_tmpbuf << FL_USHIFT);
+ return newobj_of(v0, flags, v1, v2, v3, FALSE);
+}
+
+static VALUE
+rb_imemo_tmpbuf_auto_free_maybe_mark_buffer(void *buf, size_t cnt)
+{
+ return rb_imemo_tmpbuf_new((VALUE)buf, 0, (VALUE)cnt, 0);
+}
+
+rb_imemo_tmpbuf_t *
+rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt)
+{
+ return (rb_imemo_tmpbuf_t *)rb_imemo_tmpbuf_new((VALUE)buf, (VALUE)old_heap, (VALUE)cnt, 0);
+}
+
+static size_t
+imemo_memsize(VALUE obj)
+{
+ size_t size = 0;
+ switch (imemo_type(obj)) {
+ case imemo_ment:
+ size += sizeof(RANY(obj)->as.imemo.ment.def);
+ break;
+ case imemo_iseq:
+ size += rb_iseq_memsize((rb_iseq_t *)obj);
+ break;
+ case imemo_env:
+ size += RANY(obj)->as.imemo.env.env_size * sizeof(VALUE);
+ break;
+ case imemo_tmpbuf:
+ size += RANY(obj)->as.imemo.alloc.cnt * sizeof(VALUE);
+ break;
+ case imemo_ast:
+ size += rb_ast_memsize(&RANY(obj)->as.imemo.ast);
+ break;
+ case imemo_cref:
+ case imemo_svar:
+ case imemo_throw_data:
+ case imemo_ifunc:
+ case imemo_memo:
+ case imemo_parser_strterm:
+ break;
+ default:
+ /* unreachable */
+ break;
+ }
+ return size;
+}
+
#if IMEMO_DEBUG
VALUE
rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, const char *file, int line)
{
VALUE memo = rb_imemo_new(type, v1, v2, v3, v0);
- fprintf(stderr, "memo %p (type: %d) @ %s:%d\n", memo, imemo_type(memo), file, line);
+ fprintf(stderr, "memo %p (type: %d) @ %s:%d\n", (void *)memo, imemo_type(memo), file, line);
return memo;
}
#endif
VALUE
+rb_class_allocate_instance(VALUE klass)
+{
+ VALUE flags = T_OBJECT | ROBJECT_EMBED;
+ return newobj_of(klass, flags, Qundef, Qundef, Qundef, RGENGC_WB_PROTECTED_OBJECT);
+}
+
+VALUE
rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
+ RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1);
if (klass) Check_Type(klass, T_CLASS);
return newobj_of(klass, T_DATA, (VALUE)dmark, (VALUE)dfree, (VALUE)datap, FALSE);
}
-#undef rb_data_object_alloc
-RUBY_ALIAS_FUNCTION(rb_data_object_alloc(VALUE klass, void *datap,
- RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree),
- rb_data_object_wrap, (klass, datap, dmark, dfree))
-
-
VALUE
rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
@@ -2056,15 +2504,11 @@ rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_
VALUE
rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type)
{
+ RUBY_ASSERT_ALWAYS(type);
if (klass) Check_Type(klass, T_CLASS);
return newobj_of(klass, T_DATA, (VALUE)type, (VALUE)1, (VALUE)datap, type->flags & RUBY_FL_WB_PROTECTED);
}
-#undef rb_data_typed_object_alloc
-RUBY_ALIAS_FUNCTION(rb_data_typed_object_alloc(VALUE klass, void *datap,
- const rb_data_type_t *type),
- rb_data_typed_object_wrap, (klass, datap, type))
-
VALUE
rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type)
{
@@ -2105,8 +2549,13 @@ is_pointer_to_heap(rb_objspace_t *objspace, void *ptr)
register struct heap_page *page;
register size_t hi, lo, mid;
+ RB_DEBUG_COUNTER_INC(gc_isptr_trial);
+
if (p < heap_pages_lomem || p > heap_pages_himem) return FALSE;
+ RB_DEBUG_COUNTER_INC(gc_isptr_range);
+
if ((VALUE)p % sizeof(RVALUE) != 0) return FALSE;
+ RB_DEBUG_COUNTER_INC(gc_isptr_align);
/* check if p looks like a pointer using bsearch*/
lo = 0;
@@ -2116,7 +2565,14 @@ is_pointer_to_heap(rb_objspace_t *objspace, void *ptr)
page = heap_pages_sorted[mid];
if (page->start <= p) {
if (p < page->start + page->total_slots) {
- return TRUE;
+ RB_DEBUG_COUNTER_INC(gc_isptr_maybe);
+
+ if (page->flags.in_tomb) {
+ return FALSE;
+ }
+ else {
+ return TRUE;
+ }
}
lo = mid + 1;
}
@@ -2142,28 +2598,182 @@ rb_free_const_table(struct rb_id_table *tbl)
rb_id_table_free(tbl);
}
+static int
+free_iv_index_tbl_free_i(st_data_t key, st_data_t value, st_data_t data)
+{
+ xfree((void *)value);
+ return ST_CONTINUE;
+}
+
+static void
+iv_index_tbl_free(struct st_table *tbl)
+{
+ st_foreach(tbl, free_iv_index_tbl_free_i, 0);
+}
+
+// alive: if false, target pointers can be freed already.
+// To check it, we need objspace parameter.
+static void
+vm_ccs_free(struct rb_class_cc_entries *ccs, int alive, rb_objspace_t *objspace, VALUE klass)
+{
+ if (ccs->entries) {
+ for (int i=0; i<ccs->len; i++) {
+ const struct rb_callcache *cc = ccs->entries[i].cc;
+ if (!alive) {
+ void *ptr = asan_poisoned_object_p((VALUE)cc);
+ asan_unpoison_object((VALUE)cc, false);
+ // ccs can be free'ed.
+ if (is_pointer_to_heap(objspace, (void *)cc) &&
+ IMEMO_TYPE_P(cc, imemo_callcache) &&
+ cc->klass == klass) {
+ // OK. maybe target cc.
+ }
+ else {
+ if (ptr) {
+ asan_poison_object((VALUE)cc);
+ }
+ continue;
+ }
+ if (ptr) {
+ asan_poison_object((VALUE)cc);
+ }
+ }
+ vm_cc_invalidate(cc);
+ }
+ ruby_xfree(ccs->entries);
+ }
+ ruby_xfree(ccs);
+}
+
+void
+rb_vm_ccs_free(struct rb_class_cc_entries *ccs)
+{
+ RB_DEBUG_COUNTER_INC(ccs_free);
+ vm_ccs_free(ccs, TRUE, NULL, Qundef);
+}
+
+struct cc_tbl_i_data {
+ rb_objspace_t *objspace;
+ VALUE klass;
+ bool alive;
+};
+
+static enum rb_id_table_iterator_result
+cc_table_mark_i(ID id, VALUE ccs_ptr, void *data_ptr)
+{
+ struct cc_tbl_i_data *data = data_ptr;
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
+ VM_ASSERT(vm_ccs_p(ccs));
+ VM_ASSERT(id == ccs->cme->called_id);
+
+ if (METHOD_ENTRY_INVALIDATED(ccs->cme)) {
+ rb_vm_ccs_free(ccs);
+ return ID_TABLE_DELETE;
+ }
+ else {
+ gc_mark(data->objspace, (VALUE)ccs->cme);
+
+ for (int i=0; i<ccs->len; i++) {
+ VM_ASSERT(data->klass == ccs->entries[i].cc->klass);
+ VM_ASSERT(ccs->cme == vm_cc_cme(ccs->entries[i].cc));
+
+ gc_mark(data->objspace, (VALUE)ccs->entries[i].ci);
+ gc_mark(data->objspace, (VALUE)ccs->entries[i].cc);
+ }
+ return ID_TABLE_CONTINUE;
+ }
+}
+
+static void
+cc_table_mark(rb_objspace_t *objspace, VALUE klass)
+{
+ struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
+ if (cc_tbl) {
+ struct cc_tbl_i_data data = {
+ .objspace = objspace,
+ .klass = klass,
+ };
+ rb_id_table_foreach(cc_tbl, cc_table_mark_i, &data);
+ }
+}
+
+static enum rb_id_table_iterator_result
+cc_table_free_i(VALUE ccs_ptr, void *data_ptr)
+{
+ struct cc_tbl_i_data *data = data_ptr;
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
+ VM_ASSERT(vm_ccs_p(ccs));
+ vm_ccs_free(ccs, data->alive, data->objspace, data->klass);
+ return ID_TABLE_CONTINUE;
+}
+
+static void
+cc_table_free(rb_objspace_t *objspace, VALUE klass, bool alive)
+{
+ struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
+
+ if (cc_tbl) {
+ struct cc_tbl_i_data data = {
+ .objspace = objspace,
+ .klass = klass,
+ .alive = alive,
+ };
+ rb_id_table_foreach_values(cc_tbl, cc_table_free_i, &data);
+ rb_id_table_free(cc_tbl);
+ }
+}
+
+void
+rb_cc_table_free(VALUE klass)
+{
+ cc_table_free(&rb_objspace, klass, TRUE);
+}
+
static inline void
make_zombie(rb_objspace_t *objspace, VALUE obj, void (*dfree)(void *), void *data)
{
struct RZombie *zombie = RZOMBIE(obj);
- zombie->basic.flags = T_ZOMBIE;
+ zombie->basic.flags = T_ZOMBIE | (zombie->basic.flags & FL_SEEN_OBJ_ID);
zombie->dfree = dfree;
zombie->data = data;
zombie->next = heap_pages_deferred_final;
heap_pages_deferred_final = (VALUE)zombie;
+
+ struct heap_page *page = GET_HEAP_PAGE(obj);
+ page->final_slots++;
+ heap_pages_final_slots++;
}
static inline void
make_io_zombie(rb_objspace_t *objspace, VALUE obj)
{
rb_io_t *fptr = RANY(obj)->as.file.fptr;
- make_zombie(objspace, obj, (void (*)(void*))rb_io_fptr_finalize, fptr);
+ make_zombie(objspace, obj, rb_io_fptr_finalize_internal, fptr);
+}
+
+static void
+obj_free_object_id(rb_objspace_t *objspace, VALUE obj)
+{
+ ASSERT_vm_locking();
+ st_data_t o = (st_data_t)obj, id;
+
+ GC_ASSERT(FL_TEST(obj, FL_SEEN_OBJ_ID));
+ FL_UNSET(obj, FL_SEEN_OBJ_ID);
+
+ if (st_delete(objspace->obj_to_id_tbl, &o, &id)) {
+ GC_ASSERT(id);
+ st_delete(objspace->id_to_obj_tbl, &id, NULL);
+ }
+ else {
+ rb_bug("Object ID seen, but not in mapping table: %s\n", obj_info(obj));
+ }
}
static int
obj_free(rb_objspace_t *objspace, VALUE obj)
{
RB_DEBUG_COUNTER_INC(obj_free);
+ // RUBY_DEBUG_LOG("obj:%p (%s)", (void *)obj, obj_type_name(obj));
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_FREEOBJ, obj);
@@ -2174,6 +2784,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
case T_FALSE:
rb_bug("obj_free() called for broken object");
break;
+ default:
+ break;
}
if (FL_TEST(obj, FL_EXIVAR)) {
@@ -2181,7 +2793,10 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
FL_UNSET(obj, FL_EXIVAR);
}
-#if USE_RGENGC
+ if (FL_TEST(obj, FL_SEEN_OBJ_ID) && !FL_TEST(obj, FL_FINALIZE)) {
+ obj_free_object_id(objspace, obj);
+ }
+
if (RVALUE_WB_UNPROTECTED(obj)) CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
#if RGENGC_CHECK_MODE
@@ -2192,22 +2807,25 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
CHECK(RVALUE_UNCOLLECTIBLE);
#undef CHECK
#endif
-#endif
switch (BUILTIN_TYPE(obj)) {
case T_OBJECT:
- if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) &&
- RANY(obj)->as.object.as.heap.ivptr) {
- xfree(RANY(obj)->as.object.as.heap.ivptr);
- RB_DEBUG_COUNTER_INC(obj_obj_ptr);
- }
- else {
- RB_DEBUG_COUNTER_INC(obj_obj_embed);
- }
- break;
+ if (RANY(obj)->as.basic.flags & ROBJECT_EMBED) {
+ RB_DEBUG_COUNTER_INC(obj_obj_embed);
+ }
+ else if (ROBJ_TRANSIENT_P(obj)) {
+ RB_DEBUG_COUNTER_INC(obj_obj_transient);
+ }
+ else {
+ xfree(RANY(obj)->as.object.as.heap.ivptr);
+ RB_DEBUG_COUNTER_INC(obj_obj_ptr);
+ }
+ break;
case T_MODULE:
case T_CLASS:
+ mjit_remove_class_serial(RCLASS_SERIAL(obj));
rb_id_table_free(RCLASS_M_TBL(obj));
+ cc_table_free(objspace, obj, FALSE);
if (RCLASS_IV_TBL(obj)) {
st_free_table(RCLASS_IV_TBL(obj));
}
@@ -2215,7 +2833,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
rb_free_const_table(RCLASS_CONST_TBL(obj));
}
if (RCLASS_IV_INDEX_TBL(obj)) {
- st_free_table(RCLASS_IV_INDEX_TBL(obj));
+ iv_index_tbl_free(RCLASS_IV_INDEX_TBL(obj));
}
if (RCLASS_EXT(obj)->subclasses) {
if (BUILTIN_TYPE(obj) == T_MODULE) {
@@ -2231,21 +2849,78 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
if (RANY(obj)->as.klass.ptr)
xfree(RANY(obj)->as.klass.ptr);
RANY(obj)->as.klass.ptr = NULL;
+
+ (void)RB_DEBUG_COUNTER_INC_IF(obj_module_ptr, BUILTIN_TYPE(obj) == T_MODULE);
+ (void)RB_DEBUG_COUNTER_INC_IF(obj_class_ptr, BUILTIN_TYPE(obj) == T_CLASS);
break;
case T_STRING:
rb_str_free(obj);
break;
case T_ARRAY:
- rb_ary_free(obj);
+ rb_ary_free(obj);
break;
case T_HASH:
- if (RANY(obj)->as.hash.ntbl) {
- st_free_table(RANY(obj)->as.hash.ntbl);
- }
+#if USE_DEBUG_COUNTER
+ switch (RHASH_SIZE(obj)) {
+ case 0:
+ RB_DEBUG_COUNTER_INC(obj_hash_empty);
+ break;
+ case 1:
+ RB_DEBUG_COUNTER_INC(obj_hash_1);
+ break;
+ case 2:
+ RB_DEBUG_COUNTER_INC(obj_hash_2);
+ break;
+ case 3:
+ RB_DEBUG_COUNTER_INC(obj_hash_3);
+ break;
+ case 4:
+ RB_DEBUG_COUNTER_INC(obj_hash_4);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ RB_DEBUG_COUNTER_INC(obj_hash_5_8);
+ break;
+ default:
+ GC_ASSERT(RHASH_SIZE(obj) > 8);
+ RB_DEBUG_COUNTER_INC(obj_hash_g8);
+ }
+
+ if (RHASH_AR_TABLE_P(obj)) {
+ if (RHASH_AR_TABLE(obj) == NULL) {
+ RB_DEBUG_COUNTER_INC(obj_hash_null);
+ }
+ else {
+ RB_DEBUG_COUNTER_INC(obj_hash_ar);
+ }
+ }
+ else {
+ RB_DEBUG_COUNTER_INC(obj_hash_st);
+ }
+#endif
+ if (/* RHASH_AR_TABLE_P(obj) */ !FL_TEST_RAW(obj, RHASH_ST_TABLE_FLAG)) {
+ struct ar_table_struct *tab = RHASH(obj)->as.ar;
+
+ if (tab) {
+ if (RHASH_TRANSIENT_P(obj)) {
+ RB_DEBUG_COUNTER_INC(obj_hash_transient);
+ }
+ else {
+ ruby_xfree(tab);
+ }
+ }
+ }
+ else {
+ GC_ASSERT(RHASH_ST_TABLE_P(obj));
+ st_free_table(RHASH(obj)->as.st);
+ }
break;
case T_REGEXP:
if (RANY(obj)->as.regexp.ptr) {
onig_free(RANY(obj)->as.regexp.ptr);
+ RB_DEBUG_COUNTER_INC(obj_regexp_ptr);
}
break;
case T_DATA:
@@ -2269,40 +2944,66 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
if (dfree) {
if (dfree == RUBY_DEFAULT_FREE) {
xfree(data);
+ RB_DEBUG_COUNTER_INC(obj_data_xfree);
}
else if (free_immediately) {
(*dfree)(data);
+ RB_DEBUG_COUNTER_INC(obj_data_imm_free);
}
else {
make_zombie(objspace, obj, dfree, data);
+ RB_DEBUG_COUNTER_INC(obj_data_zombie);
return 1;
}
}
+ else {
+ RB_DEBUG_COUNTER_INC(obj_data_empty);
+ }
}
break;
case T_MATCH:
if (RANY(obj)->as.match.rmatch) {
struct rmatch *rm = RANY(obj)->as.match.rmatch;
+#if USE_DEBUG_COUNTER
+ if (rm->regs.num_regs >= 8) {
+ RB_DEBUG_COUNTER_INC(obj_match_ge8);
+ }
+ else if (rm->regs.num_regs >= 4) {
+ RB_DEBUG_COUNTER_INC(obj_match_ge4);
+ }
+ else if (rm->regs.num_regs >= 1) {
+ RB_DEBUG_COUNTER_INC(obj_match_under4);
+ }
+#endif
onig_region_free(&rm->regs, 0);
if (rm->char_offset)
xfree(rm->char_offset);
xfree(rm);
+
+ RB_DEBUG_COUNTER_INC(obj_match_ptr);
}
break;
case T_FILE:
if (RANY(obj)->as.file.fptr) {
make_io_zombie(objspace, obj);
+ RB_DEBUG_COUNTER_INC(obj_file_ptr);
return 1;
}
break;
case T_RATIONAL:
+ RB_DEBUG_COUNTER_INC(obj_rational);
+ break;
case T_COMPLEX:
+ RB_DEBUG_COUNTER_INC(obj_complex);
+ break;
+ case T_MOVED:
break;
case T_ICLASS:
/* Basically , T_ICLASS shares table with the module */
- if (FL_TEST(obj, RICLASS_IS_ORIGIN)) {
- rb_id_table_free(RCLASS_M_TBL(obj));
- }
+ if (RICLASS_OWNS_M_TBL_P(obj)) {
+ /* Method table is not shared for origin iclasses of classes */
+ rb_id_table_free(RCLASS_M_TBL(obj));
+ }
if (RCLASS_CALLABLE_M_TBL(obj) != NULL) {
rb_id_table_free(RCLASS_CALLABLE_M_TBL(obj));
}
@@ -2310,35 +3011,51 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
rb_class_detach_subclasses(obj);
RCLASS_EXT(obj)->subclasses = NULL;
}
+ cc_table_free(objspace, obj, FALSE);
rb_class_remove_from_module_subclasses(obj);
rb_class_remove_from_super_subclasses(obj);
xfree(RANY(obj)->as.klass.ptr);
RANY(obj)->as.klass.ptr = NULL;
+
+ RB_DEBUG_COUNTER_INC(obj_iclass_ptr);
break;
case T_FLOAT:
+ RB_DEBUG_COUNTER_INC(obj_float);
break;
case T_BIGNUM:
- if (!(RBASIC(obj)->flags & BIGNUM_EMBED_FLAG) && BIGNUM_DIGITS(obj)) {
+ if (!BIGNUM_EMBED_P(obj) && BIGNUM_DIGITS(obj)) {
xfree(BIGNUM_DIGITS(obj));
+ RB_DEBUG_COUNTER_INC(obj_bignum_ptr);
}
+ else {
+ RB_DEBUG_COUNTER_INC(obj_bignum_embed);
+ }
break;
case T_NODE:
- rb_gc_free_node(obj);
- break; /* no need to free iv_tbl */
+ UNEXPECTED_NODE(obj_free);
+ break;
case T_STRUCT:
- if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 &&
- RANY(obj)->as.rstruct.as.heap.ptr) {
- xfree((void *)RANY(obj)->as.rstruct.as.heap.ptr);
+ if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) ||
+ RANY(obj)->as.rstruct.as.heap.ptr == NULL) {
+ RB_DEBUG_COUNTER_INC(obj_struct_embed);
+ }
+ else if (RSTRUCT_TRANSIENT_P(obj)) {
+ RB_DEBUG_COUNTER_INC(obj_struct_transient);
+ }
+ else {
+ xfree((void *)RANY(obj)->as.rstruct.as.heap.ptr);
+ RB_DEBUG_COUNTER_INC(obj_struct_ptr);
}
break;
case T_SYMBOL:
{
rb_gc_free_dsymbol(obj);
+ RB_DEBUG_COUNTER_INC(obj_symbol);
}
break;
@@ -2346,16 +3063,52 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
switch (imemo_type(obj)) {
case imemo_ment:
rb_free_method_entry(&RANY(obj)->as.imemo.ment);
+ RB_DEBUG_COUNTER_INC(obj_imemo_ment);
break;
case imemo_iseq:
rb_iseq_free(&RANY(obj)->as.imemo.iseq);
+ RB_DEBUG_COUNTER_INC(obj_imemo_iseq);
break;
case imemo_env:
GC_ASSERT(VM_ENV_ESCAPED_P(RANY(obj)->as.imemo.env.ep));
xfree((VALUE *)RANY(obj)->as.imemo.env.env);
+ RB_DEBUG_COUNTER_INC(obj_imemo_env);
break;
- default:
+ case imemo_tmpbuf:
+ xfree(RANY(obj)->as.imemo.alloc.ptr);
+ RB_DEBUG_COUNTER_INC(obj_imemo_tmpbuf);
break;
+ case imemo_ast:
+ rb_ast_free(&RANY(obj)->as.imemo.ast);
+ RB_DEBUG_COUNTER_INC(obj_imemo_ast);
+ break;
+ case imemo_cref:
+ RB_DEBUG_COUNTER_INC(obj_imemo_cref);
+ break;
+ case imemo_svar:
+ RB_DEBUG_COUNTER_INC(obj_imemo_svar);
+ break;
+ case imemo_throw_data:
+ RB_DEBUG_COUNTER_INC(obj_imemo_throw_data);
+ break;
+ case imemo_ifunc:
+ RB_DEBUG_COUNTER_INC(obj_imemo_ifunc);
+ break;
+ case imemo_memo:
+ RB_DEBUG_COUNTER_INC(obj_imemo_memo);
+ break;
+ case imemo_parser_strterm:
+ RB_DEBUG_COUNTER_INC(obj_imemo_parser_strterm);
+ break;
+ case imemo_callinfo:
+ RB_DEBUG_COUNTER_INC(obj_imemo_callinfo);
+ break;
+ case imemo_callcache:
+ RB_DEBUG_COUNTER_INC(obj_imemo_callcache);
+ break;
+ case imemo_constcache:
+ RB_DEBUG_COUNTER_INC(obj_imemo_constcache);
+ break;
}
return 0;
@@ -2365,7 +3118,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
}
if (FL_TEST(obj, FL_FINALIZE)) {
- make_zombie(objspace, obj, 0, 0);
+ make_zombie(objspace, obj, 0, 0);
return 1;
}
else {
@@ -2373,12 +3126,53 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
}
}
+
+#define OBJ_ID_INCREMENT (sizeof(RVALUE) / 2)
+#define OBJ_ID_INITIAL (OBJ_ID_INCREMENT * 2)
+
+static int
+object_id_cmp(st_data_t x, st_data_t y)
+{
+ if (RB_TYPE_P(x, T_BIGNUM)) {
+ return !rb_big_eql(x, y);
+ } else {
+ return x != y;
+ }
+}
+
+static st_index_t
+object_id_hash(st_data_t n)
+{
+ if (RB_TYPE_P(n, T_BIGNUM)) {
+ return FIX2LONG(rb_big_hash(n));
+ } else {
+ return st_numhash(n);
+ }
+}
+static const struct st_hash_type object_id_hash_type = {
+ object_id_cmp,
+ object_id_hash,
+};
+
void
Init_heap(void)
{
rb_objspace_t *objspace = &rb_objspace;
- gc_stress_set(objspace, ruby_initial_gc_stress);
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+ /* If Ruby's heap pages are not a multiple of the system page size, we
+ * cannot use mprotect for the read barrier, so we must disable automatic
+ * compaction. */
+ int pagesize;
+ pagesize = (int)sysconf(_SC_PAGE_SIZE);
+ if ((HEAP_PAGE_SIZE % pagesize) != 0) {
+ ruby_enable_autocompact = 0;
+ }
+#endif
+
+ objspace->next_object_id = INT2FIX(OBJ_ID_INITIAL);
+ objspace->id_to_obj_tbl = st_init_table(&object_id_hash_type);
+ objspace->obj_to_id_tbl = st_init_numtable();
#if RGENGC_ESTIMATE_OLDMALLOC
objspace->rgengc.oldmalloc_increase_limit = gc_params.oldmalloc_limit_min;
@@ -2387,35 +3181,35 @@ Init_heap(void)
heap_add_pages(objspace, heap_eden, gc_params.heap_init_slots / HEAP_PAGE_OBJ_LIMIT);
init_mark_stack(&objspace->mark_stack);
-#ifdef USE_SIGALTSTACK
- {
- /* altstack of another threads are allocated in another place */
- rb_thread_t *th = GET_THREAD();
- void *tmp = th->altstack;
- th->altstack = malloc(rb_sigaltstack_size());
- free(tmp); /* free previously allocated area */
- }
-#endif
-
objspace->profile.invoke_time = getrusage_time();
finalizer_table = st_init_numtable();
}
+void
+Init_gc_stress(void)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+
+ gc_stress_set(objspace, ruby_initial_gc_stress);
+}
+
typedef int each_obj_callback(void *, void *, size_t, void *);
+static void objspace_each_objects(rb_objspace_t *objspace, each_obj_callback *callback, void *data);
+static void objspace_reachable_objects_from_root(rb_objspace_t *, void (func)(const char *, VALUE, void *), void *);
+
struct each_obj_args {
+ rb_objspace_t *objspace;
each_obj_callback *callback;
void *data;
};
-static VALUE
-objspace_each_objects(VALUE arg)
+static void
+objspace_each_objects_without_setup(rb_objspace_t *objspace, each_obj_callback *callback, void *data)
{
size_t i;
struct heap_page *page;
RVALUE *pstart = NULL, *pend;
- rb_objspace_t *objspace = &rb_objspace;
- struct each_obj_args *args = (struct each_obj_args *)arg;
i = 0;
while (i < heap_allocated_pages) {
@@ -2428,16 +3222,22 @@ objspace_each_objects(VALUE arg)
pstart = page->start;
pend = pstart + page->total_slots;
- if ((*args->callback)(pstart, pend, sizeof(RVALUE), args->data)) {
+ if ((*callback)(pstart, pend, sizeof(RVALUE), data)) {
break;
}
}
+}
+static VALUE
+objspace_each_objects_protected(VALUE arg)
+{
+ struct each_obj_args *args = (struct each_obj_args *)arg;
+ objspace_each_objects_without_setup(args->objspace, args->callback, args->data);
return Qnil;
}
static VALUE
-incremental_enable(void)
+incremental_enable(VALUE _)
{
rb_objspace_t *objspace = &rb_objspace;
@@ -2484,32 +3284,30 @@ incremental_enable(void)
void
rb_objspace_each_objects(each_obj_callback *callback, void *data)
{
- struct each_obj_args args;
- rb_objspace_t *objspace = &rb_objspace;
+ objspace_each_objects(&rb_objspace, callback, data);
+}
+
+static void
+objspace_each_objects(rb_objspace_t *objspace, each_obj_callback *callback, void *data)
+{
int prev_dont_incremental = objspace->flags.dont_incremental;
gc_rest(objspace);
objspace->flags.dont_incremental = TRUE;
- args.callback = callback;
- args.data = data;
-
if (prev_dont_incremental) {
- objspace_each_objects((VALUE)&args);
+ objspace_each_objects_without_setup(objspace, callback, data);
}
else {
- rb_ensure(objspace_each_objects, (VALUE)&args, incremental_enable, Qnil);
+ struct each_obj_args args = {objspace, callback, data};
+ rb_ensure(objspace_each_objects_protected, (VALUE)&args, incremental_enable, Qnil);
}
}
void
rb_objspace_each_objects_without_setup(each_obj_callback *callback, void *data)
{
- struct each_obj_args args;
- args.callback = callback;
- args.data = data;
-
- objspace_each_objects((VALUE)&args);
+ objspace_each_objects_without_setup(&rb_objspace, callback, data);
}
struct os_each_struct {
@@ -2521,13 +3319,19 @@ static int
internal_object_p(VALUE obj)
{
RVALUE *p = (RVALUE *)obj;
+ void *ptr = __asan_region_is_poisoned(p, SIZEOF_VALUE);
+ asan_unpoison_object(obj, false);
+ bool used_p = p->as.basic.flags;
- if (p->as.basic.flags) {
- switch (BUILTIN_TYPE(p)) {
+ if (used_p) {
+ switch (BUILTIN_TYPE(obj)) {
+ case T_NODE:
+ UNEXPECTED_NODE(internal_object_p);
+ break;
case T_NONE:
+ case T_MOVED:
case T_IMEMO:
case T_ICLASS:
- case T_NODE:
case T_ZOMBIE:
break;
case T_CLASS:
@@ -2541,6 +3345,9 @@ internal_object_p(VALUE obj)
return 0;
}
}
+ if (ptr || ! used_p) {
+ asan_poison_object(obj);
+ }
return 1;
}
@@ -2560,8 +3367,10 @@ os_obj_of_i(void *vstart, void *vend, size_t stride, void *data)
volatile VALUE v = (VALUE)p;
if (!internal_object_p(v)) {
if (!oes->of || rb_obj_is_kind_of(v, oes->of)) {
- rb_yield(v);
- oes->num++;
+ if (!rb_multi_ractor_p() || rb_ractor_shareable_p(v)) {
+ rb_yield(v);
+ oes->num++;
+ }
}
}
}
@@ -2591,9 +3400,9 @@ os_obj_of(VALUE of)
* <i>module</i>. Returns the number of objects found. Immediate
* objects (<code>Fixnum</code>s, <code>Symbol</code>s
* <code>true</code>, <code>false</code>, and <code>nil</code>) are
- * never returned. In the example below, <code>each_object</code>
- * returns both the numbers we defined and several constants defined in
- * the <code>Math</code> module.
+ * never returned. In the example below, #each_object returns both
+ * the numbers we defined and several constants defined in the Math
+ * module.
*
* If no block is given, an enumerator is returned instead.
*
@@ -2621,12 +3430,7 @@ os_each_obj(int argc, VALUE *argv, VALUE os)
{
VALUE of;
- if (argc == 0) {
- of = 0;
- }
- else {
- rb_scan_args(argc, argv, "01", &of);
- }
+ of = (!rb_check_arity(argc, 0, 1) ? 0 : argv[0]);
RETURN_ENUMERATOR(os, 1, &of);
return os_obj_of(of);
}
@@ -2659,11 +3463,12 @@ rb_undefine_finalizer(VALUE obj)
static void
should_be_callable(VALUE block)
{
- if (!rb_obj_respond_to(block, rb_intern("call"), TRUE)) {
+ if (!rb_obj_respond_to(block, idCall, TRUE)) {
rb_raise(rb_eArgError, "wrong type argument %"PRIsVALUE" (should be callable)",
rb_obj_class(block));
}
}
+
static void
should_be_finalizable(VALUE obj)
{
@@ -2683,6 +3488,57 @@ should_be_finalizable(VALUE obj)
* as an argument to <i>aProc</i>. If <i>aProc</i> is a lambda or
* method, make sure it can be called with a single argument.
*
+ * The return value is an array <code>[0, aProc]</code>.
+ *
+ * The two recommended patterns are to either create the finaliser proc
+ * in a non-instance method where it can safely capture the needed state,
+ * or to use a custom callable object that stores the needed state
+ * explicitly as instance variables.
+ *
+ * class Foo
+ * def initialize(data_needed_for_finalization)
+ * ObjectSpace.define_finalizer(self, self.class.create_finalizer(data_needed_for_finalization))
+ * end
+ *
+ * def self.create_finalizer(data_needed_for_finalization)
+ * proc {
+ * puts "finalizing #{data_needed_for_finalization}"
+ * }
+ * end
+ * end
+ *
+ * class Bar
+ * class Remover
+ * def initialize(data_needed_for_finalization)
+ * @data_needed_for_finalization = data_needed_for_finalization
+ * end
+ *
+ * def call(id)
+ * puts "finalizing #{@data_needed_for_finalization}"
+ * end
+ * end
+ *
+ * def initialize(data_needed_for_finalization)
+ * ObjectSpace.define_finalizer(self, Remover.new(data_needed_for_finalization))
+ * end
+ * end
+ *
+ * Note that if your finalizer references the object to be
+ * finalized it will never be run on GC, although it will still be
+ * run at exit. You will get a warning if you capture the object
+ * to be finalized as the receiver of the finalizer.
+ *
+ * class CapturesSelf
+ * def initialize(name)
+ * ObjectSpace.define_finalizer(self, proc {
+ * # this finalizer will only be run on exit
+ * puts "finalizing #{name}"
+ * })
+ * end
+ * end
+ *
+ * Also note that finalization can be unpredictable and is never guaranteed
+ * to be run except on exit.
*/
static VALUE
@@ -2699,6 +3555,10 @@ define_final(int argc, VALUE *argv, VALUE os)
should_be_callable(block);
}
+ if (rb_callable_receiver(block) == obj) {
+ rb_warn("finalizer references object to be finalized");
+ }
+
return define_final0(obj, block);
}
@@ -2711,7 +3571,7 @@ define_final0(VALUE obj, VALUE block)
RBASIC(obj)->flags |= FL_FINALIZE;
- block = rb_ary_new3(2, INT2FIX(rb_safe_level()), block);
+ block = rb_ary_new3(2, INT2FIX(0), block);
OBJ_FREEZE(block);
if (st_lookup(finalizer_table, obj, &data)) {
@@ -2719,13 +3579,13 @@ define_final0(VALUE obj, VALUE block)
/* avoid duplicate block, table is usually small */
{
- const VALUE *ptr = RARRAY_CONST_PTR(table);
long len = RARRAY_LEN(table);
long i;
- for (i = 0; i < len; i++, ptr++) {
- if (rb_funcall(*ptr, idEq, 1, block)) {
- return *ptr;
+ for (i = 0; i < len; i++) {
+ VALUE recv = RARRAY_AREF(table, i);
+ if (rb_funcall(recv, idEq, 1, block)) {
+ return recv;
}
}
}
@@ -2767,10 +3627,6 @@ static VALUE
run_single_final(VALUE final, VALUE objid)
{
const VALUE cmd = RARRAY_AREF(final, 1);
- const int level = OBJ_TAINTED(cmd) ?
- RUBY_SAFE_LEVEL_MAX : FIX2INT(RARRAY_AREF(final, 0));
-
- rb_set_safe_level_force(level);
return rb_check_funcall(cmd, idCall, 1, &objid);
}
@@ -2784,22 +3640,19 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
VALUE objid;
rb_control_frame_t *cfp;
long finished;
- int safe;
} saved;
- rb_thread_t *const th = GET_THREAD();
+ rb_execution_context_t * volatile ec = GET_EC();
#define RESTORE_FINALIZER() (\
- th->ec.cfp = saved.cfp, \
- rb_set_safe_level_force(saved.safe), \
+ ec->cfp = saved.cfp, \
rb_set_errinfo(saved.errinfo))
- saved.safe = rb_safe_level();
saved.errinfo = rb_errinfo();
- saved.objid = nonspecial_obj_id(obj);
- saved.cfp = th->ec.cfp;
+ saved.objid = rb_obj_id(obj);
+ saved.cfp = ec->cfp;
saved.finished = 0;
- TH_PUSH_TAG(th);
- state = TH_EXEC_TAG();
+ EC_PUSH_TAG(ec);
+ state = EC_EXEC_TAG();
if (state != TAG_NONE) {
++saved.finished; /* skip failed finalizer */
}
@@ -2808,7 +3661,7 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
saved.finished = ++i) {
run_single_final(RARRAY_AREF(table, i), saved.objid);
}
- TH_POP_TAG();
+ EC_POP_TAG();
#undef RESTORE_FINALIZER
}
@@ -2831,20 +3684,34 @@ static void
finalize_list(rb_objspace_t *objspace, VALUE zombie)
{
while (zombie) {
- VALUE next_zombie = RZOMBIE(zombie)->next;
- struct heap_page *page = GET_HEAP_PAGE(zombie);
+ VALUE next_zombie;
+ struct heap_page *page;
+ asan_unpoison_object(zombie, false);
+ next_zombie = RZOMBIE(zombie)->next;
+ page = GET_HEAP_PAGE(zombie);
run_final(objspace, zombie);
- RZOMBIE(zombie)->basic.flags = 0;
- heap_pages_final_slots--;
- page->final_slots--;
- page->free_slots++;
- heap_page_add_freeobj(objspace, GET_HEAP_PAGE(zombie), zombie);
+ RB_VM_LOCK_ENTER();
+ {
+ GC_ASSERT(BUILTIN_TYPE(zombie) == T_ZOMBIE);
+ if (FL_TEST(zombie, FL_SEEN_OBJ_ID)) {
+ obj_free_object_id(objspace, zombie);
+ }
- objspace->profile.total_freed_objects++;
+ RZOMBIE(zombie)->basic.flags = 0;
+ GC_ASSERT(heap_pages_final_slots > 0);
+ GC_ASSERT(page->final_slots > 0);
- zombie = next_zombie;
+ heap_pages_final_slots--;
+ page->final_slots--;
+ page->free_slots++;
+ heap_page_add_freeobj(objspace, GET_HEAP_PAGE(zombie), zombie);
+ objspace->profile.total_freed_objects++;
+ }
+ RB_VM_LOCK_LEAVE();
+
+ zombie = next_zombie;
}
}
@@ -2863,15 +3730,13 @@ gc_finalize_deferred(void *dmy)
{
rb_objspace_t *objspace = dmy;
if (ATOMIC_EXCHANGE(finalizing, 1)) return;
- finalize_deferred(objspace);
- ATOMIC_SET(finalizing, 0);
-}
-/* TODO: to keep compatibility, maybe unused. */
-void
-rb_gc_finalize_deferred(void)
-{
- gc_finalize_deferred(0);
+ RB_VM_LOCK_ENTER();
+ {
+ finalize_deferred(objspace);
+ ATOMIC_SET(finalizing, 0);
+ }
+ RB_VM_LOCK_LEAVE();
}
static void
@@ -2900,21 +3765,17 @@ force_chain_object(st_data_t key, st_data_t val, st_data_t arg)
return ST_CONTINUE;
}
-void
-rb_gc_call_finalizer_at_exit(void)
-{
-#if RGENGC_CHECK_MODE >= 2
- gc_verify_internal_consistency(Qnil);
-#endif
- rb_objspace_call_finalizer(&rb_objspace);
-}
+bool rb_obj_is_main_ractor(VALUE gv);
-static void
+void
rb_objspace_call_finalizer(rb_objspace_t *objspace)
{
RVALUE *p, *pend;
size_t i;
+#if RGENGC_CHECK_MODE >= 2
+ gc_verify_internal_consistency(objspace);
+#endif
gc_rest(objspace);
if (ATOMIC_EXCHANGE(finalizing, 1)) return;
@@ -2942,43 +3803,54 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
}
/* prohibit GC because force T_DATA finalizers can break an object graph consistency */
- dont_gc = 1;
+ dont_gc_on();
/* running data/file finalizers are part of garbage collection */
- gc_enter(objspace, "rb_objspace_call_finalizer");
+ unsigned int lock_lev;
+ gc_enter(objspace, gc_enter_event_finalizer, &lock_lev);
/* run data/file object's finalizers */
for (i = 0; i < heap_allocated_pages; i++) {
p = heap_pages_sorted[i]->start; pend = p + heap_pages_sorted[i]->total_slots;
while (p < pend) {
- switch (BUILTIN_TYPE(p)) {
+ VALUE vp = (VALUE)p;
+ void *poisoned = asan_poisoned_object_p(vp);
+ asan_unpoison_object(vp, false);
+ switch (BUILTIN_TYPE(vp)) {
case T_DATA:
if (!DATA_PTR(p) || !RANY(p)->as.data.dfree) break;
- if (rb_obj_is_thread((VALUE)p)) break;
- if (rb_obj_is_mutex((VALUE)p)) break;
- if (rb_obj_is_fiber((VALUE)p)) break;
- p->as.free.flags = 0;
- if (RTYPEDDATA_P(p)) {
+ if (rb_obj_is_thread(vp)) break;
+ if (rb_obj_is_mutex(vp)) break;
+ if (rb_obj_is_fiber(vp)) break;
+ if (rb_obj_is_main_ractor(vp)) break;
+ if (RTYPEDDATA_P(vp)) {
RDATA(p)->dfree = RANY(p)->as.typeddata.type->function.dfree;
}
- if (RANY(p)->as.data.dfree == (RUBY_DATA_FUNC)-1) {
+ p->as.free.flags = 0;
+ if (RANY(p)->as.data.dfree == RUBY_DEFAULT_FREE) {
xfree(DATA_PTR(p));
}
else if (RANY(p)->as.data.dfree) {
- make_zombie(objspace, (VALUE)p, RANY(p)->as.data.dfree, RANY(p)->as.data.data);
+ make_zombie(objspace, vp, RANY(p)->as.data.dfree, RANY(p)->as.data.data);
}
break;
case T_FILE:
if (RANY(p)->as.file.fptr) {
- make_io_zombie(objspace, (VALUE)p);
+ make_io_zombie(objspace, vp);
}
break;
+ default:
+ break;
}
+ if (poisoned) {
+ GC_ASSERT(BUILTIN_TYPE(vp) == T_NONE);
+ asan_poison_object(vp);
+ }
p++;
}
}
- gc_exit(objspace, "rb_objspace_call_finalizer");
+ gc_exit(objspace, gc_enter_event_finalizer, &lock_lev);
if (heap_pages_deferred_final) {
finalize_list(objspace, heap_pages_deferred_final);
@@ -2989,16 +3861,6 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
ATOMIC_SET(finalizing, 0);
}
-PUREFUNC(static inline int is_id_value(rb_objspace_t *objspace, VALUE ptr));
-static inline int
-is_id_value(rb_objspace_t *objspace, VALUE ptr)
-{
- if (!is_pointer_to_heap(objspace, (void *)ptr)) return FALSE;
- if (BUILTIN_TYPE(ptr) > T_FIXNUM) return FALSE;
- if (BUILTIN_TYPE(ptr) == T_ICLASS) return FALSE;
- return TRUE;
-}
-
static inline int
heap_is_swept_object(rb_objspace_t *objspace, rb_heap_t *heap, VALUE ptr)
{
@@ -3037,8 +3899,11 @@ is_live_object(rb_objspace_t *objspace, VALUE ptr)
{
switch (BUILTIN_TYPE(ptr)) {
case T_NONE:
+ case T_MOVED:
case T_ZOMBIE:
return FALSE;
+ default:
+ break;
}
if (!is_garbage_object(objspace, ptr)) {
@@ -3071,6 +3936,18 @@ rb_objspace_garbage_object_p(VALUE obj)
return is_garbage_object(objspace, obj);
}
+static VALUE
+id2ref_obj_tbl(rb_objspace_t *objspace, VALUE objid)
+{
+ VALUE orig;
+ if (st_lookup(objspace->id_to_obj_tbl, objid, &orig)) {
+ return orig;
+ }
+ else {
+ return Qundef;
+ }
+}
+
/*
* call-seq:
* ObjectSpace._id2ref(object_id) -> an_object
@@ -3082,10 +3959,12 @@ rb_objspace_garbage_object_p(VALUE obj)
* r = ObjectSpace._id2ref(s.object_id) #=> "I am a string"
* r == s #=> true
*
+ * On multi-ractor mode, if the object is not sharable, it raises
+ * RangeError.
*/
static VALUE
-id2ref(VALUE obj, VALUE objid)
+id2ref(VALUE objid)
{
#if SIZEOF_LONG == SIZEOF_VOIDP
#define NUM2PTR(x) NUM2ULONG(x)
@@ -3094,35 +3973,110 @@ id2ref(VALUE obj, VALUE objid)
#endif
rb_objspace_t *objspace = &rb_objspace;
VALUE ptr;
+ VALUE orig;
void *p0;
- ptr = NUM2PTR(objid);
- p0 = (void *)ptr;
+ objid = rb_to_int(objid);
+ if (FIXNUM_P(objid) || rb_big_size(objid) <= SIZEOF_VOIDP) {
+ ptr = NUM2PTR(objid);
+ if (ptr == Qtrue) return Qtrue;
+ if (ptr == Qfalse) return Qfalse;
+ if (ptr == Qnil) return Qnil;
+ if (FIXNUM_P(ptr)) return (VALUE)ptr;
+ if (FLONUM_P(ptr)) return (VALUE)ptr;
+
+ ptr = obj_id_to_ref(objid);
+ if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
+ ID symid = ptr / sizeof(RVALUE);
+ p0 = (void *)ptr;
+ if (rb_id2str(symid) == 0)
+ rb_raise(rb_eRangeError, "%p is not symbol id value", p0);
+ return ID2SYM(symid);
+ }
+ }
- if (ptr == Qtrue) return Qtrue;
- if (ptr == Qfalse) return Qfalse;
- if (ptr == Qnil) return Qnil;
- if (FIXNUM_P(ptr)) return (VALUE)ptr;
- if (FLONUM_P(ptr)) return (VALUE)ptr;
- ptr = obj_id_to_ref(objid);
+ if ((orig = id2ref_obj_tbl(objspace, objid)) != Qundef &&
+ is_live_object(objspace, orig)) {
- if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
- ID symid = ptr / sizeof(RVALUE);
- if (rb_id2str(symid) == 0)
- rb_raise(rb_eRangeError, "%p is not symbol id value", p0);
- return ID2SYM(symid);
+ if (!rb_multi_ractor_p() || rb_ractor_shareable_p(orig)) {
+ return orig;
+ }
+ else {
+ rb_raise(rb_eRangeError, "%+"PRIsVALUE" is id of the unshareable object on multi-ractor", rb_int2str(objid, 10));
+ }
}
- if (!is_id_value(objspace, ptr)) {
- rb_raise(rb_eRangeError, "%p is not id value", p0);
+ if (rb_int_ge(objid, objspace->next_object_id)) {
+ rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not id value", rb_int2str(objid, 10));
+ } else {
+ rb_raise(rb_eRangeError, "%+"PRIsVALUE" is recycled object", rb_int2str(objid, 10));
+ }
+}
+
+static VALUE
+os_id2ref(VALUE os, VALUE objid)
+{
+ return id2ref(objid);
+}
+
+static VALUE
+rb_find_object_id(VALUE obj, VALUE (*get_heap_object_id)(VALUE))
+{
+ if (STATIC_SYM_P(obj)) {
+ return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
}
- if (!is_live_object(objspace, ptr)) {
- rb_raise(rb_eRangeError, "%p is recycled object", p0);
+ else if (FLONUM_P(obj)) {
+#if SIZEOF_LONG == SIZEOF_VOIDP
+ return LONG2NUM((SIGNED_VALUE)obj);
+#else
+ return LL2NUM((SIGNED_VALUE)obj);
+#endif
}
- if (RBASIC(ptr)->klass == 0) {
- rb_raise(rb_eRangeError, "%p is internal object", p0);
+ else if (SPECIAL_CONST_P(obj)) {
+ return LONG2NUM((SIGNED_VALUE)obj);
+ }
+
+ return get_heap_object_id(obj);
+}
+
+static VALUE
+cached_object_id(VALUE obj)
+{
+ VALUE id;
+ rb_objspace_t *objspace = &rb_objspace;
+
+ RB_VM_LOCK_ENTER();
+ if (st_lookup(objspace->obj_to_id_tbl, (st_data_t)obj, &id)) {
+ GC_ASSERT(FL_TEST(obj, FL_SEEN_OBJ_ID));
+ }
+ else {
+ GC_ASSERT(!FL_TEST(obj, FL_SEEN_OBJ_ID));
+
+ id = objspace->next_object_id;
+ objspace->next_object_id = rb_int_plus(id, INT2FIX(OBJ_ID_INCREMENT));
+
+ VALUE already_disabled = rb_gc_disable_no_rest();
+ st_insert(objspace->obj_to_id_tbl, (st_data_t)obj, (st_data_t)id);
+ st_insert(objspace->id_to_obj_tbl, (st_data_t)id, (st_data_t)obj);
+ if (already_disabled == Qfalse) rb_objspace_gc_enable(objspace);
+ FL_SET(obj, FL_SEEN_OBJ_ID);
}
- return (VALUE)ptr;
+ RB_VM_LOCK_LEAVE();
+
+ return id;
+}
+
+static VALUE
+nonspecial_obj_id_(VALUE obj)
+{
+ return nonspecial_obj_id(obj);
+}
+
+
+VALUE
+rb_memory_id(VALUE obj)
+{
+ return rb_find_object_id(obj, nonspecial_obj_id_);
}
/*
@@ -3141,6 +4095,8 @@ id2ref(VALUE obj, VALUE objid)
* Note: that some objects of builtin classes are reused for optimization.
* This is the case for immediate values and frozen string literals.
*
+ * BasicObject implements +__id__+, Kernel implements +object_id+.
+ *
* Immediate values are not passed by reference but are passed by value:
* +nil+, +true+, +false+, Fixnums, Symbols, and some Floats.
*
@@ -3181,23 +4137,27 @@ rb_obj_id(VALUE obj)
* 24 if 32-bit, double is 8-byte aligned
* 40 if 64-bit
*/
- if (STATIC_SYM_P(obj)) {
- return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
- }
- else if (FLONUM_P(obj)) {
-#if SIZEOF_LONG == SIZEOF_VOIDP
- return LONG2NUM((SIGNED_VALUE)obj);
-#else
- return LL2NUM((SIGNED_VALUE)obj);
-#endif
- }
- else if (SPECIAL_CONST_P(obj)) {
- return LONG2NUM((SIGNED_VALUE)obj);
- }
- return nonspecial_obj_id(obj);
+
+ return rb_find_object_id(obj, cached_object_id);
}
-#include "regint.h"
+static enum rb_id_table_iterator_result
+cc_table_memsize_i(VALUE ccs_ptr, void *data_ptr)
+{
+ size_t *total_size = data_ptr;
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
+ *total_size += sizeof(*ccs);
+ *total_size += sizeof(ccs->entries[0]) * ccs->capa;
+ return ID_TABLE_CONTINUE;
+}
+
+static size_t
+cc_table_memsize(struct rb_id_table *cc_table)
+{
+ size_t total = rb_id_table_memsize(cc_table);
+ rb_id_table_foreach_values(cc_table, cc_table_memsize_i, &total);
+ return total;
+}
static size_t
obj_memsize_of(VALUE obj, int use_all_types)
@@ -3214,21 +4174,21 @@ obj_memsize_of(VALUE obj, int use_all_types)
switch (BUILTIN_TYPE(obj)) {
case T_OBJECT:
- if (!(RBASIC(obj)->flags & ROBJECT_EMBED) &&
- ROBJECT(obj)->as.heap.ivptr) {
- size += ROBJECT(obj)->as.heap.numiv * sizeof(VALUE);
+ if (!(RBASIC(obj)->flags & ROBJECT_EMBED)) {
+ size += ROBJECT_NUMIV(obj) * sizeof(VALUE);
}
break;
case T_MODULE:
case T_CLASS:
- if (RCLASS_M_TBL(obj)) {
- size += rb_id_table_memsize(RCLASS_M_TBL(obj));
- }
if (RCLASS_EXT(obj)) {
+ if (RCLASS_M_TBL(obj)) {
+ size += rb_id_table_memsize(RCLASS_M_TBL(obj));
+ }
if (RCLASS_IV_TBL(obj)) {
size += st_memsize(RCLASS_IV_TBL(obj));
}
if (RCLASS_IV_INDEX_TBL(obj)) {
+ // TODO: more correct value
size += st_memsize(RCLASS_IV_INDEX_TBL(obj));
}
if (RCLASS(obj)->ptr->iv_tbl) {
@@ -3237,15 +4197,21 @@ obj_memsize_of(VALUE obj, int use_all_types)
if (RCLASS(obj)->ptr->const_tbl) {
size += rb_id_table_memsize(RCLASS(obj)->ptr->const_tbl);
}
+ if (RCLASS_CC_TBL(obj)) {
+ size += cc_table_memsize(RCLASS_CC_TBL(obj));
+ }
size += sizeof(rb_classext_t);
}
break;
case T_ICLASS:
- if (FL_TEST(obj, RICLASS_IS_ORIGIN)) {
+ if (RICLASS_OWNS_M_TBL_P(obj)) {
if (RCLASS_M_TBL(obj)) {
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
}
}
+ if (RCLASS_EXT(obj) && RCLASS_CC_TBL(obj)) {
+ size += cc_table_memsize(RCLASS_CC_TBL(obj));
+ }
break;
case T_STRING:
size += rb_str_memsize(obj);
@@ -3254,9 +4220,16 @@ obj_memsize_of(VALUE obj, int use_all_types)
size += rb_ary_memsize(obj);
break;
case T_HASH:
- if (RHASH(obj)->ntbl) {
- size += st_memsize(RHASH(obj)->ntbl);
+ if (RHASH_AR_TABLE_P(obj)) {
+ if (RHASH_AR_TABLE(obj) != NULL) {
+ size_t rb_hash_ar_table_size();
+ size += rb_hash_ar_table_size();
+ }
}
+ else {
+ VM_ASSERT(RHASH_ST_TABLE(obj) != NULL);
+ size += st_memsize(RHASH_ST_TABLE(obj));
+ }
break;
case T_REGEXP:
if (RREGEXP_PTR(obj)) {
@@ -3281,7 +4254,9 @@ obj_memsize_of(VALUE obj, int use_all_types)
break;
case T_RATIONAL:
case T_COMPLEX:
+ break;
case T_IMEMO:
+ size += imemo_memsize(obj);
break;
case T_FLOAT:
@@ -3295,7 +4270,7 @@ obj_memsize_of(VALUE obj, int use_all_types)
break;
case T_NODE:
- if (use_all_types) size += rb_node_memsize(obj);
+ UNEXPECTED_NODE(obj_memsize_of);
break;
case T_STRUCT:
@@ -3306,6 +4281,7 @@ obj_memsize_of(VALUE obj, int use_all_types)
break;
case T_ZOMBIE:
+ case T_MOVED:
break;
default:
@@ -3331,6 +4307,43 @@ set_zero(st_data_t key, st_data_t val, st_data_t arg)
return ST_CONTINUE;
}
+static VALUE
+type_sym(size_t type)
+{
+ switch (type) {
+#define COUNT_TYPE(t) case (t): return ID2SYM(rb_intern(#t)); break;
+ COUNT_TYPE(T_NONE);
+ COUNT_TYPE(T_OBJECT);
+ COUNT_TYPE(T_CLASS);
+ COUNT_TYPE(T_MODULE);
+ COUNT_TYPE(T_FLOAT);
+ COUNT_TYPE(T_STRING);
+ COUNT_TYPE(T_REGEXP);
+ COUNT_TYPE(T_ARRAY);
+ COUNT_TYPE(T_HASH);
+ COUNT_TYPE(T_STRUCT);
+ COUNT_TYPE(T_BIGNUM);
+ COUNT_TYPE(T_FILE);
+ COUNT_TYPE(T_DATA);
+ COUNT_TYPE(T_MATCH);
+ COUNT_TYPE(T_COMPLEX);
+ COUNT_TYPE(T_RATIONAL);
+ COUNT_TYPE(T_NIL);
+ COUNT_TYPE(T_TRUE);
+ COUNT_TYPE(T_FALSE);
+ COUNT_TYPE(T_SYMBOL);
+ COUNT_TYPE(T_FIXNUM);
+ COUNT_TYPE(T_IMEMO);
+ COUNT_TYPE(T_UNDEF);
+ COUNT_TYPE(T_NODE);
+ COUNT_TYPE(T_ICLASS);
+ COUNT_TYPE(T_ZOMBIE);
+ COUNT_TYPE(T_MOVED);
+#undef COUNT_TYPE
+ default: return SIZET2NUM(type); break;
+ }
+}
+
/*
* call-seq:
* ObjectSpace.count_objects([result_hash]) -> hash
@@ -3374,9 +4387,10 @@ count_objects(int argc, VALUE *argv, VALUE os)
size_t freed = 0;
size_t total = 0;
size_t i;
- VALUE hash;
+ VALUE hash = Qnil;
- if (rb_scan_args(argc, argv, "01", &hash) == 1) {
+ if (rb_check_arity(argc, 0, 1) == 1) {
+ hash = argv[0];
if (!RB_TYPE_P(hash, T_HASH))
rb_raise(rb_eTypeError, "non-hash given");
}
@@ -3391,12 +4405,19 @@ count_objects(int argc, VALUE *argv, VALUE os)
p = page->start; pend = p + page->total_slots;
for (;p < pend; p++) {
+ VALUE vp = (VALUE)p;
+ void *poisoned = asan_poisoned_object_p(vp);
+ asan_unpoison_object(vp, false);
if (p->as.basic.flags) {
- counts[BUILTIN_TYPE(p)]++;
+ counts[BUILTIN_TYPE(vp)]++;
}
else {
freed++;
}
+ if (poisoned) {
+ GC_ASSERT(BUILTIN_TYPE(vp) == T_NONE);
+ asan_poison_object(vp);
+ }
}
total += page->total_slots;
}
@@ -3405,44 +4426,13 @@ count_objects(int argc, VALUE *argv, VALUE os)
hash = rb_hash_new();
}
else if (!RHASH_EMPTY_P(hash)) {
- st_foreach(RHASH_TBL_RAW(hash), set_zero, hash);
+ rb_hash_stlike_foreach(hash, set_zero, hash);
}
rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
rb_hash_aset(hash, ID2SYM(rb_intern("FREE")), SIZET2NUM(freed));
for (i = 0; i <= T_MASK; i++) {
- VALUE type;
- switch (i) {
-#define COUNT_TYPE(t) case (t): type = ID2SYM(rb_intern(#t)); break;
- COUNT_TYPE(T_NONE);
- COUNT_TYPE(T_OBJECT);
- COUNT_TYPE(T_CLASS);
- COUNT_TYPE(T_MODULE);
- COUNT_TYPE(T_FLOAT);
- COUNT_TYPE(T_STRING);
- COUNT_TYPE(T_REGEXP);
- COUNT_TYPE(T_ARRAY);
- COUNT_TYPE(T_HASH);
- COUNT_TYPE(T_STRUCT);
- COUNT_TYPE(T_BIGNUM);
- COUNT_TYPE(T_FILE);
- COUNT_TYPE(T_DATA);
- COUNT_TYPE(T_MATCH);
- COUNT_TYPE(T_COMPLEX);
- COUNT_TYPE(T_RATIONAL);
- COUNT_TYPE(T_NIL);
- COUNT_TYPE(T_TRUE);
- COUNT_TYPE(T_FALSE);
- COUNT_TYPE(T_SYMBOL);
- COUNT_TYPE(T_FIXNUM);
- COUNT_TYPE(T_IMEMO);
- COUNT_TYPE(T_UNDEF);
- COUNT_TYPE(T_NODE);
- COUNT_TYPE(T_ICLASS);
- COUNT_TYPE(T_ZOMBIE);
-#undef COUNT_TYPE
- default: type = INT2NUM(i); break;
- }
+ VALUE type = type_sym(i);
if (counts[i])
rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
}
@@ -3477,13 +4467,369 @@ objspace_free_slots(rb_objspace_t *objspace)
static void
gc_setup_mark_bits(struct heap_page *page)
{
-#if USE_RGENGC
/* copy oldgen bitmap to mark bitmap */
memcpy(&page->mark_bits[0], &page->uncollectible_bits[0], HEAP_PAGE_BITMAP_SIZE);
+}
+
+static int gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj);
+static VALUE gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free);
+
+static void
+lock_page_body(rb_objspace_t *objspace, struct heap_page_body *body)
+{
+#if defined(_WIN32)
+ DWORD old_protect;
+
+ if (!VirtualProtect(body, HEAP_PAGE_SIZE, PAGE_NOACCESS, &old_protect)) {
+#else
+ if(mprotect(body, HEAP_PAGE_SIZE, PROT_NONE)) {
+#endif
+ rb_bug("Couldn't protect page %p", (void *)body);
+ } else {
+ gc_report(5, objspace, "Protecting page in move %p\n", (void *)body);
+ }
+}
+
+static void
+unlock_page_body(rb_objspace_t *objspace, struct heap_page_body *body)
+{
+#if defined(_WIN32)
+ DWORD old_protect;
+
+ if (!VirtualProtect(body, HEAP_PAGE_SIZE, PAGE_READWRITE, &old_protect)) {
+#else
+ if(mprotect(body, HEAP_PAGE_SIZE, PROT_READ | PROT_WRITE)) {
+#endif
+ rb_bug("Couldn't unprotect page %p", (void *)body);
+ } else {
+ gc_report(5, objspace, "Unprotecting page in move %p\n", (void *)body);
+ }
+}
+
+static short
+try_move(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_page, VALUE dest)
+{
+ struct heap_page * cursor = heap->compact_cursor;
+ char from_freelist = 0;
+
+ GC_ASSERT(!MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(dest), dest));
+
+ /* T_NONE objects came from the free list. If the object is *not* a
+ * T_NONE, it is an object that just got freed but hasn't been
+ * added to the freelist yet */
+
+ if (BUILTIN_TYPE(dest) == T_NONE) {
+ from_freelist = 1;
+ }
+
+ while(1) {
+ size_t index = heap->compact_cursor_index;
+
+ bits_t *mark_bits = cursor->mark_bits;
+ bits_t *pin_bits = cursor->pinned_bits;
+ RVALUE * p = cursor->start;
+ RVALUE * offset = p - NUM_IN_PAGE(p);
+
+ /* Find an object to move and move it. Movable objects must be
+ * marked, so we iterate using the marking bitmap */
+ for (size_t i = index; i < HEAP_PAGE_BITMAP_LIMIT; i++) {
+ bits_t bits = mark_bits[i] & ~pin_bits[i];
+
+ if (bits) {
+ p = offset + i * BITS_BITLENGTH;
+
+ do {
+ if (bits & 1) {
+ /* We're trying to move "p" */
+ objspace->rcompactor.considered_count_table[BUILTIN_TYPE((VALUE)p)]++;
+
+ if (gc_is_moveable_obj(objspace, (VALUE)p)) {
+ /* We were able to move "p" */
+ objspace->rcompactor.moved_count_table[BUILTIN_TYPE((VALUE)p)]++;
+ objspace->rcompactor.total_moved++;
+ gc_move(objspace, (VALUE)p, dest);
+ gc_pin(objspace, (VALUE)p);
+ heap->compact_cursor_index = i;
+ if (from_freelist) {
+ FL_SET((VALUE)p, FL_FROM_FREELIST);
+ }
+
+ return 1;
+ }
+ }
+ p++;
+ bits >>= 1;
+ } while (bits);
+ }
+ }
+
+ /* We couldn't find a movable object on the compact cursor, so lets
+ * move to the next page (previous page since we are traveling in the
+ * opposite direction of the sweep cursor) and look there. */
+
+ struct heap_page * next;
+
+ next = list_prev(&heap->pages, cursor, page_node);
+
+ /* Protect the current cursor since it probably has T_MOVED slots. */
+ lock_page_body(objspace, GET_PAGE_BODY(cursor->start));
+
+ heap->compact_cursor = next;
+ heap->compact_cursor_index = 0;
+ cursor = next;
+
+ // Cursors have met, lets quit. We set `heap->compact_cursor` equal
+ // to `heap->sweeping_page` so we know how far to iterate through
+ // the heap when unprotecting pages.
+ if (next == sweep_page) {
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void
+gc_unprotect_pages(rb_objspace_t *objspace, rb_heap_t *heap)
+{
+ struct heap_page *cursor = heap->compact_cursor;
+
+ while(cursor) {
+ unlock_page_body(objspace, GET_PAGE_BODY(cursor->start));
+ cursor = list_next(&heap->pages, cursor, page_node);
+ }
+}
+
+static void gc_update_references(rb_objspace_t * objspace, rb_heap_t *heap);
+static void invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page);
+
+static void read_barrier_handler(intptr_t address)
+{
+ VALUE obj;
+ rb_objspace_t * objspace = &rb_objspace;
+
+ address -= address % sizeof(RVALUE);
+
+ obj = (VALUE)address;
+
+ RB_VM_LOCK_ENTER();
+ {
+ unlock_page_body(objspace, GET_PAGE_BODY(obj));
+
+ objspace->profile.read_barrier_faults++;
+
+ invalidate_moved_page(objspace, GET_HEAP_PAGE(obj));
+ }
+ RB_VM_LOCK_LEAVE();
+}
+
+#if defined(_WIN32)
+static LPTOP_LEVEL_EXCEPTION_FILTER old_handler;
+typedef void (*signal_handler)(int);
+static signal_handler old_sigsegv_handler;
+
+static LONG WINAPI read_barrier_signal(EXCEPTION_POINTERS * info)
+{
+ /* EXCEPTION_ACCESS_VIOLATION is what's raised by access to protected pages */
+ if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
+ /* > The second array element specifies the virtual address of the inaccessible data.
+ * https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record
+ *
+ * Use this address to invalidate the page */
+ read_barrier_handler((intptr_t)info->ExceptionRecord->ExceptionInformation[1]);
+ return EXCEPTION_CONTINUE_EXECUTION;
+ } else {
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+}
+
+static void
+uninstall_handlers(void)
+{
+ signal(SIGSEGV, old_sigsegv_handler);
+ SetUnhandledExceptionFilter(old_handler);
+}
+
+static void
+install_handlers(void)
+{
+ /* Remove SEGV handler so that the Unhandled Exception Filter handles it */
+ old_sigsegv_handler = signal(SIGSEGV, NULL);
+ /* Unhandled Exception Filter has access to the violation address similar
+ * to si_addr from sigaction */
+ old_handler = SetUnhandledExceptionFilter(read_barrier_signal);
+}
#else
- /* clear mark bitmap */
- memset(&page->mark_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
+static struct sigaction old_sigbus_handler;
+static struct sigaction old_sigsegv_handler;
+
+static void
+read_barrier_signal(int sig, siginfo_t * info, void * data)
+{
+ // setup SEGV/BUS handlers for errors
+ struct sigaction prev_sigbus, prev_sigsegv;
+ sigaction(SIGBUS, &old_sigbus_handler, &prev_sigbus);
+ sigaction(SIGSEGV, &old_sigsegv_handler, &prev_sigsegv);
+
+ // enable SIGBUS/SEGV
+ sigset_t set, prev_set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGBUS);
+ sigaddset(&set, SIGSEGV);
+ sigprocmask(SIG_UNBLOCK, &set, &prev_set);
+
+ // run handler
+ read_barrier_handler((intptr_t)info->si_addr);
+
+ // reset SEGV/BUS handlers
+ sigaction(SIGBUS, &prev_sigbus, NULL);
+ sigaction(SIGSEGV, &prev_sigsegv, NULL);
+ sigprocmask(SIG_SETMASK, &prev_set, NULL);
+}
+
+static void
+uninstall_handlers(void)
+{
+ sigaction(SIGBUS, &old_sigbus_handler, NULL);
+ sigaction(SIGSEGV, &old_sigsegv_handler, NULL);
+}
+
+static void
+install_handlers(void)
+{
+ struct sigaction action;
+ memset(&action, 0, sizeof(struct sigaction));
+ sigemptyset(&action.sa_mask);
+ action.sa_sigaction = read_barrier_signal;
+ action.sa_flags = SA_SIGINFO | SA_ONSTACK;
+
+ sigaction(SIGBUS, &action, &old_sigbus_handler);
+ sigaction(SIGSEGV, &action, &old_sigsegv_handler);
+}
#endif
+
+static void
+revert_stack_objects(VALUE stack_obj, void *ctx)
+{
+ rb_objspace_t * objspace = (rb_objspace_t*)ctx;
+
+ if (BUILTIN_TYPE(stack_obj) == T_MOVED) {
+ /* For now we'll revert the whole page if the object made it to the
+ * stack. I think we can change this to move just the one object
+ * back though */
+ invalidate_moved_page(objspace, GET_HEAP_PAGE(stack_obj));
+ }
+}
+
+static void
+check_stack_for_moved(rb_objspace_t *objspace)
+{
+ rb_execution_context_t *ec = GET_EC();
+ rb_vm_t *vm = rb_ec_vm_ptr(ec);
+ rb_vm_each_stack_value(vm, revert_stack_objects, (void*)objspace);
+}
+
+static void
+gc_compact_finish(rb_objspace_t *objspace, rb_heap_t *heap)
+{
+ GC_ASSERT(heap->sweeping_page == heap->compact_cursor);
+
+ gc_unprotect_pages(objspace, heap);
+ uninstall_handlers();
+
+ /* The mutator is allowed to run during incremental sweeping. T_MOVED
+ * objects can get pushed on the stack and when the compaction process
+ * finishes up, it may remove the read barrier before anything has a
+ * chance to read from the T_MOVED address. To fix this, we scan the stack
+ * then revert any moved objects that made it to the stack. */
+ check_stack_for_moved(objspace);
+
+ gc_update_references(objspace, heap);
+ heap->compact_cursor = NULL;
+ heap->compact_cursor_index = 0;
+ objspace->profile.compact_count++;
+ if (gc_prof_enabled(objspace)) {
+ gc_profile_record *record = gc_prof_record(objspace);
+ record->moved_objects = objspace->rcompactor.total_moved - record->moved_objects;
+ }
+ rb_clear_constant_cache();
+ objspace->flags.during_compacting = FALSE;
+}
+
+static int
+gc_fill_swept_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_page, int *freed_slots, int *empty_slots)
+{
+ /* Find any pinned but not marked objects and try to fill those slots */
+ int i;
+ int moved_slots = 0;
+ int finished_compacting = 0;
+ bits_t *mark_bits, *pin_bits;
+ bits_t bitset;
+ RVALUE *p, *offset;
+
+ mark_bits = sweep_page->mark_bits;
+ pin_bits = sweep_page->pinned_bits;
+
+ p = sweep_page->start;
+ offset = p - NUM_IN_PAGE(p);
+
+ struct heap_page * cursor = heap->compact_cursor;
+
+ unlock_page_body(objspace, GET_PAGE_BODY(cursor->start));
+
+ for (i=0; i < HEAP_PAGE_BITMAP_LIMIT; i++) {
+ /* *Want to move* objects are pinned but not marked. */
+ bitset = pin_bits[i] & ~mark_bits[i];
+
+ if (bitset) {
+ p = offset + i * BITS_BITLENGTH;
+ do {
+ if (bitset & 1) {
+ VALUE dest = (VALUE)p;
+
+ GC_ASSERT(MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(dest), dest));
+ GC_ASSERT(!MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(dest), dest));
+
+ CLEAR_IN_BITMAP(GET_HEAP_PINNED_BITS(dest), dest);
+
+ if (finished_compacting) {
+ if (BUILTIN_TYPE(dest) == T_NONE) {
+ (*empty_slots)++;
+ } else {
+ (*freed_slots)++;
+ }
+ (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)dest, sizeof(RVALUE));
+ heap_page_add_freeobj(objspace, sweep_page, dest);
+ } else {
+ /* Zombie slots don't get marked, but we can't reuse
+ * their memory until they have their finalizers run.*/
+ if (BUILTIN_TYPE(dest) != T_ZOMBIE) {
+ if(!try_move(objspace, heap, sweep_page, dest)) {
+ finished_compacting = 1;
+ (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
+ gc_report(5, objspace, "Quit compacting, couldn't find an object to move\n");
+ if (BUILTIN_TYPE(dest) == T_NONE) {
+ (*empty_slots)++;
+ } else {
+ (*freed_slots)++;
+ }
+ heap_page_add_freeobj(objspace, sweep_page, dest);
+ gc_report(3, objspace, "page_sweep: %s is added to freelist\n", obj_info(dest));
+ } else {
+ moved_slots++;
+ }
+ }
+ }
+ }
+ p++;
+ bitset >>= 1;
+ } while (bitset);
+ }
+ }
+
+ lock_page_body(objspace, GET_PAGE_BODY(heap->compact_cursor->start));
+
+ return finished_compacting;
}
static inline int
@@ -3491,54 +4837,109 @@ gc_page_sweep(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_
{
int i;
int empty_slots = 0, freed_slots = 0, final_slots = 0;
- RVALUE *p, *pend,*offset;
+ int was_compacting = 0;
+ RVALUE *p, *offset;
bits_t *bits, bitset;
gc_report(2, objspace, "page_sweep: start.\n");
+ if (heap->compact_cursor) {
+ if (sweep_page == heap->compact_cursor) {
+ /* The compaction cursor and sweep page met, so we need to quit compacting */
+ gc_report(5, objspace, "Quit compacting, mark and compact cursor met\n");
+ gc_compact_finish(objspace, heap);
+ } else {
+ /* We anticipate filling the page, so NULL out the freelist. */
+ asan_unpoison_memory_region(&sweep_page->freelist, sizeof(RVALUE*), false);
+ sweep_page->freelist = NULL;
+ asan_poison_memory_region(&sweep_page->freelist, sizeof(RVALUE*));
+ was_compacting = 1;
+ }
+ }
+
sweep_page->flags.before_sweep = FALSE;
- p = sweep_page->start; pend = p + sweep_page->total_slots;
+ p = sweep_page->start;
offset = p - NUM_IN_PAGE(p);
bits = sweep_page->mark_bits;
/* create guard : fill 1 out-of-range */
bits[BITMAP_INDEX(p)] |= BITMAP_BIT(p)-1;
- bits[BITMAP_INDEX(pend)] |= ~(BITMAP_BIT(pend) - 1);
+
+ int out_of_range_bits = (NUM_IN_PAGE(p) + sweep_page->total_slots) % BITS_BITLENGTH;
+ if (out_of_range_bits != 0) { // sizeof(RVALUE) == 64
+ bits[BITMAP_INDEX(p) + sweep_page->total_slots / BITS_BITLENGTH] |= ~(((bits_t)1 << out_of_range_bits) - 1);
+ }
for (i=0; i < HEAP_PAGE_BITMAP_LIMIT; i++) {
bitset = ~bits[i];
if (bitset) {
p = offset + i * BITS_BITLENGTH;
do {
+ VALUE vp = (VALUE)p;
+ asan_unpoison_object(vp, false);
if (bitset & 1) {
- switch (BUILTIN_TYPE(p)) {
- default: { /* majority case */
- gc_report(2, objspace, "page_sweep: free %s\n", obj_info((VALUE)p));
-#if USE_RGENGC && RGENGC_CHECK_MODE
- if (!is_full_marking(objspace)) {
- if (RVALUE_OLD_P((VALUE)p)) rb_bug("page_sweep: %s - old while minor GC.", obj_info((VALUE)p));
- if (rgengc_remembered(objspace, (VALUE)p)) rb_bug("page_sweep: %s - remembered.", obj_info((VALUE)p));
- }
-#endif
- if (obj_free(objspace, (VALUE)p)) {
- final_slots++;
- }
- else {
- (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
- heap_page_add_freeobj(objspace, sweep_page, (VALUE)p);
- gc_report(3, objspace, "page_sweep: %s is added to freelist\n", obj_info((VALUE)p));
- freed_slots++;
- }
- break;
- }
+ switch (BUILTIN_TYPE(vp)) {
+ default: /* majority case */
+ gc_report(2, objspace, "page_sweep: free %p\n", (void *)p);
+#if RGENGC_CHECK_MODE
+ if (!is_full_marking(objspace)) {
+ if (RVALUE_OLD_P(vp)) rb_bug("page_sweep: %p - old while minor GC.", (void *)p);
+ if (rgengc_remembered_sweep(objspace, vp)) rb_bug("page_sweep: %p - remembered.", (void *)p);
+ }
+#endif
+ if (obj_free(objspace, vp)) {
+ final_slots++;
+ }
+ else {
+ if (heap->compact_cursor) {
+ /* We *want* to fill this slot */
+ MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(vp), vp);
+ } else {
+ (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
+ heap_page_add_freeobj(objspace, sweep_page, vp);
+ gc_report(3, objspace, "page_sweep: %s is added to freelist\n", obj_info(vp));
+ freed_slots++;
+ }
+
+ }
+ break;
/* minor cases */
+ case T_MOVED:
+ if (objspace->flags.during_compacting) {
+ /* The sweep cursor shouldn't have made it to any
+ * T_MOVED slots while the compact flag is enabled.
+ * The sweep cursor and compact cursor move in
+ * opposite directions, and when they meet references will
+ * get updated and "during_compacting" should get disabled */
+ rb_bug("T_MOVED shouldn't be seen until compaction is finished\n");
+ }
+ gc_report(3, objspace, "page_sweep: %s is added to freelist\n", obj_info(vp));
+ if (FL_TEST(vp, FL_FROM_FREELIST)) {
+ empty_slots++;
+ } else {
+ freed_slots++;
+ }
+ heap_page_add_freeobj(objspace, sweep_page, vp);
+ break;
case T_ZOMBIE:
/* already counted */
break;
case T_NONE:
- empty_slots++; /* already freed */
+ if (heap->compact_cursor) {
+ /* We *want* to fill this slot */
+ MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(vp), vp);
+ } else {
+ /* When we started sweeping this page, we were in
+ * compacting mode and nulled the free list for
+ * the page. But compaction finished, so we need to
+ * put any T_NONE slots back on the freelist. */
+ if (was_compacting) {
+ heap_page_add_freeobj(objspace, sweep_page, vp);
+ }
+ empty_slots++; /* already freed */
+ }
break;
}
}
@@ -3548,7 +4949,15 @@ gc_page_sweep(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_
}
}
- gc_setup_mark_bits(sweep_page);
+ if (heap->compact_cursor) {
+ if (gc_fill_swept_page(objspace, heap, sweep_page, &freed_slots, &empty_slots)) {
+ gc_compact_finish(objspace, heap);
+ }
+ }
+
+ if (!heap->compact_cursor) {
+ gc_setup_mark_bits(sweep_page);
+ }
#if GC_PROFILE_MORE_DETAIL
if (gc_prof_enabled(objspace)) {
@@ -3557,15 +4966,13 @@ gc_page_sweep(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_
record->empty_objects += empty_slots;
}
#endif
- if (0) fprintf(stderr, "gc_page_sweep(%d): total_slots: %d, freed_slots: %d, empty_slots: %d, final_slots: %d\n",
- (int)rb_gc_count(),
- (int)sweep_page->total_slots,
+ if (0) fprintf(stderr, "gc_page_sweep(%"PRIdSIZE"): total_slots: %d, freed_slots: %d, empty_slots: %d, final_slots: %d\n",
+ rb_gc_count(),
+ sweep_page->total_slots,
freed_slots, empty_slots, final_slots);
sweep_page->free_slots = freed_slots + empty_slots;
objspace->profile.total_freed_objects += freed_slots;
- heap_pages_final_slots += final_slots;
- sweep_page->final_slots += final_slots;
if (heap_pages_deferred_final && !finalizing) {
rb_thread_t *th = GET_THREAD();
@@ -3621,21 +5028,17 @@ gc_mode_transition(rb_objspace_t *objspace, enum gc_mode mode)
static void
gc_sweep_start_heap(rb_objspace_t *objspace, rb_heap_t *heap)
{
- heap->sweep_pages = heap->pages;
+ heap->sweeping_page = list_top(&heap->pages, struct heap_page, page_node);
heap->free_pages = NULL;
#if GC_ENABLE_INCREMENTAL_MARK
heap->pooled_pages = NULL;
objspace->rincgc.pooled_slots = 0;
#endif
- if (heap->using_page) {
- RVALUE **p = &heap->using_page->freelist;
- while (*p) {
- p = &(*p)->as.free.next;
- }
- *p = heap->freelist;
- heap->using_page = NULL;
+
+ rb_ractor_t *r = NULL;
+ list_for_each(&GET_VM()->ractor.set, r, vmlr_node) {
+ rb_gc_ractor_newobj_cache_clear(&r->newobj_cache);
}
- heap->freelist = NULL;
}
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
@@ -3665,15 +5068,17 @@ gc_sweep_finish(rb_objspace_t *objspace)
gc_mode_transition(objspace, gc_mode_none);
#if RGENGC_CHECK_MODE >= 2
- gc_verify_internal_consistency(Qnil);
+ gc_verify_internal_consistency(objspace);
#endif
}
static int
gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
{
- struct heap_page *sweep_page = heap->sweep_pages;
+ struct heap_page *sweep_page = heap->sweeping_page;
int unlink_limit = 3;
+ int swept_slots = 0;
+
#if GC_ENABLE_INCREMENTAL_MARK
int need_pool = will_be_incremental_marking(objspace) ? TRUE : FALSE;
@@ -3688,9 +5093,10 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
gc_prof_sweep_timer_start(objspace);
#endif
- while (sweep_page) {
- struct heap_page *next_sweep_page = heap->sweep_pages = sweep_page->next;
+ do {
+ RUBY_DEBUG_LOG("sweep_page:%p", sweep_page);
int free_slots = gc_page_sweep(objspace, heap, sweep_page);
+ heap->sweeping_page = list_next(&heap->pages, sweep_page, page_node);
if (sweep_page->final_slots + free_slots == sweep_page->total_slots &&
heap_pages_freeable_pages > 0 &&
@@ -3704,27 +5110,26 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
else if (free_slots > 0) {
#if GC_ENABLE_INCREMENTAL_MARK
if (need_pool) {
- if (heap_add_poolpage(objspace, heap, sweep_page)) {
- need_pool = FALSE;
- }
+ heap_add_poolpage(objspace, heap, sweep_page);
+ need_pool = FALSE;
}
else {
- heap_add_freepage(objspace, heap, sweep_page);
- break;
+ heap_add_freepage(heap, sweep_page);
+ swept_slots += free_slots;
+ if (swept_slots > 2048) {
+ break;
+ }
}
#else
- heap_add_freepage(objspace, heap, sweep_page);
- break;
+ heap_add_freepage(heap, sweep_page);
#endif
}
else {
sweep_page->free_next = NULL;
}
+ } while ((sweep_page = heap->sweeping_page));
- sweep_page = next_sweep_page;
- }
-
- if (heap->sweep_pages == NULL) {
+ if (!heap->sweeping_page) {
gc_sweep_finish(objspace);
}
@@ -3732,6 +5137,8 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
gc_prof_sweep_timer_stop(objspace);
#endif
+ GC_ASSERT(gc_mode(objspace) == gc_mode_sweeping ? heap->free_pages != NULL : 1);
+
return heap->free_pages != NULL;
}
@@ -3745,22 +5152,96 @@ gc_sweep_rest(rb_objspace_t *objspace)
}
}
-#if GC_ENABLE_LAZY_SWEEP
static void
gc_sweep_continue(rb_objspace_t *objspace, rb_heap_t *heap)
{
- GC_ASSERT(dont_gc == FALSE);
+ GC_ASSERT(dont_gc_val() == FALSE);
+ if (!GC_ENABLE_LAZY_SWEEP) return;
- gc_enter(objspace, "sweep_continue");
-#if USE_RGENGC
- if (objspace->rgengc.need_major_gc == GPR_FLAG_NONE && heap_increment(objspace, heap)) {
- gc_report(3, objspace, "gc_sweep_continue: success heap_increment().\n");
- }
-#endif
+ unsigned int lock_lev;
+ gc_enter(objspace, gc_enter_event_sweep_continue, &lock_lev);
gc_sweep_step(objspace, heap);
- gc_exit(objspace, "sweep_continue");
+ gc_exit(objspace, gc_enter_event_sweep_continue, &lock_lev);
+}
+
+static void
+invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page)
+{
+ int i;
+ int empty_slots = 0, freed_slots = 0;
+ bits_t *mark_bits, *pin_bits;
+ bits_t bitset;
+ RVALUE *p, *offset;
+
+ mark_bits = page->mark_bits;
+ pin_bits = page->pinned_bits;
+
+ p = page->start;
+ offset = p - NUM_IN_PAGE(p);
+
+ for (i=0; i < HEAP_PAGE_BITMAP_LIMIT; i++) {
+ /* Moved objects are pinned but never marked. We reuse the pin bits
+ * to indicate there is a moved object in this slot. */
+ bitset = pin_bits[i] & ~mark_bits[i];
+
+ if (bitset) {
+ p = offset + i * BITS_BITLENGTH;
+ do {
+ if (bitset & 1) {
+ VALUE forwarding_object = (VALUE)p;
+ VALUE object;
+
+ if (BUILTIN_TYPE(forwarding_object) == T_MOVED) {
+ GC_ASSERT(MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(forwarding_object), forwarding_object));
+ GC_ASSERT(!MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(forwarding_object), forwarding_object));
+
+ CLEAR_IN_BITMAP(GET_HEAP_PINNED_BITS(forwarding_object), forwarding_object);
+
+ object = rb_gc_location(forwarding_object);
+
+ if (FL_TEST(forwarding_object, FL_FROM_FREELIST)) {
+ empty_slots++; /* already freed */
+ } else {
+ freed_slots++;
+ }
+
+ gc_move(objspace, object, forwarding_object);
+ /* forwarding_object is now our actual object, and "object"
+ * is the free slot for the original page */
+ heap_page_add_freeobj(objspace, GET_HEAP_PAGE(object), object);
+
+ GC_ASSERT(MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(forwarding_object), forwarding_object));
+ GC_ASSERT(BUILTIN_TYPE(forwarding_object) != T_MOVED);
+ GC_ASSERT(BUILTIN_TYPE(forwarding_object) != T_NONE);
+ }
+ }
+ p++;
+ bitset >>= 1;
+ } while (bitset);
+ }
+ }
+
+ page->free_slots += (empty_slots + freed_slots);
+ objspace->profile.total_freed_objects += freed_slots;
+}
+
+static void
+gc_compact_start(rb_objspace_t *objspace, rb_heap_t *heap)
+{
+ heap->compact_cursor = list_tail(&heap->pages, struct heap_page, page_node);
+ heap->compact_cursor_index = 0;
+
+ if (gc_prof_enabled(objspace)) {
+ gc_profile_record *record = gc_prof_record(objspace);
+ record->moved_objects = objspace->rcompactor.total_moved;
+ }
+
+ memset(objspace->rcompactor.considered_count_table, 0, T_MASK * sizeof(size_t));
+ memset(objspace->rcompactor.moved_count_table, 0, T_MASK * sizeof(size_t));
+
+ /* Set up read barrier for pages containing MOVED objects */
+ install_handlers();
}
-#endif
static void
gc_sweep(rb_objspace_t *objspace)
@@ -3774,19 +5255,32 @@ gc_sweep(rb_objspace_t *objspace)
gc_prof_sweep_timer_start(objspace);
#endif
gc_sweep_start(objspace);
+ if (objspace->flags.during_compacting) {
+ struct heap_page *page = NULL;
+
+ list_for_each(&heap_eden->pages, page, page_node) {
+ page->flags.before_sweep = TRUE;
+ }
+
+ gc_compact_start(objspace, heap_eden);
+ }
+
gc_sweep_rest(objspace);
#if !GC_ENABLE_LAZY_SWEEP
gc_prof_sweep_timer_stop(objspace);
#endif
}
else {
- struct heap_page *page;
+ struct heap_page *page = NULL;
gc_sweep_start(objspace);
- page = heap_eden->sweep_pages;
- while (page) {
- page->flags.before_sweep = TRUE;
- page = page->next;
- }
+
+ if (ruby_enable_autocompact && is_full_marking(objspace)) {
+ gc_compact_start(objspace, heap_eden);
+ }
+
+ list_for_each(&heap_eden->pages, page, page_node) {
+ page->flags.before_sweep = TRUE;
+ }
gc_sweep_step(objspace, heap_eden);
}
@@ -3898,6 +5392,22 @@ free_stack_chunks(mark_stack_t *stack)
static void
push_mark_stack(mark_stack_t *stack, VALUE data)
{
+ VALUE obj = data;
+ switch (BUILTIN_TYPE(obj)) {
+ case T_NIL:
+ case T_FIXNUM:
+ case T_MOVED:
+ rb_bug("push_mark_stack() called for broken object");
+ break;
+
+ case T_NODE:
+ UNEXPECTED_NODE(push_mark_stack);
+ break;
+
+ default:
+ break;
+ }
+
if (stack->index == stack->limit) {
push_mark_stack_chunk(stack);
}
@@ -3966,16 +5476,17 @@ init_mark_stack(mark_stack_t *stack)
/* Marking */
-#ifdef __ia64
-#define SET_STACK_END (SET_MACHINE_STACK_END(&ec->machine.stack_end), ec->machine.register_stack_end = rb_ia64_bsp())
-#else
#define SET_STACK_END SET_MACHINE_STACK_END(&ec->machine.stack_end)
-#endif
#define STACK_START (ec->machine.stack_start)
#define STACK_END (ec->machine.stack_end)
#define STACK_LEVEL_MAX (ec->machine.stack_maxsize/sizeof(VALUE))
+#ifdef __EMSCRIPTEN__
+#undef STACK_GROW_DIRECTION
+#define STACK_GROW_DIRECTION 1
+#endif
+
#if STACK_GROW_DIRECTION < 0
# define STACK_LENGTH (size_t)(STACK_START - STACK_END)
#elif STACK_GROW_DIRECTION > 0
@@ -4000,7 +5511,7 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
size_t
ruby_stack_length(VALUE **p)
{
- rb_execution_context_t *ec = &GET_THREAD()->ec;
+ rb_execution_context_t *ec = GET_EC();
SET_STACK_END;
if (p) *p = STACK_UPPER(STACK_END, STACK_START, STACK_END);
return STACK_LENGTH;
@@ -4016,46 +5527,41 @@ ruby_stack_length(VALUE **p)
#endif
#if PREVENT_STACK_OVERFLOW
static int
-stack_check(rb_thread_t *th, int water_mark)
+stack_check(rb_execution_context_t *ec, int water_mark)
{
- rb_execution_context_t *ec = &th->ec;
- int ret;
SET_STACK_END;
- ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
-#ifdef __ia64
- if (!ret) {
- ret = (VALUE*)rb_ia64_bsp() - ec->machine.register_stack_start >
- ec->machine.register_stack_maxsize/sizeof(VALUE) - water_mark;
- }
-#endif
- return ret;
+
+ size_t length = STACK_LENGTH;
+ size_t maximum_length = STACK_LEVEL_MAX - water_mark;
+
+ return length > maximum_length;
}
#else
-#define stack_check(th, water_mark) FALSE
+#define stack_check(ec, water_mark) FALSE
#endif
-#define STACKFRAME_FOR_CALL_CFUNC 838
+#define STACKFRAME_FOR_CALL_CFUNC 2048
-int
-rb_threadptr_stack_check(rb_thread_t *th)
+MJIT_FUNC_EXPORTED int
+rb_ec_stack_check(rb_execution_context_t *ec)
{
- return stack_check(th, STACKFRAME_FOR_CALL_CFUNC);
+ return stack_check(ec, STACKFRAME_FOR_CALL_CFUNC);
}
int
ruby_stack_check(void)
{
- return stack_check(GET_THREAD(), STACKFRAME_FOR_CALL_CFUNC);
+ return stack_check(GET_EC(), STACKFRAME_FOR_CALL_CFUNC);
}
-ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
+ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(static void mark_locations_array(rb_objspace_t *objspace, register const VALUE *x, register long n));
static void
mark_locations_array(rb_objspace_t *objspace, register const VALUE *x, register long n)
{
VALUE v;
while (n--) {
v = *x;
- gc_mark_maybe(objspace, v);
+ gc_mark_maybe(objspace, v);
x++;
}
}
@@ -4082,37 +5588,75 @@ gc_mark_values(rb_objspace_t *objspace, long n, const VALUE *values)
long i;
for (i=0; i<n; i++) {
- gc_mark(objspace, values[i]);
+ gc_mark(objspace, values[i]);
}
}
void
rb_gc_mark_values(long n, const VALUE *values)
{
+ long i;
+ rb_objspace_t *objspace = &rb_objspace;
+
+ for (i=0; i<n; i++) {
+ gc_mark_and_pin(objspace, values[i]);
+ }
+}
+
+static void
+gc_mark_stack_values(rb_objspace_t *objspace, long n, const VALUE *values)
+{
+ long i;
+
+ for (i=0; i<n; i++) {
+ if (is_markable_object(objspace, values[i])) {
+ gc_mark_and_pin(objspace, values[i]);
+ }
+ }
+}
+
+void
+rb_gc_mark_vm_stack_values(long n, const VALUE *values)
+{
rb_objspace_t *objspace = &rb_objspace;
- gc_mark_values(objspace, n, values);
+ gc_mark_stack_values(objspace, n, values);
}
static int
-mark_entry(st_data_t key, st_data_t value, st_data_t data)
+mark_value(st_data_t key, st_data_t value, st_data_t data)
{
rb_objspace_t *objspace = (rb_objspace_t *)data;
gc_mark(objspace, (VALUE)value);
return ST_CONTINUE;
}
+static int
+mark_value_pin(st_data_t key, st_data_t value, st_data_t data)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)data;
+ gc_mark_and_pin(objspace, (VALUE)value);
+ return ST_CONTINUE;
+}
+
+static void
+mark_tbl_no_pin(rb_objspace_t *objspace, st_table *tbl)
+{
+ if (!tbl || tbl->num_entries == 0) return;
+ st_foreach(tbl, mark_value, (st_data_t)objspace);
+}
+
static void
mark_tbl(rb_objspace_t *objspace, st_table *tbl)
{
if (!tbl || tbl->num_entries == 0) return;
- st_foreach(tbl, mark_entry, (st_data_t)objspace);
+ st_foreach(tbl, mark_value_pin, (st_data_t)objspace);
}
static int
mark_key(st_data_t key, st_data_t value, st_data_t data)
{
rb_objspace_t *objspace = (rb_objspace_t *)data;
- gc_mark(objspace, (VALUE)key);
+ gc_mark_and_pin(objspace, (VALUE)key);
return ST_CONTINUE;
}
@@ -4123,6 +5667,21 @@ mark_set(rb_objspace_t *objspace, st_table *tbl)
st_foreach(tbl, mark_key, (st_data_t)objspace);
}
+static int
+pin_value(st_data_t key, st_data_t value, st_data_t data)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)data;
+ gc_mark_and_pin(objspace, (VALUE)value);
+ return ST_CONTINUE;
+}
+
+static void
+mark_finalizer_tbl(rb_objspace_t *objspace, st_table *tbl)
+{
+ if (!tbl) return;
+ st_foreach(tbl, pin_value, (st_data_t)objspace);
+}
+
void
rb_mark_set(st_table *tbl)
{
@@ -4139,17 +5698,58 @@ mark_keyvalue(st_data_t key, st_data_t value, st_data_t data)
return ST_CONTINUE;
}
+static int
+pin_key_pin_value(st_data_t key, st_data_t value, st_data_t data)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)data;
+
+ gc_mark_and_pin(objspace, (VALUE)key);
+ gc_mark_and_pin(objspace, (VALUE)value);
+ return ST_CONTINUE;
+}
+
+static int
+pin_key_mark_value(st_data_t key, st_data_t value, st_data_t data)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)data;
+
+ gc_mark_and_pin(objspace, (VALUE)key);
+ gc_mark(objspace, (VALUE)value);
+ return ST_CONTINUE;
+}
+
static void
-mark_hash(rb_objspace_t *objspace, st_table *tbl)
+mark_hash(rb_objspace_t *objspace, VALUE hash)
+{
+ if (rb_hash_compare_by_id_p(hash)) {
+ rb_hash_stlike_foreach(hash, pin_key_mark_value, (st_data_t)objspace);
+ }
+ else {
+ rb_hash_stlike_foreach(hash, mark_keyvalue, (st_data_t)objspace);
+ }
+
+ if (RHASH_AR_TABLE_P(hash)) {
+ if (LIKELY(during_gc) && RHASH_TRANSIENT_P(hash)) {
+ rb_transient_heap_mark(hash, RHASH_AR_TABLE(hash));
+ }
+ }
+ else {
+ VM_ASSERT(!RHASH_TRANSIENT_P(hash));
+ }
+ gc_mark(objspace, RHASH(hash)->ifnone);
+}
+
+static void
+mark_st(rb_objspace_t *objspace, st_table *tbl)
{
if (!tbl) return;
- st_foreach(tbl, mark_keyvalue, (st_data_t)objspace);
+ st_foreach(tbl, pin_key_pin_value, (st_data_t)objspace);
}
void
rb_mark_hash(st_table *tbl)
{
- mark_hash(&rb_objspace, tbl);
+ mark_st(&rb_objspace, tbl);
}
static void
@@ -4171,7 +5771,8 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
gc_mark(objspace, def->body.attr.location);
break;
case VM_METHOD_TYPE_BMETHOD:
- gc_mark(objspace, def->body.proc);
+ gc_mark(objspace, def->body.bmethod.proc);
+ if (def->body.bmethod.hooks) rb_hook_list_mark(def->body.bmethod.hooks);
break;
case VM_METHOD_TYPE_ALIAS:
gc_mark(objspace, (VALUE)def->body.alias.original_me);
@@ -4249,6 +5850,7 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec
VALUE *stack_start, *stack_end;
FLUSH_REGISTER_WINDOWS;
+ memset(&save_regs_gc_mark, 0, sizeof(save_regs_gc_mark));
/* This assumes that all registers are saved into the jmp_buf (and stack) */
rb_setjmp(save_regs_gc_mark.j);
@@ -4279,11 +5881,7 @@ mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec,
{
gc_mark_locations(objspace, stack_start, stack_end);
-#ifdef __ia64
- gc_mark_locations(objspace,
- ec->machine.register_stack_start,
- ec->machine.register_stack_end);
-#endif
+
#if defined(__mc68000__)
gc_mark_locations(objspace,
(VALUE*)((char*)stack_start + 2),
@@ -4297,15 +5895,35 @@ rb_mark_tbl(st_table *tbl)
mark_tbl(&rb_objspace, tbl);
}
+void
+rb_mark_tbl_no_pin(st_table *tbl)
+{
+ mark_tbl_no_pin(&rb_objspace, tbl);
+}
+
static void
gc_mark_maybe(rb_objspace_t *objspace, VALUE obj)
{
(void)VALGRIND_MAKE_MEM_DEFINED(&obj, sizeof(obj));
+
if (is_pointer_to_heap(objspace, (void *)obj)) {
- int type = BUILTIN_TYPE(obj);
- if (type != T_ZOMBIE && type != T_NONE) {
- gc_mark_ptr(objspace, obj);
- }
+ void *ptr = __asan_region_is_poisoned((void *)obj, SIZEOF_VALUE);
+ asan_unpoison_object(obj, false);
+
+ /* Garbage can live on the stack, so do not mark or pin */
+ switch (BUILTIN_TYPE(obj)) {
+ case T_ZOMBIE:
+ case T_NONE:
+ break;
+ default:
+ gc_mark_and_pin(objspace, obj);
+ break;
+ }
+
+ if (ptr) {
+ GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE);
+ asan_poison_object(obj);
+ }
}
}
@@ -4318,12 +5936,12 @@ rb_gc_mark_maybe(VALUE obj)
static inline int
gc_mark_set(rb_objspace_t *objspace, VALUE obj)
{
+ ASSERT_vm_locking();
if (RVALUE_MARKED(obj)) return 0;
MARK_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj);
return 1;
}
-#if USE_RGENGC
static int
gc_remember_unprotected(rb_objspace_t *objspace, VALUE obj)
{
@@ -4347,12 +5965,10 @@ gc_remember_unprotected(rb_objspace_t *objspace, VALUE obj)
return FALSE;
}
}
-#endif
static void
rgengc_check_relation(rb_objspace_t *objspace, VALUE obj)
{
-#if USE_RGENGC
const VALUE old_parent = objspace->rgengc.parent_object;
if (old_parent) { /* parent object is old */
@@ -4385,7 +6001,6 @@ rgengc_check_relation(rb_objspace_t *objspace, VALUE obj)
}
GC_ASSERT(old_parent == objspace->rgengc.parent_object);
-#endif
}
static void
@@ -4408,7 +6023,6 @@ gc_grey(rb_objspace_t *objspace, VALUE obj)
static void
gc_aging(rb_objspace_t *objspace, VALUE obj)
{
-#if USE_RGENGC
struct heap_page *page = GET_HEAP_PAGE(obj);
GC_ASSERT(RVALUE_MARKING(obj) == FALSE);
@@ -4425,28 +6039,63 @@ gc_aging(rb_objspace_t *objspace, VALUE obj)
}
}
check_rvalue_consistency(obj);
-#endif /* USE_RGENGC */
objspace->marked_slots++;
}
NOINLINE(static void gc_mark_ptr(rb_objspace_t *objspace, VALUE obj));
+static void reachable_objects_from_callback(VALUE obj);
static void
gc_mark_ptr(rb_objspace_t *objspace, VALUE obj)
{
- if (LIKELY(objspace->mark_func_data == NULL)) {
+ if (LIKELY(during_gc)) {
rgengc_check_relation(objspace, obj);
if (!gc_mark_set(objspace, obj)) return; /* already marked */
+
+ if (0) { // for debug GC marking miss
+ if (objspace->rgengc.parent_object) {
+ RUBY_DEBUG_LOG("%p (%s) parent:%p (%s)",
+ (void *)obj, obj_type_name(obj),
+ (void *)objspace->rgengc.parent_object, obj_type_name(objspace->rgengc.parent_object));
+ }
+ else {
+ RUBY_DEBUG_LOG("%p (%s)", (void *)obj, obj_type_name(obj));
+ }
+ }
+
+ if (UNLIKELY(RB_TYPE_P(obj, T_NONE))) {
+ rp(obj);
+ rb_bug("try to mark T_NONE object"); /* check here will help debugging */
+ }
gc_aging(objspace, obj);
gc_grey(objspace, obj);
}
else {
- objspace->mark_func_data->mark_func(obj, objspace->mark_func_data->data);
+ reachable_objects_from_callback(obj);
}
}
static inline void
+gc_pin(rb_objspace_t *objspace, VALUE obj)
+{
+ GC_ASSERT(is_markable_object(objspace, obj));
+ if (UNLIKELY(objspace->flags.during_compacting)) {
+ if (LIKELY(during_gc)) {
+ MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj);
+ }
+ }
+}
+
+static inline void
+gc_mark_and_pin(rb_objspace_t *objspace, VALUE obj)
+{
+ if (!is_markable_object(objspace, obj)) return;
+ gc_pin(objspace, obj);
+ gc_mark_ptr(objspace, obj);
+}
+
+static inline void
gc_mark(rb_objspace_t *objspace, VALUE obj)
{
if (!is_markable_object(objspace, obj)) return;
@@ -4454,11 +6103,17 @@ gc_mark(rb_objspace_t *objspace, VALUE obj)
}
void
-rb_gc_mark(VALUE ptr)
+rb_gc_mark_movable(VALUE ptr)
{
gc_mark(&rb_objspace, ptr);
}
+void
+rb_gc_mark(VALUE ptr)
+{
+ gc_mark_and_pin(&rb_objspace, ptr);
+}
+
/* CAUTION: THIS FUNCTION ENABLE *ONLY BEFORE* SWEEPING.
* This function is only for GC_END_MARK timing.
*/
@@ -4472,14 +6127,12 @@ rb_objspace_marked_object_p(VALUE obj)
static inline void
gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
{
-#if USE_RGENGC
if (RVALUE_OLD_P(obj)) {
objspace->rgengc.parent_object = obj;
}
else {
objspace->rgengc.parent_object = Qfalse;
}
-#endif
}
static void
@@ -4489,11 +6142,16 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
case imemo_env:
{
const rb_env_t *env = (const rb_env_t *)obj;
- GC_ASSERT(VM_ENV_ESCAPED_P(env->ep));
- gc_mark_values(objspace, (long)env->env_size, env->env);
- VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
- gc_mark(objspace, (VALUE)rb_vm_env_prev_env(env));
- gc_mark(objspace, (VALUE)env->iseq);
+
+ if (LIKELY(env->ep)) {
+ // just after newobj() can be NULL here.
+ GC_ASSERT(env->ep[VM_ENV_DATA_INDEX_ENV] == obj);
+ GC_ASSERT(VM_ENV_ESCAPED_P(env->ep));
+ gc_mark_values(objspace, (long)env->env_size, env->env);
+ VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
+ gc_mark(objspace, (VALUE)rb_vm_env_prev_env(env));
+ gc_mark(objspace, (VALUE)env->iseq);
+ }
}
return;
case imemo_cref:
@@ -4524,6 +6182,35 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
case imemo_iseq:
rb_iseq_mark((rb_iseq_t *)obj);
return;
+ case imemo_tmpbuf:
+ {
+ const rb_imemo_tmpbuf_t *m = &RANY(obj)->as.imemo.alloc;
+ do {
+ rb_gc_mark_locations(m->ptr, m->ptr + m->cnt);
+ } while ((m = m->next) != NULL);
+ }
+ return;
+ case imemo_ast:
+ rb_ast_mark(&RANY(obj)->as.imemo.ast);
+ return;
+ case imemo_parser_strterm:
+ rb_strterm_mark(obj);
+ return;
+ case imemo_callinfo:
+ return;
+ case imemo_callcache:
+ {
+ const struct rb_callcache *cc = (const struct rb_callcache *)obj;
+ // should not mark klass here
+ gc_mark(objspace, (VALUE)vm_cc_cme(cc));
+ }
+ return;
+ case imemo_constcache:
+ {
+ const struct iseq_inline_constant_cache_entry *ice = (struct iseq_inline_constant_cache_entry *)obj;
+ gc_mark(objspace, ice->value);
+ }
+ return;
#if VM_CHECK_MODE > 0
default:
VM_UNREACHABLE(gc_mark_imemo);
@@ -4542,19 +6229,28 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
}
switch (BUILTIN_TYPE(obj)) {
+ case T_FLOAT:
+ case T_BIGNUM:
+ case T_SYMBOL:
+ /* Not immediates, but does not have references and singleton
+ * class */
+ return;
+
case T_NIL:
case T_FIXNUM:
rb_bug("rb_gc_mark() called for broken object");
break;
case T_NODE:
- obj = rb_gc_mark_node(&any->as.node);
- if (obj) gc_mark(objspace, obj);
- return; /* no need to mark class. */
+ UNEXPECTED_NODE(rb_gc_mark);
+ break;
case T_IMEMO:
gc_mark_imemo(objspace, obj);
return;
+
+ default:
+ break;
}
gc_mark(objspace, any->as.basic.klass);
@@ -4562,38 +6258,52 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
case T_MODULE:
- mark_m_tbl(objspace, RCLASS_M_TBL(obj));
+ if (RCLASS_SUPER(obj)) {
+ gc_mark(objspace, RCLASS_SUPER(obj));
+ }
if (!RCLASS_EXT(obj)) break;
- mark_tbl(objspace, RCLASS_IV_TBL(obj));
+
+ mark_m_tbl(objspace, RCLASS_M_TBL(obj));
+ cc_table_mark(objspace, obj);
+ mark_tbl_no_pin(objspace, RCLASS_IV_TBL(obj));
mark_const_tbl(objspace, RCLASS_CONST_TBL(obj));
- gc_mark(objspace, RCLASS_SUPER((VALUE)obj));
break;
case T_ICLASS:
- if (FL_TEST(obj, RICLASS_IS_ORIGIN)) {
+ if (RICLASS_OWNS_M_TBL_P(obj)) {
mark_m_tbl(objspace, RCLASS_M_TBL(obj));
}
+ if (RCLASS_SUPER(obj)) {
+ gc_mark(objspace, RCLASS_SUPER(obj));
+ }
if (!RCLASS_EXT(obj)) break;
mark_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
- gc_mark(objspace, RCLASS_SUPER((VALUE)obj));
+ cc_table_mark(objspace, obj);
break;
case T_ARRAY:
- if (FL_TEST(obj, ELTS_SHARED)) {
- gc_mark(objspace, any->as.array.as.heap.aux.shared);
+ if (FL_TEST(obj, ELTS_SHARED)) {
+ VALUE root = any->as.array.as.heap.aux.shared_root;
+ gc_mark(objspace, root);
}
else {
long i, len = RARRAY_LEN(obj);
- const VALUE *ptr = RARRAY_CONST_PTR(obj);
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(obj);
for (i=0; i < len; i++) {
- gc_mark(objspace, *ptr++);
+ gc_mark(objspace, ptr[i]);
}
- }
+
+ if (LIKELY(during_gc)) {
+ if (!FL_TEST_RAW(obj, RARRAY_EMBED_FLAG) &&
+ RARRAY_TRANSIENT_P(obj)) {
+ rb_transient_heap_mark(obj, ptr);
+ }
+ }
+ }
break;
case T_HASH:
- mark_hash(objspace, any->as.hash.ntbl);
- gc_mark(objspace, any->as.hash.ifnone);
+ mark_hash(objspace, obj);
break;
case T_STRING:
@@ -4616,16 +6326,23 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
case T_OBJECT:
{
+ const VALUE * const ptr = ROBJECT_IVPTR(obj);
+
uint32_t i, len = ROBJECT_NUMIV(obj);
- VALUE *ptr = ROBJECT_IVPTR(obj);
for (i = 0; i < len; i++) {
- gc_mark(objspace, *ptr++);
+ gc_mark(objspace, ptr[i]);
+ }
+
+ if (LIKELY(during_gc) &&
+ ROBJ_TRANSIENT_P(obj)) {
+ rb_transient_heap_mark(obj, ptr);
}
}
break;
case T_FILE:
if (any->as.file.fptr) {
+ gc_mark(objspace, any->as.file.fptr->self);
gc_mark(objspace, any->as.file.fptr->pathv);
gc_mark(objspace, any->as.file.fptr->tied_io_for_writing);
gc_mark(objspace, any->as.file.fptr->writeconv_asciicompat);
@@ -4639,11 +6356,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
gc_mark(objspace, any->as.regexp.src);
break;
- case T_FLOAT:
- case T_BIGNUM:
- case T_SYMBOL:
- break;
-
case T_MATCH:
gc_mark(objspace, any->as.match.regexp);
if (any->as.match.str) {
@@ -4663,12 +6375,18 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
case T_STRUCT:
{
- long len = RSTRUCT_LEN(obj);
- const VALUE *ptr = RSTRUCT_CONST_PTR(obj);
+ long i;
+ const long len = RSTRUCT_LEN(obj);
+ const VALUE * const ptr = RSTRUCT_CONST_PTR(obj);
- while (len--) {
- gc_mark(objspace, *ptr++);
- }
+ for (i=0; i<len; i++) {
+ gc_mark(objspace, ptr[i]);
+ }
+
+ if (LIKELY(during_gc) &&
+ RSTRUCT_TRANSIENT_P(obj)) {
+ rb_transient_heap_mark(obj, ptr);
+ }
}
break;
@@ -4676,10 +6394,11 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
#if GC_DEBUG
rb_gcdebug_print_obj_condition((VALUE)obj);
#endif
+ if (BUILTIN_TYPE(obj) == T_MOVED) rb_bug("rb_gc_mark(): %p is T_MOVED", (void *)obj);
if (BUILTIN_TYPE(obj) == T_NONE) rb_bug("rb_gc_mark(): %p is T_NONE", (void *)obj);
if (BUILTIN_TYPE(obj) == T_ZOMBIE) rb_bug("rb_gc_mark(): %p is T_ZOMBIE", (void *)obj);
rb_bug("rb_gc_mark(): unknown data type 0x%x(%p) %s",
- BUILTIN_TYPE(obj), any,
+ BUILTIN_TYPE(obj), (void *)any,
is_pointer_to_heap(objspace, any) ? "corrupted object" : "non object");
}
}
@@ -4724,7 +6443,7 @@ gc_mark_stacked_objects(rb_objspace_t *objspace, int incremental, size_t count)
#endif
}
- if (RGENGC_CHECK_MODE >= 3) gc_verify_internal_consistency(Qnil);
+ if (RGENGC_CHECK_MODE >= 3) gc_verify_internal_consistency(objspace);
if (is_mark_stack_empty(mstack)) {
shrink_stack_chunk_cache(mstack);
@@ -4768,14 +6487,14 @@ show_mark_ticks(void)
}
}
-#endif /* PRITNT_ROOT_TICKS */
+#endif /* PRINT_ROOT_TICKS */
static void
gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
{
struct gc_list *list;
- rb_thread_t *th = GET_THREAD();
- rb_execution_context_t *ec = &th->ec;
+ rb_execution_context_t *ec = GET_EC();
+ rb_vm_t *vm = rb_ec_vm_ptr(ec);
#if PRINT_ROOT_TICKS
tick_t start_tick = tick();
@@ -4789,9 +6508,7 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
if (categoryp) *categoryp = "xxx";
-#if USE_RGENGC
objspace->rgengc.parent_object = Qfalse;
-#endif
#if PRINT_ROOT_TICKS
#define MARK_CHECKPOINT_PRINT_TICK(category) do { \
@@ -4804,7 +6521,7 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
prev_category = category; \
start_tick = tick(); \
} while (0)
-#else /* PRITNT_ROOT_TICKS */
+#else /* PRINT_ROOT_TICKS */
#define MARK_CHECKPOINT_PRINT_TICK(category)
#endif
@@ -4815,22 +6532,19 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
MARK_CHECKPOINT("vm");
SET_STACK_END;
- rb_vm_mark(th->vm);
- if (th->vm->self) gc_mark(objspace, th->vm->self);
+ rb_vm_mark(vm);
+ if (vm->self) gc_mark(objspace, vm->self);
MARK_CHECKPOINT("finalizers");
- mark_tbl(objspace, finalizer_table);
+ mark_finalizer_tbl(objspace, finalizer_table);
MARK_CHECKPOINT("machine_context");
- mark_current_machine_context(objspace, &th->ec);
-
- MARK_CHECKPOINT("encodings");
- rb_gc_mark_encodings();
+ mark_current_machine_context(objspace, ec);
/* mark protected global variables */
MARK_CHECKPOINT("global_list");
for (list = global_list; list; list = list->next) {
- rb_gc_mark_maybe(*list->varptr);
+ gc_mark_maybe(objspace, *list->varptr);
}
MARK_CHECKPOINT("end_proc");
@@ -4839,6 +6553,10 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
MARK_CHECKPOINT("global_tbl");
rb_gc_mark_global_tbl();
+ MARK_CHECKPOINT("object_id");
+ rb_gc_mark(objspace->next_object_id);
+ mark_tbl_no_pin(objspace, objspace->obj_to_id_tbl); /* Only mark ids */
+
if (stress_to_class) rb_gc_mark(stress_to_class);
MARK_CHECKPOINT("finish");
@@ -4903,7 +6621,7 @@ reflist_dump(struct reflist *refs)
}
static int
-reflist_refered_from_machine_context(struct reflist *refs)
+reflist_referred_from_machine_context(struct reflist *refs)
{
int i;
for (i=0; i<refs->pos; i++) {
@@ -4932,8 +6650,10 @@ static int
allrefs_add(struct allrefs *data, VALUE obj)
{
struct reflist *refs;
+ st_data_t r;
- if (st_lookup(data->references, obj, (st_data_t *)&refs)) {
+ if (st_lookup(data->references, obj, &r)) {
+ refs = (struct reflist *)r;
reflist_add(refs, data->root_obj);
return 0;
}
@@ -4972,8 +6692,8 @@ objspace_allrefs(rb_objspace_t *objspace)
struct allrefs data;
struct mark_func_data_struct mfd;
VALUE obj;
- int prev_dont_gc = dont_gc;
- dont_gc = TRUE;
+ int prev_dont_gc = dont_gc_val();
+ dont_gc_on();
data.objspace = objspace;
data.references = st_init_numtable();
@@ -4994,12 +6714,12 @@ objspace_allrefs(rb_objspace_t *objspace)
}
free_stack_chunks(&data.mark_stack);
- dont_gc = prev_dont_gc;
+ dont_gc_set(prev_dont_gc);
return data.references;
}
static int
-objspace_allrefs_destruct_i(st_data_t key, st_data_t value, void *ptr)
+objspace_allrefs_destruct_i(st_data_t key, st_data_t value, st_data_t ptr)
{
struct reflist *refs = (struct reflist *)value;
reflist_destruct(refs);
@@ -5028,13 +6748,14 @@ allrefs_dump_i(st_data_t k, st_data_t v, st_data_t ptr)
static void
allrefs_dump(rb_objspace_t *objspace)
{
- fprintf(stderr, "[all refs] (size: %d)\n", (int)objspace->rgengc.allrefs_table->num_entries);
+ VALUE size = objspace->rgengc.allrefs_table->num_entries;
+ fprintf(stderr, "[all refs] (size: %"PRIuVALUE")\n", size);
st_foreach(objspace->rgengc.allrefs_table, allrefs_dump_i, 0);
}
#endif
static int
-gc_check_after_marks_i(st_data_t k, st_data_t v, void *ptr)
+gc_check_after_marks_i(st_data_t k, st_data_t v, st_data_t ptr)
{
VALUE obj = k;
struct reflist *refs = (struct reflist *)v;
@@ -5046,7 +6767,7 @@ gc_check_after_marks_i(st_data_t k, st_data_t v, void *ptr)
fprintf(stderr, "gc_check_after_marks_i: %p is referred from ", (void *)obj);
reflist_dump(refs);
- if (reflist_refered_from_machine_context(refs)) {
+ if (reflist_referred_from_machine_context(refs)) {
fprintf(stderr, " (marked from machine stack).\n");
/* marked from machine context can be false positive */
}
@@ -5059,13 +6780,13 @@ gc_check_after_marks_i(st_data_t k, st_data_t v, void *ptr)
}
static void
-gc_marks_check(rb_objspace_t *objspace, int (*checker_func)(ANYARGS), const char *checker_name)
+gc_marks_check(rb_objspace_t *objspace, st_foreach_callback_func *checker_func, const char *checker_name)
{
size_t saved_malloc_increase = objspace->malloc_params.increase;
#if RGENGC_ESTIMATE_OLDMALLOC
size_t saved_oldmalloc_increase = objspace->rgengc.oldmalloc_increase;
#endif
- VALUE already_disabled = rb_gc_disable();
+ VALUE already_disabled = rb_objspace_gc_disable(objspace);
objspace->rgengc.allrefs_table = objspace_allrefs(objspace);
@@ -5083,7 +6804,7 @@ gc_marks_check(rb_objspace_t *objspace, int (*checker_func)(ANYARGS), const char
objspace_allrefs_destruct(objspace->rgengc.allrefs_table);
objspace->rgengc.allrefs_table = 0;
- if (already_disabled == Qfalse) rb_gc_enable();
+ if (already_disabled == Qfalse) rb_objspace_gc_enable(objspace);
objspace->malloc_params.increase = saved_malloc_increase;
#if RGENGC_ESTIMATE_OLDMALLOC
objspace->rgengc.oldmalloc_increase = saved_oldmalloc_increase;
@@ -5097,14 +6818,11 @@ struct verify_internal_consistency_struct {
size_t live_object_count;
size_t zombie_object_count;
-#if USE_RGENGC
VALUE parent;
size_t old_object_count;
size_t remembered_shady_count;
-#endif
};
-#if USE_RGENGC
static void
check_generation_i(const VALUE child, void *ptr)
{
@@ -5135,12 +6853,18 @@ check_color_i(const VALUE child, void *ptr)
data->err_count++;
}
}
-#endif
static void
check_children_i(const VALUE child, void *ptr)
{
- check_rvalue_consistency(child);
+ struct verify_internal_consistency_struct *data = (struct verify_internal_consistency_struct *)ptr;
+ if (check_rvalue_consistency_force(child, FALSE) != 0) {
+ fprintf(stderr, "check_children_i: %s has error (referenced from %s)",
+ obj_info(child), obj_info(data->parent));
+ rb_print_backtrace(); /* C backtrace will help to debug */
+
+ data->err_count++;
+ }
}
static int
@@ -5151,16 +6875,22 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride, v
rb_objspace_t *objspace = data->objspace;
for (obj = (VALUE)page_start; obj != (VALUE)page_end; obj += stride) {
+ void *poisoned = asan_poisoned_object_p(obj);
+ asan_unpoison_object(obj, false);
+
if (is_live_object(objspace, obj)) {
/* count objects */
data->live_object_count++;
+ data->parent = obj;
- rb_objspace_reachable_objects_from(obj, check_children_i, (void *)data);
+ /* Normally, we don't expect T_MOVED objects to be in the heap.
+ * But they can stay alive on the stack, */
+ if (!gc_object_moved_p(objspace, obj)) {
+ /* moved slots don't have children */
+ rb_objspace_reachable_objects_from(obj, check_children_i, (void *)data);
+ }
-#if USE_RGENGC
/* check health of children */
- data->parent = obj;
-
if (RVALUE_OLD_P(obj)) data->old_object_count++;
if (RVALUE_WB_UNPROTECTED(obj) && RVALUE_UNCOLLECTIBLE(obj)) data->remembered_shady_count++;
@@ -5177,14 +6907,17 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride, v
rb_objspace_reachable_objects_from(obj, check_color_i, (void *)data);
}
}
-#endif
}
else {
if (BUILTIN_TYPE(obj) == T_ZOMBIE) {
- GC_ASSERT(RBASIC(obj)->flags == T_ZOMBIE);
+ GC_ASSERT((RBASIC(obj)->flags & ~FL_SEEN_OBJ_ID) == T_ZOMBIE);
data->zombie_object_count++;
}
}
+ if (poisoned) {
+ GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE);
+ asan_poison_object(obj);
+ }
}
return 0;
@@ -5193,81 +6926,101 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride, v
static int
gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj)
{
-#if USE_RGENGC
int i;
unsigned int has_remembered_shady = FALSE;
unsigned int has_remembered_old = FALSE;
- int rememberd_old_objects = 0;
+ int remembered_old_objects = 0;
int free_objects = 0;
int zombie_objects = 0;
for (i=0; i<page->total_slots; i++) {
- VALUE obj = (VALUE)&page->start[i];
- if (RBASIC(obj) == 0) free_objects++;
- if (BUILTIN_TYPE(obj) == T_ZOMBIE) zombie_objects++;
- if (RVALUE_PAGE_UNCOLLECTIBLE(page, obj) && RVALUE_PAGE_WB_UNPROTECTED(page, obj)) has_remembered_shady = TRUE;
- if (RVALUE_PAGE_MARKING(page, obj)) {
+ VALUE val = (VALUE)&page->start[i];
+ void *poisoned = asan_poisoned_object_p(val);
+ asan_unpoison_object(val, false);
+
+ if (RBASIC(val) == 0) free_objects++;
+ if (BUILTIN_TYPE(val) == T_ZOMBIE) zombie_objects++;
+ if (RVALUE_PAGE_UNCOLLECTIBLE(page, val) && RVALUE_PAGE_WB_UNPROTECTED(page, val)) {
+ has_remembered_shady = TRUE;
+ }
+ if (RVALUE_PAGE_MARKING(page, val)) {
has_remembered_old = TRUE;
- rememberd_old_objects++;
+ remembered_old_objects++;
}
+
+ if (poisoned) {
+ GC_ASSERT(BUILTIN_TYPE(val) == T_NONE);
+ asan_poison_object(val);
+ }
}
if (!is_incremental_marking(objspace) &&
page->flags.has_remembered_objects == FALSE && has_remembered_old == TRUE) {
for (i=0; i<page->total_slots; i++) {
- VALUE obj = (VALUE)&page->start[i];
- if (RVALUE_PAGE_MARKING(page, obj)) {
- fprintf(stderr, "marking -> %s\n", obj_info(obj));
+ VALUE val = (VALUE)&page->start[i];
+ if (RVALUE_PAGE_MARKING(page, val)) {
+ fprintf(stderr, "marking -> %s\n", obj_info(val));
}
}
rb_bug("page %p's has_remembered_objects should be false, but there are remembered old objects (%d). %s",
- page, rememberd_old_objects, obj ? obj_info(obj) : "");
+ (void *)page, remembered_old_objects, obj ? obj_info(obj) : "");
}
if (page->flags.has_uncollectible_shady_objects == FALSE && has_remembered_shady == TRUE) {
rb_bug("page %p's has_remembered_shady should be false, but there are remembered shady objects. %s",
- page, obj ? obj_info(obj) : "");
+ (void *)page, obj ? obj_info(obj) : "");
}
if (0) {
/* free_slots may not equal to free_objects */
if (page->free_slots != free_objects) {
- rb_bug("page %p's free_slots should be %d, but %d\n", page, (int)page->free_slots, free_objects);
+ rb_bug("page %p's free_slots should be %d, but %d\n", (void *)page, page->free_slots, free_objects);
}
}
if (page->final_slots != zombie_objects) {
- rb_bug("page %p's final_slots should be %d, but %d\n", page, (int)page->final_slots, zombie_objects);
+ rb_bug("page %p's final_slots should be %d, but %d\n", (void *)page, page->final_slots, zombie_objects);
}
- return rememberd_old_objects;
-#else
- return 0;
-#endif
+ return remembered_old_objects;
}
static int
-gc_verify_heap_pages_(rb_objspace_t *objspace, struct heap_page *page)
-{
- int rememberd_old_objects = 0;
+gc_verify_heap_pages_(rb_objspace_t *objspace, struct list_head *head)
+{
+ int remembered_old_objects = 0;
+ struct heap_page *page = 0;
+
+ list_for_each(head, page, page_node) {
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
+ RVALUE *p = page->freelist;
+ while (p) {
+ VALUE vp = (VALUE)p;
+ VALUE prev = vp;
+ asan_unpoison_object(vp, false);
+ if (BUILTIN_TYPE(vp) != T_NONE) {
+ fprintf(stderr, "freelist slot expected to be T_NONE but was: %s\n", obj_info(vp));
+ }
+ p = p->as.free.next;
+ asan_poison_object(prev);
+ }
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
- while (page) {
if (page->flags.has_remembered_objects == FALSE) {
- rememberd_old_objects += gc_verify_heap_page(objspace, page, Qfalse);
+ remembered_old_objects += gc_verify_heap_page(objspace, page, Qfalse);
}
- page = page->next;
}
- return rememberd_old_objects;
+ return remembered_old_objects;
}
static int
gc_verify_heap_pages(rb_objspace_t *objspace)
{
- int rememberd_old_objects = 0;
- rememberd_old_objects = gc_verify_heap_pages_(objspace, heap_eden->pages);
- rememberd_old_objects = gc_verify_heap_pages_(objspace, heap_tomb->pages);
- return rememberd_old_objects;
+ int remembered_old_objects = 0;
+ remembered_old_objects += gc_verify_heap_pages_(objspace, &heap_eden->pages);
+ remembered_old_objects += gc_verify_heap_pages_(objspace, &heap_tomb->pages);
+ return remembered_old_objects;
}
/*
@@ -5281,20 +7034,23 @@ gc_verify_heap_pages(rb_objspace_t *objspace)
* if RGenGC is supported.
*/
static VALUE
-gc_verify_internal_consistency(VALUE dummy)
+gc_verify_internal_consistency_m(VALUE dummy)
+{
+ gc_verify_internal_consistency(&rb_objspace);
+ return Qnil;
+}
+
+static void
+gc_verify_internal_consistency_(rb_objspace_t *objspace)
{
- rb_objspace_t *objspace = &rb_objspace;
struct verify_internal_consistency_struct data = {0};
- struct each_obj_args eo_args;
data.objspace = objspace;
gc_report(5, objspace, "gc_verify_internal_consistency: start\n");
/* check relations */
- eo_args.callback = verify_internal_consistency_i;
- eo_args.data = (void *)&data;
- objspace_each_objects((VALUE)&eo_args);
+ objspace_each_objects_without_setup(objspace, verify_internal_consistency_i, &data);
if (data.err_count != 0) {
#if RGENGC_CHECK_MODE >= 5
@@ -5310,24 +7066,28 @@ gc_verify_internal_consistency(VALUE dummy)
/* check counters */
- if (!is_lazy_sweeping(heap_eden) && !finalizing) {
+ if (!is_lazy_sweeping(heap_eden) &&
+ !finalizing &&
+ ruby_single_main_ractor != NULL) {
if (objspace_live_slots(objspace) != data.live_object_count) {
- fprintf(stderr, "heap_pages_final_slots: %d, objspace->profile.total_freed_objects: %d\n",
- (int)heap_pages_final_slots, (int)objspace->profile.total_freed_objects);
- rb_bug("inconsistent live slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace_live_slots(objspace), data.live_object_count);
+ fprintf(stderr, "heap_pages_final_slots: %"PRIdSIZE", "
+ "objspace->profile.total_freed_objects: %"PRIdSIZE"\n",
+ heap_pages_final_slots, objspace->profile.total_freed_objects);
+ rb_bug("inconsistent live slot number: expect %"PRIuSIZE", but %"PRIuSIZE".",
+ objspace_live_slots(objspace), data.live_object_count);
}
}
-#if USE_RGENGC
if (!is_marking(objspace)) {
if (objspace->rgengc.old_objects != data.old_object_count) {
- rb_bug("inconsistent old slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.old_objects, data.old_object_count);
+ rb_bug("inconsistent old slot number: expect %"PRIuSIZE", but %"PRIuSIZE".",
+ objspace->rgengc.old_objects, data.old_object_count);
}
if (objspace->rgengc.uncollectible_wb_unprotected_objects != data.remembered_shady_count) {
- rb_bug("inconsistent old slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.uncollectible_wb_unprotected_objects, data.remembered_shady_count);
+ rb_bug("inconsistent number of wb unprotected objects: expect %"PRIuSIZE", but %"PRIuSIZE".",
+ objspace->rgengc.uncollectible_wb_unprotected_objects, data.remembered_shady_count);
}
}
-#endif
if (!finalizing) {
size_t list_count = 0;
@@ -5354,14 +7114,36 @@ gc_verify_internal_consistency(VALUE dummy)
}
gc_report(5, objspace, "gc_verify_internal_consistency: OK\n");
+}
- return Qnil;
+static void
+gc_verify_internal_consistency(rb_objspace_t *objspace)
+{
+ RB_VM_LOCK_ENTER();
+ {
+ rb_vm_barrier(); // stop other ractors
+
+ unsigned int prev_during_gc = during_gc;
+ during_gc = FALSE; // stop gc here
+ {
+ gc_verify_internal_consistency_(objspace);
+ }
+ during_gc = prev_during_gc;
+ }
+ RB_VM_LOCK_LEAVE();
}
void
rb_gc_verify_internal_consistency(void)
{
- gc_verify_internal_consistency(Qnil);
+ gc_verify_internal_consistency(&rb_objspace);
+}
+
+static VALUE
+gc_verify_transient_heap_internal_consistency(VALUE dmy)
+{
+ rb_transient_heap_verify();
+ return Qnil;
}
/* marks */
@@ -5373,15 +7155,19 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
gc_report(1, objspace, "gc_marks_start: (%s)\n", full_mark ? "full" : "minor");
gc_mode_transition(objspace, gc_mode_marking);
-#if USE_RGENGC
if (full_mark) {
#if GC_ENABLE_INCREMENTAL_MARK
objspace->rincgc.step_slots = (objspace->marked_slots * 2) / ((objspace->rincgc.pooled_slots / HEAP_PAGE_OBJ_LIMIT) + 1);
- if (0) fprintf(stderr, "objspace->marked_slots: %d, objspace->rincgc.pooled_page_num: %d, objspace->rincgc.step_slots: %d, \n",
- (int)objspace->marked_slots, (int)objspace->rincgc.pooled_slots, (int)objspace->rincgc.step_slots);
+ if (0) fprintf(stderr, "objspace->marked_slots: %"PRIdSIZE", "
+ "objspace->rincgc.pooled_page_num: %"PRIdSIZE", "
+ "objspace->rincgc.step_slots: %"PRIdSIZE", \n",
+ objspace->marked_slots, objspace->rincgc.pooled_slots, objspace->rincgc.step_slots);
#endif
objspace->flags.during_minor_gc = FALSE;
+ if (ruby_enable_autocompact) {
+ objspace->flags.during_compacting |= TRUE;
+ }
objspace->profile.major_gc_count++;
objspace->rgengc.uncollectible_wb_unprotected_objects = 0;
objspace->rgengc.old_objects = 0;
@@ -5396,20 +7182,20 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
objspace->profile.minor_gc_count++;
rgengc_rememberset_mark(objspace, heap_eden);
}
-#endif
gc_mark_roots(objspace, NULL);
- gc_report(1, objspace, "gc_marks_start: (%s) end, stack in %d\n", full_mark ? "full" : "minor", (int)mark_stack_size(&objspace->mark_stack));
+ gc_report(1, objspace, "gc_marks_start: (%s) end, stack in %"PRIdSIZE"\n",
+ full_mark ? "full" : "minor", mark_stack_size(&objspace->mark_stack));
}
#if GC_ENABLE_INCREMENTAL_MARK
static void
gc_marks_wb_unprotected_objects(rb_objspace_t *objspace)
{
- struct heap_page *page = heap_eden->pages;
+ struct heap_page *page = 0;
- while (page) {
+ list_for_each(&heap_eden->pages, page, page_node) {
bits_t *mark_bits = page->mark_bits;
bits_t *wbun_bits = page->wb_unprotected_bits;
RVALUE *p = page->start;
@@ -5434,8 +7220,6 @@ gc_marks_wb_unprotected_objects(rb_objspace_t *objspace)
} while (bits);
}
}
-
- page = page->next;
}
gc_mark_stacked_objects_all(objspace);
@@ -5448,8 +7232,7 @@ heap_move_pooled_pages_to_free_pages(rb_heap_t *heap)
if (page) {
heap->pooled_pages = page->free_next;
- page->free_next = heap->free_pages;
- heap->free_pages = page;
+ heap_add_freepage(heap, page);
}
return page;
@@ -5469,13 +7252,15 @@ gc_marks_finish(rb_objspace_t *objspace)
}
if (RGENGC_CHECK_MODE && is_mark_stack_empty(&objspace->mark_stack) == 0) {
- rb_bug("gc_marks_finish: mark stack is not empty (%d).", (int)mark_stack_size(&objspace->mark_stack));
+ rb_bug("gc_marks_finish: mark stack is not empty (%"PRIdSIZE").",
+ mark_stack_size(&objspace->mark_stack));
}
gc_mark_roots(objspace, 0);
if (is_mark_stack_empty(&objspace->mark_stack) == FALSE) {
- gc_report(1, objspace, "gc_marks_finish: not empty (%d). retry.\n", (int)mark_stack_size(&objspace->mark_stack));
+ gc_report(1, objspace, "gc_marks_finish: not empty (%"PRIdSIZE"). retry.\n",
+ mark_stack_size(&objspace->mark_stack));
return FALSE;
}
@@ -5492,17 +7277,15 @@ gc_marks_finish(rb_objspace_t *objspace)
#endif /* GC_ENABLE_INCREMENTAL_MARK */
#if RGENGC_CHECK_MODE >= 2
- gc_verify_internal_consistency(Qnil);
+ gc_verify_internal_consistency(objspace);
#endif
-#if USE_RGENGC
if (is_full_marking(objspace)) {
/* See the comment about RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR */
const double r = gc_params.oldobject_limit_factor;
objspace->rgengc.uncollectible_wb_unprotected_objects_limit = (size_t)(objspace->rgengc.uncollectible_wb_unprotected_objects * r);
objspace->rgengc.old_objects_limit = (size_t)(objspace->rgengc.old_objects * r);
}
-#endif
#if RGENGC_CHECK_MODE >= 4
gc_marks_check(objspace, gc_check_after_marks_i, "after_marks");
@@ -5516,11 +7299,15 @@ gc_marks_finish(rb_objspace_t *objspace)
size_t max_free_slots = (size_t)(total_slots * gc_params.heap_free_slots_max_ratio);
size_t min_free_slots = (size_t)(total_slots * gc_params.heap_free_slots_min_ratio);
int full_marking = is_full_marking(objspace);
+ const int r_cnt = GET_VM()->ractor.cnt;
+ const int r_mul = r_cnt > 8 ? 8 : r_cnt; // upto 8
GC_ASSERT(heap->total_slots >= objspace->marked_slots);
/* setup free-able page counts */
- if (max_free_slots < gc_params.heap_init_slots) max_free_slots = gc_params.heap_init_slots;
+ if (max_free_slots < gc_params.heap_init_slots * r_mul) {
+ max_free_slots = gc_params.heap_init_slots * r_mul;
+ }
if (sweep_slots > max_free_slots) {
heap_pages_freeable_pages = (sweep_slots - max_free_slots) / HEAP_PAGE_OBJ_LIMIT;
@@ -5529,24 +7316,25 @@ gc_marks_finish(rb_objspace_t *objspace)
heap_pages_freeable_pages = 0;
}
- /* check free_min */
- if (min_free_slots < gc_params.heap_free_slots) min_free_slots = gc_params.heap_free_slots;
+ /* check free_min */
+ if (min_free_slots < gc_params.heap_free_slots * r_mul) {
+ min_free_slots = gc_params.heap_free_slots * r_mul;
+ }
-#if USE_RGENGC
if (sweep_slots < min_free_slots) {
if (!full_marking) {
if (objspace->profile.count - objspace->rgengc.last_major_gc < RVALUE_OLD_AGE) {
full_marking = TRUE;
/* do not update last_major_gc, because full marking is not done. */
- goto increment;
+ /* goto increment; */
}
else {
gc_report(1, objspace, "gc_marks_finish: next is full GC!!)\n");
objspace->rgengc.need_major_gc |= GPR_FLAG_MAJOR_BY_NOFREE;
}
}
- else {
- increment:
+ if (full_marking) {
+ /* increment: */
gc_report(1, objspace, "gc_marks_finish: heap_set_increment!!\n");
heap_set_increment(objspace, heap_extend_pages(objspace, sweep_slots, total_slots));
heap_increment(objspace, heap);
@@ -5570,27 +7358,25 @@ gc_marks_finish(rb_objspace_t *objspace)
objspace->rgengc.need_major_gc = GPR_FLAG_MAJOR_BY_FORCE;
}
- gc_report(1, objspace, "gc_marks_finish (marks %d objects, old %d objects, total %d slots, sweep %d slots, increment: %d, next GC: %s)\n",
- (int)objspace->marked_slots, (int)objspace->rgengc.old_objects, (int)heap->total_slots, (int)sweep_slots, (int)heap_allocatable_pages,
+ gc_report(1, objspace, "gc_marks_finish (marks %"PRIdSIZE" objects, "
+ "old %"PRIdSIZE" objects, total %"PRIdSIZE" slots, "
+ "sweep %"PRIdSIZE" slots, increment: %"PRIdSIZE", next GC: %s)\n",
+ objspace->marked_slots, objspace->rgengc.old_objects, heap->total_slots, sweep_slots, heap_allocatable_pages,
objspace->rgengc.need_major_gc ? "major" : "minor");
-#else /* USE_RGENGC */
- if (sweep_slots < min_free_slots) {
- gc_report(1, objspace, "gc_marks_finish: heap_set_increment!!\n");
- heap_set_increment(objspace, heap_extend_pages(objspace, sweep_slot, total_slot));
- heap_increment(objspace, heap);
- }
-#endif
}
+ rb_transient_heap_finish_marking();
+ rb_ractor_finish_marking();
+
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_MARK, 0);
return TRUE;
}
-#if GC_ENABLE_INCREMENTAL_MARK
static void
-gc_marks_step(rb_objspace_t *objspace, int slots)
+gc_marks_step(rb_objspace_t *objspace, size_t slots)
{
+#if GC_ENABLE_INCREMENTAL_MARK
GC_ASSERT(is_marking(objspace));
if (gc_mark_stacked_objects_incremental(objspace, slots)) {
@@ -5599,9 +7385,9 @@ gc_marks_step(rb_objspace_t *objspace, int slots)
gc_sweep(objspace);
}
}
- if (0) fprintf(stderr, "objspace->marked_slots: %d\n", (int)objspace->marked_slots);
-}
+ if (0) fprintf(stderr, "objspace->marked_slots: %"PRIdSIZE"\n", objspace->marked_slots);
#endif
+}
static void
gc_marks_rest(rb_objspace_t *objspace)
@@ -5626,74 +7412,63 @@ gc_marks_rest(rb_objspace_t *objspace)
gc_sweep(objspace);
}
-#if GC_ENABLE_INCREMENTAL_MARK
static void
gc_marks_continue(rb_objspace_t *objspace, rb_heap_t *heap)
{
- int slots = 0;
- const char *from;
+ GC_ASSERT(dont_gc_val() == FALSE);
+#if GC_ENABLE_INCREMENTAL_MARK
- GC_ASSERT(dont_gc == FALSE);
+ unsigned int lock_lev;
+ gc_enter(objspace, gc_enter_event_mark_continue, &lock_lev);
- gc_enter(objspace, "marks_continue");
+ int slots = 0;
+ const char *from;
- PUSH_MARK_FUNC_DATA(NULL);
- {
- if (heap->pooled_pages) {
- while (heap->pooled_pages && slots < HEAP_PAGE_OBJ_LIMIT) {
- struct heap_page *page = heap_move_pooled_pages_to_free_pages(heap);
- slots += page->free_slots;
- }
- from = "pooled-pages";
- }
- else if (heap_increment(objspace, heap)) {
- slots = heap->free_pages->free_slots;
- from = "incremented-pages";
- }
+ if (heap->pooled_pages) {
+ while (heap->pooled_pages && slots < HEAP_PAGE_OBJ_LIMIT) {
+ struct heap_page *page = heap_move_pooled_pages_to_free_pages(heap);
+ slots += page->free_slots;
+ }
+ from = "pooled-pages";
+ }
+ else if (heap_increment(objspace, heap)) {
+ slots = heap->free_pages->free_slots;
+ from = "incremented-pages";
+ }
- if (slots > 0) {
- gc_report(2, objspace, "gc_marks_continue: provide %d slots from %s.\n", slots, from);
- gc_marks_step(objspace, (int)objspace->rincgc.step_slots);
- }
- else {
- gc_report(2, objspace, "gc_marks_continue: no more pooled pages (stack depth: %d).\n", (int)mark_stack_size(&objspace->mark_stack));
- gc_marks_rest(objspace);
- }
+ if (slots > 0) {
+ gc_report(2, objspace, "gc_marks_continue: provide %d slots from %s.\n",
+ slots, from);
+ gc_marks_step(objspace, objspace->rincgc.step_slots);
+ }
+ else {
+ gc_report(2, objspace, "gc_marks_continue: no more pooled pages (stack depth: %"PRIdSIZE").\n",
+ mark_stack_size(&objspace->mark_stack));
+ gc_marks_rest(objspace);
}
- POP_MARK_FUNC_DATA();
- gc_exit(objspace, "marks_continue");
-}
+ gc_exit(objspace, gc_enter_event_mark_continue, &lock_lev);
#endif
+}
static void
gc_marks(rb_objspace_t *objspace, int full_mark)
{
gc_prof_mark_timer_start(objspace);
- PUSH_MARK_FUNC_DATA(NULL);
- {
- /* setup marking */
+ /* setup marking */
-#if USE_RGENGC
- gc_marks_start(objspace, full_mark);
- if (!is_incremental_marking(objspace)) {
- gc_marks_rest(objspace);
- }
+ gc_marks_start(objspace, full_mark);
+ if (!is_incremental_marking(objspace)) {
+ gc_marks_rest(objspace);
+ }
#if RGENGC_PROFILE > 0
- if (gc_prof_record(objspace)) {
- gc_profile_record *record = gc_prof_record(objspace);
- record->old_objects = objspace->rgengc.old_objects;
- }
-#endif
-
-#else /* USE_RGENGC */
- gc_marks_start(objspace, TRUE);
- gc_marks_rest(objspace);
-#endif
+ if (gc_prof_record(objspace)) {
+ gc_profile_record *record = gc_prof_record(objspace);
+ record->old_objects = objspace->rgengc.old_objects;
}
- POP_MARK_FUNC_DATA();
+#endif
gc_prof_mark_timer_stop(objspace);
}
@@ -5708,7 +7483,6 @@ gc_report_body(int level, rb_objspace_t *objspace, const char *fmt, ...)
va_list args;
const char *status = " ";
-#if USE_RGENGC
if (during_gc) {
status = is_full_marking(objspace) ? "+" : "-";
}
@@ -5720,7 +7494,6 @@ gc_report_body(int level, rb_objspace_t *objspace, const char *fmt, ...)
status = "M";
}
}
-#endif
va_start(args, fmt);
vsnprintf(buf, 1024, fmt, args);
@@ -5731,8 +7504,6 @@ gc_report_body(int level, rb_objspace_t *objspace, const char *fmt, ...)
}
}
-#if USE_RGENGC
-
/* bit operations */
static int
@@ -5789,14 +7560,20 @@ rgengc_remember(rb_objspace_t *objspace, VALUE obj)
}
static int
-rgengc_remembered(rb_objspace_t *objspace, VALUE obj)
+rgengc_remembered_sweep(rb_objspace_t *objspace, VALUE obj)
{
int result = rgengc_remembersetbits_get(objspace, obj);
check_rvalue_consistency(obj);
- gc_report(6, objspace, "rgengc_remembered: %s\n", obj_info(obj));
return result;
}
+static int
+rgengc_remembered(rb_objspace_t *objspace, VALUE obj)
+{
+ gc_report(6, objspace, "rgengc_remembered: %s\n", obj_info(obj));
+ return rgengc_remembered_sweep(objspace, obj);
+}
+
#ifndef PROFILE_REMEMBERSET_MARK
#define PROFILE_REMEMBERSET_MARK 0
#endif
@@ -5805,13 +7582,13 @@ static void
rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap)
{
size_t j;
- struct heap_page *page = heap->pages;
+ struct heap_page *page = 0;
#if PROFILE_REMEMBERSET_MARK
int has_old = 0, has_shady = 0, has_both = 0, skip = 0;
#endif
gc_report(1, objspace, "rgengc_rememberset_mark: start\n");
- while (page) {
+ list_for_each(&heap->pages, page, page_node) {
if (page->flags.has_remembered_objects | page->flags.has_uncollectible_shady_objects) {
RVALUE *p = page->start;
RVALUE *offset = p - NUM_IN_PAGE(p);
@@ -5856,8 +7633,6 @@ rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap)
skip++;
}
#endif
-
- page = page->next;
}
#if PROFILE_REMEMBERSET_MARK
@@ -5869,15 +7644,15 @@ rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap)
static void
rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap)
{
- struct heap_page *page = heap->pages;
+ struct heap_page *page = 0;
- while (page) {
+ list_for_each(&heap->pages, page, page_node) {
memset(&page->mark_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
- memset(&page->marking_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
memset(&page->uncollectible_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
+ memset(&page->marking_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
+ memset(&page->pinned_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
page->flags.has_uncollectible_shady_objects = FALSE;
page->flags.has_remembered_objects = FALSE;
- page = page->next;
}
}
@@ -5897,7 +7672,11 @@ gc_writebarrier_generational(VALUE a, VALUE b, rb_objspace_t *objspace)
#if 1
/* mark `a' and remember (default behavior) */
if (!rgengc_remembered(objspace, a)) {
- rgengc_remember(objspace, a);
+ RB_VM_LOCK_ENTER_NO_BARRIER();
+ {
+ rgengc_remember(objspace, a);
+ }
+ RB_VM_LOCK_LEAVE_NO_BARRIER();
gc_report(1, objspace, "gc_writebarrier_generational: %s (remembered) -> %s\n", obj_info(a), obj_info(b));
}
#else
@@ -5934,18 +7713,18 @@ NOINLINE(static void gc_writebarrier_incremental(VALUE a, VALUE b, rb_objspace_t
static void
gc_writebarrier_incremental(VALUE a, VALUE b, rb_objspace_t *objspace)
{
- gc_report(2, objspace, "gc_writebarrier_incremental: [LG] %s -> %s\n", obj_info(a), obj_info(b));
+ gc_report(2, objspace, "gc_writebarrier_incremental: [LG] %p -> %s\n", (void *)a, obj_info(b));
if (RVALUE_BLACK_P(a)) {
if (RVALUE_WHITE_P(b)) {
if (!RVALUE_WB_UNPROTECTED(a)) {
- gc_report(2, objspace, "gc_writebarrier_incremental: [IN] %s -> %s\n", obj_info(a), obj_info(b));
+ gc_report(2, objspace, "gc_writebarrier_incremental: [IN] %p -> %s\n", (void *)a, obj_info(b));
gc_mark_from(objspace, b, a);
}
}
else if (RVALUE_OLD_P(a) && !RVALUE_OLD_P(b)) {
if (!RVALUE_WB_UNPROTECTED(b)) {
- gc_report(1, objspace, "gc_writebarrier_incremental: [GN] %s -> %s\n", obj_info(a), obj_info(b));
+ gc_report(1, objspace, "gc_writebarrier_incremental: [GN] %p -> %s\n", (void *)a, obj_info(b));
RVALUE_AGE_SET_OLD(objspace, b);
if (RVALUE_BLACK_P(b)) {
@@ -5953,10 +7732,14 @@ gc_writebarrier_incremental(VALUE a, VALUE b, rb_objspace_t *objspace)
}
}
else {
- gc_report(1, objspace, "gc_writebarrier_incremental: [LL] %s -> %s\n", obj_info(a), obj_info(b));
+ gc_report(1, objspace, "gc_writebarrier_incremental: [LL] %p -> %s\n", (void *)a, obj_info(b));
gc_remember_unprotected(objspace, b);
}
}
+
+ if (UNLIKELY(objspace->flags.during_compacting)) {
+ MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(b), b);
+ }
}
}
#else
@@ -5972,16 +7755,22 @@ rb_gc_writebarrier(VALUE a, VALUE b)
if (RGENGC_CHECK_MODE && SPECIAL_CONST_P(b)) rb_bug("rb_gc_writebarrier: b is special const");
if (!is_incremental_marking(objspace)) {
- if (!RVALUE_OLD_P(a) || RVALUE_OLD_P(b)) {
- return;
- }
- else {
- gc_writebarrier_generational(a, b, objspace);
- }
+ if (!RVALUE_OLD_P(a) || RVALUE_OLD_P(b)) {
+ // do nothing
+ }
+ else {
+ gc_writebarrier_generational(a, b, objspace);
+ }
}
- else { /* slow path */
- gc_writebarrier_incremental(a, b, objspace);
+ else {
+ /* slow path */
+ RB_VM_LOCK_ENTER_NO_BARRIER();
+ {
+ gc_writebarrier_incremental(a, b, objspace);
+ }
+ RB_VM_LOCK_LEAVE_NO_BARRIER();
}
+ return;
}
void
@@ -6013,6 +7802,7 @@ rb_gc_writebarrier_unprotect(VALUE obj)
RVALUE_AGE_RESET(obj);
}
+ RB_DEBUG_COUNTER_INC(obj_wb_unprotect);
MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
}
}
@@ -6020,7 +7810,7 @@ rb_gc_writebarrier_unprotect(VALUE obj)
/*
* remember `obj' if needed.
*/
-void
+MJIT_FUNC_EXPORTED void
rb_gc_writebarrier_remember(VALUE obj)
{
rb_objspace_t *objspace = &rb_objspace;
@@ -6044,7 +7834,7 @@ static st_table *rgengc_unprotect_logging_table;
static int
rgengc_unprotect_logging_exit_func_i(st_data_t key, st_data_t val, st_data_t arg)
{
- fprintf(stderr, "%s\t%d\n", (char *)key, (int)val);
+ fprintf(stderr, "%s\t%"PRIuVALUE"\n", (char *)key, (VALUE)val);
return ST_CONTINUE;
}
@@ -6081,12 +7871,10 @@ rb_gc_unprotect_logging(void *objptr, const char *filename, int line)
st_insert(rgengc_unprotect_logging_table, (st_data_t)ptr, cnt);
}
}
-#endif /* USE_RGENGC */
void
rb_copy_wb_protected_attribute(VALUE dest, VALUE obj)
{
-#if USE_RGENGC
rb_objspace_t *objspace = &rb_objspace;
if (RVALUE_WB_UNPROTECTED(obj) && !RVALUE_WB_UNPROTECTED(dest)) {
@@ -6100,7 +7888,6 @@ rb_copy_wb_protected_attribute(VALUE dest, VALUE obj)
}
check_rvalue_consistency(dest);
-#endif
}
/* RGENGC analysis information */
@@ -6108,11 +7895,7 @@ rb_copy_wb_protected_attribute(VALUE dest, VALUE obj)
VALUE
rb_obj_rgengc_writebarrier_protected_p(VALUE obj)
{
-#if USE_RGENGC
return RVALUE_WB_UNPROTECTED(obj) ? Qfalse : Qtrue;
-#else
- return Qfalse;
-#endif
}
VALUE
@@ -6126,80 +7909,109 @@ rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
{
size_t n = 0;
static ID ID_marked;
-#if USE_RGENGC
- static ID ID_wb_protected, ID_old, ID_marking, ID_uncollectible;
-#endif
+ static ID ID_wb_protected, ID_old, ID_marking, ID_uncollectible, ID_pinned;
if (!ID_marked) {
#define I(s) ID_##s = rb_intern(#s);
I(marked);
-#if USE_RGENGC
I(wb_protected);
I(old);
I(marking);
I(uncollectible);
-#endif
+ I(pinned);
#undef I
}
-#if USE_RGENGC
if (RVALUE_WB_UNPROTECTED(obj) == 0 && n<max) flags[n++] = ID_wb_protected;
if (RVALUE_OLD_P(obj) && n<max) flags[n++] = ID_old;
if (RVALUE_UNCOLLECTIBLE(obj) && n<max) flags[n++] = ID_uncollectible;
if (MARKED_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj) && n<max) flags[n++] = ID_marking;
-#endif
if (MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj) && n<max) flags[n++] = ID_marked;
+ if (MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj) && n<max) flags[n++] = ID_pinned;
return n;
}
/* GC */
void
+rb_gc_ractor_newobj_cache_clear(rb_ractor_newobj_cache_t *newobj_cache)
+{
+ struct heap_page *page = newobj_cache->using_page;
+ RVALUE *freelist = newobj_cache->freelist;
+ RUBY_DEBUG_LOG("ractor using_page:%p freelist:%p", page, freelist);
+
+ if (page && freelist) {
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
+ if (page->freelist) {
+ RVALUE *p = page->freelist;
+ asan_unpoison_object((VALUE)p, false);
+ while (p->as.free.next) {
+ RVALUE *prev = p;
+ p = p->as.free.next;
+ asan_poison_object((VALUE)prev);
+ asan_unpoison_object((VALUE)p, false);
+ }
+ p->as.free.next = freelist;
+ asan_poison_object((VALUE)p);
+ }
+ else {
+ page->freelist = freelist;
+ }
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
+ }
+
+ newobj_cache->using_page = NULL;
+ newobj_cache->freelist = NULL;
+}
+
+void
rb_gc_force_recycle(VALUE obj)
{
rb_objspace_t *objspace = &rb_objspace;
+ RB_VM_LOCK_ENTER();
+ {
+ int is_old = RVALUE_OLD_P(obj);
-#if USE_RGENGC
- int is_old = RVALUE_OLD_P(obj);
-
- gc_report(2, objspace, "rb_gc_force_recycle: %s\n", obj_info(obj));
+ gc_report(2, objspace, "rb_gc_force_recycle: %s\n", obj_info(obj));
- if (is_old) {
- if (RVALUE_MARKED(obj)) {
- objspace->rgengc.old_objects--;
- }
- }
- CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS(obj), obj);
- CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
+ if (is_old) {
+ if (RVALUE_MARKED(obj)) {
+ objspace->rgengc.old_objects--;
+ }
+ }
+ CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS(obj), obj);
+ CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
+ CLEAR_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj);
#if GC_ENABLE_INCREMENTAL_MARK
- if (is_incremental_marking(objspace)) {
- if (MARKED_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj)) {
- invalidate_mark_stack(&objspace->mark_stack, obj);
- CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj);
- }
- CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj);
- }
- else {
+ if (is_incremental_marking(objspace)) {
+ if (MARKED_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj)) {
+ invalidate_mark_stack(&objspace->mark_stack, obj);
+ CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj);
+ }
+ CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj);
+ }
+ else {
#endif
- if (is_old || !GET_HEAP_PAGE(obj)->flags.before_sweep) {
- CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj);
- }
- CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj);
+ if (is_old || GET_HEAP_PAGE(obj)->flags.before_sweep) {
+ CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj);
+ }
+ CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj);
#if GC_ENABLE_INCREMENTAL_MARK
- }
-#endif
+ }
#endif
- objspace->profile.total_freed_objects++;
+ objspace->profile.total_freed_objects++;
- heap_page_add_freeobj(objspace, GET_HEAP_PAGE(obj), obj);
+ heap_page_add_freeobj(objspace, GET_HEAP_PAGE(obj), obj);
- /* Disable counting swept_slots because there are no meaning.
- * if (!MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(p), p)) {
- * objspace->heap.swept_slots++;
- * }
- */
+ /* Disable counting swept_slots because there are no meaning.
+ * if (!MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(p), p)) {
+ * objspace->heap.swept_slots++;
+ * }
+ */
+ }
+ RB_VM_LOCK_LEAVE();
}
#ifndef MARK_OBJECT_ARY_BUCKET_SIZE
@@ -6209,15 +8021,19 @@ rb_gc_force_recycle(VALUE obj)
void
rb_gc_register_mark_object(VALUE obj)
{
- VALUE ary_ary = GET_THREAD()->vm->mark_object_ary;
- VALUE ary = rb_ary_last(0, 0, ary_ary);
+ RB_VM_LOCK_ENTER();
+ {
+ VALUE ary_ary = GET_VM()->mark_object_ary;
+ VALUE ary = rb_ary_last(0, 0, ary_ary);
- if (ary == Qnil || RARRAY_LEN(ary) >= MARK_OBJECT_ARY_BUCKET_SIZE) {
- ary = rb_ary_tmp_new(MARK_OBJECT_ARY_BUCKET_SIZE);
- rb_ary_push(ary_ary, ary);
- }
+ if (ary == Qnil || RARRAY_LEN(ary) >= MARK_OBJECT_ARY_BUCKET_SIZE) {
+ ary = rb_ary_tmp_new(MARK_OBJECT_ARY_BUCKET_SIZE);
+ rb_ary_push(ary_ary, ary);
+ }
- rb_ary_push(ary, obj);
+ rb_ary_push(ary, obj);
+ }
+ RB_VM_LOCK_LEAVE();
}
void
@@ -6276,7 +8092,7 @@ enum {
static void
heap_ready_to_gc(rb_objspace_t *objspace, rb_heap_t *heap)
{
- if (!heap->freelist && !heap->free_pages) {
+ if (!heap->free_pages) {
if (!heap_increment(objspace, heap)) {
heap_set_increment(objspace, 1);
heap_increment(objspace, heap);
@@ -6287,7 +8103,7 @@ heap_ready_to_gc(rb_objspace_t *objspace, rb_heap_t *heap)
static int
ready_to_gc(rb_objspace_t *objspace)
{
- if (dont_gc || during_gc || ruby_disable_gc) {
+ if (dont_gc_val() || during_gc || ruby_disable_gc) {
heap_ready_to_gc(objspace, heap_eden);
return FALSE;
}
@@ -6306,8 +8122,7 @@ gc_reset_malloc_info(rb_objspace_t *objspace)
if (inc > malloc_limit) {
malloc_limit = (size_t)(inc * gc_params.malloc_limit_growth_factor);
- if (gc_params.malloc_limit_max > 0 && /* ignore max-check if 0 */
- malloc_limit > gc_params.malloc_limit_max) {
+ if (malloc_limit > gc_params.malloc_limit_max) {
malloc_limit = gc_params.malloc_limit_max;
}
}
@@ -6343,12 +8158,12 @@ gc_reset_malloc_info(rb_objspace_t *objspace)
}
}
- if (0) fprintf(stderr, "%d\t%d\t%u\t%u\t%d\n",
- (int)rb_gc_count(),
- (int)objspace->rgengc.need_major_gc,
- (unsigned int)objspace->rgengc.oldmalloc_increase,
- (unsigned int)objspace->rgengc.oldmalloc_increase_limit,
- (unsigned int)gc_params.oldmalloc_limit_max);
+ if (0) fprintf(stderr, "%"PRIdSIZE"\t%d\t%"PRIuSIZE"\t%"PRIuSIZE"\t%"PRIdSIZE"\n",
+ rb_gc_count(),
+ objspace->rgengc.need_major_gc,
+ objspace->rgengc.oldmalloc_increase,
+ objspace->rgengc.oldmalloc_increase_limit,
+ gc_params.oldmalloc_limit_max);
}
else {
/* major GC */
@@ -6366,39 +8181,55 @@ gc_reset_malloc_info(rb_objspace_t *objspace)
}
static int
-garbage_collect(rb_objspace_t *objspace, int full_mark, int immediate_mark, int immediate_sweep, int reason)
+garbage_collect(rb_objspace_t *objspace, int reason)
{
+ int ret;
+
+ RB_VM_LOCK_ENTER();
+ {
#if GC_PROFILE_MORE_DETAIL
- objspace->profile.prepare_time = getrusage_time();
+ objspace->profile.prepare_time = getrusage_time();
#endif
- gc_rest(objspace);
+ gc_rest(objspace);
#if GC_PROFILE_MORE_DETAIL
- objspace->profile.prepare_time = getrusage_time() - objspace->profile.prepare_time;
+ objspace->profile.prepare_time = getrusage_time() - objspace->profile.prepare_time;
#endif
- return gc_start(objspace, full_mark, immediate_mark, immediate_sweep, reason);
+ ret = gc_start(objspace, reason);
+ }
+ RB_VM_LOCK_LEAVE();
+
+ return ret;
}
static int
-gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark, const unsigned int immediate_sweep, int reason)
+gc_start(rb_objspace_t *objspace, int reason)
{
- int do_full_mark = full_mark;
- objspace->flags.immediate_sweep = immediate_sweep;
+ unsigned int do_full_mark = !!((unsigned)reason & GPR_FLAG_FULL_MARK);
+ unsigned int immediate_mark = (unsigned)reason & GPR_FLAG_IMMEDIATE_MARK;
+
+ /* reason may be clobbered, later, so keep set immediate_sweep here */
+ objspace->flags.immediate_sweep = !!((unsigned)reason & GPR_FLAG_IMMEDIATE_SWEEP);
+
+ /* Explicitly enable compaction (GC.compact) */
+ objspace->flags.during_compacting = !!(reason & GPR_FLAG_COMPACT);
if (!heap_allocated_pages) return FALSE; /* heap is not ready */
- if (reason != GPR_FLAG_METHOD && !ready_to_gc(objspace)) return TRUE; /* GC is not allowed */
+ if (!(reason & GPR_FLAG_METHOD) && !ready_to_gc(objspace)) return TRUE; /* GC is not allowed */
GC_ASSERT(gc_mode(objspace) == gc_mode_none);
GC_ASSERT(!is_lazy_sweeping(heap_eden));
GC_ASSERT(!is_incremental_marking(objspace));
+
+ unsigned int lock_lev;
+ gc_enter(objspace, gc_enter_event_start, &lock_lev);
+
#if RGENGC_CHECK_MODE >= 2
- gc_verify_internal_consistency(Qnil);
+ gc_verify_internal_consistency(objspace);
#endif
- gc_enter(objspace, "gc_start");
-
if (ruby_gc_stressful) {
int flag = FIXNUM_P(ruby_gc_stress_mode) ? FIX2INT(ruby_gc_stress_mode) : 0;
@@ -6409,7 +8240,6 @@ gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark,
objspace->flags.immediate_sweep = !(flag & (1<<gc_stress_no_immediate_sweep));
}
else {
-#if USE_RGENGC
if (objspace->rgengc.need_major_gc) {
reason |= objspace->rgengc.need_major_gc;
do_full_mark = TRUE;
@@ -6420,7 +8250,6 @@ gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark,
}
objspace->rgengc.need_major_gc = GPR_FLAG_NONE;
-#endif
}
if (do_full_mark && (reason & GPR_FLAG_MAJOR_MASK) == 0) {
@@ -6442,16 +8271,38 @@ gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark,
if (objspace->flags.immediate_sweep) reason |= GPR_FLAG_IMMEDIATE_SWEEP;
- gc_report(1, objspace, "gc_start(%d, %d, %d, reason: %d) => %d, %d, %d\n",
- full_mark, immediate_mark, immediate_sweep, reason,
+ gc_report(1, objspace, "gc_start(reason: %d) => %u, %d, %d\n",
+ reason,
do_full_mark, !is_incremental_marking(objspace), objspace->flags.immediate_sweep);
+#if USE_DEBUG_COUNTER
+ RB_DEBUG_COUNTER_INC(gc_count);
+
+ if (reason & GPR_FLAG_MAJOR_MASK) {
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_major_nofree, reason & GPR_FLAG_MAJOR_BY_NOFREE);
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_major_oldgen, reason & GPR_FLAG_MAJOR_BY_OLDGEN);
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_major_shady, reason & GPR_FLAG_MAJOR_BY_SHADY);
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_major_force, reason & GPR_FLAG_MAJOR_BY_FORCE);
+#if RGENGC_ESTIMATE_OLDMALLOC
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_major_oldmalloc, reason & GPR_FLAG_MAJOR_BY_OLDMALLOC);
+#endif
+ }
+ else {
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_minor_newobj, reason & GPR_FLAG_NEWOBJ);
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_minor_malloc, reason & GPR_FLAG_MALLOC);
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_minor_method, reason & GPR_FLAG_METHOD);
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_minor_capi, reason & GPR_FLAG_CAPI);
+ (void)RB_DEBUG_COUNTER_INC_IF(gc_minor_stress, reason & GPR_FLAG_STRESS);
+ }
+#endif
+
objspace->profile.count++;
objspace->profile.latest_gc_info = reason;
objspace->profile.total_allocated_objects_at_gc_start = objspace->total_allocated_objects;
objspace->profile.heap_used_at_gc_start = heap_allocated_pages;
gc_prof_setup_new_record(objspace, reason);
gc_reset_malloc_info(objspace);
+ rb_transient_heap_start_marking(do_full_mark);
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_START, 0 /* TODO: pass minor/immediate flag? */);
GC_ASSERT(during_gc);
@@ -6462,7 +8313,7 @@ gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark,
}
gc_prof_timer_stop(objspace);
- gc_exit(objspace, "gc_start");
+ gc_exit(objspace, gc_enter_event_start, &lock_lev);
return TRUE;
}
@@ -6473,28 +8324,24 @@ gc_rest(rb_objspace_t *objspace)
int sweeping = is_lazy_sweeping(heap_eden);
if (marking || sweeping) {
- gc_enter(objspace, "gc_rest");
+ unsigned int lock_lev;
+ gc_enter(objspace, gc_enter_event_rest, &lock_lev);
- if (RGENGC_CHECK_MODE >= 2) gc_verify_internal_consistency(Qnil);
+ if (RGENGC_CHECK_MODE >= 2) gc_verify_internal_consistency(objspace);
if (is_incremental_marking(objspace)) {
- PUSH_MARK_FUNC_DATA(NULL);
- gc_marks_rest(objspace);
- POP_MARK_FUNC_DATA();
- }
+ gc_marks_rest(objspace);
+ }
if (is_lazy_sweeping(heap_eden)) {
gc_sweep_rest(objspace);
}
- gc_exit(objspace, "gc_rest");
+ gc_exit(objspace, gc_enter_event_rest, &lock_lev);
}
}
struct objspace_and_reason {
rb_objspace_t *objspace;
int reason;
- int full_mark;
- int immediate_mark;
- int immediate_sweep;
};
static void
@@ -6503,12 +8350,10 @@ gc_current_status_fill(rb_objspace_t *objspace, char *buff)
int i = 0;
if (is_marking(objspace)) {
buff[i++] = 'M';
-#if USE_RGENGC
if (is_full_marking(objspace)) buff[i++] = 'F';
#if GC_ENABLE_INCREMENTAL_MARK
if (is_incremental_marking(objspace)) buff[i++] = 'I';
#endif
-#endif
}
else if (is_sweeping(objspace)) {
buff[i++] = 'S';
@@ -6575,51 +8420,98 @@ gc_record(rb_objspace_t *objspace, int direction, const char *event)
}
#endif /* PRINT_ENTER_EXIT_TICK */
-static inline void
-gc_enter(rb_objspace_t *objspace, const char *event)
+static const char *
+gc_enter_event_cstr(enum gc_enter_event event)
{
- GC_ASSERT(during_gc == 0);
- if (RGENGC_CHECK_MODE >= 3) gc_verify_internal_consistency(Qnil);
+ switch (event) {
+ case gc_enter_event_start: return "start";
+ case gc_enter_event_mark_continue: return "mark_continue";
+ case gc_enter_event_sweep_continue: return "sweep_continue";
+ case gc_enter_event_rest: return "rest";
+ case gc_enter_event_finalizer: return "finalizer";
+ case gc_enter_event_rb_memerror: return "rb_memerror";
+ }
+ return NULL;
+}
+
+static void
+gc_enter_count(enum gc_enter_event event)
+{
+ switch (event) {
+ case gc_enter_event_start: RB_DEBUG_COUNTER_INC(gc_enter_start); break;
+ case gc_enter_event_mark_continue: RB_DEBUG_COUNTER_INC(gc_enter_mark_continue); break;
+ case gc_enter_event_sweep_continue: RB_DEBUG_COUNTER_INC(gc_enter_sweep_continue); break;
+ case gc_enter_event_rest: RB_DEBUG_COUNTER_INC(gc_enter_rest); break;
+ case gc_enter_event_finalizer: RB_DEBUG_COUNTER_INC(gc_enter_finalizer); break;
+ case gc_enter_event_rb_memerror: /* nothing */ break;
+ }
+}
+
+static inline void
+gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev)
+{
+ RB_VM_LOCK_ENTER_LEV(lock_lev);
+
+ switch (event) {
+ case gc_enter_event_rest:
+ if (!is_marking(objspace)) break;
+ // fall through
+ case gc_enter_event_start:
+ case gc_enter_event_mark_continue:
+ // stop other ractors
+ rb_vm_barrier();
+ break;
+ default:
+ break;
+ }
+
+ gc_enter_count(event);
+ if (UNLIKELY(during_gc != 0)) rb_bug("during_gc != 0");
+ if (RGENGC_CHECK_MODE >= 3) gc_verify_internal_consistency(objspace);
+
+ mjit_gc_start_hook();
during_gc = TRUE;
- gc_report(1, objspace, "gc_entr: %s [%s]\n", event, gc_current_status(objspace));
- gc_record(objspace, 0, event);
+ RUBY_DEBUG_LOG("%s (%s)",gc_enter_event_cstr(event), gc_current_status(objspace));
+ gc_report(1, objspace, "gc_enter: %s [%s]\n", gc_enter_event_cstr(event), gc_current_status(objspace));
+ gc_record(objspace, 0, gc_enter_event_cstr(event));
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_ENTER, 0); /* TODO: which parameter should be passed? */
}
static inline void
-gc_exit(rb_objspace_t *objspace, const char *event)
+gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev)
{
GC_ASSERT(during_gc != 0);
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_EXIT, 0); /* TODO: which parameter should be passsed? */
- gc_record(objspace, 1, event);
- gc_report(1, objspace, "gc_exit: %s [%s]\n", event, gc_current_status(objspace));
+ gc_record(objspace, 1, gc_enter_event_cstr(event));
+ RUBY_DEBUG_LOG("%s (%s)", gc_enter_event_cstr(event), gc_current_status(objspace));
+ gc_report(1, objspace, "gc_exit: %s [%s]\n", gc_enter_event_cstr(event), gc_current_status(objspace));
during_gc = FALSE;
+
+ mjit_gc_exit_hook();
+ RB_VM_LOCK_LEAVE_LEV(lock_lev);
}
static void *
gc_with_gvl(void *ptr)
{
struct objspace_and_reason *oar = (struct objspace_and_reason *)ptr;
- return (void *)(VALUE)garbage_collect(oar->objspace, oar->full_mark, oar->immediate_mark, oar->immediate_sweep, oar->reason);
+ return (void *)(VALUE)garbage_collect(oar->objspace, oar->reason);
}
static int
-garbage_collect_with_gvl(rb_objspace_t *objspace, int full_mark, int immediate_mark, int immediate_sweep, int reason)
+garbage_collect_with_gvl(rb_objspace_t *objspace, int reason)
{
- if (dont_gc) return TRUE;
+ if (dont_gc_val()) return TRUE;
if (ruby_thread_has_gvl_p()) {
- return garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, reason);
+ return garbage_collect(objspace, reason);
}
else {
if (ruby_native_thread_p()) {
struct objspace_and_reason oar;
oar.objspace = objspace;
oar.reason = reason;
- oar.full_mark = full_mark;
- oar.immediate_mark = immediate_mark;
- oar.immediate_sweep = immediate_sweep;
return (int)(VALUE)rb_thread_call_with_gvl(gc_with_gvl, (void *)&oar);
}
else {
@@ -6630,73 +8522,968 @@ garbage_collect_with_gvl(rb_objspace_t *objspace, int full_mark, int immediate_m
}
}
-int
-rb_garbage_collect(void)
+static VALUE
+gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE full_mark, VALUE immediate_mark, VALUE immediate_sweep, VALUE compact)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+ int reason = GPR_FLAG_FULL_MARK |
+ GPR_FLAG_IMMEDIATE_MARK |
+ GPR_FLAG_IMMEDIATE_SWEEP |
+ GPR_FLAG_METHOD;
+
+ /* For now, compact implies full mark / sweep, so ignore other flags */
+ if (RTEST(compact)) {
+ reason |= GPR_FLAG_COMPACT;
+ } else {
+ if (!RTEST(full_mark)) reason &= ~GPR_FLAG_FULL_MARK;
+ if (!RTEST(immediate_mark)) reason &= ~GPR_FLAG_IMMEDIATE_MARK;
+ if (!RTEST(immediate_sweep)) reason &= ~GPR_FLAG_IMMEDIATE_SWEEP;
+ }
+
+ garbage_collect(objspace, reason);
+ gc_finalize_deferred(objspace);
+
+ return Qnil;
+}
+
+static int
+gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj)
{
- return garbage_collect(&rb_objspace, TRUE, TRUE, TRUE, GPR_FLAG_CAPI);
+ GC_ASSERT(!SPECIAL_CONST_P(obj));
+
+ switch (BUILTIN_TYPE(obj)) {
+ case T_NONE:
+ case T_NIL:
+ case T_MOVED:
+ case T_ZOMBIE:
+ return FALSE;
+ case T_SYMBOL:
+ if (DYNAMIC_SYM_P(obj) && (RSYMBOL(obj)->id & ~ID_SCOPE_MASK)) {
+ return FALSE;
+ }
+ /* fall through */
+ case T_STRING:
+ case T_OBJECT:
+ case T_FLOAT:
+ case T_IMEMO:
+ case T_ARRAY:
+ case T_BIGNUM:
+ case T_ICLASS:
+ case T_MODULE:
+ case T_REGEXP:
+ case T_DATA:
+ case T_MATCH:
+ case T_STRUCT:
+ case T_HASH:
+ case T_FILE:
+ case T_COMPLEX:
+ case T_RATIONAL:
+ case T_NODE:
+ case T_CLASS:
+ if (FL_TEST(obj, FL_FINALIZE)) {
+ /* The finalizer table is a numtable. It looks up objects by address.
+ * We can't mark the keys in the finalizer table because that would
+ * prevent the objects from being collected. This check prevents
+ * objects that are keys in the finalizer table from being moved
+ * without directly pinning them. */
+ if (st_is_member(finalizer_table, obj)) {
+ return FALSE;
+ }
+ }
+ GC_ASSERT(RVALUE_MARKED(obj));
+ GC_ASSERT(!RVALUE_PINNED(obj));
+
+ return TRUE;
+
+ default:
+ rb_bug("gc_is_moveable_obj: unreachable (%d)", (int)BUILTIN_TYPE(obj));
+ break;
+ }
+
+ return FALSE;
+}
+
+static VALUE
+gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free)
+{
+ int marked;
+ int wb_unprotected;
+ int uncollectible;
+ int marking;
+ RVALUE *dest = (RVALUE *)free;
+ RVALUE *src = (RVALUE *)scan;
+
+ gc_report(4, objspace, "Moving object: %p -> %p\n", (void*)scan, (void *)free);
+
+ GC_ASSERT(BUILTIN_TYPE(scan) != T_NONE);
+ GC_ASSERT(!MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(free), free));
+
+ /* Save off bits for current object. */
+ marked = rb_objspace_marked_object_p((VALUE)src);
+ wb_unprotected = RVALUE_WB_UNPROTECTED((VALUE)src);
+ uncollectible = RVALUE_UNCOLLECTIBLE((VALUE)src);
+ marking = RVALUE_MARKING((VALUE)src);
+
+ /* Clear bits for eventual T_MOVED */
+ CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS((VALUE)src), (VALUE)src);
+ CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS((VALUE)src), (VALUE)src);
+ CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)src), (VALUE)src);
+ CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)src), (VALUE)src);
+
+ if (FL_TEST((VALUE)src, FL_EXIVAR)) {
+ /* Same deal as below. Generic ivars are held in st tables.
+ * Resizing the table could cause a GC to happen and we can't allow it */
+ VALUE already_disabled = rb_gc_disable_no_rest();
+ rb_mv_generic_ivar((VALUE)src, (VALUE)dest);
+ if (already_disabled == Qfalse) rb_objspace_gc_enable(objspace);
+ }
+
+ st_data_t srcid = (st_data_t)src, id;
+
+ /* If the source object's object_id has been seen, we need to update
+ * the object to object id mapping. */
+ if (st_lookup(objspace->obj_to_id_tbl, srcid, &id)) {
+ gc_report(4, objspace, "Moving object with seen id: %p -> %p\n", (void *)src, (void *)dest);
+ /* inserting in the st table can cause the GC to run. We need to
+ * prevent re-entry in to the GC since `gc_move` is running in the GC,
+ * so temporarily disable the GC around the st table mutation */
+ VALUE already_disabled = rb_gc_disable_no_rest();
+ st_delete(objspace->obj_to_id_tbl, &srcid, 0);
+ st_insert(objspace->obj_to_id_tbl, (st_data_t)dest, id);
+ if (already_disabled == Qfalse) rb_objspace_gc_enable(objspace);
+ }
+
+ /* Move the object */
+ memcpy(dest, src, sizeof(RVALUE));
+ memset(src, 0, sizeof(RVALUE));
+
+ /* Set bits for object in new location */
+ if (marking) {
+ MARK_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)dest), (VALUE)dest);
+ }
+ else {
+ CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)dest), (VALUE)dest);
+ }
+
+ if (marked) {
+ MARK_IN_BITMAP(GET_HEAP_MARK_BITS((VALUE)dest), (VALUE)dest);
+ }
+ else {
+ CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS((VALUE)dest), (VALUE)dest);
+ }
+
+ if (wb_unprotected) {
+ MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS((VALUE)dest), (VALUE)dest);
+ }
+ else {
+ CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS((VALUE)dest), (VALUE)dest);
+ }
+
+ if (uncollectible) {
+ MARK_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)dest), (VALUE)dest);
+ }
+ else {
+ CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)dest), (VALUE)dest);
+ }
+
+ /* Assign forwarding address */
+ src->as.moved.flags = T_MOVED;
+ src->as.moved.dummy = Qundef;
+ src->as.moved.destination = (VALUE)dest;
+ GC_ASSERT(BUILTIN_TYPE((VALUE)dest) != T_NONE);
+
+ return (VALUE)src;
}
-#undef Init_stack
+static int
+compare_free_slots(const void *left, const void *right, void *dummy)
+{
+ struct heap_page *left_page;
+ struct heap_page *right_page;
+
+ left_page = *(struct heap_page * const *)left;
+ right_page = *(struct heap_page * const *)right;
+
+ return left_page->free_slots - right_page->free_slots;
+}
+
+static void
+gc_sort_heap_by_empty_slots(rb_objspace_t *objspace)
+{
+ size_t total_pages = heap_eden->total_pages;
+ size_t size = size_mul_or_raise(total_pages, sizeof(struct heap_page *), rb_eRuntimeError);
+ struct heap_page *page = 0, **page_list = malloc(size);
+ size_t i = 0;
+
+ list_for_each(&heap_eden->pages, page, page_node) {
+ page_list[i++] = page;
+ assert(page != NULL);
+ }
+ assert(total_pages > 0);
+ assert((size_t)i == total_pages);
+
+ /* Sort the heap so "filled pages" are first. `heap_add_page` adds to the
+ * head of the list, so empty pages will end up at the start of the heap */
+ ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_free_slots, NULL);
+
+ /* Reset the eden heap */
+ list_head_init(&objspace->eden_heap.pages);
+ for (i = 0; i < total_pages; i++) {
+ list_add(&heap_eden->pages, &page_list[i]->page_node);
+ if (page_list[i]->free_slots != 0) {
+ heap_add_freepage(heap_eden, page_list[i]);
+ }
+ }
+
+ free(page_list);
+}
+
+static void
+gc_ref_update_array(rb_objspace_t * objspace, VALUE v)
+{
+ long i, len;
+
+ if (FL_TEST(v, ELTS_SHARED))
+ return;
+
+ len = RARRAY_LEN(v);
+ if (len > 0) {
+ VALUE *ptr = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(v);
+ for (i = 0; i < len; i++) {
+ UPDATE_IF_MOVED(objspace, ptr[i]);
+ }
+ }
+}
+
+static void
+gc_ref_update_object(rb_objspace_t * objspace, VALUE v)
+{
+ VALUE *ptr = ROBJECT_IVPTR(v);
+
+ uint32_t i, len = ROBJECT_NUMIV(v);
+ for (i = 0; i < len; i++) {
+ UPDATE_IF_MOVED(objspace, ptr[i]);
+ }
+}
+
+static int
+hash_replace_ref(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)argp;
+
+ if (gc_object_moved_p(objspace, (VALUE)*key)) {
+ *key = rb_gc_location((VALUE)*key);
+ }
+
+ if (gc_object_moved_p(objspace, (VALUE)*value)) {
+ *value = rb_gc_location((VALUE)*value);
+ }
+
+ return ST_CONTINUE;
+}
+
+static int
+hash_foreach_replace(st_data_t key, st_data_t value, st_data_t argp, int error)
+{
+ rb_objspace_t *objspace;
+
+ objspace = (rb_objspace_t *)argp;
+
+ if (gc_object_moved_p(objspace, (VALUE)key)) {
+ return ST_REPLACE;
+ }
+
+ if (gc_object_moved_p(objspace, (VALUE)value)) {
+ return ST_REPLACE;
+ }
+ return ST_CONTINUE;
+}
+
+static int
+hash_replace_ref_value(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)argp;
+
+ if (gc_object_moved_p(objspace, (VALUE)*value)) {
+ *value = rb_gc_location((VALUE)*value);
+ }
+
+ return ST_CONTINUE;
+}
+
+static int
+hash_foreach_replace_value(st_data_t key, st_data_t value, st_data_t argp, int error)
+{
+ rb_objspace_t *objspace;
+
+ objspace = (rb_objspace_t *)argp;
+
+ if (gc_object_moved_p(objspace, (VALUE)value)) {
+ return ST_REPLACE;
+ }
+ return ST_CONTINUE;
+}
+
+static void
+gc_update_tbl_refs(rb_objspace_t * objspace, st_table *tbl)
+{
+ if (!tbl || tbl->num_entries == 0) return;
+
+ if (st_foreach_with_replace(tbl, hash_foreach_replace_value, hash_replace_ref_value, (st_data_t)objspace)) {
+ rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ }
+}
+
+static void
+gc_update_table_refs(rb_objspace_t * objspace, st_table *tbl)
+{
+ if (!tbl || tbl->num_entries == 0) return;
+
+ if (st_foreach_with_replace(tbl, hash_foreach_replace, hash_replace_ref, (st_data_t)objspace)) {
+ rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ }
+}
+
+/* Update MOVED references in an st_table */
void
-Init_stack(volatile VALUE *addr)
+rb_gc_update_tbl_refs(st_table *ptr)
{
- ruby_init_stack(addr);
+ rb_objspace_t *objspace = &rb_objspace;
+ gc_update_table_refs(objspace, ptr);
}
-/*
- * call-seq:
- * GC.start -> nil
- * ObjectSpace.garbage_collect -> nil
- * include GC; garbage_collect -> nil
- * GC.start(full_mark: true, immediate_sweep: true) -> nil
- * ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true) -> nil
- * include GC; garbage_collect(full_mark: true, immediate_sweep: true) -> nil
- *
- * Initiates garbage collection, unless manually disabled.
- *
- * This method is defined with keyword arguments that default to true:
- *
- * def GC.start(full_mark: true, immediate_sweep: true); end
- *
- * Use full_mark: false to perform a minor GC.
- * Use immediate_sweep: false to defer sweeping (use lazy sweep).
- *
- * Note: These keyword arguments are implementation and version dependent. They
- * are not guaranteed to be future-compatible, and may be ignored if the
- * underlying implementation does not support them.
- */
+static void
+gc_ref_update_hash(rb_objspace_t * objspace, VALUE v)
+{
+ rb_hash_stlike_foreach_with_replace(v, hash_foreach_replace, hash_replace_ref, (st_data_t)objspace);
+}
+
+static void
+gc_ref_update_method_entry(rb_objspace_t *objspace, rb_method_entry_t *me)
+{
+ rb_method_definition_t *def = me->def;
+
+ UPDATE_IF_MOVED(objspace, me->owner);
+ UPDATE_IF_MOVED(objspace, me->defined_class);
+
+ if (def) {
+ switch (def->type) {
+ case VM_METHOD_TYPE_ISEQ:
+ if (def->body.iseq.iseqptr) {
+ TYPED_UPDATE_IF_MOVED(objspace, rb_iseq_t *, def->body.iseq.iseqptr);
+ }
+ TYPED_UPDATE_IF_MOVED(objspace, rb_cref_t *, def->body.iseq.cref);
+ break;
+ case VM_METHOD_TYPE_ATTRSET:
+ case VM_METHOD_TYPE_IVAR:
+ UPDATE_IF_MOVED(objspace, def->body.attr.location);
+ break;
+ case VM_METHOD_TYPE_BMETHOD:
+ UPDATE_IF_MOVED(objspace, def->body.bmethod.proc);
+ break;
+ case VM_METHOD_TYPE_ALIAS:
+ TYPED_UPDATE_IF_MOVED(objspace, struct rb_method_entry_struct *, def->body.alias.original_me);
+ return;
+ case VM_METHOD_TYPE_REFINED:
+ TYPED_UPDATE_IF_MOVED(objspace, struct rb_method_entry_struct *, def->body.refined.orig_me);
+ UPDATE_IF_MOVED(objspace, def->body.refined.owner);
+ break;
+ case VM_METHOD_TYPE_CFUNC:
+ case VM_METHOD_TYPE_ZSUPER:
+ case VM_METHOD_TYPE_MISSING:
+ case VM_METHOD_TYPE_OPTIMIZED:
+ case VM_METHOD_TYPE_UNDEF:
+ case VM_METHOD_TYPE_NOTIMPLEMENTED:
+ break;
+ }
+ }
+}
+
+static void
+gc_update_values(rb_objspace_t *objspace, long n, VALUE *values)
+{
+ long i;
+
+ for (i=0; i<n; i++) {
+ UPDATE_IF_MOVED(objspace, values[i]);
+ }
+}
+
+static void
+gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
+{
+ switch (imemo_type(obj)) {
+ case imemo_env:
+ {
+ rb_env_t *env = (rb_env_t *)obj;
+ TYPED_UPDATE_IF_MOVED(objspace, rb_iseq_t *, env->iseq);
+ UPDATE_IF_MOVED(objspace, env->ep[VM_ENV_DATA_INDEX_ENV]);
+ gc_update_values(objspace, (long)env->env_size, (VALUE *)env->env);
+ }
+ break;
+ case imemo_cref:
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.cref.klass);
+ TYPED_UPDATE_IF_MOVED(objspace, struct rb_cref_struct *, RANY(obj)->as.imemo.cref.next);
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.cref.refinements);
+ break;
+ case imemo_svar:
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.cref_or_me);
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.lastline);
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.backref);
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.others);
+ break;
+ case imemo_throw_data:
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.throw_data.throw_obj);
+ break;
+ case imemo_ifunc:
+ break;
+ case imemo_memo:
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.memo.v1);
+ UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.memo.v2);
+ break;
+ case imemo_ment:
+ gc_ref_update_method_entry(objspace, &RANY(obj)->as.imemo.ment);
+ break;
+ case imemo_iseq:
+ rb_iseq_update_references((rb_iseq_t *)obj);
+ break;
+ case imemo_ast:
+ rb_ast_update_references((rb_ast_t *)obj);
+ break;
+ case imemo_callcache:
+ {
+ const struct rb_callcache *cc = (const struct rb_callcache *)obj;
+ if (cc->klass) {
+ UPDATE_IF_MOVED(objspace, cc->klass);
+ if (!is_live_object(objspace, cc->klass)) {
+ *((VALUE *)(&cc->klass)) = (VALUE)0;
+ }
+ }
+
+ if (cc->cme_) {
+ TYPED_UPDATE_IF_MOVED(objspace, struct rb_callable_method_entry_struct *, cc->cme_);
+ if (!is_live_object(objspace, (VALUE)cc->cme_)) {
+ *((struct rb_callable_method_entry_struct **)(&cc->cme_)) = (struct rb_callable_method_entry_struct *)0;
+ }
+ }
+ }
+ break;
+ case imemo_constcache:
+ {
+ const struct iseq_inline_constant_cache_entry *ice = (struct iseq_inline_constant_cache_entry *)obj;
+ UPDATE_IF_MOVED(objspace, ice->value);
+ }
+ break;
+ case imemo_parser_strterm:
+ case imemo_tmpbuf:
+ case imemo_callinfo:
+ break;
+ default:
+ rb_bug("not reachable %d", imemo_type(obj));
+ break;
+ }
+}
+
+static enum rb_id_table_iterator_result
+check_id_table_move(ID id, VALUE value, void *data)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)data;
+
+ if (gc_object_moved_p(objspace, (VALUE)value)) {
+ return ID_TABLE_REPLACE;
+ }
+
+ return ID_TABLE_CONTINUE;
+}
+
+/* Returns the new location of an object, if it moved. Otherwise returns
+ * the existing location. */
+VALUE
+rb_gc_location(VALUE value)
+{
+
+ VALUE destination;
+
+ if (!SPECIAL_CONST_P(value)) {
+ void *poisoned = asan_poisoned_object_p(value);
+ asan_unpoison_object(value, false);
+
+ if (BUILTIN_TYPE(value) == T_MOVED) {
+ destination = (VALUE)RMOVED(value)->destination;
+ GC_ASSERT(BUILTIN_TYPE(destination) != T_NONE);
+ }
+ else {
+ destination = value;
+ }
+
+ /* Re-poison slot if it's not the one we want */
+ if (poisoned) {
+ GC_ASSERT(BUILTIN_TYPE(value) == T_NONE);
+ asan_poison_object(value);
+ }
+ }
+ else {
+ destination = value;
+ }
+
+ return destination;
+}
+
+static enum rb_id_table_iterator_result
+update_id_table(ID *key, VALUE * value, void *data, int existing)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)data;
+
+ if (gc_object_moved_p(objspace, (VALUE)*value)) {
+ *value = rb_gc_location((VALUE)*value);
+ }
+
+ return ID_TABLE_CONTINUE;
+}
+
+static void
+update_m_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
+{
+ if (tbl) {
+ rb_id_table_foreach_with_replace(tbl, check_id_table_move, update_id_table, objspace);
+ }
+}
+
+static enum rb_id_table_iterator_result
+update_cc_tbl_i(ID id, VALUE ccs_ptr, void *data)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)data;
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
+ VM_ASSERT(vm_ccs_p(ccs));
+
+ if (gc_object_moved_p(objspace, (VALUE)ccs->cme)) {
+ ccs->cme = (const rb_callable_method_entry_t *)rb_gc_location((VALUE)ccs->cme);
+ }
+
+ for (int i=0; i<ccs->len; i++) {
+ if (gc_object_moved_p(objspace, (VALUE)ccs->entries[i].ci)) {
+ ccs->entries[i].ci = (struct rb_callinfo *)rb_gc_location((VALUE)ccs->entries[i].ci);
+ }
+ if (gc_object_moved_p(objspace, (VALUE)ccs->entries[i].cc)) {
+ ccs->entries[i].cc = (struct rb_callcache *)rb_gc_location((VALUE)ccs->entries[i].cc);
+ }
+ }
+
+ // do not replace
+ return ID_TABLE_CONTINUE;
+}
+
+static void
+update_cc_tbl(rb_objspace_t *objspace, VALUE klass)
+{
+ struct rb_id_table *tbl = RCLASS_CC_TBL(klass);
+ if (tbl) {
+ rb_id_table_foreach_with_replace(tbl, update_cc_tbl_i, 0, objspace);
+ }
+}
+
+static enum rb_id_table_iterator_result
+update_const_table(VALUE value, void *data)
+{
+ rb_const_entry_t *ce = (rb_const_entry_t *)value;
+ rb_objspace_t * objspace = (rb_objspace_t *)data;
+
+ if (gc_object_moved_p(objspace, ce->value)) {
+ ce->value = rb_gc_location(ce->value);
+ }
+
+ if (gc_object_moved_p(objspace, ce->file)) {
+ ce->file = rb_gc_location(ce->file);
+ }
+
+ return ID_TABLE_CONTINUE;
+}
+
+static void
+update_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
+{
+ if (!tbl) return;
+ rb_id_table_foreach_values(tbl, update_const_table, objspace);
+}
+
+static void
+update_subclass_entries(rb_objspace_t *objspace, rb_subclass_entry_t *entry)
+{
+ while (entry) {
+ UPDATE_IF_MOVED(objspace, entry->klass);
+ entry = entry->next;
+ }
+}
+
+static int
+update_iv_index_tbl_i(st_data_t key, st_data_t value, st_data_t arg)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)arg;
+ struct rb_iv_index_tbl_entry *ent = (struct rb_iv_index_tbl_entry *)value;
+ UPDATE_IF_MOVED(objspace, ent->class_value);
+ return ST_CONTINUE;
+}
+
+static void
+update_class_ext(rb_objspace_t *objspace, rb_classext_t *ext)
+{
+ UPDATE_IF_MOVED(objspace, ext->origin_);
+ UPDATE_IF_MOVED(objspace, ext->refined_class);
+ update_subclass_entries(objspace, ext->subclasses);
+
+ // ext->iv_index_tbl
+ if (ext->iv_index_tbl) {
+ st_foreach(ext->iv_index_tbl, update_iv_index_tbl_i, (st_data_t)objspace);
+ }
+}
+
+static void
+gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
+{
+ RVALUE *any = RANY(obj);
+
+ gc_report(4, objspace, "update-refs: %p ->\n", (void *)obj);
+
+ switch (BUILTIN_TYPE(obj)) {
+ case T_CLASS:
+ case T_MODULE:
+ if (RCLASS_SUPER((VALUE)obj)) {
+ UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
+ }
+ if (!RCLASS_EXT(obj)) break;
+ update_m_tbl(objspace, RCLASS_M_TBL(obj));
+ update_cc_tbl(objspace, obj);
+
+ gc_update_tbl_refs(objspace, RCLASS_IV_TBL(obj));
+
+ update_class_ext(objspace, RCLASS_EXT(obj));
+ update_const_tbl(objspace, RCLASS_CONST_TBL(obj));
+ break;
+
+ case T_ICLASS:
+ if (FL_TEST(obj, RICLASS_IS_ORIGIN) &&
+ !FL_TEST(obj, RICLASS_ORIGIN_SHARED_MTBL)) {
+ update_m_tbl(objspace, RCLASS_M_TBL(obj));
+ }
+ if (RCLASS_SUPER((VALUE)obj)) {
+ UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
+ }
+ if (!RCLASS_EXT(obj)) break;
+ if (RCLASS_IV_TBL(obj)) {
+ gc_update_tbl_refs(objspace, RCLASS_IV_TBL(obj));
+ }
+ update_class_ext(objspace, RCLASS_EXT(obj));
+ update_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
+ update_cc_tbl(objspace, obj);
+ break;
+
+ case T_IMEMO:
+ gc_ref_update_imemo(objspace, obj);
+ return;
+
+ case T_NIL:
+ case T_FIXNUM:
+ case T_NODE:
+ case T_MOVED:
+ case T_NONE:
+ /* These can't move */
+ return;
+
+ case T_ARRAY:
+ if (FL_TEST(obj, ELTS_SHARED)) {
+ UPDATE_IF_MOVED(objspace, any->as.array.as.heap.aux.shared_root);
+ }
+ else {
+ gc_ref_update_array(objspace, obj);
+ }
+ break;
+
+ case T_HASH:
+ gc_ref_update_hash(objspace, obj);
+ UPDATE_IF_MOVED(objspace, any->as.hash.ifnone);
+ break;
+
+ case T_STRING:
+ if (STR_SHARED_P(obj)) {
+ UPDATE_IF_MOVED(objspace, any->as.string.as.heap.aux.shared);
+ }
+ break;
+
+ case T_DATA:
+ /* Call the compaction callback, if it exists */
+ {
+ void *const ptr = DATA_PTR(obj);
+ if (ptr) {
+ if (RTYPEDDATA_P(obj)) {
+ RUBY_DATA_FUNC compact_func = any->as.typeddata.type->function.dcompact;
+ if (compact_func) (*compact_func)(ptr);
+ }
+ }
+ }
+ break;
+
+ case T_OBJECT:
+ gc_ref_update_object(objspace, obj);
+ break;
+
+ case T_FILE:
+ if (any->as.file.fptr) {
+ UPDATE_IF_MOVED(objspace, any->as.file.fptr->self);
+ UPDATE_IF_MOVED(objspace, any->as.file.fptr->pathv);
+ UPDATE_IF_MOVED(objspace, any->as.file.fptr->tied_io_for_writing);
+ UPDATE_IF_MOVED(objspace, any->as.file.fptr->writeconv_asciicompat);
+ UPDATE_IF_MOVED(objspace, any->as.file.fptr->writeconv_pre_ecopts);
+ UPDATE_IF_MOVED(objspace, any->as.file.fptr->encs.ecopts);
+ UPDATE_IF_MOVED(objspace, any->as.file.fptr->write_lock);
+ }
+ break;
+ case T_REGEXP:
+ UPDATE_IF_MOVED(objspace, any->as.regexp.src);
+ break;
+
+ case T_SYMBOL:
+ if (DYNAMIC_SYM_P((VALUE)any)) {
+ UPDATE_IF_MOVED(objspace, RSYMBOL(any)->fstr);
+ }
+ break;
+
+ case T_FLOAT:
+ case T_BIGNUM:
+ break;
+
+ case T_MATCH:
+ UPDATE_IF_MOVED(objspace, any->as.match.regexp);
+
+ if (any->as.match.str) {
+ UPDATE_IF_MOVED(objspace, any->as.match.str);
+ }
+ break;
+
+ case T_RATIONAL:
+ UPDATE_IF_MOVED(objspace, any->as.rational.num);
+ UPDATE_IF_MOVED(objspace, any->as.rational.den);
+ break;
+
+ case T_COMPLEX:
+ UPDATE_IF_MOVED(objspace, any->as.complex.real);
+ UPDATE_IF_MOVED(objspace, any->as.complex.imag);
+
+ break;
+
+ case T_STRUCT:
+ {
+ long i, len = RSTRUCT_LEN(obj);
+ VALUE *ptr = (VALUE *)RSTRUCT_CONST_PTR(obj);
+
+ for (i = 0; i < len; i++) {
+ UPDATE_IF_MOVED(objspace, ptr[i]);
+ }
+ }
+ break;
+ default:
+#if GC_DEBUG
+ rb_gcdebug_print_obj_condition((VALUE)obj);
+ rb_obj_info_dump(obj);
+ rb_bug("unreachable");
+#endif
+ break;
+
+ }
+
+ UPDATE_IF_MOVED(objspace, RBASIC(obj)->klass);
+
+ gc_report(4, objspace, "update-refs: %p <-\n", (void *)obj);
+}
+
+static int
+gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t * objspace, struct heap_page *page)
+{
+ VALUE v = (VALUE)vstart;
+ asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
+ asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
+ page->flags.has_uncollectible_shady_objects = FALSE;
+ page->flags.has_remembered_objects = FALSE;
+
+ /* For each object on the page */
+ for (; v != (VALUE)vend; v += stride) {
+ void *poisoned = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
+ switch (BUILTIN_TYPE(v)) {
+ case T_NONE:
+ case T_MOVED:
+ case T_ZOMBIE:
+ break;
+ default:
+ if (RVALUE_WB_UNPROTECTED(v)) {
+ page->flags.has_uncollectible_shady_objects = TRUE;
+ }
+ if (RVALUE_PAGE_MARKING(page, v)) {
+ page->flags.has_remembered_objects = TRUE;
+ }
+ if (page->flags.before_sweep) {
+ if (RVALUE_MARKED(v)) {
+ gc_update_object_references(objspace, v);
+ }
+ } else {
+ gc_update_object_references(objspace, v);
+ }
+ }
+
+ if (poisoned) {
+ asan_poison_object(v);
+ }
+ }
+
+ return 0;
+}
+
+extern rb_symbols_t ruby_global_symbols;
+#define global_symbols ruby_global_symbols
+
+static void
+gc_update_references(rb_objspace_t * objspace, rb_heap_t *heap)
+{
+ rb_execution_context_t *ec = GET_EC();
+ rb_vm_t *vm = rb_ec_vm_ptr(ec);
+ short should_set_mark_bits = 1;
+
+ struct heap_page *page = NULL;
+
+ list_for_each(&heap->pages, page, page_node) {
+ gc_ref_update(page->start, page->start + page->total_slots, sizeof(RVALUE), objspace, page);
+ if (page == heap->sweeping_page) {
+ should_set_mark_bits = 0;
+ }
+ if (should_set_mark_bits) {
+ gc_setup_mark_bits(page);
+ }
+ }
+ rb_vm_update_references(vm);
+ rb_transient_heap_update_references();
+ rb_gc_update_global_tbl();
+ global_symbols.ids = rb_gc_location(global_symbols.ids);
+ global_symbols.dsymbol_fstr_hash = rb_gc_location(global_symbols.dsymbol_fstr_hash);
+ gc_update_tbl_refs(objspace, objspace->obj_to_id_tbl);
+ gc_update_table_refs(objspace, objspace->id_to_obj_tbl);
+ gc_update_table_refs(objspace, global_symbols.str_sym);
+ gc_update_table_refs(objspace, finalizer_table);
+}
+
+static VALUE type_sym(size_t type);
static VALUE
-gc_start_internal(int argc, VALUE *argv, VALUE self)
+gc_compact_stats(rb_execution_context_t *ec, VALUE self)
{
+ size_t i;
rb_objspace_t *objspace = &rb_objspace;
- int full_mark = TRUE, immediate_mark = TRUE, immediate_sweep = TRUE;
- VALUE opt = Qnil;
- static ID keyword_ids[3];
+ VALUE h = rb_hash_new();
+ VALUE considered = rb_hash_new();
+ VALUE moved = rb_hash_new();
- rb_scan_args(argc, argv, "0:", &opt);
+ for (i=0; i<T_MASK; i++) {
+ if(objspace->rcompactor.considered_count_table[i]) {
+ rb_hash_aset(considered, type_sym(i), SIZET2NUM(objspace->rcompactor.considered_count_table[i]));
+ }
- if (!NIL_P(opt)) {
- VALUE kwvals[3];
+ if(objspace->rcompactor.moved_count_table[i]) {
+ rb_hash_aset(moved, type_sym(i), SIZET2NUM(objspace->rcompactor.moved_count_table[i]));
+ }
+ }
- if (!keyword_ids[0]) {
- keyword_ids[0] = rb_intern("full_mark");
- keyword_ids[1] = rb_intern("immediate_mark");
- keyword_ids[2] = rb_intern("immediate_sweep");
- }
+ rb_hash_aset(h, ID2SYM(rb_intern("considered")), considered);
+ rb_hash_aset(h, ID2SYM(rb_intern("moved")), moved);
- rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals);
+ return h;
+}
- if (kwvals[0] != Qundef) full_mark = RTEST(kwvals[0]);
- if (kwvals[1] != Qundef) immediate_mark = RTEST(kwvals[1]);
- if (kwvals[2] != Qundef) immediate_sweep = RTEST(kwvals[2]);
+static void
+root_obj_check_moved_i(const char *category, VALUE obj, void *data)
+{
+ if (gc_object_moved_p(&rb_objspace, obj)) {
+ rb_bug("ROOT %s points to MOVED: %p -> %s\n", category, (void *)obj, obj_info(rb_gc_location(obj)));
}
+}
- garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, GPR_FLAG_METHOD);
- gc_finalize_deferred(objspace);
+static void
+reachable_object_check_moved_i(VALUE ref, void *data)
+{
+ VALUE parent = (VALUE)data;
+ if (gc_object_moved_p(&rb_objspace, ref)) {
+ rb_bug("Object %s points to MOVED: %p -> %s\n", obj_info(parent), (void *)ref, obj_info(rb_gc_location(ref)));
+ }
+}
- return Qnil;
+static int
+heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data)
+{
+ VALUE v = (VALUE)vstart;
+ for (; v != (VALUE)vend; v += stride) {
+ if (gc_object_moved_p(&rb_objspace, v)) {
+ /* Moved object still on the heap, something may have a reference. */
+ }
+ else {
+ void *poisoned = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
+ switch (BUILTIN_TYPE(v)) {
+ case T_NONE:
+ case T_ZOMBIE:
+ break;
+ default:
+ if (!rb_objspace_garbage_object_p(v)) {
+ rb_objspace_reachable_objects_from(v, reachable_object_check_moved_i, (void *)v);
+ }
+ }
+
+ if (poisoned) {
+ GC_ASSERT(BUILTIN_TYPE(v) == T_NONE);
+ asan_poison_object(v);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static VALUE
+gc_compact(rb_execution_context_t *ec, VALUE self)
+{
+ /* Run GC with compaction enabled */
+ gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
+
+ return gc_compact_stats(ec, self);
+}
+
+static VALUE
+gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE double_heap, VALUE toward_empty)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+
+ /* Clear the heap. */
+ gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qfalse);
+
+ RB_VM_LOCK_ENTER();
+ {
+ gc_rest(objspace);
+
+ if (RTEST(double_heap)) {
+ heap_add_pages(objspace, heap_eden, heap_allocated_pages);
+ }
+
+ if (RTEST(toward_empty)) {
+ gc_sort_heap_by_empty_slots(objspace);
+ }
+ }
+ RB_VM_LOCK_LEAVE();
+
+ gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
+
+ objspace_reachable_objects_from_root(objspace, root_obj_check_moved_i, NULL);
+ objspace_each_objects(objspace, heap_check_moved_i, NULL);
+
+ return gc_compact_stats(ec, self);
}
VALUE
@@ -6710,8 +9497,8 @@ void
rb_gc(void)
{
rb_objspace_t *objspace = &rb_objspace;
- garbage_collect(objspace, TRUE, TRUE, TRUE, GPR_FLAG_CAPI);
- gc_finalize_deferred(objspace);
+ int reason = GPR_DEFAULT_REASON;
+ garbage_collect(objspace, reason);
}
int
@@ -6721,13 +9508,6 @@ rb_during_gc(void)
return during_gc;
}
-int
-rb_threadptr_during_gc(rb_thread_t *th)
-{
- rb_objspace_t *objspace = rb_objspace_of(th->vm);
- return during_gc;
-}
-
#if RGENGC_PROFILE >= 2
static const char *type_name(int type, VALUE obj);
@@ -6738,8 +9518,8 @@ gc_count_add_each_types(VALUE hash, const char *name, const size_t *types)
VALUE result = rb_hash_new_with_size(T_MASK);
int i;
for (i=0; i<T_MASK; i++) {
- const char *type = type_name(i, 0);
- rb_hash_aset(result, ID2SYM(rb_intern(type)), SIZET2NUM(types[i]));
+ const char *type = type_name(i, 0);
+ rb_hash_aset(result, ID2SYM(rb_intern(type)), SIZET2NUM(types[i]));
}
rb_hash_aset(hash, ID2SYM(rb_intern(name)), result);
}
@@ -6751,18 +9531,8 @@ rb_gc_count(void)
return rb_objspace.profile.count;
}
-/*
- * call-seq:
- * GC.count -> Integer
- *
- * The number of times GC occurred.
- *
- * It returns the number of times GC occurred since the process started.
- *
- */
-
static VALUE
-gc_count(VALUE self)
+gc_count(rb_execution_context_t *ec, VALUE self)
{
return SIZET2NUM(rb_gc_count());
}
@@ -6782,47 +9552,47 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const int orig_
VALUE flags = orig_flags ? orig_flags : objspace->profile.latest_gc_info;
if (SYMBOL_P(hash_or_key)) {
- key = hash_or_key;
+ key = hash_or_key;
}
else if (RB_TYPE_P(hash_or_key, T_HASH)) {
- hash = hash_or_key;
+ hash = hash_or_key;
}
else {
- rb_raise(rb_eTypeError, "non-hash or symbol given");
+ rb_raise(rb_eTypeError, "non-hash or symbol given");
}
if (sym_major_by == Qnil) {
#define S(s) sym_##s = ID2SYM(rb_intern_const(#s))
- S(major_by);
- S(gc_by);
- S(immediate_sweep);
- S(have_finalizer);
- S(state);
-
- S(stress);
- S(nofree);
- S(oldgen);
- S(shady);
- S(force);
+ S(major_by);
+ S(gc_by);
+ S(immediate_sweep);
+ S(have_finalizer);
+ S(state);
+
+ S(stress);
+ S(nofree);
+ S(oldgen);
+ S(shady);
+ S(force);
#if RGENGC_ESTIMATE_OLDMALLOC
- S(oldmalloc);
+ S(oldmalloc);
#endif
- S(newobj);
- S(malloc);
- S(method);
- S(capi);
+ S(newobj);
+ S(malloc);
+ S(method);
+ S(capi);
- S(none);
- S(marking);
- S(sweeping);
+ S(none);
+ S(marking);
+ S(sweeping);
#undef S
}
#define SET(name, attr) \
if (key == sym_##name) \
- return (attr); \
+ return (attr); \
else if (hash != Qnil) \
- rb_hash_aset(hash, sym_##name, (attr));
+ rb_hash_aset(hash, sym_##name, (attr));
major_by =
(flags & GPR_FLAG_MAJOR_BY_NOFREE) ? sym_nofree :
@@ -6836,25 +9606,25 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const int orig_
SET(major_by, major_by);
SET(gc_by,
- (flags & GPR_FLAG_NEWOBJ) ? sym_newobj :
- (flags & GPR_FLAG_MALLOC) ? sym_malloc :
- (flags & GPR_FLAG_METHOD) ? sym_method :
- (flags & GPR_FLAG_CAPI) ? sym_capi :
- (flags & GPR_FLAG_STRESS) ? sym_stress :
- Qnil
+ (flags & GPR_FLAG_NEWOBJ) ? sym_newobj :
+ (flags & GPR_FLAG_MALLOC) ? sym_malloc :
+ (flags & GPR_FLAG_METHOD) ? sym_method :
+ (flags & GPR_FLAG_CAPI) ? sym_capi :
+ (flags & GPR_FLAG_STRESS) ? sym_stress :
+ Qnil
);
SET(have_finalizer, (flags & GPR_FLAG_HAVE_FINALIZE) ? Qtrue : Qfalse);
SET(immediate_sweep, (flags & GPR_FLAG_IMMEDIATE_SWEEP) ? Qtrue : Qfalse);
if (orig_flags == 0) {
- SET(state, gc_mode(objspace) == gc_mode_none ? sym_none :
- gc_mode(objspace) == gc_mode_marking ? sym_marking : sym_sweeping);
+ SET(state, gc_mode(objspace) == gc_mode_none ? sym_none :
+ gc_mode(objspace) == gc_mode_marking ? sym_marking : sym_sweeping);
}
#undef SET
if (!NIL_P(key)) {/* matched key should return above */
- rb_raise(rb_eArgError, "unknown key: %"PRIsVALUE, rb_sym2str(key));
+ rb_raise(rb_eArgError, "unknown key: %"PRIsVALUE, rb_sym2str(key));
}
return hash;
@@ -6867,29 +9637,16 @@ rb_gc_latest_gc_info(VALUE key)
return gc_info_decode(objspace, key, 0);
}
-/*
- * call-seq:
- * GC.latest_gc_info -> {:gc_by=>:newobj}
- * GC.latest_gc_info(hash) -> hash
- * GC.latest_gc_info(:major_by) -> :malloc
- *
- * Returns information about the most recent garbage collection.
- */
-
static VALUE
-gc_latest_gc_info(int argc, VALUE *argv, VALUE self)
+gc_latest_gc_info(rb_execution_context_t *ec, VALUE self, VALUE arg)
{
rb_objspace_t *objspace = &rb_objspace;
- VALUE arg = Qnil;
- if (rb_scan_args(argc, argv, "01", &arg) == 1) {
- if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) {
- rb_raise(rb_eTypeError, "non-hash or symbol given");
- }
+ if (NIL_P(arg)) {
+ arg = rb_hash_new();
}
-
- if (arg == Qnil) {
- arg = rb_hash_new();
+ else if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) {
+ rb_raise(rb_eTypeError, "non-hash or symbol given");
}
return gc_info_decode(objspace, arg, 0);
@@ -6913,9 +9670,11 @@ enum gc_stat_sym {
gc_stat_sym_total_freed_objects,
gc_stat_sym_malloc_increase_bytes,
gc_stat_sym_malloc_increase_bytes_limit,
-#if USE_RGENGC
gc_stat_sym_minor_gc_count,
gc_stat_sym_major_gc_count,
+ gc_stat_sym_compact_count,
+ gc_stat_sym_read_barrier_faults,
+ gc_stat_sym_total_moved_objects,
gc_stat_sym_remembered_wb_unprotected_objects,
gc_stat_sym_remembered_wb_unprotected_objects_limit,
gc_stat_sym_old_objects,
@@ -6932,40 +9691,10 @@ enum gc_stat_sym {
gc_stat_sym_total_remembered_normal_object_count,
gc_stat_sym_total_remembered_shady_object_count,
#endif
-#endif
gc_stat_sym_last
};
-enum gc_stat_compat_sym {
- gc_stat_compat_sym_gc_stat_heap_used,
- gc_stat_compat_sym_heap_eden_page_length,
- gc_stat_compat_sym_heap_tomb_page_length,
- gc_stat_compat_sym_heap_increment,
- gc_stat_compat_sym_heap_length,
- gc_stat_compat_sym_heap_live_slot,
- gc_stat_compat_sym_heap_free_slot,
- gc_stat_compat_sym_heap_final_slot,
- gc_stat_compat_sym_heap_swept_slot,
-#if USE_RGENGC
- gc_stat_compat_sym_remembered_shady_object,
- gc_stat_compat_sym_remembered_shady_object_limit,
- gc_stat_compat_sym_old_object,
- gc_stat_compat_sym_old_object_limit,
-#endif
- gc_stat_compat_sym_total_allocated_object,
- gc_stat_compat_sym_total_freed_object,
- gc_stat_compat_sym_malloc_increase,
- gc_stat_compat_sym_malloc_limit,
-#if RGENGC_ESTIMATE_OLDMALLOC
- gc_stat_compat_sym_oldmalloc_increase,
- gc_stat_compat_sym_oldmalloc_limit,
-#endif
- gc_stat_compat_sym_last
-};
-
static VALUE gc_stat_symbols[gc_stat_sym_last];
-static VALUE gc_stat_compat_symbols[gc_stat_compat_sym_last];
-static VALUE gc_stat_compat_table;
static void
setup_gc_stat_symbols(void)
@@ -6989,9 +9718,11 @@ setup_gc_stat_symbols(void)
S(total_freed_objects);
S(malloc_increase_bytes);
S(malloc_increase_bytes_limit);
-#if USE_RGENGC
S(minor_gc_count);
S(major_gc_count);
+ S(compact_count);
+ S(read_barrier_faults);
+ S(total_moved_objects);
S(remembered_wb_unprotected_objects);
S(remembered_wb_unprotected_objects_limit);
S(old_objects);
@@ -7008,106 +9739,10 @@ setup_gc_stat_symbols(void)
S(total_remembered_normal_object_count);
S(total_remembered_shady_object_count);
#endif /* RGENGC_PROFILE */
-#endif /* USE_RGENGC */
-#undef S
-#define S(s) gc_stat_compat_symbols[gc_stat_compat_sym_##s] = ID2SYM(rb_intern_const(#s))
- S(gc_stat_heap_used);
- S(heap_eden_page_length);
- S(heap_tomb_page_length);
- S(heap_increment);
- S(heap_length);
- S(heap_live_slot);
- S(heap_free_slot);
- S(heap_final_slot);
- S(heap_swept_slot);
-#if USE_RGEGC
- S(remembered_shady_object);
- S(remembered_shady_object_limit);
- S(old_object);
- S(old_object_limit);
-#endif
- S(total_allocated_object);
- S(total_freed_object);
- S(malloc_increase);
- S(malloc_limit);
-#if RGENGC_ESTIMATE_OLDMALLOC
- S(oldmalloc_increase);
- S(oldmalloc_limit);
-#endif
#undef S
-
- {
- VALUE table = gc_stat_compat_table = rb_hash_new();
- rb_obj_hide(table);
- rb_gc_register_mark_object(table);
-
- /* compatibility layer for Ruby 2.1 */
-#define OLD_SYM(s) gc_stat_compat_symbols[gc_stat_compat_sym_##s]
-#define NEW_SYM(s) gc_stat_symbols[gc_stat_sym_##s]
- rb_hash_aset(table, OLD_SYM(gc_stat_heap_used), NEW_SYM(heap_allocated_pages));
- rb_hash_aset(table, OLD_SYM(heap_eden_page_length), NEW_SYM(heap_eden_pages));
- rb_hash_aset(table, OLD_SYM(heap_tomb_page_length), NEW_SYM(heap_tomb_pages));
- rb_hash_aset(table, OLD_SYM(heap_increment), NEW_SYM(heap_allocatable_pages));
- rb_hash_aset(table, OLD_SYM(heap_length), NEW_SYM(heap_sorted_length));
- rb_hash_aset(table, OLD_SYM(heap_live_slot), NEW_SYM(heap_live_slots));
- rb_hash_aset(table, OLD_SYM(heap_free_slot), NEW_SYM(heap_free_slots));
- rb_hash_aset(table, OLD_SYM(heap_final_slot), NEW_SYM(heap_final_slots));
-#if USE_RGEGC
- rb_hash_aset(table, OLD_SYM(remembered_shady_object), NEW_SYM(remembered_wb_unprotected_objects));
- rb_hash_aset(table, OLD_SYM(remembered_shady_object_limit), NEW_SYM(remembered_wb_unprotected_objects_limit));
- rb_hash_aset(table, OLD_SYM(old_object), NEW_SYM(old_objects));
- rb_hash_aset(table, OLD_SYM(old_object_limit), NEW_SYM(old_objects_limit));
-#endif
- rb_hash_aset(table, OLD_SYM(total_allocated_object), NEW_SYM(total_allocated_objects));
- rb_hash_aset(table, OLD_SYM(total_freed_object), NEW_SYM(total_freed_objects));
- rb_hash_aset(table, OLD_SYM(malloc_increase), NEW_SYM(malloc_increase_bytes));
- rb_hash_aset(table, OLD_SYM(malloc_limit), NEW_SYM(malloc_increase_bytes_limit));
-#if RGENGC_ESTIMATE_OLDMALLOC
- rb_hash_aset(table, OLD_SYM(oldmalloc_increase), NEW_SYM(oldmalloc_increase_bytes));
- rb_hash_aset(table, OLD_SYM(oldmalloc_limit), NEW_SYM(oldmalloc_increase_bytes_limit));
-#endif
-#undef OLD_SYM
-#undef NEW_SYM
- rb_obj_freeze(table);
- }
}
}
-static VALUE
-compat_key(VALUE key)
-{
- VALUE new_key = rb_hash_lookup(gc_stat_compat_table, key);
-
- if (!NIL_P(new_key)) {
- static int warned = 0;
- if (warned == 0) {
- rb_warn("GC.stat keys were changed from Ruby 2.1. "
- "In this case, you refer to obsolete `%"PRIsVALUE"' (new key is `%"PRIsVALUE"'). "
- "Please check <https://bugs.ruby-lang.org/issues/9924> for more information.",
- key, new_key);
- warned = 1;
- }
- }
-
- return new_key;
-}
-
-static VALUE
-default_proc_for_compat_func(VALUE hash, VALUE dmy, int argc, VALUE *argv)
-{
- VALUE key, new_key;
-
- Check_Type(hash, T_HASH);
- rb_check_arity(argc, 2, 2);
- key = argv[1];
-
- if ((new_key = compat_key(key)) != Qnil) {
- return rb_hash_lookup(hash, new_key);
- }
-
- return Qnil;
-}
-
static size_t
gc_stat_internal(VALUE hash_or_sym)
{
@@ -7118,15 +9753,6 @@ gc_stat_internal(VALUE hash_or_sym)
if (RB_TYPE_P(hash_or_sym, T_HASH)) {
hash = hash_or_sym;
-
- if (NIL_P(RHASH_IFNONE(hash))) {
- static VALUE default_proc_for_compat = 0;
- if (default_proc_for_compat == 0) { /* TODO: it should be */
- default_proc_for_compat = rb_proc_new(default_proc_for_compat_func, Qnil);
- rb_gc_register_mark_object(default_proc_for_compat);
- }
- rb_hash_set_default_proc(hash, default_proc_for_compat);
- }
}
else if (SYMBOL_P(hash_or_sym)) {
key = hash_or_sym;
@@ -7141,7 +9767,6 @@ gc_stat_internal(VALUE hash_or_sym)
else if (hash != Qnil) \
rb_hash_aset(hash, gc_stat_symbols[gc_stat_sym_##name], SIZET2NUM(attr));
- again:
SET(count, objspace->profile.count);
/* implementation dependent counters */
@@ -7161,9 +9786,11 @@ gc_stat_internal(VALUE hash_or_sym)
SET(total_freed_objects, objspace->profile.total_freed_objects);
SET(malloc_increase_bytes, malloc_increase);
SET(malloc_increase_bytes_limit, malloc_limit);
-#if USE_RGENGC
SET(minor_gc_count, objspace->profile.minor_gc_count);
SET(major_gc_count, objspace->profile.major_gc_count);
+ SET(compact_count, objspace->profile.compact_count);
+ SET(read_barrier_faults, objspace->profile.read_barrier_faults);
+ SET(total_moved_objects, objspace->rcompactor.total_moved);
SET(remembered_wb_unprotected_objects, objspace->rgengc.uncollectible_wb_unprotected_objects);
SET(remembered_wb_unprotected_objects_limit, objspace->rgengc.uncollectible_wb_unprotected_objects_limit);
SET(old_objects, objspace->rgengc.old_objects);
@@ -7181,15 +9808,9 @@ gc_stat_internal(VALUE hash_or_sym)
SET(total_remembered_normal_object_count, objspace->profile.total_remembered_normal_object_count);
SET(total_remembered_shady_object_count, objspace->profile.total_remembered_shady_object_count);
#endif /* RGENGC_PROFILE */
-#endif /* USE_RGENGC */
#undef SET
if (!NIL_P(key)) { /* matched key should return above */
- VALUE new_key;
- if ((new_key = compat_key(key)) != Qnil) {
- key = new_key;
- goto again;
- }
rb_raise(rb_eArgError, "unknown key: %"PRIsVALUE, rb_sym2str(key));
}
@@ -7207,69 +9828,23 @@ gc_stat_internal(VALUE hash_or_sym)
return 0;
}
-/*
- * call-seq:
- * GC.stat -> Hash
- * GC.stat(hash) -> hash
- * GC.stat(:key) -> Numeric
- *
- * Returns a Hash containing information about the GC.
- *
- * The hash includes information about internal statistics about GC such as:
- *
- * {
- * :count=>0,
- * :heap_allocated_pages=>24,
- * :heap_sorted_length=>24,
- * :heap_allocatable_pages=>0,
- * :heap_available_slots=>9783,
- * :heap_live_slots=>7713,
- * :heap_free_slots=>2070,
- * :heap_final_slots=>0,
- * :heap_marked_slots=>0,
- * :heap_eden_pages=>24,
- * :heap_tomb_pages=>0,
- * :total_allocated_pages=>24,
- * :total_freed_pages=>0,
- * :total_allocated_objects=>7796,
- * :total_freed_objects=>83,
- * :malloc_increase_bytes=>2389312,
- * :malloc_increase_bytes_limit=>16777216,
- * :minor_gc_count=>0,
- * :major_gc_count=>0,
- * :remembered_wb_unprotected_objects=>0,
- * :remembered_wb_unprotected_objects_limit=>0,
- * :old_objects=>0,
- * :old_objects_limit=>0,
- * :oldmalloc_increase_bytes=>2389760,
- * :oldmalloc_increase_bytes_limit=>16777216
- * }
- *
- * The contents of the hash are implementation specific and may be changed in
- * the future.
- *
- * This method is only expected to work on C Ruby.
- *
- */
-
static VALUE
-gc_stat(int argc, VALUE *argv, VALUE self)
+gc_stat(rb_execution_context_t *ec, VALUE self, VALUE arg) // arg is (nil || hash || symbol)
{
- VALUE arg = Qnil;
-
- if (rb_scan_args(argc, argv, "01", &arg) == 1) {
- if (SYMBOL_P(arg)) {
- size_t value = gc_stat_internal(arg);
- return SIZET2NUM(value);
- }
- else if (!RB_TYPE_P(arg, T_HASH)) {
- rb_raise(rb_eTypeError, "non-hash or symbol given");
- }
- }
-
- if (arg == Qnil) {
+ if (NIL_P(arg)) {
arg = rb_hash_new();
}
+ else if (SYMBOL_P(arg)) {
+ size_t value = gc_stat_internal(arg);
+ return SIZET2NUM(value);
+ }
+ else if (RB_TYPE_P(arg, T_HASH)) {
+ // ok
+ }
+ else {
+ rb_raise(rb_eTypeError, "non-hash or symbol given");
+ }
+
gc_stat_internal(arg);
return arg;
}
@@ -7287,15 +9862,8 @@ rb_gc_stat(VALUE key)
}
}
-/*
- * call-seq:
- * GC.stress -> integer, true or false
- *
- * Returns current status of GC stress mode.
- */
-
static VALUE
-gc_stress_get(VALUE self)
+gc_stress_get(rb_execution_context_t *ec, VALUE self)
{
rb_objspace_t *objspace = &rb_objspace;
return ruby_gc_stress_mode;
@@ -7308,76 +9876,92 @@ gc_stress_set(rb_objspace_t *objspace, VALUE flag)
objspace->gc_stress_mode = flag;
}
-/*
- * call-seq:
- * GC.stress = flag -> flag
- *
- * Updates the GC stress mode.
- *
- * When stress mode is enabled, the GC is invoked at every GC opportunity:
- * all memory and object allocations.
- *
- * Enabling stress mode will degrade performance, it is only for debugging.
- *
- * flag can be true, false, or an integer bit-ORed following flags.
- * 0x01:: no major GC
- * 0x02:: no immediate sweep
- * 0x04:: full mark after malloc/calloc/realloc
- */
-
static VALUE
-gc_stress_set_m(VALUE self, VALUE flag)
+gc_stress_set_m(rb_execution_context_t *ec, VALUE self, VALUE flag)
{
rb_objspace_t *objspace = &rb_objspace;
gc_stress_set(objspace, flag);
return flag;
}
-/*
- * call-seq:
- * GC.enable -> true or false
- *
- * Enables garbage collection, returning +true+ if garbage
- * collection was previously disabled.
- *
- * GC.disable #=> false
- * GC.enable #=> true
- * GC.enable #=> false
- *
- */
-
VALUE
rb_gc_enable(void)
{
rb_objspace_t *objspace = &rb_objspace;
- int old = dont_gc;
+ return rb_objspace_gc_enable(objspace);
+}
- dont_gc = FALSE;
+VALUE
+rb_objspace_gc_enable(rb_objspace_t *objspace)
+{
+ int old = dont_gc_val();
+
+ dont_gc_off();
return old ? Qtrue : Qfalse;
}
-/*
- * call-seq:
- * GC.disable -> true or false
- *
- * Disables garbage collection, returning +true+ if garbage
- * collection was already disabled.
- *
- * GC.disable #=> false
- * GC.disable #=> true
- *
- */
+static VALUE
+gc_enable(rb_execution_context_t *ec, VALUE _)
+{
+ return rb_gc_enable();
+}
+
+VALUE
+rb_gc_disable_no_rest(void)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+ return gc_disable_no_rest(objspace);
+}
+
+static VALUE
+gc_disable_no_rest(rb_objspace_t *objspace)
+{
+ int old = dont_gc_val();
+ dont_gc_on();
+ return old ? Qtrue : Qfalse;
+}
VALUE
rb_gc_disable(void)
{
rb_objspace_t *objspace = &rb_objspace;
- int old = dont_gc;
+ return rb_objspace_gc_disable(objspace);
+}
+VALUE
+rb_objspace_gc_disable(rb_objspace_t *objspace)
+{
gc_rest(objspace);
+ return gc_disable_no_rest(objspace);
+}
- dont_gc = TRUE;
- return old ? Qtrue : Qfalse;
+static VALUE
+gc_disable(rb_execution_context_t *ec, VALUE _)
+{
+ return rb_gc_disable();
+}
+
+static VALUE
+gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v)
+{
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+ /* If Ruby's heap pages are not a multiple of the system page size, we
+ * cannot use mprotect for the read barrier, so we must disable automatic
+ * compaction. */
+ int pagesize;
+ pagesize = (int)sysconf(_SC_PAGE_SIZE);
+ if ((HEAP_PAGE_SIZE % pagesize) != 0) {
+ rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this platform");
+ }
+#endif
+ ruby_enable_autocompact = RTEST(v);
+ return v;
+}
+
+static VALUE
+gc_get_auto_compact(rb_execution_context_t *ec, VALUE _)
+{
+ return ruby_enable_autocompact ? Qtrue : Qfalse;
}
static int
@@ -7469,13 +10053,15 @@ get_envparam_double(const char *name, double *default_value, double lower_bound,
}
}
else {
- accept:
- if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%f (default value: %f)\n", name, val, *default_value);
- *default_value = val;
- return 1;
+ goto accept;
}
}
return 0;
+
+ accept:
+ if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%f (default value: %f)\n", name, val, *default_value);
+ *default_value = val;
+ return 1;
}
static void
@@ -7533,26 +10119,17 @@ gc_set_initial_pages(void)
*/
void
-ruby_gc_set_params(int safe_level)
+ruby_gc_set_params(void)
{
- if (safe_level > 0) return;
-
/* RUBY_GC_HEAP_FREE_SLOTS */
if (get_envparam_size("RUBY_GC_HEAP_FREE_SLOTS", &gc_params.heap_free_slots, 0)) {
/* ok */
}
- else if (get_envparam_size("RUBY_FREE_MIN", &gc_params.heap_free_slots, 0)) {
- rb_warn("RUBY_FREE_MIN is obsolete. Use RUBY_GC_HEAP_FREE_SLOTS instead.");
- }
/* RUBY_GC_HEAP_INIT_SLOTS */
if (get_envparam_size("RUBY_GC_HEAP_INIT_SLOTS", &gc_params.heap_init_slots, 0)) {
gc_set_initial_pages();
}
- else if (get_envparam_size("RUBY_HEAP_MIN_SLOTS", &gc_params.heap_init_slots, 0)) {
- rb_warn("RUBY_HEAP_MIN_SLOTS is obsolete. Use RUBY_GC_HEAP_INIT_SLOTS instead.");
- gc_set_initial_pages();
- }
get_envparam_double("RUBY_GC_HEAP_GROWTH_FACTOR", &gc_params.growth_factor, 1.0, 0.0, FALSE);
get_envparam_size ("RUBY_GC_HEAP_GROWTH_MAX_SLOTS", &gc_params.growth_max_slots, 0);
@@ -7566,6 +10143,9 @@ ruby_gc_set_params(int safe_level)
get_envparam_size ("RUBY_GC_MALLOC_LIMIT", &gc_params.malloc_limit_min, 0);
get_envparam_size ("RUBY_GC_MALLOC_LIMIT_MAX", &gc_params.malloc_limit_max, 0);
+ if (!gc_params.malloc_limit_max) { /* ignore max-check if 0 */
+ gc_params.malloc_limit_max = SIZE_MAX;
+ }
get_envparam_double("RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR", &gc_params.malloc_limit_growth_factor, 1.0, 0.0, FALSE);
#if RGENGC_ESTIMATE_OLDMALLOC
@@ -7578,18 +10158,30 @@ ruby_gc_set_params(int safe_level)
#endif
}
+static void
+reachable_objects_from_callback(VALUE obj)
+{
+ rb_ractor_t *cr = GET_RACTOR();
+ cr->mfd->mark_func(obj, cr->mfd->data);
+}
+
void
rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data)
{
rb_objspace_t *objspace = &rb_objspace;
+ if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true");
+
if (is_markable_object(objspace, obj)) {
- struct mark_func_data_struct mfd;
- mfd.mark_func = func;
- mfd.data = data;
- PUSH_MARK_FUNC_DATA(&mfd);
+ rb_ractor_t *cr = GET_RACTOR();
+ struct gc_mark_func_data_struct mfd = {
+ .mark_func = func,
+ .data = data,
+ }, *prev_mfd = cr->mfd;
+
+ cr->mfd = &mfd;
gc_mark_children(objspace, obj);
- POP_MARK_FUNC_DATA();
+ cr->mfd = prev_mfd;
}
}
@@ -7610,48 +10202,80 @@ void
rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *passing_data)
{
rb_objspace_t *objspace = &rb_objspace;
- struct root_objects_data data;
- struct mark_func_data_struct mfd;
+ objspace_reachable_objects_from_root(objspace, func, passing_data);
+}
- data.func = func;
- data.data = passing_data;
+static void
+objspace_reachable_objects_from_root(rb_objspace_t *objspace, void (func)(const char *category, VALUE, void *), void *passing_data)
+{
+ if (during_gc) rb_bug("objspace_reachable_objects_from_root() is not supported while during_gc == true");
- mfd.mark_func = root_objects_from;
- mfd.data = &data;
+ rb_ractor_t *cr = GET_RACTOR();
+ struct root_objects_data data = {
+ .func = func,
+ .data = passing_data,
+ };
+ struct gc_mark_func_data_struct mfd = {
+ .mark_func = root_objects_from,
+ .data = &data,
+ }, *prev_mfd = cr->mfd;
- PUSH_MARK_FUNC_DATA(&mfd);
+ cr->mfd = &mfd;
gc_mark_roots(objspace, &data.category);
- POP_MARK_FUNC_DATA();
+ cr->mfd = prev_mfd;
}
/*
------------------------ Extended allocator ------------------------
*/
-static void objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t size);
+struct gc_raise_tag {
+ VALUE exc;
+ const char *fmt;
+ va_list *ap;
+};
static void *
-negative_size_allocation_error_with_gvl(void *ptr)
+gc_vraise(void *ptr)
{
- rb_raise(rb_eNoMemError, "%s", (const char *)ptr);
- return 0; /* should not be reached */
+ struct gc_raise_tag *argv = ptr;
+ rb_vraise(argv->exc, argv->fmt, *argv->ap);
+ UNREACHABLE_RETURN(NULL);
}
static void
-negative_size_allocation_error(const char *msg)
+gc_raise(VALUE exc, const char *fmt, ...)
{
+ va_list ap;
+ va_start(ap, fmt);
+ struct gc_raise_tag argv = {
+ exc, fmt, &ap,
+ };
+
if (ruby_thread_has_gvl_p()) {
- rb_raise(rb_eNoMemError, "%s", msg);
+ gc_vraise(&argv);
+ UNREACHABLE;
+ }
+ else if (ruby_native_thread_p()) {
+ rb_thread_call_with_gvl(gc_vraise, &argv);
+ UNREACHABLE;
}
else {
- if (ruby_native_thread_p()) {
- rb_thread_call_with_gvl(negative_size_allocation_error_with_gvl, (void *)msg);
- }
- else {
- fprintf(stderr, "[FATAL] %s\n", msg);
- exit(EXIT_FAILURE);
- }
+ /* Not in a ruby thread */
+ fprintf(stderr, "%s", "[FATAL] ");
+ vfprintf(stderr, fmt, ap);
}
+
+ va_end(ap);
+ abort();
+}
+
+static void objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t size);
+
+static void
+negative_size_allocation_error(const char *msg)
+{
+ gc_raise(rb_eNoMemError, "%s", msg);
}
static void *
@@ -7661,6 +10285,8 @@ ruby_memerror_body(void *dummy)
return 0;
}
+NORETURN(static void ruby_memerror(void));
+RBIMPL_ATTR_MAYBE_UNUSED()
static void
ruby_memerror(void)
{
@@ -7674,39 +10300,48 @@ ruby_memerror(void)
else {
/* no ruby thread */
fprintf(stderr, "[FATAL] failed to allocate memory\n");
- exit(EXIT_FAILURE);
}
}
+ exit(EXIT_FAILURE);
}
void
rb_memerror(void)
{
- rb_thread_t *th = GET_THREAD();
- rb_objspace_t *objspace = rb_objspace_of(th->vm);
+ rb_execution_context_t *ec = GET_EC();
+ rb_objspace_t *objspace = rb_objspace_of(rb_ec_vm_ptr(ec));
VALUE exc;
- if (during_gc) gc_exit(objspace, "rb_memerror");
+ if (0) {
+ // Print out pid, sleep, so you can attach debugger to see what went wrong:
+ fprintf(stderr, "rb_memerror pid=%"PRI_PIDT_PREFIX"d\n", getpid());
+ sleep(60);
+ }
+
+ if (during_gc) {
+ // TODO: OMG!! How to implement it?
+ gc_exit(objspace, gc_enter_event_rb_memerror, NULL);
+ }
exc = nomem_error;
if (!exc ||
- rb_thread_raised_p(th, RAISED_NOMEMORY)) {
+ rb_ec_raised_p(ec, RAISED_NOMEMORY)) {
fprintf(stderr, "[FATAL] failed to allocate memory\n");
exit(EXIT_FAILURE);
}
- if (rb_thread_raised_p(th, RAISED_NOMEMORY)) {
- rb_thread_raised_clear(th);
+ if (rb_ec_raised_p(ec, RAISED_NOMEMORY)) {
+ rb_ec_raised_clear(ec);
}
else {
- rb_thread_raised_set(th, RAISED_NOMEMORY);
+ rb_ec_raised_set(ec, RAISED_NOMEMORY);
exc = ruby_vm_special_exception_copy(exc);
}
- th->ec.errinfo = exc;
- TH_JUMP_TAG(th, TAG_RAISE);
+ ec->errinfo = exc;
+ EC_JUMP_TAG(ec, TAG_RAISE);
}
-static void *
-aligned_malloc(size_t alignment, size_t size)
+void *
+rb_aligned_malloc(size_t alignment, size_t size)
{
void *res;
@@ -7740,7 +10375,7 @@ aligned_malloc(size_t alignment, size_t size)
}
static void
-aligned_free(void *ptr)
+rb_aligned_free(void *ptr)
{
#if defined __MINGW32__
__mingw_aligned_free(ptr);
@@ -7764,9 +10399,9 @@ objspace_malloc_size(rb_objspace_t *objspace, void *ptr, size_t hint)
}
enum memop_type {
- MEMOP_TYPE_MALLOC = 1,
- MEMOP_TYPE_FREE = 2,
- MEMOP_TYPE_REALLOC = 3
+ MEMOP_TYPE_MALLOC = 0,
+ MEMOP_TYPE_FREE,
+ MEMOP_TYPE_REALLOC
};
static inline void
@@ -7785,7 +10420,13 @@ static void
objspace_malloc_gc_stress(rb_objspace_t *objspace)
{
if (ruby_gc_stressful && ruby_native_thread_p()) {
- garbage_collect_with_gvl(objspace, gc_stress_full_mark_after_malloc_p(), TRUE, TRUE, GPR_FLAG_STRESS | GPR_FLAG_MALLOC);
+ int reason = GPR_FLAG_IMMEDIATE_MARK | GPR_FLAG_IMMEDIATE_SWEEP |
+ GPR_FLAG_STRESS | GPR_FLAG_MALLOC;
+
+ if (gc_stress_full_mark_after_malloc_p()) {
+ reason |= GPR_FLAG_FULL_MARK;
+ }
+ garbage_collect_with_gvl(objspace, reason);
}
}
@@ -7807,12 +10448,12 @@ objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, si
if (type == MEMOP_TYPE_MALLOC) {
retry:
- if (malloc_increase > malloc_limit && ruby_native_thread_p() && !dont_gc) {
+ if (malloc_increase > malloc_limit && ruby_native_thread_p() && !dont_gc_val()) {
if (ruby_thread_has_gvl_p() && is_lazy_sweeping(heap_eden)) {
gc_rest(objspace); /* gc_rest can reduce malloc_increase */
goto retry;
}
- garbage_collect_with_gvl(objspace, FALSE, FALSE, FALSE, GPR_FLAG_MALLOC);
+ garbage_collect_with_gvl(objspace, GPR_FLAG_MALLOC);
}
}
@@ -7832,12 +10473,12 @@ objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, si
atomic_sub_nounderflow(&objspace->malloc_params.allocated_size, dec_size);
}
- if (0) fprintf(stderr, "increase - ptr: %p, type: %s, new_size: %d, old_size: %d\n",
+ if (0) fprintf(stderr, "increase - ptr: %p, type: %s, new_size: %"PRIdSIZE", old_size: %"PRIdSIZE"\n",
mem,
type == MEMOP_TYPE_MALLOC ? "malloc" :
type == MEMOP_TYPE_FREE ? "free " :
type == MEMOP_TYPE_REALLOC ? "realloc": "error",
- (int)new_size, (int)old_size);
+ new_size, old_size);
switch (type) {
case MEMOP_TYPE_MALLOC:
@@ -7861,13 +10502,27 @@ objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, si
#endif
}
+struct malloc_obj_info { /* 4 words */
+ size_t size;
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ size_t gen;
+ const char *file;
+ size_t line;
+#endif
+};
+
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+const char *ruby_malloc_info_file;
+int ruby_malloc_info_line;
+#endif
+
static inline size_t
objspace_malloc_prepare(rb_objspace_t *objspace, size_t size)
{
if (size == 0) size = 1;
#if CALC_EXACT_MALLOC_SIZE
- size += sizeof(size_t);
+ size += sizeof(struct malloc_obj_info);
#endif
return size;
@@ -7880,24 +10535,65 @@ objspace_malloc_fixup(rb_objspace_t *objspace, void *mem, size_t size)
objspace_malloc_increase(objspace, mem, size, 0, MEMOP_TYPE_MALLOC);
#if CALC_EXACT_MALLOC_SIZE
- ((size_t *)mem)[0] = size;
- mem = (size_t *)mem + 1;
+ {
+ struct malloc_obj_info *info = mem;
+ info->size = size;
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ info->gen = objspace->profile.count;
+ info->file = ruby_malloc_info_file;
+ info->line = info->file ? ruby_malloc_info_line : 0;
+#endif
+ mem = info + 1;
+ }
#endif
return mem;
}
-#define TRY_WITH_GC(alloc) do { \
+#if defined(__GNUC__) && RUBY_DEBUG
+#define RB_BUG_INSTEAD_OF_RB_MEMERROR
+#endif
+
+#ifdef RB_BUG_INSTEAD_OF_RB_MEMERROR
+#define TRY_WITH_GC(siz, expr) do { \
+ const gc_profile_record_flag gpr = \
+ GPR_FLAG_FULL_MARK | \
+ GPR_FLAG_IMMEDIATE_MARK | \
+ GPR_FLAG_IMMEDIATE_SWEEP | \
+ GPR_FLAG_MALLOC; \
+ objspace_malloc_gc_stress(objspace); \
+ \
+ if (LIKELY((expr))) { \
+ /* Success on 1st try */ \
+ } \
+ else if (!garbage_collect_with_gvl(objspace, gpr)) { \
+ /* @shyouhei thinks this doesn't happen */ \
+ rb_bug("TRY_WITH_GC: could not GC"); \
+ } \
+ else if ((expr)) { \
+ /* Success on 2nd try */ \
+ } \
+ else { \
+ rb_bug("TRY_WITH_GC: could not allocate:" \
+ "%"PRIdSIZE" bytes for %s", \
+ siz, # expr); \
+ } \
+ } while (0)
+#else
+#define TRY_WITH_GC(siz, alloc) do { \
objspace_malloc_gc_stress(objspace); \
if (!(alloc) && \
- (!garbage_collect_with_gvl(objspace, TRUE, TRUE, TRUE, GPR_FLAG_MALLOC) || /* full/immediate mark && immediate sweep */ \
+ (!garbage_collect_with_gvl(objspace, GPR_FLAG_FULL_MARK | \
+ GPR_FLAG_IMMEDIATE_MARK | GPR_FLAG_IMMEDIATE_SWEEP | \
+ GPR_FLAG_MALLOC) || \
!(alloc))) { \
ruby_memerror(); \
} \
} while (0)
+#endif
/* these shouldn't be called directly.
- * objspace_* functinos do not check allocation size.
+ * objspace_* functions do not check allocation size.
*/
static void *
objspace_xmalloc0(rb_objspace_t *objspace, size_t size)
@@ -7905,18 +10601,15 @@ objspace_xmalloc0(rb_objspace_t *objspace, size_t size)
void *mem;
size = objspace_malloc_prepare(objspace, size);
- TRY_WITH_GC(mem = malloc(size));
+ TRY_WITH_GC(size, mem = malloc(size));
+ RB_DEBUG_COUNTER_INC(heap_xmalloc);
return objspace_malloc_fixup(objspace, mem, size);
}
static inline size_t
xmalloc2_size(const size_t count, const size_t elsize)
{
- size_t ret;
- if (rb_mul_size_overflow(count, elsize, SSIZE_MAX, &ret)) {
- ruby_malloc_size_overflow(count, elsize);
- }
- return ret;
+ return size_mul_or_raise(count, elsize, rb_eArgError);
}
static void *
@@ -7932,40 +10625,196 @@ objspace_xrealloc(rb_objspace_t *objspace, void *ptr, size_t new_size, size_t ol
* see http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_400.htm
*/
if (new_size == 0) {
- objspace_xfree(objspace, ptr, old_size);
- return 0;
+ if ((mem = objspace_xmalloc0(objspace, 0)) != NULL) {
+ /*
+ * - OpenBSD's malloc(3) man page says that when 0 is passed, it
+ * returns a non-NULL pointer to an access-protected memory page.
+ * The returned pointer cannot be read / written at all, but
+ * still be a valid argument of free().
+ *
+ * https://man.openbsd.org/malloc.3
+ *
+ * - Linux's malloc(3) man page says that it _might_ perhaps return
+ * a non-NULL pointer when its argument is 0. That return value
+ * is safe (and is expected) to be passed to free().
+ *
+ * http://man7.org/linux/man-pages/man3/malloc.3.html
+ *
+ * - As I read the implementation jemalloc's malloc() returns fully
+ * normal 16 bytes memory region when its argument is 0.
+ *
+ * - As I read the implementation musl libc's malloc() returns
+ * fully normal 32 bytes memory region when its argument is 0.
+ *
+ * - Other malloc implementations can also return non-NULL.
+ */
+ objspace_xfree(objspace, ptr, old_size);
+ return mem;
+ }
+ else {
+ /*
+ * It is dangerous to return NULL here, because that could lead to
+ * RCE. Fallback to 1 byte instead of zero.
+ *
+ * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11932
+ */
+ new_size = 1;
+ }
}
#if CALC_EXACT_MALLOC_SIZE
- new_size += sizeof(size_t);
- ptr = (size_t *)ptr - 1;
- old_size = ((size_t *)ptr)[0];
+ {
+ struct malloc_obj_info *info = (struct malloc_obj_info *)ptr - 1;
+ new_size += sizeof(struct malloc_obj_info);
+ ptr = info;
+ old_size = info->size;
+ }
#endif
old_size = objspace_malloc_size(objspace, ptr, old_size);
- TRY_WITH_GC(mem = realloc(ptr, new_size));
+ TRY_WITH_GC(new_size, mem = realloc(ptr, new_size));
new_size = objspace_malloc_size(objspace, mem, new_size);
#if CALC_EXACT_MALLOC_SIZE
- ((size_t *)mem)[0] = new_size;
- mem = (size_t *)mem + 1;
+ {
+ struct malloc_obj_info *info = mem;
+ info->size = new_size;
+ mem = info + 1;
+ }
#endif
objspace_malloc_increase(objspace, mem, new_size, old_size, MEMOP_TYPE_REALLOC);
+ RB_DEBUG_COUNTER_INC(heap_xrealloc);
return mem;
}
+#if CALC_EXACT_MALLOC_SIZE && USE_GC_MALLOC_OBJ_INFO_DETAILS
+
+#define MALLOC_INFO_GEN_SIZE 100
+#define MALLOC_INFO_SIZE_SIZE 10
+static size_t malloc_info_gen_cnt[MALLOC_INFO_GEN_SIZE];
+static size_t malloc_info_gen_size[MALLOC_INFO_GEN_SIZE];
+static size_t malloc_info_size[MALLOC_INFO_SIZE_SIZE+1];
+static st_table *malloc_info_file_table;
+
+static int
+mmalloc_info_file_i(st_data_t key, st_data_t val, st_data_t dmy)
+{
+ const char *file = (void *)key;
+ const size_t *data = (void *)val;
+
+ fprintf(stderr, "%s\t%"PRIdSIZE"\t%"PRIdSIZE"\n", file, data[0], data[1]);
+
+ return ST_CONTINUE;
+}
+
+__attribute__((destructor))
+void
+rb_malloc_info_show_results(void)
+{
+ int i;
+
+ fprintf(stderr, "* malloc_info gen statistics\n");
+ for (i=0; i<MALLOC_INFO_GEN_SIZE; i++) {
+ if (i == MALLOC_INFO_GEN_SIZE-1) {
+ fprintf(stderr, "more\t%"PRIdSIZE"\t%"PRIdSIZE"\n", malloc_info_gen_cnt[i], malloc_info_gen_size[i]);
+ }
+ else {
+ fprintf(stderr, "%d\t%"PRIdSIZE"\t%"PRIdSIZE"\n", i, malloc_info_gen_cnt[i], malloc_info_gen_size[i]);
+ }
+ }
+
+ fprintf(stderr, "* malloc_info size statistics\n");
+ for (i=0; i<MALLOC_INFO_SIZE_SIZE; i++) {
+ int s = 16 << i;
+ fprintf(stderr, "%d\t%"PRIdSIZE"\n", s, malloc_info_size[i]);
+ }
+ fprintf(stderr, "more\t%"PRIdSIZE"\n", malloc_info_size[i]);
+
+ if (malloc_info_file_table) {
+ fprintf(stderr, "* malloc_info file statistics\n");
+ st_foreach(malloc_info_file_table, mmalloc_info_file_i, 0);
+ }
+}
+#else
+void
+rb_malloc_info_show_results(void)
+{
+}
+#endif
+
static void
objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t old_size)
{
+ if (!ptr) {
+ /*
+ * ISO/IEC 9899 says "If ptr is a null pointer, no action occurs" since
+ * its first version. We would better follow.
+ */
+ return;
+ }
#if CALC_EXACT_MALLOC_SIZE
- ptr = ((size_t *)ptr) - 1;
- old_size = ((size_t*)ptr)[0];
+ struct malloc_obj_info *info = (struct malloc_obj_info *)ptr - 1;
+ ptr = info;
+ old_size = info->size;
+
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ {
+ int gen = (int)(objspace->profile.count - info->gen);
+ int gen_index = gen >= MALLOC_INFO_GEN_SIZE ? MALLOC_INFO_GEN_SIZE-1 : gen;
+ int i;
+
+ malloc_info_gen_cnt[gen_index]++;
+ malloc_info_gen_size[gen_index] += info->size;
+
+ for (i=0; i<MALLOC_INFO_SIZE_SIZE; i++) {
+ size_t s = 16 << i;
+ if (info->size <= s) {
+ malloc_info_size[i]++;
+ goto found;
+ }
+ }
+ malloc_info_size[i]++;
+ found:;
+
+ {
+ st_data_t key = (st_data_t)info->file, d;
+ size_t *data;
+
+ if (malloc_info_file_table == NULL) {
+ malloc_info_file_table = st_init_numtable_with_size(1024);
+ }
+ if (st_lookup(malloc_info_file_table, key, &d)) {
+ /* hit */
+ data = (size_t *)d;
+ }
+ else {
+ data = malloc(xmalloc2_size(2, sizeof(size_t)));
+ if (data == NULL) rb_bug("objspace_xfree: can not allocate memory");
+ data[0] = data[1] = 0;
+ st_insert(malloc_info_file_table, key, (st_data_t)data);
+ }
+ data[0] ++;
+ data[1] += info->size;
+ };
+ if (0 && gen >= 2) { /* verbose output */
+ if (info->file) {
+ fprintf(stderr, "free - size:%"PRIdSIZE", gen:%d, pos: %s:%"PRIdSIZE"\n",
+ info->size, gen, info->file, info->line);
+ }
+ else {
+ fprintf(stderr, "free - size:%"PRIdSIZE", gen:%d\n",
+ info->size, gen);
+ }
+ }
+ }
+#endif
#endif
old_size = objspace_malloc_size(objspace, ptr, old_size);
free(ptr);
+ RB_DEBUG_COUNTER_INC(heap_xfree);
objspace_malloc_increase(objspace, ptr, 0, old_size, MEMOP_TYPE_FREE);
}
@@ -7977,7 +10826,7 @@ ruby_xmalloc0(size_t size)
}
void *
-ruby_xmalloc(size_t size)
+ruby_xmalloc_body(size_t size)
{
if ((ssize_t)size < 0) {
negative_size_allocation_error("too large allocation size");
@@ -7994,7 +10843,7 @@ ruby_malloc_size_overflow(size_t count, size_t elsize)
}
void *
-ruby_xmalloc2(size_t n, size_t size)
+ruby_xmalloc2_body(size_t n, size_t size)
{
return objspace_xmalloc0(&rb_objspace, xmalloc2_size(n, size));
}
@@ -8005,12 +10854,12 @@ objspace_xcalloc(rb_objspace_t *objspace, size_t size)
void *mem;
size = objspace_malloc_prepare(objspace, size);
- TRY_WITH_GC(mem = calloc(1, size));
+ TRY_WITH_GC(size, mem = calloc1(size));
return objspace_malloc_fixup(objspace, mem, size);
}
void *
-ruby_xcalloc(size_t n, size_t size)
+ruby_xcalloc_body(size_t n, size_t size)
{
return objspace_xcalloc(&rb_objspace, xmalloc2_size(n, size));
}
@@ -8029,7 +10878,7 @@ ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size)
}
void *
-ruby_xrealloc(void *ptr, size_t new_size)
+ruby_xrealloc_body(void *ptr, size_t new_size)
{
return ruby_sized_xrealloc(ptr, new_size, 0);
}
@@ -8040,15 +10889,12 @@ ruby_xrealloc(void *ptr, size_t new_size)
void *
ruby_sized_xrealloc2(void *ptr, size_t n, size_t size, size_t old_n)
{
- size_t len = size * n;
- if (n != 0 && size != len / n) {
- rb_raise(rb_eArgError, "realloc: possible integer overflow");
- }
+ size_t len = xmalloc2_size(n, size);
return objspace_xrealloc(&rb_objspace, ptr, len, old_n * size);
}
void *
-ruby_xrealloc2(void *ptr, size_t n, size_t size)
+ruby_xrealloc2_body(void *ptr, size_t n, size_t size)
{
return ruby_sized_xrealloc2(ptr, n, size, 0);
}
@@ -8070,6 +10916,34 @@ ruby_xfree(void *x)
ruby_sized_xfree(x, 0);
}
+void *
+rb_xmalloc_mul_add(size_t x, size_t y, size_t z) /* x * y + z */
+{
+ size_t w = size_mul_add_or_raise(x, y, z, rb_eArgError);
+ return ruby_xmalloc(w);
+}
+
+void *
+rb_xrealloc_mul_add(const void *p, size_t x, size_t y, size_t z) /* x * y + z */
+{
+ size_t w = size_mul_add_or_raise(x, y, z, rb_eArgError);
+ return ruby_xrealloc((void *)p, w);
+}
+
+void *
+rb_xmalloc_mul_add_mul(size_t x, size_t y, size_t z, size_t w) /* x * y + z * w */
+{
+ size_t u = size_mul_add_mul_or_raise(x, y, z, w, rb_eArgError);
+ return ruby_xmalloc(u);
+}
+
+void *
+rb_xcalloc_mul_add_mul(size_t x, size_t y, size_t z, size_t w) /* x * y + z * w */
+{
+ size_t u = size_mul_add_mul_or_raise(x, y, z, w, rb_eArgError);
+ return ruby_xcalloc(u, 1);
+}
+
/* Mimic ruby_xmalloc, but need not rb_objspace.
* should return pointer suitable for ruby_xfree
*/
@@ -8078,13 +10952,25 @@ ruby_mimmalloc(size_t size)
{
void *mem;
#if CALC_EXACT_MALLOC_SIZE
- size += sizeof(size_t);
+ size += sizeof(struct malloc_obj_info);
#endif
mem = malloc(size);
#if CALC_EXACT_MALLOC_SIZE
+ if (!mem) {
+ return NULL;
+ }
+ else
/* set 0 for consistency of allocated_size/allocations */
- ((size_t *)mem)[0] = 0;
- mem = (size_t *)mem + 1;
+ {
+ struct malloc_obj_info *info = mem;
+ info->size = 0;
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ info->gen = 0;
+ info->file = NULL;
+ info->line = 0;
+#endif
+ mem = info + 1;
+ }
#endif
return mem;
}
@@ -8092,24 +10978,28 @@ ruby_mimmalloc(size_t size)
void
ruby_mimfree(void *ptr)
{
- size_t *mem = (size_t *)ptr;
#if CALC_EXACT_MALLOC_SIZE
- mem = mem - 1;
+ struct malloc_obj_info *info = (struct malloc_obj_info *)ptr - 1;
+ ptr = info;
#endif
- free(mem);
+ free(ptr);
}
void *
rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t size, size_t cnt)
{
- NODE *s;
void *ptr;
+ VALUE imemo;
+ rb_imemo_tmpbuf_t *tmpbuf;
- s = rb_node_newnode(NODE_ALLOCA, 0, 0, 0);
+ /* Keep the order; allocate an empty imemo first then xmalloc, to
+ * get rid of potential memory leak */
+ imemo = rb_imemo_tmpbuf_auto_free_maybe_mark_buffer(NULL, 0);
+ *store = imemo;
ptr = ruby_xmalloc0(size);
- s->u1.value = (VALUE)ptr;
- s->u3.cnt = cnt;
- *store = (VALUE)s;
+ tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
+ tmpbuf->ptr = ptr;
+ tmpbuf->cnt = cnt;
return ptr;
}
@@ -8128,10 +11018,10 @@ rb_alloc_tmp_buffer(volatile VALUE *store, long len)
void
rb_free_tmp_buffer(volatile VALUE *store)
{
- VALUE s = ATOMIC_VALUE_EXCHANGE(*store, 0);
+ rb_imemo_tmpbuf_t *s = (rb_imemo_tmpbuf_t*)ATOMIC_VALUE_EXCHANGE(*store, 0);
if (s) {
- void *ptr = ATOMIC_PTR_EXCHANGE(RNODE(s)->u1.node, 0);
- RNODE(s)->u3.cnt = 0;
+ void *ptr = ATOMIC_PTR_EXCHANGE(s->ptr, 0);
+ s->cnt = 0;
ruby_xfree(ptr);
}
}
@@ -8204,13 +11094,22 @@ wmap_mark_map(st_data_t key, st_data_t val, st_data_t arg)
#endif
static void
+wmap_compact(void *ptr)
+{
+ struct weakmap *w = ptr;
+ if (w->wmap2obj) rb_gc_update_tbl_refs(w->wmap2obj);
+ if (w->obj2wmap) rb_gc_update_tbl_refs(w->obj2wmap);
+ w->final = rb_gc_location(w->final);
+}
+
+static void
wmap_mark(void *ptr)
{
struct weakmap *w = ptr;
#if WMAP_DELETE_DEAD_OBJECT_IN_MARK
if (w->obj2wmap) st_foreach(w->obj2wmap, wmap_mark_map, (st_data_t)&rb_objspace);
#endif
- rb_gc_mark(w->final);
+ rb_gc_mark_movable(w->final);
}
static int
@@ -8256,22 +11155,45 @@ static const rb_data_type_t weakmap_type = {
wmap_mark,
wmap_free,
wmap_memsize,
+ wmap_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
+static VALUE wmap_finalize(RB_BLOCK_CALL_FUNC_ARGLIST(objid, self));
+
static VALUE
wmap_allocate(VALUE klass)
{
struct weakmap *w;
VALUE obj = TypedData_Make_Struct(klass, struct weakmap, &weakmap_type, w);
- w->obj2wmap = st_init_numtable();
- w->wmap2obj = st_init_numtable();
- w->final = rb_obj_method(obj, ID2SYM(rb_intern("finalize")));
+ w->obj2wmap = rb_init_identtable();
+ w->wmap2obj = rb_init_identtable();
+ w->final = rb_func_lambda_new(wmap_finalize, obj, 1, 1);
return obj;
}
static int
+wmap_live_p(rb_objspace_t *objspace, VALUE obj)
+{
+ if (SPECIAL_CONST_P(obj)) return TRUE;
+ if (is_pointer_to_heap(objspace, (void *)obj)) {
+ void *poisoned = asan_unpoison_object_temporary(obj);
+
+ enum ruby_value_type t = BUILTIN_TYPE(obj);
+ int ret = (!(t == T_NONE || t >= T_FIXNUM || t == T_ICLASS) &&
+ is_live_object(objspace, obj));
+
+ if (poisoned) {
+ asan_poison_object(obj);
+ }
+
+ return ret;
+ }
+ return TRUE;
+}
+
+static int
wmap_final_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
{
VALUE wmap, *ptr, size, i, j;
@@ -8287,15 +11209,16 @@ wmap_final_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
return ST_DELETE;
}
if (j < i) {
- ptr = ruby_sized_xrealloc2(ptr, j + 1, sizeof(VALUE), i);
+ SIZED_REALLOC_N(ptr, VALUE, j + 1, i);
ptr[0] = j;
*value = (st_data_t)ptr;
}
return ST_CONTINUE;
}
+/* :nodoc: */
static VALUE
-wmap_finalize(VALUE self, VALUE objid)
+wmap_finalize(RB_BLOCK_CALL_FUNC_ARGLIST(objid, self))
{
st_data_t orig, wmap, data;
VALUE obj, *rids, i, size;
@@ -8303,7 +11226,9 @@ wmap_finalize(VALUE self, VALUE objid)
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
/* Get reference from object id. */
- obj = obj_id_to_ref(objid);
+ if ((obj = id2ref_obj_tbl(&rb_objspace, objid)) == Qundef) {
+ rb_bug("wmap_finalize: objid is not found.");
+ }
/* obj is original referenced object and/or weak reference. */
orig = (st_data_t)obj;
@@ -8330,10 +11255,26 @@ struct wmap_iter_arg {
VALUE value;
};
+static VALUE
+wmap_inspect_append(rb_objspace_t *objspace, VALUE str, VALUE obj)
+{
+ if (SPECIAL_CONST_P(obj)) {
+ return rb_str_append(str, rb_inspect(obj));
+ }
+ else if (wmap_live_p(objspace, obj)) {
+ return rb_str_append(str, rb_any_to_s(obj));
+ }
+ else {
+ return rb_str_catf(str, "#<collected:%p>", (void*)obj);
+ }
+}
+
static int
wmap_inspect_i(st_data_t key, st_data_t val, st_data_t arg)
{
- VALUE str = (VALUE)arg;
+ struct wmap_iter_arg *argp = (struct wmap_iter_arg *)arg;
+ rb_objspace_t *objspace = argp->objspace;
+ VALUE str = argp->value;
VALUE k = (VALUE)key, v = (VALUE)val;
if (RSTRING_PTR(str)[0] == '#') {
@@ -8343,13 +11284,9 @@ wmap_inspect_i(st_data_t key, st_data_t val, st_data_t arg)
rb_str_cat2(str, ": ");
RSTRING_PTR(str)[0] = '#';
}
- k = SPECIAL_CONST_P(k) ? rb_inspect(k) : rb_any_to_s(k);
- rb_str_append(str, k);
+ wmap_inspect_append(objspace, str, k);
rb_str_cat2(str, " => ");
- v = SPECIAL_CONST_P(v) ? rb_inspect(v) : rb_any_to_s(v);
- rb_str_append(str, v);
- OBJ_INFECT(str, k);
- OBJ_INFECT(str, v);
+ wmap_inspect_append(objspace, str, v);
return ST_CONTINUE;
}
@@ -8360,11 +11297,14 @@ wmap_inspect(VALUE self)
VALUE str;
VALUE c = rb_class_name(CLASS_OF(self));
struct weakmap *w;
+ struct wmap_iter_arg args;
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
str = rb_sprintf("-<%"PRIsVALUE":%p", c, (void *)self);
if (w->wmap2obj) {
- st_foreach(w->wmap2obj, wmap_inspect_i, str);
+ args.objspace = &rb_objspace;
+ args.value = str;
+ st_foreach(w->wmap2obj, wmap_inspect_i, (st_data_t)&args);
}
RSTRING_PTR(str)[0] = '#';
rb_str_cat2(str, ">");
@@ -8376,7 +11316,7 @@ wmap_each_i(st_data_t key, st_data_t val, st_data_t arg)
{
rb_objspace_t *objspace = (rb_objspace_t *)arg;
VALUE obj = (VALUE)val;
- if (is_id_value(objspace, obj) && is_live_object(objspace, obj)) {
+ if (wmap_live_p(objspace, obj)) {
rb_yield_values(2, (VALUE)key, obj);
}
return ST_CONTINUE;
@@ -8399,7 +11339,7 @@ wmap_each_key_i(st_data_t key, st_data_t val, st_data_t arg)
{
rb_objspace_t *objspace = (rb_objspace_t *)arg;
VALUE obj = (VALUE)val;
- if (is_id_value(objspace, obj) && is_live_object(objspace, obj)) {
+ if (wmap_live_p(objspace, obj)) {
rb_yield((VALUE)key);
}
return ST_CONTINUE;
@@ -8422,7 +11362,7 @@ wmap_each_value_i(st_data_t key, st_data_t val, st_data_t arg)
{
rb_objspace_t *objspace = (rb_objspace_t *)arg;
VALUE obj = (VALUE)val;
- if (is_id_value(objspace, obj) && is_live_object(objspace, obj)) {
+ if (wmap_live_p(objspace, obj)) {
rb_yield(obj);
}
return ST_CONTINUE;
@@ -8447,7 +11387,7 @@ wmap_keys_i(st_data_t key, st_data_t val, st_data_t arg)
rb_objspace_t *objspace = argp->objspace;
VALUE ary = argp->value;
VALUE obj = (VALUE)val;
- if (is_id_value(objspace, obj) && is_live_object(objspace, obj)) {
+ if (wmap_live_p(objspace, obj)) {
rb_ary_push(ary, (VALUE)key);
}
return ST_CONTINUE;
@@ -8474,7 +11414,7 @@ wmap_values_i(st_data_t key, st_data_t val, st_data_t arg)
rb_objspace_t *objspace = argp->objspace;
VALUE ary = argp->value;
VALUE obj = (VALUE)val;
- if (is_id_value(objspace, obj) && is_live_object(objspace, obj)) {
+ if (wmap_live_p(objspace, obj)) {
rb_ary_push(ary, obj);
}
return ST_CONTINUE;
@@ -8501,7 +11441,7 @@ wmap_aset_update(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
if (existing) {
size = (ptr = optr = (VALUE *)*val)[0];
++size;
- ptr = ruby_sized_xrealloc2(ptr, size + 1, sizeof(VALUE), size);
+ SIZED_REALLOC_N(ptr, VALUE, size + 1, size);
}
else {
optr = 0;
@@ -8517,23 +11457,26 @@ wmap_aset_update(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
/* Creates a weak reference from the given key to the given value */
static VALUE
-wmap_aset(VALUE self, VALUE wmap, VALUE orig)
+wmap_aset(VALUE self, VALUE key, VALUE value)
{
struct weakmap *w;
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
- should_be_finalizable(orig);
- should_be_finalizable(wmap);
- define_final0(orig, w->final);
- define_final0(wmap, w->final);
- st_update(w->obj2wmap, (st_data_t)orig, wmap_aset_update, wmap);
- st_insert(w->wmap2obj, (st_data_t)wmap, (st_data_t)orig);
- return nonspecial_obj_id(orig);
+ if (FL_ABLE(value)) {
+ define_final0(value, w->final);
+ }
+ if (FL_ABLE(key)) {
+ define_final0(key, w->final);
+ }
+
+ st_update(w->obj2wmap, (st_data_t)value, wmap_aset_update, key);
+ st_insert(w->wmap2obj, (st_data_t)key, (st_data_t)value);
+ return nonspecial_obj_id(value);
}
/* Retrieves a weakly referenced object with the given key */
static VALUE
-wmap_aref(VALUE self, VALUE wmap)
+wmap_lookup(VALUE self, VALUE key)
{
st_data_t data;
VALUE obj;
@@ -8541,20 +11484,28 @@ wmap_aref(VALUE self, VALUE wmap)
rb_objspace_t *objspace = &rb_objspace;
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
- if (!st_lookup(w->wmap2obj, (st_data_t)wmap, &data)) return Qnil;
+ if (!st_lookup(w->wmap2obj, (st_data_t)key, &data)) return Qundef;
obj = (VALUE)data;
- if (!is_id_value(objspace, obj)) return Qnil;
- if (!is_live_object(objspace, obj)) return Qnil;
+ if (!wmap_live_p(objspace, obj)) return Qundef;
return obj;
}
+/* Retrieves a weakly referenced object with the given key */
+static VALUE
+wmap_aref(VALUE self, VALUE key)
+{
+ VALUE obj = wmap_lookup(self, key);
+ return obj != Qundef ? obj : Qnil;
+}
+
/* Returns +true+ if +key+ is registered */
static VALUE
wmap_has_key(VALUE self, VALUE key)
{
- return NIL_P(wmap_aref(self, key)) ? Qfalse : Qtrue;
+ return wmap_lookup(self, key) == Qundef ? Qfalse : Qtrue;
}
+/* Returns the number of referenced objects */
static VALUE
wmap_size(VALUE self)
{
@@ -8643,12 +11594,12 @@ gc_prof_setup_new_record(rb_objspace_t *objspace, int reason)
if (!objspace->profile.records) {
objspace->profile.size = GC_PROFILE_RECORD_DEFAULT_SIZE;
- objspace->profile.records = malloc(sizeof(gc_profile_record) * objspace->profile.size);
+ objspace->profile.records = malloc(xmalloc2_size(sizeof(gc_profile_record), objspace->profile.size));
}
if (index >= objspace->profile.size) {
void *ptr;
objspace->profile.size += 1000;
- ptr = realloc(objspace->profile.records, sizeof(gc_profile_record) * objspace->profile.size);
+ ptr = realloc(objspace->profile.records, xmalloc2_size(sizeof(gc_profile_record), objspace->profile.size));
if (!ptr) rb_memerror();
objspace->profile.records = ptr;
}
@@ -8818,19 +11769,17 @@ gc_prof_set_heap_info(rb_objspace_t *objspace)
*/
static VALUE
-gc_profile_clear(void)
+gc_profile_clear(VALUE _)
{
rb_objspace_t *objspace = &rb_objspace;
- if (GC_PROFILE_RECORD_DEFAULT_SIZE * 2 < objspace->profile.size) {
- objspace->profile.size = GC_PROFILE_RECORD_DEFAULT_SIZE * 2;
- objspace->profile.records = realloc(objspace->profile.records, sizeof(gc_profile_record) * objspace->profile.size);
- if (!objspace->profile.records) {
- rb_memerror();
- }
- }
- MEMZERO(objspace->profile.records, gc_profile_record, objspace->profile.size);
+ void *p = objspace->profile.records;
+ objspace->profile.records = NULL;
+ objspace->profile.size = 0;
objspace->profile.next_index = 0;
objspace->profile.current_record = 0;
+ if (p) {
+ free(p);
+ }
return Qnil;
}
@@ -8885,7 +11834,7 @@ gc_profile_clear(void)
*/
static VALUE
-gc_profile_record_get(void)
+gc_profile_record_get(VALUE _)
{
VALUE prof;
VALUE gc_profile = rb_ary_new();
@@ -8906,6 +11855,7 @@ gc_profile_record_get(void)
rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_USE_SIZE")), SIZET2NUM(record->heap_use_size));
rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_TOTAL_SIZE")), SIZET2NUM(record->heap_total_size));
rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_TOTAL_OBJECTS")), SIZET2NUM(record->heap_total_objects));
+ rb_hash_aset(prof, ID2SYM(rb_intern("MOVED_OBJECTS")), SIZET2NUM(record->moved_objects));
rb_hash_aset(prof, ID2SYM(rb_intern("GC_IS_MARKED")), Qtrue);
#if GC_PROFILE_MORE_DETAIL
rb_hash_aset(prof, ID2SYM(rb_intern("GC_MARK_TIME")), DBL2NUM(record->gc_mark_time));
@@ -8989,7 +11939,7 @@ gc_profile_dump_on(VALUE out, VALUE (*append)(VALUE, VALUE))
}
#if GC_PROFILE_MORE_DETAIL
- append(out, rb_str_new_cstr("\n\n" \
+ const char *str = "\n\n" \
"More detail.\n" \
"Prepare Time = Previously GC's rest sweep time\n"
"Index Flags Allocate Inc. Allocate Limit"
@@ -9003,7 +11953,8 @@ gc_profile_dump_on(VALUE out, VALUE (*append)(VALUE, VALUE))
#if GC_PROFILE_DETAIL_MEMORY
" MaxRSS(KB) MinorFLT MajorFLT"
#endif
- "\n"));
+ "\n";
+ append(out, rb_str_new_cstr(str));
for (i = 0; i < count; i++) {
record = &objspace->profile.records[i];
@@ -9072,7 +12023,7 @@ gc_profile_dump_on(VALUE out, VALUE (*append)(VALUE, VALUE))
*/
static VALUE
-gc_profile_result(void)
+gc_profile_result(VALUE _)
{
VALUE str = rb_str_buf_new(0);
gc_profile_dump_on(str, rb_str_buf_append);
@@ -9093,12 +12044,7 @@ gc_profile_report(int argc, VALUE *argv, VALUE self)
{
VALUE out;
- if (argc == 0) {
- out = rb_stdout;
- }
- else {
- rb_scan_args(argc, argv, "01", &out);
- }
+ out = (!rb_check_arity(argc, 0, 1) ? rb_stdout : argv[0]);
gc_profile_dump_on(out, rb_io_write);
return Qnil;
@@ -9151,7 +12097,7 @@ gc_profile_enable_get(VALUE self)
*/
static VALUE
-gc_profile_enable(void)
+gc_profile_enable(VALUE _)
{
rb_objspace_t *objspace = &rb_objspace;
objspace->profile.run = TRUE;
@@ -9168,7 +12114,7 @@ gc_profile_enable(void)
*/
static VALUE
-gc_profile_disable(void)
+gc_profile_disable(VALUE _)
{
rb_objspace_t *objspace = &rb_objspace;
@@ -9208,8 +12154,8 @@ type_name(int type, VALUE obj)
TYPE_NAME(T_FIXNUM);
TYPE_NAME(T_UNDEF);
TYPE_NAME(T_IMEMO);
- TYPE_NAME(T_NODE);
TYPE_NAME(T_ICLASS);
+ TYPE_NAME(T_MOVED);
TYPE_NAME(T_ZOMBIE);
case T_DATA:
if (obj && rb_objspace_data_type_name(obj)) {
@@ -9227,8 +12173,8 @@ obj_type_name(VALUE obj)
return type_name(TYPE(obj), obj);
}
-static const char *
-method_type_name(rb_method_type_t type)
+const char *
+rb_method_type_name(rb_method_type_t type)
{
switch (type) {
case VM_METHOD_TYPE_ISEQ: return "iseq";
@@ -9244,7 +12190,7 @@ method_type_name(rb_method_type_t type)
case VM_METHOD_TYPE_UNDEF: return "undef";
case VM_METHOD_TYPE_NOTIMPLEMENTED: return "notimplemented";
}
- rb_bug("method_type_name: unreachable (type: %d)", type);
+ rb_bug("rb_method_type_name: unreachable (type: %d)", type);
}
/* from array.c */
@@ -9258,129 +12204,254 @@ method_type_name(rb_method_type_t type)
static void
rb_raw_iseq_info(char *buff, const int buff_size, const rb_iseq_t *iseq)
{
- if (iseq->body->location.label) {
+ if (buff_size > 0 && iseq->body && iseq->body->location.label && !RB_TYPE_P(iseq->body->location.pathobj, T_MOVED)) {
VALUE path = rb_iseq_path(iseq);
- snprintf(buff, buff_size, "%s %s@%s:%d", buff,
+ VALUE n = iseq->body->location.first_lineno;
+ snprintf(buff, buff_size, " %s@%s:%d",
RSTRING_PTR(iseq->body->location.label),
RSTRING_PTR(path),
- FIX2INT(iseq->body->location.first_lineno));
+ n ? FIX2INT(n) : 0 );
}
}
+bool rb_ractor_p(VALUE rv);
+
+static int
+str_len_no_raise(VALUE str)
+{
+ long len = RSTRING_LEN(str);
+ if (len < 0) return 0;
+ if (len > INT_MAX) return INT_MAX;
+ return (int)len;
+}
+
const char *
rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
{
+ int pos = 0;
+ void *poisoned = asan_poisoned_object_p(obj);
+ asan_unpoison_object(obj, false);
+
+#define BUFF_ARGS buff + pos, buff_size - pos
+#define APPENDF(f) if ((pos += snprintf f) >= buff_size) goto end
if (SPECIAL_CONST_P(obj)) {
- snprintf(buff, buff_size, "%s", obj_type_name(obj));
+ APPENDF((BUFF_ARGS, "%s", obj_type_name(obj)));
+
+ if (FIXNUM_P(obj)) {
+ APPENDF((BUFF_ARGS, " %ld", FIX2LONG(obj)));
+ }
+ else if (SYMBOL_P(obj)) {
+ APPENDF((BUFF_ARGS, " %s", rb_id2name(SYM2ID(obj))));
+ }
}
else {
#define TF(c) ((c) != 0 ? "true" : "false")
#define C(c, s) ((c) != 0 ? (s) : " ")
const int type = BUILTIN_TYPE(obj);
-#if USE_RGENGC
const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
- snprintf(buff, buff_size, "%p [%d%s%s%s%s] %s",
- (void *)obj, age,
- C(RVALUE_UNCOLLECTIBLE_BITMAP(obj), "L"),
- C(RVALUE_MARK_BITMAP(obj), "M"),
- C(RVALUE_MARKING_BITMAP(obj), "R"),
- C(RVALUE_WB_UNPROTECTED_BITMAP(obj), "U"),
- obj_type_name(obj));
-#else
- snprintf(buff, buff_size, "%p [%s] %s",
- (void *)obj,
- C(RVALUE_MARK_BITMAP(obj), "M"),
- obj_type_name(obj));
-#endif
+ if (is_pointer_to_heap(&rb_objspace, (void *)obj)) {
+ APPENDF((BUFF_ARGS, "%p [%d%s%s%s%s%s] %s ",
+ (void *)obj, age,
+ C(RVALUE_UNCOLLECTIBLE_BITMAP(obj), "L"),
+ C(RVALUE_MARK_BITMAP(obj), "M"),
+ C(RVALUE_PIN_BITMAP(obj), "P"),
+ C(RVALUE_MARKING_BITMAP(obj), "R"),
+ C(RVALUE_WB_UNPROTECTED_BITMAP(obj), "U"),
+ obj_type_name(obj)));
+ }
+ else {
+ /* fake */
+ APPENDF((BUFF_ARGS, "%p [%dXXXX] %s",
+ (void *)obj, age,
+ obj_type_name(obj)));
+ }
if (internal_object_p(obj)) {
/* ignore */
}
else if (RBASIC(obj)->klass == 0) {
- snprintf(buff, buff_size, "%s (temporary internal)", buff);
+ APPENDF((BUFF_ARGS, "(temporary internal)"));
}
else {
- VALUE class_path = rb_class_path_cached(RBASIC(obj)->klass);
+ if (RTEST(RBASIC(obj)->klass)) {
+ VALUE class_path = rb_class_path_cached(RBASIC(obj)->klass);
if (!NIL_P(class_path)) {
- snprintf(buff, buff_size, "%s (%s)", buff, RSTRING_PTR(class_path));
+ APPENDF((BUFF_ARGS, "(%s)", RSTRING_PTR(class_path)));
}
+ }
}
#if GC_DEBUG
- snprintf(buff, buff_size, "%s @%s:%d", buff, RANY(obj)->file, RANY(obj)->line);
+ APPENDF((BUFF_ARGS, "@%s:%d", RANY(obj)->file, RANY(obj)->line));
#endif
switch (type) {
case T_NODE:
- snprintf(buff, buff_size, "%s (%s)", buff,
- ruby_node_name(nd_type(obj)));
+ UNEXPECTED_NODE(rb_raw_obj_info);
break;
case T_ARRAY:
- snprintf(buff, buff_size, "%s [%s%s] len: %d", buff,
- C(ARY_EMBED_P(obj), "E"),
- C(ARY_SHARED_P(obj), "S"),
- (int)RARRAY_LEN(obj));
+ if (FL_TEST(obj, ELTS_SHARED)) {
+ APPENDF((BUFF_ARGS, "shared -> %s",
+ rb_obj_info(RARRAY(obj)->as.heap.aux.shared_root)));
+ }
+ else if (FL_TEST(obj, RARRAY_EMBED_FLAG)) {
+ APPENDF((BUFF_ARGS, "[%s%s] len: %ld (embed)",
+ C(ARY_EMBED_P(obj), "E"),
+ C(ARY_SHARED_P(obj), "S"),
+ RARRAY_LEN(obj)));
+ }
+ else {
+ APPENDF((BUFF_ARGS, "[%s%s%s] len: %ld, capa:%ld ptr:%p",
+ C(ARY_EMBED_P(obj), "E"),
+ C(ARY_SHARED_P(obj), "S"),
+ C(RARRAY_TRANSIENT_P(obj), "T"),
+ RARRAY_LEN(obj),
+ ARY_EMBED_P(obj) ? -1L : RARRAY(obj)->as.heap.aux.capa,
+ (void *)RARRAY_CONST_PTR_TRANSIENT(obj)));
+ }
break;
case T_STRING: {
- snprintf(buff, buff_size, "%s %s", buff, RSTRING_PTR(obj));
- break;
- }
- case T_CLASS: {
- VALUE class_path = rb_class_path_cached(obj);
- if (!NIL_P(class_path)) {
- snprintf(buff, buff_size, "%s %s", buff, RSTRING_PTR(class_path));
- }
- break;
+ if (STR_SHARED_P(obj)) APPENDF((BUFF_ARGS, " [shared] "));
+ APPENDF((BUFF_ARGS, "%.*s", str_len_no_raise(obj), RSTRING_PTR(obj)));
+ break;
}
+ case T_SYMBOL: {
+ VALUE fstr = RSYMBOL(obj)->fstr;
+ ID id = RSYMBOL(obj)->id;
+ if (RB_TYPE_P(fstr, T_STRING)) {
+ APPENDF((BUFF_ARGS, ":%s id:%d", RSTRING_PTR(fstr), (unsigned int)id));
+ }
+ else {
+ APPENDF((BUFF_ARGS, "(%p) id:%d", (void *)fstr, (unsigned int)id));
+ }
+ break;
+ }
+ case T_MOVED: {
+ APPENDF((BUFF_ARGS, "-> %p", (void*)rb_gc_location(obj)));
+ break;
+ }
+ case T_HASH: {
+ APPENDF((BUFF_ARGS, "[%c%c] %"PRIdSIZE,
+ RHASH_AR_TABLE_P(obj) ? 'A' : 'S',
+ RHASH_TRANSIENT_P(obj) ? 'T' : ' ',
+ RHASH_SIZE(obj)));
+ break;
+ }
+ case T_CLASS:
+ case T_MODULE:
+ {
+ VALUE class_path = rb_class_path_cached(obj);
+ if (!NIL_P(class_path)) {
+ APPENDF((BUFF_ARGS, "%s", RSTRING_PTR(class_path)));
+ }
+ else {
+ APPENDF((BUFF_ARGS, "(annon)"));
+ }
+ break;
+ }
+ case T_ICLASS:
+ {
+ VALUE class_path = rb_class_path_cached(RBASIC_CLASS(obj));
+ if (!NIL_P(class_path)) {
+ APPENDF((BUFF_ARGS, "src:%s", RSTRING_PTR(class_path)));
+ }
+ break;
+ }
+ case T_OBJECT:
+ {
+ uint32_t len = ROBJECT_NUMIV(obj);
+
+ if (RANY(obj)->as.basic.flags & ROBJECT_EMBED) {
+ APPENDF((BUFF_ARGS, "(embed) len:%d", len));
+ }
+ else {
+ VALUE *ptr = ROBJECT_IVPTR(obj);
+ APPENDF((BUFF_ARGS, "len:%d ptr:%p", len, (void *)ptr));
+ }
+ }
+ break;
case T_DATA: {
- const rb_iseq_t *iseq;
- if (rb_obj_is_proc(obj) && (iseq = vm_proc_iseq(obj)) != NULL) {
- rb_raw_iseq_info(buff, buff_size, iseq);
- }
- else {
- const char * const type_name = rb_objspace_data_type_name(obj);
- if (type_name) {
- snprintf(buff, buff_size, "%s %s", buff, type_name);
- }
- }
- break;
+ const struct rb_block *block;
+ const rb_iseq_t *iseq;
+ if (rb_obj_is_proc(obj) &&
+ (block = vm_proc_block(obj)) != NULL &&
+ (vm_block_type(block) == block_type_iseq) &&
+ (iseq = vm_block_iseq(block)) != NULL) {
+ rb_raw_iseq_info(BUFF_ARGS, iseq);
+ }
+ else if (rb_ractor_p(obj)) {
+ rb_ractor_t *r = (void *)DATA_PTR(obj);
+ if (r) {
+ APPENDF((BUFF_ARGS, "r:%d", r->pub.id));
+ }
+ }
+ else {
+ const char * const type_name = rb_objspace_data_type_name(obj);
+ if (type_name) {
+ APPENDF((BUFF_ARGS, "%s", type_name));
+ }
+ }
+ break;
}
case T_IMEMO: {
- const char *imemo_name;
- switch (imemo_type(obj)) {
-#define IMEMO_NAME(x) case imemo_##x: imemo_name = #x; break;
- IMEMO_NAME(env);
- IMEMO_NAME(cref);
- IMEMO_NAME(svar);
- IMEMO_NAME(throw_data);
- IMEMO_NAME(ifunc);
- IMEMO_NAME(memo);
- IMEMO_NAME(ment);
- IMEMO_NAME(iseq);
-#undef IMEMO_NAME
- }
- snprintf(buff, buff_size, "%s %s", buff, imemo_name);
+ APPENDF((BUFF_ARGS, "<%s> ", rb_imemo_name(imemo_type(obj))));
- switch (imemo_type(obj)) {
- case imemo_ment: {
- const rb_method_entry_t *me = &RANY(obj)->as.imemo.ment;
- snprintf(buff, buff_size, "%s (called_id: %s, type: %s, alias: %d, owner: %s, defined_class: %s)", buff,
+ switch (imemo_type(obj)) {
+ case imemo_ment: {
+ const rb_method_entry_t *me = &RANY(obj)->as.imemo.ment;
+ if (me->def) {
+ APPENDF((BUFF_ARGS, ":%s (%s%s%s%s) type:%s alias:%d owner:%p defined_class:%p",
rb_id2name(me->called_id),
- method_type_name(me->def->type),
- me->def->alias_count,
- obj_info(me->owner),
- obj_info(me->defined_class));
- break;
+ METHOD_ENTRY_VISI(me) == METHOD_VISI_PUBLIC ? "pub" :
+ METHOD_ENTRY_VISI(me) == METHOD_VISI_PRIVATE ? "pri" : "pro",
+ METHOD_ENTRY_COMPLEMENTED(me) ? ",cmp" : "",
+ METHOD_ENTRY_CACHED(me) ? ",cc" : "",
+ METHOD_ENTRY_INVALIDATED(me) ? ",inv" : "",
+ rb_method_type_name(me->def->type),
+ me->def->alias_count,
+ (void *)me->owner, // obj_info(me->owner),
+ (void *)me->defined_class)); //obj_info(me->defined_class)));
+
+ if (me->def->type == VM_METHOD_TYPE_ISEQ) {
+ // APPENDF((BUFF_ARGS, " (iseq:%p)", (void *)me->def->body.iseq.iseqptr));
+ APPENDF((BUFF_ARGS, " (iseq:%s)", obj_info((VALUE)me->def->body.iseq.iseqptr)));
+ }
}
- case imemo_iseq: {
- const rb_iseq_t *iseq = (const rb_iseq_t *)obj;
- rb_raw_iseq_info(buff, buff_size, iseq);
- break;
+ else {
+ APPENDF((BUFF_ARGS, "%s", rb_id2name(me->called_id)));
}
- default:
- break;
+ break;
+ }
+ case imemo_iseq: {
+ const rb_iseq_t *iseq = (const rb_iseq_t *)obj;
+ rb_raw_iseq_info(BUFF_ARGS, iseq);
+ break;
}
+ case imemo_callinfo:
+ {
+ const struct rb_callinfo *ci = (const struct rb_callinfo *)obj;
+ APPENDF((BUFF_ARGS, "(mid:%s, flag:%x argc:%d, kwarg:%s)",
+ rb_id2name(vm_ci_mid(ci)),
+ vm_ci_flag(ci),
+ vm_ci_argc(ci),
+ vm_ci_kwarg(ci) ? "available" : "NULL"));
+ break;
+ }
+ case imemo_callcache:
+ {
+ const struct rb_callcache *cc = (const struct rb_callcache *)obj;
+ VALUE class_path = cc->klass ? rb_class_path_cached(cc->klass) : Qnil;
+
+ APPENDF((BUFF_ARGS, "(klass:%s, cme:%s (%p) call:%p",
+ NIL_P(class_path) ? "??" : RSTRING_PTR(class_path),
+ vm_cc_cme(cc) ? rb_id2name(vm_cc_cme(cc)->called_id) : "<NULL>",
+ (void *)vm_cc_cme(cc), (void *)vm_cc_call(cc)));
+ break;
+ }
+ default:
+ break;
+ }
}
default:
break;
@@ -9388,7 +12459,14 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
#undef TF
#undef C
}
+ end:
+ if (poisoned) {
+ asan_poison_object(obj);
+ }
+
return buff;
+#undef APPENDF
+#undef BUFF_ARGS
}
#if RGENGC_OBJ_INFO
@@ -9417,15 +12495,10 @@ obj_info(VALUE obj)
}
#endif
-const char *
+MJIT_FUNC_EXPORTED const char *
rb_obj_info(VALUE obj)
{
- if (!rb_special_const_p(obj)) {
- return obj_info(obj);
- }
- else {
- return obj_type_name(obj);
- }
+ return obj_info(obj);
}
void
@@ -9435,6 +12508,13 @@ rb_obj_info_dump(VALUE obj)
fprintf(stderr, "rb_obj_info_dump: %s\n", rb_raw_obj_info(buff, 0x100, obj));
}
+MJIT_FUNC_EXPORTED void
+rb_obj_info_dump_loc(VALUE obj, const char *file, int line, const char *func)
+{
+ char buff[0x100];
+ fprintf(stderr, "<OBJ_INFO:%s@%s:%d> %s\n", func, file, line, rb_raw_obj_info(buff, 0x100, obj));
+}
+
#if GC_DEBUG
void
@@ -9444,6 +12524,12 @@ rb_gcdebug_print_obj_condition(VALUE obj)
fprintf(stderr, "created at: %s:%d\n", RANY(obj)->file, RANY(obj)->line);
+ if (BUILTIN_TYPE(obj) == T_MOVED) {
+ fprintf(stderr, "moved?: true\n");
+ }
+ else {
+ fprintf(stderr, "moved?: false\n");
+ }
if (is_pointer_to_heap(objspace, (void *)obj)) {
fprintf(stderr, "pointer to heap?: true\n");
}
@@ -9453,12 +12539,11 @@ rb_gcdebug_print_obj_condition(VALUE obj)
}
fprintf(stderr, "marked? : %s\n", MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj) ? "true" : "false");
-#if USE_RGENGC
+ fprintf(stderr, "pinned? : %s\n", MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj) ? "true" : "false");
fprintf(stderr, "age? : %d\n", RVALUE_AGE(obj));
fprintf(stderr, "old? : %s\n", RVALUE_OLD_P(obj) ? "true" : "false");
fprintf(stderr, "WB-protected?: %s\n", RVALUE_WB_UNPROTECTED(obj) ? "false" : "true");
fprintf(stderr, "remembered? : %s\n", RVALUE_REMEMBERED(obj) ? "true" : "false");
-#endif
if (is_lazy_sweeping(heap_eden)) {
fprintf(stderr, "lazy sweeping?: true\n");
@@ -9470,7 +12555,7 @@ rb_gcdebug_print_obj_condition(VALUE obj)
}
static VALUE
-gcdebug_sentinel(VALUE obj, VALUE name)
+gcdebug_sentinel(RB_BLOCK_CALL_FUNC_ARGLIST(obj, name))
{
fprintf(stderr, "WARNING: object %s(%p) is inadvertently collected\n", (char *)name, (void *)obj);
return Qnil;
@@ -9485,6 +12570,13 @@ rb_gcdebug_sentinel(VALUE obj, const char *name)
#endif /* GC_DEBUG */
#if GC_DEBUG_STRESS_TO_CLASS
+/*
+ * call-seq:
+ * GC.add_stress_to_class(class[, ...])
+ *
+ * Raises NoMemoryError when allocating an instance of the given classes.
+ *
+ */
static VALUE
rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self)
{
@@ -9497,6 +12589,14 @@ rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self)
return self;
}
+/*
+ * call-seq:
+ * GC.remove_stress_to_class(class[, ...])
+ *
+ * No longer raises NoMemoryError when allocating an instance of the
+ * given classes.
+ *
+ */
static VALUE
rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
{
@@ -9524,9 +12624,9 @@ rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
*
* ObjectSpace also provides support for object finalizers, procs that will be
* called when a specific object is about to be destroyed by garbage
- * collection.
- *
- * require 'objspace'
+ * collection. See the documentation for
+ * <code>ObjectSpace.define_finalizer</code> for important information on
+ * how to use this method correctly.
*
* a = "A"
* b = "B"
@@ -9534,6 +12634,9 @@ rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
* ObjectSpace.define_finalizer(a, proc {|id| puts "Finalizer one on #{id}" })
* ObjectSpace.define_finalizer(b, proc {|id| puts "Finalizer two on #{id}" })
*
+ * a = nil
+ * b = nil
+ *
* _produces:_
*
* Finalizer two on 537763470
@@ -9568,16 +12671,7 @@ rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
* See also GC.count, GC.malloc_allocated_size and GC.malloc_allocations
*/
-/*
- * The GC module provides an interface to Ruby's mark and
- * sweep garbage collection mechanism.
- *
- * Some of the underlying methods are also available via the ObjectSpace
- * module.
- *
- * You may obtain information about the operation of the GC through
- * GC::Profiler.
- */
+#include "gc.rbinc"
void
Init_GC(void)
@@ -9588,22 +12682,16 @@ Init_GC(void)
VALUE gc_constants;
rb_mGC = rb_define_module("GC");
- rb_define_singleton_method(rb_mGC, "start", gc_start_internal, -1);
- rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0);
- rb_define_singleton_method(rb_mGC, "disable", rb_gc_disable, 0);
- rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0);
- rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set_m, 1);
- rb_define_singleton_method(rb_mGC, "count", gc_count, 0);
- rb_define_singleton_method(rb_mGC, "stat", gc_stat, -1);
- rb_define_singleton_method(rb_mGC, "latest_gc_info", gc_latest_gc_info, -1);
- rb_define_method(rb_mGC, "garbage_collect", gc_start_internal, -1);
gc_constants = rb_hash_new();
+ rb_hash_aset(gc_constants, ID2SYM(rb_intern("DEBUG")), GC_DEBUG ? Qtrue : Qfalse);
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVALUE_SIZE")), SIZET2NUM(sizeof(RVALUE)));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("HEAP_PAGE_OBJ_LIMIT")), SIZET2NUM(HEAP_PAGE_OBJ_LIMIT));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("HEAP_PAGE_BITMAP_SIZE")), SIZET2NUM(HEAP_PAGE_BITMAP_SIZE));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("HEAP_PAGE_BITMAP_PLANES")), SIZET2NUM(HEAP_PAGE_BITMAP_PLANES));
+ rb_hash_aset(gc_constants, ID2SYM(rb_intern("HEAP_PAGE_SIZE")), SIZET2NUM(HEAP_PAGE_SIZE));
OBJ_FREEZE(gc_constants);
+ /* internal constants */
rb_define_const(rb_mGC, "INTERNAL_CONSTANTS", gc_constants);
rb_mProfiler = rb_define_module_under(rb_mGC, "Profiler");
@@ -9617,13 +12705,13 @@ Init_GC(void)
rb_define_singleton_method(rb_mProfiler, "total_time", gc_profile_total_time, 0);
rb_mObjSpace = rb_define_module("ObjectSpace");
+
rb_define_module_function(rb_mObjSpace, "each_object", os_each_obj, -1);
- rb_define_module_function(rb_mObjSpace, "garbage_collect", gc_start_internal, -1);
rb_define_module_function(rb_mObjSpace, "define_finalizer", define_final, -1);
rb_define_module_function(rb_mObjSpace, "undefine_finalizer", undefine_final, 1);
- rb_define_module_function(rb_mObjSpace, "_id2ref", id2ref, 1);
+ rb_define_module_function(rb_mObjSpace, "_id2ref", os_id2ref, 1);
rb_vm_register_special_exception(ruby_error_nomemory, rb_eNoMemError, "failed to allocate memory");
@@ -9649,12 +12737,12 @@ Init_GC(void)
rb_define_method(rb_cWeakMap, "values", wmap_values, 0);
rb_define_method(rb_cWeakMap, "size", wmap_size, 0);
rb_define_method(rb_cWeakMap, "length", wmap_size, 0);
- rb_define_private_method(rb_cWeakMap, "finalize", wmap_finalize, 1);
rb_include_module(rb_cWeakMap, rb_mEnumerable);
}
/* internal methods */
- rb_define_singleton_method(rb_mGC, "verify_internal_consistency", gc_verify_internal_consistency, 0);
+ rb_define_singleton_method(rb_mGC, "verify_internal_consistency", gc_verify_internal_consistency_m, 0);
+ rb_define_singleton_method(rb_mGC, "verify_transient_heap_internal_consistency", gc_verify_transient_heap_internal_consistency, 0);
#if MALLOC_ALLOCATED_SIZE
rb_define_singleton_method(rb_mGC, "malloc_allocated_size", gc_malloc_allocated_size, 0);
rb_define_singleton_method(rb_mGC, "malloc_allocations", gc_malloc_allocations, 0);
@@ -9665,9 +12753,9 @@ Init_GC(void)
rb_define_singleton_method(rb_mGC, "remove_stress_to_class", rb_gcdebug_remove_stress_to_class, -1);
#endif
- /* ::GC::OPTS, which shows GC build options */
{
VALUE opts;
+ /* GC build options */
rb_define_const(rb_mGC, "OPTS", opts = rb_ary_new());
#define OPT(o) if (o) rb_ary_push(opts, rb_fstring_lit(#o))
OPT(GC_DEBUG);
@@ -9686,3 +12774,69 @@ Init_GC(void)
OBJ_FREEZE(opts);
}
}
+
+#ifdef ruby_xmalloc
+#undef ruby_xmalloc
+#endif
+#ifdef ruby_xmalloc2
+#undef ruby_xmalloc2
+#endif
+#ifdef ruby_xcalloc
+#undef ruby_xcalloc
+#endif
+#ifdef ruby_xrealloc
+#undef ruby_xrealloc
+#endif
+#ifdef ruby_xrealloc2
+#undef ruby_xrealloc2
+#endif
+
+void *
+ruby_xmalloc(size_t size)
+{
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ ruby_malloc_info_file = __FILE__;
+ ruby_malloc_info_line = __LINE__;
+#endif
+ return ruby_xmalloc_body(size);
+}
+
+void *
+ruby_xmalloc2(size_t n, size_t size)
+{
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ ruby_malloc_info_file = __FILE__;
+ ruby_malloc_info_line = __LINE__;
+#endif
+ return ruby_xmalloc2_body(n, size);
+}
+
+void *
+ruby_xcalloc(size_t n, size_t size)
+{
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ ruby_malloc_info_file = __FILE__;
+ ruby_malloc_info_line = __LINE__;
+#endif
+ return ruby_xcalloc_body(n, size);
+}
+
+void *
+ruby_xrealloc(void *ptr, size_t new_size)
+{
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ ruby_malloc_info_file = __FILE__;
+ ruby_malloc_info_line = __LINE__;
+#endif
+ return ruby_xrealloc_body(ptr, new_size);
+}
+
+void *
+ruby_xrealloc2(void *ptr, size_t n, size_t new_size)
+{
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS
+ ruby_malloc_info_file = __FILE__;
+ ruby_malloc_info_line = __LINE__;
+#endif
+ return ruby_xrealloc2_body(ptr, n, new_size);
+}
diff --git a/gc.h b/gc.h
index f5e3731d24..5d113cafce 100644
--- a/gc.h
+++ b/gc.h
@@ -1,17 +1,28 @@
-
#ifndef RUBY_GC_H
#define RUBY_GC_H 1
+#include "ruby/ruby.h"
-#if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__) && !defined(__native_client__)
+#if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__)
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
-#elif defined(__i386) && defined(__GNUC__) && !defined(__native_client__)
+#elif defined(__i386) && defined(__GNUC__)
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p)))
+#elif defined(__powerpc64__) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr\t%0, %%r1" : "=r" (*(p)))
+#elif defined(__aarch64__) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mov\t%0, sp" : "=r" (*(p)))
#else
NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
#define SET_MACHINE_STACK_END(p) rb_gc_set_stack_end(p)
#define USE_CONSERVATIVE_STACK_END
#endif
+#define RB_GC_SAVE_MACHINE_CONTEXT(th) \
+ do { \
+ FLUSH_REGISTER_WINDOWS; \
+ setjmp((th)->ec->machine.regs); \
+ SET_MACHINE_STACK_END(&(th)->ec->machine.stack_end); \
+ } while (0)
+
/* for GC debug */
#ifndef RUBY_MARK_FREE_DEBUG
@@ -57,6 +68,10 @@ rb_gc_debug_body(const char *mode, const char *msg, int st, void *ptr)
#define RUBY_GC_INFO if(0)printf
#endif
+#define RUBY_MARK_MOVABLE_UNLESS_NULL(ptr) do { \
+ VALUE markobj = (ptr); \
+ if (RTEST(markobj)) {rb_gc_mark_movable(markobj);} \
+} while (0)
#define RUBY_MARK_UNLESS_NULL(ptr) do { \
VALUE markobj = (ptr); \
if (RTEST(markobj)) {rb_gc_mark(markobj);} \
@@ -77,6 +92,14 @@ int ruby_get_stack_grow_direction(volatile VALUE *addr);
# define STACK_UPPER(x, a, b) (stack_growup_p(x) ? (a) : (b))
#endif
+/*
+ STACK_GROW_DIR_DETECTION is used with STACK_DIR_UPPER.
+
+ On most normal systems, stacks grow from high address to lower address. In
+ this case, STACK_DIR_UPPER(a, b) will return (b), but on exotic systems where
+ the stack grows UP (from low address to high address), it will return (a).
+*/
+
#if STACK_GROW_DIRECTION
#define STACK_GROW_DIR_DETECTION
#define STACK_DIR_UPPER(a,b) STACK_UPPER(0, (a), (b))
@@ -88,10 +111,10 @@ int ruby_get_stack_grow_direction(volatile VALUE *addr);
const char *rb_obj_info(VALUE obj);
const char *rb_raw_obj_info(char *buff, const int buff_size, VALUE obj);
-void rb_obj_info_dump(VALUE obj);
+
+VALUE rb_gc_disable_no_rest(void);
struct rb_thread_struct;
-int rb_threadptr_during_gc(struct rb_thread_struct *th);
RUBY_SYMBOL_EXPORT_BEGIN
diff --git a/gc.rb b/gc.rb
new file mode 100644
index 0000000000..8a00b406ce
--- /dev/null
+++ b/gc.rb
@@ -0,0 +1,241 @@
+# for gc.c
+
+# The GC module provides an interface to Ruby's mark and
+# sweep garbage collection mechanism.
+#
+# Some of the underlying methods are also available via the ObjectSpace
+# module.
+#
+# You may obtain information about the operation of the GC through
+# GC::Profiler.
+module GC
+
+ # call-seq:
+ # GC.start -> nil
+ # ObjectSpace.garbage_collect -> nil
+ # include GC; garbage_collect -> nil
+ # GC.start(full_mark: true, immediate_sweep: true) -> nil
+ # ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true) -> nil
+ # include GC; garbage_collect(full_mark: true, immediate_sweep: true) -> nil
+ #
+ # Initiates garbage collection, even if manually disabled.
+ #
+ # This method is defined with keyword arguments that default to true:
+ #
+ # def GC.start(full_mark: true, immediate_sweep: true); end
+ #
+ # Use full_mark: false to perform a minor GC.
+ # Use immediate_sweep: false to defer sweeping (use lazy sweep).
+ #
+ # Note: These keyword arguments are implementation and version dependent. They
+ # are not guaranteed to be future-compatible, and may be ignored if the
+ # underlying implementation does not support them.
+ def self.start full_mark: true, immediate_mark: true, immediate_sweep: true
+ Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
+ end
+
+ def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
+ Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
+ end
+
+ # call-seq:
+ # GC.auto_compact -> true or false
+ #
+ # Returns whether or not automatic compaction has been enabled.
+ #
+ def self.auto_compact
+ Primitive.gc_get_auto_compact
+ end
+
+ # call-seq:
+ # GC.auto_compact = flag
+ #
+ # Updates automatic compaction mode.
+ #
+ # When enabled, the compactor will execute on every major collection.
+ #
+ # Enabling compaction will degrade performance on major collections.
+ def self.auto_compact=(flag)
+ Primitive.gc_set_auto_compact(flag)
+ end
+
+ # call-seq:
+ # GC.enable -> true or false
+ #
+ # Enables garbage collection, returning +true+ if garbage
+ # collection was previously disabled.
+ #
+ # GC.disable #=> false
+ # GC.enable #=> true
+ # GC.enable #=> false
+ #
+ def self.enable
+ Primitive.gc_enable
+ end
+
+ # call-seq:
+ # GC.disable -> true or false
+ #
+ # Disables garbage collection, returning +true+ if garbage
+ # collection was already disabled.
+ #
+ # GC.disable #=> false
+ # GC.disable #=> true
+ def self.disable
+ Primitive.gc_disable
+ end
+
+ # call-seq:
+ # GC.stress -> integer, true or false
+ #
+ # Returns current status of GC stress mode.
+ def self.stress
+ Primitive.gc_stress_get
+ end
+
+ # call-seq:
+ # GC.stress = flag -> flag
+ #
+ # Updates the GC stress mode.
+ #
+ # When stress mode is enabled, the GC is invoked at every GC opportunity:
+ # all memory and object allocations.
+ #
+ # Enabling stress mode will degrade performance, it is only for debugging.
+ #
+ # flag can be true, false, or an integer bit-ORed following flags.
+ # 0x01:: no major GC
+ # 0x02:: no immediate sweep
+ # 0x04:: full mark after malloc/calloc/realloc
+ def self.stress=(flag)
+ Primitive.gc_stress_set_m flag
+ end
+
+ # call-seq:
+ # GC.count -> Integer
+ #
+ # The number of times GC occurred.
+ #
+ # It returns the number of times GC occurred since the process started.
+ def self.count
+ Primitive.gc_count
+ end
+
+ # call-seq:
+ # GC.stat -> Hash
+ # GC.stat(hash) -> hash
+ # GC.stat(:key) -> Numeric
+ #
+ # Returns a Hash containing information about the GC.
+ #
+ # The hash includes information about internal statistics about GC such as:
+ #
+ # {
+ # :count=>0,
+ # :heap_allocated_pages=>24,
+ # :heap_sorted_length=>24,
+ # :heap_allocatable_pages=>0,
+ # :heap_available_slots=>9783,
+ # :heap_live_slots=>7713,
+ # :heap_free_slots=>2070,
+ # :heap_final_slots=>0,
+ # :heap_marked_slots=>0,
+ # :heap_eden_pages=>24,
+ # :heap_tomb_pages=>0,
+ # :total_allocated_pages=>24,
+ # :total_freed_pages=>0,
+ # :total_allocated_objects=>7796,
+ # :total_freed_objects=>83,
+ # :malloc_increase_bytes=>2389312,
+ # :malloc_increase_bytes_limit=>16777216,
+ # :minor_gc_count=>0,
+ # :major_gc_count=>0,
+ # :remembered_wb_unprotected_objects=>0,
+ # :remembered_wb_unprotected_objects_limit=>0,
+ # :old_objects=>0,
+ # :old_objects_limit=>0,
+ # :oldmalloc_increase_bytes=>2389760,
+ # :oldmalloc_increase_bytes_limit=>16777216
+ # }
+ #
+ # The contents of the hash are implementation specific and may be changed in
+ # the future.
+ #
+ # If the optional argument, hash, is given,
+ # it is overwritten and returned.
+ # This is intended to avoid probe effect.
+ #
+ # This method is only expected to work on C Ruby.
+ def self.stat hash_or_key = nil
+ Primitive.gc_stat hash_or_key
+ end
+
+ # call-seq:
+ # GC.latest_gc_info -> {:gc_by=>:newobj}
+ # GC.latest_gc_info(hash) -> hash
+ # GC.latest_gc_info(:major_by) -> :malloc
+ #
+ # Returns information about the most recent garbage collection.
+ #
+ # If the optional argument, hash, is given,
+ # it is overwritten and returned.
+ # This is intended to avoid probe effect.
+ def self.latest_gc_info hash_or_key = nil
+ Primitive.gc_latest_gc_info hash_or_key
+ end
+
+ # call-seq:
+ # GC.latest_compact_info -> {:considered=>{:T_CLASS=>11}, :moved=>{:T_CLASS=>11}}
+ #
+ # Returns information about object moved in the most recent GC compaction.
+ #
+ # The returned hash has two keys :considered and :moved. The hash for
+ # :considered lists the number of objects that were considered for movement
+ # by the compactor, and the :moved hash lists the number of objects that
+ # were actually moved. Some objects can't be moved (maybe they were pinned)
+ # so these numbers can be used to calculate compaction efficiency.
+ def self.latest_compact_info
+ Primitive.gc_compact_stats
+ end
+
+ # call-seq:
+ # GC.compact
+ #
+ # This function compacts objects together in Ruby's heap. It eliminates
+ # unused space (or fragmentation) in the heap by moving objects in to that
+ # unused space. This function returns a hash which contains statistics about
+ # which objects were moved. See `GC.latest_gc_info` for details about
+ # compaction statistics.
+ #
+ # This method is implementation specific and not expected to be implemented
+ # in any implementation besides MRI.
+ def self.compact
+ Primitive.gc_compact
+ end
+
+ # call-seq:
+ # GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
+ #
+ # Verify compaction reference consistency.
+ #
+ # This method is implementation specific. During compaction, objects that
+ # were moved are replaced with T_MOVED objects. No object should have a
+ # reference to a T_MOVED object after compaction.
+ #
+ # This function doubles the heap to ensure room to move all objects,
+ # compacts the heap to make sure everything moves, updates all references,
+ # then performs a full GC. If any object contains a reference to a T_MOVED
+ # object, that object should be pushed on the mark stack, and will
+ # make a SEGV.
+ def self.verify_compaction_references(toward: nil, double_heap: false)
+ Primitive.gc_verify_compaction_references(double_heap, toward == :empty)
+ end
+end
+
+module ObjectSpace
+ def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
+ Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
+ end
+
+ module_function :garbage_collect
+end
diff --git a/gem_prelude.rb b/gem_prelude.rb
index be9c41933c..c4debb6509 100644
--- a/gem_prelude.rb
+++ b/gem_prelude.rb
@@ -1,8 +1,11 @@
-if defined?(Gem)
- require 'rubygems.rb'
- begin
- gem 'did_you_mean'
- require 'did_you_mean'
- rescue Gem::LoadError, LoadError
- end if defined?(DidYouMean)
-end
+begin
+ require 'rubygems'
+rescue LoadError
+ warn "`RubyGems' were not loaded."
+end if defined?(Gem)
+
+begin
+ require 'did_you_mean'
+rescue LoadError
+ warn "`did_you_mean' was not loaded."
+end if defined?(DidYouMean)
diff --git a/gems/bundled_gems b/gems/bundled_gems
index 1c7d4977ef..445d876df8 100644
--- a/gems/bundled_gems
+++ b/gems/bundled_gems
@@ -1,7 +1,9 @@
-did_you_mean 1.1.2
-minitest 5.10.3
-net-telnet 0.1.1
-power_assert 1.1.0
-rake 12.1.0
-test-unit 3.2.5
-xmlrpc 0.3.0
+# gem-name version-to-bundle repository-url [optional-commit-hash-to-test-or-defaults-to-v-version]
+minitest 5.14.2 https://github.com/seattlerb/minitest
+power_assert 1.2.1 https://github.com/ruby/power_assert
+rake 13.0.3 https://github.com/ruby/rake
+test-unit 3.3.7 https://github.com/test-unit/test-unit 3.3.7
+rexml 3.2.5 https://github.com/ruby/rexml
+rss 0.2.9 https://github.com/ruby/rss 0.2.9
+typeprof 0.15.2 https://github.com/ruby/typeprof
+rbs 1.4.0 https://github.com/ruby/rbs
diff --git a/golf_prelude.rb b/golf_prelude.rb
index e45f4cafd9..a13d3f71bc 100644
--- a/golf_prelude.rb
+++ b/golf_prelude.rb
@@ -1,6 +1,7 @@
class Object
@@golf_hash = {}
+ verbose, $VERBOSE = $VERBOSE, nil
def method_missing m, *a, &b
t = @@golf_hash[ [m, self.class] ] ||= matching_methods(m)[0]
if t && b
@@ -12,6 +13,7 @@ class Object
t ? __send__(t, *a, &b) : super
end
end
+ $VERBOSE = verbose
def matching_methods(s = '', m = callable_methods)
r = /^#{s.to_s.gsub(/./){"(.*?)" + Regexp.escape($&)}}/
@@ -50,6 +52,11 @@ class Object
puts "#{a}ello, #{b}orld#{c}"
end
+ def f(m = 100)
+ 1.upto(m){|n|puts'FizzBuzz
+'[i=n**4%-15,i+13]||n}
+ end
+
alias say puts
def do_while
diff --git a/goruby.c b/goruby.c
index ddb62562d4..e4119c56f7 100644
--- a/goruby.c
+++ b/goruby.c
@@ -49,10 +49,8 @@ goruby_options(int argc, char **argv)
close(infd);
return ret;
}
- else {
- no_irb:
- return ruby_options(argc, argv);
- }
+ no_irb:
+ return ruby_options(argc, argv);
}
int
diff --git a/hash.c b/hash.c
index 878e215dc5..17d4186acf 100644
--- a/hash.c
+++ b/hash.c
@@ -11,14 +11,9 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/st.h"
-#include "ruby/util.h"
+#include "ruby/internal/config.h"
+
#include <errno.h>
-#include "probes.h"
-#include "id.h"
-#include "symbol.h"
-#include "gc.h"
#ifdef __APPLE__
# ifdef HAVE_CRT_EXTERNS_H
@@ -28,13 +23,42 @@
# endif
#endif
+#include "debug_counter.h"
+#include "id.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/bignum.h"
+#include "internal/class.h"
+#include "internal/cont.h"
+#include "internal/error.h"
+#include "internal/hash.h"
+#include "internal/object.h"
+#include "internal/proc.h"
+#include "internal/symbol.h"
+#include "internal/time.h"
+#include "internal/vm.h"
+#include "probes.h"
+#include "ruby/st.h"
+#include "ruby/util.h"
+#include "ruby_assert.h"
+#include "symbol.h"
+#include "transient_heap.h"
+
+#ifndef HASH_DEBUG
+#define HASH_DEBUG 0
+#endif
+
+#if HASH_DEBUG
+#include "gc.h"
+#endif
+
#define HAS_EXTRA_STATES(hash, klass) ( \
((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \
- FL_TEST((hash), FL_EXIVAR|FL_TAINT|HASH_PROC_DEFAULT) || \
+ FL_TEST((hash), FL_EXIVAR|RHASH_PROC_DEFAULT) || \
!NIL_P(RHASH_IFNONE(hash)))
#define SET_DEFAULT(hash, ifnone) ( \
- FL_UNSET_RAW(hash, HASH_PROC_DEFAULT), \
+ FL_UNSET_RAW(hash, RHASH_PROC_DEFAULT), \
RHASH_SET_IFNONE(hash, ifnone))
#define SET_PROC_DEFAULT(hash, proc) set_proc_default(hash, proc)
@@ -44,9 +68,9 @@
static inline void
copy_default(struct RHash *hash, const struct RHash *hash2)
{
- hash->basic.flags &= ~HASH_PROC_DEFAULT;
- hash->basic.flags |= hash2->basic.flags & HASH_PROC_DEFAULT;
- RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
+ hash->basic.flags &= ~RHASH_PROC_DEFAULT;
+ hash->basic.flags |= hash2->basic.flags & RHASH_PROC_DEFAULT;
+ RHASH_SET_IFNONE(hash, RHASH_IFNONE((VALUE)hash2));
}
static VALUE
@@ -82,7 +106,8 @@ rb_hash_freeze(VALUE hash)
VALUE rb_cHash;
static VALUE envtbl;
-static ID id_hash, id_yield, id_default, id_flatten_bang;
+static ID id_hash, id_default, id_flatten_bang;
+static ID id_hash_iter_lev;
VALUE
rb_hash_set_ifnone(VALUE hash, VALUE ifnone)
@@ -95,9 +120,6 @@ static int
rb_any_cmp(VALUE a, VALUE b)
{
if (a == b) return 0;
- if (FIXNUM_P(a) && FIXNUM_P(b)) {
- return a != b;
- }
if (RB_TYPE_P(a, T_STRING) && RBASIC(a)->klass == rb_cString &&
RB_TYPE_P(b, T_STRING) && RBASIC(b)->klass == rb_cString) {
return rb_str_hash_cmp(a, b);
@@ -120,7 +142,11 @@ hash_recursive(VALUE obj, VALUE arg, int recurse)
VALUE
rb_hash(VALUE obj)
{
- VALUE hval = rb_exec_recursive_outer(hash_recursive, obj, 0);
+ VALUE hval = rb_check_funcall_basic_kw(obj, id_hash, rb_mKernel, 0, 0, 0);
+
+ if (hval == Qundef) {
+ hval = rb_exec_recursive_outer(hash_recursive, obj, 0);
+ }
while (!FIXNUM_P(hval)) {
if (RB_TYPE_P(hval, T_BIGNUM)) {
@@ -128,17 +154,27 @@ rb_hash(VALUE obj)
unsigned long ul;
sign = rb_integer_pack(hval, &ul, 1, sizeof(ul), 0,
INTEGER_PACK_NATIVE_BYTE_ORDER);
- ul &= (1UL << (sizeof(long)*CHAR_BIT-1)) - 1;
- if (sign < 0)
- return LONG2FIX(-(long)ul);
- return LONG2FIX((long)ul);
+ if (sign < 0) {
+ hval = LONG2FIX(ul | FIXNUM_MIN);
+ }
+ else {
+ hval = LONG2FIX(ul & FIXNUM_MAX);
+ }
}
hval = rb_to_int(hval);
}
return hval;
}
-long rb_objid_hash(st_index_t index);
+static long rb_objid_hash(st_index_t index);
+
+static st_index_t
+dbl_to_index(double d)
+{
+ union {double d; st_index_t i;} u;
+ u.d = d;
+ return u.i;
+}
long
rb_dbl_long_hash(double d)
@@ -148,12 +184,7 @@ rb_dbl_long_hash(double d)
#if SIZEOF_INT == SIZEOF_VOIDP
return rb_memhash(&d, sizeof(d));
#else
- {
- union {double d; uint64_t i;} u;
-
- u.d = d;
- return rb_objid_hash(rb_hash_start(u.i));
- }
+ return rb_objid_hash(dbl_to_index(d));
#endif
}
@@ -163,38 +194,40 @@ any_hash(VALUE a, st_index_t (*other_func)(VALUE))
VALUE hval;
st_index_t hnum;
- if (SPECIAL_CONST_P(a)) {
+ switch (TYPE(a)) {
+ case T_SYMBOL:
if (STATIC_SYM_P(a)) {
- hnum = a >> (RUBY_SPECIAL_SHIFT + ID_SCOPE_SHIFT);
- hnum = rb_hash_start(hnum);
- goto out;
- }
- else if (FLONUM_P(a)) {
- /* prevent pathological behavior: [Bug #10761] */
- goto flt;
- }
+ hnum = a >> (RUBY_SPECIAL_SHIFT + ID_SCOPE_SHIFT);
+ hnum = rb_hash_start(hnum);
+ }
+ else {
+ hnum = RSYMBOL(a)->hashval;
+ }
+ break;
+ case T_FIXNUM:
+ case T_TRUE:
+ case T_FALSE:
+ case T_NIL:
hnum = rb_objid_hash((st_index_t)a);
- }
- else if (BUILTIN_TYPE(a) == T_STRING) {
+ break;
+ case T_STRING:
hnum = rb_str_hash(a);
- }
- else if (BUILTIN_TYPE(a) == T_SYMBOL) {
- hnum = RSYMBOL(a)->hashval;
- }
- else if (BUILTIN_TYPE(a) == T_BIGNUM) {
+ break;
+ case T_BIGNUM:
hval = rb_big_hash(a);
hnum = FIX2LONG(hval);
- }
- else if (BUILTIN_TYPE(a) == T_FLOAT) {
- flt:
+ break;
+ case T_FLOAT: /* prevent pathological behavior: [Bug #10761] */
hnum = rb_dbl_long_hash(rb_float_value(a));
- }
- else {
+ break;
+ default:
hnum = other_func(a);
}
- out:
- hnum <<= 1;
- return (long)RSHIFT(hnum, 1);
+ if ((SIGNED_VALUE)hnum > 0)
+ hnum &= FIXNUM_MAX;
+ else
+ hnum |= FIXNUM_MIN;
+ return (long)hnum;
}
static st_index_t
@@ -216,14 +249,14 @@ rb_any_hash(VALUE a)
/* Here we two primes with random bit generation. */
static const uint64_t prime1 = ((uint64_t)0x2e0bb864 << 32) | 0xe9ea7df5;
-static const uint64_t prime2 = ((uint64_t)0xcdb32970 << 32) | 0x830fcaa1;
+static const uint32_t prime2 = 0x830fcab9;
static inline uint64_t
mult_and_mix(uint64_t m1, uint64_t m2)
{
-#if defined(__GNUC__) && UINT_MAX != ULONG_MAX
- __uint128_t r = (__uint128_t) m1 * (__uint128_t) m2;
+#if defined HAVE_UINT128_T
+ uint128_t r = (uint128_t) m1 * (uint128_t) m2;
return (uint64_t) (r >> 64) ^ (uint64_t) r;
#else
uint64_t hm1 = m1 >> 32, hm2 = m2 >> 32;
@@ -242,18 +275,51 @@ key64_hash(uint64_t key, uint32_t seed)
return mult_and_mix(key + seed, prime1);
}
-long
+/* Should cast down the result for each purpose */
+#define st_index_hash(index) key64_hash(rb_hash_start(index), prime2)
+
+static long
rb_objid_hash(st_index_t index)
{
- return (long)key64_hash(rb_hash_start(index), (uint32_t)prime2);
+ return (long)st_index_hash(index);
}
static st_index_t
objid_hash(VALUE obj)
{
- return rb_objid_hash((st_index_t)obj);
+ VALUE object_id = rb_obj_id(obj);
+ if (!FIXNUM_P(object_id))
+ object_id = rb_big_hash(object_id);
+
+#if SIZEOF_LONG == SIZEOF_VOIDP
+ return (st_index_t)st_index_hash((st_index_t)NUM2LONG(object_id));
+#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
+ return (st_index_t)st_index_hash((st_index_t)NUM2LL(object_id));
+#endif
}
+/**
+ * call-seq:
+ * obj.hash -> integer
+ *
+ * Generates an Integer hash value for this object. This function must have the
+ * property that <code>a.eql?(b)</code> implies <code>a.hash == b.hash</code>.
+ *
+ * The hash value is used along with #eql? by the Hash class to determine if
+ * two objects reference the same hash key. Any hash value that exceeds the
+ * capacity of an Integer will be truncated before being used.
+ *
+ * The hash value for an object may not be identical across invocations or
+ * implementations of Ruby. If you need a stable identifier across Ruby
+ * invocations and implementations you will need to generate one with a custom
+ * method.
+ *
+ * Certain core classes such as Integer use built-in hash calculations and
+ * do not call the #hash method when used as a hash key.
+ *--
+ * \private
+ *++
+ */
VALUE
rb_obj_hash(VALUE obj)
{
@@ -278,18 +344,964 @@ rb_ident_hash(st_data_t n)
* many integers get interpreted as 2.0 or -2.0 [Bug #10761]
*/
if (FLONUM_P(n)) {
- n ^= (st_data_t)rb_float_value(n);
+ n ^= dbl_to_index(rb_float_value(n));
}
#endif
- return (st_index_t)key64_hash(rb_hash_start((st_index_t)n), (uint32_t)prime2);
+ return (st_index_t)st_index_hash((st_index_t)n);
}
-static const struct st_hash_type identhash = {
+#define identhash rb_hashtype_ident
+const struct st_hash_type rb_hashtype_ident = {
rb_ident_cmp,
rb_ident_hash,
};
+typedef st_index_t st_hash_t;
+
+/*
+ * RHASH_AR_TABLE_P(h):
+ * * as.ar == NULL or
+ * as.ar points ar_table.
+ * * as.ar is allocated by transient heap or xmalloc.
+ *
+ * !RHASH_AR_TABLE_P(h):
+ * * as.st points st_table.
+ */
+
+#define RHASH_AR_TABLE_MAX_BOUND RHASH_AR_TABLE_MAX_SIZE
+
+#define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n])
+#define RHASH_AR_CLEARED_HINT 0xff
+
+typedef struct ar_table_pair_struct {
+ VALUE key;
+ VALUE val;
+} ar_table_pair;
+
+typedef struct ar_table_struct {
+ /* 64bit CPU: 8B * 2 * 8 = 128B */
+ ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE];
+} ar_table;
+
+size_t
+rb_hash_ar_table_size(void)
+{
+ return sizeof(ar_table);
+}
+
+static inline st_hash_t
+ar_do_hash(st_data_t key)
+{
+ return (st_hash_t)rb_any_hash(key);
+}
+
+static inline ar_hint_t
+ar_do_hash_hint(st_hash_t hash_value)
+{
+ return (ar_hint_t)hash_value;
+}
+
+static inline ar_hint_t
+ar_hint(VALUE hash, unsigned int index)
+{
+ return RHASH(hash)->ar_hint.ary[index];
+}
+
+static inline void
+ar_hint_set_hint(VALUE hash, unsigned int index, ar_hint_t hint)
+{
+ RHASH(hash)->ar_hint.ary[index] = hint;
+}
+
+static inline void
+ar_hint_set(VALUE hash, unsigned int index, st_hash_t hash_value)
+{
+ ar_hint_set_hint(hash, index, ar_do_hash_hint(hash_value));
+}
+
+static inline void
+ar_clear_entry(VALUE hash, unsigned int index)
+{
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
+ pair->key = Qundef;
+ ar_hint_set_hint(hash, index, RHASH_AR_CLEARED_HINT);
+}
+
+static inline int
+ar_cleared_entry(VALUE hash, unsigned int index)
+{
+ if (ar_hint(hash, index) == RHASH_AR_CLEARED_HINT) {
+ /* RHASH_AR_CLEARED_HINT is only a hint, not mean cleared entry,
+ * so you need to check key == Qundef
+ */
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
+ return pair->key == Qundef;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static inline void
+ar_set_entry(VALUE hash, unsigned int index, st_data_t key, st_data_t val, st_hash_t hash_value)
+{
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
+ pair->key = key;
+ pair->val = val;
+ ar_hint_set(hash, index, hash_value);
+}
+
+#define RHASH_AR_TABLE_SIZE(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
+ RHASH_AR_TABLE_SIZE_RAW(h))
+
+#define RHASH_AR_TABLE_BOUND_RAW(h) \
+ ((unsigned int)((RBASIC(h)->flags >> RHASH_AR_TABLE_BOUND_SHIFT) & \
+ (RHASH_AR_TABLE_BOUND_MASK >> RHASH_AR_TABLE_BOUND_SHIFT)))
+
+#define RHASH_AR_TABLE_BOUND(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
+ RHASH_AR_TABLE_BOUND_RAW(h))
+
+#define RHASH_ST_TABLE_SET(h, s) rb_hash_st_table_set(h, s)
+#define RHASH_TYPE(hash) (RHASH_AR_TABLE_P(hash) ? &objhash : RHASH_ST_TABLE(hash)->type)
+
+#define HASH_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(HASH_DEBUG, expr, #expr)
+
+#if HASH_DEBUG
+#define hash_verify(hash) hash_verify_(hash, __FILE__, __LINE__)
+
+void
+rb_hash_dump(VALUE hash)
+{
+ rb_obj_info_dump(hash);
+
+ if (RHASH_AR_TABLE_P(hash)) {
+ unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
+
+ fprintf(stderr, " size:%u bound:%u\n",
+ RHASH_AR_TABLE_SIZE(hash), RHASH_AR_TABLE_BOUND(hash));
+
+ for (i=0; i<bound; i++) {
+ st_data_t k, v;
+
+ if (!ar_cleared_entry(hash, i)) {
+ char b1[0x100], b2[0x100];
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ k = pair->key;
+ v = pair->val;
+ fprintf(stderr, " %d key:%s val:%s hint:%02x\n", i,
+ rb_raw_obj_info(b1, 0x100, k),
+ rb_raw_obj_info(b2, 0x100, v),
+ ar_hint(hash, i));
+ n++;
+ }
+ else {
+ fprintf(stderr, " %d empty\n", i);
+ }
+ }
+ }
+}
+
+static VALUE
+hash_verify_(VALUE hash, const char *file, int line)
+{
+ HASH_ASSERT(RB_TYPE_P(hash, T_HASH));
+
+ if (RHASH_AR_TABLE_P(hash)) {
+ unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
+
+ for (i=0; i<bound; i++) {
+ st_data_t k, v;
+ if (!ar_cleared_entry(hash, i)) {
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ k = pair->key;
+ v = pair->val;
+ HASH_ASSERT(k != Qundef);
+ HASH_ASSERT(v != Qundef);
+ n++;
+ }
+ }
+ if (n != RHASH_AR_TABLE_SIZE(hash)) {
+ rb_bug("n:%u, RHASH_AR_TABLE_SIZE:%u", n, RHASH_AR_TABLE_SIZE(hash));
+ }
+ }
+ else {
+ HASH_ASSERT(RHASH_ST_TABLE(hash) != NULL);
+ HASH_ASSERT(RHASH_AR_TABLE_SIZE_RAW(hash) == 0);
+ HASH_ASSERT(RHASH_AR_TABLE_BOUND_RAW(hash) == 0);
+ }
+
+#if USE_TRANSIENT_HEAP
+ if (RHASH_TRANSIENT_P(hash)) {
+ volatile st_data_t MAYBE_UNUSED(key) = RHASH_AR_TABLE_REF(hash, 0)->key; /* read */
+ HASH_ASSERT(RHASH_AR_TABLE(hash) != NULL);
+ HASH_ASSERT(rb_transient_heap_managed_ptr_p(RHASH_AR_TABLE(hash)));
+ }
+#endif
+ return hash;
+}
+
+#else
+#define hash_verify(h) ((void)0)
+#endif
+
+static inline int
+RHASH_TABLE_NULL_P(VALUE hash)
+{
+ if (RHASH(hash)->as.ar == NULL) {
+ HASH_ASSERT(RHASH_AR_TABLE_P(hash));
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static inline int
+RHASH_TABLE_EMPTY_P(VALUE hash)
+{
+ return RHASH_SIZE(hash) == 0;
+}
+
+int
+rb_hash_ar_table_p(VALUE hash)
+{
+ if (FL_TEST_RAW((hash), RHASH_ST_TABLE_FLAG)) {
+ HASH_ASSERT(RHASH(hash)->as.st != NULL);
+ return FALSE;
+ }
+ else {
+ return TRUE;
+ }
+}
+
+ar_table *
+rb_hash_ar_table(VALUE hash)
+{
+ HASH_ASSERT(RHASH_AR_TABLE_P(hash));
+ return RHASH(hash)->as.ar;
+}
+
+st_table *
+rb_hash_st_table(VALUE hash)
+{
+ HASH_ASSERT(!RHASH_AR_TABLE_P(hash));
+ return RHASH(hash)->as.st;
+}
+
+void
+rb_hash_st_table_set(VALUE hash, st_table *st)
+{
+ HASH_ASSERT(st != NULL);
+ FL_SET_RAW((hash), RHASH_ST_TABLE_FLAG);
+ RHASH(hash)->as.st = st;
+}
+
+static void
+hash_ar_table_set(VALUE hash, ar_table *ar)
+{
+ HASH_ASSERT(RHASH_AR_TABLE_P(hash));
+ HASH_ASSERT((RHASH_TRANSIENT_P(hash) && ar == NULL) ? FALSE : TRUE);
+ RHASH(hash)->as.ar = ar;
+ hash_verify(hash);
+}
+
+#define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG)
+#define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG)
+
+static inline void
+RHASH_AR_TABLE_BOUND_SET(VALUE h, st_index_t n)
+{
+ HASH_ASSERT(RHASH_AR_TABLE_P(h));
+ HASH_ASSERT(n <= RHASH_AR_TABLE_MAX_BOUND);
+
+ RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
+ RBASIC(h)->flags |= n << RHASH_AR_TABLE_BOUND_SHIFT;
+}
+
+static inline void
+RHASH_AR_TABLE_SIZE_SET(VALUE h, st_index_t n)
+{
+ HASH_ASSERT(RHASH_AR_TABLE_P(h));
+ HASH_ASSERT(n <= RHASH_AR_TABLE_MAX_SIZE);
+
+ RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
+ RBASIC(h)->flags |= n << RHASH_AR_TABLE_SIZE_SHIFT;
+}
+
+static inline void
+HASH_AR_TABLE_SIZE_ADD(VALUE h, st_index_t n)
+{
+ HASH_ASSERT(RHASH_AR_TABLE_P(h));
+
+ RHASH_AR_TABLE_SIZE_SET(h, RHASH_AR_TABLE_SIZE(h) + n);
+
+ hash_verify(h);
+}
+
+#define RHASH_AR_TABLE_SIZE_INC(h) HASH_AR_TABLE_SIZE_ADD(h, 1)
+
+static inline void
+RHASH_AR_TABLE_SIZE_DEC(VALUE h)
+{
+ HASH_ASSERT(RHASH_AR_TABLE_P(h));
+ int new_size = RHASH_AR_TABLE_SIZE(h) - 1;
+
+ if (new_size != 0) {
+ RHASH_AR_TABLE_SIZE_SET(h, new_size);
+ }
+ else {
+ RHASH_AR_TABLE_SIZE_SET(h, 0);
+ RHASH_AR_TABLE_BOUND_SET(h, 0);
+ }
+ hash_verify(h);
+}
+
+static inline void
+RHASH_AR_TABLE_CLEAR(VALUE h)
+{
+ RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
+ RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
+
+ hash_ar_table_set(h, NULL);
+}
+
+static ar_table*
+ar_alloc_table(VALUE hash)
+{
+ ar_table *tab = (ar_table*)rb_transient_heap_alloc(hash, sizeof(ar_table));
+
+ if (tab != NULL) {
+ RHASH_SET_TRANSIENT_FLAG(hash);
+ }
+ else {
+ RHASH_UNSET_TRANSIENT_FLAG(hash);
+ tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
+ }
+
+ RHASH_AR_TABLE_SIZE_SET(hash, 0);
+ RHASH_AR_TABLE_BOUND_SET(hash, 0);
+ hash_ar_table_set(hash, tab);
+
+ return tab;
+}
+
+NOINLINE(static int ar_equal(VALUE x, VALUE y));
+
+static int
+ar_equal(VALUE x, VALUE y)
+{
+ return rb_any_cmp(x, y) == 0;
+}
+
+static unsigned
+ar_find_entry_hint(VALUE hash, ar_hint_t hint, st_data_t key)
+{
+ unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
+ const ar_hint_t *hints = RHASH(hash)->ar_hint.ary;
+
+ /* if table is NULL, then bound also should be 0 */
+
+ for (i = 0; i < bound; i++) {
+ if (hints[i] == hint) {
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ if (ar_equal(key, pair->key)) {
+ RB_DEBUG_COUNTER_INC(artable_hint_hit);
+ return i;
+ }
+ else {
+#if 0
+ static int pid;
+ static char fname[256];
+ static FILE *fp;
+
+ if (pid != getpid()) {
+ snprintf(fname, sizeof(fname), "/tmp/ruby-armiss.%d", pid = getpid());
+ if ((fp = fopen(fname, "w")) == NULL) rb_bug("fopen");
+ }
+
+ st_hash_t h1 = ar_do_hash(key);
+ st_hash_t h2 = ar_do_hash(pair->key);
+
+ fprintf(fp, "miss: hash_eq:%d hints[%d]:%02x hint:%02x\n"
+ " key :%016lx %s\n"
+ " pair->key:%016lx %s\n",
+ h1 == h2, i, hints[i], hint,
+ h1, rb_obj_info(key), h2, rb_obj_info(pair->key));
+#endif
+ RB_DEBUG_COUNTER_INC(artable_hint_miss);
+ }
+ }
+ }
+ RB_DEBUG_COUNTER_INC(artable_hint_notfound);
+ return RHASH_AR_TABLE_MAX_BOUND;
+}
+
+static unsigned
+ar_find_entry(VALUE hash, st_hash_t hash_value, st_data_t key)
+{
+ ar_hint_t hint = ar_do_hash_hint(hash_value);
+ return ar_find_entry_hint(hash, hint, key);
+}
+
+static inline void
+ar_free_and_clear_table(VALUE hash)
+{
+ ar_table *tab = RHASH_AR_TABLE(hash);
+
+ if (tab) {
+ if (RHASH_TRANSIENT_P(hash)) {
+ RHASH_UNSET_TRANSIENT_FLAG(hash);
+ }
+ else {
+ ruby_xfree(RHASH_AR_TABLE(hash));
+ }
+ RHASH_AR_TABLE_CLEAR(hash);
+ }
+ HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
+ HASH_ASSERT(RHASH_AR_TABLE_BOUND(hash) == 0);
+ HASH_ASSERT(RHASH_TRANSIENT_P(hash) == 0);
+}
+
+static void
+ar_try_convert_table(VALUE hash)
+{
+ if (!RHASH_AR_TABLE_P(hash)) return;
+
+ const unsigned size = RHASH_AR_TABLE_SIZE(hash);
+
+ st_table *new_tab;
+ st_index_t i;
+
+ if (size < RHASH_AR_TABLE_MAX_SIZE) {
+ return;
+ }
+
+ new_tab = st_init_table_with_size(&objhash, size * 2);
+
+ for (i = 0; i < RHASH_AR_TABLE_MAX_BOUND; i++) {
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ st_add_direct(new_tab, pair->key, pair->val);
+ }
+ ar_free_and_clear_table(hash);
+ RHASH_ST_TABLE_SET(hash, new_tab);
+ return;
+}
+
+static st_table *
+ar_force_convert_table(VALUE hash, const char *file, int line)
+{
+ st_table *new_tab;
+
+ if (RHASH_ST_TABLE_P(hash)) {
+ return RHASH_ST_TABLE(hash);
+ }
+
+ if (RHASH_AR_TABLE(hash)) {
+ unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
+
+#if RHASH_CONVERT_TABLE_DEBUG
+ rb_obj_info_dump(hash);
+ fprintf(stderr, "force_convert: %s:%d\n", file, line);
+ RB_DEBUG_COUNTER_INC(obj_hash_force_convert);
+#endif
+
+ new_tab = st_init_table_with_size(&objhash, RHASH_AR_TABLE_SIZE(hash));
+
+ for (i = 0; i < bound; i++) {
+ if (ar_cleared_entry(hash, i)) continue;
+
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ st_add_direct(new_tab, pair->key, pair->val);
+ }
+ ar_free_and_clear_table(hash);
+ }
+ else {
+ new_tab = st_init_table(&objhash);
+ }
+ RHASH_ST_TABLE_SET(hash, new_tab);
+
+ return new_tab;
+}
+
+static ar_table *
+hash_ar_table(VALUE hash)
+{
+ if (RHASH_TABLE_NULL_P(hash)) {
+ ar_alloc_table(hash);
+ }
+ return RHASH_AR_TABLE(hash);
+}
+
+static int
+ar_compact_table(VALUE hash)
+{
+ const unsigned bound = RHASH_AR_TABLE_BOUND(hash);
+ const unsigned size = RHASH_AR_TABLE_SIZE(hash);
+
+ if (size == bound) {
+ return size;
+ }
+ else {
+ unsigned i, j=0;
+ ar_table_pair *pairs = RHASH_AR_TABLE(hash)->pairs;
+
+ for (i=0; i<bound; i++) {
+ if (ar_cleared_entry(hash, i)) {
+ if (j <= i) j = i+1;
+ for (; j<bound; j++) {
+ if (!ar_cleared_entry(hash, j)) {
+ pairs[i] = pairs[j];
+ ar_hint_set_hint(hash, i, (st_hash_t)ar_hint(hash, j));
+ ar_clear_entry(hash, j);
+ j++;
+ goto found;
+ }
+ }
+ /* non-empty is not found */
+ goto done;
+ found:;
+ }
+ }
+ done:
+ HASH_ASSERT(i<=bound);
+
+ RHASH_AR_TABLE_BOUND_SET(hash, size);
+ hash_verify(hash);
+ return size;
+ }
+}
+
+static int
+ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash_value)
+{
+ unsigned bin = RHASH_AR_TABLE_BOUND(hash);
+
+ if (RHASH_AR_TABLE_SIZE(hash) >= RHASH_AR_TABLE_MAX_SIZE) {
+ return 1;
+ }
+ else {
+ if (UNLIKELY(bin >= RHASH_AR_TABLE_MAX_BOUND)) {
+ bin = ar_compact_table(hash);
+ hash_ar_table(hash);
+ }
+ HASH_ASSERT(bin < RHASH_AR_TABLE_MAX_BOUND);
+
+ ar_set_entry(hash, bin, key, val, hash_value);
+ RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
+ RHASH_AR_TABLE_SIZE_INC(hash);
+ return 0;
+ }
+}
+
+static int
+ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
+{
+ if (RHASH_AR_TABLE_SIZE(hash) > 0) {
+ unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
+
+ for (i = 0; i < bound; i++) {
+ if (ar_cleared_entry(hash, i)) continue;
+
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
+ /* pair may be not valid here because of theap */
+
+ switch (retval) {
+ case ST_CONTINUE:
+ break;
+ case ST_CHECK:
+ case ST_STOP:
+ return 0;
+ case ST_REPLACE:
+ if (replace) {
+ VALUE key = pair->key;
+ VALUE val = pair->val;
+ retval = (*replace)(&key, &val, arg, TRUE);
+
+ // TODO: pair should be same as pair before.
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ pair->key = key;
+ pair->val = val;
+ }
+ break;
+ case ST_DELETE:
+ ar_clear_entry(hash, i);
+ RHASH_AR_TABLE_SIZE_DEC(hash);
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+ar_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
+{
+ return ar_general_foreach(hash, func, replace, arg);
+}
+
+struct functor {
+ st_foreach_callback_func *func;
+ st_data_t arg;
+};
+
+static int
+apply_functor(st_data_t k, st_data_t v, st_data_t d, int _)
+{
+ const struct functor *f = (void *)d;
+ return f->func(k, v, f->arg);
+}
+
+static int
+ar_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
+{
+ const struct functor f = { func, arg };
+ return ar_general_foreach(hash, apply_functor, NULL, (st_data_t)&f);
+}
+
+static int
+ar_foreach_check(VALUE hash, st_foreach_check_callback_func *func, st_data_t arg,
+ st_data_t never)
+{
+ if (RHASH_AR_TABLE_SIZE(hash) > 0) {
+ unsigned i, ret = 0, bound = RHASH_AR_TABLE_BOUND(hash);
+ enum st_retval retval;
+ st_data_t key;
+ ar_table_pair *pair;
+ ar_hint_t hint;
+
+ for (i = 0; i < bound; i++) {
+ if (ar_cleared_entry(hash, i)) continue;
+
+ pair = RHASH_AR_TABLE_REF(hash, i);
+ key = pair->key;
+ hint = ar_hint(hash, i);
+
+ retval = (*func)(key, pair->val, arg, 0);
+ hash_verify(hash);
+
+ switch (retval) {
+ case ST_CHECK: {
+ pair = RHASH_AR_TABLE_REF(hash, i);
+ if (pair->key == never) break;
+ ret = ar_find_entry_hint(hash, hint, key);
+ if (ret == RHASH_AR_TABLE_MAX_BOUND) {
+ retval = (*func)(0, 0, arg, 1);
+ return 2;
+ }
+ }
+ case ST_CONTINUE:
+ break;
+ case ST_STOP:
+ case ST_REPLACE:
+ return 0;
+ case ST_DELETE: {
+ if (!ar_cleared_entry(hash, i)) {
+ ar_clear_entry(hash, i);
+ RHASH_AR_TABLE_SIZE_DEC(hash);
+ }
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+ar_update(VALUE hash, st_data_t key,
+ st_update_callback_func *func, st_data_t arg)
+{
+ int retval, existing;
+ unsigned bin = RHASH_AR_TABLE_MAX_BOUND;
+ st_data_t value = 0, old_key;
+ st_hash_t hash_value = ar_do_hash(key);
+
+ if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
+ // `#hash` changes ar_table -> st_table
+ return -1;
+ }
+
+ if (RHASH_AR_TABLE_SIZE(hash) > 0) {
+ bin = ar_find_entry(hash, hash_value, key);
+ existing = (bin != RHASH_AR_TABLE_MAX_BOUND) ? TRUE : FALSE;
+ }
+ else {
+ hash_ar_table(hash); /* allocate ltbl if needed */
+ existing = FALSE;
+ }
+
+ if (existing) {
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
+ key = pair->key;
+ value = pair->val;
+ }
+ old_key = key;
+ retval = (*func)(&key, &value, arg, existing);
+ /* pair can be invalid here because of theap */
+
+ switch (retval) {
+ case ST_CONTINUE:
+ if (!existing) {
+ if (ar_add_direct_with_hash(hash, key, value, hash_value)) {
+ return -1;
+ }
+ }
+ else {
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
+ if (old_key != key) {
+ pair->key = key;
+ }
+ pair->val = value;
+ }
+ break;
+ case ST_DELETE:
+ if (existing) {
+ ar_clear_entry(hash, bin);
+ RHASH_AR_TABLE_SIZE_DEC(hash);
+ }
+ break;
+ }
+ return existing;
+}
+
+static int
+ar_insert(VALUE hash, st_data_t key, st_data_t value)
+{
+ unsigned bin = RHASH_AR_TABLE_BOUND(hash);
+ st_hash_t hash_value = ar_do_hash(key);
+
+ if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
+ // `#hash` changes ar_table -> st_table
+ return -1;
+ }
+
+ hash_ar_table(hash); /* prepare ltbl */
+
+ bin = ar_find_entry(hash, hash_value, key);
+ if (bin == RHASH_AR_TABLE_MAX_BOUND) {
+ if (RHASH_AR_TABLE_SIZE(hash) >= RHASH_AR_TABLE_MAX_SIZE) {
+ return -1;
+ }
+ else if (bin >= RHASH_AR_TABLE_MAX_BOUND) {
+ bin = ar_compact_table(hash);
+ hash_ar_table(hash);
+ }
+ HASH_ASSERT(bin < RHASH_AR_TABLE_MAX_BOUND);
+
+ ar_set_entry(hash, bin, key, value, hash_value);
+ RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
+ RHASH_AR_TABLE_SIZE_INC(hash);
+ return 0;
+ }
+ else {
+ RHASH_AR_TABLE_REF(hash, bin)->val = value;
+ return 1;
+ }
+}
+
+static int
+ar_lookup(VALUE hash, st_data_t key, st_data_t *value)
+{
+ if (RHASH_AR_TABLE_SIZE(hash) == 0) {
+ return 0;
+ }
+ else {
+ st_hash_t hash_value = ar_do_hash(key);
+ if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
+ // `#hash` changes ar_table -> st_table
+ return st_lookup(RHASH_ST_TABLE(hash), key, value);
+ }
+ unsigned bin = ar_find_entry(hash, hash_value, key);
+
+ if (bin == RHASH_AR_TABLE_MAX_BOUND) {
+ return 0;
+ }
+ else {
+ HASH_ASSERT(bin < RHASH_AR_TABLE_MAX_BOUND);
+ if (value != NULL) {
+ *value = RHASH_AR_TABLE_REF(hash, bin)->val;
+ }
+ return 1;
+ }
+ }
+}
+
+static int
+ar_delete(VALUE hash, st_data_t *key, st_data_t *value)
+{
+ unsigned bin;
+ st_hash_t hash_value = ar_do_hash(*key);
+
+ if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
+ // `#hash` changes ar_table -> st_table
+ return st_delete(RHASH_ST_TABLE(hash), key, value);
+ }
+
+ bin = ar_find_entry(hash, hash_value, *key);
+
+ if (bin == RHASH_AR_TABLE_MAX_BOUND) {
+ if (value != 0) *value = 0;
+ return 0;
+ }
+ else {
+ if (value != 0) {
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
+ *value = pair->val;
+ }
+ ar_clear_entry(hash, bin);
+ RHASH_AR_TABLE_SIZE_DEC(hash);
+ return 1;
+ }
+}
+
+static int
+ar_shift(VALUE hash, st_data_t *key, st_data_t *value)
+{
+ if (RHASH_AR_TABLE_SIZE(hash) > 0) {
+ unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
+
+ for (i = 0; i < bound; i++) {
+ if (!ar_cleared_entry(hash, i)) {
+ ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
+ if (value != 0) *value = pair->val;
+ *key = pair->key;
+ ar_clear_entry(hash, i);
+ RHASH_AR_TABLE_SIZE_DEC(hash);
+ return 1;
+ }
+ }
+ }
+ if (value != NULL) *value = 0;
+ return 0;
+}
+
+static long
+ar_keys(VALUE hash, st_data_t *keys, st_index_t size)
+{
+ unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
+ st_data_t *keys_start = keys, *keys_end = keys + size;
+
+ for (i = 0; i < bound; i++) {
+ if (keys == keys_end) {
+ break;
+ }
+ else {
+ if (!ar_cleared_entry(hash, i)) {
+ *keys++ = RHASH_AR_TABLE_REF(hash, i)->key;
+ }
+ }
+ }
+
+ return keys - keys_start;
+}
+
+static long
+ar_values(VALUE hash, st_data_t *values, st_index_t size)
+{
+ unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
+ st_data_t *values_start = values, *values_end = values + size;
+
+ for (i = 0; i < bound; i++) {
+ if (values == values_end) {
+ break;
+ }
+ else {
+ if (!ar_cleared_entry(hash, i)) {
+ *values++ = RHASH_AR_TABLE_REF(hash, i)->val;
+ }
+ }
+ }
+
+ return values - values_start;
+}
+
+static ar_table*
+ar_copy(VALUE hash1, VALUE hash2)
+{
+ ar_table *old_tab = RHASH_AR_TABLE(hash2);
+
+ if (old_tab != NULL) {
+ ar_table *new_tab = RHASH_AR_TABLE(hash1);
+ if (new_tab == NULL) {
+ new_tab = (ar_table*) rb_transient_heap_alloc(hash1, sizeof(ar_table));
+ if (new_tab != NULL) {
+ RHASH_SET_TRANSIENT_FLAG(hash1);
+ }
+ else {
+ RHASH_UNSET_TRANSIENT_FLAG(hash1);
+ new_tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
+ }
+ }
+ *new_tab = *old_tab;
+ RHASH(hash1)->ar_hint.word = RHASH(hash2)->ar_hint.word;
+ RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
+ RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
+ hash_ar_table_set(hash1, new_tab);
+
+ rb_gc_writebarrier_remember(hash1);
+ return new_tab;
+ }
+ else {
+ RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
+ RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
+
+ if (RHASH_TRANSIENT_P(hash1)) {
+ RHASH_UNSET_TRANSIENT_FLAG(hash1);
+ }
+ else if (RHASH_AR_TABLE(hash1)) {
+ ruby_xfree(RHASH_AR_TABLE(hash1));
+ }
+
+ hash_ar_table_set(hash1, NULL);
+
+ rb_gc_writebarrier_remember(hash1);
+ return old_tab;
+ }
+}
+
+static void
+ar_clear(VALUE hash)
+{
+ if (RHASH_AR_TABLE(hash) != NULL) {
+ RHASH_AR_TABLE_SIZE_SET(hash, 0);
+ RHASH_AR_TABLE_BOUND_SET(hash, 0);
+ }
+ else {
+ HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
+ HASH_ASSERT(RHASH_AR_TABLE_BOUND(hash) == 0);
+ }
+}
+
+#if USE_TRANSIENT_HEAP
+void
+rb_hash_transient_heap_evacuate(VALUE hash, int promote)
+{
+ if (RHASH_TRANSIENT_P(hash)) {
+ ar_table *new_tab;
+ ar_table *old_tab = RHASH_AR_TABLE(hash);
+
+ if (UNLIKELY(old_tab == NULL)) {
+ rb_gc_force_recycle(hash);
+ return;
+ }
+ HASH_ASSERT(old_tab != NULL);
+ if (! promote) {
+ new_tab = rb_transient_heap_alloc(hash, sizeof(ar_table));
+ if (new_tab == NULL) promote = true;
+ }
+ if (promote) {
+ new_tab = ruby_xmalloc(sizeof(ar_table));
+ RHASH_UNSET_TRANSIENT_FLAG(hash);
+ }
+ *new_tab = *old_tab;
+ hash_ar_table_set(hash, new_tab);
+ }
+ hash_verify(hash);
+}
+#endif
+
typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
struct foreach_safe_arg {
@@ -313,7 +1325,7 @@ foreach_safe_i(st_data_t key, st_data_t value, st_data_t args, int error)
}
void
-st_foreach_safe(st_table *table, int (*func)(ANYARGS), st_data_t a)
+st_foreach_safe(st_table *table, st_foreach_func *func, st_data_t a)
{
struct foreach_safe_arg arg;
@@ -334,6 +1346,27 @@ struct hash_foreach_arg {
};
static int
+hash_ar_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
+{
+ struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
+ int status;
+
+ if (error) return ST_STOP;
+ status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
+ /* TODO: rehash check? rb_raise(rb_eRuntimeError, "rehash occurred during iteration"); */
+
+ switch (status) {
+ case ST_DELETE:
+ return ST_DELETE;
+ case ST_CONTINUE:
+ break;
+ case ST_STOP:
+ return ST_STOP;
+ }
+ return ST_CHECK;
+}
+
+static int
hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
{
struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
@@ -341,10 +1374,10 @@ hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
st_table *tbl;
if (error) return ST_STOP;
- tbl = RHASH(arg->hash)->ntbl;
+ tbl = RHASH_ST_TABLE(arg->hash);
status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
- if (RHASH(arg->hash)->ntbl != tbl) {
- rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
+ if (RHASH_ST_TABLE(arg->hash) != tbl) {
+ rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
}
switch (status) {
case ST_DELETE:
@@ -357,42 +1390,142 @@ hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
return ST_CHECK;
}
+static int
+iter_lev_in_ivar(VALUE hash)
+{
+ VALUE levval = rb_ivar_get(hash, id_hash_iter_lev);
+ HASH_ASSERT(FIXNUM_P(levval));
+ return FIX2INT(levval);
+}
+
+void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
+
+static void
+iter_lev_in_ivar_set(VALUE hash, int lev)
+{
+ rb_ivar_set_internal(hash, id_hash_iter_lev, INT2FIX(lev));
+}
+
+static int
+iter_lev_in_flags(VALUE hash)
+{
+ unsigned int u = (unsigned int)((RBASIC(hash)->flags >> RHASH_LEV_SHIFT) & RHASH_LEV_MAX);
+ return (int)u;
+}
+
+static int
+RHASH_ITER_LEV(VALUE hash)
+{
+ int lev = iter_lev_in_flags(hash);
+
+ if (lev == RHASH_LEV_MAX) {
+ return iter_lev_in_ivar(hash);
+ }
+ else {
+ return lev;
+ }
+}
+
+static void
+hash_iter_lev_inc(VALUE hash)
+{
+ int lev = iter_lev_in_flags(hash);
+ if (lev == RHASH_LEV_MAX) {
+ lev = iter_lev_in_ivar(hash);
+ iter_lev_in_ivar_set(hash, lev+1);
+ }
+ else {
+ lev += 1;
+ RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((VALUE)lev << RHASH_LEV_SHIFT));
+ if (lev == RHASH_LEV_MAX) {
+ iter_lev_in_ivar_set(hash, lev);
+ }
+ }
+}
+
+static void
+hash_iter_lev_dec(VALUE hash)
+{
+ int lev = iter_lev_in_flags(hash);
+ if (lev == RHASH_LEV_MAX) {
+ lev = iter_lev_in_ivar(hash);
+ HASH_ASSERT(lev > 0);
+ iter_lev_in_ivar_set(hash, lev-1);
+ }
+ else {
+ HASH_ASSERT(lev > 0);
+ RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((lev-1) << RHASH_LEV_SHIFT));
+ }
+}
+
static VALUE
hash_foreach_ensure_rollback(VALUE hash)
{
- RHASH_ITER_LEV(hash)++;
+ hash_iter_lev_inc(hash);
return 0;
}
static VALUE
hash_foreach_ensure(VALUE hash)
{
- RHASH_ITER_LEV(hash)--;
+ hash_iter_lev_dec(hash);
return 0;
}
+int
+rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
+{
+ if (RHASH_AR_TABLE_P(hash)) {
+ return ar_foreach(hash, func, arg);
+ }
+ else {
+ return st_foreach(RHASH_ST_TABLE(hash), func, arg);
+ }
+}
+
+int
+rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
+{
+ if (RHASH_AR_TABLE_P(hash)) {
+ return ar_foreach_with_replace(hash, func, replace, arg);
+ }
+ else {
+ return st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg);
+ }
+}
+
static VALUE
hash_foreach_call(VALUE arg)
{
VALUE hash = ((struct hash_foreach_arg *)arg)->hash;
- if (st_foreach_check(RHASH(hash)->ntbl, hash_foreach_iter, (st_data_t)arg, (st_data_t)Qundef)) {
- rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ int ret = 0;
+ if (RHASH_AR_TABLE_P(hash)) {
+ ret = ar_foreach_check(hash, hash_ar_foreach_iter,
+ (st_data_t)arg, (st_data_t)Qundef);
+ }
+ else if (RHASH_ST_TABLE_P(hash)) {
+ ret = st_foreach_check(RHASH_ST_TABLE(hash), hash_foreach_iter,
+ (st_data_t)arg, (st_data_t)Qundef);
+ }
+ if (ret) {
+ rb_raise(rb_eRuntimeError, "ret: %d, hash modified during iteration", ret);
}
return Qnil;
}
void
-rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
+rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
{
struct hash_foreach_arg arg;
- if (!RHASH(hash)->ntbl)
+ if (RHASH_TABLE_EMPTY_P(hash))
return;
- RHASH_ITER_LEV(hash)++;
+ hash_iter_lev_inc(hash);
arg.hash = hash;
arg.func = (rb_foreach_func *)func;
arg.arg = farg;
rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
+ hash_verify(hash);
}
static VALUE
@@ -426,69 +1559,82 @@ rb_hash_new(void)
return hash_alloc(rb_cHash);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_new_with_size(st_index_t size)
{
VALUE ret = rb_hash_new();
- if (size)
- RHASH(ret)->ntbl = st_init_table_with_size(&objhash, size);
+ if (size == 0) {
+ /* do nothing */
+ }
+ else if (size <= RHASH_AR_TABLE_MAX_SIZE) {
+ ar_alloc_table(ret);
+ }
+ else {
+ RHASH_ST_TABLE_SET(ret, st_init_table_with_size(&objhash, size));
+ }
return ret;
}
static VALUE
-hash_dup(VALUE hash, VALUE klass, VALUE flags)
+hash_copy(VALUE ret, VALUE hash)
{
- VALUE ret = hash_alloc_flags(klass, flags,
- RHASH_IFNONE(hash));
- if (!RHASH_EMPTY_P(hash))
- RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
+ if (!RHASH_EMPTY_P(hash)) {
+ if (RHASH_AR_TABLE_P(hash))
+ ar_copy(ret, hash);
+ else if (RHASH_ST_TABLE_P(hash))
+ RHASH_ST_TABLE_SET(ret, st_copy(RHASH_ST_TABLE(hash)));
+ }
return ret;
}
+static VALUE
+hash_dup(VALUE hash, VALUE klass, VALUE flags)
+{
+ return hash_copy(hash_alloc_flags(klass, flags, RHASH_IFNONE(hash)),
+ hash);
+}
+
VALUE
rb_hash_dup(VALUE hash)
{
const VALUE flags = RBASIC(hash)->flags;
VALUE ret = hash_dup(hash, rb_obj_class(hash),
- flags & (FL_EXIVAR|FL_TAINT|HASH_PROC_DEFAULT));
+ flags & (FL_EXIVAR|RHASH_PROC_DEFAULT));
if (flags & FL_EXIVAR)
rb_copy_generic_ivar(ret, hash);
return ret;
}
+MJIT_FUNC_EXPORTED VALUE
+rb_hash_resurrect(VALUE hash)
+{
+ VALUE ret = hash_dup(hash, rb_cHash, 0);
+ return ret;
+}
+
static void
rb_hash_modify_check(VALUE hash)
{
rb_check_frozen(hash);
}
-static struct st_table *
-hash_tbl(VALUE hash)
+MJIT_FUNC_EXPORTED struct st_table *
+rb_hash_tbl_raw(VALUE hash, const char *file, int line)
{
- if (!RHASH(hash)->ntbl) {
- RHASH(hash)->ntbl = st_init_table(&objhash);
- }
- return RHASH(hash)->ntbl;
+ return ar_force_convert_table(hash, file, line);
}
struct st_table *
-rb_hash_tbl(VALUE hash)
+rb_hash_tbl(VALUE hash, const char *file, int line)
{
OBJ_WB_UNPROTECT(hash);
- return hash_tbl(hash);
-}
-
-struct st_table *
-rb_hash_tbl_raw(VALUE hash)
-{
- return hash_tbl(hash);
+ return rb_hash_tbl_raw(hash, file, line);
}
static void
rb_hash_modify(VALUE hash)
{
rb_hash_modify_check(hash);
- hash_tbl(hash);
}
NORETURN(static void no_new_key(void));
@@ -528,6 +1674,22 @@ struct update_arg {
typedef int (*tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int);
+int
+rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg)
+{
+ if (RHASH_AR_TABLE_P(hash)) {
+ int result = ar_update(hash, (st_data_t)key, func, arg);
+ if (result == -1) {
+ ar_try_convert_table(hash);
+ }
+ else {
+ return result;
+ }
+ }
+
+ return st_update(RHASH_ST_TABLE(hash), (st_data_t)key, func, arg);
+}
+
static int
tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
{
@@ -541,7 +1703,7 @@ tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
arg.new_value = 0;
arg.old_value = Qundef;
- result = st_update(RHASH(hash)->ntbl, (st_data_t)key, func, (st_data_t)&arg);
+ result = rb_hash_stlike_update(hash, key, func, (st_data_t)&arg);
/* write barrier */
if (arg.new_key) RB_OBJ_WRITTEN(hash, arg.old_key, arg.new_key);
@@ -571,43 +1733,39 @@ set_proc_default(VALUE hash, VALUE proc)
}
}
- FL_SET_RAW(hash, HASH_PROC_DEFAULT);
+ FL_SET_RAW(hash, RHASH_PROC_DEFAULT);
RHASH_SET_IFNONE(hash, proc);
}
/*
* call-seq:
- * Hash.new -> new_hash
- * Hash.new(obj) -> new_hash
- * Hash.new {|hash, key| block } -> new_hash
- *
- * Returns a new, empty hash. If this hash is subsequently accessed by
- * a key that doesn't correspond to a hash entry, the value returned
- * depends on the style of <code>new</code> used to create the hash. In
- * the first form, the access returns <code>nil</code>. If
- * <i>obj</i> is specified, this single object will be used for
- * all <em>default values</em>. If a block is specified, it will be
- * called with the hash object and the key, and should return the
- * default value. It is the block's responsibility to store the value
- * in the hash if required.
- *
- * h = Hash.new("Go Fish")
- * h["a"] = 100
- * h["b"] = 200
- * h["a"] #=> 100
- * h["c"] #=> "Go Fish"
- * # The following alters the single default object
- * h["c"].upcase! #=> "GO FISH"
- * h["d"] #=> "GO FISH"
- * h.keys #=> ["a", "b"]
- *
- * # While this creates a new default object each time
- * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
- * h["c"] #=> "Go Fish: c"
- * h["c"].upcase! #=> "GO FISH: C"
- * h["d"] #=> "Go Fish: d"
- * h.keys #=> ["c", "d"]
- *
+ * Hash.new(default_value = nil) -> new_hash
+ * Hash.new {|hash, key| ... } -> new_hash
+ *
+ * Returns a new empty \Hash object.
+ *
+ * The initial default value and initial default proc for the new hash
+ * depend on which form above was used. See {Default Values}[#class-Hash-label-Default+Values].
+ *
+ * If neither an argument nor a block given,
+ * initializes both the default value and the default proc to <tt>nil</tt>:
+ * h = Hash.new
+ * h.default # => nil
+ * h.default_proc # => nil
+ *
+ * If argument <tt>default_value</tt> given but no block given,
+ * initializes the default value to the given <tt>default_value</tt>
+ * and the default proc to <tt>nil</tt>:
+ * h = Hash.new(false)
+ * h.default # => false
+ * h.default_proc # => nil
+ *
+ * If a block given but no argument, stores the block as the default proc
+ * and sets the default value to <tt>nil</tt>:
+ * h = Hash.new {|hash, key| "Default value for #{key}" }
+ * h.default # => nil
+ * h.default_proc.class # => Proc
+ * h[:nosuch] # => "Default value for nosuch"
*/
static VALUE
@@ -632,22 +1790,31 @@ rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
/*
* call-seq:
- * Hash[ key, value, ... ] -> new_hash
- * Hash[ [ [key, value], ... ] ] -> new_hash
- * Hash[ object ] -> new_hash
+ * Hash[] -> new_empty_hash
+ * Hash[hash] -> new_hash
+ * Hash[ [*2_element_arrays] ] -> new_hash
+ * Hash[*objects] -> new_hash
+ *
+ * Returns a new \Hash object populated with the given objects, if any.
+ * See Hash::new.
*
- * Creates a new hash populated with the given objects.
+ * With no argument, returns a new empty \Hash.
*
- * Similar to the literal <code>{ _key_ => _value_, ... }</code>. In the first
- * form, keys and values occur in pairs, so there must be an even number of
- * arguments.
+ * When the single given argument is a \Hash,
+ * returns a new \Hash populated with the entries from the given \Hash.
+ * h = {foo: 0, bar: 1, baz: 2}
+ * Hash[h] # => {:foo=>0, :bar=>1, :baz=>2}
*
- * The second and third form take a single argument which is either an array
- * of key-value pairs or an object convertible to a hash.
+ * When the single given argument is an \Array of 2-element Arrays,
+ * returns a new \Hash object wherein each 2-element array forms a key-value entry:
+ * Hash[ [ [:foo, 0], [:bar, 1] ] ] # => {:foo=>0, :bar=>1}
*
- * Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
- * Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
- * Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
+ * When the argument count is an even number;
+ * returns a new \Hash object wherein each successive pair of arguments
+ * has become a key-value entry:
+ * Hash[:foo, 0, :bar, 1] # => {:foo=>0, :bar=>1}
+ *
+ * Raises an exception if the argument list does not conform to any of the above.
*/
static VALUE
@@ -656,12 +1823,10 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
VALUE hash, tmp;
if (argc == 1) {
- tmp = rb_hash_s_try_convert(Qnil, argv[0]);
+ tmp = rb_hash_s_try_convert(Qnil, argv[0]);
if (!NIL_P(tmp)) {
hash = hash_alloc(klass);
- if (RHASH(tmp)->ntbl) {
- RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl);
- }
+ hash_copy(hash, tmp);
return hash;
}
@@ -676,17 +1841,8 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
VALUE key, val = Qnil;
if (NIL_P(v)) {
-#if 0 /* refix in the next release */
rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
rb_builtin_class_name(e), i);
-
-#else
- rb_warn("wrong element type %s at %ld (expected array)",
- rb_builtin_class_name(e), i);
- rb_warn("ignoring wrong elements is deprecated, remove them explicitly");
- rb_warn("this causes ArgumentError in the next release");
- continue;
-#endif
}
switch (RARRAY_LEN(v)) {
default:
@@ -708,15 +1864,16 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
hash = hash_alloc(klass);
rb_hash_bulk_insert(argc, argv, hash);
-
+ hash_verify(hash);
return hash;
}
-static VALUE
-to_hash(VALUE hash)
+MJIT_FUNC_EXPORTED VALUE
+rb_to_hash_type(VALUE hash)
{
return rb_convert_type_with_id(hash, T_HASH, "Hash", idTo_hash);
}
+#define to_hash rb_to_hash_type
VALUE
rb_check_hash_type(VALUE hash)
@@ -726,14 +1883,16 @@ rb_check_hash_type(VALUE hash)
/*
* call-seq:
- * Hash.try_convert(obj) -> hash or nil
+ * Hash.try_convert(obj) -> obj, new_hash, or nil
+ *
+ * If +obj+ is a \Hash object, returns +obj+.
*
- * Try to convert <i>obj</i> into a hash, using to_hash method.
- * Returns converted hash or nil if <i>obj</i> cannot be converted
- * for any reason.
+ * Otherwise if +obj+ responds to <tt>:to_hash</tt>,
+ * calls <tt>obj.to_hash</tt> and returns the result.
*
- * Hash.try_convert({1=>2}) # => {1=>2}
- * Hash.try_convert("1=>2") # => nil
+ * Returns +nil+ if +obj+ does not respond to <tt>:to_hash</tt>
+ *
+ * Raises an exception unless <tt>obj.to_hash</tt> returns a \Hash object.
*/
static VALUE
rb_hash_s_try_convert(VALUE dummy, VALUE hash)
@@ -741,6 +1900,52 @@ rb_hash_s_try_convert(VALUE dummy, VALUE hash)
return rb_check_hash_type(hash);
}
+/*
+ * call-seq:
+ * Hash.ruby2_keywords_hash?(hash) -> true or false
+ *
+ * Checks if a given hash is flagged by Module#ruby2_keywords (or
+ * Proc#ruby2_keywords).
+ * This method is not for casual use; debugging, researching, and
+ * some truly necessary cases like serialization of arguments.
+ *
+ * ruby2_keywords def foo(*args)
+ * Hash.ruby2_keywords_hash?(args.last)
+ * end
+ * foo(k: 1) #=> true
+ * foo({k: 1}) #=> false
+ */
+static VALUE
+rb_hash_s_ruby2_keywords_hash_p(VALUE dummy, VALUE hash)
+{
+ Check_Type(hash, T_HASH);
+ return (RHASH(hash)->basic.flags & RHASH_PASS_AS_KEYWORDS) ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq:
+ * Hash.ruby2_keywords_hash(hash) -> hash
+ *
+ * Duplicates a given hash and adds a ruby2_keywords flag.
+ * This method is not for casual use; debugging, researching, and
+ * some truly necessary cases like deserialization of arguments.
+ *
+ * h = {k: 1}
+ * h = Hash.ruby2_keywords_hash(h)
+ * def foo(k: 42)
+ * k
+ * end
+ * foo(*[h]) #=> 1 with neither a warning or an error
+ */
+static VALUE
+rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash)
+{
+ Check_Type(hash, T_HASH);
+ hash = rb_hash_dup(hash);
+ RHASH(hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
+ return hash;
+}
+
struct rehash_arg {
VALUE hash;
st_table *tbl;
@@ -749,30 +1954,25 @@ struct rehash_arg {
static int
rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
{
- st_table *tbl = (st_table *)arg;
-
- st_insert(tbl, (st_data_t)key, (st_data_t)value);
+ if (RHASH_AR_TABLE_P(arg)) {
+ ar_insert(arg, (st_data_t)key, (st_data_t)value);
+ }
+ else {
+ st_insert(RHASH_ST_TABLE(arg), (st_data_t)key, (st_data_t)value);
+ }
return ST_CONTINUE;
}
/*
* call-seq:
- * hsh.rehash -> hsh
- *
- * Rebuilds the hash based on the current hash values for each key. If
- * values of key objects have changed since they were inserted, this
- * method will reindex <i>hsh</i>. If <code>Hash#rehash</code> is
- * called while an iterator is traversing the hash, a
- * <code>RuntimeError</code> will be raised in the iterator.
- *
- * a = [ "a", "b" ]
- * c = [ "c", "d" ]
- * h = { a => 100, c => 300 }
- * h[a] #=> 100
- * a[0] = "z"
- * h[a] #=> nil
- * h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300}
- * h[a] #=> 100
+ * hash.rehash -> self
+ *
+ * Rebuilds the hash table by recomputing the hash index for each key;
+ * returns <tt>self</tt>.
+ *
+ * The hash table becomes invalid if the hash value of a key
+ * has changed after the entry was created.
+ * See {Modifying an Active Hash Key}[#class-Hash-label-Modifying+an+Active+Hash+Key].
*/
VALUE
@@ -785,46 +1985,80 @@ rb_hash_rehash(VALUE hash)
rb_raise(rb_eRuntimeError, "rehash during iteration");
}
rb_hash_modify_check(hash);
- if (!RHASH(hash)->ntbl)
- return hash;
- tmp = hash_alloc(0);
- tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries);
- RHASH(tmp)->ntbl = tbl;
-
- rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tbl);
- st_free_table(RHASH(hash)->ntbl);
- RHASH(hash)->ntbl = tbl;
- RHASH(tmp)->ntbl = 0;
-
+ if (RHASH_AR_TABLE_P(hash)) {
+ tmp = hash_alloc(0);
+ ar_alloc_table(tmp);
+ rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
+ ar_free_and_clear_table(hash);
+ ar_copy(hash, tmp);
+ ar_free_and_clear_table(tmp);
+ }
+ else if (RHASH_ST_TABLE_P(hash)) {
+ st_table *old_tab = RHASH_ST_TABLE(hash);
+ tmp = hash_alloc(0);
+ tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries);
+ RHASH_ST_TABLE_SET(tmp, tbl);
+ rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
+ st_free_table(old_tab);
+ RHASH_ST_TABLE_SET(hash, tbl);
+ RHASH_ST_CLEAR(tmp);
+ }
+ hash_verify(hash);
return hash;
}
+static VALUE
+call_default_proc(VALUE proc, VALUE hash, VALUE key)
+{
+ VALUE args[2] = {hash, key};
+ return rb_proc_call_with_block(proc, 2, args, Qnil);
+}
+
VALUE
rb_hash_default_value(VALUE hash, VALUE key)
{
- if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
+ if (LIKELY(rb_method_basic_definition_p(CLASS_OF(hash), id_default))) {
VALUE ifnone = RHASH_IFNONE(hash);
- if (!FL_TEST(hash, HASH_PROC_DEFAULT)) return ifnone;
+ if (!FL_TEST(hash, RHASH_PROC_DEFAULT)) return ifnone;
if (key == Qundef) return Qnil;
- return rb_funcall(ifnone, id_yield, 2, hash, key);
+ return call_default_proc(ifnone, hash, key);
}
else {
return rb_funcall(hash, id_default, 1, key);
}
}
+static inline int
+hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
+{
+ hash_verify(hash);
+
+ if (RHASH_AR_TABLE_P(hash)) {
+ return ar_lookup(hash, key, pval);
+ }
+ else {
+ return st_lookup(RHASH_ST_TABLE(hash), key, pval);
+ }
+}
+
+MJIT_FUNC_EXPORTED int
+rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
+{
+ return hash_stlike_lookup(hash, key, pval);
+}
+
/*
* call-seq:
- * hsh[key] -> value
- *
- * Element Reference---Retrieves the <i>value</i> object corresponding
- * to the <i>key</i> object. If not found, returns the default value (see
- * <code>Hash::new</code> for details).
+ * hash[key] -> value
*
- * h = { "a" => 100, "b" => 200 }
- * h["a"] #=> 100
- * h["c"] #=> nil
+ * Returns the value associated with the given +key+, if found:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h[:foo] # => 0
*
+ * If +key+ is not found, returns a default value
+ * (see {Default Values}[#class-Hash-label-Default+Values]):
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h[:nosuch] # => nil
*/
VALUE
@@ -832,10 +2066,12 @@ rb_hash_aref(VALUE hash, VALUE key)
{
st_data_t val;
- if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
- return rb_hash_default_value(hash, key);
+ if (hash_stlike_lookup(hash, key, &val)) {
+ return (VALUE)val;
+ }
+ else {
+ return rb_hash_default_value(hash, key);
}
- return (VALUE)val;
}
VALUE
@@ -843,10 +2079,12 @@ rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
{
st_data_t val;
- if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
- return def; /* without Hash#default */
+ if (hash_stlike_lookup(hash, key, &val)) {
+ return (VALUE)val;
+ }
+ else {
+ return def; /* without Hash#default */
}
- return (VALUE)val;
}
VALUE
@@ -857,31 +2095,26 @@ rb_hash_lookup(VALUE hash, VALUE key)
/*
* call-seq:
- * hsh.fetch(key [, default] ) -> obj
- * hsh.fetch(key) {| key | block } -> obj
- *
- * Returns a value from the hash for the given key. If the key can't be
- * found, there are several options: With no other arguments, it will
- * raise a <code>KeyError</code> exception; if <i>default</i> is given,
- * then that will be returned; if the optional code block is specified,
- * then that will be run and its result returned.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.fetch("a") #=> 100
- * h.fetch("z", "go fish") #=> "go fish"
- * h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
+ * hash.fetch(key) -> object
+ * hash.fetch(key, default_value) -> object
+ * hash.fetch(key) {|key| ... } -> object
*
- * The following example shows that an exception is raised if the key
- * is not found and a default value is not supplied.
+ * Returns the value for the given +key+, if found.
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.fetch(:bar) # => 1
*
- * h = { "a" => 100, "b" => 200 }
- * h.fetch("z")
+ * If +key+ is not found and no block was given,
+ * returns +default_value+:
+ * {}.fetch(:nosuch, :default) # => :default
+ * {}.fetch(:nosuch) # => nil
*
- * <em>produces:</em>
+ * If +key+ is not found and a block was given,
+ * yields +key+ to the block and returns the block's return value:
+ * {}.fetch(:nosuch) {|key| "No key #{key}"} # => "No key nosuch"
*
- * prog.rb:2:in `fetch': key not found (KeyError)
- * from prog.rb:2
+ * Raises KeyError if neither +default_value+ nor a block was given.
*
+ * Note that this method does not use the values of either #default or #default_proc.
*/
static VALUE
@@ -898,19 +2131,26 @@ rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
if (block_given && argc == 2) {
rb_warn("block supersedes default value argument");
}
- if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
- if (block_given) return rb_yield(key);
- if (argc == 1) {
- VALUE desc = rb_protect(rb_inspect, key, 0);
- if (NIL_P(desc)) {
- desc = rb_any_to_s(key);
- }
- desc = rb_str_ellipsize(desc, 65);
- rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
- }
- return argv[1];
+
+ if (hash_stlike_lookup(hash, key, &val)) {
+ return (VALUE)val;
+ }
+ else {
+ if (block_given) {
+ return rb_yield(key);
+ }
+ else if (argc == 1) {
+ VALUE desc = rb_protect(rb_inspect, key, 0);
+ if (NIL_P(desc)) {
+ desc = rb_any_to_s(key);
+ }
+ desc = rb_str_ellipsize(desc, 65);
+ rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
+ }
+ else {
+ return argv[1];
+ }
}
- return (VALUE)val;
}
VALUE
@@ -921,59 +2161,49 @@ rb_hash_fetch(VALUE hash, VALUE key)
/*
* call-seq:
- * hsh.default(key=nil) -> obj
- *
- * Returns the default value, the value that would be returned by
- * <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
- * See also <code>Hash::new</code> and <code>Hash#default=</code>.
- *
- * h = Hash.new #=> {}
- * h.default #=> nil
- * h.default(2) #=> nil
- *
- * h = Hash.new("cat") #=> {}
- * h.default #=> "cat"
- * h.default(2) #=> "cat"
- *
- * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {}
- * h.default #=> nil
- * h.default(2) #=> 20
+ * hash.default -> object
+ * hash.default(key) -> object
+ *
+ * Returns the default value for the given +key+.
+ * The returned value will be determined either by the default proc or by the default value.
+ * See {Default Values}[#class-Hash-label-Default+Values].
+ *
+ * With no argument, returns the current default value:
+ * h = {}
+ * h.default # => nil
+ *
+ * If +key+ is given, returns the default value for +key+,
+ * regardless of whether that key exists:
+ * h = Hash.new { |hash, key| hash[key] = "No key #{key}"}
+ * h[:foo] = "Hello"
+ * h.default(:foo) # => "No key foo"
*/
static VALUE
rb_hash_default(int argc, VALUE *argv, VALUE hash)
{
- VALUE args[2], ifnone;
+ VALUE ifnone;
rb_check_arity(argc, 0, 1);
ifnone = RHASH_IFNONE(hash);
- if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
+ if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
if (argc == 0) return Qnil;
- args[0] = hash;
- args[1] = argv[0];
- return rb_funcallv(ifnone, id_yield, 2, args);
+ return call_default_proc(ifnone, hash, argv[0]);
}
return ifnone;
}
/*
* call-seq:
- * hsh.default = obj -> obj
- *
- * Sets the default value, the value returned for a key that does not
- * exist in the hash. It is not possible to set the default to a
- * <code>Proc</code> that will be executed on each key lookup.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.default = "Go fish"
- * h["a"] #=> 100
- * h["z"] #=> "Go fish"
- * # This doesn't do what you might hope...
- * h.default = proc do |hash, key|
- * hash[key] = key + key
- * end
- * h[2] #=> #<Proc:0x401b3948@-:6>
- * h["cat"] #=> #<Proc:0x401b3948@-:6>
+ * hash.default = value -> object
+ *
+ * Sets the default value to +value+; returns +value+:
+ * h = {}
+ * h.default # => nil
+ * h.default = false # => false
+ * h.default # => false
+ *
+ * See {Default Values}[#class-Hash-label-Default+Values].
*/
static VALUE
@@ -986,23 +2216,20 @@ rb_hash_set_default(VALUE hash, VALUE ifnone)
/*
* call-seq:
- * hsh.default_proc -> anObject
- *
- * If <code>Hash::new</code> was invoked with a block, return that
- * block, otherwise return <code>nil</code>.
- *
- * h = Hash.new {|h,k| h[k] = k*k } #=> {}
- * p = h.default_proc #=> #<Proc:0x401b3d08@-:1>
- * a = [] #=> []
- * p.call(a, 2)
- * a #=> [nil, nil, 4]
+ * hash.default_proc -> proc or nil
+ *
+ * Returns the default proc for +self+
+ * (see {Default Values}[#class-Hash-label-Default+Values]):
+ * h = {}
+ * h.default_proc # => nil
+ * h.default_proc = proc {|hash, key| "Default value for #{key}" }
+ * h.default_proc.class # => Proc
*/
-
static VALUE
rb_hash_default_proc(VALUE hash)
{
- if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
+ if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
return RHASH_IFNONE(hash);
}
return Qnil;
@@ -1010,15 +2237,16 @@ rb_hash_default_proc(VALUE hash)
/*
* call-seq:
- * hsh.default_proc = proc_obj or nil
- *
- * Sets the default proc to be executed on each failed key lookup.
- *
- * h.default_proc = proc do |hash, key|
- * hash[key] = key + key
- * end
- * h[2] #=> 4
- * h["cat"] #=> "catcat"
+ * hash.default_proc = proc -> proc
+ *
+ * Sets the default proc for +self+ to +proc+:
+ * (see {Default Values}[#class-Hash-label-Default+Values]):
+ * h = {}
+ * h.default_proc # => nil
+ * h.default_proc = proc { |hash, key| "Default value for #{key}" }
+ * h.default_proc.class # => Proc
+ * h.default_proc = nil
+ * h.default_proc # => nil
*/
VALUE
@@ -1056,16 +2284,15 @@ key_i(VALUE key, VALUE value, VALUE arg)
/*
* call-seq:
- * hsh.key(value) -> key
+ * hash.key(value) -> key or nil
*
- * Returns the key of an occurrence of a given value. If the value is
- * not found, returns <code>nil</code>.
- *
- * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
- * h.key(200) #=> "b"
- * h.key(300) #=> "c"
- * h.key(999) #=> nil
+ * Returns the key for the first-found entry with the given +value+
+ * (see {Entry Order}[#class-Hash-label-Entry+Order]):
+ * h = {foo: 0, bar: 2, baz: 2}
+ * h.key(0) # => :foo
+ * h.key(2) # => :bar
*
+ * Returns +nil+ if so such value is found.
*/
static VALUE
@@ -1081,12 +2308,15 @@ rb_hash_key(VALUE hash, VALUE value)
return args[1];
}
-/* :nodoc: */
-static VALUE
-rb_hash_index(VALUE hash, VALUE value)
+int
+rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
{
- rb_warn("Hash#index is deprecated; use Hash#key");
- return rb_hash_key(hash, value);
+ if (RHASH_AR_TABLE_P(hash)) {
+ return ar_delete(hash, pkey, pval);
+ }
+ else {
+ return st_delete(RHASH_ST_TABLE(hash), pkey, pval);
+ }
}
/*
@@ -1099,14 +2329,11 @@ rb_hash_delete_entry(VALUE hash, VALUE key)
{
st_data_t ktmp = (st_data_t)key, val;
- if (!RHASH(hash)->ntbl) {
- return Qundef;
- }
- else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val)) {
- return (VALUE)val;
+ if (rb_hash_stlike_delete(hash, &ktmp, &val)) {
+ return (VALUE)val;
}
else {
- return Qundef;
+ return Qundef;
}
}
@@ -1130,20 +2357,29 @@ rb_hash_delete(VALUE hash, VALUE key)
/*
* call-seq:
- * hsh.delete(key) -> value
- * hsh.delete(key) {| key | block } -> value
+ * hash.delete(key) -> value or nil
+ * hash.delete(key) {|key| ... } -> object
*
- * Deletes the key-value pair and returns the value from <i>hsh</i> whose
- * key is equal to <i>key</i>. If the key is not found, it returns
- * <em>nil</em>. If the optional code block is given and the
- * key is not found, pass in the key and return the result of
- * <i>block</i>.
+ * Deletes the entry for the given +key+ and returns its associated value.
*
- * h = { "a" => 100, "b" => 200 }
- * h.delete("a") #=> 100
- * h.delete("z") #=> nil
- * h.delete("z") { |el| "#{el} not found" } #=> "z not found"
+ * If no block is given and +key+ is found, deletes the entry and returns the associated value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.delete(:bar) # => 1
+ * h # => {:foo=>0, :baz=>2}
*
+ * If no block given and +key+ is not found, returns +nil+.
+ *
+ * If a block is given and +key+ is found, ignores the block,
+ * deletes the entry, and returns the associated value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.delete(:baz) { |key| raise 'Will never happen'} # => 2
+ * h # => {:foo=>0, :bar=>1}
+ *
+ * If a block is given and +key+ is not found,
+ * calls the block and returns the block's return value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.delete(:nosuch) { |key| "Key #{key} not found" } # => "Key nosuch not found"
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
*/
static VALUE
@@ -1184,15 +2420,17 @@ shift_i_safe(VALUE key, VALUE value, VALUE arg)
/*
* call-seq:
- * hsh.shift -> anArray or obj
+ * hash.shift -> [key, value] or default_value
*
- * Removes a key-value pair from <i>hsh</i> and returns it as the
- * two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
- * the hash's default value if the hash is empty.
+ * Removes the first hash entry
+ * (see {Entry Order}[#class-Hash-label-Entry+Order]);
+ * returns a 2-element \Array containing the removed key and value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.shift # => [:foo, 0]
+ * h # => {:bar=>1, :baz=>2}
*
- * h = { 1 => "a", 2 => "b", 3 => "c" }
- * h.shift #=> [1, "a"]
- * h #=> {2=>"b", 3=>"c"}
+ * Returns the default value if the hash is empty
+ * (see {Default Values}[#class-Hash-label-Default+Values]).
*/
static VALUE
@@ -1201,14 +2439,29 @@ rb_hash_shift(VALUE hash)
struct shift_var var;
rb_hash_modify_check(hash);
- if (RHASH(hash)->ntbl) {
+ if (RHASH_AR_TABLE_P(hash)) {
var.key = Qundef;
if (RHASH_ITER_LEV(hash) == 0) {
- if (st_shift(RHASH(hash)->ntbl, &var.key, &var.val)) {
+ if (ar_shift(hash, &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val);
}
}
else {
+ rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
+ if (var.key != Qundef) {
+ rb_hash_delete_entry(hash, var.key);
+ return rb_assoc_new(var.key, var.val);
+ }
+ }
+ }
+ if (RHASH_ST_TABLE_P(hash)) {
+ var.key = Qundef;
+ if (RHASH_ITER_LEV(hash) == 0) {
+ if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
+ return rb_assoc_new(var.key, var.val);
+ }
+ }
+ else {
rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
if (var.key != Qundef) {
rb_hash_delete_entry(hash, var.key);
@@ -1223,6 +2476,7 @@ static int
delete_if_i(VALUE key, VALUE value, VALUE hash)
{
if (RTEST(rb_yield_values(2, key, value))) {
+ rb_hash_modify(hash);
return ST_DELETE;
}
return ST_CONTINUE;
@@ -1236,17 +2490,19 @@ hash_enum_size(VALUE hash, VALUE args, VALUE eobj)
/*
* call-seq:
- * hsh.delete_if {| key, value | block } -> hsh
- * hsh.delete_if -> an_enumerator
- *
- * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
- * evaluates to <code>true</code>.
- *
- * If no block is given, an enumerator is returned instead.
- *
- * h = { "a" => 100, "b" => 200, "c" => 300 }
- * h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
- *
+ * hash.delete_if {|key, value| ... } -> self
+ * hash.delete_if -> new_enumerator
+ *
+ * If a block given, calls the block with each key-value pair;
+ * deletes each entry for which the block returns a truthy value;
+ * returns +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.delete_if {|key, value| value > 0 } # => {:foo=>0}
+ *
+ * If no block given, returns a new \Enumerator:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.delete_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:delete_if>
+ * e.each { |key, value| value > 0 } # => {:foo=>0}
*/
VALUE
@@ -1254,18 +2510,28 @@ rb_hash_delete_if(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
rb_hash_modify_check(hash);
- if (RHASH(hash)->ntbl)
- rb_hash_foreach(hash, delete_if_i, hash);
+ if (!RHASH_TABLE_EMPTY_P(hash)) {
+ rb_hash_foreach(hash, delete_if_i, hash);
+ }
return hash;
}
/*
* call-seq:
- * hsh.reject! {| key, value | block } -> hsh or nil
- * hsh.reject! -> an_enumerator
+ * hash.reject! {|key, value| ... } -> self or nil
+ * hash.reject! -> new_enumerator
+ *
+ * Returns +self+, whose remaining entries are those
+ * for which the block returns +false+ or +nil+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.reject! {|key, value| value < 2 } # => {:baz=>2}
*
- * Equivalent to <code>Hash#delete_if</code>, but returns
- * <code>nil</code> if no changes were made.
+ * Returns +nil+ if no entries are removed.
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.reject! # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject!>
+ * e.each {|key, value| key.start_with?('b') } # => {:foo=>0}
*/
VALUE
@@ -1278,7 +2544,7 @@ rb_hash_reject_bang(VALUE hash)
n = RHASH_SIZE(hash);
if (!n) return Qnil;
rb_hash_foreach(hash, delete_if_i, hash);
- if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
+ if (n == RHASH_SIZE(hash)) return Qnil;
return hash;
}
@@ -1293,16 +2559,20 @@ reject_i(VALUE key, VALUE value, VALUE result)
/*
* call-seq:
- * hsh.reject {|key, value| block} -> a_hash
- * hsh.reject -> an_enumerator
- *
- * Returns a new hash consisting of entries for which the block returns false.
- *
- * If no block is given, an enumerator is returned instead.
- *
- * h = { "a" => 100, "b" => 200, "c" => 300 }
- * h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300}
- * h.reject {|k,v| v > 100} #=> {"a" => 100}
+ * hash.reject {|key, value| ... } -> new_hash
+ * hash.reject -> new_enumerator
+ *
+ * Returns a new \Hash object whose entries are all those
+ * from +self+ for which the block returns +false+ or +nil+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = h.reject {|key, value| key.start_with?('b') }
+ * h1 # => {:foo=>0}
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.reject # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject>
+ * h1 = e.each {|key, value| key.start_with?('b') }
+ * h1 # => {:foo=>0}
*/
VALUE
@@ -1325,14 +2595,76 @@ rb_hash_reject(VALUE hash)
}
/*
- * call-seq:
- * hsh.values_at(key, ...) -> array
+ * call-seq:
+ * hash.slice(*keys) -> new_hash
*
- * Return an array containing the values associated with the given keys.
- * Also see <code>Hash.select</code>.
+ * Returns a new \Hash object containing the entries for the given +keys+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.slice(:baz, :foo) # => {:baz=>2, :foo=>0}
*
- * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
- * h.values_at("cow", "cat") #=> ["bovine", "feline"]
+ * Any given +keys+ that are not found are ignored.
+ */
+
+static VALUE
+rb_hash_slice(int argc, VALUE *argv, VALUE hash)
+{
+ int i;
+ VALUE key, value, result;
+
+ if (argc == 0 || RHASH_EMPTY_P(hash)) {
+ return rb_hash_new();
+ }
+ result = rb_hash_new_with_size(argc);
+
+ for (i = 0; i < argc; i++) {
+ key = argv[i];
+ value = rb_hash_lookup2(hash, key, Qundef);
+ if (value != Qundef)
+ rb_hash_aset(result, key, value);
+ }
+
+ return result;
+}
+
+/*
+ * call-seq:
+ * hsh.except(*keys) -> a_hash
+ *
+ * Returns a new \Hash excluding entries for the given +keys+:
+ * h = { a: 100, b: 200, c: 300 }
+ * h.except(:a) #=> {:b=>200, :c=>300}
+ *
+ * Any given +keys+ that are not found are ignored.
+ */
+
+static VALUE
+rb_hash_except(int argc, VALUE *argv, VALUE hash)
+{
+ int i;
+ VALUE key, result;
+
+ result = hash_alloc(rb_cHash);
+ hash_copy(result, hash);
+
+ for (i = 0; i < argc; i++) {
+ key = argv[i];
+ rb_hash_delete(result, key);
+ }
+
+ return result;
+}
+
+/*
+ * call-seq:
+ * hash.values_at(*keys) -> new_array
+ *
+ * Returns a new \Array containing values for the given +keys+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.values_at(:baz, :foo) # => [2, 0]
+ *
+ * The {default values}[#class-Hash-label-Default+Values] are returned
+ * for any keys that are not found:
+ * h.values_at(:hello, :foo) # => [nil, 0]
*/
VALUE
@@ -1348,22 +2680,26 @@ rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
}
/*
- * call-seq:
- * hsh.fetch_values(key, ...) -> array
- * hsh.fetch_values(key, ...) { |key| block } -> array
+ * call-seq:
+ * hash.fetch_values(*keys) -> new_array
+ * hash.fetch_values(*keys) {|key| ... } -> new_array
*
- * Returns an array containing the values associated with the given keys
- * but also raises <code>KeyError</code> when one of keys can't be found.
- * Also see <code>Hash#values_at</code> and <code>Hash#fetch</code>.
+ * Returns a new \Array containing the values associated with the given keys *keys:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.fetch_values(:baz, :foo) # => [2, 0]
*
- * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
+ * Returns a new empty \Array if no arguments given.
*
- * h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
- * h.fetch_values("cow", "bird") # raises KeyError
- * h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
+ * When a block is given, calls the block with each missing key,
+ * treating the block's return value as the value for that key:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * values = h.fetch_values(:bar, :foo, :bad, :bam) {|key| key.to_s}
+ * values # => [1, 0, "bad", "bam"]
+ *
+ * When no block is given, raises an exception if any given key is not found.
*/
-VALUE
+static VALUE
rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
{
VALUE result = rb_ary_new2(argc);
@@ -1386,19 +2722,22 @@ select_i(VALUE key, VALUE value, VALUE result)
/*
* call-seq:
- * hsh.select {|key, value| block} -> a_hash
- * hsh.select -> an_enumerator
+ * hash.select {|key, value| ... } -> new_hash
+ * hash.select -> new_enumerator
*
- * Returns a new hash consisting of entries for which the block returns true.
+ * Hash#filter is an alias for Hash#select.
*
- * If no block is given, an enumerator is returned instead.
+ * Returns a new \Hash object whose entries are those for which the block returns a truthy value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.select {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
*
- * h = { "a" => 100, "b" => 200, "c" => 300 }
- * h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
- * h.select {|k,v| v < 200} #=> {"a" => 100}
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.select # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select>
+ * e.each {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
*/
-VALUE
+static VALUE
rb_hash_select(VALUE hash)
{
VALUE result;
@@ -1415,6 +2754,7 @@ static int
keep_if_i(VALUE key, VALUE value, VALUE hash)
{
if (!RTEST(rb_yield_values(2, key, value))) {
+ rb_hash_modify(hash);
return ST_DELETE;
}
return ST_CONTINUE;
@@ -1422,47 +2762,62 @@ keep_if_i(VALUE key, VALUE value, VALUE hash)
/*
* call-seq:
- * hsh.select! {| key, value | block } -> hsh or nil
- * hsh.select! -> an_enumerator
+ * hash.select! {|key, value| ... } -> self or nil
+ * hash.select! -> new_enumerator
*
- * Equivalent to <code>Hash#keep_if</code>, but returns
- * <code>nil</code> if no changes were made.
+ * Hash#filter! is an alias for Hash#select!.
+ *
+ * Returns +self+, whose entries are those for which the block returns a truthy value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.select! {|key, value| value < 2 } => {:foo=>0, :bar=>1}
+ *
+ * Returns +nil+ if no entries were removed.
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.select! # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select!>
+ * e.each { |key, value| value < 2 } # => {:foo=>0, :bar=>1}
*/
-VALUE
+static VALUE
rb_hash_select_bang(VALUE hash)
{
st_index_t n;
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
rb_hash_modify_check(hash);
- if (!RHASH(hash)->ntbl)
- return Qnil;
- n = RHASH(hash)->ntbl->num_entries;
+ n = RHASH_SIZE(hash);
+ if (!n) return Qnil;
rb_hash_foreach(hash, keep_if_i, hash);
- if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
+ if (n == RHASH_SIZE(hash)) return Qnil;
return hash;
}
/*
* call-seq:
- * hsh.keep_if {| key, value | block } -> hsh
- * hsh.keep_if -> an_enumerator
- *
- * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
- * evaluates to false.
- *
- * If no block is given, an enumerator is returned instead.
- *
+ * hash.keep_if {|key, value| ... } -> self
+ * hash.keep_if -> new_enumerator
+ *
+ * Calls the block for each key-value pair;
+ * retains the entry if the block returns a truthy value;
+ * otherwise deletes the entry; returns +self+.
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.keep_if { |key, value| key.start_with?('b') } # => {:bar=>1, :baz=>2}
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.keep_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:keep_if>
+ * e.each { |key, value| key.start_with?('b') } # => {:bar=>1, :baz=>2}
*/
-VALUE
+static VALUE
rb_hash_keep_if(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
rb_hash_modify_check(hash);
- if (RHASH(hash)->ntbl)
- rb_hash_foreach(hash, keep_if_i, hash);
+ if (!RHASH_TABLE_EMPTY_P(hash)) {
+ rb_hash_foreach(hash, keep_if_i, hash);
+ }
return hash;
}
@@ -1474,26 +2829,24 @@ clear_i(VALUE key, VALUE value, VALUE dummy)
/*
* call-seq:
- * hsh.clear -> hsh
- *
- * Removes all key-value pairs from <i>hsh</i>.
- *
- * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
- * h.clear #=> {}
+ * hash.clear -> self
*
+ * Removes all hash entries; returns +self+.
*/
VALUE
rb_hash_clear(VALUE hash)
{
rb_hash_modify_check(hash);
- if (!RHASH(hash)->ntbl)
- return hash;
- if (RHASH(hash)->ntbl->num_entries > 0) {
- if (RHASH_ITER_LEV(hash) > 0)
- rb_hash_foreach(hash, clear_i, 0);
- else
- st_clear(RHASH(hash)->ntbl);
+
+ if (RHASH_ITER_LEV(hash) > 0) {
+ rb_hash_foreach(hash, clear_i, 0);
+ }
+ else if (RHASH_AR_TABLE_P(hash)) {
+ ar_clear(hash);
+ }
+ else {
+ st_clear(RHASH_ST_TABLE(hash));
}
return hash;
@@ -1514,22 +2867,14 @@ hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
return ST_CONTINUE;
}
-static VALUE
-fstring_existing_str(VALUE str)
+VALUE
+rb_hash_key_str(VALUE key)
{
- st_data_t fstr;
- st_table *tbl = rb_vm_fstring_table();
-
- if (st_lookup(tbl, str, &fstr)) {
- if (rb_objspace_garbage_object_p(fstr)) {
- return rb_fstring(str);
- }
- else {
- return (VALUE)fstr;
- }
+ if (!RB_FL_ANY_RAW(key, FL_EXIVAR) && RBASIC_CLASS(key) == rb_cString) {
+ return rb_fstring(key);
}
else {
- return Qnil;
+ return rb_str_new_frozen(key);
}
}
@@ -1537,15 +2882,7 @@ static int
hash_aset_str(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
{
if (!existing && !RB_OBJ_FROZEN(*key)) {
- VALUE k;
-
- if (!RB_OBJ_TAINTED(*key) &&
- (k = fstring_existing_str(*key)) != Qnil) {
- *key = k;
- }
- else {
- *key = rb_str_new_frozen(*key);
- }
+ *key = rb_hash_key_str(*key);
}
return hash_aset(key, val, arg, existing);
}
@@ -1555,43 +2892,43 @@ NOINSERT_UPDATE_CALLBACK(hash_aset_str)
/*
* call-seq:
- * hsh[key] = value -> value
- * hsh.store(key, value) -> value
- *
- * == Element Assignment
- *
- * Associates the value given by +value+ with the key given by +key+.
- *
- * h = { "a" => 100, "b" => 200 }
- * h["a"] = 9
- * h["c"] = 4
- * h #=> {"a"=>9, "b"=>200, "c"=>4}
- * h.store("d", 42) #=> 42
- * h #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
- *
- * +key+ should not have its value changed while it is in use as a key (an
- * <tt>unfrozen String</tt> passed as a key will be duplicated and frozen).
- *
- * a = "a"
- * b = "b".freeze
- * h = { a => 100, b => 200 }
- * h.key(100).equal? a #=> false
- * h.key(200).equal? b #=> true
- *
+ * hash[key] = value -> value
+ * hash.store(key, value)
+ *
+ * Hash#store is an alias for Hash#[]=.
+
+ * Associates the given +value+ with the given +key+; returns +value+.
+ *
+ * If the given +key+ exists, replaces its value with the given +value+;
+ * the ordering is not affected
+ * (see {Entry Order}[#class-Hash-label-Entry+Order]):
+ * h = {foo: 0, bar: 1}
+ * h[:foo] = 2 # => 2
+ * h.store(:bar, 3) # => 3
+ * h # => {:foo=>2, :bar=>3}
+ *
+ * If +key+ does not exist, adds the +key+ and +value+;
+ * the new entry is last in the order
+ * (see {Entry Order}[#class-Hash-label-Entry+Order]):
+ * h = {foo: 0, bar: 1}
+ * h[:baz] = 2 # => 2
+ * h.store(:bat, 3) # => 3
+ * h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
*/
VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
int iter_lev = RHASH_ITER_LEV(hash);
- st_table *tbl = RHASH(hash)->ntbl;
rb_hash_modify(hash);
- if (!tbl) {
+
+ if (RHASH_TABLE_NULL_P(hash)) {
if (iter_lev > 0) no_new_key();
- tbl = hash_tbl(hash);
+ ar_alloc_table(hash);
}
- if (tbl->type == &identhash || rb_obj_class(key) != rb_cString) {
+
+ if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
}
else {
@@ -1600,86 +2937,63 @@ rb_hash_aset(VALUE hash, VALUE key, VALUE val)
return val;
}
-static int
-replace_i(VALUE key, VALUE val, VALUE hash)
-{
- rb_hash_aset(hash, key, val);
-
- return ST_CONTINUE;
-}
-
-/* :nodoc: */
-static VALUE
-rb_hash_initialize_copy(VALUE hash, VALUE hash2)
-{
- st_table *ntbl;
-
- rb_hash_modify_check(hash);
- hash2 = to_hash(hash2);
-
- Check_Type(hash2, T_HASH);
-
- if (hash == hash2) return hash;
-
- ntbl = RHASH(hash)->ntbl;
- if (RHASH(hash2)->ntbl) {
- if (ntbl) st_free_table(ntbl);
- RHASH(hash)->ntbl = st_copy(RHASH(hash2)->ntbl);
- if (RHASH(hash)->ntbl->num_entries)
- rb_hash_rehash(hash);
- }
- else if (ntbl) {
- st_clear(ntbl);
- }
-
- COPY_DEFAULT(hash, hash2);
-
- return hash;
-}
-
/*
* call-seq:
- * hsh.replace(other_hash) -> hsh
- *
- * Replaces the contents of <i>hsh</i> with the contents of
- * <i>other_hash</i>.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
+ * hash.replace(other_hash) -> self
*
+ * Replaces the entire contents of +self+ with the contents of +other_hash+;
+ * returns +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.replace({bat: 3, bam: 4}) # => {:bat=>3, :bam=>4}
*/
static VALUE
rb_hash_replace(VALUE hash, VALUE hash2)
{
- st_table *table2;
-
rb_hash_modify_check(hash);
if (hash == hash2) return hash;
+ if (RHASH_ITER_LEV(hash) > 0) {
+ rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
+ }
hash2 = to_hash(hash2);
COPY_DEFAULT(hash, hash2);
- table2 = RHASH(hash2)->ntbl;
+ if (RHASH_AR_TABLE_P(hash)) {
+ if (RHASH_AR_TABLE_P(hash2)) {
+ ar_clear(hash);
+ }
+ else {
+ ar_free_and_clear_table(hash);
+ RHASH_ST_TABLE_SET(hash, st_init_table_with_size(RHASH_TYPE(hash2), RHASH_SIZE(hash2)));
+ }
+ }
+ else {
+ if (RHASH_AR_TABLE_P(hash2)) {
+ st_free_table(RHASH_ST_TABLE(hash));
+ RHASH_ST_CLEAR(hash);
+ }
+ else {
+ st_clear(RHASH_ST_TABLE(hash));
+ RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type;
+ }
+ }
+ rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);
- rb_hash_clear(hash);
- if (table2) hash_tbl(hash)->type = table2->type;
- rb_hash_foreach(hash2, replace_i, hash);
+ rb_gc_writebarrier_remember(hash);
return hash;
}
/*
* call-seq:
- * hsh.length -> integer
- * hsh.size -> integer
+ * hash.length -> integer
+ * hash.size -> integer
*
- * Returns the number of key-value pairs in the hash.
+ * Returns the count of entries in +self+:
+ * {foo: 0, bar: 1, baz: 2}.length # => 3
*
- * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
- * h.length #=> 4
- * h.delete("a") #=> 200
- * h.length #=> 3
+ * Hash#length is an alias for Hash#size.
*/
VALUE
@@ -1688,15 +3002,19 @@ rb_hash_size(VALUE hash)
return INT2FIX(RHASH_SIZE(hash));
}
+size_t
+rb_hash_size_num(VALUE hash)
+{
+ return (long)RHASH_SIZE(hash);
+}
/*
* call-seq:
- * hsh.empty? -> true or false
- *
- * Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
- *
- * {}.empty? #=> true
+ * hash.empty? -> true or false
*
+ * Returns +true+ if there are no hash entries, +false+ otherwise:
+ * {}.empty? # => true
+ * {foo: 0, bar: 1, baz: 2}.empty? # => false
*/
static VALUE
@@ -1706,7 +3024,7 @@ rb_hash_empty_p(VALUE hash)
}
static int
-each_value_i(VALUE key, VALUE value)
+each_value_i(VALUE key, VALUE value, VALUE _)
{
rb_yield(value);
return ST_CONTINUE;
@@ -1714,21 +3032,26 @@ each_value_i(VALUE key, VALUE value)
/*
* call-seq:
- * hsh.each_value {| value | block } -> hsh
- * hsh.each_value -> an_enumerator
- *
- * Calls <i>block</i> once for each key in <i>hsh</i>, passing the
- * value as a parameter.
- *
- * If no block is given, an enumerator is returned instead.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.each_value {|value| puts value }
- *
- * <em>produces:</em>
- *
- * 100
- * 200
+ * hash.each_value {|value| ... } -> self
+ * hash.each_value -> new_enumerator
+ *
+ * Calls the given block with each value; returns +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.each_value {|value| puts value } # => {:foo=>0, :bar=>1, :baz=>2}
+ * Output:
+ * 0
+ * 1
+ * 2
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.each_value # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_value>
+ * h1 = e.each {|value| puts value }
+ * h1 # => {:foo=>0, :bar=>1, :baz=>2}
+ * Output:
+ * 0
+ * 1
+ * 2
*/
static VALUE
@@ -1740,7 +3063,7 @@ rb_hash_each_value(VALUE hash)
}
static int
-each_key_i(VALUE key, VALUE value)
+each_key_i(VALUE key, VALUE value, VALUE _)
{
rb_yield(key);
return ST_CONTINUE;
@@ -1748,21 +3071,26 @@ each_key_i(VALUE key, VALUE value)
/*
* call-seq:
- * hsh.each_key {| key | block } -> hsh
- * hsh.each_key -> an_enumerator
- *
- * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
- * as a parameter.
- *
- * If no block is given, an enumerator is returned instead.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.each_key {|key| puts key }
- *
- * <em>produces:</em>
- *
- * a
- * b
+ * hash.each_key {|key| ... } -> self
+ * hash.each_key -> new_enumerator
+ *
+ * Calls the given block with each key; returns +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.each_key {|key| puts key } # => {:foo=>0, :bar=>1, :baz=>2}
+ * Output:
+ * foo
+ * bar
+ * baz
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.each_key # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_key>
+ * h1 = e.each {|key| puts key }
+ * h1 # => {:foo=>0, :bar=>1, :baz=>2}
+ * Output:
+ * foo
+ * bar
+ * baz
*/
static VALUE
rb_hash_each_key(VALUE hash)
@@ -1773,14 +3101,14 @@ rb_hash_each_key(VALUE hash)
}
static int
-each_pair_i(VALUE key, VALUE value)
+each_pair_i(VALUE key, VALUE value, VALUE _)
{
rb_yield(rb_assoc_new(key, value));
return ST_CONTINUE;
}
static int
-each_pair_i_fast(VALUE key, VALUE value)
+each_pair_i_fast(VALUE key, VALUE value, VALUE _)
{
VALUE argv[2];
argv[0] = key;
@@ -1791,37 +3119,65 @@ each_pair_i_fast(VALUE key, VALUE value)
/*
* call-seq:
- * hsh.each {| key, value | block } -> hsh
- * hsh.each_pair {| key, value | block } -> hsh
- * hsh.each -> an_enumerator
- * hsh.each_pair -> an_enumerator
- *
- * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
- * pair as parameters.
- *
- * If no block is given, an enumerator is returned instead.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.each {|key, value| puts "#{key} is #{value}" }
- *
- * <em>produces:</em>
- *
- * a is 100
- * b is 200
- *
+ * hash.each {|key, value| ... } -> self
+ * hash.each_pair {|key, value| ... } -> self
+ * hash.each -> new_enumerator
+ * hash.each_pair -> new_enumerator
+ *
+ * Hash#each is an alias for Hash#each_pair.
+
+ * Calls the given block with each key-value pair; returns +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.each_pair {|key, value| puts "#{key}: #{value}"} # => {:foo=>0, :bar=>1, :baz=>2}
+ * Output:
+ * foo: 0
+ * bar: 1
+ * baz: 2
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.each_pair # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_pair>
+ * h1 = e.each {|key, value| puts "#{key}: #{value}"}
+ * h1 # => {:foo=>0, :bar=>1, :baz=>2}
+ * Output:
+ * foo: 0
+ * bar: 1
+ * baz: 2
*/
static VALUE
rb_hash_each_pair(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
- if (rb_block_arity() > 1)
+ if (rb_block_pair_yield_optimizable())
rb_hash_foreach(hash, each_pair_i_fast, 0);
else
rb_hash_foreach(hash, each_pair_i, 0);
return hash;
}
+struct transform_keys_args{
+ VALUE trans;
+ VALUE result;
+ int block_given;
+};
+
+static int
+transform_keys_hash_i(VALUE key, VALUE value, VALUE transarg)
+{
+ struct transform_keys_args *p = (void *)transarg;
+ VALUE trans = p->trans, result = p->result;
+ VALUE new_key = rb_hash_lookup2(trans, key, Qundef);
+ if (new_key == Qundef) {
+ if (p->block_given)
+ new_key = rb_yield(key);
+ else
+ new_key = key;
+ }
+ rb_hash_aset(result, new_key, value);
+ return ST_CONTINUE;
+}
+
static int
transform_keys_i(VALUE key, VALUE value, VALUE result)
{
@@ -1832,92 +3188,164 @@ transform_keys_i(VALUE key, VALUE value, VALUE result)
/*
* call-seq:
- * hsh.transform_keys {|key| block } -> new_hash
- * hsh.transform_keys -> an_enumerator
- *
- * Returns a new hash with the results of running the block once for
- * every key.
- * This method does not change the values.
- *
- * h = { a: 1, b: 2, c: 3 }
- * h.transform_keys {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
- * h.transform_keys(&:to_s) #=> { "a" => 1, "b" => 2, "c" => 3 }
- * h.transform_keys.with_index {|k, i| "#{k}.#{i}" }
- * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
- *
- * If no block is given, an enumerator is returned instead.
+ * hash.transform_keys {|key| ... } -> new_hash
+ * hash.transform_keys(hash2) -> new_hash
+ * hash.transform_keys(hash2) {|other_key| ...} -> new_hash
+ * hash.transform_keys -> new_enumerator
+ *
+ * Returns a new \Hash object; each entry has:
+ * * A key provided by the block.
+ * * The value from +self+.
+ *
+ * An optional hash argument can be provided to map keys to new keys.
+ * Any key not given will be mapped using the provided block,
+ * or remain the same if no block is given.
+ *
+ * Transform keys:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = h.transform_keys {|key| key.to_s }
+ * h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}
+ *
+ * h.transform_keys(foo: :bar, bar: :foo)
+ * #=> {bar: 0, foo: 1, baz: 2}
+ *
+ * h.transform_keys(foo: :hello, &:to_s)
+ * #=> {:hello=>0, "bar"=>1, "baz"=>2}
+ *
+ * Overwrites values for duplicate keys:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = h.transform_keys {|key| :bat }
+ * h1 # => {:bat=>2}
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.transform_keys # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_keys>
+ * h1 = e.each { |key| key.to_s }
+ * h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}
*/
static VALUE
-rb_hash_transform_keys(VALUE hash)
+rb_hash_transform_keys(int argc, VALUE *argv, VALUE hash)
{
VALUE result;
+ struct transform_keys_args transarg = {0};
- RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
+ argc = rb_check_arity(argc, 0, 1);
+ if (argc > 0) {
+ transarg.trans = to_hash(argv[0]);
+ transarg.block_given = rb_block_given_p();
+ }
+ else {
+ RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
+ }
result = rb_hash_new();
if (!RHASH_EMPTY_P(hash)) {
- rb_hash_foreach(hash, transform_keys_i, result);
+ if (transarg.trans) {
+ transarg.result = result;
+ rb_hash_foreach(hash, transform_keys_hash_i, (VALUE)&transarg);
+ }
+ else {
+ rb_hash_foreach(hash, transform_keys_i, result);
+ }
}
return result;
}
+static int flatten_i(VALUE key, VALUE val, VALUE ary);
+
/*
* call-seq:
- * hsh.transform_keys! {|key| block } -> hsh
- * hsh.transform_keys! -> an_enumerator
+ * hash.transform_keys! {|key| ... } -> self
+ * hash.transform_keys!(hash2) -> self
+ * hash.transform_keys!(hash2) {|other_key| ...} -> self
+ * hash.transform_keys! -> new_enumerator
*
- * Invokes the given block once for each key in <i>hsh</i>, replacing it
- * with the new key returned by the block, and then returns <i>hsh</i>.
- * This method does not change the values.
- *
- * h = { a: 1, b: 2, c: 3 }
- * h.transform_keys! {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
- * h.transform_keys!(&:to_sym) #=> { a: 1, b: 2, c: 3 }
- * h.transform_keys!.with_index {|k, i| "#{k}.#{i}" }
- * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
- *
- * If no block is given, an enumerator is returned instead.
+ * Same as Hash#transform_keys but modifies the receiver in place
+ * instead of returning a new hash.
*/
static VALUE
-rb_hash_transform_keys_bang(VALUE hash)
+rb_hash_transform_keys_bang(int argc, VALUE *argv, VALUE hash)
{
- RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
+ VALUE trans = 0;
+ int block_given = 0;
+
+ argc = rb_check_arity(argc, 0, 1);
+ if (argc > 0) {
+ trans = to_hash(argv[0]);
+ block_given = rb_block_given_p();
+ }
+ else {
+ RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
+ }
rb_hash_modify_check(hash);
- if (RHASH(hash)->ntbl) {
- long i;
- VALUE keys = rb_hash_keys(hash);
- for (i = 0; i < RARRAY_LEN(keys); ++i) {
- VALUE key = RARRAY_AREF(keys, i), new_key = rb_yield(key);
- rb_hash_aset(hash, new_key, rb_hash_delete(hash, key));
- }
+ if (!RHASH_TABLE_EMPTY_P(hash)) {
+ long i;
+ VALUE new_keys = hash_alloc(0);
+ VALUE pairs = rb_ary_tmp_new(RHASH_SIZE(hash) * 2);
+ rb_hash_foreach(hash, flatten_i, pairs);
+ for (i = 0; i < RARRAY_LEN(pairs); i += 2) {
+ VALUE key = RARRAY_AREF(pairs, i), new_key, val;
+
+ if (!trans) {
+ new_key = rb_yield(key);
+ }
+ else if ((new_key = rb_hash_lookup2(trans, key, Qundef)) != Qundef) {
+ /* use the transformed key */
+ }
+ else if (block_given) {
+ new_key = rb_yield(key);
+ }
+ else {
+ new_key = key;
+ }
+ val = RARRAY_AREF(pairs, i+1);
+ if (!hash_stlike_lookup(new_keys, key, NULL)) {
+ rb_hash_stlike_delete(hash, &key, NULL);
+ }
+ rb_hash_aset(hash, new_key, val);
+ rb_hash_aset(new_keys, new_key, Qnil);
+ }
+ rb_ary_clear(pairs);
+ rb_hash_clear(new_keys);
}
return hash;
}
static int
-transform_values_i(VALUE key, VALUE value, VALUE result)
+transform_values_foreach_func(st_data_t key, st_data_t value, st_data_t argp, int error)
{
- VALUE new_value = rb_yield(value);
- rb_hash_aset(result, key, new_value);
+ return ST_REPLACE;
+}
+
+static int
+transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
+{
+ VALUE new_value = rb_yield((VALUE)*value);
+ VALUE hash = (VALUE)argp;
+ rb_hash_modify(hash);
+ RB_OBJ_WRITE(hash, value, new_value);
return ST_CONTINUE;
}
/*
* call-seq:
- * hsh.transform_values {|value| block } -> new_hash
- * hsh.transform_values -> an_enumerator
- *
- * Returns a new hash with the results of running the block once for
- * every value.
- * This method does not change the keys.
- *
- * h = { a: 1, b: 2, c: 3 }
- * h.transform_values {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
- * h.transform_values(&:to_s) #=> { a: "1", b: "2", c: "3" }
- * h.transform_values.with_index {|v, i| "#{v}.#{i}" }
- * #=> { a: "1.0", b: "2.1", c: "3.2" }
- *
- * If no block is given, an enumerator is returned instead.
+ * hash.transform_values {|value| ... } -> new_hash
+ * hash.transform_values -> new_enumerator
+ *
+ * Returns a new \Hash object; each entry has:
+ * * A key from +self+.
+ * * A value provided by the block.
+ *
+ * Transform values:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = h.transform_values {|value| value * 100}
+ * h1 # => {:foo=>0, :bar=>100, :baz=>200}
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.transform_values # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_values>
+ * h1 = e.each { |value| value * 100}
+ * h1 # => {:foo=>0, :bar=>100, :baz=>200}
*/
static VALUE
rb_hash_transform_values(VALUE hash)
@@ -1925,9 +3353,11 @@ rb_hash_transform_values(VALUE hash)
VALUE result;
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
- result = rb_hash_new_with_size(RHASH_SIZE(hash));
+ result = hash_copy(hash_alloc(rb_cHash), hash);
+ SET_DEFAULT(result, Qnil);
+
if (!RHASH_EMPTY_P(hash)) {
- rb_hash_foreach(hash, transform_values_i, result);
+ rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, result);
}
return result;
@@ -1935,28 +3365,29 @@ rb_hash_transform_values(VALUE hash)
/*
* call-seq:
- * hsh.transform_values! {|value| block } -> hsh
- * hsh.transform_values! -> an_enumerator
- *
- * Invokes the given block once for each value in <i>hsh</i>, replacing it
- * with the new value returned by the block, and then returns <i>hsh</i>.
- * This method does not change the keys.
- *
- * h = { a: 1, b: 2, c: 3 }
- * h.transform_values! {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
- * h.transform_values!(&:to_s) #=> { a: "2", b: "5", c: "10" }
- * h.transform_values!.with_index {|v, i| "#{v}.#{i}" }
- * #=> { a: "2.0", b: "5.1", c: "10.2" }
- *
- * If no block is given, an enumerator is returned instead.
+ * hash.transform_values! {|value| ... } -> self
+ * hash.transform_values! -> new_enumerator
+ *
+ * Returns +self+, whose keys are unchanged, and whose values are determined by the given block.
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.transform_values! {|value| value * 100} # => {:foo=>0, :bar=>100, :baz=>200}
+ *
+ * Returns a new \Enumerator if no block given:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * e = h.transform_values! # => #<Enumerator: {:foo=>0, :bar=>100, :baz=>200}:transform_values!>
+ * h1 = e.each {|value| value * 100}
+ * h1 # => {:foo=>0, :bar=>100, :baz=>200}
*/
static VALUE
rb_hash_transform_values_bang(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
rb_hash_modify_check(hash);
- if (RHASH(hash)->ntbl)
- rb_hash_foreach(hash, transform_values_i, hash);
+
+ if (!RHASH_TABLE_EMPTY_P(hash)) {
+ rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash);
+ }
+
return hash;
}
@@ -1969,13 +3400,12 @@ to_a_i(VALUE key, VALUE value, VALUE ary)
/*
* call-seq:
- * hsh.to_a -> array
+ * hash.to_a -> new_array
*
- * Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
- * value</i> <code>]</code> arrays.
- *
- * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
- * h.to_a #=> [["c", 300], ["a", 100], ["d", 400]]
+ * Returns a new \Array of 2-element \Array objects;
+ * each nested \Array contains a key-value pair from +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.to_a # => [[:foo, 0], [:bar, 1], [:baz, 2]]
*/
static VALUE
@@ -1985,7 +3415,6 @@ rb_hash_to_a(VALUE hash)
ary = rb_ary_new_capa(RHASH_SIZE(hash));
rb_hash_foreach(hash, to_a_i, ary);
- OBJ_INFECT(ary, hash);
return ary;
}
@@ -2003,11 +3432,9 @@ inspect_i(VALUE key, VALUE value, VALUE str)
rb_enc_copy(str, str2);
}
rb_str_buf_append(str, str2);
- OBJ_INFECT(str, str2);
rb_str_buf_cat_ascii(str, "=>");
str2 = rb_inspect(value);
rb_str_buf_append(str, str2);
- OBJ_INFECT(str, str2);
return ST_CONTINUE;
}
@@ -2021,20 +3448,19 @@ inspect_hash(VALUE hash, VALUE dummy, int recur)
str = rb_str_buf_new2("{");
rb_hash_foreach(hash, inspect_i, str);
rb_str_buf_cat2(str, "}");
- OBJ_INFECT(str, hash);
return str;
}
/*
- * call-seq:
- * hsh.to_s -> string
- * hsh.inspect -> string
+ * call-seq:
+ * hash.inspect -> new_string
*
- * Return the contents of this hash as a string.
+ * Returns a new \String containing the hash entries:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.inspect # => "{:foo=>0, :bar=>1, :baz=>2}"
*
- * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
- * h.to_s #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
+ * Hash#to_s is an alias for Hash#inspect.
*/
static VALUE
@@ -2046,32 +3472,78 @@ rb_hash_inspect(VALUE hash)
}
/*
- * call-seq:
- * hsh.to_hash => hsh
+ * call-seq:
+ * hash.to_hash -> self
*
- * Returns +self+.
+ * Returns +self+.
*/
-
static VALUE
rb_hash_to_hash(VALUE hash)
{
return hash;
}
+VALUE
+rb_hash_set_pair(VALUE hash, VALUE arg)
+{
+ VALUE pair;
+
+ pair = rb_check_array_type(arg);
+ if (NIL_P(pair)) {
+ rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
+ rb_builtin_class_name(arg));
+ }
+ if (RARRAY_LEN(pair) != 2) {
+ rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
+ RARRAY_LEN(pair));
+ }
+ rb_hash_aset(hash, RARRAY_AREF(pair, 0), RARRAY_AREF(pair, 1));
+ return hash;
+}
+
+static int
+to_h_i(VALUE key, VALUE value, VALUE hash)
+{
+ rb_hash_set_pair(hash, rb_yield_values(2, key, value));
+ return ST_CONTINUE;
+}
+
+static VALUE
+rb_hash_to_h_block(VALUE hash)
+{
+ VALUE h = rb_hash_new_with_size(RHASH_SIZE(hash));
+ rb_hash_foreach(hash, to_h_i, h);
+ return h;
+}
+
/*
* call-seq:
- * hsh.to_h -> hsh or new_hash
+ * hash.to_h -> self or new_hash
+ * hash.to_h {|key, value| ... } -> new_hash
+ *
+ * For an instance of \Hash, returns +self+.
+ *
+ * For a subclass of \Hash, returns a new \Hash
+ * containing the content of +self+.
*
- * Returns +self+. If called on a subclass of Hash, converts
- * the receiver to a Hash object.
+ * When a block is given, returns a new \Hash object
+ * whose content is based on the block;
+ * the block should return a 2-element \Array object
+ * specifying the key-value pair to be included in the returned \Array:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = h.to_h {|key, value| [value, key] }
+ * h1 # => {0=>:foo, 1=>:bar, 2=>:baz}
*/
static VALUE
rb_hash_to_h(VALUE hash)
{
+ if (rb_block_given_p()) {
+ return rb_hash_to_h_block(hash);
+ }
if (rb_obj_class(hash) != rb_cHash) {
const VALUE flags = RBASIC(hash)->flags;
- hash = hash_dup(hash, rb_cHash, flags & HASH_PROC_DEFAULT);
+ hash = hash_dup(hash, rb_cHash, flags & RHASH_PROC_DEFAULT);
}
return hash;
}
@@ -2085,32 +3557,32 @@ keys_i(VALUE key, VALUE value, VALUE ary)
/*
* call-seq:
- * hsh.keys -> array
- *
- * Returns a new array populated with the keys from this hash. See also
- * <code>Hash#values</code>.
- *
- * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
- * h.keys #=> ["a", "b", "c", "d"]
+ * hash.keys -> new_array
*
+ * Returns a new \Array containing all keys in +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.keys # => [:foo, :bar, :baz]
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_keys(VALUE hash)
{
- VALUE keys;
st_index_t size = RHASH_SIZE(hash);
+ VALUE keys = rb_ary_new_capa(size);
- keys = rb_ary_new_capa(size);
if (size == 0) return keys;
if (ST_DATA_COMPATIBLE_P(VALUE)) {
- st_table *table = RHASH(hash)->ntbl;
-
- rb_gc_writebarrier_remember(keys);
- RARRAY_PTR_USE(keys, ptr, {
- size = st_keys(table, ptr, size);
- });
+ RARRAY_PTR_USE_TRANSIENT(keys, ptr, {
+ if (RHASH_AR_TABLE_P(hash)) {
+ size = ar_keys(hash, ptr, size);
+ }
+ else {
+ st_table *table = RHASH_ST_TABLE(hash);
+ size = st_keys(table, ptr, size);
+ }
+ });
+ rb_gc_writebarrier_remember(keys);
rb_ary_set_len(keys, size);
}
else {
@@ -2129,14 +3601,11 @@ values_i(VALUE key, VALUE value, VALUE ary)
/*
* call-seq:
- * hsh.values -> array
- *
- * Returns a new array populated with the values from <i>hsh</i>. See
- * also <code>Hash#keys</code>.
- *
- * h = { "a" => 100, "b" => 200, "c" => 300 }
- * h.values #=> [100, 200, 300]
+ * hash.values -> new_array
*
+ * Returns a new \Array containing all values in +self+:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.values # => [0, 1, 2]
*/
VALUE
@@ -2149,14 +3618,22 @@ rb_hash_values(VALUE hash)
if (size == 0) return values;
if (ST_DATA_COMPATIBLE_P(VALUE)) {
- st_table *table = RHASH(hash)->ntbl;
-
- rb_gc_writebarrier_remember(values);
- RARRAY_PTR_USE(values, ptr, {
- size = st_values(table, ptr, size);
- });
+ if (RHASH_AR_TABLE_P(hash)) {
+ rb_gc_writebarrier_remember(values);
+ RARRAY_PTR_USE_TRANSIENT(values, ptr, {
+ size = ar_values(hash, ptr, size);
+ });
+ }
+ else if (RHASH_ST_TABLE_P(hash)) {
+ st_table *table = RHASH_ST_TABLE(hash);
+ rb_gc_writebarrier_remember(values);
+ RARRAY_PTR_USE_TRANSIENT(values, ptr, {
+ size = st_values(table, ptr, size);
+ });
+ }
rb_ary_set_len(values, size);
}
+
else {
rb_hash_foreach(hash, values_i, values);
}
@@ -2166,32 +3643,25 @@ rb_hash_values(VALUE hash)
/*
* call-seq:
- * hsh.has_key?(key) -> true or false
- * hsh.include?(key) -> true or false
- * hsh.key?(key) -> true or false
- * hsh.member?(key) -> true or false
- *
- * Returns <code>true</code> if the given key is present in <i>hsh</i>.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.has_key?("a") #=> true
- * h.has_key?("z") #=> false
- *
- * Note that <code>include?</code> and <code>member?</code> do not test member
- * equality using <code>==</code> as do other Enumerables.
+ * hash.include?(key) -> true or false
+ * hash.has_key?(key) -> true or false
+ * hash.key?(key) -> true or false
+ * hash.member?(key) -> true or false
+
+ * Methods #has_key?, #key?, and #member? are aliases for \#include?.
*
- * See also Enumerable#include?
+ * Returns +true+ if +key+ is a key in +self+, otherwise +false+.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
- if (!RHASH(hash)->ntbl)
+ if (hash_stlike_lookup(hash, key, NULL)) {
+ return Qtrue;
+ }
+ else {
return Qfalse;
- if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
- return Qtrue;
}
- return Qfalse;
}
static int
@@ -2208,15 +3678,9 @@ rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
/*
* call-seq:
- * hsh.has_value?(value) -> true or false
- * hsh.value?(value) -> true or false
+ * hash.has_value?(value) -> true or false
*
- * Returns <code>true</code> if the given value is present for some key
- * in <i>hsh</i>.
- *
- * h = { "a" => 100, "b" => 200 }
- * h.value?(100) #=> true
- * h.value?(999) #=> false
+ * Returns +true+ if +value+ is a value in +self+, otherwise +false+.
*/
static VALUE
@@ -2232,7 +3696,7 @@ rb_hash_has_value(VALUE hash, VALUE val)
struct equal_data {
VALUE result;
- st_table *tbl;
+ VALUE hash;
int eql;
};
@@ -2242,15 +3706,17 @@ eql_i(VALUE key, VALUE val1, VALUE arg)
struct equal_data *data = (struct equal_data *)arg;
st_data_t val2;
- if (!st_lookup(data->tbl, key, &val2)) {
- data->result = Qfalse;
- return ST_STOP;
+ if (!hash_stlike_lookup(data->hash, key, &val2)) {
+ data->result = Qfalse;
+ return ST_STOP;
}
- if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
- data->result = Qfalse;
- return ST_STOP;
+ else {
+ if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
+ data->result = Qfalse;
+ return ST_STOP;
+ }
+ return ST_CONTINUE;
}
- return ST_CONTINUE;
}
static VALUE
@@ -2290,44 +3756,42 @@ hash_equal(VALUE hash1, VALUE hash2, int eql)
}
if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
return Qfalse;
- if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl)
- return Qtrue;
- if (RHASH(hash1)->ntbl->type != RHASH(hash2)->ntbl->type)
- return Qfalse;
+ if (!RHASH_TABLE_EMPTY_P(hash1) && !RHASH_TABLE_EMPTY_P(hash2)) {
+ if (RHASH_TYPE(hash1) != RHASH_TYPE(hash2)) {
+ return Qfalse;
+ }
+ else {
+ data.hash = hash2;
+ data.eql = eql;
+ return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
+ }
+ }
+
#if 0
if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
- FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
+ FL_TEST(hash1, RHASH_PROC_DEFAULT) == FL_TEST(hash2, RHASH_PROC_DEFAULT)))
return Qfalse;
#endif
-
- data.tbl = RHASH(hash2)->ntbl;
- data.eql = eql;
- return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
+ return Qtrue;
}
/*
* call-seq:
- * hsh == other_hash -> true or false
- *
- * Equality---Two hashes are equal if they each contain the same number
- * of keys and if each key-value pair is equal to (according to
- * <code>Object#==</code>) the corresponding elements in the other
- * hash.
+ * hash == object -> true or false
*
- * h1 = { "a" => 1, "c" => 2 }
- * h2 = { 7 => 35, "c" => 2, "a" => 1 }
- * h3 = { "a" => 1, "c" => 2, 7 => 35 }
- * h4 = { "a" => 1, "d" => 2, "f" => 35 }
- * h1 == h2 #=> false
- * h2 == h3 #=> true
- * h3 == h4 #=> false
+ * Returns +true+ if all of the following are true:
+ * * +object+ is a \Hash object.
+ * * +hash+ and +object+ have the same keys (regardless of order).
+ * * For each key +key+, <tt>hash[key] == object[key]</tt>.
*
- * The orders of each hashes are not compared.
- *
- * h1 = { "a" => 1, "c" => 2 }
- * h2 = { "c" => 2, "a" => 1 }
- * h1 == h2 #=> true
+ * Otherwise, returns +false+.
*
+ * Equal:
+ * h1 = {foo: 0, bar: 1, baz: 2}
+ * h2 = {foo: 0, bar: 1, baz: 2}
+ * h1 == h2 # => true
+ * h3 = {baz: 2, bar: 1, foo: 0}
+ * h1 == h3 # => true
*/
static VALUE
@@ -2338,11 +3802,21 @@ rb_hash_equal(VALUE hash1, VALUE hash2)
/*
* call-seq:
- * hash.eql?(other) -> true or false
+ * hash.eql? object -> true or false
+ *
+ * Returns +true+ if all of the following are true:
+ * * +object+ is a \Hash object.
+ * * +hash+ and +object+ have the same keys (regardless of order).
+ * * For each key +key+, <tt>h[key] eql? object[key]</tt>.
+ *
+ * Otherwise, returns +false+.
*
- * Returns <code>true</code> if <i>hash</i> and <i>other</i> are
- * both hashes with the same content.
- * The orders of each hashes are not compared.
+ * Equal:
+ * h1 = {foo: 0, bar: 1, baz: 2}
+ * h2 = {foo: 0, bar: 1, baz: 2}
+ * h1.eql? h2 # => true
+ * h3 = {baz: 2, bar: 1, foo: 0}
+ * h1.eql? h3 # => true
*/
static VALUE
@@ -2365,12 +3839,16 @@ hash_i(VALUE key, VALUE val, VALUE arg)
/*
* call-seq:
- * hsh.hash -> integer
+ * hash.hash -> an_integer
*
- * Compute a hash-code for this hash. Two hashes with the same content
- * will have the same hash code (and will compare using <code>eql?</code>).
+ * Returns the \Integer hash-code for the hash.
*
- * See also Object#hash.
+ * Two \Hash objects have the same hash-code if their content is the same
+ * (regardless or order):
+ * h1 = {foo: 0, bar: 1, baz: 2}
+ * h2 = {baz: 2, bar: 1, foo: 0}
+ * h2.hash == h1.hash # => true
+ * h2.eql? h1 # => true
*/
static VALUE
@@ -2395,32 +3873,17 @@ rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
/*
* call-seq:
- * hsh.invert -> new_hash
- *
- * Returns a new hash created by using <i>hsh</i>'s values as keys, and
- * the keys as values.
- * If a key with the same value already exists in the <i>hsh</i>, then
- * the last one defined will be used, the earlier value(s) will be discarded.
- *
- * h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
- * h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
+ * hash.invert -> new_hash
*
- * If there is no key with the same value, Hash#invert is involutive.
- *
- * h = { a: 1, b: 3, c: 4 }
- * h.invert.invert == h #=> true
- *
- * The condition, no key with the same value, can be tested by comparing
- * the size of inverted hash.
- *
- * # no key with the same value
- * h = { a: 1, b: 3, c: 4 }
- * h.size == h.invert.size #=> true
- *
- * # two (or more) keys has the same value
- * h = { a: 1, b: 3, c: 1 }
- * h.size == h.invert.size #=> false
+ * Returns a new \Hash object with the each key-value pair inverted:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = h.invert
+ * h1 # => {0=>:foo, 1=>:bar, 2=>:baz}
*
+ * Overwrites any repeated new keys:
+ * (see {Entry Order}[#class-Hash-label-Entry+Order]):
+ * h = {foo: 0, bar: 0, baz: 0}
+ * h.invert # => {0=>:baz}
*/
static VALUE
@@ -2484,39 +3947,71 @@ rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
/*
* call-seq:
- * hsh.merge!(other_hash) -> hsh
- * hsh.update(other_hash) -> hsh
- * hsh.merge!(other_hash){|key, oldval, newval| block} -> hsh
- * hsh.update(other_hash){|key, oldval, newval| block} -> hsh
- *
- * Adds the contents of _other_hash_ to _hsh_. If no block is specified,
- * entries with duplicate keys are overwritten with the values from
- * _other_hash_, otherwise the value of each duplicate key is determined by
- * calling the block with the key, its value in _hsh_ and its value in
- * _other_hash_.
- *
- * h1 = { "a" => 100, "b" => 200 }
- * h2 = { "b" => 254, "c" => 300 }
- * h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
- *
- * h1 = { "a" => 100, "b" => 200 }
- * h2 = { "b" => 254, "c" => 300 }
- * h1.merge!(h2) { |key, v1, v2| v1 }
- * #=> {"a"=>100, "b"=>200, "c"=>300}
+ * hash.merge! -> self
+ * hash.merge!(*other_hashes) -> self
+ * hash.merge!(*other_hashes) { |key, old_value, new_value| ... } -> self
+ *
+ * Merges each of +other_hashes+ into +self+; returns +self+.
+ *
+ * Each argument in +other_hashes+ must be a \Hash.
+ *
+ * \Method #update is an alias for \#merge!.
+ *
+ * With arguments and no block:
+ * * Returns +self+, after the given hashes are merged into it.
+ * * The given hashes are merged left to right.
+ * * Each new entry is added at the end.
+ * * Each duplicate-key entry's value overwrites the previous value.
+ *
+ * Example:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = {bat: 3, bar: 4}
+ * h2 = {bam: 5, bat:6}
+ * h.merge!(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}
+ *
+ * With arguments and a block:
+ * * Returns +self+, after the given hashes are merged.
+ * * The given hashes are merged left to right.
+ * * Each new-key entry is added at the end.
+ * * For each duplicate key:
+ * * Calls the block with the key and the old and new values.
+ * * The block's return value becomes the new value for the entry.
+ *
+ * Example:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = {bat: 3, bar: 4}
+ * h2 = {bam: 5, bat:6}
+ * h3 = h.merge!(h1, h2) { |key, old_value, new_value| old_value + new_value }
+ * h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}
+ *
+ * With no arguments:
+ * * Returns +self+, unmodified.
+ * * The block, if given, is ignored.
+ *
+ * Example:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.merge # => {:foo=>0, :bar=>1, :baz=>2}
+ * h1 = h.merge! { |key, old_value, new_value| raise 'Cannot happen' }
+ * h1 # => {:foo=>0, :bar=>1, :baz=>2}
*/
static VALUE
-rb_hash_update(VALUE hash1, VALUE hash2)
+rb_hash_update(int argc, VALUE *argv, VALUE self)
{
- rb_hash_modify(hash1);
- hash2 = to_hash(hash2);
- if (rb_block_given_p()) {
- rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
- }
- else {
- rb_hash_foreach(hash2, rb_hash_update_i, hash1);
+ int i;
+ bool block_given = rb_block_given_p();
+
+ rb_hash_modify(self);
+ for (i = 0; i < argc; i++){
+ VALUE hash = to_hash(argv[i]);
+ if (block_given) {
+ rb_hash_foreach(hash, rb_hash_update_block_i, self);
+ }
+ else {
+ rb_hash_foreach(hash, rb_hash_update_i, self);
+ }
}
- return hash1;
+ return self;
}
struct update_func_arg {
@@ -2575,28 +4070,59 @@ rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
/*
* call-seq:
- * hsh.merge(other_hash) -> new_hash
- * hsh.merge(other_hash){|key, oldval, newval| block} -> new_hash
- *
- * Returns a new hash containing the contents of <i>other_hash</i> and
- * the contents of <i>hsh</i>. If no block is specified, the value for
- * entries with duplicate keys will be that of <i>other_hash</i>. Otherwise
- * the value for each duplicate key is determined by calling the block
- * with the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
- *
- * h1 = { "a" => 100, "b" => 200 }
- * h2 = { "b" => 254, "c" => 300 }
- * h1.merge(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
- * h1.merge(h2){|key, oldval, newval| newval - oldval}
- * #=> {"a"=>100, "b"=>54, "c"=>300}
- * h1 #=> {"a"=>100, "b"=>200}
- *
+ * hash.merge -> copy_of_self
+ * hash.merge(*other_hashes) -> new_hash
+ * hash.merge(*other_hashes) { |key, old_value, new_value| ... } -> new_hash
+ *
+ * Returns the new \Hash formed by merging each of +other_hashes+
+ * into a copy of +self+.
+ *
+ * Each argument in +other_hashes+ must be a \Hash.
+ *
+ * ---
+ *
+ * With arguments and no block:
+ * * Returns the new \Hash object formed by merging each successive
+ * \Hash in +other_hashes+ into +self+.
+ * * Each new-key entry is added at the end.
+ * * Each duplicate-key entry's value overwrites the previous value.
+ *
+ * Example:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = {bat: 3, bar: 4}
+ * h2 = {bam: 5, bat:6}
+ * h.merge(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}
+ *
+ * With arguments and a block:
+ * * Returns a new \Hash object that is the merge of +self+ and each given hash.
+ * * The given hashes are merged left to right.
+ * * Each new-key entry is added at the end.
+ * * For each duplicate key:
+ * * Calls the block with the key and the old and new values.
+ * * The block's return value becomes the new value for the entry.
+ *
+ * Example:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h1 = {bat: 3, bar: 4}
+ * h2 = {bam: 5, bat:6}
+ * h3 = h.merge(h1, h2) { |key, old_value, new_value| old_value + new_value }
+ * h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}
+ *
+ * With no arguments:
+ * * Returns a copy of +self+.
+ * * The block, if given, is ignored.
+ *
+ * Example:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.merge # => {:foo=>0, :bar=>1, :baz=>2}
+ * h1 = h.merge { |key, old_value, new_value| raise 'Cannot happen' }
+ * h1 # => {:foo=>0, :bar=>1, :baz=>2}
*/
static VALUE
-rb_hash_merge(VALUE hash1, VALUE hash2)
+rb_hash_merge(int argc, VALUE *argv, VALUE self)
{
- return rb_hash_update(rb_hash_dup(hash1), hash2);
+ return rb_hash_update(argc, argv, rb_hash_dup(self));
}
static int
@@ -2621,7 +4147,8 @@ static VALUE
reset_hash_type(VALUE arg)
{
struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
- RHASH(p->hash)->ntbl->type = p->orighash;
+ HASH_ASSERT(RHASH_ST_TABLE_P(p->hash));
+ RHASH_ST_TABLE(p->hash)->type = p->orighash;
return Qundef;
}
@@ -2639,16 +4166,13 @@ assoc_i(VALUE key, VALUE val, VALUE arg)
/*
* call-seq:
- * hash.assoc(obj) -> an_array or nil
+ * hash.assoc(key) -> new_array or nil
*
- * Searches through the hash comparing _obj_ with the key using <code>==</code>.
- * Returns the key-value pair (two elements array) or +nil+
- * if no match is found. See <code>Array#assoc</code>.
+ * If the given +key+ is found, returns a 2-element \Array containing that key and its value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.assoc(:bar) # => [:bar, 1]
*
- * h = {"colors" => ["red", "blue", "green"],
- * "letters" => ["a", "b", "c" ]}
- * h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
- * h.assoc("foo") #=> nil
+ * Returns +nil+ if key +key+ is not found.
*/
VALUE
@@ -2659,7 +4183,10 @@ rb_hash_assoc(VALUE hash, VALUE key)
VALUE args[2];
if (RHASH_EMPTY_P(hash)) return Qnil;
- table = RHASH(hash)->ntbl;
+
+ ar_force_convert_table(hash, __FILE__, __LINE__);
+ HASH_ASSERT(RHASH_ST_TABLE_P(hash));
+ table = RHASH_ST_TABLE(hash);
orighash = table->type;
if (orighash != &identhash) {
@@ -2669,7 +4196,7 @@ rb_hash_assoc(VALUE hash, VALUE key)
assochash.compare = assoc_cmp;
assochash.hash = orighash->hash;
- table->type = &assochash;
+ table->type = &assochash;
args[0] = hash;
args[1] = key;
ensure_arg.hash = hash;
@@ -2698,15 +4225,15 @@ rassoc_i(VALUE key, VALUE val, VALUE arg)
/*
* call-seq:
- * hash.rassoc(obj) -> an_array or nil
+ * hash.rassoc(value) -> new_array or nil
*
- * Searches through the hash comparing _obj_ with the value using <code>==</code>.
- * Returns the first key-value pair (two-element array) that matches. See
- * also <code>Array#rassoc</code>.
+ * Returns a new 2-element \Array consisting of the key and value
+ * of the first-found entry whose value is <tt>==</tt> to value
+ * (see {Entry Order}[#class-Hash-label-Entry+Order]):
+ * h = {foo: 0, bar: 1, baz: 1}
+ * h.rassoc(1) # => [:bar, 1]
*
- * a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
- * a.rassoc("two") #=> [2, "two"]
- * a.rassoc("four") #=> nil
+ * Returns +nil+ if no such value found.
*/
VALUE
@@ -2734,18 +4261,33 @@ flatten_i(VALUE key, VALUE val, VALUE ary)
/*
* call-seq:
- * hash.flatten -> an_array
- * hash.flatten(level) -> an_array
- *
- * Returns a new array that is a one-dimensional flattening of this
- * hash. That is, for every key or value that is an array, extract
- * its elements into the new array. Unlike Array#flatten, this
- * method does not flatten recursively by default. The optional
- * <i>level</i> argument determines the level of recursion to flatten.
- *
- * a = {1=> "one", 2 => [2,"two"], 3 => "three"}
- * a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
- * a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
+ * hash.flatten -> new_array
+ * hash.flatten(level) -> new_array
+ *
+ * Returns a new \Array object that is a 1-dimensional flattening of +self+.
+ *
+ * ---
+ *
+ * By default, nested Arrays are not flattened:
+ * h = {foo: 0, bar: [:bat, 3], baz: 2}
+ * h.flatten # => [:foo, 0, :bar, [:bat, 3], :baz, 2]
+ *
+ * Takes the depth of recursive flattening from \Integer argument +level+:
+ * h = {foo: 0, bar: [:bat, [:baz, [:bat, ]]]}
+ * h.flatten(1) # => [:foo, 0, :bar, [:bat, [:baz, [:bat]]]]
+ * h.flatten(2) # => [:foo, 0, :bar, :bat, [:baz, [:bat]]]
+ * h.flatten(3) # => [:foo, 0, :bar, :bat, :baz, [:bat]]
+ * h.flatten(4) # => [:foo, 0, :bar, :bat, :baz, :bat]
+ *
+ * When +level+ is negative, flattens all nested Arrays:
+ * h = {foo: 0, bar: [:bat, [:baz, [:bat, ]]]}
+ * h.flatten(-1) # => [:foo, 0, :bar, :bat, :baz, :bat]
+ * h.flatten(-2) # => [:foo, 0, :bar, :bat, :baz, :bat]
+ *
+ * When +level+ is zero, returns the equivalent of #to_a :
+ * h = {foo: 0, bar: [:bat, 3], baz: 2}
+ * h.flatten(0) # => [[:foo, 0], [:bar, [:bat, 3]], [:baz, 2]]
+ * h.flatten(0) == h.to_a # => true
*/
static VALUE
@@ -2753,17 +4295,23 @@ rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
{
VALUE ary;
+ rb_check_arity(argc, 0, 1);
+
if (argc) {
- int level = NUM2INT(*argv);
+ int level = NUM2INT(argv[0]);
+
if (level == 0) return rb_hash_to_a(hash);
ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
rb_hash_foreach(hash, flatten_i, ary);
- if (level - 1 > 0) {
- *argv = INT2FIX(level - 1);
- rb_funcallv(ary, id_flatten_bang, argc, argv);
+ level--;
+
+ if (level > 0) {
+ VALUE ary_flatten_level = INT2FIX(level);
+ rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
}
else if (level < 0) {
+ /* flatten recursively */
rb_funcallv(ary, id_flatten_bang, 0, 0);
}
}
@@ -2795,14 +4343,12 @@ set_if_not_nil(VALUE key, VALUE value, VALUE hash)
/*
* call-seq:
- * hsh.compact -> new_hash
- *
- * Returns a new hash with the nil values/key pairs removed
- *
- * h = { a: 1, b: false, c: nil }
- * h.compact #=> { a: 1, b: false }
- * h #=> { a: 1, b: false, c: nil }
+ * hash.compact -> new_hash
*
+ * Returns a copy of +self+ with all +nil+-valued entries removed:
+ * h = {foo: 0, bar: nil, baz: 2, bat: nil}
+ * h1 = h.compact
+ * h1 # => {:foo=>0, :baz=>2}
*/
static VALUE
@@ -2817,80 +4363,106 @@ rb_hash_compact(VALUE hash)
/*
* call-seq:
- * hsh.compact! -> hsh or nil
- *
- * Removes all nil values from the hash.
- * Returns nil if no changes were made, otherwise returns the hash.
+ * hash.compact! -> self or nil
*
- * h = { a: 1, b: false, c: nil }
- * h.compact! #=> { a: 1, b: false }
+ * Returns +self+ with all its +nil+-valued entries removed (in place):
+ * h = {foo: 0, bar: nil, baz: 2, bat: nil}
+ * h.compact! # => {:foo=>0, :baz=>2}
*
+ * Returns +nil+ if no entries were removed.
*/
static VALUE
rb_hash_compact_bang(VALUE hash)
{
+ st_index_t n;
rb_hash_modify_check(hash);
- if (RHASH(hash)->ntbl) {
- st_index_t n = RHASH(hash)->ntbl->num_entries;
+ n = RHASH_SIZE(hash);
+ if (n) {
rb_hash_foreach(hash, delete_if_nil, hash);
- if (n != RHASH(hash)->ntbl->num_entries)
+ if (n != RHASH_SIZE(hash))
return hash;
}
return Qnil;
}
+static st_table *rb_init_identtable_with_size(st_index_t size);
+
/*
* call-seq:
- * hsh.compare_by_identity -> hsh
- *
- * Makes <i>hsh</i> compare its keys by their identity, i.e. it
- * will consider exact same objects as same keys.
- *
- * h1 = { "a" => 100, "b" => 200, :c => "c" }
- * h1["a"] #=> 100
- * h1.compare_by_identity
- * h1.compare_by_identity? #=> true
- * h1["a".dup] #=> nil # different objects.
- * h1[:c] #=> "c" # same symbols are all same.
- *
+ * hash.compare_by_identity -> self
+ *
+ * Sets +self+ to consider only identity in comparing keys;
+ * two keys are considered the same only if they are the same object;
+ * returns +self+.
+ *
+ * By default, these two object are considered to be the same key,
+ * so +s1+ will overwrite +s0+:
+ * s0 = 'x'
+ * s1 = 'x'
+ * h = {}
+ * h.compare_by_identity? # => false
+ * h[s0] = 0
+ * h[s1] = 1
+ * h # => {"x"=>1}
+ *
+ * After calling \#compare_by_identity, the keys are considered to be different,
+ * and therefore do not overwrite each other:
+ * h = {}
+ * h.compare_by_identity # => {}
+ * h.compare_by_identity? # => true
+ * h[s0] = 0
+ * h[s1] = 1
+ * h # => {"x"=>0, "x"=>1}
*/
static VALUE
rb_hash_compare_by_id(VALUE hash)
{
+ VALUE tmp;
+ st_table *identtable;
+
if (rb_hash_compare_by_id_p(hash)) return hash;
- rb_hash_modify(hash);
- RHASH(hash)->ntbl->type = &identhash;
- rb_hash_rehash(hash);
+
+ rb_hash_modify_check(hash);
+ ar_force_convert_table(hash, __FILE__, __LINE__);
+ HASH_ASSERT(RHASH_ST_TABLE_P(hash));
+
+ tmp = hash_alloc(0);
+ identtable = rb_init_identtable_with_size(RHASH_SIZE(hash));
+ RHASH_ST_TABLE_SET(tmp, identtable);
+ rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
+ st_free_table(RHASH_ST_TABLE(hash));
+ RHASH_ST_TABLE_SET(hash, identtable);
+ RHASH_ST_CLEAR(tmp);
+ rb_gc_force_recycle(tmp);
+
return hash;
}
/*
* call-seq:
- * hsh.compare_by_identity? -> true or false
- *
- * Returns <code>true</code> if <i>hsh</i> will compare its keys by
- * their identity. Also see <code>Hash#compare_by_identity</code>.
+ * hash.compare_by_identity? -> true or false
*
+ * Returns +true+ if #compare_by_identity has been called, +false+ otherwise.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_compare_by_id_p(VALUE hash)
{
- if (!RHASH(hash)->ntbl)
- return Qfalse;
- if (RHASH(hash)->ntbl->type == &identhash) {
+ if (RHASH_ST_TABLE_P(hash) && RHASH_ST_TABLE(hash)->type == &identhash) {
return Qtrue;
}
- return Qfalse;
+ else {
+ return Qfalse;
+ }
}
VALUE
rb_ident_hash_new(void)
{
VALUE hash = rb_hash_new();
- RHASH(hash)->ntbl = st_init_table(&identhash);
+ RHASH_ST_TABLE_SET(hash, st_init_table(&identhash));
return hash;
}
@@ -2900,7 +4472,7 @@ rb_init_identtable(void)
return st_init_table(&identhash);
}
-st_table *
+static st_table *
rb_init_identtable_with_size(st_index_t size)
{
return st_init_table_with_size(&identhash, size);
@@ -2928,50 +4500,105 @@ any_p_i_fast(VALUE key, VALUE value, VALUE arg)
return ST_CONTINUE;
}
+static int
+any_p_i_pattern(VALUE key, VALUE value, VALUE arg)
+{
+ VALUE ret = rb_funcall(((VALUE *)arg)[1], idEqq, 1, rb_assoc_new(key, value));
+ if (RTEST(ret)) {
+ *(VALUE *)arg = Qtrue;
+ return ST_STOP;
+ }
+ return ST_CONTINUE;
+}
+
/*
* call-seq:
- * hsh.any? [{ |(key, value)| block }] -> true or false
- *
- * See also Enumerable#any?
+ * hash.any? -> true or false
+ * hash.any?(object) -> true or false
+ * hash.any? {|key, value| ... } -> true or false
+ *
+ * Returns +true+ if any element satisfies a given criterion;
+ * +false+ otherwise.
+ *
+ * With no argument and no block,
+ * returns +true+ if +self+ is non-empty; +false+ if empty.
+ *
+ * With argument +object+ and no block,
+ * returns +true+ if for any key +key+
+ * <tt>h.assoc(key) == object</tt>:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.any?([:bar, 1]) # => true
+ * h.any?([:bar, 0]) # => false
+ * h.any?([:baz, 1]) # => false
+ *
+ * With no argument and a block,
+ * calls the block with each key-value pair;
+ * returns +true+ if the block returns any truthy value,
+ * +false+ otherwise:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.any? {|key, value| value < 3 } # => true
+ * h.any? {|key, value| value > 3 } # => false
*/
static VALUE
-rb_hash_any_p(VALUE hash)
+rb_hash_any_p(int argc, VALUE *argv, VALUE hash)
{
- VALUE ret = Qfalse;
+ VALUE args[2];
+ args[0] = Qfalse;
+ rb_check_arity(argc, 0, 1);
if (RHASH_EMPTY_P(hash)) return Qfalse;
- if (!rb_block_given_p()) {
- /* yields pairs, never false */
- return Qtrue;
+ if (argc) {
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ args[1] = argv[0];
+
+ rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args);
}
- if (rb_block_arity() > 1)
- rb_hash_foreach(hash, any_p_i_fast, (VALUE)&ret);
- else
- rb_hash_foreach(hash, any_p_i, (VALUE)&ret);
- return ret;
+ else {
+ if (!rb_block_given_p()) {
+ /* yields pairs, never false */
+ return Qtrue;
+ }
+ if (rb_block_pair_yield_optimizable())
+ rb_hash_foreach(hash, any_p_i_fast, (VALUE)args);
+ else
+ rb_hash_foreach(hash, any_p_i, (VALUE)args);
+ }
+ return args[0];
}
/*
- * call-seq:
- * hsh.dig(key, ...) -> object
- *
- * Extracts the nested value specified by the sequence of <i>key</i>
- * objects by calling +dig+ at each step, returning +nil+ if any
- * intermediate step is +nil+.
- *
- * h = { foo: {bar: {baz: 1}}}
- *
- * h.dig(:foo, :bar, :baz) #=> 1
- * h.dig(:foo, :zot, :xyz) #=> nil
- *
- * g = { foo: [10, 11, 12] }
- * g.dig(:foo, 1) #=> 11
- * g.dig(:foo, 1, 0) #=> TypeError: Integer does not have #dig method
- * g.dig(:foo, :bar) #=> TypeError: no implicit conversion of Symbol into Integer
+ * call-seq:
+ * hash.dig(key, *identifiers) -> object
+ *
+ * Finds and returns the object in nested objects
+ * that is specified by +key+ and +identifiers+.
+ * The nested objects may be instances of various classes.
+ * See {Dig Methods}[rdoc-ref:doc/dig_methods.rdoc].
+ *
+ * Nested Hashes:
+ * h = {foo: {bar: {baz: 2}}}
+ * h.dig(:foo) # => {:bar=>{:baz=>2}}
+ * h.dig(:foo, :bar) # => {:bar=>{:baz=>2}}
+ * h.dig(:foo, :bar, :baz) # => 2
+ * h.dig(:foo, :bar, :BAZ) # => nil
+ *
+ * Nested Hashes and Arrays:
+ * h = {foo: {bar: [:a, :b, :c]}}
+ * h.dig(:foo, :bar, 2) # => :c
+ *
+ * This method will use the {default values}[#class-Hash-label-Default+Values]
+ * for keys that are not present:
+ * h = {foo: {bar: [:a, :b, :c]}}
+ * h.dig(:hello) # => nil
+ * h.default_proc = -> (hash, _key) { hash }
+ * h.dig(:hello, :world) # => h
+ * h.dig(:hello, :world, :foo, :bar, 2) # => :c
*/
-VALUE
+static VALUE
rb_hash_dig(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
@@ -3002,17 +4629,15 @@ hash_le(VALUE hash1, VALUE hash2)
}
/*
- * call-seq:
- * hash <= other -> true or false
- *
- * Returns <code>true</code> if <i>hash</i> is subset of
- * <i>other</i> or equals to <i>other</i>.
- *
- * h1 = {a:1, b:2}
- * h2 = {a:1, b:2, c:3}
- * h1 <= h2 #=> true
- * h2 <= h1 #=> false
- * h1 <= h1 #=> true
+ * call-seq:
+ * hash <= other_hash -> true or false
+ *
+ * Returns +true+ if +hash+ is a subset of +other_hash+, +false+ otherwise:
+ * h1 = {foo: 0, bar: 1}
+ * h2 = {foo: 0, bar: 1, baz: 2}
+ * h1 <= h2 # => true
+ * h2 <= h1 # => false
+ * h1 <= h1 # => true
*/
static VALUE
rb_hash_le(VALUE hash, VALUE other)
@@ -3023,17 +4648,15 @@ rb_hash_le(VALUE hash, VALUE other)
}
/*
- * call-seq:
- * hash < other -> true or false
- *
- * Returns <code>true</code> if <i>hash</i> is subset of
- * <i>other</i>.
- *
- * h1 = {a:1, b:2}
- * h2 = {a:1, b:2, c:3}
- * h1 < h2 #=> true
- * h2 < h1 #=> false
- * h1 < h1 #=> false
+ * call-seq:
+ * hash < other_hash -> true or false
+ *
+ * Returns +true+ if +hash+ is a proper subset of +other_hash+, +false+ otherwise:
+ * h1 = {foo: 0, bar: 1}
+ * h2 = {foo: 0, bar: 1, baz: 2}
+ * h1 < h2 # => true
+ * h2 < h1 # => false
+ * h1 < h1 # => false
*/
static VALUE
rb_hash_lt(VALUE hash, VALUE other)
@@ -3044,17 +4667,15 @@ rb_hash_lt(VALUE hash, VALUE other)
}
/*
- * call-seq:
- * hash >= other -> true or false
- *
- * Returns <code>true</code> if <i>other</i> is subset of
- * <i>hash</i> or equals to <i>hash</i>.
- *
- * h1 = {a:1, b:2}
- * h2 = {a:1, b:2, c:3}
- * h1 >= h2 #=> false
- * h2 >= h1 #=> true
- * h1 >= h1 #=> true
+ * call-seq:
+ * hash >= other_hash -> true or false
+ *
+ * Returns +true+ if +hash+ is a superset of +other_hash+, +false+ otherwise:
+ * h1 = {foo: 0, bar: 1, baz: 2}
+ * h2 = {foo: 0, bar: 1}
+ * h1 >= h2 # => true
+ * h2 >= h1 # => false
+ * h1 >= h1 # => true
*/
static VALUE
rb_hash_ge(VALUE hash, VALUE other)
@@ -3065,17 +4686,15 @@ rb_hash_ge(VALUE hash, VALUE other)
}
/*
- * call-seq:
- * hash > other -> true or false
- *
- * Returns <code>true</code> if <i>other</i> is subset of
- * <i>hash</i>.
- *
- * h1 = {a:1, b:2}
- * h2 = {a:1, b:2, c:3}
- * h1 > h2 #=> false
- * h2 > h1 #=> true
- * h1 > h1 #=> false
+ * call-seq:
+ * hash > other_hash -> true or false
+ *
+ * Returns +true+ if +hash+ is a proper superset of +other_hash+, +false+ otherwise:
+ * h1 = {foo: 0, bar: 1, baz: 2}
+ * h2 = {foo: 0, bar: 1}
+ * h1 > h2 # => true
+ * h2 > h1 # => false
+ * h1 > h1 # => false
*/
static VALUE
rb_hash_gt(VALUE hash, VALUE other)
@@ -3086,16 +4705,34 @@ rb_hash_gt(VALUE hash, VALUE other)
}
static VALUE
-hash_proc_call(VALUE key, VALUE hash, int argc, const VALUE *argv, VALUE passed_proc)
+hash_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(key, hash))
{
rb_check_arity(argc, 1, 1);
return rb_hash_aref(hash, *argv);
}
+/*
+ * call-seq:
+ * hash.to_proc -> proc
+ *
+ * Returns a \Proc object that maps a key to its value:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * proc = h.to_proc
+ * proc.class # => Proc
+ * proc.call(:foo) # => 0
+ * proc.call(:bar) # => 1
+ * proc.call(:nosuch) # => nil
+ */
static VALUE
rb_hash_to_proc(VALUE hash)
{
- return rb_func_proc_new(hash_proc_call, hash);
+ return rb_func_lambda_new(hash_proc_call, hash, 1, 1);
+}
+
+static VALUE
+rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
+{
+ return hash;
}
static int
@@ -3115,14 +4752,71 @@ add_new_i(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
int
rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
{
- st_table *tbl = rb_hash_tbl_raw(hash);
+ st_table *tbl;
+ int ret = 0;
VALUE args[2];
args[0] = hash;
args[1] = val;
+
+ if (RHASH_AR_TABLE_P(hash)) {
+ hash_ar_table(hash);
+
+ ret = ar_update(hash, (st_data_t)key, add_new_i, (st_data_t)args);
+ if (ret != -1) {
+ return ret;
+ }
+ ar_try_convert_table(hash);
+ }
+ tbl = RHASH_TBL_RAW(hash);
return st_update(tbl, (st_data_t)key, add_new_i, (st_data_t)args);
+
}
-static int path_tainted = -1;
+static st_data_t
+key_stringify(VALUE key)
+{
+ return (rb_obj_class(key) == rb_cString && !RB_OBJ_FROZEN(key)) ?
+ rb_hash_key_str(key) : key;
+}
+
+static void
+ar_bulk_insert(VALUE hash, long argc, const VALUE *argv)
+{
+ long i;
+ for (i = 0; i < argc; ) {
+ st_data_t k = key_stringify(argv[i++]);
+ st_data_t v = argv[i++];
+ ar_insert(hash, k, v);
+ RB_OBJ_WRITTEN(hash, Qundef, k);
+ RB_OBJ_WRITTEN(hash, Qundef, v);
+ }
+}
+
+void
+rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
+{
+ HASH_ASSERT(argc % 2 == 0);
+ if (argc > 0) {
+ st_index_t size = argc / 2;
+
+ if (RHASH_TABLE_NULL_P(hash)) {
+ if (size <= RHASH_AR_TABLE_MAX_SIZE) {
+ hash_ar_table(hash);
+ }
+ else {
+ RHASH_TBL_RAW(hash);
+ }
+ }
+
+ if (RHASH_AR_TABLE_P(hash) &&
+ (RHASH_AR_TABLE_SIZE(hash) + size <= RHASH_AR_TABLE_MAX_SIZE)) {
+ ar_bulk_insert(hash, argc, argv);
+ }
+ else {
+ rb_hash_bulk_insert_into_st_table(argc, argv, hash);
+ }
+ }
+}
static char **origenviron;
#ifdef _WIN32
@@ -3132,22 +4826,7 @@ static char **my_environ;
#undef environ
#define environ my_environ
#undef getenv
-static char *(*w32_getenv)(const char*);
-static char *
-w32_getenv_unknown(const char *name)
-{
- char *(*func)(const char*);
- if (rb_locale_encindex() == rb_ascii8bit_encindex()) {
- func = rb_w32_getenv;
- }
- else {
- func = rb_w32_ugetenv;
- }
- /* atomic assignment in flat memory model */
- return (w32_getenv = func)(name);
-}
-static char *(*w32_getenv)(const char*) = w32_getenv_unknown;
-#define getenv(n) w32_getenv(n)
+#define getenv(n) rb_w32_ugetenv(n)
#elif defined(__APPLE__)
#undef environ
#define environ (*_NSGetEnviron())
@@ -3166,22 +4845,21 @@ extern char **environ;
#define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
#endif
-static VALUE
-env_enc_str_new(const char *ptr, long len, rb_encoding *enc)
+static inline rb_encoding *
+env_encoding()
{
#ifdef _WIN32
- rb_encoding *internal = rb_default_internal_encoding();
- const int ecflags = ECONV_INVALID_REPLACE | ECONV_UNDEF_REPLACE;
- rb_encoding *utf8 = rb_utf8_encoding();
- VALUE str = rb_enc_str_new(NULL, 0, (internal ? internal : enc));
- if (NIL_P(rb_str_cat_conv_enc_opts(str, 0, ptr, len, utf8, ecflags, Qnil))) {
- rb_str_initialize(str, ptr, len, utf8);
- }
+ return rb_utf8_encoding();
#else
- VALUE str = rb_external_str_new_with_enc(ptr, len, enc);
+ return rb_locale_encoding();
#endif
+}
+
+static VALUE
+env_enc_str_new(const char *ptr, long len, rb_encoding *enc)
+{
+ VALUE str = rb_external_str_new_with_enc(ptr, len, enc);
- OBJ_TAINT(str);
rb_obj_freeze(str);
return str;
}
@@ -3195,7 +4873,7 @@ env_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
static VALUE
env_str_new(const char *ptr, long len)
{
- return env_enc_str_new(ptr, len, rb_locale_encoding());
+ return env_enc_str_new(ptr, len, env_encoding());
}
static VALUE
@@ -3205,48 +4883,25 @@ env_str_new2(const char *ptr)
return env_str_new(ptr, strlen(ptr));
}
-static int env_path_tainted(const char *);
-
-static rb_encoding *
-env_encoding_for(const char *name, const char *ptr)
-{
- if (ENVMATCH(name, PATH_ENV) && !env_path_tainted(ptr)) {
- return rb_filesystem_encoding();
- }
- else {
- return rb_locale_encoding();
- }
-}
+static const char TZ_ENV[] = "TZ";
static VALUE
env_name_new(const char *name, const char *ptr)
{
- return env_enc_str_new_cstr(ptr, env_encoding_for(name, ptr));
+ return env_enc_str_new_cstr(ptr, env_encoding());
}
static void *
get_env_cstr(
-#ifdef _WIN32
- volatile VALUE *pstr,
-#else
VALUE str,
-#endif
const char *name)
{
-#ifdef _WIN32
- VALUE str = *pstr;
-#endif
char *var;
rb_encoding *enc = rb_enc_get(str);
if (!rb_enc_asciicompat(enc)) {
rb_raise(rb_eArgError, "bad environment variable %s: ASCII incompatible encoding: %s",
name, rb_enc_name(enc));
}
-#ifdef _WIN32
- if (!rb_enc_str_asciionly_p(str)) {
- *pstr = str = rb_str_conv_enc(str, NULL, rb_utf8_encoding());
- }
-#endif
var = RSTRING_PTR(str);
if (memchr(var, '\0', RSTRING_LEN(str))) {
rb_raise(rb_eArgError, "bad environment variable %s: contains null byte", name);
@@ -3254,13 +4909,8 @@ get_env_cstr(
return rb_str_fill_terminator(str, 1); /* ASCII compatible */
}
-#ifdef _WIN32
-#define get_env_ptr(var, val) \
- (var = get_env_cstr(&(val), #var))
-#else
#define get_env_ptr(var, val) \
(var = get_env_cstr(val, #var))
-#endif
static inline const char *
env_name(volatile VALUE *s)
@@ -3273,21 +4923,34 @@ env_name(volatile VALUE *s)
#define env_name(s) env_name(&(s))
+static VALUE env_aset(VALUE nm, VALUE val);
+
+static void
+reset_by_modified_env(const char *nam)
+{
+ /*
+ * ENV['TZ'] = nil has a special meaning.
+ * TZ is no longer considered up-to-date and ruby call tzset() as needed.
+ * It could be useful if sysadmin change /etc/localtime.
+ * This hack might works only on Linux glibc.
+ */
+ if (ENVMATCH(nam, TZ_ENV)) {
+ ruby_reset_timezone();
+ }
+}
+
static VALUE
-env_delete(VALUE obj, VALUE name)
+env_delete(VALUE name)
{
- const char *nam, *val;
+ const char *nam = env_name(name);
+ const char *val = getenv(nam);
+
+ reset_by_modified_env(nam);
- nam = env_name(name);
- val = getenv(nam);
if (val) {
VALUE value = env_str_new2(val);
ruby_setenv(nam, 0);
- if (ENVMATCH(nam, PATH_ENV)) {
- RB_GC_GUARD(name);
- path_tainted = 0;
- }
return value;
}
return Qnil;
@@ -3295,20 +4958,36 @@ env_delete(VALUE obj, VALUE name)
/*
* call-seq:
- * ENV.delete(name) -> value
- * ENV.delete(name) { |name| } -> value
+ * ENV.delete(name) -> value
+ * ENV.delete(name) { |name| block } -> value
+ * ENV.delete(missing_name) -> nil
+ * ENV.delete(missing_name) { |name| block } -> block_value
+ *
+ * Deletes the environment variable with +name+ if it exists and returns its value:
+ * ENV['foo'] = '0'
+ * ENV.delete('foo') # => '0'
*
- * Deletes the environment variable with +name+ and returns the value of the
- * variable. If a block is given it will be called when the named environment
- * does not exist.
+ * If a block is not given and the named environment variable does not exist, returns +nil+.
+ *
+ * If a block given and the environment variable does not exist,
+ * yields +name+ to the block and returns the value of the block:
+ * ENV.delete('foo') { |name| name * 2 } # => "foofoo"
+ *
+ * If a block given and the environment variable exists,
+ * deletes the environment variable and returns its value (ignoring the block):
+ * ENV['foo'] = '0'
+ * ENV.delete('foo') { |name| raise 'ignored' } # => "0"
+ *
+ * Raises an exception if +name+ is invalid.
+ * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
*/
static VALUE
env_delete_m(VALUE obj, VALUE name)
{
VALUE val;
- val = env_delete(obj, name);
- if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
+ val = env_delete(name);
+ if (NIL_P(val) && rb_block_given_p()) val = rb_yield(name);
return val;
}
@@ -3316,8 +4995,13 @@ env_delete_m(VALUE obj, VALUE name)
* call-seq:
* ENV[name] -> value
*
- * Retrieves the +value+ for environment variable +name+ as a String. Returns
- * +nil+ if the named variable does not exist.
+ * Returns the value for the environment variable +name+ if it exists:
+ * ENV['foo'] = '0'
+ * ENV['foo'] # => "0"
+ * Returns +nil+ if the named variable does not exist.
+ *
+ * Raises an exception if +name+ is invalid.
+ * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
*/
static VALUE
rb_f_getenv(VALUE obj, VALUE name)
@@ -3333,21 +5017,32 @@ rb_f_getenv(VALUE obj, VALUE name)
}
/*
- * :yield: missing_name
* call-seq:
- * ENV.fetch(name) -> value
- * ENV.fetch(name, default) -> value
- * ENV.fetch(name) { |missing_name| ... } -> value
- *
- * Retrieves the environment variable +name+.
- *
- * If the given name does not exist and neither +default+ nor a block a
- * provided an KeyError is raised. If a block is given it is called with
- * the missing name to provide a value. If a default value is given it will
- * be returned when no block is given.
+ * ENV.fetch(name) -> value
+ * ENV.fetch(name, default) -> value
+ * ENV.fetch(name) { |name| block } -> value
+ *
+ * If +name+ is the name of an environment variable, returns its value:
+ * ENV['foo'] = '0'
+ * ENV.fetch('foo') # => '0'
+ * Otherwise if a block is given (but not a default value),
+ * yields +name+ to the block and returns the block's return value:
+ * ENV.fetch('foo') { |name| :need_not_return_a_string } # => :need_not_return_a_string
+ * Otherwise if a default value is given (but not a block), returns the default value:
+ * ENV.delete('foo')
+ * ENV.fetch('foo', :default_need_not_be_a_string) # => :default_need_not_be_a_string
+ * If the environment variable does not exist and both default and block are given,
+ * issues a warning ("warning: block supersedes default value argument"),
+ * yields +name+ to the block, and returns the block's return value:
+ * ENV.fetch('foo', :default) { |name| :block_return } # => :block_return
+ * Raises KeyError if +name+ is valid, but not found,
+ * and neither default value nor block is given:
+ * ENV.fetch('foo') # Raises KeyError (key not found: "foo")
+ * Raises an exception if +name+ is invalid.
+ * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
*/
static VALUE
-env_fetch(int argc, VALUE *argv)
+env_fetch(int argc, VALUE *argv, VALUE _)
{
VALUE key;
long block_given;
@@ -3371,28 +5066,11 @@ env_fetch(int argc, VALUE *argv)
return env_name_new(nam, env);
}
-static void
-path_tainted_p(const char *path)
-{
- path_tainted = rb_path_check(path)?0:1;
-}
-
-static int
-env_path_tainted(const char *path)
-{
- if (path_tainted < 0) {
- path_tainted_p(path);
- }
- return path_tainted;
-}
-
int
rb_env_path_tainted(void)
{
- if (path_tainted < 0) {
- path_tainted_p(getenv(PATH_ENV));
- }
- return path_tainted;
+ rb_warn_deprecated_to_remove("rb_env_path_tainted", "3.2");
+ return 0;
}
#if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
@@ -3431,10 +5109,33 @@ getenvsize(const WCHAR* p)
while (*p++) p += lstrlenW(p) + 1;
return p - porg + 1;
}
+
static size_t
getenvblocksize(void)
{
+#ifdef _MAX_ENV
+ return _MAX_ENV;
+#else
return 32767;
+#endif
+}
+
+static int
+check_envsize(size_t n)
+{
+ if (_WIN32_WINNT < 0x0600 && rb_w32_osver() < 6) {
+ /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx */
+ /* Windows Server 2003 and Windows XP: The maximum size of the
+ * environment block for the process is 32,767 characters. */
+ WCHAR* p = GetEnvironmentStringsW();
+ if (!p) return -1; /* never happen */
+ n += getenvsize(p);
+ FreeEnvironmentStringsW(p);
+ if (n >= getenvblocksize()) {
+ return -1;
+ }
+ }
+ return 0;
}
#endif
@@ -3474,16 +5175,11 @@ ruby_setenv(const char *name, const char *value)
check_envname(name);
len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
if (value) {
- WCHAR* p = GetEnvironmentStringsW();
- size_t n;
int len2;
- if (!p) goto fail; /* never happen */
- n = lstrlen(name) + 2 + strlen(value) + getenvsize(p);
- FreeEnvironmentStringsW(p);
- if (n >= getenvblocksize()) {
+ len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
+ if (check_envsize((size_t)len + len2)) { /* len and len2 include '\0' */
goto fail; /* 2 for '=' & '\0' */
}
- len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
wname = ALLOCV_N(WCHAR, buf, len + len2);
wvalue = wname + len;
MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
@@ -3611,21 +5307,61 @@ ruby_unsetenv(const char *name)
/*
* call-seq:
- * ENV[name] = value
+ * ENV[name] = value -> value
* ENV.store(name, value) -> value
*
- * Sets the environment variable +name+ to +value+. If the value given is
- * +nil+ the environment variable is deleted.
- * +name+ must be a string.
- *
+ * ENV.store is an alias for ENV.[]=.
+ *
+ * Creates, updates, or deletes the named environment variable, returning the value.
+ * Both +name+ and +value+ may be instances of String.
+ * See {Valid Names and Values}[#class-ENV-label-Valid+Names+and+Values].
+ *
+ * - If the named environment variable does not exist:
+ * - If +value+ is +nil+, does nothing.
+ * ENV.clear
+ * ENV['foo'] = nil # => nil
+ * ENV.include?('foo') # => false
+ * ENV.store('bar', nil) # => nil
+ * ENV.include?('bar') # => false
+ * - If +value+ is not +nil+, creates the environment variable with +name+ and +value+:
+ * # Create 'foo' using ENV.[]=.
+ * ENV['foo'] = '0' # => '0'
+ * ENV['foo'] # => '0'
+ * # Create 'bar' using ENV.store.
+ * ENV.store('bar', '1') # => '1'
+ * ENV['bar'] # => '1'
+ * - If the named environment variable exists:
+ * - If +value+ is not +nil+, updates the environment variable with value +value+:
+ * # Update 'foo' using ENV.[]=.
+ * ENV['foo'] = '2' # => '2'
+ * ENV['foo'] # => '2'
+ * # Update 'bar' using ENV.store.
+ * ENV.store('bar', '3') # => '3'
+ * ENV['bar'] # => '3'
+ * - If +value+ is +nil+, deletes the environment variable:
+ * # Delete 'foo' using ENV.[]=.
+ * ENV['foo'] = nil # => nil
+ * ENV.include?('foo') # => false
+ * # Delete 'bar' using ENV.store.
+ * ENV.store('bar', nil) # => nil
+ * ENV.include?('bar') # => false
+ *
+ * Raises an exception if +name+ or +value+ is invalid.
+ * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
*/
static VALUE
-env_aset(VALUE obj, VALUE nm, VALUE val)
+env_aset_m(VALUE obj, VALUE nm, VALUE val)
+{
+ return env_aset(nm, val);
+}
+
+static VALUE
+env_aset(VALUE nm, VALUE val)
{
char *name, *value;
if (NIL_P(val)) {
- env_delete(obj, nm);
+ env_delete(nm);
return Qnil;
}
SafeStringValue(nm);
@@ -3636,38 +5372,26 @@ env_aset(VALUE obj, VALUE nm, VALUE val)
get_env_ptr(value, val);
ruby_setenv(name, value);
- if (ENVMATCH(name, PATH_ENV)) {
- RB_GC_GUARD(nm);
- if (OBJ_TAINTED(val)) {
- /* already tainted, no check */
- path_tainted = 1;
- return val;
- }
- else {
- path_tainted_p(value);
- }
- }
+ reset_by_modified_env(name);
return val;
}
-/*
- * call-seq:
- * ENV.keys -> Array
- *
- * Returns every environment variable name in an Array
- */
static VALUE
-env_keys(void)
+env_keys(int raw)
{
char **env;
VALUE ary;
+ rb_encoding *enc = raw ? 0 : rb_locale_encoding();
ary = rb_ary_new();
env = GET_ENVIRON(environ);
while (*env) {
char *s = strchr(*env, '=');
if (s) {
- rb_ary_push(ary, env_str_new(*env, s-*env));
+ const char *p = *env;
+ size_t l = s - p;
+ VALUE e = raw ? rb_utf8_str_new(p, l) : env_enc_str_new(p, l, enc);
+ rb_ary_push(ary, e);
}
env++;
}
@@ -3675,6 +5399,25 @@ env_keys(void)
return ary;
}
+/*
+ * call-seq:
+ * ENV.keys -> array of names
+ *
+ * Returns all variable names in an Array:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.keys # => ['bar', 'foo']
+ * The order of the names is OS-dependent.
+ * See {About Ordering}[#class-ENV-label-About+Ordering].
+ *
+ * Returns the empty Array if ENV is empty.
+ */
+
+static VALUE
+env_f_keys(VALUE _)
+{
+ return env_keys(FALSE);
+}
+
static VALUE
rb_env_size(VALUE ehash, VALUE args, VALUE eobj)
{
@@ -3693,12 +5436,20 @@ rb_env_size(VALUE ehash, VALUE args, VALUE eobj)
/*
* call-seq:
- * ENV.each_key { |name| } -> Hash
- * ENV.each_key -> Enumerator
- *
- * Yields each environment variable name.
- *
- * An Enumerator is returned if no block is given.
+ * ENV.each_key { |name| block } -> ENV
+ * ENV.each_key -> an_enumerator
+ *
+ * Yields each environment variable name:
+ * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
+ * names = []
+ * ENV.each_key { |name| names.push(name) } # => ENV
+ * names # => ["bar", "foo"]
+ *
+ * Returns an Enumerator if no block given:
+ * e = ENV.each_key # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_key>
+ * names = []
+ * e.each { |name| names.push(name) } # => ENV
+ * names # => ["bar", "foo"]
*/
static VALUE
env_each_key(VALUE ehash)
@@ -3707,19 +5458,13 @@ env_each_key(VALUE ehash)
long i;
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
- keys = env_keys();
+ keys = env_keys(FALSE);
for (i=0; i<RARRAY_LEN(keys); i++) {
rb_yield(RARRAY_AREF(keys, i));
}
return ehash;
}
-/*
- * call-seq:
- * ENV.values -> Array
- *
- * Returns every environment variable value as an Array
- */
static VALUE
env_values(void)
{
@@ -3741,12 +5486,38 @@ env_values(void)
/*
* call-seq:
- * ENV.each_value { |value| } -> Hash
- * ENV.each_value -> Enumerator
+ * ENV.values -> array of values
*
- * Yields each environment variable +value+.
+ * Returns all environment variable values in an Array:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.values # => ['1', '0']
+ * The order of the values is OS-dependent.
+ * See {About Ordering}[#class-ENV-label-About+Ordering].
*
- * An Enumerator is returned if no block was given.
+ * Returns the empty Array if ENV is empty.
+ */
+static VALUE
+env_f_values(VALUE _)
+{
+ return env_values();
+}
+
+/*
+ * call-seq:
+ * ENV.each_value { |value| block } -> ENV
+ * ENV.each_value -> an_enumerator
+ *
+ * Yields each environment variable value:
+ * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
+ * values = []
+ * ENV.each_value { |value| values.push(value) } # => ENV
+ * values # => ["1", "0"]
+ *
+ * Returns an Enumerator if no block given:
+ * e = ENV.each_value # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_value>
+ * values = []
+ * e.each { |value| values.push(value) } # => ENV
+ * values # => ["1", "0"]
*/
static VALUE
env_each_value(VALUE ehash)
@@ -3764,14 +5535,21 @@ env_each_value(VALUE ehash)
/*
* call-seq:
- * ENV.each { |name, value| } -> Hash
- * ENV.each -> Enumerator
- * ENV.each_pair { |name, value| } -> Hash
- * ENV.each_pair -> Enumerator
- *
- * Yields each environment variable +name+ and +value+.
- *
- * If no block is given an Enumerator is returned.
+ * ENV.each { |name, value| block } -> ENV
+ * ENV.each -> an_enumerator
+ * ENV.each_pair { |name, value| block } -> ENV
+ * ENV.each_pair -> an_enumerator
+ *
+ * Yields each environment variable name and its value as a 2-element \Array:
+ * h = {}
+ * ENV.each_pair { |name, value| h[name] = value } # => ENV
+ * h # => {"bar"=>"1", "foo"=>"0"}
+ *
+ * Returns an Enumerator if no block given:
+ * h = {}
+ * e = ENV.each_pair # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_pair>
+ * e.each { |name, value| h[name] = value } # => ENV
+ * h # => {"bar"=>"1", "foo"=>"0"}
*/
static VALUE
env_each_pair(VALUE ehash)
@@ -3794,7 +5572,7 @@ env_each_pair(VALUE ehash)
}
FREE_ENVIRON(environ);
- if (rb_block_arity() > 1) {
+ if (rb_block_pair_yield_optimizable()) {
for (i=0; i<RARRAY_LEN(ary); i+=2) {
rb_yield_values(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1));
}
@@ -3809,12 +5587,25 @@ env_each_pair(VALUE ehash)
/*
* call-seq:
- * ENV.reject! { |name, value| } -> ENV or nil
- * ENV.reject! -> Enumerator
- *
- * Equivalent to ENV#delete_if but returns +nil+ if no changes were made.
- *
- * Returns an Enumerator if no block was given.
+ * ENV.reject! { |name, value| block } -> ENV or nil
+ * ENV.reject! -> an_enumerator
+ *
+ * Similar to ENV.delete_if, but returns +nil+ if no changes were made.
+ *
+ * Yields each environment variable name and its value as a 2-element Array,
+ * deleting each environment variable for which the block returns a truthy value,
+ * and returning ENV (if any deletions) or +nil+ (if not):
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.reject! { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"foo"=>"0"}
+ * ENV.reject! { |name, value| name.start_with?('b') } # => nil
+ *
+ * Returns an Enumerator if no block given:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * e = ENV.reject! # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:reject!>
+ * e.each { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"foo"=>"0"}
+ * e.each { |name, value| name.start_with?('b') } # => nil
*/
static VALUE
env_reject_bang(VALUE ehash)
@@ -3824,14 +5615,13 @@ env_reject_bang(VALUE ehash)
int del = 0;
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
- keys = env_keys();
+ keys = env_keys(FALSE);
RBASIC_CLEAR_CLASS(keys);
for (i=0; i<RARRAY_LEN(keys); i++) {
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(val)) {
if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
- FL_UNSET(RARRAY_AREF(keys, i), FL_TAINT);
- env_delete(Qnil, RARRAY_AREF(keys, i));
+ env_delete(RARRAY_AREF(keys, i));
del++;
}
}
@@ -3843,12 +5633,23 @@ env_reject_bang(VALUE ehash)
/*
* call-seq:
- * ENV.delete_if { |name, value| } -> Hash
- * ENV.delete_if -> Enumerator
- *
- * Deletes every environment variable for which the block evaluates to +true+.
- *
- * If no block is given an enumerator is returned instead.
+ * ENV.delete_if { |name, value| block } -> ENV
+ * ENV.delete_if -> an_enumerator
+ *
+ * Yields each environment variable name and its value as a 2-element Array,
+ * deleting each environment variable for which the block returns a truthy value,
+ * and returning ENV (regardless of whether any deletions):
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.delete_if { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"foo"=>"0"}
+ * ENV.delete_if { |name, value| name.start_with?('b') } # => ENV
+ *
+ * Returns an Enumerator if no block given:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * e = ENV.delete_if # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:delete_if!>
+ * e.each { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"foo"=>"0"}
+ * e.each { |name, value| name.start_with?('b') } # => ENV
*/
static VALUE
env_delete_if(VALUE ehash)
@@ -3860,13 +5661,23 @@ env_delete_if(VALUE ehash)
/*
* call-seq:
- * ENV.values_at(name, ...) -> Array
+ * ENV.values_at(*names) -> array of values
+ *
+ * Returns an Array containing the environment variable values associated with
+ * the given names:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.values_at('foo', 'baz') # => ["0", "2"]
*
- * Returns an array containing the environment variable values associated with
- * the given names. See also ENV.select.
+ * Returns +nil+ in the Array for each name that is not an ENV name:
+ * ENV.values_at('foo', 'bat', 'bar', 'bam') # => ["0", nil, "1", nil]
+ *
+ * Returns an empty \Array if no names given.
+ *
+ * Raises an exception if any name is invalid.
+ * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
*/
static VALUE
-env_values_at(int argc, VALUE *argv)
+env_values_at(int argc, VALUE *argv, VALUE _)
{
VALUE result;
long i;
@@ -3880,12 +5691,24 @@ env_values_at(int argc, VALUE *argv)
/*
* call-seq:
- * ENV.select { |name, value| } -> Hash
- * ENV.select -> Enumerator
- *
- * Returns a copy of the environment for entries where the block returns true.
- *
- * Returns an Enumerator if no block was given.
+ * ENV.select { |name, value| block } -> hash of name/value pairs
+ * ENV.select -> an_enumerator
+ * ENV.filter { |name, value| block } -> hash of name/value pairs
+ * ENV.filter -> an_enumerator
+ *
+ * ENV.filter is an alias for ENV.select.
+ *
+ * Yields each environment variable name and its value as a 2-element Array,
+ * returning a Hash of the names and values for which the block returns a truthy value:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.select { |name, value| name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
+ * ENV.filter { |name, value| name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
+ *
+ * Returns an Enumerator if no block given:
+ * e = ENV.select # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:select>
+ * e.each { |name, value | name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
+ * e = ENV.filter # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:filter>
+ * e.each { |name, value | name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
*/
static VALUE
env_select(VALUE ehash)
@@ -3896,7 +5719,7 @@ env_select(VALUE ehash)
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
result = rb_hash_new();
- keys = env_keys();
+ keys = env_keys(FALSE);
for (i = 0; i < RARRAY_LEN(keys); ++i) {
VALUE key = RARRAY_AREF(keys, i);
VALUE val = rb_f_getenv(Qnil, key);
@@ -3913,10 +5736,40 @@ env_select(VALUE ehash)
/*
* call-seq:
- * ENV.select! { |name, value| } -> ENV or nil
- * ENV.select! -> Enumerator
- *
- * Equivalent to ENV#keep_if but returns +nil+ if no changes were made.
+ * ENV.select! { |name, value| block } -> ENV or nil
+ * ENV.select! -> an_enumerator
+ * ENV.filter! { |name, value| block } -> ENV or nil
+ * ENV.filter! -> an_enumerator
+ *
+ * ENV.filter! is an alias for ENV.select!.
+ *
+ * Yields each environment variable name and its value as a 2-element Array,
+ * deleting each entry for which the block returns +false+ or +nil+,
+ * and returning ENV if any deletions made, or +nil+ otherwise:
+ *
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.select! { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"bar"=>"1", "baz"=>"2"}
+ * ENV.select! { |name, value| true } # => nil
+ *
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.filter! { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"bar"=>"1", "baz"=>"2"}
+ * ENV.filter! { |name, value| true } # => nil
+ *
+ * Returns an Enumerator if no block given:
+ *
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * e = ENV.select! # => #<Enumerator: {"bar"=>"1", "baz"=>"2"}:select!>
+ * e.each { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"bar"=>"1", "baz"=>"2"}
+ * e.each { |name, value| true } # => nil
+ *
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * e = ENV.filter! # => #<Enumerator: {"bar"=>"1", "baz"=>"2"}:filter!>
+ * e.each { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"bar"=>"1", "baz"=>"2"}
+ * e.each { |name, value| true } # => nil
*/
static VALUE
env_select_bang(VALUE ehash)
@@ -3926,14 +5779,13 @@ env_select_bang(VALUE ehash)
int del = 0;
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
- keys = env_keys();
+ keys = env_keys(FALSE);
RBASIC_CLEAR_CLASS(keys);
for (i=0; i<RARRAY_LEN(keys); i++) {
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(val)) {
if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
- FL_UNSET(RARRAY_AREF(keys, i), FL_TAINT);
- env_delete(Qnil, RARRAY_AREF(keys, i));
+ env_delete(RARRAY_AREF(keys, i));
del++;
}
}
@@ -3945,12 +5797,21 @@ env_select_bang(VALUE ehash)
/*
* call-seq:
- * ENV.keep_if { |name, value| } -> Hash
- * ENV.keep_if -> Enumerator
- *
- * Deletes every environment variable where the block evaluates to +false+.
- *
- * Returns an enumerator if no block was given.
+ * ENV.keep_if { |name, value| block } -> ENV
+ * ENV.keep_if -> an_enumerator
+ *
+ * Yields each environment variable name and its value as a 2-element Array,
+ * deleting each environment variable for which the block returns +false+ or +nil+,
+ * and returning ENV:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.keep_if { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"bar"=>"1", "baz"=>"2"}
+ *
+ * Returns an Enumerator if no block given:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * e = ENV.keep_if # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:keep_if>
+ * e.each { |name, value| name.start_with?('b') } # => ENV
+ * ENV # => {"bar"=>"1", "baz"=>"2"}
*/
static VALUE
env_keep_if(VALUE ehash)
@@ -3962,22 +5823,48 @@ env_keep_if(VALUE ehash)
/*
* call-seq:
- * ENV.clear
- *
- * Removes every environment variable.
+ * ENV.slice(*names) -> hash of name/value pairs
+ *
+ * Returns a Hash of the given ENV names and their corresponding values:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2', 'bat' => '3')
+ * ENV.slice('foo', 'baz') # => {"foo"=>"0", "baz"=>"2"}
+ * ENV.slice('baz', 'foo') # => {"baz"=>"2", "foo"=>"0"}
+ * Raises an exception if any of the +names+ is invalid
+ * (see {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values]):
+ * ENV.slice('foo', 'bar', :bat) # Raises TypeError (no implicit conversion of Symbol into String)
*/
+static VALUE
+env_slice(int argc, VALUE *argv, VALUE _)
+{
+ int i;
+ VALUE key, value, result;
+
+ if (argc == 0) {
+ return rb_hash_new();
+ }
+ result = rb_hash_new_with_size(argc);
+
+ for (i = 0; i < argc; i++) {
+ key = argv[i];
+ value = rb_f_getenv(Qnil, key);
+ if (value != Qnil)
+ rb_hash_aset(result, key, value);
+ }
+
+ return result;
+}
+
VALUE
rb_env_clear(void)
{
VALUE keys;
long i;
- keys = env_keys();
+ keys = env_keys(TRUE);
for (i=0; i<RARRAY_LEN(keys); i++) {
- VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
- if (!NIL_P(val)) {
- env_delete(Qnil, RARRAY_AREF(keys, i));
- }
+ VALUE key = RARRAY_AREF(keys, i);
+ const char *nam = RSTRING_PTR(key);
+ ruby_setenv(nam, 0);
}
RB_GC_GUARD(keys);
return envtbl;
@@ -3985,24 +5872,43 @@ rb_env_clear(void)
/*
* call-seq:
+ * ENV.clear -> ENV
+ *
+ * Removes every environment variable; returns ENV:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.size # => 2
+ * ENV.clear # => ENV
+ * ENV.size # => 0
+ */
+static VALUE
+env_clear(VALUE _)
+{
+ return rb_env_clear();
+}
+
+/*
+ * call-seq:
* ENV.to_s -> "ENV"
*
- * Returns "ENV"
+ * Returns String 'ENV':
+ * ENV.to_s # => "ENV"
*/
static VALUE
-env_to_s(void)
+env_to_s(VALUE _)
{
return rb_usascii_str_new2("ENV");
}
/*
* call-seq:
- * ENV.inspect -> string
+ * ENV.inspect -> a_string
*
- * Returns the contents of the environment as a String.
+ * Returns the contents of the environment as a String:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.inspect # => "{\"bar\"=>\"1\", \"foo\"=>\"0\"}"
*/
static VALUE
-env_inspect(void)
+env_inspect(VALUE _)
{
char **env;
VALUE str, i;
@@ -4026,22 +5932,21 @@ env_inspect(void)
}
FREE_ENVIRON(environ);
rb_str_buf_cat2(str, "}");
- OBJ_TAINT(str);
return str;
}
/*
* call-seq:
- * ENV.to_a -> Array
- *
- * Converts the environment variables into an array of names and value arrays.
- *
- * ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
+ * ENV.to_a -> array of 2-element arrays
*
+ * Returns the contents of ENV as an Array of 2-element Arrays,
+ * each of which is a name/value pair:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.to_a # => [["bar", "1"], ["foo", "0"]]
*/
static VALUE
-env_to_a(void)
+env_to_a(VALUE _)
{
char **env;
VALUE ary;
@@ -4062,26 +5967,30 @@ env_to_a(void)
/*
* call-seq:
- * ENV.rehash
+ * ENV.rehash -> nil
+ *
+ * (Provided for compatibility with Hash.)
*
- * Re-hashing the environment variables does nothing. It is provided for
- * compatibility with Hash.
+ * Does not modify ENV; returns +nil+.
*/
static VALUE
-env_none(void)
+env_none(VALUE _)
{
return Qnil;
}
/*
* call-seq:
- * ENV.length
- * ENV.size
+ * ENV.length -> an_integer
+ * ENV.size -> an_integer
*
- * Returns the number of environment variables.
+ * Returns the count of environment variables:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.length # => 2
+ * ENV.size # => 2
*/
static VALUE
-env_size(void)
+env_size(VALUE _)
{
int i;
char **env;
@@ -4097,10 +6006,14 @@ env_size(void)
* call-seq:
* ENV.empty? -> true or false
*
- * Returns true when there are no environment variables
+ * Returns +true+ when there are no environment variables, +false+ otherwise:
+ * ENV.clear
+ * ENV.empty? # => true
+ * ENV['foo'] = '0'
+ * ENV.empty? # => false
*/
static VALUE
-env_empty_p(void)
+env_empty_p(VALUE _)
{
char **env;
@@ -4115,12 +6028,28 @@ env_empty_p(void)
/*
* call-seq:
- * ENV.key?(name) -> true or false
* ENV.include?(name) -> true or false
* ENV.has_key?(name) -> true or false
* ENV.member?(name) -> true or false
+ * ENV.key?(name) -> true or false
*
- * Returns +true+ if there is an environment variable with the given +name+.
+ * ENV.has_key?, ENV.member?, and ENV.key? are aliases for ENV.include?.
+ *
+ * Returns +true+ if there is an environment variable with the given +name+:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.include?('foo') # => true
+ * Returns +false+ if +name+ is a valid String and there is no such environment variable:
+ * ENV.include?('baz') # => false
+ * Returns +false+ if +name+ is the empty String or is a String containing character <code>'='</code>:
+ * ENV.include?('') # => false
+ * ENV.include?('=') # => false
+ * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
+ * ENV.include?("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
+ * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
+ * ENV.include?("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
+ * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
+ * Raises an exception if +name+ is not a String:
+ * ENV.include?(Object.new) # TypeError (no implicit conversion of Object into String)
*/
static VALUE
env_has_key(VALUE env, VALUE key)
@@ -4134,10 +6063,23 @@ env_has_key(VALUE env, VALUE key)
/*
* call-seq:
- * ENV.assoc(name) -> Array or nil
- *
- * Returns an Array of the name and value of the environment variable with
- * +name+ or +nil+ if the name cannot be found.
+ * ENV.assoc(name) -> [name, value] or nil
+ *
+ * Returns a 2-element Array containing the name and value of the environment variable
+ * for +name+ if it exists:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.assoc('foo') # => ['foo', '0']
+ * Returns +nil+ if +name+ is a valid String and there is no such environment variable.
+ *
+ * Returns +nil+ if +name+ is the empty String or is a String containing character <code>'='</code>.
+ *
+ * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
+ * ENV.assoc("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
+ * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
+ * ENV.assoc("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
+ * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
+ * Raises an exception if +name+ is not a String:
+ * ENV.assoc(Object.new) # TypeError (no implicit conversion of Object into String)
*/
static VALUE
env_assoc(VALUE env, VALUE key)
@@ -4152,10 +6094,15 @@ env_assoc(VALUE env, VALUE key)
/*
* call-seq:
- * ENV.value?(value) -> true or false
+ * ENV.value?(value) -> true or false
* ENV.has_value?(value) -> true or false
*
- * Returns +true+ if there is an environment variable with the given +value+.
+ * Returns +true+ if +value+ is the value for some environment variable name, +false+ otherwise:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.value?('0') # => true
+ * ENV.has_value?('0') # => true
+ * ENV.value?('2') # => false
+ * ENV.has_value?('2') # => false
*/
static VALUE
env_has_value(VALUE dmy, VALUE obj)
@@ -4164,7 +6111,6 @@ env_has_value(VALUE dmy, VALUE obj)
obj = rb_check_string_type(obj);
if (NIL_P(obj)) return Qnil;
- rb_check_safe_obj(obj);
env = GET_ENVIRON(environ);
while (*env) {
char *s = strchr(*env, '=');
@@ -4183,10 +6129,17 @@ env_has_value(VALUE dmy, VALUE obj)
/*
* call-seq:
- * ENV.rassoc(value)
+ * ENV.rassoc(value) -> [name, value] or nil
+ *
+ * Returns a 2-element Array containing the name and value of the
+ * *first* *found* environment variable that has value +value+, if one
+ * exists:
+ * ENV.replace('foo' => '0', 'bar' => '0')
+ * ENV.rassoc('0') # => ["bar", "0"]
+ * The order in which environment variables are examined is OS-dependent.
+ * See {About Ordering}[#class-ENV-label-About+Ordering].
*
- * Returns an Array of the name and value of the environment variable with
- * +value+ or +nil+ if the value cannot be found.
+ * Returns +nil+ if there is no such environment variable.
*/
static VALUE
env_rassoc(VALUE dmy, VALUE obj)
@@ -4195,14 +6148,13 @@ env_rassoc(VALUE dmy, VALUE obj)
obj = rb_check_string_type(obj);
if (NIL_P(obj)) return Qnil;
- rb_check_safe_obj(obj);
env = GET_ENVIRON(environ);
while (*env) {
char *s = strchr(*env, '=');
if (s++) {
long len = strlen(s);
if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
- VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
+ VALUE result = rb_assoc_new(rb_str_new(*env, s-*env-1), obj);
FREE_ENVIRON(environ);
return result;
}
@@ -4215,10 +6167,19 @@ env_rassoc(VALUE dmy, VALUE obj)
/*
* call-seq:
- * ENV.key(value) -> name
+ * ENV.key(value) -> name or nil
+ *
+ * Returns the name of the first environment variable with +value+, if it exists:
+ * ENV.replace('foo' => '0', 'bar' => '0')
+ * ENV.key('0') # => "foo"
+ * The order in which environment variables are examined is OS-dependent.
+ * See {About Ordering}[#class-ENV-label-About+Ordering].
+ *
+ * Returns +nil+ if there is no such value.
*
- * Returns the name of the environment variable with +value+. If the value is
- * not found +nil+ is returned.
+ * Raises an exception if +value+ is invalid:
+ * ENV.key(Object.new) # raises TypeError (no implicit conversion of Object into String)
+ * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
*/
static VALUE
env_key(VALUE dmy, VALUE value)
@@ -4244,27 +6205,6 @@ env_key(VALUE dmy, VALUE value)
return Qnil;
}
-/*
- * call-seq:
- * ENV.index(value) -> key
- *
- * Deprecated method that is equivalent to ENV.key
- */
-static VALUE
-env_index(VALUE dmy, VALUE value)
-{
- rb_warn("ENV.index is deprecated; use ENV.key");
- return env_key(dmy, value);
-}
-
-/*
- * call-seq:
- * ENV.to_hash -> hash
- * ENV.to_h -> hash
- *
- * Creates a hash with a copy of the environment variables.
- *
- */
static VALUE
env_to_hash(void)
{
@@ -4287,27 +6227,123 @@ env_to_hash(void)
/*
* call-seq:
- * ENV.reject { |name, value| } -> Hash
- * ENV.reject -> Enumerator
+ * ENV.to_hash -> hash of name/value pairs
+ *
+ * Returns a Hash containing all name/value pairs from ENV:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
+ */
+
+static VALUE
+env_f_to_hash(VALUE _)
+{
+ return env_to_hash();
+}
+
+/*
+ * call-seq:
+ * ENV.to_h -> hash of name/value pairs
+ * ENV.to_h {|name, value| block } -> hash of name/value pairs
+ *
+ * With no block, returns a Hash containing all name/value pairs from ENV:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.to_h # => {"bar"=>"1", "foo"=>"0"}
+ * With a block, returns a Hash whose items are determined by the block.
+ * Each name/value pair in ENV is yielded to the block.
+ * The block must return a 2-element Array (name/value pair)
+ * that is added to the return Hash as a key and value:
+ * ENV.to_h { |name, value| [name.to_sym, value.to_i] } # => {:bar=>1, :foo=>0}
+ * Raises an exception if the block does not return an Array:
+ * ENV.to_h { |name, value| name } # Raises TypeError (wrong element type String (expected array))
+ * Raises an exception if the block returns an Array of the wrong size:
+ * ENV.to_h { |name, value| [name] } # Raises ArgumentError (element has wrong array length (expected 2, was 1))
+ */
+static VALUE
+env_to_h(VALUE _)
+{
+ VALUE hash = env_to_hash();
+ if (rb_block_given_p()) {
+ hash = rb_hash_to_h_block(hash);
+ }
+ return hash;
+}
+
+/*
+ * call-seq:
+ * ENV.except(*keys) -> a_hash
+ *
+ * Returns a hash except the given keys from ENV and their values.
*
- * Same as ENV#delete_if, but works on (and returns) a copy of the
- * environment.
+ * ENV #=> {"LANG"=>"en_US.UTF-8", "TERM"=>"xterm-256color", "HOME"=>"/Users/rhc"}
+ * ENV.except("TERM","HOME") #=> {"LANG"=>"en_US.UTF-8"}
*/
static VALUE
-env_reject(void)
+env_except(int argc, VALUE *argv, VALUE _)
+{
+ int i;
+ VALUE key, hash = env_to_hash();
+
+ for (i = 0; i < argc; i++) {
+ key = argv[i];
+ rb_hash_delete(hash, key);
+ }
+
+ return hash;
+}
+
+/*
+ * call-seq:
+ * ENV.reject { |name, value| block } -> hash of name/value pairs
+ * ENV.reject -> an_enumerator
+ *
+ * Yields each environment variable name and its value as a 2-element Array.
+ * Returns a Hash whose items are determined by the block.
+ * When the block returns a truthy value, the name/value pair is added to the return Hash;
+ * otherwise the pair is ignored:
+ * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
+ * ENV.reject { |name, value| name.start_with?('b') } # => {"foo"=>"0"}
+ * Returns an Enumerator if no block given:
+ * e = ENV.reject
+ * e.each { |name, value| name.start_with?('b') } # => {"foo"=>"0"}
+ */
+static VALUE
+env_reject(VALUE _)
{
return rb_hash_delete_if(env_to_hash());
}
+NORETURN(static VALUE env_freeze(VALUE self));
/*
* call-seq:
- * ENV.shift -> Array or nil
+ * ENV.freeze
*
- * Removes an environment variable name-value pair from ENV and returns it as
- * an Array. Returns +nil+ if when the environment is empty.
+ * Raises an exception:
+ * ENV.freeze # Raises TypeError (cannot freeze ENV)
+ */
+static VALUE
+env_freeze(VALUE self)
+{
+ rb_raise(rb_eTypeError, "cannot freeze ENV");
+ UNREACHABLE_RETURN(self);
+}
+
+/*
+ * call-seq:
+ * ENV.shift -> [name, value] or nil
+ *
+ * Removes the first environment variable from ENV and returns
+ * a 2-element Array containing its name and value:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.to_hash # => {'bar' => '1', 'foo' => '0'}
+ * ENV.shift # => ['bar', '1']
+ * ENV.to_hash # => {'foo' => '0'}
+ * Exactly which environment variable is "first" is OS-dependent.
+ * See {About Ordering}[#class-ENV-label-About+Ordering].
+ *
+ * Returns +nil+ if the environment is empty.
*/
static VALUE
-env_shift(void)
+env_shift(VALUE _)
{
char **env;
VALUE result = Qnil;
@@ -4318,7 +6354,7 @@ env_shift(void)
if (s) {
VALUE key = env_str_new(*env, s-*env);
VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
- env_delete(Qnil, key);
+ env_delete(key);
result = rb_assoc_new(key, val);
}
}
@@ -4328,33 +6364,71 @@ env_shift(void)
/*
* call-seq:
- * ENV.invert -> Hash
- *
- * Returns a new hash created by using environment variable names as values
- * and values as names.
+ * ENV.invert -> hash of value/name pairs
+ *
+ * Returns a Hash whose keys are the ENV values,
+ * and whose values are the corresponding ENV names:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.invert # => {"1"=>"bar", "0"=>"foo"}
+ * For a duplicate ENV value, overwrites the hash entry:
+ * ENV.replace('foo' => '0', 'bar' => '0')
+ * ENV.invert # => {"0"=>"foo"}
+ * Note that the order of the ENV processing is OS-dependent,
+ * which means that the order of overwriting is also OS-dependent.
+ * See {About Ordering}[#class-ENV-label-About+Ordering].
*/
static VALUE
-env_invert(void)
+env_invert(VALUE _)
{
return rb_hash_invert(env_to_hash());
}
+static void
+keylist_delete(VALUE keys, VALUE key)
+{
+ long keylen, elen;
+ const char *keyptr, *eptr;
+ RSTRING_GETMEM(key, keyptr, keylen);
+ /* Don't stop at first key, as it is possible to have
+ multiple environment values with the same key.
+ */
+ for (long i=0; i<RARRAY_LEN(keys); i++) {
+ VALUE e = RARRAY_AREF(keys, i);
+ RSTRING_GETMEM(e, eptr, elen);
+ if (elen != keylen) continue;
+ if (!ENVNMATCH(keyptr, eptr, elen)) continue;
+ rb_ary_delete_at(keys, i);
+ i--;
+ }
+}
+
static int
env_replace_i(VALUE key, VALUE val, VALUE keys)
{
- env_aset(Qnil, key, val);
- if (rb_ary_includes(keys, key)) {
- rb_ary_delete(keys, key);
- }
+ env_name(key);
+ env_aset(key, val);
+
+ keylist_delete(keys, key);
return ST_CONTINUE;
}
/*
* call-seq:
- * ENV.replace(hash) -> env
+ * ENV.replace(hash) -> ENV
+ *
+ * Replaces the entire content of the environment variables
+ * with the name/value pairs in the given +hash+;
+ * returns ENV.
+ *
+ * Replaces the content of ENV with the given pairs:
+ * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
+ * ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
*
- * Replaces the contents of the environment variables with the contents of
- * +hash+.
+ * Raises an exception if a name or value is invalid
+ * (see {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values]):
+ * ENV.replace('foo' => '0', :bar => '1') # Raises TypeError (no implicit conversion of Symbol into String)
+ * ENV.replace('foo' => '0', 'bar' => 1) # Raises TypeError (no implicit conversion of Integer into String)
+ * ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
*/
static VALUE
env_replace(VALUE env, VALUE hash)
@@ -4362,121 +6436,303 @@ env_replace(VALUE env, VALUE hash)
VALUE keys;
long i;
- keys = env_keys();
+ keys = env_keys(TRUE);
if (env == hash) return env;
hash = to_hash(hash);
rb_hash_foreach(hash, env_replace_i, keys);
for (i=0; i<RARRAY_LEN(keys); i++) {
- env_delete(env, RARRAY_AREF(keys, i));
+ env_delete(RARRAY_AREF(keys, i));
}
RB_GC_GUARD(keys);
return env;
}
static int
-env_update_i(VALUE key, VALUE val)
+env_update_i(VALUE key, VALUE val, VALUE _)
{
- if (rb_block_given_p()) {
- val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
+ env_aset(key, val);
+ return ST_CONTINUE;
+}
+
+static int
+env_update_block_i(VALUE key, VALUE val, VALUE _)
+{
+ VALUE oldval = rb_f_getenv(Qnil, key);
+ if (!NIL_P(oldval)) {
+ val = rb_yield_values(3, key, oldval, val);
}
- env_aset(Qnil, key, val);
+ env_aset(key, val);
return ST_CONTINUE;
}
/*
* call-seq:
- * ENV.update(hash) -> Hash
- * ENV.update(hash) { |name, old_value, new_value| } -> Hash
- *
- * Adds the contents of +hash+ to the environment variables. If no block is
- * specified entries with duplicate keys are overwritten, otherwise the value
- * of each duplicate name is determined by calling the block with the key, its
- * value from the environment and its value from the hash.
+ * ENV.update(hash) -> ENV
+ * ENV.update(hash) { |name, env_val, hash_val| block } -> ENV
+ * ENV.merge!(hash) -> ENV
+ * ENV.merge!(hash) { |name, env_val, hash_val| block } -> ENV
+ *
+ * ENV.update is an alias for ENV.merge!.
+ *
+ * Adds to ENV each key/value pair in the given +hash+; returns ENV:
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.merge!('baz' => '2', 'bat' => '3') # => {"bar"=>"1", "bat"=>"3", "baz"=>"2", "foo"=>"0"}
+ * Deletes the ENV entry for a hash value that is +nil+:
+ * ENV.merge!('baz' => nil, 'bat' => nil) # => {"bar"=>"1", "foo"=>"0"}
+ * For an already-existing name, if no block given, overwrites the ENV value:
+ * ENV.merge!('foo' => '4') # => {"bar"=>"1", "foo"=>"4"}
+ * For an already-existing name, if block given,
+ * yields the name, its ENV value, and its hash value;
+ * the block's return value becomes the new name:
+ * ENV.merge!('foo' => '5') { |name, env_val, hash_val | env_val + hash_val } # => {"bar"=>"1", "foo"=>"45"}
+ * Raises an exception if a name or value is invalid
+ * (see {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values]);
+ * ENV.replace('foo' => '0', 'bar' => '1')
+ * ENV.merge!('foo' => '6', :bar => '7', 'baz' => '9') # Raises TypeError (no implicit conversion of Symbol into String)
+ * ENV # => {"bar"=>"1", "foo"=>"6"}
+ * ENV.merge!('foo' => '7', 'bar' => 8, 'baz' => '9') # Raises TypeError (no implicit conversion of Integer into String)
+ * ENV # => {"bar"=>"1", "foo"=>"7"}
+ * Raises an exception if the block returns an invalid name:
+ * (see {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values]):
+ * ENV.merge!('bat' => '8', 'foo' => '9') { |name, env_val, hash_val | 10 } # Raises TypeError (no implicit conversion of Integer into String)
+ * ENV # => {"bar"=>"1", "bat"=>"8", "foo"=>"7"}
+ *
+ * Note that for the exceptions above,
+ * hash pairs preceding an invalid name or value are processed normally;
+ * those following are ignored.
*/
static VALUE
env_update(VALUE env, VALUE hash)
{
if (env == hash) return env;
hash = to_hash(hash);
- rb_hash_foreach(hash, env_update_i, 0);
+ rb_foreach_func *func = rb_block_given_p() ?
+ env_update_block_i : env_update_i;
+ rb_hash_foreach(hash, func, 0);
return env;
}
/*
- * A Hash is a dictionary-like collection of unique keys and their values.
- * Also called associative arrays, they are similar to Arrays, but where an
- * Array uses integers as its index, a Hash allows you to use any object
- * type.
+ * A \Hash maps each of its unique keys to a specific value.
*
- * Hashes enumerate their values in the order that the corresponding keys
- * were inserted.
+ * A \Hash has certain similarities to an \Array, but:
+ * - An \Array index is always an \Integer.
+ * - A \Hash key can be (almost) any object.
*
- * A Hash can be easily created by using its implicit form:
+ * === \Hash \Data Syntax
*
- * grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
+ * The older syntax for \Hash data uses the "hash rocket," <tt>=></tt>:
*
- * Hashes allow an alternate syntax for keys that are symbols.
- * Instead of
+ * h = {:foo => 0, :bar => 1, :baz => 2}
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
*
- * options = { :font_size => 10, :font_family => "Arial" }
+ * Alternatively, but only for a \Hash key that's a \Symbol,
+ * you can use a newer JSON-style syntax,
+ * where each bareword becomes a \Symbol:
*
- * You could write it as:
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
*
- * options = { font_size: 10, font_family: "Arial" }
+ * You can also use a \String in place of a bareword:
*
- * Each named key is a symbol you can access in hash:
+ * h = {'foo': 0, 'bar': 1, 'baz': 2}
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
*
- * options[:font_size] # => 10
+ * And you can mix the styles:
*
- * A Hash can also be created through its ::new method:
+ * h = {foo: 0, :bar => 1, 'baz': 2}
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
*
- * grades = Hash.new
- * grades["Dorothy Doe"] = 9
+ * But it's an error to try the JSON-style syntax
+ * for a key that's not a bareword or a String:
*
- * Hashes have a <em>default value</em> that is returned when accessing
- * keys that do not exist in the hash. If no default is set +nil+ is used.
- * You can set the default value by sending it as an argument to Hash.new:
+ * # Raises SyntaxError (syntax error, unexpected ':', expecting =>):
+ * h = {0: 'zero'}
*
- * grades = Hash.new(0)
+ * === Common Uses
*
- * Or by using the #default= method:
+ * You can use a \Hash to give names to objects:
*
- * grades = {"Timmy Doe" => 8}
- * grades.default = 0
+ * person = {name: 'Matz', language: 'Ruby'}
+ * person # => {:name=>"Matz", :language=>"Ruby"}
*
- * Accessing a value in a Hash requires using its key:
+ * You can use a \Hash to give names to method arguments:
*
- * puts grades["Jane Doe"] # => 0
+ * def some_method(hash)
+ * p hash
+ * end
+ * some_method({foo: 0, bar: 1, baz: 2}) # => {:foo=>0, :bar=>1, :baz=>2}
*
- * === Common Uses
+ * Note: when the last argument in a method call is a \Hash,
+ * the curly braces may be omitted:
*
- * Hashes are an easy way to represent data structures, such as
+ * some_method(foo: 0, bar: 1, baz: 2) # => {:foo=>0, :bar=>1, :baz=>2}
*
- * books = {}
- * books[:matz] = "The Ruby Programming Language"
- * books[:black] = "The Well-Grounded Rubyist"
+ * You can use a \Hash to initialize an object:
*
- * Hashes are also commonly used as a way to have named parameters in
- * functions. Note that no brackets are used below. If a hash is the last
- * argument on a method call, no braces are needed, thus creating a really
- * clean interface:
+ * class Dev
+ * attr_accessor :name, :language
+ * def initialize(hash)
+ * self.name = hash[:name]
+ * self.language = hash[:language]
+ * end
+ * end
+ * matz = Dev.new(name: 'Matz', language: 'Ruby')
+ * matz # => #<Dev: @name="Matz", @language="Ruby">
*
- * Person.create(name: "John Doe", age: 27)
+ * === Creating a \Hash
+ *
+ * Here are three ways to create a \Hash:
+ *
+ * - \Method <tt>Hash.new</tt>
+ * - \Method <tt>Hash[]</tt>
+ * - Literal form: <tt>{}</tt>.
+ *
+ * ---
+ *
+ * You can create a \Hash by calling method Hash.new.
+ *
+ * Create an empty Hash:
+ *
+ * h = Hash.new
+ * h # => {}
+ * h.class # => Hash
+ *
+ * ---
+ *
+ * You can create a \Hash by calling method Hash.[].
+ *
+ * Create an empty Hash:
+ *
+ * h = Hash[]
+ * h # => {}
+ *
+ * Create a \Hash with initial entries:
+ *
+ * h = Hash[foo: 0, bar: 1, baz: 2]
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
+ *
+ * ---
+ *
+ * You can create a \Hash by using its literal form (curly braces).
+ *
+ * Create an empty \Hash:
+ *
+ * h = {}
+ * h # => {}
+ *
+ * Create a \Hash with initial entries:
+ *
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
*
- * def self.create(params)
- * @name = params[:name]
- * @age = params[:age]
- * end
*
- * === Hash Keys
+ * === \Hash Value Basics
*
- * Two objects refer to the same hash key when their <code>hash</code> value
+ * The simplest way to retrieve a \Hash value (instance method #[]):
+ *
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h[:foo] # => 0
+ *
+ * The simplest way to create or update a \Hash value (instance method #[]=):
+ *
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h[:bat] = 3 # => 3
+ * h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
+ * h[:foo] = 4 # => 4
+ * h # => {:foo=>4, :bar=>1, :baz=>2, :bat=>3}
+ *
+ * The simplest way to delete a \Hash entry (instance method #delete):
+ *
+ * h = {foo: 0, bar: 1, baz: 2}
+ * h.delete(:bar) # => 1
+ * h # => {:foo=>0, :baz=>2}
+ *
+ * === Entry Order
+ *
+ * A \Hash object presents its entries in the order of their creation. This is seen in:
+ *
+ * - Iterative methods such as <tt>each</tt>, <tt>each_key</tt>, <tt>each_pair</tt>, <tt>each_value</tt>.
+ * - Other order-sensitive methods such as <tt>shift</tt>, <tt>keys</tt>, <tt>values</tt>.
+ * - The \String returned by method <tt>inspect</tt>.
+ *
+ * A new \Hash has its initial ordering per the given entries:
+ *
+ * h = Hash[foo: 0, bar: 1]
+ * h # => {:foo=>0, :bar=>1}
+ *
+ * New entries are added at the end:
+ *
+ * h[:baz] = 2
+ * h # => {:foo=>0, :bar=>1, :baz=>2}
+ *
+ * Updating a value does not affect the order:
+ *
+ * h[:baz] = 3
+ * h # => {:foo=>0, :bar=>1, :baz=>3}
+ *
+ * But re-creating a deleted entry can affect the order:
+ *
+ * h.delete(:foo)
+ * h[:foo] = 5
+ * h # => {:bar=>1, :baz=>3, :foo=>5}
+ *
+ * === \Hash Keys
+ *
+ * ==== \Hash Key Equivalence
+ *
+ * Two objects are treated as the same \hash key when their <code>hash</code> value
* is identical and the two objects are <code>eql?</code> to each other.
*
- * A user-defined class may be used as a hash key if the <code>hash</code>
- * and <code>eql?</code> methods are overridden to provide meaningful
- * behavior. By default, separate instances refer to separate hash keys.
+ * ==== Modifying an Active \Hash Key
+ *
+ * Modifying a \Hash key while it is in use damages the hash's index.
+ *
+ * This \Hash has keys that are Arrays:
+ *
+ * a0 = [ :foo, :bar ]
+ * a1 = [ :baz, :bat ]
+ * h = {a0 => 0, a1 => 1}
+ * h.include?(a0) # => true
+ * h[a0] # => 0
+ * a0.hash # => 110002110
+ *
+ * Modifying array element <tt>a0[0]</tt> changes its hash value:
+ *
+ * a0[0] = :bam
+ * a0.hash # => 1069447059
+ *
+ * And damages the \Hash index:
+ *
+ * h.include?(a0) # => false
+ * h[a0] # => nil
+ *
+ * You can repair the hash index using method +rehash+:
+ *
+ * h.rehash # => {[:bam, :bar]=>0, [:baz, :bat]=>1}
+ * h.include?(a0) # => true
+ * h[a0] # => 0
+ *
+ * A \String key is always safe.
+ * That's because an unfrozen \String
+ * passed as a key will be replaced by a duplicated and frozen \String:
+ *
+ * s = 'foo'
+ * s.frozen? # => false
+ * h = {s => 0}
+ * first_key = h.keys.first
+ * first_key.frozen? # => true
+ *
+ * ==== User-Defined \Hash Keys
+ *
+ * To be useable as a \Hash key, objects must implement the methods <code>hash</code> and <code>eql?</code>.
+ * Note: this requirement does not apply if the \Hash uses #compare_by_id since comparison will then rely on
+ * the keys' object id instead of <code>hash</code> and <code>eql?</code>.
+ *
+ * \Object defines basic implementation for <code>hash</code> and <code>eq?</code> that makes each object
+ * a distinct key. Typically, user-defined classes will want to override these methods to provide meaningful
+ * behavior, or for example inherit \Struct that has useful definitions for these.
*
* A typical implementation of <code>hash</code> is based on the
* object's data while <code>eql?</code> is usually aliased to the overridden
@@ -4491,8 +6747,8 @@ env_update(VALUE env, VALUE hash)
* end
*
* def ==(other)
- * self.class === other and
- * other.author == @author and
+ * self.class === other &&
+ * other.author == @author &&
* other.title == @title
* end
*
@@ -4513,19 +6769,98 @@ env_update(VALUE env, VALUE hash)
*
* reviews.length #=> 1
*
- * See also Object#hash and Object#eql?
+ * === Default Values
+ *
+ * The methods #[], #values_at and #dig need to return the value associated to a certain key.
+ * When that key is not found, that value will be determined by its default proc (if any)
+ * or else its default (initially `nil`).
+ *
+ * You can retrieve the default value with method #default:
+ *
+ * h = Hash.new
+ * h.default # => nil
+ *
+ * You can set the default value by passing an argument to method Hash.new or
+ * with method #default=
+ *
+ * h = Hash.new(-1)
+ * h.default # => -1
+ * h.default = 0
+ * h.default # => 0
+ *
+ * This default value is returned for #[], #values_at and #dig when a key is
+ * not found:
+ *
+ * counts = {foo: 42}
+ * counts.default # => nil (default)
+ * counts[:foo] = 42
+ * counts[:bar] # => nil
+ * counts.default = 0
+ * counts[:bar] # => 0
+ * counts.values_at(:foo, :bar, :baz) # => [42, 0, 0]
+ * counts.dig(:bar) # => 0
+ *
+ * Note that the default value is used without being duplicated. It is not advised to set
+ * the default value to a mutable object:
+ *
+ * synonyms = Hash.new([])
+ * synonyms[:hello] # => []
+ * synonyms[:hello] << :hi # => [:hi], but this mutates the default!
+ * synonyms.default # => [:hi]
+ * synonyms[:world] << :universe
+ * synonyms[:world] # => [:hi, :universe], oops
+ * synonyms.keys # => [], oops
+ *
+ * To use a mutable object as default, it is recommended to use a default proc
+ *
+ * ==== Default \Proc
+ *
+ * When the default proc for a \Hash is set (i.e., not +nil+),
+ * the default value returned by method #[] is determined by the default proc alone.
+ *
+ * You can retrieve the default proc with method #default_proc:
+ *
+ * h = Hash.new
+ * h.default_proc # => nil
+ *
+ * You can set the default proc by calling Hash.new with a block or
+ * calling the method #default_proc=
+ *
+ * h = Hash.new { |hash, key| "Default value for #{key}" }
+ * h.default_proc.class # => Proc
+ * h.default_proc = proc { |hash, key| "Default value for #{key.inspect}" }
+ * h.default_proc.class # => Proc
+ *
+ * When the default proc is set (i.e., not +nil+)
+ * and method #[] is called with with a non-existent key,
+ * #[] calls the default proc with both the \Hash object itself and the missing key,
+ * then returns the proc's return value:
+ *
+ * h = Hash.new { |hash, key| "Default value for #{key}" }
+ * h[:nosuch] # => "Default value for nosuch"
+ *
+ * Note that in the example above no entry for key +:nosuch+ is created:
+ *
+ * h.include?(:nosuch) # => false
+ *
+ * However, the proc itself can add a new entry:
+ *
+ * synonyms = Hash.new { |hash, key| hash[key] = [] }
+ * synonyms.include?(:hello) # => false
+ * synonyms[:hello] << :hi # => [:hi]
+ * synonyms[:world] << :universe # => [:universe]
+ * synonyms.keys # => [:hello, :world]
+ *
+ * Note that setting the default proc will clear the default value and vice versa.
*/
void
Init_Hash(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
- id_hash = rb_intern("hash");
- id_yield = rb_intern("yield");
- id_default = rb_intern("default");
- id_flatten_bang = rb_intern("flatten!");
+ id_hash = rb_intern_const("hash");
+ id_default = rb_intern_const("default");
+ id_flatten_bang = rb_intern_const("flatten!");
+ id_hash_iter_lev = rb_make_internal_id();
rb_cHash = rb_define_class("Hash", rb_cObject);
@@ -4535,7 +6870,7 @@ Init_Hash(void)
rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
rb_define_method(rb_cHash, "initialize", rb_hash_initialize, -1);
- rb_define_method(rb_cHash, "initialize_copy", rb_hash_initialize_copy, 1);
+ rb_define_method(rb_cHash, "initialize_copy", rb_hash_replace, 1);
rb_define_method(rb_cHash, "rehash", rb_hash_rehash, 0);
rb_define_method(rb_cHash, "to_hash", rb_hash_to_hash, 0);
@@ -4557,7 +6892,6 @@ Init_Hash(void)
rb_define_method(rb_cHash, "default_proc", rb_hash_default_proc, 0);
rb_define_method(rb_cHash, "default_proc=", rb_hash_set_default_proc, 1);
rb_define_method(rb_cHash, "key", rb_hash_key, 1);
- rb_define_method(rb_cHash, "index", rb_hash_index, 1);
rb_define_method(rb_cHash, "size", rb_hash_size, 0);
rb_define_method(rb_cHash, "length", rb_hash_size, 0);
rb_define_method(rb_cHash, "empty?", rb_hash_empty_p, 0);
@@ -4567,8 +6901,8 @@ Init_Hash(void)
rb_define_method(rb_cHash, "each_pair", rb_hash_each_pair, 0);
rb_define_method(rb_cHash, "each", rb_hash_each_pair, 0);
- rb_define_method(rb_cHash, "transform_keys", rb_hash_transform_keys, 0);
- rb_define_method(rb_cHash, "transform_keys!", rb_hash_transform_keys_bang, 0);
+ rb_define_method(rb_cHash, "transform_keys", rb_hash_transform_keys, -1);
+ rb_define_method(rb_cHash, "transform_keys!", rb_hash_transform_keys_bang, -1);
rb_define_method(rb_cHash, "transform_values", rb_hash_transform_values, 0);
rb_define_method(rb_cHash, "transform_values!", rb_hash_transform_values_bang, 0);
@@ -4583,14 +6917,18 @@ Init_Hash(void)
rb_define_method(rb_cHash, "keep_if", rb_hash_keep_if, 0);
rb_define_method(rb_cHash, "select", rb_hash_select, 0);
rb_define_method(rb_cHash, "select!", rb_hash_select_bang, 0);
+ rb_define_method(rb_cHash, "filter", rb_hash_select, 0);
+ rb_define_method(rb_cHash, "filter!", rb_hash_select_bang, 0);
rb_define_method(rb_cHash, "reject", rb_hash_reject, 0);
rb_define_method(rb_cHash, "reject!", rb_hash_reject_bang, 0);
+ rb_define_method(rb_cHash, "slice", rb_hash_slice, -1);
+ rb_define_method(rb_cHash, "except", rb_hash_except, -1);
rb_define_method(rb_cHash, "clear", rb_hash_clear, 0);
rb_define_method(rb_cHash, "invert", rb_hash_invert, 0);
- rb_define_method(rb_cHash, "update", rb_hash_update, 1);
+ rb_define_method(rb_cHash, "update", rb_hash_update, -1);
rb_define_method(rb_cHash, "replace", rb_hash_replace, 1);
- rb_define_method(rb_cHash, "merge!", rb_hash_update, 1);
- rb_define_method(rb_cHash, "merge", rb_hash_merge, 1);
+ rb_define_method(rb_cHash, "merge!", rb_hash_update, -1);
+ rb_define_method(rb_cHash, "merge", rb_hash_merge, -1);
rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
@@ -4607,7 +6945,7 @@ Init_Hash(void)
rb_define_method(rb_cHash, "compare_by_identity", rb_hash_compare_by_id, 0);
rb_define_method(rb_cHash, "compare_by_identity?", rb_hash_compare_by_id_p, 0);
- rb_define_method(rb_cHash, "any?", rb_hash_any_p, 0);
+ rb_define_method(rb_cHash, "any?", rb_hash_any_p, -1);
rb_define_method(rb_cHash, "dig", rb_hash_dig, -1);
rb_define_method(rb_cHash, "<=", rb_hash_le, 1);
@@ -4615,9 +6953,89 @@ Init_Hash(void)
rb_define_method(rb_cHash, ">=", rb_hash_ge, 1);
rb_define_method(rb_cHash, ">", rb_hash_gt, 1);
+ rb_define_method(rb_cHash, "deconstruct_keys", rb_hash_deconstruct_keys, 1);
+
+ rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash?", rb_hash_s_ruby2_keywords_hash_p, 1);
+ rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash", rb_hash_s_ruby2_keywords_hash, 1);
+
/* Document-class: ENV
*
* ENV is a hash-like accessor for environment variables.
+ *
+ * === Interaction with the Operating System
+ *
+ * The ENV object interacts with the operating system's environment variables:
+ *
+ * - When you get the value for a name in ENV, the value is retrieved from among the current environment variables.
+ * - When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.
+ * - When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.
+ *
+ * === Names and Values
+ *
+ * Generally, a name or value is a String.
+ *
+ * ==== Valid Names and Values
+ *
+ * Each name or value must be one of the following:
+ *
+ * - A String.
+ * - An object that responds to \#to_str by returning a String, in which case that String will be used as the name or value.
+ *
+ * ==== Invalid Names and Values
+ *
+ * A new name:
+ *
+ * - May not be the empty string:
+ * ENV[''] = '0'
+ * # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
+ *
+ * - May not contain character <code>"="</code>:
+ * ENV['='] = '0'
+ * # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))
+ *
+ * A new name or value:
+ *
+ * - May not be a non-String that does not respond to \#to_str:
+ *
+ * ENV['foo'] = Object.new
+ * # Raises TypeError (no implicit conversion of Object into String)
+ * ENV[Object.new] = '0'
+ * # Raises TypeError (no implicit conversion of Object into String)
+ *
+ * - May not contain the NUL character <code>"\0"</code>:
+ *
+ * ENV['foo'] = "\0"
+ * # Raises ArgumentError (bad environment variable value: contains null byte)
+ * ENV["\0"] == '0'
+ * # Raises ArgumentError (bad environment variable name: contains null byte)
+ *
+ * - May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:
+ *
+ * ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP)
+ * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
+ * ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0'
+ * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
+ *
+ * === About Ordering
+ *
+ * ENV enumerates its name/value pairs in the order found
+ * in the operating system's environment variables.
+ * Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.
+ *
+ * This will be seen in:
+ * - A Hash returned by an ENV method.
+ * - An Enumerator returned by an ENV method.
+ * - An Array returned by ENV.keys, ENV.values, or ENV.to_a.
+ * - The String returned by ENV.inspect.
+ * - The Array returned by ENV.shift.
+ * - The name returned by ENV.key.
+ *
+ * === About the Examples
+ * Some methods in ENV return ENV itself. Typically, there are many environment variables.
+ * It's not useful to display a large ENV in the examples here,
+ * so most example snippets begin by resetting the contents of ENV:
+ * - ENV.replace replaces ENV with a new collection of entries.
+ * - ENV.clear empties ENV.
*/
/*
@@ -4630,8 +7048,8 @@ Init_Hash(void)
rb_define_singleton_method(envtbl, "[]", rb_f_getenv, 1);
rb_define_singleton_method(envtbl, "fetch", env_fetch, -1);
- rb_define_singleton_method(envtbl, "[]=", env_aset, 2);
- rb_define_singleton_method(envtbl, "store", env_aset, 2);
+ rb_define_singleton_method(envtbl, "[]=", env_aset_m, 2);
+ rb_define_singleton_method(envtbl, "store", env_aset_m, 2);
rb_define_singleton_method(envtbl, "each", env_each_pair, 0);
rb_define_singleton_method(envtbl, "each_pair", env_each_pair, 0);
rb_define_singleton_method(envtbl, "each_key", env_each_key, 0);
@@ -4639,26 +7057,31 @@ Init_Hash(void)
rb_define_singleton_method(envtbl, "delete", env_delete_m, 1);
rb_define_singleton_method(envtbl, "delete_if", env_delete_if, 0);
rb_define_singleton_method(envtbl, "keep_if", env_keep_if, 0);
- rb_define_singleton_method(envtbl, "clear", rb_env_clear, 0);
+ rb_define_singleton_method(envtbl, "slice", env_slice, -1);
+ rb_define_singleton_method(envtbl, "except", env_except, -1);
+ rb_define_singleton_method(envtbl, "clear", env_clear, 0);
rb_define_singleton_method(envtbl, "reject", env_reject, 0);
rb_define_singleton_method(envtbl, "reject!", env_reject_bang, 0);
rb_define_singleton_method(envtbl, "select", env_select, 0);
rb_define_singleton_method(envtbl, "select!", env_select_bang, 0);
+ rb_define_singleton_method(envtbl, "filter", env_select, 0);
+ rb_define_singleton_method(envtbl, "filter!", env_select_bang, 0);
rb_define_singleton_method(envtbl, "shift", env_shift, 0);
+ rb_define_singleton_method(envtbl, "freeze", env_freeze, 0);
rb_define_singleton_method(envtbl, "invert", env_invert, 0);
rb_define_singleton_method(envtbl, "replace", env_replace, 1);
rb_define_singleton_method(envtbl, "update", env_update, 1);
+ rb_define_singleton_method(envtbl, "merge!", env_update, 1);
rb_define_singleton_method(envtbl, "inspect", env_inspect, 0);
rb_define_singleton_method(envtbl, "rehash", env_none, 0);
rb_define_singleton_method(envtbl, "to_a", env_to_a, 0);
rb_define_singleton_method(envtbl, "to_s", env_to_s, 0);
rb_define_singleton_method(envtbl, "key", env_key, 1);
- rb_define_singleton_method(envtbl, "index", env_index, 1);
rb_define_singleton_method(envtbl, "size", env_size, 0);
rb_define_singleton_method(envtbl, "length", env_size, 0);
rb_define_singleton_method(envtbl, "empty?", env_empty_p, 0);
- rb_define_singleton_method(envtbl, "keys", env_keys, 0);
- rb_define_singleton_method(envtbl, "values", env_values, 0);
+ rb_define_singleton_method(envtbl, "keys", env_f_keys, 0);
+ rb_define_singleton_method(envtbl, "values", env_f_values, 0);
rb_define_singleton_method(envtbl, "values_at", env_values_at, -1);
rb_define_singleton_method(envtbl, "include?", env_has_key, 1);
rb_define_singleton_method(envtbl, "member?", env_has_key, 1);
@@ -4666,8 +7089,8 @@ Init_Hash(void)
rb_define_singleton_method(envtbl, "has_value?", env_has_value, 1);
rb_define_singleton_method(envtbl, "key?", env_has_key, 1);
rb_define_singleton_method(envtbl, "value?", env_has_value, 1);
- rb_define_singleton_method(envtbl, "to_hash", env_to_hash, 0);
- rb_define_singleton_method(envtbl, "to_h", env_to_hash, 0);
+ rb_define_singleton_method(envtbl, "to_hash", env_f_to_hash, 0);
+ rb_define_singleton_method(envtbl, "to_h", env_to_h, 0);
rb_define_singleton_method(envtbl, "assoc", env_assoc, 1);
rb_define_singleton_method(envtbl, "rassoc", env_rassoc, 1);
@@ -4680,4 +7103,6 @@ Init_Hash(void)
/* for callcc */
ruby_register_rollback_func_for_ensure(hash_foreach_ensure, hash_foreach_ensure_rollback);
+
+ HASH_ASSERT(sizeof(ar_hint_t) * RHASH_AR_TABLE_MAX_SIZE == sizeof(VALUE));
}
diff --git a/hrtime.h b/hrtime.h
new file mode 100644
index 0000000000..f133bdb1ac
--- /dev/null
+++ b/hrtime.h
@@ -0,0 +1,168 @@
+#ifndef RB_HRTIME_H
+#define RB_HRTIME_H
+#include "ruby/ruby.h"
+#include <time.h>
+#if defined(HAVE_SYS_TIME_H)
+# include <sys/time.h>
+#endif
+
+/*
+ * Hi-res monotonic clock. It is currently nsec resolution, which has over
+ * 500 years of range (with an unsigned 64-bit integer). Developers
+ * targeting small systems may try 32-bit and low-resolution (milliseconds).
+ *
+ * TBD: Is nsec even necessary? usec resolution seems enough for userspace
+ * and it'll be suitable for use with devices lasting over 500,000 years
+ * (maybe some devices designed for long-term space travel)
+ *
+ * Current API:
+ *
+ * * rb_hrtime_now - current clock value (monotonic if available)
+ * * rb_hrtime_mul - multiply with overflow check
+ * * rb_hrtime_add - add with overflow check
+ * * rb_timeval2hrtime - convert from timeval
+ * * rb_timespec2hrtime - convert from timespec
+ * * rb_msec2hrtime - convert from millisecond
+ * * rb_sec2hrtime - convert from time_t (seconds)
+ * * rb_hrtime2timeval - convert to timeval
+ * * rb_hrtime2timespec - convert to timespec
+ *
+ * Note: no conversion to milliseconds is provided here because different
+ * functions have different limits (e.g. epoll_wait vs w32_wait_events).
+ * So we provide RB_HRTIME_PER_MSEC and similar macros for implementing
+ * this for each use case.
+ */
+#define RB_HRTIME_PER_USEC ((rb_hrtime_t)1000)
+#define RB_HRTIME_PER_MSEC (RB_HRTIME_PER_USEC * (rb_hrtime_t)1000)
+#define RB_HRTIME_PER_SEC (RB_HRTIME_PER_MSEC * (rb_hrtime_t)1000)
+#define RB_HRTIME_MAX UINT64_MAX
+
+/*
+ * Lets try to support time travelers. Lets assume anybody with a time machine
+ * also has access to a modern gcc or clang with 128-bit int support
+ */
+#ifdef MY_RUBY_BUILD_MAY_TIME_TRAVEL
+typedef int128_t rb_hrtime_t;
+#else
+typedef uint64_t rb_hrtime_t;
+#endif
+
+/* thread.c */
+/* returns the value of the monotonic clock (if available) */
+rb_hrtime_t rb_hrtime_now(void);
+
+/*
+ * multiply @a and @b with overflow check and return the
+ * (clamped to RB_HRTIME_MAX) result.
+ */
+static inline rb_hrtime_t
+rb_hrtime_mul(rb_hrtime_t a, rb_hrtime_t b)
+{
+ rb_hrtime_t c;
+
+#ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
+ if (__builtin_mul_overflow(a, b, &c))
+ return RB_HRTIME_MAX;
+#else
+ if (b != 0 && a > RB_HRTIME_MAX / b) /* overflow */
+ return RB_HRTIME_MAX;
+ c = a * b;
+#endif
+ return c;
+}
+
+/*
+ * add @a and @b with overflow check and return the
+ * (clamped to RB_HRTIME_MAX) result.
+ */
+static inline rb_hrtime_t
+rb_hrtime_add(rb_hrtime_t a, rb_hrtime_t b)
+{
+ rb_hrtime_t c;
+
+#ifdef HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW
+ if (__builtin_add_overflow(a, b, &c))
+ return RB_HRTIME_MAX;
+#else
+ c = a + b;
+ if (c < a) /* overflow */
+ return RB_HRTIME_MAX;
+#endif
+ return c;
+}
+
+/*
+ * convert a timeval struct to rb_hrtime_t, clamping at RB_HRTIME_MAX
+ */
+static inline rb_hrtime_t
+rb_timeval2hrtime(const struct timeval *tv)
+{
+ rb_hrtime_t s = rb_hrtime_mul((rb_hrtime_t)tv->tv_sec, RB_HRTIME_PER_SEC);
+ rb_hrtime_t u = rb_hrtime_mul((rb_hrtime_t)tv->tv_usec, RB_HRTIME_PER_USEC);
+
+ return rb_hrtime_add(s, u);
+}
+
+/*
+ * convert a timespec struct to rb_hrtime_t, clamping at RB_HRTIME_MAX
+ */
+static inline rb_hrtime_t
+rb_timespec2hrtime(const struct timespec *ts)
+{
+ rb_hrtime_t s = rb_hrtime_mul((rb_hrtime_t)ts->tv_sec, RB_HRTIME_PER_SEC);
+
+ return rb_hrtime_add(s, (rb_hrtime_t)ts->tv_nsec);
+}
+
+/*
+ * convert a millisecond value to rb_hrtime_t, clamping at RB_HRTIME_MAX
+ */
+static inline rb_hrtime_t
+rb_msec2hrtime(unsigned long msec)
+{
+ return rb_hrtime_mul((rb_hrtime_t)msec, RB_HRTIME_PER_MSEC);
+}
+
+/*
+ * convert a time_t value to rb_hrtime_t, clamping at RB_HRTIME_MAX
+ * Negative values will be clamped at 0.
+ */
+static inline rb_hrtime_t
+rb_sec2hrtime(time_t sec)
+{
+ if (sec <= 0) return 0;
+
+ return rb_hrtime_mul((rb_hrtime_t)sec, RB_HRTIME_PER_SEC);
+}
+
+/*
+ * convert a rb_hrtime_t value to a timespec, suitable for calling
+ * functions like ppoll(2) or kevent(2)
+ */
+static inline struct timespec *
+rb_hrtime2timespec(struct timespec *ts, const rb_hrtime_t *hrt)
+{
+ if (hrt) {
+ ts->tv_sec = (time_t)(*hrt / RB_HRTIME_PER_SEC);
+ ts->tv_nsec = (int32_t)(*hrt % RB_HRTIME_PER_SEC);
+ return ts;
+ }
+ return 0;
+}
+
+/*
+ * convert a rb_hrtime_t value to a timeval, suitable for calling
+ * functions like select(2)
+ */
+static inline struct timeval *
+rb_hrtime2timeval(struct timeval *tv, const rb_hrtime_t *hrt)
+{
+ if (hrt) {
+ tv->tv_sec = (time_t)(*hrt / RB_HRTIME_PER_SEC);
+ tv->tv_usec = (int32_t)((*hrt % RB_HRTIME_PER_SEC)/RB_HRTIME_PER_USEC);
+
+ return tv;
+ }
+ return 0;
+}
+#endif /* RB_HRTIME_H */
diff --git a/ia64.s b/ia64.s
deleted file mode 100644
index 1087105585..0000000000
--- a/ia64.s
+++ /dev/null
@@ -1,42 +0,0 @@
-// rb_ia64_flushrs and rb_ia64_bsp is written in IA64 assembly language
-// because Intel Compiler for IA64 doesn't support inline assembly.
-//
-// This file is based on following C program compiled by gcc.
-//
-// void rb_ia64_flushrs(void) { __builtin_ia64_flushrs(); }
-// void *rb_ia64_bsp(void) { return __builtin_ia64_bsp(); }
-//
-// Note that rb_ia64_flushrs and rb_ia64_bsp works in its own stack frame.
-// It's because BSP is updated by br.call/brl.call (not alloc instruction).
-// So rb_ia64_flushrs flushes stack frames including caller's one.
-// rb_ia64_bsp returns the address next to caller's register stack frame.
-//
-// See also
-// Intel Itanium Architecture Software Developer's Manual
-// Volume 2: System Architecture.
-//
- .file "ia64.c"
- .text
- .align 16
- .global rb_ia64_flushrs#
- .proc rb_ia64_flushrs#
-rb_ia64_flushrs:
- .prologue
- .body
- flushrs
- ;;
- nop.i 0
- br.ret.sptk.many b0
- .endp rb_ia64_flushrs#
- .align 16
- .global rb_ia64_bsp#
- .proc rb_ia64_bsp#
-rb_ia64_bsp:
- .prologue
- .body
- nop.m 0
- ;;
- mov r8 = ar.bsp
- br.ret.sptk.many b0
- .endp rb_ia64_bsp#
- .ident "GCC: (GNU) 3.3.5 (Debian 1:3.3.5-13)"
diff --git a/id_table.c b/id_table.c
index 74c9e756a0..840ab46ee3 100644
--- a/id_table.c
+++ b/id_table.c
@@ -7,6 +7,7 @@
#endif
#if ID_TABLE_DEBUG == 0
+#undef NDEBUG
#define NDEBUG
#endif
#include "ruby_assert.h"
@@ -229,7 +230,7 @@ rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
int index = hash_table_index(tbl, key);
if (index >= 0) {
- *valp = tbl->items[index].val;
+ *valp = tbl->items[index].val;
return TRUE;
}
else {
@@ -267,6 +268,27 @@ rb_id_table_delete(struct rb_id_table *tbl, ID id)
}
void
+rb_id_table_foreach_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data)
+{
+ int i, capa = tbl->capa;
+
+ for (i=0; i<capa; i++) {
+ if (ITEM_KEY_ISSET(tbl, i)) {
+ enum rb_id_table_iterator_result ret = (*func)(Qundef, tbl->items[i].val, data);
+ assert(ITEM_GET_KEY(tbl, i));
+
+ if (ret == ID_TABLE_REPLACE) {
+ VALUE val = tbl->items[i].val;
+ ret = (*replace)(NULL, &val, data, TRUE);
+ tbl->items[i].val = val;
+ }
+ else if (ret == ID_TABLE_STOP)
+ return;
+ }
+ }
+}
+
+void
rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data)
{
int i, capa = tbl->capa;
diff --git a/id_table.h b/id_table.h
index b10b4ac164..f3dc681d17 100644
--- a/id_table.h
+++ b/id_table.h
@@ -1,5 +1,7 @@
#ifndef RUBY_ID_TABLE_H
#define RUBY_ID_TABLE_H 1
+#include "ruby/internal/config.h"
+#include <stddef.h>
#include "ruby/ruby.h"
struct rb_id_table;
@@ -9,6 +11,7 @@ enum rb_id_table_iterator_result {
ID_TABLE_CONTINUE = ST_CONTINUE,
ID_TABLE_STOP = ST_STOP,
ID_TABLE_DELETE = ST_DELETE,
+ ID_TABLE_REPLACE = ST_REPLACE,
ID_TABLE_ITERATOR_RESULT_END
};
@@ -23,9 +26,11 @@ int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val);
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp);
int rb_id_table_delete(struct rb_id_table *tbl, ID id);
+typedef enum rb_id_table_iterator_result rb_id_table_update_callback_func_t(ID *id, VALUE *val, void *data, int existing);
typedef enum rb_id_table_iterator_result rb_id_table_foreach_func_t(ID id, VALUE val, void *data);
typedef enum rb_id_table_iterator_result rb_id_table_foreach_values_func_t(VALUE val, void *data);
void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data);
+void rb_id_table_foreach_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data);
void rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data);
#endif /* RUBY_ID_TABLE_H */
diff --git a/include/ruby.h b/include/ruby.h
index 076b5ce258..31c1df3c5e 100644
--- a/include/ruby.h
+++ b/include/ruby.h
@@ -1,28 +1,33 @@
-/**********************************************************************
-
- ruby.h -
-
- $Author$
- created at: Sun 10 12:06:15 Jun JST 2007
-
- Copyright (C) 2007-2008 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_H
+#ifndef RUBY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_H 1
-
+/**
+ * @file
+ * @author $Author$
+ * @date Sun 10 12:06:15 Jun JST 2007
+ * @copyright 2007-2008 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#define HAVE_RUBY_ATOMIC_H 1
+#define HAVE_RUBY_DEBUG_H 1
#define HAVE_RUBY_DEFINES_H 1
#define HAVE_RUBY_ENCODING_H 1
#define HAVE_RUBY_INTERN_H 1
#define HAVE_RUBY_IO_H 1
+#define HAVE_RUBY_MEMORY_VIEW_H 1
#define HAVE_RUBY_MISSING_H 1
+#define HAVE_RUBY_ONIGMO_H 1
#define HAVE_RUBY_ONIGURUMA_H 1
+#define HAVE_RUBY_RACTOR_H 1
+#define HAVE_RUBY_RANDOM_H 1
#define HAVE_RUBY_RE_H 1
#define HAVE_RUBY_REGEX_H 1
#define HAVE_RUBY_RUBY_H 1
#define HAVE_RUBY_ST_H 1
#define HAVE_RUBY_THREAD_H 1
+#define HAVE_RUBY_THREAD_NATIVE_H 1
#define HAVE_RUBY_UTIL_H 1
#define HAVE_RUBY_VERSION_H 1
#define HAVE_RUBY_VM_H 1
diff --git a/include/ruby/assert.h b/include/ruby/assert.h
new file mode 100644
index 0000000000..9b70d7103e
--- /dev/null
+++ b/include/ruby/assert.h
@@ -0,0 +1,234 @@
+#ifndef RUBY_ASSERT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_ASSERT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @date Wed May 18 00:21:44 JST 1994
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ */
+#include "ruby/internal/assume.h"
+#include "ruby/internal/attr/cold.h"
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/backward/2/assume.h"
+
+/* RUBY_NDEBUG is very simple: after everything described below are done,
+ * define it with either NDEBUG is undefined (=0) or defined (=1). It is truly
+ * subordinate.
+ *
+ * RUBY_DEBUG versus NDEBUG is complicated. Assertions shall be:
+ *
+ * | -UNDEBUG | -DNDEBUG
+ * ---------------+----------+---------
+ * -URUBY_DEBUG | (*1) | disabled
+ * -DRUBY_DEBUG=0 | disabled | disabled
+ * -DRUBY_DEBUG=1 | enabled | (*2)
+ * -DRUBY_DEBUG | enabled | (*2)
+ *
+ * where:
+ *
+ * - (*1): Assertions shall be silently disabled, no warnings, in favour of
+ * commit 21991e6ca59274e41a472b5256bd3245f6596c90.
+ *
+ * - (*2): Compile-time warnings shall be issued.
+ */
+
+/** @cond INTERNAL_MACRO */
+
+/*
+ * Pro tip: `!!RUBY_DEBUG-1` expands to...
+ *
+ * - `!!(-1)` (== `!0` == `1`) when RUBY_DEBUG is defined to be empty,
+ * - `(!!0)-1` (== `0-1` == `-1`) when RUBY_DEBUG is defined as 0, and
+ * - `(!!n)-1` (== `1-1` == `0`) when RUBY_DEBUG is defined as something else.
+ */
+#if ! defined(RUBY_DEBUG)
+# define RBIMPL_RUBY_DEBUG 0
+#elif !!RUBY_DEBUG-1 < 0
+# define RBIMPL_RUBY_DEBUG 0
+#else
+# define RBIMPL_RUBY_DEBUG 1
+#endif
+
+/*
+ * ISO/IEC 9899 (all past versions) says that "If NDEBUG is defined as a macro
+ * name at the point in the source file where <assert.h> is included, ..."
+ * which means we must not take its defined value into account.
+ */
+#if defined(NDEBUG)
+# define RBIMPL_NDEBUG 1
+#else
+# define RBIMPL_NDEBUG 0
+#endif
+
+/** @endcond */
+
+/* Here we go... */
+#undef RUBY_DEBUG
+#undef RUBY_NDEBUG
+#undef NDEBUG
+#if defined(__DOXYGEN__)
+# /** Define this macro when you want assertions. */
+# define RUBY_DEBUG 0
+# /** Define this macro when you don't want assertions. */
+# define NDEBUG
+# /** This macro is basically the same as #NDEBUG */
+# define RUBY_NDEBUG 1
+
+#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 0)
+# /* Assertions disabled as per request, no conflicts. */
+# define RUBY_DEBUG 0
+# define RUBY_NDEBUG 1
+# define NDEBUG
+
+#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 1)
+# /* Assertions enabled as per request, no conflicts. */
+# define RUBY_DEBUG 1
+# define RUBY_NDEBUG 0
+# /* keep NDEBUG undefined */
+
+#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 0)
+# /* The (*1) situation in avobe diagram. */
+# define RUBY_DEBUG 0
+# define RUBY_NDEBUG 1
+# define NDEBUG
+
+#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 1)
+# /* The (*2) situation in above diagram. */
+# define RUBY_DEBUG 1
+# define RUBY_NDEBUG 0
+# /* keep NDEBUG undefined */
+
+# if defined(_MSC_VER)
+# pragma message("NDEBUG is ignored because RUBY_DEBUG>0.")
+# elif defined(__GNUC__)
+# pragma GCC warning "NDEBUG is ignored because RUBY_DEBUG>0."
+# else
+# error NDEBUG is ignored because RUBY_DEBUG>0.
+# endif
+#endif
+#undef RBIMPL_NDEBUG
+#undef RBIMPL_RUBY_DEBUG
+
+/** @cond INTERNAL_MACRO */
+#define RBIMPL_ASSERT_NOTHING RBIMPL_CAST((void)0)
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+RBIMPL_ATTR_NORETURN()
+RBIMPL_ATTR_COLD()
+void rb_assert_failure(const char *file, int line, const char *name, const char *expr);
+RBIMPL_SYMBOL_EXPORT_END()
+
+#ifdef RUBY_FUNCTION_NAME_STRING
+# define RBIMPL_ASSERT_FUNC RUBY_FUNCTION_NAME_STRING
+#else
+# define RBIMPL_ASSERT_FUNC RBIMPL_CAST((const char *)0)
+#endif
+
+/** @endcond */
+
+/**
+ * Prints the given message, and terminates the entire process abnormally.
+ *
+ * @param mesg The message to display.
+ */
+#define RUBY_ASSERT_FAIL(mesg) \
+ rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
+
+/**
+ * Asserts that the expression is truthy. If not aborts with the message.
+ *
+ * @param expr What supposedly evaluates to true.
+ * @param mesg The message to display on failure.
+ */
+#define RUBY_ASSERT_MESG(expr, mesg) \
+ (RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(mesg))
+
+/**
+ * A variant of #RUBY_ASSERT that does not interface with #RUBY_DEBUG.
+ *
+ * @copydetails #RUBY_ASSERT
+ */
+#define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
+
+/**
+ * Asserts that the given expression is truthy iff #RUBY_DEBUG is truthy.
+ *
+ * @param expr What supposedly evaluates to true.
+ */
+#if RUBY_DEBUG
+# define RUBY_ASSERT(expr) RUBY_ASSERT_MESG((expr), #expr)
+#else
+# define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
+#endif
+
+/**
+ * A variant of #RUBY_ASSERT that interfaces with #NDEBUG instead of
+ * #RUBY_DEBUG. This almost resembles `assert` C standard macro, except minor
+ * implementation details.
+ *
+ * @copydetails #RUBY_ASSERT
+ */
+/* Currently `RUBY_DEBUG == ! defined(NDEBUG)` is always true. There is no
+ * difference any longer between this one and `RUBY_ASSERT`. */
+#if defined(NDEBUG)
+# define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
+#else
+# define RUBY_ASSERT_NDEBUG(expr) RUBY_ASSERT_MESG((expr), #expr)
+#endif
+
+/**
+ * @copydoc #RUBY_ASSERT_WHEN
+ * @param mesg The message to display on failure.
+ */
+#if RUBY_DEBUG
+# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) RUBY_ASSERT_MESG((expr), (mesg))
+#else
+# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
+ ((cond) ? RUBY_ASSERT_MESG((expr), (mesg)) : RBIMPL_ASSERT_NOTHING)
+#endif
+
+/**
+ * A variant of #RUBY_ASSERT that asserts when either #RUBY_DEBUG or `cond`
+ * parameter is truthy.
+ *
+ * @param cond Extra condition that shall hold for assertion to take effect.
+ * @param expr What supposedly evaluates to true.
+ */
+#define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
+
+/**
+ * This is either #RUBY_ASSERT or #RBIMPL_ASSUME, depending on #RUBY_DEBUG.
+ *
+ * @copydetails #RUBY_ASSERT
+ */
+#if RUBY_DEBUG
+# define RBIMPL_ASSERT_OR_ASSUME(expr) RUBY_ASSERT_ALWAYS(expr)
+#elif RBIMPL_COMPILER_BEFORE(Clang, 7, 0, 0)
+# /* See commit 67d259c5dccd31fe49d417fec169977712ffdf10 */
+# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
+#elif defined(RUBY_ASSERT_NOASSUME)
+# /* See commit d300a734414ef6de7e8eb563b7cc4389c455ed08 */
+# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
+#elif ! defined(RBIMPL_HAVE___ASSUME)
+# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
+#else
+# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSUME(expr)
+#endif
+
+#endif /* RUBY_ASSERT_H */
diff --git a/include/ruby/atomic.h b/include/ruby/atomic.h
new file mode 100644
index 0000000000..a898c30ddf
--- /dev/null
+++ b/include/ruby/atomic.h
@@ -0,0 +1,236 @@
+#ifndef RUBY_ATOMIC_H
+#define RUBY_ATOMIC_H
+
+/*
+ * - RUBY_ATOMIC_CAS, RUBY_ATOMIC_EXCHANGE, RUBY_ATOMIC_FETCH_*:
+ * return the old * value.
+ * - RUBY_ATOMIC_ADD, RUBY_ATOMIC_SUB, RUBY_ATOMIC_INC, RUBY_ATOMIC_DEC, RUBY_ATOMIC_OR, RUBY_ATOMIC_SET:
+ * may be void.
+ */
+#if 0
+#elif defined HAVE_GCC_ATOMIC_BUILTINS
+typedef unsigned int rb_atomic_t;
+# define RUBY_ATOMIC_FETCH_ADD(var, val) __atomic_fetch_add(&(var), (val), __ATOMIC_SEQ_CST)
+# define RUBY_ATOMIC_FETCH_SUB(var, val) __atomic_fetch_sub(&(var), (val), __ATOMIC_SEQ_CST)
+# define RUBY_ATOMIC_OR(var, val) __atomic_fetch_or(&(var), (val), __ATOMIC_SEQ_CST)
+# define RUBY_ATOMIC_EXCHANGE(var, val) __atomic_exchange_n(&(var), (val), __ATOMIC_SEQ_CST)
+# define RUBY_ATOMIC_CAS(var, oldval, newval) RB_GNUC_EXTENSION_BLOCK( \
+ __typeof__(var) oldvaldup = (oldval); /* oldval should not be modified */ \
+ __atomic_compare_exchange_n(&(var), &oldvaldup, (newval), 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
+ oldvaldup )
+
+# define RUBY_ATOMIC_GENERIC_MACRO 1
+
+#elif defined HAVE_GCC_SYNC_BUILTINS
+/* @shyouhei hack to support atomic operations in case of gcc. Gcc
+ * has its own pseudo-insns to support them. See info, or
+ * http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html */
+
+typedef unsigned int rb_atomic_t; /* Anything OK */
+# define RUBY_ATOMIC_FETCH_ADD(var, val) __sync_fetch_and_add(&(var), (val))
+# define RUBY_ATOMIC_FETCH_SUB(var, val) __sync_fetch_and_sub(&(var), (val))
+# define RUBY_ATOMIC_OR(var, val) __sync_fetch_and_or(&(var), (val))
+# define RUBY_ATOMIC_EXCHANGE(var, val) __sync_lock_test_and_set(&(var), (val))
+# define RUBY_ATOMIC_CAS(var, oldval, newval) __sync_val_compare_and_swap(&(var), (oldval), (newval))
+
+# define RUBY_ATOMIC_GENERIC_MACRO 1
+
+#elif defined _WIN32
+#if RBIMPL_COMPILER_SINCE(MSVC, 13, 0, 0)
+#pragma intrinsic(_InterlockedOr)
+#endif
+typedef LONG rb_atomic_t;
+
+# define RUBY_ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
+# define RUBY_ATOMIC_INC(var) InterlockedIncrement(&(var))
+# define RUBY_ATOMIC_DEC(var) InterlockedDecrement(&(var))
+# define RUBY_ATOMIC_FETCH_ADD(var, val) InterlockedExchangeAdd(&(var), (val))
+# define RUBY_ATOMIC_FETCH_SUB(var, val) InterlockedExchangeAdd(&(var), -(LONG)(val))
+#if defined __GNUC__
+# define RUBY_ATOMIC_OR(var, val) __asm__("lock\n\t" "orl\t%1, %0" : "=m"(var) : "Ir"(val))
+#elif RBIMPL_COMPILER_BEFORE(MSVC, 13, 0, 0)
+# define RUBY_ATOMIC_OR(var, val) rb_w32_atomic_or(&(var), (val))
+static inline void
+rb_w32_atomic_or(volatile rb_atomic_t *var, rb_atomic_t val)
+{
+#ifdef _M_IX86
+ __asm mov eax, var;
+ __asm mov ecx, val;
+ __asm lock or [eax], ecx;
+#else
+#error unsupported architecture
+#endif
+}
+#else
+# define RUBY_ATOMIC_OR(var, val) _InterlockedOr(&(var), (val))
+#endif
+# define RUBY_ATOMIC_EXCHANGE(var, val) InterlockedExchange(&(var), (val))
+# define RUBY_ATOMIC_CAS(var, oldval, newval) InterlockedCompareExchange(&(var), (newval), (oldval))
+# if RBIMPL_COMPILER_BEFORE(MSVC, 13, 0, 0)
+static inline rb_atomic_t
+rb_w32_atomic_cas(volatile rb_atomic_t *var, rb_atomic_t oldval, rb_atomic_t newval)
+{
+ return (rb_atomic_t)InterlockedCompareExchange((PVOID *)var, (PVOID)newval, (PVOID)oldval);
+}
+# undef RUBY_ATOMIC_CAS
+# define RUBY_ATOMIC_CAS(var, oldval, newval) rb_w32_atomic_cas(&(var), (oldval), (newval))
+# endif
+# ifdef _M_AMD64
+# define RUBY_ATOMIC_SIZE_ADD(var, val) InterlockedExchangeAdd64((LONG_LONG *)&(var), (val))
+# define RUBY_ATOMIC_SIZE_SUB(var, val) InterlockedExchangeAdd64((LONG_LONG *)&(var), -(LONG)(val))
+# define RUBY_ATOMIC_SIZE_INC(var) InterlockedIncrement64(&(var))
+# define RUBY_ATOMIC_SIZE_DEC(var) InterlockedDecrement64(&(var))
+# define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) InterlockedExchange64(&(var), (val))
+# define RUBY_ATOMIC_SIZE_CAS(var, oldval, newval) InterlockedCompareExchange64(&(var), (newval), (oldval))
+# else
+# define RUBY_ATOMIC_SIZE_ADD(var, val) InterlockedExchangeAdd((LONG *)&(var), (val))
+# define RUBY_ATOMIC_SIZE_SUB(var, val) InterlockedExchangeAdd((LONG *)&(var), -(LONG)(val))
+# define RUBY_ATOMIC_SIZE_INC(var) InterlockedIncrement((LONG *)&(var))
+# define RUBY_ATOMIC_SIZE_DEC(var) InterlockedDecrement((LONG *)&(var))
+# define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) InterlockedExchange((LONG *)&(var), (val))
+# endif
+
+# ifdef InterlockedExchangePointer
+# define RUBY_ATOMIC_PTR_EXCHANGE(var, val) InterlockedExchangePointer((PVOID volatile *)&(var), (PVOID)(val))
+# endif /* See below for definitions of other situations */
+
+#elif defined(__sun) && defined(HAVE_ATOMIC_H)
+#include <atomic.h>
+typedef unsigned int rb_atomic_t;
+
+# define RUBY_ATOMIC_INC(var) atomic_inc_uint(&(var))
+# define RUBY_ATOMIC_DEC(var) atomic_dec_uint(&(var))
+# define RUBY_ATOMIC_FETCH_ADD(var, val) rb_atomic_fetch_add(&(var), (val))
+# define RUBY_ATOMIC_FETCH_SUB(var, val) rb_atomic_fetch_sub(&(var), (val))
+# define RUBY_ATOMIC_ADD(var, val) atomic_add_uint(&(var), (val))
+# define RUBY_ATOMIC_SUB(var, val) atomic_sub_uint(&(var), (val))
+# define RUBY_ATOMIC_OR(var, val) atomic_or_uint(&(var), (val))
+# define RUBY_ATOMIC_EXCHANGE(var, val) atomic_swap_uint(&(var), (val))
+# define RUBY_ATOMIC_CAS(var, oldval, newval) atomic_cas_uint(&(var), (oldval), (newval))
+
+static inline rb_atomic_t
+rb_atomic_fetch_add(volatile rb_atomic_t *var, rb_atomic_t val)
+{
+ return atomic_add_int_nv(var, val) - val;
+}
+
+static inline rb_atomic_t
+rb_atomic_fetch_sub(volatile rb_atomic_t *var, rb_atomic_t val)
+{
+ return atomic_add_int_nv(var, (rb_atomic_t)(-(int)val)) + val;
+}
+
+# if defined(_LP64) || defined(_I32LPx)
+# define RUBY_ATOMIC_SIZE_ADD(var, val) atomic_add_long(&(var), (val))
+# define RUBY_ATOMIC_SIZE_SUB(var, val) atomic_add_long(&(var), -(val))
+# define RUBY_ATOMIC_SIZE_INC(var) atomic_inc_ulong(&(var))
+# define RUBY_ATOMIC_SIZE_DEC(var) atomic_dec_ulong(&(var))
+# define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_ulong(&(var), (val))
+# define RUBY_ATOMIC_SIZE_CAS(var, oldval, val) atomic_cas_ulong(&(var), (oldval), (val))
+# else
+# define RUBY_ATOMIC_SIZE_ADD(var, val) atomic_add_int(&(var), (val))
+# define RUBY_ATOMIC_SIZE_SUB(var, val) atomic_add_int(&(var), -(val))
+# define RUBY_ATOMIC_SIZE_INC(var) atomic_inc_uint(&(var))
+# define RUBY_ATOMIC_SIZE_DEC(var) atomic_dec_uint(&(var))
+# define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_uint(&(var), (val))
+# endif
+
+#else
+# error No atomic operation found
+#endif
+
+#ifndef RUBY_ATOMIC_SET
+# define RUBY_ATOMIC_SET(var, val) (void)RUBY_ATOMIC_EXCHANGE(var, val)
+#endif
+
+#ifndef RUBY_ATOMIC_ADD
+# define RUBY_ATOMIC_ADD(var, val) (void)RUBY_ATOMIC_FETCH_ADD(var, val)
+#endif
+
+#ifndef RUBY_ATOMIC_SUB
+# define RUBY_ATOMIC_SUB(var, val) (void)RUBY_ATOMIC_FETCH_SUB(var, val)
+#endif
+
+#ifndef RUBY_ATOMIC_INC
+# define RUBY_ATOMIC_INC(var) RUBY_ATOMIC_ADD(var, 1)
+#endif
+
+#ifndef RUBY_ATOMIC_DEC
+# define RUBY_ATOMIC_DEC(var) RUBY_ATOMIC_SUB(var, 1)
+#endif
+
+#ifndef RUBY_ATOMIC_SIZE_INC
+# define RUBY_ATOMIC_SIZE_INC(var) RUBY_ATOMIC_INC(var)
+#endif
+
+#ifndef RUBY_ATOMIC_SIZE_DEC
+# define RUBY_ATOMIC_SIZE_DEC(var) RUBY_ATOMIC_DEC(var)
+#endif
+
+#ifndef RUBY_ATOMIC_SIZE_EXCHANGE
+# define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) RUBY_ATOMIC_EXCHANGE(var, val)
+#endif
+
+#ifndef RUBY_ATOMIC_SIZE_CAS
+# define RUBY_ATOMIC_SIZE_CAS(var, oldval, val) RUBY_ATOMIC_CAS(var, oldval, val)
+#endif
+
+#ifndef RUBY_ATOMIC_SIZE_ADD
+# define RUBY_ATOMIC_SIZE_ADD(var, val) RUBY_ATOMIC_ADD(var, val)
+#endif
+
+#ifndef RUBY_ATOMIC_SIZE_SUB
+# define RUBY_ATOMIC_SIZE_SUB(var, val) RUBY_ATOMIC_SUB(var, val)
+#endif
+
+#if RUBY_ATOMIC_GENERIC_MACRO
+# ifndef RUBY_ATOMIC_PTR_EXCHANGE
+# define RUBY_ATOMIC_PTR_EXCHANGE(var, val) RUBY_ATOMIC_EXCHANGE(var, val)
+# endif
+
+# ifndef RUBY_ATOMIC_PTR_CAS
+# define RUBY_ATOMIC_PTR_CAS(var, oldval, newval) RUBY_ATOMIC_CAS(var, oldval, newval)
+# endif
+
+# ifndef RUBY_ATOMIC_VALUE_EXCHANGE
+# define RUBY_ATOMIC_VALUE_EXCHANGE(var, val) RUBY_ATOMIC_EXCHANGE(var, val)
+# endif
+
+# ifndef RUBY_ATOMIC_VALUE_CAS
+# define RUBY_ATOMIC_VALUE_CAS(var, oldval, val) RUBY_ATOMIC_CAS(var, oldval, val)
+# endif
+#endif
+
+#ifndef RUBY_ATOMIC_PTR_EXCHANGE
+# if SIZEOF_VOIDP == SIZEOF_SIZE_T
+# define RUBY_ATOMIC_PTR_EXCHANGE(var, val) (void *)RUBY_ATOMIC_SIZE_EXCHANGE(*(size_t *)&(var), (size_t)(val))
+# else
+# error No atomic exchange for void*
+# endif
+#endif
+
+#ifndef RUBY_ATOMIC_PTR_CAS
+# if SIZEOF_VOIDP == SIZEOF_SIZE_T
+# define RUBY_ATOMIC_PTR_CAS(var, oldval, val) (void *)RUBY_ATOMIC_SIZE_CAS(*(size_t *)&(var), (size_t)(oldval), (size_t)(val))
+# else
+# error No atomic compare-and-set for void*
+# endif
+#endif
+
+#ifndef RUBY_ATOMIC_VALUE_EXCHANGE
+# if SIZEOF_VALUE == SIZEOF_SIZE_T
+# define RUBY_ATOMIC_VALUE_EXCHANGE(var, val) RUBY_ATOMIC_SIZE_EXCHANGE(*(size_t *)&(var), (size_t)(val))
+# else
+# error No atomic exchange for VALUE
+# endif
+#endif
+
+#ifndef RUBY_ATOMIC_VALUE_CAS
+# if SIZEOF_VALUE == SIZEOF_SIZE_T
+# define RUBY_ATOMIC_VALUE_CAS(var, oldval, val) RUBY_ATOMIC_SIZE_CAS(*(size_t *)&(var), (size_t)(oldval), (size_t)(val))
+# else
+# error No atomic compare-and-set for VALUE
+# endif
+#endif
+
+#endif /* RUBY_ATOMIC_H */
diff --git a/include/ruby/backward.h b/include/ruby/backward.h
index c3606ac614..350a58ee95 100644
--- a/include/ruby/backward.h
+++ b/include/ruby/backward.h
@@ -1,21 +1,20 @@
-#ifndef RUBY_RUBY_BACKWARD_H
+#ifndef RUBY_RUBY_BACKWARD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RUBY_BACKWARD_H 1
-
-#define RClass RClassDeprecated
-#ifndef __cplusplus
-DEPRECATED_TYPE(("RClass is internal use only"),
-struct RClass {
- struct RBasic basic;
-});
-#endif
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/value.h"
+#include "ruby/internal/interpreter.h"
+#include "ruby/backward/2/attributes.h"
#define DECLARE_DEPRECATED_FEATURE(ver, func) \
NORETURN(ERRORFUNC(("deprecated since "#ver), DEPRECATED(void func(void))))
-/* complex.c */
-DECLARE_DEPRECATED_FEATURE(2.2, rb_complex_set_real);
-DECLARE_DEPRECATED_FEATURE(2.2, rb_complex_set_imag);
-
/* eval.c */
DECLARE_DEPRECATED_FEATURE(2.2, rb_disable_super);
DECLARE_DEPRECATED_FEATURE(2.2, rb_enable_super);
@@ -38,24 +37,35 @@ DECLARE_DEPRECATED_FEATURE(2.2, rb_frame_pop);
#define DECLARE_DEPRECATED_INTERNAL_FEATURE(func) \
NORETURN(ERRORFUNC(("deprecated internal function"), DEPRECATED(void func(void))))
+/* eval.c */
+NORETURN(ERRORFUNC(("internal function"), void rb_frozen_class_p(VALUE)));
+DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_exec_end_proc);
+
/* error.c */
DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_compile_error);
DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_compile_error_with_enc);
DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_compile_error_append);
+/* gc.c */
+DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_gc_call_finalizer_at_exit);
+
+/* signal.c */
+DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_trap_exit);
+
/* struct.c */
DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_struct_ptr);
+/* thread.c */
+DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_clear_trace_func);
+
/* variable.c */
DECLARE_DEPRECATED_INTERNAL_FEATURE(rb_generic_ivar_table);
+NORETURN(ERRORFUNC(("internal function"), VALUE rb_mod_const_missing(VALUE, VALUE)));
/* from version.c */
-#ifndef RUBY_SHOW_COPYRIGHT_TO_DIE
-# define RUBY_SHOW_COPYRIGHT_TO_DIE 1
-#endif
-#if RUBY_SHOW_COPYRIGHT_TO_DIE
+#if defined(RUBY_SHOW_COPYRIGHT_TO_DIE) && !!(RUBY_SHOW_COPYRIGHT_TO_DIE+0)
/* for source code backward compatibility */
-DEPRECATED(static inline int ruby_show_copyright_to_die(int));
+RBIMPL_ATTR_DEPRECATED(("since 2.4"))
static inline int
ruby_show_copyright_to_die(int exitcode)
{
diff --git a/include/ruby/backward/2/assume.h b/include/ruby/backward/2/assume.h
new file mode 100644
index 0000000000..3fbb81439a
--- /dev/null
+++ b/include/ruby/backward/2/assume.h
@@ -0,0 +1,43 @@
+#ifndef RUBY_BACKWARD2_ASSUME_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_ASSUME_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #ASSUME / #RB_LIKELY / #UNREACHABLE
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/assume.h"
+#include "ruby/internal/has/builtin.h"
+
+#undef ASSUME /* Kill config.h definition */
+#undef UNREACHABLE /* Kill config.h definition */
+#define ASSUME RBIMPL_ASSUME
+#define UNREACHABLE RBIMPL_UNREACHABLE()
+#define UNREACHABLE_RETURN RBIMPL_UNREACHABLE_RETURN
+
+/* likely */
+#if RBIMPL_HAS_BUILTIN(__builtin_expect)
+# define RB_LIKELY(x) (__builtin_expect(!!(x), 1))
+# define RB_UNLIKELY(x) (__builtin_expect(!!(x), 0))
+
+#else
+# define RB_LIKELY(x) (x)
+# define RB_UNLIKELY(x) (x)
+#endif
+
+#endif /* RUBY_BACKWARD2_ASSUME_H */
diff --git a/include/ruby/backward/2/attributes.h b/include/ruby/backward/2/attributes.h
new file mode 100644
index 0000000000..eaff9e3381
--- /dev/null
+++ b/include/ruby/backward/2/attributes.h
@@ -0,0 +1,170 @@
+#ifndef RUBY_BACKWARD2_ATTRIBUTES_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_ATTRIBUTES_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Various attribute-related macros.
+ *
+ * ### Q&A ###
+ *
+ * - Q: Why are the macros defined in this header file so inconsistent in
+ * style?
+ *
+ * - A: Don't know. Don't blame me. Backward compatibility is the key here.
+ * I'm just preserving what they have been.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/attr/alloc_size.h"
+#include "ruby/internal/attr/cold.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/deprecated.h"
+#include "ruby/internal/attr/error.h"
+#include "ruby/internal/attr/forceinline.h"
+#include "ruby/internal/attr/format.h"
+#include "ruby/internal/attr/maybe_unused.h"
+#include "ruby/internal/attr/noinline.h"
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/attr/restrict.h"
+#include "ruby/internal/attr/returns_nonnull.h"
+#include "ruby/internal/attr/warning.h"
+#include "ruby/internal/has/attribute.h"
+
+/* function attributes */
+#undef CONSTFUNC
+#define CONSTFUNC(x) RBIMPL_ATTR_CONST() x
+
+#undef PUREFUNC
+#define PUREFUNC(x) RBIMPL_ATTR_PURE() x
+
+#undef DEPRECATED
+#define DEPRECATED(x) RBIMPL_ATTR_DEPRECATED(("")) x
+
+#undef DEPRECATED_BY
+#define DEPRECATED_BY(n,x) RBIMPL_ATTR_DEPRECATED(("by: " # n)) x
+
+#undef DEPRECATED_TYPE
+#if defined(__GNUC__)
+# define DEPRECATED_TYPE(mesg, decl) \
+ _Pragma("message \"DEPRECATED_TYPE is deprecated\""); \
+ decl RBIMPL_ATTR_DEPRECATED(mseg)
+#elif defined(_MSC_VER)
+# pragma deprecated(DEPRECATED_TYPE)
+# define DEPRECATED_TYPE(mesg, decl) \
+ __pragma(message(__FILE__"("STRINGIZE(__LINE__)"): warning: " \
+ "DEPRECATED_TYPE is deprecated")) \
+ decl RBIMPL_ATTR_DEPRECATED(mseg)
+#else
+# define DEPRECATED_TYPE(mesg, decl) \
+ <-<-"DEPRECATED_TYPE is deprecated"->->
+#endif
+
+#undef RUBY_CXX_DEPRECATED
+#define RUBY_CXX_DEPRECATED(mseg) RBIMPL_ATTR_DEPRECATED((mseg))
+
+#undef NOINLINE
+#define NOINLINE(x) RBIMPL_ATTR_NOINLINE() x
+
+#ifndef MJIT_HEADER
+# undef ALWAYS_INLINE
+# define ALWAYS_INLINE(x) RBIMPL_ATTR_FORCEINLINE() x
+#endif
+
+#undef ERRORFUNC
+#define ERRORFUNC(mesg, x) RBIMPL_ATTR_ERROR(mesg) x
+#if RBIMPL_HAS_ATTRIBUTE(error)
+# define HAVE_ATTRIBUTE_ERRORFUNC 1
+#else
+# define HAVE_ATTRIBUTE_ERRORFUNC 0
+#endif
+
+#undef WARNINGFUNC
+#define WARNINGFUNC(mesg, x) RBIMPL_ATTR_WARNING(mesg) x
+#if RBIMPL_HAS_ATTRIBUTE(warning)
+# define HAVE_ATTRIBUTE_WARNINGFUNC 1
+#else
+# define HAVE_ATTRIBUTE_WARNINGFUNC 0
+#endif
+
+/*
+ cold attribute for code layout improvements
+ RUBY_FUNC_ATTRIBUTE not used because MSVC does not like nested func macros
+ */
+#undef COLDFUNC
+#define COLDFUNC RBIMPL_ATTR_COLD()
+
+#define PRINTF_ARGS(decl, string_index, first_to_check) \
+ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, (string_index), (first_to_check)) \
+ decl
+
+#undef RUBY_ATTR_ALLOC_SIZE
+#define RUBY_ATTR_ALLOC_SIZE RBIMPL_ATTR_ALLOC_SIZE
+
+#undef RUBY_ATTR_MALLOC
+#define RUBY_ATTR_MALLOC RBIMPL_ATTR_RESTRICT()
+
+#undef RUBY_ATTR_RETURNS_NONNULL
+#define RUBY_ATTR_RETURNS_NONNULL RBIMPL_ATTR_RETURNS_NONNULL()
+
+#ifndef FUNC_MINIMIZED
+#define FUNC_MINIMIZED(x) x
+#endif
+
+#ifndef FUNC_UNOPTIMIZED
+#define FUNC_UNOPTIMIZED(x) x
+#endif
+
+#ifndef RUBY_ALIAS_FUNCTION_TYPE
+#define RUBY_ALIAS_FUNCTION_TYPE(type, prot, name, args) \
+ FUNC_MINIMIZED(type prot) {return (type)name args;}
+#endif
+
+#ifndef RUBY_ALIAS_FUNCTION_VOID
+#define RUBY_ALIAS_FUNCTION_VOID(prot, name, args) \
+ FUNC_MINIMIZED(void prot) {name args;}
+#endif
+
+#ifndef RUBY_ALIAS_FUNCTION
+#define RUBY_ALIAS_FUNCTION(prot, name, args) \
+ RUBY_ALIAS_FUNCTION_TYPE(VALUE, prot, name, args)
+#endif
+
+#undef RUBY_FUNC_NONNULL
+#define RUBY_FUNC_NONNULL(n, x) RBIMPL_ATTR_NONNULL(n) x
+
+#undef NORETURN
+#define NORETURN(x) RBIMPL_ATTR_NORETURN() x
+#define NORETURN_STYLE_NEW
+
+#ifndef PACKED_STRUCT
+# define PACKED_STRUCT(x) x
+#endif
+
+#ifndef PACKED_STRUCT_UNALIGNED
+# if UNALIGNED_WORD_ACCESS
+# define PACKED_STRUCT_UNALIGNED(x) PACKED_STRUCT(x)
+# else
+# define PACKED_STRUCT_UNALIGNED(x) x
+# endif
+#endif
+
+#undef RB_UNUSED_VAR
+#define RB_UNUSED_VAR(x) x RBIMPL_ATTR_MAYBE_UNUSED()
+
+#endif /* RUBY_BACKWARD2_ATTRIBUTES_H */
diff --git a/include/ruby/backward/2/bool.h b/include/ruby/backward/2/bool.h
new file mode 100644
index 0000000000..53164eb3b8
--- /dev/null
+++ b/include/ruby/backward/2/bool.h
@@ -0,0 +1,37 @@
+#ifndef RUBY_BACKWARD2_BOOL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_BOOL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines old #TRUE / #FALSE
+ */
+#include "ruby/internal/stdbool.h"
+
+#ifndef FALSE
+# define FALSE false
+#elif FALSE
+# error FALSE must be false
+#endif
+
+#ifndef TRUE
+# define TRUE true
+#elif ! TRUE
+# error TRUE must be true
+#endif
+
+#endif /* RUBY_BACKWARD2_BOOL_H */
diff --git a/include/ruby/backward/2/gcc_version_since.h b/include/ruby/backward/2/gcc_version_since.h
new file mode 100644
index 0000000000..2a5b76c102
--- /dev/null
+++ b/include/ruby/backward/2/gcc_version_since.h
@@ -0,0 +1,38 @@
+#ifndef RUBY_BACKWARD2_GCC_VERSION_SINCE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_GCC_VERSION_SINCE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines old #GCC_VERSION_SINCE
+ */
+#include "ruby/internal/compiler_since.h"
+
+#ifndef GCC_VERSION_SINCE
+#define GCC_VERSION_SINCE(x, y, z) RBIMPL_COMPILER_SINCE(GCC, (x), (y), (z))
+#endif
+
+#ifndef GCC_VERSION_BEFORE
+#define GCC_VERSION_BEFORE(x, y, z) \
+ (RBIMPL_COMPILER_BEFORE(GCC, (x), (y), (z)) || \
+ (RBIMPL_COMPILER_IS(GCC) && \
+ ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
+ ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
+ (RBIMPL_COMPILER_VERSION_PATCH == (z))))))
+#endif
+
+#endif /* RUBY_BACKWARD2_GCC_VERSION_SINCE_H */
diff --git a/include/ruby/backward/2/inttypes.h b/include/ruby/backward/2/inttypes.h
new file mode 100644
index 0000000000..c1e376a107
--- /dev/null
+++ b/include/ruby/backward/2/inttypes.h
@@ -0,0 +1,132 @@
+#ifndef RUBY_BACKWARD2_INTTYPES_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_INTTYPES_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief C99 shim for `<inttypes.h>`
+ */
+#include "ruby/internal/config.h" /* PRI_LL_PREFIX etc. are here */
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+#include "ruby/internal/value.h" /* PRI_VALUE_PREFIX is here. */
+
+#ifndef PRI_INT_PREFIX
+# define PRI_INT_PREFIX ""
+#endif
+
+#ifndef PRI_LONG_PREFIX
+# define PRI_LONG_PREFIX "l"
+#endif
+
+#ifndef PRI_SHORT_PREFIX
+# define PRI_SHORT_PREFIX "h"
+#endif
+
+#ifdef PRI_64_PREFIX
+# /* Take that. */
+#elif SIZEOF_LONG == 8
+# define PRI_64_PREFIX PRI_LONG_PREFIX
+#elif SIZEOF_LONG_LONG == 8
+# define PRI_64_PREFIX PRI_LL_PREFIX
+#endif
+
+#ifndef PRIdPTR
+# define PRIdPTR PRI_PTR_PREFIX"d"
+# define PRIiPTR PRI_PTR_PREFIX"i"
+# define PRIoPTR PRI_PTR_PREFIX"o"
+# define PRIuPTR PRI_PTR_PREFIX"u"
+# define PRIxPTR PRI_PTR_PREFIX"x"
+# define PRIXPTR PRI_PTR_PREFIX"X"
+#endif
+
+#ifndef RUBY_PRI_VALUE_MARK
+# define RUBY_PRI_VALUE_MARK "\v"
+#endif
+
+#if defined PRIdPTR && !defined PRI_VALUE_PREFIX
+# define PRIdVALUE PRIdPTR
+# define PRIoVALUE PRIoPTR
+# define PRIuVALUE PRIuPTR
+# define PRIxVALUE PRIxPTR
+# define PRIXVALUE PRIXPTR
+# define PRIsVALUE PRIiPTR"" RUBY_PRI_VALUE_MARK
+#else
+# define PRIdVALUE PRI_VALUE_PREFIX"d"
+# define PRIoVALUE PRI_VALUE_PREFIX"o"
+# define PRIuVALUE PRI_VALUE_PREFIX"u"
+# define PRIxVALUE PRI_VALUE_PREFIX"x"
+# define PRIXVALUE PRI_VALUE_PREFIX"X"
+# define PRIsVALUE PRI_VALUE_PREFIX"i" RUBY_PRI_VALUE_MARK
+#endif
+
+#ifndef PRI_VALUE_PREFIX
+# define PRI_VALUE_PREFIX ""
+#endif
+
+#ifdef PRI_TIMET_PREFIX
+# /* Take that. */
+#elif SIZEOF_TIME_T == SIZEOF_INT
+# define PRI_TIMET_PREFIX
+#elif SIZEOF_TIME_T == SIZEOF_LONG
+# define PRI_TIMET_PREFIX "l"
+#elif SIZEOF_TIME_T == SIZEOF_LONG_LONG
+# define PRI_TIMET_PREFIX PRI_LL_PREFIX
+#endif
+
+#ifdef PRI_PTRDIFF_PREFIX
+# /* Take that. */
+#elif SIZEOF_PTRDIFF_T == SIZEOF_INT
+# define PRI_PTRDIFF_PREFIX ""
+#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
+# define PRI_PTRDIFF_PREFIX "l"
+#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
+# define PRI_PTRDIFF_PREFIX PRI_LL_PREFIX
+#endif
+
+#ifndef PRIdPTRDIFF
+# define PRIdPTRDIFF PRI_PTRDIFF_PREFIX"d"
+# define PRIiPTRDIFF PRI_PTRDIFF_PREFIX"i"
+# define PRIoPTRDIFF PRI_PTRDIFF_PREFIX"o"
+# define PRIuPTRDIFF PRI_PTRDIFF_PREFIX"u"
+# define PRIxPTRDIFF PRI_PTRDIFF_PREFIX"x"
+# define PRIXPTRDIFF PRI_PTRDIFF_PREFIX"X"
+#endif
+
+#ifdef PRI_SIZE_PREFIX
+# /* Take that. */
+#elif SIZEOF_SIZE_T == SIZEOF_INT
+# define PRI_SIZE_PREFIX ""
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define PRI_SIZE_PREFIX "l"
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define PRI_SIZE_PREFIX PRI_LL_PREFIX
+#endif
+
+#ifndef PRIdSIZE
+# define PRIdSIZE PRI_SIZE_PREFIX"d"
+# define PRIiSIZE PRI_SIZE_PREFIX"i"
+# define PRIoSIZE PRI_SIZE_PREFIX"o"
+# define PRIuSIZE PRI_SIZE_PREFIX"u"
+# define PRIxSIZE PRI_SIZE_PREFIX"x"
+# define PRIXSIZE PRI_SIZE_PREFIX"X"
+#endif
+
+#endif /* RUBY_BACKWARD2_INTTYPES_H */
diff --git a/include/ruby/backward/2/limits.h b/include/ruby/backward/2/limits.h
new file mode 100644
index 0000000000..e38009b01a
--- /dev/null
+++ b/include/ruby/backward/2/limits.h
@@ -0,0 +1,100 @@
+#ifndef RUBY_BACKWARD2_LIMITS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_LIMITS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Historical shim for `<limits.h>`.
+ *
+ * The macros in this header file are obsolescent. Does anyone really need our
+ * own definition of #CHAR_BIT today?
+ */
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ruby/backward/2/long_long.h"
+
+#ifndef LONG_MAX
+# /* assuming 32bit(2's complement) long */
+# define LONG_MAX 2147483647L
+#endif
+
+#ifndef LONG_MIN
+# define LONG_MIN (-LONG_MAX-1)
+#endif
+
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+
+#ifdef LLONG_MAX
+# /* Take that. */
+#elif defined(LONG_LONG_MAX)
+# define LLONG_MAX LONG_LONG_MAX
+#elif defined(_I64_MAX)
+# define LLONG_MAX _I64_MAX
+#else
+# /* assuming 64bit(2's complement) long long */
+# define LLONG_MAX 9223372036854775807LL
+#endif
+
+#ifdef LLONG_MIN
+# /* Take that. */
+#elif defined(LONG_LONG_MIN)
+# define LLONG_MIN LONG_LONG_MIN
+#elif defined(_I64_MAX)
+# define LLONG_MIN _I64_MIN
+#else
+# define LLONG_MIN (-LLONG_MAX-1)
+#endif
+
+#ifdef SIZE_MAX
+# /* Take that. */
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define SIZE_MAX ULLONG_MAX
+# define SIZE_MIN ULLONG_MIN
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define SIZE_MAX ULONG_MAX
+# define SIZE_MIN ULONG_MIN
+#elif SIZEOF_SIZE_T == SIZEOF_INT
+# define SIZE_MAX UINT_MAX
+# define SIZE_MIN UINT_MIN
+#else
+# define SIZE_MAX USHRT_MAX
+# define SIZE_MIN USHRT_MIN
+#endif
+
+#ifdef SSIZE_MAX
+# /* Take that. */
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define SSIZE_MAX LLONG_MAX
+# define SSIZE_MIN LLONG_MIN
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define SSIZE_MAX LONG_MAX
+# define SSIZE_MIN LONG_MIN
+#elif SIZEOF_SIZE_T == SIZEOF_INT
+# define SSIZE_MAX INT_MAX
+# define SSIZE_MIN INT_MIN
+#else
+# define SSIZE_MAX SHRT_MAX
+# define SSIZE_MIN SHRT_MIN
+#endif
+
+#endif /* RUBY_BACKWARD2_LIMITS_H */
diff --git a/include/ruby/backward/2/long_long.h b/include/ruby/backward/2/long_long.h
new file mode 100644
index 0000000000..83eabb459c
--- /dev/null
+++ b/include/ruby/backward/2/long_long.h
@@ -0,0 +1,65 @@
+#ifndef RUBY_BACKWARD2_LONG_LONG_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_LONG_LONG_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines old #LONG_LONG
+ *
+ * No known compiler that can compile today's ruby lacks long long.
+ * Historically MSVC was one of such compiler, but it implemented long long a
+ * while ago (some time back in 2013). The macros are for backwards
+ * compatibility only.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/has/warning.h"
+#include "ruby/internal/warning_push.h"
+
+#if RBIMPL_HAS_WARNING("-Wc++11-long-long")
+# define HAVE_TRUE_LONG_LONG 1
+# define LONG_LONG \
+ RBIMPL_WARNING_PUSH() \
+ RBIMPL_WARNING_IGNORED(-Wc++11-long-long) \
+ long long \
+ RBIMPL_WARNING_POP()
+
+#elif RBIMPL_HAS_WARNING("-Wlong-long")
+# define HAVE_TRUE_LONG_LONG 1
+# define LONG_LONG \
+ RBIMPL_WARNING_PUSH() \
+ RBIMPL_WARNING_IGNORED(-Wlong-long) \
+ long long \
+ RBIMPL_WARNING_POP()
+
+#elif defined(HAVE_LONG_LONG)
+# define HAVE_TRUE_LONG_LONG 1
+# define LONG_LONG long long
+
+#elif SIZEOF___INT64 > 0
+# define HAVE_LONG_LONG 1
+# define LONG_LONG __int64
+# undef SIZEOF_LONG_LONG
+# define SIZEOF_LONG_LONG SIZEOF___INT64
+
+#else
+# error Hello! Ruby developers believe this message must not happen.
+# error If you encounter this message, can you file a bug report?
+# error Remember to attach a detailed description of your environment.
+# error Thank you!
+#endif
+
+#endif /* RBIMPL_BACKWARD2_LONG_LONG_H */
diff --git a/include/ruby/backward/2/r_cast.h b/include/ruby/backward/2/r_cast.h
new file mode 100644
index 0000000000..4600699a9e
--- /dev/null
+++ b/include/ruby/backward/2/r_cast.h
@@ -0,0 +1,33 @@
+#ifndef RUBY_BACKWARD2_R_CAST_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_R_CAST_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines old #R_CAST
+ *
+ * Nobody is actively using this macro.
+ */
+#define R_CAST(st) (struct st*)
+#define RMOVED(obj) (R_CAST(RMoved)(obj))
+
+#if defined(__GNUC__)
+# warning R_CAST and RMOVED are deprecated
+#elif defined(_MSC_VER)
+# pragma message("warning: R_CAST and RMOVED are deprecated")
+#endif
+#endif /* RUBY_BACKWARD2_R_CAST_H */
diff --git a/include/ruby/backward/2/rmodule.h b/include/ruby/backward/2/rmodule.h
new file mode 100644
index 0000000000..a3e2d39f35
--- /dev/null
+++ b/include/ruby/backward/2/rmodule.h
@@ -0,0 +1,37 @@
+#ifndef RUBY_BACKWARD2_RMODULE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_RMODULE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Orphan macros.
+ *
+ * These macros seems broken since at least 2011. Nobody (except ruby itself
+ * who is implementing the internals) could have used those macros for a while.
+ * Kept public as-is here to keep some theoretical backwards compatibility.
+ */
+#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
+#define RMODULE_CONST_TBL(m) RCLASS_CONST_TBL(m)
+#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
+#define RMODULE_SUPER(m) RCLASS_SUPER(m)
+
+#if defined(__GNUC__)
+# warning RMODULE_* macros are deprecated
+#elif defined(_MSC_VER)
+# pragma message("warning: RMODULE_* macros are deprecated")
+#endif
+#endif /* RUBY_BACKWARD2_RMODULE_H */
diff --git a/include/ruby/backward/2/stdalign.h b/include/ruby/backward/2/stdalign.h
new file mode 100644
index 0000000000..2d3c333bde
--- /dev/null
+++ b/include/ruby/backward/2/stdalign.h
@@ -0,0 +1,30 @@
+#ifndef RUBY_BACKWARD2_STDALIGN_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_STDALIGN_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RUBY_ALIGNAS / #RUBY_ALIGNOF
+ */
+#include "ruby/internal/stdalign.h"
+
+#undef RUBY_ALIGNAS
+#undef RUBY_ALIGNOF
+#define RUBY_ALIGNAS RBIMPL_ALIGNAS
+#define RUBY_ALIGNOF RBIMPL_ALIGNOF
+
+#endif /* RUBY_BACKWARD2_STDALIGN_H */
diff --git a/include/ruby/backward/2/stdarg.h b/include/ruby/backward/2/stdarg.h
new file mode 100644
index 0000000000..c2a9ca1e2f
--- /dev/null
+++ b/include/ruby/backward/2/stdarg.h
@@ -0,0 +1,47 @@
+#ifndef RUBY_BACKWARD2_STDARG_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_BACKWARD2_STDARG_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines old #_
+ *
+ * Nobody should ever use these macros any longer. No konwn compilers lack
+ * prototypes today. It's 21st century. Just forget them.
+ */
+
+#undef _
+#ifdef HAVE_PROTOTYPES
+# define _(args) args
+#else
+# define _(args) ()
+#endif
+
+#undef __
+#ifdef HAVE_STDARG_PROTOTYPES
+# define __(args) args
+#else
+# define __(args) ()
+#endif
+
+#ifdef __cplusplus
+#define ANYARGS ...
+#else
+#define ANYARGS
+#endif
+
+#endif /* RUBY_BACKWARD2_STDARG_H */
diff --git a/include/ruby/backward/classext.h b/include/ruby/backward/classext.h
deleted file mode 100644
index 9d5747316a..0000000000
--- a/include/ruby/backward/classext.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#if defined __GNUC__
-#warning use of RClass internals is deprecated
-#elif defined _MSC_VER
-#pragma message("warning: use of RClass internals is deprecated")
-#endif
-
-#ifndef RUBY_BACKWARD_CLASSEXT_H
-#define RUBY_BACKWARD_CLASSEXT_H 1
-
-typedef struct rb_deprecated_classext_struct {
- VALUE super;
-} rb_deprecated_classext_t;
-
-#undef RCLASS_SUPER(c)
-#define RCLASS_EXT(c) ((rb_deprecated_classext_t *)RCLASS(c)->ptr)
-#define RCLASS_SUPER(c) (RCLASS(c)->super)
-
-#endif /* RUBY_BACKWARD_CLASSEXT_H */
diff --git a/include/ruby/backward/cxxanyargs.hpp b/include/ruby/backward/cxxanyargs.hpp
new file mode 100644
index 0000000000..bc5745d850
--- /dev/null
+++ b/include/ruby/backward/cxxanyargs.hpp
@@ -0,0 +1,683 @@
+#ifndef RUBY_BACKWARD_CXXANYARGS_HPP //-*-C++-*-vi:ft=cpp
+#define RUBY_BACKWARD_CXXANYARGS_HPP
+/// @file
+/// @author \@shyouhei
+/// @copyright This file is a part of the programming language Ruby.
+/// Permission is hereby granted, to either redistribute and/or
+/// modify this file, provided that the conditions mentioned in the
+/// file COPYING are met. Consult the file for details.
+/// @note DO NOT MODERNIZE THIS FILE! As the file name implies it is
+/// meant to be a backwards compatibility shim. Please stick to
+/// C++ 98 and never use newer features, like `constexpr`.
+/// @brief Provides old prototypes for C++ programs.
+#include "ruby/internal/config.h"
+#include "ruby/internal/intern/class.h"
+#include "ruby/internal/intern/cont.h"
+#include "ruby/internal/intern/hash.h"
+#include "ruby/internal/intern/proc.h"
+#include "ruby/internal/intern/thread.h"
+#include "ruby/internal/intern/variable.h"
+#include "ruby/internal/intern/vm.h"
+#include "ruby/internal/iterator.h"
+#include "ruby/internal/method.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/variable.h"
+#include "ruby/backward/2/stdarg.h"
+#include "ruby/st.h"
+
+extern "C++" {
+
+#ifdef HAVE_NULLPTR
+#include <cstddef>
+#endif
+
+/// @brief The main namespace.
+/// @note The name "ruby" might already be taken, but that must not be a
+/// problem because namespaces are allowed to reopen.
+namespace ruby {
+
+/// Backwards compatibility layer.
+namespace backward {
+
+/// Provides ANYARGS deprecation warnings. In C, ANYARGS means there is no
+/// function prototype. Literally anything, even including nothing, can be a
+/// valid ANYARGS. So passing a correctly prototyped function pointer to an
+/// ANYARGS-ed function parameter is valid, at the same time passing an
+/// ANYARGS-ed function pointer to a granular typed function parameter is also
+/// valid. However on the other hand in C++, ANYARGS doesn't actually mean any
+/// number of arguments. C++'s ANYARGS means _variadic_ number of arguments.
+/// This is incompatible with ordinal, correct function prototypes.
+///
+/// Luckily, function prototypes being distinct each other means they can be
+/// overloaded. We can provide a compatibility layer for older Ruby APIs which
+/// used to have ANYARGS. This namespace includes such attempts.
+namespace cxxanyargs {
+
+typedef VALUE type(ANYARGS); ///< ANYARGS-ed function type.
+typedef void void_type(ANYARGS); ///< ANYARGS-ed function type, void variant.
+typedef int int_type(ANYARGS); ///< ANYARGS-ed function type, int variant.
+typedef VALUE onearg_type(VALUE); ///< Single-argumented function type.
+
+/// @name Hooking global variables
+/// @{
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Define a function-backended global variable.
+/// @param[in] q Name of the variable.
+/// @param[in] w Getter function.
+/// @param[in] e Setter function.
+/// @note Both functions can be nullptr.
+/// @see rb_define_hooked_variable()
+/// @deprecated Use glanular typed overload instead.
+inline void
+rb_define_virtual_variable(const char *q, type *w, void_type *e)
+{
+ rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t*>(w);
+ rb_gvar_setter_t *t = reinterpret_cast<rb_gvar_setter_t*>(e);
+ ::rb_define_virtual_variable(q, r, t);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_virtual_variable(const char *q, rb_gvar_getter_t *w, void_type *e)
+{
+ rb_gvar_setter_t *t = reinterpret_cast<rb_gvar_setter_t*>(e);
+ ::rb_define_virtual_variable(q, w, t);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_virtual_variable(const char *q, type *w, rb_gvar_setter_t *e)
+{
+ rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t*>(w);
+ ::rb_define_virtual_variable(q, r, e);
+}
+
+#ifdef HAVE_NULLPTR
+inline void
+rb_define_virtual_variable(const char *q, rb_gvar_getter_t *w, std::nullptr_t e)
+{
+ ::rb_define_virtual_variable(q, w, e);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_virtual_variable(const char *q, type *w, std::nullptr_t e)
+{
+ rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t *>(w);
+ ::rb_define_virtual_variable(q, r, e);
+}
+
+inline void
+rb_define_virtual_variable(const char *q, std::nullptr_t w, rb_gvar_setter_t *e)
+{
+ ::rb_define_virtual_variable(q, w, e);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_virtual_variable(const char *q, std::nullptr_t w, void_type *e)
+{
+ rb_gvar_setter_t *r = reinterpret_cast<rb_gvar_setter_t *>(e);
+ ::rb_define_virtual_variable(q, w, r);
+}
+#endif
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Define a function-backended global variable.
+/// @param[in] q Name of the variable.
+/// @param[in] w Variable storage.
+/// @param[in] e Getter function.
+/// @param[in] r Setter function.
+/// @note Both functions can be nullptr.
+/// @see rb_define_virtual_variable()
+/// @deprecated Use glanular typed overload instead.
+inline void
+rb_define_hooked_variable(const char *q, VALUE *w, type *e, void_type *r)
+{
+ rb_gvar_getter_t *t = reinterpret_cast<rb_gvar_getter_t*>(e);
+ rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t*>(r);
+ ::rb_define_hooked_variable(q, w, t, y);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_hooked_variable(const char *q, VALUE *w, rb_gvar_getter_t *e, void_type *r)
+{
+ rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t*>(r);
+ ::rb_define_hooked_variable(q, w, e, y);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_hooked_variable(const char *q, VALUE *w, type *e, rb_gvar_setter_t *r)
+{
+ rb_gvar_getter_t *t = reinterpret_cast<rb_gvar_getter_t*>(e);
+ ::rb_define_hooked_variable(q, w, t, r);
+}
+
+#ifdef HAVE_NULLPTR
+inline void
+rb_define_hooked_variable(const char *q, VALUE *w, rb_gvar_getter_t *e, std::nullptr_t r)
+{
+ ::rb_define_hooked_variable(q, w, e, r);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_hooked_variable(const char *q, VALUE *w, type *e, std::nullptr_t r)
+{
+ rb_gvar_getter_t *y = reinterpret_cast<rb_gvar_getter_t *>(e);
+ ::rb_define_hooked_variable(q, w, y, r);
+}
+
+inline void
+rb_define_hooked_variable(const char *q, VALUE *w, std::nullptr_t e, rb_gvar_setter_t *r)
+{
+ ::rb_define_hooked_variable(q, w, e, r);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+inline void
+rb_define_hooked_variable(const char *q, VALUE *w, std::nullptr_t e, void_type *r)
+{
+ rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t *>(r);
+ ::rb_define_hooked_variable(q, w, e, y);
+}
+#endif
+
+/// @}
+/// @name Exceptions and tag jumps
+/// @{
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Old way to implement iterators.
+/// @param[in] q A function that can yield.
+/// @param[in] w Passed to `q`.
+/// @param[in] e What is to be yielded.
+/// @param[in] r Passed to `e`.
+/// @return The return value of `q`.
+/// @note `e` can be nullptr.
+/// @deprecated This function is obsolated since long before 2.x era. Do not
+/// use it any longer. rb_block_call() is provided instead.
+inline VALUE
+rb_iterate(onearg_type *q, VALUE w, type *e, VALUE r)
+{
+ rb_block_call_func_t t = reinterpret_cast<rb_block_call_func_t>(e);
+ return ::rb_iterate(q, w, t, r);
+}
+
+#ifdef HAVE_NULLPTR
+inline VALUE
+rb_iterate(onearg_type *q, VALUE w, std::nullptr_t e, VALUE r)
+{
+ return ::rb_iterate(q, w, e, r);
+}
+#endif
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Call a method with a block.
+/// @param[in] q The self.
+/// @param[in] w The method.
+/// @param[in] e The # of elems of `r`
+/// @param[in] r The arguments.
+/// @param[in] t What is to be yielded.
+/// @param[in] y Passed to `t`
+/// @return Return value of `q#w(*r,&t)`
+/// @note 't' can be nullptr.
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
+{
+ rb_block_call_func_t u = reinterpret_cast<rb_block_call_func_t>(t);
+ return ::rb_block_call(q, w, e, r, u, y);
+}
+
+#ifdef HAVE_NULLPTR
+inline VALUE
+rb_block_call(VALUE q, ID w, int e, const VALUE *r, std::nullptr_t t, VALUE y)
+{
+ return ::rb_block_call(q, w, e, r, t, y);
+}
+#endif
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief An equivalent of `rescue` clause.
+/// @param[in] q A function that can raise.
+/// @param[in] w Passed to `q`.
+/// @param[in] e A function that cleans-up.
+/// @param[in] r Passed to `e`.
+/// @return The return value of `q` if no exception occurs, or the return
+/// value of `e` if otherwise.
+/// @note `e` can be nullptr.
+/// @see rb_ensure()
+/// @see rb_rescue2()
+/// @see rb_protect()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_rescue(type *q, VALUE w, type *e, VALUE r)
+{
+ typedef VALUE func1_t(VALUE);
+ typedef VALUE func2_t(VALUE, VALUE);
+ func1_t *t = reinterpret_cast<func1_t*>(q);
+ func2_t *y = reinterpret_cast<func2_t*>(e);
+ return ::rb_rescue(t, w, y, r);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief An equivalent of `rescue` clause.
+/// @param[in] q A function that can raise.
+/// @param[in] w Passed to `q`.
+/// @param[in] e A function that cleans-up.
+/// @param[in] r Passed to `e`.
+/// @param[in] ... 0-terminated list of subclass of @ref rb_eException.
+/// @return The return value of `q` if no exception occurs, or the return
+/// value of `e` if otherwise.
+/// @note `e` can be nullptr.
+/// @see rb_ensure()
+/// @see rb_rescue()
+/// @see rb_protect()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_rescue2(type *q, VALUE w, type *e, VALUE r, ...)
+{
+ typedef VALUE func1_t(VALUE);
+ typedef VALUE func2_t(VALUE, VALUE);
+ func1_t *t = reinterpret_cast<func1_t*>(q);
+ func2_t *y = reinterpret_cast<func2_t*>(e);
+ va_list ap;
+ va_start(ap, r);
+ VALUE ret = ::rb_vrescue2(t, w, y, r, ap);
+ va_end(ap);
+ return ret;
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief An equivalent of `ensure` clause.
+/// @param[in] q A function that can raise.
+/// @param[in] w Passed to `q`.
+/// @param[in] e A function that ensures.
+/// @param[in] r Passed to `e`.
+/// @return The return value of `q`.
+/// @note It makes no sense to pass nullptr to `e`.
+/// @see rb_rescue()
+/// @see rb_rescue2()
+/// @see rb_protect()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_ensure(type *q, VALUE w, type *e, VALUE r)
+{
+ typedef VALUE func1_t(VALUE);
+ func1_t *t = reinterpret_cast<func1_t*>(q);
+ func1_t *y = reinterpret_cast<func1_t*>(e);
+ return ::rb_ensure(t, w, y, r);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief An equivalent of `Kernel#catch`.
+/// @param[in] q The "tag" string.
+/// @param[in] w A function that can throw.
+/// @param[in] e Passed to `w`.
+/// @return What was thrown.
+/// @note `q` can be a nullptr but makes no sense to pass nullptr to`w`.
+/// @see rb_block_call()
+/// @see rb_protect()
+/// @see rb_rb_catch_obj()
+/// @see rb_rescue()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_catch(const char *q, type *w, VALUE e)
+{
+ rb_block_call_func_t r = reinterpret_cast<rb_block_call_func_t>(w);
+ return ::rb_catch(q, r, e);
+}
+
+#ifdef HAVE_NULLPTR
+inline VALUE
+rb_catch(const char *q, std::nullptr_t w, VALUE e)
+{
+ return ::rb_catch(q, w, e);
+}
+#endif
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief An equivalent of `Kernel#catch`.
+/// @param[in] q The "tag" object.
+/// @param[in] w A function that can throw.
+/// @param[in] e Passed to `w`.
+/// @return What was thrown.
+/// @note It makes no sense to pass nullptr to`w`.
+/// @see rb_block_call()
+/// @see rb_protect()
+/// @see rb_rb_catch_obj()
+/// @see rb_rescue()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_catch_obj(VALUE q, type *w, VALUE e)
+{
+ rb_block_call_func_t r = reinterpret_cast<rb_block_call_func_t>(w);
+ return ::rb_catch_obj(q, r, e);
+}
+
+/// @}
+/// @name Procs, Fibers and Threads
+/// @{
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Creates a @ref rb_cFiber instance.
+/// @param[in] q The fiber body.
+/// @param[in] w Passed to `q`.
+/// @return What was allocated.
+/// @note It makes no sense to pass nullptr to`q`.
+/// @see rb_proc_new()
+/// @see rb_thread_creatr()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_fiber_new(type *q, VALUE w)
+{
+ rb_block_call_func_t e = reinterpret_cast<rb_block_call_func_t>(q);
+ return ::rb_fiber_new(e, w);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Creates a @ref rb_cProc instance.
+/// @param[in] q The proc body.
+/// @param[in] w Passed to `q`.
+/// @return What was allocated.
+/// @note It makes no sense to pass nullptr to`q`.
+/// @see rb_fiber_new()
+/// @see rb_thread_creatr()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_proc_new(type *q, VALUE w)
+{
+ rb_block_call_func_t e = reinterpret_cast<rb_block_call_func_t>(q);
+ return ::rb_proc_new(e, w);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Creates a @ref rb_cThread instance.
+/// @param[in] q The thread body.
+/// @param[in] w Passed to `q`.
+/// @return What was allocated.
+/// @note It makes no sense to pass nullptr to`q`.
+/// @see rb_proc_new()
+/// @see rb_fiber_new()
+/// @deprecated Use glanular typed overload instead.
+inline VALUE
+rb_thread_create(type *q, void *w)
+{
+ typedef VALUE ptr_t(void*);
+ ptr_t *e = reinterpret_cast<ptr_t*>(q);
+ return ::rb_thread_create(e, w);
+}
+
+/// @}
+/// @name Hash and st_table
+/// @{
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Iteration over the given table.
+/// @param[in] q A table to scan.
+/// @param[in] w A function to iterate.
+/// @param[in] e Passed to `w`.
+/// @retval 0 Always returns 0.
+/// @note It makes no sense to pass nullptr to`w`.
+/// @see st_foreach_check()
+/// @see rb_hash_foreach()
+/// @deprecated Use glanular typed overload instead.
+inline int
+st_foreach(st_table *q, int_type *w, st_data_t e)
+{
+ st_foreach_callback_func *r =
+ reinterpret_cast<st_foreach_callback_func*>(w);
+ return ::st_foreach(q, r, e);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Iteration over the given table.
+/// @param[in] q A table to scan.
+/// @param[in] w A function to iterate.
+/// @param[in] e Passed to `w`.
+/// @retval 0 Successful end of iteration.
+/// @retval 1 Element removed during traversing.
+/// @note It makes no sense to pass nullptr to`w`.
+/// @see st_foreach()
+/// @deprecated Use glanular typed overload instead.
+inline int
+st_foreach_check(st_table *q, int_type *w, st_data_t e, st_data_t)
+{
+ st_foreach_check_callback_func *t =
+ reinterpret_cast<st_foreach_check_callback_func*>(w);
+ return ::st_foreach_check(q, t, e, 0);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Iteration over the given table.
+/// @param[in] q A table to scan.
+/// @param[in] w A function to iterate.
+/// @param[in] e Passed to `w`.
+/// @note It makes no sense to pass nullptr to`w`.
+/// @see st_foreach_check()
+/// @deprecated Use glanular typed overload instead.
+inline void
+st_foreach_safe(st_table *q, int_type *w, st_data_t e)
+{
+ st_foreach_callback_func *r =
+ reinterpret_cast<st_foreach_callback_func*>(w);
+ ::st_foreach_safe(q, r, e);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Iteration over the given hash.
+/// @param[in] q A hash to scan.
+/// @param[in] w A function to iterate.
+/// @param[in] e Passed to `w`.
+/// @note It makes no sense to pass nullptr to`w`.
+/// @see st_foreach()
+/// @deprecated Use glanular typed overload instead.
+inline void
+rb_hash_foreach(VALUE q, int_type *w, VALUE e)
+{
+ st_foreach_callback_func *r =
+ reinterpret_cast<st_foreach_callback_func*>(w);
+ ::rb_hash_foreach(q, r, e);
+}
+
+RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
+/// @brief Iteration over each instance variable of the object.
+/// @param[in] q An object.
+/// @param[in] w A function to iterate.
+/// @param[in] e Passed to `w`.
+/// @note It makes no sense to pass nullptr to`w`.
+/// @see st_foreach()
+/// @deprecated Use glanular typed overload instead.
+inline void
+rb_ivar_foreach(VALUE q, int_type *w, VALUE e)
+{
+ st_foreach_callback_func *r =
+ reinterpret_cast<st_foreach_callback_func*>(w);
+ ::rb_ivar_foreach(q, r, e);
+}
+
+/// @}
+
+/// Driver for *_define_method. ::rb_define_method function for instance takes
+/// a pointer to ANYARGS-ed functions, which in fact varies 18 different
+/// prototypes. We still need to preserve ANYARGS for storages but why not
+/// check the consistencies if possible. In C++ a function has its own
+/// prototype, which is a compile-time constant (static type) by nature. We
+/// can list up all the possible input types and provide warnings for other
+/// cases. This is such attempt.
+namespace define_method {
+
+/// Type of ::rb_f_notimplement().
+typedef VALUE notimpl_type(int, const VALUE *, VALUE, VALUE);
+
+/// @brief Template metaprogramming to generate function prototypes.
+/// @tparam T Type of method id (`ID` or `const char*` in practice).
+/// @tparam F Definition driver e.g. ::rb_define_method.
+template<typename T, void (*F)(VALUE klass, T mid, type *func, int arity)>
+struct driver {
+
+ /// @brief Defines a method
+ /// @tparam N Arity of the function.
+ /// @tparam U The function in question
+ template<int N, typename U>
+ struct engine {
+
+ /* :TODO: Following deprecation attribute renders tons of warnings (one
+ * per every method definitions), which is annoying. Of course
+ * annoyance is the core feature of deprecation warnings... But that
+ * could be too much, especially when the warnings happen inside of
+ * machine-generated programs. And SWIG is known to do such thing.
+ * The new (granular) API was introduced in API version 2.7. As of
+ * this writing the version is 2.8. Let's warn this later, some time
+ * during 3.x. Hopefully codes in old (ANYARGS-ed) format should be
+ * less than now. */
+#if (RUBY_API_VERSION_MAJOR * 100 + RUBY_API_VERSION_MINOR) >= 301
+ RUBY_CXX_DEPRECATED("use of ANYARGS is deprecated")
+#endif
+ /// @copydoc define(VALUE klass, T mid, U func)
+ /// @deprecated Pass corrctly typed function instead.
+ static inline void
+ define(VALUE klass, T mid, type func)
+ {
+ F(klass, mid, func, N);
+ }
+
+ /// @brief Defines klass#mid as func, whose arity is N.
+ /// @param[in] klass Where the method lives.
+ /// @param[in] mid Name of the method to define.
+ /// @param[in] func Function that implements klass#mid.
+ static inline void
+ define(VALUE klass, T mid, U func)
+ {
+ F(klass, mid, reinterpret_cast<type *>(func), N);
+ }
+
+ /// @copydoc define(VALUE klass, T mid, U func)
+ static inline void
+ define(VALUE klass, T mid, notimpl_type func)
+ {
+ F(klass, mid, reinterpret_cast<type *>(func), N);
+ }
+ };
+
+ /// @cond INTERNAL_MACRO
+ template<int N, bool = false> struct specific : public engine<N, type *> {};
+ template<bool b> struct specific<15, b> : public engine<15, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<14, b> : public engine<14, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<13, b> : public engine<13, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<12, b> : public engine<12, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<11, b> : public engine<11, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<10, b> : public engine<10, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 9, b> : public engine< 9, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 8, b> : public engine< 8, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 7, b> : public engine< 7, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 6, b> : public engine< 6, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 5, b> : public engine< 5, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 4, b> : public engine< 4, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 3, b> : public engine< 3, VALUE(*)(VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 2, b> : public engine< 2, VALUE(*)(VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 1, b> : public engine< 1, VALUE(*)(VALUE, VALUE)> {};
+ template<bool b> struct specific< 0, b> : public engine< 0, VALUE(*)(VALUE)> {};
+ template<bool b> struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> {
+ using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define;
+ static inline void define(VALUE c, T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(c, m, reinterpret_cast<type *>(f), -1); }
+ };
+ template<bool b> struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {};
+ /// @endcond
+};
+
+/* We could perhaps merge this struct into the one above using variadic
+ * template parameters if we could assume C++11, but sadly we cannot. */
+template<typename T, void (*F)(T mid, type func, int arity)>
+struct driver0 {
+ template<int N, typename U>
+ struct engine {
+ RUBY_CXX_DEPRECATED("use of ANYARGS is deprecated")
+ static inline void
+ define(T mid, type func)
+ {
+ F(mid, func, N);
+ }
+ static inline void
+ define(T mid, U func)
+ {
+ F(mid, reinterpret_cast<type *>(func), N);
+ }
+ static inline void
+ define(T mid, notimpl_type func)
+ {
+ F(mid, reinterpret_cast<type *>(func), N);
+ }
+ };
+ /// @cond INTERNAL_MACRO
+ template<int N, bool = false> struct specific : public engine<N, type *> {};
+ template<bool b> struct specific<15, b> : public engine<15, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<14, b> : public engine<14, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<13, b> : public engine<13, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<12, b> : public engine<12, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<11, b> : public engine<11, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific<10, b> : public engine<10, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 9, b> : public engine< 9, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 8, b> : public engine< 8, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 7, b> : public engine< 7, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 6, b> : public engine< 6, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 5, b> : public engine< 5, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 4, b> : public engine< 4, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 3, b> : public engine< 3, VALUE(*)(VALUE, VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 2, b> : public engine< 2, VALUE(*)(VALUE, VALUE, VALUE)> {};
+ template<bool b> struct specific< 1, b> : public engine< 1, VALUE(*)(VALUE, VALUE)> {};
+ template<bool b> struct specific< 0, b> : public engine< 0, VALUE(*)(VALUE)> {};
+ template<bool b> struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> {
+ using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define;
+ static inline void define(T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(m, reinterpret_cast<type *>(f), -1); }
+ };
+ template<bool b> struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {};
+ /// @endcond
+};
+
+struct rb_define_method : public driver <const char *, ::rb_define_method> {}; ///< Dispatches appropriate driver for ::rb_define_method.
+struct rb_define_method_id : public driver <ID, ::rb_define_method_id> {}; ///< Dispatches appropriate driver for ::rb_define_method_id.
+struct rb_define_private_method : public driver <const char *, ::rb_define_private_method> {}; ///< Dispatches appropriate driver for ::rb_define_private_method.
+struct rb_define_protected_method : public driver <const char *, ::rb_define_protected_method> {}; ///< Dispatches appropriate driver for ::rb_define_protected_method.
+struct rb_define_singleton_method : public driver <const char *, ::rb_define_singleton_method> {}; ///< Dispatches appropriate driver for ::rb_define_singleton_method.
+struct rb_define_module_function : public driver <const char *, ::rb_define_module_function> {}; ///< Dispatches appropriate driver for ::rb_define_module_function.
+struct rb_define_global_function : public driver0<const char *, ::rb_define_global_function> {}; ///< Dispatches appropriate driver for ::rb_define_global_function.
+
+/// @brief Defines klass\#mid.
+/// @param klass Where the method lives.
+/// @copydetails #rb_define_global_function(mid, func, arity)
+#define rb_define_method(klass, mid, func, arity) ruby::backward::cxxanyargs::define_method::rb_define_method::specific<arity>::define(klass, mid, func)
+
+/// @copydoc #rb_define_method(klass, mid, func, arity)
+#define rb_define_method_id(klass, mid, func, arity) ruby::backward::cxxanyargs::define_method::rb_define_method_id::specific<arity>::define(klass, mid, func)
+
+/// @brief Defines klass\#mid and makes it private.
+/// @copydetails #rb_define_method(klass, mid, func, arity)
+#define rb_define_private_method(klass, mid, func, arity) ruby::backward::cxxanyargs::define_method::rb_define_private_method::specific<arity>::define(klass, mid, func)
+
+/// @brief Defines klass\#mid and makes it protected.
+/// @copydetails #rb_define_method
+#define rb_define_protected_method(klass, mid, func, arity) ruby::backward::cxxanyargs::define_method::rb_define_protected_method::specific<arity>::define(klass, mid, func)
+
+/// @brief Defines klass.mid.(klass, mid, func, arity)
+/// @copydetails #rb_define_method
+#define rb_define_singleton_method(klass, mid, func, arity) ruby::backward::cxxanyargs::define_method::rb_define_singleton_method::specific<arity>::define(klass, mid, func)
+
+/// @brief Defines klass\#mid and makes it a module function.
+/// @copydetails #rb_define_method(klass, mid, func, arity)
+#define rb_define_module_function(klass, mid, func, arity) ruby::backward::cxxanyargs::define_method::rb_define_module_function::specific<arity>::define(klass, mid, func)
+
+/// @brief Defines ::rb_mKernel \#mid.
+/// @param mid Name of the defining method.
+/// @param func Implementation of \#mid.
+/// @param arity Arity of \#mid.
+#define rb_define_global_function(mid, func, arity) ruby::backward::cxxanyargs::define_method::rb_define_global_function::specific<arity>::define(mid, func)
+
+}}}}}
+
+using namespace ruby::backward::cxxanyargs;
+#endif // RUBY_BACKWARD_CXXANYARGS_HPP
diff --git a/include/ruby/backward/rubyio.h b/include/ruby/backward/rubyio.h
deleted file mode 100644
index a6e3a7c78b..0000000000
--- a/include/ruby/backward/rubyio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#if defined __GNUC__
-#warning use "ruby/io.h" instead of "rubyio.h"
-#elif defined _MSC_VER
-#pragma message("warning: use \"ruby/io.h\" instead of \"rubyio.h\"")
-#endif
-#include "ruby/io.h"
diff --git a/include/ruby/backward/rubysig.h b/include/ruby/backward/rubysig.h
deleted file mode 100644
index 58b13cab1c..0000000000
--- a/include/ruby/backward/rubysig.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**********************************************************************
-
- rubysig.h -
-
- $Author$
- $Date$
- created at: Wed Aug 16 01:15:38 JST 1995
-
- Copyright (C) 1993-2008 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#if defined __GNUC__
-#warning rubysig.h is obsolete
-#elif defined _MSC_VER
-#pragma message("warning: rubysig.h is obsolete")
-#endif
-
-#ifndef RUBYSIG_H
-#define RUBYSIG_H
-#include "ruby/ruby.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
-
-#define RUBY_CRITICAL(statements) do {statements;} while (0)
-#define DEFER_INTS (0)
-#define ENABLE_INTS (1)
-#define ALLOW_INTS do {CHECK_INTS;} while (0)
-#define CHECK_INTS rb_thread_check_ints()
-
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
-
-#endif
diff --git a/include/ruby/backward/st.h b/include/ruby/backward/st.h
deleted file mode 100644
index 3e36d44cf8..0000000000
--- a/include/ruby/backward/st.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#if defined __GNUC__
-#warning use "ruby/st.h" instead of bare "st.h"
-#elif defined _MSC_VER
-#pragma message("warning: use \"ruby/st.h\" instead of bare \"st.h\"")
-#endif
-#include "ruby/st.h"
diff --git a/include/ruby/backward/util.h b/include/ruby/backward/util.h
deleted file mode 100644
index 11d32a2da8..0000000000
--- a/include/ruby/backward/util.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#if defined __GNUC__
-#warning use "ruby/util.h" instead of bare "util.h"
-#elif defined _MSC_VER
-#pragma message("warning: use \"ruby/util.h\" instead of bare \"util.h\"")
-#endif
-#include "ruby/util.h"
diff --git a/include/ruby/debug.h b/include/ruby/debug.h
index 9bfc9b9a83..16891e8458 100644
--- a/include/ruby/debug.h
+++ b/include/ruby/debug.h
@@ -1,25 +1,20 @@
-/**********************************************************************
-
- ruby/debug.h -
-
- $Author: ko1 $
- created at: Tue Nov 20 20:35:08 2012
-
- Copyright (C) 2012 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RB_DEBUG_H
+#ifndef RB_DEBUG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RB_DEBUG_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
+/**
+ * @file
+ * @author $Author: ko1 $
+ * @date Tue Nov 20 20:35:08 2012
+ * @copyright Copyright (C) 2012 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/event.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
/* Note: This file contains experimental APIs. */
/* APIs can be replaced at Ruby 2.0.1 or later */
@@ -75,6 +70,7 @@ VALUE rb_tracearg_event(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_lineno(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_path(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_method_id(rb_trace_arg_t *trace_arg);
+VALUE rb_tracearg_callee_id(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_defined_class(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_binding(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_self(rb_trace_arg_t *trace_arg);
@@ -82,7 +78,11 @@ VALUE rb_tracearg_return_value(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_raised_exception(rb_trace_arg_t *trace_arg);
VALUE rb_tracearg_object(rb_trace_arg_t *trace_arg);
-/* Postponed Job API */
+/*
+ * Postponed Job API
+ * rb_postponed_job_register and rb_postponed_job_register_one are
+ * async-signal-safe and used via SIGPROF by the "stackprof" RubyGem
+ */
typedef void (*rb_postponed_job_func_t)(void *arg);
int rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data);
int rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data);
@@ -98,13 +98,6 @@ typedef enum {
void rb_add_event_hook2(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data, rb_event_hook_flag_t hook_flag);
void rb_thread_add_event_hook2(VALUE thval, rb_event_hook_func_t func, rb_event_flag_t events, VALUE data, rb_event_hook_flag_t hook_flag);
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_DEBUG_H */
diff --git a/include/ruby/defines.h b/include/ruby/defines.h
index a4da7ea014..d632a69fc1 100644
--- a/include/ruby/defines.h
+++ b/include/ruby/defines.h
@@ -1,110 +1,28 @@
-/************************************************
-
- defines.h -
-
- $Author$
- created at: Wed May 18 00:21:44 JST 1994
-
-************************************************/
-
-#ifndef RUBY_DEFINES_H
+#ifndef RUBY_DEFINES_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_DEFINES_H 1
+/**
+ * @file
+ * @author $Author$
+ * @date Wed May 18 00:21:44 JST 1994
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-#include "ruby/config.h"
-#ifdef RUBY_EXTCONF_H
-#include RUBY_EXTCONF_H
-#endif
-
-/* function attributes */
-#ifndef CONSTFUNC
-# define CONSTFUNC(x) x
-#endif
-#ifndef PUREFUNC
-# define PUREFUNC(x) x
-#endif
-#define NORETURN_STYLE_NEW 1
-#ifndef NORETURN
-# define NORETURN(x) x
-#endif
-#ifndef DEPRECATED
-# define DEPRECATED(x) x
-#endif
-#ifndef DEPRECATED_BY
-# define DEPRECATED_BY(n,x) DEPRECATED(x)
-#endif
-#ifndef DEPRECATED_TYPE
-# define DEPRECATED_TYPE(mesg, decl) decl
-#endif
-#ifndef NOINLINE
-# define NOINLINE(x) x
-#endif
-#ifndef ALWAYS_INLINE
-# define ALWAYS_INLINE(x) x
-#endif
-#ifndef ERRORFUNC
-# define HAVE_ATTRIBUTE_ERRORFUNC 0
-# define ERRORFUNC(mesg, x) x
-#else
-# define HAVE_ATTRIBUTE_ERRORFUNC 1
-#endif
-#ifndef WARNINGFUNC
-# define HAVE_ATTRIBUTE_WARNINGFUNC 0
-# define WARNINGFUNC(mesg, x) x
-#else
-# define HAVE_ATTRIBUTE_WARNINGFUNC 1
-#endif
-
-#ifndef GCC_VERSION_SINCE
-# if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
-# define GCC_VERSION_SINCE(major, minor, patchlevel) \
- ((__GNUC__ > (major)) || \
- ((__GNUC__ == (major) && \
- ((__GNUC_MINOR__ > (minor)) || \
- (__GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel))))))
-# else
-# define GCC_VERSION_SINCE(major, minor, patchlevel) 0
-# endif
-#endif
-
-/* likely */
-#if __GNUC__ >= 3
-#define RB_LIKELY(x) (__builtin_expect(!!(x), 1))
-#define RB_UNLIKELY(x) (__builtin_expect(!!(x), 0))
-#else /* __GNUC__ >= 3 */
-#define RB_LIKELY(x) (x)
-#define RB_UNLIKELY(x) (x)
-#endif /* __GNUC__ >= 3 */
-
-#ifdef __GNUC__
-#define PRINTF_ARGS(decl, string_index, first_to_check) \
- decl __attribute__((format(printf, string_index, first_to_check)))
-#else
-#define PRINTF_ARGS(decl, string_index, first_to_check) decl
-#endif
-
-#ifdef __GNUC__
-#define RB_GNUC_EXTENSION __extension__
-#define RB_GNUC_EXTENSION_BLOCK(x) __extension__ ({ x; })
-#else
-#define RB_GNUC_EXTENSION
-#define RB_GNUC_EXTENSION_BLOCK(x) (x)
-#endif
+#include "ruby/internal/config.h"
/* 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>
#endif
+
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
@@ -113,21 +31,30 @@ extern "C" {
# 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_STDALIGN_H
+# include <stdalign.h>
+#endif
+
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@@ -137,232 +64,46 @@ extern "C" {
#endif
#ifdef RUBY_USE_SETJMPEX
-#include <setjmpex.h>
-#endif
-
+# include <setjmpex.h>
+#endif
+
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/xmalloc.h"
+#include "ruby/backward/2/assume.h"
+#include "ruby/backward/2/attributes.h"
+#include "ruby/backward/2/bool.h"
+#include "ruby/backward/2/gcc_version_since.h"
+#include "ruby/backward/2/long_long.h"
+#include "ruby/backward/2/stdalign.h"
+#include "ruby/backward/2/stdarg.h"
+#include "ruby/internal/dosish.h"
#include "ruby/missing.h"
#define RUBY
-#ifdef __cplusplus
-# ifndef HAVE_PROTOTYPES
-# define HAVE_PROTOTYPES 1
-# endif
-# ifndef HAVE_STDARG_PROTOTYPES
-# define HAVE_STDARG_PROTOTYPES 1
-# endif
-#endif
-
-#undef _
-#ifdef HAVE_PROTOTYPES
-# define _(args) args
-#else
-# define _(args) ()
-#endif
-
-#undef __
-#ifdef HAVE_STDARG_PROTOTYPES
-# define __(args) args
-#else
-# define __(args) ()
-#endif
-
-#ifdef __cplusplus
-#define ANYARGS ...
-#else
-#define ANYARGS
-#endif
-
-#ifndef RUBY_SYMBOL_EXPORT_BEGIN
-# define RUBY_SYMBOL_EXPORT_BEGIN /* begin */
-# define RUBY_SYMBOL_EXPORT_END /* end */
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
-
-#define xmalloc ruby_xmalloc
-#define xmalloc2 ruby_xmalloc2
-#define xcalloc ruby_xcalloc
-#define xrealloc ruby_xrealloc
-#define xrealloc2 ruby_xrealloc2
-#define xfree ruby_xfree
-
-#if GCC_VERSION_SINCE(4,3,0)
-# define RUBY_ATTR_ALLOC_SIZE(params) __attribute__ ((alloc_size params))
+#ifdef __GNUC__
+# define RB_GNUC_EXTENSION __extension__
+# define RB_GNUC_EXTENSION_BLOCK(x) __extension__ ({ x; })
#else
-# define RUBY_ATTR_ALLOC_SIZE(params)
-#endif
-
-void *xmalloc(size_t) RUBY_ATTR_ALLOC_SIZE((1));
-void *xmalloc2(size_t,size_t) RUBY_ATTR_ALLOC_SIZE((1,2));
-void *xcalloc(size_t,size_t) RUBY_ATTR_ALLOC_SIZE((1,2));
-void *xrealloc(void*,size_t) RUBY_ATTR_ALLOC_SIZE((2));
-void *xrealloc2(void*,size_t,size_t) RUBY_ATTR_ALLOC_SIZE((2,3));
-void xfree(void*);
-
-#define STRINGIZE(expr) STRINGIZE0(expr)
-#ifndef STRINGIZE0
-#define STRINGIZE0(expr) #expr
-#endif
-
-#ifdef HAVE_LONG_LONG
-# define HAVE_TRUE_LONG_LONG 1
-#endif
-
-#if SIZEOF_LONG_LONG > 0
-# define LONG_LONG long long
-#elif SIZEOF___INT64 > 0
-# define HAVE_LONG_LONG 1
-# define LONG_LONG __int64
-# undef SIZEOF_LONG_LONG
-# define SIZEOF_LONG_LONG SIZEOF___INT64
-#endif
-
-#ifdef __CYGWIN__
-#undef _WIN32
-#endif
-
-#if defined(_WIN32)
-/*
- DOSISH mean MS-Windows style filesystem.
- But you should use more precise macros like DOSISH_DRIVE_LETTER, PATH_SEP,
- ENV_IGNORECASE or CASEFOLD_FILESYSTEM.
- */
-#define DOSISH 1
-# define DOSISH_DRIVE_LETTER
-#endif
-
-#ifdef AC_APPLE_UNIVERSAL_BUILD
-#undef WORDS_BIGENDIAN
-#ifdef __BIG_ENDIAN__
-#define WORDS_BIGENDIAN
-#endif
-#endif
-
-#ifdef _WIN32
-#include "ruby/win32.h"
-#endif
-
-#ifdef RUBY_EXPORT
-#undef RUBY_EXTERN
-
-#ifndef FALSE
-# define FALSE 0
-#elif FALSE
-# error FALSE must be false
-#endif
-#ifndef TRUE
-# define TRUE 1
-#elif !TRUE
-# error TRUE must be true
-#endif
-
-#endif
-
-#ifndef RUBY_FUNC_EXPORTED
-#define RUBY_FUNC_EXPORTED
-#endif
-
-#ifndef RUBY_EXTERN
-#define RUBY_EXTERN extern
-#endif
-
-#ifndef EXTERN
-#define EXTERN RUBY_EXTERN /* deprecated */
+# define RB_GNUC_EXTENSION
+# define RB_GNUC_EXTENSION_BLOCK(x) (x)
#endif
+/* :FIXME: Can someone tell us why is this macro defined here? @shyouhei
+ * thinks this is a truly internal macro but cannot move around because he
+ * doesn't understand the reason of this arrangement. */
#ifndef RUBY_MBCHAR_MAXSIZE
-#define RUBY_MBCHAR_MAXSIZE INT_MAX
- /* MB_CUR_MAX will not work well in C locale */
+# define RUBY_MBCHAR_MAXSIZE INT_MAX
+# /* MB_CUR_MAX will not work well in C locale */
#endif
#if defined(__sparc)
+RBIMPL_SYMBOL_EXPORT_BEGIN()
void rb_sparc_flush_register_windows(void);
-# define FLUSH_REGISTER_WINDOWS rb_sparc_flush_register_windows()
-#elif defined(__ia64)
-void *rb_ia64_bsp(void);
-void rb_ia64_flushrs(void);
-# define FLUSH_REGISTER_WINDOWS rb_ia64_flushrs()
-#else
-# define FLUSH_REGISTER_WINDOWS ((void)0)
-#endif
-
-#if defined(DOSISH)
-#define PATH_SEP ";"
+RBIMPL_SYMBOL_EXPORT_END()
+# define FLUSH_REGISTER_WINDOWS rb_sparc_flush_register_windows()
#else
-#define PATH_SEP ":"
-#endif
-#define PATH_SEP_CHAR PATH_SEP[0]
-
-#define PATH_ENV "PATH"
-
-#if defined(DOSISH)
-#define ENV_IGNORECASE
-#endif
-
-#ifndef CASEFOLD_FILESYSTEM
-# if defined DOSISH
-# define CASEFOLD_FILESYSTEM 1
-# else
-# define CASEFOLD_FILESYSTEM 0
-# endif
-#endif
-
-#ifndef DLEXT_MAXLEN
-#define DLEXT_MAXLEN 4
-#endif
-
-#ifndef RUBY_PLATFORM
-#define RUBY_PLATFORM "unknown-unknown"
-#endif
-
-#ifndef FUNC_MINIMIZED
-#define FUNC_MINIMIZED(x) x
-#endif
-#ifndef FUNC_UNOPTIMIZED
-#define FUNC_UNOPTIMIZED(x) x
-#endif
-#ifndef RUBY_ALIAS_FUNCTION_TYPE
-#define RUBY_ALIAS_FUNCTION_TYPE(type, prot, name, args) \
- FUNC_MINIMIZED(type prot) {return (type)name args;}
-#endif
-#ifndef RUBY_ALIAS_FUNCTION_VOID
-#define RUBY_ALIAS_FUNCTION_VOID(prot, name, args) \
- FUNC_MINIMIZED(void prot) {name args;}
-#endif
-#ifndef RUBY_ALIAS_FUNCTION
-#define RUBY_ALIAS_FUNCTION(prot, name, args) \
- RUBY_ALIAS_FUNCTION_TYPE(VALUE, prot, name, args)
-#endif
-
-#ifndef UNALIGNED_WORD_ACCESS
-# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
- defined(__powerpc64__) || \
- defined(__mc68020__)
-# define UNALIGNED_WORD_ACCESS 1
-# else
-# define UNALIGNED_WORD_ACCESS 0
-# endif
-#endif
-#ifndef PACKED_STRUCT
-# define PACKED_STRUCT(x) x
-#endif
-#ifndef PACKED_STRUCT_UNALIGNED
-# if UNALIGNED_WORD_ACCESS
-# define PACKED_STRUCT_UNALIGNED(x) PACKED_STRUCT(x)
-# else
-# define PACKED_STRUCT_UNALIGNED(x) x
-# endif
-#endif
-
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
+# define FLUSH_REGISTER_WINDOWS ((void)0)
#endif
#endif /* RUBY_DEFINES_H */
diff --git a/include/ruby/encoding.h b/include/ruby/encoding.h
index e6ceb19cdf..07e6c9a671 100644
--- a/include/ruby/encoding.h
+++ b/include/ruby/encoding.h
@@ -1,29 +1,22 @@
-/**********************************************************************
-
- encoding.h -
-
- $Author: matz $
- created at: Thu May 24 11:49:41 JST 2007
-
- Copyright (C) 2007 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_ENCODING_H
+#ifndef RUBY_ENCODING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_ENCODING_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
+/**
+ * @file
+ * @author $Author: matz $
+ * @date Thu May 24 11:49:41 JST 2007
+ * @copyright Copyright (C) 2007 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/config.h"
#include <stdarg.h>
#include "ruby/ruby.h"
#include "ruby/oniguruma.h"
+#include "ruby/internal/dllexport.h"
-RUBY_SYMBOL_EXPORT_BEGIN
+RBIMPL_SYMBOL_EXPORT_BEGIN()
enum ruby_encoding_consts {
RUBY_ENCODING_INLINE_MAX = 127,
@@ -118,7 +111,9 @@ PUREFUNC(int rb_enc_dummy_p(rb_encoding *enc));
PUREFUNC(int rb_enc_to_index(rb_encoding *enc));
int rb_enc_get_index(VALUE obj);
void rb_enc_set_index(VALUE obj, int encindex);
+int rb_enc_capable(VALUE obj);
int rb_enc_find_index(const char *name);
+int rb_enc_alias(const char *alias, const char *orig);
int rb_to_encoding_index(VALUE);
rb_encoding *rb_to_encoding(VALUE);
rb_encoding *rb_find_encoding(VALUE);
@@ -132,6 +127,8 @@ void rb_enc_copy(VALUE dst, VALUE src);
VALUE rb_enc_str_new(const char*, long, rb_encoding*);
VALUE rb_enc_str_new_cstr(const char*, rb_encoding*);
VALUE rb_enc_str_new_static(const char*, long, rb_encoding*);
+VALUE rb_enc_interned_str(const char *, long, rb_encoding *);
+VALUE rb_enc_interned_str_cstr(const char *, rb_encoding *);
VALUE rb_enc_reg_new(const char*, long, rb_encoding*, int);
PRINTF_ARGS(VALUE rb_enc_sprintf(rb_encoding *, const char*, ...), 2, 3);
VALUE rb_enc_vsprintf(rb_encoding *, const char*, va_list);
@@ -411,13 +408,6 @@ enum ruby_econv_flag_type {
/* end of flags for rb_econv_convert */
RUBY_ECONV_FLAGS_PLACEHOLDER};
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_ENCODING_H */
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 9b6a8d7dea..2480e2e703 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -1,960 +1,64 @@
-/**********************************************************************
-
- intern.h -
-
- $Author$
- created at: Thu Jun 10 14:22:17 JST 1993
-
- Copyright (C) 1993-2007 Yukihiro Matsumoto
- Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
- Copyright (C) 2000 Information-technology Promotion Agency, Japan
-
-**********************************************************************/
-
-#ifndef RUBY_INTERN_H
+#ifndef RUBY_INTERN_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERN_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
+/**
+ * @file
+ * @author $Author$
+ * @date Thu Jun 10 14:22:17 JST 1993
+ * @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
+ * @copyright Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
+ * @copyright Copyright (C) 2000 Information-technology Promotion Agency, Japan
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/config.h"
#include "ruby/defines.h"
-#ifdef RUBY_EXTCONF_H
-#include RUBY_EXTCONF_H
-#endif
-#ifdef HAVE_STDARG_PROTOTYPES
-# include <stdarg.h>
-#else
-# include <varargs.h>
-#endif
+#include <stdarg.h>
#include "ruby/st.h"
-RUBY_SYMBOL_EXPORT_BEGIN
-
/*
* Functions and variables that are used by more than one source file of
* the kernel.
*/
-#define UNLIMITED_ARGUMENTS (-1)
-
-/* array.c */
-void rb_mem_clear(register VALUE*, register long);
-VALUE rb_assoc_new(VALUE, VALUE);
-VALUE rb_check_array_type(VALUE);
-VALUE rb_ary_new(void);
-VALUE rb_ary_new_capa(long capa);
-VALUE rb_ary_new_from_args(long n, ...);
-VALUE rb_ary_new_from_values(long n, const VALUE *elts);
-VALUE rb_ary_tmp_new(long);
-void rb_ary_free(VALUE);
-void rb_ary_modify(VALUE);
-VALUE rb_ary_freeze(VALUE);
-VALUE rb_ary_shared_with_p(VALUE, VALUE);
-VALUE rb_ary_aref(int, const VALUE*, VALUE);
-VALUE rb_ary_subseq(VALUE, long, long);
-void rb_ary_store(VALUE, long, VALUE);
-VALUE rb_ary_dup(VALUE);
-VALUE rb_ary_resurrect(VALUE ary);
-VALUE rb_ary_to_ary(VALUE);
-VALUE rb_ary_to_s(VALUE);
-VALUE rb_ary_cat(VALUE, const VALUE *, long);
-VALUE rb_ary_push(VALUE, VALUE);
-VALUE rb_ary_pop(VALUE);
-VALUE rb_ary_shift(VALUE);
-VALUE rb_ary_unshift(VALUE, VALUE);
-VALUE rb_ary_entry(VALUE, long);
-VALUE rb_ary_each(VALUE);
-VALUE rb_ary_join(VALUE, VALUE);
-VALUE rb_ary_reverse(VALUE);
-VALUE rb_ary_rotate(VALUE, long);
-VALUE rb_ary_sort(VALUE);
-VALUE rb_ary_sort_bang(VALUE);
-VALUE rb_ary_delete(VALUE, VALUE);
-VALUE rb_ary_delete_at(VALUE, long);
-VALUE rb_ary_clear(VALUE);
-VALUE rb_ary_plus(VALUE, VALUE);
-VALUE rb_ary_concat(VALUE, VALUE);
-VALUE rb_ary_assoc(VALUE, VALUE);
-VALUE rb_ary_rassoc(VALUE, VALUE);
-VALUE rb_ary_includes(VALUE, VALUE);
-VALUE rb_ary_cmp(VALUE, VALUE);
-VALUE rb_ary_replace(VALUE copy, VALUE orig);
-VALUE rb_get_values_at(VALUE, long, int, const VALUE*, VALUE(*)(VALUE,long));
-VALUE rb_ary_resize(VALUE ary, long len);
-#define rb_ary_new2 rb_ary_new_capa
-#define rb_ary_new3 rb_ary_new_from_args
-#define rb_ary_new4 rb_ary_new_from_values
-/* bignum.c */
-VALUE rb_big_new(size_t, int);
-int rb_bigzero_p(VALUE x);
-VALUE rb_big_clone(VALUE);
-void rb_big_2comp(VALUE);
-VALUE rb_big_norm(VALUE);
-void rb_big_resize(VALUE big, size_t len);
-VALUE rb_cstr_to_inum(const char*, int, int);
-VALUE rb_str_to_inum(VALUE, int, int);
-VALUE rb_cstr2inum(const char*, int);
-VALUE rb_str2inum(VALUE, int);
-VALUE rb_big2str(VALUE, int);
-long rb_big2long(VALUE);
-#define rb_big2int(x) rb_big2long(x)
-unsigned long rb_big2ulong(VALUE);
-#define rb_big2uint(x) rb_big2ulong(x)
-#if HAVE_LONG_LONG
-LONG_LONG rb_big2ll(VALUE);
-unsigned LONG_LONG rb_big2ull(VALUE);
-#endif /* HAVE_LONG_LONG */
-void rb_big_pack(VALUE val, unsigned long *buf, long num_longs);
-VALUE rb_big_unpack(unsigned long *buf, long num_longs);
-int rb_uv_to_utf8(char[6],unsigned long);
-VALUE rb_dbl2big(double);
-double rb_big2dbl(VALUE);
-VALUE rb_big_cmp(VALUE, VALUE);
-VALUE rb_big_eq(VALUE, VALUE);
-VALUE rb_big_eql(VALUE, VALUE);
-VALUE rb_big_plus(VALUE, VALUE);
-VALUE rb_big_minus(VALUE, VALUE);
-VALUE rb_big_mul(VALUE, VALUE);
-VALUE rb_big_div(VALUE, VALUE);
-VALUE rb_big_idiv(VALUE, VALUE);
-VALUE rb_big_modulo(VALUE, VALUE);
-VALUE rb_big_divmod(VALUE, VALUE);
-VALUE rb_big_pow(VALUE, VALUE);
-VALUE rb_big_and(VALUE, VALUE);
-VALUE rb_big_or(VALUE, VALUE);
-VALUE rb_big_xor(VALUE, VALUE);
-VALUE rb_big_lshift(VALUE, VALUE);
-VALUE rb_big_rshift(VALUE, VALUE);
-
-/* For rb_integer_pack and rb_integer_unpack: */
-/* "MS" in MSWORD and MSBYTE means "most significant" */
-/* "LS" in LSWORD and LSBYTE means "least significant" */
-#define INTEGER_PACK_MSWORD_FIRST 0x01
-#define INTEGER_PACK_LSWORD_FIRST 0x02
-#define INTEGER_PACK_MSBYTE_FIRST 0x10
-#define INTEGER_PACK_LSBYTE_FIRST 0x20
-#define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40
-#define INTEGER_PACK_2COMP 0x80
-#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400
-/* For rb_integer_unpack: */
-#define INTEGER_PACK_FORCE_BIGNUM 0x100
-#define INTEGER_PACK_NEGATIVE 0x200
-/* Combinations: */
-#define INTEGER_PACK_LITTLE_ENDIAN \
- (INTEGER_PACK_LSWORD_FIRST | \
- INTEGER_PACK_LSBYTE_FIRST)
-#define INTEGER_PACK_BIG_ENDIAN \
- (INTEGER_PACK_MSWORD_FIRST | \
- INTEGER_PACK_MSBYTE_FIRST)
-int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
-VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
-size_t rb_absint_size(VALUE val, int *nlz_bits_ret);
-size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);
-int rb_absint_singlebit_p(VALUE val);
-
-/* rational.c */
-VALUE rb_rational_raw(VALUE, VALUE);
-#define rb_rational_raw1(x) rb_rational_raw((x), INT2FIX(1))
-#define rb_rational_raw2(x,y) rb_rational_raw((x), (y))
-VALUE rb_rational_new(VALUE, VALUE);
-#define rb_rational_new1(x) rb_rational_new((x), INT2FIX(1))
-#define rb_rational_new2(x,y) rb_rational_new((x), (y))
-VALUE rb_Rational(VALUE, VALUE);
-#define rb_Rational1(x) rb_Rational((x), INT2FIX(1))
-#define rb_Rational2(x,y) rb_Rational((x), (y))
-VALUE rb_rational_num(VALUE rat);
-VALUE rb_rational_den(VALUE rat);
-VALUE rb_flt_rationalize_with_prec(VALUE, VALUE);
-VALUE rb_flt_rationalize(VALUE);
-/* complex.c */
-VALUE rb_complex_raw(VALUE, VALUE);
-#define rb_complex_raw1(x) rb_complex_raw((x), INT2FIX(0))
-#define rb_complex_raw2(x,y) rb_complex_raw((x), (y))
-VALUE rb_complex_new(VALUE, VALUE);
-#define rb_complex_new1(x) rb_complex_new((x), INT2FIX(0))
-#define rb_complex_new2(x,y) rb_complex_new((x), (y))
-VALUE rb_complex_polar(VALUE, VALUE);
-VALUE rb_Complex(VALUE, VALUE);
-#define rb_Complex1(x) rb_Complex((x), INT2FIX(0))
-#define rb_Complex2(x,y) rb_Complex((x), (y))
-/* class.c */
-VALUE rb_class_new(VALUE);
-VALUE rb_mod_init_copy(VALUE, VALUE);
-VALUE rb_singleton_class_clone(VALUE);
-void rb_singleton_class_attached(VALUE,VALUE);
-void rb_check_inheritable(VALUE);
-VALUE rb_define_class_id(ID, VALUE);
-VALUE rb_define_class_id_under(VALUE, ID, VALUE);
-VALUE rb_module_new(void);
-VALUE rb_define_module_id(ID);
-VALUE rb_define_module_id_under(VALUE, ID);
-VALUE rb_mod_included_modules(VALUE);
-VALUE rb_mod_include_p(VALUE, VALUE);
-VALUE rb_mod_ancestors(VALUE);
-VALUE rb_class_instance_methods(int, const VALUE*, VALUE);
-VALUE rb_class_public_instance_methods(int, const VALUE*, VALUE);
-VALUE rb_class_protected_instance_methods(int, const VALUE*, VALUE);
-VALUE rb_class_private_instance_methods(int, const VALUE*, VALUE);
-VALUE rb_obj_singleton_methods(int, const VALUE*, VALUE);
-void rb_define_method_id(VALUE, ID, VALUE (*)(ANYARGS), int);
-void rb_frozen_class_p(VALUE);
-void rb_undef(VALUE, ID);
-void rb_define_protected_method(VALUE, const char*, VALUE (*)(ANYARGS), int);
-void rb_define_private_method(VALUE, const char*, VALUE (*)(ANYARGS), int);
-void rb_define_singleton_method(VALUE, const char*, VALUE(*)(ANYARGS), int);
-VALUE rb_singleton_class(VALUE);
-/* compar.c */
-int rb_cmpint(VALUE, VALUE, VALUE);
-NORETURN(void rb_cmperr(VALUE, VALUE));
-/* cont.c */
-VALUE rb_fiber_new(VALUE (*)(ANYARGS), VALUE);
-VALUE rb_fiber_resume(VALUE fib, int argc, const VALUE *argv);
-VALUE rb_fiber_yield(int argc, const VALUE *argv);
-VALUE rb_fiber_current(void);
-VALUE rb_fiber_alive_p(VALUE);
-/* enum.c */
-VALUE rb_enum_values_pack(int, const VALUE*);
-/* enumerator.c */
-VALUE rb_enumeratorize(VALUE, VALUE, int, const VALUE *);
-typedef VALUE rb_enumerator_size_func(VALUE, VALUE, VALUE);
-VALUE rb_enumeratorize_with_size(VALUE, VALUE, int, const VALUE *, rb_enumerator_size_func *);
-#ifndef RUBY_EXPORT
-#define rb_enumeratorize_with_size(obj, id, argc, argv, size_fn) \
- rb_enumeratorize_with_size(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn))
-#endif
-#define SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
- rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \
- (argc), (argv), (size_fn))
-#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) do { \
- if (!rb_block_given_p()) \
- return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \
- } while (0)
-#define RETURN_ENUMERATOR(obj, argc, argv) RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0)
-/* error.c */
-VALUE rb_exc_new(VALUE, const char*, long);
-VALUE rb_exc_new_cstr(VALUE, const char*);
-VALUE rb_exc_new_str(VALUE, VALUE);
-#define rb_exc_new2 rb_exc_new_cstr
-#define rb_exc_new3 rb_exc_new_str
-PRINTF_ARGS(NORETURN(void rb_loaderror(const char*, ...)), 1, 2);
-PRINTF_ARGS(NORETURN(void rb_loaderror_with_path(VALUE path, const char*, ...)), 2, 3);
-PRINTF_ARGS(NORETURN(void rb_name_error(ID, const char*, ...)), 2, 3);
-PRINTF_ARGS(NORETURN(void rb_name_error_str(VALUE, const char*, ...)), 2, 3);
-NORETURN(void rb_invalid_str(const char*, const char*));
-NORETURN(void rb_error_frozen(const char*));
-NORETURN(void rb_error_frozen_object(VALUE));
-CONSTFUNC(void rb_error_untrusted(VALUE));
-void rb_check_frozen(VALUE);
-CONSTFUNC(void rb_check_trusted(VALUE));
-#define rb_check_frozen_internal(obj) do { \
- VALUE frozen_obj = (obj); \
- if (OBJ_FROZEN(frozen_obj)) { \
- rb_error_frozen_object(frozen_obj); \
- } \
- } while (0)
-#define rb_check_trusted_internal(obj) ((void) 0)
-#ifdef __GNUC__
-#define rb_check_frozen(obj) __extension__({rb_check_frozen_internal(obj);})
-#define rb_check_trusted(obj) __extension__({rb_check_trusted_internal(obj);})
-#else
-static inline void
-rb_check_frozen_inline(VALUE obj)
-{
- rb_check_frozen_internal(obj);
-}
-#define rb_check_frozen(obj) rb_check_frozen_inline(obj)
-static inline void
-rb_check_trusted_inline(VALUE obj)
-{
- rb_check_trusted_internal(obj);
-}
-#define rb_check_trusted(obj) rb_check_trusted_inline(obj)
-#endif
-void rb_check_copyable(VALUE obj, VALUE orig);
-
-#define RB_OBJ_INIT_COPY(obj, orig) \
- ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
-#define OBJ_INIT_COPY(obj, orig) RB_OBJ_INIT_COPY(obj, orig)
-
-/* eval.c */
-int rb_sourceline(void);
-const char *rb_sourcefile(void);
-VALUE rb_check_funcall(VALUE, ID, int, const VALUE*);
-
-NORETURN(void rb_error_arity(int, int, int));
-static inline int
-rb_check_arity(int argc, int min, int max)
-{
- if ((argc < min) || (max != UNLIMITED_ARGUMENTS && argc > max))
- rb_error_arity(argc, min, max);
- return argc;
-}
-#define rb_check_arity rb_check_arity /* for ifdef */
-
-#if defined(NFDBITS) && defined(HAVE_RB_FD_INIT)
-typedef struct {
- int maxfd;
- fd_set *fdset;
-} rb_fdset_t;
-
-void rb_fd_init(rb_fdset_t *);
-void rb_fd_term(rb_fdset_t *);
-void rb_fd_zero(rb_fdset_t *);
-void rb_fd_set(int, rb_fdset_t *);
-void rb_fd_clr(int, rb_fdset_t *);
-int rb_fd_isset(int, const rb_fdset_t *);
-void rb_fd_copy(rb_fdset_t *, const fd_set *, int);
-void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);
-
-struct timeval;
-int rb_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *);
-
-#define rb_fd_ptr(f) ((f)->fdset)
-#define rb_fd_max(f) ((f)->maxfd)
-
-#elif defined(_WIN32)
-
-typedef struct {
- int capa;
- fd_set *fdset;
-} rb_fdset_t;
-
-void rb_fd_init(rb_fdset_t *);
-void rb_fd_term(rb_fdset_t *);
-#define rb_fd_zero(f) ((f)->fdset->fd_count = 0)
-void rb_fd_set(int, rb_fdset_t *);
-#define rb_fd_clr(n, f) rb_w32_fdclr((n), (f)->fdset)
-#define rb_fd_isset(n, f) rb_w32_fdisset((n), (f)->fdset)
-#define rb_fd_copy(d, s, n) rb_w32_fd_copy((d), (s), (n))
-void rb_w32_fd_copy(rb_fdset_t *, const fd_set *, int);
-#define rb_fd_dup(d, s) rb_w32_fd_dup((d), (s))
-void rb_w32_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);
-#define rb_fd_select(n, rfds, wfds, efds, timeout) rb_w32_select((n), (rfds) ? ((rb_fdset_t*)(rfds))->fdset : NULL, (wfds) ? ((rb_fdset_t*)(wfds))->fdset : NULL, (efds) ? ((rb_fdset_t*)(efds))->fdset: NULL, (timeout))
-#define rb_fd_resize(n, f) ((void)(f))
-
-#define rb_fd_ptr(f) ((f)->fdset)
-#define rb_fd_max(f) ((f)->fdset->fd_count)
-
-#else
-
-typedef fd_set rb_fdset_t;
-#define rb_fd_zero(f) FD_ZERO(f)
-#define rb_fd_set(n, f) FD_SET((n), (f))
-#define rb_fd_clr(n, f) FD_CLR((n), (f))
-#define rb_fd_isset(n, f) FD_ISSET((n), (f))
-#define rb_fd_copy(d, s, n) (*(d) = *(s))
-#define rb_fd_dup(d, s) (*(d) = *(s))
-#define rb_fd_resize(n, f) ((void)(f))
-#define rb_fd_ptr(f) (f)
-#define rb_fd_init(f) FD_ZERO(f)
-#define rb_fd_init_copy(d, s) (*(d) = *(s))
-#define rb_fd_term(f) ((void)(f))
-#define rb_fd_max(f) FD_SETSIZE
-#define rb_fd_select(n, rfds, wfds, efds, timeout) select((n), (rfds), (wfds), (efds), (timeout))
-
-#endif
-
-NORETURN(void rb_exc_raise(VALUE));
-NORETURN(void rb_exc_fatal(VALUE));
-NORETURN(VALUE rb_f_exit(int, const VALUE*));
-NORETURN(VALUE rb_f_abort(int, const VALUE*));
-void rb_remove_method(VALUE, const char*);
-void rb_remove_method_id(VALUE, ID);
-#define HAVE_RB_DEFINE_ALLOC_FUNC 1
-typedef VALUE (*rb_alloc_func_t)(VALUE);
-void rb_define_alloc_func(VALUE, rb_alloc_func_t);
-void rb_undef_alloc_func(VALUE);
-rb_alloc_func_t rb_get_alloc_func(VALUE);
-void rb_clear_constant_cache(void);
-void rb_clear_method_cache_by_class(VALUE);
-void rb_alias(VALUE, ID, ID);
-void rb_attr(VALUE,ID,int,int,int);
-int rb_method_boundp(VALUE, ID, int);
-int rb_method_basic_definition_p(VALUE, ID);
-VALUE rb_eval_cmd(VALUE, VALUE, int);
-int rb_obj_respond_to(VALUE, ID, int);
-int rb_respond_to(VALUE, ID);
-NORETURN(VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj));
-#if !defined(RUBY_EXPORT) && defined(_WIN32)
-RUBY_EXTERN VALUE (*const rb_f_notimplement_)(int, const VALUE *, VALUE);
-#define rb_f_notimplement (*rb_f_notimplement_)
-#endif
-NORETURN(void rb_interrupt(void));
-VALUE rb_apply(VALUE, ID, VALUE);
-void rb_backtrace(void);
-ID rb_frame_this_func(void);
-VALUE rb_obj_instance_eval(int, const VALUE*, VALUE);
-VALUE rb_obj_instance_exec(int, const VALUE*, VALUE);
-VALUE rb_mod_module_eval(int, const VALUE*, VALUE);
-VALUE rb_mod_module_exec(int, const VALUE*, VALUE);
-void rb_load(VALUE, int);
-void rb_load_protect(VALUE, int, int*);
-NORETURN(void rb_jump_tag(int));
-int rb_provided(const char*);
-int rb_feature_provided(const char *, const char **);
-void rb_provide(const char*);
-VALUE rb_f_require(VALUE, VALUE);
-VALUE rb_require_safe(VALUE, int);
-void rb_obj_call_init(VALUE, int, const VALUE*);
-VALUE rb_class_new_instance(int, const VALUE*, VALUE);
-VALUE rb_block_proc(void);
-VALUE rb_block_lambda(void);
-VALUE rb_proc_new(VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE);
-VALUE rb_obj_is_proc(VALUE);
-VALUE rb_proc_call(VALUE, VALUE);
-VALUE rb_proc_call_with_block(VALUE, int argc, const VALUE *argv, VALUE);
-int rb_proc_arity(VALUE);
-VALUE rb_proc_lambda_p(VALUE);
-VALUE rb_binding_new(void);
-VALUE rb_obj_method(VALUE, VALUE);
-VALUE rb_obj_is_method(VALUE);
-VALUE rb_method_call(int, const VALUE*, VALUE);
-VALUE rb_method_call_with_block(int, const VALUE *, VALUE, VALUE);
-int rb_mod_method_arity(VALUE, ID);
-int rb_obj_method_arity(VALUE, ID);
-VALUE rb_protect(VALUE (*)(VALUE), VALUE, int*);
-void rb_set_end_proc(void (*)(VALUE), VALUE);
-void rb_exec_end_proc(void);
-void rb_thread_schedule(void);
-void rb_thread_wait_fd(int);
-int rb_thread_fd_writable(int);
-void rb_thread_fd_close(int);
-int rb_thread_alone(void);
-void rb_thread_sleep(int);
-void rb_thread_sleep_forever(void);
-void rb_thread_sleep_deadly(void);
-VALUE rb_thread_stop(void);
-VALUE rb_thread_wakeup(VALUE);
-VALUE rb_thread_wakeup_alive(VALUE);
-VALUE rb_thread_run(VALUE);
-VALUE rb_thread_kill(VALUE);
-VALUE rb_thread_create(VALUE (*)(ANYARGS), void*);
-int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *);
-void rb_thread_wait_for(struct timeval);
-VALUE rb_thread_current(void);
-VALUE rb_thread_main(void);
-VALUE rb_thread_local_aref(VALUE, ID);
-VALUE rb_thread_local_aset(VALUE, ID, VALUE);
-void rb_thread_atfork(void);
-void rb_thread_atfork_before_exec(void);
-VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
-VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE);
-VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
-VALUE rb_exec_recursive_paired_outer(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE);
-/* dir.c */
-VALUE rb_dir_getwd(void);
-/* file.c */
-VALUE rb_file_s_expand_path(int, const VALUE *);
-VALUE rb_file_expand_path(VALUE, VALUE);
-VALUE rb_file_s_absolute_path(int, const VALUE *);
-VALUE rb_file_absolute_path(VALUE, VALUE);
-VALUE rb_file_dirname(VALUE fname);
-int rb_find_file_ext_safe(VALUE*, const char* const*, int);
-VALUE rb_find_file_safe(VALUE, int);
-int rb_find_file_ext(VALUE*, const char* const*);
-VALUE rb_find_file(VALUE);
-VALUE rb_file_directory_p(VALUE,VALUE);
-VALUE rb_str_encode_ospath(VALUE);
-int rb_is_absolute_path(const char *);
-/* gc.c */
-NORETURN(void rb_memerror(void));
-PUREFUNC(int rb_during_gc(void));
-void rb_gc_mark_locations(const VALUE*, const VALUE*);
-void rb_mark_tbl(struct st_table*);
-void rb_mark_set(struct st_table*);
-void rb_mark_hash(struct st_table*);
-void rb_gc_mark_maybe(VALUE);
-void rb_gc_mark(VALUE);
-void rb_gc_force_recycle(VALUE);
-void rb_gc(void);
-void rb_gc_copy_finalizer(VALUE,VALUE);
-void rb_gc_finalize_deferred(void);
-void rb_gc_call_finalizer_at_exit(void);
-VALUE rb_gc_enable(void);
-VALUE rb_gc_disable(void);
-VALUE rb_gc_start(void);
-VALUE rb_define_finalizer(VALUE, VALUE);
-VALUE rb_undefine_finalizer(VALUE);
-size_t rb_gc_count(void);
-size_t rb_gc_stat(VALUE);
-VALUE rb_gc_latest_gc_info(VALUE);
-void rb_gc_adjust_memory_usage(ssize_t);
-/* hash.c */
-void st_foreach_safe(struct st_table *, int (*)(ANYARGS), st_data_t);
-VALUE rb_check_hash_type(VALUE);
-void rb_hash_foreach(VALUE, int (*)(ANYARGS), VALUE);
-VALUE rb_hash(VALUE);
-VALUE rb_hash_new(void);
-VALUE rb_hash_dup(VALUE);
-VALUE rb_hash_freeze(VALUE);
-VALUE rb_hash_aref(VALUE, VALUE);
-VALUE rb_hash_lookup(VALUE, VALUE);
-VALUE rb_hash_lookup2(VALUE, VALUE, VALUE);
-VALUE rb_hash_fetch(VALUE, VALUE);
-VALUE rb_hash_aset(VALUE, VALUE, VALUE);
-VALUE rb_hash_clear(VALUE);
-VALUE rb_hash_delete_if(VALUE);
-VALUE rb_hash_delete(VALUE,VALUE);
-VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
-typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value);
-VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func);
-struct st_table *rb_hash_tbl(VALUE);
-int rb_path_check(const char*);
-int rb_env_path_tainted(void);
-VALUE rb_env_clear(void);
-VALUE rb_hash_size(VALUE);
-/* io.c */
-#define rb_defout rb_stdout
-RUBY_EXTERN VALUE rb_fs;
-RUBY_EXTERN VALUE rb_output_fs;
-RUBY_EXTERN VALUE rb_rs;
-RUBY_EXTERN VALUE rb_default_rs;
-RUBY_EXTERN VALUE rb_output_rs;
-VALUE rb_io_write(VALUE, VALUE);
-VALUE rb_io_gets(VALUE);
-VALUE rb_io_getbyte(VALUE);
-VALUE rb_io_ungetc(VALUE, VALUE);
-VALUE rb_io_ungetbyte(VALUE, VALUE);
-VALUE rb_io_close(VALUE);
-VALUE rb_io_flush(VALUE);
-VALUE rb_io_eof(VALUE);
-VALUE rb_io_binmode(VALUE);
-VALUE rb_io_ascii8bit_binmode(VALUE);
-VALUE rb_io_addstr(VALUE, VALUE);
-VALUE rb_io_printf(int, const VALUE*, VALUE);
-VALUE rb_io_print(int, const VALUE*, VALUE);
-VALUE rb_io_puts(int, const VALUE*, VALUE);
-VALUE rb_io_fdopen(int, int, const char*);
-VALUE rb_io_get_io(VALUE);
-VALUE rb_file_open(const char*, const char*);
-VALUE rb_file_open_str(VALUE, const char*);
-VALUE rb_gets(void);
-void rb_write_error(const char*);
-void rb_write_error2(const char*, long);
-void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds);
-int rb_pipe(int *pipes);
-int rb_reserved_fd_p(int fd);
-int rb_cloexec_open(const char *pathname, int flags, mode_t mode);
-int rb_cloexec_dup(int oldfd);
-int rb_cloexec_dup2(int oldfd, int newfd);
-int rb_cloexec_pipe(int fildes[2]);
-int rb_cloexec_fcntl_dupfd(int fd, int minfd);
-#define RB_RESERVED_FD_P(fd) rb_reserved_fd_p(fd)
-void rb_update_max_fd(int fd);
-void rb_fd_fix_cloexec(int fd);
-/* marshal.c */
-VALUE rb_marshal_dump(VALUE, VALUE);
-VALUE rb_marshal_load(VALUE);
-void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE));
-/* numeric.c */
-NORETURN(void rb_num_zerodiv(void));
-#define RB_NUM_COERCE_FUNCS_NEED_OPID 1
-VALUE rb_num_coerce_bin(VALUE, VALUE, ID);
-VALUE rb_num_coerce_cmp(VALUE, VALUE, ID);
-VALUE rb_num_coerce_relop(VALUE, VALUE, ID);
-VALUE rb_num_coerce_bit(VALUE, VALUE, ID);
-VALUE rb_num2fix(VALUE);
-VALUE rb_fix2str(VALUE, int);
-CONSTFUNC(VALUE rb_dbl_cmp(double, double));
-/* object.c */
-int rb_eql(VALUE, VALUE);
-VALUE rb_any_to_s(VALUE);
-VALUE rb_inspect(VALUE);
-VALUE rb_obj_is_instance_of(VALUE, VALUE);
-VALUE rb_obj_is_kind_of(VALUE, VALUE);
-VALUE rb_obj_alloc(VALUE);
-VALUE rb_obj_clone(VALUE);
-VALUE rb_obj_dup(VALUE);
-VALUE rb_obj_init_copy(VALUE,VALUE);
-VALUE rb_obj_taint(VALUE);
-PUREFUNC(VALUE rb_obj_tainted(VALUE));
-VALUE rb_obj_untaint(VALUE);
-VALUE rb_obj_untrust(VALUE);
-PUREFUNC(VALUE rb_obj_untrusted(VALUE));
-VALUE rb_obj_trust(VALUE);
-VALUE rb_obj_freeze(VALUE);
-PUREFUNC(VALUE rb_obj_frozen_p(VALUE));
-VALUE rb_obj_id(VALUE);
-VALUE rb_obj_class(VALUE);
-PUREFUNC(VALUE rb_class_real(VALUE));
-PUREFUNC(VALUE rb_class_inherited_p(VALUE, VALUE));
-VALUE rb_class_superclass(VALUE);
-VALUE rb_class_get_superclass(VALUE);
-VALUE rb_convert_type(VALUE,int,const char*,const char*);
-VALUE rb_check_convert_type(VALUE,int,const char*,const char*);
-VALUE rb_check_to_integer(VALUE, const char *);
-VALUE rb_check_to_float(VALUE);
-VALUE rb_to_int(VALUE);
-VALUE rb_check_to_int(VALUE);
-VALUE rb_Integer(VALUE);
-VALUE rb_to_float(VALUE);
-VALUE rb_Float(VALUE);
-VALUE rb_String(VALUE);
-VALUE rb_Array(VALUE);
-VALUE rb_Hash(VALUE);
-double rb_cstr_to_dbl(const char*, int);
-double rb_str_to_dbl(VALUE, int);
-/* parse.y */
-ID rb_id_attrset(ID);
-CONSTFUNC(int rb_is_const_id(ID));
-CONSTFUNC(int rb_is_global_id(ID));
-CONSTFUNC(int rb_is_instance_id(ID));
-CONSTFUNC(int rb_is_attrset_id(ID));
-CONSTFUNC(int rb_is_class_id(ID));
-CONSTFUNC(int rb_is_local_id(ID));
-CONSTFUNC(int rb_is_junk_id(ID));
-int rb_symname_p(const char*);
-int rb_sym_interned_p(VALUE);
-VALUE rb_backref_get(void);
-void rb_backref_set(VALUE);
-VALUE rb_lastline_get(void);
-void rb_lastline_set(VALUE);
-/* process.c */
-void rb_last_status_set(int status, rb_pid_t pid);
-VALUE rb_last_status_get(void);
-int rb_proc_exec(const char*);
-NORETURN(VALUE rb_f_exec(int, const VALUE*));
-rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags);
-void rb_syswait(rb_pid_t pid);
-rb_pid_t rb_spawn(int, const VALUE*);
-rb_pid_t rb_spawn_err(int, const VALUE*, char*, size_t);
-VALUE rb_proc_times(VALUE);
-VALUE rb_detach_process(rb_pid_t pid);
-/* range.c */
-VALUE rb_range_new(VALUE, VALUE, int);
-VALUE rb_range_beg_len(VALUE, long*, long*, long, int);
-int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp);
-/* random.c */
-unsigned int rb_genrand_int32(void);
-double rb_genrand_real(void);
-void rb_reset_random_seed(void);
-VALUE rb_random_bytes(VALUE rnd, long n);
-VALUE rb_random_int(VALUE rnd, VALUE max);
-unsigned int rb_random_int32(VALUE rnd);
-double rb_random_real(VALUE rnd);
-unsigned long rb_random_ulong_limited(VALUE rnd, unsigned long limit);
-unsigned long rb_genrand_ulong_limited(unsigned long i);
-/* re.c */
-#define rb_memcmp memcmp
-int rb_memcicmp(const void*,const void*,long);
-void rb_match_busy(VALUE);
-VALUE rb_reg_nth_defined(int, VALUE);
-VALUE rb_reg_nth_match(int, VALUE);
-int rb_reg_backref_number(VALUE match, VALUE backref);
-VALUE rb_reg_last_match(VALUE);
-VALUE rb_reg_match_pre(VALUE);
-VALUE rb_reg_match_post(VALUE);
-VALUE rb_reg_match_last(VALUE);
-#define HAVE_RB_REG_NEW_STR 1
-VALUE rb_reg_new_str(VALUE, int);
-VALUE rb_reg_new(const char *, long, int);
-VALUE rb_reg_alloc(void);
-VALUE rb_reg_init_str(VALUE re, VALUE s, int options);
-VALUE rb_reg_match(VALUE, VALUE);
-VALUE rb_reg_match2(VALUE);
-int rb_reg_options(VALUE);
-/* ruby.c */
-#define rb_argv rb_get_argv()
-RUBY_EXTERN VALUE rb_argv0;
-VALUE rb_get_argv(void);
-void *rb_load_file(const char*);
-void *rb_load_file_str(VALUE);
-/* signal.c */
-VALUE rb_f_kill(int, const VALUE*);
-#ifdef POSIX_SIGNAL
-#define posix_signal ruby_posix_signal
-RETSIGTYPE (*posix_signal(int, RETSIGTYPE (*)(int)))(int);
-#endif
-void rb_trap_exit(void);
-void rb_trap_exec(void);
-const char *ruby_signal_name(int);
-void ruby_default_signal(int);
-/* sprintf.c */
-VALUE rb_f_sprintf(int, const VALUE*);
-PRINTF_ARGS(VALUE rb_sprintf(const char*, ...), 1, 2);
-VALUE rb_vsprintf(const char*, va_list);
-PRINTF_ARGS(VALUE rb_str_catf(VALUE, const char*, ...), 2, 3);
-VALUE rb_str_vcatf(VALUE, const char*, va_list);
-VALUE rb_str_format(int, const VALUE *, VALUE);
-/* string.c */
-VALUE rb_str_new(const char*, long);
-VALUE rb_str_new_cstr(const char*);
-VALUE rb_str_new_shared(VALUE);
-VALUE rb_str_new_frozen(VALUE);
-VALUE rb_str_new_with_class(VALUE, const char*, long);
-VALUE rb_tainted_str_new_cstr(const char*);
-VALUE rb_tainted_str_new(const char*, long);
-VALUE rb_external_str_new(const char*, long);
-VALUE rb_external_str_new_cstr(const char*);
-VALUE rb_locale_str_new(const char*, long);
-VALUE rb_locale_str_new_cstr(const char*);
-VALUE rb_filesystem_str_new(const char*, long);
-VALUE rb_filesystem_str_new_cstr(const char*);
-VALUE rb_str_buf_new(long);
-VALUE rb_str_buf_new_cstr(const char*);
-VALUE rb_str_buf_new2(const char*);
-VALUE rb_str_tmp_new(long);
-VALUE rb_usascii_str_new(const char*, long);
-VALUE rb_usascii_str_new_cstr(const char*);
-VALUE rb_utf8_str_new(const char*, long);
-VALUE rb_utf8_str_new_cstr(const char*);
-VALUE rb_str_new_static(const char *, long);
-VALUE rb_usascii_str_new_static(const char *, long);
-VALUE rb_utf8_str_new_static(const char *, long);
-void rb_str_free(VALUE);
-void rb_str_shared_replace(VALUE, VALUE);
-VALUE rb_str_buf_append(VALUE, VALUE);
-VALUE rb_str_buf_cat(VALUE, const char*, long);
-VALUE rb_str_buf_cat2(VALUE, const char*);
-VALUE rb_str_buf_cat_ascii(VALUE, const char*);
-VALUE rb_obj_as_string(VALUE);
-VALUE rb_check_string_type(VALUE);
-void rb_must_asciicompat(VALUE);
-VALUE rb_str_dup(VALUE);
-VALUE rb_str_resurrect(VALUE str);
-VALUE rb_str_locktmp(VALUE);
-VALUE rb_str_unlocktmp(VALUE);
-VALUE rb_str_dup_frozen(VALUE);
-#define rb_str_dup_frozen rb_str_new_frozen
-VALUE rb_str_plus(VALUE, VALUE);
-VALUE rb_str_times(VALUE, VALUE);
-long rb_str_sublen(VALUE, long);
-VALUE rb_str_substr(VALUE, long, long);
-VALUE rb_str_subseq(VALUE, long, long);
-char *rb_str_subpos(VALUE, long, long*);
-void rb_str_modify(VALUE);
-void rb_str_modify_expand(VALUE, long);
-VALUE rb_str_freeze(VALUE);
-void rb_str_set_len(VALUE, long);
-VALUE rb_str_resize(VALUE, long);
-VALUE rb_str_cat(VALUE, const char*, long);
-VALUE rb_str_cat_cstr(VALUE, const char*);
-VALUE rb_str_cat2(VALUE, const char*);
-VALUE rb_str_append(VALUE, VALUE);
-VALUE rb_str_concat(VALUE, VALUE);
-st_index_t rb_memhash(const void *ptr, long len);
-st_index_t rb_hash_start(st_index_t);
-st_index_t rb_hash_uint32(st_index_t, uint32_t);
-st_index_t rb_hash_uint(st_index_t, st_index_t);
-st_index_t rb_hash_end(st_index_t);
-#define rb_hash_uint32(h, i) st_hash_uint32((h), (i))
-#define rb_hash_uint(h, i) st_hash_uint((h), (i))
-#define rb_hash_end(h) st_hash_end(h)
-st_index_t rb_str_hash(VALUE);
-int rb_str_hash_cmp(VALUE,VALUE);
-int rb_str_comparable(VALUE, VALUE);
-int rb_str_cmp(VALUE, VALUE);
-VALUE rb_str_equal(VALUE str1, VALUE str2);
-VALUE rb_str_drop_bytes(VALUE, long);
-void rb_str_update(VALUE, long, long, VALUE);
-VALUE rb_str_replace(VALUE, VALUE);
-VALUE rb_str_inspect(VALUE);
-VALUE rb_str_dump(VALUE);
-VALUE rb_str_split(VALUE, const char*);
-void rb_str_setter(VALUE, ID, VALUE*);
-VALUE rb_str_intern(VALUE);
-VALUE rb_sym_to_s(VALUE);
-long rb_str_strlen(VALUE);
-VALUE rb_str_length(VALUE);
-long rb_str_offset(VALUE, long);
-PUREFUNC(size_t rb_str_capacity(VALUE));
-VALUE rb_str_ellipsize(VALUE, long);
-VALUE rb_str_scrub(VALUE, VALUE);
-/* symbol.c */
-VALUE rb_sym_all_symbols(void);
-
-#ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
-#define rb_str_new(str, len) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str) && __builtin_constant_p(len)) ? \
- rb_str_new_static((str), (len)) : \
- rb_str_new((str), (len)) \
-)
-#define rb_str_new_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_str_new_static((str), (long)strlen(str)) : \
- rb_str_new_cstr(str) \
-)
-#define rb_usascii_str_new(str, len) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str) && __builtin_constant_p(len)) ? \
- rb_usascii_str_new_static((str), (len)) : \
- rb_usascii_str_new((str), (len)) \
-)
-#define rb_utf8_str_new(str, len) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str) && __builtin_constant_p(len)) ? \
- rb_utf8_str_new_static((str), (len)) : \
- rb_utf8_str_new((str), (len)) \
-)
-#define rb_tainted_str_new_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_tainted_str_new((str), (long)strlen(str)) : \
- rb_tainted_str_new_cstr(str) \
-)
-#define rb_usascii_str_new_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_usascii_str_new_static((str), (long)strlen(str)) : \
- rb_usascii_str_new_cstr(str) \
-)
-#define rb_utf8_str_new_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_utf8_str_new_static((str), (long)strlen(str)) : \
- rb_utf8_str_new_cstr(str) \
-)
-#define rb_external_str_new_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_external_str_new((str), (long)strlen(str)) : \
- rb_external_str_new_cstr(str) \
-)
-#define rb_locale_str_new_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_locale_str_new((str), (long)strlen(str)) : \
- rb_locale_str_new_cstr(str) \
-)
-#define rb_str_buf_new_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_str_buf_cat(rb_str_buf_new((long)strlen(str)), \
- (str), (long)strlen(str)) : \
- rb_str_buf_new_cstr(str) \
-)
-#define rb_str_cat_cstr(str, ptr) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(ptr)) ? \
- rb_str_cat((str), (ptr), (long)strlen(ptr)) : \
- rb_str_cat_cstr((str), (ptr)) \
-)
-#define rb_exc_new_cstr(klass, ptr) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(ptr)) ? \
- rb_exc_new((klass), (ptr), (long)strlen(ptr)) : \
- rb_exc_new_cstr((klass), (ptr)) \
-)
-#endif
-#define rb_str_new2 rb_str_new_cstr
-#define rb_str_new3 rb_str_new_shared
-#define rb_str_new4 rb_str_new_frozen
-#define rb_str_new5 rb_str_new_with_class
-#define rb_tainted_str_new2 rb_tainted_str_new_cstr
-#define rb_str_buf_new2 rb_str_buf_new_cstr
-#define rb_usascii_str_new2 rb_usascii_str_new_cstr
-#define rb_str_buf_cat rb_str_cat
-#define rb_str_buf_cat2 rb_str_cat_cstr
-#define rb_str_cat2 rb_str_cat_cstr
-#define rb_strlen_lit(str) (sizeof(str "") - 1)
-#define rb_str_new_lit(str) rb_str_new_static((str), rb_strlen_lit(str))
-#define rb_usascii_str_new_lit(str) rb_usascii_str_new_static((str), rb_strlen_lit(str))
-#define rb_utf8_str_new_lit(str) rb_utf8_str_new_static((str), rb_strlen_lit(str))
-#define rb_enc_str_new_lit(str, enc) rb_enc_str_new_static((str), rb_strlen_lit(str), (enc))
-#define rb_str_new_literal(str) rb_str_new_lit(str)
-#define rb_usascii_str_new_literal(str) rb_usascii_str_new_lit(str)
-#define rb_utf8_str_new_literal(str) rb_utf8_str_new_lit(str)
-#define rb_enc_str_new_literal(str, enc) rb_enc_str_new_lit(str, enc)
-
-/* struct.c */
-VALUE rb_struct_new(VALUE, ...);
-VALUE rb_struct_define(const char*, ...);
-VALUE rb_struct_define_under(VALUE, const char*, ...);
-VALUE rb_struct_alloc(VALUE, VALUE);
-VALUE rb_struct_initialize(VALUE, VALUE);
-VALUE rb_struct_aref(VALUE, VALUE);
-VALUE rb_struct_aset(VALUE, VALUE, VALUE);
-VALUE rb_struct_getmember(VALUE, ID);
-VALUE rb_struct_s_members(VALUE);
-VALUE rb_struct_members(VALUE);
-VALUE rb_struct_size(VALUE s);
-VALUE rb_struct_alloc_noinit(VALUE);
-VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t, ...);
-VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...);
-
-/* thread.c */
-typedef void rb_unblock_function_t(void *);
-typedef VALUE rb_blocking_function_t(void *);
-void rb_thread_check_ints(void);
-int rb_thread_interrupted(VALUE thval);
-
-#define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
-#define RUBY_UBF_PROCESS ((rb_unblock_function_t *)-1)
-VALUE rb_mutex_new(void);
-VALUE rb_mutex_locked_p(VALUE mutex);
-VALUE rb_mutex_trylock(VALUE mutex);
-VALUE rb_mutex_lock(VALUE mutex);
-VALUE rb_mutex_unlock(VALUE mutex);
-VALUE rb_mutex_sleep(VALUE self, VALUE timeout);
-VALUE rb_mutex_synchronize(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg);
-/* time.c */
-void rb_timespec_now(struct timespec *);
-VALUE rb_time_new(time_t, long);
-VALUE rb_time_nano_new(time_t, long);
-VALUE rb_time_timespec_new(const struct timespec *, int);
-VALUE rb_time_num_new(VALUE, VALUE);
-struct timeval rb_time_interval(VALUE num);
-struct timeval rb_time_timeval(VALUE time);
-struct timespec rb_time_timespec(VALUE time);
-/* variable.c */
-VALUE rb_mod_name(VALUE);
-VALUE rb_class_path(VALUE);
-VALUE rb_class_path_cached(VALUE);
-void rb_set_class_path(VALUE, VALUE, const char*);
-void rb_set_class_path_string(VALUE, VALUE, VALUE);
-VALUE rb_path_to_class(VALUE);
-VALUE rb_path2class(const char*);
-void rb_name_class(VALUE, ID);
-VALUE rb_class_name(VALUE);
-VALUE rb_autoload_load(VALUE, ID);
-VALUE rb_autoload_p(VALUE, ID);
-VALUE rb_f_trace_var(int, const VALUE*);
-VALUE rb_f_untrace_var(int, const VALUE*);
-VALUE rb_f_global_variables(void);
-void rb_alias_variable(ID, ID);
-void rb_copy_generic_ivar(VALUE,VALUE);
-void rb_free_generic_ivar(VALUE);
-VALUE rb_ivar_get(VALUE, ID);
-VALUE rb_ivar_set(VALUE, ID, VALUE);
-VALUE rb_ivar_defined(VALUE, ID);
-void rb_ivar_foreach(VALUE, int (*)(ANYARGS), st_data_t);
-st_index_t rb_ivar_count(VALUE);
-VALUE rb_attr_get(VALUE, ID);
-VALUE rb_obj_instance_variables(VALUE);
-VALUE rb_obj_remove_instance_variable(VALUE, VALUE);
-void *rb_mod_const_at(VALUE, void*);
-void *rb_mod_const_of(VALUE, void*);
-VALUE rb_const_list(void*);
-VALUE rb_mod_constants(int, const VALUE *, VALUE);
-VALUE rb_mod_remove_const(VALUE, VALUE);
-int rb_const_defined(VALUE, ID);
-int rb_const_defined_at(VALUE, ID);
-int rb_const_defined_from(VALUE, ID);
-VALUE rb_const_get(VALUE, ID);
-VALUE rb_const_get_at(VALUE, ID);
-VALUE rb_const_get_from(VALUE, ID);
-void rb_const_set(VALUE, ID, VALUE);
-VALUE rb_const_remove(VALUE, ID);
-NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
-VALUE rb_cvar_defined(VALUE, ID);
-void rb_cvar_set(VALUE, ID, VALUE);
-VALUE rb_cvar_get(VALUE, ID);
-void rb_cv_set(VALUE, const char*, VALUE);
-VALUE rb_cv_get(VALUE, const char*);
-void rb_define_class_variable(VALUE, const char*, VALUE);
-VALUE rb_mod_class_variables(int, const VALUE*, VALUE);
-VALUE rb_mod_remove_cvar(VALUE, VALUE);
-
-ID rb_frame_callee(void);
-VALUE rb_str_succ(VALUE);
-VALUE rb_time_succ(VALUE);
-int rb_frame_method_id_and_class(ID *idp, VALUE *klassp);
-VALUE rb_make_backtrace(void);
-VALUE rb_make_exception(int, const VALUE*);
-
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+#include "ruby/internal/intern/array.h"
+#include "ruby/internal/intern/bignum.h"
+#include "ruby/internal/intern/class.h"
+#include "ruby/internal/intern/compar.h"
+#include "ruby/internal/intern/complex.h"
+#include "ruby/internal/intern/cont.h"
+#include "ruby/internal/intern/dir.h"
+#include "ruby/internal/intern/enum.h"
+#include "ruby/internal/intern/enumerator.h"
+#include "ruby/internal/intern/error.h"
+#include "ruby/internal/intern/eval.h"
+#include "ruby/internal/intern/file.h"
+#include "ruby/internal/intern/gc.h"
+#include "ruby/internal/intern/hash.h"
+#include "ruby/internal/intern/io.h"
+#include "ruby/internal/intern/load.h"
+#include "ruby/internal/intern/marshal.h"
+#include "ruby/internal/intern/numeric.h"
+#include "ruby/internal/intern/object.h"
+#include "ruby/internal/intern/parse.h"
+#include "ruby/internal/intern/proc.h"
+#include "ruby/internal/intern/process.h"
+#include "ruby/internal/intern/random.h"
+#include "ruby/internal/intern/range.h"
+#include "ruby/internal/intern/rational.h"
+#include "ruby/internal/intern/re.h"
+#include "ruby/internal/intern/ruby.h"
+#include "ruby/internal/intern/select.h"
+#include "ruby/internal/intern/signal.h"
+#include "ruby/internal/intern/sprintf.h"
+#include "ruby/internal/intern/string.h"
+#include "ruby/internal/intern/struct.h"
+#include "ruby/internal/intern/thread.h"
+#include "ruby/internal/intern/time.h"
+#include "ruby/internal/intern/variable.h"
+#include "ruby/internal/intern/vm.h"
#endif /* RUBY_INTERN_H */
diff --git a/include/ruby/internal/anyargs.h b/include/ruby/internal/anyargs.h
new file mode 100644
index 0000000000..f09a4e72e9
--- /dev/null
+++ b/include/ruby/internal/anyargs.h
@@ -0,0 +1,375 @@
+#ifndef RBIMPL_ANYARGS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ANYARGS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Function overloads to issue warnings around #ANYARGS.
+ *
+ * For instance ::rb_define_method takes a pointer to #ANYARGS -ed functions,
+ * which in fact varies 18 different prototypes. We still need to preserve
+ * #ANYARGS for storages but why not check the consistencies if possible. With
+ * those complex macro overlays defined in this header file, use of a function
+ * pointer gets checked against the corresponding arity argument.
+ *
+ * ### Q&A ###
+ *
+ * - Q: Where did the magic number "18" came from in the description above?
+ *
+ * - A: Count the case branch of `vm_method.c:call_cfunc_invoker_func()`. Note
+ * also that the 18 branches has lasted for at least 25 years. See also
+ * commit 200e0ee2fd3c1c006c528874a88f684447215524.
+ *
+ * - Q: What is this `__weakref__` thing?
+ *
+ * - A: That is a kind of function overloading mechanism that GCC provides. In
+ * this case for instance `rb_define_method_00` is an alias of
+ * ::rb_define_method, with a strong type.
+ *
+ * - Q: What is this `__transparent_union__` thing?
+ *
+ * A: That is another kind of function overloading mechanism that GCC
+ * provides. In this case the attributed function pointer is either
+ * `VALUE(*)(int,VALUE*,VALUE)` or `VALUE(*)(int,const VALUE*,VALUE)`.
+ *
+ * This is better than `void*` or #ANYARGS because we can reject all other
+ * possibilities than the two.
+ *
+ * - Q: What does this #rb_define_method macro mean?
+ *
+ * - A: It selects appropriate alias of the ::rb_define_method function,
+ * depending on the last (arity) argument.
+ *
+ * - Q: Why the special case for ::rb_f_notimplement ?
+ *
+ * - A: Function pointer to ::rb_f_notimplement is special cased in
+ * `vm_method.c:rb_add_method_cfunc()`. That should be handled by the
+ * `__builtin_choose_expr` chain inside of #rb_define_method macro
+ * expansion. In order to do so, comparison like
+ * `(func == rb_f_notimplement)` is inappropriate for
+ * `__builtin_choose_expr`'s expression (which must be a compile-time
+ * integer constant but the address of ::rb_f_notimplement is not fixed
+ * until the linker). Instead we are using
+ * `__builtin_types_compatible_p`, and in doing so we need to distinguish
+ * ::rb_f_notimplement from others, by type.
+ */
+#include "ruby/internal/attr/maybe_unused.h"
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/weakref.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/config.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/intern/class.h"
+#include "ruby/internal/intern/vm.h"
+#include "ruby/internal/method.h"
+#include "ruby/internal/value.h"
+#include "ruby/backward/2/stdarg.h"
+
+#if defined(__cplusplus)
+# include "ruby/backward/cxxanyargs.hpp"
+
+#elif defined(_WIN32) || defined(__CYGWIN__)
+# /* Skip due to [Bug #16134] */
+
+#elif ! RBIMPL_HAS_ATTRIBUTE(transparent_union)
+# /* :TODO: improve here, please find a way to support. */
+
+#elif ! defined(HAVE_VA_ARGS_MACRO)
+# /* :TODO: improve here, please find a way to support. */
+
+#else
+# /** @cond INTERNAL_MACRO */
+# if ! defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
+# define RBIMPL_CFUNC_IS_rb_f_notimplement(f) 0
+# else
+# define RBIMPL_CFUNC_IS_rb_f_notimplement(f) \
+ __builtin_types_compatible_p( \
+ __typeof__(f), \
+ __typeof__(rb_f_notimplement))
+# endif
+
+# if ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
+# define RBIMPL_ANYARGS_DISPATCH(expr, truthy, falsy) (falsy)
+# else
+# define RBIMPL_ANYARGS_DISPATCH(expr, truthy, falsy) \
+ __builtin_choose_expr( \
+ __builtin_choose_expr( \
+ __builtin_constant_p(expr), \
+ (expr), 0), \
+ (truthy), (falsy))
+# endif
+
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_singleton_method_m2, rb_define_singleton_method_m3)
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_singleton_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_singleton_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_singleton_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_singleton_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_singleton_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_singleton_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_singleton_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_singleton_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_singleton_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_singleton_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_singleton_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_singleton_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_singleton_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_singleton_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_singleton_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_singleton_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_singleton_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_protected_method_m2, rb_define_protected_method_m3)
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_protected_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_protected_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_protected_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_protected_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_protected_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_protected_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_protected_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_protected_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_protected_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_protected_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_protected_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_protected_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_protected_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_protected_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_protected_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_protected_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_protected_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_private_method_m2, rb_define_private_method_m3)
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_private_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_private_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_private_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_private_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_private_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_private_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_private_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_private_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_private_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_private_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_private_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_private_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_private_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_private_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_private_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_private_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_private_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_module_function_m2, rb_define_module_function_m3)
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_module_function_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_module_function_00, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_module_function_01, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_module_function_02, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_module_function_03, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_module_function_04, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_module_function_05, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_module_function_06, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_module_function_07, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_module_function_08, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_module_function_09, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_module_function_10, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_module_function_11, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_module_function_12, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_module_function_13, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_module_function_14, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_module_function_15, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_global_function_m2, rb_define_global_function_m3)
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_global_function_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_global_function_00, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_global_function_01, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_global_function_02, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_global_function_03, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_global_function_04, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_global_function_05, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_global_function_06, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_global_function_07, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_global_function_08, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_global_function_09, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_global_function_10, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_global_function_11, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_global_function_12, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_global_function_13, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_global_function_14, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_global_function_15, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_id_m2, rb_define_method_id_m3)
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_id_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_method_id_00, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_method_id_01, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_method_id_02, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_method_id_03, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_method_id_04, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_method_id_05, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_method_id_06, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_method_id_07, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_method_id_08, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_method_id_09, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_id_10, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_id_11, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_id_12, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_id_13, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_id_14, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_id_15, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_m2, rb_define_method_m3)
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_singleton_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_protected_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_private_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_module_function_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_global_function_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_id_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n))
+# define RBIMPL_ANYARGS_ATTRSET(sym) RBIMPL_ATTR_MAYBE_UNUSED() RBIMPL_ATTR_NONNULL() RBIMPL_ATTR_WEAKREF(sym)
+# define RBIMPL_ANYARGS_DECL(sym, ...) \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m3(__VA_ARGS__, VALUE(*)(ANYARGS), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m2(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m1(__VA_ARGS__, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _00(__VA_ARGS__, VALUE(*)(VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _01(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _02(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _03(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _04(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _05(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _06(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _07(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _08(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _09(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _10(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _11(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _12(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _13(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _14(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _15(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
+RBIMPL_ANYARGS_DECL(rb_define_singleton_method, VALUE, const char *)
+RBIMPL_ANYARGS_DECL(rb_define_protected_method, VALUE, const char *)
+RBIMPL_ANYARGS_DECL(rb_define_private_method, VALUE, const char *)
+RBIMPL_ANYARGS_DECL(rb_define_module_function, VALUE, const char *)
+RBIMPL_ANYARGS_DECL(rb_define_global_function, const char *)
+RBIMPL_ANYARGS_DECL(rb_define_method_id, VALUE, ID)
+RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
+/** @endcond */
+
+/**
+ * @brief Defines klass\#mid.
+ * @see ::rb_define_method
+ * @param klass Where the method lives.
+ * @param mid Name of the defining method.
+ * @param func Implementation of klass\#mid.
+ * @param arity Arity of klass\#mid.
+ */
+#define rb_define_method(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
+
+/**
+ * @brief Defines klass\#mid.
+ * @see ::rb_define_method_id
+ * @param klass Where the method lives.
+ * @param mid Name of the defining method.
+ * @param func Implementation of klass\#mid.
+ * @param arity Arity of klass\#mid.
+ */
+#define rb_define_method_id(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_method_id((arity), (func))((klass), (mid), (func), (arity))
+
+/**
+ * @brief Defines obj.mid.
+ * @see ::rb_define_singleton_method
+ * @param obj Where the method lives.
+ * @param mid Name of the defining method.
+ * @param func Implementation of obj.mid.
+ * @param arity Arity of obj.mid.
+ */
+#define rb_define_singleton_method(obj, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method((arity), (func))((obj), (mid), (func), (arity))
+
+/**
+ * @brief Defines klass\#mid and make it protected.
+ * @see ::rb_define_protected_method
+ * @param klass Where the method lives.
+ * @param mid Name of the defining method.
+ * @param func Implementation of klass\#mid.
+ * @param arity Arity of klass\#mid.
+ */
+#define rb_define_protected_method(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method((arity), (func))((klass), (mid), (func), (arity))
+
+/**
+ * @brief Defines klass\#mid and make it private.
+ * @see ::rb_define_private_method
+ * @param klass Where the method lives.
+ * @param mid Name of the defining method.
+ * @param func Implementation of klass\#mid.
+ * @param arity Arity of klass\#mid.
+ */
+#define rb_define_private_method(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_private_method((arity), (func))((klass), (mid), (func), (arity))
+
+/**
+ * @brief Defines mod\#mid and make it a module function.
+ * @see ::rb_define_module_function
+ * @param mod Where the method lives.
+ * @param mid Name of the defining method.
+ * @param func Implementation of mod\#mid.
+ * @param arity Arity of mod\#mid.
+ */
+#define rb_define_module_function(mod, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_module_function((arity), (func))((mod), (mid), (func), (arity))
+
+/**
+ * @brief Defines ::rb_mKerbel \#mid.
+ * @see ::rb_define_gobal_function
+ * @param mid Name of the defining method.
+ * @param func Implementation of ::rb_mKernel \#mid.
+ * @param arity Arity of ::rb_mKernel \#mid.
+ */
+#define rb_define_global_function(mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_global_function((arity), (func))((mid), (func), (arity))
+
+#endif /* __cplusplus */
+
+/**
+ * This macro is to properly cast a function parameter of *_define_method
+ * family. It has been around since 1.x era so you can maximize backwards
+ * compatibility by using it.
+ *
+ * ```CXX
+ * rb_define_method(klass, "method", RUBY_METHOD_FUNC(func), arity);
+ * ```
+ *
+ * @param func A pointer to a function that implements a method.
+ */
+#if ! defined(RUBY_DEVEL)
+# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
+
+#elif ! RUBY_DEVEL
+# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
+
+#elif ! defined(rb_define_method)
+# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
+
+#else
+# define RUBY_METHOD_FUNC(func) (func)
+
+#endif
+
+#endif /* RBIMPL_ANYARGS_H */
diff --git a/include/ruby/internal/arithmetic.h b/include/ruby/internal/arithmetic.h
new file mode 100644
index 0000000000..c3806db444
--- /dev/null
+++ b/include/ruby/internal/arithmetic.h
@@ -0,0 +1,38 @@
+#ifndef RBIMPL_ARITHMETIC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Conversion between C's arithmtic types and Ruby's numeric types.
+ */
+#include "ruby/internal/arithmetic/char.h"
+#include "ruby/internal/arithmetic/double.h"
+#include "ruby/internal/arithmetic/fixnum.h"
+#include "ruby/internal/arithmetic/gid_t.h"
+#include "ruby/internal/arithmetic/int.h"
+#include "ruby/internal/arithmetic/intptr_t.h"
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/arithmetic/long_long.h"
+#include "ruby/internal/arithmetic/mode_t.h"
+#include "ruby/internal/arithmetic/off_t.h"
+#include "ruby/internal/arithmetic/pid_t.h"
+#include "ruby/internal/arithmetic/short.h"
+#include "ruby/internal/arithmetic/size_t.h"
+#include "ruby/internal/arithmetic/st_data_t.h"
+#include "ruby/internal/arithmetic/uid_t.h"
+#endif /* RBIMPL_ARITHMETIC_H */
diff --git a/include/ruby/internal/arithmetic/char.h b/include/ruby/internal/arithmetic/char.h
new file mode 100644
index 0000000000..3033639a43
--- /dev/null
+++ b/include/ruby/internal/arithmetic/char.h
@@ -0,0 +1,58 @@
+#ifndef RBIMPL_ARITHMETIC_CHAR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_CHAR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `char` and Ruby's.
+ */
+#include "ruby/internal/arithmetic/int.h" /* NUM2INT is here, but */
+#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here.*/
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rstring.h"
+#include "ruby/internal/value_type.h"
+
+#define RB_NUM2CHR rb_num2char_inline
+#define NUM2CHR RB_NUM2CHR
+#define CHR2FIX RB_CHR2FIX
+
+/** @cond INTERNAL_MACRO */
+#define RB_CHR2FIX RB_CHR2FIX
+/** @endcond */
+
+RBIMPL_ATTR_CONST_UNLESS_DEBUG()
+RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RB_CHR2FIX(unsigned char c)
+{
+ return RB_INT2FIX(c);
+}
+
+static inline char
+rb_num2char_inline(VALUE x)
+{
+ if (RB_TYPE_P(x, RUBY_T_STRING) && (RSTRING_LEN(x)>=1))
+ return RSTRING_PTR(x)[0];
+ else
+ return RBIMPL_CAST((char)RB_NUM2INT(x));
+}
+
+#endif /* RBIMPL_ARITHMETIC_CHAR_H */
diff --git a/include/ruby/internal/arithmetic/double.h b/include/ruby/internal/arithmetic/double.h
new file mode 100644
index 0000000000..69d8630dbb
--- /dev/null
+++ b/include/ruby/internal/arithmetic/double.h
@@ -0,0 +1,39 @@
+#ifndef RBIMPL_ARITHMETIC_DOUBLE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_DOUBLE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `double` and Ruby's.
+ */
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+#define NUM2DBL rb_num2dbl
+#define RFLOAT_VALUE rb_float_value
+#define DBL2NUM rb_float_new
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+double rb_num2dbl(VALUE);
+RBIMPL_ATTR_PURE()
+double rb_float_value(VALUE);
+VALUE rb_float_new(double);
+VALUE rb_float_new_in_heap(double);
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_ARITHMETIC_DOUBLE_H */
diff --git a/include/ruby/internal/arithmetic/fixnum.h b/include/ruby/internal/arithmetic/fixnum.h
new file mode 100644
index 0000000000..68544b760b
--- /dev/null
+++ b/include/ruby/internal/arithmetic/fixnum.h
@@ -0,0 +1,44 @@
+#ifndef RBIMPL_ARITHMETIC_FIXNUM_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_FIXNUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Handling of integers formerly known as Fixnums.
+ */
+#include "ruby/backward/2/limits.h"
+
+#define FIXABLE RB_FIXABLE
+#define FIXNUM_MAX RUBY_FIXNUM_MAX
+#define FIXNUM_MIN RUBY_FIXNUM_MIN
+#define NEGFIXABLE RB_NEGFIXABLE
+#define POSFIXABLE RB_POSFIXABLE
+
+/*
+ * FIXABLE can be applied to anything, from double to intmax_t. The problem is
+ * double. On a 64bit system RUBY_FIXNUM_MAX is 4,611,686,018,427,387,903,
+ * which is not representable by a double. The nearest value that a double can
+ * represent is 4,611,686,018,427,387,904, which is not fixable. The
+ * seemingly-stragne "< FIXNUM_MAX + 1" expression below is due to this.
+ */
+#define RB_POSFIXABLE(_) ((_) < RUBY_FIXNUM_MAX + 1)
+#define RB_NEGFIXABLE(_) ((_) >= RUBY_FIXNUM_MIN)
+#define RB_FIXABLE(_) (RB_POSFIXABLE(_) && RB_NEGFIXABLE(_))
+#define RUBY_FIXNUM_MAX (LONG_MAX / 2)
+#define RUBY_FIXNUM_MIN (LONG_MIN / 2)
+
+#endif /* RBIMPL_ARITHMETIC_FIXNUM_H */
diff --git a/include/ruby/internal/arithmetic/gid_t.h b/include/ruby/internal/arithmetic/gid_t.h
new file mode 100644
index 0000000000..32e3578bd2
--- /dev/null
+++ b/include/ruby/internal/arithmetic/gid_t.h
@@ -0,0 +1,34 @@
+#ifndef RBIMPL_ARITHMETIC_GID_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_GID_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `gid_t` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/long.h"
+
+#ifndef GIDT2NUM
+# define GIDT2NUM RB_LONG2NUM
+#endif
+
+#ifndef NUM2GIDT
+# define NUM2GIDT RB_NUM2LONG
+#endif
+
+#endif /* RBIMPL_ARITHMETIC_GID_T_H */
diff --git a/include/ruby/internal/arithmetic/int.h b/include/ruby/internal/arithmetic/int.h
new file mode 100644
index 0000000000..346fa9258b
--- /dev/null
+++ b/include/ruby/internal/arithmetic/int.h
@@ -0,0 +1,163 @@
+#ifndef RBIMPL_ARITHMETIC_INT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_INT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `int` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/fixnum.h"
+#include "ruby/internal/arithmetic/intptr_t.h"
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/compiler_is.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/warning_push.h"
+#include "ruby/assert.h"
+
+#define RB_INT2NUM rb_int2num_inline
+#define RB_NUM2INT rb_num2int_inline
+#define RB_UINT2NUM rb_uint2num_inline
+
+#define FIX2INT RB_FIX2INT
+#define FIX2UINT RB_FIX2UINT
+#define INT2NUM RB_INT2NUM
+#define NUM2INT RB_NUM2INT
+#define NUM2UINT RB_NUM2UINT
+#define UINT2NUM RB_UINT2NUM
+
+/** @cond INTERNAL_MACRO */
+#define RB_FIX2INT RB_FIX2INT
+#define RB_NUM2UINT RB_NUM2UINT
+#define RB_FIX2UINT RB_FIX2UINT
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+long rb_num2int(VALUE);
+long rb_fix2int(VALUE);
+unsigned long rb_num2uint(VALUE);
+unsigned long rb_fix2uint(VALUE);
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+RB_FIX2INT(VALUE x)
+{
+ /* "FIX2INT raises a TypeError if passed nil", says rubyspec. Not sure if
+ * that is a desired behaviour but just preserve backwards compatilibily.
+ */
+#if 0
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+#endif
+ long ret;
+
+ if /* constexpr */ (sizeof(int) < sizeof(long)) {
+ ret = rb_fix2int(x);
+ }
+ else {
+ ret = RB_FIX2LONG(x);
+ }
+
+ return RBIMPL_CAST((int)ret);
+}
+
+static inline int
+rb_num2int_inline(VALUE x)
+{
+ long ret;
+
+ if /* constexpr */ (sizeof(int) == sizeof(long)) {
+ ret = RB_NUM2LONG(x);
+ }
+ else if (RB_FIXNUM_P(x)) {
+ ret = rb_fix2int(x);
+ }
+ else {
+ ret = rb_num2int(x);
+ }
+
+ return RBIMPL_CAST((int)ret);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline unsigned int
+RB_NUM2UINT(VALUE x)
+{
+ unsigned long ret;
+
+ if /* constexpr */ (sizeof(int) < sizeof(long)) {
+ ret = rb_num2uint(x);
+ }
+ else {
+ ret = RB_NUM2ULONG(x);
+ }
+
+ return RBIMPL_CAST((unsigned int)ret);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline unsigned int
+RB_FIX2UINT(VALUE x)
+{
+#if 0 /* Ditto for RB_FIX2INT. */
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+#endif
+ unsigned long ret;
+
+ if /* constexpr */ (sizeof(int) < sizeof(long)) {
+ ret = rb_fix2uint(x);
+ }
+ else {
+ ret = RB_FIX2ULONG(x);
+ }
+
+ return RBIMPL_CAST((unsigned int)ret);
+}
+
+RBIMPL_WARNING_PUSH()
+#if RBIMPL_COMPILER_IS(GCC)
+RBIMPL_WARNING_IGNORED(-Wtype-limits) /* We can ignore them here. */
+#elif RBIMPL_HAS_WARNING("-Wtautological-constant-out-of-range-compare")
+RBIMPL_WARNING_IGNORED(-Wtautological-constant-out-of-range-compare)
+#endif
+
+static inline VALUE
+rb_int2num_inline(int v)
+{
+ if (RB_FIXABLE(v))
+ return RB_INT2FIX(v);
+ else
+ return rb_int2big(v);
+}
+
+static inline VALUE
+rb_uint2num_inline(unsigned int v)
+{
+ if (RB_POSFIXABLE(v))
+ return RB_LONG2FIX(v);
+ else
+ return rb_uint2big(v);
+}
+
+RBIMPL_WARNING_POP()
+
+#endif /* RBIMPL_ARITHMETIC_INT_H */
diff --git a/include/ruby/internal/arithmetic/intptr_t.h b/include/ruby/internal/arithmetic/intptr_t.h
new file mode 100644
index 0000000000..442c87144c
--- /dev/null
+++ b/include/ruby/internal/arithmetic/intptr_t.h
@@ -0,0 +1,42 @@
+#ifndef RBIMPL_ARITHMETIC_INTPTR_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_INTPTR_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `intptr_t` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "ruby/internal/value.h"
+#include "ruby/internal/dllexport.h"
+
+#define rb_int_new rb_int2inum
+#define rb_uint_new rb_uint2inum
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_int2big(intptr_t i);
+VALUE rb_int2inum(intptr_t i);
+VALUE rb_uint2big(uintptr_t i);
+VALUE rb_uint2inum(uintptr_t i);
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_ARITHMETIC_INTPTR_T_H */
diff --git a/include/ruby/internal/arithmetic/long.h b/include/ruby/internal/arithmetic/long.h
new file mode 100644
index 0000000000..aff7d68478
--- /dev/null
+++ b/include/ruby/internal/arithmetic/long.h
@@ -0,0 +1,244 @@
+#ifndef RBIMPL_ARITHMETIC_LONG_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_LONG_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `long` and Ruby's.
+ *
+ * ### Q&A ###
+ *
+ * - Q: Why are INT2FIX etc. here, not in `int.h`?
+ *
+ * - A: Because they are in fact handling `long`. It seems someone did not
+ * understand the difference of `int` and `long` when they designed those
+ * macros.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/fixnum.h" /* FIXABLE */
+#include "ruby/internal/arithmetic/intptr_t.h" /* rb_int2big etc.*/
+#include "ruby/internal/assume.h"
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/cold.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h" /* FIXNUM_FLAG */
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+
+#define FIX2LONG RB_FIX2LONG
+#define FIX2ULONG RB_FIX2ULONG
+#define INT2FIX RB_INT2FIX
+#define LONG2FIX RB_INT2FIX
+#define LONG2NUM RB_LONG2NUM
+#define NUM2LONG RB_NUM2LONG
+#define NUM2ULONG RB_NUM2ULONG
+#define RB_FIX2LONG rb_fix2long
+#define RB_FIX2ULONG rb_fix2ulong
+#define RB_LONG2FIX RB_INT2FIX
+#define RB_LONG2NUM rb_long2num_inline
+#define RB_NUM2LONG rb_num2long_inline
+#define RB_NUM2ULONG rb_num2ulong_inline
+#define RB_ULONG2NUM rb_ulong2num_inline
+#define ULONG2NUM RB_ULONG2NUM
+#define rb_fix_new RB_INT2FIX
+#define rb_long2int rb_long2int_inline
+
+/** @cond INTERNAL_MACRO */
+#define RB_INT2FIX RB_INT2FIX
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+RBIMPL_ATTR_NORETURN()
+RBIMPL_ATTR_COLD()
+void rb_out_of_int(SIGNED_VALUE num);
+
+long rb_num2long(VALUE num);
+unsigned long rb_num2ulong(VALUE num);
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_CONST_UNLESS_DEBUG()
+RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RB_INT2FIX(long i)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(i));
+
+ /* :NOTE: VALUE can be wider than long. As j being unsigned, 2j+1 is fully
+ * defined. Also it can be compiled into a single LEA instruction. */
+ const unsigned long j = i;
+ const unsigned long k = 2 * j + RUBY_FIXNUM_FLAG;
+ const long l = k;
+ const SIGNED_VALUE m = l; /* Sign extend */
+ const VALUE n = m;
+
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(n));
+ return n;
+}
+
+static inline int
+rb_long2int_inline(long n)
+{
+ int i = RBIMPL_CAST((int)n);
+
+ if /* constexpr */ (sizeof(long) <= sizeof(int)) {
+ RBIMPL_ASSUME(i == n);
+ }
+
+ if (i != n)
+ rb_out_of_int(n);
+
+ return i;
+}
+
+RBIMPL_ATTR_CONST_UNLESS_DEBUG()
+RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
+static inline long
+rbimpl_fix2long_by_idiv(VALUE x)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+
+ /* :NOTE: VALUE can be wider than long. (x-1)/2 never overflows because
+ * RB_FIXNUM_P(x) holds. Also it has no portability issue like y>>1
+ * below. */
+ const SIGNED_VALUE y = x - RUBY_FIXNUM_FLAG;
+ const SIGNED_VALUE z = y / 2;
+ const long w = RBIMPL_CAST((long)z);
+
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(w));
+ return w;
+}
+
+RBIMPL_ATTR_CONST_UNLESS_DEBUG()
+RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
+static inline long
+rbimpl_fix2long_by_shift(VALUE x)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+
+ /* :NOTE: VALUE can be wider than long. If right shift is arithmetic, this
+ * is noticeably faster than above. */
+ const SIGNED_VALUE y = x;
+ const SIGNED_VALUE z = y >> 1;
+ const long w = RBIMPL_CAST((long)z);
+
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(w));
+ return w;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+static inline bool
+rbimpl_right_shift_is_arithmetic_p(void)
+{
+ return (-1 >> 1) == -1;
+}
+
+RBIMPL_ATTR_CONST_UNLESS_DEBUG()
+RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
+static inline long
+rb_fix2long(VALUE x)
+{
+ if /* constexpr */ (rbimpl_right_shift_is_arithmetic_p()) {
+ return rbimpl_fix2long_by_shift(x);
+ }
+ else {
+ return rbimpl_fix2long_by_idiv(x);
+ }
+}
+
+RBIMPL_ATTR_CONST_UNLESS_DEBUG()
+RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
+static inline unsigned long
+rb_fix2ulong(VALUE x)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+ return rb_fix2long(x);
+}
+
+static inline long
+rb_num2long_inline(VALUE x)
+{
+ if (RB_FIXNUM_P(x))
+ return RB_FIX2LONG(x);
+ else
+ return rb_num2long(x);
+}
+
+static inline unsigned long
+rb_num2ulong_inline(VALUE x)
+{
+ /* This (negative fixnum would become a large unsigned long while negative
+ * bignum is an exception) has been THE behaviour of NUM2ULONG since the
+ * beginning. It is strange, but we can no longer change how it works at
+ * this moment. We have to get by with it. See also:
+ * https://bugs.ruby-lang.org/issues/9089 */
+ if (RB_FIXNUM_P(x))
+ return RB_FIX2ULONG(x);
+ else
+ return rb_num2ulong(x);
+}
+
+static inline VALUE
+rb_long2num_inline(long v)
+{
+ if (RB_FIXABLE(v))
+ return RB_LONG2FIX(v);
+ else
+ return rb_int2big(v);
+}
+
+static inline VALUE
+rb_ulong2num_inline(unsigned long v)
+{
+ if (RB_POSFIXABLE(v))
+ return RB_LONG2FIX(v);
+ else
+ return rb_uint2big(v);
+}
+
+/**
+ * @cond INTERNAL_MACRO
+ *
+ * Following overload is necessary because sometimes INT2FIX is used as a enum
+ * value (e.g. `enum { FOO = INT2FIX(0) };`). THIS IS NG in theory because a
+ * VALUE does not fit into an enum (which must be a signed int). But we cannot
+ * break existing codes.
+ */
+#if RBIMPL_HAS_ATTR_CONSTEXPR_CXX14
+# /* C++ can write constexpr as enum values. */
+
+#elif ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
+# undef INT2FIX
+# define INT2FIX(i) (RBIMPL_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG)
+
+#else
+# undef INT2FIX
+# define INT2FIX(i) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(i), \
+ RBIMPL_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG, \
+ RB_INT2FIX(i))
+#endif
+/** @endcond */
+
+#endif /* RBIMPL_ARITHMETIC_LONG_H */
diff --git a/include/ruby/internal/arithmetic/long_long.h b/include/ruby/internal/arithmetic/long_long.h
new file mode 100644
index 0000000000..96ffb37d57
--- /dev/null
+++ b/include/ruby/internal/arithmetic/long_long.h
@@ -0,0 +1,53 @@
+#ifndef RBIMPL_ARITHMETIC_LONG_LONG_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_LONG_LONG_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `long long` and Ruby's.
+ */
+#include "ruby/internal/value.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/backward/2/long_long.h"
+
+#define RB_LL2NUM rb_ll2inum
+#define RB_ULL2NUM rb_ull2inum
+#define LL2NUM RB_LL2NUM
+#define ULL2NUM RB_ULL2NUM
+#define RB_NUM2LL rb_num2ll_inline
+#define RB_NUM2ULL rb_num2ull
+#define NUM2LL RB_NUM2LL
+#define NUM2ULL RB_NUM2ULL
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_ll2inum(LONG_LONG);
+VALUE rb_ull2inum(unsigned LONG_LONG);
+LONG_LONG rb_num2ll(VALUE);
+unsigned LONG_LONG rb_num2ull(VALUE);
+RBIMPL_SYMBOL_EXPORT_END()
+
+static inline LONG_LONG
+rb_num2ll_inline(VALUE x)
+{
+ if (RB_FIXNUM_P(x))
+ return RB_FIX2LONG(x);
+ else
+ return rb_num2ll(x);
+}
+
+#endif /* RBIMPL_ARITHMETIC_LONG_LONG_H */
diff --git a/include/ruby/internal/arithmetic/mode_t.h b/include/ruby/internal/arithmetic/mode_t.h
new file mode 100644
index 0000000000..ee47eb8221
--- /dev/null
+++ b/include/ruby/internal/arithmetic/mode_t.h
@@ -0,0 +1,34 @@
+#ifndef RBIMPL_ARITHMETIC_MODE_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_MODE_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `mode_t` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/int.h"
+
+#ifndef NUM2MODET
+# define NUM2MODET RB_NUM2INT
+#endif
+
+#ifndef MODET2NUM
+# define MODET2NUM RB_INT2NUM
+#endif
+
+#endif /* RBIMPL_ARITHMETIC_MODE_T_H */
diff --git a/include/ruby/internal/arithmetic/off_t.h b/include/ruby/internal/arithmetic/off_t.h
new file mode 100644
index 0000000000..84ec807e3d
--- /dev/null
+++ b/include/ruby/internal/arithmetic/off_t.h
@@ -0,0 +1,49 @@
+#ifndef RBIMPL_ARITHMETIC_OFF_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_OFF_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `off_t` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/int.h"
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/arithmetic/long_long.h"
+#include "ruby/backward/2/long_long.h"
+
+#ifdef OFFT2NUM
+# /* take that. */
+#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
+# define OFFT2NUM RB_LL2NUM
+#elif SIZEOF_OFF_T == SIZEOF_LONG
+# define OFFT2NUM RB_LONG2NUM
+#else
+# define OFFT2NUM RB_INT2NUM
+#endif
+
+#ifdef NUM2OFFT
+# /* take that. */
+#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
+# define NUM2OFFT RB_NUM2LL
+#elif SIZEOF_OFF_T == SIZEOF_LONG
+# define NUM2OFFT RB_NUM2LONG
+#else
+# define NUM2OFFT RB_NUM2INT
+#endif
+
+#endif /* RBIMPL_ARITHMETIC_OFF_T_H */
diff --git a/include/ruby/internal/arithmetic/pid_t.h b/include/ruby/internal/arithmetic/pid_t.h
new file mode 100644
index 0000000000..eaca402776
--- /dev/null
+++ b/include/ruby/internal/arithmetic/pid_t.h
@@ -0,0 +1,34 @@
+#ifndef RBIMPL_ARITHMETIC_PID_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_PID_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `pid_t` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/long.h"
+
+#ifndef PIDT2NUM
+# define PIDT2NUM RB_LONG2NUM
+#endif
+
+#ifndef NUM2PIDT
+# define NUM2PIDT RB_NUM2LONG
+#endif
+
+#endif /* RBIMPL_ARITHMETIC_PID_T_H */
diff --git a/include/ruby/internal/arithmetic/short.h b/include/ruby/internal/arithmetic/short.h
new file mode 100644
index 0000000000..ef213a8d3e
--- /dev/null
+++ b/include/ruby/internal/arithmetic/short.h
@@ -0,0 +1,54 @@
+#ifndef RBIMPL_ARITHMETIC_SHORT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_SHORT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `short` and Ruby's.
+ *
+ * Shyouhei wonders: why there is no SHORT2NUM, given there are both
+ * #USHORT2NUM and #CHR2FIX?
+ */
+#include "ruby/internal/value.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h"
+
+#define RB_NUM2SHORT rb_num2short_inline
+#define RB_NUM2USHORT rb_num2ushort
+#define NUM2SHORT RB_NUM2SHORT
+#define NUM2USHORT RB_NUM2USHORT
+#define USHORT2NUM RB_INT2FIX
+#define RB_FIX2SHORT rb_fix2short
+#define FIX2SHORT RB_FIX2SHORT
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+short rb_num2short(VALUE);
+unsigned short rb_num2ushort(VALUE);
+short rb_fix2short(VALUE);
+unsigned short rb_fix2ushort(VALUE);
+RBIMPL_SYMBOL_EXPORT_END()
+
+static inline short
+rb_num2short_inline(VALUE x)
+{
+ if (RB_FIXNUM_P(x))
+ return rb_fix2short(x);
+ else
+ return rb_num2short(x);
+}
+
+#endif /* RBIMPL_ARITHMETIC_SOHRT_H */
diff --git a/include/ruby/internal/arithmetic/size_t.h b/include/ruby/internal/arithmetic/size_t.h
new file mode 100644
index 0000000000..0458f1f5f3
--- /dev/null
+++ b/include/ruby/internal/arithmetic/size_t.h
@@ -0,0 +1,56 @@
+#ifndef RBIMPL_ARITHMETIC_SIZE_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_SIZE_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `size_t` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/int.h"
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/arithmetic/long_long.h"
+#include "ruby/backward/2/long_long.h"
+
+#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define RB_SIZE2NUM RB_ULL2NUM
+# define RB_SSIZE2NUM RB_LL2NUM
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define RB_SIZE2NUM RB_ULONG2NUM
+# define RB_SSIZE2NUM RB_LONG2NUM
+#else
+# define RB_SIZE2NUM RB_UINT2NUM
+# define RB_SSIZE2NUM RB_INT2NUM
+#endif
+
+#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define RB_NUM2SIZE RB_NUM2ULL
+# define RB_NUM2SSIZE RB_NUM2LL
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define RB_NUM2SIZE RB_NUM2ULONG
+# define RB_NUM2SSIZE RB_NUM2LONG
+#else
+# define RB_NUM2SIZE RB_NUM2UINT
+# define RB_NUM2SSIZE RB_NUM2INT
+#endif
+
+#define NUM2SIZET RB_NUM2SIZE
+#define SIZET2NUM RB_SIZE2NUM
+#define NUM2SSIZET RB_NUM2SSIZE
+#define SSIZET2NUM RB_SSIZE2NUM
+
+#endif /* RBIMPL_ARITHMETIC_SIZE_T_H */
diff --git a/include/ruby/internal/arithmetic/st_data_t.h b/include/ruby/internal/arithmetic/st_data_t.h
new file mode 100644
index 0000000000..93a5ccb7a1
--- /dev/null
+++ b/include/ruby/internal/arithmetic/st_data_t.h
@@ -0,0 +1,59 @@
+#ifndef RBIMPL_ARITHMERIC_ST_DATA_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMERIC_ST_DATA_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `st_data_t` and Ruby's.
+ */
+#include "ruby/internal/arithmetic/fixnum.h"
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+#include "ruby/st.h"
+
+#define ST2FIX RB_ST2FIX
+/** @cond INTERNAL_MACRO */
+#define RB_ST2FIX RB_ST2FIX
+/** @endcond */
+
+RBIMPL_ATTR_CONST_UNLESS_DEBUG()
+RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
+RBIMPL_ATTR_ARTIFICIAL()
+/* See also [ruby-core:84395] [Bug #14218] [ruby-core:82687] [Bug #13877] */
+static inline VALUE
+RB_ST2FIX(st_data_t i)
+{
+ SIGNED_VALUE x = i;
+
+ if (x >= 0) {
+ x &= RUBY_FIXNUM_MAX;
+ }
+ else {
+ x |= RUBY_FIXNUM_MIN;
+ }
+
+ RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(x));
+ unsigned long y = RBIMPL_CAST((unsigned long)x);
+ return RB_LONG2FIX(y);
+}
+
+#endif /* RBIMPL_ARITHMERIC_ST_DATA_T_H */
diff --git a/include/ruby/internal/arithmetic/uid_t.h b/include/ruby/internal/arithmetic/uid_t.h
new file mode 100644
index 0000000000..bdcf42f049
--- /dev/null
+++ b/include/ruby/internal/arithmetic/uid_t.h
@@ -0,0 +1,34 @@
+#ifndef RBIMPL_ARITHMETIC_UID_T_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ARITHMETIC_UID_T_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `uid_t` and Ruby's.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/long.h"
+
+#ifndef UIDT2NUM
+# define UIDT2NUM RB_LONG2NUM
+#endif
+
+#ifndef NUM2UIDT
+# define NUM2UIDT RB_NUM2LONG
+#endif
+
+#endif /* RBIMPL_ARITHMETIC_UID_T_H */
diff --git a/include/ruby/internal/assume.h b/include/ruby/internal/assume.h
new file mode 100644
index 0000000000..e95b2fb12a
--- /dev/null
+++ b/include/ruby/internal/assume.h
@@ -0,0 +1,90 @@
+#ifndef RBIMPL_ASSUME_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ASSUME_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ASSUME / #RBIMPL_UNREACHABLE.
+ *
+ * These macros must be defined at once because:
+ *
+ * - #RBIMPL_ASSUME could fallback to #RBIMPL_UNREACHABLE.
+ * - #RBIMPL_UNREACHABLE could fallback to #RBIMPL_ASSUME.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/builtin.h"
+#include "ruby/internal/warning_push.h"
+
+/** @cond INTERNAL_MACRO */
+#if RBIMPL_COMPILER_SINCE(MSVC, 13, 10, 0)
+# define RBIMPL_HAVE___ASSUME
+
+#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
+# define RBIMPL_HAVE___ASSUME
+#endif
+/** @endcond */
+
+/** Wraps (or simulates) `__builtin_unreachable`. */
+#if RBIMPL_HAS_BUILTIN(__builtin_unreachable)
+# define RBIMPL_UNREACHABLE_RETURN(_) __builtin_unreachable()
+
+#elif defined(RBIMPL_HAVE___ASSUME)
+# define RBIMPL_UNREACHABLE_RETURN(_) return (__assume(0), (_))
+
+#else
+# define RBIMPL_UNREACHABLE_RETURN(_) return (_)
+#endif
+
+/** Wraps (or simulates) `__builtin_unreachable`. */
+#if RBIMPL_HAS_BUILTIN(__builtin_unreachable)
+# define RBIMPL_UNREACHABLE __builtin_unreachable
+
+#elif defined(RBIMPL_HAVE___ASSUME)
+# define RBIMPL_UNREACHABLE() __assume(0)
+#endif
+
+/** Wraps (or simulates) `__assume`. */
+#if RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
+# /* icc warnings are false positives. Ignore them. */
+# /* "warning #2261: __assume expression with side effects discarded" */
+# define RBIMPL_ASSUME(expr) \
+ RBIMPL_WARNING_PUSH() \
+ RBIMPL_WARNING_IGNORED(2261) \
+ __assume(expr) \
+ RBIMPL_WARNING_POP()
+
+#elif defined(RBIMPL_HAVE___ASSUME)
+# define RBIMPL_ASSUME __assume
+
+#elif RBIMPL_HAS_BUILTIN(__builtin_assume)
+# define RBIMPL_ASSUME __builtin_assume
+
+#elif ! defined(RBIMPL_UNREACHABLE)
+# define RBIMPL_ASSUME(_) RBIMPL_CAST((void)(_))
+
+#else
+# define RBIMPL_ASSUME(_) \
+ (RB_LIKELY(!!(_)) ? RBIMPL_CAST((void)0) : RBIMPL_UNREACHABLE())
+#endif
+
+#if ! defined(RBIMPL_UNREACHABLE)
+# define RBIMPL_UNREACHABLE() RBIMPL_ASSUME(0)
+#endif
+
+#endif /* RBIMPL_ASSUME_H */
diff --git a/include/ruby/internal/attr/alloc_size.h b/include/ruby/internal/attr/alloc_size.h
new file mode 100644
index 0000000000..ea96feec99
--- /dev/null
+++ b/include/ruby/internal/attr/alloc_size.h
@@ -0,0 +1,32 @@
+#ifndef RBIMPL_ATTR_ALLOC_SIZE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_ALLOC_SIZE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_ALLOC_SIZE.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((alloc_size))` */
+#if RBIMPL_HAS_ATTRIBUTE(alloc_size)
+# define RBIMPL_ATTR_ALLOC_SIZE(tuple) __attribute__((__alloc_size__ tuple))
+#else
+# define RBIMPL_ATTR_ALLOC_SIZE(tuple) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_ALLOC_SIZE_H */
diff --git a/include/ruby/internal/attr/artificial.h b/include/ruby/internal/attr/artificial.h
new file mode 100644
index 0000000000..fa9a3814cc
--- /dev/null
+++ b/include/ruby/internal/attr/artificial.h
@@ -0,0 +1,46 @@
+#ifndef RBIMPL_ATTR_ARTIFICIAL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_ARTIFICIAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_ARTIFICIAL.
+ *
+ * ### Q&A ###
+ *
+ * - Q: What is this attribute? I don't get what GCC manual is talking about.
+ *
+ * - A: In short it is an attribute to manipulate GDB backtraces. The
+ * attribute makes the best sense when it comes with
+ * __attribute__((always_inline)). When a function annotated with this
+ * attribute gets inlined, and when you somehow look at a backtrace which
+ * includes such inlined call site, then the backtrace shows the caller
+ * and not the callee. This is handy for instance when an identical
+ * function is inlined more than once in a single big function. On such
+ * case it gets vital to know where the inlining happened in the callee.
+ * See also https://stackoverflow.com/a/21936099
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((artificial))` */
+#if RBIMPL_HAS_ATTRIBUTE(artificial)
+# define RBIMPL_ATTR_ARTIFICIAL() __attribute__((__artificial__))
+#else
+# define RBIMPL_ATTR_ARTIFICIAL() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_ARTIFICIAL_H */
diff --git a/include/ruby/internal/attr/cold.h b/include/ruby/internal/attr/cold.h
new file mode 100644
index 0000000000..fcee507456
--- /dev/null
+++ b/include/ruby/internal/attr/cold.h
@@ -0,0 +1,37 @@
+#ifndef RBIMPL_ATTR_COLD_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_COLD_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_COLD.
+ */
+#include "ruby/internal/compiler_is.h"
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((cold))` */
+#if RBIMPL_COMPILER_IS(SunPro)
+# /* Recent SunPro has __has_attribute, and is borken. */
+# /* It reports it has attribute cold, reality isn't (warnings issued). */
+# define RBIMPL_ATTR_COLD() /* void */
+#elif RBIMPL_HAS_ATTRIBUTE(cold)
+# define RBIMPL_ATTR_COLD() __attribute__((__cold__))
+#else
+# define RBIMPL_ATTR_COLD() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_COLD_H */
diff --git a/include/ruby/internal/attr/const.h b/include/ruby/internal/attr/const.h
new file mode 100644
index 0000000000..d5b8da0c2d
--- /dev/null
+++ b/include/ruby/internal/attr/const.h
@@ -0,0 +1,46 @@
+#ifndef RBIMPL_ATTR_CONST_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_CONST_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_CONST.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/declspec_attribute.h"
+
+/** Wraps (or simulates) `__attribute__((const))` */
+#if RBIMPL_HAS_ATTRIBUTE(const)
+# define RBIMPL_ATTR_CONST() __attribute__((__const__))
+#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noalias)
+# /* If a function can be a const, that is also a noalias. */
+# define RBIMPL_ATTR_CONST() __declspec(noalias)
+#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
+# define RBIMPL_ATTR_CONST() _Pragma("no_side_effect")
+#else
+# define RBIMPL_ATTR_CONST() /* void */
+#endif
+
+/** Enables #RBIMPL_ATTR_CONST iff. ! #RUBY_DEBUG. */
+#if !RUBY_DEBUG
+# define RBIMPL_ATTR_CONST_UNLESS_DEBUG() RBIMPL_ATTR_CONST()
+#else
+# define RBIMPL_ATTR_CONST_UNLESS_DEBUG() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_CONST_H */
diff --git a/include/ruby/internal/attr/constexpr.h b/include/ruby/internal/attr/constexpr.h
new file mode 100644
index 0000000000..96b010ce6f
--- /dev/null
+++ b/include/ruby/internal/attr/constexpr.h
@@ -0,0 +1,85 @@
+#ifndef RBIMPL_ATTR_CONSTEXPR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_CONSTEXPR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief #RBIMPL_ATTR_CONSTEXPR.
+ */
+#include "ruby/internal/has/feature.h"
+#include "ruby/internal/compiler_is.h"
+#include "ruby/internal/token_paste.h"
+
+/** @cond INTERNAL_MACRO */
+#if ! defined(__cplusplus)
+# /* Makes no sense. */
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 0
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
+
+#elif defined(__cpp_constexpr)
+# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cpp_constexpr >= 200704L)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cpp_constexpr >= 201304L)
+
+#elif RBIMPL_COMPILER_SINCE(MSVC, 19, 0, 0)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 00)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 00)
+
+#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 13, 0)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cplusplus >= 201103L)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cplusplus >= 201402L)
+
+#elif RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cplusplus >= 201103L)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cplusplus >= 201402L)
+
+#elif RBIMPL_HAS_FEATURE(cxx_relaxed_constexpr)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 1
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 1
+
+#elif RBIMPL_HAS_FEATURE(cxx_constexpr)
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 1
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
+
+#else
+# /* :FIXME: icpc must have constexpr but don't know how to detect. */
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 0
+# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
+#endif
+/** @endcond */
+
+/** Wraps (or simulates) C++11 `constexpr`. */
+#if RBIMPL_HAS_ATTR_CONSTEXPR_CXX14
+# define RBIMPL_ATTR_CONSTEXPR(_) constexpr
+
+#elif RBIMPL_HAS_ATTR_CONSTEXPR_CXX11
+# define RBIMPL_ATTR_CONSTEXPR(_) RBIMPL_TOKEN_PASTE(RBIMPL_ATTR_CONSTEXPR_, _)
+# define RBIMPL_ATTR_CONSTEXPR_CXX11 constexpr
+# define RBIMPL_ATTR_CONSTEXPR_CXX14 /* void */
+
+#else
+# define RBIMPL_ATTR_CONSTEXPR(_) /* void */
+#endif
+
+/** Enables #RBIMPL_ATTR_CONSTEXPR iff. ! #RUBY_DEBUG. */
+#if !RUBY_DEBUG
+# define RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(_) RBIMPL_ATTR_CONSTEXPR(_)
+#else
+# define RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(_) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_CONSTEXPR_H */
diff --git a/include/ruby/internal/attr/deprecated.h b/include/ruby/internal/attr/deprecated.h
new file mode 100644
index 0000000000..38a7deeaaa
--- /dev/null
+++ b/include/ruby/internal/attr/deprecated.h
@@ -0,0 +1,63 @@
+#ifndef RBIMPL_ATTR_DEPRECATED_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_DEPRECATED_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_DEPRECATED.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/c_attribute.h"
+#include "ruby/internal/has/cpp_attribute.h"
+#include "ruby/internal/has/declspec_attribute.h"
+#include "ruby/internal/has/extension.h"
+
+/** Wraps (or simulates) `[[deprecated]]` */
+#if RBIMPL_HAS_EXTENSION(attribute_deprecated_with_message)
+# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))
+
+#elif defined(__cplusplus) && RBIMPL_COMPILER_SINCE(GCC, 10, 1, 0) /* && RBIMPL_COMPILER_BEFORE(GCC, 10, X, Y) */
+# /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95302 */
+# define RBIMPL_ATTR_DEPRECATED(msg) /* disable until they fix this bug */
+
+#elif RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
+# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))
+
+#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
+# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))
+
+#elif RBIMPL_HAS_ATTRIBUTE(deprecated) /* but not with message. */
+# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__))
+
+#elif RBIMPL_COMPILER_SINCE(MSVC, 14, 0, 0)
+# define RBIMPL_ATTR_DEPRECATED(msg) __declspec(deprecated msg)
+
+#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(deprecated)
+# define RBIMPL_ATTR_DEPRECATED(msg) __declspec(deprecated)
+
+#elif RBIMPL_HAS_CPP_ATTRIBUTE(deprecated)
+# define RBIMPL_ATTR_DEPRECATED(msg) [[deprecated msg]]
+
+#elif RBIMPL_HAS_C_ATTRIBUTE(deprecated)
+# define RBIMPL_ATTR_DEPRECATED(msg) [[deprecated msg]]
+
+#else
+# define RBIMPL_ATTR_DEPRECATED(msg) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_DEPRECATED_H */
diff --git a/include/ruby/internal/attr/diagnose_if.h b/include/ruby/internal/attr/diagnose_if.h
new file mode 100644
index 0000000000..6a79e904b7
--- /dev/null
+++ b/include/ruby/internal/attr/diagnose_if.h
@@ -0,0 +1,42 @@
+#ifndef RBIMPL_ATTR_DIAGNOSE_IF_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_DIAGNOSE_IF_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_DIAGNOSE_IF.
+ */
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/warning_push.h"
+
+/** Wraps (or simulates) `__attribute__((diagnose_if))` */
+#if RBIMPL_COMPILER_BEFORE(Clang, 5, 0, 0)
+# /* https://bugs.llvm.org/show_bug.cgi?id=34319 */
+# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) /* void */
+
+#elif RBIMPL_HAS_ATTRIBUTE(diagnose_if)
+# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) \
+ RBIMPL_WARNING_PUSH() \
+ RBIMPL_WARNING_IGNORED(-Wgcc-compat) \
+ __attribute__((__diagnose_if__(_, __, ___))) \
+ RBIMPL_WARNING_POP()
+
+#else
+# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_DIAGNOSE_IF_H */
diff --git a/include/ruby/internal/attr/enum_extensibility.h b/include/ruby/internal/attr/enum_extensibility.h
new file mode 100644
index 0000000000..6faa58185a
--- /dev/null
+++ b/include/ruby/internal/attr/enum_extensibility.h
@@ -0,0 +1,32 @@
+#ifndef RBIMPL_ATTR_ENUM_EXTENSIBILITY_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_ENUM_EXTENSIBILITY_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief #RBIMPL_ATTR_ENUM_EXTENSIBILITY.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((enum_extensibility))` */
+#if RBIMPL_HAS_ATTRIBUTE(enum_extensibility)
+# define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_) __attribute__((__enum_extensibility__(_)))
+#else
+# define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_ENUM_EXTENSIBILITY_H */
diff --git a/include/ruby/internal/attr/error.h b/include/ruby/internal/attr/error.h
new file mode 100644
index 0000000000..da19b73c2b
--- /dev/null
+++ b/include/ruby/internal/attr/error.h
@@ -0,0 +1,32 @@
+#ifndef RBIMPL_ATTR_ERROR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_ERROR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_ERROR.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((error))` */
+#if RBIMPL_HAS_ATTRIBUTE(error)
+# define RBIMPL_ATTR_ERROR(msg) __attribute__((__error__ msg))
+#else
+# define RBIMPL_ATTR_ERROR(msg) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_ERROR_H */
diff --git a/include/ruby/internal/attr/flag_enum.h b/include/ruby/internal/attr/flag_enum.h
new file mode 100644
index 0000000000..148384d842
--- /dev/null
+++ b/include/ruby/internal/attr/flag_enum.h
@@ -0,0 +1,33 @@
+#ifndef RBIMPL_ATTR_FLAG_ENUM_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_FLAG_ENUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_FLAG_ENUM.
+ * @see https://clang.llvm.org/docs/AttributeReference.html#flag_enum
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((flag_enum)` */
+#if RBIMPL_HAS_ATTRIBUTE(flag_enum)
+# define RBIMPL_ATTR_FLAG_ENUM() __attribute__((__flag_enum__))
+#else
+# define RBIMPL_ATTR_FLAG_ENUM() /* void */
+#endif
+
+#endif /* RBIMPLATTR_FLAG_ENUM_H */
diff --git a/include/ruby/internal/attr/forceinline.h b/include/ruby/internal/attr/forceinline.h
new file mode 100644
index 0000000000..6b31f1016f
--- /dev/null
+++ b/include/ruby/internal/attr/forceinline.h
@@ -0,0 +1,40 @@
+#ifndef RBIMPL_ATTR_FORCEINLINE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_FORCEINLINE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_FORCEINLINE.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/attribute.h"
+
+/**
+ * Wraps (or simulates) `__forceinline`. MSVC complains on declarations like
+ * `static inline __forceinline void foo()`. It seems MSVC's `inline` and
+ * `__forceinline` are mutually exclusive. We have to mimic that behaviour for
+ * non-MSVC compilers.
+ */
+#if RBIMPL_COMPILER_SINCE(MSVC, 12, 0, 0)
+# define RBIMPL_ATTR_FORCEINLINE() __forceinline
+#elif RBIMPL_HAS_ATTRIBUTE(always_inline)
+# define RBIMPL_ATTR_FORCEINLINE() __attribute__((__always_inline__)) inline
+#else
+# define RBIMPL_ATTR_FORCEINLINE() inline
+#endif
+
+#endif /* RBIMPL_ATTR_FORCEINLINE_H */
diff --git a/include/ruby/internal/attr/format.h b/include/ruby/internal/attr/format.h
new file mode 100644
index 0000000000..fcbf7b6cfe
--- /dev/null
+++ b/include/ruby/internal/attr/format.h
@@ -0,0 +1,38 @@
+#ifndef RBIMPL_ATTR_FORMAT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_FORMAT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_FORMAT.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((format))` */
+#if RBIMPL_HAS_ATTRIBUTE(format)
+# define RBIMPL_ATTR_FORMAT(x, y, z) __attribute__((__format__(x, y, z)))
+#else
+# define RBIMPL_ATTR_FORMAT(x, y, z) /* void */
+#endif
+
+#if defined(__MINGW_PRINTF_FORMAT)
+# define RBIMPL_PRINTF_FORMAT __MINGW_PRINTF_FORMAT
+#else
+# define RBIMPL_PRINTF_FORMAT __printf__
+#endif
+
+#endif /* RBIMPL_ATTR_FORMAT_H */
diff --git a/include/ruby/internal/attr/maybe_unused.h b/include/ruby/internal/attr/maybe_unused.h
new file mode 100644
index 0000000000..f46d1bc670
--- /dev/null
+++ b/include/ruby/internal/attr/maybe_unused.h
@@ -0,0 +1,38 @@
+#ifndef RBIMPL_ATTR_MAYBE_UNUSED_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_MAYBE_UNUSED_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_MAYBE_UNUSED.
+ */
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/c_attribute.h"
+#include "ruby/internal/has/cpp_attribute.h"
+
+/** Wraps (or simulates) `[[maybe_unused]]` */
+#if RBIMPL_HAS_CPP_ATTRIBUTE(maybe_unused)
+# define RBIMPL_ATTR_MAYBE_UNUSED() [[maybe_unused]]
+#elif RBIMPL_HAS_C_ATTRIBUTE(maybe_unused)
+# define RBIMPL_ATTR_MAYBE_UNUSED() [[maybe_unused]]
+#elif RBIMPL_HAS_ATTRIBUTE(unused)
+# define RBIMPL_ATTR_MAYBE_UNUSED() __attribute__((__unused__))
+#else
+# define RBIMPL_ATTR_MAYBE_UNUSED() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_MAYBE_UNUSED */
diff --git a/include/ruby/internal/attr/noalias.h b/include/ruby/internal/attr/noalias.h
new file mode 100644
index 0000000000..63324b7184
--- /dev/null
+++ b/include/ruby/internal/attr/noalias.h
@@ -0,0 +1,58 @@
+#ifndef RBIMPL_ATTR_NOALIAS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NOALIAS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_NOALIAS.
+ *
+ * ### Q&A ###
+ *
+ * - Q: There are seemingly similar attributes named #RBIMPL_ATTR_CONST,
+ * #RBIMPL_ATTR_PURE, and #RBIMPL_ATTR_NOALIAS. What are the difference?
+ *
+ * - A: Allowed operations are different.
+ *
+ * - #RBIMPL_ATTR_CONST ... Functions attributed by this are not allowed to
+ * read/write _any_ pointers at all (there are exceptional situations
+ * when reading a pointer is possible but forget that; they are too
+ * exceptional to be useful). Just remember that everything pointer-
+ * related are NG.
+ *
+ * - #RBIMPL_ATTR_PURE ... Functions attributed by this can read any
+ * nonvolatile pointers, but no writes are allowed at all. The ability
+ * to read _any_ nonvolatile pointers makes it possible to mark ::VALUE-
+ * taking functions as being pure, as long as they are read-only.
+ *
+ * - #RBIMPL_ATTR_NOALIAS ... Can both read/write, but only through
+ * pointers passed to the function as parameters. This is a typical
+ * situation when you create a C++ non-static member function which only
+ * concerns `this`. No global variables are allowed to read/write. So
+ * this is not a super-set of being pure. If you want to read something,
+ * that has to be passed to the function as a pointer. ::VALUE -taking
+ * functions thus cannot be attributed as such.
+ */
+#include "ruby/internal/has/declspec_attribute.h"
+
+/** Wraps (or simulates) `__declspec((noalias))` */
+#if RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noalias)
+# define RBIMPL_ATTR_NOALIAS() __declspec(noalias)
+#else
+# define RBIMPL_ATTR_NOALIAS() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NOALIAS_H */
diff --git a/include/ruby/internal/attr/nodiscard.h b/include/ruby/internal/attr/nodiscard.h
new file mode 100644
index 0000000000..5fd71b1c23
--- /dev/null
+++ b/include/ruby/internal/attr/nodiscard.h
@@ -0,0 +1,45 @@
+#ifndef RBIMPL_ATTR_NODISCARD_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NODISCARD_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_NODISCARD.
+ */
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/c_attribute.h"
+#include "ruby/internal/has/cpp_attribute.h"
+
+/**
+ * Wraps (or simulates) `[[nodiscard]]`. In C++ (at least since C++20) a
+ * nodiscard attribute can have a message why the result shall not be ignoed.
+ * However GCC attribute and SAL annotation cannot take them.
+ */
+#if RBIMPL_HAS_CPP_ATTRIBUTE(nodiscard)
+# define RBIMPL_ATTR_NODISCARD() [[nodiscard]]
+#elif RBIMPL_HAS_C_ATTRIBUTE(nodiscard)
+# define RBIMPL_ATTR_NODISCARD() [[nodiscard]]
+#elif RBIMPL_HAS_ATTRIBUTE(warn_unused_result)
+# define RBIMPL_ATTR_NODISCARD() __attribute__((__warn_unused_result__))
+#elif defined(_Check_return_)
+# /* Take SAL definition. */
+# define RBIMPL_ATTR_NODISCARD() _Check_return_
+#else
+# define RBIMPL_ATTR_NODISCARD() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NODISCARD_H */
diff --git a/include/ruby/internal/attr/noexcept.h b/include/ruby/internal/attr/noexcept.h
new file mode 100644
index 0000000000..968a7742b9
--- /dev/null
+++ b/include/ruby/internal/attr/noexcept.h
@@ -0,0 +1,91 @@
+#ifndef RBIMPL_ATTR_NOEXCEPT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NOEXCEPT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_NOEXCEPT.
+ *
+ * This isn't actually an attribute in C++ but who cares...
+ *
+ * Mainly due to aesthetic reasons, this one is rarely used in the project.
+ * But can be handy on occasions, especially when a function's noexcept-ness
+ * depends on its calling functions.
+ *
+ * ### Q&A ###
+ *
+ * - Q: Can a function that raises Ruby exceptions be attributed `noexcept`?
+ *
+ * - A: Yes. `noexcept` is about C++ exceptions, not Ruby's. They don't
+ * interface each other. You can safely attribute a function that raises
+ * Ruby exceptions as `noexcept`.
+ *
+ * - Q: How, then, can I assert that a function I wrote doesn't raise any Ruby
+ * exceptions?
+ *
+ * - A: `__attribute__((__leaf__))` is for that purpose. A function attributed
+ * as leaf can still throw C++ exceptions, but not Ruby's. Note however,
+ * that it's extremely difficult -- if not impossible -- to assert that a
+ * function doesn't raise any Ruby exceptions at all. Use of that
+ * attribute is not recommended; mere mortals can't properly use that by
+ * hand.
+ *
+ * - Q: Does it make sense to attribute an inline function `noexcept`?
+ *
+ * - A: I thought so before. But no, I don't think they are useful any longer.
+ *
+ * - When an inline function attributed `noexcept` actually doesn't throw
+ * any exceptions at all: these days I don't see any difference in
+ * generated assembly by adding/removing this attribute. C++ compilers
+ * get smarter and smarter. Today they can infer if it actually throws
+ * or not without any annotations by humans (correct me if I'm wrong).
+ *
+ * - When an inline function attributed `noexcepr` actually _does_ throw an
+ * exception: they have to call `std::terminate` then (C++ standard
+ * mandates so). This means exception handling routines are actually
+ * enforced, not omitted. This doesn't impact runtime performance (The
+ * Itanium C++ ABI has zero-cost exception handling), but does impact on
+ * generated binary size. This is bad.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/feature.h"
+
+/** Wraps (or simulates) C++11 `noexcept` */
+#if ! defined(__cplusplus)
+# /* Doesn't make sense. */
+# define RBIMPL_ATTR_NOEXCEPT(_) /* void */
+
+#elif RBIMPL_HAS_FEATURE(cxx_noexcept)
+# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
+
+#elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
+# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
+
+#elif defined(__INTEL_CXX11_MODE__)
+# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
+
+#elif RBIMPL_COMPILER_SINCE(MSVC, 19, 0, 0)
+# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
+
+#elif __cplusplus >= 201103L
+# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
+
+#else
+# define RBIMPL_ATTR_NOEXCEPT(_) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NOEXCEPT_H */
diff --git a/include/ruby/internal/attr/noinline.h b/include/ruby/internal/attr/noinline.h
new file mode 100644
index 0000000000..619f99a171
--- /dev/null
+++ b/include/ruby/internal/attr/noinline.h
@@ -0,0 +1,35 @@
+#ifndef RBIMPL_ATTR_NOINLINE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NOINLINE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_NOINLINE.
+ */
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/declspec_attribute.h"
+
+/** Wraps (or simulates) `__declspec(noinline)` */
+#if RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noinline)
+# define RBIMPL_ATTR_NOINLINE() __declspec(noinline)
+#elif RBIMPL_HAS_ATTRIBUTE(noinline)
+# define RBIMPL_ATTR_NOINLINE() __attribute__((__noinline__))
+#else
+# define RBIMPL_ATTR_NOINLINE() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NOINLINE_H */
diff --git a/include/ruby/internal/attr/nonnull.h b/include/ruby/internal/attr/nonnull.h
new file mode 100644
index 0000000000..cfced0bf74
--- /dev/null
+++ b/include/ruby/internal/attr/nonnull.h
@@ -0,0 +1,32 @@
+#ifndef RBIMPL_ATTR_NONNULL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NONNULL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_NONNULL.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((nonnull))` */
+#if RBIMPL_HAS_ATTRIBUTE(nonnull)
+# define RBIMPL_ATTR_NONNULL(list) __attribute__((__nonnull__ list))
+#else
+# define RBIMPL_ATTR_NONNULL(list) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NONNULL_H */
diff --git a/include/ruby/internal/attr/noreturn.h b/include/ruby/internal/attr/noreturn.h
new file mode 100644
index 0000000000..f741167c12
--- /dev/null
+++ b/include/ruby/internal/attr/noreturn.h
@@ -0,0 +1,48 @@
+#ifndef RBIMPL_ATTR_NORETURN_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NORETURN_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_NORETURN.
+ */
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/cpp_attribute.h"
+#include "ruby/internal/has/declspec_attribute.h"
+
+/** Wraps (or simulates) `[[noreturn]]` */
+#if RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noreturn)
+# define RBIMPL_ATTR_NORETURN() __declspec(noreturn)
+
+#elif RBIMPL_HAS_ATTRIBUTE(noreturn)
+# define RBIMPL_ATTR_NORETURN() __attribute__((__noreturn__))
+
+#elif RBIMPL_HAS_CPP_ATTRIBUTE(noreturn)
+# define RBIMPL_ATTR_NORETURN() [[noreturn]]
+
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112)
+# define RBIMPL_ATTR_NORETURN() _Noreturn
+
+#elif defined(_Noreturn)
+# /* glibc <sys/cdefs.h> has this macro. */
+# define RBIMPL_ATTR_NORETURN() _Noreturn
+
+#else
+# define RBIMPL_ATTR_NORETURN() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NORETURN_H */
diff --git a/include/ruby/internal/attr/pure.h b/include/ruby/internal/attr/pure.h
new file mode 100644
index 0000000000..1a10540ef3
--- /dev/null
+++ b/include/ruby/internal/attr/pure.h
@@ -0,0 +1,43 @@
+#ifndef RBIMPL_ATTR_PURE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_PURE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_PURE.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/assert.h"
+
+/** Wraps (or simulates) `__attribute__((pure))` */
+#if RBIMPL_HAS_ATTRIBUTE(pure)
+# define RBIMPL_ATTR_PURE() __attribute__((__pure__))
+#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
+# define RBIMPL_ATTR_PURE() _Pragma("does_not_write_global_data")
+#else
+# define RBIMPL_ATTR_PURE() /* void */
+#endif
+
+/** Enables #RBIMPL_ATTR_PURE iff. ! #RUBY_DEBUG. */
+#if !RUBY_DEBUG
+# define RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_PURE()
+#else
+# define RBIMPL_ATTR_PURE_UNLESS_DEBUG() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_PURE_H */
diff --git a/include/ruby/internal/attr/restrict.h b/include/ruby/internal/attr/restrict.h
new file mode 100644
index 0000000000..3f4b7db165
--- /dev/null
+++ b/include/ruby/internal/attr/restrict.h
@@ -0,0 +1,45 @@
+#ifndef RBIMPL_ATTR_RESTRICT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_RESTRICT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_RESTRICT.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/token_paste.h"
+
+/* :FIXME: config.h includes conflicting `#define restrict`. MSVC can be
+ * detected using `RBIMPL_COMPILER_SINCE()`, but Clang & family cannot use
+ * `__has_declspec_attribute()` which involves macro substitution. */
+
+/** Wraps (or simulates) `__declspec(restrict)` */
+#if RBIMPL_COMPILER_SINCE(MSVC, 14, 0, 0)
+# define RBIMPL_ATTR_RESTRICT() __declspec(RBIMPL_TOKEN_PASTE(re, strict))
+
+#elif RBIMPL_HAS_ATTRIBUTE(malloc)
+# define RBIMPL_ATTR_RESTRICT() __attribute__((__malloc__))
+
+#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
+# define RBIMPL_ATTR_RESTRICT() _Pragma("returns_new_memory")
+
+#else
+# define RBIMPL_ATTR_RESTRICT() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_RESTRICT_H */
diff --git a/include/ruby/internal/attr/returns_nonnull.h b/include/ruby/internal/attr/returns_nonnull.h
new file mode 100644
index 0000000000..91c7be15cd
--- /dev/null
+++ b/include/ruby/internal/attr/returns_nonnull.h
@@ -0,0 +1,37 @@
+#ifndef RBIMPL_ATTR_RETURNS_NONNULL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_RETURNS_NONNULL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_RETURNS_NONNULL.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((returns_nonnull))` */
+#if defined(_Ret_nonnull_)
+# /* Take SAL definition. */
+# define RBIMPL_ATTR_RETURNS_NONNULL() _Ret_nonnull_
+
+#elif RBIMPL_HAS_ATTRIBUTE(returns_nonnull)
+# define RBIMPL_ATTR_RETURNS_NONNULL() __attribute__((__returns_nonnull__))
+
+#else
+# define RBIMPL_ATTR_RETURNS_NONNULL() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_RETURNS_NONNULL_H */
diff --git a/include/ruby/internal/attr/warning.h b/include/ruby/internal/attr/warning.h
new file mode 100644
index 0000000000..fb6b214828
--- /dev/null
+++ b/include/ruby/internal/attr/warning.h
@@ -0,0 +1,32 @@
+#ifndef RBIMPL_ATTR_WARNING_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_WARNING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_WARNING.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((warning))` */
+#if RBIMPL_HAS_ATTRIBUTE(warning)
+# define RBIMPL_ATTR_WARNING(msg) __attribute__((__warning__ msg))
+#else
+# define RBIMPL_ATTR_WARNING(msg) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_WARNING_H */
diff --git a/include/ruby/internal/attr/weakref.h b/include/ruby/internal/attr/weakref.h
new file mode 100644
index 0000000000..59dba678fa
--- /dev/null
+++ b/include/ruby/internal/attr/weakref.h
@@ -0,0 +1,32 @@
+#ifndef RBIMPL_ATTR_WEAKREF_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_WEAKREF_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_WEAKREF.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((weakref))` */
+#if RBIMPL_HAS_ATTRIBUTE(weakref)
+# define RBIMPL_ATTR_WEAKREF(sym) __attribute__((__weakref__(# sym)))
+#else
+# define RBIMPL_ATTR_WEAKREF(sym) /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_WEAKREF_H */
diff --git a/include/ruby/internal/cast.h b/include/ruby/internal/cast.h
new file mode 100644
index 0000000000..065a5d01c2
--- /dev/null
+++ b/include/ruby/internal/cast.h
@@ -0,0 +1,53 @@
+#ifndef RBIMPL_CAST_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_CAST_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines RBIMPL_CAST.
+ * @cond INTERNAL_MACRO
+ *
+ * This casting macro makes sense only inside of other macros that are part of
+ * public headers. They could be used from C++, and C-style casts could issue
+ * warnings. Ruby internals are pure C so they should not bother.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/warning.h"
+#include "ruby/internal/warning_push.h"
+
+#if ! defined(__cplusplus)
+# define RBIMPL_CAST(expr) (expr)
+
+#elif RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
+# /* g++ has -Wold-style-cast since 1997 or so, but its _Pragma is broken. */
+# /* See https://gcc.godbolt.org/z/XWhU6J */
+# define RBIMPL_CAST(expr) (expr)
+# pragma GCC diagnostic ignored "-Wold-style-cast"
+
+#elif RBIMPL_HAS_WARNING("-Wold-style-cast")
+# define RBIMPL_CAST(expr) \
+ RBIMPL_WARNING_PUSH() \
+ RBIMPL_WARNING_IGNORED(-Wold-style-cast) \
+ (expr) \
+ RBIMPL_WARNING_POP()
+
+#else
+# define RBIMPL_CAST(expr) (expr)
+#endif
+/** @endcond */
+
+#endif /* RBIMPL_CAST_H */
diff --git a/include/ruby/internal/compiler_is.h b/include/ruby/internal/compiler_is.h
new file mode 100644
index 0000000000..776d7add4f
--- /dev/null
+++ b/include/ruby/internal/compiler_is.h
@@ -0,0 +1,45 @@
+#ifndef RBIMPL_COMPILER_IS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_IS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_IS.
+ */
+
+/**
+ * @brief Checks if the compiler is of given brand.
+ * @param cc Compiler brand, like `MSVC`.
+ * @retval true It is.
+ * @retval false It isn't.
+ */
+#define RBIMPL_COMPILER_IS(cc) RBIMPL_COMPILER_IS_ ## cc
+
+#include "ruby/internal/compiler_is/apple.h"
+#include "ruby/internal/compiler_is/clang.h"
+#include "ruby/internal/compiler_is/gcc.h"
+#include "ruby/internal/compiler_is/intel.h"
+#include "ruby/internal/compiler_is/msvc.h"
+#include "ruby/internal/compiler_is/sunpro.h"
+/* :TODO: Other possible compilers to support:
+ *
+ * - IBM XL: recent XL are clang-backended so some tweaks like we do for
+ * Apple's might be needed.
+ *
+ * - ARM's armclang: ditto, it can be clang-backended. */
+
+#endif /* RBIMPL_COMPILER_IS_H */
diff --git a/include/ruby/internal/compiler_is/apple.h b/include/ruby/internal/compiler_is/apple.h
new file mode 100644
index 0000000000..5a5f558254
--- /dev/null
+++ b/include/ruby/internal/compiler_is/apple.h
@@ -0,0 +1,41 @@
+#ifndef RBIMPL_COMPILER_IS_APPLE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_IS_APPLE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_IS_Apple.
+ *
+ * Apple ships clang. Problem is, its `__clang_major__` etc. are not the
+ * upstream LLVM version, but XCode's. We have to think Apple's is distinct
+ * from LLVM's, when it comes to compiler detection business in this header
+ * file.
+ */
+#if ! defined(__clang__)
+# define RBIMPL_COMPILER_IS_Apple 0
+
+#elif ! defined(__apple_build_version__)
+# define RBIMPL_COMPILER_IS_Apple 0
+
+#else
+# define RBIMPL_COMPILER_IS_Apple 1
+# define RBIMPL_COMPILER_VERSION_MAJOR __clang_major__
+# define RBIMPL_COMPILER_VERSION_MINOR __clang_minor__
+# define RBIMPL_COMPILER_VERSION_PATCH __clang_patchlevel__
+#endif
+
+#endif /* RBIMPL_COMPILER_IS_APPLE_H */
diff --git a/include/ruby/internal/compiler_is/clang.h b/include/ruby/internal/compiler_is/clang.h
new file mode 100644
index 0000000000..30655f2f25
--- /dev/null
+++ b/include/ruby/internal/compiler_is/clang.h
@@ -0,0 +1,38 @@
+#ifndef RBIMPL_COMPILER_IS_CLANG_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_IS_CLANG_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_IS_Clang.
+ */
+#include "ruby/internal/compiler_is/apple.h"
+
+#if ! defined(__clang__)
+# define RBIMPL_COMPILER_IS_Clang 0
+
+#elif RBIMPL_COMPILER_IS(Apple)
+# define RBIMPL_COMPILER_IS_Clang 0
+
+#else
+# define RBIMPL_COMPILER_IS_Clang 1
+# define RBIMPL_COMPILER_VERSION_MAJOR __clang_major__
+# define RBIMPL_COMPILER_VERSION_MINOR __clang_minor__
+# define RBIMPL_COMPILER_VERSION_PATCH __clang_patchlevel__
+#endif
+
+#endif /* RBIMPL_COMPILER_IS_CLANG_H */
diff --git a/include/ruby/internal/compiler_is/gcc.h b/include/ruby/internal/compiler_is/gcc.h
new file mode 100644
index 0000000000..6eabfb61a2
--- /dev/null
+++ b/include/ruby/internal/compiler_is/gcc.h
@@ -0,0 +1,46 @@
+#ifndef RBIMPL_COMPILER_IS_GCC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_IS_GCC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_IS_GCC.
+ */
+#include "ruby/internal/compiler_is/apple.h"
+#include "ruby/internal/compiler_is/clang.h"
+#include "ruby/internal/compiler_is/intel.h"
+
+#if ! defined(__GNUC__)
+# define RBIMPL_COMPILER_IS_GCC 0
+
+#elif RBIMPL_COMPILER_IS(Apple)
+# define RBIMPL_COMPILER_IS_GCC 0
+
+#elif RBIMPL_COMPILER_IS(Clang)
+# define RBIMPL_COMPILER_IS_GCC 0
+
+#elif RBIMPL_COMPILER_IS(Intel)
+# define RBIMPL_COMPILER_IS_GCC 0
+
+#else
+# define RBIMPL_COMPILER_IS_GCC 1
+# define RBIMPL_COMPILER_VERSION_MAJOR __GNUC__
+# define RBIMPL_COMPILER_VERSION_MINOR __GNUC_MINOR__
+# define RBIMPL_COMPILER_VERSION_PATCH __GNUC_PATCHLEVEL__
+#endif
+
+#endif /* RBIMPL_COMPILER_IS_GCC_H */
diff --git a/include/ruby/internal/compiler_is/intel.h b/include/ruby/internal/compiler_is/intel.h
new file mode 100644
index 0000000000..ada120485e
--- /dev/null
+++ b/include/ruby/internal/compiler_is/intel.h
@@ -0,0 +1,41 @@
+#ifndef RBIMPL_COMPILER_IS_INTEL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_IS_INTEL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_IS_Intel.
+ */
+#if ! defined(__INTEL_COMPILER)
+# define RBIMPL_COMPILER_IS_Intel 0
+
+#elif ! defined(__INTEL_COMPILER_UPDATE)
+# define RBIMPL_COMPILER_IS_Intel 1
+# /* __INTEL_COMPILER = XXYZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
+# define RBIMPL_COMPILER_VERSION_MINOR (__INTEL_COMPILER % 100 / 10)
+# define RBIMPL_COMPILER_VERSION_PATCH (__INTEL_COMPILER % 10)
+
+#else
+# define RBIMPL_COMPILER_IS_Intel 1
+# /* __INTEL_COMPILER = XXYZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
+# define RBIMPL_COMPILER_VERSION_MINOR (__INTEL_COMPILER % 100 / 10)
+# define RBIMPL_COMPILER_VERSION_PATCH __INTEL_COMPILER_UPDATE
+#endif
+
+#endif /* RBIMPL_COMPILER_IS_INTEL_H */
diff --git a/include/ruby/internal/compiler_is/msvc.h b/include/ruby/internal/compiler_is/msvc.h
new file mode 100644
index 0000000000..60189da1a3
--- /dev/null
+++ b/include/ruby/internal/compiler_is/msvc.h
@@ -0,0 +1,57 @@
+#ifndef RBIMPL_COMPILER_IS_MSVC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_IS_MSVC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_IS_MSVC.
+ */
+#include "ruby/internal/compiler_is/clang.h"
+#include "ruby/internal/compiler_is/intel.h"
+
+#if ! defined(_MSC_VER)
+# define RBIMPL_COMPILER_IS_MSVC 0
+
+#elif RBIMPL_COMPILER_IS(Clang)
+# define RBIMPL_COMPILER_IS_MSVC 0
+
+#elif RBIMPL_COMPILER_IS(Intel)
+# define RBIMPL_COMPILER_IS_MSVC 0
+
+#elif _MSC_VER >= 1400
+# define RBIMPL_COMPILER_IS_MSVC 1
+# /* _MSC_FULL_VER = XXYYZZZZZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_FULL_VER / 10000000)
+# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_FULL_VER % 10000000 / 100000)
+# define RBIMPL_COMPILER_VERSION_PATCH (_MSC_FULL_VER % 100000)
+
+#elif defined(_MSC_FULL_VER)
+# define RBIMPL_COMPILER_IS_MSVC 1
+# /* _MSC_FULL_VER = XXYYZZZZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_FULL_VER / 1000000)
+# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_FULL_VER % 1000000 / 10000)
+# define RBIMPL_COMPILER_VERSION_PATCH (_MSC_FULL_VER % 10000)
+
+#else
+# define RBIMPL_COMPILER_IS_MSVC 1
+# /* _MSC_VER = XXYY */
+# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_VER / 100)
+# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_VER % 100)
+# define RBIMPL_COMPILER_VERSION_PATCH 0
+#endif
+
+#endif /* RBIMPL_COMPILER_IS_MSVC_H */
diff --git a/include/ruby/internal/compiler_is/sunpro.h b/include/ruby/internal/compiler_is/sunpro.h
new file mode 100644
index 0000000000..2eb7b892f2
--- /dev/null
+++ b/include/ruby/internal/compiler_is/sunpro.h
@@ -0,0 +1,55 @@
+#ifndef RBIMPL_COMPILER_IS_SUNPRO_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_IS_SUNPRO_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_IS_SunPro.
+ */
+#if ! (defined(__SUNPRO_C) || defined(__SUNPRO_CC))
+# define RBIMPL_COMPILER_IS_SunPro 0
+
+#elif defined(__SUNPRO_C) && __SUNPRO_C >= 0x5100
+# define RBIMPL_COMPILER_IS_SunPro 1
+# /* __SUNPRO_C = 0xXYYZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_C >> 12)
+# define RBIMPL_COMPILER_VERSION_MINOR ((__SUNPRO_C >> 8 & 0xF) * 10 + (__SUNPRO_C >> 4 & 0xF))
+# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_C & 0xF)
+
+#elif defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5100
+# define RBIMPL_COMPILER_IS_SunPro 1
+# /* __SUNPRO_CC = 0xXYYZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_CC >> 12)
+# define RBIMPL_COMPILER_VERSION_MINOR ((__SUNPRO_CC >> 8 & 0xF) * 10 + (__SUNPRO_CC >> 4 & 0xF))
+# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_CC & 0xF)
+
+#elif defined(__SUNPRO_C)
+# define RBIMPL_COMPILER_IS_SunPro 1
+# /* __SUNPRO_C = 0xXYZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_C >> 8)
+# define RBIMPL_COMPILER_VERSION_MINOR (__SUNPRO_C >> 4 & 0xF)
+# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_C & 0xF)
+
+#else
+# define RBIMPL_COMPILER_IS_SunPro 1
+# /* __SUNPRO_CC = 0xXYZ */
+# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_CC >> 8)
+# define RBIMPL_COMPILER_VERSION_MINOR (__SUNPRO_CC >> 4 & 0xF)
+# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_CC & 0xF)
+#endif
+
+#endif /* RBIMPL_COMPILER_IS_SUNPRO_H */
diff --git a/include/ruby/internal/compiler_since.h b/include/ruby/internal/compiler_since.h
new file mode 100644
index 0000000000..92abb8acc8
--- /dev/null
+++ b/include/ruby/internal/compiler_since.h
@@ -0,0 +1,61 @@
+#ifndef RBIMPL_COMPILER_SINCE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_COMPILER_SINCE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_COMPILER_SINCE.
+ */
+#include "ruby/internal/compiler_is.h"
+
+/**
+ * @brief Checks if the compiler is of given brand and is newer than or equal
+ * to the passed version.
+ * @param cc Compiler brand, like `MSVC`.
+ * @param x Major version.
+ * @param y Minor version.
+ * @param z Patchlevel.
+ * @retval true cc >= x.y.z.
+ * @retval false oherwise.
+ */
+#define RBIMPL_COMPILER_SINCE(cc, x, y, z) \
+ (RBIMPL_COMPILER_IS(cc) && \
+ ((RBIMPL_COMPILER_VERSION_MAJOR > (x)) || \
+ ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
+ ((RBIMPL_COMPILER_VERSION_MINOR > (y)) || \
+ ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
+ (RBIMPL_COMPILER_VERSION_PATCH >= (z)))))))
+
+/**
+ * @brief Checks if the compiler is of given brand and is older than the
+ * passed version.
+ * @param cc Compiler brand, like `MSVC`.
+ * @param x Major version.
+ * @param y Minor version.
+ * @param z Patchlevel.
+ * @retval true cc < x.y.z.
+ * @retval false oherwise.
+ */
+#define RBIMPL_COMPILER_BEFORE(cc, x, y, z) \
+ (RBIMPL_COMPILER_IS(cc) && \
+ ((RBIMPL_COMPILER_VERSION_MAJOR < (x)) || \
+ ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
+ ((RBIMPL_COMPILER_VERSION_MINOR < (y)) || \
+ ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
+ (RBIMPL_COMPILER_VERSION_PATCH < (z)))))))
+
+#endif /* RBIMPL_COMPILER_SINCE_H */
diff --git a/include/ruby/internal/config.h b/include/ruby/internal/config.h
new file mode 100644
index 0000000000..67d7e0156f
--- /dev/null
+++ b/include/ruby/internal/config.h
@@ -0,0 +1,144 @@
+#ifndef RBIMPL_CONFIG_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_CONFIG_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Thin wrapper to ruby/config.h
+ */
+#include "ruby/config.h"
+
+#ifdef RUBY_EXTCONF_H
+# include RUBY_EXTCONF_H
+#endif
+
+#include "ruby/internal/compiler_since.h"
+
+#undef HAVE_PROTOTYPES
+#define HAVE_PROTOTYPES 1
+
+#undef HAVE_STDARG_PROTOTYPES
+#define HAVE_STDARG_PROTOTYPES 1
+
+#undef TOKEN_PASTE
+#define TOKEN_PASTE(x,y) x##y
+
+#if defined(__cplusplus)
+#/* __builtin_choose_expr and __builtin_types_compatible aren't available
+# * on C++. See https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
+# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
+# undef HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P
+
+/* HAVE_VA_ARGS_MACRO is for C. C++ situations might be different. */
+# undef HAVE_VA_ARGS_MACRO
+# if __cplusplus >= 201103L
+# define HAVE_VA_ARGS_MACRO
+# elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
+# define HAVE_VA_ARGS_MACRO
+# elif defined(__INTEL_CXX11_MODE__)
+# define HAVE_VA_ARGS_MACRO
+# elif RBIMPL_COMPILER_SINCE(MSVC, 16, 0, 0)
+# define HAVE_VA_ARGS_MACRO
+# else
+# /* NG, not known. */
+# endif
+#endif
+
+#if RBIMPL_COMPILER_BEFORE(GCC, 4, 9, 0)
+# /* See https://bugs.ruby-lang.org/issues/14221 */
+# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
+#endif
+
+#if RBIMPL_COMPILER_BEFORE(GCC, 5, 0, 0)
+# /* GCC 4.9.2 reportedly has this feature and is broken. The function is not
+# * officially documented below. Seems we should not use it.
+# * https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Other-Builtins.html */
+# undef HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN
+#endif
+
+#if defined(__SUNPRO_CC)
+# /* Oracle Developer Studio 12.5: GCC compatibility guide says it supports
+# * statement expressions. But to our knowledge they support the extension
+# * only for C and not for C++. Prove me wrong. Am happy to support them if
+# * there is a way. */
+# undef HAVE_STMT_AND_DECL_IN_EXPR
+#endif
+
+#ifndef STRINGIZE0
+# define STRINGIZE(expr) STRINGIZE0(expr)
+# define STRINGIZE0(expr) #expr
+#endif
+
+#ifdef AC_APPLE_UNIVERSAL_BUILD
+# undef WORDS_BIGENDIAN
+# ifdef __BIG_ENDIAN__
+# define WORDS_BIGENDIAN
+# endif
+#endif
+
+#ifndef DLEXT_MAXLEN
+# define DLEXT_MAXLEN 4
+#endif
+
+#ifndef RUBY_PLATFORM
+# define RUBY_PLATFORM "unknown-unknown"
+#endif
+
+#ifdef UNALIGNED_WORD_ACCESS
+# /* Take that. */
+#elif defined(__i386)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(__i386__)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(_M_IX86)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(__x86_64)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(__x86_64__)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(_M_AMD64)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(__powerpc64__)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(__aarch64__)
+# define UNALIGNED_WORD_ACCESS 1
+#elif defined(__mc68020__)
+# define UNALIGNED_WORD_ACCESS 1
+#else
+# define UNALIGNED_WORD_ACCESS 0
+#endif
+
+/* Detection of __VA_OPT__ */
+#if ! defined(HAVE_VA_ARGS_MACRO)
+# undef HAVE___VA_OPT__
+
+#else
+# /* Idea taken from: https://stackoverflow.com/a/48045656 */
+# define RBIMPL_TEST3(q, w, e, ...) e
+# define RBIMPL_TEST2(...) RBIMPL_TEST3(__VA_OPT__(,),1,0,0)
+# define RBIMPL_TEST1() RBIMPL_TEST2("ruby")
+# if RBIMPL_TEST1()
+# define HAVE___VA_OPT__
+# else
+# undef HAVE___VA_OPT__
+# endif
+# undef RBIMPL_TEST1
+# undef RBIMPL_TEST2
+# undef RBIMPL_TEST3
+#endif /* HAVE_VA_ARGS_MACRO */
+
+#endif /* RBIMPL_CONFIG_H */
diff --git a/include/ruby/internal/constant_p.h b/include/ruby/internal/constant_p.h
new file mode 100644
index 0000000000..e54a8d85b9
--- /dev/null
+++ b/include/ruby/internal/constant_p.h
@@ -0,0 +1,37 @@
+#ifndef RBIMPL_CONSTANT_P_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_CONSTANT_P_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_CONSTANT_P.
+ *
+ * Note that __builtin_constant_p can be applicable inside of inline functions,
+ * according to GCC manual. Clang lacks that feature, though.
+ *
+ * @see https://bugs.llvm.org/show_bug.cgi?id=4898
+ * @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
+ */
+#include "ruby/internal/has/builtin.h"
+
+#if RBIMPL_HAS_BUILTIN(__builtin_constant_p)
+# define RBIMPL_CONSTANT_P(expr) __builtin_constant_p(expr)
+#else
+# define RBIMPL_CONSTANT_P(expr) 0
+#endif
+
+#endif /* RBIMPL_CONSTANT_P_H */
diff --git a/include/ruby/internal/core.h b/include/ruby/internal/core.h
new file mode 100644
index 0000000000..53a00a4603
--- /dev/null
+++ b/include/ruby/internal/core.h
@@ -0,0 +1,35 @@
+#ifndef RBIMPL_CORE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_CORE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Core data structures, definitions and manupulations.
+ */
+#include "ruby/internal/core/rarray.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/core/rbignum.h"
+#include "ruby/internal/core/rclass.h"
+#include "ruby/internal/core/rdata.h"
+#include "ruby/internal/core/rfile.h"
+#include "ruby/internal/core/rhash.h"
+#include "ruby/internal/core/robject.h"
+#include "ruby/internal/core/rregexp.h"
+#include "ruby/internal/core/rstring.h"
+#include "ruby/internal/core/rstruct.h"
+#include "ruby/internal/core/rtypeddata.h"
+#endif /* RBIMPL_CORE_H */
diff --git a/include/ruby/internal/core/rarray.h b/include/ruby/internal/core/rarray.h
new file mode 100644
index 0000000000..938e2dc897
--- /dev/null
+++ b/include/ruby/internal/core/rarray.h
@@ -0,0 +1,270 @@
+#ifndef RBIMPL_RARRAY_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RARRAY_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RArray.
+ */
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/attr/maybe_unused.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/rgengc.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/assert.h"
+
+#ifndef USE_TRANSIENT_HEAP
+# define USE_TRANSIENT_HEAP 1
+#endif
+
+#define RARRAY(obj) RBIMPL_CAST((struct RArray *)(obj))
+#define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG
+#define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
+#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
+#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
+#if USE_TRANSIENT_HEAP
+# define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
+#else
+# define RARRAY_TRANSIENT_FLAG 0
+#endif
+#define RARRAY_LEN rb_array_len
+#define RARRAY_CONST_PTR rb_array_const_ptr
+#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient
+
+/** @cond INTERNAL_MACRO */
+#if defined(__fcc__) || defined(__fcc_version) || \
+ defined(__FCC__) || defined(__FCC_VERSION)
+/* workaround for old version of Fujitsu C Compiler (fcc) */
+# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
+#else
+# define FIX_CONST_VALUE_PTR(x) (x)
+#endif
+
+#define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
+#define RARRAY_LENINT RARRAY_LENINT
+#define RARRAY_TRANSIENT_P RARRAY_TRANSIENT_P
+#define RARRAY_ASET RARRAY_ASET
+#define RARRAY_PTR RARRAY_PTR
+/** @endcond */
+
+enum ruby_rarray_flags {
+ RARRAY_EMBED_FLAG = RUBY_FL_USER1,
+ /* RUBY_FL_USER2 is for ELTS_SHARED */
+ RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3
+#if USE_TRANSIENT_HEAP
+ ,
+ RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13
+#endif
+};
+
+enum ruby_rarray_consts {
+ RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3,
+ RARRAY_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
+};
+
+struct RArray {
+ struct RBasic basic;
+ union {
+ struct {
+ long len;
+ union {
+ long capa;
+#if defined(__clang__) /* <- clang++ is sane */ || \
+ !defined(__cplusplus) /* <- C99 is sane */ || \
+ (__cplusplus > 199711L) /* <- C++11 is sane */
+ const
+#endif
+ VALUE shared_root;
+ } aux;
+ const VALUE *ptr;
+ } heap;
+ const VALUE ary[RARRAY_EMBED_LEN_MAX];
+ } as;
+};
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE *rb_ary_ptr_use_start(VALUE ary);
+void rb_ary_ptr_use_end(VALUE a);
+#if USE_TRANSIENT_HEAP
+void rb_ary_detransient(VALUE a);
+#endif
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline long
+RARRAY_EMBED_LEN(VALUE ary)
+{
+ RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ANY_RAW(ary, RARRAY_EMBED_FLAG));
+
+ VALUE f = RBASIC(ary)->flags;
+ f &= RARRAY_EMBED_LEN_MASK;
+ f >>= RARRAY_EMBED_LEN_SHIFT;
+ return RBIMPL_CAST((long)f);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+static inline long
+rb_array_len(VALUE a)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+ if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
+ return RARRAY_EMBED_LEN(a);
+ }
+ else {
+ return RARRAY(a)->as.heap.len;
+ }
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+RARRAY_LENINT(VALUE ary)
+{
+ return rb_long2int(RARRAY_LEN(ary));
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RARRAY_TRANSIENT_P(VALUE ary)
+{
+ RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ return RB_FL_ANY_RAW(ary, RARRAY_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+/* internal function. do not use this function */
+static inline const VALUE *
+rb_array_const_ptr_transient(VALUE a)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+ if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
+ return FIX_CONST_VALUE_PTR(RARRAY(a)->as.ary);
+ }
+ else {
+ return FIX_CONST_VALUE_PTR(RARRAY(a)->as.heap.ptr);
+ }
+}
+
+#if ! USE_TRANSIENT_HEAP
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+#endif
+/* internal function. do not use this function */
+static inline const VALUE *
+rb_array_const_ptr(VALUE a)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ if (RARRAY_TRANSIENT_P(a)) {
+ rb_ary_detransient(a);
+ }
+#endif
+ return rb_array_const_ptr_transient(a);
+}
+
+/* internal function. do not use this function */
+static inline VALUE *
+rb_array_ptr_use_start(VALUE a,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ int allow_transient)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ if (!allow_transient) {
+ if (RARRAY_TRANSIENT_P(a)) {
+ rb_ary_detransient(a);
+ }
+ }
+#endif
+
+ return rb_ary_ptr_use_start(a);
+}
+
+/* internal function. do not use this function */
+static inline void
+rb_array_ptr_use_end(VALUE a,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ int allow_transient)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+ rb_ary_ptr_use_end(a);
+}
+
+#define RBIMPL_RARRAY_STMT(flag, ary, var, expr) do { \
+ RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY); \
+ const VALUE rbimpl_ary = (ary); \
+ VALUE *var = rb_array_ptr_use_start(rbimpl_ary, (flag)); \
+ expr; \
+ rb_array_ptr_use_end(rbimpl_ary, (flag)); \
+} while (0)
+
+#define RARRAY_PTR_USE_START(a) rb_array_ptr_use_start(a, 0)
+#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
+#define RARRAY_PTR_USE(ary, ptr_name, expr) \
+ RBIMPL_RARRAY_STMT(0, ary, ptr_name, expr)
+
+#define RARRAY_PTR_USE_START_TRANSIENT(a) rb_array_ptr_use_start(a, 1)
+#define RARRAY_PTR_USE_END_TRANSIENT(a) rb_array_ptr_use_end(a, 1)
+#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr) \
+ RBIMPL_RARRAY_STMT(1, ary, ptr_name, expr)
+
+static inline VALUE *
+RARRAY_PTR(VALUE ary)
+{
+ RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+
+ VALUE tmp = RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
+ return RBIMPL_CAST((VALUE *)RARRAY_CONST_PTR(tmp));
+}
+
+static inline void
+RARRAY_ASET(VALUE ary, long i, VALUE v)
+{
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr,
+ RB_OBJ_WRITE(ary, &ptr[i], v));
+}
+
+/*
+ * :FIXME: we want to convert RARRAY_AREF into an inline function (to add rooms
+ * for more sanity checks). However there were situations where the address of
+ * this macro is taken i.e. &RARRAY_AREF(...). They cannot be possible if this
+ * is not a macro. Such usages are abuse, and we eliminated them internally.
+ * However we are afraid of similar things to remain in the wild. This macro
+ * remains as it is due to that. If we could warn such usages we can set a
+ * transition path, but currently no way is found to do so.
+ */
+#define RARRAY_AREF(a, i) RARRAY_CONST_PTR_TRANSIENT(a)[i]
+
+#endif /* RBIMPL_RARRAY_H */
diff --git a/include/ruby/internal/core/rbasic.h b/include/ruby/internal/core/rbasic.h
new file mode 100644
index 0000000000..a6093c047a
--- /dev/null
+++ b/include/ruby/internal/core/rbasic.h
@@ -0,0 +1,85 @@
+#ifndef RBIMPL_RBASIC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RBASIC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RBasic.
+ */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/attr/forceinline.h"
+#include "ruby/internal/attr/noalias.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+
+#define RBASIC(obj) RBIMPL_CAST((struct RBasic *)(obj))
+#define RBASIC_CLASS RBASIC_CLASS
+#define RVALUE_EMBED_LEN_MAX RVALUE_EMBED_LEN_MAX
+
+/** @cond INTERNAL_MACRO */
+#define RBIMPL_EMBED_LEN_MAX_OF(T) \
+ RBIMPL_CAST((int)(sizeof(VALUE[RVALUE_EMBED_LEN_MAX]) / (sizeof(T))))
+/** @endcond */
+
+enum ruby_rvalue_flags { RVALUE_EMBED_LEN_MAX = 3 };
+
+struct
+RUBY_ALIGNAS(SIZEOF_VALUE)
+RBasic {
+ VALUE flags; /**< @see enum ::ruby_fl_type. */
+ const VALUE klass;
+
+#ifdef __cplusplus
+ public:
+ RBIMPL_ATTR_CONSTEXPR(CXX11)
+ RBIMPL_ATTR_ARTIFICIAL()
+ RBIMPL_ATTR_FORCEINLINE()
+ RBIMPL_ATTR_NOALIAS()
+ /**
+ * We need to define this explicit constructor because the field `klass` is
+ * const-qualified above, which effectively defines the implicit default
+ * constructor as "deleted" (as of C++11) -- No way but to define one by
+ * ourselves.
+ */
+ RBasic() :
+ flags(RBIMPL_VALUE_NULL),
+ klass(RBIMPL_VALUE_NULL)
+ {
+ }
+#endif
+};
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_obj_hide(VALUE obj);
+VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change klass information */
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RBASIC_CLASS(VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
+ return RBASIC(obj)->klass;
+}
+
+#endif /* RBIMPL_RBASIC_H */
diff --git a/include/ruby/internal/core/rbignum.h b/include/ruby/internal/core/rbignum.h
new file mode 100644
index 0000000000..89db566501
--- /dev/null
+++ b/include/ruby/internal/core/rbignum.h
@@ -0,0 +1,51 @@
+#ifndef RBIMPL_RBIGNUM_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RBIGNUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RBignum.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/internal/stdbool.h"
+
+#define RBIGNUM_SIGN rb_big_sign
+
+/** @cond INTERNAL_MACRO */
+#define RBIGNUM_POSITIVE_P RBIGNUM_POSITIVE_P
+#define RBIGNUM_NEGATIVE_P RBIGNUM_NEGATIVE_P
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+int rb_big_sign(VALUE num);
+RBIMPL_SYMBOL_EXPORT_END()
+
+static inline bool
+RBIGNUM_POSITIVE_P(VALUE b) {
+ RBIMPL_ASSERT_TYPE(b, RUBY_T_BIGNUM);
+ return RBIGNUM_SIGN(b);
+}
+
+static inline bool
+RBIGNUM_NEGATIVE_P(VALUE b) {
+ RBIMPL_ASSERT_TYPE(b, RUBY_T_BIGNUM);
+ return ! RBIGNUM_POSITIVE_P(b);
+}
+
+#endif /* RBIMPL_RBIGNUM_H */
diff --git a/include/ruby/internal/core/rclass.h b/include/ruby/internal/core/rclass.h
new file mode 100644
index 0000000000..0aa6b1290e
--- /dev/null
+++ b/include/ruby/internal/core/rclass.h
@@ -0,0 +1,47 @@
+#ifndef RBIMPL_RCLASS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RCLASS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RClass.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/cast.h"
+
+#define RMODULE_IS_OVERLAID RMODULE_IS_OVERLAID
+#define RMODULE_IS_REFINEMENT RMODULE_IS_REFINEMENT
+#define RMODULE_INCLUDED_INTO_REFINEMENT RMODULE_INCLUDED_INTO_REFINEMENT
+
+#define RCLASS(obj) RBIMPL_CAST((struct RClass *)(obj))
+#define RMODULE RCLASS
+#define RCLASS_SUPER rb_class_get_superclass
+
+enum ruby_rmodule_flags {
+ RMODULE_IS_OVERLAID = RUBY_FL_USER2,
+ RMODULE_IS_REFINEMENT = RUBY_FL_USER3,
+ RMODULE_INCLUDED_INTO_REFINEMENT = RUBY_FL_USER4
+};
+
+struct RClass; /* Opaque, declared here for RCLASS() macro. */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_class_get_superclass(VALUE);
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_RCLASS_H */
diff --git a/include/ruby/internal/core/rdata.h b/include/ruby/internal/core/rdata.h
new file mode 100644
index 0000000000..ca44a931dc
--- /dev/null
+++ b/include/ruby/internal/core/rdata.h
@@ -0,0 +1,184 @@
+#ifndef RBIMPL_RDATA_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RDATA_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RData.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/internal/attr/deprecated.h"
+#include "ruby/internal/attr/warning.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/token_paste.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/defines.h"
+
+#ifdef RUBY_UNTYPED_DATA_WARNING
+# /* Take that. */
+#elif defined(RUBY_EXPORT)
+# define RUBY_UNTYPED_DATA_WARNING 1
+#else
+# define RUBY_UNTYPED_DATA_WARNING 0
+#endif
+
+/** @cond INTERNAL_MACRO */
+#define RBIMPL_DATA_FUNC(f) RBIMPL_CAST((void (*)(void *))(f))
+#define RBIMPL_ATTRSET_UNTYPED_DATA_FUNC() \
+ RBIMPL_ATTR_WARNING(("untyped Data is unsafe; use TypedData instead")) \
+ RBIMPL_ATTR_DEPRECATED(("by TypedData"))
+/** @endcond */
+
+#define RDATA(obj) RBIMPL_CAST((struct RData *)(obj))
+#define DATA_PTR(obj) RDATA(obj)->data
+#define RUBY_MACRO_SELECT RBIMPL_TOKEN_PASTE
+#define RUBY_DEFAULT_FREE RBIMPL_DATA_FUNC(-1)
+#define RUBY_NEVER_FREE RBIMPL_DATA_FUNC(0)
+#define RUBY_UNTYPED_DATA_FUNC(f) f RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
+
+/*
+#define RUBY_DATA_FUNC(func) ((void (*)(void*))(func))
+*/
+typedef void (*RUBY_DATA_FUNC)(void*);
+
+struct RData {
+ struct RBasic basic;
+ RUBY_DATA_FUNC dmark;
+ RUBY_DATA_FUNC dfree;
+ void *data;
+};
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
+VALUE rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
+RUBY_EXTERN VALUE rb_cObject;
+RBIMPL_SYMBOL_EXPORT_END()
+
+#define Data_Wrap_Struct(klass, mark, free, sval) \
+ rb_data_object_wrap( \
+ (klass), \
+ (sval), \
+ RBIMPL_DATA_FUNC(mark), \
+ RBIMPL_DATA_FUNC(free))
+
+#define Data_Make_Struct0(result, klass, type, size, mark, free, sval) \
+ VALUE result = rb_data_object_zalloc( \
+ (klass), \
+ (size), \
+ RBIMPL_DATA_FUNC(mark), \
+ RBIMPL_DATA_FUNC(free)); \
+ (sval) = RBIMPL_CAST((type *)DATA_PTR(result)); \
+ RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))
+
+#ifdef HAVE_STMT_AND_DECL_IN_EXPR
+#define Data_Make_Struct(klass, type, mark, free, sval) \
+ RB_GNUC_EXTENSION({ \
+ Data_Make_Struct0( \
+ data_struct_obj, \
+ klass, \
+ type, \
+ sizeof(type), \
+ mark, \
+ free, \
+ sval); \
+ data_struct_obj; \
+ })
+#else
+#define Data_Make_Struct(klass, type, mark, free, sval) \
+ rb_data_object_make( \
+ (klass), \
+ RBIMPL_DATA_FUNC(mark), \
+ RBIMPL_DATA_FUNC(free), \
+ RBIMPL_CAST((void **)&(sval)), \
+ sizeof(type))
+#endif
+
+#define Data_Get_Struct(obj, type, sval) \
+ ((sval) = RBIMPL_CAST((type*)rb_data_object_get(obj)))
+
+RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
+static inline VALUE
+rb_data_object_wrap_warning(VALUE klass, void *ptr, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free)
+{
+ return rb_data_object_wrap(klass, ptr, mark, free);
+}
+
+static inline void *
+rb_data_object_get(VALUE obj)
+{
+ Check_Type(obj, RUBY_T_DATA);
+ return DATA_PTR(obj);
+}
+
+RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
+static inline void *
+rb_data_object_get_warning(VALUE obj)
+{
+ return rb_data_object_get(obj);
+}
+
+#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
+# define rb_data_object_wrap_warning(klass, ptr, mark, free) \
+ RB_GNUC_EXTENSION( \
+ __builtin_choose_expr( \
+ __builtin_constant_p(klass) && !(klass), \
+ rb_data_object_wrap(klass, ptr, mark, free), \
+ (rb_data_object_wrap_warning)(klass, ptr, mark, free)))
+#endif
+
+static inline VALUE
+rb_data_object_make(VALUE klass, RUBY_DATA_FUNC mark_func, RUBY_DATA_FUNC free_func, void **datap, size_t size)
+{
+ Data_Make_Struct0(result, klass, void, size, mark_func, free_func, *datap);
+ return result;
+}
+
+RBIMPL_ATTR_DEPRECATED(("by: rb_data_object_wrap"))
+static inline VALUE
+rb_data_object_alloc(VALUE klass, void *data, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
+{
+ return rb_data_object_wrap(klass, data, dmark, dfree);
+}
+
+RBIMPL_ATTR_DEPRECATED(("by: rb_cObject. Will be removed in 3.1."))
+RBIMPL_ATTR_PURE()
+static inline VALUE
+rb_cData(void)
+{
+ return rb_cObject;
+}
+#define rb_cData rb_cData()
+
+#define rb_data_object_wrap_0 rb_data_object_wrap
+#define rb_data_object_wrap_1 rb_data_object_wrap_warning
+#define rb_data_object_wrap RUBY_MACRO_SELECT(rb_data_object_wrap_, RUBY_UNTYPED_DATA_WARNING)
+#define rb_data_object_get_0 rb_data_object_get
+#define rb_data_object_get_1 rb_data_object_get_warning
+#define rb_data_object_get RUBY_MACRO_SELECT(rb_data_object_get_, RUBY_UNTYPED_DATA_WARNING)
+#define rb_data_object_make_0 rb_data_object_make
+#define rb_data_object_make_1 rb_data_object_make_warning
+#define rb_data_object_make RUBY_MACRO_SELECT(rb_data_object_make_, RUBY_UNTYPED_DATA_WARNING)
+#endif /* RBIMPL_RDATA_H */
diff --git a/include/ruby/internal/core/rfile.h b/include/ruby/internal/core/rfile.h
new file mode 100644
index 0000000000..464625b2bd
--- /dev/null
+++ b/include/ruby/internal/core/rfile.h
@@ -0,0 +1,36 @@
+#ifndef RBIMPL_RFILE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RFILE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RFile.
+ */
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/cast.h"
+
+/* rb_io_t is in ruby/io.h. The header file has historically not been included
+ * into ruby/ruby.h. We follow that tradition. */
+struct rb_io_t;
+
+struct RFile {
+ struct RBasic basic;
+ struct rb_io_t *fptr;
+};
+
+#define RFILE(obj) RBIMPL_CAST((struct RFile *)(obj))
+#endif /* RBIMPL_RFILE_H */
diff --git a/include/ruby/internal/core/rhash.h b/include/ruby/internal/core/rhash.h
new file mode 100644
index 0000000000..9bedf0af80
--- /dev/null
+++ b/include/ruby/internal/core/rhash.h
@@ -0,0 +1,62 @@
+#ifndef RBIMPL_RHASH_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RHASH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RHash.
+ *
+ * Shyouhei really suffered agnish over placement of macros in this file. They
+ * are half-brken. The situation (as of wriring) is:
+ *
+ * - #RHASH_TBL: works.
+ * - #RHASH_ITER_LEV: compile-time error.
+ * - #RHASH_IFNONE: compile-time error.
+ * - #RHASH_SIZE: works.
+ * - #RHASH_EMPTY_P: works.
+ * - #RHASH_SET_IFNONE: works (why... given you cannot query).
+ *
+ * Shyouhei stopped thinking. Let them be as is.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
+# include "ruby/backward.h"
+#endif
+
+#define RHASH_TBL(h) rb_hash_tbl(h, __FILE__, __LINE__)
+#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)
+#define RHASH_IFNONE(h) rb_hash_ifnone(h)
+#define RHASH_SIZE(h) rb_hash_size_num(h)
+#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
+#define RHASH_SET_IFNONE(h, ifnone) rb_hash_set_ifnone((VALUE)h, ifnone)
+
+struct st_table; /* in ruby/st.h */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+size_t rb_hash_size_num(VALUE hash);
+struct st_table *rb_hash_tbl(VALUE, const char *file, int line);
+VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_RHASH_H */
diff --git a/include/ruby/internal/core/rmatch.h b/include/ruby/internal/core/rmatch.h
new file mode 100644
index 0000000000..03ab5e5d82
--- /dev/null
+++ b/include/ruby/internal/core/rmatch.h
@@ -0,0 +1,73 @@
+#ifndef RBIMPL_RMATCH_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RMATCH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RMatch.
+ */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/attr/returns_nonnull.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/assert.h"
+
+#define RMATCH(obj) RBIMPL_CAST((struct RMatch *)(obj))
+/** @cond INTERNAL_MACRO */
+#define RMATCH_REGS RMATCH_REGS
+/** @endcond */
+
+struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */
+struct re_registers; /* Also in onigmo.h */
+
+/* @shyouhei wonders: is anyone actively using this typedef ...? */
+typedef struct re_pattern_buffer Regexp;
+
+struct rmatch_offset {
+ long beg;
+ long end;
+};
+
+struct rmatch {
+ struct re_registers regs;
+
+ struct rmatch_offset *char_offset;
+ int char_offset_num_allocated;
+};
+
+struct RMatch {
+ struct RBasic basic;
+ VALUE str;
+ struct rmatch *rmatch;
+ VALUE regexp; /* RRegexp */
+};
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline struct re_registers *
+RMATCH_REGS(VALUE match)
+{
+ RBIMPL_ASSERT_TYPE(match, RUBY_T_MATCH);
+ RBIMPL_ASSERT_OR_ASSUME(RMATCH(match)->rmatch != NULL);
+ return &RMATCH(match)->rmatch->regs;
+}
+
+#endif /* RBIMPL_RMATCH_H */
diff --git a/include/ruby/internal/core/robject.h b/include/ruby/internal/core/robject.h
new file mode 100644
index 0000000000..c352c87a40
--- /dev/null
+++ b/include/ruby/internal/core/robject.h
@@ -0,0 +1,96 @@
+#ifndef RBIMPL_ROBJECT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ROBJECT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RObject.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/deprecated.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+
+#define ROBJECT(obj) RBIMPL_CAST((struct RObject *)(obj))
+#define ROBJECT_EMBED_LEN_MAX ROBJECT_EMBED_LEN_MAX
+#define ROBJECT_EMBED ROBJECT_EMBED
+/** @cond INTERNAL_MACRO */
+#define ROBJECT_NUMIV ROBJECT_NUMIV
+#define ROBJECT_IVPTR ROBJECT_IVPTR
+#define ROBJECT_IV_INDEX_TBL ROBJECT_IV_INDEX_TBL
+/** @endcond */
+
+enum ruby_robject_flags { ROBJECT_EMBED = RUBY_FL_USER1 };
+
+enum ruby_robject_consts { ROBJECT_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE) };
+
+struct st_table;
+
+struct RObject {
+ struct RBasic basic;
+ union {
+ struct {
+ uint32_t numiv;
+ VALUE *ivptr;
+ struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
+ } heap;
+ VALUE ary[ROBJECT_EMBED_LEN_MAX];
+ } as;
+};
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline uint32_t
+ROBJECT_NUMIV(VALUE obj)
+{
+ RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
+
+ if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
+ return ROBJECT_EMBED_LEN_MAX;
+ }
+ else {
+ return ROBJECT(obj)->as.heap.numiv;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE *
+ROBJECT_IVPTR(VALUE obj)
+{
+ RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
+
+ struct RObject *const ptr = ROBJECT(obj);
+
+ if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
+ return ptr->as.ary;
+ }
+ else {
+ return ptr->as.heap.ivptr;
+ }
+}
+
+#endif /* RBIMPL_ROBJECT_H */
diff --git a/include/ruby/internal/core/rregexp.h b/include/ruby/internal/core/rregexp.h
new file mode 100644
index 0000000000..f289ee1dda
--- /dev/null
+++ b/include/ruby/internal/core/rregexp.h
@@ -0,0 +1,84 @@
+#ifndef RBIMPL_RREGEXP_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RREGEXP_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RRegexp.
+ */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/core/rstring.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+
+#define RREGEXP(obj) RBIMPL_CAST((struct RRegexp *)(obj))
+#define RREGEXP_PTR(obj) (RREGEXP(obj)->ptr)
+/** @cond INTERNAL_MACRO */
+#define RREGEXP_SRC RREGEXP_SRC
+#define RREGEXP_SRC_PTR RREGEXP_SRC_PTR
+#define RREGEXP_SRC_LEN RREGEXP_SRC_LEN
+#define RREGEXP_SRC_END RREGEXP_SRC_END
+/** @endcond */
+
+struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */
+
+struct RRegexp {
+ struct RBasic basic;
+ struct re_pattern_buffer *ptr;
+ const VALUE src;
+ unsigned long usecnt;
+};
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RREGEXP_SRC(VALUE rexp)
+{
+ RBIMPL_ASSERT_TYPE(rexp, RUBY_T_REGEXP);
+ VALUE ret = RREGEXP(rexp)->src;
+ RBIMPL_ASSERT_TYPE(ret, RUBY_T_STRING);
+ return ret;
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline char *
+RREGEXP_SRC_PTR(VALUE rexp)
+{
+ return RSTRING_PTR(RREGEXP_SRC(rexp));
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline long
+RREGEXP_SRC_LEN(VALUE rexp)
+{
+ return RSTRING_LEN(RREGEXP_SRC(rexp));
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline char *
+RREGEXP_SRC_END(VALUE rexp)
+{
+ return RSTRING_END(RREGEXP_SRC(rexp));
+}
+
+#endif /* RBIMPL_RREGEXP_H */
diff --git a/include/ruby/internal/core/rstring.h b/include/ruby/internal/core/rstring.h
new file mode 100644
index 0000000000..d073da1d2c
--- /dev/null
+++ b/include/ruby/internal/core/rstring.h
@@ -0,0 +1,215 @@
+#ifndef RBIMPL_RSTRING_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RSTRING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RString.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/internal/warning_push.h"
+#include "ruby/assert.h"
+
+#define RSTRING(obj) RBIMPL_CAST((struct RString *)(obj))
+#define RSTRING_NOEMBED RSTRING_NOEMBED
+#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
+#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
+#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
+#define RSTRING_FSTR RSTRING_FSTR
+
+/** @cond INTERNAL_MACRO */
+#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
+#define RSTRING_LEN RSTRING_LEN
+#define RSTRING_LENINT RSTRING_LENINT
+#define RSTRING_PTR RSTRING_PTR
+#define RSTRING_END RSTRING_END
+/** @endcond */
+
+#define StringValue(v) rb_string_value(&(v))
+#define StringValuePtr(v) rb_string_value_ptr(&(v))
+#define StringValueCStr(v) rb_string_value_cstr(&(v))
+#define SafeStringValue(v) StringValue(v)
+#define ExportStringValue(v) do { \
+ StringValue(v); \
+ (v) = rb_str_export(v); \
+} while (0)
+
+enum ruby_rstring_flags {
+ RSTRING_NOEMBED = RUBY_FL_USER1,
+ RSTRING_EMBED_LEN_MASK = RUBY_FL_USER2 | RUBY_FL_USER3 | RUBY_FL_USER4 |
+ RUBY_FL_USER5 | RUBY_FL_USER6,
+ /* Actually, string encodings are also encoded into the flags, using
+ * remaining bits.*/
+ RSTRING_FSTR = RUBY_FL_USER17
+};
+
+enum ruby_rstring_consts {
+ RSTRING_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 2,
+ RSTRING_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(char) - 1
+};
+
+struct RString {
+ struct RBasic basic;
+ union {
+ struct {
+ long len;
+ char *ptr;
+ union {
+ long capa;
+ VALUE shared;
+ } aux;
+ } heap;
+ char ary[RSTRING_EMBED_LEN_MAX + 1];
+ } as;
+};
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_str_to_str(VALUE);
+VALUE rb_string_value(volatile VALUE*);
+char *rb_string_value_ptr(volatile VALUE*);
+char *rb_string_value_cstr(volatile VALUE*);
+VALUE rb_str_export(VALUE);
+VALUE rb_str_export_locale(VALUE);
+
+RBIMPL_ATTR_ERROR(("rb_check_safe_str() and Check_SafeStr() are obsolete; use StringValue() instead"))
+void rb_check_safe_str(VALUE);
+#define Check_SafeStr(v) rb_check_safe_str(RBIMPL_CAST((VALUE)(v)))
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline long
+RSTRING_EMBED_LEN(VALUE str)
+{
+ RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
+ RBIMPL_ASSERT_OR_ASSUME(! RB_FL_ANY_RAW(str, RSTRING_NOEMBED));
+
+ VALUE f = RBASIC(str)->flags;
+ f &= RSTRING_EMBED_LEN_MASK;
+ f >>= RSTRING_EMBED_LEN_SHIFT;
+ return RBIMPL_CAST((long)f);
+}
+
+RBIMPL_WARNING_PUSH()
+#if RBIMPL_COMPILER_IS(Intel)
+RBIMPL_WARNING_IGNORED(413)
+#endif
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline struct RString
+rbimpl_rstring_getmem(VALUE str)
+{
+ RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
+
+ if (RB_FL_ANY_RAW(str, RSTRING_NOEMBED)) {
+ return *RSTRING(str);
+ }
+ else {
+ /* Expecting compilers to optimize this on-stack struct away. */
+ struct RString retval;
+ retval.as.heap.len = RSTRING_EMBED_LEN(str);
+ retval.as.heap.ptr = RSTRING(str)->as.ary;
+ return retval;
+ }
+}
+
+RBIMPL_WARNING_POP()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline long
+RSTRING_LEN(VALUE str)
+{
+ return rbimpl_rstring_getmem(str).as.heap.len;
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline char *
+RSTRING_PTR(VALUE str)
+{
+ char *ptr = rbimpl_rstring_getmem(str).as.heap.ptr;
+
+ if (RB_UNLIKELY(! ptr)) {
+ /* :BEWARE: @shyouhei thinks that currently, there are rooms for this
+ * function to return NULL. In the 20th century that was a pointless
+ * concern. However struct RString can hold fake strings nowadays. It
+ * seems no check against NULL are exercised around handling of them
+ * (one of such usages is located in marshal.c, which scares
+ * @shyouhei). Better check here for maximum safety.
+ *
+ * Also, this is not rb_warn() because RSTRING_PTR() can be called
+ * during GC (see what obj_info() does). rb_warn() needs to allocate
+ * Ruby objects. That is not possible at this moment. */
+ fprintf(stderr, "%s\n",
+ "RSTRING_PTR is returning NULL!! "
+ "SIGSEGV is highly expected to follow immediately. "
+ "If you could reproduce, attach your debugger here, "
+ "and look at the passed string."
+ );
+ }
+
+ return ptr;
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline char *
+RSTRING_END(VALUE str)
+{
+ struct RString buf = rbimpl_rstring_getmem(str);
+
+ if (RB_UNLIKELY(! buf.as.heap.ptr)) {
+ /* Ditto. */
+ fprintf(stderr, "%s\n",
+ "RSTRING_END is returning NULL!! "
+ "SIGSEGV is highly expected to follow immediately. "
+ "If you could reproduce, attach your debugger here, "
+ "and look at the passed string."
+ );
+ }
+
+ return &buf.as.heap.ptr[buf.as.heap.len];
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+RSTRING_LENINT(VALUE str)
+{
+ return rb_long2int(RSTRING_LEN(str));
+}
+
+#ifdef HAVE_STMT_AND_DECL_IN_EXPR
+# define RSTRING_GETMEM(str, ptrvar, lenvar) \
+ __extension__ ({ \
+ struct RString rbimpl_str = rbimpl_rstring_getmem(str); \
+ (ptrvar) = rbimpl_str.as.heap.ptr; \
+ (lenvar) = rbimpl_str.as.heap.len; \
+ })
+#else
+# define RSTRING_GETMEM(str, ptrvar, lenvar) \
+ ((ptrvar) = RSTRING_PTR(str), \
+ (lenvar) = RSTRING_LEN(str))
+#endif /* HAVE_STMT_AND_DECL_IN_EXPR */
+#endif /* RBIMPL_RSTRING_H */
diff --git a/include/ruby/internal/core/rstruct.h b/include/ruby/internal/core/rstruct.h
new file mode 100644
index 0000000000..17454f7cbe
--- /dev/null
+++ b/include/ruby/internal/core/rstruct.h
@@ -0,0 +1,73 @@
+#ifndef RBIMPL_RSTRUCT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RSTRUCT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Routines to manipulate struct ::RStruct.
+ */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/internal/arithmetic/long.h"
+#include "ruby/internal/arithmetic/int.h"
+#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
+# include "ruby/backward.h"
+#endif
+
+#define RSTRUCT_PTR(st) rb_struct_ptr(st)
+/** @cond INTERNAL_MACRO */
+#define RSTRUCT_LEN RSTRUCT_LEN
+#define RSTRUCT_SET RSTRUCT_SET
+#define RSTRUCT_GET RSTRUCT_GET
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_struct_size(VALUE s);
+VALUE rb_struct_aref(VALUE, VALUE);
+VALUE rb_struct_aset(VALUE, VALUE, VALUE);
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline long
+RSTRUCT_LEN(VALUE st)
+{
+ RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);
+
+ return RB_NUM2LONG(rb_struct_size(st));
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RSTRUCT_SET(VALUE st, int k, VALUE v)
+{
+ RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);
+
+ return rb_struct_aset(st, INT2NUM(k), (v));
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RSTRUCT_GET(VALUE st, int k)
+{
+ RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);
+
+ return rb_struct_aref(st, INT2NUM(k));
+}
+
+#endif /* RBIMPL_RSTRUCT_H */
diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h
new file mode 100644
index 0000000000..c038e6f2b8
--- /dev/null
+++ b/include/ruby/internal/core/rtypeddata.h
@@ -0,0 +1,186 @@
+#ifndef RBIMPL_RTYPEDDATA_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RTYPEDDATA_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines struct ::RTypedData.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/internal/assume.h"
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/core/rdata.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/error.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value_type.h"
+
+#define HAVE_TYPE_RB_DATA_TYPE_T 1
+#define HAVE_RB_DATA_TYPE_T_FUNCTION 1
+#define HAVE_RB_DATA_TYPE_T_PARENT 1
+#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
+#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
+#define RTYPEDDATA(obj) RBIMPL_CAST((struct RTypedData *)(obj))
+#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data)
+#define Check_TypedStruct(v, t) \
+ rb_check_typeddata(RBIMPL_CAST((VALUE)(v)), (t))
+
+/** @cond INTERNAL_MACRO */
+#define RTYPEDDATA_P RTYPEDDATA_P
+#define RTYPEDDATA_TYPE RTYPEDDATA_TYPE
+#define RUBY_TYPED_FREE_IMMEDIATELY RUBY_TYPED_FREE_IMMEDIATELY
+#define RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
+#define RUBY_TYPED_WB_PROTECTED RUBY_TYPED_WB_PROTECTED
+#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
+/** @endcond */
+
+/* bits for rb_data_type_struct::flags */
+enum rbimpl_typeddata_flags {
+ RUBY_TYPED_FREE_IMMEDIATELY = 1,
+ RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE,
+ RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */
+ RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */
+};
+
+typedef struct rb_data_type_struct rb_data_type_t;
+
+struct rb_data_type_struct {
+ const char *wrap_struct_name;
+ struct {
+ RUBY_DATA_FUNC dmark;
+ RUBY_DATA_FUNC dfree;
+ size_t (*dsize)(const void *);
+ RUBY_DATA_FUNC dcompact;
+ void *reserved[1]; /* For future extension.
+ This array *must* be filled with ZERO. */
+ } function;
+ const rb_data_type_t *parent;
+ void *data; /* This area can be used for any purpose
+ by a programmer who define the type. */
+ VALUE flags; /* RUBY_FL_WB_PROTECTED */
+};
+
+struct RTypedData {
+ struct RBasic basic;
+ const rb_data_type_t *type;
+ VALUE typed_flag; /* 1 or not */
+ void *data;
+};
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *);
+VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type);
+int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);
+int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type);
+void *rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type);
+RBIMPL_SYMBOL_EXPORT_END()
+
+#define TypedData_Wrap_Struct(klass,data_type,sval)\
+ rb_data_typed_object_wrap((klass),(sval),(data_type))
+
+#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
+ VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
+ (sval) = RBIMPL_CAST((type *)RTYPEDDATA_DATA(result)); \
+ RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))
+
+#ifdef HAVE_STMT_AND_DECL_IN_EXPR
+#define TypedData_Make_Struct(klass, type, data_type, sval) \
+ RB_GNUC_EXTENSION({ \
+ TypedData_Make_Struct0( \
+ data_struct_obj, \
+ klass, \
+ type, \
+ sizeof(type), \
+ data_type, \
+ sval); \
+ data_struct_obj; \
+ })
+#else
+#define TypedData_Make_Struct(klass, type, data_type, sval) \
+ rb_data_typed_object_make( \
+ (klass), \
+ (data_type), \
+ RBIMPL_CAST((void **)&(sval)), \
+ sizeof(type))
+#endif
+
+#define TypedData_Get_Struct(obj,type,data_type,sval) \
+ ((sval) = RBIMPL_CAST((type *)rb_check_typeddata((obj), (data_type))))
+
+RBIMPL_ATTR_PURE()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+rbimpl_rtypeddata_p(VALUE obj)
+{
+ return RTYPEDDATA(obj)->typed_flag == 1;
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RTYPEDDATA_P(VALUE obj)
+{
+#if RUBY_DEBUG
+ if (RB_UNLIKELY(! RB_TYPE_P(obj, RUBY_T_DATA))) {
+ Check_Type(obj, RUBY_T_DATA);
+ RBIMPL_UNREACHABLE_RETURN(false);
+ }
+#endif
+
+ return rbimpl_rtypeddata_p(obj);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
+static inline const struct rb_data_type_struct *
+RTYPEDDATA_TYPE(VALUE obj)
+{
+#if RUBY_DEBUG
+ if (RB_UNLIKELY(! RTYPEDDATA_P(obj))) {
+ rb_unexpected_type(obj, RUBY_T_DATA);
+ RBIMPL_UNREACHABLE_RETURN(NULL);
+ }
+#endif
+
+ return RTYPEDDATA(obj)->type;
+}
+
+static inline VALUE
+rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
+{
+ TypedData_Make_Struct0(result, klass, void, size, type, *datap);
+ return result;
+}
+
+RBIMPL_ATTR_DEPRECATED(("by: rb_data_typed_object_wrap"))
+static inline VALUE
+rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
+{
+ return rb_data_typed_object_wrap(klass, datap, type);
+}
+
+#endif /* RBIMPL_RTYPEDDATA_H */
diff --git a/include/ruby/internal/ctype.h b/include/ruby/internal/ctype.h
new file mode 100644
index 0000000000..aea3e0ca3d
--- /dev/null
+++ b/include/ruby/internal/ctype.h
@@ -0,0 +1,203 @@
+#ifndef RBIMPL_CTYPE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_CTYPE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Our own, locale independent, character handling routines.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <ctype.h>
+#endif
+
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/dllexport.h"
+
+#ifndef ISPRINT
+# define ISASCII rb_isascii
+# define ISPRINT rb_isprint
+# define ISGRAPH rb_isgraph
+# define ISSPACE rb_isspace
+# define ISUPPER rb_isupper
+# define ISLOWER rb_islower
+# define ISALNUM rb_isalnum
+# define ISALPHA rb_isalpha
+# define ISDIGIT rb_isdigit
+# define ISXDIGIT rb_isxdigit
+# define ISBLANK rb_isblank
+# define ISCNTRL rb_iscntrl
+# define ISPUNCT rb_ispunct
+#endif
+
+#define TOUPPER rb_toupper
+#define TOLOWER rb_tolower
+#define STRCASECMP st_locale_insensitive_strcasecmp
+#define STRNCASECMP st_locale_insensitive_strncasecmp
+#define STRTOUL ruby_strtoul
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+/* locale insensitive functions */
+int st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
+int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
+unsigned long ruby_strtoul(const char *str, char **endptr, int base);
+RBIMPL_SYMBOL_EXPORT_END()
+
+/*
+ * We are making the functions below to return `int` instead of `bool`. They
+ * have been as such since their birth at 5f237d79033b2109afb768bc889611fa9630.
+ */
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isascii(int c)
+{
+ return '\0' <= c && c <= '\x7f';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isupper(int c)
+{
+ return 'A' <= c && c <= 'Z';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_islower(int c)
+{
+ return 'a' <= c && c <= 'z';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isalpha(int c)
+{
+ return rb_isupper(c) || rb_islower(c);
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isdigit(int c)
+{
+ return '0' <= c && c <= '9';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isalnum(int c)
+{
+ return rb_isalpha(c) || rb_isdigit(c);
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isxdigit(int c)
+{
+ return rb_isdigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isblank(int c)
+{
+ return c == ' ' || c == '\t';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isspace(int c)
+{
+ return c == ' ' || ('\t' <= c && c <= '\r');
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_iscntrl(int c)
+{
+ return ('\0' <= c && c < ' ') || c == '\x7f';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isprint(int c)
+{
+ return ' ' <= c && c <= '\x7e';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_ispunct(int c)
+{
+ return !rb_isalnum(c);
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_isgraph(int c)
+{
+ return '!' <= c && c <= '\x7e';
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_tolower(int c)
+{
+ return rb_isupper(c) ? (c|0x20) : c;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline int
+rb_toupper(int c)
+{
+ return rb_islower(c) ? (c&0x5f) : c;
+}
+
+#endif /* RBIMPL_CTYPE_H */
diff --git a/include/ruby/internal/dllexport.h b/include/ruby/internal/dllexport.h
new file mode 100644
index 0000000000..1488140854
--- /dev/null
+++ b/include/ruby/internal/dllexport.h
@@ -0,0 +1,92 @@
+#ifndef RBIMPL_DLLEXPORT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_DLLEXPORT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Tewaking visibility of C variables/functions.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/compiler_is.h"
+
+/* For MinGW, we need __declspec(dllimport) for RUBY_EXTERN on MJIT.
+ mswin's RUBY_EXTERN already has that. See also: win32/Makefile.sub */
+#undef RUBY_EXTERN
+#if defined(MJIT_HEADER) && defined(_WIN32)
+# define RUBY_EXTERN extern __declspec(dllimport)
+#elif defined(RUBY_EXPORT)
+# define RUBY_EXTERN extern
+#elif defined(_WIN32)
+# define RUBY_EXTERN extern __declspec(dllimport)
+#else
+# define RUBY_EXTERN extern
+#endif
+
+#ifndef RUBY_SYMBOL_EXPORT_BEGIN
+# define RUBY_SYMBOL_EXPORT_BEGIN /* begin */
+#endif
+
+#ifndef RUBY_SYMBOL_EXPORT_END
+# define RUBY_SYMBOL_EXPORT_END /* end */
+#endif
+
+#ifndef RUBY_FUNC_EXPORTED
+# define RUBY_FUNC_EXPORTED /* void */
+#endif
+
+/* These macros are used for functions which are exported only for MJIT
+ and NOT ensured to be exported in future versions. */
+
+#if ! defined(MJIT_HEADER)
+# define MJIT_FUNC_EXPORTED RUBY_FUNC_EXPORTED
+#elif ! RBIMPL_COMPILER_IS(MSVC)
+# define MJIT_FUNC_EXPORTED RUBY_FUNC_EXPORTED
+#else
+# define MJIT_FUNC_EXPORTED static
+#endif
+
+#define MJIT_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
+#define MJIT_SYMBOL_EXPORT_END RUBY_SYMBOL_EXPORT_END
+
+/* On mswin, MJIT header transformation can't be used since cl.exe can't output
+ preprocessed output preserving macros. So this `MJIT_STATIC` is needed
+ to force non-static function to static on MJIT header to avoid symbol conflict. */
+#ifdef MJIT_HEADER
+# define MJIT_STATIC static
+#else
+# define MJIT_STATIC
+#endif
+
+/** Shortcut macro equivalent to `RUBY_SYMBOL_EXPORT_BEGIN extern "C" {`.
+ * \@shyouhei finds it handy. */
+#if defined(__DOXYGEN__)
+# define RBIMPL_SYMBOL_EXPORT_BEGIN() /* void */
+#elif defined(__cplusplus)
+# define RBIMPL_SYMBOL_EXPORT_BEGIN() RUBY_SYMBOL_EXPORT_BEGIN extern "C" {
+#else
+# define RBIMPL_SYMBOL_EXPORT_BEGIN() RUBY_SYMBOL_EXPORT_BEGIN
+#endif
+
+/** Counterpart of #RBIMPL_SYMBOL_EXPORT_BEGIN */
+#if defined(__DOXYGEN__)
+# define RBIMPL_SYMBOL_EXPORT_END() /* void */
+#elif defined(__cplusplus)
+# define RBIMPL_SYMBOL_EXPORT_END() } RUBY_SYMBOL_EXPORT_END
+#else
+# define RBIMPL_SYMBOL_EXPORT_END() RUBY_SYMBOL_EXPORT_END
+#endif
+#endif /* RBIMPL_DLLEXPORT_H */
diff --git a/include/ruby/internal/dosish.h b/include/ruby/internal/dosish.h
new file mode 100644
index 0000000000..eb71e36505
--- /dev/null
+++ b/include/ruby/internal/dosish.h
@@ -0,0 +1,63 @@
+#ifndef RBIMPL_DOSISH_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_DOSISH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Support for so-called dosish systems.
+ */
+#ifdef __CYGWIN__
+#undef _WIN32
+#endif
+
+#if defined(_WIN32)
+/*
+ DOSISH mean MS-Windows style filesystem.
+ But you should use more precise macros like DOSISH_DRIVE_LETTER, PATH_SEP,
+ ENV_IGNORECASE or CASEFOLD_FILESYSTEM.
+ */
+#define DOSISH 1
+# define DOSISH_DRIVE_LETTER
+#endif
+
+#ifdef _WIN32
+#include "ruby/win32.h"
+#endif
+
+#if defined(DOSISH)
+#define PATH_SEP ";"
+#else
+#define PATH_SEP ":"
+#endif
+
+#define PATH_SEP_CHAR PATH_SEP[0]
+
+#define PATH_ENV "PATH"
+
+#if defined(DOSISH)
+#define ENV_IGNORECASE
+#endif
+
+#ifndef CASEFOLD_FILESYSTEM
+# if defined DOSISH
+# define CASEFOLD_FILESYSTEM 1
+# else
+# define CASEFOLD_FILESYSTEM 0
+# endif
+#endif
+
+#endif /* RBIMPL_DOSISH_H */
diff --git a/include/ruby/internal/error.h b/include/ruby/internal/error.h
new file mode 100644
index 0000000000..7e9d5c4167
--- /dev/null
+++ b/include/ruby/internal/error.h
@@ -0,0 +1,84 @@
+#ifndef RBIMPL_ERROR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ERROR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Declares ::rb_raise().
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/backward/2/attributes.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+VALUE rb_errinfo(void);
+void rb_set_errinfo(VALUE);
+
+typedef enum {
+ RB_WARN_CATEGORY_NONE,
+ RB_WARN_CATEGORY_DEPRECATED,
+ RB_WARN_CATEGORY_EXPERIMENTAL,
+ RB_WARN_CATEGORY_ALL_BITS = 0x6 /* no RB_WARN_CATEGORY_NONE bit */
+} rb_warning_category_t;
+
+/* for rb_readwrite_sys_fail first argument */
+enum rb_io_wait_readwrite {RB_IO_WAIT_READABLE, RB_IO_WAIT_WRITABLE};
+#define RB_IO_WAIT_READABLE RB_IO_WAIT_READABLE
+#define RB_IO_WAIT_WRITABLE RB_IO_WAIT_WRITABLE
+
+PRINTF_ARGS(NORETURN(void rb_raise(VALUE, const char*, ...)), 2, 3);
+PRINTF_ARGS(NORETURN(void rb_fatal(const char*, ...)), 1, 2);
+COLDFUNC PRINTF_ARGS(NORETURN(void rb_bug(const char*, ...)), 1, 2);
+NORETURN(void rb_bug_errno(const char*, int));
+NORETURN(void rb_sys_fail(const char*));
+NORETURN(void rb_sys_fail_str(VALUE));
+NORETURN(void rb_mod_sys_fail(VALUE, const char*));
+NORETURN(void rb_mod_sys_fail_str(VALUE, VALUE));
+NORETURN(void rb_readwrite_sys_fail(enum rb_io_wait_readwrite, const char*));
+NORETURN(void rb_iter_break(void));
+NORETURN(void rb_iter_break_value(VALUE));
+NORETURN(void rb_exit(int));
+NORETURN(void rb_notimplement(void));
+VALUE rb_syserr_new(int, const char *);
+VALUE rb_syserr_new_str(int n, VALUE arg);
+NORETURN(void rb_syserr_fail(int, const char*));
+NORETURN(void rb_syserr_fail_str(int, VALUE));
+NORETURN(void rb_mod_syserr_fail(VALUE, int, const char*));
+NORETURN(void rb_mod_syserr_fail_str(VALUE, int, VALUE));
+NORETURN(void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite, int, const char*));
+NORETURN(void rb_unexpected_type(VALUE,int));
+
+VALUE *rb_ruby_verbose_ptr(void);
+VALUE *rb_ruby_debug_ptr(void);
+#define ruby_verbose (*rb_ruby_verbose_ptr())
+#define ruby_debug (*rb_ruby_debug_ptr())
+
+/* reports if `-W' specified */
+PRINTF_ARGS(void rb_warning(const char*, ...), 1, 2);
+PRINTF_ARGS(void rb_category_warning(rb_warning_category_t, const char*, ...), 2, 3);
+PRINTF_ARGS(void rb_compile_warning(const char *, int, const char*, ...), 3, 4);
+PRINTF_ARGS(void rb_category_compile_warn(rb_warning_category_t, const char *, int, const char*, ...), 4, 5);
+PRINTF_ARGS(void rb_sys_warning(const char*, ...), 1, 2);
+/* reports always */
+COLDFUNC PRINTF_ARGS(void rb_warn(const char*, ...), 1, 2);
+COLDFUNC PRINTF_ARGS(void rb_category_warn(rb_warning_category_t, const char*, ...), 2, 3);
+PRINTF_ARGS(void rb_compile_warn(const char *, int, const char*, ...), 3, 4);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_ERROR_H */
diff --git a/include/ruby/internal/eval.h b/include/ruby/internal/eval.h
new file mode 100644
index 0000000000..934611fbb9
--- /dev/null
+++ b/include/ruby/internal/eval.h
@@ -0,0 +1,50 @@
+#ifndef RBIMPL_EVAL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_EVAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Declares ::rb_eval_string().
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+VALUE rb_eval_string(const char*);
+VALUE rb_eval_string_protect(const char*, int*);
+VALUE rb_eval_string_wrap(const char*, int*);
+VALUE rb_funcall(VALUE, ID, int, ...);
+VALUE rb_funcallv(VALUE, ID, int, const VALUE*);
+VALUE rb_funcallv_kw(VALUE, ID, int, const VALUE*, int);
+VALUE rb_funcallv_public(VALUE, ID, int, const VALUE*);
+VALUE rb_funcallv_public_kw(VALUE, ID, int, const VALUE*, int);
+#define rb_funcall2 rb_funcallv
+#define rb_funcall3 rb_funcallv_public
+VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
+VALUE rb_funcall_passing_block_kw(VALUE, ID, int, const VALUE*, int);
+VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
+VALUE rb_funcall_with_block_kw(VALUE, ID, int, const VALUE*, VALUE, int);
+VALUE rb_call_super(int, const VALUE*);
+VALUE rb_call_super_kw(int, const VALUE*, int);
+VALUE rb_current_receiver(void);
+int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *);
+VALUE rb_extract_keywords(VALUE *orighash);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_EVAL_H */
diff --git a/include/ruby/internal/event.h b/include/ruby/internal/event.h
new file mode 100644
index 0000000000..f20e01dc01
--- /dev/null
+++ b/include/ruby/internal/event.h
@@ -0,0 +1,75 @@
+#ifndef RBIMPL_EVENT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_EVENT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Debugging and tracing APIs.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* traditional set_trace_func events */
+#define RUBY_EVENT_NONE 0x0000
+#define RUBY_EVENT_LINE 0x0001
+#define RUBY_EVENT_CLASS 0x0002
+#define RUBY_EVENT_END 0x0004
+#define RUBY_EVENT_CALL 0x0008
+#define RUBY_EVENT_RETURN 0x0010
+#define RUBY_EVENT_C_CALL 0x0020
+#define RUBY_EVENT_C_RETURN 0x0040
+#define RUBY_EVENT_RAISE 0x0080
+#define RUBY_EVENT_ALL 0x00ff
+
+/* for TracePoint extended events */
+#define RUBY_EVENT_B_CALL 0x0100
+#define RUBY_EVENT_B_RETURN 0x0200
+#define RUBY_EVENT_THREAD_BEGIN 0x0400
+#define RUBY_EVENT_THREAD_END 0x0800
+#define RUBY_EVENT_FIBER_SWITCH 0x1000
+#define RUBY_EVENT_SCRIPT_COMPILED 0x2000
+#define RUBY_EVENT_TRACEPOINT_ALL 0xffff
+
+/* special events */
+#define RUBY_EVENT_RESERVED_FOR_INTERNAL_USE 0x030000
+
+/* internal events */
+#define RUBY_INTERNAL_EVENT_SWITCH 0x040000
+#define RUBY_EVENT_SWITCH 0x040000 /* obsolete name. this macro is for compatibility */
+ /* 0x080000 */
+#define RUBY_INTERNAL_EVENT_NEWOBJ 0x100000
+#define RUBY_INTERNAL_EVENT_FREEOBJ 0x200000
+#define RUBY_INTERNAL_EVENT_GC_START 0x400000
+#define RUBY_INTERNAL_EVENT_GC_END_MARK 0x800000
+#define RUBY_INTERNAL_EVENT_GC_END_SWEEP 0x1000000
+#define RUBY_INTERNAL_EVENT_GC_ENTER 0x2000000
+#define RUBY_INTERNAL_EVENT_GC_EXIT 0x4000000
+#define RUBY_INTERNAL_EVENT_OBJSPACE_MASK 0x7f00000
+#define RUBY_INTERNAL_EVENT_MASK 0xffff0000
+
+typedef uint32_t rb_event_flag_t;
+typedef void (*rb_event_hook_func_t)(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass);
+
+#define RB_EVENT_HOOKS_HAVE_CALLBACK_DATA 1
+void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);
+int rb_remove_event_hook(rb_event_hook_func_t func);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_EVENT_H */
diff --git a/include/ruby/internal/fl_type.h b/include/ruby/internal/fl_type.h
new file mode 100644
index 0000000000..455448fe8d
--- /dev/null
+++ b/include/ruby/internal/fl_type.h
@@ -0,0 +1,471 @@
+#ifndef RBIMPL_FL_TYPE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_FL_TYPE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines enum ::ruby_fl_type.
+ */
+#include "ruby/internal/config.h" /* for ENUM_OVER_INT */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/flag_enum.h"
+#include "ruby/internal/attr/forceinline.h"
+#include "ruby/internal/attr/noalias.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/assert.h"
+#include "ruby/defines.h"
+
+/** @cond INTERNAL_MACRO */
+#ifdef ENUM_OVER_INT
+# define RBIMPL_WIDER_ENUM 1
+#elif SIZEOF_INT * CHAR_BIT > 12+19+1
+# define RBIMPL_WIDER_ENUM 1
+#else
+# define RBIMPL_WIDER_ENUM 0
+#endif
+/** @endcond */
+
+#define FL_SINGLETON RBIMPL_CAST((VALUE)RUBY_FL_SINGLETON)
+#define FL_WB_PROTECTED RBIMPL_CAST((VALUE)RUBY_FL_WB_PROTECTED)
+#define FL_PROMOTED0 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED0)
+#define FL_PROMOTED1 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED1)
+#define FL_FINALIZE RBIMPL_CAST((VALUE)RUBY_FL_FINALIZE)
+#define FL_TAINT RBIMPL_CAST((VALUE)RUBY_FL_TAINT)
+#define FL_SHAREABLE RBIMPL_CAST((VALUE)RUBY_FL_SHAREABLE)
+#define FL_UNTRUSTED RBIMPL_CAST((VALUE)RUBY_FL_UNTRUSTED)
+#define FL_SEEN_OBJ_ID RBIMPL_CAST((VALUE)RUBY_FL_SEEN_OBJ_ID)
+#define FL_EXIVAR RBIMPL_CAST((VALUE)RUBY_FL_EXIVAR)
+#define FL_FREEZE RBIMPL_CAST((VALUE)RUBY_FL_FREEZE)
+
+#define FL_USHIFT RBIMPL_CAST((VALUE)RUBY_FL_USHIFT)
+
+#define FL_USER0 RBIMPL_CAST((VALUE)RUBY_FL_USER0)
+#define FL_USER1 RBIMPL_CAST((VALUE)RUBY_FL_USER1)
+#define FL_USER2 RBIMPL_CAST((VALUE)RUBY_FL_USER2)
+#define FL_USER3 RBIMPL_CAST((VALUE)RUBY_FL_USER3)
+#define FL_USER4 RBIMPL_CAST((VALUE)RUBY_FL_USER4)
+#define FL_USER5 RBIMPL_CAST((VALUE)RUBY_FL_USER5)
+#define FL_USER6 RBIMPL_CAST((VALUE)RUBY_FL_USER6)
+#define FL_USER7 RBIMPL_CAST((VALUE)RUBY_FL_USER7)
+#define FL_USER8 RBIMPL_CAST((VALUE)RUBY_FL_USER8)
+#define FL_USER9 RBIMPL_CAST((VALUE)RUBY_FL_USER9)
+#define FL_USER10 RBIMPL_CAST((VALUE)RUBY_FL_USER10)
+#define FL_USER11 RBIMPL_CAST((VALUE)RUBY_FL_USER11)
+#define FL_USER12 RBIMPL_CAST((VALUE)RUBY_FL_USER12)
+#define FL_USER13 RBIMPL_CAST((VALUE)RUBY_FL_USER13)
+#define FL_USER14 RBIMPL_CAST((VALUE)RUBY_FL_USER14)
+#define FL_USER15 RBIMPL_CAST((VALUE)RUBY_FL_USER15)
+#define FL_USER16 RBIMPL_CAST((VALUE)RUBY_FL_USER16)
+#define FL_USER17 RBIMPL_CAST((VALUE)RUBY_FL_USER17)
+#define FL_USER18 RBIMPL_CAST((VALUE)RUBY_FL_USER18)
+#define FL_USER19 RBIMPL_CAST((VALUE)(unsigned int)RUBY_FL_USER19)
+
+#define ELTS_SHARED RUBY_ELTS_SHARED
+#define RUBY_ELTS_SHARED RUBY_ELTS_SHARED
+#define RB_OBJ_FREEZE rb_obj_freeze_inline
+
+/** @cond INTERNAL_MACRO */
+#define RB_FL_ABLE RB_FL_ABLE
+#define RB_FL_ALL RB_FL_ALL
+#define RB_FL_ALL_RAW RB_FL_ALL_RAW
+#define RB_FL_ANY RB_FL_ANY
+#define RB_FL_ANY_RAW RB_FL_ANY_RAW
+#define RB_FL_REVERSE RB_FL_REVERSE
+#define RB_FL_REVERSE_RAW RB_FL_REVERSE_RAW
+#define RB_FL_SET RB_FL_SET
+#define RB_FL_SET_RAW RB_FL_SET_RAW
+#define RB_FL_TEST RB_FL_TEST
+#define RB_FL_TEST_RAW RB_FL_TEST_RAW
+#define RB_FL_UNSET RB_FL_UNSET
+#define RB_FL_UNSET_RAW RB_FL_UNSET_RAW
+#define RB_OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW
+#define RB_OBJ_FROZEN RB_OBJ_FROZEN
+#define RB_OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW
+#define RB_OBJ_INFECT RB_OBJ_INFECT
+#define RB_OBJ_INFECT_RAW RB_OBJ_INFECT_RAW
+#define RB_OBJ_TAINT RB_OBJ_TAINT
+#define RB_OBJ_TAINTABLE RB_OBJ_TAINTABLE
+#define RB_OBJ_TAINTED RB_OBJ_TAINTED
+#define RB_OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW
+#define RB_OBJ_TAINT_RAW RB_OBJ_TAINT_RAW
+#define RB_OBJ_UNTRUST RB_OBJ_UNTRUST
+#define RB_OBJ_UNTRUSTED RB_OBJ_UNTRUSTED
+/** @endcond */
+
+/**
+ * @defgroup deprecated_macros deprecated macro APIs
+ * @{
+ * These macros are deprecated. Prefer their `RB_`-prefixed versions.
+ */
+#define FL_ABLE RB_FL_ABLE
+#define FL_ALL RB_FL_ALL
+#define FL_ALL_RAW RB_FL_ALL_RAW
+#define FL_ANY RB_FL_ANY
+#define FL_ANY_RAW RB_FL_ANY_RAW
+#define FL_REVERSE RB_FL_REVERSE
+#define FL_REVERSE_RAW RB_FL_REVERSE_RAW
+#define FL_SET RB_FL_SET
+#define FL_SET_RAW RB_FL_SET_RAW
+#define FL_TEST RB_FL_TEST
+#define FL_TEST_RAW RB_FL_TEST_RAW
+#define FL_UNSET RB_FL_UNSET
+#define FL_UNSET_RAW RB_FL_UNSET_RAW
+#define OBJ_FREEZE RB_OBJ_FREEZE
+#define OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW
+#define OBJ_FROZEN RB_OBJ_FROZEN
+#define OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW
+#define OBJ_INFECT RB_OBJ_INFECT
+#define OBJ_INFECT_RAW RB_OBJ_INFECT_RAW
+#define OBJ_TAINT RB_OBJ_TAINT
+#define OBJ_TAINTABLE RB_OBJ_TAINTABLE
+#define OBJ_TAINTED RB_OBJ_TAINTED
+#define OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW
+#define OBJ_TAINT_RAW RB_OBJ_TAINT_RAW
+#define OBJ_UNTRUST RB_OBJ_UNTRUST
+#define OBJ_UNTRUSTED RB_OBJ_UNTRUSTED
+/** @} */
+
+/* This is an enum because GDB wants it (rather than a macro) */
+enum ruby_fl_ushift { RUBY_FL_USHIFT = 12 };
+
+/* > The expression that defines the value of an enumeration constant shall be
+ * > an integer constant expression that has a value representable as an `int`.
+ *
+ * -- ISO/IEC 9899:2018 section 6.7.2.2
+ *
+ * So ENUM_OVER_INT situation is an extension to the standard. Note however
+ * that we do not support 16 bit `int` environment. */
+RB_GNUC_EXTENSION
+enum
+RBIMPL_ATTR_FLAG_ENUM()
+ruby_fl_type {
+ RUBY_FL_WB_PROTECTED = (1<<5),
+ RUBY_FL_PROMOTED0 = (1<<5),
+ RUBY_FL_PROMOTED1 = (1<<6),
+ RUBY_FL_PROMOTED = RUBY_FL_PROMOTED0 | RUBY_FL_PROMOTED1,
+ RUBY_FL_FINALIZE = (1<<7),
+ RUBY_FL_TAINT = (1<<8),
+ RUBY_FL_SHAREABLE = (1<<8),
+ RUBY_FL_UNTRUSTED = RUBY_FL_TAINT,
+ RUBY_FL_SEEN_OBJ_ID = (1<<9),
+ RUBY_FL_EXIVAR = (1<<10),
+ RUBY_FL_FREEZE = (1<<11),
+
+#define RBIMPL_FL_USER_N(n) RUBY_FL_USER##n = (1<<(RUBY_FL_USHIFT+n))
+ RBIMPL_FL_USER_N(0),
+ RBIMPL_FL_USER_N(1),
+ RBIMPL_FL_USER_N(2),
+ RBIMPL_FL_USER_N(3),
+ RBIMPL_FL_USER_N(4),
+ RBIMPL_FL_USER_N(5),
+ RBIMPL_FL_USER_N(6),
+ RBIMPL_FL_USER_N(7),
+ RBIMPL_FL_USER_N(8),
+ RBIMPL_FL_USER_N(9),
+ RBIMPL_FL_USER_N(10),
+ RBIMPL_FL_USER_N(11),
+ RBIMPL_FL_USER_N(12),
+ RBIMPL_FL_USER_N(13),
+ RBIMPL_FL_USER_N(14),
+ RBIMPL_FL_USER_N(15),
+ RBIMPL_FL_USER_N(16),
+ RBIMPL_FL_USER_N(17),
+ RBIMPL_FL_USER_N(18),
+#if ENUM_OVER_INT
+ RBIMPL_FL_USER_N(19),
+#else
+# define RUBY_FL_USER19 (RBIMPL_VALUE_ONE<<(RUBY_FL_USHIFT+19))
+#endif
+#undef RBIMPL_FL_USER_N
+#undef RBIMPL_WIDER_ENUM
+
+ RUBY_ELTS_SHARED = RUBY_FL_USER2,
+ RUBY_FL_SINGLETON = RUBY_FL_USER0,
+};
+
+enum { RUBY_FL_DUPPED = RUBY_T_MASK | RUBY_FL_EXIVAR | RUBY_FL_TAINT };
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+void rb_obj_infect(VALUE victim, VALUE carrier);
+void rb_freeze_singleton_class(VALUE klass);
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+RBIMPL_ATTR_FORCEINLINE()
+static bool
+RB_FL_ABLE(VALUE obj)
+{
+ if (RB_SPECIAL_CONST_P(obj)) {
+ return false;
+ }
+ else if (RB_TYPE_P(obj, RUBY_T_NODE)) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
+ return RBASIC(obj)->flags & flags;
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RB_FL_TEST(VALUE obj, VALUE flags)
+{
+ if (RB_FL_ABLE(obj)) {
+ return RB_FL_TEST_RAW(obj, flags);
+ }
+ else {
+ return RBIMPL_VALUE_NULL;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_FL_ANY_RAW(VALUE obj, VALUE flags)
+{
+ return RB_FL_TEST_RAW(obj, flags);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_FL_ANY(VALUE obj, VALUE flags)
+{
+ return RB_FL_TEST(obj, flags);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_FL_ALL_RAW(VALUE obj, VALUE flags)
+{
+ return RB_FL_TEST_RAW(obj, flags) == flags;
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_FL_ALL(VALUE obj, VALUE flags)
+{
+ return RB_FL_TEST(obj, flags) == flags;
+}
+
+RBIMPL_ATTR_NOALIAS()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+rbimpl_fl_set_raw_raw(struct RBasic *obj, VALUE flags)
+{
+ obj->flags |= flags;
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_FL_SET_RAW(VALUE obj, VALUE flags)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
+ rbimpl_fl_set_raw_raw(RBASIC(obj), flags);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_FL_SET(VALUE obj, VALUE flags)
+{
+ if (RB_FL_ABLE(obj)) {
+ RB_FL_SET_RAW(obj, flags);
+ }
+}
+
+RBIMPL_ATTR_NOALIAS()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+rbimpl_fl_unset_raw_raw(struct RBasic *obj, VALUE flags)
+{
+ obj->flags &= ~flags;
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_FL_UNSET_RAW(VALUE obj, VALUE flags)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
+ rbimpl_fl_unset_raw_raw(RBASIC(obj), flags);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_FL_UNSET(VALUE obj, VALUE flags)
+{
+ if (RB_FL_ABLE(obj)) {
+ RB_FL_UNSET_RAW(obj, flags);
+ }
+}
+
+RBIMPL_ATTR_NOALIAS()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+rbimpl_fl_reverse_raw_raw(struct RBasic *obj, VALUE flags)
+{
+ obj->flags ^= flags;
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_FL_REVERSE_RAW(VALUE obj, VALUE flags)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
+ rbimpl_fl_reverse_raw_raw(RBASIC(obj), flags);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_FL_REVERSE(VALUE obj, VALUE flags)
+{
+ if (RB_FL_ABLE(obj)) {
+ RB_FL_REVERSE_RAW(obj, flags);
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_OBJ_TAINTABLE(VALUE obj)
+{
+ if (! RB_FL_ABLE(obj)) {
+ return false;
+ }
+ else if (RB_TYPE_P(obj, RUBY_T_BIGNUM)) {
+ return false;
+ }
+ else if (RB_TYPE_P(obj, RUBY_T_FLOAT)) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RB_OBJ_TAINTED_RAW(VALUE obj)
+{
+ return RB_FL_TEST_RAW(obj, RUBY_FL_TAINT);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_OBJ_TAINTED(VALUE obj)
+{
+ return RB_FL_ANY(obj, RUBY_FL_TAINT);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_OBJ_TAINT_RAW(VALUE obj)
+{
+ RB_FL_SET_RAW(obj, RUBY_FL_TAINT);
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_OBJ_TAINT(VALUE obj)
+{
+ if (RB_OBJ_TAINTABLE(obj)) {
+ RB_OBJ_TAINT_RAW(obj);
+ }
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_OBJ_INFECT_RAW(VALUE dst, VALUE src)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_OBJ_TAINTABLE(dst));
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(src));
+ RB_FL_SET_RAW(dst, RB_OBJ_TAINTED_RAW(src));
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_OBJ_INFECT(VALUE dst, VALUE src)
+{
+ if (RB_OBJ_TAINTABLE(dst) && RB_FL_ABLE(src)) {
+ RB_OBJ_INFECT_RAW(dst, src);
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+/* It is intentional not to return bool here. There is a place in ruby core
+ * (namely class.c:singleton_class_of()) where return value of this function is
+ * verbatimly passed to RB_FL_SET_RAW. */
+static inline VALUE
+RB_OBJ_FROZEN_RAW(VALUE obj)
+{
+ return RB_FL_TEST_RAW(obj, RUBY_FL_FREEZE);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_OBJ_FROZEN(VALUE obj)
+{
+ if (! RB_FL_ABLE(obj)) {
+ return true;
+ }
+ else {
+ return RB_OBJ_FROZEN_RAW(obj);
+ }
+}
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+RB_OBJ_FREEZE_RAW(VALUE obj)
+{
+ RB_FL_SET_RAW(obj, RUBY_FL_FREEZE);
+}
+
+static inline void
+rb_obj_freeze_inline(VALUE x)
+{
+ if (RB_FL_ABLE(x)) {
+ RB_OBJ_FREEZE_RAW(x);
+ if (RBASIC_CLASS(x) && !(RBASIC(x)->flags & RUBY_FL_SINGLETON)) {
+ rb_freeze_singleton_class(x);
+ }
+ }
+}
+
+#endif /* RBIMPL_FL_TYPE_H */
diff --git a/include/ruby/internal/gc.h b/include/ruby/internal/gc.h
new file mode 100644
index 0000000000..d94f8a3736
--- /dev/null
+++ b/include/ruby/internal/gc.h
@@ -0,0 +1,57 @@
+#ifndef RBIMPL_GC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_GC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Registering values to the GC.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/**
+ * Inform the garbage collector that `valptr` points to a live Ruby object that
+ * should not be moved. Note that extensions should use this API on global
+ * constants instead of assuming constants defined in Ruby are always alive.
+ * Ruby code can remove global constants.
+ */
+void rb_gc_register_address(VALUE *valptr);
+
+/**
+ * An alias for `rb_gc_register_address()`.
+ */
+void rb_global_variable(VALUE *);
+
+/**
+ * Inform the garbage collector that a pointer previously passed to
+ * `rb_gc_register_address()` no longer points to a live Ruby object.
+ */
+void rb_gc_unregister_address(VALUE *valptr);
+
+/**
+ * Inform the garbage collector that `object` is a live Ruby object that should
+ * not be moved.
+ *
+ * See also: rb_gc_register_address()
+ */
+void rb_gc_register_mark_object(VALUE object);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_GC_H */
diff --git a/include/ruby/internal/glob.h b/include/ruby/internal/glob.h
new file mode 100644
index 0000000000..b78bb75b88
--- /dev/null
+++ b/include/ruby/internal/glob.h
@@ -0,0 +1,35 @@
+#ifndef RBIMPL_GLOB_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_GLOB_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Declares ::rb_glob().
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+typedef int ruby_glob_func(const char*,VALUE, void*);
+void rb_glob(const char*,void(*)(const char*,VALUE,void*),VALUE);
+int ruby_glob(const char*,int,ruby_glob_func*,VALUE);
+int ruby_brace_glob(const char*,int,ruby_glob_func*,VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_GLOB_H */
diff --git a/include/ruby/internal/globals.h b/include/ruby/internal/globals.h
new file mode 100644
index 0000000000..ddd731349e
--- /dev/null
+++ b/include/ruby/internal/globals.h
@@ -0,0 +1,157 @@
+#ifndef RBIMPL_GLOBALS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_GLOBALS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Ruby-level global variables / constants, visible from C.
+ */
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+#define RUBY_INTEGER_UNIFICATION 1
+
+RUBY_EXTERN VALUE rb_mKernel;
+RUBY_EXTERN VALUE rb_mComparable;
+RUBY_EXTERN VALUE rb_mEnumerable;
+RUBY_EXTERN VALUE rb_mErrno;
+RUBY_EXTERN VALUE rb_mFileTest;
+RUBY_EXTERN VALUE rb_mGC;
+RUBY_EXTERN VALUE rb_mMath;
+RUBY_EXTERN VALUE rb_mProcess;
+RUBY_EXTERN VALUE rb_mWaitReadable;
+RUBY_EXTERN VALUE rb_mWaitWritable;
+
+RUBY_EXTERN VALUE rb_cBasicObject;
+RUBY_EXTERN VALUE rb_cObject;
+RUBY_EXTERN VALUE rb_cArray;
+RUBY_EXTERN VALUE rb_cBinding;
+RUBY_EXTERN VALUE rb_cClass;
+RUBY_EXTERN VALUE rb_cDir;
+RUBY_EXTERN VALUE rb_cEncoding;
+RUBY_EXTERN VALUE rb_cEnumerator;
+RUBY_EXTERN VALUE rb_cFalseClass;
+RUBY_EXTERN VALUE rb_cFile;
+RUBY_EXTERN VALUE rb_cComplex;
+RUBY_EXTERN VALUE rb_cFloat;
+RUBY_EXTERN VALUE rb_cHash;
+RUBY_EXTERN VALUE rb_cIO;
+RUBY_EXTERN VALUE rb_cInteger;
+RUBY_EXTERN VALUE rb_cMatch;
+RUBY_EXTERN VALUE rb_cMethod;
+RUBY_EXTERN VALUE rb_cModule;
+RUBY_EXTERN VALUE rb_cNameErrorMesg;
+RUBY_EXTERN VALUE rb_cNilClass;
+RUBY_EXTERN VALUE rb_cNumeric;
+RUBY_EXTERN VALUE rb_cProc;
+RUBY_EXTERN VALUE rb_cRandom;
+RUBY_EXTERN VALUE rb_cRange;
+RUBY_EXTERN VALUE rb_cRational;
+RUBY_EXTERN VALUE rb_cRegexp;
+RUBY_EXTERN VALUE rb_cStat;
+RUBY_EXTERN VALUE rb_cString;
+RUBY_EXTERN VALUE rb_cStruct;
+RUBY_EXTERN VALUE rb_cSymbol;
+RUBY_EXTERN VALUE rb_cThread;
+RUBY_EXTERN VALUE rb_cTime;
+RUBY_EXTERN VALUE rb_cTrueClass;
+RUBY_EXTERN VALUE rb_cUnboundMethod;
+
+RUBY_EXTERN VALUE rb_eException;
+RUBY_EXTERN VALUE rb_eStandardError;
+RUBY_EXTERN VALUE rb_eSystemExit;
+RUBY_EXTERN VALUE rb_eInterrupt;
+RUBY_EXTERN VALUE rb_eSignal;
+RUBY_EXTERN VALUE rb_eFatal;
+RUBY_EXTERN VALUE rb_eArgError;
+RUBY_EXTERN VALUE rb_eEOFError;
+RUBY_EXTERN VALUE rb_eIndexError;
+RUBY_EXTERN VALUE rb_eStopIteration;
+RUBY_EXTERN VALUE rb_eKeyError;
+RUBY_EXTERN VALUE rb_eRangeError;
+RUBY_EXTERN VALUE rb_eIOError;
+RUBY_EXTERN VALUE rb_eRuntimeError;
+RUBY_EXTERN VALUE rb_eFrozenError;
+RUBY_EXTERN VALUE rb_eSecurityError;
+RUBY_EXTERN VALUE rb_eSystemCallError;
+RUBY_EXTERN VALUE rb_eThreadError;
+RUBY_EXTERN VALUE rb_eTypeError;
+RUBY_EXTERN VALUE rb_eZeroDivError;
+RUBY_EXTERN VALUE rb_eNotImpError;
+RUBY_EXTERN VALUE rb_eNoMemError;
+RUBY_EXTERN VALUE rb_eNoMethodError;
+RUBY_EXTERN VALUE rb_eFloatDomainError;
+RUBY_EXTERN VALUE rb_eLocalJumpError;
+RUBY_EXTERN VALUE rb_eSysStackError;
+RUBY_EXTERN VALUE rb_eRegexpError;
+RUBY_EXTERN VALUE rb_eEncodingError;
+RUBY_EXTERN VALUE rb_eEncCompatError;
+RUBY_EXTERN VALUE rb_eNoMatchingPatternError;
+
+RUBY_EXTERN VALUE rb_eScriptError;
+RUBY_EXTERN VALUE rb_eNameError;
+RUBY_EXTERN VALUE rb_eSyntaxError;
+RUBY_EXTERN VALUE rb_eLoadError;
+
+RUBY_EXTERN VALUE rb_eMathDomainError;
+
+RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;
+
+RBIMPL_ATTR_PURE()
+static inline VALUE
+rb_class_of(VALUE obj)
+{
+ if (! RB_SPECIAL_CONST_P(obj)) {
+ return RBASIC_CLASS(obj);
+ }
+ else if (obj == RUBY_Qfalse) {
+ return rb_cFalseClass;
+ }
+ else if (obj == RUBY_Qnil) {
+ return rb_cNilClass;
+ }
+ else if (obj == RUBY_Qtrue) {
+ return rb_cTrueClass;
+ }
+ else if (RB_FIXNUM_P(obj)) {
+ return rb_cInteger;
+ }
+ else if (RB_STATIC_SYM_P(obj)) {
+ return rb_cSymbol;
+ }
+ else if (RB_FLONUM_P(obj)) {
+ return rb_cFloat;
+ }
+
+#if !RUBY_DEBUG
+ RBIMPL_UNREACHABLE_RETURN(Qfalse);
+#else
+ RUBY_ASSERT_FAIL("unexpected type");
+#endif
+}
+
+#define CLASS_OF rb_class_of
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_GLOBALS_H */
diff --git a/include/ruby/internal/has/attribute.h b/include/ruby/internal/has/attribute.h
new file mode 100644
index 0000000000..512f061dc5
--- /dev/null
+++ b/include/ruby/internal/has/attribute.h
@@ -0,0 +1,164 @@
+#ifndef RBIMPL_HAS_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_ATTRIBUTE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_ATTRIBUTE.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/token_paste.h"
+
+#if defined(__has_attribute)
+# if __has_attribute(pure) || RBIMPL_COMPILER_IS(GCC)
+# /* FreeBSD's <sys/cdefs.h> defines its own *broken* version of
+# * __has_attribute. Cygwin copied that content to be a victim of the
+# * broken-ness. We don't take them into account. */
+# define RBIMPL_HAVE___HAS_ATTRIBUTE 1
+# endif
+#endif
+
+/** Wraps (or simulates) `__has_attribute`. */
+#if defined(RBIMPL_HAVE___HAS_ATTRIBUTE)
+# define RBIMPL_HAS_ATTRIBUTE(_) __has_attribute(_)
+
+#elif RBIMPL_COMPILER_IS(GCC)
+# /* GCC <= 4 lack __has_attribute predefined macro, while have attributes
+# * themselves. We can simulate the macro like the following: */
+# define RBIMPL_HAS_ATTRIBUTE(_) RBIMPL_TOKEN_PASTE(RBIMPL_HAS_ATTRIBUTE_, _)
+# define RBIMPL_HAS_ATTRIBUTE_aligned RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_alloc_size RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_artificial RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_always_inline RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
+# define RBIMPL_HAS_ATTRIBUTE_cdecl RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_cold RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_const RBIMPL_COMPILER_SINCE(GCC, 2, 6, 0)
+# define RBIMPL_HAS_ATTRIBUTE_deprecated RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
+# define RBIMPL_HAS_ATTRIBUTE_dllexport RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_dllimport RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_error RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_format RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_hot RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_leaf RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
+# define RBIMPL_HAS_ATTRIBUTE_malloc RBIMPL_COMPILER_SINCE(GCC, 3, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_no_address_safety_analysis RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
+# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_address RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
+# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_undefined RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_noinline RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
+# define RBIMPL_HAS_ATTRIBUTE_nonnull RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_noreturn RBIMPL_COMPILER_SINCE(GCC, 2, 5, 0)
+# define RBIMPL_HAS_ATTRIBUTE_nothrow RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_pure RBIMPL_COMPILER_SINCE(GCC, 2,96, 0)
+# define RBIMPL_HAS_ATTRIBUTE_returns_nonnull RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_returns_twice RBIMPL_COMPILER_SINCE(GCC, 4, 1, 0)
+# define RBIMPL_HAS_ATTRIBUTE_stdcall RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_unused RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_ATTRIBUTE_visibility RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_warn_unused_result RBIMPL_COMPILER_SINCE(GCC, 3, 4, 0)
+# define RBIMPL_HAS_ATTRIBUTE_warning RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
+# define RBIMPL_HAS_ATTRIBUTE_weak RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# /* Note that "0, 0, 0" might be inaccurate. */
+
+#elif RBIMPL_COMPILER_IS(SunPro)
+# /* Oracle Solaris Studio 12.4 (cc version 5.11) introduced __has_attribute.
+# * Before that, following attributes were available. */
+# /* See https://docs.oracle.com/cd/F24633_01/index.html */
+# define RBIMPL_HAS_ATTRIBUTE(_) RBIMPL_TOKEN_PASTE(RBIMPL_HAS_ATTRIBUTE_, _)
+# define RBIMPL_HAS_ATTRIBUTE_alias RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_aligned RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_always_inline RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
+# define RBIMPL_HAS_ATTRIBUTE_const RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_constructor RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_destructor RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_malloc RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_noinline RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_noreturn RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_packed RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_pure RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_returns_twice RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
+# define RBIMPL_HAS_ATTRIBUTE_vector_size RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
+# define RBIMPL_HAS_ATTRIBUTE_visibility RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+# define RBIMPL_HAS_ATTRIBUTE_weak RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
+
+#elif defined (_MSC_VER)
+# define RBIMPL_HAS_ATTRIBUTE(_) 0
+# /* Fallback below doesn't work: see win32/Makefile.sub */
+
+#else
+# /* Take config.h definition when available. */
+# define RBIMPL_HAS_ATTRIBUTE(_) (RBIMPL_TOKEN_PASTE(RBIMPL_HAS_ATTRIBUTE_, _)+0)
+# ifdef ALWAYS_INLINE
+# define RBIMPL_HAS_ATTRIBUTE_always_inline 1
+# endif
+# ifdef FUNC_CDECL
+# define RBIMPL_HAS_ATTRIBUTE_cdecl 1
+# endif
+# ifdef CONSTFUNC
+# define RBIMPL_HAS_ATTRIBUTE_const 1
+# endif
+# ifdef DEPRECATED
+# define RBIMPL_HAS_ATTRIBUTE_deprecated 1
+# endif
+# ifdef ERRORFUNC
+# define RBIMPL_HAS_ATTRIBUTE_error 1
+# endif
+# ifdef FUNC_FASTCALL
+# define RBIMPL_HAS_ATTRIBUTE_fastcall 1
+# endif
+# ifdef PUREFUNC
+# define RBIMPL_HAS_ATTRIBUTE_pure 1
+# endif
+# ifdef NO_ADDRESS_SAFETY_ANALYSIS
+# define RBIMPL_HAS_ATTRIBUTE_no_address_safety_analysis 1
+# endif
+# ifdef NO_SANITIZE
+# define RBIMPL_HAS_ATTRIBUTE_no_sanitize 1
+# endif
+# ifdef NO_SANITIZE_ADDRESS
+# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_address 1
+# endif
+# ifdef NOINLINE
+# define RBIMPL_HAS_ATTRIBUTE_noinline 1
+# endif
+# ifdef RBIMPL_FUNC_NONNULL
+# define RBIMPL_HAS_ATTRIBUTE_nonnull 1
+# endif
+# ifdef NORETURN
+# define RBIMPL_HAS_ATTRIBUTE_noreturn 1
+# endif
+# ifdef FUNC_OPTIMIZED
+# define RBIMPL_HAS_ATTRIBUTE_optimize 1
+# endif
+# ifdef FUNC_STDCALL
+# define RBIMPL_HAS_ATTRIBUTE_stdcall 1
+# endif
+# ifdef MAYBE_UNUSED
+# define RBIMPL_HAS_ATTRIBUTE_unused 1
+# endif
+# ifdef WARN_UNUSED_RESULT
+# define RBIMPL_HAS_ATTRIBUTE_warn_unused_result 1
+# endif
+# ifdef WARNINGFUNC
+# define RBIMPL_HAS_ATTRIBUTE_warning 1
+# endif
+# ifdef WEAK
+# define RBIMPL_HAS_ATTRIBUTE_weak 1
+# endif
+#endif
+
+#endif /* RBIMPL_HAS_ATTRIBUTE_H */
diff --git a/include/ruby/internal/has/builtin.h b/include/ruby/internal/has/builtin.h
new file mode 100644
index 0000000000..18cfc69e19
--- /dev/null
+++ b/include/ruby/internal/has/builtin.h
@@ -0,0 +1,105 @@
+#ifndef RBIMPL_HAS_BUILTIN_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_BUILTIN_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_BUILTIN.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/token_paste.h"
+
+#if defined(__has_builtin)
+# if RBIMPL_COMPILER_IS(Intel)
+# /* :TODO: Intel C Compiler has __has_builtin (since 19.1 maybe?), and is
+# * reportedly broken. We have to skip them. However the situation can
+# * change. They might improve someday. We need to revisit here later. */
+# elif RBIMPL_COMPILER_IS(GCC) && ! __has_builtin(__builtin_alloca)
+# /* FreeBSD's <sys/cdefs.h> defines its own *broken* version of
+# * __has_builtin. Cygwin copied that content to be a victim of the
+# * broken-ness. We don't take them into account. */
+# else
+# define RBIMPL_HAVE___HAS_BUILTIN 1
+# endif
+#endif
+
+/** Wraps (or simulates) `__has_builtin`. */
+#if defined(RBIMPL_HAVE___HAS_BUILTIN)
+# define RBIMPL_HAS_BUILTIN(_) __has_builtin(_)
+
+#elif RBIMPL_COMPILER_IS(GCC)
+# /* :FIXME: Historically GCC has had tons of builtins, but it implemented
+# * __has_builtin only since GCC 10. This section can be made more
+# * granular. */
+# /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 */
+# define RBIMPL_HAS_BUILTIN(_) RBIMPL_TOKEN_PASTE(RBIMPL_HAS_BUILTIN_, _)
+# define RBIMPL_HAS_BUILTIN___builtin_add_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_alloca RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_alloca_with_align RBIMPL_COMPILER_SINCE(GCC, 6, 1, 0)
+# /* See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 for bswap16. */
+# define RBIMPL_HAS_BUILTIN___builtin_bswap16 RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_bswap32 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_bswap64 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_clz RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_clzl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_clzll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_constant_p RBIMPL_COMPILER_SINCE(GCC, 2,95, 3)
+# define RBIMPL_HAS_BUILTIN___builtin_ctz RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_ctzl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_ctzll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_expect RBIMPL_COMPILER_SINCE(GCC, 3, 0, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow_p RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_popcount RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_popcountl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_popcountll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
+# define RBIMPL_HAS_BUILTIN___builtin_unreachable RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
+# /* Note that "0, 0, 0" might be inaccurate. */
+
+#elif RBIMPL_COMPILER_IS(MSVC)
+# /* MSVC has UNREACHABLE, but that is not __builtin_unreachable. */
+# define RBIMPL_HAS_BUILTIN(_) 0
+
+#else
+# /* Take config.h definition when available */
+# define RBIMPL_HAS_BUILTIN(_) (RBIMPL_TOKEN_PASTE(RBIMPL_HAS_BUILTIN_, _)+0)
+# define RBIMPL_HAS_BUILTIN___builtin_add_overflow HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW
+# define RBIMPL_HAS_BUILTIN___builtin_alloca_with_align HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN
+# define RBIMPL_HAS_BUILTIN___builtin_assume_aligned HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
+# define RBIMPL_HAS_BUILTIN___builtin_bswap16 HAVE_BUILTIN___BUILTIN_BSWAP16
+# define RBIMPL_HAS_BUILTIN___builtin_bswap32 HAVE_BUILTIN___BUILTIN_BSWAP32
+# define RBIMPL_HAS_BUILTIN___builtin_bswap64 HAVE_BUILTIN___BUILTIN_BSWAP64
+# define RBIMPL_HAS_BUILTIN___builtin_clz HAVE_BUILTIN___BUILTIN_CLZ
+# define RBIMPL_HAS_BUILTIN___builtin_clzl HAVE_BUILTIN___BUILTIN_CLZL
+# define RBIMPL_HAS_BUILTIN___builtin_clzll HAVE_BUILTIN___BUILTIN_CLZLL
+# define RBIMPL_HAS_BUILTIN___builtin_constant_p HAVE_BUILTIN___BUILTIN_CONSTANT_P
+# define RBIMPL_HAS_BUILTIN___builtin_ctz HAVE_BUILTIN___BUILTIN_CTZ
+# define RBIMPL_HAS_BUILTIN___builtin_ctzll HAVE_BUILTIN___BUILTIN_CTZLL
+# define RBIMPL_HAS_BUILTIN___builtin_expect HAVE_BUILTIN___BUILTIN_EXPECT
+# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
+# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow_p HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P
+# define RBIMPL_HAS_BUILTIN___builtin_popcount HAVE_BUILTIN___BUILTIN_POPCOUNT
+# define RBIMPL_HAS_BUILTIN___builtin_popcountll HAVE_BUILTIN___BUILTIN_POPCOUNTLL
+# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW
+# if defined(UNREACHABLE)
+# define RBIMPL_HAS_BUILTIN___builtin_unreachable 1
+# endif
+#endif
+
+#endif /* RBIMPL_HAS_BUILTIN_H */
diff --git a/include/ruby/internal/has/c_attribute.h b/include/ruby/internal/has/c_attribute.h
new file mode 100644
index 0000000000..b7eb94d22a
--- /dev/null
+++ b/include/ruby/internal/has/c_attribute.h
@@ -0,0 +1,38 @@
+#ifndef RBIMPL_HAS_C_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_C_ATTRIBUTE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_C_ATTRIBUTE.
+ */
+
+/** Wraps (or simulates) `__has_c_attribute`. */
+#if defined(__cplusplus)
+# /* Makes no sense. */
+# define RBIMPL_HAS_C_ATTRIBUTE(_) 0
+
+#elif defined(__has_c_attribute)
+# define RBIMPL_HAS_C_ATTRIBUTE(_) __has_c_attribute(_)
+
+#else
+# /* As of writing everything that lacks __has_c_attribute also completely
+# * lacks C2x attributes as well. Might change in future? */
+# define RBIMPL_HAS_C_ATTRIBUTE(_) 0
+#endif
+
+#endif /* RBIMPL_HAS_C_ATTRIBUTE_H */
diff --git a/include/ruby/internal/has/cpp_attribute.h b/include/ruby/internal/has/cpp_attribute.h
new file mode 100644
index 0000000000..255f611d70
--- /dev/null
+++ b/include/ruby/internal/has/cpp_attribute.h
@@ -0,0 +1,87 @@
+#ifndef RBIMPL_HAS_CPP_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_CPP_ATTRIBUTE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_CPP_ATTRIBUTE.
+ */
+#include "ruby/internal/compiler_is.h"
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/token_paste.h"
+
+/** @cond INTERNAL_MACRO */
+#if RBIMPL_COMPILER_IS(SunPro)
+# /* Oracle Developer Studio 12.5's C++ preprocessor is reportedly broken. We
+# * could simulate __has_cpp_attribute like below, but don't know the exact
+# * list of which version supported which attribute. Just kill everything for
+# * now. If you can please :FIXME: */
+# /* https://unicode-org.atlassian.net/browse/ICU-12893 */
+# /* https://github.com/boostorg/config/pull/95 */
+# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) 0
+
+#elif defined(__has_cpp_attribute)
+# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) __has_cpp_attribute(_)
+
+#elif RBIMPL_COMPILER_IS(MSVC)
+# /* MSVC has never updated its __cplusplus since forever (unless specified
+# * explicitly by a compiler flag). They also lack __has_cpp_attribute until
+# * 2019. However, they do have attributes since 2015 or so. */
+# /* https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance */
+# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) RBIMPL_TOKEN_PASTE(RBIMPL_HAS_CPP_ATTRIBUTE_, _)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn 200809 * RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 0)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_carries_dependency 200809 * RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 0)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated 201309 * RBIMPL_COMPILER_SINCE(MSVC, 19, 10, 0)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_fallthrough 201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 10, 0)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_maybe_unused 201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 0)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_nodiscard 201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 0)
+
+#elif RBIMPL_COMPILER_BEFORE(Clang, 3, 6, 0)
+# /* Clang 3.6.0 introduced __has_cpp_attribute. Prior to that following
+# * attributes were already there. */
+# /* https://clang.llvm.org/cxx_status.html */
+# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) RBIMPL_TOKEN_PASTE(RBIMPL_HAS_CPP_ATTRIBUTE_, _)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn 200809 * RBIMPL_COMPILER_SINCE(Clang, 3, 3, 0)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated 201309 * RBIMPL_COMPILER_SINCE(Clang, 3, 4, 0)
+
+#elif RBIMPL_COMPILER_BEFORE(GCC, 5, 0, 0)
+# /* GCC 5+ have __has_cpp_attribute, while 4.x had following attributes. */
+# /* https://gcc.gnu.org/projects/cxx-status.html */
+# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) RBIMPL_TOKEN_PASTE(RBIMPL_HAS_CPP_ATTRIBUTE_, _)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn 200809 * RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
+# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated 201309 * RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
+
+#else
+# /* :FIXME:
+# * Candidate compilers to list here:
+# * - icpc: They have __INTEL_CXX11_MODE__.
+# */
+# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) 0
+#endif
+/** @endcond */
+
+/** Wraps (or simulates) `__has_cpp_attribute`. */
+#if ! defined(__cplusplus)
+# /* Makes no sense. */
+# define RBIMPL_HAS_CPP_ATTRIBUTE(_) 0
+#else
+# /* GCC needs workarounds. See https://gcc.godbolt.org/z/jdz3pa */
+# define RBIMPL_HAS_CPP_ATTRIBUTE(_) \
+ ((RBIMPL_HAS_CPP_ATTRIBUTE0(_) <= __cplusplus) ? RBIMPL_HAS_CPP_ATTRIBUTE0(_) : 0)
+#endif
+
+#endif /* RBIMPL_HAS_CPP_ATTRIBUTE_H */
diff --git a/include/ruby/internal/has/declspec_attribute.h b/include/ruby/internal/has/declspec_attribute.h
new file mode 100644
index 0000000000..02610338b8
--- /dev/null
+++ b/include/ruby/internal/has/declspec_attribute.h
@@ -0,0 +1,48 @@
+#ifndef RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_DECLSPEC_ATTRIBUTE.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/token_paste.h"
+
+/** Wraps (or simulates) `__has_declspec_attribute`. */
+#if defined(__has_declspec_attribute)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE(_) __has_declspec_attribute(_)
+#else
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE(_) RBIMPL_TOKEN_PASTE(RBIMPL_HAS_DECLSPEC_ATTRIBUTE_, _)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_align RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_deprecated RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllexport RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllimport RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_empty_bases RBIMPL_COMPILER_SINCE(MSVC,19, 0, 23918)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noalias RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noinline RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noreturn RBIMPL_COMPILER_SINCE(MSVC,11, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
+# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_restrict RBIMPL_COMPILER_SINCE(MSVC,14, 0, 0)
+# /* Note that "8, 0, 0" might be inaccurate. */
+# if ! defined(__cplusplus)
+# /* Clang has this in both C/C++, but MSVC has this in C++ only.*/
+# undef RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow
+# endif
+#endif
+
+#endif /* RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H */
diff --git a/include/ruby/internal/has/extension.h b/include/ruby/internal/has/extension.h
new file mode 100644
index 0000000000..9ceb365ab9
--- /dev/null
+++ b/include/ruby/internal/has/extension.h
@@ -0,0 +1,33 @@
+#ifndef RBIMPL_HAS_EXTENSION_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_EXTENSION_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_EXTENSION.
+ */
+#include "ruby/internal/has/feature.h"
+
+/** Wraps (or simulates) `__has_extension`. */
+#if defined(__has_extension)
+# define RBIMPL_HAS_EXTENSION(_) __has_extension(_)
+#else
+# /* Pre-3.0 clang had __has_feature but not __has_extension. */
+# define RBIMPL_HAS_EXTENSION(_) RBIMPL_HAS_FEATURE(_)
+#endif
+
+#endif /* RBIMPL_HAS_EXTENSION_H */
diff --git a/include/ruby/internal/has/feature.h b/include/ruby/internal/has/feature.h
new file mode 100644
index 0000000000..b827590c00
--- /dev/null
+++ b/include/ruby/internal/has/feature.h
@@ -0,0 +1,31 @@
+#ifndef RBIMPL_HAS_FEATURE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_FEATURE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_FEATURE.
+ */
+
+/** Wraps (or simulates) `__has_feature`. */
+#if defined(__has_feature)
+# define RBIMPL_HAS_FEATURE(_) __has_feature(_)
+#else
+# define RBIMPL_HAS_FEATURE(_) 0
+#endif
+
+#endif /* RBIMPL_HAS_FEATURE_H */
diff --git a/include/ruby/internal/has/warning.h b/include/ruby/internal/has/warning.h
new file mode 100644
index 0000000000..03975ecc2f
--- /dev/null
+++ b/include/ruby/internal/has/warning.h
@@ -0,0 +1,31 @@
+#ifndef RBIMPL_HAS_WARNING_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_HAS_WARNING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_HAS_WARNING.
+ */
+
+/** Wraps (or simulates) `__has_warning`. */
+#if defined(__has_warning)
+# define RBIMPL_HAS_WARNING(_) __has_warning(_)
+#else
+# define RBIMPL_HAS_WARNING(_) 0
+#endif
+
+#endif /* RBIMPL_HAS_WARNING_H */
diff --git a/include/ruby/internal/intern/array.h b/include/ruby/internal/intern/array.h
new file mode 100644
index 0000000000..aafe0d1350
--- /dev/null
+++ b/include/ruby/internal/intern/array.h
@@ -0,0 +1,78 @@
+#ifndef RBIMPL_INTERN_ARRAY_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_ARRAY_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cArray.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* array.c */
+void rb_mem_clear(VALUE*, long);
+VALUE rb_assoc_new(VALUE, VALUE);
+VALUE rb_check_array_type(VALUE);
+VALUE rb_ary_new(void);
+VALUE rb_ary_new_capa(long capa);
+VALUE rb_ary_new_from_args(long n, ...);
+VALUE rb_ary_new_from_values(long n, const VALUE *elts);
+VALUE rb_ary_tmp_new(long);
+void rb_ary_free(VALUE);
+void rb_ary_modify(VALUE);
+VALUE rb_ary_freeze(VALUE);
+VALUE rb_ary_shared_with_p(VALUE, VALUE);
+VALUE rb_ary_aref(int, const VALUE*, VALUE);
+VALUE rb_ary_subseq(VALUE, long, long);
+void rb_ary_store(VALUE, long, VALUE);
+VALUE rb_ary_dup(VALUE);
+VALUE rb_ary_resurrect(VALUE ary);
+VALUE rb_ary_to_ary(VALUE);
+VALUE rb_ary_to_s(VALUE);
+VALUE rb_ary_cat(VALUE, const VALUE *, long);
+VALUE rb_ary_push(VALUE, VALUE);
+VALUE rb_ary_pop(VALUE);
+VALUE rb_ary_shift(VALUE);
+VALUE rb_ary_unshift(VALUE, VALUE);
+VALUE rb_ary_entry(VALUE, long);
+VALUE rb_ary_each(VALUE);
+VALUE rb_ary_join(VALUE, VALUE);
+VALUE rb_ary_reverse(VALUE);
+VALUE rb_ary_rotate(VALUE, long);
+VALUE rb_ary_sort(VALUE);
+VALUE rb_ary_sort_bang(VALUE);
+VALUE rb_ary_delete(VALUE, VALUE);
+VALUE rb_ary_delete_at(VALUE, long);
+VALUE rb_ary_clear(VALUE);
+VALUE rb_ary_plus(VALUE, VALUE);
+VALUE rb_ary_concat(VALUE, VALUE);
+VALUE rb_ary_assoc(VALUE, VALUE);
+VALUE rb_ary_rassoc(VALUE, VALUE);
+VALUE rb_ary_includes(VALUE, VALUE);
+VALUE rb_ary_cmp(VALUE, VALUE);
+VALUE rb_ary_replace(VALUE copy, VALUE orig);
+VALUE rb_get_values_at(VALUE, long, int, const VALUE*, VALUE(*)(VALUE,long));
+VALUE rb_ary_resize(VALUE ary, long len);
+#define rb_ary_new2 rb_ary_new_capa
+#define rb_ary_new3 rb_ary_new_from_args
+#define rb_ary_new4 rb_ary_new_from_values
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_ARRAY_H */
diff --git a/include/ruby/internal/intern/bignum.h b/include/ruby/internal/intern/bignum.h
new file mode 100644
index 0000000000..1ac92e9c90
--- /dev/null
+++ b/include/ruby/internal/intern/bignum.h
@@ -0,0 +1,105 @@
+#ifndef RBIMPL_INTERN_BIGNUM_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_BIGNUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to so-called rb_cBignum.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/backward/2/long_long.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* bignum.c */
+VALUE rb_big_new(size_t, int);
+int rb_bigzero_p(VALUE x);
+VALUE rb_big_clone(VALUE);
+void rb_big_2comp(VALUE);
+VALUE rb_big_norm(VALUE);
+void rb_big_resize(VALUE big, size_t len);
+VALUE rb_cstr_to_inum(const char*, int, int);
+VALUE rb_str_to_inum(VALUE, int, int);
+VALUE rb_cstr2inum(const char*, int);
+VALUE rb_str2inum(VALUE, int);
+VALUE rb_big2str(VALUE, int);
+long rb_big2long(VALUE);
+#define rb_big2int(x) rb_big2long(x)
+unsigned long rb_big2ulong(VALUE);
+#define rb_big2uint(x) rb_big2ulong(x)
+#if HAVE_LONG_LONG
+LONG_LONG rb_big2ll(VALUE);
+unsigned LONG_LONG rb_big2ull(VALUE);
+#endif /* HAVE_LONG_LONG */
+void rb_big_pack(VALUE val, unsigned long *buf, long num_longs);
+VALUE rb_big_unpack(unsigned long *buf, long num_longs);
+int rb_uv_to_utf8(char[6],unsigned long);
+VALUE rb_dbl2big(double);
+double rb_big2dbl(VALUE);
+VALUE rb_big_cmp(VALUE, VALUE);
+VALUE rb_big_eq(VALUE, VALUE);
+VALUE rb_big_eql(VALUE, VALUE);
+VALUE rb_big_plus(VALUE, VALUE);
+VALUE rb_big_minus(VALUE, VALUE);
+VALUE rb_big_mul(VALUE, VALUE);
+VALUE rb_big_div(VALUE, VALUE);
+VALUE rb_big_idiv(VALUE, VALUE);
+VALUE rb_big_modulo(VALUE, VALUE);
+VALUE rb_big_divmod(VALUE, VALUE);
+VALUE rb_big_pow(VALUE, VALUE);
+VALUE rb_big_and(VALUE, VALUE);
+VALUE rb_big_or(VALUE, VALUE);
+VALUE rb_big_xor(VALUE, VALUE);
+VALUE rb_big_lshift(VALUE, VALUE);
+VALUE rb_big_rshift(VALUE, VALUE);
+
+/* For rb_integer_pack and rb_integer_unpack: */
+/* "MS" in MSWORD and MSBYTE means "most significant" */
+/* "LS" in LSWORD and LSBYTE means "least significant" */
+#define INTEGER_PACK_MSWORD_FIRST 0x01
+#define INTEGER_PACK_LSWORD_FIRST 0x02
+#define INTEGER_PACK_MSBYTE_FIRST 0x10
+#define INTEGER_PACK_LSBYTE_FIRST 0x20
+#define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40
+#define INTEGER_PACK_2COMP 0x80
+#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400
+/* For rb_integer_unpack: */
+#define INTEGER_PACK_FORCE_BIGNUM 0x100
+#define INTEGER_PACK_NEGATIVE 0x200
+/* Combinations: */
+#define INTEGER_PACK_LITTLE_ENDIAN \
+ (INTEGER_PACK_LSWORD_FIRST | \
+ INTEGER_PACK_LSBYTE_FIRST)
+#define INTEGER_PACK_BIG_ENDIAN \
+ (INTEGER_PACK_MSWORD_FIRST | \
+ INTEGER_PACK_MSBYTE_FIRST)
+int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
+VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
+size_t rb_absint_size(VALUE val, int *nlz_bits_ret);
+size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);
+int rb_absint_singlebit_p(VALUE val);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_BIGNUM_H */
diff --git a/include/ruby/internal/intern/class.h b/include/ruby/internal/intern/class.h
new file mode 100644
index 0000000000..d3be80d283
--- /dev/null
+++ b/include/ruby/internal/intern/class.h
@@ -0,0 +1,57 @@
+#ifndef RBIMPL_INTERN_CLASS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_CLASS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cClass/::rb_cModule.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/backward/2/stdarg.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* class.c */
+VALUE rb_class_new(VALUE);
+VALUE rb_mod_init_copy(VALUE, VALUE);
+VALUE rb_singleton_class_clone(VALUE);
+void rb_singleton_class_attached(VALUE,VALUE);
+void rb_check_inheritable(VALUE);
+VALUE rb_define_class_id(ID, VALUE);
+VALUE rb_define_class_id_under(VALUE, ID, VALUE);
+VALUE rb_module_new(void);
+VALUE rb_define_module_id(ID);
+VALUE rb_define_module_id_under(VALUE, ID);
+VALUE rb_mod_included_modules(VALUE);
+VALUE rb_mod_include_p(VALUE, VALUE);
+VALUE rb_mod_ancestors(VALUE);
+VALUE rb_class_instance_methods(int, const VALUE*, VALUE);
+VALUE rb_class_public_instance_methods(int, const VALUE*, VALUE);
+VALUE rb_class_protected_instance_methods(int, const VALUE*, VALUE);
+VALUE rb_class_private_instance_methods(int, const VALUE*, VALUE);
+VALUE rb_obj_singleton_methods(int, const VALUE*, VALUE);
+void rb_define_method_id(VALUE, ID, VALUE (*)(ANYARGS), int);
+void rb_undef(VALUE, ID);
+void rb_define_protected_method(VALUE, const char*, VALUE (*)(ANYARGS), int);
+void rb_define_private_method(VALUE, const char*, VALUE (*)(ANYARGS), int);
+void rb_define_singleton_method(VALUE, const char*, VALUE(*)(ANYARGS), int);
+VALUE rb_singleton_class(VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_CLASS_H */
diff --git a/include/ruby/internal/intern/compar.h b/include/ruby/internal/intern/compar.h
new file mode 100644
index 0000000000..d226ca37b1
--- /dev/null
+++ b/include/ruby/internal/intern/compar.h
@@ -0,0 +1,34 @@
+#ifndef RBIMPL_INTERN_COMPAR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_COMPAR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_mComparable.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* compar.c */
+int rb_cmpint(VALUE, VALUE, VALUE);
+NORETURN(void rb_cmperr(VALUE, VALUE));
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_COMPAR_H */
diff --git a/include/ruby/internal/intern/complex.h b/include/ruby/internal/intern/complex.h
new file mode 100644
index 0000000000..70343221f6
--- /dev/null
+++ b/include/ruby/internal/intern/complex.h
@@ -0,0 +1,60 @@
+#ifndef RBIMPL_INTERN_COMPLEX_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_COMPLEX_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cComplex.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here. */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* complex.c */
+VALUE rb_complex_raw(VALUE, VALUE);
+#define rb_complex_raw1(x) rb_complex_raw((x), INT2FIX(0))
+#define rb_complex_raw2(x,y) rb_complex_raw((x), (y))
+VALUE rb_complex_new(VALUE, VALUE);
+#define rb_complex_new1(x) rb_complex_new((x), INT2FIX(0))
+#define rb_complex_new2(x,y) rb_complex_new((x), (y))
+VALUE rb_complex_new_polar(VALUE abs, VALUE arg);
+DEPRECATED_BY(rb_complex_new_polar, VALUE rb_complex_polar(VALUE abs, VALUE arg));
+VALUE rb_complex_real(VALUE z);
+VALUE rb_complex_imag(VALUE z);
+VALUE rb_complex_plus(VALUE x, VALUE y);
+VALUE rb_complex_minus(VALUE x, VALUE y);
+VALUE rb_complex_mul(VALUE x, VALUE y);
+VALUE rb_complex_div(VALUE x, VALUE y);
+VALUE rb_complex_uminus(VALUE z);
+VALUE rb_complex_conjugate(VALUE z);
+VALUE rb_complex_abs(VALUE z);
+VALUE rb_complex_arg(VALUE z);
+VALUE rb_complex_pow(VALUE base, VALUE exp);
+VALUE rb_dbl_complex_new(double real, double imag);
+#define rb_complex_add rb_complex_plus
+#define rb_complex_sub rb_complex_minus
+#define rb_complex_nagate rb_complex_uminus
+
+VALUE rb_Complex(VALUE, VALUE);
+#define rb_Complex1(x) rb_Complex((x), INT2FIX(0))
+#define rb_Complex2(x,y) rb_Complex((x), (y))
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_COMPLEX_H */
diff --git a/include/ruby/internal/intern/cont.h b/include/ruby/internal/intern/cont.h
new file mode 100644
index 0000000000..cfa5630af2
--- /dev/null
+++ b/include/ruby/internal/intern/cont.h
@@ -0,0 +1,41 @@
+#ifndef RBIMPL_INTERN_CONT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_CONT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to rb_cFiber.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/iterator.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* cont.c */
+VALUE rb_fiber_new(rb_block_call_func_t, VALUE);
+VALUE rb_fiber_new_kw(rb_block_call_func_t, VALUE, int kw_splat);
+VALUE rb_fiber_resume(VALUE fib, int argc, const VALUE *argv);
+VALUE rb_fiber_resume_kw(VALUE fib, int argc, const VALUE *argv, int kw_splat);
+VALUE rb_fiber_yield(int argc, const VALUE *argv);
+VALUE rb_fiber_yield_kw(int argc, const VALUE *argv, int kw_splat);
+VALUE rb_fiber_current(void);
+VALUE rb_fiber_alive_p(VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_CONT_H */
diff --git a/include/ruby/internal/intern/dir.h b/include/ruby/internal/intern/dir.h
new file mode 100644
index 0000000000..936f4e1f36
--- /dev/null
+++ b/include/ruby/internal/intern/dir.h
@@ -0,0 +1,33 @@
+#ifndef RBIMPL_INTERN_DIR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_DIR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cDir.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* dir.c */
+VALUE rb_dir_getwd(void);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_DIR_H */
diff --git a/include/ruby/internal/intern/enum.h b/include/ruby/internal/intern/enum.h
new file mode 100644
index 0000000000..17c20c1c0a
--- /dev/null
+++ b/include/ruby/internal/intern/enum.h
@@ -0,0 +1,33 @@
+#ifndef RBIMPL_INTERN_ENUM_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_ENUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_mEnumerable.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* enum.c */
+VALUE rb_enum_values_pack(int, const VALUE*);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_ENUM_H */
diff --git a/include/ruby/internal/intern/enumerator.h b/include/ruby/internal/intern/enumerator.h
new file mode 100644
index 0000000000..c81485155c
--- /dev/null
+++ b/include/ruby/internal/intern/enumerator.h
@@ -0,0 +1,80 @@
+#ifndef RBIMPL_INTERN_ENUMERATOR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_ENUMERATOR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cEnumerator.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/intern/eval.h" /* rb_frame_this_func */
+#include "ruby/internal/iterator.h" /* rb_block_given_p */
+#include "ruby/internal/symbol.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+typedef VALUE rb_enumerator_size_func(VALUE, VALUE, VALUE);
+
+typedef struct {
+ VALUE begin;
+ VALUE end;
+ VALUE step;
+ int exclude_end;
+} rb_arithmetic_sequence_components_t;
+
+/* enumerator.c */
+VALUE rb_enumeratorize(VALUE, VALUE, int, const VALUE *);
+VALUE rb_enumeratorize_with_size(VALUE, VALUE, int, const VALUE *, rb_enumerator_size_func *);
+VALUE rb_enumeratorize_with_size_kw(VALUE, VALUE, int, const VALUE *, rb_enumerator_size_func *, int);
+int rb_arithmetic_sequence_extract(VALUE, rb_arithmetic_sequence_components_t *);
+VALUE rb_arithmetic_sequence_beg_len_step(VALUE, long *begp, long *lenp, long *stepp, long len, int err);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#ifndef RUBY_EXPORT
+# define rb_enumeratorize_with_size(obj, id, argc, argv, size_fn) \
+ rb_enumeratorize_with_size(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn))
+# define rb_enumeratorize_with_size_kw(obj, id, argc, argv, size_fn, kw_splat) \
+ rb_enumeratorize_with_size_kw(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn), kw_splat)
+#endif
+
+#define SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
+ rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \
+ (argc), (argv), (size_fn))
+
+#define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \
+ rb_enumeratorize_with_size_kw((obj), ID2SYM(rb_frame_this_func()), \
+ (argc), (argv), (size_fn), (kw_splat))
+
+#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) do { \
+ if (!rb_block_given_p()) \
+ return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \
+ } while (0)
+
+#define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) do { \
+ if (!rb_block_given_p()) \
+ return SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat); \
+ } while (0)
+
+#define RETURN_ENUMERATOR(obj, argc, argv) \
+ RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0)
+
+#define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) \
+ RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, 0, kw_splat)
+
+#endif /* RBIMPL_INTERN_ENUMERATOR_H */
diff --git a/include/ruby/internal/intern/error.h b/include/ruby/internal/intern/error.h
new file mode 100644
index 0000000000..aa9fe2daba
--- /dev/null
+++ b/include/ruby/internal/intern/error.h
@@ -0,0 +1,82 @@
+#ifndef RBIMPL_INTERN_ERROR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_ERROR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_eException.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/backward/2/assume.h"
+#include "ruby/backward/2/attributes.h"
+
+#define UNLIMITED_ARGUMENTS (-1)
+#define rb_exc_new2 rb_exc_new_cstr
+#define rb_exc_new3 rb_exc_new_str
+#define rb_check_trusted rb_check_trusted
+#define rb_check_trusted_inline rb_check_trusted
+#define rb_check_arity rb_check_arity
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* error.c */
+VALUE rb_exc_new(VALUE, const char*, long);
+VALUE rb_exc_new_cstr(VALUE, const char*);
+VALUE rb_exc_new_str(VALUE, VALUE);
+PRINTF_ARGS(NORETURN(void rb_loaderror(const char*, ...)), 1, 2);
+PRINTF_ARGS(NORETURN(void rb_loaderror_with_path(VALUE path, const char*, ...)), 2, 3);
+PRINTF_ARGS(NORETURN(void rb_name_error(ID, const char*, ...)), 2, 3);
+PRINTF_ARGS(NORETURN(void rb_name_error_str(VALUE, const char*, ...)), 2, 3);
+PRINTF_ARGS(NORETURN(void rb_frozen_error_raise(VALUE, const char*, ...)), 2, 3);
+NORETURN(void rb_invalid_str(const char*, const char*));
+NORETURN(void rb_error_frozen(const char*));
+NORETURN(void rb_error_frozen_object(VALUE));
+void rb_error_untrusted(VALUE);
+void rb_check_frozen(VALUE);
+void rb_check_trusted(VALUE);
+void rb_check_copyable(VALUE obj, VALUE orig);
+NORETURN(MJIT_STATIC void rb_error_arity(int, int, int));
+RBIMPL_SYMBOL_EXPORT_END()
+
+/* Does anyone use this? Remain not deleted for compatibility. */
+#define rb_check_frozen_internal(obj) do { \
+ VALUE frozen_obj = (obj); \
+ if (RB_UNLIKELY(RB_OBJ_FROZEN(frozen_obj))) { \
+ rb_error_frozen_object(frozen_obj); \
+ } \
+ } while (0)
+
+static inline void
+rb_check_frozen_inline(VALUE obj)
+{
+ if (RB_UNLIKELY(RB_OBJ_FROZEN(obj))) {
+ rb_error_frozen_object(obj);
+ }
+}
+#define rb_check_frozen rb_check_frozen_inline
+
+static inline int
+rb_check_arity(int argc, int min, int max)
+{
+ if ((argc < min) || (max != UNLIMITED_ARGUMENTS && argc > max))
+ rb_error_arity(argc, min, max);
+ return argc;
+}
+
+#endif /* RBIMPL_INTERN_ERROR_H */
diff --git a/include/ruby/internal/intern/eval.h b/include/ruby/internal/intern/eval.h
new file mode 100644
index 0000000000..11957053d7
--- /dev/null
+++ b/include/ruby/internal/intern/eval.h
@@ -0,0 +1,59 @@
+#ifndef RBIMPL_INTERN_EVAL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_EVAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Pre-1.9 era evaluator APIs (now considered miscellaneous).
+ */
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* eval.c */
+RBIMPL_ATTR_NORETURN()
+void rb_exc_raise(VALUE);
+
+RBIMPL_ATTR_NORETURN()
+void rb_exc_fatal(VALUE);
+
+RBIMPL_ATTR_NORETURN()
+VALUE rb_f_exit(int, const VALUE*);
+
+RBIMPL_ATTR_NORETURN()
+VALUE rb_f_abort(int, const VALUE*);
+
+RBIMPL_ATTR_NORETURN()
+void rb_interrupt(void);
+ID rb_frame_this_func(void);
+
+RBIMPL_ATTR_NORETURN()
+void rb_jump_tag(int);
+void rb_obj_call_init(VALUE, int, const VALUE*);
+void rb_obj_call_init_kw(VALUE, int, const VALUE*, int);
+VALUE rb_protect(VALUE (*)(VALUE), VALUE, int*);
+ID rb_frame_callee(void);
+VALUE rb_make_exception(int, const VALUE*);
+
+/* eval_jump.c */
+void rb_set_end_proc(void (*)(VALUE), VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_EVAL_H */
diff --git a/include/ruby/internal/intern/file.h b/include/ruby/internal/intern/file.h
new file mode 100644
index 0000000000..9ebefece66
--- /dev/null
+++ b/include/ruby/internal/intern/file.h
@@ -0,0 +1,42 @@
+#ifndef RBIMPL_INTERN_FILE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_FILE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cFile.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* file.c */
+VALUE rb_file_s_expand_path(int, const VALUE *);
+VALUE rb_file_expand_path(VALUE, VALUE);
+VALUE rb_file_s_absolute_path(int, const VALUE *);
+VALUE rb_file_absolute_path(VALUE, VALUE);
+VALUE rb_file_dirname(VALUE fname);
+int rb_find_file_ext(VALUE*, const char* const*);
+VALUE rb_find_file(VALUE);
+VALUE rb_file_directory_p(VALUE,VALUE);
+VALUE rb_str_encode_ospath(VALUE);
+int rb_is_absolute_path(const char *);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_FILE_H */
diff --git a/include/ruby/internal/intern/gc.h b/include/ruby/internal/intern/gc.h
new file mode 100644
index 0000000000..30759e0ded
--- /dev/null
+++ b/include/ruby/internal/intern/gc.h
@@ -0,0 +1,57 @@
+#ifndef RBIMPL_INTERN_GC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_GC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_mGC.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/backward/2/attributes.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* gc.c */
+COLDFUNC NORETURN(void rb_memerror(void));
+PUREFUNC(int rb_during_gc(void));
+void rb_gc_mark_locations(const VALUE*, const VALUE*);
+void rb_mark_tbl(struct st_table*);
+void rb_mark_tbl_no_pin(struct st_table*);
+void rb_mark_set(struct st_table*);
+void rb_mark_hash(struct st_table*);
+void rb_gc_update_tbl_refs(st_table *ptr);
+void rb_gc_mark_maybe(VALUE);
+void rb_gc_mark(VALUE);
+void rb_gc_mark_movable(VALUE);
+VALUE rb_gc_location(VALUE);
+void rb_gc_force_recycle(VALUE);
+void rb_gc(void);
+void rb_gc_copy_finalizer(VALUE,VALUE);
+VALUE rb_gc_enable(void);
+VALUE rb_gc_disable(void);
+VALUE rb_gc_start(void);
+VALUE rb_define_finalizer(VALUE, VALUE);
+VALUE rb_undefine_finalizer(VALUE);
+size_t rb_gc_count(void);
+size_t rb_gc_stat(VALUE);
+VALUE rb_gc_latest_gc_info(VALUE);
+void rb_gc_adjust_memory_usage(ssize_t);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_GC_H */
diff --git a/include/ruby/internal/intern/hash.h b/include/ruby/internal/intern/hash.h
new file mode 100644
index 0000000000..c7a27c2cfa
--- /dev/null
+++ b/include/ruby/internal/intern/hash.h
@@ -0,0 +1,59 @@
+#ifndef RBIMPL_INTERN_HASH_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_HASH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cHash.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/st.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* hash.c */
+void rb_st_foreach_safe(struct st_table *, int (*)(st_data_t, st_data_t, st_data_t), st_data_t);
+#define st_foreach_safe rb_st_foreach_safe
+VALUE rb_check_hash_type(VALUE);
+void rb_hash_foreach(VALUE, int (*)(VALUE, VALUE, VALUE), VALUE);
+VALUE rb_hash(VALUE);
+VALUE rb_hash_new(void);
+VALUE rb_hash_dup(VALUE);
+VALUE rb_hash_freeze(VALUE);
+VALUE rb_hash_aref(VALUE, VALUE);
+VALUE rb_hash_lookup(VALUE, VALUE);
+VALUE rb_hash_lookup2(VALUE, VALUE, VALUE);
+VALUE rb_hash_fetch(VALUE, VALUE);
+VALUE rb_hash_aset(VALUE, VALUE, VALUE);
+VALUE rb_hash_clear(VALUE);
+VALUE rb_hash_delete_if(VALUE);
+VALUE rb_hash_delete(VALUE,VALUE);
+VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
+void rb_hash_bulk_insert(long, const VALUE *, VALUE);
+typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value);
+VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func);
+struct st_table *rb_hash_tbl(VALUE, const char *file, int line);
+int rb_path_check(const char*);
+int rb_env_path_tainted(void);
+VALUE rb_env_clear(void);
+VALUE rb_hash_size(VALUE);
+void rb_hash_free(VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_HASH_H */
diff --git a/include/ruby/internal/intern/io.h b/include/ruby/internal/intern/io.h
new file mode 100644
index 0000000000..d2f2e53486
--- /dev/null
+++ b/include/ruby/internal/intern/io.h
@@ -0,0 +1,70 @@
+#ifndef RBIMPL_INTERN_IO_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_IO_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cIO.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* io.c */
+#define rb_defout rb_stdout
+RUBY_EXTERN VALUE rb_fs;
+RUBY_EXTERN VALUE rb_output_fs;
+RUBY_EXTERN VALUE rb_rs;
+RUBY_EXTERN VALUE rb_default_rs;
+RUBY_EXTERN VALUE rb_output_rs;
+VALUE rb_io_write(VALUE, VALUE);
+VALUE rb_io_gets(VALUE);
+VALUE rb_io_getbyte(VALUE);
+VALUE rb_io_ungetc(VALUE, VALUE);
+VALUE rb_io_ungetbyte(VALUE, VALUE);
+VALUE rb_io_close(VALUE);
+VALUE rb_io_flush(VALUE);
+VALUE rb_io_eof(VALUE);
+VALUE rb_io_binmode(VALUE);
+VALUE rb_io_ascii8bit_binmode(VALUE);
+VALUE rb_io_addstr(VALUE, VALUE);
+VALUE rb_io_printf(int, const VALUE*, VALUE);
+VALUE rb_io_print(int, const VALUE*, VALUE);
+VALUE rb_io_puts(int, const VALUE*, VALUE);
+VALUE rb_io_fdopen(int, int, const char*);
+VALUE rb_io_get_io(VALUE);
+VALUE rb_file_open(const char*, const char*);
+VALUE rb_file_open_str(VALUE, const char*);
+VALUE rb_gets(void);
+void rb_write_error(const char*);
+void rb_write_error2(const char*, long);
+void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds);
+int rb_pipe(int *pipes);
+int rb_reserved_fd_p(int fd);
+int rb_cloexec_open(const char *pathname, int flags, mode_t mode);
+int rb_cloexec_dup(int oldfd);
+int rb_cloexec_dup2(int oldfd, int newfd);
+int rb_cloexec_pipe(int fildes[2]);
+int rb_cloexec_fcntl_dupfd(int fd, int minfd);
+#define RB_RESERVED_FD_P(fd) rb_reserved_fd_p(fd)
+void rb_update_max_fd(int fd);
+void rb_fd_fix_cloexec(int fd);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_IO_H */
diff --git a/include/ruby/internal/intern/load.h b/include/ruby/internal/intern/load.h
new file mode 100644
index 0000000000..2cc5be0ebe
--- /dev/null
+++ b/include/ruby/internal/intern/load.h
@@ -0,0 +1,44 @@
+#ifndef RBIMPL_INTERN_LOAD_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_LOAD_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_f_require().
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* load.c */
+void rb_load(VALUE, int);
+void rb_load_protect(VALUE, int, int*);
+int rb_provided(const char*);
+int rb_feature_provided(const char *, const char **);
+void rb_provide(const char*);
+VALUE rb_f_require(VALUE, VALUE);
+VALUE rb_require_string(VALUE);
+
+// extension configuration
+void rb_ext_ractor_safe(bool flag);
+#define RB_EXT_RACTOR_SAFE(f) rb_ext_ractor_safe(f)
+#define HAVE_RB_EXT_RACTOR_SAFE 1
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_LOAD_H */
diff --git a/include/ruby/internal/intern/marshal.h b/include/ruby/internal/intern/marshal.h
new file mode 100644
index 0000000000..6b0243244e
--- /dev/null
+++ b/include/ruby/internal/intern/marshal.h
@@ -0,0 +1,35 @@
+#ifndef RBIMPL_INTERN_MARSHAL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_MARSHAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to rb_mMarshal.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* marshal.c */
+VALUE rb_marshal_dump(VALUE, VALUE);
+VALUE rb_marshal_load(VALUE);
+void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE));
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_MARSHAL_H */
diff --git a/include/ruby/internal/intern/numeric.h b/include/ruby/internal/intern/numeric.h
new file mode 100644
index 0000000000..effc583756
--- /dev/null
+++ b/include/ruby/internal/intern/numeric.h
@@ -0,0 +1,42 @@
+#ifndef RBIMPL_INTERN_NUMERIC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_NUMERIC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cNumeric.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/backward/2/attributes.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* numeric.c */
+NORETURN(void rb_num_zerodiv(void));
+#define RB_NUM_COERCE_FUNCS_NEED_OPID 1
+VALUE rb_num_coerce_bin(VALUE, VALUE, ID);
+VALUE rb_num_coerce_cmp(VALUE, VALUE, ID);
+VALUE rb_num_coerce_relop(VALUE, VALUE, ID);
+VALUE rb_num_coerce_bit(VALUE, VALUE, ID);
+VALUE rb_num2fix(VALUE);
+VALUE rb_fix2str(VALUE, int);
+CONSTFUNC(VALUE rb_dbl_cmp(double, double));
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_NUMERIC_H */
diff --git a/include/ruby/internal/intern/object.h b/include/ruby/internal/intern/object.h
new file mode 100644
index 0000000000..d55178584b
--- /dev/null
+++ b/include/ruby/internal/intern/object.h
@@ -0,0 +1,90 @@
+#ifndef RBIMPL_INTERN_OBJECT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_OBJECT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cObject.
+ */
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+#define RB_OBJ_INIT_COPY(obj, orig) \
+ ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
+#define OBJ_INIT_COPY(obj, orig) RB_OBJ_INIT_COPY(obj, orig)
+
+VALUE rb_class_new_instance_pass_kw(int, const VALUE *, VALUE);
+VALUE rb_class_new_instance(int, const VALUE*, VALUE);
+VALUE rb_class_new_instance_kw(int, const VALUE*, VALUE, int);
+
+/* object.c */
+int rb_eql(VALUE, VALUE);
+VALUE rb_any_to_s(VALUE);
+VALUE rb_inspect(VALUE);
+VALUE rb_obj_is_instance_of(VALUE, VALUE);
+VALUE rb_obj_is_kind_of(VALUE, VALUE);
+VALUE rb_obj_alloc(VALUE);
+VALUE rb_obj_clone(VALUE);
+VALUE rb_obj_dup(VALUE);
+VALUE rb_obj_init_copy(VALUE,VALUE);
+VALUE rb_obj_taint(VALUE);
+
+RBIMPL_ATTR_PURE()
+VALUE rb_obj_tainted(VALUE);
+VALUE rb_obj_untaint(VALUE);
+VALUE rb_obj_untrust(VALUE);
+
+RBIMPL_ATTR_PURE()
+VALUE rb_obj_untrusted(VALUE);
+VALUE rb_obj_trust(VALUE);
+VALUE rb_obj_freeze(VALUE);
+
+RBIMPL_ATTR_PURE()
+VALUE rb_obj_frozen_p(VALUE);
+
+VALUE rb_obj_id(VALUE);
+VALUE rb_memory_id(VALUE);
+VALUE rb_obj_class(VALUE);
+
+RBIMPL_ATTR_PURE()
+VALUE rb_class_real(VALUE);
+
+RBIMPL_ATTR_PURE()
+VALUE rb_class_inherited_p(VALUE, VALUE);
+VALUE rb_class_superclass(VALUE);
+VALUE rb_class_get_superclass(VALUE);
+VALUE rb_convert_type(VALUE,int,const char*,const char*);
+VALUE rb_check_convert_type(VALUE,int,const char*,const char*);
+VALUE rb_check_to_integer(VALUE, const char *);
+VALUE rb_check_to_float(VALUE);
+VALUE rb_to_int(VALUE);
+VALUE rb_check_to_int(VALUE);
+VALUE rb_Integer(VALUE);
+VALUE rb_to_float(VALUE);
+VALUE rb_Float(VALUE);
+VALUE rb_String(VALUE);
+VALUE rb_Array(VALUE);
+VALUE rb_Hash(VALUE);
+double rb_cstr_to_dbl(const char*, int);
+double rb_str_to_dbl(VALUE, int);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_OBJECT_H */
diff --git a/include/ruby/internal/intern/parse.h b/include/ruby/internal/intern/parse.h
new file mode 100644
index 0000000000..4a5b8cb147
--- /dev/null
+++ b/include/ruby/internal/intern/parse.h
@@ -0,0 +1,64 @@
+#ifndef RBIMPL_INTERN_PARSE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_PARSE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cSymbol.
+ */
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* parse.y */
+ID rb_id_attrset(ID);
+
+RBIMPL_ATTR_CONST()
+int rb_is_const_id(ID);
+
+RBIMPL_ATTR_CONST()
+int rb_is_global_id(ID);
+
+RBIMPL_ATTR_CONST()
+int rb_is_instance_id(ID);
+
+RBIMPL_ATTR_CONST()
+int rb_is_attrset_id(ID);
+
+RBIMPL_ATTR_CONST()
+int rb_is_class_id(ID);
+
+RBIMPL_ATTR_CONST()
+int rb_is_local_id(ID);
+
+RBIMPL_ATTR_CONST()
+int rb_is_junk_id(ID);
+int rb_symname_p(const char*);
+int rb_sym_interned_p(VALUE);
+VALUE rb_backref_get(void);
+void rb_backref_set(VALUE);
+VALUE rb_lastline_get(void);
+void rb_lastline_set(VALUE);
+
+/* symbol.c */
+VALUE rb_sym_all_symbols(void);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_PARSE_H */
diff --git a/include/ruby/internal/intern/proc.h b/include/ruby/internal/intern/proc.h
new file mode 100644
index 0000000000..d6f77cbd4d
--- /dev/null
+++ b/include/ruby/internal/intern/proc.h
@@ -0,0 +1,53 @@
+#ifndef RBIMPL_INTERN_PROC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_PROC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cProc.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/iterator.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* proc.c */
+VALUE rb_block_proc(void);
+VALUE rb_block_lambda(void);
+VALUE rb_proc_new(rb_block_call_func_t, VALUE);
+VALUE rb_obj_is_proc(VALUE);
+VALUE rb_proc_call(VALUE, VALUE);
+VALUE rb_proc_call_kw(VALUE, VALUE, int);
+VALUE rb_proc_call_with_block(VALUE, int argc, const VALUE *argv, VALUE);
+VALUE rb_proc_call_with_block_kw(VALUE, int argc, const VALUE *argv, VALUE, int);
+int rb_proc_arity(VALUE);
+VALUE rb_proc_lambda_p(VALUE);
+VALUE rb_binding_new(void);
+VALUE rb_obj_method(VALUE, VALUE);
+VALUE rb_obj_is_method(VALUE);
+VALUE rb_method_call(int, const VALUE*, VALUE);
+VALUE rb_method_call_kw(int, const VALUE*, VALUE, int);
+VALUE rb_method_call_with_block(int, const VALUE *, VALUE, VALUE);
+VALUE rb_method_call_with_block_kw(int, const VALUE *, VALUE, VALUE, int);
+int rb_mod_method_arity(VALUE, ID);
+int rb_obj_method_arity(VALUE, ID);
+VALUE rb_protect(VALUE (*)(VALUE), VALUE, int*);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_PROC_H */
diff --git a/include/ruby/internal/intern/process.h b/include/ruby/internal/intern/process.h
new file mode 100644
index 0000000000..2b1005a205
--- /dev/null
+++ b/include/ruby/internal/intern/process.h
@@ -0,0 +1,46 @@
+#ifndef RBIMPL_INTERN_PROCESS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_PROCESS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_mProcess.
+ */
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/config.h" /* rb_pid_t is defined here. */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* process.c */
+void rb_last_status_set(int status, rb_pid_t pid);
+VALUE rb_last_status_get(void);
+int rb_proc_exec(const char*);
+
+RBIMPL_ATTR_NORETURN()
+VALUE rb_f_exec(int, const VALUE*);
+rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags);
+void rb_syswait(rb_pid_t pid);
+rb_pid_t rb_spawn(int, const VALUE*);
+rb_pid_t rb_spawn_err(int, const VALUE*, char*, size_t);
+VALUE rb_proc_times(VALUE);
+VALUE rb_detach_process(rb_pid_t pid);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_PROCESS_H */
diff --git a/include/ruby/internal/intern/random.h b/include/ruby/internal/intern/random.h
new file mode 100644
index 0000000000..25c52f4ce4
--- /dev/null
+++ b/include/ruby/internal/intern/random.h
@@ -0,0 +1,45 @@
+#ifndef RBIMPL_INTERN_RANDOM_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_RANDOM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief MT19937 backended pseudo random number generator.
+ * @see Matsumoto, M., Nishimura, T., "Mersenne Twister: A 623-
+ * dimensionally equidistributed uniform pseudorandom number
+ * generator", ACM Trans. on Modeling and Computer Simulation, 8
+ * (1): pp 3-30, 1998. https://doi.org/10.1145/272991.272995
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* random.c */
+unsigned int rb_genrand_int32(void);
+double rb_genrand_real(void);
+void rb_reset_random_seed(void);
+VALUE rb_random_bytes(VALUE rnd, long n);
+VALUE rb_random_int(VALUE rnd, VALUE max);
+unsigned int rb_random_int32(VALUE rnd);
+double rb_random_real(VALUE rnd);
+unsigned long rb_random_ulong_limited(VALUE rnd, unsigned long limit);
+unsigned long rb_genrand_ulong_limited(unsigned long i);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_RANDOM_H */
diff --git a/include/ruby/internal/intern/range.h b/include/ruby/internal/intern/range.h
new file mode 100644
index 0000000000..7ca47915e2
--- /dev/null
+++ b/include/ruby/internal/intern/range.h
@@ -0,0 +1,35 @@
+#ifndef RBIMPL_INTERN_RANGE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_RANGE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cRange.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* range.c */
+VALUE rb_range_new(VALUE, VALUE, int);
+VALUE rb_range_beg_len(VALUE, long*, long*, long, int);
+int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_RANGE_H */
diff --git a/include/ruby/internal/intern/rational.h b/include/ruby/internal/intern/rational.h
new file mode 100644
index 0000000000..30a87ff31f
--- /dev/null
+++ b/include/ruby/internal/intern/rational.h
@@ -0,0 +1,46 @@
+#ifndef RBIMPL_INTERN_RATIONAL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_RATIONAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cRational.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here. */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* rational.c */
+VALUE rb_rational_raw(VALUE, VALUE);
+#define rb_rational_raw1(x) rb_rational_raw((x), INT2FIX(1))
+#define rb_rational_raw2(x,y) rb_rational_raw((x), (y))
+VALUE rb_rational_new(VALUE, VALUE);
+#define rb_rational_new1(x) rb_rational_new((x), INT2FIX(1))
+#define rb_rational_new2(x,y) rb_rational_new((x), (y))
+VALUE rb_Rational(VALUE, VALUE);
+#define rb_Rational1(x) rb_Rational((x), INT2FIX(1))
+#define rb_Rational2(x,y) rb_Rational((x), (y))
+VALUE rb_rational_num(VALUE rat);
+VALUE rb_rational_den(VALUE rat);
+VALUE rb_flt_rationalize_with_prec(VALUE, VALUE);
+VALUE rb_flt_rationalize(VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_RATIONAL_H */
diff --git a/include/ruby/internal/intern/re.h b/include/ruby/internal/intern/re.h
new file mode 100644
index 0000000000..dd7baef954
--- /dev/null
+++ b/include/ruby/internal/intern/re.h
@@ -0,0 +1,50 @@
+#ifndef RBIMPL_INTERN_RE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_RE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cRegexp.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* re.c */
+#define rb_memcmp memcmp
+int rb_memcicmp(const void*,const void*,long);
+void rb_match_busy(VALUE);
+VALUE rb_reg_nth_defined(int, VALUE);
+VALUE rb_reg_nth_match(int, VALUE);
+int rb_reg_backref_number(VALUE match, VALUE backref);
+VALUE rb_reg_last_match(VALUE);
+VALUE rb_reg_match_pre(VALUE);
+VALUE rb_reg_match_post(VALUE);
+VALUE rb_reg_match_last(VALUE);
+#define HAVE_RB_REG_NEW_STR 1
+VALUE rb_reg_new_str(VALUE, int);
+VALUE rb_reg_new(const char *, long, int);
+VALUE rb_reg_alloc(void);
+VALUE rb_reg_init_str(VALUE re, VALUE s, int options);
+VALUE rb_reg_match(VALUE, VALUE);
+VALUE rb_reg_match2(VALUE);
+int rb_reg_options(VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_RE_H */
diff --git a/include/ruby/internal/intern/ruby.h b/include/ruby/internal/intern/ruby.h
new file mode 100644
index 0000000000..9d9a71cf7a
--- /dev/null
+++ b/include/ruby/internal/intern/ruby.h
@@ -0,0 +1,37 @@
+#ifndef RBIMPL_INTERN_RUBY_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_RUBY_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Process-global APIs.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* ruby.c */
+#define rb_argv rb_get_argv()
+RUBY_EXTERN VALUE rb_argv0;
+VALUE rb_get_argv(void);
+void *rb_load_file(const char*);
+void *rb_load_file_str(VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_RUBY_H */
diff --git a/include/ruby/internal/intern/select.h b/include/ruby/internal/intern/select.h
new file mode 100644
index 0000000000..43d4cf354c
--- /dev/null
+++ b/include/ruby/internal/intern/select.h
@@ -0,0 +1,52 @@
+#ifndef RBIMPL_INTERN_SELECT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_SELECT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs to provide ::rb_fd_select().
+ * @note Functions and structs defined in this header file are not
+ * necessarily ruby-specific. They don't need ::VALUE etc.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h> /* for NFDBITS (BSD Net/2) */
+#endif
+
+#include "ruby/internal/dllexport.h"
+
+/* thread.c */
+#if defined(NFDBITS) && defined(HAVE_RB_FD_INIT)
+# include "ruby/internal/intern/select/largesize.h"
+#elif defined(_WIN32)
+# include "ruby/internal/intern/select/win32.h"
+# define rb_fd_resize(n, f) ((void)(f))
+#else
+# include "ruby/internal/intern/select/posix.h"
+# define rb_fd_resize(n, f) ((void)(f))
+#endif
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+struct timeval;
+
+int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_SELECT_H */
diff --git a/include/ruby/internal/intern/select/largesize.h b/include/ruby/internal/intern/select/largesize.h
new file mode 100644
index 0000000000..ba56a159b1
--- /dev/null
+++ b/include/ruby/internal/intern/select/largesize.h
@@ -0,0 +1,103 @@
+#ifndef RBIMPL_INTERN_SELECT_LARGESIZE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_SELECT_LARGESIZE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs to provide ::rb_fd_select().
+ *
+ * Several Unix platforms support file descriptors bigger than FD_SETSIZE in
+ * `select(2)` system call.
+ *
+ * - Linux 2.2.12 (?)
+ *
+ * - NetBSD 1.2 (src/sys/kern/sys_generic.c:1.25)
+ * `select(2)` documents how to allocate fd_set dynamically.
+ * http://netbsd.gw.com/cgi-bin/man-cgi?select++NetBSD-4.0
+ *
+ * - FreeBSD 2.2 (src/sys/kern/sys_generic.c:1.19)
+ *
+ * - OpenBSD 2.0 (src/sys/kern/sys_generic.c:1.4)
+ * `select(2)` documents how to allocate fd_set dynamically.
+ * http://www.openbsd.org/cgi-bin/man.cgi?query=select&manpath=OpenBSD+4.4
+ *
+ * - HP-UX documents how to allocate fd_set dynamically.
+ * http://docs.hp.com/en/B2355-60105/select.2.html
+ *
+ * - Solaris 8 has `select_large_fdset`
+ *
+ * - Mac OS X 10.7 (Lion)
+ * `select(2)` returns `EINVAL` if `nfds` is greater than `FD_SET_SIZE` and
+ * `_DARWIN_UNLIMITED_SELECT` (or `_DARWIN_C_SOURCE`) isn't defined.
+ * http://developer.apple.com/library/mac/#releasenotes/Darwin/SymbolVariantsRelNotes/_index.html
+ *
+ * When `fd_set` is not big enough to hold big file descriptors, it should be
+ * allocated dynamically. Note that this assumes `fd_set` is structured as
+ * bitmap.
+ *
+ * `rb_fd_init` allocates the memory.
+ * `rb_fd_term` frees the memory.
+ * `rb_fd_set` may re-allocate bitmap.
+ *
+ * So `rb_fd_set` doesn't reject file descriptors bigger than `FD_SETSIZE`.
+ */
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/dllexport.h"
+
+/**@cond INTERNAL_MACRO */
+#define rb_fd_ptr rb_fd_ptr
+#define rb_fd_max rb_fd_max
+/** @endcond */
+
+struct timeval;
+
+typedef struct {
+ int maxfd;
+ fd_set *fdset;
+} rb_fdset_t;
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+void rb_fd_init(rb_fdset_t *);
+void rb_fd_term(rb_fdset_t *);
+void rb_fd_zero(rb_fdset_t *);
+void rb_fd_set(int, rb_fdset_t *);
+void rb_fd_clr(int, rb_fdset_t *);
+int rb_fd_isset(int, const rb_fdset_t *);
+void rb_fd_copy(rb_fdset_t *, const fd_set *, int);
+void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);
+int rb_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *);
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_NONNULL(())
+RBIMPL_ATTR_PURE()
+/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
+static inline fd_set *
+rb_fd_ptr(const rb_fdset_t *f)
+{
+ return f->fdset;
+}
+
+RBIMPL_ATTR_NONNULL(())
+RBIMPL_ATTR_PURE()
+static inline int
+rb_fd_max(const rb_fdset_t *f)
+{
+ return f->maxfd;
+}
+
+#endif /* RBIMPL_INTERN_SELECT_LARGESIZE_H */
diff --git a/include/ruby/internal/intern/select/posix.h b/include/ruby/internal/intern/select/posix.h
new file mode 100644
index 0000000000..0bf68ae204
--- /dev/null
+++ b/include/ruby/internal/intern/select/posix.h
@@ -0,0 +1,82 @@
+#ifndef RBIMPL_INTERN_SELECT_POSIX_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_SELECT_POSIX_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs to provide ::rb_fd_select().
+ */
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h> /* for select(2) (modern POSIX) */
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h> /* for select(2) (archaic UNIX) */
+#endif
+
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/attr/const.h"
+
+typedef fd_set rb_fdset_t;
+
+#define rb_fd_zero FD_ZERO
+#define rb_fd_set FD_SET
+#define rb_fd_clr FD_CLR
+#define rb_fd_isset FD_ISSET
+#define rb_fd_init FD_ZERO
+#define rb_fd_select select
+/**@cond INTERNAL_MACRO */
+#define rb_fd_copy rb_fd_copy
+#define rb_fd_dup rb_fd_dup
+#define rb_fd_ptr rb_fd_ptr
+#define rb_fd_max rb_fd_max
+/** @endcond */
+
+static inline void
+rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int n)
+{
+ *dst = *src;
+}
+
+static inline void
+rb_fd_dup(rb_fdset_t *dst, const fd_set *src)
+{
+ *dst = *src;
+}
+
+RBIMPL_ATTR_PURE()
+/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
+static inline fd_set *
+rb_fd_ptr(rb_fdset_t *f)
+{
+ return f;
+}
+
+RBIMPL_ATTR_CONST()
+static inline int
+rb_fd_max(const rb_fdset_t *f)
+{
+ return FD_SETSIZE;
+}
+
+/* :FIXME: What are these? They don't exist for shibling implementations. */
+#define rb_fd_init_copy(d, s) (*(d) = *(s))
+#define rb_fd_term(f) ((void)(f))
+
+#endif /* RBIMPL_INTERN_SELECT_POSIX_H */
diff --git a/include/ruby/internal/intern/select/win32.h b/include/ruby/internal/intern/select/win32.h
new file mode 100644
index 0000000000..ef75a0f760
--- /dev/null
+++ b/include/ruby/internal/intern/select/win32.h
@@ -0,0 +1,124 @@
+#ifndef RBIMPL_INTERN_SELECT_WIN32_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_SELECT_WIN32_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs to provide ::rb_fd_select().
+ */
+#include "ruby/internal/dosish.h" /* for rb_w32_select */
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/attr/noalias.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/assert.h"
+
+/**@cond INTERNAL_MACRO */
+#define rb_fd_zero rb_fd_zero
+#define rb_fd_clr rb_fd_clr
+#define rb_fd_isset rb_fd_isset
+#define rb_fd_copy rb_fd_copy
+#define rb_fd_dup rb_fd_dup
+#define rb_fd_ptr rb_fd_ptr
+#define rb_fd_max rb_fd_max
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+struct timeval;
+
+typedef struct {
+ int capa;
+ fd_set *fdset;
+} rb_fdset_t;
+
+void rb_fd_init(rb_fdset_t *);
+void rb_fd_term(rb_fdset_t *);
+void rb_fd_set(int, rb_fdset_t *);
+void rb_w32_fd_copy(rb_fdset_t *, const fd_set *, int);
+void rb_w32_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_NONNULL(())
+RBIMPL_ATTR_NOALIAS()
+static inline void
+rb_fd_zero(rb_fdset_t *f)
+{
+ f->fdset->fd_count = 0;
+}
+
+RBIMPL_ATTR_NONNULL(())
+static inline void
+rb_fd_clr(int n, rb_fdset_t *f)
+{
+ rb_w32_fdclr(n, f->fdset);
+}
+
+RBIMPL_ATTR_NONNULL(())
+static inline int
+rb_fd_isset(int n, rb_fdset_t *f)
+{
+ return rb_w32_fdisset(n, f->fdset);
+}
+
+RBIMPL_ATTR_NONNULL(())
+static inline void
+rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int n)
+{
+ rb_w32_fd_copy(dst, src, n);
+}
+
+RBIMPL_ATTR_NONNULL(())
+static inline void
+rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src)
+{
+ rb_w32_fd_dup(dst, src);
+}
+
+static inline int
+rb_fd_select(int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout)
+{
+ return rb_w32_select(
+ n,
+ rfds ? rfds->fdset : NULL,
+ wfds ? wfds->fdset : NULL,
+ efds ? efds->fdset : NULL,
+ timeout);
+}
+
+RBIMPL_ATTR_NONNULL(())
+RBIMPL_ATTR_PURE()
+/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
+static inline fd_set *
+rb_fd_ptr(const rb_fdset_t *f)
+{
+ return f->fdset;
+}
+
+RBIMPL_ATTR_NONNULL(())
+RBIMPL_ATTR_PURE()
+static inline int
+rb_fd_max(const rb_fdset_t *f)
+{
+ const fd_set *p = f->fdset;
+
+ RBIMPL_ASSERT_OR_ASSUME(p);
+ return p->fd_count;
+}
+
+#endif /* RBIMPL_INTERN_SELECT_WIN32_H */
diff --git a/include/ruby/internal/intern/signal.h b/include/ruby/internal/intern/signal.h
new file mode 100644
index 0000000000..8739c51f53
--- /dev/null
+++ b/include/ruby/internal/intern/signal.h
@@ -0,0 +1,39 @@
+#ifndef RBIMPL_INTERN_SIGNAL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_SIGNAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Signal handling APIs.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* signal.c */
+VALUE rb_f_kill(int, const VALUE*);
+#ifdef POSIX_SIGNAL
+#define posix_signal ruby_posix_signal
+void (*posix_signal(int, void (*)(int)))(int);
+#endif
+const char *ruby_signal_name(int);
+void ruby_default_signal(int);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_SIGNAL_H */
diff --git a/include/ruby/internal/intern/sprintf.h b/include/ruby/internal/intern/sprintf.h
new file mode 100644
index 0000000000..2c90548353
--- /dev/null
+++ b/include/ruby/internal/intern/sprintf.h
@@ -0,0 +1,43 @@
+#ifndef RBIMPL_INTERN_SPRINTF_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_SPRINTF_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Our own private printf(3).
+ */
+#include "ruby/internal/attr/format.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* sprintf.c */
+VALUE rb_f_sprintf(int, const VALUE*);
+
+RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
+VALUE rb_sprintf(const char*, ...);
+VALUE rb_vsprintf(const char*, va_list);
+
+RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
+VALUE rb_str_catf(VALUE, const char*, ...);
+VALUE rb_str_vcatf(VALUE, const char*, va_list);
+VALUE rb_str_format(int, const VALUE *, VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_SPRINTF_H */
diff --git a/include/ruby/internal/intern/string.h b/include/ruby/internal/intern/string.h
new file mode 100644
index 0000000000..a590b2043e
--- /dev/null
+++ b/include/ruby/internal/intern/string.h
@@ -0,0 +1,298 @@
+#ifndef RBIMPL_INTERN_STRING_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_STRING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cString.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/constant_p.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/variable.h" /* rb_gvar_setter_t */
+#include "ruby/st.h" /* st_index_t */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* string.c */
+VALUE rb_str_new(const char*, long);
+VALUE rb_str_new_cstr(const char*);
+VALUE rb_str_new_shared(VALUE);
+VALUE rb_str_new_frozen(VALUE);
+VALUE rb_str_new_with_class(VALUE, const char*, long);
+VALUE rb_tainted_str_new_cstr(const char*);
+VALUE rb_tainted_str_new(const char*, long);
+VALUE rb_external_str_new(const char*, long);
+VALUE rb_external_str_new_cstr(const char*);
+VALUE rb_locale_str_new(const char*, long);
+VALUE rb_locale_str_new_cstr(const char*);
+VALUE rb_filesystem_str_new(const char*, long);
+VALUE rb_filesystem_str_new_cstr(const char*);
+VALUE rb_str_buf_new(long);
+VALUE rb_str_buf_new_cstr(const char*);
+VALUE rb_str_buf_new2(const char*);
+VALUE rb_str_tmp_new(long);
+VALUE rb_usascii_str_new(const char*, long);
+VALUE rb_usascii_str_new_cstr(const char*);
+VALUE rb_utf8_str_new(const char*, long);
+VALUE rb_utf8_str_new_cstr(const char*);
+/**
+ * *_str_new_static functions are intended for C string literals.
+ * They require memory in the range [ptr, ptr+len] to always be readable.
+ * Note that this range covers a total of len + 1 bytes.
+ */
+VALUE rb_str_new_static(const char *ptr, long len);
+VALUE rb_usascii_str_new_static(const char *ptr, long len);
+VALUE rb_utf8_str_new_static(const char *ptr, long len);
+VALUE rb_str_to_interned_str(VALUE);
+VALUE rb_interned_str(const char *, long);
+VALUE rb_interned_str_cstr(const char *);
+void rb_str_free(VALUE);
+void rb_str_shared_replace(VALUE, VALUE);
+VALUE rb_str_buf_append(VALUE, VALUE);
+VALUE rb_str_buf_cat(VALUE, const char*, long);
+VALUE rb_str_buf_cat2(VALUE, const char*);
+VALUE rb_str_buf_cat_ascii(VALUE, const char*);
+VALUE rb_obj_as_string(VALUE);
+VALUE rb_check_string_type(VALUE);
+void rb_must_asciicompat(VALUE);
+VALUE rb_str_dup(VALUE);
+VALUE rb_str_resurrect(VALUE str);
+VALUE rb_str_locktmp(VALUE);
+VALUE rb_str_unlocktmp(VALUE);
+VALUE rb_str_dup_frozen(VALUE);
+#define rb_str_dup_frozen rb_str_new_frozen
+VALUE rb_str_plus(VALUE, VALUE);
+VALUE rb_str_times(VALUE, VALUE);
+long rb_str_sublen(VALUE, long);
+VALUE rb_str_substr(VALUE, long, long);
+VALUE rb_str_subseq(VALUE, long, long);
+char *rb_str_subpos(VALUE, long, long*);
+void rb_str_modify(VALUE);
+void rb_str_modify_expand(VALUE, long);
+VALUE rb_str_freeze(VALUE);
+void rb_str_set_len(VALUE, long);
+VALUE rb_str_resize(VALUE, long);
+VALUE rb_str_cat(VALUE, const char*, long);
+VALUE rb_str_cat_cstr(VALUE, const char*);
+VALUE rb_str_cat2(VALUE, const char*);
+VALUE rb_str_append(VALUE, VALUE);
+VALUE rb_str_concat(VALUE, VALUE);
+st_index_t rb_memhash(const void *ptr, long len);
+st_index_t rb_hash_start(st_index_t);
+st_index_t rb_hash_uint32(st_index_t, uint32_t);
+st_index_t rb_hash_uint(st_index_t, st_index_t);
+st_index_t rb_hash_end(st_index_t);
+#define rb_hash_uint32(h, i) st_hash_uint32((h), (i))
+#define rb_hash_uint(h, i) st_hash_uint((h), (i))
+#define rb_hash_end(h) st_hash_end(h)
+st_index_t rb_str_hash(VALUE);
+int rb_str_hash_cmp(VALUE,VALUE);
+int rb_str_comparable(VALUE, VALUE);
+int rb_str_cmp(VALUE, VALUE);
+VALUE rb_str_equal(VALUE str1, VALUE str2);
+VALUE rb_str_drop_bytes(VALUE, long);
+void rb_str_update(VALUE, long, long, VALUE);
+VALUE rb_str_replace(VALUE, VALUE);
+VALUE rb_str_inspect(VALUE);
+VALUE rb_str_dump(VALUE);
+VALUE rb_str_split(VALUE, const char*);
+rb_gvar_setter_t rb_str_setter;
+VALUE rb_str_intern(VALUE);
+VALUE rb_sym_to_s(VALUE);
+long rb_str_strlen(VALUE);
+VALUE rb_str_length(VALUE);
+long rb_str_offset(VALUE, long);
+RBIMPL_ATTR_PURE()
+size_t rb_str_capacity(VALUE);
+VALUE rb_str_ellipsize(VALUE, long);
+VALUE rb_str_scrub(VALUE, VALUE);
+VALUE rb_str_succ(VALUE);
+
+RBIMPL_ATTR_NONNULL(())
+static inline long
+rbimpl_strlen(const char *str)
+{
+ return RBIMPL_CAST((long)strlen(str));
+}
+
+static inline VALUE
+rbimpl_str_new_cstr(const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_str_new_static(str, len);
+}
+
+static inline VALUE
+rbimpl_tainted_str_new_cstr(const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_tainted_str_new(str, len);
+}
+
+static inline VALUE
+rbimpl_usascii_str_new_cstr(const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_usascii_str_new_static(str, len);
+}
+
+static inline VALUE
+rbimpl_utf8_str_new_cstr(const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_utf8_str_new_static(str, len);
+}
+
+static inline VALUE
+rbimpl_external_str_new_cstr(const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_external_str_new(str, len);
+}
+
+static inline VALUE
+rbimpl_locale_str_new_cstr(const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_locale_str_new(str, len);
+}
+
+static inline VALUE
+rbimpl_str_buf_new_cstr(const char *str)
+{
+ long len = rbimpl_strlen(str);
+ VALUE buf = rb_str_buf_new(len);
+ return rb_str_buf_cat(buf, str, len);
+}
+
+static inline VALUE
+rbimpl_str_cat_cstr(VALUE buf, const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_str_cat(buf, str, len);
+}
+
+static inline VALUE
+rbimpl_exc_new_cstr(VALUE exc, const char *str)
+{
+ long len = rbimpl_strlen(str);
+ return rb_exc_new(exc, str, len);
+}
+
+#define rb_str_new(str, len) \
+ ((RBIMPL_CONSTANT_P(str) && \
+ RBIMPL_CONSTANT_P(len) ? \
+ rb_str_new_static : \
+ rb_str_new) ((str), (len)))
+
+#define rb_str_new_cstr(str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_str_new_cstr : \
+ rb_str_new_cstr) (str))
+
+#define rb_usascii_str_new(str, len) \
+ ((RBIMPL_CONSTANT_P(str) && \
+ RBIMPL_CONSTANT_P(len) ? \
+ rb_usascii_str_new_static : \
+ rb_usascii_str_new) ((str), (len)))
+
+#define rb_utf8_str_new(str, len) \
+ ((RBIMPL_CONSTANT_P(str) && \
+ RBIMPL_CONSTANT_P(len) ? \
+ rb_utf8_str_new_static : \
+ rb_utf8_str_new) ((str), (len)))
+
+#define rb_tainted_str_new_cstr(str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_tainted_str_new_cstr : \
+ rb_tainted_str_new_cstr) (str))
+
+#define rb_usascii_str_new_cstr(str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_usascii_str_new_cstr : \
+ rb_usascii_str_new_cstr) (str))
+
+#define rb_utf8_str_new_cstr(str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_utf8_str_new_cstr : \
+ rb_utf8_str_new_cstr) (str))
+
+#define rb_external_str_new_cstr(str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_external_str_new_cstr : \
+ rb_external_str_new_cstr) (str))
+
+#define rb_locale_str_new_cstr(str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_locale_str_new_cstr : \
+ rb_locale_str_new_cstr) (str))
+
+#define rb_str_buf_new_cstr(str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_str_buf_new_cstr : \
+ rb_str_buf_new_cstr) (str))
+
+#define rb_str_cat_cstr(buf, str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_str_cat_cstr : \
+ rb_str_cat_cstr) ((buf), (str)))
+
+#define rb_exc_new_cstr(exc, str) \
+ ((RBIMPL_CONSTANT_P(str) ? \
+ rbimpl_exc_new_cstr : \
+ rb_exc_new_cstr) ((exc), (str)))
+
+#define rb_str_new2 rb_str_new_cstr
+#define rb_str_new3 rb_str_new_shared
+#define rb_str_new4 rb_str_new_frozen
+#define rb_str_new5 rb_str_new_with_class
+#define rb_tainted_str_new2 rb_tainted_str_new_cstr
+#define rb_str_buf_new2 rb_str_buf_new_cstr
+#define rb_usascii_str_new2 rb_usascii_str_new_cstr
+#define rb_str_buf_cat rb_str_cat
+#define rb_str_buf_cat2 rb_str_cat_cstr
+#define rb_str_cat2 rb_str_cat_cstr
+#define rb_strlen_lit(str) (sizeof(str "") - 1)
+#define rb_str_new_lit(str) rb_str_new_static((str), rb_strlen_lit(str))
+#define rb_usascii_str_new_lit(str) rb_usascii_str_new_static((str), rb_strlen_lit(str))
+#define rb_utf8_str_new_lit(str) rb_utf8_str_new_static((str), rb_strlen_lit(str))
+#define rb_enc_str_new_lit(str, enc) rb_enc_str_new_static((str), rb_strlen_lit(str), (enc))
+#define rb_str_new_literal(str) rb_str_new_lit(str)
+#define rb_usascii_str_new_literal(str) rb_usascii_str_new_lit(str)
+#define rb_utf8_str_new_literal(str) rb_utf8_str_new_lit(str)
+#define rb_enc_str_new_literal(str, enc) rb_enc_str_new_lit(str, enc)
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_STRING_H */
diff --git a/include/ruby/internal/intern/struct.h b/include/ruby/internal/intern/struct.h
new file mode 100644
index 0000000000..8818da96c7
--- /dev/null
+++ b/include/ruby/internal/intern/struct.h
@@ -0,0 +1,47 @@
+#ifndef RBIMPL_INTERN_STRUCT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_STRUCT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cStruct.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/intern/vm.h" /* rb_alloc_func_t */
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* struct.c */
+VALUE rb_struct_new(VALUE, ...);
+VALUE rb_struct_define(const char*, ...);
+VALUE rb_struct_define_under(VALUE, const char*, ...);
+VALUE rb_struct_alloc(VALUE, VALUE);
+VALUE rb_struct_initialize(VALUE, VALUE);
+VALUE rb_struct_aref(VALUE, VALUE);
+VALUE rb_struct_aset(VALUE, VALUE, VALUE);
+VALUE rb_struct_getmember(VALUE, ID);
+VALUE rb_struct_s_members(VALUE);
+VALUE rb_struct_members(VALUE);
+VALUE rb_struct_size(VALUE s);
+VALUE rb_struct_alloc_noinit(VALUE);
+VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t, ...);
+VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_STRUCT_H */
diff --git a/include/ruby/internal/intern/thread.h b/include/ruby/internal/intern/thread.h
new file mode 100644
index 0000000000..a12a371058
--- /dev/null
+++ b/include/ruby/internal/intern/thread.h
@@ -0,0 +1,76 @@
+#ifndef RBIMPL_INTERN_THREAD_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_THREAD_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cThread.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+struct timeval;
+
+/* thread.c */
+void rb_thread_schedule(void);
+void rb_thread_wait_fd(int);
+int rb_thread_fd_writable(int);
+void rb_thread_fd_close(int);
+int rb_thread_alone(void);
+void rb_thread_sleep(int);
+void rb_thread_sleep_forever(void);
+void rb_thread_sleep_deadly(void);
+VALUE rb_thread_stop(void);
+VALUE rb_thread_wakeup(VALUE);
+VALUE rb_thread_wakeup_alive(VALUE);
+VALUE rb_thread_run(VALUE);
+VALUE rb_thread_kill(VALUE);
+VALUE rb_thread_create(VALUE (*)(void *), void*);
+void rb_thread_wait_for(struct timeval);
+VALUE rb_thread_current(void);
+VALUE rb_thread_main(void);
+VALUE rb_thread_local_aref(VALUE, ID);
+VALUE rb_thread_local_aset(VALUE, ID, VALUE);
+void rb_thread_atfork(void);
+void rb_thread_atfork_before_exec(void);
+VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
+VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE);
+VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
+VALUE rb_exec_recursive_paired_outer(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE);
+
+typedef void rb_unblock_function_t(void *);
+typedef VALUE rb_blocking_function_t(void *);
+void rb_thread_check_ints(void);
+int rb_thread_interrupted(VALUE thval);
+
+#define RUBY_UBF_IO RBIMPL_CAST((rb_unblock_function_t *)-1)
+#define RUBY_UBF_PROCESS RBIMPL_CAST((rb_unblock_function_t *)-1)
+VALUE rb_mutex_new(void);
+VALUE rb_mutex_locked_p(VALUE mutex);
+VALUE rb_mutex_trylock(VALUE mutex);
+VALUE rb_mutex_lock(VALUE mutex);
+VALUE rb_mutex_unlock(VALUE mutex);
+VALUE rb_mutex_sleep(VALUE self, VALUE timeout);
+VALUE rb_mutex_synchronize(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_THREAD_H */
diff --git a/include/ruby/internal/intern/time.h b/include/ruby/internal/intern/time.h
new file mode 100644
index 0000000000..c7ae6ec2f5
--- /dev/null
+++ b/include/ruby/internal/intern/time.h
@@ -0,0 +1,51 @@
+#ifndef RBIMPL_INTERN_TIME_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_TIME_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cTime.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_TIME_H
+# include <time.h> /* for time_t */
+#endif
+
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+struct timespec;
+struct timeval;
+
+/* time.c */
+void rb_timespec_now(struct timespec *);
+VALUE rb_time_new(time_t, long);
+VALUE rb_time_nano_new(time_t, long);
+VALUE rb_time_timespec_new(const struct timespec *, int);
+VALUE rb_time_num_new(VALUE, VALUE);
+struct timeval rb_time_interval(VALUE num);
+struct timeval rb_time_timeval(VALUE time);
+struct timespec rb_time_timespec(VALUE time);
+struct timespec rb_time_timespec_interval(VALUE num);
+VALUE rb_time_utc_offset(VALUE time);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_TIME_H */
diff --git a/include/ruby/internal/intern/variable.h b/include/ruby/internal/intern/variable.h
new file mode 100644
index 0000000000..8210662fa0
--- /dev/null
+++ b/include/ruby/internal/intern/variable.h
@@ -0,0 +1,83 @@
+#ifndef RBIMPL_INTERN_VARIABLE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_VARIABLE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to names inside of a Ruby program.
+ */
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/st.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* variable.c */
+VALUE rb_mod_name(VALUE);
+VALUE rb_class_path(VALUE);
+VALUE rb_class_path_cached(VALUE);
+void rb_set_class_path(VALUE, VALUE, const char*);
+void rb_set_class_path_string(VALUE, VALUE, VALUE);
+VALUE rb_path_to_class(VALUE);
+VALUE rb_path2class(const char*);
+VALUE rb_class_name(VALUE);
+VALUE rb_autoload_load(VALUE, ID);
+VALUE rb_autoload_p(VALUE, ID);
+VALUE rb_f_trace_var(int, const VALUE*);
+VALUE rb_f_untrace_var(int, const VALUE*);
+VALUE rb_f_global_variables(void);
+void rb_alias_variable(ID, ID);
+void rb_copy_generic_ivar(VALUE,VALUE);
+void rb_free_generic_ivar(VALUE);
+VALUE rb_ivar_get(VALUE, ID);
+VALUE rb_ivar_set(VALUE, ID, VALUE);
+VALUE rb_ivar_defined(VALUE, ID);
+void rb_ivar_foreach(VALUE, int (*)(ID, VALUE, st_data_t), st_data_t);
+st_index_t rb_ivar_count(VALUE);
+VALUE rb_attr_get(VALUE, ID);
+VALUE rb_obj_instance_variables(VALUE);
+VALUE rb_obj_remove_instance_variable(VALUE, VALUE);
+void *rb_mod_const_at(VALUE, void*);
+void *rb_mod_const_of(VALUE, void*);
+VALUE rb_const_list(void*);
+VALUE rb_mod_constants(int, const VALUE *, VALUE);
+VALUE rb_mod_remove_const(VALUE, VALUE);
+int rb_const_defined(VALUE, ID);
+int rb_const_defined_at(VALUE, ID);
+int rb_const_defined_from(VALUE, ID);
+VALUE rb_const_get(VALUE, ID);
+VALUE rb_const_get_at(VALUE, ID);
+VALUE rb_const_get_from(VALUE, ID);
+void rb_const_set(VALUE, ID, VALUE);
+VALUE rb_const_remove(VALUE, ID);
+#if 0 /* EXPERIMENTAL: remove if no problem */
+RBIMPL_ATTR_NORETURN()
+VALUE rb_mod_const_missing(VALUE,VALUE);
+#endif
+VALUE rb_cvar_defined(VALUE, ID);
+void rb_cvar_set(VALUE, ID, VALUE);
+VALUE rb_cvar_get(VALUE, ID);
+void rb_cv_set(VALUE, const char*, VALUE);
+VALUE rb_cv_get(VALUE, const char*);
+void rb_define_class_variable(VALUE, const char*, VALUE);
+VALUE rb_mod_class_variables(int, const VALUE*, VALUE);
+VALUE rb_mod_remove_cvar(VALUE, VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_VARIABLE_H */
diff --git a/include/ruby/internal/intern/vm.h b/include/ruby/internal/intern/vm.h
new file mode 100644
index 0000000000..706f160ad8
--- /dev/null
+++ b/include/ruby/internal/intern/vm.h
@@ -0,0 +1,77 @@
+#ifndef RBIMPL_INTERN_VM_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_VM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_cRubyVM.
+ */
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* vm.c */
+int rb_sourceline(void);
+const char *rb_sourcefile(void);
+int rb_frame_method_id_and_class(ID *idp, VALUE *klassp);
+
+/* vm_eval.c */
+VALUE rb_check_funcall(VALUE, ID, int, const VALUE*);
+VALUE rb_check_funcall_kw(VALUE, ID, int, const VALUE*, int);
+void rb_remove_method(VALUE, const char*);
+void rb_remove_method_id(VALUE, ID);
+
+VALUE rb_eval_cmd_kw(VALUE, VALUE, int);
+VALUE rb_apply(VALUE, ID, VALUE);
+
+VALUE rb_obj_instance_eval(int, const VALUE*, VALUE);
+VALUE rb_obj_instance_exec(int, const VALUE*, VALUE);
+VALUE rb_mod_module_eval(int, const VALUE*, VALUE);
+VALUE rb_mod_module_exec(int, const VALUE*, VALUE);
+
+/* vm_method.c */
+#define HAVE_RB_DEFINE_ALLOC_FUNC 1
+typedef VALUE (*rb_alloc_func_t)(VALUE);
+void rb_define_alloc_func(VALUE, rb_alloc_func_t);
+void rb_undef_alloc_func(VALUE);
+rb_alloc_func_t rb_get_alloc_func(VALUE);
+void rb_clear_constant_cache(void);
+void rb_clear_method_cache_by_class(VALUE);
+void rb_alias(VALUE, ID, ID);
+void rb_attr(VALUE,ID,int,int,int);
+int rb_method_boundp(VALUE, ID, int);
+int rb_method_basic_definition_p(VALUE, ID);
+
+int rb_obj_respond_to(VALUE, ID, int);
+int rb_respond_to(VALUE, ID);
+
+RBIMPL_ATTR_NORETURN()
+VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker);
+#if !defined(RUBY_EXPORT) && defined(_WIN32)
+RUBY_EXTERN VALUE (*const rb_f_notimplement_)(int, const VALUE *, VALUE, VALUE marker);
+#define rb_f_notimplement (*rb_f_notimplement_)
+#endif
+
+/* vm_backtrace.c */
+void rb_backtrace(void);
+VALUE rb_make_backtrace(void);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_VM_H */
diff --git a/include/ruby/internal/interpreter.h b/include/ruby/internal/interpreter.h
new file mode 100644
index 0000000000..29dee60aab
--- /dev/null
+++ b/include/ruby/internal/interpreter.h
@@ -0,0 +1,93 @@
+#ifndef RBIMPL_INTERPRETER_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERPRETER_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Interpreter embedding APIs.
+ */
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/**
+ * @defgroup embed CRuby Embedding APIs
+ * CRuby interpreter APIs. These are APIs to embed MRI interpreter into your
+ * program.
+ * These functions are not a part of Ruby extension library API.
+ * Extension libraries of Ruby should not depend on these functions.
+ * @{
+ */
+
+/** @defgroup ruby1 ruby(1) implementation
+ * A part of the implementation of ruby(1) command.
+ * Other programs that embed Ruby interpreter do not always need to use these
+ * functions.
+ * @{
+ */
+
+void ruby_sysinit(int *argc, char ***argv);
+void ruby_init(void);
+void* ruby_options(int argc, char** argv);
+int ruby_executable_node(void *n, int *status);
+int ruby_run_node(void *n);
+
+/* version.c */
+void ruby_show_version(void);
+#ifndef ruby_show_copyright
+void ruby_show_copyright(void);
+#endif
+
+/*! A convenience macro to call ruby_init_stack(). Must be placed just after
+ * variable declarations */
+#define RUBY_INIT_STACK \
+ VALUE variable_in_this_stack_frame; \
+ ruby_init_stack(&variable_in_this_stack_frame);
+/*! @} */
+
+void ruby_init_stack(volatile VALUE*);
+
+int ruby_setup(void);
+int ruby_cleanup(volatile int);
+
+void ruby_finalize(void);
+
+RBIMPL_ATTR_NORETURN()
+void ruby_stop(int);
+
+int ruby_stack_check(void);
+size_t ruby_stack_length(VALUE**);
+
+int ruby_exec_node(void *n);
+
+void ruby_script(const char* name);
+void ruby_set_script_name(VALUE name);
+
+void ruby_prog_init(void);
+void ruby_set_argv(int, char**);
+void *ruby_process_options(int, char**);
+void ruby_init_loadpath(void);
+void ruby_incpush(const char*);
+void ruby_sig_finalize(void);
+
+/*! @} */
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERPRETER_H */
diff --git a/include/ruby/internal/iterator.h b/include/ruby/internal/iterator.h
new file mode 100644
index 0000000000..99c0831b13
--- /dev/null
+++ b/include/ruby/internal/iterator.h
@@ -0,0 +1,65 @@
+#ifndef RBIMPL_ITERATOR_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ITERATOR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Block related APIs.
+ */
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+#define RB_BLOCK_CALL_FUNC_STRICT 1
+#define RUBY_BLOCK_CALL_FUNC_TAKES_BLOCKARG 1
+#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) \
+ VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg
+typedef VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg));
+typedef rb_block_call_func *rb_block_call_func_t;
+
+VALUE rb_each(VALUE);
+VALUE rb_yield(VALUE);
+VALUE rb_yield_values(int n, ...);
+VALUE rb_yield_values2(int n, const VALUE *argv);
+VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat);
+VALUE rb_yield_splat(VALUE);
+VALUE rb_yield_splat_kw(VALUE, int);
+VALUE rb_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)); /* rb_block_call_func */
+int rb_keyword_given_p(void);
+int rb_block_given_p(void);
+void rb_need_block(void);
+VALUE rb_iterate(VALUE(*)(VALUE),VALUE,rb_block_call_func_t,VALUE);
+VALUE rb_block_call(VALUE,ID,int,const VALUE*,rb_block_call_func_t,VALUE);
+VALUE rb_block_call_kw(VALUE,ID,int,const VALUE*,rb_block_call_func_t,VALUE,int);
+VALUE rb_rescue(VALUE(*)(VALUE),VALUE,VALUE(*)(VALUE,VALUE),VALUE);
+VALUE rb_rescue2(VALUE(*)(VALUE),VALUE,VALUE(*)(VALUE,VALUE),VALUE,...);
+VALUE rb_vrescue2(VALUE(*)(VALUE),VALUE,VALUE(*)(VALUE,VALUE),VALUE,va_list);
+VALUE rb_ensure(VALUE(*)(VALUE),VALUE,VALUE(*)(VALUE),VALUE);
+VALUE rb_catch(const char*,rb_block_call_func_t,VALUE);
+VALUE rb_catch_obj(VALUE,rb_block_call_func_t,VALUE);
+
+RBIMPL_ATTR_NORETURN()
+void rb_throw(const char*,VALUE);
+
+RBIMPL_ATTR_NORETURN()
+void rb_throw_obj(VALUE,VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_ITERATOR_H */
diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h
new file mode 100644
index 0000000000..46dfcadd10
--- /dev/null
+++ b/include/ruby/internal/memory.h
@@ -0,0 +1,281 @@
+#ifndef RBIMPL_MEMORY_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_MEMORY_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Memory management stuff.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#if defined(_MSC_VER) && defined(_WIN64)
+# include <intrin.h>
+# pragma intrinsic(_umul128)
+#endif
+
+#include "ruby/internal/attr/alloc_size.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/attr/noalias.h"
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/attr/restrict.h"
+#include "ruby/internal/attr/returns_nonnull.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/has/builtin.h"
+#include "ruby/internal/stdalign.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/xmalloc.h"
+#include "ruby/backward/2/limits.h"
+#include "ruby/backward/2/long_long.h"
+#include "ruby/backward/2/assume.h"
+#include "ruby/defines.h"
+
+/* Make alloca work the best possible way. */
+#if defined(alloca)
+# /* Take that. */
+#elif RBIMPL_HAS_BUILTIN(__builtin_alloca)
+# define alloca __builtin_alloca
+#elif defined(_AIX)
+# pragma alloca
+#elif defined(__cplusplus)
+extern "C" void *alloca(size_t);
+#else
+extern void *alloca();
+#endif
+
+#if defined(HAVE_INT128_T) && SIZEOF_SIZE_T <= 8
+# define DSIZE_T uint128_t
+#elif SIZEOF_SIZE_T * 2 <= SIZEOF_LONG_LONG
+# define DSIZE_T unsigned LONG_LONG
+#endif
+
+#ifdef C_ALLOCA
+# define RUBY_ALLOCV_LIMIT 0
+#else
+# define RUBY_ALLOCV_LIMIT 1024
+#endif
+
+#ifdef __GNUC__
+#define RB_GC_GUARD(v) \
+ (*__extension__ ({ \
+ volatile VALUE *rb_gc_guarded_ptr = &(v); \
+ __asm__("" : : "m"(rb_gc_guarded_ptr)); \
+ rb_gc_guarded_ptr; \
+ }))
+#elif defined _MSC_VER
+#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr(&(v)))
+#else
+#define HAVE_RB_GC_GUARDED_PTR_VAL 1
+#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr_val(&(v),(v)))
+#endif
+
+/* Casts needed because void* is NOT compaible with others in C++. */
+#define RB_ALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))
+#define RB_ALLOC(type) RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))
+#define RB_ZALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))
+#define RB_ZALLOC(type) (RB_ZALLOC_N(type, 1))
+#define RB_REALLOC_N(var,type,n) \
+ ((var) = RBIMPL_CAST((type *)ruby_xrealloc2((void *)(var), (n), sizeof(type))))
+
+#define ALLOCA_N(type,n) \
+ RBIMPL_CAST((type *)(!(n) ? NULL : alloca(rbimpl_size_mul_or_raise(sizeof(type), (n)))))
+
+/* allocates _n_ bytes temporary buffer and stores VALUE including it
+ * in _v_. _n_ may be evaluated twice. */
+#define RB_ALLOCV(v, n) \
+ ((n) < RUBY_ALLOCV_LIMIT ? \
+ ((v) = 0, !(n) ? NULL : alloca(n)) : \
+ rb_alloc_tmp_buffer(&(v), (n)))
+#define RB_ALLOCV_N(type, v, n) \
+ RBIMPL_CAST((type *) \
+ (((size_t)(n) < RUBY_ALLOCV_LIMIT / sizeof(type)) ? \
+ ((v) = 0, !(n) ? NULL : alloca((n) * sizeof(type))) : \
+ rb_alloc_tmp_buffer2(&(v), (n), sizeof(type))))
+#define RB_ALLOCV_END(v) rb_free_tmp_buffer(&(v))
+
+#define MEMZERO(p,type,n) memset((p), 0, rbimpl_size_mul_or_raise(sizeof(type), (n)))
+#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
+#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
+#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
+
+#define ALLOC_N RB_ALLOC_N
+#define ALLOC RB_ALLOC
+#define ZALLOC_N RB_ZALLOC_N
+#define ZALLOC RB_ZALLOC
+#define REALLOC_N RB_REALLOC_N
+#define ALLOCV RB_ALLOCV
+#define ALLOCV_N RB_ALLOCV_N
+#define ALLOCV_END RB_ALLOCV_END
+
+/* Expecting this struct to be eliminated by function inlinings */
+struct rbimpl_size_mul_overflow_tag {
+ bool left;
+ size_t right;
+};
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((2))
+void *rb_alloc_tmp_buffer(volatile VALUE *store, long len);
+
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((2,3))
+void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t len,size_t count);
+
+void rb_free_tmp_buffer(volatile VALUE *store);
+
+RBIMPL_ATTR_NORETURN()
+void ruby_malloc_size_overflow(size_t, size_t);
+
+#ifdef HAVE_RB_GC_GUARDED_PTR_VAL
+volatile VALUE *rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val);
+#endif
+RBIMPL_SYMBOL_EXPORT_END()
+
+#ifdef _MSC_VER
+# pragma optimize("", off)
+
+static inline volatile VALUE *
+rb_gc_guarded_ptr(volatile VALUE *ptr)
+{
+ return ptr;
+}
+
+# pragma optimize("", on)
+#endif
+
+/* Does anyone use it? Just here for backwards compatibility. */
+static inline int
+rb_mul_size_overflow(size_t a, size_t b, size_t max, size_t *c)
+{
+#ifdef DSIZE_T
+ RB_GNUC_EXTENSION DSIZE_T da, db, c2;
+ da = a;
+ db = b;
+ c2 = da * db;
+ if (c2 > max) return 1;
+ *c = RBIMPL_CAST((size_t)c2);
+#else
+ if (b != 0 && a > max / b) return 1;
+ *c = a * b;
+#endif
+ return 0;
+}
+
+#if RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
+RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70507 */
+#elif RBIMPL_COMPILER_SINCE(Clang, 7, 0, 0)
+RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://bugs.llvm.org/show_bug.cgi?id=37633 */
+#endif
+RBIMPL_ATTR_CONST()
+static inline struct rbimpl_size_mul_overflow_tag
+rbimpl_size_mul_overflow(size_t x, size_t y)
+{
+ struct rbimpl_size_mul_overflow_tag ret = { false, 0, };
+
+#if RBIMPL_HAS_BUILTIN(__builtin_mul_overflow)
+ ret.left = __builtin_mul_overflow(x, y, &ret.right);
+
+#elif defined(DSIZE_T)
+ RB_GNUC_EXTENSION DSIZE_T dx = x;
+ RB_GNUC_EXTENSION DSIZE_T dy = y;
+ RB_GNUC_EXTENSION DSIZE_T dz = dx * dy;
+ ret.left = dz > SIZE_MAX;
+ ret.right = RBIMPL_CAST((size_t)dz);
+
+#elif defined(_MSC_VER) && defined(_WIN64)
+ unsigned __int64 dp = 0;
+ unsigned __int64 dz = _umul128(x, y, &dp);
+ ret.left = RBIMPL_CAST((bool)dp);
+ ret.right = RBIMPL_CAST((size_t)dz);
+
+#else
+ /* https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap */
+ ret.left = (y != 0) && (x > SIZE_MAX / y);
+ ret.right = x * y;
+#endif
+
+ return ret;
+}
+
+static inline size_t
+rbimpl_size_mul_or_raise(size_t x, size_t y)
+{
+ struct rbimpl_size_mul_overflow_tag size =
+ rbimpl_size_mul_overflow(x, y);
+
+ if (RB_LIKELY(! size.left)) {
+ return size.right;
+ }
+ else {
+ ruby_malloc_size_overflow(x, y);
+ RBIMPL_UNREACHABLE_RETURN(0);
+ }
+}
+
+static inline void *
+rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize)
+{
+ const size_t total_size = rbimpl_size_mul_or_raise(count, elsize);
+ const size_t cnt = (total_size + sizeof(VALUE) - 1) / sizeof(VALUE);
+ return rb_alloc_tmp_buffer_with_count(store, total_size, cnt);
+}
+
+#ifndef __MINGW32__
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+RBIMPL_ATTR_NOALIAS()
+RBIMPL_ATTR_NONNULL((1))
+RBIMPL_ATTR_RETURNS_NONNULL()
+/* At least since 2004, glibc's <string.h> annotates memcpy to be
+ * __attribute__((__nonnull__(1, 2))). However it is safe to pass NULL to the
+ * source pointer, if n is 0. Let's wrap memcpy. */
+static inline void *
+ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
+{
+ if (n) {
+ return memcpy(dest, src, n);
+ }
+ else {
+ return dest;
+ }
+}
+RBIMPL_SYMBOL_EXPORT_END()
+#undef memcpy
+#define memcpy ruby_nonempty_memcpy
+#endif
+
+#endif /* RBIMPL_MEMORY_H */
diff --git a/include/ruby/internal/method.h b/include/ruby/internal/method.h
new file mode 100644
index 0000000000..67600e8732
--- /dev/null
+++ b/include/ruby/internal/method.h
@@ -0,0 +1,39 @@
+#ifndef RBIMPL_METHOD_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_METHOD_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Creation and modification of Ruby methods.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/backward/2/stdarg.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+void rb_define_method(VALUE,const char*,VALUE(*)(ANYARGS),int);
+void rb_define_module_function(VALUE,const char*,VALUE(*)(ANYARGS),int);
+void rb_define_global_function(const char*,VALUE(*)(ANYARGS),int);
+
+void rb_undef_method(VALUE,const char*);
+void rb_define_alias(VALUE,const char*,const char*);
+void rb_define_attr(VALUE,const char*,int,int);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_METHOD_H */
diff --git a/include/ruby/internal/module.h b/include/ruby/internal/module.h
new file mode 100644
index 0000000000..0f2dfdb1be
--- /dev/null
+++ b/include/ruby/internal/module.h
@@ -0,0 +1,39 @@
+#ifndef RBIMPL_MODULE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_MODULE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Creation and modification of Ruby modules.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+VALUE rb_define_class(const char*,VALUE);
+VALUE rb_define_module(const char*);
+VALUE rb_define_class_under(VALUE, const char*, VALUE);
+VALUE rb_define_module_under(VALUE, const char*);
+
+void rb_include_module(VALUE,VALUE);
+void rb_extend_object(VALUE,VALUE);
+void rb_prepend_module(VALUE,VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_MODULE_H */
diff --git a/include/ruby/internal/newobj.h b/include/ruby/internal/newobj.h
new file mode 100644
index 0000000000..684226e54b
--- /dev/null
+++ b/include/ruby/internal/newobj.h
@@ -0,0 +1,73 @@
+#ifndef RBIMPL_NEWOBJ_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_NEWOBJ_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #NEWOBJ.
+ */
+#include "ruby/internal/cast.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+
+#define RB_NEWOBJ(obj,type) type *(obj) = RBIMPL_CAST((type *)rb_newobj())
+#define RB_NEWOBJ_OF(obj,type,klass,flags) type *(obj) = RBIMPL_CAST((type *)rb_newobj_of(klass, flags))
+
+#define NEWOBJ RB_NEWOBJ
+#define NEWOBJ_OF RB_NEWOBJ_OF /* core has special NEWOBJ_OF() in internal.h */
+#define OBJSETUP rb_obj_setup /* use NEWOBJ_OF instead of NEWOBJ()+OBJSETUP() */
+#define CLONESETUP rb_clone_setup
+#define DUPSETUP rb_dup_setup
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+VALUE rb_newobj(void);
+VALUE rb_newobj_of(VALUE, VALUE);
+VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type);
+VALUE rb_obj_class(VALUE);
+VALUE rb_singleton_class_clone(VALUE);
+void rb_singleton_class_attached(VALUE,VALUE);
+void rb_copy_generic_ivar(VALUE,VALUE);
+RBIMPL_SYMBOL_EXPORT_END()
+
+static inline void
+rb_clone_setup(VALUE clone, VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(clone));
+
+ const VALUE flags = RUBY_FL_PROMOTED0 | RUBY_FL_PROMOTED1 | RUBY_FL_FINALIZE;
+ rb_obj_setup(clone, rb_singleton_class_clone(obj),
+ RB_FL_TEST_RAW(obj, ~flags));
+ rb_singleton_class_attached(RBASIC_CLASS(clone), clone);
+ if (RB_FL_TEST(obj, RUBY_FL_EXIVAR)) rb_copy_generic_ivar(clone, obj);
+}
+
+static inline void
+rb_dup_setup(VALUE dup, VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(dup));
+
+ rb_obj_setup(dup, rb_obj_class(obj), RB_FL_TEST_RAW(obj, RUBY_FL_DUPPED));
+ if (RB_FL_TEST(obj, RUBY_FL_EXIVAR)) rb_copy_generic_ivar(dup, obj);
+}
+
+#endif /* RBIMPL_NEWOBJ_H */
diff --git a/include/ruby/internal/rgengc.h b/include/ruby/internal/rgengc.h
new file mode 100644
index 0000000000..2681d41844
--- /dev/null
+++ b/include/ruby/internal/rgengc.h
@@ -0,0 +1,199 @@
+#ifndef RBIMPL_RGENGC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RGENGC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief RGENGC write-barrier APIs.
+ * @see Sasada, K., "Gradual write-barrier insertion into a Ruby
+ * interpreter", in proceedings of the 2019 ACM SIGPLAN
+ * International Symposium on Memory Management (ISMM 2019), pp
+ * 115-121, 2019. https://doi.org/10.1145/3315573.3329986
+ */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+#include "ruby/backward/2/attributes.h"
+
+#undef USE_RGENGC
+#define USE_RGENGC 1
+
+#ifndef USE_RINCGC
+# define USE_RINCGC 1
+#endif
+
+#ifndef USE_RGENGC_LOGGING_WB_UNPROTECT
+# define USE_RGENGC_LOGGING_WB_UNPROTECT 0
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_ARRAY
+# define RGENGC_WB_PROTECTED_ARRAY 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_HASH
+# define RGENGC_WB_PROTECTED_HASH 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_STRUCT
+# define RGENGC_WB_PROTECTED_STRUCT 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_STRING
+# define RGENGC_WB_PROTECTED_STRING 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_OBJECT
+# define RGENGC_WB_PROTECTED_OBJECT 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_REGEXP
+# define RGENGC_WB_PROTECTED_REGEXP 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_CLASS
+# define RGENGC_WB_PROTECTED_CLASS 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_FLOAT
+# define RGENGC_WB_PROTECTED_FLOAT 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_COMPLEX
+# define RGENGC_WB_PROTECTED_COMPLEX 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_RATIONAL
+# define RGENGC_WB_PROTECTED_RATIONAL 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_BIGNUM
+# define RGENGC_WB_PROTECTED_BIGNUM 1
+#endif
+
+#ifndef RGENGC_WB_PROTECTED_NODE_CREF
+# define RGENGC_WB_PROTECTED_NODE_CREF 1
+#endif
+
+/**
+ * @name Write barrier (WB) interfaces:
+ * @{
+ *
+ * @note The following core interfaces can be changed in the future. Please
+ * catch up if you want to insert WB into C-extensions correctly.
+ */
+
+/**
+ * WB for new reference from `a' to `b'. Write `b' into `*slot'. `slot' is a
+ * pointer in `a'.
+ */
+#define RB_OBJ_WRITE(a, slot, b) \
+ RBIMPL_CAST(rb_obj_write((VALUE)(a), (VALUE *)(slot), (VALUE)(b), __FILE__, __LINE__))
+/**
+ * WB for new reference from `a' to `b'. This doesn't write any values, but
+ * only a WB declaration. `oldv' is replaced value with `b' (not used in
+ * current Ruby).
+ */
+#define RB_OBJ_WRITTEN(a, oldv, b) \
+ RBIMPL_CAST(rb_obj_written((VALUE)(a), (VALUE)(oldv), (VALUE)(b), __FILE__, __LINE__))
+/** @} */
+
+#define OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
+#define OBJ_PROMOTED RB_OBJ_PROMOTED
+#define OBJ_WB_UNPROTECT RB_OBJ_WB_UNPROTECT
+
+#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
+#define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \
+ (RGENGC_WB_PROTECTED_##type ? OBJ_WB_UNPROTECT(obj) : obj)
+#define RGENGC_LOGGING_WB_UNPROTECT rb_gc_unprotect_logging
+
+/** @cond INTERNAL_MACRO */
+#define RB_OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
+#define RB_OBJ_PROMOTED RB_OBJ_PROMOTED
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+void rb_gc_writebarrier(VALUE a, VALUE b);
+void rb_gc_writebarrier_unprotect(VALUE obj);
+#if USE_RGENGC_LOGGING_WB_UNPROTECT
+void rb_gc_unprotect_logging(void *objptr, const char *filename, int line);
+#endif
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_OBJ_PROMOTED_RAW(VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
+ return RB_FL_ANY_RAW(obj, RUBY_FL_PROMOTED);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_OBJ_PROMOTED(VALUE obj)
+{
+ if (! RB_FL_ABLE(obj)) {
+ return false;
+ }
+ else {
+ return RB_OBJ_PROMOTED_RAW(obj);
+ }
+}
+
+static inline VALUE
+rb_obj_wb_unprotect(VALUE x, RB_UNUSED_VAR(const char *filename), RB_UNUSED_VAR(int line))
+{
+#if USE_RGENGC_LOGGING_WB_UNPROTECT
+ RGENGC_LOGGING_WB_UNPROTECT(RBIMPL_CAST((void *)x), filename, line);
+#endif
+ rb_gc_writebarrier_unprotect(x);
+ return x;
+}
+
+static inline VALUE
+rb_obj_written(VALUE a, RB_UNUSED_VAR(VALUE oldv), VALUE b, RB_UNUSED_VAR(const char *filename), RB_UNUSED_VAR(int line))
+{
+#if USE_RGENGC_LOGGING_WB_UNPROTECT
+ RGENGC_LOGGING_OBJ_WRITTEN(a, oldv, b, filename, line);
+#endif
+
+ if (!RB_SPECIAL_CONST_P(b)) {
+ rb_gc_writebarrier(a, b);
+ }
+
+ return a;
+}
+
+static inline VALUE
+rb_obj_write(VALUE a, VALUE *slot, VALUE b, RB_UNUSED_VAR(const char *filename), RB_UNUSED_VAR(int line))
+{
+#ifdef RGENGC_LOGGING_WRITE
+ RGENGC_LOGGING_WRITE(a, slot, b, filename, line);
+#endif
+
+ *slot = b;
+
+ rb_obj_written(a, RUBY_Qundef /* ignore `oldv' now */, b, filename, line);
+ return a;
+}
+
+#endif /* RBIMPL_RGENGC_H */
diff --git a/include/ruby/internal/scan_args.h b/include/ruby/internal/scan_args.h
new file mode 100644
index 0000000000..d9329e7e98
--- /dev/null
+++ b/include/ruby/internal/scan_args.h
@@ -0,0 +1,401 @@
+#ifndef RBIMPL_SCAN_ARGS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_SCAN_ARGS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Compile-time static implementation of ::rb_scan_args().
+ *
+ * This is a beast. It statically analyses the argument spec string, and
+ * expands the assignment of variables into dedicated codes.
+ */
+#include "ruby/internal/attr/diagnose_if.h"
+#include "ruby/internal/attr/error.h"
+#include "ruby/internal/attr/forceinline.h"
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/config.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/intern/array.h" /* rb_ary_new_from_values */
+#include "ruby/internal/intern/error.h" /* rb_error_arity */
+#include "ruby/internal/intern/hash.h" /* rb_hash_dup */
+#include "ruby/internal/intern/proc.h" /* rb_block_proc */
+#include "ruby/internal/iterator.h" /* rb_block_given_p / rb_keyword_given_p */
+#include "ruby/internal/static_assert.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+
+#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS 0
+#define RB_SCAN_ARGS_KEYWORDS 1
+#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS 3
+#define RB_NO_KEYWORDS 0
+#define RB_PASS_KEYWORDS 1
+#define RB_PASS_CALLED_KEYWORDS rb_keyword_given_p()
+/* rb_scan_args() format allows ':' for optional hash */
+#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+int rb_scan_args(int, const VALUE*, const char*, ...);
+int rb_scan_args_kw(int, int, const VALUE*, const char*, ...);
+
+RBIMPL_ATTR_ERROR(("bad scan arg format"))
+void rb_scan_args_bad_format(const char*);
+
+RBIMPL_ATTR_ERROR(("variable argument length doesn't match"))
+void rb_scan_args_length_mismatch(const char*,int);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+/* If we could use constexpr the following macros could be inline functions
+ * ... but sadly we cannot. */
+
+#define rb_scan_args_isdigit(c) (RBIMPL_CAST((unsigned char)((c)-'0'))<10)
+
+#define rb_scan_args_count_end(fmt, ofs, vari) \
+ ((fmt)[ofs] ? -1 : (vari))
+
+#define rb_scan_args_count_block(fmt, ofs, vari) \
+ ((fmt)[ofs]!='&' ? \
+ rb_scan_args_count_end(fmt, ofs, vari) : \
+ rb_scan_args_count_end(fmt, (ofs)+1, (vari)+1))
+
+#define rb_scan_args_count_hash(fmt, ofs, vari) \
+ ((fmt)[ofs]!=':' ? \
+ rb_scan_args_count_block(fmt, ofs, vari) : \
+ rb_scan_args_count_block(fmt, (ofs)+1, (vari)+1))
+
+#define rb_scan_args_count_trail(fmt, ofs, vari) \
+ (!rb_scan_args_isdigit((fmt)[ofs]) ? \
+ rb_scan_args_count_hash(fmt, ofs, vari) : \
+ rb_scan_args_count_hash(fmt, (ofs)+1, (vari)+((fmt)[ofs]-'0')))
+
+#define rb_scan_args_count_var(fmt, ofs, vari) \
+ ((fmt)[ofs]!='*' ? \
+ rb_scan_args_count_trail(fmt, ofs, vari) : \
+ rb_scan_args_count_trail(fmt, (ofs)+1, (vari)+1))
+
+#define rb_scan_args_count_opt(fmt, ofs, vari) \
+ (!rb_scan_args_isdigit((fmt)[ofs]) ? \
+ rb_scan_args_count_var(fmt, ofs, vari) : \
+ rb_scan_args_count_var(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
+
+#define rb_scan_args_count_lead(fmt, ofs, vari) \
+ (!rb_scan_args_isdigit((fmt)[ofs]) ? \
+ rb_scan_args_count_var(fmt, ofs, vari) : \
+ rb_scan_args_count_opt(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
+
+#define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0)
+
+#if RBIMPL_HAS_ATTRIBUTE(diagnose_if)
+# /* Assertions done in the attribute. */
+# define rb_scan_args_verify(fmt, varc) RBIMPL_ASSERT_NOTHING
+#else
+# /* At one sight it _seems_ the expressions below could be written using
+# * static assrtions. The reality is no, they don't. Because fmt is a string
+# * literal, any operations against fmt cannot produce the "integer constant
+# * expression"s, as defined in ISO/IEC 9899:2018 section 6.6 paragraph #6.
+# * Static assertions need such integer constant expressions as defined in
+# * ISO/IEC 9899:2018 section 6.7.10 paragraph #3.
+# *
+# * GCC nonetheless constant-folds this into no-op, though. */
+# define rb_scan_args_verify(fmt, varc) \
+ (sizeof(char[1-2*(rb_scan_args_count(fmt)<0)])!=1 ? \
+ rb_scan_args_bad_format(fmt) : \
+ sizeof(char[1-2*(rb_scan_args_count(fmt)!=(varc))])!=1 ? \
+ rb_scan_args_length_mismatch(fmt, varc) : \
+ RBIMPL_ASSERT_NOTHING)
+#endif
+
+static inline bool
+rb_scan_args_keyword_p(int kw_flag, VALUE last)
+{
+ switch (kw_flag) {
+ case RB_SCAN_ARGS_PASS_CALLED_KEYWORDS:
+ return !! rb_keyword_given_p();
+ case RB_SCAN_ARGS_KEYWORDS:
+ return true;
+ case RB_SCAN_ARGS_LAST_HASH_KEYWORDS:
+ return RB_TYPE_P(last, T_HASH);
+ default:
+ return false;
+ }
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static bool
+rb_scan_args_lead_p(const char *fmt)
+{
+ return rb_scan_args_isdigit(fmt[0]);
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_n_lead(const char *fmt)
+{
+ return (rb_scan_args_lead_p(fmt) ? fmt[0]-'0' : 0);
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static bool
+rb_scan_args_opt_p(const char *fmt)
+{
+ return (rb_scan_args_lead_p(fmt) && rb_scan_args_isdigit(fmt[1]));
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_n_opt(const char *fmt)
+{
+ return (rb_scan_args_opt_p(fmt) ? fmt[1]-'0' : 0);
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_var_idx(const char *fmt)
+{
+ return (!rb_scan_args_lead_p(fmt) ? 0 : !rb_scan_args_isdigit(fmt[1]) ? 1 : 2);
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static bool
+rb_scan_args_f_var(const char *fmt)
+{
+ return (fmt[rb_scan_args_var_idx(fmt)]=='*');
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_trail_idx(const char *fmt)
+{
+ const int idx = rb_scan_args_var_idx(fmt);
+ return idx+(fmt[idx]=='*');
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_n_trail(const char *fmt)
+{
+ const int idx = rb_scan_args_trail_idx(fmt);
+ return (rb_scan_args_isdigit(fmt[idx]) ? fmt[idx]-'0' : 0);
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_hash_idx(const char *fmt)
+{
+ const int idx = rb_scan_args_trail_idx(fmt);
+ return idx+rb_scan_args_isdigit(fmt[idx]);
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static bool
+rb_scan_args_f_hash(const char *fmt)
+{
+ return (fmt[rb_scan_args_hash_idx(fmt)]==':');
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_block_idx(const char *fmt)
+{
+ const int idx = rb_scan_args_hash_idx(fmt);
+ return idx+(fmt[idx]==':');
+}
+
+RBIMPL_ATTR_FORCEINLINE()
+static bool
+rb_scan_args_f_block(const char *fmt)
+{
+ return (fmt[rb_scan_args_block_idx(fmt)]=='&');
+}
+
+# if 0
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_end_idx(const char *fmt)
+{
+ const int idx = rb_scan_args_block_idx(fmt);
+ return idx+(fmt[idx]=='&');
+}
+# endif
+
+/* NOTE: Use `char *fmt` instead of `const char *fmt` because of clang's bug*/
+/* https://bugs.llvm.org/show_bug.cgi?id=38095 */
+# define rb_scan_args0(argc, argv, fmt, varc, vars) \
+ rb_scan_args_set(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, argc, argv, \
+ rb_scan_args_n_lead(fmt), \
+ rb_scan_args_n_opt(fmt), \
+ rb_scan_args_n_trail(fmt), \
+ rb_scan_args_f_var(fmt), \
+ rb_scan_args_f_hash(fmt), \
+ rb_scan_args_f_block(fmt), \
+ (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
+# define rb_scan_args_kw0(kw_flag, argc, argv, fmt, varc, vars) \
+ rb_scan_args_set(kw_flag, argc, argv, \
+ rb_scan_args_n_lead(fmt), \
+ rb_scan_args_n_opt(fmt), \
+ rb_scan_args_n_trail(fmt), \
+ rb_scan_args_f_var(fmt), \
+ rb_scan_args_f_hash(fmt), \
+ rb_scan_args_f_block(fmt), \
+ (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
+
+RBIMPL_ATTR_FORCEINLINE()
+static int
+rb_scan_args_set(int kw_flag, int argc, const VALUE *argv,
+ int n_lead, int n_opt, int n_trail,
+ bool f_var, bool f_hash, bool f_block,
+ VALUE *vars[], RB_UNUSED_VAR(const char *fmt), RB_UNUSED_VAR(int varc))
+ RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) < 0, "bad scan arg format", "error")
+ RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) != varc, "variable argument length doesn't match", "error")
+{
+ int i, argi = 0, vari = 0;
+ VALUE *var, hash = Qnil;
+#define rb_scan_args_next_param() vars[vari++]
+ const int n_mand = n_lead + n_trail;
+
+ /* capture an option hash - phase 1: pop from the argv */
+ if (f_hash && argc > 0) {
+ VALUE last = argv[argc - 1];
+ if (rb_scan_args_keyword_p(kw_flag, last)) {
+ hash = rb_hash_dup(last);
+ argc--;
+ }
+ }
+
+ if (argc < n_mand) {
+ goto argc_error;
+ }
+
+ /* capture leading mandatory arguments */
+ for (i = 0; i < n_lead; i++) {
+ var = rb_scan_args_next_param();
+ if (var) *var = argv[argi];
+ argi++;
+ }
+
+ /* capture optional arguments */
+ for (i = 0; i < n_opt; i++) {
+ var = rb_scan_args_next_param();
+ if (argi < argc - n_trail) {
+ if (var) *var = argv[argi];
+ argi++;
+ }
+ else {
+ if (var) *var = Qnil;
+ }
+ }
+
+ /* capture variable length arguments */
+ if (f_var) {
+ int n_var = argc - argi - n_trail;
+
+ var = rb_scan_args_next_param();
+ if (0 < n_var) {
+ if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
+ argi += n_var;
+ }
+ else {
+ if (var) *var = rb_ary_new();
+ }
+ }
+
+ /* capture trailing mandatory arguments */
+ for (i = 0; i < n_trail; i++) {
+ var = rb_scan_args_next_param();
+ if (var) *var = argv[argi];
+ argi++;
+ }
+
+ /* capture an option hash - phase 2: assignment */
+ if (f_hash) {
+ var = rb_scan_args_next_param();
+ if (var) *var = hash;
+ }
+
+ /* capture iterator block */
+ if (f_block) {
+ var = rb_scan_args_next_param();
+ if (rb_block_given_p()) {
+ *var = rb_block_proc();
+ }
+ else {
+ *var = Qnil;
+ }
+ }
+
+ if (argi == argc) {
+ return argc;
+ }
+
+ argc_error:
+ rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
+ UNREACHABLE_RETURN(-1);
+#undef rb_scan_args_next_param
+}
+
+#if ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
+# /* skip */
+
+#elif ! defined(HAVE_VA_ARGS_MACRO)
+# /* skip */
+
+#elif ! defined(__OPTIMIZE__)
+# /* skip */
+
+#elif defined(HAVE___VA_OPT__)
+# define rb_scan_args(argc, argvp, fmt, ...) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(fmt), \
+ rb_scan_args0( \
+ argc, argvp, fmt, \
+ (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
+ ((VALUE*[]){__VA_ARGS__})), \
+ (rb_scan_args)(argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
+# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(fmt), \
+ rb_scan_args_kw0( \
+ kw_flag, argc, argvp, fmt, \
+ (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
+ ((VALUE*[]){__VA_ARGS__})), \
+ (rb_scan_args_kw)(kw_flag, argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
+
+#elif defined(__STRICT_ANSI__)
+# /* skip */
+
+#elif defined(__GNUC__)
+# define rb_scan_args(argc, argvp, fmt, ...) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(fmt), \
+ rb_scan_args0( \
+ argc, argvp, fmt, \
+ (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
+ ((VALUE*[]){__VA_ARGS__})), \
+ (rb_scan_args)(argc, argvp, fmt, __VA_ARGS__))
+# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(fmt), \
+ rb_scan_args_kw0( \
+ kw_flag, argc, argvp, fmt, \
+ (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
+ ((VALUE*[]){__VA_ARGS__})), \
+ (rb_scan_args_kw)(kw_flag, argc, argvp, fmt, __VA_ARGS__ /**/))
+#endif
+
+#endif /* RBIMPL_SCAN_ARGS_H */
diff --git a/include/ruby/internal/special_consts.h b/include/ruby/internal/special_consts.h
new file mode 100644
index 0000000000..f36a230af2
--- /dev/null
+++ b/include/ruby/internal/special_consts.h
@@ -0,0 +1,204 @@
+#ifndef RBIMPL_SPECIAL_CONSTS_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_SPECIAL_CONSTS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines enum ::ruby_special_consts.
+ * @see Sasada, K., "A Lighweight Representation of Floting-Point
+ * Numbers on Ruby Interpreter", in proceedings of 10th JSSST
+ * SIGPPL Workshop on Programming and Programming Languages
+ * (PPL2008), pp. 9-16, 2008.
+ */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/const.h"
+#include "ruby/internal/attr/constexpr.h"
+#include "ruby/internal/attr/enum_extensibility.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+
+#if defined(USE_FLONUM)
+# /* Take that. */
+#elif SIZEOF_VALUE >= SIZEOF_DOUBLE
+# define USE_FLONUM 1
+#else
+# define USE_FLONUM 0
+#endif
+
+#define RTEST RB_TEST
+
+#define FIXNUM_P RB_FIXNUM_P
+#define IMMEDIATE_P RB_IMMEDIATE_P
+#define NIL_P RB_NIL_P
+#define SPECIAL_CONST_P RB_SPECIAL_CONST_P
+#define STATIC_SYM_P RB_STATIC_SYM_P
+
+#define Qfalse RUBY_Qfalse
+#define Qnil RUBY_Qnil
+#define Qtrue RUBY_Qtrue
+#define Qundef RUBY_Qundef
+
+/** @cond INTERNAL_MACRO */
+#define FIXNUM_FLAG RUBY_FIXNUM_FLAG
+#define FLONUM_FLAG RUBY_FLONUM_FLAG
+#define FLONUM_MASK RUBY_FLONUM_MASK
+#define FLONUM_P RB_FLONUM_P
+#define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK
+#define SYMBOL_FLAG RUBY_SYMBOL_FLAG
+
+#define RB_FIXNUM_P RB_FIXNUM_P
+#define RB_FLONUM_P RB_FLONUM_P
+#define RB_IMMEDIATE_P RB_IMMEDIATE_P
+#define RB_NIL_P RB_NIL_P
+#define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
+#define RB_STATIC_SYM_P RB_STATIC_SYM_P
+#define RB_TEST RB_TEST
+/** @endcond */
+
+/** special constants - i.e. non-zero and non-fixnum constants */
+enum
+RBIMPL_ATTR_ENUM_EXTENSIBILITY(closed)
+ruby_special_consts {
+#if USE_FLONUM
+ RUBY_Qfalse = 0x00, /* ...0000 0000 */
+ RUBY_Qtrue = 0x14, /* ...0001 0100 */
+ RUBY_Qnil = 0x08, /* ...0000 1000 */
+ RUBY_Qundef = 0x34, /* ...0011 0100 */
+ RUBY_IMMEDIATE_MASK = 0x07, /* ...0000 0111 */
+ RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
+ RUBY_FLONUM_MASK = 0x03, /* ...0000 0011 */
+ RUBY_FLONUM_FLAG = 0x02, /* ...xxxx xx10 */
+ RUBY_SYMBOL_FLAG = 0x0c, /* ...xxxx 1100 */
+#else
+ RUBY_Qfalse = 0x00, /* ...0000 0000 */
+ RUBY_Qtrue = 0x02, /* ...0000 0010 */
+ RUBY_Qnil = 0x04, /* ...0000 0100 */
+ RUBY_Qundef = 0x06, /* ...0000 0110 */
+ RUBY_IMMEDIATE_MASK = 0x03, /* ...0000 0011 */
+ RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
+ RUBY_FLONUM_MASK = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
+ RUBY_FLONUM_FLAG = 0x02, /* ...0000 0010 */
+ RUBY_SYMBOL_FLAG = 0x0e, /* ...0000 1110 */
+#endif
+
+ RUBY_SPECIAL_SHIFT = 8 /** Least significant 8 bits are reserved. */
+};
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+/*
+ * :NOTE: rbimpl_test HAS to be `__attribute__((const))` in order for clang to
+ * properly deduce `__builtin_assume()`.
+ */
+static inline bool
+RB_TEST(VALUE obj)
+{
+ /*
+ * Qfalse: ....0000 0000
+ * Qnil: ....0000 1000
+ * ~Qnil: ....1111 0111
+ * v ....xxxx xxxx
+ * ----------------------------
+ * RTEST(v) ....xxxx 0xxx
+ *
+ * RTEST(v) can be 0 if and only if (v == Qfalse || v == Qnil).
+ */
+ return obj & ~RUBY_Qnil;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_NIL_P(VALUE obj)
+{
+ return obj == RUBY_Qnil;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_FIXNUM_P(VALUE obj)
+{
+ return obj & RUBY_FIXNUM_FLAG;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX14)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_STATIC_SYM_P(VALUE obj)
+{
+ RBIMPL_ATTR_CONSTEXPR(CXX14)
+ const VALUE mask = ~(RBIMPL_VALUE_FULL << RUBY_SPECIAL_SHIFT);
+ return (obj & mask) == RUBY_SYMBOL_FLAG;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_FLONUM_P(VALUE obj)
+{
+#if USE_FLONUM
+ return (obj & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG;
+#else
+ return false;
+#endif
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_IMMEDIATE_P(VALUE obj)
+{
+ return obj & RUBY_IMMEDIATE_MASK;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_SPECIAL_CONST_P(VALUE obj)
+{
+ return RB_IMMEDIATE_P(obj) || ! RB_TEST(obj);
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+/* This function is to mimic old rb_special_const_p macro but have anyone
+ * actually used its return value? Wasn't it just something no one needed? */
+static inline VALUE
+rb_special_const_p(VALUE obj)
+{
+ return RB_SPECIAL_CONST_P(obj) * RUBY_Qtrue;
+}
+
+/**
+ * @cond INTERNAL_MACRO
+ * See [ruby-dev:27513] for the following macros.
+ */
+#define RUBY_Qfalse RBIMPL_CAST((VALUE)RUBY_Qfalse)
+#define RUBY_Qtrue RBIMPL_CAST((VALUE)RUBY_Qtrue)
+#define RUBY_Qnil RBIMPL_CAST((VALUE)RUBY_Qnil)
+#define RUBY_Qundef RBIMPL_CAST((VALUE)RUBY_Qundef)
+/** @endcond */
+
+#endif /* RBIMPL_SPECIAL_CONSTS_H */
diff --git a/include/ruby/internal/static_assert.h b/include/ruby/internal/static_assert.h
new file mode 100644
index 0000000000..d4bdadf196
--- /dev/null
+++ b/include/ruby/internal/static_assert.h
@@ -0,0 +1,77 @@
+#ifndef RBIMPL_STATIC_ASSERT_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_STATIC_ASSERT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_STATIC_ASSERT.
+ */
+#include <assert.h>
+#include "ruby/internal/has/extension.h"
+#include "ruby/internal/compiler_since.h"
+
+/** @cond INTERNAL_MACRO */
+#if defined(__cplusplus) && defined(__cpp_static_assert)
+# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */
+# define RBIMPL_STATIC_ASSERT0 static_assert
+
+#elif defined(__cplusplus) && RBIMPL_COMPILER_SINCE(MSVC, 16, 0, 0)
+# define RBIMPL_STATIC_ASSERT0 static_assert
+
+#elif defined(__INTEL_CXX11_MODE__)
+# define RBIMPL_STATIC_ASSERT0 static_assert
+
+#elif defined(__cplusplus) && __cplusplus >= 201103L
+# define RBIMPL_STATIC_ASSERT0 static_assert
+
+#elif defined(__cplusplus) && RBIMPL_HAS_EXTENSION(cxx_static_assert)
+# define RBIMPL_STATIC_ASSERT0 __extension__ static_assert
+
+#elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
+# define RBIMPL_STATIC_ASSERT0 __extension__ static_assert
+
+#elif defined(__STDC_VERSION__) && RBIMPL_HAS_EXTENSION(c_static_assert)
+# define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert
+
+#elif defined(__STDC_VERSION__) && RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
+# define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert
+
+#elif defined(static_assert)
+# /* Take <assert.h> definition */
+# define RBIMPL_STATIC_ASSERT0 static_assert
+#endif
+/** @endcond */
+
+/**
+ * @brief Wraps (or simulates) `static_assert`
+ * @param name Valid C/C++ identifier, describing the assertion.
+ * @param expr Expression to assert.
+ * @note `name` shall not be a string literal.
+ */
+#if defined(__DOXYGEN__)
+# define RBIMPL_STATIC_ASSERT static_assert
+
+#elif defined(RBIMPL_STATIC_ASSERT0)
+# define RBIMPL_STATIC_ASSERT(name, expr) \
+ RBIMPL_STATIC_ASSERT0(expr, # name ": " # expr)
+
+#else
+# define RBIMPL_STATIC_ASSERT(name, expr) \
+ typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)]
+#endif
+
+#endif /* RBIMPL_STATIC_ASSERT_H */
diff --git a/include/ruby/internal/stdalign.h b/include/ruby/internal/stdalign.h
new file mode 100644
index 0000000000..02eb7ab959
--- /dev/null
+++ b/include/ruby/internal/stdalign.h
@@ -0,0 +1,133 @@
+#ifndef RBIMPL_STDALIGN_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_STDALIGN_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ALIGNAS / #RBIMPL_ALIGNOF
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#include "ruby/internal/compiler_is.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/declspec_attribute.h"
+#include "ruby/internal/has/feature.h"
+
+/**
+ * Wraps (or simulates) `alignas`. This is C++11's `alignas` and is _different_
+ * from C11 `_Alignas`. For instance,
+ *
+ * ```CXX
+ * typedef struct alignas(128) foo { int foo } foo;
+ * ```
+ *
+ * is a valid C++ while
+ *
+ * ```C
+ * typedef struct _Alignas(128) foo { int foo } foo;
+ * ```
+ *
+ * is an invalid C because:
+ *
+ * - You cannot `struct _Alignas`.
+ * - A `typedef` cannot have alignments.
+ */
+#if defined(__cplusplus) && RBIMPL_HAS_FEATURE(cxx_alignas)
+# define RBIMPL_ALIGNAS alignas
+
+#elif defined(__cplusplus) && (__cplusplus >= 201103L)
+# define RBIMPL_ALIGNAS alignas
+
+#elif defined(__INTEL_CXX11_MODE__)
+# define RBIMPL_ALIGNAS alignas
+
+#elif defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define RBIMPL_ALIGNAS alignas
+
+#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(align)
+# define RBIMPL_ALIGNAS(_) __declspec(align(_))
+
+#elif RBIMPL_HAS_ATTRIBUTE(aligned)
+# define RBIMPL_ALIGNAS(_) __attribute__((__aligned__(_)))
+
+#else
+# define RBIMPL_ALIGNAS(_) /* void */
+#endif
+
+/**
+ * Wraps (or simulates) `alignof`.
+ *
+ * We want C11's `_Alignof`. However in spite of its clear language, compilers
+ * (including GCC and clang) tend to have buggy implementations. We have to
+ * avoid such things to resort to our own version.
+ *
+ * @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023
+ * @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560
+ * @see https://bugs.llvm.org/show_bug.cgi?id=26547
+ */
+#if defined(__cplusplus)
+# /* C++11 `alignof()` can be buggy. */
+# /* see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 */
+# /* But don't worry, we can use templates. */
+# define RBIMPL_ALIGNOF(T) (static_cast<size_t>(ruby::rbimpl_alignof<T>::value))
+
+namespace ruby {
+template<typename T>
+struct rbimpl_alignof {
+ typedef struct {
+ char _;
+ T t;
+ } type;
+
+ enum {
+ value = offsetof(type, t)
+ };
+};
+}
+
+#elif RBIMPL_COMPILER_IS(MSVC)
+# /* Windows have no alignment glitch.*/
+# define RBIMPL_ALIGNOF __alignof
+
+#elif defined(HAVE__ALIGNOF)
+# /* Autoconf detected availability of a sane `_Alignof()`. */
+# define RBIMPL_ALIGNOF(T) RB_GNUC_EXTENSION(_Alignof(T))
+
+#else
+# /* :BEWARE: This is the last resort. If your compiler somehow supports
+# * querying the alignment of a type, you definitely should use that instead.
+# * There are 2 known pitfalls for this fallback implementation:
+# *
+# * First, it is either an undefined behaviour (C) or an explicit error (C++)
+# * to define a struct inside of `offsetof`. C compilers tend to accept such
+# * things, but AFAIK C++ has no room to allow.
+# *
+# * Second, there exist T such that `struct { char _; T t; }` is invalid. A
+# * known example is when T is a struct with a flexible array member. Such
+# * struct cannot be enclosed into another one.
+# */
+# /* see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2083.htm */
+# /* see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm */
+# define RBIMPL_ALIGNOF(T) offsetof(struct { char _; T t; }, t)
+
+#endif
+
+#endif /* RBIMPL_STDALIGN_H */
diff --git a/include/ruby/internal/stdbool.h b/include/ruby/internal/stdbool.h
new file mode 100644
index 0000000000..0cd5103a05
--- /dev/null
+++ b/include/ruby/internal/stdbool.h
@@ -0,0 +1,51 @@
+#ifndef RBIMPL_STDBOOL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_STDBOOL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief C99 shim for <stdbool.h>
+ */
+#include "ruby/internal/config.h"
+
+#if defined(__bool_true_false_are_defined)
+# /* Take that. */
+
+#elif defined(__cplusplus)
+# /* bool is a keyword in C++. */
+# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L)
+# include <cstdbool>
+# endif
+#
+# ifndef __bool_true_false_are_defined
+# define __bool_true_false_are_defined
+# endif
+
+#elif defined(HAVE_STDBOOL_H)
+# /* Take stdbool.h definition. */
+# include <stdbool.h>
+
+#else
+typedef unsigned char _Bool;
+# /* See also http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2229.htm */
+# define bool _Bool
+# define true ((_Bool)+1)
+# define false ((_Bool)+0)
+# define __bool_true_false_are_defined
+#endif
+
+#endif /* RBIMPL_STDBOOL_H */
diff --git a/include/ruby/internal/symbol.h b/include/ruby/internal/symbol.h
new file mode 100644
index 0000000000..762f1e8f9b
--- /dev/null
+++ b/include/ruby/internal/symbol.h
@@ -0,0 +1,114 @@
+#ifndef RBIMPL_SYMBOL_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_SYMBOL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #rb_intern
+ */
+#include "ruby/internal/config.h"
+
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/attr/noalias.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/constant_p.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/has/builtin.h"
+#include "ruby/internal/value.h"
+
+#define RB_ID2SYM rb_id2sym
+#define RB_SYM2ID rb_sym2id
+#define ID2SYM RB_ID2SYM
+#define SYM2ID RB_SYM2ID
+#define CONST_ID_CACHE RUBY_CONST_ID_CACHE
+#define CONST_ID RUBY_CONST_ID
+
+/** @cond INTERNAL_MACRO */
+#define rb_intern_const rb_intern_const
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+ID rb_sym2id(VALUE);
+VALUE rb_id2sym(ID);
+ID rb_intern(const char*);
+ID rb_intern2(const char*, long);
+ID rb_intern_str(VALUE str);
+const char *rb_id2name(ID);
+ID rb_check_id(volatile VALUE *);
+ID rb_to_id(VALUE);
+VALUE rb_id2str(ID);
+VALUE rb_sym2str(VALUE);
+VALUE rb_to_symbol(VALUE name);
+VALUE rb_check_symbol(volatile VALUE *namep);
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE()
+RBIMPL_ATTR_NONNULL(())
+static inline ID
+rb_intern_const(const char *str)
+{
+ size_t len = strlen(str);
+ return rb_intern2(str, RBIMPL_CAST((long)len));
+}
+
+RBIMPL_ATTR_NOALIAS()
+RBIMPL_ATTR_NONNULL(())
+static inline ID
+rbimpl_intern_const(ID *ptr, const char *str)
+{
+ while (! *ptr) {
+ *ptr = rb_intern_const(str);
+ }
+
+ return *ptr;
+}
+
+/* Does anyone use it? Preserved for backward compat. */
+#define RUBY_CONST_ID_CACHE(result, str) \
+ { \
+ static ID rb_intern_id_cache; \
+ rbimpl_intern_const(&rb_intern_id_cache, (str)); \
+ result rb_intern_id_cache; \
+ }
+#define RUBY_CONST_ID(var, str) \
+ do { \
+ static ID rbimpl_id; \
+ (var) = rbimpl_intern_const(&rbimpl_id, (str)); \
+ } while (0)
+
+#if defined(HAVE_STMT_AND_DECL_IN_EXPR)
+/* __builtin_constant_p and statement expression is available
+ * since gcc-2.7.2.3 at least. */
+#define rb_intern(str) \
+ (RBIMPL_CONSTANT_P(str) ? \
+ __extension__ ({ \
+ static ID rbimpl_id; \
+ rbimpl_intern_const(&rbimpl_id, (str)); \
+ }) : \
+ (rb_intern)(str))
+#endif
+
+#endif /* RBIMPL_SYMBOL_H */
diff --git a/include/ruby/internal/token_paste.h b/include/ruby/internal/token_paste.h
new file mode 100644
index 0000000000..c42f7a67ef
--- /dev/null
+++ b/include/ruby/internal/token_paste.h
@@ -0,0 +1,75 @@
+#ifndef RBIMPL_TOKEN_PASTE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_TOKEN_PASTE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_TOKEN_PASTE.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/warning.h"
+#include "ruby/internal/warning_push.h"
+
+/* :TODO: add your compiler here. There are many compilers that can suppress
+ * warnings via pragmas, but not all of them accept such things inside of `#if`
+ * and variants' conditions. And such nitpicking behavours tend not be
+ * documented. Please improve this file when you are really sure about your
+ * compiler's behaviour. */
+
+#if RBIMPL_COMPILER_SINCE(GCC, 4, 2, 0)
+# /* GCC is one of such compiler who cannot write `_Pragma` inside of a `#if`.
+# * Cannot but globally kill everything. This is of course a very bad thing.
+# * If you know how to reroute this please tell us. */
+# /* https://gcc.godbolt.org/z/K2xr7X */
+# define RBIMPL_TOKEN_PASTE(x, y) TOKEN_PASTE(x, y)
+# pragma GCC diagnostic ignored "-Wundef"
+# /* > warning: "symbol" is not defined, evaluates to 0 [-Wundef] */
+
+#elif RBIMPL_COMPILER_IS(Intel)
+# /* Ditto for icc. */
+# /* https://gcc.godbolt.org/z/pTwDxE */
+# define RBIMPL_TOKEN_PASTE(x, y) TOKEN_PASTE(x, y)
+# pragma warning(disable: 193)
+# /* > warning #193: zero used for undefined preprocessing identifier */
+
+#elif RBIMPL_COMPILER_BEFORE(MSVC, 19, 14, 26428)
+# /* :FIXME: is 19.14 the exact version they supported this? */
+# define RBIMPL_TOKEN_PASTE(x, y) TOKEN_PASTE(x, y)
+# pragma warning(disable: 4668)
+# /* > warning C4668: 'symbol' is not defined as a preprocessor macro */
+
+#elif RBIMPL_COMPILER_IS(MSVC)
+# define RBIMPL_TOKEN_PASTE(x, y) \
+ RBIMPL_WARNING_PUSH() \
+ RBIMPL_WARNING_IGNORED(4668) \
+ TOKEN_PASTE(x, y) \
+ RBIMPL_WARNING_POP()
+
+#elif RBIMPL_HAS_WARNING("-Wundef")
+# define RBIMPL_TOKEN_PASTE(x, y) \
+ RBIMPL_WARNING_PUSH() \
+ RBIMPL_WARNING_IGNORED(-Wundef) \
+ TOKEN_PASTE(x, y) \
+ RBIMPL_WARNING_POP()
+
+#else
+# /* No way. */
+# define RBIMPL_TOKEN_PASTE(x, y) TOKEN_PASTE(x, y)
+#endif
+
+#endif /* RBIMPL_TOKEN_PASTE_H */
diff --git a/include/ruby/internal/value.h b/include/ruby/internal/value.h
new file mode 100644
index 0000000000..b87fe140af
--- /dev/null
+++ b/include/ruby/internal/value.h
@@ -0,0 +1,66 @@
+#ifndef RBIMPL_VALUE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_VALUE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines ::VALUE and ::ID.
+ */
+#include "ruby/internal/static_assert.h"
+#include "ruby/backward/2/long_long.h"
+#include "ruby/backward/2/limits.h"
+
+#if defined HAVE_UINTPTR_T && 0
+typedef uintptr_t VALUE;
+typedef uintptr_t ID;
+# define SIGNED_VALUE intptr_t
+# define SIZEOF_VALUE SIZEOF_UINTPTR_T
+# undef PRI_VALUE_PREFIX
+# define RBIMPL_VALUE_NULL UINTPTR_C(0)
+# define RBIMPL_VALUE_ONE UINTPTR_C(1)
+# define RBIMPL_VALUE_FULL UINTPTR_MAX
+
+#elif SIZEOF_LONG == SIZEOF_VOIDP
+typedef unsigned long VALUE;
+typedef unsigned long ID;
+# define SIGNED_VALUE long
+# define SIZEOF_VALUE SIZEOF_LONG
+# define PRI_VALUE_PREFIX "l"
+# define RBIMPL_VALUE_NULL 0UL
+# define RBIMPL_VALUE_ONE 1UL
+# define RBIMPL_VALUE_FULL ULONG_MAX
+
+#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
+typedef unsigned LONG_LONG VALUE;
+typedef unsigned LONG_LONG ID;
+# define SIGNED_VALUE LONG_LONG
+# define LONG_LONG_VALUE 1
+# define SIZEOF_VALUE SIZEOF_LONG_LONG
+# define PRI_VALUE_PREFIX PRI_LL_PREFIX
+# define RBIMPL_VALUE_NULL 0ULL
+# define RBIMPL_VALUE_ONE 1ULL
+# define RBIMPL_VALUE_FULL ULLONG_MAX
+
+#else
+# error ---->> ruby requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
+#endif
+
+RBIMPL_STATIC_ASSERT(sizeof_int, SIZEOF_INT == sizeof(int));
+RBIMPL_STATIC_ASSERT(sizeof_long, SIZEOF_LONG == sizeof(long));
+RBIMPL_STATIC_ASSERT(sizeof_long_long, SIZEOF_LONG_LONG == sizeof(LONG_LONG));
+RBIMPL_STATIC_ASSERT(sizeof_voidp, SIZEOF_VOIDP == sizeof(void *));
+#endif /* RBIMPL_VALUE_H */
diff --git a/include/ruby/internal/value_type.h b/include/ruby/internal/value_type.h
new file mode 100644
index 0000000000..6f24f08910
--- /dev/null
+++ b/include/ruby/internal/value_type.h
@@ -0,0 +1,354 @@
+#ifndef RBIMPL_VALUE_TYPE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_VALUE_TYPE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines enum ::ruby_value_type.
+ */
+#include "ruby/internal/assume.h"
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/cold.h"
+#include "ruby/internal/attr/enum_extensibility.h"
+#include "ruby/internal/attr/forceinline.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/cast.h"
+#include "ruby/internal/constant_p.h"
+#include "ruby/internal/core/rbasic.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/has/builtin.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+
+#if defined(T_DATA)
+/*
+ * :!BEWARE!: (Recent?) Solaris' <nfs/nfs.h> have conflicting definition of
+ * T_DATA. Let us stop here. Please have a workaround like this:
+ *
+ * ```C
+ * #include <ruby/ruby.h> // <- Include this one first.
+ * #undef T_DATA // <- ... and stick to RUBY_T_DATA forever.
+ * #include <nfs/nfs.h> // <- OS-provided T_DATA introduced.
+ * ```
+ *
+ * See also [ruby-core:4261]
+ */
+# error Bail out due to conflicting definition of T_DATA.
+#endif
+
+#define T_ARRAY RUBY_T_ARRAY
+#define T_BIGNUM RUBY_T_BIGNUM
+#define T_CLASS RUBY_T_CLASS
+#define T_COMPLEX RUBY_T_COMPLEX
+#define T_DATA RUBY_T_DATA
+#define T_FALSE RUBY_T_FALSE
+#define T_FILE RUBY_T_FILE
+#define T_FIXNUM RUBY_T_FIXNUM
+#define T_FLOAT RUBY_T_FLOAT
+#define T_HASH RUBY_T_HASH
+#define T_ICLASS RUBY_T_ICLASS
+#define T_IMEMO RUBY_T_IMEMO
+#define T_MASK RUBY_T_MASK
+#define T_MATCH RUBY_T_MATCH
+#define T_MODULE RUBY_T_MODULE
+#define T_MOVED RUBY_T_MOVED
+#define T_NIL RUBY_T_NIL
+#define T_NODE RUBY_T_NODE
+#define T_NONE RUBY_T_NONE
+#define T_OBJECT RUBY_T_OBJECT
+#define T_RATIONAL RUBY_T_RATIONAL
+#define T_REGEXP RUBY_T_REGEXP
+#define T_STRING RUBY_T_STRING
+#define T_STRUCT RUBY_T_STRUCT
+#define T_SYMBOL RUBY_T_SYMBOL
+#define T_TRUE RUBY_T_TRUE
+#define T_UNDEF RUBY_T_UNDEF
+#define T_ZOMBIE RUBY_T_ZOMBIE
+
+#define BUILTIN_TYPE RB_BUILTIN_TYPE
+#define DYNAMIC_SYM_P RB_DYNAMIC_SYM_P
+#define RB_INTEGER_TYPE_P rb_integer_type_p
+#define SYMBOL_P RB_SYMBOL_P
+#define rb_type_p RB_TYPE_P
+
+/** @cond INTERNAL_MACRO */
+#define RB_BUILTIN_TYPE RB_BUILTIN_TYPE
+#define RB_DYNAMIC_SYM_P RB_DYNAMIC_SYM_P
+#define RB_FLOAT_TYPE_P RB_FLOAT_TYPE_P
+#define RB_SYMBOL_P RB_SYMBOL_P
+#define RB_TYPE_P RB_TYPE_P
+#define Check_Type Check_Type
+
+#if !RUBY_DEBUG
+# define RBIMPL_ASSERT_TYPE(v, t) RBIMPL_ASSERT_OR_ASSUME(RB_TYPE_P((v), (t)))
+#else
+# define RBIMPL_ASSERT_TYPE Check_Type
+#endif
+/** @endcond */
+
+#define TYPE(_) RBIMPL_CAST((int)rb_type(_))
+
+/** C-level type of an object. */
+enum
+RBIMPL_ATTR_ENUM_EXTENSIBILITY(closed)
+ruby_value_type {
+ RUBY_T_NONE = 0x00, /**< Non-object (sweeped etc.) */
+
+ RUBY_T_OBJECT = 0x01, /**< @see struct ::RObject */
+ RUBY_T_CLASS = 0x02, /**< @see struct ::RClass and ::rb_cClass */
+ RUBY_T_MODULE = 0x03, /**< @see struct ::RClass and ::rb_cModule */
+ RUBY_T_FLOAT = 0x04, /**< @see struct ::RFloat */
+ RUBY_T_STRING = 0x05, /**< @see struct ::RString */
+ RUBY_T_REGEXP = 0x06, /**< @see struct ::RRegexp */
+ RUBY_T_ARRAY = 0x07, /**< @see struct ::RArray */
+ RUBY_T_HASH = 0x08, /**< @see struct ::RHash */
+ RUBY_T_STRUCT = 0x09, /**< @see struct ::RStruct */
+ RUBY_T_BIGNUM = 0x0a, /**< @see struct ::RBignum */
+ RUBY_T_FILE = 0x0b, /**< @see struct ::RFile */
+ RUBY_T_DATA = 0x0c, /**< @see struct ::RTypedData */
+ RUBY_T_MATCH = 0x0d, /**< @see struct ::RMatch */
+ RUBY_T_COMPLEX = 0x0e, /**< @see struct ::RComplex */
+ RUBY_T_RATIONAL = 0x0f, /**< @see struct ::RRational */
+
+ RUBY_T_NIL = 0x11, /**< @see ::RUBY_Qnil */
+ RUBY_T_TRUE = 0x12, /**< @see ::RUBY_Qfalse */
+ RUBY_T_FALSE = 0x13, /**< @see ::RUBY_Qtrue */
+ RUBY_T_SYMBOL = 0x14, /**< @see struct ::RSymbol */
+ RUBY_T_FIXNUM = 0x15, /**< Integers formerly known as Fixnums. */
+ RUBY_T_UNDEF = 0x16, /**< @see ::RUBY_Qundef */
+
+ RUBY_T_IMEMO = 0x1a, /**< @see struct ::RIMemo */
+ RUBY_T_NODE = 0x1b, /**< @see struct ::RNode */
+ RUBY_T_ICLASS = 0x1c, /**< Hidden classes known as IClasses. */
+ RUBY_T_ZOMBIE = 0x1d, /**< @see struct ::RZombie */
+ RUBY_T_MOVED = 0x1e, /**< @see struct ::RMoved */
+
+ RUBY_T_MASK = 0x1f
+};
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+RBIMPL_ATTR_COLD()
+void rb_check_type(VALUE obj, int t);
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline enum ruby_value_type
+RB_BUILTIN_TYPE(VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
+
+ VALUE ret = RBASIC(obj)->flags & RUBY_T_MASK;
+ return RBIMPL_CAST((enum ruby_value_type)ret);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+static inline bool
+rb_integer_type_p(VALUE obj)
+{
+ if (RB_FIXNUM_P(obj)) {
+ return true;
+ }
+ else if (RB_SPECIAL_CONST_P(obj)) {
+ return false;
+ }
+ else {
+ return RB_BUILTIN_TYPE(obj) == RUBY_T_BIGNUM;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+static inline enum ruby_value_type
+rb_type(VALUE obj)
+{
+ if (! RB_SPECIAL_CONST_P(obj)) {
+ return RB_BUILTIN_TYPE(obj);
+ }
+ else if (obj == RUBY_Qfalse) {
+ return RUBY_T_FALSE;
+ }
+ else if (obj == RUBY_Qnil) {
+ return RUBY_T_NIL;
+ }
+ else if (obj == RUBY_Qtrue) {
+ return RUBY_T_TRUE;
+ }
+ else if (obj == RUBY_Qundef) {
+ return RUBY_T_UNDEF;
+ }
+ else if (RB_FIXNUM_P(obj)) {
+ return RUBY_T_FIXNUM;
+ }
+ else if (RB_STATIC_SYM_P(obj)) {
+ return RUBY_T_SYMBOL;
+ }
+ else {
+ RBIMPL_ASSUME(RB_FLONUM_P(obj));
+ return RUBY_T_FLOAT;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_FLOAT_TYPE_P(VALUE obj)
+{
+ if (RB_FLONUM_P(obj)) {
+ return true;
+ }
+ else if (RB_SPECIAL_CONST_P(obj)) {
+ return false;
+ }
+ else {
+ return RB_BUILTIN_TYPE(obj) == RUBY_T_FLOAT;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_DYNAMIC_SYM_P(VALUE obj)
+{
+ if (RB_SPECIAL_CONST_P(obj)) {
+ return false;
+ }
+ else {
+ return RB_BUILTIN_TYPE(obj) == RUBY_T_SYMBOL;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_SYMBOL_P(VALUE obj)
+{
+ return RB_STATIC_SYM_P(obj) || RB_DYNAMIC_SYM_P(obj);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+RBIMPL_ATTR_FORCEINLINE()
+static bool
+rbimpl_RB_TYPE_P_fastpath(VALUE obj, enum ruby_value_type t)
+{
+ if (t == RUBY_T_TRUE) {
+ return obj == RUBY_Qtrue;
+ }
+ else if (t == RUBY_T_FALSE) {
+ return obj == RUBY_Qfalse;
+ }
+ else if (t == RUBY_T_NIL) {
+ return obj == RUBY_Qnil;
+ }
+ else if (t == RUBY_T_UNDEF) {
+ return obj == RUBY_Qundef;
+ }
+ else if (t == RUBY_T_FIXNUM) {
+ return RB_FIXNUM_P(obj);
+ }
+ else if (t == RUBY_T_SYMBOL) {
+ return RB_SYMBOL_P(obj);
+ }
+ else if (t == RUBY_T_FLOAT) {
+ return RB_FLOAT_TYPE_P(obj);
+ }
+ else if (RB_SPECIAL_CONST_P(obj)) {
+ return false;
+ }
+ else if (t == RB_BUILTIN_TYPE(obj)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline bool
+RB_TYPE_P(VALUE obj, enum ruby_value_type t)
+{
+ if (RBIMPL_CONSTANT_P(t)) {
+ return rbimpl_RB_TYPE_P_fastpath(obj, t);
+ }
+ else {
+ return t == rb_type(obj);
+ }
+}
+
+/** @cond INTERNAL_MACRO */
+/* Clang, unlike GCC, cannot propagate __builtin_constant_p beyond function
+ * boundary. */
+#if defined(__clang__)
+# undef RB_TYPE_P
+# define RB_TYPE_P(obj, t) \
+ (RBIMPL_CONSTANT_P(t) ? \
+ rbimpl_RB_TYPE_P_fastpath((obj), (t)) : \
+ (RB_TYPE_P)((obj), (t)))
+#endif
+
+/* clang 3.x (4.2 compatible) can't eliminate CSE of RB_BUILTIN_TYPE
+ * in inline function and caller function
+ * See also 8998c06461ea0bef11b3aeb30b6d2ab71c8762ba
+ */
+#if RBIMPL_COMPILER_BEFORE(Clang, 4, 0, 0)
+# undef rb_integer_type_p
+# define rb_integer_type_p(obj) \
+ __extension__ ({ \
+ const VALUE integer_type_obj = (obj); \
+ (RB_FIXNUM_P(integer_type_obj) || \
+ (!RB_SPECIAL_CONST_P(integer_type_obj) && \
+ RB_BUILTIN_TYPE(integer_type_obj) == RUBY_T_BIGNUM)); \
+ })
+#endif
+/** @endcond */
+
+RBIMPL_ATTR_PURE()
+RBIMPL_ATTR_ARTIFICIAL()
+/* Defined in ruby/internal/core/rtypeddata.h */
+static inline bool rbimpl_rtypeddata_p(VALUE obj);
+
+RBIMPL_ATTR_ARTIFICIAL()
+static inline void
+Check_Type(VALUE v, enum ruby_value_type t)
+{
+ if (RB_UNLIKELY(! RB_TYPE_P(v, t))) {
+ goto slowpath;
+ }
+ else if (t != RUBY_T_DATA) {
+ goto fastpath;
+ }
+ else if (rbimpl_rtypeddata_p(v)) {
+ /* The intention itself is not necessarily clear to me, but at least it
+ * is intentional to rule out typed data here. See commit
+ * a7c32bf81d3391cfb78cfda278f469717d0fb794. */
+ goto slowpath;
+ }
+ else {
+ goto fastpath;
+ }
+
+ fastpath:
+ return;
+
+ slowpath: /* <- :TODO: mark this label as cold. */
+ rb_check_type(v, t);
+}
+
+#endif /* RBIMPL_VALUE_TYPE_H */
diff --git a/include/ruby/internal/variable.h b/include/ruby/internal/variable.h
new file mode 100644
index 0000000000..b0cfa61a62
--- /dev/null
+++ b/include/ruby/internal/variable.h
@@ -0,0 +1,62 @@
+#ifndef RBIMPL_VARIABLE_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_VARIABLE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief C-function backended Ruby-global variables.
+ */
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/attr/noreturn.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+typedef VALUE rb_gvar_getter_t(ID id, VALUE *data);
+typedef void rb_gvar_setter_t(VALUE val, ID id, VALUE *data);
+typedef void rb_gvar_marker_t(VALUE *var);
+
+rb_gvar_getter_t rb_gvar_undef_getter;
+rb_gvar_setter_t rb_gvar_undef_setter;
+rb_gvar_marker_t rb_gvar_undef_marker;
+
+rb_gvar_getter_t rb_gvar_val_getter;
+rb_gvar_setter_t rb_gvar_val_setter;
+rb_gvar_marker_t rb_gvar_val_marker;
+
+rb_gvar_getter_t rb_gvar_var_getter;
+rb_gvar_setter_t rb_gvar_var_setter;
+rb_gvar_marker_t rb_gvar_var_marker;
+
+RBIMPL_ATTR_NORETURN()
+rb_gvar_setter_t rb_gvar_readonly_setter;
+
+void rb_define_variable(const char*,VALUE*);
+void rb_define_virtual_variable(const char*,rb_gvar_getter_t*,rb_gvar_setter_t*);
+void rb_define_hooked_variable(const char*,VALUE*,rb_gvar_getter_t*,rb_gvar_setter_t*);
+void rb_define_readonly_variable(const char*,const VALUE*);
+void rb_define_const(VALUE,const char*,VALUE);
+void rb_define_global_const(const char*,VALUE);
+
+VALUE rb_gv_set(const char*, VALUE);
+VALUE rb_gv_get(const char*);
+VALUE rb_iv_get(VALUE, const char*);
+VALUE rb_iv_set(VALUE, const char*, VALUE);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_VARIABLE_H */
diff --git a/include/ruby/internal/warning_push.h b/include/ruby/internal/warning_push.h
new file mode 100644
index 0000000000..b8a21aaeab
--- /dev/null
+++ b/include/ruby/internal/warning_push.h
@@ -0,0 +1,91 @@
+#ifndef RBIMPL_WARNING_PUSH_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_WARNING_PUSH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines RBIMPL_WARNING_PUSH.
+ * @cond INTERNAL_MACRO
+ *
+ * ### Q&A ###
+ *
+ * Q: Why all the macros defined in this file are function-like macros?
+ *
+ * A: Sigh. This is because of Doxgen. Its `SKIP_FUNCTION_MACROS = YES`
+ * configuration setting requests us that if we want it to ignore these
+ * macros, then we have to do two things: (1) let them be defined as
+ * function-like macros, and (2) place them separately in their own line,
+ * like below:
+ *
+ * ```CXX
+ * // NG -- foo's type considered something like `unsigned int`.
+ * RBIMPL_WARNING_PUSH
+ * int foo(void);
+ * RBIMPL_WARNING_POP
+ *
+ * // OK -- the macros are ignored by Doxygen.
+ * RBIMPL_WARNING_PUSH()
+ * int foo(void);
+ * RBIMPL_WARNING_POP()
+ * ```
+ */
+#include "ruby/internal/compiler_is.h"
+#include "ruby/internal/compiler_since.h"
+
+#if RBIMPL_COMPILER_SINCE(MSVC, 12, 0, 0)
+# /* Not sure exactly when but it seems VC++ 6.0 is a version with it.*/
+# define RBIMPL_WARNING_PUSH() __pragma(warning(push))
+# define RBIMPL_WARNING_POP() __pragma(warning(pop))
+# define RBIMPL_WARNING_ERROR(flag) __pragma(warning(error: flag))
+# define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))
+
+#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
+# define RBIMPL_WARNING_PUSH() __pragma(warning(push))
+# define RBIMPL_WARNING_POP() __pragma(warning(pop))
+# define RBIMPL_WARNING_ERROR(flag) __pragma(warning(error: flag))
+# define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))
+
+#elif RBIMPL_COMPILER_IS(Clang) || RBIMPL_COMPILER_IS(Apple)
+# /* Not sure exactly when but it seems LLVM 2.6.0 is a version with it. */
+# define RBIMPL_WARNING_PRAGMA0(x) _Pragma(# x)
+# define RBIMPL_WARNING_PRAGMA1(x) RBIMPL_WARNING_PRAGMA0(clang diagnostic x)
+# define RBIMPL_WARNING_PRAGMA2(x, y) RBIMPL_WARNING_PRAGMA1(x # y)
+# define RBIMPL_WARNING_PUSH() RBIMPL_WARNING_PRAGMA1(push)
+# define RBIMPL_WARNING_POP() RBIMPL_WARNING_PRAGMA1(pop)
+# define RBIMPL_WARNING_ERROR(flag) RBIMPL_WARNING_PRAGMA2(error, flag)
+# define RBIMPL_WARNING_IGNORED(flag) RBIMPL_WARNING_PRAGMA2(ignored, flag)
+
+#elif RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
+# /* https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html */
+# define RBIMPL_WARNING_PRAGMA0(x) _Pragma(# x)
+# define RBIMPL_WARNING_PRAGMA1(x) RBIMPL_WARNING_PRAGMA0(GCC diagnostic x)
+# define RBIMPL_WARNING_PRAGMA2(x, y) RBIMPL_WARNING_PRAGMA1(x # y)
+# define RBIMPL_WARNING_PUSH() RBIMPL_WARNING_PRAGMA1(push)
+# define RBIMPL_WARNING_POP() RBIMPL_WARNING_PRAGMA1(pop)
+# define RBIMPL_WARNING_ERROR(flag) RBIMPL_WARNING_PRAGMA2(error, flag)
+# define RBIMPL_WARNING_IGNORED(flag) RBIMPL_WARNING_PRAGMA2(ignored, flag)
+
+#else
+# /* :FIXME: improve here */
+# define RBIMPL_WARNING_PUSH() /* void */
+# define RBIMPL_WARNING_POP() /* void */
+# define RBIMPL_WARNING_ERROR(flag) /* void */
+# define RBIMPL_WARNING_IGNORED(flag) /* void */
+#endif /* _MSC_VER */
+/** @endcond */
+
+#endif /* RBIMPL_WARNING_PUSH_H */
diff --git a/include/ruby/internal/xmalloc.h b/include/ruby/internal/xmalloc.h
new file mode 100644
index 0000000000..76da1eb099
--- /dev/null
+++ b/include/ruby/internal/xmalloc.h
@@ -0,0 +1,362 @@
+#ifndef RBIMPL_XMALLOC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_XMALLOC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Declares ::ruby_xmalloc().
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#include "ruby/internal/attr/alloc_size.h"
+#include "ruby/internal/attr/nodiscard.h"
+#include "ruby/internal/attr/noexcept.h"
+#include "ruby/internal/attr/restrict.h"
+#include "ruby/internal/attr/returns_nonnull.h"
+#include "ruby/internal/dllexport.h"
+
+#ifndef USE_GC_MALLOC_OBJ_INFO_DETAILS
+# define USE_GC_MALLOC_OBJ_INFO_DETAILS 0
+#endif
+
+#define xmalloc ruby_xmalloc
+#define xmalloc2 ruby_xmalloc2
+#define xcalloc ruby_xcalloc
+#define xrealloc ruby_xrealloc
+#define xrealloc2 ruby_xrealloc2
+#define xfree ruby_xfree
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((1))
+/**
+ * Allocates a storage instance. It is largely the same as system malloc(),
+ * except:
+ *
+ * - It raises Ruby exceptions instead of returning NULL, and
+ * - In case of `ENOMEM` it tries to GC to make some room.
+ *
+ * @param[in] size Requested amount of memory.
+ * @exception rb_eNoMemError No space left for `size` bytes allocation.
+ * @return A valid pointer to an allocated storage instance; which has at
+ * least `size` bytes width, with appropriate alignment detected by
+ * the underlying malloc() routine.
+ * @note It doesn't return NULL.
+ * @note Unlike some malloc() implementations, it allocates something and
+ * returns a meaningful value even when `size` is equal to zero.
+ * @warning The return value shall be invalidated exactly once by either
+ * ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
+ * failure to pass it to system free(), because the system and Ruby
+ * might or might not share the same malloc() implementation.
+ */
+void *ruby_xmalloc(size_t size)
+RBIMPL_ATTR_NOEXCEPT(malloc(size))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((1,2))
+/**
+ * Identical to ruby_xmalloc(), except it allocates `nelems` * `elemsiz` bytes.
+ * This is needed because the multiplication could integer overflow. On such
+ * situations Ruby does not try to allocate at all but raises Ruby level
+ * exceptions instead. If there is no integer overflow the behaviour is
+ * exactly the same as `ruby_xmalloc(nelems*elemsiz)`.
+ *
+ * @param[in] nelems Number of elements.
+ * @param[in] elemsiz Size of an element.
+ * @exception rb_eNoMemError No space left for allocation.
+ * @exception rb_eArgError `nelems` * `elemsiz` would overflow.
+ * @return A valid pointer to an allocated storage instance; which has at
+ * least `nelems` * `elemsiz` bytes width, with appropriate
+ * alignment detected by the underlying malloc() routine.
+ * @note It doesn't return NULL.
+ * @note Unlike some malloc() implementations, it allocates something and
+ * returns a meaningful value even when `nelems` or `elemsiz` or
+ * both are zero.
+ * @warning The return value shall be invalidated exactly once by either
+ * ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
+ * failure to pass it to system free(), because the system and Ruby
+ * might or might not share the same malloc() implementation.
+ */
+void *ruby_xmalloc2(size_t nelems, size_t elemsiz)
+RBIMPL_ATTR_NOEXCEPT(malloc(nelems * elemsiz))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((1,2))
+/**
+ * Identical to ruby_xmalloc2(), except it zero-fills the region before it
+ * returns. This could also be seen as a routine identical to ruby_xmalloc(),
+ * except it calls calloc() instead of malloc() internally.
+ *
+ * @param[in] nelems Number of elements.
+ * @param[in] elemsiz Size of an element.
+ * @exception rb_eNoMemError No space left for allocation.
+ * @exception rb_eArgError `nelems` * `elemsiz` would overflow.
+ * @return A valid pointer to an allocated storage instance; which has at
+ * least `nelems` * `elemsiz` bytes width, with appropriate
+ * alignment detected by the underlying calloc() routine.
+ * @note It doesn't return NULL.
+ * @note Unlike some calloc() implementations, it allocates something and
+ * returns a meaningful value even when `nelems` or `elemsiz` or
+ * both are zero.
+ * @warning The return value shall be invalidated exactly once by either
+ * ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
+ * failure to pass it to system free(), because the system and Ruby
+ * might or might not share the same malloc() implementation.
+ */
+void *ruby_xcalloc(size_t nelems, size_t elemsiz)
+RBIMPL_ATTR_NOEXCEPT(calloc(nelems, elemsiz))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((2))
+/**
+ * Resize the storage instance.
+ *
+ * @param[in] ptr A valid pointer to a storage instance that was
+ * previously returned from either ruby_xmalloc(),
+ * ruby_xmalloc2(), ruby_xcalloc(),
+ * ruby_xrealloc(), or ruby_xrealloc2().
+ * @param[in] newsiz Requested new amount of memory.
+ * @exception rb_eNoMemError No space left for `newsiz` bytes allocation.
+ * @retval ptr In case the function returns the passed pointer
+ * as-is, the storage instance that the pointer
+ * holds is either grown or shrunken to have at
+ * least `newsiz` bytes.
+ * @retval otherwise A valid pointer to a newly allocated storage
+ * instance which has at least `newsiz` bytes
+ * width, and holds previous contents of `ptr`. In
+ * this case `ptr` is invalidated as if it was
+ * passed to ruby_xfree().
+ * @note It doesn't return NULL.
+ * @warning Unlike some realloc() implementations, passing zero to `elemsiz`
+ * is not the same as calling ruby_xfree(), because this function
+ * never returns NULL. Something meaningful still returns then.
+ * @warning It is a failure not to check the return value. Do not assume
+ * anything on it. It could be either identical to, or distinct
+ * form the passed argument.
+ * @warning Do not assume anything on the alignment of the return value.
+ * There is no guarantee that it inherits the passed argument's
+ * one.
+ * @warning The return value shall be invalidated exactly once by either
+ * ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
+ * failure to pass it to system free(), because the system and Ruby
+ * might or might not share the same malloc() implementation.
+ */
+void *ruby_xrealloc(void *ptr, size_t newsiz)
+RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newsiz))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((2,3))
+/**
+ * Identical to ruby_xrealloc(), except it resizes the given storage instance
+ * to `newelems` * `newsiz` bytes. This is needed because the multiplication
+ * could integer overflow. On such situations Ruby does not try to touch the
+ * contents of argument pointer at all but raises Ruby level exceptions
+ * instead. If there is no integer overflow the behaviour is exactly the same
+ * as `ruby_xrealloc(ptr,nelems*elemsiz)`.
+ *
+ * This is roughly the same as reallocarray() function that OpenBSD
+ * etc. provides, but also interacts with our GC.
+ *
+ * @param[in] ptr A valid pointer to a storage instance that was
+ * previously returned from either ruby_xmalloc(),
+ * ruby_xmalloc2(), ruby_xcalloc(),
+ * ruby_xrealloc(), or ruby_xrealloc2().
+
+ * @param[in] newelems Requested new number of elements.
+ * @param[in] newsiz Requested new size of each element.
+ * @exception rb_eNoMemError No space left for allocation.
+ * @exception rb_eArgError `newelems` * `newsiz` would overflow.
+ * @retval ptr In case the function returns the passed pointer
+ * as-is, the storage instance that the pointer
+ * holds is either grown or shrunken to have at
+ * least `newelems` * `newsiz` bytes.
+ * @retval otherwise A valid pointer to a newly allocated storage
+ * instance which has at least `newelems` *
+ * `newsiz` bytes width, and holds previous
+ * contents of `ptr`. In this case `ptr` is
+ * invalidated as if it was passed to ruby_xfree().
+ * @note It doesn't return NULL.
+ * @warning Unlike some realloc() implementations, passing zero to either
+ * `newelems` or `elemsiz` are not the same as calling
+ * ruby_xfree(), because this function never returns NULL.
+ * Something meaningful still returns then.
+ * @warning It is a failure not to check the return value. Do not assume
+ * anything on it. It could be either identical to, or distinct
+ * form the passed argument.
+ * @warning Do not assume anything on the alignment of the return value.
+ * There is no guarantee that it inherits the passed argument's
+ * one.
+ * @warning The return value shall be invalidated exactly once by either
+ * ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
+ * failure to pass it to system free(), because the system and Ruby
+ * might or might not share the same malloc() implementation.
+ */
+void *ruby_xrealloc2(void *ptr, size_t newelems, size_t newsiz)
+RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newelems * newsiz))
+;
+
+/**
+ * Deallocates a storage instance.
+ *
+ * @param[out] ptr Either NULL, or a valid pointer previously returned from
+ * one of ruby_xmalloc(), ruby_xmalloc2(), ruby_xcalloc(),
+ * ruby_xrealloc(), or ruby_xrealloc2().
+ * @warning Every single storage instance that was previously allocated by
+ * either ruby_xmalloc(), ruby_xmalloc2(), ruby_xcalloc(),
+ * ruby_xrealloc(), or ruby_xrealloc2() shall be invalidated
+ * exactly once by either passing it to ruby_xfree(), or passing
+ * it to either ruby_xrealloc(), ruby_xrealloc2() then check the
+ * return value for invalidation.
+ * @warning Do not pass anything other than pointers described above. For
+ * instance pointers returned from malloc() or mmap() shall not be
+ * passed to this function, because the underlying memory
+ * management mechanism could differ.
+ * @warning Do not pass any invalid pointers to this function e.g. by
+ * calling it twice with a same argument.
+ */
+void ruby_xfree(void *ptr)
+RBIMPL_ATTR_NOEXCEPT(free(ptr))
+;
+
+#if USE_GC_MALLOC_OBJ_INFO_DETAILS || defined(__DOXYGEN)
+# define ruby_xmalloc(s1) ruby_xmalloc_with_location(s1, __FILE__, __LINE__)
+# define ruby_xmalloc2(s1, s2) ruby_xmalloc2_with_location(s1, s2, __FILE__, __LINE__)
+# define ruby_xcalloc(s1, s2) ruby_xcalloc_with_location(s1, s2, __FILE__, __LINE__)
+# define ruby_xrealloc(ptr, s1) ruby_xrealloc_with_location(ptr, s1, __FILE__, __LINE__)
+# define ruby_xrealloc2(ptr, s1, s2) ruby_xrealloc2_with_location(ptr, s1, s2, __FILE__, __LINE__)
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((1))
+void *ruby_xmalloc_body(size_t size)
+RBIMPL_ATTR_NOEXCEPT(malloc(size))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((1,2))
+void *ruby_xmalloc2_body(size_t nelems, size_t elemsiz)
+RBIMPL_ATTR_NOEXCEPT(malloc(nelems * elemsiz))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RESTRICT()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((1,2))
+void *ruby_xcalloc_body(size_t nelems, size_t elemsiz)
+RBIMPL_ATTR_NOEXCEPT(calloc(nelems, elemsiz))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((2))
+void *ruby_xrealloc_body(void *ptr, size_t newsiz)
+RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newsiz))
+;
+
+RBIMPL_ATTR_NODISCARD()
+RBIMPL_ATTR_RETURNS_NONNULL()
+RBIMPL_ATTR_ALLOC_SIZE((2,3))
+void *ruby_xrealloc2_body(void *ptr, size_t newelems, size_t newsiz)
+RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newelems * newsiz))
+;
+
+RUBY_EXTERN const char *ruby_malloc_info_file;
+RUBY_EXTERN int ruby_malloc_info_line;
+
+static inline void *
+ruby_xmalloc_with_location(size_t s, const char *file, int line)
+{
+ void *ptr;
+ ruby_malloc_info_file = file;
+ ruby_malloc_info_line = line;
+ ptr = ruby_xmalloc_body(s);
+ ruby_malloc_info_file = NULL;
+ return ptr;
+}
+
+static inline void *
+ruby_xmalloc2_with_location(size_t s1, size_t s2, const char *file, int line)
+{
+ void *ptr;
+ ruby_malloc_info_file = file;
+ ruby_malloc_info_line = line;
+ ptr = ruby_xmalloc2_body(s1, s2);
+ ruby_malloc_info_file = NULL;
+ return ptr;
+}
+
+static inline void *
+ruby_xcalloc_with_location(size_t s1, size_t s2, const char *file, int line)
+{
+ void *ptr;
+ ruby_malloc_info_file = file;
+ ruby_malloc_info_line = line;
+ ptr = ruby_xcalloc_body(s1, s2);
+ ruby_malloc_info_file = NULL;
+ return ptr;
+}
+
+static inline void *
+ruby_xrealloc_with_location(void *ptr, size_t s, const char *file, int line)
+{
+ void *rptr;
+ ruby_malloc_info_file = file;
+ ruby_malloc_info_line = line;
+ rptr = ruby_xrealloc_body(ptr, s);
+ ruby_malloc_info_file = NULL;
+ return rptr;
+}
+
+static inline void *
+ruby_xrealloc2_with_location(void *ptr, size_t s1, size_t s2, const char *file, int line)
+{
+ void *rptr;
+ ruby_malloc_info_file = file;
+ ruby_malloc_info_line = line;
+ rptr = ruby_xrealloc2_body(ptr, s1, s2);
+ ruby_malloc_info_file = NULL;
+ return rptr;
+}
+#endif
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_XMALLOC_H */
diff --git a/include/ruby/io.h b/include/ruby/io.h
index 60d6f6d32e..a3de95f281 100644
--- a/include/ruby/io.h
+++ b/include/ruby/io.h
@@ -1,33 +1,25 @@
-/**********************************************************************
-
- rubyio.h -
-
- $Author$
- created at: Fri Nov 12 16:47:09 JST 1993
-
- Copyright (C) 1993-2007 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_IO_H
+#ifndef RUBY_IO_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_IO_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
+/**
+ * @file
+ * @author $Author$
+ * @date Fri Nov 12 16:47:09 JST 1993
+ * @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/config.h"
#include <stdio.h>
-#include <errno.h>
#include "ruby/encoding.h"
#if defined(HAVE_STDIO_EXT_H)
#include <stdio_ext.h>
#endif
-#include "ruby/config.h"
+#include <errno.h>
#if defined(HAVE_POLL)
# ifdef _AIX
# define reqevents events
@@ -49,7 +41,14 @@ extern "C" {
# define RB_WAITFD_OUT 0x004
#endif
-RUBY_SYMBOL_EXPORT_BEGIN
+typedef enum {
+ RUBY_IO_READABLE = RB_WAITFD_IN,
+ RUBY_IO_WRITABLE = RB_WAITFD_OUT,
+ RUBY_IO_PRIORITY = RB_WAITFD_PRI,
+} rb_io_event_t;
+
+#include "ruby/internal/dllexport.h"
+RBIMPL_SYMBOL_EXPORT_BEGIN()
PACKED_STRUCT_UNALIGNED(struct rb_io_buffer_t {
char *ptr; /* off + len <= capa */
@@ -60,6 +59,8 @@ PACKED_STRUCT_UNALIGNED(struct rb_io_buffer_t {
typedef struct rb_io_buffer_t rb_io_buffer_t;
typedef struct rb_io_t {
+ VALUE self;
+
FILE *stdio_file; /* stdio ptr for read/write if available */
int fd; /* file descriptor */
int mode; /* mode flags: FMODE_XXXs */
@@ -97,6 +98,8 @@ typedef struct rb_io_t {
VALUE write_lock;
} rb_io_t;
+typedef struct rb_io_enc_t rb_io_enc_t;
+
#define HAVE_RB_IO_T 1
#define FMODE_READABLE 0x00000001
@@ -109,6 +112,7 @@ typedef struct rb_io_t {
#define FMODE_APPEND 0x00000040
#define FMODE_CREATE 0x00000080
/* #define FMODE_NOREVLOOKUP 0x00000100 */
+#define FMODE_EXCL 0x00000400
#define FMODE_TRUNC 0x00000800
#define FMODE_TEXTMODE 0x00001000
/* #define FMODE_PREP 0x00010000 */
@@ -117,11 +121,13 @@ typedef struct rb_io_t {
/* #define FMODE_INET 0x00400000 */
/* #define FMODE_INET6 0x00800000 */
-#define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)
+#define RB_IO_POINTER(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)
+#define GetOpenFile RB_IO_POINTER
-#define MakeOpenFile(obj, fp) do {\
+#define RB_IO_OPEN(obj, fp) do {\
(fp) = rb_io_make_open_file(obj);\
} while (0)
+#define MakeOpenFile RB_IO_OPEN
rb_io_t *rb_io_make_open_file(VALUE obj);
@@ -143,13 +149,17 @@ VALUE rb_io_get_io(VALUE io);
VALUE rb_io_check_io(VALUE io);
VALUE rb_io_get_write_io(VALUE io);
VALUE rb_io_set_write_io(VALUE io, VALUE w);
-int rb_io_wait_readable(int);
-int rb_io_wait_writable(int);
-int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);
void rb_io_set_nonblock(rb_io_t *fptr);
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p);
+void rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, int *oflags_p, int *fmode_p, rb_io_enc_t *convconfig_p);
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size);
+int rb_io_wait_readable(int fd);
+int rb_io_wait_writable(int fd);
+int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);
+
+VALUE rb_io_wait(VALUE io, VALUE events, VALUE timeout);
+
/* compatibility for ruby 1.8 and older */
#define rb_io_mode_flags(modestr) [<"rb_io_mode_flags() is obsolete; use rb_io_modestr_fmode()">]
#define rb_io_modenum_flags(oflags) [<"rb_io_modenum_flags() is obsolete; use rb_io_oflags_fmode()">]
@@ -165,13 +175,6 @@ VALUE rb_stat_new(const struct stat *);
/* gc.c */
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_IO_H */
diff --git a/include/ruby/memory_view.h b/include/ruby/memory_view.h
new file mode 100644
index 0000000000..4996cdbbb3
--- /dev/null
+++ b/include/ruby/memory_view.h
@@ -0,0 +1,165 @@
+#ifndef RUBY_MEMORY_VIEW_H
+#define RUBY_MEMORY_VIEW_H 1
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Memory View.
+ */
+
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/intern.h"
+
+enum ruby_memory_view_flags {
+ RUBY_MEMORY_VIEW_SIMPLE = 0,
+ RUBY_MEMORY_VIEW_WRITABLE = (1<<0),
+ RUBY_MEMORY_VIEW_FORMAT = (1<<1),
+ RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL = (1<<2),
+ RUBY_MEMORY_VIEW_STRIDES = (1<<3) | RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL,
+ RUBY_MEMORY_VIEW_ROW_MAJOR = (1<<4) | RUBY_MEMORY_VIEW_STRIDES,
+ RUBY_MEMORY_VIEW_COLUMN_MAJOR = (1<<5) | RUBY_MEMORY_VIEW_STRIDES,
+ RUBY_MEMORY_VIEW_ANY_CONTIGUOUS = RUBY_MEMORY_VIEW_ROW_MAJOR | RUBY_MEMORY_VIEW_COLUMN_MAJOR,
+ RUBY_MEMORY_VIEW_INDIRECT = (1<<6) | RUBY_MEMORY_VIEW_STRIDES,
+};
+
+typedef struct {
+ char format;
+ unsigned native_size_p: 1;
+ unsigned little_endian_p: 1;
+ size_t offset;
+ size_t size;
+ size_t repeat;
+} rb_memory_view_item_component_t;
+
+typedef struct {
+ /* The original object that has the memory exported via this memory view.
+ * The consumer of this memory view has the responsibility to call rb_gc_mark
+ * for preventing this obj collected by GC. */
+ VALUE obj;
+
+ /* The pointer to the exported memory. */
+ void *data;
+
+ /* The number of bytes in data. */
+ ssize_t byte_size;
+
+ /* true for readonly memory, false for writable memory. */
+ bool readonly;
+
+ /* A string to describe the format of an element, or NULL for unsigned bytes.
+ * The format string is a sequence of the following pack-template specifiers:
+ *
+ * c, C, s, s!, S, S!, n, v, i, i!, I, I!, l, l!, L, L!,
+ * N, V, f, e, g, q, q!, Q, Q!, d, E, G, j, J, x
+ *
+ * For example, "dd" for an element that consists of two double values,
+ * and "CCC" for an element that consists of three bytes, such as
+ * an RGB color triplet.
+ *
+ * Also, the value endianness can be explicitly specified by '<' or '>'
+ * following a value type specifier.
+ *
+ * The items are packed contiguously. When you emulate the alignment of
+ * structure members, put '|' at the beginning of the format string,
+ * like "|iqc". On x86_64 Linux ABI, the size of the item by this format
+ * is 24 bytes instead of 13 bytes.
+ */
+ const char *format;
+
+ /* The number of bytes in each element.
+ * item_size should equal to rb_memory_view_item_size_from_format(format). */
+ ssize_t item_size;
+
+ struct {
+ /* The array of rb_memory_view_item_component_t that describes the
+ * item structure. rb_memory_view_prepare_item_desc and
+ * rb_memory_view_get_item allocate this memory if needed,
+ * and rb_memory_view_release frees it. */
+ const rb_memory_view_item_component_t *components;
+
+ /* The number of components in an item. */
+ size_t length;
+ } item_desc;
+
+ /* The number of dimension. */
+ ssize_t ndim;
+
+ /* ndim size array indicating the number of elements in each dimension.
+ * This can be NULL when ndim == 1. */
+ const ssize_t *shape;
+
+ /* ndim size array indicating the number of bytes to skip to go to the
+ * next element in each dimension. */
+ const ssize_t *strides;
+
+ /* The offset in each dimension when this memory view exposes a nested array.
+ * Or, NULL when this memory view exposes a flat array. */
+ const ssize_t *sub_offsets;
+
+ /* the private data for managing this exported memory */
+ void *const private;
+} rb_memory_view_t;
+
+typedef bool (* rb_memory_view_get_func_t)(VALUE obj, rb_memory_view_t *view, int flags);
+typedef bool (* rb_memory_view_release_func_t)(VALUE obj, rb_memory_view_t *view);
+typedef bool (* rb_memory_view_available_p_func_t)(VALUE obj);
+
+typedef struct {
+ rb_memory_view_get_func_t get_func;
+ rb_memory_view_release_func_t release_func;
+ rb_memory_view_available_p_func_t available_p_func;
+} rb_memory_view_entry_t;
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* memory_view.c */
+bool rb_memory_view_register(VALUE klass, const rb_memory_view_entry_t *entry);
+
+RBIMPL_ATTR_PURE()
+bool rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view);
+RBIMPL_ATTR_PURE()
+bool rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view);
+RBIMPL_ATTR_NOALIAS()
+void rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides);
+RBIMPL_ATTR_NOALIAS()
+bool rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly);
+ssize_t rb_memory_view_parse_item_format(const char *format,
+ rb_memory_view_item_component_t **members,
+ size_t *n_members, const char **err);
+ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err);
+void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices);
+VALUE rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members);
+void rb_memory_view_prepare_item_desc(rb_memory_view_t *view);
+VALUE rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices);
+
+bool rb_memory_view_available_p(VALUE obj);
+bool rb_memory_view_get(VALUE obj, rb_memory_view_t* memory_view, int flags);
+bool rb_memory_view_release(rb_memory_view_t* memory_view);
+
+/* for testing */
+RUBY_EXTERN VALUE rb_memory_view_exported_object_registry;
+RUBY_EXTERN const rb_data_type_t rb_memory_view_exported_object_registry_data_type;
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE()
+static inline bool
+rb_memory_view_is_contiguous(const rb_memory_view_t *view)
+{
+ if (rb_memory_view_is_row_major_contiguous(view)) {
+ return true;
+ }
+ else if (rb_memory_view_is_column_major_contiguous(view)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+#endif /* RUBY_BUFFER_H */
diff --git a/include/ruby/missing.h b/include/ruby/missing.h
index a3d7a6b7b7..f83f1b695c 100644
--- a/include/ruby/missing.h
+++ b/include/ruby/missing.h
@@ -1,42 +1,45 @@
-/************************************************
-
- missing.h - prototype for *.c in ./missing, and
- for missing timeval struct
-
- $Author$
- created at: Sat May 11 23:46:03 JST 2002
-
-************************************************/
-
-#ifndef RUBY_MISSING_H
+#ifndef RUBY_MISSING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_MISSING_H 1
+/**
+ * @file
+ * @author $Author$
+ * @date Sat May 11 23:46:03 JST 2002
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Prototype for *.c in ./missing, and for missing timeval struct.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
+# include <cmath>
+#else
+# include <math.h> /* for INFINITY and NAN */
#endif
-#include "ruby/config.h"
-#include <stddef.h>
-#include <math.h> /* for INFINITY and NAN */
#ifdef RUBY_ALTERNATIVE_MALLOC_HEADER
# include RUBY_ALTERNATIVE_MALLOC_HEADER
#endif
-#ifdef RUBY_EXTCONF_H
-#include RUBY_EXTCONF_H
-#endif
-#if !defined(HAVE_STRUCT_TIMEVAL) || !defined(HAVE_STRUCT_TIMESPEC)
#if defined(HAVE_TIME_H)
# include <time.h>
#endif
+
#if defined(HAVE_SYS_TIME_H)
# include <sys/time.h>
#endif
+
+#ifdef HAVE_IEEEFP_H
+# include <ieeefp.h>
#endif
+#include "ruby/internal/dllexport.h"
+
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
@@ -44,11 +47,6 @@ extern "C" {
# define M_PI_2 (M_PI/2)
#endif
-#ifndef RUBY_SYMBOL_EXPORT_BEGIN
-# define RUBY_SYMBOL_EXPORT_BEGIN /* begin */
-# define RUBY_SYMBOL_EXPORT_END /* end */
-#endif
-
#if !defined(HAVE_STRUCT_TIMEVAL)
struct timeval {
time_t tv_sec; /* seconds */
@@ -57,6 +55,10 @@ struct timeval {
#endif /* HAVE_STRUCT_TIMEVAL */
#if !defined(HAVE_STRUCT_TIMESPEC)
+/* :BEWARE: @shyouhei warns that IT IS A WRONG IDEA to define our own version
+ * of struct timespec here. `clock_gettime` is a system call, and your kernel
+ * could expect something other than just `long` (results stack smashing if
+ * that happens). See also https://ewontfix.com/19/ */
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
@@ -70,14 +72,7 @@ struct timezone {
};
#endif
-#ifdef RUBY_EXPORT
-#undef RUBY_EXTERN
-#endif
-#ifndef RUBY_EXTERN
-#define RUBY_EXTERN extern
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
+RBIMPL_SYMBOL_EXPORT_BEGIN()
#ifndef HAVE_ACOSH
RUBY_EXTERN double acosh(double);
@@ -136,7 +131,7 @@ RUBY_EXTERN double lgamma_r(double, int *);
RUBY_EXTERN double cbrt(double);
#endif
-#if !defined(HAVE_INFINITY) || !defined(HAVE_NAN)
+#if !defined(INFINITY) || !defined(NAN)
union bytesequence4_or_float {
unsigned char bytesequence[4];
float float_value;
@@ -147,38 +142,53 @@ union bytesequence4_or_float {
/** @internal */
RUBY_EXTERN const union bytesequence4_or_float rb_infinity;
# define INFINITY (rb_infinity.float_value)
+# define USE_RB_INFINITY 1
#endif
#ifndef NAN
/** @internal */
RUBY_EXTERN const union bytesequence4_or_float rb_nan;
# define NAN (rb_nan.float_value)
+# define USE_RB_NAN 1
#endif
-#ifndef isinf
-# ifndef HAVE_ISINF
-# if defined(HAVE_FINITE) && defined(HAVE_ISNAN)
-# ifdef HAVE_IEEEFP_H
-# include <ieeefp.h>
-# endif
-# define isinf(x) (!finite(x) && !isnan(x))
-# else
+#ifndef HUGE_VAL
+# define HUGE_VAL ((double)INFINITY)
+#endif
+
+#if defined(isinf)
+# /* Take that. */
+#elif defined(HAVE_ISINF)
+# /* Take that. */
+#elif defined(HAVE_FINITE) && defined(HAVE_ISNAN)
+# define isinf(x) (!finite(x) && !isnan(x))
+#elif defined(__cplusplus) && __cplusplus >= 201103L
+# // <cmath> must include constexpr bool isinf(double);
+#else
RUBY_EXTERN int isinf(double);
-# endif
-# endif
#endif
-#ifndef isnan
-# ifndef HAVE_ISNAN
+#if defined(isnan)
+# /* Take that. */
+#elif defined(HAVE_ISNAN)
+# /* Take that. */
+#elif defined(__cplusplus) && __cplusplus >= 201103L
+# // <cmath> must include constexpr bool isnan(double);
+#else
RUBY_EXTERN int isnan(double);
-# endif
#endif
-#ifndef isfinite
-# ifndef HAVE_ISFINITE
-# define HAVE_ISFINITE 1
-# define isfinite(x) finite(x)
-# endif
+#if defined(isfinite)
+# /* Take that. */
+#elif defined(HAVE_ISFINITE)
+# /* Take that. */
+#else
+# define HAVE_ISFINITE 1
+# define isfinite(x) finite(x)
+#endif
+
+#ifndef HAVE_NAN
+RUBY_EXTERN double nan(const char *);
#endif
#ifndef HAVE_NEXTAFTER
@@ -231,8 +241,8 @@ RUBY_EXTERN int ffs(int);
#endif
#ifdef BROKEN_CLOSE
-#include <sys/types.h>
-#include <sys/socket.h>
+# include <sys/types.h>
+# include <sys/socket.h>
RUBY_EXTERN int ruby_getpeername(int, struct sockaddr *, socklen_t *);
RUBY_EXTERN int ruby_getsockname(int, struct sockaddr *, socklen_t *);
RUBY_EXTERN int ruby_shutdown(int, int);
@@ -243,20 +253,14 @@ RUBY_EXTERN int ruby_close(int);
RUBY_EXTERN void setproctitle(const char *fmt, ...);
#endif
-#ifndef HAVE_EXPLICIT_BZERO
+#ifdef HAVE_EXPLICIT_BZERO
+# /* Take that. */
+#elif defined(SecureZeroMemory)
+# define explicit_bzero(b, len) SecureZeroMemory(b, len)
+#else
RUBY_EXTERN void explicit_bzero(void *b, size_t len);
-# if defined SecureZeroMemory
-# define explicit_bzero(b, len) SecureZeroMemory(b, len)
-# endif
#endif
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_MISSING_H */
diff --git a/include/ruby/onigmo.h b/include/ruby/onigmo.h
index 99afcf66fa..6187b37dc3 100644
--- a/include/ruby/onigmo.h
+++ b/include/ruby/onigmo.h
@@ -39,7 +39,7 @@ extern "C" {
#define ONIGMO_VERSION_MAJOR 6
#define ONIGMO_VERSION_MINOR 1
-#define ONIGMO_VERSION_TEENY 2
+#define ONIGMO_VERSION_TEENY 3
#ifndef ONIG_EXTERN
# ifdef RUBY_EXTERN
@@ -434,7 +434,7 @@ int onigenc_str_bytelen_null(OnigEncoding enc, const OnigUChar* p);
/* PART: regular expression */
/* config parameters */
-#define ONIG_NREGION 10
+#define ONIG_NREGION 4
#define ONIG_MAX_CAPTURE_GROUP_NUM 32767
#define ONIG_MAX_BACKREF_NUM 1000
#define ONIG_MAX_REPEAT_NUM 100000
@@ -701,6 +701,7 @@ ONIG_EXTERN const OnigSyntaxType* OnigDefaultSyntax;
#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \
((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i])
+#ifdef USE_CAPTURE_HISTORY
typedef struct OnigCaptureTreeNodeStruct {
int group; /* group number */
OnigPosition beg;
@@ -709,6 +710,7 @@ typedef struct OnigCaptureTreeNodeStruct {
int num_childs;
struct OnigCaptureTreeNodeStruct** childs;
} OnigCaptureTreeNode;
+#endif
/* match result region type */
struct re_registers {
@@ -716,8 +718,10 @@ struct re_registers {
int num_regs;
OnigPosition* beg;
OnigPosition* end;
+#ifdef USE_CAPTURE_HISTORY
/* extended */
OnigCaptureTreeNode* history_root; /* capture history tree root */
+#endif
};
/* capture tree traverse */
@@ -866,8 +870,10 @@ ONIG_EXTERN
int onig_number_of_captures(const OnigRegexType *reg);
ONIG_EXTERN
int onig_number_of_capture_histories(const OnigRegexType *reg);
+#ifdef USE_CAPTURE_HISTORY
ONIG_EXTERN
OnigCaptureTreeNode* onig_get_capture_tree(OnigRegion* region);
+#endif
ONIG_EXTERN
int onig_capture_tree_traverse(OnigRegion* region, int at, int(*callback_func)(int,OnigPosition,OnigPosition,int,int,void*), void* arg);
ONIG_EXTERN
diff --git a/include/ruby/ractor.h b/include/ruby/ractor.h
new file mode 100644
index 0000000000..1d6687456c
--- /dev/null
+++ b/include/ruby/ractor.h
@@ -0,0 +1,68 @@
+#ifndef RUBY_RACTOR_H
+#define RUBY_RACTOR_H 1
+
+/**
+ * @file
+ * @author Koichi Sasada
+ * @date Tue Nov 17 16:39:15 2020
+ * @copyright Copyright (C) 2020 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+
+struct rb_ractor_local_storage_type {
+ void (*mark)(void *ptr);
+ void (*free)(void *ptr);
+ // TODO: update
+};
+
+typedef struct rb_ractor_local_key_struct *rb_ractor_local_key_t;
+
+RUBY_SYMBOL_EXPORT_BEGIN
+RUBY_EXTERN VALUE rb_cRactor;
+
+VALUE rb_ractor_stdin(void);
+VALUE rb_ractor_stdout(void);
+VALUE rb_ractor_stderr(void);
+void rb_ractor_stdin_set(VALUE);
+void rb_ractor_stdout_set(VALUE);
+void rb_ractor_stderr_set(VALUE);
+
+rb_ractor_local_key_t rb_ractor_local_storage_value_newkey(void);
+VALUE rb_ractor_local_storage_value(rb_ractor_local_key_t key);
+bool rb_ractor_local_storage_value_lookup(rb_ractor_local_key_t key, VALUE *val);
+void rb_ractor_local_storage_value_set(rb_ractor_local_key_t key, VALUE val);
+
+RUBY_EXTERN const struct rb_ractor_local_storage_type rb_ractor_local_storage_type_free;
+#define RB_RACTOR_LOCAL_STORAGE_TYPE_FREE (&rb_ractor_local_storage_type_free)
+
+rb_ractor_local_key_t rb_ractor_local_storage_ptr_newkey(const struct rb_ractor_local_storage_type *type);
+void *rb_ractor_local_storage_ptr(rb_ractor_local_key_t key);
+void rb_ractor_local_storage_ptr_set(rb_ractor_local_key_t key, void *ptr);
+
+VALUE rb_ractor_make_shareable(VALUE obj);
+VALUE rb_ractor_make_shareable_copy(VALUE obj);
+
+RUBY_SYMBOL_EXPORT_END
+
+#define RB_OBJ_SHAREABLE_P(obj) FL_TEST_RAW((obj), RUBY_FL_SHAREABLE)
+
+static inline bool
+rb_ractor_shareable_p(VALUE obj)
+{
+ bool rb_ractor_shareable_p_continue(VALUE obj);
+
+ if (SPECIAL_CONST_P(obj)) {
+ return true;
+ }
+ else if (RB_OBJ_SHAREABLE_P(obj)) {
+ return true;
+ }
+ else {
+ return rb_ractor_shareable_p_continue(obj);
+ }
+}
+
+#endif /* RUBY_RACTOR_H */
diff --git a/include/ruby/random.h b/include/ruby/random.h
new file mode 100644
index 0000000000..56b2dd413f
--- /dev/null
+++ b/include/ruby/random.h
@@ -0,0 +1,92 @@
+#ifndef RUBY_RANDOM_H
+#define RUBY_RANDOM_H 1
+/**
+ * @file
+ * @date Sat May 7 11:51:14 JST 2016
+ * @copyright 2007-2020 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+
+#include "ruby/ruby.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+struct rb_random_struct {
+ VALUE seed;
+};
+typedef struct rb_random_struct rb_random_t;
+
+typedef void rb_random_init_func(rb_random_t *, const uint32_t *, size_t);
+typedef unsigned int rb_random_get_int32_func(rb_random_t *);
+typedef void rb_random_get_bytes_func(rb_random_t *, void *, size_t);
+typedef double rb_random_get_real_func(rb_random_t *, int);
+
+typedef struct {
+ size_t default_seed_bits;
+ rb_random_init_func *init;
+ rb_random_get_int32_func *get_int32;
+ rb_random_get_bytes_func *get_bytes;
+ rb_random_get_real_func *get_real;
+} rb_random_interface_t;
+
+#define RB_RANDOM_INTERFACE_DECLARE(prefix) \
+ static void prefix##_init(rb_random_t *, const uint32_t *, size_t); \
+ static unsigned int prefix##_get_int32(rb_random_t *); \
+ static void prefix##_get_bytes(rb_random_t *, void *, size_t)
+
+#define RB_RANDOM_INTERFACE_DECLARE_WITH_REAL(prefix) \
+ RB_RANDOM_INTERFACE_DECLARE(prefix); \
+ static double prefix##_get_real(rb_random_t *, int)
+
+#define RB_RANDOM_INTERFACE_DEFINE(prefix) \
+ prefix##_init, \
+ prefix##_get_int32, \
+ prefix##_get_bytes
+
+#define RB_RANDOM_INTERFACE_DEFINE_WITH_REAL(prefix) \
+ RB_RANDOM_INTERFACE_DEFINE(prefix), \
+ prefix##_get_real
+
+#if defined _WIN32 && !defined __CYGWIN__
+typedef rb_data_type_t rb_random_data_type_t;
+# define RB_RANDOM_PARENT 0
+#else
+typedef const rb_data_type_t rb_random_data_type_t;
+# define RB_RANDOM_PARENT &rb_random_data_type
+#endif
+
+#define RB_RANDOM_DATA_INIT_PARENT(random_data) \
+ rbimpl_random_data_init_parent(&random_data)
+
+void rb_random_mark(void *ptr);
+void rb_random_base_init(rb_random_t *rnd);
+double rb_int_pair_to_real(uint32_t a, uint32_t b, int excl);
+void rb_rand_bytes_int32(rb_random_get_int32_func *, rb_random_t *, void *, size_t);
+RUBY_EXTERN const rb_data_type_t rb_random_data_type;
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
+static inline const rb_random_interface_t *
+rb_rand_if(VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RTYPEDDATA_P(obj));
+ const struct rb_data_type_struct *t = RTYPEDDATA_TYPE(obj);
+ const void *ret = t->data;
+ return RBIMPL_CAST((const rb_random_interface_t *)ret);
+}
+
+RBIMPL_ATTR_NOALIAS()
+static inline void
+rbimpl_random_data_init_parent(rb_random_data_type_t *random_data)
+{
+#if defined _WIN32 && !defined __CYGWIN__
+ random_data->parent = &rb_random_data_type;
+#endif
+}
+
+#endif /* RUBY_RANDOM_H */
diff --git a/include/ruby/re.h b/include/ruby/re.h
index 166f254aa5..ec0f425db0 100644
--- a/include/ruby/re.h
+++ b/include/ruby/re.h
@@ -1,55 +1,24 @@
-/**********************************************************************
-
- re.h -
-
- $Author$
- created at: Thu Sep 30 14:18:32 JST 1993
-
- Copyright (C) 1993-2007 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_RE_H
+#ifndef RUBY_RE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RE_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
+/**
+ * @file
+ * @author $Author$
+ * @date Thu Sep 30 14:18:32 JST 1993
+ * @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/config.h"
#include <sys/types.h>
#include <stdio.h>
#include "ruby/regex.h"
+#include "ruby/internal/core/rmatch.h"
+#include "ruby/internal/dllexport.h"
-RUBY_SYMBOL_EXPORT_BEGIN
-
-typedef struct re_pattern_buffer Regexp;
-
-struct rmatch_offset {
- long beg;
- long end;
-};
-
-struct rmatch {
- struct re_registers regs;
-
- int char_offset_updated;
- int char_offset_num_allocated;
- struct rmatch_offset *char_offset;
-};
-
-struct RMatch {
- struct RBasic basic;
- VALUE str;
- struct rmatch *rmatch;
- VALUE regexp; /* RRegexp */
-};
-
-#define RMATCH(obj) (R_CAST(RMatch)(obj))
-#define RMATCH_REGS(obj) (&(R_CAST(RMatch)(obj))->rmatch->regs)
+RBIMPL_SYMBOL_EXPORT_BEGIN()
VALUE rb_reg_regcomp(VALUE);
long rb_reg_search(VALUE, VALUE, long, int);
@@ -60,13 +29,6 @@ VALUE rb_reg_quote(VALUE);
regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
int rb_reg_region_copy(struct re_registers *, const struct re_registers *);
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_RE_H */
diff --git a/include/ruby/regex.h b/include/ruby/regex.h
index 024bed4a4e..22dae3231d 100644
--- a/include/ruby/regex.h
+++ b/include/ruby/regex.h
@@ -1,16 +1,14 @@
-/**********************************************************************
-
- regex.h -
-
- $Author$
-
- Copyright (C) 1993-2007 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef ONIGURUMA_REGEX_H
+#ifndef ONIGURUMA_REGEX_H /*-*-C++-*-vi:se ft=cpp:*/
#define ONIGURUMA_REGEX_H 1
-
+/**
+ * @file
+ * @author $Author$
+ * @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
#if defined(__cplusplus)
extern "C" {
#if 0
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index ff1c463a29..c68168d500 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1,52 +1,18 @@
-/**********************************************************************
-
- ruby/ruby.h -
-
- $Author$
- created at: Thu Jun 10 14:26:32 JST 1993
-
- Copyright (C) 1993-2008 Yukihiro Matsumoto
- Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
- Copyright (C) 2000 Information-technology Promotion Agency, Japan
-
-**********************************************************************/
-
-#ifndef RUBY_RUBY_H
+#ifndef RUBY_RUBY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RUBY_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-#include "ruby/config.h"
-#ifdef RUBY_EXTCONF_H
-#include RUBY_EXTCONF_H
-#endif
-
-#if defined(__cplusplus)
-/* __builtin_choose_expr and __builtin_types_compatible aren't available
- * on C++. See https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
-# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
-# undef HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P
-#endif
-
-#include "defines.h"
-
-#ifndef ASSUME
-# ifdef UNREACHABLE
-# define ASSUME(x) (RB_LIKELY(!!(x)) ? (void)0 : UNREACHABLE)
-# else
-# define ASSUME(x) ((void)(x))
-# endif
-#endif
-#ifndef UNREACHABLE
-# define UNREACHABLE ((void)0) /* unreachable */
-#endif
-
-#define RUBY_MACRO_SELECT(base, n) TOKEN_PASTE(base, n)
+/**
+ * @file
+ * @author $Author$
+ * @date Thu Jun 10 14:26:32 JST 1993
+ * @copyright Copyright (C) 1993-2008 Yukihiro Matsumoto
+ * @copyright Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
+ * @copyright Copyright (C) 2000 Information-technology Promotion Agency, Japan
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/config.h"
#ifdef HAVE_INTRINSICS_H
# include <intrinsics.h>
@@ -54,1727 +20,73 @@ extern "C" {
#include <stdarg.h>
-RUBY_SYMBOL_EXPORT_BEGIN
-
-/* Make alloca work the best possible way. */
-#ifdef __GNUC__
-# ifndef alloca
-# define alloca __builtin_alloca
-# endif
-#else
-# ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
-#pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-void *alloca();
-# endif
-# endif /* AIX */
-# endif /* HAVE_ALLOCA_H */
-#endif /* __GNUC__ */
-
-#if defined HAVE_UINTPTR_T && 0
-typedef uintptr_t VALUE;
-typedef uintptr_t ID;
-# define SIGNED_VALUE intptr_t
-# define SIZEOF_VALUE SIZEOF_UINTPTR_T
-# undef PRI_VALUE_PREFIX
-#elif SIZEOF_LONG == SIZEOF_VOIDP
-typedef unsigned long VALUE;
-typedef unsigned long ID;
-# define SIGNED_VALUE long
-# define SIZEOF_VALUE SIZEOF_LONG
-# define PRI_VALUE_PREFIX "l"
-#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
-typedef unsigned LONG_LONG VALUE;
-typedef unsigned LONG_LONG ID;
-# define SIGNED_VALUE LONG_LONG
-# define LONG_LONG_VALUE 1
-# define SIZEOF_VALUE SIZEOF_LONG_LONG
-# define PRI_VALUE_PREFIX PRI_LL_PREFIX
-#else
-# error ---->> ruby requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
-#endif
-
-typedef char ruby_check_sizeof_int[SIZEOF_INT == sizeof(int) ? 1 : -1];
-typedef char ruby_check_sizeof_long[SIZEOF_LONG == sizeof(long) ? 1 : -1];
-#ifdef HAVE_LONG_LONG
-typedef char ruby_check_sizeof_long_long[SIZEOF_LONG_LONG == sizeof(LONG_LONG) ? 1 : -1];
-#endif
-typedef char ruby_check_sizeof_voidp[SIZEOF_VOIDP == sizeof(void*) ? 1 : -1];
-
-#ifndef PRI_INT_PREFIX
-#define PRI_INT_PREFIX ""
-#endif
-#ifndef PRI_LONG_PREFIX
-#define PRI_LONG_PREFIX "l"
-#endif
-
-#if SIZEOF_LONG == 8
-#define PRI_64_PREFIX PRI_LONG_PREFIX
-#elif SIZEOF_LONG_LONG == 8
-#define PRI_64_PREFIX PRI_LL_PREFIX
-#endif
-
-#define RUBY_PRI_VALUE_MARK "\v"
-#if defined PRIdPTR && !defined PRI_VALUE_PREFIX
-#define PRIdVALUE PRIdPTR
-#define PRIoVALUE PRIoPTR
-#define PRIuVALUE PRIuPTR
-#define PRIxVALUE PRIxPTR
-#define PRIXVALUE PRIXPTR
-#define PRIsVALUE PRIiPTR"" RUBY_PRI_VALUE_MARK
-#else
-#define PRIdVALUE PRI_VALUE_PREFIX"d"
-#define PRIoVALUE PRI_VALUE_PREFIX"o"
-#define PRIuVALUE PRI_VALUE_PREFIX"u"
-#define PRIxVALUE PRI_VALUE_PREFIX"x"
-#define PRIXVALUE PRI_VALUE_PREFIX"X"
-#define PRIsVALUE PRI_VALUE_PREFIX"i" RUBY_PRI_VALUE_MARK
-#endif
-#ifndef PRI_VALUE_PREFIX
-# define PRI_VALUE_PREFIX ""
-#endif
-
-#ifndef PRI_TIMET_PREFIX
-# if SIZEOF_TIME_T == SIZEOF_INT
-# define PRI_TIMET_PREFIX
-# elif SIZEOF_TIME_T == SIZEOF_LONG
-# define PRI_TIMET_PREFIX "l"
-# elif SIZEOF_TIME_T == SIZEOF_LONG_LONG
-# define PRI_TIMET_PREFIX PRI_LL_PREFIX
-# endif
-#endif
-
-#if defined PRI_PTRDIFF_PREFIX
-#elif SIZEOF_PTRDIFF_T == SIZEOF_INT
-# define PRI_PTRDIFF_PREFIX ""
-#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
-# define PRI_PTRDIFF_PREFIX "l"
-#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
-# define PRI_PTRDIFF_PREFIX PRI_LL_PREFIX
-#endif
-#define PRIdPTRDIFF PRI_PTRDIFF_PREFIX"d"
-#define PRIiPTRDIFF PRI_PTRDIFF_PREFIX"i"
-#define PRIoPTRDIFF PRI_PTRDIFF_PREFIX"o"
-#define PRIuPTRDIFF PRI_PTRDIFF_PREFIX"u"
-#define PRIxPTRDIFF PRI_PTRDIFF_PREFIX"x"
-#define PRIXPTRDIFF PRI_PTRDIFF_PREFIX"X"
-
-#if defined PRI_SIZE_PREFIX
-#elif SIZEOF_SIZE_T == SIZEOF_INT
-# define PRI_SIZE_PREFIX ""
-#elif SIZEOF_SIZE_T == SIZEOF_LONG
-# define PRI_SIZE_PREFIX "l"
-#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
-# define PRI_SIZE_PREFIX PRI_LL_PREFIX
-#endif
-#define PRIdSIZE PRI_SIZE_PREFIX"d"
-#define PRIiSIZE PRI_SIZE_PREFIX"i"
-#define PRIoSIZE PRI_SIZE_PREFIX"o"
-#define PRIuSIZE PRI_SIZE_PREFIX"u"
-#define PRIxSIZE PRI_SIZE_PREFIX"x"
-#define PRIXSIZE PRI_SIZE_PREFIX"X"
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# ifndef LONG_MAX
-# ifdef HAVE_LIMITS_H
-# include <limits.h>
-# else
- /* assuming 32bit(2's complement) long */
-# define LONG_MAX 2147483647
-# endif
-# endif
-# ifndef LONG_MIN
-# define LONG_MIN (-LONG_MAX-1)
-# endif
-# ifndef CHAR_BIT
-# define CHAR_BIT 8
-# endif
-#endif
-
-#ifdef HAVE_LONG_LONG
-# ifndef LLONG_MAX
-# ifdef LONG_LONG_MAX
-# define LLONG_MAX LONG_LONG_MAX
-# else
-# ifdef _I64_MAX
-# define LLONG_MAX _I64_MAX
-# else
- /* assuming 64bit(2's complement) long long */
-# define LLONG_MAX 9223372036854775807LL
-# endif
-# endif
-# endif
-# ifndef LLONG_MIN
-# ifdef LONG_LONG_MIN
-# define LLONG_MIN LONG_LONG_MIN
-# else
-# ifdef _I64_MIN
-# define LLONG_MIN _I64_MIN
-# else
-# define LLONG_MIN (-LLONG_MAX-1)
-# endif
-# endif
-# endif
-#endif
-
-#define RUBY_FIXNUM_MAX (LONG_MAX>>1)
-#define RUBY_FIXNUM_MIN RSHIFT((long)LONG_MIN,1)
-#define FIXNUM_MAX RUBY_FIXNUM_MAX
-#define FIXNUM_MIN RUBY_FIXNUM_MIN
-
-#define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
-#define INT2FIX(i) RB_INT2FIX(i)
-#define RB_LONG2FIX(i) RB_INT2FIX(i)
-#define LONG2FIX(i) RB_INT2FIX(i)
-#define rb_fix_new(v) RB_INT2FIX(v)
-VALUE rb_int2inum(SIGNED_VALUE);
-
-#define rb_int_new(v) rb_int2inum(v)
-VALUE rb_uint2inum(VALUE);
-
-#define rb_uint_new(v) rb_uint2inum(v)
-
-#ifdef HAVE_LONG_LONG
-VALUE rb_ll2inum(LONG_LONG);
-#define LL2NUM(v) rb_ll2inum(v)
-VALUE rb_ull2inum(unsigned LONG_LONG);
-#define ULL2NUM(v) rb_ull2inum(v)
-#endif
-
-#ifndef OFFT2NUM
-#if SIZEOF_OFF_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
-# define OFFT2NUM(v) LL2NUM(v)
-#elif SIZEOF_OFF_T == SIZEOF_LONG
-# define OFFT2NUM(v) LONG2NUM(v)
-#else
-# define OFFT2NUM(v) INT2NUM(v)
-#endif
-#endif
-
-#if SIZEOF_SIZE_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
-# define SIZET2NUM(v) ULL2NUM(v)
-# define SSIZET2NUM(v) LL2NUM(v)
-#elif SIZEOF_SIZE_T == SIZEOF_LONG
-# define SIZET2NUM(v) ULONG2NUM(v)
-# define SSIZET2NUM(v) LONG2NUM(v)
-#else
-# define SIZET2NUM(v) UINT2NUM(v)
-# define SSIZET2NUM(v) INT2NUM(v)
-#endif
-
-#ifndef SIZE_MAX
-# if SIZEOF_SIZE_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
-# define SIZE_MAX ULLONG_MAX
-# define SIZE_MIN ULLONG_MIN
-# elif SIZEOF_SIZE_T == SIZEOF_LONG
-# define SIZE_MAX ULONG_MAX
-# define SIZE_MIN ULONG_MIN
-# elif SIZEOF_SIZE_T == SIZEOF_INT
-# define SIZE_MAX UINT_MAX
-# define SIZE_MIN UINT_MIN
-# else
-# define SIZE_MAX USHRT_MAX
-# define SIZE_MIN USHRT_MIN
-# endif
-#endif
-
-#ifndef SSIZE_MAX
-# if SIZEOF_SIZE_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
-# define SSIZE_MAX LLONG_MAX
-# define SSIZE_MIN LLONG_MIN
-# elif SIZEOF_SIZE_T == SIZEOF_LONG
-# define SSIZE_MAX LONG_MAX
-# define SSIZE_MIN LONG_MIN
-# elif SIZEOF_SIZE_T == SIZEOF_INT
-# define SSIZE_MAX INT_MAX
-# define SSIZE_MIN INT_MIN
-# else
-# define SSIZE_MAX SHRT_MAX
-# define SSIZE_MIN SHRT_MIN
-# endif
-#endif
-
-#if SIZEOF_INT < SIZEOF_VALUE
-NORETURN(void rb_out_of_int(SIGNED_VALUE num));
-#endif
-
-#if SIZEOF_INT < SIZEOF_LONG
-static inline int
-rb_long2int_inline(long n)
-{
- int i = (int)n;
- if ((long)i != n)
- rb_out_of_int(n);
-
- return i;
-}
-#define rb_long2int(n) rb_long2int_inline(n)
-#else
-#define rb_long2int(n) ((int)(n))
-#endif
-
-#ifndef PIDT2NUM
-#define PIDT2NUM(v) LONG2NUM(v)
-#endif
-#ifndef NUM2PIDT
-#define NUM2PIDT(v) NUM2LONG(v)
-#endif
-#ifndef UIDT2NUM
-#define UIDT2NUM(v) LONG2NUM(v)
-#endif
-#ifndef NUM2UIDT
-#define NUM2UIDT(v) NUM2LONG(v)
-#endif
-#ifndef GIDT2NUM
-#define GIDT2NUM(v) LONG2NUM(v)
-#endif
-#ifndef NUM2GIDT
-#define NUM2GIDT(v) NUM2LONG(v)
-#endif
-#ifndef NUM2MODET
-#define NUM2MODET(v) NUM2INT(v)
-#endif
-#ifndef MODET2NUM
-#define MODET2NUM(v) INT2NUM(v)
-#endif
-
-#define RB_FIX2LONG(x) ((long)RSHIFT((SIGNED_VALUE)(x),1))
-static inline long
-rb_fix2long(VALUE x)
-{
- return RB_FIX2LONG(x);
-}
-#define RB_FIX2ULONG(x) ((unsigned long)RB_FIX2LONG(x))
-static inline unsigned long
-rb_fix2ulong(VALUE x)
-{
- return RB_FIX2ULONG(x);
-}
-#define RB_FIXNUM_P(f) (((int)(SIGNED_VALUE)(f))&RUBY_FIXNUM_FLAG)
-#define RB_POSFIXABLE(f) ((f) < RUBY_FIXNUM_MAX+1)
-#define RB_NEGFIXABLE(f) ((f) >= RUBY_FIXNUM_MIN)
-#define RB_FIXABLE(f) (RB_POSFIXABLE(f) && RB_NEGFIXABLE(f))
-#define FIX2LONG(x) RB_FIX2LONG(x)
-#define FIX2ULONG(x) RB_FIX2ULONG(x)
-#define FIXNUM_P(f) RB_FIXNUM_P(f)
-#define POSFIXABLE(f) RB_POSFIXABLE(f)
-#define NEGFIXABLE(f) RB_NEGFIXABLE(f)
-#define FIXABLE(f) RB_FIXABLE(f)
-
-#define RB_IMMEDIATE_P(x) ((VALUE)(x) & RUBY_IMMEDIATE_MASK)
-#define IMMEDIATE_P(x) RB_IMMEDIATE_P(x)
-
-ID rb_sym2id(VALUE);
-VALUE rb_id2sym(ID);
-#define RB_STATIC_SYM_P(x) (((VALUE)(x)&~((~(VALUE)0)<<RUBY_SPECIAL_SHIFT)) == RUBY_SYMBOL_FLAG)
-#define RB_DYNAMIC_SYM_P(x) (!RB_SPECIAL_CONST_P(x) && RB_BUILTIN_TYPE(x) == (RUBY_T_SYMBOL))
-#define RB_SYMBOL_P(x) (RB_STATIC_SYM_P(x)||RB_DYNAMIC_SYM_P(x))
-#define RB_ID2SYM(x) (rb_id2sym(x))
-#define RB_SYM2ID(x) (rb_sym2id(x))
-#define STATIC_SYM_P(x) RB_STATIC_SYM_P(x)
-#define DYNAMIC_SYM_P(x) RB_DYNAMIC_SYM_P(x)
-#define SYMBOL_P(x) RB_SYMBOL_P(x)
-#define ID2SYM(x) RB_ID2SYM(x)
-#define SYM2ID(x) RB_SYM2ID(x)
-
-#ifndef USE_FLONUM
-#if SIZEOF_VALUE >= SIZEOF_DOUBLE
-#define USE_FLONUM 1
-#else
-#define USE_FLONUM 0
-#endif
-#endif
-
-#if USE_FLONUM
-#define RB_FLONUM_P(x) ((((int)(SIGNED_VALUE)(x))&RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG)
-#else
-#define RB_FLONUM_P(x) 0
-#endif
-#define FLONUM_P(x) RB_FLONUM_P(x)
+#include "defines.h"
+#include "ruby/internal/anyargs.h"
+#include "ruby/internal/arithmetic.h"
+#include "ruby/internal/core.h"
+#include "ruby/internal/ctype.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/error.h"
+#include "ruby/internal/eval.h"
+#include "ruby/internal/event.h"
+#include "ruby/internal/fl_type.h"
+#include "ruby/internal/gc.h"
+#include "ruby/internal/glob.h"
+#include "ruby/internal/globals.h"
+#include "ruby/internal/has/warning.h"
+#include "ruby/internal/interpreter.h"
+#include "ruby/internal/iterator.h"
+#include "ruby/internal/memory.h"
+#include "ruby/internal/method.h"
+#include "ruby/internal/module.h"
+#include "ruby/internal/newobj.h"
+#include "ruby/internal/rgengc.h"
+#include "ruby/internal/scan_args.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/symbol.h"
+#include "ruby/internal/value.h"
+#include "ruby/internal/value_type.h"
+#include "ruby/internal/variable.h"
+#include "ruby/assert.h"
+#include "ruby/backward/2/assume.h"
+#include "ruby/backward/2/inttypes.h"
+#include "ruby/backward/2/limits.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
/* Module#methods, #singleton_methods and so on return Symbols */
#define USE_SYMBOL_AS_METHOD_NAME 1
-/* special constants - i.e. non-zero and non-fixnum constants */
-enum ruby_special_consts {
-#if USE_FLONUM
- RUBY_Qfalse = 0x00, /* ...0000 0000 */
- RUBY_Qtrue = 0x14, /* ...0001 0100 */
- RUBY_Qnil = 0x08, /* ...0000 1000 */
- RUBY_Qundef = 0x34, /* ...0011 0100 */
-
- RUBY_IMMEDIATE_MASK = 0x07,
- RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
- RUBY_FLONUM_MASK = 0x03,
- RUBY_FLONUM_FLAG = 0x02, /* ...xxxx xx10 */
- RUBY_SYMBOL_FLAG = 0x0c, /* ...0000 1100 */
-#else
- RUBY_Qfalse = 0, /* ...0000 0000 */
- RUBY_Qtrue = 2, /* ...0000 0010 */
- RUBY_Qnil = 4, /* ...0000 0100 */
- RUBY_Qundef = 6, /* ...0000 0110 */
-
- RUBY_IMMEDIATE_MASK = 0x03,
- RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
- RUBY_FLONUM_MASK = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
- RUBY_FLONUM_FLAG = 0x02,
- RUBY_SYMBOL_FLAG = 0x0e, /* ...0000 1110 */
-#endif
- RUBY_SPECIAL_SHIFT = 8
-};
-
-#define RUBY_Qfalse ((VALUE)RUBY_Qfalse)
-#define RUBY_Qtrue ((VALUE)RUBY_Qtrue)
-#define RUBY_Qnil ((VALUE)RUBY_Qnil)
-#define RUBY_Qundef ((VALUE)RUBY_Qundef) /* undefined value for placeholder */
-#define Qfalse RUBY_Qfalse
-#define Qtrue RUBY_Qtrue
-#define Qnil RUBY_Qnil
-#define Qundef RUBY_Qundef
-#define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK
-#define FIXNUM_FLAG RUBY_FIXNUM_FLAG
-#if USE_FLONUM
-#define FLONUM_MASK RUBY_FLONUM_MASK
-#define FLONUM_FLAG RUBY_FLONUM_FLAG
-#endif
-#define SYMBOL_FLAG RUBY_SYMBOL_FLAG
-
-#define RB_TEST(v) !(((VALUE)(v) & (VALUE)~RUBY_Qnil) == 0)
-#define RB_NIL_P(v) !((VALUE)(v) != RUBY_Qnil)
-#define RTEST(v) RB_TEST(v)
-#define NIL_P(v) RB_NIL_P(v)
-
-#define CLASS_OF(v) rb_class_of((VALUE)(v))
-
-enum ruby_value_type {
- RUBY_T_NONE = 0x00,
-
- RUBY_T_OBJECT = 0x01,
- RUBY_T_CLASS = 0x02,
- RUBY_T_MODULE = 0x03,
- RUBY_T_FLOAT = 0x04,
- RUBY_T_STRING = 0x05,
- RUBY_T_REGEXP = 0x06,
- RUBY_T_ARRAY = 0x07,
- RUBY_T_HASH = 0x08,
- RUBY_T_STRUCT = 0x09,
- RUBY_T_BIGNUM = 0x0a,
- RUBY_T_FILE = 0x0b,
- RUBY_T_DATA = 0x0c,
- RUBY_T_MATCH = 0x0d,
- RUBY_T_COMPLEX = 0x0e,
- RUBY_T_RATIONAL = 0x0f,
-
- RUBY_T_NIL = 0x11,
- RUBY_T_TRUE = 0x12,
- RUBY_T_FALSE = 0x13,
- RUBY_T_SYMBOL = 0x14,
- RUBY_T_FIXNUM = 0x15,
- RUBY_T_UNDEF = 0x16,
-
- RUBY_T_IMEMO = 0x1a,
- RUBY_T_NODE = 0x1b,
- RUBY_T_ICLASS = 0x1c,
- RUBY_T_ZOMBIE = 0x1d,
-
- RUBY_T_MASK = 0x1f
-};
-
-#define T_NONE RUBY_T_NONE
-#define T_NIL RUBY_T_NIL
-#define T_OBJECT RUBY_T_OBJECT
-#define T_CLASS RUBY_T_CLASS
-#define T_ICLASS RUBY_T_ICLASS
-#define T_MODULE RUBY_T_MODULE
-#define T_FLOAT RUBY_T_FLOAT
-#define T_STRING RUBY_T_STRING
-#define T_REGEXP RUBY_T_REGEXP
-#define T_ARRAY RUBY_T_ARRAY
-#define T_HASH RUBY_T_HASH
-#define T_STRUCT RUBY_T_STRUCT
-#define T_BIGNUM RUBY_T_BIGNUM
-#define T_FILE RUBY_T_FILE
-#define T_FIXNUM RUBY_T_FIXNUM
-#define T_TRUE RUBY_T_TRUE
-#define T_FALSE RUBY_T_FALSE
-#define T_DATA RUBY_T_DATA
-#define T_MATCH RUBY_T_MATCH
-#define T_SYMBOL RUBY_T_SYMBOL
-#define T_RATIONAL RUBY_T_RATIONAL
-#define T_COMPLEX RUBY_T_COMPLEX
-#define T_IMEMO RUBY_T_IMEMO
-#define T_UNDEF RUBY_T_UNDEF
-#define T_NODE RUBY_T_NODE
-#define T_ZOMBIE RUBY_T_ZOMBIE
-#define T_MASK RUBY_T_MASK
-
-#define RB_BUILTIN_TYPE(x) (int)(((struct RBasic*)(x))->flags & RUBY_T_MASK)
-#define BUILTIN_TYPE(x) RB_BUILTIN_TYPE(x)
-
-static inline int rb_type(VALUE obj);
-#define TYPE(x) rb_type((VALUE)(x))
-
-#define RB_FLOAT_TYPE_P(obj) (\
- RB_FLONUM_P(obj) || \
- (!RB_SPECIAL_CONST_P(obj) && RB_BUILTIN_TYPE(obj) == RUBY_T_FLOAT))
-
-#define RB_TYPE_P(obj, type) ( \
- ((type) == RUBY_T_FIXNUM) ? RB_FIXNUM_P(obj) : \
- ((type) == RUBY_T_TRUE) ? ((obj) == RUBY_Qtrue) : \
- ((type) == RUBY_T_FALSE) ? ((obj) == RUBY_Qfalse) : \
- ((type) == RUBY_T_NIL) ? ((obj) == RUBY_Qnil) : \
- ((type) == RUBY_T_UNDEF) ? ((obj) == RUBY_Qundef) : \
- ((type) == RUBY_T_SYMBOL) ? RB_SYMBOL_P(obj) : \
- ((type) == RUBY_T_FLOAT) ? RB_FLOAT_TYPE_P(obj) : \
- (!RB_SPECIAL_CONST_P(obj) && RB_BUILTIN_TYPE(obj) == (type)))
-
-#ifdef __GNUC__
-#define RB_GC_GUARD(v) \
- (*__extension__ ({ \
- volatile VALUE *rb_gc_guarded_ptr = &(v); \
- __asm__("" : : "m"(rb_gc_guarded_ptr)); \
- rb_gc_guarded_ptr; \
- }))
-#elif defined _MSC_VER
-#pragma optimize("", off)
-static inline volatile VALUE *rb_gc_guarded_ptr(volatile VALUE *ptr) {return ptr;}
-#pragma optimize("", on)
-#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr(&(v)))
-#else
-volatile VALUE *rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val);
-#define HAVE_RB_GC_GUARDED_PTR_VAL 1
-#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr_val(&(v),(v)))
-#endif
-
-#ifdef __GNUC__
-#define RB_UNUSED_VAR(x) x __attribute__ ((unused))
-#else
-#define RB_UNUSED_VAR(x) x
-#endif
-
-void rb_check_type(VALUE,int);
-#define Check_Type(v,t) rb_check_type((VALUE)(v),(t))
-
-VALUE rb_str_to_str(VALUE);
-VALUE rb_string_value(volatile VALUE*);
-char *rb_string_value_ptr(volatile VALUE*);
-char *rb_string_value_cstr(volatile VALUE*);
-
-#define StringValue(v) rb_string_value(&(v))
-#define StringValuePtr(v) rb_string_value_ptr(&(v))
-#define StringValueCStr(v) rb_string_value_cstr(&(v))
-
-void rb_check_safe_obj(VALUE);
-#define SafeStringValue(v) do {\
- StringValue(v);\
- rb_check_safe_obj(v);\
-} while (0)
-#if GCC_VERSION_SINCE(4,4,0)
-void rb_check_safe_str(VALUE) __attribute__((error("rb_check_safe_str() and Check_SafeStr() are obsolete; use SafeStringValue() instead")));
-# define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
-#else
-# define rb_check_safe_str(x) [<"rb_check_safe_str() is obsolete; use SafeStringValue() instead">]
-# define Check_SafeStr(v) [<"Check_SafeStr() is obsolete; use SafeStringValue() instead">]
-#endif
-
-VALUE rb_str_export(VALUE);
-#define ExportStringValue(v) do {\
- SafeStringValue(v);\
- (v) = rb_str_export(v);\
-} while (0)
-VALUE rb_str_export_locale(VALUE);
-
VALUE rb_get_path(VALUE);
#define FilePathValue(v) (RB_GC_GUARD(v) = rb_get_path(v))
VALUE rb_get_path_no_checksafe(VALUE);
-#define FilePathStringValue(v) ((v) = rb_get_path_no_checksafe(v))
-
-#define RUBY_SAFE_LEVEL_MAX 1
-void rb_secure(int);
-int rb_safe_level(void);
-void rb_set_safe_level(int);
-#if GCC_VERSION_SINCE(4,4,0)
-int ruby_safe_level_2_error(void) __attribute__((error("$SAFE=2 to 4 are obsolete")));
-int ruby_safe_level_2_warning(void) __attribute__((const,warning("$SAFE=2 to 4 are obsolete")));
-# ifdef RUBY_EXPORT
-# define ruby_safe_level_2_warning() ruby_safe_level_2_error()
-# endif
-# if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
-# define RUBY_SAFE_LEVEL_INVALID_P(level) \
- __extension__(\
- __builtin_choose_expr(\
- __builtin_constant_p(level), \
- ((level) < 0 || RUBY_SAFE_LEVEL_MAX < (level)), 0))
-# define RUBY_SAFE_LEVEL_CHECK(level, type) \
- __extension__(__builtin_choose_expr(RUBY_SAFE_LEVEL_INVALID_P(level), ruby_safe_level_2_##type(), (level)))
-# else
-/* in gcc 4.8 or earlier, __builtin_choose_expr() does not consider
- * __builtin_constant_p(variable) a constant expression.
- */
-# define RUBY_SAFE_LEVEL_INVALID_P(level) \
- __extension__(__builtin_constant_p(level) && \
- ((level) < 0 || RUBY_SAFE_LEVEL_MAX < (level)))
-# define RUBY_SAFE_LEVEL_CHECK(level, type) \
- (RUBY_SAFE_LEVEL_INVALID_P(level) ? ruby_safe_level_2_##type() : (level))
-# endif
-# define rb_secure(level) rb_secure(RUBY_SAFE_LEVEL_CHECK(level, warning))
-# define rb_set_safe_level(level) rb_set_safe_level(RUBY_SAFE_LEVEL_CHECK(level, error))
-#endif
-void rb_set_safe_level_force(int);
-CONSTFUNC(void rb_secure_update(VALUE));
-NORETURN(void rb_insecure_operation(void));
-
-VALUE rb_errinfo(void);
-void rb_set_errinfo(VALUE);
-
-long rb_num2long(VALUE);
-unsigned long rb_num2ulong(VALUE);
-static inline long
-rb_num2long_inline(VALUE x)
-{
- if (RB_FIXNUM_P(x))
- return RB_FIX2LONG(x);
- else
- return rb_num2long(x);
-}
-#define RB_NUM2LONG(x) rb_num2long_inline(x)
-#define NUM2LONG(x) RB_NUM2LONG(x)
-static inline unsigned long
-rb_num2ulong_inline(VALUE x)
-{
- if (RB_FIXNUM_P(x))
- return RB_FIX2ULONG(x);
- else
- return rb_num2ulong(x);
-}
-#define RB_NUM2ULONG(x) rb_num2ulong_inline(x)
-#define NUM2ULONG(x) RB_NUM2ULONG(x)
-#if SIZEOF_INT < SIZEOF_LONG
-long rb_num2int(VALUE);
-long rb_fix2int(VALUE);
-#define RB_FIX2INT(x) ((int)rb_fix2int((VALUE)(x)))
-
-static inline int
-rb_num2int_inline(VALUE x)
-{
- if (RB_FIXNUM_P(x))
- return (int)rb_fix2int(x);
- else
- return (int)rb_num2int(x);
-}
-#define RB_NUM2INT(x) rb_num2int_inline(x)
-
-unsigned long rb_num2uint(VALUE);
-#define RB_NUM2UINT(x) ((unsigned int)rb_num2uint(x))
-unsigned long rb_fix2uint(VALUE);
-#define RB_FIX2UINT(x) ((unsigned int)rb_fix2uint(x))
-#else /* SIZEOF_INT < SIZEOF_LONG */
-#define RB_NUM2INT(x) ((int)RB_NUM2LONG(x))
-#define RB_NUM2UINT(x) ((unsigned int)RB_NUM2ULONG(x))
-#define RB_FIX2INT(x) ((int)RB_FIX2LONG(x))
-#define RB_FIX2UINT(x) ((unsigned int)RB_FIX2ULONG(x))
-#endif /* SIZEOF_INT < SIZEOF_LONG */
-#define NUM2INT(x) RB_NUM2INT(x)
-#define NUM2UINT(x) RB_NUM2UINT(x)
-#define FIX2INT(x) RB_FIX2INT(x)
-#define FIX2UINT(x) RB_FIX2UINT(x)
-
-short rb_num2short(VALUE);
-unsigned short rb_num2ushort(VALUE);
-short rb_fix2short(VALUE);
-unsigned short rb_fix2ushort(VALUE);
-#define RB_FIX2SHORT(x) (rb_fix2short((VALUE)(x)))
-#define FIX2SHORT(x) RB_FIX2SHORT(x)
-static inline short
-rb_num2short_inline(VALUE x)
-{
- if (RB_FIXNUM_P(x))
- return rb_fix2short(x);
- else
- return rb_num2short(x);
-}
-
-#define RB_NUM2SHORT(x) rb_num2short_inline(x)
-#define RB_NUM2USHORT(x) rb_num2ushort(x)
-#define NUM2SHORT(x) RB_NUM2SHORT(x)
-#define NUM2USHORT(x) RB_NUM2USHORT(x)
-
-#ifdef HAVE_LONG_LONG
-LONG_LONG rb_num2ll(VALUE);
-unsigned LONG_LONG rb_num2ull(VALUE);
-static inline LONG_LONG
-rb_num2ll_inline(VALUE x)
-{
- if (RB_FIXNUM_P(x))
- return RB_FIX2LONG(x);
- else
- return rb_num2ll(x);
-}
-# define RB_NUM2LL(x) rb_num2ll_inline(x)
-# define RB_NUM2ULL(x) rb_num2ull(x)
-# define NUM2LL(x) RB_NUM2LL(x)
-# define NUM2ULL(x) RB_NUM2ULL(x)
-#endif
-
-#if !defined(NUM2OFFT)
-# if defined(HAVE_LONG_LONG) && SIZEOF_OFF_T > SIZEOF_LONG
-# define NUM2OFFT(x) ((off_t)NUM2LL(x))
-# else
-# define NUM2OFFT(x) NUM2LONG(x)
-# endif
-#endif
-
-#if defined(HAVE_LONG_LONG) && SIZEOF_SIZE_T > SIZEOF_LONG
-# define NUM2SIZET(x) ((size_t)NUM2ULL(x))
-# define NUM2SSIZET(x) ((ssize_t)NUM2LL(x))
-#else
-# define NUM2SIZET(x) NUM2ULONG(x)
-# define NUM2SSIZET(x) NUM2LONG(x)
-#endif
-
-double rb_num2dbl(VALUE);
-#define NUM2DBL(x) rb_num2dbl((VALUE)(x))
-
-VALUE rb_uint2big(VALUE);
-VALUE rb_int2big(SIGNED_VALUE);
-
-VALUE rb_newobj(void);
-VALUE rb_newobj_of(VALUE, VALUE);
-VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type);
-#define RB_NEWOBJ(obj,type) type *(obj) = (type*)rb_newobj()
-#define RB_NEWOBJ_OF(obj,type,klass,flags) type *(obj) = (type*)rb_newobj_of(klass, flags)
-#define NEWOBJ(obj,type) RB_NEWOBJ(obj,type)
-#define NEWOBJ_OF(obj,type,klass,flags) RB_NEWOBJ_OF(obj,type,klass,flags) /* core has special NEWOBJ_OF() in internal.h */
-#define OBJSETUP(obj,c,t) rb_obj_setup(obj, c, t) /* use NEWOBJ_OF instead of NEWOBJ()+OBJSETUP() */
-#define CLONESETUP(clone,obj) rb_clone_setup(clone,obj)
-#define DUPSETUP(dup,obj) rb_dup_setup(dup,obj)
-
-#ifndef USE_RGENGC
-#define USE_RGENGC 1
-#ifndef USE_RINCGC
-#define USE_RINCGC 1
-#endif
-#endif
-
-#if USE_RGENGC == 0
-#define USE_RINCGC 0
-#endif
-
-#ifndef RGENGC_WB_PROTECTED_ARRAY
-#define RGENGC_WB_PROTECTED_ARRAY 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_HASH
-#define RGENGC_WB_PROTECTED_HASH 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_STRUCT
-#define RGENGC_WB_PROTECTED_STRUCT 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_STRING
-#define RGENGC_WB_PROTECTED_STRING 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_OBJECT
-#define RGENGC_WB_PROTECTED_OBJECT 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_REGEXP
-#define RGENGC_WB_PROTECTED_REGEXP 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_CLASS
-#define RGENGC_WB_PROTECTED_CLASS 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_FLOAT
-#define RGENGC_WB_PROTECTED_FLOAT 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_COMPLEX
-#define RGENGC_WB_PROTECTED_COMPLEX 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_RATIONAL
-#define RGENGC_WB_PROTECTED_RATIONAL 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_BIGNUM
-#define RGENGC_WB_PROTECTED_BIGNUM 1
-#endif
-#ifndef RGENGC_WB_PROTECTED_NODE_CREF
-#define RGENGC_WB_PROTECTED_NODE_CREF 1
-#endif
-
-#ifdef __GNUC__
-__extension__
-#endif
-enum ruby_fl_type {
- RUBY_FL_WB_PROTECTED = (1<<5),
- RUBY_FL_PROMOTED0 = (1<<5),
- RUBY_FL_PROMOTED1 = (1<<6),
- RUBY_FL_PROMOTED = RUBY_FL_PROMOTED0|RUBY_FL_PROMOTED1,
- RUBY_FL_FINALIZE = (1<<7),
- RUBY_FL_TAINT = (1<<8),
- RUBY_FL_UNTRUSTED = RUBY_FL_TAINT,
- RUBY_FL_EXIVAR = (1<<10),
- RUBY_FL_FREEZE = (1<<11),
-
- RUBY_FL_USHIFT = 12,
-
-#define RUBY_FL_USER_N(n) RUBY_FL_USER##n = (1<<(RUBY_FL_USHIFT+n))
- RUBY_FL_USER_N(0),
- RUBY_FL_USER_N(1),
- RUBY_FL_USER_N(2),
- RUBY_FL_USER_N(3),
- RUBY_FL_USER_N(4),
- RUBY_FL_USER_N(5),
- RUBY_FL_USER_N(6),
- RUBY_FL_USER_N(7),
- RUBY_FL_USER_N(8),
- RUBY_FL_USER_N(9),
- RUBY_FL_USER_N(10),
- RUBY_FL_USER_N(11),
- RUBY_FL_USER_N(12),
- RUBY_FL_USER_N(13),
- RUBY_FL_USER_N(14),
- RUBY_FL_USER_N(15),
- RUBY_FL_USER_N(16),
- RUBY_FL_USER_N(17),
- RUBY_FL_USER_N(18),
-#if defined ENUM_OVER_INT || SIZEOF_INT*CHAR_BIT>12+19+1
- RUBY_FL_USER_N(19),
-#else
-#define RUBY_FL_USER19 (((VALUE)1)<<(RUBY_FL_USHIFT+19))
-#endif
-
- RUBY_ELTS_SHARED = RUBY_FL_USER2,
- RUBY_FL_DUPPED = (RUBY_T_MASK|RUBY_FL_EXIVAR|RUBY_FL_TAINT),
- RUBY_FL_SINGLETON = RUBY_FL_USER0
-};
-
-struct RBasic {
- VALUE flags;
- const VALUE klass;
-}
-#ifdef __GNUC__
- __attribute__((aligned(sizeof(VALUE))))
-#endif
-;
-
-VALUE rb_obj_hide(VALUE obj);
-VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change klass information */
-
-#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
-# define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \
- __extension__( \
- __builtin_choose_expr( \
- RGENGC_WB_PROTECTED_##type, \
- OBJ_WB_UNPROTECT((VALUE)(obj)), ((VALUE)(obj))))
-#else
-# define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \
- (RGENGC_WB_PROTECTED_##type ? \
- OBJ_WB_UNPROTECT((VALUE)(obj)) : ((VALUE)(obj)))
-#endif
-
-#define RBASIC_CLASS(obj) (RBASIC(obj)->klass)
-
-#define ROBJECT_EMBED_LEN_MAX ROBJECT_EMBED_LEN_MAX
-#define ROBJECT_EMBED ROBJECT_EMBED
-enum ruby_robject_flags {
- ROBJECT_EMBED_LEN_MAX = 3,
- ROBJECT_EMBED = RUBY_FL_USER1,
-
- ROBJECT_ENUM_END
-};
-
-struct RObject {
- struct RBasic basic;
- union {
- struct {
- uint32_t numiv;
- VALUE *ivptr;
- void *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
- } heap;
- VALUE ary[ROBJECT_EMBED_LEN_MAX];
- } as;
-};
-#define ROBJECT_NUMIV(o) \
- ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
- ROBJECT_EMBED_LEN_MAX : \
- ROBJECT(o)->as.heap.numiv)
-#define ROBJECT_IVPTR(o) \
- ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
- ROBJECT(o)->as.ary : \
- ROBJECT(o)->as.heap.ivptr)
-#define ROBJECT_IV_INDEX_TBL(o) \
- ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
- RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \
- ROBJECT(o)->as.heap.iv_index_tbl)
-
-#define RCLASS_SUPER(c) rb_class_get_superclass(c)
-#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
-#define RMODULE_CONST_TBL(m) RCLASS_CONST_TBL(m)
-#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
-#define RMODULE_SUPER(m) RCLASS_SUPER(m)
-#define RMODULE_IS_OVERLAID RMODULE_IS_OVERLAID
-#define RMODULE_IS_REFINEMENT RMODULE_IS_REFINEMENT
-#define RMODULE_INCLUDED_INTO_REFINEMENT RMODULE_INCLUDED_INTO_REFINEMENT
-enum ruby_rmodule_flags {
- RMODULE_IS_OVERLAID = RUBY_FL_USER2,
- RMODULE_IS_REFINEMENT = RUBY_FL_USER3,
- RMODULE_INCLUDED_INTO_REFINEMENT = RUBY_FL_USER4,
-
- RMODULE_ENUM_END
-};
-
-PUREFUNC(double rb_float_value(VALUE));
-VALUE rb_float_new(double);
-VALUE rb_float_new_in_heap(double);
-
-#define RFLOAT_VALUE(v) rb_float_value(v)
-#define DBL2NUM(dbl) rb_float_new(dbl)
-
-#define RUBY_ELTS_SHARED RUBY_ELTS_SHARED
-#define ELTS_SHARED RUBY_ELTS_SHARED
-
-#define RSTRING_NOEMBED RSTRING_NOEMBED
-#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
-#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
-#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
-#define RSTRING_FSTR RSTRING_FSTR
-enum ruby_rstring_flags {
- RSTRING_NOEMBED = RUBY_FL_USER1,
- RSTRING_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|
- RUBY_FL_USER5|RUBY_FL_USER6),
- RSTRING_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+2),
- RSTRING_EMBED_LEN_MAX = (int)((sizeof(VALUE)*3)/sizeof(char)-1),
- RSTRING_FSTR = RUBY_FL_USER17,
-
- RSTRING_ENUM_END
-};
-struct RString {
- struct RBasic basic;
- union {
- struct {
- long len;
- char *ptr;
- union {
- long capa;
- VALUE shared;
- } aux;
- } heap;
- char ary[RSTRING_EMBED_LEN_MAX + 1];
- } as;
-};
-#define RSTRING_EMBED_LEN(str) \
- (long)((RBASIC(str)->flags >> RSTRING_EMBED_LEN_SHIFT) & \
- (RSTRING_EMBED_LEN_MASK >> RSTRING_EMBED_LEN_SHIFT))
-#define RSTRING_LEN(str) \
- (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \
- RSTRING_EMBED_LEN(str) : \
- RSTRING(str)->as.heap.len)
-#define RSTRING_PTR(str) \
- (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \
- RSTRING(str)->as.ary : \
- RSTRING(str)->as.heap.ptr)
-#define RSTRING_END(str) \
- (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \
- (RSTRING(str)->as.ary + RSTRING_EMBED_LEN(str)) : \
- (RSTRING(str)->as.heap.ptr + RSTRING(str)->as.heap.len))
-#define RSTRING_LENINT(str) rb_long2int(RSTRING_LEN(str))
-#define RSTRING_GETMEM(str, ptrvar, lenvar) \
- (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \
- ((ptrvar) = RSTRING(str)->as.ary, (lenvar) = RSTRING_EMBED_LEN(str)) : \
- ((ptrvar) = RSTRING(str)->as.heap.ptr, (lenvar) = RSTRING(str)->as.heap.len))
-
-enum ruby_rarray_flags {
- RARRAY_EMBED_LEN_MAX = 3,
- RARRAY_EMBED_FLAG = RUBY_FL_USER1,
- /* RUBY_FL_USER2 is for ELTS_SHARED */
- RARRAY_EMBED_LEN_MASK = (RUBY_FL_USER4|RUBY_FL_USER3),
- RARRAY_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+3),
-
- RARRAY_ENUM_END
-};
-#define RARRAY_EMBED_FLAG (VALUE)RARRAY_EMBED_FLAG
-#define RARRAY_EMBED_LEN_MASK (VALUE)RARRAY_EMBED_LEN_MASK
-#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
-#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
-struct RArray {
- struct RBasic basic;
- union {
- struct {
- long len;
- union {
- long capa;
- VALUE shared;
- } aux;
- const VALUE *ptr;
- } heap;
- const VALUE ary[RARRAY_EMBED_LEN_MAX];
- } as;
-};
-#define RARRAY_EMBED_LEN(a) \
- (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
- (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT))
-#define RARRAY_LEN(a) rb_array_len(a)
-#define RARRAY_LENINT(ary) rb_long2int(RARRAY_LEN(ary))
-#define RARRAY_CONST_PTR(a) rb_array_const_ptr(a)
-
-#define RARRAY_PTR_USE_START(a) ((VALUE *)RARRAY_CONST_PTR(a))
-#define RARRAY_PTR_USE_END(a) /* */
-
-#define RARRAY_PTR_USE(ary, ptr_name, expr) do { \
- const VALUE _ary = (ary); \
- VALUE *ptr_name = (VALUE *)RARRAY_PTR_USE_START(_ary); \
- expr; \
- RARRAY_PTR_USE_END(_ary); \
-} while (0)
-
-#define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i])
-#define RARRAY_ASET(a, i, v) do { \
- const VALUE _ary = (a); \
- VALUE *ptr = (VALUE *)RARRAY_PTR_USE_START(_ary); \
- RB_OBJ_WRITE(_ary, &ptr[i], (v)); \
- RARRAY_PTR_USE_END(_ary); \
-} while (0)
-
-#define RARRAY_PTR(a) ((VALUE *)RARRAY_CONST_PTR(RB_OBJ_WB_UNPROTECT_FOR(ARRAY, a)))
-
-struct RRegexp {
- struct RBasic basic;
- struct re_pattern_buffer *ptr;
- const VALUE src;
- unsigned long usecnt;
-};
-#define RREGEXP_PTR(r) (RREGEXP(r)->ptr)
-#define RREGEXP_SRC(r) (RREGEXP(r)->src)
-#define RREGEXP_SRC_PTR(r) RSTRING_PTR(RREGEXP(r)->src)
-#define RREGEXP_SRC_LEN(r) RSTRING_LEN(RREGEXP(r)->src)
-#define RREGEXP_SRC_END(r) RSTRING_END(RREGEXP(r)->src)
-
-/* RHASH_TBL allocates st_table if not available. */
-#define RHASH_TBL(h) rb_hash_tbl(h)
-#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)
-#define RHASH_IFNONE(h) rb_hash_ifnone(h)
-#define RHASH_SIZE(h) NUM2SIZET(rb_hash_size(h))
-#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
-#define RHASH_SET_IFNONE(h, ifnone) rb_hash_set_ifnone((VALUE)h, ifnone)
-
-struct RFile {
- struct RBasic basic;
- struct rb_io_t *fptr;
-};
-
-#define RCOMPLEX_SET_REAL(cmp, r) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->real,(r))
-#define RCOMPLEX_SET_IMAG(cmp, i) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->imag,(i))
-
-struct RData {
- struct RBasic basic;
- void (*dmark)(void*);
- void (*dfree)(void*);
- void *data;
-};
-
-typedef struct rb_data_type_struct rb_data_type_t;
-
-struct rb_data_type_struct {
- const char *wrap_struct_name;
- struct {
- void (*dmark)(void*);
- void (*dfree)(void*);
- size_t (*dsize)(const void *);
- void *reserved[2]; /* For future extension.
- This array *must* be filled with ZERO. */
- } function;
- const rb_data_type_t *parent;
- void *data; /* This area can be used for any purpose
- by a programmer who define the type. */
- VALUE flags; /* RUBY_FL_WB_PROTECTED */
-};
-
-#define HAVE_TYPE_RB_DATA_TYPE_T 1
-#define HAVE_RB_DATA_TYPE_T_FUNCTION 1
-#define HAVE_RB_DATA_TYPE_T_PARENT 1
-
-struct RTypedData {
- struct RBasic basic;
- const rb_data_type_t *type;
- VALUE typed_flag; /* 1 or not */
- void *data;
-};
-
-#define DATA_PTR(dta) (RDATA(dta)->data)
-
-#define RTYPEDDATA_P(v) (RTYPEDDATA(v)->typed_flag == 1)
-#define RTYPEDDATA_TYPE(v) (RTYPEDDATA(v)->type)
-#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data)
-
-/*
-#define RUBY_DATA_FUNC(func) ((void (*)(void*))(func))
-*/
-typedef void (*RUBY_DATA_FUNC)(void*);
-
-#ifndef RUBY_UNTYPED_DATA_WARNING
-# if defined RUBY_EXPORT
-# define RUBY_UNTYPED_DATA_WARNING 1
-# else
-# define RUBY_UNTYPED_DATA_WARNING 0
-# endif
-#endif
-VALUE rb_data_object_wrap(VALUE,void*,RUBY_DATA_FUNC,RUBY_DATA_FUNC);
-VALUE rb_data_object_zalloc(VALUE,size_t,RUBY_DATA_FUNC,RUBY_DATA_FUNC);
-VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *);
-VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type);
-int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);
-int rb_typeddata_is_kind_of(VALUE, const rb_data_type_t *);
-void *rb_check_typeddata(VALUE, const rb_data_type_t *);
-#define Check_TypedStruct(v,t) rb_check_typeddata((VALUE)(v),(t))
-#define RUBY_DEFAULT_FREE ((RUBY_DATA_FUNC)-1)
-#define RUBY_NEVER_FREE ((RUBY_DATA_FUNC)0)
-#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
-#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
-
-/* bits for rb_data_type_struct::flags */
-#define RUBY_TYPED_FREE_IMMEDIATELY 1 /* TYPE field */
-#define RUBY_TYPED_WB_PROTECTED RUBY_FL_WB_PROTECTED /* THIS FLAG DEPENDS ON Ruby version */
-#define RUBY_TYPED_PROMOTED1 RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */
-
-#define Data_Wrap_Struct(klass,mark,free,sval)\
- rb_data_object_wrap((klass),(sval),(RUBY_DATA_FUNC)(mark),(RUBY_DATA_FUNC)(free))
-
-#define Data_Make_Struct0(result, klass, type, size, mark, free, sval) \
- VALUE result = rb_data_object_zalloc((klass), (size), \
- (RUBY_DATA_FUNC)(mark), \
- (RUBY_DATA_FUNC)(free)); \
- (void)((sval) = (type *)DATA_PTR(result));
-
-#ifdef __GNUC__
-#define Data_Make_Struct(klass,type,mark,free,sval) ({\
- Data_Make_Struct0(data_struct_obj, klass, type, sizeof(type), mark, free, sval); \
- data_struct_obj; \
-})
-#else
-#define Data_Make_Struct(klass,type,mark,free,sval) (\
- rb_data_object_make((klass),(RUBY_DATA_FUNC)(mark),(RUBY_DATA_FUNC)(free),(void **)&(sval),sizeof(type)) \
-)
-#endif
-
-#define TypedData_Wrap_Struct(klass,data_type,sval)\
- rb_data_typed_object_wrap((klass),(sval),(data_type))
-
-#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
- VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
- (void)((sval) = (type *)DATA_PTR(result));
-
-#ifdef __GNUC__
-#define TypedData_Make_Struct(klass, type, data_type, sval) ({\
- TypedData_Make_Struct0(data_struct_obj, klass, type, sizeof(type), data_type, sval); \
- data_struct_obj; \
-})
-#else
-#define TypedData_Make_Struct(klass, type, data_type, sval) (\
- rb_data_typed_object_make((klass),(data_type),(void **)&(sval),sizeof(type)) \
-)
-#endif
-
-#define Data_Get_Struct(obj,type,sval) \
- ((sval) = (type*)rb_data_object_get(obj))
-
-#define TypedData_Get_Struct(obj,type,data_type,sval) \
- ((sval) = (type*)rb_check_typeddata((obj), (data_type)))
-
-#define RSTRUCT_LEN(st) NUM2LONG(rb_struct_size(st))
-#define RSTRUCT_PTR(st) rb_struct_ptr(st)
-#define RSTRUCT_SET(st, idx, v) rb_struct_aset(st, INT2NUM(idx), (v))
-#define RSTRUCT_GET(st, idx) rb_struct_aref(st, INT2NUM(idx))
-
-int rb_big_sign(VALUE);
-#define RBIGNUM_SIGN(b) (rb_big_sign(b))
-#define RBIGNUM_POSITIVE_P(b) (RBIGNUM_SIGN(b)!=0)
-#define RBIGNUM_NEGATIVE_P(b) (RBIGNUM_SIGN(b)==0)
-
-#define R_CAST(st) (struct st*)
-#define RBASIC(obj) (R_CAST(RBasic)(obj))
-#define ROBJECT(obj) (R_CAST(RObject)(obj))
-#define RCLASS(obj) (R_CAST(RClass)(obj))
-#define RMODULE(obj) RCLASS(obj)
-#define RSTRING(obj) (R_CAST(RString)(obj))
-#define RREGEXP(obj) (R_CAST(RRegexp)(obj))
-#define RARRAY(obj) (R_CAST(RArray)(obj))
-#define RDATA(obj) (R_CAST(RData)(obj))
-#define RTYPEDDATA(obj) (R_CAST(RTypedData)(obj))
-#define RFILE(obj) (R_CAST(RFile)(obj))
-
-#define FL_SINGLETON ((VALUE)RUBY_FL_SINGLETON)
-#define FL_WB_PROTECTED ((VALUE)RUBY_FL_WB_PROTECTED)
-#define FL_PROMOTED0 ((VALUE)RUBY_FL_PROMOTED0)
-#define FL_PROMOTED1 ((VALUE)RUBY_FL_PROMOTED1)
-#define FL_FINALIZE ((VALUE)RUBY_FL_FINALIZE)
-#define FL_TAINT ((VALUE)RUBY_FL_TAINT)
-#define FL_UNTRUSTED ((VALUE)RUBY_FL_UNTRUSTED)
-#define FL_EXIVAR ((VALUE)RUBY_FL_EXIVAR)
-#define FL_FREEZE ((VALUE)RUBY_FL_FREEZE)
-
-#define FL_USHIFT ((VALUE)RUBY_FL_USHIFT)
-
-#define FL_USER0 ((VALUE)RUBY_FL_USER0)
-#define FL_USER1 ((VALUE)RUBY_FL_USER1)
-#define FL_USER2 ((VALUE)RUBY_FL_USER2)
-#define FL_USER3 ((VALUE)RUBY_FL_USER3)
-#define FL_USER4 ((VALUE)RUBY_FL_USER4)
-#define FL_USER5 ((VALUE)RUBY_FL_USER5)
-#define FL_USER6 ((VALUE)RUBY_FL_USER6)
-#define FL_USER7 ((VALUE)RUBY_FL_USER7)
-#define FL_USER8 ((VALUE)RUBY_FL_USER8)
-#define FL_USER9 ((VALUE)RUBY_FL_USER9)
-#define FL_USER10 ((VALUE)RUBY_FL_USER10)
-#define FL_USER11 ((VALUE)RUBY_FL_USER11)
-#define FL_USER12 ((VALUE)RUBY_FL_USER12)
-#define FL_USER13 ((VALUE)RUBY_FL_USER13)
-#define FL_USER14 ((VALUE)RUBY_FL_USER14)
-#define FL_USER15 ((VALUE)RUBY_FL_USER15)
-#define FL_USER16 ((VALUE)RUBY_FL_USER16)
-#define FL_USER17 ((VALUE)RUBY_FL_USER17)
-#define FL_USER18 ((VALUE)RUBY_FL_USER18)
-#define FL_USER19 ((VALUE)RUBY_FL_USER19)
-
-#define RB_SPECIAL_CONST_P(x) (RB_IMMEDIATE_P(x) || !RB_TEST(x))
-#define SPECIAL_CONST_P(x) RB_SPECIAL_CONST_P(x)
-
-#define RB_FL_ABLE(x) (!RB_SPECIAL_CONST_P(x) && RB_BUILTIN_TYPE(x) != RUBY_T_NODE)
-#define RB_FL_TEST_RAW(x,f) (RBASIC(x)->flags&(f))
-#define RB_FL_TEST(x,f) (RB_FL_ABLE(x)?RB_FL_TEST_RAW((x),(f)):0)
-#define RB_FL_ANY_RAW(x,f) RB_FL_TEST_RAW((x),(f))
-#define RB_FL_ANY(x,f) RB_FL_TEST((x),(f))
-#define RB_FL_ALL_RAW(x,f) (RB_FL_TEST_RAW((x),(f)) == (f))
-#define RB_FL_ALL(x,f) (RB_FL_TEST((x),(f)) == (f))
-#define RB_FL_SET_RAW(x,f) (void)(RBASIC(x)->flags |= (f))
-#define RB_FL_SET(x,f) (RB_FL_ABLE(x) ? RB_FL_SET_RAW(x, f) : (void)0)
-#define RB_FL_UNSET_RAW(x,f) (void)(RBASIC(x)->flags &= ~(VALUE)(f))
-#define RB_FL_UNSET(x,f) (RB_FL_ABLE(x) ? RB_FL_UNSET_RAW(x, f) : (void)0)
-#define RB_FL_REVERSE_RAW(x,f) (void)(RBASIC(x)->flags ^= (f))
-#define RB_FL_REVERSE(x,f) (RB_FL_ABLE(x) ? RB_FL_REVERSE_RAW(x, f) : (void)0)
-
-#define RB_OBJ_TAINTABLE(x) (RB_FL_ABLE(x) && RB_BUILTIN_TYPE(x) != RUBY_T_BIGNUM && RB_BUILTIN_TYPE(x) != RUBY_T_FLOAT)
-#define RB_OBJ_TAINTED_RAW(x) RB_FL_TEST_RAW(x, RUBY_FL_TAINT)
-#define RB_OBJ_TAINTED(x) (!!RB_FL_TEST((x), RUBY_FL_TAINT))
-#define RB_OBJ_TAINT_RAW(x) RB_FL_SET_RAW(x, RUBY_FL_TAINT)
-#define RB_OBJ_TAINT(x) (RB_OBJ_TAINTABLE(x) ? RB_OBJ_TAINT_RAW(x) : (void)0)
-#define RB_OBJ_UNTRUSTED(x) RB_OBJ_TAINTED(x)
-#define RB_OBJ_UNTRUST(x) RB_OBJ_TAINT(x)
-#define RB_OBJ_INFECT_RAW(x,s) RB_FL_SET_RAW(x, RB_OBJ_TAINTED_RAW(s))
-#define RB_OBJ_INFECT(x,s) ( \
- (RB_OBJ_TAINTABLE(x) && RB_FL_ABLE(s)) ? \
- RB_OBJ_INFECT_RAW(x, s) : (void)0)
-
-#define RB_OBJ_FROZEN_RAW(x) (RBASIC(x)->flags&RUBY_FL_FREEZE)
-#define RB_OBJ_FROZEN(x) (!RB_FL_ABLE(x) || RB_OBJ_FROZEN_RAW(x))
-#define RB_OBJ_FREEZE_RAW(x) (void)(RBASIC(x)->flags |= RUBY_FL_FREEZE)
-#define RB_OBJ_FREEZE(x) rb_obj_freeze_inline((VALUE)x)
-
-/*!
- * \defgroup deprecated_macros deprecated macro APIs
- * \{
- * \par These macros are deprecated. Prefer their `RB_`-prefixed versions.
- */
-#define FL_ABLE(x) RB_FL_ABLE(x)
-#define FL_TEST_RAW(x,f) RB_FL_TEST_RAW(x,f)
-#define FL_TEST(x,f) RB_FL_TEST(x,f)
-#define FL_ANY_RAW(x,f) RB_FL_ANY_RAW(x,f)
-#define FL_ANY(x,f) RB_FL_ANY(x,f)
-#define FL_ALL_RAW(x,f) RB_FL_ALL_RAW(x,f)
-#define FL_ALL(x,f) RB_FL_ALL(x,f)
-#define FL_SET_RAW(x,f) RB_FL_SET_RAW(x,f)
-#define FL_SET(x,f) RB_FL_SET(x,f)
-#define FL_UNSET_RAW(x,f) RB_FL_UNSET_RAW(x,f)
-#define FL_UNSET(x,f) RB_FL_UNSET(x,f)
-#define FL_REVERSE_RAW(x,f) RB_FL_REVERSE_RAW(x,f)
-#define FL_REVERSE(x,f) RB_FL_REVERSE(x,f)
-
-#define OBJ_TAINTABLE(x) RB_OBJ_TAINTABLE(x)
-#define OBJ_TAINTED_RAW(x) RB_OBJ_TAINTED_RAW(x)
-#define OBJ_TAINTED(x) RB_OBJ_TAINTED(x)
-#define OBJ_TAINT_RAW(x) RB_OBJ_TAINT_RAW(x)
-#define OBJ_TAINT(x) RB_OBJ_TAINT(x)
-#define OBJ_UNTRUSTED(x) RB_OBJ_UNTRUSTED(x)
-#define OBJ_UNTRUST(x) RB_OBJ_UNTRUST(x)
-#define OBJ_INFECT_RAW(x,s) RB_OBJ_INFECT_RAW(x,s)
-#define OBJ_INFECT(x,s) RB_OBJ_INFECT(x,s)
-#define OBJ_FROZEN_RAW(x) RB_OBJ_FROZEN_RAW(x)
-#define OBJ_FROZEN(x) RB_OBJ_FROZEN(x)
-#define OBJ_FREEZE_RAW(x) RB_OBJ_FREEZE_RAW(x)
-#define OBJ_FREEZE(x) RB_OBJ_FREEZE(x)
-
-/* \} */
-
-void rb_freeze_singleton_class(VALUE klass);
-
-static inline void
-rb_obj_freeze_inline(VALUE x)
-{
- if (RB_FL_ABLE(x)) {
- RB_OBJ_FREEZE_RAW(x);
- if (RBASIC_CLASS(x) && !(RBASIC(x)->flags & RUBY_FL_SINGLETON)) {
- rb_freeze_singleton_class(x);
- }
- }
-}
-
-#if GCC_VERSION_SINCE(4,4,0)
-# define RUBY_UNTYPED_DATA_FUNC(func) func __attribute__((warning("untyped Data is unsafe; use TypedData instead")))
-#else
-# define RUBY_UNTYPED_DATA_FUNC(func) DEPRECATED(func)
-#endif
-
-#if defined(__GNUC__) && !defined(__NO_INLINE__)
-#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
-RUBY_UNTYPED_DATA_FUNC(static inline VALUE rb_data_object_wrap_warning(VALUE,void*,RUBY_DATA_FUNC,RUBY_DATA_FUNC));
-#endif
-RUBY_UNTYPED_DATA_FUNC(static inline void *rb_data_object_get_warning(VALUE));
-
-static inline VALUE
-rb_data_object_wrap_warning(VALUE klass, void *ptr, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free)
-{
- return rb_data_object_wrap(klass, ptr, mark, free);
-}
-
-#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
-#define rb_data_object_wrap_warning(klass, ptr, mark, free) \
- __extension__( \
- __builtin_choose_expr( \
- __builtin_constant_p(klass) && !(klass), \
- rb_data_object_wrap(klass, ptr, mark, free), \
- rb_data_object_wrap_warning(klass, ptr, mark, free)))
-#endif
-#endif
-
-static inline void *
-rb_data_object_get(VALUE obj)
-{
- Check_Type(obj, RUBY_T_DATA);
- return ((struct RData *)obj)->data;
-}
-
-#if defined(__GNUC__) && !defined(__NO_INLINE__)
-static inline void *
-rb_data_object_get_warning(VALUE obj)
-{
- return rb_data_object_get(obj);
-}
-#endif
-
-static inline VALUE
-rb_data_object_make(VALUE klass, RUBY_DATA_FUNC mark_func, RUBY_DATA_FUNC free_func, void **datap, size_t size)
-{
- Data_Make_Struct0(result, klass, void, size, mark_func, free_func, *datap);
- return result;
-}
-
-static inline VALUE
-rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
-{
- TypedData_Make_Struct0(result, klass, void, size, type, *datap);
- return result;
-}
-
-#ifndef rb_data_object_alloc
-DEPRECATED_BY(rb_data_object_wrap, static inline VALUE rb_data_object_alloc(VALUE,void*,RUBY_DATA_FUNC,RUBY_DATA_FUNC));
-static inline VALUE
-rb_data_object_alloc(VALUE klass, void *data, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
-{
- return rb_data_object_wrap(klass, data, dmark, dfree);
-}
-#endif
-
-#ifndef rb_data_typed_object_alloc
-DEPRECATED_BY(rb_data_typed_object_wrap, static inline VALUE rb_data_typed_object_alloc(VALUE,void*,const rb_data_type_t*));
-static inline VALUE
-rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
-{
- return rb_data_typed_object_wrap(klass, datap, type);
-}
-#endif
-
-#if defined(__GNUC__) && !defined(__NO_INLINE__)
-#define rb_data_object_wrap_0 rb_data_object_wrap
-#define rb_data_object_wrap_1 rb_data_object_wrap_warning
-#define rb_data_object_wrap RUBY_MACRO_SELECT(rb_data_object_wrap_, RUBY_UNTYPED_DATA_WARNING)
-#define rb_data_object_get_0 rb_data_object_get
-#define rb_data_object_get_1 rb_data_object_get_warning
-#define rb_data_object_get RUBY_MACRO_SELECT(rb_data_object_get_, RUBY_UNTYPED_DATA_WARNING)
-#define rb_data_object_make_0 rb_data_object_make
-#define rb_data_object_make_1 rb_data_object_make_warning
-#define rb_data_object_make RUBY_MACRO_SELECT(rb_data_object_make_, RUBY_UNTYPED_DATA_WARNING)
-#endif
-
-#if USE_RGENGC
-#define RB_OBJ_PROMOTED_RAW(x) RB_FL_ALL_RAW(x, RUBY_FL_PROMOTED)
-#define RB_OBJ_PROMOTED(x) (RB_SPECIAL_CONST_P(x) ? 0 : RB_OBJ_PROMOTED_RAW(x))
-#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
-
-void rb_gc_writebarrier(VALUE a, VALUE b);
-void rb_gc_writebarrier_unprotect(VALUE obj);
-
-#else /* USE_RGENGC */
-#define RB_OBJ_PROMOTED(x) 0
-#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
-#endif
-#define OBJ_PROMOTED_RAW(x) RB_OBJ_PROMOTED_RAW(x)
-#define OBJ_PROMOTED(x) RB_OBJ_PROMOTED(x)
-#define OBJ_WB_UNPROTECT(x) RB_OBJ_WB_UNPROTECT(x)
-
-/* Write barrier (WB) interfaces:
- * - RB_OBJ_WRITE(a, slot, b): WB for new reference from `a' to `b'.
- * Write `b' into `*slot'. `slot' is a pointer in `a'.
- * - RB_OBJ_WRITTEN(a, oldv, b): WB for new reference from `a' to `b'.
- * This doesn't write any values, but only a WB declaration.
- * `oldv' is replaced value with `b' (not used in current Ruby).
- *
- * NOTE: The following core interfaces can be changed in the future.
- * Please catch up if you want to insert WB into C-extensions
- * correctly.
- */
-#define RB_OBJ_WRITE(a, slot, b) rb_obj_write((VALUE)(a), (VALUE *)(slot), (VALUE)(b), __FILE__, __LINE__)
-#define RB_OBJ_WRITTEN(a, oldv, b) rb_obj_written((VALUE)(a), (VALUE)(oldv), (VALUE)(b), __FILE__, __LINE__)
-
-#ifndef USE_RGENGC_LOGGING_WB_UNPROTECT
-#define USE_RGENGC_LOGGING_WB_UNPROTECT 0
-#endif
-
-#if USE_RGENGC_LOGGING_WB_UNPROTECT
-void rb_gc_unprotect_logging(void *objptr, const char *filename, int line);
-#define RGENGC_LOGGING_WB_UNPROTECT rb_gc_unprotect_logging
-#endif
-
-static inline VALUE
-rb_obj_wb_unprotect(VALUE x, RB_UNUSED_VAR(const char *filename), RB_UNUSED_VAR(int line))
-{
-#ifdef RGENGC_LOGGING_WB_UNPROTECT
- RGENGC_LOGGING_WB_UNPROTECT((void *)x, filename, line);
-#endif
-#if USE_RGENGC
- rb_gc_writebarrier_unprotect(x);
-#endif
- return x;
-}
-
-static inline VALUE
-rb_obj_written(VALUE a, RB_UNUSED_VAR(VALUE oldv), VALUE b, RB_UNUSED_VAR(const char *filename), RB_UNUSED_VAR(int line))
-{
-#ifdef RGENGC_LOGGING_OBJ_WRITTEN
- RGENGC_LOGGING_OBJ_WRITTEN(a, oldv, b, filename, line);
-#endif
-
-#if USE_RGENGC
- if (!RB_SPECIAL_CONST_P(b)) {
- rb_gc_writebarrier(a, b);
- }
-#endif
-
- return a;
-}
-
-static inline VALUE
-rb_obj_write(VALUE a, VALUE *slot, VALUE b, RB_UNUSED_VAR(const char *filename), RB_UNUSED_VAR(int line))
-{
-#ifdef RGENGC_LOGGING_WRITE
- RGENGC_LOGGING_WRITE(a, slot, b, filename, line);
-#endif
-
- *slot = b;
-
-#if USE_RGENGC
- rb_obj_written(a, RUBY_Qundef /* ignore `oldv' now */, b, filename, line);
-#endif
- return a;
-}
-
-#define RUBY_INTEGER_UNIFICATION 1
-#define RB_INTEGER_TYPE_P(obj) rb_integer_type_p(obj)
-#if defined __GNUC__ && !GCC_VERSION_SINCE(4, 3, 0)
-/* clang 3.x (4.2 compatible) can't eliminate CSE of RB_BUILTIN_TYPE
- * in inline function and caller function */
-#define rb_integer_type_p(obj) \
- __extension__ ({ \
- const VALUE integer_type_obj = (obj); \
- (RB_FIXNUM_P(integer_type_obj) || \
- (!RB_SPECIAL_CONST_P(integer_type_obj) && \
- RB_BUILTIN_TYPE(integer_type_obj) == RUBY_T_BIGNUM)); \
- })
-#else
-static inline int
-rb_integer_type_p(VALUE obj)
-{
- return (RB_FIXNUM_P(obj) ||
- (!RB_SPECIAL_CONST_P(obj) &&
- RB_BUILTIN_TYPE(obj) == RUBY_T_BIGNUM));
-}
-#endif
-
-#if SIZEOF_INT < SIZEOF_LONG
-# define RB_INT2NUM(v) RB_INT2FIX((int)(v))
-# define RB_UINT2NUM(v) RB_LONG2FIX((unsigned int)(v))
-#else
-static inline VALUE
-rb_int2num_inline(int v)
-{
- if (RB_FIXABLE(v))
- return RB_INT2FIX(v);
- else
- return rb_int2big(v);
-}
-#define RB_INT2NUM(x) rb_int2num_inline(x)
-
-static inline VALUE
-rb_uint2num_inline(unsigned int v)
-{
- if (RB_POSFIXABLE(v))
- return RB_LONG2FIX(v);
- else
- return rb_uint2big(v);
-}
-#define RB_UINT2NUM(x) rb_uint2num_inline(x)
-#endif
-#define INT2NUM(x) RB_INT2NUM(x)
-#define UINT2NUM(x) RB_UINT2NUM(x)
-
-static inline VALUE
-rb_long2num_inline(long v)
-{
- if (RB_FIXABLE(v))
- return RB_LONG2FIX(v);
- else
- return rb_int2big(v);
-}
-#define RB_LONG2NUM(x) rb_long2num_inline(x)
-
-static inline VALUE
-rb_ulong2num_inline(unsigned long v)
-{
- if (RB_POSFIXABLE(v))
- return RB_LONG2FIX(v);
- else
- return rb_uint2big(v);
-}
-#define RB_ULONG2NUM(x) rb_ulong2num_inline(x)
-
-static inline char
-rb_num2char_inline(VALUE x)
-{
- if (RB_TYPE_P(x, RUBY_T_STRING) && (RSTRING_LEN(x)>=1))
- return RSTRING_PTR(x)[0];
- else
- return (char)(NUM2INT(x) & 0xff);
-}
-#define RB_NUM2CHR(x) rb_num2char_inline(x)
-
-#define RB_CHR2FIX(x) RB_INT2FIX((long)((x)&0xff))
-
-#define LONG2NUM(x) RB_LONG2NUM(x)
-#define ULONG2NUM(x) RB_ULONG2NUM(x)
-#define NUM2CHR(x) RB_NUM2CHR(x)
-#define CHR2FIX(x) RB_CHR2FIX(x)
-
-#define RB_ST2FIX(h) RB_LONG2FIX((long)(h))
-#define ST2FIX(h) RB_ST2FIX(h)
-
-#define RB_ALLOC_N(type,n) ((type*)ruby_xmalloc2((size_t)(n),sizeof(type)))
-#define RB_ALLOC(type) ((type*)ruby_xmalloc(sizeof(type)))
-#define RB_ZALLOC_N(type,n) ((type*)ruby_xcalloc((size_t)(n),sizeof(type)))
-#define RB_ZALLOC(type) (RB_ZALLOC_N(type,1))
-#define RB_REALLOC_N(var,type,n) ((var)=(type*)ruby_xrealloc2((char*)(var),(size_t)(n),sizeof(type)))
-
-#define ALLOC_N(type,n) RB_ALLOC_N(type,n)
-#define ALLOC(type) RB_ALLOC(type)
-#define ZALLOC_N(type,n) RB_ZALLOC_N(type,n)
-#define ZALLOC(type) RB_ZALLOC(type)
-#define REALLOC_N(var,type,n) RB_REALLOC_N(var,type,n)
-
-#define ALLOCA_N(type,n) ((type*)alloca(sizeof(type)*(n)))
-
-void *rb_alloc_tmp_buffer(volatile VALUE *store, long len) RUBY_ATTR_ALLOC_SIZE((2));
-void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t len,size_t count) RUBY_ATTR_ALLOC_SIZE((2,3));
-void rb_free_tmp_buffer(volatile VALUE *store);
-NORETURN(void ruby_malloc_size_overflow(size_t, size_t));
-#if HAVE_LONG_LONG && SIZEOF_SIZE_T * 2 <= SIZEOF_LONG_LONG
-# define DSIZE_T unsigned LONG_LONG
-#elif defined(HAVE_INT128_T)
-# define DSIZE_T uint128_t
-#endif
-static inline int
-rb_mul_size_overflow(size_t a, size_t b, size_t max, size_t *c)
-{
-#ifdef DSIZE_T
-# ifdef __GNUC__
- __extension__
-# endif
- DSIZE_T c2 = (DSIZE_T)a * (DSIZE_T)b;
- if (c2 > max) return 1;
- *c = (size_t)c2;
-#else
- if (b != 0 && a > max / b) return 1;
- *c = a * b;
-#endif
- return 0;
-}
-static inline void *
-rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize)
-{
- size_t cnt = (size_t)count;
- if (elsize == sizeof(VALUE)) {
- if (RB_UNLIKELY(cnt > LONG_MAX / sizeof(VALUE))) {
- ruby_malloc_size_overflow(cnt, elsize);
- }
- }
- else {
- size_t size, max = LONG_MAX - sizeof(VALUE) + 1;
- if (RB_UNLIKELY(rb_mul_size_overflow(cnt, elsize, max, &size))) {
- ruby_malloc_size_overflow(cnt, elsize);
- }
- cnt = (size + sizeof(VALUE) - 1) / sizeof(VALUE);
- }
- return rb_alloc_tmp_buffer_with_count(store, cnt * sizeof(VALUE), cnt);
-}
-/* allocates _n_ bytes temporary buffer and stores VALUE including it
- * in _v_. _n_ may be evaluated twice. */
-#ifdef C_ALLOCA
-# define RB_ALLOCV(v, n) rb_alloc_tmp_buffer(&(v), (n))
-# define RB_ALLOCV_N(type, v, n) \
- rb_alloc_tmp_buffer2(&(v), (n), sizeof(type))
-#else
-# define RUBY_ALLOCV_LIMIT 1024
-# define RB_ALLOCV(v, n) ((n) < RUBY_ALLOCV_LIMIT ? \
- (RB_GC_GUARD(v) = 0, alloca(n)) : \
- rb_alloc_tmp_buffer(&(v), (n)))
-# define RB_ALLOCV_N(type, v, n) \
- ((type*)(((size_t)(n) < RUBY_ALLOCV_LIMIT / sizeof(type)) ? \
- (RB_GC_GUARD(v) = 0, alloca((size_t)(n) * sizeof(type))) : \
- rb_alloc_tmp_buffer2(&(v), (long)(n), sizeof(type))))
-#endif
-#define RB_ALLOCV_END(v) rb_free_tmp_buffer(&(v))
-
-#define ALLOCV(v, n) RB_ALLOCV(v, n)
-#define ALLOCV_N(type, v, n) RB_ALLOCV_N(type, v, n)
-#define ALLOCV_END(v) RB_ALLOCV_END(v)
-
-#define MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(size_t)(n))
-#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(size_t)(n))
-#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(size_t)(n))
-#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(size_t)(n))
-
-void rb_obj_infect(VALUE victim, VALUE carrier);
-
-typedef int ruby_glob_func(const char*,VALUE, void*);
-void rb_glob(const char*,void(*)(const char*,VALUE,void*),VALUE);
-int ruby_glob(const char*,int,ruby_glob_func*,VALUE);
-int ruby_brace_glob(const char*,int,ruby_glob_func*,VALUE);
-
-VALUE rb_define_class(const char*,VALUE);
-VALUE rb_define_module(const char*);
-VALUE rb_define_class_under(VALUE, const char*, VALUE);
-VALUE rb_define_module_under(VALUE, const char*);
-
-void rb_include_module(VALUE,VALUE);
-void rb_extend_object(VALUE,VALUE);
-void rb_prepend_module(VALUE,VALUE);
-
-struct rb_global_variable;
-
-typedef VALUE rb_gvar_getter_t(ID id, void *data, struct rb_global_variable *gvar);
-typedef void rb_gvar_setter_t(VALUE val, ID id, void *data, struct rb_global_variable *gvar);
-typedef void rb_gvar_marker_t(VALUE *var);
-
-VALUE rb_gvar_undef_getter(ID id, void *data, struct rb_global_variable *gvar);
-void rb_gvar_undef_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar);
-void rb_gvar_undef_marker(VALUE *var);
-
-VALUE rb_gvar_val_getter(ID id, void *data, struct rb_global_variable *gvar);
-void rb_gvar_val_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar);
-void rb_gvar_val_marker(VALUE *var);
-
-VALUE rb_gvar_var_getter(ID id, void *data, struct rb_global_variable *gvar);
-void rb_gvar_var_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar);
-void rb_gvar_var_marker(VALUE *var);
-
-NORETURN(void rb_gvar_readonly_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar));
-
-void rb_define_variable(const char*,VALUE*);
-void rb_define_virtual_variable(const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS));
-void rb_define_hooked_variable(const char*,VALUE*,VALUE(*)(ANYARGS),void(*)(ANYARGS));
-void rb_define_readonly_variable(const char*,const VALUE*);
-void rb_define_const(VALUE,const char*,VALUE);
-void rb_define_global_const(const char*,VALUE);
-
-#define RUBY_METHOD_FUNC(func) ((VALUE (*)(ANYARGS))(func))
-void rb_define_method(VALUE,const char*,VALUE(*)(ANYARGS),int);
-void rb_define_module_function(VALUE,const char*,VALUE(*)(ANYARGS),int);
-void rb_define_global_function(const char*,VALUE(*)(ANYARGS),int);
-
-void rb_undef_method(VALUE,const char*);
-void rb_define_alias(VALUE,const char*,const char*);
-void rb_define_attr(VALUE,const char*,int,int);
-
-void rb_global_variable(VALUE*);
-void rb_gc_register_mark_object(VALUE);
-void rb_gc_register_address(VALUE*);
-void rb_gc_unregister_address(VALUE*);
-
-ID rb_intern(const char*);
-ID rb_intern2(const char*, long);
-ID rb_intern_str(VALUE str);
-const char *rb_id2name(ID);
-ID rb_check_id(volatile VALUE *);
-ID rb_to_id(VALUE);
-VALUE rb_id2str(ID);
-VALUE rb_sym2str(VALUE);
-VALUE rb_to_symbol(VALUE name);
-VALUE rb_check_symbol(volatile VALUE *namep);
-
-#define RUBY_CONST_ID_CACHE(result, str) \
- { \
- static ID rb_intern_id_cache; \
- if (!rb_intern_id_cache) \
- rb_intern_id_cache = rb_intern2((str), (long)strlen(str)); \
- result rb_intern_id_cache; \
- }
-#define RUBY_CONST_ID(var, str) \
- do RUBY_CONST_ID_CACHE((var) =, (str)) while (0)
-#define CONST_ID_CACHE(result, str) RUBY_CONST_ID_CACHE(result, str)
-#define CONST_ID(var, str) RUBY_CONST_ID(var, str)
-#ifdef __GNUC__
-/* __builtin_constant_p and statement expression is available
- * since gcc-2.7.2.3 at least. */
-#define rb_intern(str) \
- (__builtin_constant_p(str) ? \
- __extension__ (RUBY_CONST_ID_CACHE((ID), (str))) : \
- rb_intern(str))
-#define rb_intern_const(str) \
- (__builtin_constant_p(str) ? \
- __extension__ (rb_intern2((str), (long)strlen(str))) : \
- (rb_intern)(str))
+#define FilePathStringValue(v) ((v) = rb_get_path(v))
+#if defined(HAVE_BUILTIN___BUILTIN_CONSTANT_P) && defined(HAVE_STMT_AND_DECL_IN_EXPR)
# define rb_varargs_argc_check_runtime(argc, vargc) \
(((argc) <= (vargc)) ? (argc) : \
(rb_fatal("argc(%d) exceeds actual arguments(%d)", \
argc, vargc), 0))
+# define rb_varargs_argc_valid_p(argc, vargc) \
+ ((argc) == 0 ? (vargc) <= 1 : /* [ruby-core:85266] [Bug #14425] */ \
+ (argc) == (vargc))
# if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# if HAVE_ATTRIBUTE_ERRORFUNC
ERRORFUNC((" argument length doesn't match"), int rb_varargs_bad_length(int,int));
# else
-# define rb_varargs_bad_length(argc, vargc) ((argc)/((argc) == (vargc)))
+# define rb_varargs_bad_length(argc, vargc) \
+ ((argc)/rb_varargs_argc_valid_p(argc, vargc))
# endif
# define rb_varargs_argc_check(argc, vargc) \
__builtin_choose_expr(__builtin_constant_p(argc), \
- (((argc) == (vargc)) ? (argc) : \
+ (rb_varargs_argc_valid_p(argc, vargc) ? (argc) : \
rb_varargs_bad_length(argc, vargc)), \
rb_varargs_argc_check_runtime(argc, vargc))
# else
# define rb_varargs_argc_check(argc, vargc) \
rb_varargs_argc_check_runtime(argc, vargc)
# endif
-
-#else
-#define rb_intern_const(str) rb_intern2((str), (long)strlen(str))
#endif
const char *rb_class2name(VALUE);
@@ -1782,290 +94,12 @@ const char *rb_obj_classname(VALUE);
void rb_p(VALUE);
-VALUE rb_eval_string(const char*);
-VALUE rb_eval_string_protect(const char*, int*);
-VALUE rb_eval_string_wrap(const char*, int*);
-VALUE rb_funcall(VALUE, ID, int, ...);
-VALUE rb_funcallv(VALUE, ID, int, const VALUE*);
-VALUE rb_funcallv_public(VALUE, ID, int, const VALUE*);
-#define rb_funcall2 rb_funcallv
-#define rb_funcall3 rb_funcallv_public
-VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
-VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
-int rb_scan_args(int, const VALUE*, const char*, ...);
-VALUE rb_call_super(int, const VALUE*);
-VALUE rb_current_receiver(void);
-int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *);
-VALUE rb_extract_keywords(VALUE *orighash);
-
-/* rb_scan_args() format allows ':' for optional hash */
-#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1
-
-VALUE rb_gv_set(const char*, VALUE);
-VALUE rb_gv_get(const char*);
-VALUE rb_iv_get(VALUE, const char*);
-VALUE rb_iv_set(VALUE, const char*, VALUE);
-
VALUE rb_equal(VALUE,VALUE);
-VALUE *rb_ruby_verbose_ptr(void);
-VALUE *rb_ruby_debug_ptr(void);
-#define ruby_verbose (*rb_ruby_verbose_ptr())
-#define ruby_debug (*rb_ruby_debug_ptr())
-
-/* for rb_readwrite_sys_fail first argument */
-enum rb_io_wait_readwrite {RB_IO_WAIT_READABLE, RB_IO_WAIT_WRITABLE};
-#define RB_IO_WAIT_READABLE RB_IO_WAIT_READABLE
-#define RB_IO_WAIT_WRITABLE RB_IO_WAIT_WRITABLE
-
-PRINTF_ARGS(NORETURN(void rb_raise(VALUE, const char*, ...)), 2, 3);
-PRINTF_ARGS(NORETURN(void rb_fatal(const char*, ...)), 1, 2);
-PRINTF_ARGS(NORETURN(void rb_bug(const char*, ...)), 1, 2);
-NORETURN(void rb_bug_errno(const char*, int));
-NORETURN(void rb_sys_fail(const char*));
-NORETURN(void rb_sys_fail_str(VALUE));
-NORETURN(void rb_mod_sys_fail(VALUE, const char*));
-NORETURN(void rb_mod_sys_fail_str(VALUE, VALUE));
-NORETURN(void rb_readwrite_sys_fail(enum rb_io_wait_readwrite, const char*));
-NORETURN(void rb_iter_break(void));
-NORETURN(void rb_iter_break_value(VALUE));
-NORETURN(void rb_exit(int));
-NORETURN(void rb_notimplement(void));
-VALUE rb_syserr_new(int, const char *);
-VALUE rb_syserr_new_str(int n, VALUE arg);
-NORETURN(void rb_syserr_fail(int, const char*));
-NORETURN(void rb_syserr_fail_str(int, VALUE));
-NORETURN(void rb_mod_syserr_fail(VALUE, int, const char*));
-NORETURN(void rb_mod_syserr_fail_str(VALUE, int, VALUE));
-NORETURN(void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite, int, const char*));
-
-/* reports if `-W' specified */
-PRINTF_ARGS(void rb_warning(const char*, ...), 1, 2);
-PRINTF_ARGS(void rb_compile_warning(const char *, int, const char*, ...), 3, 4);
-PRINTF_ARGS(void rb_sys_warning(const char*, ...), 1, 2);
-/* reports always */
-PRINTF_ARGS(void rb_warn(const char*, ...), 1, 2);
-PRINTF_ARGS(void rb_compile_warn(const char *, int, const char*, ...), 3, 4);
-
-#define RUBY_BLOCK_CALL_FUNC_TAKES_BLOCKARG 1
-#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) \
- VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg
-typedef VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg));
-
-#if defined RB_BLOCK_CALL_FUNC_STRICT && RB_BLOCK_CALL_FUNC_STRICT
-typedef rb_block_call_func *rb_block_call_func_t;
-#else
-typedef VALUE (*rb_block_call_func_t)(ANYARGS);
-#endif
-
-VALUE rb_each(VALUE);
-VALUE rb_yield(VALUE);
-VALUE rb_yield_values(int n, ...);
-VALUE rb_yield_values2(int n, const VALUE *argv);
-VALUE rb_yield_splat(VALUE);
-VALUE rb_yield_block(VALUE, VALUE, int, const VALUE *, VALUE); /* rb_block_call_func */
-int rb_block_given_p(void);
-void rb_need_block(void);
-VALUE rb_iterate(VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE);
-VALUE rb_block_call(VALUE,ID,int,const VALUE*,rb_block_call_func_t,VALUE);
-VALUE rb_rescue(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE);
-VALUE rb_rescue2(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...);
-VALUE rb_ensure(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE);
-VALUE rb_catch(const char*,VALUE(*)(ANYARGS),VALUE);
-VALUE rb_catch_obj(VALUE,VALUE(*)(ANYARGS),VALUE);
-NORETURN(void rb_throw(const char*,VALUE));
-NORETURN(void rb_throw_obj(VALUE,VALUE));
-
VALUE rb_require(const char*);
-RUBY_EXTERN VALUE rb_mKernel;
-RUBY_EXTERN VALUE rb_mComparable;
-RUBY_EXTERN VALUE rb_mEnumerable;
-RUBY_EXTERN VALUE rb_mErrno;
-RUBY_EXTERN VALUE rb_mFileTest;
-RUBY_EXTERN VALUE rb_mGC;
-RUBY_EXTERN VALUE rb_mMath;
-RUBY_EXTERN VALUE rb_mProcess;
-RUBY_EXTERN VALUE rb_mWaitReadable;
-RUBY_EXTERN VALUE rb_mWaitWritable;
-
-RUBY_EXTERN VALUE rb_cBasicObject;
-RUBY_EXTERN VALUE rb_cObject;
-RUBY_EXTERN VALUE rb_cArray;
-#ifndef RUBY_INTEGER_UNIFICATION
-RUBY_EXTERN VALUE rb_cBignum;
-#endif
-RUBY_EXTERN VALUE rb_cBinding;
-RUBY_EXTERN VALUE rb_cClass;
-RUBY_EXTERN VALUE rb_cCont;
-RUBY_EXTERN VALUE rb_cDir;
-RUBY_EXTERN VALUE rb_cData;
-RUBY_EXTERN VALUE rb_cFalseClass;
-RUBY_EXTERN VALUE rb_cEncoding;
-RUBY_EXTERN VALUE rb_cEnumerator;
-RUBY_EXTERN VALUE rb_cFile;
-#ifndef RUBY_INTEGER_UNIFICATION
-RUBY_EXTERN VALUE rb_cFixnum;
-#endif
-RUBY_EXTERN VALUE rb_cFloat;
-RUBY_EXTERN VALUE rb_cHash;
-RUBY_EXTERN VALUE rb_cInteger;
-RUBY_EXTERN VALUE rb_cIO;
-RUBY_EXTERN VALUE rb_cMatch;
-RUBY_EXTERN VALUE rb_cMethod;
-RUBY_EXTERN VALUE rb_cModule;
-RUBY_EXTERN VALUE rb_cNameErrorMesg;
-RUBY_EXTERN VALUE rb_cNilClass;
-RUBY_EXTERN VALUE rb_cNumeric;
-RUBY_EXTERN VALUE rb_cProc;
-RUBY_EXTERN VALUE rb_cRandom;
-RUBY_EXTERN VALUE rb_cRange;
-RUBY_EXTERN VALUE rb_cRational;
-RUBY_EXTERN VALUE rb_cComplex;
-RUBY_EXTERN VALUE rb_cRegexp;
-RUBY_EXTERN VALUE rb_cStat;
-RUBY_EXTERN VALUE rb_cString;
-RUBY_EXTERN VALUE rb_cStruct;
-RUBY_EXTERN VALUE rb_cSymbol;
-RUBY_EXTERN VALUE rb_cThread;
-RUBY_EXTERN VALUE rb_cTime;
-RUBY_EXTERN VALUE rb_cTrueClass;
-RUBY_EXTERN VALUE rb_cUnboundMethod;
-
-RUBY_EXTERN VALUE rb_eException;
-RUBY_EXTERN VALUE rb_eStandardError;
-RUBY_EXTERN VALUE rb_eSystemExit;
-RUBY_EXTERN VALUE rb_eInterrupt;
-RUBY_EXTERN VALUE rb_eSignal;
-RUBY_EXTERN VALUE rb_eFatal;
-RUBY_EXTERN VALUE rb_eArgError;
-RUBY_EXTERN VALUE rb_eEOFError;
-RUBY_EXTERN VALUE rb_eIndexError;
-RUBY_EXTERN VALUE rb_eStopIteration;
-RUBY_EXTERN VALUE rb_eKeyError;
-RUBY_EXTERN VALUE rb_eRangeError;
-RUBY_EXTERN VALUE rb_eIOError;
-RUBY_EXTERN VALUE rb_eRuntimeError;
-RUBY_EXTERN VALUE rb_eSecurityError;
-RUBY_EXTERN VALUE rb_eSystemCallError;
-RUBY_EXTERN VALUE rb_eThreadError;
-RUBY_EXTERN VALUE rb_eTypeError;
-RUBY_EXTERN VALUE rb_eZeroDivError;
-RUBY_EXTERN VALUE rb_eNotImpError;
-RUBY_EXTERN VALUE rb_eNoMemError;
-RUBY_EXTERN VALUE rb_eNoMethodError;
-RUBY_EXTERN VALUE rb_eFloatDomainError;
-RUBY_EXTERN VALUE rb_eLocalJumpError;
-RUBY_EXTERN VALUE rb_eSysStackError;
-RUBY_EXTERN VALUE rb_eRegexpError;
-RUBY_EXTERN VALUE rb_eEncodingError;
-RUBY_EXTERN VALUE rb_eEncCompatError;
-
-RUBY_EXTERN VALUE rb_eScriptError;
-RUBY_EXTERN VALUE rb_eNameError;
-RUBY_EXTERN VALUE rb_eSyntaxError;
-RUBY_EXTERN VALUE rb_eLoadError;
-
-RUBY_EXTERN VALUE rb_eMathDomainError;
-
-RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;
-
-static inline VALUE
-rb_class_of(VALUE obj)
-{
- if (RB_IMMEDIATE_P(obj)) {
- if (RB_FIXNUM_P(obj)) return rb_cInteger;
- if (RB_FLONUM_P(obj)) return rb_cFloat;
- if (obj == RUBY_Qtrue) return rb_cTrueClass;
- if (RB_STATIC_SYM_P(obj)) return rb_cSymbol;
- }
- else if (!RB_TEST(obj)) {
- if (obj == RUBY_Qnil) return rb_cNilClass;
- if (obj == RUBY_Qfalse) return rb_cFalseClass;
- }
- return RBASIC(obj)->klass;
-}
-
-static inline int
-rb_type(VALUE obj)
-{
- if (RB_IMMEDIATE_P(obj)) {
- if (RB_FIXNUM_P(obj)) return RUBY_T_FIXNUM;
- if (RB_FLONUM_P(obj)) return RUBY_T_FLOAT;
- if (obj == RUBY_Qtrue) return RUBY_T_TRUE;
- if (RB_STATIC_SYM_P(obj)) return RUBY_T_SYMBOL;
- if (obj == RUBY_Qundef) return RUBY_T_UNDEF;
- }
- else if (!RB_TEST(obj)) {
- if (obj == RUBY_Qnil) return RUBY_T_NIL;
- if (obj == RUBY_Qfalse) return RUBY_T_FALSE;
- }
- return RB_BUILTIN_TYPE(obj);
-}
-
-#ifdef __GNUC__
-#define rb_type_p(obj, type) \
- __extension__ (__builtin_constant_p(type) ? RB_TYPE_P((obj), (type)) : \
- rb_type(obj) == (type))
-#else
-#define rb_type_p(obj, type) (rb_type(obj) == (type))
-#endif
-
-#ifdef __GNUC__
-#define rb_special_const_p(obj) \
- __extension__ ({ \
- VALUE special_const_obj = (obj); \
- (int)(RB_SPECIAL_CONST_P(special_const_obj) ? RUBY_Qtrue : RUBY_Qfalse); \
- })
-#else
-static inline int
-rb_special_const_p(VALUE obj)
-{
- if (RB_SPECIAL_CONST_P(obj)) return (int)RUBY_Qtrue;
- return (int)RUBY_Qfalse;
-}
-#endif
-
#include "ruby/intern.h"
-static inline void
-rb_clone_setup(VALUE clone, VALUE obj)
-{
- rb_obj_setup(clone, rb_singleton_class_clone(obj),
- RBASIC(obj)->flags & ~(FL_PROMOTED0|FL_PROMOTED1|FL_FINALIZE));
- rb_singleton_class_attached(RBASIC_CLASS(clone), clone);
- if (RB_FL_TEST(obj, RUBY_FL_EXIVAR)) rb_copy_generic_ivar(clone, obj);
-}
-
-static inline void
-rb_dup_setup(VALUE dup, VALUE obj)
-{
- rb_obj_setup(dup, rb_obj_class(obj), RB_FL_TEST_RAW(obj, RUBY_FL_DUPPED));
- if (RB_FL_TEST(obj, RUBY_FL_EXIVAR)) rb_copy_generic_ivar(dup, obj);
-}
-
-static inline long
-rb_array_len(VALUE a)
-{
- return (RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
- RARRAY_EMBED_LEN(a) : RARRAY(a)->as.heap.len;
-}
-
-#if defined(__fcc__) || defined(__fcc_version) || \
- defined(__FCC__) || defined(__FCC_VERSION)
-/* workaround for old version of Fujitsu C Compiler (fcc) */
-# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
-#else
-# define FIX_CONST_VALUE_PTR(x) (x)
-#endif
-
-static inline const VALUE *
-rb_array_const_ptr(VALUE a)
-{
- return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
- RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
-}
-
#if defined(EXTLIB) && defined(USE_DLN_A_OUT)
/* hook for external modules */
static char *dln_libs_to_be_linked[] = { EXTLIB, 0 };
@@ -2075,374 +109,14 @@ static char *dln_libs_to_be_linked[] = { EXTLIB, 0 };
#define HAVE_NATIVETHREAD
int ruby_native_thread_p(void);
-/* traditional set_trace_func events */
-#define RUBY_EVENT_NONE 0x0000
-#define RUBY_EVENT_LINE 0x0001
-#define RUBY_EVENT_CLASS 0x0002
-#define RUBY_EVENT_END 0x0004
-#define RUBY_EVENT_CALL 0x0008
-#define RUBY_EVENT_RETURN 0x0010
-#define RUBY_EVENT_C_CALL 0x0020
-#define RUBY_EVENT_C_RETURN 0x0040
-#define RUBY_EVENT_RAISE 0x0080
-#define RUBY_EVENT_ALL 0x00ff
-
-/* for TracePoint extended events */
-#define RUBY_EVENT_B_CALL 0x0100
-#define RUBY_EVENT_B_RETURN 0x0200
-#define RUBY_EVENT_THREAD_BEGIN 0x0400
-#define RUBY_EVENT_THREAD_END 0x0800
-#define RUBY_EVENT_FIBER_SWITCH 0x1000
-#define RUBY_EVENT_TRACEPOINT_ALL 0xffff
-
-/* special events */
-#define RUBY_EVENT_SPECIFIED_LINE 0x010000
-#define RUBY_EVENT_COVERAGE 0x020000
-
-/* internal events */
-#define RUBY_INTERNAL_EVENT_SWITCH 0x040000
-#define RUBY_EVENT_SWITCH 0x040000 /* obsolete name. this macro is for compatibility */
- /* 0x080000 */
-#define RUBY_INTERNAL_EVENT_NEWOBJ 0x100000
-#define RUBY_INTERNAL_EVENT_FREEOBJ 0x200000
-#define RUBY_INTERNAL_EVENT_GC_START 0x400000
-#define RUBY_INTERNAL_EVENT_GC_END_MARK 0x800000
-#define RUBY_INTERNAL_EVENT_GC_END_SWEEP 0x1000000
-#define RUBY_INTERNAL_EVENT_GC_ENTER 0x2000000
-#define RUBY_INTERNAL_EVENT_GC_EXIT 0x4000000
-#define RUBY_INTERNAL_EVENT_OBJSPACE_MASK 0x7f00000
-#define RUBY_INTERNAL_EVENT_MASK 0xfffe0000
-
-typedef uint32_t rb_event_flag_t;
-typedef void (*rb_event_hook_func_t)(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass);
-
-#define RB_EVENT_HOOKS_HAVE_CALLBACK_DATA 1
-void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);
-int rb_remove_event_hook(rb_event_hook_func_t func);
-
-/* locale insensitive functions */
-
-static inline int rb_isascii(int c){ return '\0' <= c && c <= '\x7f'; }
-static inline int rb_isupper(int c){ return 'A' <= c && c <= 'Z'; }
-static inline int rb_islower(int c){ return 'a' <= c && c <= 'z'; }
-static inline int rb_isalpha(int c){ return rb_isupper(c) || rb_islower(c); }
-static inline int rb_isdigit(int c){ return '0' <= c && c <= '9'; }
-static inline int rb_isalnum(int c){ return rb_isalpha(c) || rb_isdigit(c); }
-static inline int rb_isxdigit(int c){ return rb_isdigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'); }
-static inline int rb_isblank(int c){ return c == ' ' || c == '\t'; }
-static inline int rb_isspace(int c){ return c == ' ' || ('\t' <= c && c <= '\r'); }
-static inline int rb_iscntrl(int c){ return ('\0' <= c && c < ' ') || c == '\x7f'; }
-static inline int rb_isprint(int c){ return ' ' <= c && c <= '\x7e'; }
-static inline int rb_ispunct(int c){ return !rb_isalnum(c); }
-static inline int rb_isgraph(int c){ return '!' <= c && c <= '\x7e'; }
-static inline int rb_tolower(int c) { return rb_isupper(c) ? (c|0x20) : c; }
-static inline int rb_toupper(int c) { return rb_islower(c) ? (c&0x5f) : c; }
-
-#ifndef ISPRINT
-#define ISASCII(c) rb_isascii(c)
-#define ISPRINT(c) rb_isprint(c)
-#define ISGRAPH(c) rb_isgraph(c)
-#define ISSPACE(c) rb_isspace(c)
-#define ISUPPER(c) rb_isupper(c)
-#define ISLOWER(c) rb_islower(c)
-#define ISALNUM(c) rb_isalnum(c)
-#define ISALPHA(c) rb_isalpha(c)
-#define ISDIGIT(c) rb_isdigit(c)
-#define ISXDIGIT(c) rb_isxdigit(c)
-#endif
-#define TOUPPER(c) rb_toupper(c)
-#define TOLOWER(c) rb_tolower(c)
-
-int st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
-int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
-#define STRCASECMP(s1, s2) (st_locale_insensitive_strcasecmp((s1), (s2)))
-#define STRNCASECMP(s1, s2, n) (st_locale_insensitive_strncasecmp((s1), (s2), (n)))
-
-unsigned long ruby_strtoul(const char *str, char **endptr, int base);
-#define STRTOUL(str, endptr, base) (ruby_strtoul((str), (endptr), (base)))
-
#define InitVM(ext) {void InitVM_##ext(void);InitVM_##ext();}
PRINTF_ARGS(int ruby_snprintf(char *str, size_t n, char const *fmt, ...), 3, 4);
int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
-#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P) && defined(__OPTIMIZE__)
-# define rb_scan_args(argc,argvp,fmt,...) \
- __builtin_choose_expr(__builtin_constant_p(fmt), \
- rb_scan_args0(argc,argvp,fmt,\
- (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
- ((VALUE*[]){__VA_ARGS__})), \
- rb_scan_args(argc,argvp,fmt,__VA_ARGS__))
-# if HAVE_ATTRIBUTE_ERRORFUNC
-ERRORFUNC(("bad scan arg format"), int rb_scan_args_bad_format(const char*));
-ERRORFUNC(("variable argument length doesn't match"), int rb_scan_args_length_mismatch(const char*,int));
-# else
-# define rb_scan_args_bad_format(fmt) 0
-# define rb_scan_args_length_mismatch(fmt, varc) 0
-# endif
-
-# define rb_scan_args_isdigit(c) ((unsigned char)((c)-'0')<10)
-
-# define rb_scan_args_count_end(fmt, ofs, varc, vari) \
- ((vari)/(!fmt[ofs] || rb_scan_args_bad_format(fmt)))
-
-# define rb_scan_args_count_block(fmt, ofs, varc, vari) \
- (fmt[ofs]!='&' ? \
- rb_scan_args_count_end(fmt, ofs, varc, vari) : \
- rb_scan_args_count_end(fmt, ofs+1, varc, vari+1))
-
-# define rb_scan_args_count_hash(fmt, ofs, varc, vari) \
- (fmt[ofs]!=':' ? \
- rb_scan_args_count_block(fmt, ofs, varc, vari) : \
- rb_scan_args_count_block(fmt, ofs+1, varc, vari+1))
-
-# define rb_scan_args_count_trail(fmt, ofs, varc, vari) \
- (!rb_scan_args_isdigit(fmt[ofs]) ? \
- rb_scan_args_count_hash(fmt, ofs, varc, vari) : \
- rb_scan_args_count_hash(fmt, ofs+1, varc, vari+(fmt[ofs]-'0')))
-
-# define rb_scan_args_count_var(fmt, ofs, varc, vari) \
- (fmt[ofs]!='*' ? \
- rb_scan_args_count_trail(fmt, ofs, varc, vari) : \
- rb_scan_args_count_trail(fmt, ofs+1, varc, vari+1))
-
-# define rb_scan_args_count_opt(fmt, ofs, varc, vari) \
- (!rb_scan_args_isdigit(fmt[1]) ? \
- rb_scan_args_count_var(fmt, ofs, varc, vari) : \
- rb_scan_args_count_var(fmt, ofs+1, varc, vari+fmt[ofs]-'0'))
-
-# define rb_scan_args_count(fmt, varc) \
- ((!rb_scan_args_isdigit(fmt[0]) ? \
- rb_scan_args_count_var(fmt, 0, varc, 0) : \
- rb_scan_args_count_opt(fmt, 1, varc, fmt[0]-'0')) \
- == (varc) || \
- rb_scan_args_length_mismatch(fmt, varc))
-
-# define rb_scan_args_verify_count(fmt, varc) \
- ((varc)/(rb_scan_args_count(fmt, varc)))
-
-# ifdef __GNUC__
-# define rb_scan_args_verify(fmt, varc) \
- ({ \
- int verify; \
- _Pragma("GCC diagnostic push"); \
- _Pragma("GCC diagnostic ignored \"-Warray-bounds\""); \
- verify = rb_scan_args_verify_count(fmt, varc); \
- _Pragma("GCC diagnostic pop"); \
- verify; \
- })
-# else
-# define rb_scan_args_verify(fmt, varc) \
- rb_scan_args_verify_count(fmt, varc)
-# endif
-
-ALWAYS_INLINE(static int rb_scan_args_lead_p(const char *fmt));
-static inline int
-rb_scan_args_lead_p(const char *fmt)
-{
- return rb_scan_args_isdigit(fmt[0]);
-}
-
-ALWAYS_INLINE(static int rb_scan_args_n_lead(const char *fmt));
-static inline int
-rb_scan_args_n_lead(const char *fmt)
-{
- return (rb_scan_args_lead_p(fmt) ? fmt[0]-'0' : 0);
-}
-
-ALWAYS_INLINE(static int rb_scan_args_opt_p(const char *fmt));
-static inline int
-rb_scan_args_opt_p(const char *fmt)
-{
- return (rb_scan_args_lead_p(fmt) && rb_scan_args_isdigit(fmt[1]));
-}
-
-ALWAYS_INLINE(static int rb_scan_args_n_opt(const char *fmt));
-static inline int
-rb_scan_args_n_opt(const char *fmt)
-{
- return (rb_scan_args_opt_p(fmt) ? fmt[1]-'0' : 0);
-}
-
-ALWAYS_INLINE(static int rb_scan_args_var_idx(const char *fmt));
-static inline int
-rb_scan_args_var_idx(const char *fmt)
-{
- return (!rb_scan_args_lead_p(fmt) ? 0 : !rb_scan_args_isdigit(fmt[1]) ? 1 : 2);
-}
-
-ALWAYS_INLINE(static int rb_scan_args_f_var(const char *fmt));
-static inline int
-rb_scan_args_f_var(const char *fmt)
-{
- return (fmt[rb_scan_args_var_idx(fmt)]=='*');
-}
-
-ALWAYS_INLINE(static int rb_scan_args_trail_idx(const char *fmt));
-static inline int
-rb_scan_args_trail_idx(const char *fmt)
-{
- const int idx = rb_scan_args_var_idx(fmt);
- return idx+(fmt[idx]=='*');
-}
-
-ALWAYS_INLINE(static int rb_scan_args_n_trail(const char *fmt));
-static inline int
-rb_scan_args_n_trail(const char *fmt)
-{
- const int idx = rb_scan_args_trail_idx(fmt);
- return (rb_scan_args_isdigit(fmt[idx]) ? fmt[idx]-'0' : 0);
-}
-
-ALWAYS_INLINE(static int rb_scan_args_hash_idx(const char *fmt));
-static inline int
-rb_scan_args_hash_idx(const char *fmt)
-{
- const int idx = rb_scan_args_trail_idx(fmt);
- return idx+rb_scan_args_isdigit(fmt[idx]);
-}
-
-ALWAYS_INLINE(static int rb_scan_args_f_hash(const char *fmt));
-static inline int
-rb_scan_args_f_hash(const char *fmt)
-{
- return (fmt[rb_scan_args_hash_idx(fmt)]==':');
-}
-
-ALWAYS_INLINE(static int rb_scan_args_block_idx(const char *fmt));
-static inline int
-rb_scan_args_block_idx(const char *fmt)
-{
- const int idx = rb_scan_args_hash_idx(fmt);
- return idx+(fmt[idx]==':');
-}
-
-ALWAYS_INLINE(static int rb_scan_args_f_block(const char *fmt));
-static inline int
-rb_scan_args_f_block(const char *fmt)
-{
- return (fmt[rb_scan_args_block_idx(fmt)]=='&');
-}
-
-# if 0
-ALWAYS_INLINE(static int rb_scan_args_end_idx(const char *fmt));
-static inline int
-rb_scan_args_end_idx(const char *fmt)
-{
- const int idx = rb_scan_args_block_idx(fmt);
- return idx+(fmt[idx]=='&');
-}
-# endif
-
-# define rb_scan_args0(argc, argv, fmt, varc, vars) \
- rb_scan_args_set(argc, argv, \
- rb_scan_args_n_lead(fmt), \
- rb_scan_args_n_opt(fmt), \
- rb_scan_args_n_trail(fmt), \
- rb_scan_args_f_var(fmt), \
- rb_scan_args_f_hash(fmt), \
- rb_scan_args_f_block(fmt), \
- (rb_scan_args_verify(fmt, varc), vars))
-ALWAYS_INLINE(static int
-rb_scan_args_set(int argc, const VALUE *argv,
- int n_lead, int n_opt, int n_trail,
- int f_var, int f_hash, int f_block,
- VALUE *vars[]));
-inline int
-rb_scan_args_set(int argc, const VALUE *argv,
- int n_lead, int n_opt, int n_trail,
- int f_var, int f_hash, int f_block,
- VALUE *vars[])
-{
- int i, argi = 0, vari = 0, last_idx = -1;
- VALUE *var, hash = Qnil, last_hash = 0;
- const int n_mand = n_lead + n_trail;
-
- /* capture an option hash - phase 1: pop */
- if (f_hash && n_mand < argc) {
- VALUE last = argv[argc - 1];
-
- if (RB_NIL_P(last)) {
- /* nil is taken as an empty option hash only if it is not
- ambiguous; i.e. '*' is not specified and arguments are
- given more than sufficient */
- if (!f_var && n_mand + n_opt < argc)
- argc--;
- }
- else {
- hash = rb_check_hash_type(last);
- if (!RB_NIL_P(hash)) {
- VALUE opts = rb_extract_keywords(&hash);
- if (!(last_hash = hash)) argc--;
- else last_idx = argc - 1;
- hash = opts ? opts : Qnil;
- }
- }
- }
-
- rb_check_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
-
- /* capture leading mandatory arguments */
- for (i = n_lead; i-- > 0; ) {
- var = vars[vari++];
- if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
- argi++;
- }
- /* capture optional arguments */
- for (i = n_opt; i-- > 0; ) {
- var = vars[vari++];
- if (argi < argc - n_trail) {
- if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
- argi++;
- }
- else {
- if (var) *var = Qnil;
- }
- }
- /* capture variable length arguments */
- if (f_var) {
- int n_var = argc - argi - n_trail;
-
- var = vars[vari++];
- if (0 < n_var) {
- if (var) {
- int f_last = (last_idx + 1 == argc - n_trail);
- *var = rb_ary_new4(n_var-f_last, &argv[argi]);
- if (f_last) rb_ary_push(*var, last_hash);
- }
- argi += n_var;
- }
- else {
- if (var) *var = rb_ary_new();
- }
- }
- /* capture trailing mandatory arguments */
- for (i = n_trail; i-- > 0; ) {
- var = vars[vari++];
- if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
- argi++;
- }
- /* capture an option hash - phase 2: assignment */
- if (f_hash) {
- var = vars[vari++];
- if (var) *var = hash;
- }
- /* capture iterator block */
- if (f_block) {
- var = vars[vari++];
- if (rb_block_given_p()) {
- *var = rb_block_proc();
- }
- else {
- *var = Qnil;
- }
- }
-
- return argc;
-}
-#endif
-
-#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
+# /* Skip it; clang -pedantic doesn't like the following */
+#elif defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO) && defined(__OPTIMIZE__)
# define rb_yield_values(argc, ...) \
__extension__({ \
const int rb_yield_values_argc = (argc); \
@@ -2460,7 +134,7 @@ __extension__({ \
const VALUE rb_funcall_args[] = {__VA_ARGS__}; \
const int rb_funcall_nargs = \
(int)(sizeof(rb_funcall_args) / sizeof(VALUE)); \
- rb_funcallv(recv, mid, \
+ rb_funcallv(recv, mid, \
rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), \
rb_funcall_nargs ? rb_funcall_args : NULL); \
})
@@ -2470,82 +144,10 @@ __extension__({ \
#include "ruby/subst.h"
#endif
-/**
- * @defgroup embed CRuby Embedding APIs
- * CRuby interpreter APIs. These are APIs to embed MRI interpreter into your
- * program.
- * These functions are not a part of Ruby extension library API.
- * Extension libraries of Ruby should not depend on these functions.
- * @{
- */
-
-/** @defgroup ruby1 ruby(1) implementation
- * A part of the implementation of ruby(1) command.
- * Other programs that embed Ruby interpreter do not always need to use these
- * functions.
- * @{
- */
-
-void ruby_sysinit(int *argc, char ***argv);
-void ruby_init(void);
-void* ruby_options(int argc, char** argv);
-int ruby_executable_node(void *n, int *status);
-int ruby_run_node(void *n);
-
-/* version.c */
-void ruby_show_version(void);
-void ruby_show_copyright(void);
-
-
-/*! A convenience macro to call ruby_init_stack(). Must be placed just after
- * variable declarations */
-#define RUBY_INIT_STACK \
- VALUE variable_in_this_stack_frame; \
- ruby_init_stack(&variable_in_this_stack_frame);
-/*! @} */
-
-#ifdef __ia64
-void ruby_init_stack(volatile VALUE*, void*);
-#define ruby_init_stack(addr) ruby_init_stack((addr), rb_ia64_bsp())
-#else
-void ruby_init_stack(volatile VALUE*);
-#endif
-#define Init_stack(addr) ruby_init_stack(addr)
-
-int ruby_setup(void);
-int ruby_cleanup(volatile int);
-
-void ruby_finalize(void);
-NORETURN(void ruby_stop(int));
-
-void ruby_set_stack_size(size_t);
-int ruby_stack_check(void);
-size_t ruby_stack_length(VALUE**);
-
-int ruby_exec_node(void *n);
-
-void ruby_script(const char* name);
-void ruby_set_script_name(VALUE name);
-
-void ruby_prog_init(void);
-void ruby_set_argv(int, char**);
-void *ruby_process_options(int, char**);
-void ruby_init_loadpath(void);
-void ruby_incpush(const char*);
-void ruby_sig_finalize(void);
-
-/*! @} */
-
#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
# include "ruby/backward.h"
#endif
-RUBY_SYMBOL_EXPORT_END
+RBIMPL_SYMBOL_EXPORT_END()
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
#endif /* RUBY_RUBY_H */
diff --git a/include/ruby/st.h b/include/ruby/st.h
index 47e14a3e2c..1e4bb80686 100644
--- a/include/ruby/st.h
+++ b/include/ruby/st.h
@@ -1,7 +1,7 @@
/* This is a public domain general purpose hash table package
originally written by Peter Moore @ UCB.
- The hash table data strutures were redesigned and the package was
+ The hash table data structures were redesigned and the package was
rewritten by Vladimir Makarov <vmakarov@redhat.com>. */
#ifndef RUBY_ST_H
@@ -59,8 +59,8 @@ typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index
#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
struct st_hash_type {
- int (*compare)(ANYARGS /*st_data_t, st_data_t*/); /* st_compare_func* */
- st_index_t (*hash)(ANYARGS /*st_data_t*/); /* st_hash_func* */
+ int (*compare)(st_data_t, st_data_t); /* st_compare_func* */
+ st_index_t (*hash)(st_data_t); /* st_hash_func* */
};
#define ST_INDEX_BITS (SIZEOF_ST_INDEX_T * CHAR_BIT)
@@ -96,53 +96,95 @@ struct st_table {
#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
-enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
-
-st_table *st_init_table(const struct st_hash_type *);
-st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
-st_table *st_init_numtable(void);
-st_table *st_init_numtable_with_size(st_index_t);
-st_table *st_init_strtable(void);
-st_table *st_init_strtable_with_size(st_index_t);
-st_table *st_init_strcasetable(void);
-st_table *st_init_strcasetable_with_size(st_index_t);
-int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
-int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
-int st_shift(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
-int st_insert(st_table *, st_data_t, st_data_t);
-int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
-int st_lookup(st_table *, st_data_t, st_data_t *);
-int st_get_key(st_table *, st_data_t, st_data_t *);
+enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK, ST_REPLACE};
+
+st_table *rb_st_init_table(const struct st_hash_type *);
+#define st_init_table rb_st_init_table
+st_table *rb_st_init_table_with_size(const struct st_hash_type *, st_index_t);
+#define st_init_table_with_size rb_st_init_table_with_size
+st_table *rb_st_init_numtable(void);
+#define st_init_numtable rb_st_init_numtable
+st_table *rb_st_init_numtable_with_size(st_index_t);
+#define st_init_numtable_with_size rb_st_init_numtable_with_size
+st_table *rb_st_init_strtable(void);
+#define st_init_strtable rb_st_init_strtable
+st_table *rb_st_init_strtable_with_size(st_index_t);
+#define st_init_strtable_with_size rb_st_init_strtable_with_size
+st_table *rb_st_init_strcasetable(void);
+#define st_init_strcasetable rb_st_init_strcasetable
+st_table *rb_st_init_strcasetable_with_size(st_index_t);
+#define st_init_strcasetable_with_size rb_st_init_strcasetable_with_size
+int rb_st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
+#define st_delete rb_st_delete
+int rb_st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
+#define st_delete_safe rb_st_delete_safe
+int rb_st_shift(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
+#define st_shift rb_st_shift
+int rb_st_insert(st_table *, st_data_t, st_data_t);
+#define st_insert rb_st_insert
+int rb_st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
+#define st_insert2 rb_st_insert2
+int rb_st_lookup(st_table *, st_data_t, st_data_t *);
+#define st_lookup rb_st_lookup
+int rb_st_get_key(st_table *, st_data_t, st_data_t *);
+#define st_get_key rb_st_get_key
typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing);
/* *key may be altered, but must equal to the old key, i.e., the
* results of hash() are same and compare() returns 0, otherwise the
* behavior is undefined */
-int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
-int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
-int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t);
-st_index_t st_keys(st_table *table, st_data_t *keys, st_index_t size);
-st_index_t st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
-st_index_t st_values(st_table *table, st_data_t *values, st_index_t size);
-st_index_t st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
-void st_add_direct(st_table *, st_data_t, st_data_t);
-void st_free_table(st_table *);
-void st_cleanup_safe(st_table *, st_data_t);
-void st_clear(st_table *);
-st_table *st_copy(st_table *);
-CONSTFUNC(int st_numcmp(st_data_t, st_data_t));
-CONSTFUNC(st_index_t st_numhash(st_data_t));
-PUREFUNC(int st_locale_insensitive_strcasecmp(const char *s1, const char *s2));
-PUREFUNC(int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n));
-#define st_strcasecmp st_locale_insensitive_strcasecmp
-#define st_strncasecmp st_locale_insensitive_strncasecmp
-PUREFUNC(size_t st_memsize(const st_table *));
-PUREFUNC(st_index_t st_hash(const void *ptr, size_t len, st_index_t h));
-CONSTFUNC(st_index_t st_hash_uint32(st_index_t h, uint32_t i));
-CONSTFUNC(st_index_t st_hash_uint(st_index_t h, st_index_t i));
-CONSTFUNC(st_index_t st_hash_end(st_index_t h));
-CONSTFUNC(st_index_t st_hash_start(st_index_t h));
+int rb_st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
+#define st_update rb_st_update
+typedef int st_foreach_callback_func(st_data_t, st_data_t, st_data_t);
+typedef int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int);
+int rb_st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
+#define st_foreach_with_replace rb_st_foreach_with_replace
+int rb_st_foreach(st_table *, st_foreach_callback_func *, st_data_t);
+#define st_foreach rb_st_foreach
+int rb_st_foreach_check(st_table *, st_foreach_check_callback_func *, st_data_t, st_data_t);
+#define st_foreach_check rb_st_foreach_check
+st_index_t rb_st_keys(st_table *table, st_data_t *keys, st_index_t size);
+#define st_keys rb_st_keys
+st_index_t rb_st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
+#define st_keys_check rb_st_keys_check
+st_index_t rb_st_values(st_table *table, st_data_t *values, st_index_t size);
+#define st_values rb_st_values
+st_index_t rb_st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
+#define st_values_check rb_st_values_check
+void rb_st_add_direct(st_table *, st_data_t, st_data_t);
+#define st_add_direct rb_st_add_direct
+void rb_st_free_table(st_table *);
+#define st_free_table rb_st_free_table
+void rb_st_cleanup_safe(st_table *, st_data_t);
+#define st_cleanup_safe rb_st_cleanup_safe
+void rb_st_clear(st_table *);
+#define st_clear rb_st_clear
+st_table *rb_st_copy(st_table *);
+#define st_copy rb_st_copy
+CONSTFUNC(int rb_st_numcmp(st_data_t, st_data_t));
+#define st_numcmp rb_st_numcmp
+CONSTFUNC(st_index_t rb_st_numhash(st_data_t));
+#define st_numhash rb_st_numhash
+PUREFUNC(int rb_st_locale_insensitive_strcasecmp(const char *s1, const char *s2));
+#define st_locale_insensitive_strcasecmp rb_st_locale_insensitive_strcasecmp
+PUREFUNC(int rb_st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n));
+#define st_locale_insensitive_strncasecmp rb_st_locale_insensitive_strncasecmp
+#define st_strcasecmp rb_st_locale_insensitive_strcasecmp
+#define st_strncasecmp rb_st_locale_insensitive_strncasecmp
+PUREFUNC(size_t rb_st_memsize(const st_table *));
+#define st_memsize rb_st_memsize
+PUREFUNC(st_index_t rb_st_hash(const void *ptr, size_t len, st_index_t h));
+#define st_hash rb_st_hash
+CONSTFUNC(st_index_t rb_st_hash_uint32(st_index_t h, uint32_t i));
+#define st_hash_uint32 rb_st_hash_uint32
+CONSTFUNC(st_index_t rb_st_hash_uint(st_index_t h, st_index_t i));
+#define st_hash_uint rb_st_hash_uint
+CONSTFUNC(st_index_t rb_st_hash_end(st_index_t h));
+#define st_hash_end rb_st_hash_end
+CONSTFUNC(st_index_t rb_st_hash_start(st_index_t h));
#define st_hash_start(h) ((st_index_t)(h))
+void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE);
+
RUBY_SYMBOL_EXPORT_END
#if defined(__cplusplus)
diff --git a/include/ruby/subst.h b/include/ruby/subst.h
index 1f0e6db5a4..cf48a3909c 100644
--- a/include/ruby/subst.h
+++ b/include/ruby/subst.h
@@ -1,5 +1,13 @@
-#ifndef RUBY_SUBST_H
+#ifndef RUBY_SUBST_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_SUBST_H 1
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
#undef snprintf
#undef vsnprintf
diff --git a/include/ruby/thread.h b/include/ruby/thread.h
index 550f678e54..b05537badb 100644
--- a/include/ruby/thread.h
+++ b/include/ruby/thread.h
@@ -1,27 +1,23 @@
-/**********************************************************************
-
- thread.h -
-
- $Author: matz $
- created at: Tue Jul 10 17:35:43 JST 2012
-
- Copyright (C) 2007 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_THREAD_H
+#ifndef RUBY_THREAD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_THREAD_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
+/**
+ * @file
+ * @author $Author: matz $
+ * @date Tue Jul 10 17:35:43 JST 2012
+ * @copyright Copyright (C) 2007 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
#include "ruby/intern.h"
+#include "ruby/internal/dllexport.h"
+
+/* flags for rb_nogvl */
+#define RB_NOGVL_INTR_FAIL (0x1)
+#define RB_NOGVL_UBF_ASYNC_SAFE (0x2)
-RUBY_SYMBOL_EXPORT_BEGIN
+RBIMPL_SYMBOL_EXPORT_BEGIN()
void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
@@ -30,16 +26,17 @@ void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
void *rb_thread_call_without_gvl2(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2);
+/*
+ * XXX: unstable/unapproved - out-of-tree code should NOT not depend
+ * on this until it hits Ruby 2.6.1
+ */
+void *rb_nogvl(void *(*func)(void *), void *data1,
+ rb_unblock_function_t *ubf, void *data2,
+ int flags);
+
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_AFTER 0x01
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_THREAD_H */
diff --git a/include/ruby/thread_native.h b/include/ruby/thread_native.h
index 8e500c5a13..7e08c2e97f 100644
--- a/include/ruby/thread_native.h
+++ b/include/ruby/thread_native.h
@@ -1,22 +1,21 @@
-/**********************************************************************
-
- thread_native.h -
-
- $Author: ko1 $
- created at: Wed May 14 19:37:31 2014
-
- Copyright (C) 2014 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_THREAD_NATIVE_H
+#ifndef RUBY_THREAD_NATIVE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_THREAD_NATIVE_H 1
+/**
+ * @file
+ * @author $Author: ko1 $
+ * @date Wed May 14 19:37:31 2014
+ * @copyright Copyright (C) 2014 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
/*
* This file contains wrapper APIs for native thread primitives
* which Ruby interpreter uses.
*
- * Now, we only suppors pthread and Windows threads.
+ * Now, we only support pthread and Windows threads.
*
* If you want to use Ruby's Mutex and so on to synchronize Ruby Threads,
* please use Mutex directly.
@@ -32,10 +31,14 @@ typedef union rb_thread_lock_union {
CRITICAL_SECTION crit;
} rb_nativethread_lock_t;
+typedef struct rb_thread_cond_struct rb_nativethread_cond_t;
+
#elif defined(HAVE_PTHREAD_H)
+
#include <pthread.h>
typedef pthread_t rb_nativethread_id_t;
typedef pthread_mutex_t rb_nativethread_lock_t;
+typedef pthread_cond_t rb_nativethread_cond_t;
#else
#error "unsupported thread type"
@@ -51,6 +54,19 @@ void rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock);
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock);
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock);
+void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
+int rb_native_mutex_trylock(rb_nativethread_lock_t *lock);
+void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);
+void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);
+void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);
+
+void rb_native_cond_signal(rb_nativethread_cond_t *cond);
+void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
+void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
+void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec);
+void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
+void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
+
RUBY_SYMBOL_EXPORT_END
#endif
diff --git a/include/ruby/util.h b/include/ruby/util.h
index 3b78e467b4..af022dacbd 100644
--- a/include/ruby/util.h
+++ b/include/ruby/util.h
@@ -1,51 +1,20 @@
-/**********************************************************************
-
- util.h -
-
- $Author$
- created at: Thu Mar 9 11:55:53 JST 1995
-
- Copyright (C) 1993-2007 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_UTIL_H
+#ifndef RUBY_UTIL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_UTIL_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
+/**
+ * @file
+ * @author $Author$
+ * @date Thu Mar 9 11:55:53 JST 1995
+ * @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/config.h"
+#include "ruby/internal/dllexport.h"
#include "ruby/defines.h"
-#ifdef RUBY_EXTCONF_H
-#include RUBY_EXTCONF_H
-#endif
-#ifndef _
-#ifdef __cplusplus
-# ifndef HAVE_PROTOTYPES
-# define HAVE_PROTOTYPES 1
-# endif
-# ifndef HAVE_STDARG_PROTOTYPES
-# define HAVE_STDARG_PROTOTYPES 1
-# endif
-#endif
-#ifdef HAVE_PROTOTYPES
-# define _(args) args
-#else
-# define _(args) ()
-#endif
-#ifdef HAVE_STDARG_PROTOTYPES
-# define __(args) args
-#else
-# define __(args) ()
-#endif
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
+RBIMPL_SYMBOL_EXPORT_BEGIN()
#define DECIMAL_SIZE_OF_BITS(n) (((n) * 3010 + 9998) / 9999)
/* an approximation of ceil(n * log10(2)), up to 65536 at least */
@@ -70,7 +39,6 @@ char *ruby_strdup(const char *);
#define strdup(s) ruby_strdup(s)
char *ruby_getcwd(void);
-#define my_getcwd() ruby_getcwd()
double ruby_strtod(const char *, char **);
#undef strtod
@@ -78,13 +46,6 @@ double ruby_strtod(const char *, char **);
void ruby_each_words(const char *, void (*)(const char*, int, void*), void *);
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_UTIL_H */
diff --git a/include/ruby/version.h b/include/ruby/version.h
index 10b1b05436..924bfa8f91 100644
--- a/include/ruby/version.h
+++ b/include/ruby/version.h
@@ -1,17 +1,17 @@
-/**********************************************************************
-
- ruby/version.h -
-
- $Author$
- created at: Wed May 13 12:56:56 JST 2009
-
- Copyright (C) 1993-2009 Yukihiro Matsumoto
- Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
- Copyright (C) 2000 Information-technology Promotion Agency, Japan
-
-**********************************************************************/
-
-/*
+#ifndef RUBY_VERSION_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RUBY_VERSION_H 1
+/**
+ * @file
+ * @author $Author$
+ * @date Wed May 13 12:56:56 JST 2009
+ * @copyright Copyright (C) 1993-2009 Yukihiro Matsumoto
+ * @copyright Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
+ * @copyright Copyright (C) 2000 Information-technology Promotion Agency, Japan
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ *
* This file contains only
* - never-changeable information, and
* - interfaces accessible from extension libraries.
@@ -20,9 +20,6 @@
* check the features with mkmf.rb instead.
*/
-#ifndef RUBY_VERSION_H
-#define RUBY_VERSION_H 1
-
/* The origin. */
#define RUBY_AUTHOR "Yukihiro Matsumoto"
#define RUBY_BIRTH_YEAR 1993
@@ -30,20 +27,16 @@
#define RUBY_BIRTH_DAY 24
/* API version */
-#define RUBY_API_VERSION_MAJOR 2
-#define RUBY_API_VERSION_MINOR 5
+#define RUBY_API_VERSION_MAJOR 3
+#define RUBY_API_VERSION_MINOR 0
#define RUBY_API_VERSION_TEENY 0
#define RUBY_API_VERSION_CODE (RUBY_API_VERSION_MAJOR*10000+RUBY_API_VERSION_MINOR*100+RUBY_API_VERSION_TEENY)
#ifdef RUBY_EXTERN
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
+/* Internal note: this file could be included from verconf.mk _before_
+ * generating config.h, on Windows. The #ifdef above is to trick such
+ * situation. */
+RBIMPL_SYMBOL_EXPORT_BEGIN()
/*
* Interfaces from extension libraries.
@@ -61,14 +54,7 @@ RUBY_EXTERN const char ruby_description[];
RUBY_EXTERN const char ruby_copyright[];
RUBY_EXTERN const char ruby_engine[];
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif
#endif
diff --git a/include/ruby/vm.h b/include/ruby/vm.h
index 73345264bd..7bdd567453 100644
--- a/include/ruby/vm.h
+++ b/include/ruby/vm.h
@@ -1,31 +1,23 @@
-/**********************************************************************
-
- ruby/vm.h -
-
- $Author$
- created at: Sat May 31 15:17:36 2008
-
- Copyright (C) 2008 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_VM_H
+#ifndef RUBY_VM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_VM_H 1
+/**
+ * @file
+ * @author $Author$
+ * @date Sat May 31 15:17:36 2008
+ * @copyright Copyright (C) 2008 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/dllexport.h"
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
+RBIMPL_SYMBOL_EXPORT_BEGIN()
/* Place holder.
*
* We will prepare VM creation/control APIs on 1.9.2 or later.
- * If you have an interest about it, please see mvm branch.
- * http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/
+ *
*/
/* VM type declaration */
@@ -52,13 +44,6 @@ int ruby_vm_destruct(ruby_vm_t *vm);
*/
void ruby_vm_at_exit(void(*func)(ruby_vm_t *));
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_VM_H */
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index a2ba226b59..00259485a2 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -138,11 +138,18 @@ typedef int clockid_t;
#undef stat
#undef fstat
#ifdef RUBY_EXPORT
-#define utime(_p, _t) rb_w32_utime(_p, _t)
-#define lseek(_f, _o, _w) _lseeki64(_f, _o, _w)
+#define utime(_p, _t) rb_w32_uutime(_p, _t)
+#undef HAVE_UTIMES
+#define HAVE_UTIMES 1
+#define utimes(_p, _t) rb_w32_uutimes(_p, _t)
+#undef HAVE_UTIMENSAT
+#define HAVE_UTIMENSAT 1
+#define AT_FDCWD -100
+#define utimensat(_d, _p, _t, _f) rb_w32_uutimensat(_d, _p, _t, _f)
+#define lseek(_f, _o, _w) rb_w32_lseek(_f, _o, _w)
#define pipe(p) rb_w32_pipe(p)
-#define open rb_w32_open
+#define open rb_w32_uopen
#define close(h) rb_w32_close(h)
#define fclose(f) rb_w32_fclose(f)
#define read(f, b, s) rb_w32_read(f, b, s)
@@ -151,42 +158,51 @@ typedef int clockid_t;
#define getppid() rb_w32_getppid()
#define sleep(x) rb_w32_Sleep((x)*1000)
#define Sleep(msec) (void)rb_w32_Sleep(msec)
-#define fstati64(fd,st) rb_w32_fstati64(fd,st)
#undef execv
-#define execv(path,argv) rb_w32_aspawn(P_OVERLAY,path,argv)
+#define execv(path,argv) rb_w32_uaspawn(P_OVERLAY,path,argv)
#undef isatty
#define isatty(h) rb_w32_isatty(h)
#undef mkdir
-#define mkdir(p, m) rb_w32_mkdir(p, m)
+#define mkdir(p, m) rb_w32_umkdir(p, m)
#undef rmdir
-#define rmdir(p) rb_w32_rmdir(p)
+#define rmdir(p) rb_w32_urmdir(p)
#undef unlink
-#define unlink(p) rb_w32_unlink(p)
+#define unlink(p) rb_w32_uunlink(p)
#endif /* RUBY_EXPORT */
-#if SIZEOF_OFF_T == 8
+/* same with stati64 except the size of st_ino and nanosecond timestamps */
+struct stati128 {
+ _dev_t st_dev;
+ unsigned __int64 st_ino;
+ __int64 st_inohigh;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ __int64 st_size;
+ __time64_t st_atime;
+ long st_atimensec;
+ __time64_t st_mtime;
+ long st_mtimensec;
+ __time64_t st_ctime;
+ long st_ctimensec;
+};
+
#define off_t __int64
-#define stat stati64
-#define fstat(fd,st) fstati64(fd,st)
-#if !defined(_MSC_VER) || RUBY_MSVCRT_VERSION < 80
-#define stati64 _stati64
-#ifndef _stati64
-#define _stati64(path, st) rb_w32_stati64(path, st)
-#endif
-#else
-#define stati64 _stat64
-#define _stat64(path, st) rb_w32_stati64(path, st)
-#endif
-#else
-#define stat(path,st) rb_w32_stat(path,st)
-#define fstat(fd,st) rb_w32_fstat(fd,st)
-extern int rb_w32_stat(const char *, struct stat *);
-extern int rb_w32_fstat(int, struct stat *);
-#endif
-#define lstat(path,st) rb_w32_lstati64(path,st)
-#define access(path,mode) rb_w32_access(path,mode)
+#define stat stati128
+#undef SIZEOF_STRUCT_STAT_ST_INO
+#define SIZEOF_STRUCT_STAT_ST_INO sizeof(unsigned __int64)
+#define HAVE_STRUCT_STAT_ST_INOHIGH
+#define HAVE_STRUCT_STAT_ST_ATIMENSEC
+#define HAVE_STRUCT_STAT_ST_MTIMENSEC
+#define HAVE_STRUCT_STAT_ST_CTIMENSEC
+#define fstat(fd,st) rb_w32_fstati128(fd,st)
+#define stati128(path, st) rb_w32_ustati128(path,st)
+#define lstat(path,st) rb_w32_ulstati128(path,st)
+#define access(path,mode) rb_w32_uaccess(path,mode)
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
@@ -235,7 +251,6 @@ struct ifaddrs {
extern void rb_w32_sysinit(int *, char ***);
extern DWORD rb_w32_osid(void);
-extern rb_pid_t rb_w32_pipe_exec(const char *, const char *, int, int *, int *);
extern int flock(int fd, int oper);
extern int rb_w32_io_cancelable_p(int);
extern int rb_w32_is_socket(int);
@@ -271,10 +286,8 @@ extern struct servent *WSAAPI rb_w32_getservbyport(int, const char *);
extern int socketpair(int, int, int, int *);
extern int getifaddrs(struct ifaddrs **);
extern void freeifaddrs(struct ifaddrs *);
-extern char * rb_w32_getcwd(char *, int);
+extern char * rb_w32_ugetcwd(char *, int);
extern char * rb_w32_ugetenv(const char *);
-extern char * rb_w32_getenv(const char *);
-extern int rb_w32_rename(const char *, const char *);
extern int rb_w32_urename(const char *, const char *);
extern char **rb_w32_get_environ(void);
extern void rb_w32_free_environ(char **);
@@ -283,22 +296,15 @@ extern const char *WSAAPI rb_w32_inet_ntop(int,const void *,char *,size_t);
extern int WSAAPI rb_w32_inet_pton(int,const char *,void *);
extern DWORD rb_w32_osver(void);
-extern int chown(const char *, int, int);
extern int rb_w32_uchown(const char *, int, int);
-extern int link(const char *, const char *);
extern int rb_w32_ulink(const char *, const char *);
-extern ssize_t readlink(const char *, char *, size_t);
extern ssize_t rb_w32_ureadlink(const char *, char *, size_t);
extern ssize_t rb_w32_wreadlink(const WCHAR *, WCHAR *, size_t);
-extern int symlink(const char *src, const char *link);
extern int rb_w32_usymlink(const char *src, const char *link);
extern int gettimeofday(struct timeval *, struct timezone *);
extern int clock_gettime(clockid_t, struct timespec *);
extern int clock_getres(clockid_t, struct timespec *);
extern rb_pid_t waitpid (rb_pid_t, int *, int);
-extern rb_pid_t rb_w32_spawn(int, const char *, const char*);
-extern rb_pid_t rb_w32_aspawn(int, const char *, char *const *);
-extern rb_pid_t rb_w32_aspawn_flags(int, const char *, char *const *, DWORD);
extern rb_pid_t rb_w32_uspawn(int, const char *, const char*);
extern rb_pid_t rb_w32_uaspawn(int, const char *, char *const *);
extern rb_pid_t rb_w32_uaspawn_flags(int, const char *, char *const *, DWORD);
@@ -309,21 +315,15 @@ extern rb_pid_t rb_w32_getpid(void);
extern rb_pid_t rb_w32_getppid(void);
extern int rb_w32_isatty(int);
extern int rb_w32_uchdir(const char *);
-extern int rb_w32_mkdir(const char *, int);
extern int rb_w32_umkdir(const char *, int);
-extern int rb_w32_rmdir(const char *);
extern int rb_w32_urmdir(const char *);
-extern int rb_w32_unlink(const char *);
extern int rb_w32_uunlink(const char *);
extern int rb_w32_uchmod(const char *, int);
-extern int rb_w32_stati64(const char *, struct stati64 *);
-extern int rb_w32_ustati64(const char *, struct stati64 *);
-extern int rb_w32_lstati64(const char *, struct stati64 *);
-extern int rb_w32_ulstati64(const char *, struct stati64 *);
-extern int rb_w32_access(const char *, int);
+extern int rb_w32_ustati128(const char *, struct stati128 *);
+extern int rb_w32_ulstati128(const char *, struct stati128 *);
extern int rb_w32_uaccess(const char *, int);
extern char rb_w32_fd_is_text(int);
-extern int rb_w32_fstati64(int, struct stati64 *);
+extern int rb_w32_fstati128(int, struct stati128 *);
extern int rb_w32_dup2(int, int);
#include <float.h>
@@ -418,11 +418,7 @@ extern int rb_w32_utruncate(const char *path, off_t length);
#undef HAVE_TRUNCATE
#define HAVE_TRUNCATE 1
-#if defined HAVE_TRUNCATE64
-#define truncate truncate64
-#else
-#define truncate rb_w32_truncate
-#endif
+#define truncate rb_w32_utruncate
#if defined(_MSC_VER) && _MSC_VER >= 1400 && _MSC_VER < 1800
#define strtoll _strtoi64
@@ -440,8 +436,6 @@ extern rb_gid_t getegid (void);
extern int setuid (rb_uid_t);
extern int setgid (rb_gid_t);
-extern int fstati64(int, struct stati64 *);
-
extern char *rb_w32_strerror(int);
#ifdef RUBY_EXPORT
@@ -693,13 +687,13 @@ extern char *rb_w32_strerror(int);
#define get_osfhandle(h) rb_w32_get_osfhandle(h)
#undef getcwd
-#define getcwd(b, s) rb_w32_getcwd(b, s)
+#define getcwd(b, s) rb_w32_ugetcwd(b, s)
#undef getenv
-#define getenv(n) rb_w32_getenv(n)
+#define getenv(n) rb_w32_ugetenv(n)
#undef rename
-#define rename(o, n) rb_w32_rename(o, n)
+#define rename(o, n) rb_w32_urename(o, n)
#undef times
#define times(t) rb_w32_times(t)
@@ -722,7 +716,6 @@ struct tm *localtime_r(const time_t *, struct tm *);
/* thread stuff */
int rb_w32_sleep(unsigned long msec);
-int rb_w32_open(const char *, int, ...);
int rb_w32_uopen(const char *, int, ...);
int rb_w32_wopen(const WCHAR *, int, ...);
int rb_w32_close(int);
@@ -730,8 +723,10 @@ int rb_w32_fclose(FILE*);
int rb_w32_pipe(int[2]);
ssize_t rb_w32_read(int, void *, size_t);
ssize_t rb_w32_write(int, const void *, size_t);
-int rb_w32_utime(const char *, const struct utimbuf *);
+off_t rb_w32_lseek(int, off_t, int);
int rb_w32_uutime(const char *, const struct utimbuf *);
+int rb_w32_uutimes(const char *, const struct timeval *);
+int rb_w32_uutimensat(int /* must be AT_FDCWD */, const char *, const struct timespec *, int /* must be 0 */);
long rb_w32_write_console(uintptr_t, int); /* use uintptr_t instead of VALUE because it's not defined yet here */
int WINAPI rb_w32_Sleep(unsigned long msec);
int rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout);
@@ -741,6 +736,27 @@ int rb_w32_unwrap_io_handle(int);
WCHAR *rb_w32_mbstr_to_wstr(UINT, const char *, int, long *);
char *rb_w32_wstr_to_mbstr(UINT, const WCHAR *, int, long *);
+DEPRECATED_BY(rb_w32_ugetcwd, char *rb_w32_getcwd(char *, int));
+DEPRECATED_BY(rb_w32_ugetenv, char *rb_w32_getenv(const char *));
+DEPRECATED_BY(rb_w32_urename, int rb_w32_rename(const char *, const char *));
+DEPRECATED_BY(rb_w32_uopen, int rb_w32_open(const char *, int, ...));
+DEPRECATED_BY(rb_w32_uchown, int chown(const char *, int, int));
+DEPRECATED_BY(rb_w32_ulink, int link(const char *, const char *));
+DEPRECATED_BY(rb_w32_ureadlink, ssize_t readlink(const char *, char *, size_t));
+DEPRECATED_BY(rb_w32_usymlink, int symlink(const char *src, const char *link));
+DEPRECATED_BY(rb_w32_umkdir, int rb_w32_mkdir(const char *, int));
+DEPRECATED_BY(rb_w32_urmdir, int rb_w32_rmdir(const char *));
+DEPRECATED_BY(rb_w32_uunlink, int rb_w32_unlink(const char *));
+DEPRECATED_BY(rb_w32_uutime, int rb_w32_utime(const char *, const struct utimbuf *));
+DEPRECATED_BY(rb_w32_uutimes, int rb_w32_utimes(const char *, const struct timeval *));
+DEPRECATED_BY(rb_w32_uutimensat, int rb_w32_utimensat(int, const char *, const struct timespec *, int));
+DEPRECATED_BY(rb_w32_ustati128, int rb_w32_stati128(const char *, struct stati128 *));
+DEPRECATED_BY(rb_w32_ulstati128, int rb_w32_lstati128(const char *, struct stati128 *));
+DEPRECATED_BY(rb_w32_uaccess, int rb_w32_access(const char *, int));
+DEPRECATED_BY(rb_w32_uspawn, rb_pid_t rb_w32_spawn(int, const char *, const char*));
+DEPRECATED_BY(rb_w32_uaspawn, rb_pid_t rb_w32_aspawn(int, const char *, char *const *));
+DEPRECATED_BY(rb_w32_uaspawn_flags, rb_pid_t rb_w32_aspawn_flags(int, const char *, char *const *, DWORD));
+
/*
== ***CAUTION***
Since this function is very dangerous, ((*NEVER*))
diff --git a/inits.c b/inits.c
index 5822f04cab..f636748101 100644
--- a/inits.c
+++ b/inits.c
@@ -9,15 +9,25 @@
**********************************************************************/
-#include "internal.h"
+#include "internal/inits.h"
+#include "ruby.h"
+#include "builtin.h"
+static void Init_builtin_prelude(void);
+#include "prelude.rbinc"
#define CALL(n) {void Init_##n(void); Init_##n();}
void
rb_call_inits(void)
{
+ CALL(Thread_Mutex);
+#if USE_TRANSIENT_HEAP
+ CALL(TransientHeap);
+#endif
+ CALL(vm_postponed_job);
CALL(Method);
CALL(RandomSeedCore);
+ CALL(encodings);
CALL(sym);
CALL(var_tables);
CALL(Object);
@@ -28,7 +38,6 @@ rb_call_inits(void)
CALL(String);
CALL(Exception);
CALL(eval);
- CALL(safe);
CALL(jump);
CALL(Numeric);
CALL(Bignum);
@@ -52,14 +61,41 @@ rb_call_inits(void)
CALL(Math);
CALL(GC);
CALL(Enumerator);
+ CALL(Ractor);
CALL(VM);
CALL(ISeq);
CALL(Thread);
+ CALL(Scheduler);
CALL(process);
CALL(Cont);
CALL(Rational);
CALL(Complex);
+ CALL(MemoryView);
CALL(version);
CALL(vm_trace);
+ CALL(vm_stack_canary);
+ CALL(ast);
+ CALL(gc_stress);
+
+ // enable builtin loading
+ CALL(builtin);
+}
+
+void
+rb_call_builtin_inits(void)
+{
+#define BUILTIN(n) CALL(builtin_##n)
+ BUILTIN(gc);
+ BUILTIN(ractor);
+ BUILTIN(integer);
+ BUILTIN(io);
+ BUILTIN(dir);
+ BUILTIN(ast);
+ BUILTIN(trace_point);
+ BUILTIN(pack);
+ BUILTIN(warning);
+ BUILTIN(array);
+ BUILTIN(kernel);
+ Init_builtin_prelude();
}
#undef CALL
diff --git a/insns.def b/insns.def
index bd47c2c0b0..51e130786b 100644
--- a/insns.def
+++ b/insns.def
@@ -1,36 +1,62 @@
-/** ##skip -*- mode:c; style:ruby; coding: utf-8 -*-
+/* -*- C -*-
insns.def - YARV instruction definitions
$Author: $
created at: 04/01/01 01:17:55 JST
Copyright (C) 2004-2007 Koichi Sasada
-*/
-
-/** ##skip
- instruction comment
- @c: category
- @e: english description
- @j: japanese description
-
- instruction form:
- DEFINE_INSN
- instruction_name
- (instruction_operands, ..)
- (pop_values, ..)
- (return value)
- {
+ Massive rewrite by @shyouhei in 2017.
+ */
+
+/* Some comments about this file's contents:
+
+ - The new format aims to be editable by C editor of your choice;
+ your mileage might vary of course.
+
+ - Each instructions are in following format:
+
+ DEFINE_INSN
+ instruction_name
+ (type operand, type operand, ..)
+ (pop_values, ..)
+ (return values ..)
+ // attr type name contents..
+ {
.. // insn body
- }
+ }
- */
+ - Unlike the old format which was line-oriented, you can now place
+ newlines and comments at liberal positions.
+
+ - `DEFINE_INSN` is a keyword.
+
+ - An instruction name must be a valid C identifier.
+
+ - Operands, pop values, return values are series of either variable
+ declarations, keyword `void`, or keyword `...`. They are much
+ like C function declarations.
+ - Attribute pragmas are optional, and can include arbitrary C
+ expressions. You can write anything there but as of writing,
+ supported attributes are:
-/**
- @c nop
- @e nop
- @j nop
+ * sp_inc: Used to dynamically calculate sp increase in
+ `insn_stack_increase`.
+
+ * handles_sp: If it is true, VM deals with sp in the insn.
+ Default is if the instruction takes ISEQ operand or not.
+
+ * leaf: indicates that the instruction is "leaf" i.e. it does
+ not introduce new stack frame on top of it.
+ If an instruction handles sp, that can never be a leaf.
+
+ - Attributes can access operands, but not stack (push/pop) variables.
+
+ - An instruction's body is a pure C block, copied verbatimly into
+ the generated C source code.
*/
+
+/* nop */
DEFINE_INSN
nop
()
@@ -44,12 +70,8 @@ nop
/* deal with variables */
/**********************************************************/
-/**
- @c variable
- @e Get local variable (pointed by `idx' and `level').
+/* Get local variable (pointed by `idx' and `level').
'level' indicates the nesting depth from the current block.
- @j level, idx ã§æŒ‡å®šã•れãŸãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã®å€¤ã‚’スタックã«ç½®ã。
- level ã¯ãƒ–ロックã®ãƒã‚¹ãƒˆãƒ¬ãƒ™ãƒ«ã§ã€ä½•段上ã‹ã‚’示ã™ã€‚
*/
DEFINE_INSN
getlocal
@@ -62,12 +84,8 @@ getlocal
(void)RB_DEBUG_COUNTER_INC_IF(lvar_get_dynamic, level > 0);
}
-/**
- @c variable
- @e Set a local variable (pointed to by 'idx') as val.
+/* Set a local variable (pointed to by 'idx') as val.
'level' indicates the nesting depth from the current block.
- @j level, idx ã§æŒ‡å®šã•れãŸãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã®å€¤ã‚’ val ã«ã™ã‚‹ã€‚
- level ã¯ãƒ–ロックã®ãƒã‚¹ãƒˆãƒ¬ãƒ™ãƒ«ã§ã€ä½•段上ã‹ã‚’示ã™ã€‚
*/
DEFINE_INSN
setlocal
@@ -80,174 +98,220 @@ setlocal
(void)RB_DEBUG_COUNTER_INC_IF(lvar_set_dynamic, level > 0);
}
-/**
- @c variable
- @e Get value of special local variable ($~, $_, ..).
- @j 特殊ãªãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ï¼ˆ$~, $_, ...)ã®å€¤ã‚’得る。
+/* Get a block parameter. */
+DEFINE_INSN
+getblockparam
+(lindex_t idx, rb_num_t level)
+()
+(VALUE val)
+{
+ const VALUE *ep = vm_get_ep(GET_EP(), level);
+ VM_ASSERT(VM_ENV_LOCAL_P(ep));
+
+ if (!VM_ENV_FLAGS(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)) {
+ val = rb_vm_bh_to_procval(ec, VM_ENV_BLOCK_HANDLER(ep));
+ vm_env_write(ep, -(int)idx, val);
+ VM_ENV_FLAGS_SET(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM);
+ }
+ else {
+ val = *(ep - idx);
+ RB_DEBUG_COUNTER_INC(lvar_get);
+ (void)RB_DEBUG_COUNTER_INC_IF(lvar_get_dynamic, level > 0);
+ }
+}
+
+/* Set block parameter. */
+DEFINE_INSN
+setblockparam
+(lindex_t idx, rb_num_t level)
+(VALUE val)
+()
+{
+ const VALUE *ep = vm_get_ep(GET_EP(), level);
+ VM_ASSERT(VM_ENV_LOCAL_P(ep));
+
+ vm_env_write(ep, -(int)idx, val);
+ RB_DEBUG_COUNTER_INC(lvar_set);
+ (void)RB_DEBUG_COUNTER_INC_IF(lvar_set_dynamic, level > 0);
+
+ VM_ENV_FLAGS_SET(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM);
+}
+
+/* Get special proxy object which only responds to `call` method if the block parameter
+ represents a iseq/ifunc block. Otherwise, same as `getblockparam`.
*/
DEFINE_INSN
+getblockparamproxy
+(lindex_t idx, rb_num_t level)
+()
+(VALUE val)
+{
+ const VALUE *ep = vm_get_ep(GET_EP(), level);
+ VM_ASSERT(VM_ENV_LOCAL_P(ep));
+
+ if (!VM_ENV_FLAGS(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)) {
+ VALUE block_handler = VM_ENV_BLOCK_HANDLER(ep);
+
+ if (block_handler) {
+ switch (vm_block_handler_type(block_handler)) {
+ case block_handler_type_iseq:
+ case block_handler_type_ifunc:
+ val = rb_block_param_proxy;
+ break;
+ case block_handler_type_symbol:
+ val = rb_sym_to_proc(VM_BH_TO_SYMBOL(block_handler));
+ goto INSN_LABEL(set);
+ case block_handler_type_proc:
+ val = VM_BH_TO_PROC(block_handler);
+ goto INSN_LABEL(set);
+ default:
+ VM_UNREACHABLE(getblockparamproxy);
+ }
+ }
+ else {
+ val = Qnil;
+ INSN_LABEL(set):
+ vm_env_write(ep, -(int)idx, val);
+ VM_ENV_FLAGS_SET(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM);
+ }
+ }
+ else {
+ val = *(ep - idx);
+ RB_DEBUG_COUNTER_INC(lvar_get);
+ (void)RB_DEBUG_COUNTER_INC_IF(lvar_get_dynamic, level > 0);
+ }
+}
+
+/* Get value of special local variable ($~, $_, ..). */
+DEFINE_INSN
getspecial
(rb_num_t key, rb_num_t type)
()
(VALUE val)
+/* `$~ = MatchData.allocate; $&` can raise. */
+// attr bool leaf = (type == 0) ? true : false;
{
- val = vm_getspecial(th, GET_LEP(), key, type);
+ val = vm_getspecial(ec, GET_LEP(), key, type);
}
-/**
- @c variable
- @e Set value of special local variable ($~, $_, ...) to obj.
- @j 特別ãªãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ï¼ˆ$~, $_, ...)ã®å€¤ã‚’設定ã™ã‚‹ã€‚
- */
+/* Set value of special local variable ($~, $_, ...) to obj. */
DEFINE_INSN
setspecial
(rb_num_t key)
(VALUE obj)
()
{
- lep_svar_set(th, GET_LEP(), key, obj);
+ lep_svar_set(ec, GET_LEP(), key, obj);
}
-/**
- @c variable
- @e Get value of instance variable id of self.
- @j self ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹å¤‰æ•° id ã®å€¤ã‚’得る。
- */
+/* Get value of instance variable id of self. */
DEFINE_INSN
getinstancevariable
-(ID id, IC ic)
+(ID id, IVC ic)
()
(VALUE val)
+/* Ractor crashes when it accesses class/module-level instances variables. */
+// attr bool leaf = false; /* has IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR() */
{
- val = vm_getinstancevariable(GET_SELF(), id, ic);
+ val = vm_getinstancevariable(GET_ISEQ(), GET_SELF(), id, ic);
}
-/**
- @c variable
- @e Set value of instance variable id of self to val.
- @j self ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹å¤‰æ•° id ã‚’ val ã«ã™ã‚‹ã€‚
- */
+/* Set value of instance variable id of self to val. */
DEFINE_INSN
setinstancevariable
-(ID id, IC ic)
+(ID id, IVC ic)
(VALUE val)
()
+// attr bool leaf = false; /* has rb_check_frozen_internal() */
{
- vm_setinstancevariable(GET_SELF(), id, val, ic);
+ vm_setinstancevariable(GET_ISEQ(), GET_SELF(), id, val, ic);
}
-/**
- @c variable
- @e Get value of class variable id of klass as val.
- @j ç¾åœ¨ã®ã‚¹ã‚³ãƒ¼ãƒ—ã®ã‚¯ãƒ©ã‚¹å¤‰æ•° id ã®å€¤ã‚’得る。
- */
+/* Get value of class variable id of klass as val. */
DEFINE_INSN
getclassvariable
(ID id)
()
(VALUE val)
+/* "class variable access from toplevel" warning can be hooked. */
+// attr bool leaf = false; /* has rb_warning() */
{
- val = rb_cvar_get(vm_get_cvar_base(rb_vm_get_cref(GET_EP()), GET_CFP()), id);
+ val = rb_cvar_get(vm_get_cvar_base(vm_get_cref(GET_EP()), GET_CFP(), 1), id);
}
-/**
- @c variable
- @e Set value of class variable id of klass as val.
- @j klass ã®ã‚¯ãƒ©ã‚¹å¤‰æ•° id ã‚’ val ã«ã™ã‚‹ã€‚
- */
+/* Set value of class variable id of klass as val. */
DEFINE_INSN
setclassvariable
(ID id)
(VALUE val)
()
+/* "class variable access from toplevel" warning can be hooked. */
+// attr bool leaf = false; /* has rb_warning() */
{
vm_ensure_not_refinement_module(GET_SELF());
- rb_cvar_set(vm_get_cvar_base(rb_vm_get_cref(GET_EP()), GET_CFP()), id, val);
+ rb_cvar_set(vm_get_cvar_base(vm_get_cref(GET_EP()), GET_CFP(), 1), id, val);
}
-/**
- @c variable
- @e
- Get constant variable id. If klass is Qnil, constants
- are searched in the current scope. If klass is Qfalse, constants
- are searched as top level constants. Otherwise, get constant under klass
+/* Get constant variable id. If klass is Qnil and allow_nil is Qtrue, constants
+ are searched in the current scope. Otherwise, get constant under klass
class or module.
- @j 定数 id ã®å€¤ã‚’得る。
- klass ㌠Qnil ãªã‚‰ã€ãã®ã‚¹ã‚³ãƒ¼ãƒ—ã§å¾—られる定数ã®å€¤ã‚’得る。
- Qfalse ãªã‚‰ã€ãƒˆãƒƒãƒ—レベルスコープを得る。
- ãれ以外ãªã‚‰ã€klass クラスã®ä¸‹ã®å®šæ•°ã‚’得る。
*/
DEFINE_INSN
getconstant
(ID id)
-(VALUE klass)
+(VALUE klass, VALUE allow_nil)
(VALUE val)
+/* getconstant can kick autoload */
+// attr bool leaf = false; /* has rb_autoload_load() */
{
- val = vm_get_ev_const(th, klass, id, 0);
+ val = vm_get_ev_const(ec, klass, id, allow_nil == Qtrue, 0);
}
-/**
- @c variable
- @e
- Set constant variable id. If klass is Qfalse, constant
- is able to access in this scope. if klass is Qnil, set
- top level constant. otherwise, set constant under klass
- class or module.
-
- @j 定数 id ã®å€¤ã‚’ val ã«ã™ã‚‹ã€‚
- klass ㌠Qfalse ãªã‚‰ã€ãã®ã‚¹ã‚³ãƒ¼ãƒ—ã§å¾—られる定数 id ã®å€¤ã‚’設定ã™ã‚‹ã€‚
- Qnil ãªã‚‰ã€ãƒˆãƒƒãƒ—レベルスコープã®å€¤ã‚’設定ã™ã‚‹ã€‚
- ãれ以外ãªã‚‰ã€klass クラスã®ä¸‹ã®å®šæ•°ã‚’設定ã™ã‚‹ã€‚
+/* Set constant variable id under cbase class or module.
*/
DEFINE_INSN
setconstant
(ID id)
(VALUE val, VALUE cbase)
()
+/* Assigning an object to a constant is basically a leaf operation.
+ * The problem is, assigning a Module instance to a constant _names_
+ * that module. Naming involves string manipulations, which are
+ * method calls. */
+// attr bool leaf = false; /* has StringValue() */
{
vm_check_if_namespace(cbase);
vm_ensure_not_refinement_module(GET_SELF());
rb_const_set(cbase, id, val);
}
-/**
- @c variable
- @e get global variable id.
- @j グローãƒãƒ«å¤‰æ•° id ã®å€¤ã‚’得る。
- */
+/* get global variable id. */
DEFINE_INSN
getglobal
-(GENTRY entry)
+(ID gid)
()
(VALUE val)
+// attr bool leaf = false;
{
- val = GET_GLOBAL((VALUE)entry);
+ val = rb_gvar_get(gid);
}
-/**
- @c variable
- @e set global variable id as val.
- @j グローãƒãƒ«å¤‰æ•° id ã®å€¤ã‚’設定ã™ã‚‹ã€‚
- */
+/* set global variable id as val. */
DEFINE_INSN
setglobal
-(GENTRY entry)
+(ID gid)
(VALUE val)
()
+// attr bool leaf = false;
{
- SET_GLOBAL((VALUE)entry, val);
+ rb_gvar_set(gid, val);
}
-
/**********************************************************/
/* deal with values */
/**********************************************************/
-/**
- @c put
- @e put nil to stack.
- @j スタック㫠nil をプッシュã™ã‚‹ã€‚
- */
+/* put nil to stack. */
DEFINE_INSN
putnil
()
@@ -257,11 +321,7 @@ putnil
val = Qnil;
}
-/**
- @c put
- @e put self.
- @j スタック㫠self をプッシュã™ã‚‹ã€‚
- */
+/* put self. */
DEFINE_INSN
putself
()
@@ -271,11 +331,7 @@ putself
val = GET_SELF();
}
-/**
- @c put
- @e put some object.
- i.e. Fixnum, true, false, nil, and so on.
- @j オブジェクト val をスタックã«ãƒ—ッシュã™ã‚‹ã€‚
+/* put some object.
i.e. Fixnum, true, false, nil, and so on.
*/
DEFINE_INSN
@@ -287,12 +343,7 @@ putobject
/* */
}
-/**
- @c put
- @e put special object. "value_type" is for expansion.
- @j 特別ãªã‚ªãƒ–ジェクト val をスタックã«ãƒ—ッシュã™ã‚‹ã€‚
- オブジェクトã®ç¨®é¡žã¯ value_type ã«ã‚ˆã‚‹ï¼Ž
- */
+/* put special object. "value_type" is for expansion. */
DEFINE_INSN
putspecialobject
(rb_num_t value_type)
@@ -305,104 +356,59 @@ putspecialobject
val = vm_get_special_object(GET_EP(), type);
}
-/**
- @c put
- @e put iseq value.
- @j iseq をスタックã«ãƒ—ッシュã™ã‚‹ã€‚
- */
-DEFINE_INSN
-putiseq
-(ISEQ iseq)
-()
-(VALUE ret)
-{
- ret = (VALUE)iseq;
-}
-
-/**
- @c put
- @e put string val. string will be copied.
- @j 文字列をコピーã—ã¦ã‚¹ã‚¿ãƒƒã‚¯ã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* put string val. string will be copied. */
DEFINE_INSN
putstring
(VALUE str)
()
(VALUE val)
{
- val = rb_str_resurrect(str);
+ val = rb_ec_str_resurrect(ec, str);
}
-/**
- @c put
- @e put concatenate strings
- @j ã‚¹ã‚¿ãƒƒã‚¯ãƒˆãƒƒãƒ—ã®æ–‡å­—列を n 個連çµã—ï¼Œçµæžœã‚’スタックã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* put concatenate strings */
DEFINE_INSN
concatstrings
(rb_num_t num)
(...)
-(VALUE val) // inc += 1 - num;
+(VALUE val)
+/* This instruction can concat UTF-8 and binary strings, resulting in
+ * Encoding::CompatibilityError. */
+// attr bool leaf = false; /* has rb_enc_cr_str_buf_cat() */
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
{
val = rb_str_concat_literals(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
-/**
- @c put
- @e push the result of to_s.
- @j to_s ã®çµæžœã‚’スタックã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* push the result of to_s. */
DEFINE_INSN
tostring
()
(VALUE val, VALUE str)
(VALUE val)
{
- VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
val = rb_obj_as_string_result(str, val);
}
-/**
- @c put
- @e Freeze (dynamically) created strings. if debug_info is given, set it.
- @j (埋ã‚è¾¼ã¿ï¼‰æ–‡å­—列を freeze ã™ã‚‹ã€‚ã‚‚ã—ã€debug_info ãŒä¸Žãˆã‚‰ã‚Œã¦ã„れã°ã€ãれを設定ã™ã‚‹ã€‚
- */
-DEFINE_INSN
-freezestring
-(VALUE debug_info)
-(VALUE str)
-(VALUE str)
-{
- vm_freezestring(str, debug_info);
-}
-
-/**
- @c put
- @e compile str to Regexp and push it.
+/* compile str to Regexp and push it.
opt is the option for the Regexp.
- @j 文字列 str ã‚’æ­£è¦è¡¨ç¾ã«ã‚³ãƒ³ãƒ‘イルã—ã¦ã‚¹ã‚¿ãƒƒã‚¯ã«ãƒ—ッシュã™ã‚‹ã€‚
- コンパイル時,opt ã‚’æ­£è¦è¡¨ç¾ã®ã‚ªãƒ—ションã¨ã™ã‚‹ã€‚
*/
DEFINE_INSN
toregexp
(rb_num_t opt, rb_num_t cnt)
(...)
-(VALUE val) // inc += 1 - cnt;
+(VALUE val)
+/* This instruction can raise RegexpError, thus can call
+ * RegexpError#initialize */
+// attr bool leaf = false;
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)cnt;
{
- VALUE rb_reg_new_ary(VALUE ary, int options);
- VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
const VALUE ary = rb_ary_tmp_new_from_values(0, cnt, STACK_ADDR_FROM_TOP(cnt));
- POPN(cnt);
val = rb_reg_new_ary(ary, (int)opt);
rb_ary_clear(ary);
}
-/**
- @c put
- @e intern str to Symbol and push it.
- @j 文字列 str をシンボルã«å¤‰æ›ã—ã¦ã‚¹ã‚¿ãƒƒã‚¯ã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* intern str to Symbol and push it. */
DEFINE_INSN
intern
()
@@ -412,38 +418,60 @@ intern
sym = rb_str_intern(str);
}
-/**
- @c put
- @e put new array initialized with num values on the stack.
- @j æ–°ã—ã„é…列をスタック上㮠num 個ã®å€¤ã§åˆæœŸåŒ–ã—ã¦ç”Ÿæˆã—プッシュã™ã‚‹ã€‚
- */
+/* put new array initialized with num values on the stack. */
DEFINE_INSN
newarray
(rb_num_t num)
(...)
-(VALUE val) // inc += 1 - num;
+(VALUE val)
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
{
- val = rb_ary_new4(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
+ val = rb_ec_ary_new_from_values(ec, num, STACK_ADDR_FROM_TOP(num));
}
-/**
- @c put
- @e dup array
- @j é…列 ary ã‚’ dup ã—ã¦ã‚¹ã‚¿ãƒƒã‚¯ã«ãƒ—ッシュã™ã‚‹ã€‚
+/* put new array initialized with num values on the stack. There
+ should be at least one element on the stack, and the top element
+ should be a hash. If the top element is empty, it is not
+ included in the array.
*/
DEFINE_INSN
+newarraykwsplat
+(rb_num_t num)
+(...)
+(VALUE val)
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
+{
+ if (RHASH_EMPTY_P(*STACK_ADDR_FROM_TOP(1))) {
+ val = rb_ary_new4(num-1, STACK_ADDR_FROM_TOP(num));
+ }
+ else {
+ val = rb_ary_new4(num, STACK_ADDR_FROM_TOP(num));
+ }
+}
+
+/* dup array */
+DEFINE_INSN
duparray
(VALUE ary)
()
(VALUE val)
{
+ RUBY_DTRACE_CREATE_HOOK(ARRAY, RARRAY_LEN(ary));
val = rb_ary_resurrect(ary);
}
-/**
- @c put
- @e if TOS is an array expand, expand it to num objects.
+/* dup hash */
+DEFINE_INSN
+duphash
+(VALUE hash)
+()
+(VALUE val)
+{
+ RUBY_DTRACE_CREATE_HOOK(HASH, RHASH_SIZE(hash) << 1);
+ val = rb_hash_resurrect(hash);
+}
+
+/* if TOS is an array expand, expand it to num objects.
if the number of the array is less than num, push nils to fill.
if it is greater than num, exceeding elements are dropped.
unless TOS is an array, push num - 1 nils.
@@ -451,63 +479,48 @@ duparray
flag: 0x01 - rest args array
flag: 0x02 - for postarg
flag: 0x04 - reverse?
- @j スタックトップã®ã‚ªãƒ–ジェクトãŒé…列ã§ã‚れã°ã€ãれを展開ã™ã‚‹ã€‚
- é…列オブジェクトã®è¦ç´ æ•°ãŒ num以下ãªã‚‰ã°ã€ä»£ã‚り㫠nil ã‚’ç©ã‚€ã€‚num以上ãªã‚‰ã€
- num以上ã®è¦ç´ ã¯åˆ‡ã‚Šæ¨ã¦ã‚‹ã€‚
- é…列オブジェクトã§ãªã‘れã°ã€num - 1 個㮠nil ã‚’ç©ã‚€ã€‚
- ã‚‚ã— flag ãŒçœŸãªã‚‰ã€æ®‹ã‚Šè¦ç´ ã®é…列をç©ã‚€
- flag: 0x01 - 最後をé…列ã«
- flag: 0x02 - postarg 用
- flag: 0x04 - reverse?
*/
DEFINE_INSN
expandarray
(rb_num_t num, rb_num_t flag)
(..., VALUE ary)
-(...) // inc += num - 1 + (flag & 1 ? 1 : 0);
+(...)
+// attr bool leaf = false; /* has rb_check_array_type() */
+// attr rb_snum_t sp_inc = (rb_snum_t)num - 1 + (flag & 1 ? 1 : 0);
{
- vm_expandarray(GET_CFP(), ary, num, (int)flag);
+ vm_expandarray(GET_SP(), ary, num, (int)flag);
}
-/**
- @c put
- @e concat two arrays
- @j 二ã¤ã®é…列 ary1, ary2 を連çµã—スタックã¸ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* concat two arrays */
DEFINE_INSN
concatarray
()
(VALUE ary1, VALUE ary2)
(VALUE ary)
+// attr bool leaf = false; /* has rb_check_array_type() */
{
ary = vm_concat_array(ary1, ary2);
}
-/**
- @c put
- @e call to_a on array ary to splat
- @j splat ã®ãŸã‚ã«é…列 ary ã«å¯¾ã—㦠to_a を呼ã³å‡ºã™ã€‚
- */
+/* call to_a on array ary to splat */
DEFINE_INSN
splatarray
(VALUE flag)
(VALUE ary)
(VALUE obj)
+// attr bool leaf = false; /* has rb_check_array_type() */
{
obj = vm_splat_array(flag, ary);
}
-/**
- @c put
- @e put new Hash from n elements. n must be an even number.
- @j æ–°ã—ã„ãƒãƒƒã‚·ãƒ¥ã‚’スタックトップ㮠n å€‹ã‚’åˆæœŸå€¤ã¨ã—ã¦ç”Ÿæˆã™ã‚‹ã€‚
- n ã¯ã‚­ãƒ¼ã¨å€¤ã®ãƒšã‚¢ãªã®ã§ 2 ã®å€æ•°ã§ãªã‘れã°ãªã‚‰ãªã„。
- */
+/* put new Hash from n elements. n must be an even number. */
DEFINE_INSN
newhash
(rb_num_t num)
(...)
-(VALUE val) // inc += 1 - num;
+(VALUE val)
+// attr bool leaf = false; /* has rb_hash_key_str() */
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
{
RUBY_DTRACE_CREATE_HOOK(HASH, num);
@@ -516,19 +529,16 @@ newhash
if (num) {
rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val);
}
- POPN(num);
}
-/**
- @c put
- @e put new Range object.(Range.new(low, high, flag))
- @j Range.new(low, high, flag) ã®ã‚ˆã†ãªã‚ªãƒ–ジェクトを生æˆã—スタックã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* put new Range object.(Range.new(low, high, flag)) */
DEFINE_INSN
newrange
(rb_num_t flag)
(VALUE low, VALUE high)
(VALUE val)
+/* rb_range_new() exercises "bad value for range" check. */
+// attr bool leaf = false; /* see also: range.c:range_init() */
{
val = rb_range_new(low, high, (int)flag);
}
@@ -537,11 +547,7 @@ newrange
/* deal with stack operation */
/**********************************************************/
-/**
- @c stack
- @e pop from stack.
- @j スタックã‹ã‚‰ä¸€ã¤ãƒãƒƒãƒ—ã™ã‚‹ã€‚
- */
+/* pop from stack. */
DEFINE_INSN
pop
()
@@ -552,11 +558,7 @@ pop
/* none */
}
-/**
- @c stack
- @e duplicate stack top.
- @j スタックトップをコピーã—ã¦ã‚¹ã‚¿ãƒƒã‚¯ã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* duplicate stack top. */
DEFINE_INSN
dup
()
@@ -566,30 +568,21 @@ dup
val1 = val2 = val;
}
-/**
- @c stack
- @e duplicate stack top n elements
- @j スタックトップ㮠n 個をコピーã—ã¦ã‚¹ã‚¿ãƒƒã‚¯ã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* duplicate stack top n elements */
DEFINE_INSN
dupn
(rb_num_t n)
(...)
-(...) // inc += n;
+(...)
+// attr rb_snum_t sp_inc = n;
{
void *dst = GET_SP();
void *src = STACK_ADDR_FROM_TOP(n);
- INC_SP(n); /* alloca */
MEMCPY(dst, src, VALUE, n);
}
-
-/**
- @c stack
- @e swap top 2 vals
- @j スタックトップ㮠2 ã¤ã®å€¤ã‚’交æ›ã™ã‚‹ã€‚
- */
+/* swap top 2 vals */
DEFINE_INSN
swap
()
@@ -599,16 +592,13 @@ swap
/* none */
}
-/**
- @c stack
- @e reverse stack top N order.
- @j スタックトップ㮠n 個ã®å€¤ã‚’逆転ã™ã‚‹ã€‚
- */
+/* reverse stack top N order. */
DEFINE_INSN
reverse
(rb_num_t n)
(...)
-(...) // inc += 0;
+(...)
+// attr rb_snum_t sp_inc = 0;
{
rb_num_t i;
VALUE *sp = STACK_ADDR_FROM_TOP(n);
@@ -621,161 +611,108 @@ reverse
}
}
-/**
- @c stack
- @e for stack caching.
- @j スタックキャッシングã®çŠ¶æ…‹ã‚’èª¿æ•´ã™ã‚‹ãŸã‚ã«å¿…è¦ãªå‘½ä»¤ã€‚
- */
-DEFINE_INSN
+/* for stack caching. */
+DEFINE_INSN_IF(STACK_CACHING)
reput
()
(..., VALUE val)
-(VALUE val) // inc += 0;
+(VALUE val)
+// attr rb_snum_t sp_inc = 0;
{
/* none */
}
-/**
- @c stack
- @e get nth stack value from stack top
- @j スタックトップã‹ã‚‰ n 個目をスタックã«ãƒ—ッシュã™ã‚‹ã€‚
- */
+/* get nth stack value from stack top */
DEFINE_INSN
topn
(rb_num_t n)
(...)
-(VALUE val) // inc += 1;
+(VALUE val)
+// attr rb_snum_t sp_inc = 1;
{
val = TOPN(n);
}
-/**
- @c stack
- @e set Nth stack entry to stack top
- @j スタックトップã®å€¤ã‚’ n 個目ã®ã‚¹ã‚¿ãƒƒã‚¯ã«ã‚³ãƒ”ー
- */
+/* set Nth stack entry to stack top */
DEFINE_INSN
setn
(rb_num_t n)
(..., VALUE val)
-(VALUE val) // inc += 0
+(VALUE val)
+// attr rb_snum_t sp_inc = 0;
{
- TOPN(n-1) = val;
+ TOPN(n) = val;
}
-/**
- @c stack
- @e empty current stack
- @j current stack を空ã«ã™ã‚‹ã€‚
- */
+/* empty current stack */
DEFINE_INSN
adjuststack
(rb_num_t n)
(...)
-(...) // inc -= n
+(...)
+// attr rb_snum_t sp_inc = -(rb_snum_t)n;
{
- DEC_SP(n);
+ /* none */
}
-
/**********************************************************/
/* deal with setting */
/**********************************************************/
-/**
- @c setting
- @e defined?
- @j defined? を行ã†ã€‚
- */
+/* defined? */
DEFINE_INSN
defined
(rb_num_t op_type, VALUE obj, VALUE needstr)
(VALUE v)
(VALUE val)
+// attr bool leaf = leafness_of_defined(op_type);
{
- val = vm_defined(th, GET_CFP(), op_type, obj, needstr, v);
+ val = vm_defined(ec, GET_CFP(), op_type, obj, needstr, v);
}
-/**
- @c setting
- @e check `target' matches `pattern'.
+/* check `target' matches `pattern'.
`flag & VM_CHECKMATCH_TYPE_MASK' describe how to check pattern.
VM_CHECKMATCH_TYPE_WHEN: ignore target and check pattern is truthy.
VM_CHECKMATCH_TYPE_CASE: check `patten === target'.
- VM_CHECKMATCH_TYPE_RESCUE: check `pattern.kind_op?(Module) && pattern == target'.
+ VM_CHECKMATCH_TYPE_RESCUE: check `pattern.kind_op?(Module) && pattern === target'.
if `flag & VM_CHECKMATCH_ARRAY' is not 0, then `patten' is array of patterns.
- @j see above comments.
*/
DEFINE_INSN
checkmatch
(rb_num_t flag)
(VALUE target, VALUE pattern)
(VALUE result)
+// attr bool leaf = leafness_of_checkmatch(flag);
{
- result = vm_check_match(target, pattern, flag);
+ result = vm_check_match(ec, target, pattern, flag);
}
-/**
- @c setting
- @e check keywords are specified or not.
- @j ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãŒæŒ‡å®šã•れã¦ã„ã‚‹ã‹ã©ã†ã‹ãƒã‚§ãƒƒã‚¯ã™ã‚‹
- */
+/* check keywords are specified or not. */
DEFINE_INSN
checkkeyword
-(lindex_t kw_bits_index, rb_num_t keyword_index)
+(lindex_t kw_bits_index, lindex_t keyword_index)
()
(VALUE ret)
{
ret = vm_check_keyword(kw_bits_index, keyword_index, GET_EP());
}
-/**
- @c setting
- @e trace
- @j trace 用ã®å‘½ä»¤ã€‚
- */
-DEFINE_INSN
-trace
-(rb_num_t nf)
-()
-()
-{
- rb_event_flag_t flag = (rb_event_flag_t)nf;
-
- vm_dtrace(flag, th);
- EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0, 0 /* id and klass are resolved at callee */,
- (flag & (RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN)) ? TOPN(0) : Qundef);
-}
-
-/**
- @c setting
- @e trace
- @j trace 用ã®å‘½ä»¤ã€‚
- */
+/* check if val is type. */
DEFINE_INSN
-trace2
-(rb_num_t nf, VALUE data)
-()
-()
+checktype
+(rb_num_t type)
+(VALUE val)
+(VALUE ret)
{
- rb_event_flag_t flag = (rb_event_flag_t)nf;
-
- vm_dtrace(flag, th);
- EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0, 0 /* id and klass are resolved at callee */, data);
+ ret = (TYPE(val) == (int)type) ? Qtrue : Qfalse;
}
/**********************************************************/
/* deal with control flow 1: class/module */
/**********************************************************/
-/**
- @c class/module
- @e
- enter class definition scope. if super is Qfalse, and class
+/* enter class definition scope. if super is Qfalse, and class
"klass" is defined, it's redefine. otherwise, define "klass" class.
- @j クラス定義スコープã¸ç§»è¡Œã™ã‚‹ã€‚
- ã‚‚ã— super ㌠Qfalse ã§ klassクラスãŒå®šç¾©ã•れã¦ã„れã°å†å®šç¾©ã§ã‚る。
- ãã†ã§ãªã‘れã°ã€klass クラスを定義ã™ã‚‹ã€‚
*/
DEFINE_INSN
defineclass
@@ -788,9 +725,9 @@ defineclass
rb_iseq_check(class_iseq);
/* enter scope */
- vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS | VM_ENV_FLAG_LOCAL, klass,
+ vm_push_frame(ec, class_iseq, VM_FRAME_MAGIC_CLASS | VM_ENV_FLAG_LOCAL, klass,
GET_BLOCK_HANDLER(),
- (VALUE)vm_cref_push(th, klass, NULL, FALSE),
+ (VALUE)vm_cref_push(ec, klass, NULL, FALSE),
class_iseq->body->iseq_encoded, GET_SP(),
class_iseq->body->local_table_size,
class_iseq->body->stack_max);
@@ -798,54 +735,104 @@ defineclass
NEXT_INSN();
}
+DEFINE_INSN
+definemethod
+(ID id, ISEQ iseq)
+()
+()
+{
+ vm_define_method(ec, Qnil, id, (VALUE)iseq, FALSE);
+}
+
+DEFINE_INSN
+definesmethod
+(ID id, ISEQ iseq)
+(VALUE obj)
+()
+{
+ vm_define_method(ec, obj, id, (VALUE)iseq, TRUE);
+}
/**********************************************************/
/* deal with control flow 2: method/iterator */
/**********************************************************/
-/**
- @c method/iterator
- @e invoke method.
- @j メソッド呼ã³å‡ºã—を行ã†ã€‚ci ã«å¿…è¦ãªæƒ…å ±ãŒæ ¼ç´ã•れã¦ã„る。
- */
+/* invoke method. */
DEFINE_INSN
send
-(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
+(CALL_DATA cd, ISEQ blockiseq)
+(...)
+(VALUE val)
+// attr rb_snum_t sp_inc = sp_inc_of_sendish(cd->ci);
+// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
+{
+ VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false);
+ val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
+
+ if (val == Qundef) {
+ RESTORE_REGS();
+ NEXT_INSN();
+ }
+}
+
+/* Invoke method without block */
+DEFINE_INSN
+opt_send_without_block
+(CALL_DATA cd)
(...)
-(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
+(VALUE val)
+// attr bool handles_sp = true;
+// attr rb_snum_t sp_inc = sp_inc_of_sendish(cd->ci);
+// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
{
- struct rb_calling_info calling;
+ VALUE bh = VM_BLOCK_HANDLER_NONE;
+ val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
- vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, FALSE);
- vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
- CALL_METHOD(&calling, ci, cc);
+ if (val == Qundef) {
+ RESTORE_REGS();
+ NEXT_INSN();
+ }
}
DEFINE_INSN
opt_str_freeze
-(VALUE str)
+(VALUE str, CALL_DATA cd)
()
(VALUE val)
{
- if (BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG)) {
- val = str;
+ val = vm_opt_str_freeze(str, BOP_FREEZE, idFreeze);
+
+ if (val == Qundef) {
+ PUSH(rb_str_resurrect(str));
+ CALL_SIMPLE_METHOD();
}
- else {
- val = rb_funcall(rb_str_resurrect(str), idFreeze, 0);
+}
+
+/* optimized nil? */
+DEFINE_INSN
+opt_nil_p
+(CALL_DATA cd)
+(VALUE recv)
+(VALUE val)
+{
+ val = vm_opt_nil_p(GET_ISEQ(), cd, recv);
+
+ if (val == Qundef) {
+ CALL_SIMPLE_METHOD();
}
}
DEFINE_INSN
opt_str_uminus
-(VALUE str)
+(VALUE str, CALL_DATA cd)
()
(VALUE val)
{
- if (BASIC_OP_UNREDEFINED_P(BOP_UMINUS, STRING_REDEFINED_OP_FLAG)) {
- val = str;
- }
- else {
- val = rb_funcall(rb_str_resurrect(str), idUMinus, 0);
+ val = vm_opt_str_freeze(str, BOP_UMINUS, idUMinus);
+
+ if (val == Qundef) {
+ PUSH(rb_str_resurrect(str));
+ CALL_SIMPLE_METHOD();
}
}
@@ -853,105 +840,88 @@ DEFINE_INSN
opt_newarray_max
(rb_num_t num)
(...)
-(VALUE val) // inc += 1 - num;
+(VALUE val)
+/* This instruction typically has no funcalls. But it compares array
+ * contents each other by nature. That part could call methods when
+ * necessary. No way to detect such method calls beforehand. We
+ * cannot but mark it being not leaf. */
+// attr bool leaf = false; /* has rb_funcall() */
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
{
val = vm_opt_newarray_max(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
DEFINE_INSN
opt_newarray_min
(rb_num_t num)
(...)
-(VALUE val) // inc += 1 - num;
+(VALUE val)
+/* Same discussion as opt_newarray_max. */
+// attr bool leaf = false; /* has rb_funcall() */
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
{
val = vm_opt_newarray_min(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
-/**
- @c optimize
- @e Invoke method without block
- @j ブロックãªã—ã§ãƒ¡ã‚½ãƒƒãƒ‰å‘¼ã³å‡ºã—を行ã†ã€‚
- */
-DEFINE_INSN
-opt_send_without_block
-(CALL_INFO ci, CALL_CACHE cc)
-(...)
-(VALUE val) // inc += -ci->orig_argc;
-{
- struct rb_calling_info calling;
- calling.block_handler = VM_BLOCK_HANDLER_NONE;
- vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
- CALL_METHOD(&calling, ci, cc);
-}
-
-/**
- @c method/iterator
- @e super(args) # args.size => num
- @j super を実行ã™ã‚‹ã€‚ci ã«å¿…è¦ãªæƒ…å ±ãŒæ ¼ç´ã•れã¦ã„る。
- */
+/* super(args) # args.size => num */
DEFINE_INSN
invokesuper
-(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
+(CALL_DATA cd, ISEQ blockiseq)
(...)
-(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
+(VALUE val)
+// attr rb_snum_t sp_inc = sp_inc_of_sendish(cd->ci);
+// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
{
- struct rb_calling_info calling;
- calling.argc = ci->orig_argc;
+ VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true);
+ val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super);
- vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, TRUE);
- calling.recv = GET_SELF();
- vm_search_super_method(th, GET_CFP(), &calling, ci, cc);
- CALL_METHOD(&calling, ci, cc);
+ if (val == Qundef) {
+ RESTORE_REGS();
+ NEXT_INSN();
+ }
}
-/**
- @c method/iterator
- @e yield(args)
- @j yield を実行ã™ã‚‹ã€‚
- */
+/* yield(args) */
DEFINE_INSN
invokeblock
-(CALL_INFO ci)
+(CALL_DATA cd)
(...)
-(VALUE val) // inc += 1 - ci->orig_argc;
+(VALUE val)
+// attr bool handles_sp = true;
+// attr rb_snum_t sp_inc = sp_inc_of_invokeblock(cd->ci);
+// attr rb_snum_t comptime_sp_inc = sp_inc_of_invokeblock(ci);
{
- struct rb_calling_info calling;
- calling.argc = ci->orig_argc;
- calling.block_handler = VM_BLOCK_HANDLER_NONE;
- calling.recv = GET_SELF();
+ VALUE bh = VM_BLOCK_HANDLER_NONE;
+ val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_invokeblock);
- val = vm_invoke_block(th, GET_CFP(), &calling, ci);
if (val == Qundef) {
- RESTORE_REGS();
- NEXT_INSN();
+ RESTORE_REGS();
+ NEXT_INSN();
}
}
-/**
- @c method/iterator
- @e return from this scope.
- @j ã“ã®ã‚¹ã‚³ãƒ¼ãƒ—ã‹ã‚‰æŠœã‘る。
- */
+/* return from this scope. */
DEFINE_INSN
leave
()
(VALUE val)
(VALUE val)
+/* This is super surprising but when leaving from a frame, we check
+ * for interrupts. If any, that should be executed on top of the
+ * current execution context. This is a method call. */
+// attr bool leaf = false; /* has rb_threadptr_execute_interrupts() */
+// attr bool handles_sp = true;
{
if (OPT_CHECKED_RUN) {
- const VALUE *const bp = vm_base_ptr(reg_cfp);
- if (reg_cfp->sp != bp) {
- vm_stack_consistency_error(th, reg_cfp, bp);
+ const VALUE *const bp = vm_base_ptr(GET_CFP());
+ if (GET_SP() != bp) {
+ vm_stack_consistency_error(ec, GET_CFP(), bp);
}
}
- RUBY_VM_CHECK_INTS(th);
-
- if (vm_pop_frame(th, GET_CFP(), GET_EP())) {
+ if (vm_pop_frame(ec, GET_CFP(), GET_EP())) {
#if OPT_CALL_THREADED_CODE
- th->retval = val;
+ rb_ec_thread_ptr(ec)->retval = val;
return 0;
#else
return val;
@@ -966,19 +936,16 @@ leave
/* deal with control flow 3: exception */
/**********************************************************/
-/**
- @c exception
- @e longjump
- @j 大域ジャンプを行ã†ã€‚
- */
+/* longjump */
DEFINE_INSN
throw
(rb_num_t throw_state)
(VALUE throwobj)
(VALUE val)
+/* Same discussion as leave. */
+// attr bool leaf = false; /* has rb_threadptr_execute_interrupts() */
{
- RUBY_VM_CHECK_INTS(th);
- val = vm_throw(th, GET_CFP(), throw_state, throwobj);
+ val = vm_throw(ec, GET_CFP(), throw_state, throwobj);
THROW_EXCEPTION(val);
/* unreachable */
}
@@ -987,149 +954,112 @@ throw
/* deal with control flow 4: local jump */
/**********************************************************/
-/**
- @c jump
- @e set PC to (PC + dst).
- @j PC ã‚’ (PC + dst) ã«ã™ã‚‹ã€‚
- */
+/* set PC to (PC + dst). */
DEFINE_INSN
jump
(OFFSET dst)
()
()
+/* Same discussion as leave. */
+// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */
{
- RUBY_VM_CHECK_INTS(th);
+ RUBY_VM_CHECK_INTS(ec);
JUMP(dst);
}
-/**
- @c jump
- @e if val is not false or nil, set PC to (PC + dst).
- @j ã‚‚ã— val ㌠false ã‹ nil ã§ãªã‘れã°ã€PC ã‚’ (PC + dst) ã«ã™ã‚‹ã€‚
- */
+/* if val is not false or nil, set PC to (PC + dst). */
DEFINE_INSN
branchif
(OFFSET dst)
(VALUE val)
()
+/* Same discussion as jump. */
+// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */
{
if (RTEST(val)) {
- RUBY_VM_CHECK_INTS(th);
+ RUBY_VM_CHECK_INTS(ec);
JUMP(dst);
}
}
-/**
- @c jump
- @e if val is false or nil, set PC to (PC + dst).
- @j ã‚‚ã— val ㌠false ã‹ nil ãªã‚‰ã°ã€PC ã‚’ (PC + dst) ã«ã™ã‚‹ã€‚
- */
+/* if val is false or nil, set PC to (PC + dst). */
DEFINE_INSN
branchunless
(OFFSET dst)
(VALUE val)
()
+/* Same discussion as jump. */
+// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */
{
if (!RTEST(val)) {
- RUBY_VM_CHECK_INTS(th);
+ RUBY_VM_CHECK_INTS(ec);
JUMP(dst);
}
}
-/**
- @c jump
- @e if val is nil, set PC to (PC + dst).
- @j ã‚‚ã— val ㌠nil ãªã‚‰ã°ã€PC ã‚’ (PC + dst) ã«ã™ã‚‹ã€‚
- */
+/* if val is nil, set PC to (PC + dst). */
DEFINE_INSN
branchnil
(OFFSET dst)
(VALUE val)
()
+/* Same discussion as jump. */
+// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */
{
if (NIL_P(val)) {
- RUBY_VM_CHECK_INTS(th);
- JUMP(dst);
- }
-}
-
-/**
- @c jump
- @e if val is type, set PC to (PC + dst).
- @j ã‚‚ã— val ㌠type ãªã‚‰ã°ã€PC ã‚’ (PC + dst) ã«ã™ã‚‹ã€‚
- */
-DEFINE_INSN
-branchiftype
-(rb_num_t type, OFFSET dst)
-(VALUE val)
-()
-{
- if (TYPE(val) == (int)type) {
- RUBY_VM_CHECK_INTS(th);
+ RUBY_VM_CHECK_INTS(ec);
JUMP(dst);
}
}
-
/**********************************************************/
/* for optimize */
/**********************************************************/
-/**
- @c optimize
- @e push inline-cached value and go to dst if it is valid
- @j ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒæœ‰åйãªã‚‰ã€å€¤ã‚’スタックã«ãƒ—ッシュã—㦠dst ã¸ã‚¸ãƒ£ãƒ³ãƒ—ã™ã‚‹ã€‚
- */
+/* push inline-cached value and go to dst if it is valid */
DEFINE_INSN
-getinlinecache
+opt_getinlinecache
(OFFSET dst, IC ic)
()
(VALUE val)
{
- val = vm_ic_hit_p(ic, GET_EP());
- if (val != Qnil) {
- JUMP(dst);
+ struct iseq_inline_constant_cache_entry *ice = ic->entry;
+ if (ice && vm_ic_hit_p(ice, GET_EP())) {
+ val = ice->value;
+ JUMP(dst);
+ }
+ else {
+ val = Qnil;
}
}
-/**
- @c optimize
- @e set inline cache
- @j インラインキャッシュã®å€¤ã‚’設定ã™ã‚‹ã€‚
- */
+/* set inline cache */
DEFINE_INSN
-setinlinecache
+opt_setinlinecache
(IC ic)
(VALUE val)
(VALUE val)
{
- vm_ic_update(ic, val, GET_EP());
+ vm_ic_update(GET_ISEQ(), ic, val, GET_EP());
}
-/**
- @c optimize
- @e run iseq only once
- @j once を実ç¾ã™ã‚‹ã€‚
- */
+/* run iseq only once */
DEFINE_INSN
once
-(ISEQ iseq, IC ic)
+(ISEQ iseq, ISE ise)
()
(VALUE val)
{
- val = vm_once_dispatch(iseq, ic, th);
+ val = vm_once_dispatch(ec, iseq, ise);
}
-/**
- @c optimize
- @e case dispatcher, jump by table if possible
- @j case æ–‡ã§ã€å¯èƒ½ãªã‚‰è¡¨å¼•ãã§ã‚¸ãƒ£ãƒ³ãƒ—ã™ã‚‹ã€‚
- */
+/* case dispatcher, jump by table if possible */
DEFINE_INSN
opt_case_dispatch
(CDHASH hash, OFFSET else_offset)
(..., VALUE key)
-() // inc += -1;
+()
+// attr rb_snum_t sp_inc = -1;
{
OFFSET dst = vm_case_dispatch(hash, else_offset, key);
@@ -1140,311 +1070,255 @@ opt_case_dispatch
/** simple functions */
-/**
- @c optimize
- @e optimized X+Y.
- @j 最é©åŒ–ã•れ㟠X+Y。
- */
+/* optimized X+Y. */
DEFINE_INSN
opt_plus
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_plus(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X-Y.
- @j 最é©åŒ–ã•れ㟠X-Y。
- */
+/* optimized X-Y. */
DEFINE_INSN
opt_minus
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_minus(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X*Y.
- @j 最é©åŒ–ã•れ㟠X*Y。
- */
+/* optimized X*Y. */
DEFINE_INSN
opt_mult
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_mult(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X/Y.
- @j 最é©åŒ–ã•れ㟠X/Y。
- */
+/* optimized X/Y. */
DEFINE_INSN
opt_div
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
+/* In case of division by zero, it raises. Thus
+ * ZeroDivisionError#initialize is called. */
+// attr bool leaf = false;
{
val = vm_opt_div(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X%Y.
- @j 最é©åŒ–ã•れ㟠X%Y。
- */
+/* optimized X%Y. */
DEFINE_INSN
opt_mod
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
+/* Same discussion as opt_mod. */
+// attr bool leaf = false;
{
val = vm_opt_mod(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X==Y.
- @j 最é©åŒ–ã•れ㟠X==Y。
- */
+/* optimized X==Y. */
DEFINE_INSN
opt_eq
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
- val = opt_eq_func(recv, obj, ci, cc);
+ val = opt_equality(GET_ISEQ(), recv, obj, cd);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X!=Y.
- @j 最é©åŒ–ã•れ㟠X!=Y。
- */
+/* optimized X!=Y. */
DEFINE_INSN
opt_neq
-(CALL_INFO ci, CALL_CACHE cc, CALL_INFO ci_eq, CALL_CACHE cc_eq)
+(CALL_DATA cd_eq, CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
- val = vm_opt_neq(ci, cc, ci_eq, cc_eq, recv, obj);
+ val = vm_opt_neq(GET_ISEQ(), cd, cd_eq, recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X<Y.
- @j 最é©åŒ–ã•れ㟠X<Y。
- */
+/* optimized X<Y. */
DEFINE_INSN
opt_lt
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_lt(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X<=Y.
- @j 最é©åŒ–ã•れ㟠X<=Y。
- */
+/* optimized X<=Y. */
DEFINE_INSN
opt_le
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_le(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X>Y.
- @j 最é©åŒ–ã•れ㟠X>Y。
- */
+/* optimized X>Y. */
DEFINE_INSN
opt_gt
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_gt(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized X>=Y.
- @j 最é©åŒ–ã•れ㟠X>=Y。
- */
+/* optimized X>=Y. */
DEFINE_INSN
opt_ge
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_ge(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e <<
- @j 最é©åŒ–ã•れ㟠X<<Y。
- */
+/* << */
DEFINE_INSN
opt_ltlt
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
+/* This instruction can append an integer, as a codepoint, into a
+ * string. Then what happens if that codepoint does not exist in the
+ * string's encoding? Of course an exception. That's not a leaf. */
+// attr bool leaf = false; /* has "invalid codepoint" exception */
{
val = vm_opt_ltlt(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e []
- @j 最é©åŒ–ã•れ㟠recv[obj]。
- */
+/* optimized X&Y. */
+DEFINE_INSN
+opt_and
+(CALL_DATA cd)
+(VALUE recv, VALUE obj)
+(VALUE val)
+{
+ val = vm_opt_and(recv, obj);
+
+ if (val == Qundef) {
+ CALL_SIMPLE_METHOD();
+ }
+}
+
+/* optimized X|Y. */
+DEFINE_INSN
+opt_or
+(CALL_DATA cd)
+(VALUE recv, VALUE obj)
+(VALUE val)
+{
+ val = vm_opt_or(recv, obj);
+
+ if (val == Qundef) {
+ CALL_SIMPLE_METHOD();
+ }
+}
+
+/* [] */
DEFINE_INSN
opt_aref
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
+/* This is complicated. In case of hash, vm_opt_aref() resorts to
+ * rb_hash_aref(). If `recv` has no `obj`, this function then yields
+ * default_proc. This is a method call. So opt_aref is
+ * (surprisingly) not leaf. */
+// attr bool leaf = false; /* has rb_funcall() */ /* calls #yield */
{
val = vm_opt_aref(recv, obj);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e recv[obj] = set
- @j 最é©åŒ–ã•れ㟠recv[obj] = set。
- */
+/* recv[obj] = set */
DEFINE_INSN
opt_aset
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv, VALUE obj, VALUE set)
(VALUE val)
+/* This is another story than opt_aref. When vm_opt_aset() resorts
+ * to rb_hash_aset(), which should call #hash for `obj`. */
+// attr bool leaf = false; /* has rb_funcall() */ /* calls #hash */
{
val = vm_opt_aset(recv, obj, set);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- PUSH(obj);
- PUSH(set);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e recv[str] = set
- @j 最é©åŒ–ã•れ㟠recv[str] = set。
- */
+/* recv[str] = set */
DEFINE_INSN
opt_aset_with
-(CALL_INFO ci, CALL_CACHE cc, VALUE key)
+(VALUE key, CALL_DATA cd)
(VALUE recv, VALUE val)
(VALUE val)
+/* Same discussion as opt_aset. */
+// attr bool leaf = false; /* has rb_funcall() */ /* calls #hash */
{
VALUE tmp = vm_opt_aset_with(recv, key, val);
@@ -1452,187 +1326,132 @@ opt_aset_with
val = tmp;
}
else {
- /* other */
- PUSH(recv);
- PUSH(rb_str_resurrect(key));
+#ifndef MJIT_HEADER
+ TOPN(0) = rb_str_resurrect(key);
PUSH(val);
- CALL_SIMPLE_METHOD(recv);
+#endif
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e recv[str]
- @j 最é©åŒ–ã•れ㟠recv[str]。
- */
+/* recv[str] */
DEFINE_INSN
opt_aref_with
-(CALL_INFO ci, CALL_CACHE cc, VALUE key)
+(VALUE key, CALL_DATA cd)
(VALUE recv)
(VALUE val)
+/* Same discussion as opt_aref. */
+// attr bool leaf = false; /* has rb_funcall() */ /* calls #yield */
{
val = vm_opt_aref_with(recv, key);
if (val == Qundef) {
- /* other */
- PUSH(recv);
+#ifndef MJIT_HEADER
PUSH(rb_str_resurrect(key));
- CALL_SIMPLE_METHOD(recv);
+#endif
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized length
- @j 最é©åŒ–ã•れ㟠recv.length()。
- */
+/* optimized length */
DEFINE_INSN
opt_length
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv)
(VALUE val)
{
val = vm_opt_length(recv, BOP_LENGTH);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized size
- @j 最é©åŒ–ã•れ㟠recv.size()。
- */
+/* optimized size */
DEFINE_INSN
opt_size
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv)
(VALUE val)
{
val = vm_opt_length(recv, BOP_SIZE);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized empty?
- @j 最é©åŒ–ã•れ㟠recv.empty?()。
- */
+/* optimized empty? */
DEFINE_INSN
opt_empty_p
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv)
(VALUE val)
{
val = vm_opt_empty_p(recv);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized succ
- @j 最é©åŒ–ã•れ㟠recv.succ()。
- */
+/* optimized succ */
DEFINE_INSN
opt_succ
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv)
(VALUE val)
{
val = vm_opt_succ(recv);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e optimized not
- @j 最é©åŒ–ã•れ㟠recv.!()。
- */
+/* optimized not */
DEFINE_INSN
opt_not
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE recv)
(VALUE val)
{
- val = vm_opt_not(ci, cc, recv);
+ val = vm_opt_not(GET_ISEQ(), cd, recv);
if (val == Qundef) {
- /* other */
- PUSH(recv);
- CALL_SIMPLE_METHOD(recv);
+ CALL_SIMPLE_METHOD();
}
}
-
-/**
- @c optimize
- @e optimized regexp match
- @j 最é©åŒ–ã•ã‚ŒãŸæ­£è¦è¡¨ç¾ãƒžãƒƒãƒã€‚
- */
-DEFINE_INSN
-opt_regexpmatch1
-(VALUE recv)
-(VALUE obj)
-(VALUE val)
-{
- val = vm_opt_regexpmatch1(recv, obj);
-}
-
-/**
- @c optimize
- @e optimized regexp match 2
- @j 最é©åŒ–ã•ã‚ŒãŸæ­£è¦è¡¨ç¾ãƒžãƒƒãƒ 2
- */
+/* optimized regexp match 2 */
DEFINE_INSN
opt_regexpmatch2
-(CALL_INFO ci, CALL_CACHE cc)
+(CALL_DATA cd)
(VALUE obj2, VALUE obj1)
(VALUE val)
+// attr bool leaf = false; /* match_at() has rb_thread_check_ints() */
{
val = vm_opt_regexpmatch2(obj2, obj1);
if (val == Qundef) {
- /* other */
- PUSH(obj2);
- PUSH(obj1);
- CALL_SIMPLE_METHOD(obj2);
+ CALL_SIMPLE_METHOD();
}
}
-/**
- @c optimize
- @e call native compiled method
- @j ãƒã‚¤ãƒ†ã‚£ãƒ–コンパイルã—ãŸãƒ¡ã‚½ãƒƒãƒ‰ã‚’起動。
- */
-DEFINE_INSN
+/* call native compiled method */
+DEFINE_INSN_IF(SUPPORT_CALL_C_FUNCTION)
opt_call_c_function
(rb_insn_func_t funcptr)
()
()
+// attr bool leaf = false; /* anything can happen inside */
+// attr bool handles_sp = true;
{
- reg_cfp = (funcptr)(th, reg_cfp);
+ reg_cfp = (funcptr)(ec, reg_cfp);
if (reg_cfp == 0) {
- VALUE err = th->ec.errinfo;
- th->ec.errinfo = Qnil;
+ VALUE err = ec->errinfo;
+ ec->errinfo = Qnil;
THROW_EXCEPTION(err);
}
@@ -1640,12 +1459,56 @@ opt_call_c_function
NEXT_INSN();
}
-/**
- @c joke
- @e BLT
- @j BLT
- */
+/* call specific function with args */
+DEFINE_INSN
+invokebuiltin
+(RB_BUILTIN bf)
+(...)
+(VALUE val)
+// attr bool leaf = false; /* anything can happen inside */
+// attr rb_snum_t sp_inc = 1 - bf->argc;
+{
+ val = vm_invoke_builtin(ec, reg_cfp, bf, STACK_ADDR_FROM_TOP(bf->argc));
+}
+
+/* call specific function with args (same parameters) */
+DEFINE_INSN
+opt_invokebuiltin_delegate
+(RB_BUILTIN bf, rb_num_t index)
+()
+(VALUE val)
+// attr bool leaf = false; /* anything can happen inside */
+{
+ val = vm_invoke_builtin_delegate(ec, reg_cfp, bf, (unsigned int)index);
+}
+
+/* call specific function with args (same parameters) and leave */
DEFINE_INSN
+opt_invokebuiltin_delegate_leave
+(RB_BUILTIN bf, rb_num_t index)
+()
+(VALUE val)
+// attr bool leaf = false; /* anything can happen inside */
+{
+ val = vm_invoke_builtin_delegate(ec, reg_cfp, bf, (unsigned int)index);
+
+ /* leave fastpath */
+ /* TracePoint/return fallbacks this insn to opt_invokebuiltin_delegate */
+ if (vm_pop_frame(ec, GET_CFP(), GET_EP())) {
+#if OPT_CALL_THREADED_CODE
+ rb_ec_thread_ptr(ec)->retval = val;
+ return 0;
+#else
+ return val;
+#endif
+ }
+ else {
+ RESTORE_REGS();
+ }
+}
+
+/* BLT */
+DEFINE_INSN_IF(SUPPORT_JOKE)
bitblt
()
()
@@ -1654,12 +1517,8 @@ bitblt
ret = rb_str_new2("a bit of bacon, lettuce and tomato");
}
-/**
- @c joke
- @e The Answer to Life, the Universe, and Everything
- @j 人生ã€å®‡å®™ã€ã™ã¹ã¦ã®ç­”ãˆã€‚
- */
-DEFINE_INSN
+/* The Answer to Life, the Universe, and Everything */
+DEFINE_INSN_IF(SUPPORT_JOKE)
answer
()
()
@@ -1667,4 +1526,3 @@ answer
{
ret = INT2FIX(42);
}
-
diff --git a/integer.rb b/integer.rb
new file mode 100644
index 0000000000..d18494f42f
--- /dev/null
+++ b/integer.rb
@@ -0,0 +1,150 @@
+class Integer
+ # call-seq:
+ # -int -> integer
+ #
+ # Returns +int+, negated.
+ def -@
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_uminus(self)'
+ end
+
+ # call-seq:
+ # ~int -> integer
+ #
+ # One's complement: returns a number where each bit is flipped.
+ #
+ # Inverts the bits in an Integer. As integers are conceptually of
+ # infinite length, the result acts as if it had an infinite number of
+ # one bits to the left. In hex representations, this is displayed
+ # as two periods to the left of the digits.
+ #
+ # sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
+ def ~
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_comp(self)'
+ end
+
+ def abs
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_abs(self)'
+ end
+
+ # call-seq:
+ # int.bit_length -> integer
+ #
+ # Returns the number of bits of the value of +int+.
+ #
+ # "Number of bits" means the bit position of the highest bit
+ # which is different from the sign bit
+ # (where the least significant bit has bit position 1).
+ # If there is no such bit (zero or minus one), zero is returned.
+ #
+ # I.e. this method returns <i>ceil(log2(int < 0 ? -int : int+1))</i>.
+ #
+ # (-2**1000-1).bit_length #=> 1001
+ # (-2**1000).bit_length #=> 1000
+ # (-2**1000+1).bit_length #=> 1000
+ # (-2**12-1).bit_length #=> 13
+ # (-2**12).bit_length #=> 12
+ # (-2**12+1).bit_length #=> 12
+ # -0x101.bit_length #=> 9
+ # -0x100.bit_length #=> 8
+ # -0xff.bit_length #=> 8
+ # -2.bit_length #=> 1
+ # -1.bit_length #=> 0
+ # 0.bit_length #=> 0
+ # 1.bit_length #=> 1
+ # 0xff.bit_length #=> 8
+ # 0x100.bit_length #=> 9
+ # (2**12-1).bit_length #=> 12
+ # (2**12).bit_length #=> 13
+ # (2**12+1).bit_length #=> 13
+ # (2**1000-1).bit_length #=> 1000
+ # (2**1000).bit_length #=> 1001
+ # (2**1000+1).bit_length #=> 1001
+ #
+ # This method can be used to detect overflow in Array#pack as follows:
+ #
+ # if n.bit_length < 32
+ # [n].pack("l") # no overflow
+ # else
+ # raise "overflow"
+ # end
+ def bit_length
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_bit_length(self)'
+ end
+
+ # call-seq:
+ # int.even? -> true or false
+ #
+ # Returns +true+ if +int+ is an even number.
+ def even?
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_even_p(self)'
+ end
+
+ # call-seq:
+ # int.integer? -> true
+ #
+ # Since +int+ is already an Integer, this always returns +true+.
+ def integer?
+ return true
+ end
+
+ def magnitude
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_abs(self)'
+ end
+
+ # call-seq:
+ # int.odd? -> true or false
+ #
+ # Returns +true+ if +int+ is an odd number.
+ def odd?
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_odd_p(self)'
+ end
+
+ # call-seq:
+ # int.ord -> self
+ #
+ # Returns the +int+ itself.
+ #
+ # 97.ord #=> 97
+ #
+ # This method is intended for compatibility to character literals
+ # in Ruby 1.9.
+ #
+ # For example, <code>?a.ord</code> returns 97 both in 1.8 and 1.9.
+ def ord
+ return self
+ end
+
+ # call-seq:
+ # int.to_i -> integer
+ #
+ # Since +int+ is already an Integer, returns +self+.
+ #
+ # #to_int is an alias for #to_i.
+ def to_i
+ return self
+ end
+
+ # call-seq:
+ # int.to_int -> integer
+ #
+ # Since +int+ is already an Integer, returns +self+.
+ def to_int
+ return self
+ end
+
+ # call-seq:
+ # int.zero? -> true or false
+ #
+ # Returns +true+ if +int+ has a zero value.
+ def zero?
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_zero_p(self)'
+ end
+end
diff --git a/internal.h b/internal.h
index 0b2e6366ee..c3b3a799b1 100644
--- a/internal.h
+++ b/internal.h
@@ -1,1957 +1,107 @@
-/**********************************************************************
-
- internal.h -
-
- $Author$
- created at: Tue May 17 11:42:20 JST 2011
-
- Copyright (C) 2011 Yukihiro Matsumoto
-
-**********************************************************************/
-
-#ifndef RUBY_INTERNAL_H
+#ifndef RUBY_INTERNAL_H /*-*-C-*-vi:se ft=c:*/
#define RUBY_INTERNAL_H 1
+/**
+ * @file
+ * @author $Author$
+ * @date Tue May 17 11:42:20 JST 2011
+ * @copyright Copyright (C) 2011 Yukihiro Matsumoto
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/internal/config.h"
-#include "ruby.h"
-#include "ruby/encoding.h"
-#include "ruby/io.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-#ifdef HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
-
-#ifndef __bool_true_false_are_defined
-# ifndef __cplusplus
-# undef bool
-# undef false
-# undef true
-# define bool signed char
-# define false 0
-# define true 1
-# define __bool_true_false_are_defined 1
-# endif
+#ifdef __cplusplus
+# error not for C++
#endif
#define LIKELY(x) RB_LIKELY(x)
#define UNLIKELY(x) RB_UNLIKELY(x)
-#ifndef MAYBE_UNUSED
-# define MAYBE_UNUSED(x) x
-#endif
-
-#ifndef WARN_UNUSED_RESULT
-# define WARN_UNUSED_RESULT(x) x
-#endif
-
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-# include <valgrind/memcheck.h>
-# ifndef VALGRIND_MAKE_MEM_DEFINED
-# define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
-# endif
-# ifndef VALGRIND_MAKE_MEM_UNDEFINED
-# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
-# endif
-#else
-# define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
-# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
-#endif
-
#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
+#define roomof(x, y) (((x) + (y) - 1) / (y))
+#define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
-#ifndef __has_feature
-# define __has_feature(x) 0
-#endif
-
-#ifndef __has_extension
-# define __has_extension __has_feature
-#endif
-
-#if GCC_VERSION_SINCE(4, 6, 0) || __has_extension(c_static_assert)
-# define STATIC_ASSERT(name, expr) _Static_assert(expr, #name ": " #expr)
-#else
-# define STATIC_ASSERT(name, expr) typedef int static_assert_##name##_check[1 - 2*!(expr)]
-#endif
-
-#define SIGNED_INTEGER_TYPE_P(int_type) (0 > ((int_type)0)-1)
-#define SIGNED_INTEGER_MAX(sint_type) \
- (sint_type) \
- ((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) | \
- ((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) - 1))
-#define SIGNED_INTEGER_MIN(sint_type) (-SIGNED_INTEGER_MAX(sint_type)-1)
-#define UNSIGNED_INTEGER_MAX(uint_type) (~(uint_type)0)
-
-#if SIGNEDNESS_OF_TIME_T < 0 /* signed */
-# define TIMET_MAX SIGNED_INTEGER_MAX(time_t)
-# define TIMET_MIN SIGNED_INTEGER_MIN(time_t)
-#elif SIGNEDNESS_OF_TIME_T > 0 /* unsigned */
-# define TIMET_MAX UNSIGNED_INTEGER_MAX(time_t)
-# define TIMET_MIN ((time_t)0)
-#endif
-#define TIMET_MAX_PLUS_ONE (2*(double)(TIMET_MAX/2+1))
-
-#ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P
-#define MUL_OVERFLOW_P(a, b) \
- __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0)
-#elif defined HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
-#define MUL_OVERFLOW_P(a, b) \
- ({__typeof__(a) c; __builtin_mul_overflow((a), (b), &c);})
-#endif
-
-#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
- (a) == 0 ? 0 : \
- (a) == -1 ? (b) < -(max) : \
- (a) > 0 ? \
- ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
- ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
-
-#ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P
-/* __builtin_mul_overflow_p can take bitfield */
-/* and GCC permits bitfields for integers other than int */
-#define MUL_OVERFLOW_FIXNUM_P(a, b) ({ \
- struct { long fixnum : SIZEOF_LONG * CHAR_BIT - 1; } c; \
- __builtin_mul_overflow_p((a), (b), c.fixnum); \
-})
-#else
-#define MUL_OVERFLOW_FIXNUM_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
-#endif
-
-#ifdef MUL_OVERFLOW_P
-#define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
-#define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
-#define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_P(a, b)
-#else
-#define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
-#define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
-#define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
-#endif
-
-#ifndef swap16
-# ifdef HAVE_BUILTIN___BUILTIN_BSWAP16
-# define swap16(x) __builtin_bswap16(x)
-# endif
-#endif
-
-#ifndef swap16
-# define swap16(x) ((uint16_t)((((x)&0xFF)<<8) | (((x)>>8)&0xFF)))
-#endif
-
-#ifndef swap32
-# ifdef HAVE_BUILTIN___BUILTIN_BSWAP32
-# define swap32(x) __builtin_bswap32(x)
-# endif
-#endif
-
-#ifndef swap32
-# define swap32(x) ((uint32_t)((((x)&0xFF)<<24) \
- |(((x)>>24)&0xFF) \
- |(((x)&0x0000FF00)<<8) \
- |(((x)&0x00FF0000)>>8) ))
-#endif
-
-#ifndef swap64
-# ifdef HAVE_BUILTIN___BUILTIN_BSWAP64
-# define swap64(x) __builtin_bswap64(x)
-# endif
-#endif
-
-#ifndef swap64
-# ifdef HAVE_INT64_T
-# define byte_in_64bit(n) ((uint64_t)0xff << (n))
-# define swap64(x) ((uint64_t)((((x)&byte_in_64bit(0))<<56) \
- |(((x)>>56)&0xFF) \
- |(((x)&byte_in_64bit(8))<<40) \
- |(((x)&byte_in_64bit(48))>>40) \
- |(((x)&byte_in_64bit(16))<<24) \
- |(((x)&byte_in_64bit(40))>>24) \
- |(((x)&byte_in_64bit(24))<<8) \
- |(((x)&byte_in_64bit(32))>>8)))
-# endif
-#endif
-
-static inline unsigned int
-nlz_int(unsigned int x)
-{
-#if defined(HAVE_BUILTIN___BUILTIN_CLZ)
- if (x == 0) return SIZEOF_INT * CHAR_BIT;
- return (unsigned int)__builtin_clz(x);
-#else
- unsigned int y;
-# if 64 < SIZEOF_INT * CHAR_BIT
- unsigned int n = 128;
-# elif 32 < SIZEOF_INT * CHAR_BIT
- unsigned int n = 64;
-# else
- unsigned int n = 32;
-# endif
-# if 64 < SIZEOF_INT * CHAR_BIT
- y = x >> 64; if (y) {n -= 64; x = y;}
-# endif
-# if 32 < SIZEOF_INT * CHAR_BIT
- y = x >> 32; if (y) {n -= 32; x = y;}
-# endif
- y = x >> 16; if (y) {n -= 16; x = y;}
- y = x >> 8; if (y) {n -= 8; x = y;}
- y = x >> 4; if (y) {n -= 4; x = y;}
- y = x >> 2; if (y) {n -= 2; x = y;}
- y = x >> 1; if (y) {return n - 2;}
- return (unsigned int)(n - x);
-#endif
-}
-
-static inline unsigned int
-nlz_long(unsigned long x)
-{
-#if defined(HAVE_BUILTIN___BUILTIN_CLZL)
- if (x == 0) return SIZEOF_LONG * CHAR_BIT;
- return (unsigned int)__builtin_clzl(x);
-#else
- unsigned long y;
-# if 64 < SIZEOF_LONG * CHAR_BIT
- unsigned int n = 128;
-# elif 32 < SIZEOF_LONG * CHAR_BIT
- unsigned int n = 64;
-# else
- unsigned int n = 32;
-# endif
-# if 64 < SIZEOF_LONG * CHAR_BIT
- y = x >> 64; if (y) {n -= 64; x = y;}
-# endif
-# if 32 < SIZEOF_LONG * CHAR_BIT
- y = x >> 32; if (y) {n -= 32; x = y;}
-# endif
- y = x >> 16; if (y) {n -= 16; x = y;}
- y = x >> 8; if (y) {n -= 8; x = y;}
- y = x >> 4; if (y) {n -= 4; x = y;}
- y = x >> 2; if (y) {n -= 2; x = y;}
- y = x >> 1; if (y) {return n - 2;}
- return (unsigned int)(n - x);
-#endif
-}
-
-#ifdef HAVE_LONG_LONG
-static inline unsigned int
-nlz_long_long(unsigned LONG_LONG x)
-{
-#if defined(HAVE_BUILTIN___BUILTIN_CLZLL)
- if (x == 0) return SIZEOF_LONG_LONG * CHAR_BIT;
- return (unsigned int)__builtin_clzll(x);
-#else
- unsigned LONG_LONG y;
-# if 64 < SIZEOF_LONG_LONG * CHAR_BIT
- unsigned int n = 128;
-# elif 32 < SIZEOF_LONG_LONG * CHAR_BIT
- unsigned int n = 64;
-# else
- unsigned int n = 32;
-# endif
-# if 64 < SIZEOF_LONG_LONG * CHAR_BIT
- y = x >> 64; if (y) {n -= 64; x = y;}
-# endif
-# if 32 < SIZEOF_LONG_LONG * CHAR_BIT
- y = x >> 32; if (y) {n -= 32; x = y;}
-# endif
- y = x >> 16; if (y) {n -= 16; x = y;}
- y = x >> 8; if (y) {n -= 8; x = y;}
- y = x >> 4; if (y) {n -= 4; x = y;}
- y = x >> 2; if (y) {n -= 2; x = y;}
- y = x >> 1; if (y) {return n - 2;}
- return (unsigned int)(n - x);
-#endif
-}
-#endif
-
-#ifdef HAVE_UINT128_T
-static inline unsigned int
-nlz_int128(uint128_t x)
-{
- uint128_t y;
- unsigned int n = 128;
- y = x >> 64; if (y) {n -= 64; x = y;}
- y = x >> 32; if (y) {n -= 32; x = y;}
- y = x >> 16; if (y) {n -= 16; x = y;}
- y = x >> 8; if (y) {n -= 8; x = y;}
- y = x >> 4; if (y) {n -= 4; x = y;}
- y = x >> 2; if (y) {n -= 2; x = y;}
- y = x >> 1; if (y) {return n - 2;}
- return (unsigned int)(n - x);
-}
-#endif
-
-static inline unsigned int
-nlz_intptr(uintptr_t x)
-{
-#if SIZEOF_VOIDP == 8
- return nlz_long_long(x);
-#elif SIZEOF_VOIDP == 4
- return nlz_int(x);
-#endif
-}
-
-static inline unsigned int
-rb_popcount32(uint32_t x)
-{
-#ifdef HAVE_BUILTIN___BUILTIN_POPCOUNT
- return (unsigned int)__builtin_popcount(x);
-#else
- x = (x & 0x55555555) + (x >> 1 & 0x55555555);
- x = (x & 0x33333333) + (x >> 2 & 0x33333333);
- x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
- x = (x & 0x001f001f) + (x >> 8 & 0x001f001f);
- return (x & 0x0000003f) + (x >>16 & 0x0000003f);
-#endif
-}
-
-static inline int
-rb_popcount64(uint64_t x)
-{
-#ifdef HAVE_BUILTIN___BUILTIN_POPCOUNT
- return __builtin_popcountll(x);
-#else
- x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
- x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
- x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707);
- x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f);
- x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f);
- return (x & 0x7f) + (x >>32 & 0x7f);
-#endif
-}
-
-static inline int
-rb_popcount_intptr(uintptr_t x)
-{
-#if SIZEOF_VOIDP == 8
- return rb_popcount64(x);
-#elif SIZEOF_VOIDP == 4
- return rb_popcount32(x);
-#endif
-}
-
-static inline int
-ntz_int32(uint32_t x)
-{
-#ifdef HAVE_BUILTIN___BUILTIN_CTZ
- return __builtin_ctz(x);
-#else
- return rb_popcount32((~x) & (x-1));
-#endif
-}
-
-static inline int
-ntz_int64(uint64_t x)
-{
-#ifdef HAVE_BUILTIN___BUILTIN_CTZLL
- return __builtin_ctzll(x);
-#else
- return rb_popcount64((~x) & (x-1));
-#endif
-}
-
-static inline int
-ntz_intptr(uintptr_t x)
-{
-#if SIZEOF_VOIDP == 8
- return ntz_int64(x);
-#elif SIZEOF_VOIDP == 4
- return ntz_int32(x);
-#endif
-}
-
-#if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
-# define DLONG LONG_LONG
-# define DL2NUM(x) LL2NUM(x)
-#elif defined(HAVE_INT128_T)
-# define DLONG int128_t
-# define DL2NUM(x) (RB_FIXABLE(x) ? LONG2FIX(x) : rb_int128t2big(x))
-VALUE rb_int128t2big(int128_t n);
-#endif
-
-static inline long
-rb_overflowed_fix_to_int(long x)
-{
- return (long)((unsigned long)(x >> 1) ^ (1LU << (SIZEOF_LONG * CHAR_BIT - 1)));
-}
-
-static inline VALUE
-rb_fix_plus_fix(VALUE x, VALUE y)
-{
-#ifdef HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW
- long lz;
- /* NOTE
- * (1) `LONG2FIX(FIX2LONG(x)+FIX2LONG(y))`
- + = `((lx*2+1)/2 + (ly*2+1)/2)*2+1`
- + = `lx*2 + ly*2 + 1`
- + = `(lx*2+1) + (ly*2+1) - 1`
- + = `x + y - 1`
- * (2) Fixnum's LSB is always 1.
- * It means you can always run `x - 1` without overflow.
- * (3) Of course `z = x + (y-1)` may overflow.
- * At that time true value is
- * * positive: 0b0 1xxx...1, and z = 0b1xxx...1
- * * nevative: 0b1 0xxx...1, and z = 0b0xxx...1
- * To convert this true value to long,
- * (a) Use arithmetic shift
- * * positive: 0b11xxx...
- * * negative: 0b00xxx...
- * (b) invert MSB
- * * positive: 0b01xxx...
- * * negative: 0b10xxx...
- */
- if (__builtin_add_overflow((long)x, (long)y-1, &lz)) {
- return rb_int2big(rb_overflowed_fix_to_int(lz));
- }
- else {
- return (VALUE)lz;
- }
-#else
- long lz = FIX2LONG(x) + FIX2LONG(y);
- return LONG2NUM(lz);
-#endif
-}
-
-static inline VALUE
-rb_fix_minus_fix(VALUE x, VALUE y)
-{
-#ifdef HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW
- long lz;
- if (__builtin_sub_overflow((long)x, (long)y-1, &lz)) {
- return rb_int2big(rb_overflowed_fix_to_int(lz));
- }
- else {
- return (VALUE)lz;
- }
-#else
- long lz = FIX2LONG(x) - FIX2LONG(y);
- return LONG2NUM(lz);
-#endif
-}
-
-/* arguments must be Fixnum */
-static inline VALUE
-rb_fix_mul_fix(VALUE x, VALUE y)
-{
- long lx = FIX2LONG(x);
- long ly = FIX2LONG(y);
-#ifdef DLONG
- return DL2NUM((DLONG)lx * (DLONG)ly);
-#else
- if (MUL_OVERFLOW_FIXNUM_P(lx, ly)) {
- return rb_big_mul(rb_int2big(lx), rb_int2big(ly));
- }
- else {
- return LONG2FIX(lx * ly);
- }
-#endif
-}
-
-/*
- * This behaves different from C99 for negative arguments.
- * Note that div may overflow fixnum.
- */
-static inline void
-rb_fix_divmod_fix(VALUE a, VALUE b, VALUE *divp, VALUE *modp)
-{
- /* assume / and % comply C99.
- * ldiv(3) won't be inlined by GCC and clang.
- * I expect / and % are compiled as single idiv.
- */
- long x = FIX2LONG(a);
- long y = FIX2LONG(b);
- long div, mod;
- if (x == FIXNUM_MIN && y == -1) {
- if (divp) *divp = LONG2NUM(-FIXNUM_MIN);
- if (modp) *modp = LONG2FIX(0);
- return;
- }
- div = x / y;
- mod = x % y;
- if (y > 0 ? mod < 0 : mod > 0) {
- mod += y;
- div -= 1;
- }
- if (divp) *divp = LONG2FIX(div);
- if (modp) *modp = LONG2FIX(mod);
-}
-
-/* div() for Ruby
- * This behaves different from C99 for negative arguments.
- */
-static inline VALUE
-rb_fix_div_fix(VALUE x, VALUE y)
-{
- VALUE div;
- rb_fix_divmod_fix(x, y, &div, NULL);
- return div;
-}
-
-/* mod() for Ruby
- * This behaves different from C99 for negative arguments.
- */
-static inline VALUE
-rb_fix_mod_fix(VALUE x, VALUE y)
-{
- VALUE mod;
- rb_fix_divmod_fix(x, y, NULL, &mod);
- return mod;
-}
-
-#if defined(HAVE_UINT128_T)
-# define bit_length(x) \
- (unsigned int) \
- (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int((unsigned int)(x)) : \
- sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long((unsigned long)(x)) : \
- sizeof(x) <= SIZEOF_LONG_LONG ? SIZEOF_LONG_LONG * CHAR_BIT - nlz_long_long((unsigned LONG_LONG)(x)) : \
- SIZEOF_INT128_T * CHAR_BIT - nlz_int128((uint128_t)(x)))
-#elif defined(HAVE_LONG_LONG)
-# define bit_length(x) \
- (unsigned int) \
- (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int((unsigned int)(x)) : \
- sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long((unsigned long)(x)) : \
- SIZEOF_LONG_LONG * CHAR_BIT - nlz_long_long((unsigned LONG_LONG)(x)))
-#else
-# define bit_length(x) \
- (unsigned int) \
- (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int((unsigned int)(x)) : \
- SIZEOF_LONG * CHAR_BIT - nlz_long((unsigned long)(x)))
-#endif
-
-#ifndef BDIGIT
-# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
-# define BDIGIT unsigned int
-# define SIZEOF_BDIGIT SIZEOF_INT
-# define BDIGIT_DBL unsigned LONG_LONG
-# define BDIGIT_DBL_SIGNED LONG_LONG
-# define PRI_BDIGIT_PREFIX ""
-# define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
-# elif SIZEOF_INT*2 <= SIZEOF_LONG
-# define BDIGIT unsigned int
-# define SIZEOF_BDIGIT SIZEOF_INT
-# define BDIGIT_DBL unsigned long
-# define BDIGIT_DBL_SIGNED long
-# define PRI_BDIGIT_PREFIX ""
-# define PRI_BDIGIT_DBL_PREFIX "l"
-# elif SIZEOF_SHORT*2 <= SIZEOF_LONG
-# define BDIGIT unsigned short
-# define SIZEOF_BDIGIT SIZEOF_SHORT
-# define BDIGIT_DBL unsigned long
-# define BDIGIT_DBL_SIGNED long
-# define PRI_BDIGIT_PREFIX "h"
-# define PRI_BDIGIT_DBL_PREFIX "l"
-# else
-# define BDIGIT unsigned short
-# define SIZEOF_BDIGIT (SIZEOF_LONG/2)
-# define SIZEOF_ACTUAL_BDIGIT SIZEOF_LONG
-# define BDIGIT_DBL unsigned long
-# define BDIGIT_DBL_SIGNED long
-# define PRI_BDIGIT_PREFIX "h"
-# define PRI_BDIGIT_DBL_PREFIX "l"
-# endif
-#endif
-#ifndef SIZEOF_ACTUAL_BDIGIT
-# define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT
-#endif
-
-#ifdef PRI_BDIGIT_PREFIX
-# define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
-# define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
-# define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
-# define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
-# define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
-# define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
-#endif
-
-#ifdef PRI_BDIGIT_DBL_PREFIX
-# define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
-# define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
-# define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
-# define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
-# define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
-# define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
-#endif
-
-#define BIGNUM_EMBED_LEN_NUMBITS 3
-#ifndef BIGNUM_EMBED_LEN_MAX
-# if (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT) < (1 << BIGNUM_EMBED_LEN_NUMBITS)-1
-# define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT)
-# else
-# define BIGNUM_EMBED_LEN_MAX ((1 << BIGNUM_EMBED_LEN_NUMBITS)-1)
-# endif
-#endif
-
-struct RBignum {
- struct RBasic basic;
- union {
- struct {
- size_t len;
- BDIGIT *digits;
- } heap;
- BDIGIT ary[BIGNUM_EMBED_LEN_MAX];
- } as;
-};
-#define BIGNUM_SIGN_BIT ((VALUE)FL_USER1)
-/* sign: positive:1, negative:0 */
-#define BIGNUM_SIGN(b) ((RBASIC(b)->flags & BIGNUM_SIGN_BIT) != 0)
-#define BIGNUM_SET_SIGN(b,sign) \
- ((sign) ? (RBASIC(b)->flags |= BIGNUM_SIGN_BIT) \
- : (RBASIC(b)->flags &= ~BIGNUM_SIGN_BIT))
-#define BIGNUM_POSITIVE_P(b) BIGNUM_SIGN(b)
-#define BIGNUM_NEGATIVE_P(b) (!BIGNUM_SIGN(b))
-#define BIGNUM_NEGATE(b) (RBASIC(b)->flags ^= BIGNUM_SIGN_BIT)
-
-#define BIGNUM_EMBED_FLAG ((VALUE)FL_USER2)
-#define BIGNUM_EMBED_LEN_MASK ((VALUE)(FL_USER5|FL_USER4|FL_USER3))
-#define BIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+BIGNUM_EMBED_LEN_NUMBITS)
-#define BIGNUM_LEN(b) \
- ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
- (size_t)((RBASIC(b)->flags >> BIGNUM_EMBED_LEN_SHIFT) & \
- (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT)) : \
- RBIGNUM(b)->as.heap.len)
-/* LSB:BIGNUM_DIGITS(b)[0], MSB:BIGNUM_DIGITS(b)[BIGNUM_LEN(b)-1] */
-#define BIGNUM_DIGITS(b) \
- ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
- RBIGNUM(b)->as.ary : \
- RBIGNUM(b)->as.heap.digits)
-#define BIGNUM_LENINT(b) rb_long2int(BIGNUM_LEN(b))
-
-#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
-
-struct RRational {
- struct RBasic basic;
- const VALUE num;
- const VALUE den;
-};
-
-#define RRATIONAL(obj) (R_CAST(RRational)(obj))
-#define RRATIONAL_SET_NUM(rat, n) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->num,(n))
-#define RRATIONAL_SET_DEN(rat, d) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->den,(d))
-
-struct RFloat {
- struct RBasic basic;
- double float_value;
-};
-
-#define RFLOAT(obj) (R_CAST(RFloat)(obj))
+/* Prevent compiler from reordering access */
+#define ACCESS_ONCE(type,x) (*((volatile type *)&(x)))
-struct RComplex {
- struct RBasic basic;
- const VALUE real;
- const VALUE imag;
-};
+#include "ruby/ruby.h"
-#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
+/* Following macros were formerly defined in this header but moved to somewhere
+ * else. In order to detect them we undef here. */
-#ifdef RCOMPLEX_SET_REAL /* shortcut macro for internal only */
-#undef RCOMPLEX_SET_REAL
-#undef RCOMPLEX_SET_IMAG
-#define RCOMPLEX_SET_REAL(cmp, r) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->real,(r))
-#define RCOMPLEX_SET_IMAG(cmp, i) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->imag,(i))
-#endif
+/* internal/array.h */
+#undef RARRAY_AREF
-struct RHash {
- struct RBasic basic;
- struct st_table *ntbl; /* possibly 0 */
- int iter_lev;
- const VALUE ifnone;
-};
+/* internal/class.h */
+#undef RClass
+#undef RCLASS_SUPER
-#define RHASH(obj) (R_CAST(RHash)(obj))
+/* internal/gc.h */
+#undef NEWOBJ_OF
+#undef RB_NEWOBJ_OF
+#undef RB_OBJ_WRITE
-#ifdef RHASH_ITER_LEV
-#undef RHASH_ITER_LEV
+/* internal/hash.h */
#undef RHASH_IFNONE
#undef RHASH_SIZE
-#define RHASH_ITER_LEV(h) (RHASH(h)->iter_lev)
-#define RHASH_IFNONE(h) (RHASH(h)->ifnone)
-#define RHASH_SIZE(h) (RHASH(h)->ntbl ? RHASH(h)->ntbl->num_entries : (st_index_t)0)
-#endif
-
-/* missing/setproctitle.c */
-#ifndef HAVE_SETPROCTITLE
-extern void ruby_init_setproctitle(int argc, char *argv[]);
-#endif
-
-#define RSTRUCT_EMBED_LEN_MAX RSTRUCT_EMBED_LEN_MAX
-#define RSTRUCT_EMBED_LEN_MASK RSTRUCT_EMBED_LEN_MASK
-#define RSTRUCT_EMBED_LEN_SHIFT RSTRUCT_EMBED_LEN_SHIFT
-enum {
- RSTRUCT_EMBED_LEN_MAX = 3,
- RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
- RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
+#undef RHASH_TBL
+#undef RHASH_EMPTY_P
- RSTRUCT_ENUM_END
-};
-
-struct RStruct {
- struct RBasic basic;
- union {
- struct {
- long len;
- const VALUE *ptr;
- } heap;
- const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
- } as;
-};
+/* internal/object.h */
+#undef ROBJECT_IV_INDEX_TBL
+/* internal/struct.h */
#undef RSTRUCT_LEN
#undef RSTRUCT_PTR
#undef RSTRUCT_SET
#undef RSTRUCT_GET
-#define RSTRUCT_EMBED_LEN(st) \
- (long)((RBASIC(st)->flags >> RSTRUCT_EMBED_LEN_SHIFT) & \
- (RSTRUCT_EMBED_LEN_MASK >> RSTRUCT_EMBED_LEN_SHIFT))
-#define RSTRUCT_LEN(st) rb_struct_len(st)
-#define RSTRUCT_LENINT(st) rb_long2int(RSTRUCT_LEN(st))
-#define RSTRUCT_CONST_PTR(st) rb_struct_const_ptr(st)
-#define RSTRUCT_PTR(st) ((VALUE *)RSTRUCT_CONST_PTR(RB_OBJ_WB_UNPROTECT_FOR(STRUCT, st)))
-#define RSTRUCT_SET(st, idx, v) RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[idx], (v))
-#define RSTRUCT_GET(st, idx) (RSTRUCT_CONST_PTR(st)[idx])
-#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
-
-static inline long
-rb_struct_len(VALUE st)
-{
- return (RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ?
- RSTRUCT_EMBED_LEN(st) : RSTRUCT(st)->as.heap.len;
-}
-
-static inline const VALUE *
-rb_struct_const_ptr(VALUE st)
-{
- return FIX_CONST_VALUE_PTR((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ?
- RSTRUCT(st)->as.ary : RSTRUCT(st)->as.heap.ptr);
-}
-
-/* class.c */
-
-struct rb_deprecated_classext_struct {
- char conflict[sizeof(VALUE) * 3];
-};
-struct rb_subclass_entry;
-typedef struct rb_subclass_entry rb_subclass_entry_t;
+/* Also, we keep the following macros here. They are expected to be
+ * overridden in each headers. */
-struct rb_subclass_entry {
- VALUE klass;
- rb_subclass_entry_t *next;
-};
+/* internal/array.h */
+#define rb_ary_new_from_args(...) rb_nonexistent_symbol(__VA_ARGS__)
-#if defined(HAVE_LONG_LONG)
-typedef unsigned LONG_LONG rb_serial_t;
-#define SERIALT2NUM ULL2NUM
-#elif defined(HAVE_UINT64_T)
-typedef uint64_t rb_serial_t;
-#define SERIALT2NUM SIZET2NUM
-#else
-typedef unsigned long rb_serial_t;
-#define SERIALT2NUM ULONG2NUM
-#endif
-
-struct rb_classext_struct {
- struct st_table *iv_index_tbl;
- struct st_table *iv_tbl;
- struct rb_id_table *const_tbl;
- struct rb_id_table *callable_m_tbl;
- rb_subclass_entry_t *subclasses;
- rb_subclass_entry_t **parent_subclasses;
- /**
- * In the case that this is an `ICLASS`, `module_subclasses` points to the link
- * in the module's `subclasses` list that indicates that the klass has been
- * included. Hopefully that makes sense.
- */
- rb_subclass_entry_t **module_subclasses;
- rb_serial_t class_serial;
- const VALUE origin_;
- VALUE refined_class;
- rb_alloc_func_t allocator;
-};
-
-typedef struct rb_classext_struct rb_classext_t;
-
-#undef RClass
-struct RClass {
- struct RBasic basic;
- VALUE super;
- rb_classext_t *ptr;
- struct rb_id_table *m_tbl;
-};
-
-void rb_class_subclass_add(VALUE super, VALUE klass);
-void rb_class_remove_from_super_subclasses(VALUE);
-int rb_singleton_class_internal_p(VALUE sklass);
-
-#define RCLASS_EXT(c) (RCLASS(c)->ptr)
-#define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
-#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
-#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
-#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
-#define RCLASS_IV_INDEX_TBL(c) (RCLASS_EXT(c)->iv_index_tbl)
-#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
-#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
-#define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial)
-
-#define RICLASS_IS_ORIGIN FL_USER5
-
-static inline void
-RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
-{
- RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin);
- if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN);
-}
-
-#undef RCLASS_SUPER
-static inline VALUE
-RCLASS_SUPER(VALUE klass)
-{
- return RCLASS(klass)->super;
-}
-
-static inline VALUE
-RCLASS_SET_SUPER(VALUE klass, VALUE super)
-{
- if (super) {
- rb_class_remove_from_super_subclasses(klass);
- rb_class_subclass_add(super, klass);
- }
- RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
- return super;
-}
-/* IMEMO: Internal memo object */
-
-#ifndef IMEMO_DEBUG
-#define IMEMO_DEBUG 0
-#endif
+/* internal/io.h */
+#define rb_io_fptr_finalize(...) rb_nonexistent_symbol(__VA_ARGS__)
-struct RIMemo {
- VALUE flags;
- VALUE v0;
- VALUE v1;
- VALUE v2;
- VALUE v3;
-};
+/* internal/string.h */
+#define rb_fstring_cstr(...) rb_nonexistent_symbol(__VA_ARGS__)
-enum imemo_type {
- imemo_env = 0,
- imemo_cref = 1,
- imemo_svar = 2,
- imemo_throw_data = 3,
- imemo_ifunc = 4,
- imemo_memo = 5,
- imemo_ment = 6,
- imemo_iseq = 7,
- imemo_mask = 0x07
-};
+/* internal/symbol.h */
+#define rb_sym_intern_ascii_cstr(...) rb_nonexistent_symbol(__VA_ARGS__)
-static inline enum imemo_type
-imemo_type(VALUE imemo)
-{
- return (RBASIC(imemo)->flags >> FL_USHIFT) & imemo_mask;
-}
+/* internal/vm.h */
+#define rb_funcallv(...) rb_nonexistent_symbol(__VA_ARGS__)
+#define rb_method_basic_definition_p(...) rb_nonexistent_symbol(__VA_ARGS__)
-static inline int
-imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
-{
- if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
- /* fixed at compile time if imemo_type is given. */
- const VALUE mask = (imemo_mask << FL_USHIFT) | RUBY_T_MASK;
- const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
- /* fixed at runtime. */
- return expected_type == (RBASIC(imemo)->flags & mask);
- }
- else {
- return 0;
- }
-}
-/* FL_USER0 to FL_USER2 is for type */
-#define IMEMO_FL_USHIFT (FL_USHIFT + 3)
-#define IMEMO_FL_USER0 FL_USER3
-#define IMEMO_FL_USER1 FL_USER4
-#define IMEMO_FL_USER2 FL_USER5
-#define IMEMO_FL_USER3 FL_USER6
-#define IMEMO_FL_USER4 FL_USER7
-
-/* CREF in method.h */
-
-/* SVAR */
-
-struct vm_svar {
- VALUE flags;
- const VALUE cref_or_me;
- const VALUE lastline;
- const VALUE backref;
- const VALUE others;
-};
-
-/* THROW_DATA */
-
-#define THROW_DATA_CONSUMED IMEMO_FL_USER0
-
-struct vm_throw_data {
- VALUE flags;
- VALUE reserved;
- const VALUE throw_obj;
- const struct rb_control_frame_struct *catch_frame;
- VALUE throw_state;
-};
-
-#define THROW_DATA_P(err) RB_TYPE_P((VALUE)(err), T_IMEMO)
-
-/* IFUNC */
-
-struct vm_ifunc_argc {
-#if SIZEOF_INT * 2 > SIZEOF_VALUE
- int min: (SIZEOF_VALUE * CHAR_BIT) / 2;
- int max: (SIZEOF_VALUE * CHAR_BIT) / 2;
-#else
- int min, max;
-#endif
-};
-
-struct vm_ifunc {
- VALUE flags;
- VALUE reserved;
- VALUE (*func)(ANYARGS);
- const void *data;
- struct vm_ifunc_argc argc;
-};
-
-#define IFUNC_NEW(a, b, c) ((struct vm_ifunc *)rb_imemo_new(imemo_ifunc, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
-struct vm_ifunc *rb_vm_ifunc_new(VALUE (*func)(ANYARGS), const void *data, int min_argc, int max_argc);
-static inline struct vm_ifunc *
-rb_vm_ifunc_proc_new(VALUE (*func)(ANYARGS), const void *data)
-{
- return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
-}
-
-/* MEMO */
-
-struct MEMO {
- VALUE flags;
- VALUE reserved;
- const VALUE v1;
- const VALUE v2;
- union {
- long cnt;
- long state;
- const VALUE value;
- VALUE (*func)(ANYARGS);
- } u3;
-};
-
-#define MEMO_V1_SET(m, v) RB_OBJ_WRITE((m), &(m)->v1, (v))
-#define MEMO_V2_SET(m, v) RB_OBJ_WRITE((m), &(m)->v2, (v))
-
-#define MEMO_CAST(m) ((struct MEMO *)m)
-
-#define MEMO_NEW(a, b, c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
-
-#define roomof(x, y) (((x) + (y) - 1) / (y))
-#define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
-#define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value))
-#define NEW_MEMO_FOR(type, value) \
- ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
-#define NEW_PARTIAL_MEMO_FOR(type, value, member) \
- ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), \
- rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \
- MEMO_FOR(type, value))
-
-#define STRING_P(s) (RB_TYPE_P((s), T_STRING) && CLASS_OF(s) == rb_cString)
-
-#ifdef RUBY_INTEGER_UNIFICATION
-# define rb_cFixnum rb_cInteger
-# define rb_cBignum rb_cInteger
-#endif
-
-enum {
- cmp_opt_Fixnum,
- cmp_opt_String,
- cmp_opt_Float,
- cmp_optimizable_count
-};
-
-struct cmp_opt_data {
- unsigned int opt_methods;
- unsigned int opt_inited;
-};
-
-#define NEW_CMP_OPT_MEMO(type, value) \
- NEW_PARTIAL_MEMO_FOR(type, value, cmp_opt)
-#define CMP_OPTIMIZABLE_BIT(type) (1U << TOKEN_PASTE(cmp_opt_,type))
-#define CMP_OPTIMIZABLE(data, type) \
- (((data).opt_inited & CMP_OPTIMIZABLE_BIT(type)) ? \
- ((data).opt_methods & CMP_OPTIMIZABLE_BIT(type)) : \
- (((data).opt_inited |= CMP_OPTIMIZABLE_BIT(type)), \
- rb_method_basic_definition_p(TOKEN_PASTE(rb_c,type), id_cmp) && \
- ((data).opt_methods |= CMP_OPTIMIZABLE_BIT(type))))
-
-#define OPTIMIZED_CMP(a, b, data) \
- ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data, Fixnum)) ? \
- (((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : \
- (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data, String)) ? \
- rb_str_cmp(a, b) : \
- (RB_FLOAT_TYPE_P(a) && RB_FLOAT_TYPE_P(b) && CMP_OPTIMIZABLE(data, Float)) ? \
- rb_float_cmp(a, b) : \
- rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b))
-
-/* ment is in method.h */
-
-/* global variable */
-
-struct rb_global_entry {
- struct rb_global_variable *var;
- ID id;
-};
-
-struct rb_global_entry *rb_global_entry(ID);
-VALUE rb_gvar_get(struct rb_global_entry *);
-VALUE rb_gvar_set(struct rb_global_entry *, VALUE);
-VALUE rb_gvar_defined(struct rb_global_entry *);
-
-struct vtm; /* defined by timev.h */
-
-/* array.c */
-VALUE rb_ary_last(int, const VALUE *, VALUE);
-void rb_ary_set_len(VALUE, long);
-void rb_ary_delete_same(VALUE, VALUE);
-VALUE rb_ary_tmp_new_fill(long capa);
-VALUE rb_ary_at(VALUE, VALUE);
-size_t rb_ary_memsize(VALUE);
-#ifdef __GNUC__
-#define rb_ary_new_from_args(n, ...) \
- __extension__ ({ \
- const VALUE args_to_new_ary[] = {__VA_ARGS__}; \
- if (__builtin_constant_p(n)) { \
- STATIC_ASSERT(rb_ary_new_from_args, numberof(args_to_new_ary) == (n)); \
- } \
- rb_ary_new_from_values(numberof(args_to_new_ary), args_to_new_ary); \
- })
-#endif
-
-/* bignum.c */
-extern const char ruby_digitmap[];
-double rb_big_fdiv_double(VALUE x, VALUE y);
-VALUE rb_big_uminus(VALUE x);
-VALUE rb_big_hash(VALUE);
-VALUE rb_big_odd_p(VALUE);
-VALUE rb_big_even_p(VALUE);
-size_t rb_big_size(VALUE);
-VALUE rb_integer_float_cmp(VALUE x, VALUE y);
-VALUE rb_integer_float_eq(VALUE x, VALUE y);
-VALUE rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base);
-VALUE rb_big_comp(VALUE x);
-VALUE rb_big_aref(VALUE x, VALUE y);
-VALUE rb_big_abs(VALUE x);
-VALUE rb_big_size_m(VALUE big);
-VALUE rb_big_bit_length(VALUE big);
-VALUE rb_big_remainder(VALUE x, VALUE y);
-VALUE rb_big_gt(VALUE x, VALUE y);
-VALUE rb_big_ge(VALUE x, VALUE y);
-VALUE rb_big_lt(VALUE x, VALUE y);
-VALUE rb_big_le(VALUE x, VALUE y);
-
-/* class.c */
-VALUE rb_class_boot(VALUE);
-VALUE rb_class_inherited(VALUE, VALUE);
-VALUE rb_make_metaclass(VALUE, VALUE);
-VALUE rb_include_class_new(VALUE, VALUE);
-void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
-void rb_class_detach_subclasses(VALUE);
-void rb_class_detach_module_subclasses(VALUE);
-void rb_class_remove_from_module_subclasses(VALUE);
-VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
-VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
-VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
-VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
-VALUE rb_special_singleton_class(VALUE);
-VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
-VALUE rb_singleton_class_get(VALUE obj);
-void Init_class_hierarchy(void);
-
-int rb_class_has_methods(VALUE c);
-void rb_undef_methods_from(VALUE klass, VALUE super);
-
-/* compar.c */
-VALUE rb_invcmp(VALUE, VALUE);
-
-/* compile.c */
-struct rb_block;
-int rb_dvar_defined(ID, const struct rb_block *);
-int rb_local_defined(ID, const struct rb_block *);
-CONSTFUNC(const char * rb_insns_name(int i));
-VALUE rb_insns_name_array(void);
-
-/* complex.c */
-VALUE rb_complex_plus(VALUE, VALUE);
-VALUE rb_complex_mul(VALUE, VALUE);
-VALUE rb_complex_abs(VALUE x);
-VALUE rb_complex_sqrt(VALUE x);
-
-/* cont.c */
-VALUE rb_obj_is_fiber(VALUE);
-void rb_fiber_reset_root_local_storage(VALUE);
-void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(ANYARGS), VALUE (*rollback_func)(ANYARGS));
-
-/* debug.c */
-PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2);
-
-/* dir.c */
-VALUE rb_dir_getwd_ospath(void);
-
-/* dmyext.c */
-void Init_enc(void);
-void Init_ext(void);
-
-/* encoding.c */
-ID rb_id_encoding(void);
-CONSTFUNC(void rb_gc_mark_encodings(void));
-rb_encoding *rb_enc_get_from_index(int index);
-rb_encoding *rb_enc_check_str(VALUE str1, VALUE str2);
-int rb_encdb_replicate(const char *alias, const char *orig);
-int rb_encdb_alias(const char *alias, const char *orig);
-int rb_encdb_dummy(const char *name);
-void rb_encdb_declare(const char *name);
-void rb_enc_set_base(const char *name, const char *orig);
-int rb_enc_set_dummy(int index);
-void rb_encdb_set_unicode(int index);
-PUREFUNC(int rb_data_is_encoding(VALUE obj));
-
-/* enum.c */
-VALUE rb_f_send(int argc, VALUE *argv, VALUE recv);
-VALUE rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary);
-
-/* error.c */
-extern VALUE rb_eEAGAIN;
-extern VALUE rb_eEWOULDBLOCK;
-extern VALUE rb_eEINPROGRESS;
-void rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args);
-VALUE rb_syntax_error_append(VALUE, VALUE, int, int, rb_encoding*, const char*, va_list);
-VALUE rb_check_backtrace(VALUE);
-NORETURN(void rb_async_bug_errno(const char *,int));
-const char *rb_builtin_type_name(int t);
-const char *rb_builtin_class_name(VALUE x);
-PRINTF_ARGS(void rb_sys_warn(const char *fmt, ...), 1, 2);
-PRINTF_ARGS(void rb_syserr_warn(int err, const char *fmt, ...), 2, 3);
-PRINTF_ARGS(void rb_enc_warn(rb_encoding *enc, const char *fmt, ...), 2, 3);
-PRINTF_ARGS(void rb_sys_enc_warn(rb_encoding *enc, const char *fmt, ...), 2, 3);
-PRINTF_ARGS(void rb_syserr_enc_warn(int err, rb_encoding *enc, const char *fmt, ...), 3, 4);
-PRINTF_ARGS(void rb_sys_warning(const char *fmt, ...), 1, 2);
-PRINTF_ARGS(void rb_syserr_warning(int err, const char *fmt, ...), 2, 3);
-PRINTF_ARGS(void rb_enc_warning(rb_encoding *enc, const char *fmt, ...), 2, 3);
-PRINTF_ARGS(void rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...), 2, 3);
-PRINTF_ARGS(void rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt, ...), 3, 4);
-
-#define rb_raise_cstr(etype, mesg) \
- rb_exc_raise(rb_exc_new_str(etype, rb_str_new_cstr(mesg)))
-#define rb_raise_static(etype, mesg) \
- rb_exc_raise(rb_exc_new_str(etype, rb_str_new_static(mesg, rb_strlen_lit(mesg))))
-
-VALUE rb_name_err_new(VALUE mesg, VALUE recv, VALUE method);
-#define rb_name_err_raise_str(mesg, recv, name) \
- rb_exc_raise(rb_name_err_new(mesg, recv, name))
-#define rb_name_err_raise(mesg, recv, name) \
- rb_name_err_raise_str(rb_fstring_cstr(mesg), (recv), (name))
-VALUE rb_key_err_new(VALUE mesg, VALUE recv, VALUE name);
-#define rb_key_err_raise(mesg, recv, name) \
- rb_exc_raise(rb_key_err_new(mesg, recv, name))
-NORETURN(void ruby_deprecated_internal_feature(const char *));
-#define DEPRECATED_INTERNAL_FEATURE(func) \
- (ruby_deprecated_internal_feature(func), UNREACHABLE)
-VALUE rb_warning_warn(VALUE mod, VALUE str);
-VALUE rb_warning_string(const char *fmt, ...);
-
-/* eval.c */
-VALUE rb_refinement_module_get_refined_class(VALUE module);
-
-/* eval_error.c */
-VALUE rb_get_backtrace(VALUE info);
-
-/* eval_jump.c */
-void rb_call_end_proc(VALUE data);
-void rb_mark_end_proc(void);
-
-/* file.c */
-VALUE rb_home_dir_of(VALUE user, VALUE result);
-VALUE rb_default_home_dir(VALUE result);
-VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict);
-VALUE rb_check_realpath(VALUE basedir, VALUE path);
-void rb_file_const(const char*, VALUE);
-int rb_file_load_ok(const char *);
-VALUE rb_file_expand_path_fast(VALUE, VALUE);
-VALUE rb_file_expand_path_internal(VALUE, VALUE, int, int, VALUE);
-VALUE rb_get_path_check_to_string(VALUE, int);
-VALUE rb_get_path_check_convert(VALUE, VALUE, int);
-VALUE rb_get_path_check(VALUE, int);
-void Init_File(void);
-int ruby_is_fd_loadable(int fd);
-
-#ifdef RUBY_FUNCTION_NAME_STRING
-# if defined __GNUC__ && __GNUC__ >= 4
-# pragma GCC visibility push(default)
-# endif
-NORETURN(void rb_sys_fail_path_in(const char *func_name, VALUE path));
-NORETURN(void rb_syserr_fail_path_in(const char *func_name, int err, VALUE path));
-# if defined __GNUC__ && __GNUC__ >= 4
-# pragma GCC visibility pop
-# endif
-# define rb_sys_fail_path(path) rb_sys_fail_path_in(RUBY_FUNCTION_NAME_STRING, path)
-# define rb_syserr_fail_path(err, path) rb_syserr_fail_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
-#else
-# define rb_sys_fail_path(path) rb_sys_fail_str(path)
-# define rb_syserr_fail_path(err, path) rb_syserr_fail_str((err), (path))
-#endif
+/* MRI debug support */
/* gc.c */
-extern VALUE *ruby_initial_gc_stress_ptr;
-extern int ruby_disable_gc;
-void Init_heap(void);
-void *ruby_mimmalloc(size_t size);
-void ruby_mimfree(void *ptr);
-void rb_objspace_set_event_hook(const rb_event_flag_t event);
-#if USE_RGENGC
-void rb_gc_writebarrier_remember(VALUE obj);
-#else
-#define rb_gc_writebarrier_remember(obj) 0
-#endif
-void ruby_gc_set_params(int safe_level);
-void rb_copy_wb_protected_attribute(VALUE dest, VALUE obj);
-
-#if defined(HAVE_MALLOC_USABLE_SIZE) || defined(HAVE_MALLOC_SIZE) || defined(_WIN32)
-#define ruby_sized_xrealloc(ptr, new_size, old_size) ruby_xrealloc(ptr, new_size)
-#define ruby_sized_xrealloc2(ptr, new_count, element_size, old_count) ruby_xrealloc(ptr, new_count, element_size)
-#define ruby_sized_xfree(ptr, size) ruby_xfree(ptr)
-#define SIZED_REALLOC_N(var,type,n,old_n) REALLOC_N(var, type, n)
-#else
-void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_ALLOC_SIZE((2));
-void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_ALLOC_SIZE((2, 3));
-void ruby_sized_xfree(void *x, size_t size);
-#define SIZED_REALLOC_N(var,type,n,old_n) ((var)=(type*)ruby_sized_xrealloc((char*)(var), (n) * sizeof(type), (old_n) * sizeof(type)))
-#endif
-
-/* optimized version of NEWOBJ() */
-#undef NEWOBJF_OF
-#undef RB_NEWOBJ_OF
-#define RB_NEWOBJ_OF(obj,type,klass,flags) \
- type *(obj) = (type*)(((flags) & FL_WB_PROTECTED) ? \
- rb_wb_protected_newobj_of(klass, (flags) & ~FL_WB_PROTECTED) : \
- rb_wb_unprotected_newobj_of(klass, flags))
-#define NEWOBJ_OF(obj,type,klass,flags) RB_NEWOBJ_OF(obj,type,klass,flags)
-
-/* hash.c */
-struct st_table *rb_hash_tbl_raw(VALUE hash);
-VALUE rb_hash_new_with_size(st_index_t size);
-VALUE rb_hash_has_key(VALUE hash, VALUE key);
-VALUE rb_hash_default_value(VALUE hash, VALUE key);
-VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
-long rb_objid_hash(st_index_t index);
-long rb_dbl_long_hash(double d);
-st_table *rb_init_identtable(void);
-st_table *rb_init_identtable_with_size(st_index_t size);
-VALUE rb_hash_compare_by_id_p(VALUE hash);
-
-#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h)
-VALUE rb_hash_keys(VALUE hash);
-VALUE rb_hash_values(VALUE hash);
-VALUE rb_hash_rehash(VALUE hash);
-int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
-#define HASH_PROC_DEFAULT FL_USER2
-
-/* inits.c */
-void rb_call_inits(void);
-
-/* io.c */
-const char *ruby_get_inplace_mode(void);
-void ruby_set_inplace_mode(const char *);
-ssize_t rb_io_bufread(VALUE io, void *buf, size_t size);
-void rb_stdio_set_default_encoding(void);
-VALUE rb_io_flush_raw(VALUE, int);
-size_t rb_io_memsize(const rb_io_t *);
-int rb_stderr_tty_p(void);
-
-/* load.c */
-VALUE rb_get_load_path(void);
-VALUE rb_get_expanded_load_path(void);
-int rb_require_internal(VALUE fname, int safe);
-NORETURN(void rb_load_fail(VALUE, const char*));
-
-/* loadpath.c */
-extern const char ruby_exec_prefix[];
-extern const char ruby_initial_load_paths[];
-
-/* localeinit.c */
-int Init_enc_set_filesystem_encoding(void);
-
-/* math.c */
-VALUE rb_math_atan2(VALUE, VALUE);
-VALUE rb_math_cos(VALUE);
-VALUE rb_math_cosh(VALUE);
-VALUE rb_math_exp(VALUE);
-VALUE rb_math_hypot(VALUE, VALUE);
-VALUE rb_math_log(int argc, const VALUE *argv);
-VALUE rb_math_sin(VALUE);
-VALUE rb_math_sinh(VALUE);
-VALUE rb_math_sqrt(VALUE);
-
-/* newline.c */
-void Init_newline(void);
-
-/* numeric.c */
-
-#define FIXNUM_POSITIVE_P(num) ((SIGNED_VALUE)(num) > (SIGNED_VALUE)INT2FIX(0))
-#define FIXNUM_NEGATIVE_P(num) ((SIGNED_VALUE)(num) < 0)
-#define FIXNUM_ZERO_P(num) ((num) == INT2FIX(0))
-
-#define INT_NEGATIVE_P(x) (FIXNUM_P(x) ? FIXNUM_NEGATIVE_P(x) : BIGNUM_NEGATIVE_P(x))
+void rb_obj_info_dump(VALUE obj);
+void rb_obj_info_dump_loc(VALUE obj, const char *file, int line, const char *func);
-#ifndef ROUND_DEFAULT
-# define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_UP
-#endif
-enum ruby_num_rounding_mode {
- RUBY_NUM_ROUND_HALF_UP,
- RUBY_NUM_ROUND_HALF_EVEN,
- RUBY_NUM_ROUND_HALF_DOWN,
- RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT
-};
-#define ROUND_TO(mode, even, up, down) \
- ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : \
- (mode) == RUBY_NUM_ROUND_HALF_UP ? up : down)
-#define ROUND_FUNC(mode, name) \
- ROUND_TO(mode, name##_half_even, name##_half_up, name##_half_down)
-#define ROUND_CALL(mode, name, args) \
- ROUND_TO(mode, name##_half_even args, \
- name##_half_up args, name##_half_down args)
-
-int rb_num_to_uint(VALUE val, unsigned int *ret);
-VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl);
-int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl);
-double ruby_float_mod(double x, double y);
-int rb_num_negative_p(VALUE);
-VALUE rb_int_succ(VALUE num);
-VALUE rb_int_pred(VALUE num);
-VALUE rb_int_uminus(VALUE num);
-VALUE rb_float_uminus(VALUE num);
-VALUE rb_int_plus(VALUE x, VALUE y);
-VALUE rb_int_minus(VALUE x, VALUE y);
-VALUE rb_int_mul(VALUE x, VALUE y);
-VALUE rb_int_idiv(VALUE x, VALUE y);
-VALUE rb_int_modulo(VALUE x, VALUE y);
-VALUE rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode);
-VALUE rb_int2str(VALUE num, int base);
-VALUE rb_dbl_hash(double d);
-VALUE rb_fix_plus(VALUE x, VALUE y);
-VALUE rb_int_gt(VALUE x, VALUE y);
-int rb_float_cmp(VALUE x, VALUE y);
-VALUE rb_float_gt(VALUE x, VALUE y);
-VALUE rb_int_ge(VALUE x, VALUE y);
-enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
-double rb_int_fdiv_double(VALUE x, VALUE y);
-VALUE rb_int_pow(VALUE x, VALUE y);
-VALUE rb_float_pow(VALUE x, VALUE y);
-VALUE rb_int_cmp(VALUE x, VALUE y);
-VALUE rb_int_equal(VALUE x, VALUE y);
-VALUE rb_int_divmod(VALUE x, VALUE y);
-VALUE rb_int_and(VALUE x, VALUE y);
-VALUE rb_int_lshift(VALUE x, VALUE y);
-VALUE rb_int_div(VALUE x, VALUE y);
-VALUE rb_int_abs(VALUE num);
-VALUE rb_float_abs(VALUE flt);
-VALUE rb_float_equal(VALUE x, VALUE y);
-VALUE rb_float_eql(VALUE x, VALUE y);
-
-#if USE_FLONUM
-#define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
-#define RUBY_BIT_ROTR(v, n) (((v) >> (n)) | ((v) << ((sizeof(v) * 8) - n)))
-#endif
-
-static inline double
-rb_float_flonum_value(VALUE v)
-{
-#if USE_FLONUM
- if (v != (VALUE)0x8000000000000002) { /* LIKELY */
- union {
- double d;
- VALUE v;
- } t;
-
- VALUE b63 = (v >> 63);
- /* e: xx1... -> 011... */
- /* xx0... -> 100... */
- /* ^b63 */
- t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~(VALUE)0x03), 3);
- return t.d;
- }
-#endif
- return 0.0;
-}
-
-static inline double
-rb_float_noflonum_value(VALUE v)
-{
- return ((struct RFloat *)v)->float_value;
-}
-
-static inline double
-rb_float_value_inline(VALUE v)
-{
- if (FLONUM_P(v)) {
- return rb_float_flonum_value(v);
- }
- return rb_float_noflonum_value(v);
-}
-
-static inline VALUE
-rb_float_new_inline(double d)
-{
-#if USE_FLONUM
- union {
- double d;
- VALUE v;
- } t;
- int bits;
-
- t.d = d;
- bits = (int)((VALUE)(t.v >> 60) & 0x7);
- /* bits contains 3 bits of b62..b60. */
- /* bits - 3 = */
- /* b011 -> b000 */
- /* b100 -> b001 */
-
- if (t.v != 0x3000000000000000 /* 1.72723e-77 */ &&
- !((bits-3) & ~0x01)) {
- return (RUBY_BIT_ROTL(t.v, 3) & ~(VALUE)0x01) | 0x02;
- }
- else if (t.v == (VALUE)0) {
- /* +0.0 */
- return 0x8000000000000002;
- }
- /* out of range */
-#endif
- return rb_float_new_in_heap(d);
-}
-
-#define rb_float_value(v) rb_float_value_inline(v)
-#define rb_float_new(d) rb_float_new_inline(d)
-
-/* object.c */
-void rb_obj_copy_ivar(VALUE dest, VALUE obj);
-CONSTFUNC(VALUE rb_obj_equal(VALUE obj1, VALUE obj2));
-CONSTFUNC(VALUE rb_obj_not(VALUE obj));
-VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
-NORETURN(void rb_undefined_alloc(VALUE klass));
-double rb_num_to_dbl(VALUE val);
-VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound);
-VALUE rb_immutable_obj_clone(int, VALUE *, VALUE);
-VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
-VALUE rb_convert_type_with_id(VALUE,int,const char*,ID);
-VALUE rb_check_convert_type_with_id(VALUE,int,const char*,ID);
-
-struct RBasicRaw {
- VALUE flags;
- VALUE klass;
-};
-
-#define RBASIC_CLEAR_CLASS(obj) memset(&(((struct RBasicRaw *)((VALUE)(obj)))->klass), 0, sizeof(VALUE))
-#define RBASIC_SET_CLASS_RAW(obj, cls) memcpy(&((struct RBasicRaw *)((VALUE)(obj)))->klass, &(cls), sizeof(VALUE))
-#define RBASIC_SET_CLASS(obj, cls) do { \
- VALUE _obj_ = (obj); \
- RB_OBJ_WRITE(_obj_, &((struct RBasicRaw *)(_obj_))->klass, cls); \
-} while (0)
-
-/* parse.y */
-#ifndef USE_SYMBOL_GC
-#define USE_SYMBOL_GC 1
-#endif
-VALUE rb_parser_get_yydebug(VALUE);
-VALUE rb_parser_set_yydebug(VALUE, VALUE);
-VALUE rb_parser_set_context(VALUE, const struct rb_block *, int);
-void *rb_parser_load_file(VALUE parser, VALUE name);
-int rb_is_const_name(VALUE name);
-int rb_is_class_name(VALUE name);
-int rb_is_global_name(VALUE name);
-int rb_is_instance_name(VALUE name);
-int rb_is_attrset_name(VALUE name);
-int rb_is_local_name(VALUE name);
-int rb_is_method_name(VALUE name);
-int rb_is_junk_name(VALUE name);
-PUREFUNC(int rb_is_const_sym(VALUE sym));
-PUREFUNC(int rb_is_class_sym(VALUE sym));
-PUREFUNC(int rb_is_global_sym(VALUE sym));
-PUREFUNC(int rb_is_instance_sym(VALUE sym));
-PUREFUNC(int rb_is_attrset_sym(VALUE sym));
-PUREFUNC(int rb_is_local_sym(VALUE sym));
-PUREFUNC(int rb_is_method_sym(VALUE sym));
-PUREFUNC(int rb_is_junk_sym(VALUE sym));
-ID rb_make_internal_id(void);
-void rb_gc_free_dsymbol(VALUE);
-ID rb_id_attrget(ID id);
-
-/* proc.c */
-VALUE rb_proc_location(VALUE self);
-st_index_t rb_hash_proc(st_index_t hash, VALUE proc);
-int rb_block_arity(void);
-int rb_block_min_max_arity(int *max);
-VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val);
-VALUE rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc);
-VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info);
-
-/* process.c */
-#define RB_MAX_GROUPS (65536)
-
-struct rb_execarg {
- union {
- struct {
- VALUE shell_script;
- } sh;
- struct {
- VALUE command_name;
- VALUE command_abspath; /* full path string or nil */
- VALUE argv_str;
- VALUE argv_buf;
- } cmd;
- } invoke;
- VALUE redirect_fds;
- VALUE envp_str;
- VALUE envp_buf;
- VALUE dup2_tmpbuf;
- unsigned use_shell : 1;
- unsigned pgroup_given : 1;
- unsigned umask_given : 1;
- unsigned unsetenv_others_given : 1;
- unsigned unsetenv_others_do : 1;
- unsigned close_others_given : 1;
- unsigned close_others_do : 1;
- unsigned chdir_given : 1;
- unsigned new_pgroup_given : 1;
- unsigned new_pgroup_flag : 1;
- unsigned uid_given : 1;
- unsigned gid_given : 1;
- rb_pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0<V). */
- VALUE rlimit_limits; /* Qfalse or [[rtype, softlim, hardlim], ...] */
- mode_t umask_mask;
- rb_uid_t uid;
- rb_gid_t gid;
- int close_others_maxhint;
- VALUE fd_dup2;
- VALUE fd_close;
- VALUE fd_open;
- VALUE fd_dup2_child;
- VALUE env_modification; /* Qfalse or [[k1,v1], ...] */
- VALUE path_env;
- VALUE chdir_dir;
-};
-
-/* argv_str contains extra two elements.
- * The beginning one is for /bin/sh used by exec_with_sh.
- * The last one for terminating NULL used by execve.
- * See rb_exec_fillarg() in process.c. */
-#define ARGVSTR2ARGC(argv_str) (RSTRING_LEN(argv_str) / sizeof(char *) - 2)
-#define ARGVSTR2ARGV(argv_str) ((char **)RSTRING_PTR(argv_str) + 1)
-
-rb_pid_t rb_fork_ruby(int *status);
-void rb_last_status_clear(void);
-
-/* rational.c */
-VALUE rb_rational_uminus(VALUE self);
-VALUE rb_rational_plus(VALUE self, VALUE other);
-VALUE rb_lcm(VALUE x, VALUE y);
-VALUE rb_rational_reciprocal(VALUE x);
-VALUE rb_cstr_to_rat(const char *, int);
-VALUE rb_rational_abs(VALUE self);
-VALUE rb_rational_cmp(VALUE self, VALUE other);
-VALUE rb_numeric_quo(VALUE x, VALUE y);
-
-/* re.c */
-VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
-VALUE rb_reg_check_preprocess(VALUE);
-long rb_reg_search0(VALUE, VALUE, long, int, int);
-VALUE rb_reg_match_p(VALUE re, VALUE str, long pos);
-void rb_backref_set_string(VALUE string, long pos, long len);
-int rb_match_count(VALUE match);
-int rb_match_nth_defined(int nth, VALUE match);
-
-/* signal.c */
-extern int ruby_enable_coredump;
-int rb_get_next_signal(void);
-int rb_sigaltstack_size(void);
-
-/* st.c */
-extern void rb_hash_bulk_insert(long, const VALUE *, VALUE);
-
-/* strftime.c */
-#ifdef RUBY_ENCODING_H
-VALUE rb_strftime_timespec(const char *format, size_t format_len, rb_encoding *enc,
- const struct vtm *vtm, struct timespec *ts, int gmt);
-VALUE rb_strftime(const char *format, size_t format_len, rb_encoding *enc,
- const struct vtm *vtm, VALUE timev, int gmt);
-#endif
-
-/* string.c */
-VALUE rb_fstring(VALUE);
-VALUE rb_fstring_new(const char *ptr, long len);
-#define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str))
-#define rb_fstring_literal(str) rb_fstring_lit(str)
-VALUE rb_fstring_cstr(const char *str);
-#ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
-# define rb_fstring_cstr(str) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_fstring_new((str), (long)strlen(str)) : \
- rb_fstring_cstr(str) \
-)
-#endif
-#ifdef RUBY_ENCODING_H
-VALUE rb_fstring_enc_new(const char *ptr, long len, rb_encoding *enc);
-#define rb_fstring_enc_lit(str, enc) rb_fstring_enc_new((str), rb_strlen_lit(str), (enc))
-#define rb_fstring_enc_literal(str, enc) rb_fstring_enc_lit(str, enc)
-VALUE rb_fstring_enc_cstr(const char *ptr, rb_encoding *enc);
-# ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
-# define rb_fstring_enc_cstr(str, enc) RB_GNUC_EXTENSION_BLOCK( \
- (__builtin_constant_p(str)) ? \
- rb_fstring_enc_new((str), (long)strlen(str), (enc)) : \
- rb_fstring_enc_cstr(str, enc) \
-)
-# endif
-#endif
-int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
-int rb_str_symname_p(VALUE);
-VALUE rb_str_quote_unprintable(VALUE);
-VALUE rb_id_quote_unprintable(ID);
-#define QUOTE(str) rb_str_quote_unprintable(str)
-#define QUOTE_ID(id) rb_id_quote_unprintable(id)
-char *rb_str_fill_terminator(VALUE str, const int termlen);
-void rb_str_change_terminator_length(VALUE str, const int oldtermlen, const int termlen);
-VALUE rb_str_locktmp_ensure(VALUE str, VALUE (*func)(VALUE), VALUE arg);
-VALUE rb_str_tmp_frozen_acquire(VALUE str);
-void rb_str_tmp_frozen_release(VALUE str, VALUE tmp);
-VALUE rb_str_chomp_string(VALUE str, VALUE chomp);
-#ifdef RUBY_ENCODING_H
-VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
-VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
- rb_encoding *from, int ecflags, VALUE ecopts);
-VALUE rb_enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl);
-VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc);
-#endif
-#define STR_NOEMBED FL_USER1
-#define STR_SHARED FL_USER2 /* = ELTS_SHARED */
-#define STR_EMBED_P(str) (!FL_TEST_RAW((str), STR_NOEMBED))
-#define STR_SHARED_P(s) FL_ALL_RAW((s), STR_NOEMBED|ELTS_SHARED)
-#define is_ascii_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT)
-#define is_broken_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN)
-size_t rb_str_memsize(VALUE);
-VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, VALUE passed_proc);
-VALUE rb_sym_to_proc(VALUE sym);
-char *rb_str_to_cstr(VALUE str);
-VALUE rb_str_eql(VALUE str1, VALUE str2);
-
-/* symbol.c */
-#ifdef RUBY_ENCODING_H
-VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc);
-VALUE rb_sym_intern_cstr(const char *ptr, rb_encoding *enc);
-#ifdef __GNUC__
-#define rb_sym_intern_cstr(ptr, enc) __extension__ ( \
-{ \
- (__builtin_constant_p(ptr)) ? \
- rb_sym_intern((ptr), (long)strlen(ptr), (enc)) : \
- rb_sym_intern_cstr((ptr), (enc)); \
-})
-#endif
-#endif
-VALUE rb_sym_intern_ascii(const char *ptr, long len);
-VALUE rb_sym_intern_ascii_cstr(const char *ptr);
-#ifdef __GNUC__
-#define rb_sym_intern_ascii_cstr(ptr) __extension__ ( \
-{ \
- (__builtin_constant_p(ptr)) ? \
- rb_sym_intern_ascii((ptr), (long)strlen(ptr)) : \
- rb_sym_intern_ascii_cstr(ptr); \
-})
-#endif
-
-/* struct.c */
-VALUE rb_struct_init_copy(VALUE copy, VALUE s);
-VALUE rb_struct_lookup(VALUE s, VALUE idx);
-
-/* time.c */
-struct timeval rb_time_timeval(VALUE);
-
-/* thread.c */
-#define COVERAGE_INDEX_LINES 0
-#define COVERAGE_INDEX_BRANCHES 1
-#define COVERAGE_INDEX_METHODS 2
-#define COVERAGE_TARGET_LINES 1
-#define COVERAGE_TARGET_BRANCHES 2
-#define COVERAGE_TARGET_METHODS 4
-
-VALUE rb_obj_is_mutex(VALUE obj);
-VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
-void rb_thread_execute_interrupts(VALUE th);
-void rb_clear_trace_func(void);
-VALUE rb_get_coverages(void);
-VALUE rb_default_coverage(int);
-VALUE rb_thread_shield_new(void);
-VALUE rb_thread_shield_wait(VALUE self);
-VALUE rb_thread_shield_release(VALUE self);
-VALUE rb_thread_shield_destroy(VALUE self);
-int rb_thread_to_be_killed(VALUE thread);
-void rb_mutex_allow_trap(VALUE self, int val);
-VALUE rb_uninterruptible(VALUE (*b_proc)(ANYARGS), VALUE data);
-VALUE rb_mutex_owned_p(VALUE self);
-
-/* thread_pthread.c, thread_win32.c */
-void Init_native_thread(void);
-int rb_divert_reserved_fd(int fd);
-
-/* transcode.c */
-extern VALUE rb_cEncodingConverter;
-size_t rb_econv_memsize(rb_econv_t *);
-
-/* us_ascii.c */
-extern rb_encoding OnigEncodingUS_ASCII;
-
-/* util.c */
-char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
-char *ruby_hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve);
-
-/* utf_8.c */
-extern rb_encoding OnigEncodingUTF_8;
-
-/* variable.c */
-void rb_gc_mark_global_tbl(void);
-size_t rb_generic_ivar_memsize(VALUE);
-VALUE rb_search_class_path(VALUE);
-VALUE rb_attr_delete(VALUE, ID);
-VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
-void rb_autoload_str(VALUE mod, ID id, VALUE file);
-void rb_deprecate_constant(VALUE mod, const char *name);
-
-/* version.c */
-extern const char ruby_engine[];
-
-/* vm_insnhelper.h */
-rb_serial_t rb_next_class_serial(void);
-
-/* vm.c */
-VALUE rb_obj_is_thread(VALUE obj);
-void rb_vm_mark(void *ptr);
-void Init_BareVM(void);
-void Init_vm_objects(void);
-PUREFUNC(VALUE rb_vm_top_self(void));
-void rb_thread_recycle_stack_release(VALUE *);
-void rb_vm_change_state(void);
-void rb_vm_inc_const_missing_count(void);
-const void **rb_vm_get_insns_address_table(void);
-VALUE rb_sourcefilename(void);
-VALUE rb_source_location(int *pline);
-const char *rb_source_loc(int *pline);
-void rb_vm_pop_cfunc_frame(void);
-int rb_vm_add_root_module(ID id, VALUE module);
-void rb_vm_check_redefinition_by_prepend(VALUE klass);
-VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
-VALUE ruby_vm_special_exception_copy(VALUE);
-PUREFUNC(st_table *rb_vm_fstring_table(void));
-
-
-/* vm_dump.c */
-void rb_print_backtrace(void);
-
-/* vm_eval.c */
-void Init_vm_eval(void);
-VALUE rb_current_realfilepath(void);
-VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE);
-typedef void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE);
-VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
- rb_check_funcall_hook *hook, VALUE arg);
-VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE);
-VALUE rb_yield_1(VALUE val);
-VALUE rb_yield_force_blockarg(VALUE values);
-VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
- rb_block_call_func_t bl_proc, int min_argc, int max_argc,
- VALUE data2);
-
-/* vm_insnhelper.c */
-VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
-VALUE rb_eql_opt(VALUE obj1, VALUE obj2);
-
-/* vm_method.c */
-void Init_eval_method(void);
-int rb_method_defined_by(VALUE obj, ID mid, VALUE (*cfunc)(ANYARGS));
-
-/* miniprelude.c, prelude.c */
-void Init_prelude(void);
-
-/* vm_backtrace.c */
-void Init_vm_backtrace(void);
-VALUE rb_vm_thread_backtrace(int argc, const VALUE *argv, VALUE thval);
-VALUE rb_vm_thread_backtrace_locations(int argc, const VALUE *argv, VALUE thval);
-
-VALUE rb_make_backtrace(void);
-void rb_backtrace_print_as_bugreport(void);
-int rb_backtrace_p(VALUE obj);
-VALUE rb_backtrace_to_str_ary(VALUE obj);
-VALUE rb_backtrace_to_location_ary(VALUE obj);
-void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output);
+/* debug.c */
RUBY_SYMBOL_EXPORT_BEGIN
-const char *rb_objspace_data_type_name(VALUE obj);
-
-/* Temporary. This API will be removed (renamed). */
-VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
-
-/* bignum.c (export) */
-VALUE rb_big_mul_normal(VALUE x, VALUE y);
-VALUE rb_big_mul_balance(VALUE x, VALUE y);
-VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
-VALUE rb_big_mul_toom3(VALUE x, VALUE y);
-VALUE rb_big_sq_fast(VALUE x);
-VALUE rb_big_divrem_normal(VALUE x, VALUE y);
-VALUE rb_big2str_poweroftwo(VALUE x, int base);
-VALUE rb_big2str_generic(VALUE x, int base);
-VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck);
-VALUE rb_str2big_normal(VALUE arg, int base, int badcheck);
-VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck);
-#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
-VALUE rb_big_mul_gmp(VALUE x, VALUE y);
-VALUE rb_big_divrem_gmp(VALUE x, VALUE y);
-VALUE rb_big2str_gmp(VALUE x, int base);
-VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
-#endif
-enum rb_int_parse_flags {
- RB_INT_PARSE_SIGN = 0x01,
- RB_INT_PARSE_UNDERSCORE = 0x02,
- RB_INT_PARSE_PREFIX = 0x04,
- RB_INT_PARSE_ALL = 0x07,
- RB_INT_PARSE_DEFAULT = 0x07
-};
-VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
-
-/* error.c (export) */
-int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
-NORETURN(void rb_unexpected_type(VALUE,int));
-#undef Check_Type
-#define Check_Type(v, t) \
- (!RB_TYPE_P((VALUE)(v), (t)) || \
- ((t) == RUBY_T_DATA && RTYPEDDATA_P(v)) ? \
- rb_unexpected_type((VALUE)(v), (t)) : (void)0)
-
-/* file.c (export) */
-#ifdef HAVE_READLINK
-VALUE rb_readlink(VALUE path, rb_encoding *enc);
-#endif
-#ifdef __APPLE__
-VALUE rb_str_normalize_ospath(const char *ptr, long len);
-#endif
-
-/* hash.c (export) */
-VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
-VALUE rb_ident_hash_new(void);
-
-/* io.c (export) */
-void rb_maygvl_fd_fix_cloexec(int fd);
-int rb_gc_for_fd(int err);
-void rb_write_error_str(VALUE mesg);
-
-/* numeric.c (export) */
-VALUE rb_int_positive_pow(long x, unsigned long y);
-
-/* process.c (export) */
-int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen);
-rb_pid_t rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen);
-VALUE rb_execarg_new(int argc, const VALUE *argv, int accept_shell);
-struct rb_execarg *rb_execarg_get(VALUE execarg_obj); /* dangerous. needs GC guard. */
-VALUE rb_execarg_init(int argc, const VALUE *argv, int accept_shell, VALUE execarg_obj);
-int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val);
-void rb_execarg_parent_start(VALUE execarg_obj);
-void rb_execarg_parent_end(VALUE execarg_obj);
-int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char* errmsg, size_t errmsg_buflen);
-VALUE rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash);
-void rb_execarg_setenv(VALUE execarg_obj, VALUE env);
-
-/* rational.c (export) */
-VALUE rb_gcd(VALUE x, VALUE y);
-VALUE rb_gcd_normal(VALUE self, VALUE other);
-#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
-VALUE rb_gcd_gmp(VALUE x, VALUE y);
-#endif
-
-/* string.c (export) */
-#ifdef RUBY_ENCODING_H
-/* internal use */
-VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc);
-#endif
-
-/* thread.c (export) */
-int ruby_thread_has_gvl_p(void); /* for ext/fiddle/closure.c */
-
-/* util.c (export) */
-extern const signed char ruby_digit36_to_number_table[];
-extern const char ruby_hexdigits[];
-extern unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
-
-/* variable.c (export) */
-void rb_mark_generic_ivar(VALUE);
-VALUE rb_const_missing(VALUE klass, VALUE name);
-int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
-st_table *rb_st_copy(VALUE obj, struct st_table *orig_tbl);
-
-/* gc.c (export) */
-VALUE rb_wb_protected_newobj_of(VALUE, VALUE);
-VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE);
-
-size_t rb_obj_memsize_of(VALUE);
-void rb_gc_verify_internal_consistency(void);
-
-#define RB_OBJ_GC_FLAGS_MAX 5
-size_t rb_obj_gc_flags(VALUE, ID[], size_t);
-void rb_gc_mark_values(long n, const VALUE *values);
-
-#if IMEMO_DEBUG
-VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, const char *file, int line);
-#define rb_imemo_new(type, v1, v2, v3, v0) rb_imemo_new_debug(type, v1, v2, v3, v0, __FILE__, __LINE__)
-#else
-VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
-#endif
-
+void ruby_debug_breakpoint(void);
+PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2);
RUBY_SYMBOL_EXPORT_END
-#define RUBY_DTRACE_CREATE_HOOK(name, arg) \
- RUBY_DTRACE_HOOK(name##_CREATE, arg)
-#define RUBY_DTRACE_HOOK(name, arg) \
-do { \
- if (UNLIKELY(RUBY_DTRACE_##name##_ENABLED())) { \
- int dtrace_line; \
- const char *dtrace_file = rb_source_loc(&dtrace_line); \
- if (!dtrace_file) dtrace_file = ""; \
- RUBY_DTRACE_##name(arg, dtrace_file, dtrace_line); \
- } \
-} while (0)
+// show obj data structure without any side-effect
+#define rp(obj) rb_obj_info_dump_loc((VALUE)(obj), __FILE__, __LINE__, RUBY_FUNCTION_NAME_STRING)
-#define RB_OBJ_BUILTIN_TYPE(obj) rb_obj_builtin_type(obj)
-#define OBJ_BUILTIN_TYPE(obj) RB_OBJ_BUILTIN_TYPE(obj)
-#ifdef __GNUC__
-#define rb_obj_builtin_type(obj) \
-__extension__({ \
- VALUE arg_obj = (obj); \
- RB_SPECIAL_CONST_P(arg_obj) ? -1 : \
- RB_BUILTIN_TYPE(arg_obj); \
- })
-#else
-static inline int
-rb_obj_builtin_type(VALUE obj)
-{
- return RB_SPECIAL_CONST_P(obj) ? -1 :
- RB_BUILTIN_TYPE(obj);
-}
-#endif
+// same as rp, but add message header
+#define rp_m(msg, obj) do { \
+ fprintf(stderr, "%s", (msg)); \
+ rb_obj_info_dump((VALUE)obj); \
+} while (0)
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+// `ruby_debug_breakpoint()` does nothing,
+// but breakpoint is set in run.gdb, so `make gdb` can stop here.
+#define bp() ruby_debug_breakpoint()
#endif /* RUBY_INTERNAL_H */
diff --git a/internal/array.h b/internal/array.h
new file mode 100644
index 0000000000..44c0efbbc1
--- /dev/null
+++ b/internal/array.h
@@ -0,0 +1,119 @@
+#ifndef INTERNAL_ARRAY_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_ARRAY_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Array.
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "internal/static_assert.h" /* for STATIC_ASSERT */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/ruby.h" /* for RARRAY_LEN */
+
+#ifndef ARRAY_DEBUG
+# define ARRAY_DEBUG (0+RUBY_DEBUG)
+#endif
+
+#define RARRAY_PTR_IN_USE_FLAG FL_USER14
+
+/* array.c */
+VALUE rb_ary_last(int, const VALUE *, VALUE);
+void rb_ary_set_len(VALUE, long);
+void rb_ary_delete_same(VALUE, VALUE);
+VALUE rb_ary_tmp_new_fill(long capa);
+VALUE rb_ary_at(VALUE, VALUE);
+size_t rb_ary_memsize(VALUE);
+VALUE rb_to_array_type(VALUE obj);
+void rb_ary_cancel_sharing(VALUE ary);
+
+static inline VALUE rb_ary_entry_internal(VALUE ary, long offset);
+static inline bool ARY_PTR_USING_P(VALUE ary);
+static inline void RARY_TRANSIENT_SET(VALUE ary);
+static inline void RARY_TRANSIENT_UNSET(VALUE ary);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* array.c (export) */
+void rb_ary_detransient(VALUE a);
+VALUE *rb_ary_ptr_use_start(VALUE ary);
+void rb_ary_ptr_use_end(VALUE ary);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
+VALUE rb_check_to_array(VALUE ary);
+VALUE rb_ary_behead(VALUE, long);
+VALUE rb_ary_aref1(VALUE ary, VALUE i);
+
+struct rb_execution_context_struct;
+VALUE rb_ec_ary_new_from_values(struct rb_execution_context_struct *ec, long n, const VALUE *elts);
+MJIT_SYMBOL_EXPORT_END
+
+static inline VALUE
+rb_ary_entry_internal(VALUE ary, long offset)
+{
+ long len = RARRAY_LEN(ary);
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
+ if (len == 0) return Qnil;
+ if (offset < 0) {
+ offset += len;
+ if (offset < 0) return Qnil;
+ }
+ else if (len <= offset) {
+ return Qnil;
+ }
+ return ptr[offset];
+}
+
+static inline bool
+ARY_PTR_USING_P(VALUE ary)
+{
+ return FL_TEST_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
+}
+
+static inline void
+RARY_TRANSIENT_SET(VALUE ary)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(ary, RARRAY_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+RARY_TRANSIENT_UNSET(VALUE ary)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(ary, RARRAY_TRANSIENT_FLAG);
+#endif
+}
+
+#undef rb_ary_new_from_args
+#if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
+# /* Skip it; clang -pedantic doesn't like the following */
+#elif defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO)
+#define rb_ary_new_from_args(n, ...) \
+ __extension__ ({ \
+ const VALUE args_to_new_ary[] = {__VA_ARGS__}; \
+ if (__builtin_constant_p(n)) { \
+ STATIC_ASSERT(rb_ary_new_from_args, numberof(args_to_new_ary) == (n)); \
+ } \
+ rb_ary_new_from_values(numberof(args_to_new_ary), args_to_new_ary); \
+ })
+#endif
+
+#undef RARRAY_AREF
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+static inline VALUE
+RARRAY_AREF(VALUE ary, long i)
+{
+ RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+
+ return RARRAY_CONST_PTR_TRANSIENT(ary)[i];
+}
+
+#endif /* INTERNAL_ARRAY_H */
diff --git a/internal/bignum.h b/internal/bignum.h
new file mode 100644
index 0000000000..95c1e6eacd
--- /dev/null
+++ b/internal/bignum.h
@@ -0,0 +1,246 @@
+#ifndef INTERNAL_BIGNUM_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_BIGNUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Bignums.
+ */
+#include "ruby/internal/config.h" /* for HAVE_LIBGMP */
+#include <stddef.h> /* for size_t */
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h> /* for ssize_t (note: on Windows ssize_t is */
+#endif /* `#define`d in ruby/config.h) */
+
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/ruby.h" /* for struct RBasic */
+
+#ifndef BDIGIT
+# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
+# define BDIGIT unsigned int
+# define SIZEOF_BDIGIT SIZEOF_INT
+# define BDIGIT_DBL unsigned LONG_LONG
+# define BDIGIT_DBL_SIGNED LONG_LONG
+# define PRI_BDIGIT_PREFIX ""
+# define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
+# elif SIZEOF_INT*2 <= SIZEOF_LONG
+# define BDIGIT unsigned int
+# define SIZEOF_BDIGIT SIZEOF_INT
+# define BDIGIT_DBL unsigned long
+# define BDIGIT_DBL_SIGNED long
+# define PRI_BDIGIT_PREFIX ""
+# define PRI_BDIGIT_DBL_PREFIX "l"
+# elif SIZEOF_SHORT*2 <= SIZEOF_LONG
+# define BDIGIT unsigned short
+# define SIZEOF_BDIGIT SIZEOF_SHORT
+# define BDIGIT_DBL unsigned long
+# define BDIGIT_DBL_SIGNED long
+# define PRI_BDIGIT_PREFIX "h"
+# define PRI_BDIGIT_DBL_PREFIX "l"
+# else
+# define BDIGIT unsigned short
+# define SIZEOF_BDIGIT (SIZEOF_LONG/2)
+# define SIZEOF_ACTUAL_BDIGIT SIZEOF_LONG
+# define BDIGIT_DBL unsigned long
+# define BDIGIT_DBL_SIGNED long
+# define PRI_BDIGIT_PREFIX "h"
+# define PRI_BDIGIT_DBL_PREFIX "l"
+# endif
+#endif
+
+#ifndef SIZEOF_ACTUAL_BDIGIT
+# define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT
+#endif
+
+#ifdef PRI_BDIGIT_PREFIX
+# define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
+# define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
+# define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
+# define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
+# define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
+# define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
+#endif
+
+#ifdef PRI_BDIGIT_DBL_PREFIX
+# define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
+# define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
+# define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
+# define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
+# define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
+# define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
+#endif
+
+#define RBIGNUM(obj) ((struct RBignum *)(obj))
+#define BIGNUM_SIGN_BIT FL_USER1
+#define BIGNUM_EMBED_FLAG ((VALUE)FL_USER2)
+#define BIGNUM_EMBED_LEN_NUMBITS 3
+#define BIGNUM_EMBED_LEN_MASK \
+ (~(~(VALUE)0U << BIGNUM_EMBED_LEN_NUMBITS) << BIGNUM_EMBED_LEN_SHIFT)
+#define BIGNUM_EMBED_LEN_SHIFT \
+ (FL_USHIFT+3) /* bit offset of BIGNUM_EMBED_LEN_MASK */
+#ifndef BIGNUM_EMBED_LEN_MAX
+# if (SIZEOF_VALUE*RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT) < (1 << BIGNUM_EMBED_LEN_NUMBITS)-1
+# define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT)
+# else
+# define BIGNUM_EMBED_LEN_MAX ((1 << BIGNUM_EMBED_LEN_NUMBITS)-1)
+# endif
+#endif
+
+enum rb_int_parse_flags {
+ RB_INT_PARSE_SIGN = 0x01,
+ RB_INT_PARSE_UNDERSCORE = 0x02,
+ RB_INT_PARSE_PREFIX = 0x04,
+ RB_INT_PARSE_ALL = 0x07,
+ RB_INT_PARSE_DEFAULT = 0x07,
+};
+
+struct RBignum {
+ struct RBasic basic;
+ union {
+ struct {
+ size_t len;
+ BDIGIT *digits;
+ } heap;
+ BDIGIT ary[BIGNUM_EMBED_LEN_MAX];
+ } as;
+};
+
+/* bignum.c */
+extern const char ruby_digitmap[];
+double rb_big_fdiv_double(VALUE x, VALUE y);
+VALUE rb_big_uminus(VALUE x);
+VALUE rb_big_hash(VALUE);
+VALUE rb_big_odd_p(VALUE);
+VALUE rb_big_even_p(VALUE);
+size_t rb_big_size(VALUE);
+VALUE rb_integer_float_cmp(VALUE x, VALUE y);
+VALUE rb_integer_float_eq(VALUE x, VALUE y);
+VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception);
+VALUE rb_big_comp(VALUE x);
+VALUE rb_big_aref(VALUE x, VALUE y);
+VALUE rb_big_abs(VALUE x);
+VALUE rb_big_size_m(VALUE big);
+VALUE rb_big_bit_length(VALUE big);
+VALUE rb_big_remainder(VALUE x, VALUE y);
+VALUE rb_big_gt(VALUE x, VALUE y);
+VALUE rb_big_ge(VALUE x, VALUE y);
+VALUE rb_big_lt(VALUE x, VALUE y);
+VALUE rb_big_le(VALUE x, VALUE y);
+VALUE rb_int_powm(int const argc, VALUE * const argv, VALUE const num);
+static inline bool BIGNUM_SIGN(VALUE b);
+static inline bool BIGNUM_POSITIVE_P(VALUE b);
+static inline bool BIGNUM_NEGATIVE_P(VALUE b);
+static inline void BIGNUM_SET_SIGN(VALUE b, bool sign);
+static inline void BIGNUM_NEGATE(VALUE b);
+static inline size_t BIGNUM_LEN(VALUE b);
+static inline BDIGIT *BIGNUM_DIGITS(VALUE b);
+static inline int BIGNUM_LENINT(VALUE b);
+static inline bool BIGNUM_EMBED_P(VALUE b);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* bignum.c (export) */
+VALUE rb_big_mul_normal(VALUE x, VALUE y);
+VALUE rb_big_mul_balance(VALUE x, VALUE y);
+VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
+VALUE rb_big_mul_toom3(VALUE x, VALUE y);
+VALUE rb_big_sq_fast(VALUE x);
+VALUE rb_big_divrem_normal(VALUE x, VALUE y);
+VALUE rb_big2str_poweroftwo(VALUE x, int base);
+VALUE rb_big2str_generic(VALUE x, int base);
+VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck);
+VALUE rb_str2big_normal(VALUE arg, int base, int badcheck);
+VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck);
+#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
+VALUE rb_big_mul_gmp(VALUE x, VALUE y);
+VALUE rb_big_divrem_gmp(VALUE x, VALUE y);
+VALUE rb_big2str_gmp(VALUE x, int base);
+VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
+#endif
+VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+#if defined(HAVE_INT128_T)
+VALUE rb_int128t2big(int128_t n);
+#endif
+MJIT_SYMBOL_EXPORT_END
+
+/* sign: positive:1, negative:0 */
+static inline bool
+BIGNUM_SIGN(VALUE b)
+{
+ return FL_TEST_RAW(b, BIGNUM_SIGN_BIT);
+}
+
+static inline bool
+BIGNUM_POSITIVE_P(VALUE b)
+{
+ return BIGNUM_SIGN(b);
+}
+
+static inline bool
+BIGNUM_NEGATIVE_P(VALUE b)
+{
+ return ! BIGNUM_POSITIVE_P(b);
+}
+
+static inline void
+BIGNUM_SET_SIGN(VALUE b, bool sign)
+{
+ if (sign) {
+ FL_SET_RAW(b, BIGNUM_SIGN_BIT);
+ }
+ else {
+ FL_UNSET_RAW(b, BIGNUM_SIGN_BIT);
+ }
+}
+
+static inline void
+BIGNUM_NEGATE(VALUE b)
+{
+ FL_REVERSE_RAW(b, BIGNUM_SIGN_BIT);
+}
+
+static inline size_t
+BIGNUM_LEN(VALUE b)
+{
+ if (! BIGNUM_EMBED_P(b)) {
+ return RBIGNUM(b)->as.heap.len;
+ }
+ else {
+ size_t ret = RBASIC(b)->flags;
+ ret &= BIGNUM_EMBED_LEN_MASK;
+ ret >>= BIGNUM_EMBED_LEN_SHIFT;
+ return ret;
+ }
+}
+
+static inline int
+BIGNUM_LENINT(VALUE b)
+{
+ return rb_long2int(BIGNUM_LEN(b));
+}
+
+/* LSB:BIGNUM_DIGITS(b)[0], MSB:BIGNUM_DIGITS(b)[BIGNUM_LEN(b)-1] */
+static inline BDIGIT *
+BIGNUM_DIGITS(VALUE b)
+{
+ if (BIGNUM_EMBED_P(b)) {
+ return RBIGNUM(b)->as.ary;
+ }
+ else {
+ return RBIGNUM(b)->as.heap.digits;
+ }
+}
+
+static inline bool
+BIGNUM_EMBED_P(VALUE b)
+{
+ return FL_TEST_RAW(b, BIGNUM_EMBED_FLAG);
+}
+
+#endif /* INTERNAL_BIGNUM_H */
diff --git a/internal/bits.h b/internal/bits.h
new file mode 100644
index 0000000000..746947bfc2
--- /dev/null
+++ b/internal/bits.h
@@ -0,0 +1,566 @@
+#ifndef INTERNAL_BITS_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_BITS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for bitwise integer algorithms.
+ * @see Henry S. Warren Jr., "Hacker's Delight" (2nd ed.), 2013.
+ * @see SEI CERT C Coding Standard INT32-C. "Ensure that operations on
+ * signed integers do not result in overflow"
+ * @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
+ * @see https://clang.llvm.org/docs/LanguageExtensions.html#builtin-rotateleft
+ * @see https://clang.llvm.org/docs/LanguageExtensions.html#builtin-rotateright
+ * @see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/byteswap-uint64-byteswap-ulong-byteswap-ushort
+ * @see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rotl-rotl64-rotr-rotr64
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/lzcnt16-lzcnt-lzcnt64
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_lzcnt_u32
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_tzcnt_u32
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_rotl64
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_rotr64
+ * @see https://stackoverflow.com/a/776523
+ */
+#include "ruby/internal/config.h"
+#include <limits.h> /* for CHAR_BITS */
+#include <stdint.h> /* for uintptr_t */
+#include "internal/compilers.h" /* for MSC_VERSION_SINCE */
+
+#if MSC_VERSION_SINCE(1310)
+# include <stdlib.h> /* for _byteswap_uint64 */
+#endif
+
+#if defined(HAVE_X86INTRIN_H) && ! defined(MJIT_HEADER)
+# /* Rule out MJIT_HEADER, which does not interface well with <immintrin.h> */
+# include <x86intrin.h> /* for _lzcnt_u64 */
+#elif MSC_VERSION_SINCE(1310)
+# include <intrin.h> /* for the following intrinsics */
+#endif
+
+#if defined(_MSC_VER) && defined(__AVX__)
+# pragma intrinsic(__popcnt)
+# pragma intrinsic(__popcnt64)
+#endif
+
+#if defined(_MSC_VER) && defined(__AVX2__)
+# pragma intrinsic(__lzcnt)
+# pragma intrinsic(__lzcnt64)
+#endif
+
+#if MSC_VERSION_SINCE(1310)
+# pragma intrinsic(_rotl)
+# pragma intrinsic(_rotr)
+# ifdef _WIN64
+# pragma intrinsic(_rotl64)
+# pragma intrinsic(_rotr64)
+# endif
+#endif
+
+#if MSC_VERSION_SINCE(1400)
+# pragma intrinsic(_BitScanForward)
+# pragma intrinsic(_BitScanReverse)
+# ifdef _WIN64
+# pragma intrinsic(_BitScanForward64)
+# pragma intrinsic(_BitScanReverse64)
+# endif
+#endif
+
+#include "ruby/ruby.h" /* for VALUE */
+#include "internal/static_assert.h" /* for STATIC_ASSERT */
+
+/* The most significant bit of the lower part of half-long integer.
+ * If sizeof(long) == 4, this is 0x8000.
+ * If sizeof(long) == 8, this is 0x80000000.
+ */
+#define HALF_LONG_MSB ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
+
+#define SIGNED_INTEGER_TYPE_P(T) (0 > ((T)0)-1)
+
+#define SIGNED_INTEGER_MIN(T) \
+ ((sizeof(T) == sizeof(int8_t)) ? ((T)INT8_MIN) : \
+ ((sizeof(T) == sizeof(int16_t)) ? ((T)INT16_MIN) : \
+ ((sizeof(T) == sizeof(int32_t)) ? ((T)INT32_MIN) : \
+ ((sizeof(T) == sizeof(int64_t)) ? ((T)INT64_MIN) : \
+ 0))))
+
+#define SIGNED_INTEGER_MAX(T) ((T)(SIGNED_INTEGER_MIN(T) ^ ((T)~(T)0)))
+
+#define UNSIGNED_INTEGER_MAX(T) ((T)~(T)0)
+
+#if __has_builtin(__builtin_mul_overflow_p)
+# define MUL_OVERFLOW_P(a, b) \
+ __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0)
+#elif __has_builtin(__builtin_mul_overflow)
+# define MUL_OVERFLOW_P(a, b) \
+ __extension__ ({ __typeof__(a) c; __builtin_mul_overflow((a), (b), &c); })
+#endif
+
+#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
+ (a) == 0 ? 0 : \
+ (a) == -1 ? (b) < -(max) : \
+ (a) > 0 ? \
+ ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
+ ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
+
+#if __has_builtin(__builtin_mul_overflow_p)
+/* __builtin_mul_overflow_p can take bitfield */
+/* and GCC permits bitfields for integers other than int */
+# define MUL_OVERFLOW_FIXNUM_P(a, b) \
+ __extension__ ({ \
+ struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; \
+ __builtin_mul_overflow_p((a), (b), c.fixnum); \
+ })
+#else
+# define MUL_OVERFLOW_FIXNUM_P(a, b) \
+ MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
+#endif
+
+#ifdef MUL_OVERFLOW_P
+# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
+# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
+# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_P(a, b)
+#else
+# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
+# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
+# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
+#endif
+
+#ifdef HAVE_UINT128_T
+# define bit_length(x) \
+ (unsigned int) \
+ (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
+ sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \
+ 128 - nlz_int128((uint128_t)(x)))
+#else
+# define bit_length(x) \
+ (unsigned int) \
+ (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
+ 64 - nlz_int64((uint64_t)(x)))
+#endif
+
+#ifndef swap16
+# define swap16 ruby_swap16
+#endif
+
+#ifndef swap32
+# define swap32 ruby_swap32
+#endif
+
+#ifndef swap64
+# define swap64 ruby_swap64
+#endif
+
+static inline uint16_t ruby_swap16(uint16_t);
+static inline uint32_t ruby_swap32(uint32_t);
+static inline uint64_t ruby_swap64(uint64_t);
+static inline unsigned nlz_int(unsigned x);
+static inline unsigned nlz_long(unsigned long x);
+static inline unsigned nlz_long_long(unsigned long long x);
+static inline unsigned nlz_intptr(uintptr_t x);
+static inline unsigned nlz_int32(uint32_t x);
+static inline unsigned nlz_int64(uint64_t x);
+#ifdef HAVE_UINT128_T
+static inline unsigned nlz_int128(uint128_t x);
+#endif
+static inline unsigned rb_popcount32(uint32_t x);
+static inline unsigned rb_popcount64(uint64_t x);
+static inline unsigned rb_popcount_intptr(uintptr_t x);
+static inline int ntz_int32(uint32_t x);
+static inline int ntz_int64(uint64_t x);
+static inline int ntz_intptr(uintptr_t x);
+static inline VALUE RUBY_BIT_ROTL(VALUE, int);
+static inline VALUE RUBY_BIT_ROTR(VALUE, int);
+
+static inline uint16_t
+ruby_swap16(uint16_t x)
+{
+#if __has_builtin(__builtin_bswap16)
+ return __builtin_bswap16(x);
+
+#elif MSC_VERSION_SINCE(1310)
+ return _byteswap_ushort(x);
+
+#else
+ return (x << 8) | (x >> 8);
+
+#endif
+}
+
+static inline uint32_t
+ruby_swap32(uint32_t x)
+{
+#if __has_builtin(__builtin_bswap32)
+ return __builtin_bswap32(x);
+
+#elif MSC_VERSION_SINCE(1310)
+ return _byteswap_ulong(x);
+
+#else
+ x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);
+ x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8);
+ return x;
+
+#endif
+}
+
+static inline uint64_t
+ruby_swap64(uint64_t x)
+{
+#if __has_builtin(__builtin_bswap64)
+ return __builtin_bswap64(x);
+
+#elif MSC_VERSION_SINCE(1310)
+ return _byteswap_uint64(x);
+
+#else
+ x = ((x & 0x00000000FFFFFFFFULL) << 32) | ((x & 0xFFFFFFFF00000000ULL) >> 32);
+ x = ((x & 0x0000FFFF0000FFFFULL) << 16) | ((x & 0xFFFF0000FFFF0000ULL) >> 16);
+ x = ((x & 0x00FF00FF00FF00FFULL) << 8) | ((x & 0xFF00FF00FF00FF00ULL) >> 8);
+ return x;
+
+#endif
+}
+
+static inline unsigned int
+nlz_int32(uint32_t x)
+{
+#if defined(_MSC_VER) && defined(__AVX2__)
+ /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC.
+ * AMD CPUs have had this instruction for decades (since K10) but for
+ * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum
+ * safety. */
+ return (unsigned int)__lzcnt(x);
+
+#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
+ return (unsigned int)_lzcnt_u32(x);
+
+#elif MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
+ unsigned long r;
+ return _BitScanReverse(&r, x) ? (31 - (int)r) : 32;
+
+#elif __has_builtin(__builtin_clz)
+ STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32);
+ return x ? (unsigned int)__builtin_clz(x) : 32;
+
+#else
+ uint32_t y;
+ unsigned n = 32;
+ y = x >> 16; if (y) {n -= 16; x = y;}
+ y = x >> 8; if (y) {n -= 8; x = y;}
+ y = x >> 4; if (y) {n -= 4; x = y;}
+ y = x >> 2; if (y) {n -= 2; x = y;}
+ y = x >> 1; if (y) {return n - 2;}
+ return (unsigned int)(n - x);
+#endif
+}
+
+static inline unsigned int
+nlz_int64(uint64_t x)
+{
+#if defined(_MSC_VER) && defined(__AVX2__)
+ return (unsigned int)__lzcnt64(x);
+
+#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
+ return (unsigned int)_lzcnt_u64(x);
+
+#elif defined(_WIN64) && MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
+ unsigned long r;
+ return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64;
+
+#elif __has_builtin(__builtin_clzl)
+ if (x == 0) {
+ return 64;
+ }
+ else if (sizeof(long) * CHAR_BIT == 64) {
+ return (unsigned int)__builtin_clzl((unsigned long)x);
+ }
+ else if (sizeof(long long) * CHAR_BIT == 64) {
+ return (unsigned int)__builtin_clzll((unsigned long long)x);
+ }
+ else {
+ /* :FIXME: Is there a way to make this branch a compile-time error? */
+ UNREACHABLE_RETURN(~0);
+ }
+
+#else
+ uint64_t y;
+ unsigned int n = 64;
+ y = x >> 32; if (y) {n -= 32; x = y;}
+ y = x >> 16; if (y) {n -= 16; x = y;}
+ y = x >> 8; if (y) {n -= 8; x = y;}
+ y = x >> 4; if (y) {n -= 4; x = y;}
+ y = x >> 2; if (y) {n -= 2; x = y;}
+ y = x >> 1; if (y) {return n - 2;}
+ return (unsigned int)(n - x);
+
+#endif
+}
+
+#ifdef HAVE_UINT128_T
+static inline unsigned int
+nlz_int128(uint128_t x)
+{
+ uint64_t y = (uint64_t)(x >> 64);
+
+ if (x == 0) {
+ return 128;
+ }
+ else if (y == 0) {
+ return (unsigned int)nlz_int64(x) + 64;
+ }
+ else {
+ return (unsigned int)nlz_int64(y);
+ }
+}
+#endif
+
+static inline unsigned int
+nlz_int(unsigned int x)
+{
+ if (sizeof(unsigned int) * CHAR_BIT == 32) {
+ return nlz_int32((uint32_t)x);
+ }
+ else if (sizeof(unsigned int) * CHAR_BIT == 64) {
+ return nlz_int64((uint64_t)x);
+ }
+ else {
+ UNREACHABLE_RETURN(~0);
+ }
+}
+
+static inline unsigned int
+nlz_long(unsigned long x)
+{
+ if (sizeof(unsigned long) * CHAR_BIT == 32) {
+ return nlz_int32((uint32_t)x);
+ }
+ else if (sizeof(unsigned long) * CHAR_BIT == 64) {
+ return nlz_int64((uint64_t)x);
+ }
+ else {
+ UNREACHABLE_RETURN(~0);
+ }
+}
+
+static inline unsigned int
+nlz_long_long(unsigned long long x)
+{
+ if (sizeof(unsigned long long) * CHAR_BIT == 64) {
+ return nlz_int64((uint64_t)x);
+ }
+#ifdef HAVE_UINT128_T
+ else if (sizeof(unsigned long long) * CHAR_BIT == 128) {
+ return nlz_int128((uint128_t)x);
+ }
+#endif
+ else {
+ UNREACHABLE_RETURN(~0);
+ }
+}
+
+static inline unsigned int
+nlz_intptr(uintptr_t x)
+{
+ if (sizeof(uintptr_t) == sizeof(unsigned int)) {
+ return nlz_int((unsigned int)x);
+ }
+ if (sizeof(uintptr_t) == sizeof(unsigned long)) {
+ return nlz_long((unsigned long)x);
+ }
+ if (sizeof(uintptr_t) == sizeof(unsigned long long)) {
+ return nlz_long_long((unsigned long long)x);
+ }
+ else {
+ UNREACHABLE_RETURN(~0);
+ }
+}
+
+static inline unsigned int
+rb_popcount32(uint32_t x)
+{
+#if defined(_MSC_VER) && defined(__AVX__)
+ /* Note: CPUs since Nehalem and Barcelona have had this instruction so SSE
+ * 4.2 should suffice, but it seems there is no such thing like __SSE_4_2__
+ * predefined macro in MSVC. They do have __AVX__ so use it instead. */
+ return (unsigned int)__popcnt(x);
+
+#elif __has_builtin(__builtin_popcount)
+ STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT >= 32);
+ return (unsigned int)__builtin_popcount(x);
+
+#else
+ x = (x & 0x55555555) + (x >> 1 & 0x55555555);
+ x = (x & 0x33333333) + (x >> 2 & 0x33333333);
+ x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
+ x = (x & 0x001f001f) + (x >> 8 & 0x001f001f);
+ x = (x & 0x0000003f) + (x >>16 & 0x0000003f);
+ return (unsigned int)x;
+
+#endif
+}
+
+static inline unsigned int
+rb_popcount64(uint64_t x)
+{
+#if defined(_MSC_VER) && defined(__AVX__)
+ return (unsigned int)__popcnt64(x);
+
+#elif __has_builtin(__builtin_popcount)
+ if (sizeof(long) * CHAR_BIT == 64) {
+ return (unsigned int)__builtin_popcountl((unsigned long)x);
+ }
+ else if (sizeof(long long) * CHAR_BIT == 64) {
+ return (unsigned int)__builtin_popcountll((unsigned long long)x);
+ }
+ else {
+ /* :FIXME: Is there a way to make this branch a compile-time error? */
+ UNREACHABLE_RETURN(~0);
+ }
+
+#else
+ x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
+ x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
+ x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707);
+ x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f);
+ x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f);
+ x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f);
+ return (unsigned int)x;
+
+#endif
+}
+
+static inline unsigned int
+rb_popcount_intptr(uintptr_t x)
+{
+ if (sizeof(uintptr_t) * CHAR_BIT == 64) {
+ return rb_popcount64((uint64_t)x);
+ }
+ else if (sizeof(uintptr_t) * CHAR_BIT == 32) {
+ return rb_popcount32((uint32_t)x);
+ }
+ else {
+ UNREACHABLE_RETURN(~0);
+ }
+}
+
+static inline int
+ntz_int32(uint32_t x)
+{
+#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
+ return (unsigned)_tzcnt_u32(x);
+
+#elif MSC_VERSION_SINCE(1400)
+ /* :FIXME: Is there any way to issue TZCNT instead of BSF, apart from using
+ * assembly? Because issuing LZCNT seems possible (see nlz.h). */
+ unsigned long r;
+ return _BitScanForward(&r, x) ? (int)r : 32;
+
+#elif __has_builtin(__builtin_ctz)
+ STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32);
+ return x ? (unsigned)__builtin_ctz(x) : 32;
+
+#else
+ return rb_popcount32((~x) & (x-1));
+
+#endif
+}
+
+static inline int
+ntz_int64(uint64_t x)
+{
+#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
+ return (unsigned)_tzcnt_u64(x);
+
+#elif defined(_WIN64) && MSC_VERSION_SINCE(1400)
+ unsigned long r;
+ return _BitScanForward64(&r, x) ? (int)r : 64;
+
+#elif __has_builtin(__builtin_ctzl)
+ if (x == 0) {
+ return 64;
+ }
+ else if (sizeof(long) * CHAR_BIT == 64) {
+ return (unsigned)__builtin_ctzl((unsigned long)x);
+ }
+ else if (sizeof(long long) * CHAR_BIT == 64) {
+ return (unsigned)__builtin_ctzll((unsigned long long)x);
+ }
+ else {
+ /* :FIXME: Is there a way to make this branch a compile-time error? */
+ UNREACHABLE_RETURN(~0);
+ }
+
+#else
+ return rb_popcount64((~x) & (x-1));
+
+#endif
+}
+
+static inline int
+ntz_intptr(uintptr_t x)
+{
+ if (sizeof(uintptr_t) * CHAR_BIT == 64) {
+ return ntz_int64((uint64_t)x);
+ }
+ else if (sizeof(uintptr_t) * CHAR_BIT == 32) {
+ return ntz_int32((uint32_t)x);
+ }
+ else {
+ UNREACHABLE_RETURN(~0);
+ }
+}
+
+static inline VALUE
+RUBY_BIT_ROTL(VALUE v, int n)
+{
+#if __has_builtin(__builtin_rotateleft32) && (SIZEOF_VALUE * CHAR_BIT == 32)
+ return __builtin_rotateleft32(v, n);
+
+#elif __has_builtin(__builtin_rotateleft64) && (SIZEOF_VALUE * CHAR_BIT == 64)
+ return __builtin_rotateleft64(v, n);
+
+#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 32)
+ return _rotl(v, n);
+
+#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 64)
+ return _rotl64(v, n);
+
+#elif defined(_lrotl) && (SIZEOF_VALUE == SIZEOF_LONG)
+ return _lrotl(v, n);
+
+#else
+ const int m = (sizeof(VALUE) * CHAR_BIT) - 1;
+ return (v << (n & m)) | (v >> (-n & m));
+#endif
+}
+
+static inline VALUE
+RUBY_BIT_ROTR(VALUE v, int n)
+{
+#if __has_builtin(__builtin_rotateright32) && (SIZEOF_VALUE * CHAR_BIT == 32)
+ return __builtin_rotateright32(v, n);
+
+#elif __has_builtin(__builtin_rotateright64) && (SIZEOF_VALUE * CHAR_BIT == 64)
+ return __builtin_rotateright64(v, n);
+
+#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 32)
+ return _rotr(v, n);
+
+#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 64)
+ return _rotr64(v, n);
+
+#elif defined(_lrotr) && (SIZEOF_VALUE == SIZEOF_LONG)
+ return _lrotr(v, n);
+
+#else
+ const int m = (sizeof(VALUE) * CHAR_BIT) - 1;
+ return (v << (-n & m)) | (v >> (n & m));
+#endif
+}
+
+#endif /* INTERNAL_BITS_H */
diff --git a/internal/class.h b/internal/class.h
new file mode 100644
index 0000000000..eade920ff0
--- /dev/null
+++ b/internal/class.h
@@ -0,0 +1,174 @@
+#ifndef INTERNAL_CLASS_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_CLASS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Class.
+ */
+#include "id_table.h" /* for struct rb_id_table */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
+#include "internal/serial.h" /* for rb_serial_t */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/intern.h" /* for rb_alloc_func_t */
+#include "ruby/ruby.h" /* for struct RBasic */
+
+#ifdef RCLASS_SUPER
+# undef RCLASS_SUPER
+#endif
+
+struct rb_subclass_entry {
+ VALUE klass;
+ struct rb_subclass_entry *next;
+};
+
+struct rb_iv_index_tbl_entry {
+ uint32_t index;
+ rb_serial_t class_serial;
+ VALUE class_value;
+};
+
+struct rb_classext_struct {
+ struct st_table *iv_index_tbl; // ID -> struct rb_iv_index_tbl_entry
+ struct st_table *iv_tbl;
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE /* otherwise m_tbl is in struct RClass */
+ struct rb_id_table *m_tbl;
+#endif
+ struct rb_id_table *const_tbl;
+ struct rb_id_table *callable_m_tbl;
+ struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
+ struct rb_subclass_entry *subclasses;
+ struct rb_subclass_entry **parent_subclasses;
+ /**
+ * In the case that this is an `ICLASS`, `module_subclasses` points to the link
+ * in the module's `subclasses` list that indicates that the klass has been
+ * included. Hopefully that makes sense.
+ */
+ struct rb_subclass_entry **module_subclasses;
+#if SIZEOF_SERIAL_T != SIZEOF_VALUE /* otherwise class_serial is in struct RClass */
+ rb_serial_t class_serial;
+#endif
+ const VALUE origin_;
+ const VALUE refined_class;
+ rb_alloc_func_t allocator;
+ const VALUE includer;
+};
+
+struct RClass {
+ struct RBasic basic;
+ VALUE super;
+ struct rb_classext_struct *ptr;
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE
+ /* Class serial is as wide as VALUE. Place it here. */
+ rb_serial_t class_serial;
+#else
+ /* Class serial does not fit into struct RClass. Place m_tbl instead. */
+ struct rb_id_table *m_tbl;
+#endif
+};
+
+typedef struct rb_subclass_entry rb_subclass_entry_t;
+typedef struct rb_classext_struct rb_classext_t;
+
+#define RCLASS_EXT(c) (RCLASS(c)->ptr)
+#define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
+#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE
+# define RCLASS_M_TBL(c) (RCLASS_EXT(c)->m_tbl)
+#else
+# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
+#endif
+#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
+#define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
+#define RCLASS_IV_INDEX_TBL(c) (RCLASS_EXT(c)->iv_index_tbl)
+#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
+#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE
+# define RCLASS_SERIAL(c) (RCLASS(c)->class_serial)
+#else
+# define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial)
+#endif
+#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
+
+#define RICLASS_IS_ORIGIN FL_USER5
+#define RCLASS_CLONED FL_USER6
+#define RICLASS_ORIGIN_SHARED_MTBL FL_USER8
+
+/* class.c */
+void rb_class_subclass_add(VALUE super, VALUE klass);
+void rb_class_remove_from_super_subclasses(VALUE);
+int rb_singleton_class_internal_p(VALUE sklass);
+VALUE rb_class_boot(VALUE);
+VALUE rb_make_metaclass(VALUE, VALUE);
+VALUE rb_include_class_new(VALUE, VALUE);
+void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
+void rb_class_detach_subclasses(VALUE);
+void rb_class_detach_module_subclasses(VALUE);
+void rb_class_remove_from_module_subclasses(VALUE);
+VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_special_singleton_class(VALUE);
+VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
+VALUE rb_singleton_class_get(VALUE obj);
+int rb_class_has_methods(VALUE c);
+void rb_undef_methods_from(VALUE klass, VALUE super);
+
+static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
+static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass);
+static inline VALUE RCLASS_SUPER(VALUE klass);
+static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super);
+static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_class_inherited(VALUE, VALUE);
+VALUE rb_keyword_error_new(const char *, VALUE);
+MJIT_SYMBOL_EXPORT_END
+
+static inline void
+RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
+{
+ RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin);
+ if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN);
+}
+
+static inline void
+RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass)
+{
+ FL_SET(iclass, RICLASS_ORIGIN_SHARED_MTBL);
+}
+
+static inline bool
+RICLASS_OWNS_M_TBL_P(VALUE iclass)
+{
+ return FL_TEST_RAW(iclass, RICLASS_IS_ORIGIN | RICLASS_ORIGIN_SHARED_MTBL) == RICLASS_IS_ORIGIN;
+}
+
+static inline void
+RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
+{
+ RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
+}
+
+static inline VALUE
+RCLASS_SUPER(VALUE klass)
+{
+ return RCLASS(klass)->super;
+}
+
+static inline VALUE
+RCLASS_SET_SUPER(VALUE klass, VALUE super)
+{
+ if (super) {
+ rb_class_remove_from_super_subclasses(klass);
+ rb_class_subclass_add(super, klass);
+ }
+ RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
+ return super;
+}
+
+#endif /* INTERNAL_CLASS_H */
diff --git a/internal/compar.h b/internal/compar.h
new file mode 100644
index 0000000000..888a3b5e1e
--- /dev/null
+++ b/internal/compar.h
@@ -0,0 +1,50 @@
+#ifndef INTERNAL_COMPAR_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_COMPAR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Comparable.
+ */
+#include "internal/vm.h" /* for rb_method_basic_definition_p */
+
+#define STRING_P(s) (RB_TYPE_P((s), T_STRING) && CLASS_OF(s) == rb_cString)
+
+enum {
+ cmp_opt_Integer,
+ cmp_opt_String,
+ cmp_opt_Float,
+ cmp_optimizable_count
+};
+
+struct cmp_opt_data {
+ unsigned int opt_methods;
+ unsigned int opt_inited;
+};
+
+#define NEW_CMP_OPT_MEMO(type, value) \
+ NEW_PARTIAL_MEMO_FOR(type, value, cmp_opt)
+#define CMP_OPTIMIZABLE_BIT(type) (1U << TOKEN_PASTE(cmp_opt_,type))
+#define CMP_OPTIMIZABLE(data, type) \
+ (((data).opt_inited & CMP_OPTIMIZABLE_BIT(type)) ? \
+ ((data).opt_methods & CMP_OPTIMIZABLE_BIT(type)) : \
+ (((data).opt_inited |= CMP_OPTIMIZABLE_BIT(type)), \
+ rb_method_basic_definition_p(TOKEN_PASTE(rb_c,type), id_cmp) && \
+ ((data).opt_methods |= CMP_OPTIMIZABLE_BIT(type))))
+
+#define OPTIMIZED_CMP(a, b, data) \
+ ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data, Integer)) ? \
+ (((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : \
+ (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data, String)) ? \
+ rb_str_cmp(a, b) : \
+ (RB_FLOAT_TYPE_P(a) && RB_FLOAT_TYPE_P(b) && CMP_OPTIMIZABLE(data, Float)) ? \
+ rb_float_cmp(a, b) : \
+ rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b))
+
+/* compar.c */
+VALUE rb_invcmp(VALUE, VALUE);
+
+#endif /* INTERNAL_COMPAR_H */
diff --git a/internal/compile.h b/internal/compile.h
new file mode 100644
index 0000000000..9842e0f5e0
--- /dev/null
+++ b/internal/compile.h
@@ -0,0 +1,32 @@
+#ifndef INTERNAL_COMPILE_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_COMPILE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for the compiler.
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "ruby/ruby.h" /* for rb_event_flag_t */
+
+struct rb_iseq_struct; /* in vm_core.h */
+
+/* compile.c */
+int rb_dvar_defined(ID, const struct rb_iseq_struct *);
+int rb_local_defined(ID, const struct rb_iseq_struct *);
+const char *rb_insns_name(int i);
+VALUE rb_insns_name_array(void);
+
+/* iseq.c */
+int rb_vm_insn_addr2insn(const void *);
+
+MJIT_SYMBOL_EXPORT_BEGIN
+/* iseq.c (export) */
+rb_event_flag_t rb_iseq_event_flags(const struct rb_iseq_struct *iseq, size_t pos);
+MJIT_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_COMPILE_H */
diff --git a/internal/compilers.h b/internal/compilers.h
new file mode 100644
index 0000000000..8a2f1d8d26
--- /dev/null
+++ b/internal/compilers.h
@@ -0,0 +1,108 @@
+#ifndef INTERNAL_COMPILERS_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_COMPILERS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header absorbing C compipler differences.
+ */
+#include "ruby/internal/compiler_since.h"
+#include "ruby/internal/has/attribute.h"
+#include "ruby/internal/has/builtin.h"
+#include "ruby/internal/has/c_attribute.h"
+#include "ruby/internal/has/declspec_attribute.h"
+#include "ruby/internal/has/extension.h"
+#include "ruby/internal/has/feature.h"
+#include "ruby/internal/has/warning.h"
+#include "ruby/backward/2/gcc_version_since.h"
+
+#define MSC_VERSION_SINCE(_) RBIMPL_COMPILER_SINCE(MSVC, (_) / 100, (_) % 100, 0)
+#define MSC_VERSION_BEFORE(_) RBIMPL_COMPILER_BEFORE(MSVC, (_) / 100, (_) % 100, 0)
+
+#ifndef __has_attribute
+# define __has_attribute(...) RBIMPL_HAS_ATTRIBUTE(__VA_ARGS__)
+#endif
+
+#ifndef __has_c_attribute
+# /* As of writing everything that lacks __has_c_attribute also completely
+# * lacks C2x attributes as well. Might change in future? */
+# define __has_c_attribute(...) 0
+#endif
+
+#ifndef __has_declspec_attribute
+# define __has_declspec_attribute(...) RBIMPL_HAS_DECLSPEC_ATTRIBUTE(__VA_ARGS__)
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(...) RBIMPL_HAS_BUILTIN(__VA_ARGS__)
+#endif
+
+#ifndef __has_feature
+# define __has_feature(...) RBIMPL_HAS_FEATURE(__VA_ARGS__)
+#endif
+
+#ifndef __has_extension
+# define __has_extension(...) RBIMPL_HAS_EXTENSION(__VA_ARGS__)
+#endif
+
+#ifndef __has_warning
+# define __has_warning(...) RBIMPL_HAS_WARNING(__VA_ARGS__)
+#endif
+
+#ifndef __GNUC__
+# define __extension__ /* void */
+#endif
+
+#ifndef MAYBE_UNUSED
+# define MAYBE_UNUSED(x) x
+#endif
+
+#ifndef WARN_UNUSED_RESULT
+# define WARN_UNUSED_RESULT(x) x
+#endif
+
+#define RB_OBJ_BUILTIN_TYPE(obj) rb_obj_builtin_type(obj)
+#define OBJ_BUILTIN_TYPE(obj) RB_OBJ_BUILTIN_TYPE(obj)
+#ifdef __GNUC__
+#define rb_obj_builtin_type(obj) \
+__extension__({ \
+ VALUE arg_obj = (obj); \
+ RB_SPECIAL_CONST_P(arg_obj) ? -1 : \
+ (int)RB_BUILTIN_TYPE(arg_obj); \
+ })
+#else
+# include "ruby/ruby.h"
+static inline int
+rb_obj_builtin_type(VALUE obj)
+{
+ return RB_SPECIAL_CONST_P(obj) ? -1 :
+ (int)RB_BUILTIN_TYPE(obj);
+}
+#endif
+
+/* A macro for defining a flexible array, like: VALUE ary[FLEX_ARY_LEN]; */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define FLEX_ARY_LEN /* VALUE ary[]; */
+#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
+# define FLEX_ARY_LEN 0 /* VALUE ary[0]; */
+#else
+# define FLEX_ARY_LEN 1 /* VALUE ary[1]; */
+#endif
+
+/*
+ * For declaring bitfields out of non-unsigned int types:
+ * struct date {
+ * BITFIELD(enum months, month, 4);
+ * ...
+ * };
+ */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define BITFIELD(type, name, size) type name : size
+#else
+# define BITFIELD(type, name, size) unsigned int name : size
+#endif
+
+#endif /* INTERNAL_COMPILERS_H */
diff --git a/internal/complex.h b/internal/complex.h
new file mode 100644
index 0000000000..9eae804ddb
--- /dev/null
+++ b/internal/complex.h
@@ -0,0 +1,30 @@
+#ifndef INTERNAL_COMPLEX_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_COMPLEX_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Complex.
+ */
+#include "ruby/internal/value.h" /* for struct RBasic */
+
+struct RComplex {
+ struct RBasic basic;
+ VALUE real;
+ VALUE imag;
+};
+
+#define RCOMPLEX(obj) ((struct RComplex *)(obj))
+
+/* shortcut macro for internal only */
+#define RCOMPLEX_SET_REAL(cmp, r) RB_OBJ_WRITE((cmp), &RCOMPLEX(cmp)->real, (r))
+#define RCOMPLEX_SET_IMAG(cmp, i) RB_OBJ_WRITE((cmp), &RCOMPLEX(cmp)->imag, (i))
+
+/* complex.c */
+VALUE rb_dbl_complex_new_polar_pi(double abs, double ang);
+st_index_t rb_complex_hash(VALUE comp);
+
+#endif /* INTERNAL_COMPLEX_H */
diff --git a/internal/cont.h b/internal/cont.h
new file mode 100644
index 0000000000..9e49dd3c8e
--- /dev/null
+++ b/internal/cont.h
@@ -0,0 +1,26 @@
+#ifndef INTERNAL_CONT_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_CONT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Fiber.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+
+struct rb_thread_struct; /* in vm_core.h */
+struct rb_fiber_struct; /* in cont.c */
+
+/* cont.c */
+VALUE rb_obj_is_fiber(VALUE);
+void rb_fiber_reset_root_local_storage(struct rb_thread_struct *);
+void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(VALUE), VALUE (*rollback_func)(VALUE));
+void rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber);
+
+VALUE rb_fiberptr_self(struct rb_fiber_struct *fiber);
+unsigned int rb_fiberptr_blocking(struct rb_fiber_struct *fiber);
+
+#endif /* INTERNAL_CONT_H */
diff --git a/internal/dir.h b/internal/dir.h
new file mode 100644
index 0000000000..ffbdb25208
--- /dev/null
+++ b/internal/dir.h
@@ -0,0 +1,17 @@
+#ifndef INTERNAL_DIR_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_DIR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Dir.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+
+/* dir.c */
+VALUE rb_dir_getwd_ospath(void);
+
+#endif /* INTERNAL_DIR_H */
diff --git a/internal/enc.h b/internal/enc.h
new file mode 100644
index 0000000000..0afc74db5d
--- /dev/null
+++ b/internal/enc.h
@@ -0,0 +1,20 @@
+#ifndef INTERNAL_ENC_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_ENC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Encoding.
+ */
+#include "ruby/encoding.h" /* for rb_encoding */
+
+/* us_ascii.c */
+extern rb_encoding OnigEncodingUS_ASCII;
+
+/* utf_8.c */
+extern rb_encoding OnigEncodingUTF_8;
+
+#endif /* INTERNAL_ENC_H */
diff --git a/internal/encoding.h b/internal/encoding.h
new file mode 100644
index 0000000000..c0cf061bd4
--- /dev/null
+++ b/internal/encoding.h
@@ -0,0 +1,31 @@
+#ifndef INTERNAL_ENCODING_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_ENCODING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Encoding.
+ */
+#include "ruby/ruby.h" /* for ID */
+#include "ruby/encoding.h" /* for rb_encoding */
+
+#define rb_enc_autoload_p(enc) (!rb_enc_mbmaxlen(enc))
+
+/* encoding.c */
+ID rb_id_encoding(void);
+rb_encoding *rb_enc_get_from_index(int index);
+rb_encoding *rb_enc_check_str(VALUE str1, VALUE str2);
+int rb_encdb_replicate(const char *alias, const char *orig);
+int rb_encdb_alias(const char *alias, const char *orig);
+int rb_enc_autoload(rb_encoding *enc);
+int rb_encdb_dummy(const char *name);
+void rb_encdb_declare(const char *name);
+void rb_enc_set_base(const char *name, const char *orig);
+int rb_enc_set_dummy(int index);
+void rb_encdb_set_unicode(int index);
+PUREFUNC(int rb_data_is_encoding(VALUE obj));
+
+#endif /* INTERNAL_ENCODING_H */
diff --git a/internal/enum.h b/internal/enum.h
new file mode 100644
index 0000000000..50890f0c9f
--- /dev/null
+++ b/internal/enum.h
@@ -0,0 +1,19 @@
+#ifndef INTERNAL_ENUM_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_ENUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Enumerable.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+
+/* enum.c */
+extern VALUE rb_cArithSeq;
+VALUE rb_f_send(int argc, VALUE *argv, VALUE recv);
+VALUE rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary);
+
+#endif /* INTERNAL_ENUM_H */
diff --git a/internal/enumerator.h b/internal/enumerator.h
new file mode 100644
index 0000000000..2e20c37d9e
--- /dev/null
+++ b/internal/enumerator.h
@@ -0,0 +1,22 @@
+#ifndef INTERNAL_ENUMERATOR_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_ENUMERATOR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Enumerator.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+#include "ruby/intern.h" /* for rb_enumerator_size_func */
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* enumerator.c (export) */
+VALUE rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv,
+ rb_enumerator_size_func *size_fn,
+ VALUE beg, VALUE end, VALUE step, int excl);
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_ENUMERATOR_H */
diff --git a/internal/error.h b/internal/error.h
new file mode 100644
index 0000000000..0dd629f052
--- /dev/null
+++ b/internal/error.h
@@ -0,0 +1,124 @@
+#ifndef INTERNAL_ERROR_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_ERROR_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Exception.
+ */
+#include "ruby/internal/config.h"
+#include <stdarg.h> /* for va_list */
+#include "internal/string.h" /* for rb_fstring_cstr */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/encoding.h" /* for rb_encoding */
+#include "ruby/intern.h" /* for rb_exc_raise */
+#include "ruby/ruby.h" /* for enum ruby_value_type */
+
+#ifdef Check_Type
+# undef Check_Type /* in ruby/ruby.h */
+#endif
+
+#ifdef rb_raise_static
+# undef rb_raise_static
+# undef rb_sys_fail_path
+# undef rb_syserr_fail_path
+#endif
+
+#define rb_raise_static(e, m) \
+ rb_raise_cstr_i((e), rb_str_new_static((m), rb_strlen_lit(m)))
+#ifdef RUBY_FUNCTION_NAME_STRING
+# define rb_sys_fail_path(path) rb_sys_fail_path_in(RUBY_FUNCTION_NAME_STRING, path)
+# define rb_syserr_fail_path(err, path) rb_syserr_fail_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
+# define rb_syserr_new_path(err, path) rb_syserr_new_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
+#else
+# define rb_sys_fail_path(path) rb_sys_fail_str(path)
+# define rb_syserr_fail_path(err, path) rb_syserr_fail_str((err), (path))
+# define rb_syserr_new_path(err, path) rb_syserr_new_str((err), (path))
+#endif
+
+/* error.c */
+extern long rb_backtrace_length_limit;
+extern VALUE rb_eEAGAIN;
+extern VALUE rb_eEWOULDBLOCK;
+extern VALUE rb_eEINPROGRESS;
+void rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args);
+NORETURN(void rb_async_bug_errno(const char *,int));
+const char *rb_builtin_type_name(int t);
+const char *rb_builtin_class_name(VALUE x);
+PRINTF_ARGS(void rb_warn_deprecated(const char *fmt, const char *suggest, ...), 1, 3);
+PRINTF_ARGS(void rb_warn_deprecated_to_remove(const char *fmt, const char *removal, ...), 1, 3);
+VALUE rb_syntax_error_append(VALUE, VALUE, int, int, rb_encoding*, const char*, va_list);
+PRINTF_ARGS(void rb_enc_warn(rb_encoding *enc, const char *fmt, ...), 2, 3);
+PRINTF_ARGS(void rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...), 2, 3);
+PRINTF_ARGS(void rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt, ...), 3, 4);
+rb_warning_category_t rb_warning_category_from_name(VALUE category);
+bool rb_warning_category_enabled_p(rb_warning_category_t category);
+VALUE rb_name_err_new(VALUE mesg, VALUE recv, VALUE method);
+VALUE rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv);
+VALUE rb_key_err_new(VALUE mesg, VALUE recv, VALUE name);
+PRINTF_ARGS(VALUE rb_warning_string(const char *fmt, ...), 1, 2);
+NORETURN(void rb_vraise(VALUE, const char *, va_list));
+NORETURN(static inline void rb_raise_cstr(VALUE etype, const char *mesg));
+NORETURN(static inline void rb_raise_cstr_i(VALUE etype, VALUE mesg));
+NORETURN(static inline void rb_name_err_raise_str(VALUE mesg, VALUE recv, VALUE name));
+NORETURN(static inline void rb_name_err_raise(const char *mesg, VALUE recv, VALUE name));
+NORETURN(static inline void rb_key_err_raise(VALUE mesg, VALUE recv, VALUE name));
+static inline void Check_Type(VALUE v, enum ruby_value_type t);
+static inline bool rb_typeddata_is_instance_of_inline(VALUE obj, const rb_data_type_t *data_type);
+#define rb_typeddata_is_instance_of rb_typeddata_is_instance_of_inline
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* error.c (export) */
+int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
+#ifdef RUBY_FUNCTION_NAME_STRING
+NORETURN(void rb_sys_fail_path_in(const char *func_name, VALUE path));
+NORETURN(void rb_syserr_fail_path_in(const char *func_name, int err, VALUE path));
+VALUE rb_syserr_new_path_in(const char *func_name, int n, VALUE path);
+#endif
+RUBY_SYMBOL_EXPORT_END
+
+static inline void
+rb_raise_cstr_i(VALUE etype, VALUE mesg)
+{
+ VALUE exc = rb_exc_new_str(etype, mesg);
+ rb_exc_raise(exc);
+}
+
+static inline void
+rb_raise_cstr(VALUE etype, const char *mesg)
+{
+ VALUE str = rb_str_new_cstr(mesg);
+ rb_raise_cstr_i(etype, str);
+}
+
+static inline void
+rb_name_err_raise_str(VALUE mesg, VALUE recv, VALUE name)
+{
+ VALUE exc = rb_name_err_new(mesg, recv, name);
+ rb_exc_raise(exc);
+}
+
+static inline void
+rb_name_err_raise(const char *mesg, VALUE recv, VALUE name)
+{
+ VALUE str = rb_fstring_cstr(mesg);
+ rb_name_err_raise_str(str, recv, name);
+}
+
+static inline void
+rb_key_err_raise(VALUE mesg, VALUE recv, VALUE name)
+{
+ VALUE exc = rb_key_err_new(mesg, recv, name);
+ rb_exc_raise(exc);
+}
+
+static inline bool
+rb_typeddata_is_instance_of_inline(VALUE obj, const rb_data_type_t *data_type)
+{
+ return RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj) && (RTYPEDDATA_TYPE(obj) == data_type);
+}
+
+#endif /* INTERNAL_ERROR_H */
diff --git a/internal/eval.h b/internal/eval.h
new file mode 100644
index 0000000000..8dae76b6f8
--- /dev/null
+++ b/internal/eval.h
@@ -0,0 +1,33 @@
+#ifndef INTERNAL_EVAL_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_EVAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for the evaluator.
+ * @note There also is eval_intern.h, which is evaluator's internal
+ * header (related to this file, but not the same role).
+ */
+#include "ruby/ruby.h" /* for ID */
+
+#define id_signo ruby_static_id_signo
+#define id_status ruby_static_id_status
+
+/* eval.c */
+extern ID ruby_static_id_signo;
+extern ID ruby_static_id_status;
+VALUE rb_refinement_module_get_refined_class(VALUE module);
+void rb_class_modify_check(VALUE);
+NORETURN(VALUE rb_f_raise(int argc, VALUE *argv));
+
+/* eval_error.c */
+VALUE rb_get_backtrace(VALUE info);
+
+/* eval_jump.c */
+void rb_call_end_proc(VALUE data);
+void rb_mark_end_proc(void);
+
+#endif /* INTERNAL_EVAL_H */
diff --git a/internal/file.h b/internal/file.h
new file mode 100644
index 0000000000..a93c1392f0
--- /dev/null
+++ b/internal/file.h
@@ -0,0 +1,39 @@
+#ifndef INTERNAL_FILE_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_FILE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for File.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+#include "ruby/encoding.h" /* for rb_encodinng */
+
+/* file.c */
+extern const char ruby_null_device[];
+VALUE rb_home_dir_of(VALUE user, VALUE result);
+VALUE rb_default_home_dir(VALUE result);
+VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict);
+VALUE rb_check_realpath(VALUE basedir, VALUE path, rb_encoding *origenc);
+void rb_file_const(const char*, VALUE);
+int rb_file_load_ok(const char *);
+VALUE rb_file_expand_path_fast(VALUE, VALUE);
+VALUE rb_file_expand_path_internal(VALUE, VALUE, int, int, VALUE);
+VALUE rb_get_path_check_to_string(VALUE);
+VALUE rb_get_path_check_convert(VALUE);
+int ruby_is_fd_loadable(int fd);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* file.c (export) */
+#ifdef HAVE_READLINK
+VALUE rb_readlink(VALUE path, rb_encoding *enc);
+#endif
+#ifdef __APPLE__
+VALUE rb_str_normalize_ospath(const char *ptr, long len);
+#endif
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_FILE_H */
diff --git a/internal/fixnum.h b/internal/fixnum.h
new file mode 100644
index 0000000000..7e0e4be84c
--- /dev/null
+++ b/internal/fixnum.h
@@ -0,0 +1,185 @@
+#ifndef INTERNAL_FIXNUM_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_FIXNUM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Fixnums.
+ */
+#include "ruby/internal/config.h" /* for HAVE_LONG_LONG */
+#include <limits.h> /* for CHAR_BIT */
+#include "internal/compilers.h" /* for __has_builtin */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/intern.h" /* for rb_big_mul */
+#include "ruby/ruby.h" /* for RB_FIXABLE */
+
+#if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
+# define DLONG LONG_LONG
+# define DL2NUM(x) LL2NUM(x)
+#elif defined(HAVE_INT128_T)
+# define DLONG int128_t
+# define DL2NUM(x) (RB_FIXABLE(x) ? LONG2FIX(x) : rb_int128t2big(x))
+VALUE rb_int128t2big(int128_t n); /* in bignum.c */
+#endif
+
+static inline long rb_overflowed_fix_to_int(long x);
+static inline VALUE rb_fix_plus_fix(VALUE x, VALUE y);
+static inline VALUE rb_fix_minus_fix(VALUE x, VALUE y);
+static inline VALUE rb_fix_mul_fix(VALUE x, VALUE y);
+static inline void rb_fix_divmod_fix(VALUE x, VALUE y, VALUE *divp, VALUE *modp);
+static inline VALUE rb_fix_div_fix(VALUE x, VALUE y);
+static inline VALUE rb_fix_mod_fix(VALUE x, VALUE y);
+static inline bool FIXNUM_POSITIVE_P(VALUE num);
+static inline bool FIXNUM_NEGATIVE_P(VALUE num);
+static inline bool FIXNUM_ZERO_P(VALUE num);
+
+static inline long
+rb_overflowed_fix_to_int(long x)
+{
+ return (long)((unsigned long)(x >> 1) ^ (1LU << (SIZEOF_LONG * CHAR_BIT - 1)));
+}
+
+static inline VALUE
+rb_fix_plus_fix(VALUE x, VALUE y)
+{
+#if !__has_builtin(__builtin_add_overflow)
+ long lz = FIX2LONG(x) + FIX2LONG(y);
+ return LONG2NUM(lz);
+#else
+ long lz;
+ /* NOTE
+ * (1) `LONG2FIX(FIX2LONG(x)+FIX2LONG(y))`
+ + = `((lx*2+1)/2 + (ly*2+1)/2)*2+1`
+ + = `lx*2 + ly*2 + 1`
+ + = `(lx*2+1) + (ly*2+1) - 1`
+ + = `x + y - 1`
+ * (2) Fixnum's LSB is always 1.
+ * It means you can always run `x - 1` without overflow.
+ * (3) Of course `z = x + (y-1)` may overflow.
+ * At that time true value is
+ * * positive: 0b0 1xxx...1, and z = 0b1xxx...1
+ * * negative: 0b1 0xxx...1, and z = 0b0xxx...1
+ * To convert this true value to long,
+ * (a) Use arithmetic shift
+ * * positive: 0b11xxx...
+ * * negative: 0b00xxx...
+ * (b) invert MSB
+ * * positive: 0b01xxx...
+ * * negative: 0b10xxx...
+ */
+ if (__builtin_add_overflow((long)x, (long)y-1, &lz)) {
+ return rb_int2big(rb_overflowed_fix_to_int(lz));
+ }
+ else {
+ return (VALUE)lz;
+ }
+#endif
+}
+
+static inline VALUE
+rb_fix_minus_fix(VALUE x, VALUE y)
+{
+#if !__has_builtin(__builtin_sub_overflow)
+ long lz = FIX2LONG(x) - FIX2LONG(y);
+ return LONG2NUM(lz);
+#else
+ long lz;
+ if (__builtin_sub_overflow((long)x, (long)y-1, &lz)) {
+ return rb_int2big(rb_overflowed_fix_to_int(lz));
+ }
+ else {
+ return (VALUE)lz;
+ }
+#endif
+}
+
+/* arguments must be Fixnum */
+static inline VALUE
+rb_fix_mul_fix(VALUE x, VALUE y)
+{
+ long lx = FIX2LONG(x);
+ long ly = FIX2LONG(y);
+#ifdef DLONG
+ return DL2NUM((DLONG)lx * (DLONG)ly);
+#else
+ if (MUL_OVERFLOW_FIXNUM_P(lx, ly)) {
+ return rb_big_mul(rb_int2big(lx), rb_int2big(ly));
+ }
+ else {
+ return LONG2FIX(lx * ly);
+ }
+#endif
+}
+
+/*
+ * This behaves different from C99 for negative arguments.
+ * Note that div may overflow fixnum.
+ */
+static inline void
+rb_fix_divmod_fix(VALUE a, VALUE b, VALUE *divp, VALUE *modp)
+{
+ /* assume / and % comply C99.
+ * ldiv(3) won't be inlined by GCC and clang.
+ * I expect / and % are compiled as single idiv.
+ */
+ long x = FIX2LONG(a);
+ long y = FIX2LONG(b);
+ long div, mod;
+ if (x == FIXNUM_MIN && y == -1) {
+ if (divp) *divp = LONG2NUM(-FIXNUM_MIN);
+ if (modp) *modp = LONG2FIX(0);
+ return;
+ }
+ div = x / y;
+ mod = x % y;
+ if (y > 0 ? mod < 0 : mod > 0) {
+ mod += y;
+ div -= 1;
+ }
+ if (divp) *divp = LONG2FIX(div);
+ if (modp) *modp = LONG2FIX(mod);
+}
+
+/* div() for Ruby
+ * This behaves different from C99 for negative arguments.
+ */
+static inline VALUE
+rb_fix_div_fix(VALUE x, VALUE y)
+{
+ VALUE div;
+ rb_fix_divmod_fix(x, y, &div, NULL);
+ return div;
+}
+
+/* mod() for Ruby
+ * This behaves different from C99 for negative arguments.
+ */
+static inline VALUE
+rb_fix_mod_fix(VALUE x, VALUE y)
+{
+ VALUE mod;
+ rb_fix_divmod_fix(x, y, NULL, &mod);
+ return mod;
+}
+
+static inline bool
+FIXNUM_POSITIVE_P(VALUE num)
+{
+ return (SIGNED_VALUE)num > (SIGNED_VALUE)INT2FIX(0);
+}
+
+static inline bool
+FIXNUM_NEGATIVE_P(VALUE num)
+{
+ return (SIGNED_VALUE)num < 0;
+}
+
+static inline bool
+FIXNUM_ZERO_P(VALUE num)
+{
+ return num == INT2FIX(0);
+}
+#endif /* INTERNAL_FIXNUM_H */
diff --git a/internal/gc.h b/internal/gc.h
new file mode 100644
index 0000000000..d439f6d8f6
--- /dev/null
+++ b/internal/gc.h
@@ -0,0 +1,167 @@
+#ifndef INTERNAL_GC_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_GC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for GC.
+ */
+#include "ruby/internal/config.h"
+
+#include <stddef.h> /* for size_t */
+
+#include "internal/compilers.h" /* for __has_attribute */
+#include "ruby/ruby.h" /* for rb_event_flag_t */
+
+struct rb_execution_context_struct; /* in vm_core.h */
+struct rb_objspace; /* in vm_core.h */
+
+#ifdef NEWOBJ_OF
+# undef NEWOBJ_OF
+# undef RB_NEWOBJ_OF
+# undef RB_OBJ_WRITE
+#endif
+
+/* optimized version of NEWOBJ() */
+#define RB_NEWOBJ_OF(var, T, c, f) \
+ T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
+ rb_wb_protected_newobj_of((c), (f) & ~FL_WB_PROTECTED) : \
+ rb_wb_unprotected_newobj_of((c), (f)))
+
+#define RB_EC_NEWOBJ_OF(ec, var, T, c, f) \
+ T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
+ rb_ec_wb_protected_newobj_of((ec), (c), (f) & ~FL_WB_PROTECTED) : \
+ rb_wb_unprotected_newobj_of((c), (f)))
+
+#define NEWOBJ_OF(var, T, c, f) RB_NEWOBJ_OF((var), T, (c), (f))
+#define RB_OBJ_GC_FLAGS_MAX 6 /* used in ext/objspace */
+
+#ifndef USE_UNALIGNED_MEMBER_ACCESS
+# define UNALIGNED_MEMBER_ACCESS(expr) (expr)
+#elif ! USE_UNALIGNED_MEMBER_ACCESS
+# define UNALIGNED_MEMBER_ACCESS(expr) (expr)
+#elif ! (__has_warning("-Waddress-of-packed-member") || GCC_VERSION_SINCE(9, 0, 0))
+# define UNALIGNED_MEMBER_ACCESS(expr) (expr)
+#else
+# include "internal/warnings.h"
+# define UNALIGNED_MEMBER_ACCESS(expr) __extension__({ \
+ COMPILER_WARNING_PUSH; \
+ COMPILER_WARNING_IGNORED(-Waddress-of-packed-member); \
+ __typeof__(expr) unaligned_member_access_result = (expr); \
+ COMPILER_WARNING_POP; \
+ unaligned_member_access_result; \
+})
+#endif
+
+#define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
+#define RB_OBJ_WRITE(a, slot, b) \
+ rb_obj_write((VALUE)(a), UNALIGNED_MEMBER_ACCESS((VALUE *)(slot)), \
+ (VALUE)(b), __FILE__, __LINE__)
+
+typedef struct ractor_newobj_cache {
+ struct RVALUE *freelist;
+ struct heap_page *using_page;
+} rb_ractor_newobj_cache_t;
+
+/* gc.c */
+extern VALUE *ruby_initial_gc_stress_ptr;
+extern int ruby_disable_gc;
+RUBY_ATTR_MALLOC void *ruby_mimmalloc(size_t size);
+void ruby_mimfree(void *ptr);
+void rb_objspace_set_event_hook(const rb_event_flag_t event);
+VALUE rb_objspace_gc_enable(struct rb_objspace *);
+VALUE rb_objspace_gc_disable(struct rb_objspace *);
+void ruby_gc_set_params(void);
+void rb_copy_wb_protected_attribute(VALUE dest, VALUE obj);
+#if __has_attribute(alloc_align)
+__attribute__((__alloc_align__(1)))
+#endif
+RUBY_ATTR_MALLOC void *rb_aligned_malloc(size_t, size_t) RUBY_ATTR_ALLOC_SIZE((2));
+size_t rb_size_mul_or_raise(size_t, size_t, VALUE); /* used in compile.c */
+size_t rb_size_mul_add_or_raise(size_t, size_t, size_t, VALUE); /* used in iseq.h */
+RUBY_ATTR_MALLOC void *rb_xmalloc_mul_add(size_t, size_t, size_t);
+void *rb_xrealloc_mul_add(const void *, size_t, size_t, size_t);
+RUBY_ATTR_MALLOC void *rb_xmalloc_mul_add_mul(size_t, size_t, size_t, size_t);
+RUBY_ATTR_MALLOC void *rb_xcalloc_mul_add_mul(size_t, size_t, size_t, size_t);
+static inline void *ruby_sized_xrealloc_inlined(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2));
+static inline void *ruby_sized_xrealloc2_inlined(void *ptr, size_t new_count, size_t elemsiz, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
+static inline void ruby_sized_xfree_inlined(void *ptr, size_t size);
+VALUE rb_class_allocate_instance(VALUE klass);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* gc.c (export) */
+const char *rb_objspace_data_type_name(VALUE obj);
+VALUE rb_wb_protected_newobj_of(VALUE, VALUE);
+VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE);
+VALUE rb_ec_wb_protected_newobj_of(struct rb_execution_context_struct *ec, VALUE klass, VALUE flags);
+size_t rb_obj_memsize_of(VALUE);
+void rb_gc_verify_internal_consistency(void);
+size_t rb_obj_gc_flags(VALUE, ID[], size_t);
+void rb_gc_mark_values(long n, const VALUE *values);
+void rb_gc_mark_vm_stack_values(long n, const VALUE *values);
+void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2));
+void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
+void ruby_sized_xfree(void *x, size_t size);
+void rb_gc_ractor_newobj_cache_clear(rb_ractor_newobj_cache_t *newobj_cache);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+int rb_ec_stack_check(struct rb_execution_context_struct *ec);
+void rb_gc_writebarrier_remember(VALUE obj);
+const char *rb_obj_info(VALUE obj);
+MJIT_SYMBOL_EXPORT_END
+
+#if defined(HAVE_MALLOC_USABLE_SIZE) || defined(HAVE_MALLOC_SIZE) || defined(_WIN32)
+
+static inline void *
+ruby_sized_xrealloc_inlined(void *ptr, size_t new_size, size_t old_size)
+{
+ return ruby_xrealloc(ptr, new_size);
+}
+
+static inline void *
+ruby_sized_xrealloc2_inlined(void *ptr, size_t new_count, size_t elemsiz, size_t old_count)
+{
+ return ruby_xrealloc2(ptr, new_count, elemsiz);
+}
+
+static inline void
+ruby_sized_xfree_inlined(void *ptr, size_t size)
+{
+ ruby_xfree(ptr);
+}
+
+# define SIZED_REALLOC_N(x, y, z, w) REALLOC_N(x, y, z)
+
+#else
+
+static inline void *
+ruby_sized_xrealloc_inlined(void *ptr, size_t new_size, size_t old_size)
+{
+ return ruby_sized_xrealloc(ptr, new_size, old_size);
+}
+
+static inline void *
+ruby_sized_xrealloc2_inlined(void *ptr, size_t new_count, size_t elemsiz, size_t old_count)
+{
+ return ruby_sized_xrealloc2(ptr, new_count, elemsiz, old_count);
+}
+
+static inline void
+ruby_sized_xfree_inlined(void *ptr, size_t size)
+{
+ ruby_sized_xfree(ptr, size);
+}
+
+# define SIZED_REALLOC_N(v, T, m, n) \
+ ((v) = (T *)ruby_sized_xrealloc2((void *)(v), (m), sizeof(T), (n)))
+
+#endif /* HAVE_MALLOC_USABLE_SIZE */
+
+#define ruby_sized_xrealloc ruby_sized_xrealloc_inlined
+#define ruby_sized_xrealloc2 ruby_sized_xrealloc2_inlined
+#define ruby_sized_xfree ruby_sized_xfree_inlined
+#endif /* INTERNAL_GC_H */
diff --git a/internal/hash.h b/internal/hash.h
new file mode 100644
index 0000000000..a4677c581b
--- /dev/null
+++ b/internal/hash.h
@@ -0,0 +1,241 @@
+#ifndef INTERNAL_HASH_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_HASH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Hash.
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/ruby.h" /* for struct RBasic */
+#include "ruby/st.h" /* for struct st_table */
+
+#define RHASH_AR_TABLE_MAX_SIZE SIZEOF_VALUE
+
+struct ar_table_struct;
+typedef unsigned char ar_hint_t;
+
+enum ruby_rhash_flags {
+ RHASH_PASS_AS_KEYWORDS = FL_USER1, /* FL 1 */
+ RHASH_PROC_DEFAULT = FL_USER2, /* FL 2 */
+ RHASH_ST_TABLE_FLAG = FL_USER3, /* FL 3 */
+ RHASH_AR_TABLE_SIZE_MASK = (FL_USER4|FL_USER5|FL_USER6|FL_USER7), /* FL 4..7 */
+ RHASH_AR_TABLE_SIZE_SHIFT = (FL_USHIFT+4),
+ RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */
+ RHASH_AR_TABLE_BOUND_SHIFT = (FL_USHIFT+8),
+
+#if USE_TRANSIENT_HEAP
+ RHASH_TRANSIENT_FLAG = FL_USER12, /* FL 12 */
+#endif
+
+ // we can not put it in "enum" because it can exceed "int" range.
+#define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
+ FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
+
+ RHASH_LEV_SHIFT = (FL_USHIFT + 13),
+ RHASH_LEV_MAX = 127, /* 7 bits */
+};
+
+struct RHash {
+ struct RBasic basic;
+ union {
+ st_table *st;
+ struct ar_table_struct *ar; /* possibly 0 */
+ } as;
+ const VALUE ifnone;
+ union {
+ ar_hint_t ary[RHASH_AR_TABLE_MAX_SIZE];
+ VALUE word;
+ } ar_hint;
+};
+
+#define RHASH(obj) ((struct RHash *)(obj))
+
+#ifdef RHASH_IFNONE
+# undef RHASH_IFNONE
+#endif
+
+#ifdef RHASH_SIZE
+# undef RHASH_SIZE
+#endif
+
+#ifdef RHASH_EMPTY_P
+# undef RHASH_EMPTY_P
+#endif
+
+/* hash.c */
+void rb_hash_st_table_set(VALUE hash, st_table *st);
+VALUE rb_hash_default_value(VALUE hash, VALUE key);
+VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
+long rb_dbl_long_hash(double d);
+st_table *rb_init_identtable(void);
+VALUE rb_to_hash_type(VALUE obj);
+VALUE rb_hash_key_str(VALUE);
+VALUE rb_hash_values(VALUE hash);
+VALUE rb_hash_rehash(VALUE hash);
+int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
+VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
+int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
+int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
+int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
+extern st_table *rb_hash_st_table(VALUE hash);
+
+static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
+static inline VALUE RHASH_IFNONE(VALUE h);
+static inline size_t RHASH_SIZE(VALUE h);
+static inline bool RHASH_EMPTY_P(VALUE h);
+static inline bool RHASH_AR_TABLE_P(VALUE h);
+static inline bool RHASH_ST_TABLE_P(VALUE h);
+static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
+static inline st_table *RHASH_ST_TABLE(VALUE h);
+static inline size_t RHASH_ST_SIZE(VALUE h);
+static inline void RHASH_ST_CLEAR(VALUE h);
+static inline bool RHASH_TRANSIENT_P(VALUE h);
+static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h);
+static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* hash.c (export) */
+VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
+VALUE rb_ident_hash_new(void);
+int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_hash_new_with_size(st_index_t size);
+VALUE rb_hash_resurrect(VALUE hash);
+int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
+VALUE rb_hash_keys(VALUE hash);
+VALUE rb_hash_has_key(VALUE hash, VALUE key);
+VALUE rb_hash_compare_by_id_p(VALUE hash);
+
+st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
+#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
+MJIT_SYMBOL_EXPORT_END
+
+#if 0 /* for debug */
+
+static inline bool
+RHASH_AR_TABLE_P(VALUE h)
+{
+ extern int rb_hash_ar_table_p(VALUE hash);
+ return rb_hash_ar_table_p(h)
+}
+
+static inline struct ar_table_struct *
+RHASH_AR_TABLE(VALUE h)
+{
+ extern struct ar_table_struct *rb_hash_ar_table(VALUE hash);
+ return rb_hash_ar_table(h)
+}
+
+static inline st_table *
+RHASH_ST_TABLE(VALUE h)
+{
+ return rb_hash_st_table(h)
+}
+
+#else
+
+static inline bool
+RHASH_AR_TABLE_P(VALUE h)
+{
+ return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
+}
+
+static inline struct ar_table_struct *
+RHASH_AR_TABLE(VALUE h)
+{
+ return RHASH(h)->as.ar;
+}
+
+static inline st_table *
+RHASH_ST_TABLE(VALUE h)
+{
+ return RHASH(h)->as.st;
+}
+
+#endif
+
+static inline VALUE
+RHASH_IFNONE(VALUE h)
+{
+ return RHASH(h)->ifnone;
+}
+
+static inline size_t
+RHASH_SIZE(VALUE h)
+{
+ if (RHASH_AR_TABLE_P(h)) {
+ return RHASH_AR_TABLE_SIZE_RAW(h);
+ }
+ else {
+ return RHASH_ST_SIZE(h);
+ }
+}
+
+static inline bool
+RHASH_EMPTY_P(VALUE h)
+{
+ return RHASH_SIZE(h) == 0;
+}
+
+static inline bool
+RHASH_ST_TABLE_P(VALUE h)
+{
+ return ! RHASH_AR_TABLE_P(h);
+}
+
+static inline size_t
+RHASH_ST_SIZE(VALUE h)
+{
+ return RHASH_ST_TABLE(h)->num_entries;
+}
+
+static inline void
+RHASH_ST_CLEAR(VALUE h)
+{
+ FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG);
+ RHASH(h)->as.ar = NULL;
+}
+
+static inline unsigned
+RHASH_AR_TABLE_SIZE_RAW(VALUE h)
+{
+ VALUE ret = FL_TEST_RAW(h, RHASH_AR_TABLE_SIZE_MASK);
+ ret >>= RHASH_AR_TABLE_SIZE_SHIFT;
+ return (unsigned)ret;
+}
+
+static inline bool
+RHASH_TRANSIENT_P(VALUE h)
+{
+#if USE_TRANSIENT_HEAP
+ return FL_TEST_RAW(h, RHASH_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+static inline void
+RHASH_SET_TRANSIENT_FLAG(VALUE h)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(h, RHASH_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+RHASH_UNSET_TRANSIENT_FLAG(VALUE h)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG);
+#endif
+}
+
+#endif /* INTERNAL_HASH_H */
diff --git a/internal/imemo.h b/internal/imemo.h
new file mode 100644
index 0000000000..a9e2136ac4
--- /dev/null
+++ b/internal/imemo.h
@@ -0,0 +1,244 @@
+#ifndef INTERNAL_IMEMO_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_IMEMO_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief IMEMO: Internal memo object.
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "internal/array.h" /* for rb_ary_tmp_new_fill */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/ruby.h" /* for rb_block_call_func_t */
+
+#ifndef IMEMO_DEBUG
+# define IMEMO_DEBUG 0
+#endif
+
+#define IMEMO_MASK 0x0f
+
+/* FL_USER0 to FL_USER3 is for type */
+#define IMEMO_FL_USHIFT (FL_USHIFT + 4)
+#define IMEMO_FL_USER0 FL_USER4
+#define IMEMO_FL_USER1 FL_USER5
+#define IMEMO_FL_USER2 FL_USER6
+#define IMEMO_FL_USER3 FL_USER7
+#define IMEMO_FL_USER4 FL_USER8
+#define IMEMO_FL_USER5 FL_USER9
+
+enum imemo_type {
+ imemo_env = 0,
+ imemo_cref = 1, /*!< class reference */
+ imemo_svar = 2, /*!< special variable */
+ imemo_throw_data = 3,
+ imemo_ifunc = 4, /*!< iterator function */
+ imemo_memo = 5,
+ imemo_ment = 6,
+ imemo_iseq = 7,
+ imemo_tmpbuf = 8,
+ imemo_ast = 9,
+ imemo_parser_strterm = 10,
+ imemo_callinfo = 11,
+ imemo_callcache = 12,
+ imemo_constcache = 13,
+};
+
+/* CREF (Class REFerence) is defined in method.h */
+
+/*! SVAR (Special VARiable) */
+struct vm_svar {
+ VALUE flags;
+ const VALUE cref_or_me; /*!< class reference or rb_method_entry_t */
+ const VALUE lastline;
+ const VALUE backref;
+ const VALUE others;
+};
+
+/*! THROW_DATA */
+struct vm_throw_data {
+ VALUE flags;
+ VALUE reserved;
+ const VALUE throw_obj;
+ const struct rb_control_frame_struct *catch_frame;
+ int throw_state;
+};
+
+#define THROW_DATA_CONSUMED IMEMO_FL_USER0
+
+/* IFUNC (Internal FUNCtion) */
+
+struct vm_ifunc_argc {
+#if SIZEOF_INT * 2 > SIZEOF_VALUE
+ signed int min: (SIZEOF_VALUE * CHAR_BIT) / 2;
+ signed int max: (SIZEOF_VALUE * CHAR_BIT) / 2;
+#else
+ int min, max;
+#endif
+};
+
+/*! IFUNC (Internal FUNCtion) */
+struct vm_ifunc {
+ VALUE flags;
+ VALUE reserved;
+ rb_block_call_func_t func;
+ const void *data;
+ struct vm_ifunc_argc argc;
+};
+
+struct rb_imemo_tmpbuf_struct {
+ VALUE flags;
+ VALUE reserved;
+ VALUE *ptr; /* malloc'ed buffer */
+ struct rb_imemo_tmpbuf_struct *next; /* next imemo */
+ size_t cnt; /* buffer size in VALUE */
+};
+
+/*! MEMO
+ *
+ * @see imemo_type
+ * */
+struct MEMO {
+ VALUE flags;
+ VALUE reserved;
+ const VALUE v1;
+ const VALUE v2;
+ union {
+ long cnt;
+ long state;
+ const VALUE value;
+ void (*func)(void);
+ } u3;
+};
+
+/* ment is in method.h */
+
+#define THROW_DATA_P(err) imemo_throw_data_p((VALUE)err)
+#define MEMO_CAST(m) ((struct MEMO *)(m))
+#define MEMO_NEW(a, b, c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
+#define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value))
+#define NEW_MEMO_FOR(type, value) \
+ ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
+#define NEW_PARTIAL_MEMO_FOR(type, value, member) \
+ ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), \
+ rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \
+ MEMO_FOR(type, value))
+
+typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
+VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
+rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
+struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
+void rb_strterm_mark(VALUE obj);
+static inline enum imemo_type imemo_type(VALUE imemo);
+static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
+static inline bool imemo_throw_data_p(VALUE imemo);
+static inline struct vm_ifunc *rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data);
+static inline VALUE rb_imemo_tmpbuf_auto_free_pointer(void);
+static inline void *RB_IMEMO_TMPBUF_PTR(VALUE v);
+static inline void *rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr);
+static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str);
+static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
+static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+#if IMEMO_DEBUG
+VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, const char *file, int line);
+#define rb_imemo_new(type, v1, v2, v3, v0) rb_imemo_new_debug(type, v1, v2, v3, v0, __FILE__, __LINE__)
+#else
+VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
+#endif
+const char *rb_imemo_name(enum imemo_type type);
+RUBY_SYMBOL_EXPORT_END
+
+static inline enum imemo_type
+imemo_type(VALUE imemo)
+{
+ return (RBASIC(imemo)->flags >> FL_USHIFT) & IMEMO_MASK;
+}
+
+static inline int
+imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
+{
+ if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
+ /* fixed at compile time if imemo_type is given. */
+ const VALUE mask = (IMEMO_MASK << FL_USHIFT) | RUBY_T_MASK;
+ const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
+ /* fixed at runtime. */
+ return expected_type == (RBASIC(imemo)->flags & mask);
+ }
+ else {
+ return 0;
+ }
+}
+
+#define IMEMO_TYPE_P(v, t) imemo_type_p((VALUE)v, t)
+
+static inline bool
+imemo_throw_data_p(VALUE imemo)
+{
+ return RB_TYPE_P(imemo, T_IMEMO);
+}
+
+static inline struct vm_ifunc *
+rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
+{
+ return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
+}
+
+static inline VALUE
+rb_imemo_tmpbuf_auto_free_pointer(void)
+{
+ return rb_imemo_new(imemo_tmpbuf, 0, 0, 0, 0);
+}
+
+static inline void *
+RB_IMEMO_TMPBUF_PTR(VALUE v)
+{
+ const struct rb_imemo_tmpbuf_struct *p = (const void *)v;
+ return p->ptr;
+}
+
+static inline void *
+rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
+{
+ return ((rb_imemo_tmpbuf_t *)v)->ptr = ptr;
+}
+
+static inline VALUE
+rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
+{
+ const void *src;
+ VALUE imemo;
+ rb_imemo_tmpbuf_t *tmpbuf;
+ void *dst;
+ size_t len;
+
+ SafeStringValue(str);
+ /* create tmpbuf to keep the pointer before xmalloc */
+ imemo = rb_imemo_tmpbuf_auto_free_pointer();
+ tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
+ len = RSTRING_LEN(str);
+ src = RSTRING_PTR(str);
+ dst = ruby_xmalloc(len);
+ memcpy(dst, src, len);
+ tmpbuf->ptr = dst;
+ return imemo;
+}
+
+static inline void
+MEMO_V1_SET(struct MEMO *m, VALUE v)
+{
+ RB_OBJ_WRITE(m, &m->v1, v);
+}
+
+static inline void
+MEMO_V2_SET(struct MEMO *m, VALUE v)
+{
+ RB_OBJ_WRITE(m, &m->v2, v);
+}
+
+#endif /* INTERNAL_IMEMO_H */
diff --git a/internal/inits.h b/internal/inits.h
new file mode 100644
index 0000000000..680c9cc1a5
--- /dev/null
+++ b/internal/inits.h
@@ -0,0 +1,51 @@
+#ifndef INTERNAL_INITS_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_INITS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header aggregating init functions.
+ */
+
+/* class.c */
+void Init_class_hierarchy(void);
+
+/* dmyext.c */
+void Init_enc(void);
+void Init_ext(void);
+
+/* file.c */
+void Init_File(void);
+
+/* gc.c */
+void Init_heap(void);
+
+/* localeinit.c */
+int Init_enc_set_filesystem_encoding(void);
+
+/* newline.c */
+void Init_newline(void);
+
+/* vm.c */
+void Init_BareVM(void);
+void Init_vm_objects(void);
+
+/* vm_backtrace.c */
+void Init_vm_backtrace(void);
+
+/* vm_eval.c */
+void Init_vm_eval(void);
+
+/* vm_insnhelper.c */
+void Init_vm_stack_canary(void);
+
+/* vm_method.c */
+void Init_eval_method(void);
+
+/* inits.c */
+void rb_call_inits(void);
+
+#endif /* INTERNAL_INITS_H */
diff --git a/internal/io.h b/internal/io.h
new file mode 100644
index 0000000000..b184cec439
--- /dev/null
+++ b/internal/io.h
@@ -0,0 +1,35 @@
+#ifndef INTERNAL_IO_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_IO_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for IO.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+#include "ruby/io.h" /* for rb_io_t */
+
+/* io.c */
+void ruby_set_inplace_mode(const char *);
+void rb_stdio_set_default_encoding(void);
+VALUE rb_io_flush_raw(VALUE, int);
+size_t rb_io_memsize(const rb_io_t *);
+int rb_stderr_tty_p(void);
+void rb_io_fptr_finalize_internal(void *ptr);
+#ifdef rb_io_fptr_finalize
+# undef rb_io_fptr_finalize
+#endif
+#define rb_io_fptr_finalize rb_io_fptr_finalize_internal
+VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* io.c (export) */
+void rb_maygvl_fd_fix_cloexec(int fd);
+int rb_gc_for_fd(int err);
+void rb_write_error_str(VALUE mesg);
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_IO_H */
diff --git a/internal/load.h b/internal/load.h
new file mode 100644
index 0000000000..37c1dee351
--- /dev/null
+++ b/internal/load.h
@@ -0,0 +1,19 @@
+#ifndef INTERNAL_LOAD_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_LOAD_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for require.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+
+/* load.c */
+VALUE rb_get_expanded_load_path(void);
+int rb_require_internal(VALUE fname);
+NORETURN(void rb_load_fail(VALUE, const char*));
+
+#endif /* INTERNAL_LOAD_H */
diff --git a/internal/loadpath.h b/internal/loadpath.h
new file mode 100644
index 0000000000..f89f6694cd
--- /dev/null
+++ b/internal/loadpath.h
@@ -0,0 +1,17 @@
+#ifndef INTERNAL_LOADPATH_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_LOADPATH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for $LOAD_PATH.
+ */
+
+/* loadpath.c */
+extern const char ruby_exec_prefix[];
+extern const char ruby_initial_load_paths[];
+
+#endif /* INTERNAL_LOADPATH_H */
diff --git a/internal/math.h b/internal/math.h
new file mode 100644
index 0000000000..cd8d553790
--- /dev/null
+++ b/internal/math.h
@@ -0,0 +1,24 @@
+#ifndef INTERNAL_MATH_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_MATH_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Math.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+
+/* math.c */
+VALUE rb_math_atan2(VALUE, VALUE);
+VALUE rb_math_cos(VALUE);
+VALUE rb_math_cosh(VALUE);
+VALUE rb_math_exp(VALUE);
+VALUE rb_math_hypot(VALUE, VALUE);
+VALUE rb_math_log(int argc, const VALUE *argv);
+VALUE rb_math_sin(VALUE);
+VALUE rb_math_sinh(VALUE);
+
+#endif /* INTERNAL_MATH_H */
diff --git a/internal/missing.h b/internal/missing.h
new file mode 100644
index 0000000000..0224075b3d
--- /dev/null
+++ b/internal/missing.h
@@ -0,0 +1,19 @@
+#ifndef INTERNAL_MISSING_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_MISSING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header corresponding missing.
+ */
+#include "ruby/internal/config.h" /* for HAVE_SETPROCTITLE */
+
+/* missing/setproctitle.c */
+#ifndef HAVE_SETPROCTITLE
+extern void ruby_init_setproctitle(int argc, char *argv[]);
+#endif
+
+#endif /* INTERNAL_MISSING_H */
diff --git a/internal/numeric.h b/internal/numeric.h
new file mode 100644
index 0000000000..32d5bd27fa
--- /dev/null
+++ b/internal/numeric.h
@@ -0,0 +1,255 @@
+#ifndef INTERNAL_NUMERIC_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_NUMERIC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Numeric.
+ */
+#include "internal/bignum.h" /* for BIGNUM_POSITIVE_P */
+#include "internal/bits.h" /* for RUBY_BIT_ROTL */
+#include "internal/fixnum.h" /* for FIXNUM_POSITIVE_P */
+#include "internal/vm.h" /* for rb_method_basic_definition_p */
+#include "ruby/intern.h" /* for rb_cmperr */
+#include "ruby/ruby.h" /* for USE_FLONUM */
+
+#define ROUND_TO(mode, even, up, down) \
+ ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : \
+ (mode) == RUBY_NUM_ROUND_HALF_UP ? up : down)
+#define ROUND_FUNC(mode, name) \
+ ROUND_TO(mode, name##_half_even, name##_half_up, name##_half_down)
+#define ROUND_CALL(mode, name, args) \
+ ROUND_TO(mode, name##_half_even args, \
+ name##_half_up args, name##_half_down args)
+
+#ifndef ROUND_DEFAULT
+# define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_UP
+#endif
+
+enum ruby_num_rounding_mode {
+ RUBY_NUM_ROUND_HALF_UP,
+ RUBY_NUM_ROUND_HALF_EVEN,
+ RUBY_NUM_ROUND_HALF_DOWN,
+ RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT,
+};
+
+struct RFloat {
+ struct RBasic basic;
+ double float_value;
+};
+
+#define RFLOAT(obj) ((struct RFloat *)(obj))
+
+/* numeric.c */
+int rb_num_to_uint(VALUE val, unsigned int *ret);
+VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl);
+double ruby_float_step_size(double beg, double end, double unit, int excl);
+int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless);
+int rb_num_negative_p(VALUE);
+VALUE rb_int_succ(VALUE num);
+VALUE rb_float_uminus(VALUE num);
+VALUE rb_int_plus(VALUE x, VALUE y);
+VALUE rb_float_plus(VALUE x, VALUE y);
+VALUE rb_int_minus(VALUE x, VALUE y);
+VALUE rb_float_minus(VALUE x, VALUE y);
+VALUE rb_int_mul(VALUE x, VALUE y);
+VALUE rb_float_mul(VALUE x, VALUE y);
+VALUE rb_float_div(VALUE x, VALUE y);
+VALUE rb_int_idiv(VALUE x, VALUE y);
+VALUE rb_int_modulo(VALUE x, VALUE y);
+VALUE rb_int2str(VALUE num, int base);
+VALUE rb_fix_plus(VALUE x, VALUE y);
+VALUE rb_int_gt(VALUE x, VALUE y);
+VALUE rb_float_gt(VALUE x, VALUE y);
+VALUE rb_int_ge(VALUE x, VALUE y);
+enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
+double rb_int_fdiv_double(VALUE x, VALUE y);
+VALUE rb_int_pow(VALUE x, VALUE y);
+VALUE rb_float_pow(VALUE x, VALUE y);
+VALUE rb_int_cmp(VALUE x, VALUE y);
+VALUE rb_int_equal(VALUE x, VALUE y);
+VALUE rb_int_divmod(VALUE x, VALUE y);
+VALUE rb_int_and(VALUE x, VALUE y);
+VALUE rb_int_lshift(VALUE x, VALUE y);
+VALUE rb_int_div(VALUE x, VALUE y);
+int rb_int_positive_p(VALUE num);
+int rb_int_negative_p(VALUE num);
+VALUE rb_num_pow(VALUE x, VALUE y);
+VALUE rb_float_ceil(VALUE num, int ndigits);
+VALUE rb_float_floor(VALUE x, int ndigits);
+VALUE rb_float_abs(VALUE flt);
+static inline VALUE rb_num_compare_with_zero(VALUE num, ID mid);
+static inline int rb_num_positive_int_p(VALUE num);
+static inline int rb_num_negative_int_p(VALUE num);
+static inline double rb_float_flonum_value(VALUE v);
+static inline double rb_float_noflonum_value(VALUE v);
+static inline double rb_float_value_inline(VALUE v);
+static inline VALUE rb_float_new_inline(double d);
+static inline bool INT_POSITIVE_P(VALUE num);
+static inline bool INT_NEGATIVE_P(VALUE num);
+static inline bool FLOAT_ZERO_P(VALUE num);
+#define rb_float_value rb_float_value_inline
+#define rb_float_new rb_float_new_inline
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* numeric.c (export) */
+VALUE rb_int_positive_pow(long x, unsigned long y);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_flo_div_flo(VALUE x, VALUE y);
+double ruby_float_mod(double x, double y);
+VALUE rb_float_equal(VALUE x, VALUE y);
+int rb_float_cmp(VALUE x, VALUE y);
+VALUE rb_float_eql(VALUE x, VALUE y);
+VALUE rb_fix_aref(VALUE fix, VALUE idx);
+VALUE rb_int_zero_p(VALUE num);
+VALUE rb_int_even_p(VALUE num);
+VALUE rb_int_odd_p(VALUE num);
+VALUE rb_int_abs(VALUE num);
+VALUE rb_int_bit_length(VALUE num);
+VALUE rb_int_uminus(VALUE num);
+VALUE rb_int_comp(VALUE num);
+MJIT_SYMBOL_EXPORT_END
+
+static inline bool
+INT_POSITIVE_P(VALUE num)
+{
+ if (FIXNUM_P(num)) {
+ return FIXNUM_POSITIVE_P(num);
+ }
+ else {
+ return BIGNUM_POSITIVE_P(num);
+ }
+}
+
+static inline bool
+INT_NEGATIVE_P(VALUE num)
+{
+ if (FIXNUM_P(num)) {
+ return FIXNUM_NEGATIVE_P(num);
+ }
+ else {
+ return BIGNUM_NEGATIVE_P(num);
+ }
+}
+
+static inline bool
+FLOAT_ZERO_P(VALUE num)
+{
+ return RFLOAT_VALUE(num) == 0.0;
+}
+
+static inline VALUE
+rb_num_compare_with_zero(VALUE num, ID mid)
+{
+ VALUE zero = INT2FIX(0);
+ VALUE r = rb_check_funcall(num, mid, 1, &zero);
+ if (r == Qundef) {
+ rb_cmperr(num, zero);
+ }
+ return r;
+}
+
+static inline int
+rb_num_positive_int_p(VALUE num)
+{
+ const ID mid = '>';
+
+ if (FIXNUM_P(num)) {
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
+ return FIXNUM_POSITIVE_P(num);
+ }
+ else if (RB_TYPE_P(num, T_BIGNUM)) {
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
+ return BIGNUM_POSITIVE_P(num);
+ }
+ return RTEST(rb_num_compare_with_zero(num, mid));
+}
+
+static inline int
+rb_num_negative_int_p(VALUE num)
+{
+ const ID mid = '<';
+
+ if (FIXNUM_P(num)) {
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
+ return FIXNUM_NEGATIVE_P(num);
+ }
+ else if (RB_TYPE_P(num, T_BIGNUM)) {
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
+ return BIGNUM_NEGATIVE_P(num);
+ }
+ return RTEST(rb_num_compare_with_zero(num, mid));
+}
+
+static inline double
+rb_float_flonum_value(VALUE v)
+{
+#if USE_FLONUM
+ if (v != (VALUE)0x8000000000000002) { /* LIKELY */
+ union {
+ double d;
+ VALUE v;
+ } t;
+
+ VALUE b63 = (v >> 63);
+ /* e: xx1... -> 011... */
+ /* xx0... -> 100... */
+ /* ^b63 */
+ t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~(VALUE)0x03), 3);
+ return t.d;
+ }
+#endif
+ return 0.0;
+}
+
+static inline double
+rb_float_noflonum_value(VALUE v)
+{
+ return RFLOAT(v)->float_value;
+}
+
+static inline double
+rb_float_value_inline(VALUE v)
+{
+ if (FLONUM_P(v)) {
+ return rb_float_flonum_value(v);
+ }
+ return rb_float_noflonum_value(v);
+}
+
+static inline VALUE
+rb_float_new_inline(double d)
+{
+#if USE_FLONUM
+ union {
+ double d;
+ VALUE v;
+ } t;
+ int bits;
+
+ t.d = d;
+ bits = (int)((VALUE)(t.v >> 60) & 0x7);
+ /* bits contains 3 bits of b62..b60. */
+ /* bits - 3 = */
+ /* b011 -> b000 */
+ /* b100 -> b001 */
+
+ if (t.v != 0x3000000000000000 /* 1.72723e-77 */ &&
+ !((bits-3) & ~0x01)) {
+ return (RUBY_BIT_ROTL(t.v, 3) & ~(VALUE)0x01) | 0x02;
+ }
+ else if (t.v == (VALUE)0) {
+ /* +0.0 */
+ return 0x8000000000000002;
+ }
+ /* out of range */
+#endif
+ return rb_float_new_in_heap(d);
+}
+
+#endif /* INTERNAL_NUMERIC_H */
diff --git a/internal/object.h b/internal/object.h
new file mode 100644
index 0000000000..aa820128c7
--- /dev/null
+++ b/internal/object.h
@@ -0,0 +1,83 @@
+#ifndef INTERNAL_OBJECT_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_OBJECT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Object.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+#include "internal/class.h" /* for RCLASS_IV_INDEX_TBL */
+
+#ifdef ROBJECT_IV_INDEX_TBL
+# undef ROBJECT_IV_INDEX_TBL
+#endif
+
+/* object.c */
+VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
+NORETURN(void rb_undefined_alloc(VALUE klass));
+double rb_num_to_dbl(VALUE val);
+VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound);
+VALUE rb_immutable_obj_clone(int, VALUE *, VALUE);
+VALUE rb_check_convert_type_with_id(VALUE,int,const char*,ID);
+int rb_bool_expected(VALUE, const char *);
+static inline void RBASIC_CLEAR_CLASS(VALUE obj);
+static inline void RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass);
+static inline void RBASIC_SET_CLASS(VALUE obj, VALUE klass);
+static inline struct st_table *ROBJECT_IV_INDEX_TBL_inline(VALUE obj);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* object.c (export) */
+int rb_opts_exception_p(VALUE opts, int default_value);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+CONSTFUNC(VALUE rb_obj_equal(VALUE obj1, VALUE obj2));
+CONSTFUNC(VALUE rb_obj_not(VALUE obj));
+VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
+void rb_obj_copy_ivar(VALUE dest, VALUE obj);
+VALUE rb_false(VALUE obj);
+VALUE rb_convert_type_with_id(VALUE v, int t, const char* nam, ID mid);
+VALUE rb_obj_size(VALUE self, VALUE args, VALUE obj);
+MJIT_SYMBOL_EXPORT_END
+
+static inline void
+RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass)
+{
+ struct { VALUE flags; VALUE klass; } *ptr = (void *)obj;
+ ptr->klass = klass;
+}
+
+static inline void
+RBASIC_CLEAR_CLASS(VALUE obj)
+{
+ RBASIC_SET_CLASS_RAW(obj, 0);
+}
+
+static inline void
+RBASIC_SET_CLASS(VALUE obj, VALUE klass)
+{
+ VALUE oldv = RBASIC_CLASS(obj);
+ RBASIC_SET_CLASS_RAW(obj, klass);
+ RB_OBJ_WRITTEN(obj, oldv, klass);
+}
+
+RBIMPL_ATTR_PURE()
+static inline struct st_table *
+ROBJECT_IV_INDEX_TBL_inline(VALUE obj)
+{
+ if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
+ VALUE klass = rb_obj_class(obj);
+ return RCLASS_IV_INDEX_TBL(klass);
+ }
+ else {
+ const struct RObject *const ptr = ROBJECT(obj);
+ return ptr->as.heap.iv_index_tbl;
+ }
+}
+#define ROBJECT_IV_INDEX_TBL ROBJECT_IV_INDEX_TBL_inline
+
+#endif /* INTERNAL_OBJECT_H */
diff --git a/internal/parse.h b/internal/parse.h
new file mode 100644
index 0000000000..a37a39f84d
--- /dev/null
+++ b/internal/parse.h
@@ -0,0 +1,23 @@
+#ifndef INTERNAL_PARSE_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_PARSE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for the parser.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+struct rb_iseq_struct; /* in vm_core.h */
+
+/* parse.y */
+VALUE rb_parser_set_yydebug(VALUE, VALUE);
+void *rb_parser_load_file(VALUE parser, VALUE name);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_PARSE_H */
diff --git a/internal/proc.h b/internal/proc.h
new file mode 100644
index 0000000000..5628a1f1c7
--- /dev/null
+++ b/internal/proc.h
@@ -0,0 +1,33 @@
+#ifndef INTERNAL_PROC_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_PROC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Proc.
+ */
+#include "ruby/ruby.h" /* for rb_block_call_func_t */
+#include "ruby/st.h" /* for st_index_t */
+struct rb_block; /* in vm_core.h */
+struct rb_iseq_struct; /* in vm_core.h */
+
+/* proc.c */
+VALUE rb_proc_location(VALUE self);
+st_index_t rb_hash_proc(st_index_t hash, VALUE proc);
+int rb_block_pair_yield_optimizable(void);
+int rb_block_arity(void);
+int rb_block_min_max_arity(int *max);
+VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info);
+VALUE rb_callable_receiver(VALUE);
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val);
+VALUE rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc);
+VALUE rb_iseq_location(const struct rb_iseq_struct *iseq);
+VALUE rb_sym_to_proc(VALUE sym);
+MJIT_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_PROC_H */
diff --git a/internal/process.h b/internal/process.h
new file mode 100644
index 0000000000..904c9a5cea
--- /dev/null
+++ b/internal/process.h
@@ -0,0 +1,136 @@
+#ifndef INTERNAL_PROCESS_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_PROCESS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Process.
+ */
+#include "ruby/internal/config.h" /* for rb_pid_t */
+#include <stddef.h> /* for size_t */
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h> /* for mode_t */
+#endif
+
+#ifdef _WIN32
+# include "ruby/win32.h" /* for mode_t */
+#endif
+
+#include "ruby/ruby.h" /* for VALUE */
+#include "internal/imemo.h" /* for RB_IMEMO_TMPBUF_PTR */
+#include "internal/warnings.h" /* for COMPILER_WARNING_PUSH */
+
+#define RB_MAX_GROUPS (65536)
+
+struct waitpid_state;
+struct rb_execarg {
+ union {
+ struct {
+ VALUE shell_script;
+ } sh;
+ struct {
+ VALUE command_name;
+ VALUE command_abspath; /* full path string or nil */
+ VALUE argv_str;
+ VALUE argv_buf;
+ } cmd;
+ } invoke;
+ VALUE redirect_fds;
+ VALUE envp_str;
+ VALUE envp_buf;
+ VALUE dup2_tmpbuf;
+ unsigned use_shell : 1;
+ unsigned pgroup_given : 1;
+ unsigned umask_given : 1;
+ unsigned unsetenv_others_given : 1;
+ unsigned unsetenv_others_do : 1;
+ unsigned close_others_given : 1;
+ unsigned close_others_do : 1;
+ unsigned chdir_given : 1;
+ unsigned new_pgroup_given : 1;
+ unsigned new_pgroup_flag : 1;
+ unsigned uid_given : 1;
+ unsigned gid_given : 1;
+ unsigned exception : 1;
+ unsigned exception_given : 1;
+ struct waitpid_state *waitpid_state; /* for async process management */
+ rb_pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0<V). */
+ VALUE rlimit_limits; /* Qfalse or [[rtype, softlim, hardlim], ...] */
+ mode_t umask_mask;
+ rb_uid_t uid;
+ rb_gid_t gid;
+ int close_others_maxhint;
+ VALUE fd_dup2;
+ VALUE fd_close;
+ VALUE fd_open;
+ VALUE fd_dup2_child;
+ VALUE env_modification; /* Qfalse or [[k1,v1], ...] */
+ VALUE path_env;
+ VALUE chdir_dir;
+};
+
+/* process.c */
+rb_pid_t rb_fork_ruby(int *status);
+void rb_last_status_clear(void);
+static inline char **ARGVSTR2ARGV(VALUE argv_str);
+static inline size_t ARGVSTR2ARGC(VALUE argv_str);
+
+#ifdef HAVE_PWD_H
+VALUE rb_getlogin(void);
+VALUE rb_getpwdirnam_for_login(VALUE login); /* read as: "get pwd db home dir by username for login" */
+VALUE rb_getpwdiruid(void); /* read as: "get pwd db home dir for getuid()" */
+#endif
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* process.c (export) */
+int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen);
+rb_pid_t rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen);
+VALUE rb_execarg_new(int argc, const VALUE *argv, int accept_shell, int allow_exc_opt);
+struct rb_execarg *rb_execarg_get(VALUE execarg_obj); /* dangerous. needs GC guard. */
+int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val);
+void rb_execarg_parent_start(VALUE execarg_obj);
+void rb_execarg_parent_end(VALUE execarg_obj);
+int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char* errmsg, size_t errmsg_buflen);
+VALUE rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash);
+void rb_execarg_setenv(VALUE execarg_obj, VALUE env);
+RUBY_SYMBOL_EXPORT_END
+
+/* argv_str contains extra two elements.
+ * The beginning one is for /bin/sh used by exec_with_sh.
+ * The last one for terminating NULL used by execve.
+ * See rb_exec_fillarg() in process.c. */
+static inline char **
+ARGVSTR2ARGV(VALUE argv_str)
+{
+ char **buf = RB_IMEMO_TMPBUF_PTR(argv_str);
+ return &buf[1];
+}
+
+static inline size_t
+ARGVSTR2ARGC(VALUE argv_str)
+{
+ size_t i = 0;
+ char *const *p = ARGVSTR2ARGV(argv_str);
+ while (p[i++])
+ ;
+ return i - 1;
+}
+
+#ifdef HAVE_WORKING_FORK
+COMPILER_WARNING_PUSH
+#if __has_warning("-Wdeprecated-declarations") || RBIMPL_COMPILER_IS(GCC)
+COMPILER_WARNING_IGNORED(-Wdeprecated-declarations)
+#endif
+static inline rb_pid_t
+rb_fork(void)
+{
+ return fork();
+}
+COMPILER_WARNING_POP
+#endif
+
+#endif /* INTERNAL_PROCESS_H */
diff --git a/internal/random.h b/internal/random.h
new file mode 100644
index 0000000000..a92e65b8ba
--- /dev/null
+++ b/internal/random.h
@@ -0,0 +1,17 @@
+#ifndef INTERNAL_RANDOM_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_RANDOM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Random.
+ */
+#include <stddef.h> /* for size_t */
+
+/* random.c */
+int ruby_fill_random_bytes(void *, size_t, int);
+
+#endif /* INTERNAL_RANDOM_H */
diff --git a/internal/range.h b/internal/range.h
new file mode 100644
index 0000000000..4fe6037c89
--- /dev/null
+++ b/internal/range.h
@@ -0,0 +1,41 @@
+#ifndef INTERNAL_RANGE_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_RANGE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Range.
+ */
+#include "internal/struct.h" /* for RSTRUCT */
+
+/* range.c */
+static inline VALUE RANGE_BEG(VALUE r);
+static inline VALUE RANGE_END(VALUE r);
+static inline VALUE RANGE_EXCL(VALUE r);
+
+static inline VALUE
+RANGE_BEG(VALUE r)
+{
+ return RSTRUCT(r)->as.ary[0];
+}
+
+static inline VALUE
+RANGE_END(VALUE r)
+{
+ return RSTRUCT(r)->as.ary[1];
+}
+
+static inline VALUE
+RANGE_EXCL(VALUE r)
+{
+ return RSTRUCT(r)->as.ary[2];
+}
+
+VALUE
+rb_range_component_beg_len(VALUE b, VALUE e, int excl,
+ long *begp, long *lenp, long len, int err);
+
+#endif /* INTERNAL_RANGE_H */
diff --git a/internal/rational.h b/internal/rational.h
new file mode 100644
index 0000000000..6bbd2a9810
--- /dev/null
+++ b/internal/rational.h
@@ -0,0 +1,72 @@
+#ifndef INTERNAL_RATIONAL_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_RATIONAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Rational.
+ */
+#include "ruby/internal/config.h" /* for HAVE_LIBGMP */
+#include "ruby/ruby.h" /* for struct RBasic */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
+#include "internal/numeric.h" /* for INT_POSITIVE_P */
+#include "ruby_assert.h" /* for assert */
+
+struct RRational {
+ struct RBasic basic;
+ VALUE num;
+ VALUE den;
+};
+
+#define RRATIONAL(obj) ((struct RRational *)(obj))
+
+/* rational.c */
+VALUE rb_rational_canonicalize(VALUE x);
+VALUE rb_rational_uminus(VALUE self);
+VALUE rb_rational_plus(VALUE self, VALUE other);
+VALUE rb_rational_minus(VALUE self, VALUE other);
+VALUE rb_rational_mul(VALUE self, VALUE other);
+VALUE rb_rational_div(VALUE self, VALUE other);
+VALUE rb_lcm(VALUE x, VALUE y);
+VALUE rb_rational_reciprocal(VALUE x);
+VALUE rb_cstr_to_rat(const char *, int);
+VALUE rb_rational_hash(VALUE self);
+VALUE rb_rational_abs(VALUE self);
+VALUE rb_rational_cmp(VALUE self, VALUE other);
+VALUE rb_rational_pow(VALUE self, VALUE other);
+VALUE rb_rational_floor(VALUE self, int ndigits);
+VALUE rb_numeric_quo(VALUE x, VALUE y);
+VALUE rb_float_numerator(VALUE x);
+VALUE rb_float_denominator(VALUE x);
+
+static inline void RATIONAL_SET_NUM(VALUE r, VALUE n);
+static inline void RATIONAL_SET_DEN(VALUE r, VALUE d);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* rational.c (export) */
+VALUE rb_gcd(VALUE x, VALUE y);
+VALUE rb_gcd_normal(VALUE self, VALUE other);
+#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
+VALUE rb_gcd_gmp(VALUE x, VALUE y);
+#endif
+RUBY_SYMBOL_EXPORT_END
+
+static inline void
+RATIONAL_SET_NUM(VALUE r, VALUE n)
+{
+ assert(RB_INTEGER_TYPE_P(n));
+ RB_OBJ_WRITE(r, &RRATIONAL(r)->num, n);
+}
+
+static inline void
+RATIONAL_SET_DEN(VALUE r, VALUE d)
+{
+ assert(RB_INTEGER_TYPE_P(d));
+ assert(INT_POSITIVE_P(d));
+ RB_OBJ_WRITE(r, &RRATIONAL(r)->den, d);
+}
+
+#endif /* INTERNAL_RATIONAL_H */
diff --git a/internal/re.h b/internal/re.h
new file mode 100644
index 0000000000..28fa3fb51c
--- /dev/null
+++ b/internal/re.h
@@ -0,0 +1,29 @@
+#ifndef INTERNAL_RE_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_RE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Regexp.
+ */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/ruby.h" /* for VALUE */
+
+/* re.c */
+VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
+VALUE rb_reg_check_preprocess(VALUE);
+long rb_reg_search0(VALUE, VALUE, long, int, int);
+VALUE rb_reg_match_p(VALUE re, VALUE str, long pos);
+bool rb_reg_start_with_p(VALUE re, VALUE str);
+void rb_backref_set_string(VALUE string, long pos, long len);
+void rb_match_unbusy(VALUE);
+int rb_match_count(VALUE match);
+int rb_match_nth_defined(int nth, VALUE match);
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_reg_new_ary(VALUE ary, int options);
+MJIT_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_RE_H */
diff --git a/internal/sanitizers.h b/internal/sanitizers.h
new file mode 100644
index 0000000000..b4f5bdeda1
--- /dev/null
+++ b/internal/sanitizers.h
@@ -0,0 +1,191 @@
+#ifndef INTERNAL_SANITIZERS_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_SANITIZERS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for ASAN / MSAN / etc.
+ */
+#include "ruby/internal/config.h"
+#include "internal/compilers.h" /* for __has_feature */
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+#endif
+
+#ifdef HAVE_SANITIZER_ASAN_INTERFACE_H
+# include <sanitizer/asan_interface.h>
+#endif
+
+#ifdef HAVE_SANITIZER_MSAN_INTERFACE_H
+# if __has_feature(memory_sanitizer)
+# include <sanitizer/msan_interface.h>
+# endif
+#endif
+
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/ruby.h" /* for VALUE */
+
+#if 0
+#elif __has_feature(memory_sanitizer) && __has_feature(address_sanitizer)
+# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
+ __attribute__((__no_sanitize__("memory, address"), __noinline__)) x
+#elif __has_feature(address_sanitizer)
+# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
+ __attribute__((__no_sanitize__("address"), __noinline__)) x
+#elif defined(NO_SANITIZE_ADDRESS)
+# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
+ NO_SANITIZE_ADDRESS(NOINLINE(x))
+#elif defined(NO_ADDRESS_SAFETY_ANALYSIS)
+# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
+ NO_ADDRESS_SAFETY_ANALYSIS(NOINLINE(x))
+#else
+# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) x
+#endif
+
+#if defined(NO_SANITIZE) && RBIMPL_COMPILER_IS(GCC)
+/* GCC warns about unknown sanitizer, which is annoying. */
+# include "internal/warnings.h"
+# undef NO_SANITIZE
+# define NO_SANITIZE(x, y) \
+ COMPILER_WARNING_PUSH; \
+ COMPILER_WARNING_IGNORED(-Wattributes); \
+ __attribute__((__no_sanitize__(x))) y; \
+ COMPILER_WARNING_POP
+#endif
+
+#ifndef NO_SANITIZE
+# define NO_SANITIZE(x, y) y
+#endif
+
+#if !__has_feature(address_sanitizer)
+# define __asan_poison_memory_region(x, y)
+# define __asan_unpoison_memory_region(x, y)
+# define __asan_region_is_poisoned(x, y) 0
+#endif
+
+#if !__has_feature(memory_sanitizer)
+# define __msan_allocated_memory(x, y) ((void)(x), (void)(y))
+# define __msan_poison(x, y) ((void)(x), (void)(y))
+# define __msan_unpoison(x, y) ((void)(x), (void)(y))
+# define __msan_unpoison_string(x) ((void)(x))
+#endif
+
+#ifdef VALGRIND_MAKE_READABLE
+# define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
+#endif
+
+#ifdef VALGRIND_MAKE_WRITABLE
+# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
+#endif
+
+#ifndef VALGRIND_MAKE_MEM_DEFINED
+# define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
+#endif
+
+#ifndef VALGRIND_MAKE_MEM_UNDEFINED
+# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
+#endif
+
+#ifndef MJIT_HEADER
+
+/*!
+ * This function asserts that a (continuous) memory region from ptr to size
+ * being "poisoned". Both read / write access to such memory region are
+ * prohibited until properly unpoisoned. The region must be previously
+ * allocated (do not pass a freed pointer here), but not necessarily be an
+ * entire object that the malloc returns. You can punch hole a part of a
+ * gigantic heap arena. This is handy when you do not free an allocated memory
+ * region to reuse later: poison when you keep it unused, and unpoison when you
+ * reuse.
+ *
+ * \param[in] ptr pointer to the beginning of the memory region to poison.
+ * \param[in] size the length of the memory region to poison.
+ */
+static inline void
+asan_poison_memory_region(const volatile void *ptr, size_t size)
+{
+ __msan_poison(ptr, size);
+ __asan_poison_memory_region(ptr, size);
+}
+
+/*!
+ * This is a variant of asan_poison_memory_region that takes a VALUE.
+ *
+ * \param[in] obj target object.
+ */
+static inline void
+asan_poison_object(VALUE obj)
+{
+ MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj;
+ asan_poison_memory_region(ptr, SIZEOF_VALUE);
+}
+
+#if !__has_feature(address_sanitizer)
+#define asan_poison_object_if(ptr, obj) ((void)(ptr), (void)(obj))
+#else
+#define asan_poison_object_if(ptr, obj) do { \
+ if (ptr) asan_poison_object(obj); \
+ } while (0)
+#endif
+
+/*!
+ * This function predicates if the given object is fully addressable or not.
+ *
+ * \param[in] obj target object.
+ * \retval 0 the given object is fully addressable.
+ * \retval otherwise pointer to first such byte who is poisoned.
+ */
+static inline void *
+asan_poisoned_object_p(VALUE obj)
+{
+ MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj;
+ return __asan_region_is_poisoned(ptr, SIZEOF_VALUE);
+}
+
+/*!
+ * This function asserts that a (formally poisoned) memory region from ptr to
+ * size is now addressable. Write access to such memory region gets allowed.
+ * However read access might or might not be possible depending on situations,
+ * because the region can have contents of previous usages. That information
+ * should be passed by the malloc_p flag. If that is true, the contents of the
+ * region is _not_ fully defined (like the return value of malloc behaves).
+ * Reading from there is NG; write something first. If malloc_p is false on
+ * the other hand, that memory region is fully defined and can be read
+ * immediately.
+ *
+ * \param[in] ptr pointer to the beginning of the memory region to unpoison.
+ * \param[in] size the length of the memory region.
+ * \param[in] malloc_p if the memory region is like a malloc's return value or not.
+ */
+static inline void
+asan_unpoison_memory_region(const volatile void *ptr, size_t size, bool malloc_p)
+{
+ __asan_unpoison_memory_region(ptr, size);
+ if (malloc_p) {
+ __msan_allocated_memory(ptr, size);
+ }
+ else {
+ __msan_unpoison(ptr, size);
+ }
+}
+
+/*!
+ * This is a variant of asan_unpoison_memory_region that takes a VALUE.
+ *
+ * \param[in] obj target object.
+ * \param[in] malloc_p if the memory region is like a malloc's return value or not.
+ */
+static inline void
+asan_unpoison_object(VALUE obj, bool newobj_p)
+{
+ MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj;
+ asan_unpoison_memory_region(ptr, SIZEOF_VALUE, newobj_p);
+}
+
+#endif /* MJIT_HEADER */
+
+#endif /* INTERNAL_SANITIZERS_H */
diff --git a/internal/scheduler.h b/internal/scheduler.h
new file mode 100644
index 0000000000..8314020220
--- /dev/null
+++ b/internal/scheduler.h
@@ -0,0 +1,44 @@
+#ifndef RUBY_SCHEDULER_H /*-*-C-*-vi:se ft=c:*/
+#define RUBY_SCHEDULER_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Scheduler.
+ */
+#include "ruby/ruby.h"
+#include "ruby/intern.h"
+
+VALUE rb_scheduler_get();
+VALUE rb_scheduler_set(VALUE scheduler);
+
+VALUE rb_scheduler_current();
+VALUE rb_thread_scheduler_current(VALUE thread);
+
+VALUE rb_scheduler_timeout(struct timeval *timeout);
+
+VALUE rb_scheduler_close(VALUE scheduler);
+
+VALUE rb_scheduler_kernel_sleep(VALUE scheduler, VALUE duration);
+VALUE rb_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv);
+
+int rb_scheduler_supports_process_wait(VALUE scheduler);
+VALUE rb_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags);
+
+VALUE rb_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout);
+VALUE rb_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);
+
+VALUE rb_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout);
+VALUE rb_scheduler_io_wait_readable(VALUE scheduler, VALUE io);
+VALUE rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io);
+
+int rb_scheduler_supports_io_read(VALUE scheduler);
+VALUE rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length);
+
+int rb_scheduler_supports_io_write(VALUE scheduler);
+VALUE rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length);
+
+#endif /* RUBY_SCHEDULER_H */
diff --git a/internal/serial.h b/internal/serial.h
new file mode 100644
index 0000000000..977cb35477
--- /dev/null
+++ b/internal/serial.h
@@ -0,0 +1,24 @@
+#ifndef INTERNAL_SERIAL_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_SERIAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for rb_serial_t.
+ */
+#include "ruby/internal/config.h" /* for HAVE_LONG_LONG */
+#include "ruby/defines.h" /* for LONG_LONG */
+
+#ifndef HAVE_LONG_LONG
+# error need C99+
+#endif
+
+typedef unsigned LONG_LONG rb_serial_t;
+#define SERIALT2NUM ULL2NUM
+#define PRI_SERIALT_PREFIX PRI_LL_PREFIX
+#define SIZEOF_SERIAL_T SIZEOF_LONG_LONG
+
+#endif /* INTERNAL_SERIAL_H */
diff --git a/internal/signal.h b/internal/signal.h
new file mode 100644
index 0000000000..6b4672f15b
--- /dev/null
+++ b/internal/signal.h
@@ -0,0 +1,22 @@
+#ifndef INTERNAL_SIGNAL_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_SIGNAL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for SignalException.
+ */
+
+/* signal.c */
+extern int ruby_enable_coredump;
+int rb_get_next_signal(void);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* signal.c (export) */
+int rb_grantpt(int fd);
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_SIGNAL_H */
diff --git a/internal/static_assert.h b/internal/static_assert.h
new file mode 100644
index 0000000000..284e410313
--- /dev/null
+++ b/internal/static_assert.h
@@ -0,0 +1,17 @@
+#ifndef INTERNAL_STATIC_ASSERT_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_STATIC_ASSERT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief C11 shim for _Static_assert.
+ */
+#include "ruby/internal/static_assert.h"
+#ifndef STATIC_ASSERT
+# define STATIC_ASSERT RBIMPL_STATIC_ASSERT
+#endif
+
+#endif /* INTERNAL_STATIC_ASSERT_H */
diff --git a/internal/string.h b/internal/string.h
new file mode 100644
index 0000000000..adc8385cb6
--- /dev/null
+++ b/internal/string.h
@@ -0,0 +1,141 @@
+#ifndef INTERNAL_STRING_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_STRING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for String.
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "internal/compilers.h" /* for __has_builtin */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/encoding.h" /* for rb_encoding */
+#include "ruby/ruby.h" /* for VALUE */
+
+#define STR_NOEMBED FL_USER1
+#define STR_SHARED FL_USER2 /* = ELTS_SHARED */
+
+#ifdef rb_fstring_cstr
+# undef rb_fstring_cstr
+#endif
+
+/* string.c */
+VALUE rb_fstring(VALUE);
+VALUE rb_fstring_cstr(const char *str);
+VALUE rb_fstring_enc_new(const char *ptr, long len, rb_encoding *enc);
+int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
+int rb_str_symname_p(VALUE);
+VALUE rb_str_quote_unprintable(VALUE);
+char *rb_str_fill_terminator(VALUE str, const int termlen);
+void rb_str_change_terminator_length(VALUE str, const int oldtermlen, const int termlen);
+VALUE rb_str_locktmp_ensure(VALUE str, VALUE (*func)(VALUE), VALUE arg);
+VALUE rb_str_chomp_string(VALUE str, VALUE chomp);
+VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
+VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
+ rb_encoding *from, int ecflags, VALUE ecopts);
+VALUE rb_enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl);
+VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc);
+size_t rb_str_memsize(VALUE);
+char *rb_str_to_cstr(VALUE str);
+const char *ruby_escaped_char(int c);
+void rb_str_make_independent(VALUE str);
+int rb_enc_str_coderange_scan(VALUE str, rb_encoding *enc);
+
+static inline bool STR_EMBED_P(VALUE str);
+static inline bool STR_SHARED_P(VALUE str);
+static inline VALUE QUOTE(VALUE v);
+static inline VALUE QUOTE_ID(ID v);
+static inline bool is_ascii_string(VALUE str);
+static inline bool is_broken_string(VALUE str);
+static inline VALUE rb_str_eql_internal(const VALUE str1, const VALUE str2);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* string.c (export) */
+VALUE rb_str_tmp_frozen_acquire(VALUE str);
+void rb_str_tmp_frozen_release(VALUE str, VALUE tmp);
+VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc);
+VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE);
+VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_fstring_new(const char *ptr, long len);
+VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
+VALUE rb_str_opt_plus(VALUE x, VALUE y);
+VALUE rb_str_concat_literals(size_t num, const VALUE *strary);
+VALUE rb_str_eql(VALUE str1, VALUE str2);
+VALUE rb_id_quote_unprintable(ID);
+VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed_proc);
+
+struct rb_execution_context_struct;
+VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str);
+MJIT_SYMBOL_EXPORT_END
+
+#define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str))
+#define rb_fstring_literal(str) rb_fstring_lit(str)
+#define rb_fstring_enc_lit(str, enc) rb_fstring_enc_new((str), rb_strlen_lit(str), (enc))
+#define rb_fstring_enc_literal(str, enc) rb_fstring_enc_lit(str, enc)
+
+static inline VALUE
+QUOTE(VALUE v)
+{
+ return rb_str_quote_unprintable(v);
+}
+
+static inline VALUE
+QUOTE_ID(ID i)
+{
+ return rb_id_quote_unprintable(i);
+}
+
+static inline bool
+STR_EMBED_P(VALUE str)
+{
+ return ! FL_TEST_RAW(str, STR_NOEMBED);
+}
+
+static inline bool
+STR_SHARED_P(VALUE str)
+{
+ return FL_ALL_RAW(str, STR_NOEMBED | ELTS_SHARED);
+}
+
+static inline bool
+is_ascii_string(VALUE str)
+{
+ return rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT;
+}
+
+static inline bool
+is_broken_string(VALUE str)
+{
+ return rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN;
+}
+
+/* expect tail call optimization */
+static inline VALUE
+rb_str_eql_internal(const VALUE str1, const VALUE str2)
+{
+ const long len = RSTRING_LEN(str1);
+ const char *ptr1, *ptr2;
+
+ if (len != RSTRING_LEN(str2)) return Qfalse;
+ if (!rb_str_comparable(str1, str2)) return Qfalse;
+ if ((ptr1 = RSTRING_PTR(str1)) == (ptr2 = RSTRING_PTR(str2)))
+ return Qtrue;
+ if (memcmp(ptr1, ptr2, len) == 0)
+ return Qtrue;
+ return Qfalse;
+}
+
+#if __has_builtin(__builtin_constant_p)
+# define rb_fstring_cstr(str) \
+ (__builtin_constant_p(str) ? \
+ rb_fstring_new((str), (long)strlen(str)) : \
+ (rb_fstring_cstr)(str))
+#endif
+#endif /* INTERNAL_STRING_H */
diff --git a/internal/struct.h b/internal/struct.h
new file mode 100644
index 0000000000..82b2738b69
--- /dev/null
+++ b/internal/struct.h
@@ -0,0 +1,154 @@
+#ifndef INTERNAL_STRUCT_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_STRUCT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Struct.
+ */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
+#include "ruby/ruby.h" /* for struct RBasic */
+
+enum {
+ RSTRUCT_EMBED_LEN_MAX = RVALUE_EMBED_LEN_MAX,
+ RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
+ RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
+ RSTRUCT_TRANSIENT_FLAG = FL_USER3,
+};
+
+struct RStruct {
+ struct RBasic basic;
+ union {
+ struct {
+ long len;
+ const VALUE *ptr;
+ } heap;
+ const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
+ } as;
+};
+
+#define RSTRUCT(obj) ((struct RStruct *)(obj))
+
+#ifdef RSTRUCT_LEN
+# undef RSTRUCT_LEN
+#endif
+
+#ifdef RSTRUCT_PTR
+# undef RSTRUCT_PTR
+#endif
+
+#ifdef RSTRUCT_SET
+# undef RSTRUCT_SET
+#endif
+
+#ifdef RSTRUCT_GET
+# undef RSTRUCT_GET
+#endif
+
+#define RSTRUCT_LEN internal_RSTRUCT_LEN
+#define RSTRUCT_SET internal_RSTRUCT_SET
+#define RSTRUCT_GET internal_RSTRUCT_GET
+
+/* struct.c */
+VALUE rb_struct_init_copy(VALUE copy, VALUE s);
+VALUE rb_struct_lookup(VALUE s, VALUE idx);
+VALUE rb_struct_s_keyword_init(VALUE klass);
+static inline const VALUE *rb_struct_const_heap_ptr(VALUE st);
+static inline bool RSTRUCT_TRANSIENT_P(VALUE st);
+static inline void RSTRUCT_TRANSIENT_SET(VALUE st);
+static inline void RSTRUCT_TRANSIENT_UNSET(VALUE st);
+static inline long RSTRUCT_EMBED_LEN(VALUE st);
+static inline long RSTRUCT_LEN(VALUE st);
+static inline int RSTRUCT_LENINT(VALUE st);
+static inline const VALUE *RSTRUCT_CONST_PTR(VALUE st);
+static inline void RSTRUCT_SET(VALUE st, long k, VALUE v);
+static inline VALUE RSTRUCT_GET(VALUE st, long k);
+
+static inline bool
+RSTRUCT_TRANSIENT_P(VALUE st)
+{
+#if USE_TRANSIENT_HEAP
+ return FL_TEST_RAW(st, RSTRUCT_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+static inline void
+RSTRUCT_TRANSIENT_SET(VALUE st)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+RSTRUCT_TRANSIENT_UNSET(VALUE st)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
+#endif
+}
+
+static inline long
+RSTRUCT_EMBED_LEN(VALUE st)
+{
+ long ret = FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK);
+ ret >>= RSTRUCT_EMBED_LEN_SHIFT;
+ return ret;
+}
+
+static inline long
+RSTRUCT_LEN(VALUE st)
+{
+ if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
+ return RSTRUCT_EMBED_LEN(st);
+ }
+ else {
+ return RSTRUCT(st)->as.heap.len;
+ }
+}
+
+static inline int
+RSTRUCT_LENINT(VALUE st)
+{
+ return rb_long2int(RSTRUCT_LEN(st));
+}
+
+static inline const VALUE *
+RSTRUCT_CONST_PTR(VALUE st)
+{
+ const struct RStruct *p = RSTRUCT(st);
+
+ if (FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
+ return p->as.ary;
+ }
+ else {
+ return p->as.heap.ptr;
+ }
+}
+
+static inline void
+RSTRUCT_SET(VALUE st, long k, VALUE v)
+{
+ RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[k], v);
+}
+
+static inline VALUE
+RSTRUCT_GET(VALUE st, long k)
+{
+ return RSTRUCT_CONST_PTR(st)[k];
+}
+
+static inline const VALUE *
+rb_struct_const_heap_ptr(VALUE st)
+{
+ /* TODO: check embed on debug mode */
+ return RSTRUCT(st)->as.heap.ptr;
+}
+
+#endif /* INTERNAL_STRUCT_H */
diff --git a/internal/symbol.h b/internal/symbol.h
new file mode 100644
index 0000000000..691df66228
--- /dev/null
+++ b/internal/symbol.h
@@ -0,0 +1,41 @@
+#ifndef INTERNAL_SYMBOL_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_SYMBOL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Symbol.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+#include "ruby/encoding.h" /* for rb_encoding */
+#include "internal/compilers.h" /* for __has_builtin */
+
+#ifdef rb_sym_intern_ascii_cstr
+# undef rb_sym_intern_ascii_cstr
+#endif
+
+/* symbol.c */
+VALUE rb_to_symbol_type(VALUE obj);
+VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc);
+VALUE rb_sym_intern_ascii(const char *ptr, long len);
+VALUE rb_sym_intern_ascii_cstr(const char *ptr);
+int rb_is_const_name(VALUE name);
+int rb_is_class_name(VALUE name);
+int rb_is_instance_name(VALUE name);
+int rb_is_local_name(VALUE name);
+PUREFUNC(int rb_is_const_sym(VALUE sym));
+PUREFUNC(int rb_is_attrset_sym(VALUE sym));
+ID rb_make_internal_id(void);
+void rb_gc_free_dsymbol(VALUE);
+
+#if __has_builtin(__builtin_constant_p)
+#define rb_sym_intern_ascii_cstr(ptr) \
+ (__builtin_constant_p(ptr) ? \
+ rb_sym_intern_ascii((ptr), (long)strlen(ptr)) : \
+ rb_sym_intern_ascii_cstr(ptr))
+#endif
+
+#endif /* INTERNAL_SYMBOL_H */
diff --git a/internal/thread.h b/internal/thread.h
new file mode 100644
index 0000000000..09b8551b5c
--- /dev/null
+++ b/internal/thread.h
@@ -0,0 +1,54 @@
+#ifndef INTERNAL_THREAD_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_THREAD_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Thread.
+ */
+#include "ruby/ruby.h" /* for VALUE */
+#include "ruby/intern.h" /* for rb_blocking_function_t */
+
+struct rb_thread_struct; /* in vm_core.h */
+
+/* thread.c */
+#define COVERAGE_INDEX_LINES 0
+#define COVERAGE_INDEX_BRANCHES 1
+#define COVERAGE_TARGET_LINES 1
+#define COVERAGE_TARGET_BRANCHES 2
+#define COVERAGE_TARGET_METHODS 4
+#define COVERAGE_TARGET_ONESHOT_LINES 8
+
+VALUE rb_obj_is_mutex(VALUE obj);
+VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
+void rb_thread_execute_interrupts(VALUE th);
+VALUE rb_get_coverages(void);
+int rb_get_coverage_mode(void);
+VALUE rb_default_coverage(int);
+VALUE rb_thread_shield_new(void);
+VALUE rb_thread_shield_wait(VALUE self);
+VALUE rb_thread_shield_release(VALUE self);
+VALUE rb_thread_shield_destroy(VALUE self);
+int rb_thread_to_be_killed(VALUE thread);
+void rb_mutex_allow_trap(VALUE self, int val);
+VALUE rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data);
+VALUE rb_mutex_owned_p(VALUE self);
+
+int rb_thread_wait_for_single_fd(int fd, int events, struct timeval * timeout);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* Temporary. This API will be removed (renamed). */
+VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
+
+/* thread.c (export) */
+int ruby_thread_has_gvl_p(void); /* for ext/fiddle/closure.c */
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+int rb_threadptr_execute_interrupts(struct rb_thread_struct *th, int blocking_timing);
+MJIT_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_THREAD_H */
diff --git a/internal/time.h b/internal/time.h
new file mode 100644
index 0000000000..f9ac084603
--- /dev/null
+++ b/internal/time.h
@@ -0,0 +1,35 @@
+#ifndef INTERNAL_TIME_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_TIME_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Time.
+ */
+#include "ruby/internal/config.h" /* for SIGNEDNESS_OF_TIME_T */
+#include "internal/bits.h" /* for SIGNED_INTEGER_MAX */
+#include "ruby/ruby.h" /* for VALUE */
+
+#if SIGNEDNESS_OF_TIME_T < 0 /* signed */
+# define TIMET_MAX SIGNED_INTEGER_MAX(time_t)
+# define TIMET_MIN SIGNED_INTEGER_MIN(time_t)
+#elif SIGNEDNESS_OF_TIME_T > 0 /* unsigned */
+# define TIMET_MAX UNSIGNED_INTEGER_MAX(time_t)
+# define TIMET_MIN ((time_t)0)
+#endif
+
+struct timeval; /* <- in <sys/time.h> or <winsock2.h> */
+
+/* time.c */
+struct timeval rb_time_timeval(VALUE);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* time.c (export) */
+void ruby_reset_leap_second_info(void);
+void ruby_reset_timezone(void);
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_TIME_H */
diff --git a/internal/transcode.h b/internal/transcode.h
new file mode 100644
index 0000000000..a60ac06d10
--- /dev/null
+++ b/internal/transcode.h
@@ -0,0 +1,21 @@
+#ifndef INTERNAL_TRANSCODE_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_TRANSCODE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for Encoding::Converter.
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "ruby/ruby.h" /* for VALUE */
+#include "ruby/encoding.h" /* for rb_econv_t */
+
+/* transcode.c */
+extern VALUE rb_cEncodingConverter;
+size_t rb_econv_memsize(rb_econv_t *);
+
+#endif /* INTERNAL_TRANSCODE_H */
diff --git a/internal/util.h b/internal/util.h
new file mode 100644
index 0000000000..c28b884d32
--- /dev/null
+++ b/internal/util.h
@@ -0,0 +1,31 @@
+#ifndef INTERNAL_UTIL_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_UTIL_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header corresponding util.c.
+ * @warning DO NOT ADD RANDOM GARBAGE HERE THIS FILE IS FOR util.c
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h> /* for ssize_t (note: on Windows ssize_t is */
+#endif /* `#define`d in ruby/config.h) */
+
+/* util.c */
+char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
+char *ruby_hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* util.c (export) */
+extern const signed char ruby_digit36_to_number_table[];
+extern const char ruby_hexdigits[];
+extern unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* INTERNAL_UTIL_H */
diff --git a/internal/variable.h b/internal/variable.h
new file mode 100644
index 0000000000..057beccfcc
--- /dev/null
+++ b/internal/variable.h
@@ -0,0 +1,84 @@
+#ifndef INTERNAL_VARIABLE_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_VARIABLE_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for variables.
+ */
+#include "ruby/internal/config.h"
+#include <stddef.h> /* for size_t */
+#include "constant.h" /* for rb_const_entry_t */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "ruby/ruby.h" /* for VALUE */
+
+/* global variable */
+
+#define ROBJECT_TRANSIENT_FLAG FL_USER13
+
+/* variable.c */
+void rb_gc_mark_global_tbl(void);
+void rb_gc_update_global_tbl(void);
+size_t rb_generic_ivar_memsize(VALUE);
+VALUE rb_search_class_path(VALUE);
+VALUE rb_attr_delete(VALUE, ID);
+VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
+void rb_autoload_str(VALUE mod, ID id, VALUE file);
+VALUE rb_autoload_at_p(VALUE, ID, int);
+NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
+rb_gvar_getter_t *rb_gvar_getter_function_of(ID);
+rb_gvar_setter_t *rb_gvar_setter_function_of(ID);
+void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_);
+void rb_gvar_ractor_local(const char *name);
+static inline bool ROBJ_TRANSIENT_P(VALUE obj);
+static inline void ROBJ_TRANSIENT_SET(VALUE obj);
+static inline void ROBJ_TRANSIENT_UNSET(VALUE obj);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+/* variable.c (export) */
+void rb_mark_generic_ivar(VALUE);
+void rb_mv_generic_ivar(VALUE src, VALUE dst);
+VALUE rb_const_missing(VALUE klass, VALUE name);
+int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
+void rb_iv_tbl_copy(VALUE dst, VALUE src);
+void rb_deprecate_constant(VALUE mod, const char *name);
+RUBY_SYMBOL_EXPORT_END
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_gvar_get(ID);
+VALUE rb_gvar_set(ID, VALUE);
+VALUE rb_gvar_defined(ID);
+void rb_const_warn_if_deprecated(const rb_const_entry_t *, VALUE, ID);
+void rb_init_iv_list(VALUE obj);
+MJIT_SYMBOL_EXPORT_END
+
+static inline bool
+ROBJ_TRANSIENT_P(VALUE obj)
+{
+#if USE_TRANSIENT_HEAP
+ return FL_TEST_RAW(obj, ROBJECT_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+static inline void
+ROBJ_TRANSIENT_SET(VALUE obj)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(obj, ROBJECT_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+ROBJ_TRANSIENT_UNSET(VALUE obj)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(obj, ROBJECT_TRANSIENT_FLAG);
+#endif
+}
+
+#endif /* INTERNAL_VARIABLE_H */
diff --git a/internal/vm.h b/internal/vm.h
new file mode 100644
index 0000000000..689b4fa61f
--- /dev/null
+++ b/internal/vm.h
@@ -0,0 +1,131 @@
+#ifndef INTERNAL_VM_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_VM_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header for RubyVM.
+ */
+#include "ruby/internal/stdbool.h" /* for bool */
+#include "internal/serial.h" /* for rb_serial_t */
+#include "internal/static_assert.h" /* for STATIC_ASSERT */
+#include "ruby/ruby.h" /* for ID */
+#include "ruby/st.h" /* for st_table */
+
+#ifdef rb_funcallv
+# undef rb_funcallv
+#endif
+
+#ifdef rb_method_basic_definition_p
+# undef rb_method_basic_definition_p
+#endif
+
+struct rb_callable_method_entry_struct; /* in method.h */
+struct rb_method_definition_struct; /* in method.h */
+struct rb_execution_context_struct; /* in vm_core.h */
+struct rb_control_frame_struct; /* in vm_core.h */
+struct rb_callinfo; /* in vm_core.h */
+
+enum method_missing_reason {
+ MISSING_NOENTRY = 0x00,
+ MISSING_PRIVATE = 0x01,
+ MISSING_PROTECTED = 0x02,
+ MISSING_FCALL = 0x04,
+ MISSING_VCALL = 0x08,
+ MISSING_SUPER = 0x10,
+ MISSING_MISSING = 0x20,
+ MISSING_NONE = 0x40
+};
+
+/* vm_insnhelper.h */
+rb_serial_t rb_next_class_serial(void);
+
+/* vm.c */
+VALUE rb_obj_is_thread(VALUE obj);
+void rb_vm_mark(void *ptr);
+void rb_vm_each_stack_value(void *ptr, void (*cb)(VALUE, void*), void *ctx);
+PUREFUNC(VALUE rb_vm_top_self(void));
+void rb_vm_inc_const_missing_count(void);
+const void **rb_vm_get_insns_address_table(void);
+VALUE rb_source_location(int *pline);
+const char *rb_source_location_cstr(int *pline);
+MJIT_STATIC void rb_vm_pop_cfunc_frame(void);
+int rb_vm_add_root_module(VALUE module);
+void rb_vm_check_redefinition_by_prepend(VALUE klass);
+int rb_vm_check_optimizable_mid(VALUE mid);
+VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
+MJIT_STATIC VALUE ruby_vm_special_exception_copy(VALUE);
+PUREFUNC(st_table *rb_vm_fstring_table(void));
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE vm_exec(struct rb_execution_context_struct *, bool); /* used in JIT-ed code */
+MJIT_SYMBOL_EXPORT_END
+
+/* vm_eval.c */
+VALUE rb_current_realfilepath(void);
+VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE);
+typedef void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE);
+VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
+ rb_check_funcall_hook *hook, VALUE arg);
+VALUE rb_check_funcall_with_hook_kw(VALUE recv, ID mid, int argc, const VALUE *argv,
+ rb_check_funcall_hook *hook, VALUE arg, int kw_splat);
+const char *rb_type_str(enum ruby_value_type type);
+VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE);
+VALUE rb_check_funcall_basic_kw(VALUE, ID, VALUE, int, const VALUE*, int);
+VALUE rb_yield_1(VALUE val);
+VALUE rb_yield_force_blockarg(VALUE values);
+VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
+ rb_block_call_func_t bl_proc, int min_argc, int max_argc,
+ VALUE data2);
+void rb_check_stack_overflow(void);
+
+/* vm_insnhelper.c */
+VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
+VALUE rb_eql_opt(VALUE obj1, VALUE obj2);
+
+struct rb_iseq_struct;
+MJIT_SYMBOL_EXPORT_BEGIN
+const struct rb_callcache *rb_vm_search_method_slowpath(const struct rb_callinfo *ci, VALUE klass);
+MJIT_SYMBOL_EXPORT_END
+
+/* vm_method.c */
+struct rb_execution_context_struct;
+MJIT_SYMBOL_EXPORT_BEGIN
+int rb_ec_obj_respond_to(struct rb_execution_context_struct *ec, VALUE obj, ID id, int priv);
+MJIT_SYMBOL_EXPORT_END
+
+/* vm_dump.c */
+void rb_print_backtrace(void);
+
+/* vm_backtrace.c */
+VALUE rb_vm_thread_backtrace(int argc, const VALUE *argv, VALUE thval);
+VALUE rb_vm_thread_backtrace_locations(int argc, const VALUE *argv, VALUE thval);
+VALUE rb_vm_backtrace(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
+VALUE rb_vm_backtrace_locations(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
+VALUE rb_make_backtrace(void);
+void rb_backtrace_print_as_bugreport(void);
+int rb_backtrace_p(VALUE obj);
+VALUE rb_backtrace_to_str_ary(VALUE obj);
+VALUE rb_backtrace_to_location_ary(VALUE obj);
+void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output);
+
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_ec_backtrace_object(const struct rb_execution_context_struct *ec);
+void rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self);
+MJIT_SYMBOL_EXPORT_END
+
+#define RUBY_DTRACE_CREATE_HOOK(name, arg) \
+ RUBY_DTRACE_HOOK(name##_CREATE, arg)
+#define RUBY_DTRACE_HOOK(name, arg) \
+do { \
+ if (UNLIKELY(RUBY_DTRACE_##name##_ENABLED())) { \
+ int dtrace_line; \
+ const char *dtrace_file = rb_source_location_cstr(&dtrace_line); \
+ if (!dtrace_file) dtrace_file = ""; \
+ RUBY_DTRACE_##name(arg, dtrace_file, dtrace_line); \
+ } \
+} while (0)
+#endif /* INTERNAL_VM_H */
diff --git a/internal/warnings.h b/internal/warnings.h
new file mode 100644
index 0000000000..63ded99d04
--- /dev/null
+++ b/internal/warnings.h
@@ -0,0 +1,17 @@
+#ifndef INTERNAL_WARNINGS_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_WARNINGS_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Internal header to suppres / mandate warnings.
+ */
+#include "ruby/internal/warning_push.h"
+#define COMPILER_WARNING_PUSH RBIMPL_WARNING_PUSH()
+#define COMPILER_WARNING_POP RBIMPL_WARNING_POP()
+#define COMPILER_WARNING_ERROR(flag) RBIMPL_WARNING_ERROR(flag)
+#define COMPILER_WARNING_IGNORED(flag) RBIMPL_WARNING_IGNORED(flag)
+#endif /* INTERNAL_WARNINGS_H */
diff --git a/io.c b/io.c
index 3000e94d9a..caa4dd28f7 100644
--- a/io.c
+++ b/io.c
@@ -11,15 +11,32 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/io.h"
-#include "ruby/thread.h"
-#include "dln.h"
-#include "encindex.h"
-#include "id.h"
+#include "ruby/internal/config.h"
+
+#include "internal/scheduler.h"
+
+#ifdef _WIN32
+# include "ruby/ruby.h"
+# include "ruby/io.h"
+#endif
+
#include <ctype.h>
#include <errno.h>
-#include "ruby_atomic.h"
+#include <stddef.h>
+
+/* non-Linux poll may not work on all FDs */
+#if defined(HAVE_POLL)
+# if defined(__linux__)
+# define USE_POLL 1
+# endif
+# if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000
+# define USE_POLL 1
+# endif
+#endif
+
+#ifndef USE_POLL
+# define USE_POLL 0
+#endif
#undef free
#define free(x) xfree(x)
@@ -44,7 +61,7 @@
#endif
#ifdef __QNXNTO__
-#include "unix.h"
+#include <unix.h>
#endif
#include <sys/types.h>
@@ -93,7 +110,37 @@
# include <sys/wait.h> /* for WNOHANG on BSD */
#endif
+#ifdef HAVE_COPYFILE_H
+# include <copyfile.h>
+#endif
+
+#include "ruby/internal/stdbool.h"
+#include "ccan/list/list.h"
+#include "dln.h"
+#include "encindex.h"
+#include "id.h"
+#include "internal.h"
+#include "internal/encoding.h"
+#include "internal/error.h"
+#include "internal/inits.h"
+#include "internal/io.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/process.h"
+#include "internal/thread.h"
+#include "internal/transcode.h"
+#include "internal/variable.h"
+#include "ruby/io.h"
+#include "ruby/thread.h"
#include "ruby/util.h"
+#include "ruby_atomic.h"
+#include "ruby/ractor.h"
+
+#if !USE_POLL
+# include "vm_core.h"
+#endif
+
+#include "builtin.h"
#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
@@ -120,13 +167,6 @@
off_t __syscall(quad_t number, ...);
#endif
-#ifdef __native_client__
-# undef F_GETFD
-# ifdef NACL_NEWLIB
-# undef HAVE_IOCTL
-# endif
-#endif
-
#define IO_RBUF_CAPA_MIN 8192
#define IO_CBUF_CAPA_MIN (128*1024)
#define IO_RBUF_CAPA_FOR(fptr) (NEED_READCONV(fptr) ? IO_CBUF_CAPA_MIN : IO_RBUF_CAPA_MIN)
@@ -136,6 +176,8 @@ off_t __syscall(quad_t number, ...);
#ifdef _WIN32
#undef open
#define open rb_w32_uopen
+#undef rename
+#define rename(f, t) rb_w32_urename((f), (t))
#endif
VALUE rb_cIO;
@@ -161,7 +203,6 @@ VALUE rb_default_rs;
static VALUE argf;
-#define id_exception idException
static ID id_write, id_read, id_getc, id_flush, id_readpartial, id_set_encoding;
static VALUE sym_mode, sym_perm, sym_flags, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
static VALUE sym_textmode, sym_binmode, sym_autoclose;
@@ -174,12 +215,15 @@ static VALUE sym_DATA;
static VALUE sym_HOLE;
#endif
+static VALUE rb_io_initialize(int argc, VALUE *argv, VALUE io);
+static VALUE prep_io(int fd, int fmode, VALUE klass, const char *path);
+
struct argf {
VALUE filename, current_file;
long last_lineno; /* $. */
long lineno;
VALUE argv;
- char *inplace;
+ VALUE inplace;
struct rb_io_enc_t encs;
int8_t init_p, next_p, binmode;
};
@@ -188,14 +232,22 @@ static rb_atomic_t max_file_descriptor = NOFILE;
void
rb_update_max_fd(int fd)
{
- struct stat buf;
rb_atomic_t afd = (rb_atomic_t)fd;
rb_atomic_t max_fd = max_file_descriptor;
+ int err;
- if (afd <= max_fd)
+ if (fd < 0 || afd <= max_fd)
return;
- if (fstat(fd, &buf) != 0 && errno == EBADF) {
+#if defined(HAVE_FCNTL) && defined(F_GETFL)
+ err = fcntl(fd, F_GETFL) == -1;
+#else
+ {
+ struct stat buf;
+ err = fstat(fd, &buf) != 0;
+ }
+#endif
+ if (err && errno == EBADF) {
rb_bug("rb_update_max_fd: invalid fd (%d) given.", fd);
}
@@ -220,7 +272,7 @@ rb_maygvl_fd_fix_cloexec(int fd)
flags2 = flags | FD_CLOEXEC; /* Set CLOEXEC for non-standard file descriptors: 3, 4, 5, ... */
if (flags != flags2) {
ret = fcntl(fd, F_SETFD, flags2);
- if (ret == -1) {
+ if (ret != 0) {
rb_bug("rb_maygvl_fd_fix_cloexec: fcntl(%d, F_SETFD, %d) failed: %s", fd, flags2, strerror(errno));
}
}
@@ -257,14 +309,27 @@ rb_cloexec_open(const char *pathname, int flags, mode_t mode)
int ret;
static int o_cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
+ static const int retry_interval = 0;
+ static const int retry_max_count = 10000;
+
+ int retry_count = 0;
+
#ifdef O_CLOEXEC
/* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */
flags |= O_CLOEXEC;
#elif defined O_NOINHERIT
flags |= O_NOINHERIT;
#endif
- ret = open(pathname, flags, mode);
- if (ret == -1) return -1;
+
+ while ((ret = open(pathname, flags, mode)) == -1) {
+ int e = errno;
+ if (e != EAGAIN && e != EWOULDBLOCK) break;
+ if (retry_count++ >= retry_max_count) break;
+
+ sleep(retry_interval);
+ }
+
+ if (ret < 0) return ret;
if (ret <= 2 || o_cloexec_state == 0) {
rb_maygvl_fd_fix_cloexec(ret);
}
@@ -313,47 +378,62 @@ rb_cloexec_dup2(int oldfd, int newfd)
#else
ret = dup2(oldfd, newfd);
#endif
- if (ret == -1) return -1;
+ if (ret < 0) return ret;
}
rb_maygvl_fd_fix_cloexec(ret);
return ret;
}
-int
-rb_cloexec_pipe(int fildes[2])
+static int
+rb_fd_set_nonblock(int fd)
{
- int ret;
+#ifdef _WIN32
+ return rb_w32_set_nonblock(fd);
+#elif defined(F_GETFL)
+ int oflags = fcntl(fd, F_GETFL);
-#if defined(HAVE_PIPE2)
- static int try_pipe2 = 1;
- if (try_pipe2) {
- ret = pipe2(fildes, O_CLOEXEC);
- if (ret != -1)
- return ret;
- /* pipe2 is available since Linux 2.6.27, glibc 2.9. */
- if (errno == ENOSYS) {
- try_pipe2 = 0;
- ret = pipe(fildes);
- }
- }
- else {
- ret = pipe(fildes);
- }
+ if (oflags == -1)
+ return -1;
+ if (oflags & O_NONBLOCK)
+ return 0;
+ oflags |= O_NONBLOCK;
+ return fcntl(fd, F_SETFL, oflags);
+#endif
+ return 0;
+}
+
+int
+rb_cloexec_pipe(int descriptors[2])
+{
+#ifdef HAVE_PIPE2
+ int result = pipe2(descriptors, O_CLOEXEC | O_NONBLOCK);
#else
- ret = pipe(fildes);
+ int result = pipe(descriptors);
#endif
- if (ret == -1) return -1;
+
+ if (result < 0)
+ return result;
+
#ifdef __CYGWIN__
- if (ret == 0 && fildes[1] == -1) {
- close(fildes[0]);
- fildes[0] = -1;
- errno = ENFILE;
- return -1;
+ if (result == 0 && descriptors[1] == -1) {
+ close(descriptors[0]);
+ descriptors[0] = -1;
+ errno = ENFILE;
+ return -1;
}
#endif
- rb_maygvl_fd_fix_cloexec(fildes[0]);
- rb_maygvl_fd_fix_cloexec(fildes[1]);
- return ret;
+
+#ifndef HAVE_PIPE2
+ rb_maygvl_fd_fix_cloexec(descriptors[0]);
+ rb_maygvl_fd_fix_cloexec(descriptors[1]);
+
+#ifndef _WIN32
+ rb_fd_set_nonblock(descriptors[0]);
+ rb_fd_set_nonblock(descriptors[1]);
+#endif
+#endif
+
+ return result;
}
int
@@ -385,7 +465,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd)
ret = fcntl(fd, F_DUPFD, minfd);
#elif defined(HAVE_DUP)
ret = dup(fd);
- if (ret != -1 && ret < minfd) {
+ if (ret >= 0 && ret < minfd) {
const int prev_fd = ret;
ret = rb_cloexec_fcntl_dupfd(fd, minfd);
close(prev_fd);
@@ -394,7 +474,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd)
#else
# error "dup() or fcntl(F_DUPFD) must be supported."
#endif
- if (ret == -1) return -1;
+ if (ret < 0) return ret;
rb_maygvl_fd_fix_cloexec(ret);
return ret;
}
@@ -444,6 +524,42 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd)
static int io_fflush(rb_io_t *);
static rb_io_t *flush_before_seek(rb_io_t *fptr);
+#define FMODE_PREP (1<<16)
+#define FMODE_SIGNAL_ON_EPIPE (1<<17)
+
+#define fptr_signal_on_epipe(fptr) \
+ (((fptr)->mode & FMODE_SIGNAL_ON_EPIPE) != 0)
+
+#define fptr_set_signal_on_epipe(fptr, flag) \
+ ((flag) ? \
+ (fptr)->mode |= FMODE_SIGNAL_ON_EPIPE : \
+ (fptr)->mode &= ~FMODE_SIGNAL_ON_EPIPE)
+
+extern ID ruby_static_id_signo;
+
+NORETURN(static void raise_on_write(rb_io_t *fptr, int e, VALUE errinfo));
+static void
+raise_on_write(rb_io_t *fptr, int e, VALUE errinfo)
+{
+#if defined EPIPE
+ if (fptr_signal_on_epipe(fptr) && (e == EPIPE)) {
+ const VALUE sig =
+# if defined SIGPIPE
+ INT2FIX(SIGPIPE) - INT2FIX(0) +
+# endif
+ INT2FIX(0);
+ rb_ivar_set(errinfo, ruby_static_id_signo, sig);
+ }
+#endif
+ rb_exc_raise(errinfo);
+}
+
+#define rb_sys_fail_on_write(fptr) \
+ do { \
+ int e = errno; \
+ raise_on_write(fptr, e, rb_syserr_new_path(e, (fptr)->pathv)); \
+ } while (0)
+
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) ((fptr)->mode & FMODE_TEXTMODE)
#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
@@ -458,7 +574,14 @@ static rb_io_t *flush_before_seek(rb_io_t *fptr);
* conversion IO process and universal newline decorator by default.
*/
#define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || (fptr)->encs.ecflags & ~ECONV_CRLF_NEWLINE_DECORATOR)
-#define NEED_WRITECONV(fptr) (((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || ((fptr)->encs.ecflags & ((ECONV_DECORATOR_MASK & ~ECONV_CRLF_NEWLINE_DECORATOR)|ECONV_STATEFUL_DECORATOR_MASK)))
+#define WRITECONV_MASK ( \
+ (ECONV_DECORATOR_MASK & ~ECONV_CRLF_NEWLINE_DECORATOR)|\
+ ECONV_STATEFUL_DECORATOR_MASK|\
+ 0)
+#define NEED_WRITECONV(fptr) ( \
+ ((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || \
+ ((fptr)->encs.ecflags & WRITECONV_MASK) || \
+ 0)
#define SET_BINARY_MODE(fptr) setmode((fptr)->fd, O_BINARY)
#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) do {\
@@ -586,7 +709,11 @@ set_binary_mode_with_seek_cur(rb_io_t *fptr)
/* Unix */
# define DEFAULT_TEXTMODE 0
#define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || NEED_NEWLINE_DECORATOR_ON_READ(fptr))
-#define NEED_WRITECONV(fptr) (((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) || ((fptr)->encs.ecflags & (ECONV_DECORATOR_MASK|ECONV_STATEFUL_DECORATOR_MASK)))
+#define NEED_WRITECONV(fptr) ( \
+ ((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || \
+ NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) || \
+ ((fptr)->encs.ecflags & (ECONV_DECORATOR_MASK|ECONV_STATEFUL_DECORATOR_MASK)) || \
+ 0)
#define SET_BINARY_MODE(fptr) (void)(fptr)
#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) (void)(fptr)
#define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags) ((void)(enc2), (void)(ecflags))
@@ -614,6 +741,15 @@ is_socket(int fd, VALUE path)
static const char closed_stream[] = "closed stream";
+static void
+io_fd_check_closed(int fd)
+{
+ if (fd < 0) {
+ rb_thread_check_ints(); /* check for ruby_error_stream_closed */
+ rb_raise(rb_eIOError, closed_stream);
+ }
+}
+
void
rb_eof_error(void)
{
@@ -639,9 +775,7 @@ void
rb_io_check_closed(rb_io_t *fptr)
{
rb_io_check_initialized(fptr);
- if (fptr->fd < 0) {
- rb_raise(rb_eIOError, closed_stream);
- }
+ io_fd_check_closed(fptr->fd);
}
static rb_io_t *
@@ -775,7 +909,7 @@ static rb_io_t *
flush_before_seek(rb_io_t *fptr)
{
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
io_unread(fptr);
errno = 0;
return fptr;
@@ -799,13 +933,13 @@ rb_io_check_char_readable(rb_io_t *fptr)
}
if (fptr->wbuf.len) {
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
}
if (fptr->tied_io_for_writing) {
rb_io_t *wfptr;
GetOpenFile(fptr->tied_io_for_writing, wfptr);
if (io_fflush(wfptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(wfptr);
}
}
@@ -916,7 +1050,9 @@ io_alloc(VALUE klass)
#endif
struct io_internal_read_struct {
+ VALUE th;
int fd;
+ int nonblock;
void *buf;
size_t capa;
};
@@ -935,25 +1071,44 @@ struct io_internal_writev_struct {
};
#endif
+static int nogvl_wait_for_single_fd(VALUE th, int fd, short events);
static VALUE
internal_read_func(void *ptr)
{
struct io_internal_read_struct *iis = ptr;
- return read(iis->fd, iis->buf, iis->capa);
+ ssize_t r;
+retry:
+ r = read(iis->fd, iis->buf, iis->capa);
+ if (r < 0 && !iis->nonblock) {
+ int e = errno;
+ if (e == EAGAIN || e == EWOULDBLOCK) {
+ if (nogvl_wait_for_single_fd(iis->th, iis->fd, RB_WAITFD_IN) != -1) {
+ goto retry;
+ }
+ errno = e;
+ }
+ }
+ return r;
}
+#if defined __APPLE__
+# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE)
+#else
+# define do_write_retry(code) ret = code
+#endif
static VALUE
internal_write_func(void *ptr)
{
struct io_internal_write_struct *iis = ptr;
- return write(iis->fd, iis->buf, iis->capa);
+ ssize_t ret;
+ do_write_retry(write(iis->fd, iis->buf, iis->capa));
+ return (VALUE)ret;
}
static void*
internal_write_func2(void *ptr)
{
- struct io_internal_write_struct *iis = ptr;
- return (void*)(intptr_t)write(iis->fd, iis->buf, iis->capa);
+ return (void*)internal_write_func(ptr);
}
#ifdef HAVE_WRITEV
@@ -961,17 +1116,22 @@ static VALUE
internal_writev_func(void *ptr)
{
struct io_internal_writev_struct *iis = ptr;
- return writev(iis->fd, iis->iov, iis->iovcnt);
+ ssize_t ret;
+ do_write_retry(writev(iis->fd, iis->iov, iis->iovcnt));
+ return (VALUE)ret;
}
#endif
static ssize_t
rb_read_internal(int fd, void *buf, size_t count)
{
- struct io_internal_read_struct iis;
- iis.fd = fd;
- iis.buf = buf;
- iis.capa = count;
+ struct io_internal_read_struct iis = {
+ .th = rb_thread_current(),
+ .fd = fd,
+ .nonblock = 0,
+ .buf = buf,
+ .capa = count
+ };
return (ssize_t)rb_thread_io_blocking_region(internal_read_func, &iis, fd);
}
@@ -979,10 +1139,11 @@ rb_read_internal(int fd, void *buf, size_t count)
static ssize_t
rb_write_internal(int fd, const void *buf, size_t count)
{
- struct io_internal_write_struct iis;
- iis.fd = fd;
- iis.buf = buf;
- iis.capa = count;
+ struct io_internal_write_struct iis = {
+ .fd = fd,
+ .buf = buf,
+ .capa = count
+ };
return (ssize_t)rb_thread_io_blocking_region(internal_write_func, &iis, fd);
}
@@ -990,10 +1151,11 @@ rb_write_internal(int fd, const void *buf, size_t count)
static ssize_t
rb_write_internal2(int fd, const void *buf, size_t count)
{
- struct io_internal_write_struct iis;
- iis.fd = fd;
- iis.buf = buf;
- iis.capa = count;
+ struct io_internal_write_struct iis = {
+ .fd = fd,
+ .buf = buf,
+ .capa = count
+ };
return (ssize_t)rb_thread_call_without_gvl2(internal_write_func2, &iis,
RUBY_UBF_IO, NULL);
@@ -1003,10 +1165,11 @@ rb_write_internal2(int fd, const void *buf, size_t count)
static ssize_t
rb_writev_internal(int fd, const struct iovec *iov, int iovcnt)
{
- struct io_internal_writev_struct iis;
- iis.fd = fd;
- iis.iov = iov;
- iis.iovcnt = iovcnt;
+ struct io_internal_writev_struct iis = {
+ .fd = fd,
+ .iov = iov,
+ .iovcnt = iovcnt,
+ };
return (ssize_t)rb_thread_io_blocking_region(internal_writev_func, &iis, fd);
}
@@ -1057,8 +1220,7 @@ io_flush_buffer_async2(VALUE arg)
rb_io_t *fptr = (rb_io_t *)arg;
VALUE ret;
- ret = (VALUE)rb_thread_call_without_gvl2(io_flush_buffer_sync2, fptr,
- RUBY_UBF_IO, NULL);
+ ret = (VALUE)rb_thread_call_without_gvl2(io_flush_buffer_sync2, fptr, RUBY_UBF_IO, NULL);
if (!ret) {
/* pending async interrupt is there. */
@@ -1091,7 +1253,6 @@ io_fflush(rb_io_t *fptr)
rb_io_check_closed(fptr);
if (fptr->wbuf.len == 0)
return 0;
- rb_io_check_closed(fptr);
while (fptr->wbuf.len > 0 && io_flush_buffer(fptr) != 0) {
if (!rb_io_wait_writable(fptr->fd))
return -1;
@@ -1100,67 +1261,139 @@ io_fflush(rb_io_t *fptr)
return 0;
}
+VALUE
+rb_io_wait(VALUE io, VALUE events, VALUE timeout)
+{
+ VALUE scheduler = rb_scheduler_current();
+
+ if (scheduler != Qnil) {
+ return rb_scheduler_io_wait(scheduler, io, events, timeout);
+ }
+
+ rb_io_t * fptr = NULL;
+ RB_IO_POINTER(io, fptr);
+
+ struct timeval tv_storage;
+ struct timeval *tv = NULL;
+
+ if (timeout != Qnil) {
+ tv_storage = rb_time_interval(timeout);
+ tv = &tv_storage;
+ }
+
+ int ready = rb_thread_wait_for_single_fd(fptr->fd, RB_NUM2INT(events), tv);
+
+ if (ready < 0) {
+ rb_sys_fail(0);
+ }
+
+ // Not sure if this is necessary:
+ rb_io_check_closed(fptr);
+
+ if (ready > 0) {
+ return RB_INT2NUM(ready);
+ } else {
+ return Qfalse;
+ }
+}
+
+static VALUE
+rb_io_from_fd(int fd)
+{
+ return prep_io(fd, FMODE_PREP, rb_cIO, NULL);
+}
+
int
rb_io_wait_readable(int f)
{
- if (f < 0) {
- rb_raise(rb_eIOError, closed_stream);
- }
+ VALUE scheduler;
+
+ io_fd_check_closed(f);
+
+ scheduler = rb_scheduler_current();
switch (errno) {
case EINTR:
#if defined(ERESTART)
case ERESTART:
#endif
- rb_thread_check_ints();
- return TRUE;
+ rb_thread_check_ints();
+ return TRUE;
case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
- rb_thread_wait_fd(f);
- return TRUE;
+ if (scheduler != Qnil) {
+ return RTEST(
+ rb_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
+ );
+ } else {
+ rb_thread_wait_fd(f);
+ }
+ return TRUE;
default:
- return FALSE;
+ return FALSE;
}
}
int
rb_io_wait_writable(int f)
{
- if (f < 0) {
- rb_raise(rb_eIOError, closed_stream);
- }
+ VALUE scheduler;
+
+ io_fd_check_closed(f);
+
+ scheduler = rb_scheduler_current();
switch (errno) {
case EINTR:
#if defined(ERESTART)
case ERESTART:
#endif
- /*
- * In old Linux, several special files under /proc and /sys don't handle
- * select properly. Thus we need avoid to call if don't use O_NONBLOCK.
- * Otherwise, we face nasty hang up. Sigh.
- * e.g. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
- * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
- * In EINTR case, we only need to call RUBY_VM_CHECK_INTS_BLOCKING().
- * Then rb_thread_check_ints() is enough.
- */
- rb_thread_check_ints();
- return TRUE;
+ /*
+ * In old Linux, several special files under /proc and /sys don't handle
+ * select properly. Thus we need avoid to call if don't use O_NONBLOCK.
+ * Otherwise, we face nasty hang up. Sigh.
+ * e.g. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
+ * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
+ * In EINTR case, we only need to call RUBY_VM_CHECK_INTS_BLOCKING().
+ * Then rb_thread_check_ints() is enough.
+ */
+ rb_thread_check_ints();
+ return TRUE;
case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
- rb_thread_fd_writable(f);
- return TRUE;
+ if (scheduler != Qnil) {
+ return RTEST(
+ rb_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
+ );
+ } else {
+ rb_thread_fd_writable(f);
+ }
+ return TRUE;
default:
- return FALSE;
+ return FALSE;
}
}
+int
+rb_wait_for_single_fd(int fd, int events, struct timeval *timeout)
+{
+ VALUE scheduler = rb_scheduler_current();
+
+ if (scheduler != Qnil) {
+ return RTEST(
+ rb_scheduler_io_wait(scheduler, rb_io_from_fd(fd), RB_INT2NUM(events), rb_scheduler_timeout(timeout))
+ );
+ }
+
+ return rb_thread_wait_for_single_fd(fd, events, timeout);
+}
+
static void
make_writeconv(rb_io_t *fptr)
{
@@ -1248,8 +1481,8 @@ io_binwrite_string(VALUE arg)
r = rb_writev_internal(fptr->fd, iov, 2);
- if (r == -1)
- return -1;
+ if (r < 0)
+ return r;
if (fptr->wbuf.len <= r) {
r -= fptr->wbuf.len;
@@ -1310,12 +1543,24 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
rb_thread_check_ints();
if ((n = len) <= 0) return n;
+
+ VALUE scheduler = rb_scheduler_current();
+ if (scheduler != Qnil && rb_scheduler_supports_io_write(scheduler)) {
+ ssize_t length = RB_NUM2SSIZE(
+ rb_scheduler_io_write(scheduler, fptr->self, str, offset, len)
+ );
+
+ if (length < 0) rb_sys_fail_path(fptr->pathv);
+
+ return length;
+ }
+
if (fptr->wbuf.ptr == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
fptr->wbuf.off = 0;
fptr->wbuf.len = 0;
fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
- fptr->write_lock = rb_mutex_new();
+ fptr->write_lock = rb_mutex_new();
rb_mutex_allow_trap(fptr->write_lock, 1);
}
if ((!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY))) ||
@@ -1328,7 +1573,7 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
arg.ptr = ptr + offset;
arg.length = n;
if (fptr->write_lock) {
- r = rb_mutex_synchronize(fptr->write_lock, io_binwrite_string, (VALUE)&arg);
+ r = rb_mutex_synchronize(fptr->write_lock, io_binwrite_string, (VALUE)&arg);
}
else {
r = io_binwrite_string((VALUE)&arg);
@@ -1362,6 +1607,11 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
# define MODE_BTMODE(a,b,c) ((fmode & FMODE_BINMODE) ? (b) : \
(fmode & FMODE_TEXTMODE) ? (c) : (a))
+
+#define MODE_BTXMODE(a, b, c, d, e, f) ((fmode & FMODE_EXCL) ? \
+ MODE_BTMODE(d, e, f) : \
+ MODE_BTMODE(a, b, c))
+
static VALUE
do_writeconv(VALUE str, rb_io_t *fptr, int *converted)
{
@@ -1475,21 +1725,210 @@ io_write(VALUE io, VALUE str, int nosync)
rb_io_check_writable(fptr);
n = io_fwrite(str, fptr, nosync);
- if (n == -1L) rb_sys_fail_path(fptr->pathv);
+ if (n < 0L) rb_sys_fail_on_write(fptr);
return LONG2FIX(n);
}
+#ifdef HAVE_WRITEV
+struct binwritev_arg {
+ rb_io_t *fptr;
+ const struct iovec *iov;
+ int iovcnt;
+};
+
+static VALUE
+call_writev_internal(VALUE arg)
+{
+ struct binwritev_arg *p = (struct binwritev_arg *)arg;
+ return rb_writev_internal(p->fptr->fd, p->iov, p->iovcnt);
+}
+
+static long
+io_binwritev(struct iovec *iov, int iovcnt, rb_io_t *fptr)
+{
+ int i;
+ long r, total = 0, written_len = 0;
+
+ /* don't write anything if current thread has a pending interrupt. */
+ rb_thread_check_ints();
+
+ if (iovcnt == 0) return 0;
+ for (i = 1; i < iovcnt; i++) total += iov[i].iov_len;
+
+ if (fptr->wbuf.ptr == NULL && !(fptr->mode & FMODE_SYNC)) {
+ fptr->wbuf.off = 0;
+ fptr->wbuf.len = 0;
+ fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
+ fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
+ fptr->write_lock = rb_mutex_new();
+ rb_mutex_allow_trap(fptr->write_lock, 1);
+ }
+
+ if (fptr->wbuf.ptr && fptr->wbuf.len) {
+ long offset = fptr->wbuf.off + fptr->wbuf.len;
+ if (offset + total <= fptr->wbuf.capa) {
+ for (i = 1; i < iovcnt; i++) {
+ memcpy(fptr->wbuf.ptr+offset, iov[i].iov_base, iov[i].iov_len);
+ offset += iov[i].iov_len;
+ }
+ fptr->wbuf.len += total;
+ return total;
+ }
+ else {
+ iov[0].iov_base = fptr->wbuf.ptr + fptr->wbuf.off;
+ iov[0].iov_len = fptr->wbuf.len;
+ }
+ }
+ else {
+ iov++;
+ if (!--iovcnt) return 0;
+ }
+
+ retry:
+ if (fptr->write_lock) {
+ struct binwritev_arg arg;
+ arg.fptr = fptr;
+ arg.iov = iov;
+ arg.iovcnt = iovcnt;
+ r = rb_mutex_synchronize(fptr->write_lock, call_writev_internal, (VALUE)&arg);
+ }
+ else {
+ r = rb_writev_internal(fptr->fd, iov, iovcnt);
+ }
+
+ if (r >= 0) {
+ written_len += r;
+ if (fptr->wbuf.ptr && fptr->wbuf.len) {
+ if (written_len < fptr->wbuf.len) {
+ fptr->wbuf.off += r;
+ fptr->wbuf.len -= r;
+ }
+ else {
+ written_len -= fptr->wbuf.len;
+ fptr->wbuf.off = 0;
+ fptr->wbuf.len = 0;
+ }
+ }
+ if (written_len == total) return total;
+
+ while (r >= (ssize_t)iov->iov_len) {
+ /* iovcnt > 0 */
+ r -= iov->iov_len;
+ iov->iov_len = 0;
+ iov++;
+ if (!--iovcnt) return total;
+ /* defensive check: written_len should == total */
+ }
+ iov->iov_base = (char *)iov->iov_base + r;
+ iov->iov_len -= r;
+
+ errno = EAGAIN;
+ }
+ if (rb_io_wait_writable(fptr->fd)) {
+ rb_io_check_closed(fptr);
+ goto retry;
+ }
+
+ return -1L;
+}
+
+static long
+io_fwritev(int argc, const VALUE *argv, rb_io_t *fptr)
+{
+ int i, converted, iovcnt = argc + 1;
+ long n;
+ VALUE v1, v2, str, tmp, *tmp_array;
+ struct iovec *iov;
+
+ iov = ALLOCV_N(struct iovec, v1, iovcnt);
+ tmp_array = ALLOCV_N(VALUE, v2, argc);
+
+ for (i = 0; i < argc; i++) {
+ str = rb_obj_as_string(argv[i]);
+ converted = 0;
+ str = do_writeconv(str, fptr, &converted);
+ if (converted)
+ OBJ_FREEZE(str);
+
+ tmp = rb_str_tmp_frozen_acquire(str);
+ tmp_array[i] = tmp;
+ /* iov[0] is reserved for buffer of fptr */
+ iov[i+1].iov_base = RSTRING_PTR(tmp);
+ iov[i+1].iov_len = RSTRING_LEN(tmp);
+ }
+
+ n = io_binwritev(iov, iovcnt, fptr);
+ if (v1) ALLOCV_END(v1);
+
+ for (i = 0; i < argc; i++) {
+ rb_str_tmp_frozen_release(argv[i], tmp_array[i]);
+ }
+
+ if (v2) ALLOCV_END(v2);
+
+ return n;
+}
+
+static int
+iovcnt_ok(int iovcnt)
+{
+#ifdef IOV_MAX
+ return iovcnt < IOV_MAX;
+#else /* GNU/Hurd has writev, but no IOV_MAX */
+ return 1;
+#endif
+}
+#endif /* HAVE_WRITEV */
+
+static VALUE
+io_writev(int argc, const VALUE *argv, VALUE io)
+{
+ rb_io_t *fptr;
+ long n;
+ VALUE tmp, total = INT2FIX(0);
+ int i, cnt = 1;
+
+ io = GetWriteIO(io);
+ tmp = rb_io_check_io(io);
+ if (NIL_P(tmp)) {
+ /* port is not IO, call write method for it. */
+ return rb_funcallv(io, id_write, argc, argv);
+ }
+ io = tmp;
+
+ GetOpenFile(io, fptr);
+ rb_io_check_writable(fptr);
+
+ for (i = 0; i < argc; i += cnt) {
+#ifdef HAVE_WRITEV
+ if ((fptr->mode & (FMODE_SYNC|FMODE_TTY)) && iovcnt_ok(cnt = argc - i)) {
+ n = io_fwritev(cnt, &argv[i], fptr);
+ }
+ else
+#endif
+ {
+ cnt = 1;
+ /* sync at last item */
+ n = io_fwrite(rb_obj_as_string(argv[i]), fptr, (i < argc-1));
+ }
+ if (n < 0L) rb_sys_fail_on_write(fptr);
+ total = rb_fix_plus(LONG2FIX(n), total);
+ }
+
+ return total;
+}
+
/*
* call-seq:
- * ios.write(string) -> integer
+ * ios.write(string, ...) -> integer
*
- * Writes the given string to <em>ios</em>. The stream must be opened
- * for writing. If the argument is not a string, it will be converted
+ * Writes the given strings to <em>ios</em>. The stream must be opened
+ * for writing. Arguments that are not a string will be converted
* to a string using <code>to_s</code>. Returns the number of bytes
- * written.
+ * written in total.
*
- * count = $stdout.write("This is a test\n")
+ * count = $stdout.write("This is", " a test\n")
* puts "That was #{count} bytes of data"
*
* <em>produces:</em>
@@ -1499,9 +1938,15 @@ io_write(VALUE io, VALUE str, int nosync)
*/
static VALUE
-io_write_m(VALUE io, VALUE str)
+io_write_m(int argc, VALUE *argv, VALUE io)
{
- return io_write(io, str, 0);
+ if (argc != 1) {
+ return io_writev(argc, argv, io);
+ }
+ else {
+ VALUE str = argv[0];
+ return io_write(io, str, 0);
+ }
}
VALUE
@@ -1510,6 +1955,23 @@ rb_io_write(VALUE io, VALUE str)
return rb_funcallv(io, id_write, 1, &str);
}
+static VALUE
+rb_io_writev(VALUE io, int argc, const VALUE *argv)
+{
+ if (argc > 1 && rb_obj_method_arity(io, id_write) == 1) {
+ if (io != rb_ractor_stderr() && RTEST(ruby_verbose)) {
+ VALUE klass = CLASS_OF(io);
+ char sep = FL_TEST(klass, FL_SINGLETON) ? (klass = io, '.') : '#';
+ rb_category_warning(RB_WARN_CATEGORY_DEPRECATED, "%+"PRIsVALUE"%c""write is outdated interface"
+ " which accepts just one argument",
+ klass, sep);
+ }
+ do rb_io_write(io, *argv++); while (--argc);
+ return argv[0]; /* unused right now */
+ }
+ return rb_funcallv(io, id_write, argc, argv);
+}
+
/*
* call-seq:
* ios << obj -> ios
@@ -1561,7 +2023,7 @@ rb_io_flush_raw(VALUE io, int sync)
if (fptr->mode & FMODE_WRITABLE) {
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
}
if (fptr->mode & FMODE_READABLE) {
io_unread(fptr);
@@ -1720,7 +2182,7 @@ static void clear_readconv(rb_io_t *fptr);
* ios.rewind -> 0
*
* Positions <em>ios</em> to the beginning of input, resetting
- * <code>lineno</code> to zero.
+ * #lineno to zero.
*
* f = File.new("testfile")
* f.readline #=> "This is line one\n"
@@ -1750,6 +2212,16 @@ rb_io_rewind(VALUE io)
}
static int
+fptr_wait_readable(rb_io_t *fptr)
+{
+ int ret = rb_io_wait_readable(fptr->fd);
+
+ if (ret)
+ rb_io_check_closed(fptr);
+ return ret;
+}
+
+static int
io_fillbuf(rb_io_t *fptr)
{
ssize_t r;
@@ -1769,7 +2241,7 @@ io_fillbuf(rb_io_t *fptr)
r = rb_read_internal(fptr->fd, fptr->rbuf.ptr, fptr->rbuf.capa);
}
if (r < 0) {
- if (rb_io_wait_readable(fptr->fd))
+ if (fptr_wait_readable(fptr))
goto retry;
{
int e = errno;
@@ -1796,14 +2268,14 @@ io_fillbuf(rb_io_t *fptr)
*
* Returns true if <em>ios</em> is at end of file that means
* there are no more data to read.
- * The stream must be opened for reading or an <code>IOError</code> will be
+ * The stream must be opened for reading or an IOError will be
* raised.
*
* f = File.new("testfile")
* dummy = f.readlines
* f.eof #=> true
*
- * If <em>ios</em> is a stream such as pipe or socket, <code>IO#eof?</code>
+ * If <em>ios</em> is a stream such as pipe or socket, IO#eof?
* blocks until the other end sends some data or closes it.
*
* r, w = IO.pipe
@@ -1817,10 +2289,9 @@ io_fillbuf(rb_io_t *fptr)
* r, w = IO.pipe
* r.eof? # blocks forever
*
- * Note that <code>IO#eof?</code> reads data to the input byte buffer.
- * So <code>IO#sysread</code> may not behave as you intend with
- * <code>IO#eof?</code>, unless you call <code>IO#rewind</code>
- * first (which is not available for some streams).
+ * Note that IO#eof? reads data to the input byte buffer. So
+ * IO#sysread may not behave as you intend with IO#eof?, unless you
+ * call IO#rewind first (which is not available for some streams).
*/
VALUE
@@ -1852,7 +2323,7 @@ rb_io_eof(VALUE io)
* Returns the current ``sync mode'' of <em>ios</em>. When sync mode is
* true, all output is immediately flushed to the underlying operating
* system and is not buffered by Ruby internally. See also
- * <code>IO#fsync</code>.
+ * IO#fsync.
*
* f = File.new("testfile")
* f.sync #=> false
@@ -1877,7 +2348,7 @@ rb_io_sync(VALUE io)
* Sets the ``sync mode'' to <code>true</code> or <code>false</code>.
* When sync mode is true, all output is immediately flushed to the
* underlying operating system and is not buffered internally. Returns
- * the new state. See also <code>IO#fsync</code>.
+ * the new state. See also IO#fsync.
*
* f = File.new("testfile")
* f.sync = true
@@ -1904,12 +2375,11 @@ rb_io_set_sync(VALUE io, VALUE sync)
* ios.fsync -> 0 or nil
*
* Immediately writes all buffered data in <em>ios</em> to disk.
- * Note that <code>fsync</code> differs from
- * using <code>IO#sync=</code>. The latter ensures that data is flushed
- * from Ruby's buffers, but does not guarantee that the underlying
- * operating system actually writes it to disk.
+ * Note that #fsync differs from using IO#sync=. The latter ensures
+ * that data is flushed from Ruby's buffers, but does not guarantee
+ * that the underlying operating system actually writes it to disk.
*
- * <code>NotImplementedError</code> is raised
+ * NotImplementedError is raised
* if the underlying operating system does not support <em>fsync(2)</em>.
*/
@@ -1922,7 +2392,7 @@ rb_io_fsync(VALUE io)
GetOpenFile(io, fptr);
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
if ((int)rb_thread_io_blocking_region(nogvl_fsync, fptr, fptr->fd) < 0)
rb_sys_fail_path(fptr->pathv);
return INT2FIX(0);
@@ -1958,8 +2428,8 @@ nogvl_fdatasync(void *ptr)
* Immediately writes all buffered data in <em>ios</em> to disk.
*
* If the underlying operating system does not support <em>fdatasync(2)</em>,
- * <code>IO#fsync</code> is called instead (which might raise a
- * <code>NotImplementedError</code>).
+ * IO#fsync is called instead (which might raise a
+ * NotImplementedError).
*/
static VALUE
@@ -1971,7 +2441,7 @@ rb_io_fdatasync(VALUE io)
GetOpenFile(io, fptr);
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
if ((int)rb_thread_io_blocking_region(nogvl_fdatasync, fptr, fptr->fd) == 0)
return INT2FIX(0);
@@ -2012,7 +2482,7 @@ rb_io_fileno(VALUE io)
* ios.pid -> integer
*
* Returns the process ID of a child process associated with
- * <em>ios</em>. This will be set by <code>IO.popen</code>.
+ * <em>ios</em>. This will be set by IO.popen.
*
* pipe = IO.popen("-")
* if pipe
@@ -2116,7 +2586,7 @@ io_bufread(char *ptr, long len, rb_io_t *fptr)
c = rb_read_internal(fptr->fd, ptr+offset, n);
if (c == 0) break;
if (c < 0) {
- if (rb_io_wait_readable(fptr->fd))
+ if (fptr_wait_readable(fptr))
goto again;
return -1;
}
@@ -2159,6 +2629,17 @@ bufread_call(VALUE arg)
static long
io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
{
+ VALUE scheduler = rb_scheduler_current();
+ if (scheduler != Qnil && rb_scheduler_supports_io_read(scheduler)) {
+ ssize_t length = RB_NUM2SSIZE(
+ rb_scheduler_io_read(scheduler, fptr->self, str, offset, size)
+ );
+
+ if (length < 0) rb_sys_fail_path(fptr->pathv);
+
+ return length;
+ }
+
long len;
struct bufread_arg arg;
@@ -2172,16 +2653,6 @@ io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
return len;
}
-ssize_t
-rb_io_bufread(VALUE io, void *buf, size_t size)
-{
- rb_io_t *fptr;
-
- GetOpenFile(io, fptr);
- rb_io_check_readable(fptr);
- return (ssize_t)io_bufread(buf, (long)size, fptr);
-}
-
static long
remain_size(rb_io_t *fptr)
{
@@ -2196,7 +2667,7 @@ remain_size(rb_io_t *fptr)
)
{
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
pos = lseek(fptr->fd, 0, SEEK_CUR);
if (st.st_size >= pos && pos >= 0) {
siz += st.st_size - pos;
@@ -2214,7 +2685,6 @@ remain_size(rb_io_t *fptr)
static VALUE
io_enc_str(VALUE str, rb_io_t *fptr)
{
- OBJ_TAINT(str);
rb_enc_associate(str, io_read_encoding(fptr));
return str;
}
@@ -2302,7 +2772,7 @@ fill_cbuf(rb_io_t *fptr, int ec_flags)
if (res == econv_source_buffer_empty) {
if (fptr->rbuf.len == 0) {
READ_CHECK(fptr);
- if (io_fillbuf(fptr) == -1) {
+ if (io_fillbuf(fptr) < 0) {
if (!fptr->readconv) {
return MORE_CHAR_FINISHED;
}
@@ -2344,7 +2814,6 @@ io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
else {
rb_str_cat(str, fptr->cbuf.ptr+fptr->cbuf.off, len);
}
- OBJ_TAINT(str);
rb_enc_associate(str, fptr->encs.enc);
}
fptr->cbuf.off += len;
@@ -2472,60 +2941,34 @@ read_all(rb_io_t *fptr, long siz, VALUE str)
void
rb_io_set_nonblock(rb_io_t *fptr)
{
-#ifdef _WIN32
- if (rb_w32_set_nonblock(fptr->fd) != 0) {
+ if (rb_fd_set_nonblock(fptr->fd) != 0) {
rb_sys_fail_path(fptr->pathv);
}
-#else
- int oflags;
-#ifdef F_GETFL
- oflags = fcntl(fptr->fd, F_GETFL);
- if (oflags == -1) {
- rb_sys_fail_path(fptr->pathv);
- }
-#else
- oflags = 0;
-#endif
- if ((oflags & O_NONBLOCK) == 0) {
- oflags |= O_NONBLOCK;
- if (fcntl(fptr->fd, F_SETFL, oflags) == -1) {
- rb_sys_fail_path(fptr->pathv);
- }
- }
-#endif
}
-struct read_internal_arg {
- int fd;
- char *str_ptr;
- long len;
-};
-
static VALUE
read_internal_call(VALUE arg)
{
- struct read_internal_arg *p = (struct read_internal_arg *)arg;
- p->len = rb_read_internal(p->fd, p->str_ptr, p->len);
- return Qundef;
+ struct io_internal_read_struct *iis = (struct io_internal_read_struct *)arg;
+
+ return rb_thread_io_blocking_region(internal_read_func, iis, iis->fd);
}
-static int
-no_exception_p(VALUE opts)
+static long
+read_internal_locktmp(VALUE str, struct io_internal_read_struct *iis)
{
- VALUE except;
- ID id = id_exception;
-
- rb_get_kwargs(opts, &id, 0, 1, &except);
- return except == Qfalse;
+ return (long)rb_str_locktmp_ensure(str, read_internal_call, (VALUE)iis);
}
+#define no_exception_p(opts) !rb_opts_exception_p((opts), TRUE)
+
static VALUE
-io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
+io_getpartial(int argc, VALUE *argv, VALUE io, int no_exception, int nonblock)
{
rb_io_t *fptr;
VALUE length, str;
long n, len;
- struct read_internal_arg arg;
+ struct io_internal_read_struct iis;
int shrinkable;
rb_scan_args(argc, argv, "11", &length, &str);
@@ -2535,13 +2978,14 @@ io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
}
shrinkable = io_setstrbuf(&str, len);
- OBJ_TAINT(str);
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
- if (len == 0)
+ if (len == 0) {
+ io_set_read_length(str, 0, shrinkable);
return str;
+ }
if (!nonblock)
READ_CHECK(fptr);
@@ -2552,17 +2996,18 @@ io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
rb_io_set_nonblock(fptr);
}
io_setstrbuf(&str, len);
- arg.fd = fptr->fd;
- arg.str_ptr = RSTRING_PTR(str);
- arg.len = len;
- rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
- n = arg.len;
+ iis.th = rb_thread_current();
+ iis.fd = fptr->fd;
+ iis.nonblock = nonblock;
+ iis.buf = RSTRING_PTR(str);
+ iis.capa = len;
+ n = read_internal_locktmp(str, &iis);
if (n < 0) {
int e = errno;
- if (!nonblock && rb_io_wait_readable(fptr->fd))
+ if (!nonblock && fptr_wait_readable(fptr))
goto again;
if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) {
- if (no_exception_p(opts))
+ if (no_exception)
return sym_wait_readable;
else
rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE,
@@ -2593,7 +3038,7 @@ io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
* The _outbuf_ will contain only the received data after the method call
* even if it is not empty at the beginning.
*
- * It raises <code>EOFError</code> on end of file.
+ * It raises EOFError on end of file.
*
* readpartial is designed for streams such as pipe, socket, tty, etc.
* It blocks only when no data immediately available.
@@ -2632,11 +3077,15 @@ io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
*
* Note that readpartial behaves similar to sysread.
* The differences are:
- * * If the byte buffer is not empty, read from the byte buffer instead of "sysread for buffered IO (IOError)".
- * * It doesn't cause Errno::EWOULDBLOCK and Errno::EINTR. When readpartial meets EWOULDBLOCK and EINTR by read system call, readpartial retry the system call.
+ * * If the byte buffer is not empty, read from the byte buffer
+ * instead of "sysread for buffered IO (IOError)".
+ * * It doesn't cause Errno::EWOULDBLOCK and Errno::EINTR. When
+ * readpartial meets EWOULDBLOCK and EINTR by read system call,
+ * readpartial retry the system call.
*
* The latter means that readpartial is nonblocking-flag insensitive.
- * It blocks on the situation IO#sysread causes Errno::EWOULDBLOCK as if the fd is blocking mode.
+ * It blocks on the situation IO#sysread causes Errno::EWOULDBLOCK as
+ * if the fd is blocking mode.
*
*/
@@ -2652,9 +3101,9 @@ io_readpartial(int argc, VALUE *argv, VALUE io)
}
static VALUE
-io_nonblock_eof(VALUE opts)
+io_nonblock_eof(int no_exception)
{
- if (!no_exception_p(opts)) {
+ if (!no_exception) {
rb_eof_error();
}
return Qnil;
@@ -2662,11 +3111,11 @@ io_nonblock_eof(VALUE opts)
/* :nodoc: */
static VALUE
-io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex)
+io_read_nonblock(rb_execution_context_t *ec, VALUE io, VALUE length, VALUE str, VALUE ex)
{
rb_io_t *fptr;
long n, len;
- struct read_internal_arg arg;
+ struct io_internal_read_struct iis;
int shrinkable;
if ((len = NUM2LONG(length)) < 0) {
@@ -2674,26 +3123,29 @@ io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex)
}
shrinkable = io_setstrbuf(&str, len);
- OBJ_TAINT(str);
+ rb_bool_expected(ex, "exception");
+
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
- if (len == 0)
+ if (len == 0) {
+ io_set_read_length(str, 0, shrinkable);
return str;
+ }
n = read_buffered_data(RSTRING_PTR(str), len, fptr);
if (n <= 0) {
rb_io_set_nonblock(fptr);
shrinkable |= io_setstrbuf(&str, len);
- arg.fd = fptr->fd;
- arg.str_ptr = RSTRING_PTR(str);
- arg.len = len;
- rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
- n = arg.len;
+ iis.fd = fptr->fd;
+ iis.nonblock = 1;
+ iis.buf = RSTRING_PTR(str);
+ iis.capa = len;
+ n = read_internal_locktmp(str, &iis);
if (n < 0) {
int e = errno;
if ((e == EWOULDBLOCK || e == EAGAIN)) {
- if (ex == Qfalse) return sym_wait_readable;
+ if (!ex) return sym_wait_readable;
rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE,
e, "read would block");
}
@@ -2703,7 +3155,7 @@ io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex)
io_set_read_length(str, n, shrinkable);
if (n == 0) {
- if (ex == Qfalse) return Qnil;
+ if (!ex) return Qnil;
rb_eof_error();
}
@@ -2712,28 +3164,30 @@ io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex)
/* :nodoc: */
static VALUE
-io_write_nonblock(VALUE io, VALUE str, VALUE ex)
+io_write_nonblock(rb_execution_context_t *ec, VALUE io, VALUE str, VALUE ex)
{
rb_io_t *fptr;
long n;
if (!RB_TYPE_P(str, T_STRING))
str = rb_obj_as_string(str);
+ rb_bool_expected(ex, "exception");
io = GetWriteIO(io);
GetOpenFile(io, fptr);
rb_io_check_writable(fptr);
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
rb_io_set_nonblock(fptr);
n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
+ RB_GC_GUARD(str);
- if (n == -1) {
+ if (n < 0) {
int e = errno;
if (e == EWOULDBLOCK || e == EAGAIN) {
- if (ex == Qfalse) {
+ if (!ex) {
return sym_wait_writable;
}
else {
@@ -2857,7 +3311,6 @@ io_read(int argc, VALUE *argv, VALUE io)
}
#endif
if (n == 0) return Qnil;
- OBJ_TAINT(str);
return str;
}
@@ -3034,6 +3487,12 @@ rb_io_getline_fast(rb_io_t *fptr, rb_encoding *enc, int chomp)
read_buffered_data(RSTRING_PTR(str)+len, pending - chomplen, fptr);
fptr->rbuf.off += chomplen;
fptr->rbuf.len -= chomplen;
+ if (pending == 1 && chomplen == 1 && len > 0) {
+ if (RSTRING_PTR(str)[len-1] == '\r') {
+ rb_str_resize(str, --len);
+ break;
+ }
+ }
}
len += pending - chomplen;
if (cr != ENC_CODERANGE_BROKEN)
@@ -3291,20 +3750,20 @@ rb_io_gets_internal(VALUE io)
/*
* call-seq:
- * ios.gets(sep=$/) -> string or nil
- * ios.gets(limit) -> string or nil
- * ios.gets(sep, limit) -> string or nil
+ * ios.gets(sep=$/ [, getline_args]) -> string or nil
+ * ios.gets(limit [, getline_args]) -> string or nil
+ * ios.gets(sep, limit [, getline_args]) -> string or nil
*
* Reads the next ``line'' from the I/O stream; lines are separated by
* <i>sep</i>. A separator of +nil+ reads the entire
* contents, and a zero-length separator reads the input a paragraph at
* a time (two successive newlines in the input separate paragraphs).
- * The stream must be opened for reading or an <code>IOError</code>
- * will be raised. The line read in will be returned and also assigned
- * to <code>$_</code>. Returns +nil+ if called at end of
- * file. If the first argument is an integer, or optional second
- * argument is given, the returning string would not be longer than the
- * given value in bytes.
+ * The stream must be opened for reading or an IOError will be raised.
+ * The line read in will be returned and also assigned to
+ * <code>$_</code>. Returns +nil+ if called at end of file. If the
+ * first argument is an integer, or optional second argument is given,
+ * the returning string would not be longer than the given value in
+ * bytes.
*
* File.new("testfile").gets #=> "This is line one\n"
* $_ #=> "This is line one\n"
@@ -3338,12 +3797,12 @@ rb_io_gets_m(int argc, VALUE *argv, VALUE io)
* ios.lineno -> integer
*
* Returns the current line number in <em>ios</em>. The stream must be
- * opened for reading. <code>lineno</code> counts the number of times
- * #gets is called rather than the number of newlines encountered. The two
- * values will differ if #gets is called with a separator other than newline.
+ * opened for reading. #lineno counts the number of times #gets is called
+ * rather than the number of newlines encountered. The two values will
+ * differ if #gets is called with a separator other than newline.
*
* Methods that use <code>$/</code> like #each, #lines and #readline will
- * also increment <code>lineno</code>.
+ * also increment #lineno.
*
* See also the <code>$.</code> variable.
*
@@ -3395,12 +3854,11 @@ rb_io_set_lineno(VALUE io, VALUE lineno)
/*
* call-seq:
- * ios.readline(sep=$/) -> string
- * ios.readline(limit) -> string
- * ios.readline(sep, limit) -> string
+ * ios.readline(sep=$/ [, getline_args]) -> string
+ * ios.readline(limit [, getline_args]) -> string
+ * ios.readline(sep, limit [, getline_args]) -> string
*
- * Reads a line as with <code>IO#gets</code>, but raises an
- * <code>EOFError</code> on end of file.
+ * Reads a line as with IO#gets, but raises an EOFError on end of file.
*/
static VALUE
@@ -3418,20 +3876,26 @@ static VALUE io_readlines(const struct getline_arg *arg, VALUE io);
/*
* call-seq:
- * ios.readlines(sep=$/) -> array
- * ios.readlines(limit) -> array
- * ios.readlines(sep, limit) -> array
+ * ios.readlines(sep=$/ [, getline_args]) -> array
+ * ios.readlines(limit [, getline_args]) -> array
+ * ios.readlines(sep, limit [, getline_args]) -> array
*
* Reads all of the lines in <em>ios</em>, and returns them in
- * <i>anArray</i>. Lines are separated by the optional <i>sep</i>. If
+ * an array. Lines are separated by the optional <i>sep</i>. If
* <i>sep</i> is +nil+, the rest of the stream is returned
- * as a single record. If the first argument is an integer, or
+ * as a single record.
+ * If the first argument is an integer, or an
* optional second argument is given, the returning string would not be
* longer than the given value in bytes. The stream must be opened for
- * reading or an <code>IOError</code> will be raised.
+ * reading or an IOError will be raised.
*
* f = File.new("testfile")
* f.readlines[0] #=> "This is line one\n"
+ *
+ * f = File.new("testfile", chomp: true)
+ * f.readlines[0] #=> "This is line one"
+ *
+ * See IO.readlines for details about getline_args.
*/
static VALUE
@@ -3459,19 +3923,19 @@ io_readlines(const struct getline_arg *arg, VALUE io)
/*
* call-seq:
- * ios.each(sep=$/) {|line| block } -> ios
- * ios.each(limit) {|line| block } -> ios
- * ios.each(sep, limit) {|line| block } -> ios
+ * ios.each(sep=$/ [, getline_args]) {|line| block } -> ios
+ * ios.each(limit [, getline_args]) {|line| block } -> ios
+ * ios.each(sep, limit [, getline_args]) {|line| block } -> ios
* ios.each(...) -> an_enumerator
*
- * ios.each_line(sep=$/) {|line| block } -> ios
- * ios.each_line(limit) {|line| block } -> ios
- * ios.each_line(sep, limit) {|line| block } -> ios
+ * ios.each_line(sep=$/ [, getline_args]) {|line| block } -> ios
+ * ios.each_line(limit [, getline_args]) {|line| block } -> ios
+ * ios.each_line(sep, limit [, getline_args]) {|line| block } -> ios
* ios.each_line(...) -> an_enumerator
*
* Executes the block for every line in <em>ios</em>, where lines are
* separated by <i>sep</i>. <em>ios</em> must be opened for
- * reading or an <code>IOError</code> will be raised.
+ * reading or an IOError will be raised.
*
* If no block is given, an enumerator is returned instead.
*
@@ -3484,6 +3948,8 @@ io_readlines(const struct getline_arg *arg, VALUE io)
* 2: This is line two
* 3: This is line three
* 4: And so on...
+ *
+ * See IO.readlines for details about getline_args.
*/
static VALUE
@@ -3503,26 +3969,13 @@ rb_io_each_line(int argc, VALUE *argv, VALUE io)
}
/*
- * This is a deprecated alias for <code>each_line</code>.
- */
-
-static VALUE
-rb_io_lines(int argc, VALUE *argv, VALUE io)
-{
- rb_warn("IO#lines is deprecated; use #each_line instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(io, ID2SYM(rb_intern("each_line")), argc, argv);
- return rb_io_each_line(argc, argv, io);
-}
-
-/*
* call-seq:
* ios.each_byte {|byte| block } -> ios
* ios.each_byte -> an_enumerator
*
* Calls the given block once for each byte (0..255) in <em>ios</em>,
* passing the byte as an argument. The stream must be opened for
- * reading or an <code>IOError</code> will be raised.
+ * reading or an IOError will be raised.
*
* If no block is given, an enumerator is returned instead.
*
@@ -3545,27 +3998,14 @@ rb_io_each_byte(VALUE io)
char *p = fptr->rbuf.ptr + fptr->rbuf.off++;
fptr->rbuf.len--;
rb_yield(INT2FIX(*p & 0xff));
+ rb_io_check_byte_readable(fptr);
errno = 0;
}
- rb_io_check_byte_readable(fptr);
READ_CHECK(fptr);
} while (io_fillbuf(fptr) >= 0);
return io;
}
-/*
- * This is a deprecated alias for <code>each_byte</code>.
- */
-
-static VALUE
-rb_io_bytes(VALUE io)
-{
- rb_warn("IO#bytes is deprecated; use #each_byte instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(io, ID2SYM(rb_intern("each_byte")), 0, 0);
- return rb_io_each_byte(io);
-}
-
static VALUE
io_getc(rb_io_t *fptr, rb_encoding *enc)
{
@@ -3573,9 +4013,9 @@ io_getc(rb_io_t *fptr, rb_encoding *enc)
VALUE str;
if (NEED_READCONV(fptr)) {
- VALUE str = Qnil;
rb_encoding *read_enc = io_read_encoding(fptr);
+ str = Qnil;
SET_BINARY_MODE(fptr);
make_readconv(fptr, 0);
@@ -3680,7 +4120,7 @@ io_getc(rb_io_t *fptr, rb_encoding *enc)
*
* Calls the given block once for each character in <em>ios</em>,
* passing the character as an argument. The stream must be opened for
- * reading or an <code>IOError</code> will be raised.
+ * reading or an IOError will be raised.
*
* If no block is given, an enumerator is returned instead.
*
@@ -3708,29 +4148,15 @@ rb_io_each_char(VALUE io)
}
/*
- * This is a deprecated alias for <code>each_char</code>.
- */
-
-static VALUE
-rb_io_chars(VALUE io)
-{
- rb_warn("IO#chars is deprecated; use #each_char instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(io, ID2SYM(rb_intern("each_char")), 0, 0);
- return rb_io_each_char(io);
-}
-
-
-/*
* call-seq:
* ios.each_codepoint {|c| block } -> ios
* ios.codepoints {|c| block } -> ios
* ios.each_codepoint -> an_enumerator
* ios.codepoints -> an_enumerator
*
- * Passes the <code>Integer</code> ordinal of each character in <i>ios</i>,
+ * Passes the Integer ordinal of each character in <i>ios</i>,
* passing the codepoint as an argument. The stream must be opened for
- * reading or an <code>IOError</code> will be raised.
+ * reading or an IOError will be raised.
*
* If no block is given, an enumerator is returned instead.
*
@@ -3793,6 +4219,7 @@ rb_io_each_codepoint(VALUE io)
fptr->cbuf.off += n;
fptr->cbuf.len -= n;
rb_yield(UINT2NUM(c));
+ rb_io_check_byte_readable(fptr);
}
}
NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr);
@@ -3809,8 +4236,7 @@ rb_io_each_codepoint(VALUE io)
rb_yield(UINT2NUM(c));
}
else if (MBCLEN_INVALID_P(r)) {
- invalid:
- rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
+ goto invalid;
}
else if (MBCLEN_NEEDMORE_P(r)) {
char cbuf[8], *p = cbuf;
@@ -3831,24 +4257,15 @@ rb_io_each_codepoint(VALUE io)
else {
continue;
}
+ rb_io_check_byte_readable(fptr);
}
return io;
-}
-
-/*
- * This is a deprecated alias for <code>each_codepoint</code>.
- */
-static VALUE
-rb_io_codepoints(VALUE io)
-{
- rb_warn("IO#codepoints is deprecated; use #each_codepoint instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(io, ID2SYM(rb_intern("each_codepoint")), 0, 0);
- return rb_io_each_codepoint(io);
+ invalid:
+ rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
+ UNREACHABLE_RETURN(Qundef);
}
-
/*
* call-seq:
* ios.getc -> string or nil
@@ -3880,7 +4297,7 @@ rb_io_getc(VALUE io)
* ios.readchar -> string
*
* Reads a one-character string from <em>ios</em>. Raises an
- * <code>EOFError</code> on end of file.
+ * EOFError on end of file.
*
* f = File.new("testfile")
* f.readchar #=> "h"
@@ -3919,11 +4336,12 @@ rb_io_getbyte(VALUE io)
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
READ_CHECK(fptr);
- if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && RB_TYPE_P(rb_stdout, T_FILE)) {
+ VALUE r_stdout = rb_ractor_stdout();
+ if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && RB_TYPE_P(r_stdout, T_FILE)) {
rb_io_t *ofp;
- GetOpenFile(rb_stdout, ofp);
+ GetOpenFile(r_stdout, ofp);
if (ofp->mode & FMODE_TTY) {
- rb_io_flush(rb_stdout);
+ rb_io_flush(r_stdout);
}
}
if (io_fillbuf(fptr) < 0) {
@@ -3939,8 +4357,8 @@ rb_io_getbyte(VALUE io)
* call-seq:
* ios.readbyte -> integer
*
- * Reads a byte as with <code>IO#getbyte</code>, but raises an
- * <code>EOFError</code> on end of file.
+ * Reads a byte as with IO#getbyte, but raises an EOFError on end of
+ * file.
*/
static VALUE
@@ -3963,7 +4381,7 @@ rb_io_readbyte(VALUE io)
* such that a subsequent buffered read will return it. Only one byte
* may be pushed back before a subsequent read operation (that is,
* you will be able to read only the last of several bytes that have been pushed
- * back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
+ * back). Has no effect with unbuffered reads (such as IO#sysread).
*
* f = File.new("testfile") #=> #<File:testfile>
* b = f.getbyte #=> 0x38
@@ -3978,13 +4396,17 @@ rb_io_ungetbyte(VALUE io, VALUE b)
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
- if (NIL_P(b)) return Qnil;
- if (FIXNUM_P(b)) {
- char cc = FIX2INT(b);
- b = rb_str_new(&cc, 1);
- }
- else {
- SafeStringValue(b);
+ switch (TYPE(b)) {
+ case T_NIL:
+ return Qnil;
+ case T_FIXNUM:
+ case T_BIGNUM: ;
+ VALUE v = rb_int_modulo(b, INT2FIX(256));
+ unsigned char c = NUM2INT(v) & 0xFF;
+ b = rb_str_new((const char *)&c, 1);
+ break;
+ default:
+ SafeStringValue(b);
}
io_ungetbyte(b, fptr);
return Qnil;
@@ -3998,7 +4420,7 @@ rb_io_ungetbyte(VALUE io, VALUE b)
* such that a subsequent buffered character read will return it. Only one character
* may be pushed back before a subsequent read operation (that is,
* you will be able to read only the last of several characters that have been pushed
- * back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
+ * back). Has no effect with unbuffered reads (such as IO#sysread).
*
* f = File.new("testfile") #=> #<File:testfile>
* c = f.getc #=> "8"
@@ -4014,7 +4436,6 @@ rb_io_ungetc(VALUE io, VALUE c)
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
- if (NIL_P(c)) return Qnil;
if (FIXNUM_P(c)) {
c = rb_enc_uint_chr(FIX2UINT(c), io_read_encoding(fptr));
}
@@ -4153,7 +4574,7 @@ rb_io_set_close_on_exec(VALUE io, VALUE arg)
if ((ret & FD_CLOEXEC) != flag) {
ret = (ret & ~FD_CLOEXEC) | flag;
ret = fcntl(fd, F_SETFD, ret);
- if (ret == -1) rb_sys_fail_path(fptr->pathv);
+ if (ret != 0) rb_sys_fail_path(fptr->pathv);
}
}
@@ -4165,7 +4586,7 @@ rb_io_set_close_on_exec(VALUE io, VALUE arg)
if ((ret & FD_CLOEXEC) != flag) {
ret = (ret & ~FD_CLOEXEC) | flag;
ret = fcntl(fd, F_SETFD, ret);
- if (ret == -1) rb_sys_fail_path(fptr->pathv);
+ if (ret != 0) rb_sys_fail_path(fptr->pathv);
}
}
return Qnil;
@@ -4174,7 +4595,6 @@ rb_io_set_close_on_exec(VALUE io, VALUE arg)
#define rb_io_set_close_on_exec rb_f_notimplement
#endif
-#define FMODE_PREP (1<<16)
#define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
#define PREP_STDIO_NAME(f) (RSTRING_PTR((f)->pathv))
@@ -4295,7 +4715,8 @@ static void free_io_buffer(rb_io_buffer_t *buf);
static void clear_codeconv(rb_io_t *fptr);
static void
-fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
+fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl,
+ struct list_head *busy)
{
VALUE err = Qnil;
int fd = fptr->fd;
@@ -4315,8 +4736,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
}
if (fptr->wbuf.len) {
if (noraise) {
- if ((int)io_flush_buffer_sync(fptr) < 0 && NIL_P(err))
- err = Qtrue;
+ io_flush_buffer_sync(fptr);
}
else {
if (io_fflush(fptr) < 0 && NIL_P(err))
@@ -4328,6 +4748,14 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
fptr->stdio_file = 0;
fptr->mode &= ~(FMODE_READABLE|FMODE_WRITABLE);
+ /*
+ * ensure waiting_fd users do not hit EBADF, wait for them
+ * to exit before we call close().
+ */
+ if (busy) {
+ do rb_thread_schedule(); while (!list_empty(busy));
+ }
+
if (IS_PREP_STDIO(fptr) || fd <= 2) {
/* need to keep FILE objects of stdin, stdout and stderr */
}
@@ -4335,7 +4763,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
/* stdio_file is deallocated anyway
* even if fclose failed. */
if ((maygvl_fclose(stdio_file, noraise) < 0) && NIL_P(err))
- err = noraise ? Qtrue : INT2NUM(errno);
+ if (!noraise) err = INT2NUM(errno);
}
else if (0 <= fd) {
/* fptr->fd may be closed even if close fails.
@@ -4346,7 +4774,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
keepgvl |= !(mode & FMODE_WRITABLE);
keepgvl |= noraise;
if ((maygvl_close(fd, keepgvl) < 0) && NIL_P(err))
- err = noraise ? Qtrue : INT2NUM(errno);
+ if (!noraise) err = INT2NUM(errno);
}
if (!NIL_P(err) && !noraise) {
@@ -4360,7 +4788,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
static void
fptr_finalize(rb_io_t *fptr, int noraise)
{
- fptr_finalize_flush(fptr, noraise, FALSE);
+ fptr_finalize_flush(fptr, noraise, FALSE, 0);
free_io_buffer(&fptr->rbuf);
free_io_buffer(&fptr->wbuf);
clear_codeconv(fptr);
@@ -4413,21 +4841,36 @@ clear_codeconv(rb_io_t *fptr)
clear_writeconv(fptr);
}
-int
-rb_io_fptr_finalize(rb_io_t *fptr)
+void
+rb_io_fptr_finalize_internal(void *ptr)
{
- if (!fptr) return 0;
+ rb_io_t *fptr = ptr;
+
+ if (!ptr) return;
fptr->pathv = Qnil;
if (0 <= fptr->fd)
- rb_io_fptr_cleanup(fptr, TRUE);
+ rb_io_fptr_cleanup(fptr, TRUE);
fptr->write_lock = 0;
free_io_buffer(&fptr->rbuf);
free_io_buffer(&fptr->wbuf);
clear_codeconv(fptr);
free(fptr);
- return 1;
}
+#undef rb_io_fptr_finalize
+int
+rb_io_fptr_finalize(rb_io_t *fptr)
+{
+ if (!fptr) {
+ return 0;
+ }
+ else {
+ rb_io_fptr_finalize_internal(fptr);
+ return 1;
+ }
+}
+#define rb_io_fptr_finalize(fptr) rb_io_fptr_finalize_internal(fptr)
+
RUBY_FUNC_EXPORTED size_t
rb_io_memsize(const rb_io_t *fptr)
{
@@ -4447,16 +4890,16 @@ rb_io_memsize(const rb_io_t *fptr)
# define KEEPGVL FALSE
#endif
-int rb_notify_fd_close(int fd);
+int rb_notify_fd_close(int fd, struct list_head *);
static rb_io_t *
io_close_fptr(VALUE io)
{
rb_io_t *fptr;
- int fd;
VALUE write_io;
rb_io_t *write_fptr;
- int busy;
+ struct list_head busy;
+ list_head_init(&busy);
write_io = GetWriteIO(io);
if (io != write_io) {
write_fptr = RFILE(write_io)->fptr;
@@ -4469,11 +4912,9 @@ io_close_fptr(VALUE io)
if (!fptr) return 0;
if (fptr->fd < 0) return 0;
- fd = fptr->fd;
- busy = rb_notify_fd_close(fd);
- if (busy) {
- fptr_finalize_flush(fptr, FALSE, KEEPGVL);
- do rb_thread_schedule(); while (rb_notify_fd_close(fd));
+ if (rb_notify_fd_close(fptr->fd, &busy)) {
+ /* calls close(fptr->fd): */
+ fptr_finalize_flush(fptr, FALSE, KEEPGVL, &busy);
}
rb_io_fptr_cleanup(fptr, FALSE);
return fptr;
@@ -4484,9 +4925,9 @@ fptr_waitpid(rb_io_t *fptr, int nohang)
{
int status;
if (fptr->pid) {
- rb_last_status_clear();
- rb_waitpid(fptr->pid, &status, nohang ? WNOHANG : 0);
- fptr->pid = 0;
+ rb_last_status_clear();
+ rb_waitpid(fptr->pid, &status, nohang ? WNOHANG : 0);
+ fptr->pid = 0;
}
}
@@ -4504,12 +4945,11 @@ rb_io_close(VALUE io)
*
* Closes <em>ios</em> and flushes any pending writes to the operating
* system. The stream is unavailable for any further data operations;
- * an <code>IOError</code> is raised if such an attempt is made. I/O
- * streams are automatically closed when they are claimed by the
- * garbage collector.
+ * an IOError is raised if such an attempt is made. I/O streams are
+ * automatically closed when they are claimed by the garbage collector.
*
- * If <em>ios</em> is opened by <code>IO.popen</code>,
- * <code>close</code> sets <code>$?</code>.
+ * If <em>ios</em> is opened by IO.popen, #close sets
+ * <code>$?</code>.
*
* Calling this method on closed IO object is just ignored since Ruby 2.3.
*/
@@ -4536,7 +4976,7 @@ static VALUE
ignore_closed_stream(VALUE io, VALUE exc)
{
enum {mesg_len = sizeof(closed_stream)-1};
- VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
+ VALUE mesg = rb_attr_get(exc, idMesg);
if (!RB_TYPE_P(mesg, T_STRING) ||
RSTRING_LEN(mesg) != mesg_len ||
memcmp(RSTRING_PTR(mesg), closed_stream, mesg_len)) {
@@ -4599,7 +5039,7 @@ rb_io_closed(VALUE io)
*
* Closes the read end of a duplex I/O stream (i.e., one that contains
* both a read and a write stream, such as a pipe). Will raise an
- * <code>IOError</code> if the stream is not duplexed.
+ * IOError if the stream is not duplexed.
*
* f = IO.popen("/bin/sh","r+")
* f.close_read
@@ -4609,6 +5049,8 @@ rb_io_closed(VALUE io)
*
* prog.rb:3:in `readlines': not opened for reading (IOError)
* from prog.rb:3
+ *
+ * Calling this method on closed IO object is just ignored since Ruby 2.3.
*/
static VALUE
@@ -4658,7 +5100,7 @@ rb_io_close_read(VALUE io)
*
* Closes the write end of a duplex I/O stream (i.e., one that contains
* both a read and a write stream, such as a pipe). Will raise an
- * <code>IOError</code> if the stream is not duplexed.
+ * IOError if the stream is not duplexed.
*
* f = IO.popen("/bin/sh","r+")
* f.close_write
@@ -4669,6 +5111,8 @@ rb_io_close_read(VALUE io)
* prog.rb:3:in `write': not opened for writing (IOError)
* from prog.rb:3:in `print'
* from prog.rb:3
+ *
+ * Calling this method on closed IO object is just ignored since Ruby 2.3.
*/
static VALUE
@@ -4709,8 +5153,8 @@ rb_io_close_write(VALUE io)
* ios.sysseek(offset, whence=IO::SEEK_SET) -> integer
*
* Seeks to a given <i>offset</i> in the stream according to the value
- * of <i>whence</i> (see <code>IO#seek</code> for values of
- * <i>whence</i>). Returns the new offset into the file.
+ * of <i>whence</i> (see IO#seek for values of <i>whence</i>). Returns
+ * the new offset into the file.
*
* f = File.new("testfile")
* f.sysseek(-13, IO::SEEK_END) #=> 53
@@ -4739,7 +5183,7 @@ rb_io_sysseek(int argc, VALUE *argv, VALUE io)
}
errno = 0;
pos = lseek(fptr->fd, pos, whence);
- if (pos == -1 && errno) rb_sys_fail_path(fptr->pathv);
+ if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
return OFFT2NUM(pos);
}
@@ -4751,7 +5195,7 @@ rb_io_sysseek(int argc, VALUE *argv, VALUE io)
* Writes the given string to <em>ios</em> using a low-level write.
* Returns the number of bytes written. Do not mix with other methods
* that write to <em>ios</em> or you may get unpredictable results.
- * Raises <code>SystemCallError</code> on error.
+ * Raises SystemCallError on error.
*
* f = File.new("out", "w")
* f.syswrite("ABCDEF") #=> 6
@@ -4779,7 +5223,7 @@ rb_io_syswrite(VALUE io, VALUE str)
tmp = rb_str_tmp_frozen_acquire(str);
RSTRING_GETMEM(tmp, ptr, len);
n = rb_write_internal(fptr->fd, ptr, len);
- if (n == -1) rb_sys_fail_path(fptr->pathv);
+ if (n < 0) rb_sys_fail_path(fptr->pathv);
rb_str_tmp_frozen_release(str, tmp);
return LONG2FIX(n);
@@ -4798,8 +5242,7 @@ rb_io_syswrite(VALUE io, VALUE str)
* The _outbuf_ will contain only the received data after the method call
* even if it is not empty at the beginning.
*
- * Raises <code>SystemCallError</code> on error and
- * <code>EOFError</code> at end of file.
+ * Raises SystemCallError on error and EOFError at end of file.
*
* f = File.new("testfile")
* f.sysread(16) #=> "This is line one"
@@ -4811,7 +5254,7 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
VALUE len, str;
rb_io_t *fptr;
long n, ilen;
- struct read_internal_arg arg;
+ struct io_internal_read_struct iis;
int shrinkable;
rb_scan_args(argc, argv, "11", &len, &str);
@@ -4839,21 +5282,19 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
rb_io_check_closed(fptr);
io_setstrbuf(&str, ilen);
- rb_str_locktmp(str);
- arg.fd = fptr->fd;
- arg.str_ptr = RSTRING_PTR(str);
- arg.len = ilen;
- rb_ensure(read_internal_call, (VALUE)&arg, rb_str_unlocktmp, str);
- n = arg.len;
+ iis.fd = fptr->fd;
+ iis.nonblock = 1; /* for historical reasons, maybe (see above) */
+ iis.buf = RSTRING_PTR(str);
+ iis.capa = ilen;
+ n = read_internal_locktmp(str, &iis);
- if (n == -1) {
+ if (n < 0) {
rb_sys_fail_path(fptr->pathv);
}
io_set_read_length(str, n, shrinkable);
if (n == 0 && ilen > 0) {
rb_eof_error();
}
- OBJ_TAINT(str);
return str;
}
@@ -4894,14 +5335,15 @@ pread_internal_call(VALUE arg)
* This bypasses any userspace buffering of the IO layer.
* If the optional <i>outbuf</i> argument is present, it must
* reference a String, which will receive the data.
- * Raises <code>SystemCallError</code> on error, <code>EOFError</code>
- * at end of file and <code>NotImplementedError</code> if platform does not
- * implement the system call.
- *
- * f = File.new("testfile")
- * f.read #=> "This is line one\nThis is line two\n"
- * f.pread(12, 0) #=> "This is line"
- * f.pread(9, 8) #=> "line one\n"
+ * Raises SystemCallError on error, EOFError at end of file and
+ * NotImplementedError if platform does not implement the system call.
+ *
+ * File.write("testfile", "This is line one\nThis is line two\n")
+ * File.open("testfile") do |f|
+ * p f.read # => "This is line one\nThis is line two\n"
+ * p f.pread(12, 0) # => "This is line"
+ * p f.pread(9, 8) # => "line one\n"
+ * end
*/
static VALUE
rb_io_pread(int argc, VALUE *argv, VALUE io)
@@ -4929,14 +5371,13 @@ rb_io_pread(int argc, VALUE *argv, VALUE io)
rb_str_locktmp(str);
n = (ssize_t)rb_ensure(pread_internal_call, (VALUE)&arg, rb_str_unlocktmp, str);
- if (n == -1) {
+ if (n < 0) {
rb_sys_fail_path(fptr->pathv);
}
io_set_read_length(str, n, shrinkable);
if (n == 0 && arg.count > 0) {
rb_eof_error();
}
- OBJ_TAINT(str);
return str;
}
@@ -4963,13 +5404,14 @@ internal_pwrite_func(void *ptr)
* same IO object for reading the file at various locations.
* This bypasses any userspace buffering of the IO layer.
* Returns the number of bytes written.
- * Raises <code>SystemCallError</code> on error and <code>NotImplementedError</code>
+ * Raises SystemCallError on error and NotImplementedError
* if platform does not implement the system call.
*
- * f = File.new("out", "w")
- * f.pwrite("ABCDEF", 3) #=> 6
+ * File.open("out", "w") do |f|
+ * f.pwrite("ABCDEF", 3) #=> 6
+ * end
*
- * File.read("out") #=> "\u0000\u0000\u0000ABCDEF"
+ * File.read("out") #=> "\u0000\u0000\u0000ABCDEF"
*/
static VALUE
rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
@@ -4977,12 +5419,11 @@ rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
rb_io_t *fptr;
ssize_t n;
struct prdwr_internal_arg arg;
+ VALUE tmp;
if (!RB_TYPE_P(str, T_STRING))
str = rb_obj_as_string(str);
- arg.buf = RSTRING_PTR(str);
- arg.count = (size_t)RSTRING_LEN(str);
arg.offset = NUM2OFFT(offset);
io = GetWriteIO(io);
@@ -4990,10 +5431,13 @@ rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
rb_io_check_writable(fptr);
arg.fd = fptr->fd;
- n = (ssize_t)rb_thread_io_blocking_region(internal_pwrite_func, &arg, fptr->fd);
- RB_GC_GUARD(str);
+ tmp = rb_str_tmp_frozen_acquire(str);
+ arg.buf = RSTRING_PTR(tmp);
+ arg.count = (size_t)RSTRING_LEN(tmp);
- if (n == -1) rb_sys_fail_path(fptr->pathv);
+ n = (ssize_t)rb_thread_io_blocking_region(internal_pwrite_func, &arg, fptr->fd);
+ if (n < 0) rb_sys_fail_path(fptr->pathv);
+ rb_str_tmp_frozen_release(str, tmp);
return SSIZET2NUM(n);
}
@@ -5112,10 +5556,10 @@ rb_io_fmode_modestr(int fmode)
case FMODE_READABLE:
return MODE_BTMODE("r", "rb", "rt");
case FMODE_WRITABLE:
- return MODE_BTMODE("w", "wb", "wt");
+ return MODE_BTXMODE("w", "wb", "wt", "wx", "wbx", "wtx");
case FMODE_READWRITE:
if (fmode & FMODE_CREATE) {
- return MODE_BTMODE("w+", "wb+", "wt+");
+ return MODE_BTXMODE("w+", "wb+", "wt+", "w+x", "wb+x", "wt+x");
}
return MODE_BTMODE("r+", "rb+", "rt+");
}
@@ -5149,8 +5593,7 @@ rb_io_modestr_fmode(const char *modestr)
fmode |= FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE;
break;
default:
- error:
- rb_raise(rb_eArgError, "invalid access mode %s", modestr);
+ goto error;
}
while (*m) {
@@ -5164,6 +5607,11 @@ rb_io_modestr_fmode(const char *modestr)
case '+':
fmode |= FMODE_READWRITE;
break;
+ case 'x':
+ if (modestr[0] != 'w')
+ goto error;
+ fmode |= FMODE_EXCL;
+ break;
default:
goto error;
case ':':
@@ -5179,6 +5627,10 @@ rb_io_modestr_fmode(const char *modestr)
goto error;
return fmode;
+
+ error:
+ rb_raise(rb_eArgError, "invalid access mode %s", modestr);
+ UNREACHABLE_RETURN(Qundef);
}
int
@@ -5207,6 +5659,9 @@ rb_io_oflags_fmode(int oflags)
if (oflags & O_CREAT) {
fmode |= FMODE_CREATE;
}
+ if (oflags & O_EXCL) {
+ fmode |= FMODE_EXCL;
+ }
#ifdef O_BINARY
if (oflags & O_BINARY) {
fmode |= FMODE_BINMODE;
@@ -5242,6 +5697,9 @@ rb_io_fmode_oflags(int fmode)
if (fmode & FMODE_CREATE) {
oflags |= O_CREAT;
}
+ if (fmode & FMODE_EXCL) {
+ oflags |= O_EXCL;
+ }
#ifdef O_BINARY
if (fmode & FMODE_BINMODE) {
oflags |= O_BINARY;
@@ -5265,7 +5723,11 @@ rb_io_oflags_modestr(int oflags)
#else
# define MODE_BINARY(a,b) (a)
#endif
- int accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR);
+ int accmode;
+ if (oflags & O_EXCL) {
+ rb_raise(rb_eArgError, "exclusive access mode is not supported");
+ }
+ accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR);
if (oflags & O_APPEND) {
if (accmode == O_WRONLY) {
return MODE_BINARY("a", "ab");
@@ -5274,7 +5736,7 @@ rb_io_oflags_modestr(int oflags)
return MODE_BINARY("a+", "ab+");
}
}
- switch (oflags & (O_RDONLY|O_WRONLY|O_RDWR)) {
+ switch (accmode) {
default:
rb_raise(rb_eArgError, "invalid access oflags 0x%x", oflags);
case O_RDONLY:
@@ -5523,7 +5985,7 @@ extract_binmode(VALUE opthash, int *fmode)
}
}
-static void
+void
rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
int *oflags_p, int *fmode_p, convconfig_t *convconfig_p)
{
@@ -5581,6 +6043,18 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
#endif
SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags);
ecopts = Qnil;
+ if (fmode & FMODE_BINMODE) {
+#ifdef O_BINARY
+ oflags |= O_BINARY;
+#endif
+ if (!has_enc)
+ rb_io_ext_int_to_encs(rb_ascii8bit_encoding(), NULL, &enc, &enc2, fmode);
+ }
+#if DEFAULT_TEXTMODE
+ else if (NIL_P(vmode)) {
+ fmode |= DEFAULT_TEXTMODE;
+ }
+#endif
}
else {
VALUE v;
@@ -5761,7 +6235,10 @@ static int
io_strip_bom(VALUE io)
{
VALUE b1, b2, b3, b4;
+ rb_io_t *fptr;
+ GetOpenFile(io, fptr);
+ if (!(fptr->mode & FMODE_READABLE)) return 0;
if (NIL_P(b1 = rb_io_getbyte(io))) return 0;
switch (b1) {
case INT2FIX(0xEF):
@@ -5792,12 +6269,9 @@ io_strip_bom(VALUE io)
return ENCINDEX_UTF_32LE;
}
rb_io_ungetbyte(io, b4);
- rb_io_ungetbyte(io, b3);
- }
- else {
- rb_io_ungetbyte(io, b3);
- return ENCINDEX_UTF_16LE;
}
+ rb_io_ungetbyte(io, b3);
+ return ENCINDEX_UTF_16LE;
}
rb_io_ungetbyte(io, b2);
break;
@@ -5820,20 +6294,23 @@ io_strip_bom(VALUE io)
return 0;
}
-static void
+static rb_encoding *
io_set_encoding_by_bom(VALUE io)
{
int idx = io_strip_bom(io);
rb_io_t *fptr;
+ rb_encoding *extenc = NULL;
GetOpenFile(io, fptr);
if (idx) {
- io_encoding_set(fptr, rb_enc_from_encoding(rb_enc_from_index(idx)),
- rb_io_internal_encoding(io), Qnil);
+ extenc = rb_enc_from_index(idx);
+ io_encoding_set(fptr, rb_enc_from_encoding(extenc),
+ rb_io_internal_encoding(io), Qnil);
}
else {
fptr->encs.enc2 = NULL;
}
+ return extenc;
}
static VALUE
@@ -5881,6 +6358,8 @@ rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
if (p) {
parse_mode_enc(p+1, rb_usascii_encoding(),
&convconfig.enc, &convconfig.enc2, &fmode);
+ convconfig.ecflags = 0;
+ convconfig.ecopts = Qnil;
}
else {
rb_encoding *e;
@@ -5932,23 +6411,16 @@ pipe_add_fptr(rb_io_t *fptr)
static void
pipe_del_fptr(rb_io_t *fptr)
{
- struct pipe_list *list = pipe_list;
+ struct pipe_list **prev = &pipe_list;
struct pipe_list *tmp;
- if (list->fptr == fptr) {
- pipe_list = list->next;
- free(list);
- return;
- }
-
- while (list->next) {
- if (list->next->fptr == fptr) {
- tmp = list->next;
- list->next = list->next->next;
+ while ((tmp = *prev) != 0) {
+ if (tmp->fptr == fptr) {
+ *prev = tmp->next;
free(tmp);
return;
}
- list = list->next;
+ prev = &tmp->next;
}
}
@@ -5973,7 +6445,7 @@ pipe_finalize(rb_io_t *fptr, int noraise)
#if !defined(HAVE_WORKING_FORK) && !defined(_WIN32)
int status = 0;
if (fptr->stdio_file) {
- status = pclose(fptr->stdio_file);
+ status = pclose(fptr->stdio_file);
}
fptr->fd = -1;
fptr->stdio_file = 0;
@@ -5985,6 +6457,31 @@ pipe_finalize(rb_io_t *fptr, int noraise)
}
#endif
+static void
+fptr_copy_finalizer(rb_io_t *fptr, const rb_io_t *orig)
+{
+#if defined(__CYGWIN__) || !defined(HAVE_WORKING_FORK)
+ void (*const old_finalize)(struct rb_io_t*,int) = fptr->finalize;
+
+ if (old_finalize == orig->finalize) return;
+#endif
+
+ fptr->finalize = orig->finalize;
+
+#if defined(__CYGWIN__) || !defined(HAVE_WORKING_FORK)
+ if (old_finalize != pipe_finalize) {
+ struct pipe_list *list;
+ for (list = pipe_list; list; list = list->next) {
+ if (list->fptr == fptr) break;
+ }
+ if (!list) pipe_add_fptr(fptr);
+ }
+ else {
+ pipe_del_fptr(fptr);
+ }
+#endif
+}
+
void
rb_io_synchronized(rb_io_t *fptr)
{
@@ -6003,7 +6500,7 @@ rb_pipe(int *pipes)
{
int ret;
ret = rb_cloexec_pipe(pipes);
- if (ret == -1) {
+ if (ret < 0) {
if (rb_gc_for_fd(errno)) {
ret = rb_cloexec_pipe(pipes);
}
@@ -6080,9 +6577,9 @@ linux_get_maxfd(void)
char buf[4096], *p, *np, *e;
ssize_t ss;
fd = rb_cloexec_open("/proc/self/status", O_RDONLY|O_NOCTTY, 0);
- if (fd == -1) return -1;
+ if (fd < 0) return fd;
ss = read(fd, buf, sizeof(buf));
- if (ss == -1) goto err;
+ if (ss < 0) goto err;
p = buf;
e = buf + ss;
while ((int)sizeof("FDSize:\t0\n")-1 <= e-p &&
@@ -6101,7 +6598,7 @@ linux_get_maxfd(void)
err:
close(fd);
- return -1;
+ return (int)ss;
}
#endif
@@ -6271,7 +6768,7 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode,
# if defined(HAVE_SPAWNVE)
if (eargp->envp_str) envp = (char **)RSTRING_PTR(eargp->envp_str);
# endif
- while ((pid = DO_SPAWN(cmd, args, envp)) == -1) {
+ while ((pid = DO_SPAWN(cmd, args, envp)) < 0) {
/* exec failed */
switch (e = errno) {
case EAGAIN:
@@ -6304,7 +6801,7 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode,
}
/* parent */
- if (pid == -1) {
+ if (pid < 0) {
# if defined(HAVE_WORKING_FORK)
e = errno;
# endif
@@ -6415,7 +6912,7 @@ pipe_open_s(VALUE prog, const char *modestr, int fmode,
VALUE execarg_obj = Qnil;
if (!is_popen_fork(prog))
- execarg_obj = rb_execarg_new(argc, argv, TRUE);
+ execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
return pipe_open(execarg_obj, modestr, fmode, convconfig);
}
@@ -6429,6 +6926,8 @@ pipe_close(VALUE io)
return Qnil;
}
+static VALUE popen_finish(VALUE port, VALUE klass);
+
/*
* call-seq:
* IO.popen([env,] cmd, mode="r" [, opt]) -> io
@@ -6436,7 +6935,7 @@ pipe_close(VALUE io)
*
* Runs the specified command as a subprocess; the subprocess's
* standard input and output will be connected to the returned
- * <code>IO</code> object.
+ * IO object.
*
* The PID of the started process can be obtained by IO#pid method.
*
@@ -6455,7 +6954,7 @@ pipe_close(VALUE io)
* If <i>cmd</i> is an +Array+ of +String+,
* then it will be used as the subprocess's +argv+ bypassing a shell.
* The array can contain a hash at first for environments and
- * a hash at last for options similar to <code>spawn</code>.
+ * a hash at last for options similar to #spawn.
*
* The default mode for the new file object is ``r'',
* but <i>mode</i> may be set to any of the modes listed in the description for class IO.
@@ -6477,15 +6976,13 @@ pipe_close(VALUE io)
* ls_result_with_error = ls_io.read
* }
*
- * Raises exceptions which <code>IO.pipe</code> and
- * <code>Kernel.spawn</code> raise.
+ * Raises exceptions which IO.pipe and Kernel.spawn raise.
*
* If a block is given, Ruby will run the command as a child connected
* to Ruby with a pipe. Ruby's end of the pipe will be passed as a
* parameter to the block.
* At the end of block, Ruby closes the pipe and sets <code>$?</code>.
- * In this case <code>IO.popen</code> returns
- * the value of the block.
+ * In this case IO.popen returns the value of the block.
*
* If a block is given with a _cmd_ of ``<code>-</code>'',
* the block will be run in two separate processes: once in the parent,
@@ -6520,10 +7017,7 @@ pipe_close(VALUE io)
static VALUE
rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
{
- const char *modestr;
- VALUE pname, pmode = Qnil, port, tmp, opt = Qnil, env = Qnil, execarg_obj = Qnil;
- int oflags, fmode;
- convconfig_t convconfig;
+ VALUE pname, pmode = Qnil, opt = Qnil, env = Qnil;
if (argc > 1 && !NIL_P(opt = rb_check_hash_type(argv[argc-1]))) --argc;
if (argc > 1 && !NIL_P(env = rb_check_hash_type(argv[0]))) --argc, ++argv;
@@ -6539,6 +7033,16 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
rb_error_arity(argc + ex, 1 + ex, 2 + ex);
}
}
+ return popen_finish(rb_io_popen(pname, pmode, env, opt), klass);
+}
+
+VALUE
+rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt)
+{
+ const char *modestr;
+ VALUE tmp, execarg_obj = Qnil;
+ int oflags, fmode;
+ convconfig_t convconfig;
tmp = rb_check_array_type(pname);
if (!NIL_P(tmp)) {
@@ -6548,14 +7052,14 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
rb_raise(rb_eArgError, "too many arguments");
}
#endif
- execarg_obj = rb_execarg_new((int)len, RARRAY_CONST_PTR(tmp), FALSE);
+ execarg_obj = rb_execarg_new((int)len, RARRAY_CONST_PTR(tmp), FALSE, FALSE);
RB_GC_GUARD(tmp);
}
else {
SafeStringValue(pname);
execarg_obj = Qnil;
if (!is_popen_fork(pname))
- execarg_obj = rb_execarg_new(1, &pname, TRUE);
+ execarg_obj = rb_execarg_new(1, &pname, TRUE, FALSE);
}
if (!NIL_P(execarg_obj)) {
if (!NIL_P(opt))
@@ -6566,13 +7070,18 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
rb_io_extract_modeenc(&pmode, 0, opt, &oflags, &fmode, &convconfig);
modestr = rb_io_oflags_modestr(oflags);
- port = pipe_open(execarg_obj, modestr, fmode, &convconfig);
+ return pipe_open(execarg_obj, modestr, fmode, &convconfig);
+}
+
+static VALUE
+popen_finish(VALUE port, VALUE klass)
+{
if (NIL_P(port)) {
/* child */
if (rb_block_given_p()) {
rb_yield(Qnil);
- rb_io_flush(rb_stdout);
- rb_io_flush(rb_stderr);
+ rb_io_flush(rb_ractor_stdout());
+ rb_io_flush(rb_ractor_stderr());
_exit(0);
}
return Qnil;
@@ -6630,11 +7139,11 @@ rb_open_file(int argc, const VALUE *argv, VALUE io)
* File.open(filename, mode="r" [, opt]) {|file| block } -> obj
* File.open(filename [, mode [, perm]] [, opt]) {|file| block } -> obj
*
- * With no associated block, <code>File.open</code> is a synonym for
+ * With no associated block, File.open is a synonym for
* File.new. If the optional code block is given, it will
* be passed the opened +file+ as an argument and the File object will
* automatically be closed when the block terminates. The value of the block
- * will be returned from <code>File.open</code>.
+ * will be returned from File.open.
*
* If a file is being created, its initial permissions may be set using the
* +perm+ parameter. See File.new for further discussion.
@@ -6649,7 +7158,7 @@ rb_open_file(int argc, const VALUE *argv, VALUE io)
* IO.open(fd, mode="r" [, opt]) -> io
* IO.open(fd, mode="r" [, opt]) {|io| block } -> obj
*
- * With no associated block, <code>IO.open</code> is a synonym for IO.new. If
+ * With no associated block, IO.open is a synonym for IO.new. If
* the optional code block is given, it will be passed +io+ as an argument,
* and the IO object will automatically be closed when the block terminates.
* In this instance, IO.open returns the value of the block.
@@ -6660,7 +7169,7 @@ rb_open_file(int argc, const VALUE *argv, VALUE io)
static VALUE
rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
- VALUE io = rb_class_new_instance(argc, argv, klass);
+ VALUE io = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
@@ -6674,13 +7183,13 @@ rb_io_s_open(int argc, VALUE *argv, VALUE klass)
* IO.sysopen(path, [mode, [perm]]) -> integer
*
* Opens the given path, returning the underlying file descriptor as a
- * <code>Integer</code>.
+ * Integer.
*
* IO.sysopen("testfile") #=> 3
*/
static VALUE
-rb_io_s_sysopen(int argc, VALUE *argv)
+rb_io_s_sysopen(int argc, VALUE *argv, VALUE _)
{
VALUE fname, vmode, vperm;
VALUE intmode;
@@ -6716,7 +7225,6 @@ check_pipe_command(VALUE filename_or_command)
if (rb_enc_ascget(s, e, &chlen, rb_enc_get(filename_or_command)) == '|') {
VALUE cmd = rb_str_new(s+chlen, l-chlen);
- OBJ_INFECT(cmd, filename_or_command);
return cmd;
}
return Qnil;
@@ -6821,7 +7329,7 @@ check_pipe_command(VALUE filename_or_command)
*/
static VALUE
-rb_f_open(int argc, VALUE *argv)
+rb_f_open(int argc, VALUE *argv, VALUE _)
{
ID to_open = 0;
int redirect = FALSE;
@@ -6847,7 +7355,7 @@ rb_f_open(int argc, VALUE *argv)
}
}
if (redirect) {
- VALUE io = rb_funcallv(argv[0], to_open, argc-1, argv+1);
+ VALUE io = rb_funcallv_kw(argv[0], to_open, argc-1, argv+1, RB_PASS_CALLED_KEYWORDS);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
@@ -6857,10 +7365,10 @@ rb_f_open(int argc, VALUE *argv)
return rb_io_s_open(argc, argv, rb_cFile);
}
-static VALUE rb_io_open_generic(VALUE, int, int, const convconfig_t *, mode_t);
+static VALUE rb_io_open_generic(VALUE, VALUE, int, int, const convconfig_t *, mode_t);
static VALUE
-rb_io_open(VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
+rb_io_open(VALUE io, VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
{
int oflags, fmode;
convconfig_t convconfig;
@@ -6868,34 +7376,24 @@ rb_io_open(VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, &convconfig);
perm = NIL_P(vperm) ? 0666 : NUM2MODET(vperm);
- return rb_io_open_generic(filename, oflags, fmode, &convconfig, perm);
+ return rb_io_open_generic(io, filename, oflags, fmode, &convconfig, perm);
}
static VALUE
-rb_io_open_generic(VALUE filename, int oflags, int fmode,
+rb_io_open_generic(VALUE klass, VALUE filename, int oflags, int fmode,
const convconfig_t *convconfig, mode_t perm)
{
VALUE cmd;
- if (!NIL_P(cmd = check_pipe_command(filename))) {
+ if (klass == rb_cIO && !NIL_P(cmd = check_pipe_command(filename))) {
return pipe_open_s(cmd, rb_io_oflags_modestr(oflags), fmode, convconfig);
}
else {
- return rb_file_open_generic(io_alloc(rb_cFile), filename,
+ return rb_file_open_generic(io_alloc(klass), filename,
oflags, fmode, convconfig, perm);
}
}
static VALUE
-rb_io_open_with_args(int argc, const VALUE *argv)
-{
- VALUE io;
-
- io = io_alloc(rb_cFile);
- rb_open_file(argc, argv, io);
- return io;
-}
-
-static VALUE
io_reopen(VALUE io, VALUE nfile)
{
rb_io_t *fptr, *orig;
@@ -6919,17 +7417,17 @@ io_reopen(VALUE io, VALUE nfile)
}
if (fptr->mode & FMODE_WRITABLE) {
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
}
else {
- io_tell(fptr);
+ flush_before_seek(fptr);
}
if (orig->mode & FMODE_READABLE) {
pos = io_tell(orig);
}
if (orig->mode & FMODE_WRITABLE) {
if (io_fflush(orig) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
}
/* copy rb_io_t structure */
@@ -6938,11 +7436,7 @@ io_reopen(VALUE io, VALUE nfile)
fptr->lineno = orig->lineno;
if (RTEST(orig->pathv)) fptr->pathv = orig->pathv;
else if (!IS_PREP_STDIO(fptr)) fptr->pathv = Qnil;
- fptr->finalize = orig->finalize;
-#if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK)
- if (fptr->finalize == pipe_finalize)
- pipe_add_fptr(fptr);
-#endif
+ fptr_copy_finalizer(fptr, orig);
fd = fptr->fd;
fd2 = orig->fd;
@@ -6962,7 +7456,7 @@ io_reopen(VALUE io, VALUE nfile)
rb_update_max_fd(fd);
fptr->fd = fd;
}
- rb_notify_fd_close(fd);
+ rb_thread_fd_close(fd);
if ((orig->mode & FMODE_READABLE) && pos >= 0) {
if (io_seek(fptr, pos, SEEK_SET) < 0 && errno) {
rb_sys_fail_path(fptr->pathv);
@@ -6997,12 +7491,13 @@ rb_freopen(VALUE fname, const char *mode, FILE *fp)
/*
* call-seq:
- * ios.reopen(other_IO) -> ios
- * ios.reopen(path, mode_str) -> ios
+ * ios.reopen(other_IO) -> ios
+ * ios.reopen(path, mode [, opt]) -> ios
*
* Reassociates <em>ios</em> with the I/O stream given in
* <i>other_IO</i> or to a new stream opened on <i>path</i>. This may
* dynamically change the actual class of this stream.
+ * The +mode+ and +opt+ parameters accept the same values as IO.open.
*
* f1 = File.new("testfile")
* f2 = File.new("testfile")
@@ -7061,7 +7556,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
if (fptr->mode & FMODE_WRITABLE) {
if (io_fflush(fptr) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(fptr);
}
fptr->rbuf.off = fptr->rbuf.len = 0;
@@ -7069,7 +7564,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
int e = rb_freopen(rb_str_encode_ospath(fptr->pathv),
rb_io_oflags_modestr(oflags),
fptr->stdio_file);
- if (e) rb_syserr_fail_path(e, fptr->pathv);
+ if (e) rb_syserr_fail_path(e, fptr->pathv);
fptr->fd = fileno(fptr->stdio_file);
rb_fd_fix_cloexec(fptr->fd);
#ifdef USE_SETVBUF
@@ -7121,11 +7616,7 @@ rb_io_init_copy(VALUE dest, VALUE io)
fptr->pid = orig->pid;
fptr->lineno = orig->lineno;
if (!NIL_P(orig->pathv)) fptr->pathv = orig->pathv;
- fptr->finalize = orig->finalize;
-#if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK)
- if (fptr->finalize == pipe_finalize)
- pipe_add_fptr(fptr);
-#endif
+ fptr_copy_finalizer(fptr, orig);
fd = ruby_dup(orig->fd);
fptr->fd = fd;
@@ -7151,8 +7642,7 @@ rb_io_init_copy(VALUE dest, VALUE io)
* ios.printf(format_string [, obj, ...]) -> nil
*
* Formats and writes to <em>ios</em>, converting parameters under
- * control of the format string. See <code>Kernel#sprintf</code>
- * for details.
+ * control of the format string. See Kernel#sprintf for details.
*/
VALUE
@@ -7174,13 +7664,13 @@ rb_io_printf(int argc, const VALUE *argv, VALUE out)
*/
static VALUE
-rb_f_printf(int argc, VALUE *argv)
+rb_f_printf(int argc, VALUE *argv, VALUE _)
{
VALUE out;
if (argc == 0) return Qnil;
if (RB_TYPE_P(argv[0], T_STRING)) {
- out = rb_stdout;
+ out = rb_ractor_stdout();
}
else {
out = argv[0];
@@ -7192,6 +7682,16 @@ rb_f_printf(int argc, VALUE *argv)
return Qnil;
}
+static void
+deprecated_str_setter(VALUE val, ID id, VALUE *var)
+{
+ rb_str_setter(val, id, &val);
+ if (!NIL_P(val)) {
+ rb_warn_deprecated("`%s'", NULL, rb_id2name(id));
+ }
+ *var = val;
+}
+
/*
* call-seq:
* ios.print -> nil
@@ -7228,6 +7728,9 @@ rb_io_print(int argc, const VALUE *argv, VALUE out)
line = rb_lastline_get();
argv = &line;
}
+ if (argc > 1 && !NIL_P(rb_output_fs)) {
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
+ }
for (i=0; i<argc; i++) {
if (!NIL_P(rb_output_fs) && i>0) {
rb_io_write(out, rb_output_fs);
@@ -7265,9 +7768,9 @@ rb_io_print(int argc, const VALUE *argv, VALUE out)
*/
static VALUE
-rb_f_print(int argc, const VALUE *argv)
+rb_f_print(int argc, const VALUE *argv, VALUE _)
{
- rb_io_print(argc, argv, rb_stdout);
+ rb_io_print(argc, argv, rb_ractor_stdout());
return Qnil;
}
@@ -7275,11 +7778,10 @@ rb_f_print(int argc, const VALUE *argv)
* call-seq:
* ios.putc(obj) -> obj
*
- * If <i>obj</i> is <code>Numeric</code>, write the character whose code is
- * the least-significant byte of <i>obj</i>, otherwise write the first byte
- * of the string representation of <i>obj</i> to <em>ios</em>. Note: This
- * method is not safe for use with multi-byte characters as it will truncate
- * them.
+ * If <i>obj</i> is Numeric, write the character whose code is the
+ * least-significant byte of <i>obj</i>. If <i>obj</i> is String,
+ * write the first character of <i>obj</i> to <em>ios</em>. Otherwise,
+ * raise TypeError.
*
* $stdout.putc "A"
* $stdout.putc 65
@@ -7319,10 +7821,11 @@ rb_io_putc(VALUE io, VALUE ch)
static VALUE
rb_f_putc(VALUE recv, VALUE ch)
{
- if (recv == rb_stdout) {
+ VALUE r_stdout = rb_ractor_stdout();
+ if (recv == r_stdout) {
return rb_io_putc(recv, ch);
}
- return rb_funcallv(rb_stdout, rb_intern("putc"), 1, &ch);
+ return rb_funcallv(r_stdout, rb_intern("putc"), 1, &ch);
}
@@ -7391,8 +7894,8 @@ io_puts_ary(VALUE ary, VALUE out, int recur)
VALUE
rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
- int i;
- VALUE line;
+ int i, n;
+ VALUE line, args[2];
/* if no argument given, print newline. */
if (argc == 0) {
@@ -7409,11 +7912,13 @@ rb_io_puts(int argc, const VALUE *argv, VALUE out)
}
line = rb_obj_as_string(argv[i]);
string:
- rb_io_write(out, line);
+ n = 0;
+ args[n++] = line;
if (RSTRING_LEN(line) == 0 ||
!rb_str_end_with_asciichar(line, '\n')) {
- rb_io_write(out, rb_default_rs);
+ args[n++] = rb_default_rs;
}
+ rb_io_writev(out, n, args);
}
return Qnil;
@@ -7431,52 +7936,50 @@ rb_io_puts(int argc, const VALUE *argv, VALUE out)
static VALUE
rb_f_puts(int argc, VALUE *argv, VALUE recv)
{
- if (recv == rb_stdout) {
+ VALUE r_stdout = rb_ractor_stdout();
+ if (recv == r_stdout) {
return rb_io_puts(argc, argv, recv);
}
- return rb_funcallv(rb_stdout, rb_intern("puts"), argc, argv);
+ return rb_funcallv(r_stdout, rb_intern("puts"), argc, argv);
}
-void
-rb_p(VALUE obj) /* for debug print within C code */
+static VALUE
+rb_p_write(VALUE str)
{
- VALUE str = rb_obj_as_string(rb_inspect(obj));
- if (RB_TYPE_P(rb_stdout, T_FILE) &&
- rb_method_basic_definition_p(CLASS_OF(rb_stdout), id_write)) {
- io_write(rb_stdout, str, 1);
- io_write(rb_stdout, rb_default_rs, 0);
+ VALUE args[2];
+ args[0] = str;
+ args[1] = rb_default_rs;
+ VALUE r_stdout = rb_ractor_stdout();
+ if (RB_TYPE_P(r_stdout, T_FILE) &&
+ rb_method_basic_definition_p(CLASS_OF(r_stdout), id_write)) {
+ io_writev(2, args, r_stdout);
}
else {
- rb_io_write(rb_stdout, str);
- rb_io_write(rb_stdout, rb_default_rs);
+ rb_io_writev(r_stdout, 2, args);
}
+ return Qnil;
}
-struct rb_f_p_arg {
- int argc;
- VALUE *argv;
-};
+void
+rb_p(VALUE obj) /* for debug print within C code */
+{
+ rb_p_write(rb_obj_as_string(rb_inspect(obj)));
+}
static VALUE
-rb_f_p_internal(VALUE arg)
+rb_p_result(int argc, const VALUE *argv)
{
- struct rb_f_p_arg *arg1 = (struct rb_f_p_arg*)arg;
- int argc = arg1->argc;
- VALUE *argv = arg1->argv;
- int i;
VALUE ret = Qnil;
- for (i=0; i<argc; i++) {
- rb_p(argv[i]);
- }
if (argc == 1) {
ret = argv[0];
}
else if (argc > 1) {
ret = rb_ary_new4(argc, argv);
}
- if (RB_TYPE_P(rb_stdout, T_FILE)) {
- rb_io_flush(rb_stdout);
+ VALUE r_stdout = rb_ractor_stdout();
+ if (RB_TYPE_P(r_stdout, T_FILE)) {
+ rb_io_flush(r_stdout);
}
return ret;
}
@@ -7502,11 +8005,12 @@ rb_f_p_internal(VALUE arg)
static VALUE
rb_f_p(int argc, VALUE *argv, VALUE self)
{
- struct rb_f_p_arg arg;
- arg.argc = argc;
- arg.argv = argv;
-
- return rb_uninterruptible(rb_f_p_internal, (VALUE)&arg);
+ int i;
+ for (i=0; i<argc; i++) {
+ VALUE inspected = rb_obj_as_string(rb_inspect(argv[i]));
+ rb_uninterruptible(rb_p_write, inspected);
+ }
+ return rb_p_result(argc, argv);
}
/*
@@ -7538,28 +8042,34 @@ rb_obj_display(int argc, VALUE *argv, VALUE self)
{
VALUE out;
- if (argc == 0) {
- out = rb_stdout;
- }
- else {
- rb_scan_args(argc, argv, "01", &out);
- }
+ out = (!rb_check_arity(argc, 0, 1) ? rb_ractor_stdout() : argv[0]);
rb_io_write(out, self);
return Qnil;
}
+static int
+rb_stderr_to_original_p(void)
+{
+ return (rb_ractor_stderr() == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0);
+}
+
void
rb_write_error2(const char *mesg, long len)
{
- if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0) {
+ if (rb_stderr_to_original_p()) {
+#ifdef _WIN32
+ if (isatty(fileno(stderr))) {
+ if (rb_w32_write_console(rb_str_new(mesg, len), fileno(stderr)) > 0) return;
+ }
+#endif
if (fwrite(mesg, sizeof(char), (size_t)len, stderr) < (size_t)len) {
/* failed to write to stderr, what can we do? */
return;
}
}
else {
- rb_io_write(rb_stderr, rb_str_new(mesg, len));
+ rb_io_write(rb_ractor_stderr(), rb_str_new(mesg, len));
}
}
@@ -7573,7 +8083,7 @@ void
rb_write_error_str(VALUE mesg)
{
/* a stopgap measure for the time being */
- if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0) {
+ if (rb_stderr_to_original_p()) {
size_t len = (size_t)RSTRING_LEN(mesg);
#ifdef _WIN32
if (isatty(fileno(stderr))) {
@@ -7587,14 +8097,14 @@ rb_write_error_str(VALUE mesg)
}
else {
/* may unlock GVL, and */
- rb_io_write(rb_stderr, mesg);
+ rb_io_write(rb_ractor_stderr(), mesg);
}
}
int
rb_stderr_tty_p(void)
{
- if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0)
+ if (rb_stderr_to_original_p())
return isatty(fileno(stderr));
return 0;
}
@@ -7610,10 +8120,41 @@ must_respond_to(ID mid, VALUE val, ID id)
}
static void
-stdout_setter(VALUE val, ID id, VALUE *variable)
+stdin_setter(VALUE val, ID id, VALUE *ptr)
+{
+ rb_ractor_stdin_set(val);
+}
+
+static VALUE
+stdin_getter(ID id, VALUE *ptr)
+{
+ return rb_ractor_stdin();
+}
+
+static void
+stdout_setter(VALUE val, ID id, VALUE *ptr)
+{
+ must_respond_to(id_write, val, id);
+ rb_ractor_stdout_set(val);
+}
+
+static VALUE
+stdout_getter(ID id, VALUE *ptr)
+{
+ return rb_ractor_stdout();
+}
+
+static void
+stderr_setter(VALUE val, ID id, VALUE *ptr)
{
must_respond_to(id_write, val, id);
- *variable = val;
+ rb_ractor_stderr_set(val);
+}
+
+static VALUE
+stderr_getter(ID id, VALUE *ptr)
+{
+ return rb_ractor_stderr();
}
static VALUE
@@ -7623,6 +8164,7 @@ prep_io(int fd, int fmode, VALUE klass, const char *path)
VALUE io = io_alloc(klass);
MakeOpenFile(io, fp);
+ fp->self = io;
fp->fd = fd;
fp->mode = fmode;
if (!io_check_tty(fp)) {
@@ -7665,11 +8207,29 @@ prep_stdio(FILE *f, int fmode, VALUE klass, const char *path)
return io;
}
+VALUE
+rb_io_prep_stdin(void)
+{
+ return prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>");
+}
+
+VALUE
+rb_io_prep_stdout(void)
+{
+ return prep_stdio(stdout, FMODE_WRITABLE|FMODE_SIGNAL_ON_EPIPE, rb_cIO, "<STDOUT>");
+}
+
+VALUE
+rb_io_prep_stderr(void)
+{
+ return prep_stdio(stderr, FMODE_WRITABLE|FMODE_SYNC, rb_cIO, "<STDERR>");
+}
+
FILE *
rb_io_stdio_file(rb_io_t *fptr)
{
if (!fptr->stdio_file) {
- int oflags = rb_io_fmode_oflags(fptr->mode);
+ int oflags = rb_io_fmode_oflags(fptr->mode) & ~O_EXCL;
fptr->stdio_file = rb_fdopen(fptr->fd, rb_io_oflags_modestr(oflags));
}
return fptr->stdio_file;
@@ -7688,6 +8248,7 @@ static inline rb_io_t *
rb_io_fptr_new(void)
{
rb_io_t *fp = ALLOC(rb_io_t);
+ fp->self = Qnil;
fp->fd = -1;
fp->stdio_file = NULL;
fp->mode = 0;
@@ -7720,11 +8281,12 @@ rb_io_make_open_file(VALUE obj)
Check_Type(obj, T_FILE);
if (RFILE(obj)->fptr) {
- rb_io_close(obj);
- rb_io_fptr_finalize(RFILE(obj)->fptr);
- RFILE(obj)->fptr = 0;
+ rb_io_close(obj);
+ rb_io_fptr_finalize(RFILE(obj)->fptr);
+ RFILE(obj)->fptr = 0;
}
fp = rb_io_fptr_new();
+ fp->self = obj;
RFILE(obj)->fptr = fp;
return fp;
}
@@ -7787,6 +8349,10 @@ rb_io_make_open_file(VALUE obj)
*
* "t" Text file mode
*
+ * The exclusive access mode ("x") can be used together with "w" to ensure
+ * the file is created. Errno::EEXIST is raised when it already exists.
+ * It may not be supported with all kinds of streams (e.g. pipes).
+ *
* When the open mode of original IO is read only, the mode cannot be
* changed to be writable. Similarly, the open mode cannot be changed from
* write only to readable.
@@ -7825,8 +8391,7 @@ rb_io_make_open_file(VALUE obj)
* If +mode+ parameter is given, this parameter will be bitwise-ORed.
*
* :\external_encoding ::
- * External encoding for the IO. "-" is a synonym for the default external
- * encoding.
+ * External encoding for the IO.
*
* :\internal_encoding ::
* Internal encoding for the IO. "-" is a synonym for the default internal
@@ -7876,7 +8441,7 @@ rb_io_make_open_file(VALUE obj)
* io.puts "Hello, World!"
*
* Both of above print "Hello, World!" in UTF-16LE to standard error output
- * with converting EOL generated by <code>puts</code> to CR.
+ * with converting EOL generated by #puts to CR.
*/
static VALUE
@@ -7905,7 +8470,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
oflags = fcntl(fd, F_GETFL);
if (oflags == -1) rb_sys_fail(0);
#else
- if (fstat(fd, &st) == -1) rb_sys_fail(0);
+ if (fstat(fd, &st) < 0) rb_sys_fail(0);
#endif
rb_update_max_fd(fd);
#if defined(HAVE_FCNTL) && defined(F_GETFL)
@@ -7922,6 +8487,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
fmode |= FMODE_PREP;
}
MakeOpenFile(io, fp);
+ fp->self = io;
fp->fd = fd;
fp->mode = fmode;
fp->encs = convconfig;
@@ -7940,6 +8506,44 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
/*
* call-seq:
+ * ios.set_encoding_by_bom -> encoding or nil
+ *
+ * Checks if +ios+ starts with a BOM, and then consumes it and sets
+ * the external encoding. Returns the result encoding if found, or
+ * nil. If +ios+ is not binmode or its encoding has been set
+ * already, an exception will be raised.
+ *
+ * File.write("bom.txt", "\u{FEFF}abc")
+ * ios = File.open("bom.txt", "rb")
+ * ios.set_encoding_by_bom #=> #<Encoding:UTF-8>
+ *
+ * File.write("nobom.txt", "abc")
+ * ios = File.open("nobom.txt", "rb")
+ * ios.set_encoding_by_bom #=> nil
+ */
+
+static VALUE
+rb_io_set_encoding_by_bom(VALUE io)
+{
+ rb_io_t *fptr;
+
+ GetOpenFile(io, fptr);
+ if (!(fptr->mode & FMODE_BINMODE)) {
+ rb_raise(rb_eArgError, "ASCII incompatible encoding needs binmode");
+ }
+ if (fptr->encs.enc2) {
+ rb_raise(rb_eArgError, "encoding conversion is set");
+ }
+ else if (fptr->encs.enc && fptr->encs.enc != rb_ascii8bit_encoding()) {
+ rb_raise(rb_eArgError, "encoding is set to %s already",
+ rb_enc_name(fptr->encs.enc));
+ }
+ if (!io_set_encoding_by_bom(io)) return Qnil;
+ return rb_enc_from_encoding(fptr->encs.enc);
+}
+
+/*
+ * call-seq:
* File.new(filename, mode="r" [, opt]) -> file
* File.new(filename [, mode [, perm]] [, opt]) -> file
*
@@ -7954,8 +8558,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
*
* The new File object is buffered mode (or non-sync mode), unless
* +filename+ is a tty.
- * See IO#flush, IO#fsync, IO#fdatasync, and <code>IO#sync=</code>
- * about sync mode.
+ * See IO#flush, IO#fsync, IO#fdatasync, and IO#sync= about sync mode.
*
* === Examples
*
@@ -7993,7 +8596,7 @@ rb_io_s_new(int argc, VALUE *argv, VALUE klass)
rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
cname, cname);
}
- return rb_class_new_instance(argc, argv, klass);
+ return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
}
@@ -8001,7 +8604,7 @@ rb_io_s_new(int argc, VALUE *argv, VALUE klass)
* call-seq:
* IO.for_fd(fd, mode [, opt]) -> io
*
- * Synonym for <code>IO.new</code>.
+ * Synonym for IO.new.
*
*/
@@ -8038,12 +8641,12 @@ rb_io_autoclose_p(VALUE io)
* f = open("/dev/null")
* IO.for_fd(f.fileno)
* # ...
- * f.gets # may cause IOError
+ * f.gets # may cause Errno::EBADF
*
* f = open("/dev/null")
- * IO.for_fd(f.fileno).autoclose = true
+ * IO.for_fd(f.fileno).autoclose = false
* # ...
- * f.gets # won't cause IOError
+ * f.gets # won't cause Errno::EBADF
*/
static VALUE
@@ -8055,7 +8658,7 @@ rb_io_set_autoclose(VALUE io, VALUE autoclose)
fptr->mode |= FMODE_PREP;
else
fptr->mode &= ~FMODE_PREP;
- return io;
+ return autoclose;
}
static void
@@ -8065,29 +8668,21 @@ argf_mark(void *ptr)
rb_gc_mark(p->filename);
rb_gc_mark(p->current_file);
rb_gc_mark(p->argv);
+ rb_gc_mark(p->inplace);
rb_gc_mark(p->encs.ecopts);
}
-static void
-argf_free(void *ptr)
-{
- struct argf *p = ptr;
- xfree(p->inplace);
- xfree(p);
-}
-
static size_t
argf_memsize(const void *ptr)
{
const struct argf *p = ptr;
size_t size = sizeof(*p);
- if (p->inplace) size += strlen(p->inplace) + 1;
return size;
}
static const rb_data_type_t argf_type = {
"ARGF",
- {argf_mark, argf_free, argf_memsize},
+ {argf_mark, RUBY_TYPED_DEFAULT_FREE, argf_memsize},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -8129,11 +8724,6 @@ argf_initialize_copy(VALUE argf, VALUE orig)
if (!OBJ_INIT_COPY(argf, orig)) return argf;
ARGF = argf_of(orig);
ARGF.argv = rb_obj_dup(ARGF.argv);
- if (ARGF.inplace) {
- const char *inplace = ARGF.inplace;
- ARGF.inplace = 0;
- ARGF.inplace = ruby_strdup(inplace);
- }
return argf;
}
@@ -8220,8 +8810,10 @@ argf_next_argv(VALUE argf)
int stdout_binmode = 0;
int fmode;
- if (RB_TYPE_P(rb_stdout, T_FILE)) {
- GetOpenFile(rb_stdout, fptr);
+ VALUE r_stdout = rb_ractor_stdout();
+
+ if (RB_TYPE_P(r_stdout, T_FILE)) {
+ GetOpenFile(r_stdout, fptr);
if (fptr->mode & FMODE_BINMODE)
stdout_binmode = 1;
}
@@ -8249,8 +8841,9 @@ argf_next_argv(VALUE argf)
retry:
if (RARRAY_LEN(ARGF.argv) > 0) {
VALUE filename = rb_ary_shift(ARGF.argv);
- StringValueCStr(filename);
- ARGF.filename = rb_str_encode_ospath(filename);
+ FilePathValue(filename);
+ ARGF.filename = filename;
+ filename = rb_str_encode_ospath(filename);
fn = StringValueCStr(filename);
if (RSTRING_LEN(filename) == 1 && fn[0] == '-') {
ARGF.current_file = rb_stdin;
@@ -8271,15 +8864,19 @@ argf_next_argv(VALUE argf)
VALUE str;
int fw;
- if (RB_TYPE_P(rb_stdout, T_FILE) && rb_stdout != orig_stdout) {
- rb_io_close(rb_stdout);
+ if (RB_TYPE_P(r_stdout, T_FILE) && r_stdout != orig_stdout) {
+ rb_io_close(r_stdout);
}
fstat(fr, &st);
str = filename;
- if (*ARGF.inplace) {
+ if (!NIL_P(ARGF.inplace)) {
+ VALUE suffix = ARGF.inplace;
str = rb_str_dup(str);
- rb_str_cat2(str, ARGF.inplace);
- /* TODO: encoding of ARGF.inplace */
+ if (NIL_P(rb_str_cat_conv_enc_opts(str, RSTRING_LEN(str),
+ RSTRING_PTR(suffix), RSTRING_LEN(suffix),
+ rb_enc_get(suffix), 0, Qnil))) {
+ rb_str_append(str, suffix);
+ }
#ifdef NO_SAFE_RENAME
(void)close(fr);
(void)unlink(RSTRING_PTR(str));
@@ -8337,7 +8934,7 @@ argf_next_argv(VALUE argf)
}
#endif
write_io = prep_io(fw, FMODE_WRITABLE, rb_cFile, fn);
- rb_stdout = write_io;
+ rb_ractor_stdout_set(write_io);
if (stdout_binmode) rb_io_binmode(rb_stdout);
}
fmode = FMODE_READABLE;
@@ -8348,6 +8945,7 @@ argf_next_argv(VALUE argf)
if (!NIL_P(write_io)) {
rb_io_set_write_io(ARGF.current_file, write_io);
}
+ RB_GC_GUARD(filename);
}
if (ARGF.binmode) rb_io_ascii8bit_binmode(ARGF.current_file);
GetOpenFile(ARGF.current_file, fptr);
@@ -8376,7 +8974,7 @@ argf_next_argv(VALUE argf)
ARGF.filename = rb_str_new2("-");
if (ARGF.inplace) {
rb_warn("Can't do inplace edit for stdio");
- rb_stdout = orig_stdout;
+ rb_ractor_stdout_set(orig_stdout);
}
}
if (ARGF.init_p == -1) ARGF.init_p = 1;
@@ -8433,9 +9031,9 @@ static VALUE argf_gets(int, VALUE *, VALUE);
/*
* call-seq:
- * gets(sep=$/) -> string or nil
- * gets(limit) -> string or nil
- * gets(sep, limit) -> string or nil
+ * gets(sep=$/ [, getline_args]) -> string or nil
+ * gets(limit [, getline_args]) -> string or nil
+ * gets(sep, limit [, getline_args]) -> string or nil
*
* Returns (and assigns to <code>$_</code>) the next line from the list
* of files in +ARGV+ (or <code>$*</code>), or from standard input if
@@ -8475,9 +9073,9 @@ rb_f_gets(int argc, VALUE *argv, VALUE recv)
/*
* call-seq:
- * ARGF.gets(sep=$/) -> string or nil
- * ARGF.gets(limit) -> string or nil
- * ARGF.gets(sep, limit) -> string or nil
+ * ARGF.gets(sep=$/ [, getline_args]) -> string or nil
+ * ARGF.gets(limit [, getline_args]) -> string or nil
+ * ARGF.gets(sep, limit [, getline_args]) -> string or nil
*
* Returns the next line from the current file in +ARGF+.
*
@@ -8488,6 +9086,8 @@ rb_f_gets(int argc, VALUE *argv, VALUE recv)
* The optional _limit_ argument specifies how many characters of each line
* to return. By default all characters are returned.
*
+ * See IO.readlines for details about getline_args.
+ *
*/
static VALUE
argf_gets(int argc, VALUE *argv, VALUE argf)
@@ -8534,7 +9134,7 @@ static VALUE argf_readline(int, VALUE *, VALUE);
* readline(limit) -> string
* readline(sep, limit) -> string
*
- * Equivalent to <code>Kernel::gets</code>, except
+ * Equivalent to Kernel::gets, except
* +readline+ raises +EOFError+ at end of file.
*/
@@ -8670,6 +9270,7 @@ rb_f_backquote(VALUE obj, VALUE str)
GetOpenFile(port, fptr);
result = read_all(fptr, remain_size(fptr), Qnil);
rb_io_close(port);
+ RFILE(port)->fptr = NULL;
rb_io_fptr_finalize(fptr);
rb_gc_force_recycle(port); /* also guards from premature GC */
@@ -8966,17 +9567,17 @@ advice_arg_check(VALUE advice)
*
* If an error occurs, one of the following exceptions will be raised:
*
- * <code>IOError</code>:: The <code>IO</code> stream is closed.
- * <code>Errno::EBADF</code>::
+ * IOError:: The IO stream is closed.
+ * Errno::EBADF::
* The file descriptor of the current file is invalid.
- * <code>Errno::EINVAL</code>:: An invalid value for _advice_ was given.
- * <code>Errno::ESPIPE</code>::
+ * Errno::EINVAL:: An invalid value for _advice_ was given.
+ * Errno::ESPIPE::
* The file descriptor of the current file refers to a FIFO or
- * pipe. (Linux raises <code>Errno::EINVAL</code> in this case).
- * <code>TypeError</code>::
+ * pipe. (Linux raises Errno::EINVAL in this case).
+ * TypeError::
* Either _advice_ was not a Symbol, or one of the
- * other arguments was not an <code>Integer</code>.
- * <code>RangeError</code>:: One of the arguments given was too big/small.
+ * other arguments was not an Integer.
+ * RangeError:: One of the arguments given was too big/small.
*
* This list is not exhaustive; other Errno:: exceptions are also possible.
*/
@@ -9009,29 +9610,28 @@ rb_io_advise(int argc, VALUE *argv, VALUE io)
* IO.select(read_array [, write_array [, error_array [, timeout]]]) -> array or nil
*
* Calls select(2) system call.
- * It monitors given arrays of <code>IO</code> objects, waits until one or more
- * of <code>IO</code> objects are ready for reading, are ready for writing,
- * and have pending exceptions respectively, and returns an array that
- * contains arrays of those IO objects. It will return +nil+
- * if optional <i>timeout</i> value is given and no <code>IO</code> object
- * is ready in <i>timeout</i> seconds.
- *
- * <code>IO.select</code> peeks the buffer of <code>IO</code> objects for testing readability.
- * If the <code>IO</code> buffer is not empty,
- * <code>IO.select</code> immediately notifies readability.
- * This "peek" only happens for <code>IO</code> objects.
- * It does not happen for IO-like objects such as OpenSSL::SSL::SSLSocket.
- *
- * The best way to use <code>IO.select</code> is invoking it
- * after nonblocking methods such as <code>read_nonblock</code>, <code>write_nonblock</code>, etc.
- * The methods raise an exception which is extended by
- * <code>IO::WaitReadable</code> or <code>IO::WaitWritable</code>.
- * The modules notify how the caller should wait with <code>IO.select</code>.
- * If <code>IO::WaitReadable</code> is raised, the caller should wait for reading.
- * If <code>IO::WaitWritable</code> is raised, the caller should wait for writing.
- *
- * So, blocking read (<code>readpartial</code>) can be emulated using
- * <code>read_nonblock</code> and <code>IO.select</code> as follows:
+ * It monitors given arrays of IO objects, waits until one or more of
+ * IO objects are ready for reading, are ready for writing, and have
+ * pending exceptions respectively, and returns an array that contains
+ * arrays of those IO objects. It will return +nil+ if optional
+ * <i>timeout</i> value is given and no IO object is ready in
+ * <i>timeout</i> seconds.
+ *
+ * IO.select peeks the buffer of IO objects for testing readability.
+ * If the IO buffer is not empty, IO.select immediately notifies
+ * readability. This "peek" only happens for IO objects. It does not
+ * happen for IO-like objects such as OpenSSL::SSL::SSLSocket.
+ *
+ * The best way to use IO.select is invoking it after nonblocking
+ * methods such as #read_nonblock, #write_nonblock, etc. The methods
+ * raise an exception which is extended by IO::WaitReadable or
+ * IO::WaitWritable. The modules notify how the caller should wait
+ * with IO.select. If IO::WaitReadable is raised, the caller should
+ * wait for reading. If IO::WaitWritable is raised, the caller should
+ * wait for writing.
+ *
+ * So, blocking read (#readpartial) can be emulated using
+ * #read_nonblock and IO.select as follows:
*
* begin
* result = io_like.read_nonblock(maxlen)
@@ -9043,57 +9643,57 @@ rb_io_advise(int argc, VALUE *argv, VALUE io)
* retry
* end
*
- * Especially, the combination of nonblocking methods and
- * <code>IO.select</code> is preferred for <code>IO</code> like
- * objects such as <code>OpenSSL::SSL::SSLSocket</code>.
- * It has <code>to_io</code> method to return underlying <code>IO</code> object.
- * <code>IO.select</code> calls <code>to_io</code> to obtain the file descriptor to wait.
+ * Especially, the combination of nonblocking methods and IO.select is
+ * preferred for IO like objects such as OpenSSL::SSL::SSLSocket. It
+ * has #to_io method to return underlying IO object. IO.select calls
+ * #to_io to obtain the file descriptor to wait.
*
- * This means that readability notified by <code>IO.select</code> doesn't mean
- * readability from <code>OpenSSL::SSL::SSLSocket</code> object.
+ * This means that readability notified by IO.select doesn't mean
+ * readability from OpenSSL::SSL::SSLSocket object.
*
- * The most likely situation is that <code>OpenSSL::SSL::SSLSocket</code> buffers some data.
- * <code>IO.select</code> doesn't see the buffer.
- * So <code>IO.select</code> can block when <code>OpenSSL::SSL::SSLSocket#readpartial</code> doesn't block.
+ * The most likely situation is that OpenSSL::SSL::SSLSocket buffers
+ * some data. IO.select doesn't see the buffer. So IO.select can
+ * block when OpenSSL::SSL::SSLSocket#readpartial doesn't block.
*
* However, several more complicated situations exist.
*
* SSL is a protocol which is sequence of records.
* The record consists of multiple bytes.
- * So, the remote side of SSL sends a partial record,
- * <code>IO.select</code> notifies readability but
- * <code>OpenSSL::SSL::SSLSocket</code> cannot decrypt a byte and
- * <code>OpenSSL::SSL::SSLSocket#readpartial</code> will blocks.
+ * So, the remote side of SSL sends a partial record, IO.select
+ * notifies readability but OpenSSL::SSL::SSLSocket cannot decrypt a
+ * byte and OpenSSL::SSL::SSLSocket#readpartial will block.
*
* Also, the remote side can request SSL renegotiation which forces
* the local SSL engine to write some data.
- * This means <code>OpenSSL::SSL::SSLSocket#readpartial</code> may
- * invoke <code>write</code> system call and it can block.
- * In such a situation, <code>OpenSSL::SSL::SSLSocket#read_nonblock</code>
- * raises IO::WaitWritable instead of blocking.
- * So, the caller should wait for ready for writability as above example.
+ * This means OpenSSL::SSL::SSLSocket#readpartial may invoke #write
+ * system call and it can block.
+ * In such a situation, OpenSSL::SSL::SSLSocket#read_nonblock raises
+ * IO::WaitWritable instead of blocking.
+ * So, the caller should wait for ready for writability as above
+ * example.
*
- * The combination of nonblocking methods and <code>IO.select</code> is
- * also useful for streams such as tty, pipe socket socket when
- * multiple processes read from a stream.
+ * The combination of nonblocking methods and IO.select is also useful
+ * for streams such as tty, pipe socket socket when multiple processes
+ * read from a stream.
*
* Finally, Linux kernel developers don't guarantee that
* readability of select(2) means readability of following read(2) even
* for a single process.
* See select(2) manual on GNU/Linux system.
*
- * Invoking <code>IO.select</code> before <code>IO#readpartial</code> works well as usual.
- * However it is not the best way to use <code>IO.select</code>.
+ * Invoking IO.select before IO#readpartial works well as usual.
+ * However it is not the best way to use IO.select.
*
* The writability notified by select(2) doesn't show
- * how many bytes writable.
- * <code>IO#write</code> method blocks until given whole string is written.
- * So, <code>IO#write(two or more bytes)</code> can block after writability is notified by <code>IO.select</code>.
- * <code>IO#write_nonblock</code> is required to avoid the blocking.
+ * how many bytes are writable.
+ * IO#write method blocks until given whole string is written.
+ * So, <code>IO#write(two or more bytes)</code> can block after
+ * writability is notified by IO.select. IO#write_nonblock is required
+ * to avoid the blocking.
*
- * Blocking write (<code>write</code>) can be emulated using
- * <code>write_nonblock</code> and <code>IO.select</code> as follows:
- * IO::WaitReadable should also be rescued for SSL renegotiation in <code>OpenSSL::SSL::SSLSocket</code>.
+ * Blocking write (#write) can be emulated using #write_nonblock and
+ * IO.select as follows: IO::WaitReadable should also be rescued for
+ * SSL renegotiation in OpenSSL::SSL::SSLSocket.
*
* while 0 < string.bytesize
* begin
@@ -9109,9 +9709,9 @@ rb_io_advise(int argc, VALUE *argv, VALUE io)
* end
*
* === Parameters
- * read_array:: an array of <code>IO</code> objects that wait until ready for read
- * write_array:: an array of <code>IO</code> objects that wait until ready for write
- * error_array:: an array of <code>IO</code> objects that wait for exceptions
+ * read_array:: an array of IO objects that wait until ready for read
+ * write_array:: an array of IO objects that wait until ready for write
+ * error_array:: an array of IO objects that wait for exceptions
* timeout:: a numeric value in second
*
* === Example
@@ -9168,12 +9768,12 @@ rb_f_select(int argc, VALUE *argv, VALUE obj)
return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
}
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
typedef unsigned long ioctl_req_t;
# define NUM2IOCTLREQ(num) NUM2ULONG(num)
#else
typedef int ioctl_req_t;
-# define NUM2IOCTLREQ(num) NUM2INT(num)
+# define NUM2IOCTLREQ(num) ((int)NUM2LONG(num))
#endif
#ifdef HAVE_IOCTL
@@ -9260,14 +9860,6 @@ typedef long fcntl_arg_t;
typedef int fcntl_arg_t;
#endif
-#if defined __native_client__ && !defined __GLIBC__
-// struct flock is currently missing the NaCl newlib headers
-// TODO(sbc): remove this once it gets added.
-#undef F_GETLK
-#undef F_SETLK
-#undef F_SETLKW
-#endif
-
static long
fcntl_narg_len(int cmd)
{
@@ -9570,9 +10162,9 @@ rb_fcntl(VALUE io, VALUE req, VALUE arg)
* query file-oriented I/O streams. Arguments and results are platform
* dependent. If <i>arg</i> is a number, its value is passed
* directly. If it is a string, it is interpreted as a binary sequence
- * of bytes (<code>Array#pack</code> might be a useful way to build this
- * string). On Unix platforms, see <code>fcntl(2)</code> for details.
- * Not implemented on all platforms.
+ * of bytes (Array#pack might be a useful way to build this string). On
+ * Unix platforms, see <code>fcntl(2)</code> for details. Not
+ * implemented on all platforms.
*/
static VALUE
@@ -9623,7 +10215,7 @@ rb_io_fcntl(int argc, VALUE *argv, VALUE io)
*/
static VALUE
-rb_f_syscall(int argc, VALUE *argv)
+rb_f_syscall(int argc, VALUE *argv, VALUE _)
{
VALUE arg[8];
#if SIZEOF_VOIDP == 8 && defined(HAVE___SYSCALL) && SIZEOF_INT != 8 /* mainly *BSD */
@@ -9658,7 +10250,8 @@ rb_f_syscall(int argc, VALUE *argv)
int i;
if (RTEST(ruby_verbose)) {
- rb_warning("We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
+ rb_category_warning(RB_WARN_CATEGORY_DEPRECATED,
+ "We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
}
if (argc == 0)
@@ -9826,7 +10419,7 @@ pipe_pair_close(VALUE rw)
* IO.pipe(...) {|read_io, write_io| ... }
*
* Creates a pair of pipe endpoints (connected to each other) and
- * returns them as a two-element array of <code>IO</code> objects:
+ * returns them as a two-element array of IO objects:
* <code>[</code> <i>read_io</i>, <i>write_io</i> <code>]</code>.
*
* If a block is given, the block is called and
@@ -9888,7 +10481,7 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
VALUE ret;
argc = rb_scan_args(argc, argv, "02:", &v1, &v2, &opt);
- if (rb_pipe(pipes) == -1)
+ if (rb_pipe(pipes) < 0)
rb_sys_fail(0);
args[0] = klass;
@@ -9925,6 +10518,12 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
rb_io_synchronized(fptr2);
extract_binmode(opt, &fmode);
+
+ if ((fmode & FMODE_BINMODE) && v1 == Qnil) {
+ rb_io_ascii8bit_binmode(r);
+ rb_io_ascii8bit_binmode(w);
+ }
+
#if DEFAULT_TEXTMODE
if ((fptr->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
fptr->mode &= ~FMODE_TEXTMODE;
@@ -9962,9 +10561,10 @@ struct foreach_arg {
};
static void
-open_key_args(int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg)
+open_key_args(VALUE klass, int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg)
{
VALUE path, v;
+ VALUE vmode = Qnil, vperm = Qnil;
path = *argv++;
argc--;
@@ -9973,34 +10573,24 @@ open_key_args(int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg)
arg->argc = argc;
arg->argv = argv;
if (NIL_P(opt)) {
- arg->io = rb_io_open(path, INT2NUM(O_RDONLY), INT2FIX(0666), Qnil);
- return;
+ vmode = INT2NUM(O_RDONLY);
+ vperm = INT2FIX(0666);
}
- v = rb_hash_aref(opt, sym_open_args);
- if (!NIL_P(v)) {
- VALUE args;
- long n;
+ else if (!NIL_P(v = rb_hash_aref(opt, sym_open_args))) {
+ int n;
- v = rb_convert_type_with_id(v, T_ARRAY, "Array", idTo_ary);
- n = RARRAY_LEN(v) + 1;
-#if SIZEOF_LONG > SIZEOF_INT
- if (n > INT_MAX) {
- rb_raise(rb_eArgError, "too many arguments");
- }
-#endif
- args = rb_ary_tmp_new(n);
- rb_ary_push(args, path);
- rb_ary_concat(args, v);
- arg->io = rb_io_open_with_args((int)n, RARRAY_CONST_PTR(args));
- rb_ary_clear(args); /* prevent from GC */
- return;
+ v = rb_to_array_type(v);
+ n = RARRAY_LENINT(v);
+ rb_check_arity(n, 0, 3); /* rb_io_open */
+ rb_scan_args_kw(RB_SCAN_ARGS_LAST_HASH_KEYWORDS, n, RARRAY_CONST_PTR(v), "02:", &vmode, &vperm, &opt);
}
- arg->io = rb_io_open(path, Qnil, Qnil, opt);
+ arg->io = rb_io_open(klass, path, vmode, vperm, opt);
}
static VALUE
-io_s_foreach(struct getline_arg *arg)
+io_s_foreach(VALUE v)
{
+ struct getline_arg *arg = (void *)v;
VALUE str;
while (!NIL_P(str = rb_io_getline_1(arg->rs, arg->limit, arg->chomp, arg->io))) {
@@ -10013,9 +10603,9 @@ io_s_foreach(struct getline_arg *arg)
/*
* call-seq:
- * IO.foreach(name, sep=$/ [, open_args]) {|line| block } -> nil
- * IO.foreach(name, limit [, open_args]) {|line| block } -> nil
- * IO.foreach(name, sep, limit [, open_args]) {|line| block } -> nil
+ * IO.foreach(name, sep=$/ [, getline_args, open_args]) {|line| block } -> nil
+ * IO.foreach(name, limit [, getline_args, open_args]) {|line| block } -> nil
+ * IO.foreach(name, sep, limit [, getline_args, open_args]) {|line| block } -> nil
* IO.foreach(...) -> an_enumerator
*
* Executes the block for every line in the named I/O port, where lines
@@ -10033,7 +10623,8 @@ io_s_foreach(struct getline_arg *arg)
* GOT And so on...
*
* If the last argument is a hash, it's the keyword argument to open.
- * See <code>IO.read</code> for detail.
+ * See IO.readlines for details about getline_args.
+ * And see also IO.read for details about open_args.
*
*/
@@ -10048,7 +10639,7 @@ rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
RETURN_ENUMERATOR(self, orig_argc, argv);
extract_getline_args(argc-1, argv+1, &garg);
- open_key_args(argc, argv, opt, &arg);
+ open_key_args(self, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
extract_getline_opts(opt, &garg);
check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io);
@@ -10056,16 +10647,17 @@ rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
}
static VALUE
-io_s_readlines(struct getline_arg *arg)
+io_s_readlines(VALUE v)
{
+ struct getline_arg *arg = (void *)v;
return io_readlines(arg, arg->io);
}
/*
* call-seq:
- * IO.readlines(name, sep=$/ [, open_args]) -> array
- * IO.readlines(name, limit [, open_args]) -> array
- * IO.readlines(name, sep, limit [, open_args]) -> array
+ * IO.readlines(name, sep=$/ [, getline_args, open_args]) -> array
+ * IO.readlines(name, limit [, getline_args, open_args]) -> array
+ * IO.readlines(name, sep, limit [, getline_args, open_args]) -> array
*
* Reads the entire file specified by <i>name</i> as individual
* lines, and returns those lines in an array. Lines are separated by
@@ -10074,9 +10666,21 @@ io_s_readlines(struct getline_arg *arg)
* a = IO.readlines("testfile")
* a[0] #=> "This is line one\n"
*
+ * b = IO.readlines("testfile", chomp: true)
+ * b[0] #=> "This is line one"
+ *
* If the last argument is a hash, it's the keyword argument to open.
- * See <code>IO.read</code> for detail.
*
+ * === Options for getline
+ *
+ * The options hash accepts the following keys:
+ *
+ * :chomp::
+ * When the optional +chomp+ keyword argument has a true value,
+ * <code>\n</code>, <code>\r</code>, and <code>\r\n</code>
+ * will be removed from the end of each line.
+ *
+ * See also IO.read for details about open_args.
*/
static VALUE
@@ -10088,7 +10692,7 @@ rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
extract_getline_args(argc-1, argv+1, &garg);
- open_key_args(argc, argv, opt, &arg);
+ open_key_args(io, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
extract_getline_opts(opt, &garg);
check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io);
@@ -10096,8 +10700,9 @@ rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
}
static VALUE
-io_s_read(struct foreach_arg *arg)
+io_s_read(VALUE v)
{
+ struct foreach_arg *arg = (void *)v;
return io_read(arg->argc, arg->argv, arg->io);
}
@@ -10120,8 +10725,8 @@ seek_before_access(VALUE argp)
* IO.read(name, [length [, offset]] [, opt] ) -> string
*
* Opens the file, optionally seeks to the given +offset+, then returns
- * +length+ bytes (defaulting to the rest of the file). <code>read</code>
- * ensures the file is closed before returning.
+ * +length+ bytes (defaulting to the rest of the file). #read ensures
+ * the file is closed before returning.
*
* If +name+ starts with a pipe character (<code>"|"</code>), a subprocess is
* created in the same way as Kernel#open, and its output is returned.
@@ -10164,7 +10769,7 @@ rb_io_s_read(int argc, VALUE *argv, VALUE io)
struct foreach_arg arg;
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
- open_key_args(argc, argv, opt, &arg);
+ open_key_args(io, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
struct seek_arg sarg;
@@ -10186,10 +10791,10 @@ rb_io_s_read(int argc, VALUE *argv, VALUE io)
* call-seq:
* IO.binread(name, [length [, offset]] ) -> string
*
- * Opens the file, optionally seeks to the given <i>offset</i>, then returns
- * <i>length</i> bytes (defaulting to the rest of the file).
- * <code>binread</code> ensures the file is closed before returning.
- * The open mode would be "rb:ASCII-8BIT".
+ * Opens the file, optionally seeks to the given <i>offset</i>, then
+ * returns <i>length</i> bytes (defaulting to the rest of the file).
+ * #binread ensures the file is closed before returning. The open mode
+ * would be <code>"rb:ASCII-8BIT"</code>.
*
* IO.binread("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
* IO.binread("testfile", 20) #=> "This is line one\nThi"
@@ -10213,7 +10818,7 @@ rb_io_s_binread(int argc, VALUE *argv, VALUE io)
rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
FilePathValue(argv[0]);
convconfig.enc = rb_ascii8bit_encoding();
- arg.io = rb_io_open_generic(argv[0], oflags, fmode, &convconfig, 0);
+ arg.io = rb_io_open_generic(io, argv[0], oflags, fmode, &convconfig, 0);
if (NIL_P(arg.io)) return Qnil;
arg.argv = argv+1;
arg.argc = (argc > 1) ? 1 : 0;
@@ -10233,13 +10838,14 @@ rb_io_s_binread(int argc, VALUE *argv, VALUE io)
}
static VALUE
-io_s_write0(struct write_arg *arg)
+io_s_write0(VALUE v)
{
+ struct write_arg *arg = (void * )v;
return io_write(arg->io,arg->str,arg->nosync);
}
static VALUE
-io_s_write(int argc, VALUE *argv, int binary)
+io_s_write(int argc, VALUE *argv, VALUE klass, int binary)
{
VALUE string, offset, opt;
struct foreach_arg arg;
@@ -10259,7 +10865,7 @@ io_s_write(int argc, VALUE *argv, int binary)
if (NIL_P(offset)) mode |= O_TRUNC;
rb_hash_aset(opt,sym_mode,INT2NUM(mode));
}
- open_key_args(argc,argv,opt,&arg);
+ open_key_args(klass, argc, argv, opt, &arg);
#ifndef O_BINARY
if (binary) rb_io_binmode_m(arg.io);
@@ -10292,10 +10898,9 @@ io_s_write(int argc, VALUE *argv, int binary)
* IO.write(name, string [, offset] [, opt]) -> integer
*
* Opens the file, optionally seeks to the given <i>offset</i>, writes
- * <i>string</i>, then returns the length written.
- * <code>write</code> ensures the file is closed before returning.
- * If <i>offset</i> is not given, the file is truncated. Otherwise,
- * it is not truncated.
+ * <i>string</i>, then returns the length written. #write ensures the
+ * file is closed before returning. If <i>offset</i> is not given in
+ * write mode, the file is truncated. Otherwise, it is not truncated.
*
* IO.write("testfile", "0123456789", 20) #=> 10
* # File could contain: "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n"
@@ -10333,7 +10938,7 @@ io_s_write(int argc, VALUE *argv, int binary)
static VALUE
rb_io_s_write(int argc, VALUE *argv, VALUE io)
{
- return io_s_write(argc, argv, 0);
+ return io_s_write(argc, argv, io, 0);
}
/*
@@ -10341,14 +10946,14 @@ rb_io_s_write(int argc, VALUE *argv, VALUE io)
* IO.binwrite(name, string, [offset] ) -> integer
* IO.binwrite(name, string, [offset], open_args ) -> integer
*
- * Same as <code>IO.write</code> except opening the file in binary mode
- * and ASCII-8BIT encoding ("wb:ASCII-8BIT").
+ * Same as IO.write except opening the file in binary mode and
+ * ASCII-8BIT encoding (<code>"wb:ASCII-8BIT"</code>).
*/
static VALUE
rb_io_s_binwrite(int argc, VALUE *argv, VALUE io)
{
- return io_s_write(argc, argv, 1);
+ return io_s_write(argc, argv, io, 1);
}
struct copy_stream_struct {
@@ -10359,14 +10964,18 @@ struct copy_stream_struct {
int src_fd;
int dst_fd;
- int close_src;
- int close_dst;
+ unsigned close_src : 1;
+ unsigned close_dst : 1;
+ int error_no;
off_t total;
const char *syserr;
- int error_no;
const char *notimp;
- rb_fdset_t fds;
VALUE th;
+ struct stat src_stat;
+ struct stat dst_stat;
+#ifdef HAVE_FCOPYFILE
+ copyfile_state_t copyfile_state;
+#endif
};
static void *
@@ -10401,19 +11010,39 @@ maygvl_copy_stream_continue_p(int has_gvl, struct copy_stream_struct *stp)
return FALSE;
}
-/* non-Linux poll may not work on all FDs */
-#if defined(HAVE_POLL) && defined(__linux__)
-# define USE_POLL 1
-# define IOWAIT_SYSCALL "poll"
-#else
-# define IOWAIT_SYSCALL "select"
-# define USE_POLL 0
-#endif
+struct wait_for_single_fd {
+ VALUE scheduler;
+
+ int fd;
+ short events;
+
+ VALUE result;
+};
+
+static void *
+rb_thread_scheduler_wait_for_single_fd(void * _args)
+{
+ struct wait_for_single_fd *args = (struct wait_for_single_fd *)_args;
+
+ args->result = rb_scheduler_io_wait(args->scheduler, rb_io_from_fd(args->fd), INT2NUM(args->events), Qnil);
+
+ return NULL;
+}
#if USE_POLL
+# define IOWAIT_SYSCALL "poll"
+STATIC_ASSERT(pollin_expected, POLLIN == RB_WAITFD_IN);
+STATIC_ASSERT(pollout_expected, POLLOUT == RB_WAITFD_OUT);
static int
-nogvl_wait_for_single_fd(int fd, short events)
+nogvl_wait_for_single_fd(VALUE th, int fd, short events)
{
+ VALUE scheduler = rb_thread_scheduler_current(th);
+ if (scheduler != Qnil) {
+ struct wait_for_single_fd args = {.scheduler = scheduler, .fd = fd, .events = events};
+ rb_thread_call_with_gvl(rb_thread_scheduler_wait_for_single_fd, &args);
+ return RTEST(args.result);
+ }
+
struct pollfd fds;
fds.fd = fd;
@@ -10421,6 +11050,39 @@ nogvl_wait_for_single_fd(int fd, short events)
return poll(&fds, 1, -1);
}
+#else /* !USE_POLL */
+# define IOWAIT_SYSCALL "select"
+static int
+nogvl_wait_for_single_fd(VALUE th, int fd, short events)
+{
+ VALUE scheduler = rb_thread_scheduler_current(th);
+ if (scheduler != Qnil) {
+ struct wait_for_single_fd args = {.scheduler = scheduler, .fd = fd, .events = events};
+ rb_thread_call_with_gvl(rb_thread_scheduler_wait_for_single_fd, &args);
+ return RTEST(args.result);
+ }
+
+ rb_fdset_t fds;
+ int ret;
+
+ rb_fd_init(&fds);
+ rb_fd_set(fd, &fds);
+
+ switch (events) {
+ case RB_WAITFD_IN:
+ ret = rb_fd_select(fd + 1, &fds, 0, 0, 0);
+ break;
+ case RB_WAITFD_OUT:
+ ret = rb_fd_select(fd + 1, 0, &fds, 0, 0);
+ break;
+ default:
+ VM_UNREACHABLE(nogvl_wait_for_single_fd);
+ }
+
+ rb_fd_term(&fds);
+ return ret;
+}
+#endif /* !USE_POLL */
static int
maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
@@ -10432,69 +11094,220 @@ maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
ret = rb_wait_for_single_fd(stp->src_fd, RB_WAITFD_IN, NULL);
}
else {
- ret = nogvl_wait_for_single_fd(stp->src_fd, POLLIN);
+ ret = nogvl_wait_for_single_fd(stp->th, stp->src_fd, RB_WAITFD_IN);
}
- } while (ret == -1 && maygvl_copy_stream_continue_p(has_gvl, stp));
+ } while (ret < 0 && maygvl_copy_stream_continue_p(has_gvl, stp));
- if (ret == -1) {
- stp->syserr = "poll";
+ if (ret < 0) {
+ stp->syserr = IOWAIT_SYSCALL;
stp->error_no = errno;
- return -1;
+ return ret;
}
return 0;
}
-#else /* !USE_POLL */
-static int
-maygvl_select(int has_gvl, int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout)
-{
- if (has_gvl)
- return rb_thread_fd_select(n, rfds, wfds, efds, timeout);
- else
- return rb_fd_select(n, rfds, wfds, efds, timeout);
-}
static int
-maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
+nogvl_copy_stream_wait_write(struct copy_stream_struct *stp)
{
int ret;
do {
- rb_fd_zero(&stp->fds);
- rb_fd_set(stp->src_fd, &stp->fds);
- ret = maygvl_select(has_gvl, rb_fd_max(&stp->fds), &stp->fds, NULL, NULL, NULL);
- } while (ret == -1 && maygvl_copy_stream_continue_p(has_gvl, stp));
+ ret = nogvl_wait_for_single_fd(stp->th, stp->dst_fd, RB_WAITFD_OUT);
+ } while (ret < 0 && maygvl_copy_stream_continue_p(0, stp));
- if (ret == -1) {
- stp->syserr = "select";
+ if (ret < 0) {
+ stp->syserr = IOWAIT_SYSCALL;
stp->error_no = errno;
- return -1;
+ return ret;
}
return 0;
}
-#endif /* !USE_POLL */
+
+#ifdef USE_COPY_FILE_RANGE
+
+static ssize_t
+simple_copy_file_range(int in_fd, off_t *in_offset, int out_fd, off_t *out_offset, size_t count, unsigned int flags)
+{
+#ifdef HAVE_COPY_FILE_RANGE
+ return copy_file_range(in_fd, in_offset, out_fd, out_offset, count, flags);
+#else
+ return syscall(__NR_copy_file_range, in_fd, in_offset, out_fd, out_offset, count, flags);
+#endif
+}
static int
-nogvl_copy_stream_wait_write(struct copy_stream_struct *stp)
+nogvl_copy_file_range(struct copy_stream_struct *stp)
{
- int ret;
+ ssize_t ss;
+ off_t src_size;
+ off_t copy_length, src_offset, *src_offset_ptr;
- do {
-#if USE_POLL
- ret = nogvl_wait_for_single_fd(stp->dst_fd, POLLOUT);
-#else
- rb_fd_zero(&stp->fds);
- rb_fd_set(stp->dst_fd, &stp->fds);
- ret = rb_fd_select(rb_fd_max(&stp->fds), NULL, &stp->fds, NULL, NULL);
+ if (!S_ISREG(stp->src_stat.st_mode))
+ return 0;
+
+ src_size = stp->src_stat.st_size;
+ src_offset = stp->src_offset;
+ if (src_offset >= (off_t)0) {
+ src_offset_ptr = &src_offset;
+ }
+ else {
+ src_offset_ptr = NULL; /* if src_offset_ptr is NULL, then bytes are read from in_fd starting from the file offset */
+ }
+
+ copy_length = stp->copy_length;
+ if (copy_length < (off_t)0) {
+ if (src_offset < (off_t)0) {
+ off_t current_offset;
+ errno = 0;
+ current_offset = lseek(stp->src_fd, 0, SEEK_CUR);
+ if (current_offset < (off_t)0 && errno) {
+ stp->syserr = "lseek";
+ stp->error_no = errno;
+ return (int)current_offset;
+ }
+ copy_length = src_size - current_offset;
+ }
+ else {
+ copy_length = src_size - src_offset;
+ }
+ }
+
+ retry_copy_file_range:
+# if SIZEOF_OFF_T > SIZEOF_SIZE_T
+ /* we are limited by the 32-bit ssize_t return value on 32-bit */
+ ss = (copy_length > (off_t)SSIZE_MAX) ? SSIZE_MAX : (ssize_t)copy_length;
+# else
+ ss = (ssize_t)copy_length;
+# endif
+ ss = simple_copy_file_range(stp->src_fd, src_offset_ptr, stp->dst_fd, NULL, ss, 0);
+ if (0 < ss) {
+ stp->total += ss;
+ copy_length -= ss;
+ if (0 < copy_length) {
+ goto retry_copy_file_range;
+ }
+ }
+ if (ss < 0) {
+ if (maygvl_copy_stream_continue_p(0, stp)) {
+ goto retry_copy_file_range;
+ }
+ switch (errno) {
+ case EINVAL:
+ case EPERM: /* copy_file_range(2) doesn't exist (may happen in
+ docker container) */
+#ifdef ENOSYS
+ case ENOSYS:
+#endif
+#ifdef EXDEV
+ case EXDEV: /* in_fd and out_fd are not on the same filesystem */
#endif
- } while (ret == -1 && maygvl_copy_stream_continue_p(0, stp));
+ return 0;
+ case EAGAIN:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ {
+ int ret = nogvl_copy_stream_wait_write(stp);
+ if (ret < 0) return ret;
+ }
+ goto retry_copy_file_range;
+ case EBADF:
+ {
+ int e = errno;
+ int flags = fcntl(stp->dst_fd, F_GETFL);
- if (ret == -1) {
- stp->syserr = IOWAIT_SYSCALL;
+ if (flags != -1 && flags & O_APPEND) {
+ return 0;
+ }
+ errno = e;
+ }
+ }
+ stp->syserr = "copy_file_range";
stp->error_no = errno;
- return -1;
+ return (int)ss;
}
- return 0;
+ return 1;
}
+#endif
+
+#ifdef HAVE_FCOPYFILE
+static int
+nogvl_fcopyfile(struct copy_stream_struct *stp)
+{
+ off_t cur, ss = 0;
+ const off_t src_offset = stp->src_offset;
+ int ret;
+
+ if (stp->copy_length >= (off_t)0) {
+ /* copy_length can't be specified in fcopyfile(3) */
+ return 0;
+ }
+
+ if (!S_ISREG(stp->src_stat.st_mode))
+ return 0;
+
+ if (!S_ISREG(stp->dst_stat.st_mode))
+ return 0;
+ if (lseek(stp->dst_fd, 0, SEEK_CUR) > (off_t)0) /* if dst IO was already written */
+ return 0;
+ if (fcntl(stp->dst_fd, F_GETFL) & O_APPEND) {
+ /* fcopyfile(3) appends src IO to dst IO and then truncates
+ * dst IO to src IO's original size. */
+ off_t end = lseek(stp->dst_fd, 0, SEEK_END);
+ lseek(stp->dst_fd, 0, SEEK_SET);
+ if (end > (off_t)0) return 0;
+ }
+
+ if (src_offset > (off_t)0) {
+ off_t r;
+
+ /* get current offset */
+ errno = 0;
+ cur = lseek(stp->src_fd, 0, SEEK_CUR);
+ if (cur < (off_t)0 && errno) {
+ stp->error_no = errno;
+ return 1;
+ }
+
+ errno = 0;
+ r = lseek(stp->src_fd, src_offset, SEEK_SET);
+ if (r < (off_t)0 && errno) {
+ stp->error_no = errno;
+ return 1;
+ }
+ }
+
+ stp->copyfile_state = copyfile_state_alloc(); /* this will be freed by copy_stream_finalize() */
+ ret = fcopyfile(stp->src_fd, stp->dst_fd, stp->copyfile_state, COPYFILE_DATA);
+ copyfile_state_get(stp->copyfile_state, COPYFILE_STATE_COPIED, &ss); /* get copied bytes */
+
+ if (ret == 0) { /* success */
+ stp->total = ss;
+ if (src_offset > (off_t)0) {
+ off_t r;
+ errno = 0;
+ /* reset offset */
+ r = lseek(stp->src_fd, cur, SEEK_SET);
+ if (r < (off_t)0 && errno) {
+ stp->error_no = errno;
+ return 1;
+ }
+ }
+ }
+ else {
+ switch (errno) {
+ case ENOTSUP:
+ case EPERM:
+ case EINVAL:
+ return 0;
+ }
+ stp->syserr = "fcopyfile";
+ stp->error_no = errno;
+ return (int)ret;
+ }
+ return 1;
+}
+#endif
#ifdef HAVE_SENDFILE
@@ -10529,7 +11342,7 @@ simple_sendfile(int out_fd, int in_fd, off_t *offset, off_t count)
# else
r = sendfile(in_fd, out_fd, pos, (size_t)count, NULL, &sbytes, 0);
# endif
- if (r != 0 && sbytes == 0) return -1;
+ if (r != 0 && sbytes == 0) return r;
if (offset) {
*offset += sbytes;
}
@@ -10547,51 +11360,38 @@ simple_sendfile(int out_fd, int in_fd, off_t *offset, off_t count)
static int
nogvl_copy_stream_sendfile(struct copy_stream_struct *stp)
{
- struct stat src_stat, dst_stat;
ssize_t ss;
- int ret;
-
+ off_t src_size;
off_t copy_length;
off_t src_offset;
int use_pread;
- ret = fstat(stp->src_fd, &src_stat);
- if (ret == -1) {
- stp->syserr = "fstat";
- stp->error_no = errno;
- return -1;
- }
- if (!S_ISREG(src_stat.st_mode))
+ if (!S_ISREG(stp->src_stat.st_mode))
return 0;
- ret = fstat(stp->dst_fd, &dst_stat);
- if (ret == -1) {
- stp->syserr = "fstat";
- stp->error_no = errno;
- return -1;
- }
+ src_size = stp->src_stat.st_size;
#ifndef __linux__
- if ((dst_stat.st_mode & S_IFMT) != S_IFSOCK)
+ if ((stp->dst_stat.st_mode & S_IFMT) != S_IFSOCK)
return 0;
#endif
src_offset = stp->src_offset;
- use_pread = src_offset != (off_t)-1;
+ use_pread = src_offset >= (off_t)0;
copy_length = stp->copy_length;
- if (copy_length == (off_t)-1) {
+ if (copy_length < (off_t)0) {
if (use_pread)
- copy_length = src_stat.st_size - src_offset;
+ copy_length = src_size - src_offset;
else {
off_t cur;
errno = 0;
cur = lseek(stp->src_fd, 0, SEEK_CUR);
- if (cur == (off_t)-1 && errno) {
+ if (cur < (off_t)0 && errno) {
stp->syserr = "lseek";
stp->error_no = errno;
- return -1;
+ return (int)cur;
}
- copy_length = src_stat.st_size - cur;
+ copy_length = src_size - cur;
}
}
@@ -10615,7 +11415,7 @@ nogvl_copy_stream_sendfile(struct copy_stream_struct *stp)
goto retry_sendfile;
}
}
- if (ss == -1) {
+ if (ss < 0) {
if (maygvl_copy_stream_continue_p(0, stp))
goto retry_sendfile;
switch (errno) {
@@ -10623,29 +11423,37 @@ nogvl_copy_stream_sendfile(struct copy_stream_struct *stp)
#ifdef ENOSYS
case ENOSYS:
#endif
+#ifdef EOPNOTSUP
+ /* some RedHat kernels may return EOPNOTSUP on an NFS mount.
+ see also: [Feature #16965] */
+ case EOPNOTSUP:
+#endif
return 0;
case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
+ {
+ int ret;
#ifndef __linux__
- /*
- * Linux requires stp->src_fd to be a mmap-able (regular) file,
- * select() reports regular files to always be "ready", so
- * there is no need to select() on it.
- * Other OSes may have the same limitation for sendfile() which
- * allow us to bypass maygvl_copy_stream_wait_read()...
- */
- if (maygvl_copy_stream_wait_read(0, stp) == -1)
- return -1;
-#endif
- if (nogvl_copy_stream_wait_write(stp) == -1)
- return -1;
+ /*
+ * Linux requires stp->src_fd to be a mmap-able (regular) file,
+ * select() reports regular files to always be "ready", so
+ * there is no need to select() on it.
+ * Other OSes may have the same limitation for sendfile() which
+ * allow us to bypass maygvl_copy_stream_wait_read()...
+ */
+ ret = maygvl_copy_stream_wait_read(0, stp);
+ if (ret < 0) return ret;
+#endif
+ ret = nogvl_copy_stream_wait_write(stp);
+ if (ret < 0) return ret;
+ }
goto retry_sendfile;
}
stp->syserr = "sendfile";
stp->error_no = errno;
- return -1;
+ return (int)ss;
}
return 1;
}
@@ -10665,7 +11473,7 @@ maygvl_copy_stream_read(int has_gvl, struct copy_stream_struct *stp, char *buf,
{
ssize_t ss;
retry_read:
- if (offset == (off_t)-1) {
+ if (offset < (off_t)0) {
ss = maygvl_read(has_gvl, stp->src_fd, buf, len);
}
else {
@@ -10679,7 +11487,7 @@ maygvl_copy_stream_read(int has_gvl, struct copy_stream_struct *stp, char *buf,
if (ss == 0) {
return 0;
}
- if (ss == -1) {
+ if (ss < 0) {
if (maygvl_copy_stream_continue_p(has_gvl, stp))
goto retry_read;
switch (errno) {
@@ -10687,18 +11495,19 @@ maygvl_copy_stream_read(int has_gvl, struct copy_stream_struct *stp, char *buf,
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
- if (maygvl_copy_stream_wait_read(has_gvl, stp) == -1)
- return -1;
+ {
+ int ret = maygvl_copy_stream_wait_read(has_gvl, stp);
+ if (ret < 0) return ret;
+ }
goto retry_read;
#ifdef ENOSYS
case ENOSYS:
stp->notimp = "pread";
- return -1;
+ return ss;
#endif
}
- stp->syserr = offset == (off_t)-1 ? "read" : "pread";
+ stp->syserr = offset < (off_t)0 ? "read" : "pread";
stp->error_no = errno;
- return -1;
}
return ss;
}
@@ -10710,17 +11519,17 @@ nogvl_copy_stream_write(struct copy_stream_struct *stp, char *buf, size_t len)
int off = 0;
while (len) {
ss = write(stp->dst_fd, buf+off, len);
- if (ss == -1) {
- if (maygvl_copy_stream_continue_p(0, stp))
- continue;
+ if (ss < 0) {
+ if (maygvl_copy_stream_continue_p(0, stp))
+ continue;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
- if (nogvl_copy_stream_wait_write(stp) == -1)
- return -1;
+ int ret = nogvl_copy_stream_wait_write(stp);
+ if (ret < 0) return ret;
continue;
}
stp->syserr = "write";
stp->error_no = errno;
- return -1;
+ return (int)ss;
}
off += (int)ss;
len -= (int)ss;
@@ -10742,15 +11551,15 @@ nogvl_copy_stream_read_write(struct copy_stream_struct *stp)
int use_pread;
copy_length = stp->copy_length;
- use_eof = copy_length == (off_t)-1;
+ use_eof = copy_length < (off_t)0;
src_offset = stp->src_offset;
- use_pread = src_offset != (off_t)-1;
+ use_pread = src_offset >= (off_t)0;
if (use_pread && stp->close_src) {
off_t r;
errno = 0;
r = lseek(stp->src_fd, src_offset, SEEK_SET);
- if (r == (off_t)-1 && errno) {
+ if (r < (off_t)0 && errno) {
stp->syserr = "lseek";
stp->error_no = errno;
return;
@@ -10790,10 +11599,22 @@ static void *
nogvl_copy_stream_func(void *arg)
{
struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
-#ifdef USE_SENDFILE
+#if defined(USE_SENDFILE) || defined(USE_COPY_FILE_RANGE) || defined(HAVE_FCOPYFILE)
int ret;
#endif
+#ifdef USE_COPY_FILE_RANGE
+ ret = nogvl_copy_file_range(stp);
+ if (ret != 0)
+ goto finish; /* error or success */
+#endif
+
+#ifdef HAVE_FCOPYFILE
+ ret = nogvl_fcopyfile(stp);
+ if (ret != 0)
+ goto finish; /* error or success */
+#endif
+
#ifdef USE_SENDFILE
ret = nogvl_copy_stream_sendfile(stp);
if (ret != 0)
@@ -10802,7 +11623,7 @@ nogvl_copy_stream_func(void *arg)
nogvl_copy_stream_read_write(stp);
-#ifdef USE_SENDFILE
+#if defined(USE_SENDFILE) || defined(USE_COPY_FILE_RANGE) || defined(HAVE_FCOPYFILE)
finish:
#endif
return 0;
@@ -10819,7 +11640,7 @@ copy_stream_fallback_body(VALUE arg)
off_t off = stp->src_offset;
ID read_method = id_readpartial;
- if (stp->src_fd == -1) {
+ if (stp->src_fd < 0) {
if (!rb_respond_to(stp->src, read_method)) {
read_method = id_read;
}
@@ -10828,15 +11649,17 @@ copy_stream_fallback_body(VALUE arg)
while (1) {
long numwrote;
long l;
- if (stp->copy_length == (off_t)-1) {
+ if (stp->copy_length < (off_t)0) {
l = buflen;
}
else {
- if (rest == 0)
- break;
+ if (rest == 0) {
+ rb_str_resize(buf, 0);
+ break;
+ }
l = buflen < rest ? buflen : (long)rest;
}
- if (stp->src_fd == -1) {
+ if (stp->src_fd < 0) {
VALUE rc = rb_funcall(stp->src, read_method, 2, INT2FIX(l), buf);
if (read_method == id_read && NIL_P(rc))
@@ -10847,11 +11670,11 @@ copy_stream_fallback_body(VALUE arg)
rb_str_resize(buf, buflen);
ss = maygvl_copy_stream_read(1, stp, RSTRING_PTR(buf), l, off);
rb_str_resize(buf, ss > 0 ? ss : 0);
- if (ss == -1)
+ if (ss < 0)
return Qnil;
if (ss == 0)
rb_eof_error();
- if (off != (off_t)-1)
+ if (off >= (off_t)0)
off += ss;
}
n = rb_io_write(stp->dst, buf);
@@ -10869,11 +11692,11 @@ copy_stream_fallback_body(VALUE arg)
static VALUE
copy_stream_fallback(struct copy_stream_struct *stp)
{
- if (stp->src_fd == -1 && stp->src_offset != (off_t)-1) {
+ if (stp->src_fd < 0 && stp->src_offset >= (off_t)0) {
rb_raise(rb_eArgError, "cannot specify src_offset for non-IO");
}
rb_rescue2(copy_stream_fallback_body, (VALUE)stp,
- (VALUE (*) (ANYARGS))0, (VALUE)0,
+ (VALUE (*) (VALUE, VALUE))0, (VALUE)0,
rb_eEOFError, (VALUE)0);
return Qnil;
}
@@ -10902,6 +11725,7 @@ copy_stream_body(VALUE arg)
src_fd = -1;
}
else {
+ int stat_ret;
VALUE tmp_io = rb_io_check_io(src_io);
if (!NIL_P(tmp_io)) {
src_io = tmp_io;
@@ -10918,6 +11742,13 @@ copy_stream_body(VALUE arg)
GetOpenFile(src_io, src_fptr);
rb_io_check_byte_readable(src_fptr);
src_fd = src_fptr->fd;
+
+ stat_ret = fstat(src_fd, &stp->src_stat);
+ if (stat_ret < 0) {
+ stp->syserr = "fstat";
+ stp->error_no = errno;
+ return Qnil;
+ }
}
stp->src_fd = src_fd;
@@ -10928,7 +11759,8 @@ copy_stream_body(VALUE arg)
dst_fd = -1;
}
else {
- VALUE tmp_io = rb_io_check_io(dst_io);
+ int stat_ret;
+ VALUE tmp_io = rb_io_check_io(dst_io);
if (!NIL_P(tmp_io)) {
dst_io = GetWriteIO(tmp_io);
}
@@ -10949,6 +11781,13 @@ copy_stream_body(VALUE arg)
GetOpenFile(dst_io, dst_fptr);
rb_io_check_writable(dst_fptr);
dst_fd = dst_fptr->fd;
+
+ stat_ret = fstat(dst_fd, &stp->dst_stat);
+ if (stat_ret < 0) {
+ stp->syserr = "fstat";
+ stp->error_no = errno;
+ return Qnil;
+ }
}
stp->dst_fd = dst_fd;
@@ -10959,10 +11798,10 @@ copy_stream_body(VALUE arg)
if (dst_fptr)
io_ascii8bit_binmode(dst_fptr);
- if (stp->src_offset == (off_t)-1 && src_fptr && src_fptr->rbuf.len) {
+ if (stp->src_offset < (off_t)0 && src_fptr && src_fptr->rbuf.len) {
size_t len = src_fptr->rbuf.len;
VALUE str;
- if (stp->copy_length != (off_t)-1 && stp->copy_length < (off_t)len) {
+ if (stp->copy_length >= (off_t)0 && stp->copy_length < (off_t)len) {
len = (size_t)stp->copy_length;
}
str = rb_str_buf_new(len);
@@ -10970,12 +11809,13 @@ copy_stream_body(VALUE arg)
read_buffered_data(RSTRING_PTR(str), len, src_fptr);
if (dst_fptr) { /* IO or filename */
if (io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str), dst_fptr, 0) < 0)
- rb_sys_fail(0);
+ rb_sys_fail_on_write(dst_fptr);
}
else /* others such as StringIO */
rb_io_write(dst_io, str);
+ rb_str_resize(str, 0);
stp->total += len;
- if (stp->copy_length != (off_t)-1)
+ if (stp->copy_length >= (off_t)0)
stp->copy_length -= len;
}
@@ -10986,13 +11826,10 @@ copy_stream_body(VALUE arg)
if (stp->copy_length == 0)
return Qnil;
- if (src_fd == -1 || dst_fd == -1) {
+ if (src_fd < 0 || dst_fd < 0) {
return copy_stream_fallback(stp);
}
- rb_fd_set(src_fd, &stp->fds);
- rb_fd_set(dst_fd, &stp->fds);
-
rb_thread_call_without_gvl(nogvl_copy_stream_func, (void*)stp, RUBY_UBF_IO, 0);
return Qnil;
}
@@ -11001,13 +11838,19 @@ static VALUE
copy_stream_finalize(VALUE arg)
{
struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
+
+#ifdef HAVE_FCOPYFILE
+ if (stp->copyfile_state) {
+ copyfile_state_free(stp->copyfile_state);
+ }
+#endif
+
if (stp->close_src) {
rb_io_close_m(stp->src);
}
if (stp->close_dst) {
rb_io_close_m(stp->dst);
}
- rb_fd_term(&stp->fds);
if (stp->syserr) {
rb_syserr_fail(stp->error_no, stp->syserr);
}
@@ -11024,7 +11867,11 @@ copy_stream_finalize(VALUE arg)
* IO.copy_stream(src, dst, copy_length, src_offset)
*
* IO.copy_stream copies <i>src</i> to <i>dst</i>.
- * <i>src</i> and <i>dst</i> is either a filename or an IO.
+ * <i>src</i> and <i>dst</i> is either a filename or an IO-like object.
+ * IO-like object for <i>src</i> should have #readpartial or #read
+ * method. IO-like object for <i>dst</i> should have #write method.
+ * (Specialized mechanisms, such as sendfile system call, may be used
+ * on appropriate situation.)
*
* This method returns the number of bytes copied.
*
@@ -11068,7 +11915,6 @@ rb_io_s_copy_stream(int argc, VALUE *argv, VALUE io)
else
st.src_offset = NUM2OFFT(src_offset);
- rb_fd_init(&st.fds);
rb_ensure(copy_stream_body, (VALUE)&st, copy_stream_finalize, (VALUE)&st);
return OFFT2NUM(st.total);
@@ -11510,7 +12356,7 @@ argf_read(int argc, VALUE *argv, VALUE argf)
long slen = RSTRING_LEN(str);
if (slen < len) {
len -= slen;
- argv[0] = INT2NUM(len);
+ argv[0] = LONG2NUM(len);
goto retry;
}
}
@@ -11546,11 +12392,11 @@ static VALUE argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts,
* The _outbuf_ will contain only the received data after the method call
* even if it is not empty at the beginning.
*
- * It raises <code>EOFError</code> on end of ARGF stream.
+ * It raises EOFError on end of ARGF stream.
* Since ARGF stream is a concatenation of multiple files,
* internally EOF is occur for each file.
* ARGF.readpartial returns empty strings for EOFs except the last one and
- * raises <code>EOFError</code> for the last one.
+ * raises EOFError for the last one.
*
*/
@@ -11562,8 +12408,8 @@ argf_readpartial(int argc, VALUE *argv, VALUE argf)
/*
* call-seq:
- * ARGF.read_nonblock(maxlen) -> string
- * ARGF.read_nonblock(maxlen, outbuf) -> outbuf
+ * ARGF.read_nonblock(maxlen[, options]) -> string
+ * ARGF.read_nonblock(maxlen, outbuf[, options]) -> outbuf
*
* Reads at most _maxlen_ bytes from the ARGF stream in non-blocking mode.
*/
@@ -11585,12 +12431,14 @@ static VALUE
argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts, int nonblock)
{
VALUE tmp, str, length;
+ int no_exception;
rb_scan_args(argc, argv, "11", &length, &str);
if (!NIL_P(str)) {
StringValue(str);
argv[1] = str;
}
+ no_exception = no_exception_p(opts);
if (!next_argv()) {
if (!NIL_P(str)) {
@@ -11599,24 +12447,25 @@ argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts, int nonblock)
rb_eof_error();
}
if (ARGF_GENERIC_INPUT_P()) {
+ VALUE (*const rescue_does_nothing)(VALUE, VALUE) = 0;
struct argf_call_arg arg;
arg.argc = argc;
arg.argv = argv;
arg.argf = argf;
tmp = rb_rescue2(argf_forward_call, (VALUE)&arg,
- RUBY_METHOD_FUNC(0), Qnil, rb_eEOFError, (VALUE)0);
+ rescue_does_nothing, Qnil, rb_eEOFError, (VALUE)0);
}
else {
- tmp = io_getpartial(argc, argv, ARGF.current_file, opts, nonblock);
+ tmp = io_getpartial(argc, argv, ARGF.current_file, no_exception, nonblock);
}
if (NIL_P(tmp)) {
if (ARGF.next_p == -1) {
- return io_nonblock_eof(opts);
+ return io_nonblock_eof(no_exception);
}
argf_close(argf);
ARGF.next_p = 1;
if (RARRAY_LEN(ARGF.argv) == 0) {
- return io_nonblock_eof(opts);
+ return io_nonblock_eof(no_exception);
}
if (NIL_P(str))
str = rb_str_new(NULL, 0);
@@ -11794,10 +12643,14 @@ argf_block_call_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, argf))
return Qnil;
}
+#define ARGF_block_call(mid, argc, argv, func, argf) \
+ rb_block_call_kw(ARGF.current_file, mid, argc, argv, \
+ func, argf, rb_keyword_given_p())
+
static void
argf_block_call(ID mid, int argc, VALUE *argv, VALUE argf)
{
- VALUE ret = rb_block_call(ARGF.current_file, mid, argc, argv, argf_block_call_i, argf);
+ VALUE ret = ARGF_block_call(mid, argc, argv, argf_block_call_i, argf);
if (ret != Qundef) ARGF.next_p = 1;
}
@@ -11813,7 +12666,7 @@ argf_block_call_line_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, argf))
static void
argf_block_call_line(ID mid, int argc, VALUE *argv, VALUE argf)
{
- VALUE ret = rb_block_call(ARGF.current_file, mid, argc, argv, argf_block_call_line_i, argf);
+ VALUE ret = ARGF_block_call(mid, argc, argv, argf_block_call_line_i, argf);
if (ret != Qundef) ARGF.next_p = 1;
}
@@ -11838,13 +12691,21 @@ argf_block_call_line(ID mid, int argc, VALUE *argv, VALUE argf)
* a single file consisting of the concatenation of each named file. After
* the last line of the first file has been returned, the first line of the
* second file is returned. The +ARGF.filename+ and +ARGF.lineno+ methods can
- * be used to determine the filename and line number, respectively, of the
- * current line.
+ * be used to determine the filename of the current line and line number of
+ * the whole input, respectively.
*
* For example, the following code prints out each line of each named file
* prefixed with its line number, displaying the filename once per file:
*
* ARGF.each_line do |line|
+ * puts ARGF.filename if ARGF.file.lineno == 1
+ * puts "#{ARGF.file.lineno}: #{line}"
+ * end
+ *
+ * While the following code prints only the first file's name at first, and
+ * the contents with line number counted through all named files.
+ *
+ * ARGF.each_line do |line|
* puts ARGF.filename if ARGF.lineno == 1
* puts "#{ARGF.lineno}: #{line}"
* end
@@ -11860,23 +12721,7 @@ argf_each_line(int argc, VALUE *argv, VALUE argf)
}
/*
- * This is a deprecated alias for <code>each_line</code>.
- */
-
-static VALUE
-argf_lines(int argc, VALUE *argv, VALUE argf)
-{
- rb_warn("ARGF#lines is deprecated; use #each_line instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(argf, ID2SYM(rb_intern("each_line")), argc, argv);
- return argf_each_line(argc, argv, argf);
-}
-
-/*
* call-seq:
- * ARGF.bytes {|byte| block } -> ARGF
- * ARGF.bytes -> an_enumerator
- *
* ARGF.each_byte {|byte| block } -> ARGF
* ARGF.each_byte -> an_enumerator
*
@@ -11907,19 +12752,6 @@ argf_each_byte(VALUE argf)
}
/*
- * This is a deprecated alias for <code>each_byte</code>.
- */
-
-static VALUE
-argf_bytes(VALUE argf)
-{
- rb_warn("ARGF#bytes is deprecated; use #each_byte instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(argf, ID2SYM(rb_intern("each_byte")), 0, 0);
- return argf_each_byte(argf);
-}
-
-/*
* call-seq:
* ARGF.each_char {|char| block } -> ARGF
* ARGF.each_char -> an_enumerator
@@ -11946,19 +12778,6 @@ argf_each_char(VALUE argf)
}
/*
- * This is a deprecated alias for <code>each_char</code>.
- */
-
-static VALUE
-argf_chars(VALUE argf)
-{
- rb_warn("ARGF#chars is deprecated; use #each_char instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(argf, ID2SYM(rb_intern("each_char")), 0, 0);
- return argf_each_char(argf);
-}
-
-/*
* call-seq:
* ARGF.each_codepoint {|codepoint| block } -> ARGF
* ARGF.each_codepoint -> an_enumerator
@@ -11985,19 +12804,6 @@ argf_each_codepoint(VALUE argf)
}
/*
- * This is a deprecated alias for <code>each_codepoint</code>.
- */
-
-static VALUE
-argf_codepoints(VALUE argf)
-{
- rb_warn("ARGF#codepoints is deprecated; use #each_codepoint instead");
- if (!rb_block_given_p())
- return rb_enumeratorize(argf, ID2SYM(rb_intern("each_codepoint")), 0, 0);
- return argf_each_codepoint(argf);
-}
-
-/*
* call-seq:
* ARGF.filename -> String
* ARGF.path -> String
@@ -12189,7 +12995,8 @@ static VALUE
argf_inplace_mode_get(VALUE argf)
{
if (!ARGF.inplace) return Qnil;
- return rb_str_new2(ARGF.inplace);
+ if (NIL_P(ARGF.inplace)) return rb_str_new(0, 0);
+ return rb_str_dup(ARGF.inplace);
}
static VALUE
@@ -12221,18 +13028,14 @@ opt_i_get(ID id, VALUE *var)
static VALUE
argf_inplace_mode_set(VALUE argf, VALUE val)
{
- if (rb_safe_level() >= 1 && OBJ_TAINTED(val))
- rb_insecure_operation();
-
if (!RTEST(val)) {
- if (ARGF.inplace) free(ARGF.inplace);
- ARGF.inplace = 0;
+ ARGF.inplace = Qfalse;
+ }
+ else if (StringValueCStr(val), !RSTRING_LEN(val)) {
+ ARGF.inplace = Qnil;
}
else {
- const char *suffix = StringValueCStr(val);
- if (ARGF.inplace) free(ARGF.inplace);
- ARGF.inplace = 0;
- ARGF.inplace = strdup(suffix);
+ ARGF.inplace = rb_str_new_frozen(val);
}
return argf;
}
@@ -12243,18 +13046,10 @@ opt_i_set(VALUE val, ID id, VALUE *var)
argf_inplace_mode_set(*var, val);
}
-const char *
-ruby_get_inplace_mode(void)
-{
- return ARGF.inplace;
-}
-
void
ruby_set_inplace_mode(const char *suffix)
{
- if (ARGF.inplace) free(ARGF.inplace);
- ARGF.inplace = 0;
- if (suffix) ARGF.inplace = strdup(suffix);
+ ARGF.inplace = !suffix ? Qfalse : !*suffix ? Qnil : rb_str_new(suffix, strlen(suffix));
}
/*
@@ -12318,53 +13113,67 @@ argf_write(VALUE argf, VALUE str)
}
void
-rb_readwrite_sys_fail(enum rb_io_wait_readwrite writable, const char *mesg)
+rb_readwrite_sys_fail(enum rb_io_wait_readwrite waiting, const char *mesg)
{
- rb_readwrite_syserr_fail(writable, errno, mesg);
+ rb_readwrite_syserr_fail(waiting, errno, mesg);
}
void
-rb_readwrite_syserr_fail(enum rb_io_wait_readwrite writable, int n, const char *mesg)
+rb_readwrite_syserr_fail(enum rb_io_wait_readwrite waiting, int n, const char *mesg)
{
- VALUE arg;
+ VALUE arg, c = Qnil;
arg = mesg ? rb_str_new2(mesg) : Qnil;
- if (writable == RB_IO_WAIT_WRITABLE) {
+ switch (waiting) {
+ case RB_IO_WAIT_WRITABLE:
switch (n) {
case EAGAIN:
- rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINWaitWritable));
+ c = rb_eEAGAINWaitWritable;
break;
#if EAGAIN != EWOULDBLOCK
case EWOULDBLOCK:
- rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKWaitWritable));
+ c = rb_eEWOULDBLOCKWaitWritable;
break;
#endif
case EINPROGRESS:
- rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEINPROGRESSWaitWritable));
+ c = rb_eEINPROGRESSWaitWritable;
break;
default:
- rb_mod_sys_fail_str(rb_mWaitWritable, arg);
+ rb_mod_syserr_fail_str(rb_mWaitWritable, n, arg);
}
- }
- else if (writable == RB_IO_WAIT_READABLE) {
+ break;
+ case RB_IO_WAIT_READABLE:
switch (n) {
case EAGAIN:
- rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINWaitReadable));
+ c = rb_eEAGAINWaitReadable;
break;
#if EAGAIN != EWOULDBLOCK
case EWOULDBLOCK:
- rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKWaitReadable));
+ c = rb_eEWOULDBLOCKWaitReadable;
break;
#endif
case EINPROGRESS:
- rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEINPROGRESSWaitReadable));
+ c = rb_eEINPROGRESSWaitReadable;
break;
default:
- rb_mod_sys_fail_str(rb_mWaitReadable, arg);
+ rb_mod_syserr_fail_str(rb_mWaitReadable, n, arg);
}
+ break;
+ default:
+ rb_bug("invalid read/write type passed to rb_readwrite_sys_fail: %d", waiting);
}
- else {
- rb_bug("invalid read/write type passed to rb_readwrite_sys_fail: %d", writable);
- }
+ rb_exc_raise(rb_class_new_instance(1, &arg, c));
+}
+
+static VALUE
+get_LAST_READ_LINE(ID _x, VALUE *_y)
+{
+ return rb_lastline_get();
+}
+
+static void
+set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
+{
+ rb_lastline_set(val);
}
/*
@@ -12525,9 +13334,6 @@ rb_readwrite_syserr_fail(enum rb_io_wait_readwrite writable, int n, const char *
void
Init_IO(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
VALUE rb_cARGF;
#ifdef __CYGWIN__
#include <sys/cygwin.h>
@@ -12545,12 +13351,12 @@ Init_IO(void)
rb_eIOError = rb_define_class("IOError", rb_eStandardError);
rb_eEOFError = rb_define_class("EOFError", rb_eIOError);
- id_write = rb_intern("write");
- id_read = rb_intern("read");
- id_getc = rb_intern("getc");
- id_flush = rb_intern("flush");
- id_readpartial = rb_intern("readpartial");
- id_set_encoding = rb_intern("set_encoding");
+ id_write = rb_intern_const("write");
+ id_read = rb_intern_const("read");
+ id_getc = rb_intern_const("getc");
+ id_flush = rb_intern_const("flush");
+ id_readpartial = rb_intern_const("readpartial");
+ id_set_encoding = rb_intern_const("set_encoding");
rb_define_global_function("syscall", rb_f_syscall, -1);
@@ -12573,10 +13379,18 @@ Init_IO(void)
rb_cIO = rb_define_class("IO", rb_cObject);
rb_include_module(rb_cIO, rb_mEnumerable);
+ rb_define_const(rb_cIO, "READABLE", INT2NUM(RUBY_IO_READABLE));
+ rb_define_const(rb_cIO, "WRITABLE", INT2NUM(RUBY_IO_WRITABLE));
+ rb_define_const(rb_cIO, "PRIORITY", INT2NUM(RUBY_IO_PRIORITY));
+
+ /* exception to wait for reading. see IO.select. */
rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
+ /* exception to wait for writing. see IO.select. */
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
+ /* exception to wait for reading by EAGAIN. see IO.select. */
rb_eEAGAINWaitReadable = rb_define_class_under(rb_cIO, "EAGAINWaitReadable", rb_eEAGAIN);
rb_include_module(rb_eEAGAINWaitReadable, rb_mWaitReadable);
+ /* exception to wait for writing by EAGAIN. see IO.select. */
rb_eEAGAINWaitWritable = rb_define_class_under(rb_cIO, "EAGAINWaitWritable", rb_eEAGAIN);
rb_include_module(rb_eEAGAINWaitWritable, rb_mWaitWritable);
#if EAGAIN == EWOULDBLOCK
@@ -12587,13 +13401,17 @@ Init_IO(void)
/* same as IO::EAGAINWaitWritable */
rb_define_const(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEAGAINWaitWritable);
#else
+ /* exception to wait for reading by EWOULDBLOCK. see IO.select. */
rb_eEWOULDBLOCKWaitReadable = rb_define_class_under(rb_cIO, "EWOULDBLOCKWaitReadable", rb_eEWOULDBLOCK);
rb_include_module(rb_eEWOULDBLOCKWaitReadable, rb_mWaitReadable);
+ /* exception to wait for writing by EWOULDBLOCK. see IO.select. */
rb_eEWOULDBLOCKWaitWritable = rb_define_class_under(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEWOULDBLOCK);
rb_include_module(rb_eEWOULDBLOCKWaitWritable, rb_mWaitWritable);
#endif
+ /* exception to wait for reading by EINPROGRESS. see IO.select. */
rb_eEINPROGRESSWaitReadable = rb_define_class_under(rb_cIO, "EINPROGRESSWaitReadable", rb_eEINPROGRESS);
rb_include_module(rb_eEINPROGRESSWaitReadable, rb_mWaitReadable);
+ /* exception to wait for writing by EINPROGRESS. see IO.select. */
rb_eEINPROGRESSWaitWritable = rb_define_class_under(rb_cIO, "EINPROGRESSWaitWritable", rb_eEINPROGRESS);
rb_include_module(rb_eEINPROGRESSWaitWritable, rb_mWaitWritable);
@@ -12622,17 +13440,18 @@ Init_IO(void)
rb_define_method(rb_cIO, "initialize", rb_io_initialize, -1);
rb_output_fs = Qnil;
- rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter);
+ rb_define_hooked_variable("$,", &rb_output_fs, 0, deprecated_str_setter);
- rb_default_rs = rb_fstring_cstr("\n"); /* avoid modifying RS_default */
+ rb_default_rs = rb_fstring_lit("\n"); /* avoid modifying RS_default */
rb_gc_register_mark_object(rb_default_rs);
rb_rs = rb_default_rs;
rb_output_rs = Qnil;
- rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter);
- rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter);
- rb_define_hooked_variable("$\\", &rb_output_rs, 0, rb_str_setter);
+ rb_define_hooked_variable("$/", &rb_rs, 0, deprecated_str_setter);
+ rb_define_hooked_variable("$-0", &rb_rs, 0, deprecated_str_setter);
+ rb_define_hooked_variable("$\\", &rb_output_rs, 0, deprecated_str_setter);
- rb_define_virtual_variable("$_", rb_lastline_get, rb_lastline_set);
+ rb_define_virtual_variable("$_", get_LAST_READ_LINE, set_LAST_READ_LINE);
+ rb_gvar_ractor_local("$_");
rb_define_method(rb_cIO, "initialize_copy", rb_io_init_copy, 1);
rb_define_method(rb_cIO, "reopen", rb_io_reopen, -1);
@@ -12647,10 +13466,6 @@ Init_IO(void)
rb_define_method(rb_cIO, "each_byte", rb_io_each_byte, 0);
rb_define_method(rb_cIO, "each_char", rb_io_each_char, 0);
rb_define_method(rb_cIO, "each_codepoint", rb_io_each_codepoint, 0);
- rb_define_method(rb_cIO, "lines", rb_io_lines, -1);
- rb_define_method(rb_cIO, "bytes", rb_io_bytes, 0);
- rb_define_method(rb_cIO, "chars", rb_io_chars, 0);
- rb_define_method(rb_cIO, "codepoints", rb_io_codepoints, 0);
rb_define_method(rb_cIO, "syswrite", rb_io_syswrite, 1);
rb_define_method(rb_cIO, "sysread", rb_io_sysread, -1);
@@ -12672,13 +13487,9 @@ Init_IO(void)
rb_define_method(rb_cIO, "readlines", rb_io_readlines, -1);
- /* for prelude.rb use only: */
- rb_define_private_method(rb_cIO, "__read_nonblock", io_read_nonblock, 3);
- rb_define_private_method(rb_cIO, "__write_nonblock", io_write_nonblock, 2);
-
rb_define_method(rb_cIO, "readpartial", io_readpartial, -1);
rb_define_method(rb_cIO, "read", io_read, -1);
- rb_define_method(rb_cIO, "write", io_write_m, 1);
+ rb_define_method(rb_cIO, "write", io_write_m, -1);
rb_define_method(rb_cIO, "gets", rb_io_gets_m, -1);
rb_define_method(rb_cIO, "readline", rb_io_readline, -1);
rb_define_method(rb_cIO, "getc", rb_io_getc, 0);
@@ -12734,17 +13545,29 @@ Init_IO(void)
rb_define_method(rb_cIO, "external_encoding", rb_io_external_encoding, 0);
rb_define_method(rb_cIO, "internal_encoding", rb_io_internal_encoding, 0);
rb_define_method(rb_cIO, "set_encoding", rb_io_set_encoding, -1);
+ rb_define_method(rb_cIO, "set_encoding_by_bom", rb_io_set_encoding_by_bom, 0);
rb_define_method(rb_cIO, "autoclose?", rb_io_autoclose_p, 0);
rb_define_method(rb_cIO, "autoclose=", rb_io_set_autoclose, 1);
- rb_define_variable("$stdin", &rb_stdin);
- rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>");
- rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter);
- rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO, "<STDOUT>");
- rb_define_hooked_variable("$stderr", &rb_stderr, 0, stdout_setter);
- rb_stderr = prep_stdio(stderr, FMODE_WRITABLE|FMODE_SYNC, rb_cIO, "<STDERR>");
- rb_define_hooked_variable("$>", &rb_stdout, 0, stdout_setter);
+ rb_define_virtual_variable("$stdin", stdin_getter, stdin_setter);
+ rb_define_virtual_variable("$stdout", stdout_getter, stdout_setter);
+ rb_define_virtual_variable("$>", stdout_getter, stdout_setter);
+ rb_define_virtual_variable("$stderr", stderr_getter, stderr_setter);
+
+ rb_gvar_ractor_local("$stdin");
+ rb_gvar_ractor_local("$stdout");
+ rb_gvar_ractor_local("$>");
+ rb_gvar_ractor_local("$stderr");
+
+ rb_stdin = rb_io_prep_stdin();
+ rb_stdout = rb_io_prep_stdout();
+ rb_stderr = rb_io_prep_stderr();
+
+ rb_global_variable(&rb_stdin);
+ rb_global_variable(&rb_stdout);
+ rb_global_variable(&rb_stderr);
+
orig_stdout = rb_stdout;
orig_stderr = rb_stderr;
@@ -12781,10 +13604,6 @@ Init_IO(void)
rb_define_method(rb_cARGF, "each_byte", argf_each_byte, 0);
rb_define_method(rb_cARGF, "each_char", argf_each_char, 0);
rb_define_method(rb_cARGF, "each_codepoint", argf_each_codepoint, 0);
- rb_define_method(rb_cARGF, "lines", argf_lines, -1);
- rb_define_method(rb_cARGF, "bytes", argf_bytes, 0);
- rb_define_method(rb_cARGF, "chars", argf_chars, 0);
- rb_define_method(rb_cARGF, "codepoints", argf_codepoints, 0);
rb_define_method(rb_cARGF, "read", argf_read, -1);
rb_define_method(rb_cARGF, "readpartial", argf_readpartial, -1);
@@ -12846,6 +13665,8 @@ Init_IO(void)
ARGF.filename = rb_str_new2("-");
rb_define_hooked_variable("$-i", &argf, opt_i_get, opt_i_set);
+ rb_gvar_ractor_local("$-i");
+
rb_define_hooked_variable("$*", &argf, argf_argv_getter, rb_gvar_readonly_setter);
#if defined (_WIN32) || defined(__CYGWIN__)
@@ -12856,31 +13677,33 @@ Init_IO(void)
rb_define_method(rb_cFile, "initialize", rb_file_initialize, -1);
- sym_mode = ID2SYM(rb_intern("mode"));
- sym_perm = ID2SYM(rb_intern("perm"));
- sym_flags = ID2SYM(rb_intern("flags"));
- sym_extenc = ID2SYM(rb_intern("external_encoding"));
- sym_intenc = ID2SYM(rb_intern("internal_encoding"));
+ sym_mode = ID2SYM(rb_intern_const("mode"));
+ sym_perm = ID2SYM(rb_intern_const("perm"));
+ sym_flags = ID2SYM(rb_intern_const("flags"));
+ sym_extenc = ID2SYM(rb_intern_const("external_encoding"));
+ sym_intenc = ID2SYM(rb_intern_const("internal_encoding"));
sym_encoding = ID2SYM(rb_id_encoding());
- sym_open_args = ID2SYM(rb_intern("open_args"));
- sym_textmode = ID2SYM(rb_intern("textmode"));
- sym_binmode = ID2SYM(rb_intern("binmode"));
- sym_autoclose = ID2SYM(rb_intern("autoclose"));
- sym_normal = ID2SYM(rb_intern("normal"));
- sym_sequential = ID2SYM(rb_intern("sequential"));
- sym_random = ID2SYM(rb_intern("random"));
- sym_willneed = ID2SYM(rb_intern("willneed"));
- sym_dontneed = ID2SYM(rb_intern("dontneed"));
- sym_noreuse = ID2SYM(rb_intern("noreuse"));
- sym_SET = ID2SYM(rb_intern("SET"));
- sym_CUR = ID2SYM(rb_intern("CUR"));
- sym_END = ID2SYM(rb_intern("END"));
+ sym_open_args = ID2SYM(rb_intern_const("open_args"));
+ sym_textmode = ID2SYM(rb_intern_const("textmode"));
+ sym_binmode = ID2SYM(rb_intern_const("binmode"));
+ sym_autoclose = ID2SYM(rb_intern_const("autoclose"));
+ sym_normal = ID2SYM(rb_intern_const("normal"));
+ sym_sequential = ID2SYM(rb_intern_const("sequential"));
+ sym_random = ID2SYM(rb_intern_const("random"));
+ sym_willneed = ID2SYM(rb_intern_const("willneed"));
+ sym_dontneed = ID2SYM(rb_intern_const("dontneed"));
+ sym_noreuse = ID2SYM(rb_intern_const("noreuse"));
+ sym_SET = ID2SYM(rb_intern_const("SET"));
+ sym_CUR = ID2SYM(rb_intern_const("CUR"));
+ sym_END = ID2SYM(rb_intern_const("END"));
#ifdef SEEK_DATA
- sym_DATA = ID2SYM(rb_intern("DATA"));
+ sym_DATA = ID2SYM(rb_intern_const("DATA"));
#endif
#ifdef SEEK_HOLE
- sym_HOLE = ID2SYM(rb_intern("HOLE"));
+ sym_HOLE = ID2SYM(rb_intern_const("HOLE"));
#endif
- sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
- sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
+ sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
+ sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
}
+
+#include "io.rbinc"
diff --git a/io.rb b/io.rb
new file mode 100644
index 0000000000..40873ea4fd
--- /dev/null
+++ b/io.rb
@@ -0,0 +1,123 @@
+class IO
+ # other IO methods are defined in io.c
+
+ # call-seq:
+ # ios.read_nonblock(maxlen [, options]) -> string
+ # ios.read_nonblock(maxlen, outbuf [, options]) -> outbuf
+ #
+ # Reads at most <i>maxlen</i> bytes from <em>ios</em> using
+ # the read(2) system call after O_NONBLOCK is set for
+ # the underlying file descriptor.
+ #
+ # If the optional <i>outbuf</i> argument is present,
+ # it must reference a String, which will receive the data.
+ # The <i>outbuf</i> will contain only the received data after the method call
+ # even if it is not empty at the beginning.
+ #
+ # read_nonblock just calls the read(2) system call.
+ # It causes all errors the read(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc.
+ # The caller should care such errors.
+ #
+ # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
+ # it is extended by IO::WaitReadable.
+ # So IO::WaitReadable can be used to rescue the exceptions for retrying
+ # read_nonblock.
+ #
+ # read_nonblock causes EOFError on EOF.
+ #
+ # On some platforms, such as Windows, non-blocking mode is not supported
+ # on IO objects other than sockets. In such cases, Errno::EBADF will
+ # be raised.
+ #
+ # If the read byte buffer is not empty,
+ # read_nonblock reads from the buffer like readpartial.
+ # In this case, the read(2) system call is not called.
+ #
+ # When read_nonblock raises an exception kind of IO::WaitReadable,
+ # read_nonblock should not be called
+ # until io is readable for avoiding busy loop.
+ # This can be done as follows.
+ #
+ # # emulates blocking read (readpartial).
+ # begin
+ # result = io.read_nonblock(maxlen)
+ # rescue IO::WaitReadable
+ # IO.select([io])
+ # retry
+ # end
+ #
+ # Although IO#read_nonblock doesn't raise IO::WaitWritable.
+ # OpenSSL::Buffering#read_nonblock can raise IO::WaitWritable.
+ # If IO and SSL should be used polymorphically,
+ # IO::WaitWritable should be rescued too.
+ # See the document of OpenSSL::Buffering#read_nonblock for sample code.
+ #
+ # Note that this method is identical to readpartial
+ # except the non-blocking flag is set.
+ #
+ # By specifying a keyword argument _exception_ to +false+, you can indicate
+ # that read_nonblock should not raise an IO::WaitReadable exception, but
+ # return the symbol +:wait_readable+ instead. At EOF, it will return nil
+ # instead of raising EOFError.
+ def read_nonblock(len, buf = nil, exception: true)
+ Primitive.io_read_nonblock(len, buf, exception)
+ end
+
+ # call-seq:
+ # ios.write_nonblock(string) -> integer
+ # ios.write_nonblock(string [, options]) -> integer
+ #
+ # Writes the given string to <em>ios</em> using
+ # the write(2) system call after O_NONBLOCK is set for
+ # the underlying file descriptor.
+ #
+ # It returns the number of bytes written.
+ #
+ # write_nonblock just calls the write(2) system call.
+ # It causes all errors the write(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc.
+ # The result may also be smaller than string.length (partial write).
+ # The caller should care such errors and partial write.
+ #
+ # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
+ # it is extended by IO::WaitWritable.
+ # So IO::WaitWritable can be used to rescue the exceptions for retrying write_nonblock.
+ #
+ # # Creates a pipe.
+ # r, w = IO.pipe
+ #
+ # # write_nonblock writes only 65536 bytes and return 65536.
+ # # (The pipe size is 65536 bytes on this environment.)
+ # s = "a" * 100000
+ # p w.write_nonblock(s) #=> 65536
+ #
+ # # write_nonblock cannot write a byte and raise EWOULDBLOCK (EAGAIN).
+ # p w.write_nonblock("b") # Resource temporarily unavailable (Errno::EAGAIN)
+ #
+ # If the write buffer is not empty, it is flushed at first.
+ #
+ # When write_nonblock raises an exception kind of IO::WaitWritable,
+ # write_nonblock should not be called
+ # until io is writable for avoiding busy loop.
+ # This can be done as follows.
+ #
+ # begin
+ # result = io.write_nonblock(string)
+ # rescue IO::WaitWritable, Errno::EINTR
+ # IO.select(nil, [io])
+ # retry
+ # end
+ #
+ # Note that this doesn't guarantee to write all data in string.
+ # The length written is reported as result and it should be checked later.
+ #
+ # On some platforms such as Windows, write_nonblock is not supported
+ # according to the kind of the IO object.
+ # In such cases, write_nonblock raises <code>Errno::EBADF</code>.
+ #
+ # By specifying a keyword argument _exception_ to +false+, you can indicate
+ # that write_nonblock should not raise an IO::WaitWritable exception, but
+ # return the symbol +:wait_writable+ instead.
+ def write_nonblock(buf, exception: true)
+ Primitive.io_write_nonblock(buf, exception)
+ end
+end
diff --git a/iseq.c b/iseq.c
index adb0c79917..2d83bc3f06 100644
--- a/iseq.c
+++ b/iseq.c
@@ -9,20 +9,37 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/util.h"
-#include "eval_intern.h"
+#define RUBY_VM_INSNS_INFO 1
+/* #define RUBY_MARK_FREE_DEBUG 1 */
+
+#include "ruby/internal/config.h"
#ifdef HAVE_DLADDR
# include <dlfcn.h>
#endif
-/* #define RUBY_MARK_FREE_DEBUG 1 */
+#include "eval_intern.h"
#include "gc.h"
-#include "vm_core.h"
-#include "iseq.h"
#include "id_table.h"
+#include "internal.h"
+#include "internal/bits.h"
+#include "internal/class.h"
+#include "internal/compile.h"
+#include "internal/error.h"
+#include "internal/file.h"
+#include "internal/hash.h"
+#include "internal/parse.h"
+#include "internal/sanitizers.h"
+#include "internal/symbol.h"
+#include "internal/thread.h"
+#include "internal/variable.h"
+#include "iseq.h"
+#include "mjit.h"
+#include "ruby/util.h"
+#include "vm_core.h"
+#include "vm_callinfo.h"
+#include "builtin.h"
#include "insns.inc"
#include "insns_info.inc"
@@ -30,6 +47,12 @@ VALUE rb_cISeq;
static VALUE iseqw_new(const rb_iseq_t *iseq);
static const rb_iseq_t *iseqw_check(VALUE iseqw);
+#if VM_INSN_INFO_TABLE_IMPL == 2
+static struct succ_index_table *succ_index_table_create(int max_pos, int *data, int size);
+static unsigned int *succ_index_table_invert(int max_pos, struct succ_index_table *sd, int size);
+static int succ_index_lookup(const struct succ_index_table *sd, int x);
+#endif
+
#define hidden_obj_p(obj) (!SPECIAL_CONST_P(obj) && !RBASIC(obj)->klass)
static inline VALUE
@@ -43,22 +66,34 @@ obj_resurrect(VALUE obj)
case T_ARRAY:
obj = rb_ary_resurrect(obj);
break;
+ case T_HASH:
+ obj = rb_hash_resurrect(obj);
+ break;
+ default:
+ break;
}
}
return obj;
}
static void
+free_arena(struct iseq_compile_data_storage *cur)
+{
+ struct iseq_compile_data_storage *next;
+
+ while (cur) {
+ next = cur->next;
+ ruby_xfree(cur);
+ cur = next;
+ }
+}
+
+static void
compile_data_free(struct iseq_compile_data *compile_data)
{
if (compile_data) {
- struct iseq_compile_data_storage *cur, *next;
- cur = compile_data->storage_head;
- while (cur) {
- next = cur->next;
- ruby_xfree(cur);
- cur = next;
- }
+ free_arena(compile_data->node.storage_head);
+ free_arena(compile_data->insn.storage_head);
if (compile_data->ivar_cache_table) {
rb_id_table_free(compile_data->ivar_cache_table);
}
@@ -71,60 +106,320 @@ rb_iseq_free(const rb_iseq_t *iseq)
{
RUBY_FREE_ENTER("iseq");
- if (iseq) {
- if (iseq->body) {
- ruby_xfree((void *)iseq->body->iseq_encoded);
- ruby_xfree((void *)iseq->body->line_info_table);
- ruby_xfree((void *)iseq->body->local_table);
- ruby_xfree((void *)iseq->body->is_entries);
-
- if (iseq->body->ci_entries) {
- unsigned int i;
- struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&iseq->body->ci_entries[iseq->body->ci_size];
- for (i=0; i<iseq->body->ci_kw_size; i++) {
- const struct rb_call_info_kw_arg *kw_arg = ci_kw_entries[i].kw_arg;
- ruby_xfree((void *)kw_arg);
- }
- ruby_xfree(iseq->body->ci_entries);
- ruby_xfree(iseq->body->cc_entries);
- }
- ruby_xfree((void *)iseq->body->catch_table);
- ruby_xfree((void *)iseq->body->param.opt_table);
+ if (iseq && iseq->body) {
+ struct rb_iseq_constant_body *const body = iseq->body;
+ mjit_free_iseq(iseq); /* Notify MJIT */
+ ruby_xfree((void *)body->iseq_encoded);
+ ruby_xfree((void *)body->insns_info.body);
+ if (body->insns_info.positions) ruby_xfree((void *)body->insns_info.positions);
+#if VM_INSN_INFO_TABLE_IMPL == 2
+ if (body->insns_info.succ_index_table) ruby_xfree(body->insns_info.succ_index_table);
+#endif
+ if (LIKELY(body->local_table != rb_iseq_shared_exc_local_tbl))
+ ruby_xfree((void *)body->local_table);
+ ruby_xfree((void *)body->is_entries);
- if (iseq->body->param.keyword != NULL) {
- ruby_xfree((void *)iseq->body->param.keyword->default_values);
- ruby_xfree((void *)iseq->body->param.keyword);
- }
- compile_data_free(ISEQ_COMPILE_DATA(iseq));
- ruby_xfree(iseq->body);
+ if (body->call_data) {
+ ruby_xfree(body->call_data);
+ }
+ ruby_xfree((void *)body->catch_table);
+ ruby_xfree((void *)body->param.opt_table);
+
+ if (body->param.keyword != NULL) {
+ ruby_xfree((void *)body->param.keyword->default_values);
+ ruby_xfree((void *)body->param.keyword);
}
+ compile_data_free(ISEQ_COMPILE_DATA(iseq));
+ if (body->outer_variables) rb_id_table_free(body->outer_variables);
+ ruby_xfree(body);
+ }
+
+ if (iseq && ISEQ_EXECUTABLE_P(iseq) && iseq->aux.exec.local_hooks) {
+ rb_hook_list_free(iseq->aux.exec.local_hooks);
}
+
RUBY_FREE_LEAVE("iseq");
}
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+static VALUE
+rb_vm_insn_addr2insn2(const void *addr)
+{
+ return (VALUE)rb_vm_insn_addr2insn(addr);
+}
+#endif
+
+static VALUE
+rb_vm_insn_null_translator(const void *addr)
+{
+ return (VALUE)addr;
+}
+
+typedef VALUE iseq_value_itr_t(void *ctx, VALUE obj);
+typedef VALUE rb_vm_insns_translator_t(const void *addr);
+
+static int
+iseq_extract_values(VALUE *code, size_t pos, iseq_value_itr_t * func, void *data, rb_vm_insns_translator_t * translator)
+{
+ VALUE insn = translator((void *)code[pos]);
+ int len = insn_len(insn);
+ int op_no;
+ const char *types = insn_op_types(insn);
+
+ for (op_no = 0; types[op_no]; op_no++) {
+ char type = types[op_no];
+ switch (type) {
+ case TS_CDHASH:
+ case TS_ISEQ:
+ case TS_VALUE:
+ {
+ VALUE op = code[pos + op_no + 1];
+ if (!SPECIAL_CONST_P(op)) {
+ VALUE newop = func(data, op);
+ if (newop != op) {
+ code[pos + op_no + 1] = newop;
+ }
+ }
+ }
+ break;
+ case TS_IC:
+ {
+ IC ic = (IC)code[pos + op_no + 1];
+ if (ic->entry) {
+ VALUE nv = func(data, (VALUE)ic->entry);
+ if ((VALUE)ic->entry != nv) {
+ ic->entry = (void *)nv;
+ }
+ }
+ }
+ break;
+ case TS_IVC:
+ {
+ IVC ivc = (IVC)code[pos + op_no + 1];
+ if (ivc->entry) {
+ if (RB_TYPE_P(ivc->entry->class_value, T_NONE)) {
+ rb_bug("!! %u", ivc->entry->index);
+ }
+ VALUE nv = func(data, ivc->entry->class_value);
+ if (ivc->entry->class_value != nv) {
+ ivc->entry->class_value = nv;
+ }
+ }
+ }
+ break;
+ case TS_ISE:
+ {
+ union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)code[pos + op_no + 1];
+ if (is->once.value) {
+ VALUE nv = func(data, is->once.value);
+ if (is->once.value != nv) {
+ is->once.value = nv;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return len;
+}
+
+static void
+rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
+{
+ unsigned int size;
+ VALUE *code;
+ size_t n;
+ rb_vm_insns_translator_t *const translator =
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ (FL_TEST((VALUE)iseq, ISEQ_TRANSLATED)) ? rb_vm_insn_addr2insn2 :
+#endif
+ rb_vm_insn_null_translator;
+ const struct rb_iseq_constant_body *const body = iseq->body;
+
+ size = body->iseq_size;
+ code = body->iseq_encoded;
+
+ for (n = 0; n < size;) {
+ n += iseq_extract_values(code, n, func, data, translator);
+ }
+}
+
+static VALUE
+update_each_insn_value(void *ctx, VALUE obj)
+{
+ return rb_gc_location(obj);
+}
+
+void
+rb_iseq_update_references(rb_iseq_t *iseq)
+{
+ if (iseq->body) {
+ struct rb_iseq_constant_body *body = iseq->body;
+
+ body->variable.coverage = rb_gc_location(body->variable.coverage);
+ body->variable.pc2branchindex = rb_gc_location(body->variable.pc2branchindex);
+ body->location.label = rb_gc_location(body->location.label);
+ body->location.base_label = rb_gc_location(body->location.base_label);
+ body->location.pathobj = rb_gc_location(body->location.pathobj);
+ if (body->local_iseq) {
+ body->local_iseq = (struct rb_iseq_struct *)rb_gc_location((VALUE)body->local_iseq);
+ }
+ if (body->parent_iseq) {
+ body->parent_iseq = (struct rb_iseq_struct *)rb_gc_location((VALUE)body->parent_iseq);
+ }
+ if (body->call_data) {
+ for (unsigned int i=0; i<body->ci_size; i++) {
+ struct rb_call_data *cds = body->call_data;
+ if (!SPECIAL_CONST_P((VALUE)cds[i].ci)) {
+ cds[i].ci = (struct rb_callinfo *)rb_gc_location((VALUE)cds[i].ci);
+ }
+ cds[i].cc = (struct rb_callcache *)rb_gc_location((VALUE)cds[i].cc);
+ }
+ }
+ if (FL_TEST((VALUE)iseq, ISEQ_MARKABLE_ISEQ)) {
+ rb_iseq_each_value(iseq, update_each_insn_value, NULL);
+ VALUE *original_iseq = ISEQ_ORIGINAL_ISEQ(iseq);
+ if (original_iseq) {
+ size_t n = 0;
+ const unsigned int size = body->iseq_size;
+ while (n < size) {
+ n += iseq_extract_values(original_iseq, n, update_each_insn_value, NULL, rb_vm_insn_null_translator);
+ }
+ }
+ }
+
+ if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
+ int i, j;
+
+ i = body->param.keyword->required_num;
+
+ for (j = 0; i < body->param.keyword->num; i++, j++) {
+ VALUE obj = body->param.keyword->default_values[j];
+ if (obj != Qundef) {
+ body->param.keyword->default_values[j] = rb_gc_location(obj);
+ }
+ }
+ }
+
+ if (body->catch_table) {
+ struct iseq_catch_table *table = body->catch_table;
+ unsigned int i;
+ for (i = 0; i < table->size; i++) {
+ struct iseq_catch_table_entry *entry;
+ entry = UNALIGNED_MEMBER_PTR(table, entries[i]);
+ if (entry->iseq) {
+ entry->iseq = (rb_iseq_t *)rb_gc_location((VALUE)entry->iseq);
+ }
+ }
+ }
+#if USE_MJIT
+ mjit_update_references(iseq);
+#endif
+ }
+}
+
+static VALUE
+each_insn_value(void *ctx, VALUE obj)
+{
+ rb_gc_mark_movable(obj);
+ return obj;
+}
+
void
rb_iseq_mark(const rb_iseq_t *iseq)
{
RUBY_MARK_ENTER("iseq");
+ RUBY_MARK_UNLESS_NULL(iseq->wrapper);
+
if (iseq->body) {
- const struct rb_iseq_constant_body *body = iseq->body;
+ const struct rb_iseq_constant_body *const body = iseq->body;
+
+ if (FL_TEST((VALUE)iseq, ISEQ_MARKABLE_ISEQ)) {
+ rb_iseq_each_value(iseq, each_insn_value, NULL);
+ }
+
+ rb_gc_mark_movable(body->variable.coverage);
+ rb_gc_mark_movable(body->variable.pc2branchindex);
+ rb_gc_mark_movable(body->location.label);
+ rb_gc_mark_movable(body->location.base_label);
+ rb_gc_mark_movable(body->location.pathobj);
+ RUBY_MARK_MOVABLE_UNLESS_NULL((VALUE)body->parent_iseq);
+
+ if (body->call_data) {
+ struct rb_call_data *cds = (struct rb_call_data *)body->call_data;
+ for (unsigned int i=0; i<body->ci_size; i++) {
+ const struct rb_callinfo *ci = cds[i].ci;
+ const struct rb_callcache *cc = cds[i].cc;
+
+ if (vm_ci_markable(ci)) {
+ rb_gc_mark_movable((VALUE)ci);
+ }
+ if (cc && vm_cc_markable(cc)) {
+ if (!vm_cc_invalidated_p(cc)) {
+ rb_gc_mark_movable((VALUE)cc);
+ }
+ else {
+ cds[i].cc = rb_vm_empty_cc();
+ }
+ }
+ }
+ }
+
+ if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
+ const struct rb_iseq_param_keyword *const keyword = body->param.keyword;
+ int i, j;
+
+ i = keyword->required_num;
- RUBY_MARK_UNLESS_NULL(body->mark_ary);
- rb_gc_mark(body->location.label);
- rb_gc_mark(body->location.base_label);
- rb_gc_mark(body->location.pathobj);
- RUBY_MARK_UNLESS_NULL((VALUE)body->parent_iseq);
+ for (j = 0; i < keyword->num; i++, j++) {
+ VALUE obj = keyword->default_values[j];
+ if (!SPECIAL_CONST_P(obj)) {
+ rb_gc_mark_movable(obj);
+ }
+ }
+ }
+
+ if (body->catch_table) {
+ const struct iseq_catch_table *table = body->catch_table;
+ unsigned int i;
+ for (i = 0; i < table->size; i++) {
+ const struct iseq_catch_table_entry *entry;
+ entry = UNALIGNED_MEMBER_PTR(table, entries[i]);
+ if (entry->iseq) {
+ rb_gc_mark_movable((VALUE)entry->iseq);
+ }
+ }
+ }
+
+#if USE_MJIT
+ mjit_mark_cc_entries(body);
+#endif
}
- if (FL_TEST(iseq, ISEQ_NOT_LOADED_YET)) {
+ if (FL_TEST_RAW((VALUE)iseq, ISEQ_NOT_LOADED_YET)) {
rb_gc_mark(iseq->aux.loader.obj);
}
- else if (ISEQ_COMPILE_DATA(iseq) != 0) {
+ else if (FL_TEST_RAW((VALUE)iseq, ISEQ_USE_COMPILE_DATA)) {
const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq);
- RUBY_MARK_UNLESS_NULL(compile_data->mark_ary);
- RUBY_MARK_UNLESS_NULL(compile_data->err_info);
- RUBY_MARK_UNLESS_NULL(compile_data->catch_table_ary);
+
+ rb_iseq_mark_insn_storage(compile_data->insn.storage_head);
+
+ RUBY_MARK_UNLESS_NULL(compile_data->err_info);
+ if (RTEST(compile_data->catch_table_ary)) {
+ rb_gc_mark(compile_data->catch_table_ary);
+ }
+ VM_ASSERT(compile_data != NULL);
+ }
+ else {
+ /* executable */
+ VM_ASSERT(ISEQ_EXECUTABLE_P(iseq));
+ if (iseq->aux.exec.local_hooks) {
+ rb_hook_list_mark(iseq->aux.exec.local_hooks);
+ }
}
RUBY_MARK_LEAVE("iseq");
@@ -143,8 +438,8 @@ param_keyword_size(const struct rb_iseq_param_keyword *pkw)
return size;
}
-static size_t
-iseq_memsize(const rb_iseq_t *iseq)
+size_t
+rb_iseq_memsize(const rb_iseq_t *iseq)
{
size_t size = 0; /* struct already counted as RVALUE size */
const struct rb_iseq_constant_body *body = iseq->body;
@@ -152,41 +447,23 @@ iseq_memsize(const rb_iseq_t *iseq)
/* TODO: should we count original_iseq? */
- if (body) {
- struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&body->ci_entries[body->ci_size];
-
- size += sizeof(struct rb_iseq_constant_body);
- size += body->iseq_size * sizeof(VALUE);
- size += body->line_info_size * sizeof(struct iseq_line_info_entry);
- size += body->local_table_size * sizeof(ID);
- if (body->catch_table) {
- size += iseq_catch_table_bytes(body->catch_table->size);
- }
- size += (body->param.opt_num + 1) * sizeof(VALUE);
- size += param_keyword_size(body->param.keyword);
-
- /* body->is_entries */
- size += body->is_size * sizeof(union iseq_inline_storage_entry);
-
- /* body->ci_entries */
- size += body->ci_size * sizeof(struct rb_call_info);
- size += body->ci_kw_size * sizeof(struct rb_call_info_with_kwarg);
-
- /* body->cc_entries */
- size += body->ci_size * sizeof(struct rb_call_cache);
- size += body->ci_kw_size * sizeof(struct rb_call_cache);
-
- if (ci_kw_entries) {
- unsigned int i;
+ if (ISEQ_EXECUTABLE_P(iseq) && body) {
+ size += sizeof(struct rb_iseq_constant_body);
+ size += body->iseq_size * sizeof(VALUE);
+ size += body->insns_info.size * (sizeof(struct iseq_insn_info_entry) + sizeof(unsigned int));
+ size += body->local_table_size * sizeof(ID);
+ if (body->catch_table) {
+ size += iseq_catch_table_bytes(body->catch_table->size);
+ }
+ size += (body->param.opt_num + 1) * sizeof(VALUE);
+ size += param_keyword_size(body->param.keyword);
- for (i = 0; i < body->ci_kw_size; i++) {
- const struct rb_call_info_kw_arg *kw_arg = ci_kw_entries[i].kw_arg;
+ /* body->is_entries */
+ size += body->is_size * sizeof(union iseq_inline_storage_entry);
- if (kw_arg) {
- size += rb_call_info_kw_arg_bytes(kw_arg->keyword_len);
- }
- }
- }
+ /* body->call_data */
+ size += body->ci_size * sizeof(struct rb_call_data);
+ // TODO: should we count imemo_callinfo?
}
compile_data = ISEQ_COMPILE_DATA(iseq);
@@ -195,9 +472,9 @@ iseq_memsize(const rb_iseq_t *iseq)
size += sizeof(struct iseq_compile_data);
- cur = compile_data->storage_head;
+ cur = compile_data->node.storage_head;
while (cur) {
- size += cur->size + SIZEOF_ISEQ_COMPILE_DATA_STORAGE;
+ size += cur->size + offsetof(struct iseq_compile_data_storage, buff);
cur = cur->next;
}
}
@@ -205,11 +482,19 @@ iseq_memsize(const rb_iseq_t *iseq)
return size;
}
+struct rb_iseq_constant_body *
+rb_iseq_constant_body_alloc(void)
+{
+ struct rb_iseq_constant_body *iseq_body;
+ iseq_body = ZALLOC(struct rb_iseq_constant_body);
+ return iseq_body;
+}
+
static rb_iseq_t *
iseq_alloc(void)
{
rb_iseq_t *iseq = iseq_imemo_alloc();
- iseq->body = ZALLOC(struct rb_iseq_constant_body);
+ iseq->body = rb_iseq_constant_body_alloc();
return iseq;
}
@@ -240,7 +525,7 @@ rb_iseq_pathobj_set(const rb_iseq_t *iseq, VALUE path, VALUE realpath)
}
static rb_iseq_location_t *
-iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno)
+iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_code_location_t *code_location, const int node_id)
{
rb_iseq_location_t *loc = &iseq->body->location;
@@ -248,81 +533,96 @@ iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, VAL
RB_OBJ_WRITE(iseq, &loc->label, name);
RB_OBJ_WRITE(iseq, &loc->base_label, name);
loc->first_lineno = first_lineno;
+ if (code_location) {
+ loc->node_id = node_id;
+ loc->code_location = *code_location;
+ }
+ else {
+ loc->code_location.beg_pos.lineno = 0;
+ loc->code_location.beg_pos.column = 0;
+ loc->code_location.end_pos.lineno = -1;
+ loc->code_location.end_pos.column = -1;
+ }
+
return loc;
}
static void
set_relation(rb_iseq_t *iseq, const rb_iseq_t *piseq)
{
- const VALUE type = iseq->body->type;
+ struct rb_iseq_constant_body *const body = iseq->body;
+ const VALUE type = body->type;
/* set class nest stack */
if (type == ISEQ_TYPE_TOP) {
- iseq->body->local_iseq = iseq;
+ body->local_iseq = iseq;
}
else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
- iseq->body->local_iseq = iseq;
+ body->local_iseq = iseq;
}
else if (piseq) {
- iseq->body->local_iseq = piseq->body->local_iseq;
+ body->local_iseq = piseq->body->local_iseq;
}
if (piseq) {
- iseq->body->parent_iseq = piseq;
+ body->parent_iseq = piseq;
}
if (type == ISEQ_TYPE_MAIN) {
- iseq->body->local_iseq = iseq;
+ body->local_iseq = iseq;
}
}
-void
-rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj)
+static struct iseq_compile_data_storage *
+new_arena(void)
{
- /* TODO: check dedup */
- rb_ary_push(ISEQ_MARK_ARY(iseq), obj);
+ struct iseq_compile_data_storage * new_arena =
+ (struct iseq_compile_data_storage *)
+ ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE +
+ offsetof(struct iseq_compile_data_storage, buff));
+
+ new_arena->pos = 0;
+ new_arena->next = 0;
+ new_arena->size = INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE;
+
+ return new_arena;
}
static VALUE
prepare_iseq_build(rb_iseq_t *iseq,
- VALUE name, VALUE path, VALUE realpath, VALUE first_lineno,
- const rb_iseq_t *parent, enum iseq_type type,
- const rb_compile_option_t *option)
+ VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_code_location_t *code_location, const int node_id,
+ const rb_iseq_t *parent, int isolated_depth, enum iseq_type type, const rb_compile_option_t *option)
{
VALUE coverage = Qfalse;
VALUE err_info = Qnil;
+ struct rb_iseq_constant_body *const body = iseq->body;
if (parent && (type == ISEQ_TYPE_MAIN || type == ISEQ_TYPE_TOP))
err_info = Qfalse;
- iseq->body->type = type;
+ body->type = type;
set_relation(iseq, parent);
name = rb_fstring(name);
- iseq_location_setup(iseq, name, path, realpath, first_lineno);
- if (iseq != iseq->body->local_iseq) {
- RB_OBJ_WRITE(iseq, &iseq->body->location.base_label, iseq->body->local_iseq->body->location.label);
+ iseq_location_setup(iseq, name, path, realpath, first_lineno, code_location, node_id);
+ if (iseq != body->local_iseq) {
+ RB_OBJ_WRITE(iseq, &body->location.base_label, body->local_iseq->body->location.label);
}
- RB_OBJ_WRITE(iseq, &iseq->body->mark_ary, iseq_mark_ary_create(0));
+ ISEQ_COVERAGE_SET(iseq, Qnil);
+ ISEQ_ORIGINAL_ISEQ_CLEAR(iseq);
+ body->variable.flip_count = 0;
- ISEQ_COMPILE_DATA(iseq) = ZALLOC(struct iseq_compile_data);
+ ISEQ_COMPILE_DATA_ALLOC(iseq);
RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->err_info, err_info);
- RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->mark_ary, rb_ary_tmp_new(3));
-
- ISEQ_COMPILE_DATA(iseq)->storage_head = ISEQ_COMPILE_DATA(iseq)->storage_current =
- (struct iseq_compile_data_storage *)
- ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE +
- SIZEOF_ISEQ_COMPILE_DATA_STORAGE);
-
- RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, rb_ary_tmp_new(3));
- ISEQ_COMPILE_DATA(iseq)->storage_head->pos = 0;
- ISEQ_COMPILE_DATA(iseq)->storage_head->next = 0;
- ISEQ_COMPILE_DATA(iseq)->storage_head->size =
- INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE;
- ISEQ_COMPILE_DATA(iseq)->option = option;
- ISEQ_COMPILE_DATA(iseq)->last_coverable_line = -1;
+ RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, Qnil);
+ ISEQ_COMPILE_DATA(iseq)->node.storage_head = ISEQ_COMPILE_DATA(iseq)->node.storage_current = new_arena();
+ ISEQ_COMPILE_DATA(iseq)->insn.storage_head = ISEQ_COMPILE_DATA(iseq)->insn.storage_current = new_arena();
+ ISEQ_COMPILE_DATA(iseq)->isolated_depth = isolated_depth;
+ ISEQ_COMPILE_DATA(iseq)->option = option;
ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = NULL;
+ ISEQ_COMPILE_DATA(iseq)->builtin_function_table = GET_VM()->builtin_function_table;
+
if (option->coverage_enabled) {
VALUE coverages = rb_get_coverages();
@@ -332,24 +632,78 @@ prepare_iseq_build(rb_iseq_t *iseq,
}
}
ISEQ_COVERAGE_SET(iseq, coverage);
+ if (coverage && ISEQ_BRANCH_COVERAGE(iseq))
+ ISEQ_PC2BRANCHINDEX_SET(iseq, rb_ary_tmp_new(0));
return Qtrue;
}
+#if VM_CHECK_MODE > 0 && VM_INSN_INFO_TABLE_IMPL > 0
+static void validate_get_insn_info(const rb_iseq_t *iseq);
+#endif
+
+void
+rb_iseq_insns_info_encode_positions(const rb_iseq_t *iseq)
+{
+#if VM_INSN_INFO_TABLE_IMPL == 2
+ /* create succ_index_table */
+ struct rb_iseq_constant_body *const body = iseq->body;
+ int size = body->insns_info.size;
+ int max_pos = body->iseq_size;
+ int *data = (int *)body->insns_info.positions;
+ if (body->insns_info.succ_index_table) ruby_xfree(body->insns_info.succ_index_table);
+ body->insns_info.succ_index_table = succ_index_table_create(max_pos, data, size);
+#if VM_CHECK_MODE == 0
+ ruby_xfree(body->insns_info.positions);
+ body->insns_info.positions = NULL;
+#endif
+#endif
+}
+
+#if VM_INSN_INFO_TABLE_IMPL == 2
+unsigned int *
+rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body)
+{
+ int size = body->insns_info.size;
+ int max_pos = body->iseq_size;
+ struct succ_index_table *sd = body->insns_info.succ_index_table;
+ return succ_index_table_invert(max_pos, sd, size);
+}
+#endif
+
+void
+rb_iseq_init_trace(rb_iseq_t *iseq)
+{
+ iseq->aux.exec.global_trace_events = 0;
+ if (ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS) {
+ rb_iseq_trace_set(iseq, ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS);
+ }
+}
+
static VALUE
-cleanup_iseq_build(rb_iseq_t *iseq)
+finish_iseq_build(rb_iseq_t *iseq)
{
struct iseq_compile_data *data = ISEQ_COMPILE_DATA(iseq);
+ const struct rb_iseq_constant_body *const body = iseq->body;
VALUE err = data->err_info;
- ISEQ_COMPILE_DATA(iseq) = 0;
+ ISEQ_COMPILE_DATA_CLEAR(iseq);
compile_data_free(data);
+#if VM_CHECK_MODE > 0 && VM_INSN_INFO_TABLE_IMPL > 0
+ validate_get_insn_info(iseq);
+#endif
+
if (RTEST(err)) {
- VALUE path = pathobj_path(iseq->body->location.pathobj);
+ VALUE path = pathobj_path(body->location.pathobj);
if (err == Qtrue) err = rb_exc_new_cstr(rb_eSyntaxError, "compile error");
rb_funcallv(err, rb_intern("set_backtrace"), 1, &path);
rb_exc_raise(err);
}
+
+ RB_DEBUG_COUNTER_INC(iseq_num);
+ RB_DEBUG_COUNTER_ADD(iseq_cd_num, iseq->body->ci_size);
+
+ rb_iseq_init_trace(iseq);
return Qtrue;
}
@@ -361,7 +715,6 @@ static rb_compile_option_t COMPILE_OPTION_DEFAULT = {
OPT_OPERANDS_UNIFICATION, /* int operands_unification; */
OPT_INSTRUCTIONS_UNIFICATION, /* int instructions_unification; */
OPT_STACK_CACHING, /* int stack_caching; */
- OPT_TRACE_INSTRUCTION, /* int trace_instruction */
OPT_FROZEN_STRING_LITERAL,
OPT_DEBUG_FROZEN_STRING_LITERAL,
TRUE, /* coverage_enabled */
@@ -388,7 +741,6 @@ set_compile_option_from_hash(rb_compile_option_t *option, VALUE opt)
SET_COMPILE_OPTION(option, opt, operands_unification);
SET_COMPILE_OPTION(option, opt, instructions_unification);
SET_COMPILE_OPTION(option, opt, stack_caching);
- SET_COMPILE_OPTION(option, opt, trace_instruction);
SET_COMPILE_OPTION(option, opt, frozen_string_literal);
SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
SET_COMPILE_OPTION(option, opt, coverage_enabled);
@@ -397,7 +749,7 @@ set_compile_option_from_hash(rb_compile_option_t *option, VALUE opt)
#undef SET_COMPILE_OPTION_NUM
}
-void
+static void
rb_iseq_make_compile_option(rb_compile_option_t *option, VALUE opt)
{
Check_Type(opt, T_HASH);
@@ -430,7 +782,7 @@ make_compile_option(rb_compile_option_t *option, VALUE opt)
static VALUE
make_compile_option_value(rb_compile_option_t *option)
{
- VALUE opt = rb_hash_new();
+ VALUE opt = rb_hash_new_with_size(11);
#define SET_COMPILE_OPTION(o, h, mem) \
rb_hash_aset((h), ID2SYM(rb_intern(#mem)), (o)->mem ? Qtrue : Qfalse)
#define SET_COMPILE_OPTION_NUM(o, h, mem) \
@@ -443,7 +795,6 @@ make_compile_option_value(rb_compile_option_t *option)
SET_COMPILE_OPTION(option, opt, operands_unification);
SET_COMPILE_OPTION(option, opt, instructions_unification);
SET_COMPILE_OPTION(option, opt, stack_caching);
- SET_COMPILE_OPTION(option, opt, trace_instruction);
SET_COMPILE_OPTION(option, opt, frozen_string_literal);
SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
SET_COMPILE_OPTION(option, opt, coverage_enabled);
@@ -455,26 +806,42 @@ make_compile_option_value(rb_compile_option_t *option)
}
rb_iseq_t *
-rb_iseq_new(NODE *node, VALUE name, VALUE path, VALUE realpath,
+rb_iseq_new(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath,
const rb_iseq_t *parent, enum iseq_type type)
{
- return rb_iseq_new_with_opt(node, name, path, realpath, INT2FIX(0), parent, type,
- &COMPILE_OPTION_DEFAULT);
+ return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent,
+ 0, type, &COMPILE_OPTION_DEFAULT);
}
rb_iseq_t *
-rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
-{
- return rb_iseq_new_with_opt(node, name, path, realpath, INT2FIX(0), parent, ISEQ_TYPE_TOP,
- &COMPILE_OPTION_DEFAULT);
+rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
+{
+ VALUE coverages = rb_get_coverages();
+ if (RTEST(coverages)) {
+ if (ast->line_count >= 0) {
+ int len = (rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES) ? 0 : ast->line_count;
+ VALUE coverage = rb_default_coverage(len);
+ rb_hash_aset(coverages, path, coverage);
+ }
+ }
+
+ return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, 0,
+ ISEQ_TYPE_TOP, &COMPILE_OPTION_DEFAULT);
}
rb_iseq_t *
-rb_iseq_new_main(NODE *node, VALUE path, VALUE realpath, const rb_iseq_t *parent)
+rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent)
{
- return rb_iseq_new_with_opt(node, rb_fstring_cstr("<main>"),
+ return rb_iseq_new_with_opt(ast, rb_fstring_lit("<main>"),
path, realpath, INT2FIX(0),
- parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
+ parent, 0, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
+}
+
+rb_iseq_t *
+rb_iseq_new_eval(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth)
+{
+ return rb_iseq_new_with_opt(ast, name, path, realpath, first_lineno,
+ parent, isolated_depth, ISEQ_TYPE_EVAL, &COMPILE_OPTION_DEFAULT);
}
static inline rb_iseq_t *
@@ -492,22 +859,50 @@ iseq_translate(rb_iseq_t *iseq)
}
rb_iseq_t *
-rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE path, VALUE realpath,
- VALUE first_lineno, const rb_iseq_t *parent,
- enum iseq_type type, const rb_compile_option_t *option)
+rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath,
+ VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth,
+ enum iseq_type type, const rb_compile_option_t *option)
{
+ const NODE *node = ast ? ast->root : 0;
/* TODO: argument check */
rb_iseq_t *iseq = iseq_alloc();
+ rb_compile_option_t new_opt;
- if (!option) option = &COMPILE_OPTION_DEFAULT;
- prepare_iseq_build(iseq, name, path, realpath, first_lineno, parent, type, option);
+ if (option) {
+ new_opt = *option;
+ }
+ else {
+ new_opt = COMPILE_OPTION_DEFAULT;
+ }
+ if (ast && ast->compile_option) rb_iseq_make_compile_option(&new_opt, ast->compile_option);
+
+ prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, node ? nd_node_id(node) : -1, parent, isolated_depth, type, &new_opt);
rb_iseq_compile_node(iseq, node);
- cleanup_iseq_build(iseq);
+ finish_iseq_build(iseq);
return iseq_translate(iseq);
}
+rb_iseq_t *
+rb_iseq_new_with_callback(
+ const struct rb_iseq_new_with_callback_callback_func * ifunc,
+ VALUE name, VALUE path, VALUE realpath,
+ VALUE first_lineno, const rb_iseq_t *parent,
+ enum iseq_type type, const rb_compile_option_t *option)
+{
+ /* TODO: argument check */
+ rb_iseq_t *iseq = iseq_alloc();
+
+ if (!option) option = &COMPILE_OPTION_DEFAULT;
+ prepare_iseq_build(iseq, name, path, realpath, first_lineno, NULL, -1, parent, 0, type, option);
+
+ rb_iseq_compile_callback(iseq, ifunc);
+ finish_iseq_build(iseq);
+
+ return iseq;
+}
+
const rb_iseq_t *
rb_iseq_load_iseq(VALUE fname)
{
@@ -520,10 +915,10 @@ rb_iseq_load_iseq(VALUE fname)
return NULL;
}
-#define CHECK_ARRAY(v) rb_convert_type_with_id((v), T_ARRAY, "Array", idTo_ary)
-#define CHECK_HASH(v) rb_convert_type_with_id((v), T_HASH, "Hash", idTo_hash)
-#define CHECK_STRING(v) rb_convert_type_with_id((v), T_STRING, "String", idTo_str)
-#define CHECK_SYMBOL(v) rb_convert_type_with_id((v), T_SYMBOL, "Symbol", idTo_sym)
+#define CHECK_ARRAY(v) rb_to_array_type(v)
+#define CHECK_HASH(v) rb_to_hash_type(v)
+#define CHECK_STRING(v) rb_str_to_str(v)
+#define CHECK_SYMBOL(v) rb_to_symbol_type(v)
static inline VALUE CHECK_INTEGER(VALUE v) {(void)NUM2LONG(v); return v;}
static enum iseq_type
@@ -537,7 +932,7 @@ iseq_type_from_sym(VALUE type)
const ID id_ensure = rb_intern("ensure");
const ID id_eval = rb_intern("eval");
const ID id_main = rb_intern("main");
- const ID id_defined_guard = rb_intern("defined_guard");
+ const ID id_plain = rb_intern("plain");
/* ensure all symbols are static or pinned down before
* conversion */
const ID typeid = rb_check_id(&type);
@@ -549,7 +944,7 @@ iseq_type_from_sym(VALUE type)
if (typeid == id_ensure) return ISEQ_TYPE_ENSURE;
if (typeid == id_eval) return ISEQ_TYPE_EVAL;
if (typeid == id_main) return ISEQ_TYPE_MAIN;
- if (typeid == id_defined_guard) return ISEQ_TYPE_DEFINED_GUARD;
+ if (typeid == id_plain) return ISEQ_TYPE_PLAIN;
return (enum iseq_type)-1;
}
@@ -559,12 +954,13 @@ iseq_load(VALUE data, const rb_iseq_t *parent, VALUE opt)
rb_iseq_t *iseq = iseq_alloc();
VALUE magic, version1, version2, format_type, misc;
- VALUE name, path, realpath, first_lineno;
+ VALUE name, path, realpath, first_lineno, code_location, node_id;
VALUE type, body, locals, params, exception;
st_data_t iseq_type;
rb_compile_option_t option;
int i = 0;
+ rb_code_location_t tmp_loc = { {0, 0}, {-1, -1} };
/* [magic, major_version, minor_version, format_type, misc,
* label, path, first_lineno,
@@ -596,17 +992,27 @@ iseq_load(VALUE data, const rb_iseq_t *parent, VALUE opt)
iseq_type = iseq_type_from_sym(type);
if (iseq_type == (enum iseq_type)-1) {
- rb_raise(rb_eTypeError, "unsupport type: :%"PRIsVALUE, rb_sym2str(type));
+ rb_raise(rb_eTypeError, "unsupported type: :%"PRIsVALUE, rb_sym2str(type));
+ }
+
+ node_id = rb_hash_aref(misc, ID2SYM(rb_intern("node_id")));
+
+ code_location = rb_hash_aref(misc, ID2SYM(rb_intern("code_location")));
+ if (RB_TYPE_P(code_location, T_ARRAY) && RARRAY_LEN(code_location) == 4) {
+ tmp_loc.beg_pos.lineno = NUM2INT(rb_ary_entry(code_location, 0));
+ tmp_loc.beg_pos.column = NUM2INT(rb_ary_entry(code_location, 1));
+ tmp_loc.end_pos.lineno = NUM2INT(rb_ary_entry(code_location, 2));
+ tmp_loc.end_pos.column = NUM2INT(rb_ary_entry(code_location, 3));
}
make_compile_option(&option, opt);
option.peephole_optimization = FALSE; /* because peephole optimization can modify original iseq */
- prepare_iseq_build(iseq, name, path, realpath, first_lineno,
- parent, (enum iseq_type)iseq_type, &option);
+ prepare_iseq_build(iseq, name, path, realpath, first_lineno, &tmp_loc, NUM2INT(node_id),
+ parent, 0, (enum iseq_type)iseq_type, &option);
rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body);
- cleanup_iseq_build(iseq);
+ finish_iseq_build(iseq);
return iseqw_new(iseq);
}
@@ -628,22 +1034,19 @@ rb_iseq_load(VALUE data, VALUE parent, VALUE opt)
return iseq_load(data, RTEST(parent) ? (rb_iseq_t *)parent : NULL, opt);
}
-rb_iseq_t *
-rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, const struct rb_block *base_block, VALUE opt)
+static rb_iseq_t *
+rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, VALUE opt)
{
- rb_thread_t *th = GET_THREAD();
rb_iseq_t *iseq = NULL;
- const rb_iseq_t *const parent = base_block ? vm_block_iseq(base_block) : NULL;
rb_compile_option_t option;
- const enum iseq_type type = parent ? ISEQ_TYPE_EVAL : ISEQ_TYPE_TOP;
#if !defined(__GNUC__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 8)
# define INITIALIZED volatile /* suppress warnings by gcc 4.8 */
#else
# define INITIALIZED /* volatile */
#endif
- NODE *(*parse)(VALUE vparser, VALUE fname, VALUE file, int start);
+ rb_ast_t *(*parse)(VALUE vparser, VALUE fname, VALUE file, int start);
int ln;
- NODE *INITIALIZED node;
+ rb_ast_t *INITIALIZED ast;
/* safe results first */
make_compile_option(&option, opt);
@@ -658,36 +1061,28 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, c
}
{
const VALUE parser = rb_parser_new();
- rb_parser_set_context(parser, base_block, FALSE);
- node = (*parse)(parser, file, src, ln);
+ VALUE name = rb_fstring_lit("<compiled>");
+ const rb_iseq_t *outer_scope = rb_iseq_new(NULL, name, name, Qnil, 0, ISEQ_TYPE_TOP);
+ VALUE outer_scope_v = (VALUE)outer_scope;
+ rb_parser_set_context(parser, outer_scope, FALSE);
+ RB_GC_GUARD(outer_scope_v);
+ ast = (*parse)(parser, file, src, ln);
}
- if (!node) {
- rb_exc_raise(th->ec.errinfo);
+ if (!ast->body.root) {
+ rb_ast_dispose(ast);
+ rb_exc_raise(GET_EC()->errinfo);
}
else {
- INITIALIZED VALUE label = parent ?
- parent->body->location.label :
- rb_fstring_cstr("<compiled>");
- iseq = rb_iseq_new_with_opt(node, label, file, realpath, line,
- parent, type, &option);
+ INITIALIZED VALUE label = rb_fstring_lit("<compiled>");
+ iseq = rb_iseq_new_with_opt(&ast->body, label, file, realpath, line,
+ NULL, 0, ISEQ_TYPE_TOP, &option);
+ rb_ast_dispose(ast);
}
return iseq;
}
-rb_iseq_t *
-rb_iseq_compile(VALUE src, VALUE file, VALUE line)
-{
- return rb_iseq_compile_with_option(src, file, Qnil, line, 0, Qnil);
-}
-
-rb_iseq_t *
-rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, const struct rb_block *base_block)
-{
- return rb_iseq_compile_with_option(src, file, Qnil, line, base_block, Qnil);
-}
-
VALUE
rb_iseq_path(const rb_iseq_t *iseq)
{
@@ -727,24 +1122,56 @@ rb_iseq_first_lineno(const rb_iseq_t *iseq)
VALUE
rb_iseq_method_name(const rb_iseq_t *iseq)
{
- const rb_iseq_t *local_iseq;
-
- local_iseq = iseq->body->local_iseq;
+ struct rb_iseq_constant_body *const body = iseq->body->local_iseq->body;
- if (local_iseq->body->type == ISEQ_TYPE_METHOD) {
- return local_iseq->body->location.base_label;
+ if (body->type == ISEQ_TYPE_METHOD) {
+ return body->location.base_label;
}
else {
return Qnil;
}
}
+void
+rb_iseq_code_location(const rb_iseq_t *iseq, int *beg_pos_lineno, int *beg_pos_column, int *end_pos_lineno, int *end_pos_column)
+{
+ const rb_code_location_t *loc = &iseq->body->location.code_location;
+ if (beg_pos_lineno) *beg_pos_lineno = loc->beg_pos.lineno;
+ if (beg_pos_column) *beg_pos_column = loc->beg_pos.column;
+ if (end_pos_lineno) *end_pos_lineno = loc->end_pos.lineno;
+ if (end_pos_column) *end_pos_column = loc->end_pos.column;
+}
+
VALUE
rb_iseq_coverage(const rb_iseq_t *iseq)
{
return ISEQ_COVERAGE(iseq);
}
+static int
+remove_coverage_i(void *vstart, void *vend, size_t stride, void *data)
+{
+ VALUE v = (VALUE)vstart;
+ for (; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
+ if (rb_obj_is_iseq(v)) {
+ rb_iseq_t *iseq = (rb_iseq_t *)v;
+ ISEQ_COVERAGE_SET(iseq, Qnil);
+ }
+
+ asan_poison_object_if(ptr, v);
+ }
+ return 0;
+}
+
+void
+rb_iseq_remove_coverage_all(void)
+{
+ rb_objspace_each_objects(remove_coverage_i, NULL);
+}
+
/* define wrapper class methods (RubyVM::InstructionSequence) */
static void
@@ -756,7 +1183,7 @@ iseqw_mark(void *ptr)
static size_t
iseqw_memsize(const void *ptr)
{
- return iseq_memsize((const rb_iseq_t *)ptr);
+ return rb_iseq_memsize((const rb_iseq_t *)ptr);
}
static const rb_data_type_t iseqw_data_type = {
@@ -768,14 +1195,22 @@ static const rb_data_type_t iseqw_data_type = {
static VALUE
iseqw_new(const rb_iseq_t *iseq)
{
- union { const rb_iseq_t *in; void *out; } deconst;
- VALUE obj;
+ if (iseq->wrapper) {
+ return iseq->wrapper;
+ }
+ else {
+ union { const rb_iseq_t *in; void *out; } deconst;
+ VALUE obj;
+ deconst.in = iseq;
+ obj = TypedData_Wrap_Struct(rb_cISeq, &iseqw_data_type, deconst.out);
+ RB_OBJ_WRITTEN(obj, Qundef, iseq);
- deconst.in = iseq;
- obj = TypedData_Wrap_Struct(rb_cISeq, &iseqw_data_type, deconst.out);
- RB_OBJ_WRITTEN(obj, Qundef, iseq);
+ /* cache a wrapper object */
+ RB_OBJ_WRITE((VALUE)iseq, &iseq->wrapper, obj);
+ RB_OBJ_FREEZE((VALUE)iseq);
- return obj;
+ return obj;
+ }
}
VALUE
@@ -792,10 +1227,14 @@ rb_iseqw_new(const rb_iseq_t *iseq)
* Takes +source+, a String of Ruby code and compiles it to an
* InstructionSequence.
*
- * Optionally takes +file+, +path+, and +line+ which describe the filename,
- * absolute path and first line number of the ruby code in +source+ which are
+ * Optionally takes +file+, +path+, and +line+ which describe the file path,
+ * real path and first line number of the ruby code in +source+ which are
* metadata attached to the returned +iseq+.
*
+ * +file+ is used for `__FILE__` and exception backtrace. +path+ is used for
+ * +require_relative+ base. It is recommended these should be the same full
+ * path.
+ *
* +options+, which can be +true+, +false+ or a +Hash+, is used to
* modify the default behavior of the Ruby iseq compiler.
*
@@ -804,6 +1243,14 @@ rb_iseqw_new(const rb_iseq_t *iseq)
* RubyVM::InstructionSequence.compile("a = 1 + 2")
* #=> <RubyVM::InstructionSequence:<compiled>@<compiled>>
*
+ * path = "test.rb"
+ * RubyVM::InstructionSequence.compile(File.read(path), path, File.expand_path(path))
+ * #=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>
+ *
+ * path = File.expand_path("test.rb")
+ * RubyVM::InstructionSequence.compile(File.read(path), path, path)
+ * #=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
+ *
*/
static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
@@ -811,8 +1258,6 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self)
VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;
int i;
- rb_secure(1);
-
i = rb_scan_args(argc, argv, "1*:", &src, NULL, &opt);
if (i > 4+NIL_P(opt)) rb_error_arity(argc, 1, 5);
switch (i) {
@@ -821,10 +1266,15 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self)
case 3: path = argv[--i];
case 2: file = argv[--i];
}
- if (NIL_P(file)) file = rb_fstring_cstr("<compiled>");
+
+ if (NIL_P(file)) file = rb_fstring_lit("<compiled>");
+ if (NIL_P(path)) path = file;
if (NIL_P(line)) line = INT2FIX(1);
- return iseqw_new(rb_iseq_compile_with_option(src, file, path, line, 0, opt));
+ Check_Type(path, T_STRING);
+ Check_Type(file, T_STRING);
+
+ return iseqw_new(rb_iseq_compile_with_option(src, file, path, line, opt));
}
/*
@@ -851,12 +1301,11 @@ static VALUE
iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
{
VALUE file, line = INT2FIX(1), opt = Qnil;
- VALUE parser, f, exc = Qnil;
- NODE *node;
+ VALUE parser, f, exc = Qnil, ret;
+ rb_ast_t *ast;
rb_compile_option_t option;
int i;
- rb_secure(1);
i = rb_scan_args(argc, argv, "1*:", &file, NULL, &opt);
if (i > 1+NIL_P(opt)) rb_error_arity(argc, 1, 2);
switch (i) {
@@ -869,18 +1318,23 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
parser = rb_parser_new();
rb_parser_set_context(parser, NULL, FALSE);
- node = rb_parser_compile_file_path(parser, file, f, NUM2INT(line));
- if (!node) exc = GET_THREAD()->ec.errinfo;
+ ast = (rb_ast_t *)rb_parser_load_file(parser, file);
+ if (!ast->body.root) exc = GET_EC()->errinfo;
rb_io_close(f);
- if (!node) rb_exc_raise(exc);
+ if (!ast->body.root) {
+ rb_ast_dispose(ast);
+ rb_exc_raise(exc);
+ }
make_compile_option(&option, opt);
- return iseqw_new(rb_iseq_new_with_opt(node, rb_fstring_cstr("<main>"),
- file,
- rb_realpath_internal(Qnil, file, 1),
- line, NULL, ISEQ_TYPE_TOP, &option));
+ ret = iseqw_new(rb_iseq_new_with_opt(&ast->body, rb_fstring_lit("<main>"),
+ file,
+ rb_realpath_internal(Qnil, file, 1),
+ line, NULL, 0, ISEQ_TYPE_TOP, &option));
+ rb_ast_dispose(ast);
+ return ret;
}
/*
@@ -907,7 +1361,6 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
* * +:specialized_instruction+
* * +:stack_caching+
* * +:tailcall_optimization+
- * * +:trace_instruction+
*
* Additionally, +:debug_level+ can be set to an integer.
*
@@ -919,7 +1372,6 @@ static VALUE
iseqw_s_compile_option_set(VALUE self, VALUE opt)
{
rb_compile_option_t option;
- rb_secure(1);
make_compile_option(&option, opt);
COMPILE_OPTION_DEFAULT = option;
return opt;
@@ -945,7 +1397,7 @@ iseqw_check(VALUE iseqw)
rb_iseq_t *iseq = DATA_PTR(iseqw);
if (!iseq->body) {
- ibf_load_iseq_complete(iseq);
+ rb_ibf_load_iseq_complete(iseq);
}
if (!iseq->body->location.label) {
@@ -971,7 +1423,6 @@ rb_iseqw_to_iseq(VALUE iseqw)
static VALUE
iseqw_eval(VALUE self)
{
- rb_secure(1);
return rb_iseq_eval(iseqw_check(self));
}
@@ -983,15 +1434,17 @@ static VALUE
iseqw_inspect(VALUE self)
{
const rb_iseq_t *iseq = iseqw_check(self);
+ const struct rb_iseq_constant_body *const body = iseq->body;
VALUE klass = rb_class_name(rb_obj_class(self));
- if (!iseq->body->location.label) {
+ if (!body->location.label) {
return rb_sprintf("#<%"PRIsVALUE": uninitialized>", klass);
}
else {
- return rb_sprintf("<%"PRIsVALUE":%"PRIsVALUE"@%"PRIsVALUE">",
+ return rb_sprintf("<%"PRIsVALUE":%"PRIsVALUE"@%"PRIsVALUE":%d>",
klass,
- iseq->body->location.label, rb_iseq_path(iseq));
+ body->location.label, rb_iseq_path(iseq),
+ FIX2INT(rb_iseq_first_lineno(iseq)));
}
}
@@ -1178,7 +1631,7 @@ static VALUE iseq_data_to_ary(const rb_iseq_t *iseq);
* The type of the instruction sequence.
*
* Valid values are +:top+, +:method+, +:block+, +:class+, +:rescue+,
- * +:ensure+, +:eval+, +:main+, and +:defined_guard+.
+ * +:ensure+, +:eval+, +:main+, and +plain+.
*
* [locals]
* An array containing the names of all arguments and local variables as
@@ -1204,52 +1657,170 @@ static VALUE
iseqw_to_a(VALUE self)
{
const rb_iseq_t *iseq = iseqw_check(self);
- rb_secure(1);
return iseq_data_to_ary(iseq);
}
-/* TODO: search algorithm is brute force.
- this should be binary search or so. */
+#if VM_INSN_INFO_TABLE_IMPL == 1 /* binary search */
+static const struct iseq_insn_info_entry *
+get_insn_info_binary_search(const rb_iseq_t *iseq, size_t pos)
+{
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ size_t size = body->insns_info.size;
+ const struct iseq_insn_info_entry *insns_info = body->insns_info.body;
+ const unsigned int *positions = body->insns_info.positions;
+ const int debug = 0;
-static const struct iseq_line_info_entry *
-get_line_info(const rb_iseq_t *iseq, size_t pos)
+ if (debug) {
+ printf("size: %"PRIuSIZE"\n", size);
+ printf("insns_info[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n",
+ (size_t)0, positions[0], insns_info[0].line_no, pos);
+ }
+
+ if (size == 0) {
+ return NULL;
+ }
+ else if (size == 1) {
+ return &insns_info[0];
+ }
+ else {
+ size_t l = 1, r = size - 1;
+ while (l <= r) {
+ size_t m = l + (r - l) / 2;
+ if (positions[m] == pos) {
+ return &insns_info[m];
+ }
+ if (positions[m] < pos) {
+ l = m + 1;
+ }
+ else {
+ r = m - 1;
+ }
+ }
+ if (l >= size) {
+ return &insns_info[size-1];
+ }
+ if (positions[l] > pos) {
+ return &insns_info[l-1];
+ }
+ return &insns_info[l];
+ }
+}
+
+static const struct iseq_insn_info_entry *
+get_insn_info(const rb_iseq_t *iseq, size_t pos)
{
- size_t i = 0, size = iseq->body->line_info_size;
- const struct iseq_line_info_entry *table = iseq->body->line_info_table;
+ return get_insn_info_binary_search(iseq, pos);
+}
+#endif
+
+#if VM_INSN_INFO_TABLE_IMPL == 2 /* succinct bitvector */
+static const struct iseq_insn_info_entry *
+get_insn_info_succinct_bitvector(const rb_iseq_t *iseq, size_t pos)
+{
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ size_t size = body->insns_info.size;
+ const struct iseq_insn_info_entry *insns_info = body->insns_info.body;
+ const int debug = 0;
+
+ if (debug) {
+#if VM_CHECK_MODE > 0
+ const unsigned int *positions = body->insns_info.positions;
+ printf("size: %"PRIuSIZE"\n", size);
+ printf("insns_info[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n",
+ (size_t)0, positions[0], insns_info[0].line_no, pos);
+#else
+ printf("size: %"PRIuSIZE"\n", size);
+ printf("insns_info[%"PRIuSIZE"]: line: %d, pos: %"PRIuSIZE"\n",
+ (size_t)0, insns_info[0].line_no, pos);
+#endif
+ }
+
+ if (size == 0) {
+ return NULL;
+ }
+ else if (size == 1) {
+ return &insns_info[0];
+ }
+ else {
+ int index;
+ VM_ASSERT(body->insns_info.succ_index_table != NULL);
+ index = succ_index_lookup(body->insns_info.succ_index_table, (int)pos);
+ return &insns_info[index-1];
+ }
+}
+
+static const struct iseq_insn_info_entry *
+get_insn_info(const rb_iseq_t *iseq, size_t pos)
+{
+ return get_insn_info_succinct_bitvector(iseq, pos);
+}
+#endif
+
+#if VM_CHECK_MODE > 0 || VM_INSN_INFO_TABLE_IMPL == 0
+static const struct iseq_insn_info_entry *
+get_insn_info_linear_search(const rb_iseq_t *iseq, size_t pos)
+{
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ size_t i = 0, size = body->insns_info.size;
+ const struct iseq_insn_info_entry *insns_info = body->insns_info.body;
+ const unsigned int *positions = body->insns_info.positions;
const int debug = 0;
if (debug) {
printf("size: %"PRIuSIZE"\n", size);
- printf("table[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n",
- i, table[i].position, table[i].line_no, pos);
+ printf("insns_info[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n",
+ i, positions[i], insns_info[i].line_no, pos);
}
if (size == 0) {
- return 0;
+ return NULL;
}
else if (size == 1) {
- return &table[0];
+ return &insns_info[0];
}
else {
for (i=1; i<size; i++) {
- if (debug) printf("table[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n",
- i, table[i].position, table[i].line_no, pos);
+ if (debug) printf("insns_info[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n",
+ i, positions[i], insns_info[i].line_no, pos);
- if (table[i].position == pos) {
- return &table[i];
+ if (positions[i] == pos) {
+ return &insns_info[i];
}
- if (table[i].position > pos) {
- return &table[i-1];
+ if (positions[i] > pos) {
+ return &insns_info[i-1];
}
}
}
- return &table[i-1];
+ return &insns_info[i-1];
}
+#endif
-static unsigned int
-find_line_no(const rb_iseq_t *iseq, size_t pos)
+#if VM_INSN_INFO_TABLE_IMPL == 0 /* linear search */
+static const struct iseq_insn_info_entry *
+get_insn_info(const rb_iseq_t *iseq, size_t pos)
{
- const struct iseq_line_info_entry *entry = get_line_info(iseq, pos);
+ return get_insn_info_linear_search(iseq, pos);
+}
+#endif
+
+#if VM_CHECK_MODE > 0 && VM_INSN_INFO_TABLE_IMPL > 0
+static void
+validate_get_insn_info(const rb_iseq_t *iseq)
+{
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ size_t i;
+ for (i = 0; i < body->iseq_size; i++) {
+ if (get_insn_info_linear_search(iseq, i) != get_insn_info(iseq, i)) {
+ rb_bug("validate_get_insn_info: get_insn_info_linear_search(iseq, %"PRIuSIZE") != get_insn_info(iseq, %"PRIuSIZE")", i, i);
+ }
+ }
+}
+#endif
+
+unsigned int
+rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos)
+{
+ const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pos);
if (entry) {
return entry->line_no;
@@ -1259,30 +1830,61 @@ find_line_no(const rb_iseq_t *iseq, size_t pos)
}
}
-unsigned int
-rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos)
+MJIT_FUNC_EXPORTED rb_event_flag_t
+rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos)
{
- if (pos == 0) {
- return find_line_no(iseq, pos);
+ const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pos);
+ if (entry) {
+ return entry->events;
}
else {
- return find_line_no(iseq, pos - 1);
+ return 0;
+ }
+}
+
+void
+rb_iseq_clear_event_flags(const rb_iseq_t *iseq, size_t pos, rb_event_flag_t reset)
+{
+ struct iseq_insn_info_entry *entry = (struct iseq_insn_info_entry *)get_insn_info(iseq, pos);
+ if (entry) {
+ entry->events &= ~reset;
+ if (!(entry->events & iseq->aux.exec.global_trace_events)) {
+ void rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, size_t pos);
+ rb_iseq_trace_flag_cleared(iseq, pos);
+ }
}
}
static VALUE
-id_to_name(ID id, VALUE default_value)
+local_var_name(const rb_iseq_t *diseq, VALUE level, VALUE op)
{
- VALUE str = rb_id2str(id);
- if (!str) {
- str = default_value;
+ VALUE i;
+ VALUE name;
+ ID lid;
+ int idx;
+
+ for (i = 0; i < level; i++) {
+ diseq = diseq->body->parent_iseq;
}
- else if (!rb_str_symname_p(str)) {
- str = rb_str_inspect(str);
+ idx = diseq->body->local_table_size - (int)op - 1;
+ lid = diseq->body->local_table[idx];
+ name = rb_id2str(lid);
+ if (!name) {
+ name = rb_str_new_cstr("?");
}
- return str;
+ else if (!rb_str_symname_p(name)) {
+ name = rb_str_inspect(name);
+ }
+ else {
+ name = rb_str_dup(name);
+ }
+ rb_str_catf(name, "@%d", idx);
+ return name;
}
+int rb_insn_unified_local_var_level(VALUE);
+VALUE rb_dump_literal(VALUE lit);
+
VALUE
rb_insn_operand_intern(const rb_iseq_t *iseq,
VALUE insn, int op_no, VALUE op,
@@ -1298,26 +1900,40 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
break;
case TS_NUM: /* ULONG */
+ if (insn == BIN(defined) && op_no == 0) {
+ enum defined_type deftype = (enum defined_type)op;
+ switch (deftype) {
+ case DEFINED_FUNC:
+ ret = rb_fstring_lit("func");
+ break;
+ case DEFINED_REF:
+ ret = rb_fstring_lit("ref");
+ break;
+ case DEFINED_CONST_FROM:
+ ret = rb_fstring_lit("constant-from");
+ break;
+ default:
+ ret = rb_iseq_defined_string(deftype);
+ break;
+ }
+ if (ret) break;
+ }
+ else if (insn == BIN(checktype) && op_no == 0) {
+ const char *type_str = rb_type_str((enum ruby_value_type)op);
+ if (type_str) {
+ ret = rb_str_new_cstr(type_str); break;
+ }
+ }
ret = rb_sprintf("%"PRIuVALUE, op);
break;
case TS_LINDEX:{
- if (insn == BIN(getlocal) || insn == BIN(setlocal)) {
- if (pnop) {
- const rb_iseq_t *diseq = iseq;
- VALUE level = *pnop, i;
- ID lid;
-
- for (i = 0; i < level; i++) {
- diseq = diseq->body->parent_iseq;
- }
- lid = diseq->body->local_table[diseq->body->local_table_size +
- VM_ENV_DATA_SIZE - 1 - op];
- ret = id_to_name(lid, INT2FIX('*'));
- }
- else {
- ret = rb_sprintf("%"PRIuVALUE, op);
- }
+ int level;
+ if (types[op_no+1] == TS_NUM && pnop) {
+ ret = local_var_name(iseq, *pnop, op - VM_ENV_DATA_SIZE);
+ }
+ else if ((level = rb_insn_unified_local_var_level(insn)) >= 0) {
+ ret = local_var_name(iseq, (VALUE)level, op - VM_ENV_DATA_SIZE);
}
else {
ret = rb_inspect(INT2FIX(op));
@@ -1325,11 +1941,25 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
break;
}
case TS_ID: /* ID (symbol) */
- op = ID2SYM(op);
+ ret = rb_inspect(ID2SYM(op));
+ break;
case TS_VALUE: /* VALUE */
op = obj_resurrect(op);
- ret = rb_inspect(op);
+ if (insn == BIN(defined) && op_no == 1 && FIXNUM_P(op)) {
+ /* should be DEFINED_REF */
+ int type = NUM2INT(op);
+ if (type) {
+ if (type & 1) {
+ ret = rb_sprintf(":$%c", (type >> 1));
+ }
+ else {
+ ret = rb_sprintf(":$%d", (type >> 1));
+ }
+ break;
+ }
+ }
+ ret = rb_dump_literal(op);
if (CLASS_OF(op) == rb_cISeq) {
if (child) {
rb_ary_push(child, op);
@@ -1351,53 +1981,53 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
}
break;
}
- case TS_GENTRY:
- {
- struct rb_global_entry *entry = (struct rb_global_entry *)op;
- ret = rb_str_dup(rb_id2str(entry->id));
- }
- break;
case TS_IC:
+ case TS_IVC:
+ case TS_ISE:
ret = rb_sprintf("<is:%"PRIdPTRDIFF">", (union iseq_inline_storage_entry *)op - iseq->body->is_entries);
break;
- case TS_CALLINFO:
+ case TS_CALLDATA:
{
- struct rb_call_info *ci = (struct rb_call_info *)op;
+ struct rb_call_data *cd = (struct rb_call_data *)op;
+ const struct rb_callinfo *ci = cd->ci;
VALUE ary = rb_ary_new();
+ ID mid = vm_ci_mid(ci);
- if (ci->mid) {
- rb_ary_push(ary, rb_sprintf("mid:%"PRIsVALUE, rb_id2str(ci->mid)));
+ if (mid) {
+ rb_ary_push(ary, rb_sprintf("mid:%"PRIsVALUE, rb_id2str(mid)));
}
- rb_ary_push(ary, rb_sprintf("argc:%d", ci->orig_argc));
+ rb_ary_push(ary, rb_sprintf("argc:%d", vm_ci_argc(ci)));
- if (ci->flag & VM_CALL_KWARG) {
- struct rb_call_info_kw_arg *kw_args = ((struct rb_call_info_with_kwarg *)ci)->kw_arg;
- VALUE kw_ary = rb_ary_new_from_values(kw_args->keyword_len, kw_args->keywords);
- rb_ary_push(ary, rb_sprintf("kw:[%"PRIsVALUE"]", rb_ary_join(kw_ary, rb_str_new2(","))));
+ if (vm_ci_flag(ci) & VM_CALL_KWARG) {
+ const struct rb_callinfo_kwarg *kw_args = vm_ci_kwarg(ci);
+ VALUE kw_ary = rb_ary_new_from_values(kw_args->keyword_len, kw_args->keywords);
+ rb_ary_push(ary, rb_sprintf("kw:[%"PRIsVALUE"]", rb_ary_join(kw_ary, rb_str_new2(","))));
}
- if (ci->flag) {
+ if (vm_ci_flag(ci)) {
VALUE flags = rb_ary_new();
- if (ci->flag & VM_CALL_ARGS_SPLAT) rb_ary_push(flags, rb_str_new2("ARGS_SPLAT"));
- if (ci->flag & VM_CALL_ARGS_BLOCKARG) rb_ary_push(flags, rb_str_new2("ARGS_BLOCKARG"));
- if (ci->flag & VM_CALL_FCALL) rb_ary_push(flags, rb_str_new2("FCALL"));
- if (ci->flag & VM_CALL_VCALL) rb_ary_push(flags, rb_str_new2("VCALL"));
- if (ci->flag & VM_CALL_TAILCALL) rb_ary_push(flags, rb_str_new2("TAILCALL"));
- if (ci->flag & VM_CALL_SUPER) rb_ary_push(flags, rb_str_new2("SUPER"));
- if (ci->flag & VM_CALL_KWARG) rb_ary_push(flags, rb_str_new2("KWARG"));
- if (ci->flag & VM_CALL_OPT_SEND) rb_ary_push(flags, rb_str_new2("SNED")); /* maybe not reachable */
- if (ci->flag & VM_CALL_ARGS_SIMPLE) rb_ary_push(flags, rb_str_new2("ARGS_SIMPLE")); /* maybe not reachable */
+# define CALL_FLAG(n) if (vm_ci_flag(ci) & VM_CALL_##n) rb_ary_push(flags, rb_str_new2(#n))
+ CALL_FLAG(ARGS_SPLAT);
+ CALL_FLAG(ARGS_BLOCKARG);
+ CALL_FLAG(FCALL);
+ CALL_FLAG(VCALL);
+ CALL_FLAG(ARGS_SIMPLE);
+ CALL_FLAG(BLOCKISEQ);
+ CALL_FLAG(TAILCALL);
+ CALL_FLAG(SUPER);
+ CALL_FLAG(ZSUPER);
+ CALL_FLAG(KWARG);
+ CALL_FLAG(KW_SPLAT);
+ CALL_FLAG(KW_SPLAT_MUT);
+ CALL_FLAG(OPT_SEND); /* maybe not reachable */
rb_ary_push(ary, rb_ary_join(flags, rb_str_new2("|")));
}
- ret = rb_sprintf("<callinfo!%"PRIsVALUE">", rb_ary_join(ary, rb_str_new2(", ")));
- }
- break;
- case TS_CALLCACHE:
- ret = rb_str_new2("<callcache>");
+ ret = rb_sprintf("<calldata!%"PRIsVALUE">", rb_ary_join(ary, rb_str_new2(", ")));
+ }
break;
case TS_CDHASH:
@@ -1417,12 +2047,29 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
}
break;
+ case TS_BUILTIN:
+ {
+ const struct rb_builtin_function *bf = (const struct rb_builtin_function *)op;
+ ret = rb_sprintf("<builtin!%s/%d>",
+ bf->name, bf->argc);
+ }
+ break;
+
default:
- rb_bug("insn_operand_intern: unknown operand type: %c", type);
+ rb_bug("unknown operand type: %c", type);
}
return ret;
}
+static VALUE
+right_strip(VALUE str)
+{
+ const char *beg = RSTRING_PTR(str), *end = RSTRING_END(str);
+ while (end-- > beg && *end == ' ');
+ rb_str_set_len(str, end - beg + 1);
+ return str;
+}
+
/**
* Disassemble a instruction
* Iseq -> Iseq inspect object
@@ -1440,10 +2087,11 @@ rb_iseq_disasm_insn(VALUE ret, const VALUE *code, size_t pos,
insn_name_buff = insn_name(insn);
if (1) {
- rb_str_catf(str, "%04"PRIuSIZE" %-16s ", pos, insn_name_buff);
+ extern const int rb_vm_max_insn_name_size;
+ rb_str_catf(str, "%04"PRIuSIZE" %-*s ", pos, rb_vm_max_insn_name_size, insn_name_buff);
}
else {
- rb_str_catf(str, "%04"PRIuSIZE" %-16.*s ", pos,
+ rb_str_catf(str, "%04"PRIuSIZE" %-28.*s ", pos,
(int)strcspn(insn_name_buff, "_"), insn_name_buff);
}
@@ -1459,8 +2107,8 @@ rb_iseq_disasm_insn(VALUE ret, const VALUE *code, size_t pos,
}
{
- unsigned int line_no = find_line_no(iseq, pos);
- unsigned int prev = pos == 0 ? 0 : find_line_no(iseq, pos - 1);
+ unsigned int line_no = rb_iseq_line_no(iseq, pos);
+ unsigned int prev = pos == 0 ? 0 : rb_iseq_line_no(iseq, pos - 1);
if (line_no && line_no != prev) {
long slen = RSTRING_LEN(str);
slen = (slen > 70) ? 0 : (70 - slen);
@@ -1468,12 +2116,31 @@ rb_iseq_disasm_insn(VALUE ret, const VALUE *code, size_t pos,
}
}
+ {
+ rb_event_flag_t events = rb_iseq_event_flags(iseq, pos);
+ if (events) {
+ str = rb_str_catf(str, "[%s%s%s%s%s%s%s%s%s%s%s]",
+ events & RUBY_EVENT_LINE ? "Li" : "",
+ events & RUBY_EVENT_CLASS ? "Cl" : "",
+ events & RUBY_EVENT_END ? "En" : "",
+ events & RUBY_EVENT_CALL ? "Ca" : "",
+ events & RUBY_EVENT_RETURN ? "Re" : "",
+ events & RUBY_EVENT_C_CALL ? "Cc" : "",
+ events & RUBY_EVENT_C_RETURN ? "Cr" : "",
+ events & RUBY_EVENT_B_CALL ? "Bc" : "",
+ events & RUBY_EVENT_B_RETURN ? "Br" : "",
+ events & RUBY_EVENT_COVERAGE_LINE ? "Cli" : "",
+ events & RUBY_EVENT_COVERAGE_BRANCH ? "Cbr" : "");
+ }
+ }
+
+ right_strip(str);
if (ret) {
rb_str_cat2(str, "\n");
rb_str_concat(ret, str);
}
else {
- printf("%s\n", RSTRING_PTR(str));
+ printf("%.*s\n", (int)RSTRING_LEN(str), RSTRING_PTR(str));
}
return len;
}
@@ -1495,7 +2162,7 @@ catch_type(int type)
case CATCH_TYPE_NEXT:
return "next";
default:
- rb_bug("unknown catch type (%d)", type);
+ rb_bug("unknown catch type: %d", type);
return 0;
}
}
@@ -1503,127 +2170,175 @@ catch_type(int type)
static VALUE
iseq_inspect(const rb_iseq_t *iseq)
{
- if (!iseq->body->location.label) {
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ if (!body->location.label) {
return rb_sprintf("#<ISeq: uninitialized>");
}
else {
- return rb_sprintf("#<ISeq:%s@%s>", RSTRING_PTR(iseq->body->location.label), RSTRING_PTR(rb_iseq_path(iseq)));
+ const rb_code_location_t *loc = &body->location.code_location;
+ return rb_sprintf("#<ISeq:%"PRIsVALUE"@%"PRIsVALUE":%d (%d,%d)-(%d,%d)>",
+ body->location.label, rb_iseq_path(iseq),
+ loc->beg_pos.lineno,
+ loc->beg_pos.lineno,
+ loc->beg_pos.column,
+ loc->end_pos.lineno,
+ loc->end_pos.column);
}
}
-VALUE
-rb_iseq_disasm(const rb_iseq_t *iseq)
+static const rb_data_type_t tmp_set = {
+ "tmpset",
+ {(void (*)(void *))rb_mark_set, (void (*)(void *))st_free_table, 0, 0,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static VALUE
+rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent)
{
+ const struct rb_iseq_constant_body *const body = iseq->body;
VALUE *code;
VALUE str = rb_str_new(0, 0);
VALUE child = rb_ary_tmp_new(3);
unsigned int size;
unsigned int i;
long l;
- const ID *tbl;
size_t n;
enum {header_minlen = 72};
+ st_table *done_iseq = 0;
+ VALUE done_iseq_wrapper = Qnil;
+ const char *indent_str;
+ long indent_len;
- rb_secure(1);
+ size = body->iseq_size;
- size = iseq->body->iseq_size;
+ indent_len = RSTRING_LEN(indent);
+ indent_str = RSTRING_PTR(indent);
+ rb_str_cat(str, indent_str, indent_len);
rb_str_cat2(str, "== disasm: ");
- rb_str_concat(str, iseq_inspect(iseq));
- if ((l = RSTRING_LEN(str)) < header_minlen) {
- rb_str_resize(str, header_minlen);
- memset(RSTRING_PTR(str) + l, '=', header_minlen - l);
+ rb_str_append(str, iseq_inspect(iseq));
+ rb_str_catf(str, " (catch: %s)", body->catch_except_p ? "TRUE" : "FALSE");
+ if ((l = RSTRING_LEN(str) - indent_len) < header_minlen) {
+ rb_str_modify_expand(str, header_minlen - l);
+ memset(RSTRING_END(str), '=', header_minlen - l);
}
rb_str_cat2(str, "\n");
/* show catch table information */
- if (iseq->body->catch_table) {
+ if (body->catch_table) {
+ rb_str_cat(str, indent_str, indent_len);
rb_str_cat2(str, "== catch table\n");
}
- if (iseq->body->catch_table) {
- for (i = 0; i < iseq->body->catch_table->size; i++) {
- const struct iseq_catch_table_entry *entry = &iseq->body->catch_table->entries[i];
+ if (body->catch_table) {
+ rb_str_cat_cstr(indent, "| ");
+ indent_str = RSTRING_PTR(indent);
+ for (i = 0; i < body->catch_table->size; i++) {
+ const struct iseq_catch_table_entry *entry =
+ UNALIGNED_MEMBER_PTR(body->catch_table, entries[i]);
+ rb_str_cat(str, indent_str, indent_len);
rb_str_catf(str,
"| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n",
catch_type((int)entry->type), (int)entry->start,
(int)entry->end, (int)entry->sp, (int)entry->cont);
- if (entry->iseq) {
- rb_str_concat(str, rb_iseq_disasm(rb_iseq_check(entry->iseq)));
+ if (entry->iseq && !(done_iseq && st_is_member(done_iseq, (st_data_t)entry->iseq))) {
+ rb_str_concat(str, rb_iseq_disasm_recursive(rb_iseq_check(entry->iseq), indent));
+ if (!done_iseq) {
+ done_iseq = st_init_numtable();
+ done_iseq_wrapper = TypedData_Wrap_Struct(0, &tmp_set, done_iseq);
+ }
+ st_insert(done_iseq, (st_data_t)entry->iseq, (st_data_t)0);
+ indent_str = RSTRING_PTR(indent);
}
}
+ rb_str_resize(indent, indent_len);
+ indent_str = RSTRING_PTR(indent);
}
- if (iseq->body->catch_table) {
+ if (body->catch_table) {
+ rb_str_cat(str, indent_str, indent_len);
rb_str_cat2(str, "|-------------------------------------"
"-----------------------------------\n");
}
/* show local table information */
- tbl = iseq->body->local_table;
-
- if (tbl) {
+ if (body->local_table) {
+ const struct rb_iseq_param_keyword *const keyword = body->param.keyword;
+ rb_str_cat(str, indent_str, indent_len);
rb_str_catf(str,
"local table (size: %d, argc: %d "
"[opts: %d, rest: %d, post: %d, block: %d, kw: %d@%d, kwrest: %d])\n",
- iseq->body->local_table_size,
- iseq->body->param.lead_num,
- iseq->body->param.opt_num,
- iseq->body->param.flags.has_rest ? iseq->body->param.rest_start : -1,
- iseq->body->param.post_num,
- iseq->body->param.flags.has_block ? iseq->body->param.block_start : -1,
- iseq->body->param.flags.has_kw ? iseq->body->param.keyword->num : -1,
- iseq->body->param.flags.has_kw ? iseq->body->param.keyword->required_num : -1,
- iseq->body->param.flags.has_kwrest ? iseq->body->param.keyword->rest_start : -1);
-
- for (i = 0; i < iseq->body->local_table_size; i++) {
- int li = (int)i;
+ body->local_table_size,
+ body->param.lead_num,
+ body->param.opt_num,
+ body->param.flags.has_rest ? body->param.rest_start : -1,
+ body->param.post_num,
+ body->param.flags.has_block ? body->param.block_start : -1,
+ body->param.flags.has_kw ? keyword->num : -1,
+ body->param.flags.has_kw ? keyword->required_num : -1,
+ body->param.flags.has_kwrest ? keyword->rest_start : -1);
+
+ for (i = body->local_table_size; i > 0;) {
+ int li = body->local_table_size - --i - 1;
long width;
- VALUE name = id_to_name(tbl[i], 0);
- char argi[0x100] = "";
- char opti[0x100] = "";
-
- if (iseq->body->param.flags.has_opt) {
- int argc = iseq->body->param.lead_num;
- int opts = iseq->body->param.opt_num;
+ VALUE name = local_var_name(iseq, 0, i);
+ char argi[0x100];
+ char opti[0x100];
+
+ opti[0] = '\0';
+ if (body->param.flags.has_opt) {
+ int argc = body->param.lead_num;
+ int opts = body->param.opt_num;
if (li >= argc && li < argc + opts) {
snprintf(opti, sizeof(opti), "Opt=%"PRIdVALUE,
- iseq->body->param.opt_table[li - argc]);
+ body->param.opt_table[li - argc]);
}
}
- snprintf(argi, sizeof(argi), "%s%s%s%s%s", /* arg, opts, rest, post block */
- iseq->body->param.lead_num > li ? "Arg" : "",
+ snprintf(argi, sizeof(argi), "%s%s%s%s%s%s", /* arg, opts, rest, post, kwrest, block */
+ body->param.lead_num > li ? "Arg" : "",
opti,
- (iseq->body->param.flags.has_rest && iseq->body->param.rest_start == li) ? "Rest" : "",
- (iseq->body->param.flags.has_post && iseq->body->param.post_start <= li && li < iseq->body->param.post_start + iseq->body->param.post_num) ? "Post" : "",
- (iseq->body->param.flags.has_block && iseq->body->param.block_start == li) ? "Block" : "");
+ (body->param.flags.has_rest && body->param.rest_start == li) ? "Rest" : "",
+ (body->param.flags.has_post && body->param.post_start <= li && li < body->param.post_start + body->param.post_num) ? "Post" : "",
+ (body->param.flags.has_kwrest && keyword->rest_start == li) ? "Kwrest" : "",
+ (body->param.flags.has_block && body->param.block_start == li) ? "Block" : "");
- rb_str_catf(str, "[%2d] ", iseq->body->local_table_size - i);
+ rb_str_cat(str, indent_str, indent_len);
+ rb_str_catf(str, "[%2d] ", i + 1);
width = RSTRING_LEN(str) + 11;
- if (name)
- rb_str_append(str, name);
- else
- rb_str_cat2(str, "?");
+ rb_str_append(str, name);
if (*argi) rb_str_catf(str, "<%s>", argi);
if ((width -= RSTRING_LEN(str)) > 0) rb_str_catf(str, "%*s", (int)width, "");
}
- rb_str_cat2(str, "\n");
+ rb_str_cat_cstr(right_strip(str), "\n");
}
/* show each line */
code = rb_iseq_original_iseq(iseq);
for (n = 0; n < size;) {
+ rb_str_cat(str, indent_str, indent_len);
n += rb_iseq_disasm_insn(str, code, n, iseq, child);
}
for (l = 0; l < RARRAY_LEN(child); l++) {
VALUE isv = rb_ary_entry(child, l);
- rb_str_concat(str, rb_iseq_disasm(rb_iseq_check((rb_iseq_t *)isv)));
+ if (done_iseq && st_is_member(done_iseq, (st_data_t)isv)) continue;
+ rb_str_cat_cstr(str, "\n");
+ rb_str_concat(str, rb_iseq_disasm_recursive(rb_iseq_check((rb_iseq_t *)isv), indent));
+ indent_str = RSTRING_PTR(indent);
}
+ RB_GC_GUARD(done_iseq_wrapper);
return str;
}
+VALUE
+rb_iseq_disasm(const rb_iseq_t *iseq)
+{
+ VALUE str = rb_iseq_disasm_recursive(iseq, rb_str_new(0, 0));
+ rb_str_resize(str, RSTRING_LEN(str));
+ return str;
+}
+
/*
* call-seq:
* iseq.disasm -> str
@@ -1648,6 +2363,116 @@ iseqw_disasm(VALUE self)
return rb_iseq_disasm(iseqw_check(self));
}
+static int
+iseq_iterate_children(const rb_iseq_t *iseq, void (*iter_func)(const rb_iseq_t *child_iseq, void *data), void *data)
+{
+ unsigned int i;
+ VALUE *code = rb_iseq_original_iseq(iseq);
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ const rb_iseq_t *child;
+ VALUE all_children = rb_obj_hide(rb_ident_hash_new());
+
+ if (body->catch_table) {
+ for (i = 0; i < body->catch_table->size; i++) {
+ const struct iseq_catch_table_entry *entry =
+ UNALIGNED_MEMBER_PTR(body->catch_table, entries[i]);
+ child = entry->iseq;
+ if (child) {
+ if (rb_hash_aref(all_children, (VALUE)child) == Qnil) {
+ rb_hash_aset(all_children, (VALUE)child, Qtrue);
+ (*iter_func)(child, data);
+ }
+ }
+ }
+ }
+
+ for (i=0; i<body->iseq_size;) {
+ VALUE insn = code[i];
+ int len = insn_len(insn);
+ const char *types = insn_op_types(insn);
+ int j;
+
+ for (j=0; types[j]; j++) {
+ switch (types[j]) {
+ case TS_ISEQ:
+ child = (const rb_iseq_t *)code[i+j+1];
+ if (child) {
+ if (rb_hash_aref(all_children, (VALUE)child) == Qnil) {
+ rb_hash_aset(all_children, (VALUE)child, Qtrue);
+ (*iter_func)(child, data);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ i += len;
+ }
+
+ return (int)RHASH_SIZE(all_children);
+}
+
+static void
+yield_each_children(const rb_iseq_t *child_iseq, void *data)
+{
+ rb_yield(iseqw_new(child_iseq));
+}
+
+/*
+ * call-seq:
+ * iseq.each_child{|child_iseq| ...} -> iseq
+ *
+ * Iterate all direct child instruction sequences.
+ * Iteration order is implementation/version defined
+ * so that people should not rely on the order.
+ */
+static VALUE
+iseqw_each_child(VALUE self)
+{
+ const rb_iseq_t *iseq = iseqw_check(self);
+ iseq_iterate_children(iseq, yield_each_children, NULL);
+ return self;
+}
+
+static void
+push_event_info(const rb_iseq_t *iseq, rb_event_flag_t events, int line, VALUE ary)
+{
+#define C(ev, cstr, l) if (events & ev) rb_ary_push(ary, rb_ary_new_from_args(2, l, ID2SYM(rb_intern(cstr))));
+ C(RUBY_EVENT_CLASS, "class", rb_iseq_first_lineno(iseq));
+ C(RUBY_EVENT_CALL, "call", rb_iseq_first_lineno(iseq));
+ C(RUBY_EVENT_B_CALL, "b_call", rb_iseq_first_lineno(iseq));
+ C(RUBY_EVENT_LINE, "line", INT2FIX(line));
+ C(RUBY_EVENT_END, "end", INT2FIX(line));
+ C(RUBY_EVENT_RETURN, "return", INT2FIX(line));
+ C(RUBY_EVENT_B_RETURN, "b_return", INT2FIX(line));
+#undef C
+}
+
+/*
+ * call-seq:
+ * iseq.trace_points -> ary
+ *
+ * Return trace points in the instruction sequence.
+ * Return an array of [line, event_symbol] pair.
+ */
+static VALUE
+iseqw_trace_points(VALUE self)
+{
+ const rb_iseq_t *iseq = iseqw_check(self);
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ unsigned int i;
+ VALUE ary = rb_ary_new();
+
+ for (i=0; i<body->insns_info.size; i++) {
+ const struct iseq_insn_info_entry *entry = &body->insns_info.body[i];
+ if (entry->events) {
+ push_event_info(iseq, entry->events, entry->line_no, ary);
+ }
+ }
+ return ary;
+}
+
/*
* Returns the instruction sequence containing the given proc or method.
*
@@ -1688,17 +2513,18 @@ iseqw_s_of(VALUE klass, VALUE body)
{
const rb_iseq_t *iseq = NULL;
- rb_secure(1);
-
if (rb_obj_is_proc(body)) {
- iseq = vm_proc_iseq(body);
+ iseq = vm_proc_iseq(body);
- if (!rb_obj_is_iseq((VALUE)iseq)) {
- iseq = NULL;
- }
+ if (!rb_obj_is_iseq((VALUE)iseq)) {
+ iseq = NULL;
+ }
}
- else {
- iseq = rb_method_iseq(body);
+ else if (rb_obj_is_method(body)) {
+ iseq = rb_method_iseq(body);
+ }
+ else if (rb_typeddata_is_instance_of(body, &iseqw_data_type)) {
+ return body;
}
return iseq ? iseqw_new(iseq) : Qnil;
@@ -1769,16 +2595,16 @@ ruby_node_name(int node)
switch (node) {
#include "node_name.inc"
default:
- rb_bug("unknown node (%d)", node);
+ rb_bug("unknown node: %d", node);
return 0;
}
}
#define DECL_SYMBOL(name) \
- static VALUE sym_##name
+ static ID sym_##name
#define INIT_SYMBOL(name) \
- sym_##name = ID2SYM(rb_intern(#name))
+ sym_##name = rb_intern(#name)
static VALUE
register_label(struct st_table *table, unsigned long idx)
@@ -1800,7 +2626,7 @@ exception_type2symbol(VALUE type)
case CATCH_TYPE_REDO: CONST_ID(id, "redo"); break;
case CATCH_TYPE_NEXT: CONST_ID(id, "next"); break;
default:
- rb_bug("exception_type2symbol: unknown type %d", (int)type);
+ rb_bug("unknown exception type: %d", (int)type);
}
return ID2SYM(id);
}
@@ -1813,18 +2639,25 @@ cdhash_each(VALUE key, VALUE value, VALUE ary)
return ST_CONTINUE;
}
+static const rb_data_type_t label_wrapper = {
+ "label_wrapper",
+ {(void (*)(void *))rb_mark_tbl, (void (*)(void *))st_free_table, 0, 0,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
static VALUE
iseq_data_to_ary(const rb_iseq_t *iseq)
{
unsigned int i;
long l;
- size_t ti;
+ const struct rb_iseq_constant_body *const iseq_body = iseq->body;
+ const struct iseq_insn_info_entry *prev_insn_info;
unsigned int pos;
- unsigned int line = 0;
+ int last_line = 0;
VALUE *seq, *iseq_original;
VALUE val = rb_ary_new();
- VALUE type; /* Symbol */
+ ID type; /* Symbol */
VALUE locals = rb_ary_new();
VALUE params = rb_hash_new();
VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
@@ -1832,8 +2665,9 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
VALUE exception = rb_ary_new(); /* [[....]] */
VALUE misc = rb_hash_new();
- static VALUE insn_syms[VM_INSTRUCTION_SIZE];
+ static ID insn_syms[VM_INSTRUCTION_SIZE/2]; /* w/o-trace only */
struct st_table *labels_table = st_init_numtable();
+ VALUE labels_wrapper = TypedData_Wrap_Struct(0, &label_wrapper, labels_table);
DECL_SYMBOL(top);
DECL_SYMBOL(method);
@@ -1843,12 +2677,12 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
DECL_SYMBOL(ensure);
DECL_SYMBOL(eval);
DECL_SYMBOL(main);
- DECL_SYMBOL(defined_guard);
+ DECL_SYMBOL(plain);
if (sym_top == 0) {
int i;
- for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
- insn_syms[i] = ID2SYM(rb_intern(insn_name(i)));
+ for (i=0; i<numberof(insn_syms); i++) {
+ insn_syms[i] = rb_intern(insn_name(i));
}
INIT_SYMBOL(top);
INIT_SYMBOL(method);
@@ -1858,11 +2692,11 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
INIT_SYMBOL(ensure);
INIT_SYMBOL(eval);
INIT_SYMBOL(main);
- INIT_SYMBOL(defined_guard);
+ INIT_SYMBOL(plain);
}
/* type */
- switch (iseq->body->type) {
+ switch (iseq_body->type) {
case ISEQ_TYPE_TOP: type = sym_top; break;
case ISEQ_TYPE_METHOD: type = sym_method; break;
case ISEQ_TYPE_BLOCK: type = sym_block; break;
@@ -1871,19 +2705,19 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
case ISEQ_TYPE_ENSURE: type = sym_ensure; break;
case ISEQ_TYPE_EVAL: type = sym_eval; break;
case ISEQ_TYPE_MAIN: type = sym_main; break;
- case ISEQ_TYPE_DEFINED_GUARD: type = sym_defined_guard; break;
- default: rb_bug("unsupported iseq type");
+ case ISEQ_TYPE_PLAIN: type = sym_plain; break;
+ default: rb_bug("unsupported iseq type: %d", (int)iseq_body->type);
};
/* locals */
- for (i=0; i<iseq->body->local_table_size; i++) {
- ID lid = iseq->body->local_table[i];
+ for (i=0; i<iseq_body->local_table_size; i++) {
+ ID lid = iseq_body->local_table[i];
if (lid) {
if (rb_id2str(lid)) {
rb_ary_push(locals, ID2SYM(lid));
}
else { /* hidden variable from id_internal() */
- rb_ary_push(locals, ULONG2NUM(iseq->body->local_table_size-i+1));
+ rb_ary_push(locals, ULONG2NUM(iseq_body->local_table_size-i+1));
}
}
else {
@@ -1893,57 +2727,58 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
/* params */
{
+ const struct rb_iseq_param_keyword *const keyword = iseq_body->param.keyword;
int j;
- if (iseq->body->param.flags.has_opt) {
- int len = iseq->body->param.opt_num + 1;
- VALUE arg_opt_labels = rb_ary_new2(len);
+ if (iseq_body->param.flags.has_opt) {
+ int len = iseq_body->param.opt_num + 1;
+ VALUE arg_opt_labels = rb_ary_new2(len);
- for (j = 0; j < len; j++) {
- VALUE l = register_label(labels_table, iseq->body->param.opt_table[j]);
- rb_ary_push(arg_opt_labels, l);
- }
- rb_hash_aset(params, ID2SYM(rb_intern("opt")), arg_opt_labels);
+ for (j = 0; j < len; j++) {
+ VALUE l = register_label(labels_table, iseq_body->param.opt_table[j]);
+ rb_ary_push(arg_opt_labels, l);
+ }
+ rb_hash_aset(params, ID2SYM(rb_intern("opt")), arg_opt_labels);
}
/* commit */
- if (iseq->body->param.flags.has_lead) rb_hash_aset(params, ID2SYM(rb_intern("lead_num")), INT2FIX(iseq->body->param.lead_num));
- if (iseq->body->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_num")), INT2FIX(iseq->body->param.post_num));
- if (iseq->body->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_start")), INT2FIX(iseq->body->param.post_start));
- if (iseq->body->param.flags.has_rest) rb_hash_aset(params, ID2SYM(rb_intern("rest_start")), INT2FIX(iseq->body->param.rest_start));
- if (iseq->body->param.flags.has_block) rb_hash_aset(params, ID2SYM(rb_intern("block_start")), INT2FIX(iseq->body->param.block_start));
- if (iseq->body->param.flags.has_kw) {
+ if (iseq_body->param.flags.has_lead) rb_hash_aset(params, ID2SYM(rb_intern("lead_num")), INT2FIX(iseq_body->param.lead_num));
+ if (iseq_body->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_num")), INT2FIX(iseq_body->param.post_num));
+ if (iseq_body->param.flags.has_post) rb_hash_aset(params, ID2SYM(rb_intern("post_start")), INT2FIX(iseq_body->param.post_start));
+ if (iseq_body->param.flags.has_rest) rb_hash_aset(params, ID2SYM(rb_intern("rest_start")), INT2FIX(iseq_body->param.rest_start));
+ if (iseq_body->param.flags.has_block) rb_hash_aset(params, ID2SYM(rb_intern("block_start")), INT2FIX(iseq_body->param.block_start));
+ if (iseq_body->param.flags.has_kw) {
VALUE keywords = rb_ary_new();
int i, j;
- for (i=0; i<iseq->body->param.keyword->required_num; i++) {
- rb_ary_push(keywords, ID2SYM(iseq->body->param.keyword->table[i]));
+ for (i=0; i<keyword->required_num; i++) {
+ rb_ary_push(keywords, ID2SYM(keyword->table[i]));
}
- for (j=0; i<iseq->body->param.keyword->num; i++, j++) {
- VALUE key = rb_ary_new_from_args(1, ID2SYM(iseq->body->param.keyword->table[i]));
- if (iseq->body->param.keyword->default_values[j] != Qundef) {
- rb_ary_push(key, iseq->body->param.keyword->default_values[j]);
+ for (j=0; i<keyword->num; i++, j++) {
+ VALUE key = rb_ary_new_from_args(1, ID2SYM(keyword->table[i]));
+ if (keyword->default_values[j] != Qundef) {
+ rb_ary_push(key, keyword->default_values[j]);
}
rb_ary_push(keywords, key);
}
rb_hash_aset(params, ID2SYM(rb_intern("kwbits")),
- INT2FIX(iseq->body->param.keyword->bits_start));
+ INT2FIX(keyword->bits_start));
rb_hash_aset(params, ID2SYM(rb_intern("keyword")), keywords);
}
- if (iseq->body->param.flags.has_kwrest) rb_hash_aset(params, ID2SYM(rb_intern("kwrest")), INT2FIX(iseq->body->param.keyword->rest_start));
- if (iseq->body->param.flags.ambiguous_param0) rb_hash_aset(params, ID2SYM(rb_intern("ambiguous_param0")), Qtrue);
+ if (iseq_body->param.flags.has_kwrest) rb_hash_aset(params, ID2SYM(rb_intern("kwrest")), INT2FIX(keyword->rest_start));
+ if (iseq_body->param.flags.ambiguous_param0) rb_hash_aset(params, ID2SYM(rb_intern("ambiguous_param0")), Qtrue);
}
/* body */
iseq_original = rb_iseq_original_iseq((rb_iseq_t *)iseq);
- for (seq = iseq_original; seq < iseq_original + iseq->body->iseq_size; ) {
+ for (seq = iseq_original; seq < iseq_original + iseq_body->iseq_size; ) {
VALUE insn = *seq++;
int j, len = insn_len(insn);
VALUE *nseq = seq + len - 1;
VALUE ary = rb_ary_new2(len);
- rb_ary_push(ary, insn_syms[insn]);
+ rb_ary_push(ary, ID2SYM(insn_syms[insn%numberof(insn_syms)]));
for (j=0; j<len-1; j++, seq++) {
switch (insn_op_type(insn, j)) {
case TS_OFFSET: {
@@ -1970,47 +2805,42 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
}
}
break;
- case TS_GENTRY:
- {
- struct rb_global_entry *entry = (struct rb_global_entry *)*seq;
- rb_ary_push(ary, ID2SYM(entry->id));
- }
- break;
case TS_IC:
+ case TS_IVC:
+ case TS_ISE:
{
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
- rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));
+ rb_ary_push(ary, INT2FIX(is - iseq_body->is_entries));
}
break;
- case TS_CALLINFO:
+ case TS_CALLDATA:
{
- struct rb_call_info *ci = (struct rb_call_info *)*seq;
+ struct rb_call_data *cd = (struct rb_call_data *)*seq;
+ const struct rb_callinfo *ci = cd->ci;
VALUE e = rb_hash_new();
- int orig_argc = ci->orig_argc;
+ int argc = vm_ci_argc(ci);
- rb_hash_aset(e, ID2SYM(rb_intern("mid")), ci->mid ? ID2SYM(ci->mid) : Qnil);
- rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(ci->flag));
+ ID mid = vm_ci_mid(ci);
+ rb_hash_aset(e, ID2SYM(rb_intern("mid")), mid ? ID2SYM(mid) : Qnil);
+ rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(vm_ci_flag(ci)));
- if (ci->flag & VM_CALL_KWARG) {
- struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci;
- int i;
- VALUE kw = rb_ary_new2((long)ci_kw->kw_arg->keyword_len);
+ if (vm_ci_flag(ci) & VM_CALL_KWARG) {
+ const struct rb_callinfo_kwarg *kwarg = vm_ci_kwarg(ci);
+ int i;
+ VALUE kw = rb_ary_new2((long)kwarg->keyword_len);
- orig_argc -= ci_kw->kw_arg->keyword_len;
- for (i = 0; i < ci_kw->kw_arg->keyword_len; i++) {
- rb_ary_push(kw, ci_kw->kw_arg->keywords[i]);
+ argc -= kwarg->keyword_len;
+ for (i = 0; i < kwarg->keyword_len; i++) {
+ rb_ary_push(kw, kwarg->keywords[i]);
}
rb_hash_aset(e, ID2SYM(rb_intern("kw_arg")), kw);
}
rb_hash_aset(e, ID2SYM(rb_intern("orig_argc")),
- INT2FIX(orig_argc));
+ INT2FIX(argc));
rb_ary_push(ary, e);
}
break;
- case TS_CALLCACHE:
- rb_ary_push(ary, Qfalse);
- break;
case TS_ID:
rb_ary_push(ary, ID2SYM(*seq));
break;
@@ -2042,6 +2872,21 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
rb_ary_push(ary, val);
}
break;
+ case TS_BUILTIN:
+ {
+ VALUE val = rb_hash_new();
+#if SIZEOF_VALUE <= SIZEOF_LONG
+ VALUE func_ptr = LONG2NUM((SIGNED_VALUE)((RB_BUILTIN)*seq)->func_ptr);
+#else
+ VALUE func_ptr = LL2NUM((SIGNED_VALUE)((RB_BUILTIN)*seq)->func_ptr);
+#endif
+ rb_hash_aset(val, ID2SYM(rb_intern("func_ptr")), func_ptr);
+ rb_hash_aset(val, ID2SYM(rb_intern("argc")), INT2NUM(((RB_BUILTIN)*seq)->argc));
+ rb_hash_aset(val, ID2SYM(rb_intern("index")), INT2NUM(((RB_BUILTIN)*seq)->index));
+ rb_hash_aset(val, ID2SYM(rb_intern("name")), rb_str_new_cstr(((RB_BUILTIN)*seq)->name));
+ rb_ary_push(ary, val);
+ }
+ break;
default:
rb_bug("unknown operand: %c", insn_op_type(insn, j));
}
@@ -2052,9 +2897,10 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
nbody = body;
/* exception */
- if (iseq->body->catch_table) for (i=0; i<iseq->body->catch_table->size; i++) {
+ if (iseq_body->catch_table) for (i=0; i<iseq_body->catch_table->size; i++) {
VALUE ary = rb_ary_new();
- const struct iseq_catch_table_entry *entry = &iseq->body->catch_table->entries[i];
+ const struct iseq_catch_table_entry *entry =
+ UNALIGNED_MEMBER_PTR(iseq_body->catch_table, entries[i]);
rb_ary_push(ary, exception_type2symbol(entry->type));
if (entry->iseq) {
rb_ary_push(ary, iseq_data_to_ary(rb_iseq_check(entry->iseq)));
@@ -2071,9 +2917,10 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
/* make body with labels and insert line number */
body = rb_ary_new();
- ti = 0;
+ prev_insn_info = NULL;
for (l=0, pos=0; l<RARRAY_LEN(nbody); l++) {
+ const struct iseq_insn_info_entry *info;
VALUE ary = RARRAY_AREF(nbody, l);
st_data_t label;
@@ -2081,24 +2928,45 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
rb_ary_push(body, (VALUE)label);
}
- if (ti < iseq->body->line_info_size && iseq->body->line_info_table[ti].position == pos) {
- line = iseq->body->line_info_table[ti].line_no;
- rb_ary_push(body, INT2FIX(line));
- ti++;
+ info = get_insn_info(iseq, pos);
+
+ if (prev_insn_info != info) {
+ int line = info->line_no;
+ rb_event_flag_t events = info->events;
+
+ if (line > 0 && last_line != line) {
+ rb_ary_push(body, INT2FIX(line));
+ last_line = line;
+ }
+#define CHECK_EVENT(ev) if (events & ev) rb_ary_push(body, ID2SYM(rb_intern(#ev)));
+ CHECK_EVENT(RUBY_EVENT_LINE);
+ CHECK_EVENT(RUBY_EVENT_CLASS);
+ CHECK_EVENT(RUBY_EVENT_END);
+ CHECK_EVENT(RUBY_EVENT_CALL);
+ CHECK_EVENT(RUBY_EVENT_RETURN);
+ CHECK_EVENT(RUBY_EVENT_B_CALL);
+ CHECK_EVENT(RUBY_EVENT_B_RETURN);
+#undef CHECK_EVENT
+ prev_insn_info = info;
}
rb_ary_push(body, ary);
pos += RARRAY_LENINT(ary); /* reject too huge data */
}
RB_GC_GUARD(nbody);
+ RB_GC_GUARD(labels_wrapper);
+
+ rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq_body->param.size));
+ rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq_body->local_table_size));
+ rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq_body->stack_max));
+ rb_hash_aset(misc, ID2SYM(rb_intern("node_id")), INT2FIX(iseq_body->location.node_id));
+ rb_hash_aset(misc, ID2SYM(rb_intern("code_location")),
+ rb_ary_new_from_args(4,
+ INT2FIX(iseq_body->location.code_location.beg_pos.lineno),
+ INT2FIX(iseq_body->location.code_location.beg_pos.column),
+ INT2FIX(iseq_body->location.code_location.end_pos.lineno),
+ INT2FIX(iseq_body->location.code_location.end_pos.column)));
- st_free_table(labels_table);
-
- rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->body->param.size));
- rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq->body->local_table_size));
- rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq->body->stack_max));
-
- /* TODO: compatibility issue */
/*
* [:magic, :major_version, :minor_version, :format_type, :misc,
* :name, :path, :absolute_path, :start_lineno, :type, :locals, :args,
@@ -2109,11 +2977,11 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
rb_ary_push(val, INT2FIX(ISEQ_MINOR_VERSION)); /* minor */
rb_ary_push(val, INT2FIX(1));
rb_ary_push(val, misc);
- rb_ary_push(val, iseq->body->location.label);
+ rb_ary_push(val, iseq_body->location.label);
rb_ary_push(val, rb_iseq_path(iseq));
rb_ary_push(val, rb_iseq_realpath(iseq));
- rb_ary_push(val, iseq->body->location.first_lineno);
- rb_ary_push(val, type);
+ rb_ary_push(val, iseq_body->location.first_lineno);
+ rb_ary_push(val, ID2SYM(type));
rb_ary_push(val, locals);
rb_ary_push(val, params);
rb_ary_push(val, exception);
@@ -2125,10 +2993,12 @@ VALUE
rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
{
int i, r;
- VALUE a, args = rb_ary_new2(iseq->body->param.size);
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ const struct rb_iseq_param_keyword *const keyword = body->param.keyword;
+ VALUE a, args = rb_ary_new2(body->param.size);
ID req, opt, rest, block, key, keyrest;
#define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type))
-#define PARAM_ID(i) iseq->body->local_table[(i)]
+#define PARAM_ID(i) body->local_table[(i)]
#define PARAM(i, type) ( \
PARAM_TYPE(type), \
rb_id2str(PARAM_ID(i)) ? \
@@ -2138,18 +3008,18 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
CONST_ID(req, "req");
CONST_ID(opt, "opt");
if (is_proc) {
- for (i = 0; i < iseq->body->param.lead_num; i++) {
+ for (i = 0; i < body->param.lead_num; i++) {
PARAM_TYPE(opt);
rb_ary_push(a, rb_id2str(PARAM_ID(i)) ? ID2SYM(PARAM_ID(i)) : Qnil);
rb_ary_push(args, a);
}
}
else {
- for (i = 0; i < iseq->body->param.lead_num; i++) {
+ for (i = 0; i < body->param.lead_num; i++) {
rb_ary_push(args, PARAM(i, req));
}
}
- r = iseq->body->param.lead_num + iseq->body->param.opt_num;
+ r = body->param.lead_num + body->param.opt_num;
for (; i < r; i++) {
PARAM_TYPE(opt);
if (rb_id2str(PARAM_ID(i))) {
@@ -2157,52 +3027,58 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
}
rb_ary_push(args, a);
}
- if (iseq->body->param.flags.has_rest) {
+ if (body->param.flags.has_rest) {
CONST_ID(rest, "rest");
- rb_ary_push(args, PARAM(iseq->body->param.rest_start, rest));
+ rb_ary_push(args, PARAM(body->param.rest_start, rest));
}
- r = iseq->body->param.post_start + iseq->body->param.post_num;
+ r = body->param.post_start + body->param.post_num;
if (is_proc) {
- for (i = iseq->body->param.post_start; i < r; i++) {
+ for (i = body->param.post_start; i < r; i++) {
PARAM_TYPE(opt);
rb_ary_push(a, rb_id2str(PARAM_ID(i)) ? ID2SYM(PARAM_ID(i)) : Qnil);
rb_ary_push(args, a);
}
}
else {
- for (i = iseq->body->param.post_start; i < r; i++) {
+ for (i = body->param.post_start; i < r; i++) {
rb_ary_push(args, PARAM(i, req));
}
}
- if (iseq->body->param.flags.has_kw) {
+ if (body->param.flags.accepts_no_kwarg) {
+ ID nokey;
+ CONST_ID(nokey, "nokey");
+ PARAM_TYPE(nokey);
+ rb_ary_push(args, a);
+ }
+ if (body->param.flags.has_kw) {
i = 0;
- if (iseq->body->param.keyword->required_num > 0) {
+ if (keyword->required_num > 0) {
ID keyreq;
CONST_ID(keyreq, "keyreq");
- for (; i < iseq->body->param.keyword->required_num; i++) {
+ for (; i < keyword->required_num; i++) {
PARAM_TYPE(keyreq);
- if (rb_id2str(iseq->body->param.keyword->table[i])) {
- rb_ary_push(a, ID2SYM(iseq->body->param.keyword->table[i]));
+ if (rb_id2str(keyword->table[i])) {
+ rb_ary_push(a, ID2SYM(keyword->table[i]));
}
rb_ary_push(args, a);
}
}
CONST_ID(key, "key");
- for (; i < iseq->body->param.keyword->num; i++) {
+ for (; i < keyword->num; i++) {
PARAM_TYPE(key);
- if (rb_id2str(iseq->body->param.keyword->table[i])) {
- rb_ary_push(a, ID2SYM(iseq->body->param.keyword->table[i]));
+ if (rb_id2str(keyword->table[i])) {
+ rb_ary_push(a, ID2SYM(keyword->table[i]));
}
rb_ary_push(args, a);
}
}
- if (iseq->body->param.flags.has_kwrest) {
+ if (body->param.flags.has_kwrest) {
CONST_ID(keyrest, "keyrest");
- rb_ary_push(args, PARAM(iseq->body->param.keyword->rest_start, keyrest));
+ rb_ary_push(args, PARAM(keyword->rest_start, keyrest));
}
- if (iseq->body->param.flags.has_block) {
+ if (body->param.flags.has_block) {
CONST_ID(block, "block");
- rb_ary_push(args, PARAM(iseq->body->param.block_start, block));
+ rb_ary_push(args, PARAM(body->param.block_start, block));
}
return args;
}
@@ -2247,131 +3123,262 @@ rb_iseq_defined_string(enum defined_type type)
return str;
}
-/* Experimental tracing support: trace(line) -> trace(specified_line)
- * MRI Specific.
- */
+/* A map from encoded_insn to insn_data: decoded insn number, its len,
+ * non-trace version of encoded insn, and trace version. */
+
+static st_table *encoded_insn_data;
+typedef struct insn_data_struct {
+ int insn;
+ int insn_len;
+ void *notrace_encoded_insn;
+ void *trace_encoded_insn;
+} insn_data_t;
+static insn_data_t insn_data[VM_INSTRUCTION_SIZE/2];
+
+void
+rb_vm_encoded_insn_data_table_init(void)
+{
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ const void * const *table = rb_vm_get_insns_address_table();
+#define INSN_CODE(insn) ((VALUE)table[insn])
+#else
+#define INSN_CODE(insn) (insn)
+#endif
+ st_data_t insn;
+ encoded_insn_data = st_init_numtable_with_size(VM_INSTRUCTION_SIZE / 2);
+
+ for (insn = 0; insn < VM_INSTRUCTION_SIZE/2; insn++) {
+ st_data_t key1 = (st_data_t)INSN_CODE(insn);
+ st_data_t key2 = (st_data_t)INSN_CODE(insn + VM_INSTRUCTION_SIZE/2);
+
+ insn_data[insn].insn = (int)insn;
+ insn_data[insn].insn_len = insn_len(insn);
+
+ if (insn != BIN(opt_invokebuiltin_delegate_leave)) {
+ insn_data[insn].notrace_encoded_insn = (void *) key1;
+ insn_data[insn].trace_encoded_insn = (void *) key2;
+ }
+ else {
+ insn_data[insn].notrace_encoded_insn = (void *) INSN_CODE(BIN(opt_invokebuiltin_delegate));
+ insn_data[insn].trace_encoded_insn = (void *) INSN_CODE(BIN(opt_invokebuiltin_delegate) + VM_INSTRUCTION_SIZE/2);
+ }
+
+ st_add_direct(encoded_insn_data, key1, (st_data_t)&insn_data[insn]);
+ st_add_direct(encoded_insn_data, key2, (st_data_t)&insn_data[insn]);
+ }
+}
int
-rb_iseqw_line_trace_each(VALUE iseqw, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data)
+rb_vm_insn_addr2insn(const void *addr)
{
- int trace_num = 0;
- unsigned int pos;
- size_t insn;
- const rb_iseq_t *iseq = iseqw_check(iseqw);
- int cont = 1;
- VALUE *iseq_original;
-
- iseq_original = rb_iseq_original_iseq(iseq);
- for (pos = 0; cont && pos < iseq->body->iseq_size; pos += insn_len(insn)) {
- insn = iseq_original[pos];
-
- if (insn == BIN(trace)) {
- rb_event_flag_t current_events;
-
- current_events = (rb_event_flag_t)iseq_original[pos+1];
-
- if (current_events & RUBY_EVENT_LINE) {
- rb_event_flag_t events = current_events & RUBY_EVENT_SPECIFIED_LINE;
- trace_num++;
-
- if (func) {
- int line = find_line_no(iseq, pos);
- /* printf("line: %d\n", line); */
- cont = (*func)(line, &events, data);
- if (current_events != events) {
- VALUE *encoded = (VALUE *)iseq->body->iseq_encoded;
- iseq_original[pos+1] = encoded[pos+1] =
- (VALUE)(current_events | (events & RUBY_EVENT_SPECIFIED_LINE));
- }
- }
- }
- }
+ st_data_t key = (st_data_t)addr;
+ st_data_t val;
+
+ if (st_lookup(encoded_insn_data, key, &val)) {
+ insn_data_t *e = (insn_data_t *)val;
+ return (int)e->insn;
}
- return trace_num;
+
+ rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr);
}
-static int
-collect_trace(int line, rb_event_flag_t *events_ptr, void *ptr)
+static inline int
+encoded_iseq_trace_instrument(VALUE *iseq_encoded_insn, rb_event_flag_t turnon, bool remain_current_trace)
{
- VALUE result = (VALUE)ptr;
- rb_ary_push(result, INT2NUM(line));
- return 1;
+ st_data_t key = (st_data_t)*iseq_encoded_insn;
+ st_data_t val;
+
+ if (st_lookup(encoded_insn_data, key, &val)) {
+ insn_data_t *e = (insn_data_t *)val;
+ if (remain_current_trace && key == (st_data_t)e->trace_encoded_insn) {
+ turnon = 1;
+ }
+ *iseq_encoded_insn = (VALUE) (turnon ? e->trace_encoded_insn : e->notrace_encoded_insn);
+ return e->insn_len;
+ }
+
+ rb_bug("trace_instrument: invalid insn address: %p", (void *)*iseq_encoded_insn);
}
-/*
- * <b>Experimental MRI specific feature, only available as C level api.</b>
- *
- * Returns all +specified_line+ events.
- */
-VALUE
-rb_iseqw_line_trace_all(VALUE iseqw)
+void
+rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, size_t pos)
{
- VALUE result = rb_ary_new();
- rb_iseqw_line_trace_each(iseqw, collect_trace, (void *)result);
- return result;
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ VALUE *iseq_encoded = (VALUE *)body->iseq_encoded;
+ encoded_iseq_trace_instrument(&iseq_encoded[pos], 0, false);
}
-struct set_specifc_data {
- int pos;
- int set;
- int prev; /* 1: set, 2: unset, 0: not found */
+static int
+iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line)
+{
+ unsigned int pc;
+ int n = 0;
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ VALUE *iseq_encoded = (VALUE *)body->iseq_encoded;
+
+ VM_ASSERT(ISEQ_EXECUTABLE_P(iseq));
+
+ for (pc=0; pc<body->iseq_size;) {
+ const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pc);
+ rb_event_flag_t pc_events = entry->events;
+ rb_event_flag_t target_events = turnon_events;
+ unsigned int line = (int)entry->line_no;
+
+ if (target_line == 0 || target_line == line) {
+ /* ok */
+ }
+ else {
+ target_events &= ~RUBY_EVENT_LINE;
+ }
+
+ if (pc_events & target_events) {
+ n++;
+ }
+ pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (target_events | iseq->aux.exec.global_trace_events), true);
+ }
+
+ if (n > 0) {
+ if (iseq->aux.exec.local_hooks == NULL) {
+ ((rb_iseq_t *)iseq)->aux.exec.local_hooks = RB_ZALLOC(rb_hook_list_t);
+ }
+ rb_hook_list_connect_tracepoint((VALUE)iseq, iseq->aux.exec.local_hooks, tpval, target_line);
+ }
+
+ return n;
+}
+
+struct trace_set_local_events_struct {
+ rb_event_flag_t turnon_events;
+ VALUE tpval;
+ unsigned int target_line;
+ int n;
};
+static void
+iseq_add_local_tracepoint_i(const rb_iseq_t *iseq, void *p)
+{
+ struct trace_set_local_events_struct *data = (struct trace_set_local_events_struct *)p;
+ data->n += iseq_add_local_tracepoint(iseq, data->turnon_events, data->tpval, data->target_line);
+ iseq_iterate_children(iseq, iseq_add_local_tracepoint_i, p);
+}
+
+int
+rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line)
+{
+ struct trace_set_local_events_struct data;
+ data.turnon_events = turnon_events;
+ data.tpval = tpval;
+ data.target_line = target_line;
+ data.n = 0;
+
+ iseq_add_local_tracepoint_i(iseq, (void *)&data);
+ if (0) rb_funcall(Qnil, rb_intern("puts"), 1, rb_iseq_disasm(iseq)); /* for debug */
+ return data.n;
+}
+
static int
-line_trace_specify(int line, rb_event_flag_t *events_ptr, void *ptr)
+iseq_remove_local_tracepoint(const rb_iseq_t *iseq, VALUE tpval)
{
- struct set_specifc_data *data = (struct set_specifc_data *)ptr;
+ int n = 0;
- if (data->pos == 0) {
- data->prev = *events_ptr & RUBY_EVENT_SPECIFIED_LINE ? 1 : 2;
- if (data->set) {
- *events_ptr = *events_ptr | RUBY_EVENT_SPECIFIED_LINE;
- }
- else {
- *events_ptr = *events_ptr & ~RUBY_EVENT_SPECIFIED_LINE;
- }
- return 0; /* found */
- }
- else {
- data->pos--;
- return 1;
+ if (iseq->aux.exec.local_hooks) {
+ unsigned int pc;
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ VALUE *iseq_encoded = (VALUE *)body->iseq_encoded;
+ rb_event_flag_t local_events = 0;
+
+ rb_hook_list_remove_tracepoint(iseq->aux.exec.local_hooks, tpval);
+ local_events = iseq->aux.exec.local_hooks->events;
+
+ if (local_events == 0) {
+ if (iseq->aux.exec.local_hooks->running == 0) {
+ rb_hook_list_free(iseq->aux.exec.local_hooks);
+ }
+ ((rb_iseq_t *)iseq)->aux.exec.local_hooks = NULL;
+ }
+
+ for (pc = 0; pc<body->iseq_size;) {
+ rb_event_flag_t pc_events = rb_iseq_event_flags(iseq, pc);
+ pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (local_events | iseq->aux.exec.global_trace_events), false);
+ }
}
+ return n;
}
-/*
- * <b>Experimental MRI specific feature, only available as C level api.</b>
- *
- * Set a +specified_line+ event at the given line position, if the +set+
- * parameter is +true+.
- *
- * This method is useful for building a debugger breakpoint at a specific line.
- *
- * A TypeError is raised if +set+ is not boolean.
- *
- * If +pos+ is a negative integer a TypeError exception is raised.
- */
-VALUE
-rb_iseqw_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set)
+struct trace_clear_local_events_struct {
+ VALUE tpval;
+ int n;
+};
+
+static void
+iseq_remove_local_tracepoint_i(const rb_iseq_t *iseq, void *p)
{
- struct set_specifc_data data;
+ struct trace_clear_local_events_struct *data = (struct trace_clear_local_events_struct *)p;
+ data->n += iseq_remove_local_tracepoint(iseq, data->tpval);
+ iseq_iterate_children(iseq, iseq_remove_local_tracepoint_i, p);
+}
- data.prev = 0;
- data.pos = NUM2INT(pos);
- if (data.pos < 0) rb_raise(rb_eTypeError, "`pos' is negative");
+int
+rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval)
+{
+ struct trace_clear_local_events_struct data;
+ data.tpval = tpval;
+ data.n = 0;
- switch (set) {
- case Qtrue: data.set = 1; break;
- case Qfalse: data.set = 0; break;
- default:
- rb_raise(rb_eTypeError, "`set' should be true/false");
+ iseq_remove_local_tracepoint_i(iseq, (void *)&data);
+ return data.n;
+}
+
+void
+rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
+{
+ if (iseq->aux.exec.global_trace_events == turnon_events) {
+ return;
}
- rb_iseqw_line_trace_each(iseqval, line_trace_specify, (void *)&data);
+ if (!ISEQ_EXECUTABLE_P(iseq)) {
+ /* this is building ISeq */
+ return;
+ }
+ else {
+ unsigned int pc;
+ const struct rb_iseq_constant_body *const body = iseq->body;
+ VALUE *iseq_encoded = (VALUE *)body->iseq_encoded;
+ rb_event_flag_t enabled_events;
+ rb_event_flag_t local_events = iseq->aux.exec.local_hooks ? iseq->aux.exec.local_hooks->events : 0;
+ ((rb_iseq_t *)iseq)->aux.exec.global_trace_events = turnon_events;
+ enabled_events = turnon_events | local_events;
+
+ for (pc=0; pc<body->iseq_size;) {
+ rb_event_flag_t pc_events = rb_iseq_event_flags(iseq, pc);
+ pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & enabled_events, true);
+ }
+ }
+}
- if (data.prev == 0) {
- rb_raise(rb_eTypeError, "`pos' is out of range.");
+static int
+trace_set_i(void *vstart, void *vend, size_t stride, void *data)
+{
+ rb_event_flag_t turnon_events = *(rb_event_flag_t *)data;
+
+ VALUE v = (VALUE)vstart;
+ for (; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
+ if (rb_obj_is_iseq(v)) {
+ rb_iseq_trace_set(rb_iseq_check((rb_iseq_t *)v), turnon_events);
+ }
+
+ asan_poison_object_if(ptr, v);
}
- return data.prev == 1 ? Qtrue : Qfalse;
+ return 0;
+}
+
+void
+rb_iseq_trace_set_all(rb_event_flag_t turnon_events)
+{
+ rb_objspace_each_objects(trace_set_i, &turnon_events);
}
VALUE
@@ -2400,9 +3407,8 @@ rb_iseqw_local_variables(VALUE iseqval)
static VALUE
iseqw_to_binary(int argc, VALUE *argv, VALUE self)
{
- VALUE opt;
- rb_scan_args(argc, argv, "01", &opt);
- return iseq_ibf_dump(iseqw_check(self), opt);
+ VALUE opt = !rb_check_arity(argc, 0, 1) ? Qnil : argv[0];
+ return rb_iseq_ibf_dump(iseqw_check(self), opt);
}
/*
@@ -2421,7 +3427,7 @@ iseqw_to_binary(int argc, VALUE *argv, VALUE self)
static VALUE
iseqw_s_load_from_binary(VALUE self, VALUE str)
{
- return iseqw_new(iseq_ibf_load(str));
+ return iseqw_new(rb_iseq_ibf_load(str));
}
/*
@@ -2433,19 +3439,156 @@ iseqw_s_load_from_binary(VALUE self, VALUE str)
static VALUE
iseqw_s_load_from_binary_extra_data(VALUE self, VALUE str)
{
- return iseq_ibf_load_extra_data(str);
+ return rb_iseq_ibf_load_extra_data(str);
+}
+
+#if VM_INSN_INFO_TABLE_IMPL == 2
+
+/* An implementation of succinct bit-vector for insn_info table.
+ *
+ * A succinct bit-vector is a small and efficient data structure that provides
+ * a bit-vector augmented with an index for O(1) rank operation:
+ *
+ * rank(bv, n): the number of 1's within a range from index 0 to index n
+ *
+ * This can be used to lookup insn_info table from PC.
+ * For example, consider the following iseq and insn_info_table:
+ *
+ * iseq insn_info_table
+ * PC insn+operand position lineno event
+ * 0: insn1 0: 1 [Li]
+ * 2: insn2 2: 2 [Li] <= (A)
+ * 5: insn3 8: 3 [Li] <= (B)
+ * 8: insn4
+ *
+ * In this case, a succinct bit-vector whose indexes 0, 2, 8 is "1" and
+ * other indexes is "0", i.e., "101000001", is created.
+ * To lookup the lineno of insn2, calculate rank("10100001", 2) = 2, so
+ * the line (A) is the entry in question.
+ * To lookup the lineno of insn4, calculate rank("10100001", 8) = 3, so
+ * the line (B) is the entry in question.
+ *
+ * A naive implementation of succinct bit-vector works really well
+ * not only for large size but also for small size. However, it has
+ * tiny overhead for very small size. So, this implementation consist
+ * of two parts: one part is the "immediate" table that keeps rank result
+ * as a raw table, and the other part is a normal succinct bit-vector.
+ */
+
+#define IMMEDIATE_TABLE_SIZE 54 /* a multiple of 9, and < 128 */
+
+struct succ_index_table {
+ uint64_t imm_part[IMMEDIATE_TABLE_SIZE / 9];
+ struct succ_dict_block {
+ unsigned int rank;
+ uint64_t small_block_ranks; /* 9 bits * 7 = 63 bits */
+ uint64_t bits[512/64];
+ } succ_part[FLEX_ARY_LEN];
+};
+
+#define imm_block_rank_set(v, i, r) (v) |= (uint64_t)(r) << (7 * (i))
+#define imm_block_rank_get(v, i) (((int)((v) >> ((i) * 7))) & 0x7f)
+#define small_block_rank_set(v, i, r) (v) |= (uint64_t)(r) << (9 * ((i) - 1))
+#define small_block_rank_get(v, i) ((i) == 0 ? 0 : (((int)((v) >> (((i) - 1) * 9))) & 0x1ff))
+
+static struct succ_index_table *
+succ_index_table_create(int max_pos, int *data, int size)
+{
+ const int imm_size = (max_pos < IMMEDIATE_TABLE_SIZE ? max_pos + 8 : IMMEDIATE_TABLE_SIZE) / 9;
+ const int succ_size = (max_pos < IMMEDIATE_TABLE_SIZE ? 0 : (max_pos - IMMEDIATE_TABLE_SIZE + 511)) / 512;
+ struct succ_index_table *sd =
+ rb_xcalloc_mul_add_mul(
+ imm_size, sizeof(uint64_t),
+ succ_size, sizeof(struct succ_dict_block));
+ int i, j, k, r;
+
+ r = 0;
+ for (j = 0; j < imm_size; j++) {
+ for (i = 0; i < 9; i++) {
+ if (r < size && data[r] == j * 9 + i) r++;
+ imm_block_rank_set(sd->imm_part[j], i, r);
+ }
+ }
+ for (k = 0; k < succ_size; k++) {
+ struct succ_dict_block *sd_block = &sd->succ_part[k];
+ int small_rank = 0;
+ sd_block->rank = r;
+ for (j = 0; j < 8; j++) {
+ uint64_t bits = 0;
+ if (j) small_block_rank_set(sd_block->small_block_ranks, j, small_rank);
+ for (i = 0; i < 64; i++) {
+ if (r < size && data[r] == k * 512 + j * 64 + i + IMMEDIATE_TABLE_SIZE) {
+ bits |= ((uint64_t)1) << i;
+ r++;
+ }
+ }
+ sd_block->bits[j] = bits;
+ small_rank += rb_popcount64(bits);
+ }
+ }
+ return sd;
+}
+
+static unsigned int *
+succ_index_table_invert(int max_pos, struct succ_index_table *sd, int size)
+{
+ const int imm_size = (max_pos < IMMEDIATE_TABLE_SIZE ? max_pos + 8 : IMMEDIATE_TABLE_SIZE) / 9;
+ const int succ_size = (max_pos < IMMEDIATE_TABLE_SIZE ? 0 : (max_pos - IMMEDIATE_TABLE_SIZE + 511)) / 512;
+ unsigned int *positions = ALLOC_N(unsigned int, size), *p;
+ int i, j, k, r = -1;
+ p = positions;
+ for (j = 0; j < imm_size; j++) {
+ for (i = 0; i < 9; i++) {
+ int nr = imm_block_rank_get(sd->imm_part[j], i);
+ if (r != nr) *p++ = j * 9 + i;
+ r = nr;
+ }
+ }
+ for (k = 0; k < succ_size; k++) {
+ for (j = 0; j < 8; j++) {
+ for (i = 0; i < 64; i++) {
+ if (sd->succ_part[k].bits[j] & (((uint64_t)1) << i)) {
+ *p++ = k * 512 + j * 64 + i + IMMEDIATE_TABLE_SIZE;
+ }
+ }
+ }
+ }
+ return positions;
}
+static int
+succ_index_lookup(const struct succ_index_table *sd, int x)
+{
+ if (x < IMMEDIATE_TABLE_SIZE) {
+ const int i = x / 9;
+ const int j = x % 9;
+ return imm_block_rank_get(sd->imm_part[i], j);
+ }
+ else {
+ const int block_index = (x - IMMEDIATE_TABLE_SIZE) / 512;
+ const struct succ_dict_block *block = &sd->succ_part[block_index];
+ const int block_bit_index = (x - IMMEDIATE_TABLE_SIZE) % 512;
+ const int small_block_index = block_bit_index / 64;
+ const int small_block_popcount = small_block_rank_get(block->small_block_ranks, small_block_index);
+ const int popcnt = rb_popcount64(block->bits[small_block_index] << (63 - block_bit_index % 64));
+
+ return block->rank + small_block_popcount + popcnt;
+ }
+}
+#endif
+
/*
* Document-class: RubyVM::InstructionSequence
*
* The InstructionSequence class represents a compiled sequence of
- * instructions for the Ruby Virtual Machine.
+ * instructions for the Virtual Machine used in MRI. Not all implementations of Ruby
+ * may implement this class, and for the implementations that implement it,
+ * the methods defined and behavior of the methods can change in any version.
*
* With it, you can get a handle to the instructions that make up a method or
* a proc, compile strings of Ruby code down to VM instructions, and
* disassemble instruction sequences to strings for easy inspection. It is
- * mostly useful if you want to learn how the Ruby VM works, but it also lets
+ * mostly useful if you want to learn how YARV works, but it also lets
* you control various settings for the Ruby iseq compiler.
*
* You can find the source for the VM instructions in +insns.def+ in the Ruby
@@ -2454,6 +3597,8 @@ iseqw_s_load_from_binary_extra_data(VALUE self, VALUE str)
* The instruction sequence results will almost certainly change as Ruby
* changes, so example output in this documentation may be different from what
* you see.
+ *
+ * Of course, this class is MRI specific.
*/
void
@@ -2479,16 +3624,8 @@ Init_ISeq(void)
rb_define_method(rb_cISeq, "label", iseqw_label, 0);
rb_define_method(rb_cISeq, "base_label", iseqw_base_label, 0);
rb_define_method(rb_cISeq, "first_lineno", iseqw_first_lineno, 0);
-
-#if 0
- /* Now, it is experimental. No discussions, no tests. */
- /* They can be used from C level. Please give us feedback. */
- rb_define_method(rb_cISeq, "line_trace_all", rb_iseqw_line_trace_all, 0);
- rb_define_method(rb_cISeq, "line_trace_specify", rb_iseqw_line_trace_specify, 2);
-#else
- (void)rb_iseqw_line_trace_all;
- (void)rb_iseqw_line_trace_specify;
-#endif
+ rb_define_method(rb_cISeq, "trace_points", iseqw_trace_points, 0);
+ rb_define_method(rb_cISeq, "each_child", iseqw_each_child, 0);
#if 0 /* TBD */
rb_define_private_method(rb_cISeq, "marshal_dump", iseqw_marshal_dump, 0);
diff --git a/iseq.h b/iseq.h
index 752fa838d8..bae534c71d 100644
--- a/iseq.h
+++ b/iseq.h
@@ -1,3 +1,5 @@
+#ifndef RUBY_ISEQ_H
+#define RUBY_ISEQ_H 1
/**********************************************************************
iseq.h -
@@ -8,76 +10,135 @@
Copyright (C) 2004-2008 Koichi Sasada
**********************************************************************/
+#include "internal/gc.h"
+#include "vm_core.h"
-#ifndef RUBY_ISEQ_H
-#define RUBY_ISEQ_H 1
-
-#define ISEQ_MAJOR_VERSION 2
-#define ISEQ_MINOR_VERSION 3
+RUBY_EXTERN const int ruby_api_version[];
+#define ISEQ_MAJOR_VERSION ((unsigned int)ruby_api_version[0])
+#define ISEQ_MINOR_VERSION ((unsigned int)ruby_api_version[1])
#ifndef rb_iseq_t
typedef struct rb_iseq_struct rb_iseq_t;
#define rb_iseq_t rb_iseq_t
#endif
-static inline size_t
-rb_call_info_kw_arg_bytes(int keyword_len)
-{
- return sizeof(struct rb_call_info_kw_arg) + sizeof(VALUE) * (keyword_len - 1);
-}
-
-enum iseq_mark_ary_index {
- ISEQ_MARK_ARY_COVERAGE,
- ISEQ_MARK_ARY_FLIP_CNT,
- ISEQ_MARK_ARY_ORIGINAL_ISEQ,
- ISEQ_MARK_ARY_INITIAL_SIZE
-};
-
-static inline VALUE
-iseq_mark_ary_create(int flip_cnt)
-{
- VALUE ary = rb_ary_tmp_new(ISEQ_MARK_ARY_INITIAL_SIZE);
- rb_ary_push(ary, Qnil); /* ISEQ_MARK_ARY_COVERAGE */
- rb_ary_push(ary, INT2FIX(flip_cnt)); /* ISEQ_MARK_ARY_FLIP_CNT */
- rb_ary_push(ary, Qnil); /* ISEQ_MARK_ARY_ORIGINAL_ISEQ */
- return ary;
-}
-
-#define ISEQ_MARK_ARY(iseq) (iseq)->body->mark_ary
+extern const ID rb_iseq_shared_exc_local_tbl[];
-#define ISEQ_COVERAGE(iseq) RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_COVERAGE)
-#define ISEQ_COVERAGE_SET(iseq, cov) RARRAY_ASET(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_COVERAGE, cov)
+#define ISEQ_COVERAGE(iseq) iseq->body->variable.coverage
+#define ISEQ_COVERAGE_SET(iseq, cov) RB_OBJ_WRITE(iseq, &iseq->body->variable.coverage, cov)
#define ISEQ_LINE_COVERAGE(iseq) RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_LINES)
#define ISEQ_BRANCH_COVERAGE(iseq) RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_BRANCHES)
-#define ISEQ_METHOD_COVERAGE(iseq) RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_METHODS)
-#define ISEQ_FLIP_CNT(iseq) FIX2INT(RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_FLIP_CNT))
+#define ISEQ_PC2BRANCHINDEX(iseq) iseq->body->variable.pc2branchindex
+#define ISEQ_PC2BRANCHINDEX_SET(iseq, h) RB_OBJ_WRITE(iseq, &iseq->body->variable.pc2branchindex, h)
-static inline int
+#define ISEQ_FLIP_CNT(iseq) (iseq)->body->variable.flip_count
+
+static inline rb_snum_t
ISEQ_FLIP_CNT_INCREMENT(const rb_iseq_t *iseq)
{
- int cnt = ISEQ_FLIP_CNT(iseq);
- RARRAY_ASET(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_FLIP_CNT, INT2FIX(cnt+1));
+ rb_snum_t cnt = iseq->body->variable.flip_count;
+ iseq->body->variable.flip_count += 1;
return cnt;
}
static inline VALUE *
ISEQ_ORIGINAL_ISEQ(const rb_iseq_t *iseq)
{
- VALUE str = RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_ORIGINAL_ISEQ);
- if (RTEST(str)) return (VALUE *)RSTRING_PTR(str);
- return NULL;
+ return iseq->body->variable.original_iseq;
+}
+
+static inline void
+ISEQ_ORIGINAL_ISEQ_CLEAR(const rb_iseq_t *iseq)
+{
+ void *ptr = iseq->body->variable.original_iseq;
+ iseq->body->variable.original_iseq = NULL;
+ if (ptr) {
+ ruby_xfree(ptr);
+ }
}
static inline VALUE *
ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size)
{
- VALUE str = rb_str_tmp_new(size * sizeof(VALUE));
- RARRAY_ASET(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_ORIGINAL_ISEQ, str);
- return (VALUE *)RSTRING_PTR(str);
+ return iseq->body->variable.original_iseq =
+ ALLOC_N(VALUE, size);
}
-#define ISEQ_COMPILE_DATA(iseq) (iseq)->aux.compile_data
+#define ISEQ_TRACE_EVENTS (RUBY_EVENT_LINE | \
+ RUBY_EVENT_CLASS | \
+ RUBY_EVENT_END | \
+ RUBY_EVENT_CALL | \
+ RUBY_EVENT_RETURN| \
+ RUBY_EVENT_B_CALL| \
+ RUBY_EVENT_B_RETURN| \
+ RUBY_EVENT_COVERAGE_LINE| \
+ RUBY_EVENT_COVERAGE_BRANCH)
+
+#define ISEQ_NOT_LOADED_YET IMEMO_FL_USER1
+#define ISEQ_USE_COMPILE_DATA IMEMO_FL_USER2
+#define ISEQ_TRANSLATED IMEMO_FL_USER3
+#define ISEQ_MARKABLE_ISEQ IMEMO_FL_USER4
+
+#define ISEQ_EXECUTABLE_P(iseq) (FL_TEST_RAW(((VALUE)iseq), ISEQ_NOT_LOADED_YET | ISEQ_USE_COMPILE_DATA) == 0)
+
+struct iseq_compile_data {
+ /* GC is needed */
+ const VALUE err_info;
+ const VALUE catch_table_ary; /* Array */
+
+ /* GC is not needed */
+ struct iseq_label_data *start_label;
+ struct iseq_label_data *end_label;
+ struct iseq_label_data *redo_label;
+ const rb_iseq_t *current_block;
+ struct iseq_compile_data_ensure_node_stack *ensure_node_stack;
+ struct {
+ struct iseq_compile_data_storage *storage_head;
+ struct iseq_compile_data_storage *storage_current;
+ } node;
+ struct {
+ struct iseq_compile_data_storage *storage_head;
+ struct iseq_compile_data_storage *storage_current;
+ } insn;
+ int loopval_popped; /* used by NODE_BREAK */
+ int last_line;
+ int label_no;
+ int node_level;
+ int isolated_depth;
+ unsigned int ci_index;
+ const rb_compile_option_t *option;
+ struct rb_id_table *ivar_cache_table;
+ const struct rb_builtin_function *builtin_function_table;
+#if OPT_SUPPORT_JOKE
+ st_table *labels_table;
+#endif
+};
+
+static inline struct iseq_compile_data *
+ISEQ_COMPILE_DATA(const rb_iseq_t *iseq)
+{
+ if (iseq->flags & ISEQ_USE_COMPILE_DATA) {
+ return iseq->aux.compile_data;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static inline void
+ISEQ_COMPILE_DATA_ALLOC(rb_iseq_t *iseq)
+{
+ iseq->aux.compile_data = ZALLOC(struct iseq_compile_data);
+ iseq->flags |= ISEQ_USE_COMPILE_DATA;
+}
+
+static inline void
+ISEQ_COMPILE_DATA_CLEAR(rb_iseq_t *iseq)
+{
+ iseq->flags &= ~ISEQ_USE_COMPILE_DATA;
+ iseq->aux.compile_data = NULL;
+}
static inline rb_iseq_t *
iseq_imemo_alloc(void)
@@ -85,33 +146,40 @@ iseq_imemo_alloc(void)
return (rb_iseq_t *)rb_imemo_new(imemo_iseq, 0, 0, 0, 0);
}
-#define ISEQ_NOT_LOADED_YET IMEMO_FL_USER1
-
-VALUE iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt);
-void ibf_load_iseq_complete(rb_iseq_t *iseq);
-const rb_iseq_t *iseq_ibf_load(VALUE str);
-VALUE iseq_ibf_load_extra_data(VALUE str);
+VALUE rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt);
+void rb_ibf_load_iseq_complete(rb_iseq_t *iseq);
+const rb_iseq_t *rb_iseq_ibf_load(VALUE str);
+const rb_iseq_t *rb_iseq_ibf_load_bytes(const char *cstr, size_t);
+VALUE rb_iseq_ibf_load_extra_data(VALUE str);
+void rb_iseq_init_trace(rb_iseq_t *iseq);
+int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line);
+int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval);
+const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
+
+#if VM_INSN_INFO_TABLE_IMPL == 2
+unsigned int *rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body);
+#endif
RUBY_SYMBOL_EXPORT_BEGIN
/* compile.c */
-VALUE rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node);
-int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
+VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node);
+VALUE rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc);
VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
VALUE locals, VALUE args,
VALUE exception, VALUE body);
+void rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *arena);
/* iseq.c */
-void rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj);
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
-struct st_table *ruby_insn_make_insn_table(void);
unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos);
+void rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events);
+void rb_iseq_trace_set_all(rb_event_flag_t turnon_events);
+void rb_iseq_insns_info_encode_positions(const rb_iseq_t *iseq);
-int rb_iseqw_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data);
-VALUE rb_iseqw_line_trace_all(VALUE iseqval);
-VALUE rb_iseqw_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set);
+struct rb_iseq_constant_body *rb_iseq_constant_body_alloc(void);
VALUE rb_iseqw_new(const rb_iseq_t *iseq);
const rb_iseq_t *rb_iseqw_to_iseq(VALUE iseqw);
@@ -120,6 +188,9 @@ VALUE rb_iseq_label(const rb_iseq_t *iseq);
VALUE rb_iseq_base_label(const rb_iseq_t *iseq);
VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq);
VALUE rb_iseq_method_name(const rb_iseq_t *iseq);
+void rb_iseq_code_location(const rb_iseq_t *iseq, int *first_lineno, int *first_column, int *last_lineno, int *last_column);
+
+void rb_iseq_remove_coverage_all(void);
/* proc.c */
const rb_iseq_t *rb_method_iseq(VALUE body);
@@ -133,16 +204,15 @@ struct rb_compile_option_struct {
unsigned int operands_unification: 1;
unsigned int instructions_unification: 1;
unsigned int stack_caching: 1;
- unsigned int trace_instruction: 1;
unsigned int frozen_string_literal: 1;
unsigned int debug_frozen_string_literal: 1;
unsigned int coverage_enabled: 1;
int debug_level;
};
-struct iseq_line_info_entry {
- unsigned int position;
- unsigned int line_no;
+struct iseq_insn_info_entry {
+ int line_no;
+ rb_event_flag_t events;
};
struct iseq_catch_table_entry {
@@ -167,7 +237,7 @@ struct iseq_catch_table_entry {
* CATCH_TYPE_REDO, CATCH_TYPE_NEXT:
* NULL.
*/
- const rb_iseq_t *iseq;
+ rb_iseq_t *iseq;
unsigned int start;
unsigned int end;
@@ -177,18 +247,19 @@ struct iseq_catch_table_entry {
PACKED_STRUCT_UNALIGNED(struct iseq_catch_table {
unsigned int size;
- struct iseq_catch_table_entry entries[1]; /* flexible array */
+ struct iseq_catch_table_entry entries[FLEX_ARY_LEN];
});
static inline int
iseq_catch_table_bytes(int n)
{
enum {
- catch_table_entries_max = (INT_MAX - sizeof(struct iseq_catch_table)) / sizeof(struct iseq_catch_table_entry)
+ catch_table_entry_size = sizeof(struct iseq_catch_table_entry),
+ catch_table_entries_max = (INT_MAX - offsetof(struct iseq_catch_table, entries)) / catch_table_entry_size
};
if (n > catch_table_entries_max) rb_fatal("too large iseq_catch_table - %d", n);
- return (int)(sizeof(struct iseq_catch_table) +
- (n - 1) * sizeof(struct iseq_catch_table_entry));
+ return (int)(offsetof(struct iseq_catch_table, entries) +
+ n * catch_table_entry_size);
}
#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512)
@@ -197,47 +268,13 @@ struct iseq_compile_data_storage {
struct iseq_compile_data_storage *next;
unsigned int pos;
unsigned int size;
- char buff[1]; /* flexible array */
-};
-
-/* account for flexible array */
-#define SIZEOF_ISEQ_COMPILE_DATA_STORAGE \
- (sizeof(struct iseq_compile_data_storage) - 1)
-
-struct iseq_compile_data {
- /* GC is needed */
- const VALUE err_info;
- VALUE mark_ary;
- const VALUE catch_table_ary; /* Array */
-
- /* GC is not needed */
- struct iseq_label_data *start_label;
- struct iseq_label_data *end_label;
- struct iseq_label_data *redo_label;
- const rb_iseq_t *current_block;
- VALUE ensure_node;
- VALUE for_iseq;
- struct iseq_compile_data_ensure_node_stack *ensure_node_stack;
- int loopval_popped; /* used by NODE_BREAK */
- int cached_const;
- struct iseq_compile_data_storage *storage_head;
- struct iseq_compile_data_storage *storage_current;
- int last_line;
- int last_coverable_line;
- int label_no;
- int node_level;
- unsigned int ci_index;
- unsigned int ci_kw_index;
- const rb_compile_option_t *option;
- struct rb_id_table *ivar_cache_table;
-#if SUPPORT_JOKE
- st_table *labels_table;
-#endif
+ char buff[FLEX_ARY_LEN];
};
/* defined? */
enum defined_type {
+ DEFINED_NOT_DEFINED,
DEFINED_NIL = 1,
DEFINED_IVAR,
DEFINED_LVAR,
@@ -254,11 +291,11 @@ enum defined_type {
DEFINED_EXPR,
DEFINED_IVAR2,
DEFINED_REF,
- DEFINED_FUNC
+ DEFINED_FUNC,
+ DEFINED_CONST_FROM
};
VALUE rb_iseq_defined_string(enum defined_type type);
-void rb_iseq_make_compile_option(struct rb_compile_option_struct *option, VALUE opt);
/* vm.c */
VALUE rb_iseq_local_variables(const rb_iseq_t *iseq);
diff --git a/kernel.rb b/kernel.rb
new file mode 100644
index 0000000000..04a371a7c8
--- /dev/null
+++ b/kernel.rb
@@ -0,0 +1,174 @@
+module Kernel
+ #
+ # call-seq:
+ # obj.class -> class
+ #
+ # Returns the class of <i>obj</i>. This method must always be called
+ # with an explicit receiver, as #class is also a reserved word in
+ # Ruby.
+ #
+ # 1.class #=> Integer
+ # self.class #=> Object
+ #--
+ # Equivalent to \c Object\#class in Ruby.
+ #
+ # Returns the class of \c obj, skipping singleton classes or module inclusions.
+ #++
+ #
+ def class
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_obj_class(self)'
+ end
+
+ #
+ # call-seq:
+ # obj.clone(freeze: nil) -> an_object
+ #
+ # Produces a shallow copy of <i>obj</i>---the instance variables of
+ # <i>obj</i> are copied, but not the objects they reference.
+ # #clone copies the frozen value state of <i>obj</i>, unless the
+ # +:freeze+ keyword argument is given with a false or true value.
+ # See also the discussion under Object#dup.
+ #
+ # class Klass
+ # attr_accessor :str
+ # end
+ # s1 = Klass.new #=> #<Klass:0x401b3a38>
+ # s1.str = "Hello" #=> "Hello"
+ # s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello">
+ # s2.str[1,4] = "i" #=> "i"
+ # s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
+ # s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">"
+ #
+ # This method may have class-specific behavior. If so, that
+ # behavior will be documented under the #+initialize_copy+ method of
+ # the class.
+ #
+ def clone(freeze: nil)
+ Primitive.rb_obj_clone2(freeze)
+ end
+
+ #
+ # call-seq:
+ # obj.frozen? -> true or false
+ #
+ # Returns the freeze status of <i>obj</i>.
+ #
+ # a = [ "a", "b", "c" ]
+ # a.freeze #=> ["a", "b", "c"]
+ # a.frozen? #=> true
+ #--
+ # Determines if the object is frozen. Equivalent to \c Object\#frozen? in Ruby.
+ # \param[in] obj the object to be determines
+ # \retval Qtrue if frozen
+ # \retval Qfalse if not frozen
+ #++
+ #
+ def frozen?
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_obj_frozen_p(self)'
+ end
+
+ #
+ # call-seq:
+ # obj.tap {|x| block } -> obj
+ #
+ # Yields self to the block, and then returns self.
+ # The primary purpose of this method is to "tap into" a method chain,
+ # in order to perform operations on intermediate results within the chain.
+ #
+ # (1..10) .tap {|x| puts "original: #{x}" }
+ # .to_a .tap {|x| puts "array: #{x}" }
+ # .select {|x| x.even? } .tap {|x| puts "evens: #{x}" }
+ # .map {|x| x*x } .tap {|x| puts "squares: #{x}" }
+ #
+ #--
+ # \private
+ #++
+ #
+ def tap
+ yield(self)
+ self
+ end
+
+ #
+ # call-seq:
+ # obj.then {|x| block } -> an_object
+ #
+ # Yields self to the block and returns the result of the block.
+ #
+ # 3.next.then {|x| x**x }.to_s #=> "256"
+ #
+ # Good usage for +then+ is value piping in method chains:
+ #
+ # require 'open-uri'
+ # require 'json'
+ #
+ # construct_url(arguments).
+ # then {|url| open(url).read }.
+ # then {|response| JSON.parse(response) }
+ #
+ # When called without block, the method returns +Enumerator+,
+ # which can be used, for example, for conditional
+ # circuit-breaking:
+ #
+ # # meets condition, no-op
+ # 1.then.detect(&:odd?) # => 1
+ # # does not meet condition, drop value
+ # 2.then.detect(&:odd?) # => nil
+ #
+ def then
+ unless Primitive.block_given_p
+ return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
+ end
+ yield(self)
+ end
+
+ #
+ # call-seq:
+ # obj.yield_self {|x| block } -> an_object
+ #
+ # Yields self to the block and returns the result of the block.
+ #
+ # "my string".yield_self {|s| s.upcase } #=> "MY STRING"
+ #
+ # Good usage for +then+ is value piping in method chains:
+ #
+ # require 'open-uri'
+ # require 'json'
+ #
+ # construct_url(arguments).
+ # then {|url| open(url).read }.
+ # then {|response| JSON.parse(response) }
+ #
+ def yield_self
+ unless Primitive.block_given_p
+ return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
+ end
+ yield(self)
+ end
+
+ module_function
+
+ #
+ # call-seq:
+ # Float(arg, exception: true) -> float or nil
+ #
+ # Returns <i>arg</i> converted to a float. Numeric types are
+ # converted directly, and with exception to String and
+ # <code>nil</code> the rest are converted using
+ # <i>arg</i><code>.to_f</code>. Converting a String with invalid
+ # characters will result in a ArgumentError. Converting
+ # <code>nil</code> generates a TypeError. Exceptions can be
+ # suppressed by passing <code>exception: false</code>.
+ #
+ # Float(1) #=> 1.0
+ # Float("123.456") #=> 123.456
+ # Float("123.0_badstring") #=> ArgumentError: invalid value for Float(): "123.0_badstring"
+ # Float(nil) #=> TypeError: can't convert nil into Float
+ # Float("123.0_badstring", exception: false) #=> nil
+ #
+ def Float(arg, exception: true)
+ Primitive.rb_f_float(arg, exception)
+ end
+end
diff --git a/lex.c.blt b/lex.c.blt
index 7d8dd5b6e7..92a4793b00 100644
--- a/lex.c.blt
+++ b/lex.c.blt
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
/* Command-line: gperf -C -P -p -j1 -i 1 -g -o -t -N rb_reserved_word -k'1,3,$' defs/keywords */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -25,15 +25,16 @@
&& ('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
+#define gperf_offsetof(s, n) (short)offsetof(struct s##_t, s##_str##n)
#line 1 "defs/keywords"
-struct kwtable {int name, id[2], state;};
+struct kwtable {short name, id[2], state;};
const struct kwtable *rb_reserved_word(const char *, unsigned int);
#ifndef RIPPER
-static const struct kwtable *reserved_word(const char *, unsigned int);
+static const struct kwtable *reserved_word(/*const char *, unsigned int*/);
#define rb_reserved_word(str, len) reserved_word(str, len)
#line 9 "defs/keywords"
struct kwtable;
@@ -45,15 +46,15 @@ struct kwtable;
#define MAX_HASH_VALUE 50
/* maximum key range = 43, duplicates = 0 */
-#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || defined(__GNUC_STDC_INLINE__)
-inline
-#elif defined(__GNUC__)
+#ifdef __GNUC__
__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
#endif
static unsigned int
-hash (str, len)
- register const char *str;
- register unsigned int len;
+hash (register const char *str, register size_t len)
{
static const unsigned char asso_values[] =
{
@@ -84,7 +85,7 @@ hash (str, len)
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51
};
- register int hval = len;
+ register unsigned int hval = (unsigned int)len;
switch (hval)
{
@@ -96,7 +97,7 @@ hash (str, len)
hval += asso_values[(unsigned char)str[0]];
break;
}
- return hval + asso_values[(unsigned char)str[len - 1]];
+ return (unsigned int)hval + asso_values[(unsigned char)str[len - 1]];
}
struct stringpool_t
@@ -188,110 +189,102 @@ static const struct stringpool_t stringpool_contents =
"while"
};
#define stringpool ((const char *) &stringpool_contents)
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct kwtable *
-rb_reserved_word (str, len)
- register const char *str;
- register unsigned int len;
+rb_reserved_word (register const char *str, register size_t len)
{
static const struct kwtable wordlist[] =
{
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
#line 19 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str8), {keyword_break, keyword_break}, EXPR_MID},
+ {gperf_offsetof(stringpool, 8), {keyword_break, keyword_break}, EXPR_MID},
#line 25 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str9), {keyword_else, keyword_else}, EXPR_BEG},
+ {gperf_offsetof(stringpool, 9), {keyword_else, keyword_else}, EXPR_BEG},
#line 35 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str10), {keyword_nil, keyword_nil}, EXPR_END},
+ {gperf_offsetof(stringpool, 10), {keyword_nil, keyword_nil}, EXPR_END},
#line 28 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str11), {keyword_ensure, keyword_ensure}, EXPR_BEG},
+ {gperf_offsetof(stringpool, 11), {keyword_ensure, keyword_ensure}, EXPR_BEG},
#line 27 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str12), {keyword_end, keyword_end}, EXPR_END},
+ {gperf_offsetof(stringpool, 12), {keyword_end, keyword_end}, EXPR_END},
#line 44 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str13), {keyword_then, keyword_then}, EXPR_BEG},
+ {gperf_offsetof(stringpool, 13), {keyword_then, keyword_then}, EXPR_BEG},
#line 36 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str14), {keyword_not, keyword_not}, EXPR_ARG},
+ {gperf_offsetof(stringpool, 14), {keyword_not, keyword_not}, EXPR_ARG},
#line 29 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str15), {keyword_false, keyword_false}, EXPR_END},
+ {gperf_offsetof(stringpool, 15), {keyword_false, keyword_false}, EXPR_END},
#line 42 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str16), {keyword_self, keyword_self}, EXPR_END},
+ {gperf_offsetof(stringpool, 16), {keyword_self, keyword_self}, EXPR_END},
#line 26 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str17), {keyword_elsif, keyword_elsif}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 17), {keyword_elsif, keyword_elsif}, EXPR_VALUE},
#line 39 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str18), {keyword_rescue, modifier_rescue}, EXPR_MID},
+ {gperf_offsetof(stringpool, 18), {keyword_rescue, modifier_rescue}, EXPR_MID},
#line 45 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str19), {keyword_true, keyword_true}, EXPR_END},
+ {gperf_offsetof(stringpool, 19), {keyword_true, keyword_true}, EXPR_END},
#line 48 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str20), {keyword_until, modifier_until}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 20), {keyword_until, modifier_until}, EXPR_VALUE},
#line 47 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str21), {keyword_unless, modifier_unless}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 21), {keyword_unless, modifier_unless}, EXPR_VALUE},
#line 41 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str22), {keyword_return, keyword_return}, EXPR_MID},
+ {gperf_offsetof(stringpool, 22), {keyword_return, keyword_return}, EXPR_MID},
#line 22 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str23), {keyword_def, keyword_def}, EXPR_FNAME},
+ {gperf_offsetof(stringpool, 23), {keyword_def, keyword_def}, EXPR_FNAME},
#line 17 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str24), {keyword_and, keyword_and}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 24), {keyword_and, keyword_and}, EXPR_VALUE},
#line 24 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str25), {keyword_do, keyword_do}, EXPR_BEG},
+ {gperf_offsetof(stringpool, 25), {keyword_do, keyword_do}, EXPR_BEG},
#line 51 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str26), {keyword_yield, keyword_yield}, EXPR_ARG},
+ {gperf_offsetof(stringpool, 26), {keyword_yield, keyword_yield}, EXPR_ARG},
#line 30 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str27), {keyword_for, keyword_for}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 27), {keyword_for, keyword_for}, EXPR_VALUE},
#line 46 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str28), {keyword_undef, keyword_undef}, EXPR_FNAME|EXPR_FITEM},
+ {gperf_offsetof(stringpool, 28), {keyword_undef, keyword_undef}, EXPR_FNAME|EXPR_FITEM},
#line 37 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str29), {keyword_or, keyword_or}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 29), {keyword_or, keyword_or}, EXPR_VALUE},
#line 32 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str30), {keyword_in, keyword_in}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 30), {keyword_in, keyword_in}, EXPR_VALUE},
#line 49 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str31), {keyword_when, keyword_when}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 31), {keyword_when, keyword_when}, EXPR_VALUE},
#line 40 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str32), {keyword_retry, keyword_retry}, EXPR_END},
+ {gperf_offsetof(stringpool, 32), {keyword_retry, keyword_retry}, EXPR_END},
#line 31 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str33), {keyword_if, modifier_if}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 33), {keyword_if, modifier_if}, EXPR_VALUE},
#line 20 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str34), {keyword_case, keyword_case}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 34), {keyword_case, keyword_case}, EXPR_VALUE},
#line 38 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str35), {keyword_redo, keyword_redo}, EXPR_END},
+ {gperf_offsetof(stringpool, 35), {keyword_redo, keyword_redo}, EXPR_END},
#line 34 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str36), {keyword_next, keyword_next}, EXPR_MID},
+ {gperf_offsetof(stringpool, 36), {keyword_next, keyword_next}, EXPR_MID},
#line 43 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str37), {keyword_super, keyword_super}, EXPR_ARG},
+ {gperf_offsetof(stringpool, 37), {keyword_super, keyword_super}, EXPR_ARG},
#line 33 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str38), {keyword_module, keyword_module}, EXPR_VALUE},
+ {gperf_offsetof(stringpool, 38), {keyword_module, keyword_module}, EXPR_VALUE},
#line 18 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str39), {keyword_begin, keyword_begin}, EXPR_BEG},
+ {gperf_offsetof(stringpool, 39), {keyword_begin, keyword_begin}, EXPR_BEG},
#line 12 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str40), {keyword__LINE__, keyword__LINE__}, EXPR_END},
+ {gperf_offsetof(stringpool, 40), {keyword__LINE__, keyword__LINE__}, EXPR_END},
#line 13 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str41), {keyword__FILE__, keyword__FILE__}, EXPR_END},
+ {gperf_offsetof(stringpool, 41), {keyword__FILE__, keyword__FILE__}, EXPR_END},
#line 11 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str42), {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
+ {gperf_offsetof(stringpool, 42), {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
#line 15 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str43), {keyword_END, keyword_END}, EXPR_END},
+ {gperf_offsetof(stringpool, 43), {keyword_END, keyword_END}, EXPR_END},
#line 16 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str44), {keyword_alias, keyword_alias}, EXPR_FNAME|EXPR_FITEM},
+ {gperf_offsetof(stringpool, 44), {keyword_alias, keyword_alias}, EXPR_FNAME|EXPR_FITEM},
#line 14 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str45), {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
+ {gperf_offsetof(stringpool, 45), {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
#line 23 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str46), {keyword_defined, keyword_defined}, EXPR_ARG},
+ {gperf_offsetof(stringpool, 46), {keyword_defined, keyword_defined}, EXPR_ARG},
#line 21 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str47), {keyword_class, keyword_class}, EXPR_CLASS},
+ {gperf_offsetof(stringpool, 47), {keyword_class, keyword_class}, EXPR_CLASS},
{-1}, {-1},
#line 50 "defs/keywords"
- {(int)offsetof(struct stringpool_t, stringpool_str50), {keyword_while, modifier_while}, EXPR_VALUE}
+ {gperf_offsetof(stringpool, 50), {keyword_while, modifier_while}, EXPR_VALUE}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = hash (str, len);
+ register unsigned int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register int o = wordlist[key].name;
if (o >= 0)
diff --git a/lib/.document b/lib/.document
new file mode 100644
index 0000000000..0d612d1077
--- /dev/null
+++ b/lib/.document
@@ -0,0 +1,26 @@
+# Add files to this as they become documented
+
+*.rb
+
+# bundler # not in RDoc
+cgi
+csv
+drb
+forwardable
+irb
+matrix
+net
+optparse
+racc/*.rb
+racc/rdoc
+rdoc
+rexml
+rinda
+rss
+rubygems
+scanf.rb
+shell
+unicode_normalize
+uri
+webrick
+yaml
diff --git a/lib/English.gemspec b/lib/English.gemspec
new file mode 100644
index 0000000000..ad6eb7aced
--- /dev/null
+++ b/lib/English.gemspec
@@ -0,0 +1,24 @@
+Gem::Specification.new do |spec|
+ spec.name = "english"
+ spec.version = "0.7.1"
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Require 'English.rb' to reference global variables with less cryptic names.}
+ spec.description = %q{Require 'English.rb' to reference global variables with less cryptic names.}
+ spec.homepage = "https://github.com/ruby/English"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/English.rb b/lib/English.rb
index a4f5bb6620..ec90ff10cd 100644
--- a/lib/English.rb
+++ b/lib/English.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# Include the English library file in a Ruby script, and you can
-# reference the global variables such as \VAR{\$\_} using less
-# cryptic names, listed in the following table.% \vref{tab:english}.
+# reference the global variables such as <tt>$_</tt> using less
+# cryptic names, listed below.
#
# Without 'English':
#
@@ -52,45 +52,43 @@ module English end if false
alias $ERROR_INFO $!
# The stack backtrace generated by the last
-# exception. <tt>See Kernel.caller</tt> for details. Thread local.
+# exception. See Kernel#caller for details. Thread local.
alias $ERROR_POSITION $@
-# The default separator pattern used by <tt>String.split</tt>. May be
-# set from the command line using the <tt>-F</tt> flag.
+# The default separator pattern used by String#split. May be set from
+# the command line using the <tt>-F</tt> flag.
alias $FS $;
-# The default separator pattern used by <tt>String.split</tt>. May be
-# set from the command line using the <tt>-F</tt> flag.
+# The default separator pattern used by String#split. May be set from
+# the command line using the <tt>-F</tt> flag.
alias $FIELD_SEPARATOR $;
# The separator string output between the parameters to methods such
-# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,
-# which adds no text.
+# as Kernel#print and Array#join. Defaults to +nil+, which adds no
+# text.
alias $OFS $,
# The separator string output between the parameters to methods such
-# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,
-# which adds no text.
+# as Kernel#print and Array#join. Defaults to +nil+, which adds no
+# text.
alias $OUTPUT_FIELD_SEPARATOR $,
# The input record separator (newline by default). This is the value
-# that routines such as <tt>Kernel.gets</tt> use to determine record
+# that routines such as Kernel#gets use to determine record
# boundaries. If set to +nil+, +gets+ will read the entire file.
alias $RS $/
# The input record separator (newline by default). This is the value
-# that routines such as <tt>Kernel.gets</tt> use to determine record
+# that routines such as Kernel#gets use to determine record
# boundaries. If set to +nil+, +gets+ will read the entire file.
alias $INPUT_RECORD_SEPARATOR $/
# The string appended to the output of every call to methods such as
-# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is
-# +nil+.
+# Kernel#print and IO#write. The default value is +nil+.
alias $ORS $\
# The string appended to the output of every call to methods such as
-# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is
-# +nil+.
+# Kernel#print and IO#write. The default value is +nil+.
alias $OUTPUT_RECORD_SEPARATOR $\
# The number of the last line read from the current input file.
@@ -99,14 +97,14 @@ alias $INPUT_LINE_NUMBER $.
# The number of the last line read from the current input file.
alias $NR $.
-# The last line read by <tt>Kernel.gets</tt> or
-# <tt>Kernel.readline</tt>. Many string-related functions in the
-# +Kernel+ module operate on <tt>$_</tt> by default. The variable is
+# The last line read by Kernel#gets or
+# Kernel#readline. Many string-related functions in the
+# Kernel module operate on <tt>$_</tt> by default. The variable is
# local to the current scope. Thread local.
alias $LAST_READ_LINE $_
-# The destination of output for <tt>Kernel.print</tt>
-# and <tt>Kernel.printf</tt>. The default value is
+# The destination of output for Kernel#print
+# and Kernel#printf. The default value is
# <tt>$stdout</tt>.
alias $DEFAULT_OUTPUT $>
@@ -115,7 +113,7 @@ alias $DEFAULT_OUTPUT $>
# given as command-line arguments, or <tt>$stdin</tt>
# (in the case where there are no
# arguments). <tt>$<</tt> supports methods similar to a
-# +File+ object:
+# File object:
# +inmode+, +close+,
# <tt>closed?</tt>, +each+,
# <tt>each_byte</tt>, <tt>each_line</tt>,
@@ -129,8 +127,8 @@ alias $DEFAULT_OUTPUT $>
# +rewind+, +seek+, +skip+,
# +tell+, <tt>to_a</tt>, <tt>to_i</tt>,
# <tt>to_io</tt>, <tt>to_s</tt>, along with the
-# methods in +Enumerable+. The method +file+
-# returns a +File+ object for the file currently
+# methods in Enumerable. The method +file+
+# returns a File object for the file currently
# being read. This may change as <tt>$<</tt> reads
# through the files on the command line. Read only.
alias $DEFAULT_INPUT $<
diff --git a/lib/abbrev.gemspec b/lib/abbrev.gemspec
new file mode 100644
index 0000000000..4edf0edaa3
--- /dev/null
+++ b/lib/abbrev.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "abbrev"
+ spec.version = "0.1.0"
+ spec.authors = ["Akinori MUSHA"]
+ spec.email = ["knu@idaemons.org"]
+
+ spec.summary = %q{Calculates a set of unique abbreviations for a given set of strings}
+ spec.description = %q{Calculates a set of unique abbreviations for a given set of strings}
+ spec.homepage = "https://github.com/ruby/abbrev"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/base64.gemspec b/lib/base64.gemspec
new file mode 100644
index 0000000000..331ecc4491
--- /dev/null
+++ b/lib/base64.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "base64"
+ spec.version = "0.1.0"
+ spec.authors = ["Yusuke Endoh"]
+ spec.email = ["mame@ruby-lang.org"]
+
+ spec.summary = %q{Support for encoding and decoding binary data using a Base64 representation.}
+ spec.description = %q{Support for encoding and decoding binary data using a Base64 representation.}
+ spec.homepage = "https://github.com/ruby/base64"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/base64.rb b/lib/base64.rb
index 24f0b02966..5c8df841f1 100644
--- a/lib/base64.rb
+++ b/lib/base64.rb
@@ -81,8 +81,9 @@ module Base64
# Note that the result can still contain '='.
# You can remove the padding by setting +padding+ as false.
def urlsafe_encode64(bin, padding: true)
- str = strict_encode64(bin).tr("+/", "-_")
- str = str.delete("=") unless padding
+ str = strict_encode64(bin)
+ str.tr!("+/", "-_")
+ str.delete!("=") unless padding
str
end
diff --git a/lib/benchmark.rb b/lib/benchmark.rb
index 8d768b631e..5ce9710586 100644
--- a/lib/benchmark.rb
+++ b/lib/benchmark.rb
@@ -439,6 +439,9 @@ module Benchmark
#
# An in-place version of #add.
+ # Changes the times of this Tms object by making it the sum of the times
+ # for this Tms object, plus the time required to execute
+ # the code block (+blk+).
#
def add!(&blk)
t = Benchmark.measure(&blk)
@@ -452,7 +455,7 @@ module Benchmark
#
# Returns a new Tms object obtained by memberwise summation
- # of the individual times for this Tms object with those of the other
+ # of the individual times for this Tms object with those of the +other+
# Tms object.
# This method and #/() are useful for taking statistics.
#
@@ -460,20 +463,20 @@ module Benchmark
#
# Returns a new Tms object obtained by memberwise subtraction
- # of the individual times for the other Tms object from those of this
+ # of the individual times for the +other+ Tms object from those of this
# Tms object.
#
def -(other); memberwise(:-, other) end
#
# Returns a new Tms object obtained by memberwise multiplication
- # of the individual times for this Tms object by _x_.
+ # of the individual times for this Tms object by +x+.
#
def *(x); memberwise(:*, x) end
#
# Returns a new Tms object obtained by memberwise division
- # of the individual times for this Tms object by _x_.
+ # of the individual times for this Tms object by +x+.
# This method and #+() are useful for taking statistics.
#
def /(x); memberwise(:/, x) end
@@ -529,7 +532,7 @@ module Benchmark
#
# Returns a new Tms object obtained by memberwise operation +op+
# of the individual times for this Tms object with those of the other
- # Tms object.
+ # Tms object (+x+).
#
# +op+ can be a mathematical operation such as <tt>+</tt>, <tt>-</tt>,
# <tt>*</tt>, <tt>/</tt>
diff --git a/lib/benchmark/benchmark.gemspec b/lib/benchmark/benchmark.gemspec
new file mode 100644
index 0000000000..031ccbe34a
--- /dev/null
+++ b/lib/benchmark/benchmark.gemspec
@@ -0,0 +1,29 @@
+begin
+ require_relative "lib/benchmark/version"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "benchmark"
+ spec.version = Benchmark::VERSION
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{a performance benchmarking library}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/benchmark"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/benchmark/version.rb b/lib/benchmark/version.rb
new file mode 100644
index 0000000000..90d1a3900c
--- /dev/null
+++ b/lib/benchmark/version.rb
@@ -0,0 +1,3 @@
+module Benchmark
+ VERSION = "0.1.1"
+end
diff --git a/lib/bundler.gemspec b/lib/bundler.gemspec
deleted file mode 100644
index 49f82ba3cb..0000000000
--- a/lib/bundler.gemspec
+++ /dev/null
@@ -1,251 +0,0 @@
-# coding: utf-8
-# frozen_string_literal: true
-lib = File.expand_path("../lib/", __FILE__)
-$:.unshift lib unless $:.include?(lib)
-require "bundler/version"
-
-Gem::Specification.new do |s|
- s.name = "bundler"
- s.version = Bundler::VERSION
- s.license = "MIT"
- s.authors = [
- "André Arko", "Samuel Giddins", "Chris Morris", "James Wen", "Tim Moore",
- "André Medeiros", "Jessica Lynn Suttles", "Terence Lee", "Carl Lerche",
- "Yehuda Katz"
- ]
- s.email = ["team@bundler.io"]
- s.homepage = "http://bundler.io"
- s.summary = "The best way to manage your application's dependencies"
- s.description = "Bundler manages an application's dependencies through its entire life, across many machines, systematically and repeatably"
-
- if s.respond_to?(:metadata=)
- s.metadata = {
- "bug_tracker_uri" => "http://github.com/bundler/bundler/issues",
- "changelog_uri" => "https://github.com/bundler/bundler/blob/master/CHANGELOG.md",
- "homepage_uri" => "https://bundler.io/",
- "source_code_uri" => "http://github.com/bundler/bundler/",
- }
- end
-
- s.required_ruby_version = ">= 1.8.7"
- s.required_rubygems_version = ">= 1.3.6"
-
- s.add_development_dependency "automatiek", "~> 0.1.0"
- s.add_development_dependency "mustache", "0.99.6"
- s.add_development_dependency "rake", "~> 10.0"
- s.add_development_dependency "rdiscount", "~> 2.2"
- s.add_development_dependency "ronn", "~> 0.7.3"
- s.add_development_dependency "rspec", "~> 3.5"
-
- s.files = [
- "lib/bundler.gemspec",
- "bin/bundle",
- "bin/bundle_ruby",
- "bin/bundler",
- "lib/bundler.rb",
- "lib/bundler/capistrano.rb",
- "lib/bundler/cli.rb",
- "lib/bundler/cli/add.rb",
- "lib/bundler/cli/binstubs.rb",
- "lib/bundler/cli/cache.rb",
- "lib/bundler/cli/check.rb",
- "lib/bundler/cli/clean.rb",
- "lib/bundler/cli/common.rb",
- "lib/bundler/cli/config.rb",
- "lib/bundler/cli/console.rb",
- "lib/bundler/cli/doctor.rb",
- "lib/bundler/cli/exec.rb",
- "lib/bundler/cli/gem.rb",
- "lib/bundler/cli/info.rb",
- "lib/bundler/cli/init.rb",
- "lib/bundler/cli/inject.rb",
- "lib/bundler/cli/install.rb",
- "lib/bundler/cli/issue.rb",
- "lib/bundler/cli/lock.rb",
- "lib/bundler/cli/open.rb",
- "lib/bundler/cli/outdated.rb",
- "lib/bundler/cli/package.rb",
- "lib/bundler/cli/platform.rb",
- "lib/bundler/cli/plugin.rb",
- "lib/bundler/cli/pristine.rb",
- "lib/bundler/cli/show.rb",
- "lib/bundler/cli/update.rb",
- "lib/bundler/cli/viz.rb",
- "lib/bundler/compact_index_client.rb",
- "lib/bundler/compact_index_client/cache.rb",
- "lib/bundler/compact_index_client/updater.rb",
- "lib/bundler/constants.rb",
- "lib/bundler/current_ruby.rb",
- "lib/bundler/definition.rb",
- "lib/bundler/dep_proxy.rb",
- "lib/bundler/dependency.rb",
- "lib/bundler/deployment.rb",
- "lib/bundler/deprecate.rb",
- "lib/bundler/dsl.rb",
- "lib/bundler/endpoint_specification.rb",
- "lib/bundler/env.rb",
- "lib/bundler/environment_preserver.rb",
- "lib/bundler/errors.rb",
- "lib/bundler/feature_flag.rb",
- "lib/bundler/fetcher.rb",
- "lib/bundler/fetcher/base.rb",
- "lib/bundler/fetcher/compact_index.rb",
- "lib/bundler/fetcher/dependency.rb",
- "lib/bundler/fetcher/downloader.rb",
- "lib/bundler/fetcher/index.rb",
- "lib/bundler/friendly_errors.rb",
- "lib/bundler/gem_helper.rb",
- "lib/bundler/gem_helpers.rb",
- "lib/bundler/gem_remote_fetcher.rb",
- "lib/bundler/gem_tasks.rb",
- "lib/bundler/gem_version_promoter.rb",
- "lib/bundler/gemdeps.rb",
- "lib/bundler/graph.rb",
- "lib/bundler/index.rb",
- "lib/bundler/injector.rb",
- "lib/bundler/inline.rb",
- "lib/bundler/installer.rb",
- "lib/bundler/installer/gem_installer.rb",
- "lib/bundler/installer/parallel_installer.rb",
- "lib/bundler/installer/standalone.rb",
- "lib/bundler/lazy_specification.rb",
- "lib/bundler/lockfile_parser.rb",
- "lib/bundler/match_platform.rb",
- "lib/bundler/mirror.rb",
- "lib/bundler/plugin.rb",
- "lib/bundler/plugin/api.rb",
- "lib/bundler/plugin/api/source.rb",
- "lib/bundler/plugin/dsl.rb",
- "lib/bundler/plugin/index.rb",
- "lib/bundler/plugin/installer.rb",
- "lib/bundler/plugin/installer/git.rb",
- "lib/bundler/plugin/installer/rubygems.rb",
- "lib/bundler/plugin/source_list.rb",
- "lib/bundler/psyched_yaml.rb",
- "lib/bundler/remote_specification.rb",
- "lib/bundler/resolver.rb",
- "lib/bundler/retry.rb",
- "lib/bundler/ruby_dsl.rb",
- "lib/bundler/ruby_version.rb",
- "lib/bundler/rubygems_ext.rb",
- "lib/bundler/rubygems_gem_installer.rb",
- "lib/bundler/rubygems_integration.rb",
- "lib/bundler/runtime.rb",
- "lib/bundler/settings.rb",
- "lib/bundler/setup.rb",
- "lib/bundler/shared_helpers.rb",
- "lib/bundler/similarity_detector.rb",
- "lib/bundler/source.rb",
- "lib/bundler/source/gemspec.rb",
- "lib/bundler/source/git.rb",
- "lib/bundler/source/git/git_proxy.rb",
- "lib/bundler/source/path.rb",
- "lib/bundler/source/path/installer.rb",
- "lib/bundler/source/rubygems.rb",
- "lib/bundler/source/rubygems/remote.rb",
- "lib/bundler/source_list.rb",
- "lib/bundler/spec_set.rb",
- "lib/bundler/ssl_certs/.document",
- "lib/bundler/ssl_certs/certificate_manager.rb",
- "lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem",
- "lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem",
- "lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem",
- "lib/bundler/stub_specification.rb",
- "lib/bundler/templates/Executable",
- "lib/bundler/templates/Executable.standalone",
- "lib/bundler/templates/Gemfile",
- "lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt",
- "lib/bundler/templates/newgem/Gemfile.tt",
- "lib/bundler/templates/newgem/LICENSE.txt.tt",
- "lib/bundler/templates/newgem/README.md.tt",
- "lib/bundler/templates/newgem/Rakefile.tt",
- "lib/bundler/templates/newgem/bin/console.tt",
- "lib/bundler/templates/newgem/bin/setup.tt",
- "lib/bundler/templates/newgem/exe/newgem.tt",
- "lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt",
- "lib/bundler/templates/newgem/ext/newgem/newgem.c.tt",
- "lib/bundler/templates/newgem/ext/newgem/newgem.h.tt",
- "lib/bundler/templates/newgem/gitignore.tt",
- "lib/bundler/templates/newgem/lib/newgem.rb.tt",
- "lib/bundler/templates/newgem/lib/newgem/version.rb.tt",
- "lib/bundler/templates/newgem/newgem.gemspec.tt",
- "lib/bundler/templates/newgem/rspec.tt",
- "lib/bundler/templates/newgem/spec/newgem_spec.rb.tt",
- "lib/bundler/templates/newgem/spec/spec_helper.rb.tt",
- "lib/bundler/templates/newgem/test/newgem_test.rb.tt",
- "lib/bundler/templates/newgem/test/test_helper.rb.tt",
- "lib/bundler/templates/newgem/travis.yml.tt",
- "lib/bundler/ui.rb",
- "lib/bundler/ui/rg_proxy.rb",
- "lib/bundler/ui/shell.rb",
- "lib/bundler/ui/silent.rb",
- "lib/bundler/uri_credentials_filter.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/errors.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb",
- "lib/bundler/vendor/molinillo/lib/molinillo/state.rb",
- "lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb",
- "lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb",
- "lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb",
- "lib/bundler/vendor/thor/lib/thor.rb",
- "lib/bundler/vendor/thor/lib/thor/actions.rb",
- "lib/bundler/vendor/thor/lib/thor/actions/create_file.rb",
- "lib/bundler/vendor/thor/lib/thor/actions/create_link.rb",
- "lib/bundler/vendor/thor/lib/thor/actions/directory.rb",
- "lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb",
- "lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb",
- "lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb",
- "lib/bundler/vendor/thor/lib/thor/base.rb",
- "lib/bundler/vendor/thor/lib/thor/command.rb",
- "lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb",
- "lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb",
- "lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb",
- "lib/bundler/vendor/thor/lib/thor/error.rb",
- "lib/bundler/vendor/thor/lib/thor/group.rb",
- "lib/bundler/vendor/thor/lib/thor/invocation.rb",
- "lib/bundler/vendor/thor/lib/thor/line_editor.rb",
- "lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb",
- "lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb",
- "lib/bundler/vendor/thor/lib/thor/parser.rb",
- "lib/bundler/vendor/thor/lib/thor/parser/argument.rb",
- "lib/bundler/vendor/thor/lib/thor/parser/arguments.rb",
- "lib/bundler/vendor/thor/lib/thor/parser/option.rb",
- "lib/bundler/vendor/thor/lib/thor/parser/options.rb",
- "lib/bundler/vendor/thor/lib/thor/rake_compat.rb",
- "lib/bundler/vendor/thor/lib/thor/runner.rb",
- "lib/bundler/vendor/thor/lib/thor/shell.rb",
- "lib/bundler/vendor/thor/lib/thor/shell/basic.rb",
- "lib/bundler/vendor/thor/lib/thor/shell/color.rb",
- "lib/bundler/vendor/thor/lib/thor/shell/html.rb",
- "lib/bundler/vendor/thor/lib/thor/util.rb",
- "lib/bundler/vendor/thor/lib/thor/version.rb",
- "lib/bundler/vendored_molinillo.rb",
- "lib/bundler/vendored_persistent.rb",
- "lib/bundler/vendored_thor.rb",
- "lib/bundler/version.rb",
- "lib/bundler/version_ranges.rb",
- "lib/bundler/vlad.rb",
- "lib/bundler/worker.rb",
- "lib/bundler/yaml_serializer.rb"
- ]
-
- s.bindir = "exe"
- s.executables = %w(bundle bundler)
- s.require_paths = ["lib"]
-end
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 88822f8f1a..1ab87ac299 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -1,81 +1,103 @@
# frozen_string_literal: true
-require "fileutils"
+
+require_relative "bundler/vendored_fileutils"
require "pathname"
require "rbconfig"
-require "thread"
-require "tmpdir"
-
-require "bundler/errors"
-require "bundler/environment_preserver"
-require "bundler/plugin"
-require "bundler/rubygems_ext"
-require "bundler/rubygems_integration"
-require "bundler/version"
-require "bundler/constants"
-require "bundler/current_ruby"
+require_relative "bundler/errors"
+require_relative "bundler/environment_preserver"
+require_relative "bundler/plugin"
+require_relative "bundler/rubygems_ext"
+require_relative "bundler/rubygems_integration"
+require_relative "bundler/version"
+require_relative "bundler/constants"
+require_relative "bundler/current_ruby"
+require_relative "bundler/build_metadata"
+
+# Bundler provides a consistent environment for Ruby projects by
+# tracking and installing the exact gems and versions that are needed.
+#
+# Since Ruby 2.6, Bundler is a part of Ruby's standard library.
+#
+# Bunder is used by creating _gemfiles_ listing all the project dependencies
+# and (optionally) their versions and then using
+#
+# require 'bundler/setup'
+#
+# or Bundler.setup to setup environment where only specified gems and their
+# specified versions could be used.
+#
+# See {Bundler website}[https://bundler.io/docs.html] for extensive documentation
+# on gemfiles creation and Bundler usage.
+#
+# As a standard library inside project, Bundler could be used for introspection
+# of loaded and required modules.
+#
module Bundler
- environment_preserver = EnvironmentPreserver.new(ENV, %w(PATH GEM_PATH))
+ environment_preserver = EnvironmentPreserver.from_env
ORIGINAL_ENV = environment_preserver.restore
- ENV.replace(environment_preserver.backup)
- SUDO_MUTEX = Mutex.new
-
- autoload :Definition, "bundler/definition"
- autoload :Dependency, "bundler/dependency"
- autoload :DepProxy, "bundler/dep_proxy"
- autoload :Deprecate, "bundler/deprecate"
- autoload :Dsl, "bundler/dsl"
- autoload :EndpointSpecification, "bundler/endpoint_specification"
- autoload :Env, "bundler/env"
- autoload :Fetcher, "bundler/fetcher"
- autoload :FeatureFlag, "bundler/feature_flag"
- autoload :GemHelper, "bundler/gem_helper"
- autoload :GemHelpers, "bundler/gem_helpers"
- autoload :GemRemoteFetcher, "bundler/gem_remote_fetcher"
- autoload :GemVersionPromoter, "bundler/gem_version_promoter"
- autoload :Graph, "bundler/graph"
- autoload :Index, "bundler/index"
- autoload :Injector, "bundler/injector"
- autoload :Installer, "bundler/installer"
- autoload :LazySpecification, "bundler/lazy_specification"
- autoload :LockfileParser, "bundler/lockfile_parser"
- autoload :MatchPlatform, "bundler/match_platform"
- autoload :RemoteSpecification, "bundler/remote_specification"
- autoload :Resolver, "bundler/resolver"
- autoload :Retry, "bundler/retry"
- autoload :RubyDsl, "bundler/ruby_dsl"
- autoload :RubyGemsGemInstaller, "bundler/rubygems_gem_installer"
- autoload :RubyVersion, "bundler/ruby_version"
- autoload :Runtime, "bundler/runtime"
- autoload :Settings, "bundler/settings"
- autoload :SharedHelpers, "bundler/shared_helpers"
- autoload :Source, "bundler/source"
- autoload :SourceList, "bundler/source_list"
- autoload :SpecSet, "bundler/spec_set"
- autoload :StubSpecification, "bundler/stub_specification"
- autoload :UI, "bundler/ui"
- autoload :URICredentialsFilter, "bundler/uri_credentials_filter"
- autoload :VersionRanges, "bundler/version_ranges"
+ environment_preserver.replace_with_backup
+ SUDO_MUTEX = Thread::Mutex.new
+
+ autoload :Definition, File.expand_path("bundler/definition", __dir__)
+ autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
+ autoload :DepProxy, File.expand_path("bundler/dep_proxy", __dir__)
+ autoload :Deprecate, File.expand_path("bundler/deprecate", __dir__)
+ autoload :Digest, File.expand_path("bundler/digest", __dir__)
+ autoload :Dsl, File.expand_path("bundler/dsl", __dir__)
+ autoload :EndpointSpecification, File.expand_path("bundler/endpoint_specification", __dir__)
+ autoload :Env, File.expand_path("bundler/env", __dir__)
+ autoload :Fetcher, File.expand_path("bundler/fetcher", __dir__)
+ autoload :FeatureFlag, File.expand_path("bundler/feature_flag", __dir__)
+ autoload :GemHelper, File.expand_path("bundler/gem_helper", __dir__)
+ autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__)
+ autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__)
+ autoload :Graph, File.expand_path("bundler/graph", __dir__)
+ autoload :Index, File.expand_path("bundler/index", __dir__)
+ autoload :Injector, File.expand_path("bundler/injector", __dir__)
+ autoload :Installer, File.expand_path("bundler/installer", __dir__)
+ autoload :LazySpecification, File.expand_path("bundler/lazy_specification", __dir__)
+ autoload :LockfileParser, File.expand_path("bundler/lockfile_parser", __dir__)
+ autoload :MatchPlatform, File.expand_path("bundler/match_platform", __dir__)
+ autoload :ProcessLock, File.expand_path("bundler/process_lock", __dir__)
+ autoload :RemoteSpecification, File.expand_path("bundler/remote_specification", __dir__)
+ autoload :Resolver, File.expand_path("bundler/resolver", __dir__)
+ autoload :Retry, File.expand_path("bundler/retry", __dir__)
+ autoload :RubyDsl, File.expand_path("bundler/ruby_dsl", __dir__)
+ autoload :RubyVersion, File.expand_path("bundler/ruby_version", __dir__)
+ autoload :Runtime, File.expand_path("bundler/runtime", __dir__)
+ autoload :Settings, File.expand_path("bundler/settings", __dir__)
+ autoload :SharedHelpers, File.expand_path("bundler/shared_helpers", __dir__)
+ autoload :Source, File.expand_path("bundler/source", __dir__)
+ autoload :SourceList, File.expand_path("bundler/source_list", __dir__)
+ autoload :SourceMap, File.expand_path("bundler/source_map", __dir__)
+ autoload :SpecSet, File.expand_path("bundler/spec_set", __dir__)
+ autoload :StubSpecification, File.expand_path("bundler/stub_specification", __dir__)
+ autoload :UI, File.expand_path("bundler/ui", __dir__)
+ autoload :URICredentialsFilter, File.expand_path("bundler/uri_credentials_filter", __dir__)
+ autoload :VersionRanges, File.expand_path("bundler/version_ranges", __dir__)
class << self
- attr_writer :bundle_path
-
def configure
@configured ||= configure_gem_home_and_path
end
def ui
- (defined?(@ui) && @ui) || (self.ui = UI::Silent.new)
+ (defined?(@ui) && @ui) || (self.ui = UI::Shell.new)
end
def ui=(ui)
- Bundler.rubygems.ui = ui ? UI::RGProxy.new(ui) : nil
+ Bundler.rubygems.ui = UI::RGProxy.new(ui)
@ui = ui
end
# Returns absolute path of where gems are installed on the filesystem.
def bundle_path
- @bundle_path ||= Pathname.new(settings.path).expand_path(root)
+ @bundle_path ||= Pathname.new(configured_bundle_path.path).expand_path(root)
+ end
+
+ def configured_bundle_path
+ @configured_bundle_path ||= settings.path.tap(&:validate!)
end
# Returns absolute location of where binstubs are installed to.
@@ -88,6 +110,33 @@ module Bundler
end
end
+ # Turns on the Bundler runtime. After +Bundler.setup+ call, all +load+ or
+ # +require+ of the gems would be allowed only if they are part of
+ # the Gemfile or Ruby's standard library. If the versions specified
+ # in Gemfile, only those versions would be loaded.
+ #
+ # Assuming Gemfile
+ #
+ # gem 'first_gem', '= 1.0'
+ # group :test do
+ # gem 'second_gem', '= 1.0'
+ # end
+ #
+ # The code using Bundler.setup works as follows:
+ #
+ # require 'third_gem' # allowed, required from global gems
+ # require 'first_gem' # allowed, loads the last installed version
+ # Bundler.setup
+ # require 'fourth_gem' # fails with LoadError
+ # require 'second_gem' # loads exactly version 1.0
+ #
+ # +Bundler.setup+ can be called only once, all subsequent calls are no-op.
+ #
+ # If _groups_ list is provided, only gems from specified groups would
+ # be allowed (gems specified outside groups belong to special +:default+ group).
+ #
+ # To require all gems from Gemfile (or only some groups), see Bundler.require.
+ #
def setup(*groups)
# Return if all groups are already loaded
return @setup if defined?(@setup) && @setup
@@ -104,6 +153,24 @@ module Bundler
end
end
+ # Setups Bundler environment (see Bundler.setup) if it is not already set,
+ # and loads all gems from groups specified. Unlike ::setup, can be called
+ # multiple times with different groups (if they were allowed by setup).
+ #
+ # Assuming Gemfile
+ #
+ # gem 'first_gem', '= 1.0'
+ # group :test do
+ # gem 'second_gem', '= 1.0'
+ # end
+ #
+ # The code will work as follows:
+ #
+ # Bundler.setup # allow all groups
+ # Bundler.require(:default) # requires only first_gem
+ # # ...later
+ # Bundler.require(:test) # requires second_gem
+ #
def require(*groups)
setup(*groups).require(*groups)
end
@@ -113,7 +180,7 @@ module Bundler
end
def environment
- SharedHelpers.major_deprecation "Bundler.environment has been removed in favor of Bundler.load"
+ SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load", :print_caller_location => true
load
end
@@ -130,6 +197,12 @@ module Bundler
end
end
+ def frozen_bundle?
+ frozen = settings[:deployment]
+ frozen ||= settings[:frozen]
+ frozen
+ end
+
def locked_gems
@locked_gems ||=
if defined?(@definition) && @definition
@@ -140,25 +213,33 @@ module Bundler
end
end
+ def most_specific_locked_platform?(platform)
+ return false unless defined?(@definition) && @definition
+
+ definition.most_specific_locked_platform == platform
+ end
+
def ruby_scope
- "#{Bundler.rubygems.ruby_engine}/#{Bundler.rubygems.config_map[:ruby_version]}"
+ "#{Bundler.rubygems.ruby_engine}/#{RbConfig::CONFIG["ruby_version"]}"
end
def user_home
@user_home ||= begin
home = Bundler.rubygems.user_home
+ bundle_home = home ? File.join(home, ".bundle") : nil
warning = if home.nil?
"Your home directory is not set."
elsif !File.directory?(home)
"`#{home}` is not a directory."
- elsif !File.writable?(home)
+ elsif !File.writable?(home) && (!File.directory?(bundle_home) || !File.writable?(bundle_home))
"`#{home}` is not writable."
end
if warning
- user_home = tmp_home_path(Etc.getlogin, warning)
- Bundler.ui.warn "#{warning}\nBundler will use `#{user_home}' as your home directory temporarily.\n"
+ Bundler.ui.warn "#{warning}\n"
+ user_home = tmp_home_path
+ Bundler.ui.warn "Bundler will use `#{user_home}' as your home directory temporarily.\n"
user_home
else
Pathname.new(home)
@@ -166,22 +247,26 @@ module Bundler
end
end
- def tmp_home_path(login, warning)
- login ||= "unknown"
- path = Pathname.new(Dir.tmpdir).join("bundler", "home")
- SharedHelpers.filesystem_access(path) do |tmp_home_path|
- unless tmp_home_path.exist?
- tmp_home_path.mkpath
- tmp_home_path.chmod(0o777)
- end
- tmp_home_path.join(login).tap(&:mkpath)
+ def user_bundle_path(dir = "home")
+ env_var, fallback = case dir
+ when "home"
+ ["BUNDLE_USER_HOME", proc { Pathname.new(user_home).join(".bundle") }]
+ when "cache"
+ ["BUNDLE_USER_CACHE", proc { user_bundle_path.join("cache") }]
+ when "config"
+ ["BUNDLE_USER_CONFIG", proc { user_bundle_path.join("config") }]
+ when "plugin"
+ ["BUNDLE_USER_PLUGIN", proc { user_bundle_path.join("plugin") }]
+ else
+ raise BundlerError, "Unknown user path requested: #{dir}"
end
- rescue => e
- raise e.exception("#{warning}\nBundler also failed to create a temporary home directory at `#{path}':\n#{e}")
+ # `fallback` will already be a Pathname, but Pathname.new() is
+ # idempotent so it's OK
+ Pathname.new(ENV.fetch(env_var, &fallback))
end
- def user_bundle_path
- Pathname.new(user_home).join(".bundle")
+ def user_cache
+ user_bundle_path("cache")
end
def home
@@ -196,17 +281,9 @@ module Bundler
bundle_path.join("specifications")
end
- def cache
- bundle_path.join("cache/bundler")
- end
-
- def user_cache
- user_bundle_path.join("cache")
- end
-
def root
@root ||= begin
- default_gemfile.dirname.expand_path
+ SharedHelpers.root
rescue GemfileNotFound
bundle_dir = default_bundle_dir
raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir
@@ -215,8 +292,14 @@ module Bundler
end
def app_config_path
- if ENV["BUNDLE_APP_CONFIG"]
- Pathname.new(ENV["BUNDLE_APP_CONFIG"]).expand_path(root)
+ if app_config = ENV["BUNDLE_APP_CONFIG"]
+ app_config_pathname = Pathname.new(app_config)
+
+ if app_config_pathname.absolute?
+ app_config_pathname
+ else
+ app_config_pathname.expand_path(root)
+ end
else
root.join(".bundle")
end
@@ -224,10 +307,11 @@ module Bundler
def app_cache(custom_path = nil)
path = custom_path || root
- path.join(settings.app_cache_path)
+ Pathname.new(path).join(settings.app_cache_path)
end
def tmp(name = Process.pid.to_s)
+ Kernel.send(:require, "tmpdir")
Pathname.new(Dir.mktmpdir(["bundler", name]))
end
@@ -237,7 +321,7 @@ module Bundler
message = <<EOF
It is a security vulnerability to allow your home directory to be world-writable, and bundler can not continue.
You should probably consider fixing this issue by running `chmod o-w ~` on *nix.
-Please refer to http://ruby-doc.org/stdlib-2.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
+Please refer to https://ruby-doc.org/stdlib-2.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
EOF
File.world_writable?(path) ? Bundler.ui.warn(message) : raise
raise PathError, "Please fix the world-writable issue with your #{path} directory"
@@ -254,10 +338,20 @@ EOF
ORIGINAL_ENV.clone
end
- # @deprecated Use `original_env` instead
- # @return [Hash] Environment with all bundler-related variables removed
+ # @deprecated Use `unbundled_env` instead
def clean_env
- Bundler::SharedHelpers.major_deprecation("`Bundler.clean_env` has weird edge cases, use `.original_env` instead")
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.clean_env` has been deprecated in favor of `Bundler.unbundled_env`. " \
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env`",
+ :print_caller_location => true
+ )
+
+ unbundled_env
+ end
+
+ # @return [Hash] Environment with all bundler-related variables removed
+ def unbundled_env
env = original_env
if env.key?("BUNDLER_ORIG_MANPATH")
@@ -267,7 +361,10 @@ EOF
env.delete_if {|k, _| k[0, 7] == "BUNDLE_" }
if env.key?("RUBYOPT")
- env["RUBYOPT"] = env["RUBYOPT"].sub "-rbundler/setup", ""
+ rubyopt = env["RUBYOPT"].split(" ")
+ rubyopt.delete("-r#{File.expand_path("bundler/setup", __dir__)}")
+ rubyopt.delete("-rbundler/setup")
+ env["RUBYOPT"] = rubyopt.join(" ")
end
if env.key?("RUBYLIB")
@@ -279,24 +376,74 @@ EOF
env
end
+ # Run block with environment present before Bundler was activated
def with_original_env
with_env(original_env) { yield }
end
+ # @deprecated Use `with_unbundled_env` instead
def with_clean_env
- with_env(clean_env) { yield }
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. " \
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`",
+ :print_caller_location => true
+ )
+
+ with_env(unbundled_env) { yield }
end
+ # Run block with all bundler-related variables removed
+ def with_unbundled_env
+ with_env(unbundled_env) { yield }
+ end
+
+ # Run subcommand with the environment present before Bundler was activated
+ def original_system(*args)
+ with_original_env { Kernel.system(*args) }
+ end
+
+ # @deprecated Use `unbundled_system` instead
def clean_system(*args)
- with_clean_env { Kernel.system(*args) }
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.clean_system` has been deprecated in favor of `Bundler.unbundled_system`. " \
+ "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`",
+ :print_caller_location => true
+ )
+
+ with_env(unbundled_env) { Kernel.system(*args) }
end
+ # Run subcommand in an environment with all bundler related variables removed
+ def unbundled_system(*args)
+ with_unbundled_env { Kernel.system(*args) }
+ end
+
+ # Run a `Kernel.exec` to a subcommand with the environment present before Bundler was activated
+ def original_exec(*args)
+ with_original_env { Kernel.exec(*args) }
+ end
+
+ # @deprecated Use `unbundled_exec` instead
def clean_exec(*args)
- with_clean_env { Kernel.exec(*args) }
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
+ "`Bundler.clean_exec` has been deprecated in favor of `Bundler.unbundled_exec`. " \
+ "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`",
+ :print_caller_location => true
+ )
+
+ with_env(unbundled_env) { Kernel.exec(*args) }
+ end
+
+ # Run a `Kernel.exec` to a subcommand in an environment with all bundler related variables removed
+ def unbundled_exec(*args)
+ with_env(unbundled_env) { Kernel.exec(*args) }
end
def local_platform
- return Gem::Platform::RUBY if settings[:force_ruby_platform]
+ return Gem::Platform::RUBY if settings[:force_ruby_platform] || Gem.platforms == [Gem::Platform::RUBY]
Gem::Platform.local
end
@@ -313,21 +460,29 @@ EOF
end
def system_bindir
- # Gem.bindir doesn't always return the location that Rubygems will install
- # system binaries. If you put '-n foo' in your .gemrc, Rubygems will
- # install binstubs there instead. Unfortunately, Rubygems doesn't expose
+ # Gem.bindir doesn't always return the location that RubyGems will install
+ # system binaries. If you put '-n foo' in your .gemrc, RubyGems will
+ # install binstubs there instead. Unfortunately, RubyGems doesn't expose
# that directory at all, so rather than parse .gemrc ourselves, we allow
- # the directory to be set as well, via `bundle config bindir foo`.
+ # the directory to be set as well, via `bundle config set --local bindir foo`.
Bundler.settings[:system_bindir] || Bundler.rubygems.gem_bindir
end
+ def preferred_gemfile_name
+ Bundler.settings[:init_gems_rb] ? "gems.rb" : "Gemfile"
+ end
+
+ def use_system_gems?
+ configured_bundle_path.use_system_gems?
+ end
+
def requires_sudo?
return @requires_sudo if defined?(@requires_sudo_ran)
sudo_present = which "sudo" if settings.allow_sudo?
if sudo_present
- # the bundle path and subdirectories need to be writable for Rubygems
+ # the bundle path and subdirectories need to be writable for RubyGems
# to be able to unpack and install gems without exploding
path = bundle_path
path = path.parent until path.exist?
@@ -337,16 +492,20 @@ EOF
bin_dir = bin_dir.parent until bin_dir.exist?
# if any directory is not writable, we need sudo
- files = [path, bin_dir] | Dir[path.join("build_info/*").to_s] | Dir[path.join("*").to_s]
- sudo_needed = files.any? {|f| !File.writable?(f) }
+ files = [path, bin_dir] | Dir[bundle_path.join("build_info/*").to_s] | Dir[bundle_path.join("*").to_s]
+ unwritable_files = files.reject {|f| File.writable?(f) }
+ sudo_needed = !unwritable_files.empty?
+ if sudo_needed
+ Bundler.ui.warn "Following files may not be writable, so sudo is needed:\n #{unwritable_files.map(&:to_s).sort.join("\n ")}"
+ end
end
@requires_sudo_ran = true
@requires_sudo = settings.allow_sudo? && sudo_present && sudo_needed
end
- def mkdir_p(path)
- if requires_sudo?
+ def mkdir_p(path, options = {})
+ if requires_sudo? && !options[:no_sudo]
sudo "mkdir -p '#{path}'" unless File.exist?(path)
else
SharedHelpers.filesystem_access(path, :write) do |p|
@@ -374,7 +533,8 @@ EOF
Your user account isn't allowed to install to the system RubyGems.
You can cancel this installation and run:
- bundle install --path vendor/bundle
+ bundle config set --local path 'vendor/bundle'
+ bundle install
to install the gems into ./vendor/bundle/, or you can enter your password
and install the bundled gems to RubyGems using sudo.
@@ -393,12 +553,14 @@ EOF
end
def read_file(file)
- File.open(file, "rb", &:read)
+ SharedHelpers.filesystem_access(file, :read) do
+ File.open(file, "r:UTF-8", &:read)
+ end
end
def load_marshal(data)
Marshal.load(data)
- rescue => e
+ rescue StandardError => e
raise MarshalError, "#{e.class}: #{e.message}"
end
@@ -413,7 +575,7 @@ EOF
def load_gemspec_uncached(file, validate = false)
path = Pathname.new(file)
- contents = path.read
+ contents = read_file(file)
spec = if contents.start_with?("---") # YAML header
eval_yaml_gemspec(path, contents)
else
@@ -448,15 +610,23 @@ EOF
reset_rubygems!
end
- def reset_paths!
- @root = nil
+ def reset_settings_and_root!
@settings = nil
+ @root = nil
+ end
+
+ def reset_paths!
+ @bin_path = nil
+ @bundler_major_version = nil
+ @bundle_path = nil
+ @configured = nil
+ @configured_bundle_path = nil
@definition = nil
- @setup = nil
@load = nil
@locked_gems = nil
- @bundle_path = nil
- @bin_path = nil
+ @root = nil
+ @settings = nil
+ @setup = nil
@user_home = nil
end
@@ -467,9 +637,17 @@ EOF
@rubygems = nil
end
- private
+ def configure_gem_home_and_path(path = bundle_path)
+ configure_gem_path
+ configure_gem_home(path)
+ Bundler.rubygems.clear_paths
+ end
+
+ private
def eval_yaml_gemspec(path, contents)
+ require_relative "bundler/psyched_yaml"
+
# If the YAML is invalid, Syck raises an ArgumentError, and Psych
# raises a Psych::SyntaxError. See psyched_yaml.rb for more info.
Gem::Specification.from_yaml(contents)
@@ -478,47 +656,33 @@ EOF
end
def eval_gemspec(path, contents)
- eval(contents, TOPLEVEL_BINDING, path.expand_path.to_s)
+ eval(contents, TOPLEVEL_BINDING.dup, path.expand_path.to_s)
rescue ScriptError, StandardError => e
msg = "There was an error while loading `#{path.basename}`: #{e.message}"
- if e.is_a?(LoadError) && RUBY_VERSION >= "1.9"
- msg += "\nDoes it try to require a relative path? That's been removed in Ruby 1.9"
- end
-
raise GemspecError, Dsl::DSLError.new(msg, path, e.backtrace, contents)
end
- def configure_gem_home_and_path
- configure_gem_path
- configure_gem_home
- bundle_path
- end
-
- def configure_gem_path(env = ENV, settings = self.settings)
- blank_home = env["GEM_HOME"].nil? || env["GEM_HOME"].empty?
- if settings[:disable_shared_gems]
+ def configure_gem_path
+ unless use_system_gems?
# this needs to be empty string to cause
# PathSupport.split_gem_path to only load up the
# Bundler --path setting as the GEM_PATH.
- env["GEM_PATH"] = ""
- elsif blank_home || Bundler.rubygems.gem_dir != bundle_path.to_s
- possibles = [Bundler.rubygems.gem_dir, Bundler.rubygems.gem_path]
- paths = possibles.flatten.compact.uniq.reject(&:empty?)
- env["GEM_PATH"] = paths.join(File::PATH_SEPARATOR)
+ Bundler::SharedHelpers.set_env "GEM_PATH", ""
end
end
- def configure_gem_home
- # TODO: This mkdir_p is only needed for JRuby <= 1.5 and should go away (GH #602)
- begin
- FileUtils.mkdir_p bundle_path.to_s
- rescue
- nil
- end
+ def configure_gem_home(path)
+ Bundler::SharedHelpers.set_env "GEM_HOME", path.to_s
+ end
- ENV["GEM_HOME"] = File.expand_path(bundle_path, root)
- Bundler.rubygems.clear_paths
+ def tmp_home_path
+ Kernel.send(:require, "tmpdir")
+ SharedHelpers.filesystem_access(Dir.tmpdir) do
+ path = Bundler.tmp
+ at_exit { Bundler.rm_rf(path) }
+ path
+ end
end
# @param env [Hash]
diff --git a/lib/bundler/build_metadata.rb b/lib/bundler/build_metadata.rb
new file mode 100644
index 0000000000..0846e82e06
--- /dev/null
+++ b/lib/bundler/build_metadata.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Bundler
+ # Represents metadata from when the Bundler gem was built.
+ module BuildMetadata
+ # begin ivars
+ @release = false
+ # end ivars
+
+ # A hash representation of the build metadata.
+ def self.to_h
+ {
+ "Built At" => built_at,
+ "Git SHA" => git_commit_sha,
+ "Released Version" => release?,
+ }
+ end
+
+ # A string representing the date the bundler gem was built.
+ def self.built_at
+ @built_at ||= Time.now.utc.strftime("%Y-%m-%d").freeze
+ end
+
+ # The SHA for the git commit the bundler gem was built from.
+ def self.git_commit_sha
+ return @git_commit_sha if instance_variable_defined? :@git_commit_sha
+
+ # If Bundler has been installed without its .git directory and without a
+ # commit instance variable then we can't determine its commits SHA.
+ git_dir = File.join(File.expand_path("../../../..", __FILE__), ".git")
+ if File.directory?(git_dir)
+ return @git_commit_sha = Dir.chdir(git_dir) { `git rev-parse --short HEAD`.strip.freeze }
+ end
+
+ @git_commit_sha ||= "unknown"
+ end
+
+ # Whether this is an official release build of Bundler.
+ def self.release?
+ @release
+ end
+ end
+end
diff --git a/lib/bundler/bundler.gemspec b/lib/bundler/bundler.gemspec
new file mode 100644
index 0000000000..38c533b0c1
--- /dev/null
+++ b/lib/bundler/bundler.gemspec
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+begin
+ require_relative "lib/bundler/version"
+rescue LoadError
+ # for Ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |s|
+ s.name = "bundler"
+ s.version = Bundler::VERSION
+ s.license = "MIT"
+ s.authors = [
+ "André Arko", "Samuel Giddins", "Colby Swandale", "Hiroshi Shibata",
+ "David Rodríguez", "Grey Baker", "Stephanie Morillo", "Chris Morris", "James Wen", "Tim Moore",
+ "André Medeiros", "Jessica Lynn Suttles", "Terence Lee", "Carl Lerche",
+ "Yehuda Katz"
+ ]
+ s.email = ["team@bundler.io"]
+ s.homepage = "https://bundler.io"
+ s.summary = "The best way to manage your application's dependencies"
+ s.description = "Bundler manages an application's dependencies through its entire life, across many machines, systematically and repeatably"
+
+ if s.respond_to?(:metadata=)
+ s.metadata = {
+ "bug_tracker_uri" => "https://github.com/rubygems/rubygems/issues?q=is%3Aopen+is%3Aissue+label%3ABundler",
+ "changelog_uri" => "https://github.com/rubygems/rubygems/blob/master/bundler/CHANGELOG.md",
+ "homepage_uri" => "https://bundler.io/",
+ "source_code_uri" => "https://github.com/rubygems/rubygems/",
+ }
+ end
+
+ s.required_ruby_version = ">= 2.3.0"
+ s.required_rubygems_version = ">= 2.5.2"
+
+ s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
+
+ # include the gemspec itself because warbler breaks w/o it
+ s.files += %w[lib/bundler/bundler.gemspec]
+
+ s.bindir = "libexec"
+ s.executables = %w[bundle bundler]
+ s.require_paths = ["lib"]
+end
diff --git a/lib/bundler/capistrano.rb b/lib/bundler/capistrano.rb
index 7b0bbbd6d2..1f3712d48e 100644
--- a/lib/bundler/capistrano.rb
+++ b/lib/bundler/capistrano.rb
@@ -1,13 +1,18 @@
# frozen_string_literal: true
+
+require_relative "shared_helpers"
+Bundler::SharedHelpers.major_deprecation 2,
+ "The Bundler task for Capistrano. Please use https://github.com/capistrano/bundler"
+
# Capistrano task for Bundler.
#
# Add "require 'bundler/capistrano'" in your Capistrano deploy.rb, and
# Bundler will be activated after each new deployment.
-require "bundler/deployment"
+require_relative "deployment"
require "capistrano/version"
if defined?(Capistrano::Version) && Gem::Version.new(Capistrano::Version).release >= Gem::Version.new("3.0")
- raise "For Capistrano 3.x integration, please use http://github.com/capistrano/bundler"
+ raise "For Capistrano 3.x integration, please use https://github.com/capistrano/bundler"
end
Capistrano::Configuration.instance(:must_exist).load do
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 03e08e25a1..d271086b25 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -1,19 +1,28 @@
# frozen_string_literal: true
-require "bundler"
-require "bundler/vendored_thor"
+
+require_relative "vendored_thor"
module Bundler
class CLI < Thor
- AUTO_INSTALL_CMDS = %w(show binstubs outdated exec open console licenses clean).freeze
- PARSEABLE_COMMANDS = %w(
- check config help exec platform show version
- ).freeze
+ require_relative "cli/common"
+
+ package_name "Bundler"
+
+ AUTO_INSTALL_CMDS = %w[show binstubs outdated exec open console licenses clean].freeze
+ PARSEABLE_COMMANDS = %w[check config help exec platform show version].freeze
+
+ COMMAND_ALIASES = {
+ "check" => "c",
+ "install" => "i",
+ "plugin" => "",
+ "list" => "ls",
+ "exec" => ["e", "ex", "exe"],
+ "cache" => ["package", "pack"],
+ "version" => ["-v", "--version"],
+ }.freeze
def self.start(*)
super
- rescue Exception => e
- Bundler.ui = UI::Shell.new
- raise e
ensure
Bundler::SharedHelpers.print_major_deprecations!
end
@@ -25,16 +34,34 @@ module Bundler
end
end
+ def self.all_aliases
+ @all_aliases ||= begin
+ command_aliases = {}
+
+ COMMAND_ALIASES.each do |name, aliases|
+ Array(aliases).each do |one_alias|
+ command_aliases[one_alias] = name
+ end
+ end
+
+ command_aliases
+ end
+ end
+
+ def self.aliases_for(command_name)
+ COMMAND_ALIASES.select {|k, _| k == command_name }.invert
+ end
+
def initialize(*args)
super
custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile]
if custom_gemfile && !custom_gemfile.empty?
- ENV["BUNDLE_GEMFILE"] = File.expand_path(custom_gemfile)
- Bundler.reset_paths!
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile)
+ Bundler.reset_settings_and_root!
end
- Bundler.settings[:retry] = options[:retry] if options[:retry]
+ Bundler.settings.set_command_option_if_given :retry, options[:retry]
current_cmd = args.last[:current_command].name
auto_install if AUTO_INSTALL_CMDS.include?(current_cmd)
@@ -42,25 +69,40 @@ module Bundler
raise InvalidOption, e.message
ensure
self.options ||= {}
- Bundler.settings.cli_flags_given = !options.empty?
unprinted_warnings = Bundler.ui.unprinted_warnings
Bundler.ui = UI::Shell.new(options)
Bundler.ui.level = "debug" if options["verbose"]
unprinted_warnings.each {|w| Bundler.ui.warn(w) }
-
- if ENV["RUBYGEMS_GEMDEPS"] && !ENV["RUBYGEMS_GEMDEPS"].empty?
- Bundler.ui.warn(
- "The RUBYGEMS_GEMDEPS environment variable is set. This enables RubyGems' " \
- "experimental Gemfile mode, which may conflict with Bundler and cause unexpected errors. " \
- "To remove this warning, unset RUBYGEMS_GEMDEPS.", :wrap => true
- )
- end
end
check_unknown_options!(:except => [:config, :exec])
stop_on_unknown_option! :exec
- default_task :install
+ desc "cli_help", "Prints a summary of bundler commands", :hide => true
+ def cli_help
+ version
+ Bundler.ui.info "\n"
+
+ primary_commands = ["install", "update", "cache", "exec", "config", "help"]
+
+ list = self.class.printable_commands(true)
+ by_name = list.group_by {|name, _message| name.match(/^bundle (\w+)/)[1] }
+ utilities = by_name.keys.sort - primary_commands
+ primary_commands.map! {|name| (by_name[name] || raise("no primary command #{name}")).first }
+ utilities.map! {|name| by_name[name].first }
+
+ shell.say "Bundler commands:\n\n"
+
+ shell.say " Primary commands:\n"
+ shell.print_table(primary_commands, :indent => 4, :truncate => true)
+ shell.say
+ shell.say " Utilities:\n"
+ shell.print_table(utilities, :indent => 4, :truncate => true)
+ shell.say
+ self.class.send(:class_options_help, shell)
+ end
+ default_task(Bundler.feature_flag.default_cli_command)
+
class_option "no-color", :type => :boolean, :desc => "Disable colorization in output"
class_option "retry", :type => :numeric, :aliases => "-r", :banner => "NUM",
:desc => "Specify the number of times you wish to attempt network commands"
@@ -73,16 +115,17 @@ module Bundler
else command = "bundle-#{cli}"
end
- man_path = File.expand_path("../../../man", __FILE__)
- man_pages = Hash[Dir.glob(File.join(man_path, "*")).grep(/.*\.\d*\Z/).collect do |f|
+ man_path = File.expand_path("man", __dir__)
+ man_pages = Hash[Dir.glob(File.join(man_path, "**", "*")).grep(/.*\.\d*\Z/).collect do |f|
[File.basename(f, ".*"), f]
end]
if man_pages.include?(command)
+ man_page = man_pages[command]
if Bundler.which("man") && man_path !~ %r{^file:/.+!/META-INF/jruby.home/.+}
- Kernel.exec "man #{man_pages[command]}"
+ Kernel.exec "man #{man_page}"
else
- puts File.read("#{man_path}/#{File.basename(man_pages[command])}.txt")
+ puts File.read("#{man_path}/#{File.basename(man_page)}.ronn")
end
elsif command_path = Bundler.which("bundler-#{cli}")
Kernel.exec(command_path, "--help")
@@ -109,7 +152,7 @@ module Bundler
D
method_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
def init
- require "bundler/cli/init"
+ require_relative "cli/init"
Init.new(options.dup).run
end
@@ -124,13 +167,28 @@ module Bundler
method_option "gemfile", :type => :string, :banner =>
"Use the specified gemfile instead of Gemfile"
method_option "path", :type => :string, :banner =>
- "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME). Bundler will remember this value for future installs on this machine"
- map "c" => "check"
+ "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
def check
- require "bundler/cli/check"
+ remembered_flag_deprecation("path")
+
+ require_relative "cli/check"
Check.new(options).run
end
+ map aliases_for("check")
+
+ desc "remove [GEM [GEM ...]]", "Removes gems from the Gemfile"
+ long_desc <<-D
+ Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid. If the gem is not found, Bundler prints a error message and if gem could not be removed due to any reason Bundler will display a warning.
+ D
+ method_option "install", :type => :boolean, :banner =>
+ "Runs 'bundle install' after removing the gems from the Gemfile"
+ def remove(*gems)
+ SharedHelpers.major_deprecation(2, "The `--install` flag has been deprecated. `bundle install` is triggered by default.") if ARGV.include?("--install")
+ require_relative "cli/remove"
+ Remove.new(gems, options).run
+ end
+
desc "install [OPTIONS]", "Install the current environment to the system"
long_desc <<-D
Install will install all of the gems in the current bundle, making them available
@@ -160,12 +218,12 @@ module Bundler
"Do not attempt to fetch gems remotely and use the gem cache instead"
method_option "no-cache", :type => :boolean, :banner =>
"Don't update the existing gem cache."
- method_option "force", :type => :boolean, :banner =>
+ method_option "redownload", :type => :boolean, :aliases => "--force", :banner =>
"Force downloading every gem."
method_option "no-prune", :type => :boolean, :banner =>
"Don't remove stale gems from the cache."
method_option "path", :type => :string, :banner =>
- "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME). Bundler will remember this value for future installs on this machine"
+ "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
method_option "quiet", :type => :boolean, :banner =>
"Only output warnings and errors."
method_option "shebang", :type => :string, :banner =>
@@ -181,15 +239,24 @@ module Bundler
"Exclude gems that are part of the specified named group."
method_option "with", :type => :array, :banner =>
"Include gems that are part of the specified named group."
- map "i" => "install"
def install
- require "bundler/cli/install"
+ SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
+
+ %w[clean deployment frozen no-prune path shebang system without with].each do |option|
+ remembered_flag_deprecation(option)
+ end
+
+ remembered_negative_flag_deprecation("no-deployment")
+
+ require_relative "cli/install"
Bundler.settings.temporary(:no_install => false) do
Install.new(options.dup).run
end
end
- desc "update [OPTIONS]", "update the current environment"
+ map aliases_for("install")
+
+ desc "update [OPTIONS]", "Update the current environment"
long_desc <<-D
Update will install the newest versions of the gems listed in the Gemfile. Use
update when you have changed the Gemfile, or if you want to get the newest
@@ -197,6 +264,8 @@ module Bundler
D
method_option "full-index", :type => :boolean, :banner =>
"Fall back to using the single-file index of all gems"
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
method_option "group", :aliases => "-g", :type => :array, :banner =>
"Update a specific group"
method_option "jobs", :aliases => "-j", :type => :numeric, :banner =>
@@ -207,7 +276,7 @@ module Bundler
"Only output warnings and errors."
method_option "source", :type => :array, :banner =>
"Update a specific source (and all gems associated with it)"
- method_option "force", :type => :boolean, :banner =>
+ method_option "redownload", :type => :boolean, :aliases => "--force", :banner =>
"Force downloading every gem."
method_option "ruby", :type => :boolean, :banner =>
"Update ruby specified in Gemfile.lock"
@@ -223,9 +292,14 @@ module Bundler
"Do not allow any gem to be updated past latest --patch | --minor | --major"
method_option "conservative", :type => :boolean, :banner =>
"Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
+ method_option "all", :type => :boolean, :banner =>
+ "Update everything."
def update(*gems)
- require "bundler/cli/update"
- Update.new(options, gems).run
+ SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
+ require_relative "cli/update"
+ Bundler.settings.temporary(:no_install => false) do
+ Update.new(options, gems).run
+ end
end
desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
@@ -238,17 +312,28 @@ module Bundler
method_option "outdated", :type => :boolean,
:banner => "Show verbose output including whether gems are outdated."
def show(gem_name = nil)
- Bundler::SharedHelpers.major_deprecation("use `bundle show` instead of `bundle list`") if ARGV[0] == "list"
- require "bundler/cli/show"
+ SharedHelpers.major_deprecation(2, "the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement") if ARGV.include?("--outdated")
+ require_relative "cli/show"
Show.new(options, gem_name).run
end
- # TODO: 2.0 remove `bundle list`
- map %w(list) => "show"
+
+ desc "list", "List all gems in the bundle"
+ method_option "name-only", :type => :boolean, :banner => "print only the gem names"
+ method_option "only-group", :type => :array, :default => [], :banner => "print gems from a given set of groups"
+ method_option "without-group", :type => :array, :default => [], :banner => "print all gems except from a given set of groups"
+ method_option "paths", :type => :boolean, :banner => "print the path to each gem in the bundle"
+ def list
+ require_relative "cli/list"
+ List.new(options).run
+ end
+
+ map aliases_for("list")
desc "info GEM [OPTIONS]", "Show information for the given gem"
method_option "path", :type => :boolean, :banner => "Print full path to gem"
+ method_option "version", :type => :boolean, :banner => "Print gem version"
def info(gem_name)
- require "bundler/cli/info"
+ require_relative "cli/info"
Info.new(options, gem_name).run
end
@@ -262,10 +347,16 @@ module Bundler
"Overwrite existing binstubs if they exist"
method_option "path", :type => :string, :lazy_default => "bin", :banner =>
"Binstub destination directory (default bin)"
+ method_option "shebang", :type => :string, :banner =>
+ "Specify a different shebang executable name than the default (usually 'ruby')"
method_option "standalone", :type => :boolean, :banner =>
"Make binstubs that can work without the Bundler runtime"
+ method_option "all", :type => :boolean, :banner =>
+ "Install binstubs for all gems"
+ method_option "all-platforms", :type => :boolean, :default => false, :banner =>
+ "Install binstubs for all platforms"
def binstubs(*gems)
- require "bundler/cli/binstubs"
+ require_relative "cli/binstubs"
Binstubs.new(options, gems).run
end
@@ -276,13 +367,18 @@ module Bundler
method_option "version", :aliases => "-v", :type => :string
method_option "group", :aliases => "-g", :type => :string
method_option "source", :aliases => "-s", :type => :string
-
- def add(gem_name)
- require "bundler/cli/add"
- Add.new(options.dup, gem_name).run
- end
-
- desc "outdated GEM [OPTIONS]", "list installed gems with newer versions available"
+ method_option "git", :type => :string
+ method_option "branch", :type => :string
+ method_option "skip-install", :type => :boolean, :banner =>
+ "Adds gem to the Gemfile but does not install it"
+ method_option "optimistic", :type => :boolean, :banner => "Adds optimistic declaration of version to gem"
+ method_option "strict", :type => :boolean, :banner => "Adds strict declaration of version to gem"
+ def add(*gems)
+ require_relative "cli/add"
+ Add.new(options.dup, gems).run
+ end
+
+ desc "outdated GEM [OPTIONS]", "List installed gems with newer versions available"
long_desc <<-D
Outdated lists the names and versions of gems that have a newer version available
in the given source. Calling outdated with [GEM [GEM]] will only check for newer
@@ -292,15 +388,16 @@ module Bundler
For more information on patch level options (--major, --minor, --patch,
--update-strict) see documentation on the same options on the update command.
D
- method_option "group", :aliases => "--group", :type => :string, :banner => "List gems from a specific group"
- method_option "groups", :aliases => "--groups", :type => :boolean, :banner => "List gems organized by groups"
+ method_option "group", :type => :string, :banner => "List gems from a specific group"
+ method_option "groups", :type => :boolean, :banner => "List gems organized by groups"
method_option "local", :type => :boolean, :banner =>
"Do not attempt to fetch gems remotely and use the gem cache instead"
method_option "pre", :type => :boolean, :banner => "Check for newer pre-release gems"
method_option "source", :type => :array, :banner => "Check against a specific source"
- method_option "strict", :type => :boolean, :banner =>
+ strict_is_update = Bundler.feature_flag.forget_cli_options?
+ method_option "filter-strict", :type => :boolean, :aliases => strict_is_update ? [] : %w[--strict], :banner =>
"Only list newer versions allowed by your Gemfile requirements"
- method_option "update-strict", :type => :boolean, :banner =>
+ method_option "update-strict", :type => :boolean, :aliases => strict_is_update ? %w[--strict] : [], :banner =>
"Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major"
method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version"
method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)"
@@ -310,59 +407,81 @@ module Bundler
method_option "filter-patch", :type => :boolean, :banner => "Only list patch newer versions"
method_option "parseable", :aliases => "--porcelain", :type => :boolean, :banner =>
"Use minimal formatting for more parseable output"
+ method_option "only-explicit", :type => :boolean, :banner =>
+ "Only list gems specified in your Gemfile, not their dependencies"
def outdated(*gems)
- require "bundler/cli/outdated"
+ require_relative "cli/outdated"
Outdated.new(options, gems).run
end
- desc "cache [OPTIONS]", "Cache all the gems to vendor/cache", :hide => true
- method_option "all", :type => :boolean, :banner => "Include all sources (including path and git)."
- method_option "all-platforms", :type => :boolean, :banner => "Include gems for all platforms present in the lockfile, not only the current one"
- method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
- def cache
- require "bundler/cli/cache"
- Cache.new(options).run
+ desc "fund [OPTIONS]", "Lists information about gems seeking funding assistance"
+ method_option "group", :aliases => "-g", :type => :array, :banner =>
+ "Fetch funding information for a specific group"
+ def fund
+ require_relative "cli/fund"
+ Fund.new(options).run
end
- desc "package [OPTIONS]", "Locks and then caches all of the gems into vendor/cache"
- method_option "all", :type => :boolean, :banner => "Include all sources (including path and git)."
+ desc "cache [OPTIONS]", "Locks and then caches all of the gems into vendor/cache"
+ method_option "all", :type => :boolean,
+ :default => Bundler.feature_flag.cache_all?,
+ :banner => "Include all sources (including path and git)."
method_option "all-platforms", :type => :boolean, :banner => "Include gems for all platforms present in the lockfile, not only the current one"
method_option "cache-path", :type => :string, :banner =>
"Specify a different cache path than the default (vendor/cache)."
method_option "gemfile", :type => :string, :banner => "Use the specified gemfile instead of Gemfile"
- method_option "no-install", :type => :boolean, :banner => "Don't install the gems, only the package."
+ method_option "no-install", :type => :boolean, :banner => "Don't install the gems, only update the cache."
method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
method_option "path", :type => :string, :banner =>
- "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME). Bundler will remember this value for future installs on this machine"
+ "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
method_option "quiet", :type => :boolean, :banner => "Only output warnings and errors."
method_option "frozen", :type => :boolean, :banner =>
- "Do not allow the Gemfile.lock to be updated after this package operation's install"
+ "Do not allow the Gemfile.lock to be updated after this bundle cache operation's install"
long_desc <<-D
- The package command will copy the .gem files for every gem in the bundle into the
+ The cache command will copy the .gem files for every gem in the bundle into the
directory ./vendor/cache. If you then check that directory into your source
control repository, others who check out your source will be able to install the
bundle without having to download any additional gems.
D
- def package
- require "bundler/cli/package"
- Package.new(options).run
+ def cache
+ SharedHelpers.major_deprecation 2,
+ "The `--all` flag is deprecated because it relies on being " \
+ "remembered across bundler invocations, which bundler will no longer " \
+ "do in future versions. Instead please use `bundle config set cache_all true`, " \
+ "and stop using this flag" if ARGV.include?("--all")
+
+ SharedHelpers.major_deprecation 2,
+ "The `--path` flag is deprecated because its semantics are unclear. " \
+ "Use `bundle config cache_path` to configure the path of your cache of gems, " \
+ "and `bundle config path` to configure the path where your gems are installed, " \
+ "and stop using this flag" if ARGV.include?("--path")
+
+ require_relative "cli/cache"
+ Cache.new(options).run
end
- map %w(pack) => :package
+
+ map aliases_for("cache")
desc "exec [OPTIONS]", "Run the command in context of the bundle"
- method_option :keep_file_descriptors, :type => :boolean, :default => false
+ method_option :keep_file_descriptors, :type => :boolean, :default => true
+ method_option :gemfile, :type => :string, :required => false
long_desc <<-D
Exec runs a command, providing it access to the gems in the bundle. While using
bundle exec you can require and call the bundled gems as if they were installed
- into the system wide Rubygems repository.
+ into the system wide RubyGems repository.
D
- map "e" => "exec"
def exec(*args)
- require "bundler/cli/exec"
+ if ARGV.include?("--no-keep-file-descriptors")
+ SharedHelpers.major_deprecation(2, "The `--no-keep-file-descriptors` has been deprecated. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to")
+ end
+
+ require_relative "cli/exec"
Exec.new(options, args).run
end
- desc "config NAME [VALUE]", "retrieve or set a configuration value"
+ map aliases_for("exec")
+
+ desc "config NAME [VALUE]", "Retrieve or set a configuration value"
long_desc <<-D
Retrieves or sets a configuration value. If only one parameter is provided, retrieve the value. If two parameters are provided, replace the
existing value with the newly provided one.
@@ -370,34 +489,42 @@ module Bundler
By default, setting a configuration value sets it for all projects
on the machine.
- If a global setting is superceded by local configuration, this command
- will show the current value, as well as any superceded values and
+ If a global setting is superseded by local configuration, this command
+ will show the current value, as well as any superseded values and
where they were specified.
D
- method_option "parseable", :type => :boolean, :banner => "Use minimal formatting for more parseable output"
- def config(*args)
- require "bundler/cli/config"
- Config.new(options, args, self).run
- end
+ require_relative "cli/config"
+ subcommand "config", Config
desc "open GEM", "Opens the source directory of the given bundled gem"
def open(name)
- require "bundler/cli/open"
+ require_relative "cli/open"
Open.new(options, name).run
end
- desc "console [GROUP]", "Opens an IRB session with the bundle pre-loaded"
- def console(group = nil)
- # TODO: Remove for 2.0
- require "bundler/cli/console"
- Console.new(options, group).run
+ unless Bundler.feature_flag.bundler_3_mode?
+ desc "console [GROUP]", "Opens an IRB session with the bundle pre-loaded"
+ def console(group = nil)
+ require_relative "cli/console"
+ Console.new(options, group).run
+ end
end
desc "version", "Prints the bundler's version information"
def version
- Bundler.ui.info "Bundler version #{Bundler::VERSION}"
+ cli_help = current_command.name == "cli_help"
+ if cli_help || ARGV.include?("version")
+ build_info = " (#{BuildMetadata.built_at} commit #{BuildMetadata.git_commit_sha})"
+ end
+
+ if !cli_help && Bundler.feature_flag.print_only_version_number?
+ Bundler.ui.info "#{Bundler::VERSION}#{build_info}"
+ else
+ Bundler.ui.info "Bundler version #{Bundler::VERSION}#{build_info}"
+ end
end
- map %w(-v --version) => :version
+
+ map aliases_for("version")
desc "licenses", "Prints the license of all gems in the bundle"
def licenses
@@ -413,34 +540,46 @@ module Bundler
end
end
- desc "viz [OPTIONS]", "Generates a visual dependency graph"
- long_desc <<-D
- Viz generates a PNG file of the current Gemfile as a dependency graph.
- Viz requires the ruby-graphviz gem (and its dependencies).
- The associated gems must also be installed via 'bundle install'.
- D
- method_option :file, :type => :string, :default => "gem_graph", :aliases => "-f", :desc => "The name to use for the generated file. see format option"
- method_option :format, :type => :string, :default => "png", :aliases => "-F", :desc => "This is output format option. Supported format is png, jpg, svg, dot ..."
- method_option :requirements, :type => :boolean, :default => false, :aliases => "-R", :desc => "Set to show the version of each required dependency."
- method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version."
- method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group."
- def viz
- require "bundler/cli/viz"
- Viz.new(options.dup).run
+ unless Bundler.feature_flag.bundler_3_mode?
+ desc "viz [OPTIONS]", "Generates a visual dependency graph", :hide => true
+ long_desc <<-D
+ Viz generates a PNG file of the current Gemfile as a dependency graph.
+ Viz requires the ruby-graphviz gem (and its dependencies).
+ The associated gems must also be installed via 'bundle install'.
+ D
+ method_option :file, :type => :string, :default => "gem_graph", :aliases => "-f", :desc => "The name to use for the generated file. see format option"
+ method_option :format, :type => :string, :default => "png", :aliases => "-F", :desc => "This is output format option. Supported format is png, jpg, svg, dot ..."
+ method_option :requirements, :type => :boolean, :default => false, :aliases => "-R", :desc => "Set to show the version of each required dependency."
+ method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version."
+ method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group."
+ def viz
+ SharedHelpers.major_deprecation 2, "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
+ require_relative "cli/viz"
+ Viz.new(options.dup).run
+ end
end
old_gem = instance_method(:gem)
- desc "gem GEM [OPTIONS]", "Creates a skeleton for creating a rubygem"
+ desc "gem NAME [OPTIONS]", "Creates a skeleton for creating a rubygem"
method_option :exe, :type => :boolean, :default => false, :aliases => ["--bin", "-b"], :desc => "Generate a binary executable for your library."
- method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config gem.coc true`."
+ method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config set --global gem.coc true`."
method_option :edit, :type => :string, :aliases => "-e", :required => false, :banner => "EDITOR",
:lazy_default => [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? },
:desc => "Open generated gemspec in the specified editor (defaults to $EDITOR or $BUNDLER_EDITOR)"
method_option :ext, :type => :boolean, :default => false, :desc => "Generate the boilerplate for C extension code"
- method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config gem.mit true`."
- method_option :test, :type => :string, :lazy_default => "rspec", :aliases => "-t", :banner => "rspec",
- :desc => "Generate a test directory for your library, either rspec or minitest. Set a default with `bundle config gem.test rspec`."
+ method_option :git, :type => :boolean, :default => true, :desc => "Initialize a git repo inside your library."
+ method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set --global gem.mit true`."
+ method_option :rubocop, :type => :boolean, :desc => "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`."
+ method_option :changelog, :type => :boolean, :desc => "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`."
+ method_option :test, :type => :string, :lazy_default => Bundler.settings["gem.test"] || "", :aliases => "-t", :banner => "Use the specified test framework for your library",
+ :desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
+ method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
+ :desc => "Generate CI configuration, either GitHub Actions, Travis CI, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|travis|gitlab|circle)`"
+ method_option :linter, :type => :string, :lazy_default => Bundler.settings["gem.linter"] || "",
+ :desc => "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
+ method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
+
def gem(name)
end
@@ -448,7 +587,7 @@ module Bundler
def gem_command.run(instance, args = [])
arity = 1 # name
- require "bundler/cli/gem"
+ require_relative "cli/gem"
cmd_args = args + [instance]
cmd_args.unshift(instance.options)
@@ -470,13 +609,13 @@ module Bundler
File.expand_path(File.join(File.dirname(__FILE__), "templates"))
end
- desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory"
+ desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory", :hide => true
method_option "dry-run", :type => :boolean, :default => false, :banner =>
"Only print out changes, do not clean gems"
method_option "force", :type => :boolean, :default => false, :banner =>
"Forces clean even if --path is not set"
def clean
- require "bundler/cli/clean"
+ require_relative "cli/clean"
Clean.new(options.dup).run
end
@@ -484,18 +623,18 @@ module Bundler
method_option "ruby", :type => :boolean, :default => false, :banner =>
"only display ruby related platform information"
def platform
- require "bundler/cli/platform"
+ require_relative "cli/platform"
Platform.new(options).run
end
- desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile"
+ desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile", :hide => true
method_option "source", :type => :string, :banner =>
"Install gem from the given source"
method_option "group", :type => :string, :banner =>
"Install gem into a bundler group"
def inject(name, version)
- SharedHelpers.major_deprecation "The `inject` command has been replaced by the `add` command"
- require "bundler/cli/inject"
+ SharedHelpers.major_deprecation 2, "The `inject` command has been replaced by the `add` command"
+ require_relative "cli/inject"
Inject.new(options.dup, name, version).run
end
@@ -506,6 +645,8 @@ module Bundler
"do not attempt to fetch remote gemspecs and use the local gem cache only"
method_option "print", :type => :boolean, :default => false, :banner =>
"print the lockfile to STDOUT instead of writing to the file system"
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
method_option "lockfile", :type => :string, :default => nil, :banner =>
"the path the lockfile should be written to"
method_option "full-index", :type => :boolean, :default => false, :banner =>
@@ -525,13 +666,13 @@ module Bundler
method_option "conservative", :type => :boolean, :banner =>
"If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated"
def lock
- require "bundler/cli/lock"
+ require_relative "cli/lock"
Lock.new(options).run
end
desc "env", "Print information about the environment Bundler is running under"
def env
- Env.new.write($stdout)
+ Env.write($stdout)
end
desc "doctor [OPTIONS]", "Checks the bundle for common problems"
@@ -545,40 +686,50 @@ module Bundler
method_option "quiet", :type => :boolean, :banner =>
"Only output warnings and errors."
def doctor
- require "bundler/cli/doctor"
+ require_relative "cli/doctor"
Doctor.new(options).run
end
desc "issue", "Learn how to report an issue in Bundler"
def issue
- require "bundler/cli/issue"
+ require_relative "cli/issue"
Issue.new.run
end
- desc "pristine", "Restores installed gems to pristine condition from files located in the gem cache. Gem installed from a git repository will be issued `git checkout --force`."
- def pristine
- require "bundler/cli/pristine"
- Pristine.new.run
+ desc "pristine [GEMS...]", "Restores installed gems to pristine condition"
+ long_desc <<-D
+ Restores installed gems to pristine condition from files located in the
+ gem cache. Gems installed from a git repository will be issued `git
+ checkout --force`.
+ D
+ def pristine(*gems)
+ require_relative "cli/pristine"
+ Pristine.new(gems).run
end
if Bundler.feature_flag.plugins?
- require "bundler/cli/plugin"
- desc "plugin SUBCOMMAND ...ARGS", "manage the bundler plugins"
+ require_relative "cli/plugin"
+ desc "plugin", "Manage the bundler plugins"
subcommand "plugin", Plugin
end
# Reformat the arguments passed to bundle that include a --help flag
# into the corresponding `bundle help #{command}` call
def self.reformatted_help_args(args)
- bundler_commands = all_commands.keys
- help_flags = %w(--help -h)
- exec_commands = %w(e ex exe exec)
+ bundler_commands = (COMMAND_ALIASES.keys + COMMAND_ALIASES.values).flatten
+
+ help_flags = %w[--help -h]
+ exec_commands = ["exec"] + COMMAND_ALIASES["exec"]
+
help_used = args.index {|a| help_flags.include? a }
exec_used = args.index {|a| exec_commands.include? a }
+
command = args.find {|a| bundler_commands.include? a }
+ command = all_aliases[command] if all_aliases[command]
+
if exec_used && help_used
if exec_used + help_used == 1
- %w(help exec)
+ %w[help exec]
else
args
end
@@ -591,11 +742,11 @@ module Bundler
end
end
- private
+ private
# Automatically invoke `bundle install` and resume if
# Bundler.settings[:auto_install] exists. This is set through config cmd
- # `bundle config auto_install 1`.
+ # `bundle config set --global auto_install 1`.
#
# Note that this method `nil`s out the global Definition object, so it
# should be called first, before you instantiate anything like an
@@ -613,16 +764,20 @@ module Bundler
end
end
+ def current_command
+ _, _, config = @_initializer
+ config[:current_command]
+ end
+
def print_command
return unless Bundler.ui.debug?
- _, _, config = @_initializer
- current_command = config[:current_command]
- command_name = current_command.name
+ cmd = current_command
+ command_name = cmd.name
return if PARSEABLE_COMMANDS.include?(command_name)
command = ["bundle", command_name] + args
options_to_print = options.dup
options_to_print.delete_if do |k, v|
- next unless o = current_command.options[k]
+ next unless o = cmd.options[k]
o.default == v
end
command << Thor::Options.to_switches(options_to_print.sort_by(&:first)).strip
@@ -633,13 +788,13 @@ module Bundler
def warn_on_outdated_bundler
return if Bundler.settings[:disable_version_check]
- _, _, config = @_initializer
- current_command = config[:current_command]
command_name = current_command.name
return if PARSEABLE_COMMANDS.include?(command_name)
+ return unless SharedHelpers.md5_available?
+
latest = Fetcher::CompactIndex.
- new(nil, Source::Rubygems::Remote.new(URI("https://rubygems.org")), nil).
+ new(nil, Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org")), nil).
send(:compact_index_client).
instance_variable_get(:@cache).
dependencies("bundler").
@@ -649,10 +804,48 @@ module Bundler
current = Gem::Version.new(VERSION)
return if current >= latest
+ latest_installed = Bundler.rubygems.find_name("bundler").map(&:version).max
- Bundler.ui.warn "The latest bundler is #{latest}, but you are currently running #{current}.\nTo update, run `gem install bundler#{" --pre" if latest.prerelease?}`"
- rescue
+ installation = "To install the latest version, run `gem install bundler#{" --pre" if latest.prerelease?}`"
+ if latest_installed && latest_installed > current
+ suggestion = "To update to the most recent installed version (#{latest_installed}), run `bundle update --bundler`"
+ suggestion = "#{installation}\n#{suggestion}" if latest_installed < latest
+ else
+ suggestion = installation
+ end
+
+ Bundler.ui.warn "The latest bundler is #{latest}, but you are currently running #{current}.\n#{suggestion}"
+ rescue RuntimeError
nil
end
+
+ def remembered_negative_flag_deprecation(name)
+ positive_name = name.gsub(/\Ano-/, "")
+ option = current_command.options[positive_name]
+ flag_name = "--no-" + option.switch_name.gsub(/\A--/, "")
+
+ flag_deprecation(positive_name, flag_name, option)
+ end
+
+ def remembered_flag_deprecation(name)
+ option = current_command.options[name]
+ flag_name = option.switch_name
+
+ flag_deprecation(name, flag_name, option)
+ end
+
+ def flag_deprecation(name, flag_name, option)
+ name_index = ARGV.find {|arg| flag_name == arg.split("=")[0] }
+ return unless name_index
+
+ value = options[name]
+ value = value.join(" ").to_s if option.type == :array
+
+ Bundler::SharedHelpers.major_deprecation 2,
+ "The `#{flag_name}` flag is deprecated because it relies on being " \
+ "remembered across bundler invocations, which bundler will no longer " \
+ "do in future versions. Instead please use `bundle config set --local #{name.tr("-", "_")} " \
+ "'#{value}'`, and stop using this flag"
+ end
end
end
diff --git a/lib/bundler/cli/add.rb b/lib/bundler/cli/add.rb
index e80c775433..5bcf30d82d 100644
--- a/lib/bundler/cli/add.rb
+++ b/lib/bundler/cli/add.rb
@@ -1,26 +1,47 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Add
- def initialize(options, gem_name)
- @gem_name = gem_name
+ attr_reader :gems, :options, :version
+
+ def initialize(options, gems)
+ @gems = gems
@options = options
- @options[:group] = @options[:group].split(",").map(&:strip) if !@options[:group].nil? && !@options[:group].empty?
+ @options[:group] = options[:group].split(",").map(&:strip) unless options[:group].nil?
+ @version = options[:version].split(",").map(&:strip) unless options[:version].nil?
end
def run
- version = @options[:version].nil? ? nil : @options[:version].split(",").map(&:strip)
+ validate_options!
+ inject_dependencies
+ perform_bundle_install unless options["skip-install"]
+ end
- unless version.nil?
- version.each do |v|
- raise InvalidOption, "Invalid gem requirement pattern '#{v}'" unless Gem::Requirement::PATTERN =~ v.to_s
- end
- end
- dependency = Bundler::Dependency.new(@gem_name, version, @options)
+ private
- Injector.inject([dependency], :conservative_versioning => @options[:version].nil?) # Perform conservative versioning only when version is not specified
+ def perform_bundle_install
Installer.install(Bundler.root, Bundler.definition)
+ Bundler.load.cache if Bundler.app_cache.exist?
+ end
+
+ def inject_dependencies
+ dependencies = gems.map {|g| Bundler::Dependency.new(g, version, options) }
+
+ Injector.inject(dependencies,
+ :conservative_versioning => options[:version].nil?, # Perform conservative versioning only when version is not specified
+ :optimistic => options[:optimistic],
+ :strict => options[:strict])
+ end
+
+ def validate_options!
+ raise InvalidOption, "You can not specify `--strict` and `--optimistic` at the same time." if options[:strict] && options[:optimistic]
+
+ # raise error when no gems are specified
+ raise InvalidOption, "Please specify gems to add." if gems.empty?
+
+ version.to_a.each do |v|
+ raise InvalidOption, "Invalid gem requirement pattern '#{v}'" unless Gem::Requirement::PATTERN =~ v.to_s
+ end
end
end
end
diff --git a/lib/bundler/cli/binstubs.rb b/lib/bundler/cli/binstubs.rb
index 95103b7dd8..639c01ff39 100644
--- a/lib/bundler/cli/binstubs.rb
+++ b/lib/bundler/cli/binstubs.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Binstubs
@@ -11,11 +10,23 @@ module Bundler
def run
Bundler.definition.validate_runtime!
- Bundler.settings[:bin] = options["path"] if options["path"]
- Bundler.settings[:bin] = nil if options["path"] && options["path"].empty?
+ path_option = options["path"]
+ path_option = nil if path_option && path_option.empty?
+ Bundler.settings.set_command_option :bin, path_option if options["path"]
+ Bundler.settings.set_command_option_if_given :shebang, options["shebang"]
installer = Installer.new(Bundler.root, Bundler.definition)
- if gems.empty?
+ installer_opts = {
+ :force => options[:force],
+ :binstubs_cmd => true,
+ :all_platforms => options["all-platforms"],
+ }
+
+ if options[:all]
+ raise InvalidOption, "Cannot specify --all with specific gems" unless gems.empty?
+ @gems = Bundler.definition.specs.map(&:name)
+ installer_opts.delete(:binstubs_cmd)
+ elsif gems.empty?
Bundler.ui.error "`bundle binstubs` needs at least one gem to run."
exit 1
end
@@ -28,12 +39,13 @@ module Bundler
)
end
- if spec.name == "bundler"
- Bundler.ui.warn "Sorry, Bundler can only be run via Rubygems."
- elsif options[:standalone]
- installer.generate_standalone_bundler_executable_stubs(spec)
+ if options[:standalone]
+ next Bundler.ui.warn("Sorry, Bundler can only be run via RubyGems.") if gem_name == "bundler"
+ Bundler.settings.temporary(:path => (Bundler.settings[:path] || Bundler.root)) do
+ installer.generate_standalone_bundler_executable_stubs(spec, installer_opts)
+ end
else
- installer.generate_bundler_executable_stubs(spec, :force => options[:force], :binstubs_cmd => true)
+ installer.generate_bundler_executable_stubs(spec, installer_opts)
end
end
end
diff --git a/lib/bundler/cli/cache.rb b/lib/bundler/cli/cache.rb
index 5ba105a31d..c8698ed7e3 100644
--- a/lib/bundler/cli/cache.rb
+++ b/lib/bundler/cli/cache.rb
@@ -1,35 +1,43 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Cache
attr_reader :options
+
def initialize(options)
@options = options
end
def run
- Bundler.definition.validate_runtime!
- Bundler.definition.resolve_with_cache!
+ Bundler.ui.level = "warn" if options[:quiet]
+ Bundler.settings.set_command_option_if_given :path, options[:path]
+ Bundler.settings.set_command_option_if_given :cache_path, options["cache-path"]
+
setup_cache_all
- Bundler.settings[:cache_all_platforms] = options["all-platforms"] if options.key?("all-platforms")
- Bundler.load.cache
- Bundler.settings[:no_prune] = true if options["no-prune"]
- Bundler.load.lock
- rescue GemNotFound => e
- Bundler.ui.error(e.message)
- Bundler.ui.warn "Run `bundle install` to install missing gems."
- exit 1
+ install
+
+ # TODO: move cache contents here now that all bundles are locked
+ custom_path = Bundler.settings[:path] if options[:path]
+
+ Bundler.settings.temporary(:cache_all_platforms => options["all-platforms"]) do
+ Bundler.load.cache(custom_path)
+ end
end
- private
+ private
+
+ def install
+ require_relative "install"
+ options = self.options.dup
+ options["local"] = false if Bundler.settings[:cache_all_platforms]
+ options["no-cache"] = true
+ Bundler::CLI::Install.new(options).run
+ end
def setup_cache_all
- Bundler.settings[:cache_all] = options[:all] if options.key?("all")
+ all = options.fetch(:all, Bundler.feature_flag.cache_all? || nil)
- if Bundler.definition.has_local_dependencies? && !Bundler.settings[:cache_all]
- Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
- "to package them as well, please pass the --all flag. This will be the default " \
- "on Bundler 2.0."
- end
+ Bundler.settings.set_command_option_if_given :cache_all, all
end
end
end
diff --git a/lib/bundler/cli/check.rb b/lib/bundler/cli/check.rb
index 057a7e5695..65c51337d2 100644
--- a/lib/bundler/cli/check.rb
+++ b/lib/bundler/cli/check.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Check
attr_reader :options
@@ -8,14 +9,13 @@ module Bundler
end
def run
- if options[:path]
- Bundler.settings[:path] = File.expand_path(options[:path])
- Bundler.settings[:disable_shared_gems] = true
- end
+ Bundler.settings.set_command_option_if_given :path, options[:path]
+
+ definition = Bundler.definition
+ definition.validate_runtime!
begin
- definition = Bundler.definition
- definition.validate_runtime!
+ definition.resolve_only_locally!
not_installed = definition.missing_specs
rescue GemNotFound, VersionConflict
Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies."
@@ -28,7 +28,7 @@ module Bundler
not_installed.each {|s| Bundler.ui.error " * #{s.name} (#{s.version})" }
Bundler.ui.warn "Install missing gems with `bundle install`"
exit 1
- elsif !Bundler.default_lockfile.file? && Bundler.settings[:frozen]
+ elsif !Bundler.default_lockfile.file? && Bundler.frozen_bundle?
Bundler.ui.error "This bundle has been frozen, but there is no #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} present"
exit 1
else
diff --git a/lib/bundler/cli/clean.rb b/lib/bundler/cli/clean.rb
index 5eba09c6bc..c6b0968e3e 100644
--- a/lib/bundler/cli/clean.rb
+++ b/lib/bundler/cli/clean.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Clean
attr_reader :options
@@ -12,15 +13,13 @@ module Bundler
Bundler.load.clean(options[:"dry-run"])
end
- protected
+ protected
def require_path_or_force
- if !Bundler.settings[:path] && !options[:force]
- Bundler.ui.error "Cleaning all the gems on your system is dangerous! " \
- "If you're sure you want to remove every system gem not in this " \
- "bundle, run `bundle clean --force`."
- exit 1
- end
+ return unless Bundler.use_system_gems? && !options[:force]
+ raise InvalidOption, "Cleaning all the gems on your system is dangerous! " \
+ "If you're sure you want to remove every system gem not in this " \
+ "bundle, run `bundle clean --force`."
end
end
end
diff --git a/lib/bundler/cli/common.rb b/lib/bundler/cli/common.rb
index bacbb2edc5..ba259143b7 100644
--- a/lib/bundler/cli/common.rb
+++ b/lib/bundler/cli/common.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
module CLI::Common
def self.output_post_install_messages(messages)
@@ -13,17 +14,37 @@ module Bundler
Bundler.ui.info msg
end
- def self.output_without_groups_message
- return unless Bundler.settings.without.any?
- Bundler.ui.confirm without_groups_message
+ def self.output_fund_metadata_summary
+ definition = Bundler.definition
+ current_dependencies = definition.requested_dependencies
+ current_specs = definition.specs
+
+ count = current_dependencies.count {|dep| current_specs[dep.name].first.metadata.key?("funding_uri") }
+
+ return if count.zero?
+
+ intro = count > 1 ? "#{count} installed gems you directly depend on are" : "#{count} installed gem you directly depend on is"
+ message = "#{intro} looking for funding.\n Run `bundle fund` for details"
+ Bundler.ui.info message
+ end
+
+ def self.output_without_groups_message(command)
+ return if Bundler.settings[:without].empty?
+ Bundler.ui.confirm without_groups_message(command)
+ end
+
+ def self.without_groups_message(command)
+ command_in_past_tense = command == :install ? "installed" : "updated"
+ groups = Bundler.settings[:without]
+ "Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}."
end
- def self.without_groups_message
- groups = Bundler.settings.without
+ def self.verbalize_groups(groups)
+ groups.map!{|g| "'#{g}'" }
group_list = [groups[0...-1].join(", "), groups[-1..-1]].
reject {|s| s.to_s.empty? }.join(" and ")
- group_str = (groups.size == 1) ? "group" : "groups"
- "Gems in the #{group_str} #{group_list} were not installed."
+ group_str = groups.size == 1 ? "group" : "groups"
+ "#{group_str} #{group_list}"
end
def self.select_spec(name, regex_match = nil)
@@ -37,7 +58,13 @@ module Bundler
case specs.count
when 0
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
+ dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name }
+
+ if dep_in_other_group
+ raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored."
+ else
+ raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
+ end
when 1
specs.first
else
@@ -48,10 +75,6 @@ module Bundler
end
def self.ask_for_spec_from(specs)
- if !$stdout.tty? && ENV["BUNDLE_SPEC_RUN"].nil?
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
- end
-
specs.each_with_index do |spec, index|
Bundler.ui.info "#{index.succ} : #{spec.name}", true
end
@@ -62,7 +85,7 @@ module Bundler
end
def self.gem_not_found_message(missing_gem_name, alternatives)
- require "bundler/similarity_detector"
+ require_relative "../similarity_detector"
message = "Could not find gem '#{missing_gem_name}'."
alternate_names = alternatives.map {|a| a.respond_to?(:name) ? a.name : a }
suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name)
@@ -71,7 +94,9 @@ module Bundler
end
def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems)
- locked_names = locked_gems.specs.map(&:name)
+ return unless locked_gems
+
+ locked_names = locked_gems.specs.map(&:name).uniq
names.-(locked_names).each do |g|
raise GemNotFound, gem_not_found_message(g, locked_names)
end
@@ -79,15 +104,25 @@ module Bundler
def self.configure_gem_version_promoter(definition, options)
patch_level = patch_level_options(options)
+ patch_level << :patch if patch_level.empty? && Bundler.settings[:prefer_patch]
raise InvalidOption, "Provide only one of the following options: #{patch_level.join(", ")}" unless patch_level.length <= 1
+
definition.gem_version_promoter.tap do |gvp|
gvp.level = patch_level.first || :major
- gvp.strict = options[:strict] || options["update-strict"]
+ gvp.strict = options[:strict] || options["update-strict"] || options["filter-strict"]
end
end
def self.patch_level_options(options)
[:major, :minor, :patch].select {|v| options.keys.include?(v.to_s) }
end
+
+ def self.clean_after_install?
+ clean = Bundler.settings[:clean]
+ return clean unless clean.nil?
+ clean ||= Bundler.feature_flag.auto_clean_without_path? && Bundler.settings[:path].nil?
+ clean &&= !Bundler.use_system_gems?
+ clean
+ end
end
end
diff --git a/lib/bundler/cli/config.rb b/lib/bundler/cli/config.rb
index e8f13620ec..8d2aba0916 100644
--- a/lib/bundler/cli/config.rb
+++ b/lib/bundler/cli/config.rb
@@ -1,118 +1,194 @@
# frozen_string_literal: true
+
module Bundler
- class CLI::Config
- attr_reader :name, :options, :scope, :thor
- attr_accessor :args
-
- def initialize(options, args, thor)
- @options = options
- @args = args
- @thor = thor
- @name = peek = args.shift
- @scope = "global"
- return unless peek && peek.start_with?("--")
- @name = args.shift
- @scope = peek[2..-1]
+ class CLI::Config < Thor
+ class_option :parseable, :type => :boolean, :banner => "Use minimal formatting for more parseable output"
+
+ def self.scope_options
+ method_option :global, :type => :boolean, :banner => "Only change the global config"
+ method_option :local, :type => :boolean, :banner => "Only change the local config"
end
+ private_class_method :scope_options
- def run
- unless name
- confirm_all
- return
- end
+ desc "base NAME [VALUE]", "The Bundler 1 config interface", :hide => true
+ scope_options
+ method_option :delete, :type => :boolean, :banner => "delete"
+ def base(name = nil, *value)
+ new_args =
+ if ARGV.size == 1
+ ["config", "list"]
+ elsif ARGV.include?("--delete")
+ ARGV.map {|arg| arg == "--delete" ? "unset" : arg }
+ elsif ARGV.include?("--global") || ARGV.include?("--local") || ARGV.size == 3
+ ["config", "set", *ARGV[1..-1]]
+ else
+ ["config", "get", ARGV[1]]
+ end
- unless valid_scope?(scope)
- Bundler.ui.error "Invalid scope --#{scope} given. Please use --local or --global."
- exit 1
- end
+ SharedHelpers.major_deprecation 3,
+ "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead."
+
+ Base.new(options, name, value, self).run
+ end
+
+ desc "list", "List out all configured settings"
+ def list
+ Base.new(options, nil, nil, self).run
+ end
+
+ desc "get NAME", "Returns the value for the given key"
+ def get(name)
+ Base.new(options, name, nil, self).run
+ end
+
+ desc "set NAME VALUE", "Sets the given value for the given key"
+ scope_options
+ def set(name, value, *value_)
+ Base.new(options, name, value_.unshift(value), self).run
+ end
+
+ desc "unset NAME", "Unsets the value for the given key"
+ scope_options
+ def unset(name)
+ options[:delete] = true
+ Base.new(options, name, nil, self).run
+ end
- if scope == "delete"
- Bundler.settings.set_local(name, nil)
- Bundler.settings.set_global(name, nil)
- return
+ default_task :base
+
+ class Base
+ attr_reader :name, :value, :options, :scope, :thor
+
+ def initialize(options, name, value, thor)
+ @options = options
+ @name = name
+ value = Array(value)
+ @value = value.empty? ? nil : value.join(" ")
+ @thor = thor
+ validate_scope!
end
- if args.empty?
- if options[:parseable]
- if value = Bundler.settings[name]
- Bundler.ui.info("#{name}=#{value}")
+ def run
+ unless name
+ warn_unused_scope "Ignoring --#{scope}"
+ confirm_all
+ return
+ end
+
+ if options[:delete]
+ if !explicit_scope? || scope != "global"
+ Bundler.settings.set_local(name, nil)
+ end
+ if !explicit_scope? || scope != "local"
+ Bundler.settings.set_global(name, nil)
end
return
end
- confirm(name)
- return
- end
+ if value.nil?
+ warn_unused_scope "Ignoring --#{scope} since no value to set was given"
- Bundler.ui.info(message) if message
- Bundler.settings.send("set_#{scope}", name, new_value)
- end
+ if options[:parseable]
+ if value = Bundler.settings[name]
+ Bundler.ui.info("#{name}=#{value}")
+ end
+ return
+ end
- private
+ confirm(name)
+ return
+ end
- def confirm_all
- if @options[:parseable]
- thor.with_padding do
+ Bundler.ui.info(message) if message
+ Bundler.settings.send("set_#{scope}", name, new_value)
+ end
+
+ def confirm_all
+ if @options[:parseable]
+ thor.with_padding do
+ Bundler.settings.all.each do |setting|
+ val = Bundler.settings[setting]
+ Bundler.ui.info "#{setting}=#{val}"
+ end
+ end
+ else
+ Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n"
Bundler.settings.all.each do |setting|
- val = Bundler.settings[setting]
- Bundler.ui.info "#{setting}=#{val}"
+ Bundler.ui.confirm setting
+ show_pretty_values_for(setting)
+ Bundler.ui.confirm ""
end
end
- else
- Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n"
- Bundler.settings.all.each do |setting|
- Bundler.ui.confirm "#{setting}"
- show_pretty_values_for(setting)
- Bundler.ui.confirm ""
- end
end
- end
- def confirm(name)
- Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used"
- show_pretty_values_for(name)
- end
+ def confirm(name)
+ Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used"
+ show_pretty_values_for(name)
+ end
- def new_value
- pathname = Pathname.new(args.join(" "))
- if name.start_with?("local.") && pathname.directory?
- pathname.expand_path.to_s
- else
- args.join(" ")
+ def new_value
+ pathname = Pathname.new(value)
+ if name.start_with?("local.") && pathname.directory?
+ pathname.expand_path.to_s
+ else
+ value
+ end
end
- end
- def message
- locations = Bundler.settings.locations(name)
- if @options[:parseable]
- "#{name}=#{new_value}" if new_value
- elsif scope == "global"
- if locations[:local]
- "Your application has set #{name} to #{locations[:local].inspect}. " \
- "This will override the global value you are currently setting"
- elsif locations[:env]
- "You have a bundler environment variable for #{name} set to " \
- "#{locations[:env].inspect}. This will take precedence over the global value you are setting"
- elsif locations[:global] && locations[:global] != args.join(" ")
- "You are replacing the current global value of #{name}, which is currently " \
- "#{locations[:global].inspect}"
+ def message
+ locations = Bundler.settings.locations(name)
+ if @options[:parseable]
+ "#{name}=#{new_value}" if new_value
+ elsif scope == "global"
+ if !locations[:local].nil?
+ "Your application has set #{name} to #{locations[:local].inspect}. " \
+ "This will override the global value you are currently setting"
+ elsif locations[:env]
+ "You have a bundler environment variable for #{name} set to " \
+ "#{locations[:env].inspect}. This will take precedence over the global value you are setting"
+ elsif !locations[:global].nil? && locations[:global] != value
+ "You are replacing the current global value of #{name}, which is currently " \
+ "#{locations[:global].inspect}"
+ end
+ elsif scope == "local" && !locations[:local].nil? && locations[:local] != value
+ "You are replacing the current local value of #{name}, which is currently " \
+ "#{locations[:local].inspect}"
end
- elsif scope == "local" && locations[:local] != args.join(" ")
- "You are replacing the current local value of #{name}, which is currently " \
- "#{locations[:local].inspect}"
end
- end
- def show_pretty_values_for(setting)
- thor.with_padding do
- Bundler.settings.pretty_values_for(setting).each do |line|
- Bundler.ui.info line
+ def show_pretty_values_for(setting)
+ thor.with_padding do
+ Bundler.settings.pretty_values_for(setting).each do |line|
+ Bundler.ui.info line
+ end
end
end
- end
- def valid_scope?(scope)
- %w(delete local global).include?(scope)
+ def explicit_scope?
+ @explicit_scope
+ end
+
+ def warn_unused_scope(msg)
+ return unless explicit_scope?
+ return if options[:parseable]
+
+ Bundler.ui.warn(msg)
+ end
+
+ def validate_scope!
+ @explicit_scope = true
+ scopes = %w[global local].select {|s| options[s] }
+ case scopes.size
+ when 0
+ @scope = "global"
+ @explicit_scope = false
+ when 1
+ @scope = scopes.first
+ else
+ raise InvalidOption,
+ "The options #{scopes.join " and "} were specified. Please only use one of the switches at a time."
+ end
+ end
end
end
end
diff --git a/lib/bundler/cli/console.rb b/lib/bundler/cli/console.rb
index 715abf2554..97b8dc0663 100644
--- a/lib/bundler/cli/console.rb
+++ b/lib/bundler/cli/console.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Console
attr_reader :options, :group
@@ -8,10 +9,10 @@ module Bundler
end
def run
- Bundler::SharedHelpers.major_deprecation "bundle console will be replaced " \
+ Bundler::SharedHelpers.major_deprecation 2, "bundle console will be replaced " \
"by `bin/console` generated by `bundle gem <name>`"
- group ? Bundler.require(:default, *(group.split.map!(&:to_sym))) : Bundler.require
+ group ? Bundler.require(:default, *group.split(" ").map!(&:to_sym)) : Bundler.require
ARGV.clear
console = get_console(Bundler.settings[:console] || "irb")
diff --git a/lib/bundler/cli/doctor.rb b/lib/bundler/cli/doctor.rb
index ae27983240..43f1ca92e2 100644
--- a/lib/bundler/cli/doctor.rb
+++ b/lib/bundler/cli/doctor.rb
@@ -1,11 +1,12 @@
# frozen_string_literal: true
require "rbconfig"
+require "shellwords"
module Bundler
class CLI::Doctor
- DARWIN_REGEX = /\s+(.+) \(compatibility /
- LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/
+ DARWIN_REGEX = /\s+(.+) \(compatibility /.freeze
+ LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/.freeze
attr_reader :options
@@ -22,14 +23,14 @@ module Bundler
end
def dylibs_darwin(path)
- output = `/usr/bin/otool -L "#{path}"`.chomp
+ output = `/usr/bin/otool -L #{path.shellescape}`.chomp
dylibs = output.split("\n")[1..-1].map {|l| l.match(DARWIN_REGEX).captures[0] }.uniq
# ignore @rpath and friends
dylibs.reject {|dylib| dylib.start_with? "@" }
end
def dylibs_ldd(path)
- output = `/usr/bin/ldd "#{path}"`.chomp
+ output = `/usr/bin/ldd #{path.shellescape}`.chomp
output.split("\n").map do |l|
match = l.match(LDD_REGEX)
next if match.nil?
@@ -56,12 +57,13 @@ module Bundler
end
def check!
- require "bundler/cli/check"
+ require_relative "check"
Bundler::CLI::Check.new({}).run
end
def run
- Bundler.ui.level = "error" if options[:quiet]
+ Bundler.ui.level = "warn" if options[:quiet]
+ Bundler.settings.validate!
check!
definition = Bundler.definition
@@ -77,6 +79,8 @@ module Bundler
end
end
+ permissions_valid = check_home_permissions
+
if broken_links.any?
message = "The following gems are missing OS dependencies:"
broken_links.map do |spec, paths|
@@ -85,9 +89,63 @@ module Bundler
end
end.flatten.sort.each {|m| message += m }
raise ProductionError, message
- else
+ elsif !permissions_valid
Bundler.ui.info "No issues found with the installed bundle"
end
end
+
+ private
+
+ def check_home_permissions
+ require "find"
+ files_not_readable_or_writable = []
+ files_not_rw_and_owned_by_different_user = []
+ files_not_owned_by_current_user_but_still_rw = []
+ broken_symlinks = []
+ Find.find(Bundler.bundle_path.to_s).each do |f|
+ if !File.exist?(f)
+ broken_symlinks << f
+ elsif !File.writable?(f) || !File.readable?(f)
+ if File.stat(f).uid != Process.uid
+ files_not_rw_and_owned_by_different_user << f
+ else
+ files_not_readable_or_writable << f
+ end
+ elsif File.stat(f).uid != Process.uid
+ files_not_owned_by_current_user_but_still_rw << f
+ end
+ end
+
+ ok = true
+
+ if broken_symlinks.any?
+ Bundler.ui.warn "Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{broken_symlinks.join("\n - ")}"
+
+ ok = false
+ end
+
+ if files_not_owned_by_current_user_but_still_rw.any?
+ Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \
+ "user, but are still readable/writable. These files are:\n - #{files_not_owned_by_current_user_but_still_rw.join("\n - ")}"
+
+ ok = false
+ end
+
+ if files_not_rw_and_owned_by_different_user.any?
+ Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \
+ "user, and are not readable/writable. These files are:\n - #{files_not_rw_and_owned_by_different_user.join("\n - ")}"
+
+ ok = false
+ end
+
+ if files_not_readable_or_writable.any?
+ Bundler.ui.warn "Files exist in the Bundler home that are not " \
+ "readable/writable by the current user. These files are:\n - #{files_not_readable_or_writable.join("\n - ")}"
+
+ ok = false
+ end
+
+ ok
+ end
end
end
diff --git a/lib/bundler/cli/exec.rb b/lib/bundler/cli/exec.rb
index 62f7bc26cb..42b602a055 100644
--- a/lib/bundler/cli/exec.rb
+++ b/lib/bundler/cli/exec.rb
@@ -1,22 +1,18 @@
# frozen_string_literal: true
-require "bundler/current_ruby"
+
+require_relative "../current_ruby"
module Bundler
class CLI::Exec
attr_reader :options, :args, :cmd
- RESERVED_SIGNALS = %w(SEGV BUS ILL FPE VTALRM KILL STOP).freeze
+ TRAPPED_SIGNALS = %w[INT].freeze
def initialize(options, args)
@options = options
@cmd = args.shift
@args = args
-
- if Bundler.current_ruby.ruby_2? && !Bundler.current_ruby.jruby?
- @args << { :close_others => !options.keep_file_descriptors? }
- elsif options.keep_file_descriptors?
- Bundler.ui.warn "Ruby version #{RUBY_VERSION} defaults to keeping non-standard file descriptors on Kernel#exec."
- end
+ @args << { :close_others => !options.keep_file_descriptors? } unless Bundler.current_ruby.jruby?
end
def run
@@ -26,19 +22,14 @@ module Bundler
if !Bundler.settings[:disable_exec_load] && ruby_shebang?(bin_path)
return kernel_load(bin_path, *args)
end
- # First, try to exec directly to something in PATH
- if Bundler.current_ruby.jruby_18?
- kernel_exec(bin_path, *args)
- else
- kernel_exec([bin_path, cmd], *args)
- end
+ kernel_exec(bin_path, *args)
else
# exec using the given command
kernel_exec(cmd, *args)
end
end
- private
+ private
def validate_cmd!
return unless cmd.nil?
@@ -47,15 +38,11 @@ module Bundler
end
def kernel_exec(*args)
- ui = Bundler.ui
- Bundler.ui = nil
Kernel.exec(*args)
rescue Errno::EACCES, Errno::ENOEXEC
- Bundler.ui = ui
Bundler.ui.error "bundler: not executable: #{cmd}"
exit 126
rescue Errno::ENOENT
- Bundler.ui = ui
Bundler.ui.error "bundler: command not found: #{cmd}"
Bundler.ui.warn "Install missing gem executables with `bundle install`"
exit 127
@@ -66,19 +53,15 @@ module Bundler
ARGV.replace(args)
$0 = file
Process.setproctitle(process_title(file, args)) if Process.respond_to?(:setproctitle)
- ui = Bundler.ui
- Bundler.ui = nil
- require "bundler/setup"
- signals = Signal.list.keys - RESERVED_SIGNALS
- signals.each {|s| trap(s, "DEFAULT") }
+ require_relative "../setup"
+ TRAPPED_SIGNALS.each {|s| trap(s, "DEFAULT") }
Kernel.load(file)
- rescue SystemExit
+ rescue SystemExit, SignalException
raise
- rescue Exception => e # rubocop:disable Lint/RescueException
- Bundler.ui = ui
+ rescue Exception # rubocop:disable Lint/RescueException
Bundler.ui.error "bundler: failed to load command: #{cmd} (#{file})"
- backtrace = e.backtrace.take_while {|bt| !bt.start_with?(__FILE__) }
- abort "#{e.class}: #{e.message}\n #{backtrace.join("\n ")}"
+ Bundler::FriendlyErrors.disable!
+ raise
end
def process_title(file, args)
@@ -89,6 +72,7 @@ module Bundler
possibilities = [
"#!/usr/bin/env ruby\n",
"#!/usr/bin/env jruby\n",
+ "#!/usr/bin/env truffleruby\n",
"#!#{Gem.ruby}\n",
]
diff --git a/lib/bundler/cli/fund.rb b/lib/bundler/cli/fund.rb
new file mode 100644
index 0000000000..52db5aef68
--- /dev/null
+++ b/lib/bundler/cli/fund.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Bundler
+ class CLI::Fund
+ attr_reader :options
+
+ def initialize(options)
+ @options = options
+ end
+
+ def run
+ Bundler.definition.validate_runtime!
+
+ groups = Array(options[:group]).map(&:to_sym)
+
+ deps = if groups.any?
+ Bundler.definition.dependencies_for(groups)
+ else
+ Bundler.definition.current_dependencies
+ end
+
+ fund_info = deps.each_with_object([]) do |dep, arr|
+ spec = Bundler.definition.specs[dep.name].first
+ if spec.metadata.key?("funding_uri")
+ arr << "* #{spec.name} (#{spec.version})\n Funding: #{spec.metadata["funding_uri"]}"
+ end
+ end
+
+ if fund_info.empty?
+ Bundler.ui.info "None of the installed gems you directly depend on are looking for funding."
+ else
+ Bundler.ui.info fund_info.join("\n")
+ end
+ end
+ end
+end
diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb
index fed904e9aa..2a74325fde 100644
--- a/lib/bundler/cli/gem.rb
+++ b/lib/bundler/cli/gem.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "pathname"
module Bundler
@@ -10,7 +11,8 @@ module Bundler
class CLI::Gem
TEST_FRAMEWORK_VERSIONS = {
"rspec" => "3.0",
- "minitest" => "5.0"
+ "minitest" => "5.0",
+ "test-unit" => "3.0",
}.freeze
attr_reader :options, :gem_name, :thor, :name, :target
@@ -37,11 +39,19 @@ module Bundler
constant_name = name.gsub(/-[_-]*(?![_-]|$)/) { "::" }.gsub(/([_-]+|(::)|^)(.|$)/) { $2.to_s + $3.upcase }
constant_array = constant_name.split("::")
- git_installed = Bundler.git_present?
+ use_git = Bundler.git_present? && options[:git]
+
+ git_author_name = use_git ? `git config user.name`.chomp : ""
+ git_username = use_git ? `git config github.user`.chomp : ""
+ git_user_email = use_git ? `git config user.email`.chomp : ""
- git_author_name = git_installed ? `git config user.name`.chomp : ""
- github_username = git_installed ? `git config github.user`.chomp : ""
- git_user_email = git_installed ? `git config user.email`.chomp : ""
+ github_username = if options[:github_username].nil?
+ git_username
+ elsif options[:github_username] == false
+ ""
+ else
+ options[:github_username]
+ end
config = {
:name => name,
@@ -56,34 +66,35 @@ module Bundler
:ext => options[:ext],
:exe => options[:exe],
:bundler_version => bundler_dependency_version,
- :github_username => github_username.empty? ? "[USERNAME]" : github_username
+ :git => use_git,
+ :github_username => github_username.empty? ? "[USERNAME]" : github_username,
+ :required_ruby_version => required_ruby_version,
}
ensure_safe_gem_name(name, constant_array)
templates = {
- "Gemfile.tt" => "Gemfile",
+ "#{Bundler.preferred_gemfile_name}.tt" => Bundler.preferred_gemfile_name,
"lib/newgem.rb.tt" => "lib/#{namespaced_path}.rb",
"lib/newgem/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
+ "sig/newgem.rbs.tt" => "sig/#{namespaced_path}.rbs",
"newgem.gemspec.tt" => "#{name}.gemspec",
"Rakefile.tt" => "Rakefile",
"README.md.tt" => "README.md",
"bin/console.tt" => "bin/console",
- "bin/setup.tt" => "bin/setup"
+ "bin/setup.tt" => "bin/setup",
}
- executables = %w(
+ executables = %w[
bin/console
bin/setup
- )
+ ]
- templates.merge!("gitignore.tt" => ".gitignore") if Bundler.git_present?
+ templates.merge!("gitignore.tt" => ".gitignore") if use_git
if test_framework = ask_and_set_test_framework
config[:test] = test_framework
config[:test_framework_version] = TEST_FRAMEWORK_VERSIONS[test_framework]
- templates.merge!("travis.yml.tt" => ".travis.yml")
-
case test_framework
when "rspec"
templates.merge!(
@@ -91,20 +102,38 @@ module Bundler
"spec/spec_helper.rb.tt" => "spec/spec_helper.rb",
"spec/newgem_spec.rb.tt" => "spec/#{namespaced_path}_spec.rb"
)
+ config[:test_task] = :spec
when "minitest"
templates.merge!(
- "test/test_helper.rb.tt" => "test/test_helper.rb",
- "test/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
+ "test/minitest/test_helper.rb.tt" => "test/test_helper.rb",
+ "test/minitest/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
)
+ config[:test_task] = :test
+ when "test-unit"
+ templates.merge!(
+ "test/test-unit/test_helper.rb.tt" => "test/test_helper.rb",
+ "test/test-unit/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
+ )
+ config[:test_task] = :test
end
end
- config[:test_task] = config[:test] == "minitest" ? "test" : "spec"
+ config[:ci] = ask_and_set_ci
+ case config[:ci]
+ when "github"
+ templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml")
+ when "travis"
+ templates.merge!("travis.yml.tt" => ".travis.yml")
+ when "gitlab"
+ templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml")
+ when "circle"
+ templates.merge!("circleci/config.yml.tt" => ".circleci/config.yml")
+ end
if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?",
"This means that any other developer or company will be legally allowed to use your code " \
"for free as long as they admit you created it. You can read more about the MIT license " \
- "at http://choosealicense.com/licenses/mit.")
+ "at https://choosealicense.com/licenses/mit.")
config[:mit] = true
Bundler.ui.info "MIT License enabled in config"
templates.merge!("LICENSE.txt.tt" => "LICENSE.txt")
@@ -117,12 +146,36 @@ module Bundler
"of enforcing it, so be sure that you are prepared to do that. Be sure that your email " \
"address is specified as a contact in the generated code of conduct so that people know " \
"who to contact in case of a violation. For suggestions about " \
- "how to enforce codes of conduct, see http://bit.ly/coc-enforcement.")
+ "how to enforce codes of conduct, see https://bit.ly/coc-enforcement.")
config[:coc] = true
Bundler.ui.info "Code of conduct enabled in config"
templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md")
end
+ if ask_and_set(:changelog, "Do you want to include a changelog?",
+ "A changelog is a file which contains a curated, chronologically ordered list of notable " \
+ "changes for each version of a project. To make it easier for users and contributors to" \
+ " see precisely what notable changes have been made between each release (or version) of" \
+ " the project. Whether consumers or developers, the end users of software are" \
+ " human beings who care about what's in the software. When the software changes, people " \
+ "want to know why and how. see https://keepachangelog.com")
+ config[:changelog] = true
+ Bundler.ui.info "Changelog enabled in config"
+ templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
+ end
+
+ config[:linter] = ask_and_set_linter
+ case config[:linter]
+ when "rubocop"
+ config[:linter_version] = rubocop_version
+ Bundler.ui.info "RuboCop enabled in config"
+ templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
+ when "standard"
+ config[:linter_version] = standard_version
+ Bundler.ui.info "Standard enabled in config"
+ templates.merge!("standard.yml.tt" => ".standard.yml")
+ end
+
templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
if options[:ext]
@@ -133,35 +186,44 @@ module Bundler
)
end
+ if target.exist? && !target.directory?
+ Bundler.ui.error "Couldn't create a new gem named `#{gem_name}` because there's an existing file named `#{gem_name}`."
+ exit Bundler::BundlerError.all_errors[Bundler::GenericSystemCallError]
+ end
+
+ if use_git
+ Bundler.ui.info "Initializing git repo in #{target}"
+ require "shellwords"
+ `git init #{target.to_s.shellescape}`
+
+ config[:git_default_branch] = File.read("#{target}/.git/HEAD").split("/").last.chomp
+ end
+
templates.each do |src, dst|
destination = target.join(dst)
- SharedHelpers.filesystem_access(destination) do
- thor.template("newgem/#{src}", destination, config)
- end
+ thor.template("newgem/#{src}", destination, config)
end
executables.each do |file|
- SharedHelpers.filesystem_access(target.join(file)) do |path|
- executable = (path.stat.mode | 0o111)
- path.chmod(executable)
- end
+ path = target.join(file)
+ executable = (path.stat.mode | 0o111)
+ path.chmod(executable)
end
- if Bundler.git_present?
- Bundler.ui.info "Initializing git repo in #{target}"
+ if use_git
Dir.chdir(target) do
- `git init`
`git add .`
end
end
# Open gemspec in editor
open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit]
- rescue Errno::EEXIST => e
- raise GenericSystemCallError.new(e, "There was a conflict while creating the new gem.")
+
+ Bundler.ui.info "Gem '#{name}' was successfully created. " \
+ "For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
end
- private
+ private
def resolve_name(name)
SharedHelpers.pwd.join(name).basename.to_s
@@ -186,18 +248,19 @@ module Bundler
Bundler.ui.error "You have specified a gem name which does not conform to the \n" \
"naming guidelines for C extensions. For more information, \n" \
"see the 'Extension Naming' section at the following URL:\n" \
- "http://guides.rubygems.org/gems-with-extensions/\n"
+ "https://guides.rubygems.org/gems-with-extensions/\n"
exit 1
end
def ask_and_set_test_framework
test_framework = options[:test] || Bundler.settings["gem.test"]
- if test_framework.nil?
+ if test_framework.to_s.empty?
Bundler.ui.confirm "Do you want to generate tests with your gem?"
- result = Bundler.ui.ask "Type 'rspec' or 'minitest' to generate those test files now and " \
- "in the future. rspec/minitest/(none):"
- if result =~ /rspec|minitest/
+ Bundler.ui.info hint_text("test")
+
+ result = Bundler.ui.ask "Enter a test framework. rspec/minitest/test-unit/(none):"
+ if result =~ /rspec|minitest|test-unit/
test_framework = result
else
test_framework = false
@@ -208,9 +271,106 @@ module Bundler
Bundler.settings.set_global("gem.test", test_framework)
end
+ if options[:test] == Bundler.settings["gem.test"]
+ Bundler.ui.info "#{options[:test]} is already configured, ignoring --test flag."
+ end
+
test_framework
end
+ def hint_text(setting)
+ if Bundler.settings["gem.#{setting}"] == false
+ "Your choice will only be applied to this gem."
+ else
+ "Future `bundle gem` calls will use your choice. " \
+ "This setting can be changed anytime with `bundle config gem.#{setting}`."
+ end
+ end
+
+ def ask_and_set_ci
+ ci_template = options[:ci] || Bundler.settings["gem.ci"]
+
+ if ci_template.to_s.empty?
+ Bundler.ui.confirm "Do you want to set up continuous integration for your gem? " \
+ "Supported services:\n" \
+ "* CircleCI: https://circleci.com/\n" \
+ "* GitHub Actions: https://github.com/features/actions\n" \
+ "* GitLab CI: https://docs.gitlab.com/ee/ci/\n" \
+ "* Travis CI: https://travis-ci.org/\n" \
+ "\n"
+ Bundler.ui.info hint_text("ci")
+
+ result = Bundler.ui.ask "Enter a CI service. github/travis/gitlab/circle/(none):"
+ if result =~ /github|travis|gitlab|circle/
+ ci_template = result
+ else
+ ci_template = false
+ end
+ end
+
+ if Bundler.settings["gem.ci"].nil?
+ Bundler.settings.set_global("gem.ci", ci_template)
+ end
+
+ if options[:ci] == Bundler.settings["gem.ci"]
+ Bundler.ui.info "#{options[:ci]} is already configured, ignoring --ci flag."
+ end
+
+ ci_template
+ end
+
+ def ask_and_set_linter
+ linter_template = options[:linter] || Bundler.settings["gem.linter"]
+ linter_template = deprecated_rubocop_option if linter_template.nil?
+
+ if linter_template.to_s.empty?
+ Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
+ "Supported Linters:\n" \
+ "* RuboCop: https://rubocop.org\n" \
+ "* Standard: https://github.com/testdouble/standard\n" \
+ "\n"
+ Bundler.ui.info hint_text("linter")
+
+ result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):"
+ if result =~ /rubocop|standard/
+ linter_template = result
+ else
+ linter_template = false
+ end
+ end
+
+ if Bundler.settings["gem.linter"].nil?
+ Bundler.settings.set_global("gem.linter", linter_template)
+ end
+
+ # Once gem.linter safely set, unset the deprecated gem.rubocop
+ unless Bundler.settings["gem.rubocop"].nil?
+ Bundler.settings.set_global("gem.rubocop", nil)
+ end
+
+ if options[:linter] == Bundler.settings["gem.linter"]
+ Bundler.ui.info "#{options[:linter]} is already configured, ignoring --linter flag."
+ end
+
+ linter_template
+ end
+
+ def deprecated_rubocop_option
+ if !options[:rubocop].nil?
+ if options[:rubocop]
+ Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
+ "rubocop"
+ else
+ Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
+ false
+ end
+ elsif !Bundler.settings["gem.rubocop"].nil?
+ Bundler::SharedHelpers.major_deprecation 2,
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
+ Bundler.settings["gem.rubocop"] ? "rubocop" : false
+ end
+ end
+
def bundler_dependency_version
v = Gem::Version.new(Bundler::VERSION)
req = v.segments[0..1]
@@ -244,5 +404,30 @@ module Bundler
def open_editor(editor, file)
thor.run(%(#{editor} "#{file}"))
end
+
+ def required_ruby_version
+ if Gem.ruby_version < Gem::Version.new("2.4.a") then "2.3.0"
+ elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "2.4.0"
+ elsif Gem.ruby_version < Gem::Version.new("2.6.a") then "2.5.0"
+ else
+ "2.6.0"
+ end
+ end
+
+ def rubocop_version
+ if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.81.0"
+ elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.12"
+ else
+ "1.21"
+ end
+ end
+
+ def standard_version
+ if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.2.5"
+ elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.0"
+ else
+ "1.3"
+ end
+ end
end
end
diff --git a/lib/bundler/cli/info.rb b/lib/bundler/cli/info.rb
index 4465fba9d4..76c8cf60c0 100644
--- a/lib/bundler/cli/info.rb
+++ b/lib/bundler/cli/info.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Info
@@ -10,18 +9,25 @@ module Bundler
end
def run
+ Bundler.ui.silence do
+ Bundler.definition.validate_runtime!
+ Bundler.load.lock
+ end
+
spec = spec_for_gem(gem_name)
- spec_not_found(gem_name) unless spec
- return print_gem_path(spec) if @options[:path]
- print_gem_info(spec)
+ if spec
+ return print_gem_path(spec) if @options[:path]
+ return print_gem_version(spec) if @options[:version]
+ print_gem_info(spec)
+ end
end
- private
+ private
def spec_for_gem(gem_name)
spec = Bundler.definition.specs.find {|s| s.name == gem_name }
- spec || default_gem_spec(gem_name)
+ spec || default_gem_spec(gem_name) || Bundler::CLI::Common.select_spec(gem_name, :regex_match)
end
def default_gem_spec(gem_name)
@@ -34,17 +40,45 @@ module Bundler
raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(gem_name, Bundler.definition.dependencies)
end
+ def print_gem_version(spec)
+ Bundler.ui.info spec.version.to_s
+ end
+
def print_gem_path(spec)
- Bundler.ui.info spec.full_gem_path
+ name = spec.name
+ if name == "bundler"
+ path = File.expand_path("../../../..", __FILE__)
+ else
+ path = spec.full_gem_path
+ if spec.deleted_gem?
+ return Bundler.ui.warn "The gem #{name} has been deleted. It was installed at: #{path}"
+ end
+ end
+
+ Bundler.ui.info path
end
def print_gem_info(spec)
+ metadata = spec.metadata
+ name = spec.name
gem_info = String.new
- gem_info << " * #{spec.name} (#{spec.version}#{spec.git_version})\n"
+ gem_info << " * #{name} (#{spec.version}#{spec.git_version})\n"
gem_info << "\tSummary: #{spec.summary}\n" if spec.summary
gem_info << "\tHomepage: #{spec.homepage}\n" if spec.homepage
+ gem_info << "\tDocumentation: #{metadata["documentation_uri"]}\n" if metadata.key?("documentation_uri")
+ gem_info << "\tSource Code: #{metadata["source_code_uri"]}\n" if metadata.key?("source_code_uri")
+ gem_info << "\tFunding: #{metadata["funding_uri"]}\n" if metadata.key?("funding_uri")
+ gem_info << "\tWiki: #{metadata["wiki_uri"]}\n" if metadata.key?("wiki_uri")
+ gem_info << "\tChangelog: #{metadata["changelog_uri"]}\n" if metadata.key?("changelog_uri")
+ gem_info << "\tBug Tracker: #{metadata["bug_tracker_uri"]}\n" if metadata.key?("bug_tracker_uri")
+ gem_info << "\tMailing List: #{metadata["mailing_list_uri"]}\n" if metadata.key?("mailing_list_uri")
gem_info << "\tPath: #{spec.full_gem_path}\n"
gem_info << "\tDefault Gem: yes" if spec.respond_to?(:default_gem?) && spec.default_gem?
+
+ if name != "bundler" && spec.deleted_gem?
+ return Bundler.ui.warn "The gem #{name} has been deleted. Gemspec information is still available though:\n#{gem_info}"
+ end
+
Bundler.ui.info gem_info
end
end
diff --git a/lib/bundler/cli/init.rb b/lib/bundler/cli/init.rb
index 8ffd1db41a..d851d02d42 100644
--- a/lib/bundler/cli/init.rb
+++ b/lib/bundler/cli/init.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Init
attr_reader :options
@@ -7,8 +8,13 @@ module Bundler
end
def run
- if File.exist?("Gemfile")
- Bundler.ui.error "Gemfile already exists at #{SharedHelpers.pwd}/Gemfile"
+ if File.exist?(gemfile)
+ Bundler.ui.error "#{gemfile} already exists at #{File.expand_path(gemfile)}"
+ exit 1
+ end
+
+ unless File.writable?(Dir.pwd)
+ Bundler.ui.error "Can not create #{gemfile} as the current directory is not writable."
exit 1
end
@@ -21,15 +27,21 @@ module Bundler
spec = Bundler.load_gemspec_uncached(gemspec)
- puts "Writing new Gemfile to #{SharedHelpers.pwd}/Gemfile"
- File.open("Gemfile", "wb") do |file|
+ File.open(gemfile, "wb") do |file|
file << "# Generated from #{gemspec}\n"
file << spec.to_gemfile
end
else
- puts "Writing new Gemfile to #{SharedHelpers.pwd}/Gemfile"
- FileUtils.cp(File.expand_path("../../templates/Gemfile", __FILE__), "Gemfile")
+ FileUtils.cp(File.expand_path("../../templates/#{gemfile}", __FILE__), gemfile)
end
+
+ puts "Writing new #{gemfile} to #{SharedHelpers.pwd}/#{gemfile}"
+ end
+
+ private
+
+ def gemfile
+ @gemfile ||= Bundler.preferred_gemfile_name
end
end
end
diff --git a/lib/bundler/cli/inject.rb b/lib/bundler/cli/inject.rb
index b17292643f..8093a85283 100644
--- a/lib/bundler/cli/inject.rb
+++ b/lib/bundler/cli/inject.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Inject
attr_reader :options, :name, :version, :group, :source, :gems
@@ -43,7 +44,7 @@ module Bundler
end
end
- private
+ private
def last_version_number
definition = Bundler.definition(true)
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index ff6bedd9fd..4c1915fea6 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Install
@@ -9,21 +8,11 @@ module Bundler
end
def run
- Bundler.ui.level = "error" if options[:quiet]
+ Bundler.ui.level = "warn" if options[:quiet]
warn_if_root
- [:with, :without].each do |option|
- if options[option]
- options[option] = options[option].join(":").tr(" ", ":").split(":")
- end
- end
-
- check_for_group_conflicts
-
- normalize_groups
-
- ENV["RB_USER_INSTALL"] = "1" if Bundler::FREEBSD
+ Bundler::SharedHelpers.set_env "RB_USER_INSTALL", "1" if Bundler::FREEBSD
# Disable color in deployment mode
Bundler.ui.shell = Thor::Shell::Basic.new if options[:deployment]
@@ -32,22 +21,25 @@ module Bundler
check_trust_policy
- if options[:deployment] || options[:frozen]
+ if options[:deployment] || options[:frozen] || Bundler.frozen_bundle?
unless Bundler.default_lockfile.exist?
- flag = options[:deployment] ? "--deployment" : "--frozen"
- raise ProductionError, "The #{flag} flag requires a #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}. Please make " \
+ flag = "--deployment flag" if options[:deployment]
+ flag ||= "--frozen flag" if options[:frozen]
+ flag ||= "deployment setting"
+ raise ProductionError, "The #{flag} requires a #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}. Please make " \
"sure you have checked your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} into version control " \
"before deploying."
end
options[:local] = true if Bundler.app_cache.exist?
- Bundler.settings[:frozen] = "1"
+ Bundler.settings.set_command_option :deployment, true if options[:deployment]
+ Bundler.settings.set_command_option :frozen, true if options[:frozen]
end
# When install is called with --no-deployment, disable deployment mode
if options[:deployment] == false
- Bundler.settings.delete(:frozen)
+ Bundler.settings.set_command_option :frozen, nil
options[:system] = true
end
@@ -56,8 +48,8 @@ module Bundler
Bundler::Fetcher.disable_endpoint = options["full-index"]
if options["binstubs"]
- Bundler::SharedHelpers.major_deprecation \
- "The --binstubs option will be removed in favor of `bundle binstubs`"
+ Bundler::SharedHelpers.major_deprecation 2,
+ "The --binstubs option will be removed in favor of `bundle binstubs --all`"
end
Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins?
@@ -66,49 +58,40 @@ module Bundler
definition.validate_runtime!
installer = Installer.install(Bundler.root, definition, options)
- Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.settings[:frozen]
+
+ Bundler.settings.temporary(:cache_all_platforms => options[:local] ? false : Bundler.settings[:cache_all_platforms]) do
+ Bundler.load.cache(nil, options[:local]) if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
+ end
Bundler.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}."
- Bundler::CLI::Common.output_without_groups_message
+ Bundler::CLI::Common.output_without_groups_message(:install)
- if Bundler.settings[:path]
- absolute_path = File.expand_path(Bundler.settings[:path])
- relative_path = absolute_path.sub(File.expand_path(".") + File::SEPARATOR, "." + File::SEPARATOR)
- Bundler.ui.confirm "Bundled gems are installed into #{relative_path}."
- else
+ if Bundler.use_system_gems?
Bundler.ui.confirm "Use `bundle info [gemname]` to see where a bundled gem is installed."
+ else
+ relative_path = Bundler.configured_bundle_path.base_path_relative_to_pwd
+ Bundler.ui.confirm "Bundled gems are installed into `#{relative_path}`"
end
Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
warn_ambiguous_gems
- if Bundler.settings[:clean] && Bundler.settings[:path]
- require "bundler/cli/clean"
+ if CLI::Common.clean_after_install?
+ require_relative "clean"
Bundler::CLI::Clean.new(options).run
end
- rescue GemNotFound, VersionConflict => e
- if options[:local] && Bundler.app_cache.exist?
- Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
- end
- unless Bundler.definition.has_rubygems_remotes?
- Bundler.ui.warn <<-WARN, :wrap => true
- Your Gemfile has no gem server sources. If you need gems that are \
- not already on your machine, add a line like this to your Gemfile:
- source 'https://rubygems.org'
- WARN
- end
- raise e
- rescue Gem::InvalidSpecificationException => e
+ Bundler::CLI::Common.output_fund_metadata_summary
+ rescue Gem::InvalidSpecificationException
Bundler.ui.warn "You have one or more invalid gemspecs that need to be fixed."
- raise e
+ raise
end
- private
+ private
def warn_if_root
- return if Bundler.settings[:silence_root_warning] || Bundler::WINDOWS || !Process.uid.zero?
+ return if Bundler.settings[:silence_root_warning] || Gem.win_platform? || !Process.uid.zero?
Bundler.ui.warn "Don't run Bundler as root. Bundler can ask for sudo " \
"if it is needed, and installing your bundle as root will break this " \
"application for all non-root users on this machine.", :wrap => true
@@ -124,15 +107,11 @@ module Bundler
"#{count} #{count == 1 ? "gem" : "gems"} now installed"
end
- def check_for_group_conflicts
- if options[:without] && options[:with]
- conflicting_groups = options[:without] & options[:with]
- unless conflicting_groups.empty?
- Bundler.ui.error "You can't list a group in both, --with and --without." \
- " The offending groups are: #{conflicting_groups.join(", ")}."
- exit 1
- end
- end
+ def check_for_group_conflicts_in_cli_options
+ conflicting_groups = Array(options[:without]) & Array(options[:with])
+ return if conflicting_groups.empty?
+ raise InvalidOption, "You can't list a group in both with and without." \
+ " The offending groups are: #{conflicting_groups.join(", ")}."
end
def check_for_options_conflicts
@@ -145,69 +124,83 @@ module Bundler
end
def check_trust_policy
- if options["trust-policy"]
- unless Bundler.rubygems.security_policies.keys.include?(options["trust-policy"])
- Bundler.ui.error "Rubygems doesn't know about trust policy '#{options["trust-policy"]}'. " \
- "The known policies are: #{Bundler.rubygems.security_policies.keys.join(", ")}."
- exit 1
- end
- Bundler.settings["trust-policy"] = options["trust-policy"]
- else
- Bundler.settings["trust-policy"] = nil if Bundler.settings["trust-policy"]
+ trust_policy = options["trust-policy"]
+ unless Bundler.rubygems.security_policies.keys.unshift(nil).include?(trust_policy)
+ raise InvalidOption, "RubyGems doesn't know about trust policy '#{trust_policy}'. " \
+ "The known policies are: #{Bundler.rubygems.security_policies.keys.join(", ")}."
end
+ Bundler.settings.set_command_option_if_given :"trust-policy", trust_policy
end
def normalize_groups
- Bundler.settings.with = [] if options[:with] && options[:with].empty?
- Bundler.settings.without = [] if options[:without] && options[:without].empty?
+ options[:with] &&= options[:with].join(":").tr(" ", ":").split(":")
+ options[:without] &&= options[:without].join(":").tr(" ", ":").split(":")
+
+ check_for_group_conflicts_in_cli_options
+
+ Bundler.settings.set_command_option :with, nil if options[:with] == []
+ Bundler.settings.set_command_option :without, nil if options[:without] == []
- with = options.fetch("with", [])
- with |= Bundler.settings.with.map(&:to_s)
+ with = options.fetch(:with, [])
+ with |= Bundler.settings[:with].map(&:to_s)
with -= options[:without] if options[:without]
- without = options.fetch("without", [])
- without |= Bundler.settings.without.map(&:to_s)
+ without = options.fetch(:without, [])
+ without |= Bundler.settings[:without].map(&:to_s)
without -= options[:with] if options[:with]
options[:with] = with
options[:without] = without
+
+ unless Bundler.settings[:without] == options[:without] && Bundler.settings[:with] == options[:with]
+ # need to nil them out first to get around validation for backwards compatibility
+ Bundler.settings.set_command_option :without, nil
+ Bundler.settings.set_command_option :with, nil
+ Bundler.settings.set_command_option :without, options[:without] - options[:with]
+ Bundler.settings.set_command_option :with, options[:with]
+ end
end
def normalize_settings
- Bundler.settings[:path] = nil if options[:system]
- Bundler.settings[:path] = "vendor/bundle" if options[:deployment]
- Bundler.settings[:path] = options["path"] if options["path"]
- Bundler.settings[:path] ||= "bundle" if options["standalone"]
+ Bundler.settings.set_command_option :path, nil if options[:system]
+ Bundler.settings.temporary(:path_relative_to_cwd => false) do
+ Bundler.settings.set_command_option :path, "vendor/bundle" if Bundler.settings[:deployment] && Bundler.settings[:path].nil?
+ end
+ Bundler.settings.set_command_option_if_given :path, options[:path]
+ Bundler.settings.temporary(:path_relative_to_cwd => false) do
+ Bundler.settings.set_command_option :path, "bundle" if options["standalone"] && Bundler.settings[:path].nil?
+ end
- Bundler.settings[:bin] = options["binstubs"] if options["binstubs"]
- Bundler.settings[:bin] = nil if options["binstubs"] && options["binstubs"].empty?
+ bin_option = options["binstubs"]
+ bin_option = nil if bin_option && bin_option.empty?
+ Bundler.settings.set_command_option :bin, bin_option if options["binstubs"]
- Bundler.settings[:shebang] = options["shebang"] if options["shebang"]
+ Bundler.settings.set_command_option_if_given :shebang, options["shebang"]
- Bundler.settings[:jobs] = options["jobs"] if options["jobs"]
+ Bundler.settings.set_command_option_if_given :jobs, options["jobs"]
- Bundler.settings[:no_prune] = true if options["no-prune"]
+ Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"]
- Bundler.settings[:no_install] = true if options["no-install"]
+ Bundler.settings.set_command_option_if_given :no_install, options["no-install"]
- Bundler.settings[:clean] = options["clean"] if options["clean"]
+ Bundler.settings.set_command_option_if_given :clean, options["clean"]
- Bundler.settings.without = options[:without]
- Bundler.settings.with = options[:with]
+ normalize_groups
- Bundler.settings[:disable_shared_gems] = Bundler.settings[:path] ? true : nil
+ options[:force] = options[:redownload]
end
def warn_ambiguous_gems
+ # TODO: remove this when we drop Bundler 1.x support
Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris|
- Bundler.ui.error "Warning: the gem '#{name}' was found in multiple sources."
- Bundler.ui.error "Installed from: #{installed_from_uri}"
- Bundler.ui.error "Also found in:"
- also_found_in_uris.each {|uri| Bundler.ui.error " * #{uri}" }
- Bundler.ui.error "You should add a source requirement to restrict this gem to your preferred source."
- Bundler.ui.error "For example:"
- Bundler.ui.error " gem '#{name}', :source => '#{installed_from_uri}'"
- Bundler.ui.error "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
+ Bundler.ui.warn "Warning: the gem '#{name}' was found in multiple sources."
+ Bundler.ui.warn "Installed from: #{installed_from_uri}"
+ Bundler.ui.warn "Also found in:"
+ also_found_in_uris.each {|uri| Bundler.ui.warn " * #{uri}" }
+ Bundler.ui.warn "You should add a source requirement to restrict this gem to your preferred source."
+ Bundler.ui.warn "For example:"
+ Bundler.ui.warn " gem '#{name}', :source => '#{installed_from_uri}'"
+ Bundler.ui.warn "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
end
end
end
diff --git a/lib/bundler/cli/issue.rb b/lib/bundler/cli/issue.rb
index ace0f985a9..b891ecb1d2 100644
--- a/lib/bundler/cli/issue.rb
+++ b/lib/bundler/cli/issue.rb
@@ -10,30 +10,31 @@ module Bundler
be sure to check out these resources:
1. Check out our troubleshooting guide for quick fixes to common issues:
- https://github.com/bundler/bundler/blob/master/doc/TROUBLESHOOTING.md
+ https://github.com/rubygems/rubygems/blob/master/bundler/doc/TROUBLESHOOTING.md
2. Instructions for common Bundler uses can be found on the documentation
- site: http://bundler.io/
+ site: https://bundler.io/
3. Information about each Bundler command can be found in the Bundler
- man pages: http://bundler.io/man/bundle.1.html
+ man pages: https://bundler.io/man/bundle.1.html
Hopefully the troubleshooting steps above resolved your problem! If things
still aren't working the way you expect them to, please let us know so
- that we can diagnose and help fix the problem you're having. Please
- view the Filing Issues guide for more information:
- https://github.com/bundler/bundler/blob/master/doc/contributing/ISSUES.md
+ that we can diagnose and help fix the problem you're having, by filling
+ in the new issue form located at
+ https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md,
+ and copy and pasting the information below.
EOS
- Bundler.ui.info Bundler::Env.new.report
+ Bundler.ui.info Bundler::Env.report
Bundler.ui.info "\n## Bundle Doctor"
doctor
end
def doctor
- require "bundler/cli/doctor"
+ require_relative "doctor"
Bundler::CLI::Doctor.new({}).run
end
end
diff --git a/lib/bundler/cli/list.rb b/lib/bundler/cli/list.rb
new file mode 100644
index 0000000000..f56bf5b86a
--- /dev/null
+++ b/lib/bundler/cli/list.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+module Bundler
+ class CLI::List
+ def initialize(options)
+ @options = options
+ @without_group = options["without-group"].map(&:to_sym)
+ @only_group = options["only-group"].map(&:to_sym)
+ end
+
+ def run
+ raise InvalidOption, "The `--only-group` and `--without-group` options cannot be used together" if @only_group.any? && @without_group.any?
+
+ raise InvalidOption, "The `--name-only` and `--paths` options cannot be used together" if @options["name-only"] && @options[:paths]
+
+ specs = if @only_group.any? || @without_group.any?
+ filtered_specs_by_groups
+ else
+ begin
+ Bundler.load.specs
+ rescue GemNotFound => e
+ Bundler.ui.error e.message
+ Bundler.ui.warn "Install missing gems with `bundle install`."
+ exit 1
+ end
+ end.reject {|s| s.name == "bundler" }.sort_by(&:name)
+
+ return Bundler.ui.info "No gems in the Gemfile" if specs.empty?
+
+ return specs.each {|s| Bundler.ui.info s.name } if @options["name-only"]
+ return specs.each {|s| Bundler.ui.info s.full_gem_path } if @options["paths"]
+
+ Bundler.ui.info "Gems included by the bundle:"
+
+ specs.each {|s| Bundler.ui.info " * #{s.name} (#{s.version}#{s.git_version})" }
+
+ Bundler.ui.info "Use `bundle info` to print more detailed information about a gem"
+ end
+
+ private
+
+ def verify_group_exists(groups)
+ (@without_group + @only_group).each do |group|
+ raise InvalidOption, "`#{group}` group could not be found." unless groups.include?(group)
+ end
+ end
+
+ def filtered_specs_by_groups
+ definition = Bundler.definition
+ groups = definition.groups
+
+ verify_group_exists(groups)
+
+ show_groups =
+ if @without_group.any?
+ groups.reject {|g| @without_group.include?(g) }
+ elsif @only_group.any?
+ groups.select {|g| @only_group.include?(g) }
+ else
+ groups
+ end.map(&:to_sym)
+
+ definition.specs_for(show_groups)
+ end
+ end
+end
diff --git a/lib/bundler/cli/lock.rb b/lib/bundler/cli/lock.rb
index 223db9419f..7d613a6644 100644
--- a/lib/bundler/cli/lock.rb
+++ b/lib/bundler/cli/lock.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Lock
@@ -22,9 +21,13 @@ module Bundler
Bundler::Fetcher.disable_endpoint = options["full-index"]
update = options[:update]
+ conservative = options[:conservative]
+
if update.is_a?(Array) # unlocking specific gems
Bundler::CLI::Common.ensure_all_gems_in_lockfile!(update)
- update = { :gems => update, :lock_shared_dependencies => options[:conservative] }
+ update = { :gems => update, :conservative => conservative }
+ elsif update
+ update = { :conservative => conservative } if conservative
end
definition = Bundler.definition(update)
diff --git a/lib/bundler/cli/open.rb b/lib/bundler/cli/open.rb
index 9a21f6811c..ea504344f3 100644
--- a/lib/bundler/cli/open.rb
+++ b/lib/bundler/cli/open.rb
@@ -1,6 +1,4 @@
# frozen_string_literal: true
-require "bundler/cli/common"
-require "shellwords"
module Bundler
class CLI::Open
@@ -14,12 +12,17 @@ module Bundler
editor = [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? }
return Bundler.ui.info("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR") unless editor
return unless spec = Bundler::CLI::Common.select_spec(name, :regex_match)
- path = spec.full_gem_path
- Dir.chdir(path) do
- command = Shellwords.split(editor) + [path]
- Bundler.with_clean_env do
- system(*command)
- end || Bundler.ui.info("Could not run '#{command.join(" ")}'")
+ if spec.default_gem?
+ Bundler.ui.info "Unable to open #{name} because it's a default gem, so the directory it would normally be installed to does not exist."
+ else
+ path = spec.full_gem_path
+ Dir.chdir(path) do
+ require "shellwords"
+ command = Shellwords.split(editor) + [path]
+ Bundler.with_original_env do
+ system(*command)
+ end || Bundler.ui.info("Could not run '#{command.join(" ")}'")
+ end
end
end
end
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
index 863d0dd388..d5183b060b 100644
--- a/lib/bundler/cli/outdated.rb
+++ b/lib/bundler/cli/outdated.rb
@@ -1,19 +1,30 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Outdated
- attr_reader :options, :gems
+ attr_reader :options, :gems, :options_include_groups, :filter_options_patch, :sources, :strict
+ attr_accessor :outdated_gems
def initialize(options, gems)
@options = options
@gems = gems
+ @sources = Array(options[:source])
+
+ @filter_options_patch = options.keys & %w[filter-major filter-minor filter-patch]
+
+ @outdated_gems = []
+
+ @options_include_groups = [:group, :groups].any? do |v|
+ options.keys.include?(v.to_s)
+ end
+
+ # the patch level options imply strict is also true. It wouldn't make
+ # sense otherwise.
+ @strict = options["filter-strict"] || Bundler::CLI::Common.patch_level_options(options).any?
end
def run
- check_for_deployment_mode
-
- sources = Array(options[:source])
+ check_for_deployment_mode!
gems.each do |gem_name|
Bundler::CLI::Common.select_spec(gem_name)
@@ -21,11 +32,9 @@ module Bundler
Bundler.definition.validate_runtime!
current_specs = Bundler.ui.silence { Bundler.definition.resolve }
- current_dependencies = {}
- Bundler.ui.silence do
- Bundler.load.dependencies.each do |dep|
- current_dependencies[dep.name] = dep
- end
+
+ current_dependencies = Bundler.ui.silence do
+ Bundler.load.dependencies.map {|dep| [dep.name, dep] }.to_h
end
definition = if gems.empty? && sources.empty?
@@ -40,14 +49,6 @@ module Bundler
options
)
- # the patch level options imply strict is also true. It wouldn't make
- # sense otherwise.
- strict = options[:strict] ||
- Bundler::CLI::Common.patch_level_options(options).any?
-
- filter_options_patch = options.keys &
- %w(filter-major filter-minor filter-patch)
-
definition_resolution = proc do
options[:local] ? definition.resolve_with_cache! : definition.resolve_remotely!
end
@@ -59,138 +60,129 @@ module Bundler
end
Bundler.ui.info ""
- outdated_gems_by_groups = {}
- outdated_gems_list = []
# Loop through the current specs
gemfile_specs, dependency_specs = current_specs.partition do |spec|
current_dependencies.key? spec.name
end
- (gemfile_specs + dependency_specs).sort_by(&:name).each do |current_spec|
- next if !gems.empty? && !gems.include?(current_spec.name)
+ specs = if options["only-explicit"]
+ gemfile_specs
+ else
+ gemfile_specs + dependency_specs
+ end
+
+ specs.sort_by(&:name).uniq(&:name).each do |current_spec|
+ next unless gems.empty? || gems.include?(current_spec.name)
- dependency = current_dependencies[current_spec.name]
- active_spec = retrieve_active_spec(strict, definition, current_spec)
+ active_spec = retrieve_active_spec(definition, current_spec)
+ next unless active_spec
- next if active_spec.nil?
- if filter_options_patch.any?
- update_present = update_present_via_semver_portions(current_spec, active_spec, options)
- next unless update_present
- end
+ next unless filter_options_patch.empty? || update_present_via_semver_portions(current_spec, active_spec, options)
gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
next unless gem_outdated || (current_spec.git_version != active_spec.git_version)
- groups = nil
+
+ dependency = current_dependencies[current_spec.name]
+ groups = ""
if dependency && !options[:parseable]
groups = dependency.groups.join(", ")
end
- outdated_gems_list << { :active_spec => active_spec,
- :current_spec => current_spec,
- :dependency => dependency,
- :groups => groups }
-
- outdated_gems_by_groups[groups] ||= []
- outdated_gems_by_groups[groups] << { :active_spec => active_spec,
- :current_spec => current_spec,
- :dependency => dependency,
- :groups => groups }
+ outdated_gems << {
+ :active_spec => active_spec,
+ :current_spec => current_spec,
+ :dependency => dependency,
+ :groups => groups,
+ }
end
- if outdated_gems_list.empty?
- display_nothing_outdated_message(filter_options_patch)
- else
+ if outdated_gems.empty?
unless options[:parseable]
- if options[:pre]
- Bundler.ui.info "Outdated gems included in the bundle (including " \
- "pre-releases):"
- else
- Bundler.ui.info "Outdated gems included in the bundle:"
- end
- end
-
- options_include_groups = [:group, :groups].select do |v|
- options.keys.include?(v.to_s)
+ Bundler.ui.info(nothing_outdated_message)
end
+ else
+ if options_include_groups
+ relevant_outdated_gems = outdated_gems.group_by {|g| g[:groups] }.sort.flat_map do |groups, gems|
+ contains_group = groups.split(", ").include?(options[:group])
+ next unless options[:groups] || contains_group
- if options_include_groups.any?
- ordered_groups = outdated_gems_by_groups.keys.compact.sort
- [nil, ordered_groups].flatten.each do |groups|
- gems = outdated_gems_by_groups[groups]
- contains_group = if groups
- groups.split(",").include?(options[:group])
- else
- options[:group] == "group"
- end
-
- next if (!options[:groups] && !contains_group) || gems.nil?
-
- unless options[:parseable]
- if groups
- Bundler.ui.info "===== Group #{groups} ====="
- else
- Bundler.ui.info "===== Without group ====="
- end
- end
+ gems
+ end.compact
- gems.each do |gem|
- print_gem(
- gem[:current_spec],
- gem[:active_spec],
- gem[:dependency],
- groups,
- options_include_groups.any?
- )
+ if options[:parseable]
+ relevant_outdated_gems.each do |gems|
+ print_gems(gems)
end
+ else
+ print_gems_table(relevant_outdated_gems)
end
+ elsif options[:parseable]
+ print_gems(outdated_gems)
else
- outdated_gems_list.each do |gem|
- print_gem(
- gem[:current_spec],
- gem[:active_spec],
- gem[:dependency],
- gem[:groups],
- options_include_groups.any?
- )
- end
+ print_gems_table(outdated_gems)
end
exit 1
end
end
- private
+ private
+
+ def groups_text(group_text, groups)
+ "#{group_text}#{groups.split(",").size > 1 ? "s" : ""} \"#{groups}\""
+ end
+
+ def nothing_outdated_message
+ if filter_options_patch.any?
+ display = filter_options_patch.map do |o|
+ o.sub("filter-", "")
+ end.join(" or ")
- def retrieve_active_spec(strict, definition, current_spec)
- if strict
- active_spec = definition.find_resolved_spec(current_spec)
+ "No #{display} updates to display.\n"
else
- active_specs = definition.find_indexed_specs(current_spec)
- if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
- active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
- end
- active_spec = active_specs.last
+ "Bundle up to date!\n"
end
+ end
+
+ def retrieve_active_spec(definition, current_spec)
+ active_spec = definition.resolve.find_by_name_and_platform(current_spec.name, current_spec.platform)
+ return unless active_spec
- active_spec
+ return active_spec if strict
+
+ active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
+ if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
+ active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
+ end
+ active_specs.last
end
- def display_nothing_outdated_message(filter_options_patch)
- unless options[:parseable]
- if filter_options_patch.any?
- display = filter_options_patch.map do |o|
- o.sub("filter-", "")
- end.join(" or ")
+ def print_gems(gems_list)
+ gems_list.each do |gem|
+ print_gem(
+ gem[:current_spec],
+ gem[:active_spec],
+ gem[:dependency],
+ gem[:groups],
+ )
+ end
+ end
- Bundler.ui.info "No #{display} updates to display.\n"
- else
- Bundler.ui.info "Bundle up to date!\n"
- end
+ def print_gems_table(gems_list)
+ data = gems_list.map do |gem|
+ gem_column_for(
+ gem[:current_spec],
+ gem[:active_spec],
+ gem[:dependency],
+ gem[:groups],
+ )
end
+
+ print_indented([table_header] + data)
end
- def print_gem(current_spec, active_spec, dependency, groups, options_include_groups)
+ def print_gem(current_spec, active_spec, dependency, groups)
spec_version = "#{active_spec.version}#{active_spec.git_version}"
spec_version += " (from #{active_spec.loaded_from})" if Bundler.ui.debug? && active_spec.loaded_from
current_version = "#{current_spec.version}#{current_spec.git_version}"
@@ -204,23 +196,37 @@ module Bundler
output_message = if options[:parseable]
spec_outdated_info.to_s
- elsif options_include_groups || !groups
+ elsif options_include_groups || groups.empty?
" * #{spec_outdated_info}"
else
- " * #{spec_outdated_info} in groups \"#{groups}\""
+ " * #{spec_outdated_info} in #{groups_text("group", groups)}"
end
Bundler.ui.info output_message.rstrip
end
- def check_for_deployment_mode
- if Bundler.settings[:frozen]
- raise ProductionError, "You are trying to check outdated gems in " \
- "deployment mode. Run `bundle outdated` elsewhere.\n" \
- "\nIf this is a development machine, remove the " \
- "#{Bundler.default_gemfile} freeze" \
- "\nby running `bundle install --no-deployment`."
+ def gem_column_for(current_spec, active_spec, dependency, groups)
+ current_version = "#{current_spec.version}#{current_spec.git_version}"
+ spec_version = "#{active_spec.version}#{active_spec.git_version}"
+ dependency = dependency.requirement if dependency
+
+ ret_val = [active_spec.name, current_version, spec_version, dependency.to_s, groups.to_s]
+ ret_val << active_spec.loaded_from.to_s if Bundler.ui.debug?
+ ret_val
+ end
+
+ def check_for_deployment_mode!
+ return unless Bundler.frozen_bundle?
+ suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any?
+ "bundle config unset frozen"
+ elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
+ "bundle config unset deployment"
end
+ raise ProductionError, "You are trying to check outdated gems in " \
+ "deployment mode. Run `bundle outdated` elsewhere.\n" \
+ "\nIf this is a development machine, remove the " \
+ "#{Bundler.default_gemfile} freeze" \
+ "\nby running `#{suggested_command}`."
end
def update_present_via_semver_portions(current_spec, active_spec, options)
@@ -249,7 +255,36 @@ module Bundler
def get_version_semver_portion_value(spec, version_portion_index)
version_section = spec.version.segments[version_portion_index, 1]
- version_section.nil? ? 0 : (version_section.first || 0)
+ version_section.to_a[0].to_i
+ end
+
+ def print_indented(matrix)
+ header = matrix[0]
+ data = matrix[1..-1]
+
+ column_sizes = Array.new(header.size) do |index|
+ matrix.max_by {|row| row[index].length }[index].length
+ end
+
+ Bundler.ui.info justify(header, column_sizes)
+
+ data.sort_by! {|row| row[0] }
+
+ data.each do |row|
+ Bundler.ui.info justify(row, column_sizes)
+ end
+ end
+
+ def table_header
+ header = ["Gem", "Current", "Latest", "Requested", "Groups"]
+ header << "Path" if Bundler.ui.debug?
+ header
+ end
+
+ def justify(row, sizes)
+ row.each_with_index.map do |element, index|
+ element.ljust(sizes[index])
+ end.join(" ").strip + "\n"
end
end
end
diff --git a/lib/bundler/cli/package.rb b/lib/bundler/cli/package.rb
deleted file mode 100644
index cf65e8a68c..0000000000
--- a/lib/bundler/cli/package.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-module Bundler
- class CLI::Package
- attr_reader :options
-
- def initialize(options)
- @options = options
- end
-
- def run
- Bundler.ui.level = "error" if options[:quiet]
- Bundler.settings[:path] = File.expand_path(options[:path]) if options[:path]
- Bundler.settings[:cache_all_platforms] = options["all-platforms"] if options.key?("all-platforms")
- Bundler.settings[:cache_path] = options["cache-path"] if options.key?("cache-path")
-
- setup_cache_all
- install
-
- # TODO: move cache contents here now that all bundles are locked
- custom_path = Pathname.new(options[:path]) if options[:path]
- Bundler.load.cache(custom_path)
- end
-
- private
-
- def install
- require "bundler/cli/install"
- options = self.options.dup
- if Bundler.settings[:cache_all_platforms]
- options["local"] = false
- options["update"] = true
- end
- Bundler::CLI::Install.new(options).run
- end
-
- def setup_cache_all
- Bundler.settings[:cache_all] = options[:all] if options.key?("all")
-
- if Bundler.definition.has_local_dependencies? && !Bundler.settings[:cache_all]
- Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
- "to package them as well, please pass the --all flag. This will be the default " \
- "on Bundler 2.0."
- end
- end
- end
-end
diff --git a/lib/bundler/cli/platform.rb b/lib/bundler/cli/platform.rb
index 9fdab0a53c..e97cad49a4 100644
--- a/lib/bundler/cli/platform.rb
+++ b/lib/bundler/cli/platform.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Platform
attr_reader :options
diff --git a/lib/bundler/cli/plugin.rb b/lib/bundler/cli/plugin.rb
index 277822dafc..fe3f4412fa 100644
--- a/lib/bundler/cli/plugin.rb
+++ b/lib/bundler/cli/plugin.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
-require "bundler/vendored_thor"
+
+require_relative "../vendored_thor"
module Bundler
class CLI::Plugin < Thor
desc "install PLUGINS", "Install the plugin from the source"
long_desc <<-D
- Install plugins either from the rubygems source provided (with --source option) or from a git source provided with (--git option). If no sources are provided, it uses Gem.sources
+ Install plugins either from the rubygems source provided (with --source option) or from a git source provided with --git (for remote repos) or --local_git (for local repos). If no sources are provided, it uses Gem.sources
D
method_option "source", :type => :string, :default => nil, :banner =>
"URL of the RubyGems source to fetch the plugin from"
@@ -12,6 +13,8 @@ module Bundler
"The version of the plugin to fetch"
method_option "git", :type => :string, :default => nil, :banner =>
"URL of the git repo to fetch from"
+ method_option "local_git", :type => :string, :default => nil, :banner =>
+ "Path of the local git repo to fetch from"
method_option "branch", :type => :string, :default => nil, :banner =>
"The git branch to checkout"
method_option "ref", :type => :string, :default => nil, :banner =>
@@ -19,5 +22,20 @@ module Bundler
def install(*plugins)
Bundler::Plugin.install(plugins, options)
end
+
+ desc "uninstall PLUGINS", "Uninstall the plugins"
+ long_desc <<-D
+ Uninstall given list of plugins. To uninstall all the plugins, use -all option.
+ D
+ method_option "all", :type => :boolean, :default => nil, :banner =>
+ "Uninstall all the installed plugins. If no plugin is installed, then it does nothing."
+ def uninstall(*plugins)
+ Bundler::Plugin.uninstall(plugins, options)
+ end
+
+ desc "list", "List the installed plugins and available commands"
+ def list
+ Bundler::Plugin.list
+ end
end
end
diff --git a/lib/bundler/cli/pristine.rb b/lib/bundler/cli/pristine.rb
index 10d03b4b41..d6654f8053 100644
--- a/lib/bundler/cli/pristine.rb
+++ b/lib/bundler/cli/pristine.rb
@@ -1,15 +1,20 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Pristine
+ def initialize(gems)
+ @gems = gems
+ end
+
def run
+ CLI::Common.ensure_all_gems_in_lockfile!(@gems)
definition = Bundler.definition
definition.validate_runtime!
installer = Bundler::Installer.new(Bundler.root, definition)
Bundler.load.specs.each do |spec|
next if spec.name == "bundler" # Source::Rubygems doesn't install bundler
+ next if !@gems.empty? && !@gems.include?(spec.name)
gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})"
gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY
@@ -21,13 +26,24 @@ module Bundler
Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.")
next
end
+
+ FileUtils.rm_rf spec.full_gem_path
when Source::Git
+ if source.local?
+ Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.")
+ next
+ end
+
source.remote!
+ if extension_cache_path = source.extension_cache_path(spec)
+ FileUtils.rm_rf extension_cache_path
+ end
+ FileUtils.rm_rf spec.extension_dir
+ FileUtils.rm_rf spec.full_gem_path
else
Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
next
end
- FileUtils.rm_rf spec.full_gem_path
Bundler::GemInstaller.new(spec, installer, false, 0, true).install_from_spec
end
diff --git a/lib/bundler/cli/remove.rb b/lib/bundler/cli/remove.rb
new file mode 100644
index 0000000000..44a4d891dd
--- /dev/null
+++ b/lib/bundler/cli/remove.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Bundler
+ class CLI::Remove
+ def initialize(gems, options)
+ @gems = gems
+ @options = options
+ end
+
+ def run
+ raise InvalidOption, "Please specify gems to remove." if @gems.empty?
+
+ Injector.remove(@gems, {})
+ Installer.install(Bundler.root, Bundler.definition)
+ end
+ end
+end
diff --git a/lib/bundler/cli/show.rb b/lib/bundler/cli/show.rb
index 47d4470aec..5eaaba1ef7 100644
--- a/lib/bundler/cli/show.rb
+++ b/lib/bundler/cli/show.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Show
@@ -25,7 +24,7 @@ module Bundler
return unless spec
path = spec.full_gem_path
unless File.directory?(path)
- Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at:"
+ return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}"
end
end
return Bundler.ui.info(path)
@@ -54,7 +53,7 @@ module Bundler
end
end
- private
+ private
def fetch_latest_specs
definition = Bundler.definition(true)
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
index df7524f004..95a8886ea5 100644
--- a/lib/bundler/cli/update.rb
+++ b/lib/bundler/cli/update.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "bundler/cli/common"
module Bundler
class CLI::Update
@@ -10,16 +9,32 @@ module Bundler
end
def run
- Bundler.ui.level = "error" if options[:quiet]
+ Bundler.ui.level = "warn" if options[:quiet]
Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins?
sources = Array(options[:source])
groups = Array(options[:group]).map(&:to_sym)
- if gems.empty? && sources.empty? && groups.empty? && !options[:ruby] && !options[:bundler]
- # We're doing a full update
- Bundler.definition(true)
+ full_update = gems.empty? && sources.empty? && groups.empty? && !options[:ruby] && !options[:bundler]
+
+ if full_update && !options[:all]
+ if Bundler.feature_flag.update_requires_all_flag?
+ raise InvalidOption, "To update everything, pass the `--all` flag."
+ end
+ SharedHelpers.major_deprecation 3, "Pass --all to `bundle update` to update everything"
+ elsif !full_update && options[:all]
+ raise InvalidOption, "Cannot specify --all along with specific options."
+ end
+
+ conservative = options[:conservative]
+
+ if full_update
+ if conservative
+ Bundler.definition(:conservative => conservative)
+ else
+ Bundler.definition(true)
+ end
else
unless Bundler.default_lockfile.exist?
raise GemfileLockNotFound, "This Bundle hasn't been installed yet. " \
@@ -28,12 +43,13 @@ module Bundler
Bundler::CLI::Common.ensure_all_gems_in_lockfile!(gems)
if groups.any?
- specs = Bundler.definition.specs_for groups
- gems.concat(specs.map(&:name))
+ deps = Bundler.definition.dependencies.select {|d| (d.groups & groups).any? }
+ gems.concat(deps.map(&:name))
end
Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby],
- :lock_shared_dependencies => options[:conservative])
+ :conservative => conservative,
+ :bundler => options[:bundler])
end
Bundler::CLI::Common.configure_gem_version_promoter(Bundler.definition, options)
@@ -44,20 +60,59 @@ module Bundler
opts["update"] = true
opts["local"] = options[:local]
- Bundler.settings[:jobs] = opts["jobs"] if opts["jobs"]
+ Bundler.settings.set_command_option_if_given :jobs, opts["jobs"]
Bundler.definition.validate_runtime!
+
+ if locked_gems = Bundler.definition.locked_gems
+ previous_locked_info = locked_gems.specs.reduce({}) do |h, s|
+ h[s.name] = { :spec => s, :version => s.version, :source => s.source.identifier }
+ h
+ end
+ end
+
installer = Installer.install Bundler.root, Bundler.definition, opts
Bundler.load.cache if Bundler.app_cache.exist?
- if Bundler.settings[:clean] && Bundler.settings[:path]
- require "bundler/cli/clean"
+ if CLI::Common.clean_after_install?
+ require_relative "clean"
Bundler::CLI::Clean.new(options).run
end
+ if locked_gems
+ gems.each do |name|
+ locked_info = previous_locked_info[name]
+ next unless locked_info
+
+ locked_spec = locked_info[:spec]
+ new_spec = Bundler.definition.specs[name].first
+ unless new_spec
+ unless locked_spec.match_platform(Bundler.local_platform)
+ Bundler.ui.warn "Bundler attempted to update #{name} but it was not considered because it is for a different platform from the current one"
+ end
+
+ next
+ end
+
+ locked_source = locked_info[:source]
+ new_source = new_spec.source.identifier
+ next if locked_source != new_source
+
+ new_version = new_spec.version
+ locked_version = locked_info[:version]
+ if new_version < locked_version
+ Bundler.ui.warn "Note: #{name} version regressed from #{locked_version} to #{new_version}"
+ elsif new_version == locked_version
+ Bundler.ui.warn "Bundler attempted to update #{name} but its version stayed the same"
+ end
+ end
+ end
+
Bundler.ui.confirm "Bundle updated!"
- Bundler::CLI::Common.output_without_groups_message
+ Bundler::CLI::Common.output_without_groups_message(:update)
Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
+
+ Bundler::CLI::Common.output_fund_metadata_summary
end
end
end
diff --git a/lib/bundler/cli/viz.rb b/lib/bundler/cli/viz.rb
index 767fe8f3de..644f9b25cf 100644
--- a/lib/bundler/cli/viz.rb
+++ b/lib/bundler/cli/viz.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class CLI::Viz
attr_reader :options, :gem_name
diff --git a/lib/bundler/compact_index_client.rb b/lib/bundler/compact_index_client.rb
index 3ed05ca484..d5dbeb3b10 100644
--- a/lib/bundler/compact_index_client.rb
+++ b/lib/bundler/compact_index_client.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
+
require "pathname"
require "set"
module Bundler
class CompactIndexClient
- DEBUG_MUTEX = Mutex.new
+ DEBUG_MUTEX = Thread::Mutex.new
def self.debug
return unless ENV["DEBUG_COMPACT_INDEX"]
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
@@ -12,16 +13,11 @@ module Bundler
class Error < StandardError; end
- require "bundler/compact_index_client/cache"
- require "bundler/compact_index_client/updater"
+ require_relative "compact_index_client/cache"
+ require_relative "compact_index_client/updater"
attr_reader :directory
- # @return [Lambda] A lambda that takes an array of inputs and a block, and
- # maps the inputs with the block in parallel.
- #
- attr_accessor :in_parallel
-
def initialize(directory, fetcher)
@directory = Pathname.new(directory)
@updater = Updater.new(fetcher)
@@ -29,8 +25,29 @@ module Bundler
@endpoints = Set.new
@info_checksums_by_name = {}
@parsed_checksums = false
- @mutex = Mutex.new
- @in_parallel = lambda do |inputs, &blk|
+ @mutex = Thread::Mutex.new
+ end
+
+ def execution_mode=(block)
+ Bundler::CompactIndexClient.debug { "execution_mode=" }
+ @endpoints = Set.new
+
+ @execution_mode = block
+ end
+
+ # @return [Lambda] A lambda that takes an array of inputs and a block, and
+ # maps the inputs with the block in parallel.
+ #
+ def execution_mode
+ @execution_mode || sequentially
+ end
+
+ def sequential_execution_mode!
+ self.execution_mode = sequentially
+ end
+
+ def sequentially
+ @sequentially ||= lambda do |inputs, &blk|
inputs.map(&blk)
end
end
@@ -50,7 +67,7 @@ module Bundler
def dependencies(names)
Bundler::CompactIndexClient.debug { "dependencies(#{names})" }
- in_parallel.call(names) do |name|
+ execution_mode.call(names) do |name|
update_info(name)
@cache.dependencies(name).map {|d| d.unshift(name) }
end.flatten(1)
@@ -70,7 +87,7 @@ module Bundler
@parsed_checksums = true
end
- private
+ private
def update(local_path, remote_path)
Bundler::CompactIndexClient.debug { "update(#{local_path}, #{remote_path})" }
diff --git a/lib/bundler/compact_index_client/cache.rb b/lib/bundler/compact_index_client/cache.rb
index e44f05dc7e..c2cd069ec1 100644
--- a/lib/bundler/compact_index_client/cache.rb
+++ b/lib/bundler/compact_index_client/cache.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require "digest/md5"
+
+require_relative "gem_parser"
module Bundler
class CompactIndexClient
@@ -68,7 +69,7 @@ module Bundler
def info_path(name)
name = name.to_s
if name =~ /[^a-z0-9_-]/
- name += "-#{Digest::MD5.hexdigest(name).downcase}"
+ name += "-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}"
info_roots.last.join(name)
else
info_roots.first.join(name)
@@ -84,7 +85,7 @@ module Bundler
gem_line ? parse_gem(gem_line) : nil
end
- private
+ private
def lines(path)
return [] unless path.file?
@@ -93,19 +94,9 @@ module Bundler
header ? lines[header + 1..-1] : lines
end
- def parse_gem(string)
- version_and_platform, rest = string.split(" ", 2)
- version, platform = version_and_platform.split("-", 2)
- dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
- dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
- requirements = requirements ? requirements.map {|r| parse_dependency(r) } : []
- [version, platform, dependencies, requirements]
- end
-
- def parse_dependency(string)
- dependency = string.split(":")
- dependency[-1] = dependency[-1].split("&") if dependency.size > 1
- dependency
+ def parse_gem(line)
+ @dependency_parser ||= GemParser.new
+ @dependency_parser.parse(line)
end
def info_roots
diff --git a/lib/bundler/compact_index_client/gem_parser.rb b/lib/bundler/compact_index_client/gem_parser.rb
new file mode 100644
index 0000000000..e7bf4c6001
--- /dev/null
+++ b/lib/bundler/compact_index_client/gem_parser.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Bundler
+ class CompactIndexClient
+ if defined?(Gem::Resolver::APISet::GemParser)
+ GemParser = Gem::Resolver::APISet::GemParser
+ else
+ class GemParser
+ def parse(line)
+ version_and_platform, rest = line.split(" ", 2)
+ version, platform = version_and_platform.split("-", 2)
+ dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
+ dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
+ requirements = requirements ? requirements.map {|d| parse_dependency(d) } : []
+ [version, platform, dependencies, requirements]
+ end
+
+ private
+
+ def parse_dependency(string)
+ dependency = string.split(":")
+ dependency[-1] = dependency[-1].split("&") if dependency.size > 1
+ dependency
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bundler/compact_index_client/updater.rb b/lib/bundler/compact_index_client/updater.rb
index dc26095040..d9b9cec0d4 100644
--- a/lib/bundler/compact_index_client/updater.rb
+++ b/lib/bundler/compact_index_client/updater.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
-require "fileutils"
-require "stringio"
-require "tmpdir"
-require "zlib"
+
+require_relative "../vendored_fileutils"
module Bundler
class CompactIndexClient
@@ -22,17 +20,20 @@ module Bundler
def initialize(fetcher)
@fetcher = fetcher
+ require_relative "../vendored_tmpdir"
end
def update(local_path, remote_path, retrying = nil)
headers = {}
- Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir|
+ Bundler::Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir|
local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename)
# first try to fetch any new bytes on the existing file
if retrying.nil? && local_path.file?
- FileUtils.cp local_path, local_temp_path
+ SharedHelpers.filesystem_access(local_temp_path) do
+ FileUtils.cp local_path, local_temp_path
+ end
headers["If-None-Match"] = etag_for(local_temp_path)
headers["Range"] =
if local_temp_path.size.nonzero?
@@ -42,29 +43,27 @@ module Bundler
else
"bytes=#{local_temp_path.size}-"
end
- else
- # Fastly ignores Range when Accept-Encoding: gzip is set
- headers["Accept-Encoding"] = "gzip"
end
response = @fetcher.call(remote_path, headers)
return nil if response.is_a?(Net::HTTPNotModified)
content = response.body
- if response["Content-Encoding"] == "gzip"
- content = Zlib::GzipReader.new(StringIO.new(content)).read
- end
- SharedHelpers.filesystem_access(local_temp_path) do
+ etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
+ correct_response = SharedHelpers.filesystem_access(local_temp_path) do
if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
+
+ etag_for(local_temp_path) == etag
else
- local_temp_path.open("w") {|f| f << content }
+ local_temp_path.open("wb") {|f| f << content }
+
+ etag.length.zero? || etag_for(local_temp_path) == etag
end
end
- response_etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
- if etag_for(local_temp_path) == response_etag
+ if correct_response
SharedHelpers.filesystem_access(local_path) do
FileUtils.mv(local_temp_path, local_path)
end
@@ -72,11 +71,13 @@ module Bundler
end
if retrying
- raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_temp_path))
+ raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path))
end
update(local_path, remote_path, :retrying)
end
+ rescue Zlib::GzipFile::Error
+ raise Bundler::HTTPError
end
def etag_for(path)
@@ -85,20 +86,16 @@ module Bundler
end
def slice_body(body, range)
- if body.respond_to?(:byteslice)
- body.byteslice(range)
- else # pre-1.9.3
- body.unpack("@#{range.first}a#{range.end + 1}").first
- end
+ body.byteslice(range)
end
def checksum_for_file(path)
return nil unless path.file?
- # This must use IO.read instead of Digest.file().hexdigest
+ # This must use File.read instead of Digest.file().hexdigest
# because we need to preserve \n line endings on windows when calculating
# the checksum
SharedHelpers.filesystem_access(path, :read) do
- Digest::MD5.hexdigest(IO.read(path))
+ SharedHelpers.digest(:MD5).hexdigest(File.read(path))
end
end
end
diff --git a/lib/bundler/constants.rb b/lib/bundler/constants.rb
index 5b1c0a8cb1..2e4ebb37ee 100644
--- a/lib/bundler/constants.rb
+++ b/lib/bundler/constants.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/
FREEBSD = RbConfig::CONFIG["host_os"] =~ /bsd/
diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb
index cca40100ad..f84d68e262 100644
--- a/lib/bundler/current_ruby.rb
+++ b/lib/bundler/current_ruby.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
# Returns current version of Ruby
#
@@ -8,7 +9,7 @@ module Bundler
end
class CurrentRuby
- KNOWN_MINOR_VERSIONS = %w(
+ KNOWN_MINOR_VERSIONS = %w[
1.8
1.9
2.0
@@ -17,11 +18,14 @@ module Bundler
2.3
2.4
2.5
- ).freeze
+ 2.6
+ 2.7
+ 3.0
+ ].freeze
KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze
- KNOWN_PLATFORMS = %w(
+ KNOWN_PLATFORMS = %w[
jruby
maglev
mingw
@@ -30,43 +34,50 @@ module Bundler
mswin64
rbx
ruby
+ truffleruby
x64_mingw
- ).freeze
+ ].freeze
def ruby?
- !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev")
+ return true if Bundler::GemHelpers.generic_local_platform == Gem::Platform::RUBY
+
+ !mswin? && (RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev" || RUBY_ENGINE == "truffleruby")
end
def mri?
- !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby")
+ !mswin? && RUBY_ENGINE == "ruby"
end
def rbx?
- ruby? && defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
+ ruby? && RUBY_ENGINE == "rbx"
end
def jruby?
- defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
+ RUBY_ENGINE == "jruby"
end
def maglev?
- defined?(RUBY_ENGINE) && RUBY_ENGINE == "maglev"
+ RUBY_ENGINE == "maglev"
+ end
+
+ def truffleruby?
+ RUBY_ENGINE == "truffleruby"
end
def mswin?
- Bundler::WINDOWS
+ Gem.win_platform?
end
def mswin64?
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
end
def mingw?
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
end
def x64_mingw?
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
end
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 3e5b1bc447..584f379256 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
-require "bundler/lockfile_parser"
-require "digest/sha1"
-require "set"
+
+require_relative "lockfile_parser"
module Bundler
class Definition
@@ -9,12 +8,13 @@ module Bundler
attr_reader(
:dependencies,
- :gem_version_promoter,
:locked_deps,
:locked_gems,
:platforms,
:requires,
- :ruby_version
+ :ruby_version,
+ :lockfile,
+ :gemfiles
)
# Given a gemfile and lockfile creates a Bundler definition
@@ -51,8 +51,14 @@ module Bundler
# to be updated or true if all gems should be updated
# @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
# @param optional_groups [Array(String)] A list of optional groups
- def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [])
- @unlocking = unlock == true || !unlock.empty?
+ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = [])
+ if [true, false].include?(unlock)
+ @unlocking_bundler = false
+ @unlocking = unlock
+ else
+ @unlocking_bundler = unlock.delete(:bundler)
+ @unlocking = unlock.any? {|_k, v| !Array(v).empty? }
+ end
@dependencies = dependencies
@sources = sources
@@ -61,11 +67,13 @@ module Bundler
@remote = false
@specs = nil
@ruby_version = ruby_version
+ @gemfiles = gemfiles
@lockfile = lockfile
@lockfile_contents = String.new
@locked_bundler_version = nil
@locked_ruby_version = nil
+ @new_platform = nil
if lockfile && File.exist?(lockfile)
@lockfile_contents = Bundler.read_file(lockfile)
@@ -95,56 +103,76 @@ module Bundler
@locked_platforms = []
end
- @unlock[:gems] ||= []
+ locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
+ @multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?
+
+ if @multisource_allowed
+ unless sources.aggregate_global_source?
+ msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
+
+ Bundler::SharedHelpers.major_deprecation 2, msg
+ end
+
+ @sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
+ end
+
@unlock[:sources] ||= []
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
@ruby_version.diff(locked_ruby_version_object)
end
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
- add_current_platform unless Bundler.settings[:frozen]
+ add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle?
converge_path_sources_to_gemspec_sources
@path_changes = converge_paths
@source_changes = converge_sources
- unless @unlock[:lock_shared_dependencies]
- eager_unlock = expand_dependencies(@unlock[:gems])
- @unlock[:gems] = @locked_specs.for(eager_unlock).map(&:name)
+ if @unlock[:conservative]
+ @unlock[:gems] ||= @dependencies.map(&:name)
+ else
+ eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
+ @unlock[:gems] = @locked_specs.for(eager_unlock, false, false).map(&:name)
end
- @gem_version_promoter = create_gem_version_promoter
-
@dependency_changes = converge_dependencies
@local_changes = converge_locals
+ @locked_specs_incomplete_for_platform = !@locked_specs.for(requested_dependencies & expand_dependencies(locked_dependencies), true, true)
+
@requires = compute_requires
end
- def create_gem_version_promoter
- locked_specs =
- if unlocking? && @locked_specs.empty? && !@lockfile_contents.empty?
- # Definition uses an empty set of locked_specs to indicate all gems
- # are unlocked, but GemVersionPromoter needs the locked_specs
- # for conservative comparison.
- Bundler::SpecSet.new(@locked_gems.specs)
- else
- @locked_specs
- end
- GemVersionPromoter.new(locked_specs, @unlock[:gems])
+ def gem_version_promoter
+ @gem_version_promoter ||= begin
+ locked_specs =
+ if unlocking? && @locked_specs.empty? && !@lockfile_contents.empty?
+ # Definition uses an empty set of locked_specs to indicate all gems
+ # are unlocked, but GemVersionPromoter needs the locked_specs
+ # for conservative comparison.
+ Bundler::SpecSet.new(@locked_gems.specs)
+ else
+ @locked_specs
+ end
+ GemVersionPromoter.new(locked_specs, @unlock[:gems])
+ end
+ end
+
+ def resolve_only_locally!
+ @remote = false
+ sources.local_only!
+ resolve
end
def resolve_with_cache!
- raise "Specs already loaded" if @specs
sources.cached!
- specs
+ resolve
end
def resolve_remotely!
- raise "Specs already loaded" if @specs
@remote = true
sources.remote!
- specs
+ resolve
end
# For given dependency list returns a SpecSet with Gemspec of all the required
@@ -154,26 +182,7 @@ module Bundler
#
# @return [Bundler::SpecSet]
def specs
- @specs ||= begin
- begin
- specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)
- rescue GemNotFound => e # Handle yanked gem
- gem_name, gem_version = extract_gem_info(e)
- locked_gem = @locked_specs[gem_name].last
- raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
- raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
- "be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
- "that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
- "to a different version of #{locked_gem} that hasn't been removed in order to install."
- end
- unless specs["bundler"].any?
- local = Bundler.settings[:frozen] ? rubygems_index : index
- bundler = local.search(Gem::Dependency.new("bundler", VERSION)).last
- specs["bundler"] = bundler if bundler
- end
-
- specs
- end
+ @specs ||= materialize(requested_dependencies)
end
def new_specs
@@ -184,38 +193,54 @@ module Bundler
@locked_specs - specs
end
- def new_platform?
- @new_platform
- end
-
def missing_specs
- missing = []
- resolve.materialize(requested_dependencies, missing)
- missing
+ resolve.materialize(requested_dependencies).missing_specs
end
- def missing_dependencies
- missing = []
- resolve.materialize(current_dependencies, missing)
- missing
+ def missing_specs?
+ missing = missing_specs
+ return false if missing.empty?
+ Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
+ true
+ rescue BundlerError => e
+ @resolve = nil
+ @specs = nil
+ @gem_version_promoter = nil
+
+ Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
+ true
end
def requested_specs
- @requested_specs ||= begin
- groups = requested_groups
- groups.map!(&:to_sym)
- specs_for(groups)
- end
+ specs_for(requested_groups)
+ end
+
+ def requested_dependencies
+ dependencies_for(requested_groups)
end
def current_dependencies
- dependencies.select(&:should_include?)
+ dependencies.select do |d|
+ d.should_include? && !d.gem_platforms(@platforms).empty?
+ end
+ end
+
+ def locked_dependencies
+ @locked_deps.values
end
def specs_for(groups)
- deps = dependencies.select {|d| (d.groups & groups).any? }
- deps.delete_if {|d| !d.should_include? }
- specs.for(expand_dependencies(deps))
+ return specs if groups.empty?
+ deps = dependencies_for(groups)
+ materialize(deps)
+ end
+
+ def dependencies_for(groups)
+ groups.map!(&:to_sym)
+ deps = current_dependencies.reject do |d|
+ (d.groups & groups).empty?
+ end
+ expand_dependencies(deps)
end
# Resolve all the dependencies specified in Gemfile. It ensures that
@@ -226,52 +251,23 @@ module Bundler
def resolve
@resolve ||= begin
last_resolve = converge_locked_specs
- if Bundler.settings[:frozen] || (!unlocking? && nothing_changed?)
+ if Bundler.frozen_bundle?
+ Bundler.ui.debug "Frozen, using resolution from the lockfile"
+ last_resolve
+ elsif !unlocking? && nothing_changed?
Bundler.ui.debug("Found no changes, using resolution from the lockfile")
last_resolve
else
# Run a resolve against the locally available gems
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
- last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
- end
- end
- end
-
- def index
- @index ||= Index.build do |idx|
- dependency_names = @dependencies.map(&:name)
-
- sources.all_sources.each do |source|
- source.dependency_names = dependency_names.dup
- idx.add_source source.specs
- dependency_names -= pinned_spec_names(source.specs)
- dependency_names.concat(source.unmet_deps).uniq!
- end
- idx << Gem::Specification.new("ruby\0", RubyVersion.system.to_gem_version_with_patchlevel)
- idx << Gem::Specification.new("rubygems\0", Gem::VERSION)
- end
- end
-
- # used when frozen is enabled so we can find the bundler
- # spec, even if (say) a git gem is not checked out.
- def rubygems_index
- @rubygems_index ||= Index.build do |idx|
- sources.rubygems_sources.each do |rubygems|
- idx.add_source rubygems.specs
+ expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
+ Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
end
end
end
- def has_rubygems_remotes?
- sources.rubygems_sources.any? {|s| s.remotes.any? }
- end
-
- def has_local_dependencies?
- !sources.path_sources.empty? || !sources.git_sources.empty?
- end
-
def spec_git_paths
- sources.git_sources.map {|s| s.path.to_s }
+ sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact
end
def groups
@@ -295,10 +291,11 @@ module Bundler
end
end
- preserve_unknown_sections ||= !updating_major && (Bundler.settings[:frozen] || !unlocking?)
- return if lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
+ preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
+
+ return if file && File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
- if Bundler.settings[:frozen]
+ if Bundler.frozen_bundle?
Bundler.ui.error "Cannot write a changed lockfile while frozen."
return
end
@@ -338,51 +335,8 @@ module Bundler
end
def to_lock
- out = String.new
-
- sources.lock_sources.each do |source|
- # Add the source header
- out << source.to_lock
- # Find all specs for this source
- resolve.
- select {|s| source.can_lock?(s) }.
- # This needs to be sorted by full name so that
- # gems with the same name, but different platform
- # are ordered consistently
- sort_by(&:full_name).
- each do |spec|
- next if spec.name == "bundler"
- out << spec.to_lock
- end
- out << "\n"
- end
-
- out << "PLATFORMS\n"
-
- platforms.map(&:to_s).sort.each do |p|
- out << " #{p}\n"
- end
-
- out << "\n"
- out << "DEPENDENCIES\n"
-
- handled = []
- dependencies.sort_by(&:to_s).each do |dep|
- next if handled.include?(dep.name)
- out << dep.to_lock
- handled << dep.name
- end
-
- if locked_ruby_version
- out << "\nRUBY VERSION\n"
- out << " #{locked_ruby_version}\n"
- end
-
- # Record the version of Bundler that was used to create the lockfile
- out << "\nBUNDLED WITH\n"
- out << " #{locked_bundler_version}\n"
-
- out
+ require_relative "lockfile_generator"
+ LockfileGenerator.generate(self)
end
def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
@@ -392,8 +346,11 @@ module Bundler
"updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control."
unless explicit_flag
-
- suggested_command = Bundler.settings.locations("frozen")[:global] == "1" ? "bundle config --delete frozen" : "bundle install --no-deployment"
+ suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any?
+ "bundle config unset frozen"
+ elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
+ "bundle config unset deployment"
+ end
msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
"freeze \nby running `#{suggested_command}`."
end
@@ -407,44 +364,26 @@ module Bundler
added.concat new_platforms.map {|p| "* platform: #{p}" }
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
- gemfile_sources = sources.lock_sources
-
- new_sources = gemfile_sources - @locked_sources
- deleted_sources = @locked_sources - gemfile_sources
-
- new_deps = @dependencies - @locked_deps.values
- deleted_deps = @locked_deps.values - @dependencies
-
- # Check if it is possible that the source is only changed thing
- if (new_deps.empty? && deleted_deps.empty?) && (!new_sources.empty? && !deleted_sources.empty?)
- new_sources.reject! {|source| source.is_a_path? && source.path.exist? }
- deleted_sources.reject! {|source| source.is_a_path? && source.path.exist? }
- end
-
- if @locked_sources != gemfile_sources
- if new_sources.any?
- added.concat new_sources.map {|source| "* source: #{source}" }
- end
-
- if deleted_sources.any?
- deleted.concat deleted_sources.map {|source| "* source: #{source}" }
- end
- end
+ new_deps = @dependencies - locked_dependencies
+ deleted_deps = locked_dependencies - @dependencies
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
- if deleted_deps.any?
- deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
- end
+ deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
both_sources = Hash.new {|h, k| h[k] = [] }
@dependencies.each {|d| both_sources[d.name][0] = d }
- @locked_deps.each {|name, d| both_sources[name][1] = d.source }
+ locked_dependencies.each {|d| both_sources[d.name][1] = d }
+
+ both_sources.each do |name, (dep, lock_dep)|
+ next if dep.nil? || lock_dep.nil?
- both_sources.each do |name, (dep, lock_source)|
- next unless (dep.nil? && !lock_source.nil?) || (!dep.nil? && !lock_source.nil? && !lock_source.can_lock?(dep))
- gemfile_source_name = (dep && dep.source) || "no specified source"
- lockfile_source_name = lock_source || "no specified source"
- changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
+ gemfile_source = dep.source || sources.default_source
+ lock_source = lock_dep.source || sources.default_source
+ next if lock_source.include?(gemfile_source)
+
+ gemfile_source_name = dep.source ? gemfile_source.identifier : "no specified source"
+ lockfile_source_name = lock_dep.source ? lock_source.identifier : "no specified source"
+ changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
end
reason = change_reason
@@ -488,15 +427,11 @@ module Bundler
end
def validate_platforms!
- return if @platforms.any? do |bundle_platform|
- Bundler.rubygems.platforms.any? do |local_platform|
- MatchPlatform.platforms_match?(bundle_platform, local_platform)
- end
- end
+ return if current_platform_locked?
raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
- "but your local platforms are #{Bundler.rubygems.platforms.map(&:to_s)}, and " \
- "there's no compatible match between those two lists."
+ "but your local platform is #{Bundler.local_platform}. " \
+ "Add the current platform to the lockfile with `bundle lock --add-platform #{Bundler.local_platform}` and try again."
end
def add_platform(platform)
@@ -509,32 +444,69 @@ module Bundler
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
end
- def add_current_platform
- current_platform = Bundler.local_platform
- add_platform(current_platform) if Bundler.settings[:specific_platform]
- add_platform(generic(current_platform))
- end
-
- def find_resolved_spec(current_spec)
- specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
- end
-
- def find_indexed_specs(current_spec)
- index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
+ def most_specific_locked_platform
+ @platforms.min_by do |bundle_platform|
+ platform_specificity_match(bundle_platform, local_platform)
+ end
end
attr_reader :sources
private :sources
def nothing_changed?
- !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
+ !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
end
def unlocking?
@unlocking
end
- private
+ private
+
+ def materialize(dependencies)
+ specs = resolve.materialize(dependencies)
+ missing_specs = specs.missing_specs
+
+ if missing_specs.any?
+ missing_specs.each do |s|
+ locked_gem = @locked_specs[s.name].last
+ next if locked_gem.nil? || locked_gem.version != s.version || !@remote
+ raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
+ "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
+ "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
+ "removed in order to install."
+ end
+
+ raise GemNotFound, "Could not find #{missing_specs.map(&:full_name).join(", ")} in any of the sources"
+ end
+
+ unless specs["bundler"].any?
+ bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
+ specs["bundler"] = bundler
+ end
+
+ specs
+ end
+
+ def precompute_source_requirements_for_indirect_dependencies?
+ @remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
+ end
+
+ def current_ruby_platform_locked?
+ return false unless generic_local_platform == Gem::Platform::RUBY
+
+ current_platform_locked?
+ end
+
+ def current_platform_locked?
+ @platforms.any? do |bundle_platform|
+ MatchPlatform.platforms_match?(bundle_platform, Bundler.local_platform)
+ end
+ end
+
+ def add_current_platform
+ add_platform(local_platform)
+ end
def change_reason
if unlocking?
@@ -554,14 +526,12 @@ module Bundler
[@new_platform, "you added a new platform to your gemfile"],
[@path_changes, "the gemspecs for path gems changed"],
[@local_changes, "the gemspecs for git local gems changed"],
+ [@locked_specs_incomplete_for_platform, "the lockfile does not have all gems needed for the current platform"],
].select(&:first).map(&:last).join(", ")
end
def pretty_dep(dep, source = false)
- msg = String.new(dep.name)
- msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
- msg << " from the `#{dep.source}` source" if source && dep.source
- msg
+ SharedHelpers.pretty_dependency(dep, source)
end
# Check if the specs of the given source changed
@@ -574,9 +544,9 @@ module Bundler
def dependencies_for_source_changed?(source, locked_source = source)
deps_for_source = @dependencies.select {|s| s.source == source }
- locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
+ locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
- Set.new(deps_for_source) != Set.new(locked_deps_for_source)
+ deps_for_source.uniq.sort != locked_deps_for_source.sort
end
def specs_for_source_changed?(source)
@@ -585,6 +555,9 @@ module Bundler
# order here matters, since Index#== is checking source.specs.include?(locked_index)
locked_index != source.specs
+ rescue PathError, GitError => e
+ Bundler.ui.debug "Assuming that #{source} has not changed since fetching its specs errored (#{e})"
+ false
end
# Get all locals and override their matching sources.
@@ -633,25 +606,10 @@ module Bundler
end
def converge_sources
- changes = false
-
- # Get the Rubygems sources from the Gemfile.lock
- locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
- # Get the Rubygems remotes from the Gemfile
- actual_remotes = sources.rubygems_remotes
-
- # If there is a Rubygems source in both
- if !locked_gem_sources.empty? && !actual_remotes.empty?
- locked_gem_sources.each do |locked_gem|
- # Merge the remotes from the Gemfile into the Gemfile.lock
- changes |= locked_gem.replace_remotes(actual_remotes)
- end
- end
-
# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
# if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
# source in the Gemfile.lock, use the one from the Gemfile.
- changes |= sources.replace_sources!(@locked_sources)
+ changes = sources.replace_sources!(@locked_sources)
sources.all_sources.each do |source|
# If the source is unlockable and the current command allows an unlock of
@@ -669,28 +627,14 @@ module Bundler
end
def converge_dependencies
- frozen = Bundler.settings[:frozen]
- (@dependencies + @locked_deps.values).each do |dep|
- locked_source = @locked_deps[dep.name]
- # This is to make sure that if bundler is installing in deployment mode and
- # after locked_source and sources don't match, we still use locked_source.
- if frozen && !locked_source.nil? &&
- locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
- dep.source = locked_source.source
- elsif dep.source
+ changes = false
+
+ @dependencies.each do |dep|
+ if dep.source
dep.source = sources.get(dep.source)
end
- if dep.source.is_a?(Source::Gemspec)
- dep.platforms.concat(@platforms.map {|p| Dependency::REVERSE_PLATFORM_MAP[p] }.flatten(1)).uniq!
- end
- end
- changes = false
- # We want to know if all match, but don't want to check all entries
- # This means we need to return false if any dependency doesn't match
- # the lock or doesn't exist in the lock.
- @dependencies.each do |dependency|
- unless locked_dep = @locked_deps[dependency.name]
+ unless locked_dep = @locked_deps[dep.name]
changes = true
next
end
@@ -701,11 +645,11 @@ module Bundler
# directive, the lockfile dependencies and resolved dependencies end up
# with a mismatch on #type. Work around that by setting the type on the
# dep from the lockfile.
- locked_dep.instance_variable_set(:@type, dependency.type)
+ locked_dep.instance_variable_set(:@type, dep.type)
# We already know the name matches from the hash lookup
# so we only need to check the requirement now
- changes ||= dependency.requirement != locked_dep.requirement
+ changes ||= dep.requirement != locked_dep.requirement
end
changes
@@ -715,125 +659,98 @@ module Bundler
# commonly happen if the Gemfile has changed since the lockfile was last
# generated
def converge_locked_specs
- deps = []
-
- # Build a list of dependencies that are the same in the Gemfile
- # and Gemfile.lock. If the Gemfile modified a dependency, but
- # the gem in the Gemfile.lock still satisfies it, this is fine
- # too.
- @dependencies.each do |dep|
- locked_dep = @locked_deps[dep.name]
+ resolve = converge_specs(@locked_specs)
- # If the locked_dep doesn't match the dependency we're looking for then we ignore the locked_dep
- locked_dep = nil unless locked_dep == dep
+ diff = nil
- if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
- deps << dep
- elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source)
- @locked_specs.each do |s|
- @unlock[:gems] << s.name if s.source == dep.source
- end
+ # Now, we unlock any sources that do not have anymore gems pinned to it
+ sources.all_sources.each do |source|
+ next unless source.respond_to?(:unlock!)
- dep.source.unlock! if dep.source.respond_to?(:unlock!)
- dep.source.specs.each {|s| @unlock[:gems] << s.name }
+ unless resolve.any? {|s| s.source == source }
+ diff ||= @locked_specs.to_a - resolve.to_a
+ source.unlock! if diff.any? {|s| s.source == source }
end
end
+ resolve
+ end
+
+ def converge_specs(specs)
+ deps = []
converged = []
- @locked_specs.each do |s|
+ specs.each do |s|
# Replace the locked dependency's source with the equivalent source from the Gemfile
dep = @dependencies.find {|d| s.satisfies?(d) }
- s.source = (dep && dep.source) || sources.get(s.source)
- # Don't add a spec to the list if its source is expired. For example,
- # if you change a Git gem to Rubygems.
- next if s.source.nil?
- next if @unlock[:sources].include?(s.source.name)
+ if dep && (!dep.source || s.source.include?(dep.source))
+ deps << dep
+ end
- # XXX This is a backwards-compatibility fix to preserve the ability to
- # unlock a single gem by passing its name via `--source`. See issue #3759
- # TODO: delete in Bundler 2
- next if @unlock[:sources].include?(s.name)
+ s.source = (dep && dep.source) || sources.get(s.source) || sources.default_source unless Bundler.frozen_bundle?
+
+ next if @unlock[:sources].include?(s.source.name)
# If the spec is from a path source and it doesn't exist anymore
# then we unlock it.
# Path sources have special logic
if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
- other = s.source.specs[s].first
+ new_specs = begin
+ s.source.specs
+ rescue PathError, GitError
+ # if we won't need the source (according to the lockfile),
+ # don't error if the path/git source isn't available
+ next if specs.
+ for(requested_dependencies, false, true).
+ none? {|locked_spec| locked_spec.source == s.source }
+
+ raise
+ end
+
+ new_spec = new_specs[s].first
# If the spec is no longer in the path source, unlock it. This
# commonly happens if the version changed in the gemspec
- next unless other
+ next unless new_spec
- deps2 = other.dependencies.select {|d| d.type != :development }
- runtime_dependencies = s.dependencies.select {|d| d.type != :development }
- # If the dependencies of the path source have changed, unlock it
- next unless runtime_dependencies.sort == deps2.sort
+ s.dependencies.replace(new_spec.dependencies)
end
- converged << s
- end
-
- resolve = SpecSet.new(converged)
- resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems], false, false, false)
- diff = nil
-
- # Now, we unlock any sources that do not have anymore gems pinned to it
- sources.all_sources.each do |source|
- next unless source.respond_to?(:unlock!)
-
- unless resolve.any? {|s| s.source == source }
- diff ||= @locked_specs.to_a - resolve.to_a
- source.unlock! if diff.any? {|s| s.source == source }
+ if dep.nil? && requested_dependencies.find {|d| s.name == d.name }
+ @unlock[:gems] << s.name
+ else
+ converged << s
end
end
- resolve
- end
-
- def in_locked_deps?(dep, locked_dep)
- # Because the lockfile can't link a dep to a specific remote, we need to
- # treat sources as equivalent anytime the locked dep has all the remotes
- # that the Gemfile dep does.
- locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
- end
-
- def satisfies_locked_spec?(dep)
- @locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
+ resolve = SpecSet.new(converged)
+ SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
end
- # This list of dependencies is only used in #resolve, so it's OK to add
- # the metadata dependencies here
- def expanded_dependencies
- @expanded_dependencies ||= begin
- ruby_versions = concat_ruby_version_requirements(@ruby_version)
- if ruby_versions.empty? || !@ruby_version.exact?
- concat_ruby_version_requirements(RubyVersion.system)
- concat_ruby_version_requirements(locked_ruby_version_object) unless @unlock[:ruby]
- end
-
- metadata_dependencies = [
- Dependency.new("ruby\0", ruby_versions),
- Dependency.new("rubygems\0", Gem::VERSION),
+ def metadata_dependencies
+ @metadata_dependencies ||= begin
+ ruby_versions = ruby_version_requirements(@ruby_version)
+ [
+ Dependency.new("Ruby\0", ruby_versions),
+ Dependency.new("RubyGems\0", Gem::VERSION),
]
- expand_dependencies(dependencies + metadata_dependencies, @remote)
end
end
- def concat_ruby_version_requirements(ruby_version, ruby_versions = [])
- return ruby_versions unless ruby_version
+ def ruby_version_requirements(ruby_version)
+ return [] unless ruby_version
if ruby_version.patchlevel
- ruby_versions << ruby_version.to_gem_version_with_patchlevel
+ [ruby_version.to_gem_version_with_patchlevel]
else
- ruby_versions.concat(ruby_version.versions.map do |version|
+ ruby_version.versions.map do |version|
requirement = Gem::Requirement.new(version)
if requirement.exact?
"~> #{version}.0"
else
requirement
end
- end)
+ end
end
end
@@ -841,61 +758,38 @@ module Bundler
deps = []
dependencies.each do |dep|
dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
- next if !remote && !dep.current_platform?
- platforms = dep.gem_platforms(@platforms)
- if platforms.empty?
- mapped_platforms = dep.platforms.map {|p| Dependency::PLATFORM_MAP[p] }
- Bundler.ui.warn \
- "The dependency #{dep} will be unused by any of the platforms Bundler is installing for. " \
- "Bundler is installing for #{@platforms.join ", "} but the dependency " \
- "is only for #{mapped_platforms.join ", "}. " \
- "To add those platforms to the bundle, " \
- "run `bundle lock --add-platform #{mapped_platforms.join " "}`."
- end
- platforms.each do |p|
- deps << DepProxy.new(dep, p) if remote || p == generic_local_platform
- end
+ next unless remote || dep.current_platform?
+ target_platforms = dep.gem_platforms(remote ? @platforms : [generic_local_platform])
+ deps += expand_dependency_with_platforms(dep, target_platforms)
end
deps
end
- def requested_dependencies
- groups = requested_groups
- groups.map!(&:to_sym)
- dependencies.reject {|d| !d.should_include? || (d.groups & groups).empty? }
+ def expand_dependency_with_platforms(dep, platforms)
+ platforms.map do |p|
+ DepProxy.get_proxy(dep, p)
+ end
end
def source_requirements
- # Load all specs from remote sources
- index
-
# Record the specs available in each gem's source, so that those
# specs will be available later when the resolver knows where to
# look for that gemspec (or its dependencies)
- source_requirements = {}
- dependencies.each do |dep|
- next unless dep.source
- source_requirements[dep.name] = dep.source.specs
+ source_requirements = if precompute_source_requirements_for_indirect_dependencies?
+ { :default => sources.default_source }.merge(source_map.all_requirements)
+ else
+ { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
end
- source_requirements
- end
-
- def pinned_spec_names(specs)
- names = []
- specs.each do |s|
- # TODO: when two sources without blocks is an error, we can change
- # this check to !s.source.is_a?(Source::LocalRubygems). For now,
- # we need to ask every Rubygems for every gem name.
- if s.source.is_a?(Source::Git) || s.source.is_a?(Source::Path)
- names << s.name
- end
+ metadata_dependencies.each do |dep|
+ source_requirements[dep.name] = sources.metadata_source
end
- names.uniq!
- names
+ source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
+ source_requirements["bundler"] = sources.metadata_source # needs to come last to override
+ source_requirements
end
def requested_groups
- groups - Bundler.settings.without - @optional_groups + Bundler.settings.with
+ groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
end
def lockfiles_equal?(current, proposed, preserve_unknown_sections)
@@ -911,12 +805,6 @@ module Bundler
current == proposed
end
- def extract_gem_info(error)
- # This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
- # to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
- error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
- end
-
def compute_requires
dependencies.reduce({}) do |requires, dep|
next requires unless dep.should_include?
@@ -929,12 +817,16 @@ module Bundler
end
def additional_base_requirements_for_resolve
- return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions?
- @locked_gems.specs.reduce({}) do |requirements, locked_spec|
- dep = Gem::Dependency.new(locked_spec.name, ">= #{locked_spec.version}")
- requirements[locked_spec.name] = DepProxy.new(dep, locked_spec.platform)
- requirements
- end.values
+ return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
+ converge_specs(@locked_gems.specs).map do |locked_spec|
+ name = locked_spec.name
+ dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
+ DepProxy.get_proxy(dep, locked_spec.platform)
+ end
+ end
+
+ def source_map
+ @source_map ||= SourceMap.new(sources, dependencies)
end
end
end
diff --git a/lib/bundler/dep_proxy.rb b/lib/bundler/dep_proxy.rb
index 998975bbaf..a32dc37b49 100644
--- a/lib/bundler/dep_proxy.rb
+++ b/lib/bundler/dep_proxy.rb
@@ -1,20 +1,21 @@
# frozen_string_literal: true
+
module Bundler
class DepProxy
attr_reader :__platform, :dep
+ @proxies = {}
+
+ def self.get_proxy(dep, platform)
+ @proxies[[dep, platform]] ||= new(dep, platform).freeze
+ end
+
def initialize(dep, platform)
@dep = dep
@__platform = platform
end
- def hash
- @hash ||= dep.hash
- end
-
- def ==(other)
- dep == other.dep && __platform == other.__platform
- end
+ private_class_method :new
alias_method :eql?, :==
@@ -37,7 +38,15 @@ module Bundler
s
end
- private
+ def dup
+ raise NoMethodError.new("DepProxy cannot be duplicated")
+ end
+
+ def clone
+ raise NoMethodError.new("DepProxy cannot be cloned")
+ end
+
+ private
def method_missing(*args, &blk)
@dep.send(*args, &blk)
diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb
index d2bac66cdb..af07e8bc36 100644
--- a/lib/bundler/dependency.rb
+++ b/lib/bundler/dependency.rb
@@ -1,13 +1,13 @@
# frozen_string_literal: true
+
require "rubygems/dependency"
-require "bundler/shared_helpers"
-require "bundler/rubygems_ext"
+require_relative "shared_helpers"
+require_relative "rubygems_ext"
module Bundler
class Dependency < Gem::Dependency
attr_reader :autorequire
- attr_reader :groups
- attr_reader :platforms
+ attr_reader :groups, :platforms, :gemfile, :git, :branch
PLATFORM_MAP = {
:ruby => Gem::Platform::RUBY,
@@ -19,6 +19,7 @@ module Bundler
:ruby_23 => Gem::Platform::RUBY,
:ruby_24 => Gem::Platform::RUBY,
:ruby_25 => Gem::Platform::RUBY,
+ :ruby_26 => Gem::Platform::RUBY,
:mri => Gem::Platform::RUBY,
:mri_18 => Gem::Platform::RUBY,
:mri_19 => Gem::Platform::RUBY,
@@ -28,7 +29,9 @@ module Bundler
:mri_23 => Gem::Platform::RUBY,
:mri_24 => Gem::Platform::RUBY,
:mri_25 => Gem::Platform::RUBY,
+ :mri_26 => Gem::Platform::RUBY,
:rbx => Gem::Platform::RUBY,
+ :truffleruby => Gem::Platform::RUBY,
:jruby => Gem::Platform::JAVA,
:jruby_18 => Gem::Platform::JAVA,
:jruby_19 => Gem::Platform::JAVA,
@@ -41,6 +44,7 @@ module Bundler
:mswin_23 => Gem::Platform::MSWIN,
:mswin_24 => Gem::Platform::MSWIN,
:mswin_25 => Gem::Platform::MSWIN,
+ :mswin_26 => Gem::Platform::MSWIN,
:mswin64 => Gem::Platform::MSWIN64,
:mswin64_19 => Gem::Platform::MSWIN64,
:mswin64_20 => Gem::Platform::MSWIN64,
@@ -49,6 +53,7 @@ module Bundler
:mswin64_23 => Gem::Platform::MSWIN64,
:mswin64_24 => Gem::Platform::MSWIN64,
:mswin64_25 => Gem::Platform::MSWIN64,
+ :mswin64_26 => Gem::Platform::MSWIN64,
:mingw => Gem::Platform::MINGW,
:mingw_18 => Gem::Platform::MINGW,
:mingw_19 => Gem::Platform::MINGW,
@@ -58,6 +63,7 @@ module Bundler
:mingw_23 => Gem::Platform::MINGW,
:mingw_24 => Gem::Platform::MINGW,
:mingw_25 => Gem::Platform::MINGW,
+ :mingw_26 => Gem::Platform::MINGW,
:x64_mingw => Gem::Platform::X64_MINGW,
:x64_mingw_20 => Gem::Platform::X64_MINGW,
:x64_mingw_21 => Gem::Platform::X64_MINGW,
@@ -65,17 +71,9 @@ module Bundler
:x64_mingw_23 => Gem::Platform::X64_MINGW,
:x64_mingw_24 => Gem::Platform::X64_MINGW,
:x64_mingw_25 => Gem::Platform::X64_MINGW,
+ :x64_mingw_26 => Gem::Platform::X64_MINGW,
}.freeze
- REVERSE_PLATFORM_MAP = {}.tap do |reverse_platform_map|
- PLATFORM_MAP.each do |key, value|
- reverse_platform_map[value] ||= []
- reverse_platform_map[value] << key
- end
-
- reverse_platform_map.each {|_, platforms| platforms.freeze }
- end.freeze
-
def initialize(name, version, options = {}, &blk)
type = options["type"] || :runtime
super(name, version, type)
@@ -83,23 +81,30 @@ module Bundler
@autorequire = nil
@groups = Array(options["group"] || :default).map(&:to_sym)
@source = options["source"]
+ @git = options["git"]
+ @branch = options["branch"]
@platforms = Array(options["platforms"])
@env = options["env"]
@should_include = options.fetch("should_include", true)
+ @gemfile = options["gemfile"]
@autorequire = Array(options["require"] || []) if options.key?("require")
end
+ # Returns the platforms this dependency is valid for, in the same order as
+ # passed in the `valid_platforms` parameter
def gem_platforms(valid_platforms)
return valid_platforms if @platforms.empty?
- platforms = []
- @platforms.each do |p|
- platform = PLATFORM_MAP[p]
- next unless valid_platforms.include?(platform)
- platforms |= [platform]
- end
- platforms
+ valid_generic_platforms = valid_platforms.map {|p| [p, GemHelpers.generic(p)] }.to_h
+ @gem_platforms ||= expanded_platforms.compact.uniq
+
+ filtered_generic_platforms = valid_generic_platforms.values & @gem_platforms
+ valid_generic_platforms.select {|_, v| filtered_generic_platforms.include?(v) }.keys
+ end
+
+ def expanded_platforms
+ @platforms.map {|pl| PLATFORM_MAP[pl] }
end
def should_include?
diff --git a/lib/bundler/deployment.rb b/lib/bundler/deployment.rb
index 94f2fac620..b432ae6ae1 100644
--- a/lib/bundler/deployment.rb
+++ b/lib/bundler/deployment.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require "bundler/shared_helpers"
-Bundler::SharedHelpers.major_deprecation "Bundler no longer integrates with " \
+require_relative "shared_helpers"
+Bundler::SharedHelpers.major_deprecation 2, "Bundler no longer integrates with " \
"Capistrano, but Capistrano provides its own integration with " \
"Bundler via the capistrano-bundler gem. Use it instead."
diff --git a/lib/bundler/deprecate.rb b/lib/bundler/deprecate.rb
index b978c0df6c..f59533630e 100644
--- a/lib/bundler/deprecate.rb
+++ b/lib/bundler/deprecate.rb
@@ -1,11 +1,23 @@
# frozen_string_literal: true
+
+begin
+ require "rubygems/deprecate"
+rescue LoadError
+ # it's fine if it doesn't exist on the current RubyGems...
+ nil
+end
+
module Bundler
- if defined? ::Deprecate
+ # If Bundler::Deprecate is an autoload constant, we need to define it
+ if defined?(Bundler::Deprecate) && !autoload?(:Deprecate)
+ # nothing to do!
+ elsif defined? ::Deprecate
Deprecate = ::Deprecate
elsif defined? Gem::Deprecate
Deprecate = Gem::Deprecate
else
- class Deprecate; end
+ class Deprecate
+ end
end
unless Deprecate.respond_to?(:skip_during)
@@ -20,7 +32,7 @@ module Bundler
unless Deprecate.respond_to?(:skip)
def Deprecate.skip
- @skip
+ @skip ||= false
end
end
diff --git a/lib/bundler/digest.rb b/lib/bundler/digest.rb
new file mode 100644
index 0000000000..759f609416
--- /dev/null
+++ b/lib/bundler/digest.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+# This code was extracted from https://github.com/Solistra/ruby-digest which is under public domain
+module Bundler
+ module Digest
+ # The initial constant values for the 32-bit constant words A, B, C, D, and
+ # E, respectively.
+ SHA1_WORDS = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0].freeze
+
+ # The 8-bit field used for bitwise `AND` masking. Defaults to `0xFFFFFFFF`.
+ SHA1_MASK = 0xFFFFFFFF
+
+ class << self
+ def sha1(string)
+ unless string.is_a?(String)
+ raise TypeError, "can't convert #{string.class.inspect} into String"
+ end
+
+ buffer = string.b
+
+ words = SHA1_WORDS.dup
+ generate_split_buffer(buffer) do |chunk|
+ w = []
+ chunk.each_slice(4) do |a, b, c, d|
+ w << (((a << 8 | b) << 8 | c) << 8 | d)
+ end
+ a, b, c, d, e = *words
+ (16..79).each do |i|
+ w[i] = SHA1_MASK & rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1)
+ end
+ 0.upto(79) do |i|
+ case i
+ when 0..19
+ f = ((b & c) | (~b & d))
+ k = 0x5A827999
+ when 20..39
+ f = (b ^ c ^ d)
+ k = 0x6ED9EBA1
+ when 40..59
+ f = ((b & c) | (b & d) | (c & d))
+ k = 0x8F1BBCDC
+ when 60..79
+ f = (b ^ c ^ d)
+ k = 0xCA62C1D6
+ end
+ t = SHA1_MASK & (SHA1_MASK & rotate(a, 5) + f + e + k + w[i])
+ a, b, c, d, e = t, a, SHA1_MASK & rotate(b, 30), c, d # rubocop:disable Style/ParallelAssignment
+ end
+ mutated = [a, b, c, d, e]
+ words.map!.with_index {|word, index| SHA1_MASK & (word + mutated[index]) }
+ end
+
+ words.pack("N*").unpack("H*").first
+ end
+
+ private
+
+ def generate_split_buffer(string, &block)
+ size = string.bytesize * 8
+ buffer = string.bytes << 128
+ buffer << 0 while buffer.size % 64 != 56
+ buffer.concat([size].pack("Q>").bytes)
+ buffer.each_slice(64, &block)
+ end
+
+ def rotate(value, spaces)
+ value << spaces | value >> (32 - spaces)
+ end
+ end
+ end
+end
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index e4c257d267..1108fc3b78 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
-require "bundler/dependency"
-require "bundler/ruby_dsl"
+
+require_relative "dependency"
+require_relative "ruby_dsl"
module Bundler
class Dsl
@@ -14,6 +15,11 @@ module Bundler
VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze
+ VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
+ platform platforms type source install_if gemfile].freeze
+
+ GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze
+
attr_reader :gemspecs
attr_accessor :dependencies
@@ -30,16 +36,18 @@ module Bundler
@ruby_version = nil
@gemspecs = []
@gemfile = nil
+ @gemfiles = []
add_git_sources
end
def eval_gemfile(gemfile, contents = nil)
- expanded_gemfile_path = Pathname.new(gemfile).expand_path
+ expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile && @gemfile.parent)
original_gemfile = @gemfile
@gemfile = expanded_gemfile_path
- contents ||= Bundler.read_file(gemfile.to_s)
- instance_eval(contents.dup.untaint, gemfile.to_s, 1)
- rescue Exception => e
+ @gemfiles << expanded_gemfile_path
+ contents ||= Bundler.read_file(@gemfile.to_s)
+ instance_eval(contents.dup.tap{|x| x.untaint if RUBY_VERSION < "2.7" }, gemfile.to_s, 1)
+ rescue Exception => e # rubocop:disable Lint/RescueException
message = "There was an error " \
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
"`#{File.basename gemfile.to_s}`: #{e.message}"
@@ -57,7 +65,7 @@ module Bundler
development_group = opts[:development_group] || :development
expanded_path = gemfile_root.join(path)
- gemspecs = Dir[File.join(expanded_path, "{,*}.gemspec")].map {|g| Bundler.load_gemspec(g) }.compact
+ gemspecs = Gem::Util.glob_files_in_dir("{,*}.gemspec", expanded_path).map {|g| Bundler.load_gemspec(g) }.compact
gemspecs.reject! {|s| s.name != name } if name
Index.sort_specs(gemspecs)
specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] }
@@ -69,8 +77,7 @@ module Bundler
@gemspecs << spec
- gem_platforms = Bundler::Dependency::REVERSE_PLATFORM_MAP[Bundler::GemHelpers.generic_local_platform]
- gem spec.name, :name => spec.name, :path => path, :glob => glob, :platforms => gem_platforms
+ gem spec.name, :name => spec.name, :path => path, :glob => glob
group(development_group) do
spec.development_dependencies.each do |dep|
@@ -87,6 +94,7 @@ module Bundler
def gem(name, *args)
options = args.last.is_a?(Hash) ? args.pop.dup : {}
+ options["gemfile"] = @gemfile
version = args || [">= 0"]
normalize_options(name, version, options)
@@ -95,25 +103,35 @@ module Bundler
# if there's already a dependency with this name we try to prefer one
if current = @dependencies.find {|d| d.name == dep.name }
- if current.requirement != dep.requirement
- if current.type == :development
- @dependencies.delete current
- else
+ deleted_dep = @dependencies.delete(current) if current.type == :development
+
+ unless deleted_dep
+ if current.requirement != dep.requirement
return if dep.type == :development
- raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
- "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})"
- end
- else
- Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
- "You should probably keep only one of them.\n" \
- "While it's not a problem now, it could cause errors if you change the version of one of them later."
- end
+ update_prompt = ""
- if current.source != dep.source
- if current.type == :development
- @dependencies.delete current
+ if File.basename(@gemfile) == Injector::INJECTED_GEMS
+ if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
+ update_prompt = ". Gem already added"
+ else
+ update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
+
+ update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
+ end
+ end
+
+ raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
+ "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
+ "#{update_prompt}"
else
+ Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
+ "You should probably keep only one of them.\n" \
+ "Remove any duplicate entries and specify the gem only once.\n" \
+ "While it's not a problem now, it could cause errors if you change the version of one of them later."
+ end
+
+ if current.source != dep.source
return if dep.type == :development
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
@@ -128,10 +146,12 @@ module Bundler
def source(source, *args, &blk)
options = args.last.is_a?(Hash) ? args.pop.dup : {}
options = normalize_hash(options)
+ source = normalize_source(source)
+
if options.key?("type")
options["type"] = options["type"].to_s
unless Plugin.source?(options["type"])
- raise "No sources available for #{options["type"]}"
+ raise InvalidOption, "No plugin sources available for #{options["type"]}"
end
unless block_given?
@@ -141,12 +161,9 @@ module Bundler
source_opts = options.merge("uri" => source)
with_source(@sources.add_plugin_source(options["type"], source_opts), &blk)
elsif block_given?
- source = normalize_source(source)
with_source(@sources.add_rubygems_source("remotes" => source), &blk)
else
- source = normalize_source(source)
- check_primary_source_safety(@sources)
- @sources.add_rubygems_remote(source)
+ @sources.add_global_rubygems_remote(source)
end
end
@@ -169,6 +186,9 @@ module Bundler
"root_path" => gemfile_root,
"gemspec" => gemspecs.find {|g| g.name == options["name"] }
)
+
+ source_options["global"] = true unless block_given?
+
source = @sources.add_path_source(source_options)
with_source(source, &blk)
end
@@ -197,16 +217,17 @@ module Bundler
end
def to_definition(lockfile, unlock)
- Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups)
+ check_primary_source_safety
+ Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
end
def group(*args, &blk)
- opts = Hash === args.last ? args.pop.dup : {}
- normalize_group_options(opts, args)
+ options = args.last.is_a?(Hash) ? args.pop.dup : {}
+ normalize_group_options(options, args)
@groups.concat args
- if opts["optional"]
+ if options["optional"]
optional_groups = args - @optional_groups
@optional_groups.concat optional_groups
end
@@ -216,9 +237,9 @@ module Bundler
args.each { @groups.pop }
end
- def install_if(*args, &blk)
+ def install_if(*args)
@install_conditionals.concat args
- blk.call
+ yield
ensure
args.each { @install_conditionals.pop }
end
@@ -247,43 +268,45 @@ module Bundler
raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
end
- private
+ def check_primary_source_safety
+ check_path_source_safety
+ check_rubygems_source_safety
+ end
+
+ private
def add_git_sources
git_source(:github) do |repo_name|
- # It would be better to use https instead of the git protocol, but this
- # can break deployment of existing locked bundles when switching between
- # different versions of Bundler. The change will be made in 2.0, which
- # does not guarantee compatibility with the 1.x series.
- #
- # See https://github.com/bundler/bundler/pull/2569 for discussion
- #
- # This can be overridden by adding this code to your Gemfiles:
- #
- # git_source(:github) do |repo_name|
- # repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
- # "https://github.com/#{repo_name}.git"
- # end
- repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
- # TODO: 2.0 upgrade this setting to the default
- if Bundler.settings["github.https"]
- "https://github.com/#{repo_name}.git"
+ warn_deprecated_git_source(:github, <<-'RUBY'.strip, 'Change any "reponame" :github sources to "username/reponame".')
+"https://github.com/#{repo_name}.git"
+ RUBY
+ if repo_name =~ GITHUB_PULL_REQUEST_URL
+ {
+ "git" => "https://github.com/#{$1}.git",
+ "branch" => "refs/pull/#{$2}/head",
+ "ref" => nil,
+ "tag" => nil,
+ }
else
- warn_github_source_change(repo_name)
- "git://github.com/#{repo_name}.git"
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
+ "https://github.com/#{repo_name}.git"
end
end
- # TODO: 2.0 remove this deprecated git source
git_source(:gist) do |repo_name|
- warn_deprecated_git_source(:gist, 'https://gist.github.com/#{repo_name}.git')
+ warn_deprecated_git_source(:gist, '"https://gist.github.com/#{repo_name}.git"')
+
"https://gist.github.com/#{repo_name}.git"
end
- # TODO: 2.0 remove this deprecated git source
git_source(:bitbucket) do |repo_name|
- user_name, repo_name = repo_name.split "/"
- warn_deprecated_git_source(:bitbucket, 'https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git')
+ warn_deprecated_git_source(:bitbucket, <<-'RUBY'.strip)
+user_name, repo_name = repo_name.split("/")
+repo_name ||= user_name
+"https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
+ RUBY
+
+ user_name, repo_name = repo_name.split("/")
repo_name ||= user_name
"https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
end
@@ -308,7 +331,7 @@ module Bundler
end
def valid_keys
- @valid_keys ||= %w(group groups git path glob name branch ref tag require submodules platform platforms type source install_if)
+ @valid_keys ||= VALID_KEYS
end
def normalize_options(name, version, opts)
@@ -318,6 +341,7 @@ module Bundler
if name =~ /\s/
raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace)
end
+ raise GemfileError, %(an empty gem name is not valid) if name.empty?
normalize_hash(opts)
@@ -352,10 +376,14 @@ module Bundler
git_name = (git_names & opts.keys).last
if @git_sources[git_name]
- opts["git"] = @git_sources[git_name].call(opts[git_name])
+ git_opts = @git_sources[git_name].call(opts[git_name])
+ git_opts = { "git" => git_opts } if git_opts.is_a?(String)
+ opts.merge!(git_opts) do |key, _gemfile_value, _git_source_value|
+ raise GemfileError, %(The :#{key} option can't be used with `#{git_name}: #{opts[git_name].inspect}`)
+ end
end
- %w(git path).each do |type|
+ %w[git path].each do |type|
next unless param = opts[type]
if version.first && version.first =~ /^\s*=?\s*(\d[^\s]*)\s*$/
options = opts.merge("name" => name, "version" => $1)
@@ -366,8 +394,8 @@ module Bundler
opts["source"] = source
end
- opts["source"] ||= @source
- opts["env"] ||= @env
+ opts["source"] ||= @source
+ opts["env"] ||= @env
opts["platforms"] = platforms.dup
opts["group"] = groups
opts["should_include"] = install_if
@@ -377,7 +405,7 @@ module Bundler
normalize_hash(opts)
groups = groups.map {|group| ":#{group}" }.join(", ")
- validate_keys("group #{groups}", opts, %w(optional))
+ validate_keys("group #{groups}", opts, %w[optional])
opts["optional"] ||= false
end
@@ -390,25 +418,25 @@ module Bundler
raise GemfileError, %(The `branch` option for `#{command}` is not allowed. Only gems with a git source can specify a branch)
end
- if invalid_keys.any?
- message = String.new
- message << "You passed #{invalid_keys.map {|k| ":" + k }.join(", ")} "
- message << if invalid_keys.size > 1
- "as options for #{command}, but they are invalid."
- else
- "as an option for #{command}, but it is invalid."
- end
-
- message << " Valid options are: #{valid_keys.join(", ")}."
- message << " You may be able to resolve this by upgrading Bundler to the newest version."
- raise InvalidOption, message
+ return true unless invalid_keys.any?
+
+ message = String.new
+ message << "You passed #{invalid_keys.map {|k| ":" + k }.join(", ")} "
+ message << if invalid_keys.size > 1
+ "as options for #{command}, but they are invalid."
+ else
+ "as an option for #{command}, but it is invalid."
end
+
+ message << " Valid options are: #{valid_keys.join(", ")}."
+ message << " You may be able to resolve this by upgrading Bundler to the newest version."
+ raise InvalidOption, message
end
def normalize_source(source)
case source
when :gemcutter, :rubygems, :rubyforge
- Bundler::SharedHelpers.major_deprecation "The source :#{source} is deprecated because HTTP " \
+ Bundler::SharedHelpers.major_deprecation 2, "The source :#{source} is deprecated because HTTP " \
"requests are insecure.\nPlease change your source to 'https://" \
"rubygems.org' if possible, or 'http://rubygems.org' if not."
"http://rubygems.org"
@@ -419,39 +447,62 @@ module Bundler
end
end
- def check_primary_source_safety(source)
- return unless source.rubygems_primary_remotes.any?
+ def check_path_source_safety
+ return if @sources.global_path_source.nil?
+
+ msg = "You can no longer specify a path source by itself. Instead, \n" \
+ "either use the :path option on a gem, or specify the gems that \n" \
+ "bundler should find in the path source by passing a block to \n" \
+ "the path method, like: \n\n" \
+ " path 'dir/containing/rails' do\n" \
+ " gem 'rails'\n" \
+ " end\n\n"
+
+ SharedHelpers.major_deprecation(2, msg.strip)
+ end
+
+ def check_rubygems_source_safety
+ if @sources.implicit_global_source?
+ implicit_global_source_warning
+ elsif @sources.aggregate_global_source?
+ multiple_global_source_warning
+ end
+ end
+
+ def implicit_global_source_warning
+ Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \
+ "Not using an explicit global source may result in a different lockfile being generated depending on " \
+ "the gems you have installed locally before bundler is run. " \
+ "Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
+ end
- # TODO: 2.0 upgrade from setting to default
- if Bundler.settings[:disable_multisource]
- raise GemfileError, "Warning: this Gemfile contains multiple primary sources. " \
+ def multiple_global_source_warning
+ if Bundler.feature_flag.bundler_3_mode?
+ msg = "This Gemfile contains multiple primary sources. " \
"Each source after the first must include a block to indicate which gems " \
- "should come from that source. To downgrade this error to a warning, run " \
- "`bundle config --delete disable_multisource`"
+ "should come from that source"
+ raise GemfileEvalError, msg
else
- Bundler::SharedHelpers.major_deprecation "Your Gemfile contains multiple primary sources. " \
+ Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
- "a block to indicate which gems should come from the secondary source. " \
- "To upgrade this warning to an error, run `bundle config " \
- "disable_multisource true`."
+ "a block to indicate which gems should come from the secondary source."
end
end
- def warn_github_source_change(repo_name)
- # TODO: 2.0 remove deprecation
- Bundler::SharedHelpers.major_deprecation "The :github option uses the git: protocol, which is not secure. " \
- "Bundler 2.0 will use the https: protocol, which is secure. Enable this change now by " \
- "running `bundle config github.https true`."
- end
+ def warn_deprecated_git_source(name, replacement, additional_message = nil)
+ additional_message &&= " #{additional_message}"
+ replacement = if replacement.count("\n").zero?
+ "{|repo_name| #{replacement} }"
+ else
+ "do |repo_name|\n#{replacement.to_s.gsub(/^/, " ")}\n end"
+ end
+
+ Bundler::SharedHelpers.major_deprecation 3, <<-EOS
+The :#{name} git source is deprecated, and will be removed in the future.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
+
+ git_source(:#{name}) #{replacement}
- def warn_deprecated_git_source(name, repo_string)
- # TODO: 2.0 remove deprecation
- Bundler::SharedHelpers.major_deprecation <<-EOS
-The :#{name} git source is deprecated, and will be removed in Bundler 2.0. Add this code to your Gemfile to ensure it continues to work:
- git_source(:#{name}) do |repo_name|
- "#{repo_string}"
- end
EOS
end
@@ -530,7 +581,7 @@ The :#{name} git source is deprecated, and will be removed in Bundler 2.0. Add t
lines = contents.lines.to_a
indent = " # "
indicator = indent.tr("#", ">")
- first_line = (line_numer.zero?)
+ first_line = line_numer.zero?
last_line = (line_numer == (lines.count - 1))
m << "\n"
@@ -544,13 +595,13 @@ The :#{name} git source is deprecated, and will be removed in Bundler 2.0. Add t
end
end
- private
+ private
def parse_line_number_from_description
description = self.description
if dsl_path && description =~ /((#{Regexp.quote File.expand_path(dsl_path)}|#{Regexp.quote dsl_path.to_s}):\d+)/
trace_line = Regexp.last_match[1]
- description = description.sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
+ description = description.sub(/\n.*\n(\.\.\.)? *\^~+$/, "").sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
end
[trace_line, description]
end
diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb
index 5a1deeea47..476151ae56 100644
--- a/lib/bundler/endpoint_specification.rb
+++ b/lib/bundler/endpoint_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
# used for Creating Specifications from the Gemcutter Endpoint
class EndpointSpecification < Gem::Specification
@@ -9,11 +10,15 @@ module Bundler
attr_accessor :source, :remote, :dependencies
def initialize(name, version, platform, dependencies, metadata = nil)
+ super()
@name = name
@version = Gem::Version.create version
@platform = platform
@dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
+ @loaded_from = nil
+ @remote_specification = nil
+
parse_metadata(metadata)
end
@@ -71,6 +76,8 @@ module Bundler
@remote_specification.post_install_message
elsif _local_specification
_local_specification.post_install_message
+ else
+ super
end
end
@@ -80,6 +87,8 @@ module Bundler
@remote_specification.extensions
elsif _local_specification
_local_specification.extensions
+ else
+ super
end
end
@@ -95,7 +104,7 @@ module Bundler
@remote_specification = spec
end
- private
+ private
def local_specification_path
"#{base_dir}/specifications/#{full_name}.gemspec"
@@ -114,7 +123,7 @@ module Bundler
@required_ruby_version = Gem::Requirement.new(v)
end
end
- rescue => e
+ rescue StandardError => e
raise GemspecError, "There was an error parsing the metadata for the gem #{name} (#{version}): #{e.class}\n#{e}\nThe metadata was #{data.inspect}"
end
diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb
index 8b990baf40..00d4ef2196 100644
--- a/lib/bundler/env.rb
+++ b/lib/bundler/env.rb
@@ -1,33 +1,21 @@
# frozen_string_literal: true
-require "bundler/rubygems_integration"
-require "bundler/source/git/git_proxy"
+
+require_relative "rubygems_integration"
+require_relative "source/git/git_proxy"
module Bundler
class Env
- def write(io)
+ def self.write(io)
io.write report
end
- def report(options = {})
+ def self.report(options = {})
print_gemfile = options.delete(:print_gemfile) { true }
print_gemspecs = options.delete(:print_gemspecs) { true }
- out = String.new("## Environment\n\n```\n")
- out << "Bundler #{Bundler::VERSION}\n"
- out << "Rubygems #{Gem::VERSION}\n"
- out << "Ruby #{ruby_version}"
- out << "GEM_HOME #{ENV["GEM_HOME"]}\n" unless ENV["GEM_HOME"].nil? || ENV["GEM_HOME"].empty?
- out << "GEM_PATH #{ENV["GEM_PATH"]}\n" unless ENV["GEM_PATH"] == ENV["GEM_HOME"]
- out << "RVM #{ENV["rvm_version"]}\n" if ENV["rvm_version"]
- out << "Git #{git_version}\n"
- out << "Platform #{Gem::Platform.local}\n"
- out << "OpenSSL #{OpenSSL::OPENSSL_VERSION}\n" if defined?(OpenSSL::OPENSSL_VERSION)
- %w(rubygems-bundler open_gem).each do |name|
- specs = Bundler.rubygems.find_name(name)
- out << "#{name} (#{specs.map(&:version).join(",")})\n" unless specs.empty?
- end
-
- out << "```\n"
+ out = String.new
+ append_formatted_table("Environment", environment, out)
+ append_formatted_table("Bundler Build Metadata", BuildMetadata.to_h, out)
unless Bundler.settings.all.empty?
out << "\n## Bundler settings\n\n```\n"
@@ -43,9 +31,18 @@ module Bundler
return out unless SharedHelpers.in_bundle?
if print_gemfile
+ gemfiles = [Bundler.default_gemfile]
+ begin
+ gemfiles = Bundler.definition.gemfiles
+ rescue GemfileNotFound
+ nil
+ end
+
out << "\n## Gemfile\n"
- out << "\n### #{Bundler.default_gemfile.relative_path_from(SharedHelpers.pwd)}\n\n"
- out << "```ruby\n" << read_file(Bundler.default_gemfile).chomp << "\n```\n"
+ gemfiles.each do |gemfile|
+ out << "\n### #{Pathname.new(gemfile).relative_path_from(SharedHelpers.pwd)}\n\n"
+ out << "```ruby\n" << read_file(gemfile).chomp << "\n```\n"
+ end
out << "\n### #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}\n\n"
out << "```\n" << read_file(Bundler.default_lockfile).chomp << "\n```\n"
@@ -63,32 +60,91 @@ module Bundler
out
end
- private
-
- def read_file(filename)
- File.read(filename.to_s).strip
+ def self.read_file(filename)
+ Bundler.read_file(filename.to_s).strip
rescue Errno::ENOENT
"<No #{filename} found>"
- rescue => e
+ rescue RuntimeError => e
"#{e.class}: #{e.message}"
end
- def ruby_version
- str = String.new("#{RUBY_VERSION}")
- if RUBY_VERSION < "1.9"
- str << " (#{RUBY_RELEASE_DATE}"
- str << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
- str << ") [#{RUBY_PLATFORM}]\n"
- else
- str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
- str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]\n"
- end
+ def self.ruby_version
+ str = String.new(RUBY_VERSION)
+ str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
+ str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]"
end
- def git_version
+ def self.git_version
Bundler::Source::Git::GitProxy.new(nil, nil, nil).full_version
rescue Bundler::Source::Git::GitNotInstalledError
"not installed"
end
+
+ def self.version_of(script)
+ return "not installed" unless Bundler.which(script)
+ `#{script} --version`.chomp
+ end
+
+ def self.chruby_version
+ return "not installed" unless Bundler.which("chruby-exec")
+ `chruby-exec -- chruby --version`.
+ sub(/.*^chruby: (#{Gem::Version::VERSION_PATTERN}).*/m, '\1')
+ end
+
+ def self.environment
+ out = []
+
+ out << ["Bundler", Bundler::VERSION]
+ out << [" Platforms", Gem.platforms.join(", ")]
+ out << ["Ruby", ruby_version]
+ out << [" Full Path", Gem.ruby]
+ out << [" Config Dir", Pathname.new(Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE).dirname]
+ out << ["RubyGems", Gem::VERSION]
+ out << [" Gem Home", Gem.dir]
+ out << [" Gem Path", Gem.path.join(File::PATH_SEPARATOR)]
+ out << [" User Home", Gem.user_home]
+ out << [" User Path", Gem.user_dir]
+ out << [" Bin Dir", Gem.bindir]
+ if defined?(OpenSSL::SSL)
+ out << ["OpenSSL"]
+ out << [" Compiled", OpenSSL::OPENSSL_VERSION] if defined?(OpenSSL::OPENSSL_VERSION)
+ out << [" Loaded", OpenSSL::OPENSSL_LIBRARY_VERSION] if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION)
+ out << [" Cert File", OpenSSL::X509::DEFAULT_CERT_FILE] if defined?(OpenSSL::X509::DEFAULT_CERT_FILE)
+ out << [" Cert Dir", OpenSSL::X509::DEFAULT_CERT_DIR] if defined?(OpenSSL::X509::DEFAULT_CERT_DIR)
+ end
+ out << ["Tools"]
+ out << [" Git", git_version]
+ out << [" RVM", ENV.fetch("rvm_version") { version_of("rvm") }]
+ out << [" rbenv", version_of("rbenv")]
+ out << [" chruby", chruby_version]
+
+ %w[rubygems-bundler open_gem].each do |name|
+ specs = Bundler.rubygems.find_name(name)
+ out << [" #{name}", "(#{specs.map(&:version).join(",")})"] unless specs.empty?
+ end
+ if (exe = caller.last.split(":").first) && exe =~ %r{(exe|bin)/bundler?\z}
+ shebang = File.read(exe).lines.first
+ shebang.sub!(/^#!\s*/, "")
+ unless shebang.start_with?(Gem.ruby, "/usr/bin/env ruby")
+ out << ["Gem.ruby", Gem.ruby]
+ out << ["bundle #!", shebang]
+ end
+ end
+
+ out
+ end
+
+ def self.append_formatted_table(title, pairs, out)
+ return if pairs.empty?
+ out << "\n" unless out.empty?
+ out << "## #{title}\n\n```\n"
+ ljust = pairs.map {|k, _v| k.to_s.length }.max
+ pairs.each do |k, v|
+ out << "#{k.to_s.ljust(ljust)} #{v}\n"
+ end
+ out << "```\n"
+ end
+
+ private_class_method :read_file, :ruby_version, :git_version, :append_formatted_table, :version_of, :chruby_version
end
end
diff --git a/lib/bundler/environment_preserver.rb b/lib/bundler/environment_preserver.rb
index a891f4854d..0f08e049d8 100644
--- a/lib/bundler/environment_preserver.rb
+++ b/lib/bundler/environment_preserver.rb
@@ -1,12 +1,55 @@
# frozen_string_literal: true
+
module Bundler
class EnvironmentPreserver
- # @param env [ENV]
+ INTENTIONALLY_NIL = "BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL".freeze
+ BUNDLER_KEYS = %w[
+ BUNDLE_BIN_PATH
+ BUNDLE_GEMFILE
+ BUNDLER_VERSION
+ GEM_HOME
+ GEM_PATH
+ MANPATH
+ PATH
+ RB_USER_INSTALL
+ RUBYLIB
+ RUBYOPT
+ ].map(&:freeze).freeze
+ BUNDLER_PREFIX = "BUNDLER_ORIG_".freeze
+
+ def self.from_env
+ new(env_to_hash(ENV), BUNDLER_KEYS)
+ end
+
+ def self.env_to_hash(env)
+ to_hash = env.to_hash
+ return to_hash unless Gem.win_platform?
+
+ to_hash.each_with_object({}) {|(k,v), a| a[k.upcase] = v }
+ end
+
+ # @param env [Hash]
# @param keys [Array<String>]
def initialize(env, keys)
- @original = env.to_hash
+ @original = env
@keys = keys
- @prefix = "BUNDLER_ORIG_"
+ @prefix = BUNDLER_PREFIX
+ end
+
+ # Replaces `ENV` with the bundler environment variables backed up
+ def replace_with_backup
+ unless Gem.win_platform?
+ ENV.replace(backup)
+ return
+ end
+
+ # Fallback logic for Windows below to workaround
+ # https://bugs.ruby-lang.org/issues/16798. Can be dropped once all
+ # supported rubies include the fix for that.
+
+ ENV.clear
+
+ backup.each {|k, v| ENV[k] = v }
end
# @return [Hash]
@@ -14,9 +57,10 @@ module Bundler
env = @original.clone
@keys.each do |key|
value = env[key]
- original_value = env[@prefix + key]
- if !value.nil? && !value.empty? && original_value.nil?
- env[@prefix + key] = value
+ if !value.nil? && !value.empty?
+ env[@prefix + key] ||= value
+ elsif value.nil?
+ env[@prefix + key] ||= INTENTIONALLY_NIL
end
end
env
@@ -27,10 +71,13 @@ module Bundler
env = @original.clone
@keys.each do |key|
value_original = env[@prefix + key]
- unless value_original.nil? || value_original.empty?
+ next if value_original.nil? || value_original.empty?
+ if value_original == INTENTIONALLY_NIL
+ env.delete(key)
+ else
env[key] = value_original
- env.delete(@prefix + key)
end
+ env.delete(@prefix + key)
end
env
end
diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb
index 6ce8493ea7..9ad7460e58 100644
--- a/lib/bundler/errors.rb
+++ b/lib/bundler/errors.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class BundlerError < StandardError
def self.status_code(code)
@@ -55,6 +56,7 @@ module Bundler
class SudoNotPermittedError < BundlerError; status_code(30); end
class ThreadCreationError < BundlerError; status_code(33); end
class APIResponseMismatchError < BundlerError; status_code(34); end
+ class APIResponseInvalidDependenciesError < BundlerError; status_code(35); end
class GemfileEvalError < GemfileError; end
class MarshalError < StandardError; end
@@ -73,10 +75,26 @@ module Bundler
end
end
+ def permission_type
+ case @permission_type
+ when :create
+ "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
+ when :delete
+ permissions = "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
+ permissions += ", and the same thing for all subdirectories inside #{@path}" if File.directory?(@path)
+ permissions
+ else
+ "#{@permission_type} permissions for that path"
+ end
+ end
+
+ def parent_folder
+ File.dirname(@path)
+ end
+
def message
"There was an error while trying to #{action} `#{@path}`. " \
- "It is likely that you need to grant #{@permission_type} permissions " \
- "for that path."
+ "It is likely that you need to grant #{permission_type}."
end
status_code(23)
@@ -120,7 +138,7 @@ module Bundler
class VirtualProtocolError < BundlerError
def message
- "There was an error relating to virtualization and file access." \
+ "There was an error relating to virtualization and file access. " \
"It is likely that you need to grant access to or mount some file system correctly."
end
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index 150cac1e67..e441b941c2 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -1,22 +1,47 @@
# frozen_string_literal: true
+
module Bundler
class FeatureFlag
def self.settings_flag(flag, &default)
unless Bundler::Settings::BOOL_KEYS.include?(flag.to_s)
raise "Cannot use `#{flag}` as a settings feature flag since it isn't a bool key"
end
- define_method("#{flag}?") do
- value = Bundler.settings[flag]
- value = instance_eval(&default) if value.nil? && !default.nil?
+
+ settings_method("#{flag}?", flag, &default)
+ end
+ private_class_method :settings_flag
+
+ def self.settings_option(key, &default)
+ settings_method(key, key, &default)
+ end
+ private_class_method :settings_option
+
+ def self.settings_method(name, key, &default)
+ define_method(name) do
+ value = Bundler.settings[key]
+ value = instance_eval(&default) if value.nil?
value
end
end
+ private_class_method :settings_method
(1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } }
- settings_flag(:allow_offline_install) { bundler_2_mode? }
- settings_flag(:only_update_to_newer_versions) { bundler_2_mode? }
+ settings_flag(:allow_offline_install) { bundler_3_mode? }
+ settings_flag(:auto_clean_without_path) { bundler_3_mode? }
+ settings_flag(:cache_all) { bundler_3_mode? }
+ settings_flag(:default_install_uses_path) { bundler_3_mode? }
+ settings_flag(:forget_cli_options) { bundler_3_mode? }
+ settings_flag(:global_gem_cache) { bundler_3_mode? }
+ settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
+ settings_flag(:print_only_version_number) { bundler_3_mode? }
+ settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
+ settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
+ settings_flag(:update_requires_all_flag) { bundler_4_mode? }
+ settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? }
+
+ settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install }
def initialize(bundler_version)
@bundler_version = Gem::Version.create(bundler_version)
@@ -26,7 +51,5 @@ module Bundler
@bundler_version.segments.first
end
private :major_version
-
- class << self; private :settings_flag; end
end
end
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb
index 9e208e4957..e3253a942f 100644
--- a/lib/bundler/fetcher.rb
+++ b/lib/bundler/fetcher.rb
@@ -1,19 +1,23 @@
# frozen_string_literal: true
-require "bundler/vendored_persistent"
+
+require_relative "vendored_persistent"
require "cgi"
require "securerandom"
require "zlib"
+require "rubygems/request"
module Bundler
# Handles all the fetching with the rubygems server
class Fetcher
- autoload :CompactIndex, "bundler/fetcher/compact_index"
- autoload :Downloader, "bundler/fetcher/downloader"
- autoload :Dependency, "bundler/fetcher/dependency"
- autoload :Index, "bundler/fetcher/index"
+ autoload :CompactIndex, File.expand_path("fetcher/compact_index", __dir__)
+ autoload :Downloader, File.expand_path("fetcher/downloader", __dir__)
+ autoload :Dependency, File.expand_path("fetcher/dependency", __dir__)
+ autoload :Index, File.expand_path("fetcher/index", __dir__)
# This error is raised when it looks like the network is down
class NetworkDownError < HTTPError; end
+ # This error is raised if we should rate limit our requests to the API
+ class TooManyRequestsError < HTTPError; end
# This error is raised if the API returns a 413 (only printed in verbose)
class FallbackError < HTTPError; end
# This is the error raised if OpenSSL fails the cert verification
@@ -24,7 +28,8 @@ module Bundler
" is a chance you are experiencing a man-in-the-middle attack, but" \
" most likely your system doesn't have the CA certificates needed" \
" for verification. For information about OpenSSL certificates, see" \
- " http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile" \
+ " https://railsapps.github.io/openssl-certificate-verify-failed.html." \
+ " To connect without using SSL, edit your Gemfile" \
" sources and change 'https' to 'http'."
end
end
@@ -43,7 +48,8 @@ module Bundler
remote_uri = filter_uri(remote_uri)
super "Authentication is required for #{remote_uri}.\n" \
"Please supply credentials for this source. You can do this by running:\n" \
- " bundle config #{remote_uri} username:password"
+ "`bundle config set --global #{remote_uri} username:password`\n" \
+ "or by storing the credentials in the `#{Settings.key_for(remote_uri)}` environment variable"
end
end
# This error is raised if HTTP authentication is provided, but incorrect.
@@ -93,13 +99,14 @@ module Bundler
spec -= [nil, "ruby", ""]
spec_file_name = "#{spec.join "-"}.gemspec"
- uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
+ uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
if uri.scheme == "file"
- Bundler.load_marshal Gem.inflate(Gem.read_binary(uri.path))
+ path = Bundler.rubygems.correct_for_windows_path(uri.path)
+ Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
Bundler.load_gemspec(cached_spec_path)
else
- Bundler.load_marshal Gem.inflate(downloader.fetch(uri).body)
+ Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
end
rescue MarshalError
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
@@ -132,7 +139,6 @@ module Bundler
end
specs.each do |name, version, platform, dependencies, metadata|
- next if name == "bundler"
spec = if dependencies
EndpointSpecification.new(name, version, platform, dependencies, metadata)
else
@@ -177,7 +183,7 @@ module Bundler
# engine_version raises on unknown engines
engine_version = begin
ruby.engine_versions
- rescue
+ rescue RuntimeError
"???"
end
agent << " #{ruby.engine}/#{ruby.versions_string(engine_version)}"
@@ -211,7 +217,7 @@ module Bundler
"#<#{self.class}:0x#{object_id} uri=#{uri}>"
end
- private
+ private
FETCHERS = [CompactIndex, Dependency, Index].freeze
@@ -224,8 +230,9 @@ module Bundler
"BUILDBOX" => "buildbox",
"GO_SERVER_URL" => "go",
"SNAP_CI" => "snap",
+ "GITLAB_CI" => "gitlab",
"CI_NAME" => ENV["CI_NAME"],
- "CI" => "ci"
+ "CI" => "ci",
}
env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci }
end
@@ -237,9 +244,9 @@ module Bundler
Bundler.settings[:ssl_client_cert]
raise SSLError if needs_ssl && !defined?(OpenSSL::SSL)
- con = Bundler::Persistent::Net::HTTP::Persistent.new "bundler", :ENV
+ con = PersistentHTTP.new :name => "bundler", :proxy => :ENV
if gem_proxy = Bundler.rubygems.configuration[:http_proxy]
- con.proxy = URI.parse(gem_proxy) if gem_proxy != :no_proxy
+ con.proxy = Bundler::URI.parse(gem_proxy) if gem_proxy != :no_proxy
end
if remote_uri.scheme == "https"
@@ -248,8 +255,11 @@ module Bundler
con.cert_store = bundler_cert_store
end
- if Bundler.settings[:ssl_client_cert]
- pem = File.read(Bundler.settings[:ssl_client_cert])
+ ssl_client_cert = Bundler.settings[:ssl_client_cert] ||
+ (Bundler.rubygems.configuration.ssl_client_cert if
+ Bundler.rubygems.configuration.respond_to?(:ssl_client_cert))
+ if ssl_client_cert
+ pem = File.read(ssl_client_cert)
con.cert = OpenSSL::X509::Certificate.new(pem)
con.key = OpenSSL::PKey::RSA.new(pem)
end
@@ -273,26 +283,28 @@ module Bundler
Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
- Bundler::Persistent::Net::HTTP::Persistent::Error, Zlib::BufError, Errno::EHOSTUNREACH
+ PersistentHTTP::Error, Zlib::BufError, Errno::EHOSTUNREACH
].freeze
def bundler_cert_store
store = OpenSSL::X509::Store.new
- if Bundler.settings[:ssl_ca_cert]
- if File.directory? Bundler.settings[:ssl_ca_cert]
- store.add_path Bundler.settings[:ssl_ca_cert]
+ ssl_ca_cert = Bundler.settings[:ssl_ca_cert] ||
+ (Bundler.rubygems.configuration.ssl_ca_cert if
+ Bundler.rubygems.configuration.respond_to?(:ssl_ca_cert))
+ if ssl_ca_cert
+ if File.directory? ssl_ca_cert
+ store.add_path ssl_ca_cert
else
- store.add_file Bundler.settings[:ssl_ca_cert]
+ store.add_file ssl_ca_cert
end
else
store.set_default_paths
- certs = File.expand_path("../ssl_certs/*/*.pem", __FILE__)
- Dir.glob(certs).each {|c| store.add_file c }
+ Gem::Request.get_cert_files.each {|c| store.add_file c }
end
store
end
- private
+ private
def remote_uri
@remote.uri
diff --git a/lib/bundler/fetcher/base.rb b/lib/bundler/fetcher/base.rb
index 271729a534..16cc98273a 100644
--- a/lib/bundler/fetcher/base.rb
+++ b/lib/bundler/fetcher/base.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class Fetcher
class Base
@@ -37,7 +38,7 @@ module Bundler
false
end
- private
+ private
def log_specs(debug_msg)
if Bundler.ui.debug?
diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb
index 97de88101b..bc69b884ec 100644
--- a/lib/bundler/fetcher/compact_index.rb
+++ b/lib/bundler/fetcher/compact_index.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
-require "bundler/fetcher/base"
-require "bundler/worker"
+
+require_relative "base"
+require_relative "../worker"
module Bundler
- autoload :CompactIndexClient, "bundler/compact_index_client"
+ autoload :CompactIndexClient, File.expand_path("../compact_index_client", __dir__)
class Fetcher
class CompactIndex < Base
@@ -38,7 +39,13 @@ module Bundler
until remaining_gems.empty?
log_specs "Looking up gems #{remaining_gems.inspect}"
- deps = compact_index_client.dependencies(remaining_gems)
+ deps = begin
+ parallel_compact_index_client.dependencies(remaining_gems)
+ rescue TooManyRequestsError
+ @bundle_worker.stop if @bundle_worker
+ @bundle_worker = nil # reset it. Not sure if necessary
+ serial_compact_index_client.dependencies(remaining_gems)
+ end
next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
deps.each {|dep| gem_info << dep }
complete_gems.concat(deps.map(&:first)).uniq!
@@ -61,7 +68,7 @@ module Bundler
compact_index_request :fetch_spec
def available?
- return nil unless md5_available?
+ return nil unless SharedHelpers.md5_available?
user_home = Bundler.user_home
return nil unless user_home.directory? && user_home.writable?
# Read info file checksums out of /versions, so we can know if gems are up to date
@@ -76,27 +83,35 @@ module Bundler
true
end
- private
+ private
def compact_index_client
- @compact_index_client ||= begin
+ @compact_index_client ||=
SharedHelpers.filesystem_access(cache_path) do
CompactIndexClient.new(cache_path, client_fetcher)
- end.tap do |client|
- client.in_parallel = lambda do |inputs, &blk|
- func = lambda {|object, _index| blk.call(object) }
- worker = bundle_worker(func)
- inputs.each {|input| worker.enq(input) }
- inputs.map { worker.deq }
- end
end
+ end
+
+ def parallel_compact_index_client
+ compact_index_client.execution_mode = lambda do |inputs, &blk|
+ func = lambda {|object, _index| blk.call(object) }
+ worker = bundle_worker(func)
+ inputs.each {|input| worker.enq(input) }
+ inputs.map { worker.deq }
end
+
+ compact_index_client
+ end
+
+ def serial_compact_index_client
+ compact_index_client.sequential_execution_mode!
+ compact_index_client
end
def bundle_worker(func = nil)
@bundle_worker ||= begin
worker_name = "Compact Index (#{display_uri.host})"
- Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)
+ Bundler::Worker.new(Bundler.settings.processor_count, worker_name, func)
end
@bundle_worker.tap do |worker|
worker.instance_variable_set(:@func, func) if func
@@ -120,16 +135,6 @@ module Bundler
Net::HTTPNotModified.new(nil, nil, nil)
end
end
-
- def md5_available?
- require "openssl"
- OpenSSL::Digest::MD5.digest("")
- true
- rescue LoadError
- true
- rescue OpenSSL::Digest::DigestError
- false
- end
end
end
end
diff --git a/lib/bundler/fetcher/dependency.rb b/lib/bundler/fetcher/dependency.rb
index 445b0f2332..c52c32fb5b 100644
--- a/lib/bundler/fetcher/dependency.rb
+++ b/lib/bundler/fetcher/dependency.rb
@@ -1,12 +1,13 @@
# frozen_string_literal: true
-require "bundler/fetcher/base"
+
+require_relative "base"
require "cgi"
module Bundler
class Fetcher
class Dependency < Base
def available?
- fetch_uri.scheme != "file" && downloader.fetch(dependency_api_uri)
+ @available ||= fetch_uri.scheme != "file" && downloader.fetch(dependency_api_uri)
rescue NetworkDownError => e
raise HTTPError, e.message
rescue AuthenticationRequiredError
diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb
index 453e4645eb..f2aad3a500 100644
--- a/lib/bundler/fetcher/downloader.rb
+++ b/lib/bundler/fetcher/downloader.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class Fetcher
class Downloader
@@ -10,38 +11,50 @@ module Bundler
@redirect_limit = redirect_limit
end
- def fetch(uri, options = {}, counter = 0)
+ def fetch(uri, headers = {}, counter = 0)
raise HTTPError, "Too many redirects" if counter >= redirect_limit
- response = request(uri, options)
- Bundler.ui.debug("HTTP #{response.code} #{response.message} #{uri}")
+ filtered_uri = URICredentialsFilter.credential_filtered_uri(uri)
+
+ response = request(uri, headers)
+ Bundler.ui.debug("HTTP #{response.code} #{response.message} #{filtered_uri}")
case response
when Net::HTTPSuccess, Net::HTTPNotModified
response
when Net::HTTPRedirection
- new_uri = URI.parse(response["location"])
+ new_uri = Bundler::URI.parse(response["location"])
if new_uri.host == uri.host
new_uri.user = uri.user
new_uri.password = uri.password
end
- fetch(new_uri, options, counter + 1)
+ fetch(new_uri, headers, counter + 1)
+ when Net::HTTPRequestedRangeNotSatisfiable
+ new_headers = headers.dup
+ new_headers.delete("Range")
+ new_headers["Accept-Encoding"] = "gzip"
+ fetch(uri, new_headers)
when Net::HTTPRequestEntityTooLarge
raise FallbackError, response.body
+ when Net::HTTPTooManyRequests
+ raise TooManyRequestsError, response.body
when Net::HTTPUnauthorized
+ raise BadAuthenticationError, uri.host if uri.userinfo
raise AuthenticationRequiredError, uri.host
when Net::HTTPNotFound
- raise FallbackError, "Net::HTTPNotFound"
+ raise FallbackError, "Net::HTTPNotFound: #{filtered_uri}"
else
raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
end
end
- def request(uri, options)
+ def request(uri, headers)
validate_uri_scheme!(uri)
- Bundler.ui.debug "HTTP GET #{uri}"
- req = Net::HTTP::Get.new uri.request_uri, options
+ filtered_uri = URICredentialsFilter.credential_filtered_uri(uri)
+
+ Bundler.ui.debug "HTTP GET #{filtered_uri}"
+ req = Net::HTTP::Get.new uri.request_uri, headers
if uri.user
user = CGI.unescape(uri.user)
password = uri.password ? CGI.unescape(uri.password) : nil
@@ -55,17 +68,16 @@ module Bundler
raise CertificateFailureError.new(uri)
rescue *HTTP_ERRORS => e
Bundler.ui.trace e
- case e.message
- when /host down:/, /getaddrinfo: nodename nor servname provided/
+ if e.is_a?(SocketError) || e.message =~ /host down:/
raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \
"connection and try again."
else
- raise HTTPError, "Network error while fetching #{URICredentialsFilter.credential_filtered_uri(uri)}" \
+ raise HTTPError, "Network error while fetching #{filtered_uri}" \
" (#{e})"
end
end
- private
+ private
def validate_uri_scheme!(uri)
return if uri.scheme =~ /\Ahttps?\z/
diff --git a/lib/bundler/fetcher/index.rb b/lib/bundler/fetcher/index.rb
index d8e212989e..0d14c47aa7 100644
--- a/lib/bundler/fetcher/index.rb
+++ b/lib/bundler/fetcher/index.rb
@@ -1,24 +1,24 @@
# frozen_string_literal: true
-require "bundler/fetcher/base"
-require "rubygems/remote_fetcher"
+
+require_relative "base"
module Bundler
class Fetcher
class Index < Base
def specs(_gem_names)
Bundler.rubygems.fetch_all_remote_specs(remote)
- rescue Gem::RemoteFetcher::FetchError, OpenSSL::SSL::SSLError, Net::HTTPFatalError => e
+ rescue Gem::RemoteFetcher::FetchError => e
case e.message
when /certificate verify failed/
raise CertificateFailureError.new(display_uri)
when /401/
+ raise BadAuthenticationError, remote_uri if remote_uri.userinfo
raise AuthenticationRequiredError, remote_uri
when /403/
raise BadAuthenticationError, remote_uri if remote_uri.userinfo
raise AuthenticationRequiredError, remote_uri
else
- Bundler.ui.trace e
- raise HTTPError, "Could not fetch specs from #{display_uri}"
+ raise HTTPError, "Could not fetch specs from #{display_uri} due to underlying error <#{e.message}>"
end
end
@@ -26,20 +26,21 @@ module Bundler
spec -= [nil, "ruby", ""]
spec_file_name = "#{spec.join "-"}.gemspec"
- uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
+ uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
if uri.scheme == "file"
- Bundler.load_marshal Gem.inflate(Gem.read_binary(uri.path))
+ path = Bundler.rubygems.correct_for_windows_path(uri.path)
+ Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
Bundler.load_gemspec(cached_spec_path)
else
- Bundler.load_marshal Gem.inflate(downloader.fetch(uri).body)
+ Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
end
rescue MarshalError
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
"Your network or your gem server is probably having issues right now."
end
- private
+ private
# cached gem specification path, if one exists
def gemspec_cached_path(spec_file_name)
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
index 3ba3dcdd91..cc615db60c 100644
--- a/lib/bundler/friendly_errors.rb
+++ b/lib/bundler/friendly_errors.rb
@@ -1,11 +1,22 @@
-# encoding: utf-8
# frozen_string_literal: true
-require "cgi"
-require "bundler/vendored_thor"
+
+require_relative "vendored_thor"
module Bundler
module FriendlyErrors
- module_function
+ module_function
+
+ def enable!
+ @disabled = false
+ end
+
+ def disabled?
+ @disabled
+ end
+
+ def disable!
+ @disabled = true
+ end
def log_error(error)
case error
@@ -16,7 +27,7 @@ module Bundler
Bundler.ui.error error.message
when GemRequireError
Bundler.ui.error error.message
- Bundler.ui.trace error.orig_exception, nil, true
+ Bundler.ui.trace error.orig_exception
when BundlerError
Bundler.ui.error error.message, :wrap => true
Bundler.ui.trace error
@@ -24,13 +35,7 @@ module Bundler
Bundler.ui.error error.message
when LoadError
raise error unless error.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/
- Bundler.ui.error "\nCould not load OpenSSL."
- Bundler.ui.warn <<-WARN, :wrap => true
- You must recompile Ruby with OpenSSL support or change the sources in your \
- Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL \
- using RVM are available at http://rvm.io/packages/openssl.
- WARN
- Bundler.ui.trace error
+ Bundler.ui.error "\nCould not load OpenSSL. #{error.class}: #{error}\n#{error.backtrace.join("\n ")}"
when Interrupt
Bundler.ui.error "\nQuitting..."
Bundler.ui.trace error
@@ -56,70 +61,51 @@ module Bundler
end
def request_issue_report_for(e)
- Bundler.ui.info <<-EOS.gsub(/^ {8}/, "")
+ Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, nil
--- ERROR REPORT TEMPLATE -------------------------------------------------------
- # Error Report
-
- ## Questions
-
- Please fill out answers to these questions, it'll help us figure out
- why things are going wrong.
-
- - **What did you do?**
-
- I ran the command `#{$PROGRAM_NAME} #{ARGV.join(" ")}`
-
- - **What did you expect to happen?**
-
- I expected Bundler to...
-
- - **What happened instead?**
-
- Instead, what happened was...
-
- - **Have you tried any solutions posted on similar issues in our issue tracker, stack overflow, or google?**
-
- I tried...
-
- - **Have you read our issues document, https://github.com/bundler/bundler/blob/master/doc/contributing/ISSUES.md?**
-
- ...
-
- ## Backtrace
```
#{e.class}: #{e.message}
#{e.backtrace && e.backtrace.join("\n ").chomp}
```
- #{Bundler::Env.new.report}
+ #{Bundler::Env.report}
--- TEMPLATE END ----------------------------------------------------------------
EOS
Bundler.ui.error "Unfortunately, an unexpected error occurred, and Bundler cannot continue."
- Bundler.ui.warn <<-EOS.gsub(/^ {8}/, "")
+ Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, :yellow
First, try this link to see if there are any existing issue reports for this error:
#{issues_url(e)}
- If there aren't any reports for this error yet, please create copy and paste the report template above into a new issue. Don't forget to anonymize any private data! The new issue form is located at:
- https://github.com/bundler/bundler/issues/new
+ If there aren't any reports for this error yet, please fill in the new issue form located at #{new_issue_url}, and copy and paste the report template above in there.
EOS
end
def issues_url(exception)
message = exception.message.lines.first.tr(":", " ").chomp
message = message.split("-").first if exception.is_a?(Errno)
- "https://github.com/bundler/bundler/search?q=" \
+ require "cgi"
+ "https://github.com/rubygems/rubygems/search?q=" \
"#{CGI.escape(message)}&type=Issues"
end
+
+ def new_issue_url
+ "https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md"
+ end
end
def self.with_friendly_errors
+ FriendlyErrors.enable!
yield
- rescue Exception => e
+ rescue SignalException
+ raise
+ rescue Exception => e # rubocop:disable Lint/RescueException
+ raise if FriendlyErrors.disabled?
+
FriendlyErrors.log_error(e)
exit FriendlyErrors.exit_status(e)
end
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb
index 936d1361fa..034f2e5960 100644
--- a/lib/bundler/gem_helper.rb
+++ b/lib/bundler/gem_helper.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
-require "bundler/vendored_thor" unless defined?(Thor)
-require "bundler"
+
+require_relative "../bundler"
+require "shellwords"
module Bundler
class GemHelper
@@ -14,6 +15,10 @@ module Bundler
new(opts[:dir], opts[:name]).install
end
+ def tag_prefix=(prefix)
+ instance.tag_prefix = prefix
+ end
+
def gemspec(&block)
gemspec = instance.gemspec
block.call(gemspec) if block
@@ -23,13 +28,15 @@ module Bundler
attr_reader :spec_path, :base, :gemspec
+ attr_writer :tag_prefix
+
def initialize(base = nil, name = nil)
- Bundler.ui = UI::Shell.new
- @base = (base ||= SharedHelpers.pwd)
- gemspecs = name ? [File.join(base, "#{name}.gemspec")] : Dir[File.join(base, "{,*}.gemspec")]
+ @base = File.expand_path(base || SharedHelpers.pwd)
+ gemspecs = name ? [File.join(@base, "#{name}.gemspec")] : Gem::Util.glob_files_in_dir("{,*}.gemspec", @base)
raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1
@spec_path = gemspecs.first
@gemspec = Bundler.load_gemspec(@spec_path)
+ @tag_prefix = ""
end
def install
@@ -40,6 +47,11 @@ module Bundler
built_gem_path = build_gem
end
+ desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory."
+ task "build:checksum" => "build" do
+ build_checksum(built_gem_path)
+ end
+
desc "Build and install #{name}-#{version}.gem into system gems."
task "install" => "build" do
install_gem(built_gem_path)
@@ -50,8 +62,8 @@ module Bundler
install_gem(built_gem_path, :local)
end
- desc "Create tag #{version_tag} and build and push #{name}-#{version}.gem to Rubygems\n" \
- "To prevent publishing in Rubygems use `gem_push=no rake release`"
+ desc "Create tag #{version_tag} and build and push #{name}-#{version}.gem to #{gem_push_host}\n" \
+ "To prevent publishing in RubyGems use `gem_push=no rake release`"
task "release", [:remote] => ["build", "release:guard_clean",
"release:source_control_push", "release:rubygem_push"] do
end
@@ -64,7 +76,7 @@ module Bundler
tag_version { git_push(args[:remote]) } unless already_tagged?
end
- task "release:rubygem_push" do
+ task "release:rubygem_push" => "build" do
rubygem_push(built_gem_path) if gem_push?
end
@@ -73,7 +85,7 @@ module Bundler
def build_gem
file_name = nil
- sh("gem build -V '#{spec_path}'") do
+ sh([*gem_command, "build", "-V", spec_path]) do
file_name = File.basename(built_gem_path)
SharedHelpers.filesystem_access(File.join(base, "pkg")) {|p| FileUtils.mkdir_p(p) }
FileUtils.mv(built_gem_path, "pkg")
@@ -84,46 +96,70 @@ module Bundler
def install_gem(built_gem_path = nil, local = false)
built_gem_path ||= build_gem
- out, _ = sh_with_code("gem install '#{built_gem_path}'#{" --local" if local}")
- raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
+ cmd = [*gem_command, "install", built_gem_path.to_s]
+ cmd << "--local" if local
+ sh(cmd)
Bundler.ui.confirm "#{name} (#{version}) installed."
end
- protected
+ def build_checksum(built_gem_path = nil)
+ built_gem_path ||= build_gem
+ SharedHelpers.filesystem_access(File.join(base, "checksums")) {|p| FileUtils.mkdir_p(p) }
+ file_name = "#{File.basename(built_gem_path)}.sha512"
+ require "digest/sha2"
+ checksum = ::Digest::SHA512.new.hexdigest(built_gem_path.to_s)
+ target = File.join(base, "checksums", file_name)
+ File.write(target, checksum)
+ Bundler.ui.confirm "#{name} #{version} checksum written to checksums/#{file_name}."
+ end
+
+ protected
def rubygem_push(path)
- allowed_push_host = nil
- gem_command = "gem push '#{path}'"
- gem_command += " --key #{gem_key}" if gem_key
- if @gemspec.respond_to?(:metadata)
- allowed_push_host = @gemspec.metadata["allowed_push_host"]
- gem_command += " --host #{allowed_push_host}" if allowed_push_host
- end
- unless allowed_push_host || Bundler.user_home.join(".gem/credentials").file?
- raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
- end
- sh(gem_command)
- Bundler.ui.confirm "Pushed #{name} #{version} to #{allowed_push_host ? allowed_push_host : "rubygems.org."}"
+ cmd = [*gem_command, "push", path]
+ cmd << "--key" << gem_key if gem_key
+ cmd << "--host" << allowed_push_host if allowed_push_host
+ sh_with_input(cmd)
+ Bundler.ui.confirm "Pushed #{name} #{version} to #{gem_push_host}"
end
def built_gem_path
- Dir[File.join(base, "#{name}-*.gem")].sort_by {|f| File.mtime(f) }.last
+ Gem::Util.glob_files_in_dir("#{name}-*.gem", base).sort_by {|f| File.mtime(f) }.last
+ end
+
+ def git_push(remote = nil)
+ remote ||= default_remote
+ sh("git push #{remote} refs/heads/#{current_branch}".shellsplit)
+ sh("git push #{remote} refs/tags/#{version_tag}".shellsplit)
+ Bundler.ui.confirm "Pushed git commits and release tag."
end
- def git_push(remote = "")
- perform_git_push remote
- perform_git_push "#{remote} --tags"
- Bundler.ui.confirm "Pushed git commits and tags."
+ def default_remote
+ remote_for_branch, status = sh_with_status(%W[git config --get branch.#{current_branch}.remote])
+ return "origin" unless status.success?
+
+ remote_for_branch.strip
+ end
+
+ def current_branch
+ # We can replace this with `git branch --show-current` once we drop support for git < 2.22.0
+ sh(%w[git rev-parse --abbrev-ref HEAD]).gsub(%r{\Aheads/}, "").strip
end
- def perform_git_push(options = "")
- cmd = "git push #{options}"
- out, code = sh_with_code(cmd)
- raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
+ def allowed_push_host
+ @gemspec.metadata["allowed_push_host"] if @gemspec.respond_to?(:metadata)
+ end
+
+ def gem_push_host
+ env_rubygems_host = ENV["RUBYGEMS_HOST"]
+ env_rubygems_host = nil if
+ env_rubygems_host && env_rubygems_host.empty?
+
+ allowed_push_host || env_rubygems_host || "rubygems.org"
end
def already_tagged?
- return false unless sh("git tag").split(/\n/).include?(version_tag)
+ return false unless sh(%w[git tag]).split(/\n/).include?(version_tag)
Bundler.ui.confirm "Tag #{version_tag} has already been created."
true
end
@@ -133,20 +169,20 @@ module Bundler
end
def clean?
- sh_with_code("git diff --exit-code")[1] == 0
+ sh_with_status(%w[git diff --exit-code])[1].success?
end
def committed?
- sh_with_code("git diff-index --quiet --cached HEAD")[1] == 0
+ sh_with_status(%w[git diff-index --quiet --cached HEAD])[1].success?
end
def tag_version
- sh "git tag -m \"Version #{version}\" #{version_tag}"
+ sh %W[git tag -m Version\ #{version} #{version_tag}]
Bundler.ui.confirm "Tagged #{version_tag}."
yield if block_given?
- rescue
+ rescue RuntimeError
Bundler.ui.error "Untagging #{version_tag} due to error."
- sh_with_code "git tag -d #{version_tag}"
+ sh_with_status %W[git tag -d #{version_tag}]
raise
end
@@ -155,29 +191,34 @@ module Bundler
end
def version_tag
- "v#{version}"
+ "#{@tag_prefix}v#{version}"
end
def name
gemspec.name
end
+ def sh_with_input(cmd)
+ Bundler.ui.debug(cmd)
+ SharedHelpers.chdir(base) do
+ abort unless Kernel.system(*cmd)
+ end
+ end
+
def sh(cmd, &block)
- out, code = sh_with_code(cmd, &block)
- unless code.zero?
- raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
+ out, status = sh_with_status(cmd, &block)
+ unless status.success?
+ raise("Running `#{cmd.shelljoin}` failed with the following output:\n\n#{out}\n")
end
out
end
- def sh_with_code(cmd, &block)
- cmd += " 2>&1"
- outbuf = String.new
+ def sh_with_status(cmd, &block)
Bundler.ui.debug(cmd)
SharedHelpers.chdir(base) do
- outbuf = `#{cmd}`
- status = $?.exitstatus
- block.call(outbuf) if status.zero? && block
+ outbuf = IO.popen(cmd, :err => [:child, :out], &:read)
+ status = $?
+ block.call(outbuf) if status.success? && block
[outbuf, status]
end
end
@@ -187,7 +228,11 @@ module Bundler
end
def gem_push?
- !%w(n no nil false off 0).include?(ENV["gem_push"].to_s.downcase)
+ !%w[n no nil false off 0].include?(ENV["gem_push"].to_s.downcase)
+ end
+
+ def gem_command
+ ENV["GEM_COMMAND"]&.shellsplit || ["gem"]
end
end
end
diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb
index 955834ff01..b271b8d229 100644
--- a/lib/bundler/gem_helpers.rb
+++ b/lib/bundler/gem_helpers.rb
@@ -1,7 +1,8 @@
# frozen_string_literal: true
+
module Bundler
module GemHelpers
- GENERIC_CACHE = {} # rubocop:disable MutableConstant
+ GENERIC_CACHE = { Gem::Platform::RUBY => Gem::Platform::RUBY } # rubocop:disable Style/MutableConstant
GENERICS = [
[Gem::Platform.new("java"), Gem::Platform.new("java")],
[Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")],
@@ -9,12 +10,10 @@ module Bundler
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
[Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
- [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")]
+ [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
].freeze
def generic(p)
- return p if p == Gem::Platform::RUBY
-
GENERIC_CACHE[p] ||= begin
_, found = GENERICS.find do |match, _generic|
p.os == match.os && (!match.cpu || p.cpu == match.cpu)
@@ -25,47 +24,44 @@ module Bundler
module_function :generic
def generic_local_platform
- generic(Bundler.local_platform)
+ generic(local_platform)
end
module_function :generic_local_platform
+ def local_platform
+ Bundler.local_platform
+ end
+ module_function :local_platform
+
def platform_specificity_match(spec_platform, user_platform)
spec_platform = Gem::Platform.new(spec_platform)
- return PlatformMatch::EXACT_MATCH if spec_platform == user_platform
- return PlatformMatch::WORST_MATCH if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
-
- PlatformMatch.new(
- PlatformMatch.os_match(spec_platform, user_platform),
- PlatformMatch.cpu_match(spec_platform, user_platform),
- PlatformMatch.platform_version_match(spec_platform, user_platform)
- )
+
+ PlatformMatch.specificity_score(spec_platform, user_platform)
end
module_function :platform_specificity_match
def select_best_platform_match(specs, platform)
- specs.select {|spec| spec.match_platform(platform) }.
- min_by {|spec| platform_specificity_match(spec.platform, platform) }
+ matching = specs.select {|spec| spec.match_platform(platform) }
+ exact = matching.select {|spec| spec.platform == platform }
+ return exact if exact.any?
+
+ sorted_matching = matching.sort_by {|spec| platform_specificity_match(spec.platform, platform) }
+ exemplary_spec = sorted_matching.first
+
+ sorted_matching.take_while{|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) }
end
module_function :select_best_platform_match
- PlatformMatch = Struct.new(:os_match, :cpu_match, :platform_version_match)
class PlatformMatch
- def <=>(other)
- return nil unless other.is_a?(PlatformMatch)
-
- m = os_match <=> other.os_match
- return m unless m.zero?
+ def self.specificity_score(spec_platform, user_platform)
+ return -1 if spec_platform == user_platform
+ return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
- m = cpu_match <=> other.cpu_match
- return m unless m.zero?
-
- m = platform_version_match <=> other.platform_version_match
- m
+ os_match(spec_platform, user_platform) +
+ cpu_match(spec_platform, user_platform) * 10 +
+ platform_version_match(spec_platform, user_platform) * 100
end
- EXACT_MATCH = new(-1, -1, -1).freeze
- WORST_MATCH = new(1_000_000, 1_000_000, 1_000_000).freeze
-
def self.os_match(spec_platform, user_platform)
if spec_platform.os == user_platform.os
0
@@ -96,5 +92,19 @@ module Bundler
end
end
end
+
+ def same_specificity(platform, spec, exemplary_spec)
+ platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform)
+ end
+ module_function :same_specificity
+
+ def same_deps(spec, exemplary_spec)
+ same_runtime_deps = spec.dependencies.sort == exemplary_spec.dependencies.sort
+ return same_runtime_deps unless spec.is_a?(Gem::Specification) && exemplary_spec.is_a?(Gem::Specification)
+
+ same_metadata_deps = spec.required_ruby_version == exemplary_spec.required_ruby_version && spec.required_rubygems_version == exemplary_spec.required_rubygems_version
+ same_runtime_deps && same_metadata_deps
+ end
+ module_function :same_deps
end
end
diff --git a/lib/bundler/gem_remote_fetcher.rb b/lib/bundler/gem_remote_fetcher.rb
deleted file mode 100644
index 481838a5e2..0000000000
--- a/lib/bundler/gem_remote_fetcher.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-require "rubygems/remote_fetcher"
-
-module Bundler
- # Adds support for setting custom HTTP headers when fetching gems from the
- # server.
- #
- # TODO: Get rid of this when and if gemstash only supports RubyGems versions
- # that contain https://github.com/rubygems/rubygems/commit/3db265cc20b2f813.
- class GemRemoteFetcher < Gem::RemoteFetcher
- attr_accessor :headers
-
- # Extracted from RubyGems 2.4.
- def fetch_http(uri, last_modified = nil, head = false, depth = 0)
- fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
- # beginning of change
- response = request uri, fetch_type, last_modified do |req|
- headers.each {|k, v| req.add_field(k, v) } if headers
- end
- # end of change
-
- case response
- when Net::HTTPOK, Net::HTTPNotModified then
- response.uri = uri if response.respond_to? :uri
- head ? response : response.body
- when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
- Net::HTTPTemporaryRedirect then
- raise FetchError.new("too many redirects", uri) if depth > 10
-
- location = URI.parse response["Location"]
-
- if https?(uri) && !https?(location)
- raise FetchError.new("redirecting to non-https resource: #{location}", uri)
- end
-
- fetch_http(location, last_modified, head, depth + 1)
- else
- raise FetchError.new("bad response #{response.message} #{response.code}", uri)
- end
- end
- end
-end
diff --git a/lib/bundler/gem_tasks.rb b/lib/bundler/gem_tasks.rb
index 230e7f28f2..bc725d3602 100644
--- a/lib/bundler/gem_tasks.rb
+++ b/lib/bundler/gem_tasks.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
+
require "rake/clean"
CLOBBER.include "pkg"
-require "bundler/gem_helper"
+require_relative "gem_helper"
Bundler::GemHelper.install_tasks
diff --git a/lib/bundler/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb
index d60d823d9c..3cce3f2139 100644
--- a/lib/bundler/gem_version_promoter.rb
+++ b/lib/bundler/gem_version_promoter.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
# This class contains all of the logic for determining the next version of a
# Gem to update to based on the requested level (patch, minor, major).
@@ -6,6 +7,8 @@ module Bundler
# available dependency versions as found in its index, before returning it to
# to the resolution engine to select the best version.
class GemVersionPromoter
+ DEBUG = ENV["BUNDLER_DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER"]
+
attr_reader :level, :locked_specs, :unlock_gems
# By default, strict is false, meaning every available version of a gem
@@ -21,6 +24,8 @@ module Bundler
# existing in the referenced source.
attr_accessor :strict
+ attr_accessor :prerelease_specified
+
# Given a list of locked_specs and a list of gems to unlock creates a
# GemVersionPromoter instance.
#
@@ -36,6 +41,7 @@ module Bundler
@locked_specs = locked_specs
@unlock_gems = unlock_gems
@sort_versions = {}
+ @prerelease_specified = {}
end
# @param value [Symbol] One of three Symbols: :major, :minor or :patch.
@@ -60,7 +66,7 @@ module Bundler
# @return [SpecGroup] A new instance of the SpecGroup Array sorted and
# possibly filtered.
def sort_versions(dep, spec_groups)
- before_result = "before sort_versions: #{debug_format_result(dep, spec_groups).inspect}" if ENV["DEBUG_RESOLVER"]
+ before_result = "before sort_versions: #{debug_format_result(dep, spec_groups).inspect}" if DEBUG
@sort_versions[dep] ||= begin
gem_name = dep.name
@@ -74,9 +80,9 @@ module Bundler
else
sort_dep_specs(spec_groups, locked_spec)
end.tap do |specs|
- if ENV["DEBUG_RESOLVER"]
- STDERR.puts before_result
- STDERR.puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
+ if DEBUG
+ puts before_result
+ puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
end
end
end
@@ -92,7 +98,7 @@ module Bundler
level == :minor
end
- private
+ private
def filter_dep_specs(spec_groups, locked_spec)
res = spec_groups.select do |spec_group|
@@ -103,7 +109,7 @@ module Bundler
must_match = minor? ? [0] : [0, 1]
matches = must_match.map {|idx| gsv.segments[idx] == lsv.segments[idx] }
- (matches.uniq == [true]) ? (gsv >= lsv) : false
+ matches.uniq == [true] ? (gsv >= lsv) : false
else
true
end
@@ -120,6 +126,15 @@ module Bundler
result = spec_groups.sort do |a, b|
@a_ver = a.version
@b_ver = b.version
+
+ unless @prerelease_specified[@gem_name]
+ a_pre = @a_ver.prerelease?
+ b_pre = @b_ver.prerelease?
+
+ next -1 if a_pre && !b_pre
+ next 1 if b_pre && !a_pre
+ end
+
if major?
@a_ver <=> @b_ver
elsif either_version_older_than_locked
diff --git a/lib/bundler/gemdeps.rb b/lib/bundler/gemdeps.rb
index 8595b8c7ea..cd4b25d0e6 100644
--- a/lib/bundler/gemdeps.rb
+++ b/lib/bundler/gemdeps.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class Gemdeps
def initialize(runtime)
diff --git a/lib/bundler/graph.rb b/lib/bundler/graph.rb
index e145590430..8f52e2f0f0 100644
--- a/lib/bundler/graph.rb
+++ b/lib/bundler/graph.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "set"
module Bundler
class Graph
@@ -26,7 +27,7 @@ module Bundler
GraphVizClient.new(self).run
end
- private
+ private
def _populate_relations
parent_dependencies = _groups.values.to_set.flatten
@@ -116,7 +117,7 @@ module Bundler
:style => "filled",
:fillcolor => "#B9B9D5",
:shape => "box3d",
- :fontsize => 16
+ :fontsize => 16,
}.merge(@node_options[group])
)
end
@@ -141,7 +142,7 @@ module Bundler
g.output @output_format.to_sym => "#{@output_file}.#{@output_format}"
Bundler.ui.info "#{@output_file}.#{@output_format}"
rescue ArgumentError => e
- $stderr.puts "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
+ warn "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
raise e
end
end
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index 5f54796fa2..8930fca6d0 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "set"
module Bundler
class Index
@@ -64,11 +63,14 @@ module Bundler
def unsorted_search(query, base)
results = local_search(query, base)
- seen = results.map(&:full_name).to_set unless @sources.empty?
+ seen = results.map(&:full_name).uniq unless @sources.empty?
@sources.each do |source|
source.unsorted_search(query, base).each do |spec|
- results << spec if seen.add?(spec.full_name)
+ next if seen.include?(spec.full_name)
+
+ seen << spec.full_name
+ results << spec
end
end
@@ -111,12 +113,18 @@ module Bundler
spec_sets.values.each(&blk)
end
sources.each {|s| s.each(&blk) }
+ self
+ end
+
+ def spec_names
+ names = specs.keys + sources.map(&:spec_names)
+ names.uniq!
+ names
end
- # returns a list of the dependencies
def unmet_dependency_names
dependency_names.select do |name|
- name != "bundler" && search(name).empty?
+ search(name).empty?
end
end
@@ -162,7 +170,7 @@ module Bundler
def dependencies_eql?(spec, other_spec)
deps = spec.dependencies.select {|d| d.type != :development }
other_deps = other_spec.dependencies.select {|d| d.type != :development }
- Set.new(deps) == Set.new(other_deps)
+ deps.sort == other_deps.sort
end
def add_source(index)
@@ -171,7 +179,7 @@ module Bundler
@sources.uniq! # need to use uniq! here instead of checking for the item before adding
end
- private
+ private
def specs_by_name(name)
@specs[name].values
@@ -187,18 +195,10 @@ module Bundler
if base # allow all platforms when searching from a lockfile
dependency.matches_spec?(spec)
else
- dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
+ dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
end
end
- wants_prerelease = dependency.requirement.prerelease?
- wants_prerelease ||= base && base.any? {|base_spec| base_spec.version.prerelease? }
- only_prerelease = specs.all? {|spec| spec.version.prerelease? }
-
- unless wants_prerelease || only_prerelease
- found.reject! {|spec| spec.version.prerelease? }
- end
-
found
end
end
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
index cba1b3d5e5..613bda4f84 100644
--- a/lib/bundler/injector.rb
+++ b/lib/bundler/injector.rb
@@ -1,52 +1,80 @@
# frozen_string_literal: true
+
module Bundler
class Injector
+ INJECTED_GEMS = "injected gems".freeze
+
def self.inject(new_deps, options = {})
injector = new(new_deps, options)
injector.inject(Bundler.default_gemfile, Bundler.default_lockfile)
end
- def initialize(new_deps, options = {})
- @new_deps = new_deps
+ def self.remove(gems, options = {})
+ injector = new(gems, options)
+ injector.remove(Bundler.default_gemfile, Bundler.default_lockfile)
+ end
+
+ def initialize(deps, options = {})
+ @deps = deps
@options = options
end
+ # @param [Pathname] gemfile_path The Gemfile in which to inject the new dependency.
+ # @param [Pathname] lockfile_path The lockfile in which to inject the new dependency.
+ # @return [Array]
def inject(gemfile_path, lockfile_path)
- if Bundler.settings[:frozen]
+ if Bundler.frozen_bundle?
# ensure the lock and Gemfile are synced
Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true)
- # temporarily remove frozen while we inject
- frozen = Bundler.settings.delete(:frozen)
end
- # evaluate the Gemfile we have now
- builder = Dsl.new
- builder.eval_gemfile(gemfile_path)
+ # temporarily unfreeze
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
+ # evaluate the Gemfile we have now
+ builder = Dsl.new
+ builder.eval_gemfile(gemfile_path)
+
+ # don't inject any gems that are already in the Gemfile
+ @deps -= builder.dependencies
+
+ # add new deps to the end of the in-memory Gemfile
+ # Set conservative versioning to false because
+ # we want to let the resolver resolve the version first
+ builder.eval_gemfile(INJECTED_GEMS, build_gem_lines(false)) if @deps.any?
+
+ # resolve to see if the new deps broke anything
+ @definition = builder.to_definition(lockfile_path, {})
+ @definition.resolve_remotely!
- # don't inject any gems that are already in the Gemfile
- @new_deps -= builder.dependencies
+ # since nothing broke, we can add those gems to the gemfile
+ append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @deps.any?
- # add new deps to the end of the in-memory Gemfile
- # Set conservative versioining to false because we want to let the resolver resolve the version first
- builder.eval_gemfile("injected gems", build_gem_lines(false)) if @new_deps.any?
+ # since we resolved successfully, write out the lockfile
+ @definition.lock(Bundler.default_lockfile)
- # resolve to see if the new deps broke anything
- @definition = builder.to_definition(lockfile_path, {})
- @definition.resolve_remotely!
+ # invalidate the cached Bundler.definition
+ Bundler.reset_paths!
- # since nothing broke, we can add those gems to the gemfile
- append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @new_deps.any?
+ # return an array of the deps that we added
+ @deps
+ end
+ end
+
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
+ # @param [Pathname] lockfile_path The lockfile from which to remove dependencies.
+ # @return [Array]
+ def remove(gemfile_path, lockfile_path)
+ # remove gems from each gemfiles we have
+ Bundler.definition.gemfiles.each do |path|
+ deps = remove_deps(path)
- # since we resolved successfully, write out the lockfile
- @definition.lock(Bundler.default_lockfile)
+ show_warning("No gems were removed from the gemfile.") if deps.empty?
- # return an array of the deps that we added
- return @new_deps
- ensure
- Bundler.settings[:frozen] = "1" if frozen
+ deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep, false)} was removed." }
+ end
end
- private
+ private
def conservative_version(spec)
version = spec.version
@@ -55,11 +83,21 @@ module Bundler
seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2
prerelease_suffix = version.to_s.gsub(version.release.to_s, "") if version.prerelease?
- "~> #{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
+ "#{version_prefix}#{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
+ end
+
+ def version_prefix
+ if @options[:strict]
+ "= "
+ elsif @options[:optimistic]
+ ">= "
+ else
+ "~> "
+ end
end
def build_gem_lines(conservative_versioning)
- @new_deps.map do |d|
+ @deps.map do |d|
name = d.name.dump
requirement = if conservative_versioning
@@ -69,23 +107,167 @@ module Bundler
end
if d.groups != Array(:default)
- group = d.groups.size == 1 ? ", :group => #{d.groups.inspect}" : ", :groups => #{d.groups.inspect}"
+ group = d.groups.size == 1 ? ", :group => #{d.groups.first.inspect}" : ", :groups => #{d.groups.inspect}"
end
source = ", :source => \"#{d.source}\"" unless d.source.nil?
+ git = ", :git => \"#{d.git}\"" unless d.git.nil?
+ branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil?
- %(gem #{name}#{requirement}#{group}#{source})
+ %(gem #{name}#{requirement}#{group}#{source}#{git}#{branch})
end.join("\n")
end
def append_to(gemfile_path, new_gem_lines)
gemfile_path.open("a") do |f|
f.puts
- if @options["timestamp"] || @options["timestamp"].nil?
- f.puts "# Added at #{Time.now} by #{`whoami`.chomp}:"
- end
f.puts new_gem_lines
end
end
+
+ # evaluates a gemfile to remove the specified gem
+ # from it.
+ def remove_deps(gemfile_path)
+ initial_gemfile = File.readlines(gemfile_path)
+
+ Bundler.ui.info "Removing gems from #{gemfile_path}"
+
+ # evaluate the Gemfile we have
+ builder = Dsl.new
+ builder.eval_gemfile(gemfile_path)
+
+ removed_deps = remove_gems_from_dependencies(builder, @deps, gemfile_path)
+
+ # abort the operation if no gems were removed
+ # no need to operate on gemfile further
+ return [] if removed_deps.empty?
+
+ cleaned_gemfile = remove_gems_from_gemfile(@deps, gemfile_path)
+
+ SharedHelpers.write_to_gemfile(gemfile_path, cleaned_gemfile)
+
+ # check for errors
+ # including extra gems being removed
+ # or some gems not being removed
+ # and return the actual removed deps
+ cross_check_for_errors(gemfile_path, builder.dependencies, removed_deps, initial_gemfile)
+ end
+
+ # @param [Dsl] builder Dsl object of current Gemfile.
+ # @param [Array] gems Array of names of gems to be removed.
+ # @param [Pathname] gemfile_path Path of the Gemfile.
+ # @return [Array] Array of removed dependencies.
+ def remove_gems_from_dependencies(builder, gems, gemfile_path)
+ removed_deps = []
+
+ gems.each do |gem_name|
+ deleted_dep = builder.dependencies.find {|d| d.name == gem_name }
+
+ if deleted_dep.nil?
+ raise GemfileError, "`#{gem_name}` is not specified in #{gemfile_path} so it could not be removed."
+ end
+
+ builder.dependencies.delete(deleted_dep)
+
+ removed_deps << deleted_dep
+ end
+
+ removed_deps
+ end
+
+ # @param [Array] gems Array of names of gems to be removed.
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
+ def remove_gems_from_gemfile(gems, gemfile_path)
+ patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
+ new_gemfile = []
+ multiline_removal = false
+ File.readlines(gemfile_path).each do |line|
+ match_data = line.match(patterns)
+ if match_data && is_not_within_comment?(line, match_data)
+ multiline_removal = line.rstrip.end_with?(",")
+ # skip lines which match the regex
+ next
+ end
+
+ # skip followup lines until line does not end with ','
+ new_gemfile << line unless multiline_removal
+ multiline_removal = line.rstrip.end_with?(",") if multiline_removal
+ end
+
+ # remove line \n and append them with other strings
+ new_gemfile.each_with_index do |_line, index|
+ if new_gemfile[index + 1] == "\n"
+ new_gemfile[index] += new_gemfile[index + 1]
+ new_gemfile.delete_at(index + 1)
+ end
+ end
+
+ %w[group source env install_if].each {|block| remove_nested_blocks(new_gemfile, block) }
+
+ new_gemfile.join.chomp
+ end
+
+ # @param [String] line Individual line of gemfile content.
+ # @param [MatchData] match_data Data about Regex match.
+ def is_not_within_comment?(line, match_data)
+ match_start_index = match_data.offset(0).first
+ !line[0..match_start_index].include?("#")
+ end
+
+ # @param [Array] gemfile Array of gemfile contents.
+ # @param [String] block_name Name of block name to look for.
+ def remove_nested_blocks(gemfile, block_name)
+ nested_blocks = 0
+
+ # count number of nested blocks
+ gemfile.each_with_index {|line, index| nested_blocks += 1 if !gemfile[index + 1].nil? && gemfile[index + 1].include?(block_name) && line.include?(block_name) }
+
+ while nested_blocks >= 0
+ nested_blocks -= 1
+
+ gemfile.each_with_index do |line, index|
+ next unless !line.nil? && line.strip.start_with?(block_name)
+ if gemfile[index + 1] =~ /^\s*end\s*$/
+ gemfile[index] = nil
+ gemfile[index + 1] = nil
+ end
+ end
+
+ gemfile.compact!
+ end
+ end
+
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
+ # @param [Array] original_deps Array of original dependencies.
+ # @param [Array] removed_deps Array of removed dependencies.
+ # @param [Array] initial_gemfile Contents of original Gemfile before any operation.
+ def cross_check_for_errors(gemfile_path, original_deps, removed_deps, initial_gemfile)
+ # evaluate the new gemfile to look for any failure cases
+ builder = Dsl.new
+ builder.eval_gemfile(gemfile_path)
+
+ # record gems which were removed but not requested
+ extra_removed_gems = original_deps - builder.dependencies
+
+ # if some extra gems were removed then raise error
+ # and revert Gemfile to original
+ unless extra_removed_gems.empty?
+ SharedHelpers.write_to_gemfile(gemfile_path, initial_gemfile.join)
+
+ raise InvalidOption, "Gems could not be removed. #{extra_removed_gems.join(", ")} would also have been removed. Bundler cannot continue."
+ end
+
+ # record gems which could not be removed due to some reasons
+ errored_deps = builder.dependencies.select {|d| d.gemfile == gemfile_path } & removed_deps.select {|d| d.gemfile == gemfile_path }
+
+ show_warning "#{errored_deps.map(&:name).join(", ")} could not be removed." unless errored_deps.empty?
+
+ # return actual removed dependencies
+ removed_deps - errored_deps
+ end
+
+ def show_warning(message)
+ Bundler.ui.info Bundler.ui.add_color(message, :yellow)
+ end
end
end
diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb
index 38dcda6b5b..a718418fce 100644
--- a/lib/bundler/inline.rb
+++ b/lib/bundler/inline.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
# Allows for declaring a Gemfile inline in a ruby script, optionally installing
# any gems that aren't already installed on the user's system.
#
@@ -29,48 +30,56 @@
# puts Pod::VERSION # => "0.34.4"
#
def gemfile(install = false, options = {}, &gemfile)
- require "bundler"
+ require_relative "../bundler"
opts = options.dup
ui = opts.delete(:ui) { Bundler::UI::Shell.new }
+ ui.level = "silent" if opts.delete(:quiet)
raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
- old_root = Bundler.method(:root)
- def Bundler.root
- Bundler::SharedHelpers.pwd.expand_path
- end
- ENV["BUNDLE_GEMFILE"] = "Gemfile"
+ begin
+ old_root = Bundler.method(:root)
+ bundler_module = class << Bundler; self; end
+ bundler_module.send(:remove_method, :root)
+ def Bundler.root
+ Bundler::SharedHelpers.pwd.expand_path
+ end
+ old_gemfile = ENV["BUNDLE_GEMFILE"]
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
- Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
- builder = Bundler::Dsl.new
- builder.instance_eval(&gemfile)
+ Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
+ builder = Bundler::Dsl.new
+ builder.instance_eval(&gemfile)
+ builder.check_primary_source_safety
- definition = builder.to_definition(nil, true)
- def definition.lock(*); end
- definition.validate_runtime!
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
+ definition = builder.to_definition(nil, true)
+ def definition.lock(*); end
+ definition.validate_runtime!
+
+ Bundler.ui = install ? ui : Bundler::UI::Silent.new
+ if install || definition.missing_specs?
+ Bundler.settings.temporary(:inline => true) do
+ installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
+ installer.post_install_messages.each do |name, message|
+ Bundler.ui.info "Post-install message from #{name}:\n#{message}"
+ end
+ end
+ end
- missing_specs = proc do
- begin
- !definition.missing_specs.empty?
- rescue Bundler::GemNotFound, Bundler::GitError
- definition.instance_variable_set(:@index, nil)
- true
+ runtime = Bundler::Runtime.new(nil, definition)
+ runtime.setup.require
+ end
+ ensure
+ if bundler_module
+ bundler_module.send(:remove_method, :root)
+ bundler_module.send(:define_method, :root, old_root)
end
- end
- Bundler.ui = ui if install
- if install || missing_specs.call
- Bundler.settings.temporary(:inline => true) do
- installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
- installer.post_install_messages.each do |name, message|
- Bundler.ui.info "Post-install message from #{name}:\n#{message}"
- end
+ if old_gemfile
+ ENV["BUNDLE_GEMFILE"] = old_gemfile
+ else
+ ENV["BUNDLE_GEMFILE"] = ""
end
end
-
- runtime = Bundler::Runtime.new(nil, definition)
- runtime.setup.require
-ensure
- bundler_module = class << Bundler; self; end
- bundler_module.send(:define_method, :root, old_root) if old_root
end
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index bce0e46393..63e02ba496 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require "erb"
-require "rubygems/dependency_installer"
-require "bundler/worker"
-require "bundler/installer/parallel_installer"
-require "bundler/installer/standalone"
-require "bundler/installer/gem_installer"
+
+require_relative "worker"
+require_relative "installer/parallel_installer"
+require_relative "installer/standalone"
+require_relative "installer/gem_installer"
module Bundler
class Installer
@@ -20,8 +19,9 @@ module Bundler
# For more information see the #run method on this class.
def self.install(root, definition, options = {})
installer = new(root, definition)
- Plugin.hook("before-install-all", definition.dependencies)
+ Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL_ALL, definition.dependencies)
installer.run(options)
+ Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL_ALL, definition.dependencies)
installer
end
@@ -33,25 +33,26 @@ module Bundler
# Runs the install procedures for a specific Gemfile.
#
- # Firstly, this method will check to see if Bundler.bundle_path exists
- # and if not then will create it. This is usually the location of gems
- # on the system, be it RVM or at a system path.
+ # Firstly, this method will check to see if `Bundler.bundle_path` exists
+ # and if not then Bundler will create the directory. This is usually the same
+ # location as RubyGems which typically is the `~/.gem` directory
+ # unless other specified.
#
- # Secondly, it checks if Bundler has been configured to be "frozen"
+ # Secondly, it checks if Bundler has been configured to be "frozen".
# Frozen ensures that the Gemfile and the Gemfile.lock file are matching.
# This stops a situation where a developer may update the Gemfile but may not run
# `bundle install`, which leads to the Gemfile.lock file not being correctly updated.
# If this file is not correctly updated then any other developer running
# `bundle install` will potentially not install the correct gems.
#
- # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile using
- # Bundler::Environment#dependencies. If there are no dependencies specified then
- # Bundler returns a warning message stating so and this method returns.
+ # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile.
+ # If there are no dependencies specified then Bundler returns a warning message stating
+ # so and this method returns.
#
- # Fourthly, Bundler checks if the default lockfile (Gemfile.lock) exists, and if so
- # then proceeds to set up a definition based on the default gemfile (Gemfile) and the
- # default lock file (Gemfile.lock). However, this is not the case if the platform is different
- # to that which is specified in Gemfile.lock, or if there are any missing specs for the gems.
+ # Fourthly, Bundler checks if the Gemfile.lock exists, and if so
+ # then proceeds to set up a definition based on the Gemfile and the Gemfile.lock.
+ # During this step Bundler will also download information about any new gems
+ # that are not in the Gemfile.lock and resolve any dependencies if needed.
#
# Fifthly, Bundler resolves the dependencies either through a cache of gems or by remote.
# This then leads into the gems being installed, along with stubs for their executables,
@@ -61,26 +62,37 @@ module Bundler
# Sixthly, a new Gemfile.lock is created from the installed gems to ensure that the next time
# that a user runs `bundle install` they will receive any updates from this process.
#
- # Finally: TODO add documentation for how the standalone process works.
+ # Finally, if the user has specified the standalone flag, Bundler will generate the needed
+ # require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more
+ # information.
def run(options)
create_bundle_path
- if Bundler.settings[:frozen]
- @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
- end
+ ProcessLock.lock do
+ if Bundler.frozen_bundle?
+ @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
+ end
- if @definition.dependencies.empty?
- Bundler.ui.warn "The Gemfile specifies no dependencies"
- lock
- return
- end
+ if @definition.dependencies.empty?
+ Bundler.ui.warn "The Gemfile specifies no dependencies"
+ lock
+ return
+ end
- resolve_if_need(options)
- ensure_specs_are_compatible!
- install(options)
+ if resolve_if_needed(options)
+ ensure_specs_are_compatible!
+ load_plugins
+ options.delete(:jobs)
+ else
+ options[:jobs] = 1 # to avoid the overhead of Bundler::Worker
+ end
+ install(options)
- lock unless Bundler.settings[:frozen]
- Standalone.new(options[:standalone], @definition).generate if options[:standalone]
+ Gem::Specification.reset # invalidate gem specification cache so that installed gems are immediately available
+
+ lock unless Bundler.frozen_bundle?
+ Standalone.new(options[:standalone], @definition).generate if options[:standalone]
+ end
end
def generate_bundler_executable_stubs(spec, options = {})
@@ -101,23 +113,39 @@ module Bundler
end
# double-assignment to avoid warnings about variables that will be used by ERB
- bin_path = bin_path = Bundler.bin_path
- template = template = File.read(File.expand_path("../templates/Executable", __FILE__))
- relative_gemfile_path = relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
- ruby_command = ruby_command = Thor::Util.ruby_command
+ bin_path = Bundler.bin_path
+ bin_path = bin_path
+ relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
+ relative_gemfile_path = relative_gemfile_path
+ ruby_command = Thor::Util.ruby_command
+ ruby_command = ruby_command
+ template_path = File.expand_path("../templates/Executable", __FILE__)
+ if spec.name == "bundler"
+ template_path += ".bundler"
+ spec.executables = %(bundle)
+ end
+ template = File.read(template_path)
exists = []
spec.executables.each do |executable|
- next if executable == "bundle"
-
binstub_path = "#{bin_path}/#{executable}"
if File.exist?(binstub_path) && !options[:force]
exists << executable
next
end
- File.open(binstub_path, "w", 0o777 & ~File.umask) do |f|
- f.puts ERB.new(template, nil, "-").result(binding)
+ mode = Gem.win_platform? ? "wb:UTF-8" : "w"
+ require "erb"
+ content = if RUBY_VERSION >= "2.6"
+ ERB.new(template, :trim_mode => "-").result(binding)
+ else
+ ERB.new(template, nil, "-").result(binding)
+ end
+
+ File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask)
+ if Gem.win_platform? || options[:all_platforms]
+ prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
+ File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
end
end
@@ -136,36 +164,82 @@ module Bundler
end
end
- def generate_standalone_bundler_executable_stubs(spec)
+ def generate_standalone_bundler_executable_stubs(spec, options = {})
# double-assignment to avoid warnings about variables that will be used by ERB
bin_path = Bundler.bin_path
- standalone_path = standalone_path = Bundler.root.join(Bundler.settings[:path]).relative_path_from(bin_path)
+ unless path = Bundler.settings[:path]
+ raise "Can't standalone without an explicit path set"
+ end
+ standalone_path = Bundler.root.join(path).relative_path_from(bin_path)
+ standalone_path = standalone_path
template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__))
- ruby_command = ruby_command = Thor::Util.ruby_command
+ ruby_command = Thor::Util.ruby_command
+ ruby_command = ruby_command
spec.executables.each do |executable|
next if executable == "bundle"
- executable_path = executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
- File.open "#{bin_path}/#{executable}", "w", 0o755 do |f|
- f.puts ERB.new(template, nil, "-").result(binding)
+ executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
+ executable_path = executable_path
+
+ mode = Gem.win_platform? ? "wb:UTF-8" : "w"
+ require "erb"
+ content = if RUBY_VERSION >= "2.6"
+ ERB.new(template, :trim_mode => "-").result(binding)
+ else
+ ERB.new(template, nil, "-").result(binding)
+ end
+
+ File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755)
+ if Gem.win_platform? || options[:all_platforms]
+ prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
+ File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
end
end
end
- private
+ private
# the order that the resolver provides is significant, since
# dependencies might affect the installation of a gem.
# that said, it's a rare situation (other than rake), and parallel
# installation is SO MUCH FASTER. so we let people opt in.
def install(options)
- Bundler.rubygems.load_plugins
force = options["force"]
- jobs = 1
- jobs = [Bundler.settings[:jobs].to_i - 1, 1].max if can_install_in_parallel?
+ jobs = installation_parallelization(options)
install_in_parallel jobs, options[:standalone], force
end
+ def installation_parallelization(options)
+ if jobs = options.delete(:jobs)
+ return jobs
+ end
+
+ if jobs = Bundler.settings[:jobs]
+ return jobs
+ end
+
+ # Parallelization has some issues on Windows, so it's not yet the default
+ return 1 if Gem.win_platform?
+
+ Bundler.settings.processor_count
+ end
+
+ def load_plugins
+ Bundler.rubygems.load_plugins
+
+ requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
+ path_plugin_files = requested_path_gems.map do |spec|
+ begin
+ Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
+ rescue TypeError
+ error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
+ raise Gem::InvalidSpecificationException, error_message
+ end
+ end.flatten
+ Bundler.rubygems.load_plugin_files(path_plugin_files)
+ Bundler.rubygems.load_env_plugins
+ end
+
def ensure_specs_are_compatible!
system_ruby = Bundler::RubyVersion.system
rubygems_version = Gem::Version.create(Gem::VERSION)
@@ -184,17 +258,6 @@ module Bundler
end
end
- def can_install_in_parallel?
- if Bundler.rubygems.provides?(">= 2.1.0")
- true
- else
- Bundler.ui.warn "Rubygems #{Gem::VERSION} is not threadsafe, so your "\
- "gems will be installed one at a time. Upgrade to Rubygems 2.1.0 " \
- "or higher to enable parallel gem installation."
- false
- end
- end
-
def install_in_parallel(size, standalone, force = false)
spec_installations = ParallelInstaller.call(self, @definition.specs, size, standalone, force)
spec_installations.each do |installation|
@@ -207,23 +270,18 @@ module Bundler
Bundler.mkdir_p(p)
end unless Bundler.bundle_path.exist?
rescue Errno::EEXIST
- raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " \
+ raise PathError, "Could not install to path `#{Bundler.bundle_path}` " \
"because a file already exists at that path. Either remove or rename the file so the directory can be created."
end
- def resolve_if_need(options)
- if !options["update"] && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
- local = Bundler.ui.silence do
- begin
- tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
- true unless tmpdef.new_platform? || tmpdef.missing_dependencies.any?
- rescue BundlerError
- end
- end
+ # returns whether or not a re-resolve was needed
+ def resolve_if_needed(options)
+ if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
+ return false if @definition.nothing_changed? && !@definition.missing_specs?
end
- return if local
options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
+ true
end
def lock(opts = {})
diff --git a/lib/bundler/installer/gem_installer.rb b/lib/bundler/installer/gem_installer.rb
index a4d9bcaa07..1df86ccfbc 100644
--- a/lib/bundler/installer/gem_installer.rb
+++ b/lib/bundler/installer/gem_installer.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class GemInstaller
attr_reader :spec, :standalone, :worker, :force, :installer
@@ -16,39 +17,37 @@ module Bundler
Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
generate_executable_stubs
return true, post_install_message
- rescue Bundler::InstallHookError, Bundler::SecurityError, APIResponseMismatchError
+ rescue Bundler::InstallHookError, Bundler::SecurityError, Bundler::APIResponseMismatchError
raise
rescue Errno::ENOSPC
return false, out_of_space_message
- rescue => e
+ rescue Bundler::BundlerError, Gem::InstallError, Bundler::APIResponseInvalidDependenciesError => e
return false, specific_failure_message(e)
end
- private
+ private
def specific_failure_message(e)
message = "#{e.class}: #{e.message}\n"
- message += " " + e.backtrace.join("\n ") + "\n\n" if Bundler.ui.debug?
+ message += " " + e.backtrace.join("\n ") + "\n\n"
message = message.lines.first + Bundler.ui.add_color(message.lines.drop(1).join, :clear)
message + Bundler.ui.add_color(failure_message, :red)
end
def failure_message
- return install_error_message if spec.source.options["git"]
- "#{install_error_message}\n#{gem_install_message}"
+ install_error_message
end
def install_error_message
"An error occurred while installing #{spec.name} (#{spec.version}), and Bundler cannot continue."
end
- def gem_install_message
- "Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
- end
-
def spec_settings
# Fetch the build settings, if there are any
- Bundler.settings["build.#{spec.name}"]
+ if settings = Bundler.settings["build.#{spec.name}"]
+ require "shellwords"
+ Shellwords.shellsplit(settings)
+ end
end
def install
@@ -65,6 +64,7 @@ module Bundler
end
def generate_executable_stubs
+ return if Bundler.feature_flag.forget_cli_options?
return if Bundler.settings[:inline]
if Bundler.settings[:bin] && standalone
installer.generate_standalone_bundler_executable_stubs(spec)
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index 97c124e015..5b6680e5e1 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -1,14 +1,16 @@
# frozen_string_literal: true
-require "bundler/worker"
-require "bundler/installer/gem_installer"
+
+require_relative "../worker"
+require_relative "gem_installer"
module Bundler
class ParallelInstaller
class SpecInstallation
- attr_accessor :spec, :name, :post_install_message, :state, :error
+ attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error
def initialize(spec)
@spec = spec
@name = spec.name
+ @full_name = spec.full_name
@state = :none
@post_install_message = ""
@error = nil
@@ -26,13 +28,8 @@ module Bundler
state == :failed
end
- def installation_attempted?
- installed? || failed?
- end
-
- # Only true when spec in neither installed nor already enqueued
def ready_to_enqueue?
- !enqueued? && !installation_attempted?
+ state == :none
end
def has_post_install_message?
@@ -53,14 +50,11 @@ module Bundler
# Represents only the non-development dependencies, the ones that are
# itself and are in the total list.
def dependencies
- @dependencies ||= begin
- all_dependencies.reject {|dep| ignorable_dependency? dep }
- end
+ @dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
end
def missing_lockfile_dependencies(all_spec_names)
- deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
- deps.reject {|dep| all_spec_names.include? dep.name }
+ dependencies.reject {|dep| all_spec_names.include? dep.name }
end
# Represents all dependencies
@@ -69,7 +63,7 @@ module Bundler
end
def to_s
- "#<#{self.class} #{@spec.full_name} (#{state})>"
+ "#<#{self.class} #{full_name} (#{state})>"
end
end
@@ -77,11 +71,6 @@ module Bundler
new(*args).call
end
- # Returns max number of threads machine can handle with a min of 1
- def self.max_threads
- [Bundler.settings[:jobs].to_i - 1, 1].max
- end
-
attr_reader :size
def initialize(installer, all_specs, size, standalone, force)
@@ -91,55 +80,52 @@ module Bundler
@force = force
@specs = all_specs.map {|s| SpecInstallation.new(s) }
@spec_set = all_specs
+ @rake = @specs.find {|s| s.name == "rake" }
end
def call
- # Since `autoload` has the potential for threading issues on 1.8.7
- # TODO: remove in bundler 2.0
- require "bundler/gem_remote_fetcher" if RUBY_VERSION < "1.9"
-
check_for_corrupt_lockfile
- enqueue_specs
- process_specs until @specs.all?(&:installed?) || @specs.any?(&:failed?)
- handle_error if @specs.any?(&:failed?)
+
+ if @rake
+ do_install(@rake, 0)
+ Gem::Specification.reset
+ end
+
+ if @size > 1
+ install_with_worker
+ else
+ install_serially
+ end
+
+ check_for_unmet_dependencies
+
+ handle_error if failed_specs.any?
@specs
ensure
worker_pool && worker_pool.stop
end
- def worker_pool
- @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
- gem_installer = Bundler::GemInstaller.new(
- spec_install.spec, @installer, @standalone, worker_num, @force
- )
- success, message = gem_installer.install_from_spec
- if success && !message.nil?
- spec_install.post_install_message = message
- elsif !success
- spec_install.state = :failed
- spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
- end
- spec_install
- }
- end
+ def check_for_unmet_dependencies
+ unmet_dependencies = @specs.map do |s|
+ [
+ s,
+ s.dependencies.reject {|dep| @specs.any? {|spec| dep.matches_spec?(spec.spec) } },
+ ]
+ end.reject {|a| a.last.empty? }
+ return if unmet_dependencies.empty?
- # Dequeue a spec and save its post-install message and then enqueue the
- # remaining specs.
- # Some specs might've had to wait til this spec was installed to be
- # processed so the call to `enqueue_specs` is important after every
- # dequeue.
- def process_specs
- spec = worker_pool.deq
- spec.state = :installed unless spec.failed?
- enqueue_specs
- end
+ warning = []
+ warning << "Your lockfile doesn't include a valid resolution."
+ warning << "You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies."
+ warning << "The unmet dependencies are:"
- def handle_error
- errors = @specs.select(&:failed?).map(&:error)
- if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
- raise exception
+ unmet_dependencies.each do |spec, unmet_spec_dependencies|
+ unmet_spec_dependencies.each do |unmet_spec_dependency|
+ warning << "* #{unmet_spec_dependency}, depended upon #{spec.full_name}, unsatisfied by #{@specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }.full_name}"
+ end
end
- raise Bundler::InstallError, errors.map(&:to_s).join("\n\n")
+
+ Bundler.ui.warn(warning.join("\n"))
end
def check_for_corrupt_lockfile
@@ -148,7 +134,7 @@ module Bundler
s,
s.missing_lockfile_dependencies(@specs.map(&:name)),
]
- end.reject { |a| a.last.empty? }
+ end.reject {|a| a.last.empty? }
return if missing_dependencies.empty?
warning = []
@@ -167,6 +153,73 @@ module Bundler
Bundler.ui.warn(warning.join("\n"))
end
+ private
+
+ def failed_specs
+ @specs.select(&:failed?)
+ end
+
+ def install_with_worker
+ enqueue_specs
+ process_specs until finished_installing?
+ end
+
+ def install_serially
+ until finished_installing?
+ raise "failed to find a spec to enqueue while installing serially" unless spec_install = @specs.find(&:ready_to_enqueue?)
+ spec_install.state = :enqueued
+ do_install(spec_install, 0)
+ end
+ end
+
+ def worker_pool
+ @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda {|spec_install, worker_num|
+ do_install(spec_install, worker_num)
+ }
+ end
+
+ def do_install(spec_install, worker_num)
+ Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL, spec_install)
+ gem_installer = Bundler::GemInstaller.new(
+ spec_install.spec, @installer, @standalone, worker_num, @force
+ )
+ success, message = gem_installer.install_from_spec
+ if success
+ spec_install.state = :installed
+ spec_install.post_install_message = message unless message.nil?
+ else
+ spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
+ spec_install.state = :failed
+ end
+ Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL, spec_install)
+ spec_install
+ end
+
+ # Dequeue a spec and save its post-install message and then enqueue the
+ # remaining specs.
+ # Some specs might've had to wait til this spec was installed to be
+ # processed so the call to `enqueue_specs` is important after every
+ # dequeue.
+ def process_specs
+ worker_pool.deq
+ enqueue_specs
+ end
+
+ def finished_installing?
+ @specs.all? do |spec|
+ return true if spec.failed?
+ spec.installed?
+ end
+ end
+
+ def handle_error
+ errors = failed_specs.map(&:error)
+ if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
+ raise exception
+ end
+ raise Bundler::InstallError, errors.join("\n\n")
+ end
+
def require_tree_for_spec(spec)
tree = @spec_set.what_required(spec)
t = String.new("In #{File.basename(SharedHelpers.default_gemfile)}:\n")
diff --git a/lib/bundler/installer/standalone.rb b/lib/bundler/installer/standalone.rb
index 03411d85e2..e8494b4bcd 100644
--- a/lib/bundler/installer/standalone.rb
+++ b/lib/bundler/installer/standalone.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: true
+
module Bundler
class Standalone
def initialize(groups, definition)
- @specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
+ @specs = definition.specs_for(groups)
end
def generate
@@ -11,30 +12,31 @@ module Bundler
end
File.open File.join(bundler_path, "setup.rb"), "w" do |file|
file.puts "require 'rbconfig'"
- file.puts "# ruby 1.8.7 doesn't define RUBY_ENGINE"
- file.puts "ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'"
- file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
- file.puts "path = File.expand_path('..', __FILE__)"
+ file.puts reverse_rubygems_kernel_mixin
paths.each do |path|
- file.puts %($:.unshift "\#{path}/#{path}")
+ if Pathname.new(path).absolute?
+ file.puts %($:.unshift "#{path}")
+ else
+ file.puts %($:.unshift File.expand_path("\#{__dir__}/#{path}"))
+ end
end
end
end
- private
+ private
def paths
@specs.map do |spec|
next if spec.name == "bundler"
Array(spec.require_paths).map do |path|
- gem_path(path, spec).sub(version_dir, '#{ruby_engine}/#{ruby_version}')
+ gem_path(path, spec).sub(version_dir, '#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}')
# This is a static string intentionally. It's interpolated at a later time.
end
- end.flatten
+ end.flatten.compact
end
def version_dir
- "#{Bundler::RubyVersion.system.engine}/#{RbConfig::CONFIG["ruby_version"]}"
+ "#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}"
end
def bundler_path
@@ -43,10 +45,28 @@ module Bundler
def gem_path(path, spec)
full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
- Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
+ if spec.source.instance_of?(Source::Path)
+ full_path
+ else
+ Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
+ end
rescue TypeError
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
raise Gem::InvalidSpecificationException.new(error_message)
end
+
+ def reverse_rubygems_kernel_mixin
+ <<~END
+ kernel = (class << ::Kernel; self; end)
+ [kernel, ::Kernel].each do |k|
+ if k.private_method_defined?(:gem_original_require)
+ private_require = k.private_method_defined?(:require)
+ k.send(:remove_method, :require)
+ k.send(:define_method, :require, k.instance_method(:gem_original_require))
+ k.send(:private, :require) if private_require
+ end
+ end
+ END
+ end
end
end
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index 8d9a02c2b8..4eb228f314 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -1,25 +1,9 @@
# frozen_string_literal: true
-require "uri"
-require "bundler/match_platform"
+
+require_relative "match_platform"
module Bundler
class LazySpecification
- Identifier = Struct.new(:name, :version, :source, :platform, :dependencies)
- class Identifier
- include Comparable
- def <=>(other)
- return unless other.is_a?(Identifier)
- [name, version, platform_string] <=> [other.name, other.version, other.platform_string]
- end
-
- protected
-
- def platform_string
- platform_string = platform.to_s
- platform_string == Index::RUBY ? Index::NULL : platform_string
- end
- end
-
include MatchPlatform
attr_reader :name, :version, :dependencies, :platform
@@ -46,8 +30,32 @@ module Bundler
identifier == other.identifier
end
+ def eql?(other)
+ identifier.eql?(other.identifier)
+ end
+
+ def hash
+ identifier.hash
+ end
+
+ ##
+ # Does this locked specification satisfy +dependency+?
+ #
+ # NOTE: Rubygems default requirement is ">= 0", which doesn't match
+ # prereleases of 0 versions, like "0.0.0.dev" or "0.0.0.SNAPSHOT". However,
+ # bundler users expect those to work. We need to make sure that Gemfile
+ # dependencies without explicit requirements (which use ">= 0" under the
+ # hood by default) are still valid for locked specs using this kind of
+ # versions. The method implements an ad-hoc fix for that. A better solution
+ # might be to change default rubygems requirement of dependencies to be ">=
+ # 0.A" but that's a major refactoring likely to break things. Hopefully we
+ # can attempt it in the future.
+ #
+
def satisfies?(dependency)
- @name == dependency.name && dependency.requirement.satisfied_by?(Gem::Version.new(@version))
+ effective_requirement = dependency.requirement == Gem::Requirement.default ? Gem::Requirement.new(">= 0.A") : dependency.requirement
+
+ @name == dependency.name && effective_requirement.satisfied_by?(Gem::Version.new(@version))
end
def to_lock
@@ -68,18 +76,26 @@ module Bundler
end
def __materialize__
- search_object = Bundler.settings[:specific_platform] || Bundler.settings[:force_ruby_platform] ? self : Dependency.new(name, version)
@specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name
source.gemspec.tap {|s| s.source = source }
else
- search = source.specs.search(search_object).last
- if search && Gem::Platform.new(search.platform) != Gem::Platform.new(platform) && !search.runtime_dependencies.-(dependencies.reject {|d| d.type == :development }).empty?
- Bundler.ui.warn "Unable to use the platform-specific (#{search.platform}) version of #{name} (#{version}) " \
- "because it has different dependencies from the #{platform} version. " \
- "To use the platform-specific version of the gem, run `bundle config specific_platform true` and install again."
- search = source.specs.search(self).last
+ search_object = if source.is_a?(Source::Path)
+ Dependency.new(name, version)
+ else
+ ruby_platform_materializes_to_ruby_platform? ? self : Dependency.new(name, version)
end
- search.dependencies = dependencies if search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)
+ platform_object = Gem::Platform.new(platform)
+ candidates = source.specs.search(search_object)
+ same_platform_candidates = candidates.select do |spec|
+ MatchPlatform.platforms_match?(spec.platform, platform_object)
+ end
+ installable_candidates = same_platform_candidates.select do |spec|
+ !spec.is_a?(EndpointSpecification) ||
+ (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
+ spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version))
+ end
+ search = installable_candidates.last || same_platform_candidates.last
+ search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
search
end
end
@@ -97,7 +113,7 @@ module Bundler
end
def identifier
- @__identifier ||= Identifier.new(name, version, source, platform, dependencies)
+ @__identifier ||= [name, version, platform_string]
end
def git_version
@@ -105,7 +121,14 @@ module Bundler
" #{source.revision[0..6]}"
end
- private
+ protected
+
+ def platform_string
+ platform_string = platform.to_s
+ platform_string == Index::RUBY ? Index::NULL : platform_string
+ end
+
+ private
def to_ary
nil
@@ -118,5 +141,18 @@ module Bundler
@specification.send(method, *args, &blk)
end
+
+ #
+ # For backwards compatibility with existing lockfiles, if the most specific
+ # locked platform is RUBY, we keep the previous behaviour of resolving the
+ # best platform variant at materiliazation time. For previous bundler
+ # versions (before 2.2.0) this was always the case (except when the lockfile
+ # only included non-ruby platforms), but we're also keeping this behaviour
+ # on newer bundlers unless users generate the lockfile from scratch or
+ # explicitly add a more specific platform.
+ #
+ def ruby_platform_materializes_to_ruby_platform?
+ !Bundler.most_specific_locked_platform?(Gem::Platform::RUBY) || Bundler.settings[:force_ruby_platform]
+ end
end
end
diff --git a/lib/bundler/lockfile_generator.rb b/lib/bundler/lockfile_generator.rb
new file mode 100644
index 0000000000..3bc6bd7339
--- /dev/null
+++ b/lib/bundler/lockfile_generator.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+module Bundler
+ class LockfileGenerator
+ attr_reader :definition
+ attr_reader :out
+
+ # @private
+ def initialize(definition)
+ @definition = definition
+ @out = String.new
+ end
+
+ def self.generate(definition)
+ new(definition).generate!
+ end
+
+ def generate!
+ add_sources
+ add_platforms
+ add_dependencies
+ add_locked_ruby_version
+ add_bundled_with
+
+ out
+ end
+
+ private
+
+ def add_sources
+ definition.send(:sources).lock_sources.each_with_index do |source, idx|
+ out << "\n" unless idx.zero?
+
+ # Add the source header
+ out << source.to_lock
+
+ # Find all specs for this source
+ specs = definition.resolve.select {|s| source.can_lock?(s) }
+ add_specs(specs)
+ end
+ end
+
+ def add_specs(specs)
+ # This needs to be sorted by full name so that
+ # gems with the same name, but different platform
+ # are ordered consistently
+ specs.sort_by(&:full_name).each do |spec|
+ next if spec.name == "bundler".freeze
+ out << spec.to_lock
+ end
+ end
+
+ def add_platforms
+ add_section("PLATFORMS", definition.platforms)
+ end
+
+ def add_dependencies
+ out << "\nDEPENDENCIES\n"
+
+ handled = []
+ definition.dependencies.sort_by(&:to_s).each do |dep|
+ next if handled.include?(dep.name)
+ out << dep.to_lock
+ handled << dep.name
+ end
+ end
+
+ def add_locked_ruby_version
+ return unless locked_ruby_version = definition.locked_ruby_version
+ add_section("RUBY VERSION", locked_ruby_version.to_s)
+ end
+
+ def add_bundled_with
+ add_section("BUNDLED WITH", definition.locked_bundler_version.to_s)
+ end
+
+ def add_section(name, value)
+ out << "\n#{name}\n"
+ case value
+ when Array
+ value.map(&:to_s).sort.each do |val|
+ out << " #{val}\n"
+ end
+ when Hash
+ value.to_a.sort_by {|k, _| k.to_s }.each do |key, val|
+ out << " #{key}: #{val}\n"
+ end
+ when String
+ out << " #{value}\n"
+ else
+ raise ArgumentError, "#{value.inspect} can't be serialized in a lockfile"
+ end
+ end
+ end
+end
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index dbf8926690..6ff4910a36 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -1,15 +1,5 @@
# frozen_string_literal: true
-# Some versions of the Bundler 1.1 RC series introduced corrupted
-# lockfiles. There were two major problems:
-#
-# * multiple copies of the same GIT section appeared in the lockfile
-# * when this happened, those sections got multiple copies of gems
-# in those sections.
-#
-# As a result, Bundler 1.1 contains code that fixes the earlier
-# corruption. We will remove this fix-up code in Bundler 1.2.
-
module Bundler
class LockfileParser
attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
@@ -23,16 +13,14 @@ module Bundler
PATH = "PATH".freeze
PLUGIN = "PLUGIN SOURCE".freeze
SPECS = " specs:".freeze
- OPTIONS = /^ ([a-z]+): (.*)$/i
+ OPTIONS = /^ ([a-z]+): (.*)$/i.freeze
SOURCE = [GIT, GEM, PATH, PLUGIN].freeze
SECTIONS_BY_VERSION_INTRODUCED = {
- # The strings have to be dup'ed for old RG on Ruby 2.3+
- # TODO: remove dup in Bundler 2.0
- Gem::Version.create("1.0".dup) => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
- Gem::Version.create("1.10".dup) => [BUNDLED].freeze,
- Gem::Version.create("1.12".dup) => [RUBY].freeze,
- Gem::Version.create("1.13".dup) => [PLUGIN].freeze,
+ Gem::Version.create("1.0") => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
+ Gem::Version.create("1.10") => [BUNDLED].freeze,
+ Gem::Version.create("1.12") => [RUBY].freeze,
+ Gem::Version.create("1.13") => [PLUGIN].freeze,
}.freeze
KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze
@@ -65,8 +53,6 @@ module Bundler
@state = nil
@specs = {}
- @rubygems_aggregate = Source::Rubygems.new
-
if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \
"Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock."
@@ -90,7 +76,6 @@ module Bundler
send("parse_#{@state}", line)
end
end
- @sources << @rubygems_aggregate
@specs = @specs.values.sort_by(&:identifier)
warn_for_outdated_bundler_version
rescue ArgumentError => e
@@ -101,22 +86,17 @@ module Bundler
def warn_for_outdated_bundler_version
return unless bundler_version
+ return if bundler_version.segments.last == "dev"
prerelease_text = bundler_version.prerelease? ? " --pre" : ""
current_version = Gem::Version.create(Bundler::VERSION)
- case current_version.segments.first <=> bundler_version.segments.first
- when -1
- raise LockfileError, "You must use Bundler #{bundler_version.segments.first} or greater with this lockfile."
- when 0
- if current_version < bundler_version
- Bundler.ui.warn "Warning: the running version of Bundler (#{current_version}) is older " \
- "than the version that created the lockfile (#{bundler_version}). We suggest you " \
- "upgrade to the latest version of Bundler by running `gem " \
- "install bundler#{prerelease_text}`.\n"
- end
- end
+ return unless current_version < bundler_version
+ Bundler.ui.warn "Warning: the running version of Bundler (#{current_version}) is older " \
+ "than the version that created the lockfile (#{bundler_version}). We suggest you to " \
+ "upgrade to the version that created the lockfile by running `gem install " \
+ "bundler:#{bundler_version}#{prerelease_text}`.\n"
end
- private
+ private
TYPES = {
GIT => Bundler::Source::Git,
@@ -134,17 +114,11 @@ module Bundler
@sources << @current_source
when GIT
@current_source = TYPES[@type].from_lock(@opts)
- # Strip out duplicate GIT sections
- if @sources.include?(@current_source)
- @current_source = @sources.find {|s| s == @current_source }
- else
- @sources << @current_source
- end
+ @sources << @current_source
when GEM
- Array(@opts["remote"]).each do |url|
- @rubygems_aggregate.add_remote(url)
- end
- @current_source = @rubygems_aggregate
+ @opts["remotes"] = Array(@opts.delete("remote")).reverse
+ @current_source = TYPES[@type].from_lock(@opts)
+ @sources << @current_source
when PLUGIN
@current_source = Plugin.source_from_lock(@opts)
@sources << @current_source
@@ -179,7 +153,7 @@ module Bundler
(?:-(.*))?\))? # Optional platform
(!)? # Optional pinned marker
$ # Line end
- /xo
+ /xo.freeze
def parse_dependency(line)
return unless line =~ NAME_VERSION
@@ -222,10 +196,9 @@ module Bundler
platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
@current_spec = LazySpecification.new(name, version, platform)
@current_spec.source = @current_source
+ @current_source.add_dependency_names(name)
- # Avoid introducing multiple copies of the same spec (caused by
- # duplicate GIT sections)
- @specs[@current_spec.identifier] ||= @current_spec
+ @specs[@current_spec.identifier] = @current_spec
elsif spaces.size == 6
version = version.split(",").map(&:strip) if version
dep = Gem::Dependency.new(name, version)
diff --git a/lib/bundler/ssl_certs/.document b/lib/bundler/man/.document
index fb66f13c33..fb66f13c33 100644
--- a/lib/bundler/ssl_certs/.document
+++ b/lib/bundler/man/.document
diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1
new file mode 100644
index 0000000000..a94467e25f
--- /dev/null
+++ b/lib/bundler/man/bundle-add.1
@@ -0,0 +1,66 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-ADD" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
+.
+.SH "SYNOPSIS"
+\fBbundle add\fR \fIGEM_NAME\fR [\-\-group=GROUP] [\-\-version=VERSION] [\-\-source=SOURCE] [\-\-git=GIT] [\-\-branch=BRANCH] [\-\-skip\-install] [\-\-strict] [\-\-optimistic]
+.
+.SH "DESCRIPTION"
+Adds the named gem to the Gemfile and run \fBbundle install\fR\. \fBbundle install\fR can be avoided by using the flag \fB\-\-skip\-install\fR\.
+.
+.P
+Example:
+.
+.P
+bundle add rails
+.
+.P
+bundle add rails \-\-version "< 3\.0, > 1\.1"
+.
+.P
+bundle add rails \-\-version "~> 5\.0\.0" \-\-source "https://gems\.example\.com" \-\-group "development"
+.
+.P
+bundle add rails \-\-skip\-install
+.
+.P
+bundle add rails \-\-group "development, test"
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-version\fR, \fB\-v\fR
+Specify version requirements(s) for the added gem\.
+.
+.TP
+\fB\-\-group\fR, \fB\-g\fR
+Specify the group(s) for the added gem\. Multiple groups should be separated by commas\.
+.
+.TP
+\fB\-\-source\fR, , \fB\-s\fR
+Specify the source for the added gem\.
+.
+.TP
+\fB\-\-git\fR
+Specify the git source for the added gem\.
+.
+.TP
+\fB\-\-branch\fR
+Specify the git branch for the added gem\.
+.
+.TP
+\fB\-\-skip\-install\fR
+Adds the gem to the Gemfile but does not install it\.
+.
+.TP
+\fB\-\-optimistic\fR
+Adds optimistic declaration of version
+.
+.TP
+\fB\-\-strict\fR
+Adds strict declaration of version
+
diff --git a/lib/bundler/man/bundle-add.1.ronn b/lib/bundler/man/bundle-add.1.ronn
new file mode 100644
index 0000000000..26cbe55647
--- /dev/null
+++ b/lib/bundler/man/bundle-add.1.ronn
@@ -0,0 +1,46 @@
+bundle-add(1) -- Add gem to the Gemfile and run bundle install
+================================================================
+
+## SYNOPSIS
+
+`bundle add` <GEM_NAME> [--group=GROUP] [--version=VERSION] [--source=SOURCE] [--git=GIT] [--branch=BRANCH] [--skip-install] [--strict] [--optimistic]
+
+## DESCRIPTION
+Adds the named gem to the Gemfile and run `bundle install`. `bundle install` can be avoided by using the flag `--skip-install`.
+
+Example:
+
+bundle add rails
+
+bundle add rails --version "< 3.0, > 1.1"
+
+bundle add rails --version "~> 5.0.0" --source "https://gems.example.com" --group "development"
+
+bundle add rails --skip-install
+
+bundle add rails --group "development, test"
+
+## OPTIONS
+* `--version`, `-v`:
+ Specify version requirements(s) for the added gem.
+
+* `--group`, `-g`:
+ Specify the group(s) for the added gem. Multiple groups should be separated by commas.
+
+* `--source`, , `-s`:
+ Specify the source for the added gem.
+
+* `--git`:
+ Specify the git source for the added gem.
+
+* `--branch`:
+ Specify the git branch for the added gem.
+
+* `--skip-install`:
+ Adds the gem to the Gemfile but does not install it.
+
+* `--optimistic`:
+ Adds optimistic declaration of version
+
+* `--strict`:
+ Adds strict declaration of version
diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1
new file mode 100644
index 0000000000..6d1b1d4247
--- /dev/null
+++ b/lib/bundler/man/bundle-binstubs.1
@@ -0,0 +1,42 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-BINSTUBS" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
+.
+.SH "SYNOPSIS"
+\fBbundle binstubs\fR \fIGEM_NAME\fR [\-\-force] [\-\-path PATH] [\-\-standalone]
+.
+.SH "DESCRIPTION"
+Binstubs are scripts that wrap around executables\. Bundler creates a small Ruby file (a binstub) that loads Bundler, runs the command, and puts it into \fBbin/\fR\. Binstubs are a shortcut\-or alternative\- to always using \fBbundle exec\fR\. This gives you a file that can be run directly, and one that will always run the correct gem version used by the application\.
+.
+.P
+For example, if you run \fBbundle binstubs rspec\-core\fR, Bundler will create the file \fBbin/rspec\fR\. That file will contain enough code to load Bundler, tell it to load the bundled gems, and then run rspec\.
+.
+.P
+This command generates binstubs for executables in \fBGEM_NAME\fR\. Binstubs are put into \fBbin\fR, or the \fB\-\-path\fR directory if one has been set\. Calling binstubs with [GEM [GEM]] will create binstubs for all given gems\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-force\fR
+Overwrite existing binstubs if they exist\.
+.
+.TP
+\fB\-\-path\fR
+The location to install the specified binstubs to\. This defaults to \fBbin\fR\.
+.
+.TP
+\fB\-\-standalone\fR
+Makes binstubs that can work without depending on Rubygems or Bundler at runtime\.
+.
+.TP
+\fB\-\-shebang\fR
+Specify a different shebang executable name than the default (default \'ruby\')
+.
+.TP
+\fB\-\-all\fR
+Create binstubs for all gems in the bundle\.
+
diff --git a/lib/bundler/man/bundle-binstubs.1.ronn b/lib/bundler/man/bundle-binstubs.1.ronn
new file mode 100644
index 0000000000..a96186929f
--- /dev/null
+++ b/lib/bundler/man/bundle-binstubs.1.ronn
@@ -0,0 +1,41 @@
+bundle-binstubs(1) -- Install the binstubs of the listed gems
+=============================================================
+
+## SYNOPSIS
+
+`bundle binstubs` <GEM_NAME> [--force] [--path PATH] [--standalone]
+
+## DESCRIPTION
+
+Binstubs are scripts that wrap around executables. Bundler creates a
+small Ruby file (a binstub) that loads Bundler, runs the command,
+and puts it into `bin/`. Binstubs are a shortcut-or alternative-
+to always using `bundle exec`. This gives you a file that can be run
+directly, and one that will always run the correct gem version
+used by the application.
+
+For example, if you run `bundle binstubs rspec-core`, Bundler will create
+the file `bin/rspec`. That file will contain enough code to load Bundler,
+tell it to load the bundled gems, and then run rspec.
+
+This command generates binstubs for executables in `GEM_NAME`.
+Binstubs are put into `bin`, or the `--path` directory if one has been set.
+Calling binstubs with [GEM [GEM]] will create binstubs for all given gems.
+
+## OPTIONS
+
+* `--force`:
+ Overwrite existing binstubs if they exist.
+
+* `--path`:
+ The location to install the specified binstubs to. This defaults to `bin`.
+
+* `--standalone`:
+ Makes binstubs that can work without depending on Rubygems or Bundler at
+ runtime.
+
+* `--shebang`:
+ Specify a different shebang executable name than the default (default 'ruby')
+
+* `--all`:
+ Create binstubs for all gems in the bundle.
diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1
new file mode 100644
index 0000000000..acbdae0df2
--- /dev/null
+++ b/lib/bundler/man/bundle-cache.1
@@ -0,0 +1,55 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CACHE" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
+.
+.SH "SYNOPSIS"
+\fBbundle cache\fR
+.
+.SH "DESCRIPTION"
+Copy all of the \fB\.gem\fR files needed to run the application into the \fBvendor/cache\fR directory\. In the future, when running [bundle install(1)][bundle\-install], use the gems in the cache in preference to the ones on \fBrubygems\.org\fR\.
+.
+.SH "GIT AND PATH GEMS"
+The \fBbundle cache\fR command can also package \fB:git\fR and \fB:path\fR dependencies besides \.gem files\. This needs to be explicitly enabled via the \fB\-\-all\fR option\. Once used, the \fB\-\-all\fR option will be remembered\.
+.
+.SH "SUPPORT FOR MULTIPLE PLATFORMS"
+When using gems that have different packages for different platforms, Bundler supports caching of gems for other platforms where the Gemfile has been resolved (i\.e\. present in the lockfile) in \fBvendor/cache\fR\. This needs to be enabled via the \fB\-\-all\-platforms\fR option\. This setting will be remembered in your local bundler configuration\.
+.
+.SH "REMOTE FETCHING"
+By default, if you run \fBbundle install(1)\fR](bundle\-install\.1\.html) after running bundle cache(1) \fIbundle\-cache\.1\.html\fR, bundler will still connect to \fBrubygems\.org\fR to check whether a platform\-specific gem exists for any of the gems in \fBvendor/cache\fR\.
+.
+.P
+For instance, consider this Gemfile(5):
+.
+.IP "" 4
+.
+.nf
+
+source "https://rubygems\.org"
+
+gem "nokogiri"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+If you run \fBbundle cache\fR under C Ruby, bundler will retrieve the version of \fBnokogiri\fR for the \fB"ruby"\fR platform\. If you deploy to JRuby and run \fBbundle install\fR, bundler is forced to check to see whether a \fB"java"\fR platformed \fBnokogiri\fR exists\.
+.
+.P
+Even though the \fBnokogiri\fR gem for the Ruby platform is \fItechnically\fR acceptable on JRuby, it has a C extension that does not run on JRuby\. As a result, bundler will, by default, still connect to \fBrubygems\.org\fR to check whether it has a version of one of your gems more specific to your platform\.
+.
+.P
+This problem is also not limited to the \fB"java"\fR platform\. A similar (common) problem can happen when developing on Windows and deploying to Linux, or even when developing on OSX and deploying to Linux\.
+.
+.P
+If you know for sure that the gems packaged in \fBvendor/cache\fR are appropriate for the platform you are on, you can run \fBbundle install \-\-local\fR to skip checking for more appropriate gems, and use the ones in \fBvendor/cache\fR\.
+.
+.P
+One way to be sure that you have the right platformed versions of all your gems is to run \fBbundle cache\fR on an identical machine and check in the gems\. For instance, you can run \fBbundle cache\fR on an identical staging box during your staging process, and check in the \fBvendor/cache\fR before deploying to production\.
+.
+.P
+By default, bundle cache(1) \fIbundle\-cache\.1\.html\fR fetches and also installs the gems to the default location\. To package the dependencies to \fBvendor/cache\fR without installing them to the local install location, you can run \fBbundle cache \-\-no\-install\fR\.
diff --git a/lib/bundler/man/bundle-cache.1.ronn b/lib/bundler/man/bundle-cache.1.ronn
new file mode 100644
index 0000000000..383adb2ba3
--- /dev/null
+++ b/lib/bundler/man/bundle-cache.1.ronn
@@ -0,0 +1,72 @@
+bundle-cache(1) -- Package your needed `.gem` files into your application
+===========================================================================
+
+## SYNOPSIS
+
+`bundle cache`
+
+## DESCRIPTION
+
+Copy all of the `.gem` files needed to run the application into the
+`vendor/cache` directory. In the future, when running [bundle install(1)][bundle-install],
+use the gems in the cache in preference to the ones on `rubygems.org`.
+
+## GIT AND PATH GEMS
+
+The `bundle cache` command can also package `:git` and `:path` dependencies
+besides .gem files. This needs to be explicitly enabled via the `--all` option.
+Once used, the `--all` option will be remembered.
+
+## SUPPORT FOR MULTIPLE PLATFORMS
+
+When using gems that have different packages for different platforms, Bundler
+supports caching of gems for other platforms where the Gemfile has been resolved
+(i.e. present in the lockfile) in `vendor/cache`. This needs to be enabled via
+the `--all-platforms` option. This setting will be remembered in your local
+bundler configuration.
+
+## REMOTE FETCHING
+
+By default, if you run `bundle install(1)`](bundle-install.1.html) after running
+[bundle cache(1)](bundle-cache.1.html), bundler will still connect to `rubygems.org`
+to check whether a platform-specific gem exists for any of the gems
+in `vendor/cache`.
+
+For instance, consider this Gemfile(5):
+
+ source "https://rubygems.org"
+
+ gem "nokogiri"
+
+If you run `bundle cache` under C Ruby, bundler will retrieve
+the version of `nokogiri` for the `"ruby"` platform. If you deploy
+to JRuby and run `bundle install`, bundler is forced to check to
+see whether a `"java"` platformed `nokogiri` exists.
+
+Even though the `nokogiri` gem for the Ruby platform is
+_technically_ acceptable on JRuby, it has a C extension
+that does not run on JRuby. As a result, bundler will, by default,
+still connect to `rubygems.org` to check whether it has a version
+of one of your gems more specific to your platform.
+
+This problem is also not limited to the `"java"` platform.
+A similar (common) problem can happen when developing on Windows
+and deploying to Linux, or even when developing on OSX and
+deploying to Linux.
+
+If you know for sure that the gems packaged in `vendor/cache`
+are appropriate for the platform you are on, you can run
+`bundle install --local` to skip checking for more appropriate
+gems, and use the ones in `vendor/cache`.
+
+One way to be sure that you have the right platformed versions
+of all your gems is to run `bundle cache` on an identical
+machine and check in the gems. For instance, you can run
+`bundle cache` on an identical staging box during your
+staging process, and check in the `vendor/cache` before
+deploying to production.
+
+By default, [bundle cache(1)](bundle-cache.1.html) fetches and also
+installs the gems to the default location. To package the
+dependencies to `vendor/cache` without installing them to the
+local install location, you can run `bundle cache --no-install`.
diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1
new file mode 100644
index 0000000000..e555c9b399
--- /dev/null
+++ b/lib/bundler/man/bundle-check.1
@@ -0,0 +1,31 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CHECK" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
+.
+.SH "SYNOPSIS"
+\fBbundle check\fR [\-\-dry\-run] [\-\-gemfile=FILE] [\-\-path=PATH]
+.
+.SH "DESCRIPTION"
+\fBcheck\fR searches the local machine for each of the gems requested in the Gemfile\. If all gems are found, Bundler prints a success message and exits with a status of 0\.
+.
+.P
+If not, the first missing gem is listed and Bundler exits status 1\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-dry\-run\fR
+Locks the [\fBGemfile(5)\fR][Gemfile(5)] before running the command\.
+.
+.TP
+\fB\-\-gemfile\fR
+Use the specified gemfile instead of the [\fBGemfile(5)\fR][Gemfile(5)]\.
+.
+.TP
+\fB\-\-path\fR
+Specify a different path than the system default (\fB$BUNDLE_PATH\fR or \fB$GEM_HOME\fR)\. Bundler will remember this value for future installs on this machine\.
+
diff --git a/lib/bundler/man/bundle-check.1.ronn b/lib/bundler/man/bundle-check.1.ronn
new file mode 100644
index 0000000000..f2846b8ff2
--- /dev/null
+++ b/lib/bundler/man/bundle-check.1.ronn
@@ -0,0 +1,26 @@
+bundle-check(1) -- Verifies if dependencies are satisfied by installed gems
+===========================================================================
+
+## SYNOPSIS
+
+`bundle check` [--dry-run]
+ [--gemfile=FILE]
+ [--path=PATH]
+
+## DESCRIPTION
+
+`check` searches the local machine for each of the gems requested in the
+Gemfile. If all gems are found, Bundler prints a success message and exits with
+a status of 0.
+
+If not, the first missing gem is listed and Bundler exits status 1.
+
+## OPTIONS
+
+* `--dry-run`:
+ Locks the [`Gemfile(5)`][Gemfile(5)] before running the command.
+* `--gemfile`:
+ Use the specified gemfile instead of the [`Gemfile(5)`][Gemfile(5)].
+* `--path`:
+ Specify a different path than the system default (`$BUNDLE_PATH` or `$GEM_HOME`).
+ Bundler will remember this value for future installs on this machine.
diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1
new file mode 100644
index 0000000000..d403247524
--- /dev/null
+++ b/lib/bundler/man/bundle-clean.1
@@ -0,0 +1,24 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CLEAN" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
+.
+.SH "SYNOPSIS"
+\fBbundle clean\fR [\-\-dry\-run] [\-\-force]
+.
+.SH "DESCRIPTION"
+This command will remove all unused gems in your bundler directory\. This is useful when you have made many changes to your gem dependencies\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-dry\-run\fR
+Print the changes, but do not clean the unused gems\.
+.
+.TP
+\fB\-\-force\fR
+Force a clean even if \fB\-\-path\fR is not set\.
+
diff --git a/lib/bundler/man/bundle-clean.1.ronn b/lib/bundler/man/bundle-clean.1.ronn
new file mode 100644
index 0000000000..de23991782
--- /dev/null
+++ b/lib/bundler/man/bundle-clean.1.ronn
@@ -0,0 +1,18 @@
+bundle-clean(1) -- Cleans up unused gems in your bundler directory
+==================================================================
+
+## SYNOPSIS
+
+`bundle clean` [--dry-run] [--force]
+
+## DESCRIPTION
+
+This command will remove all unused gems in your bundler directory. This is
+useful when you have made many changes to your gem dependencies.
+
+## OPTIONS
+
+* `--dry-run`:
+ Print the changes, but do not clean the unused gems.
+* `--force`:
+ Force a clean even if `--path` is not set.
diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1
new file mode 100644
index 0000000000..976dae3aec
--- /dev/null
+++ b/lib/bundler/man/bundle-config.1
@@ -0,0 +1,496 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CONFIG" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-config\fR \- Set bundler configuration options
+.
+.SH "SYNOPSIS"
+\fBbundle config\fR [list|get|set|unset] [\fIname\fR [\fIvalue\fR]]
+.
+.SH "DESCRIPTION"
+This command allows you to interact with Bundler\'s configuration system\.
+.
+.P
+Bundler loads configuration settings in this order:
+.
+.IP "1." 4
+Local config (\fB<project_root>/\.bundle/config\fR or \fB$BUNDLE_APP_CONFIG/config\fR)
+.
+.IP "2." 4
+Environmental variables (\fBENV\fR)
+.
+.IP "3." 4
+Global config (\fB~/\.bundle/config\fR)
+.
+.IP "4." 4
+Bundler default config
+.
+.IP "" 0
+.
+.P
+Executing \fBbundle config list\fR with will print a list of all bundler configuration for the current bundle, and where that configuration was set\.
+.
+.P
+Executing \fBbundle config get <name>\fR will print the value of that configuration setting, and where it was set\.
+.
+.P
+Executing \fBbundle config set <name> <value>\fR will set that configuration to the value specified for all bundles executed as the current user\. The configuration will be stored in \fB~/\.bundle/config\fR\. If \fIname\fR already is set, \fIname\fR will be overridden and user will be warned\.
+.
+.P
+Executing \fBbundle config set \-\-global <name> <value>\fR works the same as above\.
+.
+.P
+Executing \fBbundle config set \-\-local <name> <value>\fR will set that configuration in the directory for the local application\. The configuration will be stored in \fB<project_root>/\.bundle/config\fR\. If \fBBUNDLE_APP_CONFIG\fR is set, the configuration will be stored in \fB$BUNDLE_APP_CONFIG/config\fR\.
+.
+.P
+Executing \fBbundle config unset <name>\fR will delete the configuration in both local and global sources\.
+.
+.P
+Executing \fBbundle config unset \-\-global <name>\fR will delete the configuration only from the user configuration\.
+.
+.P
+Executing \fBbundle config unset \-\-local <name> <value>\fR will delete the configuration only from the local application\.
+.
+.P
+Executing bundle with the \fBBUNDLE_IGNORE_CONFIG\fR environment variable set will cause it to ignore all configuration\.
+.
+.SH "REMEMBERING OPTIONS"
+Flags passed to \fBbundle install\fR or the Bundler runtime, such as \fB\-\-path foo\fR or \fB\-\-without production\fR, are remembered between commands and saved to your local application\'s configuration (normally, \fB\./\.bundle/config\fR)\.
+.
+.P
+However, this will be changed in bundler 3, so it\'s better not to rely on this behavior\. If these options must be remembered, it\'s better to set them using \fBbundle config\fR (e\.g\., \fBbundle config set \-\-local path foo\fR)\.
+.
+.P
+The options that can be configured are:
+.
+.TP
+\fBbin\fR
+Creates a directory (defaults to \fB~/bin\fR) and place any executables from the gem there\. These executables run in Bundler\'s context\. If used, you might add this directory to your environment\'s \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\.
+.
+.TP
+\fBdeployment\fR
+In deployment mode, Bundler will \'roll\-out\' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\.
+.
+.TP
+\fBpath\fR
+The location to install the specified gems to\. This defaults to Rubygems\' setting\. Bundler shares this location with Rubygems, \fBgem install \.\.\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \.\.\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
+.
+.TP
+\fBwithout\fR
+A space\-separated list of groups referencing gems to skip during installation\.
+.
+.TP
+\fBwith\fR
+A space\-separated list of groups referencing gems to include during installation\.
+.
+.SH "BUILD OPTIONS"
+You can use \fBbundle config\fR to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem\.
+.
+.P
+A very common example, the \fBmysql\fR gem, requires Snow Leopard users to pass configuration flags to \fBgem install\fR to specify where to find the \fBmysql_config\fR executable\.
+.
+.IP "" 4
+.
+.nf
+
+gem install mysql \-\- \-\-with\-mysql\-config=/usr/local/mysql/bin/mysql_config
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Since the specific location of that executable can change from machine to machine, you can specify these flags on a per\-machine basis\.
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global build\.mysql \-\-with\-mysql\-config=/usr/local/mysql/bin/mysql_config
+.
+.fi
+.
+.IP "" 0
+.
+.P
+After running this command, every time bundler needs to install the \fBmysql\fR gem, it will pass along the flags you specified\.
+.
+.SH "CONFIGURATION KEYS"
+Configuration keys in bundler have two forms: the canonical form and the environment variable form\.
+.
+.P
+For instance, passing the \fB\-\-without\fR flag to bundle install(1) \fIbundle\-install\.1\.html\fR prevents Bundler from installing certain groups specified in the Gemfile(5)\. Bundler persists this value in \fBapp/\.bundle/config\fR so that calls to \fBBundler\.setup\fR do not try to find gems from the \fBGemfile\fR that you didn\'t install\. Additionally, subsequent calls to bundle install(1) \fIbundle\-install\.1\.html\fR remember this setting and skip those groups\.
+.
+.P
+The canonical form of this configuration is \fB"without"\fR\. To convert the canonical form to the environment variable form, capitalize it, and prepend \fBBUNDLE_\fR\. The environment variable form of \fB"without"\fR is \fBBUNDLE_WITHOUT\fR\.
+.
+.P
+Any periods in the configuration keys must be replaced with two underscores when setting it via environment variables\. The configuration key \fBlocal\.rack\fR becomes the environment variable \fBBUNDLE_LOCAL__RACK\fR\.
+.
+.SH "LIST OF AVAILABLE KEYS"
+The following is a list of all configuration keys and their purpose\. You can learn more about their operation in bundle install(1) \fIbundle\-install\.1\.html\fR\.
+.
+.IP "\(bu" 4
+\fBallow_deployment_source_credential_changes\fR (\fBBUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES\fR): When in deployment mode, allow changing the credentials to a gem\'s source\. Ex: \fBhttps://some\.host\.com/gems/path/\fR \-> \fBhttps://user_name:password@some\.host\.com/gems/path\fR
+.
+.IP "\(bu" 4
+\fBallow_offline_install\fR (\fBBUNDLE_ALLOW_OFFLINE_INSTALL\fR): Allow Bundler to use cached data when installing without network access\.
+.
+.IP "\(bu" 4
+\fBauto_clean_without_path\fR (\fBBUNDLE_AUTO_CLEAN_WITHOUT_PATH\fR): Automatically run \fBbundle clean\fR after installing when an explicit \fBpath\fR has not been set and Bundler is not installing into the system gems\.
+.
+.IP "\(bu" 4
+\fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR): Automatically run \fBbundle install\fR when gems are missing\.
+.
+.IP "\(bu" 4
+\fBbin\fR (\fBBUNDLE_BIN\fR): Install executables from gems in the bundle to the specified directory\. Defaults to \fBfalse\fR\.
+.
+.IP "\(bu" 4
+\fBcache_all\fR (\fBBUNDLE_CACHE_ALL\fR): Cache all gems, including path and git gems\. This needs to be explicitly configured on bundler 1 and bundler 2, but will be the default on bundler 3\.
+.
+.IP "\(bu" 4
+\fBcache_all_platforms\fR (\fBBUNDLE_CACHE_ALL_PLATFORMS\fR): Cache gems for all platforms\.
+.
+.IP "\(bu" 4
+\fBcache_path\fR (\fBBUNDLE_CACHE_PATH\fR): The directory that bundler will place cached gems in when running \fBbundle package\fR, and that bundler will look in when installing gems\. Defaults to \fBvendor/cache\fR\.
+.
+.IP "\(bu" 4
+\fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\.
+.
+.IP "\(bu" 4
+\fBconsole\fR (\fBBUNDLE_CONSOLE\fR): The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\.
+.
+.IP "\(bu" 4
+\fBdefault_install_uses_path\fR (\fBBUNDLE_DEFAULT_INSTALL_USES_PATH\fR): Whether a \fBbundle install\fR without an explicit \fB\-\-path\fR argument defaults to installing gems in \fB\.bundle\fR\.
+.
+.IP "\(bu" 4
+\fBdeployment\fR (\fBBUNDLE_DEPLOYMENT\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\.
+.
+.IP "\(bu" 4
+\fBdisable_checksum_validation\fR (\fBBUNDLE_DISABLE_CHECKSUM_VALIDATION\fR): Allow installing gems even if they do not match the checksum provided by RubyGems\.
+.
+.IP "\(bu" 4
+\fBdisable_exec_load\fR (\fBBUNDLE_DISABLE_EXEC_LOAD\fR): Stop Bundler from using \fBload\fR to launch an executable in\-process in \fBbundle exec\fR\.
+.
+.IP "\(bu" 4
+\fBdisable_local_branch_check\fR (\fBBUNDLE_DISABLE_LOCAL_BRANCH_CHECK\fR): Allow Bundler to use a local git override without a branch specified in the Gemfile\.
+.
+.IP "\(bu" 4
+\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR): Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\.
+.
+.IP "\(bu" 4
+\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR): Stop Bundler from accessing gems installed to RubyGems\' normal location\.
+.
+.IP "\(bu" 4
+\fBdisable_version_check\fR (\fBBUNDLE_DISABLE_VERSION_CHECK\fR): Stop Bundler from checking if a newer Bundler version is available on rubygems\.org\.
+.
+.IP "\(bu" 4
+\fBforce_ruby_platform\fR (\fBBUNDLE_FORCE_RUBY_PLATFORM\fR): Ignore the current machine\'s platform and install only \fBruby\fR platform gems\. As a result, gems with native extensions will be compiled from source\.
+.
+.IP "\(bu" 4
+\fBfrozen\fR (\fBBUNDLE_FROZEN\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\. Defaults to \fBtrue\fR when \fB\-\-deployment\fR is used\.
+.
+.IP "\(bu" 4
+\fBgem\.github_username\fR (\fBBUNDLE_GEM__GITHUB_USERNAME\fR): Sets a GitHub username or organization to be used in \fBREADME\fR file when you create a new gem via \fBbundle gem\fR command\. It can be overridden by passing an explicit \fB\-\-github\-username\fR flag to \fBbundle gem\fR\.
+.
+.IP "\(bu" 4
+\fBgem\.push_key\fR (\fBBUNDLE_GEM__PUSH_KEY\fR): Sets the \fB\-\-key\fR parameter for \fBgem push\fR when using the \fBrake release\fR command with a private gemstash server\.
+.
+.IP "\(bu" 4
+\fBgemfile\fR (\fBBUNDLE_GEMFILE\fR): The name of the file that bundler should use as the \fBGemfile\fR\. This location of this file also sets the root of the project, which is used to resolve relative paths in the \fBGemfile\fR, among other things\. By default, bundler will search up from the current working directory until it finds a \fBGemfile\fR\.
+.
+.IP "\(bu" 4
+\fBglobal_gem_cache\fR (\fBBUNDLE_GLOBAL_GEM_CACHE\fR): Whether Bundler should cache all gems globally, rather than locally to the installing Ruby installation\.
+.
+.IP "\(bu" 4
+\fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR): When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\.
+.
+.IP "\(bu" 4
+\fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR): Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\.
+.
+.IP "\(bu" 4
+\fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can install in parallel\. Defaults to 1 on Windows, and to the the number of processors on other platforms\.
+.
+.IP "\(bu" 4
+\fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR): Whether \fBbundle package\fR should skip installing gems\.
+.
+.IP "\(bu" 4
+\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\.
+.
+.IP "\(bu" 4
+\fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. Defaults to \fBGem\.dir\fR\. When \-\-deployment is used, defaults to vendor/bundle\.
+.
+.IP "\(bu" 4
+\fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR): Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\.
+.
+.IP "\(bu" 4
+\fBpath_relative_to_cwd\fR (\fBBUNDLE_PATH_RELATIVE_TO_CWD\fR) Makes \fB\-\-path\fR relative to the CWD instead of the \fBGemfile\fR\.
+.
+.IP "\(bu" 4
+\fBplugins\fR (\fBBUNDLE_PLUGINS\fR): Enable Bundler\'s experimental plugin system\.
+.
+.IP "\(bu" 4
+\fBprefer_patch\fR (BUNDLE_PREFER_PATCH): Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\.
+.
+.IP "\(bu" 4
+\fBprint_only_version_number\fR (\fBBUNDLE_PRINT_ONLY_VERSION_NUMBER\fR): Print only version number from \fBbundler \-\-version\fR\.
+.
+.IP "\(bu" 4
+\fBredirect\fR (\fBBUNDLE_REDIRECT\fR): The number of redirects allowed for network requests\. Defaults to \fB5\fR\.
+.
+.IP "\(bu" 4
+\fBretry\fR (\fBBUNDLE_RETRY\fR): The number of times to retry failed network requests\. Defaults to \fB3\fR\.
+.
+.IP "\(bu" 4
+\fBsetup_makes_kernel_gem_public\fR (\fBBUNDLE_SETUP_MAKES_KERNEL_GEM_PUBLIC\fR): Have \fBBundler\.setup\fR make the \fBKernel#gem\fR method public, even though RubyGems declares it as private\.
+.
+.IP "\(bu" 4
+\fBshebang\fR (\fBBUNDLE_SHEBANG\fR): The program name that should be invoked for generated binstubs\. Defaults to the ruby install name used to generate the binstub\.
+.
+.IP "\(bu" 4
+\fBsilence_deprecations\fR (\fBBUNDLE_SILENCE_DEPRECATIONS\fR): Whether Bundler should silence deprecation warnings for behavior that will be changed in the next major version\.
+.
+.IP "\(bu" 4
+\fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR): Silence the warning Bundler prints when installing gems as root\.
+.
+.IP "\(bu" 4
+\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\.
+.
+.IP "\(bu" 4
+\fBssl_client_cert\fR (\fBBUNDLE_SSL_CLIENT_CERT\fR): Path to a designated file containing a X\.509 client certificate and key in PEM format\.
+.
+.IP "\(bu" 4
+\fBssl_verify_mode\fR (\fBBUNDLE_SSL_VERIFY_MODE\fR): The SSL verification mode Bundler uses when making HTTPS requests\. Defaults to verify peer\.
+.
+.IP "\(bu" 4
+\fBsuppress_install_using_messages\fR (\fBBUNDLE_SUPPRESS_INSTALL_USING_MESSAGES\fR): Avoid printing \fBUsing \.\.\.\fR messages during installation when the version of a gem has not changed\.
+.
+.IP "\(bu" 4
+\fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR): The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\.
+.
+.IP "\(bu" 4
+\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\.
+.
+.IP "\(bu" 4
+\fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\.
+.
+.IP "\(bu" 4
+\fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR): The custom user agent fragment Bundler includes in API requests\.
+.
+.IP "\(bu" 4
+\fBwith\fR (\fBBUNDLE_WITH\fR): A \fB:\fR\-separated list of groups whose gems bundler should install\.
+.
+.IP "\(bu" 4
+\fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A \fB:\fR\-separated list of groups whose gems bundler should not install\.
+.
+.IP "" 0
+.
+.P
+In general, you should set these settings per\-application by using the applicable flag to the bundle install(1) \fIbundle\-install\.1\.html\fR or bundle package(1) \fIbundle\-package\.1\.html\fR command\.
+.
+.P
+You can set them globally either via environment variables or \fBbundle config\fR, whichever is preferable for your setup\. If you use both, environment variables will take preference over global settings\.
+.
+.SH "LOCAL GIT REPOS"
+Bundler also allows you to work against a git repository locally instead of using the remote version\. This can be achieved by setting up a local override:
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-local local\.GEM_NAME /path/to/local/git/repository
+.
+.fi
+.
+.IP "" 0
+.
+.P
+For example, in order to use a local Rack repository, a developer could call:
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-local local\.rack ~/Work/git/rack
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Now instead of checking out the remote git repository, the local override will be used\. Similar to a path source, every time the local git repository change, changes will be automatically picked up by Bundler\. This means a commit in the local git repo will update the revision in the \fBGemfile\.lock\fR to the local git repo revision\. This requires the same attention as git submodules\. Before pushing to the remote, you need to ensure the local override was pushed, otherwise you may point to a commit that only exists in your local machine\. You\'ll also need to CGI escape your usernames and passwords as well\.
+.
+.P
+Bundler does many checks to ensure a developer won\'t work with invalid references\. Particularly, we force a developer to specify a branch in the \fBGemfile\fR in order to use this feature\. If the branch specified in the \fBGemfile\fR and the current branch in the local git repository do not match, Bundler will abort\. This ensures that a developer is always working against the correct branches, and prevents accidental locking to a different branch\.
+.
+.P
+Finally, Bundler also ensures that the current revision in the \fBGemfile\.lock\fR exists in the local git repository\. By doing this, Bundler forces you to fetch the latest changes in the remotes\.
+.
+.SH "MIRRORS OF GEM SOURCES"
+Bundler supports overriding gem sources with mirrors\. This allows you to configure rubygems\.org as the gem source in your Gemfile while still using your mirror to fetch gems\.
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global mirror\.SOURCE_URL MIRROR_URL
+.
+.fi
+.
+.IP "" 0
+.
+.P
+For example, to use a mirror of rubygems\.org hosted at rubygems\-mirror\.org:
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global mirror\.http://rubygems\.org http://rubygems\-mirror\.org
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Each mirror also provides a fallback timeout setting\. If the mirror does not respond within the fallback timeout, Bundler will try to use the original server instead of the mirror\.
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global mirror\.SOURCE_URL\.fallback_timeout TIMEOUT
+.
+.fi
+.
+.IP "" 0
+.
+.P
+For example, to fall back to rubygems\.org after 3 seconds:
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global mirror\.https://rubygems\.org\.fallback_timeout 3
+.
+.fi
+.
+.IP "" 0
+.
+.P
+The default fallback timeout is 0\.1 seconds, but the setting can currently only accept whole seconds (for example, 1, 15, or 30)\.
+.
+.SH "CREDENTIALS FOR GEM SOURCES"
+Bundler allows you to configure credentials for any gem source, which allows you to avoid putting secrets into your Gemfile\.
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global SOURCE_HOSTNAME USERNAME:PASSWORD
+.
+.fi
+.
+.IP "" 0
+.
+.P
+For example, to save the credentials of user \fBclaudette\fR for the gem source at \fBgems\.longerous\.com\fR, you would run:
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global gems\.longerous\.com claudette:s00pers3krit
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Or you can set the credentials as an environment variable like this:
+.
+.IP "" 4
+.
+.nf
+
+export BUNDLE_GEMS__LONGEROUS__COM="claudette:s00pers3krit"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+For gems with a git source with HTTP(S) URL you can specify credentials like so:
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-global https://github\.com/rubygems/rubygems\.git username:password
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Or you can set the credentials as an environment variable like so:
+.
+.IP "" 4
+.
+.nf
+
+export BUNDLE_GITHUB__COM=username:password
+.
+.fi
+.
+.IP "" 0
+.
+.P
+This is especially useful for private repositories on hosts such as Github, where you can use personal OAuth tokens:
+.
+.IP "" 4
+.
+.nf
+
+export BUNDLE_GITHUB__COM=abcd0123generatedtoken:x\-oauth\-basic
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Note that any configured credentials will be redacted by informative commands such as \fBbundle config list\fR or \fBbundle config get\fR, unless you use the \fB\-\-parseable\fR flag\. This is to avoid unintentionally leaking credentials when copy\-pasting bundler output\.
+.
+.P
+Also note that to guarantee a sane mapping between valid environment variable names and valid host names, bundler makes the following transformations:
+.
+.IP "\(bu" 4
+Any \fB\-\fR characters in a host name are mapped to a triple dash (\fB___\fR) in the corresponding environment variable\.
+.
+.IP "\(bu" 4
+Any \fB\.\fR characters in a host name are mapped to a double dash (\fB__\fR) in the corresponding environment variable\.
+.
+.IP "" 0
+.
+.P
+This means that if you have a gem server named \fBmy\.gem\-host\.com\fR, you\'ll need to use the \fBBUNDLE_MY__GEM___HOST__COM\fR variable to configure credentials for it through ENV\.
+.
+.SH "CONFIGURE BUNDLER DIRECTORIES"
+Bundler\'s home, config, cache and plugin directories are able to be configured through environment variables\. The default location for Bundler\'s home directory is \fB~/\.bundle\fR, which all directories inherit from by default\. The following outlines the available environment variables and their default values
+.
+.IP "" 4
+.
+.nf
+
+BUNDLE_USER_HOME : $HOME/\.bundle
+BUNDLE_USER_CACHE : $BUNDLE_USER_HOME/cache
+BUNDLE_USER_CONFIG : $BUNDLE_USER_HOME/config
+BUNDLE_USER_PLUGIN : $BUNDLE_USER_HOME/plugin
+.
+.fi
+.
+.IP "" 0
+
diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn
new file mode 100644
index 0000000000..f412ee3aec
--- /dev/null
+++ b/lib/bundler/man/bundle-config.1.ronn
@@ -0,0 +1,396 @@
+bundle-config(1) -- Set bundler configuration options
+=====================================================
+
+## SYNOPSIS
+
+`bundle config` [list|get|set|unset] [<name> [<value>]]
+
+## DESCRIPTION
+
+This command allows you to interact with Bundler's configuration system.
+
+Bundler loads configuration settings in this order:
+
+1. Local config (`<project_root>/.bundle/config` or `$BUNDLE_APP_CONFIG/config`)
+2. Environmental variables (`ENV`)
+3. Global config (`~/.bundle/config`)
+4. Bundler default config
+
+Executing `bundle config list` with will print a list of all bundler
+configuration for the current bundle, and where that configuration
+was set.
+
+Executing `bundle config get <name>` will print the value of that configuration
+setting, and where it was set.
+
+Executing `bundle config set <name> <value>` will set that configuration to the
+value specified for all bundles executed as the current user. The configuration
+will be stored in `~/.bundle/config`. If <name> already is set, <name> will be
+overridden and user will be warned.
+
+Executing `bundle config set --global <name> <value>` works the same as above.
+
+Executing `bundle config set --local <name> <value>` will set that configuration
+in the directory for the local application. The configuration will be stored in
+`<project_root>/.bundle/config`. If `BUNDLE_APP_CONFIG` is set, the configuration
+will be stored in `$BUNDLE_APP_CONFIG/config`.
+
+Executing `bundle config unset <name>` will delete the configuration in both
+local and global sources.
+
+Executing `bundle config unset --global <name>` will delete the configuration
+only from the user configuration.
+
+Executing `bundle config unset --local <name> <value>` will delete the
+configuration only from the local application.
+
+Executing bundle with the `BUNDLE_IGNORE_CONFIG` environment variable set will
+cause it to ignore all configuration.
+
+## REMEMBERING OPTIONS
+
+Flags passed to `bundle install` or the Bundler runtime, such as `--path foo` or
+`--without production`, are remembered between commands and saved to your local
+application's configuration (normally, `./.bundle/config`).
+
+However, this will be changed in bundler 3, so it's better not to rely on this
+behavior. If these options must be remembered, it's better to set them using
+`bundle config` (e.g., `bundle config set --local path foo`).
+
+The options that can be configured are:
+
+* `bin`:
+ Creates a directory (defaults to `~/bin`) and place any executables from the
+ gem there. These executables run in Bundler's context. If used, you might add
+ this directory to your environment's `PATH` variable. For instance, if the
+ `rails` gem comes with a `rails` executable, this flag will create a
+ `bin/rails` executable that ensures that all referred dependencies will be
+ resolved using the bundled gems.
+
+* `deployment`:
+ In deployment mode, Bundler will 'roll-out' the bundle for
+ `production` use. Please check carefully if you want to have this option
+ enabled in `development` or `test` environments.
+
+* `path`:
+ The location to install the specified gems to. This defaults to Rubygems'
+ setting. Bundler shares this location with Rubygems, `gem install ...` will
+ have gem installed there, too. Therefore, gems installed without a
+ `--path ...` setting will show up by calling `gem list`. Accordingly, gems
+ installed to other locations will not get listed.
+
+* `without`:
+ A space-separated list of groups referencing gems to skip during installation.
+
+* `with`:
+ A space-separated list of groups referencing gems to include during installation.
+
+## BUILD OPTIONS
+
+You can use `bundle config` to give Bundler the flags to pass to the gem
+installer every time bundler tries to install a particular gem.
+
+A very common example, the `mysql` gem, requires Snow Leopard users to
+pass configuration flags to `gem install` to specify where to find the
+`mysql_config` executable.
+
+ gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
+
+Since the specific location of that executable can change from machine
+to machine, you can specify these flags on a per-machine basis.
+
+ bundle config set --global build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config
+
+After running this command, every time bundler needs to install the
+`mysql` gem, it will pass along the flags you specified.
+
+## CONFIGURATION KEYS
+
+Configuration keys in bundler have two forms: the canonical form and the
+environment variable form.
+
+For instance, passing the `--without` flag to [bundle install(1)](bundle-install.1.html)
+prevents Bundler from installing certain groups specified in the Gemfile(5). Bundler
+persists this value in `app/.bundle/config` so that calls to `Bundler.setup`
+do not try to find gems from the `Gemfile` that you didn't install. Additionally,
+subsequent calls to [bundle install(1)](bundle-install.1.html) remember this setting
+and skip those groups.
+
+The canonical form of this configuration is `"without"`. To convert the canonical
+form to the environment variable form, capitalize it, and prepend `BUNDLE_`. The
+environment variable form of `"without"` is `BUNDLE_WITHOUT`.
+
+Any periods in the configuration keys must be replaced with two underscores when
+setting it via environment variables. The configuration key `local.rack` becomes
+the environment variable `BUNDLE_LOCAL__RACK`.
+
+## LIST OF AVAILABLE KEYS
+
+The following is a list of all configuration keys and their purpose. You can
+learn more about their operation in [bundle install(1)](bundle-install.1.html).
+
+* `allow_deployment_source_credential_changes` (`BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES`):
+ When in deployment mode, allow changing the credentials to a gem's source.
+ Ex: `https://some.host.com/gems/path/` -> `https://user_name:password@some.host.com/gems/path`
+* `allow_offline_install` (`BUNDLE_ALLOW_OFFLINE_INSTALL`):
+ Allow Bundler to use cached data when installing without network access.
+* `auto_clean_without_path` (`BUNDLE_AUTO_CLEAN_WITHOUT_PATH`):
+ Automatically run `bundle clean` after installing when an explicit `path`
+ has not been set and Bundler is not installing into the system gems.
+* `auto_install` (`BUNDLE_AUTO_INSTALL`):
+ Automatically run `bundle install` when gems are missing.
+* `bin` (`BUNDLE_BIN`):
+ Install executables from gems in the bundle to the specified directory.
+ Defaults to `false`.
+* `cache_all` (`BUNDLE_CACHE_ALL`):
+ Cache all gems, including path and git gems. This needs to be explicitly
+ configured on bundler 1 and bundler 2, but will be the default on bundler 3.
+* `cache_all_platforms` (`BUNDLE_CACHE_ALL_PLATFORMS`):
+ Cache gems for all platforms.
+* `cache_path` (`BUNDLE_CACHE_PATH`):
+ The directory that bundler will place cached gems in when running
+ <code>bundle package</code>, and that bundler will look in when installing gems.
+ Defaults to `vendor/cache`.
+* `clean` (`BUNDLE_CLEAN`):
+ Whether Bundler should run `bundle clean` automatically after
+ `bundle install`.
+* `console` (`BUNDLE_CONSOLE`):
+ The console that `bundle console` starts. Defaults to `irb`.
+* `default_install_uses_path` (`BUNDLE_DEFAULT_INSTALL_USES_PATH`):
+ Whether a `bundle install` without an explicit `--path` argument defaults
+ to installing gems in `.bundle`.
+* `deployment` (`BUNDLE_DEPLOYMENT`):
+ Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the
+ lockfile has not been updated, running Bundler commands will be blocked.
+* `disable_checksum_validation` (`BUNDLE_DISABLE_CHECKSUM_VALIDATION`):
+ Allow installing gems even if they do not match the checksum provided by
+ RubyGems.
+* `disable_exec_load` (`BUNDLE_DISABLE_EXEC_LOAD`):
+ Stop Bundler from using `load` to launch an executable in-process in
+ `bundle exec`.
+* `disable_local_branch_check` (`BUNDLE_DISABLE_LOCAL_BRANCH_CHECK`):
+ Allow Bundler to use a local git override without a branch specified in the
+ Gemfile.
+* `disable_local_revision_check` (`BUNDLE_DISABLE_LOCAL_REVISION_CHECK`):
+ Allow Bundler to use a local git override without checking if the revision
+ present in the lockfile is present in the repository.
+* `disable_shared_gems` (`BUNDLE_DISABLE_SHARED_GEMS`):
+ Stop Bundler from accessing gems installed to RubyGems' normal location.
+* `disable_version_check` (`BUNDLE_DISABLE_VERSION_CHECK`):
+ Stop Bundler from checking if a newer Bundler version is available on
+ rubygems.org.
+* `force_ruby_platform` (`BUNDLE_FORCE_RUBY_PLATFORM`):
+ Ignore the current machine's platform and install only `ruby` platform gems.
+ As a result, gems with native extensions will be compiled from source.
+* `frozen` (`BUNDLE_FROZEN`):
+ Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the
+ lockfile has not been updated, running Bundler commands will be blocked.
+ Defaults to `true` when `--deployment` is used.
+* `gem.github_username` (`BUNDLE_GEM__GITHUB_USERNAME`):
+ Sets a GitHub username or organization to be used in `README` file when you
+ create a new gem via `bundle gem` command. It can be overridden by passing an
+ explicit `--github-username` flag to `bundle gem`.
+* `gem.push_key` (`BUNDLE_GEM__PUSH_KEY`):
+ Sets the `--key` parameter for `gem push` when using the `rake release`
+ command with a private gemstash server.
+* `gemfile` (`BUNDLE_GEMFILE`):
+ The name of the file that bundler should use as the `Gemfile`. This location
+ of this file also sets the root of the project, which is used to resolve
+ relative paths in the `Gemfile`, among other things. By default, bundler
+ will search up from the current working directory until it finds a
+ `Gemfile`.
+* `global_gem_cache` (`BUNDLE_GLOBAL_GEM_CACHE`):
+ Whether Bundler should cache all gems globally, rather than locally to the
+ installing Ruby installation.
+* `ignore_messages` (`BUNDLE_IGNORE_MESSAGES`):
+ When set, no post install messages will be printed. To silence a single gem,
+ use dot notation like `ignore_messages.httparty true`.
+* `init_gems_rb` (`BUNDLE_INIT_GEMS_RB`):
+ Generate a `gems.rb` instead of a `Gemfile` when running `bundle init`.
+* `jobs` (`BUNDLE_JOBS`):
+ The number of gems Bundler can install in parallel. Defaults to 1 on Windows,
+ and to the the number of processors on other platforms.
+* `no_install` (`BUNDLE_NO_INSTALL`):
+ Whether `bundle package` should skip installing gems.
+* `no_prune` (`BUNDLE_NO_PRUNE`):
+ Whether Bundler should leave outdated gems unpruned when caching.
+* `path` (`BUNDLE_PATH`):
+ The location on disk where all gems in your bundle will be located regardless
+ of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location
+ will be installed by `bundle install`. Defaults to `Gem.dir`. When --deployment
+ is used, defaults to vendor/bundle.
+* `path.system` (`BUNDLE_PATH__SYSTEM`):
+ Whether Bundler will install gems into the default system path (`Gem.dir`).
+* `path_relative_to_cwd` (`BUNDLE_PATH_RELATIVE_TO_CWD`)
+ Makes `--path` relative to the CWD instead of the `Gemfile`.
+* `plugins` (`BUNDLE_PLUGINS`):
+ Enable Bundler's experimental plugin system.
+* `prefer_patch` (BUNDLE_PREFER_PATCH):
+ Prefer updating only to next patch version during updates. Makes `bundle update` calls equivalent to `bundler update --patch`.
+* `print_only_version_number` (`BUNDLE_PRINT_ONLY_VERSION_NUMBER`):
+ Print only version number from `bundler --version`.
+* `redirect` (`BUNDLE_REDIRECT`):
+ The number of redirects allowed for network requests. Defaults to `5`.
+* `retry` (`BUNDLE_RETRY`):
+ The number of times to retry failed network requests. Defaults to `3`.
+* `setup_makes_kernel_gem_public` (`BUNDLE_SETUP_MAKES_KERNEL_GEM_PUBLIC`):
+ Have `Bundler.setup` make the `Kernel#gem` method public, even though
+ RubyGems declares it as private.
+* `shebang` (`BUNDLE_SHEBANG`):
+ The program name that should be invoked for generated binstubs. Defaults to
+ the ruby install name used to generate the binstub.
+* `silence_deprecations` (`BUNDLE_SILENCE_DEPRECATIONS`):
+ Whether Bundler should silence deprecation warnings for behavior that will
+ be changed in the next major version.
+* `silence_root_warning` (`BUNDLE_SILENCE_ROOT_WARNING`):
+ Silence the warning Bundler prints when installing gems as root.
+* `ssl_ca_cert` (`BUNDLE_SSL_CA_CERT`):
+ Path to a designated CA certificate file or folder containing multiple
+ certificates for trusted CAs in PEM format.
+* `ssl_client_cert` (`BUNDLE_SSL_CLIENT_CERT`):
+ Path to a designated file containing a X.509 client certificate
+ and key in PEM format.
+* `ssl_verify_mode` (`BUNDLE_SSL_VERIFY_MODE`):
+ The SSL verification mode Bundler uses when making HTTPS requests.
+ Defaults to verify peer.
+* `suppress_install_using_messages` (`BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES`):
+ Avoid printing `Using ...` messages during installation when the version of
+ a gem has not changed.
+* `system_bindir` (`BUNDLE_SYSTEM_BINDIR`):
+ The location where RubyGems installs binstubs. Defaults to `Gem.bindir`.
+* `timeout` (`BUNDLE_TIMEOUT`):
+ The seconds allowed before timing out for network requests. Defaults to `10`.
+* `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`):
+ Require passing `--all` to `bundle update` when everything should be updated,
+ and disallow passing no options to `bundle update`.
+* `user_agent` (`BUNDLE_USER_AGENT`):
+ The custom user agent fragment Bundler includes in API requests.
+* `with` (`BUNDLE_WITH`):
+ A `:`-separated list of groups whose gems bundler should install.
+* `without` (`BUNDLE_WITHOUT`):
+ A `:`-separated list of groups whose gems bundler should not install.
+
+In general, you should set these settings per-application by using the applicable
+flag to the [bundle install(1)](bundle-install.1.html) or [bundle package(1)](bundle-package.1.html) command.
+
+You can set them globally either via environment variables or `bundle config`,
+whichever is preferable for your setup. If you use both, environment variables
+will take preference over global settings.
+
+## LOCAL GIT REPOS
+
+Bundler also allows you to work against a git repository locally
+instead of using the remote version. This can be achieved by setting
+up a local override:
+
+ bundle config set --local local.GEM_NAME /path/to/local/git/repository
+
+For example, in order to use a local Rack repository, a developer could call:
+
+ bundle config set --local local.rack ~/Work/git/rack
+
+Now instead of checking out the remote git repository, the local
+override will be used. Similar to a path source, every time the local
+git repository change, changes will be automatically picked up by
+Bundler. This means a commit in the local git repo will update the
+revision in the `Gemfile.lock` to the local git repo revision. This
+requires the same attention as git submodules. Before pushing to
+the remote, you need to ensure the local override was pushed, otherwise
+you may point to a commit that only exists in your local machine.
+You'll also need to CGI escape your usernames and passwords as well.
+
+Bundler does many checks to ensure a developer won't work with
+invalid references. Particularly, we force a developer to specify
+a branch in the `Gemfile` in order to use this feature. If the branch
+specified in the `Gemfile` and the current branch in the local git
+repository do not match, Bundler will abort. This ensures that
+a developer is always working against the correct branches, and prevents
+accidental locking to a different branch.
+
+Finally, Bundler also ensures that the current revision in the
+`Gemfile.lock` exists in the local git repository. By doing this, Bundler
+forces you to fetch the latest changes in the remotes.
+
+## MIRRORS OF GEM SOURCES
+
+Bundler supports overriding gem sources with mirrors. This allows you to
+configure rubygems.org as the gem source in your Gemfile while still using your
+mirror to fetch gems.
+
+ bundle config set --global mirror.SOURCE_URL MIRROR_URL
+
+For example, to use a mirror of rubygems.org hosted at rubygems-mirror.org:
+
+ bundle config set --global mirror.http://rubygems.org http://rubygems-mirror.org
+
+Each mirror also provides a fallback timeout setting. If the mirror does not
+respond within the fallback timeout, Bundler will try to use the original
+server instead of the mirror.
+
+ bundle config set --global mirror.SOURCE_URL.fallback_timeout TIMEOUT
+
+For example, to fall back to rubygems.org after 3 seconds:
+
+ bundle config set --global mirror.https://rubygems.org.fallback_timeout 3
+
+The default fallback timeout is 0.1 seconds, but the setting can currently
+only accept whole seconds (for example, 1, 15, or 30).
+
+## CREDENTIALS FOR GEM SOURCES
+
+Bundler allows you to configure credentials for any gem source, which allows
+you to avoid putting secrets into your Gemfile.
+
+ bundle config set --global SOURCE_HOSTNAME USERNAME:PASSWORD
+
+For example, to save the credentials of user `claudette` for the gem source at
+`gems.longerous.com`, you would run:
+
+ bundle config set --global gems.longerous.com claudette:s00pers3krit
+
+Or you can set the credentials as an environment variable like this:
+
+ export BUNDLE_GEMS__LONGEROUS__COM="claudette:s00pers3krit"
+
+For gems with a git source with HTTP(S) URL you can specify credentials like so:
+
+ bundle config set --global https://github.com/rubygems/rubygems.git username:password
+
+Or you can set the credentials as an environment variable like so:
+
+ export BUNDLE_GITHUB__COM=username:password
+
+This is especially useful for private repositories on hosts such as Github,
+where you can use personal OAuth tokens:
+
+ export BUNDLE_GITHUB__COM=abcd0123generatedtoken:x-oauth-basic
+
+Note that any configured credentials will be redacted by informative commands
+such as `bundle config list` or `bundle config get`, unless you use the
+`--parseable` flag. This is to avoid unintentionally leaking credentials when
+copy-pasting bundler output.
+
+Also note that to guarantee a sane mapping between valid environment variable
+names and valid host names, bundler makes the following transformations:
+
+* Any `-` characters in a host name are mapped to a triple dash (`___`) in the
+ corresponding environment variable.
+
+* Any `.` characters in a host name are mapped to a double dash (`__`) in the
+ corresponding environment variable.
+
+This means that if you have a gem server named `my.gem-host.com`, you'll need to
+use the `BUNDLE_MY__GEM___HOST__COM` variable to configure credentials for it
+through ENV.
+
+## CONFIGURE BUNDLER DIRECTORIES
+
+Bundler's home, config, cache and plugin directories are able to be configured
+through environment variables. The default location for Bundler's home directory is
+`~/.bundle`, which all directories inherit from by default. The following
+outlines the available environment variables and their default values
+
+ BUNDLE_USER_HOME : $HOME/.bundle
+ BUNDLE_USER_CACHE : $BUNDLE_USER_HOME/cache
+ BUNDLE_USER_CONFIG : $BUNDLE_USER_HOME/config
+ BUNDLE_USER_PLUGIN : $BUNDLE_USER_HOME/plugin
diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1
new file mode 100644
index 0000000000..87a7fe5f2f
--- /dev/null
+++ b/lib/bundler/man/bundle-doctor.1
@@ -0,0 +1,44 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-DOCTOR" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-doctor\fR \- Checks the bundle for common problems
+.
+.SH "SYNOPSIS"
+\fBbundle doctor\fR [\-\-quiet] [\-\-gemfile=GEMFILE]
+.
+.SH "DESCRIPTION"
+Checks your Gemfile and gem environment for common problems\. If issues are detected, Bundler prints them and exits status 1\. Otherwise, Bundler prints a success message and exits status 0\.
+.
+.P
+Examples of common problems caught by bundle\-doctor include:
+.
+.IP "\(bu" 4
+Invalid Bundler settings
+.
+.IP "\(bu" 4
+Mismatched Ruby versions
+.
+.IP "\(bu" 4
+Mismatched platforms
+.
+.IP "\(bu" 4
+Uninstalled gems
+.
+.IP "\(bu" 4
+Missing dependencies
+.
+.IP "" 0
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-quiet\fR
+Only output warnings and errors\.
+.
+.TP
+\fB\-\-gemfile=<gemfile>\fR
+The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project\'s root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\.
+
diff --git a/lib/bundler/man/bundle-doctor.1.ronn b/lib/bundler/man/bundle-doctor.1.ronn
new file mode 100644
index 0000000000..271ee800ad
--- /dev/null
+++ b/lib/bundler/man/bundle-doctor.1.ronn
@@ -0,0 +1,33 @@
+bundle-doctor(1) -- Checks the bundle for common problems
+=========================================================
+
+## SYNOPSIS
+
+`bundle doctor` [--quiet]
+ [--gemfile=GEMFILE]
+
+## DESCRIPTION
+
+Checks your Gemfile and gem environment for common problems. If issues
+are detected, Bundler prints them and exits status 1. Otherwise,
+Bundler prints a success message and exits status 0.
+
+Examples of common problems caught by bundle-doctor include:
+
+* Invalid Bundler settings
+* Mismatched Ruby versions
+* Mismatched platforms
+* Uninstalled gems
+* Missing dependencies
+
+## OPTIONS
+
+* `--quiet`:
+ Only output warnings and errors.
+
+* `--gemfile=<gemfile>`:
+ The location of the Gemfile(5) which Bundler should use. This defaults
+ to a Gemfile(5) in the current working directory. In general, Bundler
+ will assume that the location of the Gemfile(5) is also the project's
+ root and will try to find `Gemfile.lock` and `vendor/cache` relative
+ to this location.
diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1
new file mode 100644
index 0000000000..69adfa7c92
--- /dev/null
+++ b/lib/bundler/man/bundle-exec.1
@@ -0,0 +1,165 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-EXEC" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-exec\fR \- Execute a command in the context of the bundle
+.
+.SH "SYNOPSIS"
+\fBbundle exec\fR [\-\-keep\-file\-descriptors] \fIcommand\fR
+.
+.SH "DESCRIPTION"
+This command executes the command, making all gems specified in the [\fBGemfile(5)\fR][Gemfile(5)] available to \fBrequire\fR in Ruby programs\.
+.
+.P
+Essentially, if you would normally have run something like \fBrspec spec/my_spec\.rb\fR, and you want to use the gems specified in the [\fBGemfile(5)\fR][Gemfile(5)] and installed via bundle install(1) \fIbundle\-install\.1\.html\fR, you should run \fBbundle exec rspec spec/my_spec\.rb\fR\.
+.
+.P
+Note that \fBbundle exec\fR does not require that an executable is available on your shell\'s \fB$PATH\fR\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-keep\-file\-descriptors\fR
+Exec in Ruby 2\.0 began discarding non\-standard file descriptors\. When this flag is passed, exec will revert to the 1\.9 behaviour of passing all file descriptors to the new process\.
+.
+.SH "BUNDLE INSTALL \-\-BINSTUBS"
+If you use the \fB\-\-binstubs\fR flag in bundle install(1) \fIbundle\-install\.1\.html\fR, Bundler will automatically create a directory (which defaults to \fBapp_root/bin\fR) containing all of the executables available from gems in the bundle\.
+.
+.P
+After using \fB\-\-binstubs\fR, \fBbin/rspec spec/my_spec\.rb\fR is identical to \fBbundle exec rspec spec/my_spec\.rb\fR\.
+.
+.SH "ENVIRONMENT MODIFICATIONS"
+\fBbundle exec\fR makes a number of changes to the shell environment, then executes the command you specify in full\.
+.
+.IP "\(bu" 4
+make sure that it\'s still possible to shell out to \fBbundle\fR from inside a command invoked by \fBbundle exec\fR (using \fB$BUNDLE_BIN_PATH\fR)
+.
+.IP "\(bu" 4
+put the directory containing executables (like \fBrails\fR, \fBrspec\fR, \fBrackup\fR) for your bundle on \fB$PATH\fR
+.
+.IP "\(bu" 4
+make sure that if bundler is invoked in the subshell, it uses the same \fBGemfile\fR (by setting \fBBUNDLE_GEMFILE\fR)
+.
+.IP "\(bu" 4
+add \fB\-rbundler/setup\fR to \fB$RUBYOPT\fR, which makes sure that Ruby programs invoked in the subshell can see the gems in the bundle
+.
+.IP "" 0
+.
+.P
+It also modifies Rubygems:
+.
+.IP "\(bu" 4
+disallow loading additional gems not in the bundle
+.
+.IP "\(bu" 4
+modify the \fBgem\fR method to be a no\-op if a gem matching the requirements is in the bundle, and to raise a \fBGem::LoadError\fR if it\'s not
+.
+.IP "\(bu" 4
+Define \fBGem\.refresh\fR to be a no\-op, since the source index is always frozen when using bundler, and to prevent gems from the system leaking into the environment
+.
+.IP "\(bu" 4
+Override \fBGem\.bin_path\fR to use the gems in the bundle, making system executables work
+.
+.IP "\(bu" 4
+Add all gems in the bundle into Gem\.loaded_specs
+.
+.IP "" 0
+.
+.P
+Finally, \fBbundle exec\fR also implicitly modifies \fBGemfile\.lock\fR if the lockfile and the Gemfile do not match\. Bundler needs the Gemfile to determine things such as a gem\'s groups, \fBautorequire\fR, and platforms, etc\., and that information isn\'t stored in the lockfile\. The Gemfile and lockfile must be synced in order to \fBbundle exec\fR successfully, so \fBbundle exec\fR updates the lockfile beforehand\.
+.
+.SS "Loading"
+By default, when attempting to \fBbundle exec\fR to a file with a ruby shebang, Bundler will \fBKernel\.load\fR that file instead of using \fBKernel\.exec\fR\. For the vast majority of cases, this is a performance improvement\. In a rare few cases, this could cause some subtle side\-effects (such as dependence on the exact contents of \fB$0\fR or \fB__FILE__\fR) and the optimization can be disabled by enabling the \fBdisable_exec_load\fR setting\.
+.
+.SS "Shelling out"
+Any Ruby code that opens a subshell (like \fBsystem\fR, backticks, or \fB%x{}\fR) will automatically use the current Bundler environment\. If you need to shell out to a Ruby command that is not part of your current bundle, use the \fBwith_clean_env\fR method with a block\. Any subshells created inside the block will be given the environment present before Bundler was activated\. For example, Homebrew commands run Ruby, but don\'t work inside a bundle:
+.
+.IP "" 4
+.
+.nf
+
+Bundler\.with_clean_env do
+ `brew install wget`
+end
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Using \fBwith_clean_env\fR is also necessary if you are shelling out to a different bundle\. Any Bundler commands run in a subshell will inherit the current Gemfile, so commands that need to run in the context of a different bundle also need to use \fBwith_clean_env\fR\.
+.
+.IP "" 4
+.
+.nf
+
+Bundler\.with_clean_env do
+ Dir\.chdir "/other/bundler/project" do
+ `bundle exec \./script`
+ end
+end
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Bundler provides convenience helpers that wrap \fBsystem\fR and \fBexec\fR, and they can be used like this:
+.
+.IP "" 4
+.
+.nf
+
+Bundler\.clean_system(\'brew install wget\')
+Bundler\.clean_exec(\'brew install wget\')
+.
+.fi
+.
+.IP "" 0
+.
+.SH "RUBYGEMS PLUGINS"
+At present, the Rubygems plugin system requires all files named \fBrubygems_plugin\.rb\fR on the load path of \fIany\fR installed gem when any Ruby code requires \fBrubygems\.rb\fR\. This includes executables installed into the system, like \fBrails\fR, \fBrackup\fR, and \fBrspec\fR\.
+.
+.P
+Since Rubygems plugins can contain arbitrary Ruby code, they commonly end up activating themselves or their dependencies\.
+.
+.P
+For instance, the \fBgemcutter 0\.5\fR gem depended on \fBjson_pure\fR\. If you had that version of gemcutter installed (even if you \fIalso\fR had a newer version without this problem), Rubygems would activate \fBgemcutter 0\.5\fR and \fBjson_pure <latest>\fR\.
+.
+.P
+If your Gemfile(5) also contained \fBjson_pure\fR (or a gem with a dependency on \fBjson_pure\fR), the latest version on your system might conflict with the version in your Gemfile(5), or the snapshot version in your \fBGemfile\.lock\fR\.
+.
+.P
+If this happens, bundler will say:
+.
+.IP "" 4
+.
+.nf
+
+You have already activated json_pure 1\.4\.6 but your Gemfile
+requires json_pure 1\.4\.3\. Consider using bundle exec\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In this situation, you almost certainly want to remove the underlying gem with the problematic gem plugin\. In general, the authors of these plugins (in this case, the \fBgemcutter\fR gem) have released newer versions that are more careful in their plugins\.
+.
+.P
+You can find a list of all the gems containing gem plugins by running
+.
+.IP "" 4
+.
+.nf
+
+ruby \-rrubygems \-e "puts Gem\.find_files(\'rubygems_plugin\.rb\')"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+At the very least, you should remove all but the newest version of each gem plugin, and also remove all gem plugins that you aren\'t using (\fBgem uninstall gem_name\fR)\.
diff --git a/lib/bundler/man/bundle-exec.1.ronn b/lib/bundler/man/bundle-exec.1.ronn
new file mode 100644
index 0000000000..dec3c7cb82
--- /dev/null
+++ b/lib/bundler/man/bundle-exec.1.ronn
@@ -0,0 +1,152 @@
+bundle-exec(1) -- Execute a command in the context of the bundle
+================================================================
+
+## SYNOPSIS
+
+`bundle exec` [--keep-file-descriptors] <command>
+
+## DESCRIPTION
+
+This command executes the command, making all gems specified in the
+[`Gemfile(5)`][Gemfile(5)] available to `require` in Ruby programs.
+
+Essentially, if you would normally have run something like
+`rspec spec/my_spec.rb`, and you want to use the gems specified
+in the [`Gemfile(5)`][Gemfile(5)] and installed via [bundle install(1)](bundle-install.1.html), you
+should run `bundle exec rspec spec/my_spec.rb`.
+
+Note that `bundle exec` does not require that an executable is
+available on your shell's `$PATH`.
+
+## OPTIONS
+
+* `--keep-file-descriptors`:
+ Exec in Ruby 2.0 began discarding non-standard file descriptors. When this
+ flag is passed, exec will revert to the 1.9 behaviour of passing all file
+ descriptors to the new process.
+
+## BUNDLE INSTALL --BINSTUBS
+
+If you use the `--binstubs` flag in [bundle install(1)](bundle-install.1.html), Bundler will
+automatically create a directory (which defaults to `app_root/bin`)
+containing all of the executables available from gems in the bundle.
+
+After using `--binstubs`, `bin/rspec spec/my_spec.rb` is identical
+to `bundle exec rspec spec/my_spec.rb`.
+
+## ENVIRONMENT MODIFICATIONS
+
+`bundle exec` makes a number of changes to the shell environment,
+then executes the command you specify in full.
+
+* make sure that it's still possible to shell out to `bundle`
+ from inside a command invoked by `bundle exec` (using
+ `$BUNDLE_BIN_PATH`)
+* put the directory containing executables (like `rails`, `rspec`,
+ `rackup`) for your bundle on `$PATH`
+* make sure that if bundler is invoked in the subshell, it uses
+ the same `Gemfile` (by setting `BUNDLE_GEMFILE`)
+* add `-rbundler/setup` to `$RUBYOPT`, which makes sure that
+ Ruby programs invoked in the subshell can see the gems in
+ the bundle
+
+It also modifies Rubygems:
+
+* disallow loading additional gems not in the bundle
+* modify the `gem` method to be a no-op if a gem matching
+ the requirements is in the bundle, and to raise a
+ `Gem::LoadError` if it's not
+* Define `Gem.refresh` to be a no-op, since the source
+ index is always frozen when using bundler, and to
+ prevent gems from the system leaking into the environment
+* Override `Gem.bin_path` to use the gems in the bundle,
+ making system executables work
+* Add all gems in the bundle into Gem.loaded_specs
+
+Finally, `bundle exec` also implicitly modifies `Gemfile.lock` if the lockfile
+and the Gemfile do not match. Bundler needs the Gemfile to determine things
+such as a gem's groups, `autorequire`, and platforms, etc., and that
+information isn't stored in the lockfile. The Gemfile and lockfile must be
+synced in order to `bundle exec` successfully, so `bundle exec`
+updates the lockfile beforehand.
+
+### Loading
+
+By default, when attempting to `bundle exec` to a file with a ruby shebang,
+Bundler will `Kernel.load` that file instead of using `Kernel.exec`. For the
+vast majority of cases, this is a performance improvement. In a rare few cases,
+this could cause some subtle side-effects (such as dependence on the exact
+contents of `$0` or `__FILE__`) and the optimization can be disabled by enabling
+the `disable_exec_load` setting.
+
+### Shelling out
+
+Any Ruby code that opens a subshell (like `system`, backticks, or `%x{}`) will
+automatically use the current Bundler environment. If you need to shell out to
+a Ruby command that is not part of your current bundle, use the
+`with_clean_env` method with a block. Any subshells created inside the block
+will be given the environment present before Bundler was activated. For
+example, Homebrew commands run Ruby, but don't work inside a bundle:
+
+ Bundler.with_clean_env do
+ `brew install wget`
+ end
+
+Using `with_clean_env` is also necessary if you are shelling out to a different
+bundle. Any Bundler commands run in a subshell will inherit the current
+Gemfile, so commands that need to run in the context of a different bundle also
+need to use `with_clean_env`.
+
+ Bundler.with_clean_env do
+ Dir.chdir "/other/bundler/project" do
+ `bundle exec ./script`
+ end
+ end
+
+Bundler provides convenience helpers that wrap `system` and `exec`, and they
+can be used like this:
+
+ Bundler.clean_system('brew install wget')
+ Bundler.clean_exec('brew install wget')
+
+
+## RUBYGEMS PLUGINS
+
+At present, the Rubygems plugin system requires all files
+named `rubygems_plugin.rb` on the load path of _any_ installed
+gem when any Ruby code requires `rubygems.rb`. This includes
+executables installed into the system, like `rails`, `rackup`,
+and `rspec`.
+
+Since Rubygems plugins can contain arbitrary Ruby code, they
+commonly end up activating themselves or their dependencies.
+
+For instance, the `gemcutter 0.5` gem depended on `json_pure`.
+If you had that version of gemcutter installed (even if
+you _also_ had a newer version without this problem), Rubygems
+would activate `gemcutter 0.5` and `json_pure <latest>`.
+
+If your Gemfile(5) also contained `json_pure` (or a gem
+with a dependency on `json_pure`), the latest version on
+your system might conflict with the version in your
+Gemfile(5), or the snapshot version in your `Gemfile.lock`.
+
+If this happens, bundler will say:
+
+ You have already activated json_pure 1.4.6 but your Gemfile
+ requires json_pure 1.4.3. Consider using bundle exec.
+
+In this situation, you almost certainly want to remove the
+underlying gem with the problematic gem plugin. In general,
+the authors of these plugins (in this case, the `gemcutter`
+gem) have released newer versions that are more careful in
+their plugins.
+
+You can find a list of all the gems containing gem plugins
+by running
+
+ ruby -rrubygems -e "puts Gem.find_files('rubygems_plugin.rb')"
+
+At the very least, you should remove all but the newest
+version of each gem plugin, and also remove all gem plugins
+that you aren't using (`gem uninstall gem_name`).
diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1
new file mode 100644
index 0000000000..fae5c34e7e
--- /dev/null
+++ b/lib/bundler/man/bundle-gem.1
@@ -0,0 +1,115 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-GEM" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
+.
+.SH "SYNOPSIS"
+\fBbundle gem\fR \fIGEM_NAME\fR \fIOPTIONS\fR
+.
+.SH "DESCRIPTION"
+Generates a directory named \fBGEM_NAME\fR with a \fBRakefile\fR, \fBGEM_NAME\.gemspec\fR, and other supporting files and directories that can be used to develop a rubygem with that name\.
+.
+.P
+Run \fBrake \-T\fR in the resulting project for a list of Rake tasks that can be used to test and publish the gem to rubygems\.org\.
+.
+.P
+The generated project skeleton can be customized with OPTIONS, as explained below\. Note that these options can also be specified via Bundler\'s global configuration file using the following names:
+.
+.IP "\(bu" 4
+\fBgem\.coc\fR
+.
+.IP "\(bu" 4
+\fBgem\.mit\fR
+.
+.IP "\(bu" 4
+\fBgem\.test\fR
+.
+.IP "" 0
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-exe\fR or \fB\-b\fR or \fB\-\-bin\fR
+Specify that Bundler should create a binary executable (as \fBexe/GEM_NAME\fR) in the generated rubygem project\. This binary will also be added to the \fBGEM_NAME\.gemspec\fR manifest\. This behavior is disabled by default\.
+.
+.TP
+\fB\-\-no\-exe\fR
+Do not create a binary (overrides \fB\-\-exe\fR specified in the global config)\.
+.
+.TP
+\fB\-\-coc\fR
+Add a \fBCODE_OF_CONDUCT\.md\fR file to the root of the generated project\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
+.TP
+\fB\-\-no\-coc\fR
+Do not create a \fBCODE_OF_CONDUCT\.md\fR (overrides \fB\-\-coc\fR specified in the global config)\.
+.
+.TP
+\fB\-\-ext\fR
+Add boilerplate for C extension code to the generated project\. This behavior is disabled by default\.
+.
+.TP
+\fB\-\-no\-ext\fR
+Do not add C extension code (overrides \fB\-\-ext\fR specified in the global config)\.
+.
+.TP
+\fB\-\-mit\fR
+Add an MIT license to a \fBLICENSE\.txt\fR file in the root of the generated project\. Your name from the global git config is used for the copyright statement\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
+.TP
+\fB\-\-no\-mit\fR
+Do not create a \fBLICENSE\.txt\fR (overrides \fB\-\-mit\fR specified in the global config)\.
+.
+.TP
+\fB\-t\fR, \fB\-\-test=minitest\fR, \fB\-\-test=rspec\fR, \fB\-\-test=test\-unit\fR
+Specify the test framework that Bundler should use when generating the project\. Acceptable values are \fBminitest\fR, \fBrspec\fR and \fBtest\-unit\fR\. The \fBGEM_NAME\.gemspec\fR will be configured and a skeleton test/spec directory will be created based on this option\. Given no option is specified:
+.
+.IP
+When Bundler is configured to generate tests, this defaults to Bundler\'s global config setting \fBgem\.test\fR\.
+.
+.IP
+When Bundler is configured to not generate tests, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
+.
+.IP
+When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
+.TP
+\fB\-\-ci\fR, \fB\-\-ci=github\fR, \fB\-\-ci=travis\fR, \fB\-\-ci=gitlab\fR, \fB\-\-ci=circle\fR
+Specify the continuous integration service that Bundler should use when generating the project\. Acceptable values are \fBgithub\fR, \fBtravis\fR, \fBgitlab\fR and \fBcircle\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
+.
+.IP
+When Bundler is configured to generate CI files, this defaults to Bundler\'s global config setting \fBgem\.ci\fR\.
+.
+.IP
+When Bundler is configured to not generate CI files, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
+.
+.IP
+When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
+.TP
+\fB\-\-linter\fR, \fB\-\-linter=rubocop\fR, \fB\-\-linter=standard\fR
+Specify the linter and code formatter that Bundler should add to the project\'s development dependencies\. Acceptable values are \fBrubocop\fR and \fBstandard\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
+.
+.IP
+When Bundler is configured to add a linter, this defaults to Bundler\'s global config setting \fBgem\.linter\fR\.
+.
+.IP
+When Bundler is configured not to add a linter, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
+.
+.IP
+When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
+.TP
+\fB\-e\fR, \fB\-\-edit[=EDITOR]\fR
+Open the resulting GEM_NAME\.gemspec in EDITOR, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\.
+.
+.SH "SEE ALSO"
+.
+.IP "\(bu" 4
+bundle config(1) \fIbundle\-config\.1\.html\fR
+.
+.IP "" 0
+
diff --git a/lib/bundler/man/bundle-gem.1.ronn b/lib/bundler/man/bundle-gem.1.ronn
new file mode 100644
index 0000000000..61c741fb24
--- /dev/null
+++ b/lib/bundler/man/bundle-gem.1.ronn
@@ -0,0 +1,117 @@
+bundle-gem(1) -- Generate a project skeleton for creating a rubygem
+====================================================================
+
+## SYNOPSIS
+
+`bundle gem` <GEM_NAME> [OPTIONS]
+
+## DESCRIPTION
+
+Generates a directory named `GEM_NAME` with a `Rakefile`, `GEM_NAME.gemspec`,
+and other supporting files and directories that can be used to develop a
+rubygem with that name.
+
+Run `rake -T` in the resulting project for a list of Rake tasks that can be used
+to test and publish the gem to rubygems.org.
+
+The generated project skeleton can be customized with OPTIONS, as explained
+below. Note that these options can also be specified via Bundler's global
+configuration file using the following names:
+
+* `gem.coc`
+* `gem.mit`
+* `gem.test`
+
+## OPTIONS
+
+* `--exe` or `-b` or `--bin`:
+ Specify that Bundler should create a binary executable (as `exe/GEM_NAME`)
+ in the generated rubygem project. This binary will also be added to the
+ `GEM_NAME.gemspec` manifest. This behavior is disabled by default.
+
+* `--no-exe`:
+ Do not create a binary (overrides `--exe` specified in the global config).
+
+* `--coc`:
+ Add a `CODE_OF_CONDUCT.md` file to the root of the generated project. If
+ this option is unspecified, an interactive prompt will be displayed and the
+ answer will be saved in Bundler's global config for future `bundle gem` use.
+
+* `--no-coc`:
+ Do not create a `CODE_OF_CONDUCT.md` (overrides `--coc` specified in the
+ global config).
+
+* `--ext`:
+ Add boilerplate for C extension code to the generated project. This behavior
+ is disabled by default.
+
+* `--no-ext`:
+ Do not add C extension code (overrides `--ext` specified in the global
+ config).
+
+* `--mit`:
+ Add an MIT license to a `LICENSE.txt` file in the root of the generated
+ project. Your name from the global git config is used for the copyright
+ statement. If this option is unspecified, an interactive prompt will be
+ displayed and the answer will be saved in Bundler's global config for future
+ `bundle gem` use.
+
+* `--no-mit`:
+ Do not create a `LICENSE.txt` (overrides `--mit` specified in the global
+ config).
+
+* `-t`, `--test=minitest`, `--test=rspec`, `--test=test-unit`:
+ Specify the test framework that Bundler should use when generating the
+ project. Acceptable values are `minitest`, `rspec` and `test-unit`. The
+ `GEM_NAME.gemspec` will be configured and a skeleton test/spec directory will
+ be created based on this option. Given no option is specified:
+
+ When Bundler is configured to generate tests, this defaults to Bundler's
+ global config setting `gem.test`.
+
+ When Bundler is configured to not generate tests, an interactive prompt will
+ be displayed and the answer will be used for the current rubygem project.
+
+ When Bundler is unconfigured, an interactive prompt will be displayed and
+ the answer will be saved in Bundler's global config for future `bundle gem`
+ use.
+
+* `--ci`, `--ci=github`, `--ci=travis`, `--ci=gitlab`, `--ci=circle`:
+ Specify the continuous integration service that Bundler should use when
+ generating the project. Acceptable values are `github`, `travis`, `gitlab`
+ and `circle`. A configuration file will be generated in the project directory.
+ Given no option is specified:
+
+ When Bundler is configured to generate CI files, this defaults to Bundler's
+ global config setting `gem.ci`.
+
+ When Bundler is configured to not generate CI files, an interactive prompt
+ will be displayed and the answer will be used for the current rubygem project.
+
+ When Bundler is unconfigured, an interactive prompt will be displayed and
+ the answer will be saved in Bundler's global config for future `bundle gem`
+ use.
+
+* `--linter`, `--linter=rubocop`, `--linter=standard`:
+ Specify the linter and code formatter that Bundler should add to the
+ project's development dependencies. Acceptable values are `rubocop` and
+ `standard`. A configuration file will be generated in the project directory.
+ Given no option is specified:
+
+ When Bundler is configured to add a linter, this defaults to Bundler's
+ global config setting `gem.linter`.
+
+ When Bundler is configured not to add a linter, an interactive prompt
+ will be displayed and the answer will be used for the current rubygem project.
+
+ When Bundler is unconfigured, an interactive prompt will be displayed and
+ the answer will be saved in Bundler's global config for future `bundle gem`
+ use.
+
+* `-e`, `--edit[=EDITOR]`:
+ Open the resulting GEM_NAME.gemspec in EDITOR, or the default editor if not
+ specified. The default is `$BUNDLER_EDITOR`, `$VISUAL`, or `$EDITOR`.
+
+## SEE ALSO
+
+* [bundle config(1)](bundle-config.1.html)
diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1
new file mode 100644
index 0000000000..9e1400ec56
--- /dev/null
+++ b/lib/bundler/man/bundle-info.1
@@ -0,0 +1,20 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INFO" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-info\fR \- Show information for the given gem in your bundle
+.
+.SH "SYNOPSIS"
+\fBbundle info\fR [GEM] [\-\-path]
+.
+.SH "DESCRIPTION"
+Print the basic information about the provided GEM such as homepage, version, path and summary\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-path\fR
+Print the path of the given gem
+
diff --git a/lib/bundler/man/bundle-info.1.ronn b/lib/bundler/man/bundle-info.1.ronn
new file mode 100644
index 0000000000..47e457aa3c
--- /dev/null
+++ b/lib/bundler/man/bundle-info.1.ronn
@@ -0,0 +1,17 @@
+bundle-info(1) -- Show information for the given gem in your bundle
+=========================================================================
+
+## SYNOPSIS
+
+`bundle info` [GEM]
+ [--path]
+
+## DESCRIPTION
+
+Print the basic information about the provided GEM such as homepage, version,
+path and summary.
+
+## OPTIONS
+
+* `--path`:
+Print the path of the given gem
diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1
new file mode 100644
index 0000000000..612d16031c
--- /dev/null
+++ b/lib/bundler/man/bundle-init.1
@@ -0,0 +1,25 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INIT" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
+.
+.SH "SYNOPSIS"
+\fBbundle init\fR [\-\-gemspec=FILE]
+.
+.SH "DESCRIPTION"
+Init generates a default [\fBGemfile(5)\fR][Gemfile(5)] in the current working directory\. When adding a [\fBGemfile(5)\fR][Gemfile(5)] to a gem with a gemspec, the \fB\-\-gemspec\fR option will automatically add each dependency listed in the gemspec file to the newly created [\fBGemfile(5)\fR][Gemfile(5)]\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-gemspec\fR
+Use the specified \.gemspec to create the [\fBGemfile(5)\fR][Gemfile(5)]
+.
+.SH "FILES"
+Included in the default [\fBGemfile(5)\fR][Gemfile(5)] generated is the line \fB# frozen_string_literal: true\fR\. This is a magic comment supported for the first time in Ruby 2\.3\. The presence of this line results in all string literals in the file being implicitly frozen\.
+.
+.SH "SEE ALSO"
+Gemfile(5) \fIhttps://bundler\.io/man/gemfile\.5\.html\fR
diff --git a/lib/bundler/man/bundle-init.1.ronn b/lib/bundler/man/bundle-init.1.ronn
new file mode 100644
index 0000000000..9d3d97deea
--- /dev/null
+++ b/lib/bundler/man/bundle-init.1.ronn
@@ -0,0 +1,29 @@
+bundle-init(1) -- Generates a Gemfile into the current working directory
+========================================================================
+
+## SYNOPSIS
+
+`bundle init` [--gemspec=FILE]
+
+## DESCRIPTION
+
+Init generates a default [`Gemfile(5)`][Gemfile(5)] in the current working directory. When
+adding a [`Gemfile(5)`][Gemfile(5)] to a gem with a gemspec, the `--gemspec` option will
+automatically add each dependency listed in the gemspec file to the newly
+created [`Gemfile(5)`][Gemfile(5)].
+
+## OPTIONS
+
+* `--gemspec`:
+ Use the specified .gemspec to create the [`Gemfile(5)`][Gemfile(5)]
+
+## FILES
+
+Included in the default [`Gemfile(5)`][Gemfile(5)]
+generated is the line `# frozen_string_literal: true`. This is a magic comment
+supported for the first time in Ruby 2.3. The presence of this line
+results in all string literals in the file being implicitly frozen.
+
+## SEE ALSO
+
+[Gemfile(5)](https://bundler.io/man/gemfile.5.html)
diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1
new file mode 100644
index 0000000000..ded4d6d64b
--- /dev/null
+++ b/lib/bundler/man/bundle-inject.1
@@ -0,0 +1,33 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INJECT" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
+.
+.SH "SYNOPSIS"
+\fBbundle inject\fR [GEM] [VERSION]
+.
+.SH "DESCRIPTION"
+Adds the named gem(s) with their version requirements to the resolved [\fBGemfile(5)\fR][Gemfile(5)]\.
+.
+.P
+This command will add the gem to both your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock if it isn\'t listed yet\.
+.
+.P
+Example:
+.
+.IP "" 4
+.
+.nf
+
+bundle install
+bundle inject \'rack\' \'> 0\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+This will inject the \'rack\' gem with a version greater than 0 in your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock
diff --git a/lib/bundler/man/bundle-inject.1.ronn b/lib/bundler/man/bundle-inject.1.ronn
new file mode 100644
index 0000000000..f454341896
--- /dev/null
+++ b/lib/bundler/man/bundle-inject.1.ronn
@@ -0,0 +1,22 @@
+bundle-inject(1) -- Add named gem(s) with version requirements to Gemfile
+=========================================================================
+
+## SYNOPSIS
+
+`bundle inject` [GEM] [VERSION]
+
+## DESCRIPTION
+
+Adds the named gem(s) with their version requirements to the resolved
+[`Gemfile(5)`][Gemfile(5)].
+
+This command will add the gem to both your [`Gemfile(5)`][Gemfile(5)] and Gemfile.lock if it
+isn't listed yet.
+
+Example:
+
+ bundle install
+ bundle inject 'rack' '> 0'
+
+This will inject the 'rack' gem with a version greater than 0 in your
+[`Gemfile(5)`][Gemfile(5)] and Gemfile.lock
diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1
new file mode 100644
index 0000000000..6ccf100b4e
--- /dev/null
+++ b/lib/bundler/man/bundle-install.1
@@ -0,0 +1,338 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INSTALL" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
+.
+.SH "SYNOPSIS"
+\fBbundle install\fR [\-\-binstubs[=DIRECTORY]] [\-\-clean] [\-\-deployment] [\-\-frozen] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-no\-cache] [\-\-no\-prune] [\-\-path PATH] [\-\-quiet] [\-\-redownload] [\-\-retry=NUMBER] [\-\-shebang] [\-\-standalone[=GROUP[ GROUP\.\.\.]]] [\-\-system] [\-\-trust\-policy=POLICY] [\-\-with=GROUP[ GROUP\.\.\.]] [\-\-without=GROUP[ GROUP\.\.\.]]
+.
+.SH "DESCRIPTION"
+Install the gems specified in your Gemfile(5)\. If this is the first time you run bundle install (and a \fBGemfile\.lock\fR does not exist), Bundler will fetch all remote sources, resolve dependencies and install all needed gems\.
+.
+.P
+If a \fBGemfile\.lock\fR does exist, and you have not updated your Gemfile(5), Bundler will fetch all remote sources, but use the dependencies specified in the \fBGemfile\.lock\fR instead of resolving dependencies\.
+.
+.P
+If a \fBGemfile\.lock\fR does exist, and you have updated your Gemfile(5), Bundler will use the dependencies in the \fBGemfile\.lock\fR for all gems that you did not update, but will re\-resolve the dependencies of gems that you did update\. You can find more information about this update process below under \fICONSERVATIVE UPDATING\fR\.
+.
+.SH "OPTIONS"
+The \fB\-\-clean\fR, \fB\-\-deployment\fR, \fB\-\-frozen\fR, \fB\-\-no\-prune\fR, \fB\-\-path\fR, \fB\-\-shebang\fR, \fB\-\-system\fR, \fB\-\-without\fR and \fB\-\-with\fR options are deprecated because they only make sense if they are applied to every subsequent \fBbundle install\fR run automatically and that requires \fBbundler\fR to silently remember them\. Since \fBbundler\fR will no longer remember CLI flags in future versions, \fBbundle config\fR (see bundle\-config(1)) should be used to apply them permanently\.
+.
+.TP
+\fB\-\-binstubs[=<directory>]\fR
+Binstubs are scripts that wrap around executables\. Bundler creates a small Ruby file (a binstub) that loads Bundler, runs the command, and puts it in \fBbin/\fR\. This lets you link the binstub inside of an application to the exact gem version the application needs\.
+.
+.IP
+Creates a directory (defaults to \fB~/bin\fR) and places any executables from the gem there\. These executables run in Bundler\'s context\. If used, you might add this directory to your environment\'s \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\.
+.
+.TP
+\fB\-\-clean\fR
+On finishing the installation Bundler is going to remove any gems not present in the current Gemfile(5)\. Don\'t worry, gems currently in use will not be removed\.
+.
+.IP
+This option is deprecated in favor of the \fBclean\fR setting\.
+.
+.TP
+\fB\-\-deployment\fR
+In \fIdeployment mode\fR, Bundler will \'roll\-out\' the bundle for production or CI use\. Please check carefully if you want to have this option enabled in your development environment\.
+.
+.IP
+This option is deprecated in favor of the \fBdeployment\fR setting\.
+.
+.TP
+\fB\-\-redownload\fR
+Force download every gem, even if the required versions are already available locally\.
+.
+.TP
+\fB\-\-frozen\fR
+Do not allow the Gemfile\.lock to be updated after this install\. Exits non\-zero if there are going to be changes to the Gemfile\.lock\.
+.
+.IP
+This option is deprecated in favor of the \fBfrozen\fR setting\.
+.
+.TP
+\fB\-\-full\-index\fR
+Bundler will not call Rubygems\' API endpoint (default) but download and cache a (currently big) index file of all gems\. Performance can be improved for large bundles that seldom change by enabling this option\.
+.
+.TP
+\fB\-\-gemfile=<gemfile>\fR
+The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project\'s root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\.
+.
+.TP
+\fB\-\-jobs=[<number>]\fR, \fB\-j[<number>]\fR
+The maximum number of parallel download and install jobs\. The default is \fB1\fR\.
+.
+.TP
+\fB\-\-local\fR
+Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if an appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
+.
+.TP
+\fB\-\-no\-cache\fR
+Do not update the cache in \fBvendor/cache\fR with the newly bundled gems\. This does not remove any gems in the cache but keeps the newly bundled gems from being cached during the install\.
+.
+.TP
+\fB\-\-no\-prune\fR
+Don\'t remove stale gems from the cache when the installation finishes\.
+.
+.IP
+This option is deprecated in favor of the \fBno_prune\fR setting\.
+.
+.TP
+\fB\-\-path=<path>\fR
+The location to install the specified gems to\. This defaults to Rubygems\' setting\. Bundler shares this location with Rubygems, \fBgem install \.\.\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \.\.\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
+.
+.IP
+This option is deprecated in favor of the \fBpath\fR setting\.
+.
+.TP
+\fB\-\-quiet\fR
+Do not print progress information to the standard output\. Instead, Bundler will exit using a status code (\fB$?\fR)\.
+.
+.TP
+\fB\-\-retry=[<number>]\fR
+Retry failed network or git requests for \fInumber\fR times\.
+.
+.TP
+\fB\-\-shebang=<ruby\-executable>\fR
+Uses the specified ruby executable (usually \fBruby\fR) to execute the scripts created with \fB\-\-binstubs\fR\. In addition, if you use \fB\-\-binstubs\fR together with \fB\-\-shebang jruby\fR these executables will be changed to execute \fBjruby\fR instead\.
+.
+.IP
+This option is deprecated in favor of the \fBshebang\fR setting\.
+.
+.TP
+\fB\-\-standalone[=<list>]\fR
+Makes a bundle that can work without depending on Rubygems or Bundler at runtime\. A space separated list of groups to install has to be specified\. Bundler creates a directory named \fBbundle\fR and installs the bundle there\. It also generates a \fBbundle/bundler/setup\.rb\fR file to replace Bundler\'s own setup in the manner required\. Using this option implicitly sets \fBpath\fR, which is a [remembered option][REMEMBERED OPTIONS]\.
+.
+.TP
+\fB\-\-system\fR
+Installs the gems specified in the bundle to the system\'s Rubygems location\. This overrides any previous configuration of \fB\-\-path\fR\.
+.
+.IP
+This option is deprecated in favor of the \fBsystem\fR setting\.
+.
+.TP
+\fB\-\-trust\-policy=[<policy>]\fR
+Apply the Rubygems security policy \fIpolicy\fR, where policy is one of \fBHighSecurity\fR, \fBMediumSecurity\fR, \fBLowSecurity\fR, \fBAlmostNoSecurity\fR, or \fBNoSecurity\fR\. For more details, please see the Rubygems signing documentation linked below in \fISEE ALSO\fR\.
+.
+.TP
+\fB\-\-with=<list>\fR
+A space\-separated list of groups referencing gems to install\. If an optional group is given it is installed\. If a group is given that is in the remembered list of groups given to \-\-without, it is removed from that list\.
+.
+.IP
+This option is deprecated in favor of the \fBwith\fR setting\.
+.
+.TP
+\fB\-\-without=<list>\fR
+A space\-separated list of groups referencing gems to skip during installation\. If a group is given that is in the remembered list of groups given to \-\-with, it is removed from that list\.
+.
+.IP
+This option is deprecated in favor of the \fBwithout\fR setting\.
+.
+.SH "DEPLOYMENT MODE"
+Bundler\'s defaults are optimized for development\. To switch to defaults optimized for deployment and for CI, use the \fB\-\-deployment\fR flag\. Do not activate deployment mode on development machines, as it will cause an error when the Gemfile(5) is modified\.
+.
+.IP "1." 4
+A \fBGemfile\.lock\fR is required\.
+.
+.IP
+To ensure that the same versions of the gems you developed with and tested with are also used in deployments, a \fBGemfile\.lock\fR is required\.
+.
+.IP
+This is mainly to ensure that you remember to check your \fBGemfile\.lock\fR into version control\.
+.
+.IP "2." 4
+The \fBGemfile\.lock\fR must be up to date
+.
+.IP
+In development, you can modify your Gemfile(5) and re\-run \fBbundle install\fR to \fIconservatively update\fR your \fBGemfile\.lock\fR snapshot\.
+.
+.IP
+In deployment, your \fBGemfile\.lock\fR should be up\-to\-date with changes made in your Gemfile(5)\.
+.
+.IP "3." 4
+Gems are installed to \fBvendor/bundle\fR not your default system location
+.
+.IP
+In development, it\'s convenient to share the gems used in your application with other applications and other scripts that run on the system\.
+.
+.IP
+In deployment, isolation is a more important default\. In addition, the user deploying the application may not have permission to install gems to the system, or the web server may not have permission to read them\.
+.
+.IP
+As a result, \fBbundle install \-\-deployment\fR installs gems to the \fBvendor/bundle\fR directory in the application\. This may be overridden using the \fB\-\-path\fR option\.
+.
+.IP "" 0
+.
+.SH "SUDO USAGE"
+By default, Bundler installs gems to the same location as \fBgem install\fR\.
+.
+.P
+In some cases, that location may not be writable by your Unix user\. In that case, Bundler will stage everything in a temporary directory, then ask you for your \fBsudo\fR password in order to copy the gems into their system location\.
+.
+.P
+From your perspective, this is identical to installing the gems directly into the system\.
+.
+.P
+You should never use \fBsudo bundle install\fR\. This is because several other steps in \fBbundle install\fR must be performed as the current user:
+.
+.IP "\(bu" 4
+Updating your \fBGemfile\.lock\fR
+.
+.IP "\(bu" 4
+Updating your \fBvendor/cache\fR, if necessary
+.
+.IP "\(bu" 4
+Checking out private git repositories using your user\'s SSH keys
+.
+.IP "" 0
+.
+.P
+Of these three, the first two could theoretically be performed by \fBchown\fRing the resulting files to \fB$SUDO_USER\fR\. The third, however, can only be performed by invoking the \fBgit\fR command as the current user\. Therefore, git gems are downloaded and installed into \fB~/\.bundle\fR rather than $GEM_HOME or $BUNDLE_PATH\.
+.
+.P
+As a result, you should run \fBbundle install\fR as the current user, and Bundler will ask for your password if it is needed to put the gems into their final location\.
+.
+.SH "INSTALLING GROUPS"
+By default, \fBbundle install\fR will install all gems in all groups in your Gemfile(5), except those declared for a different platform\.
+.
+.P
+However, you can explicitly tell Bundler to skip installing certain groups with the \fB\-\-without\fR option\. This option takes a space\-separated list of groups\.
+.
+.P
+While the \fB\-\-without\fR option will skip \fIinstalling\fR the gems in the specified groups, it will still \fIdownload\fR those gems and use them to resolve the dependencies of every gem in your Gemfile(5)\.
+.
+.P
+This is so that installing a different set of groups on another machine (such as a production server) will not change the gems and versions that you have already developed and tested against\.
+.
+.P
+\fBBundler offers a rock\-solid guarantee that the third\-party code you are running in development and testing is also the third\-party code you are running in production\. You can choose to exclude some of that code in different environments, but you will never be caught flat\-footed by different versions of third\-party code being used in different environments\.\fR
+.
+.P
+For a simple illustration, consider the following Gemfile(5):
+.
+.IP "" 4
+.
+.nf
+
+source \'https://rubygems\.org\'
+
+gem \'sinatra\'
+
+group :production do
+ gem \'rack\-perftools\-profiler\'
+end
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In this case, \fBsinatra\fR depends on any version of Rack (\fB>= 1\.0\fR), while \fBrack\-perftools\-profiler\fR depends on 1\.x (\fB~> 1\.0\fR)\.
+.
+.P
+When you run \fBbundle install \-\-without production\fR in development, we look at the dependencies of \fBrack\-perftools\-profiler\fR as well\. That way, you do not spend all your time developing against Rack 2\.0, using new APIs unavailable in Rack 1\.x, only to have Bundler switch to Rack 1\.2 when the \fBproduction\fR group \fIis\fR used\.
+.
+.P
+This should not cause any problems in practice, because we do not attempt to \fBinstall\fR the gems in the excluded groups, and only evaluate as part of the dependency resolution process\.
+.
+.P
+This also means that you cannot include different versions of the same gem in different groups, because doing so would result in different sets of dependencies used in development and production\. Because of the vagaries of the dependency resolution process, this usually affects more than the gems you list in your Gemfile(5), and can (surprisingly) radically change the gems you are using\.
+.
+.SH "THE GEMFILE\.LOCK"
+When you run \fBbundle install\fR, Bundler will persist the full names and versions of all gems that you used (including dependencies of the gems specified in the Gemfile(5)) into a file called \fBGemfile\.lock\fR\.
+.
+.P
+Bundler uses this file in all subsequent calls to \fBbundle install\fR, which guarantees that you always use the same exact code, even as your application moves across machines\.
+.
+.P
+Because of the way dependency resolution works, even a seemingly small change (for instance, an update to a point\-release of a dependency of a gem in your Gemfile(5)) can result in radically different gems being needed to satisfy all dependencies\.
+.
+.P
+As a result, you \fBSHOULD\fR check your \fBGemfile\.lock\fR into version control, in both applications and gems\. If you do not, every machine that checks out your repository (including your production server) will resolve all dependencies again, which will result in different versions of third\-party code being used if \fBany\fR of the gems in the Gemfile(5) or any of their dependencies have been updated\.
+.
+.P
+When Bundler first shipped, the \fBGemfile\.lock\fR was included in the \fB\.gitignore\fR file included with generated gems\. Over time, however, it became clear that this practice forces the pain of broken dependencies onto new contributors, while leaving existing contributors potentially unaware of the problem\. Since \fBbundle install\fR is usually the first step towards a contribution, the pain of broken dependencies would discourage new contributors from contributing\. As a result, we have revised our guidance for gem authors to now recommend checking in the lock for gems\.
+.
+.SH "CONSERVATIVE UPDATING"
+When you make a change to the Gemfile(5) and then run \fBbundle install\fR, Bundler will update only the gems that you modified\.
+.
+.P
+In other words, if a gem that you \fBdid not modify\fR worked before you called \fBbundle install\fR, it will continue to use the exact same versions of all dependencies as it used before the update\.
+.
+.P
+Let\'s take a look at an example\. Here\'s your original Gemfile(5):
+.
+.IP "" 4
+.
+.nf
+
+source \'https://rubygems\.org\'
+
+gem \'actionpack\', \'2\.3\.8\'
+gem \'activemerchant\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In this case, both \fBactionpack\fR and \fBactivemerchant\fR depend on \fBactivesupport\fR\. The \fBactionpack\fR gem depends on \fBactivesupport 2\.3\.8\fR and \fBrack ~> 1\.1\.0\fR, while the \fBactivemerchant\fR gem depends on \fBactivesupport >= 2\.3\.2\fR, \fBbraintree >= 2\.0\.0\fR, and \fBbuilder >= 2\.0\.0\fR\.
+.
+.P
+When the dependencies are first resolved, Bundler will select \fBactivesupport 2\.3\.8\fR, which satisfies the requirements of both gems in your Gemfile(5)\.
+.
+.P
+Next, you modify your Gemfile(5) to:
+.
+.IP "" 4
+.
+.nf
+
+source \'https://rubygems\.org\'
+
+gem \'actionpack\', \'3\.0\.0\.rc\'
+gem \'activemerchant\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+The \fBactionpack 3\.0\.0\.rc\fR gem has a number of new dependencies, and updates the \fBactivesupport\fR dependency to \fB= 3\.0\.0\.rc\fR and the \fBrack\fR dependency to \fB~> 1\.2\.1\fR\.
+.
+.P
+When you run \fBbundle install\fR, Bundler notices that you changed the \fBactionpack\fR gem, but not the \fBactivemerchant\fR gem\. It evaluates the gems currently being used to satisfy its requirements:
+.
+.TP
+\fBactivesupport 2\.3\.8\fR
+also used to satisfy a dependency in \fBactivemerchant\fR, which is not being updated
+.
+.TP
+\fBrack ~> 1\.1\.0\fR
+not currently being used to satisfy another dependency
+.
+.P
+Because you did not explicitly ask to update \fBactivemerchant\fR, you would not expect it to suddenly stop working after updating \fBactionpack\fR\. However, satisfying the new \fBactivesupport 3\.0\.0\.rc\fR dependency of actionpack requires updating one of its dependencies\.
+.
+.P
+Even though \fBactivemerchant\fR declares a very loose dependency that theoretically matches \fBactivesupport 3\.0\.0\.rc\fR, Bundler treats gems in your Gemfile(5) that have not changed as an atomic unit together with their dependencies\. In this case, the \fBactivemerchant\fR dependency is treated as \fBactivemerchant 1\.7\.1 + activesupport 2\.3\.8\fR, so \fBbundle install\fR will report that it cannot update \fBactionpack\fR\.
+.
+.P
+To explicitly update \fBactionpack\fR, including its dependencies which other gems in the Gemfile(5) still depend on, run \fBbundle update actionpack\fR (see \fBbundle update(1)\fR)\.
+.
+.P
+\fBSummary\fR: In general, after making a change to the Gemfile(5) , you should first try to run \fBbundle install\fR, which will guarantee that no other gem in the Gemfile(5) is impacted by the change\. If that does not work, run bundle update(1) \fIbundle\-update\.1\.html\fR\.
+.
+.SH "SEE ALSO"
+.
+.IP "\(bu" 4
+Gem install docs \fIhttp://guides\.rubygems\.org/rubygems\-basics/#installing\-gems\fR
+.
+.IP "\(bu" 4
+Rubygems signing docs \fIhttp://guides\.rubygems\.org/security/\fR
+.
+.IP "" 0
+
diff --git a/lib/bundler/man/bundle-install.1.ronn b/lib/bundler/man/bundle-install.1.ronn
new file mode 100644
index 0000000000..5ea777f1d4
--- /dev/null
+++ b/lib/bundler/man/bundle-install.1.ronn
@@ -0,0 +1,405 @@
+bundle-install(1) -- Install the dependencies specified in your Gemfile
+=======================================================================
+
+## SYNOPSIS
+
+`bundle install` [--binstubs[=DIRECTORY]]
+ [--clean]
+ [--deployment]
+ [--frozen]
+ [--full-index]
+ [--gemfile=GEMFILE]
+ [--jobs=NUMBER]
+ [--local]
+ [--no-cache]
+ [--no-prune]
+ [--path PATH]
+ [--quiet]
+ [--redownload]
+ [--retry=NUMBER]
+ [--shebang]
+ [--standalone[=GROUP[ GROUP...]]]
+ [--system]
+ [--trust-policy=POLICY]
+ [--with=GROUP[ GROUP...]]
+ [--without=GROUP[ GROUP...]]
+
+## DESCRIPTION
+
+Install the gems specified in your Gemfile(5). If this is the first
+time you run bundle install (and a `Gemfile.lock` does not exist),
+Bundler will fetch all remote sources, resolve dependencies and
+install all needed gems.
+
+If a `Gemfile.lock` does exist, and you have not updated your Gemfile(5),
+Bundler will fetch all remote sources, but use the dependencies
+specified in the `Gemfile.lock` instead of resolving dependencies.
+
+If a `Gemfile.lock` does exist, and you have updated your Gemfile(5),
+Bundler will use the dependencies in the `Gemfile.lock` for all gems
+that you did not update, but will re-resolve the dependencies of
+gems that you did update. You can find more information about this
+update process below under [CONSERVATIVE UPDATING][].
+
+## OPTIONS
+
+The `--clean`, `--deployment`, `--frozen`, `--no-prune`, `--path`, `--shebang`,
+`--system`, `--without` and `--with` options are deprecated because they only
+make sense if they are applied to every subsequent `bundle install` run
+automatically and that requires `bundler` to silently remember them. Since
+`bundler` will no longer remember CLI flags in future versions, `bundle config`
+(see bundle-config(1)) should be used to apply them permanently.
+
+* `--binstubs[=<directory>]`:
+ Binstubs are scripts that wrap around executables. Bundler creates a small Ruby
+ file (a binstub) that loads Bundler, runs the command, and puts it in `bin/`.
+ This lets you link the binstub inside of an application to the exact gem
+ version the application needs.
+
+ Creates a directory (defaults to `~/bin`) and places any executables from the
+ gem there. These executables run in Bundler's context. If used, you might add
+ this directory to your environment's `PATH` variable. For instance, if the
+ `rails` gem comes with a `rails` executable, this flag will create a
+ `bin/rails` executable that ensures that all referred dependencies will be
+ resolved using the bundled gems.
+
+* `--clean`:
+ On finishing the installation Bundler is going to remove any gems not present
+ in the current Gemfile(5). Don't worry, gems currently in use will not be
+ removed.
+
+ This option is deprecated in favor of the `clean` setting.
+
+* `--deployment`:
+ In [deployment mode][DEPLOYMENT MODE], Bundler will 'roll-out' the bundle for
+ production or CI use. Please check carefully if you want to have this option
+ enabled in your development environment.
+
+ This option is deprecated in favor of the `deployment` setting.
+
+* `--redownload`:
+ Force download every gem, even if the required versions are already available
+ locally.
+
+* `--frozen`:
+ Do not allow the Gemfile.lock to be updated after this install. Exits
+ non-zero if there are going to be changes to the Gemfile.lock.
+
+ This option is deprecated in favor of the `frozen` setting.
+
+* `--full-index`:
+ Bundler will not call Rubygems' API endpoint (default) but download and cache
+ a (currently big) index file of all gems. Performance can be improved for
+ large bundles that seldom change by enabling this option.
+
+* `--gemfile=<gemfile>`:
+ The location of the Gemfile(5) which Bundler should use. This defaults
+ to a Gemfile(5) in the current working directory. In general, Bundler
+ will assume that the location of the Gemfile(5) is also the project's
+ root and will try to find `Gemfile.lock` and `vendor/cache` relative
+ to this location.
+
+* `--jobs=[<number>]`, `-j[<number>]`:
+ The maximum number of parallel download and install jobs. The default
+ is `1`.
+
+* `--local`:
+ Do not attempt to connect to `rubygems.org`. Instead, Bundler will use the
+ gems already present in Rubygems' cache or in `vendor/cache`. Note that if an
+ appropriate platform-specific gem exists on `rubygems.org` it will not be
+ found.
+
+* `--no-cache`:
+ Do not update the cache in `vendor/cache` with the newly bundled gems. This
+ does not remove any gems in the cache but keeps the newly bundled gems from
+ being cached during the install.
+
+* `--no-prune`:
+ Don't remove stale gems from the cache when the installation finishes.
+
+ This option is deprecated in favor of the `no_prune` setting.
+
+* `--path=<path>`:
+ The location to install the specified gems to. This defaults to Rubygems'
+ setting. Bundler shares this location with Rubygems, `gem install ...` will
+ have gem installed there, too. Therefore, gems installed without a
+ `--path ...` setting will show up by calling `gem list`. Accordingly, gems
+ installed to other locations will not get listed.
+
+ This option is deprecated in favor of the `path` setting.
+
+* `--quiet`:
+ Do not print progress information to the standard output. Instead, Bundler
+ will exit using a status code (`$?`).
+
+* `--retry=[<number>]`:
+ Retry failed network or git requests for <number> times.
+
+* `--shebang=<ruby-executable>`:
+ Uses the specified ruby executable (usually `ruby`) to execute the scripts
+ created with `--binstubs`. In addition, if you use `--binstubs` together with
+ `--shebang jruby` these executables will be changed to execute `jruby`
+ instead.
+
+ This option is deprecated in favor of the `shebang` setting.
+
+* `--standalone[=<list>]`:
+ Makes a bundle that can work without depending on Rubygems or Bundler at
+ runtime. A space separated list of groups to install has to be specified.
+ Bundler creates a directory named `bundle` and installs the bundle there. It
+ also generates a `bundle/bundler/setup.rb` file to replace Bundler's own setup
+ in the manner required. Using this option implicitly sets `path`, which is a
+ [remembered option][REMEMBERED OPTIONS].
+
+* `--system`:
+ Installs the gems specified in the bundle to the system's Rubygems location.
+ This overrides any previous configuration of `--path`.
+
+ This option is deprecated in favor of the `system` setting.
+
+* `--trust-policy=[<policy>]`:
+ Apply the Rubygems security policy <policy>, where policy is one of
+ `HighSecurity`, `MediumSecurity`, `LowSecurity`, `AlmostNoSecurity`, or
+ `NoSecurity`. For more details, please see the Rubygems signing documentation
+ linked below in [SEE ALSO][].
+
+* `--with=<list>`:
+ A space-separated list of groups referencing gems to install. If an
+ optional group is given it is installed. If a group is given that is
+ in the remembered list of groups given to --without, it is removed
+ from that list.
+
+ This option is deprecated in favor of the `with` setting.
+
+* `--without=<list>`:
+ A space-separated list of groups referencing gems to skip during installation.
+ If a group is given that is in the remembered list of groups given
+ to --with, it is removed from that list.
+
+ This option is deprecated in favor of the `without` setting.
+
+## DEPLOYMENT MODE
+
+Bundler's defaults are optimized for development. To switch to
+defaults optimized for deployment and for CI, use the `--deployment`
+flag. Do not activate deployment mode on development machines, as it
+will cause an error when the Gemfile(5) is modified.
+
+1. A `Gemfile.lock` is required.
+
+ To ensure that the same versions of the gems you developed with
+ and tested with are also used in deployments, a `Gemfile.lock`
+ is required.
+
+ This is mainly to ensure that you remember to check your
+ `Gemfile.lock` into version control.
+
+2. The `Gemfile.lock` must be up to date
+
+ In development, you can modify your Gemfile(5) and re-run
+ `bundle install` to [conservatively update][CONSERVATIVE UPDATING]
+ your `Gemfile.lock` snapshot.
+
+ In deployment, your `Gemfile.lock` should be up-to-date with
+ changes made in your Gemfile(5).
+
+3. Gems are installed to `vendor/bundle` not your default system location
+
+ In development, it's convenient to share the gems used in your
+ application with other applications and other scripts that run on
+ the system.
+
+ In deployment, isolation is a more important default. In addition,
+ the user deploying the application may not have permission to install
+ gems to the system, or the web server may not have permission to
+ read them.
+
+ As a result, `bundle install --deployment` installs gems to
+ the `vendor/bundle` directory in the application. This may be
+ overridden using the `--path` option.
+
+## SUDO USAGE
+
+By default, Bundler installs gems to the same location as `gem install`.
+
+In some cases, that location may not be writable by your Unix user. In
+that case, Bundler will stage everything in a temporary directory,
+then ask you for your `sudo` password in order to copy the gems into
+their system location.
+
+From your perspective, this is identical to installing the gems
+directly into the system.
+
+You should never use `sudo bundle install`. This is because several
+other steps in `bundle install` must be performed as the current user:
+
+* Updating your `Gemfile.lock`
+* Updating your `vendor/cache`, if necessary
+* Checking out private git repositories using your user's SSH keys
+
+Of these three, the first two could theoretically be performed by
+`chown`ing the resulting files to `$SUDO_USER`. The third, however,
+can only be performed by invoking the `git` command as
+the current user. Therefore, git gems are downloaded and installed
+into `~/.bundle` rather than $GEM_HOME or $BUNDLE_PATH.
+
+As a result, you should run `bundle install` as the current user,
+and Bundler will ask for your password if it is needed to put the
+gems into their final location.
+
+## INSTALLING GROUPS
+
+By default, `bundle install` will install all gems in all groups
+in your Gemfile(5), except those declared for a different platform.
+
+However, you can explicitly tell Bundler to skip installing
+certain groups with the `--without` option. This option takes
+a space-separated list of groups.
+
+While the `--without` option will skip _installing_ the gems in the
+specified groups, it will still _download_ those gems and use them to
+resolve the dependencies of every gem in your Gemfile(5).
+
+This is so that installing a different set of groups on another
+ machine (such as a production server) will not change the
+gems and versions that you have already developed and tested against.
+
+`Bundler offers a rock-solid guarantee that the third-party
+code you are running in development and testing is also the
+third-party code you are running in production. You can choose
+to exclude some of that code in different environments, but you
+will never be caught flat-footed by different versions of
+third-party code being used in different environments.`
+
+For a simple illustration, consider the following Gemfile(5):
+
+ source 'https://rubygems.org'
+
+ gem 'sinatra'
+
+ group :production do
+ gem 'rack-perftools-profiler'
+ end
+
+In this case, `sinatra` depends on any version of Rack (`>= 1.0`), while
+`rack-perftools-profiler` depends on 1.x (`~> 1.0`).
+
+When you run `bundle install --without production` in development, we
+look at the dependencies of `rack-perftools-profiler` as well. That way,
+you do not spend all your time developing against Rack 2.0, using new
+APIs unavailable in Rack 1.x, only to have Bundler switch to Rack 1.2
+when the `production` group _is_ used.
+
+This should not cause any problems in practice, because we do not
+attempt to `install` the gems in the excluded groups, and only evaluate
+as part of the dependency resolution process.
+
+This also means that you cannot include different versions of the same
+gem in different groups, because doing so would result in different
+sets of dependencies used in development and production. Because of
+the vagaries of the dependency resolution process, this usually
+affects more than the gems you list in your Gemfile(5), and can
+(surprisingly) radically change the gems you are using.
+
+## THE GEMFILE.LOCK
+
+When you run `bundle install`, Bundler will persist the full names
+and versions of all gems that you used (including dependencies of
+the gems specified in the Gemfile(5)) into a file called `Gemfile.lock`.
+
+Bundler uses this file in all subsequent calls to `bundle install`,
+which guarantees that you always use the same exact code, even
+as your application moves across machines.
+
+Because of the way dependency resolution works, even a
+seemingly small change (for instance, an update to a point-release
+of a dependency of a gem in your Gemfile(5)) can result in radically
+different gems being needed to satisfy all dependencies.
+
+As a result, you `SHOULD` check your `Gemfile.lock` into version
+control, in both applications and gems. If you do not, every machine that
+checks out your repository (including your production server) will resolve all
+dependencies again, which will result in different versions of
+third-party code being used if `any` of the gems in the Gemfile(5)
+or any of their dependencies have been updated.
+
+When Bundler first shipped, the `Gemfile.lock` was included in the `.gitignore`
+file included with generated gems. Over time, however, it became clear that
+this practice forces the pain of broken dependencies onto new contributors,
+while leaving existing contributors potentially unaware of the problem. Since
+`bundle install` is usually the first step towards a contribution, the pain of
+broken dependencies would discourage new contributors from contributing. As a
+result, we have revised our guidance for gem authors to now recommend checking
+in the lock for gems.
+
+## CONSERVATIVE UPDATING
+
+When you make a change to the Gemfile(5) and then run `bundle install`,
+Bundler will update only the gems that you modified.
+
+In other words, if a gem that you `did not modify` worked before
+you called `bundle install`, it will continue to use the exact
+same versions of all dependencies as it used before the update.
+
+Let's take a look at an example. Here's your original Gemfile(5):
+
+ source 'https://rubygems.org'
+
+ gem 'actionpack', '2.3.8'
+ gem 'activemerchant'
+
+In this case, both `actionpack` and `activemerchant` depend on
+`activesupport`. The `actionpack` gem depends on `activesupport 2.3.8`
+and `rack ~> 1.1.0`, while the `activemerchant` gem depends on
+`activesupport >= 2.3.2`, `braintree >= 2.0.0`, and `builder >= 2.0.0`.
+
+When the dependencies are first resolved, Bundler will select
+`activesupport 2.3.8`, which satisfies the requirements of both
+gems in your Gemfile(5).
+
+Next, you modify your Gemfile(5) to:
+
+ source 'https://rubygems.org'
+
+ gem 'actionpack', '3.0.0.rc'
+ gem 'activemerchant'
+
+The `actionpack 3.0.0.rc` gem has a number of new dependencies,
+and updates the `activesupport` dependency to `= 3.0.0.rc` and
+the `rack` dependency to `~> 1.2.1`.
+
+When you run `bundle install`, Bundler notices that you changed
+the `actionpack` gem, but not the `activemerchant` gem. It
+evaluates the gems currently being used to satisfy its requirements:
+
+ * `activesupport 2.3.8`:
+ also used to satisfy a dependency in `activemerchant`,
+ which is not being updated
+ * `rack ~> 1.1.0`:
+ not currently being used to satisfy another dependency
+
+Because you did not explicitly ask to update `activemerchant`,
+you would not expect it to suddenly stop working after updating
+`actionpack`. However, satisfying the new `activesupport 3.0.0.rc`
+dependency of actionpack requires updating one of its dependencies.
+
+Even though `activemerchant` declares a very loose dependency
+that theoretically matches `activesupport 3.0.0.rc`, Bundler treats
+gems in your Gemfile(5) that have not changed as an atomic unit
+together with their dependencies. In this case, the `activemerchant`
+dependency is treated as `activemerchant 1.7.1 + activesupport 2.3.8`,
+so `bundle install` will report that it cannot update `actionpack`.
+
+To explicitly update `actionpack`, including its dependencies
+which other gems in the Gemfile(5) still depend on, run
+`bundle update actionpack` (see `bundle update(1)`).
+
+`Summary`: In general, after making a change to the Gemfile(5) , you
+should first try to run `bundle install`, which will guarantee that no
+other gem in the Gemfile(5) is impacted by the change. If that
+does not work, run [bundle update(1)](bundle-update.1.html).
+
+## SEE ALSO
+
+* [Gem install docs](http://guides.rubygems.org/rubygems-basics/#installing-gems)
+* [Rubygems signing docs](http://guides.rubygems.org/security/)
diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1
new file mode 100644
index 0000000000..a697173af9
--- /dev/null
+++ b/lib/bundler/man/bundle-list.1
@@ -0,0 +1,50 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-LIST" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-list\fR \- List all the gems in the bundle
+.
+.SH "SYNOPSIS"
+\fBbundle list\fR [\-\-name\-only] [\-\-paths] [\-\-without\-group=GROUP[ GROUP\.\.\.]] [\-\-only\-group=GROUP[ GROUP\.\.\.]]
+.
+.SH "DESCRIPTION"
+Prints a list of all the gems in the bundle including their version\.
+.
+.P
+Example:
+.
+.P
+bundle list \-\-name\-only
+.
+.P
+bundle list \-\-paths
+.
+.P
+bundle list \-\-without\-group test
+.
+.P
+bundle list \-\-only\-group dev
+.
+.P
+bundle list \-\-only\-group dev test \-\-paths
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-name\-only\fR
+Print only the name of each gem\.
+.
+.TP
+\fB\-\-paths\fR
+Print the path to each gem in the bundle\.
+.
+.TP
+\fB\-\-without\-group=<list>\fR
+A space\-separated list of groups of gems to skip during printing\.
+.
+.TP
+\fB\-\-only\-group=<list>\fR
+A space\-separated list of groups of gems to print\.
+
diff --git a/lib/bundler/man/bundle-list.1.ronn b/lib/bundler/man/bundle-list.1.ronn
new file mode 100644
index 0000000000..dc058ecd5f
--- /dev/null
+++ b/lib/bundler/man/bundle-list.1.ronn
@@ -0,0 +1,33 @@
+bundle-list(1) -- List all the gems in the bundle
+=========================================================================
+
+## SYNOPSIS
+
+`bundle list` [--name-only] [--paths] [--without-group=GROUP[ GROUP...]] [--only-group=GROUP[ GROUP...]]
+
+## DESCRIPTION
+
+Prints a list of all the gems in the bundle including their version.
+
+Example:
+
+bundle list --name-only
+
+bundle list --paths
+
+bundle list --without-group test
+
+bundle list --only-group dev
+
+bundle list --only-group dev test --paths
+
+## OPTIONS
+
+* `--name-only`:
+ Print only the name of each gem.
+* `--paths`:
+ Print the path to each gem in the bundle.
+* `--without-group=<list>`:
+ A space-separated list of groups of gems to skip during printing.
+* `--only-group=<list>`:
+ A space-separated list of groups of gems to print.
diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1
new file mode 100644
index 0000000000..ef515b0337
--- /dev/null
+++ b/lib/bundler/man/bundle-lock.1
@@ -0,0 +1,84 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-LOCK" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
+.
+.SH "SYNOPSIS"
+\fBbundle lock\fR [\-\-update] [\-\-local] [\-\-print] [\-\-lockfile=PATH] [\-\-full\-index] [\-\-add\-platform] [\-\-remove\-platform] [\-\-patch] [\-\-minor] [\-\-major] [\-\-strict] [\-\-conservative]
+.
+.SH "DESCRIPTION"
+Lock the gems specified in Gemfile\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-update=<*gems>\fR
+Ignores the existing lockfile\. Resolve then updates lockfile\. Taking a list of gems or updating all gems if no list is given\.
+.
+.TP
+\fB\-\-local\fR
+Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if a appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
+.
+.TP
+\fB\-\-print\fR
+Prints the lockfile to STDOUT instead of writing to the file system\.
+.
+.TP
+\fB\-\-lockfile=<path>\fR
+The path where the lockfile should be written to\.
+.
+.TP
+\fB\-\-full\-index\fR
+Fall back to using the single\-file index of all gems\.
+.
+.TP
+\fB\-\-add\-platform\fR
+Add a new platform to the lockfile, re\-resolving for the addition of that platform\.
+.
+.TP
+\fB\-\-remove\-platform\fR
+Remove a platform from the lockfile\.
+.
+.TP
+\fB\-\-patch\fR
+If updating, prefer updating only to next patch version\.
+.
+.TP
+\fB\-\-minor\fR
+If updating, prefer updating only to next minor version\.
+.
+.TP
+\fB\-\-major\fR
+If updating, prefer updating to next major version (default)\.
+.
+.TP
+\fB\-\-strict\fR
+If updating, do not allow any gem to be updated past latest \-\-patch | \-\-minor | \-\-major\.
+.
+.TP
+\fB\-\-conservative\fR
+If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated\.
+.
+.SH "UPDATING ALL GEMS"
+If you run \fBbundle lock\fR with \fB\-\-update\fR option without list of gems, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
+.
+.SH "UPDATING A LIST OF GEMS"
+Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\.
+.
+.P
+For instance, you only want to update \fBnokogiri\fR, run \fBbundle lock \-\-update nokogiri\fR\.
+.
+.P
+Bundler will update \fBnokogiri\fR and any of its dependencies, but leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\.
+.
+.SH "SUPPORTING OTHER PLATFORMS"
+If you want your bundle to support platforms other than the one you\'re running locally, you can run \fBbundle lock \-\-add\-platform PLATFORM\fR to add PLATFORM to the lockfile, force bundler to re\-resolve and consider the new platform when picking gems, all without needing to have a machine that matches PLATFORM handy to install those platform\-specific gems on\.
+.
+.P
+For a full explanation of gem platforms, see \fBgem help platform\fR\.
+.
+.SH "PATCH LEVEL OPTIONS"
+See bundle update(1) \fIbundle\-update\.1\.html\fR for details\.
diff --git a/lib/bundler/man/bundle-lock.1.ronn b/lib/bundler/man/bundle-lock.1.ronn
new file mode 100644
index 0000000000..3aa5920f5a
--- /dev/null
+++ b/lib/bundler/man/bundle-lock.1.ronn
@@ -0,0 +1,94 @@
+bundle-lock(1) -- Creates / Updates a lockfile without installing
+=================================================================
+
+## SYNOPSIS
+
+`bundle lock` [--update]
+ [--local]
+ [--print]
+ [--lockfile=PATH]
+ [--full-index]
+ [--add-platform]
+ [--remove-platform]
+ [--patch]
+ [--minor]
+ [--major]
+ [--strict]
+ [--conservative]
+
+## DESCRIPTION
+
+Lock the gems specified in Gemfile.
+
+## OPTIONS
+
+* `--update=<*gems>`:
+ Ignores the existing lockfile. Resolve then updates lockfile. Taking a list
+ of gems or updating all gems if no list is given.
+
+* `--local`:
+ Do not attempt to connect to `rubygems.org`. Instead, Bundler will use the
+ gems already present in Rubygems' cache or in `vendor/cache`. Note that if a
+ appropriate platform-specific gem exists on `rubygems.org` it will not be
+ found.
+
+* `--print`:
+ Prints the lockfile to STDOUT instead of writing to the file system.
+
+* `--lockfile=<path>`:
+ The path where the lockfile should be written to.
+
+* `--full-index`:
+ Fall back to using the single-file index of all gems.
+
+* `--add-platform`:
+ Add a new platform to the lockfile, re-resolving for the addition of that
+ platform.
+
+* `--remove-platform`:
+ Remove a platform from the lockfile.
+
+* `--patch`:
+ If updating, prefer updating only to next patch version.
+
+* `--minor`:
+ If updating, prefer updating only to next minor version.
+
+* `--major`:
+ If updating, prefer updating to next major version (default).
+
+* `--strict`:
+ If updating, do not allow any gem to be updated past latest --patch | --minor | --major.
+
+* `--conservative`:
+ If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated.
+
+## UPDATING ALL GEMS
+
+If you run `bundle lock` with `--update` option without list of gems, bundler will
+ignore any previously installed gems and resolve all dependencies again based
+on the latest versions of all gems available in the sources.
+
+## UPDATING A LIST OF GEMS
+
+Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of
+the gems that you specified locked to the versions in the `Gemfile.lock`.
+
+For instance, you only want to update `nokogiri`, run `bundle lock --update nokogiri`.
+
+Bundler will update `nokogiri` and any of its dependencies, but leave the rest of the
+gems that you specified locked to the versions in the `Gemfile.lock`.
+
+## SUPPORTING OTHER PLATFORMS
+
+If you want your bundle to support platforms other than the one you're running
+locally, you can run `bundle lock --add-platform PLATFORM` to add PLATFORM to
+the lockfile, force bundler to re-resolve and consider the new platform when
+picking gems, all without needing to have a machine that matches PLATFORM handy
+to install those platform-specific gems on.
+
+For a full explanation of gem platforms, see `gem help platform`.
+
+## PATCH LEVEL OPTIONS
+
+See [bundle update(1)](bundle-update.1.html) for details.
diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1
new file mode 100644
index 0000000000..dd28566bdb
--- /dev/null
+++ b/lib/bundler/man/bundle-open.1
@@ -0,0 +1,32 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-OPEN" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
+.
+.SH "SYNOPSIS"
+\fBbundle open\fR [GEM]
+.
+.SH "DESCRIPTION"
+Opens the source directory of the provided GEM in your editor\.
+.
+.P
+For this to work the \fBEDITOR\fR or \fBBUNDLER_EDITOR\fR environment variable has to be set\.
+.
+.P
+Example:
+.
+.IP "" 4
+.
+.nf
+
+bundle open \'rack\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Will open the source directory for the \'rack\' gem in your bundle\.
diff --git a/lib/bundler/man/bundle-open.1.ronn b/lib/bundler/man/bundle-open.1.ronn
new file mode 100644
index 0000000000..497beac93f
--- /dev/null
+++ b/lib/bundler/man/bundle-open.1.ronn
@@ -0,0 +1,19 @@
+bundle-open(1) -- Opens the source directory for a gem in your bundle
+=====================================================================
+
+## SYNOPSIS
+
+`bundle open` [GEM]
+
+## DESCRIPTION
+
+Opens the source directory of the provided GEM in your editor.
+
+For this to work the `EDITOR` or `BUNDLER_EDITOR` environment variable has to
+be set.
+
+Example:
+
+ bundle open 'rack'
+
+Will open the source directory for the 'rack' gem in your bundle.
diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1
new file mode 100644
index 0000000000..b9d50a1c71
--- /dev/null
+++ b/lib/bundler/man/bundle-outdated.1
@@ -0,0 +1,155 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-OUTDATED" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-outdated\fR \- List installed gems with newer versions available
+.
+.SH "SYNOPSIS"
+\fBbundle outdated\fR [GEM] [\-\-local] [\-\-pre] [\-\-source] [\-\-strict] [\-\-parseable | \-\-porcelain] [\-\-group=GROUP] [\-\-groups] [\-\-update\-strict] [\-\-patch|\-\-minor|\-\-major] [\-\-filter\-major] [\-\-filter\-minor] [\-\-filter\-patch] [\-\-only\-explicit]
+.
+.SH "DESCRIPTION"
+Outdated lists the names and versions of gems that have a newer version available in the given source\. Calling outdated with [GEM [GEM]] will only check for newer versions of the given gems\. Prerelease gems are ignored by default\. If your gems are up to date, Bundler will exit with a status of 0\. Otherwise, it will exit 1\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-local\fR
+Do not attempt to fetch gems remotely and use the gem cache instead\.
+.
+.TP
+\fB\-\-pre\fR
+Check for newer pre\-release gems\.
+.
+.TP
+\fB\-\-source\fR
+Check against a specific source\.
+.
+.TP
+\fB\-\-strict\fR
+Only list newer versions allowed by your Gemfile requirements\.
+.
+.TP
+\fB\-\-parseable\fR, \fB\-\-porcelain\fR
+Use minimal formatting for more parseable output\.
+.
+.TP
+\fB\-\-group\fR
+List gems from a specific group\.
+.
+.TP
+\fB\-\-groups\fR
+List gems organized by groups\.
+.
+.TP
+\fB\-\-update\-strict\fR
+Strict conservative resolution, do not allow any gem to be updated past latest \-\-patch | \-\-minor| \-\-major\.
+.
+.TP
+\fB\-\-minor\fR
+Prefer updating only to next minor version\.
+.
+.TP
+\fB\-\-major\fR
+Prefer updating to next major version (default)\.
+.
+.TP
+\fB\-\-patch\fR
+Prefer updating only to next patch version\.
+.
+.TP
+\fB\-\-filter\-major\fR
+Only list major newer versions\.
+.
+.TP
+\fB\-\-filter\-minor\fR
+Only list minor newer versions\.
+.
+.TP
+\fB\-\-filter\-patch\fR
+Only list patch newer versions\.
+.
+.TP
+\fB\-\-only\-explicit\fR
+Only list gems specified in your Gemfile, not their dependencies\.
+.
+.SH "PATCH LEVEL OPTIONS"
+See bundle update(1) \fIbundle\-update\.1\.html\fR for details\.
+.
+.P
+One difference between the patch level options in \fBbundle update\fR and here is the \fB\-\-strict\fR option\. \fB\-\-strict\fR was already an option on outdated before the patch level options were added\. \fB\-\-strict\fR wasn\'t altered, and the \fB\-\-update\-strict\fR option on \fBoutdated\fR reflects what \fB\-\-strict\fR does on \fBbundle update\fR\.
+.
+.SH "FILTERING OUTPUT"
+The 3 filtering options do not affect the resolution of versions, merely what versions are shown in the output\.
+.
+.P
+If the regular output shows the following:
+.
+.IP "" 4
+.
+.nf
+
+* faker (newest 1\.6\.6, installed 1\.6\.5, requested ~> 1\.4) in groups "development, test"
+* hashie (newest 3\.4\.6, installed 1\.2\.0, requested = 1\.2\.0) in groups "default"
+* headless (newest 2\.3\.1, installed 2\.2\.3) in groups "test"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+\fB\-\-filter\-major\fR would only show:
+.
+.IP "" 4
+.
+.nf
+
+* hashie (newest 3\.4\.6, installed 1\.2\.0, requested = 1\.2\.0) in groups "default"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+\fB\-\-filter\-minor\fR would only show:
+.
+.IP "" 4
+.
+.nf
+
+* headless (newest 2\.3\.1, installed 2\.2\.3) in groups "test"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+\fB\-\-filter\-patch\fR would only show:
+.
+.IP "" 4
+.
+.nf
+
+* faker (newest 1\.6\.6, installed 1\.6\.5, requested ~> 1\.4) in groups "development, test"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Filter options can be combined\. \fB\-\-filter\-minor\fR and \fB\-\-filter\-patch\fR would show:
+.
+.IP "" 4
+.
+.nf
+
+* faker (newest 1\.6\.6, installed 1\.6\.5, requested ~> 1\.4) in groups "development, test"
+* headless (newest 2\.3\.1, installed 2\.2\.3) in groups "test"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Combining all three \fBfilter\fR options would be the same result as providing none of them\.
diff --git a/lib/bundler/man/bundle-outdated.1.ronn b/lib/bundler/man/bundle-outdated.1.ronn
new file mode 100644
index 0000000000..a991d23789
--- /dev/null
+++ b/lib/bundler/man/bundle-outdated.1.ronn
@@ -0,0 +1,111 @@
+bundle-outdated(1) -- List installed gems with newer versions available
+=======================================================================
+
+## SYNOPSIS
+
+`bundle outdated` [GEM] [--local]
+ [--pre]
+ [--source]
+ [--strict]
+ [--parseable | --porcelain]
+ [--group=GROUP]
+ [--groups]
+ [--update-strict]
+ [--patch|--minor|--major]
+ [--filter-major]
+ [--filter-minor]
+ [--filter-patch]
+ [--only-explicit]
+
+## DESCRIPTION
+
+Outdated lists the names and versions of gems that have a newer version available
+in the given source. Calling outdated with [GEM [GEM]] will only check for newer
+versions of the given gems. Prerelease gems are ignored by default. If your gems
+are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1.
+
+## OPTIONS
+
+* `--local`:
+ Do not attempt to fetch gems remotely and use the gem cache instead.
+
+* `--pre`:
+ Check for newer pre-release gems.
+
+* `--source`:
+ Check against a specific source.
+
+* `--strict`:
+ Only list newer versions allowed by your Gemfile requirements.
+
+* `--parseable`, `--porcelain`:
+ Use minimal formatting for more parseable output.
+
+* `--group`:
+ List gems from a specific group.
+
+* `--groups`:
+ List gems organized by groups.
+
+* `--update-strict`:
+ Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor| --major.
+
+* `--minor`:
+ Prefer updating only to next minor version.
+
+* `--major`:
+ Prefer updating to next major version (default).
+
+* `--patch`:
+ Prefer updating only to next patch version.
+
+* `--filter-major`:
+ Only list major newer versions.
+
+* `--filter-minor`:
+ Only list minor newer versions.
+
+* `--filter-patch`:
+ Only list patch newer versions.
+
+* `--only-explicit`:
+ Only list gems specified in your Gemfile, not their dependencies.
+
+## PATCH LEVEL OPTIONS
+
+See [bundle update(1)](bundle-update.1.html) for details.
+
+One difference between the patch level options in `bundle update` and here is the `--strict` option.
+`--strict` was already an option on outdated before the patch level options were added. `--strict`
+wasn't altered, and the `--update-strict` option on `outdated` reflects what `--strict` does on
+`bundle update`.
+
+## FILTERING OUTPUT
+
+The 3 filtering options do not affect the resolution of versions, merely what versions are shown
+in the output.
+
+If the regular output shows the following:
+
+ * faker (newest 1.6.6, installed 1.6.5, requested ~> 1.4) in groups "development, test"
+ * hashie (newest 3.4.6, installed 1.2.0, requested = 1.2.0) in groups "default"
+ * headless (newest 2.3.1, installed 2.2.3) in groups "test"
+
+`--filter-major` would only show:
+
+ * hashie (newest 3.4.6, installed 1.2.0, requested = 1.2.0) in groups "default"
+
+`--filter-minor` would only show:
+
+ * headless (newest 2.3.1, installed 2.2.3) in groups "test"
+
+`--filter-patch` would only show:
+
+ * faker (newest 1.6.6, installed 1.6.5, requested ~> 1.4) in groups "development, test"
+
+Filter options can be combined. `--filter-minor` and `--filter-patch` would show:
+
+ * faker (newest 1.6.6, installed 1.6.5, requested ~> 1.4) in groups "development, test"
+ * headless (newest 2.3.1, installed 2.2.3) in groups "test"
+
+Combining all three `filter` options would be the same result as providing none of them.
diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1
new file mode 100644
index 0000000000..b1c859f64b
--- /dev/null
+++ b/lib/bundler/man/bundle-platform.1
@@ -0,0 +1,61 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-PLATFORM" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-platform\fR \- Displays platform compatibility information
+.
+.SH "SYNOPSIS"
+\fBbundle platform\fR [\-\-ruby]
+.
+.SH "DESCRIPTION"
+\fBplatform\fR will display information from your Gemfile, Gemfile\.lock, and Ruby VM about your platform\.
+.
+.P
+For instance, using this Gemfile(5):
+.
+.IP "" 4
+.
+.nf
+
+source "https://rubygems\.org"
+
+ruby "1\.9\.3"
+
+gem "rack"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+If you run \fBbundle platform\fR on Ruby 1\.9\.3, it will display the following output:
+.
+.IP "" 4
+.
+.nf
+
+Your platform is: x86_64\-linux
+
+Your app has gems that work on these platforms:
+* ruby
+
+Your Gemfile specifies a Ruby version requirement:
+* ruby 1\.9\.3
+
+Your current platform satisfies the Ruby version requirement\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+\fBplatform\fR will list all the platforms in your \fBGemfile\.lock\fR as well as the \fBruby\fR directive if applicable from your Gemfile(5)\. It will also let you know if the \fBruby\fR directive requirement has been met\. If \fBruby\fR directive doesn\'t match the running Ruby VM, it will tell you what part does not\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-ruby\fR
+It will display the ruby directive information, so you don\'t have to parse it from the Gemfile(5)\.
+
diff --git a/lib/bundler/man/bundle-platform.1.ronn b/lib/bundler/man/bundle-platform.1.ronn
new file mode 100644
index 0000000000..b5d3283fb6
--- /dev/null
+++ b/lib/bundler/man/bundle-platform.1.ronn
@@ -0,0 +1,42 @@
+bundle-platform(1) -- Displays platform compatibility information
+=================================================================
+
+## SYNOPSIS
+
+`bundle platform` [--ruby]
+
+## DESCRIPTION
+
+`platform` will display information from your Gemfile, Gemfile.lock, and Ruby
+VM about your platform.
+
+For instance, using this Gemfile(5):
+
+ source "https://rubygems.org"
+
+ ruby "1.9.3"
+
+ gem "rack"
+
+If you run `bundle platform` on Ruby 1.9.3, it will display the following output:
+
+ Your platform is: x86_64-linux
+
+ Your app has gems that work on these platforms:
+ * ruby
+
+ Your Gemfile specifies a Ruby version requirement:
+ * ruby 1.9.3
+
+ Your current platform satisfies the Ruby version requirement.
+
+`platform` will list all the platforms in your `Gemfile.lock` as well as the
+`ruby` directive if applicable from your Gemfile(5). It will also let you know
+if the `ruby` directive requirement has been met. If `ruby` directive doesn't
+match the running Ruby VM, it will tell you what part does not.
+
+## OPTIONS
+
+* `--ruby`:
+ It will display the ruby directive information, so you don't have to
+ parse it from the Gemfile(5).
diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1
new file mode 100644
index 0000000000..6e4a028666
--- /dev/null
+++ b/lib/bundler/man/bundle-pristine.1
@@ -0,0 +1,34 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-PRISTINE" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
+.
+.SH "SYNOPSIS"
+\fBbundle pristine\fR
+.
+.SH "DESCRIPTION"
+\fBpristine\fR restores the installed gems in the bundle to their pristine condition using the local gem cache from RubyGems\. For git gems, a forced checkout will be performed\.
+.
+.P
+For further explanation, \fBbundle pristine\fR ignores unpacked files on disk\. In other words, this command utilizes the local \fB\.gem\fR cache or the gem\'s git repository as if one were installing from scratch\.
+.
+.P
+Note: the Bundler gem cannot be restored to its original state with \fBpristine\fR\. One also cannot use \fBbundle pristine\fR on gems with a \'path\' option in the Gemfile, because bundler has no original copy it can restore from\.
+.
+.P
+When is it practical to use \fBbundle pristine\fR?
+.
+.P
+It comes in handy when a developer is debugging a gem\. \fBbundle pristine\fR is a great way to get rid of experimental changes to a gem that one may not want\.
+.
+.P
+Why use \fBbundle pristine\fR over \fBgem pristine \-\-all\fR?
+.
+.P
+Both commands are very similar\. For context: \fBbundle pristine\fR, without arguments, cleans all gems from the lockfile\. Meanwhile, \fBgem pristine \-\-all\fR cleans all installed gems for that Ruby version\.
+.
+.P
+If a developer forgets which gems in their project they might have been debugging, the Rubygems \fBgem pristine [GEMNAME]\fR command may be inconvenient\. One can avoid waiting for \fBgem pristine \-\-all\fR, and instead run \fBbundle pristine\fR\.
diff --git a/lib/bundler/man/bundle-pristine.1.ronn b/lib/bundler/man/bundle-pristine.1.ronn
new file mode 100644
index 0000000000..e2d6b6a348
--- /dev/null
+++ b/lib/bundler/man/bundle-pristine.1.ronn
@@ -0,0 +1,34 @@
+bundle-pristine(1) -- Restores installed gems to their pristine condition
+===========================================================================
+
+## SYNOPSIS
+
+`bundle pristine`
+
+## DESCRIPTION
+
+`pristine` restores the installed gems in the bundle to their pristine condition
+using the local gem cache from RubyGems. For git gems, a forced checkout will be performed.
+
+For further explanation, `bundle pristine` ignores unpacked files on disk. In other
+words, this command utilizes the local `.gem` cache or the gem's git repository
+as if one were installing from scratch.
+
+Note: the Bundler gem cannot be restored to its original state with `pristine`.
+One also cannot use `bundle pristine` on gems with a 'path' option in the Gemfile,
+because bundler has no original copy it can restore from.
+
+When is it practical to use `bundle pristine`?
+
+It comes in handy when a developer is debugging a gem. `bundle pristine` is a
+great way to get rid of experimental changes to a gem that one may not want.
+
+Why use `bundle pristine` over `gem pristine --all`?
+
+Both commands are very similar.
+For context: `bundle pristine`, without arguments, cleans all gems from the lockfile.
+Meanwhile, `gem pristine --all` cleans all installed gems for that Ruby version.
+
+If a developer forgets which gems in their project they might
+have been debugging, the Rubygems `gem pristine [GEMNAME]` command may be inconvenient.
+One can avoid waiting for `gem pristine --all`, and instead run `bundle pristine`.
diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1
new file mode 100644
index 0000000000..0b4edd1414
--- /dev/null
+++ b/lib/bundler/man/bundle-remove.1
@@ -0,0 +1,31 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-REMOVE" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-remove\fR \- Removes gems from the Gemfile
+.
+.SH "SYNOPSIS"
+\fBbundle remove [GEM [GEM \.\.\.]] [\-\-install]\fR
+.
+.SH "DESCRIPTION"
+Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid\. If a gem cannot be removed, a warning is printed\. If a gem is already absent from the Gemfile, and error is raised\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-install\fR
+Runs \fBbundle install\fR after the given gems have been removed from the Gemfile, which ensures that both the lockfile and the installed gems on disk are also updated to remove the given gem(s)\.
+.
+.P
+Example:
+.
+.P
+bundle remove rails
+.
+.P
+bundle remove rails rack
+.
+.P
+bundle remove rails rack \-\-install
diff --git a/lib/bundler/man/bundle-remove.1.ronn b/lib/bundler/man/bundle-remove.1.ronn
new file mode 100644
index 0000000000..40a239b4a2
--- /dev/null
+++ b/lib/bundler/man/bundle-remove.1.ronn
@@ -0,0 +1,23 @@
+bundle-remove(1) -- Removes gems from the Gemfile
+===========================================================================
+
+## SYNOPSIS
+
+`bundle remove [GEM [GEM ...]] [--install]`
+
+## DESCRIPTION
+
+Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid. If a gem cannot be removed, a warning is printed. If a gem is already absent from the Gemfile, and error is raised.
+
+## OPTIONS
+
+* `--install`:
+ Runs `bundle install` after the given gems have been removed from the Gemfile, which ensures that both the lockfile and the installed gems on disk are also updated to remove the given gem(s).
+
+Example:
+
+bundle remove rails
+
+bundle remove rails rack
+
+bundle remove rails rack --install
diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1
new file mode 100644
index 0000000000..375699ddf0
--- /dev/null
+++ b/lib/bundler/man/bundle-show.1
@@ -0,0 +1,23 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-SHOW" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
+.
+.SH "SYNOPSIS"
+\fBbundle show\fR [GEM] [\-\-paths]
+.
+.SH "DESCRIPTION"
+Without the [GEM] option, \fBshow\fR will print a list of the names and versions of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by name\.
+.
+.P
+Calling show with [GEM] will list the exact location of that gem on your machine\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-paths\fR
+List the paths of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by gem name\.
+
diff --git a/lib/bundler/man/bundle-show.1.ronn b/lib/bundler/man/bundle-show.1.ronn
new file mode 100644
index 0000000000..a6a59a1445
--- /dev/null
+++ b/lib/bundler/man/bundle-show.1.ronn
@@ -0,0 +1,21 @@
+bundle-show(1) -- Shows all the gems in your bundle, or the path to a gem
+=========================================================================
+
+## SYNOPSIS
+
+`bundle show` [GEM]
+ [--paths]
+
+## DESCRIPTION
+
+Without the [GEM] option, `show` will print a list of the names and versions of
+all gems that are required by your [`Gemfile(5)`][Gemfile(5)], sorted by name.
+
+Calling show with [GEM] will list the exact location of that gem on your
+machine.
+
+## OPTIONS
+
+* `--paths`:
+ List the paths of all gems that are required by your [`Gemfile(5)`][Gemfile(5)],
+ sorted by gem name.
diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1
new file mode 100644
index 0000000000..c08bc66ef0
--- /dev/null
+++ b/lib/bundler/man/bundle-update.1
@@ -0,0 +1,394 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-UPDATE" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-update\fR \- Update your gems to the latest available versions
+.
+.SH "SYNOPSIS"
+\fBbundle update\fR \fI*gems\fR [\-\-all] [\-\-group=NAME] [\-\-source=NAME] [\-\-local] [\-\-ruby] [\-\-bundler[=VERSION]] [\-\-full\-index] [\-\-jobs=JOBS] [\-\-quiet] [\-\-patch|\-\-minor|\-\-major] [\-\-redownload] [\-\-strict] [\-\-conservative]
+.
+.SH "DESCRIPTION"
+Update the gems specified (all gems, if \fB\-\-all\fR flag is used), ignoring the previously installed gems specified in the \fBGemfile\.lock\fR\. In general, you should use bundle install(1) \fIbundle\-install\.1\.html\fR to install the same exact gems and versions across machines\.
+.
+.P
+You would use \fBbundle update\fR to explicitly update the version of a gem\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-all\fR
+Update all gems specified in Gemfile\.
+.
+.TP
+\fB\-\-group=<name>\fR, \fB\-g=[<name>]\fR
+Only update the gems in the specified group\. For instance, you can update all gems in the development group with \fBbundle update \-\-group development\fR\. You can also call \fBbundle update rails \-\-group test\fR to update the rails gem and all gems in the test group, for example\.
+.
+.TP
+\fB\-\-source=<name>\fR
+The name of a \fB:git\fR or \fB:path\fR source used in the Gemfile(5)\. For instance, with a \fB:git\fR source of \fBhttp://github\.com/rails/rails\.git\fR, you would call \fBbundle update \-\-source rails\fR
+.
+.TP
+\fB\-\-local\fR
+Do not attempt to fetch gems remotely and use the gem cache instead\.
+.
+.TP
+\fB\-\-ruby\fR
+Update the locked version of Ruby to the current version of Ruby\.
+.
+.TP
+\fB\-\-bundler\fR
+Update the locked version of bundler to the invoked bundler version\.
+.
+.TP
+\fB\-\-full\-index\fR
+Fall back to using the single\-file index of all gems\.
+.
+.TP
+\fB\-\-jobs=[<number>]\fR, \fB\-j[<number>]\fR
+Specify the number of jobs to run in parallel\. The default is \fB1\fR\.
+.
+.TP
+\fB\-\-retry=[<number>]\fR
+Retry failed network or git requests for \fInumber\fR times\.
+.
+.TP
+\fB\-\-quiet\fR
+Only output warnings and errors\.
+.
+.TP
+\fB\-\-redownload\fR
+Force downloading every gem\.
+.
+.TP
+\fB\-\-patch\fR
+Prefer updating only to next patch version\.
+.
+.TP
+\fB\-\-minor\fR
+Prefer updating only to next minor version\.
+.
+.TP
+\fB\-\-major\fR
+Prefer updating to next major version (default)\.
+.
+.TP
+\fB\-\-strict\fR
+Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR | \fB\-\-major\fR\.
+.
+.TP
+\fB\-\-conservative\fR
+Use bundle install conservative update behavior and do not allow indirect dependencies to be updated\.
+.
+.SH "UPDATING ALL GEMS"
+If you run \fBbundle update \-\-all\fR, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
+.
+.P
+Consider the following Gemfile(5):
+.
+.IP "" 4
+.
+.nf
+
+source "https://rubygems\.org"
+
+gem "rails", "3\.0\.0\.rc"
+gem "nokogiri"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+When you run bundle install(1) \fIbundle\-install\.1\.html\fR the first time, bundler will resolve all of the dependencies, all the way down, and install what you need:
+.
+.IP "" 4
+.
+.nf
+
+Fetching gem metadata from https://rubygems\.org/\.\.\.\.\.\.\.\.\.
+Resolving dependencies\.\.\.
+Installing builder 2\.1\.2
+Installing abstract 1\.0\.0
+Installing rack 1\.2\.8
+Using bundler 1\.7\.6
+Installing rake 10\.4\.0
+Installing polyglot 0\.3\.5
+Installing mime\-types 1\.25\.1
+Installing i18n 0\.4\.2
+Installing mini_portile 0\.6\.1
+Installing tzinfo 0\.3\.42
+Installing rack\-mount 0\.6\.14
+Installing rack\-test 0\.5\.7
+Installing treetop 1\.4\.15
+Installing thor 0\.14\.6
+Installing activesupport 3\.0\.0\.rc
+Installing erubis 2\.6\.6
+Installing activemodel 3\.0\.0\.rc
+Installing arel 0\.4\.0
+Installing mail 2\.2\.20
+Installing activeresource 3\.0\.0\.rc
+Installing actionpack 3\.0\.0\.rc
+Installing activerecord 3\.0\.0\.rc
+Installing actionmailer 3\.0\.0\.rc
+Installing railties 3\.0\.0\.rc
+Installing rails 3\.0\.0\.rc
+Installing nokogiri 1\.6\.5
+
+Bundle complete! 2 Gemfile dependencies, 26 gems total\.
+Use `bundle show [gemname]` to see where a bundled gem is installed\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+As you can see, even though you have two gems in the Gemfile(5), your application needs 26 different gems in order to run\. Bundler remembers the exact versions it installed in \fBGemfile\.lock\fR\. The next time you run bundle install(1) \fIbundle\-install\.1\.html\fR, bundler skips the dependency resolution and installs the same gems as it installed last time\.
+.
+.P
+After checking in the \fBGemfile\.lock\fR into version control and cloning it on another machine, running bundle install(1) \fIbundle\-install\.1\.html\fR will \fIstill\fR install the gems that you installed last time\. You don\'t need to worry that a new release of \fBerubis\fR or \fBmail\fR changes the gems you use\.
+.
+.P
+However, from time to time, you might want to update the gems you are using to the newest versions that still match the gems in your Gemfile(5)\.
+.
+.P
+To do this, run \fBbundle update \-\-all\fR, which will ignore the \fBGemfile\.lock\fR, and resolve all the dependencies again\. Keep in mind that this process can result in a significantly different set of the 25 gems, based on the requirements of new gems that the gem authors released since the last time you ran \fBbundle update \-\-all\fR\.
+.
+.SH "UPDATING A LIST OF GEMS"
+Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\.
+.
+.P
+For instance, in the scenario above, imagine that \fBnokogiri\fR releases version \fB1\.4\.4\fR, and you want to update it \fIwithout\fR updating Rails and all of its dependencies\. To do this, run \fBbundle update nokogiri\fR\.
+.
+.P
+Bundler will update \fBnokogiri\fR and any of its dependencies, but leave alone Rails and its dependencies\.
+.
+.SH "OVERLAPPING DEPENDENCIES"
+Sometimes, multiple gems declared in your Gemfile(5) are satisfied by the same second\-level dependency\. For instance, consider the case of \fBthin\fR and \fBrack\-perftools\-profiler\fR\.
+.
+.IP "" 4
+.
+.nf
+
+source "https://rubygems\.org"
+
+gem "thin"
+gem "rack\-perftools\-profiler"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+The \fBthin\fR gem depends on \fBrack >= 1\.0\fR, while \fBrack\-perftools\-profiler\fR depends on \fBrack ~> 1\.0\fR\. If you run bundle install, you get:
+.
+.IP "" 4
+.
+.nf
+
+Fetching source index for https://rubygems\.org/
+Installing daemons (1\.1\.0)
+Installing eventmachine (0\.12\.10) with native extensions
+Installing open4 (1\.0\.1)
+Installing perftools\.rb (0\.4\.7) with native extensions
+Installing rack (1\.2\.1)
+Installing rack\-perftools_profiler (0\.0\.2)
+Installing thin (1\.2\.7) with native extensions
+Using bundler (1\.0\.0\.rc\.3)
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In this case, the two gems have their own set of dependencies, but they share \fBrack\fR in common\. If you run \fBbundle update thin\fR, bundler will update \fBdaemons\fR, \fBeventmachine\fR and \fBrack\fR, which are dependencies of \fBthin\fR, but not \fBopen4\fR or \fBperftools\.rb\fR, which are dependencies of \fBrack\-perftools_profiler\fR\. Note that \fBbundle update thin\fR will update \fBrack\fR even though it\'s \fIalso\fR a dependency of \fBrack\-perftools_profiler\fR\.
+.
+.P
+In short, by default, when you update a gem using \fBbundle update\fR, bundler will update all dependencies of that gem, including those that are also dependencies of another gem\.
+.
+.P
+To prevent updating indirect dependencies, prior to version 1\.14 the only option was the \fBCONSERVATIVE UPDATING\fR behavior in bundle install(1) \fIbundle\-install\.1\.html\fR:
+.
+.P
+In this scenario, updating the \fBthin\fR version manually in the Gemfile(5), and then running bundle install(1) \fIbundle\-install\.1\.html\fR will only update \fBdaemons\fR and \fBeventmachine\fR, but not \fBrack\fR\. For more information, see the \fBCONSERVATIVE UPDATING\fR section of bundle install(1) \fIbundle\-install\.1\.html\fR\.
+.
+.P
+Starting with 1\.14, specifying the \fB\-\-conservative\fR option will also prevent indirect dependencies from being updated\.
+.
+.SH "PATCH LEVEL OPTIONS"
+Version 1\.14 introduced 4 patch\-level options that will influence how gem versions are resolved\. One of the following options can be used: \fB\-\-patch\fR, \fB\-\-minor\fR or \fB\-\-major\fR\. \fB\-\-strict\fR can be added to further influence resolution\.
+.
+.TP
+\fB\-\-patch\fR
+Prefer updating only to next patch version\.
+.
+.TP
+\fB\-\-minor\fR
+Prefer updating only to next minor version\.
+.
+.TP
+\fB\-\-major\fR
+Prefer updating to next major version (default)\.
+.
+.TP
+\fB\-\-strict\fR
+Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR | \fB\-\-major\fR\.
+.
+.P
+When Bundler is resolving what versions to use to satisfy declared requirements in the Gemfile or in parent gems, it looks up all available versions, filters out any versions that don\'t satisfy the requirement, and then, by default, sorts them from newest to oldest, considering them in that order\.
+.
+.P
+Providing one of the patch level options (e\.g\. \fB\-\-patch\fR) changes the sort order of the satisfying versions, causing Bundler to consider the latest \fB\-\-patch\fR or \fB\-\-minor\fR version available before other versions\. Note that versions outside the stated patch level could still be resolved to if necessary to find a suitable dependency graph\.
+.
+.P
+For example, if gem \'foo\' is locked at 1\.0\.2, with no gem requirement defined in the Gemfile, and versions 1\.0\.3, 1\.0\.4, 1\.1\.0, 1\.1\.1, 2\.0\.0 all exist, the default order of preference by default (\fB\-\-major\fR) will be "2\.0\.0, 1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2"\.
+.
+.P
+If the \fB\-\-patch\fR option is used, the order of preference will change to "1\.0\.4, 1\.0\.3, 1\.0\.2, 1\.1\.1, 1\.1\.0, 2\.0\.0"\.
+.
+.P
+If the \fB\-\-minor\fR option is used, the order of preference will change to "1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2, 2\.0\.0"\.
+.
+.P
+Combining the \fB\-\-strict\fR option with any of the patch level options will remove any versions beyond the scope of the patch level option, to ensure that no gem is updated that far\.
+.
+.P
+To continue the previous example, if both \fB\-\-patch\fR and \fB\-\-strict\fR options are used, the available versions for resolution would be "1\.0\.4, 1\.0\.3, 1\.0\.2"\. If \fB\-\-minor\fR and \fB\-\-strict\fR are used, it would be "1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2"\.
+.
+.P
+Gem requirements as defined in the Gemfile will still be the first determining factor for what versions are available\. If the gem requirement for \fBfoo\fR in the Gemfile is \'~> 1\.0\', that will accomplish the same thing as providing the \fB\-\-minor\fR and \fB\-\-strict\fR options\.
+.
+.SH "PATCH LEVEL EXAMPLES"
+Given the following gem specifications:
+.
+.IP "" 4
+.
+.nf
+
+foo 1\.4\.3, requires: ~> bar 2\.0
+foo 1\.4\.4, requires: ~> bar 2\.0
+foo 1\.4\.5, requires: ~> bar 2\.1
+foo 1\.5\.0, requires: ~> bar 2\.1
+foo 1\.5\.1, requires: ~> bar 3\.0
+bar with versions 2\.0\.3, 2\.0\.4, 2\.1\.0, 2\.1\.1, 3\.0\.0
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Gemfile:
+.
+.IP "" 4
+.
+.nf
+
+gem \'foo\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Gemfile\.lock:
+.
+.IP "" 4
+.
+.nf
+
+foo (1\.4\.3)
+ bar (~> 2\.0)
+bar (2\.0\.3)
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Cases:
+.
+.IP "" 4
+.
+.nf
+
+# Command Line Result
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+1 bundle update \-\-patch \'foo 1\.4\.5\', \'bar 2\.1\.1\'
+2 bundle update \-\-patch foo \'foo 1\.4\.5\', \'bar 2\.1\.1\'
+3 bundle update \-\-minor \'foo 1\.5\.1\', \'bar 3\.0\.0\'
+4 bundle update \-\-minor \-\-strict \'foo 1\.5\.0\', \'bar 2\.1\.1\'
+5 bundle update \-\-patch \-\-strict \'foo 1\.4\.4\', \'bar 2\.0\.4\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In case 1, bar is upgraded to 2\.1\.1, a minor version increase, because the dependency from foo 1\.4\.5 required it\.
+.
+.P
+In case 2, only foo is requested to be unlocked, but bar is also allowed to move because it\'s not a declared dependency in the Gemfile\.
+.
+.P
+In case 3, bar goes up a whole major release, because a minor increase is preferred now for foo, and when it goes to 1\.5\.1, it requires 3\.0\.0 of bar\.
+.
+.P
+In case 4, foo is preferred up to a minor version, but 1\.5\.1 won\'t work because the \-\-strict flag removes bar 3\.0\.0 from consideration since it\'s a major increment\.
+.
+.P
+In case 5, both foo and bar have any minor or major increments removed from consideration because of the \-\-strict flag, so the most they can move is up to 1\.4\.4 and 2\.0\.4\.
+.
+.SH "RECOMMENDED WORKFLOW"
+In general, when working with an application managed with bundler, you should use the following workflow:
+.
+.IP "\(bu" 4
+After you create your Gemfile(5) for the first time, run
+.
+.IP
+$ bundle install
+.
+.IP "\(bu" 4
+Check the resulting \fBGemfile\.lock\fR into version control
+.
+.IP
+$ git add Gemfile\.lock
+.
+.IP "\(bu" 4
+When checking out this repository on another development machine, run
+.
+.IP
+$ bundle install
+.
+.IP "\(bu" 4
+When checking out this repository on a deployment machine, run
+.
+.IP
+$ bundle install \-\-deployment
+.
+.IP "\(bu" 4
+After changing the Gemfile(5) to reflect a new or update dependency, run
+.
+.IP
+$ bundle install
+.
+.IP "\(bu" 4
+Make sure to check the updated \fBGemfile\.lock\fR into version control
+.
+.IP
+$ git add Gemfile\.lock
+.
+.IP "\(bu" 4
+If bundle install(1) \fIbundle\-install\.1\.html\fR reports a conflict, manually update the specific gems that you changed in the Gemfile(5)
+.
+.IP
+$ bundle update rails thin
+.
+.IP "\(bu" 4
+If you want to update all the gems to the latest possible versions that still match the gems listed in the Gemfile(5), run
+.
+.IP
+$ bundle update \-\-all
+.
+.IP "" 0
+
diff --git a/lib/bundler/man/bundle-update.1.ronn b/lib/bundler/man/bundle-update.1.ronn
new file mode 100644
index 0000000000..3a16f29149
--- /dev/null
+++ b/lib/bundler/man/bundle-update.1.ronn
@@ -0,0 +1,350 @@
+bundle-update(1) -- Update your gems to the latest available versions
+=====================================================================
+
+## SYNOPSIS
+
+`bundle update` <*gems> [--all]
+ [--group=NAME]
+ [--source=NAME]
+ [--local]
+ [--ruby]
+ [--bundler[=VERSION]]
+ [--full-index]
+ [--jobs=JOBS]
+ [--quiet]
+ [--patch|--minor|--major]
+ [--redownload]
+ [--strict]
+ [--conservative]
+
+## DESCRIPTION
+
+Update the gems specified (all gems, if `--all` flag is used), ignoring
+the previously installed gems specified in the `Gemfile.lock`. In
+general, you should use [bundle install(1)](bundle-install.1.html) to install the same exact
+gems and versions across machines.
+
+You would use `bundle update` to explicitly update the version of a
+gem.
+
+## OPTIONS
+
+* `--all`:
+ Update all gems specified in Gemfile.
+
+* `--group=<name>`, `-g=[<name>]`:
+ Only update the gems in the specified group. For instance, you can update all gems
+ in the development group with `bundle update --group development`. You can also
+ call `bundle update rails --group test` to update the rails gem and all gems in
+ the test group, for example.
+
+* `--source=<name>`:
+ The name of a `:git` or `:path` source used in the Gemfile(5). For
+ instance, with a `:git` source of `http://github.com/rails/rails.git`,
+ you would call `bundle update --source rails`
+
+* `--local`:
+ Do not attempt to fetch gems remotely and use the gem cache instead.
+
+* `--ruby`:
+ Update the locked version of Ruby to the current version of Ruby.
+
+* `--bundler`:
+ Update the locked version of bundler to the invoked bundler version.
+
+* `--full-index`:
+ Fall back to using the single-file index of all gems.
+
+* `--jobs=[<number>]`, `-j[<number>]`:
+ Specify the number of jobs to run in parallel. The default is `1`.
+
+* `--retry=[<number>]`:
+ Retry failed network or git requests for <number> times.
+
+* `--quiet`:
+ Only output warnings and errors.
+
+* `--redownload`:
+ Force downloading every gem.
+
+* `--patch`:
+ Prefer updating only to next patch version.
+
+* `--minor`:
+ Prefer updating only to next minor version.
+
+* `--major`:
+ Prefer updating to next major version (default).
+
+* `--strict`:
+ Do not allow any gem to be updated past latest `--patch` | `--minor` | `--major`.
+
+* `--conservative`:
+ Use bundle install conservative update behavior and do not allow indirect dependencies to be updated.
+
+## UPDATING ALL GEMS
+
+If you run `bundle update --all`, bundler will ignore
+any previously installed gems and resolve all dependencies again
+based on the latest versions of all gems available in the sources.
+
+Consider the following Gemfile(5):
+
+ source "https://rubygems.org"
+
+ gem "rails", "3.0.0.rc"
+ gem "nokogiri"
+
+When you run [bundle install(1)](bundle-install.1.html) the first time, bundler will resolve
+all of the dependencies, all the way down, and install what you need:
+
+ Fetching gem metadata from https://rubygems.org/.........
+ Resolving dependencies...
+ Installing builder 2.1.2
+ Installing abstract 1.0.0
+ Installing rack 1.2.8
+ Using bundler 1.7.6
+ Installing rake 10.4.0
+ Installing polyglot 0.3.5
+ Installing mime-types 1.25.1
+ Installing i18n 0.4.2
+ Installing mini_portile 0.6.1
+ Installing tzinfo 0.3.42
+ Installing rack-mount 0.6.14
+ Installing rack-test 0.5.7
+ Installing treetop 1.4.15
+ Installing thor 0.14.6
+ Installing activesupport 3.0.0.rc
+ Installing erubis 2.6.6
+ Installing activemodel 3.0.0.rc
+ Installing arel 0.4.0
+ Installing mail 2.2.20
+ Installing activeresource 3.0.0.rc
+ Installing actionpack 3.0.0.rc
+ Installing activerecord 3.0.0.rc
+ Installing actionmailer 3.0.0.rc
+ Installing railties 3.0.0.rc
+ Installing rails 3.0.0.rc
+ Installing nokogiri 1.6.5
+
+ Bundle complete! 2 Gemfile dependencies, 26 gems total.
+ Use `bundle show [gemname]` to see where a bundled gem is installed.
+
+As you can see, even though you have two gems in the Gemfile(5), your application
+needs 26 different gems in order to run. Bundler remembers the exact versions
+it installed in `Gemfile.lock`. The next time you run [bundle install(1)](bundle-install.1.html), bundler skips
+the dependency resolution and installs the same gems as it installed last time.
+
+After checking in the `Gemfile.lock` into version control and cloning it on another
+machine, running [bundle install(1)](bundle-install.1.html) will _still_ install the gems that you installed
+last time. You don't need to worry that a new release of `erubis` or `mail` changes
+the gems you use.
+
+However, from time to time, you might want to update the gems you are using to the
+newest versions that still match the gems in your Gemfile(5).
+
+To do this, run `bundle update --all`, which will ignore the `Gemfile.lock`, and resolve
+all the dependencies again. Keep in mind that this process can result in a significantly
+different set of the 25 gems, based on the requirements of new gems that the gem
+authors released since the last time you ran `bundle update --all`.
+
+## UPDATING A LIST OF GEMS
+
+Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the
+gems that you specified locked to the versions in the `Gemfile.lock`.
+
+For instance, in the scenario above, imagine that `nokogiri` releases version `1.4.4`, and
+you want to update it _without_ updating Rails and all of its dependencies. To do this,
+run `bundle update nokogiri`.
+
+Bundler will update `nokogiri` and any of its dependencies, but leave alone Rails and
+its dependencies.
+
+## OVERLAPPING DEPENDENCIES
+
+Sometimes, multiple gems declared in your Gemfile(5) are satisfied by the same
+second-level dependency. For instance, consider the case of `thin` and
+`rack-perftools-profiler`.
+
+ source "https://rubygems.org"
+
+ gem "thin"
+ gem "rack-perftools-profiler"
+
+The `thin` gem depends on `rack >= 1.0`, while `rack-perftools-profiler` depends
+on `rack ~> 1.0`. If you run bundle install, you get:
+
+ Fetching source index for https://rubygems.org/
+ Installing daemons (1.1.0)
+ Installing eventmachine (0.12.10) with native extensions
+ Installing open4 (1.0.1)
+ Installing perftools.rb (0.4.7) with native extensions
+ Installing rack (1.2.1)
+ Installing rack-perftools_profiler (0.0.2)
+ Installing thin (1.2.7) with native extensions
+ Using bundler (1.0.0.rc.3)
+
+In this case, the two gems have their own set of dependencies, but they share
+`rack` in common. If you run `bundle update thin`, bundler will update `daemons`,
+`eventmachine` and `rack`, which are dependencies of `thin`, but not `open4` or
+`perftools.rb`, which are dependencies of `rack-perftools_profiler`. Note that
+`bundle update thin` will update `rack` even though it's _also_ a dependency of
+`rack-perftools_profiler`.
+
+In short, by default, when you update a gem using `bundle update`, bundler will
+update all dependencies of that gem, including those that are also dependencies
+of another gem.
+
+To prevent updating indirect dependencies, prior to version 1.14 the only option
+was the `CONSERVATIVE UPDATING` behavior in [bundle install(1)](bundle-install.1.html):
+
+In this scenario, updating the `thin` version manually in the Gemfile(5),
+and then running [bundle install(1)](bundle-install.1.html) will only update `daemons` and `eventmachine`,
+but not `rack`. For more information, see the `CONSERVATIVE UPDATING` section
+of [bundle install(1)](bundle-install.1.html).
+
+Starting with 1.14, specifying the `--conservative` option will also prevent indirect
+dependencies from being updated.
+
+## PATCH LEVEL OPTIONS
+
+Version 1.14 introduced 4 patch-level options that will influence how gem
+versions are resolved. One of the following options can be used: `--patch`,
+`--minor` or `--major`. `--strict` can be added to further influence resolution.
+
+* `--patch`:
+ Prefer updating only to next patch version.
+
+* `--minor`:
+ Prefer updating only to next minor version.
+
+* `--major`:
+ Prefer updating to next major version (default).
+
+* `--strict`:
+ Do not allow any gem to be updated past latest `--patch` | `--minor` | `--major`.
+
+When Bundler is resolving what versions to use to satisfy declared
+requirements in the Gemfile or in parent gems, it looks up all
+available versions, filters out any versions that don't satisfy
+the requirement, and then, by default, sorts them from newest to
+oldest, considering them in that order.
+
+Providing one of the patch level options (e.g. `--patch`) changes the
+sort order of the satisfying versions, causing Bundler to consider the
+latest `--patch` or `--minor` version available before other versions.
+Note that versions outside the stated patch level could still be
+resolved to if necessary to find a suitable dependency graph.
+
+For example, if gem 'foo' is locked at 1.0.2, with no gem requirement
+defined in the Gemfile, and versions 1.0.3, 1.0.4, 1.1.0, 1.1.1, 2.0.0
+all exist, the default order of preference by default (`--major`) will
+be "2.0.0, 1.1.1, 1.1.0, 1.0.4, 1.0.3, 1.0.2".
+
+If the `--patch` option is used, the order of preference will change to
+"1.0.4, 1.0.3, 1.0.2, 1.1.1, 1.1.0, 2.0.0".
+
+If the `--minor` option is used, the order of preference will change to
+"1.1.1, 1.1.0, 1.0.4, 1.0.3, 1.0.2, 2.0.0".
+
+Combining the `--strict` option with any of the patch level options
+will remove any versions beyond the scope of the patch level option,
+to ensure that no gem is updated that far.
+
+To continue the previous example, if both `--patch` and `--strict`
+options are used, the available versions for resolution would be
+"1.0.4, 1.0.3, 1.0.2". If `--minor` and `--strict` are used, it would
+be "1.1.1, 1.1.0, 1.0.4, 1.0.3, 1.0.2".
+
+Gem requirements as defined in the Gemfile will still be the first
+determining factor for what versions are available. If the gem
+requirement for `foo` in the Gemfile is '~> 1.0', that will accomplish
+the same thing as providing the `--minor` and `--strict` options.
+
+## PATCH LEVEL EXAMPLES
+
+Given the following gem specifications:
+
+ foo 1.4.3, requires: ~> bar 2.0
+ foo 1.4.4, requires: ~> bar 2.0
+ foo 1.4.5, requires: ~> bar 2.1
+ foo 1.5.0, requires: ~> bar 2.1
+ foo 1.5.1, requires: ~> bar 3.0
+ bar with versions 2.0.3, 2.0.4, 2.1.0, 2.1.1, 3.0.0
+
+Gemfile:
+
+ gem 'foo'
+
+Gemfile.lock:
+
+ foo (1.4.3)
+ bar (~> 2.0)
+ bar (2.0.3)
+
+Cases:
+
+ # Command Line Result
+ ------------------------------------------------------------
+ 1 bundle update --patch 'foo 1.4.5', 'bar 2.1.1'
+ 2 bundle update --patch foo 'foo 1.4.5', 'bar 2.1.1'
+ 3 bundle update --minor 'foo 1.5.1', 'bar 3.0.0'
+ 4 bundle update --minor --strict 'foo 1.5.0', 'bar 2.1.1'
+ 5 bundle update --patch --strict 'foo 1.4.4', 'bar 2.0.4'
+
+In case 1, bar is upgraded to 2.1.1, a minor version increase, because
+the dependency from foo 1.4.5 required it.
+
+In case 2, only foo is requested to be unlocked, but bar is also
+allowed to move because it's not a declared dependency in the Gemfile.
+
+In case 3, bar goes up a whole major release, because a minor increase
+is preferred now for foo, and when it goes to 1.5.1, it requires 3.0.0
+of bar.
+
+In case 4, foo is preferred up to a minor version, but 1.5.1 won't work
+because the --strict flag removes bar 3.0.0 from consideration since
+it's a major increment.
+
+In case 5, both foo and bar have any minor or major increments removed
+from consideration because of the --strict flag, so the most they can
+move is up to 1.4.4 and 2.0.4.
+
+## RECOMMENDED WORKFLOW
+
+In general, when working with an application managed with bundler, you should
+use the following workflow:
+
+* After you create your Gemfile(5) for the first time, run
+
+ $ bundle install
+
+* Check the resulting `Gemfile.lock` into version control
+
+ $ git add Gemfile.lock
+
+* When checking out this repository on another development machine, run
+
+ $ bundle install
+
+* When checking out this repository on a deployment machine, run
+
+ $ bundle install --deployment
+
+* After changing the Gemfile(5) to reflect a new or update dependency, run
+
+ $ bundle install
+
+* Make sure to check the updated `Gemfile.lock` into version control
+
+ $ git add Gemfile.lock
+
+* If [bundle install(1)](bundle-install.1.html) reports a conflict, manually update the specific
+ gems that you changed in the Gemfile(5)
+
+ $ bundle update rails thin
+
+* If you want to update all the gems to the latest possible versions that
+ still match the gems listed in the Gemfile(5), run
+
+ $ bundle update --all
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
new file mode 100644
index 0000000000..f792aa6346
--- /dev/null
+++ b/lib/bundler/man/bundle-viz.1
@@ -0,0 +1,39 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-VIZ" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
+.
+.SH "SYNOPSIS"
+\fBbundle viz\fR [\-\-file=FILE] [\-\-format=FORMAT] [\-\-requirements] [\-\-version] [\-\-without=GROUP GROUP]
+.
+.SH "DESCRIPTION"
+\fBviz\fR generates a PNG file of the current \fBGemfile(5)\fR as a dependency graph\. \fBviz\fR requires the ruby\-graphviz gem (and its dependencies)\.
+.
+.P
+The associated gems must also be installed via \fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-file\fR, \fB\-f\fR
+The name to use for the generated file\. See \fB\-\-format\fR option
+.
+.TP
+\fB\-\-format\fR, \fB\-F\fR
+This is output format option\. Supported format is png, jpg, svg, dot \.\.\.
+.
+.TP
+\fB\-\-requirements\fR, \fB\-R\fR
+Set to show the version of each required dependency\.
+.
+.TP
+\fB\-\-version\fR, \fB\-v\fR
+Set to show each gem version\.
+.
+.TP
+\fB\-\-without\fR, \fB\-W\fR
+Exclude gems that are part of the specified named group\.
+
diff --git a/lib/bundler/man/bundle-viz.1.ronn b/lib/bundler/man/bundle-viz.1.ronn
new file mode 100644
index 0000000000..701df5415e
--- /dev/null
+++ b/lib/bundler/man/bundle-viz.1.ronn
@@ -0,0 +1,30 @@
+bundle-viz(1) -- Generates a visual dependency graph for your Gemfile
+=====================================================================
+
+## SYNOPSIS
+
+`bundle viz` [--file=FILE]
+ [--format=FORMAT]
+ [--requirements]
+ [--version]
+ [--without=GROUP GROUP]
+
+## DESCRIPTION
+
+`viz` generates a PNG file of the current `Gemfile(5)` as a dependency graph.
+`viz` requires the ruby-graphviz gem (and its dependencies).
+
+The associated gems must also be installed via [`bundle install(1)`](bundle-install.1.html).
+
+## OPTIONS
+
+* `--file`, `-f`:
+ The name to use for the generated file. See `--format` option
+* `--format`, `-F`:
+ This is output format option. Supported format is png, jpg, svg, dot ...
+* `--requirements`, `-R`:
+ Set to show the version of each required dependency.
+* `--version`, `-v`:
+ Set to show each gem version.
+* `--without`, `-W`:
+ Exclude gems that are part of the specified named group.
diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1
new file mode 100644
index 0000000000..b1458bf57b
--- /dev/null
+++ b/lib/bundler/man/bundle.1
@@ -0,0 +1,136 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE" "1" "December 2021" "" ""
+.
+.SH "NAME"
+\fBbundle\fR \- Ruby Dependency Management
+.
+.SH "SYNOPSIS"
+\fBbundle\fR COMMAND [\-\-no\-color] [\-\-verbose] [ARGS]
+.
+.SH "DESCRIPTION"
+Bundler manages an \fBapplication\'s dependencies\fR through its entire life across many machines systematically and repeatably\.
+.
+.P
+See the bundler website \fIhttps://bundler\.io\fR for information on getting started, and Gemfile(5) for more information on the \fBGemfile\fR format\.
+.
+.SH "OPTIONS"
+.
+.TP
+\fB\-\-no\-color\fR
+Print all output without color
+.
+.TP
+\fB\-\-retry\fR, \fB\-r\fR
+Specify the number of times you wish to attempt network commands
+.
+.TP
+\fB\-\-verbose\fR, \fB\-V\fR
+Print out additional logging information
+.
+.SH "BUNDLE COMMANDS"
+We divide \fBbundle\fR subcommands into primary commands and utilities:
+.
+.SH "PRIMARY COMMANDS"
+.
+.TP
+\fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR
+Install the gems specified by the \fBGemfile\fR or \fBGemfile\.lock\fR
+.
+.TP
+\fBbundle update(1)\fR \fIbundle\-update\.1\.html\fR
+Update dependencies to their latest versions
+.
+.TP
+\fBbundle package(1)\fR \fIbundle\-package\.1\.html\fR
+Package the \.gem files required by your application into the \fBvendor/cache\fR directory
+.
+.TP
+\fBbundle exec(1)\fR \fIbundle\-exec\.1\.html\fR
+Execute a script in the current bundle
+.
+.TP
+\fBbundle config(1)\fR \fIbundle\-config\.1\.html\fR
+Specify and read configuration options for Bundler
+.
+.TP
+\fBbundle help(1)\fR
+Display detailed help for each subcommand
+.
+.SH "UTILITIES"
+.
+.TP
+\fBbundle add(1)\fR \fIbundle\-add\.1\.html\fR
+Add the named gem to the Gemfile and run \fBbundle install\fR
+.
+.TP
+\fBbundle binstubs(1)\fR \fIbundle\-binstubs\.1\.html\fR
+Generate binstubs for executables in a gem
+.
+.TP
+\fBbundle check(1)\fR \fIbundle\-check\.1\.html\fR
+Determine whether the requirements for your application are installed and available to Bundler
+.
+.TP
+\fBbundle show(1)\fR \fIbundle\-show\.1\.html\fR
+Show the source location of a particular gem in the bundle
+.
+.TP
+\fBbundle outdated(1)\fR \fIbundle\-outdated\.1\.html\fR
+Show all of the outdated gems in the current bundle
+.
+.TP
+\fBbundle console(1)\fR
+Start an IRB session in the current bundle
+.
+.TP
+\fBbundle open(1)\fR \fIbundle\-open\.1\.html\fR
+Open an installed gem in the editor
+.
+.TP
+\fBbundle lock(1)\fR \fIbundle\-lock\.1\.html\fR
+Generate a lockfile for your dependencies
+.
+.TP
+\fBbundle viz(1)\fR \fIbundle\-viz\.1\.html\fR
+Generate a visual representation of your dependencies
+.
+.TP
+\fBbundle init(1)\fR \fIbundle\-init\.1\.html\fR
+Generate a simple \fBGemfile\fR, placed in the current directory
+.
+.TP
+\fBbundle gem(1)\fR \fIbundle\-gem\.1\.html\fR
+Create a simple gem, suitable for development with Bundler
+.
+.TP
+\fBbundle platform(1)\fR \fIbundle\-platform\.1\.html\fR
+Display platform compatibility information
+.
+.TP
+\fBbundle clean(1)\fR \fIbundle\-clean\.1\.html\fR
+Clean up unused gems in your Bundler directory
+.
+.TP
+\fBbundle doctor(1)\fR \fIbundle\-doctor\.1\.html\fR
+Display warnings about common problems
+.
+.TP
+\fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR
+Removes gems from the Gemfile
+.
+.SH "PLUGINS"
+When running a command that isn\'t listed in PRIMARY COMMANDS or UTILITIES, Bundler will try to find an executable on your path named \fBbundler\-<command>\fR and execute it, passing down any extra arguments to it\.
+.
+.SH "OBSOLETE"
+These commands are obsolete and should no longer be used:
+.
+.IP "\(bu" 4
+\fBbundle cache(1)\fR
+.
+.IP "\(bu" 4
+\fBbundle show(1)\fR
+.
+.IP "" 0
+
diff --git a/lib/bundler/man/bundle.1.ronn b/lib/bundler/man/bundle.1.ronn
new file mode 100644
index 0000000000..5b1712394a
--- /dev/null
+++ b/lib/bundler/man/bundle.1.ronn
@@ -0,0 +1,111 @@
+bundle(1) -- Ruby Dependency Management
+=======================================
+
+## SYNOPSIS
+
+`bundle` COMMAND [--no-color] [--verbose] [ARGS]
+
+## DESCRIPTION
+
+Bundler manages an `application's dependencies` through its entire life
+across many machines systematically and repeatably.
+
+See [the bundler website](https://bundler.io) for information on getting
+started, and Gemfile(5) for more information on the `Gemfile` format.
+
+## OPTIONS
+
+* `--no-color`:
+ Print all output without color
+
+* `--retry`, `-r`:
+ Specify the number of times you wish to attempt network commands
+
+* `--verbose`, `-V`:
+ Print out additional logging information
+
+## BUNDLE COMMANDS
+
+We divide `bundle` subcommands into primary commands and utilities:
+
+## PRIMARY COMMANDS
+
+* [`bundle install(1)`](bundle-install.1.html):
+ Install the gems specified by the `Gemfile` or `Gemfile.lock`
+
+* [`bundle update(1)`](bundle-update.1.html):
+ Update dependencies to their latest versions
+
+* [`bundle package(1)`](bundle-package.1.html):
+ Package the .gem files required by your application into the
+ `vendor/cache` directory
+
+* [`bundle exec(1)`](bundle-exec.1.html):
+ Execute a script in the current bundle
+
+* [`bundle config(1)`](bundle-config.1.html):
+ Specify and read configuration options for Bundler
+
+* `bundle help(1)`:
+ Display detailed help for each subcommand
+
+## UTILITIES
+
+* [`bundle add(1)`](bundle-add.1.html):
+ Add the named gem to the Gemfile and run `bundle install`
+
+* [`bundle binstubs(1)`](bundle-binstubs.1.html):
+ Generate binstubs for executables in a gem
+
+* [`bundle check(1)`](bundle-check.1.html):
+ Determine whether the requirements for your application are installed
+ and available to Bundler
+
+* [`bundle show(1)`](bundle-show.1.html):
+ Show the source location of a particular gem in the bundle
+
+* [`bundle outdated(1)`](bundle-outdated.1.html):
+ Show all of the outdated gems in the current bundle
+
+* `bundle console(1)`:
+ Start an IRB session in the current bundle
+
+* [`bundle open(1)`](bundle-open.1.html):
+ Open an installed gem in the editor
+
+* [`bundle lock(1)`](bundle-lock.1.html):
+ Generate a lockfile for your dependencies
+
+* [`bundle viz(1)`](bundle-viz.1.html):
+ Generate a visual representation of your dependencies
+
+* [`bundle init(1)`](bundle-init.1.html):
+ Generate a simple `Gemfile`, placed in the current directory
+
+* [`bundle gem(1)`](bundle-gem.1.html):
+ Create a simple gem, suitable for development with Bundler
+
+* [`bundle platform(1)`](bundle-platform.1.html):
+ Display platform compatibility information
+
+* [`bundle clean(1)`](bundle-clean.1.html):
+ Clean up unused gems in your Bundler directory
+
+* [`bundle doctor(1)`](bundle-doctor.1.html):
+ Display warnings about common problems
+
+* [`bundle remove(1)`](bundle-remove.1.html):
+ Removes gems from the Gemfile
+
+## PLUGINS
+
+When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES,
+Bundler will try to find an executable on your path named `bundler-<command>`
+and execute it, passing down any extra arguments to it.
+
+## OBSOLETE
+
+These commands are obsolete and should no longer be used:
+
+* `bundle cache(1)`
+* `bundle show(1)`
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
new file mode 100644
index 0000000000..2e423522b7
--- /dev/null
+++ b/lib/bundler/man/gemfile.5
@@ -0,0 +1,712 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "GEMFILE" "5" "December 2021" "" ""
+.
+.SH "NAME"
+\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
+.
+.SH "SYNOPSIS"
+A \fBGemfile\fR describes the gem dependencies required to execute associated Ruby code\.
+.
+.P
+Place the \fBGemfile\fR in the root of the directory containing the associated code\. For instance, in a Rails application, place the \fBGemfile\fR in the same directory as the \fBRakefile\fR\.
+.
+.SH "SYNTAX"
+A \fBGemfile\fR is evaluated as Ruby code, in a context which makes available a number of methods used to describe the gem requirements\.
+.
+.SH "GLOBAL SOURCES"
+At the top of the \fBGemfile\fR, add a line for the \fBRubygems\fR source that contains the gems listed in the \fBGemfile\fR\.
+.
+.IP "" 4
+.
+.nf
+
+source "https://rubygems\.org"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+It is possible, but not recommended as of Bundler 1\.7, to add multiple global \fBsource\fR lines\. Each of these \fBsource\fRs \fBMUST\fR be a valid Rubygems repository\.
+.
+.P
+Sources are checked for gems following the heuristics described in \fISOURCE PRIORITY\fR\. If a gem is found in more than one global source, Bundler will print a warning after installing the gem indicating which source was used, and listing the other sources where the gem is available\. A specific source can be selected for gems that need to use a non\-standard repository, suppressing this warning, by using the \fI\fB:source\fR option\fR or a \fI\fBsource\fR block\fR\.
+.
+.SS "CREDENTIALS"
+Some gem sources require a username and password\. Use bundle config(1) \fIbundle\-config\.1\.html\fR to set the username and password for any of the sources that need it\. The command must be run once on each computer that will install the Gemfile, but this keeps the credentials from being stored in plain text in version control\.
+.
+.IP "" 4
+.
+.nf
+
+bundle config gems\.example\.com user:password
+.
+.fi
+.
+.IP "" 0
+.
+.P
+For some sources, like a company Gemfury account, it may be easier to include the credentials in the Gemfile as part of the source URL\.
+.
+.IP "" 4
+.
+.nf
+
+source "https://user:password@gems\.example\.com"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Credentials in the source URL will take precedence over credentials set using \fBconfig\fR\.
+.
+.SH "RUBY"
+If your application requires a specific Ruby version or engine, specify your requirements using the \fBruby\fR method, with the following arguments\. All parameters are \fBOPTIONAL\fR unless otherwise specified\.
+.
+.SS "VERSION (required)"
+The version of Ruby that your application requires\. If your application requires an alternate Ruby engine, such as JRuby, Rubinius or TruffleRuby, this should be the Ruby version that the engine is compatible with\.
+.
+.IP "" 4
+.
+.nf
+
+ruby "1\.9\.3"
+.
+.fi
+.
+.IP "" 0
+.
+.SS "ENGINE"
+Each application \fImay\fR specify a Ruby engine\. If an engine is specified, an engine version \fImust\fR also be specified\.
+.
+.P
+What exactly is an Engine? \- A Ruby engine is an implementation of the Ruby language\.
+.
+.IP "\(bu" 4
+For background: the reference or original implementation of the Ruby programming language is called Matz\'s Ruby Interpreter \fIhttps://en\.wikipedia\.org/wiki/Ruby_MRI\fR, or MRI for short\. This is named after Ruby creator Yukihiro Matsumoto, also known as Matz\. MRI is also known as CRuby, because it is written in C\. MRI is the most widely used Ruby engine\.
+.
+.IP "\(bu" 4
+Other implementations \fIhttps://www\.ruby\-lang\.org/en/about/\fR of Ruby exist\. Some of the more well\-known implementations include Rubinius \fIhttps://rubinius\.com/\fR, and JRuby \fIhttp://jruby\.org/\fR\. Rubinius is an alternative implementation of Ruby written in Ruby\. JRuby is an implementation of Ruby on the JVM, short for Java Virtual Machine\.
+.
+.IP "" 0
+.
+.SS "ENGINE VERSION"
+Each application \fImay\fR specify a Ruby engine version\. If an engine version is specified, an engine \fImust\fR also be specified\. If the engine is "ruby" the engine version specified \fImust\fR match the Ruby version\.
+.
+.IP "" 4
+.
+.nf
+
+ruby "1\.8\.7", :engine => "jruby", :engine_version => "1\.6\.7"
+.
+.fi
+.
+.IP "" 0
+.
+.SS "PATCHLEVEL"
+Each application \fImay\fR specify a Ruby patchlevel\.
+.
+.IP "" 4
+.
+.nf
+
+ruby "2\.0\.0", :patchlevel => "247"
+.
+.fi
+.
+.IP "" 0
+.
+.SH "GEMS"
+Specify gem requirements using the \fBgem\fR method, with the following arguments\. All parameters are \fBOPTIONAL\fR unless otherwise specified\.
+.
+.SS "NAME (required)"
+For each gem requirement, list a single \fIgem\fR line\.
+.
+.IP "" 4
+.
+.nf
+
+gem "nokogiri"
+.
+.fi
+.
+.IP "" 0
+.
+.SS "VERSION"
+Each \fIgem\fR \fBMAY\fR have one or more version specifiers\.
+.
+.IP "" 4
+.
+.nf
+
+gem "nokogiri", ">= 1\.4\.2"
+gem "RedCloth", ">= 4\.1\.0", "< 4\.2\.0"
+.
+.fi
+.
+.IP "" 0
+.
+.SS "REQUIRE AS"
+Each \fIgem\fR \fBMAY\fR specify files that should be used when autorequiring via \fBBundler\.require\fR\. You may pass an array with multiple files or \fBtrue\fR if the file you want \fBrequired\fR has the same name as \fIgem\fR or \fBfalse\fR to prevent any file from being autorequired\.
+.
+.IP "" 4
+.
+.nf
+
+gem "redis", :require => ["redis/connection/hiredis", "redis"]
+gem "webmock", :require => false
+gem "byebug", :require => true
+.
+.fi
+.
+.IP "" 0
+.
+.P
+The argument defaults to the name of the gem\. For example, these are identical:
+.
+.IP "" 4
+.
+.nf
+
+gem "nokogiri"
+gem "nokogiri", :require => "nokogiri"
+gem "nokogiri", :require => true
+.
+.fi
+.
+.IP "" 0
+.
+.SS "GROUPS"
+Each \fIgem\fR \fBMAY\fR specify membership in one or more groups\. Any \fIgem\fR that does not specify membership in any group is placed in the \fBdefault\fR group\.
+.
+.IP "" 4
+.
+.nf
+
+gem "rspec", :group => :test
+gem "wirble", :groups => [:development, :test]
+.
+.fi
+.
+.IP "" 0
+.
+.P
+The Bundler runtime allows its two main methods, \fBBundler\.setup\fR and \fBBundler\.require\fR, to limit their impact to particular groups\.
+.
+.IP "" 4
+.
+.nf
+
+# setup adds gems to Ruby\'s load path
+Bundler\.setup # defaults to all groups
+require "bundler/setup" # same as Bundler\.setup
+Bundler\.setup(:default) # only set up the _default_ group
+Bundler\.setup(:test) # only set up the _test_ group (but `not` _default_)
+Bundler\.setup(:default, :test) # set up the _default_ and _test_ groups, but no others
+
+# require requires all of the gems in the specified groups
+Bundler\.require # defaults to the _default_ group
+Bundler\.require(:default) # identical
+Bundler\.require(:default, :test) # requires the _default_ and _test_ groups
+Bundler\.require(:test) # requires the _test_ group
+.
+.fi
+.
+.IP "" 0
+.
+.P
+The Bundler CLI allows you to specify a list of groups whose gems \fBbundle install\fR should not install with the \fBwithout\fR configuration\.
+.
+.P
+To specify multiple groups to ignore, specify a list of groups separated by spaces\.
+.
+.IP "" 4
+.
+.nf
+
+bundle config set \-\-local without test
+bundle config set \-\-local without development test
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Also, calling \fBBundler\.setup\fR with no parameters, or calling \fBrequire "bundler/setup"\fR will setup all groups except for the ones you excluded via \fB\-\-without\fR (since they are not available)\.
+.
+.P
+Note that on \fBbundle install\fR, bundler downloads and evaluates all gems, in order to create a single canonical list of all of the required gems and their dependencies\. This means that you cannot list different versions of the same gems in different groups\. For more details, see Understanding Bundler \fIhttps://bundler\.io/rationale\.html\fR\.
+.
+.SS "PLATFORMS"
+If a gem should only be used in a particular platform or set of platforms, you can specify them\. Platforms are essentially identical to groups, except that you do not need to use the \fB\-\-without\fR install\-time flag to exclude groups of gems for other platforms\.
+.
+.P
+There are a number of \fBGemfile\fR platforms:
+.
+.TP
+\fBruby\fR
+C Ruby (MRI), Rubinius or TruffleRuby, but \fBNOT\fR Windows
+.
+.TP
+\fBmri\fR
+Same as \fIruby\fR, but only C Ruby (MRI)
+.
+.TP
+\fBmingw\fR
+Windows 32 bit \'mingw32\' platform (aka RubyInstaller)
+.
+.TP
+\fBx64_mingw\fR
+Windows 64 bit \'mingw32\' platform (aka RubyInstaller x64)
+.
+.TP
+\fBrbx\fR
+Rubinius
+.
+.TP
+\fBjruby\fR
+JRuby
+.
+.TP
+\fBtruffleruby\fR
+TruffleRuby
+.
+.TP
+\fBmswin\fR
+Windows
+.
+.P
+You can restrict further by platform and version for all platforms \fIexcept\fR for \fBrbx\fR, \fBjruby\fR, \fBtruffleruby\fR and \fBmswin\fR\.
+.
+.P
+To specify a version in addition to a platform, append the version number without the delimiter to the platform\. For example, to specify that a gem should only be used on platforms with Ruby 2\.3, use:
+.
+.IP "" 4
+.
+.nf
+
+ruby_23
+.
+.fi
+.
+.IP "" 0
+.
+.P
+The full list of platforms and supported versions includes:
+.
+.TP
+\fBruby\fR
+1\.8, 1\.9, 2\.0, 2\.1, 2\.2, 2\.3, 2\.4, 2\.5, 2\.6
+.
+.TP
+\fBmri\fR
+1\.8, 1\.9, 2\.0, 2\.1, 2\.2, 2\.3, 2\.4, 2\.5, 2\.6
+.
+.TP
+\fBmingw\fR
+1\.8, 1\.9, 2\.0, 2\.1, 2\.2, 2\.3, 2\.4, 2\.5, 2\.6
+.
+.TP
+\fBx64_mingw\fR
+2\.0, 2\.1, 2\.2, 2\.3, 2\.4, 2\.5, 2\.6
+.
+.P
+As with groups, you can specify one or more platforms:
+.
+.IP "" 4
+.
+.nf
+
+gem "weakling", :platforms => :jruby
+gem "ruby\-debug", :platforms => :mri_18
+gem "nokogiri", :platforms => [:mri_18, :jruby]
+.
+.fi
+.
+.IP "" 0
+.
+.P
+All operations involving groups (\fBbundle install\fR \fIbundle\-install\.1\.html\fR, \fBBundler\.setup\fR, \fBBundler\.require\fR) behave exactly the same as if any groups not matching the current platform were explicitly excluded\.
+.
+.SS "SOURCE"
+You can select an alternate Rubygems repository for a gem using the \':source\' option\.
+.
+.IP "" 4
+.
+.nf
+
+gem "some_internal_gem", :source => "https://gems\.example\.com"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+This forces the gem to be loaded from this source and ignores any global sources declared at the top level of the file\. If the gem does not exist in this source, it will not be installed\.
+.
+.P
+Bundler will search for child dependencies of this gem by first looking in the source selected for the parent, but if they are not found there, it will fall back on global sources using the ordering described in \fISOURCE PRIORITY\fR\.
+.
+.P
+Selecting a specific source repository this way also suppresses the ambiguous gem warning described above in \fIGLOBAL SOURCES (#source)\fR\.
+.
+.P
+Using the \fB:source\fR option for an individual gem will also make that source available as a possible global source for any other gems which do not specify explicit sources\. Thus, when adding gems with explicit sources, it is recommended that you also ensure all other gems in the Gemfile are using explicit sources\.
+.
+.SS "GIT"
+If necessary, you can specify that a gem is located at a particular git repository using the \fB:git\fR parameter\. The repository can be accessed via several protocols:
+.
+.TP
+\fBHTTP(S)\fR
+gem "rails", :git => "https://github\.com/rails/rails\.git"
+.
+.TP
+\fBSSH\fR
+gem "rails", :git => "git@github\.com:rails/rails\.git"
+.
+.TP
+\fBgit\fR
+gem "rails", :git => "git://github\.com/rails/rails\.git"
+.
+.P
+If using SSH, the user that you use to run \fBbundle install\fR \fBMUST\fR have the appropriate keys available in their \fB$HOME/\.ssh\fR\.
+.
+.P
+\fBNOTE\fR: \fBhttp://\fR and \fBgit://\fR URLs should be avoided if at all possible\. These protocols are unauthenticated, so a man\-in\-the\-middle attacker can deliver malicious code and compromise your system\. HTTPS and SSH are strongly preferred\.
+.
+.P
+The \fBgroup\fR, \fBplatforms\fR, and \fBrequire\fR options are available and behave exactly the same as they would for a normal gem\.
+.
+.P
+A git repository \fBSHOULD\fR have at least one file, at the root of the directory containing the gem, with the extension \fB\.gemspec\fR\. This file \fBMUST\fR contain a valid gem specification, as expected by the \fBgem build\fR command\.
+.
+.P
+If a git repository does not have a \fB\.gemspec\fR, bundler will attempt to create one, but it will not contain any dependencies, executables, or C extension compilation instructions\. As a result, it may fail to properly integrate into your application\.
+.
+.P
+If a git repository does have a \fB\.gemspec\fR for the gem you attached it to, a version specifier, if provided, means that the git repository is only valid if the \fB\.gemspec\fR specifies a version matching the version specifier\. If not, bundler will print a warning\.
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", "2\.3\.8", :git => "https://github\.com/rails/rails\.git"
+# bundle install will fail, because the \.gemspec in the rails
+# repository\'s master branch specifies version 3\.0\.0
+.
+.fi
+.
+.IP "" 0
+.
+.P
+If a git repository does \fBnot\fR have a \fB\.gemspec\fR for the gem you attached it to, a version specifier \fBMUST\fR be provided\. Bundler will use this version in the simple \fB\.gemspec\fR it creates\.
+.
+.P
+Git repositories support a number of additional options\.
+.
+.TP
+\fBbranch\fR, \fBtag\fR, and \fBref\fR
+You \fBMUST\fR only specify at most one of these options\. The default is \fB:branch => "master"\fR\. For example:
+.
+.IP
+gem "rails", :git => "https://github\.com/rails/rails\.git", :branch => "5\-0\-stable"
+.
+.IP
+gem "rails", :git => "https://github\.com/rails/rails\.git", :tag => "v5\.0\.0"
+.
+.IP
+gem "rails", :git => "https://github\.com/rails/rails\.git", :ref => "4aded"
+.
+.TP
+\fBsubmodules\fR
+For reference, a git submodule \fIhttps://git\-scm\.com/book/en/v2/Git\-Tools\-Submodules\fR lets you have another git repository within a subfolder of your repository\. Specify \fB:submodules => true\fR to cause bundler to expand any submodules included in the git repository
+.
+.P
+If a git repository contains multiple \fB\.gemspecs\fR, each \fB\.gemspec\fR represents a gem located at the same place in the file system as the \fB\.gemspec\fR\.
+.
+.IP "" 4
+.
+.nf
+
+|~rails [git root]
+| |\-rails\.gemspec [rails gem located here]
+|~actionpack
+| |\-actionpack\.gemspec [actionpack gem located here]
+|~activesupport
+| |\-activesupport\.gemspec [activesupport gem located here]
+|\.\.\.
+.
+.fi
+.
+.IP "" 0
+.
+.P
+To install a gem located in a git repository, bundler changes to the directory containing the gemspec, runs \fBgem build name\.gemspec\fR and then installs the resulting gem\. The \fBgem build\fR command, which comes standard with Rubygems, evaluates the \fB\.gemspec\fR in the context of the directory in which it is located\.
+.
+.SS "GIT SOURCE"
+A custom git source can be defined via the \fBgit_source\fR method\. Provide the source\'s name as an argument, and a block which receives a single argument and interpolates it into a string to return the full repo address:
+.
+.IP "" 4
+.
+.nf
+
+git_source(:stash){ |repo_name| "https://stash\.corp\.acme\.pl/#{repo_name}\.git" }
+gem \'rails\', :stash => \'forks/rails\'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In addition, if you wish to choose a specific branch:
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :stash => "forks/rails", :branch => "branch_name"
+.
+.fi
+.
+.IP "" 0
+.
+.SS "GITHUB"
+\fBNOTE\fR: This shorthand should be avoided until Bundler 2\.0, since it currently expands to an insecure \fBgit://\fR URL\. This allows a man\-in\-the\-middle attacker to compromise your system\.
+.
+.P
+If the git repository you want to use is hosted on GitHub and is public, you can use the :github shorthand to specify the github username and repository name (without the trailing "\.git"), separated by a slash\. If both the username and repository name are the same, you can omit one\.
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :github => "rails/rails"
+gem "rails", :github => "rails"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Are both equivalent to
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :git => "git://github\.com/rails/rails\.git"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Since the \fBgithub\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\.
+.
+.P
+You can also directly pass a pull request URL:
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :github => "https://github\.com/rails/rails/pull/43753"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Which is equivalent to:
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :github => "rails/rails", branch: "refs/pull/43753/head"
+.
+.fi
+.
+.IP "" 0
+.
+.SS "GIST"
+If the git repository you want to use is hosted as a Github Gist and is public, you can use the :gist shorthand to specify the gist identifier (without the trailing "\.git")\.
+.
+.IP "" 4
+.
+.nf
+
+gem "the_hatch", :gist => "4815162342"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Is equivalent to:
+.
+.IP "" 4
+.
+.nf
+
+gem "the_hatch", :git => "https://gist\.github\.com/4815162342\.git"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Since the \fBgist\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\.
+.
+.SS "BITBUCKET"
+If the git repository you want to use is hosted on Bitbucket and is public, you can use the :bitbucket shorthand to specify the bitbucket username and repository name (without the trailing "\.git"), separated by a slash\. If both the username and repository name are the same, you can omit one\.
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :bitbucket => "rails/rails"
+gem "rails", :bitbucket => "rails"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Are both equivalent to
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :git => "https://rails@bitbucket\.org/rails/rails\.git"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Since the \fBbitbucket\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\.
+.
+.SS "PATH"
+You can specify that a gem is located in a particular location on the file system\. Relative paths are resolved relative to the directory containing the \fBGemfile\fR\.
+.
+.P
+Similar to the semantics of the \fB:git\fR option, the \fB:path\fR option requires that the directory in question either contains a \fB\.gemspec\fR for the gem, or that you specify an explicit version that bundler should use\.
+.
+.P
+Unlike \fB:git\fR, bundler does not compile C extensions for gems specified as paths\.
+.
+.IP "" 4
+.
+.nf
+
+gem "rails", :path => "vendor/rails"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+If you would like to use multiple local gems directly from the filesystem, you can set a global \fBpath\fR option to the path containing the gem\'s files\. This will automatically load gemspec files from subdirectories\.
+.
+.IP "" 4
+.
+.nf
+
+path \'components\' do
+ gem \'admin_ui\'
+ gem \'public_ui\'
+end
+.
+.fi
+.
+.IP "" 0
+.
+.SH "BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS"
+The \fB:source\fR, \fB:git\fR, \fB:path\fR, \fB:group\fR, and \fB:platforms\fR options may be applied to a group of gems by using block form\.
+.
+.IP "" 4
+.
+.nf
+
+source "https://gems\.example\.com" do
+ gem "some_internal_gem"
+ gem "another_internal_gem"
+end
+
+git "https://github\.com/rails/rails\.git" do
+ gem "activesupport"
+ gem "actionpack"
+end
+
+platforms :ruby do
+ gem "ruby\-debug"
+ gem "sqlite3"
+end
+
+group :development, :optional => true do
+ gem "wirble"
+ gem "faker"
+end
+.
+.fi
+.
+.IP "" 0
+.
+.P
+In the case of the group block form the :optional option can be given to prevent a group from being installed unless listed in the \fB\-\-with\fR option given to the \fBbundle install\fR command\.
+.
+.P
+In the case of the \fBgit\fR block form, the \fB:ref\fR, \fB:branch\fR, \fB:tag\fR, and \fB:submodules\fR options may be passed to the \fBgit\fR method, and all gems in the block will inherit those options\.
+.
+.P
+The presence of a \fBsource\fR block in a Gemfile also makes that source available as a possible global source for any other gems which do not specify explicit sources\. Thus, when defining source blocks, it is recommended that you also ensure all other gems in the Gemfile are using explicit sources, either via source blocks or \fB:source\fR directives on individual gems\.
+.
+.SH "INSTALL_IF"
+The \fBinstall_if\fR method allows gems to be installed based on a proc or lambda\. This is especially useful for optional gems that can only be used if certain software is installed or some other conditions are met\.
+.
+.IP "" 4
+.
+.nf
+
+install_if \-> { RUBY_PLATFORM =~ /darwin/ } do
+ gem "pasteboard"
+end
+.
+.fi
+.
+.IP "" 0
+.
+.SH "GEMSPEC"
+The \fB\.gemspec\fR \fIhttp://guides\.rubygems\.org/specification\-reference/\fR file is where you provide metadata about your gem to Rubygems\. Some required Gemspec attributes include the name, description, and homepage of your gem\. This is also where you specify the dependencies your gem needs to run\.
+.
+.P
+If you wish to use Bundler to help install dependencies for a gem while it is being developed, use the \fBgemspec\fR method to pull in the dependencies listed in the \fB\.gemspec\fR file\.
+.
+.P
+The \fBgemspec\fR method adds any runtime dependencies as gem requirements in the default group\. It also adds development dependencies as gem requirements in the \fBdevelopment\fR group\. Finally, it adds a gem requirement on your project (\fB:path => \'\.\'\fR)\. In conjunction with \fBBundler\.setup\fR, this allows you to require project files in your test code as you would if the project were installed as a gem; you need not manipulate the load path manually or require project files via relative paths\.
+.
+.P
+The \fBgemspec\fR method supports optional \fB:path\fR, \fB:glob\fR, \fB:name\fR, and \fB:development_group\fR options, which control where bundler looks for the \fB\.gemspec\fR, the glob it uses to look for the gemspec (defaults to: "{,\fI,\fR/*}\.gemspec"), what named \fB\.gemspec\fR it uses (if more than one is present), and which group development dependencies are included in\.
+.
+.P
+When a \fBgemspec\fR dependency encounters version conflicts during resolution, the local version under development will always be selected \-\- even if there are remote versions that better match other requirements for the \fBgemspec\fR gem\.
+.
+.SH "SOURCE PRIORITY"
+When attempting to locate a gem to satisfy a gem requirement, bundler uses the following priority order:
+.
+.IP "1." 4
+The source explicitly attached to the gem (using \fB:source\fR, \fB:path\fR, or \fB:git\fR)
+.
+.IP "2." 4
+For implicit gems (dependencies of explicit gems), any source, git, or path repository declared on the parent\. This results in bundler prioritizing the ActiveSupport gem from the Rails git repository over ones from \fBrubygems\.org\fR
+.
+.IP "3." 4
+The sources specified via global \fBsource\fR lines, searching each source in your \fBGemfile\fR from last added to first added\.
+.
+.IP "" 0
+
diff --git a/lib/bundler/man/gemfile.5.ronn b/lib/bundler/man/gemfile.5.ronn
new file mode 100644
index 0000000000..20ce3242ae
--- /dev/null
+++ b/lib/bundler/man/gemfile.5.ronn
@@ -0,0 +1,525 @@
+Gemfile(5) -- A format for describing gem dependencies for Ruby programs
+========================================================================
+
+## SYNOPSIS
+
+A `Gemfile` describes the gem dependencies required to execute associated
+Ruby code.
+
+Place the `Gemfile` in the root of the directory containing the associated
+code. For instance, in a Rails application, place the `Gemfile` in the same
+directory as the `Rakefile`.
+
+## SYNTAX
+
+A `Gemfile` is evaluated as Ruby code, in a context which makes available
+a number of methods used to describe the gem requirements.
+
+## GLOBAL SOURCES
+
+At the top of the `Gemfile`, add a line for the `Rubygems` source that contains
+the gems listed in the `Gemfile`.
+
+ source "https://rubygems.org"
+
+It is possible, but not recommended as of Bundler 1.7, to add multiple global
+`source` lines. Each of these `source`s `MUST` be a valid Rubygems repository.
+
+Sources are checked for gems following the heuristics described in
+[SOURCE PRIORITY][]. If a gem is found in more than one global source, Bundler
+will print a warning after installing the gem indicating which source was used,
+and listing the other sources where the gem is available. A specific source can
+be selected for gems that need to use a non-standard repository, suppressing
+this warning, by using the [`:source` option](#SOURCE) or a
+[`source` block](#BLOCK-FORM-OF-SOURCE-GIT-PATH-GROUP-and-PLATFORMS).
+
+### CREDENTIALS
+
+Some gem sources require a username and password. Use [bundle config(1)](bundle-config.1.html) to set
+the username and password for any of the sources that need it. The command must
+be run once on each computer that will install the Gemfile, but this keeps the
+credentials from being stored in plain text in version control.
+
+ bundle config gems.example.com user:password
+
+For some sources, like a company Gemfury account, it may be easier to
+include the credentials in the Gemfile as part of the source URL.
+
+ source "https://user:password@gems.example.com"
+
+Credentials in the source URL will take precedence over credentials set using
+`config`.
+
+## RUBY
+
+If your application requires a specific Ruby version or engine, specify your
+requirements using the `ruby` method, with the following arguments.
+All parameters are `OPTIONAL` unless otherwise specified.
+
+### VERSION (required)
+
+The version of Ruby that your application requires. If your application
+requires an alternate Ruby engine, such as JRuby, Rubinius or TruffleRuby, this
+should be the Ruby version that the engine is compatible with.
+
+ ruby "1.9.3"
+
+### ENGINE
+
+Each application _may_ specify a Ruby engine. If an engine is specified, an
+engine version _must_ also be specified.
+
+What exactly is an Engine?
+ - A Ruby engine is an implementation of the Ruby language.
+
+ - For background: the reference or original implementation of the Ruby
+ programming language is called
+ [Matz's Ruby Interpreter](https://en.wikipedia.org/wiki/Ruby_MRI), or MRI
+ for short. This is named after Ruby creator Yukihiro Matsumoto,
+ also known as Matz. MRI is also known as CRuby, because it is written in C.
+ MRI is the most widely used Ruby engine.
+
+ - [Other implementations](https://www.ruby-lang.org/en/about/) of Ruby exist.
+ Some of the more well-known implementations include
+ [Rubinius](https://rubinius.com/), and [JRuby](http://jruby.org/).
+ Rubinius is an alternative implementation of Ruby written in Ruby.
+ JRuby is an implementation of Ruby on the JVM, short for Java Virtual Machine.
+
+### ENGINE VERSION
+
+Each application _may_ specify a Ruby engine version. If an engine version is
+specified, an engine _must_ also be specified. If the engine is "ruby" the
+engine version specified _must_ match the Ruby version.
+
+ ruby "1.8.7", :engine => "jruby", :engine_version => "1.6.7"
+
+### PATCHLEVEL
+
+Each application _may_ specify a Ruby patchlevel.
+
+ ruby "2.0.0", :patchlevel => "247"
+
+## GEMS
+
+Specify gem requirements using the `gem` method, with the following arguments.
+All parameters are `OPTIONAL` unless otherwise specified.
+
+### NAME (required)
+
+For each gem requirement, list a single _gem_ line.
+
+ gem "nokogiri"
+
+### VERSION
+
+Each _gem_ `MAY` have one or more version specifiers.
+
+ gem "nokogiri", ">= 1.4.2"
+ gem "RedCloth", ">= 4.1.0", "< 4.2.0"
+
+### REQUIRE AS
+
+Each _gem_ `MAY` specify files that should be used when autorequiring via
+`Bundler.require`. You may pass an array with multiple files or `true` if the file
+you want `required` has the same name as _gem_ or `false` to
+prevent any file from being autorequired.
+
+ gem "redis", :require => ["redis/connection/hiredis", "redis"]
+ gem "webmock", :require => false
+ gem "byebug", :require => true
+
+The argument defaults to the name of the gem. For example, these are identical:
+
+ gem "nokogiri"
+ gem "nokogiri", :require => "nokogiri"
+ gem "nokogiri", :require => true
+
+### GROUPS
+
+Each _gem_ `MAY` specify membership in one or more groups. Any _gem_ that does
+not specify membership in any group is placed in the `default` group.
+
+ gem "rspec", :group => :test
+ gem "wirble", :groups => [:development, :test]
+
+The Bundler runtime allows its two main methods, `Bundler.setup` and
+`Bundler.require`, to limit their impact to particular groups.
+
+ # setup adds gems to Ruby's load path
+ Bundler.setup # defaults to all groups
+ require "bundler/setup" # same as Bundler.setup
+ Bundler.setup(:default) # only set up the _default_ group
+ Bundler.setup(:test) # only set up the _test_ group (but `not` _default_)
+ Bundler.setup(:default, :test) # set up the _default_ and _test_ groups, but no others
+
+ # require requires all of the gems in the specified groups
+ Bundler.require # defaults to the _default_ group
+ Bundler.require(:default) # identical
+ Bundler.require(:default, :test) # requires the _default_ and _test_ groups
+ Bundler.require(:test) # requires the _test_ group
+
+The Bundler CLI allows you to specify a list of groups whose gems `bundle install` should
+not install with the `without` configuration.
+
+To specify multiple groups to ignore, specify a list of groups separated by spaces.
+
+ bundle config set --local without test
+ bundle config set --local without development test
+
+Also, calling `Bundler.setup` with no parameters, or calling `require "bundler/setup"`
+will setup all groups except for the ones you excluded via `--without` (since they
+are not available).
+
+Note that on `bundle install`, bundler downloads and evaluates all gems, in order to
+create a single canonical list of all of the required gems and their dependencies.
+This means that you cannot list different versions of the same gems in different
+groups. For more details, see [Understanding Bundler](https://bundler.io/rationale.html).
+
+### PLATFORMS
+
+If a gem should only be used in a particular platform or set of platforms, you can
+specify them. Platforms are essentially identical to groups, except that you do not
+need to use the `--without` install-time flag to exclude groups of gems for other
+platforms.
+
+There are a number of `Gemfile` platforms:
+
+ * `ruby`:
+ C Ruby (MRI), Rubinius or TruffleRuby, but `NOT` Windows
+ * `mri`:
+ Same as _ruby_, but only C Ruby (MRI)
+ * `mingw`:
+ Windows 32 bit 'mingw32' platform (aka RubyInstaller)
+ * `x64_mingw`:
+ Windows 64 bit 'mingw32' platform (aka RubyInstaller x64)
+ * `rbx`:
+ Rubinius
+ * `jruby`:
+ JRuby
+ * `truffleruby`:
+ TruffleRuby
+ * `mswin`:
+ Windows
+
+You can restrict further by platform and version for all platforms *except* for
+`rbx`, `jruby`, `truffleruby` and `mswin`.
+
+To specify a version in addition to a platform, append the version number without
+the delimiter to the platform. For example, to specify that a gem should only be
+used on platforms with Ruby 2.3, use:
+
+ ruby_23
+
+The full list of platforms and supported versions includes:
+
+ * `ruby`:
+ 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6
+ * `mri`:
+ 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6
+ * `mingw`:
+ 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6
+ * `x64_mingw`:
+ 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6
+
+As with groups, you can specify one or more platforms:
+
+ gem "weakling", :platforms => :jruby
+ gem "ruby-debug", :platforms => :mri_18
+ gem "nokogiri", :platforms => [:mri_18, :jruby]
+
+All operations involving groups ([`bundle install`](bundle-install.1.html), `Bundler.setup`,
+`Bundler.require`) behave exactly the same as if any groups not
+matching the current platform were explicitly excluded.
+
+### SOURCE
+
+You can select an alternate Rubygems repository for a gem using the ':source'
+option.
+
+ gem "some_internal_gem", :source => "https://gems.example.com"
+
+This forces the gem to be loaded from this source and ignores any global sources
+declared at the top level of the file. If the gem does not exist in this source,
+it will not be installed.
+
+Bundler will search for child dependencies of this gem by first looking in the
+source selected for the parent, but if they are not found there, it will fall
+back on global sources using the ordering described in [SOURCE PRIORITY][].
+
+Selecting a specific source repository this way also suppresses the ambiguous
+gem warning described above in
+[GLOBAL SOURCES (#source)](#GLOBAL-SOURCES).
+
+Using the `:source` option for an individual gem will also make that source
+available as a possible global source for any other gems which do not specify
+explicit sources. Thus, when adding gems with explicit sources, it is
+recommended that you also ensure all other gems in the Gemfile are using
+explicit sources.
+
+### GIT
+
+If necessary, you can specify that a gem is located at a particular
+git repository using the `:git` parameter. The repository can be accessed via
+several protocols:
+
+ * `HTTP(S)`:
+ gem "rails", :git => "https://github.com/rails/rails.git"
+ * `SSH`:
+ gem "rails", :git => "git@github.com:rails/rails.git"
+ * `git`:
+ gem "rails", :git => "git://github.com/rails/rails.git"
+
+If using SSH, the user that you use to run `bundle install` `MUST` have the
+appropriate keys available in their `$HOME/.ssh`.
+
+`NOTE`: `http://` and `git://` URLs should be avoided if at all possible. These
+protocols are unauthenticated, so a man-in-the-middle attacker can deliver
+malicious code and compromise your system. HTTPS and SSH are strongly
+preferred.
+
+The `group`, `platforms`, and `require` options are available and behave
+exactly the same as they would for a normal gem.
+
+A git repository `SHOULD` have at least one file, at the root of the
+directory containing the gem, with the extension `.gemspec`. This file
+`MUST` contain a valid gem specification, as expected by the `gem build`
+command.
+
+If a git repository does not have a `.gemspec`, bundler will attempt to
+create one, but it will not contain any dependencies, executables, or
+C extension compilation instructions. As a result, it may fail to properly
+integrate into your application.
+
+If a git repository does have a `.gemspec` for the gem you attached it
+to, a version specifier, if provided, means that the git repository is
+only valid if the `.gemspec` specifies a version matching the version
+specifier. If not, bundler will print a warning.
+
+ gem "rails", "2.3.8", :git => "https://github.com/rails/rails.git"
+ # bundle install will fail, because the .gemspec in the rails
+ # repository's master branch specifies version 3.0.0
+
+If a git repository does `not` have a `.gemspec` for the gem you attached
+it to, a version specifier `MUST` be provided. Bundler will use this
+version in the simple `.gemspec` it creates.
+
+Git repositories support a number of additional options.
+
+ * `branch`, `tag`, and `ref`:
+ You `MUST` only specify at most one of these options. The default
+ is `:branch => "master"`. For example:
+
+ gem "rails", :git => "https://github.com/rails/rails.git", :branch => "5-0-stable"
+
+ gem "rails", :git => "https://github.com/rails/rails.git", :tag => "v5.0.0"
+
+ gem "rails", :git => "https://github.com/rails/rails.git", :ref => "4aded"
+
+ * `submodules`:
+ For reference, a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules)
+ lets you have another git repository within a subfolder of your repository.
+ Specify `:submodules => true` to cause bundler to expand any
+ submodules included in the git repository
+
+If a git repository contains multiple `.gemspecs`, each `.gemspec`
+represents a gem located at the same place in the file system as
+the `.gemspec`.
+
+ |~rails [git root]
+ | |-rails.gemspec [rails gem located here]
+ |~actionpack
+ | |-actionpack.gemspec [actionpack gem located here]
+ |~activesupport
+ | |-activesupport.gemspec [activesupport gem located here]
+ |...
+
+To install a gem located in a git repository, bundler changes to
+the directory containing the gemspec, runs `gem build name.gemspec`
+and then installs the resulting gem. The `gem build` command,
+which comes standard with Rubygems, evaluates the `.gemspec` in
+the context of the directory in which it is located.
+
+### GIT SOURCE
+
+A custom git source can be defined via the `git_source` method. Provide the source's name
+as an argument, and a block which receives a single argument and interpolates it into a
+string to return the full repo address:
+
+ git_source(:stash){ |repo_name| "https://stash.corp.acme.pl/#{repo_name}.git" }
+ gem 'rails', :stash => 'forks/rails'
+
+In addition, if you wish to choose a specific branch:
+
+ gem "rails", :stash => "forks/rails", :branch => "branch_name"
+
+### GITHUB
+
+`NOTE`: This shorthand should be avoided until Bundler 2.0, since it
+currently expands to an insecure `git://` URL. This allows a
+man-in-the-middle attacker to compromise your system.
+
+If the git repository you want to use is hosted on GitHub and is public, you can use the
+:github shorthand to specify the github username and repository name (without the
+trailing ".git"), separated by a slash. If both the username and repository name are the
+same, you can omit one.
+
+ gem "rails", :github => "rails/rails"
+ gem "rails", :github => "rails"
+
+Are both equivalent to
+
+ gem "rails", :git => "git://github.com/rails/rails.git"
+
+Since the `github` method is a specialization of `git_source`, it accepts a `:branch` named argument.
+
+You can also directly pass a pull request URL:
+
+ gem "rails", :github => "https://github.com/rails/rails/pull/43753"
+
+Which is equivalent to:
+
+ gem "rails", :github => "rails/rails", branch: "refs/pull/43753/head"
+
+### GIST
+
+If the git repository you want to use is hosted as a Github Gist and is public, you can use
+the :gist shorthand to specify the gist identifier (without the trailing ".git").
+
+ gem "the_hatch", :gist => "4815162342"
+
+Is equivalent to:
+
+ gem "the_hatch", :git => "https://gist.github.com/4815162342.git"
+
+Since the `gist` method is a specialization of `git_source`, it accepts a `:branch` named argument.
+
+### BITBUCKET
+
+If the git repository you want to use is hosted on Bitbucket and is public, you can use the
+:bitbucket shorthand to specify the bitbucket username and repository name (without the
+trailing ".git"), separated by a slash. If both the username and repository name are the
+same, you can omit one.
+
+ gem "rails", :bitbucket => "rails/rails"
+ gem "rails", :bitbucket => "rails"
+
+Are both equivalent to
+
+ gem "rails", :git => "https://rails@bitbucket.org/rails/rails.git"
+
+Since the `bitbucket` method is a specialization of `git_source`, it accepts a `:branch` named argument.
+
+### PATH
+
+You can specify that a gem is located in a particular location
+on the file system. Relative paths are resolved relative to the
+directory containing the `Gemfile`.
+
+Similar to the semantics of the `:git` option, the `:path`
+option requires that the directory in question either contains
+a `.gemspec` for the gem, or that you specify an explicit
+version that bundler should use.
+
+Unlike `:git`, bundler does not compile C extensions for
+gems specified as paths.
+
+ gem "rails", :path => "vendor/rails"
+
+If you would like to use multiple local gems directly from the filesystem, you can set a global `path` option to the path containing the gem's files. This will automatically load gemspec files from subdirectories.
+
+ path 'components' do
+ gem 'admin_ui'
+ gem 'public_ui'
+ end
+
+## BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS
+
+The `:source`, `:git`, `:path`, `:group`, and `:platforms` options may be
+applied to a group of gems by using block form.
+
+ source "https://gems.example.com" do
+ gem "some_internal_gem"
+ gem "another_internal_gem"
+ end
+
+ git "https://github.com/rails/rails.git" do
+ gem "activesupport"
+ gem "actionpack"
+ end
+
+ platforms :ruby do
+ gem "ruby-debug"
+ gem "sqlite3"
+ end
+
+ group :development, :optional => true do
+ gem "wirble"
+ gem "faker"
+ end
+
+In the case of the group block form the :optional option can be given
+to prevent a group from being installed unless listed in the `--with`
+option given to the `bundle install` command.
+
+In the case of the `git` block form, the `:ref`, `:branch`, `:tag`,
+and `:submodules` options may be passed to the `git` method, and
+all gems in the block will inherit those options.
+
+The presence of a `source` block in a Gemfile also makes that source
+available as a possible global source for any other gems which do not specify
+explicit sources. Thus, when defining source blocks, it is
+recommended that you also ensure all other gems in the Gemfile are using
+explicit sources, either via source blocks or `:source` directives on
+individual gems.
+
+## INSTALL_IF
+
+The `install_if` method allows gems to be installed based on a proc or lambda.
+This is especially useful for optional gems that can only be used if certain
+software is installed or some other conditions are met.
+
+ install_if -> { RUBY_PLATFORM =~ /darwin/ } do
+ gem "pasteboard"
+ end
+
+## GEMSPEC
+
+The [`.gemspec`](http://guides.rubygems.org/specification-reference/) file is where
+ you provide metadata about your gem to Rubygems. Some required Gemspec
+ attributes include the name, description, and homepage of your gem. This is
+ also where you specify the dependencies your gem needs to run.
+
+If you wish to use Bundler to help install dependencies for a gem while it is
+being developed, use the `gemspec` method to pull in the dependencies listed in
+the `.gemspec` file.
+
+The `gemspec` method adds any runtime dependencies as gem requirements in the
+default group. It also adds development dependencies as gem requirements in the
+`development` group. Finally, it adds a gem requirement on your project (`:path
+=> '.'`). In conjunction with `Bundler.setup`, this allows you to require project
+files in your test code as you would if the project were installed as a gem; you
+need not manipulate the load path manually or require project files via relative
+paths.
+
+The `gemspec` method supports optional `:path`, `:glob`, `:name`, and `:development_group`
+options, which control where bundler looks for the `.gemspec`, the glob it uses to look
+for the gemspec (defaults to: "{,*,*/*}.gemspec"), what named `.gemspec` it uses
+(if more than one is present), and which group development dependencies are included in.
+
+When a `gemspec` dependency encounters version conflicts during resolution, the
+local version under development will always be selected -- even if there are
+remote versions that better match other requirements for the `gemspec` gem.
+
+## SOURCE PRIORITY
+
+When attempting to locate a gem to satisfy a gem requirement,
+bundler uses the following priority order:
+
+ 1. The source explicitly attached to the gem (using `:source`, `:path`, or
+ `:git`)
+ 2. For implicit gems (dependencies of explicit gems), any source, git, or path
+ repository declared on the parent. This results in bundler prioritizing the
+ ActiveSupport gem from the Rails git repository over ones from
+ `rubygems.org`
+ 3. The sources specified via global `source` lines, searching each source in
+ your `Gemfile` from last added to first added.
diff --git a/lib/bundler/man/index.txt b/lib/bundler/man/index.txt
new file mode 100644
index 0000000000..ef2956b2f9
--- /dev/null
+++ b/lib/bundler/man/index.txt
@@ -0,0 +1,25 @@
+Gemfile(5) gemfile.5
+bundle(1) bundle.1
+bundle-add(1) bundle-add.1
+bundle-binstubs(1) bundle-binstubs.1
+bundle-cache(1) bundle-cache.1
+bundle-check(1) bundle-check.1
+bundle-clean(1) bundle-clean.1
+bundle-config(1) bundle-config.1
+bundle-doctor(1) bundle-doctor.1
+bundle-exec(1) bundle-exec.1
+bundle-gem(1) bundle-gem.1
+bundle-info(1) bundle-info.1
+bundle-init(1) bundle-init.1
+bundle-inject(1) bundle-inject.1
+bundle-install(1) bundle-install.1
+bundle-list(1) bundle-list.1
+bundle-lock(1) bundle-lock.1
+bundle-open(1) bundle-open.1
+bundle-outdated(1) bundle-outdated.1
+bundle-platform(1) bundle-platform.1
+bundle-pristine(1) bundle-pristine.1
+bundle-remove(1) bundle-remove.1
+bundle-show(1) bundle-show.1
+bundle-update(1) bundle-update.1
+bundle-viz(1) bundle-viz.1
diff --git a/lib/bundler/match_platform.rb b/lib/bundler/match_platform.rb
index 050cd0efd3..69074925a6 100644
--- a/lib/bundler/match_platform.rb
+++ b/lib/bundler/match_platform.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require "bundler/gem_helpers"
+
+require_relative "gem_helpers"
module Bundler
module MatchPlatform
diff --git a/lib/bundler/mirror.rb b/lib/bundler/mirror.rb
index 97a6776adb..a63b45b47d 100644
--- a/lib/bundler/mirror.rb
+++ b/lib/bundler/mirror.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "socket"
module Bundler
@@ -37,15 +38,17 @@ module Bundler
mirror = if config.all?
@all
else
- (@mirrors[config.uri] = @mirrors[config.uri] || Mirror.new)
+ @mirrors[config.uri] ||= Mirror.new
end
config.update_mirror(mirror)
end
- private
+ private
def fetch_valid_mirror_for(uri)
- mirror = (@mirrors[URI(uri.to_s.downcase)] || @mirrors[URI(uri.to_s).host] || Mirror.new(uri)).validate!(@prober)
+ downcased = uri.to_s.downcase
+ mirror = @mirrors[downcased] || @mirrors[Bundler::URI(downcased).host] || Mirror.new(uri)
+ mirror.validate!(@prober)
mirror = Mirror.new(uri) unless mirror.valid?
mirror
end
@@ -71,7 +74,7 @@ module Bundler
@uri = if uri.nil?
nil
else
- URI(uri.to_s)
+ Bundler::URI(uri.to_s)
end
@valid = nil
end
@@ -117,13 +120,13 @@ module Bundler
def initialize(config_line, value)
uri, fallback =
- config_line.match(%r{^mirror\.(all|.+?)(\.fallback_timeout)?\/?$}).captures
+ config_line.match(%r{\Amirror\.(all|.+?)(\.fallback_timeout)?\/?\z}).captures
@fallback = !fallback.nil?
@all = false
if uri == "all"
@all = true
else
- @uri = URI(uri).absolute? ? Settings.normalize_uri(uri) : uri
+ @uri = Bundler::URI(uri).absolute? ? Settings.normalize_uri(uri) : uri
end
@value = value
end
@@ -149,13 +152,13 @@ module Bundler
socket.connect_nonblock(address)
rescue Errno::EINPROGRESS
wait_for_writtable_socket(socket, address, timeout)
- rescue # Connection failed somehow, again
+ rescue RuntimeError # Connection failed somehow, again
false
end
end
end
- private
+ private
def wait_for_writtable_socket(socket, address, timeout)
if IO.select(nil, [socket], nil, timeout)
@@ -169,7 +172,7 @@ module Bundler
socket.connect_nonblock(address)
rescue Errno::EISCONN
true
- rescue # Connection failed
+ rescue StandardError # Connection failed
false
end
end
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index 66f485ef8e..158c69e1a1 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -1,20 +1,23 @@
# frozen_string_literal: true
-require "bundler/plugin/api"
+
+require_relative "plugin/api"
module Bundler
module Plugin
- autoload :DSL, "bundler/plugin/dsl"
- autoload :Index, "bundler/plugin/index"
- autoload :Installer, "bundler/plugin/installer"
- autoload :SourceList, "bundler/plugin/source_list"
+ autoload :DSL, File.expand_path("plugin/dsl", __dir__)
+ autoload :Events, File.expand_path("plugin/events", __dir__)
+ autoload :Index, File.expand_path("plugin/index", __dir__)
+ autoload :Installer, File.expand_path("plugin/installer", __dir__)
+ autoload :SourceList, File.expand_path("plugin/source_list", __dir__)
class MalformattedPlugin < PluginError; end
class UndefinedCommandError < PluginError; end
class UnknownSourceError < PluginError; end
+ class PluginInstallError < PluginError; end
PLUGIN_FILE_NAME = "plugins.rb".freeze
- module_function
+ module_function
def reset!
instance_variables.each {|i| remove_instance_variable(i) }
@@ -36,13 +39,57 @@ module Bundler
specs = Installer.new.install(names, options)
save_plugins names, specs
- rescue PluginError => e
- if specs
- specs_to_delete = Hash[specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }]
- specs_to_delete.values.each {|spec| Bundler.rm_rf(spec.full_gem_path) }
+ rescue PluginError
+ specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }
+ specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) }
+
+ raise
+ end
+
+ # Uninstalls plugins by the given names
+ #
+ # @param [Array<String>] names the names of plugins to be uninstalled
+ def uninstall(names, options)
+ if names.empty? && !options[:all]
+ Bundler.ui.error "No plugins to uninstall. Specify at least 1 plugin to uninstall.\n"\
+ "Use --all option to uninstall all the installed plugins."
+ return
+ end
+
+ names = index.installed_plugins if options[:all]
+ if names.any?
+ names.each do |name|
+ if index.installed?(name)
+ Bundler.rm_rf(index.plugin_path(name))
+ index.unregister_plugin(name)
+ Bundler.ui.info "Uninstalled plugin #{name}"
+ else
+ Bundler.ui.error "Plugin #{name} is not installed \n"
+ end
+ end
+ else
+ Bundler.ui.info "No plugins installed"
end
+ end
- Bundler.ui.error "Failed to install plugin #{name}: #{e.message}\n #{e.backtrace.join("\n ")}"
+ # List installed plugins and commands
+ #
+ def list
+ installed_plugins = index.installed_plugins
+ if installed_plugins.any?
+ output = String.new
+ installed_plugins.each do |plugin|
+ output << "#{plugin}\n"
+ output << "-----\n"
+ index.plugin_commands(plugin).each do |command|
+ output << " #{command}\n"
+ end
+ output << "\n"
+ end
+ else
+ output = "No plugins installed"
+ end
+ Bundler.ui.info output
end
# Evaluates the Gemfile with a limited DSL and installs the plugins
@@ -51,21 +98,24 @@ module Bundler
# @param [Pathname] gemfile path
# @param [Proc] block that can be evaluated for (inline) Gemfile
def gemfile_install(gemfile = nil, &inline)
- builder = DSL.new
- if block_given?
- builder.instance_eval(&inline)
- else
- builder.eval_gemfile(gemfile)
+ Bundler.settings.temporary(:frozen => false, :deployment => false) do
+ builder = DSL.new
+ if block_given?
+ builder.instance_eval(&inline)
+ else
+ builder.eval_gemfile(gemfile)
+ end
+ builder.check_primary_source_safety
+ definition = builder.to_definition(nil, true)
+
+ return if definition.dependencies.empty?
+
+ plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p }
+ installed_specs = Installer.new.install_definition(definition)
+
+ save_plugins plugins, installed_specs, builder.inferred_plugins
end
- definition = builder.to_definition(nil, true)
-
- return if definition.dependencies.empty?
-
- plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p }
- installed_specs = Installer.new.install_definition(definition)
-
- save_plugins plugins, installed_specs, builder.inferred_plugins
- rescue => e
+ rescue RuntimeError => e
unless e.is_a?(GemfileError)
Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}"
end
@@ -79,8 +129,8 @@ module Bundler
# The directory root for all plugin related data
#
- # Points to root in app_config_path if ran in an app else points to the one
- # in user_bundle_path
+ # If run in an app, points to local root, in app_config_path
+ # Otherwise, points to global root, in Bundler.user_bundle_path("plugin")
def root
@root ||= if SharedHelpers.in_bundle?
local_root
@@ -95,7 +145,7 @@ module Bundler
# The global directory root for all plugin related data
def global_root
- Bundler.user_bundle_path.join("plugin")
+ Bundler.user_bundle_path("plugin")
end
# The cache directory for plugin stuffs
@@ -114,7 +164,7 @@ module Bundler
end
# To be called from Cli class to pass the command and argument to
- # approriate plugin class
+ # appropriate plugin class
def exec_command(command, args)
raise UndefinedCommandError, "Command `#{command}` not found" unless command? command
@@ -133,7 +183,7 @@ module Bundler
!index.source_plugin(name.to_s).nil?
end
- # @return [Class] that handles the source. The calss includes API::Source
+ # @return [Class] that handles the source. The class includes API::Source
def source(name)
raise UnknownSourceError, "Source #{name} not found" unless source? name
@@ -154,6 +204,9 @@ module Bundler
# To be called via the API to register a hooks and corresponding block that
# will be called to handle the hook
def add_hook(event, &block)
+ unless Events.defined_event?(event)
+ raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events"
+ end
@hooks_by_event[event.to_s] << block
end
@@ -165,6 +218,9 @@ module Bundler
# @param [String] event
def hook(event, *args, &arg_blk)
return unless Bundler.feature_flag.plugins?
+ unless Events.defined_event?(event)
+ raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events"
+ end
plugins = index.hook_plugins(event)
return unless plugins.any?
@@ -189,10 +245,11 @@ module Bundler
# @param [Array<String>] names of inferred source plugins that can be ignored
def save_plugins(plugins, specs, optional_plugins = [])
plugins.each do |name|
+ next if index.installed?(name)
+
spec = specs[name]
- validate_plugin! Pathname.new(spec.full_gem_path)
- installed = register_plugin(name, spec, optional_plugins.include?(name))
- Bundler.ui.info "Installed plugin #{name}" if installed
+
+ save_plugin(name, spec, optional_plugins.include?(name))
end
end
@@ -207,6 +264,22 @@ module Bundler
raise MalformattedPlugin, "#{PLUGIN_FILE_NAME} was not found in the plugin." unless plugin_file.file?
end
+ # Validates and registers a plugin.
+ #
+ # @param [String] name the name of the plugin
+ # @param [Specification] spec of installed plugin
+ # @param [Boolean] optional_plugin, removed if there is conflict with any
+ # other plugin (used for default source plugins)
+ #
+ # @raise [PluginInstallError] if validation or registration raises any error
+ def save_plugin(name, spec, optional_plugin = false)
+ validate_plugin! Pathname.new(spec.full_gem_path)
+ installed = register_plugin(name, spec, optional_plugin)
+ Bundler.ui.info "Installed plugin #{name}" if installed
+ rescue PluginError => e
+ raise PluginInstallError, "Failed to install plugin `#{spec.name}`, due to #{e.class} (#{e.message})"
+ end
+
# Runs the plugins.rb file in an isolated namespace, records the plugin
# actions it registers for and then passes the data to index to be stored.
#
@@ -226,7 +299,7 @@ module Bundler
@hooks_by_event = Hash.new {|h, k| h[k] = [] }
load_paths = spec.load_paths
- add_to_load_path(load_paths)
+ Bundler.rubygems.add_to_load_path(load_paths)
path = Pathname.new spec.full_gem_path
begin
@@ -253,32 +326,25 @@ module Bundler
#
# @param [String] name of the plugin
def load_plugin(name)
+ return unless name && !name.empty?
+
# Need to ensure before this that plugin root where the rest of gems
# are installed to be on load path to support plugin deps. Currently not
# done to avoid conflicts
path = index.plugin_path(name)
- add_to_load_path(index.load_paths(name))
+ Bundler.rubygems.add_to_load_path(index.load_paths(name))
load path.join(PLUGIN_FILE_NAME)
@loaded_plugin_names << name
- rescue => e
+ rescue RuntimeError => e
Bundler.ui.error "Failed loading plugin #{name}: #{e.message}"
raise
end
- def add_to_load_path(load_paths)
- if insert_index = Bundler.rubygems.load_path_insert_index
- $LOAD_PATH.insert(insert_index, *load_paths)
- else
- $LOAD_PATH.unshift(*load_paths)
- end
- end
-
class << self
- private :load_plugin, :register_plugin, :save_plugins, :validate_plugin!,
- :add_to_load_path
+ private :load_plugin, :register_plugin, :save_plugins, :validate_plugin!
end
end
end
diff --git a/lib/bundler/plugin/api.rb b/lib/bundler/plugin/api.rb
index a2d5cbb4ac..ee2bffe3ab 100644
--- a/lib/bundler/plugin/api.rb
+++ b/lib/bundler/plugin/api.rb
@@ -23,7 +23,7 @@ module Bundler
# and hooks).
module Plugin
class API
- autoload :Source, "bundler/plugin/api/source"
+ autoload :Source, File.expand_path("api/source", __dir__)
# The plugins should declare that they handle a command through this helper.
#
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
index 5d3f58df92..32b1d0ee38 100644
--- a/lib/bundler/plugin/api/source.rb
+++ b/lib/bundler/plugin/api/source.rb
@@ -1,6 +1,4 @@
# frozen_string_literal: true
-require "uri"
-require "digest/sha1"
module Bundler
module Plugin
@@ -37,7 +35,7 @@ module Bundler
#
# @!attribute [rw] dependency_names
# @return [Array<String>] Names of dependencies that the source should
- # try to resolve. It is not necessary to use this list intenally. This
+ # try to resolve. It is not necessary to use this list internally. This
# is present to be compatible with `Definition` and is used by
# rubygems source.
module Source
@@ -108,7 +106,7 @@ module Bundler
def install_path
@install_path ||=
begin
- base_name = File.basename(URI.parse(uri).normalize.path)
+ base_name = File.basename(Bundler::URI.parse(uri).normalize.path)
gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}")
end
@@ -142,6 +140,13 @@ module Bundler
end
end
+ # Set internal representation to fetch the gems/specs locally.
+ #
+ # When this is called, the source should try to fetch the specs and
+ # install from the local system.
+ def local!
+ end
+
# Set internal representation to fetch the gems/specs from remote.
#
# When this is called, the source should try to fetch the specs and
@@ -170,7 +175,7 @@ module Bundler
#
# This is used by `app_cache_path`
def app_cache_dirname
- base_name = File.basename(URI.parse(uri).normalize.path)
+ base_name = File.basename(Bundler::URI.parse(uri).normalize.path)
"#{base_name}-#{uri_hash}"
end
@@ -196,7 +201,7 @@ module Bundler
# This shall check if two source object represent the same source.
#
# The comparison shall take place only on the attribute that can be
- # inferred from the options passed from Gemfile and not on attibutes
+ # inferred from the options passed from Gemfile and not on attributes
# that are used to pin down the gem to specific version (e.g. Git
# sources should compare on branch and tag but not on commit hash)
#
@@ -239,6 +244,20 @@ module Bundler
specs.unmet_dependency_names
end
+ # Used by definition.
+ #
+ # Note: Do not override if you don't know what you are doing.
+ def spec_names
+ specs.spec_names
+ end
+
+ # Used by definition.
+ #
+ # Note: Do not override if you don't know what you are doing.
+ def add_dependency_names(names)
+ @dependencies |= Array(names)
+ end
+
# Note: Do not override if you don't know what you are doing.
def can_lock?(spec)
spec.source == self
@@ -262,8 +281,9 @@ module Bundler
end
def to_s
- "plugin source for #{options[:type]} with uri #{uri}"
+ "plugin source for #{@type} with uri #{@uri}"
end
+ alias_method :identifier, :to_s
# Note: Do not override if you don't know what you are doing.
def include?(other)
@@ -271,7 +291,7 @@ module Bundler
end
def uri_hash
- Digest::SHA1.hexdigest(uri)
+ SharedHelpers.digest(:SHA1).hexdigest(uri)
end
# Note: Do not override if you don't know what you are doing.
@@ -293,6 +313,13 @@ module Bundler
def bundler_plugin_api_source?
true
end
+
+ # @private
+ # This API on source might not be stable, and for now we expect plugins
+ # to download all specs in `#specs`, so we implement the method for
+ # compatibility purposes and leave it undocumented (and don't support)
+ # overriding it)
+ def double_check_for(*); end
end
end
end
diff --git a/lib/bundler/plugin/dsl.rb b/lib/bundler/plugin/dsl.rb
index 4bfc8437e0..da751d1774 100644
--- a/lib/bundler/plugin/dsl.rb
+++ b/lib/bundler/plugin/dsl.rb
@@ -10,7 +10,7 @@ module Bundler
# So that we don't have to override all there methods to dummy ones
# explicitly.
# They will be handled by method_missing
- [:gemspec, :gem, :path, :install_if, :platforms, :env].each {|m| undef_method m }
+ [:gemspec, :gem, :install_if, :platforms, :env].each {|m| undef_method m }
# This lists the plugins that was added automatically and not specified by
# the user.
diff --git a/lib/bundler/plugin/events.rb b/lib/bundler/plugin/events.rb
new file mode 100644
index 0000000000..bc037d1af5
--- /dev/null
+++ b/lib/bundler/plugin/events.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Bundler
+ module Plugin
+ module Events
+ def self.define(const, event)
+ const = const.to_sym.freeze
+ if const_defined?(const) && const_get(const) != event
+ raise ArgumentError, "Attempting to reassign #{const} to a different value"
+ end
+ const_set(const, event) unless const_defined?(const)
+ @events ||= {}
+ @events[event] = const
+ end
+ private_class_method :define
+
+ def self.reset
+ @events.each_value do |const|
+ remove_const(const)
+ end
+ @events = nil
+ end
+ private_class_method :reset
+
+ # Check if an event has been defined
+ # @param event [String] An event to check
+ # @return [Boolean] A boolean indicating if the event has been defined
+ def self.defined_event?(event)
+ @events ||= {}
+ @events.key?(event)
+ end
+
+ # @!parse
+ # A hook called before each individual gem is installed
+ # Includes a Bundler::ParallelInstaller::SpecInstallation.
+ # No state, error, post_install_message will be present as nothing has installed yet
+ # GEM_BEFORE_INSTALL = "before-install"
+ define :GEM_BEFORE_INSTALL, "before-install"
+
+ # @!parse
+ # A hook called after each individual gem is installed
+ # Includes a Bundler::ParallelInstaller::SpecInstallation.
+ # - If state is failed, an error will be present.
+ # - If state is success, a post_install_message may be present.
+ # GEM_AFTER_INSTALL = "after-install"
+ define :GEM_AFTER_INSTALL, "after-install"
+
+ # @!parse
+ # A hook called before any gems install
+ # Includes an Array of Bundler::Dependency objects
+ # GEM_BEFORE_INSTALL_ALL = "before-install-all"
+ define :GEM_BEFORE_INSTALL_ALL, "before-install-all"
+
+ # @!parse
+ # A hook called after any gems install
+ # Includes an Array of Bundler::Dependency objects
+ # GEM_AFTER_INSTALL_ALL = "after-install-all"
+ define :GEM_AFTER_INSTALL_ALL, "after-install-all"
+ end
+ end
+end
diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb
index 8dde072f16..29d33be718 100644
--- a/lib/bundler/plugin/index.rb
+++ b/lib/bundler/plugin/index.rb
@@ -29,7 +29,12 @@ module Bundler
@hooks = {}
@load_paths = {}
- load_index(global_index_file, true)
+ begin
+ load_index(global_index_file, true)
+ rescue GenericSystemCallError
+ # no need to fail when on a read-only FS, for example
+ nil
+ end
load_index(local_index_file) if SharedHelpers.in_bundle?
end
@@ -53,16 +58,31 @@ module Bundler
raise SourceConflict.new(name, common) unless common.empty?
sources.each {|k| @sources[k] = name }
- hooks.each {|e| (@hooks[e] ||= []) << name }
+ hooks.each do |event|
+ event_hooks = (@hooks[event] ||= []) << name
+ event_hooks.uniq!
+ end
@plugin_paths[name] = path
@load_paths[name] = load_paths
save_index
- rescue
+ rescue StandardError
@commands = old_commands
raise
end
+ def unregister_plugin(name)
+ @commands.delete_if {|_, v| v == name }
+ @sources.delete_if {|_, v| v == name }
+ @hooks.each do |hook, names|
+ names.delete(name)
+ @hooks.delete(hook) if names.empty?
+ end
+ @plugin_paths.delete(name)
+ @load_paths.delete(name)
+ save_index
+ end
+
# Path of default index file
def index_file
Plugin.root.join("index")
@@ -95,6 +115,14 @@ module Bundler
@plugin_paths[name]
end
+ def installed_plugins
+ @plugin_paths.keys
+ end
+
+ def plugin_commands(plugin)
+ @commands.find_all {|_, n| n == plugin }.map(&:first)
+ end
+
def source?(source)
@sources.key? source
end
@@ -108,7 +136,7 @@ module Bundler
@hooks[event] || []
end
- private
+ private
# Reads the index file from the directory and initializes the instance
# variables.
@@ -123,7 +151,7 @@ module Bundler
data = index_f.read
- require "bundler/yaml_serializer"
+ require_relative "../yaml_serializer"
index = YAMLSerializer.load(data)
@commands.merge!(index["commands"])
@@ -146,7 +174,7 @@ module Bundler
"sources" => @sources,
}
- require "bundler/yaml_serializer"
+ require_relative "../yaml_serializer"
SharedHelpers.filesystem_access(index_file) do |index_f|
FileUtils.mkdir_p(index_f.dirname)
File.open(index_f, "w") {|f| f.puts YAMLSerializer.dump(index) }
diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb
index a50d0ceedd..d7411fff45 100644
--- a/lib/bundler/plugin/installer.rb
+++ b/lib/bundler/plugin/installer.rb
@@ -8,14 +8,18 @@ module Bundler
# are heavily dependent on the Gemfile.
module Plugin
class Installer
- autoload :Rubygems, "bundler/plugin/installer/rubygems"
- autoload :Git, "bundler/plugin/installer/git"
+ autoload :Rubygems, File.expand_path("installer/rubygems", __dir__)
+ autoload :Git, File.expand_path("installer/git", __dir__)
def install(names, options)
+ check_sources_consistency!(options)
+
version = options[:version] || [">= 0"]
if options[:git]
install_git(names, version, options)
+ elsif options[:local_git]
+ install_local_git(names, version, options)
else
sources = options[:source] || Bundler.rubygems.sources
install_rubygems(names, version, sources)
@@ -35,24 +39,26 @@ module Bundler
install_from_specs specs
end
- private
+ private
+
+ def check_sources_consistency!(options)
+ if options.key?(:git) && options.key?(:local_git)
+ raise InvalidOption, "Remote and local plugin git sources can't be both specified"
+ end
+ end
def install_git(names, version, options)
uri = options.delete(:git)
options["uri"] = uri
- source_list = SourceList.new
- source_list.add_git_source(options)
-
- # To support both sources
- if options[:source]
- source_list.add_rubygems_source("remotes" => options[:source])
- end
+ install_all_sources(names, version, options, options[:source])
+ end
- deps = names.map {|name| Dependency.new name, version }
+ def install_local_git(names, version, options)
+ uri = options.delete(:local_git)
+ options["uri"] = uri
- definition = Definition.new(nil, deps, source_list, true)
- install_definition(definition)
+ install_all_sources(names, version, options, options[:source])
end
# Installs the plugin from rubygems source and returns the path where the
@@ -64,10 +70,18 @@ module Bundler
#
# @return [Hash] map of names to the specs of plugins installed
def install_rubygems(names, version, sources)
- deps = names.map {|name| Dependency.new name, version }
+ install_all_sources(names, version, nil, sources)
+ end
+ def install_all_sources(names, version, git_source_options, rubygems_source)
source_list = SourceList.new
- source_list.add_rubygems_source("remotes" => sources)
+
+ source_list.add_git_source(git_source_options) if git_source_options
+ Array(rubygems_source).each {|remote| source_list.add_global_rubygems_remote(remote) } if rubygems_source
+
+ deps = names.map {|name| Dependency.new name, version }
+
+ Bundler.configure_gem_home_and_path(Plugin.root)
definition = Definition.new(nil, deps, source_list, true)
install_definition(definition)
diff --git a/lib/bundler/plugin/installer/rubygems.rb b/lib/bundler/plugin/installer/rubygems.rb
index 7ae74fa93b..e144c14b24 100644
--- a/lib/bundler/plugin/installer/rubygems.rb
+++ b/lib/bundler/plugin/installer/rubygems.rb
@@ -8,7 +8,7 @@ module Bundler
"#{spec.name} #{spec.version}"
end
- private
+ private
def requires_sudo?
false # Will change on implementation of project level plugins
diff --git a/lib/bundler/plugin/source_list.rb b/lib/bundler/plugin/source_list.rb
index 33f5e5afbd..547661cf2f 100644
--- a/lib/bundler/plugin/source_list.rb
+++ b/lib/bundler/plugin/source_list.rb
@@ -5,13 +5,6 @@ module Bundler
# approptiate options to be used with Source classes for plugin installation
module Plugin
class SourceList < Bundler::SourceList
- def initialize
- @path_sources = []
- @git_sources = []
- @rubygems_aggregate = Plugin::Installer::Rubygems.new
- @rubygems_sources = []
- end
-
def add_git_source(options = {})
add_source_to_list Plugin::Installer::Git.new(options), git_sources
end
@@ -21,7 +14,17 @@ module Bundler
end
def all_sources
- path_sources + git_sources + rubygems_sources
+ path_sources + git_sources + rubygems_sources + [metadata_source]
+ end
+
+ def default_source
+ git_sources.first || global_rubygems_source
+ end
+
+ private
+
+ def rubygems_aggregate_class
+ Plugin::Installer::Rubygems
end
end
end
diff --git a/lib/bundler/process_lock.rb b/lib/bundler/process_lock.rb
new file mode 100644
index 0000000000..cba4fcdba5
--- /dev/null
+++ b/lib/bundler/process_lock.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Bundler
+ class ProcessLock
+ def self.lock(bundle_path = Bundler.bundle_path)
+ lock_file_path = File.join(bundle_path, "bundler.lock")
+ has_lock = false
+
+ File.open(lock_file_path, "w") do |f|
+ f.flock(File::LOCK_EX)
+ has_lock = true
+ yield
+ f.flock(File::LOCK_UN)
+ end
+ rescue Errno::EACCES, Errno::ENOLCK, *[SharedHelpers.const_get_safely(:ENOTSUP, Errno)].compact
+ # In the case the user does not have access to
+ # create the lock file or is using NFS where
+ # locks are not available we skip locking.
+ yield
+ ensure
+ FileUtils.rm_f(lock_file_path) if has_lock
+ end
+ end
+end
diff --git a/lib/bundler/psyched_yaml.rb b/lib/bundler/psyched_yaml.rb
index 69d2ae78c5..463d52dc4a 100644
--- a/lib/bundler/psyched_yaml.rb
+++ b/lib/bundler/psyched_yaml.rb
@@ -1,9 +1,4 @@
# frozen_string_literal: true
-# Psych could be a gem, so try to ask for it
-begin
- gem "psych"
-rescue LoadError
-end if defined?(gem)
# Psych could be in the stdlib
# but it's too late if Syck is already loaded
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
index 208ee1d4b7..89b69e1045 100644
--- a/lib/bundler/remote_specification.rb
+++ b/lib/bundler/remote_specification.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "uri"
module Bundler
# Represents a lazily loaded gem specification, where the full specification
@@ -51,6 +50,8 @@ module Bundler
# once the remote gem is downloaded, the backend specification will
# be swapped out.
def __swap__(spec)
+ raise APIResponseInvalidDependenciesError unless spec.dependencies.all? {|d| d.is_a?(Gem::Dependency) }
+
SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
@_remote_specification = spec
end
@@ -77,7 +78,8 @@ module Bundler
deps = method_missing(:dependencies)
# allow us to handle when the specs dependencies are an array of array of string
- # see https://github.com/bundler/bundler/issues/5797
+ # in order to delay the crash to `#__swap__` where it results in a friendlier error
+ # see https://github.com/rubygems/bundler/issues/5797
deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) }
deps
@@ -89,7 +91,7 @@ module Bundler
" #{source.revision[0..6]}"
end
- private
+ private
def to_ary
nil
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index db2ae496a4..5eb17a3921 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -1,178 +1,11 @@
# frozen_string_literal: true
+
module Bundler
class Resolver
- require "bundler/vendored_molinillo"
-
- class Molinillo::VersionConflict
- def printable_dep(dep)
- if dep.is_a?(Bundler::Dependency)
- DepProxy.new(dep, dep.platforms.join(", ")).to_s.strip
- else
- dep.to_s
- end
- end
-
- def message
- conflicts.sort.reduce(String.new) do |o, (name, conflict)|
- o << %(\nBundler could not find compatible versions for gem "#{name}":\n)
- if conflict.locked_requirement
- o << %( In snapshot (#{Bundler.default_lockfile.basename}):\n)
- o << %( #{printable_dep(conflict.locked_requirement)}\n)
- o << %(\n)
- end
- o << %( In Gemfile:\n)
- trees = conflict.requirement_trees
-
- maximal = 1.upto(trees.size).map do |size|
- trees.map(&:last).flatten(1).combination(size).to_a
- end.flatten(1).select do |deps|
- Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
- end.min_by(&:size)
- trees.reject! {|t| !maximal.include?(t.last) } if maximal
-
- o << trees.sort_by {|t| t.reverse.map(&:name) }.map do |tree|
- t = String.new
- depth = 2
- tree.each do |req|
- t << " " * depth << req.to_s
- unless tree.last == req
- if spec = conflict.activated_by_name[req.name]
- t << %( was resolved to #{spec.version}, which)
- end
- t << %( depends on)
- end
- t << %(\n)
- depth += 1
- end
- t
- end.join("\n")
+ require_relative "vendored_molinillo"
+ require_relative "resolver/spec_group"
- if name == "bundler"
- o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
- other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
- end
-
- if name == "bundler" && other_bundler_required
- o << "\n"
- o << "This Gemfile requires a different version of Bundler.\n"
- o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
- end
- if conflict.locked_requirement
- o << "\n"
- o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
- o << %(the gems in your Gemfile, which may resolve the conflict.\n)
- elsif !conflict.existing
- o << "\n"
- if conflict.requirement_trees.first.size > 1
- o << "Could not find gem '#{conflict.requirement}', which is required by "
- o << "gem '#{conflict.requirement_trees.first[-2]}', in any of the sources."
- else
- o << "Could not find gem '#{conflict.requirement}' in any of the sources\n"
- end
- end
- o
- end.strip
- end
- end
-
- class SpecGroup < Array
- include GemHelpers
-
- attr_reader :activated
-
- def initialize(a)
- super
- @required_by = []
- @activated_platforms = []
- @dependencies = nil
- @specs = Hash.new do |specs, platform|
- specs[platform] = select_best_platform_match(self, platform)
- end
- end
-
- def initialize_copy(o)
- super
- @activated_platforms = o.activated.dup
- end
-
- def to_specs
- @activated_platforms.map do |p|
- next unless s = @specs[p]
- lazy_spec = LazySpecification.new(name, version, s.platform, source)
- lazy_spec.dependencies.replace s.dependencies
- lazy_spec
- end.compact
- end
-
- def activate_platform!(platform)
- return unless for?(platform)
- return if @activated_platforms.include?(platform)
- @activated_platforms << platform
- end
-
- def name
- @name ||= first.name
- end
-
- def version
- @version ||= first.version
- end
-
- def source
- @source ||= first.source
- end
-
- def for?(platform)
- spec = @specs[platform]
- !spec.nil?
- end
-
- def to_s
- "#{name} (#{version})"
- end
-
- def dependencies_for_activated_platforms
- dependencies = @activated_platforms.map {|p| __dependencies[p] }
- metadata_dependencies = @activated_platforms.map do |platform|
- metadata_dependencies(@specs[platform], platform)
- end
- dependencies.concat(metadata_dependencies).flatten
- end
-
- def platforms_for_dependency_named(dependency)
- __dependencies.select {|_, deps| deps.map(&:name).include? dependency }.keys
- end
-
- private
-
- def __dependencies
- @dependencies = Hash.new do |dependencies, platform|
- dependencies[platform] = []
- if spec = @specs[platform]
- spec.dependencies.each do |dep|
- next if dep.type == :development
- dependencies[platform] << DepProxy.new(dep, platform)
- end
- end
- dependencies[platform]
- end
- end
-
- def metadata_dependencies(spec, platform)
- return [] unless spec
- # Only allow endpoint specifications since they won't hit the network to
- # fetch the full gemspec when calling required_ruby_version
- return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
- dependencies = []
- if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
- dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
- end
- if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
- dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
- end
- dependencies
- end
- end
+ include GemHelpers
# Figures out the best possible configuration of gems that satisfies
# the list of passed dependencies and any child dependencies without
@@ -184,16 +17,14 @@ module Bundler
# ==== Returns
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
# collection of gemspecs is returned. Otherwise, nil is returned.
- def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
- platforms = Set.new(platforms) if platforms
+ def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
base = SpecSet.new(base) unless base.is_a?(SpecSet)
- resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
+ resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
result = resolver.start(requirements)
- SpecSet.new(result)
+ SpecSet.new(SpecSet.new(result).for(requirements.reject{|dep| dep.name.end_with?("\0") }))
end
- def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
- @index = index
+ def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
@source_requirements = source_requirements
@base = base
@resolver = Molinillo::Resolver.new(self, self)
@@ -201,21 +32,29 @@ module Bundler
@base_dg = Molinillo::DependencyGraph.new
@base.each do |ls|
dep = Dependency.new(ls.name, ls.version)
- @base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
+ @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
end
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
- @platforms = platforms
+ @platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
+ @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
@gem_version_promoter = gem_version_promoter
+ @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
end
def start(requirements)
+ @gem_version_promoter.prerelease_specified = @prerelease_specified = {}
+ requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
+
verify_gemfile_dependencies_are_found!(requirements)
dg = @resolver.resolve(requirements, @base_dg)
- dg.map(&:payload).
+ dg.
+ map(&:payload).
reject {|sg| sg.name.end_with?("\0") }.
- map(&:to_specs).flatten
+ map(&:to_specs).
+ flatten
rescue Molinillo::VersionConflict => e
- raise VersionConflict.new(e.conflicts.keys.uniq, e.message)
+ message = version_conflict_message(e)
+ raise VersionConflict.new(e.conflicts.keys.uniq, message)
rescue Molinillo::CircularDependencyError => e
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
raise CyclicDependencyError, "Your bundle requires gems that depend" \
@@ -234,12 +73,17 @@ module Bundler
return unless debug?
debug_info = yield
debug_info = debug_info.inspect unless debug_info.is_a?(String)
- STDERR.puts debug_info.split("\n").map {|s| " " * depth + s }
+ puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" }
end
def debug?
return @debug_mode if defined?(@debug_mode)
- @debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
+ @debug_mode =
+ ENV["BUNDLER_DEBUG_RESOLVER"] ||
+ ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
+ ENV["DEBUG_RESOLVER"] ||
+ ENV["DEBUG_RESOLVER_TREE"] ||
+ false
end
def before_resolution
@@ -260,15 +104,24 @@ module Bundler
specification.dependencies_for_activated_platforms
end
- def search_for(dependency)
- platform = dependency.__platform
- dependency = dependency.dep unless dependency.is_a? Gem::Dependency
- search = @search_for[dependency] ||= begin
- index = index_for(dependency)
- results = index.search(dependency, @base[dependency.name])
- if vertex = @base_dg.vertex_named(dependency.name)
+ def search_for(dependency_proxy)
+ platform = dependency_proxy.__platform
+ dependency = dependency_proxy.dep
+ name = dependency.name
+ @search_for[dependency_proxy] ||= begin
+ results = results_for(dependency, @base[name])
+
+ if vertex = @base_dg.vertex_named(name)
locked_requirement = vertex.payload.requirement
end
+
+ if !@prerelease_specified[name] && (!@use_gvp || locked_requirement.nil?)
+ # Move prereleases to the beginning of the list, so they're considered
+ # last during resolution.
+ pre, results = results.partition {|spec| spec.version.prerelease? }
+ results = pre + results
+ end
+
spec_groups = if results.any?
nested = []
results.each do |spec|
@@ -281,24 +134,44 @@ module Bundler
end
nested.reduce([]) do |groups, (version, specs)|
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
- groups << SpecGroup.new(specs)
+
+ specs_by_platform = Hash.new do |current_specs, current_platform|
+ current_specs[current_platform] = select_best_platform_match(specs, current_platform)
+ end
+
+ spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY)
+ groups << spec_group_ruby if spec_group_ruby
+
+ next groups if @resolving_only_for_ruby
+
+ spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
+ groups << spec_group if spec_group
+
+ groups
end
else
[]
end
# GVP handles major itself, but it's still a bit risky to trust it with it
# until we get it settled with new behavior. For 2.x it can take over all cases.
- if @gem_version_promoter.major?
+ if !@use_gvp
spec_groups
else
@gem_version_promoter.sort_versions(dependency, spec_groups)
end
end
- search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
end
def index_for(dependency)
- @source_requirements[dependency.name] || @index
+ source_for(dependency.name).specs
+ end
+
+ def source_for(name)
+ @source_requirements[name] || @source_requirements[:default]
+ end
+
+ def results_for(dependency, base)
+ index_for(dependency).search(dependency, base)
end
def name_for(dependency)
@@ -307,36 +180,47 @@ module Bundler
def name_for_explicit_dependency_source
Bundler.default_gemfile.basename.to_s
- rescue
+ rescue StandardError
"Gemfile"
end
def name_for_locking_dependency_source
Bundler.default_lockfile.basename.to_s
- rescue
+ rescue StandardError
"Gemfile.lock"
end
def requirement_satisfied_by?(requirement, activated, spec)
- return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
- spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
- true
+ requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
+ end
+
+ def dependencies_equal?(dependencies, other_dependencies)
+ dependencies.map(&:dep) == other_dependencies.map(&:dep)
end
def sort_dependencies(dependencies, activated, conflicts)
dependencies.sort_by do |dependency|
name = name_for(dependency)
+ vertex = activated.vertex_named(name)
[
@base_dg.vertex_named(name) ? 0 : 1,
- activated.vertex_named(name).payload ? 0 : 1,
+ vertex.payload ? 0 : 1,
+ vertex.root? ? 0 : 1,
amount_constrained(dependency),
conflicts[name] ? 0 : 1,
- activated.vertex_named(name).payload ? 0 : search_for(dependency).count,
+ vertex.payload ? 0 : search_for(dependency).count,
+ self.class.platform_sort_key(dependency.__platform),
]
end
end
- private
+ def self.platform_sort_key(platform)
+ # Prefer specific platform to not specific platform
+ return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
+ ["00", *platform.to_a.map {|part| part || "" }]
+ end
+
+ private
# returns an integer \in (-\infty, 0]
# a number closer to 0 means the dependency is less constraining
@@ -355,7 +239,8 @@ module Bundler
if all <= 1
all - 1_000_000
else
- search = search_for(dependency).size
+ search = search_for(dependency)
+ search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
search - all
end
end
@@ -364,34 +249,29 @@ module Bundler
def verify_gemfile_dependencies_are_found!(requirements)
requirements.each do |requirement|
- next if requirement.name == "bundler"
+ name = requirement.name
+ next if name == "bundler"
next unless search_for(requirement).empty?
- if (base = @base[requirement.name]) && !base.empty?
+
+ if (base = @base[name]) && !base.empty?
version = base.first.version
message = "You have requested:\n" \
- " #{requirement.name} #{requirement.requirement}\n\n" \
- "The bundle currently has #{requirement.name} locked at #{version}.\n" \
- "Try running `bundle update #{requirement.name}`\n\n" \
+ " #{name} #{requirement.requirement}\n\n" \
+ "The bundle currently has #{name} locked at #{version}.\n" \
+ "Try running `bundle update #{name}`\n\n" \
"If you are updating multiple gems in your Gemfile at once,\n" \
"try passing them all to `bundle update`"
- elsif requirement.source
- name = requirement.name
- specs = @source_requirements[name][name]
- versions_with_platforms = specs.map {|s| [s.version, s.platform] }
- message = String.new("Could not find gem '#{requirement}' in #{requirement.source}.\n")
- message << if versions_with_platforms.any?
- "Source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
- else
- "Source does not contain any versions of '#{requirement}'"
- end
else
+ source = source_for(name)
+ specs = source.specs.search(name)
+ versions_with_platforms = specs.map {|s| [s.version, s.platform] }
cache_message = begin
- " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
- rescue GemfileNotFound
- nil
- end
- message = "Could not find gem '#{requirement}' in any of the gem sources " \
- "listed in your Gemfile#{cache_message}."
+ " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
+ rescue GemfileNotFound
+ nil
+ end
+ message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
+ message << "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}" if versions_with_platforms.any?
end
raise GemNotFound, message
end
@@ -402,9 +282,106 @@ module Bundler
version = vwp.first
platform = vwp.last
version_platform_str = String.new(version.to_s)
- version_platform_str << " #{platform}" unless platform.nil?
+ version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
+ version_platform_str
end
version_platform_strs.join(", ")
end
+
+ def version_conflict_message(e)
+ # only show essential conflicts, if possible
+ conflicts = e.conflicts.dup
+
+ if conflicts["bundler"]
+ conflicts.replace("bundler" => conflicts["bundler"])
+ else
+ conflicts.delete_if do |_name, conflict|
+ deps = conflict.requirement_trees.map(&:last).flatten(1)
+ !Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
+ end
+ end
+
+ e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
+
+ solver_name = "Bundler"
+ possibility_type = "gem"
+ e.message_with_trees(
+ :solver_name => solver_name,
+ :possibility_type => possibility_type,
+ :reduce_trees => lambda do |trees|
+ # called first, because we want to reduce the amount of work required to find maximal empty sets
+ trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
+
+ # bail out if tree size is too big for Array#combination to make any sense
+ return trees if trees.size > 15
+ maximal = 1.upto(trees.size).map do |size|
+ trees.map(&:last).flatten(1).combination(size).to_a
+ end.flatten(1).select do |deps|
+ Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
+ end.min_by(&:size)
+
+ trees.reject! {|t| !maximal.include?(t.last) } if maximal
+
+ trees.sort_by {|t| t.reverse.map(&:name) }
+ end,
+ :printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
+ :additional_message_for_conflict => lambda do |o, name, conflict|
+ if name == "bundler"
+ o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
+
+ conflict_dependency = conflict.requirement
+ conflict_requirement = conflict_dependency.requirement
+ other_bundler_required = !conflict_requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
+
+ if other_bundler_required
+ o << "\n\n"
+
+ candidate_specs = source_for(:default_bundler).specs.search(conflict_dependency)
+ if candidate_specs.any?
+ target_version = candidate_specs.last.version
+ new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
+ o << "Your bundle requires a different version of Bundler than the one you're running.\n"
+ o << "Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n"
+ else
+ o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
+ end
+ end
+ elsif conflict.locked_requirement
+ o << "\n"
+ o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
+ o << %(the gems in your Gemfile, which may resolve the conflict.\n)
+ elsif !conflict.existing
+ o << "\n"
+
+ relevant_source = conflict.requirement.source || source_for(name)
+
+ metadata_requirement = name.end_with?("\0")
+
+ o << "Could not find gem '" unless metadata_requirement
+ o << SharedHelpers.pretty_dependency(conflict.requirement)
+ o << "'" unless metadata_requirement
+ if conflict.requirement_trees.first.size > 1
+ o << ", which is required by "
+ o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
+ end
+ o << " "
+
+ o << if metadata_requirement
+ "is not available in #{relevant_source}"
+ else
+ "in #{relevant_source}.\n"
+ end
+ end
+ end,
+ :version_for_spec => lambda {|spec| spec.version },
+ :incompatible_version_message_for_conflict => lambda do |name, _conflict|
+ if name.end_with?("\0")
+ %(#{solver_name} found conflicting requirements for the #{name} version:)
+ else
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
+ end
+ end
+ )
+ end
end
end
diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb
new file mode 100644
index 0000000000..8f4fd18c46
--- /dev/null
+++ b/lib/bundler/resolver/spec_group.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+module Bundler
+ class Resolver
+ class SpecGroup
+ attr_accessor :name, :version, :source
+ attr_accessor :activated_platforms
+
+ def self.create_for(specs, all_platforms, specific_platform)
+ specific_platform_specs = specs[specific_platform]
+ return unless specific_platform_specs.any?
+
+ platforms = all_platforms.select {|p| specs[p].any? }
+
+ new(specific_platform_specs.first, specs, platforms)
+ end
+
+ def initialize(exemplary_spec, specs, relevant_platforms)
+ @exemplary_spec = exemplary_spec
+ @name = exemplary_spec.name
+ @version = exemplary_spec.version
+ @source = exemplary_spec.source
+
+ @activated_platforms = relevant_platforms
+ @dependencies = Hash.new do |dependencies, platforms|
+ dependencies[platforms] = dependencies_for(platforms)
+ end
+ @specs = specs
+ end
+
+ def to_specs
+ activated_platforms.map do |p|
+ specs = @specs[p]
+ next unless specs.any?
+
+ specs.map do |s|
+ lazy_spec = LazySpecification.new(name, version, s.platform, source)
+ lazy_spec.dependencies.replace s.dependencies
+ lazy_spec
+ end
+ end.flatten.compact.uniq
+ end
+
+ def to_s
+ activated_platforms_string = sorted_activated_platforms.join(", ")
+ "#{name} (#{version}) (#{activated_platforms_string})"
+ end
+
+ def dependencies_for_activated_platforms
+ @dependencies[activated_platforms]
+ end
+
+ def ==(other)
+ return unless other.is_a?(SpecGroup)
+ name == other.name &&
+ version == other.version &&
+ sorted_activated_platforms == other.sorted_activated_platforms &&
+ source == other.source
+ end
+
+ def eql?(other)
+ return unless other.is_a?(SpecGroup)
+ name.eql?(other.name) &&
+ version.eql?(other.version) &&
+ sorted_activated_platforms.eql?(other.sorted_activated_platforms) &&
+ source.eql?(other.source)
+ end
+
+ def hash
+ name.hash ^ version.hash ^ sorted_activated_platforms.hash ^ source.hash
+ end
+
+ protected
+
+ def sorted_activated_platforms
+ activated_platforms.sort_by(&:to_s)
+ end
+
+ private
+
+ def dependencies_for(platforms)
+ platforms.map do |platform|
+ __dependencies(platform) + metadata_dependencies(platform)
+ end.flatten
+ end
+
+ def __dependencies(platform)
+ dependencies = []
+ @specs[platform].first.dependencies.each do |dep|
+ next if dep.type == :development
+ dependencies << DepProxy.get_proxy(dep, platform)
+ end
+ dependencies
+ end
+
+ def metadata_dependencies(platform)
+ spec = @specs[platform].first
+ return [] unless spec.is_a?(Gem::Specification)
+ dependencies = []
+ if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
+ dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
+ end
+ if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
+ dependencies << DepProxy.get_proxy(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
+ end
+ dependencies
+ end
+ end
+ end
+end
diff --git a/lib/bundler/retry.rb b/lib/bundler/retry.rb
index 092fb866b3..2415ade200 100644
--- a/lib/bundler/retry.rb
+++ b/lib/bundler/retry.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
# General purpose class for retrying code that may fail
class Retry
@@ -31,13 +32,13 @@ module Bundler
end
alias_method :attempts, :attempt
- private
+ private
def run(&block)
- @failed = false
+ @failed = false
@current_run += 1
@result = block.call
- rescue => e
+ rescue StandardError => e
fail_attempt(e)
end
@@ -48,7 +49,7 @@ module Bundler
raise e
end
return true unless name
- Bundler.ui.info "" unless Bundler.ui.debug? # Add new line incase dots preceded this
+ Bundler.ui.info "" unless Bundler.ui.debug? # Add new line in case dots preceded this
Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug?
end
diff --git a/lib/bundler/ruby_dsl.rb b/lib/bundler/ruby_dsl.rb
index a410b7f3d7..f6ba220cd5 100644
--- a/lib/bundler/ruby_dsl.rb
+++ b/lib/bundler/ruby_dsl.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
module RubyDsl
def ruby(*ruby_version)
diff --git a/lib/bundler/ruby_version.rb b/lib/bundler/ruby_version.rb
index f0a001d296..491f8c55a4 100644
--- a/lib/bundler/ruby_version.rb
+++ b/lib/bundler/ruby_version.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class RubyVersion
attr_reader :versions,
@@ -48,7 +49,7 @@ module Bundler
([\d.]+) # ruby version
(?:p(-?\d+))? # optional patchlevel
(?:\s\((\S+)\s(.+)\))? # optional engine info
- /xo
+ /xo.freeze
# Returns a RubyVersion from the given string.
# @param [String] the version string to match.
@@ -73,7 +74,7 @@ module Bundler
@host ||= [
RbConfig::CONFIG["host_cpu"],
RbConfig::CONFIG["host_vendor"],
- RbConfig::CONFIG["host_os"]
+ RbConfig::CONFIG["host_os"],
].join("-")
end
@@ -101,24 +102,9 @@ module Bundler
end
def self.system
- ruby_engine = if defined?(RUBY_ENGINE) && !RUBY_ENGINE.nil?
- RUBY_ENGINE.dup
- else
- # not defined in ruby 1.8.7
- "ruby"
- end
- # :sob: mocking RUBY_VERSION breaks stuff on 1.8.7
+ ruby_engine = RUBY_ENGINE.dup
ruby_version = ENV.fetch("BUNDLER_SPEC_RUBY_VERSION") { RUBY_VERSION }.dup
- ruby_engine_version = case ruby_engine
- when "ruby"
- ruby_version
- when "rbx"
- Rubinius::VERSION.dup
- when "jruby"
- JRUBY_VERSION.dup
- else
- raise BundlerError, "RUBY_ENGINE value #{RUBY_ENGINE} is not recognized"
- end
+ ruby_engine_version = RUBY_ENGINE_VERSION.dup
patchlevel = RUBY_PATCHLEVEL.to_s
@ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version)
@@ -137,7 +123,7 @@ module Bundler
@exact = versions.all? {|v| Gem::Requirement.create(v).exact? }
end
- private
+ private
def matches?(requirements, version)
# Handles RUBY_PATCHLEVEL of -1 for instances like ruby-head
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index a0f8fa848b..a3efff1e86 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -1,53 +1,35 @@
# frozen_string_literal: true
-require "pathname"
-if defined?(Gem::QuickLoader)
- # Gem Prelude makes me a sad panda :'(
- Gem::QuickLoader.load_full_rubygems_library
-end
+require "pathname"
-require "rubygems"
require "rubygems/specification"
-begin
- # Possible use in Gem::Specification#source below and require
- # shouldn't be deferred.
- require "rubygems/source"
-rescue LoadError
- # Not available before Rubygems 2.0.0, ignore
- nil
-end
+# Possible use in Gem::Specification#source below and require
+# shouldn't be deferred.
+require "rubygems/source"
-require "bundler/match_platform"
+require_relative "match_platform"
module Gem
- @loaded_stacks = Hash.new {|h, k| h[k] = [] }
-
class Specification
attr_accessor :remote, :location, :relative_loaded_from
- if instance_methods(false).map(&:to_sym).include?(:source)
- remove_method :source
- attr_writer :source
- def source
- (defined?(@source) && @source) || Gem::Source::Installed.new
- end
- else
- attr_accessor :source
+ remove_method :source
+ attr_writer :source
+ def source
+ (defined?(@source) && @source) || Gem::Source::Installed.new
end
alias_method :rg_full_gem_path, :full_gem_path
alias_method :rg_loaded_from, :loaded_from
- attr_writer :full_gem_path unless instance_methods.include?(:full_gem_path=)
-
def full_gem_path
# this cannot check source.is_a?(Bundler::Plugin::API::Source)
# because that _could_ trip the autoload, and if there are unresolved
# gems at that time, this method could be called inside another require,
# thus raising with that constant being undefined. Better to check a method
if source.respond_to?(:path) || (source.respond_to?(:bundler_plugin_api_source?) && source.bundler_plugin_api_source?)
- Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.untaint
+ Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.tap{|x| x.untaint if RUBY_VERSION < "2.7" }
else
rg_full_gem_path
end
@@ -62,32 +44,20 @@ module Gem
end
def load_paths
- return full_require_paths if respond_to?(:full_require_paths)
-
- require_paths.map do |require_path|
- if require_path.include?(full_gem_path)
- require_path
- else
- File.join(full_gem_path, require_path)
- end
- end
+ full_require_paths
end
- if method_defined?(:extension_dir)
- alias_method :rg_extension_dir, :extension_dir
- def extension_dir
- @bundler_extension_dir ||= if source.respond_to?(:extension_dir_name)
- File.expand_path(File.join(extensions_dir, source.extension_dir_name))
- else
- rg_extension_dir
- end
+ alias_method :rg_extension_dir, :extension_dir
+ def extension_dir
+ @bundler_extension_dir ||= if source.respond_to?(:extension_dir_name)
+ unique_extension_dir = [source.extension_dir_name, File.basename(full_gem_path)].uniq.join("-")
+ File.expand_path(File.join(extensions_dir, unique_extension_dir))
+ else
+ rg_extension_dir
end
end
- # RubyGems 1.8+ used only.
- methods = instance_methods(false)
- gem_dir = methods.first.is_a?(String) ? "gem_dir" : :gem_dir
- remove_method :gem_dir if methods.include?(gem_dir)
+ remove_method :gem_dir if instance_methods(false).include?(:gem_dir)
def gem_dir
full_gem_path
end
@@ -115,7 +85,11 @@ module Gem
dependencies - development_dependencies
end
- private
+ def deleted_gem?
+ !default_gem? && !File.directory?(full_gem_path)
+ end
+
+ private
def dependencies_to_gemfile(dependencies, group = nil)
gemfile = String.new
@@ -157,48 +131,99 @@ module Gem
end
out
end
+ end
+
+ # comparison is done order independently since rubygems 3.2.0.rc.2
+ unless Gem::Requirement.new("> 1", "< 2") == Gem::Requirement.new("< 2", "> 1")
+ class Requirement
+ module OrderIndependentComparison
+ def ==(other)
+ if _requirements_sorted? && other._requirements_sorted?
+ super
+ else
+ _with_sorted_requirements == other._with_sorted_requirements
+ end
+ end
- # Backport of performance enhancement added to Rubygems 1.4
- def matches_spec?(spec)
- # name can be a Regexp, so use ===
- return false unless name === spec.name
- return true if requirement.none?
+ protected
+
+ def _requirements_sorted?
+ return @_are_requirements_sorted if defined?(@_are_requirements_sorted)
+ strings = as_list
+ @_are_requirements_sorted = strings == strings.sort
+ end
+
+ def _with_sorted_requirements
+ @_with_sorted_requirements ||= _requirements_sorted? ? self : self.class.new(as_list.sort)
+ end
+ end
- requirement.satisfied_by?(spec.version)
- end unless allocate.respond_to?(:matches_spec?)
+ prepend OrderIndependentComparison
+ end
end
- class Requirement
- # Backport of performance enhancement added to RubyGems 1.4
- def none?
- # note that it might be tempting to replace with with RubyGems 2.0's
- # improved implementation. Don't. It requires `DefaultRequirement` to be
- # defined, and more importantantly, these overrides are not used when the
- # running RubyGems defines these methods
- to_s == ">= 0"
- end unless allocate.respond_to?(:none?)
-
- # Backport of performance enhancement added to RubyGems 2.2
- def exact?
- return false unless @requirements.size == 1
- @requirements[0][0] == "="
- end unless allocate.respond_to?(:exact?)
+ if Gem::Requirement.new("~> 2.0").hash == Gem::Requirement.new("~> 2.0.0").hash
+ class Requirement
+ module CorrectHashForLambdaOperator
+ def hash
+ if requirements.any? {|r| r.first == "~>" }
+ requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
+ else
+ super
+ end
+ end
+ end
+
+ prepend CorrectHashForLambdaOperator
+ end
end
+ require "rubygems/platform"
+
class Platform
JAVA = Gem::Platform.new("java") unless defined?(JAVA)
MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
+ end
+
+ Platform.singleton_class.module_eval do
+ unless Platform.singleton_methods.include?(:match_spec?)
+ def match_spec?(spec)
+ match_gem?(spec.platform, spec.name)
+ end
+
+ def match_gem?(platform, gem_name)
+ match_platforms?(platform, Gem.platforms)
+ end
- undef_method :hash if method_defined? :hash
- def hash
- @cpu.hash ^ @os.hash ^ @version.hash
+ private
+
+ def match_platforms?(platform, platforms)
+ platforms.any? do |local_platform|
+ platform.nil? ||
+ local_platform == platform ||
+ (local_platform != Gem::Platform::RUBY && local_platform =~ platform)
+ end
+ end
end
+ end
- undef_method :eql? if method_defined? :eql?
- alias_method :eql?, :==
+ require "rubygems/util"
+
+ Util.singleton_class.module_eval do
+ if Util.singleton_methods.include?(:glob_files_in_dir) # since 3.0.0.beta.2
+ remove_method :glob_files_in_dir
+ end
+
+ def glob_files_in_dir(glob, base_path)
+ if RUBY_VERSION >= "2.5"
+ Dir.glob(glob, :base => base_path).map! {|f| File.expand_path(f, base_path) }
+ else
+ Dir.glob(File.join(base_path.to_s.gsub(/[\[\]]/, '\\\\\\&'), glob)).map! {|f| File.expand_path(f) }
+ end
+ end
end
end
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb
index 977e13d948..bb9f1cb3f5 100644
--- a/lib/bundler/rubygems_gem_installer.rb
+++ b/lib/bundler/rubygems_gem_installer.rb
@@ -1,23 +1,107 @@
# frozen_string_literal: true
+
require "rubygems/installer"
module Bundler
class RubyGemsGemInstaller < Gem::Installer
- unless respond_to?(:at)
- def self.at(*args)
- new(*args)
+ def check_executable_overwrite(filename)
+ # Bundler needs to install gems regardless of binstub overwriting
+ end
+
+ def install
+ pre_install_checks
+
+ run_pre_install_hooks
+
+ spec.loaded_from = spec_file
+
+ # Completely remove any previous gem files
+ strict_rm_rf gem_dir
+ strict_rm_rf spec.extension_dir
+
+ SharedHelpers.filesystem_access(gem_dir, :create) do
+ FileUtils.mkdir_p gem_dir, :mode => 0o755
end
+
+ extract_files
+
+ build_extensions
+ write_build_info_file
+ run_post_build_hooks
+
+ generate_bin
+ generate_plugins
+
+ write_spec
+
+ SharedHelpers.filesystem_access("#{gem_home}/cache", :write) do
+ write_cache_file
+ end
+
+ say spec.post_install_message unless spec.post_install_message.nil?
+
+ run_post_install_hooks
+
+ spec
end
- def check_executable_overwrite(filename)
- # Bundler needs to install gems regardless of binstub overwriting
+ def generate_plugins
+ return unless Gem::Installer.instance_methods(false).include?(:generate_plugins)
+
+ latest = Gem::Specification.stubs_for(spec.name).first
+ return if latest && latest.version > spec.version
+
+ ensure_writable_dir @plugins_dir
+
+ if spec.plugins.empty?
+ remove_plugins_for(spec, @plugins_dir)
+ else
+ regenerate_plugins_for(spec, @plugins_dir)
+ end
end
def pre_install_checks
super && validate_bundler_checksum(options[:bundler_expected_checksum])
end
- private
+ def build_extensions
+ extension_cache_path = options[:bundler_extension_cache_path]
+ unless extension_cache_path && extension_dir = spec.extension_dir
+ require "shellwords" # compensate missing require in rubygems before version 3.2.25
+ return super
+ end
+
+ extension_dir = Pathname.new(extension_dir)
+ build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?)
+ if build_complete && !options[:force]
+ SharedHelpers.filesystem_access(extension_dir.parent, &:mkpath)
+ SharedHelpers.filesystem_access(extension_cache_path) do
+ FileUtils.cp_r extension_cache_path, spec.extension_dir
+ end
+ else
+ require "shellwords" # compensate missing require in rubygems before version 3.2.25
+ super
+ if extension_dir.directory? # not made for gems without extensions
+ SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
+ SharedHelpers.filesystem_access(extension_cache_path) do
+ FileUtils.cp_r extension_dir, extension_cache_path
+ end
+ end
+ end
+ end
+
+ private
+
+ def strict_rm_rf(dir)
+ # FileUtils.rm_rf should probably rise in case of permission issues like
+ # `rm -rf` does. However, it fails to delete the folder silently due to
+ # https://github.com/ruby/fileutils/issues/57. It should probably be fixed
+ # inside `fileutils` but for now I`m checking whether the folder was
+ # removed after it completes, and raising otherwise.
+ FileUtils.rm_rf dir
+
+ raise PermissionError.new(dir, :delete) if File.directory?(dir)
+ end
def validate_bundler_checksum(checksum)
return true if Bundler.settings[:disable_checksum_validation]
@@ -25,7 +109,7 @@ module Bundler
return true unless source = @package.instance_variable_get(:@gem)
return true unless source.respond_to?(:with_read_io)
digest = source.with_read_io do |io|
- digest = Digest::SHA256.new
+ digest = SharedHelpers.digest(:SHA256).new
digest << io.read(16_384) until io.eof?
io.rewind
send(checksum_type(checksum), digest)
@@ -43,7 +127,7 @@ module Bundler
If you wish to continue installing the downloaded gem, and are certain it does not pose a \
security issue despite the mismatching checksum, do the following:
- 1. run `bundle config disable_checksum_validation true` to turn off checksum verification
+ 1. run `bundle config set --local disable_checksum_validation true` to turn off checksum verification
2. run `bundle install`
(More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index c3e16e086c..f6d59baf15 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -1,13 +1,14 @@
# frozen_string_literal: true
-require "monitor"
-require "rubygems"
-require "rubygems/config_file"
+
+require "rubygems" unless defined?(Gem)
module Bundler
class RubygemsIntegration
if defined?(Gem::Ext::Builder::CHDIR_MONITOR)
EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR
else
+ require "monitor"
+
EXT_LOCK = Monitor.new
end
@@ -21,6 +22,7 @@ module Bundler
def initialize
@replaced_methods = {}
+ backport_ext_builder_monitor
end
def version
@@ -32,21 +34,31 @@ module Bundler
end
def build_args
+ require "rubygems/command"
Gem::Command.build_args
end
def build_args=(args)
+ require "rubygems/command"
Gem::Command.build_args = args
end
- def load_path_insert_index
- Gem.load_path_insert_index
- end
-
def loaded_specs(name)
Gem.loaded_specs[name]
end
+ def add_to_load_path(paths)
+ return Gem.add_to_load_path(*paths) if Gem.respond_to?(:add_to_load_path)
+
+ if insert_index = Gem.load_path_insert_index
+ # Gem directories must come after -I and ENV['RUBYLIB']
+ $LOAD_PATH.insert(insert_index, *paths)
+ else
+ # We are probably testing in core, -I and RUBYLIB don't apply
+ $LOAD_PATH.unshift(*paths)
+ end
+ end
+
def mark_loaded(spec)
if spec.respond_to?(:activated=)
current = Gem.loaded_specs[spec.name]
@@ -74,14 +86,18 @@ module Bundler
def spec_missing_extensions?(spec, default = true)
return spec.missing_extensions? if spec.respond_to?(:missing_extensions?)
- return false if spec_default_gem?(spec)
+ return false if spec.default_gem?
return false if spec.extensions.empty?
default
end
- def spec_default_gem?(spec)
- spec.respond_to?(:default_gem?) && spec.default_gem?
+ def spec_matches_for_glob(spec, glob)
+ return spec.matches_for_glob(glob) if spec.respond_to?(:matches_for_glob)
+
+ spec.load_paths.map do |lp|
+ Dir["#{lp}/#{glob}#{suffix_pattern}"]
+ end.flatten(1)
end
def stub_set_spec(stub, spec)
@@ -92,13 +108,8 @@ module Bundler
obj.to_s
end
- def platforms
- return [Gem::Platform::RUBY] if Bundler.settings[:force_ruby_platform]
- Gem.platforms
- end
-
def configuration
- require "bundler/psyched_yaml"
+ require_relative "psyched_yaml"
Gem.configuration
rescue Gem::SystemExitException, LoadError => e
Bundler.ui.error "#{e.class}: #{e.message}"
@@ -118,7 +129,17 @@ module Bundler
end
def inflate(obj)
- Gem.inflate(obj)
+ Gem::Util.inflate(obj)
+ end
+
+ def correct_for_windows_path(path)
+ if Gem::Util.respond_to?(:correct_for_windows_path)
+ Gem::Util.correct_for_windows_path(path)
+ elsif path[0].chr == "/" && path[1].chr =~ /[a-z]/i && path[2].chr == ":"
+ path[1..-1]
+ else
+ path
+ end
end
def sources=(val)
@@ -158,6 +179,10 @@ module Bundler
Gem.post_reset_hooks
end
+ def suffix_pattern
+ Gem.suffix_pattern
+ end
+
def gem_cache
gem_path.map {|p| File.expand_path("cache", p) }
end
@@ -165,7 +190,7 @@ module Bundler
def spec_cache_dirs
@spec_cache_dirs ||= begin
dirs = gem_path.map {|dir| File.join(dir, "specifications") }
- dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) # Not in Rubygems 2.0.3 or earlier
+ dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) # Not in RubyGems 2.0.3 or earlier
dirs.uniq.select {|dir| File.directory? dir }
end
end
@@ -174,14 +199,6 @@ module Bundler
Gem::MARSHAL_SPEC_DIR
end
- def config_map
- Gem::ConfigMap
- end
-
- def repository_subdirectories
- %w(cache doc gems specifications)
- end
-
def clear_paths
Gem.clear_paths
end
@@ -190,64 +207,29 @@ module Bundler
Gem.bin_path(gem, bin, ver)
end
- def preserve_paths
- # this is a no-op outside of Rubygems 1.8
- yield
- end
-
def loaded_gem_paths
- # RubyGems 2.2+ can put binary extension into dedicated folders,
- # therefore use RubyGems facilities to obtain their load paths.
- if Gem::Specification.method_defined? :full_require_paths
- loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
- loaded_gem_paths.flatten
- else
- $LOAD_PATH.select do |p|
- Bundler.rubygems.gem_path.any? {|gp| p =~ /^#{Regexp.escape(gp)}/ }
- end
- end
+ loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
+ loaded_gem_paths.flatten
end
def load_plugins
Gem.load_plugins if Gem.respond_to?(:load_plugins)
end
- def ui=(obj)
- Gem::DefaultUserInteraction.ui = obj
- end
-
- def ext_lock
- EXT_LOCK
+ def load_plugin_files(files)
+ Gem.load_plugin_files(files) if Gem.respond_to?(:load_plugin_files)
end
- def fetch_specs(all, pre, &blk)
- require "rubygems/spec_fetcher"
- specs = Gem::SpecFetcher.new.list(all, pre)
- specs.each { yield } if block_given?
- specs
+ def load_env_plugins
+ Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins)
end
- def fetch_prerelease_specs
- fetch_specs(false, true)
- rescue Gem::RemoteFetcher::FetchError
- {} # if we can't download them, there aren't any
+ def ui=(obj)
+ Gem::DefaultUserInteraction.ui = obj
end
- # TODO: This is for older versions of Rubygems... should we support the
- # X-Gemfile-Source header on these old versions?
- # Maybe the newer implementation will work on older Rubygems?
- # It seems difficult to keep this implementation and still send the header.
- def fetch_all_remote_specs(remote)
- old_sources = Bundler.rubygems.sources
- Bundler.rubygems.sources = [remote.uri.to_s]
- # Fetch all specs, minus prerelease specs
- spec_list = fetch_specs(true, false)
- # Then fetch the prerelease specs
- fetch_prerelease_specs.each {|k, v| spec_list[k].concat(v) }
-
- spec_list.values.first
- ensure
- Bundler.rubygems.sources = old_sources
+ def ext_lock
+ EXT_LOCK
end
def with_build_args(args)
@@ -262,21 +244,11 @@ module Bundler
end
end
- def install_with_build_args(args)
- with_build_args(args) { yield }
- end
-
- def gem_from_path(path, policy = nil)
- require "rubygems/format"
- Gem::Format.from_file_by_path(path, policy)
- end
-
def spec_from_gem(path, policy = nil)
require "rubygems/security"
+ require_relative "psyched_yaml"
gem_from_path(path, security_policies[policy]).spec
- rescue Gem::Package::FormatError
- raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
- rescue Exception, Gem::Exception, Gem::Security::Exception => e
+ rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
if e.is_a?(Gem::Security::Exception) ||
e.message =~ /unknown trust policy|unsigned gem/i ||
e.message =~ /couldn't verify (meta)?data signature/i
@@ -288,25 +260,12 @@ module Bundler
end
end
- def build(spec, skip_validation = false)
- require "rubygems/builder"
- Gem::Builder.new(spec).build
- end
-
def build_gem(gem_dir, spec)
build(spec)
end
- def download_gem(spec, uri, path)
- uri = Bundler.settings.mirror_for(uri)
- fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
- Bundler::Retry.new("download gem from #{uri}").attempts do
- fetcher.download(spec, uri, path)
- end
- end
-
def security_policy_keys
- %w(High Medium Low AlmostNo No).map {|level| "#{level}Security" }
+ %w[High Medium Low AlmostNo No].map {|level| "#{level}Security" }
end
def security_policies
@@ -328,14 +287,6 @@ module Bundler
end
end
- def binstubs_call_gem?
- true
- end
-
- def stubs_provide_full_functionality?
- false
- end
-
def replace_gem(specs, specs_by_name)
reverse_rubygems_kernel_mixin
@@ -344,7 +295,6 @@ module Bundler
kernel = (class << ::Kernel; self; end)
[kernel, ::Kernel].each do |kernel_class|
redefine_method(kernel_class, :gem) do |dep, *reqs|
- executables ||= specs.map(&:executables).flatten if ::Bundler.rubygems.binstubs_call_gem?
if executables && executables.include?(File.basename(caller.first.split(":").first))
break
end
@@ -360,8 +310,13 @@ module Bundler
end
message = if spec.nil?
+ target_file = begin
+ Bundler.default_gemfile.basename
+ rescue GemfileNotFound
+ "inline Gemfile"
+ end
"#{dep.name} is not part of the bundle." \
- " Add it to your #{Bundler.default_gemfile.basename}."
+ " Add it to your #{target_file}."
else
"can't activate #{dep}, already activated #{spec.full_name}. " \
"Make sure all dependencies are added to Gemfile."
@@ -377,69 +332,50 @@ module Bundler
raise e
end
- # TODO: delete this in 2.0, it's a backwards compatibility shim
- # see https://github.com/bundler/bundler/issues/5102
- kernel_class.send(:public, :gem)
- end
- end
-
- def stub_source_index(specs)
- Gem::SourceIndex.send(:alias_method, :old_initialize, :initialize)
- redefine_method(Gem::SourceIndex, :initialize) do |*args|
- @gems = {}
- # You're looking at this thinking: Oh! This is how I make those
- # rubygems deprecations go away!
- #
- # You'd be correct BUT using of this method in production code
- # must be approved by the rubygems team itself!
- #
- # This is your warning. If you use this and don't have approval
- # we can't protect you.
- #
- Deprecate.skip_during do
- self.spec_dirs = *args
- add_specs(*specs)
- end
+ # backwards compatibility shim, see https://github.com/rubygems/bundler/issues/5102
+ kernel_class.send(:public, :gem) if Bundler.feature_flag.setup_makes_kernel_gem_public?
end
end
# Used to make bin stubs that are not created by bundler work
# under bundler. The new Gem.bin_path only considers gems in
# +specs+
- def replace_bin_path(specs, specs_by_name)
+ def replace_bin_path(specs_by_name)
gem_class = (class << Gem; self; end)
redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
exec_name = args.first
+ raise ArgumentError, "you must supply exec_name" unless exec_name
spec_with_name = specs_by_name[gem_name]
- spec = if exec_name
- if spec_with_name && spec_with_name.executables.include?(exec_name)
- spec_with_name
- else
- specs.find {|s| s.executables.include?(exec_name) }
- end
- else
- spec_with_name
- end
+ matching_specs_by_exec_name = specs_by_name.values.select {|s| s.executables.include?(exec_name) }
+ spec = matching_specs_by_exec_name.delete(spec_with_name)
- unless spec
+ unless spec || !matching_specs_by_exec_name.empty?
message = "can't find executable #{exec_name} for gem #{gem_name}"
- if !exec_name || spec_with_name.nil?
+ if spec_with_name.nil?
message += ". #{gem_name} is not currently included in the bundle, " \
"perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?"
end
raise Gem::Exception, message
end
- raise Gem::Exception, "no default executable for #{spec.full_name}" unless exec_name ||= spec.default_executable
-
- unless spec.name == name
- Bundler::SharedHelpers.major_deprecation \
- "Bundler is using a binstub that was created for a different gem.\n" \
+ unless spec
+ spec = matching_specs_by_exec_name.shift
+ warn \
+ "Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \
"You should run `bundle binstub #{gem_name}` " \
"to work around a system/bundle conflict."
end
+
+ unless matching_specs_by_exec_name.empty?
+ conflicting_names = matching_specs_by_exec_name.map(&:name).join(", ")
+ warn \
+ "The `#{exec_name}` executable in the `#{spec.name}` gem is being loaded, but it's also present in other gems (#{conflicting_names}).\n" \
+ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
+ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
+ end
+
spec
end
@@ -469,83 +405,45 @@ module Bundler
end
end
- # Because Bundler has a static view of what specs are available,
- # we don't #refresh, so stub it out.
- def replace_refresh
- gem_class = (class << Gem; self; end)
- redefine_method(gem_class, :refresh) {}
- end
-
- # Replace or hook into Rubygems to provide a bundlerized view
+ # Replace or hook into RubyGems to provide a bundlerized view
# of the world.
def replace_entrypoints(specs)
- specs_by_name = specs.reduce({}) do |h, s|
- h[s.name] = s
- h
- end
+ specs_by_name = add_default_gems_to(specs)
replace_gem(specs, specs_by_name)
stub_rubygems(specs)
- replace_bin_path(specs, specs_by_name)
- replace_refresh
+ replace_bin_path(specs_by_name)
Gem.clear_paths
end
- # This backports the correct segment generation code from Rubygems 1.4+
- # by monkeypatching it into the method in Rubygems 1.3.6 and 1.3.7.
- def backport_segment_generation
- redefine_method(Gem::Version, :segments) do
- @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
- /^\d+$/ =~ s ? s.to_i : s
- end
- end
- end
-
- # This backport fixes the marshaling of @segments.
- def backport_yaml_initialize
- redefine_method(Gem::Version, :yaml_initialize) do |_, map|
- @version = map["version"]
- @segments = nil
- @hash = nil
- end
- end
-
- # This backports base_dir which replaces installation path
- # Rubygems 1.8+
- def backport_base_dir
- redefine_method(Gem::Specification, :base_dir) do
- return Gem.dir unless loaded_from
- File.dirname File.dirname loaded_from
- end
- end
-
- def backport_cache_file
- redefine_method(Gem::Specification, :cache_dir) do
- @cache_dir ||= File.join base_dir, "cache"
+ # Add default gems not already present in specs, and return them as a hash.
+ def add_default_gems_to(specs)
+ specs_by_name = specs.reduce({}) do |h, s|
+ h[s.name] = s
+ h
end
- redefine_method(Gem::Specification, :cache_file) do
- @cache_file ||= File.join cache_dir, "#{full_name}.gem"
- end
- end
+ Bundler.rubygems.default_stubs.each do |stub|
+ default_spec = stub.to_spec
+ default_spec_name = default_spec.name
+ next if specs_by_name.key?(default_spec_name)
- def backport_spec_file
- redefine_method(Gem::Specification, :spec_dir) do
- @spec_dir ||= File.join base_dir, "specifications"
+ specs << default_spec
+ specs_by_name[default_spec_name] = default_spec
end
- redefine_method(Gem::Specification, :spec_file) do
- @spec_file ||= File.join spec_dir, "#{full_name}.gemspec"
- end
+ specs_by_name
end
def undo_replacements
@replaced_methods.each do |(sym, klass), method|
redefine_method(klass, sym, method)
end
- post_reset_hooks.reject! do |proc|
- proc.binding.eval("__FILE__") == __FILE__
+ if Binding.public_method_defined?(:source_location)
+ post_reset_hooks.reject! {|proc| proc.binding.source_location[0] == __FILE__ }
+ else
+ post_reset_hooks.reject! {|proc| proc.binding.eval("__FILE__") == __FILE__ }
end
@replaced_methods.clear
end
@@ -581,282 +479,155 @@ module Bundler
end
end
- # Rubygems 1.4 through 1.6
- class Legacy < RubygemsIntegration
- def initialize
- super
- backport_base_dir
- backport_cache_file
- backport_spec_file
- backport_yaml_initialize
- end
-
- def stub_rubygems(specs)
- # Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
- source_index_class = (class << Gem::SourceIndex; self; end)
- redefine_method(source_index_class, :from_gems_in) do |*args|
- Gem::SourceIndex.new.tap do |source_index|
- source_index.spec_dirs = *args
- source_index.add_specs(*specs)
- end
- end
- end
+ def stub_rubygems(specs)
+ Gem::Specification.all = specs
- def all_specs
- Gem.source_index.gems.values
- end
-
- def find_name(name)
- Gem.source_index.find_name(name)
- end
-
- def validate(spec)
- # These versions of RubyGems always validate in "packaging" mode,
- # which is too strict for the kinds of checks we care about. As a
- # result, validation is disabled on versions of RubyGems below 1.7.
+ Gem.post_reset do
+ Gem::Specification.all = specs
end
- def post_reset_hooks
+ redefine_method((class << Gem; self; end), :finish_resolve) do |*|
[]
end
+ end
- def reset
- end
+ def plain_specs
+ Gem::Specification._all
end
- # Rubygems versions 1.3.6 and 1.3.7
- class Ancient < Legacy
- def initialize
- super
- backport_segment_generation
- end
+ def plain_specs=(specs)
+ Gem::Specification.all = specs
end
- # Rubygems 1.7
- class Transitional < Legacy
- def stub_rubygems(specs)
- stub_source_index(specs)
- end
+ def fetch_specs(remote, name)
+ require "rubygems/remote_fetcher"
+ path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
+ fetcher = gem_remote_fetcher
+ fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
+ string = fetcher.fetch_path(path)
+ Bundler.load_marshal(string)
+ rescue Gem::RemoteFetcher::FetchError
+ # it's okay for prerelease to fail
+ raise unless name == "prerelease_specs"
+ end
- def validate(spec)
- # Missing summary is downgraded to a warning in later versions,
- # so we set it to an empty string to prevent an exception here.
- spec.summary ||= ""
- RubygemsIntegration.instance_method(:validate).bind(self).call(spec)
- end
+ def fetch_all_remote_specs(remote)
+ specs = fetch_specs(remote, "specs")
+ pres = fetch_specs(remote, "prerelease_specs") || []
+
+ specs.concat(pres)
end
- # Rubygems 1.8.5-1.8.19
- class Modern < RubygemsIntegration
- def stub_rubygems(specs)
- Gem::Specification.all = specs
+ def download_gem(spec, uri, cache_dir)
+ require "rubygems/remote_fetcher"
+ uri = Bundler.settings.mirror_for(uri)
+ fetcher = gem_remote_fetcher
+ fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
+ Bundler::Retry.new("download gem from #{uri}").attempts do
+ gem_file_name = spec.file_name
+ local_gem_path = File.join cache_dir, gem_file_name
+ return if File.exist? local_gem_path
- Gem.post_reset do
- Gem::Specification.all = specs
- end
+ begin
+ remote_gem_path = uri + "gems/#{gem_file_name}"
+ remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1")
- stub_source_index(specs)
- end
+ SharedHelpers.filesystem_access(local_gem_path) do
+ fetcher.cache_update_path remote_gem_path, local_gem_path
+ end
+ rescue Gem::RemoteFetcher::FetchError
+ raise if spec.original_platform == spec.platform
- def all_specs
- Gem::Specification.to_a
- end
+ original_gem_file_name = "#{spec.original_name}.gem"
+ raise if gem_file_name == original_gem_file_name
- def find_name(name)
- Gem::Specification.find_all_by_name name
+ gem_file_name = original_gem_file_name
+ retry
+ end
end
+ rescue Gem::RemoteFetcher::FetchError => e
+ raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
end
- # Rubygems 1.8.0 to 1.8.4
- class AlmostModern < Modern
- # Rubygems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
- # you call Gem::Installer#install with an :install_dir set. We have to
- # change it back for our sudo mode to work.
- def preserve_paths
- old_dir = gem_dir
- old_path = gem_path
- yield
- Gem.use_paths(old_dir, old_path)
- end
+ def gem_remote_fetcher
+ require "rubygems/remote_fetcher"
+ proxy = configuration[:http_proxy]
+ Gem::RemoteFetcher.new(proxy)
end
- # Rubygems 1.8.20+
- class MoreModern < Modern
- # Rubygems 1.8.20 and adds the skip_validation parameter, so that's
- # when we start passing it through.
- def build(spec, skip_validation = false)
- require "rubygems/builder"
- Gem::Builder.new(spec).build(skip_validation)
- end
+ def gem_from_path(path, policy = nil)
+ require "rubygems/package"
+ p = Gem::Package.new(path)
+ p.security_policy = policy if policy
+ p
end
- # Rubygems 2.0
- class Future < RubygemsIntegration
- def stub_rubygems(specs)
- Gem::Specification.all = specs
-
- Gem.post_reset do
- Gem::Specification.all = specs
- end
-
- redefine_method((class << Gem; self; end), :finish_resolve) do |*|
- []
- end
- end
-
- def all_specs
- Gem::Specification.to_a
- end
-
- def find_name(name)
- Gem::Specification.find_all_by_name name
- end
+ def build(spec, skip_validation = false)
+ require "rubygems/package"
+ Gem::Package.build(spec, skip_validation)
+ end
- def fetch_specs(source, remote, name)
- path = source + "#{name}.#{Gem.marshal_version}.gz"
- fetcher = gem_remote_fetcher
- fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
- string = fetcher.fetch_path(path)
- Bundler.load_marshal(string)
- rescue Gem::RemoteFetcher::FetchError => e
- # it's okay for prerelease to fail
- raise e unless name == "prerelease_specs"
- end
+ def repository_subdirectories
+ Gem::REPOSITORY_SUBDIRECTORIES
+ end
- def fetch_all_remote_specs(remote)
- source = remote.uri.is_a?(URI) ? remote.uri : URI.parse(source.to_s)
+ def install_with_build_args(args)
+ yield
+ end
- specs = fetch_specs(source, remote, "specs")
- pres = fetch_specs(source, remote, "prerelease_specs") || []
+ def path_separator
+ Gem.path_separator
+ end
- specs.concat(pres)
+ def all_specs
+ Gem::Specification.stubs.map do |stub|
+ StubSpecification.from_stub(stub)
end
+ end
- def download_gem(spec, uri, path)
- uri = Bundler.settings.mirror_for(uri)
- fetcher = gem_remote_fetcher
- fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
- Bundler::Retry.new("download gem from #{uri}").attempts do
- fetcher.download(spec, uri, path)
+ def backport_ext_builder_monitor
+ # So we can avoid requiring "rubygems/ext" in its entirety
+ Gem.module_eval <<-RUBY, __FILE__, __LINE__ + 1
+ module Ext
end
- end
-
- def gem_remote_fetcher
- require "resolv"
- proxy = configuration[:http_proxy]
- dns = Resolv::DNS.new
- Bundler::GemRemoteFetcher.new(proxy, dns)
- end
+ RUBY
- def gem_from_path(path, policy = nil)
- require "rubygems/package"
- p = Gem::Package.new(path)
- p.security_policy = policy if policy
- p
- end
+ require "rubygems/ext/builder"
- def build(spec, skip_validation = false)
- require "rubygems/package"
- Gem::Package.build(spec, skip_validation)
- end
-
- def repository_subdirectories
- Gem::REPOSITORY_SUBDIRECTORIES
- end
+ Gem::Ext::Builder.class_eval do
+ unless const_defined?(:CHDIR_MONITOR)
+ const_set(:CHDIR_MONITOR, EXT_LOCK)
+ end
- def install_with_build_args(args)
- yield
+ remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
+ const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
end
end
- # RubyGems 2.1.0
- class MoreFuture < Future
- def initialize
- super
- backport_ext_builder_monitor
- end
-
- def all_specs
- require "bundler/remote_specification"
- Gem::Specification.stubs.map do |stub|
- StubSpecification.from_stub(stub)
- end
- end
-
- def backport_ext_builder_monitor
- # So we can avoid requiring "rubygems/ext" in its entirety
- Gem.module_eval <<-RB, __FILE__, __LINE__ + 1
- module Ext
- end
- RB
-
- require "rubygems/ext/builder"
-
- Gem::Ext::Builder.class_eval do
- unless const_defined?(:CHDIR_MONITOR)
- const_set(:CHDIR_MONITOR, EXT_LOCK)
- end
-
- remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
- const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
- end
- end
+ def find_name(name)
+ Gem::Specification.stubs_for(name).map(&:to_spec)
+ end
- if Gem::Specification.respond_to?(:stubs_for)
- def find_name(name)
- Gem::Specification.stubs_for(name).map(&:to_spec)
- end
- else
- def find_name(name)
- Gem::Specification.stubs.find_all do |spec|
- spec.name == name
- end.map(&:to_spec)
- end
+ if Gem::Specification.respond_to?(:default_stubs)
+ def default_stubs
+ Gem::Specification.default_stubs("*.gemspec")
end
-
- def use_gemdeps(gemfile)
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
- require "bundler/gemdeps"
- runtime = Bundler.setup
- Bundler.ui = nil
- activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
- [Gemdeps.new(runtime), activated_spec_names]
+ else
+ def default_stubs
+ Gem::Specification.send(:default_stubs, "*.gemspec")
end
+ end
- if provides?(">= 2.5.2")
- # RubyGems-generated binstubs call Kernel#gem
- def binstubs_call_gem?
- false
- end
-
- # only 2.5.2+ has all of the stub methods we want to use, and since this
- # is a performance optimization _only_,
- # we'll restrict ourselves to the most
- # recent RG versions instead of all versions that have stubs
- def stubs_provide_full_functionality?
- true
- end
- end
+ def use_gemdeps(gemfile)
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
+ require_relative "gemdeps"
+ runtime = Bundler.setup
+ activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
+ [Gemdeps.new(runtime), activated_spec_names]
end
end
def self.rubygems
- @rubygems ||= if RubygemsIntegration.provides?(">= 2.1.0")
- RubygemsIntegration::MoreFuture.new
- elsif RubygemsIntegration.provides?(">= 1.99.99")
- RubygemsIntegration::Future.new
- elsif RubygemsIntegration.provides?(">= 1.8.20")
- RubygemsIntegration::MoreModern.new
- elsif RubygemsIntegration.provides?(">= 1.8.5")
- RubygemsIntegration::Modern.new
- elsif RubygemsIntegration.provides?(">= 1.8.0")
- RubygemsIntegration::AlmostModern.new
- elsif RubygemsIntegration.provides?(">= 1.7.0")
- RubygemsIntegration::Transitional.new
- elsif RubygemsIntegration.provides?(">= 1.4.0")
- RubygemsIntegration::Legacy.new
- else # Rubygems 1.3.6 and 1.3.7
- RubygemsIntegration::Ancient.new
- end
+ @rubygems ||= RubygemsIntegration.new
end
end
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
index 5540509d74..c7276b0e25 100644
--- a/lib/bundler/runtime.rb
+++ b/lib/bundler/runtime.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "digest/sha1"
module Bundler
class Runtime
@@ -11,38 +10,25 @@ module Bundler
end
def setup(*groups)
- @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.settings[:frozen]
-
- groups.map!(&:to_sym)
+ @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?
# Has to happen first
clean_load_path
- specs = groups.any? ? @definition.specs_for(groups) : requested_specs
+ specs = @definition.specs_for(groups)
SharedHelpers.set_bundle_environment
Bundler.rubygems.replace_entrypoints(specs)
# Activate the specs
load_paths = specs.map do |spec|
- unless spec.loaded_from
- raise GemNotFound, "#{spec.full_name} is missing. Run `bundle install` to get it."
- end
-
check_for_activated_spec!(spec)
Bundler.rubygems.mark_loaded(spec)
spec.load_paths.reject {|path| $LOAD_PATH.include?(path) }
end.reverse.flatten
- # See Gem::Specification#add_self_to_load_path (since RubyGems 1.8)
- if insert_index = Bundler.rubygems.load_path_insert_index
- # Gem directories must come after -I and ENV['RUBYLIB']
- $LOAD_PATH.insert(insert_index, *load_paths)
- else
- # We are probably testing in core, -I and RUBYLIB don't apply
- $LOAD_PATH.unshift(*load_paths)
- end
+ Bundler.rubygems.add_to_load_path(load_paths)
setup_manpath
@@ -51,14 +37,6 @@ module Bundler
self
end
- REQUIRE_ERRORS = [
- /^no such file to load -- (.+)$/i,
- /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
- /^Missing API definition file in (.+)$/i,
- /^cannot load such file -- (.+)$/i,
- /^dlopen\([^)]*\): Library not loaded: (.+)$/i,
- ].freeze
-
def require(*groups)
groups.map!(&:to_sym)
groups = [:default] if groups.empty?
@@ -80,23 +58,21 @@ module Bundler
required_file = file
begin
Kernel.require file
- rescue => e
+ rescue RuntimeError => e
raise e if e.is_a?(LoadError) # we handle this a little later
raise Bundler::GemRequireError.new e,
"There was an error while trying to load the gem '#{file}'."
end
end
rescue LoadError => e
- REQUIRE_ERRORS.find {|r| r =~ e.message }
- raise if dep.autorequire || $1 != required_file
+ raise if dep.autorequire || e.path != required_file
if dep.autorequire.nil? && dep.name.include?("-")
begin
namespaced_file = dep.name.tr("-", "/")
Kernel.require namespaced_file
rescue LoadError => e
- REQUIRE_ERRORS.find {|r| r =~ e.message }
- raise if $1 != namespaced_file
+ raise if e.path != namespaced_file
end
end
end
@@ -124,7 +100,7 @@ module Bundler
alias_method :gems, :specs
- def cache(custom_path = nil)
+ def cache(custom_path = nil, local = false)
cache_path = Bundler.app_cache(custom_path)
SharedHelpers.filesystem_access(cache_path) do |p|
FileUtils.mkdir_p(p)
@@ -132,7 +108,20 @@ module Bundler
Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
- specs_to_cache = Bundler.settings[:cache_all_platforms] ? @definition.resolve.materialized_for_all_platforms : specs
+ specs_to_cache = if Bundler.settings[:cache_all_platforms]
+ @definition.resolve.materialized_for_all_platforms
+ else
+ begin
+ specs
+ rescue GemNotFound
+ if local
+ Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
+ end
+
+ raise
+ end
+ end
+
specs_to_cache.each do |spec|
next if spec.name == "bundler"
next if spec.source.is_a?(Source::Gemspec)
@@ -164,6 +153,7 @@ module Bundler
gem_dirs = Dir["#{Gem.dir}/gems/*"]
gem_files = Dir["#{Gem.dir}/cache/*.gem"]
gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"]
+ extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"] + Dir["#{Gem.dir}/bundler/gems/extensions/*/*/*"]
spec_gem_paths = []
# need to keep git sources around
spec_git_paths = @definition.spec_git_paths
@@ -171,7 +161,8 @@ module Bundler
spec_gem_executables = []
spec_cache_paths = []
spec_gemspec_paths = []
- specs.each do |spec|
+ spec_extension_paths = []
+ Bundler.rubygems.add_default_gems_to(specs).values.each do |spec|
spec_gem_paths << spec.full_gem_path
# need to check here in case gems are nested like for the rails git repo
md = %r{(.+bundler/gems/.+-[a-f0-9]{7,12})}.match(spec.full_gem_path)
@@ -182,6 +173,7 @@ module Bundler
end
spec_cache_paths << spec.cache_file
spec_gemspec_paths << spec.spec_file
+ spec_extension_paths << spec.extension_dir if spec.respond_to?(:extension_dir)
spec_git_cache_dirs << spec.source.cache_path.to_s if spec.source.is_a?(Bundler::Source::Git)
end
spec_gem_paths.uniq!
@@ -193,6 +185,7 @@ module Bundler
stale_gem_dirs = gem_dirs - spec_gem_paths
stale_gem_files = gem_files - spec_cache_paths
stale_gemspec_files = gemspec_files - spec_gemspec_paths
+ stale_extension_dirs = extension_dirs - spec_extension_paths
removed_stale_gem_dirs = stale_gem_dirs.collect {|dir| remove_dir(dir, dry_run) }
removed_stale_git_dirs = stale_git_dirs.collect {|dir| remove_dir(dir, dry_run) }
@@ -205,8 +198,10 @@ module Bundler
FileUtils.rm(file) if File.exist?(file)
end
end
- stale_git_cache_dirs.each do |cache_dir|
- SharedHelpers.filesystem_access(cache_dir) do |dir|
+
+ stale_dirs = stale_git_cache_dirs + stale_extension_dirs
+ stale_dirs.each do |stale_dir|
+ SharedHelpers.filesystem_access(stale_dir) do |dir|
FileUtils.rm_rf(dir) if File.exist?(dir)
end
end
@@ -215,7 +210,7 @@ module Bundler
output
end
- private
+ private
def prune_gem_cache(resolve, cache_path)
cached = Dir["#{cache_path}/*.gem"]
@@ -262,9 +257,6 @@ module Bundler
end
def setup_manpath
- # Store original MANPATH for restoration later in with_clean_env()
- ENV["BUNDLER_ORIG_MANPATH"] = ENV["MANPATH"]
-
# Add man/ subdirectories from activated bundles to MANPATH for man(1)
manuals = $LOAD_PATH.map do |path|
man_subdir = path.sub(/lib$/, "man")
@@ -272,8 +264,8 @@ module Bundler
end.compact
return if manuals.empty?
- ENV["MANPATH"] = manuals.concat(
- ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR)
+ Bundler::SharedHelpers.set_env "MANPATH", manuals.concat(
+ ENV["MANPATH"] ? ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR) : [""]
).uniq.join(File::PATH_SEPARATOR)
end
@@ -299,7 +291,7 @@ module Bundler
return unless activated_spec = Bundler.rubygems.loaded_specs(spec.name)
return if activated_spec.version == spec.version
- suggestion = if Bundler.rubygems.spec_default_gem?(activated_spec)
+ suggestion = if activated_spec.default_gem?
"Since #{spec.name} is a default gem, you can either remove your dependency on it" \
" or try updating to a newer version of bundler that supports #{spec.name} as a default gem."
else
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 1898738b7c..1ced590b6f 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -1,116 +1,149 @@
# frozen_string_literal: true
-require "uri"
module Bundler
class Settings
- autoload :Mirror, "bundler/mirror"
- autoload :Mirrors, "bundler/mirror"
+ autoload :Mirror, File.expand_path("mirror", __dir__)
+ autoload :Mirrors, File.expand_path("mirror", __dir__)
+ autoload :Validator, File.expand_path("settings/validator", __dir__)
- BOOL_KEYS = %w(
+ BOOL_KEYS = %w[
+ allow_deployment_source_credential_changes
allow_offline_install
+ auto_clean_without_path
auto_install
cache_all
cache_all_platforms
+ clean
+ default_install_uses_path
+ deployment
disable_checksum_validation
disable_exec_load
disable_local_branch_check
+ disable_local_revision_check
disable_shared_gems
disable_version_check
force_ruby_platform
+ forget_cli_options
frozen
+ gem.changelog
gem.coc
gem.mit
+ git.allow_insecure
+ global_gem_cache
ignore_messages
- major_deprecations
+ init_gems_rb
+ inline
no_install
no_prune
- only_update_to_newer_versions
+ path_relative_to_cwd
+ path.system
plugins
+ prefer_patch
+ print_only_version_number
+ setup_makes_kernel_gem_public
+ silence_deprecations
silence_root_warning
- ).freeze
+ suppress_install_using_messages
+ update_requires_all_flag
+ use_gem_version_promoter_for_major_updates
+ ].freeze
- NUMBER_KEYS = %w(
+ NUMBER_KEYS = %w[
+ jobs
redirect
retry
ssl_verify_mode
timeout
- ).freeze
+ ].freeze
+
+ ARRAY_KEYS = %w[
+ with
+ without
+ ].freeze
+
+ STRING_KEYS = %w[
+ bin
+ cache_path
+ console
+ gem.ci
+ gem.github_username
+ gem.linter
+ gem.rubocop
+ gem.test
+ gemfile
+ path
+ shebang
+ system_bindir
+ trust-policy
+ ].freeze
DEFAULT_CONFIG = {
- :redirect => 5,
- :retry => 3,
- :timeout => 10,
+ "BUNDLE_SILENCE_DEPRECATIONS" => false,
+ "BUNDLE_DISABLE_VERSION_CHECK" => true,
+ "BUNDLE_PREFER_PATCH" => false,
+ "BUNDLE_REDIRECT" => 5,
+ "BUNDLE_RETRY" => 3,
+ "BUNDLE_TIMEOUT" => 10,
}.freeze
- attr_accessor :cli_flags_given
-
def initialize(root = nil)
@root = root
@local_config = load_config(local_config_file)
+ @env_config = ENV.to_h.select {|key, _value| key =~ /\ABUNDLE_.+/ }
@global_config = load_config(global_config_file)
- @cli_flags_given = false
@temporary = {}
end
def [](name)
key = key_for(name)
- value = @temporary.fetch(name) do
- @local_config.fetch(key) do
- ENV.fetch(key) do
- @global_config.fetch(key) do
- DEFAULT_CONFIG.fetch(name) do
- nil
- end end end end end
+ value = configs.values.map {|config| config[key] }.compact.first
converted_value(value, name)
end
- def []=(key, value)
- if cli_flags_given
- command = if value.nil?
- "bundle config --delete #{key}"
- else
- "bundle config #{key} #{Array(value).join(":")}"
- end
-
- Bundler::SharedHelpers.major_deprecation \
- "flags passed to commands " \
- "will no longer be automatically remembered. Instead please set flags " \
- "you want remembered between commands using `bundle config " \
- "<setting name> <setting value>`, i.e. `#{command}`"
+ def set_command_option(key, value)
+ if Bundler.feature_flag.forget_cli_options?
+ temporary(key => value)
+ value
+ else
+ set_local(key, value)
end
+ end
+
+ def set_command_option_if_given(key, value)
+ return if value.nil?
+ set_command_option(key, value)
+ end
+
+ def set_local(key, value)
local_config_file || raise(GemfileNotFound, "Could not locate Gemfile")
+
set_key(key, value, @local_config, local_config_file)
end
- alias_method :set_local, :[]=
def temporary(update)
- existing = Hash[update.map {|k, _| [k, @temporary[k]] }]
- @temporary.update(update)
+ existing = Hash[update.map {|k, _| [k, @temporary[key_for(k)]] }]
+ update.each do |k, v|
+ set_key(k, v, @temporary, nil)
+ end
return unless block_given?
begin
yield
ensure
- existing.each {|k, v| v.nil? ? @temporary.delete(k) : @temporary[k] = v }
+ existing.each {|k, v| set_key(k, v, @temporary, nil) }
end
end
- def delete(key)
- @local_config.delete(key_for(key))
- end
-
def set_global(key, value)
set_key(key, value, @global_config, global_config_file)
end
def all
- env_keys = ENV.keys.select {|k| k =~ /BUNDLE_.*/ }
-
- keys = @global_config.keys | @local_config.keys | env_keys
+ keys = @temporary.keys | @global_config.keys | @local_config.keys | @env_config.keys
keys.map do |key|
- key.sub(/^BUNDLE_/, "").gsub(/__/, ".").downcase
- end
+ key.sub(/^BUNDLE_/, "").gsub(/___/, "-").gsub(/__/, ".").downcase
+ end.sort
end
def local_overrides
@@ -122,7 +155,11 @@ module Bundler
end
def mirror_for(uri)
- uri = URI(uri.to_s) unless uri.is_a?(URI)
+ if uri.is_a?(String)
+ require_relative "vendored_uri"
+ uri = Bundler::URI(uri)
+ end
+
gem_mirrors.for(uri.to_s).uri
end
@@ -132,72 +169,117 @@ module Bundler
def gem_mirrors
all.inject(Mirrors.new) do |mirrors, k|
- mirrors.parse(k, self[k]) if k =~ /^mirror\./
+ mirrors.parse(k, self[k]) if k.start_with?("mirror.")
mirrors
end
end
def locations(key)
key = key_for(key)
- locations = {}
- locations[:local] = @local_config[key] if @local_config.key?(key)
- locations[:env] = ENV[key] if ENV[key]
- locations[:global] = @global_config[key] if @global_config.key?(key)
- locations[:default] = DEFAULT_CONFIG[key] if DEFAULT_CONFIG.key?(key)
- locations
+ configs.keys.inject({}) do |partial_locations, level|
+ value_on_level = configs[level][key]
+ partial_locations[level] = value_on_level unless value_on_level.nil?
+ partial_locations
+ end
end
def pretty_values_for(exposed_key)
key = key_for(exposed_key)
locations = []
- if @local_config.key?(key)
- locations << "Set for your local app (#{local_config_file}): #{converted_value(@local_config[key], exposed_key).inspect}"
+
+ if value = @temporary[key]
+ locations << "Set for the current command: #{printable_value(value, exposed_key).inspect}"
+ end
+
+ if value = @local_config[key]
+ locations << "Set for your local app (#{local_config_file}): #{printable_value(value, exposed_key).inspect}"
end
- if value = ENV[key]
- locations << "Set via #{key}: #{converted_value(value, exposed_key).inspect}"
+ if value = @env_config[key]
+ locations << "Set via #{key}: #{printable_value(value, exposed_key).inspect}"
end
- if @global_config.key?(key)
- locations << "Set for the current user (#{global_config_file}): #{converted_value(@global_config[key], exposed_key).inspect}"
+ if value = @global_config[key]
+ locations << "Set for the current user (#{global_config_file}): #{printable_value(value, exposed_key).inspect}"
end
return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
locations
end
- def without=(array)
- set_array(:without, array)
+ def processor_count
+ require "etc"
+ Etc.nprocessors
+ rescue StandardError
+ 1
end
- def with=(array)
- set_array(:with, array)
- end
+ # for legacy reasons, in Bundler 2, we do not respect :disable_shared_gems
+ def path
+ configs.each do |_level, settings|
+ path = value_for("path", settings)
+ path_system = value_for("path.system", settings)
+ disabled_shared_gems = value_for("disable_shared_gems", settings)
+ next if path.nil? && path_system.nil? && disabled_shared_gems.nil?
+ system_path = path_system || (disabled_shared_gems == false)
+ return Path.new(path, system_path)
+ end
- def without
- get_array(:without)
+ Path.new(nil, false)
end
- def with
- get_array(:with)
- end
+ Path = Struct.new(:explicit_path, :system_path) do
+ def path
+ path = base_path
+ path = File.join(path, Bundler.ruby_scope) unless use_system_gems?
+ path
+ end
- # @local_config["BUNDLE_PATH"] should be prioritized over ENV["BUNDLE_PATH"]
- def path
- key = key_for(:path)
- path = ENV[key] || @global_config[key]
- return path if path && !@local_config.key?(key)
+ def use_system_gems?
+ return true if system_path
+ return false if explicit_path
+ !Bundler.feature_flag.default_install_uses_path?
+ end
- if path = self[:path]
- "#{path}/#{Bundler.ruby_scope}"
- else
- Bundler.rubygems.gem_dir
+ def base_path
+ path = explicit_path
+ path ||= ".bundle" unless use_system_gems?
+ path ||= Bundler.rubygems.gem_dir
+ path
+ end
+
+ def base_path_relative_to_pwd
+ base_path = Pathname.new(self.base_path)
+ expanded_base_path = base_path.expand_path(Bundler.root)
+ relative_path = expanded_base_path.relative_path_from(Pathname.pwd)
+ if relative_path.to_s.start_with?("..")
+ relative_path = base_path if base_path.absolute?
+ else
+ relative_path = Pathname.new(File.join(".", relative_path))
+ end
+ relative_path
+ rescue ArgumentError
+ expanded_base_path
+ end
+
+ def validate!
+ return unless explicit_path && system_path
+ path = Bundler.settings.pretty_values_for(:path)
+ path.unshift(nil, "path:") unless path.empty?
+ system_path = Bundler.settings.pretty_values_for("path.system")
+ system_path.unshift(nil, "path.system:") unless system_path.empty?
+ disable_shared_gems = Bundler.settings.pretty_values_for(:disable_shared_gems)
+ disable_shared_gems.unshift(nil, "disable_shared_gems:") unless disable_shared_gems.empty?
+ raise InvalidOption,
+ "Using a custom path while using system gems is unsupported.\n#{path.join("\n")}\n#{system_path.join("\n")}\n#{disable_shared_gems.join("\n")}"
end
end
def allow_sudo?
- !@local_config.key?(key_for(:path))
+ key = key_for(:path)
+ path_configured = @temporary.key?(key) || @local_config.key?(key)
+ !path_configured
end
def ignore_config?
@@ -205,30 +287,47 @@ module Bundler
end
def app_cache_path
- @app_cache_path ||= begin
- path = self[:cache_path] || "vendor/cache"
- raise InvalidOption, "Cache path must be relative to the bundle path" if path.start_with?("/")
- path
- end
+ @app_cache_path ||= self[:cache_path] || "vendor/cache"
end
- private
+ def validate!
+ all.each do |raw_key|
+ [@local_config, @env_config, @global_config].each do |settings|
+ value = value_for(raw_key, settings)
+ Validator.validate!(raw_key, value, settings.dup)
+ end
+ end
+ end
def key_for(key)
- key = Settings.normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
- key = key.to_s.gsub(".", "__").upcase
- "BUNDLE_#{key}"
+ self.class.key_for(key)
+ end
+
+ private
+
+ def configs
+ {
+ :temporary => @temporary,
+ :local => @local_config,
+ :env => @env_config,
+ :global => @global_config,
+ :default => DEFAULT_CONFIG,
+ }
+ end
+
+ def value_for(name, config)
+ converted_value(config[key_for(name)], name)
end
def parent_setting_for(name)
- split_specfic_setting_for(name)[0]
+ split_specific_setting_for(name)[0]
end
- def specfic_gem_for(name)
- split_specfic_setting_for(name)[1]
+ def specific_gem_for(name)
+ split_specific_setting_for(name)[1]
end
- def split_specfic_setting_for(name)
+ def split_specific_setting_for(name)
name.split(".")
end
@@ -236,6 +335,10 @@ module Bundler
BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s))
end
+ def is_string(name)
+ STRING_KEYS.include?(name.to_s) || name.to_s.start_with?("local.") || name.to_s.start_with?("mirror.") || name.to_s.start_with?("build.")
+ end
+
def to_bool(value)
case value
when nil, /\A(false|f|no|n|0|)\z/i, false
@@ -245,55 +348,100 @@ module Bundler
end
end
- def is_num(value)
- NUMBER_KEYS.include?(value.to_s)
+ def is_num(key)
+ NUMBER_KEYS.include?(key.to_s)
end
- def get_array(key)
- self[key] ? self[key].split(":").map(&:to_sym) : []
+ def is_array(key)
+ ARRAY_KEYS.include?(key.to_s)
end
- def set_array(key, array)
- self[key] = (array.empty? ? nil : array.join(":")) if array
+ def is_credential(key)
+ key == "gem.push_key"
end
- def set_key(key, value, hash, file)
- key = key_for(key)
+ def is_userinfo(value)
+ value.include?(":")
+ end
- unless hash[key] == value
- hash[key] = value
- hash.delete(key) if value.nil?
- SharedHelpers.filesystem_access(file) do |p|
- FileUtils.mkdir_p(p.dirname)
- require "bundler/yaml_serializer"
- p.open("w") {|f| f.write(YAMLSerializer.dump(hash)) }
- end
- end
+ def to_array(value)
+ return [] unless value
+ value.split(":").map(&:to_sym)
+ end
- value
+ def array_to_s(array)
+ array = Array(array)
+ return nil if array.empty?
+ array.join(":").tr(" ", ":")
+ end
+
+ def set_key(raw_key, value, hash, file)
+ raw_key = raw_key.to_s
+ value = array_to_s(value) if is_array(raw_key)
+
+ key = key_for(raw_key)
+
+ return if hash[key] == value
+
+ hash[key] = value
+ hash.delete(key) if value.nil?
+
+ Validator.validate!(raw_key, converted_value(value, raw_key), hash)
+
+ return unless file
+ SharedHelpers.filesystem_access(file) do |p|
+ FileUtils.mkdir_p(p.dirname)
+ require_relative "yaml_serializer"
+ p.open("w") {|f| f.write(YAMLSerializer.dump(hash)) }
+ end
end
def converted_value(value, key)
- if value.nil?
+ if is_array(key)
+ to_array(value)
+ elsif value.nil?
nil
elsif is_bool(key) || value == "false"
to_bool(value)
elsif is_num(key)
value.to_i
else
- value
+ value.to_s
+ end
+ end
+
+ def printable_value(value, key)
+ converted = converted_value(value, key)
+ return converted unless converted.is_a?(String)
+
+ if is_string(key)
+ converted
+ elsif is_credential(key)
+ "[REDACTED]"
+ elsif is_userinfo(converted)
+ username, pass = converted.split(":", 2)
+
+ if pass == "x-oauth-basic"
+ username = "[REDACTED]"
+ else
+ pass = "[REDACTED]"
+ end
+
+ [username, pass].join(":")
+ else
+ converted
end
end
def global_config_file
if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
Pathname.new(ENV["BUNDLE_CONFIG"])
- else
- begin
- Bundler.user_bundle_path.join("config")
- rescue PermissionError, GenericSystemCallError
- nil
- end
+ elsif ENV["BUNDLE_USER_CONFIG"] && !ENV["BUNDLE_USER_CONFIG"].empty?
+ Pathname.new(ENV["BUNDLE_USER_CONFIG"])
+ elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty?
+ Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config")
+ elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty?
+ Pathname.new(Bundler.rubygems.user_home).join(".bundle/config")
end
end
@@ -301,40 +449,64 @@ module Bundler
Pathname.new(@root).join("config") if @root
end
- CONFIG_REGEX = %r{ # rubocop:disable Style/RegexpLiteral
- ^
- (BUNDLE_.+):\s # the key
- (?: !\s)? # optional exclamation mark found with ruby 1.9.3
- (['"]?) # optional opening quote
- (.* # contents of the value
- (?: # optionally, up until the next key
- (\n(?!BUNDLE).+)*
- )
- )
- \2 # matching closing quote
- $
- }xo
-
def load_config(config_file)
return {} if !config_file || ignore_config?
SharedHelpers.filesystem_access(config_file, :read) do |file|
valid_file = file.exist? && !file.size.zero?
return {} unless valid_file
- require "bundler/yaml_serializer"
- YAMLSerializer.load file.read
+ require_relative "yaml_serializer"
+ YAMLSerializer.load(file.read).inject({}) do |config, (k, v)|
+ new_k = k
+
+ if k.include?("-")
+ Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
+ "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
+ "Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
+
+ new_k = k.gsub("-", "___")
+ end
+
+ config[new_k] = v
+ config
+ end
end
end
+ PER_URI_OPTIONS = %w[
+ fallback_timeout
+ ].freeze
+
+ NORMALIZE_URI_OPTIONS_PATTERN =
+ /
+ \A
+ (\w+\.)? # optional prefix key
+ (https?.*?) # URI
+ (\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key
+ \z
+ /ix.freeze
+
+ def self.key_for(key)
+ key = normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
+ key = key.to_s.gsub(".", "__").gsub("-", "___").upcase
+ "BUNDLE_#{key}"
+ end
+
# TODO: duplicates Rubygems#normalize_uri
# TODO: is this the correct place to validate mirror URIs?
def self.normalize_uri(uri)
uri = uri.to_s
- uri = "#{uri}/" unless uri =~ %r{/\Z}
- uri = URI(uri)
+ if uri =~ NORMALIZE_URI_OPTIONS_PATTERN
+ prefix = $1
+ uri = $2
+ suffix = $3
+ end
+ uri = "#{uri}/" unless uri.end_with?("/")
+ require_relative "vendored_uri"
+ uri = Bundler::URI(uri)
unless uri.absolute?
raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri)
end
- uri
+ "#{prefix}#{uri}#{suffix}"
end
end
end
diff --git a/lib/bundler/settings/validator.rb b/lib/bundler/settings/validator.rb
new file mode 100644
index 0000000000..0a57ea7f03
--- /dev/null
+++ b/lib/bundler/settings/validator.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+module Bundler
+ class Settings
+ class Validator
+ class Rule
+ attr_reader :description
+
+ def initialize(keys, description, &validate)
+ @keys = keys
+ @description = description
+ @validate = validate
+ end
+
+ def validate!(key, value, settings)
+ instance_exec(key, value, settings, &@validate)
+ end
+
+ def fail!(key, value, *reasons)
+ reasons.unshift @description
+ raise InvalidOption, "Setting `#{key}` to #{value.inspect} failed:\n#{reasons.map {|r| " - #{r}" }.join("\n")}"
+ end
+
+ def set(settings, key, value, *reasons)
+ hash_key = k(key)
+ return if settings[hash_key] == value
+ reasons.unshift @description
+ Bundler.ui.info "Setting `#{key}` to #{value.inspect}, since #{reasons.join(", ")}"
+ if value.nil?
+ settings.delete(hash_key)
+ else
+ settings[hash_key] = value
+ end
+ end
+
+ def k(key)
+ Bundler.settings.key_for(key)
+ end
+ end
+
+ def self.rules
+ @rules ||= Hash.new {|h, k| h[k] = [] }
+ end
+ private_class_method :rules
+
+ def self.rule(keys, description, &blk)
+ rule = Rule.new(keys, description, &blk)
+ keys.each {|k| rules[k] << rule }
+ end
+ private_class_method :rule
+
+ def self.validate!(key, value, settings)
+ rules_to_validate = rules[key]
+ rules_to_validate.each {|rule| rule.validate!(key, value, settings) }
+ end
+
+ rule %w[path path.system], "path and path.system are mutually exclusive" do |key, value, settings|
+ if key == "path" && value
+ set(settings, "path.system", nil)
+ elsif key == "path.system" && value
+ set(settings, :path, nil)
+ end
+ end
+
+ rule %w[with without], "a group cannot be in both `with` & `without` simultaneously" do |key, value, settings|
+ with = settings.fetch(k(:with), "").split(":").map(&:to_sym)
+ without = settings.fetch(k(:without), "").split(":").map(&:to_sym)
+
+ other_key = key == "with" ? :without : :with
+ other_setting = key == "with" ? without : with
+
+ conflicting = with & without
+ if conflicting.any?
+ fail!(key, value, "`#{other_key}` is current set to #{other_setting.inspect}", "the `#{conflicting.join("`, `")}` groups conflict")
+ end
+ end
+
+ rule %w[path], "relative paths are expanded relative to the current working directory" do |key, value, settings|
+ next if value.nil?
+
+ path = Pathname.new(value)
+ next if !path.relative? || !Bundler.feature_flag.path_relative_to_cwd?
+
+ path = path.expand_path
+
+ root = begin
+ Bundler.root
+ rescue GemfileNotFound
+ Pathname.pwd.expand_path
+ end
+
+ path = begin
+ path.relative_path_from(root)
+ rescue ArgumentError
+ path
+ end
+
+ set(settings, key, path.to_s)
+ end
+ end
+ end
+end
diff --git a/lib/bundler/setup.rb b/lib/bundler/setup.rb
index 9aae6478cd..32e9b2d7c0 100644
--- a/lib/bundler/setup.rb
+++ b/lib/bundler/setup.rb
@@ -1,27 +1,27 @@
# frozen_string_literal: true
-require "bundler/shared_helpers"
+
+require_relative "shared_helpers"
if Bundler::SharedHelpers.in_bundle?
- require "bundler"
+ require_relative "../bundler"
if STDOUT.tty? || ENV["BUNDLER_FORCE_TTY"]
begin
- Bundler.setup
+ Bundler.ui.silence { Bundler.setup }
rescue Bundler::BundlerError => e
- puts "\e[31m#{e.message}\e[0m"
- puts e.backtrace.join("\n") if ENV["DEBUG"]
+ Bundler.ui.error e.message
+ Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
if e.is_a?(Bundler::GemNotFound)
- puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
+ Bundler.ui.warn "Run `bundle install` to install missing gems."
end
exit e.status_code
end
else
- Bundler.setup
+ Bundler.ui.silence { Bundler.setup }
end
- # Add bundler to the load path after disabling system gems
- bundler_lib = File.expand_path("../..", __FILE__)
- $LOAD_PATH.unshift(bundler_lib) unless $LOAD_PATH.include?(bundler_lib)
-
- Bundler.ui = nil
+ # We might be in the middle of shelling out to rubygems
+ # (RUBYOPT=-rbundler/setup), so we need to give rubygems the opportunity of
+ # not being silent.
+ Gem::DefaultUserInteraction.ui = nil
end
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index a9141a1346..df1c136c56 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -1,28 +1,25 @@
# frozen_string_literal: true
+
require "pathname"
-require "rubygems"
-
-require "bundler/constants"
-require "bundler/rubygems_integration"
-require "bundler/current_ruby"
-
-module Gem
- class Dependency
- # This is only needed for RubyGems < 1.4
- unless method_defined? :requirement
- def requirement
- version_requirements
- end
- end
- end
-end
+require "rbconfig"
+
+require_relative "version"
+require_relative "constants"
+require_relative "rubygems_integration"
+require_relative "current_ruby"
module Bundler
module SharedHelpers
+ def root
+ gemfile = find_gemfile
+ raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
+ Pathname.new(gemfile).tap{|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path.parent
+ end
+
def default_gemfile
gemfile = find_gemfile
raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
- Pathname.new(gemfile).untaint
+ Pathname.new(gemfile).tap{|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path
end
def default_lockfile
@@ -31,7 +28,7 @@ module Bundler
case gemfile.basename.to_s
when "gems.rb" then Pathname.new(gemfile.sub(/.rb$/, ".locked"))
else Pathname.new("#{gemfile}.lock")
- end.untaint
+ end.tap{|x| x.untaint if RUBY_VERSION < "2.7" }
end
def default_bundle_dir
@@ -63,7 +60,7 @@ module Bundler
end
def with_clean_git_env(&block)
- keys = %w(GIT_DIR GIT_WORK_TREE)
+ keys = %w[GIT_DIR GIT_WORK_TREE]
old_env = keys.inject({}) do |h, k|
h.update(k => ENV[k])
end
@@ -103,9 +100,7 @@ module Bundler
#
# @see {Bundler::PermissionError}
def filesystem_access(path, action = :write, &block)
- # Use block.call instead of yield because of a bug in Ruby 2.2.2
- # See https://github.com/bundler/bundler/issues/5341 for details
- block.call(path.dup.untaint)
+ yield(path.dup.tap{|x| x.untaint if RUBY_VERSION < "2.7" })
rescue Errno::EACCES
raise PermissionError.new(path, action)
rescue Errno::EAGAIN
@@ -129,27 +124,32 @@ module Bundler
namespace.const_get(constant_name)
end
- def major_deprecation(message)
- return unless prints_major_deprecations?
- @major_deprecation_ui ||= Bundler::UI::Shell.new("no-color" => true)
- ui = Bundler.ui.is_a?(@major_deprecation_ui.class) ? Bundler.ui : @major_deprecation_ui
- ui.warn("[DEPRECATED FOR #{Bundler::VERSION.split(".").first.to_i + 1}.0] #{message}")
- end
+ def major_deprecation(major_version, message, print_caller_location: false)
+ if print_caller_location
+ caller_location = caller_locations(2, 2).first
+ message = "#{message} (called at #{caller_location.path}:#{caller_location.lineno})"
+ end
- def print_major_deprecations!
- deprecate_gemfile(find_gemfile) if find_gemfile == find_file("Gemfile")
- if RUBY_VERSION < "2"
- major_deprecation("Bundler will only support ruby >= 2.0, you are running #{RUBY_VERSION}")
+ bundler_major_version = Bundler.bundler_major_version
+ if bundler_major_version > major_version
+ require_relative "errors"
+ raise DeprecatedError, "[REMOVED] #{message}"
end
- return if Bundler.rubygems.provides?(">= 2")
- major_deprecation("Bundler will only support rubygems >= 2.0, you are running #{Bundler.rubygems.version}")
+
+ return unless bundler_major_version >= major_version && prints_major_deprecations?
+ Bundler.ui.warn("[DEPRECATED] #{message}")
end
- def trap(signal, override = false, &block)
- prior = Signal.trap(signal) do
- block.call
- prior.call unless override
+ def print_major_deprecations!
+ multiple_gemfiles = search_up(".") do |dir|
+ gemfiles = gemfile_names.select {|gf| File.file? File.expand_path(gf, dir) }
+ next if gemfiles.empty?
+ break gemfiles.size != 1
end
+ return unless multiple_gemfiles
+ message = "Multiple gemfiles (gems.rb and Gemfile) detected. " \
+ "Make sure you remove Gemfile and Gemfile.lock since bundler is ignoring them in favor of gems.rb and gems.rb.locked."
+ Bundler.ui.warn message
end
def ensure_same_dependencies(spec, old_deps, new_deps)
@@ -170,15 +170,51 @@ module Bundler
"\nEither installing with `--full-index` or running `bundle update #{spec.name}` should fix the problem."
end
- private
+ def pretty_dependency(dep, print_source = false)
+ msg = String.new(dep.name)
+ msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
+
+ if dep.is_a?(Bundler::Dependency)
+ platform_string = dep.platforms.join(", ")
+ msg << " " << platform_string if !platform_string.empty? && platform_string != Gem::Platform::RUBY
+ end
+
+ msg << " from the `#{dep.source}` source" if print_source && dep.source
+ msg
+ end
+
+ def md5_available?
+ return @md5_available if defined?(@md5_available)
+ @md5_available = begin
+ require "openssl"
+ ::OpenSSL::Digest.digest("MD5", "")
+ true
+ rescue LoadError
+ true
+ rescue ::OpenSSL::Digest::DigestError
+ false
+ end
+ end
+
+ def digest(name)
+ require "digest"
+ Digest(name)
+ end
+
+ def write_to_gemfile(gemfile_path, contents)
+ filesystem_access(gemfile_path) {|g| File.open(g, "w") {|file| file.puts contents } }
+ end
+
+ private
def validate_bundle_path
- return unless Bundler.bundle_path.to_s.include?(File::PATH_SEPARATOR)
- message = "Your bundle path contains a '#{File::PATH_SEPARATOR}', " \
+ path_separator = Bundler.rubygems.path_separator
+ return unless Bundler.bundle_path.to_s.split(path_separator).size > 1
+ message = "Your bundle path contains text matching #{path_separator.inspect}, " \
"which is the path separator for your system. Bundler cannot " \
"function correctly when the Bundle path contains the " \
"system's PATH separator. Please change your " \
- "bundle path to not include '#{File::PATH_SEPARATOR}'." \
+ "bundle path to not match #{path_separator.inspect}." \
"\nYour current bundle path is '#{Bundler.bundle_path}'."
raise Bundler::PathError, message
end
@@ -186,7 +222,11 @@ module Bundler
def find_gemfile
given = ENV["BUNDLE_GEMFILE"]
return given if given && !given.empty?
- find_file("Gemfile", "gems.rb")
+ find_file(*gemfile_names)
+ end
+
+ def gemfile_names
+ ["gems.rb", "Gemfile"]
end
def find_file(*names)
@@ -203,17 +243,19 @@ module Bundler
def search_up(*names)
previous = nil
- current = File.expand_path(SharedHelpers.pwd).untaint
+ current = File.expand_path(SharedHelpers.pwd).tap{|x| x.untaint if RUBY_VERSION < "2.7" }
until !File.directory?(current) || current == previous
if ENV["BUNDLE_SPEC_RUN"]
# avoid stepping above the tmp directory when testing
- if !!(ENV["BUNDLE_RUBY"] && ENV["BUNDLE_GEM"])
+ gemspec = if ENV["GEM_COMMAND"]
# for Ruby Core
- gemspec = "lib/bundler.gemspec"
+ "lib/bundler/bundler.gemspec"
else
- gemspec = "bundler.gemspec"
+ "bundler.gemspec"
end
+
+ # avoid stepping above the tmp directory when testing
return nil if File.file?(File.join(current, gemspec))
end
@@ -226,76 +268,83 @@ module Bundler
end
end
+ def set_env(key, value)
+ raise ArgumentError, "new key #{key}" unless EnvironmentPreserver::BUNDLER_KEYS.include?(key)
+ orig_key = "#{EnvironmentPreserver::BUNDLER_PREFIX}#{key}"
+ orig = ENV[key]
+ orig ||= EnvironmentPreserver::INTENTIONALLY_NIL
+ ENV[orig_key] ||= orig
+
+ ENV[key] = value
+ end
+ public :set_env
+
def set_bundle_variables
- begin
- ENV["BUNDLE_BIN_PATH"] = Bundler.rubygems.bin_path("bundler", "bundle", VERSION)
- rescue Gem::GemNotFoundException
- if File.exist?(File.expand_path("../../../exe/bundle", __FILE__))
- ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../exe/bundle", __FILE__)
- else
- ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../../bin/bundle", __FILE__)
- end
- end
+ # bundler exe & lib folders have same root folder, typical gem installation
+ exe_file = File.expand_path("../../../exe/bundle", __FILE__)
+
+ # for Ruby core repository testing
+ exe_file = File.expand_path("../../../libexec/bundle", __FILE__) unless File.exist?(exe_file)
- # Set BUNDLE_GEMFILE
- ENV["BUNDLE_GEMFILE"] = find_gemfile.to_s
- ENV["BUNDLER_VERSION"] = Bundler::VERSION
+ # bundler is a default gem, exe path is separate
+ exe_file = Bundler.rubygems.bin_path("bundler", "bundle", VERSION) unless File.exist?(exe_file)
+
+ Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s
+ Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
end
def set_path
validate_bundle_path
paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR)
paths.unshift "#{Bundler.bundle_path}/bin"
- ENV["PATH"] = paths.uniq.join(File::PATH_SEPARATOR)
+ Bundler::SharedHelpers.set_env "PATH", paths.uniq.join(File::PATH_SEPARATOR)
end
def set_rubyopt
rubyopt = [ENV["RUBYOPT"]].compact
- return if !rubyopt.empty? && rubyopt.first =~ %r{-rbundler/setup}
- rubyopt.unshift %(-rbundler/setup)
- ENV["RUBYOPT"] = rubyopt.join(" ")
+ setup_require = "-r#{File.expand_path("setup", __dir__)}"
+ return if !rubyopt.empty? && rubyopt.first =~ /#{setup_require}/
+ rubyopt.unshift setup_require
+ Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ")
end
def set_rubylib
rubylib = (ENV["RUBYLIB"] || "").split(File::PATH_SEPARATOR)
- rubylib.unshift bundler_ruby_lib
- ENV["RUBYLIB"] = rubylib.uniq.join(File::PATH_SEPARATOR)
+ rubylib.unshift bundler_ruby_lib unless RbConfig::CONFIG["rubylibdir"] == bundler_ruby_lib
+ Bundler::SharedHelpers.set_env "RUBYLIB", rubylib.uniq.join(File::PATH_SEPARATOR)
end
def bundler_ruby_lib
- File.expand_path("../..", __FILE__)
+ resolve_path File.expand_path("../..", __FILE__)
end
def clean_load_path
- # handle 1.9 where system gems are always on the load path
- return unless defined?(::Gem)
-
- bundler_lib = bundler_ruby_lib
-
loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
$LOAD_PATH.reject! do |p|
- next if File.expand_path(p).start_with?(bundler_lib)
+ resolved_path = resolve_path(p)
+ next if $LOADED_FEATURES.any? {|lf| lf.start_with?(resolved_path) }
loaded_gem_paths.delete(p)
end
$LOAD_PATH.uniq!
end
+ def resolve_path(path)
+ expanded = File.expand_path(path)
+ return expanded unless File.respond_to?(:realpath) && File.exist?(expanded)
+
+ File.realpath(expanded)
+ end
+
def prints_major_deprecations?
- require "bundler"
- deprecation_release = Bundler::VERSION.split(".").drop(1).include?("99")
- return false if !deprecation_release && !Bundler.settings[:major_deprecations]
- require "bundler/deprecate"
+ require_relative "../bundler"
+ return false if Bundler.settings[:silence_deprecations]
+ require_relative "deprecate"
return false if Bundler::Deprecate.skip
true
end
- def deprecate_gemfile(gemfile)
- return unless gemfile && File.basename(gemfile) == "Gemfile"
- Bundler::SharedHelpers.major_deprecation \
- "gems.rb and gems.locked will be preferred to Gemfile and Gemfile.lock."
- end
-
extend self
end
end
diff --git a/lib/bundler/similarity_detector.rb b/lib/bundler/similarity_detector.rb
index e9c1413ea3..50e66b9cab 100644
--- a/lib/bundler/similarity_detector.rb
+++ b/lib/bundler/similarity_detector.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class SimilarityDetector
SimilarityScore = Struct.new(:string, :distance)
@@ -25,9 +26,9 @@ module Bundler
end
end
- protected
+ protected
- # http://www.informit.com/articles/article.aspx?p=683059&seqNum=36
+ # https://www.informit.com/articles/article.aspx?p=683059&seqNum=36
def levenshtein_distance(this, that, ins = 2, del = 2, sub = 1)
# ins, del, sub are weighted costs
return nil if this.nil?
@@ -50,7 +51,7 @@ module Bundler
dm[i][j] = [
dm[i - 1][j - 1] + (this[j - 1] == that[i - 1] ? 0 : sub),
dm[i][j - 1] + ins,
- dm[i - 1][j] + del
+ dm[i - 1][j] + del,
].min
end
end
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index cf56ed1cc1..2a2b332cff 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -1,10 +1,13 @@
# frozen_string_literal: true
+
module Bundler
class Source
- autoload :Gemspec, "bundler/source/gemspec"
- autoload :Git, "bundler/source/git"
- autoload :Path, "bundler/source/path"
- autoload :Rubygems, "bundler/source/rubygems"
+ autoload :Gemspec, File.expand_path("source/gemspec", __dir__)
+ autoload :Git, File.expand_path("source/git", __dir__)
+ autoload :Metadata, File.expand_path("source/metadata", __dir__)
+ autoload :Path, File.expand_path("source/path", __dir__)
+ autoload :Rubygems, File.expand_path("source/rubygems", __dir__)
+ autoload :RubygemsAggregate, File.expand_path("source/rubygems_aggregate", __dir__)
attr_accessor :dependency_names
@@ -31,6 +34,31 @@ module Bundler
spec.source == self
end
+ def local!; end
+
+ def local_only!; end
+
+ def cached!; end
+
+ def remote!; end
+
+ def add_dependency_names(names)
+ @dependency_names = Array(dependency_names) | Array(names)
+ end
+
+ # it's possible that gems from one source depend on gems from some
+ # other source, so now we download gemspecs and iterate over those
+ # dependencies, looking for gems we don't have info on yet.
+ def double_check_for(*); end
+
+ def dependency_names_to_double_check
+ specs.dependency_names
+ end
+
+ def spec_names
+ specs.spec_names
+ end
+
def include?(other)
other == self
end
@@ -39,7 +67,24 @@ module Bundler
"#<#{self.class}:0x#{object_id} #{self}>"
end
- private
+ def identifier
+ to_s
+ end
+
+ def path?
+ instance_of?(Bundler::Source::Path)
+ end
+
+ def extension_cache_path(spec)
+ return unless Bundler.feature_flag.global_gem_cache?
+ return unless source_slug = extension_cache_slug(spec)
+ Bundler.user_cache.join(
+ "extensions", Gem::Platform.local.to_s, Bundler.ruby_scope,
+ source_slug, spec.full_name
+ )
+ end
+
+ private
def version_color(spec_version, locked_spec_version)
if Gem::Version.correct?(spec_version) && Gem::Version.correct?(locked_spec_version)
@@ -54,5 +99,17 @@ module Bundler
def earlier_version?(spec_version, locked_spec_version)
Gem::Version.new(spec_version) < Gem::Version.new(locked_spec_version)
end
+
+ def print_using_message(message)
+ if !message.include?("(was ") && Bundler.feature_flag.suppress_install_using_messages?
+ Bundler.ui.debug message
+ else
+ Bundler.ui.info message
+ end
+ end
+
+ def extension_cache_slug(_)
+ nil
+ end
end
end
diff --git a/lib/bundler/source/gemspec.rb b/lib/bundler/source/gemspec.rb
index 05e613277f..7e3447e776 100644
--- a/lib/bundler/source/gemspec.rb
+++ b/lib/bundler/source/gemspec.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class Source
class Gemspec < Path
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
index b3e218e390..a41a2f23e9 100644
--- a/lib/bundler/source/git.rb
+++ b/lib/bundler/source/git.rb
@@ -1,14 +1,13 @@
# frozen_string_literal: true
-require "fileutils"
-require "uri"
-require "digest/sha1"
+
+require_relative "../vendored_fileutils"
module Bundler
class Source
class Git < Path
- autoload :GitProxy, "bundler/source/git/git_proxy"
+ autoload :GitProxy, File.expand_path("git/git_proxy", __dir__)
- attr_reader :uri, :ref, :branch, :options, :submodules
+ attr_reader :uri, :ref, :branch, :options, :glob, :submodules
def initialize(options)
@options = options
@@ -18,11 +17,12 @@ module Bundler
@allow_remote = false
# Stringify options that could be set as symbols
- %w(ref branch tag revision).each {|k| options[k] = options[k].to_s if options[k] }
+ %w[ref branch tag revision].each {|k| options[k] = options[k].to_s if options[k] }
@uri = options["uri"] || ""
+ @safe_uri = URICredentialsFilter.credential_filtered_uri(@uri)
@branch = options["branch"]
- @ref = options["ref"] || options["branch"] || options["tag"] || "master"
+ @ref = options["ref"] || options["branch"] || options["tag"]
@submodules = options["submodules"]
@name = options["name"]
@version = options["version"].to_s.strip.gsub("-", ".pre.")
@@ -39,45 +39,56 @@ module Bundler
out = String.new("GIT\n")
out << " remote: #{@uri}\n"
out << " revision: #{revision}\n"
- %w(ref branch tag submodules).each do |opt|
+ %w[ref branch tag submodules].each do |opt|
out << " #{opt}: #{options[opt]}\n" if options[opt]
end
- out << " glob: #{@glob}\n" unless @glob == DEFAULT_GLOB
+ out << " glob: #{@glob}\n" unless default_glob?
out << " specs:\n"
end
def hash
- [self.class, uri, ref, branch, name, version, submodules].hash
+ [self.class, uri, ref, branch, name, version, glob, submodules].hash
end
def eql?(other)
other.is_a?(Git) && uri == other.uri && ref == other.ref &&
branch == other.branch && name == other.name &&
- version == other.version && submodules == other.submodules
+ version == other.version && glob == other.glob &&
+ submodules == other.submodules
end
alias_method :==, :eql?
def to_s
- at = if local?
- path
- elsif user_ref = options["ref"]
- if ref =~ /\A[a-z0-9]{4,}\z/i
- shortref_for_display(user_ref)
+ begin
+ at = if local?
+ path
+ elsif user_ref = options["ref"]
+ if ref =~ /\A[a-z0-9]{4,}\z/i
+ shortref_for_display(user_ref)
+ else
+ user_ref
+ end
+ elsif ref
+ ref
else
- user_ref
+ git_proxy.branch
end
- else
- ref
+
+ rev = "at #{at}@#{shortref_for_display(revision)}"
+ rescue GitError
+ ""
end
- rev = begin
- "@#{shortref_for_display(revision)}"
- rescue GitError
- nil
- end
+ specifiers = [rev, glob_for_display].compact
+ suffix =
+ if specifiers.any?
+ " (#{specifiers.join(", ")})"
+ else
+ ""
+ end
- "#{uri} (at #{at}#{rev})"
+ "#{@safe_uri}#{suffix}"
end
def name
@@ -117,18 +128,19 @@ module Bundler
def local_override!(path)
return false if local?
+ original_path = path
path = Pathname.new(path)
path = path.expand_path(Bundler.root) unless path.relative?
unless options["branch"] || Bundler.settings[:disable_local_branch_check]
raise GitError, "Cannot use local override for #{name} at #{path} because " \
- ":branch is not specified in Gemfile. Specify a branch or use " \
- "`bundle config --delete` to remove the local override"
+ ":branch is not specified in Gemfile. Specify a branch or run " \
+ "`bundle config unset local.#{override_for(original_path)}` to remove the local override"
end
unless path.exist?
raise GitError, "Cannot use local override for #{name} because #{path} " \
- "does not exist. Check `bundle config --delete` to remove the local override"
+ "does not exist. Run `bundle config unset local.#{override_for(original_path)}` to remove the local override"
end
set_local!(path)
@@ -144,7 +156,7 @@ module Bundler
changed = cached_revision && cached_revision != git_proxy.revision
- if changed && !@unlocked && !git_proxy.contains?(cached_revision)
+ if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(cached_revision)
raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \
"but the current branch in your local override for #{name} does not contain such commit. " \
"Please make sure your branch is up to date."
@@ -169,15 +181,13 @@ module Bundler
def install(spec, options = {})
force = options[:force]
- Bundler.ui.info "Using #{version_message(spec)} from #{self}"
+ print_using_message "Using #{version_message(spec)} from #{self}"
- if requires_checkout? && !@copied && !force
+ if (requires_checkout? && !@copied) || force
Bundler.ui.debug " * Checking out revision: #{ref}"
git_proxy.copy_to(install_path, submodules)
serialize_gemspecs_in(install_path)
@copied = true
- elsif force
- git_proxy.copy_to(install_path, submodules)
end
generate_bin_options = { :disable_extensions => !Bundler.rubygems.spec_missing_extensions?(spec), :build_args => options[:build_args] }
@@ -188,7 +198,7 @@ module Bundler
def cache(spec, custom_path = nil)
app_cache_path = app_cache_path(custom_path)
- return unless Bundler.settings[:cache_all]
+ return unless Bundler.feature_flag.cache_all?
return if path == app_cache_path
cached!
FileUtils.rm_rf(app_cache_path)
@@ -210,13 +220,11 @@ module Bundler
# When using local git repos, this is set to the local repo.
def cache_path
@cache_path ||= begin
- git_scope = "#{base_name}-#{uri_hash}"
-
- if Bundler.requires_sudo?
- Bundler.user_bundle_path.join("cache/git", git_scope)
+ if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache?
+ Bundler.user_cache
else
- Bundler.cache.join("git", git_scope)
- end
+ Bundler.bundle_path.join("cache", "bundler")
+ end.join("git", git_scope)
end
end
@@ -232,7 +240,11 @@ module Bundler
@allow_remote || @allow_cached
end
- private
+ def local?
+ @local
+ end
+
+ private
def serialize_gemspecs_in(destination)
destination = destination.expand_path(Bundler.root) if destination.relative?
@@ -258,12 +270,12 @@ module Bundler
cached_revision && super
end
- def local?
- @local
+ def requires_checkout?
+ allow_git_ops? && !local? && !cached_revision_checked_out?
end
- def requires_checkout?
- allow_git_ops? && !local?
+ def cached_revision_checked_out?
+ cached_revision && cached_revision == revision && install_path.exist?
end
def base_name
@@ -278,16 +290,26 @@ module Bundler
ref[0..11]
end
+ def glob_for_display
+ default_glob? ? nil : "glob: #{@glob}"
+ end
+
+ def default_glob?
+ @glob == DEFAULT_GLOB
+ end
+
def uri_hash
if uri =~ %r{^\w+://(\w+@)?}
# Downcase the domain component of the URI
# and strip off a trailing slash, if one is present
- input = URI.parse(uri).normalize.to_s.sub(%r{/$}, "")
+ input = Bundler::URI.parse(uri).normalize.to_s.sub(%r{/$}, "")
else
# If there is no URI scheme, assume it is an ssh/git URI
input = uri
end
- Digest::SHA1.hexdigest(input)
+ # We use SHA1 here for historical reason and to preserve backward compatibility.
+ # But a transition to a simpler mangling algorithm would be welcome.
+ Bundler::Digest.sha1(input)
end
def cached_revision
@@ -304,20 +326,30 @@ module Bundler
def fetch
git_proxy.checkout
- rescue GitError
+ rescue GitError => e
raise unless Bundler.feature_flag.allow_offline_install?
- Bundler.ui.warn "Using cached git data because of network errors"
+ Bundler.ui.warn "Using cached git data because of network errors:\n#{e}"
end
# no-op, since we validate when re-serializing the gemspec
def validate_spec(_spec); end
- if Bundler.rubygems.stubs_provide_full_functionality?
- def load_gemspec(file)
- stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
- stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s.untaint
- StubSpecification.from_stub(stub)
- end
+ def load_gemspec(file)
+ stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
+ stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s.tap{|x| x.untaint if RUBY_VERSION < "2.7" }
+ StubSpecification.from_stub(stub)
+ end
+
+ def git_scope
+ "#{base_name}-#{uri_hash}"
+ end
+
+ def extension_cache_slug(_)
+ extension_dir_name
+ end
+
+ def override_for(path)
+ Bundler.settings.local_overrides.key(path)
end
end
end
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb
index c05d7a5afa..745a7fe118 100644
--- a/lib/bundler/source/git/git_proxy.rb
+++ b/lib/bundler/source/git/git_proxy.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require "shellwords"
-require "tempfile"
+
module Bundler
class Source
class Git
@@ -16,27 +15,31 @@ module Bundler
class GitNotAllowedError < GitError
def initialize(command)
msg = String.new
- msg << "Bundler is trying to run a `git #{command}` at runtime. You probably need to run `bundle install`. However, "
- msg << "this error message could probably be more useful. Please submit a ticket at http://github.com/bundler/bundler/issues "
+ msg << "Bundler is trying to run `#{command}` at runtime. You probably need to run `bundle install`. However, "
+ msg << "this error message could probably be more useful. Please submit a ticket at https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md "
msg << "with steps to reproduce as well as the following\n\nCALLER: #{caller.join("\n")}"
super msg
end
end
class GitCommandError < GitError
- def initialize(command, path = nil, extra_info = nil)
+ attr_reader :command
+
+ def initialize(command, path, extra_info = nil)
+ @command = command
+
msg = String.new
- msg << "Git error: command `git #{command}` in directory #{SharedHelpers.pwd} has failed."
+ msg << "Git error: command `#{command}` in directory #{path} has failed."
msg << "\n#{extra_info}" if extra_info
- msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path && path.exist?
+ msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path.exist?
super msg
end
end
- class MissingGitRevisionError < GitError
- def initialize(ref, repo)
+ class MissingGitRevisionError < GitCommandError
+ def initialize(command, destination_path, ref, repo)
msg = "Revision #{ref} does not exist in the repository #{repo}. Maybe you misspelled it?"
- super msg
+ super command, destination_path, msg
end
end
@@ -53,31 +56,22 @@ module Bundler
@ref = ref
@revision = revision
@git = git
- raise GitNotInstalledError.new if allow? && !Bundler.git_present?
end
def revision
- return @revision if @revision
-
- begin
- @revision ||= find_local_revision
- rescue GitCommandError
- raise MissingGitRevisionError.new(ref, uri)
- end
-
- @revision
+ @revision ||= find_local_revision
end
def branch
- @branch ||= allowed_in_path do
- git("rev-parse --abbrev-ref HEAD").strip
+ @branch ||= allowed_with_path do
+ git("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip
end
end
def contains?(commit)
- allowed_in_path do
- result = git_null("branch --contains #{commit}")
- $? == 0 && result =~ /^\* (.*)$/
+ allowed_with_path do
+ result, status = git_null("branch", "--contains", commit, :dir => path)
+ status.success? && result =~ /^\* (.*)$/
end
end
@@ -90,18 +84,23 @@ module Bundler
end
def checkout
- if path.exist?
- return if has_revision_cached?
- Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}"
- in_path do
- git_retry %(fetch --force --quiet --tags #{uri_escaped_with_configured_credentials} "refs/heads/*:refs/heads/*")
- end
- else
- Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}"
+ return if path.exist? && has_revision_cached?
+ extra_ref = "#{ref}:#{ref}" if ref && ref.start_with?("refs/")
+
+ Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}"
+
+ configured_uri = configured_uri_for(uri).to_s
+
+ unless path.exist?
SharedHelpers.filesystem_access(path.dirname) do |p|
FileUtils.mkdir_p(p)
end
- git_retry %(clone #{uri_escaped_with_configured_credentials} "#{path}" --bare --no-hardlinks --quiet)
+ git_retry "clone", "--bare", "--no-hardlinks", "--quiet", "--", configured_uri, path.to_s
+ return unless extra_ref
+ end
+
+ with_path do
+ git_retry(*["fetch", "--force", "--quiet", "--tags", "--", configured_uri, "refs/heads/*:refs/heads/*", extra_ref].compact, :dir => path)
end
end
@@ -115,61 +114,69 @@ module Bundler
SharedHelpers.filesystem_access(destination) do |p|
FileUtils.rm_rf(p)
end
- git_retry %(clone --no-checkout --quiet "#{path}" "#{destination}")
+ git_retry "clone", "--no-checkout", "--quiet", path.to_s, destination.to_s
File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination)
rescue Errno::EEXIST => e
- file_path = e.message[%r{.*?(/.*)}, 1]
+ file_path = e.message[%r{.*?((?:[a-zA-Z]:)?/.*)}, 1]
raise GitError, "Bundler could not install a gem because it needs to " \
"create a directory, but a file exists - #{file_path}. Please delete " \
"this file and try again."
end
end
# method 2
- SharedHelpers.chdir(destination) do
- git_retry %(fetch --force --quiet --tags "#{path}")
- git "reset --hard #{@revision}"
-
- if submodules
- git_retry "submodule update --init --recursive"
- elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0")
- git_retry "submodule deinit --all --force"
- end
+ git_retry "fetch", "--force", "--quiet", "--tags", path.to_s, :dir => destination
+
+ begin
+ git "reset", "--hard", @revision, :dir => destination
+ rescue GitCommandError => e
+ raise MissingGitRevisionError.new(e.command, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri))
+ end
+
+ if submodules
+ git_retry "submodule", "update", "--init", "--recursive", :dir => destination
+ elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0")
+ inner_command = "git -C $toplevel submodule deinit --force $sm_path"
+ git_retry "submodule", "foreach", "--quiet", inner_command, :dir => destination
end
end
- private
+ private
+
+ def git_null(*command, dir: nil)
+ check_allowed(command)
+
+ out, status = SharedHelpers.with_clean_git_env do
+ capture_and_ignore_stderr(*capture3_args_for(command, dir))
+ end
- # TODO: Do not rely on /dev/null.
- # Given that open3 is not cross platform until Ruby 1.9.3,
- # the best solution is to pipe to /dev/null if it exists.
- # If it doesn't, everything will work fine, but the user
- # will get the $stderr messages as well.
- def git_null(command)
- git("#{command} 2>#{Bundler::NULL}", false)
+ [URICredentialsFilter.credential_filtered_string(out, uri), status]
end
- def git_retry(command)
- Bundler::Retry.new("`git #{command}`", GitNotAllowedError).attempts do
- git(command)
+ def git_retry(*command, dir: nil)
+ command_with_no_credentials = check_allowed(command)
+
+ Bundler::Retry.new("`#{command_with_no_credentials}` at #{dir || SharedHelpers.pwd}").attempts do
+ git(*command, :dir => dir)
end
end
- def git(command, check_errors = true, error_msg = nil)
- command_with_no_credentials = URICredentialsFilter.credential_filtered_string(command, uri)
- raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
+ def git(*command, dir: nil)
+ command_with_no_credentials = check_allowed(command)
- out = SharedHelpers.with_clean_git_env do
- capture_and_filter_stderr(uri) { `git #{command}` }
+ out, status = SharedHelpers.with_clean_git_env do
+ capture_and_filter_stderr(*capture3_args_for(command, dir))
end
- stdout_with_no_credentials = URICredentialsFilter.credential_filtered_string(out, uri)
- raise GitCommandError.new(command_with_no_credentials, path, error_msg) if check_errors && !$?.success?
- stdout_with_no_credentials
+ filtered_out = URICredentialsFilter.credential_filtered_string(out, uri)
+
+ raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, filtered_out) unless status.success?
+
+ filtered_out
end
def has_revision_cached?
return unless @revision
- in_path { git("cat-file -e #{@revision}") }
+ with_path { git("cat-file", "-e", @revision, :dir => path) }
true
rescue GitError
false
@@ -180,29 +187,17 @@ module Bundler
end
def find_local_revision
- allowed_in_path do
- git("rev-parse --verify #{Shellwords.shellescape(ref)}", true).strip
- end
- end
-
- # Escape the URI for git commands
- def uri_escaped_with_configured_credentials
- remote = configured_uri_for(uri)
- if Bundler::WINDOWS
- # Windows quoting requires double quotes only, with double quotes
- # inside the string escaped by being doubled.
- '"' + remote.gsub('"') { '""' } + '"'
- else
- # Bash requires single quoted strings, with the single quotes escaped
- # by ending the string, escaping the quote, and restarting the string.
- "'" + remote.gsub("'") { "'\\''" } + "'"
+ allowed_with_path do
+ git("rev-parse", "--verify", ref || "HEAD", :dir => path).strip
end
+ rescue GitCommandError => e
+ raise MissingGitRevisionError.new(e.command, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
end
# Adds credentials to the URI as Fetcher#configured_uri_for does
def configured_uri_for(uri)
if /https?:/ =~ uri
- remote = URI(uri)
+ remote = Bundler::URI(uri)
config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
remote.userinfo ||= config_auth
remote.to_s
@@ -212,39 +207,55 @@ module Bundler
end
def allow?
- @git ? @git.allow_git_ops? : true
+ allowed = @git ? @git.allow_git_ops? : true
+
+ raise GitNotInstalledError.new if allowed && !Bundler.git_present?
+
+ allowed
end
- def in_path(&blk)
+ def with_path(&blk)
checkout unless path.exist?
- SharedHelpers.chdir(path, &blk)
+ blk.call
end
- def allowed_in_path
- return in_path { yield } if allow?
+ def allowed_with_path
+ return with_path { yield } if allow?
raise GitError, "The git source #{uri} is not yet checked out. Please run `bundle install` before trying to start your application"
end
- # TODO: Replace this with Open3 when upgrading to bundler 2
- # Similar to #git_null, as Open3 is not cross-platform,
- # a temporary way is to use Tempfile to capture the stderr.
- # When replacing this using Open3, make sure git_null is
- # also replaced by Open3, so stdout and stderr all got handled properly.
- def capture_and_filter_stderr(uri)
- return_value, captured_err = ""
- backup_stderr = STDERR.dup
- begin
- Tempfile.open("captured_stderr") do |f|
- STDERR.reopen(f)
- return_value = yield
- f.rewind
- captured_err = f.read
- end
- ensure
- STDERR.reopen backup_stderr
+ def check_allowed(command)
+ require "shellwords"
+ command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
+ raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
+ command_with_no_credentials
+ end
+
+ def capture_and_filter_stderr(*cmd)
+ require "open3"
+ return_value, captured_err, status = Open3.capture3(*cmd)
+ Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) unless captured_err.empty?
+ [return_value, status]
+ end
+
+ def capture_and_ignore_stderr(*cmd)
+ require "open3"
+ return_value, _, status = Open3.capture3(*cmd)
+ [return_value, status]
+ end
+
+ def capture3_args_for(cmd, dir)
+ return ["git", *cmd] unless dir
+
+ if Bundler.feature_flag.bundler_3_mode? || supports_minus_c?
+ ["git", "-C", dir.to_s, *cmd]
+ else
+ ["git", *cmd, { :chdir => dir.to_s }]
end
- $stderr.puts URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
- return_value
+ end
+
+ def supports_minus_c?
+ @supports_minus_c ||= Gem::Version.new(version) >= Gem::Version.new("1.8.5")
end
end
end
diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb
new file mode 100644
index 0000000000..50b65ce0ea
--- /dev/null
+++ b/lib/bundler/source/metadata.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Bundler
+ class Source
+ class Metadata < Source
+ def specs
+ @specs ||= Index.build do |idx|
+ idx << Gem::Specification.new("Ruby\0", RubyVersion.system.to_gem_version_with_patchlevel)
+ idx << Gem::Specification.new("RubyGems\0", Gem::VERSION) do |s|
+ s.required_rubygems_version = Gem::Requirement.default
+ end
+
+ idx << Gem::Specification.new do |s|
+ s.name = "bundler"
+ s.version = VERSION
+ s.license = "MIT"
+ s.platform = Gem::Platform::RUBY
+ s.source = self
+ s.authors = ["bundler team"]
+ s.bindir = "exe"
+ s.homepage = "https://bundler.io"
+ s.summary = "The best way to manage your application's dependencies"
+ s.executables = %w[bundle]
+ # can't point to the actual gemspec or else the require paths will be wrong
+ s.loaded_from = File.expand_path("..", __FILE__)
+ end
+
+ if local_spec = Bundler.rubygems.find_name("bundler").find {|s| s.version.to_s == VERSION }
+ idx << local_spec
+ end
+
+ idx.each {|s| s.source = self }
+ end
+ end
+
+ def options
+ {}
+ end
+
+ def install(spec, _opts = {})
+ print_using_message "Using #{version_message(spec)}"
+ nil
+ end
+
+ def to_s
+ "the local ruby installation"
+ end
+
+ def ==(other)
+ self.class == other.class
+ end
+ alias_method :eql?, :==
+
+ def hash
+ self.class.hash
+ end
+
+ def version_message(spec)
+ "#{spec.name} #{spec.version}"
+ end
+ end
+ end
+end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 8dd0763cc1..01f89b204d 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: true
+
module Bundler
class Source
class Path < Source
- autoload :Installer, "bundler/source/path/installer"
+ autoload :Installer, File.expand_path("path/installer", __dir__)
attr_reader :path, :options, :root_path, :original_path
attr_writer :name
@@ -19,11 +20,16 @@ module Bundler
@allow_cached = false
@allow_remote = false
- @root_path = options["root_path"] || Bundler.root
+ @root_path = options["root_path"] || root
if options["path"]
@path = Pathname.new(options["path"])
- @path = expand(@path) unless @path.relative?
+ expanded_path = expand(@path)
+ @path = if @path.relative?
+ expanded_path.relative_path_from(root_path.expand_path)
+ else
+ expanded_path
+ end
end
@name = options["name"]
@@ -35,10 +41,12 @@ module Bundler
end
def remote!
+ @local_specs = nil
@allow_remote = true
end
def cached!
+ @local_specs = nil
@allow_cached = true
end
@@ -74,14 +82,16 @@ module Bundler
end
def install(spec, options = {})
- Bundler.ui.info "Using #{version_message(spec)} from #{self}"
+ using_message = "Using #{version_message(spec)} from #{self}"
+ using_message += " and installing its executables" unless spec.executables.empty?
+ print_using_message using_message
generate_bin(spec, :disable_extensions => true)
nil # no post-install message
end
def cache(spec, custom_path = nil)
app_cache_path = app_cache_path(custom_path)
- return unless Bundler.settings[:cache_all]
+ return unless Bundler.feature_flag.cache_all?
return if expand(@original_path).to_s.index(root_path.to_s + "/") == 0
unless @original_path.exist?
@@ -113,22 +123,22 @@ module Bundler
Bundler.root
end
- def is_a_path?
- instance_of?(Path)
- end
-
def expanded_original_path
@expanded_original_path ||= expand(original_path)
end
- private
+ private
def expanded_path
@expanded_path ||= expand(path)
end
def expand(somepath)
- somepath.expand_path(root_path)
+ if Bundler.current_ruby.jruby? # TODO: Unify when https://github.com/rubygems/bundler/issues/7598 fixed upstream and all supported jrubies include the fix
+ somepath.expand_path(root_path).expand_path
+ else
+ somepath.expand_path(root_path)
+ end
rescue ArgumentError => e
Bundler.ui.debug(e)
raise PathError, "There was an error while trying to use the path " \
@@ -137,7 +147,7 @@ module Bundler
def lockfile_path
return relative_path(original_path) if original_path.absolute?
- expand(original_path).relative_path_from(Bundler.root)
+ expand(original_path).relative_path_from(root)
end
def app_cache_path(custom_path = nil)
@@ -163,7 +173,7 @@ module Bundler
if File.directory?(expanded_path)
# We sort depth-first since `<<` will override the earlier-found specs
- Dir["#{expanded_path}/#{@glob}"].sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
+ Gem::Util.glob_files_in_dir(@glob, expanded_path).sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
next unless spec = load_gemspec(file)
spec.source = self
@@ -192,10 +202,10 @@ module Bundler
else
message = String.new("The path `#{expanded_path}` ")
message << if File.exist?(expanded_path)
- "is not a directory."
- else
- "does not exist."
- end
+ "is not a directory."
+ else
+ "does not exist."
+ end
raise PathError, message
end
@@ -228,7 +238,8 @@ module Bundler
spec,
:env_shebang => false,
:disable_extensions => options[:disable_extensions],
- :build_args => options[:build_args]
+ :build_args => options[:build_args],
+ :bundler_extension_cache_path => extension_cache_path(spec)
)
installer.post_install
rescue Gem::InvalidSpecificationException => e
@@ -242,7 +253,7 @@ module Bundler
"to modify their .gemspec so it can work with `gem build`."
end
- Bundler.ui.warn "The validation message from Rubygems was:\n #{e.message}"
+ Bundler.ui.warn "The validation message from RubyGems was:\n #{e.message}"
end
end
end
diff --git a/lib/bundler/source/path/installer.rb b/lib/bundler/source/path/installer.rb
index 9c2f74a31b..a70973bde7 100644
--- a/lib/bundler/source/path/installer.rb
+++ b/lib/bundler/source/path/installer.rb
@@ -1,4 +1,7 @@
# frozen_string_literal: true
+
+require_relative "../../rubygems_gem_installer"
+
module Bundler
class Source
class Path
@@ -6,6 +9,7 @@ module Bundler
attr_reader :spec
def initialize(spec, options = {})
+ @options = options
@spec = spec
@gem_dir = Bundler.rubygems.path(spec.full_gem_path)
@wrappers = true
@@ -24,23 +28,21 @@ module Bundler
end
def post_install
- SharedHelpers.chdir(@gem_dir) do
- run_hooks(:pre_install)
+ run_hooks(:pre_install)
- unless @disable_extensions
- build_extensions
- run_hooks(:post_build)
- end
+ unless @disable_extensions
+ build_extensions
+ run_hooks(:post_build)
+ end
- generate_bin unless spec.executables.nil? || spec.executables.empty?
+ generate_bin unless spec.executables.empty?
- run_hooks(:post_install)
- end
+ run_hooks(:post_install)
ensure
Bundler.rm_rf(@tmp_dir) if Bundler.requires_sudo?
end
- private
+ private
def generate_bin
super
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 353194f53f..8bc3aa17e9 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-require "uri"
+
require "rubygems/user_interaction"
module Bundler
class Source
class Rubygems < Source
- autoload :Remote, "bundler/source/rubygems/remote"
+ autoload :Remote, File.expand_path("rubygems/remote", __dir__)
# Use the API when installing less than X gems
API_REQUEST_LIMIT = 500
@@ -20,17 +20,38 @@ module Bundler
@dependency_names = []
@allow_remote = false
@allow_cached = false
+ @allow_local = options["allow_local"] || false
@caches = [cache_path, *Bundler.rubygems.gem_cache]
- Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
+ Array(options["remotes"]).reverse_each {|r| add_remote(r) }
+ end
+
+ def local_only!
+ @specs = nil
+ @allow_local = true
+ @allow_cached = false
+ @allow_remote = false
+ end
+
+ def local!
+ return if @allow_local
+
+ @specs = nil
+ @allow_local = true
end
def remote!
+ return if @allow_remote
+
@specs = nil
@allow_remote = true
end
def cached!
+ return if @allow_cached
+
+ @specs = nil
+ @allow_local = true
@allow_cached = true
end
@@ -48,8 +69,17 @@ module Bundler
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
end
+ def multiple_remotes?
+ @remotes.size > 1
+ end
+
+ def no_remotes?
+ @remotes.size == 0
+ end
+
def can_lock?(spec)
- spec.source.is_a?(Rubygems)
+ return super unless multiple_remotes?
+ include?(spec.source)
end
def options
@@ -69,10 +99,29 @@ module Bundler
end
def to_s
- remote_names = remotes.map(&:to_s).join(", ")
- "rubygems repository #{remote_names}"
+ if remotes.empty?
+ "locally installed gems"
+ elsif @allow_remote && @allow_cached && @allow_local
+ "rubygems repository #{remote_names}, cached gems or installed locally"
+ elsif @allow_remote && @allow_local
+ "rubygems repository #{remote_names} or installed locally"
+ elsif @allow_remote
+ "rubygems repository #{remote_names}"
+ elsif @allow_cached && @allow_local
+ "cached gems or installed locally"
+ else
+ "locally installed gems"
+ end
+ end
+
+ def identifier
+ if remotes.empty?
+ "locally installed gems"
+ else
+ "rubygems repository #{remote_names}"
+ end
end
- alias_method :name, :to_s
+ alias_method :name, :identifier
def specs
@specs ||= begin
@@ -81,7 +130,7 @@ module Bundler
# small_idx.use large_idx.
idx = @allow_remote ? remote_specs.dup : Index.new
idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
- idx.use(installed_specs, :override_dupes)
+ idx.use(installed_specs, :override_dupes) if @allow_local
idx
end
end
@@ -90,7 +139,7 @@ module Bundler
force = opts[:force]
ensure_builtin_gems_cached = opts[:ensure_builtin_gems_cached]
- if ensure_builtin_gems_cached && builtin_gem?(spec)
+ if ensure_builtin_gems_cached && spec.default_gem?
if !cached_path(spec)
cached_built_in_gem(spec) unless spec.remote
force = true
@@ -99,8 +148,8 @@ module Bundler
end
end
- if installed?(spec) && (!force || spec.name.eql?("bundler"))
- Bundler.ui.info "Using #{version_message(spec)}"
+ if installed?(spec) && !force
+ print_using_message "Using #{version_message(spec)}"
return nil # no post-install message
end
@@ -113,8 +162,14 @@ module Bundler
uris.uniq!
Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
- s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
- spec.__swap__(s)
+ path = fetch_gem(spec)
+ begin
+ s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"])
+ spec.__swap__(s)
+ rescue Gem::Package::FormatError
+ Bundler.rm_rf(path)
+ raise
+ end
end
unless Bundler.settings[:no_install]
@@ -123,6 +178,7 @@ module Bundler
Bundler.ui.confirm message
path = cached_gem(spec)
+ raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path
if requires_sudo?
install_path = Bundler.tmp(spec.full_name)
bin_path = install_path.join("bin")
@@ -131,19 +187,21 @@ module Bundler
bin_path = Bundler.system_bindir
end
- installed_spec = nil
- Bundler.rubygems.preserve_paths do
- installed_spec = Bundler::RubyGemsGemInstaller.at(
- path,
- :install_dir => install_path.to_s,
- :bin_dir => bin_path.to_s,
- :ignore_dependencies => true,
- :wrappers => true,
- :env_shebang => true,
- :build_args => opts[:build_args],
- :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum
- ).install
- end
+ Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
+
+ require_relative "../rubygems_gem_installer"
+
+ installed_spec = Bundler::RubyGemsGemInstaller.at(
+ path,
+ :install_dir => install_path.to_s,
+ :bin_dir => bin_path.to_s,
+ :ignore_dependencies => true,
+ :wrappers => true,
+ :env_shebang => true,
+ :build_args => opts[:build_args],
+ :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
+ :bundler_extension_cache_path => extension_cache_path(spec)
+ ).install
spec.full_gem_path = installed_spec.full_gem_path
# SUDO HAX
@@ -180,12 +238,8 @@ module Bundler
end
def cache(spec, custom_path = nil)
- if builtin_gem?(spec)
- cached_path = cached_built_in_gem(spec)
- else
- cached_path = cached_gem(spec)
- end
- raise GemNotFound, "Missing gem file '#{spec.full_name}.gem'." unless cached_path
+ cached_path = cached_gem(spec)
+ raise GemNotFound, "Missing gem file '#{spec.file_name}'." unless cached_path
return if File.dirname(cached_path) == Bundler.app_cache.to_s
Bundler.ui.info " * #{File.basename(cached_path)}"
FileUtils.cp(cached_path, Bundler.app_cache(custom_path))
@@ -212,17 +266,16 @@ module Bundler
@remotes.unshift(uri) unless @remotes.include?(uri)
end
- def replace_remotes(other_remotes)
- return false if other_remotes == @remotes
-
- @remotes = []
- other_remotes.reverse_each do |r|
- add_remote r.to_s
+ def spec_names
+ if @allow_remote && dependency_api_available?
+ remote_specs.spec_names
+ else
+ []
end
end
def unmet_deps
- if @allow_remote && api_fetchers.any?
+ if @allow_remote && dependency_api_available?
remote_specs.unmet_dependency_names
else
[]
@@ -236,10 +289,56 @@ module Bundler
end
end
- protected
+ def double_check_for(unmet_dependency_names)
+ return unless @allow_remote
+ return unless dependency_api_available?
+
+ unmet_dependency_names = unmet_dependency_names.call
+ unless unmet_dependency_names.nil?
+ if api_fetchers.size <= 1
+ # can't do this when there are multiple fetchers because then we might not fetch from _all_
+ # of them
+ unmet_dependency_names -= remote_specs.spec_names # avoid re-fetching things we've already gotten
+ end
+ return if unmet_dependency_names.empty?
+ end
+
+ Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}"
+
+ fetch_names(api_fetchers, unmet_dependency_names, specs, false)
+ end
+
+ def dependency_names_to_double_check
+ names = []
+ remote_specs.each do |spec|
+ case spec
+ when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
+ names.concat(spec.runtime_dependencies.map(&:name))
+ when RemoteSpecification # from the full index
+ return nil
+ else
+ raise "unhandled spec type (#{spec.inspect})"
+ end
+ end
+ names
+ end
+
+ def dependency_api_available?
+ api_fetchers.any?
+ end
+
+ protected
+
+ def remote_names
+ remotes.map(&:to_s).join(", ")
+ end
def credless_remotes
- remotes.map(&method(:suppress_configured_credentials))
+ if Bundler.settings[:allow_deployment_source_credential_changes]
+ remotes.map(&method(:remove_auth))
+ else
+ remotes.map(&method(:suppress_configured_credentials))
+ end
end
def remotes_for_spec(spec)
@@ -254,14 +353,17 @@ module Bundler
end
def cached_gem(spec)
- cached_gem = cached_path(spec)
- unless cached_gem
- raise Bundler::GemNotFound, "Could not find #{spec.file_name} for installation"
+ if spec.default_gem?
+ cached_built_in_gem(spec)
+ else
+ cached_path(spec)
end
- cached_gem
end
def cached_path(spec)
+ global_cache_path = download_cache_path(spec)
+ @caches << global_cache_path if global_cache_path
+
possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" }
possibilities.find {|p| File.exist?(p) }
end
@@ -269,14 +371,15 @@ module Bundler
def normalize_uri(uri)
uri = uri.to_s
uri = "#{uri}/" unless uri =~ %r{/$}
- uri = URI(uri)
+ require_relative "../vendored_uri"
+ uri = Bundler::URI(uri)
raise ArgumentError, "The source must be an absolute URI. For example:\n" \
- "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(URI::HTTP) && uri.host.nil?)
+ "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(Bundler::URI::HTTP) && uri.host.nil?)
uri
end
def suppress_configured_credentials(remote)
- remote_nouser = remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
+ remote_nouser = remove_auth(remote)
if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser]
remote_nouser
else
@@ -284,15 +387,17 @@ module Bundler
end
end
+ def remove_auth(remote)
+ if remote.user || remote.password
+ remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
+ else
+ remote.to_s
+ end
+ end
+
def installed_specs
- @installed_specs ||= begin
- idx = Index.new
- have_bundler = false
+ @installed_specs ||= Index.build do |idx|
Bundler.rubygems.all_specs.reverse_each do |spec|
- if spec.name == "bundler"
- next unless spec.version.to_s == VERSION
- have_bundler = true
- end
spec.source = self
if Bundler.rubygems.spec_missing_extensions?(spec, false)
Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
@@ -300,43 +405,22 @@ module Bundler
end
idx << spec
end
-
- # Always have bundler locally
- unless have_bundler
- # We're running bundler directly from the source
- # so, let's create a fake gemspec for it (it's a path)
- # gemspec
- bundler = Gem::Specification.new do |s|
- s.name = "bundler"
- s.version = VERSION
- s.platform = Gem::Platform::RUBY
- s.source = self
- s.authors = ["bundler team"]
- s.loaded_from = File.expand_path("..", __FILE__)
- end
- idx << bundler
- end
- idx
end
end
def cached_specs
@cached_specs ||= begin
- idx = installed_specs.dup
+ idx = @allow_local ? installed_specs.dup : Index.new
Dir["#{cache_path}/*.gem"].each do |gemfile|
next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
s ||= Bundler.rubygems.spec_from_gem(gemfile)
s.source = self
- if Bundler.rubygems.spec_missing_extensions?(s, false)
- Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
- next
- end
idx << s
end
- end
- idx
+ idx
+ end
end
def api_fetchers
@@ -348,85 +432,57 @@ module Bundler
index_fetchers = fetchers - api_fetchers
# gather lists from non-api sites
- index_fetchers.each do |f|
- Bundler.ui.info "Fetching source index from #{f.uri}"
- idx.use f.specs_with_retry(nil, self)
- end
+ fetch_names(index_fetchers, nil, idx, false)
# because ensuring we have all the gems we need involves downloading
# the gemspecs of those gems, if the non-api sites contain more than
- # about 100 gems, we treat all sites as non-api for speed.
+ # about 500 gems, we treat all sites as non-api for speed.
allow_api = idx.size < API_REQUEST_LIMIT && dependency_names.size < API_REQUEST_LIMIT
Bundler.ui.debug "Need to query more than #{API_REQUEST_LIMIT} gems." \
" Downloading full index instead..." unless allow_api
- if allow_api
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
- idx.use f.specs_with_retry(dependency_names, self)
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- end
-
- # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
- # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
- # but will not have found any versions of Bar from source B, which is a problem if the requested version
- # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
- # each spec we found, we add all possible versions from all sources to the index.
- loop do
- idxcount = idx.size
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching version metadata from #{f.uri}", Bundler.ui.debug?
- idx.use f.specs_with_retry(idx.dependency_names, self), true
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- end
- break if idxcount == idx.size
- end
-
- if api_fetchers.any?
- # it's possible that gems from one source depend on gems from some
- # other source, so now we download gemspecs and iterate over those
- # dependencies, looking for gems we don't have info on yet.
- unmet = idx.unmet_dependency_names
-
- # if there are any cross-site gems we missed, get them now
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching dependency metadata from #{f.uri}", Bundler.ui.debug?
- idx.use f.specs_with_retry(unmet, self)
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- end if unmet.any?
- else
- allow_api = false
- end
- end
+ fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
+ end
+ end
- unless allow_api
- api_fetchers.each do |f|
- Bundler.ui.info "Fetching source index from #{f.uri}"
- idx.use f.specs_with_retry(nil, self)
- end
+ def fetch_names(fetchers, dependency_names, index, override_dupes)
+ fetchers.each do |f|
+ if dependency_names
+ Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug?
+ index.use f.specs_with_retry(dependency_names, self), override_dupes
+ Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
+ else
+ Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}"
+ index.use f.specs_with_retry(nil, self), override_dupes
end
end
end
def fetch_gem(spec)
return false unless spec.remote
- uri = spec.remote.uri
+
spec.fetch_platform
- Bundler.ui.confirm("Fetching #{version_message(spec)}")
- download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
- gem_path = "#{rubygems_dir}/cache/#{spec.full_name}.gem"
+ cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir)
+ gem_path = "#{cache_path}/#{spec.file_name}"
- SharedHelpers.filesystem_access("#{download_path}/cache") do |p|
+ if requires_sudo?
+ download_path = Bundler.tmp(spec.full_name)
+ download_cache_path = default_cache_path_for(download_path)
+ else
+ download_cache_path = cache_path
+ end
+
+ SharedHelpers.filesystem_access(download_cache_path) do |p|
FileUtils.mkdir_p(p)
end
- Bundler.rubygems.download_gem(spec, uri, download_path)
+ download_gem(spec, download_cache_path)
if requires_sudo?
- SharedHelpers.filesystem_access("#{rubygems_dir}/cache") do |p|
+ SharedHelpers.filesystem_access(cache_path) do |p|
Bundler.mkdir_p(p)
end
- Bundler.sudo "mv #{download_path}/cache/#{spec.full_name}.gem #{gem_path}"
+ Bundler.sudo "mv #{download_cache_path}/#{spec.file_name} #{gem_path}"
end
gem_path
@@ -434,16 +490,8 @@ module Bundler
Bundler.rm_rf(download_path) if requires_sudo?
end
- def builtin_gem?(spec)
- # Ruby 2.1, where all included gems have this summary
- return true if spec.summary =~ /is bundled with Ruby/
-
- # Ruby 2.0, where gemspecs are stored in specifications/default/
- spec.loaded_from && spec.loaded_from.include?("specifications/default/")
- end
-
def installed?(spec)
- installed_specs[spec].any?
+ installed_specs[spec].any? && !spec.deleted_gem?
end
def requires_sudo?
@@ -454,9 +502,54 @@ module Bundler
Bundler.rubygems.gem_dir
end
+ def default_cache_path_for(dir)
+ "#{dir}/cache"
+ end
+
def cache_path
Bundler.app_cache
end
+
+ private
+
+ # Checks if the requested spec exists in the global cache. If it does,
+ # we copy it to the download path, and if it does not, we download it.
+ #
+ # @param [Specification] spec
+ # the spec we want to download or retrieve from the cache.
+ #
+ # @param [String] download_cache_path
+ # the local directory the .gem will end up in.
+ #
+ def download_gem(spec, download_cache_path)
+ uri = spec.remote.uri
+ Bundler.ui.confirm("Fetching #{version_message(spec)}")
+ Bundler.rubygems.download_gem(spec, uri, download_cache_path)
+ end
+
+ # Returns the global cache path of the calling Rubygems::Source object.
+ #
+ # Note that the Source determines the path's subdirectory. We use this
+ # subdirectory in the global cache path so that gems with the same name
+ # -- and possibly different versions -- from different sources are saved
+ # to their respective subdirectories and do not override one another.
+ #
+ # @param [Gem::Specification] specification
+ #
+ # @return [Pathname] The global cache path.
+ #
+ def download_cache_path(spec)
+ return unless Bundler.feature_flag.global_gem_cache?
+ return unless remote = spec.remote
+ return unless cache_slug = remote.cache_slug
+
+ Bundler.user_cache.join("gems", cache_slug)
+ end
+
+ def extension_cache_slug(spec)
+ return unless remote = spec.remote
+ remote.cache_slug
+ end
end
end
end
diff --git a/lib/bundler/source/rubygems/remote.rb b/lib/bundler/source/rubygems/remote.rb
index b49e645506..82c850ffbb 100644
--- a/lib/bundler/source/rubygems/remote.rb
+++ b/lib/bundler/source/rubygems/remote.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
class Source
class Rubygems
@@ -20,10 +21,14 @@ module Bundler
#
def cache_slug
@cache_slug ||= begin
+ return nil unless SharedHelpers.md5_available?
+
cache_uri = original_uri || uri
- uri_parts = [cache_uri.host, cache_uri.user, cache_uri.port, cache_uri.path]
- uri_digest = Digest::MD5.hexdigest(uri_parts.compact.join("."))
+ host = cache_uri.to_s.start_with?("file://") ? nil : cache_uri.host
+
+ uri_parts = [host, cache_uri.user, cache_uri.port, cache_uri.path]
+ uri_digest = SharedHelpers.digest(:MD5).hexdigest(uri_parts.compact.join("."))
uri_parts[-1] = uri_digest
uri_parts.compact.join(".")
@@ -34,7 +39,7 @@ module Bundler
"rubygems remote at #{anonymized_uri}"
end
- private
+ private
def apply_auth(uri, auth)
if auth && uri.userinfo.nil?
@@ -43,7 +48,7 @@ module Bundler
end
uri
- rescue URI::InvalidComponentError
+ rescue Bundler::URI::InvalidComponentError
error_message = "Please CGI escape your usernames and passwords before " \
"setting them for authentication."
raise HTTPError.new(error_message)
diff --git a/lib/bundler/source/rubygems_aggregate.rb b/lib/bundler/source/rubygems_aggregate.rb
new file mode 100644
index 0000000000..99ef81ad54
--- /dev/null
+++ b/lib/bundler/source/rubygems_aggregate.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module Bundler
+ class Source
+ class RubygemsAggregate
+ attr_reader :source_map, :sources
+
+ def initialize(sources, source_map)
+ @sources = sources
+ @source_map = source_map
+
+ @index = build_index
+ end
+
+ def specs
+ @index
+ end
+
+ def identifier
+ to_s
+ end
+
+ def to_s
+ "any of the sources"
+ end
+
+ private
+
+ def build_index
+ Index.build do |idx|
+ dependency_names = source_map.pinned_spec_names
+
+ sources.all_sources.each do |source|
+ source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
+ idx.add_source source.specs
+ dependency_names.concat(source.unmet_deps).uniq!
+ end
+
+ double_check_for_index(idx, dependency_names)
+ end
+ end
+
+ # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
+ # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
+ # but will not have found any versions of Bar from source B, which is a problem if the requested version
+ # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
+ # each spec we found, we add all possible versions from all sources to the index.
+ def double_check_for_index(idx, dependency_names)
+ pinned_names = source_map.pinned_spec_names
+
+ names = :names # do this so we only have to traverse to get dependency_names from the index once
+ unmet_dependency_names = lambda do
+ return names unless names == :names
+ new_names = sources.all_sources.map(&:dependency_names_to_double_check)
+ return names = nil if new_names.compact!
+ names = new_names.flatten(1).concat(dependency_names)
+ names.uniq!
+ names -= pinned_names
+ names
+ end
+
+ sources.all_sources.each do |source|
+ source.double_check_for(unmet_dependency_names)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index b6ce6029c8..a4773397c7 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -1,23 +1,53 @@
# frozen_string_literal: true
+
module Bundler
class SourceList
attr_reader :path_sources,
:git_sources,
- :plugin_sources
+ :plugin_sources,
+ :global_path_source,
+ :metadata_source
+
+ def global_rubygems_source
+ @global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true)
+ end
def initialize
- @path_sources = []
- @git_sources = []
- @plugin_sources = []
- @rubygems_aggregate = Source::Rubygems.new
- @rubygems_sources = []
+ @path_sources = []
+ @git_sources = []
+ @plugin_sources = []
+ @global_rubygems_source = nil
+ @global_path_source = nil
+ @rubygems_sources = []
+ @metadata_source = Source::Metadata.new
+
+ @merged_gem_lockfile_sections = false
+ end
+
+ def merged_gem_lockfile_sections?
+ @merged_gem_lockfile_sections
+ end
+
+ def merged_gem_lockfile_sections!(replacement_source)
+ @merged_gem_lockfile_sections = true
+ @global_rubygems_source = replacement_source
+ end
+
+ def aggregate_global_source?
+ global_rubygems_source.multiple_remotes?
+ end
+
+ def implicit_global_source?
+ global_rubygems_source.no_remotes?
end
def add_path_source(options = {})
if options["gemspec"]
add_source_to_list Source::Gemspec.new(options), path_sources
else
- add_source_to_list Source::Path.new(options), path_sources
+ path_source = add_source_to_list Source::Path.new(options), path_sources
+ @global_path_source ||= path_source if options["global"]
+ path_source
end
end
@@ -28,20 +58,31 @@ module Bundler
end
def add_rubygems_source(options = {})
- add_source_to_list Source::Rubygems.new(options), @rubygems_sources
+ new_source = Source::Rubygems.new(options)
+ return @global_rubygems_source if @global_rubygems_source == new_source
+
+ add_source_to_list new_source, @rubygems_sources
end
def add_plugin_source(source, options = {})
add_source_to_list Plugin.source(source).new(options), @plugin_sources
end
- def add_rubygems_remote(uri)
- @rubygems_aggregate.add_remote(uri)
- @rubygems_aggregate
+ def add_global_rubygems_remote(uri)
+ global_rubygems_source.add_remote(uri)
+ global_rubygems_source
+ end
+
+ def default_source
+ global_path_source || global_rubygems_source
end
def rubygems_sources
- @rubygems_sources + [@rubygems_aggregate]
+ non_global_rubygems_sources + [global_rubygems_source]
+ end
+
+ def non_global_rubygems_sources
+ @rubygems_sources
end
def rubygems_remotes
@@ -49,34 +90,54 @@ module Bundler
end
def all_sources
- path_sources + git_sources + plugin_sources + rubygems_sources
+ path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
+ end
+
+ def non_default_explicit_sources
+ all_sources - [default_source, metadata_source]
end
def get(source)
- source_list_for(source).find {|s| source == s }
+ source_list_for(source).find {|s| equivalent_source?(source, s) }
end
def lock_sources
- lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
- lock_sources << combine_rubygems_sources
+ lock_other_sources + lock_rubygems_sources
end
- def replace_sources!(replacement_sources)
- return true if replacement_sources.empty?
+ def lock_other_sources
+ (path_sources + git_sources + plugin_sources).sort_by(&:identifier)
+ end
- [path_sources, git_sources, plugin_sources].each do |source_list|
- source_list.map! do |source|
- replacement_sources.find {|s| s == source } || source
- end
+ def lock_rubygems_sources
+ if merged_gem_lockfile_sections?
+ [combine_rubygems_sources]
+ else
+ rubygems_sources.sort_by(&:identifier)
end
+ end
- replacement_rubygems =
- replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
- @rubygems_aggregate = replacement_rubygems if replacement_rubygems
+ # Returns true if there are changes
+ def replace_sources!(replacement_sources)
+ return false if replacement_sources.empty?
+
+ @rubygems_sources, @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
+ @global_rubygems_source = global_replacement_source(replacement_sources)
+
+ different_sources?(lock_sources, replacement_sources)
+ end
+
+ # Returns true if there are changes
+ def expired_sources?(replacement_sources)
+ return false if replacement_sources.empty?
+
+ lock_sources = dup_with_replaced_sources(replacement_sources).lock_sources
- # Return true if there were changes
- lock_sources.to_set != replacement_sources.to_set ||
- rubygems_remotes.to_set != replacement_rubygems.remotes.to_set
+ different_sources?(lock_sources, replacement_sources)
+ end
+
+ def local_only!
+ all_sources.each(&:local_only!)
end
def cached!
@@ -87,11 +148,37 @@ module Bundler
all_sources.each(&:remote!)
end
- def rubygems_primary_remotes
- @rubygems_aggregate.remotes
+ private
+
+ def dup_with_replaced_sources(replacement_sources)
+ new_source_list = dup
+ new_source_list.replace_sources!(replacement_sources)
+ new_source_list
+ end
+
+ def map_sources(replacement_sources)
+ [@rubygems_sources, @path_sources, @git_sources, @plugin_sources].map do |sources|
+ sources.map do |source|
+ replacement_sources.find {|s| s == source } || source
+ end
+ end
+ end
+
+ def global_replacement_source(replacement_sources)
+ replacement_source = replacement_sources.find {|s| s == global_rubygems_source }
+ return global_rubygems_source unless replacement_source
+
+ replacement_source.local!
+ replacement_source
+ end
+
+ def different_sources?(lock_sources, replacement_sources)
+ !equivalent_sources?(lock_sources, replacement_sources)
end
- private
+ def rubygems_aggregate_class
+ Source::Rubygems
+ end
def add_source_to_list(source, list)
list.unshift(source).uniq!
@@ -118,9 +205,17 @@ module Bundler
if source.uri =~ /^git\:/
Bundler.ui.warn "The git source `#{source.uri}` uses the `git` protocol, " \
"which transmits data without encryption. Disable this warning with " \
- "`bundle config git.allow_insecure true`, or switch to the `https` " \
+ "`bundle config set --local git.allow_insecure true`, or switch to the `https` " \
"protocol to keep your data secure."
end
end
+
+ def equivalent_sources?(lock_sources, replacement_sources)
+ lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier)
+ end
+
+ def equivalent_source?(source, other_source)
+ source == other_source
+ end
end
end
diff --git a/lib/bundler/source_map.rb b/lib/bundler/source_map.rb
new file mode 100644
index 0000000000..a554f26f76
--- /dev/null
+++ b/lib/bundler/source_map.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Bundler
+ class SourceMap
+ attr_reader :sources, :dependencies
+
+ def initialize(sources, dependencies)
+ @sources = sources
+ @dependencies = dependencies
+ end
+
+ def pinned_spec_names(skip = nil)
+ direct_requirements.reject {|_, source| source == skip }.keys
+ end
+
+ def all_requirements
+ requirements = direct_requirements.dup
+
+ unmet_deps = sources.non_default_explicit_sources.map do |source|
+ (source.spec_names - pinned_spec_names).each do |indirect_dependency_name|
+ previous_source = requirements[indirect_dependency_name]
+ if previous_source.nil?
+ requirements[indirect_dependency_name] = source
+ else
+ no_ambiguous_sources = Bundler.feature_flag.bundler_3_mode?
+
+ msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."]
+ msg.concat [previous_source, source].map {|s| " * #{s}" }.sort
+ msg << "You #{no_ambiguous_sources ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
+ msg = msg.join("\n")
+
+ raise SecurityError, msg if no_ambiguous_sources
+ Bundler.ui.warn "Warning: #{msg}"
+ end
+ end
+
+ source.unmet_deps
+ end
+
+ sources.default_source.add_dependency_names(unmet_deps.flatten - requirements.keys)
+
+ requirements
+ end
+
+ def direct_requirements
+ @direct_requirements ||= begin
+ requirements = {}
+ default = sources.default_source
+ dependencies.each do |dep|
+ dep_source = dep.source || default
+ dep_source.add_dependency_names(dep.name)
+ requirements[dep.name] = dep_source
+ end
+ requirements
+ end
+ end
+ end
+end
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 9642633578..a19d18388a 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -1,42 +1,38 @@
# frozen_string_literal: true
-require "tsort"
-require "forwardable"
-require "set"
+
+require_relative "vendored_tsort"
module Bundler
class SpecSet
- extend Forwardable
- include TSort, Enumerable
-
- def_delegators :@specs, :<<, :length, :add, :remove, :size, :empty?
- def_delegators :sorted, :each
+ include Enumerable
+ include TSort
def initialize(specs)
@specs = specs
end
- def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
- handled = Set.new
+ def for(dependencies, check = false, match_current_platform = false)
+ handled = []
deps = dependencies.dup
specs = []
- skip += ["bundler"]
loop do
break unless dep = deps.shift
- next if !handled.add?(dep) || skip.include?(dep.name)
+ next if handled.any?{|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"
- if spec = spec_for_dependency(dep, match_current_platform)
- specs << spec
+ handled << dep
- spec.dependencies.each do |d|
+ specs_for_dep = spec_for_dependency(dep, match_current_platform)
+ if specs_for_dep.any?
+ match_current_platform ? specs += specs_for_dep : specs |= specs_for_dep
+
+ specs_for_dep.first.dependencies.each do |d|
next if d.type == :development
- d = DepProxy.new(d, dep.__platform) unless match_current_platform
+ d = DepProxy.get_proxy(d, dep.__platform) unless match_current_platform
deps << d
end
elsif check
return false
- elsif raise_on_missing
- raise "Unable to find a spec satisfying #{dep} in the set. Perhaps the lockfile is corrupted?"
end
end
@@ -44,11 +40,7 @@ module Bundler
specs << spec
end
- check ? true : SpecSet.new(specs)
- end
-
- def valid_for?(deps)
- self.for(deps, [], true)
+ check ? true : specs
end
def [](key)
@@ -60,7 +52,6 @@ module Bundler
@specs << value
@lookup = nil
@sorted = nil
- value
end
def sort!
@@ -75,43 +66,41 @@ module Bundler
lookup.dup
end
- def materialize(deps, missing_specs = nil)
- materialized = self.for(deps, [], false, true, missing_specs).to_a
- deps = materialized.map(&:name).uniq
+ def materialize(deps)
+ materialized = self.for(deps, false, true)
+
materialized.map! do |s|
next s unless s.is_a?(LazySpecification)
- s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
- spec = s.__materialize__
- unless spec
- unless missing_specs
- raise GemNotFound, "Could not find #{s.full_name} in any of the sources"
- end
- missing_specs << s
- end
- spec
+ s.source.local!
+ s.__materialize__ || s
end
- SpecSet.new(missing_specs ? materialized.compact : materialized)
+ SpecSet.new(materialized)
end
# Materialize for all the specs in the spec set, regardless of what platform they're for
# This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform)
# @return [Array<Gem::Specification>]
def materialized_for_all_platforms
- names = @specs.map(&:name).uniq
@specs.map do |s|
next s unless s.is_a?(LazySpecification)
- s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
+ s.source.local!
+ s.source.remote!
spec = s.__materialize__
raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
spec
end
end
+ def missing_specs
+ @specs.select {|s| s.is_a?(LazySpecification) }
+ end
+
def merge(set)
arr = sorted.dup
- set.each do |s|
- next if arr.any? {|s2| s2.name == s.name && s2.version == s.version && s2.platform == s.platform }
- arr << s
+ set.each do |set_spec|
+ full_name = set_spec.full_name
+ next if arr.any? {|spec| spec.full_name == full_name }
+ arr << set_spec
end
SpecSet.new(arr)
end
@@ -127,7 +116,27 @@ module Bundler
what_required(req) << spec
end
- private
+ def <<(spec)
+ @specs << spec
+ end
+
+ def length
+ @specs.length
+ end
+
+ def size
+ @specs.size
+ end
+
+ def empty?
+ @specs.empty?
+ end
+
+ def each(&b)
+ sorted.each(&b)
+ end
+
+ private
def sorted
rake = @specs.find {|s| s.name == "rake" }
@@ -142,11 +151,7 @@ module Bundler
end
def extract_circular_gems(error)
- if Bundler.current_ruby.mri? && Bundler.current_ruby.on_19?
- error.message.scan(/(\w+) \([^)]/).flatten
- else
- error.message.scan(/@name="(.*?)"/).flatten
- end
+ error.message.scan(/@name="(.*?)"/).flatten
end
def lookup
@@ -167,11 +172,7 @@ module Bundler
def spec_for_dependency(dep, match_current_platform)
specs_for_platforms = lookup[dep.name]
if match_current_platform
- Bundler.rubygems.platforms.reverse_each do |pl|
- match = GemHelpers.select_best_platform_match(specs_for_platforms, pl)
- return match if match
- end
- nil
+ GemHelpers.select_best_platform_match(specs_for_platforms.select{|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform)
else
GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
end
diff --git a/lib/bundler/ssl_certs/certificate_manager.rb b/lib/bundler/ssl_certs/certificate_manager.rb
deleted file mode 100644
index a5e5d84b64..0000000000
--- a/lib/bundler/ssl_certs/certificate_manager.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-require "fileutils"
-require "net/https"
-require "openssl"
-
-module Bundler
- module SSLCerts
- class CertificateManager
- attr_reader :bundler_cert_path, :bundler_certs, :rubygems_certs
-
- def self.update_from!(rubygems_path)
- new(rubygems_path).update!
- end
-
- def initialize(rubygems_path = nil)
- if rubygems_path
- rubygems_cert_path = File.join(rubygems_path, "lib/rubygems/ssl_certs")
- @rubygems_certs = certificates_in(rubygems_cert_path)
- end
-
- @bundler_cert_path = File.expand_path("..", __FILE__)
- @bundler_certs = certificates_in(bundler_cert_path)
- end
-
- def up_to_date?
- rubygems_certs.all? do |rc|
- bundler_certs.find do |bc|
- File.basename(bc) == File.basename(rc) && FileUtils.compare_file(bc, rc)
- end
- end
- end
-
- def update!
- return if up_to_date?
-
- FileUtils.rm bundler_certs
- FileUtils.cp rubygems_certs, bundler_cert_path
- end
-
- def connect_to(host)
- http = Net::HTTP.new(host, 443)
- http.use_ssl = true
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
- http.cert_store = store
- http.head("/")
- end
-
- private
-
- def certificates_in(path)
- Dir[File.join(path, "**/*.pem")].sort
- end
-
- def store
- @store ||= begin
- store = OpenSSL::X509::Store.new
- bundler_certs.each do |cert|
- store.add_file cert
- end
- store
- end
- end
- end
- end
-end
diff --git a/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem b/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem
deleted file mode 100644
index 9e6810ab70..0000000000
--- a/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----
diff --git a/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem b/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem
deleted file mode 100644
index 20585f1c01..0000000000
--- a/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem
+++ /dev/null
@@ -1,25 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb
index aeacf245a3..fa071901e5 100644
--- a/lib/bundler/stub_specification.rb
+++ b/lib/bundler/stub_specification.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "bundler/remote_specification"
module Bundler
class StubSpecification < RemoteSpecification
@@ -12,17 +11,13 @@ module Bundler
attr_accessor :stub, :ignored
- # Pre 2.2.0 did not include extension_dir
- # https://github.com/rubygems/rubygems/commit/9485ca2d101b82a946d6f327f4bdcdea6d4946ea
- if Bundler.rubygems.provides?(">= 2.2.0")
- def source=(source)
- super
- # Stub has no concept of source, which means that extension_dir may be wrong
- # This is the case for git-based gems. So, instead manually assign the extension dir
- return unless source.respond_to?(:extension_dir_name)
- path = File.join(stub.extensions_dir, source.extension_dir_name)
- stub.extension_dir = File.expand_path(path)
- end
+ def source=(source)
+ super
+ # Stub has no concept of source, which means that extension_dir may be wrong
+ # This is the case for git-based gems. So, instead manually assign the extension dir
+ return unless source.respond_to?(:extension_dir_name)
+ path = File.join(stub.extensions_dir, source.extension_dir_name)
+ stub.extension_dir = File.expand_path(path)
end
def to_yaml
@@ -31,11 +26,21 @@ module Bundler
# @!group Stub Delegates
- if Bundler.rubygems.provides?(">= 2.3")
- # This is defined directly to avoid having to load every installed spec
- def missing_extensions?
- stub.missing_extensions?
- end
+ def manually_installed?
+ # This is for manually installed gems which are gems that were fixed in place after a
+ # failed installation. Once the issue was resolved, the user then manually created
+ # the gem specification using the instructions provided by `gem help install`
+ installed_by_version == Gem::Version.new(0)
+ end
+
+ # This is defined directly to avoid having to loading the full spec
+ def missing_extensions?
+ return false if default_gem?
+ return false if extensions.empty?
+ return false if File.exist? gem_build_complete_path
+ return false if manually_installed?
+
+ true
end
def activated
@@ -46,8 +51,16 @@ module Bundler
stub.instance_variable_set(:@activated, activated)
end
- def default_gem
- stub.default_gem
+ def extensions
+ stub.extensions
+ end
+
+ def gem_build_complete_path
+ File.join(extension_dir, "gem.build_complete")
+ end
+
+ def default_gem?
+ stub.default_gem?
end
def full_gem_path
@@ -56,33 +69,27 @@ module Bundler
stub.full_gem_path || method_missing(:full_gem_path)
end
- if Bundler.rubygems.provides?(">= 2.2.0")
- def full_require_paths
- stub.full_require_paths
- end
+ def full_require_paths
+ stub.full_require_paths
+ end
- # This is what we do in bundler/rubygems_ext
- # full_require_paths is always implemented in >= 2.2.0
- def load_paths
- full_require_paths
- end
+ def load_paths
+ full_require_paths
end
def loaded_from
stub.loaded_from
end
- if Bundler.rubygems.stubs_provide_full_functionality?
- def matches_for_glob(glob)
- stub.matches_for_glob(glob)
- end
+ def matches_for_glob(glob)
+ stub.matches_for_glob(glob)
end
def raw_require_paths
stub.raw_require_paths
end
- private
+ private
def _remote_specification
@_remote_specification ||= begin
diff --git a/lib/bundler/templates/.document b/lib/bundler/templates/.document
new file mode 100644
index 0000000000..fb66f13c33
--- /dev/null
+++ b/lib/bundler/templates/.document
@@ -0,0 +1 @@
+# Ignore all files in this directory
diff --git a/lib/bundler/templates/Executable b/lib/bundler/templates/Executable
index fe22de0a6d..3e8d5b317a 100755..100644
--- a/lib/bundler/templates/Executable
+++ b/lib/bundler/templates/Executable
@@ -1,5 +1,6 @@
#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %>
# frozen_string_literal: true
+
#
# This file was generated by Bundler.
#
@@ -11,6 +12,17 @@ require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../<%= relative_gemfile_path %>",
Pathname.new(__FILE__).realpath)
+bundle_binstub = File.expand_path("../bundle", __FILE__)
+
+if File.file?(bundle_binstub)
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+ load(bundle_binstub)
+ else
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+ end
+end
+
require "rubygems"
require "bundler/setup"
diff --git a/lib/bundler/templates/Executable.bundler b/lib/bundler/templates/Executable.bundler
new file mode 100644
index 0000000000..8009412ea2
--- /dev/null
+++ b/lib/bundler/templates/Executable.bundler
@@ -0,0 +1,114 @@
+#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %>
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application '<%= executable %>' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "rubygems"
+
+m = Module.new do
+ module_function
+
+ def invoked_as_script?
+ File.expand_path($0) == File.expand_path(__FILE__)
+ end
+
+ def env_var_version
+ ENV["BUNDLER_VERSION"]
+ end
+
+ def cli_arg_version
+ return unless invoked_as_script? # don't want to hijack other binstubs
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
+ bundler_version = nil
+ update_index = nil
+ ARGV.each_with_index do |a, i|
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
+ bundler_version = a
+ end
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
+ bundler_version = $1
+ update_index = i
+ end
+ bundler_version
+ end
+
+ def gemfile
+ gemfile = ENV["BUNDLE_GEMFILE"]
+ return gemfile if gemfile && !gemfile.empty?
+
+ File.expand_path("../<%= relative_gemfile_path %>", __FILE__)
+ end
+
+ def lockfile
+ lockfile =
+ case File.basename(gemfile)
+ when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
+ else "#{gemfile}.lock"
+ end
+ File.expand_path(lockfile)
+ end
+
+ def lockfile_version
+ return unless File.file?(lockfile)
+ lockfile_contents = File.read(lockfile)
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
+ Regexp.last_match(1)
+ end
+
+ def bundler_requirement
+ @bundler_requirement ||=
+ env_var_version || cli_arg_version ||
+ bundler_requirement_for(lockfile_version)
+ end
+
+ def bundler_requirement_for(version)
+ return "#{Gem::Requirement.default}.a" unless version
+
+ bundler_gem_version = Gem::Version.new(version)
+
+ requirement = bundler_gem_version.approximate_recommendation
+
+ return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
+
+ requirement += ".a" if bundler_gem_version.prerelease?
+
+ requirement
+ end
+
+ def load_bundler!
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
+
+ activate_bundler
+ end
+
+ def activate_bundler
+ gem_error = activation_error_handling do
+ gem "bundler", bundler_requirement
+ end
+ return if gem_error.nil?
+ require_error = activation_error_handling do
+ require "bundler/version"
+ end
+ return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
+ warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
+ exit 42
+ end
+
+ def activation_error_handling
+ yield
+ nil
+ rescue StandardError, LoadError => e
+ e
+ end
+end
+
+m.load_bundler!
+
+if m.invoked_as_script?
+ load Gem.bin_path("<%= spec.name %>", "<%= executable %>")
+end
diff --git a/lib/bundler/templates/Gemfile b/lib/bundler/templates/Gemfile
index 21c6283123..d41f2719b4 100644
--- a/lib/bundler/templates/Gemfile
+++ b/lib/bundler/templates/Gemfile
@@ -1,6 +1,7 @@
# frozen_string_literal: true
+
source "https://rubygems.org"
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
diff --git a/lib/bundler/templates/gems.rb b/lib/bundler/templates/gems.rb
new file mode 100644
index 0000000000..56a62a7a82
--- /dev/null
+++ b/lib/bundler/templates/gems.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+# A sample gems.rb
+source "https://rubygems.org"
+
+git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
+
+# gem "rails"
diff --git a/lib/bundler/templates/newgem/CHANGELOG.md.tt b/lib/bundler/templates/newgem/CHANGELOG.md.tt
new file mode 100644
index 0000000000..c9ea96d453
--- /dev/null
+++ b/lib/bundler/templates/newgem/CHANGELOG.md.tt
@@ -0,0 +1,5 @@
+## [Unreleased]
+
+## [0.1.0] - <%= Time.now.strftime('%F') %>
+
+- Initial release
diff --git a/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt b/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
index a3833d29d7..175b821a62 100644
--- a/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
+++ b/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
@@ -2,73 +2,83 @@
## Our Pledge
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, gender identity and expression, level of experience,
-nationality, personal appearance, race, religion, or sexual identity and
-orientation.
+We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
-Examples of behavior that contributes to creating a positive environment
-include:
+Examples of behavior that contributes to a positive environment for our community include:
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall community
-Examples of unacceptable behavior by participants include:
+Examples of unacceptable behavior include:
-* The use of sexualized language or imagery and unwelcome sexual attention or
-advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
-## Our Responsibilities
+## Enforcement Responsibilities
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
+Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
+Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
+This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at <%= config[:email] %>. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at <%= config[:email] %>. All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series of actions.
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
+**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within the community.
## Attribution
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at [http://contributor-covenant.org/version/1/4][version]
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
+available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
-[homepage]: http://contributor-covenant.org
-[version]: http://contributor-covenant.org/version/1/4/
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
diff --git a/lib/bundler/templates/newgem/Gemfile.tt b/lib/bundler/templates/newgem/Gemfile.tt
index c114bd6665..de82a63c5f 100644
--- a/lib/bundler/templates/newgem/Gemfile.tt
+++ b/lib/bundler/templates/newgem/Gemfile.tt
@@ -1,6 +1,23 @@
-source "https://rubygems.org"
+# frozen_string_literal: true
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+source "https://rubygems.org"
# Specify your gem's dependencies in <%= config[:name] %>.gemspec
gemspec
+
+gem "rake", "~> 13.0"
+<%- if config[:ext] -%>
+
+gem "rake-compiler"
+<%- end -%>
+<%- if config[:test] -%>
+
+gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
+<%- end -%>
+<%- if config[:linter] == "rubocop" -%>
+
+gem "rubocop", "~> <%= config[:linter_version] %>"
+<%- elsif config[:linter] == "standard" -%>
+
+gem "standard", "~> <%= config[:linter_version] %>"
+<%- end -%>
diff --git a/lib/bundler/templates/newgem/README.md.tt b/lib/bundler/templates/newgem/README.md.tt
index edbe55dabe..8fd87abe9a 100644
--- a/lib/bundler/templates/newgem/README.md.tt
+++ b/lib/bundler/templates/newgem/README.md.tt
@@ -14,7 +14,7 @@ gem '<%= config[:name] %>'
And then execute:
- $ bundle
+ $ bundle install
Or install it yourself as:
@@ -28,20 +28,22 @@ TODO: Write usage instructions here
After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test].sub('mini', '').sub('rspec', 'spec') %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %>
-To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
+To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
+<% if config[:git] -%>
## Contributing
-Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.<% end %>
+Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).<% end %>
+<% end -%>
<% if config[:mit] -%>
## License
-The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
+The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
<% end -%>
-<% if config[:coc] -%>
+<% if config[:git] && config[:coc] -%>
## Code of Conduct
-Everyone interacting in the <%= config[:constant_name] %> project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).
+Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).
<% end -%>
diff --git a/lib/bundler/templates/newgem/Rakefile.tt b/lib/bundler/templates/newgem/Rakefile.tt
index 099da6f3ec..00b91c8464 100644
--- a/lib/bundler/templates/newgem/Rakefile.tt
+++ b/lib/bundler/templates/newgem/Rakefile.tt
@@ -1,5 +1,9 @@
+# frozen_string_literal: true
+
require "bundler/gem_tasks"
-<% if config[:test] == "minitest" -%>
+<% default_task_names = [config[:test_task]].compact -%>
+<% case config[:test] -%>
+<% when "minitest", "test-unit" -%>
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
@@ -8,22 +12,36 @@ Rake::TestTask.new(:test) do |t|
t.test_files = FileList["test/**/*_test.rb"]
end
-<% elsif config[:test] == "rspec" -%>
+<% when "rspec" -%>
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec)
<% end -%>
+<% if config[:linter] == "rubocop" -%>
+<% default_task_names << :rubocop -%>
+require "rubocop/rake_task"
+
+RuboCop::RakeTask.new
+
+<% elsif config[:linter] == "standard" -%>
+<% default_task_names << :standard -%>
+require "standard/rake"
+
+<% end -%>
<% if config[:ext] -%>
+<% default_task_names.unshift(:clobber, :compile) -%>
require "rake/extensiontask"
-task :build => :compile
+task build: :compile
Rake::ExtensionTask.new("<%= config[:underscored_name] %>") do |ext|
ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
end
-task :default => [:clobber, :compile, :<%= config[:test_task] %>]
+<% end -%>
+<% if default_task_names.size == 1 -%>
+task default: <%= default_task_names.first.inspect %>
<% else -%>
-task :default => :<%= config[:test_task] %>
+task default: %i[<%= default_task_names.join(" ") %>]
<% end -%>
diff --git a/lib/bundler/templates/newgem/bin/console.tt b/lib/bundler/templates/newgem/bin/console.tt
index a27f82430f..08dfaaef69 100644
--- a/lib/bundler/templates/newgem/bin/console.tt
+++ b/lib/bundler/templates/newgem/bin/console.tt
@@ -1,4 +1,5 @@
#!/usr/bin/env ruby
+# frozen_string_literal: true
require "bundler/setup"
require "<%= config[:namespaced_path] %>"
diff --git a/lib/bundler/templates/newgem/circleci/config.yml.tt b/lib/bundler/templates/newgem/circleci/config.yml.tt
new file mode 100644
index 0000000000..79fd0dcc0f
--- /dev/null
+++ b/lib/bundler/templates/newgem/circleci/config.yml.tt
@@ -0,0 +1,13 @@
+version: 2.1
+jobs:
+ build:
+ docker:
+ - image: ruby:<%= RUBY_VERSION %>
+ steps:
+ - checkout
+ - run:
+ name: Run the default task
+ command: |
+ gem install bundler -v <%= Bundler::VERSION %>
+ bundle install
+ bundle exec rake
diff --git a/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt b/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt
index 8cfc828f94..e918063ddf 100644
--- a/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt
+++ b/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "mkmf"
create_makefile(<%= config[:makefile_path].inspect %>)
diff --git a/lib/bundler/templates/newgem/github/workflows/main.yml.tt b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
new file mode 100644
index 0000000000..6570d177af
--- /dev/null
+++ b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
@@ -0,0 +1,27 @@
+name: Ruby
+
+on:
+ push:
+ branches:
+ - <%= config[:git_default_branch] %>
+
+ pull_request:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ name: Ruby ${{ matrix.ruby }}
+ strategy:
+ matrix:
+ ruby:
+ - '<%= RUBY_VERSION %>'
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby }}
+ bundler-cache: true
+ - name: Run the default task
+ run: bundle exec rake
diff --git a/lib/bundler/templates/newgem/gitignore.tt b/lib/bundler/templates/newgem/gitignore.tt
index 573d76b4c2..b1c9f9986c 100644
--- a/lib/bundler/templates/newgem/gitignore.tt
+++ b/lib/bundler/templates/newgem/gitignore.tt
@@ -1,6 +1,5 @@
/.bundle/
/.yardoc
-/Gemfile.lock
/_yardoc/
/coverage/
/doc/
diff --git a/lib/bundler/templates/newgem/gitlab-ci.yml.tt b/lib/bundler/templates/newgem/gitlab-ci.yml.tt
new file mode 100644
index 0000000000..0e71ff26a4
--- /dev/null
+++ b/lib/bundler/templates/newgem/gitlab-ci.yml.tt
@@ -0,0 +1,9 @@
+image: ruby:<%= RUBY_VERSION %>
+
+before_script:
+ - gem install bundler -v <%= Bundler::VERSION %>
+ - bundle install
+
+example_job:
+ script:
+ - bundle exec rake
diff --git a/lib/bundler/templates/newgem/lib/newgem.rb.tt b/lib/bundler/templates/newgem/lib/newgem.rb.tt
index 7d8ad90ab0..caf6e32f4a 100644
--- a/lib/bundler/templates/newgem/lib/newgem.rb.tt
+++ b/lib/bundler/templates/newgem/lib/newgem.rb.tt
@@ -1,11 +1,14 @@
-require "<%= config[:namespaced_path] %>/version"
+# frozen_string_literal: true
+
+require_relative "<%= File.basename(config[:namespaced_path]) %>/version"
<%- if config[:ext] -%>
-require "<%= config[:namespaced_path] %>/<%= config[:underscored_name] %>"
+require_relative "<%= File.basename(config[:namespaced_path]) %>/<%= config[:underscored_name] %>"
<%- end -%>
<%- config[:constant_array].each_with_index do |c, i| -%>
<%= " " * i %>module <%= c %>
<%- end -%>
+<%= " " * config[:constant_array].size %>class Error < StandardError; end
<%= " " * config[:constant_array].size %># Your code goes here...
<%- (config[:constant_array].size-1).downto(0) do |i| -%>
<%= " " * i %>end
diff --git a/lib/bundler/templates/newgem/lib/newgem/version.rb.tt b/lib/bundler/templates/newgem/lib/newgem/version.rb.tt
index 389daf5048..b5cd4cb232 100644
--- a/lib/bundler/templates/newgem/lib/newgem/version.rb.tt
+++ b/lib/bundler/templates/newgem/lib/newgem/version.rb.tt
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
<%- config[:constant_array].each_with_index do |c, i| -%>
<%= " " * i %>module <%= c %>
<%- end -%>
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index caea7fe7be..82281ab674 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -1,46 +1,44 @@
-# coding: utf-8
-lib = File.expand_path("../lib", __FILE__)
-$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
-require "<%= config[:namespaced_path] %>/version"
+# frozen_string_literal: true
+
+require_relative "lib/<%=config[:namespaced_path]%>/version"
Gem::Specification.new do |spec|
- spec.name = <%= config[:name].inspect %>
- spec.version = <%= config[:constant_name] %>::VERSION
- spec.authors = [<%= config[:author].inspect %>]
- spec.email = [<%= config[:email].inspect %>]
-
- spec.summary = %q{TODO: Write a short summary, because Rubygems requires one.}
- spec.description = %q{TODO: Write a longer description or delete this line.}
- spec.homepage = "TODO: Put your gem's website or public repo URL here."
+ spec.name = <%= config[:name].inspect %>
+ spec.version = <%= config[:constant_name] %>::VERSION
+ spec.authors = [<%= config[:author].inspect %>]
+ spec.email = [<%= config[:email].inspect %>]
+
+ spec.summary = "TODO: Write a short summary, because RubyGems requires one."
+ spec.description = "TODO: Write a longer description or delete this line."
+ spec.homepage = "TODO: Put your gem's website or public repo URL here."
<%- if config[:mit] -%>
- spec.license = "MIT"
+ spec.license = "MIT"
<%- end -%>
+ spec.required_ruby_version = ">= <%= config[:required_ruby_version] %>"
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
- # to allow pushing to a single host or delete this section to allow pushing to any host.
- if spec.respond_to?(:metadata)
- spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
- else
- raise "RubyGems 2.0 or newer is required to protect against " \
- "public gem pushes."
- end
+ spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
+ spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
- f.match(%r{^(test|spec|features)/})
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
+ `git ls-files -z`.split("\x0").reject do |f|
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
+ end
end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
<%- if config[:ext] -%>
- spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
+ spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
<%- end -%>
- spec.add_development_dependency "bundler", "~> <%= config[:bundler_version] %>"
- spec.add_development_dependency "rake", "~> 10.0"
-<%- if config[:ext] -%>
- spec.add_development_dependency "rake-compiler"
-<%- end -%>
-<%- if config[:test] -%>
- spec.add_development_dependency "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
-<%- end -%>
+ # Uncomment to register a new dependency of your gem
+ # spec.add_dependency "example-gem", "~> 1.0"
+
+ # For more information and examples about making a new gem, checkout our
+ # guide at: https://bundler.io/guides/creating_gem.html
end
diff --git a/lib/bundler/templates/newgem/rspec.tt b/lib/bundler/templates/newgem/rspec.tt
index 8c18f1abdd..34c5164d9b 100644
--- a/lib/bundler/templates/newgem/rspec.tt
+++ b/lib/bundler/templates/newgem/rspec.tt
@@ -1,2 +1,3 @@
--format documentation
--color
+--require spec_helper
diff --git a/lib/bundler/templates/newgem/rubocop.yml.tt b/lib/bundler/templates/newgem/rubocop.yml.tt
new file mode 100644
index 0000000000..9ecec78807
--- /dev/null
+++ b/lib/bundler/templates/newgem/rubocop.yml.tt
@@ -0,0 +1,13 @@
+AllCops:
+ TargetRubyVersion: <%= ::Gem::Version.new(config[:required_ruby_version]).segments[0..1].join(".") %>
+
+Style/StringLiterals:
+ Enabled: true
+ EnforcedStyle: double_quotes
+
+Style/StringLiteralsInInterpolation:
+ Enabled: true
+ EnforcedStyle: double_quotes
+
+Layout/LineLength:
+ Max: 120
diff --git a/lib/bundler/templates/newgem/sig/newgem.rbs.tt b/lib/bundler/templates/newgem/sig/newgem.rbs.tt
new file mode 100644
index 0000000000..eb7b380bbb
--- /dev/null
+++ b/lib/bundler/templates/newgem/sig/newgem.rbs.tt
@@ -0,0 +1,8 @@
+<%- config[:constant_array].each_with_index do |c, i| -%>
+<%= " " * i %>module <%= c %>
+<%- end -%>
+<%= " " * config[:constant_array].size %>VERSION: String
+<%= " " * config[:constant_array].size %># See the writing guide of rbs: https://github.com/ruby/rbs#guides
+<%- (config[:constant_array].size-1).downto(0) do |i| -%>
+<%= " " * i %>end
+<%- end -%>
diff --git a/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt b/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt
index b7ef7f9e4a..82cada988c 100644
--- a/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt
+++ b/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt
@@ -1,4 +1,4 @@
-require "spec_helper"
+# frozen_string_literal: true
RSpec.describe <%= config[:constant_name] %> do
it "has a version number" do
diff --git a/lib/bundler/templates/newgem/spec/spec_helper.rb.tt b/lib/bundler/templates/newgem/spec/spec_helper.rb.tt
index 805cf57e01..70c6d1fcde 100644
--- a/lib/bundler/templates/newgem/spec/spec_helper.rb.tt
+++ b/lib/bundler/templates/newgem/spec/spec_helper.rb.tt
@@ -1,4 +1,5 @@
-require "bundler/setup"
+# frozen_string_literal: true
+
require "<%= config[:namespaced_path] %>"
RSpec.configure do |config|
diff --git a/lib/bundler/templates/newgem/standard.yml.tt b/lib/bundler/templates/newgem/standard.yml.tt
new file mode 100644
index 0000000000..9e88fbbe8b
--- /dev/null
+++ b/lib/bundler/templates/newgem/standard.yml.tt
@@ -0,0 +1,2 @@
+# For available configuration options, see:
+# https://github.com/testdouble/standard
diff --git a/lib/bundler/templates/newgem/test/minitest/newgem_test.rb.tt b/lib/bundler/templates/newgem/test/minitest/newgem_test.rb.tt
new file mode 100644
index 0000000000..9e005d69a8
--- /dev/null
+++ b/lib/bundler/templates/newgem/test/minitest/newgem_test.rb.tt
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require "test_helper"
+
+class <%= config[:constant_name] %>Test < Minitest::Test
+ def test_that_it_has_a_version_number
+ refute_nil ::<%= config[:constant_name] %>::VERSION
+ end
+
+ def test_it_does_something_useful
+ assert false
+ end
+end
diff --git a/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt b/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt
new file mode 100644
index 0000000000..e05c387bfa
--- /dev/null
+++ b/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
+require "<%= config[:namespaced_path] %>"
+
+require "minitest/autorun"
diff --git a/lib/bundler/templates/newgem/test/newgem_test.rb.tt b/lib/bundler/templates/newgem/test/newgem_test.rb.tt
deleted file mode 100644
index f2af9f90e0..0000000000
--- a/lib/bundler/templates/newgem/test/newgem_test.rb.tt
+++ /dev/null
@@ -1,11 +0,0 @@
-require "test_helper"
-
-class <%= config[:constant_name] %>Test < Minitest::Test
- def test_that_it_has_a_version_number
- refute_nil ::<%= config[:constant_name] %>::VERSION
- end
-
- def test_it_does_something_useful
- assert false
- end
-end
diff --git a/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt b/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt
new file mode 100644
index 0000000000..5c61094e62
--- /dev/null
+++ b/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require "test_helper"
+
+class <%= config[:constant_name] %>Test < Test::Unit::TestCase
+ test "VERSION" do
+ assert do
+ ::<%= config[:constant_name] %>.const_defined?(:VERSION)
+ end
+ end
+
+ test "something useful" do
+ assert_equal("expected", "actual")
+ end
+end
diff --git a/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt b/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt
new file mode 100644
index 0000000000..6f633c6039
--- /dev/null
+++ b/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
+require "<%= config[:namespaced_path] %>"
+
+require "test-unit"
diff --git a/lib/bundler/templates/newgem/test/test_helper.rb.tt b/lib/bundler/templates/newgem/test/test_helper.rb.tt
deleted file mode 100644
index 725e3e4647..0000000000
--- a/lib/bundler/templates/newgem/test/test_helper.rb.tt
+++ /dev/null
@@ -1,4 +0,0 @@
-$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
-require "<%= config[:namespaced_path] %>"
-
-require "minitest/autorun"
diff --git a/lib/bundler/templates/newgem/travis.yml.tt b/lib/bundler/templates/newgem/travis.yml.tt
index fe0761cc23..eab16addca 100644
--- a/lib/bundler/templates/newgem/travis.yml.tt
+++ b/lib/bundler/templates/newgem/travis.yml.tt
@@ -1,5 +1,6 @@
-sudo: false
+---
language: ruby
+cache: bundler
rvm:
- <%= RUBY_VERSION %>
before_install: gem install bundler -v <%= Bundler::VERSION %>
diff --git a/lib/bundler/ui.rb b/lib/bundler/ui.rb
index 794c000dc4..7a4fa03669 100644
--- a/lib/bundler/ui.rb
+++ b/lib/bundler/ui.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: true
+
module Bundler
module UI
- autoload :RGProxy, "bundler/ui/rg_proxy"
- autoload :Shell, "bundler/ui/shell"
- autoload :Silent, "bundler/ui/silent"
+ autoload :RGProxy, File.expand_path("ui/rg_proxy", __dir__)
+ autoload :Shell, File.expand_path("ui/shell", __dir__)
+ autoload :Silent, File.expand_path("ui/silent", __dir__)
end
end
diff --git a/lib/bundler/ui/rg_proxy.rb b/lib/bundler/ui/rg_proxy.rb
index 95a1ecdf0c..ef6def225b 100644
--- a/lib/bundler/ui/rg_proxy.rb
+++ b/lib/bundler/ui/rg_proxy.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require "bundler/ui"
+
+require_relative "../ui"
require "rubygems/user_interaction"
module Bundler
diff --git a/lib/bundler/ui/shell.rb b/lib/bundler/ui/shell.rb
index 87a92471fb..17777af4ac 100644
--- a/lib/bundler/ui/shell.rb
+++ b/lib/bundler/ui/shell.rb
@@ -1,17 +1,16 @@
# frozen_string_literal: true
-require "bundler/vendored_thor"
+
+require_relative "../vendored_thor"
module Bundler
module UI
class Shell
- LEVELS = %w(silent error warn confirm info debug).freeze
+ LEVELS = %w[silent error warn confirm info debug].freeze
attr_writer :shell
def initialize(options = {})
- if options["no-color"] || !STDOUT.tty?
- Thor::Base.shell = Thor::Shell::Basic
- end
+ Thor::Base.shell = options["no-color"] ? Thor::Shell::Basic : nil
@shell = Thor::Base.shell.new
@level = ENV["DEBUG"] ? "debug" : "info"
@warning_history = []
@@ -29,14 +28,17 @@ module Bundler
tell_me(msg, :green, newline) if level("confirm")
end
- def warn(msg, newline = nil)
+ def warn(msg, newline = nil, color = :yellow)
+ return unless level("warn")
return if @warning_history.include? msg
@warning_history << msg
- tell_me(msg, :yellow, newline) if level("warn")
+
+ tell_err(msg, color, newline)
end
- def error(msg, newline = nil)
- tell_me(msg, :red, newline) if level("error")
+ def error(msg, newline = nil, color = :red)
+ return unless level("error")
+ tell_err(msg, color, newline)
end
def debug(msg, newline = nil)
@@ -90,7 +92,7 @@ module Bundler
[]
end
- private
+ private
# valimism
def tell_me(msg, color = nil, newline = nil)
@@ -103,6 +105,13 @@ module Bundler
end
def tell_err(message, color = nil, newline = nil)
+ return if @shell.send(:stderr).closed?
+
+ newline ||= message.to_s !~ /( |\t)\Z/
+ message = word_wrap(message) if newline.is_a?(Hash) && newline[:wrap]
+
+ color = nil if color && !$stderr.tty?
+
buffer = @shell.send(:prepare_message, message, *color)
buffer << "\n" if newline && !message.to_s.end_with?("\n")
diff --git a/lib/bundler/ui/silent.rb b/lib/bundler/ui/silent.rb
index 48390b7198..dca1b2ac86 100644
--- a/lib/bundler/ui/silent.rb
+++ b/lib/bundler/ui/silent.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler
module UI
class Silent
diff --git a/lib/bundler/uri_credentials_filter.rb b/lib/bundler/uri_credentials_filter.rb
index 997a307533..ccfaf0bc5d 100644
--- a/lib/bundler/uri_credentials_filter.rb
+++ b/lib/bundler/uri_credentials_filter.rb
@@ -1,12 +1,19 @@
# frozen_string_literal: true
+
module Bundler
module URICredentialsFilter
- module_function
+ module_function
def credential_filtered_uri(uri_to_anonymize)
return uri_to_anonymize if uri_to_anonymize.nil?
uri = uri_to_anonymize.dup
- uri = URI(uri.to_s) unless uri.is_a?(URI)
+ if uri.is_a?(String)
+ return uri if File.exist?(uri)
+
+ require_relative "vendored_uri"
+ uri = Bundler::URI(uri)
+ end
+
if uri.userinfo
# oauth authentication
if uri.password == "x-oauth-basic" || uri.password == "x"
@@ -16,9 +23,9 @@ module Bundler
end
uri.password = nil
end
- return uri if uri_to_anonymize.is_a?(URI)
return uri.to_s if uri_to_anonymize.is_a?(String)
- rescue URI::InvalidURIError # uri is not canonical uri scheme
+ uri
+ rescue Bundler::URI::InvalidURIError # uri is not canonical uri scheme
uri
end
diff --git a/lib/bundler/vendor/.document b/lib/bundler/vendor/.document
new file mode 100644
index 0000000000..0c43bbd6b3
--- /dev/null
+++ b/lib/bundler/vendor/.document
@@ -0,0 +1 @@
+# Vendored files do not need to be documented
diff --git a/lib/bundler/vendor/connection_pool/LICENSE b/lib/bundler/vendor/connection_pool/LICENSE
new file mode 100644
index 0000000000..7673cbfb7a
--- /dev/null
+++ b/lib/bundler/vendor/connection_pool/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Mike Perham
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/bundler/vendor/connection_pool/lib/connection_pool.rb b/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
new file mode 100644
index 0000000000..984c1c3dcb
--- /dev/null
+++ b/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
@@ -0,0 +1,126 @@
+require "timeout"
+require_relative "connection_pool/version"
+
+class Bundler::ConnectionPool
+ class Error < ::RuntimeError; end
+ class PoolShuttingDownError < ::Bundler::ConnectionPool::Error; end
+ class TimeoutError < ::Timeout::Error; end
+end
+
+# Generic connection pool class for sharing a limited number of objects or network connections
+# among many threads. Note: pool elements are lazily created.
+#
+# Example usage with block (faster):
+#
+# @pool = Bundler::ConnectionPool.new { Redis.new }
+# @pool.with do |redis|
+# redis.lpop('my-list') if redis.llen('my-list') > 0
+# end
+#
+# Using optional timeout override (for that single invocation)
+#
+# @pool.with(timeout: 2.0) do |redis|
+# redis.lpop('my-list') if redis.llen('my-list') > 0
+# end
+#
+# Example usage replacing an existing connection (slower):
+#
+# $redis = Bundler::ConnectionPool.wrap { Redis.new }
+#
+# def do_work
+# $redis.lpop('my-list') if $redis.llen('my-list') > 0
+# end
+#
+# Accepts the following options:
+# - :size - number of connections to pool, defaults to 5
+# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
+#
+class Bundler::ConnectionPool
+ DEFAULTS = {size: 5, timeout: 5}
+
+ def self.wrap(options, &block)
+ Wrapper.new(options, &block)
+ end
+
+ def initialize(options = {}, &block)
+ raise ArgumentError, "Connection pool requires a block" unless block
+
+ options = DEFAULTS.merge(options)
+
+ @size = Integer(options.fetch(:size))
+ @timeout = options.fetch(:timeout)
+
+ @available = TimedStack.new(@size, &block)
+ @key = :"pool-#{@available.object_id}"
+ @key_count = :"pool-#{@available.object_id}-count"
+ end
+
+ def with(options = {})
+ Thread.handle_interrupt(Exception => :never) do
+ conn = checkout(options)
+ begin
+ Thread.handle_interrupt(Exception => :immediate) do
+ yield conn
+ end
+ ensure
+ checkin
+ end
+ end
+ end
+ alias then with
+
+ def checkout(options = {})
+ if ::Thread.current[@key]
+ ::Thread.current[@key_count] += 1
+ ::Thread.current[@key]
+ else
+ ::Thread.current[@key_count] = 1
+ ::Thread.current[@key] = @available.pop(options[:timeout] || @timeout)
+ end
+ end
+
+ def checkin
+ if ::Thread.current[@key]
+ if ::Thread.current[@key_count] == 1
+ @available.push(::Thread.current[@key])
+ ::Thread.current[@key] = nil
+ ::Thread.current[@key_count] = nil
+ else
+ ::Thread.current[@key_count] -= 1
+ end
+ else
+ raise Bundler::ConnectionPool::Error, "no connections are checked out"
+ end
+
+ nil
+ end
+
+ ##
+ # Shuts down the Bundler::ConnectionPool by passing each connection to +block+ and
+ # then removing it from the pool. Attempting to checkout a connection after
+ # shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+.
+
+ def shutdown(&block)
+ @available.shutdown(&block)
+ end
+
+ ##
+ # Reloads the Bundler::ConnectionPool by passing each connection to +block+ and then
+ # removing it the pool. Subsequent checkouts will create new connections as
+ # needed.
+
+ def reload(&block)
+ @available.shutdown(reload: true, &block)
+ end
+
+ # Size of this connection pool
+ attr_reader :size
+
+ # Number of pool entries available for checkout at this instant.
+ def available
+ @available.length
+ end
+end
+
+require_relative "connection_pool/timed_stack"
+require_relative "connection_pool/wrapper"
diff --git a/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb b/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb
new file mode 100644
index 0000000000..a7b1cf06a8
--- /dev/null
+++ b/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb
@@ -0,0 +1,174 @@
+##
+# The TimedStack manages a pool of homogeneous connections (or any resource
+# you wish to manage). Connections are created lazily up to a given maximum
+# number.
+
+# Examples:
+#
+# ts = TimedStack.new(1) { MyConnection.new }
+#
+# # fetch a connection
+# conn = ts.pop
+#
+# # return a connection
+# ts.push conn
+#
+# conn = ts.pop
+# ts.pop timeout: 5
+# #=> raises Bundler::ConnectionPool::TimeoutError after 5 seconds
+
+class Bundler::ConnectionPool::TimedStack
+ attr_reader :max
+
+ ##
+ # Creates a new pool with +size+ connections that are created from the given
+ # +block+.
+
+ def initialize(size = 0, &block)
+ @create_block = block
+ @created = 0
+ @que = []
+ @max = size
+ @mutex = Thread::Mutex.new
+ @resource = Thread::ConditionVariable.new
+ @shutdown_block = nil
+ end
+
+ ##
+ # Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be
+ # used by subclasses that extend TimedStack.
+
+ def push(obj, options = {})
+ @mutex.synchronize do
+ if @shutdown_block
+ @shutdown_block.call(obj)
+ else
+ store_connection obj, options
+ end
+
+ @resource.broadcast
+ end
+ end
+ alias << push
+
+ ##
+ # Retrieves a connection from the stack. If a connection is available it is
+ # immediately returned. If no connection is available within the given
+ # timeout a Bundler::ConnectionPool::TimeoutError is raised.
+ #
+ # +:timeout+ is the only checked entry in +options+ and is preferred over
+ # the +timeout+ argument (which will be removed in a future release). Other
+ # options may be used by subclasses that extend TimedStack.
+
+ def pop(timeout = 0.5, options = {})
+ options, timeout = timeout, 0.5 if Hash === timeout
+ timeout = options.fetch :timeout, timeout
+
+ deadline = current_time + timeout
+ @mutex.synchronize do
+ loop do
+ raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
+ return fetch_connection(options) if connection_stored?(options)
+
+ connection = try_create(options)
+ return connection if connection
+
+ to_wait = deadline - current_time
+ raise Bundler::ConnectionPool::TimeoutError, "Waited #{timeout} sec" if to_wait <= 0
+ @resource.wait(@mutex, to_wait)
+ end
+ end
+ end
+
+ ##
+ # Shuts down the TimedStack by passing each connection to +block+ and then
+ # removing it from the pool. Attempting to checkout a connection after
+ # shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+ unless
+ # +:reload+ is +true+.
+
+ def shutdown(reload: false, &block)
+ raise ArgumentError, "shutdown must receive a block" unless block_given?
+
+ @mutex.synchronize do
+ @shutdown_block = block
+ @resource.broadcast
+
+ shutdown_connections
+ @shutdown_block = nil if reload
+ end
+ end
+
+ ##
+ # Returns +true+ if there are no available connections.
+
+ def empty?
+ (@created - @que.length) >= @max
+ end
+
+ ##
+ # The number of connections available on the stack.
+
+ def length
+ @max - @created + @que.length
+ end
+
+ private
+
+ def current_time
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ end
+
+ ##
+ # This is an extension point for TimedStack and is called with a mutex.
+ #
+ # This method must returns true if a connection is available on the stack.
+
+ def connection_stored?(options = nil)
+ !@que.empty?
+ end
+
+ ##
+ # This is an extension point for TimedStack and is called with a mutex.
+ #
+ # This method must return a connection from the stack.
+
+ def fetch_connection(options = nil)
+ @que.pop
+ end
+
+ ##
+ # This is an extension point for TimedStack and is called with a mutex.
+ #
+ # This method must shut down all connections on the stack.
+
+ def shutdown_connections(options = nil)
+ while connection_stored?(options)
+ conn = fetch_connection(options)
+ @shutdown_block.call(conn)
+ end
+ @created = 0
+ end
+
+ ##
+ # This is an extension point for TimedStack and is called with a mutex.
+ #
+ # This method must return +obj+ to the stack.
+
+ def store_connection(obj, options = nil)
+ @que.push obj
+ end
+
+ ##
+ # This is an extension point for TimedStack and is called with a mutex.
+ #
+ # This method must create a connection if and only if the total number of
+ # connections allowed has not been met.
+
+ def try_create(options = nil)
+ unless @created == @max
+ object = @create_block.call
+ @created += 1
+ object
+ end
+ end
+end
diff --git a/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb b/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
new file mode 100644
index 0000000000..56ebf69902
--- /dev/null
+++ b/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
@@ -0,0 +1,3 @@
+class Bundler::ConnectionPool
+ VERSION = "2.3.0"
+end
diff --git a/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb b/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb
new file mode 100644
index 0000000000..880170c06b
--- /dev/null
+++ b/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb
@@ -0,0 +1,57 @@
+class Bundler::ConnectionPool
+ class Wrapper < ::BasicObject
+ METHODS = [:with, :pool_shutdown, :wrapped_pool]
+
+ def initialize(options = {}, &block)
+ @pool = options.fetch(:pool) { ::Bundler::ConnectionPool.new(options, &block) }
+ end
+
+ def wrapped_pool
+ @pool
+ end
+
+ def with(&block)
+ @pool.with(&block)
+ end
+
+ def pool_shutdown(&block)
+ @pool.shutdown(&block)
+ end
+
+ def pool_size
+ @pool.size
+ end
+
+ def pool_available
+ @pool.available
+ end
+
+ def respond_to?(id, *args)
+ METHODS.include?(id) || with { |c| c.respond_to?(id, *args) }
+ end
+
+ # rubocop:disable Style/MethodMissingSuper
+ # rubocop:disable Style/MissingRespondToMissing
+ if ::RUBY_VERSION >= "3.0.0"
+ def method_missing(name, *args, **kwargs, &block)
+ with do |connection|
+ connection.send(name, *args, **kwargs, &block)
+ end
+ end
+ elsif ::RUBY_VERSION >= "2.7.0"
+ ruby2_keywords def method_missing(name, *args, &block)
+ with do |connection|
+ connection.send(name, *args, &block)
+ end
+ end
+ else
+ def method_missing(name, *args, &block)
+ with do |connection|
+ connection.send(name, *args, &block)
+ end
+ end
+ end
+ # rubocop:enable Style/MethodMissingSuper
+ # rubocop:enable Style/MissingRespondToMissing
+ end
+end
diff --git a/lib/bundler/vendor/fileutils/LICENSE.txt b/lib/bundler/vendor/fileutils/LICENSE.txt
new file mode 100644
index 0000000000..a009caefea
--- /dev/null
+++ b/lib/bundler/vendor/fileutils/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/lib/bundler/vendor/fileutils/lib/fileutils.rb b/lib/bundler/vendor/fileutils/lib/fileutils.rb
new file mode 100644
index 0000000000..8f8faf30c8
--- /dev/null
+++ b/lib/bundler/vendor/fileutils/lib/fileutils.rb
@@ -0,0 +1,1764 @@
+# frozen_string_literal: true
+
+begin
+ require 'rbconfig'
+rescue LoadError
+ # for make mjit-headers
+end
+
+#
+# = fileutils.rb
+#
+# Copyright (c) 2000-2007 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+#
+# == module Bundler::FileUtils
+#
+# Namespace for several file utility methods for copying, moving, removing, etc.
+#
+# === Module Functions
+#
+# require 'bundler/vendor/fileutils/lib/fileutils'
+#
+# Bundler::FileUtils.cd(dir, **options)
+# Bundler::FileUtils.cd(dir, **options) {|dir| block }
+# Bundler::FileUtils.pwd()
+# Bundler::FileUtils.mkdir(dir, **options)
+# Bundler::FileUtils.mkdir(list, **options)
+# Bundler::FileUtils.mkdir_p(dir, **options)
+# Bundler::FileUtils.mkdir_p(list, **options)
+# Bundler::FileUtils.rmdir(dir, **options)
+# Bundler::FileUtils.rmdir(list, **options)
+# Bundler::FileUtils.ln(target, link, **options)
+# Bundler::FileUtils.ln(targets, dir, **options)
+# Bundler::FileUtils.ln_s(target, link, **options)
+# Bundler::FileUtils.ln_s(targets, dir, **options)
+# Bundler::FileUtils.ln_sf(target, link, **options)
+# Bundler::FileUtils.cp(src, dest, **options)
+# Bundler::FileUtils.cp(list, dir, **options)
+# Bundler::FileUtils.cp_r(src, dest, **options)
+# Bundler::FileUtils.cp_r(list, dir, **options)
+# Bundler::FileUtils.mv(src, dest, **options)
+# Bundler::FileUtils.mv(list, dir, **options)
+# Bundler::FileUtils.rm(list, **options)
+# Bundler::FileUtils.rm_r(list, **options)
+# Bundler::FileUtils.rm_rf(list, **options)
+# Bundler::FileUtils.install(src, dest, **options)
+# Bundler::FileUtils.chmod(mode, list, **options)
+# Bundler::FileUtils.chmod_R(mode, list, **options)
+# Bundler::FileUtils.chown(user, group, list, **options)
+# Bundler::FileUtils.chown_R(user, group, list, **options)
+# Bundler::FileUtils.touch(list, **options)
+#
+# Possible <tt>options</tt> are:
+#
+# <tt>:force</tt> :: forced operation (rewrite files if exist, remove
+# directories if not empty, etc.);
+# <tt>:verbose</tt> :: print command to be run, in bash syntax, before
+# performing it;
+# <tt>:preserve</tt> :: preserve object's group, user and modification
+# time on copying;
+# <tt>:noop</tt> :: no changes are made (usable in combination with
+# <tt>:verbose</tt> which will print the command to run)
+#
+# Each method documents the options that it honours. See also ::commands,
+# ::options and ::options_of methods to introspect which command have which
+# options.
+#
+# All methods that have the concept of a "source" file or directory can take
+# either one file or a list of files in that argument. See the method
+# documentation for examples.
+#
+# There are some `low level' methods, which do not accept keyword arguments:
+#
+# Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
+# Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
+# Bundler::FileUtils.copy_stream(srcstream, deststream)
+# Bundler::FileUtils.remove_entry(path, force = false)
+# Bundler::FileUtils.remove_entry_secure(path, force = false)
+# Bundler::FileUtils.remove_file(path, force = false)
+# Bundler::FileUtils.compare_file(path_a, path_b)
+# Bundler::FileUtils.compare_stream(stream_a, stream_b)
+# Bundler::FileUtils.uptodate?(file, cmp_list)
+#
+# == module Bundler::FileUtils::Verbose
+#
+# This module has all methods of Bundler::FileUtils module, but it outputs messages
+# before acting. This equates to passing the <tt>:verbose</tt> flag to methods
+# in Bundler::FileUtils.
+#
+# == module Bundler::FileUtils::NoWrite
+#
+# This module has all methods of Bundler::FileUtils module, but never changes
+# files/directories. This equates to passing the <tt>:noop</tt> flag to methods
+# in Bundler::FileUtils.
+#
+# == module Bundler::FileUtils::DryRun
+#
+# This module has all methods of Bundler::FileUtils module, but never changes
+# files/directories. This equates to passing the <tt>:noop</tt> and
+# <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
+#
+module Bundler::FileUtils
+ VERSION = "1.4.1"
+
+ def self.private_module_function(name) #:nodoc:
+ module_function name
+ private_class_method name
+ end
+
+ #
+ # Returns the name of the current directory.
+ #
+ def pwd
+ Dir.pwd
+ end
+ module_function :pwd
+
+ alias getwd pwd
+ module_function :getwd
+
+ #
+ # Changes the current directory to the directory +dir+.
+ #
+ # If this method is called with block, resumes to the previous
+ # working directory after the block execution has finished.
+ #
+ # Bundler::FileUtils.cd('/') # change directory
+ #
+ # Bundler::FileUtils.cd('/', verbose: true) # change directory and report it
+ #
+ # Bundler::FileUtils.cd('/') do # change directory
+ # # ... # do something
+ # end # return to original directory
+ #
+ def cd(dir, verbose: nil, &block) # :yield: dir
+ fu_output_message "cd #{dir}" if verbose
+ result = Dir.chdir(dir, &block)
+ fu_output_message 'cd -' if verbose and block
+ result
+ end
+ module_function :cd
+
+ alias chdir cd
+ module_function :chdir
+
+ #
+ # Returns true if +new+ is newer than all +old_list+.
+ # Non-existent files are older than any file.
+ #
+ # Bundler::FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \
+ # system 'make hello.o'
+ #
+ def uptodate?(new, old_list)
+ return false unless File.exist?(new)
+ new_time = File.mtime(new)
+ old_list.each do |old|
+ if File.exist?(old)
+ return false unless new_time > File.mtime(old)
+ end
+ end
+ true
+ end
+ module_function :uptodate?
+
+ def remove_trailing_slash(dir) #:nodoc:
+ dir == '/' ? dir : dir.chomp(?/)
+ end
+ private_module_function :remove_trailing_slash
+
+ #
+ # Creates one or more directories.
+ #
+ # Bundler::FileUtils.mkdir 'test'
+ # Bundler::FileUtils.mkdir %w(tmp data)
+ # Bundler::FileUtils.mkdir 'notexist', noop: true # Does not really create.
+ # Bundler::FileUtils.mkdir 'tmp', mode: 0700
+ #
+ def mkdir(list, mode: nil, noop: nil, verbose: nil)
+ list = fu_list(list)
+ fu_output_message "mkdir #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
+ return if noop
+
+ list.each do |dir|
+ fu_mkdir dir, mode
+ end
+ end
+ module_function :mkdir
+
+ #
+ # Creates a directory and all its parent directories.
+ # For example,
+ #
+ # Bundler::FileUtils.mkdir_p '/usr/local/lib/ruby'
+ #
+ # causes to make following directories, if they do not exist.
+ #
+ # * /usr
+ # * /usr/local
+ # * /usr/local/lib
+ # * /usr/local/lib/ruby
+ #
+ # You can pass several directories at a time in a list.
+ #
+ def mkdir_p(list, mode: nil, noop: nil, verbose: nil)
+ list = fu_list(list)
+ fu_output_message "mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
+ return *list if noop
+
+ list.map {|path| remove_trailing_slash(path)}.each do |path|
+ # optimize for the most common case
+ begin
+ fu_mkdir path, mode
+ next
+ rescue SystemCallError
+ next if File.directory?(path)
+ end
+
+ stack = []
+ until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/"
+ stack.push path
+ path = File.dirname(path)
+ end
+ stack.pop # root directory should exist
+ stack.reverse_each do |dir|
+ begin
+ fu_mkdir dir, mode
+ rescue SystemCallError
+ raise unless File.directory?(dir)
+ end
+ end
+ end
+
+ return *list
+ end
+ module_function :mkdir_p
+
+ alias mkpath mkdir_p
+ alias makedirs mkdir_p
+ module_function :mkpath
+ module_function :makedirs
+
+ def fu_mkdir(path, mode) #:nodoc:
+ path = remove_trailing_slash(path)
+ if mode
+ Dir.mkdir path, mode
+ File.chmod mode, path
+ else
+ Dir.mkdir path
+ end
+ end
+ private_module_function :fu_mkdir
+
+ #
+ # Removes one or more directories.
+ #
+ # Bundler::FileUtils.rmdir 'somedir'
+ # Bundler::FileUtils.rmdir %w(somedir anydir otherdir)
+ # # Does not really remove directory; outputs message.
+ # Bundler::FileUtils.rmdir 'somedir', verbose: true, noop: true
+ #
+ def rmdir(list, parents: nil, noop: nil, verbose: nil)
+ list = fu_list(list)
+ fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
+ return if noop
+ list.each do |dir|
+ Dir.rmdir(dir = remove_trailing_slash(dir))
+ if parents
+ begin
+ until (parent = File.dirname(dir)) == '.' or parent == dir
+ dir = parent
+ Dir.rmdir(dir)
+ end
+ rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
+ end
+ end
+ end
+ end
+ module_function :rmdir
+
+ #
+ # :call-seq:
+ # Bundler::FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil)
+ # Bundler::FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
+ # Bundler::FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
+ #
+ # In the first form, creates a hard link +link+ which points to +target+.
+ # If +link+ already exists, raises Errno::EEXIST.
+ # But if the +force+ option is set, overwrites +link+.
+ #
+ # Bundler::FileUtils.ln 'gcc', 'cc', verbose: true
+ # Bundler::FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
+ #
+ # In the second form, creates a link +dir/target+ pointing to +target+.
+ # In the third form, creates several hard links in the directory +dir+,
+ # pointing to each item in +targets+.
+ # If +dir+ is not a directory, raises Errno::ENOTDIR.
+ #
+ # Bundler::FileUtils.cd '/sbin'
+ # Bundler::FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked.
+ #
+ def ln(src, dest, force: nil, noop: nil, verbose: nil)
+ fu_output_message "ln#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest0(src, dest) do |s,d|
+ remove_file d, true if force
+ File.link s, d
+ end
+ end
+ module_function :ln
+
+ alias link ln
+ module_function :link
+
+ #
+ # Hard link +src+ to +dest+. If +src+ is a directory, this method links
+ # all its contents recursively. If +dest+ is a directory, links
+ # +src+ to +dest/src+.
+ #
+ # +src+ can be a list of files.
+ #
+ # If +dereference_root+ is true, this method dereference tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
+ # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
+ # Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
+ #
+ # # Examples of linking several files to target directory.
+ # Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
+ # Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true
+ #
+ # # If you want to link all contents of a directory instead of the
+ # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
+ # # use the following code.
+ # Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
+ #
+ def cp_lr(src, dest, noop: nil, verbose: nil,
+ dereference_root: true, remove_destination: false)
+ fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest(src, dest) do |s, d|
+ link_entry s, d, dereference_root, remove_destination
+ end
+ end
+ module_function :cp_lr
+
+ #
+ # :call-seq:
+ # Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
+ # Bundler::FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
+ # Bundler::FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
+ #
+ # In the first form, creates a symbolic link +link+ which points to +target+.
+ # If +link+ already exists, raises Errno::EEXIST.
+ # But if the <tt>force</tt> option is set, overwrites +link+.
+ #
+ # Bundler::FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
+ # Bundler::FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
+ #
+ # In the second form, creates a link +dir/target+ pointing to +target+.
+ # In the third form, creates several symbolic links in the directory +dir+,
+ # pointing to each item in +targets+.
+ # If +dir+ is not a directory, raises Errno::ENOTDIR.
+ #
+ # Bundler::FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
+ #
+ def ln_s(src, dest, force: nil, noop: nil, verbose: nil)
+ fu_output_message "ln -s#{force ? 'f' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest0(src, dest) do |s,d|
+ remove_file d, true if force
+ File.symlink s, d
+ end
+ end
+ module_function :ln_s
+
+ alias symlink ln_s
+ module_function :symlink
+
+ #
+ # :call-seq:
+ # Bundler::FileUtils.ln_sf(*args)
+ #
+ # Same as
+ #
+ # Bundler::FileUtils.ln_s(*args, force: true)
+ #
+ def ln_sf(src, dest, noop: nil, verbose: nil)
+ ln_s src, dest, force: true, noop: noop, verbose: verbose
+ end
+ module_function :ln_sf
+
+ #
+ # Hard links a file system entry +src+ to +dest+.
+ # If +src+ is a directory, this method links its contents recursively.
+ #
+ # Both of +src+ and +dest+ must be a path name.
+ # +src+ must exist, +dest+ must not exist.
+ #
+ # If +dereference_root+ is true, this method dereferences the tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
+ def link_entry(src, dest, dereference_root = false, remove_destination = false)
+ Entry_.new(src, nil, dereference_root).traverse do |ent|
+ destent = Entry_.new(dest, ent.rel, false)
+ File.unlink destent.path if remove_destination && File.file?(destent.path)
+ ent.link destent.path
+ end
+ end
+ module_function :link_entry
+
+ #
+ # Copies a file content +src+ to +dest+. If +dest+ is a directory,
+ # copies +src+ to +dest/src+.
+ #
+ # If +src+ is a list of files, then +dest+ must be a directory.
+ #
+ # Bundler::FileUtils.cp 'eval.c', 'eval.c.org'
+ # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
+ # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
+ # Bundler::FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
+ #
+ def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
+ fu_output_message "cp#{preserve ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest(src, dest) do |s, d|
+ copy_file s, d, preserve
+ end
+ end
+ module_function :cp
+
+ alias copy cp
+ module_function :copy
+
+ #
+ # Copies +src+ to +dest+. If +src+ is a directory, this method copies
+ # all its contents recursively. If +dest+ is a directory, copies
+ # +src+ to +dest/src+.
+ #
+ # +src+ can be a list of files.
+ #
+ # If +dereference_root+ is true, this method dereference tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
+ # # Installing Ruby library "mylib" under the site_ruby
+ # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
+ # Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib'
+ #
+ # # Examples of copying several files to target directory.
+ # Bundler::FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
+ # Bundler::FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true
+ #
+ # # If you want to copy all contents of a directory instead of the
+ # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
+ # # use following code.
+ # Bundler::FileUtils.cp_r 'src/.', 'dest' # cp_r('src', 'dest') makes dest/src,
+ # # but this doesn't.
+ #
+ def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil,
+ dereference_root: true, remove_destination: nil)
+ fu_output_message "cp -r#{preserve ? 'p' : ''}#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest(src, dest) do |s, d|
+ copy_entry s, d, preserve, dereference_root, remove_destination
+ end
+ end
+ module_function :cp_r
+
+ #
+ # Copies a file system entry +src+ to +dest+.
+ # If +src+ is a directory, this method copies its contents recursively.
+ # This method preserves file types, c.f. symlink, directory...
+ # (FIFO, device files and etc. are not supported yet)
+ #
+ # Both of +src+ and +dest+ must be a path name.
+ # +src+ must exist, +dest+ must not exist.
+ #
+ # If +preserve+ is true, this method preserves owner, group, and
+ # modified time. Permissions are copied regardless +preserve+.
+ #
+ # If +dereference_root+ is true, this method dereference tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
+ def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
+ if dereference_root
+ src = File.realpath(src)
+ end
+
+ Entry_.new(src, nil, false).wrap_traverse(proc do |ent|
+ destent = Entry_.new(dest, ent.rel, false)
+ File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
+ ent.copy destent.path
+ end, proc do |ent|
+ destent = Entry_.new(dest, ent.rel, false)
+ ent.copy_metadata destent.path if preserve
+ end)
+ end
+ module_function :copy_entry
+
+ #
+ # Copies file contents of +src+ to +dest+.
+ # Both of +src+ and +dest+ must be a path name.
+ #
+ def copy_file(src, dest, preserve = false, dereference = true)
+ ent = Entry_.new(src, nil, dereference)
+ ent.copy_file dest
+ ent.copy_metadata dest if preserve
+ end
+ module_function :copy_file
+
+ #
+ # Copies stream +src+ to +dest+.
+ # +src+ must respond to #read(n) and
+ # +dest+ must respond to #write(str).
+ #
+ def copy_stream(src, dest)
+ IO.copy_stream(src, dest)
+ end
+ module_function :copy_stream
+
+ #
+ # Moves file(s) +src+ to +dest+. If +file+ and +dest+ exist on the different
+ # disk partition, the file is copied then the original file is removed.
+ #
+ # Bundler::FileUtils.mv 'badname.rb', 'goodname.rb'
+ # Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
+ #
+ # Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
+ # Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
+ #
+ def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
+ fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest(src, dest) do |s, d|
+ destent = Entry_.new(d, nil, true)
+ begin
+ if destent.exist?
+ if destent.directory?
+ raise Errno::EEXIST, d
+ end
+ end
+ begin
+ File.rename s, d
+ rescue Errno::EXDEV,
+ Errno::EPERM # move from unencrypted to encrypted dir (ext4)
+ copy_entry s, d, true
+ if secure
+ remove_entry_secure s, force
+ else
+ remove_entry s, force
+ end
+ end
+ rescue SystemCallError
+ raise unless force
+ end
+ end
+ end
+ module_function :mv
+
+ alias move mv
+ module_function :move
+
+ #
+ # Remove file(s) specified in +list+. This method cannot remove directories.
+ # All StandardErrors are ignored when the :force option is set.
+ #
+ # Bundler::FileUtils.rm %w( junk.txt dust.txt )
+ # Bundler::FileUtils.rm Dir.glob('*.so')
+ # Bundler::FileUtils.rm 'NotExistFile', force: true # never raises exception
+ #
+ def rm(list, force: nil, noop: nil, verbose: nil)
+ list = fu_list(list)
+ fu_output_message "rm#{force ? ' -f' : ''} #{list.join ' '}" if verbose
+ return if noop
+
+ list.each do |path|
+ remove_file path, force
+ end
+ end
+ module_function :rm
+
+ alias remove rm
+ module_function :remove
+
+ #
+ # Equivalent to
+ #
+ # Bundler::FileUtils.rm(list, force: true)
+ #
+ def rm_f(list, noop: nil, verbose: nil)
+ rm list, force: true, noop: noop, verbose: verbose
+ end
+ module_function :rm_f
+
+ alias safe_unlink rm_f
+ module_function :safe_unlink
+
+ #
+ # remove files +list+[0] +list+[1]... If +list+[n] is a directory,
+ # removes its all contents recursively. This method ignores
+ # StandardError when :force option is set.
+ #
+ # Bundler::FileUtils.rm_r Dir.glob('/tmp/*')
+ # Bundler::FileUtils.rm_r 'some_dir', force: true
+ #
+ # WARNING: This method causes local vulnerability
+ # if one of parent directories or removing directory tree are world
+ # writable (including /tmp, whose permission is 1777), and the current
+ # process has strong privilege such as Unix super user (root), and the
+ # system has symbolic link. For secure removing, read the documentation
+ # of remove_entry_secure carefully, and set :secure option to true.
+ # Default is <tt>secure: false</tt>.
+ #
+ # NOTE: This method calls remove_entry_secure if :secure option is set.
+ # See also remove_entry_secure.
+ #
+ def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
+ list = fu_list(list)
+ fu_output_message "rm -r#{force ? 'f' : ''} #{list.join ' '}" if verbose
+ return if noop
+ list.each do |path|
+ if secure
+ remove_entry_secure path, force
+ else
+ remove_entry path, force
+ end
+ end
+ end
+ module_function :rm_r
+
+ #
+ # Equivalent to
+ #
+ # Bundler::FileUtils.rm_r(list, force: true)
+ #
+ # WARNING: This method causes local vulnerability.
+ # Read the documentation of rm_r first.
+ #
+ def rm_rf(list, noop: nil, verbose: nil, secure: nil)
+ rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
+ end
+ module_function :rm_rf
+
+ alias rmtree rm_rf
+ module_function :rmtree
+
+ #
+ # This method removes a file system entry +path+. +path+ shall be a
+ # regular file, a directory, or something. If +path+ is a directory,
+ # remove it recursively. This method is required to avoid TOCTTOU
+ # (time-of-check-to-time-of-use) local security vulnerability of rm_r.
+ # #rm_r causes security hole when:
+ #
+ # * Parent directory is world writable (including /tmp).
+ # * Removing directory tree includes world writable directory.
+ # * The system has symbolic link.
+ #
+ # To avoid this security hole, this method applies special preprocess.
+ # If +path+ is a directory, this method chown(2) and chmod(2) all
+ # removing directories. This requires the current process is the
+ # owner of the removing whole directory tree, or is the super user (root).
+ #
+ # WARNING: You must ensure that *ALL* parent directories cannot be
+ # moved by other untrusted users. For example, parent directories
+ # should not be owned by untrusted users, and should not be world
+ # writable except when the sticky bit set.
+ #
+ # WARNING: Only the owner of the removing directory tree, or Unix super
+ # user (root) should invoke this method. Otherwise this method does not
+ # work.
+ #
+ # For details of this security vulnerability, see Perl's case:
+ #
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
+ #
+ # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
+ #
+ def remove_entry_secure(path, force = false)
+ unless fu_have_symlink?
+ remove_entry path, force
+ return
+ end
+ fullpath = File.expand_path(path)
+ st = File.lstat(fullpath)
+ unless st.directory?
+ File.unlink fullpath
+ return
+ end
+ # is a directory.
+ parent_st = File.stat(File.dirname(fullpath))
+ unless parent_st.world_writable?
+ remove_entry path, force
+ return
+ end
+ unless parent_st.sticky?
+ raise ArgumentError, "parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
+ end
+
+ # freeze tree root
+ euid = Process.euid
+ dot_file = fullpath + "/."
+ begin
+ File.open(dot_file) {|f|
+ unless fu_stat_identical_entry?(st, f.stat)
+ # symlink (TOC-to-TOU attack?)
+ File.unlink fullpath
+ return
+ end
+ f.chown euid, -1
+ f.chmod 0700
+ }
+ rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
+ File.lstat(dot_file).tap {|fstat|
+ unless fu_stat_identical_entry?(st, fstat)
+ # symlink (TOC-to-TOU attack?)
+ File.unlink fullpath
+ return
+ end
+ File.chown euid, -1, dot_file
+ File.chmod 0700, dot_file
+ }
+ end
+
+ unless fu_stat_identical_entry?(st, File.lstat(fullpath))
+ # TOC-to-TOU attack?
+ File.unlink fullpath
+ return
+ end
+
+ # ---- tree root is frozen ----
+ root = Entry_.new(path)
+ root.preorder_traverse do |ent|
+ if ent.directory?
+ ent.chown euid, -1
+ ent.chmod 0700
+ end
+ end
+ root.postorder_traverse do |ent|
+ begin
+ ent.remove
+ rescue
+ raise unless force
+ end
+ end
+ rescue
+ raise unless force
+ end
+ module_function :remove_entry_secure
+
+ def fu_have_symlink? #:nodoc:
+ File.symlink nil, nil
+ rescue NotImplementedError
+ return false
+ rescue TypeError
+ return true
+ end
+ private_module_function :fu_have_symlink?
+
+ def fu_stat_identical_entry?(a, b) #:nodoc:
+ a.dev == b.dev and a.ino == b.ino
+ end
+ private_module_function :fu_stat_identical_entry?
+
+ #
+ # This method removes a file system entry +path+.
+ # +path+ might be a regular file, a directory, or something.
+ # If +path+ is a directory, remove it recursively.
+ #
+ # See also remove_entry_secure.
+ #
+ def remove_entry(path, force = false)
+ Entry_.new(path).postorder_traverse do |ent|
+ begin
+ ent.remove
+ rescue
+ raise unless force
+ end
+ end
+ rescue
+ raise unless force
+ end
+ module_function :remove_entry
+
+ #
+ # Removes a file +path+.
+ # This method ignores StandardError if +force+ is true.
+ #
+ def remove_file(path, force = false)
+ Entry_.new(path).remove_file
+ rescue
+ raise unless force
+ end
+ module_function :remove_file
+
+ #
+ # Removes a directory +dir+ and its contents recursively.
+ # This method ignores StandardError if +force+ is true.
+ #
+ def remove_dir(path, force = false)
+ remove_entry path, force # FIXME?? check if it is a directory
+ end
+ module_function :remove_dir
+
+ #
+ # Returns true if the contents of a file +a+ and a file +b+ are identical.
+ #
+ # Bundler::FileUtils.compare_file('somefile', 'somefile') #=> true
+ # Bundler::FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false
+ #
+ def compare_file(a, b)
+ return false unless File.size(a) == File.size(b)
+ File.open(a, 'rb') {|fa|
+ File.open(b, 'rb') {|fb|
+ return compare_stream(fa, fb)
+ }
+ }
+ end
+ module_function :compare_file
+
+ alias identical? compare_file
+ alias cmp compare_file
+ module_function :identical?
+ module_function :cmp
+
+ #
+ # Returns true if the contents of a stream +a+ and +b+ are identical.
+ #
+ def compare_stream(a, b)
+ bsize = fu_stream_blksize(a, b)
+
+ if RUBY_VERSION > "2.4"
+ sa = String.new(capacity: bsize)
+ sb = String.new(capacity: bsize)
+ else
+ sa = String.new
+ sb = String.new
+ end
+
+ begin
+ a.read(bsize, sa)
+ b.read(bsize, sb)
+ return true if sa.empty? && sb.empty?
+ end while sa == sb
+ false
+ end
+ module_function :compare_stream
+
+ #
+ # If +src+ is not same as +dest+, copies it and changes the permission
+ # mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+.
+ # This method removes destination before copy.
+ #
+ # Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
+ # Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
+ #
+ def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil,
+ noop: nil, verbose: nil)
+ if verbose
+ msg = +"install -c"
+ msg << ' -p' if preserve
+ msg << ' -m ' << mode_to_s(mode) if mode
+ msg << " -o #{owner}" if owner
+ msg << " -g #{group}" if group
+ msg << ' ' << [src,dest].flatten.join(' ')
+ fu_output_message msg
+ end
+ return if noop
+ uid = fu_get_uid(owner)
+ gid = fu_get_gid(group)
+ fu_each_src_dest(src, dest) do |s, d|
+ st = File.stat(s)
+ unless File.exist?(d) and compare_file(s, d)
+ remove_file d, true
+ copy_file s, d
+ File.utime st.atime, st.mtime, d if preserve
+ File.chmod fu_mode(mode, st), d if mode
+ File.chown uid, gid, d if uid or gid
+ end
+ end
+ end
+ module_function :install
+
+ def user_mask(target) #:nodoc:
+ target.each_char.inject(0) do |mask, chr|
+ case chr
+ when "u"
+ mask | 04700
+ when "g"
+ mask | 02070
+ when "o"
+ mask | 01007
+ when "a"
+ mask | 07777
+ else
+ raise ArgumentError, "invalid `who' symbol in file mode: #{chr}"
+ end
+ end
+ end
+ private_module_function :user_mask
+
+ def apply_mask(mode, user_mask, op, mode_mask) #:nodoc:
+ case op
+ when '='
+ (mode & ~user_mask) | (user_mask & mode_mask)
+ when '+'
+ mode | (user_mask & mode_mask)
+ when '-'
+ mode & ~(user_mask & mode_mask)
+ end
+ end
+ private_module_function :apply_mask
+
+ def symbolic_modes_to_i(mode_sym, path) #:nodoc:
+ mode = if File::Stat === path
+ path.mode
+ else
+ File.stat(path).mode
+ end
+ mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause|
+ target, *actions = clause.split(/([=+-])/)
+ raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty?
+ target = 'a' if target.empty?
+ user_mask = user_mask(target)
+ actions.each_slice(2) do |op, perm|
+ need_apply = op == '='
+ mode_mask = (perm || '').each_char.inject(0) do |mask, chr|
+ case chr
+ when "r"
+ mask | 0444
+ when "w"
+ mask | 0222
+ when "x"
+ mask | 0111
+ when "X"
+ if FileTest.directory? path
+ mask | 0111
+ else
+ mask
+ end
+ when "s"
+ mask | 06000
+ when "t"
+ mask | 01000
+ when "u", "g", "o"
+ if mask.nonzero?
+ current_mode = apply_mask(current_mode, user_mask, op, mask)
+ end
+ need_apply = false
+ copy_mask = user_mask(chr)
+ (current_mode & copy_mask) / (copy_mask & 0111) * (user_mask & 0111)
+ else
+ raise ArgumentError, "invalid `perm' symbol in file mode: #{chr}"
+ end
+ end
+
+ if mode_mask.nonzero? || need_apply
+ current_mode = apply_mask(current_mode, user_mask, op, mode_mask)
+ end
+ end
+ current_mode
+ end
+ end
+ private_module_function :symbolic_modes_to_i
+
+ def fu_mode(mode, path) #:nodoc:
+ mode.is_a?(String) ? symbolic_modes_to_i(mode, path) : mode
+ end
+ private_module_function :fu_mode
+
+ def mode_to_s(mode) #:nodoc:
+ mode.is_a?(String) ? mode : "%o" % mode
+ end
+ private_module_function :mode_to_s
+
+ #
+ # Changes permission bits on the named files (in +list+) to the bit pattern
+ # represented by +mode+.
+ #
+ # +mode+ is the symbolic and absolute mode can be used.
+ #
+ # Absolute mode is
+ # Bundler::FileUtils.chmod 0755, 'somecommand'
+ # Bundler::FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
+ # Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true
+ #
+ # Symbolic mode is
+ # Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand'
+ # Bundler::FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
+ # Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true
+ #
+ # "a" :: is user, group, other mask.
+ # "u" :: is user's mask.
+ # "g" :: is group's mask.
+ # "o" :: is other's mask.
+ # "w" :: is write permission.
+ # "r" :: is read permission.
+ # "x" :: is execute permission.
+ # "X" ::
+ # is execute permission for directories only, must be used in conjunction with "+"
+ # "s" :: is uid, gid.
+ # "t" :: is sticky bit.
+ # "+" :: is added to a class given the specified mode.
+ # "-" :: Is removed from a given class given mode.
+ # "=" :: Is the exact nature of the class will be given a specified mode.
+
+ def chmod(mode, list, noop: nil, verbose: nil)
+ list = fu_list(list)
+ fu_output_message sprintf('chmod %s %s', mode_to_s(mode), list.join(' ')) if verbose
+ return if noop
+ list.each do |path|
+ Entry_.new(path).chmod(fu_mode(mode, path))
+ end
+ end
+ module_function :chmod
+
+ #
+ # Changes permission bits on the named files (in +list+)
+ # to the bit pattern represented by +mode+.
+ #
+ # Bundler::FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
+ # Bundler::FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
+ #
+ def chmod_R(mode, list, noop: nil, verbose: nil, force: nil)
+ list = fu_list(list)
+ fu_output_message sprintf('chmod -R%s %s %s',
+ (force ? 'f' : ''),
+ mode_to_s(mode), list.join(' ')) if verbose
+ return if noop
+ list.each do |root|
+ Entry_.new(root).traverse do |ent|
+ begin
+ ent.chmod(fu_mode(mode, ent.path))
+ rescue
+ raise unless force
+ end
+ end
+ end
+ end
+ module_function :chmod_R
+
+ #
+ # Changes owner and group on the named files (in +list+)
+ # to the user +user+ and the group +group+. +user+ and +group+
+ # may be an ID (Integer/String) or a name (String).
+ # If +user+ or +group+ is nil, this method does not change
+ # the attribute.
+ #
+ # Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
+ # Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true
+ #
+ def chown(user, group, list, noop: nil, verbose: nil)
+ list = fu_list(list)
+ fu_output_message sprintf('chown %s %s',
+ (group ? "#{user}:#{group}" : user || ':'),
+ list.join(' ')) if verbose
+ return if noop
+ uid = fu_get_uid(user)
+ gid = fu_get_gid(group)
+ list.each do |path|
+ Entry_.new(path).chown uid, gid
+ end
+ end
+ module_function :chown
+
+ #
+ # Changes owner and group on the named files (in +list+)
+ # to the user +user+ and the group +group+ recursively.
+ # +user+ and +group+ may be an ID (Integer/String) or
+ # a name (String). If +user+ or +group+ is nil, this
+ # method does not change the attribute.
+ #
+ # Bundler::FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
+ # Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true
+ #
+ def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
+ list = fu_list(list)
+ fu_output_message sprintf('chown -R%s %s %s',
+ (force ? 'f' : ''),
+ (group ? "#{user}:#{group}" : user || ':'),
+ list.join(' ')) if verbose
+ return if noop
+ uid = fu_get_uid(user)
+ gid = fu_get_gid(group)
+ list.each do |root|
+ Entry_.new(root).traverse do |ent|
+ begin
+ ent.chown uid, gid
+ rescue
+ raise unless force
+ end
+ end
+ end
+ end
+ module_function :chown_R
+
+ def fu_get_uid(user) #:nodoc:
+ return nil unless user
+ case user
+ when Integer
+ user
+ when /\A\d+\z/
+ user.to_i
+ else
+ require 'etc'
+ Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
+ end
+ end
+ private_module_function :fu_get_uid
+
+ def fu_get_gid(group) #:nodoc:
+ return nil unless group
+ case group
+ when Integer
+ group
+ when /\A\d+\z/
+ group.to_i
+ else
+ require 'etc'
+ Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
+ end
+ end
+ private_module_function :fu_get_gid
+
+ #
+ # Updates modification time (mtime) and access time (atime) of file(s) in
+ # +list+. Files are created if they don't exist.
+ #
+ # Bundler::FileUtils.touch 'timestamp'
+ # Bundler::FileUtils.touch Dir.glob('*.c'); system 'make'
+ #
+ def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
+ list = fu_list(list)
+ t = mtime
+ if verbose
+ fu_output_message "touch #{nocreate ? '-c ' : ''}#{t ? t.strftime('-t %Y%m%d%H%M.%S ') : ''}#{list.join ' '}"
+ end
+ return if noop
+ list.each do |path|
+ created = nocreate
+ begin
+ File.utime(t, t, path)
+ rescue Errno::ENOENT
+ raise if created
+ File.open(path, 'a') {
+ ;
+ }
+ created = true
+ retry if t
+ end
+ end
+ end
+ module_function :touch
+
+ private
+
+ module StreamUtils_
+ private
+
+ case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
+ when /mswin|mingw/
+ def fu_windows?; true end
+ else
+ def fu_windows?; false end
+ end
+
+ def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
+ IO.copy_stream(src, dest)
+ end
+
+ def fu_stream_blksize(*streams)
+ streams.each do |s|
+ next unless s.respond_to?(:stat)
+ size = fu_blksize(s.stat)
+ return size if size
+ end
+ fu_default_blksize()
+ end
+
+ def fu_blksize(st)
+ s = st.blksize
+ return nil unless s
+ return nil if s == 0
+ s
+ end
+
+ def fu_default_blksize
+ 1024
+ end
+ end
+
+ include StreamUtils_
+ extend StreamUtils_
+
+ class Entry_ #:nodoc: internal use only
+ include StreamUtils_
+
+ def initialize(a, b = nil, deref = false)
+ @prefix = @rel = @path = nil
+ if b
+ @prefix = a
+ @rel = b
+ else
+ @path = a
+ end
+ @deref = deref
+ @stat = nil
+ @lstat = nil
+ end
+
+ def inspect
+ "\#<#{self.class} #{path()}>"
+ end
+
+ def path
+ if @path
+ File.path(@path)
+ else
+ join(@prefix, @rel)
+ end
+ end
+
+ def prefix
+ @prefix || @path
+ end
+
+ def rel
+ @rel
+ end
+
+ def dereference?
+ @deref
+ end
+
+ def exist?
+ begin
+ lstat
+ true
+ rescue Errno::ENOENT
+ false
+ end
+ end
+
+ def file?
+ s = lstat!
+ s and s.file?
+ end
+
+ def directory?
+ s = lstat!
+ s and s.directory?
+ end
+
+ def symlink?
+ s = lstat!
+ s and s.symlink?
+ end
+
+ def chardev?
+ s = lstat!
+ s and s.chardev?
+ end
+
+ def blockdev?
+ s = lstat!
+ s and s.blockdev?
+ end
+
+ def socket?
+ s = lstat!
+ s and s.socket?
+ end
+
+ def pipe?
+ s = lstat!
+ s and s.pipe?
+ end
+
+ S_IF_DOOR = 0xD000
+
+ def door?
+ s = lstat!
+ s and (s.mode & 0xF000 == S_IF_DOOR)
+ end
+
+ def entries
+ opts = {}
+ opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
+
+ files = if Dir.respond_to?(:children)
+ Dir.children(path, **opts)
+ else
+ Dir.entries(path(), **opts)
+ .reject {|n| n == '.' or n == '..' }
+ end
+
+ untaint = RUBY_VERSION < '2.7'
+ files.map {|n| Entry_.new(prefix(), join(rel(), untaint ? n.untaint : n)) }
+ end
+
+ def stat
+ return @stat if @stat
+ if lstat() and lstat().symlink?
+ @stat = File.stat(path())
+ else
+ @stat = lstat()
+ end
+ @stat
+ end
+
+ def stat!
+ return @stat if @stat
+ if lstat! and lstat!.symlink?
+ @stat = File.stat(path())
+ else
+ @stat = lstat!
+ end
+ @stat
+ rescue SystemCallError
+ nil
+ end
+
+ def lstat
+ if dereference?
+ @lstat ||= File.stat(path())
+ else
+ @lstat ||= File.lstat(path())
+ end
+ end
+
+ def lstat!
+ lstat()
+ rescue SystemCallError
+ nil
+ end
+
+ def chmod(mode)
+ if symlink?
+ File.lchmod mode, path() if have_lchmod?
+ else
+ File.chmod mode, path()
+ end
+ end
+
+ def chown(uid, gid)
+ if symlink?
+ File.lchown uid, gid, path() if have_lchown?
+ else
+ File.chown uid, gid, path()
+ end
+ end
+
+ def link(dest)
+ case
+ when directory?
+ if !File.exist?(dest) and descendant_directory?(dest, path)
+ raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
+ end
+ begin
+ Dir.mkdir dest
+ rescue
+ raise unless File.directory?(dest)
+ end
+ else
+ File.link path(), dest
+ end
+ end
+
+ def copy(dest)
+ lstat
+ case
+ when file?
+ copy_file dest
+ when directory?
+ if !File.exist?(dest) and descendant_directory?(dest, path)
+ raise ArgumentError, "cannot copy directory %s to itself %s" % [path, dest]
+ end
+ begin
+ Dir.mkdir dest
+ rescue
+ raise unless File.directory?(dest)
+ end
+ when symlink?
+ File.symlink File.readlink(path()), dest
+ when chardev?, blockdev?
+ raise "cannot handle device file"
+ when socket?
+ begin
+ require 'socket'
+ rescue LoadError
+ raise "cannot handle socket"
+ else
+ raise "cannot handle socket" unless defined?(UNIXServer)
+ end
+ UNIXServer.new(dest).close
+ File.chmod lstat().mode, dest
+ when pipe?
+ raise "cannot handle FIFO" unless File.respond_to?(:mkfifo)
+ File.mkfifo dest, lstat().mode
+ when door?
+ raise "cannot handle door: #{path()}"
+ else
+ raise "unknown file type: #{path()}"
+ end
+ end
+
+ def copy_file(dest)
+ File.open(path()) do |s|
+ File.open(dest, 'wb', s.stat.mode) do |f|
+ IO.copy_stream(s, f)
+ end
+ end
+ end
+
+ def copy_metadata(path)
+ st = lstat()
+ if !st.symlink?
+ File.utime st.atime, st.mtime, path
+ end
+ mode = st.mode
+ begin
+ if st.symlink?
+ begin
+ File.lchown st.uid, st.gid, path
+ rescue NotImplementedError
+ end
+ else
+ File.chown st.uid, st.gid, path
+ end
+ rescue Errno::EPERM, Errno::EACCES
+ # clear setuid/setgid
+ mode &= 01777
+ end
+ if st.symlink?
+ begin
+ File.lchmod mode, path
+ rescue NotImplementedError
+ end
+ else
+ File.chmod mode, path
+ end
+ end
+
+ def remove
+ if directory?
+ remove_dir1
+ else
+ remove_file
+ end
+ end
+
+ def remove_dir1
+ platform_support {
+ Dir.rmdir path().chomp(?/)
+ }
+ end
+
+ def remove_file
+ platform_support {
+ File.unlink path
+ }
+ end
+
+ def platform_support
+ return yield unless fu_windows?
+ first_time_p = true
+ begin
+ yield
+ rescue Errno::ENOENT
+ raise
+ rescue => err
+ if first_time_p
+ first_time_p = false
+ begin
+ File.chmod 0700, path() # Windows does not have symlink
+ retry
+ rescue SystemCallError
+ end
+ end
+ raise err
+ end
+ end
+
+ def preorder_traverse
+ stack = [self]
+ while ent = stack.pop
+ yield ent
+ stack.concat ent.entries.reverse if ent.directory?
+ end
+ end
+
+ alias traverse preorder_traverse
+
+ def postorder_traverse
+ if directory?
+ entries().each do |ent|
+ ent.postorder_traverse do |e|
+ yield e
+ end
+ end
+ end
+ ensure
+ yield self
+ end
+
+ def wrap_traverse(pre, post)
+ pre.call self
+ if directory?
+ entries.each do |ent|
+ ent.wrap_traverse pre, post
+ end
+ end
+ post.call self
+ end
+
+ private
+
+ @@fileutils_rb_have_lchmod = nil
+
+ def have_lchmod?
+ # This is not MT-safe, but it does not matter.
+ if @@fileutils_rb_have_lchmod == nil
+ @@fileutils_rb_have_lchmod = check_have_lchmod?
+ end
+ @@fileutils_rb_have_lchmod
+ end
+
+ def check_have_lchmod?
+ return false unless File.respond_to?(:lchmod)
+ File.lchmod 0
+ return true
+ rescue NotImplementedError
+ return false
+ end
+
+ @@fileutils_rb_have_lchown = nil
+
+ def have_lchown?
+ # This is not MT-safe, but it does not matter.
+ if @@fileutils_rb_have_lchown == nil
+ @@fileutils_rb_have_lchown = check_have_lchown?
+ end
+ @@fileutils_rb_have_lchown
+ end
+
+ def check_have_lchown?
+ return false unless File.respond_to?(:lchown)
+ File.lchown nil, nil
+ return true
+ rescue NotImplementedError
+ return false
+ end
+
+ def join(dir, base)
+ return File.path(dir) if not base or base == '.'
+ return File.path(base) if not dir or dir == '.'
+ File.join(dir, base)
+ end
+
+ if File::ALT_SEPARATOR
+ DIRECTORY_TERM = "(?=[/#{Regexp.quote(File::ALT_SEPARATOR)}]|\\z)"
+ else
+ DIRECTORY_TERM = "(?=/|\\z)"
+ end
+
+ def descendant_directory?(descendant, ascendant)
+ if File::FNM_SYSCASE.nonzero?
+ File.expand_path(File.dirname(descendant)).casecmp(File.expand_path(ascendant)) == 0
+ else
+ File.expand_path(File.dirname(descendant)) == File.expand_path(ascendant)
+ end
+ end
+ end # class Entry_
+
+ def fu_list(arg) #:nodoc:
+ [arg].flatten.map {|path| File.path(path) }
+ end
+ private_module_function :fu_list
+
+ def fu_each_src_dest(src, dest) #:nodoc:
+ fu_each_src_dest0(src, dest) do |s, d|
+ raise ArgumentError, "same file: #{s} and #{d}" if fu_same?(s, d)
+ yield s, d
+ end
+ end
+ private_module_function :fu_each_src_dest
+
+ def fu_each_src_dest0(src, dest) #:nodoc:
+ if tmp = Array.try_convert(src)
+ tmp.each do |s|
+ s = File.path(s)
+ yield s, File.join(dest, File.basename(s))
+ end
+ else
+ src = File.path(src)
+ if File.directory?(dest)
+ yield src, File.join(dest, File.basename(src))
+ else
+ yield src, File.path(dest)
+ end
+ end
+ end
+ private_module_function :fu_each_src_dest0
+
+ def fu_same?(a, b) #:nodoc:
+ File.identical?(a, b)
+ end
+ private_module_function :fu_same?
+
+ def fu_output_message(msg) #:nodoc:
+ output = @fileutils_output if defined?(@fileutils_output)
+ output ||= $stderr
+ if defined?(@fileutils_label)
+ msg = @fileutils_label + msg
+ end
+ output.puts msg
+ end
+ private_module_function :fu_output_message
+
+ # This hash table holds command options.
+ OPT_TABLE = {} #:nodoc: internal use only
+ (private_instance_methods & methods(false)).inject(OPT_TABLE) {|tbl, name|
+ (tbl[name.to_s] = instance_method(name).parameters).map! {|t, n| n if t == :key}.compact!
+ tbl
+ }
+
+ public
+
+ #
+ # Returns an Array of names of high-level methods that accept any keyword
+ # arguments.
+ #
+ # p Bundler::FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...]
+ #
+ def self.commands
+ OPT_TABLE.keys
+ end
+
+ #
+ # Returns an Array of option names.
+ #
+ # p Bundler::FileUtils.options #=> ["noop", "force", "verbose", "preserve", "mode"]
+ #
+ def self.options
+ OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }
+ end
+
+ #
+ # Returns true if the method +mid+ have an option +opt+.
+ #
+ # p Bundler::FileUtils.have_option?(:cp, :noop) #=> true
+ # p Bundler::FileUtils.have_option?(:rm, :force) #=> true
+ # p Bundler::FileUtils.have_option?(:rm, :preserve) #=> false
+ #
+ def self.have_option?(mid, opt)
+ li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}"
+ li.include?(opt)
+ end
+
+ #
+ # Returns an Array of option names of the method +mid+.
+ #
+ # p Bundler::FileUtils.options_of(:rm) #=> ["noop", "verbose", "force"]
+ #
+ def self.options_of(mid)
+ OPT_TABLE[mid.to_s].map {|sym| sym.to_s }
+ end
+
+ #
+ # Returns an Array of methods names which have the option +opt+.
+ #
+ # p Bundler::FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
+ #
+ def self.collect_method(opt)
+ OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
+ end
+
+ private
+
+ LOW_METHODS = singleton_methods(false) - collect_method(:noop).map(&:intern) # :nodoc:
+ module LowMethods # :nodoc: internal use only
+ private
+ def _do_nothing(*)end
+ ::Bundler::FileUtils::LOW_METHODS.map {|name| alias_method name, :_do_nothing}
+ end
+
+ METHODS = singleton_methods() - [:private_module_function, # :nodoc:
+ :commands, :options, :have_option?, :options_of, :collect_method]
+
+ #
+ # This module has all methods of Bundler::FileUtils module, but it outputs messages
+ # before acting. This equates to passing the <tt>:verbose</tt> flag to
+ # methods in Bundler::FileUtils.
+ #
+ module Verbose
+ include Bundler::FileUtils
+ names = ::Bundler::FileUtils.collect_method(:verbose)
+ names.each do |name|
+ module_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{name}(*args, **options)
+ super(*args, **options, verbose: true)
+ end
+ EOS
+ end
+ private(*names)
+ extend self
+ class << self
+ public(*::Bundler::FileUtils::METHODS)
+ end
+ end
+
+ #
+ # This module has all methods of Bundler::FileUtils module, but never changes
+ # files/directories. This equates to passing the <tt>:noop</tt> flag
+ # to methods in Bundler::FileUtils.
+ #
+ module NoWrite
+ include Bundler::FileUtils
+ include LowMethods
+ names = ::Bundler::FileUtils.collect_method(:noop)
+ names.each do |name|
+ module_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{name}(*args, **options)
+ super(*args, **options, noop: true)
+ end
+ EOS
+ end
+ private(*names)
+ extend self
+ class << self
+ public(*::Bundler::FileUtils::METHODS)
+ end
+ end
+
+ #
+ # This module has all methods of Bundler::FileUtils module, but never changes
+ # files/directories, with printing message before acting.
+ # This equates to passing the <tt>:noop</tt> and <tt>:verbose</tt> flag
+ # to methods in Bundler::FileUtils.
+ #
+ module DryRun
+ include Bundler::FileUtils
+ include LowMethods
+ names = ::Bundler::FileUtils.collect_method(:noop)
+ names.each do |name|
+ module_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{name}(*args, **options)
+ super(*args, **options, noop: true, verbose: true)
+ end
+ EOS
+ end
+ private(*names)
+ extend self
+ class << self
+ public(*::Bundler::FileUtils::METHODS)
+ end
+ end
+
+end
diff --git a/lib/bundler/vendor/molinillo/LICENSE b/lib/bundler/vendor/molinillo/LICENSE
new file mode 100644
index 0000000000..01feffa088
--- /dev/null
+++ b/lib/bundler/vendor/molinillo/LICENSE
@@ -0,0 +1,9 @@
+This project is licensed under the MIT license.
+
+Copyright (c) 2014 Samuel E. Giddins segiddins@segiddins.me
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo.rb b/lib/bundler/vendor/molinillo/lib/molinillo.rb
index 134bf1d720..a52b96deaf 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/gem_metadata'
-require 'bundler/vendor/molinillo/lib/molinillo/errors'
-require 'bundler/vendor/molinillo/lib/molinillo/resolver'
-require 'bundler/vendor/molinillo/lib/molinillo/modules/ui'
-require 'bundler/vendor/molinillo/lib/molinillo/modules/specification_provider'
+
+require_relative 'molinillo/gem_metadata'
+require_relative 'molinillo/errors'
+require_relative 'molinillo/resolver'
+require_relative 'molinillo/modules/ui'
+require_relative 'molinillo/modules/specification_provider'
# Bundler::Molinillo is a generic dependency resolution algorithm.
module Bundler::Molinillo
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb b/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb
index 253c18764f..bcacf35243 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
# @!visibility private
module Delegates
@@ -45,6 +46,12 @@ module Bundler::Molinillo
current_state = state || Bundler::Molinillo::ResolutionState.empty
current_state.conflicts
end
+
+ # (see Bundler::Molinillo::ResolutionState#unused_unwind_options)
+ def unused_unwind_options
+ current_state = state || Bundler::Molinillo::ResolutionState.empty
+ current_state.unused_unwind_options
+ end
end
end
end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb b/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb
index 29f48d5b3c..f8c695c1ed 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
module Delegates
# Delegates all {Bundler::Molinillo::SpecificationProvider} methods to a
@@ -25,6 +26,13 @@ module Bundler::Molinillo
end
end
+ # (see Bundler::Molinillo::SpecificationProvider#dependencies_equal?)
+ def dependencies_equal?(dependencies, other_dependencies)
+ with_no_such_dependency_error_handling do
+ specification_provider.dependencies_equal?(dependencies, other_dependencies)
+ end
+ end
+
# (see Bundler::Molinillo::SpecificationProvider#name_for)
def name_for(dependency)
with_no_such_dependency_error_handling do
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb
index 76e84ab7e6..10a25d2f08 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require 'set'
-require 'tsort'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/log'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex'
+require_relative '../../../../vendored_tsort'
+
+require_relative 'dependency_graph/log'
+require_relative 'dependency_graph/vertex'
module Bundler::Molinillo
# A directed acyclic graph that is tuned to hold named dependencies
@@ -17,7 +17,7 @@ module Bundler::Molinillo
vertices.values.each { |v| yield v }
end
- include TSort
+ include Bundler::TSort
# @!visibility private
alias tsort_each_node each
@@ -123,6 +123,7 @@ module Bundler::Molinillo
dot.join("\n")
end
+ # @param [DependencyGraph] other
# @return [Boolean] whether the two dependency graphs are equal, determined
# by a recursive traversal of each {#root_vertices} and its
# {Vertex#successors}
@@ -147,8 +148,8 @@ module Bundler::Molinillo
vertex = add_vertex(name, payload, root)
vertex.explicit_requirements << requirement if root
parent_names.each do |parent_name|
- parent_node = vertex_named(parent_name)
- add_edge(parent_node, vertex, requirement)
+ parent_vertex = vertex_named(parent_name)
+ add_edge(parent_vertex, vertex, requirement)
end
vertex
end
@@ -189,7 +190,7 @@ module Bundler::Molinillo
# @return [Edge] the added edge
def add_edge(origin, destination, requirement)
if destination.path_to?(origin)
- raise CircularDependencyError.new([origin, destination])
+ raise CircularDependencyError.new(path(destination, origin))
end
add_edge_no_circular(origin, destination, requirement)
end
@@ -218,5 +219,37 @@ module Bundler::Molinillo
def add_edge_no_circular(origin, destination, requirement)
log.add_edge_no_circular(self, origin.name, destination.name, requirement)
end
+
+ # Returns the path between two vertices
+ # @raise [ArgumentError] if there is no path between the vertices
+ # @param [Vertex] from
+ # @param [Vertex] to
+ # @return [Array<Vertex>] the shortest path from `from` to `to`
+ def path(from, to)
+ distances = Hash.new(vertices.size + 1)
+ distances[from.name] = 0
+ predecessors = {}
+ each do |vertex|
+ vertex.successors.each do |successor|
+ if distances[successor.name] > distances[vertex.name] + 1
+ distances[successor.name] = distances[vertex.name] + 1
+ predecessors[successor] = vertex
+ end
+ end
+ end
+
+ path = [to]
+ while before = predecessors[to]
+ path << before
+ to = before
+ break if to == from
+ end
+
+ unless path.last.equal?(from)
+ raise ArgumentError, "There is no path from #{from.name} to #{to.name}"
+ end
+
+ path.reverse
+ end
end
end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb
index e0dfe6cbbd..c04c7eec9c 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
class DependencyGraph
# An action that modifies a {DependencyGraph} that is reversible.
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
index 9092e4d546..946a08236e 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Bundler::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
index eda4251801..483527daf8 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Bundler::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
index e9125a59c6..d81940585a 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Bundler::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
index d20b2cb0e0..36fce7c526 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Bundler::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb
index 72a705e023..6f0de19886 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload'
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag'
+
+require_relative 'add_edge_no_circular'
+require_relative 'add_vertex'
+require_relative 'delete_edge'
+require_relative 'detach_vertex_named'
+require_relative 'set_payload'
+require_relative 'tag'
module Bundler::Molinillo
class DependencyGraph
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb
index 8d8e10fedf..2e9b90e6cd 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Bundler::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb
index 53524d36ad..5b5da3e4f9 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Bundler::Molinillo
class DependencyGraph
# @!visibility private
@@ -13,11 +14,11 @@ module Bundler::Molinillo
end
# (see Action#up)
- def up(_graph)
+ def up(graph)
end
# (see Action#down)
- def down(_graph)
+ def down(graph)
end
# @!group Tag
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
index eab989e7bc..1185a8ab05 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
class DependencyGraph
# A vertex in a {DependencyGraph} that encapsulates a {#name} and a
@@ -32,7 +33,7 @@ module Bundler::Molinillo
# @return [Array<Object>] all of the requirements that required
# this vertex
def requirements
- incoming_edges.map(&:requirement) + explicit_requirements
+ (incoming_edges.map(&:requirement) + explicit_requirements).uniq
end
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
@@ -49,14 +50,25 @@ module Bundler::Molinillo
incoming_edges.map(&:origin)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is a
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
# {#descendent?}
def recursive_predecessors
- vertices = predecessors
- vertices += vertices.map(&:recursive_predecessors).flatten(1)
- vertices.uniq!
+ _recursive_predecessors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the predecessors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
+ # {#descendent?}
+ def _recursive_predecessors(vertices = new_vertex_set)
+ incoming_edges.each do |edge|
+ vertex = edge.origin
+ next unless vertices.add?(vertex)
+ vertex._recursive_predecessors(vertices)
+ end
+
vertices
end
+ protected :_recursive_predecessors
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
# `self` as their {Edge#origin}
@@ -64,14 +76,25 @@ module Bundler::Molinillo
outgoing_edges.map(&:destination)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is an
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
# {#ancestor?}
def recursive_successors
- vertices = successors
- vertices += vertices.map(&:recursive_successors).flatten(1)
- vertices.uniq!
+ _recursive_successors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the successors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
+ # {#ancestor?}
+ def _recursive_successors(vertices = new_vertex_set)
+ outgoing_edges.each do |edge|
+ vertex = edge.destination
+ next unless vertices.add?(vertex)
+ vertex._recursive_successors(vertices)
+ end
+
vertices
end
+ protected :_recursive_successors
# @return [String] a string suitable for debugging
def inspect
@@ -105,21 +128,37 @@ module Bundler::Molinillo
# Is there a path from `self` to `other` following edges in the
# dependency graph?
- # @return true iff there is a path following edges within this {#graph}
+ # @return whether there is a path following edges within this {#graph}
def path_to?(other)
- equal?(other) || successors.any? { |v| v.path_to?(other) }
+ _path_to?(other)
end
alias descendent? path_to?
+ # @param [Vertex] other the vertex to check if there's a path to
+ # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
+ # @return [Boolean] whether there is a path to `other` from `self`
+ def _path_to?(other, visited = new_vertex_set)
+ return false unless visited.add?(self)
+ return true if equal?(other)
+ successors.any? { |v| v._path_to?(other, visited) }
+ end
+ protected :_path_to?
+
# Is there a path from `other` to `self` following edges in the
# dependency graph?
- # @return true iff there is a path following edges within this {#graph}
+ # @return whether there is a path following edges within this {#graph}
def ancestor?(other)
other.path_to?(self)
end
alias is_reachable_from? ancestor?
+
+ def new_vertex_set
+ require 'set'
+ Set.new
+ end
+ private :new_vertex_set
end
end
end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb b/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb
index f904bd0814..e210202b69 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
# An error that occurred during the resolution process
class ResolverError < StandardError; end
@@ -17,7 +18,7 @@ module Bundler::Molinillo
# @param [Array<Object>] required_by @see {#required_by}
def initialize(dependency, required_by = [])
@dependency = dependency
- @required_by = required_by
+ @required_by = required_by.uniq
super()
end
@@ -33,7 +34,7 @@ module Bundler::Molinillo
# An error caused by attempting to fulfil a dependency that was circular
#
- # @note This exception will be thrown iff a {Vertex} is added to a
+ # @note This exception will be thrown if and only if a {Vertex} is added to a
# {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
# existing {DependencyGraph::Vertex}
class CircularDependencyError < ResolverError
@@ -41,11 +42,11 @@ module Bundler::Molinillo
attr_reader :dependencies
# Initializes a new error with the given circular vertices.
- # @param [Array<DependencyGraph::Vertex>] nodes the nodes in the dependency
+ # @param [Array<DependencyGraph::Vertex>] vertices the vertices in the dependency
# that caused the error
- def initialize(nodes)
- super "There is a circular dependency between #{nodes.map(&:name).join(' and ')}"
- @dependencies = nodes.map(&:payload).to_set
+ def initialize(vertices)
+ super "There is a circular dependency between #{vertices.map(&:name).join(' and ')}"
+ @dependencies = vertices.map { |vertex| vertex.payload.possibilities.last }.to_set
end
end
@@ -55,11 +56,16 @@ module Bundler::Molinillo
# resolution to fail
attr_reader :conflicts
+ # @return [SpecificationProvider] the specification provider used during
+ # resolution
+ attr_reader :specification_provider
+
# Initializes a new error with the given version conflicts.
# @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
- def initialize(conflicts)
+ # @param [SpecificationProvider] specification_provider see {#specification_provider}
+ def initialize(conflicts, specification_provider)
pairs = []
- conflicts.values.flatten.map(&:requirements).flatten.each do |conflicting|
+ conflicts.values.flat_map(&:requirements).each do |conflicting|
conflicting.each do |source, conflict_requirements|
conflict_requirements.each do |c|
pairs << [c, source]
@@ -69,7 +75,69 @@ module Bundler::Molinillo
super "Unable to satisfy the following requirements:\n\n" \
"#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"
+
@conflicts = conflicts
+ @specification_provider = specification_provider
+ end
+
+ require_relative 'delegates/specification_provider'
+ include Delegates::SpecificationProvider
+
+ # @return [String] An error message that includes requirement trees,
+ # which is much more detailed & customizable than the default message
+ # @param [Hash] opts the options to create a message with.
+ # @option opts [String] :solver_name The user-facing name of the solver
+ # @option opts [String] :possibility_type The generic name of a possibility
+ # @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees
+ # @option opts [Proc] :printable_requirement A proc that pretty-prints requirements
+ # @option opts [Proc] :additional_message_for_conflict A proc that appends additional
+ # messages for each conflict
+ # @option opts [Proc] :version_for_spec A proc that returns the version number for a
+ # possibility
+ def message_with_trees(opts = {})
+ solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
+ possibility_type = opts.delete(:possibility_type) { 'possibility named' }
+ reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } }
+ printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
+ additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
+ version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
+ incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do
+ proc do |name, _conflict|
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
+ end
+ end
+
+ conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
+ o << "\n" << incompatible_version_message_for_conflict.call(name, conflict) << "\n"
+ if conflict.locked_requirement
+ o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
+ o << %( #{printable_requirement.call(conflict.locked_requirement)}\n)
+ o << %(\n)
+ end
+ o << %( In #{name_for_explicit_dependency_source}:\n)
+ trees = reduce_trees.call(conflict.requirement_trees)
+
+ o << trees.map do |tree|
+ t = ''.dup
+ depth = 2
+ tree.each do |req|
+ t << ' ' * depth << printable_requirement.call(req)
+ unless tree.last == req
+ if spec = conflict.activated_by_name[name_for(req)]
+ t << %( was resolved to #{version_for_spec.call(spec)}, which)
+ end
+ t << %( depends on)
+ end
+ t << %(\n)
+ depth += 1
+ end
+ t
+ end.join("\n")
+
+ additional_message_for_conflict.call(o, name, conflict)
+
+ o
+ end.strip
end
end
end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb
index a4fb6dd68e..e13a781a50 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
# The version of Bundler::Molinillo.
- VERSION = '0.5.7'.freeze
+ VERSION = '0.7.0'.freeze
end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb b/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb
index 0f1ad195f2..eeae79af3c 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
- # Provides information about specifcations and dependencies to the resolver,
+ # Provides information about specifications and dependencies to the resolver,
# allowing the {Resolver} class to remain generic while still providing power
# and flexibility.
#
@@ -44,6 +45,17 @@ module Bundler::Molinillo
true
end
+ # Determines whether two arrays of dependencies are equal, and thus can be
+ # grouped.
+ #
+ # @param [Array<Object>] dependencies
+ # @param [Array<Object>] other_dependencies
+ # @return [Boolean] whether `dependencies` and `other_dependencies` should
+ # be considered equal.
+ def dependencies_equal?(dependencies, other_dependencies)
+ dependencies == other_dependencies
+ end
+
# Returns the name for the given `dependency`.
# @note This method should be 'pure', i.e. the return value should depend
# only on the `dependency` parameter.
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb b/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb
index d47cfa2928..a166bc6991 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
# Conveys information about the resolution process to a user.
module UI
@@ -48,7 +49,8 @@ module Bundler::Molinillo
if debug?
debug_info = yield
debug_info = debug_info.inspect unless debug_info.is_a?(String)
- output.puts debug_info.split("\n").map { |s| ' ' * depth + s }
+ debug_info = debug_info.split("\n").map { |s| ":#{depth.to_s.rjust 4}: #{s}" }
+ output.puts debug_info
end
end
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb b/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb
index 1845966a75..c689ca7635 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
class Resolver
# A specific resolution from a given {Resolver}
@@ -8,22 +9,125 @@ module Bundler::Molinillo
# @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict
# @attr [Object, nil] existing the existing spec that was in conflict with
# the {#possibility}
- # @attr [Object] possibility the spec that was unable to be activated due
- # to a conflict
+ # @attr [Object] possibility_set the set of specs that was unable to be
+ # activated due to a conflict.
# @attr [Object] locked_requirement the relevant locking requirement.
# @attr [Array<Array<Object>>] requirement_trees the different requirement
# trees that led to every requirement for the conflicting name.
# @attr [{String=>Object}] activated_by_name the already-activated specs.
+ # @attr [Object] underlying_error an error that has occurred during resolution, and
+ # will be raised at the end of it if no resolution is found.
Conflict = Struct.new(
:requirement,
:requirements,
:existing,
- :possibility,
+ :possibility_set,
:locked_requirement,
:requirement_trees,
- :activated_by_name
+ :activated_by_name,
+ :underlying_error
)
+ class Conflict
+ # @return [Object] a spec that was unable to be activated due to a conflict
+ def possibility
+ possibility_set && possibility_set.latest_version
+ end
+ end
+
+ # A collection of possibility states that share the same dependencies
+ # @attr [Array] dependencies the dependencies for this set of possibilities
+ # @attr [Array] possibilities the possibilities
+ PossibilitySet = Struct.new(:dependencies, :possibilities)
+
+ class PossibilitySet
+ # String representation of the possibility set, for debugging
+ def to_s
+ "[#{possibilities.join(', ')}]"
+ end
+
+ # @return [Object] most up-to-date dependency in the possibility set
+ def latest_version
+ possibilities.last
+ end
+ end
+
+ # Details of the state to unwind to when a conflict occurs, and the cause of the unwind
+ # @attr [Integer] state_index the index of the state to unwind to
+ # @attr [Object] state_requirement the requirement of the state we're unwinding to
+ # @attr [Array] requirement_tree for the requirement we're relaxing
+ # @attr [Array] conflicting_requirements the requirements that combined to cause the conflict
+ # @attr [Array] requirement_trees for the conflict
+ # @attr [Array] requirements_unwound_to_instead array of unwind requirements that were chosen over this unwind
+ UnwindDetails = Struct.new(
+ :state_index,
+ :state_requirement,
+ :requirement_tree,
+ :conflicting_requirements,
+ :requirement_trees,
+ :requirements_unwound_to_instead
+ )
+
+ class UnwindDetails
+ include Comparable
+
+ # We compare UnwindDetails when choosing which state to unwind to. If
+ # two options have the same state_index we prefer the one most
+ # removed from a requirement that caused the conflict. Both options
+ # would unwind to the same state, but a `grandparent` option will
+ # filter out fewer of its possibilities after doing so - where a state
+ # is both a `parent` and a `grandparent` to requirements that have
+ # caused a conflict this is the correct behaviour.
+ # @param [UnwindDetail] other UnwindDetail to be compared
+ # @return [Integer] integer specifying ordering
+ def <=>(other)
+ if state_index > other.state_index
+ 1
+ elsif state_index == other.state_index
+ reversed_requirement_tree_index <=> other.reversed_requirement_tree_index
+ else
+ -1
+ end
+ end
+
+ # @return [Integer] index of state requirement in reversed requirement tree
+ # (the conflicting requirement itself will be at position 0)
+ def reversed_requirement_tree_index
+ @reversed_requirement_tree_index ||=
+ if state_requirement
+ requirement_tree.reverse.index(state_requirement)
+ else
+ 999_999
+ end
+ end
+
+ # @return [Boolean] where the requirement of the state we're unwinding
+ # to directly caused the conflict. Note: in this case, it is
+ # impossible for the state we're unwinding to to be a parent of
+ # any of the other conflicting requirements (or we would have
+ # circularity)
+ def unwinding_to_primary_requirement?
+ requirement_tree.last == state_requirement
+ end
+
+ # @return [Array] array of sub-dependencies to avoid when choosing a
+ # new possibility for the state we've unwound to. Only relevant for
+ # non-primary unwinds
+ def sub_dependencies_to_avoid
+ @requirements_to_avoid ||=
+ requirement_trees.map do |tree|
+ index = tree.index(state_requirement)
+ tree[index + 1] if index
+ end.compact
+ end
+
+ # @return [Array] array of all the requirements that led to the need for
+ # this unwind
+ def all_requirements
+ @all_requirements ||= requirement_trees.flatten(1)
+ end
+ end
+
# @return [SpecificationProvider] the provider that knows about
# dependencies, requirements, specifications, versions, etc.
attr_reader :specification_provider
@@ -64,7 +168,7 @@ module Bundler::Molinillo
start_resolution
while state
- break unless state.requirements.any? || state.requirement
+ break if !state.requirement && state.requirements.empty?
indicate_progress
if state.respond_to?(:pop_possibility_state) # DependencyState
debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
@@ -78,7 +182,7 @@ module Bundler::Molinillo
process_topmost_state
end
- activated.freeze
+ resolve_activated_specs
ensure
end_resolution
end
@@ -103,12 +207,25 @@ module Bundler::Molinillo
def start_resolution
@started_at = Time.now
- handle_missing_or_push_dependency_state(initial_state)
+ push_initial_state
debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
resolver_ui.before_resolution
end
+ def resolve_activated_specs
+ activated.vertices.each do |_, vertex|
+ next unless vertex.payload
+
+ latest_version = vertex.payload.possibilities.reverse_each.find do |possibility|
+ vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
+ end
+
+ activated.set_payload(vertex.name, latest_version)
+ end
+ activated.freeze
+ end
+
# Ends the resolution process
# @return [void]
def end_resolution
@@ -121,11 +238,11 @@ module Bundler::Molinillo
debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
end
- require 'bundler/vendor/molinillo/lib/molinillo/state'
- require 'bundler/vendor/molinillo/lib/molinillo/modules/specification_provider'
+ require_relative 'state'
+ require_relative 'modules/specification_provider'
- require 'bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state'
- require 'bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider'
+ require_relative 'delegates/resolution_state'
+ require_relative 'delegates/specification_provider'
include Bundler::Molinillo::Delegates::ResolutionState
include Bundler::Molinillo::Delegates::SpecificationProvider
@@ -136,9 +253,12 @@ module Bundler::Molinillo
if possibility
attempt_to_activate
else
- create_conflict if state.is_a? PossibilityState
- unwind_for_conflict until possibility && state.is_a?(DependencyState)
+ create_conflict
+ unwind_for_conflict
end
+ rescue CircularDependencyError => underlying_error
+ create_conflict(underlying_error)
+ unwind_for_conflict
end
# @return [Object] the current possibility that the resolution is trying
@@ -153,63 +273,296 @@ module Bundler::Molinillo
states.last
end
- # Creates the initial state for the resolution, based upon the
+ # Creates and pushes the initial state for the resolution, based upon the
# {#requested} dependencies
- # @return [DependencyState] the initial state for the resolution
- def initial_state
+ # @return [void]
+ def push_initial_state
graph = DependencyGraph.new.tap do |dg|
- original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } }
+ original_requested.each do |requested|
+ vertex = dg.add_vertex(name_for(requested), nil, true)
+ vertex.explicit_requirements << requested
+ end
dg.tag(:initial_state)
end
- requirements = sort_dependencies(original_requested, graph, {})
- initial_requirement = requirements.shift
- DependencyState.new(
- initial_requirement && name_for(initial_requirement),
- requirements,
- graph,
- initial_requirement,
- initial_requirement && search_for(initial_requirement),
- 0,
- {}
- )
+ push_state_for_requirements(original_requested, true, graph)
end
# Unwinds the states stack because a conflict has been encountered
# @return [void]
def unwind_for_conflict
- debug(depth) { "Unwinding for conflict: #{requirement} to #{state_index_for_unwind / 2}" }
+ details_for_unwind = build_details_for_unwind
+ unwind_options = unused_unwind_options
+ debug(depth) { "Unwinding for conflict: #{requirement} to #{details_for_unwind.state_index / 2}" }
conflicts.tap do |c|
- sliced_states = states.slice!((state_index_for_unwind + 1)..-1)
- raise VersionConflict.new(c) unless state
+ sliced_states = states.slice!((details_for_unwind.state_index + 1)..-1)
+ raise_error_unless_state(c)
activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
state.conflicts = c
+ state.unused_unwind_options = unwind_options
+ filter_possibilities_after_unwind(details_for_unwind)
index = states.size - 1
@parents_of.each { |_, a| a.reject! { |i| i >= index } }
+ state.unused_unwind_options.reject! { |uw| uw.state_index >= index }
+ end
+ end
+
+ # Raises a VersionConflict error, or any underlying error, if there is no
+ # current state
+ # @return [void]
+ def raise_error_unless_state(conflicts)
+ return if state
+
+ error = conflicts.values.map(&:underlying_error).compact.first
+ raise error || VersionConflict.new(conflicts, specification_provider)
+ end
+
+ # @return [UnwindDetails] Details of the nearest index to which we could unwind
+ def build_details_for_unwind
+ # Get the possible unwinds for the current conflict
+ current_conflict = conflicts[name]
+ binding_requirements = binding_requirements_for_conflict(current_conflict)
+ unwind_details = unwind_options_for_requirements(binding_requirements)
+
+ last_detail_for_current_unwind = unwind_details.sort.last
+ current_detail = last_detail_for_current_unwind
+
+ # Look for past conflicts that could be unwound to affect the
+ # requirement tree for the current conflict
+ all_reqs = last_detail_for_current_unwind.all_requirements
+ all_reqs_size = all_reqs.size
+ relevant_unused_unwinds = unused_unwind_options.select do |alternative|
+ diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
+ next if diff_reqs.size == all_reqs_size
+ # Find the highest index unwind whilst looping through
+ current_detail = alternative if alternative > current_detail
+ alternative
+ end
+
+ # Add the current unwind options to the `unused_unwind_options` array.
+ # The "used" option will be filtered out during `unwind_for_conflict`.
+ state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
+
+ # Update the requirements_unwound_to_instead on any relevant unused unwinds
+ relevant_unused_unwinds.each do |d|
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
+ end
+ unwind_details.each do |d|
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
+ end
+
+ current_detail
+ end
+
+ # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
+ # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
+ # of resolving the passed requirements
+ def unwind_options_for_requirements(binding_requirements)
+ unwind_details = []
+
+ trees = []
+ binding_requirements.reverse_each do |r|
+ partial_tree = [r]
+ trees << partial_tree
+ unwind_details << UnwindDetails.new(-1, nil, partial_tree, binding_requirements, trees, [])
+
+ # If this requirement has alternative possibilities, check if any would
+ # satisfy the other requirements that created this conflict
+ requirement_state = find_state_for(r)
+ if conflict_fixing_possibilities?(requirement_state, binding_requirements)
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+
+ # Next, look at the parent of this requirement, and check if the requirement
+ # could have been avoided if an alternative PossibilitySet had been chosen
+ parent_r = parent_of(r)
+ next if parent_r.nil?
+ partial_tree.unshift(parent_r)
+ requirement_state = find_state_for(parent_r)
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(r) }
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ parent_r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+
+ # Finally, look at the grandparent and up of this requirement, looking
+ # for any possibilities that wouldn't create their parent requirement
+ grandparent_r = parent_of(parent_r)
+ until grandparent_r.nil?
+ partial_tree.unshift(grandparent_r)
+ requirement_state = find_state_for(grandparent_r)
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(parent_r) }
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ grandparent_r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+ parent_r = grandparent_r
+ grandparent_r = parent_of(parent_r)
+ end
+ end
+
+ unwind_details
+ end
+
+ # @param [DependencyState] state
+ # @param [Array] binding_requirements array of requirements
+ # @return [Boolean] whether or not the given state has any possibilities
+ # that could satisfy the given requirements
+ def conflict_fixing_possibilities?(state, binding_requirements)
+ return false unless state
+
+ state.possibilities.any? do |possibility_set|
+ possibility_set.possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, binding_requirements)
+ end
+ end
+ end
+
+ # Filter's a state's possibilities to remove any that would not fix the
+ # conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just
+ # unwound from
+ # @return [void]
+ def filter_possibilities_after_unwind(unwind_details)
+ return unless state && !state.possibilities.empty?
+
+ if unwind_details.unwinding_to_primary_requirement?
+ filter_possibilities_for_primary_unwind(unwind_details)
+ else
+ filter_possibilities_for_parent_unwind(unwind_details)
end
end
- # @return [Integer] The index to which the resolution should unwind in the
- # case of conflict.
- def state_index_for_unwind
- current_requirement = requirement
- existing_requirement = requirement_for_existing_name(name)
- index = -1
- [current_requirement, existing_requirement].each do |r|
- until r.nil?
- current_state = find_state_for(r)
- if state_any?(current_state)
- current_index = states.index(current_state)
- index = current_index if current_index > index
- break
+ # Filter's a state's possibilities to remove any that would not satisfy
+ # the requirements in the conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
+ # @return [void]
+ def filter_possibilities_for_primary_unwind(unwind_details)
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
+ unwinds_to_state << unwind_details
+ unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements)
+
+ state.possibilities.reject! do |possibility_set|
+ possibility_set.possibilities.none? do |poss|
+ unwind_requirement_sets.any? do |requirements|
+ possibility_satisfies_requirements?(poss, requirements)
end
- r = parent_of(r)
end
end
+ end
+
+ # @param [Object] possibility a single possibility
+ # @param [Array] requirements an array of requirements
+ # @return [Boolean] whether the possibility satisfies all of the
+ # given requirements
+ def possibility_satisfies_requirements?(possibility, requirements)
+ name = name_for(possibility)
+
+ activated.tag(:swap)
+ activated.set_payload(name, possibility) if activated.vertex_named(name)
+ satisfied = requirements.all? { |r| requirement_satisfied_by?(r, activated, possibility) }
+ activated.rewind_to(:swap)
+
+ satisfied
+ end
+
+ # Filter's a state's possibilities to remove any that would (eventually)
+ # create a requirement in the conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
+ # @return [void]
+ def filter_possibilities_for_parent_unwind(unwind_details)
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
+ unwinds_to_state << unwind_details
+
+ primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
+ parent_unwinds = unwinds_to_state.uniq - primary_unwinds
+
+ allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
+ states[unwind.state_index].possibilities.select do |possibility_set|
+ possibility_set.possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
+ end
+ end
+ end
+
+ requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
+
+ state.possibilities.reject! do |possibility_set|
+ !allowed_possibility_sets.include?(possibility_set) &&
+ (requirements_to_avoid - possibility_set.dependencies).empty?
+ end
+ end
+
+ # @param [Conflict] conflict
+ # @return [Array] minimal array of requirements that would cause the passed
+ # conflict to occur.
+ def binding_requirements_for_conflict(conflict)
+ return [conflict.requirement] if conflict.possibility.nil?
+
+ possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
+
+ # When there's a `CircularDependency` error the conflicting requirement
+ # (the one causing the circular) won't be `conflict.requirement`
+ # (which won't be for the right state, because we won't have created it,
+ # because it's circular).
+ # We need to make sure we have that requirement in the conflict's list,
+ # otherwise we won't be able to unwind properly, so we just return all
+ # the requirements for the conflict.
+ return possible_binding_requirements if conflict.underlying_error
+
+ possibilities = search_for(conflict.requirement)
+
+ # If all the requirements together don't filter out all possibilities,
+ # then the only two requirements we need to consider are the initial one
+ # (where the dependency's version was first chosen) and the last
+ if binding_requirement_in_set?(nil, possible_binding_requirements, possibilities)
+ return [conflict.requirement, requirement_for_existing_name(name_for(conflict.requirement))].compact
+ end
+
+ # Loop through the possible binding requirements, removing each one
+ # that doesn't bind. Use a `reverse_each` as we want the earliest set of
+ # binding requirements, and don't use `reject!` as we wish to refine the
+ # array *on each iteration*.
+ binding_requirements = possible_binding_requirements.dup
+ possible_binding_requirements.reverse_each do |req|
+ next if req == conflict.requirement
+ unless binding_requirement_in_set?(req, binding_requirements, possibilities)
+ binding_requirements -= [req]
+ end
+ end
+
+ binding_requirements
+ end
- index
+ # @param [Object] requirement we wish to check
+ # @param [Array] possible_binding_requirements array of requirements
+ # @param [Array] possibilities array of possibilities the requirements will be used to filter
+ # @return [Boolean] whether or not the given requirement is required to filter
+ # out all elements of the array of possibilities.
+ def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
+ possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, possible_binding_requirements - [requirement])
+ end
end
+ # @param [Object] requirement
# @return [Object] the requirement that led to `requirement` being added
# to the list of requirements.
def parent_of(requirement)
@@ -219,29 +572,27 @@ module Bundler::Molinillo
parent_state.requirement
end
+ # @param [String] name
# @return [Object] the requirement that led to a version of a possibility
# with the given name being activated.
def requirement_for_existing_name(name)
- return nil unless activated.vertex_named(name).payload
+ return nil unless vertex = activated.vertex_named(name)
+ return nil unless vertex.payload
states.find { |s| s.name == name }.requirement
end
+ # @param [Object] requirement
# @return [ResolutionState] the state whose `requirement` is the given
# `requirement`.
def find_state_for(requirement)
return nil unless requirement
- states.reverse_each.find { |i| requirement == i.requirement && i.is_a?(DependencyState) }
- end
-
- # @return [Boolean] whether or not the given state has any possibilities
- # left.
- def state_any?(state)
- state && state.possibilities.any?
+ states.find { |i| requirement == i.requirement }
end
+ # @param [Object] underlying_error
# @return [Conflict] a {Conflict} that reflects the failure to activate
# the {#possibility} in conjunction with the current {#state}
- def create_conflict
+ def create_conflict(underlying_error = nil)
vertex = activated.vertex_named(name)
locked_requirement = locked_requirement_named(name)
@@ -250,18 +601,21 @@ module Bundler::Molinillo
requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
end
requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
- vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) }
+ vertex.incoming_edges.each do |edge|
+ (requirements[edge.origin.payload.latest_version] ||= []).unshift(edge.requirement)
+ end
activated_by_name = {}
- activated.each { |v| activated_by_name[v.name] = v.payload if v.payload }
+ activated.each { |v| activated_by_name[v.name] = v.payload.latest_version if v.payload }
conflicts[name] = Conflict.new(
requirement,
requirements,
- vertex.payload,
+ vertex.payload && vertex.payload.latest_version,
possibility,
locked_requirement,
requirement_trees,
- activated_by_name
+ activated_by_name,
+ underlying_error
)
end
@@ -272,6 +626,7 @@ module Bundler::Molinillo
vertex.requirements.map { |r| requirement_tree_for(r) }
end
+ # @param [Object] requirement
# @return [Array<Object>] the list of requirements that led to
# `requirement` being required.
def requirement_tree_for(requirement)
@@ -311,116 +666,47 @@ module Bundler::Molinillo
# @return [void]
def attempt_to_activate
debug(depth) { 'Attempting to activate ' + possibility.to_s }
- existing_node = activated.vertex_named(name)
- if existing_node.payload
- debug(depth) { "Found existing spec (#{existing_node.payload})" }
- attempt_to_activate_existing_spec(existing_node)
+ existing_vertex = activated.vertex_named(name)
+ if existing_vertex.payload
+ debug(depth) { "Found existing spec (#{existing_vertex.payload})" }
+ attempt_to_filter_existing_spec(existing_vertex)
else
- attempt_to_activate_new_spec
- end
- end
-
- # Attempts to activate the current {#possibility} (given that it has
- # already been activated)
- # @return [void]
- def attempt_to_activate_existing_spec(existing_node)
- existing_spec = existing_node.payload
- if requirement_satisfied_by?(requirement, activated, existing_spec)
- new_requirements = requirements.dup
- push_state_for_requirements(new_requirements, false)
- else
- return if attempt_to_swap_possibility
- create_conflict
- debug(depth) { "Unsatisfied by existing spec (#{existing_node.payload})" }
- unwind_for_conflict
- end
- end
-
- # Attempts to swp the current {#possibility} with the already-activated
- # spec with the given name
- # @return [Boolean] Whether the possibility was swapped into {#activated}
- def attempt_to_swap_possibility
- activated.tag(:swap)
- vertex = activated.vertex_named(name)
- activated.set_payload(name, possibility)
- if !vertex.requirements.
- all? { |r| requirement_satisfied_by?(r, activated, possibility) } ||
- !new_spec_satisfied?
- activated.rewind_to(:swap)
- return
- end
- fixup_swapped_children(vertex)
- activate_spec
- end
-
- # Ensures there are no orphaned successors to the given {vertex}.
- # @param [DependencyGraph::Vertex] vertex the vertex to fix up.
- # @return [void]
- def fixup_swapped_children(vertex) # rubocop:disable Metrics/CyclomaticComplexity
- payload = vertex.payload
- deps = dependencies_for(payload).group_by(&method(:name_for))
- vertex.outgoing_edges.each do |outgoing_edge|
- requirement = outgoing_edge.requirement
- parent_index = @parents_of[requirement].last
- succ = outgoing_edge.destination
- matching_deps = Array(deps[succ.name])
- dep_matched = matching_deps.include?(requirement)
-
- # only push the current index when it was originally required by the
- # same named spec
- if parent_index && states[parent_index].name == name
- @parents_of[requirement].push(states.size - 1)
+ latest = possibility.latest_version
+ possibility.possibilities.select! do |possibility|
+ requirement_satisfied_by?(requirement, activated, possibility)
end
-
- if matching_deps.empty? && !succ.root? && succ.predecessors.to_a == [vertex]
- debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
- succ.requirements.each { |r| @parents_of.delete(r) }
-
- removed_names = activated.detach_vertex_named(succ.name).map(&:name)
- requirements.delete_if do |r|
- # the only removed vertices are those with no other requirements,
- # so it's safe to delete only based upon name here
- removed_names.include?(name_for(r))
- end
- elsif !dep_matched
- debug(depth) { "Removing orphaned dependency #{requirement} after swapping #{name}" }
- # also reset if we're removing the edge, but only if its parent has
- # already been fixed up
- @parents_of[requirement].push(states.size - 1) if @parents_of[requirement].empty?
-
- activated.delete_edge(outgoing_edge)
- requirements.delete(requirement)
+ if possibility.latest_version.nil?
+ # ensure there's a possibility for better error messages
+ possibility.possibilities << latest if latest
+ create_conflict
+ unwind_for_conflict
+ else
+ activate_new_spec
end
end
end
- # Attempts to activate the current {#possibility} (given that it hasn't
- # already been activated)
+ # Attempts to update the existing vertex's `PossibilitySet` with a filtered version
# @return [void]
- def attempt_to_activate_new_spec
- if new_spec_satisfied?
- activate_spec
+ def attempt_to_filter_existing_spec(vertex)
+ filtered_set = filtered_possibility_set(vertex)
+ if !filtered_set.possibilities.empty?
+ activated.set_payload(name, filtered_set)
+ new_requirements = requirements.dup
+ push_state_for_requirements(new_requirements, false)
else
create_conflict
+ debug(depth) { "Unsatisfied by existing spec (#{vertex.payload})" }
unwind_for_conflict
end
end
- # @return [Boolean] whether the current spec is satisfied as a new
- # possibility.
- def new_spec_satisfied?
- unless requirement_satisfied_by?(requirement, activated, possibility)
- debug(depth) { 'Unsatisfied by requested spec' }
- return false
- end
-
- locked_requirement = locked_requirement_named(name)
-
- locked_spec_satisfied = !locked_requirement ||
- requirement_satisfied_by?(locked_requirement, activated, possibility)
- debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
-
- locked_spec_satisfied
+ # Generates a filtered version of the existing vertex's `PossibilitySet` using the
+ # current state's `requirement`
+ # @param [Object] vertex existing vertex
+ # @return [PossibilitySet] filtered possibility set
+ def filtered_possibility_set(vertex)
+ PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
end
# @param [String] requirement_name the spec name to search for
@@ -434,7 +720,7 @@ module Bundler::Molinillo
# Add the current {#possibility} to the dependency graph of the current
# {#state}
# @return [void]
- def activate_spec
+ def activate_new_spec
conflicts.delete(name)
debug(depth) { "Activated #{name} at #{possibility}" }
activated.set_payload(name, possibility)
@@ -442,14 +728,14 @@ module Bundler::Molinillo
end
# Requires the dependencies that the recently activated spec has
- # @param [Object] activated_spec the specification that has just been
+ # @param [Object] possibility_set the PossibilitySet that has just been
# activated
# @return [void]
- def require_nested_dependencies_for(activated_spec)
- nested_dependencies = dependencies_for(activated_spec)
+ def require_nested_dependencies_for(possibility_set)
+ nested_dependencies = dependencies_for(possibility_set.latest_version)
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
nested_dependencies.each do |d|
- activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d)
+ activated.add_child_vertex(name_for(d), nil, [name_for(possibility_set.latest_version)], d)
parent_index = states.size - 1
parents = @parents_of[d]
parents << parent_index if parents.empty?
@@ -461,23 +747,82 @@ module Bundler::Molinillo
# Pushes a new {DependencyState} that encapsulates both existing and new
# requirements
# @param [Array] new_requirements
+ # @param [Boolean] requires_sort
+ # @param [Object] new_activated
# @return [void]
def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
- new_requirement = new_requirements.shift
+ new_requirement = nil
+ loop do
+ new_requirement = new_requirements.shift
+ break if new_requirement.nil? || states.none? { |s| s.requirement == new_requirement }
+ end
new_name = new_requirement ? name_for(new_requirement) : ''.freeze
- possibilities = new_requirement ? search_for(new_requirement) : []
+ possibilities = possibilities_for_requirement(new_requirement)
handle_missing_or_push_dependency_state DependencyState.new(
new_name, new_requirements, new_activated,
- new_requirement, possibilities, depth, conflicts.dup
+ new_requirement, possibilities, depth, conflicts.dup, unused_unwind_options.dup
)
end
+ # Checks a proposed requirement with any existing locked requirement
+ # before generating an array of possibilities for it.
+ # @param [Object] requirement the proposed requirement
+ # @param [Object] activated
+ # @return [Array] possibilities
+ def possibilities_for_requirement(requirement, activated = self.activated)
+ return [] unless requirement
+ if locked_requirement_named(name_for(requirement))
+ return locked_requirement_possibility_set(requirement, activated)
+ end
+
+ group_possibilities(search_for(requirement))
+ end
+
+ # @param [Object] requirement the proposed requirement
+ # @param [Object] activated
+ # @return [Array] possibility set containing only the locked requirement, if any
+ def locked_requirement_possibility_set(requirement, activated = self.activated)
+ all_possibilities = search_for(requirement)
+ locked_requirement = locked_requirement_named(name_for(requirement))
+
+ # Longwinded way to build a possibilities array with either the locked
+ # requirement or nothing in it. Required, since the API for
+ # locked_requirement isn't guaranteed.
+ locked_possibilities = all_possibilities.select do |possibility|
+ requirement_satisfied_by?(locked_requirement, activated, possibility)
+ end
+
+ group_possibilities(locked_possibilities)
+ end
+
+ # Build an array of PossibilitySets, with each element representing a group of
+ # dependency versions that all have the same sub-dependency version constraints
+ # and are contiguous.
+ # @param [Array] possibilities an array of possibilities
+ # @return [Array<PossibilitySet>] an array of possibility sets
+ def group_possibilities(possibilities)
+ possibility_sets = []
+ current_possibility_set = nil
+
+ possibilities.reverse_each do |possibility|
+ dependencies = dependencies_for(possibility)
+ if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
+ current_possibility_set.possibilities.unshift(possibility)
+ else
+ possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
+ current_possibility_set = possibility_sets.first
+ end
+ end
+
+ possibility_sets
+ end
+
# Pushes a new {DependencyState}.
# If the {#specification_provider} says to
# {SpecificationProvider#allow_missing?} that particular requirement, and
# there are no possibilities for that requirement, then `state` is not
- # pushed, and the node in {#activated} is removed, and we continue
+ # pushed, and the vertex in {#activated} is removed, and we continue
# resolving the remaining requirements.
# @param [DependencyState] state
# @return [void]
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb b/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb
index 50d853b146..95eaab5991 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph'
+
+require_relative 'dependency_graph'
module Bundler::Molinillo
# This class encapsulates a dependency resolver.
@@ -8,7 +9,7 @@ module Bundler::Molinillo
#
#
class Resolver
- require 'bundler/vendor/molinillo/lib/molinillo/resolution'
+ require_relative 'resolution'
# @return [SpecificationProvider] the specification provider used
# in the resolution process
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/state.rb b/lib/bundler/vendor/molinillo/lib/molinillo/state.rb
index 3a8107cf1a..68fa1f54e3 100644
--- a/lib/bundler/vendor/molinillo/lib/molinillo/state.rb
+++ b/lib/bundler/vendor/molinillo/lib/molinillo/state.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Bundler::Molinillo
# A state that a {Resolution} can be in
# @attr [String] name the name of the current requirement
@@ -7,7 +8,8 @@ module Bundler::Molinillo
# @attr [Object] requirement the current requirement
# @attr [Object] possibilities the possibilities to satisfy the current requirement
# @attr [Integer] depth the depth of the resolution
- # @attr [Set<Object>] conflicts unresolved conflicts
+ # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name
+ # @attr [Array<UnwindDetails>] unused_unwind_options unwinds for previous conflicts that weren't explored
ResolutionState = Struct.new(
:name,
:requirements,
@@ -15,14 +17,15 @@ module Bundler::Molinillo
:requirement,
:possibilities,
:depth,
- :conflicts
+ :conflicts,
+ :unused_unwind_options
)
class ResolutionState
# Returns an empty resolution state
# @return [ResolutionState] an empty state
def self.empty
- new(nil, [], DependencyGraph.new, nil, nil, 0, Set.new)
+ new(nil, [], DependencyGraph.new, nil, nil, 0, {}, [])
end
end
@@ -40,7 +43,8 @@ module Bundler::Molinillo
requirement,
[possibilities.pop],
depth + 1,
- conflicts.dup
+ conflicts.dup,
+ unused_unwind_options.dup
).tap do |state|
state.activated.tag(state)
end
diff --git a/lib/bundler/vendor/net-http-persistent/README.rdoc b/lib/bundler/vendor/net-http-persistent/README.rdoc
new file mode 100644
index 0000000000..4f95ad33ba
--- /dev/null
+++ b/lib/bundler/vendor/net-http-persistent/README.rdoc
@@ -0,0 +1,82 @@
+= net-http-persistent
+
+home :: https://github.com/drbrain/net-http-persistent
+rdoc :: http://docs.seattlerb.org/net-http-persistent
+
+== DESCRIPTION:
+
+Manages persistent connections using Net::HTTP including a thread pool for
+connecting to multiple hosts.
+
+Using persistent HTTP connections can dramatically increase the speed of HTTP.
+Creating a new HTTP connection for every request involves an extra TCP
+round-trip and causes TCP congestion avoidance negotiation to start over.
+
+Net::HTTP supports persistent connections with some API methods but does not
+make setting up a single persistent connection or managing multiple
+connections easy. Net::HTTP::Persistent wraps Net::HTTP and allows you to
+focus on how to make HTTP requests.
+
+== FEATURES/PROBLEMS:
+
+* Supports TLS with secure defaults
+* Thread-safe
+* Pure ruby
+
+== SYNOPSIS
+
+The following example will make two requests to the same server. The
+connection is kept alive between requests:
+
+ require 'net/http/persistent'
+
+ uri = URI 'http://example.com/awesome/web/service'
+
+ http = Net::HTTP::Persistent.new name: 'my_app_name'
+
+ # perform a GET
+ response = http.request uri
+
+ # create a POST
+ post_uri = uri + 'create'
+ post = Net::HTTP::Post.new post_uri.path
+ post.set_form_data 'some' => 'cool data'
+
+ # perform the POST, the URI is always required
+ response = http.request post_uri, post
+
+ # if you are done making http requests, or won't make requests for several
+ # minutes
+ http.shutdown
+
+Please see the documentation on Net::HTTP::Persistent for more information,
+including SSL connection verification, header handling and tunable options.
+
+== INSTALL:
+
+ gem install net-http-persistent
+
+== LICENSE:
+
+(The MIT License)
+
+Copyright (c) Eric Hodel, Aaron Patterson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb
deleted file mode 100644
index e5e09080c2..0000000000
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'net/protocol'
-
-##
-# Aaron Patterson's monkeypatch (accepted into 1.9.1) to fix Net::HTTP's speed
-# problems.
-#
-# http://gist.github.com/251244
-
-class Net::BufferedIO #:nodoc:
- alias :old_rbuf_fill :rbuf_fill
-
- def rbuf_fill
- if @io.respond_to? :read_nonblock then
- begin
- @rbuf << @io.read_nonblock(65536)
- rescue Errno::EWOULDBLOCK, Errno::EAGAIN => e
- retry if IO.select [@io], nil, nil, @read_timeout
- raise Timeout::Error, e.message
- end
- else # SSL sockets do not have read_nonblock
- timeout @read_timeout do
- @rbuf << @io.sysread(65536)
- end
- end
- end
-end if RUBY_VERSION < '1.9'
-
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
index c872a79c13..beff6d658b 100644
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
@@ -1,17 +1,7 @@
require 'net/http'
-begin
- require 'net/https'
-rescue LoadError
- # net/https or openssl
-end if RUBY_VERSION < '1.9' # but only for 1.8
-require 'bundler/vendor/net-http-persistent/lib/net/http/faster'
-require 'uri'
+require_relative '../../../../uri/lib/uri'
require 'cgi' # for escaping
-
-begin
- require 'net/http/pipeline'
-rescue LoadError
-end
+require_relative '../../../../connection_pool/lib/connection_pool'
autoload :OpenSSL, 'openssl'
@@ -22,23 +12,19 @@ autoload :OpenSSL, 'openssl'
# servers you wish to talk to. For each host:port you communicate with a
# single persistent connection is created.
#
-# Multiple Bundler::Persistent::Net::HTTP::Persistent objects will share the same set of
-# connections.
+# Connections will be shared across threads through a connection pool to
+# increase reuse of connections.
#
-# For each thread you start a new connection will be created. A
-# Bundler::Persistent::Net::HTTP::Persistent connection will not be shared across threads.
-#
-# You can shut down the HTTP connections when done by calling #shutdown. You
-# should name your Bundler::Persistent::Net::HTTP::Persistent object if you intend to call this
-# method.
+# You can shut down any remaining HTTP connections when done by calling
+# #shutdown.
#
# Example:
#
# require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
#
-# uri = URI 'http://example.com/awesome/web/service'
+# uri = Bundler::URI 'http://example.com/awesome/web/service'
#
-# http = Bundler::Persistent::Net::HTTP::Persistent.new 'my_app_name'
+# http = Bundler::Persistent::Net::HTTP::Persistent.new
#
# # perform a GET
# response = http.request uri
@@ -53,36 +39,40 @@ autoload :OpenSSL, 'openssl'
# post = Net::HTTP::Post.new post_uri.path
# post.set_form_data 'some' => 'cool data'
#
-# # perform the POST, the URI is always required
+# # perform the POST, the Bundler::URI is always required
# response http.request post_uri, post
#
# Note that for GET, HEAD and other requests that do not have a body you want
-# to use URI#request_uri not URI#path. The request_uri contains the query
+# to use Bundler::URI#request_uri not Bundler::URI#path. The request_uri contains the query
# params which are sent in the body for other requests.
#
-# == SSL
+# == TLS/SSL
#
-# SSL connections are automatically created depending upon the scheme of the
-# URI. SSL connections are automatically verified against the default
+# TLS connections are automatically created depending upon the scheme of the
+# Bundler::URI. TLS connections are automatically verified against the default
# certificate store for your computer. You can override this by changing
# verify_mode or by specifying an alternate cert_store.
#
-# Here are the SSL settings, see the individual methods for documentation:
+# Here are the TLS settings, see the individual methods for documentation:
#
# #certificate :: This client's certificate
-# #ca_file :: The certificate-authority
+# #ca_file :: The certificate-authorities
+# #ca_path :: Directory with certificate-authorities
# #cert_store :: An SSL certificate store
+# #ciphers :: List of SSl ciphers allowed
# #private_key :: The client's SSL private key
# #reuse_ssl_sessions :: Reuse a previously opened SSL session for a new
# connection
+# #ssl_timeout :: Session lifetime
# #ssl_version :: Which specific SSL version to use
# #verify_callback :: For server certificate verification
+# #verify_depth :: Depth of certificate verification
# #verify_mode :: How connections should be verified
#
# == Proxies
#
# A proxy can be set through #proxy= or at initialization time by providing a
-# second argument to ::new. The proxy may be the URI of the proxy server or
+# second argument to ::new. The proxy may be the Bundler::URI of the proxy server or
# <code>:ENV</code> which will consult environment variables.
#
# See #proxy= and #proxy_from_env for details.
@@ -102,14 +92,15 @@ autoload :OpenSSL, 'openssl'
#
# === Segregation
#
-# By providing an application name to ::new you can separate your connections
-# from the connections of other applications.
+# Each Bundler::Persistent::Net::HTTP::Persistent instance has its own pool of connections. There
+# is no sharing with other instances (as was true in earlier versions).
#
# === Idle Timeout
#
-# If a connection hasn't been used for this number of seconds it will automatically be
-# reset upon the next use to avoid attempting to send to a closed connection.
-# The default value is 5 seconds. nil means no timeout. Set through #idle_timeout.
+# If a connection hasn't been used for this number of seconds it will
+# automatically be reset upon the next use to avoid attempting to send to a
+# closed connection. The default value is 5 seconds. nil means no timeout.
+# Set through #idle_timeout.
#
# Reducing this value may help avoid the "too many connection resets" error
# when sending non-idempotent requests while increasing this value will cause
@@ -124,8 +115,9 @@ autoload :OpenSSL, 'openssl'
#
# The number of requests that should be made before opening a new connection.
# Typically many keep-alive capable servers tune this to 100 or less, so the
-# 101st request will fail with ECONNRESET. If unset (default), this value has no
-# effect, if set, connections will be reset on the request after max_requests.
+# 101st request will fail with ECONNRESET. If unset (default), this value has
+# no effect, if set, connections will be reset on the request after
+# max_requests.
#
# === Open Timeout
#
@@ -137,45 +129,6 @@ autoload :OpenSSL, 'openssl'
# Socket options may be set on newly-created connections. See #socket_options
# for details.
#
-# === Non-Idempotent Requests
-#
-# By default non-idempotent requests will not be retried per RFC 2616. By
-# setting retry_change_requests to true requests will automatically be retried
-# once.
-#
-# Only do this when you know that retrying a POST or other non-idempotent
-# request is safe for your application and will not create duplicate
-# resources.
-#
-# The recommended way to handle non-idempotent requests is the following:
-#
-# require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
-#
-# uri = URI 'http://example.com/awesome/web/service'
-# post_uri = uri + 'create'
-#
-# http = Bundler::Persistent::Net::HTTP::Persistent.new 'my_app_name'
-#
-# post = Net::HTTP::Post.new post_uri.path
-# # ... fill in POST request
-#
-# begin
-# response = http.request post_uri, post
-# rescue Bundler::Persistent::Net::HTTP::Persistent::Error
-#
-# # POST failed, make a new request to verify the server did not process
-# # the request
-# exists_uri = uri + '...'
-# response = http.get exists_uri
-#
-# # Retry if it failed
-# retry if response.code == '404'
-# end
-#
-# The method of determining if the resource was created or not is unique to
-# the particular service you are using. Of course, you will want to add
-# protection from infinite looping.
-#
# === Connection Termination
#
# If you are done using the Bundler::Persistent::Net::HTTP::Persistent instance you may shut down
@@ -201,24 +154,27 @@ class Bundler::Persistent::Net::HTTP::Persistent
HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
##
- # The version of Bundler::Persistent::Net::HTTP::Persistent you are using
+ # The default connection pool size is 1/4 the allowed open files
+ # (<code>ulimit -n</code>) or 256 if your OS does not support file handle
+ # limits (typically windows).
- VERSION = '2.9.4'
+ if Process.const_defined? :RLIMIT_NOFILE
+ open_file_limits = Process.getrlimit(Process::RLIMIT_NOFILE)
+
+ # Under JRuby on Windows Process responds to `getrlimit` but returns something that does not match docs
+ if open_file_limits.respond_to?(:first)
+ DEFAULT_POOL_SIZE = open_file_limits.first / 4
+ else
+ DEFAULT_POOL_SIZE = 256
+ end
+ else
+ DEFAULT_POOL_SIZE = 256
+ end
##
- # Exceptions rescued for automatic retry on ruby 2.0.0. This overlaps with
- # the exception list for ruby 1.x.
+ # The version of Bundler::Persistent::Net::HTTP::Persistent you are using
- RETRIED_EXCEPTIONS = [ # :nodoc:
- (Net::ReadTimeout if Net.const_defined? :ReadTimeout),
- IOError,
- EOFError,
- Errno::ECONNRESET,
- Errno::ECONNABORTED,
- Errno::EPIPE,
- (OpenSSL::SSL::SSLError if HAVE_OPENSSL),
- Timeout::Error,
- ].compact
+ VERSION = '4.0.0'
##
# Error class for errors raised by Bundler::Persistent::Net::HTTP::Persistent. Various
@@ -241,38 +197,38 @@ class Bundler::Persistent::Net::HTTP::Persistent
# NOTE: This may not work on ruby > 1.9.
def self.detect_idle_timeout uri, max = 10
- uri = URI uri unless URI::Generic === uri
+ uri = Bundler::URI uri unless Bundler::URI::Generic === uri
uri += '/'
req = Net::HTTP::Head.new uri.request_uri
http = new 'net-http-persistent detect_idle_timeout'
- connection = http.connection_for uri
+ http.connection_for uri do |connection|
+ sleep_time = 0
- sleep_time = 0
+ http = connection.http
- loop do
- response = connection.request req
+ loop do
+ response = http.request req
- $stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG
+ $stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG
- unless Net::HTTPOK === response then
- raise Error, "bad response code #{response.code} detecting idle timeout"
- end
+ unless Net::HTTPOK === response then
+ raise Error, "bad response code #{response.code} detecting idle timeout"
+ end
- break if sleep_time >= max
+ break if sleep_time >= max
- sleep_time += 1
+ sleep_time += 1
- $stderr.puts "sleeping #{sleep_time}" if $DEBUG
- sleep sleep_time
+ $stderr.puts "sleeping #{sleep_time}" if $DEBUG
+ sleep sleep_time
+ end
end
rescue
# ignore StandardErrors, we've probably found the idle timeout.
ensure
- http.shutdown
-
return sleep_time unless $!
end
@@ -281,7 +237,9 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_reader :certificate
+ ##
# For Net::HTTP parity
+
alias cert certificate
##
@@ -291,12 +249,23 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_reader :ca_file
##
+ # A directory of SSL certificates to be used as certificate authorities.
+ # Setting this will set verify_mode to VERIFY_PEER.
+
+ attr_reader :ca_path
+
+ ##
# An SSL certificate store. Setting this will override the default
# certificate store. See verify_mode for more information.
attr_reader :cert_store
##
+ # The ciphers allowed for SSL connections
+
+ attr_reader :ciphers
+
+ ##
# Sends debug_output to this IO via Net::HTTP#set_debug_output.
#
# Never use this method in production code, it causes a serious security
@@ -310,11 +279,6 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_reader :generation # :nodoc:
##
- # Where this instance's connections live in the thread local variables
-
- attr_reader :generation_key # :nodoc:
-
- ##
# Headers that are added to every request using Net::HTTP#add_field
attr_reader :headers
@@ -338,6 +302,13 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_accessor :max_requests
##
+ # Number of retries to perform if a request fails.
+ #
+ # See also #max_retries=, Net::HTTP#max_retries=.
+
+ attr_reader :max_retries
+
+ ##
# The value sent in the Keep-Alive header. Defaults to 30. Not needed for
# HTTP/1.1 servers.
#
@@ -349,8 +320,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_accessor :keep_alive
##
- # A name for this connection. Allows you to keep your connections apart
- # from everybody else's.
+ # The name for this collection of persistent connections.
attr_reader :name
@@ -369,7 +339,9 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_reader :private_key
+ ##
# For Net::HTTP parity
+
alias key private_key
##
@@ -383,14 +355,19 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_reader :no_proxy
##
+ # Test-only accessor for the connection pool
+
+ attr_reader :pool # :nodoc:
+
+ ##
# Seconds to wait until reading one block. See Net::HTTP#read_timeout
attr_accessor :read_timeout
##
- # Where this instance's request counts live in the thread local variables
+ # Seconds to wait until writing one block. See Net::HTTP#write_timeout
- attr_reader :request_key # :nodoc:
+ attr_accessor :write_timeout
##
# By default SSL sessions are reused to avoid extra SSL handshakes. Set
@@ -418,17 +395,33 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_reader :ssl_generation # :nodoc:
##
- # Where this instance's SSL connections live in the thread local variables
+ # SSL session lifetime
- attr_reader :ssl_generation_key # :nodoc:
+ attr_reader :ssl_timeout
##
# SSL version to use.
#
# By default, the version will be negotiated automatically between client
- # and server. Ruby 1.9 and newer only.
+ # and server. Ruby 1.9 and newer only. Deprecated since Ruby 2.5.
- attr_reader :ssl_version if RUBY_VERSION > '1.9'
+ attr_reader :ssl_version
+
+ ##
+ # Minimum SSL version to use, e.g. :TLS1_1
+ #
+ # By default, the version will be negotiated automatically between client
+ # and server. Ruby 2.5 and newer only.
+
+ attr_reader :min_version
+
+ ##
+ # Maximum SSL version to use, e.g. :TLS1_2
+ #
+ # By default, the version will be negotiated automatically between client
+ # and server. Ruby 2.5 and newer only.
+
+ attr_reader :max_version
##
# Where this instance's last-use times live in the thread local variables
@@ -436,50 +429,48 @@ class Bundler::Persistent::Net::HTTP::Persistent
attr_reader :timeout_key # :nodoc:
##
- # SSL verification callback. Used when ca_file is set.
+ # SSL verification callback. Used when ca_file or ca_path is set.
attr_reader :verify_callback
##
+ # Sets the depth of SSL certificate verification
+
+ attr_reader :verify_depth
+
+ ##
# HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER which verifies
# the server certificate.
#
- # If no ca_file or cert_store is set the default system certificate store is
- # used.
+ # If no ca_file, ca_path or cert_store is set the default system certificate
+ # store is used.
#
# You can use +verify_mode+ to override any default values.
attr_reader :verify_mode
##
- # Enable retries of non-idempotent requests that change data (e.g. POST
- # requests) when the server has disconnected.
- #
- # This will in the worst case lead to multiple requests with the same data,
- # but it may be useful for some applications. Take care when enabling
- # this option to ensure it is safe to POST or perform other non-idempotent
- # requests to the server.
-
- attr_accessor :retry_change_requests
-
- ##
# Creates a new Bundler::Persistent::Net::HTTP::Persistent.
#
- # Set +name+ to keep your connections apart from everybody else's. Not
- # required currently, but highly recommended. Your library name should be
- # good enough. This parameter will be required in a future version.
+ # Set a +name+ for fun. Your library name should be good enough, but this
+ # otherwise has no purpose.
#
- # +proxy+ may be set to a URI::HTTP or :ENV to pick up proxy options from
+ # +proxy+ may be set to a Bundler::URI::HTTP or :ENV to pick up proxy options from
# the environment. See proxy_from_env for details.
#
- # In order to use a URI for the proxy you may need to do some extra work
- # beyond URI parsing if the proxy requires a password:
+ # In order to use a Bundler::URI for the proxy you may need to do some extra work
+ # beyond Bundler::URI parsing if the proxy requires a password:
#
- # proxy = URI 'http://proxy.example'
+ # proxy = Bundler::URI 'http://proxy.example'
# proxy.user = 'AzureDiamond'
# proxy.password = 'hunter2'
+ #
+ # Set +pool_size+ to limit the maximum number of connections allowed.
+ # Defaults to 1/4 the number of allowed file handles or 256 if your OS does
+ # not support a limit on allowed file handles. You can have no more than
+ # this many threads with active HTTP transactions.
- def initialize name = nil, proxy = nil
+ def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE
@name = name
@debug_output = nil
@@ -491,40 +482,41 @@ class Bundler::Persistent::Net::HTTP::Persistent
@keep_alive = 30
@open_timeout = nil
@read_timeout = nil
+ @write_timeout = nil
@idle_timeout = 5
@max_requests = nil
+ @max_retries = 1
@socket_options = []
+ @ssl_generation = 0 # incremented when SSL session variables change
@socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
Socket.const_defined? :TCP_NODELAY
- key = ['net_http_persistent', name].compact
- @generation_key = [key, 'generations' ].join('_').intern
- @ssl_generation_key = [key, 'ssl_generations'].join('_').intern
- @request_key = [key, 'requests' ].join('_').intern
- @timeout_key = [key, 'timeouts' ].join('_').intern
+ @pool = Bundler::Persistent::Net::HTTP::Persistent::Pool.new size: pool_size do |http_args|
+ Bundler::Persistent::Net::HTTP::Persistent::Connection.new Net::HTTP, http_args, @ssl_generation
+ end
@certificate = nil
@ca_file = nil
+ @ca_path = nil
+ @ciphers = nil
@private_key = nil
+ @ssl_timeout = nil
@ssl_version = nil
+ @min_version = nil
+ @max_version = nil
@verify_callback = nil
+ @verify_depth = nil
@verify_mode = nil
@cert_store = nil
- @generation = 0 # incremented when proxy URI changes
- @ssl_generation = 0 # incremented when SSL session variables change
+ @generation = 0 # incremented when proxy Bundler::URI changes
if HAVE_OPENSSL then
@verify_mode = OpenSSL::SSL::VERIFY_PEER
@reuse_ssl_sessions = OpenSSL::SSL.const_defined? :Session
end
- @retry_change_requests = false
-
- @ruby_1 = RUBY_VERSION < '2'
- @retried_on_ruby_2 = !@ruby_1
-
self.proxy = proxy if proxy
end
@@ -550,6 +542,15 @@ class Bundler::Persistent::Net::HTTP::Persistent
end
##
+ # Sets the SSL certificate authority path.
+
+ def ca_path= path
+ @ca_path = path
+
+ reconnect_ssl
+ end
+
+ ##
# Overrides the default SSL certificate store used for verifying
# connections.
@@ -560,117 +561,74 @@ class Bundler::Persistent::Net::HTTP::Persistent
end
##
- # Finishes all connections on the given +thread+ that were created before
- # the given +generation+ in the threads +generation_key+ list.
- #
- # See #shutdown for a bunch of scary warning about misusing this method.
+ # The ciphers allowed for SSL connections
- def cleanup(generation, thread = Thread.current,
- generation_key = @generation_key) # :nodoc:
- timeouts = thread[@timeout_key]
+ def ciphers= ciphers
+ @ciphers = ciphers
- (0...generation).each do |old_generation|
- next unless thread[generation_key]
-
- conns = thread[generation_key].delete old_generation
-
- conns.each_value do |conn|
- finish conn, thread
-
- timeouts.delete conn.object_id if timeouts
- end if conns
- end
+ reconnect_ssl
end
##
# Creates a new connection for +uri+
def connection_for uri
- Thread.current[@generation_key] ||= Hash.new { |h,k| h[k] = {} }
- Thread.current[@ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
- Thread.current[@request_key] ||= Hash.new 0
- Thread.current[@timeout_key] ||= Hash.new EPOCH
-
use_ssl = uri.scheme.downcase == 'https'
- if use_ssl then
- raise Bundler::Persistent::Net::HTTP::Persistent::Error, 'OpenSSL is not available' unless
- HAVE_OPENSSL
-
- ssl_generation = @ssl_generation
-
- ssl_cleanup ssl_generation
-
- connections = Thread.current[@ssl_generation_key][ssl_generation]
- else
- generation = @generation
-
- cleanup generation
-
- connections = Thread.current[@generation_key][generation]
- end
-
- net_http_args = [uri.host, uri.port]
- connection_id = net_http_args.join ':'
+ net_http_args = [uri.hostname, uri.port]
+ # I'm unsure if uri.host or uri.hostname should be checked against
+ # the proxy bypass list.
if @proxy_uri and not proxy_bypass? uri.host, uri.port then
- connection_id << @proxy_connection_id
net_http_args.concat @proxy_args
else
net_http_args.concat [nil, nil, nil, nil]
end
- connection = connections[connection_id]
+ connection = @pool.checkout net_http_args
- unless connection = connections[connection_id] then
- connections[connection_id] = http_class.new(*net_http_args)
- connection = connections[connection_id]
- ssl connection if use_ssl
- else
- reset connection if expired? connection
- end
+ http = connection.http
- start connection unless connection.started?
+ connection.ressl @ssl_generation if
+ connection.ssl_generation != @ssl_generation
+
+ if not http.started? then
+ ssl http if use_ssl
+ start http
+ elsif expired? connection then
+ reset connection
+ end
- connection.read_timeout = @read_timeout if @read_timeout
- connection.keep_alive_timeout = @idle_timeout if @idle_timeout && connection.respond_to?(:keep_alive_timeout=)
+ http.keep_alive_timeout = @idle_timeout if @idle_timeout
+ http.max_retries = @max_retries if http.respond_to?(:max_retries=)
+ http.read_timeout = @read_timeout if @read_timeout
+ http.write_timeout = @write_timeout if
+ @write_timeout && http.respond_to?(:write_timeout=)
- connection
+ return yield connection
rescue Errno::ECONNREFUSED
- address = connection.proxy_address || connection.address
- port = connection.proxy_port || connection.port
+ address = http.proxy_address || http.address
+ port = http.proxy_port || http.port
raise Error, "connection refused: #{address}:#{port}"
rescue Errno::EHOSTDOWN
- address = connection.proxy_address || connection.address
- port = connection.proxy_port || connection.port
+ address = http.proxy_address || http.address
+ port = http.proxy_port || http.port
raise Error, "host down: #{address}:#{port}"
+ ensure
+ @pool.checkin net_http_args
end
##
- # Returns an error message containing the number of requests performed on
- # this connection
-
- def error_message connection
- requests = Thread.current[@request_key][connection.object_id] - 1 # fixup
- last_use = Thread.current[@timeout_key][connection.object_id]
-
- age = Time.now - last_use
-
- "after #{requests} requests on #{connection.object_id}, " \
- "last used #{age} seconds ago"
- end
-
- ##
- # URI::escape wrapper
+ # CGI::escape wrapper
def escape str
CGI.escape str if str
end
##
- # URI::unescape wrapper
+ # CGI::unescape wrapper
def unescape str
CGI.unescape str if str
@@ -682,26 +640,23 @@ class Bundler::Persistent::Net::HTTP::Persistent
# maximum request count, false otherwise.
def expired? connection
- requests = Thread.current[@request_key][connection.object_id]
- return true if @max_requests && requests >= @max_requests
+ return true if @max_requests && connection.requests >= @max_requests
return false unless @idle_timeout
return true if @idle_timeout.zero?
- last_used = Thread.current[@timeout_key][connection.object_id]
-
- Time.now - last_used > @idle_timeout
+ Time.now - connection.last_use > @idle_timeout
end
##
# Starts the Net::HTTP +connection+
- def start connection
- connection.set_debug_output @debug_output if @debug_output
- connection.open_timeout = @open_timeout if @open_timeout
+ def start http
+ http.set_debug_output @debug_output if @debug_output
+ http.open_timeout = @open_timeout if @open_timeout
- connection.start
+ http.start
- socket = connection.instance_variable_get :@socket
+ socket = http.instance_variable_get :@socket
if socket then # for fakeweb
@socket_options.each do |option|
@@ -713,96 +668,19 @@ class Bundler::Persistent::Net::HTTP::Persistent
##
# Finishes the Net::HTTP +connection+
- def finish connection, thread = Thread.current
- if requests = thread[@request_key] then
- requests.delete connection.object_id
- end
-
+ def finish connection
connection.finish
- rescue IOError
- end
- def http_class # :nodoc:
- if RUBY_VERSION > '2.0' then
- Net::HTTP
- elsif [:Artifice, :FakeWeb, :WebMock].any? { |klass|
- Object.const_defined?(klass)
- } or not @reuse_ssl_sessions then
- Net::HTTP
- else
- Bundler::Persistent::Net::HTTP::Persistent::SSLReuse
- end
+ connection.http.instance_variable_set :@last_communicated, nil
+ connection.http.instance_variable_set :@ssl_session, nil unless
+ @reuse_ssl_sessions
end
##
# Returns the HTTP protocol version for +uri+
def http_version uri
- @http_versions["#{uri.host}:#{uri.port}"]
- end
-
- ##
- # Is +req+ idempotent according to RFC 2616?
-
- def idempotent? req
- case req
- when Net::HTTP::Delete, Net::HTTP::Get, Net::HTTP::Head,
- Net::HTTP::Options, Net::HTTP::Put, Net::HTTP::Trace then
- true
- end
- end
-
- ##
- # Is the request +req+ idempotent or is retry_change_requests allowed.
- #
- # If +retried_on_ruby_2+ is true, true will be returned if we are on ruby,
- # retry_change_requests is allowed and the request is not idempotent.
-
- def can_retry? req, retried_on_ruby_2 = false
- return @retry_change_requests && !idempotent?(req) if retried_on_ruby_2
-
- @retry_change_requests || idempotent?(req)
- end
-
- if RUBY_VERSION > '1.9' then
- ##
- # Workaround for missing Net::HTTPHeader#connection_close? on Ruby 1.8
-
- def connection_close? header
- header.connection_close?
- end
-
- ##
- # Workaround for missing Net::HTTPHeader#connection_keep_alive? on Ruby 1.8
-
- def connection_keep_alive? header
- header.connection_keep_alive?
- end
- else
- ##
- # Workaround for missing Net::HTTPRequest#connection_close? on Ruby 1.8
-
- def connection_close? header
- header['connection'] =~ /close/ or header['proxy-connection'] =~ /close/
- end
-
- ##
- # Workaround for missing Net::HTTPRequest#connection_keep_alive? on Ruby
- # 1.8
-
- def connection_keep_alive? header
- header['connection'] =~ /keep-alive/ or
- header['proxy-connection'] =~ /keep-alive/
- end
- end
-
- ##
- # Deprecated in favor of #expired?
-
- def max_age # :nodoc:
- return Time.now + 1 unless @idle_timeout
-
- Time.now - @idle_timeout
+ @http_versions["#{uri.hostname}:#{uri.port}"]
end
##
@@ -813,20 +691,20 @@ class Bundler::Persistent::Net::HTTP::Persistent
end
##
- # Pipelines +requests+ to the HTTP server at +uri+ yielding responses if a
- # block is given. Returns all responses recieved.
+ # Set the maximum number of retries for a request.
#
- # See
- # Net::HTTP::Pipeline[http://docs.seattlerb.org/net-http-pipeline/Net/HTTP/Pipeline.html]
- # for further details.
+ # Defaults to one retry.
#
- # Only if <tt>net-http-pipeline</tt> was required before
- # <tt>net-http-persistent</tt> #pipeline will be present.
+ # Set this to 0 to disable retries.
+
+ def max_retries= retries
+ retries = retries.to_int
+
+ raise ArgumentError, "max_retries must be positive" if retries < 0
- def pipeline uri, requests, &block # :yields: responses
- connection = connection_for uri
+ @max_retries = retries
- connection.pipeline requests, &block
+ reconnect
end
##
@@ -842,12 +720,12 @@ class Bundler::Persistent::Net::HTTP::Persistent
alias key= private_key=
##
- # Sets the proxy server. The +proxy+ may be the URI of the proxy server,
+ # Sets the proxy server. The +proxy+ may be the Bundler::URI of the proxy server,
# the symbol +:ENV+ which will read the proxy from the environment or nil to
# disable use of a proxy. See #proxy_from_env for details on setting the
# proxy from the environment.
#
- # If the proxy URI is set after requests have been made, the next request
+ # If the proxy Bundler::URI is set after requests have been made, the next request
# will shut-down and re-open all connections.
#
# The +no_proxy+ query parameter can be used to specify hosts which shouldn't
@@ -858,16 +736,16 @@ class Bundler::Persistent::Net::HTTP::Persistent
def proxy= proxy
@proxy_uri = case proxy
when :ENV then proxy_from_env
- when URI::HTTP then proxy
+ when Bundler::URI::HTTP then proxy
when nil then # ignore
- else raise ArgumentError, 'proxy must be :ENV or a URI::HTTP'
+ else raise ArgumentError, 'proxy must be :ENV or a Bundler::URI::HTTP'
end
@no_proxy.clear
if @proxy_uri then
@proxy_args = [
- @proxy_uri.host,
+ @proxy_uri.hostname,
@proxy_uri.port,
unescape(@proxy_uri.user),
unescape(@proxy_uri.password),
@@ -885,13 +763,13 @@ class Bundler::Persistent::Net::HTTP::Persistent
end
##
- # Creates a URI for an HTTP proxy server from ENV variables.
+ # Creates a Bundler::URI for an HTTP proxy server from ENV variables.
#
# If +HTTP_PROXY+ is set a proxy will be returned.
#
- # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the URI is given the
+ # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the Bundler::URI is given the
# indicated user and password unless HTTP_PROXY contains either of these in
- # the URI.
+ # the Bundler::URI.
#
# The +NO_PROXY+ ENV variable can be used to specify hosts which shouldn't
# be reached via proxy; if set it should be a comma separated list of
@@ -907,7 +785,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
return nil if env_proxy.nil? or env_proxy.empty?
- uri = URI normalize_uri env_proxy
+ uri = Bundler::URI normalize_uri env_proxy
env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
@@ -942,14 +820,15 @@ class Bundler::Persistent::Net::HTTP::Persistent
end
##
- # Forces reconnection of HTTP connections.
+ # Forces reconnection of all HTTP connections, including TLS/SSL
+ # connections.
def reconnect
@generation += 1
end
##
- # Forces reconnection of SSL connections.
+ # Forces reconnection of only TLS/SSL connections.
def reconnect_ssl
@ssl_generation += 1
@@ -959,18 +838,17 @@ class Bundler::Persistent::Net::HTTP::Persistent
# Finishes then restarts the Net::HTTP +connection+
def reset connection
- Thread.current[@request_key].delete connection.object_id
- Thread.current[@timeout_key].delete connection.object_id
+ http = connection.http
finish connection
- start connection
+ start http
rescue Errno::ECONNREFUSED
- e = Error.new "connection refused: #{connection.address}:#{connection.port}"
+ e = Error.new "connection refused: #{http.address}:#{http.port}"
e.set_backtrace $@
raise e
rescue Errno::EHOSTDOWN
- e = Error.new "host down: #{connection.address}:#{connection.port}"
+ e = Error.new "host down: #{http.address}:#{http.port}"
e.set_backtrace $@
raise e
end
@@ -982,92 +860,49 @@ class Bundler::Persistent::Net::HTTP::Persistent
# If a block is passed #request behaves like Net::HTTP#request (the body of
# the response will not have been read).
#
- # +req+ must be a Net::HTTPRequest subclass (see Net::HTTP for a list).
- #
- # If there is an error and the request is idempotent according to RFC 2616
- # it will be retried automatically.
+ # +req+ must be a Net::HTTPGenericRequest subclass (see Net::HTTP for a list).
def request uri, req = nil, &block
- retried = false
- bad_response = false
-
- req = request_setup req || uri
-
- connection = connection_for uri
- connection_id = connection.object_id
-
- begin
- Thread.current[@request_key][connection_id] += 1
- response = connection.request req, &block
-
- if connection_close?(req) or
- (response.http_version <= '1.0' and
- not connection_keep_alive?(response)) or
- connection_close?(response) then
- connection.finish
+ uri = Bundler::URI uri
+ req = request_setup req || uri
+ response = nil
+
+ connection_for uri do |connection|
+ http = connection.http
+
+ begin
+ connection.requests += 1
+
+ response = http.request req, &block
+
+ if req.connection_close? or
+ (response.http_version <= '1.0' and
+ not response.connection_keep_alive?) or
+ response.connection_close? then
+ finish connection
+ end
+ rescue Exception # make sure to close the connection when it was interrupted
+ finish connection
+
+ raise
+ ensure
+ connection.last_use = Time.now
end
- rescue Net::HTTPBadResponse => e
- message = error_message connection
-
- finish connection
-
- raise Error, "too many bad responses #{message}" if
- bad_response or not can_retry? req
-
- bad_response = true
- retry
- rescue *RETRIED_EXCEPTIONS => e # retried on ruby 2
- request_failed e, req, connection if
- retried or not can_retry? req, @retried_on_ruby_2
-
- reset connection
-
- retried = true
- retry
- rescue Errno::EINVAL, Errno::ETIMEDOUT => e # not retried on ruby 2
- request_failed e, req, connection if retried or not can_retry? req
-
- reset connection
-
- retried = true
- retry
- rescue Exception => e
- finish connection
-
- raise
- ensure
- Thread.current[@timeout_key][connection_id] = Time.now
end
- @http_versions["#{uri.host}:#{uri.port}"] ||= response.http_version
+ @http_versions["#{uri.hostname}:#{uri.port}"] ||= response.http_version
response
end
##
- # Raises an Error for +exception+ which resulted from attempting the request
- # +req+ on the +connection+.
- #
- # Finishes the +connection+.
-
- def request_failed exception, req, connection # :nodoc:
- due_to = "(due to #{exception.message} - #{exception.class})"
- message = "too many connection resets #{due_to} #{error_message connection}"
-
- finish connection
-
-
- raise Error, message, exception.backtrace
- end
-
- ##
- # Creates a GET request if +req_or_uri+ is a URI and adds headers to the
+ # Creates a GET request if +req_or_uri+ is a Bundler::URI and adds headers to the
# request.
#
# Returns the request.
def request_setup req_or_uri # :nodoc:
- req = if URI === req_or_uri then
+ req = if req_or_uri.respond_to? 'request_uri' then
Net::HTTP::Get.new req_or_uri.request_uri
else
req_or_uri
@@ -1090,45 +925,15 @@ class Bundler::Persistent::Net::HTTP::Persistent
end
##
- # Shuts down all connections for +thread+.
- #
- # Uses the current thread by default.
- #
- # If you've used Bundler::Persistent::Net::HTTP::Persistent across multiple threads you should
- # call this in each thread when you're done making HTTP requests.
- #
- # *NOTE*: Calling shutdown for another thread can be dangerous!
- #
- # If the thread is still using the connection it may cause an error! It is
- # best to call #shutdown in the thread at the appropriate time instead!
-
- def shutdown thread = Thread.current
- generation = reconnect
- cleanup generation, thread, @generation_key
-
- ssl_generation = reconnect_ssl
- cleanup ssl_generation, thread, @ssl_generation_key
-
- thread[@request_key] = nil
- thread[@timeout_key] = nil
- end
-
- ##
- # Shuts down all connections in all threads
- #
- # *NOTE*: THIS METHOD IS VERY DANGEROUS!
+ # Shuts down all connections
#
- # Do not call this method if other threads are still using their
- # connections! Call #shutdown at the appropriate time instead!
+ # *NOTE*: Calling shutdown for can be dangerous!
#
- # Use this method only as a last resort!
+ # If any thread is still using a connection it may cause an error! Call
+ # #shutdown when you are completely done making requests!
- def shutdown_in_all_threads
- Thread.list.each do |thread|
- shutdown thread
- end
-
- nil
+ def shutdown
+ @pool.shutdown { |http| http.finish }
end
##
@@ -1137,9 +942,14 @@ class Bundler::Persistent::Net::HTTP::Persistent
def ssl connection
connection.use_ssl = true
+ connection.ciphers = @ciphers if @ciphers
+ connection.ssl_timeout = @ssl_timeout if @ssl_timeout
connection.ssl_version = @ssl_version if @ssl_version
+ connection.min_version = @min_version if @min_version
+ connection.max_version = @max_version if @max_version
- connection.verify_mode = @verify_mode
+ connection.verify_depth = @verify_depth
+ connection.verify_mode = @verify_mode
if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and
not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then
@@ -1168,8 +978,10 @@ application:
WARNING
end
- if @ca_file then
- connection.ca_file = @ca_file
+ connection.ca_file = @ca_file if @ca_file
+ connection.ca_path = @ca_path if @ca_path
+
+ if @ca_file or @ca_path then
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
connection.verify_callback = @verify_callback if @verify_callback
end
@@ -1189,11 +1001,12 @@ application:
end
##
- # Finishes all connections that existed before the given SSL parameter
- # +generation+.
+ # SSL session lifetime
+
+ def ssl_timeout= ssl_timeout
+ @ssl_timeout = ssl_timeout
- def ssl_cleanup generation # :nodoc:
- cleanup generation, Thread.current, @ssl_generation_key
+ reconnect_ssl
end
##
@@ -1203,7 +1016,34 @@ application:
@ssl_version = ssl_version
reconnect_ssl
- end if RUBY_VERSION > '1.9'
+ end
+
+ ##
+ # Minimum SSL version to use
+
+ def min_version= min_version
+ @min_version = min_version
+
+ reconnect_ssl
+ end
+
+ ##
+ # maximum SSL version to use
+
+ def max_version= max_version
+ @max_version = max_version
+
+ reconnect_ssl
+ end
+
+ ##
+ # Sets the depth of SSL certificate verification
+
+ def verify_depth= verify_depth
+ @verify_depth = verify_depth
+
+ reconnect_ssl
+ end
##
# Sets the HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER.
@@ -1226,8 +1066,8 @@ application:
reconnect_ssl
end
-
end
-require 'bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse'
+require_relative 'persistent/connection'
+require_relative 'persistent/pool'
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb
new file mode 100644
index 0000000000..a57a5d1352
--- /dev/null
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb
@@ -0,0 +1,40 @@
+##
+# A Net::HTTP connection wrapper that holds extra information for managing the
+# connection's lifetime.
+
+class Bundler::Persistent::Net::HTTP::Persistent::Connection # :nodoc:
+
+ attr_accessor :http
+
+ attr_accessor :last_use
+
+ attr_accessor :requests
+
+ attr_accessor :ssl_generation
+
+ def initialize http_class, http_args, ssl_generation
+ @http = http_class.new(*http_args)
+ @ssl_generation = ssl_generation
+
+ reset
+ end
+
+ def finish
+ @http.finish
+ rescue IOError
+ ensure
+ reset
+ end
+
+ def reset
+ @last_use = Bundler::Persistent::Net::HTTP::Persistent::EPOCH
+ @requests = 0
+ end
+
+ def ressl ssl_generation
+ @ssl_generation = ssl_generation
+
+ finish
+ end
+
+end
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
new file mode 100644
index 0000000000..9dfa6ffdb1
--- /dev/null
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
@@ -0,0 +1,53 @@
+class Bundler::Persistent::Net::HTTP::Persistent::Pool < Bundler::ConnectionPool # :nodoc:
+
+ attr_reader :available # :nodoc:
+ attr_reader :key # :nodoc:
+
+ def initialize(options = {}, &block)
+ super
+
+ @available = Bundler::Persistent::Net::HTTP::Persistent::TimedStackMulti.new(@size, &block)
+ @key = "current-#{@available.object_id}"
+ end
+
+ def checkin net_http_args
+ stack = Thread.current[@key][net_http_args] ||= []
+
+ raise Bundler::ConnectionPool::Error, 'no connections are checked out' if
+ stack.empty?
+
+ conn = stack.pop
+
+ if stack.empty?
+ @available.push conn, connection_args: net_http_args
+
+ Thread.current[@key].delete(net_http_args)
+ Thread.current[@key] = nil if Thread.current[@key].empty?
+ end
+
+ nil
+ end
+
+ def checkout net_http_args
+ stacks = Thread.current[@key] ||= {}
+ stack = stacks[net_http_args] ||= []
+
+ if stack.empty? then
+ conn = @available.pop connection_args: net_http_args
+ else
+ conn = stack.last
+ end
+
+ stack.push conn
+
+ conn
+ end
+
+ def shutdown
+ Thread.current[@key] = nil
+ super
+ end
+end
+
+require_relative 'timed_stack_multi'
+
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb
deleted file mode 100644
index 1b6b789f6d..0000000000
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-##
-# This Net::HTTP subclass adds SSL session reuse and Server Name Indication
-# (SNI) RFC 3546.
-#
-# DO NOT DEPEND UPON THIS CLASS
-#
-# This class is an implementation detail and is subject to change or removal
-# at any time.
-
-class Bundler::Persistent::Net::HTTP::Persistent::SSLReuse < Net::HTTP
-
- @is_proxy_class = false
- @proxy_addr = nil
- @proxy_port = nil
- @proxy_user = nil
- @proxy_pass = nil
-
- def initialize address, port = nil # :nodoc:
- super
-
- @ssl_session = nil
- end
-
- ##
- # From ruby trunk r33086 including http://redmine.ruby-lang.org/issues/5341
-
- def connect # :nodoc:
- D "opening connection to #{conn_address()}..."
- s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
- D "opened"
- if use_ssl?
- ssl_parameters = Hash.new
- iv_list = instance_variables
- SSL_ATTRIBUTES.each do |name|
- ivname = "@#{name}".intern
- if iv_list.include?(ivname) and
- value = instance_variable_get(ivname)
- ssl_parameters[name] = value
- end
- end
- unless @ssl_context then
- @ssl_context = OpenSSL::SSL::SSLContext.new
- @ssl_context.set_params(ssl_parameters)
- end
- s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
- s.sync_close = true
- end
- @socket = Net::BufferedIO.new(s)
- @socket.read_timeout = @read_timeout
- @socket.continue_timeout = @continue_timeout if
- @socket.respond_to? :continue_timeout
- @socket.debug_output = @debug_output
- if use_ssl?
- begin
- if proxy?
- @socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
- @address, @port, HTTPVersion)
- @socket.writeline "Host: #{@address}:#{@port}"
- if proxy_user
- credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
- credential.delete!("\r\n")
- @socket.writeline "Proxy-Authorization: Basic #{credential}"
- end
- @socket.writeline ''
- Net::HTTPResponse.read_new(@socket).value
- end
- s.session = @ssl_session if @ssl_session
- # Server Name Indication (SNI) RFC 3546
- s.hostname = @address if s.respond_to? :hostname=
- timeout(@open_timeout) { s.connect }
- if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
- s.post_connection_check(@address)
- end
- @ssl_session = s.session
- rescue => exception
- D "Conn close because of connect error #{exception}"
- @socket.close if @socket and not @socket.closed?
- raise exception
- end
- end
- on_connect
- end if RUBY_VERSION > '1.9'
-
- ##
- # From ruby_1_8_7 branch r29865 including a modified
- # http://redmine.ruby-lang.org/issues/5341
-
- def connect # :nodoc:
- D "opening connection to #{conn_address()}..."
- s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
- D "opened"
- if use_ssl?
- unless @ssl_context.verify_mode
- warn "warning: peer certificate won't be verified in this SSL session"
- @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
- end
- s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
- s.sync_close = true
- end
- @socket = Net::BufferedIO.new(s)
- @socket.read_timeout = @read_timeout
- @socket.debug_output = @debug_output
- if use_ssl?
- if proxy?
- @socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
- @address, @port, HTTPVersion)
- @socket.writeline "Host: #{@address}:#{@port}"
- if proxy_user
- credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
- credential.delete!("\r\n")
- @socket.writeline "Proxy-Authorization: Basic #{credential}"
- end
- @socket.writeline ''
- Net::HTTPResponse.read_new(@socket).value
- end
- s.session = @ssl_session if @ssl_session
- s.connect
- if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
- s.post_connection_check(@address)
- end
- @ssl_session = s.session
- end
- on_connect
- end if RUBY_VERSION < '1.9'
-
- private :connect
-
-end
-
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
new file mode 100644
index 0000000000..2da881c554
--- /dev/null
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
@@ -0,0 +1,79 @@
+class Bundler::Persistent::Net::HTTP::Persistent::TimedStackMulti < Bundler::ConnectionPool::TimedStack # :nodoc:
+
+ ##
+ # Returns a new hash that has arrays for keys
+ #
+ # Using a class method to limit the bindings referenced by the hash's
+ # default_proc
+
+ def self.hash_of_arrays # :nodoc:
+ Hash.new { |h,k| h[k] = [] }
+ end
+
+ def initialize(size = 0, &block)
+ super
+
+ @enqueued = 0
+ @ques = self.class.hash_of_arrays
+ @lru = {}
+ @key = :"connection_args-#{object_id}"
+ end
+
+ def empty?
+ (@created - @enqueued) >= @max
+ end
+
+ def length
+ @max - @created + @enqueued
+ end
+
+ private
+
+ def connection_stored? options = {} # :nodoc:
+ !@ques[options[:connection_args]].empty?
+ end
+
+ def fetch_connection options = {} # :nodoc:
+ connection_args = options[:connection_args]
+
+ @enqueued -= 1
+ lru_update connection_args
+ @ques[connection_args].pop
+ end
+
+ def lru_update connection_args # :nodoc:
+ @lru.delete connection_args
+ @lru[connection_args] = true
+ end
+
+ def shutdown_connections # :nodoc:
+ @ques.each_key do |key|
+ super connection_args: key
+ end
+ end
+
+ def store_connection obj, options = {} # :nodoc:
+ @ques[options[:connection_args]].push obj
+ @enqueued += 1
+ end
+
+ def try_create options = {} # :nodoc:
+ connection_args = options[:connection_args]
+
+ if @created >= @max && @enqueued >= 1
+ oldest, = @lru.first
+ @lru.delete oldest
+ @ques[oldest].pop
+
+ @created -= 1
+ end
+
+ if @created < @max
+ @created += 1
+ lru_update connection_args
+ return @create_block.call(connection_args)
+ end
+ end
+
+end
+
diff --git a/lib/bundler/vendor/thor/LICENSE.md b/lib/bundler/vendor/thor/LICENSE.md
new file mode 100644
index 0000000000..ef80540b2a
--- /dev/null
+++ b/lib/bundler/vendor/thor/LICENSE.md
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Yehuda Katz, Eric Hodel, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/bundler/vendor/thor/lib/thor.rb b/lib/bundler/vendor/thor/lib/thor.rb
index 999e8b7e61..0794dbb522 100644
--- a/lib/bundler/vendor/thor/lib/thor.rb
+++ b/lib/bundler/vendor/thor/lib/thor.rb
@@ -1,7 +1,7 @@
-require "set"
-require "bundler/vendor/thor/lib/thor/base"
+require_relative "thor/base"
class Bundler::Thor
+ $thor_runner ||= false
class << self
# Allows for custom "Command" package naming.
#
@@ -90,9 +90,14 @@ class Bundler::Thor
# ==== Parameters
# Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command.
#
- def map(mappings = nil)
+ def map(mappings = nil, **kw)
@map ||= from_superclass(:map, {})
+ if mappings && !kw.empty?
+ mappings = kw.merge!(mappings)
+ else
+ mappings ||= kw
+ end
if mappings
mappings.each do |key, value|
if key.respond_to?(:each)
@@ -170,7 +175,7 @@ class Bundler::Thor
handle_no_command_error(meth) unless command
shell.say "Usage:"
- shell.say " #{banner(command)}"
+ shell.say " #{banner(command).split("\n").join("\n ")}"
shell.say
class_options_help(shell, nil => command.options.values)
if command.long_description
@@ -318,7 +323,7 @@ class Bundler::Thor
# ==== Parameters
# Symbol ...:: A list of commands that should be affected.
def stop_on_unknown_option!(*command_names)
- stop_on_unknown_option.merge(command_names)
+ @stop_on_unknown_option = stop_on_unknown_option | command_names
end
def stop_on_unknown_option?(command) #:nodoc:
@@ -332,7 +337,7 @@ class Bundler::Thor
# ==== Parameters
# Symbol ...:: A list of commands that should be affected.
def disable_required_check!(*command_names)
- disable_required_check.merge(command_names)
+ @disable_required_check = disable_required_check | command_names
end
def disable_required_check?(command) #:nodoc:
@@ -342,12 +347,12 @@ class Bundler::Thor
protected
def stop_on_unknown_option #:nodoc:
- @stop_on_unknown_option ||= Set.new
+ @stop_on_unknown_option ||= []
end
# help command has the required check disabled by default.
def disable_required_check #:nodoc:
- @disable_required_check ||= Set.new([:help])
+ @disable_required_check ||= [:help]
end
# The method responsible for dispatching given the args.
@@ -393,7 +398,9 @@ class Bundler::Thor
# the namespace should be displayed as arguments.
#
def banner(command, namespace = nil, subcommand = false)
- "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
+ command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage|
+ "#{basename} #{formatted_usage}"
+ end.join("\n")
end
def baseclass #:nodoc:
diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb
index e6698572a9..de9323b2db 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions.rb
@@ -1,17 +1,16 @@
-require "uri"
-require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
-require "bundler/vendor/thor/lib/thor/actions/create_file"
-require "bundler/vendor/thor/lib/thor/actions/create_link"
-require "bundler/vendor/thor/lib/thor/actions/directory"
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
-require "bundler/vendor/thor/lib/thor/actions/file_manipulation"
-require "bundler/vendor/thor/lib/thor/actions/inject_into_file"
+require_relative "actions/create_file"
+require_relative "actions/create_link"
+require_relative "actions/directory"
+require_relative "actions/empty_directory"
+require_relative "actions/file_manipulation"
+require_relative "actions/inject_into_file"
class Bundler::Thor
module Actions
attr_accessor :behavior
def self.included(base) #:nodoc:
+ super(base)
base.extend ClassMethods
end
@@ -113,8 +112,10 @@ class Bundler::Thor
# the script started).
#
def relative_to_original_destination_root(path, remove_dot = true)
- path = path.dup
- if path.gsub!(@destination_stack[0], ".")
+ root = @destination_stack[0]
+ if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
+ path = path.dup
+ path[0...root.size] = '.'
remove_dot ? (path[2..-1] || "") : path
else
path
@@ -217,7 +218,8 @@ class Bundler::Thor
shell.padding += 1 if verbose
contents = if is_uri
- open(path, "Accept" => "application/x-thor-template", &:read)
+ require "open-uri"
+ URI.open(path, "Accept" => "application/x-thor-template", &:read)
else
open(path, &:read)
end
@@ -252,9 +254,22 @@ class Bundler::Thor
say_status :run, desc, config.fetch(:verbose, true)
- unless options[:pretend]
- config[:capture] ? `#{command}` : system(command.to_s)
+ return if options[:pretend]
+
+ env_splat = [config[:env]] if config[:env]
+
+ if config[:capture]
+ require "open3"
+ result, status = Open3.capture2e(*env_splat, command.to_s)
+ success = status.success?
+ else
+ result = system(*env_splat, command.to_s)
+ success = result
end
+
+ abort if !success && config.fetch(:abort_on_failure, self.class.exit_on_failure?)
+
+ result
end
# Executes a ruby script (taking into account WIN32 platform quirks).
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
index 97d22d9bbd..330fc08cae 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
+require_relative "empty_directory"
class Bundler::Thor
module Actions
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb b/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb
index 3a664401b4..fb76fcdbe9 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/actions/create_file"
+require_relative "create_file"
class Bundler::Thor
module Actions
@@ -33,7 +33,8 @@ class Bundler::Thor
# Boolean:: true if it is identical, false otherwise.
#
def identical?
- exists? && File.identical?(render, destination)
+ source = File.expand_path(render, File.dirname(destination))
+ exists? && File.identical?(source, destination)
end
def invoke!
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb b/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
index f555f7b7e0..d37327a139 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
+require_relative "empty_directory"
class Bundler::Thor
module Actions
@@ -56,7 +56,7 @@ class Bundler::Thor
attr_reader :source
def initialize(base, source, destination = nil, config = {}, &block)
- @source = File.expand_path(base.find_in_source_paths(source.to_s))
+ @source = File.expand_path(Dir[Util.escape_globs(base.find_in_source_paths(source.to_s))].first)
@block = block
super(base, destination, {:recursive => true}.merge(config))
end
@@ -96,22 +96,12 @@ class Bundler::Thor
end
end
- if RUBY_VERSION < "2.0"
- def file_level_lookup(previous_lookup)
- File.join(previous_lookup, "{*,.[a-z]*}")
- end
-
- def files(lookup)
- Dir[lookup]
- end
- else
- def file_level_lookup(previous_lookup)
- File.join(previous_lookup, "*")
- end
+ def file_level_lookup(previous_lookup)
+ File.join(previous_lookup, "*")
+ end
- def files(lookup)
- Dir.glob(lookup, File::FNM_DOTMATCH)
- end
+ def files(lookup)
+ Dir.glob(lookup, File::FNM_DOTMATCH)
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
index 4c83bebc86..90a8d2e847 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
@@ -23,14 +23,14 @@ class Bundler::Thor
destination = args.first || source
source = File.expand_path(find_in_source_paths(source.to_s))
- create_file destination, nil, config do
+ resulting_destination = create_file destination, nil, config do
content = File.binread(source)
content = yield(content) if block
content
end
if config[:mode] == :preserve
mode = File.stat(source).mode
- chmod(destination, mode, config)
+ chmod(resulting_destination, mode, config)
end
end
@@ -60,6 +60,9 @@ class Bundler::Thor
# destination. If a block is given instead of destination, the content of
# the url is yielded and used as location.
#
+ # +get+ relies on open-uri, so passing application user input would provide
+ # a command injection attack vector.
+ #
# ==== Parameters
# source<String>:: the address of the given content.
# destination<String>:: the relative path to the destination root.
@@ -77,14 +80,14 @@ class Bundler::Thor
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first
- if source =~ %r{^https?\://}
+ render = if source =~ %r{^https?\://}
require "open-uri"
+ URI.send(:open, source) { |input| input.binmode.read }
else
source = File.expand_path(find_in_source_paths(source.to_s))
+ open(source) { |input| input.binmode.read }
end
- render = open(source) { |input| input.binmode.read }
-
destination ||= if block_given?
block.arity == 1 ? yield(render) : yield
else
@@ -117,7 +120,13 @@ class Bundler::Thor
context = config.delete(:context) || instance_eval("binding")
create_file destination, nil, config do
- content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").tap do |erb|
+ match = ERB.version.match(/(\d+\.\d+\.\d+)/)
+ capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+
+ CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer")
+ else
+ CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer")
+ end
+ content = capturable_erb.tap do |erb|
erb.filename = source
end.result(context)
content = yield(content) if block
@@ -242,7 +251,8 @@ class Bundler::Thor
# path<String>:: path of the file to be changed
# flag<Regexp|String>:: the regexp or string to be replaced
# replacement<String>:: the replacement, can be also given as a block
- # config<Hash>:: give :verbose => false to not log the status.
+ # config<Hash>:: give :verbose => false to not log the status, and
+ # :force => true, to force the replacement regardless of runner behavior.
#
# ==== Example
#
@@ -253,9 +263,10 @@ class Bundler::Thor
# end
#
def gsub_file(path, flag, *args, &block)
- return unless behavior == :invoke
config = args.last.is_a?(Hash) ? args.pop : {}
+ return unless behavior == :invoke || config.fetch(:force, false)
+
path = File.expand_path(path, destination_root)
say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
@@ -301,7 +312,7 @@ class Bundler::Thor
def comment_lines(path, flag, *args)
flag = flag.respond_to?(:source) ? flag.source : flag
- gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
+ gsub_file(path, /^(\s*)([^#\n]*#{flag})/, '\1# \2', *args)
end
# Removes a file at the given location.
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
index 349b26ff65..09ce0864f0 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/actions/empty_directory"
+require_relative "empty_directory"
class Bundler::Thor
module Actions
@@ -21,9 +21,14 @@ class Bundler::Thor
# gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
# end
#
+ WARNINGS = { unchanged_no_flag: 'File unchanged! The supplied flag value not found!' }
+
def insert_into_file(destination, *args, &block)
data = block_given? ? block : args.shift
- config = args.shift
+
+ config = args.shift || {}
+ config[:after] = /\z/ unless config.key?(:before) || config.key?(:after)
+
action InjectIntoFile.new(self, destination, data, config)
end
alias_method :inject_into_file, :insert_into_file
@@ -45,8 +50,6 @@ class Bundler::Thor
end
def invoke!
- say_status :invoke
-
content = if @behavior == :after
'\0' + replacement
else
@@ -54,7 +57,11 @@ class Bundler::Thor
end
if exists?
- replace!(/#{flag}/, content, config[:force])
+ if replace!(/#{flag}/, content, config[:force])
+ say_status(:invoke)
+ else
+ say_status(:unchanged, warning: WARNINGS[:unchanged_no_flag], color: :red)
+ end
else
unless pretend?
raise Bundler::Thor::Error, "The file #{ destination } does not appear to exist"
@@ -78,7 +85,7 @@ class Bundler::Thor
protected
- def say_status(behavior)
+ def say_status(behavior, warning: nil, color: nil)
status = if behavior == :invoke
if flag == /\A/
:prepend
@@ -87,11 +94,13 @@ class Bundler::Thor
else
:insert
end
+ elsif warning
+ warning
else
:subtract
end
- super(status, config[:verbose])
+ super(status, (color || config[:verbose]))
end
# Adds the content to the file.
@@ -100,8 +109,10 @@ class Bundler::Thor
return if pretend?
content = File.read(destination)
if force || !content.include?(replacement)
- content.gsub!(regexp, string)
+ success = content.gsub!(regexp, string)
+
File.open(destination, "wb") { |file| file.write(content) }
+ success
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/base.rb b/lib/bundler/vendor/thor/lib/thor/base.rb
index 9bd1077170..8487f9590a 100644
--- a/lib/bundler/vendor/thor/lib/thor/base.rb
+++ b/lib/bundler/vendor/thor/lib/thor/base.rb
@@ -1,17 +1,17 @@
-require "bundler/vendor/thor/lib/thor/command"
-require "bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access"
-require "bundler/vendor/thor/lib/thor/core_ext/ordered_hash"
-require "bundler/vendor/thor/lib/thor/error"
-require "bundler/vendor/thor/lib/thor/invocation"
-require "bundler/vendor/thor/lib/thor/parser"
-require "bundler/vendor/thor/lib/thor/shell"
-require "bundler/vendor/thor/lib/thor/line_editor"
-require "bundler/vendor/thor/lib/thor/util"
+require_relative "command"
+require_relative "core_ext/hash_with_indifferent_access"
+require_relative "error"
+require_relative "invocation"
+require_relative "nested_context"
+require_relative "parser"
+require_relative "shell"
+require_relative "line_editor"
+require_relative "util"
class Bundler::Thor
- autoload :Actions, "bundler/vendor/thor/lib/thor/actions"
- autoload :RakeCompat, "bundler/vendor/thor/lib/thor/rake_compat"
- autoload :Group, "bundler/vendor/thor/lib/thor/group"
+ autoload :Actions, File.expand_path("actions", __dir__)
+ autoload :RakeCompat, File.expand_path("rake_compat", __dir__)
+ autoload :Group, File.expand_path("group", __dir__)
# Shortcuts for help.
HELP_MAPPINGS = %w(-h -? --help -D)
@@ -22,6 +22,15 @@ class Bundler::Thor
TEMPLATE_EXTNAME = ".tt"
+ class << self
+ def deprecation_warning(message) #:nodoc:
+ unless ENV['THOR_SILENCE_DEPRECATION']
+ warn "Deprecation warning: #{message}\n" +
+ 'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.'
+ end
+ end
+ end
+
module Base
attr_accessor :options, :parent_options, :args
@@ -89,6 +98,7 @@ class Bundler::Thor
class << self
def included(base) #:nodoc:
+ super(base)
base.extend ClassMethods
base.send :include, Invocation
base.send :include, Shell
@@ -113,7 +123,7 @@ class Bundler::Thor
end
# Whenever a class inherits from Bundler::Thor or Bundler::Thor::Group, we should track the
- # class and the file on Bundler::Thor::Base. This is the method responsable for it.
+ # class and the file on Bundler::Thor::Base. This is the method responsible for it.
#
def register_klass_file(klass) #:nodoc:
file = caller[1].match(/(.*):\d+/)[1]
@@ -153,17 +163,20 @@ class Bundler::Thor
# If you want to raise an error when the default value of an option does not match
# the type call check_default_type!
- # This is disabled by default for compatibility.
+ # This will be the default; for compatibility a deprecation warning is issued if necessary.
def check_default_type!
@check_default_type = true
end
- def check_default_type #:nodoc:
- @check_default_type ||= from_superclass(:check_default_type, false)
+ # If you want to use defaults that don't match the type of an option,
+ # either specify `check_default_type: false` or call `allow_incompatible_default_type!`
+ def allow_incompatible_default_type!
+ @check_default_type = false
end
- def check_default_type? #:nodoc:
- !!check_default_type
+ def check_default_type #:nodoc:
+ @check_default_type = from_superclass(:check_default_type, nil) unless defined?(@check_default_type)
+ @check_default_type
end
# If true, option parsing is suspended as soon as an unknown option or a
@@ -353,22 +366,22 @@ class Bundler::Thor
# Returns the commands for this Bundler::Thor class.
#
# ==== Returns
- # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
- # objects as values.
+ # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command
+ # objects as values.
#
def commands
- @commands ||= Bundler::Thor::CoreExt::OrderedHash.new
+ @commands ||= Hash.new
end
alias_method :tasks, :commands
# Returns the commands for this Bundler::Thor class and all subclasses.
#
# ==== Returns
- # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
- # objects as values.
+ # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command
+ # objects as values.
#
def all_commands
- @all_commands ||= from_superclass(:all_commands, Bundler::Thor::CoreExt::OrderedHash.new)
+ @all_commands ||= from_superclass(:all_commands, Hash.new)
@all_commands.merge!(commands)
end
alias_method :all_tasks, :all_commands
@@ -415,14 +428,20 @@ class Bundler::Thor
# remove_command :this_is_not_a_command
# end
#
- def no_commands
- @no_commands = true
- yield
- ensure
- @no_commands = false
+ def no_commands(&block)
+ no_commands_context.enter(&block)
end
+
alias_method :no_tasks, :no_commands
+ def no_commands_context
+ @no_commands_context ||= NestedContext.new
+ end
+
+ def no_commands?
+ no_commands_context.entered?
+ end
+
# Sets the namespace for the Bundler::Thor or Bundler::Thor::Group class. By default the
# namespace is retrieved from the class name. If your Bundler::Thor class is named
# Scripts::MyScript, the help method, for example, will be called as:
@@ -466,13 +485,13 @@ class Bundler::Thor
dispatch(nil, given_args.dup, nil, config)
rescue Bundler::Thor::Error => e
config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
- exit(1) if exit_on_failure?
+ exit(false) if exit_on_failure?
rescue Errno::EPIPE
# This happens if a thor command is piped to something like `head`,
# which closes the pipe when it's done reading. This will also
# mean that if the pipe is closed, further unnecessary
# computation will not occur.
- exit(0)
+ exit(true)
end
# Allows to use private methods from parent in child classes as commands.
@@ -493,8 +512,7 @@ class Bundler::Thor
alias_method :public_task, :public_command
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
- raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." if has_namespace
- raise UndefinedCommandError, "Could not find command #{command.inspect}."
+ raise UndefinedCommandError.new(command, all_commands.keys, (namespace if has_namespace))
end
alias_method :handle_no_task_error, :handle_no_command_error
@@ -503,10 +521,16 @@ class Bundler::Thor
msg = "ERROR: \"#{basename} #{name}\" was called with ".dup
msg << "no arguments" if args.empty?
msg << "arguments " << args.inspect unless args.empty?
- msg << "\nUsage: #{banner(command).inspect}"
+ msg << "\nUsage: \"#{banner(command).split("\n").join("\"\n \"")}\""
raise InvocationError, msg
end
+ # A flag that makes the process exit with status 1 if any error happens.
+ def exit_on_failure?
+ Bundler::Thor.deprecation_warning "Bundler::Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `#{self.name}`"
+ false
+ end
+
protected
# Prints the class options per group. If an option does not belong to
@@ -564,7 +588,7 @@ class Bundler::Thor
# options<Hash>:: Described in both class_option and method_option.
# scope<Hash>:: Options hash that is being built up
def build_option(name, options, scope) #:nodoc:
- scope[name] = Bundler::Thor::Option.new(name, options.merge(:check_default_type => check_default_type?))
+ scope[name] = Bundler::Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options))
end
# Receives a hash of options, parse them and add to the scope. This is a
@@ -597,13 +621,15 @@ class Bundler::Thor
# Everytime someone inherits from a Bundler::Thor class, register the klass
# and file into baseclass.
def inherited(klass)
+ super(klass)
Bundler::Thor::Base.register_klass_file(klass)
- klass.instance_variable_set(:@no_commands, false)
+ klass.instance_variable_set(:@no_commands, 0)
end
# Fire this callback whenever a method is added. Added methods are
# tracked as commands by invoking the create_command method.
def method_added(meth)
+ super(meth)
meth = meth.to_s
if meth == "initialize"
@@ -614,8 +640,7 @@ class Bundler::Thor
# Return if it's not a public instance method
return unless public_method_defined?(meth.to_sym)
- @no_commands ||= false
- return if @no_commands || !create_command(meth)
+ return if no_commands? || !create_command(meth)
is_thor_reserved_word?(meth, :command)
Bundler::Thor::Base.register_klass_file(self)
@@ -642,11 +667,6 @@ class Bundler::Thor
end
end
- # A flag that makes the process exit with status 1 if any error happens.
- def exit_on_failure?
- false
- end
-
#
# The basename of the program invoking the thor class.
#
diff --git a/lib/bundler/vendor/thor/lib/thor/command.rb b/lib/bundler/vendor/thor/lib/thor/command.rb
index c636948e5d..040c971c0c 100644
--- a/lib/bundler/vendor/thor/lib/thor/command.rb
+++ b/lib/bundler/vendor/thor/lib/thor/command.rb
@@ -49,24 +49,32 @@ class Bundler::Thor
formatted ||= "".dup
- # Add usage with required arguments
- formatted << if klass && !klass.arguments.empty?
- usage.to_s.gsub(/^#{name}/) do |match|
- match << " " << klass.arguments.map(&:usage).compact.join(" ")
- end
- else
- usage.to_s
- end
+ Array(usage).map do |specific_usage|
+ formatted_specific_usage = formatted
- # Add required options
- formatted << " #{required_options}"
+ formatted_specific_usage += required_arguments_for(klass, specific_usage)
- # Strip and go!
- formatted.strip
+ # Add required options
+ formatted_specific_usage += " #{required_options}"
+
+ # Strip and go!
+ formatted_specific_usage.strip
+ end.join("\n")
end
protected
+ # Add usage with required arguments
+ def required_arguments_for(klass, usage)
+ if klass && !klass.arguments.empty?
+ usage.to_s.gsub(/^#{name}/) do |match|
+ match << " " << klass.arguments.map(&:usage).compact.join(" ")
+ end
+ else
+ usage.to_s
+ end
+ end
+
def not_debugging?(instance)
!(instance.class.respond_to?(:debugging) && instance.class.debugging)
end
@@ -97,8 +105,7 @@ class Bundler::Thor
def handle_argument_error?(instance, error, caller)
not_debugging?(instance) && (error.message =~ /wrong number of arguments/ || error.message =~ /given \d*, expected \d*/) && begin
saned = sans_backtrace(error.backtrace, caller)
- # Ruby 1.9 always include the called method in the backtrace
- saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9")
+ saned.empty? || saned.size == 1
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb
deleted file mode 100644
index 0f6e2e0af2..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class IO #:nodoc:
- class << self
- unless method_defined? :binread
- def binread(file, *args)
- raise ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3
- File.open(file, "rb") do |f|
- f.read(*args)
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb
deleted file mode 100644
index 76f1e43c65..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-class Bundler::Thor
- module CoreExt
- class OrderedHash < ::Hash
- if RUBY_VERSION < "1.9"
- def initialize(*args, &block)
- super
- @keys = []
- end
-
- def initialize_copy(other)
- super
- # make a deep copy of keys
- @keys = other.keys
- end
-
- def []=(key, value)
- @keys << key unless key?(key)
- super
- end
-
- def delete(key)
- if key? key
- index = @keys.index(key)
- @keys.delete_at index
- end
- super
- end
-
- def delete_if
- super
- sync_keys!
- self
- end
-
- alias_method :reject!, :delete_if
-
- def reject(&block)
- dup.reject!(&block)
- end
-
- def keys
- @keys.dup
- end
-
- def values
- @keys.map { |key| self[key] }
- end
-
- def to_hash
- self
- end
-
- def to_a
- @keys.map { |key| [key, self[key]] }
- end
-
- def each_key
- return to_enum(:each_key) unless block_given?
- @keys.each { |key| yield(key) }
- self
- end
-
- def each_value
- return to_enum(:each_value) unless block_given?
- @keys.each { |key| yield(self[key]) }
- self
- end
-
- def each
- return to_enum(:each) unless block_given?
- @keys.each { |key| yield([key, self[key]]) }
- self
- end
-
- def each_pair
- return to_enum(:each_pair) unless block_given?
- @keys.each { |key| yield(key, self[key]) }
- self
- end
-
- alias_method :select, :find_all
-
- def clear
- super
- @keys.clear
- self
- end
-
- def shift
- k = @keys.first
- v = delete(k)
- [k, v]
- end
-
- def merge!(other_hash)
- if block_given?
- other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
- else
- other_hash.each { |k, v| self[k] = v }
- end
- self
- end
-
- alias_method :update, :merge!
-
- def merge(other_hash, &block)
- dup.merge!(other_hash, &block)
- end
-
- # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
- def replace(other)
- super
- @keys = other.keys
- self
- end
-
- def inspect
- "#<#{self.class} #{super}>"
- end
-
- private
-
- def sync_keys!
- @keys.delete_if { |k| !key?(k) }
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/error.rb b/lib/bundler/vendor/thor/lib/thor/error.rb
index 2f816081f3..7d57129b83 100644
--- a/lib/bundler/vendor/thor/lib/thor/error.rb
+++ b/lib/bundler/vendor/thor/lib/thor/error.rb
@@ -1,4 +1,19 @@
class Bundler::Thor
+ Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
+ # In order to support versions of Ruby that don't have keyword
+ # arguments, we need our own spell checker class that doesn't take key
+ # words. Even though this code wouldn't be hit because of the check
+ # above, it's still necessary because the interpreter would otherwise be
+ # unable to parse the file.
+ class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
+ def initialize(dictionary)
+ @dictionary = dictionary
+ end
+ end
+
+ DidYouMean::Correctable
+ end
+
# Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those
# errors have their backtrace suppressed and are nicely shown to the user.
#
@@ -10,6 +25,35 @@ class Bundler::Thor
# Raised when a command was not found.
class UndefinedCommandError < Error
+ class SpellChecker
+ attr_reader :error
+
+ def initialize(error)
+ @error = error
+ end
+
+ def corrections
+ @corrections ||= spell_checker.correct(error.command).map(&:inspect)
+ end
+
+ def spell_checker
+ NoKwargSpellChecker.new(error.all_commands)
+ end
+ end
+
+ attr_reader :command, :all_commands
+
+ def initialize(command, all_commands, namespace)
+ @command = command
+ @all_commands = all_commands
+
+ message = "Could not find command #{command.inspect}"
+ message = namespace ? "#{message} in #{namespace.inspect} namespace." : "#{message}."
+
+ super(message)
+ end
+
+ prepend Correctable if Correctable
end
UndefinedTaskError = UndefinedCommandError
@@ -22,6 +66,33 @@ class Bundler::Thor
end
class UnknownArgumentError < Error
+ class SpellChecker
+ attr_reader :error
+
+ def initialize(error)
+ @error = error
+ end
+
+ def corrections
+ @corrections ||=
+ error.unknown.flat_map { |unknown| spell_checker.correct(unknown) }.uniq.map(&:inspect)
+ end
+
+ def spell_checker
+ @spell_checker ||= NoKwargSpellChecker.new(error.switches)
+ end
+ end
+
+ attr_reader :switches, :unknown
+
+ def initialize(switches, unknown)
+ @switches = switches
+ @unknown = unknown
+
+ super("Unknown switches #{unknown.map(&:inspect).join(', ')}")
+ end
+
+ prepend Correctable if Correctable
end
class RequiredArgumentMissingError < InvocationError
@@ -29,4 +100,11 @@ class Bundler::Thor
class MalformattedArgumentError < InvocationError
end
+
+ if Correctable
+ DidYouMean::SPELL_CHECKERS.merge!(
+ 'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker,
+ 'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker
+ )
+ end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/group.rb b/lib/bundler/vendor/thor/lib/thor/group.rb
index 05ddc10cd3..7861d05345 100644
--- a/lib/bundler/vendor/thor/lib/thor/group.rb
+++ b/lib/bundler/vendor/thor/lib/thor/group.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/base"
+require_relative "base"
# Bundler::Thor has a special class called Bundler::Thor::Group. The main difference to Bundler::Thor class
# is that it invokes all commands at once. It also include some methods that allows
@@ -61,7 +61,7 @@ class Bundler::Thor::Group
invocations[name] = false
invocation_blocks[name] = block if block_given?
- class_eval <<-METHOD, __FILE__, __LINE__
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
def _invoke_#{name.to_s.gsub(/\W/, '_')}
klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
@@ -120,7 +120,7 @@ class Bundler::Thor::Group
invocations[name] = true
invocation_blocks[name] = block if block_given?
- class_eval <<-METHOD, __FILE__, __LINE__
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
return unless options[#{name.inspect}]
diff --git a/lib/bundler/vendor/thor/lib/thor/invocation.rb b/lib/bundler/vendor/thor/lib/thor/invocation.rb
index 866d2212a7..248a466f8e 100644
--- a/lib/bundler/vendor/thor/lib/thor/invocation.rb
+++ b/lib/bundler/vendor/thor/lib/thor/invocation.rb
@@ -1,6 +1,7 @@
class Bundler::Thor
module Invocation
def self.included(base) #:nodoc:
+ super(base)
base.extend ClassMethods
end
diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor.rb b/lib/bundler/vendor/thor/lib/thor/line_editor.rb
index ce81a17484..5c0c336e7a 100644
--- a/lib/bundler/vendor/thor/lib/thor/line_editor.rb
+++ b/lib/bundler/vendor/thor/lib/thor/line_editor.rb
@@ -1,5 +1,5 @@
-require "bundler/vendor/thor/lib/thor/line_editor/basic"
-require "bundler/vendor/thor/lib/thor/line_editor/readline"
+require_relative "line_editor/basic"
+require_relative "line_editor/readline"
class Bundler::Thor
module LineEditor
diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb b/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb
index 0adb2b3137..fe3d7c998f 100644
--- a/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb
+++ b/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb
@@ -24,7 +24,7 @@ class Bundler::Thor
$stdin.gets
else
# Lazy-load io/console since it is gem-ified as of 2.3
- require "io/console" if RUBY_VERSION > "1.9.2"
+ require "io/console"
$stdin.noecho(&:gets)
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb b/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb
index dd39cff35d..120eadd06a 100644
--- a/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb
+++ b/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb
@@ -1,19 +1,19 @@
-begin
- require "readline"
-rescue LoadError
-end
-
class Bundler::Thor
module LineEditor
class Readline < Basic
def self.available?
+ begin
+ require "readline"
+ rescue LoadError
+ end
+
Object.const_defined?(:Readline)
end
def readline
if echo?
::Readline.completion_append_character = nil
- # Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil.
+ # rb-readline does not allow Readline.completion_proc= to receive nil.
if complete = completion_proc
::Readline.completion_proc = complete
end
diff --git a/lib/bundler/vendor/thor/lib/thor/nested_context.rb b/lib/bundler/vendor/thor/lib/thor/nested_context.rb
new file mode 100644
index 0000000000..fd36b9d43f
--- /dev/null
+++ b/lib/bundler/vendor/thor/lib/thor/nested_context.rb
@@ -0,0 +1,29 @@
+class Bundler::Thor
+ class NestedContext
+ def initialize
+ @depth = 0
+ end
+
+ def enter
+ push
+
+ yield
+ ensure
+ pop
+ end
+
+ def entered?
+ @depth > 0
+ end
+
+ private
+
+ def push
+ @depth += 1
+ end
+
+ def pop
+ @depth -= 1
+ end
+ end
+end
diff --git a/lib/bundler/vendor/thor/lib/thor/parser.rb b/lib/bundler/vendor/thor/lib/thor/parser.rb
index 08f80e565d..45394732ca 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/parser/argument"
-require "bundler/vendor/thor/lib/thor/parser/arguments"
-require "bundler/vendor/thor/lib/thor/parser/option"
-require "bundler/vendor/thor/lib/thor/parser/options"
+require_relative "parser/argument"
+require_relative "parser/arguments"
+require_relative "parser/option"
+require_relative "parser/options"
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
index 1fd790f4b7..3a5d82cf29 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
@@ -9,7 +9,7 @@ class Bundler::Thor
arguments = []
args.each do |item|
- break if item =~ /^-/
+ break if item.is_a?(String) && item =~ /^-/
arguments << item
end
@@ -30,7 +30,11 @@ class Bundler::Thor
arguments.each do |argument|
if !argument.default.nil?
- @assigns[argument.human_name] = argument.default
+ begin
+ @assigns[argument.human_name] = argument.default.dup
+ rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4
+ @assigns[argument.human_name] = argument.default
+ end
elsif argument.required?
@non_assigned_required << argument
end
@@ -82,7 +86,7 @@ class Bundler::Thor
end
def current_is_value?
- peek && peek.to_s !~ /^-/
+ peek && peek.to_s !~ /^-{1,2}\S+/
end
# Runs through the argument array getting strings that contains ":" and
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/option.rb b/lib/bundler/vendor/thor/lib/thor/parser/option.rb
index 85169b56c8..5a5af6f888 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/option.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/option.rb
@@ -1,17 +1,18 @@
class Bundler::Thor
class Option < Argument #:nodoc:
- attr_reader :aliases, :group, :lazy_default, :hide
+ attr_reader :aliases, :group, :lazy_default, :hide, :repeatable
VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
def initialize(name, options = {})
@check_default_type = options[:check_default_type]
options[:required] = false unless options.key?(:required)
+ @repeatable = options.fetch(:repeatable, false)
super
- @lazy_default = options[:lazy_default]
- @group = options[:group].to_s.capitalize if options[:group]
- @aliases = Array(options[:aliases])
- @hide = options[:hide]
+ @lazy_default = options[:lazy_default]
+ @group = options[:group].to_s.capitalize if options[:group]
+ @aliases = Array(options[:aliases])
+ @hide = options[:hide]
end
# This parse quick options given as method_options. It makes several
@@ -111,7 +112,7 @@ class Bundler::Thor
def validate!
raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
- validate_default_type! if @check_default_type
+ validate_default_type!
end
def validate_default_type!
@@ -128,7 +129,19 @@ class Bundler::Thor
@default.class.name.downcase.to_sym
end
- raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
+ expected_type = (@repeatable && @type != :hash) ? :array : @type
+
+ if default_type != expected_type
+ err = "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})"
+
+ if @check_default_type
+ raise ArgumentError, err
+ elsif @check_default_type == nil
+ Bundler::Thor.deprecation_warning "#{err}.\n" +
+ 'This will be rejected in the future unless you explicitly pass the options `check_default_type: false`' +
+ ' or call `allow_incompatible_default_type!` in your code'
+ end
+ end
end
def dasherized?
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/options.rb b/lib/bundler/vendor/thor/lib/thor/parser/options.rb
index 70f6366842..3a8927d09c 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/options.rb
@@ -44,6 +44,7 @@ class Bundler::Thor
@shorts = {}
@switches = {}
@extra = []
+ @stopped_parsing_after_extra_index = nil
options.each do |option|
@switches[option.switch_name] = option
@@ -66,6 +67,7 @@ class Bundler::Thor
if result == OPTS_END
shift
@parsing_options = false
+ @stopped_parsing_after_extra_index ||= @extra.size
super
else
result
@@ -95,10 +97,12 @@ class Bundler::Thor
switch = normalize_switch(switch)
option = switch_option(switch)
- @assigns[option.human_name] = parse_peek(switch, option)
+ result = parse_peek(switch, option)
+ assign_result!(option, result)
elsif @stop_on_unknown
@parsing_options = false
@extra << shifted
+ @stopped_parsing_after_extra_index ||= @extra.size
@extra << shift while peek
break
elsif match
@@ -120,13 +124,25 @@ class Bundler::Thor
end
def check_unknown!
+ to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra
+
# an unknown option starts with - or -- and has no more --'s afterward.
- unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
- raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
+ unknown = to_check.select { |str| str =~ /^--?(?:(?!--).)*$/ }
+ raise UnknownArgumentError.new(@switches.keys, unknown) unless unknown.empty?
end
protected
+ def assign_result!(option, result)
+ if option.repeatable && option.type == :hash
+ (@assigns[option.human_name] ||= {}).merge!(result)
+ elsif option.repeatable
+ (@assigns[option.human_name] ||= []) << result
+ else
+ @assigns[option.human_name] = result
+ end
+ end
+
# Check if the current value in peek is a registered switch.
#
# Two booleans are returned. The first is true if the current value
@@ -156,7 +172,7 @@ class Bundler::Thor
end
def switch?(arg)
- switch_option(normalize_switch(arg))
+ !switch_option(normalize_switch(arg)).nil?
end
def switch_option(arg)
@@ -189,7 +205,7 @@ class Bundler::Thor
shift
false
else
- !no_or_skip?(switch)
+ @switches.key?(switch) || !no_or_skip?(switch)
end
else
@switches.key?(switch) || !no_or_skip?(switch)
diff --git a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb b/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
index 60282e2991..f8f86372cc 100644
--- a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
+++ b/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
@@ -25,6 +25,7 @@ class Bundler::Thor
end
def self.included(base)
+ super(base)
# Hack. Make rakefile point to invoker, so rdoc task is generated properly.
rakefile = File.basename(caller[0].match(/(.*):\d+/)[1])
Rake.application.instance_variable_set(:@rakefile, rakefile)
diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb
index 65ae422d7f..54c5525093 100644
--- a/lib/bundler/vendor/thor/lib/thor/runner.rb
+++ b/lib/bundler/vendor/thor/lib/thor/runner.rb
@@ -1,12 +1,13 @@
-require "bundler/vendor/thor/lib/thor"
-require "bundler/vendor/thor/lib/thor/group"
-require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
+require_relative "../thor"
+require_relative "group"
require "yaml"
require "digest/md5"
require "pathname"
class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength
+ autoload :OpenURI, "open-uri"
+
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
def self.banner(command, all = false, subcommand = false)
@@ -65,7 +66,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
raise Error, "Error opening file '#{name}'"
end
- say "Your Bundler::Thorfile contains:"
+ say "Your Thorfile contains:"
say contents
unless options["force"]
@@ -111,7 +112,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
desc "version", "Show Bundler::Thor version"
def version
- require "bundler/vendor/thor/lib/thor/version"
+ require_relative "version"
say "Bundler::Thor #{Bundler::Thor::VERSION}"
end
@@ -204,7 +205,7 @@ private
File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
end
- # Load the Bundler::Thorfiles. If relevant_to is supplied, looks for specific files
+ # Load the Thorfiles. If relevant_to is supplied, looks for specific files
# in the thor_root instead of loading them all.
#
# By default, it also traverses the current path until find Bundler::Thor files, as
@@ -217,11 +218,11 @@ private
end
end
- # Finds Bundler::Thorfiles by traversing from your current directory down to the root
+ # Finds Thorfiles by traversing from your current directory down to the root
# directory of your system. If at any time we find a Bundler::Thor file, we stop.
#
- # We also ensure that system-wide Bundler::Thorfiles are loaded first, so local
- # Bundler::Thorfiles can override them.
+ # We also ensure that system-wide Thorfiles are loaded first, so local
+ # Thorfiles can override them.
#
# ==== Example
#
@@ -229,7 +230,7 @@ private
#
# 1. /Users/wycats/dev/thor
# 2. /Users/wycats/dev
- # 3. /Users/wycats <-- we find a Bundler::Thorfile here, so we stop
+ # 3. /Users/wycats <-- we find a Thorfile here, so we stop
#
# Suppose we start at c:\Documents and Settings\james\dev\thor ...
#
@@ -237,7 +238,7 @@ private
# 2. c:\Documents and Settings\james\dev
# 3. c:\Documents and Settings\james
# 4. c:\Documents and Settings
- # 5. c:\ <-- no Bundler::Thorfiles found!
+ # 5. c:\ <-- no Thorfiles found!
#
def thorfiles(relevant_to = nil, skip_lookup = false)
thorfiles = []
@@ -258,7 +259,7 @@ private
end
end
- # Load Bundler::Thorfiles relevant to the given method. If you provide "foo:bar" it
+ # Load Thorfiles relevant to the given method. If you provide "foo:bar" it
# will load all thor files in the thor.yaml that has "foo" e "foo:bar"
# namespaces registered.
#
diff --git a/lib/bundler/vendor/thor/lib/thor/shell.rb b/lib/bundler/vendor/thor/lib/thor/shell.rb
index e945549324..e36fa472d6 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell.rb
@@ -24,9 +24,9 @@ class Bundler::Thor
SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width]
attr_writer :shell
- autoload :Basic, "bundler/vendor/thor/lib/thor/shell/basic"
- autoload :Color, "bundler/vendor/thor/lib/thor/shell/color"
- autoload :HTML, "bundler/vendor/thor/lib/thor/shell/html"
+ autoload :Basic, File.expand_path("shell/basic", __dir__)
+ autoload :Color, File.expand_path("shell/color", __dir__)
+ autoload :HTML, File.expand_path("shell/html", __dir__)
# Add shell to initialize config values.
#
@@ -55,7 +55,7 @@ class Bundler::Thor
# Common methods that are delegated to the shell.
SHELL_DELEGATED_METHODS.each do |method|
- module_eval <<-METHOD, __FILE__, __LINE__
+ module_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{method}(*args,&block)
shell.#{method}(*args,&block)
end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
index 5162390efd..2dddd4a53a 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
@@ -1,6 +1,8 @@
class Bundler::Thor
module Shell
class Basic
+ DEFAULT_TERMINAL_WIDTH = 80
+
attr_accessor :base
attr_reader :padding
@@ -45,6 +47,10 @@ class Bundler::Thor
# Asks something to the user and receives a response.
#
+ # If a default value is specified it will be presented to the user
+ # and allows them to select that value with an empty response. This
+ # option is ignored when limited answers are supplied.
+ #
# If asked to limit the correct responses, you can pass in an
# array of acceptable answers. If one of those is not supplied,
# they will be shown a message stating that one of those answers
@@ -61,6 +67,8 @@ class Bundler::Thor
# ==== Example
# ask("What is your name?")
#
+ # ask("What is the planet furthest from the sun?", :default => "Pluto")
+ #
# ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
#
# ask("What is your password?", :echo => false)
@@ -86,6 +94,8 @@ class Bundler::Thor
# say("I know you knew that.")
#
def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
+ return if quiet?
+
buffer = prepare_message(message, *color)
buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")
@@ -222,8 +232,21 @@ class Bundler::Thor
paras = message.split("\n\n")
paras.map! do |unwrapped|
- unwrapped.strip.tr("\n", " ").squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
- end
+ words = unwrapped.split(" ")
+ counter = words.first.length
+ words.inject do |memo, word|
+ word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
+ counter = 0 if word.include? "\n"
+ if (counter + word.length + 1) < width
+ memo = "#{memo} #{word}"
+ counter += (word.length + 1)
+ else
+ memo = "#{memo}\n#{word}"
+ counter = word.length
+ end
+ memo
+ end
+ end.compact!
paras.each do |para|
para.split("\n").each do |line|
@@ -239,11 +262,11 @@ class Bundler::Thor
#
# ==== Parameters
# destination<String>:: the destination file to solve conflicts
- # block<Proc>:: an optional block that returns the value to be used in diff
+ # block<Proc>:: an optional block that returns the value to be used in diff and merge
#
def file_collision(destination)
return true if @always_force
- options = block_given? ? "[Ynaqdh]" : "[Ynaqh]"
+ options = block_given? ? "[Ynaqdhm]" : "[Ynaqh]"
loop do
answer = ask(
@@ -267,6 +290,13 @@ class Bundler::Thor
when is?(:diff)
show_diff(destination, yield) if block_given?
say "Retrying..."
+ when is?(:merge)
+ if block_given? && !merge_tool.empty?
+ merge(destination, yield)
+ return nil
+ end
+
+ say "Please specify merge tool to `THOR_MERGE` env."
else
say file_collision_help
end
@@ -279,11 +309,11 @@ class Bundler::Thor
result = if ENV["THOR_COLUMNS"]
ENV["THOR_COLUMNS"].to_i
else
- unix? ? dynamic_width : 80
+ unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
end
- result < 10 ? 80 : result
+ result < 10 ? DEFAULT_TERMINAL_WIDTH : result
rescue
- 80
+ DEFAULT_TERMINAL_WIDTH
end
# Called if something goes wrong during the execution. This is used by Bundler::Thor
@@ -344,6 +374,7 @@ class Bundler::Thor
q - quit, abort
d - diff, show the differences between the old and the new
h - help, show this help
+ m - merge, run merge tool
HELP
end
@@ -423,15 +454,41 @@ class Bundler::Thor
def ask_filtered(statement, color, options)
answer_set = options[:limited_to]
+ case_insensitive = options.fetch(:case_insensitive, false)
correct_answer = nil
until correct_answer
answers = answer_set.join(", ")
answer = ask_simply("#{statement} [#{answers}]", color, options)
- correct_answer = answer_set.include?(answer) ? answer : nil
+ correct_answer = answer_match(answer_set, answer, case_insensitive)
say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
end
correct_answer
end
+
+ def answer_match(possibilities, answer, case_insensitive)
+ if case_insensitive
+ possibilities.detect{ |possibility| possibility.downcase == answer.downcase }
+ else
+ possibilities.detect{ |possibility| possibility == answer }
+ end
+ end
+
+ def merge(destination, content) #:nodoc:
+ require "tempfile"
+ Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp|
+ temp.write content
+ temp.rewind
+ system %(#{merge_tool} "#{temp.path}" "#{destination}")
+ end
+ end
+
+ def merge_tool #:nodoc:
+ @merge_tool ||= ENV["THOR_MERGE"] || git_merge_tool
+ end
+
+ def git_merge_tool #:nodoc:
+ `git config merge.tool`.rstrip rescue ""
+ end
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/color.rb b/lib/bundler/vendor/thor/lib/thor/shell/color.rb
index da289cb50c..dc167ed3cc 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell/color.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell/color.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/shell/basic"
+require_relative "basic"
class Bundler::Thor
module Shell
@@ -97,7 +97,15 @@ class Bundler::Thor
protected
def can_display_colors?
- stdout.tty?
+ are_colors_supported? && !are_colors_disabled?
+ end
+
+ def are_colors_supported?
+ stdout.tty? && ENV["TERM"] != "dumb"
+ end
+
+ def are_colors_disabled?
+ !ENV['NO_COLOR'].nil?
end
# Overwrite show_diff to show diff with colors if Diff::LCS is
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/html.rb b/lib/bundler/vendor/thor/lib/thor/shell/html.rb
index 83d2054988..77a6d13a23 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell/html.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell/html.rb
@@ -1,4 +1,4 @@
-require "bundler/vendor/thor/lib/thor/shell/basic"
+require_relative "basic"
class Bundler::Thor
module Shell
@@ -51,13 +51,13 @@ class Bundler::Thor
def set_color(string, *colors)
if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
html_colors = colors.map { |color| lookup_color(color) }
- "<span style=\"#{html_colors.join('; ')};\">#{string}</span>"
+ "<span style=\"#{html_colors.join('; ')};\">#{Bundler::Thor::Util.escape_html(string)}</span>"
else
color, bold = colors
html_color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
styles = [html_color]
styles << BOLD if bold
- "<span style=\"#{styles.join('; ')};\">#{string}</span>"
+ "<span style=\"#{styles.join('; ')};\">#{Bundler::Thor::Util.escape_html(string)}</span>"
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/util.rb b/lib/bundler/vendor/thor/lib/thor/util.rb
index 5d03177a28..ddf4d21b90 100644
--- a/lib/bundler/vendor/thor/lib/thor/util.rb
+++ b/lib/bundler/vendor/thor/lib/thor/util.rb
@@ -27,7 +27,7 @@ class Bundler::Thor
end
# Receives a constant and converts it to a Bundler::Thor namespace. Since Bundler::Thor
- # commands can be added to a sandbox, this method is also responsable for
+ # commands can be added to a sandbox, this method is also responsible for
# removing the sandbox namespace.
#
# This method should not be used in general because it's used to deal with
@@ -211,7 +211,7 @@ class Bundler::Thor
#
def globs_for(path)
path = escape_globs(path)
- ["#{path}/Bundler::Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
+ ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
end
# Return the path to the ruby interpreter taking into account multiple
@@ -263,6 +263,22 @@ class Bundler::Thor
def escape_globs(path)
path.to_s.gsub(/[*?{}\[\]]/, '\\\\\\&')
end
+
+ # Returns a string that has had any HTML characters escaped.
+ #
+ # ==== Examples
+ #
+ # Bundler::Thor::Util.escape_html('<div>') # => "&lt;div&gt;"
+ #
+ # ==== Parameters
+ # String
+ #
+ # ==== Returns
+ # String
+ #
+ def escape_html(string)
+ CGI.escapeHTML(string)
+ end
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/version.rb b/lib/bundler/vendor/thor/lib/thor/version.rb
index df8f18821a..a3efa9f762 100644
--- a/lib/bundler/vendor/thor/lib/thor/version.rb
+++ b/lib/bundler/vendor/thor/lib/thor/version.rb
@@ -1,3 +1,3 @@
class Bundler::Thor
- VERSION = "0.20.0"
+ VERSION = "1.1.0"
end
diff --git a/lib/bundler/vendor/tmpdir/lib/tmpdir.rb b/lib/bundler/vendor/tmpdir/lib/tmpdir.rb
new file mode 100644
index 0000000000..70d43e0c6b
--- /dev/null
+++ b/lib/bundler/vendor/tmpdir/lib/tmpdir.rb
@@ -0,0 +1,154 @@
+# frozen_string_literal: true
+#
+# tmpdir - retrieve temporary directory path
+#
+# $Id$
+#
+
+require_relative '../../fileutils/lib/fileutils'
+begin
+ require 'etc.so'
+rescue LoadError # rescue LoadError for miniruby
+end
+
+class Bundler::Dir < Dir
+
+ @systmpdir ||= defined?(Etc.systmpdir) ? Etc.systmpdir : '/tmp'
+
+ ##
+ # Returns the operating system's temporary file path.
+
+ def self.tmpdir
+ tmp = nil
+ ['TMPDIR', 'TMP', 'TEMP', ['system temporary path', @systmpdir], ['/tmp']*2, ['.']*2].each do |name, dir = ENV[name]|
+ next if !dir
+ dir = File.expand_path(dir)
+ stat = File.stat(dir) rescue next
+ case
+ when !stat.directory?
+ warn "#{name} is not a directory: #{dir}"
+ when !stat.writable?
+ warn "#{name} is not writable: #{dir}"
+ when stat.world_writable? && !stat.sticky?
+ warn "#{name} is world-writable: #{dir}"
+ else
+ tmp = dir
+ break
+ end
+ end
+ raise ArgumentError, "could not find a temporary directory" unless tmp
+ tmp
+ end
+
+ # Bundler::Dir.mktmpdir creates a temporary directory.
+ #
+ # The directory is created with 0700 permission.
+ # Application should not change the permission to make the temporary directory accessible from other users.
+ #
+ # The prefix and suffix of the name of the directory is specified by
+ # the optional first argument, <i>prefix_suffix</i>.
+ # - If it is not specified or nil, "d" is used as the prefix and no suffix is used.
+ # - If it is a string, it is used as the prefix and no suffix is used.
+ # - If it is an array, first element is used as the prefix and second element is used as a suffix.
+ #
+ # Bundler::Dir.mktmpdir {|dir| dir is ".../d..." }
+ # Bundler::Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
+ # Bundler::Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }
+ #
+ # The directory is created under Bundler::Dir.tmpdir or
+ # the optional second argument <i>tmpdir</i> if non-nil value is given.
+ #
+ # Bundler::Dir.mktmpdir {|dir| dir is "#{Bundler::Dir.tmpdir}/d..." }
+ # Bundler::Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }
+ #
+ # If a block is given,
+ # it is yielded with the path of the directory.
+ # The directory and its contents are removed
+ # using Bundler::FileUtils.remove_entry before Bundler::Dir.mktmpdir returns.
+ # The value of the block is returned.
+ #
+ # Bundler::Dir.mktmpdir {|dir|
+ # # use the directory...
+ # open("#{dir}/foo", "w") { ... }
+ # }
+ #
+ # If a block is not given,
+ # The path of the directory is returned.
+ # In this case, Bundler::Dir.mktmpdir doesn't remove the directory.
+ #
+ # dir = Bundler::Dir.mktmpdir
+ # begin
+ # # use the directory...
+ # open("#{dir}/foo", "w") { ... }
+ # ensure
+ # # remove the directory.
+ # Bundler::FileUtils.remove_entry dir
+ # end
+ #
+ def self.mktmpdir(prefix_suffix=nil, *rest, **options)
+ base = nil
+ path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|p, _, _, d|
+ base = d
+ mkdir(p, 0700)
+ }
+ if block_given?
+ begin
+ yield path.dup
+ ensure
+ unless base
+ stat = File.stat(File.dirname(path))
+ if stat.world_writable? and !stat.sticky?
+ raise ArgumentError, "parent directory is world writable but not sticky"
+ end
+ end
+ Bundler::FileUtils.remove_entry path
+ end
+ else
+ path
+ end
+ end
+
+ module Tmpname # :nodoc:
+ module_function
+
+ def tmpdir
+ Bundler::Dir.tmpdir
+ end
+
+ UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~"
+
+ class << (RANDOM = Random.new)
+ MAX = 36**6 # < 0x100000000
+ def next
+ rand(MAX).to_s(36)
+ end
+ end
+ private_constant :RANDOM
+
+ def create(basename, tmpdir=nil, max_try: nil, **opts)
+ origdir = tmpdir
+ tmpdir ||= tmpdir()
+ n = nil
+ prefix, suffix = basename
+ prefix = (String.try_convert(prefix) or
+ raise ArgumentError, "unexpected prefix: #{prefix.inspect}")
+ prefix = prefix.delete(UNUSABLE_CHARS)
+ suffix &&= (String.try_convert(suffix) or
+ raise ArgumentError, "unexpected suffix: #{suffix.inspect}")
+ suffix &&= suffix.delete(UNUSABLE_CHARS)
+ begin
+ t = Time.now.strftime("%Y%m%d")
+ path = "#{prefix}#{t}-#{$$}-#{RANDOM.next}"\
+ "#{n ? %[-#{n}] : ''}#{suffix||''}"
+ path = File.join(tmpdir, path)
+ yield(path, n, opts, origdir)
+ rescue Errno::EEXIST
+ n ||= 0
+ n += 1
+ retry if !max_try or n < max_try
+ raise "cannot generate temporary name using `#{basename}' under `#{tmpdir}'"
+ end
+ path
+ end
+ end
+end
diff --git a/lib/bundler/vendor/tsort/LICENSE.txt b/lib/bundler/vendor/tsort/LICENSE.txt
new file mode 100644
index 0000000000..a009caefea
--- /dev/null
+++ b/lib/bundler/vendor/tsort/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/lib/bundler/vendor/tsort/lib/tsort.rb b/lib/bundler/vendor/tsort/lib/tsort.rb
new file mode 100644
index 0000000000..8454583295
--- /dev/null
+++ b/lib/bundler/vendor/tsort/lib/tsort.rb
@@ -0,0 +1,453 @@
+# frozen_string_literal: true
+
+#--
+# tsort.rb - provides a module for topological sorting and strongly connected components.
+#++
+#
+
+#
+# TSort implements topological sorting using Tarjan's algorithm for
+# strongly connected components.
+#
+# TSort is designed to be able to be used with any object which can be
+# interpreted as a directed graph.
+#
+# TSort requires two methods to interpret an object as a graph,
+# tsort_each_node and tsort_each_child.
+#
+# * tsort_each_node is used to iterate for all nodes over a graph.
+# * tsort_each_child is used to iterate for child nodes of a given node.
+#
+# The equality of nodes are defined by eql? and hash since
+# TSort uses Hash internally.
+#
+# == A Simple Example
+#
+# The following example demonstrates how to mix the TSort module into an
+# existing class (in this case, Hash). Here, we're treating each key in
+# the hash as a node in the graph, and so we simply alias the required
+# #tsort_each_node method to Hash's #each_key method. For each key in the
+# hash, the associated value is an array of the node's child nodes. This
+# choice in turn leads to our implementation of the required #tsort_each_child
+# method, which fetches the array of child nodes and then iterates over that
+# array using the user-supplied block.
+#
+# require 'tsort'
+#
+# class Hash
+# include TSort
+# alias tsort_each_node each_key
+# def tsort_each_child(node, &block)
+# fetch(node).each(&block)
+# end
+# end
+#
+# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
+# #=> [3, 2, 1, 4]
+#
+# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
+# #=> [[4], [2, 3], [1]]
+#
+# == A More Realistic Example
+#
+# A very simple `make' like tool can be implemented as follows:
+#
+# require 'tsort'
+#
+# class Make
+# def initialize
+# @dep = {}
+# @dep.default = []
+# end
+#
+# def rule(outputs, inputs=[], &block)
+# triple = [outputs, inputs, block]
+# outputs.each {|f| @dep[f] = [triple]}
+# @dep[triple] = inputs
+# end
+#
+# def build(target)
+# each_strongly_connected_component_from(target) {|ns|
+# if ns.length != 1
+# fs = ns.delete_if {|n| Array === n}
+# raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
+# end
+# n = ns.first
+# if Array === n
+# outputs, inputs, block = n
+# inputs_time = inputs.map {|f| File.mtime f}.max
+# begin
+# outputs_time = outputs.map {|f| File.mtime f}.min
+# rescue Errno::ENOENT
+# outputs_time = nil
+# end
+# if outputs_time == nil ||
+# inputs_time != nil && outputs_time <= inputs_time
+# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
+# block.call
+# end
+# end
+# }
+# end
+#
+# def tsort_each_child(node, &block)
+# @dep[node].each(&block)
+# end
+# include TSort
+# end
+#
+# def command(arg)
+# print arg, "\n"
+# system arg
+# end
+#
+# m = Make.new
+# m.rule(%w[t1]) { command 'date > t1' }
+# m.rule(%w[t2]) { command 'date > t2' }
+# m.rule(%w[t3]) { command 'date > t3' }
+# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
+# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
+# m.build('t5')
+#
+# == Bugs
+#
+# * 'tsort.rb' is wrong name because this library uses
+# Tarjan's algorithm for strongly connected components.
+# Although 'strongly_connected_components.rb' is correct but too long.
+#
+# == References
+#
+# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms",
+# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
+#
+module Bundler
+ module TSort
+ class Cyclic < StandardError
+ end
+
+ # Returns a topologically sorted array of nodes.
+ # The array is sorted from children to parents, i.e.
+ # the first element has no child and the last node has no parent.
+ #
+ # If there is a cycle, TSort::Cyclic is raised.
+ #
+ # class G
+ # include TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # p graph.tsort #=> [4, 2, 3, 1]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # p graph.tsort # raises TSort::Cyclic
+ #
+ def tsort
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ TSort.tsort(each_node, each_child)
+ end
+
+ # Returns a topologically sorted array of nodes.
+ # The array is sorted from children to parents, i.e.
+ # the first element has no child and the last node has no parent.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # If there is a cycle, TSort::Cyclic is raised.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p TSort.tsort(each_node, each_child) # raises TSort::Cyclic
+ #
+ def TSort.tsort(each_node, each_child)
+ TSort.tsort_each(each_node, each_child).to_a
+ end
+
+ # The iterator version of the #tsort method.
+ # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
+ # modification of _obj_ during the iteration may lead to unexpected results.
+ #
+ # #tsort_each returns +nil+.
+ # If there is a cycle, TSort::Cyclic is raised.
+ #
+ # class G
+ # include TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.tsort_each {|n| p n }
+ # #=> 4
+ # # 2
+ # # 3
+ # # 1
+ #
+ def tsort_each(&block) # :yields: node
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ TSort.tsort_each(each_node, each_child, &block)
+ end
+
+ # The iterator version of the TSort.tsort method.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # TSort.tsort_each(each_node, each_child) {|n| p n }
+ # #=> 4
+ # # 2
+ # # 3
+ # # 1
+ #
+ def TSort.tsort_each(each_node, each_child) # :yields: node
+ return to_enum(__method__, each_node, each_child) unless block_given?
+
+ TSort.each_strongly_connected_component(each_node, each_child) {|component|
+ if component.size == 1
+ yield component.first
+ else
+ raise Cyclic.new("topological sort failed: #{component.inspect}")
+ end
+ }
+ end
+
+ # Returns strongly connected components as an array of arrays of nodes.
+ # The array is sorted from children to parents.
+ # Each elements of the array represents a strongly connected component.
+ #
+ # class G
+ # include TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
+ #
+ def strongly_connected_components
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ TSort.strongly_connected_components(each_node, each_child)
+ end
+
+ # Returns strongly connected components as an array of arrays of nodes.
+ # The array is sorted from children to parents.
+ # Each elements of the array represents a strongly connected component.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p TSort.strongly_connected_components(each_node, each_child)
+ # #=> [[4], [2], [3], [1]]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p TSort.strongly_connected_components(each_node, each_child)
+ # #=> [[4], [2, 3], [1]]
+ #
+ def TSort.strongly_connected_components(each_node, each_child)
+ TSort.each_strongly_connected_component(each_node, each_child).to_a
+ end
+
+ # The iterator version of the #strongly_connected_components method.
+ # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
+ # <tt><em>obj</em>.strongly_connected_components.each</tt>, but
+ # modification of _obj_ during the iteration may lead to unexpected results.
+ #
+ # #each_strongly_connected_component returns +nil+.
+ #
+ # class G
+ # include TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.each_strongly_connected_component {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ # # [3]
+ # # [1]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # graph.each_strongly_connected_component {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def each_strongly_connected_component(&block) # :yields: nodes
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ TSort.each_strongly_connected_component(each_node, each_child, &block)
+ end
+
+ # The iterator version of the TSort.strongly_connected_components method.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ # # [3]
+ # # [1]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def TSort.each_strongly_connected_component(each_node, each_child) # :yields: nodes
+ return to_enum(__method__, each_node, each_child) unless block_given?
+
+ id_map = {}
+ stack = []
+ each_node.call {|node|
+ unless id_map.include? node
+ TSort.each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
+ yield c
+ }
+ end
+ }
+ nil
+ end
+
+ # Iterates over strongly connected component in the subgraph reachable from
+ # _node_.
+ #
+ # Return value is unspecified.
+ #
+ # #each_strongly_connected_component_from doesn't call #tsort_each_node.
+ #
+ # class G
+ # include TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ #
+ def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
+ TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
+ end
+
+ # Iterates over strongly connected components in a graph.
+ # The graph is represented by _node_ and _each_child_.
+ #
+ # _node_ is the first node.
+ # _each_child_ should have +call+ method which takes a node argument
+ # and yields for each child node.
+ #
+ # Return value is unspecified.
+ #
+ # #TSort.each_strongly_connected_component_from is a class method and
+ # it doesn't need a class to represent a graph which includes TSort.
+ #
+ # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_child = lambda {|n, &b| graph[n].each(&b) }
+ # TSort.each_strongly_connected_component_from(1, each_child) {|scc|
+ # p scc
+ # }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def TSort.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
+ return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
+
+ minimum_id = node_id = id_map[node] = id_map.size
+ stack_length = stack.length
+ stack << node
+
+ each_child.call(node) {|child|
+ if id_map.include? child
+ child_id = id_map[child]
+ minimum_id = child_id if child_id && child_id < minimum_id
+ else
+ sub_minimum_id =
+ TSort.each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
+ yield c
+ }
+ minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
+ end
+ }
+
+ if node_id == minimum_id
+ component = stack.slice!(stack_length .. -1)
+ component.each {|n| id_map[n] = nil}
+ yield component
+ end
+
+ minimum_id
+ end
+
+ # Should be implemented by a extended class.
+ #
+ # #tsort_each_node is used to iterate for all nodes over a graph.
+ #
+ def tsort_each_node # :yields: node
+ raise NotImplementedError.new
+ end
+
+ # Should be implemented by a extended class.
+ #
+ # #tsort_each_child is used to iterate for child nodes of _node_.
+ #
+ def tsort_each_child(node) # :yields: child
+ raise NotImplementedError.new
+ end
+ end
+end
diff --git a/lib/bundler/vendor/uri/LICENSE.txt b/lib/bundler/vendor/uri/LICENSE.txt
new file mode 100644
index 0000000000..a009caefea
--- /dev/null
+++ b/lib/bundler/vendor/uri/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/lib/bundler/vendor/uri/lib/uri.rb b/lib/bundler/vendor/uri/lib/uri.rb
new file mode 100644
index 0000000000..00c01bd07b
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: false
+# Bundler::URI is a module providing classes to handle Uniform Resource Identifiers
+# (RFC2396[http://tools.ietf.org/html/rfc2396]).
+#
+# == Features
+#
+# * Uniform way of handling URIs.
+# * Flexibility to introduce custom Bundler::URI schemes.
+# * Flexibility to have an alternate Bundler::URI::Parser (or just different patterns
+# and regexp's).
+#
+# == Basic example
+#
+# require 'bundler/vendor/uri/lib/uri'
+#
+# uri = Bundler::URI("http://foo.com/posts?id=30&limit=5#time=1305298413")
+# #=> #<Bundler::URI::HTTP http://foo.com/posts?id=30&limit=5#time=1305298413>
+#
+# uri.scheme #=> "http"
+# uri.host #=> "foo.com"
+# uri.path #=> "/posts"
+# uri.query #=> "id=30&limit=5"
+# uri.fragment #=> "time=1305298413"
+#
+# uri.to_s #=> "http://foo.com/posts?id=30&limit=5#time=1305298413"
+#
+# == Adding custom URIs
+#
+# module Bundler::URI
+# class RSYNC < Generic
+# DEFAULT_PORT = 873
+# end
+# @@schemes['RSYNC'] = RSYNC
+# end
+# #=> Bundler::URI::RSYNC
+#
+# Bundler::URI.scheme_list
+# #=> {"FILE"=>Bundler::URI::File, "FTP"=>Bundler::URI::FTP, "HTTP"=>Bundler::URI::HTTP,
+# # "HTTPS"=>Bundler::URI::HTTPS, "LDAP"=>Bundler::URI::LDAP, "LDAPS"=>Bundler::URI::LDAPS,
+# # "MAILTO"=>Bundler::URI::MailTo, "RSYNC"=>Bundler::URI::RSYNC}
+#
+# uri = Bundler::URI("rsync://rsync.foo.com")
+# #=> #<Bundler::URI::RSYNC rsync://rsync.foo.com>
+#
+# == RFC References
+#
+# A good place to view an RFC spec is http://www.ietf.org/rfc.html.
+#
+# Here is a list of all related RFC's:
+# - RFC822[http://tools.ietf.org/html/rfc822]
+# - RFC1738[http://tools.ietf.org/html/rfc1738]
+# - RFC2255[http://tools.ietf.org/html/rfc2255]
+# - RFC2368[http://tools.ietf.org/html/rfc2368]
+# - RFC2373[http://tools.ietf.org/html/rfc2373]
+# - RFC2396[http://tools.ietf.org/html/rfc2396]
+# - RFC2732[http://tools.ietf.org/html/rfc2732]
+# - RFC3986[http://tools.ietf.org/html/rfc3986]
+#
+# == Class tree
+#
+# - Bundler::URI::Generic (in uri/generic.rb)
+# - Bundler::URI::File - (in uri/file.rb)
+# - Bundler::URI::FTP - (in uri/ftp.rb)
+# - Bundler::URI::HTTP - (in uri/http.rb)
+# - Bundler::URI::HTTPS - (in uri/https.rb)
+# - Bundler::URI::LDAP - (in uri/ldap.rb)
+# - Bundler::URI::LDAPS - (in uri/ldaps.rb)
+# - Bundler::URI::MailTo - (in uri/mailto.rb)
+# - Bundler::URI::Parser - (in uri/common.rb)
+# - Bundler::URI::REGEXP - (in uri/common.rb)
+# - Bundler::URI::REGEXP::PATTERN - (in uri/common.rb)
+# - Bundler::URI::Util - (in uri/common.rb)
+# - Bundler::URI::Escape - (in uri/common.rb)
+# - Bundler::URI::Error - (in uri/common.rb)
+# - Bundler::URI::InvalidURIError - (in uri/common.rb)
+# - Bundler::URI::InvalidComponentError - (in uri/common.rb)
+# - Bundler::URI::BadURIError - (in uri/common.rb)
+#
+# == Copyright Info
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# Documentation::
+# Akira Yamada <akira@ruby-lang.org>
+# Dmitry V. Sabanin <sdmitry@lrn.ru>
+# Vincent Batts <vbatts@hashbangbash.com>
+# License::
+# Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
+# You can redistribute it and/or modify it under the same term as Ruby.
+# Revision:: $Id$
+#
+
+module Bundler::URI
+end
+
+require_relative 'uri/version'
+require_relative 'uri/common'
+require_relative 'uri/generic'
+require_relative 'uri/file'
+require_relative 'uri/ftp'
+require_relative 'uri/http'
+require_relative 'uri/https'
+require_relative 'uri/ldap'
+require_relative 'uri/ldaps'
+require_relative 'uri/mailto'
diff --git a/lib/bundler/vendor/uri/lib/uri/common.rb b/lib/bundler/vendor/uri/lib/uri/common.rb
new file mode 100644
index 0000000000..cc1ab86c2f
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/common.rb
@@ -0,0 +1,744 @@
+# frozen_string_literal: true
+#--
+# = uri/common.rb
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# Revision:: $Id$
+# License::
+# You can redistribute it and/or modify it under the same term as Ruby.
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative "rfc2396_parser"
+require_relative "rfc3986_parser"
+
+module Bundler::URI
+ REGEXP = RFC2396_REGEXP
+ Parser = RFC2396_Parser
+ RFC3986_PARSER = RFC3986_Parser.new
+
+ # Bundler::URI::Parser.new
+ DEFAULT_PARSER = Parser.new
+ DEFAULT_PARSER.pattern.each_pair do |sym, str|
+ unless REGEXP::PATTERN.const_defined?(sym)
+ REGEXP::PATTERN.const_set(sym, str)
+ end
+ end
+ DEFAULT_PARSER.regexp.each_pair do |sym, str|
+ const_set(sym, str)
+ end
+
+ module Util # :nodoc:
+ def make_components_hash(klass, array_hash)
+ tmp = {}
+ if array_hash.kind_of?(Array) &&
+ array_hash.size == klass.component.size - 1
+ klass.component[1..-1].each_index do |i|
+ begin
+ tmp[klass.component[i + 1]] = array_hash[i].clone
+ rescue TypeError
+ tmp[klass.component[i + 1]] = array_hash[i]
+ end
+ end
+
+ elsif array_hash.kind_of?(Hash)
+ array_hash.each do |key, value|
+ begin
+ tmp[key] = value.clone
+ rescue TypeError
+ tmp[key] = value
+ end
+ end
+ else
+ raise ArgumentError,
+ "expected Array of or Hash of components of #{klass} (#{klass.component[1..-1].join(', ')})"
+ end
+ tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase
+
+ return tmp
+ end
+ module_function :make_components_hash
+ end
+
+ # Module for escaping unsafe characters with codes.
+ module Escape
+ #
+ # == Synopsis
+ #
+ # Bundler::URI.escape(str [, unsafe])
+ #
+ # == Args
+ #
+ # +str+::
+ # String to replaces in.
+ # +unsafe+::
+ # Regexp that matches all symbols that must be replaced with codes.
+ # By default uses <tt>UNSAFE</tt>.
+ # When this argument is a String, it represents a character set.
+ #
+ # == Description
+ #
+ # Escapes the string, replacing all unsafe characters with codes.
+ #
+ # This method is obsolete and should not be used. Instead, use
+ # CGI.escape, Bundler::URI.encode_www_form or Bundler::URI.encode_www_form_component
+ # depending on your specific use case.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # enc_uri = Bundler::URI.escape("http://example.com/?a=\11\15")
+ # # => "http://example.com/?a=%09%0D"
+ #
+ # Bundler::URI.unescape(enc_uri)
+ # # => "http://example.com/?a=\t\r"
+ #
+ # Bundler::URI.escape("@?@!", "!?")
+ # # => "@%3F@%21"
+ #
+ def escape(*arg)
+ warn "Bundler::URI.escape is obsolete", uplevel: 1
+ DEFAULT_PARSER.escape(*arg)
+ end
+ alias encode escape
+ #
+ # == Synopsis
+ #
+ # Bundler::URI.unescape(str)
+ #
+ # == Args
+ #
+ # +str+::
+ # String to unescape.
+ #
+ # == Description
+ #
+ # This method is obsolete and should not be used. Instead, use
+ # CGI.unescape, Bundler::URI.decode_www_form or Bundler::URI.decode_www_form_component
+ # depending on your specific use case.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # enc_uri = Bundler::URI.escape("http://example.com/?a=\11\15")
+ # # => "http://example.com/?a=%09%0D"
+ #
+ # Bundler::URI.unescape(enc_uri)
+ # # => "http://example.com/?a=\t\r"
+ #
+ def unescape(*arg)
+ warn "Bundler::URI.unescape is obsolete", uplevel: 1
+ DEFAULT_PARSER.unescape(*arg)
+ end
+ alias decode unescape
+ end # module Escape
+
+ extend Escape
+ include REGEXP
+
+ @@schemes = {}
+ # Returns a Hash of the defined schemes.
+ def self.scheme_list
+ @@schemes
+ end
+
+ #
+ # Base class for all Bundler::URI exceptions.
+ #
+ class Error < StandardError; end
+ #
+ # Not a Bundler::URI.
+ #
+ class InvalidURIError < Error; end
+ #
+ # Not a Bundler::URI component.
+ #
+ class InvalidComponentError < Error; end
+ #
+ # Bundler::URI is valid, bad usage is not.
+ #
+ class BadURIError < Error; end
+
+ #
+ # == Synopsis
+ #
+ # Bundler::URI::split(uri)
+ #
+ # == Args
+ #
+ # +uri+::
+ # String with Bundler::URI.
+ #
+ # == Description
+ #
+ # Splits the string on following parts and returns array with result:
+ #
+ # * Scheme
+ # * Userinfo
+ # * Host
+ # * Port
+ # * Registry
+ # * Path
+ # * Opaque
+ # * Query
+ # * Fragment
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # Bundler::URI.split("http://www.ruby-lang.org/")
+ # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
+ #
+ def self.split(uri)
+ RFC3986_PARSER.split(uri)
+ end
+
+ #
+ # == Synopsis
+ #
+ # Bundler::URI::parse(uri_str)
+ #
+ # == Args
+ #
+ # +uri_str+::
+ # String with Bundler::URI.
+ #
+ # == Description
+ #
+ # Creates one of the Bundler::URI's subclasses instance from the string.
+ #
+ # == Raises
+ #
+ # Bundler::URI::InvalidURIError::
+ # Raised if Bundler::URI given is not a correct one.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://www.ruby-lang.org/")
+ # # => #<Bundler::URI::HTTP http://www.ruby-lang.org/>
+ # uri.scheme
+ # # => "http"
+ # uri.host
+ # # => "www.ruby-lang.org"
+ #
+ # It's recommended to first ::escape the provided +uri_str+ if there are any
+ # invalid Bundler::URI characters.
+ #
+ def self.parse(uri)
+ RFC3986_PARSER.parse(uri)
+ end
+
+ #
+ # == Synopsis
+ #
+ # Bundler::URI::join(str[, str, ...])
+ #
+ # == Args
+ #
+ # +str+::
+ # String(s) to work with, will be converted to RFC3986 URIs before merging.
+ #
+ # == Description
+ #
+ # Joins URIs.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # Bundler::URI.join("http://example.com/","main.rbx")
+ # # => #<Bundler::URI::HTTP http://example.com/main.rbx>
+ #
+ # Bundler::URI.join('http://example.com', 'foo')
+ # # => #<Bundler::URI::HTTP http://example.com/foo>
+ #
+ # Bundler::URI.join('http://example.com', '/foo', '/bar')
+ # # => #<Bundler::URI::HTTP http://example.com/bar>
+ #
+ # Bundler::URI.join('http://example.com', '/foo', 'bar')
+ # # => #<Bundler::URI::HTTP http://example.com/bar>
+ #
+ # Bundler::URI.join('http://example.com', '/foo/', 'bar')
+ # # => #<Bundler::URI::HTTP http://example.com/foo/bar>
+ #
+ def self.join(*str)
+ RFC3986_PARSER.join(*str)
+ end
+
+ #
+ # == Synopsis
+ #
+ # Bundler::URI::extract(str[, schemes][,&blk])
+ #
+ # == Args
+ #
+ # +str+::
+ # String to extract URIs from.
+ # +schemes+::
+ # Limit Bundler::URI matching to specific schemes.
+ #
+ # == Description
+ #
+ # Extracts URIs from a string. If block given, iterates through all matched URIs.
+ # Returns nil if block given or array with matches.
+ #
+ # == Usage
+ #
+ # require "bundler/vendor/uri/lib/uri"
+ #
+ # Bundler::URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
+ # # => ["http://foo.example.com/bla", "mailto:test@example.com"]
+ #
+ def self.extract(str, schemes = nil, &block)
+ warn "Bundler::URI.extract is obsolete", uplevel: 1 if $VERBOSE
+ DEFAULT_PARSER.extract(str, schemes, &block)
+ end
+
+ #
+ # == Synopsis
+ #
+ # Bundler::URI::regexp([match_schemes])
+ #
+ # == Args
+ #
+ # +match_schemes+::
+ # Array of schemes. If given, resulting regexp matches to URIs
+ # whose scheme is one of the match_schemes.
+ #
+ # == Description
+ #
+ # Returns a Regexp object which matches to Bundler::URI-like strings.
+ # The Regexp object returned by this method includes arbitrary
+ # number of capture group (parentheses). Never rely on it's number.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # # extract first Bundler::URI from html_string
+ # html_string.slice(Bundler::URI.regexp)
+ #
+ # # remove ftp URIs
+ # html_string.sub(Bundler::URI.regexp(['ftp']), '')
+ #
+ # # You should not rely on the number of parentheses
+ # html_string.scan(Bundler::URI.regexp) do |*matches|
+ # p $&
+ # end
+ #
+ def self.regexp(schemes = nil)
+ warn "Bundler::URI.regexp is obsolete", uplevel: 1 if $VERBOSE
+ DEFAULT_PARSER.make_regexp(schemes)
+ end
+
+ TBLENCWWWCOMP_ = {} # :nodoc:
+ 256.times do |i|
+ TBLENCWWWCOMP_[-i.chr] = -('%%%02X' % i)
+ end
+ TBLENCWWWCOMP_[' '] = '+'
+ TBLENCWWWCOMP_.freeze
+ TBLDECWWWCOMP_ = {} # :nodoc:
+ 256.times do |i|
+ h, l = i>>4, i&15
+ TBLDECWWWCOMP_[-('%%%X%X' % [h, l])] = -i.chr
+ TBLDECWWWCOMP_[-('%%%x%X' % [h, l])] = -i.chr
+ TBLDECWWWCOMP_[-('%%%X%x' % [h, l])] = -i.chr
+ TBLDECWWWCOMP_[-('%%%x%x' % [h, l])] = -i.chr
+ end
+ TBLDECWWWCOMP_['+'] = ' '
+ TBLDECWWWCOMP_.freeze
+
+ # Encodes given +str+ to URL-encoded form data.
+ #
+ # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
+ # (ASCII space) to + and converts others to %XX.
+ #
+ # If +enc+ is given, convert +str+ to the encoding before percent encoding.
+ #
+ # This is an implementation of
+ # http://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data.
+ #
+ # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form.
+ def self.encode_www_form_component(str, enc=nil)
+ str = str.to_s.dup
+ if str.encoding != Encoding::ASCII_8BIT
+ if enc && enc != Encoding::ASCII_8BIT
+ str.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace)
+ str.encode!(enc, fallback: ->(x){"&##{x.ord};"})
+ end
+ str.force_encoding(Encoding::ASCII_8BIT)
+ end
+ str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_)
+ str.force_encoding(Encoding::US_ASCII)
+ end
+
+ # Decodes given +str+ of URL-encoded form data.
+ #
+ # This decodes + to SP.
+ #
+ # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form.
+ def self.decode_www_form_component(str, enc=Encoding::UTF_8)
+ raise ArgumentError, "invalid %-encoding (#{str})" if /%(?!\h\h)/ =~ str
+ str.b.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc)
+ end
+
+ # Generates URL-encoded form data from given +enum+.
+ #
+ # This generates application/x-www-form-urlencoded data defined in HTML5
+ # from given an Enumerable object.
+ #
+ # This internally uses Bundler::URI.encode_www_form_component(str).
+ #
+ # This method doesn't convert the encoding of given items, so convert them
+ # before calling this method if you want to send data as other than original
+ # encoding or mixed encoding data. (Strings which are encoded in an HTML5
+ # ASCII incompatible encoding are converted to UTF-8.)
+ #
+ # This method doesn't handle files. When you send a file, use
+ # multipart/form-data.
+ #
+ # This refers http://url.spec.whatwg.org/#concept-urlencoded-serializer
+ #
+ # Bundler::URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
+ # #=> "q=ruby&lang=en"
+ # Bundler::URI.encode_www_form("q" => "ruby", "lang" => "en")
+ # #=> "q=ruby&lang=en"
+ # Bundler::URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
+ # #=> "q=ruby&q=perl&lang=en"
+ # Bundler::URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
+ # #=> "q=ruby&q=perl&lang=en"
+ #
+ # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form.
+ def self.encode_www_form(enum, enc=nil)
+ enum.map do |k,v|
+ if v.nil?
+ encode_www_form_component(k, enc)
+ elsif v.respond_to?(:to_ary)
+ v.to_ary.map do |w|
+ str = encode_www_form_component(k, enc)
+ unless w.nil?
+ str << '='
+ str << encode_www_form_component(w, enc)
+ end
+ end.join('&')
+ else
+ str = encode_www_form_component(k, enc)
+ str << '='
+ str << encode_www_form_component(v, enc)
+ end
+ end.join('&')
+ end
+
+ # Decodes URL-encoded form data from given +str+.
+ #
+ # This decodes application/x-www-form-urlencoded data
+ # and returns an array of key-value arrays.
+ #
+ # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser,
+ # so this supports only &-separator, and doesn't support ;-separator.
+ #
+ # ary = Bundler::URI.decode_www_form("a=1&a=2&b=3")
+ # ary #=> [['a', '1'], ['a', '2'], ['b', '3']]
+ # ary.assoc('a').last #=> '1'
+ # ary.assoc('b').last #=> '3'
+ # ary.rassoc('a').last #=> '2'
+ # Hash[ary] #=> {"a"=>"2", "b"=>"3"}
+ #
+ # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form.
+ def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false)
+ raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only?
+ ary = []
+ return ary if str.empty?
+ enc = Encoding.find(enc)
+ str.b.each_line(separator) do |string|
+ string.chomp!(separator)
+ key, sep, val = string.partition('=')
+ if isindex
+ if sep.empty?
+ val = key
+ key = +''
+ end
+ isindex = false
+ end
+
+ if use__charset_ and key == '_charset_' and e = get_encoding(val)
+ enc = e
+ use__charset_ = false
+ end
+
+ key.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_)
+ if val
+ val.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_)
+ else
+ val = +''
+ end
+
+ ary << [key, val]
+ end
+ ary.each do |k, v|
+ k.force_encoding(enc)
+ k.scrub!
+ v.force_encoding(enc)
+ v.scrub!
+ end
+ ary
+ end
+
+ private
+=begin command for WEB_ENCODINGS_
+ curl https://encoding.spec.whatwg.org/encodings.json|
+ ruby -rjson -e 'H={}
+ h={
+ "shift_jis"=>"Windows-31J",
+ "euc-jp"=>"cp51932",
+ "iso-2022-jp"=>"cp50221",
+ "x-mac-cyrillic"=>"macCyrillic",
+ }
+ JSON($<.read).map{|x|x["encodings"]}.flatten.each{|x|
+ Encoding.find(n=h.fetch(n=x["name"].downcase,n))rescue next
+ x["labels"].each{|y|H[y]=n}
+ }
+ puts "{"
+ H.each{|k,v|puts %[ #{k.dump}=>#{v.dump},]}
+ puts "}"
+'
+=end
+ WEB_ENCODINGS_ = {
+ "unicode-1-1-utf-8"=>"utf-8",
+ "utf-8"=>"utf-8",
+ "utf8"=>"utf-8",
+ "866"=>"ibm866",
+ "cp866"=>"ibm866",
+ "csibm866"=>"ibm866",
+ "ibm866"=>"ibm866",
+ "csisolatin2"=>"iso-8859-2",
+ "iso-8859-2"=>"iso-8859-2",
+ "iso-ir-101"=>"iso-8859-2",
+ "iso8859-2"=>"iso-8859-2",
+ "iso88592"=>"iso-8859-2",
+ "iso_8859-2"=>"iso-8859-2",
+ "iso_8859-2:1987"=>"iso-8859-2",
+ "l2"=>"iso-8859-2",
+ "latin2"=>"iso-8859-2",
+ "csisolatin3"=>"iso-8859-3",
+ "iso-8859-3"=>"iso-8859-3",
+ "iso-ir-109"=>"iso-8859-3",
+ "iso8859-3"=>"iso-8859-3",
+ "iso88593"=>"iso-8859-3",
+ "iso_8859-3"=>"iso-8859-3",
+ "iso_8859-3:1988"=>"iso-8859-3",
+ "l3"=>"iso-8859-3",
+ "latin3"=>"iso-8859-3",
+ "csisolatin4"=>"iso-8859-4",
+ "iso-8859-4"=>"iso-8859-4",
+ "iso-ir-110"=>"iso-8859-4",
+ "iso8859-4"=>"iso-8859-4",
+ "iso88594"=>"iso-8859-4",
+ "iso_8859-4"=>"iso-8859-4",
+ "iso_8859-4:1988"=>"iso-8859-4",
+ "l4"=>"iso-8859-4",
+ "latin4"=>"iso-8859-4",
+ "csisolatincyrillic"=>"iso-8859-5",
+ "cyrillic"=>"iso-8859-5",
+ "iso-8859-5"=>"iso-8859-5",
+ "iso-ir-144"=>"iso-8859-5",
+ "iso8859-5"=>"iso-8859-5",
+ "iso88595"=>"iso-8859-5",
+ "iso_8859-5"=>"iso-8859-5",
+ "iso_8859-5:1988"=>"iso-8859-5",
+ "arabic"=>"iso-8859-6",
+ "asmo-708"=>"iso-8859-6",
+ "csiso88596e"=>"iso-8859-6",
+ "csiso88596i"=>"iso-8859-6",
+ "csisolatinarabic"=>"iso-8859-6",
+ "ecma-114"=>"iso-8859-6",
+ "iso-8859-6"=>"iso-8859-6",
+ "iso-8859-6-e"=>"iso-8859-6",
+ "iso-8859-6-i"=>"iso-8859-6",
+ "iso-ir-127"=>"iso-8859-6",
+ "iso8859-6"=>"iso-8859-6",
+ "iso88596"=>"iso-8859-6",
+ "iso_8859-6"=>"iso-8859-6",
+ "iso_8859-6:1987"=>"iso-8859-6",
+ "csisolatingreek"=>"iso-8859-7",
+ "ecma-118"=>"iso-8859-7",
+ "elot_928"=>"iso-8859-7",
+ "greek"=>"iso-8859-7",
+ "greek8"=>"iso-8859-7",
+ "iso-8859-7"=>"iso-8859-7",
+ "iso-ir-126"=>"iso-8859-7",
+ "iso8859-7"=>"iso-8859-7",
+ "iso88597"=>"iso-8859-7",
+ "iso_8859-7"=>"iso-8859-7",
+ "iso_8859-7:1987"=>"iso-8859-7",
+ "sun_eu_greek"=>"iso-8859-7",
+ "csiso88598e"=>"iso-8859-8",
+ "csisolatinhebrew"=>"iso-8859-8",
+ "hebrew"=>"iso-8859-8",
+ "iso-8859-8"=>"iso-8859-8",
+ "iso-8859-8-e"=>"iso-8859-8",
+ "iso-ir-138"=>"iso-8859-8",
+ "iso8859-8"=>"iso-8859-8",
+ "iso88598"=>"iso-8859-8",
+ "iso_8859-8"=>"iso-8859-8",
+ "iso_8859-8:1988"=>"iso-8859-8",
+ "visual"=>"iso-8859-8",
+ "csisolatin6"=>"iso-8859-10",
+ "iso-8859-10"=>"iso-8859-10",
+ "iso-ir-157"=>"iso-8859-10",
+ "iso8859-10"=>"iso-8859-10",
+ "iso885910"=>"iso-8859-10",
+ "l6"=>"iso-8859-10",
+ "latin6"=>"iso-8859-10",
+ "iso-8859-13"=>"iso-8859-13",
+ "iso8859-13"=>"iso-8859-13",
+ "iso885913"=>"iso-8859-13",
+ "iso-8859-14"=>"iso-8859-14",
+ "iso8859-14"=>"iso-8859-14",
+ "iso885914"=>"iso-8859-14",
+ "csisolatin9"=>"iso-8859-15",
+ "iso-8859-15"=>"iso-8859-15",
+ "iso8859-15"=>"iso-8859-15",
+ "iso885915"=>"iso-8859-15",
+ "iso_8859-15"=>"iso-8859-15",
+ "l9"=>"iso-8859-15",
+ "iso-8859-16"=>"iso-8859-16",
+ "cskoi8r"=>"koi8-r",
+ "koi"=>"koi8-r",
+ "koi8"=>"koi8-r",
+ "koi8-r"=>"koi8-r",
+ "koi8_r"=>"koi8-r",
+ "koi8-ru"=>"koi8-u",
+ "koi8-u"=>"koi8-u",
+ "dos-874"=>"windows-874",
+ "iso-8859-11"=>"windows-874",
+ "iso8859-11"=>"windows-874",
+ "iso885911"=>"windows-874",
+ "tis-620"=>"windows-874",
+ "windows-874"=>"windows-874",
+ "cp1250"=>"windows-1250",
+ "windows-1250"=>"windows-1250",
+ "x-cp1250"=>"windows-1250",
+ "cp1251"=>"windows-1251",
+ "windows-1251"=>"windows-1251",
+ "x-cp1251"=>"windows-1251",
+ "ansi_x3.4-1968"=>"windows-1252",
+ "ascii"=>"windows-1252",
+ "cp1252"=>"windows-1252",
+ "cp819"=>"windows-1252",
+ "csisolatin1"=>"windows-1252",
+ "ibm819"=>"windows-1252",
+ "iso-8859-1"=>"windows-1252",
+ "iso-ir-100"=>"windows-1252",
+ "iso8859-1"=>"windows-1252",
+ "iso88591"=>"windows-1252",
+ "iso_8859-1"=>"windows-1252",
+ "iso_8859-1:1987"=>"windows-1252",
+ "l1"=>"windows-1252",
+ "latin1"=>"windows-1252",
+ "us-ascii"=>"windows-1252",
+ "windows-1252"=>"windows-1252",
+ "x-cp1252"=>"windows-1252",
+ "cp1253"=>"windows-1253",
+ "windows-1253"=>"windows-1253",
+ "x-cp1253"=>"windows-1253",
+ "cp1254"=>"windows-1254",
+ "csisolatin5"=>"windows-1254",
+ "iso-8859-9"=>"windows-1254",
+ "iso-ir-148"=>"windows-1254",
+ "iso8859-9"=>"windows-1254",
+ "iso88599"=>"windows-1254",
+ "iso_8859-9"=>"windows-1254",
+ "iso_8859-9:1989"=>"windows-1254",
+ "l5"=>"windows-1254",
+ "latin5"=>"windows-1254",
+ "windows-1254"=>"windows-1254",
+ "x-cp1254"=>"windows-1254",
+ "cp1255"=>"windows-1255",
+ "windows-1255"=>"windows-1255",
+ "x-cp1255"=>"windows-1255",
+ "cp1256"=>"windows-1256",
+ "windows-1256"=>"windows-1256",
+ "x-cp1256"=>"windows-1256",
+ "cp1257"=>"windows-1257",
+ "windows-1257"=>"windows-1257",
+ "x-cp1257"=>"windows-1257",
+ "cp1258"=>"windows-1258",
+ "windows-1258"=>"windows-1258",
+ "x-cp1258"=>"windows-1258",
+ "x-mac-cyrillic"=>"macCyrillic",
+ "x-mac-ukrainian"=>"macCyrillic",
+ "chinese"=>"gbk",
+ "csgb2312"=>"gbk",
+ "csiso58gb231280"=>"gbk",
+ "gb2312"=>"gbk",
+ "gb_2312"=>"gbk",
+ "gb_2312-80"=>"gbk",
+ "gbk"=>"gbk",
+ "iso-ir-58"=>"gbk",
+ "x-gbk"=>"gbk",
+ "gb18030"=>"gb18030",
+ "big5"=>"big5",
+ "big5-hkscs"=>"big5",
+ "cn-big5"=>"big5",
+ "csbig5"=>"big5",
+ "x-x-big5"=>"big5",
+ "cseucpkdfmtjapanese"=>"cp51932",
+ "euc-jp"=>"cp51932",
+ "x-euc-jp"=>"cp51932",
+ "csiso2022jp"=>"cp50221",
+ "iso-2022-jp"=>"cp50221",
+ "csshiftjis"=>"Windows-31J",
+ "ms932"=>"Windows-31J",
+ "ms_kanji"=>"Windows-31J",
+ "shift-jis"=>"Windows-31J",
+ "shift_jis"=>"Windows-31J",
+ "sjis"=>"Windows-31J",
+ "windows-31j"=>"Windows-31J",
+ "x-sjis"=>"Windows-31J",
+ "cseuckr"=>"euc-kr",
+ "csksc56011987"=>"euc-kr",
+ "euc-kr"=>"euc-kr",
+ "iso-ir-149"=>"euc-kr",
+ "korean"=>"euc-kr",
+ "ks_c_5601-1987"=>"euc-kr",
+ "ks_c_5601-1989"=>"euc-kr",
+ "ksc5601"=>"euc-kr",
+ "ksc_5601"=>"euc-kr",
+ "windows-949"=>"euc-kr",
+ "utf-16be"=>"utf-16be",
+ "utf-16"=>"utf-16le",
+ "utf-16le"=>"utf-16le",
+ } # :nodoc:
+
+ # :nodoc:
+ # return encoding or nil
+ # http://encoding.spec.whatwg.org/#concept-encoding-get
+ def self.get_encoding(label)
+ Encoding.find(WEB_ENCODINGS_[label.to_str.strip.downcase]) rescue nil
+ end
+end # module Bundler::URI
+
+module Bundler
+
+ #
+ # Returns +uri+ converted to an Bundler::URI object.
+ #
+ def URI(uri)
+ if uri.is_a?(Bundler::URI::Generic)
+ uri
+ elsif uri = String.try_convert(uri)
+ Bundler::URI.parse(uri)
+ else
+ raise ArgumentError,
+ "bad argument (expected Bundler::URI object or Bundler::URI string)"
+ end
+ end
+ module_function :URI
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/file.rb b/lib/bundler/vendor/uri/lib/uri/file.rb
new file mode 100644
index 0000000000..df42f8bcdd
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/file.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require_relative 'generic'
+
+module Bundler::URI
+
+ #
+ # The "file" Bundler::URI is defined by RFC8089.
+ #
+ class File < Generic
+ # A Default port of nil for Bundler::URI::File.
+ DEFAULT_PORT = nil
+
+ #
+ # An Array of the available components for Bundler::URI::File.
+ #
+ COMPONENT = [
+ :scheme,
+ :host,
+ :path
+ ].freeze
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::File object from components, with syntax checking.
+ #
+ # The components accepted are +host+ and +path+.
+ #
+ # The components should be provided either as an Array, or as a Hash
+ # with keys formed by preceding the component names with a colon.
+ #
+ # If an Array is used, the components must be passed in the
+ # order <code>[host, path]</code>.
+ #
+ # Examples:
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri1 = Bundler::URI::File.build(['host.example.com', '/path/file.zip'])
+ # uri1.to_s # => "file://host.example.com/path/file.zip"
+ #
+ # uri2 = Bundler::URI::File.build({:host => 'host.example.com',
+ # :path => '/ruby/src'})
+ # uri2.to_s # => "file://host.example.com/ruby/src"
+ #
+ def self.build(args)
+ tmp = Util::make_components_hash(self, args)
+ super(tmp)
+ end
+
+ # Protected setter for the host component +v+.
+ #
+ # See also Bundler::URI::Generic.host=.
+ #
+ def set_host(v)
+ v = "" if v.nil? || v == "localhost"
+ @host = v
+ end
+
+ # do nothing
+ def set_port(v)
+ end
+
+ # raise InvalidURIError
+ def check_userinfo(user)
+ raise Bundler::URI::InvalidURIError, "can not set userinfo for file Bundler::URI"
+ end
+
+ # raise InvalidURIError
+ def check_user(user)
+ raise Bundler::URI::InvalidURIError, "can not set user for file Bundler::URI"
+ end
+
+ # raise InvalidURIError
+ def check_password(user)
+ raise Bundler::URI::InvalidURIError, "can not set password for file Bundler::URI"
+ end
+
+ # do nothing
+ def set_userinfo(v)
+ end
+
+ # do nothing
+ def set_user(v)
+ end
+
+ # do nothing
+ def set_password(v)
+ end
+ end
+
+ @@schemes['FILE'] = File
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/ftp.rb b/lib/bundler/vendor/uri/lib/uri/ftp.rb
new file mode 100644
index 0000000000..ad39f57d7b
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/ftp.rb
@@ -0,0 +1,267 @@
+# frozen_string_literal: false
+# = uri/ftp.rb
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+# Revision:: $Id$
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative 'generic'
+
+module Bundler::URI
+
+ #
+ # FTP Bundler::URI syntax is defined by RFC1738 section 3.2.
+ #
+ # This class will be redesigned because of difference of implementations;
+ # the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it
+ # is a good summary about the de facto spec.
+ # http://tools.ietf.org/html/draft-hoffman-ftp-uri-04
+ #
+ class FTP < Generic
+ # A Default port of 21 for Bundler::URI::FTP.
+ DEFAULT_PORT = 21
+
+ #
+ # An Array of the available components for Bundler::URI::FTP.
+ #
+ COMPONENT = [
+ :scheme,
+ :userinfo, :host, :port,
+ :path, :typecode
+ ].freeze
+
+ #
+ # Typecode is "a", "i", or "d".
+ #
+ # * "a" indicates a text file (the FTP command was ASCII)
+ # * "i" indicates a binary file (FTP command IMAGE)
+ # * "d" indicates the contents of a directory should be displayed
+ #
+ TYPECODE = ['a', 'i', 'd'].freeze
+
+ # Typecode prefix ";type=".
+ TYPECODE_PREFIX = ';type='.freeze
+
+ def self.new2(user, password, host, port, path,
+ typecode = nil, arg_check = true) # :nodoc:
+ # Do not use this method! Not tested. [Bug #7301]
+ # This methods remains just for compatibility,
+ # Keep it undocumented until the active maintainer is assigned.
+ typecode = nil if typecode.size == 0
+ if typecode && !TYPECODE.include?(typecode)
+ raise ArgumentError,
+ "bad typecode is specified: #{typecode}"
+ end
+
+ # do escape
+
+ self.new('ftp',
+ [user, password],
+ host, port, nil,
+ typecode ? path + TYPECODE_PREFIX + typecode : path,
+ nil, nil, nil, arg_check)
+ end
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::FTP object from components, with syntax checking.
+ #
+ # The components accepted are +userinfo+, +host+, +port+, +path+, and
+ # +typecode+.
+ #
+ # The components should be provided either as an Array, or as a Hash
+ # with keys formed by preceding the component names with a colon.
+ #
+ # If an Array is used, the components must be passed in the
+ # order <code>[userinfo, host, port, path, typecode]</code>.
+ #
+ # If the path supplied is absolute, it will be escaped in order to
+ # make it absolute in the Bundler::URI.
+ #
+ # Examples:
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri1 = Bundler::URI::FTP.build(['user:password', 'ftp.example.com', nil,
+ # '/path/file.zip', 'i'])
+ # uri1.to_s # => "ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=i"
+ #
+ # uri2 = Bundler::URI::FTP.build({:host => 'ftp.example.com',
+ # :path => 'ruby/src'})
+ # uri2.to_s # => "ftp://ftp.example.com/ruby/src"
+ #
+ def self.build(args)
+
+ # Fix the incoming path to be generic URL syntax
+ # FTP path -> URL path
+ # foo/bar /foo/bar
+ # /foo/bar /%2Ffoo/bar
+ #
+ if args.kind_of?(Array)
+ args[3] = '/' + args[3].sub(/^\//, '%2F')
+ else
+ args[:path] = '/' + args[:path].sub(/^\//, '%2F')
+ end
+
+ tmp = Util::make_components_hash(self, args)
+
+ if tmp[:typecode]
+ if tmp[:typecode].size == 1
+ tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
+ end
+ tmp[:path] << tmp[:typecode]
+ end
+
+ return super(tmp)
+ end
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::FTP object from generic URL components with no
+ # syntax checking.
+ #
+ # Unlike build(), this method does not escape the path component as
+ # required by RFC1738; instead it is treated as per RFC2396.
+ #
+ # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
+ # +opaque+, +query+, and +fragment+, in that order.
+ #
+ def initialize(scheme,
+ userinfo, host, port, registry,
+ path, opaque,
+ query,
+ fragment,
+ parser = nil,
+ arg_check = false)
+ raise InvalidURIError unless path
+ path = path.sub(/^\//,'')
+ path.sub!(/^%2F/,'/')
+ super(scheme, userinfo, host, port, registry, path, opaque,
+ query, fragment, parser, arg_check)
+ @typecode = nil
+ if tmp = @path.index(TYPECODE_PREFIX)
+ typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
+ @path = @path[0..tmp - 1]
+
+ if arg_check
+ self.typecode = typecode
+ else
+ self.set_typecode(typecode)
+ end
+ end
+ end
+
+ # typecode accessor.
+ #
+ # See Bundler::URI::FTP::COMPONENT.
+ attr_reader :typecode
+
+ # Validates typecode +v+,
+ # returns +true+ or +false+.
+ #
+ def check_typecode(v)
+ if TYPECODE.include?(v)
+ return true
+ else
+ raise InvalidComponentError,
+ "bad typecode(expected #{TYPECODE.join(', ')}): #{v}"
+ end
+ end
+ private :check_typecode
+
+ # Private setter for the typecode +v+.
+ #
+ # See also Bundler::URI::FTP.typecode=.
+ #
+ def set_typecode(v)
+ @typecode = v
+ end
+ protected :set_typecode
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the typecode +v+
+ # (with validation).
+ #
+ # See also Bundler::URI::FTP.check_typecode.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("ftp://john@ftp.example.com/my_file.img")
+ # #=> #<Bundler::URI::FTP ftp://john@ftp.example.com/my_file.img>
+ # uri.typecode = "i"
+ # uri
+ # #=> #<Bundler::URI::FTP ftp://john@ftp.example.com/my_file.img;type=i>
+ #
+ def typecode=(typecode)
+ check_typecode(typecode)
+ set_typecode(typecode)
+ typecode
+ end
+
+ def merge(oth) # :nodoc:
+ tmp = super(oth)
+ if self != tmp
+ tmp.set_typecode(oth.typecode)
+ end
+
+ return tmp
+ end
+
+ # Returns the path from an FTP Bundler::URI.
+ #
+ # RFC 1738 specifically states that the path for an FTP Bundler::URI does not
+ # include the / which separates the Bundler::URI path from the Bundler::URI host. Example:
+ #
+ # <code>ftp://ftp.example.com/pub/ruby</code>
+ #
+ # The above Bundler::URI indicates that the client should connect to
+ # ftp.example.com then cd to pub/ruby from the initial login directory.
+ #
+ # If you want to cd to an absolute directory, you must include an
+ # escaped / (%2F) in the path. Example:
+ #
+ # <code>ftp://ftp.example.com/%2Fpub/ruby</code>
+ #
+ # This method will then return "/pub/ruby".
+ #
+ def path
+ return @path.sub(/^\//,'').sub(/^%2F/,'/')
+ end
+
+ # Private setter for the path of the Bundler::URI::FTP.
+ def set_path(v)
+ super("/" + v.sub(/^\//, "%2F"))
+ end
+ protected :set_path
+
+ # Returns a String representation of the Bundler::URI::FTP.
+ def to_s
+ save_path = nil
+ if @typecode
+ save_path = @path
+ @path = @path + TYPECODE_PREFIX + @typecode
+ end
+ str = super
+ if @typecode
+ @path = save_path
+ end
+
+ return str
+ end
+ end
+ @@schemes['FTP'] = FTP
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/generic.rb b/lib/bundler/vendor/uri/lib/uri/generic.rb
new file mode 100644
index 0000000000..56b09e1d7f
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/generic.rb
@@ -0,0 +1,1568 @@
+# frozen_string_literal: true
+
+# = uri/generic.rb
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+# Revision:: $Id$
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative 'common'
+autoload :IPSocket, 'socket'
+autoload :IPAddr, 'ipaddr'
+
+module Bundler::URI
+
+ #
+ # Base class for all Bundler::URI classes.
+ # Implements generic Bundler::URI syntax as per RFC 2396.
+ #
+ class Generic
+ include Bundler::URI
+
+ #
+ # A Default port of nil for Bundler::URI::Generic.
+ #
+ DEFAULT_PORT = nil
+
+ #
+ # Returns default port.
+ #
+ def self.default_port
+ self::DEFAULT_PORT
+ end
+
+ #
+ # Returns default port.
+ #
+ def default_port
+ self.class.default_port
+ end
+
+ #
+ # An Array of the available components for Bundler::URI::Generic.
+ #
+ COMPONENT = [
+ :scheme,
+ :userinfo, :host, :port, :registry,
+ :path, :opaque,
+ :query,
+ :fragment
+ ].freeze
+
+ #
+ # Components of the Bundler::URI in the order.
+ #
+ def self.component
+ self::COMPONENT
+ end
+
+ USE_REGISTRY = false # :nodoc:
+
+ def self.use_registry # :nodoc:
+ self::USE_REGISTRY
+ end
+
+ #
+ # == Synopsis
+ #
+ # See ::new.
+ #
+ # == Description
+ #
+ # At first, tries to create a new Bundler::URI::Generic instance using
+ # Bundler::URI::Generic::build. But, if exception Bundler::URI::InvalidComponentError is raised,
+ # then it does Bundler::URI::Escape.escape all Bundler::URI components and tries again.
+ #
+ def self.build2(args)
+ begin
+ return self.build(args)
+ rescue InvalidComponentError
+ if args.kind_of?(Array)
+ return self.build(args.collect{|x|
+ if x.is_a?(String)
+ DEFAULT_PARSER.escape(x)
+ else
+ x
+ end
+ })
+ elsif args.kind_of?(Hash)
+ tmp = {}
+ args.each do |key, value|
+ tmp[key] = if value
+ DEFAULT_PARSER.escape(value)
+ else
+ value
+ end
+ end
+ return self.build(tmp)
+ end
+ end
+ end
+
+ #
+ # == Synopsis
+ #
+ # See ::new.
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::Generic instance from components of Bundler::URI::Generic
+ # with check. Components are: scheme, userinfo, host, port, registry, path,
+ # opaque, query, and fragment. You can provide arguments either by an Array or a Hash.
+ # See ::new for hash keys to use or for order of array items.
+ #
+ def self.build(args)
+ if args.kind_of?(Array) &&
+ args.size == ::Bundler::URI::Generic::COMPONENT.size
+ tmp = args.dup
+ elsif args.kind_of?(Hash)
+ tmp = ::Bundler::URI::Generic::COMPONENT.collect do |c|
+ if args.include?(c)
+ args[c]
+ else
+ nil
+ end
+ end
+ else
+ component = self.class.component rescue ::Bundler::URI::Generic::COMPONENT
+ raise ArgumentError,
+ "expected Array of or Hash of components of #{self.class} (#{component.join(', ')})"
+ end
+
+ tmp << nil
+ tmp << true
+ return self.new(*tmp)
+ end
+
+ #
+ # == Args
+ #
+ # +scheme+::
+ # Protocol scheme, i.e. 'http','ftp','mailto' and so on.
+ # +userinfo+::
+ # User name and password, i.e. 'sdmitry:bla'.
+ # +host+::
+ # Server host name.
+ # +port+::
+ # Server port.
+ # +registry+::
+ # Registry of naming authorities.
+ # +path+::
+ # Path on server.
+ # +opaque+::
+ # Opaque part.
+ # +query+::
+ # Query data.
+ # +fragment+::
+ # Part of the Bundler::URI after '#' character.
+ # +parser+::
+ # Parser for internal use [Bundler::URI::DEFAULT_PARSER by default].
+ # +arg_check+::
+ # Check arguments [false by default].
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::Generic instance from ``generic'' components without check.
+ #
+ def initialize(scheme,
+ userinfo, host, port, registry,
+ path, opaque,
+ query,
+ fragment,
+ parser = DEFAULT_PARSER,
+ arg_check = false)
+ @scheme = nil
+ @user = nil
+ @password = nil
+ @host = nil
+ @port = nil
+ @path = nil
+ @query = nil
+ @opaque = nil
+ @fragment = nil
+ @parser = parser == DEFAULT_PARSER ? nil : parser
+
+ if arg_check
+ self.scheme = scheme
+ self.userinfo = userinfo
+ self.hostname = host
+ self.port = port
+ self.path = path
+ self.query = query
+ self.opaque = opaque
+ self.fragment = fragment
+ else
+ self.set_scheme(scheme)
+ self.set_userinfo(userinfo)
+ self.set_host(host)
+ self.set_port(port)
+ self.set_path(path)
+ self.query = query
+ self.set_opaque(opaque)
+ self.fragment=(fragment)
+ end
+ if registry
+ raise InvalidURIError,
+ "the scheme #{@scheme} does not accept registry part: #{registry} (or bad hostname?)"
+ end
+
+ @scheme&.freeze
+ self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
+ self.set_port(self.default_port) if self.default_port && !@port
+ end
+
+ #
+ # Returns the scheme component of the Bundler::URI.
+ #
+ # Bundler::URI("http://foo/bar/baz").scheme #=> "http"
+ #
+ attr_reader :scheme
+
+ # Returns the host component of the Bundler::URI.
+ #
+ # Bundler::URI("http://foo/bar/baz").host #=> "foo"
+ #
+ # It returns nil if no host component exists.
+ #
+ # Bundler::URI("mailto:foo@example.org").host #=> nil
+ #
+ # The component does not contain the port number.
+ #
+ # Bundler::URI("http://foo:8080/bar/baz").host #=> "foo"
+ #
+ # Since IPv6 addresses are wrapped with brackets in URIs,
+ # this method returns IPv6 addresses wrapped with brackets.
+ # This form is not appropriate to pass to socket methods such as TCPSocket.open.
+ # If unwrapped host names are required, use the #hostname method.
+ #
+ # Bundler::URI("http://[::1]/bar/baz").host #=> "[::1]"
+ # Bundler::URI("http://[::1]/bar/baz").hostname #=> "::1"
+ #
+ attr_reader :host
+
+ # Returns the port component of the Bundler::URI.
+ #
+ # Bundler::URI("http://foo/bar/baz").port #=> 80
+ # Bundler::URI("http://foo:8080/bar/baz").port #=> 8080
+ #
+ attr_reader :port
+
+ def registry # :nodoc:
+ nil
+ end
+
+ # Returns the path component of the Bundler::URI.
+ #
+ # Bundler::URI("http://foo/bar/baz").path #=> "/bar/baz"
+ #
+ attr_reader :path
+
+ # Returns the query component of the Bundler::URI.
+ #
+ # Bundler::URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar"
+ #
+ attr_reader :query
+
+ # Returns the opaque part of the Bundler::URI.
+ #
+ # Bundler::URI("mailto:foo@example.org").opaque #=> "foo@example.org"
+ # Bundler::URI("http://foo/bar/baz").opaque #=> nil
+ #
+ # The portion of the path that does not make use of the slash '/'.
+ # The path typically refers to an absolute path or an opaque part.
+ # (See RFC2396 Section 3 and 5.2.)
+ #
+ attr_reader :opaque
+
+ # Returns the fragment component of the Bundler::URI.
+ #
+ # Bundler::URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies"
+ #
+ attr_reader :fragment
+
+ # Returns the parser to be used.
+ #
+ # Unless a Bundler::URI::Parser is defined, DEFAULT_PARSER is used.
+ #
+ def parser
+ if !defined?(@parser) || !@parser
+ DEFAULT_PARSER
+ else
+ @parser || DEFAULT_PARSER
+ end
+ end
+
+ # Replaces self by other Bundler::URI object.
+ #
+ def replace!(oth)
+ if self.class != oth.class
+ raise ArgumentError, "expected #{self.class} object"
+ end
+
+ component.each do |c|
+ self.__send__("#{c}=", oth.__send__(c))
+ end
+ end
+ private :replace!
+
+ #
+ # Components of the Bundler::URI in the order.
+ #
+ def component
+ self.class.component
+ end
+
+ #
+ # Checks the scheme +v+ component against the Bundler::URI::Parser Regexp for :SCHEME.
+ #
+ def check_scheme(v)
+ if v && parser.regexp[:SCHEME] !~ v
+ raise InvalidComponentError,
+ "bad component(expected scheme component): #{v}"
+ end
+
+ return true
+ end
+ private :check_scheme
+
+ # Protected setter for the scheme component +v+.
+ #
+ # See also Bundler::URI::Generic.scheme=.
+ #
+ def set_scheme(v)
+ @scheme = v&.downcase
+ end
+ protected :set_scheme
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the scheme component +v+
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.check_scheme.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com")
+ # uri.scheme = "https"
+ # uri.to_s #=> "https://my.example.com"
+ #
+ def scheme=(v)
+ check_scheme(v)
+ set_scheme(v)
+ v
+ end
+
+ #
+ # Checks the +user+ and +password+.
+ #
+ # If +password+ is not provided, then +user+ is
+ # split, using Bundler::URI::Generic.split_userinfo, to
+ # pull +user+ and +password.
+ #
+ # See also Bundler::URI::Generic.check_user, Bundler::URI::Generic.check_password.
+ #
+ def check_userinfo(user, password = nil)
+ if !password
+ user, password = split_userinfo(user)
+ end
+ check_user(user)
+ check_password(password, user)
+
+ return true
+ end
+ private :check_userinfo
+
+ #
+ # Checks the user +v+ component for RFC2396 compliance
+ # and against the Bundler::URI::Parser Regexp for :USERINFO.
+ #
+ # Can not have a registry or opaque component defined,
+ # with a user component defined.
+ #
+ def check_user(v)
+ if @opaque
+ raise InvalidURIError,
+ "can not set user with opaque"
+ end
+
+ return v unless v
+
+ if parser.regexp[:USERINFO] !~ v
+ raise InvalidComponentError,
+ "bad component(expected userinfo component or user component): #{v}"
+ end
+
+ return true
+ end
+ private :check_user
+
+ #
+ # Checks the password +v+ component for RFC2396 compliance
+ # and against the Bundler::URI::Parser Regexp for :USERINFO.
+ #
+ # Can not have a registry or opaque component defined,
+ # with a user component defined.
+ #
+ def check_password(v, user = @user)
+ if @opaque
+ raise InvalidURIError,
+ "can not set password with opaque"
+ end
+ return v unless v
+
+ if !user
+ raise InvalidURIError,
+ "password component depends user component"
+ end
+
+ if parser.regexp[:USERINFO] !~ v
+ raise InvalidComponentError,
+ "bad password component"
+ end
+
+ return true
+ end
+ private :check_password
+
+ #
+ # Sets userinfo, argument is string like 'name:pass'.
+ #
+ def userinfo=(userinfo)
+ if userinfo.nil?
+ return nil
+ end
+ check_userinfo(*userinfo)
+ set_userinfo(*userinfo)
+ # returns userinfo
+ end
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the +user+ component
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.check_user.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://john:S3nsit1ve@my.example.com")
+ # uri.user = "sam"
+ # uri.to_s #=> "http://sam:V3ry_S3nsit1ve@my.example.com"
+ #
+ def user=(user)
+ check_user(user)
+ set_user(user)
+ # returns user
+ end
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the +password+ component
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.check_password.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://john:S3nsit1ve@my.example.com")
+ # uri.password = "V3ry_S3nsit1ve"
+ # uri.to_s #=> "http://john:V3ry_S3nsit1ve@my.example.com"
+ #
+ def password=(password)
+ check_password(password)
+ set_password(password)
+ # returns password
+ end
+
+ # Protected setter for the +user+ component, and +password+ if available
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.userinfo=.
+ #
+ def set_userinfo(user, password = nil)
+ unless password
+ user, password = split_userinfo(user)
+ end
+ @user = user
+ @password = password if password
+
+ [@user, @password]
+ end
+ protected :set_userinfo
+
+ # Protected setter for the user component +v+.
+ #
+ # See also Bundler::URI::Generic.user=.
+ #
+ def set_user(v)
+ set_userinfo(v, @password)
+ v
+ end
+ protected :set_user
+
+ # Protected setter for the password component +v+.
+ #
+ # See also Bundler::URI::Generic.password=.
+ #
+ def set_password(v)
+ @password = v
+ # returns v
+ end
+ protected :set_password
+
+ # Returns the userinfo +ui+ as <code>[user, password]</code>
+ # if properly formatted as 'user:password'.
+ def split_userinfo(ui)
+ return nil, nil unless ui
+ user, password = ui.split(':', 2)
+
+ return user, password
+ end
+ private :split_userinfo
+
+ # Escapes 'user:password' +v+ based on RFC 1738 section 3.1.
+ def escape_userpass(v)
+ parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
+ end
+ private :escape_userpass
+
+ # Returns the userinfo, either as 'user' or 'user:password'.
+ def userinfo
+ if @user.nil?
+ nil
+ elsif @password.nil?
+ @user
+ else
+ @user + ':' + @password
+ end
+ end
+
+ # Returns the user component.
+ def user
+ @user
+ end
+
+ # Returns the password component.
+ def password
+ @password
+ end
+
+ #
+ # Checks the host +v+ component for RFC2396 compliance
+ # and against the Bundler::URI::Parser Regexp for :HOST.
+ #
+ # Can not have a registry or opaque component defined,
+ # with a host component defined.
+ #
+ def check_host(v)
+ return v unless v
+
+ if @opaque
+ raise InvalidURIError,
+ "can not set host with registry or opaque"
+ elsif parser.regexp[:HOST] !~ v
+ raise InvalidComponentError,
+ "bad component(expected host component): #{v}"
+ end
+
+ return true
+ end
+ private :check_host
+
+ # Protected setter for the host component +v+.
+ #
+ # See also Bundler::URI::Generic.host=.
+ #
+ def set_host(v)
+ @host = v
+ end
+ protected :set_host
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the host component +v+
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.check_host.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com")
+ # uri.host = "foo.com"
+ # uri.to_s #=> "http://foo.com"
+ #
+ def host=(v)
+ check_host(v)
+ set_host(v)
+ v
+ end
+
+ # Extract the host part of the Bundler::URI and unwrap brackets for IPv6 addresses.
+ #
+ # This method is the same as Bundler::URI::Generic#host except
+ # brackets for IPv6 (and future IP) addresses are removed.
+ #
+ # uri = Bundler::URI("http://[::1]/bar")
+ # uri.hostname #=> "::1"
+ # uri.host #=> "[::1]"
+ #
+ def hostname
+ v = self.host
+ /\A\[(.*)\]\z/ =~ v ? $1 : v
+ end
+
+ # Sets the host part of the Bundler::URI as the argument with brackets for IPv6 addresses.
+ #
+ # This method is the same as Bundler::URI::Generic#host= except
+ # the argument can be a bare IPv6 address.
+ #
+ # uri = Bundler::URI("http://foo/bar")
+ # uri.hostname = "::1"
+ # uri.to_s #=> "http://[::1]/bar"
+ #
+ # If the argument seems to be an IPv6 address,
+ # it is wrapped with brackets.
+ #
+ def hostname=(v)
+ v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
+ self.host = v
+ end
+
+ #
+ # Checks the port +v+ component for RFC2396 compliance
+ # and against the Bundler::URI::Parser Regexp for :PORT.
+ #
+ # Can not have a registry or opaque component defined,
+ # with a port component defined.
+ #
+ def check_port(v)
+ return v unless v
+
+ if @opaque
+ raise InvalidURIError,
+ "can not set port with registry or opaque"
+ elsif !v.kind_of?(Integer) && parser.regexp[:PORT] !~ v
+ raise InvalidComponentError,
+ "bad component(expected port component): #{v.inspect}"
+ end
+
+ return true
+ end
+ private :check_port
+
+ # Protected setter for the port component +v+.
+ #
+ # See also Bundler::URI::Generic.port=.
+ #
+ def set_port(v)
+ v = v.empty? ? nil : v.to_i unless !v || v.kind_of?(Integer)
+ @port = v
+ end
+ protected :set_port
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the port component +v+
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.check_port.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com")
+ # uri.port = 8080
+ # uri.to_s #=> "http://my.example.com:8080"
+ #
+ def port=(v)
+ check_port(v)
+ set_port(v)
+ port
+ end
+
+ def check_registry(v) # :nodoc:
+ raise InvalidURIError, "can not set registry"
+ end
+ private :check_registry
+
+ def set_registry(v) #:nodoc:
+ raise InvalidURIError, "can not set registry"
+ end
+ protected :set_registry
+
+ def registry=(v)
+ raise InvalidURIError, "can not set registry"
+ end
+
+ #
+ # Checks the path +v+ component for RFC2396 compliance
+ # and against the Bundler::URI::Parser Regexp
+ # for :ABS_PATH and :REL_PATH.
+ #
+ # Can not have a opaque component defined,
+ # with a path component defined.
+ #
+ def check_path(v)
+ # raise if both hier and opaque are not nil, because:
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
+ if v && @opaque
+ raise InvalidURIError,
+ "path conflicts with opaque"
+ end
+
+ # If scheme is ftp, path may be relative.
+ # See RFC 1738 section 3.2.2, and RFC 2396.
+ if @scheme && @scheme != "ftp"
+ if v && v != '' && parser.regexp[:ABS_PATH] !~ v
+ raise InvalidComponentError,
+ "bad component(expected absolute path component): #{v}"
+ end
+ else
+ if v && v != '' && parser.regexp[:ABS_PATH] !~ v &&
+ parser.regexp[:REL_PATH] !~ v
+ raise InvalidComponentError,
+ "bad component(expected relative path component): #{v}"
+ end
+ end
+
+ return true
+ end
+ private :check_path
+
+ # Protected setter for the path component +v+.
+ #
+ # See also Bundler::URI::Generic.path=.
+ #
+ def set_path(v)
+ @path = v
+ end
+ protected :set_path
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the path component +v+
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.check_path.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com/pub/files")
+ # uri.path = "/faq/"
+ # uri.to_s #=> "http://my.example.com/faq/"
+ #
+ def path=(v)
+ check_path(v)
+ set_path(v)
+ v
+ end
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the query component +v+.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com/?id=25")
+ # uri.query = "id=1"
+ # uri.to_s #=> "http://my.example.com/?id=1"
+ #
+ def query=(v)
+ return @query = nil unless v
+ raise InvalidURIError, "query conflicts with opaque" if @opaque
+
+ x = v.to_str
+ v = x.dup if x.equal? v
+ v.encode!(Encoding::UTF_8) rescue nil
+ v.delete!("\t\r\n")
+ v.force_encoding(Encoding::ASCII_8BIT)
+ raise InvalidURIError, "invalid percent escape: #{$1}" if /(%\H\H)/n.match(v)
+ v.gsub!(/(?!%\h\h|[!$-&(-;=?-_a-~])./n.freeze){'%%%02X' % $&.ord}
+ v.force_encoding(Encoding::US_ASCII)
+ @query = v
+ end
+
+ #
+ # Checks the opaque +v+ component for RFC2396 compliance and
+ # against the Bundler::URI::Parser Regexp for :OPAQUE.
+ #
+ # Can not have a host, port, user, or path component defined,
+ # with an opaque component defined.
+ #
+ def check_opaque(v)
+ return v unless v
+
+ # raise if both hier and opaque are not nil, because:
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
+ if @host || @port || @user || @path # userinfo = @user + ':' + @password
+ raise InvalidURIError,
+ "can not set opaque with host, port, userinfo or path"
+ elsif v && parser.regexp[:OPAQUE] !~ v
+ raise InvalidComponentError,
+ "bad component(expected opaque component): #{v}"
+ end
+
+ return true
+ end
+ private :check_opaque
+
+ # Protected setter for the opaque component +v+.
+ #
+ # See also Bundler::URI::Generic.opaque=.
+ #
+ def set_opaque(v)
+ @opaque = v
+ end
+ protected :set_opaque
+
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the opaque component +v+
+ # (with validation).
+ #
+ # See also Bundler::URI::Generic.check_opaque.
+ #
+ def opaque=(v)
+ check_opaque(v)
+ set_opaque(v)
+ v
+ end
+
+ #
+ # Checks the fragment +v+ component against the Bundler::URI::Parser Regexp for :FRAGMENT.
+ #
+ #
+ # == Args
+ #
+ # +v+::
+ # String
+ #
+ # == Description
+ #
+ # Public setter for the fragment component +v+
+ # (with validation).
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com/?id=25#time=1305212049")
+ # uri.fragment = "time=1305212086"
+ # uri.to_s #=> "http://my.example.com/?id=25#time=1305212086"
+ #
+ def fragment=(v)
+ return @fragment = nil unless v
+
+ x = v.to_str
+ v = x.dup if x.equal? v
+ v.encode!(Encoding::UTF_8) rescue nil
+ v.delete!("\t\r\n")
+ v.force_encoding(Encoding::ASCII_8BIT)
+ v.gsub!(/(?!%\h\h|[!-~])./n){'%%%02X' % $&.ord}
+ v.force_encoding(Encoding::US_ASCII)
+ @fragment = v
+ end
+
+ #
+ # Returns true if Bundler::URI is hierarchical.
+ #
+ # == Description
+ #
+ # Bundler::URI has components listed in order of decreasing significance from left to right,
+ # see RFC3986 https://tools.ietf.org/html/rfc3986 1.2.3.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com/")
+ # uri.hierarchical?
+ # #=> true
+ # uri = Bundler::URI.parse("mailto:joe@example.com")
+ # uri.hierarchical?
+ # #=> false
+ #
+ def hierarchical?
+ if @path
+ true
+ else
+ false
+ end
+ end
+
+ #
+ # Returns true if Bundler::URI has a scheme (e.g. http:// or https://) specified.
+ #
+ def absolute?
+ if @scheme
+ true
+ else
+ false
+ end
+ end
+ alias absolute absolute?
+
+ #
+ # Returns true if Bundler::URI does not have a scheme (e.g. http:// or https://) specified.
+ #
+ def relative?
+ !absolute?
+ end
+
+ #
+ # Returns an Array of the path split on '/'.
+ #
+ def split_path(path)
+ path.split("/", -1)
+ end
+ private :split_path
+
+ #
+ # Merges a base path +base+, with relative path +rel+,
+ # returns a modified base path.
+ #
+ def merge_path(base, rel)
+
+ # RFC2396, Section 5.2, 5)
+ # RFC2396, Section 5.2, 6)
+ base_path = split_path(base)
+ rel_path = split_path(rel)
+
+ # RFC2396, Section 5.2, 6), a)
+ base_path << '' if base_path.last == '..'
+ while i = base_path.index('..')
+ base_path.slice!(i - 1, 2)
+ end
+
+ if (first = rel_path.first) and first.empty?
+ base_path.clear
+ rel_path.shift
+ end
+
+ # RFC2396, Section 5.2, 6), c)
+ # RFC2396, Section 5.2, 6), d)
+ rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
+ rel_path.delete('.')
+
+ # RFC2396, Section 5.2, 6), e)
+ tmp = []
+ rel_path.each do |x|
+ if x == '..' &&
+ !(tmp.empty? || tmp.last == '..')
+ tmp.pop
+ else
+ tmp << x
+ end
+ end
+
+ add_trailer_slash = !tmp.empty?
+ if base_path.empty?
+ base_path = [''] # keep '/' for root directory
+ elsif add_trailer_slash
+ base_path.pop
+ end
+ while x = tmp.shift
+ if x == '..'
+ # RFC2396, Section 4
+ # a .. or . in an absolute path has no special meaning
+ base_path.pop if base_path.size > 1
+ else
+ # if x == '..'
+ # valid absolute (but abnormal) path "/../..."
+ # else
+ # valid absolute path
+ # end
+ base_path << x
+ tmp.each {|t| base_path << t}
+ add_trailer_slash = false
+ break
+ end
+ end
+ base_path.push('') if add_trailer_slash
+
+ return base_path.join('/')
+ end
+ private :merge_path
+
+ #
+ # == Args
+ #
+ # +oth+::
+ # Bundler::URI or String
+ #
+ # == Description
+ #
+ # Destructive form of #merge.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com")
+ # uri.merge!("/main.rbx?page=1")
+ # uri.to_s # => "http://my.example.com/main.rbx?page=1"
+ #
+ def merge!(oth)
+ t = merge(oth)
+ if self == t
+ nil
+ else
+ replace!(t)
+ self
+ end
+ end
+
+ #
+ # == Args
+ #
+ # +oth+::
+ # Bundler::URI or String
+ #
+ # == Description
+ #
+ # Merges two URIs.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com")
+ # uri.merge("/main.rbx?page=1")
+ # # => "http://my.example.com/main.rbx?page=1"
+ #
+ def merge(oth)
+ rel = parser.send(:convert_to_uri, oth)
+
+ if rel.absolute?
+ #raise BadURIError, "both Bundler::URI are absolute" if absolute?
+ # hmm... should return oth for usability?
+ return rel
+ end
+
+ unless self.absolute?
+ raise BadURIError, "both Bundler::URI are relative"
+ end
+
+ base = self.dup
+
+ authority = rel.userinfo || rel.host || rel.port
+
+ # RFC2396, Section 5.2, 2)
+ if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query
+ base.fragment=(rel.fragment) if rel.fragment
+ return base
+ end
+
+ base.query = nil
+ base.fragment=(nil)
+
+ # RFC2396, Section 5.2, 4)
+ if !authority
+ base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
+ else
+ # RFC2396, Section 5.2, 4)
+ base.set_path(rel.path) if rel.path
+ end
+
+ # RFC2396, Section 5.2, 7)
+ base.set_userinfo(rel.userinfo) if rel.userinfo
+ base.set_host(rel.host) if rel.host
+ base.set_port(rel.port) if rel.port
+ base.query = rel.query if rel.query
+ base.fragment=(rel.fragment) if rel.fragment
+
+ return base
+ end # merge
+ alias + merge
+
+ # :stopdoc:
+ def route_from_path(src, dst)
+ case dst
+ when src
+ # RFC2396, Section 4.2
+ return ''
+ when %r{(?:\A|/)\.\.?(?:/|\z)}
+ # dst has abnormal absolute path,
+ # like "/./", "/../", "/x/../", ...
+ return dst.dup
+ end
+
+ src_path = src.scan(%r{[^/]*/})
+ dst_path = dst.scan(%r{[^/]*/?})
+
+ # discard same parts
+ while !dst_path.empty? && dst_path.first == src_path.first
+ src_path.shift
+ dst_path.shift
+ end
+
+ tmp = dst_path.join
+
+ # calculate
+ if src_path.empty?
+ if tmp.empty?
+ return './'
+ elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
+ return './' + tmp
+ else
+ return tmp
+ end
+ end
+
+ return '../' * src_path.size + tmp
+ end
+ private :route_from_path
+ # :startdoc:
+
+ # :stopdoc:
+ def route_from0(oth)
+ oth = parser.send(:convert_to_uri, oth)
+ if self.relative?
+ raise BadURIError,
+ "relative Bundler::URI: #{self}"
+ end
+ if oth.relative?
+ raise BadURIError,
+ "relative Bundler::URI: #{oth}"
+ end
+
+ if self.scheme != oth.scheme
+ return self, self.dup
+ end
+ rel = Bundler::URI::Generic.new(nil, # it is relative Bundler::URI
+ self.userinfo, self.host, self.port,
+ nil, self.path, self.opaque,
+ self.query, self.fragment, parser)
+
+ if rel.userinfo != oth.userinfo ||
+ rel.host.to_s.downcase != oth.host.to_s.downcase ||
+ rel.port != oth.port
+
+ if self.userinfo.nil? && self.host.nil?
+ return self, self.dup
+ end
+
+ rel.set_port(nil) if rel.port == oth.default_port
+ return rel, rel
+ end
+ rel.set_userinfo(nil)
+ rel.set_host(nil)
+ rel.set_port(nil)
+
+ if rel.path && rel.path == oth.path
+ rel.set_path('')
+ rel.query = nil if rel.query == oth.query
+ return rel, rel
+ elsif rel.opaque && rel.opaque == oth.opaque
+ rel.set_opaque('')
+ rel.query = nil if rel.query == oth.query
+ return rel, rel
+ end
+
+ # you can modify `rel', but can not `oth'.
+ return oth, rel
+ end
+ private :route_from0
+ # :startdoc:
+
+ #
+ # == Args
+ #
+ # +oth+::
+ # Bundler::URI or String
+ #
+ # == Description
+ #
+ # Calculates relative path from oth to self.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse('http://my.example.com/main.rbx?page=1')
+ # uri.route_from('http://my.example.com')
+ # #=> #<Bundler::URI::Generic /main.rbx?page=1>
+ #
+ def route_from(oth)
+ # you can modify `rel', but can not `oth'.
+ begin
+ oth, rel = route_from0(oth)
+ rescue
+ raise $!.class, $!.message
+ end
+ if oth == rel
+ return rel
+ end
+
+ rel.set_path(route_from_path(oth.path, self.path))
+ if rel.path == './' && self.query
+ # "./?foo" -> "?foo"
+ rel.set_path('')
+ end
+
+ return rel
+ end
+
+ alias - route_from
+
+ #
+ # == Args
+ #
+ # +oth+::
+ # Bundler::URI or String
+ #
+ # == Description
+ #
+ # Calculates relative path to oth from self.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse('http://my.example.com')
+ # uri.route_to('http://my.example.com/main.rbx?page=1')
+ # #=> #<Bundler::URI::Generic /main.rbx?page=1>
+ #
+ def route_to(oth)
+ parser.send(:convert_to_uri, oth).route_from(self)
+ end
+
+ #
+ # Returns normalized Bundler::URI.
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # Bundler::URI("HTTP://my.EXAMPLE.com").normalize
+ # #=> #<Bundler::URI::HTTP http://my.example.com/>
+ #
+ # Normalization here means:
+ #
+ # * scheme and host are converted to lowercase,
+ # * an empty path component is set to "/".
+ #
+ def normalize
+ uri = dup
+ uri.normalize!
+ uri
+ end
+
+ #
+ # Destructive version of #normalize.
+ #
+ def normalize!
+ if path&.empty?
+ set_path('/')
+ end
+ if scheme && scheme != scheme.downcase
+ set_scheme(self.scheme.downcase)
+ end
+ if host && host != host.downcase
+ set_host(self.host.downcase)
+ end
+ end
+
+ #
+ # Constructs String from Bundler::URI.
+ #
+ def to_s
+ str = ''.dup
+ if @scheme
+ str << @scheme
+ str << ':'
+ end
+
+ if @opaque
+ str << @opaque
+ else
+ if @host || %w[file postgres].include?(@scheme)
+ str << '//'
+ end
+ if self.userinfo
+ str << self.userinfo
+ str << '@'
+ end
+ if @host
+ str << @host
+ end
+ if @port && @port != self.default_port
+ str << ':'
+ str << @port.to_s
+ end
+ str << @path
+ if @query
+ str << '?'
+ str << @query
+ end
+ end
+ if @fragment
+ str << '#'
+ str << @fragment
+ end
+ str
+ end
+
+ #
+ # Compares two URIs.
+ #
+ def ==(oth)
+ if self.class == oth.class
+ self.normalize.component_ary == oth.normalize.component_ary
+ else
+ false
+ end
+ end
+
+ def hash
+ self.component_ary.hash
+ end
+
+ def eql?(oth)
+ self.class == oth.class &&
+ parser == oth.parser &&
+ self.component_ary.eql?(oth.component_ary)
+ end
+
+=begin
+
+--- Bundler::URI::Generic#===(oth)
+
+=end
+# def ===(oth)
+# raise NotImplementedError
+# end
+
+=begin
+=end
+
+
+ # Returns an Array of the components defined from the COMPONENT Array.
+ def component_ary
+ component.collect do |x|
+ self.send(x)
+ end
+ end
+ protected :component_ary
+
+ # == Args
+ #
+ # +components+::
+ # Multiple Symbol arguments defined in Bundler::URI::HTTP.
+ #
+ # == Description
+ #
+ # Selects specified components from Bundler::URI.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse('http://myuser:mypass@my.example.com/test.rbx')
+ # uri.select(:userinfo, :host, :path)
+ # # => ["myuser:mypass", "my.example.com", "/test.rbx"]
+ #
+ def select(*components)
+ components.collect do |c|
+ if component.include?(c)
+ self.send(c)
+ else
+ raise ArgumentError,
+ "expected of components of #{self.class} (#{self.class.component.join(', ')})"
+ end
+ end
+ end
+
+ def inspect
+ "#<#{self.class} #{self}>"
+ end
+
+ #
+ # == Args
+ #
+ # +v+::
+ # Bundler::URI or String
+ #
+ # == Description
+ #
+ # Attempts to parse other Bundler::URI +oth+,
+ # returns [parsed_oth, self].
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://my.example.com")
+ # uri.coerce("http://foo.com")
+ # #=> [#<Bundler::URI::HTTP http://foo.com>, #<Bundler::URI::HTTP http://my.example.com>]
+ #
+ def coerce(oth)
+ case oth
+ when String
+ oth = parser.parse(oth)
+ else
+ super
+ end
+
+ return oth, self
+ end
+
+ # Returns a proxy Bundler::URI.
+ # The proxy Bundler::URI is obtained from environment variables such as http_proxy,
+ # ftp_proxy, no_proxy, etc.
+ # If there is no proper proxy, nil is returned.
+ #
+ # If the optional parameter +env+ is specified, it is used instead of ENV.
+ #
+ # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
+ # are examined, too.
+ #
+ # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
+ # It's because HTTP_PROXY may be set by Proxy: header.
+ # So HTTP_PROXY is not used.
+ # http_proxy is not used too if the variable is case insensitive.
+ # CGI_HTTP_PROXY can be used instead.
+ def find_proxy(env=ENV)
+ raise BadURIError, "relative Bundler::URI: #{self}" if self.relative?
+ name = self.scheme.downcase + '_proxy'
+ proxy_uri = nil
+ if name == 'http_proxy' && env.include?('REQUEST_METHOD') # CGI?
+ # HTTP_PROXY conflicts with *_proxy for proxy settings and
+ # HTTP_* for header information in CGI.
+ # So it should be careful to use it.
+ pairs = env.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
+ case pairs.length
+ when 0 # no proxy setting anyway.
+ proxy_uri = nil
+ when 1
+ k, _ = pairs.shift
+ if k == 'http_proxy' && env[k.upcase] == nil
+ # http_proxy is safe to use because ENV is case sensitive.
+ proxy_uri = env[name]
+ else
+ proxy_uri = nil
+ end
+ else # http_proxy is safe to use because ENV is case sensitive.
+ proxy_uri = env.to_hash[name]
+ end
+ if !proxy_uri
+ # Use CGI_HTTP_PROXY. cf. libwww-perl.
+ proxy_uri = env["CGI_#{name.upcase}"]
+ end
+ elsif name == 'http_proxy'
+ unless proxy_uri = env[name]
+ if proxy_uri = env[name.upcase]
+ warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.', uplevel: 1
+ end
+ end
+ else
+ proxy_uri = env[name] || env[name.upcase]
+ end
+
+ if proxy_uri.nil? || proxy_uri.empty?
+ return nil
+ end
+
+ if self.hostname
+ begin
+ addr = IPSocket.getaddress(self.hostname)
+ return nil if /\A127\.|\A::1\z/ =~ addr
+ rescue SocketError
+ end
+ end
+
+ name = 'no_proxy'
+ if no_proxy = env[name] || env[name.upcase]
+ return nil unless Bundler::URI::Generic.use_proxy?(self.hostname, addr, self.port, no_proxy)
+ end
+ Bundler::URI.parse(proxy_uri)
+ end
+
+ def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc:
+ hostname = hostname.downcase
+ dothostname = ".#{hostname}"
+ no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) {|p_host, p_port|
+ if !p_port || port == p_port.to_i
+ if p_host.start_with?('.')
+ return false if hostname.end_with?(p_host.downcase)
+ else
+ return false if dothostname.end_with?(".#{p_host.downcase}")
+ end
+ if addr
+ begin
+ return false if IPAddr.new(p_host).include?(addr)
+ rescue IPAddr::InvalidAddressError
+ next
+ end
+ end
+ end
+ }
+ true
+ end
+ end
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/http.rb b/lib/bundler/vendor/uri/lib/uri/http.rb
new file mode 100644
index 0000000000..b6ca1c51de
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/http.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: false
+# = uri/http.rb
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+# Revision:: $Id$
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative 'generic'
+
+module Bundler::URI
+
+ #
+ # The syntax of HTTP URIs is defined in RFC1738 section 3.3.
+ #
+ # Note that the Ruby Bundler::URI library allows HTTP URLs containing usernames and
+ # passwords. This is not legal as per the RFC, but used to be
+ # supported in Internet Explorer 5 and 6, before the MS04-004 security
+ # update. See <URL:http://support.microsoft.com/kb/834489>.
+ #
+ class HTTP < Generic
+ # A Default port of 80 for Bundler::URI::HTTP.
+ DEFAULT_PORT = 80
+
+ # An Array of the available components for Bundler::URI::HTTP.
+ COMPONENT = %i[
+ scheme
+ userinfo host port
+ path
+ query
+ fragment
+ ].freeze
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::HTTP object from components, with syntax checking.
+ #
+ # The components accepted are userinfo, host, port, path, query, and
+ # fragment.
+ #
+ # The components should be provided either as an Array, or as a Hash
+ # with keys formed by preceding the component names with a colon.
+ #
+ # If an Array is used, the components must be passed in the
+ # order <code>[userinfo, host, port, path, query, fragment]</code>.
+ #
+ # Example:
+ #
+ # uri = Bundler::URI::HTTP.build(host: 'www.example.com', path: '/foo/bar')
+ #
+ # uri = Bundler::URI::HTTP.build([nil, "www.example.com", nil, "/path",
+ # "query", 'fragment'])
+ #
+ # Currently, if passed userinfo components this method generates
+ # invalid HTTP URIs as per RFC 1738.
+ #
+ def self.build(args)
+ tmp = Util.make_components_hash(self, args)
+ super(tmp)
+ end
+
+ #
+ # == Description
+ #
+ # Returns the full path for an HTTP request, as required by Net::HTTP::Get.
+ #
+ # If the Bundler::URI contains a query, the full path is Bundler::URI#path + '?' + Bundler::URI#query.
+ # Otherwise, the path is simply Bundler::URI#path.
+ #
+ # Example:
+ #
+ # uri = Bundler::URI::HTTP.build(path: '/foo/bar', query: 'test=true')
+ # uri.request_uri # => "/foo/bar?test=true"
+ #
+ def request_uri
+ return unless @path
+
+ url = @query ? "#@path?#@query" : @path.dup
+ url.start_with?(?/.freeze) ? url : ?/ + url
+ end
+ end
+
+ @@schemes['HTTP'] = HTTP
+
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/https.rb b/lib/bundler/vendor/uri/lib/uri/https.rb
new file mode 100644
index 0000000000..78dc6bf532
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/https.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: false
+# = uri/https.rb
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+# Revision:: $Id$
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative 'http'
+
+module Bundler::URI
+
+ # The default port for HTTPS URIs is 443, and the scheme is 'https:' rather
+ # than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs;
+ # see Bundler::URI::HTTP.
+ class HTTPS < HTTP
+ # A Default port of 443 for Bundler::URI::HTTPS
+ DEFAULT_PORT = 443
+ end
+ @@schemes['HTTPS'] = HTTPS
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/ldap.rb b/lib/bundler/vendor/uri/lib/uri/ldap.rb
new file mode 100644
index 0000000000..b707bedb97
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/ldap.rb
@@ -0,0 +1,261 @@
+# frozen_string_literal: false
+# = uri/ldap.rb
+#
+# Author::
+# Takaaki Tateishi <ttate@jaist.ac.jp>
+# Akira Yamada <akira@ruby-lang.org>
+# License::
+# Bundler::URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada.
+# You can redistribute it and/or modify it under the same term as Ruby.
+# Revision:: $Id$
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative 'generic'
+
+module Bundler::URI
+
+ #
+ # LDAP Bundler::URI SCHEMA (described in RFC2255).
+ #--
+ # ldap://<host>/<dn>[?<attrs>[?<scope>[?<filter>[?<extensions>]]]]
+ #++
+ class LDAP < Generic
+
+ # A Default port of 389 for Bundler::URI::LDAP.
+ DEFAULT_PORT = 389
+
+ # An Array of the available components for Bundler::URI::LDAP.
+ COMPONENT = [
+ :scheme,
+ :host, :port,
+ :dn,
+ :attributes,
+ :scope,
+ :filter,
+ :extensions,
+ ].freeze
+
+ # Scopes available for the starting point.
+ #
+ # * SCOPE_BASE - the Base DN
+ # * SCOPE_ONE - one level under the Base DN, not including the base DN and
+ # not including any entries under this
+ # * SCOPE_SUB - subtrees, all entries at all levels
+ #
+ SCOPE = [
+ SCOPE_ONE = 'one',
+ SCOPE_SUB = 'sub',
+ SCOPE_BASE = 'base',
+ ].freeze
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::LDAP object from components, with syntax checking.
+ #
+ # The components accepted are host, port, dn, attributes,
+ # scope, filter, and extensions.
+ #
+ # The components should be provided either as an Array, or as a Hash
+ # with keys formed by preceding the component names with a colon.
+ #
+ # If an Array is used, the components must be passed in the
+ # order <code>[host, port, dn, attributes, scope, filter, extensions]</code>.
+ #
+ # Example:
+ #
+ # uri = Bundler::URI::LDAP.build({:host => 'ldap.example.com',
+ # :dn => '/dc=example'})
+ #
+ # uri = Bundler::URI::LDAP.build(["ldap.example.com", nil,
+ # "/dc=example;dc=com", "query", nil, nil, nil])
+ #
+ def self.build(args)
+ tmp = Util::make_components_hash(self, args)
+
+ if tmp[:dn]
+ tmp[:path] = tmp[:dn]
+ end
+
+ query = []
+ [:extensions, :filter, :scope, :attributes].collect do |x|
+ next if !tmp[x] && query.size == 0
+ query.unshift(tmp[x])
+ end
+
+ tmp[:query] = query.join('?')
+
+ return super(tmp)
+ end
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::LDAP object from generic Bundler::URI components as per
+ # RFC 2396. No LDAP-specific syntax checking is performed.
+ #
+ # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
+ # +opaque+, +query+, and +fragment+, in that order.
+ #
+ # Example:
+ #
+ # uri = Bundler::URI::LDAP.new("ldap", nil, "ldap.example.com", nil, nil,
+ # "/dc=example;dc=com", nil, "query", nil)
+ #
+ # See also Bundler::URI::Generic.new.
+ #
+ def initialize(*arg)
+ super(*arg)
+
+ if @fragment
+ raise InvalidURIError, 'bad LDAP URL'
+ end
+
+ parse_dn
+ parse_query
+ end
+
+ # Private method to cleanup +dn+ from using the +path+ component attribute.
+ def parse_dn
+ @dn = @path[1..-1]
+ end
+ private :parse_dn
+
+ # Private method to cleanup +attributes+, +scope+, +filter+, and +extensions+
+ # from using the +query+ component attribute.
+ def parse_query
+ @attributes = nil
+ @scope = nil
+ @filter = nil
+ @extensions = nil
+
+ if @query
+ attrs, scope, filter, extensions = @query.split('?')
+
+ @attributes = attrs if attrs && attrs.size > 0
+ @scope = scope if scope && scope.size > 0
+ @filter = filter if filter && filter.size > 0
+ @extensions = extensions if extensions && extensions.size > 0
+ end
+ end
+ private :parse_query
+
+ # Private method to assemble +query+ from +attributes+, +scope+, +filter+, and +extensions+.
+ def build_path_query
+ @path = '/' + @dn
+
+ query = []
+ [@extensions, @filter, @scope, @attributes].each do |x|
+ next if !x && query.size == 0
+ query.unshift(x)
+ end
+ @query = query.join('?')
+ end
+ private :build_path_query
+
+ # Returns dn.
+ def dn
+ @dn
+ end
+
+ # Private setter for dn +val+.
+ def set_dn(val)
+ @dn = val
+ build_path_query
+ @dn
+ end
+ protected :set_dn
+
+ # Setter for dn +val+.
+ def dn=(val)
+ set_dn(val)
+ val
+ end
+
+ # Returns attributes.
+ def attributes
+ @attributes
+ end
+
+ # Private setter for attributes +val+.
+ def set_attributes(val)
+ @attributes = val
+ build_path_query
+ @attributes
+ end
+ protected :set_attributes
+
+ # Setter for attributes +val+.
+ def attributes=(val)
+ set_attributes(val)
+ val
+ end
+
+ # Returns scope.
+ def scope
+ @scope
+ end
+
+ # Private setter for scope +val+.
+ def set_scope(val)
+ @scope = val
+ build_path_query
+ @scope
+ end
+ protected :set_scope
+
+ # Setter for scope +val+.
+ def scope=(val)
+ set_scope(val)
+ val
+ end
+
+ # Returns filter.
+ def filter
+ @filter
+ end
+
+ # Private setter for filter +val+.
+ def set_filter(val)
+ @filter = val
+ build_path_query
+ @filter
+ end
+ protected :set_filter
+
+ # Setter for filter +val+.
+ def filter=(val)
+ set_filter(val)
+ val
+ end
+
+ # Returns extensions.
+ def extensions
+ @extensions
+ end
+
+ # Private setter for extensions +val+.
+ def set_extensions(val)
+ @extensions = val
+ build_path_query
+ @extensions
+ end
+ protected :set_extensions
+
+ # Setter for extensions +val+.
+ def extensions=(val)
+ set_extensions(val)
+ val
+ end
+
+ # Checks if Bundler::URI has a path.
+ # For Bundler::URI::LDAP this will return +false+.
+ def hierarchical?
+ false
+ end
+ end
+
+ @@schemes['LDAP'] = LDAP
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/ldaps.rb b/lib/bundler/vendor/uri/lib/uri/ldaps.rb
new file mode 100644
index 0000000000..0af35bb16b
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/ldaps.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: false
+# = uri/ldap.rb
+#
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative 'ldap'
+
+module Bundler::URI
+
+ # The default port for LDAPS URIs is 636, and the scheme is 'ldaps:' rather
+ # than 'ldap:'. Other than that, LDAPS URIs are identical to LDAP URIs;
+ # see Bundler::URI::LDAP.
+ class LDAPS < LDAP
+ # A Default port of 636 for Bundler::URI::LDAPS
+ DEFAULT_PORT = 636
+ end
+ @@schemes['LDAPS'] = LDAPS
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/mailto.rb b/lib/bundler/vendor/uri/lib/uri/mailto.rb
new file mode 100644
index 0000000000..5b2a4765c8
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/mailto.rb
@@ -0,0 +1,294 @@
+# frozen_string_literal: false
+# = uri/mailto.rb
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+# Revision:: $Id$
+#
+# See Bundler::URI for general documentation
+#
+
+require_relative 'generic'
+
+module Bundler::URI
+
+ #
+ # RFC6068, the mailto URL scheme.
+ #
+ class MailTo < Generic
+ include REGEXP
+
+ # A Default port of nil for Bundler::URI::MailTo.
+ DEFAULT_PORT = nil
+
+ # An Array of the available components for Bundler::URI::MailTo.
+ COMPONENT = [ :scheme, :to, :headers ].freeze
+
+ # :stopdoc:
+ # "hname" and "hvalue" are encodings of an RFC 822 header name and
+ # value, respectively. As with "to", all URL reserved characters must
+ # be encoded.
+ #
+ # "#mailbox" is as specified in RFC 822 [RFC822]. This means that it
+ # consists of zero or more comma-separated mail addresses, possibly
+ # including "phrase" and "comment" components. Note that all URL
+ # reserved characters in "to" must be encoded: in particular,
+ # parentheses, commas, and the percent sign ("%"), which commonly occur
+ # in the "mailbox" syntax.
+ #
+ # Within mailto URLs, the characters "?", "=", "&" are reserved.
+
+ # ; RFC 6068
+ # hfields = "?" hfield *( "&" hfield )
+ # hfield = hfname "=" hfvalue
+ # hfname = *qchar
+ # hfvalue = *qchar
+ # qchar = unreserved / pct-encoded / some-delims
+ # some-delims = "!" / "$" / "'" / "(" / ")" / "*"
+ # / "+" / "," / ";" / ":" / "@"
+ #
+ # ; RFC3986
+ # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ # pct-encoded = "%" HEXDIG HEXDIG
+ HEADER_REGEXP = /\A(?<hfield>(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g<hfield>)*\z/
+ # practical regexp for email address
+ # https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
+ EMAIL_REGEXP = /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
+ # :startdoc:
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::MailTo object from components, with syntax checking.
+ #
+ # Components can be provided as an Array or Hash. If an Array is used,
+ # the components must be supplied as <code>[to, headers]</code>.
+ #
+ # If a Hash is used, the keys are the component names preceded by colons.
+ #
+ # The headers can be supplied as a pre-encoded string, such as
+ # <code>"subject=subscribe&cc=address"</code>, or as an Array of Arrays
+ # like <code>[['subject', 'subscribe'], ['cc', 'address']]</code>.
+ #
+ # Examples:
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # m1 = Bundler::URI::MailTo.build(['joe@example.com', 'subject=Ruby'])
+ # m1.to_s # => "mailto:joe@example.com?subject=Ruby"
+ #
+ # m2 = Bundler::URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]])
+ # m2.to_s # => "mailto:john@example.com?Subject=Ruby&Cc=jack@example.com"
+ #
+ # m3 = Bundler::URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]})
+ # m3.to_s # => "mailto:listman@example.com?subject=subscribe"
+ #
+ def self.build(args)
+ tmp = Util.make_components_hash(self, args)
+
+ case tmp[:to]
+ when Array
+ tmp[:opaque] = tmp[:to].join(',')
+ when String
+ tmp[:opaque] = tmp[:to].dup
+ else
+ tmp[:opaque] = ''
+ end
+
+ if tmp[:headers]
+ query =
+ case tmp[:headers]
+ when Array
+ tmp[:headers].collect { |x|
+ if x.kind_of?(Array)
+ x[0] + '=' + x[1..-1].join
+ else
+ x.to_s
+ end
+ }.join('&')
+ when Hash
+ tmp[:headers].collect { |h,v|
+ h + '=' + v
+ }.join('&')
+ else
+ tmp[:headers].to_s
+ end
+ unless query.empty?
+ tmp[:opaque] << '?' << query
+ end
+ end
+
+ super(tmp)
+ end
+
+ #
+ # == Description
+ #
+ # Creates a new Bundler::URI::MailTo object from generic URL components with
+ # no syntax checking.
+ #
+ # This method is usually called from Bundler::URI::parse, which checks
+ # the validity of each component.
+ #
+ def initialize(*arg)
+ super(*arg)
+
+ @to = nil
+ @headers = []
+
+ # The RFC3986 parser does not normally populate opaque
+ @opaque = "?#{@query}" if @query && !@opaque
+
+ unless @opaque
+ raise InvalidComponentError,
+ "missing opaque part for mailto URL"
+ end
+ to, header = @opaque.split('?', 2)
+ # allow semicolon as a addr-spec separator
+ # http://support.microsoft.com/kb/820868
+ unless /\A(?:[^@,;]+@[^@,;]+(?:\z|[,;]))*\z/ =~ to
+ raise InvalidComponentError,
+ "unrecognised opaque part for mailtoURL: #{@opaque}"
+ end
+
+ if arg[10] # arg_check
+ self.to = to
+ self.headers = header
+ else
+ set_to(to)
+ set_headers(header)
+ end
+ end
+
+ # The primary e-mail address of the URL, as a String.
+ attr_reader :to
+
+ # E-mail headers set by the URL, as an Array of Arrays.
+ attr_reader :headers
+
+ # Checks the to +v+ component.
+ def check_to(v)
+ return true unless v
+ return true if v.size == 0
+
+ v.split(/[,;]/).each do |addr|
+ # check url safety as path-rootless
+ if /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*\z/ !~ addr
+ raise InvalidComponentError,
+ "an address in 'to' is invalid as Bundler::URI #{addr.dump}"
+ end
+
+ # check addr-spec
+ # don't s/\+/ /g
+ addr.gsub!(/%\h\h/, Bundler::URI::TBLDECWWWCOMP_)
+ if EMAIL_REGEXP !~ addr
+ raise InvalidComponentError,
+ "an address in 'to' is invalid as uri-escaped addr-spec #{addr.dump}"
+ end
+ end
+
+ true
+ end
+ private :check_to
+
+ # Private setter for to +v+.
+ def set_to(v)
+ @to = v
+ end
+ protected :set_to
+
+ # Setter for to +v+.
+ def to=(v)
+ check_to(v)
+ set_to(v)
+ v
+ end
+
+ # Checks the headers +v+ component against either
+ # * HEADER_REGEXP
+ def check_headers(v)
+ return true unless v
+ return true if v.size == 0
+ if HEADER_REGEXP !~ v
+ raise InvalidComponentError,
+ "bad component(expected opaque component): #{v}"
+ end
+
+ true
+ end
+ private :check_headers
+
+ # Private setter for headers +v+.
+ def set_headers(v)
+ @headers = []
+ if v
+ v.split('&').each do |x|
+ @headers << x.split(/=/, 2)
+ end
+ end
+ end
+ protected :set_headers
+
+ # Setter for headers +v+.
+ def headers=(v)
+ check_headers(v)
+ set_headers(v)
+ v
+ end
+
+ # Constructs String from Bundler::URI.
+ def to_s
+ @scheme + ':' +
+ if @to
+ @to
+ else
+ ''
+ end +
+ if @headers.size > 0
+ '?' + @headers.collect{|x| x.join('=')}.join('&')
+ else
+ ''
+ end +
+ if @fragment
+ '#' + @fragment
+ else
+ ''
+ end
+ end
+
+ # Returns the RFC822 e-mail text equivalent of the URL, as a String.
+ #
+ # Example:
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("mailto:ruby-list@ruby-lang.org?Subject=subscribe&cc=myaddr")
+ # uri.to_mailtext
+ # # => "To: ruby-list@ruby-lang.org\nSubject: subscribe\nCc: myaddr\n\n\n"
+ #
+ def to_mailtext
+ to = Bundler::URI.decode_www_form_component(@to)
+ head = ''
+ body = ''
+ @headers.each do |x|
+ case x[0]
+ when 'body'
+ body = Bundler::URI.decode_www_form_component(x[1])
+ when 'to'
+ to << ', ' + Bundler::URI.decode_www_form_component(x[1])
+ else
+ head << Bundler::URI.decode_www_form_component(x[0]).capitalize + ': ' +
+ Bundler::URI.decode_www_form_component(x[1]) + "\n"
+ end
+ end
+
+ "To: #{to}
+#{head}
+#{body}
+"
+ end
+ alias to_rfc822text to_mailtext
+ end
+
+ @@schemes['MAILTO'] = MailTo
+end
diff --git a/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb b/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb
new file mode 100644
index 0000000000..7634e16958
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb
@@ -0,0 +1,546 @@
+# frozen_string_literal: false
+#--
+# = uri/common.rb
+#
+# Author:: Akira Yamada <akira@ruby-lang.org>
+# Revision:: $Id$
+# License::
+# You can redistribute it and/or modify it under the same term as Ruby.
+#
+# See Bundler::URI for general documentation
+#
+
+module Bundler::URI
+ #
+ # Includes Bundler::URI::REGEXP::PATTERN
+ #
+ module RFC2396_REGEXP
+ #
+ # Patterns used to parse Bundler::URI's
+ #
+ module PATTERN
+ # :stopdoc:
+
+ # RFC 2396 (Bundler::URI Generic Syntax)
+ # RFC 2732 (IPv6 Literal Addresses in URL's)
+ # RFC 2373 (IPv6 Addressing Architecture)
+
+ # alpha = lowalpha | upalpha
+ ALPHA = "a-zA-Z"
+ # alphanum = alpha | digit
+ ALNUM = "#{ALPHA}\\d"
+
+ # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
+ # "a" | "b" | "c" | "d" | "e" | "f"
+ HEX = "a-fA-F\\d"
+ # escaped = "%" hex hex
+ ESCAPED = "%[#{HEX}]{2}"
+ # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
+ # "(" | ")"
+ # unreserved = alphanum | mark
+ UNRESERVED = "\\-_.!~*'()#{ALNUM}"
+ # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+ # "$" | ","
+ # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+ # "$" | "," | "[" | "]" (RFC 2732)
+ RESERVED = ";/?:@&=+$,\\[\\]"
+
+ # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
+ DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
+ # toplabel = alpha | alpha *( alphanum | "-" ) alphanum
+ TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
+ # hostname = *( domainlabel "." ) toplabel [ "." ]
+ HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?"
+
+ # :startdoc:
+ end # PATTERN
+
+ # :startdoc:
+ end # REGEXP
+
+ # Class that parses String's into Bundler::URI's.
+ #
+ # It contains a Hash set of patterns and Regexp's that match and validate.
+ #
+ class RFC2396_Parser
+ include RFC2396_REGEXP
+
+ #
+ # == Synopsis
+ #
+ # Bundler::URI::Parser.new([opts])
+ #
+ # == Args
+ #
+ # The constructor accepts a hash as options for parser.
+ # Keys of options are pattern names of Bundler::URI components
+ # and values of options are pattern strings.
+ # The constructor generates set of regexps for parsing URIs.
+ #
+ # You can use the following keys:
+ #
+ # * :ESCAPED (Bundler::URI::PATTERN::ESCAPED in default)
+ # * :UNRESERVED (Bundler::URI::PATTERN::UNRESERVED in default)
+ # * :DOMLABEL (Bundler::URI::PATTERN::DOMLABEL in default)
+ # * :TOPLABEL (Bundler::URI::PATTERN::TOPLABEL in default)
+ # * :HOSTNAME (Bundler::URI::PATTERN::HOSTNAME in default)
+ #
+ # == Examples
+ #
+ # p = Bundler::URI::Parser.new(:ESCAPED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})")
+ # u = p.parse("http://example.jp/%uABCD") #=> #<Bundler::URI::HTTP http://example.jp/%uABCD>
+ # Bundler::URI.parse(u.to_s) #=> raises Bundler::URI::InvalidURIError
+ #
+ # s = "http://example.com/ABCD"
+ # u1 = p.parse(s) #=> #<Bundler::URI::HTTP http://example.com/ABCD>
+ # u2 = Bundler::URI.parse(s) #=> #<Bundler::URI::HTTP http://example.com/ABCD>
+ # u1 == u2 #=> true
+ # u1.eql?(u2) #=> false
+ #
+ def initialize(opts = {})
+ @pattern = initialize_pattern(opts)
+ @pattern.each_value(&:freeze)
+ @pattern.freeze
+
+ @regexp = initialize_regexp(@pattern)
+ @regexp.each_value(&:freeze)
+ @regexp.freeze
+ end
+
+ # The Hash of patterns.
+ #
+ # See also Bundler::URI::Parser.initialize_pattern.
+ attr_reader :pattern
+
+ # The Hash of Regexp.
+ #
+ # See also Bundler::URI::Parser.initialize_regexp.
+ attr_reader :regexp
+
+ # Returns a split Bundler::URI against regexp[:ABS_URI].
+ def split(uri)
+ case uri
+ when ''
+ # null uri
+
+ when @regexp[:ABS_URI]
+ scheme, opaque, userinfo, host, port,
+ registry, path, query, fragment = $~[1..-1]
+
+ # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
+ # opaque_part = uric_no_slash *uric
+
+ # abs_path = "/" path_segments
+ # net_path = "//" authority [ abs_path ]
+
+ # authority = server | reg_name
+ # server = [ [ userinfo "@" ] hostport ]
+
+ if !scheme
+ raise InvalidURIError,
+ "bad Bundler::URI(absolute but no scheme): #{uri}"
+ end
+ if !opaque && (!path && (!host && !registry))
+ raise InvalidURIError,
+ "bad Bundler::URI(absolute but no path): #{uri}"
+ end
+
+ when @regexp[:REL_URI]
+ scheme = nil
+ opaque = nil
+
+ userinfo, host, port, registry,
+ rel_segment, abs_path, query, fragment = $~[1..-1]
+ if rel_segment && abs_path
+ path = rel_segment + abs_path
+ elsif rel_segment
+ path = rel_segment
+ elsif abs_path
+ path = abs_path
+ end
+
+ # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+
+ # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
+
+ # net_path = "//" authority [ abs_path ]
+ # abs_path = "/" path_segments
+ # rel_path = rel_segment [ abs_path ]
+
+ # authority = server | reg_name
+ # server = [ [ userinfo "@" ] hostport ]
+
+ else
+ raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri}"
+ end
+
+ path = '' if !path && !opaque # (see RFC2396 Section 5.2)
+ ret = [
+ scheme,
+ userinfo, host, port, # X
+ registry, # X
+ path, # Y
+ opaque, # Y
+ query,
+ fragment
+ ]
+ return ret
+ end
+
+ #
+ # == Args
+ #
+ # +uri+::
+ # String
+ #
+ # == Description
+ #
+ # Parses +uri+ and constructs either matching Bundler::URI scheme object
+ # (File, FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or Bundler::URI::Generic.
+ #
+ # == Usage
+ #
+ # p = Bundler::URI::Parser.new
+ # p.parse("ldap://ldap.example.com/dc=example?user=john")
+ # #=> #<Bundler::URI::LDAP ldap://ldap.example.com/dc=example?user=john>
+ #
+ def parse(uri)
+ scheme, userinfo, host, port,
+ registry, path, opaque, query, fragment = self.split(uri)
+
+ if scheme && Bundler::URI.scheme_list.include?(scheme.upcase)
+ Bundler::URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
+ registry, path, opaque, query,
+ fragment, self)
+ else
+ Generic.new(scheme, userinfo, host, port,
+ registry, path, opaque, query,
+ fragment, self)
+ end
+ end
+
+
+ #
+ # == Args
+ #
+ # +uris+::
+ # an Array of Strings
+ #
+ # == Description
+ #
+ # Attempts to parse and merge a set of URIs.
+ #
+ def join(*uris)
+ uris[0] = convert_to_uri(uris[0])
+ uris.inject :merge
+ end
+
+ #
+ # :call-seq:
+ # extract( str )
+ # extract( str, schemes )
+ # extract( str, schemes ) {|item| block }
+ #
+ # == Args
+ #
+ # +str+::
+ # String to search
+ # +schemes+::
+ # Patterns to apply to +str+
+ #
+ # == Description
+ #
+ # Attempts to parse and merge a set of URIs.
+ # If no +block+ given, then returns the result,
+ # else it calls +block+ for each element in result.
+ #
+ # See also Bundler::URI::Parser.make_regexp.
+ #
+ def extract(str, schemes = nil)
+ if block_given?
+ str.scan(make_regexp(schemes)) { yield $& }
+ nil
+ else
+ result = []
+ str.scan(make_regexp(schemes)) { result.push $& }
+ result
+ end
+ end
+
+ # Returns Regexp that is default self.regexp[:ABS_URI_REF],
+ # unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI].
+ def make_regexp(schemes = nil)
+ unless schemes
+ @regexp[:ABS_URI_REF]
+ else
+ /(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
+ end
+ end
+
+ #
+ # :call-seq:
+ # escape( str )
+ # escape( str, unsafe )
+ #
+ # == Args
+ #
+ # +str+::
+ # String to make safe
+ # +unsafe+::
+ # Regexp to apply. Defaults to self.regexp[:UNSAFE]
+ #
+ # == Description
+ #
+ # Constructs a safe String from +str+, removing unsafe characters,
+ # replacing them with codes.
+ #
+ def escape(str, unsafe = @regexp[:UNSAFE])
+ unless unsafe.kind_of?(Regexp)
+ # perhaps unsafe is String object
+ unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false)
+ end
+ str.gsub(unsafe) do
+ us = $&
+ tmp = ''
+ us.each_byte do |uc|
+ tmp << sprintf('%%%02X', uc)
+ end
+ tmp
+ end.force_encoding(Encoding::US_ASCII)
+ end
+
+ #
+ # :call-seq:
+ # unescape( str )
+ # unescape( str, escaped )
+ #
+ # == Args
+ #
+ # +str+::
+ # String to remove escapes from
+ # +escaped+::
+ # Regexp to apply. Defaults to self.regexp[:ESCAPED]
+ #
+ # == Description
+ #
+ # Removes escapes from +str+.
+ #
+ def unescape(str, escaped = @regexp[:ESCAPED])
+ enc = str.encoding
+ enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
+ str.gsub(escaped) { [$&[1, 2]].pack('H2').force_encoding(enc) }
+ end
+
+ @@to_s = Kernel.instance_method(:to_s)
+ def inspect
+ @@to_s.bind_call(self)
+ end
+
+ private
+
+ # Constructs the default Hash of patterns.
+ def initialize_pattern(opts = {})
+ ret = {}
+ ret[:ESCAPED] = escaped = (opts.delete(:ESCAPED) || PATTERN::ESCAPED)
+ ret[:UNRESERVED] = unreserved = opts.delete(:UNRESERVED) || PATTERN::UNRESERVED
+ ret[:RESERVED] = reserved = opts.delete(:RESERVED) || PATTERN::RESERVED
+ ret[:DOMLABEL] = opts.delete(:DOMLABEL) || PATTERN::DOMLABEL
+ ret[:TOPLABEL] = opts.delete(:TOPLABEL) || PATTERN::TOPLABEL
+ ret[:HOSTNAME] = hostname = opts.delete(:HOSTNAME)
+
+ # RFC 2396 (Bundler::URI Generic Syntax)
+ # RFC 2732 (IPv6 Literal Addresses in URL's)
+ # RFC 2373 (IPv6 Addressing Architecture)
+
+ # uric = reserved | unreserved | escaped
+ ret[:URIC] = uric = "(?:[#{unreserved}#{reserved}]|#{escaped})"
+ # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
+ # "&" | "=" | "+" | "$" | ","
+ ret[:URIC_NO_SLASH] = uric_no_slash = "(?:[#{unreserved};?:@&=+$,]|#{escaped})"
+ # query = *uric
+ ret[:QUERY] = query = "#{uric}*"
+ # fragment = *uric
+ ret[:FRAGMENT] = fragment = "#{uric}*"
+
+ # hostname = *( domainlabel "." ) toplabel [ "." ]
+ # reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986
+ unless hostname
+ ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
+ end
+
+ # RFC 2373, APPENDIX B:
+ # IPv6address = hexpart [ ":" IPv4address ]
+ # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
+ # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
+ # hexseq = hex4 *( ":" hex4)
+ # hex4 = 1*4HEXDIG
+ #
+ # XXX: This definition has a flaw. "::" + IPv4address must be
+ # allowed too. Here is a replacement.
+ #
+ # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
+ ret[:IPV4ADDR] = ipv4addr = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
+ # hex4 = 1*4HEXDIG
+ hex4 = "[#{PATTERN::HEX}]{1,4}"
+ # lastpart = hex4 | IPv4address
+ lastpart = "(?:#{hex4}|#{ipv4addr})"
+ # hexseq1 = *( hex4 ":" ) hex4
+ hexseq1 = "(?:#{hex4}:)*#{hex4}"
+ # hexseq2 = *( hex4 ":" ) lastpart
+ hexseq2 = "(?:#{hex4}:)*#{lastpart}"
+ # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ]
+ ret[:IPV6ADDR] = ipv6addr = "(?:#{hexseq2}|(?:#{hexseq1})?::(?:#{hexseq2})?)"
+
+ # IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT
+ # unused
+
+ # ipv6reference = "[" IPv6address "]" (RFC 2732)
+ ret[:IPV6REF] = ipv6ref = "\\[#{ipv6addr}\\]"
+
+ # host = hostname | IPv4address
+ # host = hostname | IPv4address | IPv6reference (RFC 2732)
+ ret[:HOST] = host = "(?:#{hostname}|#{ipv4addr}|#{ipv6ref})"
+ # port = *digit
+ ret[:PORT] = port = '\d*'
+ # hostport = host [ ":" port ]
+ ret[:HOSTPORT] = hostport = "#{host}(?::#{port})?"
+
+ # userinfo = *( unreserved | escaped |
+ # ";" | ":" | "&" | "=" | "+" | "$" | "," )
+ ret[:USERINFO] = userinfo = "(?:[#{unreserved};:&=+$,]|#{escaped})*"
+
+ # pchar = unreserved | escaped |
+ # ":" | "@" | "&" | "=" | "+" | "$" | ","
+ pchar = "(?:[#{unreserved}:@&=+$,]|#{escaped})"
+ # param = *pchar
+ param = "#{pchar}*"
+ # segment = *pchar *( ";" param )
+ segment = "#{pchar}*(?:;#{param})*"
+ # path_segments = segment *( "/" segment )
+ ret[:PATH_SEGMENTS] = path_segments = "#{segment}(?:/#{segment})*"
+
+ # server = [ [ userinfo "@" ] hostport ]
+ server = "(?:#{userinfo}@)?#{hostport}"
+ # reg_name = 1*( unreserved | escaped | "$" | "," |
+ # ";" | ":" | "@" | "&" | "=" | "+" )
+ ret[:REG_NAME] = reg_name = "(?:[#{unreserved}$,;:@&=+]|#{escaped})+"
+ # authority = server | reg_name
+ authority = "(?:#{server}|#{reg_name})"
+
+ # rel_segment = 1*( unreserved | escaped |
+ # ";" | "@" | "&" | "=" | "+" | "$" | "," )
+ ret[:REL_SEGMENT] = rel_segment = "(?:[#{unreserved};@&=+$,]|#{escaped})+"
+
+ # scheme = alpha *( alpha | digit | "+" | "-" | "." )
+ ret[:SCHEME] = scheme = "[#{PATTERN::ALPHA}][\\-+.#{PATTERN::ALPHA}\\d]*"
+
+ # abs_path = "/" path_segments
+ ret[:ABS_PATH] = abs_path = "/#{path_segments}"
+ # rel_path = rel_segment [ abs_path ]
+ ret[:REL_PATH] = rel_path = "#{rel_segment}(?:#{abs_path})?"
+ # net_path = "//" authority [ abs_path ]
+ ret[:NET_PATH] = net_path = "//#{authority}(?:#{abs_path})?"
+
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
+ ret[:HIER_PART] = hier_part = "(?:#{net_path}|#{abs_path})(?:\\?(?:#{query}))?"
+ # opaque_part = uric_no_slash *uric
+ ret[:OPAQUE_PART] = opaque_part = "#{uric_no_slash}#{uric}*"
+
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
+ ret[:ABS_URI] = abs_uri = "#{scheme}:(?:#{hier_part}|#{opaque_part})"
+ # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
+ ret[:REL_URI] = rel_uri = "(?:#{net_path}|#{abs_path}|#{rel_path})(?:\\?#{query})?"
+
+ # Bundler::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+ ret[:URI_REF] = "(?:#{abs_uri}|#{rel_uri})?(?:##{fragment})?"
+
+ ret[:X_ABS_URI] = "
+ (#{scheme}): (?# 1: scheme)
+ (?:
+ (#{opaque_part}) (?# 2: opaque)
+ |
+ (?:(?:
+ //(?:
+ (?:(?:(#{userinfo})@)? (?# 3: userinfo)
+ (?:(#{host})(?::(\\d*))?))? (?# 4: host, 5: port)
+ |
+ (#{reg_name}) (?# 6: registry)
+ )
+ |
+ (?!//)) (?# XXX: '//' is the mark for hostport)
+ (#{abs_path})? (?# 7: path)
+ )(?:\\?(#{query}))? (?# 8: query)
+ )
+ (?:\\#(#{fragment}))? (?# 9: fragment)
+ "
+
+ ret[:X_REL_URI] = "
+ (?:
+ (?:
+ //
+ (?:
+ (?:(#{userinfo})@)? (?# 1: userinfo)
+ (#{host})?(?::(\\d*))? (?# 2: host, 3: port)
+ |
+ (#{reg_name}) (?# 4: registry)
+ )
+ )
+ |
+ (#{rel_segment}) (?# 5: rel_segment)
+ )?
+ (#{abs_path})? (?# 6: abs_path)
+ (?:\\?(#{query}))? (?# 7: query)
+ (?:\\#(#{fragment}))? (?# 8: fragment)
+ "
+
+ ret
+ end
+
+ # Constructs the default Hash of Regexp's.
+ def initialize_regexp(pattern)
+ ret = {}
+
+ # for Bundler::URI::split
+ ret[:ABS_URI] = Regexp.new('\A\s*+' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED)
+ ret[:REL_URI] = Regexp.new('\A\s*+' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED)
+
+ # for Bundler::URI::extract
+ ret[:URI_REF] = Regexp.new(pattern[:URI_REF])
+ ret[:ABS_URI_REF] = Regexp.new(pattern[:X_ABS_URI], Regexp::EXTENDED)
+ ret[:REL_URI_REF] = Regexp.new(pattern[:X_REL_URI], Regexp::EXTENDED)
+
+ # for Bundler::URI::escape/unescape
+ ret[:ESCAPED] = Regexp.new(pattern[:ESCAPED])
+ ret[:UNSAFE] = Regexp.new("[^#{pattern[:UNRESERVED]}#{pattern[:RESERVED]}]")
+
+ # for Generic#initialize
+ ret[:SCHEME] = Regexp.new("\\A#{pattern[:SCHEME]}\\z")
+ ret[:USERINFO] = Regexp.new("\\A#{pattern[:USERINFO]}\\z")
+ ret[:HOST] = Regexp.new("\\A#{pattern[:HOST]}\\z")
+ ret[:PORT] = Regexp.new("\\A#{pattern[:PORT]}\\z")
+ ret[:OPAQUE] = Regexp.new("\\A#{pattern[:OPAQUE_PART]}\\z")
+ ret[:REGISTRY] = Regexp.new("\\A#{pattern[:REG_NAME]}\\z")
+ ret[:ABS_PATH] = Regexp.new("\\A#{pattern[:ABS_PATH]}\\z")
+ ret[:REL_PATH] = Regexp.new("\\A#{pattern[:REL_PATH]}\\z")
+ ret[:QUERY] = Regexp.new("\\A#{pattern[:QUERY]}\\z")
+ ret[:FRAGMENT] = Regexp.new("\\A#{pattern[:FRAGMENT]}\\z")
+
+ ret
+ end
+
+ def convert_to_uri(uri)
+ if uri.is_a?(Bundler::URI::Generic)
+ uri
+ elsif uri = String.try_convert(uri)
+ parse(uri)
+ else
+ raise ArgumentError,
+ "bad argument (expected Bundler::URI object or Bundler::URI string)"
+ end
+ end
+
+ end # class Parser
+end # module Bundler::URI
diff --git a/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb b/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb
new file mode 100644
index 0000000000..3d0c7b91f0
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb
@@ -0,0 +1,125 @@
+# frozen_string_literal: false
+module Bundler::URI
+ class RFC3986_Parser # :nodoc:
+ # Bundler::URI defined in RFC3986
+ # this regexp is modified not to host is not empty string
+ RFC3986_URI = /\A(?<Bundler::URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*+):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
+ RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])++)(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
+ attr_reader :regexp
+
+ def initialize
+ @regexp = default_regexp.each_value(&:freeze).freeze
+ end
+
+ def split(uri) #:nodoc:
+ begin
+ uri = uri.to_str
+ rescue NoMethodError
+ raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri.inspect}"
+ end
+ uri.ascii_only? or
+ raise InvalidURIError, "Bundler::URI must be ascii only #{uri.dump}"
+ if m = RFC3986_URI.match(uri)
+ query = m["query".freeze]
+ scheme = m["scheme".freeze]
+ opaque = m["path-rootless".freeze]
+ if opaque
+ opaque << "?#{query}" if query
+ [ scheme,
+ nil, # userinfo
+ nil, # host
+ nil, # port
+ nil, # registry
+ nil, # path
+ opaque,
+ nil, # query
+ m["fragment".freeze]
+ ]
+ else # normal
+ [ scheme,
+ m["userinfo".freeze],
+ m["host".freeze],
+ m["port".freeze],
+ nil, # registry
+ (m["path-abempty".freeze] ||
+ m["path-absolute".freeze] ||
+ m["path-empty".freeze]),
+ nil, # opaque
+ query,
+ m["fragment".freeze]
+ ]
+ end
+ elsif m = RFC3986_relative_ref.match(uri)
+ [ nil, # scheme
+ m["userinfo".freeze],
+ m["host".freeze],
+ m["port".freeze],
+ nil, # registry,
+ (m["path-abempty".freeze] ||
+ m["path-absolute".freeze] ||
+ m["path-noscheme".freeze] ||
+ m["path-empty".freeze]),
+ nil, # opaque
+ m["query".freeze],
+ m["fragment".freeze]
+ ]
+ else
+ raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri.inspect}"
+ end
+ end
+
+ def parse(uri) # :nodoc:
+ scheme, userinfo, host, port,
+ registry, path, opaque, query, fragment = self.split(uri)
+ scheme_list = Bundler::URI.scheme_list
+ if scheme && scheme_list.include?(uc = scheme.upcase)
+ scheme_list[uc].new(scheme, userinfo, host, port,
+ registry, path, opaque, query,
+ fragment, self)
+ else
+ Generic.new(scheme, userinfo, host, port,
+ registry, path, opaque, query,
+ fragment, self)
+ end
+ end
+
+
+ def join(*uris) # :nodoc:
+ uris[0] = convert_to_uri(uris[0])
+ uris.inject :merge
+ end
+
+ @@to_s = Kernel.instance_method(:to_s)
+ def inspect
+ @@to_s.bind_call(self)
+ end
+
+ private
+
+ def default_regexp # :nodoc:
+ {
+ SCHEME: /\A[A-Za-z][A-Za-z0-9+\-.]*\z/,
+ USERINFO: /\A(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*\z/,
+ HOST: /\A(?:(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{,4}::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*))\z/,
+ ABS_PATH: /\A\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/,
+ REL_PATH: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/,
+ QUERY: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
+ FRAGMENT: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
+ OPAQUE: /\A(?:[^\/].*)?\z/,
+ PORT: /\A[\x09\x0a\x0c\x0d ]*+\d*[\x09\x0a\x0c\x0d ]*\z/,
+ }
+ end
+
+ def convert_to_uri(uri)
+ if uri.is_a?(Bundler::URI::Generic)
+ uri
+ elsif uri = String.try_convert(uri)
+ parse(uri)
+ else
+ raise ArgumentError,
+ "bad argument (expected Bundler::URI object or Bundler::URI string)"
+ end
+ end
+
+ end # class Parser
+end # module Bundler::URI
diff --git a/lib/bundler/vendor/uri/lib/uri/version.rb b/lib/bundler/vendor/uri/lib/uri/version.rb
new file mode 100644
index 0000000000..02079b26d4
--- /dev/null
+++ b/lib/bundler/vendor/uri/lib/uri/version.rb
@@ -0,0 +1,6 @@
+module Bundler::URI
+ # :stopdoc:
+ VERSION_CODE = '00100003'.freeze
+ VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
+ # :startdoc:
+end
diff --git a/lib/bundler/vendored_fileutils.rb b/lib/bundler/vendored_fileutils.rb
new file mode 100644
index 0000000000..1be1138ce2
--- /dev/null
+++ b/lib/bundler/vendored_fileutils.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+module Bundler; end
+require_relative "vendor/fileutils/lib/fileutils"
diff --git a/lib/bundler/vendored_molinillo.rb b/lib/bundler/vendored_molinillo.rb
index 7b231263cb..d1976f5cb4 100644
--- a/lib/bundler/vendored_molinillo.rb
+++ b/lib/bundler/vendored_molinillo.rb
@@ -1,3 +1,4 @@
# frozen_string_literal: true
+
module Bundler; end
-require "bundler/vendor/molinillo/lib/molinillo"
+require_relative "vendor/molinillo/lib/molinillo"
diff --git a/lib/bundler/vendored_persistent.rb b/lib/bundler/vendored_persistent.rb
index 729ac6b6f5..dc9573e025 100644
--- a/lib/bundler/vendored_persistent.rb
+++ b/lib/bundler/vendored_persistent.rb
@@ -1,11 +1,5 @@
# frozen_string_literal: true
-# We forcibly require OpenSSL, because net/http/persistent will only autoload
-# it. On some Rubies, autoload fails but explicit require succeeds.
-begin
- require "openssl"
-rescue LoadError
- # some Ruby builds don't have OpenSSL
-end
+
module Bundler
module Persistent
module Net
@@ -14,4 +8,40 @@ module Bundler
end
end
end
-require "bundler/vendor/net-http-persistent/lib/net/http/persistent"
+require_relative "vendor/net-http-persistent/lib/net/http/persistent"
+
+module Bundler
+ class PersistentHTTP < Persistent::Net::HTTP::Persistent
+ def connection_for(uri)
+ super(uri) do |connection|
+ result = yield connection
+ warn_old_tls_version_rubygems_connection(uri, connection)
+ result
+ end
+ end
+
+ def warn_old_tls_version_rubygems_connection(uri, connection)
+ return unless connection.http.use_ssl?
+ return unless (uri.host || "").end_with?("rubygems.org")
+
+ socket = connection.instance_variable_get(:@socket)
+ return unless socket
+ socket_io = socket.io
+ return unless socket_io.respond_to?(:ssl_version)
+ ssl_version = socket_io.ssl_version
+
+ case ssl_version
+ when /TLSv([\d\.]+)/
+ version = Gem::Version.new($1)
+ if version < Gem::Version.new("1.2")
+ Bundler.ui.warn \
+ "Warning: Your Ruby version is compiled against a copy of OpenSSL that is very old. " \
+ "Starting in January 2018, RubyGems.org will refuse connection requests from these " \
+ "very old versions of OpenSSL. If you will need to continue installing gems after " \
+ "January 2018, please follow this guide to upgrade: http://ruby.to/tls-outdated.",
+ :wrap => true
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bundler/vendored_thor.rb b/lib/bundler/vendored_thor.rb
index 4a5d0cf6bb..0666cfc9b9 100644
--- a/lib/bundler/vendored_thor.rb
+++ b/lib/bundler/vendored_thor.rb
@@ -1,7 +1,8 @@
# frozen_string_literal: true
+
module Bundler
def self.require_thor_actions
- Kernel.send(:require, "bundler/vendor/thor/lib/thor/actions")
+ require_relative "vendor/thor/lib/thor/actions"
end
end
-require "bundler/vendor/thor/lib/thor"
+require_relative "vendor/thor/lib/thor"
diff --git a/lib/bundler/vendored_tmpdir.rb b/lib/bundler/vendored_tmpdir.rb
new file mode 100644
index 0000000000..43b4fa75fe
--- /dev/null
+++ b/lib/bundler/vendored_tmpdir.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+module Bundler; end
+require_relative "vendor/tmpdir/lib/tmpdir"
diff --git a/lib/bundler/vendored_tsort.rb b/lib/bundler/vendored_tsort.rb
new file mode 100644
index 0000000000..38aed0b5de
--- /dev/null
+++ b/lib/bundler/vendored_tsort.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+module Bundler; end
+require_relative "vendor/tsort/lib/tsort"
diff --git a/lib/bundler/vendored_uri.rb b/lib/bundler/vendored_uri.rb
new file mode 100644
index 0000000000..905e8158e8
--- /dev/null
+++ b/lib/bundler/vendored_uri.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+module Bundler; end
+require_relative "vendor/uri/lib/uri"
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index b2dad6dfb6..863eeaae5f 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,24 +1,9 @@
-# frozen_string_literal: true
-
-# Ruby 1.9.3 and old RubyGems don't play nice with frozen version strings
-# rubocop:disable MutableConstant
+# frozen_string_literal: false
module Bundler
- # We're doing this because we might write tests that deal
- # with other versions of bundler and we are unsure how to
- # handle this better.
- VERSION = "1.15.4" unless defined?(::Bundler::VERSION)
+ VERSION = "2.2.33".freeze
- def self.overwrite_loaded_gem_version
- begin
- require "rubygems"
- rescue LoadError
- return
- end
- return unless bundler_spec = Gem.loaded_specs["bundler"]
- return if bundler_spec.version == VERSION
- bundler_spec.version = Bundler::VERSION
+ def self.bundler_major_version
+ @bundler_major_version ||= VERSION.split(".").first.to_i
end
- private_class_method :overwrite_loaded_gem_version
- overwrite_loaded_gem_version
end
diff --git a/lib/bundler/version_ranges.rb b/lib/bundler/version_ranges.rb
index 1ee8440edd..12a956d6a0 100644
--- a/lib/bundler/version_ranges.rb
+++ b/lib/bundler/version_ranges.rb
@@ -1,14 +1,46 @@
# frozen_string_literal: true
+
module Bundler
module VersionRanges
NEq = Struct.new(:version)
ReqR = Struct.new(:left, :right)
class ReqR
- Endpoint = Struct.new(:version, :inclusive)
+ Endpoint = Struct.new(:version, :inclusive) do
+ def <=>(other)
+ if version.equal?(INFINITY)
+ return 0 if other.version.equal?(INFINITY)
+ return 1
+ elsif other.version.equal?(INFINITY)
+ return -1
+ end
+
+ comp = version <=> other.version
+ return comp unless comp.zero?
+
+ if inclusive && !other.inclusive
+ 1
+ elsif !inclusive && other.inclusive
+ -1
+ else
+ 0
+ end
+ end
+ end
+
def to_s
"#{left.inclusive ? "[" : "("}#{left.version}, #{right.version}#{right.inclusive ? "]" : ")"}"
end
- INFINITY = Object.new.freeze
+ INFINITY = begin
+ inf = Object.new
+ def inf.to_s
+ "∞"
+ end
+ def inf.<=>(other)
+ return 0 if other.equal?(self)
+ 1
+ end
+ inf.freeze
+ end
ZERO = Gem::Version.new("0.a")
def cover?(v)
@@ -31,6 +63,15 @@ module Bundler
left.version == right.version
end
+ def <=>(other)
+ return -1 if other.equal?(INFINITY)
+
+ comp = left <=> other.left
+ return comp unless comp.zero?
+
+ right <=> other.right
+ end
+
UNIVERSAL = ReqR.new(ReqR::Endpoint.new(Gem::Version.new("0.a"), true), ReqR::Endpoint.new(ReqR::INFINITY, false)).freeze
end
@@ -56,7 +97,7 @@ module Bundler
end.uniq
ranges, neqs = ranges.partition {|r| !r.is_a?(NEq) }
- [ranges.sort_by {|range| [range.left.version, range.left.inclusive ? 0 : 1] }, neqs.map(&:version)]
+ [ranges.sort, neqs.map(&:version)]
end
def self.empty?(ranges, neqs)
@@ -65,8 +106,14 @@ module Bundler
next false if curr_range.single? && neqs.include?(curr_range.left.version)
next curr_range if last_range.right.version == ReqR::INFINITY
case last_range.right.version <=> curr_range.left.version
- when 1 then next curr_range
- when 0 then next(last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version) && curr_range)
+ # higher
+ when 1 then next ReqR.new(curr_range.left, last_range.right)
+ # equal
+ when 0
+ if last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version)
+ ReqR.new(curr_range.left, [curr_range.right, last_range.right].max)
+ end
+ # lower
when -1 then next false
end
end
diff --git a/lib/bundler/vlad.rb b/lib/bundler/vlad.rb
index db78f84baa..538e8c3e74 100644
--- a/lib/bundler/vlad.rb
+++ b/lib/bundler/vlad.rb
@@ -1,9 +1,14 @@
# frozen_string_literal: true
+
+require_relative "shared_helpers"
+Bundler::SharedHelpers.major_deprecation 2,
+ "The Bundler task for Vlad"
+
# Vlad task for Bundler.
#
# Add "require 'bundler/vlad'" in your Vlad deploy.rb, and
# include the vlad:bundle:install task in your vlad:deploy task.
-require "bundler/deployment"
+require_relative "deployment"
include Rake::DSL if defined? Rake::DSL
diff --git a/lib/bundler/worker.rb b/lib/bundler/worker.rb
index b73a7ed04a..5e4ee21c51 100644
--- a/lib/bundler/worker.rb
+++ b/lib/bundler/worker.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "thread"
module Bundler
class Worker
@@ -22,12 +21,12 @@ module Bundler
# @param func [Proc] job to run in inside the worker pool
def initialize(size, name, func)
@name = name
- @request_queue = Queue.new
- @response_queue = Queue.new
+ @request_queue = Thread::Queue.new
+ @response_queue = Thread::Queue.new
@func = func
@size = size
@threads = nil
- SharedHelpers.trap("INT") { abort_threads }
+ @previous_interrupt_handler = nil
end
# Enqueue a request to be executed in the worker pool
@@ -49,7 +48,7 @@ module Bundler
stop_threads
end
- private
+ private
def process_queue(i)
loop do
@@ -61,7 +60,7 @@ module Bundler
def apply_func(obj, i)
@func.call(obj, i)
- rescue Exception => e
+ rescue Exception => e # rubocop:disable Lint/RescueException
WrappedException.new(e)
end
@@ -69,13 +68,16 @@ module Bundler
# so as worker threads after retrieving it, shut themselves down
def stop_threads
return unless @threads
+
@threads.each { @request_queue.enq POISON }
@threads.each(&:join)
+
+ remove_interrupt_handler
+
@threads = nil
end
def abort_threads
- return unless @threads
Bundler.ui.debug("\n#{caller.join("\n")}")
@threads.each(&:exit)
exit 1
@@ -95,11 +97,23 @@ module Bundler
end
end.compact
+ add_interrupt_handler unless @threads.empty?
+
return if creation_errors.empty?
message = "Failed to create threads for the #{name} worker: #{creation_errors.map(&:to_s).uniq.join(", ")}"
raise ThreadCreationError, message if @threads.empty?
Bundler.ui.info message
end
+
+ def add_interrupt_handler
+ @previous_interrupt_handler = trap("INT") { abort_threads }
+ end
+
+ def remove_interrupt_handler
+ return unless @previous_interrupt_handler
+
+ trap "INT", @previous_interrupt_handler
+ end
end
end
diff --git a/lib/bundler/yaml_serializer.rb b/lib/bundler/yaml_serializer.rb
index 3c9eccafc2..d5ecbd4aef 100644
--- a/lib/bundler/yaml_serializer.rb
+++ b/lib/bundler/yaml_serializer.rb
@@ -3,7 +3,7 @@
module Bundler
# A stub yaml serializer that can handle only hashes and strings (as of now).
module YAMLSerializer
- module_function
+ module_function
def dump(hash)
yaml = String.new("---")
@@ -32,20 +32,19 @@ module Bundler
(.*) # value
\1 # matching closing quote
$
- /xo
+ /xo.freeze
HASH_REGEX = /
^
([ ]*) # indentations
- (.*) # key
+ (.+) # key
(?::(?=(?:\s|$))) # : (without the lookahead the #key includes this when : is present in value)
[ ]?
- (?: !\s)? # optional exclamation mark found with ruby 1.9.3
(['"]?) # optional opening quote
(.*) # value
\3 # matching closing quote
$
- /xo
+ /xo.freeze
def load(str)
res = {}
@@ -54,10 +53,10 @@ module Bundler
last_empty_key = nil
str.split(/\r?\n/).each do |line|
if match = HASH_REGEX.match(line)
- indent, key, _, val = match.captures
+ indent, key, quote, val = match.captures
key = convert_to_backward_compatible_key(key)
depth = indent.scan(/ /).length
- if val.empty?
+ if quote.empty? && val.empty?
new_hash = {}
stack[depth][key] = new_hash
stack[depth + 1] = new_hash
diff --git a/lib/cgi.rb b/lib/cgi.rb
index 0f44a929e4..6feeaf4624 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -253,7 +253,7 @@
# end
# end +
# cgi.pre do
-# CGI::escapeHTML(
+# CGI.escapeHTML(
# "params: #{cgi.params.inspect}\n" +
# "cookies: #{cgi.cookies.inspect}\n" +
# ENV.collect do |key, value|
@@ -288,6 +288,7 @@
#
class CGI
+ VERSION = "0.2.2"
end
require 'cgi/core'
diff --git a/lib/cgi/cgi.gemspec b/lib/cgi/cgi.gemspec
new file mode 100644
index 0000000000..1a883934e5
--- /dev/null
+++ b/lib/cgi/cgi.gemspec
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Support for the Common Gateway Interface protocol.}
+ spec.description = %q{Support for the Common Gateway Interface protocol.}
+ spec.homepage = "https://github.com/ruby/cgi"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = ">= 2.5.0"
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
index a2155edb77..1a9c1a82c1 100644
--- a/lib/cgi/cookie.rb
+++ b/lib/cgi/cookie.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require 'cgi/util'
+require_relative 'util'
class CGI
# Class representing an HTTP cookie.
#
@@ -40,6 +40,10 @@ class CGI
class Cookie < Array
@@accept_charset="UTF-8" unless defined?(@@accept_charset)
+ TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z"
+ PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z"
+ DOMAIN_VALUE_RE = %r"\A(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
+
# Create a new CGI::Cookie object.
#
# :call-seq:
@@ -57,7 +61,7 @@ class CGI
#
# name:: the name of the cookie. Required.
# value:: the cookie's value or list of values.
- # path:: the path for which this cookie applies. Defaults to the
+ # path:: the path for which this cookie applies. Defaults to
# the value of the +SCRIPT_NAME+ environment variable.
# domain:: the domain for which this cookie applies.
# expires:: the time at which this cookie expires, as a +Time+ object.
@@ -72,9 +76,8 @@ class CGI
@domain = nil
@expires = nil
if name.kind_of?(String)
- @name = name
- %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
- @path = ($1 or "")
+ self.name = name
+ self.path = (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
@secure = false
@httponly = false
return super(value)
@@ -85,16 +88,11 @@ class CGI
raise ArgumentError, "`name' required"
end
- @name = options["name"]
+ self.name = options["name"]
value = Array(options["value"])
# simple support for IE
- if options["path"]
- @path = options["path"]
- else
- %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
- @path = ($1 or "")
- end
- @domain = options["domain"]
+ self.path = options["path"] || (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
+ self.domain = options["domain"]
@expires = options["expires"]
@secure = options["secure"] == true
@httponly = options["httponly"] == true
@@ -103,11 +101,35 @@ class CGI
end
# Name of this cookie, as a +String+
- attr_accessor :name
+ attr_reader :name
+ # Set name of this cookie
+ def name=(str)
+ if str and !TOKEN_RE.match?(str)
+ raise ArgumentError, "invalid name: #{str.dump}"
+ end
+ @name = str
+ end
+
# Path for which this cookie applies, as a +String+
- attr_accessor :path
+ attr_reader :path
+ # Set path for which this cookie applies
+ def path=(str)
+ if str and !PATH_VALUE_RE.match?(str)
+ raise ArgumentError, "invalid path: #{str.dump}"
+ end
+ @path = str
+ end
+
# Domain for which this cookie applies, as a +String+
- attr_accessor :domain
+ attr_reader :domain
+ # Set domain for which this cookie applies
+ def domain=(str)
+ if str and ((str = str.b).bytesize > 255 or !DOMAIN_VALUE_RE.match?(str))
+ raise ArgumentError, "invalid domain: #{str.dump}"
+ end
+ @domain = str
+ end
+
# Time at which this cookie expires, as a +Time+
attr_accessor :expires
# True if this cookie is secure; false otherwise
@@ -146,7 +168,7 @@ class CGI
buf = "#{@name}=#{val}".dup
buf << "; domain=#{@domain}" if @domain
buf << "; path=#{@path}" if @path
- buf << "; expires=#{CGI::rfc1123_date(@expires)}" if @expires
+ buf << "; expires=#{CGI.rfc1123_date(@expires)}" if @expires
buf << "; secure" if @secure
buf << "; HttpOnly" if @httponly
buf
@@ -165,7 +187,6 @@ class CGI
raw_cookie.split(/;\s?/).each do |pairs|
name, values = pairs.split('=',2)
next unless name and values
- name = CGI.unescape(name)
values ||= ""
values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
if cookies.has_key?(name)
diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
index 1b5f7ed390..62e606837a 100644
--- a/lib/cgi/core.rb
+++ b/lib/cgi/core.rb
@@ -188,17 +188,28 @@ class CGI
# Using #header with the HTML5 tag maker will create a <header> element.
alias :header :http_header
+ def _no_crlf_check(str)
+ if str
+ str = str.to_s
+ raise "A HTTP status or header field must not include CR and LF" if str =~ /[\r\n]/
+ str
+ else
+ nil
+ end
+ end
+ private :_no_crlf_check
+
def _header_for_string(content_type) #:nodoc:
buf = ''.dup
if nph?()
- buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
+ buf << "#{_no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'} 200 OK#{EOL}"
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
- buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
+ buf << "Server: #{_no_crlf_check($CGI_ENV['SERVER_SOFTWARE'])}#{EOL}"
buf << "Connection: close#{EOL}"
end
- buf << "Content-Type: #{content_type}#{EOL}"
+ buf << "Content-Type: #{_no_crlf_check(content_type)}#{EOL}"
if @output_cookies
- @output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
+ @output_cookies.each {|cookie| buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}" }
end
return buf
end # _header_for_string
@@ -213,9 +224,9 @@ class CGI
## NPH
options.delete('nph') if defined?(MOD_RUBY)
if options.delete('nph') || nph?()
- protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
+ protocol = _no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'
status = options.delete('status')
- status = HTTP_STATUS[status] || status || '200 OK'
+ status = HTTP_STATUS[status] || _no_crlf_check(status) || '200 OK'
buf << "#{protocol} #{status}#{EOL}"
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || ''
@@ -223,51 +234,51 @@ class CGI
end
## common headers
status = options.delete('status')
- buf << "Status: #{HTTP_STATUS[status] || status}#{EOL}" if status
+ buf << "Status: #{HTTP_STATUS[status] || _no_crlf_check(status)}#{EOL}" if status
server = options.delete('server')
- buf << "Server: #{server}#{EOL}" if server
+ buf << "Server: #{_no_crlf_check(server)}#{EOL}" if server
connection = options.delete('connection')
- buf << "Connection: #{connection}#{EOL}" if connection
+ buf << "Connection: #{_no_crlf_check(connection)}#{EOL}" if connection
type = options.delete('type')
- buf << "Content-Type: #{type}#{EOL}" #if type
+ buf << "Content-Type: #{_no_crlf_check(type)}#{EOL}" #if type
length = options.delete('length')
- buf << "Content-Length: #{length}#{EOL}" if length
+ buf << "Content-Length: #{_no_crlf_check(length)}#{EOL}" if length
language = options.delete('language')
- buf << "Content-Language: #{language}#{EOL}" if language
+ buf << "Content-Language: #{_no_crlf_check(language)}#{EOL}" if language
expires = options.delete('expires')
buf << "Expires: #{CGI.rfc1123_date(expires)}#{EOL}" if expires
## cookie
if cookie = options.delete('cookie')
case cookie
when String, Cookie
- buf << "Set-Cookie: #{cookie}#{EOL}"
+ buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}"
when Array
arr = cookie
- arr.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
+ arr.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
when Hash
hash = cookie
- hash.each_value {|c| buf << "Set-Cookie: #{c}#{EOL}" }
+ hash.each_value {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
end
end
if @output_cookies
- @output_cookies.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
+ @output_cookies.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
end
## other headers
options.each do |key, value|
- buf << "#{key}: #{value}#{EOL}"
+ buf << "#{_no_crlf_check(key)}: #{_no_crlf_check(value)}#{EOL}"
end
return buf
end # _header_for_hash
private :_header_for_hash
def nph? #:nodoc:
- return /IIS\/(\d+)/.match($CGI_ENV['SERVER_SOFTWARE']) && $1.to_i < 5
+ return /IIS\/(\d+)/ =~ $CGI_ENV['SERVER_SOFTWARE'] && $1.to_i < 5
end
def _header_for_modruby(buf) #:nodoc:
request = Apache::request
buf.scan(/([^:]+): (.+)#{EOL}/o) do |name, value|
- warn sprintf("name:%s value:%s\n", name, value) if $DEBUG
+ $stderr.printf("name:%s value:%s\n", name, value) if $DEBUG
case name
when 'Set-Cookie'
request.headers_out.add(name, value)
@@ -375,14 +386,14 @@ class CGI
# Parse an HTTP query string into a hash of key=>value pairs.
#
- # params = CGI::parse("query_string")
+ # params = CGI.parse("query_string")
# # {"name1" => ["value1", "value2", ...],
# # "name2" => ["value1", "value2", ...], ... }
#
- def CGI::parse(query)
+ def self.parse(query)
params = {}
query.split(/[&;]/).each do |pairs|
- key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) }
+ key, value = pairs.split('=',2).collect{|v| CGI.unescape(v) }
next unless key
@@ -421,7 +432,7 @@ class CGI
module QueryExtension
%w[ CONTENT_LENGTH SERVER_PORT ].each do |env|
- define_method(env.sub(/^HTTP_/, '').downcase) do
+ define_method(env.delete_prefix('HTTP_').downcase) do
(val = env_table[env]) && Integer(val)
end
end
@@ -434,7 +445,7 @@ class CGI
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST
HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env|
- define_method(env.sub(/^HTTP_/, '').downcase) do
+ define_method(env.delete_prefix('HTTP_').downcase) do
env_table[env]
end
end
@@ -544,11 +555,11 @@ class CGI
/Content-Disposition:.* filename=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
filename = $1 || $2 || ''.dup
filename = CGI.unescape(filename) if unescape_filename?()
- body.instance_variable_set(:@original_filename, filename.taint)
+ body.instance_variable_set(:@original_filename, filename)
## content type
/Content-Type: (.*)/i.match(head)
(content_type = $1 || ''.dup).chomp!
- body.instance_variable_set(:@content_type, content_type.taint)
+ body.instance_variable_set(:@content_type, content_type)
## query parameter name
/Content-Disposition:.* name=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
name = $1 || $2 || ''
@@ -607,6 +618,7 @@ class CGI
end
def unescape_filename? #:nodoc:
user_agent = $CGI_ENV['HTTP_USER_AGENT']
+ return false unless user_agent
return /Mac/i.match(user_agent) && /Mozilla/i.match(user_agent) && !/MSIE/i.match(user_agent)
end
@@ -648,7 +660,7 @@ class CGI
# Reads query parameters in the @params field, and cookies into @cookies.
def initialize_query()
if ("POST" == env_table['REQUEST_METHOD']) and
- %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|.match(env_table['CONTENT_TYPE'])
+ %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?| =~ env_table['CONTENT_TYPE']
current_max_multipart_length = @max_multipart_length.respond_to?(:call) ? @max_multipart_length.call : @max_multipart_length
raise StandardError.new("too large multipart data.") if env_table['CONTENT_LENGTH'].to_i > current_max_multipart_length
boundary = $1.dup
@@ -656,7 +668,7 @@ class CGI
@params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
else
@multipart = false
- @params = CGI::parse(
+ @params = CGI.parse(
case env_table['REQUEST_METHOD']
when "GET", "HEAD"
if defined?(MOD_RUBY)
@@ -686,7 +698,7 @@ class CGI
end
end
- @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
+ @cookies = CGI::Cookie.parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
end
private :initialize_query
@@ -862,24 +874,24 @@ class CGI
case @options[:tag_maker]
when "html3"
- require 'cgi/html'
+ require_relative 'html'
extend Html3
extend HtmlExtension
when "html4"
- require 'cgi/html'
+ require_relative 'html'
extend Html4
extend HtmlExtension
when "html4Tr"
- require 'cgi/html'
+ require_relative 'html'
extend Html4Tr
extend HtmlExtension
when "html4Fr"
- require 'cgi/html'
+ require_relative 'html'
extend Html4Tr
extend Html4Fr
extend HtmlExtension
when "html5"
- require 'cgi/html'
+ require_relative 'html'
extend Html5
extend HtmlExtension
end
diff --git a/lib/cgi/html.rb b/lib/cgi/html.rb
index 02d847ebd3..1543943320 100644
--- a/lib/cgi/html.rb
+++ b/lib/cgi/html.rb
@@ -30,10 +30,10 @@ class CGI
attributes.each do|name, value|
next unless value
s << " "
- s << CGI::escapeHTML(name.to_s)
+ s << CGI.escapeHTML(name.to_s)
if value != true
s << '="'
- s << CGI::escapeHTML(value.to_s)
+ s << CGI.escapeHTML(value.to_s)
s << '"'
end
end
@@ -423,7 +423,7 @@ class CGI
buf << super(attributes)
if pretty
- CGI::pretty(buf, pretty)
+ CGI.pretty(buf, pretty)
else
buf
end
diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb
index fbb42986a4..29e7b3ece3 100644
--- a/lib/cgi/session.rb
+++ b/lib/cgi/session.rb
@@ -403,11 +403,11 @@ class CGI
for line in f
line.chomp!
k, v = line.split('=',2)
- @hash[CGI::unescape(k)] = Marshal.restore(CGI::unescape(v))
+ @hash[CGI.unescape(k)] = Marshal.restore(CGI.unescape(v))
end
ensure
- f.close unless f.nil?
- lockf.close if lockf
+ f&.close
+ lockf&.close
end
end
@hash
@@ -421,13 +421,13 @@ class CGI
lockf.flock File::LOCK_EX
f = File.open(@path+".new", File::CREAT|File::TRUNC|File::WRONLY, 0600)
for k,v in @hash
- f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(Marshal.dump(v)))
+ f.printf "%s=%s\n", CGI.escape(k), CGI.escape(String(Marshal.dump(v)))
end
f.close
File.rename @path+".new", @path
ensure
- f.close if f
- lockf.close if lockf
+ f&.close
+ lockf&.close
end
end
diff --git a/lib/cgi/session/pstore.rb b/lib/cgi/session/pstore.rb
index cb0370b619..cc3006400f 100644
--- a/lib/cgi/session/pstore.rb
+++ b/lib/cgi/session/pstore.rb
@@ -10,7 +10,7 @@
# persistent of session data on top of the pstore library. See
# cgi/session.rb for more details on session storage managers.
-require 'cgi/session'
+require_relative '../session'
require 'pstore'
class CGI
@@ -50,7 +50,6 @@ class CGI
require 'digest/md5'
md5 = Digest::MD5.hexdigest(id)[0,16]
path = dir+"/"+prefix+md5
- path.untaint
if File::exist?(path)
@hash = nil
else
diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb
index 464115262f..aab8b000cb 100644
--- a/lib/cgi/util.rb
+++ b/lib/cgi/util.rb
@@ -7,7 +7,7 @@ end
module CGI::Util
@@accept_charset="UTF-8" unless defined?(@@accept_charset)
# URL-encode a string.
- # url_encoded_string = CGI::escape("'Stop!' said Fred")
+ # url_encoded_string = CGI.escape("'Stop!' said Fred")
# # => "%27Stop%21%27+said+Fred"
def escape(string)
encoding = string.encoding
@@ -17,7 +17,7 @@ module CGI::Util
end
# URL-decode a string with encoding(optional).
- # string = CGI::unescape("%27Stop%21%27+said+Fred")
+ # string = CGI.unescape("%27Stop%21%27+said+Fred")
# # => "'Stop!' said Fred"
def unescape(string,encoding=@@accept_charset)
str=string.tr('+', ' ').b.gsub(/((?:%[0-9a-fA-F]{2})+)/) do |m|
@@ -36,7 +36,7 @@ module CGI::Util
}
# Escape special characters in HTML, namely '&\"<>
- # CGI::escapeHTML('Usage: foo "bar" <baz>')
+ # CGI.escapeHTML('Usage: foo "bar" <baz>')
# # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
def escapeHTML(string)
enc = string.encoding
@@ -60,7 +60,7 @@ module CGI::Util
end
# Unescape a string that has been HTML-escaped
- # CGI::unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
+ # CGI.unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
# # => "Usage: foo \"bar\" <baz>"
def unescapeHTML(string)
enc = string.encoding
@@ -118,10 +118,10 @@ module CGI::Util
end
end
- # Synonym for CGI::escapeHTML(str)
+ # Synonym for CGI.escapeHTML(str)
alias escape_html escapeHTML
- # Synonym for CGI::unescapeHTML(str)
+ # Synonym for CGI.unescapeHTML(str)
alias unescape_html unescapeHTML
# Escape only the tags of certain HTML elements in +string+.
@@ -132,30 +132,30 @@ module CGI::Util
# The attribute list of the open tag will also be escaped (for
# instance, the double-quotes surrounding attribute values).
#
- # print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
+ # print CGI.escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
# # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
#
- # print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
+ # print CGI.escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
# # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
def escapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
- CGI::escapeHTML($&)
+ CGI.escapeHTML($&)
end
else
string
end
end
- # Undo escaping such as that done by CGI::escapeElement()
+ # Undo escaping such as that done by CGI.escapeElement()
#
- # print CGI::unescapeElement(
- # CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
+ # print CGI.unescapeElement(
+ # CGI.escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
# # "&lt;BR&gt;<A HREF="url"></A>"
#
- # print CGI::unescapeElement(
- # CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
+ # print CGI.unescapeElement(
+ # CGI.escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
# # "&lt;BR&gt;<A HREF="url"></A>"
def unescapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
@@ -168,10 +168,10 @@ module CGI::Util
end
end
- # Synonym for CGI::escapeElement(str)
+ # Synonym for CGI.escapeElement(str)
alias escape_element escapeElement
- # Synonym for CGI::unescapeElement(str)
+ # Synonym for CGI.unescapeElement(str)
alias unescape_element unescapeElement
# Abbreviated day-of-week names specified by RFC 822
@@ -182,7 +182,7 @@ module CGI::Util
# Format a +Time+ object as a String using the format specified by RFC 1123.
#
- # CGI::rfc1123_date(Time.now)
+ # CGI.rfc1123_date(Time.now)
# # Sat, 01 Jan 2000 00:00:00 GMT
def rfc1123_date(time)
t = time.clone.gmtime
@@ -196,13 +196,13 @@ module CGI::Util
# +string+ is the HTML string to indent. +shift+ is the indentation
# unit to use; it defaults to two spaces.
#
- # print CGI::pretty("<HTML><BODY></BODY></HTML>")
+ # print CGI.pretty("<HTML><BODY></BODY></HTML>")
# # <HTML>
# # <BODY>
# # </BODY>
# # </HTML>
#
- # print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t")
+ # print CGI.pretty("<HTML><BODY></BODY></HTML>", "\t")
# # <HTML>
# # <BODY>
# # </BODY>
diff --git a/lib/cmath.gemspec b/lib/cmath.gemspec
deleted file mode 100644
index 28ae2549f3..0000000000
--- a/lib/cmath.gemspec
+++ /dev/null
@@ -1,24 +0,0 @@
-# coding: utf-8
-# frozen_string_literal: true
-
-Gem::Specification.new do |spec|
- spec.name = "cmath"
- spec.version = "0.0.1"
- spec.date = '2017-02-02'
- spec.authors = ["Tadayoshi Funaba"]
- spec.email = [nil]
-
- spec.summary = "Provides Trigonometric and Transcendental functions for complex numbers"
- spec.description = "CMath is a library that provides trigonometric and transcendental functions for complex numbers. The functions in this module accept integers, floating-point numbers or complex numbers as arguments."
- spec.homepage = "https://github.com/ruby/cmath"
- spec.license = "BSD-2-Clause"
-
- spec.files = "lib/cmath.rb"
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
- spec.required_ruby_version = ">= 2.5.0dev"
-
- spec.add_development_dependency "bundler"
- spec.add_development_dependency "rake"
-end
diff --git a/lib/cmath.rb b/lib/cmath.rb
deleted file mode 100644
index 4f327fd188..0000000000
--- a/lib/cmath.rb
+++ /dev/null
@@ -1,435 +0,0 @@
-# frozen_string_literal: true
-##
-# = Trigonometric and transcendental functions for complex numbers.
-#
-# CMath is a library that provides trigonometric and transcendental
-# functions for complex numbers. The functions in this module accept
-# integers, floating-point numbers or complex numbers as arguments.
-#
-# Note that the selection of functions is similar, but not identical,
-# to that in module math. The reason for having two modules is that
-# some users aren't interested in complex numbers, and perhaps don't
-# even know what they are. They would rather have Math.sqrt(-1) raise
-# an exception than return a complex number.
-#
-# For more information you can see Complex class.
-#
-# == Usage
-#
-# To start using this library, simply require cmath library:
-#
-# require "cmath"
-
-module CMath
-
- include Math
-
- # Backup of Math is needed because mathn.rb replaces Math with CMath.
- RealMath = Math # :nodoc:
- private_constant :RealMath
-
- %w[
- exp
- log
- log2
- log10
- sqrt
- cbrt
- sin
- cos
- tan
- sinh
- cosh
- tanh
- asin
- acos
- atan
- atan2
- asinh
- acosh
- atanh
- ].each do |meth|
- define_method(meth + '!') do |*args, &block|
- warn("CMath##{meth}! is deprecated; use CMath##{meth} or Math##{meth}") if $VERBOSE
- RealMath.send(meth, *args, &block)
- end
- end
-
- ##
- # Math::E raised to the +z+ power
- #
- # CMath.exp(1.i * Math::PI) #=> (-1.0+1.2246467991473532e-16i)
- def exp(z)
- begin
- if z.real?
- RealMath.exp(z)
- else
- ere = RealMath.exp(z.real)
- Complex(ere * RealMath.cos(z.imag),
- ere * RealMath.sin(z.imag))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the natural logarithm of Complex. If a second argument is given,
- # it will be the base of logarithm.
- #
- # CMath.log(1 + 4i) #=> (1.416606672028108+1.3258176636680326i)
- # CMath.log(1 + 4i, 10) #=> (0.6152244606891369+0.5757952953408879i)
- def log(z, b=::Math::E)
- begin
- if z.real? && z >= 0 && b >= 0
- RealMath.log(z, b)
- else
- Complex(RealMath.log(z.abs), z.arg) / log(b)
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the base 2 logarithm of +z+
- #
- # CMath.log2(-1) => (0.0+4.532360141827194i)
- def log2(z)
- begin
- if z.real? and z >= 0
- RealMath.log2(z)
- else
- log(z) / RealMath.log(2)
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the base 10 logarithm of +z+
- #
- # CMath.log10(-1) #=> (0.0+1.3643763538418412i)
- def log10(z)
- begin
- if z.real? and z >= 0
- RealMath.log10(z)
- else
- log(z) / RealMath.log(10)
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the non-negative square root of Complex.
- #
- # CMath.sqrt(-1 + 0i) #=> 0.0+1.0i
- def sqrt(z)
- begin
- if z.real?
- if z < 0
- Complex(0, RealMath.sqrt(-z))
- else
- RealMath.sqrt(z)
- end
- else
- if z.imag < 0 ||
- (z.imag == 0 && z.imag.to_s[0] == '-')
- sqrt(z.conjugate).conjugate
- else
- r = z.abs
- x = z.real
- Complex(RealMath.sqrt((r + x) / 2.0), RealMath.sqrt((r - x) / 2.0))
- end
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the principal value of the cube root of +z+
- #
- # CMath.cbrt(1 + 4i) #=> (1.449461632813119+0.6858152562177092i)
- def cbrt(z)
- z ** (1.0/3)
- end
-
- ##
- # Returns the sine of +z+, where +z+ is given in radians
- #
- # CMath.sin(1 + 1i) #=> (1.2984575814159773+0.6349639147847361i)
- def sin(z)
- begin
- if z.real?
- RealMath.sin(z)
- else
- Complex(RealMath.sin(z.real) * RealMath.cosh(z.imag),
- RealMath.cos(z.real) * RealMath.sinh(z.imag))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the cosine of +z+, where +z+ is given in radians
- #
- # CMath.cos(1 + 1i) #=> (0.8337300251311491-0.9888977057628651i)
- def cos(z)
- begin
- if z.real?
- RealMath.cos(z)
- else
- Complex(RealMath.cos(z.real) * RealMath.cosh(z.imag),
- -RealMath.sin(z.real) * RealMath.sinh(z.imag))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the tangent of +z+, where +z+ is given in radians
- #
- # CMath.tan(1 + 1i) #=> (0.27175258531951174+1.0839233273386943i)
- def tan(z)
- begin
- if z.real?
- RealMath.tan(z)
- else
- sin(z) / cos(z)
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the hyperbolic sine of +z+, where +z+ is given in radians
- #
- # CMath.sinh(1 + 1i) #=> (0.6349639147847361+1.2984575814159773i)
- def sinh(z)
- begin
- if z.real?
- RealMath.sinh(z)
- else
- Complex(RealMath.sinh(z.real) * RealMath.cos(z.imag),
- RealMath.cosh(z.real) * RealMath.sin(z.imag))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the hyperbolic cosine of +z+, where +z+ is given in radians
- #
- # CMath.cosh(1 + 1i) #=> (0.8337300251311491+0.9888977057628651i)
- def cosh(z)
- begin
- if z.real?
- RealMath.cosh(z)
- else
- Complex(RealMath.cosh(z.real) * RealMath.cos(z.imag),
- RealMath.sinh(z.real) * RealMath.sin(z.imag))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the hyperbolic tangent of +z+, where +z+ is given in radians
- #
- # CMath.tanh(1 + 1i) #=> (1.0839233273386943+0.27175258531951174i)
- def tanh(z)
- begin
- if z.real?
- RealMath.tanh(z)
- else
- sinh(z) / cosh(z)
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the arc sine of +z+
- #
- # CMath.asin(1 + 1i) #=> (0.6662394324925153+1.0612750619050355i)
- def asin(z)
- begin
- if z.real? and z >= -1 and z <= 1
- RealMath.asin(z)
- else
- (-1.0).i * log(1.0.i * z + sqrt(1.0 - z * z))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the arc cosine of +z+
- #
- # CMath.acos(1 + 1i) #=> (0.9045568943023813-1.0612750619050357i)
- def acos(z)
- begin
- if z.real? and z >= -1 and z <= 1
- RealMath.acos(z)
- else
- (-1.0).i * log(z + 1.0.i * sqrt(1.0 - z * z))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # Returns the arc tangent of +z+
- #
- # CMath.atan(1 + 1i) #=> (1.0172219678978514+0.4023594781085251i)
- def atan(z)
- begin
- if z.real?
- RealMath.atan(z)
- else
- 1.0.i * log((1.0.i + z) / (1.0.i - z)) / 2.0
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # returns the arc tangent of +y+ divided by +x+ using the signs of +y+ and
- # +x+ to determine the quadrant
- #
- # CMath.atan2(1 + 1i, 0) #=> (1.5707963267948966+0.0i)
- def atan2(y,x)
- begin
- if y.real? and x.real?
- RealMath.atan2(y,x)
- else
- (-1.0).i * log((x + 1.0.i * y) / sqrt(x * x + y * y))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # returns the inverse hyperbolic sine of +z+
- #
- # CMath.asinh(1 + 1i) #=> (1.0612750619050357+0.6662394324925153i)
- def asinh(z)
- begin
- if z.real?
- RealMath.asinh(z)
- else
- log(z + sqrt(1.0 + z * z))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # returns the inverse hyperbolic cosine of +z+
- #
- # CMath.acosh(1 + 1i) #=> (1.0612750619050357+0.9045568943023813i)
- def acosh(z)
- begin
- if z.real? and z >= 1
- RealMath.acosh(z)
- else
- log(z + sqrt(z * z - 1.0))
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- ##
- # returns the inverse hyperbolic tangent of +z+
- #
- # CMath.atanh(1 + 1i) #=> (0.4023594781085251+1.0172219678978514i)
- def atanh(z)
- begin
- if z.real? and z >= -1 and z <= 1
- RealMath.atanh(z)
- else
- log((1.0 + z) / (1.0 - z)) / 2.0
- end
- rescue NoMethodError
- handle_no_method_error
- end
- end
-
- module_function :exp!
- module_function :exp
- module_function :log!
- module_function :log
- module_function :log2!
- module_function :log2
- module_function :log10!
- module_function :log10
- module_function :sqrt!
- module_function :sqrt
- module_function :cbrt!
- module_function :cbrt
-
- module_function :sin!
- module_function :sin
- module_function :cos!
- module_function :cos
- module_function :tan!
- module_function :tan
-
- module_function :sinh!
- module_function :sinh
- module_function :cosh!
- module_function :cosh
- module_function :tanh!
- module_function :tanh
-
- module_function :asin!
- module_function :asin
- module_function :acos!
- module_function :acos
- module_function :atan!
- module_function :atan
- module_function :atan2!
- module_function :atan2
-
- module_function :asinh!
- module_function :asinh
- module_function :acosh!
- module_function :acosh
- module_function :atanh!
- module_function :atanh
-
- module_function :frexp
- module_function :ldexp
- module_function :hypot
- module_function :erf
- module_function :erfc
- module_function :gamma
- module_function :lgamma
-
- private
- def handle_no_method_error # :nodoc:
- if $!.name == :real?
- raise TypeError, "Numeric Number required"
- else
- raise
- end
- end
- module_function :handle_no_method_error
-
-end
diff --git a/lib/csv.gemspec b/lib/csv.gemspec
deleted file mode 100644
index 9803af69dc..0000000000
--- a/lib/csv.gemspec
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-Gem::Specification.new do |spec|
- spec.name = "csv"
- spec.version = "0.1.0"
- spec.date = "2017-09-12"
- spec.authors = ["James Edward Gray II"]
- spec.email = [nil]
-
- spec.summary = "CSV Reading and Writing"
- spec.description = "the CSV library began its life as FasterCSV."
- spec.homepage = "https://github.com/ruby/csv"
- spec.license = "BSD-2-Clause"
-
- spec.files = ["lib/csv.rb"]
- spec.require_paths = ["lib"]
- spec.required_ruby_version = ">= 2.5.0dev"
-
- spec.add_development_dependency "bundler", "~> 1.14"
- spec.add_development_dependency "rake", "~> 12"
-end
diff --git a/lib/csv.rb b/lib/csv.rb
index 1f616803aa..056cfa2051 100644
--- a/lib/csv.rb
+++ b/lib/csv.rb
@@ -2,9 +2,7 @@
# frozen_string_literal: true
# = csv.rb -- CSV Reading and Writing
#
-# Created by James Edward Gray II on 2005-10-31.
-# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
-# under the terms of Ruby's license.
+# Created by James Edward Gray II on 2005-10-31.
#
# See CSV for documentation.
#
@@ -12,18 +10,18 @@
#
# Welcome to the new and improved CSV.
#
-# This version of the CSV library began its life as FasterCSV. FasterCSV was
-# intended as a replacement to Ruby's then standard CSV library. It was
+# This version of the CSV library began its life as FasterCSV. FasterCSV was
+# intended as a replacement to Ruby's then standard CSV library. It was
# designed to address concerns users of that library had and it had three
# primary goals:
#
# 1. Be significantly faster than CSV while remaining a pure Ruby library.
-# 2. Use a smaller and easier to maintain code base. (FasterCSV eventually
-# grew larger, was also but considerably richer in features. The parsing
+# 2. Use a smaller and easier to maintain code base. (FasterCSV eventually
+# grew larger, was also but considerably richer in features. The parsing
# core remains quite small.)
# 3. Improve on the CSV interface.
#
-# Obviously, the last one is subjective. I did try to defer to the original
+# Obviously, the last one is subjective. I did try to defer to the original
# interface whenever I didn't have a compelling reason to change it though, so
# hopefully this won't be too radically different.
#
@@ -31,20 +29,20 @@
# the original library as of Ruby 1.9. If you are migrating code from 1.8 or
# earlier, you may have to change your code to comply with the new interface.
#
-# == What's Different From the Old CSV?
+# == What's the Different From the Old CSV?
#
# I'm sure I'll miss something, but I'll try to mention most of the major
# differences I am aware of, to help others quickly get up to speed:
#
-# === CSV Parsing
+# === \CSV Parsing
#
-# * This parser is m17n aware. See CSV for full details.
+# * This parser is m17n aware. See CSV for full details.
# * This library has a stricter parser and will throw MalformedCSVErrors on
# problematic data.
-# * This library has a less liberal idea of a line ending than CSV. What you
-# set as the <tt>:row_sep</tt> is law. It can auto-detect your line endings
+# * This library has a less liberal idea of a line ending than CSV. What you
+# set as the <tt>:row_sep</tt> is law. It can auto-detect your line endings
# though.
-# * The old library returned empty lines as <tt>[nil]</tt>. This library calls
+# * The old library returned empty lines as <tt>[nil]</tt>. This library calls
# them <tt>[]</tt>.
# * This library has a much faster parser.
#
@@ -58,9 +56,9 @@
# * CSV now has a new() method used to wrap objects like String and IO for
# reading and writing.
# * CSV::generate() is different from the old method.
-# * CSV no longer supports partial reads. It works line-by-line.
+# * CSV no longer supports partial reads. It works line-by-line.
# * CSV no longer allows the instance methods to override the separators for
-# performance reasons. They must be set in the constructor.
+# performance reasons. They must be set in the constructor.
#
# If you use this library and find yourself missing any functionality I have
# trimmed, please {let me know}[mailto:james@grayproductions.net].
@@ -72,16 +70,16 @@
# == What is CSV, really?
#
# CSV maintains a pretty strict definition of CSV taken directly from
-# {the RFC}[http://www.ietf.org/rfc/rfc4180.txt]. I relax the rules in only one
-# place and that is to make using this library easier. CSV will parse all valid
+# {the RFC}[http://www.ietf.org/rfc/rfc4180.txt]. I relax the rules in only one
+# place and that is to make using this library easier. CSV will parse all valid
# CSV.
#
-# What you don't want to do is feed CSV invalid data. Because of the way the
+# What you don't want to do is to feed CSV invalid data. Because of the way the
# CSV format works, it's common for a parser to need to read until the end of
-# the file to be sure a field is invalid. This eats a lot of time and memory.
+# the file to be sure a field is invalid. This consumes a lot of time and memory.
#
# Luckily, when working with invalid CSV, Ruby's built-in methods will almost
-# always be superior in every way. For example, parsing non-quoted fields is as
+# always be superior in every way. For example, parsing non-quoted fields is as
# easy as:
#
# data.split(",")
@@ -96,1870 +94,2385 @@ require "English"
require "date"
require "stringio"
+require_relative "csv/fields_converter"
+require_relative "csv/match_p"
+require_relative "csv/parser"
+require_relative "csv/row"
+require_relative "csv/table"
+require_relative "csv/writer"
+
+using CSV::MatchP if CSV.const_defined?(:MatchP)
+
+# == \CSV
+# \CSV (comma-separated variables) data is a text representation of a table:
+# - A _row_ _separator_ delimits table rows.
+# A common row separator is the newline character <tt>"\n"</tt>.
+# - A _column_ _separator_ delimits fields in a row.
+# A common column separator is the comma character <tt>","</tt>.
#
-# This class provides a complete interface to CSV files and data. It offers
-# tools to enable you to read and write to and from Strings or IO objects, as
-# needed.
+# This \CSV \String, with row separator <tt>"\n"</tt>
+# and column separator <tt>","</tt>,
+# has three rows and two columns:
+# "foo,0\nbar,1\nbaz,2\n"
#
-# == Reading
+# Despite the name \CSV, a \CSV representation can use different separators.
#
-# === From a File
+# For more about tables, see the Wikipedia article
+# "{Table (information)}[https://en.wikipedia.org/wiki/Table_(information)]",
+# especially its section
+# "{Simple table}[https://en.wikipedia.org/wiki/Table_(information)#Simple_table]"
#
-# ==== A Line at a Time
+# == \Class \CSV
#
-# CSV.foreach("path/to/file.csv") do |row|
-# # use row here...
+# Class \CSV provides methods for:
+# - Parsing \CSV data from a \String object, a \File (via its file path), or an \IO object.
+# - Generating \CSV data to a \String object.
+#
+# To make \CSV available:
+# require 'csv'
+#
+# All examples here assume that this has been done.
+#
+# == Keeping It Simple
+#
+# A \CSV object has dozens of instance methods that offer fine-grained control
+# of parsing and generating \CSV data.
+# For many needs, though, simpler approaches will do.
+#
+# This section summarizes the singleton methods in \CSV
+# that allow you to parse and generate without explicitly
+# creating \CSV objects.
+# For details, follow the links.
+#
+# === Simple Parsing
+#
+# Parsing methods commonly return either of:
+# - An \Array of Arrays of Strings:
+# - The outer \Array is the entire "table".
+# - Each inner \Array is a row.
+# - Each \String is a field.
+# - A CSV::Table object. For details, see
+# {\CSV with Headers}[#class-CSV-label-CSV+with+Headers].
+#
+# ==== Parsing a \String
+#
+# The input to be parsed can be a string:
+# string = "foo,0\nbar,1\nbaz,2\n"
+#
+# \Method CSV.parse returns the entire \CSV data:
+# CSV.parse(string) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+#
+# \Method CSV.parse_line returns only the first row:
+# CSV.parse_line(string) # => ["foo", "0"]
+#
+# \CSV extends class \String with instance method String#parse_csv,
+# which also returns only the first row:
+# string.parse_csv # => ["foo", "0"]
+#
+# ==== Parsing Via a \File Path
+#
+# The input to be parsed can be in a file:
+# string = "foo,0\nbar,1\nbaz,2\n"
+# path = 't.csv'
+# File.write(path, string)
+#
+# \Method CSV.read returns the entire \CSV data:
+# CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+#
+# \Method CSV.foreach iterates, passing each row to the given block:
+# CSV.foreach(path) do |row|
+# p row
+# end
+# Output:
+# ["foo", "0"]
+# ["bar", "1"]
+# ["baz", "2"]
+#
+# \Method CSV.table returns the entire \CSV data as a CSV::Table object:
+# CSV.table(path) # => #<CSV::Table mode:col_or_row row_count:3>
+#
+# ==== Parsing from an Open \IO Stream
+#
+# The input to be parsed can be in an open \IO stream:
+#
+# \Method CSV.read returns the entire \CSV data:
+# File.open(path) do |file|
+# CSV.read(file)
+# end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+#
+# As does method CSV.parse:
+# File.open(path) do |file|
+# CSV.parse(file)
+# end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+#
+# \Method CSV.parse_line returns only the first row:
+# File.open(path) do |file|
+# CSV.parse_line(file)
+# end # => ["foo", "0"]
+#
+# \Method CSV.foreach iterates, passing each row to the given block:
+# File.open(path) do |file|
+# CSV.foreach(file) do |row|
+# p row
+# end
# end
+# Output:
+# ["foo", "0"]
+# ["bar", "1"]
+# ["baz", "2"]
#
-# ==== All at Once
+# \Method CSV.table returns the entire \CSV data as a CSV::Table object:
+# File.open(path) do |file|
+# CSV.table(file)
+# end # => #<CSV::Table mode:col_or_row row_count:3>
#
-# arr_of_arrs = CSV.read("path/to/file.csv")
+# === Simple Generating
#
-# === From a String
+# \Method CSV.generate returns a \String;
+# this example uses method CSV#<< to append the rows
+# that are to be generated:
+# output_string = CSV.generate do |csv|
+# csv << ['foo', 0]
+# csv << ['bar', 1]
+# csv << ['baz', 2]
+# end
+# output_string # => "foo,0\nbar,1\nbaz,2\n"
+#
+# \Method CSV.generate_line returns a \String containing the single row
+# constructed from an \Array:
+# CSV.generate_line(['foo', '0']) # => "foo,0\n"
+#
+# \CSV extends class \Array with instance method <tt>Array#to_csv</tt>,
+# which forms an \Array into a \String:
+# ['foo', '0'].to_csv # => "foo,0\n"
#
-# ==== A Line at a Time
+# === "Filtering" \CSV
#
-# CSV.parse("CSV,data,String") do |row|
-# # use row here...
+# \Method CSV.filter provides a Unix-style filter for \CSV data.
+# The input data is processed to form the output data:
+# in_string = "foo,0\nbar,1\nbaz,2\n"
+# out_string = ''
+# CSV.filter(in_string, out_string) do |row|
+# row[0] = row[0].upcase
+# row[1] *= 4
# end
+# out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
+#
+# == \CSV Objects
+#
+# There are three ways to create a \CSV object:
+# - \Method CSV.new returns a new \CSV object.
+# - \Method CSV.instance returns a new or cached \CSV object.
+# - \Method \CSV() also returns a new or cached \CSV object.
+#
+# === Instance Methods
+#
+# \CSV has three groups of instance methods:
+# - Its own internally defined instance methods.
+# - Methods included by module Enumerable.
+# - Methods delegated to class IO. See below.
+#
+# ==== Delegated Methods
+#
+# For convenience, a CSV object will delegate to many methods in class IO.
+# (A few have wrapper "guard code" in \CSV.) You may call:
+# * IO#binmode
+# * #binmode?
+# * IO#close
+# * IO#close_read
+# * IO#close_write
+# * IO#closed?
+# * #eof
+# * #eof?
+# * IO#external_encoding
+# * IO#fcntl
+# * IO#fileno
+# * #flock
+# * IO#flush
+# * IO#fsync
+# * IO#internal_encoding
+# * #ioctl
+# * IO#isatty
+# * #path
+# * IO#pid
+# * IO#pos
+# * IO#pos=
+# * IO#reopen
+# * #rewind
+# * IO#seek
+# * #stat
+# * IO#string
+# * IO#sync
+# * IO#sync=
+# * IO#tell
+# * #to_i
+# * #to_io
+# * IO#truncate
+# * IO#tty?
+#
+# === Options
+#
+# The default values for options are:
+# DEFAULT_OPTIONS = {
+# # For both parsing and generating.
+# col_sep: ",",
+# row_sep: :auto,
+# quote_char: '"',
+# # For parsing.
+# field_size_limit: nil,
+# converters: nil,
+# unconverted_fields: nil,
+# headers: false,
+# return_headers: false,
+# header_converters: nil,
+# skip_blanks: false,
+# skip_lines: nil,
+# liberal_parsing: false,
+# nil_value: nil,
+# empty_value: "",
+# # For generating.
+# write_headers: nil,
+# quote_empty: true,
+# force_quotes: false,
+# write_converters: nil,
+# write_nil_value: nil,
+# write_empty_value: "",
+# strip: false,
+# }
+#
+# ==== Options for Parsing
+#
+# Options for parsing, described in detail below, include:
+# - +row_sep+: Specifies the row separator; used to delimit rows.
+# - +col_sep+: Specifies the column separator; used to delimit fields.
+# - +quote_char+: Specifies the quote character; used to quote fields.
+# - +field_size_limit+: Specifies the maximum field size allowed.
+# - +converters+: Specifies the field converters to be used.
+# - +unconverted_fields+: Specifies whether unconverted fields are to be available.
+# - +headers+: Specifies whether data contains headers,
+# or specifies the headers themselves.
+# - +return_headers+: Specifies whether headers are to be returned.
+# - +header_converters+: Specifies the header converters to be used.
+# - +skip_blanks+: Specifies whether blanks lines are to be ignored.
+# - +skip_lines+: Specifies how comments lines are to be recognized.
+# - +strip+: Specifies whether leading and trailing whitespace are
+# to be stripped from fields..
+# - +liberal_parsing+: Specifies whether \CSV should attempt to parse
+# non-compliant data.
+# - +nil_value+: Specifies the object that is to be substituted for each null (no-text) field.
+# - +empty_value+: Specifies the object that is to be substituted for each empty field.
+#
+# :include: ../doc/csv/options/common/row_sep.rdoc
+#
+# :include: ../doc/csv/options/common/col_sep.rdoc
+#
+# :include: ../doc/csv/options/common/quote_char.rdoc
+#
+# :include: ../doc/csv/options/parsing/field_size_limit.rdoc
+#
+# :include: ../doc/csv/options/parsing/converters.rdoc
+#
+# :include: ../doc/csv/options/parsing/unconverted_fields.rdoc
+#
+# :include: ../doc/csv/options/parsing/headers.rdoc
+#
+# :include: ../doc/csv/options/parsing/return_headers.rdoc
+#
+# :include: ../doc/csv/options/parsing/header_converters.rdoc
+#
+# :include: ../doc/csv/options/parsing/skip_blanks.rdoc
#
-# ==== All at Once
+# :include: ../doc/csv/options/parsing/skip_lines.rdoc
#
-# arr_of_arrs = CSV.parse("CSV,data,String")
+# :include: ../doc/csv/options/parsing/strip.rdoc
#
-# == Writing
+# :include: ../doc/csv/options/parsing/liberal_parsing.rdoc
#
-# === To a File
+# :include: ../doc/csv/options/parsing/nil_value.rdoc
#
-# CSV.open("path/to/file.csv", "wb") do |csv|
-# csv << ["row", "of", "CSV", "data"]
-# csv << ["another", "row"]
-# # ...
+# :include: ../doc/csv/options/parsing/empty_value.rdoc
+#
+# ==== Options for Generating
+#
+# Options for generating, described in detail below, include:
+# - +row_sep+: Specifies the row separator; used to delimit rows.
+# - +col_sep+: Specifies the column separator; used to delimit fields.
+# - +quote_char+: Specifies the quote character; used to quote fields.
+# - +write_headers+: Specifies whether headers are to be written.
+# - +force_quotes+: Specifies whether each output field is to be quoted.
+# - +quote_empty+: Specifies whether each empty output field is to be quoted.
+# - +write_converters+: Specifies the field converters to be used in writing.
+# - +write_nil_value+: Specifies the object that is to be substituted for each +nil+-valued field.
+# - +write_empty_value+: Specifies the object that is to be substituted for each empty field.
+#
+# :include: ../doc/csv/options/common/row_sep.rdoc
+#
+# :include: ../doc/csv/options/common/col_sep.rdoc
+#
+# :include: ../doc/csv/options/common/quote_char.rdoc
+#
+# :include: ../doc/csv/options/generating/write_headers.rdoc
+#
+# :include: ../doc/csv/options/generating/force_quotes.rdoc
+#
+# :include: ../doc/csv/options/generating/quote_empty.rdoc
+#
+# :include: ../doc/csv/options/generating/write_converters.rdoc
+#
+# :include: ../doc/csv/options/generating/write_nil_value.rdoc
+#
+# :include: ../doc/csv/options/generating/write_empty_value.rdoc
+#
+# === \CSV with Headers
+#
+# CSV allows to specify column names of CSV file, whether they are in data, or
+# provided separately. If headers are specified, reading methods return an instance
+# of CSV::Table, consisting of CSV::Row.
+#
+# # Headers are part of data
+# data = CSV.parse(<<~ROWS, headers: true)
+# Name,Department,Salary
+# Bob,Engineering,1000
+# Jane,Sales,2000
+# John,Management,5000
+# ROWS
+#
+# data.class #=> CSV::Table
+# data.first #=> #<CSV::Row "Name":"Bob" "Department":"Engineering" "Salary":"1000">
+# data.first.to_h #=> {"Name"=>"Bob", "Department"=>"Engineering", "Salary"=>"1000"}
+#
+# # Headers provided by developer
+# data = CSV.parse('Bob,Engineering,1000', headers: %i[name department salary])
+# data.first #=> #<CSV::Row name:"Bob" department:"Engineering" salary:"1000">
+#
+# === \Converters
+#
+# By default, each value (field or header) parsed by \CSV is formed into a \String.
+# You can use a _field_ _converter_ or _header_ _converter_
+# to intercept and modify the parsed values:
+# - See {Field Converters}[#class-CSV-label-Field+Converters].
+# - See {Header Converters}[#class-CSV-label-Header+Converters].
+#
+# Also by default, each value to be written during generation is written 'as-is'.
+# You can use a _write_ _converter_ to modify values before writing.
+# - See {Write Converters}[#class-CSV-label-Write+Converters].
+#
+# ==== Specifying \Converters
+#
+# You can specify converters for parsing or generating in the +options+
+# argument to various \CSV methods:
+# - Option +converters+ for converting parsed field values.
+# - Option +header_converters+ for converting parsed header values.
+# - Option +write_converters+ for converting values to be written (generated).
+#
+# There are three forms for specifying converters:
+# - A converter proc: executable code to be used for conversion.
+# - A converter name: the name of a stored converter.
+# - A converter list: an array of converter procs, converter names, and converter lists.
+#
+# ===== Converter Procs
+#
+# This converter proc, +strip_converter+, accepts a value +field+
+# and returns <tt>field.strip</tt>:
+# strip_converter = proc {|field| field.strip }
+# In this call to <tt>CSV.parse</tt>,
+# the keyword argument <tt>converters: string_converter</tt>
+# specifies that:
+# - \Proc +string_converter+ is to be called for each parsed field.
+# - The converter's return value is to replace the +field+ value.
+# Example:
+# string = " foo , 0 \n bar , 1 \n baz , 2 \n"
+# array = CSV.parse(string, converters: strip_converter)
+# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+#
+# A converter proc can receive a second argument, +field_info+,
+# that contains details about the field.
+# This modified +strip_converter+ displays its arguments:
+# strip_converter = proc do |field, field_info|
+# p [field, field_info]
+# field.strip
# end
+# string = " foo , 0 \n bar , 1 \n baz , 2 \n"
+# array = CSV.parse(string, converters: strip_converter)
+# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+# Output:
+# [" foo ", #<struct CSV::FieldInfo index=0, line=1, header=nil>]
+# [" 0 ", #<struct CSV::FieldInfo index=1, line=1, header=nil>]
+# [" bar ", #<struct CSV::FieldInfo index=0, line=2, header=nil>]
+# [" 1 ", #<struct CSV::FieldInfo index=1, line=2, header=nil>]
+# [" baz ", #<struct CSV::FieldInfo index=0, line=3, header=nil>]
+# [" 2 ", #<struct CSV::FieldInfo index=1, line=3, header=nil>]
+# Each CSV::Info object shows:
+# - The 0-based field index.
+# - The 1-based line index.
+# - The field header, if any.
+#
+# ===== Stored \Converters
+#
+# A converter may be given a name and stored in a structure where
+# the parsing methods can find it by name.
+#
+# The storage structure for field converters is the \Hash CSV::Converters.
+# It has several built-in converter procs:
+# - <tt>:integer</tt>: converts each \String-embedded integer into a true \Integer.
+# - <tt>:float</tt>: converts each \String-embedded float into a true \Float.
+# - <tt>:date</tt>: converts each \String-embedded date into a true \Date.
+# - <tt>:date_time</tt>: converts each \String-embedded date-time into a true \DateTime
+# .
+# This example creates a converter proc, then stores it:
+# strip_converter = proc {|field| field.strip }
+# CSV::Converters[:strip] = strip_converter
+# Then the parsing method call can refer to the converter
+# by its name, <tt>:strip</tt>:
+# string = " foo , 0 \n bar , 1 \n baz , 2 \n"
+# array = CSV.parse(string, converters: :strip)
+# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+#
+# The storage structure for header converters is the \Hash CSV::HeaderConverters,
+# which works in the same way.
+# It also has built-in converter procs:
+# - <tt>:downcase</tt>: Downcases each header.
+# - <tt>:symbol</tt>: Converts each header to a \Symbol.
+#
+# There is no such storage structure for write headers.
+#
+# ===== Converter Lists
+#
+# A _converter_ _list_ is an \Array that may include any assortment of:
+# - Converter procs.
+# - Names of stored converters.
+# - Nested converter lists.
+#
+# Examples:
+# numeric_converters = [:integer, :float]
+# date_converters = [:date, :date_time]
+# [numeric_converters, strip_converter]
+# [strip_converter, date_converters, :float]
+#
+# Like a converter proc, a converter list may be named and stored in either
+# \CSV::Converters or CSV::HeaderConverters:
+# CSV::Converters[:custom] = [strip_converter, date_converters, :float]
+# CSV::HeaderConverters[:custom] = [:downcase, :symbol]
+#
+# There are two built-in converter lists:
+# CSV::Converters[:numeric] # => [:integer, :float]
+# CSV::Converters[:all] # => [:date_time, :numeric]
#
-# === To a String
+# ==== Field \Converters
#
-# csv_string = CSV.generate do |csv|
-# csv << ["row", "of", "CSV", "data"]
-# csv << ["another", "row"]
-# # ...
+# With no conversion, all parsed fields in all rows become Strings:
+# string = "foo,0\nbar,1\nbaz,2\n"
+# ary = CSV.parse(string)
+# ary # => # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+#
+# When you specify a field converter, each parsed field is passed to the converter;
+# its return value becomes the stored value for the field.
+# A converter might, for example, convert an integer embedded in a \String
+# into a true \Integer.
+# (In fact, that's what built-in field converter +:integer+ does.)
+#
+# There are three ways to use field \converters.
+#
+# - Using option {converters}[#class-CSV-label-Option+converters] with a parsing method:
+# ary = CSV.parse(string, converters: :integer)
+# ary # => [0, 1, 2] # => [["foo", 0], ["bar", 1], ["baz", 2]]
+# - Using option {converters}[#class-CSV-label-Option+converters] with a new \CSV instance:
+# csv = CSV.new(string, converters: :integer)
+# # Field converters in effect:
+# csv.converters # => [:integer]
+# csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]]
+# - Using method #convert to add a field converter to a \CSV instance:
+# csv = CSV.new(string)
+# # Add a converter.
+# csv.convert(:integer)
+# csv.converters # => [:integer]
+# csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]]
+#
+# Installing a field converter does not affect already-read rows:
+# csv = CSV.new(string)
+# csv.shift # => ["foo", "0"]
+# # Add a converter.
+# csv.convert(:integer)
+# csv.converters # => [:integer]
+# csv.read # => [["bar", 1], ["baz", 2]]
+#
+# There are additional built-in \converters, and custom \converters are also supported.
+#
+# ===== Built-In Field \Converters
+#
+# The built-in field converters are in \Hash CSV::Converters:
+# - Each key is a field converter name.
+# - Each value is one of:
+# - A \Proc field converter.
+# - An \Array of field converter names.
+#
+# Display:
+# CSV::Converters.each_pair do |name, value|
+# if value.kind_of?(Proc)
+# p [name, value.class]
+# else
+# p [name, value]
+# end
# end
+# Output:
+# [:integer, Proc]
+# [:float, Proc]
+# [:numeric, [:integer, :float]]
+# [:date, Proc]
+# [:date_time, Proc]
+# [:all, [:date_time, :numeric]]
+#
+# Each of these converters transcodes values to UTF-8 before attempting conversion.
+# If a value cannot be transcoded to UTF-8 the conversion will
+# fail and the value will remain unconverted.
+#
+# Converter +:integer+ converts each field that Integer() accepts:
+# data = '0,1,2,x'
+# # Without the converter
+# csv = CSV.parse_line(data)
+# csv # => ["0", "1", "2", "x"]
+# # With the converter
+# csv = CSV.parse_line(data, converters: :integer)
+# csv # => [0, 1, 2, "x"]
+#
+# Converter +:float+ converts each field that Float() accepts:
+# data = '1.0,3.14159,x'
+# # Without the converter
+# csv = CSV.parse_line(data)
+# csv # => ["1.0", "3.14159", "x"]
+# # With the converter
+# csv = CSV.parse_line(data, converters: :float)
+# csv # => [1.0, 3.14159, "x"]
#
-# == Convert a Single Line
+# Converter +:numeric+ converts with both +:integer+ and +:float+..
#
-# csv_string = ["CSV", "data"].to_csv # to CSV
-# csv_array = "CSV,String".parse_csv # from CSV
+# Converter +:date+ converts each field that Date::parse accepts:
+# data = '2001-02-03,x'
+# # Without the converter
+# csv = CSV.parse_line(data)
+# csv # => ["2001-02-03", "x"]
+# # With the converter
+# csv = CSV.parse_line(data, converters: :date)
+# csv # => [#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>, "x"]
#
-# == Shortcut Interface
+# Converter +:date_time+ converts each field that DateTime::parse accepts:
+# data = '2020-05-07T14:59:00-05:00,x'
+# # Without the converter
+# csv = CSV.parse_line(data)
+# csv # => ["2020-05-07T14:59:00-05:00", "x"]
+# # With the converter
+# csv = CSV.parse_line(data, converters: :date_time)
+# csv # => [#<DateTime: 2020-05-07T14:59:00-05:00 ((2458977j,71940s,0n),-18000s,2299161j)>, "x"]
#
-# CSV { |csv_out| csv_out << %w{my data here} } # to $stdout
-# CSV(csv = "") { |csv_str| csv_str << %w{my data here} } # to a String
-# CSV($stderr) { |csv_err| csv_err << %w{my data here} } # to $stderr
-# CSV($stdin) { |csv_in| csv_in.each { |row| p row } } # from $stdin
+# Converter +:numeric+ converts with both +:date_time+ and +:numeric+..
#
-# == Advanced Usage
+# As seen above, method #convert adds \converters to a \CSV instance,
+# and method #converters returns an \Array of the \converters in effect:
+# csv = CSV.new('0,1,2')
+# csv.converters # => []
+# csv.convert(:integer)
+# csv.converters # => [:integer]
+# csv.convert(:date)
+# csv.converters # => [:integer, :date]
#
-# === Wrap an IO Object
+# ===== Custom Field \Converters
#
-# csv = CSV.new(io, options)
-# # ... read (with gets() or each()) from and write (with <<) to csv here ...
+# You can define a custom field converter:
+# strip_converter = proc {|field| field.strip }
+# string = " foo , 0 \n bar , 1 \n baz , 2 \n"
+# array = CSV.parse(string, converters: strip_converter)
+# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+# You can register the converter in \Converters \Hash,
+# which allows you to refer to it by name:
+# CSV::Converters[:strip] = strip_converter
+# string = " foo , 0 \n bar , 1 \n baz , 2 \n"
+# array = CSV.parse(string, converters: :strip)
+# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
#
-# == CSV and Character Encodings (M17n or Multilingualization)
+# ==== Header \Converters
+#
+# Header converters operate only on headers (and not on other rows).
+#
+# There are three ways to use header \converters;
+# these examples use built-in header converter +:dowhcase+,
+# which downcases each parsed header.
+#
+# - Option +header_converters+ with a singleton parsing method:
+# string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2"
+# tbl = CSV.parse(string, headers: true, header_converters: :downcase)
+# tbl.class # => CSV::Table
+# tbl.headers # => ["name", "count"]
+#
+# - Option +header_converters+ with a new \CSV instance:
+# csv = CSV.new(string, header_converters: :downcase)
+# # Header converters in effect:
+# csv.header_converters # => [:downcase]
+# tbl = CSV.parse(string, headers: true)
+# tbl.headers # => ["Name", "Count"]
+#
+# - Method #header_convert adds a header converter to a \CSV instance:
+# csv = CSV.new(string)
+# # Add a header converter.
+# csv.header_convert(:downcase)
+# csv.header_converters # => [:downcase]
+# tbl = CSV.parse(string, headers: true)
+# tbl.headers # => ["Name", "Count"]
+#
+# ===== Built-In Header \Converters
+#
+# The built-in header \converters are in \Hash CSV::HeaderConverters.
+# The keys there are the names of the \converters:
+# CSV::HeaderConverters.keys # => [:downcase, :symbol]
+#
+# Converter +:downcase+ converts each header by downcasing it:
+# string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2"
+# tbl = CSV.parse(string, headers: true, header_converters: :downcase)
+# tbl.class # => CSV::Table
+# tbl.headers # => ["name", "count"]
+#
+# Converter +:symbol+ converts each header by making it into a \Symbol:
+# string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2"
+# tbl = CSV.parse(string, headers: true, header_converters: :symbol)
+# tbl.headers # => [:name, :count]
+# Details:
+# - Strips leading and trailing whitespace.
+# - Downcases the header.
+# - Replaces embedded spaces with underscores.
+# - Removes non-word characters.
+# - Makes the string into a \Symbol.
+#
+# ===== Custom Header \Converters
+#
+# You can define a custom header converter:
+# upcase_converter = proc {|header| header.upcase }
+# string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+# table = CSV.parse(string, headers: true, header_converters: upcase_converter)
+# table # => #<CSV::Table mode:col_or_row row_count:4>
+# table.headers # => ["NAME", "VALUE"]
+# You can register the converter in \HeaderConverters \Hash,
+# which allows you to refer to it by name:
+# CSV::HeaderConverters[:upcase] = upcase_converter
+# table = CSV.parse(string, headers: true, header_converters: :upcase)
+# table # => #<CSV::Table mode:col_or_row row_count:4>
+# table.headers # => ["NAME", "VALUE"]
+#
+# ===== Write \Converters
+#
+# When you specify a write converter for generating \CSV,
+# each field to be written is passed to the converter;
+# its return value becomes the new value for the field.
+# A converter might, for example, strip whitespace from a field.
+#
+# Using no write converter (all fields unmodified):
+# output_string = CSV.generate do |csv|
+# csv << [' foo ', 0]
+# csv << [' bar ', 1]
+# csv << [' baz ', 2]
+# end
+# output_string # => " foo ,0\n bar ,1\n baz ,2\n"
+# Using option +write_converters+ with two custom write converters:
+# strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field }
+# upcase_converter = proc {|field| field.respond_to?(:upcase) ? field.upcase : field }
+# write_converters = [strip_converter, upcase_converter]
+# output_string = CSV.generate(write_converters: write_converters) do |csv|
+# csv << [' foo ', 0]
+# csv << [' bar ', 1]
+# csv << [' baz ', 2]
+# end
+# output_string # => "FOO,0\nBAR,1\nBAZ,2\n"
+#
+# === Character Encodings (M17n or Multilingualization)
#
# This new CSV parser is m17n savvy. The parser works in the Encoding of the IO
-# or String object being read from or written to. Your data is never transcoded
+# or String object being read from or written to. Your data is never transcoded
# (unless you ask Ruby to transcode it for you) and will literally be parsed in
-# the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the
-# Encoding of your data. This is accomplished by transcoding the parser itself
+# the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the
+# Encoding of your data. This is accomplished by transcoding the parser itself
# into your Encoding.
#
# Some transcoding must take place, of course, to accomplish this multiencoding
-# support. For example, <tt>:col_sep</tt>, <tt>:row_sep</tt>, and
+# support. For example, <tt>:col_sep</tt>, <tt>:row_sep</tt>, and
# <tt>:quote_char</tt> must be transcoded to match your data. Hopefully this
# makes the entire process feel transparent, since CSV's defaults should just
-# magically work for your data. However, you can set these values manually in
+# magically work for your data. However, you can set these values manually in
# the target Encoding to avoid the translation.
#
# It's also important to note that while all of CSV's core parser is now
-# Encoding agnostic, some features are not. For example, the built-in
+# Encoding agnostic, some features are not. For example, the built-in
# converters will try to transcode data to UTF-8 before making conversions.
# Again, you can provide custom converters that are aware of your Encodings to
-# avoid this translation. It's just too hard for me to support native
+# avoid this translation. It's just too hard for me to support native
# conversions in all of Ruby's Encodings.
#
-# Anyway, the practical side of this is simple: make sure IO and String objects
+# Anyway, the practical side of this is simple: make sure IO and String objects
# passed into CSV have the proper Encoding set and everything should just work.
# CSV methods that allow you to open IO objects (CSV::foreach(), CSV::open(),
# CSV::read(), and CSV::readlines()) do allow you to specify the Encoding.
#
# One minor exception comes when generating CSV into a String with an Encoding
-# that is not ASCII compatible. There's no existing data for CSV to use to
+# that is not ASCII compatible. There's no existing data for CSV to use to
# prepare itself and thus you will probably need to manually specify the desired
-# Encoding for most of those cases. It will try to guess using the fields in a
+# Encoding for most of those cases. It will try to guess using the fields in a
# row of output though, when using CSV::generate_line() or Array#to_csv().
#
# I try to point out any other Encoding issues in the documentation of methods
# as they come up.
#
# This has been tested to the best of my ability with all non-"dummy" Encodings
-# Ruby ships with. However, it is brave new code and may have some bugs.
+# Ruby ships with. However, it is brave new code and may have some bugs.
# Please feel free to {report}[mailto:james@grayproductions.net] any issues you
# find with it.
#
class CSV
- # The version of the installed library.
- VERSION = "2.4.8"
+
+ # The error thrown when the parser encounters illegal CSV formatting.
+ class MalformedCSVError < RuntimeError
+ attr_reader :line_number
+ alias_method :lineno, :line_number
+ def initialize(message, line_number)
+ @line_number = line_number
+ super("#{message} in line #{line_number}.")
+ end
+ end
#
- # A CSV::Row is part Array and part Hash. It retains an order for the fields
- # and allows duplicates just as an Array would, but also allows you to access
- # fields by name just as you could if they were in a Hash.
+ # A FieldInfo Struct contains details about a field's position in the data
+ # source it was read from. CSV will pass this Struct to some blocks that make
+ # decisions based on field structure. See CSV.convert_fields() for an
+ # example.
#
- # All rows returned by CSV will be constructed from this class, if header row
- # processing is activated.
+ # <b><tt>index</tt></b>:: The zero-based index of the field in its row.
+ # <b><tt>line</tt></b>:: The line of the data source this row is from.
+ # <b><tt>header</tt></b>:: The header for the column, when available.
#
- class Row
- #
- # Construct a new CSV::Row from +headers+ and +fields+, which are expected
- # to be Arrays. If one Array is shorter than the other, it will be padded
- # with +nil+ objects.
- #
- # The optional +header_row+ parameter can be set to +true+ to indicate, via
- # CSV::Row.header_row?() and CSV::Row.field_row?(), that this is a header
- # row. Otherwise, the row is assumes to be a field row.
- #
- # A CSV::Row object supports the following Array methods through delegation:
- #
- # * empty?()
- # * length()
- # * size()
- #
- def initialize(headers, fields, header_row = false)
- @header_row = header_row
- headers.each { |h| h.freeze if h.is_a? String }
-
- # handle extra headers or fields
- @row = if headers.size >= fields.size
- headers.zip(fields)
- else
- fields.zip(headers).each(&:reverse!)
- end
- end
-
- # Internal data format used to compare equality.
- attr_reader :row
- protected :row
-
- ### Array Delegation ###
+ FieldInfo = Struct.new(:index, :line, :header)
- extend Forwardable
- def_delegators :@row, :empty?, :length, :size
+ # A Regexp used to find and convert some common Date formats.
+ DateMatcher = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} |
+ \d{4}-\d{2}-\d{2} )\z /x
+ # A Regexp used to find and convert some common DateTime formats.
+ DateTimeMatcher =
+ / \A(?: (\w+,?\s+)?\w+\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2},?\s+\d{2,4} |
+ \d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2} |
+ # ISO-8601
+ \d{4}-\d{2}-\d{2}
+ (?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?(?:[+-]\d{2}(?::\d{2})|Z)?)?)?
+ )\z /x
- # Returns +true+ if this is a header row.
- def header_row?
- @header_row
- end
+ # The encoding used by all converters.
+ ConverterEncoding = Encoding.find("UTF-8")
- # Returns +true+ if this is a field row.
- def field_row?
- not header_row?
- end
+ # A \Hash containing the names and \Procs for the built-in field converters.
+ # See {Built-In Field Converters}[#class-CSV-label-Built-In+Field+Converters].
+ #
+ # This \Hash is intentionally left unfrozen, and may be extended with
+ # custom field converters.
+ # See {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters].
+ Converters = {
+ integer: lambda { |f|
+ Integer(f.encode(ConverterEncoding)) rescue f
+ },
+ float: lambda { |f|
+ Float(f.encode(ConverterEncoding)) rescue f
+ },
+ numeric: [:integer, :float],
+ date: lambda { |f|
+ begin
+ e = f.encode(ConverterEncoding)
+ e.match?(DateMatcher) ? Date.parse(e) : f
+ rescue # encoding conversion or date parse errors
+ f
+ end
+ },
+ date_time: lambda { |f|
+ begin
+ e = f.encode(ConverterEncoding)
+ e.match?(DateTimeMatcher) ? DateTime.parse(e) : f
+ rescue # encoding conversion or date parse errors
+ f
+ end
+ },
+ all: [:date_time, :numeric],
+ }
- # Returns the headers of this row.
- def headers
- @row.map(&:first)
- end
+ # A \Hash containing the names and \Procs for the built-in header converters.
+ # See {Built-In Header Converters}[#class-CSV-label-Built-In+Header+Converters].
+ #
+ # This \Hash is intentionally left unfrozen, and may be extended with
+ # custom field converters.
+ # See {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters].
+ HeaderConverters = {
+ downcase: lambda { |h| h.encode(ConverterEncoding).downcase },
+ symbol: lambda { |h|
+ h.encode(ConverterEncoding).downcase.gsub(/[^\s\w]+/, "").strip.
+ gsub(/\s+/, "_").to_sym
+ }
+ }
+ # Default values for method options.
+ DEFAULT_OPTIONS = {
+ # For both parsing and generating.
+ col_sep: ",",
+ row_sep: :auto,
+ quote_char: '"',
+ # For parsing.
+ field_size_limit: nil,
+ converters: nil,
+ unconverted_fields: nil,
+ headers: false,
+ return_headers: false,
+ header_converters: nil,
+ skip_blanks: false,
+ skip_lines: nil,
+ liberal_parsing: false,
+ nil_value: nil,
+ empty_value: "",
+ # For generating.
+ write_headers: nil,
+ quote_empty: true,
+ force_quotes: false,
+ write_converters: nil,
+ write_nil_value: nil,
+ write_empty_value: "",
+ strip: false,
+ }.freeze
- #
+ class << self
# :call-seq:
- # field( header )
- # field( header, offset )
- # field( index )
- #
- # This method will return the field value by +header+ or +index+. If a field
- # is not found, +nil+ is returned.
- #
- # When provided, +offset+ ensures that a header match occurs on or later
- # than the +offset+ index. You can use this to find duplicate headers,
- # without resorting to hard-coding exact indices.
- #
- def field(header_or_index, minimum_index = 0)
- # locate the pair
- finder = (header_or_index.is_a?(Integer) || header_or_index.is_a?(Range)) ? :[] : :assoc
- pair = @row[minimum_index..-1].send(finder, header_or_index)
-
- # return the field if we have a pair
- if pair.nil?
- nil
+ # instance(string, **options)
+ # instance(io = $stdout, **options)
+ # instance(string, **options) {|csv| ... }
+ # instance(io = $stdout, **options) {|csv| ... }
+ #
+ # Creates or retrieves cached \CSV objects.
+ # For arguments and options, see CSV.new.
+ #
+ # ---
+ #
+ # With no block given, returns a \CSV object.
+ #
+ # The first call to +instance+ creates and caches a \CSV object:
+ # s0 = 's0'
+ # csv0 = CSV.instance(s0)
+ # csv0.class # => CSV
+ #
+ # Subsequent calls to +instance+ with that _same_ +string+ or +io+
+ # retrieve that same cached object:
+ # csv1 = CSV.instance(s0)
+ # csv1.class # => CSV
+ # csv1.equal?(csv0) # => true # Same CSV object
+ #
+ # A subsequent call to +instance+ with a _different_ +string+ or +io+
+ # creates and caches a _different_ \CSV object.
+ # s1 = 's1'
+ # csv2 = CSV.instance(s1)
+ # csv2.equal?(csv0) # => false # Different CSV object
+ #
+ # All the cached objects remains available:
+ # csv3 = CSV.instance(s0)
+ # csv3.equal?(csv0) # true # Same CSV object
+ # csv4 = CSV.instance(s1)
+ # csv4.equal?(csv2) # true # Same CSV object
+ #
+ # ---
+ #
+ # When a block is given, calls the block with the created or retrieved
+ # \CSV object; returns the block's return value:
+ # CSV.instance(s0) {|csv| :foo } # => :foo
+ def instance(data = $stdout, **options)
+ # create a _signature_ for this method call, data object and options
+ sig = [data.object_id] +
+ options.values_at(*DEFAULT_OPTIONS.keys.sort_by { |sym| sym.to_s })
+
+ # fetch or create the instance for this signature
+ @@instances ||= Hash.new
+ instance = (@@instances[sig] ||= new(data, **options))
+
+ if block_given?
+ yield instance # run block, if given, returning result
else
- header_or_index.is_a?(Range) ? pair.map(&:last) : pair.last
+ instance # or return the instance
end
end
- alias_method :[], :field
- #
# :call-seq:
- # fetch( header )
- # fetch( header ) { |row| ... }
- # fetch( header, default )
- #
- # This method will fetch the field value by +header+. It has the same
- # behavior as Hash#fetch: if there is a field with the given +header+, its
- # value is returned. Otherwise, if a block is given, it is yielded the
- # +header+ and its result is returned; if a +default+ is given as the
- # second argument, it is returned; otherwise a KeyError is raised.
- #
- def fetch(header, *varargs)
- raise ArgumentError, "Too many arguments" if varargs.length > 1
- pair = @row.assoc(header)
- if pair
- pair.last
- else
- if block_given?
- yield header
- elsif varargs.empty?
- raise KeyError, "key not found: #{header}"
+ # filter(**options) {|row| ... }
+ # filter(in_string, **options) {|row| ... }
+ # filter(in_io, **options) {|row| ... }
+ # filter(in_string, out_string, **options) {|row| ... }
+ # filter(in_string, out_io, **options) {|row| ... }
+ # filter(in_io, out_string, **options) {|row| ... }
+ # filter(in_io, out_io, **options) {|row| ... }
+ #
+ # Reads \CSV input and writes \CSV output.
+ #
+ # For each input row:
+ # - Forms the data into:
+ # - A CSV::Row object, if headers are in use.
+ # - An \Array of Arrays, otherwise.
+ # - Calls the block with that object.
+ # - Appends the block's return value to the output.
+ #
+ # Arguments:
+ # * \CSV source:
+ # * Argument +in_string+, if given, should be a \String object;
+ # it will be put into a new StringIO object positioned at the beginning.
+ # * Argument +in_io+, if given, should be an IO object that is
+ # open for reading; on return, the IO object will be closed.
+ # * If neither +in_string+ nor +in_io+ is given,
+ # the input stream defaults to {ARGF}[https://ruby-doc.org/core/ARGF.html].
+ # * \CSV output:
+ # * Argument +out_string+, if given, should be a \String object;
+ # it will be put into a new StringIO object positioned at the beginning.
+ # * Argument +out_io+, if given, should be an IO object that is
+ # ppen for writing; on return, the IO object will be closed.
+ # * If neither +out_string+ nor +out_io+ is given,
+ # the output stream defaults to <tt>$stdout</tt>.
+ # * Argument +options+ should be keyword arguments.
+ # - Each argument name that is prefixed with +in_+ or +input_+
+ # is stripped of its prefix and is treated as an option
+ # for parsing the input.
+ # Option +input_row_sep+ defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>.
+ # - Each argument name that is prefixed with +out_+ or +output_+
+ # is stripped of its prefix and is treated as an option
+ # for generating the output.
+ # Option +output_row_sep+ defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>.
+ # - Each argument not prefixed as above is treated as an option
+ # both for parsing the input and for generating the output.
+ # - See {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
+ # and {Options for Generating}[#class-CSV-label-Options+for+Generating].
+ #
+ # Example:
+ # in_string = "foo,0\nbar,1\nbaz,2\n"
+ # out_string = ''
+ # CSV.filter(in_string, out_string) do |row|
+ # row[0] = row[0].upcase
+ # row[1] *= 4
+ # end
+ # out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
+ def filter(input=nil, output=nil, **options)
+ # parse options for input, output, or both
+ in_options, out_options = Hash.new, {row_sep: $INPUT_RECORD_SEPARATOR}
+ options.each do |key, value|
+ case key.to_s
+ when /\Ain(?:put)?_(.+)\Z/
+ in_options[$1.to_sym] = value
+ when /\Aout(?:put)?_(.+)\Z/
+ out_options[$1.to_sym] = value
else
- varargs.first
+ in_options[key] = value
+ out_options[key] = value
end
end
- end
- # Returns +true+ if there is a field with the given +header+.
- def has_key?(header)
- !!@row.assoc(header)
+ # build input and output wrappers
+ input = new(input || ARGF, **in_options)
+ output = new(output || $stdout, **out_options)
+
+ # process headers
+ need_manual_header_output =
+ (in_options[:headers] and
+ out_options[:headers] == true and
+ out_options[:write_headers])
+ if need_manual_header_output
+ first_row = input.shift
+ if first_row
+ if first_row.is_a?(Row)
+ headers = first_row.headers
+ yield headers
+ output << headers
+ end
+ yield first_row
+ output << first_row
+ end
+ end
+
+ # read, yield, write
+ input.each do |row|
+ yield row
+ output << row
+ end
end
- alias_method :include?, :has_key?
- alias_method :key?, :has_key?
- alias_method :member?, :has_key?
#
# :call-seq:
- # []=( header, value )
- # []=( header, offset, value )
- # []=( index, value )
- #
- # Looks up the field by the semantics described in CSV::Row.field() and
- # assigns the +value+.
- #
- # Assigning past the end of the row with an index will set all pairs between
- # to <tt>[nil, nil]</tt>. Assigning to an unused header appends the new
- # pair.
- #
- def []=(*args)
- value = args.pop
-
- if args.first.is_a? Integer
- if @row[args.first].nil? # extending past the end with index
- @row[args.first] = [nil, value]
- @row.map! { |pair| pair.nil? ? [nil, nil] : pair }
- else # normal index assignment
- @row[args.first][1] = value
- end
- else
- index = index(*args)
- if index.nil? # appending a field
- self << [args.first, value]
- else # normal header assignment
- @row[index][1] = value
- end
+ # foreach(path, mode='r', **options) {|row| ... )
+ # foreach(io, mode='r', **options {|row| ... )
+ # foreach(path, mode='r', headers: ..., **options) {|row| ... )
+ # foreach(io, mode='r', headers: ..., **options {|row| ... )
+ # foreach(path, mode='r', **options) -> new_enumerator
+ # foreach(io, mode='r', **options -> new_enumerator
+ #
+ # Calls the block with each row read from source +path+ or +io+.
+ #
+ # * Argument +path+, if given, must be the path to a file.
+ # :include: ../doc/csv/arguments/io.rdoc
+ # * Argument +mode+, if given, must be a \File mode
+ # See {Open Mode}[IO.html#method-c-new-label-Open+Mode].
+ # * Arguments <tt>**options</tt> must be keyword options.
+ # See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
+ # * This method optionally accepts an additional <tt>:encoding</tt> option
+ # that you can use to specify the Encoding of the data read from +path+ or +io+.
+ # You must provide this unless your data is in the encoding
+ # given by <tt>Encoding::default_external</tt>.
+ # Parsing will use this to determine how to parse the data.
+ # You may provide a second Encoding to
+ # have the data transcoded as it is read. For example,
+ # encoding: 'UTF-32BE:UTF-8'
+ # would read +UTF-32BE+ data from the file
+ # but transcode it to +UTF-8+ before parsing.
+ #
+ # ====== Without Option +headers+
+ #
+ # Without option +headers+, returns each row as an \Array object.
+ #
+ # These examples assume prior execution of:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ #
+ # Read rows from a file at +path+:
+ # CSV.foreach(path) {|row| p row }
+ # Output:
+ # ["foo", "0"]
+ # ["bar", "1"]
+ # ["baz", "2"]
+ #
+ # Read rows from an \IO object:
+ # File.open(path) do |file|
+ # CSV.foreach(file) {|row| p row }
+ # end
+ #
+ # Output:
+ # ["foo", "0"]
+ # ["bar", "1"]
+ # ["baz", "2"]
+ #
+ # Returns a new \Enumerator if no block given:
+ # CSV.foreach(path) # => #<Enumerator: CSV:foreach("t.csv", "r")>
+ # CSV.foreach(File.open(path)) # => #<Enumerator: CSV:foreach(#<File:t.csv>, "r")>
+ #
+ # Issues a warning if an encoding is unsupported:
+ # CSV.foreach(File.open(path), encoding: 'foo:bar') {|row| }
+ # Output:
+ # warning: Unsupported encoding foo ignored
+ # warning: Unsupported encoding bar ignored
+ #
+ # ====== With Option +headers+
+ #
+ # With {option +headers+}[#class-CSV-label-Option+headers],
+ # returns each row as a CSV::Row object.
+ #
+ # These examples assume prior execution of:
+ # string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ #
+ # Read rows from a file at +path+:
+ # CSV.foreach(path, headers: true) {|row| p row }
+ #
+ # Output:
+ # #<CSV::Row "Name":"foo" "Count":"0">
+ # #<CSV::Row "Name":"bar" "Count":"1">
+ # #<CSV::Row "Name":"baz" "Count":"2">
+ #
+ # Read rows from an \IO object:
+ # File.open(path) do |file|
+ # CSV.foreach(file, headers: true) {|row| p row }
+ # end
+ #
+ # Output:
+ # #<CSV::Row "Name":"foo" "Count":"0">
+ # #<CSV::Row "Name":"bar" "Count":"1">
+ # #<CSV::Row "Name":"baz" "Count":"2">
+ #
+ # ---
+ #
+ # Raises an exception if +path+ is a \String, but not the path to a readable file:
+ # # Raises Errno::ENOENT (No such file or directory @ rb_sysopen - nosuch.csv):
+ # CSV.foreach('nosuch.csv') {|row| }
+ #
+ # Raises an exception if +io+ is an \IO object, but not open for reading:
+ # io = File.open(path, 'w') {|row| }
+ # # Raises TypeError (no implicit conversion of nil into String):
+ # CSV.foreach(io) {|row| }
+ #
+ # Raises an exception if +mode+ is invalid:
+ # # Raises ArgumentError (invalid access mode nosuch):
+ # CSV.foreach(path, 'nosuch') {|row| }
+ #
+ def foreach(path, mode="r", **options, &block)
+ return to_enum(__method__, path, mode, **options) unless block_given?
+ open(path, mode, **options) do |csv|
+ csv.each(&block)
end
end
#
# :call-seq:
- # <<( field )
- # <<( header_and_field_array )
- # <<( header_and_field_hash )
- #
- # If a two-element Array is provided, it is assumed to be a header and field
- # and the pair is appended. A Hash works the same way with the key being
- # the header and the value being the field. Anything else is assumed to be
- # a lone field which is appended with a +nil+ header.
- #
- # This method returns the row for chaining.
- #
- def <<(arg)
- if arg.is_a?(Array) and arg.size == 2 # appending a header and name
- @row << arg
- elsif arg.is_a?(Hash) # append header and name pairs
- arg.each { |pair| @row << pair }
- else # append field value
- @row << [nil, arg]
+ # generate(csv_string, **options) {|csv| ... }
+ # generate(**options) {|csv| ... }
+ #
+ # * Argument +csv_string+, if given, must be a \String object;
+ # defaults to a new empty \String.
+ # * Arguments +options+, if given, should be generating options.
+ # See {Options for Generating}[#class-CSV-label-Options+for+Generating].
+ #
+ # ---
+ #
+ # Creates a new \CSV object via <tt>CSV.new(csv_string, **options)</tt>;
+ # calls the block with the \CSV object, which the block may modify;
+ # returns the \String generated from the \CSV object.
+ #
+ # Note that a passed \String *is* modified by this method.
+ # Pass <tt>csv_string</tt>.dup if the \String must be preserved.
+ #
+ # This method has one additional option: <tt>:encoding</tt>,
+ # which sets the base Encoding for the output if no no +str+ is specified.
+ # CSV needs this hint if you plan to output non-ASCII compatible data.
+ #
+ # ---
+ #
+ # Add lines:
+ # input_string = "foo,0\nbar,1\nbaz,2\n"
+ # output_string = CSV.generate(input_string) do |csv|
+ # csv << ['bat', 3]
+ # csv << ['bam', 4]
+ # end
+ # output_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n"
+ # input_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n"
+ # output_string.equal?(input_string) # => true # Same string, modified
+ #
+ # Add lines into new string, preserving old string:
+ # input_string = "foo,0\nbar,1\nbaz,2\n"
+ # output_string = CSV.generate(input_string.dup) do |csv|
+ # csv << ['bat', 3]
+ # csv << ['bam', 4]
+ # end
+ # output_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n"
+ # input_string # => "foo,0\nbar,1\nbaz,2\n"
+ # output_string.equal?(input_string) # => false # Different strings
+ #
+ # Create lines from nothing:
+ # output_string = CSV.generate do |csv|
+ # csv << ['foo', 0]
+ # csv << ['bar', 1]
+ # csv << ['baz', 2]
+ # end
+ # output_string # => "foo,0\nbar,1\nbaz,2\n"
+ #
+ # ---
+ #
+ # Raises an exception if +csv_string+ is not a \String object:
+ # # Raises TypeError (no implicit conversion of Integer into String)
+ # CSV.generate(0)
+ #
+ def generate(str=nil, **options)
+ encoding = options[:encoding]
+ # add a default empty String, if none was given
+ if str
+ str = StringIO.new(str)
+ str.seek(0, IO::SEEK_END)
+ str.set_encoding(encoding) if encoding
+ else
+ str = +""
+ str.force_encoding(encoding) if encoding
end
-
- self # for chaining
+ csv = new(str, **options) # wrap
+ yield csv # yield for appending
+ csv.string # return final String
end
+ # :call-seq:
+ # CSV.generate_line(ary)
+ # CSV.generate_line(ary, **options)
#
- # A shortcut for appending multiple fields. Equivalent to:
+ # Returns the \String created by generating \CSV from +ary+
+ # using the specified +options+.
#
- # args.each { |arg| csv_row << arg }
+ # Argument +ary+ must be an \Array.
#
- # This method returns the row for chaining.
+ # Special options:
+ # * Option <tt>:row_sep</tt> defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>
+ # (<tt>$/</tt>).:
+ # $INPUT_RECORD_SEPARATOR # => "\n"
+ # * This method accepts an additional option, <tt>:encoding</tt>, which sets the base
+ # Encoding for the output. This method will try to guess your Encoding from
+ # the first non-+nil+ field in +row+, if possible, but you may need to use
+ # this parameter as a backup plan.
#
- def push(*args)
- args.each { |arg| self << arg }
-
- self # for chaining
- end
-
+ # For other +options+,
+ # see {Options for Generating}[#class-CSV-label-Options+for+Generating].
#
- # :call-seq:
- # delete( header )
- # delete( header, offset )
- # delete( index )
- #
- # Used to remove a pair from the row by +header+ or +index+. The pair is
- # located as described in CSV::Row.field(). The deleted pair is returned,
- # or +nil+ if a pair could not be found.
- #
- def delete(header_or_index, minimum_index = 0)
- if header_or_index.is_a? Integer # by index
- @row.delete_at(header_or_index)
- elsif i = index(header_or_index, minimum_index) # by header
- @row.delete_at(i)
- else
- [ ]
- end
- end
-
+ # ---
#
- # The provided +block+ is passed a header and field for each pair in the row
- # and expected to return +true+ or +false+, depending on whether the pair
- # should be deleted.
+ # Returns the \String generated from an \Array:
+ # CSV.generate_line(['foo', '0']) # => "foo,0\n"
#
- # This method returns the row for chaining.
+ # ---
#
- # If no block is given, an Enumerator is returned.
+ # Raises an exception if +ary+ is not an \Array:
+ # # Raises NoMethodError (undefined method `find' for :foo:Symbol)
+ # CSV.generate_line(:foo)
#
- def delete_if(&block)
- block or return enum_for(__method__) { size }
-
- @row.delete_if(&block)
-
- self # for chaining
- end
-
- #
- # This method accepts any number of arguments which can be headers, indices,
- # Ranges of either, or two-element Arrays containing a header and offset.
- # Each argument will be replaced with a field lookup as described in
- # CSV::Row.field().
- #
- # If called with no arguments, all fields are returned.
- #
- def fields(*headers_and_or_indices)
- if headers_and_or_indices.empty? # return all fields--no arguments
- @row.map(&:last)
- else # or work like values_at()
- all = []
- headers_and_or_indices.each do |h_or_i|
- if h_or_i.is_a? Range
- index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin :
- index(h_or_i.begin)
- index_end = h_or_i.end.is_a?(Integer) ? h_or_i.end :
- index(h_or_i.end)
- new_range = h_or_i.exclude_end? ? (index_begin...index_end) :
- (index_begin..index_end)
- all.concat(fields.values_at(new_range))
- else
- all << field(*Array(h_or_i))
- end
+ def generate_line(row, **options)
+ options = {row_sep: $INPUT_RECORD_SEPARATOR}.merge(options)
+ str = +""
+ if options[:encoding]
+ str.force_encoding(options[:encoding])
+ else
+ fallback_encoding = nil
+ output_encoding = nil
+ row.each do |field|
+ next unless field.is_a?(String)
+ fallback_encoding ||= field.encoding
+ next if field.ascii_only?
+ output_encoding = field.encoding
+ break
+ end
+ output_encoding ||= fallback_encoding
+ if output_encoding
+ str.force_encoding(output_encoding)
end
- return all
end
+ (new(str, **options) << row).string
end
- alias_method :values_at, :fields
#
# :call-seq:
- # index( header )
- # index( header, offset )
- #
- # This method will return the index of a field with the provided +header+.
- # The +offset+ can be used to locate duplicate header names, as described in
- # CSV::Row.field().
- #
- def index(header, minimum_index = 0)
- # find the pair
- index = headers[minimum_index..-1].index(header)
- # return the index at the right offset, if we found one
- index.nil? ? nil : index + minimum_index
- end
+ # open(file_path, mode = "rb", **options ) -> new_csv
+ # open(io, mode = "rb", **options ) -> new_csv
+ # open(file_path, mode = "rb", **options ) { |csv| ... } -> object
+ # open(io, mode = "rb", **options ) { |csv| ... } -> object
+ #
+ # possible options elements:
+ # hash form:
+ # :invalid => nil # raise error on invalid byte sequence (default)
+ # :invalid => :replace # replace invalid byte sequence
+ # :undef => :replace # replace undefined conversion
+ # :replace => string # replacement string ("?" or "\uFFFD" if not specified)
+ #
+ # * Argument +path+, if given, must be the path to a file.
+ # :include: ../doc/csv/arguments/io.rdoc
+ # * Argument +mode+, if given, must be a \File mode
+ # See {Open Mode}[IO.html#method-c-new-label-Open+Mode].
+ # * Arguments <tt>**options</tt> must be keyword options.
+ # See {Options for Generating}[#class-CSV-label-Options+for+Generating].
+ # * This method optionally accepts an additional <tt>:encoding</tt> option
+ # that you can use to specify the Encoding of the data read from +path+ or +io+.
+ # You must provide this unless your data is in the encoding
+ # given by <tt>Encoding::default_external</tt>.
+ # Parsing will use this to determine how to parse the data.
+ # You may provide a second Encoding to
+ # have the data transcoded as it is read. For example,
+ # encoding: 'UTF-32BE:UTF-8'
+ # would read +UTF-32BE+ data from the file
+ # but transcode it to +UTF-8+ before parsing.
+ #
+ # ---
+ #
+ # These examples assume prior execution of:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ #
+ # ---
+ #
+ # With no block given, returns a new \CSV object.
+ #
+ # Create a \CSV object using a file path:
+ # csv = CSV.open(path)
+ # csv # => #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ #
+ # Create a \CSV object using an open \File:
+ # csv = CSV.open(File.open(path))
+ # csv # => #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ #
+ # ---
+ #
+ # With a block given, calls the block with the created \CSV object;
+ # returns the block's return value:
+ #
+ # Using a file path:
+ # csv = CSV.open(path) {|csv| p csv}
+ # csv # => #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ # Output:
+ # #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ #
+ # Using an open \File:
+ # csv = CSV.open(File.open(path)) {|csv| p csv}
+ # csv # => #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ # Output:
+ # #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ #
+ # ---
+ #
+ # Raises an exception if the argument is not a \String object or \IO object:
+ # # Raises TypeError (no implicit conversion of Symbol into String)
+ # CSV.open(:foo)
+ def open(filename, mode="r", **options)
+ # wrap a File opened with the remaining +args+ with no newline
+ # decorator
+ file_opts = {universal_newline: false}.merge(options)
+ options.delete(:invalid)
+ options.delete(:undef)
+ options.delete(:replace)
- # Returns +true+ if +name+ is a header for this row, and +false+ otherwise.
- def header?(name)
- headers.include? name
- end
- alias_method :include?, :header?
+ begin
+ f = File.open(filename, mode, **file_opts)
+ rescue ArgumentError => e
+ raise unless /needs binmode/.match?(e.message) and mode == "r"
+ mode = "rb"
+ file_opts = {encoding: Encoding.default_external}.merge(file_opts)
+ retry
+ end
+ begin
+ csv = new(f, **options)
+ rescue Exception
+ f.close
+ raise
+ end
- #
- # Returns +true+ if +data+ matches a field in this row, and +false+
- # otherwise.
- #
- def field?(data)
- fields.include? data
+ # handle blocks like Ruby's open(), not like the CSV library
+ if block_given?
+ begin
+ yield csv
+ ensure
+ csv.close
+ end
+ else
+ csv
+ end
end
- include Enumerable
-
#
- # Yields each pair of the row as header and field tuples (much like
- # iterating over a Hash). This method returns the row for chaining.
+ # :call-seq:
+ # parse(string) -> array_of_arrays
+ # parse(io) -> array_of_arrays
+ # parse(string, headers: ..., **options) -> csv_table
+ # parse(io, headers: ..., **options) -> csv_table
+ # parse(string, **options) {|row| ... }
+ # parse(io, **options) {|row| ... }
#
- # If no block is given, an Enumerator is returned.
+ # Parses +string+ or +io+ using the specified +options+.
#
- # Support for Enumerable.
+ # - Argument +string+ should be a \String object;
+ # it will be put into a new StringIO object positioned at the beginning.
+ # :include: ../doc/csv/arguments/io.rdoc
+ # - Argument +options+: see {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
#
- def each(&block)
- block or return enum_for(__method__) { size }
-
- @row.each(&block)
-
- self # for chaining
- end
-
+ # ====== Without Option +headers+
#
- # Returns +true+ if this row contains the same headers and fields in the
- # same order as +other+.
+ # Without {option +headers+}[#class-CSV-label-Option+headers] case.
#
- def ==(other)
- return @row == other.row if other.is_a? CSV::Row
- @row == other
- end
-
+ # These examples assume prior execution of:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
#
- # Collapses the row into a simple Hash. Be warned that this discards field
- # order and clobbers duplicate fields.
+ # ---
#
- def to_hash
- @row.to_h
- end
-
+ # With no block given, returns an \Array of Arrays formed from the source.
#
- # Returns the row as a CSV String. Headers are not used. Equivalent to:
+ # Parse a \String:
+ # a_of_a = CSV.parse(string)
+ # a_of_a # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
#
- # csv_row.fields.to_csv( options )
+ # Parse an open \File:
+ # a_of_a = File.open(path) do |file|
+ # CSV.parse(file)
+ # end
+ # a_of_a # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
#
- def to_csv(**options)
- fields.to_csv(options)
- end
- alias_method :to_s, :to_csv
-
- # A summary of fields, by header, in an ASCII compatible String.
- def inspect
- str = ["#<", self.class.to_s]
- each do |header, field|
- str << " " << (header.is_a?(Symbol) ? header.to_s : header.inspect) <<
- ":" << field.inspect
- end
- str << ">"
- begin
- str.join('')
- rescue # any encoding error
- str.map do |s|
- e = Encoding::Converter.asciicompat_encoding(s.encoding)
- e ? s.encode(e) : s.force_encoding("ASCII-8BIT")
- end.join('')
- end
- end
- end
-
- #
- # A CSV::Table is a two-dimensional data structure for representing CSV
- # documents. Tables allow you to work with the data by row or column,
- # manipulate the data, and even convert the results back to CSV, if needed.
- #
- # All tables returned by CSV will be constructed from this class, if header
- # row processing is activated.
- #
- class Table
- #
- # Construct a new CSV::Table from +array_of_rows+, which are expected
- # to be CSV::Row objects. All rows are assumed to have the same headers.
- #
- # A CSV::Table object supports the following Array methods through
- # delegation:
+ # ---
#
- # * empty?()
- # * length()
- # * size()
+ # With a block given, calls the block with each parsed row:
#
- def initialize(array_of_rows)
- @table = array_of_rows
- @mode = :col_or_row
- end
-
- # The current access mode for indexing and iteration.
- attr_reader :mode
-
- # Internal data format used to compare equality.
- attr_reader :table
- protected :table
-
- ### Array Delegation ###
-
- extend Forwardable
- def_delegators :@table, :empty?, :length, :size
-
+ # Parse a \String:
+ # CSV.parse(string) {|row| p row }
#
- # Returns a duplicate table object, in column mode. This is handy for
- # chaining in a single call without changing the table mode, but be aware
- # that this method can consume a fair amount of memory for bigger data sets.
+ # Output:
+ # ["foo", "0"]
+ # ["bar", "1"]
+ # ["baz", "2"]
#
- # This method returns the duplicate table for chaining. Don't chain
- # destructive methods (like []=()) this way though, since you are working
- # with a duplicate.
+ # Parse an open \File:
+ # File.open(path) do |file|
+ # CSV.parse(file) {|row| p row }
+ # end
#
- def by_col
- self.class.new(@table.dup).by_col!
- end
-
+ # Output:
+ # ["foo", "0"]
+ # ["bar", "1"]
+ # ["baz", "2"]
#
- # Switches the mode of this table to column mode. All calls to indexing and
- # iteration methods will work with columns until the mode is changed again.
+ # ====== With Option +headers+
#
- # This method returns the table and is safe to chain.
+ # With {option +headers+}[#class-CSV-label-Option+headers] case.
#
- def by_col!
- @mode = :col
-
- self
- end
-
+ # These examples assume prior execution of:
+ # string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
#
- # Returns a duplicate table object, in mixed mode. This is handy for
- # chaining in a single call without changing the table mode, but be aware
- # that this method can consume a fair amount of memory for bigger data sets.
+ # ---
#
- # This method returns the duplicate table for chaining. Don't chain
- # destructive methods (like []=()) this way though, since you are working
- # with a duplicate.
+ # With no block given, returns a CSV::Table object formed from the source.
#
- def by_col_or_row
- self.class.new(@table.dup).by_col_or_row!
- end
-
+ # Parse a \String:
+ # csv_table = CSV.parse(string, headers: ['Name', 'Count'])
+ # csv_table # => #<CSV::Table mode:col_or_row row_count:5>
#
- # Switches the mode of this table to mixed mode. All calls to indexing and
- # iteration methods will use the default intelligent indexing system until
- # the mode is changed again. In mixed mode an index is assumed to be a row
- # reference while anything else is assumed to be column access by headers.
+ # Parse an open \File:
+ # csv_table = File.open(path) do |file|
+ # CSV.parse(file, headers: ['Name', 'Count'])
+ # end
+ # csv_table # => #<CSV::Table mode:col_or_row row_count:4>
#
- # This method returns the table and is safe to chain.
+ # ---
#
- def by_col_or_row!
- @mode = :col_or_row
-
- self
- end
-
+ # With a block given, calls the block with each parsed row,
+ # which has been formed into a CSV::Row object:
#
- # Returns a duplicate table object, in row mode. This is handy for chaining
- # in a single call without changing the table mode, but be aware that this
- # method can consume a fair amount of memory for bigger data sets.
+ # Parse a \String:
+ # CSV.parse(string, headers: ['Name', 'Count']) {|row| p row }
#
- # This method returns the duplicate table for chaining. Don't chain
- # destructive methods (like []=()) this way though, since you are working
- # with a duplicate.
+ # Output:
+ # # <CSV::Row "Name":"foo" "Count":"0">
+ # # <CSV::Row "Name":"bar" "Count":"1">
+ # # <CSV::Row "Name":"baz" "Count":"2">
#
- def by_row
- self.class.new(@table.dup).by_row!
- end
-
+ # Parse an open \File:
+ # File.open(path) do |file|
+ # CSV.parse(file, headers: ['Name', 'Count']) {|row| p row }
+ # end
#
- # Switches the mode of this table to row mode. All calls to indexing and
- # iteration methods will work with rows until the mode is changed again.
+ # Output:
+ # # <CSV::Row "Name":"foo" "Count":"0">
+ # # <CSV::Row "Name":"bar" "Count":"1">
+ # # <CSV::Row "Name":"baz" "Count":"2">
#
- # This method returns the table and is safe to chain.
+ # ---
#
- def by_row!
- @mode = :row
+ # Raises an exception if the argument is not a \String object or \IO object:
+ # # Raises NoMethodError (undefined method `close' for :foo:Symbol)
+ # CSV.parse(:foo)
+ def parse(str, **options, &block)
+ csv = new(str, **options)
- self
- end
+ return csv.each(&block) if block_given?
- #
- # Returns the headers for the first row of this table (assumed to match all
- # other rows). An empty Array is returned for empty tables.
- #
- def headers
- if @table.empty?
- Array.new
- else
- @table.first.headers
+ # slurp contents, if no block is given
+ begin
+ csv.read
+ ensure
+ csv.close
end
end
+ # :call-seq:
+ # CSV.parse_line(string) -> new_array or nil
+ # CSV.parse_line(io) -> new_array or nil
+ # CSV.parse_line(string, **options) -> new_array or nil
+ # CSV.parse_line(io, **options) -> new_array or nil
+ # CSV.parse_line(string, headers: true, **options) -> csv_row or nil
+ # CSV.parse_line(io, headers: true, **options) -> csv_row or nil
#
- # In the default mixed mode, this method returns rows for index access and
- # columns for header access. You can force the index association by first
- # calling by_col!() or by_row!().
+ # Returns the data created by parsing the first line of +string+ or +io+
+ # using the specified +options+.
#
- # Columns are returned as an Array of values. Altering that Array has no
- # effect on the table.
+ # - Argument +string+ should be a \String object;
+ # it will be put into a new StringIO object positioned at the beginning.
+ # :include: ../doc/csv/arguments/io.rdoc
+ # - Argument +options+: see {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
#
- def [](index_or_header)
- if @mode == :row or # by index
- (@mode == :col_or_row and (index_or_header.is_a?(Integer) or index_or_header.is_a?(Range)))
- @table[index_or_header]
- else # by header
- @table.map { |row| row[index_or_header] }
- end
- end
-
- #
- # In the default mixed mode, this method assigns rows for index access and
- # columns for header access. You can force the index association by first
- # calling by_col!() or by_row!().
- #
- # Rows may be set to an Array of values (which will inherit the table's
- # headers()) or a CSV::Row.
+ # ====== Without Option +headers+
#
- # Columns may be set to a single value, which is copied to each row of the
- # column, or an Array of values. Arrays of values are assigned to rows top
- # to bottom in row major order. Excess values are ignored and if the Array
- # does not have a value for each row the extra rows will receive a +nil+.
+ # Without option +headers+, returns the first row as a new \Array.
#
- # Assigning to an existing column or row clobbers the data. Assigning to
- # new columns creates them at the right end of the table.
+ # These examples assume prior execution of:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
#
- def []=(index_or_header, value)
- if @mode == :row or # by index
- (@mode == :col_or_row and index_or_header.is_a? Integer)
- if value.is_a? Array
- @table[index_or_header] = Row.new(headers, value)
- else
- @table[index_or_header] = value
- end
- else # set column
- if value.is_a? Array # multiple values
- @table.each_with_index do |row, i|
- if row.header_row?
- row[index_or_header] = index_or_header
- else
- row[index_or_header] = value[i]
- end
- end
- else # repeated value
- @table.each do |row|
- if row.header_row?
- row[index_or_header] = index_or_header
- else
- row[index_or_header] = value
- end
- end
- end
- end
- end
-
+ # Parse the first line from a \String object:
+ # CSV.parse_line(string) # => ["foo", "0"]
#
- # The mixed mode default is to treat a list of indices as row access,
- # returning the rows indicated. Anything else is considered columnar
- # access. For columnar access, the return set has an Array for each row
- # with the values indicated by the headers in each Array. You can force
- # column or row mode using by_col!() or by_row!().
- #
- # You cannot mix column and row access.
- #
- def values_at(*indices_or_headers)
- if @mode == :row or # by indices
- ( @mode == :col_or_row and indices_or_headers.all? do |index|
- index.is_a?(Integer) or
- ( index.is_a?(Range) and
- index.first.is_a?(Integer) and
- index.last.is_a?(Integer) )
- end )
- @table.values_at(*indices_or_headers)
- else # by headers
- @table.map { |row| row.values_at(*indices_or_headers) }
- end
- end
-
+ # Parse the first line from a File object:
+ # File.open(path) do |file|
+ # CSV.parse_line(file) # => ["foo", "0"]
+ # end # => ["foo", "0"]
#
- # Adds a new row to the bottom end of this table. You can provide an Array,
- # which will be converted to a CSV::Row (inheriting the table's headers()),
- # or a CSV::Row.
+ # Returns +nil+ if the argument is an empty \String:
+ # CSV.parse_line('') # => nil
#
- # This method returns the table for chaining.
+ # ====== With Option +headers+
#
- def <<(row_or_array)
- if row_or_array.is_a? Array # append Array
- @table << Row.new(headers, row_or_array)
- else # append Row
- @table << row_or_array
- end
-
- self # for chaining
- end
-
+ # With {option +headers+}[#class-CSV-label-Option+headers],
+ # returns the first row as a CSV::Row object.
#
- # A shortcut for appending multiple rows. Equivalent to:
+ # These examples assume prior execution of:
+ # string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
#
- # rows.each { |row| self << row }
+ # Parse the first line from a \String object:
+ # CSV.parse_line(string, headers: true) # => #<CSV::Row "Name":"foo" "Count":"0">
#
- # This method returns the table for chaining.
+ # Parse the first line from a File object:
+ # File.open(path) do |file|
+ # CSV.parse_line(file, headers: true)
+ # end # => #<CSV::Row "Name":"foo" "Count":"0">
#
- def push(*rows)
- rows.each { |row| self << row }
-
- self # for chaining
- end
-
+ # ---
#
- # Removes and returns the indicated column or row. In the default mixed
- # mode indices refer to rows and everything else is assumed to be a column
- # header. Use by_col!() or by_row!() to force the lookup.
+ # Raises an exception if the argument is +nil+:
+ # # Raises ArgumentError (Cannot parse nil as CSV):
+ # CSV.parse_line(nil)
#
- def delete(index_or_header)
- if @mode == :row or # by index
- (@mode == :col_or_row and index_or_header.is_a? Integer)
- @table.delete_at(index_or_header)
- else # by header
- @table.map { |row| row.delete(index_or_header).last }
- end
+ def parse_line(line, **options)
+ new(line, **options).each.first
end
#
- # Removes any column or row for which the block returns +true+. In the
- # default mixed mode or row mode, iteration is the standard row major
- # walking of rows. In column mode, iteration will +yield+ two element
- # tuples containing the column name and an Array of values for that column.
+ # :call-seq:
+ # read(source, **options) -> array_of_arrays
+ # read(source, headers: true, **options) -> csv_table
#
- # This method returns the table for chaining.
+ # Opens the given +source+ with the given +options+ (see CSV.open),
+ # reads the source (see CSV#read), and returns the result,
+ # which will be either an \Array of Arrays or a CSV::Table.
#
- # If no block is given, an Enumerator is returned.
+ # Without headers:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ # CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
#
- def delete_if(&block)
- block or return enum_for(__method__) { @mode == :row or @mode == :col_or_row ? size : headers.size }
-
- if @mode == :row or @mode == :col_or_row # by index
- @table.delete_if(&block)
- else # by header
- deleted = []
- headers.each do |header|
- deleted << delete(header) if block[[header, self[header]]]
- end
- end
-
- self # for chaining
+ # With headers:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ # CSV.read(path, headers: true) # => #<CSV::Table mode:col_or_row row_count:4>
+ def read(path, **options)
+ open(path, **options) { |csv| csv.read }
end
- include Enumerable
-
- #
- # In the default mixed mode or row mode, iteration is the standard row major
- # walking of rows. In column mode, iteration will +yield+ two element
- # tuples containing the column name and an Array of values for that column.
- #
- # This method returns the table for chaining.
- #
- # If no block is given, an Enumerator is returned.
+ # :call-seq:
+ # CSV.readlines(source, **options)
#
- def each(&block)
- block or return enum_for(__method__) { @mode == :col ? headers.size : size }
-
- if @mode == :col
- headers.each { |header| block[[header, self[header]]] }
- else
- @table.each(&block)
- end
-
- self # for chaining
+ # Alias for CSV.read.
+ def readlines(path, **options)
+ read(path, **options)
end
- # Returns +true+ if all rows of this table ==() +other+'s rows.
- def ==(other)
- return @table == other.table if other.is_a? CSV::Table
- @table == other
+ # :call-seq:
+ # CSV.table(source, **options)
+ #
+ # Calls CSV.read with +source+, +options+, and certain default options:
+ # - +headers+: +true+
+ # - +converbers+: +:numeric+
+ # - +header_converters+: +:symbol+
+ #
+ # Returns a CSV::Table object.
+ #
+ # Example:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ # CSV.table(path) # => #<CSV::Table mode:col_or_row row_count:4>
+ def table(path, **options)
+ default_options = {
+ headers: true,
+ converters: :numeric,
+ header_converters: :symbol,
+ }
+ options = default_options.merge(options)
+ read(path, **options)
end
+ end
- #
- # Returns the table as an Array of Arrays. Headers will be the first row,
- # then all of the field rows will follow.
- #
- def to_a
- array = [headers]
- @table.each do |row|
- array.push(row.fields) unless row.header_row?
- end
- return array
- end
+ # :call-seq:
+ # CSV.new(string)
+ # CSV.new(io)
+ # CSV.new(string, **options)
+ # CSV.new(io, **options)
+ #
+ # Returns the new \CSV object created using +string+ or +io+
+ # and the specified +options+.
+ #
+ # - Argument +string+ should be a \String object;
+ # it will be put into a new StringIO object positioned at the beginning.
+ # :include: ../doc/csv/arguments/io.rdoc
+ # - Argument +options+: See:
+ # * {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
+ # * {Options for Generating}[#class-CSV-label-Options+for+Generating]
+ # For performance reasons, the options cannot be overridden
+ # in a \CSV object, so those specified here will endure.
+ #
+ # In addition to the \CSV instance methods, several \IO methods are delegated.
+ # See {Delegated Methods}[#class-CSV-label-Delegated+Methods].
+ #
+ # ---
+ #
+ # Create a \CSV object from a \String object:
+ # csv = CSV.new('foo,0')
+ # csv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ #
+ # Create a \CSV object from a \File object:
+ # File.write('t.csv', 'foo,0')
+ # csv = CSV.new(File.open('t.csv'))
+ # csv # => #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
+ #
+ # ---
+ #
+ # Raises an exception if the argument is +nil+:
+ # # Raises ArgumentError (Cannot parse nil as CSV):
+ # CSV.new(nil)
+ #
+ def initialize(data,
+ col_sep: ",",
+ row_sep: :auto,
+ quote_char: '"',
+ field_size_limit: nil,
+ converters: nil,
+ unconverted_fields: nil,
+ headers: false,
+ return_headers: false,
+ write_headers: nil,
+ header_converters: nil,
+ skip_blanks: false,
+ force_quotes: false,
+ skip_lines: nil,
+ liberal_parsing: false,
+ internal_encoding: nil,
+ external_encoding: nil,
+ encoding: nil,
+ nil_value: nil,
+ empty_value: "",
+ quote_empty: true,
+ write_converters: nil,
+ write_nil_value: nil,
+ write_empty_value: "",
+ strip: false)
+ raise ArgumentError.new("Cannot parse nil as CSV") if data.nil?
- #
- # Returns the table as a complete CSV String. Headers will be listed first,
- # then all of the field rows.
- #
- # This method assumes you want the Table.headers(), unless you explicitly
- # pass <tt>:write_headers => false</tt>.
- #
- def to_csv(write_headers: true, **options)
- array = write_headers ? [headers.to_csv(options)] : []
- @table.each do |row|
- array.push(row.fields.to_csv(options)) unless row.header_row?
- end
- return array.join('')
+ if data.is_a?(String)
+ @io = StringIO.new(data)
+ @io.set_encoding(encoding || data.encoding)
+ else
+ @io = data
end
- alias_method :to_s, :to_csv
+ @encoding = determine_encoding(encoding, internal_encoding)
- # Shows the mode and size of this table in a US-ASCII String.
- def inspect
- "#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>".encode("US-ASCII")
- end
- end
+ @base_fields_converter_options = {
+ nil_value: nil_value,
+ empty_value: empty_value,
+ }
+ @write_fields_converter_options = {
+ nil_value: write_nil_value,
+ empty_value: write_empty_value,
+ }
+ @initial_converters = converters
+ @initial_header_converters = header_converters
+ @initial_write_converters = write_converters
+
+ @parser_options = {
+ column_separator: col_sep,
+ row_separator: row_sep,
+ quote_character: quote_char,
+ field_size_limit: field_size_limit,
+ unconverted_fields: unconverted_fields,
+ headers: headers,
+ return_headers: return_headers,
+ skip_blanks: skip_blanks,
+ skip_lines: skip_lines,
+ liberal_parsing: liberal_parsing,
+ encoding: @encoding,
+ nil_value: nil_value,
+ empty_value: empty_value,
+ strip: strip,
+ }
+ @parser = nil
+ @parser_enumerator = nil
+ @eof_error = nil
+
+ @writer_options = {
+ encoding: @encoding,
+ force_encoding: (not encoding.nil?),
+ force_quotes: force_quotes,
+ headers: headers,
+ write_headers: write_headers,
+ column_separator: col_sep,
+ row_separator: row_sep,
+ quote_character: quote_char,
+ quote_empty: quote_empty,
+ }
- # The error thrown when the parser encounters illegal CSV formatting.
- class MalformedCSVError < RuntimeError; end
+ @writer = nil
+ writer if @writer_options[:write_headers]
+ end
+ # :call-seq:
+ # csv.col_sep -> string
#
- # A FieldInfo Struct contains details about a field's position in the data
- # source it was read from. CSV will pass this Struct to some blocks that make
- # decisions based on field structure. See CSV.convert_fields() for an
- # example.
- #
- # <b><tt>index</tt></b>:: The zero-based index of the field in its row.
- # <b><tt>line</tt></b>:: The line of the data source this row is from.
- # <b><tt>header</tt></b>:: The header for the column, when available.
- #
- FieldInfo = Struct.new(:index, :line, :header)
-
- # A Regexp used to find and convert some common Date formats.
- DateMatcher = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} |
- \d{4}-\d{2}-\d{2} )\z /x
- # A Regexp used to find and convert some common DateTime formats.
- DateTimeMatcher =
- / \A(?: (\w+,?\s+)?\w+\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2},?\s+\d{2,4} |
- \d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2} )\z /x
-
- # The encoding used by all converters.
- ConverterEncoding = Encoding.find("UTF-8")
+ # Returns the encoded column separator; used for parsing and writing;
+ # see {Option +col_sep+}[#class-CSV-label-Option+col_sep]:
+ # CSV.new('').col_sep # => ","
+ def col_sep
+ parser.column_separator
+ end
+ # :call-seq:
+ # csv.row_sep -> string
#
- # This Hash holds the built-in converters of CSV that can be accessed by name.
- # You can select Converters with CSV.convert() or through the +options+ Hash
- # passed to CSV::new().
- #
- # <b><tt>:integer</tt></b>:: Converts any field Integer() accepts.
- # <b><tt>:float</tt></b>:: Converts any field Float() accepts.
- # <b><tt>:numeric</tt></b>:: A combination of <tt>:integer</tt>
- # and <tt>:float</tt>.
- # <b><tt>:date</tt></b>:: Converts any field Date::parse() accepts.
- # <b><tt>:date_time</tt></b>:: Converts any field DateTime::parse() accepts.
- # <b><tt>:all</tt></b>:: All built-in converters. A combination of
- # <tt>:date_time</tt> and <tt>:numeric</tt>.
- #
- # All built-in converters transcode field data to UTF-8 before attempting a
- # conversion. If your data cannot be transcoded to UTF-8 the conversion will
- # fail and the field will remain unchanged.
- #
- # This Hash is intentionally left unfrozen and users should feel free to add
- # values to it that can be accessed by all CSV objects.
- #
- # To add a combo field, the value should be an Array of names. Combo fields
- # can be nested with other combo fields.
- #
- Converters = {
- integer: lambda { |f|
- Integer(f.encode(ConverterEncoding)) rescue f
- },
- float: lambda { |f|
- Float(f.encode(ConverterEncoding)) rescue f
- },
- numeric: [:integer, :float],
- date: lambda { |f|
- begin
- e = f.encode(ConverterEncoding)
- e =~ DateMatcher ? Date.parse(e) : f
- rescue # encoding conversion or date parse errors
- f
- end
- },
- date_time: lambda { |f|
- begin
- e = f.encode(ConverterEncoding)
- e =~ DateTimeMatcher ? DateTime.parse(e) : f
- rescue # encoding conversion or date parse errors
- f
- end
- },
- all: [:date_time, :numeric],
- }
+ # Returns the encoded row separator; used for parsing and writing;
+ # see {Option +row_sep+}[#class-CSV-label-Option+row_sep]:
+ # CSV.new('').row_sep # => "\n"
+ def row_sep
+ parser.row_separator
+ end
+ # :call-seq:
+ # csv.quote_char -> character
#
- # This Hash holds the built-in header converters of CSV that can be accessed
- # by name. You can select HeaderConverters with CSV.header_convert() or
- # through the +options+ Hash passed to CSV::new().
- #
- # <b><tt>:downcase</tt></b>:: Calls downcase() on the header String.
- # <b><tt>:symbol</tt></b>:: Leading/trailing spaces are dropped, string is
- # downcased, remaining spaces are replaced with
- # underscores, non-word characters are dropped,
- # and finally to_sym() is called.
- #
- # All built-in header converters transcode header data to UTF-8 before
- # attempting a conversion. If your data cannot be transcoded to UTF-8 the
- # conversion will fail and the header will remain unchanged.
- #
- # This Hash is intentionally left unfrozen and users should feel free to add
- # values to it that can be accessed by all CSV objects.
- #
- # To add a combo field, the value should be an Array of names. Combo fields
- # can be nested with other combo fields.
- #
- HeaderConverters = {
- downcase: lambda { |h| h.encode(ConverterEncoding).downcase },
- symbol: lambda { |h|
- h.encode(ConverterEncoding).downcase.gsub(/[^\s\w]+/, "").strip.
- gsub(/\s+/, "_").to_sym
- }
- }
+ # Returns the encoded quote character; used for parsing and writing;
+ # see {Option +quote_char+}[#class-CSV-label-Option+quote_char]:
+ # CSV.new('').quote_char # => "\""
+ def quote_char
+ parser.quote_character
+ end
+ # :call-seq:
+ # csv.field_size_limit -> integer or nil
#
- # The options used when no overrides are given by calling code. They are:
- #
- # <b><tt>:col_sep</tt></b>:: <tt>","</tt>
- # <b><tt>:row_sep</tt></b>:: <tt>:auto</tt>
- # <b><tt>:quote_char</tt></b>:: <tt>'"'</tt>
- # <b><tt>:field_size_limit</tt></b>:: +nil+
- # <b><tt>:converters</tt></b>:: +nil+
- # <b><tt>:unconverted_fields</tt></b>:: +nil+
- # <b><tt>:headers</tt></b>:: +false+
- # <b><tt>:return_headers</tt></b>:: +false+
- # <b><tt>:header_converters</tt></b>:: +nil+
- # <b><tt>:skip_blanks</tt></b>:: +false+
- # <b><tt>:force_quotes</tt></b>:: +false+
- # <b><tt>:skip_lines</tt></b>:: +nil+
- # <b><tt>:liberal_parsing</tt></b>:: +false+
- #
- DEFAULT_OPTIONS = {
- col_sep: ",",
- row_sep: :auto,
- quote_char: '"',
- field_size_limit: nil,
- converters: nil,
- unconverted_fields: nil,
- headers: false,
- return_headers: false,
- header_converters: nil,
- skip_blanks: false,
- force_quotes: false,
- skip_lines: nil,
- liberal_parsing: false,
- }.freeze
+ # Returns the limit for field size; used for parsing;
+ # see {Option +field_size_limit+}[#class-CSV-label-Option+field_size_limit]:
+ # CSV.new('').field_size_limit # => nil
+ def field_size_limit
+ parser.field_size_limit
+ end
+ # :call-seq:
+ # csv.skip_lines -> regexp or nil
#
- # This method will return a CSV instance, just like CSV::new(), but the
- # instance will be cached and returned for all future calls to this method for
- # the same +data+ object (tested by Object#object_id()) with the same
- # +options+.
- #
- # If a block is given, the instance is passed to the block and the return
- # value becomes the return value of the block.
- #
- def self.instance(data = $stdout, **options)
- # create a _signature_ for this method call, data object and options
- sig = [data.object_id] +
- options.values_at(*DEFAULT_OPTIONS.keys.sort_by { |sym| sym.to_s })
-
- # fetch or create the instance for this signature
- @@instances ||= Hash.new
- instance = (@@instances[sig] ||= new(data, options))
-
- if block_given?
- yield instance # run block, if given, returning result
- else
- instance # or return the instance
- end
+ # Returns the \Regexp used to identify comment lines; used for parsing;
+ # see {Option +skip_lines+}[#class-CSV-label-Option+skip_lines]:
+ # CSV.new('').skip_lines # => nil
+ def skip_lines
+ parser.skip_lines
end
- #
# :call-seq:
- # filter( **options ) { |row| ... }
- # filter( input, **options ) { |row| ... }
- # filter( input, output, **options ) { |row| ... }
- #
- # This method is a convenience for building Unix-like filters for CSV data.
- # Each row is yielded to the provided block which can alter it as needed.
- # After the block returns, the row is appended to +output+ altered or not.
- #
- # The +input+ and +output+ arguments can be anything CSV::new() accepts
- # (generally String or IO objects). If not given, they default to
- # <tt>ARGF</tt> and <tt>$stdout</tt>.
- #
- # The +options+ parameter is also filtered down to CSV::new() after some
- # clever key parsing. Any key beginning with <tt>:in_</tt> or
- # <tt>:input_</tt> will have that leading identifier stripped and will only
- # be used in the +options+ Hash for the +input+ object. Keys starting with
- # <tt>:out_</tt> or <tt>:output_</tt> affect only +output+. All other keys
- # are assigned to both objects.
- #
- # The <tt>:output_row_sep</tt> +option+ defaults to
- # <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
- #
- def self.filter(input=nil, output=nil, **options)
- # parse options for input, output, or both
- in_options, out_options = Hash.new, {row_sep: $INPUT_RECORD_SEPARATOR}
- options.each do |key, value|
- case key.to_s
- when /\Ain(?:put)?_(.+)\Z/
- in_options[$1.to_sym] = value
- when /\Aout(?:put)?_(.+)\Z/
- out_options[$1.to_sym] = value
- else
- in_options[key] = value
- out_options[key] = value
- end
- end
- # build input and output wrappers
- input = new(input || ARGF, in_options)
- output = new(output || $stdout, out_options)
-
- # read, yield, write
- input.each do |row|
- yield row
- output << row
+ # csv.converters -> array
+ #
+ # Returns an \Array containing field converters;
+ # see {Field Converters}[#class-CSV-label-Field+Converters]:
+ # csv = CSV.new('')
+ # csv.converters # => []
+ # csv.convert(:integer)
+ # csv.converters # => [:integer]
+ # csv.convert(proc {|x| x.to_s })
+ # csv.converters
+ def converters
+ parser_fields_converter.map do |converter|
+ name = Converters.rassoc(converter)
+ name ? name.first : converter
end
end
- #
- # This method is intended as the primary interface for reading CSV files. You
- # pass a +path+ and any +options+ you wish to set for the read. Each row of
- # file will be passed to the provided +block+ in turn.
- #
- # The +options+ parameter can be anything CSV::new() understands. This method
- # also understands an additional <tt>:encoding</tt> parameter that you can use
- # to specify the Encoding of the data in the file to be read. You must provide
- # this unless your data is in Encoding::default_external(). CSV will use this
- # to determine how to parse the data. You may provide a second Encoding to
- # have the data transcoded as it is read. For example,
- # <tt>encoding: "UTF-32BE:UTF-8"</tt> would read UTF-32BE data from the file
- # but transcode it to UTF-8 before CSV parses it.
- #
- def self.foreach(path, **options, &block)
- return to_enum(__method__, path, options) unless block
- open(path, options) do |csv|
- csv.each(&block)
- end
+ # :call-seq:
+ # csv.unconverted_fields? -> object
+ #
+ # Returns the value that determines whether unconverted fields are to be
+ # available; used for parsing;
+ # see {Option +unconverted_fields+}[#class-CSV-label-Option+unconverted_fields]:
+ # CSV.new('').unconverted_fields? # => nil
+ def unconverted_fields?
+ parser.unconverted_fields?
end
- #
# :call-seq:
- # generate( str, **options ) { |csv| ... }
- # generate( **options ) { |csv| ... }
- #
- # This method wraps a String you provide, or an empty default String, in a
- # CSV object which is passed to the provided block. You can use the block to
- # append CSV rows to the String and when the block exits, the final String
- # will be returned.
- #
- # Note that a passed String *is* modified by this method. Call dup() before
- # passing if you need a new String.
- #
- # The +options+ parameter can be anything CSV::new() understands. This method
- # understands an additional <tt>:encoding</tt> parameter when not passed a
- # String to set the base Encoding for the output. CSV needs this hint if you
- # plan to output non-ASCII compatible data.
- #
- def self.generate(str=nil, **options)
- # add a default empty String, if none was given
- if str
- io = StringIO.new(str)
- io.seek(0, IO::SEEK_END)
+ # csv.headers -> object
+ #
+ # Returns the value that determines whether headers are used; used for parsing;
+ # see {Option +headers+}[#class-CSV-label-Option+headers]:
+ # CSV.new('').headers # => nil
+ def headers
+ if @writer
+ @writer.headers
else
- encoding = options[:encoding]
- str = String.new
- str.force_encoding(encoding) if encoding
+ parsed_headers = parser.headers
+ return parsed_headers if parsed_headers
+ raw_headers = @parser_options[:headers]
+ raw_headers = nil if raw_headers == false
+ raw_headers
end
- csv = new(str, options) # wrap
- yield csv # yield for appending
- csv.string # return final String
end
+ # :call-seq:
+ # csv.return_headers? -> true or false
#
- # This method is a shortcut for converting a single row (Array) into a CSV
- # String.
- #
- # The +options+ parameter can be anything CSV::new() understands. This method
- # understands an additional <tt>:encoding</tt> parameter to set the base
- # Encoding for the output. This method will try to guess your Encoding from
- # the first non-+nil+ field in +row+, if possible, but you may need to use
- # this parameter as a backup plan.
- #
- # The <tt>:row_sep</tt> +option+ defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>
- # (<tt>$/</tt>) when calling this method.
- #
- def self.generate_line(row, **options)
- options = {row_sep: $INPUT_RECORD_SEPARATOR}.merge(options)
- str = String.new
- if options[:encoding]
- str.force_encoding(options[:encoding])
- elsif field = row.find { |f| not f.nil? }
- str.force_encoding(String(field).encoding)
- end
- (new(str, options) << row).string
+ # Returns the value that determines whether headers are to be returned; used for parsing;
+ # see {Option +return_headers+}[#class-CSV-label-Option+return_headers]:
+ # CSV.new('').return_headers? # => false
+ def return_headers?
+ parser.return_headers?
end
- #
# :call-seq:
- # open( filename, mode = "rb", **options ) { |faster_csv| ... }
- # open( filename, **options ) { |faster_csv| ... }
- # open( filename, mode = "rb", **options )
- # open( filename, **options )
- #
- # This method opens an IO object, and wraps that with CSV. This is intended
- # as the primary interface for writing a CSV file.
- #
- # You must pass a +filename+ and may optionally add a +mode+ for Ruby's
- # open(). You may also pass an optional Hash containing any +options+
- # CSV::new() understands as the final argument.
- #
- # This method works like Ruby's open() call, in that it will pass a CSV object
- # to a provided block and close it when the block terminates, or it will
- # return the CSV object when no block is provided. (*Note*: This is different
- # from the Ruby 1.8 CSV library which passed rows to the block. Use
- # CSV::foreach() for that behavior.)
- #
- # You must provide a +mode+ with an embedded Encoding designator unless your
- # data is in Encoding::default_external(). CSV will check the Encoding of the
- # underlying IO object (set by the +mode+ you pass) to determine how to parse
- # the data. You may provide a second Encoding to have the data transcoded as
- # it is read just as you can with a normal call to IO::open(). For example,
- # <tt>"rb:UTF-32BE:UTF-8"</tt> would read UTF-32BE data from the file but
- # transcode it to UTF-8 before CSV parses it.
- #
- # An opened CSV object will delegate to many IO methods for convenience. You
- # may call:
- #
- # * binmode()
- # * binmode?()
- # * close()
- # * close_read()
- # * close_write()
- # * closed?()
- # * eof()
- # * eof?()
- # * external_encoding()
- # * fcntl()
- # * fileno()
- # * flock()
- # * flush()
- # * fsync()
- # * internal_encoding()
- # * ioctl()
- # * isatty()
- # * path()
- # * pid()
- # * pos()
- # * pos=()
- # * reopen()
- # * seek()
- # * stat()
- # * sync()
- # * sync=()
- # * tell()
- # * to_i()
- # * to_io()
- # * truncate()
- # * tty?()
- #
- def self.open(filename, mode="r", **options)
- # wrap a File opened with the remaining +args+ with no newline
- # decorator
- file_opts = {universal_newline: false}.merge(options)
-
- begin
- f = File.open(filename, mode, file_opts)
- rescue ArgumentError => e
- raise unless /needs binmode/ =~ e.message and mode == "r"
- mode = "rb"
- file_opts = {encoding: Encoding.default_external}.merge(file_opts)
- retry
- end
- begin
- csv = new(f, options)
- rescue Exception
- f.close
- raise
- end
-
- # handle blocks like Ruby's open(), not like the CSV library
- if block_given?
- begin
- yield csv
- ensure
- csv.close
- end
- else
- csv
- end
+ # csv.write_headers? -> true or false
+ #
+ # Returns the value that determines whether headers are to be written; used for generating;
+ # see {Option +write_headers+}[#class-CSV-label-Option+write_headers]:
+ # CSV.new('').write_headers? # => nil
+ def write_headers?
+ @writer_options[:write_headers]
end
- #
# :call-seq:
- # parse( str, **options ) { |row| ... }
- # parse( str, **options )
- #
- # This method can be used to easily parse CSV out of a String. You may either
- # provide a +block+ which will be called with each row of the String in turn,
- # or just use the returned Array of Arrays (when no +block+ is given).
- #
- # You pass your +str+ to read from, and an optional +options+ containing
- # anything CSV::new() understands.
+ # csv.header_converters -> array
#
- def self.parse(*args, &block)
- csv = new(*args)
- if block.nil? # slurp contents, if no block is given
- begin
- csv.read
- ensure
- csv.close
- end
- else # or pass each row to a provided block
- csv.each(&block)
+ # Returns an \Array containing header converters; used for parsing;
+ # see {Header Converters}[#class-CSV-label-Header+Converters]:
+ # CSV.new('').header_converters # => []
+ def header_converters
+ header_fields_converter.map do |converter|
+ name = HeaderConverters.rassoc(converter)
+ name ? name.first : converter
end
end
+ # :call-seq:
+ # csv.skip_blanks? -> true or false
#
- # This method is a shortcut for converting a single line of a CSV String into
- # an Array. Note that if +line+ contains multiple rows, anything beyond the
- # first row is ignored.
- #
- # The +options+ parameter can be anything CSV::new() understands.
- #
- def self.parse_line(line, **options)
- new(line, options).shift
- end
-
- #
- # Use to slurp a CSV file into an Array of Arrays. Pass the +path+ to the
- # file and any +options+ CSV::new() understands. This method also understands
- # an additional <tt>:encoding</tt> parameter that you can use to specify the
- # Encoding of the data in the file to be read. You must provide this unless
- # your data is in Encoding::default_external(). CSV will use this to determine
- # how to parse the data. You may provide a second Encoding to have the data
- # transcoded as it is read. For example,
- # <tt>encoding: "UTF-32BE:UTF-8"</tt> would read UTF-32BE data from the file
- # but transcode it to UTF-8 before CSV parses it.
- #
- def self.read(path, *options)
- open(path, *options) { |csv| csv.read }
+ # Returns the value that determines whether blank lines are to be ignored; used for parsing;
+ # see {Option +skip_blanks+}[#class-CSV-label-Option+skip_blanks]:
+ # CSV.new('').skip_blanks? # => false
+ def skip_blanks?
+ parser.skip_blanks?
end
- # Alias for CSV::read().
- def self.readlines(*args)
- read(*args)
+ # :call-seq:
+ # csv.force_quotes? -> true or false
+ #
+ # Returns the value that determines whether all output fields are to be quoted;
+ # used for generating;
+ # see {Option +force_quotes+}[#class-CSV-label-Option+force_quotes]:
+ # CSV.new('').force_quotes? # => false
+ def force_quotes?
+ @writer_options[:force_quotes]
end
+ # :call-seq:
+ # csv.liberal_parsing? -> true or false
#
- # A shortcut for:
- #
- # CSV.read( path, { headers: true,
- # converters: :numeric,
- # header_converters: :symbol }.merge(options) )
- #
- def self.table(path, **options)
- read( path, { headers: true,
- converters: :numeric,
- header_converters: :symbol }.merge(options) )
+ # Returns the value that determines whether illegal input is to be handled; used for parsing;
+ # see {Option +liberal_parsing+}[#class-CSV-label-Option+liberal_parsing]:
+ # CSV.new('').liberal_parsing? # => false
+ def liberal_parsing?
+ parser.liberal_parsing?
end
+ # :call-seq:
+ # csv.encoding -> endcoding
#
- # This constructor will wrap either a String or IO object passed in +data+ for
- # reading and/or writing. In addition to the CSV instance methods, several IO
- # methods are delegated. (See CSV::open() for a complete list.) If you pass
- # a String for +data+, you can later retrieve it (after writing to it, for
- # example) with CSV.string().
- #
- # Note that a wrapped String will be positioned at the beginning (for
- # reading). If you want it at the end (for writing), use CSV::generate().
- # If you want any other positioning, pass a preset StringIO object instead.
- #
- # You may set any reading and/or writing preferences in the +options+ Hash.
- # Available options are:
- #
- # <b><tt>:col_sep</tt></b>:: The String placed between each field.
- # This String will be transcoded into
- # the data's Encoding before parsing.
- # <b><tt>:row_sep</tt></b>:: The String appended to the end of each
- # row. This can be set to the special
- # <tt>:auto</tt> setting, which requests
- # that CSV automatically discover this
- # from the data. Auto-discovery reads
- # ahead in the data looking for the next
- # <tt>"\r\n"</tt>, <tt>"\n"</tt>, or
- # <tt>"\r"</tt> sequence. A sequence
- # will be selected even if it occurs in
- # a quoted field, assuming that you
- # would have the same line endings
- # there. If none of those sequences is
- # found, +data+ is <tt>ARGF</tt>,
- # <tt>STDIN</tt>, <tt>STDOUT</tt>, or
- # <tt>STDERR</tt>, or the stream is only
- # available for output, the default
- # <tt>$INPUT_RECORD_SEPARATOR</tt>
- # (<tt>$/</tt>) is used. Obviously,
- # discovery takes a little time. Set
- # manually if speed is important. Also
- # note that IO objects should be opened
- # in binary mode on Windows if this
- # feature will be used as the
- # line-ending translation can cause
- # problems with resetting the document
- # position to where it was before the
- # read ahead. This String will be
- # transcoded into the data's Encoding
- # before parsing.
- # <b><tt>:quote_char</tt></b>:: The character used to quote fields.
- # This has to be a single character
- # String. This is useful for
- # application that incorrectly use
- # <tt>'</tt> as the quote character
- # instead of the correct <tt>"</tt>.
- # CSV will always consider a double
- # sequence of this character to be an
- # escaped quote. This String will be
- # transcoded into the data's Encoding
- # before parsing.
- # <b><tt>:field_size_limit</tt></b>:: This is a maximum size CSV will read
- # ahead looking for the closing quote
- # for a field. (In truth, it reads to
- # the first line ending beyond this
- # size.) If a quote cannot be found
- # within the limit CSV will raise a
- # MalformedCSVError, assuming the data
- # is faulty. You can use this limit to
- # prevent what are effectively DoS
- # attacks on the parser. However, this
- # limit can cause a legitimate parse to
- # fail and thus is set to +nil+, or off,
- # by default.
- # <b><tt>:converters</tt></b>:: An Array of names from the Converters
- # Hash and/or lambdas that handle custom
- # conversion. A single converter
- # doesn't have to be in an Array. All
- # built-in converters try to transcode
- # fields to UTF-8 before converting.
- # The conversion will fail if the data
- # cannot be transcoded, leaving the
- # field unchanged.
- # <b><tt>:unconverted_fields</tt></b>:: If set to +true+, an
- # unconverted_fields() method will be
- # added to all returned rows (Array or
- # CSV::Row) that will return the fields
- # as they were before conversion. Note
- # that <tt>:headers</tt> supplied by
- # Array or String were not fields of the
- # document and thus will have an empty
- # Array attached.
- # <b><tt>:headers</tt></b>:: If set to <tt>:first_row</tt> or
- # +true+, the initial row of the CSV
- # file will be treated as a row of
- # headers. If set to an Array, the
- # contents will be used as the headers.
- # If set to a String, the String is run
- # through a call of CSV::parse_line()
- # with the same <tt>:col_sep</tt>,
- # <tt>:row_sep</tt>, and
- # <tt>:quote_char</tt> as this instance
- # to produce an Array of headers. This
- # setting causes CSV#shift() to return
- # rows as CSV::Row objects instead of
- # Arrays and CSV#read() to return
- # CSV::Table objects instead of an Array
- # of Arrays.
- # <b><tt>:return_headers</tt></b>:: When +false+, header rows are silently
- # swallowed. If set to +true+, header
- # rows are returned in a CSV::Row object
- # with identical headers and
- # fields (save that the fields do not go
- # through the converters).
- # <b><tt>:write_headers</tt></b>:: When +true+ and <tt>:headers</tt> is
- # set, a header row will be added to the
- # output.
- # <b><tt>:header_converters</tt></b>:: Identical in functionality to
- # <tt>:converters</tt> save that the
- # conversions are only made to header
- # rows. All built-in converters try to
- # transcode headers to UTF-8 before
- # converting. The conversion will fail
- # if the data cannot be transcoded,
- # leaving the header unchanged.
- # <b><tt>:skip_blanks</tt></b>:: When set to a +true+ value, CSV will
- # skip over any empty rows. Note that
- # this setting will not skip rows that
- # contain column separators, even if
- # the rows contain no actual data. If
- # you want to skip rows that contain
- # separators but no content, consider
- # using <tt>:skip_lines</tt>, or
- # inspecting fields.compact.empty? on
- # each row.
- # <b><tt>:force_quotes</tt></b>:: When set to a +true+ value, CSV will
- # quote all CSV fields it creates.
- # <b><tt>:skip_lines</tt></b>:: When set to an object responding to
- # <tt>match</tt>, every line matching
- # it is considered a comment and ignored
- # during parsing. When set to a String,
- # it is first converted to a Regexp.
- # When set to +nil+ no line is considered
- # a comment. If the passed object does
- # not respond to <tt>match</tt>,
- # <tt>ArgumentError</tt> is thrown.
- # <b><tt>:liberal_parsing</tt></b>:: When set to a +true+ value, CSV will
- # attempt to parse input not conformant
- # with RFC 4180, such as double quotes
- # in unquoted fields.
- #
- # See CSV::DEFAULT_OPTIONS for the default settings.
- #
- # Options cannot be overridden in the instance methods for performance reasons,
- # so be sure to set what you want here.
- #
- def initialize(data, col_sep: ",", row_sep: :auto, quote_char: '"', field_size_limit: nil,
- converters: nil, unconverted_fields: nil, headers: false, return_headers: false,
- write_headers: nil, header_converters: nil, skip_blanks: false, force_quotes: false,
- skip_lines: nil, liberal_parsing: false, internal_encoding: nil, external_encoding: nil, encoding: nil)
- raise ArgumentError.new("Cannot parse nil as CSV") if data.nil?
+ # Returns the encoding used for parsing and generating;
+ # see {Character Encodings (M17n or Multilingualization)}[#class-CSV-label-Character+Encodings+-28M17n+or+Multilingualization-29]:
+ # CSV.new('').encoding # => #<Encoding:UTF-8>
+ attr_reader :encoding
- # create the IO object we will read from
- @io = data.is_a?(String) ? StringIO.new(data) : data
- # honor the IO encoding if we can, otherwise default to ASCII-8BIT
- internal_encoding = Encoding.find(internal_encoding) if internal_encoding
- external_encoding = Encoding.find(external_encoding) if external_encoding
- if encoding
- encoding, = encoding.split(":", 2) if encoding.is_a?(String)
- encoding = Encoding.find(encoding)
+ # :call-seq:
+ # csv.line_no -> integer
+ #
+ # Returns the count of the rows parsed or generated.
+ #
+ # Parsing:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ # CSV.open(path) do |csv|
+ # csv.each do |row|
+ # p [csv.lineno, row]
+ # end
+ # end
+ # Output:
+ # [1, ["foo", "0"]]
+ # [2, ["bar", "1"]]
+ # [3, ["baz", "2"]]
+ #
+ # Generating:
+ # CSV.generate do |csv|
+ # p csv.lineno; csv << ['foo', 0]
+ # p csv.lineno; csv << ['bar', 1]
+ # p csv.lineno; csv << ['baz', 2]
+ # end
+ # Output:
+ # 0
+ # 1
+ # 2
+ def lineno
+ if @writer
+ @writer.lineno
+ else
+ parser.lineno
end
- @encoding = raw_encoding(nil) || internal_encoding || encoding ||
- Encoding.default_internal || Encoding.default_external
- #
- # prepare for building safe regular expressions in the target encoding,
- # if we can transcode the needed characters
- #
- @re_esc = "\\".encode(@encoding).freeze rescue ""
- @re_chars = /#{%"[-\\]\\[\\.^$?*+{}()|# \r\n\t\f\v]".encode(@encoding)}/
- @unconverted_fields = unconverted_fields
-
- # Stores header row settings and loads header converters, if needed.
- @use_headers = headers
- @return_headers = return_headers
- @write_headers = write_headers
-
- # headers must be delayed until shift(), in case they need a row of content
- @headers = nil
-
- init_separators(col_sep, row_sep, quote_char, force_quotes)
- init_parsers(skip_blanks, field_size_limit, liberal_parsing)
- init_converters(converters, :@converters, :convert)
- init_converters(header_converters, :@header_converters, :header_convert)
- init_comments(skip_lines)
+ end
- @force_encoding = !!encoding
+ # :call-seq:
+ # csv.line -> array
+ #
+ # Returns the line most recently read:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ # CSV.open(path) do |csv|
+ # csv.each do |row|
+ # p [csv.lineno, csv.line]
+ # end
+ # end
+ # Output:
+ # [1, "foo,0\n"]
+ # [2, "bar,1\n"]
+ # [3, "baz,2\n"]
+ def line
+ parser.line
+ end
- # track our own lineno since IO gets confused about line-ends is CSV fields
- @lineno = 0
+ ### IO and StringIO Delegation ###
- # make sure headers have been assigned
- if header_row? and [Array, String].include? @use_headers.class and @write_headers
- parse_headers # won't read data for Array or String
- self << @headers
+ extend Forwardable
+ def_delegators :@io, :binmode, :close, :close_read, :close_write,
+ :closed?, :external_encoding, :fcntl,
+ :fileno, :flush, :fsync, :internal_encoding,
+ :isatty, :pid, :pos, :pos=, :reopen,
+ :seek, :string, :sync, :sync=, :tell,
+ :truncate, :tty?
+
+ def binmode?
+ if @io.respond_to?(:binmode?)
+ @io.binmode?
+ else
+ false
end
end
- #
- # The encoded <tt>:col_sep</tt> used in parsing and writing. See CSV::new
- # for details.
- #
- attr_reader :col_sep
- #
- # The encoded <tt>:row_sep</tt> used in parsing and writing. See CSV::new
- # for details.
- #
- attr_reader :row_sep
- #
- # The encoded <tt>:quote_char</tt> used in parsing and writing. See CSV::new
- # for details.
- #
- attr_reader :quote_char
- # The limit for field size, if any. See CSV::new for details.
- attr_reader :field_size_limit
-
- # The regex marking a line as a comment. See CSV::new for details
- attr_reader :skip_lines
-
- #
- # Returns the current list of converters in effect. See CSV::new for details.
- # Built-in converters will be returned by name, while others will be returned
- # as is.
- #
- def converters
- @converters.map do |converter|
- name = Converters.rassoc(converter)
- name ? name.first : converter
- end
+ def flock(*args)
+ raise NotImplementedError unless @io.respond_to?(:flock)
+ @io.flock(*args)
end
- #
- # Returns +true+ if unconverted_fields() to parsed results. See CSV::new
- # for details.
- #
- def unconverted_fields?() @unconverted_fields end
- #
- # Returns +nil+ if headers will not be used, +true+ if they will but have not
- # yet been read, or the actual headers after they have been read. See
- # CSV::new for details.
- #
- def headers
- @headers || true if @use_headers
+
+ def ioctl(*args)
+ raise NotImplementedError unless @io.respond_to?(:ioctl)
+ @io.ioctl(*args)
end
- #
- # Returns +true+ if headers will be returned as a row of results.
- # See CSV::new for details.
- #
- def return_headers?() @return_headers end
- # Returns +true+ if headers are written in output. See CSV::new for details.
- def write_headers?() @write_headers end
- #
- # Returns the current list of converters in effect for headers. See CSV::new
- # for details. Built-in converters will be returned by name, while others
- # will be returned as is.
- #
- def header_converters
- @header_converters.map do |converter|
- name = HeaderConverters.rassoc(converter)
- name ? name.first : converter
- end
+
+ def path
+ @io.path if @io.respond_to?(:path)
end
- #
- # Returns +true+ blank lines are skipped by the parser. See CSV::new
- # for details.
- #
- def skip_blanks?() @skip_blanks end
- # Returns +true+ if all output fields are quoted. See CSV::new for details.
- def force_quotes?() @force_quotes end
- # Returns +true+ if illegal input is handled. See CSV::new for details.
- def liberal_parsing?() @liberal_parsing end
- #
- # The Encoding CSV is parsing or writing in. This will be the Encoding you
- # receive parsed data in and/or the Encoding data will be written in.
- #
- attr_reader :encoding
+ def stat(*args)
+ raise NotImplementedError unless @io.respond_to?(:stat)
+ @io.stat(*args)
+ end
- #
- # The line number of the last row read from this file. Fields with nested
- # line-end characters will not affect this count.
- #
- attr_reader :lineno, :line
+ def to_i
+ raise NotImplementedError unless @io.respond_to?(:to_i)
+ @io.to_i
+ end
- ### IO and StringIO Delegation ###
+ def to_io
+ @io.respond_to?(:to_io) ? @io.to_io : @io
+ end
- extend Forwardable
- def_delegators :@io, :binmode, :binmode?, :close, :close_read, :close_write,
- :closed?, :eof, :eof?, :external_encoding, :fcntl,
- :fileno, :flock, :flush, :fsync, :internal_encoding,
- :ioctl, :isatty, :path, :pid, :pos, :pos=, :reopen,
- :seek, :stat, :string, :sync, :sync=, :tell, :to_i,
- :to_io, :truncate, :tty?
+ def eof?
+ return false if @eof_error
+ begin
+ parser_enumerator.peek
+ false
+ rescue MalformedCSVError => error
+ @eof_error = error
+ false
+ rescue StopIteration
+ true
+ end
+ end
+ alias_method :eof, :eof?
# Rewinds the underlying IO object and resets CSV's lineno() counter.
def rewind
- @headers = nil
- @lineno = 0
-
+ @parser = nil
+ @parser_enumerator = nil
+ @eof_error = nil
+ @writer.rewind if @writer
@io.rewind
end
### End Delegation ###
- #
- # The primary write method for wrapped Strings and IOs, +row+ (an Array or
- # CSV::Row) is converted to CSV and appended to the data source. When a
- # CSV::Row is passed, only the row's fields() are appended to the output.
- #
- # The data source must be open for writing.
- #
+ # :call-seq:
+ # csv << row -> self
+ #
+ # Appends a row to +self+.
+ #
+ # - Argument +row+ must be an \Array object or a CSV::Row object.
+ # - The output stream must be open for writing.
+ #
+ # ---
+ #
+ # Append Arrays:
+ # CSV.generate do |csv|
+ # csv << ['foo', 0]
+ # csv << ['bar', 1]
+ # csv << ['baz', 2]
+ # end # => "foo,0\nbar,1\nbaz,2\n"
+ #
+ # Append CSV::Rows:
+ # headers = []
+ # CSV.generate do |csv|
+ # csv << CSV::Row.new(headers, ['foo', 0])
+ # csv << CSV::Row.new(headers, ['bar', 1])
+ # csv << CSV::Row.new(headers, ['baz', 2])
+ # end # => "foo,0\nbar,1\nbaz,2\n"
+ #
+ # Headers in CSV::Row objects are not appended:
+ # headers = ['Name', 'Count']
+ # CSV.generate do |csv|
+ # csv << CSV::Row.new(headers, ['foo', 0])
+ # csv << CSV::Row.new(headers, ['bar', 1])
+ # csv << CSV::Row.new(headers, ['baz', 2])
+ # end # => "foo,0\nbar,1\nbaz,2\n"
+ #
+ # ---
+ #
+ # Raises an exception if +row+ is not an \Array or \CSV::Row:
+ # CSV.generate do |csv|
+ # # Raises NoMethodError (undefined method `collect' for :foo:Symbol)
+ # csv << :foo
+ # end
+ #
+ # Raises an exception if the output stream is not opened for writing:
+ # path = 't.csv'
+ # File.write(path, '')
+ # File.open(path) do |file|
+ # CSV.open(file) do |csv|
+ # # Raises IOError (not opened for writing)
+ # csv << ['foo', 0]
+ # end
+ # end
def <<(row)
- # make sure headers have been assigned
- if header_row? and [Array, String].include? @use_headers.class and !@write_headers
- parse_headers # won't read data for Array or String
- end
-
- # handle CSV::Row objects and Hashes
- row = case row
- when self.class::Row then row.fields
- when Hash then @headers.map { |header| row[header] }
- else row
- end
-
- @headers = row if header_row?
- @lineno += 1
-
- output = row.map(&@quote).join(@col_sep) + @row_sep # quote and separate
- if @io.is_a?(StringIO) and
- output.encoding != (encoding = raw_encoding)
- if @force_encoding
- output = output.encode(encoding)
- elsif (compatible_encoding = Encoding.compatible?(@io.string, output))
- @io.set_encoding(compatible_encoding)
- @io.seek(0, IO::SEEK_END)
- end
- end
- @io << output
-
- self # for chaining
+ writer << row
+ self
end
alias_method :add_row, :<<
alias_method :puts, :<<
- #
# :call-seq:
- # convert( name )
- # convert { |field| ... }
- # convert { |field, field_info| ... }
- #
- # You can use this method to install a CSV::Converters built-in, or provide a
- # block that handles a custom conversion.
- #
- # If you provide a block that takes one argument, it will be passed the field
- # and is expected to return the converted value or the field itself. If your
- # block takes two arguments, it will also be passed a CSV::FieldInfo Struct,
- # containing details about the field. Again, the block should return a
- # converted field or the field itself.
- #
+ # convert(converter_name) -> array_of_procs
+ # convert {|field, field_info| ... } -> array_of_procs
+ #
+ # - With no block, installs a field converter (a \Proc).
+ # - With a block, defines and installs a custom field converter.
+ # - Returns the \Array of installed field converters.
+ #
+ # - Argument +converter_name+, if given, should be the name
+ # of an existing field converter.
+ #
+ # See {Field Converters}[#class-CSV-label-Field+Converters].
+ # ---
+ #
+ # With no block, installs a field converter:
+ # csv = CSV.new('')
+ # csv.convert(:integer)
+ # csv.convert(:float)
+ # csv.convert(:date)
+ # csv.converters # => [:integer, :float, :date]
+ #
+ # ---
+ #
+ # The block, if given, is called for each field:
+ # - Argument +field+ is the field value.
+ # - Argument +field_info+ is a CSV::FieldInfo object
+ # containing details about the field.
+ #
+ # The examples here assume the prior execution of:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ #
+ # Example giving a block:
+ # csv = CSV.open(path)
+ # csv.convert {|field, field_info| p [field, field_info]; field.upcase }
+ # csv.read # => [["FOO", "0"], ["BAR", "1"], ["BAZ", "2"]]
+ #
+ # Output:
+ # ["foo", #<struct CSV::FieldInfo index=0, line=1, header=nil>]
+ # ["0", #<struct CSV::FieldInfo index=1, line=1, header=nil>]
+ # ["bar", #<struct CSV::FieldInfo index=0, line=2, header=nil>]
+ # ["1", #<struct CSV::FieldInfo index=1, line=2, header=nil>]
+ # ["baz", #<struct CSV::FieldInfo index=0, line=3, header=nil>]
+ # ["2", #<struct CSV::FieldInfo index=1, line=3, header=nil>]
+ #
+ # The block need not return a \String object:
+ # csv = CSV.open(path)
+ # csv.convert {|field, field_info| field.to_sym }
+ # csv.read # => [[:foo, :"0"], [:bar, :"1"], [:baz, :"2"]]
+ #
+ # If +converter_name+ is given, the block is not called:
+ # csv = CSV.open(path)
+ # csv.convert(:integer) {|field, field_info| fail 'Cannot happen' }
+ # csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]]
+ #
+ # ---
+ #
+ # Raises a parse-time exception if +converter_name+ is not the name of a built-in
+ # field converter:
+ # csv = CSV.open(path)
+ # csv.convert(:nosuch) => [nil]
+ # # Raises NoMethodError (undefined method `arity' for nil:NilClass)
+ # csv.read
def convert(name = nil, &converter)
- add_converter(:@converters, self.class::Converters, name, &converter)
+ parser_fields_converter.add_converter(name, &converter)
end
- #
# :call-seq:
- # header_convert( name )
- # header_convert { |field| ... }
- # header_convert { |field, field_info| ... }
- #
- # Identical to CSV#convert(), but for header rows.
- #
- # Note that this method must be called before header rows are read to have any
- # effect.
- #
+ # header_convert(converter_name) -> array_of_procs
+ # header_convert {|header, field_info| ... } -> array_of_procs
+ #
+ # - With no block, installs a header converter (a \Proc).
+ # - With a block, defines and installs a custom header converter.
+ # - Returns the \Array of installed header converters.
+ #
+ # - Argument +converter_name+, if given, should be the name
+ # of an existing header converter.
+ #
+ # See {Header Converters}[#class-CSV-label-Header+Converters].
+ # ---
+ #
+ # With no block, installs a header converter:
+ # csv = CSV.new('')
+ # csv.header_convert(:symbol)
+ # csv.header_convert(:downcase)
+ # csv.header_converters # => [:symbol, :downcase]
+ #
+ # ---
+ #
+ # The block, if given, is called for each header:
+ # - Argument +header+ is the header value.
+ # - Argument +field_info+ is a CSV::FieldInfo object
+ # containing details about the header.
+ #
+ # The examples here assume the prior execution of:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ #
+ # Example giving a block:
+ # csv = CSV.open(path, headers: true)
+ # csv.header_convert {|header, field_info| p [header, field_info]; header.upcase }
+ # table = csv.read
+ # table # => #<CSV::Table mode:col_or_row row_count:4>
+ # table.headers # => ["NAME", "VALUE"]
+ #
+ # Output:
+ # ["Name", #<struct CSV::FieldInfo index=0, line=1, header=nil>]
+ # ["Value", #<struct CSV::FieldInfo index=1, line=1, header=nil>]
+
+ # The block need not return a \String object:
+ # csv = CSV.open(path, headers: true)
+ # csv.header_convert {|header, field_info| header.to_sym }
+ # table = csv.read
+ # table.headers # => [:Name, :Value]
+ #
+ # If +converter_name+ is given, the block is not called:
+ # csv = CSV.open(path, headers: true)
+ # csv.header_convert(:downcase) {|header, field_info| fail 'Cannot happen' }
+ # table = csv.read
+ # table.headers # => ["name", "value"]
+ # ---
+ #
+ # Raises a parse-time exception if +converter_name+ is not the name of a built-in
+ # field converter:
+ # csv = CSV.open(path, headers: true)
+ # csv.header_convert(:nosuch)
+ # # Raises NoMethodError (undefined method `arity' for nil:NilClass)
+ # csv.read
def header_convert(name = nil, &converter)
- add_converter( :@header_converters,
- self.class::HeaderConverters,
- name,
- &converter )
+ header_fields_converter.add_converter(name, &converter)
end
include Enumerable
- #
- # Yields each row of the data source in turn.
- #
- # Support for Enumerable.
- #
- # The data source must be open for reading.
- #
- def each
- if block_given?
- while row = shift
- yield row
- end
- else
- to_enum
- end
+ # :call-seq:
+ # csv.each -> enumerator
+ # csv.each {|row| ...}
+ #
+ # Calls the block with each successive row.
+ # The data source must be opened for reading.
+ #
+ # Without headers:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string)
+ # csv.each do |row|
+ # p row
+ # end
+ # Output:
+ # ["foo", "0"]
+ # ["bar", "1"]
+ # ["baz", "2"]
+ #
+ # With headers:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string, headers: true)
+ # csv.each do |row|
+ # p row
+ # end
+ # Output:
+ # <CSV::Row "Name":"foo" "Value":"0">
+ # <CSV::Row "Name":"bar" "Value":"1">
+ # <CSV::Row "Name":"baz" "Value":"2">
+ #
+ # ---
+ #
+ # Raises an exception if the source is not opened for reading:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string)
+ # csv.close
+ # # Raises IOError (not opened for reading)
+ # csv.each do |row|
+ # p row
+ # end
+ def each(&block)
+ parser_enumerator.each(&block)
end
- #
- # Slurps the remaining rows and returns an Array of Arrays.
- #
- # The data source must be open for reading.
- #
+ # :call-seq:
+ # csv.read -> array or csv_table
+ #
+ # Forms the remaining rows from +self+ into:
+ # - A CSV::Table object, if headers are in use.
+ # - An \Array of Arrays, otherwise.
+ #
+ # The data source must be opened for reading.
+ #
+ # Without headers:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ # csv = CSV.open(path)
+ # csv.read # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
+ #
+ # With headers:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # path = 't.csv'
+ # File.write(path, string)
+ # csv = CSV.open(path, headers: true)
+ # csv.read # => #<CSV::Table mode:col_or_row row_count:4>
+ #
+ # ---
+ #
+ # Raises an exception if the source is not opened for reading:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string)
+ # csv.close
+ # # Raises IOError (not opened for reading)
+ # csv.read
def read
rows = to_a
- if @use_headers
- Table.new(rows)
+ if parser.use_headers?
+ Table.new(rows, headers: parser.headers)
else
rows
end
end
alias_method :readlines, :read
- # Returns +true+ if the next row read will be a header row.
+ # :call-seq:
+ # csv.header_row? -> true or false
+ #
+ # Returns +true+ if the next row to be read is a header row\;
+ # +false+ otherwise.
+ #
+ # Without headers:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string)
+ # csv.header_row? # => false
+ #
+ # With headers:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string, headers: true)
+ # csv.header_row? # => true
+ # csv.shift # => #<CSV::Row "Name":"foo" "Value":"0">
+ # csv.header_row? # => false
+ #
+ # ---
+ #
+ # Raises an exception if the source is not opened for reading:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string)
+ # csv.close
+ # # Raises IOError (not opened for reading)
+ # csv.header_row?
def header_row?
- @use_headers and @headers.nil?
+ parser.header_row?
end
- #
- # The primary read method for wrapped Strings and IOs, a single row is pulled
- # from the data source, parsed and returned as an Array of fields (if header
- # rows are not used) or a CSV::Row (when header rows are used).
- #
- # The data source must be open for reading.
- #
+ # :call-seq:
+ # csv.shift -> array, csv_row, or nil
+ #
+ # Returns the next row of data as:
+ # - An \Array if no headers are used.
+ # - A CSV::Row object if headers are used.
+ #
+ # The data source must be opened for reading.
+ #
+ # Without headers:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string)
+ # csv.shift # => ["foo", "0"]
+ # csv.shift # => ["bar", "1"]
+ # csv.shift # => ["baz", "2"]
+ # csv.shift # => nil
+ #
+ # With headers:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string, headers: true)
+ # csv.shift # => #<CSV::Row "Name":"foo" "Value":"0">
+ # csv.shift # => #<CSV::Row "Name":"bar" "Value":"1">
+ # csv.shift # => #<CSV::Row "Name":"baz" "Value":"2">
+ # csv.shift # => nil
+ #
+ # ---
+ #
+ # Raises an exception if the source is not opened for reading:
+ # string = "foo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string)
+ # csv.close
+ # # Raises IOError (not opened for reading)
+ # csv.shift
def shift
- #########################################################################
- ### This method is purposefully kept a bit long as simple conditional ###
- ### checks are faster than numerous (expensive) method calls. ###
- #########################################################################
-
- # handle headers not based on document content
- if header_row? and @return_headers and
- [Array, String].include? @use_headers.class
- if @unconverted_fields
- return add_unconverted_fields(parse_headers, Array.new)
- else
- return parse_headers
- end
+ if @eof_error
+ eof_error, @eof_error = @eof_error, nil
+ raise eof_error
end
-
- #
- # it can take multiple calls to <tt>@io.gets()</tt> to get a full line,
- # because of \r and/or \n characters embedded in quoted fields
- #
- in_extended_col = false
- csv = Array.new
-
- loop do
- # add another read to the line
- unless parse = @io.gets(@row_sep)
- return nil
- end
-
- if in_extended_col
- @line.concat(parse)
- else
- @line = parse.clone
- end
-
- parse.sub!(@parsers[:line_end], "")
-
- if csv.empty?
- #
- # I believe a blank line should be an <tt>Array.new</tt>, not Ruby 1.8
- # CSV's <tt>[nil]</tt>
- #
- if parse.empty?
- @lineno += 1
- if @skip_blanks
- next
- elsif @unconverted_fields
- return add_unconverted_fields(Array.new, Array.new)
- elsif @use_headers
- return self.class::Row.new(Array.new, Array.new)
- else
- return Array.new
- end
- end
- end
-
- next if @skip_lines and @skip_lines.match parse
-
- parts = parse.split(@col_sep, -1)
- if parts.empty?
- if in_extended_col
- csv[-1] << @col_sep # will be replaced with a @row_sep after the parts.each loop
- else
- csv << nil
- end
- end
-
- # This loop is the hot path of csv parsing. Some things may be non-dry
- # for a reason. Make sure to benchmark when refactoring.
- parts.each do |part|
- if in_extended_col
- # If we are continuing a previous column
- if part.end_with?(@quote_char) && part.count(@quote_char) % 2 != 0
- # extended column ends
- csv.last << part[0..-2]
- if csv.last =~ @parsers[:stray_quote]
- raise MalformedCSVError,
- "Missing or stray quote in line #{lineno + 1}"
- end
- csv.last.gsub!(@double_quote_char, @quote_char)
- in_extended_col = false
- else
- csv.last << part << @col_sep
- end
- elsif part.start_with?(@quote_char)
- # If we are starting a new quoted column
- if part.count(@quote_char) % 2 != 0
- # start an extended column
- csv << (part[1..-1] << @col_sep)
- in_extended_col = true
- elsif part.end_with?(@quote_char)
- # regular quoted column
- csv << part[1..-2]
- if csv.last =~ @parsers[:stray_quote]
- raise MalformedCSVError,
- "Missing or stray quote in line #{lineno + 1}"
- end
- csv.last.gsub!(@double_quote_char, @quote_char)
- elsif @liberal_parsing
- csv << part
- else
- raise MalformedCSVError,
- "Missing or stray quote in line #{lineno + 1}"
- end
- elsif part =~ @parsers[:quote_or_nl]
- # Unquoted field with bad characters.
- if part =~ @parsers[:nl_or_lf]
- raise MalformedCSVError, "Unquoted fields do not allow " +
- "\\r or \\n (line #{lineno + 1})."
- else
- if @liberal_parsing
- csv << part
- else
- raise MalformedCSVError, "Illegal quoting in line #{lineno + 1}."
- end
- end
- else
- # Regular ole unquoted field.
- csv << (part.empty? ? nil : part)
- end
- end
-
- # Replace tacked on @col_sep with @row_sep if we are still in an extended
- # column.
- csv[-1][-1] = @row_sep if in_extended_col
-
- if in_extended_col
- # if we're at eof?(), a quoted field wasn't closed...
- if @io.eof?
- raise MalformedCSVError,
- "Unclosed quoted field on line #{lineno + 1}."
- elsif @field_size_limit and csv.last.size >= @field_size_limit
- raise MalformedCSVError, "Field size exceeded on line #{lineno + 1}."
- end
- # otherwise, we need to loop and pull some more data to complete the row
- else
- @lineno += 1
-
- # save fields unconverted fields, if needed...
- unconverted = csv.dup if @unconverted_fields
-
- # convert fields, if needed...
- csv = convert_fields(csv) unless @use_headers or @converters.empty?
- # parse out header rows and handle CSV::Row conversions...
- csv = parse_headers(csv) if @use_headers
-
- # inject unconverted fields and accessor, if requested...
- if @unconverted_fields and not csv.respond_to? :unconverted_fields
- add_unconverted_fields(csv, unconverted)
- end
-
- # return the results
- break csv
- end
+ begin
+ parser_enumerator.next
+ rescue StopIteration
+ nil
end
end
alias_method :gets, :shift
alias_method :readline, :shift
+ # :call-seq:
+ # csv.inspect -> string
#
- # Returns a simplified description of the key CSV attributes in an
- # ASCII compatible String.
- #
+ # Returns a \String showing certain properties of +self+:
+ # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # csv = CSV.new(string, headers: true)
+ # s = csv.inspect
+ # s # => "#<CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:\",\" row_sep:\"\\n\" quote_char:\"\\\"\" headers:true>"
def inspect
- str = ["<#", self.class.to_s, " io_type:"]
+ str = ["#<", self.class.to_s, " io_type:"]
# show type of wrapped IO
if @io == $stdout then str << "$stdout"
elsif @io == $stdin then str << "$stdin"
@@ -1973,15 +2486,18 @@ class CSV
# show encoding
str << " encoding:" << @encoding.name
# show other attributes
- %w[ lineno col_sep row_sep
- quote_char skip_blanks liberal_parsing ].each do |attr_name|
- if a = instance_variable_get("@#{attr_name}")
+ ["lineno", "col_sep", "row_sep", "quote_char"].each do |attr_name|
+ if a = __send__(attr_name)
str << " " << attr_name << ":" << a.inspect
end
end
- if @use_headers
- str << " headers:" << headers.inspect
+ ["skip_blanks", "liberal_parsing"].each do |attr_name|
+ if a = __send__("#{attr_name}?")
+ str << " " << attr_name << ":" << a.inspect
+ end
end
+ _headers = headers
+ str << " headers:" << _headers.inspect if _headers
str << ">"
begin
str.join('')
@@ -1995,322 +2511,126 @@ class CSV
private
- #
- # Stores the indicated separators for later use.
- #
- # If auto-discovery was requested for <tt>@row_sep</tt>, this method will read
- # ahead in the <tt>@io</tt> and try to find one. +ARGF+, +STDIN+, +STDOUT+,
- # +STDERR+ and any stream open for output only with a default
- # <tt>@row_sep</tt> of <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
- #
- # This method also establishes the quoting rules used for CSV output.
- #
- def init_separators(col_sep, row_sep, quote_char, force_quotes)
- # store the selected separators
- @col_sep = col_sep.to_s.encode(@encoding)
- @row_sep = row_sep # encode after resolving :auto
- @quote_char = quote_char.to_s.encode(@encoding)
- @double_quote_char = @quote_char * 2
+ def determine_encoding(encoding, internal_encoding)
+ # honor the IO encoding if we can, otherwise default to ASCII-8BIT
+ io_encoding = raw_encoding
+ return io_encoding if io_encoding
- if @quote_char.length != 1
- raise ArgumentError, ":quote_char has to be a single character String"
- end
+ return Encoding.find(internal_encoding) if internal_encoding
- #
- # automatically discover row separator when requested
- # (not fully encoding safe)
- #
- if @row_sep == :auto
- if [ARGF, STDIN, STDOUT, STDERR].include?(@io) or
- (defined?(Zlib) and @io.class == Zlib::GzipWriter)
- @row_sep = $INPUT_RECORD_SEPARATOR
- else
- begin
- #
- # remember where we were (pos() will raise an exception if @io is pipe
- # or not opened for reading)
- #
- saved_pos = @io.pos
- while @row_sep == :auto
- #
- # if we run out of data, it's probably a single line
- # (ensure will set default value)
- #
- break unless sample = @io.gets(nil, 1024)
- # extend sample if we're unsure of the line ending
- if sample.end_with? encode_str("\r")
- sample << (@io.gets(nil, 1) || "")
- end
-
- # try to find a standard separator
- if sample =~ encode_re("\r\n?|\n")
- @row_sep = $&
- break
- end
- end
-
- # tricky seek() clone to work around GzipReader's lack of seek()
- @io.rewind
- # reset back to the remembered position
- while saved_pos > 1024 # avoid loading a lot of data into memory
- @io.read(1024)
- saved_pos -= 1024
- end
- @io.read(saved_pos) if saved_pos.nonzero?
- rescue IOError # not opened for reading
- # do nothing: ensure will set default
- rescue NoMethodError # Zlib::GzipWriter doesn't have some IO methods
- # do nothing: ensure will set default
- rescue SystemCallError # pipe
- # do nothing: ensure will set default
- ensure
- #
- # set default if we failed to detect
- # (stream not opened for reading, a pipe, or a single line of data)
- #
- @row_sep = $INPUT_RECORD_SEPARATOR if @row_sep == :auto
- end
- end
- end
- @row_sep = @row_sep.to_s.encode(@encoding)
-
- # establish quoting rules
- @force_quotes = force_quotes
- do_quote = lambda do |field|
- field = String(field)
- encoded_quote = @quote_char.encode(field.encoding)
- encoded_quote + field.gsub(encoded_quote, encoded_quote * 2) + encoded_quote
- end
- quotable_chars = encode_str("\r\n", @col_sep, @quote_char)
- @quote = if @force_quotes
- do_quote
- else
- lambda do |field|
- if field.nil? # represent +nil+ fields as empty unquoted fields
- ""
- else
- field = String(field) # Stringify fields
- # represent empty fields as empty quoted fields
- if field.empty? or
- field.count(quotable_chars).nonzero?
- do_quote.call(field)
- else
- field # unquoted field
- end
- end
- end
+ if encoding
+ encoding, = encoding.split(":", 2) if encoding.is_a?(String)
+ return Encoding.find(encoding)
end
- end
- # Pre-compiles parsers and stores them by name for access during reads.
- def init_parsers(skip_blanks, field_size_limit, liberal_parsing)
- # store the parser behaviors
- @skip_blanks = skip_blanks
- @field_size_limit = field_size_limit
- @liberal_parsing = liberal_parsing
-
- # prebuild Regexps for faster parsing
- esc_row_sep = escape_re(@row_sep)
- esc_quote = escape_re(@quote_char)
- @parsers = {
- # for detecting parse errors
- quote_or_nl: encode_re("[", esc_quote, "\r\n]"),
- nl_or_lf: encode_re("[\r\n]"),
- stray_quote: encode_re( "[^", esc_quote, "]", esc_quote,
- "[^", esc_quote, "]" ),
- # safer than chomp!()
- line_end: encode_re(esc_row_sep, "\\z"),
- # illegal unquoted characters
- return_newline: encode_str("\r\n")
- }
+ Encoding.default_internal || Encoding.default_external
end
- #
- # Loads any converters requested during construction.
- #
- # If +field_name+ is set <tt>:converters</tt> (the default) field converters
- # are set. When +field_name+ is <tt>:header_converters</tt> header converters
- # are added instead.
- #
- # The <tt>:unconverted_fields</tt> option is also activated for
- # <tt>:converters</tt> calls, if requested.
- #
- def init_converters(converters, ivar_name, convert_method)
- converters = case converters
- when nil then []
- when Array then converters
- else [converters]
- end
- instance_variable_set(ivar_name, [])
- convert = method(convert_method)
-
- # load converters
- converters.each do |converter|
- if converter.is_a? Proc # custom code block
- convert.call(&converter)
- else # by name
- convert.call(converter)
- end
- end
- end
-
- # Stores the pattern of comments to skip from the provided options.
- #
- # The pattern must respond to +.match+, else ArgumentError is raised.
- # Strings are converted to a Regexp.
- #
- # See also CSV.new
- def init_comments(skip_lines)
- @skip_lines = skip_lines
- @skip_lines = Regexp.new(Regexp.escape(@skip_lines)) if @skip_lines.is_a? String
- if @skip_lines and not @skip_lines.respond_to?(:match)
- raise ArgumentError, ":skip_lines has to respond to matches"
- end
- end
- #
- # The actual work method for adding converters, used by both CSV.convert() and
- # CSV.header_convert().
- #
- # This method requires the +var_name+ of the instance variable to place the
- # converters in, the +const+ Hash to lookup named converters in, and the
- # normal parameters of the CSV.convert() and CSV.header_convert() methods.
- #
- def add_converter(var_name, const, name = nil, &converter)
- if name.nil? # custom converter
- instance_variable_get(var_name) << converter
- else # named converter
- combo = const[name]
- case combo
- when Array # combo converter
- combo.each do |converter_name|
- add_converter(var_name, const, converter_name)
- end
- else # individual named converter
- instance_variable_get(var_name) << combo
+ def normalize_converters(converters)
+ converters ||= []
+ unless converters.is_a?(Array)
+ converters = [converters]
+ end
+ converters.collect do |converter|
+ case converter
+ when Proc # custom code block
+ [nil, converter]
+ else # by name
+ [converter, nil]
end
end
end
#
# Processes +fields+ with <tt>@converters</tt>, or <tt>@header_converters</tt>
- # if +headers+ is passed as +true+, returning the converted field set. Any
+ # if +headers+ is passed as +true+, returning the converted field set. Any
# converter that changes the field into something other than a String halts
- # the pipeline of conversion for that field. This is primarily an efficiency
+ # the pipeline of conversion for that field. This is primarily an efficiency
# shortcut.
#
def convert_fields(fields, headers = false)
- # see if we are converting headers or fields
- converters = headers ? @header_converters : @converters
-
- fields.map.with_index do |field, index|
- converters.each do |converter|
- break if headers && field.nil?
- field = if converter.arity == 1 # straight field converter
- converter[field]
- else # FieldInfo converter
- header = @use_headers && !headers ? @headers[index] : nil
- converter[field, FieldInfo.new(index, lineno, header)]
- end
- break unless field.is_a? String # short-circuit pipeline for speed
- end
- field # final state of each field, converted or original
+ if headers
+ header_fields_converter.convert(fields, nil, 0)
+ else
+ parser_fields_converter.convert(fields, @headers, lineno)
end
end
#
- # This method is used to turn a finished +row+ into a CSV::Row. Header rows
- # are also dealt with here, either by returning a CSV::Row with identical
- # headers and fields (save that the fields do not go through the converters)
- # or by reading past them to return a field row. Headers are also saved in
- # <tt>@headers</tt> for use in future rows.
- #
- # When +nil+, +row+ is assumed to be a header row not based on an actual row
- # of the stream.
- #
- def parse_headers(row = nil)
- if @headers.nil? # header row
- @headers = case @use_headers # save headers
- # Array of headers
- when Array then @use_headers
- # CSV header String
- when String
- self.class.parse_line( @use_headers,
- col_sep: @col_sep,
- row_sep: @row_sep,
- quote_char: @quote_char )
- # first row is headers
- else row
- end
-
- # prepare converted and unconverted copies
- row = @headers if row.nil?
- @headers = convert_fields(@headers, true)
- @headers.each { |h| h.freeze if h.is_a? String }
-
- if @return_headers # return headers
- return self.class::Row.new(@headers, row, true)
- elsif not [Array, String].include? @use_headers.class # skip to field row
- return shift
- end
+ # Returns the encoding of the internal IO object.
+ #
+ def raw_encoding
+ if @io.respond_to? :internal_encoding
+ @io.internal_encoding || @io.external_encoding
+ elsif @io.respond_to? :encoding
+ @io.encoding
+ else
+ nil
end
+ end
- self.class::Row.new(@headers, convert_fields(row)) # field row
+ def parser_fields_converter
+ @parser_fields_converter ||= build_parser_fields_converter
end
- #
- # This method injects an instance variable <tt>unconverted_fields</tt> into
- # +row+ and an accessor method for +row+ called unconverted_fields(). The
- # variable is set to the contents of +fields+.
- #
- def add_unconverted_fields(row, fields)
- class << row
- attr_reader :unconverted_fields
- end
- row.instance_variable_set(:@unconverted_fields, fields)
- row
+ def build_parser_fields_converter
+ specific_options = {
+ builtin_converters: Converters,
+ }
+ options = @base_fields_converter_options.merge(specific_options)
+ build_fields_converter(@initial_converters, options)
end
- #
- # This method is an encoding safe version of Regexp::escape(). It will escape
- # any characters that would change the meaning of a regular expression in the
- # encoding of +str+. Regular expression characters that cannot be transcoded
- # to the target encoding will be skipped and no escaping will be performed if
- # a backslash cannot be transcoded.
- #
- def escape_re(str)
- str.gsub(@re_chars) {|c| @re_esc + c}
+ def header_fields_converter
+ @header_fields_converter ||= build_header_fields_converter
end
- #
- # Builds a regular expression in <tt>@encoding</tt>. All +chunks+ will be
- # transcoded to that encoding.
- #
- def encode_re(*chunks)
- Regexp.new(encode_str(*chunks))
+ def build_header_fields_converter
+ specific_options = {
+ builtin_converters: HeaderConverters,
+ accept_nil: true,
+ }
+ options = @base_fields_converter_options.merge(specific_options)
+ build_fields_converter(@initial_header_converters, options)
end
- #
- # Builds a String in <tt>@encoding</tt>. All +chunks+ will be transcoded to
- # that encoding.
- #
- def encode_str(*chunks)
- chunks.map { |chunk| chunk.encode(@encoding.name) }.join('')
+ def writer_fields_converter
+ @writer_fields_converter ||= build_writer_fields_converter
end
- #
- # Returns the encoding of the internal IO object or the +default+ if the
- # encoding cannot be determined.
- #
- def raw_encoding(default = Encoding::ASCII_8BIT)
- if @io.respond_to? :internal_encoding
- @io.internal_encoding || @io.external_encoding
- elsif @io.is_a? StringIO
- @io.string.encoding
- elsif @io.respond_to? :encoding
- @io.encoding
- else
- default
+ def build_writer_fields_converter
+ build_fields_converter(@initial_write_converters,
+ @write_fields_converter_options)
+ end
+
+ def build_fields_converter(initial_converters, options)
+ fields_converter = FieldsConverter.new(options)
+ normalize_converters(initial_converters).each do |name, converter|
+ fields_converter.add_converter(name, &converter)
end
+ fields_converter
+ end
+
+ def parser
+ @parser ||= Parser.new(@io, parser_options)
+ end
+
+ def parser_options
+ @parser_options.merge(header_fields_converter: header_fields_converter,
+ fields_converter: parser_fields_converter)
+ end
+
+ def parser_enumerator
+ @parser_enumerator ||= parser.parse
+ end
+
+ def writer
+ @writer ||= Writer.new(@io, writer_options)
+ end
+
+ def writer_options
+ @writer_options.merge(header_fields_converter: header_fields_converter,
+ fields_converter: writer_fields_converter)
end
end
@@ -2334,22 +2654,6 @@ def CSV(*args, &block)
CSV.instance(*args, &block)
end
-class Array # :nodoc:
- # Equivalent to CSV::generate_line(self, options)
- #
- # ["CSV", "data"].to_csv
- # #=> "CSV,data\n"
- def to_csv(**options)
- CSV.generate_line(self, options)
- end
-end
-
-class String # :nodoc:
- # Equivalent to CSV::parse_line(self, options)
- #
- # "CSV,data".parse_csv
- # #=> ["CSV", "data"]
- def parse_csv(**options)
- CSV.parse_line(self, options)
- end
-end
+require_relative "csv/version"
+require_relative "csv/core_ext/array"
+require_relative "csv/core_ext/string"
diff --git a/lib/csv/core_ext/array.rb b/lib/csv/core_ext/array.rb
new file mode 100644
index 0000000000..8beb06b082
--- /dev/null
+++ b/lib/csv/core_ext/array.rb
@@ -0,0 +1,9 @@
+class Array # :nodoc:
+ # Equivalent to CSV::generate_line(self, options)
+ #
+ # ["CSV", "data"].to_csv
+ # #=> "CSV,data\n"
+ def to_csv(**options)
+ CSV.generate_line(self, **options)
+ end
+end
diff --git a/lib/csv/core_ext/string.rb b/lib/csv/core_ext/string.rb
new file mode 100644
index 0000000000..9b1d31c2a4
--- /dev/null
+++ b/lib/csv/core_ext/string.rb
@@ -0,0 +1,9 @@
+class String # :nodoc:
+ # Equivalent to CSV::parse_line(self, options)
+ #
+ # "CSV,data".parse_csv
+ # #=> ["CSV", "data"]
+ def parse_csv(**options)
+ CSV.parse_line(self, **options)
+ end
+end
diff --git a/lib/csv/csv.gemspec b/lib/csv/csv.gemspec
new file mode 100644
index 0000000000..d0284728f7
--- /dev/null
+++ b/lib/csv/csv.gemspec
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+begin
+ require_relative "lib/csv/version"
+rescue LoadError
+ # for Ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "csv"
+ spec.version = CSV::VERSION
+ spec.authors = ["James Edward Gray II", "Kouhei Sutou"]
+ spec.email = [nil, "kou@cozmixng.org"]
+
+ spec.summary = "CSV Reading and Writing"
+ spec.description = "The CSV library provides a complete interface to CSV files and data. It offers tools to enable you to read and write to and from Strings or IO objects, as needed."
+ spec.homepage = "https://github.com/ruby/csv"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ lib_path = "lib"
+ spec.require_paths = [lib_path]
+ files = []
+ lib_dir = File.join(__dir__, lib_path)
+ if File.exist?(lib_dir)
+ Dir.chdir(lib_dir) do
+ Dir.glob("**/*.rb").each do |file|
+ files << "lib/#{file}"
+ end
+ end
+ end
+ doc_dir = File.join(__dir__, "doc")
+ if File.exist?(doc_dir)
+ Dir.chdir(doc_dir) do
+ Dir.glob("**/*.rdoc").each do |rdoc_file|
+ files << "doc/#{rdoc_file}"
+ end
+ end
+ end
+ spec.files = files
+ spec.rdoc_options.concat(["--main", "README.md"])
+ rdoc_files = [
+ "LICENSE.txt",
+ "NEWS.md",
+ "README.md",
+ ]
+ recipes_dir = File.join(doc_dir, "csv", "recipes")
+ if File.exist?(recipes_dir)
+ Dir.chdir(recipes_dir) do
+ Dir.glob("**/*.rdoc").each do |recipe_file|
+ rdoc_files << "doc/csv/recipes/#{recipe_file}"
+ end
+ end
+ end
+ spec.extra_rdoc_files = rdoc_files
+
+ spec.required_ruby_version = ">= 2.5.0"
+
+ # spec.add_dependency "stringio", ">= 0.1.3"
+ spec.add_development_dependency "bundler"
+ spec.add_development_dependency "rake"
+ spec.add_development_dependency "benchmark_driver"
+ spec.add_development_dependency "simplecov"
+end
diff --git a/lib/csv/delete_suffix.rb b/lib/csv/delete_suffix.rb
new file mode 100644
index 0000000000..d457718997
--- /dev/null
+++ b/lib/csv/delete_suffix.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+# This provides String#delete_suffix? for Ruby 2.4.
+unless String.method_defined?(:delete_suffix)
+ class CSV
+ module DeleteSuffix
+ refine String do
+ def delete_suffix(suffix)
+ if end_with?(suffix)
+ self[0...-suffix.size]
+ else
+ self
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/csv/fields_converter.rb b/lib/csv/fields_converter.rb
new file mode 100644
index 0000000000..178ffb37bc
--- /dev/null
+++ b/lib/csv/fields_converter.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+class CSV
+ # Note: Don't use this class directly. This is an internal class.
+ class FieldsConverter
+ include Enumerable
+ #
+ # A CSV::FieldsConverter is a data structure for storing the
+ # fields converter properties to be passed as a parameter
+ # when parsing a new file (e.g. CSV::Parser.new(@io, parser_options))
+ #
+
+ def initialize(options={})
+ @converters = []
+ @nil_value = options[:nil_value]
+ @empty_value = options[:empty_value]
+ @empty_value_is_empty_string = (@empty_value == "")
+ @accept_nil = options[:accept_nil]
+ @builtin_converters = options[:builtin_converters]
+ @need_static_convert = need_static_convert?
+ end
+
+ def add_converter(name=nil, &converter)
+ if name.nil? # custom converter
+ @converters << converter
+ else # named converter
+ combo = @builtin_converters[name]
+ case combo
+ when Array # combo converter
+ combo.each do |sub_name|
+ add_converter(sub_name)
+ end
+ else # individual named converter
+ @converters << combo
+ end
+ end
+ end
+
+ def each(&block)
+ @converters.each(&block)
+ end
+
+ def empty?
+ @converters.empty?
+ end
+
+ def convert(fields, headers, lineno)
+ return fields unless need_convert?
+
+ fields.collect.with_index do |field, index|
+ if field.nil?
+ field = @nil_value
+ elsif field.is_a?(String) and field.empty?
+ field = @empty_value unless @empty_value_is_empty_string
+ end
+ @converters.each do |converter|
+ break if field.nil? and @accept_nil
+ if converter.arity == 1 # straight field converter
+ field = converter[field]
+ else # FieldInfo converter
+ if headers
+ header = headers[index]
+ else
+ header = nil
+ end
+ field = converter[field, FieldInfo.new(index, lineno, header)]
+ end
+ break unless field.is_a?(String) # short-circuit pipeline for speed
+ end
+ field # final state of each field, converted or original
+ end
+ end
+
+ private
+ def need_static_convert?
+ not (@nil_value.nil? and @empty_value_is_empty_string)
+ end
+
+ def need_convert?
+ @need_static_convert or
+ (not @converters.empty?)
+ end
+ end
+end
diff --git a/lib/csv/match_p.rb b/lib/csv/match_p.rb
new file mode 100644
index 0000000000..775559a3eb
--- /dev/null
+++ b/lib/csv/match_p.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# This provides String#match? and Regexp#match? for Ruby 2.3.
+unless String.method_defined?(:match?)
+ class CSV
+ module MatchP
+ refine String do
+ def match?(pattern)
+ self =~ pattern
+ end
+ end
+
+ refine Regexp do
+ def match?(string)
+ self =~ string
+ end
+ end
+ end
+ end
+end
diff --git a/lib/csv/parser.rb b/lib/csv/parser.rb
new file mode 100644
index 0000000000..2fb3b0a46e
--- /dev/null
+++ b/lib/csv/parser.rb
@@ -0,0 +1,1142 @@
+# frozen_string_literal: true
+
+require "strscan"
+
+require_relative "delete_suffix"
+require_relative "match_p"
+require_relative "row"
+require_relative "table"
+
+using CSV::DeleteSuffix if CSV.const_defined?(:DeleteSuffix)
+using CSV::MatchP if CSV.const_defined?(:MatchP)
+
+class CSV
+ # Note: Don't use this class directly. This is an internal class.
+ class Parser
+ #
+ # A CSV::Parser is m17n aware. The parser works in the Encoding of the IO
+ # or String object being read from or written to. Your data is never transcoded
+ # (unless you ask Ruby to transcode it for you) and will literally be parsed in
+ # the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the
+ # Encoding of your data. This is accomplished by transcoding the parser itself
+ # into your Encoding.
+ #
+
+ # Raised when encoding is invalid.
+ class InvalidEncoding < StandardError
+ end
+
+ #
+ # CSV::Scanner receives a CSV output, scans it and return the content.
+ # It also controls the life cycle of the object with its methods +keep_start+,
+ # +keep_end+, +keep_back+, +keep_drop+.
+ #
+ # Uses StringScanner (the official strscan gem). Strscan provides lexical
+ # scanning operations on a String. We inherit its object and take advantage
+ # on the methods. For more information, please visit:
+ # https://ruby-doc.org/stdlib-2.6.1/libdoc/strscan/rdoc/StringScanner.html
+ #
+ class Scanner < StringScanner
+ alias_method :scan_all, :scan
+
+ def initialize(*args)
+ super
+ @keeps = []
+ end
+
+ def each_line(row_separator)
+ position = pos
+ rest.each_line(row_separator) do |line|
+ position += line.bytesize
+ self.pos = position
+ yield(line)
+ end
+ end
+
+ def keep_start
+ @keeps.push(pos)
+ end
+
+ def keep_end
+ start = @keeps.pop
+ string.byteslice(start, pos - start)
+ end
+
+ def keep_back
+ self.pos = @keeps.pop
+ end
+
+ def keep_drop
+ @keeps.pop
+ end
+ end
+
+ #
+ # CSV::InputsScanner receives IO inputs, encoding and the chunk_size.
+ # It also controls the life cycle of the object with its methods +keep_start+,
+ # +keep_end+, +keep_back+, +keep_drop+.
+ #
+ # CSV::InputsScanner.scan() tries to match with pattern at the current position.
+ # If there's a match, the scanner advances the “scan pointer†and returns the matched string.
+ # Otherwise, the scanner returns nil.
+ #
+ # CSV::InputsScanner.rest() returns the “rest†of the string (i.e. everything after the scan pointer).
+ # If there is no more data (eos? = true), it returns "".
+ #
+ class InputsScanner
+ def initialize(inputs, encoding, chunk_size: 8192)
+ @inputs = inputs.dup
+ @encoding = encoding
+ @chunk_size = chunk_size
+ @last_scanner = @inputs.empty?
+ @keeps = []
+ read_chunk
+ end
+
+ def each_line(row_separator)
+ buffer = nil
+ input = @scanner.rest
+ position = @scanner.pos
+ offset = 0
+ n_row_separator_chars = row_separator.size
+ while true
+ input.each_line(row_separator) do |line|
+ @scanner.pos += line.bytesize
+ if buffer
+ if n_row_separator_chars == 2 and
+ buffer.end_with?(row_separator[0]) and
+ line.start_with?(row_separator[1])
+ buffer << line[0]
+ line = line[1..-1]
+ position += buffer.bytesize + offset
+ @scanner.pos = position
+ offset = 0
+ yield(buffer)
+ buffer = nil
+ next if line.empty?
+ else
+ buffer << line
+ line = buffer
+ buffer = nil
+ end
+ end
+ if line.end_with?(row_separator)
+ position += line.bytesize + offset
+ @scanner.pos = position
+ offset = 0
+ yield(line)
+ else
+ buffer = line
+ end
+ end
+ break unless read_chunk
+ input = @scanner.rest
+ position = @scanner.pos
+ offset = -buffer.bytesize if buffer
+ end
+ yield(buffer) if buffer
+ end
+
+ def scan(pattern)
+ value = @scanner.scan(pattern)
+ return value if @last_scanner
+
+ if value
+ read_chunk if @scanner.eos?
+ return value
+ else
+ nil
+ end
+ end
+
+ def scan_all(pattern)
+ value = @scanner.scan(pattern)
+ return value if @last_scanner
+
+ return nil if value.nil?
+ while @scanner.eos? and read_chunk and (sub_value = @scanner.scan(pattern))
+ value << sub_value
+ end
+ value
+ end
+
+ def eos?
+ @scanner.eos?
+ end
+
+ def keep_start
+ @keeps.push([@scanner.pos, nil])
+ end
+
+ def keep_end
+ start, buffer = @keeps.pop
+ keep = @scanner.string.byteslice(start, @scanner.pos - start)
+ if buffer
+ buffer << keep
+ keep = buffer
+ end
+ keep
+ end
+
+ def keep_back
+ start, buffer = @keeps.pop
+ if buffer
+ string = @scanner.string
+ keep = string.byteslice(start, string.bytesize - start)
+ if keep and not keep.empty?
+ @inputs.unshift(StringIO.new(keep))
+ @last_scanner = false
+ end
+ @scanner = StringScanner.new(buffer)
+ else
+ @scanner.pos = start
+ end
+ read_chunk if @scanner.eos?
+ end
+
+ def keep_drop
+ @keeps.pop
+ end
+
+ def rest
+ @scanner.rest
+ end
+
+ private
+ def read_chunk
+ return false if @last_scanner
+
+ unless @keeps.empty?
+ keep = @keeps.last
+ keep_start = keep[0]
+ string = @scanner.string
+ keep_data = string.byteslice(keep_start, @scanner.pos - keep_start)
+ if keep_data
+ keep_buffer = keep[1]
+ if keep_buffer
+ keep_buffer << keep_data
+ else
+ keep[1] = keep_data.dup
+ end
+ end
+ keep[0] = 0
+ end
+
+ input = @inputs.first
+ case input
+ when StringIO
+ string = input.read
+ raise InvalidEncoding unless string.valid_encoding?
+ @scanner = StringScanner.new(string)
+ @inputs.shift
+ @last_scanner = @inputs.empty?
+ true
+ else
+ chunk = input.gets(nil, @chunk_size)
+ if chunk
+ raise InvalidEncoding unless chunk.valid_encoding?
+ @scanner = StringScanner.new(chunk)
+ if input.respond_to?(:eof?) and input.eof?
+ @inputs.shift
+ @last_scanner = @inputs.empty?
+ end
+ true
+ else
+ @scanner = StringScanner.new("".encode(@encoding))
+ @inputs.shift
+ @last_scanner = @inputs.empty?
+ if @last_scanner
+ false
+ else
+ read_chunk
+ end
+ end
+ end
+ end
+ end
+
+ def initialize(input, options)
+ @input = input
+ @options = options
+ @samples = []
+
+ prepare
+ end
+
+ def column_separator
+ @column_separator
+ end
+
+ def row_separator
+ @row_separator
+ end
+
+ def quote_character
+ @quote_character
+ end
+
+ def field_size_limit
+ @field_size_limit
+ end
+
+ def skip_lines
+ @skip_lines
+ end
+
+ def unconverted_fields?
+ @unconverted_fields
+ end
+
+ def headers
+ @headers
+ end
+
+ def header_row?
+ @use_headers and @headers.nil?
+ end
+
+ def return_headers?
+ @return_headers
+ end
+
+ def skip_blanks?
+ @skip_blanks
+ end
+
+ def liberal_parsing?
+ @liberal_parsing
+ end
+
+ def lineno
+ @lineno
+ end
+
+ def line
+ last_line
+ end
+
+ def parse(&block)
+ return to_enum(__method__) unless block_given?
+
+ if @return_headers and @headers and @raw_headers
+ headers = Row.new(@headers, @raw_headers, true)
+ if @unconverted_fields
+ headers = add_unconverted_fields(headers, [])
+ end
+ yield headers
+ end
+
+ begin
+ @scanner ||= build_scanner
+ if quote_character.nil?
+ parse_no_quote(&block)
+ elsif @need_robust_parsing
+ parse_quotable_robust(&block)
+ else
+ parse_quotable_loose(&block)
+ end
+ rescue InvalidEncoding
+ if @scanner
+ ignore_broken_line
+ lineno = @lineno
+ else
+ lineno = @lineno + 1
+ end
+ message = "Invalid byte sequence in #{@encoding}"
+ raise MalformedCSVError.new(message, lineno)
+ end
+ end
+
+ def use_headers?
+ @use_headers
+ end
+
+ private
+ # A set of tasks to prepare the file in order to parse it
+ def prepare
+ prepare_variable
+ prepare_quote_character
+ prepare_backslash
+ prepare_skip_lines
+ prepare_strip
+ prepare_separators
+ prepare_quoted
+ prepare_unquoted
+ prepare_line
+ prepare_header
+ prepare_parser
+ end
+
+ def prepare_variable
+ @need_robust_parsing = false
+ @encoding = @options[:encoding]
+ liberal_parsing = @options[:liberal_parsing]
+ if liberal_parsing
+ @liberal_parsing = true
+ if liberal_parsing.is_a?(Hash)
+ @double_quote_outside_quote =
+ liberal_parsing[:double_quote_outside_quote]
+ @backslash_quote = liberal_parsing[:backslash_quote]
+ else
+ @double_quote_outside_quote = false
+ @backslash_quote = false
+ end
+ @need_robust_parsing = true
+ else
+ @liberal_parsing = false
+ @backslash_quote = false
+ end
+ @unconverted_fields = @options[:unconverted_fields]
+ @field_size_limit = @options[:field_size_limit]
+ @skip_blanks = @options[:skip_blanks]
+ @fields_converter = @options[:fields_converter]
+ @header_fields_converter = @options[:header_fields_converter]
+ end
+
+ def prepare_quote_character
+ @quote_character = @options[:quote_character]
+ if @quote_character.nil?
+ @escaped_quote_character = nil
+ @escaped_quote = nil
+ else
+ @quote_character = @quote_character.to_s.encode(@encoding)
+ if @quote_character.length != 1
+ message = ":quote_char has to be nil or a single character String"
+ raise ArgumentError, message
+ end
+ @double_quote_character = @quote_character * 2
+ @escaped_quote_character = Regexp.escape(@quote_character)
+ @escaped_quote = Regexp.new(@escaped_quote_character)
+ end
+ end
+
+ def prepare_backslash
+ return unless @backslash_quote
+
+ @backslash_character = "\\".encode(@encoding)
+
+ @escaped_backslash_character = Regexp.escape(@backslash_character)
+ @escaped_backslash = Regexp.new(@escaped_backslash_character)
+ if @quote_character.nil?
+ @backslash_quote_character = nil
+ else
+ @backslash_quote_character =
+ @backslash_character + @escaped_quote_character
+ end
+ end
+
+ def prepare_skip_lines
+ skip_lines = @options[:skip_lines]
+ case skip_lines
+ when String
+ @skip_lines = skip_lines.encode(@encoding)
+ when Regexp, nil
+ @skip_lines = skip_lines
+ else
+ unless skip_lines.respond_to?(:match)
+ message =
+ ":skip_lines has to respond to \#match: #{skip_lines.inspect}"
+ raise ArgumentError, message
+ end
+ @skip_lines = skip_lines
+ end
+ end
+
+ def prepare_strip
+ @strip = @options[:strip]
+ @escaped_strip = nil
+ @strip_value = nil
+ @rstrip_value = nil
+ if @strip.is_a?(String)
+ case @strip.length
+ when 0
+ raise ArgumentError, ":strip must not be an empty String"
+ when 1
+ # ok
+ else
+ raise ArgumentError, ":strip doesn't support 2 or more characters yet"
+ end
+ @strip = @strip.encode(@encoding)
+ @escaped_strip = Regexp.escape(@strip)
+ if @quote_character
+ @strip_value = Regexp.new(@escaped_strip +
+ "+".encode(@encoding))
+ @rstrip_value = Regexp.new(@escaped_strip +
+ "+\\z".encode(@encoding))
+ end
+ @need_robust_parsing = true
+ elsif @strip
+ strip_values = " \t\f\v"
+ @escaped_strip = strip_values.encode(@encoding)
+ if @quote_character
+ @strip_value = Regexp.new("[#{strip_values}]+".encode(@encoding))
+ @rstrip_value = Regexp.new("[#{strip_values}]+\\z".encode(@encoding))
+ end
+ @need_robust_parsing = true
+ end
+ end
+
+ begin
+ StringScanner.new("x").scan("x")
+ rescue TypeError
+ @@string_scanner_scan_accept_string = false
+ else
+ @@string_scanner_scan_accept_string = true
+ end
+
+ def prepare_separators
+ column_separator = @options[:column_separator]
+ @column_separator = column_separator.to_s.encode(@encoding)
+ if @column_separator.size < 1
+ message = ":col_sep must be 1 or more characters: "
+ message += column_separator.inspect
+ raise ArgumentError, message
+ end
+ @row_separator =
+ resolve_row_separator(@options[:row_separator]).encode(@encoding)
+
+ @escaped_column_separator = Regexp.escape(@column_separator)
+ @escaped_first_column_separator = Regexp.escape(@column_separator[0])
+ if @column_separator.size > 1
+ @column_end = Regexp.new(@escaped_column_separator)
+ @column_ends = @column_separator.each_char.collect do |char|
+ Regexp.new(Regexp.escape(char))
+ end
+ @first_column_separators = Regexp.new(@escaped_first_column_separator +
+ "+".encode(@encoding))
+ else
+ if @@string_scanner_scan_accept_string
+ @column_end = @column_separator
+ else
+ @column_end = Regexp.new(@escaped_column_separator)
+ end
+ @column_ends = nil
+ @first_column_separators = nil
+ end
+
+ escaped_row_separator = Regexp.escape(@row_separator)
+ @row_end = Regexp.new(escaped_row_separator)
+ if @row_separator.size > 1
+ @row_ends = @row_separator.each_char.collect do |char|
+ Regexp.new(Regexp.escape(char))
+ end
+ else
+ @row_ends = nil
+ end
+
+ @cr = "\r".encode(@encoding)
+ @lf = "\n".encode(@encoding)
+ @cr_or_lf = Regexp.new("[\r\n]".encode(@encoding))
+ @not_line_end = Regexp.new("[^\r\n]+".encode(@encoding))
+ end
+
+ def prepare_quoted
+ if @quote_character
+ @quotes = Regexp.new(@escaped_quote_character +
+ "+".encode(@encoding))
+ no_quoted_values = @escaped_quote_character.dup
+ if @backslash_quote
+ no_quoted_values << @escaped_backslash_character
+ end
+ @quoted_value = Regexp.new("[^".encode(@encoding) +
+ no_quoted_values +
+ "]+".encode(@encoding))
+ end
+ if @escaped_strip
+ @split_column_separator = Regexp.new(@escaped_strip +
+ "*".encode(@encoding) +
+ @escaped_column_separator +
+ @escaped_strip +
+ "*".encode(@encoding))
+ else
+ if @column_separator == " ".encode(@encoding)
+ @split_column_separator = Regexp.new(@escaped_column_separator)
+ else
+ @split_column_separator = @column_separator
+ end
+ end
+ end
+
+ def prepare_unquoted
+ return if @quote_character.nil?
+
+ no_unquoted_values = "\r\n".encode(@encoding)
+ no_unquoted_values << @escaped_first_column_separator
+ unless @liberal_parsing
+ no_unquoted_values << @escaped_quote_character
+ end
+ @unquoted_value = Regexp.new("[^".encode(@encoding) +
+ no_unquoted_values +
+ "]+".encode(@encoding))
+ end
+
+ def resolve_row_separator(separator)
+ if separator == :auto
+ cr = "\r".encode(@encoding)
+ lf = "\n".encode(@encoding)
+ if @input.is_a?(StringIO)
+ pos = @input.pos
+ separator = detect_row_separator(@input.read, cr, lf)
+ @input.seek(pos)
+ elsif @input.respond_to?(:gets)
+ if @input.is_a?(File)
+ chunk_size = 32 * 1024
+ else
+ chunk_size = 1024
+ end
+ begin
+ while separator == :auto
+ #
+ # if we run out of data, it's probably a single line
+ # (ensure will set default value)
+ #
+ break unless sample = @input.gets(nil, chunk_size)
+
+ # extend sample if we're unsure of the line ending
+ if sample.end_with?(cr)
+ sample << (@input.gets(nil, 1) || "")
+ end
+
+ @samples << sample
+
+ separator = detect_row_separator(sample, cr, lf)
+ end
+ rescue IOError
+ # do nothing: ensure will set default
+ end
+ end
+ separator = $INPUT_RECORD_SEPARATOR if separator == :auto
+ end
+ separator.to_s.encode(@encoding)
+ end
+
+ def detect_row_separator(sample, cr, lf)
+ lf_index = sample.index(lf)
+ if lf_index
+ cr_index = sample[0, lf_index].index(cr)
+ else
+ cr_index = sample.index(cr)
+ end
+ if cr_index and lf_index
+ if cr_index + 1 == lf_index
+ cr + lf
+ elsif cr_index < lf_index
+ cr
+ else
+ lf
+ end
+ elsif cr_index
+ cr
+ elsif lf_index
+ lf
+ else
+ :auto
+ end
+ end
+
+ def prepare_line
+ @lineno = 0
+ @last_line = nil
+ @scanner = nil
+ end
+
+ def last_line
+ if @scanner
+ @last_line ||= @scanner.keep_end
+ else
+ @last_line
+ end
+ end
+
+ def prepare_header
+ @return_headers = @options[:return_headers]
+
+ headers = @options[:headers]
+ case headers
+ when Array
+ @raw_headers = headers
+ @use_headers = true
+ when String
+ @raw_headers = parse_headers(headers)
+ @use_headers = true
+ when nil, false
+ @raw_headers = nil
+ @use_headers = false
+ else
+ @raw_headers = nil
+ @use_headers = true
+ end
+ if @raw_headers
+ @headers = adjust_headers(@raw_headers)
+ else
+ @headers = nil
+ end
+ end
+
+ def parse_headers(row)
+ CSV.parse_line(row,
+ col_sep: @column_separator,
+ row_sep: @row_separator,
+ quote_char: @quote_character)
+ end
+
+ def adjust_headers(headers)
+ adjusted_headers = @header_fields_converter.convert(headers, nil, @lineno)
+ adjusted_headers.each {|h| h.freeze if h.is_a? String}
+ adjusted_headers
+ end
+
+ def prepare_parser
+ @may_quoted = may_quoted?
+ end
+
+ def may_quoted?
+ return false if @quote_character.nil?
+
+ if @input.is_a?(StringIO)
+ pos = @input.pos
+ sample = @input.read
+ @input.seek(pos)
+ else
+ return false if @samples.empty?
+ sample = @samples.first
+ end
+ sample[0, 128].index(@quote_character)
+ end
+
+ SCANNER_TEST = (ENV["CSV_PARSER_SCANNER_TEST"] == "yes")
+ if SCANNER_TEST
+ class UnoptimizedStringIO
+ def initialize(string)
+ @io = StringIO.new(string, "rb:#{string.encoding}")
+ end
+
+ def gets(*args)
+ @io.gets(*args)
+ end
+
+ def each_line(*args, &block)
+ @io.each_line(*args, &block)
+ end
+
+ def eof?
+ @io.eof?
+ end
+ end
+
+ def build_scanner
+ inputs = @samples.collect do |sample|
+ UnoptimizedStringIO.new(sample)
+ end
+ if @input.is_a?(StringIO)
+ inputs << UnoptimizedStringIO.new(@input.read)
+ else
+ inputs << @input
+ end
+ chunk_size = ENV["CSV_PARSER_SCANNER_TEST_CHUNK_SIZE"] || "1"
+ InputsScanner.new(inputs,
+ @encoding,
+ chunk_size: Integer(chunk_size, 10))
+ end
+ else
+ def build_scanner
+ string = nil
+ if @samples.empty? and @input.is_a?(StringIO)
+ string = @input.read
+ elsif @samples.size == 1 and @input.respond_to?(:eof?) and @input.eof?
+ string = @samples[0]
+ end
+ if string
+ unless string.valid_encoding?
+ index = string.lines(@row_separator).index do |line|
+ !line.valid_encoding?
+ end
+ if index
+ message = "Invalid byte sequence in #{@encoding}"
+ raise MalformedCSVError.new(message, @lineno + index + 1)
+ end
+ end
+ Scanner.new(string)
+ else
+ inputs = @samples.collect do |sample|
+ StringIO.new(sample)
+ end
+ inputs << @input
+ InputsScanner.new(inputs, @encoding)
+ end
+ end
+ end
+
+ def skip_needless_lines
+ return unless @skip_lines
+
+ until @scanner.eos?
+ @scanner.keep_start
+ line = @scanner.scan_all(@not_line_end) || "".encode(@encoding)
+ line << @row_separator if parse_row_end
+ if skip_line?(line)
+ @lineno += 1
+ @scanner.keep_drop
+ else
+ @scanner.keep_back
+ return
+ end
+ end
+ end
+
+ def skip_line?(line)
+ line = line.delete_suffix(@row_separator)
+ case @skip_lines
+ when String
+ line.include?(@skip_lines)
+ when Regexp
+ @skip_lines.match?(line)
+ else
+ @skip_lines.match(line)
+ end
+ end
+
+ def parse_no_quote(&block)
+ @scanner.each_line(@row_separator) do |line|
+ next if @skip_lines and skip_line?(line)
+ original_line = line
+ line = line.delete_suffix(@row_separator)
+
+ if line.empty?
+ next if @skip_blanks
+ row = []
+ else
+ line = strip_value(line)
+ row = line.split(@split_column_separator, -1)
+ n_columns = row.size
+ i = 0
+ while i < n_columns
+ row[i] = nil if row[i].empty?
+ i += 1
+ end
+ end
+ @last_line = original_line
+ emit_row(row, &block)
+ end
+ end
+
+ def parse_quotable_loose(&block)
+ @scanner.keep_start
+ @scanner.each_line(@row_separator) do |line|
+ if @skip_lines and skip_line?(line)
+ @scanner.keep_drop
+ @scanner.keep_start
+ next
+ end
+ original_line = line
+ line = line.delete_suffix(@row_separator)
+
+ if line.empty?
+ if @skip_blanks
+ @scanner.keep_drop
+ @scanner.keep_start
+ next
+ end
+ row = []
+ elsif line.include?(@cr) or line.include?(@lf)
+ @scanner.keep_back
+ @need_robust_parsing = true
+ return parse_quotable_robust(&block)
+ else
+ row = line.split(@split_column_separator, -1)
+ n_columns = row.size
+ i = 0
+ while i < n_columns
+ column = row[i]
+ if column.empty?
+ row[i] = nil
+ else
+ n_quotes = column.count(@quote_character)
+ if n_quotes.zero?
+ # no quote
+ elsif n_quotes == 2 and
+ column.start_with?(@quote_character) and
+ column.end_with?(@quote_character)
+ row[i] = column[1..-2]
+ else
+ @scanner.keep_back
+ @need_robust_parsing = true
+ return parse_quotable_robust(&block)
+ end
+ end
+ i += 1
+ end
+ end
+ @scanner.keep_drop
+ @scanner.keep_start
+ @last_line = original_line
+ emit_row(row, &block)
+ end
+ @scanner.keep_drop
+ end
+
+ def parse_quotable_robust(&block)
+ row = []
+ skip_needless_lines
+ start_row
+ while true
+ @quoted_column_value = false
+ @unquoted_column_value = false
+ @scanner.scan_all(@strip_value) if @strip_value
+ value = parse_column_value
+ if value
+ @scanner.scan_all(@strip_value) if @strip_value
+ if @field_size_limit and value.size >= @field_size_limit
+ ignore_broken_line
+ raise MalformedCSVError.new("Field size exceeded", @lineno)
+ end
+ end
+ if parse_column_end
+ row << value
+ elsif parse_row_end
+ if row.empty? and value.nil?
+ emit_row([], &block) unless @skip_blanks
+ else
+ row << value
+ emit_row(row, &block)
+ row = []
+ end
+ skip_needless_lines
+ start_row
+ elsif @scanner.eos?
+ break if row.empty? and value.nil?
+ row << value
+ emit_row(row, &block)
+ break
+ else
+ if @quoted_column_value
+ ignore_broken_line
+ message = "Any value after quoted field isn't allowed"
+ raise MalformedCSVError.new(message, @lineno)
+ elsif @unquoted_column_value and
+ (new_line = @scanner.scan(@cr_or_lf))
+ ignore_broken_line
+ message = "Unquoted fields do not allow new line " +
+ "<#{new_line.inspect}>"
+ raise MalformedCSVError.new(message, @lineno)
+ elsif @scanner.rest.start_with?(@quote_character)
+ ignore_broken_line
+ message = "Illegal quoting"
+ raise MalformedCSVError.new(message, @lineno)
+ elsif (new_line = @scanner.scan(@cr_or_lf))
+ ignore_broken_line
+ message = "New line must be <#{@row_separator.inspect}> " +
+ "not <#{new_line.inspect}>"
+ raise MalformedCSVError.new(message, @lineno)
+ else
+ ignore_broken_line
+ raise MalformedCSVError.new("TODO: Meaningful message",
+ @lineno)
+ end
+ end
+ end
+ end
+
+ def parse_column_value
+ if @liberal_parsing
+ quoted_value = parse_quoted_column_value
+ if quoted_value
+ @scanner.scan_all(@strip_value) if @strip_value
+ unquoted_value = parse_unquoted_column_value
+ if unquoted_value
+ if @double_quote_outside_quote
+ unquoted_value = unquoted_value.gsub(@quote_character * 2,
+ @quote_character)
+ if quoted_value.empty? # %Q{""...} case
+ return @quote_character + unquoted_value
+ end
+ end
+ @quote_character + quoted_value + @quote_character + unquoted_value
+ else
+ quoted_value
+ end
+ else
+ parse_unquoted_column_value
+ end
+ elsif @may_quoted
+ parse_quoted_column_value ||
+ parse_unquoted_column_value
+ else
+ parse_unquoted_column_value ||
+ parse_quoted_column_value
+ end
+ end
+
+ def parse_unquoted_column_value
+ value = @scanner.scan_all(@unquoted_value)
+ return nil unless value
+
+ @unquoted_column_value = true
+ if @first_column_separators
+ while true
+ @scanner.keep_start
+ is_column_end = @column_ends.all? do |column_end|
+ @scanner.scan(column_end)
+ end
+ @scanner.keep_back
+ break if is_column_end
+ sub_separator = @scanner.scan_all(@first_column_separators)
+ break if sub_separator.nil?
+ value << sub_separator
+ sub_value = @scanner.scan_all(@unquoted_value)
+ break if sub_value.nil?
+ value << sub_value
+ end
+ end
+ value.gsub!(@backslash_quote_character, @quote_character) if @backslash_quote
+ if @rstrip_value
+ value.gsub!(@rstrip_value, "")
+ end
+ value
+ end
+
+ def parse_quoted_column_value
+ quotes = @scanner.scan_all(@quotes)
+ return nil unless quotes
+
+ @quoted_column_value = true
+ n_quotes = quotes.size
+ if (n_quotes % 2).zero?
+ quotes[0, (n_quotes - 2) / 2]
+ else
+ value = quotes[0, (n_quotes - 1) / 2]
+ while true
+ quoted_value = @scanner.scan_all(@quoted_value)
+ value << quoted_value if quoted_value
+ if @backslash_quote
+ if @scanner.scan(@escaped_backslash)
+ if @scanner.scan(@escaped_quote)
+ value << @quote_character
+ else
+ value << @backslash_character
+ end
+ next
+ end
+ end
+
+ quotes = @scanner.scan_all(@quotes)
+ unless quotes
+ ignore_broken_line
+ message = "Unclosed quoted field"
+ raise MalformedCSVError.new(message, @lineno)
+ end
+ n_quotes = quotes.size
+ if n_quotes == 1
+ break
+ elsif (n_quotes % 2) == 1
+ value << quotes[0, (n_quotes - 1) / 2]
+ break
+ else
+ value << quotes[0, n_quotes / 2]
+ end
+ end
+ value
+ end
+ end
+
+ def parse_column_end
+ return true if @scanner.scan(@column_end)
+ return false unless @column_ends
+
+ @scanner.keep_start
+ if @column_ends.all? {|column_end| @scanner.scan(column_end)}
+ @scanner.keep_drop
+ true
+ else
+ @scanner.keep_back
+ false
+ end
+ end
+
+ def parse_row_end
+ return true if @scanner.scan(@row_end)
+ return false unless @row_ends
+ @scanner.keep_start
+ if @row_ends.all? {|row_end| @scanner.scan(row_end)}
+ @scanner.keep_drop
+ true
+ else
+ @scanner.keep_back
+ false
+ end
+ end
+
+ def strip_value(value)
+ return value unless @strip
+ return nil if value.nil?
+
+ case @strip
+ when String
+ size = value.size
+ while value.start_with?(@strip)
+ size -= 1
+ value = value[1, size]
+ end
+ while value.end_with?(@strip)
+ size -= 1
+ value = value[0, size]
+ end
+ else
+ value.strip!
+ end
+ value
+ end
+
+ def ignore_broken_line
+ @scanner.scan_all(@not_line_end)
+ @scanner.scan_all(@cr_or_lf)
+ @lineno += 1
+ end
+
+ def start_row
+ if @last_line
+ @last_line = nil
+ else
+ @scanner.keep_drop
+ end
+ @scanner.keep_start
+ end
+
+ def emit_row(row, &block)
+ @lineno += 1
+
+ raw_row = row
+ if @use_headers
+ if @headers.nil?
+ @headers = adjust_headers(row)
+ return unless @return_headers
+ row = Row.new(@headers, row, true)
+ else
+ row = Row.new(@headers,
+ @fields_converter.convert(raw_row, @headers, @lineno))
+ end
+ else
+ # convert fields, if needed...
+ row = @fields_converter.convert(raw_row, nil, @lineno)
+ end
+
+ # inject unconverted fields and accessor, if requested...
+ if @unconverted_fields and not row.respond_to?(:unconverted_fields)
+ add_unconverted_fields(row, raw_row)
+ end
+
+ yield(row)
+ end
+
+ # This method injects an instance variable <tt>unconverted_fields</tt> into
+ # +row+ and an accessor method for +row+ called unconverted_fields(). The
+ # variable is set to the contents of +fields+.
+ def add_unconverted_fields(row, fields)
+ class << row
+ attr_reader :unconverted_fields
+ end
+ row.instance_variable_set(:@unconverted_fields, fields)
+ row
+ end
+ end
+end
diff --git a/lib/csv/row.rb b/lib/csv/row.rb
new file mode 100644
index 0000000000..0f465ea2a3
--- /dev/null
+++ b/lib/csv/row.rb
@@ -0,0 +1,624 @@
+# frozen_string_literal: true
+
+require "forwardable"
+
+class CSV
+ #
+ # A CSV::Row is part Array and part Hash. It retains an order for the fields
+ # and allows duplicates just as an Array would, but also allows you to access
+ # fields by name just as you could if they were in a Hash.
+ #
+ # All rows returned by CSV will be constructed from this class, if header row
+ # processing is activated.
+ #
+ class Row
+ #
+ # Constructs a new CSV::Row from +headers+ and +fields+, which are expected
+ # to be Arrays. If one Array is shorter than the other, it will be padded
+ # with +nil+ objects.
+ #
+ # The optional +header_row+ parameter can be set to +true+ to indicate, via
+ # CSV::Row.header_row?() and CSV::Row.field_row?(), that this is a header
+ # row. Otherwise, the row assumes to be a field row.
+ #
+ # A CSV::Row object supports the following Array methods through delegation:
+ #
+ # * empty?()
+ # * length()
+ # * size()
+ #
+ def initialize(headers, fields, header_row = false)
+ @header_row = header_row
+ headers.each { |h| h.freeze if h.is_a? String }
+
+ # handle extra headers or fields
+ @row = if headers.size >= fields.size
+ headers.zip(fields)
+ else
+ fields.zip(headers).each(&:reverse!)
+ end
+ end
+
+ # Internal data format used to compare equality.
+ attr_reader :row
+ protected :row
+
+ ### Array Delegation ###
+
+ extend Forwardable
+ def_delegators :@row, :empty?, :length, :size
+
+ def initialize_copy(other)
+ super_return_value = super
+ @row = @row.collect(&:dup)
+ super_return_value
+ end
+
+ # :call-seq:
+ # row.header_row? -> true or false
+ #
+ # Returns +true+ if this is a header row, +false+ otherwise.
+ def header_row?
+ @header_row
+ end
+
+ # :call-seq:
+ # row.field_row? -> true or false
+ #
+ # Returns +true+ if this is a field row, +false+ otherwise.
+ def field_row?
+ not header_row?
+ end
+
+ # :call-seq:
+ # row.headers
+ #
+ # Returns the headers for this row:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table.first
+ # row.headers # => ["Name", "Value"]
+ def headers
+ @row.map(&:first)
+ end
+
+ # :call-seq:
+ # field(index)
+ # field(header)
+ # field(header, offset)
+ #
+ # Returns the field value for the given +index+ or +header+.
+ #
+ # ---
+ #
+ # Fetch field value by \Integer index:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.field(0) # => "foo"
+ # row.field(1) # => "bar"
+ #
+ # Counts backward from the last column if +index+ is negative:
+ # row.field(-1) # => "0"
+ # row.field(-2) # => "foo"
+ #
+ # Returns +nil+ if +index+ is out of range:
+ # row.field(2) # => nil
+ # row.field(-3) # => nil
+ #
+ # ---
+ #
+ # Fetch field value by header (first found):
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.field('Name') # => "Foo"
+ #
+ # Fetch field value by header, ignoring +offset+ leading fields:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.field('Name', 2) # => "Baz"
+ #
+ # Returns +nil+ if the header does not exist.
+ def field(header_or_index, minimum_index = 0)
+ # locate the pair
+ finder = (header_or_index.is_a?(Integer) || header_or_index.is_a?(Range)) ? :[] : :assoc
+ pair = @row[minimum_index..-1].public_send(finder, header_or_index)
+
+ # return the field if we have a pair
+ if pair.nil?
+ nil
+ else
+ header_or_index.is_a?(Range) ? pair.map(&:last) : pair.last
+ end
+ end
+ alias_method :[], :field
+
+ #
+ # :call-seq:
+ # fetch(header)
+ # fetch(header, default)
+ # fetch(header) {|row| ... }
+ #
+ # Returns the field value as specified by +header+.
+ #
+ # ---
+ #
+ # With the single argument +header+, returns the field value
+ # for that header (first found):
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.fetch('Name') # => "Foo"
+ #
+ # Raises exception +KeyError+ if the header does not exist.
+ #
+ # ---
+ #
+ # With arguments +header+ and +default+ given,
+ # returns the field value for the header (first found)
+ # if the header exists, otherwise returns +default+:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.fetch('Name', '') # => "Foo"
+ # row.fetch(:nosuch, '') # => ""
+ #
+ # ---
+ #
+ # With argument +header+ and a block given,
+ # returns the field value for the header (first found)
+ # if the header exists; otherwise calls the block
+ # and returns its return value:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.fetch('Name') {|header| fail 'Cannot happen' } # => "Foo"
+ # row.fetch(:nosuch) {|header| "Header '#{header} not found'" } # => "Header 'nosuch not found'"
+ def fetch(header, *varargs)
+ raise ArgumentError, "Too many arguments" if varargs.length > 1
+ pair = @row.assoc(header)
+ if pair
+ pair.last
+ else
+ if block_given?
+ yield header
+ elsif varargs.empty?
+ raise KeyError, "key not found: #{header}"
+ else
+ varargs.first
+ end
+ end
+ end
+
+ # :call-seq:
+ # row.has_key?(header)
+ #
+ # Returns +true+ if there is a field with the given +header+,
+ # +false+ otherwise.
+ def has_key?(header)
+ !!@row.assoc(header)
+ end
+ alias_method :include?, :has_key?
+ alias_method :key?, :has_key?
+ alias_method :member?, :has_key?
+ alias_method :header?, :has_key?
+
+ #
+ # :call-seq:
+ # row[index] = value -> value
+ # row[header, offset] = value -> value
+ # row[header] = value -> value
+ #
+ # Assigns the field value for the given +index+ or +header+;
+ # returns +value+.
+ #
+ # ---
+ #
+ # Assign field value by \Integer index:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row[0] = 'Bat'
+ # row[1] = 3
+ # row # => #<CSV::Row "Name":"Bat" "Value":3>
+ #
+ # Counts backward from the last column if +index+ is negative:
+ # row[-1] = 4
+ # row[-2] = 'Bam'
+ # row # => #<CSV::Row "Name":"Bam" "Value":4>
+ #
+ # Extends the row with <tt>nil:nil</tt> if positive +index+ is not in the row:
+ # row[4] = 5
+ # row # => #<CSV::Row "Name":"bad" "Value":4 nil:nil nil:nil nil:5>
+ #
+ # Raises IndexError if negative +index+ is too small (too far from zero).
+ #
+ # ---
+ #
+ # Assign field value by header (first found):
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row['Name'] = 'Bat'
+ # row # => #<CSV::Row "Name":"Bat" "Name":"Bar" "Name":"Baz">
+ #
+ # Assign field value by header, ignoring +offset+ leading fields:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row['Name', 2] = 4
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":4>
+ #
+ # Append new field by (new) header:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row['New'] = 6
+ # row# => #<CSV::Row "Name":"foo" "Value":"0" "New":6>
+ def []=(*args)
+ value = args.pop
+
+ if args.first.is_a? Integer
+ if @row[args.first].nil? # extending past the end with index
+ @row[args.first] = [nil, value]
+ @row.map! { |pair| pair.nil? ? [nil, nil] : pair }
+ else # normal index assignment
+ @row[args.first][1] = value
+ end
+ else
+ index = index(*args)
+ if index.nil? # appending a field
+ self << [args.first, value]
+ else # normal header assignment
+ @row[index][1] = value
+ end
+ end
+ end
+
+ #
+ # :call-seq:
+ # row << [header, value] -> self
+ # row << hash -> self
+ # row << value -> self
+ #
+ # Adds a field to +self+; returns +self+:
+ #
+ # If the argument is a 2-element \Array <tt>[header, value]</tt>,
+ # a field is added with the given +header+ and +value+:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row << ['NAME', 'Bat']
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" "NAME":"Bat">
+ #
+ # If the argument is a \Hash, each <tt>key-value</tt> pair is added
+ # as a field with header +key+ and value +value+.
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row << {NAME: 'Bat', name: 'Bam'}
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" NAME:"Bat" name:"Bam">
+ #
+ # Otherwise, the given +value+ is added as a field with no header.
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row << 'Bag'
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" nil:"Bag">
+ def <<(arg)
+ if arg.is_a?(Array) and arg.size == 2 # appending a header and name
+ @row << arg
+ elsif arg.is_a?(Hash) # append header and name pairs
+ arg.each { |pair| @row << pair }
+ else # append field value
+ @row << [nil, arg]
+ end
+
+ self # for chaining
+ end
+
+ # :call-seq:
+ # row.push(*values) ->self
+ #
+ # Appends each of the given +values+ to +self+ as a field; returns +self+:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.push('Bat', 'Bam')
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" nil:"Bat" nil:"Bam">
+ def push(*args)
+ args.each { |arg| self << arg }
+
+ self # for chaining
+ end
+
+ #
+ # :call-seq:
+ # delete(index) -> [header, value] or nil
+ # delete(header) -> [header, value] or empty_array
+ # delete(header, offset) -> [header, value] or empty_array
+ #
+ # Removes a specified field from +self+; returns the 2-element \Array
+ # <tt>[header, value]</tt> if the field exists.
+ #
+ # If an \Integer argument +index+ is given,
+ # removes and returns the field at offset +index+,
+ # or returns +nil+ if the field does not exist:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.delete(1) # => ["Name", "Bar"]
+ # row.delete(50) # => nil
+ #
+ # Otherwise, if the single argument +header+ is given,
+ # removes and returns the first-found field with the given header,
+ # of returns a new empty \Array if the field does not exist:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.delete('Name') # => ["Name", "Foo"]
+ # row.delete('NAME') # => []
+ #
+ # If argument +header+ and \Integer argument +offset+ are given,
+ # removes and returns the first-found field with the given header
+ # whose +index+ is at least as large as +offset+:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.delete('Name', 1) # => ["Name", "Bar"]
+ # row.delete('NAME', 1) # => []
+ def delete(header_or_index, minimum_index = 0)
+ if header_or_index.is_a? Integer # by index
+ @row.delete_at(header_or_index)
+ elsif i = index(header_or_index, minimum_index) # by header
+ @row.delete_at(i)
+ else
+ [ ]
+ end
+ end
+
+ # :call-seq:
+ # row.delete_if {|header, value| ... } -> self
+ #
+ # Removes fields from +self+ as selected by the block; returns +self+.
+ #
+ # Removes each field for which the block returns a truthy value:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.delete_if {|header, value| value.start_with?('B') } # => true
+ # row # => #<CSV::Row "Name":"Foo">
+ # row.delete_if {|header, value| header.start_with?('B') } # => false
+ #
+ # If no block is given, returns a new Enumerator:
+ # row.delete_if # => #<Enumerator: #<CSV::Row "Name":"Foo">:delete_if>
+ def delete_if(&block)
+ return enum_for(__method__) { size } unless block_given?
+
+ @row.delete_if(&block)
+
+ self # for chaining
+ end
+
+ # :call-seq:
+ # self.fields(*specifiers)
+ #
+ # Returns field values per the given +specifiers+, which may be any mixture of:
+ # - \Integer index.
+ # - \Range of \Integer indexes.
+ # - 2-element \Array containing a header and offset.
+ # - Header.
+ # - \Range of headers.
+ #
+ # For +specifier+ in one of the first four cases above,
+ # returns the result of <tt>self.field(specifier)</tt>; see #field.
+ #
+ # Although there may be any number of +specifiers+,
+ # the examples here will illustrate one at a time.
+ #
+ # When the specifier is an \Integer +index+,
+ # returns <tt>self.field(index)</tt>L
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.fields(1) # => ["Bar"]
+ #
+ # When the specifier is a \Range of \Integers +range+,
+ # returns <tt>self.field(range)</tt>:
+ # row.fields(1..2) # => ["Bar", "Baz"]
+ #
+ # When the specifier is a 2-element \Array +array+,
+ # returns <tt>self.field(array)</tt>L
+ # row.fields('Name', 1) # => ["Foo", "Bar"]
+ #
+ # When the specifier is a header +header+,
+ # returns <tt>self.field(header)</tt>L
+ # row.fields('Name') # => ["Foo"]
+ #
+ # When the specifier is a \Range of headers +range+,
+ # forms a new \Range +new_range+ from the indexes of
+ # <tt>range.start</tt> and <tt>range.end</tt>,
+ # and returns <tt>self.field(new_range)</tt>:
+ # source = "Name,NAME,name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.fields('Name'..'NAME') # => ["Foo", "Bar"]
+ #
+ # Returns all fields if no argument given:
+ # row.fields # => ["Foo", "Bar", "Baz"]
+ def fields(*headers_and_or_indices)
+ if headers_and_or_indices.empty? # return all fields--no arguments
+ @row.map(&:last)
+ else # or work like values_at()
+ all = []
+ headers_and_or_indices.each do |h_or_i|
+ if h_or_i.is_a? Range
+ index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin :
+ index(h_or_i.begin)
+ index_end = h_or_i.end.is_a?(Integer) ? h_or_i.end :
+ index(h_or_i.end)
+ new_range = h_or_i.exclude_end? ? (index_begin...index_end) :
+ (index_begin..index_end)
+ all.concat(fields.values_at(new_range))
+ else
+ all << field(*Array(h_or_i))
+ end
+ end
+ return all
+ end
+ end
+ alias_method :values_at, :fields
+
+ #
+ # :call-seq:
+ # index( header )
+ # index( header, offset )
+ #
+ # This method will return the index of a field with the provided +header+.
+ # The +offset+ can be used to locate duplicate header names, as described in
+ # CSV::Row.field().
+ #
+ def index(header, minimum_index = 0)
+ # find the pair
+ index = headers[minimum_index..-1].index(header)
+ # return the index at the right offset, if we found one
+ index.nil? ? nil : index + minimum_index
+ end
+
+ #
+ # Returns +true+ if +data+ matches a field in this row, and +false+
+ # otherwise.
+ #
+ def field?(data)
+ fields.include? data
+ end
+
+ include Enumerable
+
+ #
+ # Yields each pair of the row as header and field tuples (much like
+ # iterating over a Hash). This method returns the row for chaining.
+ #
+ # If no block is given, an Enumerator is returned.
+ #
+ # Support for Enumerable.
+ #
+ def each(&block)
+ return enum_for(__method__) { size } unless block_given?
+
+ @row.each(&block)
+
+ self # for chaining
+ end
+
+ alias_method :each_pair, :each
+
+ #
+ # Returns +true+ if this row contains the same headers and fields in the
+ # same order as +other+.
+ #
+ def ==(other)
+ return @row == other.row if other.is_a? CSV::Row
+ @row == other
+ end
+
+ # :call-seq:
+ # row.to_h -> hash
+ #
+ # Returns the new \Hash formed by adding each header-value pair in +self+
+ # as a key-value pair in the \Hash.
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.to_h # => {"Name"=>"foo", "Value"=>"0"}
+ #
+ # Header order is preserved, but repeated headers are ignored:
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.to_h # => {"Name"=>"Foo"}
+ def to_h
+ hash = {}
+ each do |key, _value|
+ hash[key] = self[key] unless hash.key?(key)
+ end
+ hash
+ end
+ alias_method :to_hash, :to_h
+
+ alias_method :to_ary, :to_a
+
+ # :call-seq:
+ # row.to_csv -> csv_string
+ #
+ # Returns the row as a \CSV String. Headers are not included:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.to_csv # => "foo,0\n"
+ def to_csv(**options)
+ fields.to_csv(**options)
+ end
+ alias_method :to_s, :to_csv
+
+ # :call-seq:
+ # row.dig(index_or_header, *identifiers) -> object
+ #
+ # Finds and returns the object in nested object that is specified
+ # by +index_or_header+ and +specifiers+.
+ #
+ # The nested objects may be instances of various classes.
+ # See {Dig Methods}[https://docs.ruby-lang.org/en/master/doc/dig_methods_rdoc.html].
+ #
+ # Examples:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.dig(1) # => "0"
+ # row.dig('Value') # => "0"
+ # row.dig(5) # => nil
+ def dig(index_or_header, *indexes)
+ value = field(index_or_header)
+ if value.nil?
+ nil
+ elsif indexes.empty?
+ value
+ else
+ unless value.respond_to?(:dig)
+ raise TypeError, "#{value.class} does not have \#dig method"
+ end
+ value.dig(*indexes)
+ end
+ end
+
+ # :call-seq:
+ # row.inspect -> string
+ #
+ # Returns an ASCII-compatible \String showing:
+ # - Class \CSV::Row.
+ # - Header-value pairs.
+ # Example:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # row = table[0]
+ # row.inspect # => "#<CSV::Row \"Name\":\"foo\" \"Value\":\"0\">"
+ def inspect
+ str = ["#<", self.class.to_s]
+ each do |header, field|
+ str << " " << (header.is_a?(Symbol) ? header.to_s : header.inspect) <<
+ ":" << field.inspect
+ end
+ str << ">"
+ begin
+ str.join('')
+ rescue # any encoding error
+ str.map do |s|
+ e = Encoding::Converter.asciicompat_encoding(s.encoding)
+ e ? s.encode(e) : s.force_encoding("ASCII-8BIT")
+ end.join('')
+ end
+ end
+ end
+end
diff --git a/lib/csv/table.rb b/lib/csv/table.rb
new file mode 100644
index 0000000000..1ce0dd6daf
--- /dev/null
+++ b/lib/csv/table.rb
@@ -0,0 +1,621 @@
+# frozen_string_literal: true
+
+require "forwardable"
+
+class CSV
+ #
+ # A CSV::Table is a two-dimensional data structure for representing CSV
+ # documents. Tables allow you to work with the data by row or column,
+ # manipulate the data, and even convert the results back to CSV, if needed.
+ #
+ # All tables returned by CSV will be constructed from this class, if header
+ # row processing is activated.
+ #
+ class Table
+ #
+ # Constructs a new CSV::Table from +array_of_rows+, which are expected
+ # to be CSV::Row objects. All rows are assumed to have the same headers.
+ #
+ # The optional +headers+ parameter can be set to Array of headers.
+ # If headers aren't set, headers are fetched from CSV::Row objects.
+ # Otherwise, headers() method will return headers being set in
+ # headers argument.
+ #
+ # A CSV::Table object supports the following Array methods through
+ # delegation:
+ #
+ # * empty?()
+ # * length()
+ # * size()
+ #
+ def initialize(array_of_rows, headers: nil)
+ @table = array_of_rows
+ @headers = headers
+ unless @headers
+ if @table.empty?
+ @headers = []
+ else
+ @headers = @table.first.headers
+ end
+ end
+
+ @mode = :col_or_row
+ end
+
+ # The current access mode for indexing and iteration.
+ attr_reader :mode
+
+ # Internal data format used to compare equality.
+ attr_reader :table
+ protected :table
+
+ ### Array Delegation ###
+
+ extend Forwardable
+ def_delegators :@table, :empty?, :length, :size
+
+ #
+ # Returns a duplicate table object, in column mode. This is handy for
+ # chaining in a single call without changing the table mode, but be aware
+ # that this method can consume a fair amount of memory for bigger data sets.
+ #
+ # This method returns the duplicate table for chaining. Don't chain
+ # destructive methods (like []=()) this way though, since you are working
+ # with a duplicate.
+ #
+ def by_col
+ self.class.new(@table.dup).by_col!
+ end
+
+ #
+ # Switches the mode of this table to column mode. All calls to indexing and
+ # iteration methods will work with columns until the mode is changed again.
+ #
+ # This method returns the table and is safe to chain.
+ #
+ def by_col!
+ @mode = :col
+
+ self
+ end
+
+ #
+ # Returns a duplicate table object, in mixed mode. This is handy for
+ # chaining in a single call without changing the table mode, but be aware
+ # that this method can consume a fair amount of memory for bigger data sets.
+ #
+ # This method returns the duplicate table for chaining. Don't chain
+ # destructive methods (like []=()) this way though, since you are working
+ # with a duplicate.
+ #
+ def by_col_or_row
+ self.class.new(@table.dup).by_col_or_row!
+ end
+
+ #
+ # Switches the mode of this table to mixed mode. All calls to indexing and
+ # iteration methods will use the default intelligent indexing system until
+ # the mode is changed again. In mixed mode an index is assumed to be a row
+ # reference while anything else is assumed to be column access by headers.
+ #
+ # This method returns the table and is safe to chain.
+ #
+ def by_col_or_row!
+ @mode = :col_or_row
+
+ self
+ end
+
+ #
+ # Returns a duplicate table object, in row mode. This is handy for chaining
+ # in a single call without changing the table mode, but be aware that this
+ # method can consume a fair amount of memory for bigger data sets.
+ #
+ # This method returns the duplicate table for chaining. Don't chain
+ # destructive methods (like []=()) this way though, since you are working
+ # with a duplicate.
+ #
+ def by_row
+ self.class.new(@table.dup).by_row!
+ end
+
+ #
+ # Switches the mode of this table to row mode. All calls to indexing and
+ # iteration methods will work with rows until the mode is changed again.
+ #
+ # This method returns the table and is safe to chain.
+ #
+ def by_row!
+ @mode = :row
+
+ self
+ end
+
+ #
+ # Returns the headers for the first row of this table (assumed to match all
+ # other rows). The headers Array passed to CSV::Table.new is returned for
+ # empty tables.
+ #
+ def headers
+ if @table.empty?
+ @headers.dup
+ else
+ @table.first.headers
+ end
+ end
+
+ # :call-seq:
+ # table[n] -> row
+ # table[range] -> array_of_rows
+ # table[header] -> array_of_fields
+ #
+ # Returns data from the table; does not modify the table.
+ #
+ # ---
+ #
+ # The expression <tt>table[n]</tt>, where +n+ is a non-negative \Integer,
+ # returns the +n+th row of the table, if that row exists,
+ # and if the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
+ # table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
+ # table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
+ # table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
+ #
+ # Counts backward from the last row if +n+ is negative:
+ # table[-1] # => #<CSV::Row "Name":"baz" "Value":"2">
+ #
+ # Returns +nil+ if +n+ is too large or too small:
+ # table[4] # => nil
+ # table[-4] => nil
+ #
+ # Raises an exception if the access mode is <tt>:row</tt>
+ # and +n+ is not an
+ # {Integer-convertible object}[https://docs.ruby-lang.org/en/master/implicit_conversion_rdoc.html#label-Integer-Convertible+Objects].
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
+ # # Raises TypeError (no implicit conversion of String into Integer):
+ # table['Name']
+ #
+ # ---
+ #
+ # The expression <tt>table[range]</tt>, where +range+ is a Range object,
+ # returns rows from the table, beginning at row <tt>range.first</tt>,
+ # if those rows exist, and if the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
+ # rows = table[1..2] # => #<CSV::Row "Name":"bar" "Value":"1">
+ # rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
+ # table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
+ # rows = table[1..2] # => #<CSV::Row "Name":"bar" "Value":"1">
+ # rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
+ #
+ # If there are too few rows, returns all from <tt>range.first</tt> to the end:
+ # rows = table[1..50] # => #<CSV::Row "Name":"bar" "Value":"1">
+ # rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
+ #
+ # Special case: if <tt>range.start == table.size</tt>, returns an empty \Array:
+ # table[table.size..50] # => []
+ #
+ # If <tt>range.end</tt> is negative, calculates the ending index from the end:
+ # rows = table[0..-1]
+ # rows # => [#<CSV::Row "Name":"foo" "Value":"0">, #<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
+ #
+ # If <tt>range.start</tt> is negative, calculates the starting index from the end:
+ # rows = table[-1..2]
+ # rows # => [#<CSV::Row "Name":"baz" "Value":"2">]
+ #
+ # If <tt>range.start</tt> is larger than <tt>table.size</tt>, returns +nil+:
+ # table[4..4] # => nil
+ #
+ # ---
+ #
+ # The expression <tt>table[header]</tt>, where +header+ is a \String,
+ # returns column values (\Array of \Strings) if the column exists
+ # and if the access mode is <tt>:col</tt> or <tt>:col_or_row</tt>:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.by_col! # => #<CSV::Table mode:col row_count:4>
+ # table['Name'] # => ["foo", "bar", "baz"]
+ # table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
+ # col = table['Name']
+ # col # => ["foo", "bar", "baz"]
+ #
+ # Modifying the returned column values does not modify the table:
+ # col[0] = 'bat'
+ # col # => ["bat", "bar", "baz"]
+ # table['Name'] # => ["foo", "bar", "baz"]
+ #
+ # Returns an \Array of +nil+ values if there is no such column:
+ # table['Nosuch'] # => [nil, nil, nil]
+ def [](index_or_header)
+ if @mode == :row or # by index
+ (@mode == :col_or_row and (index_or_header.is_a?(Integer) or index_or_header.is_a?(Range)))
+ @table[index_or_header]
+ else # by header
+ @table.map { |row| row[index_or_header] }
+ end
+ end
+
+ #
+ # In the default mixed mode, this method assigns rows for index access and
+ # columns for header access. You can force the index association by first
+ # calling by_col!() or by_row!().
+ #
+ # Rows may be set to an Array of values (which will inherit the table's
+ # headers()) or a CSV::Row.
+ #
+ # Columns may be set to a single value, which is copied to each row of the
+ # column, or an Array of values. Arrays of values are assigned to rows top
+ # to bottom in row major order. Excess values are ignored and if the Array
+ # does not have a value for each row the extra rows will receive a +nil+.
+ #
+ # Assigning to an existing column or row clobbers the data. Assigning to
+ # new columns creates them at the right end of the table.
+ #
+ def []=(index_or_header, value)
+ if @mode == :row or # by index
+ (@mode == :col_or_row and index_or_header.is_a? Integer)
+ if value.is_a? Array
+ @table[index_or_header] = Row.new(headers, value)
+ else
+ @table[index_or_header] = value
+ end
+ else # set column
+ unless index_or_header.is_a? Integer
+ index = @headers.index(index_or_header) || @headers.size
+ @headers[index] = index_or_header
+ end
+ if value.is_a? Array # multiple values
+ @table.each_with_index do |row, i|
+ if row.header_row?
+ row[index_or_header] = index_or_header
+ else
+ row[index_or_header] = value[i]
+ end
+ end
+ else # repeated value
+ @table.each do |row|
+ if row.header_row?
+ row[index_or_header] = index_or_header
+ else
+ row[index_or_header] = value
+ end
+ end
+ end
+ end
+ end
+
+ # :call-seq:
+ # table.values_at(*indexes) -> array_of_rows
+ # table.values_at(*headers) -> array_of_columns_data
+ #
+ # If the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>,
+ # and each argument is either an \Integer or a \Range,
+ # returns rows.
+ # Otherwise, returns columns data.
+ #
+ # In either case, the returned values are in the order
+ # specified by the arguments. Arguments may be repeated.
+ #
+ # ---
+ #
+ # Returns rows as an \Array of \CSV::Row objects.
+ #
+ # No argument:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.values_at # => []
+ #
+ # One index:
+ # values = table.values_at(0)
+ # values # => [#<CSV::Row "Name":"foo" "Value":"0">]
+ #
+ # Two indexes:
+ # values = table.values_at(2, 0)
+ # values # => [#<CSV::Row "Name":"baz" "Value":"2">, #<CSV::Row "Name":"foo" "Value":"0">]
+ #
+ # One \Range:
+ # values = table.values_at(1..2)
+ # values # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
+ #
+ # \Ranges and indexes:
+ # values = table.values_at(0..1, 1..2, 0, 2)
+ # pp values
+ # Output:
+ # [#<CSV::Row "Name":"foo" "Value":"0">,
+ # #<CSV::Row "Name":"bar" "Value":"1">,
+ # #<CSV::Row "Name":"bar" "Value":"1">,
+ # #<CSV::Row "Name":"baz" "Value":"2">,
+ # #<CSV::Row "Name":"foo" "Value":"0">,
+ # #<CSV::Row "Name":"baz" "Value":"2">]
+ #
+ # ---
+ #
+ # Returns columns data as row Arrays,
+ # each consisting of the specified columns data for that row:
+ # values = table.values_at('Name')
+ # values # => [["foo"], ["bar"], ["baz"]]
+ # values = table.values_at('Value', 'Name')
+ # values # => [["0", "foo"], ["1", "bar"], ["2", "baz"]]
+ def values_at(*indices_or_headers)
+ if @mode == :row or # by indices
+ ( @mode == :col_or_row and indices_or_headers.all? do |index|
+ index.is_a?(Integer) or
+ ( index.is_a?(Range) and
+ index.first.is_a?(Integer) and
+ index.last.is_a?(Integer) )
+ end )
+ @table.values_at(*indices_or_headers)
+ else # by headers
+ @table.map { |row| row.values_at(*indices_or_headers) }
+ end
+ end
+
+ # :call-seq:
+ # table << row_or_array -> self
+ #
+ # If +row_or_array+ is a \CSV::Row object,
+ # it is appended to the table:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table << CSV::Row.new(table.headers, ['bat', 3])
+ # table[3] # => #<CSV::Row "Name":"bat" "Value":3>
+ #
+ # If +row_or_array+ is an \Array, it is used to create a new
+ # \CSV::Row object which is then appended to the table:
+ # table << ['bam', 4]
+ # table[4] # => #<CSV::Row "Name":"bam" "Value":4>
+ def <<(row_or_array)
+ if row_or_array.is_a? Array # append Array
+ @table << Row.new(headers, row_or_array)
+ else # append Row
+ @table << row_or_array
+ end
+
+ self # for chaining
+ end
+
+ #
+ # :call-seq:
+ # table.push(*rows_or_arrays) -> self
+ #
+ # A shortcut for appending multiple rows. Equivalent to:
+ # rows.each {|row| self << row }
+ #
+ # Each argument may be either a \CSV::Row object or an \Array:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # rows = [
+ # CSV::Row.new(table.headers, ['bat', 3]),
+ # ['bam', 4]
+ # ]
+ # table.push(*rows)
+ # table[3..4] # => [#<CSV::Row "Name":"bat" "Value":3>, #<CSV::Row "Name":"bam" "Value":4>]
+ def push(*rows)
+ rows.each { |row| self << row }
+
+ self # for chaining
+ end
+
+ # :call-seq:
+ # table.delete(*indexes) -> deleted_values
+ # table.delete(*headers) -> deleted_values
+ #
+ # If the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>,
+ # and each argument is either an \Integer or a \Range,
+ # returns deleted rows.
+ # Otherwise, returns deleted columns data.
+ #
+ # In either case, the returned values are in the order
+ # specified by the arguments. Arguments may be repeated.
+ #
+ # ---
+ #
+ # Returns rows as an \Array of \CSV::Row objects.
+ #
+ # One index:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # deleted_values = table.delete(0)
+ # deleted_values # => [#<CSV::Row "Name":"foo" "Value":"0">]
+ #
+ # Two indexes:
+ # table = CSV.parse(source, headers: true)
+ # deleted_values = table.delete(2, 0)
+ # deleted_values # => [#<CSV::Row "Name":"baz" "Value":"2">, #<CSV::Row "Name":"foo" "Value":"0">]
+ #
+ # ---
+ #
+ # Returns columns data as column Arrays.
+ #
+ # One header:
+ # table = CSV.parse(source, headers: true)
+ # deleted_values = table.delete('Name')
+ # deleted_values # => ["foo", "bar", "baz"]
+ #
+ # Two headers:
+ # table = CSV.parse(source, headers: true)
+ # deleted_values = table.delete('Value', 'Name')
+ # deleted_values # => [["0", "1", "2"], ["foo", "bar", "baz"]]
+ def delete(*indexes_or_headers)
+ if indexes_or_headers.empty?
+ raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
+ end
+ deleted_values = indexes_or_headers.map do |index_or_header|
+ if @mode == :row or # by index
+ (@mode == :col_or_row and index_or_header.is_a? Integer)
+ @table.delete_at(index_or_header)
+ else # by header
+ if index_or_header.is_a? Integer
+ @headers.delete_at(index_or_header)
+ else
+ @headers.delete(index_or_header)
+ end
+ @table.map { |row| row.delete(index_or_header).last }
+ end
+ end
+ if indexes_or_headers.size == 1
+ deleted_values[0]
+ else
+ deleted_values
+ end
+ end
+
+ # Removes rows or columns for which the block returns a truthy value;
+ # returns +self+.
+ #
+ # Removes rows when the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>;
+ # calls the block with each \CSV::Row object:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
+ # table.size # => 3
+ # table.delete_if {|row| row['Name'].start_with?('b') }
+ # table.size # => 1
+ #
+ # Removes columns when the access mode is <tt>:col</tt>;
+ # calls the block with each column as a 2-element array
+ # containing the header and an \Array of column fields:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.by_col! # => #<CSV::Table mode:col row_count:4>
+ # table.headers.size # => 2
+ # table.delete_if {|column_data| column_data[1].include?('2') }
+ # table.headers.size # => 1
+ #
+ # Returns a new \Enumerator if no block is given:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.delete_if # => #<Enumerator: #<CSV::Table mode:col_or_row row_count:4>:delete_if>
+ def delete_if(&block)
+ return enum_for(__method__) { @mode == :row or @mode == :col_or_row ? size : headers.size } unless block_given?
+
+ if @mode == :row or @mode == :col_or_row # by index
+ @table.delete_if(&block)
+ else # by header
+ deleted = []
+ headers.each do |header|
+ deleted << delete(header) if yield([header, self[header]])
+ end
+ end
+
+ self # for chaining
+ end
+
+ include Enumerable
+
+ # Calls the block with each row or column; returns +self+.
+ #
+ # When the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>,
+ # calls the block with each \CSV::Row object:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
+ # table.each {|row| p row }
+ # Output:
+ # #<CSV::Row "Name":"foo" "Value":"0">
+ # #<CSV::Row "Name":"bar" "Value":"1">
+ # #<CSV::Row "Name":"baz" "Value":"2">
+ #
+ # When the access mode is <tt>:col</tt>,
+ # calls the block with each column as a 2-element array
+ # containing the header and an \Array of column fields:
+ # table.by_col! # => #<CSV::Table mode:col row_count:4>
+ # table.each {|column_data| p column_data }
+ # Output:
+ # ["Name", ["foo", "bar", "baz"]]
+ # ["Value", ["0", "1", "2"]]
+ #
+ # Returns a new \Enumerator if no block is given:
+ # table.each # => #<Enumerator: #<CSV::Table mode:col row_count:4>:each>
+ def each(&block)
+ return enum_for(__method__) { @mode == :col ? headers.size : size } unless block_given?
+
+ if @mode == :col
+ headers.each { |header| yield([header, self[header]]) }
+ else
+ @table.each(&block)
+ end
+
+ self # for chaining
+ end
+
+ # Returns +true+ if all each row of +self+ <tt>==</tt>
+ # the corresponding row of +other_table+, otherwise, +false+.
+ #
+ # The access mode does no affect the result.
+ #
+ # Equal tables:
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
+ # table = CSV.parse(source, headers: true)
+ # other_table = CSV.parse(source, headers: true)
+ # table == other_table # => true
+ #
+ # Different row count:
+ # other_table.delete(2)
+ # table == other_table # => false
+ #
+ # Different last row:
+ # other_table << ['bat', 3]
+ # table == other_table # => false
+ def ==(other)
+ return @table == other.table if other.is_a? CSV::Table
+ @table == other
+ end
+
+ #
+ # Returns the table as an Array of Arrays. Headers will be the first row,
+ # then all of the field rows will follow.
+ #
+ def to_a
+ array = [headers]
+ @table.each do |row|
+ array.push(row.fields) unless row.header_row?
+ end
+
+ array
+ end
+
+ #
+ # Returns the table as a complete CSV String. Headers will be listed first,
+ # then all of the field rows.
+ #
+ # This method assumes you want the Table.headers(), unless you explicitly
+ # pass <tt>:write_headers => false</tt>.
+ #
+ def to_csv(write_headers: true, **options)
+ array = write_headers ? [headers.to_csv(**options)] : []
+ @table.each do |row|
+ array.push(row.fields.to_csv(**options)) unless row.header_row?
+ end
+
+ array.join("")
+ end
+ alias_method :to_s, :to_csv
+
+ #
+ # Extracts the nested value specified by the sequence of +index+ or +header+ objects by calling dig at each step,
+ # returning nil if any intermediate step is nil.
+ #
+ def dig(index_or_header, *index_or_headers)
+ value = self[index_or_header]
+ if value.nil?
+ nil
+ elsif index_or_headers.empty?
+ value
+ else
+ unless value.respond_to?(:dig)
+ raise TypeError, "#{value.class} does not have \#dig method"
+ end
+ value.dig(*index_or_headers)
+ end
+ end
+
+ # Shows the mode and size of this table in a US-ASCII String.
+ def inspect
+ "#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>".encode("US-ASCII")
+ end
+ end
+end
diff --git a/lib/csv/version.rb b/lib/csv/version.rb
new file mode 100644
index 0000000000..51dc8433f3
--- /dev/null
+++ b/lib/csv/version.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+class CSV
+ # The version of the installed library.
+ VERSION = "3.1.9"
+end
diff --git a/lib/csv/writer.rb b/lib/csv/writer.rb
new file mode 100644
index 0000000000..d49115fccf
--- /dev/null
+++ b/lib/csv/writer.rb
@@ -0,0 +1,209 @@
+# frozen_string_literal: true
+
+require_relative "match_p"
+require_relative "row"
+
+using CSV::MatchP if CSV.const_defined?(:MatchP)
+
+class CSV
+ # Note: Don't use this class directly. This is an internal class.
+ class Writer
+ #
+ # A CSV::Writer receives an output, prepares the header, format and output.
+ # It allows us to write new rows in the object and rewind it.
+ #
+ attr_reader :lineno
+ attr_reader :headers
+
+ def initialize(output, options)
+ @output = output
+ @options = options
+ @lineno = 0
+ @fields_converter = nil
+ prepare
+ if @options[:write_headers] and @headers
+ self << @headers
+ end
+ @fields_converter = @options[:fields_converter]
+ end
+
+ #
+ # Adds a new row
+ #
+ def <<(row)
+ case row
+ when Row
+ row = row.fields
+ when Hash
+ row = @headers.collect {|header| row[header]}
+ end
+
+ @headers ||= row if @use_headers
+ @lineno += 1
+
+ row = @fields_converter.convert(row, nil, lineno) if @fields_converter
+
+ i = -1
+ converted_row = row.collect do |field|
+ i += 1
+ quote(field, i)
+ end
+ line = converted_row.join(@column_separator) + @row_separator
+ if @output_encoding
+ line = line.encode(@output_encoding)
+ end
+ @output << line
+
+ self
+ end
+
+ #
+ # Winds back to the beginning
+ #
+ def rewind
+ @lineno = 0
+ @headers = nil if @options[:headers].nil?
+ end
+
+ private
+ def prepare
+ @encoding = @options[:encoding]
+
+ prepare_header
+ prepare_format
+ prepare_output
+ end
+
+ def prepare_header
+ headers = @options[:headers]
+ case headers
+ when Array
+ @headers = headers
+ @use_headers = true
+ when String
+ @headers = CSV.parse_line(headers,
+ col_sep: @options[:column_separator],
+ row_sep: @options[:row_separator],
+ quote_char: @options[:quote_character])
+ @use_headers = true
+ when true
+ @headers = nil
+ @use_headers = true
+ else
+ @headers = nil
+ @use_headers = false
+ end
+ return unless @headers
+
+ converter = @options[:header_fields_converter]
+ @headers = converter.convert(@headers, nil, 0)
+ @headers.each do |header|
+ header.freeze if header.is_a?(String)
+ end
+ end
+
+ def prepare_force_quotes_fields(force_quotes)
+ @force_quotes_fields = {}
+ force_quotes.each do |name_or_index|
+ case name_or_index
+ when Integer
+ index = name_or_index
+ @force_quotes_fields[index] = true
+ when String, Symbol
+ name = name_or_index.to_s
+ if @headers.nil?
+ message = ":headers is required when you use field name " +
+ "in :force_quotes: " +
+ "#{name_or_index.inspect}: #{force_quotes.inspect}"
+ raise ArgumentError, message
+ end
+ index = @headers.index(name)
+ next if index.nil?
+ @force_quotes_fields[index] = true
+ else
+ message = ":force_quotes element must be " +
+ "field index or field name: " +
+ "#{name_or_index.inspect}: #{force_quotes.inspect}"
+ raise ArgumentError, message
+ end
+ end
+ end
+
+ def prepare_format
+ @column_separator = @options[:column_separator].to_s.encode(@encoding)
+ row_separator = @options[:row_separator]
+ if row_separator == :auto
+ @row_separator = $INPUT_RECORD_SEPARATOR.encode(@encoding)
+ else
+ @row_separator = row_separator.to_s.encode(@encoding)
+ end
+ @quote_character = @options[:quote_character]
+ force_quotes = @options[:force_quotes]
+ if force_quotes.is_a?(Array)
+ prepare_force_quotes_fields(force_quotes)
+ @force_quotes = false
+ elsif force_quotes
+ @force_quotes_fields = nil
+ @force_quotes = true
+ else
+ @force_quotes_fields = nil
+ @force_quotes = false
+ end
+ unless @force_quotes
+ @quotable_pattern =
+ Regexp.new("[\r\n".encode(@encoding) +
+ Regexp.escape(@column_separator) +
+ Regexp.escape(@quote_character.encode(@encoding)) +
+ "]".encode(@encoding))
+ end
+ @quote_empty = @options.fetch(:quote_empty, true)
+ end
+
+ def prepare_output
+ @output_encoding = nil
+ return unless @output.is_a?(StringIO)
+
+ output_encoding = @output.internal_encoding || @output.external_encoding
+ if @encoding != output_encoding
+ if @options[:force_encoding]
+ @output_encoding = output_encoding
+ else
+ compatible_encoding = Encoding.compatible?(@encoding, output_encoding)
+ if compatible_encoding
+ @output.set_encoding(compatible_encoding)
+ @output.seek(0, IO::SEEK_END)
+ end
+ end
+ end
+ end
+
+ def quote_field(field)
+ field = String(field)
+ encoded_quote_character = @quote_character.encode(field.encoding)
+ encoded_quote_character +
+ field.gsub(encoded_quote_character,
+ encoded_quote_character * 2) +
+ encoded_quote_character
+ end
+
+ def quote(field, i)
+ if @force_quotes
+ quote_field(field)
+ elsif @force_quotes_fields and @force_quotes_fields[i]
+ quote_field(field)
+ else
+ if field.nil? # represent +nil+ fields as empty unquoted fields
+ ""
+ else
+ field = String(field) # Stringify fields
+ # represent empty fields as empty quoted fields
+ if (@quote_empty and field.empty?) or (field.valid_encoding? and @quotable_pattern.match?(field))
+ quote_field(field)
+ else
+ field # unquoted field
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/debug.gemspec b/lib/debug.gemspec
new file mode 100644
index 0000000000..0c414d4827
--- /dev/null
+++ b/lib/debug.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "debug"
+ spec.version = "0.2.1"
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Debugging functionality for Ruby}
+ spec.description = %q{Debugging functionality for Ruby}
+ spec.homepage = "https://github.com/ruby/debug"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = []
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/debug.rb b/lib/debug.rb
index 34d7d27406..bf63ccf34d 100644
--- a/lib/debug.rb
+++ b/lib/debug.rb
@@ -3,8 +3,6 @@
# Copyright (C) 2000 Information-technology Promotion Agency, Japan
# Copyright (C) 2000-2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
-require 'continuation'
-
if $SAFE > 0
STDERR.print "-r debug.rb is not available in safe mode\n"
exit 1
@@ -183,6 +181,9 @@ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ # :nodoc:
class DEBUGGER__
MUTEX = Thread::Mutex.new # :nodoc:
+ CONTINUATIONS_SUPPORTED = RUBY_ENGINE == 'ruby'
+
+ require 'continuation' if CONTINUATIONS_SUPPORTED
class Context # :nodoc:
DEBUG_LAST_CMD = []
@@ -380,8 +381,10 @@ class DEBUGGER__
def debug_command(file, line, id, binding)
MUTEX.lock
- unless defined?($debugger_restart) and $debugger_restart
- callcc{|c| $debugger_restart = c}
+ if CONTINUATIONS_SUPPORTED
+ unless defined?($debugger_restart) and $debugger_restart
+ callcc{|c| $debugger_restart = c}
+ end
end
set_last_thread(Thread.current)
frame_pos = 0
@@ -432,7 +435,7 @@ class DEBUGGER__
pos = $2
if $1
klass = debug_silent_eval($1, binding)
- file = $1
+ file = File.expand_path($1)
end
if pos =~ /^\d+$/
pname = pos
@@ -653,7 +656,11 @@ class DEBUGGER__
stdout.printf "%s\n", debug_eval($', binding).inspect
when /^\s*r(?:estart)?$/
- $debugger_restart.call
+ if CONTINUATIONS_SUPPORTED
+ $debugger_restart.call
+ else
+ stdout.print "Restart requires continuations.\n"
+ end
when /^\s*h(?:elp)?$/
debug_print_help()
@@ -1017,8 +1024,8 @@ EOHELP
#
# (rdb:1) DEBUGGER__.thread_list_all
# +1 #<Thread:0x007fb2320c03f0 run> debug_me.rb.rb:3
- # 2 #<Thread:0x007fb23218a538@debug_me.rb.rb:3 sleep>
- # 3 #<Thread:0x007fb23218b0f0@debug_me.rb.rb:3 sleep>
+ # 2 #<Thread:0x007fb23218a538 debug_me.rb.rb:3 sleep>
+ # 3 #<Thread:0x007fb23218b0f0 debug_me.rb.rb:3 sleep>
# [1, 2, 3]
#
# Your current thread is indicated by a <b>+</b>
@@ -1027,8 +1034,8 @@ EOHELP
#
# (rdb:1) th l
# +1 #<Thread:0x007f99328c0410 run> debug_me.rb:3
- # 2 #<Thread:0x007f9932938230@debug_me.rb:3 sleep> debug_me.rb:3
- # 3 #<Thread:0x007f9932938e10@debug_me.rb:3 sleep> debug_me.rb:3
+ # 2 #<Thread:0x007f9932938230 debug_me.rb:3 sleep> debug_me.rb:3
+ # 3 #<Thread:0x007f9932938e10 debug_me.rb:3 sleep> debug_me.rb:3
#
# See DEBUGGER__ for more usage.
@@ -1102,9 +1109,11 @@ EOHELP
stdout.printf "Debug.rb\n"
stdout.printf "Emacs support available.\n\n"
- RubyVM::InstructionSequence.compile_option = {
- trace_instruction: true
- }
+ if defined?(RubyVM::InstructionSequence)
+ RubyVM::InstructionSequence.compile_option = {
+ trace_instruction: true
+ }
+ end
set_trace_func proc { |event, file, line, id, binding, klass, *rest|
DEBUGGER__.context.trace_func event, file, line, id, binding, klass
}
diff --git a/lib/delegate.rb b/lib/delegate.rb
index c5a94a5d31..a5ae605e9e 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -21,6 +21,8 @@
# SimpleDelegator's implementation serves as a nice example of the use of
# Delegator:
#
+# require 'delegate'
+#
# class SimpleDelegator < Delegator
# def __getobj__
# @delegate_sd_obj # return object we are delegating to, required
@@ -37,6 +39,8 @@
# Be advised, RDoc will not detect delegated methods.
#
class Delegator < BasicObject
+ VERSION = "0.2.0"
+
kernel = ::Kernel.dup
kernel.class_eval do
alias __raise__ raise
@@ -44,7 +48,7 @@ class Delegator < BasicObject
undef_method m
end
private_instance_methods.each do |m|
- if /\Ablock_given\?\z|iterator\?\z|\A__.*__\z/ =~ m
+ if /\Ablock_given\?\z|\Aiterator\?\z|\A__.*__\z/ =~ m
next
end
undef_method m
@@ -60,8 +64,8 @@ class Delegator < BasicObject
##
# :method: raise
- # Use __raise__ if your Delegator does not have a object to delegate the
- # raise method call.
+ # Use #__raise__ if your Delegator does not have a object to delegate the
+ # #raise method call.
#
#
@@ -75,14 +79,14 @@ class Delegator < BasicObject
#
# Handles the magic of delegation through \_\_getobj\_\_.
#
- def method_missing(m, *args, &block)
+ ruby2_keywords def method_missing(m, *args, &block)
r = true
target = self.__getobj__ {r = false}
- if r && target.respond_to?(m)
+ if r && target_respond_to?(target, m, false)
target.__send__(m, *args, &block)
- elsif ::Kernel.respond_to?(m, true)
- ::Kernel.instance_method(m).bind(self).(*args, &block)
+ elsif ::Kernel.method_defined?(m) || ::Kernel.private_method_defined?(m)
+ ::Kernel.instance_method(m).bind_call(self, *args, &block)
else
super(m, *args, &block)
end
@@ -95,14 +99,31 @@ class Delegator < BasicObject
def respond_to_missing?(m, include_private)
r = true
target = self.__getobj__ {r = false}
- r &&= target.respond_to?(m, include_private)
- if r && include_private && !target.respond_to?(m, false)
- warn "#{caller(3)[0]}: delegator does not forward private method \##{m}"
+ r &&= target_respond_to?(target, m, include_private)
+ if r && include_private && !target_respond_to?(target, m, false)
+ warn "delegator does not forward private method \##{m}", uplevel: 3
return false
end
r
end
+ KERNEL_RESPOND_TO = ::Kernel.instance_method(:respond_to?)
+ private_constant :KERNEL_RESPOND_TO
+
+ # Handle BasicObject instances
+ private def target_respond_to?(target, m, include_private)
+ case target
+ when Object
+ target.respond_to?(m, include_private)
+ else
+ if KERNEL_RESPOND_TO.bind_call(target, :respond_to?)
+ target.respond_to?(m, include_private)
+ else
+ KERNEL_RESPOND_TO.bind_call(target, m, include_private)
+ end
+ end
+ end
+
#
# Returns the methods available to this delegate object as the union
# of this object's and \_\_getobj\_\_ methods.
@@ -201,8 +222,8 @@ class Delegator < BasicObject
end
end
- def initialize_clone(obj) # :nodoc:
- self.__setobj__(obj.__getobj__.clone)
+ def initialize_clone(obj, freeze: nil) # :nodoc:
+ self.__setobj__(obj.__getobj__.clone(freeze: freeze))
end
def initialize_dup(obj) # :nodoc:
self.__setobj__(obj.__getobj__.dup)
@@ -210,35 +231,12 @@ class Delegator < BasicObject
private :initialize_clone, :initialize_dup
##
- # :method: trust
- # Trust both the object returned by \_\_getobj\_\_ and self.
- #
-
- ##
- # :method: untrust
- # Untrust both the object returned by \_\_getobj\_\_ and self.
- #
-
- ##
- # :method: taint
- # Taint both the object returned by \_\_getobj\_\_ and self.
- #
-
- ##
- # :method: untaint
- # Untaint both the object returned by \_\_getobj\_\_ and self.
- #
-
- ##
# :method: freeze
# Freeze both the object returned by \_\_getobj\_\_ and self.
#
-
- [:trust, :untrust, :taint, :untaint, :freeze].each do |method|
- define_method method do
- __getobj__.send(method)
- super()
- end
+ def freeze
+ __getobj__.freeze
+ super()
end
@delegator_api = self.public_instance_methods
@@ -259,6 +257,8 @@ end
# end
# end
#
+# require 'delegate'
+#
# class UserDecorator < SimpleDelegator
# def birth_year
# born_on.year
@@ -347,7 +347,7 @@ def Delegator.delegating_block(mid) # :nodoc:
lambda do |*args, &block|
target = self.__getobj__
target.__send__(mid, *args, &block)
- end
+ end.ruby2_keywords
end
#
@@ -360,6 +360,14 @@ end
# end
# end
#
+# or:
+#
+# MyClass = DelegateClass(ClassToDelegateTo) do # Step 1
+# def initialize
+# super(obj_of_ClassToDelegateTo) # Step 2
+# end
+# end
+#
# Here's a sample of use from Tempfile which is really a File object with a
# few special rules about storage location and when the File should be
# deleted. That makes for an almost textbook perfect example of how to use
@@ -383,11 +391,13 @@ end
# # ...
# end
#
-def DelegateClass(superclass)
+def DelegateClass(superclass, &block)
klass = Class.new(Delegator)
- methods = superclass.instance_methods
- methods -= ::Delegator.public_api
- methods -= [:to_s, :inspect, :=~, :!~, :===]
+ ignores = [*::Delegator.public_api, :to_s, :inspect, :=~, :!~, :===]
+ protected_instance_methods = superclass.protected_instance_methods
+ protected_instance_methods -= ignores
+ public_instance_methods = superclass.public_instance_methods
+ public_instance_methods -= ignores
klass.module_eval do
def __getobj__ # :nodoc:
unless defined?(@delegate_dc_obj)
@@ -400,15 +410,35 @@ def DelegateClass(superclass)
__raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
@delegate_dc_obj = obj
end
- methods.each do |method|
+ protected_instance_methods.each do |method|
+ define_method(method, Delegator.delegating_block(method))
+ protected method
+ end
+ public_instance_methods.each do |method|
define_method(method, Delegator.delegating_block(method))
end
end
klass.define_singleton_method :public_instance_methods do |all=true|
- super(all) - superclass.protected_instance_methods
+ super(all) | superclass.public_instance_methods
end
klass.define_singleton_method :protected_instance_methods do |all=true|
super(all) | superclass.protected_instance_methods
end
+ klass.define_singleton_method :instance_methods do |all=true|
+ super(all) | superclass.instance_methods
+ end
+ klass.define_singleton_method :public_instance_method do |name|
+ super(name)
+ rescue NameError
+ raise unless self.public_instance_methods.include?(name)
+ superclass.public_instance_method(name)
+ end
+ klass.define_singleton_method :instance_method do |name|
+ super(name)
+ rescue NameError
+ raise unless self.instance_methods.include?(name)
+ superclass.instance_method(name)
+ end
+ klass.module_eval(&block) if block
return klass
end
diff --git a/lib/delegate/delegate.gemspec b/lib/delegate/delegate.gemspec
new file mode 100644
index 0000000000..05d9ced175
--- /dev/null
+++ b/lib/delegate/delegate.gemspec
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Provides three abilities to delegate method calls to an object.}
+ spec.description = %q{Provides three abilities to delegate method calls to an object.}
+ spec.homepage = "https://github.com/ruby/delegate"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+ spec.required_ruby_version = '>= 2.7'
+end
diff --git a/lib/did_you_mean.rb b/lib/did_you_mean.rb
new file mode 100644
index 0000000000..ab7e6b01a8
--- /dev/null
+++ b/lib/did_you_mean.rb
@@ -0,0 +1,112 @@
+require_relative "did_you_mean/version"
+require_relative "did_you_mean/core_ext/name_error"
+
+require_relative "did_you_mean/spell_checker"
+require_relative 'did_you_mean/spell_checkers/name_error_checkers'
+require_relative 'did_you_mean/spell_checkers/method_name_checker'
+require_relative 'did_you_mean/spell_checkers/key_error_checker'
+require_relative 'did_you_mean/spell_checkers/null_checker'
+require_relative 'did_you_mean/spell_checkers/require_path_checker'
+require_relative 'did_you_mean/formatters/plain_formatter'
+require_relative 'did_you_mean/tree_spell_checker'
+
+# The +DidYouMean+ gem adds functionality to suggest possible method/class
+# names upon errors such as +NameError+ and +NoMethodError+. In Ruby 2.3 or
+# later, it is automatically activated during startup.
+#
+# @example
+#
+# methosd
+# # => NameError: undefined local variable or method `methosd' for main:Object
+# # Did you mean? methods
+# # method
+#
+# OBject
+# # => NameError: uninitialized constant OBject
+# # Did you mean? Object
+#
+# @full_name = "Yuki Nishijima"
+# first_name, last_name = full_name.split(" ")
+# # => NameError: undefined local variable or method `full_name' for main:Object
+# # Did you mean? @full_name
+#
+# @@full_name = "Yuki Nishijima"
+# @@full_anme
+# # => NameError: uninitialized class variable @@full_anme in Object
+# # Did you mean? @@full_name
+#
+# full_name = "Yuki Nishijima"
+# full_name.starts_with?("Y")
+# # => NoMethodError: undefined method `starts_with?' for "Yuki Nishijima":String
+# # Did you mean? start_with?
+#
+# hash = {foo: 1, bar: 2, baz: 3}
+# hash.fetch(:fooo)
+# # => KeyError: key not found: :fooo
+# # Did you mean? :foo
+#
+#
+# == Disabling +did_you_mean+
+#
+# Occasionally, you may want to disable the +did_you_mean+ gem for e.g.
+# debugging issues in the error object itself. You can disable it entirely by
+# specifying +--disable-did_you_mean+ option to the +ruby+ command:
+#
+# $ ruby --disable-did_you_mean -e "1.zeor?"
+# -e:1:in `<main>': undefined method `zeor?' for 1:Integer (NameError)
+#
+# When you do not have direct access to the +ruby+ command (e.g.
+# +rails console+, +irb+), you could applyoptions using the +RUBYOPT+
+# environment variable:
+#
+# $ RUBYOPT='--disable-did_you_mean' irb
+# irb:0> 1.zeor?
+# # => NoMethodError (undefined method `zeor?' for 1:Integer)
+#
+#
+# == Getting the original error message
+#
+# Sometimes, you do not want to disable the gem entirely, but need to get the
+# original error message without suggestions (e.g. testing). In this case, you
+# could use the +#original_message+ method on the error object:
+#
+# no_method_error = begin
+# 1.zeor?
+# rescue NoMethodError => error
+# error
+# end
+#
+# no_method_error.message
+# # => NoMethodError (undefined method `zeor?' for 1:Integer)
+# # Did you mean? zero?
+#
+# no_method_error.original_message
+# # => NoMethodError (undefined method `zeor?' for 1:Integer)
+#
+module DidYouMean
+ # Map of error types and spell checker objects.
+ SPELL_CHECKERS = Hash.new(NullChecker)
+
+ # Adds +DidYouMean+ functionality to an error using a given spell checker
+ def self.correct_error(error_class, spell_checker)
+ SPELL_CHECKERS[error_class.name] = spell_checker
+ error_class.prepend(Correctable) unless error_class < Correctable
+ end
+
+ correct_error NameError, NameErrorCheckers
+ correct_error KeyError, KeyErrorChecker
+ correct_error NoMethodError, MethodNameChecker
+ correct_error LoadError, RequirePathChecker if RUBY_VERSION >= '2.8.0'
+
+ # Returns the currently set formatter. By default, it is set to +DidYouMean::Formatter+.
+ def self.formatter
+ @@formatter
+ end
+
+ # Updates the primary formatter used to format the suggestions.
+ def self.formatter=(formatter)
+ @@formatter = formatter
+ end
+
+ self.formatter = PlainFormatter.new
+end
diff --git a/lib/did_you_mean/core_ext/name_error.rb b/lib/did_you_mean/core_ext/name_error.rb
new file mode 100644
index 0000000000..77dcd520c0
--- /dev/null
+++ b/lib/did_you_mean/core_ext/name_error.rb
@@ -0,0 +1,25 @@
+module DidYouMean
+ module Correctable
+ def original_message
+ method(:to_s).super_method.call
+ end
+
+ def to_s
+ msg = super.dup
+ suggestion = DidYouMean.formatter.message_for(corrections)
+
+ msg << suggestion if !msg.end_with?(suggestion)
+ msg
+ rescue
+ super
+ end
+
+ def corrections
+ @corrections ||= spell_checker.corrections
+ end
+
+ def spell_checker
+ SPELL_CHECKERS[self.class.to_s].new(self)
+ end
+ end
+end
diff --git a/lib/did_you_mean/did_you_mean.gemspec b/lib/did_you_mean/did_you_mean.gemspec
new file mode 100644
index 0000000000..8fe5723129
--- /dev/null
+++ b/lib/did_you_mean/did_you_mean.gemspec
@@ -0,0 +1,27 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+begin
+ require_relative "lib/did_you_mean/version"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "did_you_mean"
+ spec.version = DidYouMean::VERSION
+ spec.authors = ["Yuki Nishijima"]
+ spec.email = ["mail@yukinishijima.net"]
+ spec.summary = '"Did you mean?" experience in Ruby'
+ spec.description = 'The gem that has been saving people from typos since 2014.'
+ spec.homepage = "https://github.com/ruby/did_you_mean"
+ spec.license = "MIT"
+
+ spec.files = `git ls-files`.split($/).reject{|path| path.start_with?('evaluation/') }
+ spec.test_files = spec.files.grep(%r{^(test)/})
+ spec.require_paths = ["lib"]
+
+ spec.required_ruby_version = '>= 2.5.0'
+
+ spec.add_development_dependency "rake"
+end
diff --git a/lib/did_you_mean/experimental.rb b/lib/did_you_mean/experimental.rb
new file mode 100644
index 0000000000..f8e37e4532
--- /dev/null
+++ b/lib/did_you_mean/experimental.rb
@@ -0,0 +1,2 @@
+warn "Experimental features in the did_you_mean gem has been removed " \
+ "and `require \"did_you_mean/experimental\"' has no effect."
diff --git a/lib/did_you_mean/formatters/plain_formatter.rb b/lib/did_you_mean/formatters/plain_formatter.rb
new file mode 100644
index 0000000000..e2d995f587
--- /dev/null
+++ b/lib/did_you_mean/formatters/plain_formatter.rb
@@ -0,0 +1,33 @@
+# frozen-string-literal: true
+
+module DidYouMean
+ # The +DidYouMean::PlainFormatter+ is the basic, default formatter for the
+ # gem. The formatter responds to the +message_for+ method and it returns a
+ # human readable string.
+ class PlainFormatter
+
+ # Returns a human readable string that contains +corrections+. This
+ # formatter is designed to be less verbose to not take too much screen
+ # space while being helpful enough to the user.
+ #
+ # @example
+ #
+ # formatter = DidYouMean::PlainFormatter.new
+ #
+ # # displays suggestions in two lines with the leading empty line
+ # puts formatter.message_for(["methods", "method"])
+ #
+ # Did you mean? methods
+ # method
+ # # => nil
+ #
+ # # displays an empty line
+ # puts formatter.message_for([])
+ #
+ # # => nil
+ #
+ def message_for(corrections)
+ corrections.empty? ? "" : "\nDid you mean? #{corrections.join("\n ")}"
+ end
+ end
+end
diff --git a/lib/did_you_mean/formatters/verbose_formatter.rb b/lib/did_you_mean/formatters/verbose_formatter.rb
new file mode 100644
index 0000000000..b8fe214d57
--- /dev/null
+++ b/lib/did_you_mean/formatters/verbose_formatter.rb
@@ -0,0 +1,49 @@
+# frozen-string-literal: true
+
+module DidYouMean
+ # The +DidYouMean::VerboseFormatter+ uses extra empty lines to make the
+ # suggestion stand out more in the error message.
+ #
+ # In order to activate the verbose formatter,
+ #
+ # @example
+ #
+ # OBject
+ # # => NameError: uninitialized constant OBject
+ # # Did you mean? Object
+ #
+ # require 'did_you_mean/verbose'
+ #
+ # OBject
+ # # => NameError: uninitialized constant OBject
+ # #
+ # # Did you mean? Object
+ # #
+ #
+ class VerboseFormatter
+
+ # Returns a human readable string that contains +corrections+. This
+ # formatter is designed to be less verbose to not take too much screen
+ # space while being helpful enough to the user.
+ #
+ # @example
+ #
+ # formatter = DidYouMean::PlainFormatter.new
+ #
+ # puts formatter.message_for(["methods", "method"])
+ #
+ #
+ # Did you mean? methods
+ # method
+ #
+ # # => nil
+ #
+ def message_for(corrections)
+ return "" if corrections.empty?
+
+ output = "\n\n Did you mean? ".dup
+ output << corrections.join("\n ")
+ output << "\n "
+ end
+ end
+end
diff --git a/lib/did_you_mean/jaro_winkler.rb b/lib/did_you_mean/jaro_winkler.rb
new file mode 100644
index 0000000000..56db130af4
--- /dev/null
+++ b/lib/did_you_mean/jaro_winkler.rb
@@ -0,0 +1,87 @@
+module DidYouMean
+ module Jaro
+ module_function
+
+ def distance(str1, str2)
+ str1, str2 = str2, str1 if str1.length > str2.length
+ length1, length2 = str1.length, str2.length
+
+ m = 0.0
+ t = 0.0
+ range = (length2 / 2).floor - 1
+ range = 0 if range < 0
+ flags1 = 0
+ flags2 = 0
+
+ # Avoid duplicating enumerable objects
+ str1_codepoints = str1.codepoints
+ str2_codepoints = str2.codepoints
+
+ i = 0
+ while i < length1
+ last = i + range
+ j = (i >= range) ? i - range : 0
+
+ while j <= last
+ if flags2[j] == 0 && str1_codepoints[i] == str2_codepoints[j]
+ flags2 |= (1 << j)
+ flags1 |= (1 << i)
+ m += 1
+ break
+ end
+
+ j += 1
+ end
+
+ i += 1
+ end
+
+ k = i = 0
+ while i < length1
+ if flags1[i] != 0
+ j = index = k
+
+ k = while j < length2
+ index = j
+ break(j + 1) if flags2[j] != 0
+
+ j += 1
+ end
+
+ t += 1 if str1_codepoints[i] != str2_codepoints[index]
+ end
+
+ i += 1
+ end
+ t = (t / 2).floor
+
+ m == 0 ? 0 : (m / length1 + m / length2 + (m - t) / m) / 3
+ end
+ end
+
+ module JaroWinkler
+ WEIGHT = 0.1
+ THRESHOLD = 0.7
+
+ module_function
+
+ def distance(str1, str2)
+ jaro_distance = Jaro.distance(str1, str2)
+
+ if jaro_distance > THRESHOLD
+ codepoints2 = str2.codepoints
+ prefix_bonus = 0
+
+ i = 0
+ str1.each_codepoint do |char1|
+ char1 == codepoints2[i] && i < 4 ? prefix_bonus += 1 : break
+ i += 1
+ end
+
+ jaro_distance + (prefix_bonus * WEIGHT * (1 - jaro_distance))
+ else
+ jaro_distance
+ end
+ end
+ end
+end
diff --git a/lib/did_you_mean/levenshtein.rb b/lib/did_you_mean/levenshtein.rb
new file mode 100644
index 0000000000..098053470f
--- /dev/null
+++ b/lib/did_you_mean/levenshtein.rb
@@ -0,0 +1,57 @@
+module DidYouMean
+ module Levenshtein # :nodoc:
+ # This code is based directly on the Text gem implementation
+ # Copyright (c) 2006-2013 Paul Battley, Michael Neumann, Tim Fletcher.
+ #
+ # Returns a value representing the "cost" of transforming str1 into str2
+ def distance(str1, str2)
+ n = str1.length
+ m = str2.length
+ return m if n.zero?
+ return n if m.zero?
+
+ d = (0..m).to_a
+ x = nil
+
+ # to avoid duplicating an enumerable object, create it outside of the loop
+ str2_codepoints = str2.codepoints
+
+ str1.each_codepoint.with_index(1) do |char1, i|
+ j = 0
+ while j < m
+ cost = (char1 == str2_codepoints[j]) ? 0 : 1
+ x = min3(
+ d[j+1] + 1, # insertion
+ i + 1, # deletion
+ d[j] + cost # substitution
+ )
+ d[j] = i
+ i = x
+
+ j += 1
+ end
+ d[m] = x
+ end
+
+ x
+ end
+ module_function :distance
+
+ private
+
+ # detects the minimum value out of three arguments. This method is
+ # faster than `[a, b, c].min` and puts less GC pressure.
+ # See https://github.com/ruby/did_you_mean/pull/1 for a performance
+ # benchmark.
+ def min3(a, b, c)
+ if a < b && a < c
+ a
+ elsif b < c
+ b
+ else
+ c
+ end
+ end
+ module_function :min3
+ end
+end
diff --git a/lib/did_you_mean/spell_checker.rb b/lib/did_you_mean/spell_checker.rb
new file mode 100644
index 0000000000..e5106abba2
--- /dev/null
+++ b/lib/did_you_mean/spell_checker.rb
@@ -0,0 +1,46 @@
+# frozen-string-literal: true
+
+require_relative "levenshtein"
+require_relative "jaro_winkler"
+
+module DidYouMean
+ class SpellChecker
+ def initialize(dictionary:)
+ @dictionary = dictionary
+ end
+
+ def correct(input)
+ input = normalize(input)
+ threshold = input.length > 3 ? 0.834 : 0.77
+
+ words = @dictionary.select { |word| JaroWinkler.distance(normalize(word), input) >= threshold }
+ words.reject! { |word| input == word.to_s }
+ words.sort_by! { |word| JaroWinkler.distance(word.to_s, input) }
+ words.reverse!
+
+ # Correct mistypes
+ threshold = (input.length * 0.25).ceil
+ corrections = words.select { |c| Levenshtein.distance(normalize(c), input) <= threshold }
+
+ # Correct misspells
+ if corrections.empty?
+ corrections = words.select do |word|
+ word = normalize(word)
+ length = input.length < word.length ? input.length : word.length
+
+ Levenshtein.distance(word, input) < length
+ end.first(1)
+ end
+
+ corrections
+ end
+
+ private
+
+ def normalize(str_or_symbol) #:nodoc:
+ str = str_or_symbol.to_s.downcase
+ str.tr!("@", "")
+ str
+ end
+ end
+end
diff --git a/lib/did_you_mean/spell_checkers/key_error_checker.rb b/lib/did_you_mean/spell_checkers/key_error_checker.rb
new file mode 100644
index 0000000000..be4bea7789
--- /dev/null
+++ b/lib/did_you_mean/spell_checkers/key_error_checker.rb
@@ -0,0 +1,20 @@
+require_relative "../spell_checker"
+
+module DidYouMean
+ class KeyErrorChecker
+ def initialize(key_error)
+ @key = key_error.key
+ @keys = key_error.receiver.keys
+ end
+
+ def corrections
+ @corrections ||= exact_matches.empty? ? SpellChecker.new(dictionary: @keys).correct(@key).map(&:inspect) : exact_matches
+ end
+
+ private
+
+ def exact_matches
+ @exact_matches ||= @keys.select { |word| @key == word.to_s }.map(&:inspect)
+ end
+ end
+end
diff --git a/lib/did_you_mean/spell_checkers/method_name_checker.rb b/lib/did_you_mean/spell_checkers/method_name_checker.rb
new file mode 100644
index 0000000000..0483127d6f
--- /dev/null
+++ b/lib/did_you_mean/spell_checkers/method_name_checker.rb
@@ -0,0 +1,69 @@
+require_relative "../spell_checker"
+
+module DidYouMean
+ class MethodNameChecker
+ attr_reader :method_name, :receiver
+
+ NAMES_TO_EXCLUDE = { NilClass => nil.methods }
+ NAMES_TO_EXCLUDE.default = []
+
+ # +MethodNameChecker::RB_RESERVED_WORDS+ is the list of reserved words in
+ # Ruby that take an argument. Unlike
+ # +VariableNameChecker::RB_RESERVED_WORDS+, these reserved words require
+ # an argument, and a +NoMethodError+ is raised due to the presence of the
+ # argument.
+ #
+ # The +MethodNameChecker+ will use this list to suggest a reversed word if
+ # a +NoMethodError+ is raised and found closest matches.
+ #
+ # Also see +VariableNameChecker::RB_RESERVED_WORDS+.
+ RB_RESERVED_WORDS = %i(
+ alias
+ case
+ def
+ defined?
+ elsif
+ end
+ ensure
+ for
+ rescue
+ super
+ undef
+ unless
+ until
+ when
+ while
+ yield
+ )
+
+ def initialize(exception)
+ @method_name = exception.name
+ @receiver = exception.receiver
+ @private_call = exception.respond_to?(:private_call?) ? exception.private_call? : false
+ end
+
+ def corrections
+ @corrections ||= begin
+ dictionary = method_names
+ dictionary = RB_RESERVED_WORDS + dictionary if @private_call
+
+ SpellChecker.new(dictionary: dictionary).correct(method_name) - names_to_exclude
+ end
+ end
+
+ def method_names
+ if Object === receiver
+ method_names = receiver.methods + receiver.singleton_methods
+ method_names += receiver.private_methods if @private_call
+ method_names.uniq!
+ method_names
+ else
+ []
+ end
+ end
+
+ def names_to_exclude
+ Object === receiver ? NAMES_TO_EXCLUDE[receiver.class] : []
+ end
+ end
+end
diff --git a/lib/did_you_mean/spell_checkers/name_error_checkers.rb b/lib/did_you_mean/spell_checkers/name_error_checkers.rb
new file mode 100644
index 0000000000..6e2aaa4cb1
--- /dev/null
+++ b/lib/did_you_mean/spell_checkers/name_error_checkers.rb
@@ -0,0 +1,20 @@
+require_relative 'name_error_checkers/class_name_checker'
+require_relative 'name_error_checkers/variable_name_checker'
+
+module DidYouMean
+ class << (NameErrorCheckers = Object.new)
+ def new(exception)
+ case exception.original_message
+ when /uninitialized constant/
+ ClassNameChecker
+ when /undefined local variable or method/,
+ /undefined method/,
+ /uninitialized class variable/,
+ /no member '.*' in struct/
+ VariableNameChecker
+ else
+ NullChecker
+ end.new(exception)
+ end
+ end
+end
diff --git a/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb b/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
new file mode 100644
index 0000000000..924265b929
--- /dev/null
+++ b/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
@@ -0,0 +1,49 @@
+# frozen-string-literal: true
+
+require_relative "../../spell_checker"
+
+module DidYouMean
+ class ClassNameChecker
+ attr_reader :class_name
+
+ def initialize(exception)
+ @class_name, @receiver, @original_message = exception.name, exception.receiver, exception.original_message
+ end
+
+ def corrections
+ @corrections ||= SpellChecker.new(dictionary: class_names)
+ .correct(class_name)
+ .map(&:full_name)
+ .reject {|qualified_name| @original_message.include?(qualified_name) }
+ end
+
+ def class_names
+ scopes.flat_map do |scope|
+ scope.constants.map do |c|
+ ClassName.new(c, scope == Object ? "" : "#{scope}::")
+ end
+ end
+ end
+
+ def scopes
+ @scopes ||= @receiver.to_s.split("::").inject([Object]) do |_scopes, scope|
+ _scopes << _scopes.last.const_get(scope)
+ end.uniq
+ end
+
+ class ClassName < String
+ attr :namespace
+
+ def initialize(name, namespace = '')
+ super(name.to_s)
+ @namespace = namespace
+ end
+
+ def full_name
+ self.class.new("#{namespace}#{self}")
+ end
+ end
+
+ private_constant :ClassName
+ end
+end
diff --git a/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb b/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
new file mode 100644
index 0000000000..3e51b4fa3a
--- /dev/null
+++ b/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
@@ -0,0 +1,82 @@
+# frozen-string-literal: true
+
+require_relative "../../spell_checker"
+
+module DidYouMean
+ class VariableNameChecker
+ attr_reader :name, :method_names, :lvar_names, :ivar_names, :cvar_names
+
+ NAMES_TO_EXCLUDE = { 'foo' => [:fork, :for] }
+ NAMES_TO_EXCLUDE.default = []
+
+ # +VariableNameChecker::RB_RESERVED_WORDS+ is the list of all reserved
+ # words in Ruby. They could be declared like methods are, and a typo would
+ # cause Ruby to raise a +NameError+ because of the way they are declared.
+ #
+ # The +:VariableNameChecker+ will use this list to suggest a reversed word
+ # if a +NameError+ is raised and found closest matches, excluding:
+ #
+ # * +do+
+ # * +if+
+ # * +in+
+ # * +or+
+ #
+ # Also see +MethodNameChecker::RB_RESERVED_WORDS+.
+ RB_RESERVED_WORDS = %i(
+ BEGIN
+ END
+ alias
+ and
+ begin
+ break
+ case
+ class
+ def
+ defined?
+ else
+ elsif
+ end
+ ensure
+ false
+ for
+ module
+ next
+ nil
+ not
+ redo
+ rescue
+ retry
+ return
+ self
+ super
+ then
+ true
+ undef
+ unless
+ until
+ when
+ while
+ yield
+ __LINE__
+ __FILE__
+ __ENCODING__
+ )
+
+ def initialize(exception)
+ @name = exception.name.to_s.tr("@", "")
+ @lvar_names = exception.respond_to?(:local_variables) ? exception.local_variables : []
+ receiver = exception.receiver
+
+ @method_names = receiver.methods + receiver.private_methods
+ @ivar_names = receiver.instance_variables
+ @cvar_names = receiver.class.class_variables
+ @cvar_names += receiver.class_variables if receiver.kind_of?(Module)
+ end
+
+ def corrections
+ @corrections ||= SpellChecker
+ .new(dictionary: (RB_RESERVED_WORDS + lvar_names + method_names + ivar_names + cvar_names))
+ .correct(name) - NAMES_TO_EXCLUDE[@name]
+ end
+ end
+end
diff --git a/lib/did_you_mean/spell_checkers/null_checker.rb b/lib/did_you_mean/spell_checkers/null_checker.rb
new file mode 100644
index 0000000000..1306f69d4a
--- /dev/null
+++ b/lib/did_you_mean/spell_checkers/null_checker.rb
@@ -0,0 +1,6 @@
+module DidYouMean
+ class NullChecker
+ def initialize(*); end
+ def corrections; [] end
+ end
+end
diff --git a/lib/did_you_mean/spell_checkers/require_path_checker.rb b/lib/did_you_mean/spell_checkers/require_path_checker.rb
new file mode 100644
index 0000000000..aaf877b412
--- /dev/null
+++ b/lib/did_you_mean/spell_checkers/require_path_checker.rb
@@ -0,0 +1,35 @@
+# frozen-string-literal: true
+
+require_relative "../spell_checker"
+require_relative "../tree_spell_checker"
+
+module DidYouMean
+ class RequirePathChecker
+ attr_reader :path
+
+ INITIAL_LOAD_PATH = $LOAD_PATH.dup.freeze
+ ENV_SPECIFIC_EXT = ".#{RbConfig::CONFIG["DLEXT"]}"
+
+ private_constant :INITIAL_LOAD_PATH, :ENV_SPECIFIC_EXT
+
+ def self.requireables
+ @requireables ||= INITIAL_LOAD_PATH
+ .flat_map {|path| Dir.glob("**/???*{.rb,#{ENV_SPECIFIC_EXT}}", base: path) }
+ .map {|path| path.chomp!(".rb") || path.chomp!(ENV_SPECIFIC_EXT) }
+ end
+
+ def initialize(exception)
+ @path = exception.path
+ end
+
+ def corrections
+ @corrections ||= begin
+ threshold = path.size * 2
+ dictionary = self.class.requireables.reject {|str| str.size >= threshold }
+ spell_checker = path.include?("/") ? TreeSpellChecker : SpellChecker
+
+ spell_checker.new(dictionary: dictionary).correct(path).uniq
+ end
+ end
+ end
+end
diff --git a/lib/did_you_mean/tree_spell_checker.rb b/lib/did_you_mean/tree_spell_checker.rb
new file mode 100644
index 0000000000..799f07fcf0
--- /dev/null
+++ b/lib/did_you_mean/tree_spell_checker.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+module DidYouMean
+ # spell checker for a dictionary that has a tree
+ # structure, see doc/tree_spell_checker_api.md
+ class TreeSpellChecker
+ attr_reader :dictionary, :separator, :augment
+
+ def initialize(dictionary:, separator: '/', augment: nil)
+ @dictionary = dictionary
+ @separator = separator
+ @augment = augment
+ end
+
+ def correct(input)
+ plausibles = plausible_dimensions(input)
+ return fall_back_to_normal_spell_check(input) if plausibles.empty?
+
+ suggestions = find_suggestions(input, plausibles)
+ return fall_back_to_normal_spell_check(input) if suggestions.empty?
+
+ suggestions
+ end
+
+ def dictionary_without_leaves
+ @dictionary_without_leaves ||= dictionary.map { |word| word.split(separator)[0..-2] }.uniq
+ end
+
+ def tree_depth
+ @tree_depth ||= dictionary_without_leaves.max { |a, b| a.size <=> b.size }.size
+ end
+
+ def dimensions
+ @dimensions ||= tree_depth.times.map do |index|
+ dictionary_without_leaves.map { |element| element[index] }.compact.uniq
+ end
+ end
+
+ def find_leaves(path)
+ path_with_separator = "#{path}#{separator}"
+
+ dictionary
+ .select {|str| str.include?(path_with_separator) }
+ .map {|str| str.gsub(path_with_separator, '') }
+ end
+
+ def plausible_dimensions(input)
+ input.split(separator)[0..-2]
+ .map
+ .with_index { |element, index| correct_element(dimensions[index], element) if dimensions[index] }
+ .compact
+ end
+
+ def possible_paths(states)
+ states.map { |state| state.join(separator) }
+ end
+
+ private
+
+ def find_suggestions(input, plausibles)
+ states = plausibles[0].product(*plausibles[1..-1])
+ paths = possible_paths(states)
+ leaf = input.split(separator).last
+
+ find_ideas(paths, leaf)
+ end
+
+ def fall_back_to_normal_spell_check(input)
+ return [] unless augment
+
+ ::DidYouMean::SpellChecker.new(dictionary: dictionary).correct(input)
+ end
+
+ def find_ideas(paths, leaf)
+ paths.flat_map do |path|
+ names = find_leaves(path)
+ ideas = correct_element(names, leaf)
+
+ ideas_to_paths(ideas, leaf, names, path)
+ end.compact
+ end
+
+ def ideas_to_paths(ideas, leaf, names, path)
+ if ideas.empty?
+ nil
+ elsif names.include?(leaf)
+ ["#{path}#{separator}#{leaf}"]
+ else
+ ideas.map {|str| "#{path}#{separator}#{str}" }
+ end
+ end
+
+ def correct_element(names, element)
+ return names if names.size == 1
+
+ str = normalize(element)
+
+ return [str] if names.include?(str)
+
+ ::DidYouMean::SpellChecker.new(dictionary: names).correct(str)
+ end
+
+ def normalize(str)
+ str.downcase!
+ str.tr!('@', ' ') if str.include?('@')
+ str
+ end
+ end
+end
diff --git a/lib/did_you_mean/verbose.rb b/lib/did_you_mean/verbose.rb
new file mode 100644
index 0000000000..4e86f167ea
--- /dev/null
+++ b/lib/did_you_mean/verbose.rb
@@ -0,0 +1,4 @@
+require_relative '../did_you_mean'
+require_relative 'formatters/verbose_formatter'
+
+DidYouMean.formatter = DidYouMean::VerboseFormatter.new
diff --git a/lib/did_you_mean/version.rb b/lib/did_you_mean/version.rb
new file mode 100644
index 0000000000..9a53a3185a
--- /dev/null
+++ b/lib/did_you_mean/version.rb
@@ -0,0 +1,3 @@
+module DidYouMean
+ VERSION = "1.5.0"
+end
diff --git a/lib/drb/acl.rb b/lib/drb/acl.rb
index 7b50644fe4..b004656f09 100644
--- a/lib/drb/acl.rb
+++ b/lib/drb/acl.rb
@@ -49,6 +49,9 @@ class ACL
# +str+ may be "*" or "all" to match any address, an IP address string
# to match a specific address, an IP address mask per IPAddr, or one
# containing "*" to match part of an IPv4 address.
+ #
+ # IPAddr::InvalidPrefixError may be raised when an IP network
+ # address with an invalid netmask/prefix is given.
def initialize(str)
if str == '*' or str == 'all'
@@ -58,6 +61,10 @@ class ACL
else
begin
@pat = [:ip, IPAddr.new(str)]
+ rescue IPAddr::InvalidPrefixError
+ # In this case, `str` shouldn't be a host name pattern
+ # because it contains a slash.
+ raise
rescue ArgumentError
@pat = [:name, dot_pat(str)]
end
diff --git a/lib/drb/drb.gemspec b/lib/drb/drb.gemspec
new file mode 100644
index 0000000000..6b31e896c3
--- /dev/null
+++ b/lib/drb/drb.gemspec
@@ -0,0 +1,30 @@
+begin
+ require_relative "lib/drb/version"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "drb"
+ spec.version = DRb::VERSION
+ spec.authors = ["Masatoshi SEKI"]
+ spec.email = ["seki@ruby-lang.org"]
+
+ spec.summary = %q{Distributed object system for Ruby}
+ spec.description = %q{Distributed object system for Ruby}
+ spec.homepage = "https://github.com/ruby/drb"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb
index 1d654b3c9f..3e23213911 100644
--- a/lib/drb/drb.rb
+++ b/lib/drb/drb.rb
@@ -48,7 +48,8 @@
require 'socket'
require 'io/wait'
-require 'drb/eq'
+require 'monitor'
+require_relative 'eq'
#
# == Overview
@@ -159,8 +160,6 @@ require 'drb/eq'
# # The object that handles requests on the server
# FRONT_OBJECT=TimeServer.new
#
-# $SAFE = 1 # disable eval() and friends
-#
# DRb.start_service(URI, FRONT_OBJECT)
# # Wait for the drb server thread to finish before exiting.
# DRb.thread.join
@@ -234,7 +233,7 @@ require 'drb/eq'
# def get_logger(name)
# if !@loggers.has_key? name
# # make the filename safe, then declare it to be so
-# fname = name.gsub(/[.\/\\\:]/, "_").untaint
+# fname = name.gsub(/[.\/\\\:]/, "_")
# @loggers[name] = Logger.new(name, @basedir + "/" + fname)
# end
# return @loggers[name]
@@ -244,8 +243,6 @@ require 'drb/eq'
#
# FRONT_OBJECT=LoggerFactory.new("/tmp/dlog")
#
-# $SAFE = 1 # disable eval() and friends
-#
# DRb.start_service(URI, FRONT_OBJECT)
# DRb.thread.join
#
@@ -285,10 +282,7 @@ require 'drb/eq'
# ro.instance_eval("`rm -rf *`")
#
# The dangers posed by instance_eval and friends are such that a
-# DRbServer should generally be run with $SAFE set to at least
-# level 1. This will disable eval() and related calls on strings
-# passed across the wire. The sample usage code given above follows
-# this practice.
+# DRbServer should only be used when clients are trusted.
#
# A DRbServer can be configured with an access control list to
# selectively allow or deny access from specified IP addresses. The
@@ -360,7 +354,7 @@ module DRb
# drb remains valid only while that object instance remains alive
# within the server runtime.
#
- # For alternative mechanisms, see DRb::TimerIdConv in rdb/timeridconv.rb
+ # For alternative mechanisms, see DRb::TimerIdConv in drb/timeridconv.rb
# and DRbNameIdConv in sample/name.rb in the full drb distribution.
class DRbIdConv
@@ -377,7 +371,12 @@ module DRb
# This implementation returns the object's __id__ in the local
# object space.
def to_id(obj)
- obj.nil? ? nil : obj.__id__
+ case obj
+ when Object
+ obj.nil? ? nil : obj.__id__
+ when BasicObject
+ obj.__id__
+ end
end
end
@@ -560,7 +559,14 @@ module DRb
end
def dump(obj, error=false) # :nodoc:
- obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped
+ case obj
+ when DRbUndumped
+ obj = make_proxy(obj, error)
+ when Object
+ # nothing
+ else
+ obj = make_proxy(obj, error)
+ end
begin
str = Marshal::dump(obj)
rescue
@@ -588,16 +594,9 @@ module DRb
raise(DRbConnError, 'premature marshal format(can\'t read)') if str.size < sz
DRb.mutex.synchronize do
begin
- save = Thread.current[:drb_untaint]
- Thread.current[:drb_untaint] = []
Marshal::load(str)
rescue NameError, ArgumentError
DRbUnknown.new($!, str)
- ensure
- Thread.current[:drb_untaint].each do |x|
- x.untaint
- end
- Thread.current[:drb_untaint] = save
end
end
end
@@ -800,7 +799,7 @@ module DRb
module_function :uri_option
def auto_load(uri) # :nodoc:
- if uri =~ /^drb([a-z0-9]+):/
+ if /\Adrb([a-z0-9]+):/ =~ uri
require("drb/#{$1}") rescue nil
end
end
@@ -816,13 +815,13 @@ module DRb
# :stopdoc:
private
def self.parse_uri(uri)
- if uri =~ /^druby:\/\/(.*?):(\d+)(\?(.*))?$/
+ if /\Adruby:\/\/(.*?):(\d+)(\?(.*))?\z/ =~ uri
host = $1
port = $2.to_i
option = $4
[host, port, option]
else
- raise(DRbBadScheme, uri) unless uri =~ /^druby:/
+ raise(DRbBadScheme, uri) unless uri.start_with?('druby:')
raise(DRbBadURI, 'can\'t parse uri:' + uri)
end
end
@@ -837,8 +836,6 @@ module DRb
# URI protocols.
def self.open(uri, config)
host, port, = parse_uri(uri)
- host.untaint
- port.untaint
soc = TCPSocket.open(host, port)
self.new(uri, soc, config)
end
@@ -847,7 +844,11 @@ module DRb
def self.getservername
host = Socket::gethostname
begin
- Socket::gethostbyname(host)[0]
+ Socket::getaddrinfo(host, nil,
+ Socket::AF_UNSPEC,
+ Socket::SOCK_STREAM,
+ 0,
+ Socket::AI_PASSIVE)[0][3]
rescue
'localhost'
end
@@ -949,6 +950,7 @@ module DRb
# returned by #open or by #accept, then it closes this particular
# client-server session.
def close
+ shutdown
if @socket
@socket.close
@socket = nil
@@ -957,14 +959,8 @@ module DRb
end
def close_shutdown_pipe
- if @shutdown_pipe_r && !@shutdown_pipe_r.closed?
- @shutdown_pipe_r.close
- @shutdown_pipe_r = nil
- end
- if @shutdown_pipe_w && !@shutdown_pipe_w.closed?
- @shutdown_pipe_w.close
- @shutdown_pipe_w = nil
- end
+ @shutdown_pipe_w.close
+ @shutdown_pipe_r.close
end
private :close_shutdown_pipe
@@ -997,7 +993,7 @@ module DRb
# Graceful shutdown
def shutdown
- @shutdown_pipe_w.close if @shutdown_pipe_w && !@shutdown_pipe_w.closed?
+ @shutdown_pipe_w.close
end
# Check to see if this connection is alive.
@@ -1012,6 +1008,8 @@ module DRb
def set_sockopt(soc) # :nodoc:
soc.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
+ rescue IOError, Errno::ECONNRESET, Errno::EINVAL
+ # closed/shutdown socket, ignore error
end
end
@@ -1054,9 +1052,6 @@ module DRb
if DRb.here?(uri)
obj = DRb.to_obj(ref)
- if ((! obj.tainted?) && Thread.current[:drb_untaint])
- Thread.current[:drb_untaint].push(obj)
- end
return obj
end
@@ -1093,7 +1088,14 @@ module DRb
def initialize(obj, uri=nil)
@uri = nil
@ref = nil
- if obj.nil?
+ case obj
+ when Object
+ is_nil = obj.nil?
+ when BasicObject
+ is_nil = false
+ end
+
+ if is_nil
return if uri.nil?
@uri, option = DRbProtocol.uri_option(uri, DRb.config)
@ref = DRbURIOption.new(option) unless option.nil?
@@ -1129,7 +1131,7 @@ module DRb
end
# Routes method calls to the referenced remote object.
- def method_missing(msg_id, *a, &b)
+ ruby2_keywords def method_missing(msg_id, *a, &b)
if DRb.here?(@uri)
obj = DRb.to_obj(@ref)
DRb.current_server.check_insecure_method(obj, msg_id)
@@ -1172,7 +1174,7 @@ module DRb
bt = []
result.backtrace.each do |x|
break if /`__send__'$/ =~ x
- if /^\(druby:\/\// =~ x
+ if /\A\(druby:\/\// =~ x
bt.push(x)
else
bt.push(prefix + x)
@@ -1193,6 +1195,54 @@ module DRb
end
end
+ class ThreadObject
+ include MonitorMixin
+
+ def initialize(&blk)
+ super()
+ @wait_ev = new_cond
+ @req_ev = new_cond
+ @res_ev = new_cond
+ @status = :wait
+ @req = nil
+ @res = nil
+ @thread = Thread.new(self, &blk)
+ end
+
+ def alive?
+ @thread.alive?
+ end
+
+ def kill
+ @thread.kill
+ @thread.join
+ end
+
+ def method_missing(msg, *arg, &blk)
+ synchronize do
+ @wait_ev.wait_until { @status == :wait }
+ @req = [msg] + arg
+ @status = :req
+ @req_ev.broadcast
+ @res_ev.wait_until { @status == :res }
+ value = @res
+ @req = @res = nil
+ @status = :wait
+ @wait_ev.broadcast
+ return value
+ end
+ end
+
+ def _execute()
+ synchronize do
+ @req_ev.wait_until { @status == :req }
+ @res = yield(@req)
+ @status = :res
+ @res_ev.signal
+ end
+ end
+ end
+
# Class handling the connection between a DRbObject and the
# server the real object lives on.
#
@@ -1204,26 +1254,50 @@ module DRb
# not normally need to deal with it directly.
class DRbConn
POOL_SIZE = 16 # :nodoc:
- @mutex = Thread::Mutex.new
- @pool = []
- def self.open(remote_uri) # :nodoc:
- begin
- conn = nil
-
- @mutex.synchronize do
- #FIXME
- new_pool = []
- @pool.each do |c|
- if conn.nil? and c.uri == remote_uri
- conn = c if c.alive?
+ def self.make_pool
+ ThreadObject.new do |queue|
+ pool = []
+ while true
+ queue._execute do |message|
+ case(message[0])
+ when :take then
+ remote_uri = message[1]
+ conn = nil
+ new_pool = []
+ pool.each do |c|
+ if conn.nil? and c.uri == remote_uri
+ conn = c if c.alive?
+ else
+ new_pool.push c
+ end
+ end
+ pool = new_pool
+ conn
+ when :store then
+ conn = message[1]
+ pool.unshift(conn)
+ pool.pop.close while pool.size > POOL_SIZE
+ conn
else
- new_pool.push c
+ nil
end
end
- @pool = new_pool
end
+ end
+ end
+ @pool_proxy = nil
+ def self.stop_pool
+ @pool_proxy&.kill
+ @pool_proxy = nil
+ end
+
+ def self.open(remote_uri) # :nodoc:
+ begin
+ @pool_proxy = make_pool unless @pool_proxy&.alive?
+
+ conn = @pool_proxy.take(remote_uri)
conn = self.new(remote_uri) unless conn
succ, result = yield(conn)
return succ, result
@@ -1231,10 +1305,7 @@ module DRb
ensure
if conn
if succ
- @mutex.synchronize do
- @pool.unshift(conn)
- @pool.pop.close while @pool.size > POOL_SIZE
- end
+ @pool_proxy.store(conn)
else
conn.close
end
@@ -1280,9 +1351,8 @@ module DRb
@@idconv = DRbIdConv.new
@@secondary_server = nil
@@argc_limit = 256
- @@load_limit = 256 * 102400
+ @@load_limit = 0xffffffff
@@verbose = false
- @@safe_level = 0
# Set the default value for the :argc_limit option.
#
@@ -1312,13 +1382,6 @@ module DRb
@@idconv = idconv
end
- # Set the default safe level to +level+. The default safe level is 0
- #
- # See #new for more information.
- def self.default_safe_level(level)
- @@safe_level = level
- end
-
# Set the default value of the :verbose option.
#
# See #new(). The initial default value is false.
@@ -1338,7 +1401,6 @@ module DRb
:tcp_acl => @@acl,
:load_limit => @@load_limit,
:argc_limit => @@argc_limit,
- :safe_level => @@safe_level
}
default_config.update(hash)
end
@@ -1372,10 +1434,6 @@ module DRb
# :argc_limit :: the maximum number of arguments to a remote
# method accepted by the server. Defaults to
# 256.
- # :safe_level :: The safe level of the DRbServer. The attribute
- # sets $SAFE for methods performed in the main_loop.
- # Defaults to 0.
- #
# The default values of these options can be modified on
# a class-wide basis by the class methods #default_argc_limit,
# #default_load_limit, #default_acl, #default_id_conv,
@@ -1407,7 +1465,6 @@ module DRb
@front = front
@idconv = @config[:idconv]
- @safe_level = @config[:safe_level]
@grp = ThreadGroup.new
@thread = run
@@ -1434,12 +1491,6 @@ module DRb
# The configuration of this DRbServer
attr_reader :config
- # The safe level for this server. This is a number corresponding to
- # $SAFE.
- #
- # The default safe_level is 0
- attr_reader :safe_level
-
# Set whether to operate in verbose mode.
#
# In verbose mode, failed calls are logged to stdout.
@@ -1466,12 +1517,7 @@ module DRb
if Thread.current['DRb'] && Thread.current['DRb']['server'] == self
Thread.current['DRb']['stop_service'] = true
else
- if @protocol.respond_to? :shutdown
- @protocol.shutdown
- else
- [@thread, *@grp.list].each {|thread| thread.kill} # xxx: Thread#kill
- end
- @thread.join
+ shutdown
end
end
@@ -1490,6 +1536,18 @@ module DRb
private
+ def shutdown
+ current = Thread.current
+ if @protocol.respond_to? :shutdown
+ @protocol.shutdown
+ else
+ [@thread, *@grp.list].each { |thread|
+ thread.kill unless thread == current # xxx: Thread#kill
+ }
+ end
+ @thread.join unless @thread == current
+ end
+
##
# Starts the DRb main loop in a new thread.
@@ -1519,9 +1577,9 @@ module DRb
# Coerce an object to a string, providing our own representation if
# to_s is not defined for the object.
def any_to_s(obj)
- obj.to_s + ":#{obj.class}"
+ "#{obj}:#{obj.class}"
rescue
- sprintf("#<%s:0x%lx>", obj.class, obj.__id__)
+ Kernel.instance_method(:to_s).bind_call(obj)
end
# Check that a method is callable via dRuby.
@@ -1537,14 +1595,27 @@ module DRb
raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class
raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)
- if obj.private_methods.include?(msg_id)
- desc = any_to_s(obj)
- raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
- elsif obj.protected_methods.include?(msg_id)
- desc = any_to_s(obj)
- raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
+ case obj
+ when Object
+ if obj.private_methods.include?(msg_id)
+ desc = any_to_s(obj)
+ raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
+ elsif obj.protected_methods.include?(msg_id)
+ desc = any_to_s(obj)
+ raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
+ else
+ true
+ end
else
- true
+ if Kernel.instance_method(:private_methods).bind(obj).call.include?(msg_id)
+ desc = any_to_s(obj)
+ raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
+ elsif Kernel.instance_method(:protected_methods).bind(obj).call.include?(msg_id)
+ desc = any_to_s(obj)
+ raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
+ else
+ true
+ end
end
end
public :check_insecure_method
@@ -1552,7 +1623,6 @@ module DRb
class InvokeMethod # :nodoc:
def initialize(drb_server, client)
@drb_server = drb_server
- @safe_level = drb_server.safe_level
@client = client
end
@@ -1561,34 +1631,22 @@ module DRb
@succ = false
setup_message
- if $SAFE < @safe_level
- info = Thread.current['DRb']
- if @block
- @result = Thread.new {
- Thread.current['DRb'] = info
- $SAFE = @safe_level
- perform_with_block
- }.value
- else
- @result = Thread.new {
- Thread.current['DRb'] = info
- $SAFE = @safe_level
- perform_without_block
- }.value
- end
+ if @block
+ @result = perform_with_block
else
- if @block
- @result = perform_with_block
- else
- @result = perform_without_block
- end
+ @result = perform_without_block
end
@succ = true
- if @msg_id == :to_ary && @result.class == Array
- @result = DRbArray.new(@result)
+ case @result
+ when Array
+ if @msg_id == :to_ary
+ @result = DRbArray.new(@result)
+ end
end
return @succ, @result
- rescue StandardError, ScriptError, Interrupt
+ rescue NoMemoryError, SystemExit, SystemStackError, SecurityError
+ raise
+ rescue Exception
@result = $!
return @succ, @result
end
@@ -1626,7 +1684,7 @@ module DRb
end
- require 'drb/invokemethod'
+ require_relative 'invokemethod'
class InvokeMethod
include InvokeMethod18Mixin
end
@@ -1666,13 +1724,16 @@ module DRb
invoke_method = InvokeMethod.new(self, client)
succ, result = invoke_method.perform
error_print(result) if !succ && verbose
- client.send_reply(succ, result)
+ unless DRbConnError === result && result.message == 'connection closed'
+ client.send_reply(succ, result)
+ end
rescue Exception => e
error_print(e) if verbose
ensure
client.close unless succ
if Thread.current['DRb']['stop_service']
- Thread.new { stop_service }
+ shutdown
+ break
end
break unless succ
end
@@ -1853,6 +1914,11 @@ module DRb
# Removes +server+ from the list of registered servers.
def remove_server(server)
@server.delete(server.uri)
+ mutex.synchronize do
+ if @primary_server == server
+ @primary_server = nil
+ end
+ end
end
module_function :remove_server
diff --git a/lib/drb/extserv.rb b/lib/drb/extserv.rb
index 1cb1be4709..a93d5d1576 100644
--- a/lib/drb/extserv.rb
+++ b/lib/drb/extserv.rb
@@ -4,7 +4,7 @@
Copyright (c) 2000,2002 Masatoshi SEKI
=end
-require 'drb/drb'
+require_relative 'drb'
require 'monitor'
module DRb
diff --git a/lib/drb/extservm.rb b/lib/drb/extservm.rb
index 5d779f51f5..040e4e3e08 100644
--- a/lib/drb/extservm.rb
+++ b/lib/drb/extservm.rb
@@ -4,7 +4,7 @@
Copyright (c) 2000 Masatoshi SEKI
=end
-require 'drb/drb'
+require_relative 'drb'
require 'monitor'
module DRb
@@ -37,7 +37,7 @@ module DRb
synchronize do
while true
server = @servers[name]
- return server if server&.alive?
+ return server if server && server.alive? # server may be `false'
invoke_service(name)
@cond.wait
end
@@ -61,8 +61,7 @@ module DRb
private
def invoke_thread
Thread.new do
- while true
- name = @queue.pop
+ while name = @queue.pop
invoke_service_command(name, @@command[name])
end
end
diff --git a/lib/drb/gw.rb b/lib/drb/gw.rb
index d000507644..65a525476e 100644
--- a/lib/drb/gw.rb
+++ b/lib/drb/gw.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: false
-require 'drb/drb'
+require_relative 'drb'
require 'monitor'
module DRb
diff --git a/lib/drb/observer.rb b/lib/drb/observer.rb
index 3ee15331a1..0fb7301edf 100644
--- a/lib/drb/observer.rb
+++ b/lib/drb/observer.rb
@@ -13,7 +13,7 @@ module DRb
if defined? @observer_peers
@observer_peers.each do |observer, method|
begin
- observer.send(method, *arg)
+ observer.__send__(method, *arg)
rescue
delete_observer(observer)
end
diff --git a/lib/drb/ssl.rb b/lib/drb/ssl.rb
index 8d2724e736..54ab1ef395 100644
--- a/lib/drb/ssl.rb
+++ b/lib/drb/ssl.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require 'socket'
require 'openssl'
-require 'drb/drb'
+require_relative 'drb'
require 'singleton'
module DRb
@@ -162,7 +162,7 @@ module DRb
return
end
- rsa = OpenSSL::PKey::RSA.new(1024){|p, n|
+ rsa = OpenSSL::PKey::RSA.new(2048){|p, n|
next unless self[:verbose]
case p
when 0; $stderr.putc "." # BN_generate_prime
@@ -196,7 +196,7 @@ module DRb
if comment = self[:SSLCertComment]
cert.add_extension(ef.create_extension("nsComment", comment))
end
- cert.sign(rsa, OpenSSL::Digest::SHA1.new)
+ cert.sign(rsa, "SHA256")
@cert = cert
@pkey = rsa
@@ -226,13 +226,13 @@ module DRb
#
# Raises DRbBadScheme or DRbBadURI if +uri+ is not matching or malformed
def self.parse_uri(uri) # :nodoc:
- if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
+ if /\Adrbssl:\/\/(.*?):(\d+)(\?(.*))?\z/ =~ uri
host = $1
port = $2.to_i
option = $4
[host, port, option]
else
- raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
+ raise(DRbBadScheme, uri) unless uri.start_with?('drbssl:')
raise(DRbBadURI, 'can\'t parse uri:' + uri)
end
end
@@ -248,8 +248,6 @@ module DRb
# configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
def self.open(uri, config)
host, port, = parse_uri(uri)
- host.untaint
- port.untaint
soc = TCPSocket.open(host, port)
ssl_conf = SSLConfig::new(config)
ssl_conf.setup_ssl_context
@@ -336,7 +334,7 @@ module DRb
end
self.class.new(uri, ssl, @config, true)
rescue OpenSSL::SSL::SSLError
- warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
+ warn("#{$!.message} (#{$!.class})", uplevel: 0) if @config[:verbose]
retry
end
end
diff --git a/lib/drb/timeridconv.rb b/lib/drb/timeridconv.rb
index 9ac7e1e69c..3ead98a7f2 100644
--- a/lib/drb/timeridconv.rb
+++ b/lib/drb/timeridconv.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: false
-require 'drb/drb'
+require_relative 'drb'
require 'monitor'
module DRb
diff --git a/lib/drb/unix.rb b/lib/drb/unix.rb
index adacf6df5b..1629ad3bcd 100644
--- a/lib/drb/unix.rb
+++ b/lib/drb/unix.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: false
require 'socket'
-require 'drb/drb'
+require_relative 'drb'
require 'tmpdir'
raise(LoadError, "UNIXServer is required") unless defined?(UNIXServer)
@@ -15,19 +15,18 @@ module DRb
class DRbUNIXSocket < DRbTCPSocket
# :stopdoc:
def self.parse_uri(uri)
- if /^drbunix:(.*?)(\?(.*))?$/ =~ uri
+ if /\Adrbunix:(.*?)(\?(.*))?\z/ =~ uri
filename = $1
option = $3
[filename, option]
else
- raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/
+ raise(DRbBadScheme, uri) unless uri.start_with?('drbunix:')
raise(DRbBadURI, 'can\'t parse uri:' + uri)
end
end
def self.open(uri, config)
filename, = parse_uri(uri)
- filename.untaint
soc = UNIXSocket.open(filename)
self.new(uri, soc, config)
end
@@ -95,6 +94,7 @@ module DRb
public
def close
return unless @socket
+ shutdown # DRbProtocol#shutdown
path = @socket.path if @server_mode
@socket.close
File.unlink(path) if @server_mode
diff --git a/lib/drb/version.rb b/lib/drb/version.rb
new file mode 100644
index 0000000000..e1f33cc65e
--- /dev/null
+++ b/lib/drb/version.rb
@@ -0,0 +1,3 @@
+module DRb
+ VERSION = "2.0.5"
+end
diff --git a/lib/drb/weakidconv.rb b/lib/drb/weakidconv.rb
new file mode 100644
index 0000000000..ecf0bf515f
--- /dev/null
+++ b/lib/drb/weakidconv.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: false
+require_relative 'drb'
+require 'monitor'
+
+module DRb
+
+ # To use WeakIdConv:
+ #
+ # DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new})
+
+ class WeakIdConv < DRbIdConv
+ class WeakSet
+ include MonitorMixin
+ def initialize
+ super()
+ @immutable = {}
+ @map = ObjectSpace::WeakMap.new
+ end
+
+ def add(obj)
+ synchronize do
+ begin
+ @map[obj] = self
+ rescue ArgumentError
+ @immutable[obj.__id__] = obj
+ end
+ return obj.__id__
+ end
+ end
+
+ def fetch(ref)
+ synchronize do
+ @immutable.fetch(ref) {
+ @map.each { |key, _|
+ return key if key.__id__ == ref
+ }
+ raise RangeError.new("invalid reference")
+ }
+ end
+ end
+ end
+
+ def initialize()
+ super()
+ @weak_set = WeakSet.new
+ end
+
+ def to_obj(ref) # :nodoc:
+ return super if ref.nil?
+ @weak_set.fetch(ref)
+ end
+
+ def to_id(obj) # :nodoc:
+ return @weak_set.add(obj)
+ end
+ end
+end
+
+# DRb.install_id_conv(WeakIdConv.new)
diff --git a/lib/e2mmap.rb b/lib/e2mmap.rb
deleted file mode 100644
index 1c1d7148ff..0000000000
--- a/lib/e2mmap.rb
+++ /dev/null
@@ -1,177 +0,0 @@
-# frozen_string_literal: true
-#
-#--
-# e2mmap.rb - for Ruby 1.1
-# $Release Version: 2.0$
-# $Revision: 1.10 $
-# by Keiju ISHITSUKA
-#
-#++
-#
-# Helper module for easily defining exceptions with predefined messages.
-#
-# == Usage
-#
-# 1.
-# class Foo
-# extend Exception2MessageMapper
-# def_e2message ExistingExceptionClass, "message..."
-# def_exception :NewExceptionClass, "message..."[, superclass]
-# ...
-# end
-#
-# 2.
-# module Error
-# extend Exception2MessageMapper
-# def_e2message ExistingExceptionClass, "message..."
-# def_exception :NewExceptionClass, "message..."[, superclass]
-# ...
-# end
-# class Foo
-# include Error
-# ...
-# end
-#
-# foo = Foo.new
-# foo.Fail ....
-#
-# 3.
-# module Error
-# extend Exception2MessageMapper
-# def_e2message ExistingExceptionClass, "message..."
-# def_exception :NewExceptionClass, "message..."[, superclass]
-# ...
-# end
-# class Foo
-# extend Exception2MessageMapper
-# include Error
-# ...
-# end
-#
-# Foo.Fail NewExceptionClass, arg...
-# Foo.Fail ExistingExceptionClass, arg...
-#
-#
-module Exception2MessageMapper
-
- E2MM = Exception2MessageMapper # :nodoc:
-
- def E2MM.extend_object(cl)
- super
- cl.bind(self) unless cl < E2MM
- end
-
- def bind(cl)
- self.module_eval "#{<<-"begin;"}\n#{<<-"end;"}", __FILE__, __LINE__+1
- begin;
- def Raise(err = nil, *rest)
- Exception2MessageMapper.Raise(self.class, err, *rest)
- end
- alias Fail Raise
-
- class << self
- undef included
- end
- def self.included(mod)
- mod.extend Exception2MessageMapper
- end
- end;
- end
-
- # Fail(err, *rest)
- # err: exception
- # rest: message arguments
- #
- def Raise(err = nil, *rest)
- E2MM.Raise(self, err, *rest)
- end
- alias Fail Raise
- alias fail Raise
-
- # def_e2message(c, m)
- # c: exception
- # m: message_form
- # define exception c with message m.
- #
- def def_e2message(c, m)
- E2MM.def_e2message(self, c, m)
- end
-
- # def_exception(n, m, s)
- # n: exception_name
- # m: message_form
- # s: superclass(default: StandardError)
- # define exception named ``c'' with message m.
- #
- def def_exception(n, m, s = StandardError)
- E2MM.def_exception(self, n, m, s)
- end
-
- #
- # Private definitions.
- #
- # {[class, exp] => message, ...}
- @MessageMap = {}
-
- # E2MM.def_e2message(k, e, m)
- # k: class to define exception under.
- # e: exception
- # m: message_form
- # define exception c with message m.
- #
- def E2MM.def_e2message(k, c, m)
- E2MM.instance_eval{@MessageMap[[k, c]] = m}
- c
- end
-
- # E2MM.def_exception(k, n, m, s)
- # k: class to define exception under.
- # n: exception_name
- # m: message_form
- # s: superclass(default: StandardError)
- # define exception named ``c'' with message m.
- #
- def E2MM.def_exception(k, n, m, s = StandardError)
- e = Class.new(s)
- E2MM.instance_eval{@MessageMap[[k, e]] = m}
- k.module_eval {remove_const(n)} if k.const_defined?(n, false)
- k.const_set(n, e)
- end
-
- # Fail(klass, err, *rest)
- # klass: class to define exception under.
- # err: exception
- # rest: message arguments
- #
- def E2MM.Raise(klass = E2MM, err = nil, *rest)
- if form = e2mm_message(klass, err)
- b = $@.nil? ? caller(1) : $@
- b.shift if b[0] =~ /^#{Regexp.quote(__FILE__)}:/
- raise err, sprintf(form, *rest), b
- else
- E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect
- end
- end
- class << E2MM
- alias Fail Raise
- end
-
- def E2MM.e2mm_message(klass, exp)
- for c in klass.ancestors
- if mes = @MessageMap[[c,exp]]
- m = klass.instance_eval('"' + mes + '"')
- return m
- end
- end
- nil
- end
- class << self
- alias message e2mm_message
- end
-
- E2MM.def_exception(E2MM,
- :ErrNotRegisteredException,
- "not registered exception(%s)")
-end
-
-
diff --git a/lib/erb.gemspec b/lib/erb.gemspec
new file mode 100644
index 0000000000..1cace278c1
--- /dev/null
+++ b/lib/erb.gemspec
@@ -0,0 +1,24 @@
+Gem::Specification.new do |spec|
+ spec.name = "erb"
+ spec.version = "2.2.0"
+ spec.authors = ["Masatoshi SEKI"]
+ spec.email = ["seki@ruby-lang.org"]
+
+ spec.summary = %q{An easy to use but powerful templating system for Ruby.}
+ spec.description = %q{An easy to use but powerful templating system for Ruby.}
+ spec.homepage = "https://github.com/ruby/erb"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "libexec"
+ spec.executables = ["erb"]
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "cgi"
+end
diff --git a/lib/erb.rb b/lib/erb.rb
index 47bb5022cc..d2ea64ab60 100644
--- a/lib/erb.rb
+++ b/lib/erb.rb
@@ -1,5 +1,5 @@
# -*- coding: us-ascii -*-
-# frozen_string_literal: false
+# frozen_string_literal: true
# = ERB -- Ruby Templating
#
# Author:: Masatoshi SEKI
@@ -57,7 +57,6 @@ require "cgi/util"
#
# There are several settings you can change when you use ERB:
# * the nature of the tags that are recognized;
-# * the value of <tt>$SAFE</tt> under which the template is run;
# * the binding used to resolve local variables in the template.
#
# See the ERB.new and ERB#result methods for more detail.
@@ -115,7 +114,7 @@ require "cgi/util"
# James Edward Gray II
# }.gsub(/^ /, '')
#
-# message = ERB.new(template, 0, "%<>")
+# message = ERB.new(template, trim_mode: "%<>")
#
# # Set up template data.
# to = "Community Spokesman <spokesman@ruby_community.org>"
@@ -248,22 +247,20 @@ require "cgi/util"
#
# == Notes
#
-# There are a variety of templating solutions available in various Ruby projects:
-# * ERB's big brother, eRuby, works the same but is written in C for speed;
-# * Amrita (smart at producing HTML/XML);
-# * cs/Template (written in C for speed);
-# * RDoc, distributed with Ruby, uses its own template engine, which can be reused elsewhere;
-# * and others; search {RubyGems.org}[https://rubygems.org/] or
-# {The Ruby Toolbox}[https://www.ruby-toolbox.com/].
+# There are a variety of templating solutions available in various Ruby projects.
+# For example, RDoc, distributed with Ruby, uses its own template engine, which
+# can be reused elsewhere.
#
-# Rails, the web application framework, uses ERB to create views.
+# Other popular engines could be found in the corresponding
+# {Category}[https://www.ruby-toolbox.com/categories/template_engines] of
+# The Ruby Toolbox.
#
class ERB
Revision = '$Date:: $' # :nodoc: #'
# Returns revision information for the erb.rb module.
def self.version
- "erb.rb [2.1.0 #{ERB::Revision.split[1]}]"
+ "erb.rb [2.2.0 #{ERB::Revision.split[1]}]"
end
end
@@ -291,7 +288,7 @@ class ERB
# <i>Generates</i>:
#
# #coding:UTF-8
- # _erbout=+''; _erbout.<< -"Got "; _erbout.<<(( obj ).to_s); _erbout.<< -"!\n"; _erbout
+ # _erbout=+''; _erbout.<< "Got ".freeze; _erbout.<<(( obj ).to_s); _erbout.<< "!\n".freeze; _erbout
#
# By default the output is sent to the print method. For example:
#
@@ -302,7 +299,7 @@ class ERB
# <i>Generates</i>:
#
# #coding:UTF-8
- # print "Got "; print(( obj ).to_s); print "!\n"
+ # print "Got ".freeze; print(( obj ).to_s); print "!\n".freeze
#
# == Evaluation
#
@@ -515,10 +512,6 @@ class ERB
end
Scanner.register_scanner(SimpleScanner, nil, false)
- # Deprecated. Kept for backward compatibility.
- SimpleScanner2 = SimpleScanner # :nodoc:
- deprecate_constant :SimpleScanner2
-
class ExplicitScanner < Scanner # :nodoc:
def scan
stag_reg = /(.*?)(^[ \t]*<%-|<%-|#{stags.join('|')}|\z)/m
@@ -547,7 +540,7 @@ class ERB
def initialize(compiler, enc=nil, frozen=nil)
@compiler = compiler
@line = []
- @script = ''
+ @script = +''
@script << "#coding:#{enc}\n" if enc
@script << "#frozen-string-literal:#{frozen}\n" unless frozen.nil?
@compiler.pre_cmd.each do |x|
@@ -576,17 +569,8 @@ class ERB
end
end
- def content_dump(s) # :nodoc:
- n = s.count("\n")
- if n > 0
- s.dump << "\n" * n
- else
- s.dump
- end
- end
-
def add_put_cmd(out, content)
- out.push("#{@put_cmd}(-#{content_dump(content)})")
+ out.push("#{@put_cmd} #{content.dump}.freeze#{"\n" * content.count("\n")}")
end
def add_insert_cmd(out, content)
@@ -602,7 +586,7 @@ class ERB
magic_comment = detect_magic_comment(s, enc)
out = Buffer.new(self, *magic_comment)
- self.content = ''
+ self.content = +''
scanner = make_scanner(s)
scanner.scan do |token|
next if token.nil?
@@ -622,7 +606,7 @@ class ERB
case stag
when PercentLine
add_put_cmd(out, content) if content.size > 0
- self.content = ''
+ self.content = +''
out.push(stag.to_s)
out.cr
when :cr
@@ -630,11 +614,11 @@ class ERB
when '<%', '<%=', '<%#'
scanner.stag = stag
add_put_cmd(out, content) if content.size > 0
- self.content = ''
+ self.content = +''
when "\n"
content << "\n"
add_put_cmd(out, content)
- self.content = ''
+ self.content = +''
when '<%%'
content << '<%'
else
@@ -647,7 +631,7 @@ class ERB
when '%>'
compile_content(scanner.stag, out)
scanner.stag = nil
- self.content = ''
+ self.content = +''
when '%%>'
content << '%>'
else
@@ -668,7 +652,7 @@ class ERB
when '<%='
add_insert_cmd(out, content)
when '<%#'
- # out.push("# #{content_dump(content)}")
+ # commented out
end
end
@@ -678,9 +662,13 @@ class ERB
return [false, '>']
when 2
return [false, '<>']
- when 0
+ when 0, nil
return [false, nil]
when String
+ unless mode.match?(/\A(%|-|>|<>){1,2}\z/)
+ warn_invalid_trim_mode(mode, uplevel: 5)
+ end
+
perc = mode.include?('%')
if mode.include?('-')
return [perc, '-']
@@ -692,6 +680,7 @@ class ERB
[perc, nil]
end
else
+ warn_invalid_trim_mode(mode, uplevel: 5)
return [false, nil]
end
end
@@ -743,6 +732,10 @@ class ERB
end
return enc, frozen
end
+
+ def warn_invalid_trim_mode(mode, uplevel:)
+ warn "Invalid ERB trim mode: #{mode.inspect} (trim_mode: nil, 0, 1, 2, or String composed of '%' and/or '-', '>', '<>')", uplevel: uplevel + 1
+ end
end
end
@@ -753,9 +746,7 @@ class ERB
# Constructs a new ERB object with the template specified in _str_.
#
# An ERB object works by building a chunk of Ruby code that will output
- # the completed template when run. If _safe_level_ is set to a non-nil value,
- # ERB code will be run in a separate thread with <b>$SAFE</b> set to the
- # provided level.
+ # the completed template when run.
#
# If _trim_mode_ is passed a String containing one or more of the following
# modifiers, ERB will adjust its code generation as listed:
@@ -790,11 +781,11 @@ class ERB
# def build
# b = binding
# # create and run templates, filling member data variables
- # ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "", "@product").result b
+ # ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), trim_mode: "", eoutvar: "@product").result b
# <%= PRODUCT[:name] %>
# <%= PRODUCT[:desc] %>
# END_PRODUCT
- # ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b
+ # ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), trim_mode: "", eoutvar: "@price").result b
# <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
# <%= PRODUCT[:desc] %>
# END_PRICE
@@ -815,14 +806,31 @@ class ERB
# Chicken Fried Steak -- 9.95
# A well messages pattie, breaded and fried.
#
- def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
- @safe_level = safe_level
+ def initialize(str, safe_level=NOT_GIVEN, legacy_trim_mode=NOT_GIVEN, legacy_eoutvar=NOT_GIVEN, trim_mode: nil, eoutvar: '_erbout')
+ # Complex initializer for $SAFE deprecation at [Feature #14256]. Use keyword arguments to pass trim_mode or eoutvar.
+ if safe_level != NOT_GIVEN
+ warn 'Passing safe_level with the 2nd argument of ERB.new is deprecated. Do not use it, and specify other arguments as keyword arguments.', uplevel: 1 if $VERBOSE || !ZERO_SAFE_LEVELS.include?(safe_level)
+ end
+ if legacy_trim_mode != NOT_GIVEN
+ warn 'Passing trim_mode with the 3rd argument of ERB.new is deprecated. Use keyword argument like ERB.new(str, trim_mode: ...) instead.', uplevel: 1 if $VERBOSE
+ trim_mode = legacy_trim_mode
+ end
+ if legacy_eoutvar != NOT_GIVEN
+ warn 'Passing eoutvar with the 4th argument of ERB.new is deprecated. Use keyword argument like ERB.new(str, eoutvar: ...) instead.', uplevel: 1 if $VERBOSE
+ eoutvar = legacy_eoutvar
+ end
+
compiler = make_compiler(trim_mode)
set_eoutvar(compiler, eoutvar)
@src, @encoding, @frozen_string = *compiler.compile(str)
@filename = nil
@lineno = 0
+ @_init = self.class.singleton_class
end
+ NOT_GIVEN = Object.new
+ private_constant :NOT_GIVEN
+ ZERO_SAFE_LEVELS = [0, nil]
+ private_constant :ZERO_SAFE_LEVELS
##
# Creates a new compiler for ERB. See ERB::Compiler.new for details
@@ -845,6 +853,21 @@ class ERB
# is run
attr_accessor :lineno
+ #
+ # Sets optional filename and line number that will be used in ERB code
+ # evaluation and error reporting. See also #filename= and #lineno=
+ #
+ # erb = ERB.new('<%= some_x %>')
+ # erb.render
+ # # undefined local variable or method `some_x'
+ # # from (erb):1
+ #
+ # erb.location = ['file.erb', 3]
+ # # All subsequent error reporting would use new location
+ # erb.render
+ # # undefined local variable or method `some_x'
+ # # from file.erb:4
+ #
def location=((filename, lineno))
@filename = filename
@lineno = lineno if lineno
@@ -876,20 +899,16 @@ class ERB
# code evaluation.
#
def result(b=new_toplevel)
- if @safe_level
- proc {
- $SAFE = @safe_level
- eval(@src, b, (@filename || '(erb)'), @lineno)
- }.call
- else
- eval(@src, b, (@filename || '(erb)'), @lineno)
+ unless @_init.equal?(self.class.singleton_class)
+ raise ArgumentError, "not initialized"
end
+ eval(@src, b, (@filename || '(erb)'), @lineno)
end
# Render a template on a new toplevel binding with local variables specified
# by a Hash object.
def result_with_hash(hash)
- b = new_toplevel
+ b = new_toplevel(hash.keys)
hash.each_pair do |key, value|
b.local_variable_set(key, value)
end
@@ -900,8 +919,15 @@ class ERB
# Returns a new binding each time *near* TOPLEVEL_BINDING for runs that do
# not specify a binding.
- def new_toplevel
- TOPLEVEL_BINDING.dup
+ def new_toplevel(vars = nil)
+ b = TOPLEVEL_BINDING
+ if vars
+ vars = vars.select {|v| b.local_variable_defined?(v)}
+ unless vars.empty?
+ return b.eval("tap {|;#{vars.join(',')}| break binding}")
+ end
+ end
+ b.dup
end
private :new_toplevel
diff --git a/lib/fileutils.gemspec b/lib/fileutils.gemspec
index b50bbf3014..53c32e7e3e 100644
--- a/lib/fileutils.gemspec
+++ b/lib/fileutils.gemspec
@@ -1,19 +1,31 @@
# frozen_string_literal: true
+
+source_version = ["", "lib/"].find do |dir|
+ begin
+ break File.open(File.join(__dir__, "#{dir}fileutils.rb")) {|f|
+ f.gets("\n VERSION = ")
+ f.gets[/\s*"(.+)"/, 1]
+ }
+ rescue Errno::ENOENT
+ end
+end
+
Gem::Specification.new do |s|
s.name = "fileutils"
- s.version = '0.7.2'
- s.date = '2017-02-06'
+ s.version = source_version
s.summary = "Several file utility methods for copying, moving, removing, etc."
s.description = "Several file utility methods for copying, moving, removing, etc."
s.require_path = %w{lib}
- s.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "fileutils.gemspec", "lib/fileutils.rb"]
- s.required_ruby_version = ">= 2.5.0dev"
+ s.files = ["LICENSE.txt", "README.md", "Rakefile", "fileutils.gemspec", "lib/fileutils.rb"]
+ s.required_ruby_version = ">= 2.3.0"
s.authors = ["Minero Aoki"]
s.email = [nil]
s.homepage = "https://github.com/ruby/fileutils"
- s.license = "BSD-2-Clause"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
- s.add_development_dependency 'rake'
+ s.metadata = {
+ "source_code_uri" => "https://github.com/ruby/fileutils"
+ }
end
diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 37945b4096..a2ad0c003e 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -1,4 +1,11 @@
# frozen_string_literal: true
+
+begin
+ require 'rbconfig'
+rescue LoadError
+ # for make mjit-headers
+end
+
#
# = fileutils.rb
#
@@ -15,48 +22,58 @@
#
# require 'fileutils'
#
-# FileUtils.cd(dir, options)
-# FileUtils.cd(dir, options) {|dir| block }
+# FileUtils.cd(dir, **options)
+# FileUtils.cd(dir, **options) {|dir| block }
# FileUtils.pwd()
-# FileUtils.mkdir(dir, options)
-# FileUtils.mkdir(list, options)
-# FileUtils.mkdir_p(dir, options)
-# FileUtils.mkdir_p(list, options)
-# FileUtils.rmdir(dir, options)
-# FileUtils.rmdir(list, options)
-# FileUtils.ln(target, link, options)
-# FileUtils.ln(targets, dir, options)
-# FileUtils.ln_s(target, link, options)
-# FileUtils.ln_s(targets, dir, options)
-# FileUtils.ln_sf(target, link, options)
-# FileUtils.cp(src, dest, options)
-# FileUtils.cp(list, dir, options)
-# FileUtils.cp_r(src, dest, options)
-# FileUtils.cp_r(list, dir, options)
-# FileUtils.mv(src, dest, options)
-# FileUtils.mv(list, dir, options)
-# FileUtils.rm(list, options)
-# FileUtils.rm_r(list, options)
-# FileUtils.rm_rf(list, options)
-# FileUtils.install(src, dest, options)
-# FileUtils.chmod(mode, list, options)
-# FileUtils.chmod_R(mode, list, options)
-# FileUtils.chown(user, group, list, options)
-# FileUtils.chown_R(user, group, list, options)
-# FileUtils.touch(list, options)
+# FileUtils.mkdir(dir, **options)
+# FileUtils.mkdir(list, **options)
+# FileUtils.mkdir_p(dir, **options)
+# FileUtils.mkdir_p(list, **options)
+# FileUtils.rmdir(dir, **options)
+# FileUtils.rmdir(list, **options)
+# FileUtils.ln(target, link, **options)
+# FileUtils.ln(targets, dir, **options)
+# FileUtils.ln_s(target, link, **options)
+# FileUtils.ln_s(targets, dir, **options)
+# FileUtils.ln_sf(target, link, **options)
+# FileUtils.cp(src, dest, **options)
+# FileUtils.cp(list, dir, **options)
+# FileUtils.cp_r(src, dest, **options)
+# FileUtils.cp_r(list, dir, **options)
+# FileUtils.mv(src, dest, **options)
+# FileUtils.mv(list, dir, **options)
+# FileUtils.rm(list, **options)
+# FileUtils.rm_r(list, **options)
+# FileUtils.rm_rf(list, **options)
+# FileUtils.install(src, dest, **options)
+# FileUtils.chmod(mode, list, **options)
+# FileUtils.chmod_R(mode, list, **options)
+# FileUtils.chown(user, group, list, **options)
+# FileUtils.chown_R(user, group, list, **options)
+# FileUtils.touch(list, **options)
+#
+# Possible <tt>options</tt> are:
#
-# The <tt>options</tt> parameter is a hash of options, taken from the list
-# <tt>:force</tt>, <tt>:noop</tt>, <tt>:preserve</tt>, and <tt>:verbose</tt>.
-# <tt>:noop</tt> means that no changes are made. The other three are obvious.
-# Each method documents the options that it honours.
+# <tt>:force</tt> :: forced operation (rewrite files if exist, remove
+# directories if not empty, etc.);
+# <tt>:verbose</tt> :: print command to be run, in bash syntax, before
+# performing it;
+# <tt>:preserve</tt> :: preserve object's group, user and modification
+# time on copying;
+# <tt>:noop</tt> :: no changes are made (usable in combination with
+# <tt>:verbose</tt> which will print the command to run)
+#
+# Each method documents the options that it honours. See also ::commands,
+# ::options and ::options_of methods to introspect which command have which
+# options.
#
# All methods that have the concept of a "source" file or directory can take
# either one file or a list of files in that argument. See the method
# documentation for examples.
#
-# There are some `low level' methods, which do not accept any option:
+# There are some `low level' methods, which do not accept keyword arguments:
#
-# FileUtils.copy_entry(src, dest, preserve = false, dereference = false)
+# FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
# FileUtils.copy_file(src, dest, preserve = false, dereference = true)
# FileUtils.copy_stream(srcstream, deststream)
# FileUtils.remove_entry(path, force = false)
@@ -84,8 +101,8 @@
# files/directories. This equates to passing the <tt>:noop</tt> and
# <tt>:verbose</tt> flags to methods in FileUtils.
#
-
module FileUtils
+ VERSION = "1.5.0"
def self.private_module_function(name) #:nodoc:
module_function name
@@ -106,19 +123,22 @@ module FileUtils
#
# Changes the current directory to the directory +dir+.
#
- # If this method is called with block, resumes to the old
- # working directory after the block execution finished.
+ # If this method is called with block, resumes to the previous
+ # working directory after the block execution has finished.
+ #
+ # FileUtils.cd('/') # change directory
#
- # FileUtils.cd('/', :verbose => true) # chdir and report it
+ # FileUtils.cd('/', verbose: true) # change directory and report it
#
- # FileUtils.cd('/') do # chdir
+ # FileUtils.cd('/') do # change directory
# # ... # do something
# end # return to original directory
#
def cd(dir, verbose: nil, &block) # :yield: dir
fu_output_message "cd #{dir}" if verbose
- Dir.chdir(dir, &block)
+ result = Dir.chdir(dir, &block)
fu_output_message 'cd -' if verbose and block
+ result
end
module_function :cd
@@ -153,9 +173,9 @@ module FileUtils
# Creates one or more directories.
#
# FileUtils.mkdir 'test'
- # FileUtils.mkdir %w( tmp data )
- # FileUtils.mkdir 'notexist', :noop => true # Does not really create.
- # FileUtils.mkdir 'tmp', :mode => 0700
+ # FileUtils.mkdir %w(tmp data)
+ # FileUtils.mkdir 'notexist', noop: true # Does not really create.
+ # FileUtils.mkdir 'tmp', mode: 0700
#
def mkdir(list, mode: nil, noop: nil, verbose: nil)
list = fu_list(list)
@@ -174,7 +194,7 @@ module FileUtils
#
# FileUtils.mkdir_p '/usr/local/lib/ruby'
#
- # causes to make following directories, if it does not exist.
+ # causes to make following directories, if they do not exist.
#
# * /usr
# * /usr/local
@@ -188,7 +208,9 @@ module FileUtils
fu_output_message "mkdir -p #{mode ? ('-m %03o ' % mode) : ''}#{list.join ' '}" if verbose
return *list if noop
- list.map {|path| remove_trailing_slash(path)}.each do |path|
+ list.each do |item|
+ path = remove_trailing_slash(item)
+
# optimize for the most common case
begin
fu_mkdir path, mode
@@ -201,8 +223,9 @@ module FileUtils
until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/"
stack.push path
path = File.dirname(path)
+ break if File.directory?(path)
end
- stack.pop # root directory should exist
+ stack.pop if path == stack.last # root directory should exist
stack.reverse_each do |dir|
begin
fu_mkdir dir, mode
@@ -238,7 +261,7 @@ module FileUtils
# FileUtils.rmdir 'somedir'
# FileUtils.rmdir %w(somedir anydir otherdir)
# # Does not really remove directory; outputs message.
- # FileUtils.rmdir 'somedir', :verbose => true, :noop => true
+ # FileUtils.rmdir 'somedir', verbose: true, noop: true
#
def rmdir(list, parents: nil, noop: nil, verbose: nil)
list = fu_list(list)
@@ -267,7 +290,7 @@ module FileUtils
#
# In the first form, creates a hard link +link+ which points to +target+.
# If +link+ already exists, raises Errno::EEXIST.
- # But if the :force option is set, overwrites +link+.
+ # But if the +force+ option is set, overwrites +link+.
#
# FileUtils.ln 'gcc', 'cc', verbose: true
# FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
@@ -294,6 +317,39 @@ module FileUtils
module_function :link
#
+ # Hard link +src+ to +dest+. If +src+ is a directory, this method links
+ # all its contents recursively. If +dest+ is a directory, links
+ # +src+ to +dest/src+.
+ #
+ # +src+ can be a list of files.
+ #
+ # If +dereference_root+ is true, this method dereference tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
+ # FileUtils.rm_r site_ruby + '/mylib', force: true
+ # FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
+ #
+ # # Examples of linking several files to target directory.
+ # FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
+ # FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true
+ #
+ # # If you want to link all contents of a directory instead of the
+ # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
+ # # use the following code.
+ # FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
+ #
+ def cp_lr(src, dest, noop: nil, verbose: nil,
+ dereference_root: true, remove_destination: false)
+ fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
+ return if noop
+ fu_each_src_dest(src, dest) do |s, d|
+ link_entry s, d, dereference_root, remove_destination
+ end
+ end
+ module_function :cp_lr
+
+ #
# :call-seq:
# FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
# FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
@@ -301,7 +357,7 @@ module FileUtils
#
# In the first form, creates a symbolic link +link+ which points to +target+.
# If +link+ already exists, raises Errno::EEXIST.
- # But if the :force option is set, overwrites +link+.
+ # But if the <tt>force</tt> option is set, overwrites +link+.
#
# FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
# FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
@@ -340,6 +396,26 @@ module FileUtils
module_function :ln_sf
#
+ # Hard links a file system entry +src+ to +dest+.
+ # If +src+ is a directory, this method links its contents recursively.
+ #
+ # Both of +src+ and +dest+ must be a path name.
+ # +src+ must exist, +dest+ must not exist.
+ #
+ # If +dereference_root+ is true, this method dereferences the tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
+ def link_entry(src, dest, dereference_root = false, remove_destination = false)
+ Entry_.new(src, nil, dereference_root).traverse do |ent|
+ destent = Entry_.new(dest, ent.rel, false)
+ File.unlink destent.path if remove_destination && File.file?(destent.path)
+ ent.link destent.path
+ end
+ end
+ module_function :link_entry
+
+ #
# Copies a file content +src+ to +dest+. If +dest+ is a directory,
# copies +src+ to +dest/src+.
#
@@ -347,7 +423,7 @@ module FileUtils
#
# FileUtils.cp 'eval.c', 'eval.c.org'
# FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
- # FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true
+ # FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
# FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
#
def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
@@ -369,13 +445,17 @@ module FileUtils
#
# +src+ can be a list of files.
#
+ # If +dereference_root+ is true, this method dereference tree root.
+ #
+ # If +remove_destination+ is true, this method removes each destination file before copy.
+ #
# # Installing Ruby library "mylib" under the site_ruby
- # FileUtils.rm_r site_ruby + '/mylib', :force
+ # FileUtils.rm_r site_ruby + '/mylib', force: true
# FileUtils.cp_r 'lib/', site_ruby + '/mylib'
#
# # Examples of copying several files to target directory.
# FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
- # FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', :noop => true, :verbose => true
+ # FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true
#
# # If you want to copy all contents of a directory instead of the
# # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
@@ -410,9 +490,13 @@ module FileUtils
# If +remove_destination+ is true, this method removes each destination file before copy.
#
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
- Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
+ if dereference_root
+ src = File.realpath(src)
+ end
+
+ Entry_.new(src, nil, false).wrap_traverse(proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
- File.unlink destent.path if remove_destination && File.file?(destent.path)
+ File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
ent.copy destent.path
end, proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
@@ -447,10 +531,10 @@ module FileUtils
# disk partition, the file is copied then the original file is removed.
#
# FileUtils.mv 'badname.rb', 'goodname.rb'
- # FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true # no error
+ # FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
#
# FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
- # FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
+ # FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
#
def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
@@ -461,13 +545,12 @@ module FileUtils
if destent.exist?
if destent.directory?
raise Errno::EEXIST, d
- else
- destent.remove_file if rename_cannot_overwrite_file?
end
end
begin
File.rename s, d
- rescue Errno::EXDEV
+ rescue Errno::EXDEV,
+ Errno::EPERM # move from unencrypted to encrypted dir (ext4)
copy_entry s, d, true
if secure
remove_entry_secure s, force
@@ -485,18 +568,13 @@ module FileUtils
alias move mv
module_function :move
- def rename_cannot_overwrite_file? #:nodoc:
- /emx/ =~ RUBY_PLATFORM
- end
- private_module_function :rename_cannot_overwrite_file?
-
#
# Remove file(s) specified in +list+. This method cannot remove directories.
# All StandardErrors are ignored when the :force option is set.
#
# FileUtils.rm %w( junk.txt dust.txt )
# FileUtils.rm Dir.glob('*.so')
- # FileUtils.rm 'NotExistFile', :force => true # never raises exception
+ # FileUtils.rm 'NotExistFile', force: true # never raises exception
#
def rm(list, force: nil, noop: nil, verbose: nil)
list = fu_list(list)
@@ -515,7 +593,7 @@ module FileUtils
#
# Equivalent to
#
- # FileUtils.rm(list, :force => true)
+ # FileUtils.rm(list, force: true)
#
def rm_f(list, noop: nil, verbose: nil)
rm list, force: true, noop: noop, verbose: verbose
@@ -531,18 +609,18 @@ module FileUtils
# StandardError when :force option is set.
#
# FileUtils.rm_r Dir.glob('/tmp/*')
- # FileUtils.rm_r 'some_dir', :force => true
+ # FileUtils.rm_r 'some_dir', force: true
#
# WARNING: This method causes local vulnerability
# if one of parent directories or removing directory tree are world
# writable (including /tmp, whose permission is 1777), and the current
# process has strong privilege such as Unix super user (root), and the
# system has symbolic link. For secure removing, read the documentation
- # of #remove_entry_secure carefully, and set :secure option to true.
- # Default is :secure=>false.
+ # of remove_entry_secure carefully, and set :secure option to true.
+ # Default is <tt>secure: false</tt>.
#
- # NOTE: This method calls #remove_entry_secure if :secure option is set.
- # See also #remove_entry_secure.
+ # NOTE: This method calls remove_entry_secure if :secure option is set.
+ # See also remove_entry_secure.
#
def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
list = fu_list(list)
@@ -561,10 +639,10 @@ module FileUtils
#
# Equivalent to
#
- # FileUtils.rm_r(list, :force => true)
+ # FileUtils.rm_r(list, force: true)
#
# WARNING: This method causes local vulnerability.
- # Read the documentation of #rm_r first.
+ # Read the documentation of rm_r first.
#
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
@@ -578,7 +656,7 @@ module FileUtils
# This method removes a file system entry +path+. +path+ shall be a
# regular file, a directory, or something. If +path+ is a directory,
# remove it recursively. This method is required to avoid TOCTTOU
- # (time-of-check-to-time-of-use) local security vulnerability of #rm_r.
+ # (time-of-check-to-time-of-use) local security vulnerability of rm_r.
# #rm_r causes security hole when:
#
# * Parent directory is world writable (including /tmp).
@@ -601,8 +679,8 @@ module FileUtils
#
# For details of this security vulnerability, see Perl's case:
#
- # * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
- # * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
#
# For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
#
@@ -626,22 +704,38 @@ module FileUtils
unless parent_st.sticky?
raise ArgumentError, "parent directory is world writable, FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
end
+
# freeze tree root
euid = Process.euid
- File.open(fullpath + '/.') {|f|
- unless fu_stat_identical_entry?(st, f.stat)
- # symlink (TOC-to-TOU attack?)
- File.unlink fullpath
- return
- end
- f.chown euid, -1
- f.chmod 0700
- unless fu_stat_identical_entry?(st, File.lstat(fullpath))
- # TOC-to-TOU attack?
- File.unlink fullpath
- return
- end
- }
+ dot_file = fullpath + "/."
+ begin
+ File.open(dot_file) {|f|
+ unless fu_stat_identical_entry?(st, f.stat)
+ # symlink (TOC-to-TOU attack?)
+ File.unlink fullpath
+ return
+ end
+ f.chown euid, -1
+ f.chmod 0700
+ }
+ rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
+ File.lstat(dot_file).tap {|fstat|
+ unless fu_stat_identical_entry?(st, fstat)
+ # symlink (TOC-to-TOU attack?)
+ File.unlink fullpath
+ return
+ end
+ File.chown euid, -1, dot_file
+ File.chmod 0700, dot_file
+ }
+ end
+
+ unless fu_stat_identical_entry?(st, File.lstat(fullpath))
+ # TOC-to-TOU attack?
+ File.unlink fullpath
+ return
+ end
+
# ---- tree root is frozen ----
root = Entry_.new(path)
root.preorder_traverse do |ent|
@@ -681,7 +775,7 @@ module FileUtils
# +path+ might be a regular file, a directory, or something.
# If +path+ is a directory, remove it recursively.
#
- # See also #remove_entry_secure.
+ # See also remove_entry_secure.
#
def remove_entry(path, force = false)
Entry_.new(path).postorder_traverse do |ent|
@@ -742,8 +836,15 @@ module FileUtils
#
def compare_stream(a, b)
bsize = fu_stream_blksize(a, b)
- sa = String.new(capacity: bsize)
- sb = String.new(capacity: bsize)
+
+ if RUBY_VERSION > "2.4"
+ sa = String.new(capacity: bsize)
+ sb = String.new(capacity: bsize)
+ else
+ sa = String.new
+ sb = String.new
+ end
+
begin
a.read(bsize, sa)
b.read(bsize, sb)
@@ -758,8 +859,8 @@ module FileUtils
# mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+.
# This method removes destination before copy.
#
- # FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
- # FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
+ # FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
+ # FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
#
def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil,
noop: nil, verbose: nil)
@@ -819,11 +920,8 @@ module FileUtils
private_module_function :apply_mask
def symbolic_modes_to_i(mode_sym, path) #:nodoc:
- mode = if File::Stat === path
- path.mode
- else
- File.stat(path).mode
- end
+ path = File.stat(path) unless File::Stat === path
+ mode = path.mode
mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause|
target, *actions = clause.split(/([=+-])/)
raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty?
@@ -840,7 +938,7 @@ module FileUtils
when "x"
mask | 0111
when "X"
- if FileTest.directory? path
+ if path.directory?
mask | 0111
else
mask
@@ -889,12 +987,12 @@ module FileUtils
# Absolute mode is
# FileUtils.chmod 0755, 'somecommand'
# FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
- # FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true
+ # FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true
#
# Symbolic mode is
# FileUtils.chmod "u=wrx,go=rx", 'somecommand'
# FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
- # FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', :verbose => true
+ # FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true
#
# "a" :: is user, group, other mask.
# "u" :: is user's mask.
@@ -954,7 +1052,7 @@ module FileUtils
# the attribute.
#
# FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
- # FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
+ # FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true
#
def chown(user, group, list, noop: nil, verbose: nil)
list = fu_list(list)
@@ -978,7 +1076,7 @@ module FileUtils
# method does not change the attribute.
#
# FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
- # FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true
+ # FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true
#
def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
list = fu_list(list)
@@ -1001,11 +1099,6 @@ module FileUtils
end
module_function :chown_R
- begin
- require 'etc'
- rescue LoadError # rescue LoadError for miniruby
- end
-
def fu_get_uid(user) #:nodoc:
return nil unless user
case user
@@ -1014,6 +1107,7 @@ module FileUtils
when /\A\d+\z/
user.to_i
else
+ require 'etc'
Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
end
end
@@ -1027,6 +1121,7 @@ module FileUtils
when /\A\d+\z/
group.to_i
else
+ require 'etc'
Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
end
end
@@ -1067,8 +1162,11 @@ module FileUtils
module StreamUtils_
private
- def fu_windows?
- /mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
+ case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
+ when /mswin|mingw/
+ def fu_windows?; true end
+ else
+ def fu_windows?; false end
end
def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
@@ -1192,10 +1290,17 @@ module FileUtils
def entries
opts = {}
- opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
- Dir.entries(path(), opts)\
- .reject {|n| n == '.' or n == '..' }\
- .map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
+ opts[:encoding] = fu_windows? ? ::Encoding::UTF_8 : path.encoding
+
+ files = if Dir.respond_to?(:children)
+ Dir.children(path, **opts)
+ else
+ Dir.entries(path(), **opts)
+ .reject {|n| n == '.' or n == '..' }
+ end
+
+ untaint = RUBY_VERSION < '2.7'
+ files.map {|n| Entry_.new(prefix(), join(rel(), untaint ? n.untaint : n)) }
end
def stat
@@ -1240,6 +1345,7 @@ module FileUtils
else
File.chmod mode, path()
end
+ rescue Errno::EOPNOTSUPP
end
def chown(uid, gid)
@@ -1250,6 +1356,22 @@ module FileUtils
end
end
+ def link(dest)
+ case
+ when directory?
+ if !File.exist?(dest) and descendant_directory?(dest, path)
+ raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
+ end
+ begin
+ Dir.mkdir dest
+ rescue
+ raise unless File.directory?(dest)
+ end
+ else
+ File.link path(), dest
+ end
+ end
+
def copy(dest)
lstat
case
@@ -1266,18 +1388,21 @@ module FileUtils
end
when symlink?
File.symlink File.readlink(path()), dest
- when chardev?
- raise "cannot handle device file" unless File.respond_to?(:mknod)
- mknod dest, ?c, 0666, lstat().rdev
- when blockdev?
- raise "cannot handle device file" unless File.respond_to?(:mknod)
- mknod dest, ?b, 0666, lstat().rdev
+ when chardev?, blockdev?
+ raise "cannot handle device file"
when socket?
- raise "cannot handle socket" unless File.respond_to?(:mknod)
- mknod dest, nil, lstat().mode, 0
+ begin
+ require 'socket'
+ rescue LoadError
+ raise "cannot handle socket"
+ else
+ raise "cannot handle socket" unless defined?(UNIXServer)
+ end
+ UNIXServer.new(dest).close
+ File.chmod lstat().mode, dest
when pipe?
raise "cannot handle FIFO" unless File.respond_to?(:mkfifo)
- mkfifo dest, 0666
+ File.mkfifo dest, lstat().mode
when door?
raise "cannot handle door: #{path()}"
else
@@ -1315,7 +1440,7 @@ module FileUtils
if st.symlink?
begin
File.lchmod mode, path
- rescue NotImplementedError
+ rescue NotImplementedError, Errno::EOPNOTSUPP
end
else
File.chmod mode, path
@@ -1396,14 +1521,14 @@ module FileUtils
private
- $fileutils_rb_have_lchmod = nil
+ @@fileutils_rb_have_lchmod = nil
def have_lchmod?
# This is not MT-safe, but it does not matter.
- if $fileutils_rb_have_lchmod == nil
- $fileutils_rb_have_lchmod = check_have_lchmod?
+ if @@fileutils_rb_have_lchmod == nil
+ @@fileutils_rb_have_lchmod = check_have_lchmod?
end
- $fileutils_rb_have_lchmod
+ @@fileutils_rb_have_lchmod
end
def check_have_lchmod?
@@ -1414,14 +1539,14 @@ module FileUtils
return false
end
- $fileutils_rb_have_lchown = nil
+ @@fileutils_rb_have_lchown = nil
def have_lchown?
# This is not MT-safe, but it does not matter.
- if $fileutils_rb_have_lchown == nil
- $fileutils_rb_have_lchown = check_have_lchown?
+ if @@fileutils_rb_have_lchown == nil
+ @@fileutils_rb_have_lchown = check_have_lchown?
end
- $fileutils_rb_have_lchown
+ @@fileutils_rb_have_lchown
end
def check_have_lchown?
@@ -1435,7 +1560,15 @@ module FileUtils
def join(dir, base)
return File.path(dir) if not base or base == '.'
return File.path(base) if not dir or dir == '.'
- File.join(dir, base)
+ begin
+ File.join(dir, base)
+ rescue EncodingError
+ if fu_windows?
+ File.join(dir.encode(::Encoding::UTF_8), base.encode(::Encoding::UTF_8))
+ else
+ raise
+ end
+ end
end
if File::ALT_SEPARATOR
@@ -1443,10 +1576,13 @@ module FileUtils
else
DIRECTORY_TERM = "(?=/|\\z)"
end
- SYSCASE = File::FNM_SYSCASE.nonzero? ? "-i" : ""
def descendant_directory?(descendant, ascendant)
- /\A(?#{SYSCASE}:#{Regexp.quote(ascendant)})#{DIRECTORY_TERM}/ =~ File.dirname(descendant)
+ if File::FNM_SYSCASE.nonzero?
+ File.expand_path(File.dirname(descendant)).casecmp(File.expand_path(ascendant)) == 0
+ else
+ File.expand_path(File.dirname(descendant)) == File.expand_path(ascendant)
+ end
end
end # class Entry_
@@ -1485,13 +1621,13 @@ module FileUtils
end
private_module_function :fu_same?
- @fileutils_output = $stderr
- @fileutils_label = ''
-
def fu_output_message(msg) #:nodoc:
- @fileutils_output ||= $stderr
- @fileutils_label ||= ''
- @fileutils_output.puts @fileutils_label + msg
+ output = @fileutils_output if defined?(@fileutils_output)
+ output ||= $stdout
+ if defined?(@fileutils_label)
+ msg = @fileutils_label + msg
+ end
+ output.puts msg
end
private_module_function :fu_output_message
@@ -1502,8 +1638,11 @@ module FileUtils
tbl
}
+ public
+
#
- # Returns an Array of method names which have any options.
+ # Returns an Array of names of high-level methods that accept any keyword
+ # arguments.
#
# p FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...]
#
@@ -1542,7 +1681,7 @@ module FileUtils
end
#
- # Returns an Array of method names which have the option +opt+.
+ # Returns an Array of methods names which have the option +opt+.
#
# p FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
#
@@ -1550,14 +1689,16 @@ module FileUtils
OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
end
- LOW_METHODS = singleton_methods(false) - collect_method(:noop).map(&:intern)
- module LowMethods
+ private
+
+ LOW_METHODS = singleton_methods(false) - collect_method(:noop).map(&:intern) # :nodoc:
+ module LowMethods # :nodoc: internal use only
private
def _do_nothing(*)end
::FileUtils::LOW_METHODS.map {|name| alias_method name, :_do_nothing}
end
- METHODS = singleton_methods() - [:private_module_function,
+ METHODS = singleton_methods() - [:private_module_function, # :nodoc:
:commands, :options, :have_option?, :options_of, :collect_method]
#
@@ -1567,8 +1708,6 @@ module FileUtils
#
module Verbose
include FileUtils
- @fileutils_output = $stderr
- @fileutils_label = ''
names = ::FileUtils.collect_method(:verbose)
names.each do |name|
module_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@ -1592,8 +1731,6 @@ module FileUtils
module NoWrite
include FileUtils
include LowMethods
- @fileutils_output = $stderr
- @fileutils_label = ''
names = ::FileUtils.collect_method(:noop)
names.each do |name|
module_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@ -1618,8 +1755,6 @@ module FileUtils
module DryRun
include FileUtils
include LowMethods
- @fileutils_output = $stderr
- @fileutils_label = ''
names = ::FileUtils.collect_method(:noop)
names.each do |name|
module_eval(<<-EOS, __FILE__, __LINE__ + 1)
diff --git a/lib/find.gemspec b/lib/find.gemspec
new file mode 100644
index 0000000000..fff0f706cd
--- /dev/null
+++ b/lib/find.gemspec
@@ -0,0 +1,24 @@
+Gem::Specification.new do |spec|
+ spec.name = "find"
+ spec.version = "0.1.0"
+ spec.authors = ['Kazuki Tsujimoto']
+ spec.email = ['kazuki@callcc.net']
+
+ spec.summary = %q{This module supports top-down traversal of a set of file paths.}
+ spec.description = %q{This module supports top-down traversal of a set of file paths.}
+ spec.homepage = "https://github.com/ruby/find"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/find.rb b/lib/find.rb
index f97cc1b836..3f54cf6b93 100644
--- a/lib/find.rb
+++ b/lib/find.rb
@@ -15,7 +15,7 @@
#
# Find.find(ENV["HOME"]) do |path|
# if FileTest.directory?(path)
-# if File.basename(path)[0] == ?.
+# if File.basename(path).start_with?('.')
# Find.prune # Don't look any further into this directory.
# else
# next
@@ -46,7 +46,7 @@ module Find
ps = [path]
while file = ps.shift
catch(:prune) do
- yield file.dup.taint
+ yield file.dup
begin
s = File.lstat(file)
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
@@ -63,7 +63,7 @@ module Find
fs.sort!
fs.reverse_each {|f|
f = File.join(file, f)
- ps.unshift f.untaint
+ ps.unshift f
}
end
end
diff --git a/lib/forwardable.rb b/lib/forwardable.rb
index 3662f56011..fb24b8c3e6 100644
--- a/lib/forwardable.rb
+++ b/lib/forwardable.rb
@@ -57,10 +57,9 @@
#
# == Another example
#
-# We want to rely on what has come before obviously, but with delegation we can
-# take just the methods we need and even rename them as appropriate. In many
-# cases this is preferable to inheritance, which gives us the entire old
-# interface, even if much of it isn't needed.
+# You could use Forwardable as an alternative to inheritance, when you don't want
+# to inherit all methods from the superclass. For instance, here is how you might
+# add a range of +Array+ instance methods to a new class +Queue+:
#
# class Queue
# extend Forwardable
@@ -113,7 +112,8 @@ module Forwardable
require 'forwardable/impl'
# Version of +forwardable.rb+
- FORWARDABLE_VERSION = "1.2.0"
+ VERSION = "1.3.2"
+ FORWARDABLE_VERSION = VERSION
@debug = nil
class << self
@@ -122,7 +122,8 @@ module Forwardable
end
# Takes a hash as its argument. The key is a symbol or an array of
- # symbols. These symbols correspond to method names. The value is
+ # symbols. These symbols correspond to method names, instance variable
+ # names, or constant names (see def_delegator). The value is
# the accessor to which the methods will be delegated.
#
# :call-seq:
@@ -151,18 +152,21 @@ module Forwardable
# def_delegator :@records, :map
#
def def_instance_delegators(accessor, *methods)
- methods.delete("__send__")
- methods.delete("__id__")
- for method in methods
+ methods.each do |method|
+ next if /\A__(?:send|id)__\z/ =~ method
def_instance_delegator(accessor, method)
end
end
# Define +method+ as delegator instance method with an optional
# alias name +ali+. Method calls to +ali+ will be delegated to
- # +accessor.method+.
+ # +accessor.method+. +accessor+ should be a method name, instance
+ # variable name, or constant name. Use the full path to the
+ # constant if providing the constant name.
+ # Returns the name of the method defined.
#
# class MyQueue
+ # CONST = 1
# extend Forwardable
# attr_reader :queue
# def initialize
@@ -170,18 +174,23 @@ module Forwardable
# end
#
# def_delegator :@queue, :push, :mypush
+ # def_delegator 'MyQueue::CONST', :to_i
# end
#
# q = MyQueue.new
# q.mypush 42
# q.queue #=> [42]
# q.push 23 #=> NoMethodError
+ # q.to_i #=> 1
#
def def_instance_delegator(accessor, method, ali = method)
gen = Forwardable._delegator_method(self, accessor, method, ali)
# If it's not a class or module, it's an instance
- (Module === self ? self : singleton_class).module_eval(&gen)
+ mod = Module === self ? self : singleton_class
+ ret = mod.module_eval(&gen)
+ mod.__send__(:ruby2_keywords, ali) if RUBY_VERSION >= '2.7'
+ ret
end
alias delegate instance_delegate
@@ -206,7 +215,7 @@ module Forwardable
method_call = "#{<<-"begin;"}\n#{<<-"end;".chomp}"
begin;
unless defined? _.#{method}
- ::Kernel.warn "\#{caller_locations(1)[0]}: "#{mesg.dump}"\#{_.class}"'##{method}'
+ ::Kernel.warn #{mesg.dump}"\#{_.class}"'##{method}', uplevel: 1
_#{method_call}
else
_.#{method}(*args, &block)
@@ -221,7 +230,7 @@ module Forwardable
#{pre}
begin
#{accessor}
- end#{method_call}#{FILTER_EXCEPTION}
+ end#{method_call}
end
end
end;
@@ -283,9 +292,8 @@ module SingleForwardable
# def_delegator :@records, :map
#
def def_single_delegators(accessor, *methods)
- methods.delete("__send__")
- methods.delete("__id__")
- for method in methods
+ methods.each do |method|
+ next if /\A__(?:send|id)__\z/ =~ method
def_single_delegator(accessor, method)
end
end
@@ -296,10 +304,13 @@ module SingleForwardable
# Defines a method _method_ which delegates to _accessor_ (i.e. it calls
# the method of the same name in _accessor_). If _new_name_ is
# provided, it is used as the name for the delegate method.
+ # Returns the name of the method defined.
def def_single_delegator(accessor, method, ali = method)
gen = Forwardable._delegator_method(self, accessor, method, ali)
- instance_eval(&gen)
+ ret = instance_eval(&gen)
+ singleton_class.__send__(:ruby2_keywords, ali) if RUBY_VERSION >= '2.7'
+ ret
end
alias delegate single_delegate
diff --git a/lib/forwardable/forwardable.gemspec b/lib/forwardable/forwardable.gemspec
new file mode 100644
index 0000000000..523b8eec6f
--- /dev/null
+++ b/lib/forwardable/forwardable.gemspec
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Keiju ISHITSUKA"]
+ spec.email = ["keiju@ruby-lang.org"]
+
+ spec.summary = %q{Provides delegation of specified methods to a designated object.}
+ spec.description = %q{Provides delegation of specified methods to a designated object.}
+ spec.homepage = "https://github.com/ruby/forwardable"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.required_ruby_version = '>= 2.4.0'
+ spec.files = ["forwardable.gemspec", "lib/forwardable.rb", "lib/forwardable/impl.rb"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/forwardable/impl.rb b/lib/forwardable/impl.rb
index 220d25aa95..58a9dfb69c 100644
--- a/lib/forwardable/impl.rb
+++ b/lib/forwardable/impl.rb
@@ -1,13 +1,5 @@
# :stopdoc:
module Forwardable
- FILE_REGEXP = %r"#{Regexp.quote(File.dirname(__FILE__))}"
- FILTER_EXCEPTION = <<-'END'
-
- rescue ::Exception
- $@.delete_if {|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
- ::Kernel::raise
- END
-
def self._valid_method?(method)
catch {|tag|
eval("BEGIN{throw tag}; ().#{method}", binding, __FILE__, __LINE__)
diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb
index ff7674f1cb..53b80ff16c 100644
--- a/lib/getoptlong.rb
+++ b/lib/getoptlong.rb
@@ -85,6 +85,9 @@
# hello -n 6 --name -- /tmp
#
class GetoptLong
+ # Version.
+ VERSION = "0.1.1"
+
#
# Orderings.
#
diff --git a/lib/getoptlong/getoptlong.gemspec b/lib/getoptlong/getoptlong.gemspec
new file mode 100644
index 0000000000..9ebe3aed7e
--- /dev/null
+++ b/lib/getoptlong/getoptlong.gemspec
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{GetoptLong for Ruby}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/getoptlong"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/ipaddr.gemspec b/lib/ipaddr.gemspec
index 11ebe826ec..5187f3be11 100644
--- a/lib/ipaddr.gemspec
+++ b/lib/ipaddr.gemspec
@@ -1,10 +1,11 @@
+# frozen_string_literal: true
# coding: utf-8
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
Gem::Specification.new do |spec|
spec.name = "ipaddr"
- spec.version = "1.0.0"
+ spec.version = "1.2.2"
spec.authors = ["Akinori MUSHA", "Hajimu UMEMOTO"]
spec.email = ["knu@idaemons.org", "ume@mahoroba.org"]
@@ -14,13 +15,10 @@ IPAddr provides a set of methods to manipulate an IP address.
Both IPv4 and IPv6 are supported.
DESCRIPTION
spec.homepage = "https://github.com/ruby/ipaddr"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "ipaddr.gemspec", "lib/ipaddr.rb"]
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.files = ["LICENSE.txt", "README.md", "ipaddr.gemspec", "lib/ipaddr.rb"]
spec.require_paths = ["lib"]
- spec.add_development_dependency "bundler", "~> 1.15"
- spec.add_development_dependency "rake", "~> 10.0"
- spec.add_development_dependency "test-unit"
+ spec.required_ruby_version = ">= 2.3"
end
diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb
index 6f70ebf773..7fff54b9d0 100644
--- a/lib/ipaddr.rb
+++ b/lib/ipaddr.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#
# ipaddr.rb - A class to manipulate an IP address
#
@@ -103,13 +103,13 @@ class IPAddr
# Creates a new ipaddr containing the given network byte ordered
# string form of an IP address.
- def IPAddr::new_ntoh(addr)
- return IPAddr.new(IPAddr::ntop(addr))
+ def self.new_ntoh(addr)
+ return new(ntop(addr))
end
# Convert a network byte ordered string form of an IP address into
# human readable form.
- def IPAddr::ntop(addr)
+ def self.ntop(addr)
case addr.size
when 4
s = addr.unpack('C4').join('.')
@@ -259,6 +259,50 @@ class IPAddr
return @family == Socket::AF_INET6
end
+ # Returns true if the ipaddr is a loopback address.
+ def loopback?
+ case @family
+ when Socket::AF_INET
+ @addr & 0xff000000 == 0x7f000000
+ when Socket::AF_INET6
+ @addr == 1
+ else
+ raise AddressFamilyError, "unsupported address family"
+ end
+ end
+
+ # Returns true if the ipaddr is a private address. IPv4 addresses
+ # in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined in RFC
+ # 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in RFC
+ # 4193 are considered private.
+ def private?
+ case @family
+ when Socket::AF_INET
+ @addr & 0xff000000 == 0x0a000000 || # 10.0.0.0/8
+ @addr & 0xfff00000 == 0xac100000 || # 172.16.0.0/12
+ @addr & 0xffff0000 == 0xc0a80000 # 192.168.0.0/16
+ when Socket::AF_INET6
+ @addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000
+ else
+ raise AddressFamilyError, "unsupported address family"
+ end
+ end
+
+ # Returns true if the ipaddr is a link-local address. IPv4
+ # addresses in 169.254.0.0/16 reserved by RFC 3927 and Link-Local
+ # IPv6 Unicast Addresses in fe80::/10 reserved by RFC 4291 are
+ # considered link-local.
+ def link_local?
+ case @family
+ when Socket::AF_INET
+ @addr & 0xffff0000 == 0xa9fe0000 # 169.254.0.0/16
+ when Socket::AF_INET6
+ @addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000
+ else
+ raise AddressFamilyError, "unsupported address family"
+ end
+ end
+
# Returns true if the ipaddr is an IPv4-mapped IPv6 address.
def ipv4_mapped?
return ipv6? && (@addr >> 32) == 0xffff
@@ -266,6 +310,11 @@ class IPAddr
# Returns true if the ipaddr is an IPv4-compatible IPv6 address.
def ipv4_compat?
+ warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
+ _ipv4_compat?
+ end
+
+ def _ipv4_compat?
if !ipv6? || (@addr >> 32) != 0
return false
end
@@ -273,6 +322,8 @@ class IPAddr
return a != 0 && a != 1
end
+ private :_ipv4_compat?
+
# Returns a new ipaddr built by converting the native IPv4 address
# into an IPv4-mapped IPv6 address.
def ipv4_mapped
@@ -285,6 +336,7 @@ class IPAddr
# Returns a new ipaddr built by converting the native IPv4 address
# into an IPv4-compatible IPv6 address.
def ipv4_compat
+ warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
if !ipv4?
raise InvalidAddressError, "not an IPv4 address"
end
@@ -295,7 +347,7 @@ class IPAddr
# native IPv4 address. If the IP address is not an IPv4-mapped or
# IPv4-compatible IPv6 address, returns self.
def native
- if !ipv4_mapped? && !ipv4_compat?
+ if !ipv4_mapped? && !_ipv4_compat?
return self
end
return self.clone.set(@addr & IN4MASK, Socket::AF_INET)
@@ -371,6 +423,35 @@ class IPAddr
return clone.set(begin_addr, @family)..clone.set(end_addr, @family)
end
+ # Returns the prefix length in bits for the ipaddr.
+ def prefix
+ case @family
+ when Socket::AF_INET
+ n = IN4MASK ^ @mask_addr
+ i = 32
+ when Socket::AF_INET6
+ n = IN6MASK ^ @mask_addr
+ i = 128
+ else
+ raise AddressFamilyError, "unsupported address family"
+ end
+ while n.positive?
+ n >>= 1
+ i -= 1
+ end
+ i
+ end
+
+ # Sets the prefix length in bits
+ def prefix=(prefix)
+ case prefix
+ when Integer
+ mask!(prefix)
+ else
+ raise InvalidPrefixError, "prefix must be an integer"
+ end
+ end
+
# Returns a string containing a human-readable representation of the
# ipaddr. ("#<IPAddr: family:address/mask>")
def inspect
@@ -413,7 +494,8 @@ class IPAddr
# Set current netmask to given mask.
def mask!(mask)
- if mask.kind_of?(String)
+ case mask
+ when String
if mask =~ /\A\d+\z/
prefixlen = mask.to_i
else
@@ -422,6 +504,10 @@ class IPAddr
raise InvalidPrefixError, "address family is not same"
end
@mask_addr = m.to_i
+ n = @mask_addr ^ m.instance_variable_get(:@mask_addr)
+ unless ((n + 1) & n).zero?
+ raise InvalidPrefixError, "invalid mask #{mask}"
+ end
@addr &= @mask_addr
return self
end
@@ -508,6 +594,8 @@ class IPAddr
else
@mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
end
+ rescue InvalidAddressError => e
+ raise e.class, "#{e.message}: #{addr}"
end
def coerce_other(other)
diff --git a/lib/irb.rb b/lib/irb.rb
index 3c7de05289..93c4d25c92 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -9,15 +9,20 @@
#
#
#
-require "e2mmap"
+require "ripper"
+require "reline"
-require "irb/init"
-require "irb/context"
-require "irb/extend-command"
+require_relative "irb/init"
+require_relative "irb/context"
+require_relative "irb/extend-command"
-require "irb/ruby-lex"
-require "irb/input-method"
-require "irb/locale"
+require_relative "irb/ruby-lex"
+require_relative "irb/input-method"
+require_relative "irb/locale"
+require_relative "irb/color"
+
+require_relative "irb/version"
+require_relative "irb/easter-egg"
# IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby
# expressions read from the standard input.
@@ -41,8 +46,8 @@ require "irb/locale"
# irb(main):006:1> end
# #=> nil
#
-# The Readline extension module can be used with irb. Use of Readline is
-# default if it's installed.
+# The singleline editor module or multiline editor module can be used with irb.
+# Use of multiline editor is default if it's installed.
#
# == Command line options
#
@@ -55,24 +60,36 @@ require "irb/locale"
# -E enc Same as `ruby -E`
# -w Same as `ruby -w`
# -W[level=2] Same as `ruby -W`
-# --inspect Use `inspect' for output (default except for bc mode)
+# --context-mode n Set n[0-4] to method to create Binding Object,
+# when new workspace was created
+# --echo Show result(default)
+# --noecho Don't show result
+# --inspect Use `inspect' for output
# --noinspect Don't use inspect for output
-# --readline Use Readline extension module
-# --noreadline Don't use Readline extension module
-# --prompt prompt-mode
-# --prompt-mode prompt-mode
+# --multiline Use multiline editor module
+# --nomultiline Don't use multiline editor module
+# --singleline Use singleline editor module
+# --nosingleline Don't use singleline editor module
+# --colorize Use colorization
+# --nocolorize Don't use colorization
+# --prompt prompt-mode/--prompt-mode prompt-mode
# Switch prompt mode. Pre-defined prompt modes are
# `default', `simple', `xmp' and `inf-ruby'
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
-# Suppresses --readline.
-# --simple-prompt Simple prompt mode
+# Suppresses --multiline and --singleline.
+# --sample-book-mode/--simple-prompt
+# Simple prompt mode
# --noprompt No prompt mode
+# --single-irb Share self with sub-irb.
# --tracer Display trace for each execution of commands.
# --back-trace-limit n
# Display backtrace top n and tail n. The default
# value is 16.
-# --irb_debug n Set internal debug level to n (not for popular use)
-# -v, --version Print the version of irb
+# --verbose Show details
+# --noverbose Don't show details
+# -v, --version Print the version of irb
+# -h, --help Print help
+# -- Separate options of irb from the list of command-line args
#
# == Configuration
#
@@ -93,19 +110,20 @@ require "irb/locale"
# IRB.conf[:IRB_RC] = nil
# IRB.conf[:BACK_TRACE_LIMIT]=16
# IRB.conf[:USE_LOADER] = false
-# IRB.conf[:USE_READLINE] = nil
+# IRB.conf[:USE_MULTILINE] = nil
+# IRB.conf[:USE_SINGLELINE] = nil
+# IRB.conf[:USE_COLORIZE] = true
# IRB.conf[:USE_TRACER] = false
# IRB.conf[:IGNORE_SIGINT] = true
# IRB.conf[:IGNORE_EOF] = false
# IRB.conf[:PROMPT_MODE] = :DEFAULT
# IRB.conf[:PROMPT] = {...}
-# IRB.conf[:DEBUG_LEVEL]=0
#
# === Auto indentation
#
-# To enable auto-indent mode in irb, add the following to your +.irbrc+:
+# To disable auto-indent mode in irb, add the following to your +.irbrc+:
#
-# IRB.conf[:AUTO_INDENT] = true
+# IRB.conf[:AUTO_INDENT] = false
#
# === Autocompletion
#
@@ -115,16 +133,23 @@ require "irb/locale"
#
# === History
#
-# By default, irb disables history and will not store any commands you used.
-#
-# If you want to enable history, add the following to your +.irbrc+:
+# By default, irb will store the last 1000 commands you used in
+# <code>IRB.conf[:HISTORY_FILE]</code> (<code>~/.irb_history</code> by default).
#
-# IRB.conf[:SAVE_HISTORY] = 1000
+# If you want to disable history, add the following to your +.irbrc+:
#
-# This will now store the last 1000 commands in <code>~/.irb_history</code>.
+# IRB.conf[:SAVE_HISTORY] = nil
#
# See IRB::Context#save_history= for more information.
#
+# The history of _results_ of commands evaluated is not stored by default,
+# but can be turned on to be stored with this +.irbrc+ setting:
+#
+# IRB.conf[:EVAL_HISTORY] = <number>
+#
+# See IRB::Context#eval_history= and History class. The history of command
+# results is not permanently saved in any file.
+#
# == Customizing the IRB Prompt
#
# In order to customize the prompt, you can change the following Hash:
@@ -134,7 +159,7 @@ require "irb/locale"
# This example can be used in your +.irbrc+
#
# IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
-# :AUTO_INDENT => true, # enables auto-indent mode
+# :AUTO_INDENT => false, # disables auto-indent mode
# :PROMPT_I => ">> ", # simple prompt
# :PROMPT_S => nil, # prompt for continuated strings
# :PROMPT_C => nil, # prompt for continuated statement
@@ -163,6 +188,7 @@ require "irb/locale"
#
# IRB.conf[:PROMPT_MODE][:DEFAULT] = {
# :PROMPT_I => "%N(%m):%03n:%i> ",
+# :PROMPT_N => "%N(%m):%03n:%i> ",
# :PROMPT_S => "%N(%m):%03n:%i%l ",
# :PROMPT_C => "%N(%m):%03n:%i* ",
# :RETURN => "%s\n" # used to printf
@@ -255,7 +281,7 @@ require "irb/locale"
# On the other hand, each conf in IRB@Command+line+options is used to
# individually configure IRB.irb.
#
-# If a proc is set for IRB.conf[:IRB_RC], its will be invoked after execution
+# If a proc is set for <code>IRB.conf[:IRB_RC]</code>, its will be invoked after execution
# of that proc with the context of the current session as its argument. Each
# session can be configured using this mechanism.
#
@@ -266,7 +292,9 @@ require "irb/locale"
# <code>_</code>::
# The value command executed, as a local variable
# <code>__</code>::
-# The history of evaluated commands
+# The history of evaluated commands. Available only if
+# <code>IRB.conf[:EVAL_HISTORY]</code> is not +nil+ (which is the default).
+# See also IRB::Context#eval_history= and IRB::History.
# <code>__[line_no]</code>::
# Returns the evaluation value at the given line number, +line_no+.
# If +line_no+ is a negative, the return value +line_no+ many lines before
@@ -302,7 +330,7 @@ require "irb/locale"
# # check if Foo#foo is available
# irb(main):005:0> Foo.instance_methods #=> [:foo, ...]
#
-# # change the active sesssion
+# # change the active session
# irb(main):006:0> fg 2
# # define Foo#bar in the context of Foo
# irb.2(Foo):005:0> def bar
@@ -354,9 +382,7 @@ module IRB
def IRB.version
if v = @CONF[:VERSION] then return v end
- require "irb/version"
- rv = @RELEASE_VERSION.sub(/\.0/, "")
- @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE)
+ @CONF[:VERSION] = format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
end
# The current IRB::Context of the session, see IRB.conf
@@ -383,7 +409,7 @@ module IRB
irb.run(@CONF)
end
- # Calls each event hook of IRB.conf[:AT_EXIT] when the current session quits.
+ # Calls each event hook of <code>IRB.conf[:AT_EXIT]</code> when the current session quits.
def IRB.irb_at_exit
@CONF[:AT_EXIT].each{|hook| hook.call}
end
@@ -405,21 +431,48 @@ module IRB
end
class Irb
+ ASSIGNMENT_NODE_TYPES = [
+ # Local, instance, global, class, constant, instance, and index assignment:
+ # "foo = bar",
+ # "@foo = bar",
+ # "$foo = bar",
+ # "@@foo = bar",
+ # "::Foo = bar",
+ # "a::Foo = bar",
+ # "Foo = bar"
+ # "foo.bar = 1"
+ # "foo[1] = bar"
+ :assign,
+
+ # Operation assignment:
+ # "foo += bar"
+ # "foo -= bar"
+ # "foo ||= bar"
+ # "foo &&= bar"
+ :opassign,
+
+ # Multiple assignment:
+ # "foo, bar = 1, 2
+ :massign,
+ ]
+ # Note: instance and index assignment expressions could also be written like:
+ # "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former
+ # be parsed as :assign and echo will be suppressed, but the latter is
+ # parsed as a :method_add_arg and the output won't be suppressed
+
# Creates a new irb session
- def initialize(workspace = nil, input_method = nil, output_method = nil)
- @context = Context.new(self, workspace, input_method, output_method)
+ def initialize(workspace = nil, input_method = nil)
+ @context = Context.new(self, workspace, input_method)
@context.main.extend ExtendCommandBundle
@signal_status = :IN_IRB
-
@scanner = RubyLex.new
- @scanner.exception_on_syntax_error = false
end
def run(conf = IRB.conf)
conf[:IRB_RC].call(context) if conf[:IRB_RC]
conf[:MAIN_CONTEXT] = context
- trap("SIGINT") do
+ prev_trap = trap("SIGINT") do
signal_handle
end
@@ -428,6 +481,7 @@ module IRB
eval_input
end
ensure
+ trap("SIGINT", prev_trap)
conf[:AT_EXIT].each{|hook| hook.call}
end
end
@@ -439,6 +493,8 @@ module IRB
# Evaluates input for this session.
def eval_input
+ exc = nil
+
@scanner.set_prompt do
|ltype, indent, continue, line_no|
if ltype
@@ -456,14 +512,16 @@ module IRB
else
@context.io.prompt = p = ""
end
- if @context.auto_indent_mode
+ if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent)
unless ltype
- ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
+ prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i
+ ind = prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size +
indent * 2 - p.size
ind += 2 if continue
@context.io.prompt = p + " " * ind if ind > 0
end
end
+ @context.io.prompt
end
@scanner.set_input(@context.io) do
@@ -477,65 +535,133 @@ module IRB
printf "Use \"exit\" to leave %s\n", @context.ap_name
end
else
- print "\n"
+ print "\n" if @context.prompting?
end
end
l
end
end
+ @scanner.set_auto_indent(@context) if @context.auto_indent_mode
+
@scanner.each_top_level_statement do |line, line_no|
signal_status(:IN_EVAL) do
begin
- line.untaint
- @context.evaluate(line, line_no)
- output_value if @context.echo?
- exc = nil
- rescue Interrupt => exc
- rescue SystemExit, SignalException
- raise
- rescue Exception => exc
- end
- if exc
- print exc.class, ": ", exc, "\n"
- if exc.backtrace && exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
- !(SyntaxError === exc)
- irb_bug = true
- else
- irb_bug = false
+ line.untaint if RUBY_VERSION < '2.7'
+ if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
+ IRB.set_measure_callback
end
-
- messages = []
- lasts = []
- levels = 0
- if exc.backtrace
- for m in exc.backtrace
- m = @context.workspace.filter_backtrace(m) unless irb_bug
- if m
- if messages.size < @context.back_trace_limit
- messages.push "\tfrom "+m
- else
- lasts.push "\tfrom "+m
- if lasts.size > @context.back_trace_limit
- lasts.shift
- levels += 1
- end
+ if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
+ result = nil
+ last_proc = proc{ result = @context.evaluate(line, line_no, exception: exc) }
+ IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) { |chain, item|
+ _name, callback, arg = item
+ proc {
+ callback.(@context, line, line_no, arg, exception: exc) do
+ chain.call
end
+ }
+ }.call
+ @context.set_last_value(result)
+ else
+ @context.evaluate(line, line_no, exception: exc)
+ end
+ if @context.echo?
+ if assignment_expression?(line)
+ if @context.echo_on_assignment?
+ output_value(@context.echo_on_assignment? == :truncate)
end
+ else
+ output_value
end
end
- print messages.join("\n"), "\n"
- unless lasts.empty?
- printf "... %d levels...\n", levels if levels > 0
- print lasts.join("\n"), "\n"
- end
- print "Maybe IRB bug!\n" if irb_bug
+ rescue Interrupt => exc
+ rescue SystemExit, SignalException
+ raise
+ rescue Exception => exc
+ else
+ exc = nil
+ next
end
- if $SAFE > 2
- abort "Error: irb does not work for $SAFE level higher than 2"
+ handle_exception(exc)
+ @context.workspace.local_variable_set(:_, exc)
+ exc = nil
+ end
+ end
+ end
+
+ def convert_invalid_byte_sequence(str)
+ str = str.force_encoding(Encoding::ASCII_8BIT)
+ conv = Encoding::Converter.new(Encoding::ASCII_8BIT, Encoding::UTF_8)
+ dst = String.new
+ begin
+ ret = conv.primitive_convert(str, dst)
+ case ret
+ when :invalid_byte_sequence
+ conv.insert_output(conf.primitive_errinfo[3].dump[1..-2])
+ redo
+ when :undefined_conversion
+ c = conv.primitive_errinfo[3].dup.force_encoding(conv.primitive_errinfo[1])
+ conv.insert_output(c.dump[1..-2])
+ redo
+ when :incomplete_input
+ conv.insert_output(conv.primitive_errinfo[3].dump[1..-2])
+ when :finished
+ end
+ break
+ end while nil
+ dst
+ end
+
+ def handle_exception(exc)
+ if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
+ !(SyntaxError === exc) && !(EncodingError === exc)
+ # The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno.
+ irb_bug = true
+ else
+ irb_bug = false
+ end
+
+ if exc.backtrace
+ order = nil
+ if '2.5.0' == RUBY_VERSION
+ # Exception#full_message doesn't have keyword arguments.
+ message = exc.full_message # the same of (highlight: true, order: bottom)
+ order = :bottom
+ elsif '2.5.1' <= RUBY_VERSION && RUBY_VERSION < '3.0.0'
+ if STDOUT.tty?
+ message = exc.full_message(order: :bottom)
+ order = :bottom
+ else
+ message = exc.full_message(order: :top)
+ order = :top
end
+ else # '3.0.0' <= RUBY_VERSION
+ message = exc.full_message(order: :top)
+ order = :top
end
+ message = convert_invalid_byte_sequence(message)
+ message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
+ case order
+ when :top
+ lines = m.split("\n")
+ when :bottom
+ lines = m.split("\n").reverse
+ end
+ unless irb_bug
+ lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
+ if lines.size > @context.back_trace_limit
+ omit = lines.size - @context.back_trace_limit
+ lines = lines[0..(@context.back_trace_limit - 1)]
+ lines << "\t... %d levels..." % omit
+ end
+ end
+ lines = lines.reverse if order == :bottom
+ lines.map{ |l| l + "\n" }.join
+ }
+ puts message
end
+ print "Maybe IRB bug!\n" if irb_bug
end
# Evaluates the given block using the given +path+ as the Context#irb_path
@@ -641,10 +767,18 @@ module IRB
when "l"
ltype
when "i"
- if $1
- format("%" + $1 + "d", indent)
+ if indent < 0
+ if $1
+ "-".rjust($1.to_i)
+ else
+ "-"
+ end
else
- indent.to_s
+ if $1
+ format("%" + $1 + "d", indent)
+ else
+ indent.to_s
+ end
end
when "n"
if $1
@@ -659,8 +793,37 @@ module IRB
p
end
- def output_value # :nodoc:
- printf @context.return_format, @context.inspect_last_value
+ def output_value(omit = false) # :nodoc:
+ str = @context.inspect_last_value
+ multiline_p = str.include?("\n")
+ if omit
+ winwidth = @context.io.winsize.last
+ if multiline_p
+ first_line = str.split("\n").first
+ result = @context.newline_before_multiline_output? ? (@context.return_format % first_line) : first_line
+ output_width = Reline::Unicode.calculate_width(result, true)
+ diff_size = output_width - Reline::Unicode.calculate_width(first_line, true)
+ if diff_size.positive? and output_width > winwidth
+ lines, _ = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
+ str = "%s...\e[0m" % lines.first
+ multiline_p = false
+ else
+ str = str.gsub(/(\A.*?\n).*/m, "\\1...")
+ end
+ else
+ output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
+ diff_size = output_width - Reline::Unicode.calculate_width(str, true)
+ if diff_size.positive? and output_width > winwidth
+ lines, _ = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
+ str = "%s...\e[0m" % lines.first
+ end
+ end
+ end
+ if multiline_p && @context.newline_before_multiline_output?
+ printf @context.return_format, "\n#{str}"
+ else
+ printf @context.return_format, str
+ end
end
# Outputs the local variables to this current session, including
@@ -679,6 +842,26 @@ module IRB
end
format("#<%s: %s>", self.class, ary.join(", "))
end
+
+ def assignment_expression?(line)
+ # Try to parse the line and check if the last of possibly multiple
+ # expressions is an assignment type.
+
+ # If the expression is invalid, Ripper.sexp should return nil which will
+ # result in false being returned. Any valid expression should return an
+ # s-expression where the second selement of the top level array is an
+ # array of parsed expressions. The first element of each expression is the
+ # expression's type.
+ verbose, $VERBOSE = $VERBOSE, nil
+ result = ASSIGNMENT_NODE_TYPES.include?(Ripper.sexp(line)&.dig(1,-1,0))
+ $VERBOSE = verbose
+ result
+ end
+
+ ATTR_TTY = "\e[%sm"
+ def ATTR_TTY.[](*a) self % a.join(";"); end
+ ATTR_PLAIN = ""
+ def ATTR_PLAIN.[](*) self; end
end
def @CONF.inspect
@@ -705,10 +888,69 @@ module IRB
end
class Binding
- # :nodoc:
- undef irb if method_defined?(:irb)
+ # Opens an IRB session where +binding.irb+ is called which allows for
+ # interactive debugging. You can call any methods or variables available in
+ # the current scope, and mutate state if you need to.
+ #
+ #
+ # Given a Ruby file called +potato.rb+ containing the following code:
+ #
+ # class Potato
+ # def initialize
+ # @cooked = false
+ # binding.irb
+ # puts "Cooked potato: #{@cooked}"
+ # end
+ # end
+ #
+ # Potato.new
+ #
+ # Running <code>ruby potato.rb</code> will open an IRB session where
+ # +binding.irb+ is called, and you will see the following:
+ #
+ # $ ruby potato.rb
+ #
+ # From: potato.rb @ line 4 :
+ #
+ # 1: class Potato
+ # 2: def initialize
+ # 3: @cooked = false
+ # => 4: binding.irb
+ # 5: puts "Cooked potato: #{@cooked}"
+ # 6: end
+ # 7: end
+ # 8:
+ # 9: Potato.new
+ #
+ # irb(#<Potato:0x00007feea1916670>):001:0>
+ #
+ # You can type any valid Ruby code and it will be evaluated in the current
+ # context. This allows you to debug without having to run your code repeatedly:
+ #
+ # irb(#<Potato:0x00007feea1916670>):001:0> @cooked
+ # => false
+ # irb(#<Potato:0x00007feea1916670>):002:0> self.class
+ # => Potato
+ # irb(#<Potato:0x00007feea1916670>):003:0> caller.first
+ # => ".../2.5.1/lib/ruby/2.5.0/irb/workspace.rb:85:in `eval'"
+ # irb(#<Potato:0x00007feea1916670>):004:0> @cooked = true
+ # => true
+ #
+ # You can exit the IRB session with the +exit+ command. Note that exiting will
+ # resume execution where +binding.irb+ had paused it, as you can see from the
+ # output printed to standard output in this example:
+ #
+ # irb(#<Potato:0x00007feea1916670>):005:0> exit
+ # Cooked potato: true
+ #
+ #
+ # See IRB@IRB+Usage for more information.
def irb
- IRB.setup(eval("__FILE__"))
- IRB::Irb.new(IRB::WorkSpace.new(self)).run(IRB.conf)
+ IRB.setup(source_location[0], argv: [])
+ workspace = IRB::WorkSpace.new(self)
+ STDOUT.print(workspace.code_around_binding)
+ binding_irb = IRB::Irb.new(workspace)
+ binding_irb.context.irb_path = File.expand_path(source_location[0])
+ binding_irb.run(IRB.conf)
end
end
diff --git a/lib/irb/.document b/lib/irb/.document
new file mode 100644
index 0000000000..3b0d6fa4ed
--- /dev/null
+++ b/lib/irb/.document
@@ -0,0 +1 @@
+**/*.rb
diff --git a/lib/irb/cmd/chws.rb b/lib/irb/cmd/chws.rb
index e93c976f82..e9f257791c 100644
--- a/lib/irb/cmd/chws.rb
+++ b/lib/irb/cmd/chws.rb
@@ -10,8 +10,8 @@
#
#
-require "irb/cmd/nop.rb"
-require "irb/ext/change-ws.rb"
+require_relative "nop"
+require_relative "../ext/change-ws"
# :stopdoc:
module IRB
diff --git a/lib/irb/cmd/fork.rb b/lib/irb/cmd/fork.rb
index ae4d51b5d1..7566d10be0 100644
--- a/lib/irb/cmd/fork.rb
+++ b/lib/irb/cmd/fork.rb
@@ -16,12 +16,12 @@ module IRB
module ExtendCommand
class Fork < Nop
def execute
- pid = send ExtendCommand.irb_original_method_name("fork")
+ pid = __send__ ExtendCommand.irb_original_method_name("fork")
unless pid
class << self
alias_method :exit, ExtendCommand.irb_original_method_name('exit')
end
- if iterator?
+ if block_given?
begin
yield
ensure
@@ -35,5 +35,3 @@ module IRB
end
end
# :startdoc:
-
-
diff --git a/lib/irb/cmd/help.rb b/lib/irb/cmd/help.rb
index db2bd567e5..0629479e92 100644
--- a/lib/irb/cmd/help.rb
+++ b/lib/irb/cmd/help.rb
@@ -9,17 +9,18 @@
#
#
-require 'rdoc/ri/driver'
-
-require "irb/cmd/nop.rb"
+require_relative "nop"
# :stopdoc:
module IRB
module ExtendCommand
class Help < Nop
- begin
- Ri = RDoc::RI::Driver.new
- rescue SystemExit
+ def execute(*names)
+ require 'rdoc/ri/driver'
+ IRB::ExtendCommand::Help.const_set(:Ri, RDoc::RI::Driver.new)
+ rescue LoadError, SystemExit
+ IRB::ExtendCommand::Help.remove_method(:execute)
+ # raise NoMethodError in ensure
else
def execute(*names)
if names.empty?
@@ -35,6 +36,9 @@ module IRB
end
nil
end
+ nil
+ ensure
+ execute(*names)
end
end
end
diff --git a/lib/irb/cmd/info.rb b/lib/irb/cmd/info.rb
new file mode 100644
index 0000000000..d122c88b77
--- /dev/null
+++ b/lib/irb/cmd/info.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: false
+
+require_relative "nop"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Info < Nop
+ def execute
+ Class.new {
+ def inspect
+ str = "Ruby version: #{RUBY_VERSION}\n"
+ str += "IRB version: #{IRB.version}\n"
+ str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
+ str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
+ str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
+ str
+ end
+ alias_method :to_s, :inspect
+ }.new
+ end
+ end
+ end
+end
+# :startdoc:
diff --git a/lib/irb/cmd/load.rb b/lib/irb/cmd/load.rb
index f800b741eb..b6769a4124 100644
--- a/lib/irb/cmd/load.rb
+++ b/lib/irb/cmd/load.rb
@@ -10,8 +10,8 @@
#
#
-require "irb/cmd/nop.rb"
-require "irb/ext/loader"
+require_relative "nop"
+require_relative "../ext/loader"
# :stopdoc:
module IRB
diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb
new file mode 100644
index 0000000000..f163f4f9e6
--- /dev/null
+++ b/lib/irb/cmd/ls.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+require "reline"
+require_relative "nop"
+require_relative "../color"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Ls < Nop
+ def execute(*arg, grep: nil)
+ o = Output.new(grep: grep)
+
+ obj = arg.empty? ? irb_context.workspace.main : arg.first
+ locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
+ klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
+
+ o.dump("constants", obj.constants) if obj.respond_to?(:constants)
+ o.dump("#{klass}.methods", obj.singleton_methods(false))
+ o.dump("#{klass}#methods", klass.public_instance_methods(false))
+ o.dump("instance variables", obj.instance_variables)
+ o.dump("class variables", klass.class_variables)
+ o.dump("locals", locals)
+ end
+
+ class Output
+ MARGIN = " "
+
+ def initialize(grep: nil)
+ @grep = grep
+ @line_width = screen_width - MARGIN.length # right padding
+ end
+
+ def dump(name, strs)
+ strs = strs.grep(@grep) if @grep
+ strs = strs.sort
+ return if strs.empty?
+
+ # Attempt a single line
+ print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
+ if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
+ puts strs.join(MARGIN)
+ return
+ end
+ puts
+
+ # Dump with the largest # of columns that fits on a line
+ cols = strs.size
+ until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1
+ cols -= 1
+ end
+ widths = col_widths(strs, cols: cols)
+ strs.each_slice(cols) do |ss|
+ puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
+ end
+ end
+
+ private
+
+ def fits_on_line?(strs, cols:, offset: 0)
+ width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1)
+ width <= @line_width - offset
+ end
+
+ def col_widths(strs, cols:)
+ cols.times.map do |col|
+ (col...strs.size).step(cols).map do |i|
+ strs[i].length
+ end.max
+ end
+ end
+
+ def screen_width
+ Reline.get_screen_size.last
+ rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
+ 80
+ end
+ end
+ private_constant :Output
+ end
+ end
+end
+# :startdoc:
diff --git a/lib/irb/cmd/measure.rb b/lib/irb/cmd/measure.rb
new file mode 100644
index 0000000000..58eaec2ded
--- /dev/null
+++ b/lib/irb/cmd/measure.rb
@@ -0,0 +1,40 @@
+require_relative "nop"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Measure < Nop
+ def initialize(*args)
+ super(*args)
+ end
+
+ def execute(type = nil, arg = nil, &block)
+ case type
+ when :off
+ IRB.conf[:MEASURE] = nil
+ IRB.unset_measure_callback(arg)
+ when :list
+ IRB.conf[:MEASURE_CALLBACKS].each do |type_name, _, arg_val|
+ puts "- #{type_name}" + (arg_val ? "(#{arg_val.inspect})" : '')
+ end
+ when :on
+ IRB.conf[:MEASURE] = true
+ added = IRB.set_measure_callback(type, arg)
+ puts "#{added[0]} is added." if added
+ else
+ if block_given?
+ IRB.conf[:MEASURE] = true
+ added = IRB.set_measure_callback(&block)
+ puts "#{added[0]} is added." if added
+ else
+ IRB.conf[:MEASURE] = true
+ added = IRB.set_measure_callback(type, arg)
+ puts "#{added[0]} is added." if added
+ end
+ end
+ nil
+ end
+ end
+ end
+end
+# :startdoc:
diff --git a/lib/irb/cmd/nop.rb b/lib/irb/cmd/nop.rb
index 9cf4337c28..d6f7a611a6 100644
--- a/lib/irb/cmd/nop.rb
+++ b/lib/irb/cmd/nop.rb
@@ -14,10 +14,16 @@ module IRB
module ExtendCommand
class Nop
-
- def self.execute(conf, *opts)
- command = new(conf)
- command.execute(*opts)
+ if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
+ def self.execute(conf, *opts, **kwargs, &block)
+ command = new(conf)
+ command.execute(*opts, **kwargs, &block)
+ end
+ else
+ def self.execute(conf, *opts, &block)
+ command = new(conf)
+ command.execute(*opts, &block)
+ end
end
def initialize(conf)
diff --git a/lib/irb/cmd/pushws.rb b/lib/irb/cmd/pushws.rb
index ffe55abed6..612157d8a0 100644
--- a/lib/irb/cmd/pushws.rb
+++ b/lib/irb/cmd/pushws.rb
@@ -10,8 +10,8 @@
#
#
-require "irb/cmd/nop.rb"
-require "irb/ext/workspaces.rb"
+require_relative "nop"
+require_relative "../ext/workspaces"
# :stopdoc:
module IRB
@@ -38,4 +38,3 @@ module IRB
end
end
# :startdoc:
-
diff --git a/lib/irb/cmd/show_source.rb b/lib/irb/cmd/show_source.rb
new file mode 100644
index 0000000000..0bd40b7d4e
--- /dev/null
+++ b/lib/irb/cmd/show_source.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require_relative "nop"
+require_relative "../color"
+require_relative "../ruby-lex"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class ShowSource < Nop
+ def execute(str = nil)
+ unless str.is_a?(String)
+ puts "Error: Expected a string but got #{str.inspect}"
+ return
+ end
+ source = find_source(str)
+ if source && File.exist?(source.file)
+ show_source(source)
+ else
+ puts "Error: Couldn't locate a definition for #{str}"
+ end
+ nil
+ end
+
+ private
+
+ # @param [IRB::ExtendCommand::ShowSource::Source] source
+ def show_source(source)
+ puts
+ puts "#{bold("From")}: #{source.file}:#{source.first_line}"
+ puts
+ code = IRB::Color.colorize_code(File.read(source.file))
+ puts code.lines[(source.first_line - 1)...source.last_line].join
+ puts
+ end
+
+ def find_source(str)
+ case str
+ when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
+ eval(str, irb_context.workspace.binding) # trigger autoload
+ base = irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
+ file, line = base.const_source_location(str) if base.respond_to?(:const_source_location) # Ruby 2.7+
+ when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
+ owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding)
+ method = Regexp.last_match[:method]
+ if owner.respond_to?(:instance_method) && owner.instance_methods.include?(method.to_sym)
+ file, line = owner.instance_method(method).source_location
+ end
+ when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
+ receiver = eval(Regexp.last_match[:receiver] || 'self', irb_context.workspace.binding)
+ method = Regexp.last_match[:method]
+ file, line = receiver.method(method).source_location if receiver.respond_to?(method)
+ end
+ if file && line
+ Source.new(file: file, first_line: line, last_line: find_end(file, line))
+ end
+ end
+
+ def find_end(file, first_line)
+ return first_line unless File.exist?(file)
+ lex = RubyLex.new
+ code = +""
+ File.read(file).lines[(first_line - 1)..-1].each_with_index do |line, i|
+ _ltype, _indent, continue, code_block_open = lex.check_state(code << line)
+ if !continue && !code_block_open
+ return first_line + i
+ end
+ end
+ first_line
+ end
+
+ def bold(str)
+ Color.colorize(str, [:BOLD])
+ end
+
+ Source = Struct.new(
+ :file, # @param [String] - file name
+ :first_line, # @param [String] - first line
+ :last_line, # @param [String] - last line
+ keyword_init: true,
+ )
+ private_constant :Source
+ end
+ end
+end
+# :startdoc:
diff --git a/lib/irb/cmd/subirb.rb b/lib/irb/cmd/subirb.rb
index c1602f6e45..1e18607d1a 100644
--- a/lib/irb/cmd/subirb.rb
+++ b/lib/irb/cmd/subirb.rb
@@ -9,8 +9,8 @@
#
#
-require "irb/cmd/nop.rb"
-require "irb/ext/multi-irb"
+require_relative "nop"
+require_relative "../ext/multi-irb"
# :stopdoc:
module IRB
diff --git a/lib/irb/cmd/whereami.rb b/lib/irb/cmd/whereami.rb
new file mode 100644
index 0000000000..b3def11b93
--- /dev/null
+++ b/lib/irb/cmd/whereami.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require_relative "nop"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Whereami < Nop
+ def execute(*)
+ code = irb_context.workspace.code_around_binding
+ if code
+ puts code
+ else
+ puts "The current context doesn't have code."
+ end
+ end
+ end
+ end
+end
+# :startdoc:
diff --git a/lib/irb/color.rb b/lib/irb/color.rb
new file mode 100644
index 0000000000..cfbb3cc668
--- /dev/null
+++ b/lib/irb/color.rb
@@ -0,0 +1,251 @@
+# frozen_string_literal: true
+require 'reline'
+require 'ripper'
+require 'irb/ruby-lex'
+
+module IRB # :nodoc:
+ module Color
+ CLEAR = 0
+ BOLD = 1
+ UNDERLINE = 4
+ REVERSE = 7
+ RED = 31
+ GREEN = 32
+ YELLOW = 33
+ BLUE = 34
+ MAGENTA = 35
+ CYAN = 36
+
+ TOKEN_KEYWORDS = {
+ on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__', '__ENCODING__'],
+ on_const: ['ENV'],
+ }
+ private_constant :TOKEN_KEYWORDS
+
+ # A constant of all-bit 1 to match any Ripper's state in #dispatch_seq
+ ALL = -1
+ private_constant :ALL
+
+ begin
+ # Following pry's colors where possible, but sometimes having a compromise like making
+ # backtick and regexp as red (string's color, because they're sharing tokens).
+ TOKEN_SEQ_EXPRS = {
+ on_CHAR: [[BLUE, BOLD], ALL],
+ on_backtick: [[RED, BOLD], ALL],
+ on_comment: [[BLUE, BOLD], ALL],
+ on_const: [[BLUE, BOLD, UNDERLINE], ALL],
+ on_embexpr_beg: [[RED], ALL],
+ on_embexpr_end: [[RED], ALL],
+ on_embvar: [[RED], ALL],
+ on_float: [[MAGENTA, BOLD], ALL],
+ on_gvar: [[GREEN, BOLD], ALL],
+ on_heredoc_beg: [[RED], ALL],
+ on_heredoc_end: [[RED], ALL],
+ on_ident: [[BLUE, BOLD], Ripper::EXPR_ENDFN],
+ on_imaginary: [[BLUE, BOLD], ALL],
+ on_int: [[BLUE, BOLD], ALL],
+ on_kw: [[GREEN], ALL],
+ on_label: [[MAGENTA], ALL],
+ on_label_end: [[RED, BOLD], ALL],
+ on_qsymbols_beg: [[RED, BOLD], ALL],
+ on_qwords_beg: [[RED, BOLD], ALL],
+ on_rational: [[BLUE, BOLD], ALL],
+ on_regexp_beg: [[RED, BOLD], ALL],
+ on_regexp_end: [[RED, BOLD], ALL],
+ on_symbeg: [[YELLOW], ALL],
+ on_symbols_beg: [[RED, BOLD], ALL],
+ on_tstring_beg: [[RED, BOLD], ALL],
+ on_tstring_content: [[RED], ALL],
+ on_tstring_end: [[RED, BOLD], ALL],
+ on_words_beg: [[RED, BOLD], ALL],
+ on_parse_error: [[RED, REVERSE], ALL],
+ compile_error: [[RED, REVERSE], ALL],
+ on_assign_error: [[RED, REVERSE], ALL],
+ on_alias_error: [[RED, REVERSE], ALL],
+ on_class_name_error:[[RED, REVERSE], ALL],
+ on_param_error: [[RED, REVERSE], ALL],
+ on___end__: [[GREEN], ALL],
+ }
+ rescue NameError
+ # Give up highlighting Ripper-incompatible older Ruby
+ TOKEN_SEQ_EXPRS = {}
+ end
+ private_constant :TOKEN_SEQ_EXPRS
+
+ ERROR_TOKENS = TOKEN_SEQ_EXPRS.keys.select { |k| k.to_s.end_with?('error') }
+ private_constant :ERROR_TOKENS
+
+ class << self
+ def colorable?
+ $stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
+ end
+
+ def inspect_colorable?(obj, seen: {}.compare_by_identity)
+ case obj
+ when String, Symbol, Regexp, Integer, Float, FalseClass, TrueClass, NilClass
+ true
+ when Hash
+ without_circular_ref(obj, seen: seen) do
+ obj.all? { |k, v| inspect_colorable?(k, seen: seen) && inspect_colorable?(v, seen: seen) }
+ end
+ when Array
+ without_circular_ref(obj, seen: seen) do
+ obj.all? { |o| inspect_colorable?(o, seen: seen) }
+ end
+ when Range
+ inspect_colorable?(obj.begin, seen: seen) && inspect_colorable?(obj.end, seen: seen)
+ when Module
+ !obj.name.nil?
+ else
+ false
+ end
+ end
+
+ def clear
+ return '' unless colorable?
+ "\e[#{CLEAR}m"
+ end
+
+ def colorize(text, seq)
+ return text unless colorable?
+ seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('')
+ "#{seq}#{text}#{clear}"
+ end
+
+ # If `complete` is false (code is incomplete), this does not warn compile_error.
+ # This option is needed to avoid warning a user when the compile_error is happening
+ # because the input is not wrong but just incomplete.
+ def colorize_code(code, complete: true, ignore_error: false)
+ return code unless colorable?
+
+ symbol_state = SymbolState.new
+ colored = +''
+ length = 0
+ end_seen = false
+
+ scan(code, allow_last_error: !complete) do |token, str, expr|
+ # IRB::ColorPrinter skips colorizing fragments with any invalid token
+ if ignore_error && ERROR_TOKENS.include?(token)
+ return Reline::Unicode.escape_for_print(code)
+ end
+
+ in_symbol = symbol_state.scan_token(token)
+ str.each_line do |line|
+ line = Reline::Unicode.escape_for_print(line)
+ if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol)
+ colored << seq.map { |s| "\e[#{s}m" }.join('')
+ colored << line.sub(/\Z/, clear)
+ else
+ colored << line
+ end
+ end
+ length += str.bytesize
+ end_seen = true if token == :on___end__
+ end
+
+ # give up colorizing incomplete Ripper tokens
+ unless end_seen or length == code.bytesize
+ return Reline::Unicode.escape_for_print(code)
+ end
+
+ colored
+ end
+
+ private
+
+ def without_circular_ref(obj, seen:, &block)
+ return false if seen.key?(obj)
+ seen[obj] = true
+ block.call
+ ensure
+ seen.delete(obj)
+ end
+
+ def supported?
+ return @supported if defined?(@supported)
+ @supported = Ripper::Lexer::Elem.method_defined?(:state)
+ end
+
+ def scan(code, allow_last_error:)
+ pos = [1, 0]
+
+ verbose, $VERBOSE = $VERBOSE, nil
+ RubyLex.compile_with_errors_suppressed(code) do |inner_code, line_no|
+ lexer = Ripper::Lexer.new(inner_code, '(ripper)', line_no)
+ if lexer.respond_to?(:scan) # Ruby 2.7+
+ lexer.scan.each do |elem|
+ str = elem.tok
+ next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
+ next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
+
+ str.each_line do |line|
+ if line.end_with?("\n")
+ pos[0] += 1
+ pos[1] = 0
+ else
+ pos[1] += line.bytesize
+ end
+ end
+
+ yield(elem.event, str, elem.state)
+ end
+ else
+ lexer.parse.each do |elem|
+ yield(elem.event, elem.tok, elem.state)
+ end
+ end
+ end
+ ensure
+ $VERBOSE = verbose
+ end
+
+ def dispatch_seq(token, expr, str, in_symbol:)
+ if ERROR_TOKENS.include?(token)
+ TOKEN_SEQ_EXPRS[token][0]
+ elsif in_symbol
+ [YELLOW]
+ elsif TOKEN_KEYWORDS.fetch(token, []).include?(str)
+ [CYAN, BOLD]
+ elsif (seq, exprs = TOKEN_SEQ_EXPRS[token]; (expr & (exprs || 0)) != 0)
+ seq
+ else
+ nil
+ end
+ end
+ end
+
+ # A class to manage a state to know whether the current token is for Symbol or not.
+ class SymbolState
+ def initialize
+ # Push `true` to detect Symbol. `false` to increase the nest level for non-Symbol.
+ @stack = []
+ end
+
+ # Return true if the token is a part of Symbol.
+ def scan_token(token)
+ prev_state = @stack.last
+ case token
+ when :on_symbeg, :on_symbols_beg, :on_qsymbols_beg
+ @stack << true
+ when :on_ident, :on_op, :on_const, :on_ivar, :on_cvar, :on_gvar, :on_kw
+ if @stack.last # Pop only when it's Symbol
+ @stack.pop
+ return prev_state
+ end
+ when :on_tstring_beg
+ @stack << false
+ when :on_embexpr_beg
+ @stack << false
+ return prev_state
+ when :on_tstring_end # :on_tstring_end may close Symbol
+ @stack.pop
+ return prev_state
+ when :on_embexpr_end
+ @stack.pop
+ end
+ @stack.last
+ end
+ end
+ private_constant :SymbolState
+ end
+end
diff --git a/lib/irb/color_printer.rb b/lib/irb/color_printer.rb
new file mode 100644
index 0000000000..30c6825750
--- /dev/null
+++ b/lib/irb/color_printer.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+require 'pp'
+require 'irb/color'
+
+module IRB
+ class ColorPrinter < ::PP
+ class << self
+ def pp(obj, out = $>, width = screen_width)
+ q = ColorPrinter.new(out, width)
+ q.guard_inspect_key {q.pp obj}
+ q.flush
+ out << "\n"
+ end
+
+ private
+
+ def screen_width
+ Reline.get_screen_size.last
+ rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
+ 79
+ end
+ end
+
+ def pp(obj)
+ if obj.is_a?(String)
+ # Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n"
+ text(obj.inspect)
+ else
+ super
+ end
+ end
+
+ def text(str, width = nil)
+ unless str.is_a?(String)
+ str = str.inspect
+ end
+ width ||= str.length
+
+ case str
+ when /\A#</, '=', '>'
+ super(Color.colorize(str, [:GREEN]), width)
+ else
+ super(Color.colorize_code(str, ignore_error: true), width)
+ end
+ end
+ end
+end
diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb
index e7499a8e2b..d1bb82122e 100644
--- a/lib/irb/completion.rb
+++ b/lib/irb/completion.rb
@@ -1,13 +1,13 @@
# frozen_string_literal: false
#
-# irb/completor.rb -
+# irb/completion.rb -
# $Release Version: 0.9$
# $Revision$
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
# From Original Idea of shugo@ruby-lang.org
#
-require "readline"
+require_relative 'ruby-lex'
module IRB
module InputCompletor # :nodoc:
@@ -16,11 +16,12 @@ module IRB
# Set of reserved words used by Ruby, you should not use these for
# constants or variables
ReservedWords = %w[
+ __ENCODING__ __LINE__ __FILE__
BEGIN END
alias and
begin break
case class
- def defined do
+ def defined? do
else elsif end ensure
false for
if in
@@ -35,118 +36,235 @@ module IRB
yield
]
- CompletionProc = proc { |input|
- bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
+ BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
+ def self.retrieve_files_to_require_from_load_path
+ @@files_from_load_path ||= $LOAD_PATH.flat_map { |path|
+ begin
+ Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path)
+ rescue Errno::ENOENT
+ []
+ end
+ }.uniq.map { |path|
+ path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
+ }
+ end
+
+ def self.retrieve_files_to_require_relative_from_current_dir
+ @@files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
+ path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
+ }
+ end
+
+ CompletionRequireProc = lambda { |target, preposing = nil, postposing = nil|
+ if target =~ /\A(['"])([^'"]+)\Z/
+ quote = $1
+ actual_target = $2
+ else
+ return nil # It's not String literal
+ end
+ tokens = RubyLex.ripper_lex_without_warning(preposing.gsub(/\s*\z/, ''))
+ tok = nil
+ tokens.reverse_each do |t|
+ unless [:on_lparen, :on_sp, :on_ignored_sp, :on_nl, :on_ignored_nl, :on_comment].include?(t.event)
+ tok = t
+ break
+ end
+ end
+ result = []
+ if tok && tok.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
+ case tok.tok
+ when 'require'
+ result = retrieve_files_to_require_from_load_path.select { |path|
+ path.start_with?(actual_target)
+ }.map { |path|
+ quote + path
+ }
+ when 'require_relative'
+ result = retrieve_files_to_require_relative_from_current_dir.select { |path|
+ path.start_with?(actual_target)
+ }.map { |path|
+ quote + path
+ }
+ end
+ end
+ result
+ }
+
+ CompletionProc = lambda { |target, preposing = nil, postposing = nil|
+ if preposing && postposing
+ result = CompletionRequireProc.(target, preposing, postposing)
+ unless result
+ result = retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
+ end
+ result
+ else
+ retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
+ end
+ }
+
+ def self.retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
case input
when /^((["'`]).*\2)\.([^.]*)$/
# String
receiver = $1
- message = Regexp.quote($3)
+ message = $3
candidates = String.instance_methods.collect{|m| m.to_s}
- select_message(receiver, message, candidates)
+ if doc_namespace
+ "String.#{message}"
+ else
+ select_message(receiver, message, candidates)
+ end
when /^(\/[^\/]*\/)\.([^.]*)$/
# Regexp
receiver = $1
- message = Regexp.quote($2)
+ message = $2
candidates = Regexp.instance_methods.collect{|m| m.to_s}
- select_message(receiver, message, candidates)
+ if doc_namespace
+ "Regexp.#{message}"
+ else
+ select_message(receiver, message, candidates)
+ end
when /^([^\]]*\])\.([^.]*)$/
# Array
receiver = $1
- message = Regexp.quote($2)
+ message = $2
candidates = Array.instance_methods.collect{|m| m.to_s}
- select_message(receiver, message, candidates)
+ if doc_namespace
+ "Array.#{message}"
+ else
+ select_message(receiver, message, candidates)
+ end
when /^([^\}]*\})\.([^.]*)$/
# Proc or Hash
receiver = $1
- message = Regexp.quote($2)
+ message = $2
- candidates = Proc.instance_methods.collect{|m| m.to_s}
- candidates |= Hash.instance_methods.collect{|m| m.to_s}
- select_message(receiver, message, candidates)
+ proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
+ hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
+ if doc_namespace
+ ["Proc.#{message}", "Hash.#{message}"]
+ else
+ select_message(receiver, message, proc_candidates | hash_candidates)
+ end
when /^(:[^:.]*)$/
# Symbol
- if Symbol.respond_to?(:all_symbols)
- sym = $1
- candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
- candidates.grep(/^#{Regexp.quote(sym)}/)
- else
- []
+ return nil if doc_namespace
+ sym = $1
+ candidates = Symbol.all_symbols.collect do |s|
+ ":" + s.id2name.encode(Encoding.default_external)
+ rescue Encoding::UndefinedConversionError
+ # ignore
end
+ candidates.grep(/^#{Regexp.quote(sym)}/)
when /^::([A-Z][^:\.\(]*)$/
# Absolute Constant or class methods
receiver = $1
candidates = Object.constants.collect{|m| m.to_s}
- candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
+ if doc_namespace
+ candidates.find { |i| i == receiver }
+ else
+ candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
+ end
when /^([A-Z].*)::([^:.]*)$/
# Constant or class methods
receiver = $1
- message = Regexp.quote($2)
+ message = $2
begin
candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
rescue Exception
candidates = []
end
- select_message(receiver, message, candidates, "::")
+ if doc_namespace
+ "#{receiver}::#{message}"
+ else
+ select_message(receiver, message, candidates, "::")
+ end
when /^(:[^:.]+)(\.|::)([^.]*)$/
# Symbol
receiver = $1
sep = $2
- message = Regexp.quote($3)
+ message = $3
candidates = Symbol.instance_methods.collect{|m| m.to_s}
- select_message(receiver, message, candidates, sep)
+ if doc_namespace
+ "Symbol.#{message}"
+ else
+ select_message(receiver, message, candidates, sep)
+ end
- when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(\.|::)([^.]*)$/
+ when /^(?<num>-?(?:0[dbo])?[0-9_]+(?:\.[0-9_]+)?(?:(?:[eE][+-]?[0-9]+)?i?|r)?)(?<sep>\.|::)(?<mes>[^.]*)$/
# Numeric
- receiver = $1
- sep = $5
- message = Regexp.quote($6)
+ receiver = $~[:num]
+ sep = $~[:sep]
+ message = $~[:mes]
begin
- candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
+ instance = eval(receiver, bind)
+ if doc_namespace
+ "#{instance.class.name}.#{message}"
+ else
+ candidates = instance.methods.collect{|m| m.to_s}
+ select_message(receiver, message, candidates, sep)
+ end
rescue Exception
- candidates = []
+ if doc_namespace
+ nil
+ else
+ candidates = []
+ end
end
- select_message(receiver, message, candidates, sep)
when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/
# Numeric(0xFFFF)
receiver = $1
sep = $2
- message = Regexp.quote($3)
+ message = $3
begin
- candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
+ instance = eval(receiver, bind)
+ if doc_namespace
+ "#{instance.class.name}.#{message}"
+ else
+ candidates = instance.methods.collect{|m| m.to_s}
+ select_message(receiver, message, candidates, sep)
+ end
rescue Exception
- candidates = []
+ if doc_namespace
+ nil
+ else
+ candidates = []
+ end
end
- select_message(receiver, message, candidates, sep)
when /^(\$[^.]*)$/
# global var
- regmessage = Regexp.new(Regexp.quote($1))
- candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
+ gvar = $1
+ all_gvars = global_variables.collect{|m| m.to_s}
+ if doc_namespace
+ all_gvars.find{ |i| i == gvar }
+ else
+ all_gvars.grep(Regexp.new(Regexp.quote(gvar)))
+ end
when /^([^."].*)(\.|::)([^.]*)$/
# variable.func or func.func
receiver = $1
sep = $2
- message = Regexp.quote($3)
+ message = $3
- gv = eval("global_variables", bind).collect{|m| m.to_s}
+ gv = eval("global_variables", bind).collect{|m| m.to_s}.push("true", "false", "nil")
lv = eval("local_variables", bind).collect{|m| m.to_s}
iv = eval("instance_variables", bind).collect{|m| m.to_s}
cv = eval("self.class.constants", bind).collect{|m| m.to_s}
@@ -169,38 +287,76 @@ module IRB
else
# func1.func2
candidates = []
+ to_ignore = ignored_modules
ObjectSpace.each_object(Module){|m|
- begin
- name = m.name
- rescue Exception
- name = ""
- end
- begin
- next if name != "IRB::Context" and
- /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
- rescue Exception
- next
- end
+ next if (to_ignore.include?(m) rescue true)
candidates.concat m.instance_methods(false).collect{|x| x.to_s}
}
candidates.sort!
candidates.uniq!
end
- select_message(receiver, message, candidates, sep)
+ if doc_namespace
+ "#{rec.class.name}#{sep}#{candidates.find{ |i| i == message }}"
+ else
+ select_message(receiver, message, candidates, sep)
+ end
when /^\.([^.]*)$/
# unknown(maybe String)
receiver = ""
- message = Regexp.quote($1)
+ message = $1
candidates = String.instance_methods(true).collect{|m| m.to_s}
- select_message(receiver, message, candidates)
+ if doc_namespace
+ "String.#{candidates.find{ |i| i == message }}"
+ else
+ select_message(receiver, message, candidates)
+ end
else
candidates = eval("methods | private_methods | local_variables | instance_variables | self.class.constants", bind).collect{|m| m.to_s}
+ candidates |= ReservedWords
+
+ if doc_namespace
+ candidates.find{ |i| i == input }
+ else
+ candidates.grep(/^#{Regexp.quote(input)}/)
+ end
+ end
+ end
- (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
+ PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
+ begin
+ require 'rdoc'
+ rescue LoadError
+ return
+ end
+
+ RDocRIDriver ||= RDoc::RI::Driver.new
+
+ if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
+ IRB.__send__(:easter_egg)
+ return
+ end
+
+ namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
+ return unless namespace
+
+ if namespace.is_a?(Array)
+ out = RDoc::Markup::Document.new
+ namespace.each do |m|
+ begin
+ RDocRIDriver.add_method(out, m)
+ rescue RDoc::RI::Driver::NotFoundError
+ end
+ end
+ RDocRIDriver.display(out)
+ else
+ begin
+ RDocRIDriver.display_names([namespace])
+ rescue RDoc::RI::Driver::NotFoundError
+ end
end
}
@@ -208,7 +364,7 @@ module IRB
Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
def self.select_message(receiver, message, candidates, sep = ".")
- candidates.grep(/^#{message}/).collect do |e|
+ candidates.grep(/^#{Regexp.quote(message)}/).collect do |e|
case e
when /^[a-zA-Z_]/
receiver + sep + e
@@ -218,11 +374,30 @@ module IRB
end
end
end
- end
-end
-if Readline.respond_to?("basic_word_break_characters=")
- Readline.basic_word_break_characters= " \t\n`><=;|&{("
+ def self.ignored_modules
+ # We could cache the result, but this is very fast already.
+ # By using this approach, we avoid Module#name calls, which are
+ # relatively slow when there are a lot of anonymous modules defined.
+ s = {}
+
+ scanner = lambda do |m|
+ next if s.include?(m) # IRB::ExtendCommandBundle::EXCB recurses.
+ s[m] = true
+ m.constants(false).each do |c|
+ value = m.const_get(c)
+ scanner.call(value) if value.is_a?(Module)
+ end
+ end
+
+ %i(IRB RubyLex).each do |sym|
+ next unless Object.const_defined?(sym)
+ scanner.call(Object.const_get(sym))
+ end
+
+ s.delete(IRB::Context) if defined?(IRB::Context)
+
+ s
+ end
+ end
end
-Readline.completion_append_character = nil
-Readline.completion_proc = IRB::InputCompletor::CompletionProc
diff --git a/lib/irb/context.rb b/lib/irb/context.rb
index 9ccdf744fb..0d358de6ff 100644
--- a/lib/irb/context.rb
+++ b/lib/irb/context.rb
@@ -9,9 +9,10 @@
#
#
#
-require "irb/workspace"
-require "irb/inspector"
-require "irb/output-method"
+require_relative "workspace"
+require_relative "inspector"
+require_relative "input-method"
+require_relative "output-method"
module IRB
# A class that wraps the current state of the irb session, including the
@@ -21,10 +22,10 @@ module IRB
#
# The optional +input_method+ argument:
#
- # +nil+:: uses stdin or Readline
+ # +nil+:: uses stdin or Reidline or Readline
# +String+:: uses a File
# +other+:: uses this as InputMethod
- def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
+ def initialize(irb, workspace = nil, input_method = nil)
@irb = irb
if workspace
@workspace = workspace
@@ -38,7 +39,21 @@ module IRB
@rc = IRB.conf[:RC]
@load_modules = IRB.conf[:LOAD_MODULES]
- @use_readline = IRB.conf[:USE_READLINE]
+ if IRB.conf.has_key?(:USE_SINGLELINE)
+ @use_singleline = IRB.conf[:USE_SINGLELINE]
+ elsif IRB.conf.has_key?(:USE_READLINE) # backward compatibility
+ @use_singleline = IRB.conf[:USE_READLINE]
+ else
+ @use_singleline = nil
+ end
+ if IRB.conf.has_key?(:USE_MULTILINE)
+ @use_multiline = IRB.conf[:USE_MULTILINE]
+ elsif IRB.conf.has_key?(:USE_REIDLINE) # backward compatibility
+ @use_multiline = IRB.conf[:USE_REIDLINE]
+ else
+ @use_multiline = nil
+ end
+ @use_colorize = IRB.conf[:USE_COLORIZE]
@verbose = IRB.conf[:VERBOSE]
@io = nil
@@ -63,23 +78,42 @@ module IRB
case input_method
when nil
- case use_readline?
+ @io = nil
+ case use_multiline?
when nil
- if (defined?(ReadlineInputMethod) && STDIN.tty? &&
- IRB.conf[:PROMPT_MODE] != :INF_RUBY)
- @io = ReadlineInputMethod.new
+ if STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_singleline?
+ # Both of multiline mode and singleline mode aren't specified.
+ @io = ReidlineInputMethod.new
else
- @io = StdioInputMethod.new
+ @io = nil
end
when false
- @io = StdioInputMethod.new
+ @io = nil
when true
- if defined?(ReadlineInputMethod)
- @io = ReadlineInputMethod.new
+ @io = ReidlineInputMethod.new
+ end
+ unless @io
+ case use_singleline?
+ when nil
+ if (defined?(ReadlineInputMethod) && STDIN.tty? &&
+ IRB.conf[:PROMPT_MODE] != :INF_RUBY)
+ @io = ReadlineInputMethod.new
+ else
+ @io = nil
+ end
+ when false
+ @io = nil
+ when true
+ if defined?(ReadlineInputMethod)
+ @io = ReadlineInputMethod.new
+ else
+ @io = nil
+ end
else
- @io = StdioInputMethod.new
+ @io = nil
end
end
+ @io = StdioInputMethod.new unless @io
when String
@io = FileInputMethod.new(input_method)
@@ -90,17 +124,20 @@ module IRB
end
self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]
- if output_method
- @output_method = output_method
- else
- @output_method = StdioOutputMethod.new
- end
-
@echo = IRB.conf[:ECHO]
if @echo.nil?
@echo = true
end
- self.debug_level = IRB.conf[:DEBUG_LEVEL]
+
+ @echo_on_assignment = IRB.conf[:ECHO_ON_ASSIGNMENT]
+ if @echo_on_assignment.nil?
+ @echo_on_assignment = :truncate
+ end
+
+ @newline_before_multiline_output = IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT]
+ if @newline_before_multiline_output.nil?
+ @newline_before_multiline_output = true
+ end
end
# The top-level workspace, see WorkSpace#main
@@ -116,9 +153,9 @@ module IRB
attr_reader :thread
# The current input method
#
- # Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or
- # other specified when the context is created. See ::new for more
- # information on +input_method+.
+ # Can be either StdioInputMethod, ReadlineInputMethod,
+ # ReidlineInputMethod, FileInputMethod or other specified when the
+ # context is created. See ::new for more # information on +input_method+.
attr_accessor :io
# Current irb session
@@ -136,12 +173,18 @@ module IRB
# +input_method+ passed to Context.new
attr_accessor :irb_path
- # Whether +Readline+ is enabled or not.
+ # Whether multiline editor mode is enabled or not.
#
- # A copy of the default <code>IRB.conf[:USE_READLINE]</code>
+ # A copy of the default <code>IRB.conf[:USE_MULTILINE]</code>
+ attr_reader :use_multiline
+ # Whether singleline editor mode is enabled or not.
#
- # See #use_readline= for more information.
- attr_reader :use_readline
+ # A copy of the default <code>IRB.conf[:USE_SINGLELINE]</code>
+ attr_reader :use_singleline
+ # Whether colorization is enabled or not.
+ #
+ # A copy of the default <code>IRB.conf[:USE_COLORIZE]</code>
+ attr_reader :use_colorize
# A copy of the default <code>IRB.conf[:INSPECT_MODE]</code>
attr_reader :inspect_mode
@@ -164,17 +207,17 @@ module IRB
# Can be either the default <code>IRB.conf[:AUTO_INDENT]</code>, or the
# mode set by #prompt_mode=
#
- # To enable auto-indentation in irb:
+ # To disable auto-indentation in irb:
#
- # IRB.conf[:AUTO_INDENT] = true
+ # IRB.conf[:AUTO_INDENT] = false
#
# or
#
- # irb_context.auto_indent_mode = true
+ # irb_context.auto_indent_mode = false
#
# or
#
- # IRB.CurrentContext.auto_indent_mode = true
+ # IRB.CurrentContext.auto_indent_mode = false
#
# See IRB@Configuration for more information.
attr_accessor :auto_indent_mode
@@ -197,7 +240,7 @@ module IRB
attr_accessor :ignore_eof
# Whether to echo the return value to output or not.
#
- # Uses IRB.conf[:ECHO] if available, or defaults to +true+.
+ # Uses <code>IRB.conf[:ECHO]</code> if available, or defaults to +true+.
#
# puts "hello"
# # hello
@@ -206,14 +249,44 @@ module IRB
# puts "omg"
# # omg
attr_accessor :echo
+ # Whether to echo for assignment expressions
+ #
+ # If set to +false+, the value of assignment will not be shown.
+ #
+ # If set to +true+, the value of assignment will be shown.
+ #
+ # If set to +:truncate+, the value of assignment will be shown and truncated.
+ #
+ # It defaults to +:truncate+.
+ #
+ # a = "omg"
+ # #=> omg
+ # a = "omg" * 10
+ # #=> omgomgomgomgomgomgomg...
+ # IRB.CurrentContext.echo_on_assignment = false
+ # a = "omg"
+ # IRB.CurrentContext.echo_on_assignment = true
+ # a = "omg"
+ # #=> omgomgomgomgomgomgomgomgomgomg
+ attr_accessor :echo_on_assignment
+ # Whether a newline is put before multiline output.
+ #
+ # Uses <code>IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT]</code> if available,
+ # or defaults to +true+.
+ #
+ # "abc\ndef"
+ # #=>
+ # abc
+ # def
+ # IRB.CurrentContext.newline_before_multiline_output = false
+ # "abc\ndef"
+ # #=> abc
+ # def
+ attr_accessor :newline_before_multiline_output
# Whether verbose messages are displayed or not.
#
# A copy of the default <code>IRB.conf[:VERBOSE]</code>
attr_accessor :verbose
- # The debug level of irb
- #
- # See #debug_level= for more information.
- attr_reader :debug_level
# The limit of backtrace lines displayed as top +n+ and tail +n+.
#
@@ -224,18 +297,34 @@ module IRB
# See IRB@Command+line+options for more command line options.
attr_accessor :back_trace_limit
- # Alias for #use_readline
- alias use_readline? use_readline
+ # Alias for #use_multiline
+ alias use_multiline? use_multiline
+ # Alias for #use_singleline
+ alias use_singleline? use_singleline
+ # backward compatibility
+ alias use_reidline use_multiline
+ # backward compatibility
+ alias use_reidline? use_multiline
+ # backward compatibility
+ alias use_readline use_singleline
+ # backward compatibility
+ alias use_readline? use_singleline
+ # Alias for #use_colorize
+ alias use_colorize? use_colorize
# Alias for #rc
alias rc? rc
alias ignore_sigint? ignore_sigint
alias ignore_eof? ignore_eof
alias echo? echo
+ alias echo_on_assignment? echo_on_assignment
+ alias newline_before_multiline_output? newline_before_multiline_output
# Returns whether messages are displayed or not.
def verbose?
if @verbose.nil?
- if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
+ if @io.kind_of?(ReidlineInputMethod)
+ false
+ elsif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
false
elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
true
@@ -248,9 +337,11 @@ module IRB
end
# Whether #verbose? is +true+, and +input_method+ is either
- # StdioInputMethod or ReadlineInputMethod, see #io for more information.
+ # StdioInputMethod or ReidlineInputMethod or ReadlineInputMethod, see #io
+ # for more information.
def prompting?
verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
+ @io.kind_of?(ReidlineInputMethod) ||
(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
end
@@ -261,7 +352,7 @@ module IRB
# to #last_value.
def set_last_value(value)
@last_value = value
- @workspace.evaluate self, "_ = IRB.CurrentContext.last_value"
+ @workspace.local_variable_set :_, value
end
# Sets the +mode+ of the prompt in this context.
@@ -349,34 +440,13 @@ module IRB
@inspect_mode
end
- # Obsolete method.
- #
- # Can be set using the +--noreadline+ and +--readline+ command line
- # options.
- #
- # See IRB@Command+line+options for more command line options.
- def use_readline=(opt)
- print "This method is obsolete."
- print "Do nothing."
- end
-
- # Sets the debug level of irb
- #
- # Can also be set using the +--irb_debug+ command line option.
- #
- # See IRB@Command+line+options for more command line options.
- def debug_level=(value)
- @debug_level = value
- RubyLex.debug_level = value
- end
-
- # Whether or not debug mode is enabled, see #debug_level=.
- def debug?
- @debug_level > 0
- end
-
- def evaluate(line, line_no) # :nodoc:
+ def evaluate(line, line_no, exception: nil) # :nodoc:
@line_no = line_no
+ if exception
+ line_no -= 1
+ line = "begin ::Kernel.raise _; rescue _.class\n#{line}\n""end"
+ @workspace.local_variable_set(:_, exception)
+ end
set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
end
diff --git a/lib/irb/easter-egg.rb b/lib/irb/easter-egg.rb
new file mode 100644
index 0000000000..3e79692de9
--- /dev/null
+++ b/lib/irb/easter-egg.rb
@@ -0,0 +1,138 @@
+require "reline"
+
+module IRB
+ class << self
+ class Vec
+ def initialize(x, y, z)
+ @x, @y, @z = x, y, z
+ end
+
+ attr_reader :x, :y, :z
+
+ def sub(other)
+ Vec.new(@x - other.x, @y - other.y, @z - other.z)
+ end
+
+ def dot(other)
+ @x*other.x + @y*other.y + @z*other.z
+ end
+
+ def cross(other)
+ ox, oy, oz = other.x, other.y, other.z
+ Vec.new(@y*oz-@z*oy, @z*ox-@x*oz, @x*oy-@y*ox)
+ end
+
+ def normalize
+ r = Math.sqrt(self.dot(self))
+ Vec.new(@x / r, @y / r, @z / r)
+ end
+ end
+
+ class Canvas
+ def initialize((h, w))
+ @data = (0..h-2).map { [0] * w }
+ @scale = [w / 2.0, h-2].min
+ @center = Complex(w / 2, h-2)
+ end
+
+ def line((x1, y1), (x2, y2))
+ p1 = Complex(x1, y1) / 2 * @scale + @center
+ p2 = Complex(x2, y2) / 2 * @scale + @center
+ line0(p1, p2)
+ end
+
+ private def line0(p1, p2)
+ mid = (p1 + p2) / 2
+ if (p1 - p2).abs < 1
+ x, y = mid.rect
+ @data[y / 2][x] |= (y % 2 > 1 ? 2 : 1)
+ else
+ line0(p1, mid)
+ line0(p2, mid)
+ end
+ end
+
+ def draw
+ @data.each {|row| row.fill(0) }
+ yield
+ @data.map {|row| row.map {|n| " ',;"[n] }.join }.join("\n")
+ end
+ end
+
+ class RubyModel
+ def initialize
+ @faces = init_ruby_model
+ end
+
+ def init_ruby_model
+ cap_vertices = (0..5).map {|i| Vec.new(*Complex.polar(1, i * Math::PI / 3).rect, 1) }
+ middle_vertices = (0..5).map {|i| Vec.new(*Complex.polar(2, (i + 0.5) * Math::PI / 3).rect, 0) }
+ bottom_vertex = Vec.new(0, 0, -2)
+
+ faces = [cap_vertices]
+ 6.times do |j|
+ i = j-1
+ faces << [cap_vertices[i], middle_vertices[i], cap_vertices[j]]
+ faces << [cap_vertices[j], middle_vertices[i], middle_vertices[j]]
+ faces << [middle_vertices[i], bottom_vertex, middle_vertices[j]]
+ end
+
+ faces
+ end
+
+ def render_frame(i)
+ angle = i / 10.0
+ dir = Vec.new(*Complex.polar(1, angle).rect, Math.sin(angle)).normalize
+ dir2 = Vec.new(*Complex.polar(1, angle - Math::PI/2).rect, 0)
+ up = dir.cross(dir2)
+ nm = dir.cross(up)
+ @faces.each do |vertices|
+ v0, v1, v2, = vertices
+ if v1.sub(v0).cross(v2.sub(v0)).dot(dir) > 0
+ points = vertices.map {|p| [nm.dot(p), up.dot(p)] }
+ (points + [points[0]]).each_cons(2) do |p1, p2|
+ yield p1, p2
+ end
+ end
+ end
+ end
+ end
+
+ private def easter_egg(type = nil)
+ type ||= [:logo, :dancing].sample
+ case type
+ when :logo
+ File.open(File.join(__dir__, 'ruby_logo.aa')) do |f|
+ require "rdoc"
+ RDoc::RI::Driver.new.page do |io|
+ IO.copy_stream(f, io)
+ end
+ end
+ when :dancing
+ begin
+ canvas = Canvas.new(Reline.get_screen_size)
+ Reline::IOGate.set_winch_handler do
+ canvas = Canvas.new(Reline.get_screen_size)
+ end
+ ruby_model = RubyModel.new
+ print "\e[?1049h"
+ 0.step do |i| # TODO (0..).each needs Ruby 2.6 or later
+ buff = canvas.draw do
+ ruby_model.render_frame(i) do |p1, p2|
+ canvas.line(p1, p2)
+ end
+ end
+ buff[0, 20] = "\e[0mPress Ctrl+C to stop\e[31m\e[1m"
+ print "\e[H" + buff
+ sleep 0.05
+ end
+ rescue Interrupt
+ ensure
+ print "\e[0m\e[?1049l"
+ end
+ end
+ end
+ end
+end
+
+IRB.__send__(:easter_egg, ARGV[0]&.to_sym) if $0 == __FILE__
diff --git a/lib/irb/ext/change-ws.rb b/lib/irb/ext/change-ws.rb
index 94bfe62bc0..4c57e44eab 100644
--- a/lib/irb/ext/change-ws.rb
+++ b/lib/irb/ext/change-ws.rb
@@ -43,4 +43,3 @@ module IRB # :nodoc:
end
end
end
-
diff --git a/lib/irb/ext/history.rb b/lib/irb/ext/history.rb
index 62363b13f4..fc304c6f6c 100644
--- a/lib/irb/ext/history.rb
+++ b/lib/irb/ext/history.rb
@@ -22,7 +22,7 @@ module IRB # :nodoc:
def set_last_value(value)
_set_last_value(value)
- if @eval_history
+ if defined?(@eval_history) && @eval_history
@eval_history_values.push @line_no, @last_value
@workspace.evaluate self, "__ = IRB.CurrentContext.instance_eval{@eval_history_values}"
end
@@ -30,9 +30,13 @@ module IRB # :nodoc:
@last_value
end
- # The command result history limit.
+ remove_method :eval_history= if method_defined?(:eval_history=)
+ # The command result history limit. This method is not available until
+ # #eval_history= was called with non-nil value (directly or via
+ # setting <code>IRB.conf[:EVAL_HISTORY]</code> in <code>.irbrc</code>).
attr_reader :eval_history
- # Sets command result history limit.
+ # Sets command result history limit. Default value is set from
+ # <code>IRB.conf[:EVAL_HISTORY]</code>.
#
# +no+ is an Integer or +nil+.
#
@@ -41,6 +45,9 @@ module IRB # :nodoc:
# If +no+ is 0, the number of history items is unlimited.
#
# If +no+ is +nil+, execution result history isn't used (default).
+ #
+ # History values are available via <code>__</code> variable, see
+ # IRB::History.
def eval_history=(no)
if no
if defined?(@eval_history) && @eval_history
@@ -58,20 +65,51 @@ module IRB # :nodoc:
end
end
- class History # :nodoc:
-
- def initialize(size = 16)
+ # Represents history of results of previously evaluated commands.
+ #
+ # Available via <code>__</code> variable, only if <code>IRB.conf[:EVAL_HISTORY]</code>
+ # or <code>IRB::CurrentContext().eval_history</code> is non-nil integer value
+ # (by default it is +nil+).
+ #
+ # Example (in `irb`):
+ #
+ # # Initialize history
+ # IRB::CurrentContext().eval_history = 10
+ # # => 10
+ #
+ # # Perform some commands...
+ # 1 + 2
+ # # => 3
+ # puts 'x'
+ # # x
+ # # => nil
+ # raise RuntimeError
+ # # ...error raised
+ #
+ # # Inspect history (format is "<item number> <evaluated value>":
+ # __
+ # # => 1 10
+ # # 2 3
+ # # 3 nil
+ #
+ # __[1]
+ # # => 10
+ #
+ class History
+
+ def initialize(size = 16) # :nodoc:
@size = size
@contents = []
end
- def size(size)
+ def size(size) # :nodoc:
if size != 0 && size < @size
@contents = @contents[@size - size .. @size]
end
@size = size
end
+ # Get one item of the content (both positive and negative indexes work).
def [](idx)
begin
if idx >= 0
@@ -84,14 +122,14 @@ module IRB # :nodoc:
end
end
- def push(no, val)
+ def push(no, val) # :nodoc:
@contents.push [no, val]
@contents.shift if @size != 0 && @contents.size > @size
end
alias real_inspect inspect
- def inspect
+ def inspect # :nodoc:
if @contents.empty?
return real_inspect
end
@@ -115,5 +153,3 @@ module IRB # :nodoc:
end
end
end
-
-
diff --git a/lib/irb/ext/loader.rb b/lib/irb/ext/loader.rb
index 840226db30..af028996e7 100644
--- a/lib/irb/ext/loader.rb
+++ b/lib/irb/ext/loader.rb
@@ -31,8 +31,31 @@ module IRB # :nodoc:
load_file(path, priv)
end
+ if File.respond_to?(:absolute_path?)
+ def absolute_path?(path)
+ File.absolute_path?(path)
+ end
+ else
+ separator =
+ if File::ALT_SEPARATOR
+ "[#{Regexp.quote(File::SEPARATOR + File::ALT_SEPARATOR)}]"
+ else
+ File::SEPARATOR
+ end
+ ABSOLUTE_PATH_PATTERN = # :nodoc:
+ case Dir.pwd
+ when /\A\w:/, /\A#{separator}{2}/
+ /\A(?:\w:|#{separator})#{separator}/
+ else
+ /\A#{separator}/
+ end
+ def absolute_path?(path)
+ ABSOLUTE_PATH_PATTERN =~ path
+ end
+ end
+
def search_file_from_ruby_path(fn) # :nodoc:
- if /^#{Regexp.quote(File::Separator)}/ =~ fn
+ if absolute_path?(fn)
return fn if File.exist?(fn)
return nil
end
@@ -50,16 +73,18 @@ module IRB # :nodoc:
# See Irb#suspend_input_method for more information.
def source_file(path)
irb.suspend_name(path, File.basename(path)) do
- irb.suspend_input_method(FileInputMethod.new(path)) do
- |back_io|
- irb.signal_status(:IN_LOAD) do
- if back_io.kind_of?(FileInputMethod)
- irb.eval_input
- else
- begin
+ FileInputMethod.open(path) do |io|
+ irb.suspend_input_method(io) do
+ |back_io|
+ irb.signal_status(:IN_LOAD) do
+ if back_io.kind_of?(FileInputMethod)
irb.eval_input
- rescue LoadAbort
- print "load abort!!\n"
+ else
+ begin
+ irb.eval_input
+ rescue LoadAbort
+ print "load abort!!\n"
+ end
end
end
end
@@ -79,16 +104,18 @@ module IRB # :nodoc:
ws = WorkSpace.new
end
irb.suspend_workspace(ws) do
- irb.suspend_input_method(FileInputMethod.new(path)) do
- |back_io|
- irb.signal_status(:IN_LOAD) do
- if back_io.kind_of?(FileInputMethod)
- irb.eval_input
- else
- begin
+ FileInputMethod.open(path) do |io|
+ irb.suspend_input_method(io) do
+ |back_io|
+ irb.signal_status(:IN_LOAD) do
+ if back_io.kind_of?(FileInputMethod)
irb.eval_input
- rescue LoadAbort
- print "load abort!!\n"
+ else
+ begin
+ irb.eval_input
+ rescue LoadAbort
+ print "load abort!!\n"
+ end
end
end
end
@@ -126,4 +153,3 @@ module IRB # :nodoc:
end
end
end
-
diff --git a/lib/irb/ext/multi-irb.rb b/lib/irb/ext/multi-irb.rb
index 28d6fba832..74de1ecde5 100644
--- a/lib/irb/ext/multi-irb.rb
+++ b/lib/irb/ext/multi-irb.rb
@@ -9,7 +9,7 @@
#
#
#
-IRB.fail CantShiftToMultiIrbMode unless defined?(Thread)
+fail CantShiftToMultiIrbMode unless defined?(Thread)
module IRB
class JobManager
@@ -67,8 +67,8 @@ module IRB
# exception is raised.
def switch(key)
th, irb = search(key)
- IRB.fail IrbAlreadyDead unless th.alive?
- IRB.fail IrbSwitchedToCurrentThread if th == Thread.current
+ fail IrbAlreadyDead unless th.alive?
+ fail IrbSwitchedToCurrentThread if th == Thread.current
@current_job = irb
th.run
Thread.stop
@@ -84,7 +84,7 @@ module IRB
def kill(*keys)
for key in keys
th, _ = search(key)
- IRB.fail IrbAlreadyDead unless th.alive?
+ fail IrbAlreadyDead unless th.alive?
th.exit
end
end
@@ -114,7 +114,7 @@ module IRB
else
@jobs.find{|k, v| v.context.main.equal?(key)}
end
- IRB.fail NoSuchJob, key if job.nil?
+ fail NoSuchJob, key if job.nil?
job
end
@@ -122,7 +122,7 @@ module IRB
def delete(key)
case key
when Integer
- IRB.fail NoSuchJob, key unless @jobs[key]
+ fail NoSuchJob, key unless @jobs[key]
@jobs[key] = nil
else
catch(:EXISTS) do
@@ -135,7 +135,7 @@ module IRB
throw :EXISTS
end
end
- IRB.fail NoSuchJob, key
+ fail NoSuchJob, key
end
end
until assoc = @jobs.pop; end unless @jobs.empty?
diff --git a/lib/irb/ext/save-history.rb b/lib/irb/ext/save-history.rb
index ab64cf543d..7acaebe36a 100644
--- a/lib/irb/ext/save-history.rb
+++ b/lib/irb/ext/save-history.rb
@@ -9,8 +9,6 @@
#
#
-require "readline"
-
module IRB
module HistorySavingAbility # :nodoc:
end
@@ -27,7 +25,7 @@ module IRB
IRB.conf[:SAVE_HISTORY]
end
- remove_method :save_history= if respond_to?(:save_history=)
+ remove_method(:save_history=) if method_defined?(:save_history=)
# Sets <code>IRB.conf[:SAVE_HISTORY]</code> to the given +val+ and calls
# #init_save_history with this context.
#
@@ -58,8 +56,6 @@ module IRB
end
module HistorySavingAbility # :nodoc:
- include Readline
-
def HistorySavingAbility.extended(obj)
IRB.conf[:AT_EXIT].push proc{obj.save_history}
obj.load_history
@@ -67,19 +63,33 @@ module IRB
end
def load_history
+ return unless self.class.const_defined?(:HISTORY)
+ history = self.class::HISTORY
if history_file = IRB.conf[:HISTORY_FILE]
history_file = File.expand_path(history_file)
end
history_file = IRB.rc_file("_history") unless history_file
if File.exist?(history_file)
- open(history_file) do |f|
- f.each {|l| HISTORY << l.chomp}
+ open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
+ f.each { |l|
+ l = l.chomp
+ if self.class == ReidlineInputMethod and history.last&.end_with?("\\")
+ history.last.delete_suffix!("\\")
+ history.last << "\n" << l
+ else
+ history << l
+ end
+ }
end
+ @loaded_history_lines = history.size
+ @loaded_history_mtime = File.mtime(history_file)
end
end
def save_history
- if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
+ return unless self.class.const_defined?(:HISTORY)
+ history = self.class::HISTORY
+ if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) != 0
if history_file = IRB.conf[:HISTORY_FILE]
history_file = File.expand_path(history_file)
end
@@ -91,13 +101,28 @@ module IRB
File.chmod(0600, history_file)
end
rescue Errno::ENOENT
+ rescue Errno::EPERM
+ return
rescue
raise
end
- open(history_file, 'w', 0600 ) do |f|
- hist = HISTORY.to_a
- f.puts(hist[-num..-1] || hist)
+ if File.exist?(history_file) && @loaded_history_mtime &&
+ File.mtime(history_file) != @loaded_history_mtime
+ history = history[@loaded_history_lines..-1]
+ append_history = true
+ end
+
+ open(history_file, "#{append_history ? 'a' : 'w'}:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
+ hist = history.map{ |l| l.split("\n").join("\\\n") }
+ unless append_history
+ begin
+ hist = hist.last(num) if hist.size > num and num > 0
+ rescue RangeError # bignum too big to convert into `long'
+ # Do nothing because the bignum should be treated as inifinity
+ end
+ end
+ f.puts(hist)
end
end
end
diff --git a/lib/irb/ext/tracer.rb b/lib/irb/ext/tracer.rb
index 200f77e341..67ac4bb965 100644
--- a/lib/irb/ext/tracer.rb
+++ b/lib/irb/ext/tracer.rb
@@ -9,7 +9,20 @@
#
#
#
-require "tracer"
+begin
+ require "tracer"
+rescue LoadError
+ $stderr.puts "Tracer extension of IRB is enabled but tracer gem doesn't found."
+ module IRB
+ TracerLoadError = true
+ class Context
+ def use_tracer=(opt)
+ # do nothing
+ end
+ end
+ end
+ return # This is about to disable loading below
+end
module IRB
@@ -69,4 +82,3 @@ module IRB
IRB.initialize_tracer
end
-
diff --git a/lib/irb/ext/use-loader.rb b/lib/irb/ext/use-loader.rb
index 571dd25d17..1897bc89e0 100644
--- a/lib/irb/ext/use-loader.rb
+++ b/lib/irb/ext/use-loader.rb
@@ -10,8 +10,8 @@
#
#
-require "irb/cmd/load"
-require "irb/ext/loader"
+require_relative "../cmd/load"
+require_relative "loader"
class Object
alias __original__load__IRB_use_loader__ load
@@ -20,10 +20,12 @@ end
module IRB
module ExtendCommandBundle
+ remove_method :irb_load if method_defined?(:irb_load)
# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
def irb_load(*opts, &b)
ExtendCommand::Load.execute(irb_context, *opts, &b)
end
+ remove_method :irb_require if method_defined?(:irb_require)
# Loads the given file similarly to Kernel#require
def irb_require(*opts, &b)
ExtendCommand::Require.execute(irb_context, *opts, &b)
@@ -44,7 +46,8 @@ module IRB
alias use_loader? use_loader
- # Sets IRB.conf[:USE_LOADER]
+ remove_method :use_loader= if method_defined?(:use_loader=)
+ # Sets <code>IRB.conf[:USE_LOADER]</code>
#
# See #use_loader for more information.
def use_loader=(opt)
@@ -70,5 +73,3 @@ module IRB
end
end
end
-
-
diff --git a/lib/irb/ext/workspaces.rb b/lib/irb/ext/workspaces.rb
index 5bd72c194f..730b58e64d 100644
--- a/lib/irb/ext/workspaces.rb
+++ b/lib/irb/ext/workspaces.rb
@@ -64,4 +64,3 @@ module IRB # :nodoc:
end
end
end
-
diff --git a/lib/irb/extend-command.rb b/lib/irb/extend-command.rb
index 064f21ba52..339e9e6084 100644
--- a/lib/irb/extend-command.rb
+++ b/lib/irb/extend-command.rb
@@ -32,7 +32,7 @@ module IRB # :nodoc:
# Displays current configuration.
#
- # Modifing the configuration is achieved by sending a message to IRB.conf.
+ # Modifying the configuration is achieved by sending a message to IRB.conf.
def irb_context
IRB.CurrentContext
end
@@ -46,58 +46,104 @@ module IRB # :nodoc:
]
@EXTEND_COMMANDS = [
- [:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
- [:irb_print_working_workspace, OVERRIDE_ALL],
- [:irb_cwws, OVERRIDE_ALL],
- [:irb_pwws, OVERRIDE_ALL],
- [:cwws, NO_OVERRIDE],
- [:pwws, NO_OVERRIDE],
- [:irb_current_working_binding, OVERRIDE_ALL],
- [:irb_print_working_binding, OVERRIDE_ALL],
- [:irb_cwb, OVERRIDE_ALL],
- [:irb_pwb, OVERRIDE_ALL],
- ],
- [:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
- [:irb_chws, OVERRIDE_ALL],
- [:irb_cws, OVERRIDE_ALL],
- [:chws, NO_OVERRIDE],
- [:cws, NO_OVERRIDE],
- [:irb_change_binding, OVERRIDE_ALL],
- [:irb_cb, OVERRIDE_ALL],
- [:cb, NO_OVERRIDE]],
-
- [:irb_workspaces, :Workspaces, "irb/cmd/pushws",
- [:workspaces, NO_OVERRIDE],
- [:irb_bindings, OVERRIDE_ALL],
- [:bindings, NO_OVERRIDE]],
- [:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
- [:irb_pushws, OVERRIDE_ALL],
- [:pushws, NO_OVERRIDE],
- [:irb_push_binding, OVERRIDE_ALL],
- [:irb_pushb, OVERRIDE_ALL],
- [:pushb, NO_OVERRIDE]],
- [:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
- [:irb_popws, OVERRIDE_ALL],
- [:popws, NO_OVERRIDE],
- [:irb_pop_binding, OVERRIDE_ALL],
- [:irb_popb, OVERRIDE_ALL],
- [:popb, NO_OVERRIDE]],
-
- [:irb_load, :Load, "irb/cmd/load"],
- [:irb_require, :Require, "irb/cmd/load"],
- [:irb_source, :Source, "irb/cmd/load",
- [:source, NO_OVERRIDE]],
-
- [:irb, :IrbCommand, "irb/cmd/subirb"],
- [:irb_jobs, :Jobs, "irb/cmd/subirb",
- [:jobs, NO_OVERRIDE]],
- [:irb_fg, :Foreground, "irb/cmd/subirb",
- [:fg, NO_OVERRIDE]],
- [:irb_kill, :Kill, "irb/cmd/subirb",
- [:kill, OVERRIDE_PRIVATE_ONLY]],
-
- [:irb_help, :Help, "irb/cmd/help",
- [:help, NO_OVERRIDE]],
+ [
+ :irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
+ [:irb_print_working_workspace, OVERRIDE_ALL],
+ [:irb_cwws, OVERRIDE_ALL],
+ [:irb_pwws, OVERRIDE_ALL],
+ [:cwws, NO_OVERRIDE],
+ [:pwws, NO_OVERRIDE],
+ [:irb_current_working_binding, OVERRIDE_ALL],
+ [:irb_print_working_binding, OVERRIDE_ALL],
+ [:irb_cwb, OVERRIDE_ALL],
+ [:irb_pwb, OVERRIDE_ALL],
+ ],
+ [
+ :irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
+ [:irb_chws, OVERRIDE_ALL],
+ [:irb_cws, OVERRIDE_ALL],
+ [:chws, NO_OVERRIDE],
+ [:cws, NO_OVERRIDE],
+ [:irb_change_binding, OVERRIDE_ALL],
+ [:irb_cb, OVERRIDE_ALL],
+ [:cb, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_workspaces, :Workspaces, "irb/cmd/pushws",
+ [:workspaces, NO_OVERRIDE],
+ [:irb_bindings, OVERRIDE_ALL],
+ [:bindings, NO_OVERRIDE],
+ ],
+ [
+ :irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
+ [:irb_pushws, OVERRIDE_ALL],
+ [:pushws, NO_OVERRIDE],
+ [:irb_push_binding, OVERRIDE_ALL],
+ [:irb_pushb, OVERRIDE_ALL],
+ [:pushb, NO_OVERRIDE],
+ ],
+ [
+ :irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
+ [:irb_popws, OVERRIDE_ALL],
+ [:popws, NO_OVERRIDE],
+ [:irb_pop_binding, OVERRIDE_ALL],
+ [:irb_popb, OVERRIDE_ALL],
+ [:popb, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_load, :Load, "irb/cmd/load"],
+ [
+ :irb_require, :Require, "irb/cmd/load"],
+ [
+ :irb_source, :Source, "irb/cmd/load",
+ [:source, NO_OVERRIDE],
+ ],
+
+ [
+ :irb, :IrbCommand, "irb/cmd/subirb"],
+ [
+ :irb_jobs, :Jobs, "irb/cmd/subirb",
+ [:jobs, NO_OVERRIDE],
+ ],
+ [
+ :irb_fg, :Foreground, "irb/cmd/subirb",
+ [:fg, NO_OVERRIDE],
+ ],
+ [
+ :irb_kill, :Kill, "irb/cmd/subirb",
+ [:kill, OVERRIDE_PRIVATE_ONLY],
+ ],
+
+ [
+ :irb_help, :Help, "irb/cmd/help",
+ [:help, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_info, :Info, "irb/cmd/info"
+ ],
+
+ [
+ :irb_ls, :Ls, "irb/cmd/ls",
+ [:ls, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_measure, :Measure, "irb/cmd/measure",
+ [:measure, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_show_source, :ShowSource, "irb/cmd/show_source",
+ [:show_source, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_whereami, :Whereami, "irb/cmd/whereami",
+ [:whereami, NO_OVERRIDE],
+ ],
]
@@ -138,20 +184,24 @@ module IRB # :nodoc:
end
if load_file
+ kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
line = __LINE__; eval %[
- def #{cmd_name}(*opts, &b)
+ def #{cmd_name}(*opts#{kwargs}, &b)
require "#{load_file}"
arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
- args << "*opts" if arity < 0
+ args << "*opts#{kwargs}" if arity < 0
args << "&block"
args = args.join(", ")
line = __LINE__; eval %[
- def #{cmd_name}(\#{args})
- ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
+ unless singleton_class.class_variable_defined?(:@@#{cmd_name}_)
+ singleton_class.class_variable_set(:@@#{cmd_name}_, true)
+ def self.#{cmd_name}_(\#{args})
+ ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
+ end
end
], nil, __FILE__, line
- send :#{cmd_name}, *opts, &b
+ __send__ :#{cmd_name}_, *opts#{kwargs}, &b
end
], nil, __FILE__, line
else
@@ -239,7 +289,7 @@ module IRB # :nodoc:
def #{cmd_name}(*opts, &b)
Context.module_eval {remove_method(:#{cmd_name})}
require "#{load_file}"
- send :#{cmd_name}, *opts, &b
+ __send__ :#{cmd_name}, *opts, &b
end
for ali in aliases
alias_method ali, cmd_name
@@ -262,8 +312,8 @@ module IRB # :nodoc:
module_eval %[
alias_method alias_name, base_method
def #{base_method}(*opts)
- send :#{extend_method}, *opts
- send :#{alias_name}, *opts
+ __send__ :#{extend_method}, *opts
+ __send__ :#{alias_name}, *opts
end
]
end
@@ -278,8 +328,8 @@ module IRB # :nodoc:
module_eval %[
alias_method alias_name, base_method
def #{base_method}(*opts)
- send :#{alias_name}, *opts
- send :#{extend_method}, *opts
+ __send__ :#{alias_name}, *opts
+ __send__ :#{extend_method}, *opts
end
]
end
diff --git a/lib/irb/frame.rb b/lib/irb/frame.rb
index 6073809249..de54a98f1b 100644
--- a/lib/irb/frame.rb
+++ b/lib/irb/frame.rb
@@ -10,13 +10,18 @@
#
#
-require "e2mmap"
-
module IRB
class Frame
- extend Exception2MessageMapper
- def_exception :FrameOverflow, "frame overflow"
- def_exception :FrameUnderflow, "frame underflow"
+ class FrameOverflow < StandardError
+ def initialize
+ super("frame overflow")
+ end
+ end
+ class FrameUnderflow < StandardError
+ def initialize
+ super("frame underflow")
+ end
+ end
# Default number of stack frames
INIT_STACK_TIMES = 3
@@ -44,7 +49,7 @@ module IRB
# Raises FrameUnderflow if there are no frames in the given stack range.
def top(n = 0)
bind = @frames[-(n + CALL_STACK_OFFSET)]
- Fail FrameUnderflow unless bind
+ fail FrameUnderflow unless bind
bind
end
@@ -54,7 +59,7 @@ module IRB
# Raises FrameOverflow if there are no frames in the given stack range.
def bottom(n = 0)
bind = @frames[n]
- Fail FrameOverflow unless bind
+ fail FrameOverflow unless bind
bind
end
diff --git a/lib/irb/help.rb b/lib/irb/help.rb
index a4264ab4ab..3eeaf841b0 100644
--- a/lib/irb/help.rb
+++ b/lib/irb/help.rb
@@ -10,7 +10,7 @@
#
#
-require 'irb/magic-file'
+require_relative 'magic-file'
module IRB
# Outputs the irb help message, see IRB@Command+line+options.
@@ -34,4 +34,3 @@ module IRB
}
end
end
-
diff --git a/lib/irb/init.rb b/lib/irb/init.rb
index 700466beda..78ef2fa3c1 100644
--- a/lib/irb/init.rb
+++ b/lib/irb/init.rb
@@ -13,15 +13,15 @@
module IRB # :nodoc:
# initialize config
- def IRB.setup(ap_path)
+ def IRB.setup(ap_path, argv: ::ARGV)
IRB.init_config(ap_path)
IRB.init_error
- IRB.parse_opts
+ IRB.parse_opts(argv: argv)
IRB.run_config
IRB.load_modules
unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
- IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE])
+ fail UndefinedPromptMode, @CONF[:PROMPT_MODE]
end
end
@@ -43,17 +43,19 @@ module IRB # :nodoc:
@CONF[:LOAD_MODULES] = []
@CONF[:IRB_RC] = nil
- @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod)
+ @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
+ @CONF[:USE_COLORIZE] = true
@CONF[:INSPECT_MODE] = true
@CONF[:USE_TRACER] = false
@CONF[:USE_LOADER] = false
@CONF[:IGNORE_SIGINT] = true
@CONF[:IGNORE_EOF] = false
@CONF[:ECHO] = nil
+ @CONF[:ECHO_ON_ASSIGNMENT] = nil
@CONF[:VERBOSE] = nil
@CONF[:EVAL_HISTORY] = nil
- @CONF[:SAVE_HISTORY] = nil
+ @CONF[:SAVE_HISTORY] = 1000
@CONF[:BACK_TRACE_LIMIT] = 16
@@ -82,7 +84,7 @@ module IRB # :nodoc:
:SIMPLE => {
:PROMPT_I => ">> ",
:PROMPT_N => ">> ",
- :PROMPT_S => nil,
+ :PROMPT_S => "%l> ",
:PROMPT_C => "?> ",
:RETURN => "=> %s\n"
},
@@ -104,16 +106,89 @@ module IRB # :nodoc:
}
@CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
- @CONF[:AUTO_INDENT] = false
+ @CONF[:AUTO_INDENT] = true
- @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
+ @CONF[:CONTEXT_MODE] = 4 # use a copy of TOPLEVEL_BINDING
@CONF[:SINGLE_IRB] = false
+ @CONF[:MEASURE] = false
+ @CONF[:MEASURE_PROC] = {}
+ @CONF[:MEASURE_PROC][:TIME] = proc { |context, code, line_no, &block|
+ time = Time.now
+ result = block.()
+ now = Time.now
+ puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE]
+ result
+ }
+ @CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, arg, &block|
+ success = false
+ begin
+ require 'stackprof'
+ success = true
+ rescue LoadError
+ puts 'Please run "gem install stackprof" before measuring by StackProf.'
+ end
+ if success
+ result = nil
+ stackprof_result = StackProf.run(mode: arg ? arg : :cpu) do
+ result = block.()
+ end
+ StackProf::Report.new(stackprof_result).print_text if IRB.conf[:MEASURE]
+ result
+ else
+ block.()
+ end
+ }
+ @CONF[:MEASURE_CALLBACKS] = []
+
@CONF[:LC_MESSAGES] = Locale.new
@CONF[:AT_EXIT] = []
+ end
+
+ def IRB.set_measure_callback(type = nil, arg = nil, &block)
+ added = nil
+ if type
+ type_sym = type.upcase.to_sym
+ if IRB.conf[:MEASURE_PROC][type_sym]
+ added = [type_sym, IRB.conf[:MEASURE_PROC][type_sym], arg]
+ end
+ elsif IRB.conf[:MEASURE_PROC][:CUSTOM]
+ added = [:CUSTOM, IRB.conf[:MEASURE_PROC][:CUSTOM], arg]
+ elsif block_given?
+ added = [:BLOCK, block, arg]
+ found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] }
+ if found
+ found[1] = block
+ return added
+ else
+ IRB.conf[:MEASURE_CALLBACKS] << added
+ return added
+ end
+ else
+ added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME], arg]
+ end
+ if added
+ found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] }
+ if found
+ # already added
+ nil
+ else
+ IRB.conf[:MEASURE_CALLBACKS] << added if added
+ added
+ end
+ else
+ nil
+ end
+ end
- @CONF[:DEBUG_LEVEL] = 0
+ def IRB.unset_measure_callback(type = nil)
+ if type.nil?
+ IRB.conf[:MEASURE_CALLBACKS].clear
+ else
+ type_sym = type.upcase.to_sym
+ IRB.conf[:MEASURE_CALLBACKS].reject!{ |t, | t == type_sym }
+ end
end
def IRB.init_error
@@ -121,9 +196,9 @@ module IRB # :nodoc:
end
# option analyzing
- def IRB.parse_opts
+ def IRB.parse_opts(argv: ::ARGV)
load_path = []
- while opt = ARGV.shift
+ while opt = argv.shift
case opt
when "-f"
@CONF[:RC] = false
@@ -131,50 +206,64 @@ module IRB # :nodoc:
$DEBUG = true
$VERBOSE = true
when "-w"
- $VERBOSE = true
+ Warning[:deprecated] = $VERBOSE = true
when /^-W(.+)?/
- opt = $1 || ARGV.shift
+ opt = $1 || argv.shift
case opt
when "0"
$VERBOSE = nil
when "1"
$VERBOSE = false
else
- $VERBOSE = true
+ Warning[:deprecated] = $VERBOSE = true
end
when /^-r(.+)?/
- opt = $1 || ARGV.shift
+ opt = $1 || argv.shift
@CONF[:LOAD_MODULES].push opt if opt
when /^-I(.+)?/
- opt = $1 || ARGV.shift
+ opt = $1 || argv.shift
load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
when '-U'
set_encoding("UTF-8", "UTF-8")
when /^-E(.+)?/, /^--encoding(?:=(.+))?/
- opt = $1 || ARGV.shift
+ opt = $1 || argv.shift
set_encoding(*opt.split(':', 2))
when "--inspect"
- if /^-/ !~ ARGV.first
- @CONF[:INSPECT_MODE] = ARGV.shift
+ if /^-/ !~ argv.first
+ @CONF[:INSPECT_MODE] = argv.shift
else
@CONF[:INSPECT_MODE] = true
end
when "--noinspect"
@CONF[:INSPECT_MODE] = false
- when "--readline"
- @CONF[:USE_READLINE] = true
- when "--noreadline"
- @CONF[:USE_READLINE] = false
+ when "--singleline", "--readline", "--legacy"
+ @CONF[:USE_SINGLELINE] = true
+ when "--nosingleline", "--noreadline"
+ @CONF[:USE_SINGLELINE] = false
+ when "--multiline", "--reidline"
+ @CONF[:USE_MULTILINE] = true
+ when "--nomultiline", "--noreidline"
+ @CONF[:USE_MULTILINE] = false
when "--echo"
@CONF[:ECHO] = true
when "--noecho"
@CONF[:ECHO] = false
+ when "--echo-on-assignment"
+ @CONF[:ECHO_ON_ASSIGNMENT] = true
+ when "--noecho-on-assignment"
+ @CONF[:ECHO_ON_ASSIGNMENT] = false
+ when "--truncate-echo-on-assignment"
+ @CONF[:ECHO_ON_ASSIGNMENT] = :truncate
when "--verbose"
@CONF[:VERBOSE] = true
when "--noverbose"
@CONF[:VERBOSE] = false
+ when "--colorize"
+ @CONF[:USE_COLORIZE] = true
+ when "--nocolorize"
+ @CONF[:USE_COLORIZE] = false
when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
- opt = $1 || ARGV.shift
+ opt = $1 || argv.shift
prompt_mode = opt.upcase.tr("-", "_").intern
@CONF[:PROMPT_MODE] = prompt_mode
when "--noprompt"
@@ -186,28 +275,26 @@ module IRB # :nodoc:
when "--tracer"
@CONF[:USE_TRACER] = true
when /^--back-trace-limit(?:=(.+))?/
- @CONF[:BACK_TRACE_LIMIT] = ($1 || ARGV.shift).to_i
+ @CONF[:BACK_TRACE_LIMIT] = ($1 || argv.shift).to_i
when /^--context-mode(?:=(.+))?/
- @CONF[:CONTEXT_MODE] = ($1 || ARGV.shift).to_i
+ @CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i
when "--single-irb"
@CONF[:SINGLE_IRB] = true
- when /^--irb_debug(?:=(.+))?/
- @CONF[:DEBUG_LEVEL] = ($1 || ARGV.shift).to_i
when "-v", "--version"
print IRB.version, "\n"
exit 0
when "-h", "--help"
- require "irb/help"
+ require_relative "help"
IRB.print_usage
exit 0
when "--"
- if opt = ARGV.shift
+ if opt = argv.shift
@CONF[:SCRIPT] = opt
$0 = opt
end
break
when /^-/
- IRB.fail UnrecognizedSwitch, opt
+ fail UnrecognizedSwitch, opt
else
@CONF[:SCRIPT] = opt
$0 = opt
@@ -252,7 +339,7 @@ module IRB # :nodoc:
when String
return rc_file
else
- IRB.fail IllegalRCNameGenerator
+ fail IllegalRCNameGenerator
end
end
@@ -261,14 +348,23 @@ module IRB # :nodoc:
if irbrc = ENV["IRBRC"]
yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
end
+ if xdg_config_home = ENV["XDG_CONFIG_HOME"]
+ irb_home = File.join(xdg_config_home, "irb")
+ unless File.exist? irb_home
+ require 'fileutils'
+ FileUtils.mkdir_p irb_home
+ end
+ yield proc{|rc| irb_home + "/irb#{rc}"}
+ end
if home = ENV["HOME"]
yield proc{|rc| home+"/.irb#{rc}"}
end
- home = Dir.pwd
- yield proc{|rc| home+"/.irb#{rc}"}
- yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"}
- yield proc{|rc| home+"/_irb#{rc}"}
- yield proc{|rc| home+"/$irb#{rc}"}
+ current_dir = Dir.pwd
+ yield proc{|rc| current_dir+"/.config/irb/irb#{rc}"}
+ yield proc{|rc| current_dir+"/.irb#{rc}"}
+ yield proc{|rc| current_dir+"/irb#{rc.sub(/\A_?/, '.')}"}
+ yield proc{|rc| current_dir+"/_irb#{rc}"}
+ yield proc{|rc| current_dir+"/$irb#{rc}"}
end
# loading modules
@@ -277,7 +373,7 @@ module IRB # :nodoc:
begin
require m
rescue LoadError => err
- warn err.backtrace[0] << ":#{err.class}: #{err}"
+ warn "#{err.class}: #{err}", uplevel: 0
end
end
end
@@ -286,15 +382,18 @@ module IRB # :nodoc:
DefaultEncodings = Struct.new(:external, :internal)
class << IRB
private
- def set_encoding(extern, intern = nil)
+ def set_encoding(extern, intern = nil, override: true)
verbose, $VERBOSE = $VERBOSE, nil
Encoding.default_external = extern unless extern.nil? || extern.empty?
Encoding.default_internal = intern unless intern.nil? || intern.empty?
- @CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern)
[$stdin, $stdout, $stderr].each do |io|
io.set_encoding(extern, intern)
end
- @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
+ if override
+ @CONF[:LC_MESSAGES].instance_variable_set(:@override_encoding, extern)
+ else
+ @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
+ end
ensure
$VERBOSE = verbose
end
diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb
index f7b1aac3bf..1854567a2d 100644
--- a/lib/irb/input-method.rb
+++ b/lib/irb/input-method.rb
@@ -9,8 +9,11 @@
#
#
#
-require 'irb/src_encoding'
-require 'irb/magic-file'
+require_relative 'src_encoding'
+require_relative 'magic-file'
+require_relative 'completion'
+require 'io/console'
+require 'reline'
module IRB
STDIN_FILE_NAME = "(line)" # :nodoc:
@@ -30,10 +33,18 @@ module IRB
#
# See IO#gets for more information.
def gets
- IRB.fail NotImplementedError, "gets"
+ fail NotImplementedError, "gets"
end
public :gets
+ def winsize
+ if instance_variable_defined?(:@stdout)
+ @stdout.winsize
+ else
+ [24, 80]
+ end
+ end
+
# Whether this input method is still readable when there is no more data to
# read.
#
@@ -41,6 +52,11 @@ module IRB
def readable_after_eof?
false
end
+
+ # For debug message
+ def inspect
+ 'Abstract InputMethod'
+ end
end
class StdioInputMethod < InputMethod
@@ -67,7 +83,15 @@ module IRB
#
# See IO#eof? for more information.
def eof?
- @stdin.eof?
+ rs, = IO.select([@stdin], [], [], 0.00001)
+ if rs and rs[0]
+ c = @stdin.getc
+ result = c.nil? ? true : false
+ @stdin.ungetc(c) unless c.nil?
+ result
+ else # buffer is empty
+ false
+ end
end
# Whether this input method is still readable when there is no more data to
@@ -91,14 +115,31 @@ module IRB
def encoding
@stdin.external_encoding
end
+
+ # For debug message
+ def inspect
+ 'StdioInputMethod'
+ end
end
# Use a File for IO with irb, see InputMethod
class FileInputMethod < InputMethod
+ class << self
+ def open(file, &block)
+ begin
+ io = new(file)
+ block.call(io)
+ ensure
+ io&.close
+ end
+ end
+ end
+
# Creates a new input method object
def initialize(file)
super
@io = IRB::MagicFile.open(file)
+ @external_encoding = @io.external_encoding
end
# The file name of this input method, usually given during initialization.
attr_reader :file_name
@@ -108,7 +149,7 @@ module IRB
#
# See IO#eof? for more information.
def eof?
- @io.eof?
+ @io.closed? || @io.eof?
end
# Reads the next line from this input method.
@@ -116,22 +157,39 @@ module IRB
# See IO#gets for more information.
def gets
print @prompt
- l = @io.gets
- l
+ @io.gets
end
# The external encoding for standard input.
def encoding
- @io.external_encoding
+ @external_encoding
+ end
+
+ # For debug message
+ def inspect
+ 'FileInputMethod'
+ end
+
+ def close
+ @io.close
end
end
begin
- require "readline"
class ReadlineInputMethod < InputMethod
- include Readline
+ def self.initialize_readline
+ require "readline"
+ rescue LoadError
+ else
+ include ::Readline
+ end
+
# Creates a new input method object using Readline
def initialize
+ self.class.initialize_readline
+ if Readline.respond_to?(:encoding_system_needs)
+ IRB.__send__(:set_encoding, Readline.encoding_system_needs.name, override: false)
+ end
super
@line_no = 0
@@ -140,6 +198,12 @@ module IRB
@stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
@stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+
+ if Readline.respond_to?("basic_word_break_characters=")
+ Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
+ end
+ Readline.completion_append_character = nil
+ Readline.completion_proc = IRB::InputCompletor::CompletionProc
end
# Reads the next line from this input method.
@@ -186,7 +250,122 @@ module IRB
def encoding
@stdin.external_encoding
end
+
+ # For debug message
+ def inspect
+ readline_impl = (defined?(Reline) && Readline == Reline) ? 'Reline' : 'ext/readline'
+ str = "ReadlineInputMethod with #{readline_impl} #{Readline::VERSION}"
+ inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
+ str += " and #{inputrc_path}" if File.exist?(inputrc_path)
+ str
+ end
+ end
+ end
+
+ class ReidlineInputMethod < InputMethod
+ include Reline
+ # Creates a new input method object using Readline
+ def initialize
+ IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false)
+ super
+
+ @line_no = 0
+ @line = []
+ @eof = false
+
+ @stdin = ::IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+ @stdout = ::IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+
+ if Reline.respond_to?("basic_word_break_characters=")
+ Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
+ end
+ Reline.completion_append_character = nil
+ Reline.completer_quote_characters = ''
+ Reline.completion_proc = IRB::InputCompletor::CompletionProc
+ Reline.output_modifier_proc =
+ if IRB.conf[:USE_COLORIZE]
+ proc do |output, complete: |
+ next unless IRB::Color.colorable?
+ IRB::Color.colorize_code(output, complete: complete)
+ end
+ else
+ proc do |output|
+ Reline::Unicode.escape_for_print(output)
+ end
+ end
+ Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
+ end
+
+ def check_termination(&block)
+ @check_termination_proc = block
+ end
+
+ def dynamic_prompt(&block)
+ @prompt_proc = block
+ end
+
+ def auto_indent(&block)
+ @auto_indent_proc = block
+ end
+
+ # Reads the next line from this input method.
+ #
+ # See IO#gets for more information.
+ def gets
+ Reline.input = @stdin
+ Reline.output = @stdout
+ Reline.prompt_proc = @prompt_proc
+ Reline.auto_indent_proc = @auto_indent_proc if @auto_indent_proc
+ if l = readmultiline(@prompt, false, &@check_termination_proc)
+ HISTORY.push(l) if !l.empty?
+ @line[@line_no += 1] = l + "\n"
+ else
+ @eof = true
+ l
+ end
+ end
+
+ # Whether the end of this input method has been reached, returns +true+
+ # if there is no more data to read.
+ #
+ # See IO#eof? for more information.
+ def eof?
+ @eof
+ end
+
+ # Whether this input method is still readable when there is no more data to
+ # read.
+ #
+ # See IO#eof for more information.
+ def readable_after_eof?
+ true
+ end
+
+ # Returns the current line number for #io.
+ #
+ # #line counts the number of times #gets is called.
+ #
+ # See IO#lineno for more information.
+ def line(line_no)
+ @line[line_no]
+ end
+
+ # The external encoding for standard input.
+ def encoding
+ @stdin.external_encoding
+ end
+
+ # For debug message
+ def inspect
+ config = Reline::Config.new
+ str = "ReidlineInputMethod with Reline #{Reline::VERSION}"
+ if config.respond_to?(:inputrc_path)
+ inputrc_path = File.expand_path(config.inputrc_path)
+ else
+ inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
+ end
+ str += " and #{inputrc_path}" if File.exist?(inputrc_path)
+ str
end
- rescue LoadError
end
end
diff --git a/lib/irb/inspector.rb b/lib/irb/inspector.rb
index f6f76712b8..c2f3b605db 100644
--- a/lib/irb/inspector.rb
+++ b/lib/irb/inspector.rb
@@ -100,18 +100,27 @@ module IRB # :nodoc:
# Proc to call when the input is evaluated and output in irb.
def inspect_value(v)
@inspect.call(v)
+ rescue
+ puts "(Object doesn't support #inspect)"
+ ''
end
end
Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
- Inspector.def_inspector([true, :p, :inspect]){|v|
- begin
- v.inspect
- rescue NoMethodError
- puts "(Object doesn't support #inspect)"
+ Inspector.def_inspector([:p, :inspect]){|v|
+ result = v.inspect
+ if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v)
+ result = Color.colorize_code(result)
+ end
+ result
+ }
+ Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require "irb/color_printer"}){|v|
+ if IRB.conf[:MAIN_CONTEXT]&.use_colorize?
+ IRB::ColorPrinter.pp(v, '').chomp
+ else
+ v.pretty_inspect.chomp
end
}
- Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v| v.pretty_inspect.chomp}
Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
begin
YAML.dump(v)
@@ -125,8 +134,3 @@ module IRB # :nodoc:
Marshal.dump(v)
}
end
-
-
-
-
-
diff --git a/lib/irb/irb.gemspec b/lib/irb/irb.gemspec
new file mode 100644
index 0000000000..38fee9d9fb
--- /dev/null
+++ b/lib/irb/irb.gemspec
@@ -0,0 +1,42 @@
+begin
+ require_relative "lib/irb/version"
+rescue LoadError
+ # for Ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "irb"
+ spec.version = IRB::VERSION
+ spec.authors = ["Keiju ISHITSUKA"]
+ spec.email = ["keiju@ruby-lang.org"]
+
+ spec.summary = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
+ spec.description = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
+ spec.homepage = "https://github.com/ruby/irb"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.files = [
+ ".document",
+ "Gemfile",
+ "LICENSE.txt",
+ "README.md",
+ "Rakefile",
+ "bin/console",
+ "bin/setup",
+ "doc/irb/irb-tools.rd.ja",
+ "doc/irb/irb.rd.ja",
+ "exe/irb",
+ "irb.gemspec",
+ "man/irb.1",
+ ] + Dir.glob("lib/**/*")
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
+
+ spec.add_dependency "reline", ">= 0.1.5"
+ spec.add_development_dependency "bundler"
+ spec.add_development_dependency "rake"
+end
diff --git a/lib/irb/lc/.document b/lib/irb/lc/.document
deleted file mode 100644
index 524bb9430b..0000000000
--- a/lib/irb/lc/.document
+++ /dev/null
@@ -1,4 +0,0 @@
-# hide help-message files which contain usage information
-error.rb
-ja/encoding_aliases.rb
-ja/error.rb
diff --git a/lib/irb/lc/error.rb b/lib/irb/lc/error.rb
index 6623f82d84..798994e92c 100644
--- a/lib/irb/lc/error.rb
+++ b/lib/irb/lc/error.rb
@@ -9,24 +9,63 @@
#
#
#
-require "e2mmap"
# :stopdoc:
module IRB
-
- # exceptions
- extend Exception2MessageMapper
- def_exception :UnrecognizedSwitch, "Unrecognized switch: %s"
- def_exception :NotImplementedError, "Need to define `%s'"
- def_exception :CantReturnToNormalMode, "Can't return to normal mode."
- def_exception :IllegalParameter, "Invalid parameter(%s)."
- def_exception :IrbAlreadyDead, "Irb is already dead."
- def_exception :IrbSwitchedToCurrentThread, "Switched to current thread."
- def_exception :NoSuchJob, "No such job(%s)."
- def_exception :CantShiftToMultiIrbMode, "Can't shift to multi irb mode."
- def_exception :CantChangeBinding, "Can't change binding to (%s)."
- def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)."
- def_exception :IllegalRCGenerator, 'Define illegal RC_NAME_GENERATOR.'
-
+ class UnrecognizedSwitch < StandardError
+ def initialize(val)
+ super("Unrecognized switch: #{val}")
+ end
+ end
+ class NotImplementedError < StandardError
+ def initialize(val)
+ super("Need to define `#{val}'")
+ end
+ end
+ class CantReturnToNormalMode < StandardError
+ def initialize
+ super("Can't return to normal mode.")
+ end
+ end
+ class IllegalParameter < StandardError
+ def initialize(val)
+ super("Invalid parameter(#{val}).")
+ end
+ end
+ class IrbAlreadyDead < StandardError
+ def initialize
+ super("Irb is already dead.")
+ end
+ end
+ class IrbSwitchedToCurrentThread < StandardError
+ def initialize
+ super("Switched to current thread.")
+ end
+ end
+ class NoSuchJob < StandardError
+ def initialize(val)
+ super("No such job(#{val}).")
+ end
+ end
+ class CantShiftToMultiIrbMode < StandardError
+ def initialize
+ super("Can't shift to multi irb mode.")
+ end
+ end
+ class CantChangeBinding < StandardError
+ def initialize(val)
+ super("Can't change binding to (#{val}).")
+ end
+ end
+ class UndefinedPromptMode < StandardError
+ def initialize(val)
+ super("Undefined prompt mode(#{val}).")
+ end
+ end
+ class IllegalRCGenerator < StandardError
+ def initialize
+ super("Define illegal RC_NAME_GENERATOR.")
+ end
+ end
end
# :startdoc:
diff --git a/lib/irb/lc/help-message b/lib/irb/lc/help-message
index d43c6a1695..9c3ea859ad 100644
--- a/lib/irb/lc/help-message
+++ b/lib/irb/lc/help-message
@@ -10,7 +10,7 @@
#
#
Usage: irb.rb [options] [programfile] [arguments]
- -f Suppress read of ~/.irbrc
+ -f Suppress read of ~/.irbrc
-d Set $DEBUG to true (same as `ruby -d')
-r load-module Same as `ruby -r'
-I path Specify $LOAD_PATH directory
@@ -18,28 +18,31 @@ Usage: irb.rb [options] [programfile] [arguments]
-E enc Same as `ruby -E`
-w Same as `ruby -w`
-W[level=2] Same as `ruby -W`
- --context-mode n Set n[0-3] to method to create Binding Object,
+ --context-mode n Set n[0-4] to method to create Binding Object,
when new workspace was created
--echo Show result(default)
--noecho Don't show result
- --inspect Use `inspect' for output (default except for bc mode)
- --noinspect Don't use inspect for output
- --readline Use Readline extension module
- --noreadline Don't use Readline extension module
+ --inspect Use `inspect' for output
+ --noinspect Don't use inspect for output
+ --multiline Use multiline editor module
+ --nomultiline Don't use multiline editor module
+ --singleline Use singleline editor module
+ --nosingleline Don't use singleline editor module
+ --colorize Use colorization
+ --nocolorize Don't use colorization
--prompt prompt-mode/--prompt-mode prompt-mode
- Switch prompt mode. Pre-defined prompt modes are
- `default', `simple', `xmp' and `inf-ruby'
+ Switch prompt mode. Pre-defined prompt modes are
+ `default', `simple', `xmp' and `inf-ruby'
--inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
- Suppresses --readline.
+ Suppresses --multiline and --singleline.
--sample-book-mode/--simple-prompt
Simple prompt mode
--noprompt No prompt mode
--single-irb Share self with sub-irb.
--tracer Display trace for each execution of commands.
--back-trace-limit n
- Display backtrace top n and tail n. The default
- value is 16.
- --irb_debug n Set internal debug level to n (not for popular use)
+ Display backtrace top n and tail n. The default
+ value is 16.
--verbose Show details
--noverbose Don't show details
-v, --version Print the version of irb
diff --git a/lib/irb/lc/ja/error.rb b/lib/irb/lc/ja/error.rb
index 919363154c..31ebb3b5f0 100644
--- a/lib/irb/lc/ja/error.rb
+++ b/lib/irb/lc/ja/error.rb
@@ -9,23 +9,64 @@
#
#
#
-require "e2mmap"
# :stopdoc:
module IRB
- # exceptions
- extend Exception2MessageMapper
- def_exception :UnrecognizedSwitch, 'スイッãƒ(%s)ãŒåˆ†ã‚Šã¾ã›ã‚“'
- def_exception :NotImplementedError, '`%s\'ã®å®šç¾©ãŒå¿…è¦ã§ã™'
- def_exception :CantReturnToNormalMode, 'Normalãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã‚Œã¾ã›ã‚“.'
- def_exception :IllegalParameter, 'パラメータ(%s)ãŒé–“é•ã£ã¦ã„ã¾ã™.'
- def_exception :IrbAlreadyDead, 'Irbã¯æ—¢ã«æ­»ã‚“ã§ã„ã¾ã™.'
- def_exception :IrbSwitchedToCurrentThread, 'カレントスレッドã«åˆ‡ã‚Šæ›¿ã‚りã¾ã—ãŸ.'
- def_exception :NoSuchJob, 'ãã®ã‚ˆã†ãªã‚¸ãƒ§ãƒ–(%s)ã¯ã‚りã¾ã›ã‚“.'
- def_exception :CantShiftToMultiIrbMode, 'multi-irb modeã«ç§»ã‚Œã¾ã›ã‚“.'
- def_exception :CantChangeBinding, 'ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°(%s)ã«å¤‰æ›´ã§ãã¾ã›ã‚“.'
- def_exception :UndefinedPromptMode, 'プロンプトモード(%s)ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“.'
- def_exception :IllegalRCNameGenerator, 'RC_NAME_GENERATORãŒæ­£ã—ã定義ã•れã¦ã„ã¾ã›ã‚“.'
+ class UnrecognizedSwitch < StandardError
+ def initialize(val)
+ super("スイッãƒ(#{val})ãŒåˆ†ã‚Šã¾ã›ã‚“")
+ end
+ end
+ class NotImplementedError < StandardError
+ def initialize(val)
+ super("`#{val}'ã®å®šç¾©ãŒå¿…è¦ã§ã™")
+ end
+ end
+ class CantReturnToNormalMode < StandardError
+ def initialize
+ super("Normalãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã‚Œã¾ã›ã‚“.")
+ end
+ end
+ class IllegalParameter < StandardError
+ def initialize(val)
+ super("パラメータ(#{val})ãŒé–“é•ã£ã¦ã„ã¾ã™.")
+ end
+ end
+ class IrbAlreadyDead < StandardError
+ def initialize
+ super("Irbã¯æ—¢ã«æ­»ã‚“ã§ã„ã¾ã™.")
+ end
+ end
+ class IrbSwitchedToCurrentThread < StandardError
+ def initialize
+ super("カレントスレッドã«åˆ‡ã‚Šæ›¿ã‚りã¾ã—ãŸ.")
+ end
+ end
+ class NoSuchJob < StandardError
+ def initialize(val)
+ super("ãã®ã‚ˆã†ãªã‚¸ãƒ§ãƒ–(#{val})ã¯ã‚りã¾ã›ã‚“.")
+ end
+ end
+ class CantShiftToMultiIrbMode < StandardError
+ def initialize
+ super("multi-irb modeã«ç§»ã‚Œã¾ã›ã‚“.")
+ end
+ end
+ class CantChangeBinding < StandardError
+ def initialize(val)
+ super("ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°(#{val})ã«å¤‰æ›´ã§ãã¾ã›ã‚“.")
+ end
+ end
+ class UndefinedPromptMode < StandardError
+ def initialize(val)
+ super("プロンプトモード(#{val})ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“.")
+ end
+ end
+ class IllegalRCGenerator < StandardError
+ def initialize
+ super("RC_NAME_GENERATORãŒæ­£ã—ã定義ã•れã¦ã„ã¾ã›ã‚“.")
+ end
+ end
end
# :startdoc:
# vim:fileencoding=utf-8
diff --git a/lib/irb/lc/ja/help-message b/lib/irb/lc/ja/help-message
index 1b24d14d28..9794a8e24e 100644
--- a/lib/irb/lc/ja/help-message
+++ b/lib/irb/lc/ja/help-message
@@ -21,16 +21,21 @@ Usage: irb.rb [options] [programfile] [arguments]
オブジェクトã®ä½œæˆæ–¹æ³•ã‚’ 0 ã‹ã‚‰ 3 ã®ã„ãšã‚Œã‹ã«è¨­å®šã™ã‚‹.
--echo å®Ÿè¡Œçµæžœã‚’表示ã™ã‚‹(デフォルト).
--noecho å®Ÿè¡Œçµæžœã‚’表示ã—ãªã„.
- --inspect çµæžœå‡ºåŠ›ã«inspectを用ã„ã‚‹(bcモード以外ã¯ãƒ‡ãƒ•ォルト).
+ --inspect çµæžœå‡ºåŠ›ã«inspectを用ã„ã‚‹.
--noinspect çµæžœå‡ºåŠ›ã«inspectを用ã„ãªã„.
- --readline readlineライブラリを利用ã™ã‚‹.
- --noreadline readlineライブラリを利用ã—ãªã„.
+ --multiline マルãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’利用ã™ã‚‹.
+ --nomultiline マルãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’利用ã—ãªã„.
+ --singleline シングルラインエディタを利用ã™ã‚‹.
+ --nosingleline シングルラインエディタを利用ã—ãªã„.
+ --colorize 色付ã‘を利用ã™ã‚‹.
+ --nocolorize 色付ã‘を利用ã—ãªã„.
--prompt prompt-mode/--prompt-mode prompt-mode
プロンプトモードを切替ãˆã¾ã™. ç¾åœ¨å®šç¾©ã•れã¦ã„るプ
ロンプトモードã¯, default, simple, xmp, inf-rubyãŒ
用æ„ã•れã¦ã„ã¾ã™.
--inf-ruby-mode emacsã®inf-ruby-mode用ã®ãƒ—ロンプト表示を行ãªã†. 特
- ã«æŒ‡å®šãŒãªã„é™ã‚Š, readlineライブラリã¯ä½¿ã‚ãªããªã‚‹.
+ ã«æŒ‡å®šãŒãªã„é™ã‚Š, シングルラインエディタã¨ãƒžãƒ«ãƒãƒ©
+ インエディタã¯ä½¿ã‚ãªããªã‚‹.
--sample-book-mode/--simple-prompt
éžå¸¸ã«ã‚·ãƒ³ãƒ—ルãªãƒ—ロンプトを用ã„るモードã§ã™.
--noprompt プロンプト表示を行ãªã‚ãªã„.
@@ -41,8 +46,6 @@ Usage: irb.rb [options] [programfile] [arguments]
ãƒãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹è¡¨ç¤ºã‚’ãƒãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹ã®é ­ã‹ã‚‰ n, 後ã‚
ã‹ã‚‰nã ã‘行ãªã†. デフォルトã¯16
- --irb_debug n irbã®ãƒ‡ãƒãƒƒã‚°ãƒ¬ãƒ™ãƒ«ã‚’nã«è¨­å®šã™ã‚‹(éžæŽ¨å¥¨).
-
--verbose 詳細ãªãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’出力ã™ã‚‹.
--noverbose 詳細ãªãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’出力ã—ãªã„(デフォルト).
-v, --version irbã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã™ã‚‹.
diff --git a/lib/irb/locale.rb b/lib/irb/locale.rb
index df540c8cbb..bb44b41002 100644
--- a/lib/irb/locale.rb
+++ b/lib/irb/locale.rb
@@ -21,8 +21,10 @@ module IRB # :nodoc:
LOCALE_DIR = "/lc/"
@@legacy_encoding_alias_map = {}.freeze
+ @@loaded = []
def initialize(locale = nil)
+ @override_encoding = nil
@lang = @territory = @encoding_name = @modifier = nil
@locale = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] || "C"
if m = LOCALE_NAME_RE.match(@locale)
@@ -31,7 +33,7 @@ module IRB # :nodoc:
if @encoding_name
begin load 'irb/encoding_aliases.rb'; rescue LoadError; end
if @encoding = @@legacy_encoding_alias_map[@encoding_name]
- warn "%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]
+ warn(("%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]), uplevel: 1)
end
@encoding = Encoding.find(@encoding_name) rescue nil
end
@@ -39,12 +41,16 @@ module IRB # :nodoc:
@encoding ||= (Encoding.find('locale') rescue Encoding::ASCII_8BIT)
end
- attr_reader :lang, :territory, :encoding, :modifier
+ attr_reader :lang, :territory, :modifier
+
+ def encoding
+ @override_encoding || @encoding
+ end
def String(mes)
mes = super(mes)
- if @encoding
- mes.encode(@encoding, undef: :replace)
+ if encoding
+ mes.encode(encoding, undef: :replace)
else
mes
end
@@ -107,7 +113,10 @@ module IRB # :nodoc:
def load(file, priv=nil)
found = find(file)
if found
- return real_load(found, priv)
+ unless @@loaded.include?(found)
+ @@loaded << found # cache
+ return real_load(found, priv)
+ end
else
raise LoadError, "No such file to load -- #{file}"
end
diff --git a/lib/irb/notifier.rb b/lib/irb/notifier.rb
index a21e865f2e..d0e413dd68 100644
--- a/lib/irb/notifier.rb
+++ b/lib/irb/notifier.rb
@@ -10,17 +10,21 @@
#
#
-require "e2mmap"
-require "irb/output-method"
+require_relative "output-method"
module IRB
# An output formatter used internally by the lexer.
module Notifier
- extend Exception2MessageMapper
- def_exception :ErrUndefinedNotifier,
- "undefined notifier level: %d is specified"
- def_exception :ErrUnrecognizedLevel,
- "unrecognized notifier level: %s is specified"
+ class ErrUndefinedNotifier < StandardError
+ def initialize(val)
+ super("undefined notifier level: #{val} is specified")
+ end
+ end
+ class ErrUnrecognizedLevel < StandardError
+ def initialize(val)
+ super("unrecognized notifier level: #{val} is specified")
+ end
+ end
# Define a new Notifier output source, returning a new CompositeNotifier
# with the given +prefix+ and +output_method+.
@@ -162,10 +166,10 @@ module IRB
@level_notifier = value
when Integer
l = @notifiers[value]
- Notifier.Raise ErrUndefinedNotifier, value unless l
+ raise ErrUndefinedNotifier, value unless l
@level_notifier = l
else
- Notifier.Raise ErrUnrecognizedLevel, value unless l
+ raise ErrUnrecognizedLevel, value unless l
end
end
diff --git a/lib/irb/output-method.rb b/lib/irb/output-method.rb
index 935a127d0a..3fda708cb0 100644
--- a/lib/irb/output-method.rb
+++ b/lib/irb/output-method.rb
@@ -10,21 +10,21 @@
#
#
-require "e2mmap"
-
module IRB
# An abstract output class for IO in irb. This is mainly used internally by
# IRB::Notifier. You can define your own output method to use with Irb.new,
# or Context.new
class OutputMethod
- extend Exception2MessageMapper
- def_exception :NotImplementedError, "Need to define `%s'"
-
+ class NotImplementedError < StandardError
+ def initialize(val)
+ super("Need to define `#{val}'")
+ end
+ end
# Open this method to implement your own output method, raises a
# NotImplementedError if you don't define #print in your own class.
def print(*opts)
- OutputMethod.Raise NotImplementedError, "print"
+ raise NotImplementedError, "print"
end
# Prints the given +opts+, with a newline delimiter.
diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb
index fb7e08099f..82df06da2b 100644
--- a/lib/irb/ruby-lex.rb
+++ b/lib/irb/ruby-lex.rb
@@ -10,74 +10,98 @@
#
#
-require "e2mmap"
-require "irb/slex"
-require "irb/ruby-token"
+require "ripper"
+require "jruby" if RUBY_ENGINE == "jruby"
# :stopdoc:
class RubyLex
- extend Exception2MessageMapper
- def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
- def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
- def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
- def_exception(:TkReading2TokenDuplicateError,
- "key duplicate(token_n='%s', key='%s')")
- def_exception(:SyntaxError, "%s")
-
- def_exception(:TerminateLineInput, "Terminate Line Input")
-
- include RubyToken
-
- class << self
- attr_accessor :debug_level
- def debug?
- @debug_level > 0
+ class TerminateLineInput < StandardError
+ def initialize
+ super("Terminate Line Input")
end
end
- @debug_level = 0
def initialize
- lex_init
- set_input(STDIN)
-
- @seek = 0
@exp_line_no = @line_no = 1
- @base_char_no = 0
- @char_no = 0
- @rests = []
- @readed = []
- @here_readed = []
-
@indent = 0
- @indent_stack = []
- @lex_state = EXPR_BEG
- @space_seen = false
- @here_header = false
- @post_symbeg = false
-
@continue = false
@line = ""
-
- @skip_space = false
- @readed_auto_clean_up = false
- @exception_on_syntax_error = true
-
@prompt = nil
end
- attr_accessor :skip_space
- attr_accessor :readed_auto_clean_up
- attr_accessor :exception_on_syntax_error
-
- attr_reader :seek
- attr_reader :char_no
- attr_reader :line_no
- attr_reader :indent
+ def self.compile_with_errors_suppressed(code)
+ line_no = 1
+ begin
+ result = yield code, line_no
+ rescue ArgumentError
+ code = ";\n#{code}"
+ line_no = 0
+ result = yield code, line_no
+ end
+ result
+ end
# io functions
def set_input(io, p = nil, &block)
@io = io
+ if @io.respond_to?(:check_termination)
+ @io.check_termination do |code|
+ if Reline::IOGate.in_pasting?
+ lex = RubyLex.new
+ rest = lex.check_termination_in_prev_line(code)
+ if rest
+ Reline.delete_text
+ rest.bytes.reverse_each do |c|
+ Reline.ungetc(c)
+ end
+ true
+ else
+ false
+ end
+ else
+ code.gsub!(/\s*\z/, '').concat("\n")
+ ltype, indent, continue, code_block_open = check_state(code)
+ if ltype or indent > 0 or continue or code_block_open
+ false
+ else
+ true
+ end
+ end
+ end
+ end
+ if @io.respond_to?(:dynamic_prompt)
+ @io.dynamic_prompt do |lines|
+ lines << '' if lines.empty?
+ result = []
+ tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
+ code = String.new
+ partial_tokens = []
+ unprocessed_tokens = []
+ line_num_offset = 0
+ tokens.each do |t|
+ partial_tokens << t
+ unprocessed_tokens << t
+ if t[2].include?("\n")
+ t_str = t[2]
+ t_str.each_line("\n") do |s|
+ code << s << "\n"
+ ltype, indent, continue, code_block_open = check_state(code, partial_tokens)
+ result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
+ line_num_offset += 1
+ end
+ unprocessed_tokens = []
+ else
+ code << t[2]
+ end
+ end
+ unless unprocessed_tokens.empty?
+ ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens)
+ result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
+ end
+ result
+ end
+ end
if p.respond_to?(:call)
@input = p
elsif block_given?
@@ -87,119 +111,105 @@ class RubyLex
end
end
- def get_readed
- if idx = @readed.rindex("\n")
- @base_char_no = @readed.size - (idx + 1)
- else
- @base_char_no += @readed.size
- end
-
- readed = @readed.join("")
- @readed = []
- readed
- end
-
- def getc
- while @rests.empty?
- @rests.push nil unless buf_input
- end
- c = @rests.shift
- if @here_header
- @here_readed.push c
- else
- @readed.push c
- end
- @seek += 1
- if c == "\n"
- @line_no += 1
- @char_no = 0
+ def set_prompt(p = nil, &block)
+ p = block if block_given?
+ if p.respond_to?(:call)
+ @prompt = p
else
- @char_no += 1
- end
- c
- end
-
- def gets
- l = ""
- while c = getc
- l.concat(c)
- break if c == "\n"
+ @prompt = Proc.new{print p}
end
- return nil if l == "" and c.nil?
- l
end
- def eof?
- @io.eof?
- end
-
- def getc_of_rests
- if @rests.empty?
- nil
- else
- getc
- end
- end
+ ERROR_TOKENS = [
+ :on_parse_error,
+ :compile_error,
+ :on_assign_error,
+ :on_alias_error,
+ :on_class_name_error,
+ :on_param_error
+ ]
- def ungetc(c = nil)
- if @here_readed.empty?
- c2 = @readed.pop
- else
- c2 = @here_readed.pop
- end
- c = c2 unless c
- @rests.unshift c #c =
- @seek -= 1
- if c == "\n"
- @line_no -= 1
- if idx = @readed.rindex("\n")
- @char_no = idx + 1
+ def self.ripper_lex_without_warning(code)
+ verbose, $VERBOSE = $VERBOSE, nil
+ tokens = nil
+ compile_with_errors_suppressed(code) do |inner_code, line_no|
+ lexer = Ripper::Lexer.new(inner_code, '-', line_no)
+ if lexer.respond_to?(:scan) # Ruby 2.7+
+ tokens = []
+ pos_to_index = {}
+ lexer.scan.each do |t|
+ if pos_to_index.has_key?(t[0])
+ index = pos_to_index[t[0]]
+ found_tk = tokens[index]
+ if ERROR_TOKENS.include?(found_tk[1]) && !ERROR_TOKENS.include?(t[1])
+ tokens[index] = t
+ end
+ else
+ pos_to_index[t[0]] = tokens.size
+ tokens << t
+ end
+ end
else
- @char_no = @base_char_no + @readed.size
+ tokens = lexer.parse
end
- else
- @char_no -= 1
end
+ tokens
+ ensure
+ $VERBOSE = verbose
end
- def peek_equal?(str)
- chrs = str.split(//)
- until @rests.size >= chrs.size
- return false unless buf_input
- end
- @rests[0, chrs.size] == chrs
- end
-
- def peek_match?(regexp)
- while @rests.empty?
- return false unless buf_input
+ def find_prev_spaces(line_index)
+ return 0 if @tokens.size == 0
+ md = @tokens[0][2].match(/(\A +)/)
+ prev_spaces = md.nil? ? 0 : md[1].count(' ')
+ line_count = 0
+ @tokens.each_with_index do |t, i|
+ if t[2].include?("\n")
+ line_count += t[2].count("\n")
+ if line_count >= line_index
+ return prev_spaces
+ end
+ if (@tokens.size - 1) > i
+ md = @tokens[i + 1][2].match(/(\A +)/)
+ prev_spaces = md.nil? ? 0 : md[1].count(' ')
+ end
+ end
end
- regexp =~ @rests.join("")
+ prev_spaces
end
- def peek(i = 0)
- while @rests.size <= i
- return nil unless buf_input
+ def set_auto_indent(context)
+ if @io.respond_to?(:auto_indent) and context.auto_indent_mode
+ @io.auto_indent do |lines, line_index, byte_pointer, is_newline|
+ if is_newline
+ @tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"))
+ prev_spaces = find_prev_spaces(line_index)
+ depth_difference = check_newline_depth_difference
+ depth_difference = 0 if depth_difference < 0
+ prev_spaces + depth_difference * 2
+ else
+ code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
+ last_line = lines[line_index]&.byteslice(0, byte_pointer)
+ code += last_line if last_line
+ @tokens = self.class.ripper_lex_without_warning(code)
+ corresponding_token_depth = check_corresponding_token_depth
+ if corresponding_token_depth
+ corresponding_token_depth
+ else
+ nil
+ end
+ end
+ end
end
- @rests[i]
end
- def buf_input
- prompt
- line = @input.call
- return nil unless line
- @rests.concat line.chars.to_a
- true
- end
- private :buf_input
-
- def set_prompt(p = nil, &block)
- p = block if block_given?
- if p.respond_to?(:call)
- @prompt = p
- else
- @prompt = Proc.new{print p}
- end
+ def check_state(code, tokens = nil)
+ tokens = self.class.ripper_lex_without_warning(code) unless tokens
+ ltype = process_literal_type(tokens)
+ indent = process_nesting_level(tokens)
+ continue = process_continue(tokens)
+ code_block_open = check_code_block(code, tokens)
+ [ltype, indent, continue, code_block_open]
end
def prompt
@@ -210,20 +220,11 @@ class RubyLex
def initialize_input
@ltype = nil
- @quoted = nil
@indent = 0
- @indent_stack = []
- @lex_state = EXPR_BEG
- @space_seen = false
- @here_header = false
-
@continue = false
- @post_symbeg = false
-
- prompt
-
@line = ""
@exp_line_no = @line_no
+ @code_block_open = false
end
def each_top_level_statement
@@ -231,13 +232,17 @@ class RubyLex
catch(:TERM_INPUT) do
loop do
begin
- @continue = false
prompt
unless l = lex
throw :TERM_INPUT if @line == ''
else
+ @line_no += l.count("\n")
+ if l == "\n"
+ @exp_line_no += 1
+ next
+ end
@line.concat l
- if @ltype or @continue or @indent > 0
+ if @code_block_open or @ltype or @continue or @indent > 0
next
end
end
@@ -245,936 +250,553 @@ class RubyLex
@line.force_encoding(@io.encoding)
yield @line, @exp_line_no
end
- break unless l
+ raise TerminateLineInput if @io.eof?
@line = ''
@exp_line_no = @line_no
@indent = 0
- @indent_stack = []
- prompt
rescue TerminateLineInput
initialize_input
prompt
- get_readed
end
end
end
end
def lex
- continue = @continue
- while tk = token
- case tk
- when TkNL, TkEND_OF_SCRIPT
- @continue = continue unless continue.nil?
- break unless @continue
- when TkSPACE, TkCOMMENT
- when TkSEMICOLON, TkBEGIN, TkELSE
- @continue = continue = false
- else
- continue = nil
- end
- end
- line = get_readed
- if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?
- nil
- else
- line
- end
+ line = @input.call
+ if @io.respond_to?(:check_termination)
+ return line # multiline
+ end
+ code = @line + (line.nil? ? '' : line)
+ code.gsub!(/\s*\z/, '').concat("\n")
+ @tokens = self.class.ripper_lex_without_warning(code)
+ @continue = process_continue
+ @code_block_open = check_code_block(code)
+ @indent = process_nesting_level
+ @ltype = process_literal_type
+ line
end
- def token
- @prev_seek = @seek
- @prev_line_no = @line_no
- @prev_char_no = @char_no
- begin
- begin
- tk = @OP.match(self)
- @space_seen = tk.kind_of?(TkSPACE)
- @lex_state = EXPR_END if @post_symbeg && tk.kind_of?(TkOp)
- @post_symbeg = tk.kind_of?(TkSYMBEG)
- rescue SyntaxError
- raise if @exception_on_syntax_error
- tk = TkError.new(@seek, @line_no, @char_no)
- end
- end while @skip_space and tk.kind_of?(TkSPACE)
- if @readed_auto_clean_up
- get_readed
- end
- tk
+ def process_continue(tokens = @tokens)
+ # last token is always newline
+ if tokens.size >= 2 and tokens[-2][1] == :on_regexp_end
+ # end of regexp literal
+ return false
+ elsif tokens.size >= 2 and tokens[-2][1] == :on_semicolon
+ return false
+ elsif tokens.size >= 2 and tokens[-2][1] == :on_kw and ['begin', 'else', 'ensure'].include?(tokens[-2][2])
+ return false
+ elsif !tokens.empty? and tokens.last[2] == "\\\n"
+ return true
+ elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
+ return false
+ elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2][2] !~ /\A\.\.\.?\z/
+ # end of literal except for regexp
+ # endless range at end of line is not a continue
+ return true
+ end
+ false
end
- ENINDENT_CLAUSE = [
- "case", "class", "def", "do", "for", "if",
- "module", "unless", "until", "while", "begin"
- ]
- DEINDENT_CLAUSE = ["end"
- ]
-
- PERCENT_LTYPE = {
- "q" => "\'",
- "Q" => "\"",
- "x" => "\`",
- "r" => "/",
- "w" => "]",
- "W" => "]",
- "i" => "]",
- "I" => "]",
- "s" => ":"
- }
-
- PERCENT_PAREN = {
- "{" => "}",
- "[" => "]",
- "<" => ">",
- "(" => ")"
- }
-
- Ltype2Token = {
- "\'" => TkSTRING,
- "\"" => TkSTRING,
- "\`" => TkXSTRING,
- "/" => TkREGEXP,
- "]" => TkDSTRING,
- ":" => TkSYMBOL
- }
- DLtype2Token = {
- "\"" => TkDSTRING,
- "\`" => TkDXSTRING,
- "/" => TkDREGEXP,
- }
-
- def lex_init()
- @OP = IRB::SLex.new
- @OP.def_rules("\0", "\004", "\032") do |op, io|
- Token(TkEND_OF_SCRIPT)
- end
-
- @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |op, io|
- @space_seen = true
- while getc =~ /[ \t\f\r\13]/; end
- ungetc
- Token(TkSPACE)
- end
-
- @OP.def_rule("#") do |op, io|
- identify_comment
- end
-
- @OP.def_rule("=begin",
- proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do
- |op, io|
- @ltype = "="
- until getc == "\n"; end
- until peek_equal?("=end") && peek(4) =~ /\s/
- until getc == "\n"; end
- end
- gets
- @ltype = nil
- Token(TkRD_COMMENT)
+ def check_code_block(code, tokens = @tokens)
+ return true if tokens.empty?
+ if tokens.last[1] == :on_heredoc_beg
+ return true
end
- @OP.def_rule("\n") do |op, io|
- print "\\n\n" if RubyLex.debug?
- case @lex_state
- when EXPR_BEG, EXPR_FNAME, EXPR_DOT
- @continue = true
- else
- @continue = false
- @lex_state = EXPR_BEG
- until (@indent_stack.empty? ||
- [TkLPAREN, TkLBRACK, TkLBRACE,
- TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
- @indent_stack.pop
+ begin # check if parser error are available
+ verbose, $VERBOSE = $VERBOSE, nil
+ case RUBY_ENGINE
+ when 'ruby'
+ self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
+ RubyVM::InstructionSequence.compile(inner_code, nil, nil, line_no)
end
- end
- @here_header = false
- @here_readed = []
- Token(TkNL)
- end
-
- @OP.def_rules("*", "**",
- "=", "==", "===",
- "=~", "<=>",
- "<", "<=",
- ">", ">=", ">>",
- "!", "!=", "!~") do
- |op, io|
- case @lex_state
- when EXPR_FNAME, EXPR_DOT
- @lex_state = EXPR_ARG
+ when 'jruby'
+ JRuby.compile_ir(code)
else
- @lex_state = EXPR_BEG
- end
- Token(op)
- end
-
- @OP.def_rules("<<") do
- |op, io|
- tk = nil
- if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
- (@lex_state != EXPR_ARG || @space_seen)
- c = peek(0)
- if /[-~"'`\w]/ =~ c
- tk = identify_here_document
+ catch(:valid) do
+ eval("BEGIN { throw :valid, true }\n#{code}")
+ false
end
end
- unless tk
- tk = Token(op)
- case @lex_state
- when EXPR_FNAME, EXPR_DOT
- @lex_state = EXPR_ARG
- else
- @lex_state = EXPR_BEG
- end
+ rescue EncodingError
+ # This is for a hash with invalid encoding symbol, {"\xAE": 1}
+ rescue SyntaxError => e
+ case e.message
+ when /unterminated (?:string|regexp) meets end of file/
+ # "unterminated regexp meets end of file"
+ #
+ # example:
+ # /
+ #
+ # "unterminated string meets end of file"
+ #
+ # example:
+ # '
+ return true
+ when /syntax error, unexpected end-of-input/
+ # "syntax error, unexpected end-of-input, expecting keyword_end"
+ #
+ # example:
+ # if ture
+ # hoge
+ # if false
+ # fuga
+ # end
+ return true
+ when /syntax error, unexpected keyword_end/
+ # "syntax error, unexpected keyword_end"
+ #
+ # example:
+ # if (
+ # end
+ #
+ # example:
+ # end
+ return false
+ when /syntax error, unexpected '\.'/
+ # "syntax error, unexpected '.'"
+ #
+ # example:
+ # .
+ return false
+ when /unexpected tREGEXP_BEG/
+ # "syntax error, unexpected tREGEXP_BEG, expecting keyword_do or '{' or '('"
+ #
+ # example:
+ # method / f /
+ return false
end
- tk
- end
-
- @OP.def_rules("'", '"') do
- |op, io|
- identify_string(op)
+ ensure
+ $VERBOSE = verbose
end
- @OP.def_rules("`") do
- |op, io|
- if @lex_state == EXPR_FNAME
- @lex_state = EXPR_END
- Token(op)
- else
- identify_string(op)
+ if defined?(Ripper::EXPR_BEG)
+ last_lex_state = tokens.last[3]
+ if last_lex_state.allbits?(Ripper::EXPR_BEG)
+ return false
+ elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_CLASS)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_FNAME)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_VALUE)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_ARG)
+ return false
end
end
- @OP.def_rules('?') do
- |op, io|
- if @lex_state == EXPR_END
- @lex_state = EXPR_BEG
- Token(TkQUESTION)
+ false
+ end
+
+ def process_nesting_level(tokens = @tokens)
+ indent = 0
+ in_oneliner_def = nil
+ tokens.each_with_index { |t, index|
+ # detecting one-liner method definition
+ if in_oneliner_def.nil?
+ if t[3].allbits?(Ripper::EXPR_ENDFN)
+ in_oneliner_def = :ENDFN
+ end
else
- ch = getc
- if @lex_state == EXPR_ARG && ch =~ /\s/
- ungetc
- @lex_state = EXPR_BEG;
- Token(TkQUESTION)
+ if t[3].allbits?(Ripper::EXPR_ENDFN)
+ # continuing
+ elsif t[3].allbits?(Ripper::EXPR_BEG)
+ if t[2] == '='
+ in_oneliner_def = :BODY
+ end
else
- if (ch == '\\')
- read_escape
+ if in_oneliner_def == :BODY
+ # one-liner method definition
+ indent -= 1
end
- @lex_state = EXPR_END
- Token(TkINTEGER)
+ in_oneliner_def = nil
end
end
- end
-
- @OP.def_rules("&", "&&", "|", "||") do
- |op, io|
- @lex_state = EXPR_BEG
- Token(op)
- end
-
- @OP.def_rules("+=", "-=", "*=", "**=",
- "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
- |op, io|
- @lex_state = EXPR_BEG
- op =~ /^(.*)=$/
- Token(TkOPASGN, $1)
- end
-
- @OP.def_rule("+@", proc{|op, io| @lex_state == EXPR_FNAME}) do
- |op, io|
- @lex_state = EXPR_ARG
- Token(op)
- end
- @OP.def_rule("-@", proc{|op, io| @lex_state == EXPR_FNAME}) do
- |op, io|
- @lex_state = EXPR_ARG
- Token(op)
- end
-
- @OP.def_rules("+", "-") do
- |op, io|
- catch(:RET) do
- if @lex_state == EXPR_ARG
- if @space_seen and peek(0) =~ /[0-9]/
- throw :RET, identify_number
- else
- @lex_state = EXPR_BEG
- end
- elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/
- throw :RET, identify_number
- else
- @lex_state = EXPR_BEG
+ case t[1]
+ when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
+ indent += 1
+ when :on_rbracket, :on_rbrace, :on_rparen
+ indent -= 1
+ when :on_kw
+ next if index > 0 and tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
+ case t[2]
+ when 'do'
+ syntax_of_do = take_corresponding_syntax_to_kw_do(tokens, index)
+ indent += 1 if syntax_of_do == :method_calling
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
+ indent += 1
+ when 'if', 'unless', 'while', 'until'
+ # postfix if/unless/while/until must be Ripper::EXPR_LABEL
+ indent += 1 unless t[3].allbits?(Ripper::EXPR_LABEL)
+ when 'end'
+ indent -= 1
end
- Token(op)
end
- end
-
- @OP.def_rule(".") do
- |op, io|
- @lex_state = EXPR_BEG
- if peek(0) =~ /[0-9]/
- ungetc
- identify_number
- else
- # for "obj.if" etc.
- @lex_state = EXPR_DOT
- Token(TkDOT)
- end
- end
-
- @OP.def_rules("..", "...") do
- |op, io|
- @lex_state = EXPR_BEG
- Token(op)
- end
-
- lex_int2
+ # percent literals are not indented
+ }
+ indent
end
- def lex_int2
- @OP.def_rules("]", "}", ")") do
- |op, io|
- @lex_state = EXPR_END
- @indent -= 1
- @indent_stack.pop
- Token(op)
- end
-
- @OP.def_rule(":") do
- |op, io|
- if @lex_state == EXPR_END || peek(0) =~ /\s/
- @lex_state = EXPR_BEG
- Token(TkCOLON)
- else
- @lex_state = EXPR_FNAME
- Token(TkSYMBEG)
- end
- end
-
- @OP.def_rule("::") do
- |op, io|
- if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen
- @lex_state = EXPR_BEG
- Token(TkCOLON3)
- else
- @lex_state = EXPR_DOT
- Token(TkCOLON2)
- end
- end
-
- @OP.def_rule("/") do
- |op, io|
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
- identify_string(op)
- elsif peek(0) == '='
- getc
- @lex_state = EXPR_BEG
- Token(TkOPASGN, "/") #/)
- elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
- identify_string(op)
- else
- @lex_state = EXPR_BEG
- Token("/") #/)
- end
- end
-
- @OP.def_rules("^") do
- |op, io|
- @lex_state = EXPR_BEG
- Token("^")
- end
-
- @OP.def_rules(",") do
- |op, io|
- @lex_state = EXPR_BEG
- Token(op)
- end
-
- @OP.def_rules(";") do
- |op, io|
- @lex_state = EXPR_BEG
- until (@indent_stack.empty? ||
- [TkLPAREN, TkLBRACK, TkLBRACE,
- TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
- @indent_stack.pop
- end
- Token(op)
- end
-
- @OP.def_rule("~") do
- |op, io|
- @lex_state = EXPR_BEG
- Token("~")
- end
-
- @OP.def_rule("~@", proc{|op, io| @lex_state == EXPR_FNAME}) do
- |op, io|
- @lex_state = EXPR_BEG
- Token("~")
- end
-
- @OP.def_rule("(") do
- |op, io|
- @indent += 1
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
- @lex_state = EXPR_BEG
- tk_c = TkfLPAREN
- else
- @lex_state = EXPR_BEG
- tk_c = TkLPAREN
- end
- @indent_stack.push tk_c
- Token(tk_c)
- end
-
- @OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do
- |op, io|
- @lex_state = EXPR_ARG
- Token("[]")
- end
-
- @OP.def_rule("[]=", proc{|op, io| @lex_state == EXPR_FNAME}) do
- |op, io|
- @lex_state = EXPR_ARG
- Token("[]=")
- end
-
- @OP.def_rule("[") do
- |op, io|
- @indent += 1
- if @lex_state == EXPR_FNAME
- tk_c = TkfLBRACK
- else
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
- tk_c = TkLBRACK
- elsif @lex_state == EXPR_ARG && @space_seen
- tk_c = TkLBRACK
- else
- tk_c = TkfLBRACK
+ def is_method_calling?(tokens, index)
+ tk = tokens[index]
+ if tk[3].anybits?(Ripper::EXPR_CMDARG) and tk[1] == :on_ident
+ # The target method call to pass the block with "do".
+ return true
+ elsif tk[3].anybits?(Ripper::EXPR_ARG) and tk[1] == :on_ident
+ non_sp_index = tokens[0..(index - 1)].rindex{ |t| t[1] != :on_sp }
+ if non_sp_index
+ prev_tk = tokens[non_sp_index]
+ if prev_tk[3].anybits?(Ripper::EXPR_DOT) and prev_tk[1] == :on_period
+ # The target method call with receiver to pass the block with "do".
+ return true
end
- @lex_state = EXPR_BEG
- end
- @indent_stack.push tk_c
- Token(tk_c)
- end
-
- @OP.def_rule("{") do
- |op, io|
- @indent += 1
- if @lex_state != EXPR_END && @lex_state != EXPR_ARG
- tk_c = TkLBRACE
- else
- tk_c = TkfLBRACE
- end
- @lex_state = EXPR_BEG
- @indent_stack.push tk_c
- Token(tk_c)
- end
-
- @OP.def_rule('\\') do
- |op, io|
- if getc == "\n"
- @space_seen = true
- @continue = true
- Token(TkSPACE)
- else
- read_escape
- Token("\\")
- end
- end
-
- @OP.def_rule('%') do
- |op, io|
- if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
- identify_quotation
- elsif peek(0) == '='
- getc
- Token(TkOPASGN, :%)
- elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
- identify_quotation
- else
- @lex_state = EXPR_BEG
- Token("%") #))
- end
- end
-
- @OP.def_rule('$') do
- |op, io|
- identify_gvar
- end
-
- @OP.def_rule('@') do
- |op, io|
- if peek(0) =~ /[\w@]/
- ungetc
- identify_identifier
- else
- Token("@")
- end
- end
-
- @OP.def_rule("") do
- |op, io|
- printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug?
- if peek(0) =~ /[0-9]/
- t = identify_number
- elsif peek(0) =~ /[^\x00-\/:-@\[-^`{-\x7F]/
- t = identify_identifier
end
- printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
- t
end
-
- p @OP if RubyLex.debug?
+ false
end
- def identify_gvar
- @lex_state = EXPR_END
-
- case ch = getc
- when /[~_*$?!@\/\\;,=:<>".]/ #"
- Token(TkGVAR, "$" + ch)
- when "-"
- Token(TkGVAR, "$-" + getc)
- when "&", "`", "'", "+"
- Token(TkBACK_REF, "$"+ch)
- when /[1-9]/
- while getc =~ /[0-9]/; end
- ungetc
- Token(TkNTH_REF)
- when /\w/
- ungetc
- ungetc
- identify_identifier
- else
- ungetc
- Token("$")
- end
+ def take_corresponding_syntax_to_kw_do(tokens, index)
+ syntax_of_do = nil
+ # Finding a syntax correnponding to "do".
+ index.downto(0) do |i|
+ tk = tokens[i]
+ # In "continue", the token isn't the corresponding syntax to "do".
+ non_sp_index = tokens[0..(i - 1)].rindex{ |t| t[1] != :on_sp }
+ first_in_fomula = false
+ if non_sp_index.nil?
+ first_in_fomula = true
+ elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index][1])
+ first_in_fomula = true
+ end
+ if is_method_calling?(tokens, i)
+ syntax_of_do = :method_calling
+ break if first_in_fomula
+ elsif tk[1] == :on_kw && %w{while until for}.include?(tk[2])
+ # A loop syntax in front of "do" found.
+ #
+ # while cond do # also "until" or "for"
+ # end
+ #
+ # This "do" doesn't increment indent because the loop syntax already
+ # incremented.
+ syntax_of_do = :loop_syntax
+ break if first_in_fomula
+ end
+ end
+ syntax_of_do
end
- def identify_identifier
- token = ""
- if peek(0) =~ /[$@]/
- token.concat(c = getc)
- if c == "@" and peek(0) == "@"
- token.concat getc
- end
- end
-
- while (ch = getc) =~ /[^\x00-\/:-@\[-^`{-\x7F]/
- print ":", ch, ":" if RubyLex.debug?
- token.concat ch
- end
- ungetc
-
- if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "="
- token.concat getc
- end
-
- # almost fix token
-
- case token
- when /^\$/
- return Token(TkGVAR, token)
- when /^\@\@/
- @lex_state = EXPR_END
- # p Token(TkCVAR, token)
- return Token(TkCVAR, token)
- when /^\@/
- @lex_state = EXPR_END
- return Token(TkIVAR, token)
- end
-
- if @lex_state != EXPR_DOT
- print token, "\n" if RubyLex.debug?
-
- token_c, *trans = TkReading2Token[token]
- if token_c
- # reserved word?
+ def is_the_in_correspond_to_a_for(tokens, index)
+ syntax_of_in = nil
+ # Finding a syntax correnponding to "do".
+ index.downto(0) do |i|
+ tk = tokens[i]
+ # In "continue", the token isn't the corresponding syntax to "do".
+ non_sp_index = tokens[0..(i - 1)].rindex{ |t| t[1] != :on_sp }
+ first_in_fomula = false
+ if non_sp_index.nil?
+ first_in_fomula = true
+ elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index][1])
+ first_in_fomula = true
+ end
+ if tk[1] == :on_kw && tk[2] == 'for'
+ # A loop syntax in front of "do" found.
+ #
+ # while cond do # also "until" or "for"
+ # end
+ #
+ # This "do" doesn't increment indent because the loop syntax already
+ # incremented.
+ syntax_of_in = :for
+ end
+ break if first_in_fomula
+ end
+ syntax_of_in
+ end
- if (@lex_state != EXPR_BEG &&
- @lex_state != EXPR_FNAME &&
- trans[1])
- # modifiers
- token_c = TkSymbol2Token[trans[1]]
- @lex_state = trans[0]
+ def check_newline_depth_difference
+ depth_difference = 0
+ open_brace_on_line = 0
+ in_oneliner_def = nil
+ @tokens.each_with_index do |t, index|
+ # detecting one-liner method definition
+ if in_oneliner_def.nil?
+ if t[3].allbits?(Ripper::EXPR_ENDFN)
+ in_oneliner_def = :ENDFN
+ end
+ else
+ if t[3].allbits?(Ripper::EXPR_ENDFN)
+ # continuing
+ elsif t[3].allbits?(Ripper::EXPR_BEG)
+ if t[2] == '='
+ in_oneliner_def = :BODY
+ end
else
- if @lex_state != EXPR_FNAME and peek(0) != ':'
- if ENINDENT_CLAUSE.include?(token)
- # check for ``class = val'' etc.
- valid = true
- case token
- when "class"
- valid = false unless peek_match?(/^\s*(<<|\w|::)/)
- when "def"
- valid = false if peek_match?(/^\s*(([+\-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/)
- when "do"
- valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&)/)
- when *ENINDENT_CLAUSE
- valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&|\|)/)
- else
- # no nothing
- end
- if valid
- if token == "do"
- if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last)
- @indent += 1
- @indent_stack.push token_c
- end
- else
- @indent += 1
- @indent_stack.push token_c
- end
- end
-
- elsif DEINDENT_CLAUSE.include?(token)
- @indent -= 1
- @indent_stack.pop
- end
- @lex_state = trans[0]
- else
- @lex_state = EXPR_END
+ if in_oneliner_def == :BODY
+ # one-liner method definition
+ depth_difference -= 1
end
+ in_oneliner_def = nil
end
- return Token(token_c, token)
end
- end
- if @lex_state == EXPR_FNAME
- @lex_state = EXPR_END
- if peek(0) == '='
- token.concat getc
- end
- elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT
- @lex_state = EXPR_ARG
- else
- @lex_state = EXPR_END
- end
-
- if token[0, 1] =~ /[A-Z]/
- return Token(TkCONSTANT, token)
- elsif token[token.size - 1, 1] =~ /[!?]/
- return Token(TkFID, token)
- else
- return Token(TkIDENTIFIER, token)
- end
- end
-
- def identify_here_document
- ch = getc
- if ch == "-" || ch == "~"
- ch = getc
- indent = true
- end
- if /['"`]/ =~ ch
- lt = ch
- quoted = ""
- while (c = getc) && c != lt
- quoted.concat c
- end
- else
- lt = '"'
- quoted = ch.dup
- while (c = getc) && c =~ /\w/
- quoted.concat c
- end
- ungetc
- end
-
- ltback, @ltype = @ltype, lt
- reserve = []
- while ch = getc
- reserve.push ch
- if ch == "\\"
- reserve.push ch = getc
- elsif ch == "\n"
- break
- end
- end
-
- @here_header = false
-
- line = ""
- while ch = getc
- if ch == "\n"
- if line == quoted
- break
+ case t[1]
+ when :on_ignored_nl, :on_nl, :on_comment
+ if index != (@tokens.size - 1) and in_oneliner_def != :BODY
+ depth_difference = 0
+ open_brace_on_line = 0
end
- line = ""
- else
- line.concat ch unless indent && line == "" && /\s/ =~ ch
- if @ltype != "'" && ch == "#" && peek(0) == "{"
- identify_string_dvar
+ next
+ when :on_sp
+ next
+ end
+ case t[1]
+ when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
+ depth_difference += 1
+ open_brace_on_line += 1
+ when :on_rbracket, :on_rbrace, :on_rparen
+ depth_difference -= 1 if open_brace_on_line > 0
+ when :on_kw
+ next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
+ case t[2]
+ when 'do'
+ syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
+ depth_difference += 1 if syntax_of_do == :method_calling
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
+ depth_difference += 1
+ when 'if', 'unless', 'while', 'until', 'rescue'
+ # postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL
+ unless t[3].allbits?(Ripper::EXPR_LABEL)
+ depth_difference += 1
+ end
+ when 'else', 'elsif', 'ensure', 'when'
+ depth_difference += 1
+ when 'in'
+ unless is_the_in_correspond_to_a_for(@tokens, index)
+ depth_difference += 1
+ end
+ when 'end'
+ depth_difference -= 1
end
end
end
-
- @here_header = true
- @here_readed.concat reserve
- while ch = reserve.pop
- ungetc ch
- end
-
- @ltype = ltback
- @lex_state = EXPR_END
- Token(Ltype2Token[lt])
- end
-
- def identify_quotation
- ch = getc
- if lt = PERCENT_LTYPE[ch]
- ch = getc
- elsif ch =~ /\W/
- lt = "\""
- else
- RubyLex.fail SyntaxError, "unknown type of %string"
- end
- @quoted = ch unless @quoted = PERCENT_PAREN[ch]
- identify_string(lt, @quoted)
+ depth_difference
end
- def identify_number
- @lex_state = EXPR_END
-
- if peek(0) == "0" && peek(1) !~ /[.eE]/
- getc
- case peek(0)
- when /[xX]/
- ch = getc
- match = /[0-9a-fA-F_]/
- when /[bB]/
- ch = getc
- match = /[01_]/
- when /[oO]/
- ch = getc
- match = /[0-7_]/
- when /[dD]/
- ch = getc
- match = /[0-9_]/
- when /[0-7]/
- match = /[0-7_]/
- when /[89]/
- RubyLex.fail SyntaxError, "Invalid octal digit"
+ def check_corresponding_token_depth
+ corresponding_token_depth = nil
+ is_first_spaces_of_line = true
+ is_first_printable_of_line = true
+ spaces_of_nest = []
+ spaces_at_line_head = 0
+ open_brace_on_line = 0
+ in_oneliner_def = nil
+ @tokens.each_with_index do |t, index|
+ # detecting one-liner method definition
+ if in_oneliner_def.nil?
+ if t[3].allbits?(Ripper::EXPR_ENDFN)
+ in_oneliner_def = :ENDFN
+ end
else
- return Token(TkINTEGER)
- end
-
- len0 = true
- non_digit = false
- while ch = getc
- if match =~ ch
- if ch == "_"
- if non_digit
- RubyLex.fail SyntaxError, "trailing `#{ch}' in number"
- else
- non_digit = ch
- end
- else
- non_digit = false
- len0 = false
+ if t[3].allbits?(Ripper::EXPR_ENDFN)
+ # continuing
+ elsif t[3].allbits?(Ripper::EXPR_BEG)
+ if t[2] == '='
+ in_oneliner_def = :BODY
end
else
- ungetc
- if len0
- RubyLex.fail SyntaxError, "numeric literal without digits"
- end
- if non_digit
- RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
+ if in_oneliner_def == :BODY
+ # one-liner method definition
+ if is_first_printable_of_line
+ corresponding_token_depth = spaces_of_nest.pop
+ else
+ spaces_of_nest.pop
+ corresponding_token_depth = nil
+ end
end
- break
+ in_oneliner_def = nil
end
end
- return Token(TkINTEGER)
- end
- type = TkINTEGER
- allow_point = true
- allow_e = true
- non_digit = false
- while ch = getc
- case ch
- when /[0-9]/
- non_digit = false
- when "_"
- non_digit = ch
- when allow_point && "."
- if non_digit
- RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
- end
- type = TkFLOAT
- if peek(0) !~ /[0-9]/
- type = TkINTEGER
- ungetc
- break
- end
- allow_point = false
- when allow_e && "e", allow_e && "E"
- if non_digit
- RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
- end
- type = TkFLOAT
- if peek(0) =~ /[+-]/
- getc
+ case t[1]
+ when :on_ignored_nl, :on_nl, :on_comment
+ if in_oneliner_def != :BODY
+ corresponding_token_depth = nil
+ spaces_at_line_head = 0
+ is_first_spaces_of_line = true
+ is_first_printable_of_line = true
+ open_brace_on_line = 0
end
- allow_e = false
- allow_point = false
- non_digit = ch
- else
- if non_digit
- RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
+ next
+ when :on_sp
+ spaces_at_line_head = t[2].count(' ') if is_first_spaces_of_line
+ is_first_spaces_of_line = false
+ next
+ end
+ case t[1]
+ when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
+ spaces_of_nest.push(spaces_at_line_head + open_brace_on_line * 2)
+ open_brace_on_line += 1
+ when :on_rbracket, :on_rbrace, :on_rparen
+ if is_first_printable_of_line
+ corresponding_token_depth = spaces_of_nest.pop
+ else
+ spaces_of_nest.pop
+ corresponding_token_depth = nil
end
- ungetc
- break
- end
- end
- Token(type)
- end
-
- def identify_string(ltype, quoted = ltype)
- @ltype = ltype
- @quoted = quoted
- subtype = nil
- begin
- nest = 0
- while ch = getc
- if @quoted == ch and nest == 0
- break
- elsif @ltype != "'" && ch == "#" && peek(0) == "{"
- identify_string_dvar
- elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#"
- subtype = true
- elsif ch == '\\' and @ltype == "'" #'
- case ch = getc
- when "\\", "\n", "'"
- else
- ungetc
+ open_brace_on_line -= 1
+ when :on_kw
+ next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
+ case t[2]
+ when 'do'
+ syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
+ if syntax_of_do == :method_calling
+ spaces_of_nest.push(spaces_at_line_head)
end
- elsif ch == '\\' #'
- read_escape
- end
- if PERCENT_PAREN.values.include?(@quoted)
- if PERCENT_PAREN[ch] == @quoted
- nest += 1
- elsif ch == @quoted
- nest -= 1
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
+ spaces_of_nest.push(spaces_at_line_head)
+ when 'rescue'
+ unless t[3].allbits?(Ripper::EXPR_LABEL)
+ corresponding_token_depth = spaces_of_nest.last
+ end
+ when 'if', 'unless', 'while', 'until'
+ # postfix if/unless/while/until must be Ripper::EXPR_LABEL
+ unless t[3].allbits?(Ripper::EXPR_LABEL)
+ spaces_of_nest.push(spaces_at_line_head)
+ end
+ when 'else', 'elsif', 'ensure', 'when', 'in'
+ corresponding_token_depth = spaces_of_nest.last
+ when 'end'
+ if is_first_printable_of_line
+ corresponding_token_depth = spaces_of_nest.pop
+ else
+ spaces_of_nest.pop
+ corresponding_token_depth = nil
end
end
end
- if @ltype == "/"
- while /[imxoesun]/ =~ peek(0)
- getc
- end
- end
- if subtype
- Token(DLtype2Token[ltype])
- else
- Token(Ltype2Token[ltype])
- end
- ensure
- @ltype = nil
- @quoted = nil
- @lex_state = EXPR_END
+ is_first_spaces_of_line = false
+ is_first_printable_of_line = false
end
+ corresponding_token_depth
end
- def identify_string_dvar
- begin
- getc
-
- reserve_continue = @continue
- reserve_ltype = @ltype
- reserve_indent = @indent
- reserve_indent_stack = @indent_stack
- reserve_state = @lex_state
- reserve_quoted = @quoted
-
- @ltype = nil
- @quoted = nil
- @indent = 0
- @indent_stack = []
- @lex_state = EXPR_BEG
-
- loop do
- @continue = false
- prompt
- tk = token
- if @ltype or @continue or @indent >= 0
- next
+ def check_string_literal(tokens)
+ i = 0
+ start_token = []
+ end_type = []
+ while i < tokens.size
+ t = tokens[i]
+ case t[1]
+ when :on_tstring_beg
+ start_token << t
+ end_type << [:on_tstring_end, :on_label_end]
+ when :on_regexp_beg
+ start_token << t
+ end_type << :on_regexp_end
+ when :on_symbeg
+ acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw}
+ if (i + 1) < tokens.size and acceptable_single_tokens.all?{ |st| tokens[i + 1][1] != st }
+ start_token << t
+ end_type << :on_tstring_end
end
- break if tk.kind_of?(TkRBRACE)
- end
- ensure
- @continue = reserve_continue
- @ltype = reserve_ltype
- @indent = reserve_indent
- @indent_stack = reserve_indent_stack
- @lex_state = reserve_state
- @quoted = reserve_quoted
- end
+ when :on_backtick
+ start_token << t
+ end_type << :on_tstring_end
+ when :on_qwords_beg, :on_words_beg, :on_qsymbols_beg, :on_symbols_beg
+ start_token << t
+ end_type << :on_tstring_end
+ when :on_heredoc_beg
+ start_token << t
+ end_type << :on_heredoc_end
+ when *end_type.last
+ start_token.pop
+ end_type.pop
+ end
+ i += 1
+ end
+ start_token.last.nil? ? '' : start_token.last
end
- def identify_comment
- @ltype = "#"
-
- while ch = getc
- if ch == "\n"
- @ltype = nil
- ungetc
- break
+ def process_literal_type(tokens = @tokens)
+ start_token = check_string_literal(tokens)
+ case start_token[1]
+ when :on_tstring_beg
+ case start_token[2]
+ when ?" then ?"
+ when /^%.$/ then ?"
+ when /^%Q.$/ then ?"
+ when ?' then ?'
+ when /^%q.$/ then ?'
+ end
+ when :on_regexp_beg then ?/
+ when :on_symbeg then ?:
+ when :on_backtick then ?`
+ when :on_qwords_beg then ?]
+ when :on_words_beg then ?]
+ when :on_qsymbols_beg then ?]
+ when :on_symbols_beg then ?]
+ when :on_heredoc_beg
+ start_token[2] =~ /<<[-~]?(['"`])[_a-zA-Z0-9]+\1/
+ case $1
+ when ?" then ?"
+ when ?' then ?'
+ when ?` then ?`
+ else ?"
end
+ else
+ nil
end
- return Token(TkCOMMENT)
end
- def read_escape
- case ch = getc
- when "\n", "\r", "\f"
- when "\\", "n", "t", "r", "f", "v", "a", "e", "b", "s" #"
- when /[0-7]/
- ungetc ch
- 3.times do
- case ch = getc
- when /[0-7]/
- when nil
- break
- else
- ungetc
- break
+ def check_termination_in_prev_line(code)
+ tokens = self.class.ripper_lex_without_warning(code)
+ past_first_newline = false
+ index = tokens.rindex do |t|
+ # traverse first token before last line
+ if past_first_newline
+ if t.tok.include?("\n")
+ true
end
+ elsif t.tok.include?("\n")
+ past_first_newline = true
+ false
+ else
+ false
end
-
- when "x"
- 2.times do
- case ch = getc
- when /[0-9a-fA-F]/
- when nil
- break
- else
- ungetc
+ end
+ if index
+ first_token = nil
+ last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
+ last_line_tokens.each do |t|
+ unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
+ first_token = t
break
end
end
-
- when "M"
- if (ch = getc) != '-'
- ungetc
+ if first_token.nil?
+ return false
+ elsif first_token && first_token.state == Ripper::EXPR_DOT
+ return false
else
- if (ch = getc) == "\\" #"
- read_escape
+ tokens_without_last_line = tokens[0..index]
+ ltype = process_literal_type(tokens_without_last_line)
+ indent = process_nesting_level(tokens_without_last_line)
+ continue = process_continue(tokens_without_last_line)
+ code_block_open = check_code_block(tokens_without_last_line.map(&:tok).join(''), tokens_without_last_line)
+ if ltype or indent > 0 or continue or code_block_open
+ return false
+ else
+ return last_line_tokens.map(&:tok).join('')
end
end
-
- when "C", "c" #, "^"
- if ch == "C" and (ch = getc) != "-"
- ungetc
- elsif (ch = getc) == "\\" #"
- read_escape
- end
- else
- # other characters
end
+ false
end
end
# :startdoc:
diff --git a/lib/irb/ruby-token.rb b/lib/irb/ruby-token.rb
deleted file mode 100644
index af53d3c93b..0000000000
--- a/lib/irb/ruby-token.rb
+++ /dev/null
@@ -1,267 +0,0 @@
-# frozen_string_literal: false
-#
-# irb/ruby-token.rb - ruby tokens
-# $Release Version: 0.9.6$
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-# :stopdoc:
-module RubyToken
- EXPR_BEG = :EXPR_BEG
- EXPR_MID = :EXPR_MID
- EXPR_END = :EXPR_END
- EXPR_ARG = :EXPR_ARG
- EXPR_FNAME = :EXPR_FNAME
- EXPR_DOT = :EXPR_DOT
- EXPR_CLASS = :EXPR_CLASS
-
- class Token
- def initialize(seek, line_no, char_no)
- @seek = seek
- @line_no = line_no
- @char_no = char_no
- end
- attr_reader :seek, :line_no, :char_no
- end
-
- class TkNode < Token
- def initialize(seek, line_no, char_no)
- super
- end
- attr_reader :node
- end
-
- class TkId < Token
- def initialize(seek, line_no, char_no, name)
- super(seek, line_no, char_no)
- @name = name
- end
- attr_reader :name
- end
-
- class TkVal < Token
- def initialize(seek, line_no, char_no, value = nil)
- super(seek, line_no, char_no)
- @value = value
- end
- attr_reader :value
- end
-
- class TkOp < Token
- attr_accessor :name
- end
-
- class TkOPASGN < TkOp
- def initialize(seek, line_no, char_no, op)
- super(seek, line_no, char_no)
- op = TkReading2Token[op][0] unless op.kind_of?(Symbol)
- @op = op
- end
- attr_reader :op
- end
-
- class TkUnknownChar < Token
- def initialize(seek, line_no, char_no, id)
- super(seek, line_no, char_no)
- @name = name
- end
- attr_reader :name
- end
-
- class TkError < Token
- end
-
- def Token(token, value = nil)
- case token
- when String
- if (tk = TkReading2Token[token]).nil?
- IRB.fail TkReading2TokenNoKey, token
- end
- tk = Token(tk[0], value)
- if tk.kind_of?(TkOp)
- tk.name = token
- end
- return tk
- when Symbol
- if (tk = TkSymbol2Token[token]).nil?
- IRB.fail TkSymbol2TokenNoKey, token
- end
- return Token(tk[0], value)
- else
- if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
- token.new(@prev_seek, @prev_line_no, @prev_char_no)
- else
- token.new(@prev_seek, @prev_line_no, @prev_char_no, value)
- end
- end
- end
-
- TokenDefinitions = [
- [:TkCLASS, TkId, "class", EXPR_CLASS],
- [:TkMODULE, TkId, "module", EXPR_BEG],
- [:TkDEF, TkId, "def", EXPR_FNAME],
- [:TkUNDEF, TkId, "undef", EXPR_FNAME],
- [:TkBEGIN, TkId, "begin", EXPR_BEG],
- [:TkRESCUE, TkId, "rescue", EXPR_MID],
- [:TkENSURE, TkId, "ensure", EXPR_BEG],
- [:TkEND, TkId, "end", EXPR_END],
- [:TkIF, TkId, "if", EXPR_BEG, :TkIF_MOD],
- [:TkUNLESS, TkId, "unless", EXPR_BEG, :TkUNLESS_MOD],
- [:TkTHEN, TkId, "then", EXPR_BEG],
- [:TkELSIF, TkId, "elsif", EXPR_BEG],
- [:TkELSE, TkId, "else", EXPR_BEG],
- [:TkCASE, TkId, "case", EXPR_BEG],
- [:TkWHEN, TkId, "when", EXPR_BEG],
- [:TkWHILE, TkId, "while", EXPR_BEG, :TkWHILE_MOD],
- [:TkUNTIL, TkId, "until", EXPR_BEG, :TkUNTIL_MOD],
- [:TkFOR, TkId, "for", EXPR_BEG],
- [:TkBREAK, TkId, "break", EXPR_END],
- [:TkNEXT, TkId, "next", EXPR_END],
- [:TkREDO, TkId, "redo", EXPR_END],
- [:TkRETRY, TkId, "retry", EXPR_END],
- [:TkIN, TkId, "in", EXPR_BEG],
- [:TkDO, TkId, "do", EXPR_BEG],
- [:TkRETURN, TkId, "return", EXPR_MID],
- [:TkYIELD, TkId, "yield", EXPR_END],
- [:TkSUPER, TkId, "super", EXPR_END],
- [:TkSELF, TkId, "self", EXPR_END],
- [:TkNIL, TkId, "nil", EXPR_END],
- [:TkTRUE, TkId, "true", EXPR_END],
- [:TkFALSE, TkId, "false", EXPR_END],
- [:TkAND, TkId, "and", EXPR_BEG],
- [:TkOR, TkId, "or", EXPR_BEG],
- [:TkNOT, TkId, "not", EXPR_BEG],
- [:TkIF_MOD, TkId],
- [:TkUNLESS_MOD, TkId],
- [:TkWHILE_MOD, TkId],
- [:TkUNTIL_MOD, TkId],
- [:TkALIAS, TkId, "alias", EXPR_FNAME],
- [:TkDEFINED, TkId, "defined?", EXPR_END],
- [:TklBEGIN, TkId, "BEGIN", EXPR_END],
- [:TklEND, TkId, "END", EXPR_END],
- [:Tk__LINE__, TkId, "__LINE__", EXPR_END],
- [:Tk__FILE__, TkId, "__FILE__", EXPR_END],
-
- [:TkIDENTIFIER, TkId],
- [:TkFID, TkId],
- [:TkGVAR, TkId],
- [:TkCVAR, TkId],
- [:TkIVAR, TkId],
- [:TkCONSTANT, TkId],
-
- [:TkINTEGER, TkVal],
- [:TkFLOAT, TkVal],
- [:TkSTRING, TkVal],
- [:TkXSTRING, TkVal],
- [:TkREGEXP, TkVal],
- [:TkSYMBOL, TkVal],
-
- [:TkDSTRING, TkNode],
- [:TkDXSTRING, TkNode],
- [:TkDREGEXP, TkNode],
- [:TkNTH_REF, TkNode],
- [:TkBACK_REF, TkNode],
-
- [:TkUPLUS, TkOp, "+@"],
- [:TkUMINUS, TkOp, "-@"],
- [:TkPOW, TkOp, "**"],
- [:TkCMP, TkOp, "<=>"],
- [:TkEQ, TkOp, "=="],
- [:TkEQQ, TkOp, "==="],
- [:TkNEQ, TkOp, "!="],
- [:TkGEQ, TkOp, ">="],
- [:TkLEQ, TkOp, "<="],
- [:TkANDOP, TkOp, "&&"],
- [:TkOROP, TkOp, "||"],
- [:TkMATCH, TkOp, "=~"],
- [:TkNMATCH, TkOp, "!~"],
- [:TkDOT2, TkOp, ".."],
- [:TkDOT3, TkOp, "..."],
- [:TkAREF, TkOp, "[]"],
- [:TkASET, TkOp, "[]="],
- [:TkLSHFT, TkOp, "<<"],
- [:TkRSHFT, TkOp, ">>"],
- [:TkCOLON2, TkOp],
- [:TkCOLON3, TkOp],
- [:TkASSOC, TkOp, "=>"],
- [:TkQUESTION, TkOp, "?"], #?
- [:TkCOLON, TkOp, ":"], #:
-
- [:TkfLPAREN], # func( #
- [:TkfLBRACK], # func[ #
- [:TkfLBRACE], # func{ #
- [:TkSTAR], # *arg
- [:TkAMPER], # &arg #
- [:TkSYMBEG], # :SYMBOL
-
- [:TkGT, TkOp, ">"],
- [:TkLT, TkOp, "<"],
- [:TkPLUS, TkOp, "+"],
- [:TkMINUS, TkOp, "-"],
- [:TkMULT, TkOp, "*"],
- [:TkDIV, TkOp, "/"],
- [:TkMOD, TkOp, "%"],
- [:TkBITOR, TkOp, "|"],
- [:TkBITXOR, TkOp, "^"],
- [:TkBITAND, TkOp, "&"],
- [:TkBITNOT, TkOp, "~"],
- [:TkNOTOP, TkOp, "!"],
-
- [:TkBACKQUOTE, TkOp, "`"],
-
- [:TkASSIGN, Token, "="],
- [:TkDOT, Token, "."],
- [:TkLPAREN, Token, "("], #(exp)
- [:TkLBRACK, Token, "["], #[arry]
- [:TkLBRACE, Token, "{"], #{hash}
- [:TkRPAREN, Token, ")"],
- [:TkRBRACK, Token, "]"],
- [:TkRBRACE, Token, "}"],
- [:TkCOMMA, Token, ","],
- [:TkSEMICOLON, Token, ";"],
-
- [:TkCOMMENT],
- [:TkRD_COMMENT],
- [:TkSPACE],
- [:TkNL],
- [:TkEND_OF_SCRIPT],
-
- [:TkBACKSLASH, TkUnknownChar, "\\"],
- [:TkAT, TkUnknownChar, "@"],
- [:TkDOLLAR, TkUnknownChar, "$"],
- ]
-
- # {reading => token_class}
- # {reading => [token_class, *opt]}
- TkReading2Token = {}
- TkSymbol2Token = {}
-
- def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
- token_n = token_n.id2name if token_n.kind_of?(Symbol)
- if RubyToken.const_defined?(token_n)
- IRB.fail AlreadyDefinedToken, token_n
- end
- token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}")
-
- if reading
- if TkReading2Token[reading]
- IRB.fail TkReading2TokenDuplicateError, token_n, reading
- end
- if opts.empty?
- TkReading2Token[reading] = [token_c]
- else
- TkReading2Token[reading] = [token_c].concat(opts)
- end
- end
- TkSymbol2Token[token_n.intern] = token_c
- end
-
- for defs in TokenDefinitions
- def_token(*defs)
- end
-end
-# :startdoc:
diff --git a/lib/irb/ruby_logo.aa b/lib/irb/ruby_logo.aa
new file mode 100644
index 0000000000..a34a3e2f28
--- /dev/null
+++ b/lib/irb/ruby_logo.aa
@@ -0,0 +1,37 @@
+
+ -+smJYYN?mm-
+ HB"BBYT TQg NggT
+ 9Q+g Nm,T 8g NJW
+ YS+ N2NJ"Sg N?
+ BQg #( gT Nggggk J
+ 5j NJ NJ NNge
+ #Q #JJ NgT N(
+ @j bj mT J
+ Bj @/d NJ (
+ #q #(( NgT #J
+ 5d #(t mT $d
+ #q @(@J NJB;
+ @( 5d ? HHH H HQmgggggggmN qD
+ 5d #uN 2QdH E O
+ 5 5JSd Nd NJH @d j
+ Fd @J4d s NQH #d (
+ #( #o6d Nd NgH #d #d
+ 4 B&Od v NgT #d F
+ #( 9JGd NH NgUd F
+ #d #GJQ d NP $
+ #J #U+#Q N Q # j
+ j /W BQ+ BQ d NJ NJ
+ - NjJH HBIjTQggPJQgW N W k #J
+ #J b HYWgggN j s Nag d NN b #d
+ #J 5- D s Ngg N d Nd F
+ Fd BKH2 #+ s NNgg J Q J ]
+ F H @ J N y K(d P I
+ F4 E N? #d y #Q NJ E j
+ F W Nd q m Bg NxW N(H-
+ F d b @ m Hd gW vKJ
+ NJ d K d s Bg aT FDd
+ b # d N m BQ mV N>
+ e5 Nd #d NggggggQWH HHHH NJ -
+ m7 NW H N HSVO1z=?11-
+ NgTH bB kH WBHWWHBHWmQgg&gggggNNN
+ NNggggggNN
diff --git a/lib/irb/slex.rb b/lib/irb/slex.rb
deleted file mode 100644
index 039b214a8d..0000000000
--- a/lib/irb/slex.rb
+++ /dev/null
@@ -1,282 +0,0 @@
-# frozen_string_literal: false
-#
-# irb/slex.rb - simple lex analyzer
-# $Release Version: 0.9.6$
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-require "e2mmap"
-require "irb/notifier"
-
-# :stopdoc:
-module IRB
- class SLex
-
- extend Exception2MessageMapper
- def_exception :ErrNodeNothing, "node nothing"
- def_exception :ErrNodeAlreadyExists, "node already exists"
-
- DOUT = Notifier::def_notifier("SLex::")
- D_WARN = DOUT::def_notifier(1, "Warn: ")
- D_DEBUG = DOUT::def_notifier(2, "Debug: ")
- D_DETAIL = DOUT::def_notifier(4, "Detail: ")
-
- DOUT.level = Notifier::D_NOMSG
-
- def initialize
- @head = Node.new("")
- end
-
- def def_rule(token, preproc = nil, postproc = nil, &block)
- D_DETAIL.pp token
-
- postproc = block if block_given?
- create(token, preproc, postproc)
- end
-
- def def_rules(*tokens, &block)
- if block_given?
- p = block
- end
- for token in tokens
- def_rule(token, nil, p)
- end
- end
-
- def preproc(token, proc)
- node = search(token)
- node.preproc=proc
- end
-
- # need a check?
- def postproc(token)
- node = search(token, proc)
- node.postproc=proc
- end
-
- def search(token)
- @head.search(token.split(//))
- end
-
- def create(token, preproc = nil, postproc = nil)
- @head.create_subnode(token.split(//), preproc, postproc)
- end
-
- def match(token)
- case token
- when Array
- when String
- return match(token.split(//))
- else
- return @head.match_io(token)
- end
- ret = @head.match(token)
- D_DETAIL.exec_if{D_DETAIL.printf "match end: %s:%s\n", ret, token.inspect}
- ret
- end
-
- def inspect
- format("<SLex: @head = %s>", @head.inspect)
- end
-
- #----------------------------------------------------------------------
- #
- # class Node -
- #
- #----------------------------------------------------------------------
- class Node
- # if postproc is nil, this node is an abstract node.
- # if postproc is non-nil, this node is a real node.
- def initialize(preproc = nil, postproc = nil)
- @Tree = {}
- @preproc = preproc
- @postproc = postproc
- end
-
- attr_accessor :preproc
- attr_accessor :postproc
-
- def search(chrs, opt = nil)
- return self if chrs.empty?
- ch = chrs.shift
- if node = @Tree[ch]
- node.search(chrs, opt)
- else
- if opt
- chrs.unshift ch
- self.create_subnode(chrs)
- else
- SLex.fail ErrNodeNothing
- end
- end
- end
-
- def create_subnode(chrs, preproc = nil, postproc = nil)
- if chrs.empty?
- if @postproc
- D_DETAIL.pp node
- SLex.fail ErrNodeAlreadyExists
- else
- D_DEBUG.puts "change abstract node to real node."
- @preproc = preproc
- @postproc = postproc
- end
- return self
- end
-
- ch = chrs.shift
- if node = @Tree[ch]
- if chrs.empty?
- if node.postproc
- DebugLogger.pp node
- DebugLogger.pp self
- DebugLogger.pp ch
- DebugLogger.pp chrs
- SLex.fail ErrNodeAlreadyExists
- else
- D_WARN.puts "change abstract node to real node"
- node.preproc = preproc
- node.postproc = postproc
- end
- else
- node.create_subnode(chrs, preproc, postproc)
- end
- else
- if chrs.empty?
- node = Node.new(preproc, postproc)
- else
- node = Node.new
- node.create_subnode(chrs, preproc, postproc)
- end
- @Tree[ch] = node
- end
- node
- end
-
- #
- # chrs: String
- # character array
- # io must have getc()/ungetc(); and ungetc() must be
- # able to be called arbitrary number of times.
- #
- def match(chrs, op = "")
- D_DETAIL.print "match>: ", chrs, "op:", op, "\n"
- if chrs.empty?
- if @preproc.nil? || @preproc.call(op, chrs)
- DOUT.printf(D_DETAIL, "op1: %s\n", op)
- @postproc.call(op, chrs)
- else
- nil
- end
- else
- ch = chrs.shift
- if node = @Tree[ch]
- if ret = node.match(chrs, op+ch)
- return ret
- else
- chrs.unshift ch
- if @postproc and @preproc.nil? || @preproc.call(op, chrs)
- DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect)
- ret = @postproc.call(op, chrs)
- return ret
- else
- return nil
- end
- end
- else
- chrs.unshift ch
- if @postproc and @preproc.nil? || @preproc.call(op, chrs)
- DOUT.printf(D_DETAIL, "op3: %s\n", op)
- @postproc.call(op, chrs)
- return ""
- else
- return nil
- end
- end
- end
- end
-
- def match_io(io, op = "")
- if op == ""
- ch = io.getc
- if ch == nil
- return nil
- end
- else
- ch = io.getc_of_rests
- end
- if ch.nil?
- if @preproc.nil? || @preproc.call(op, io)
- D_DETAIL.printf("op1: %s\n", op)
- @postproc.call(op, io)
- else
- nil
- end
- else
- if node = @Tree[ch]
- if ret = node.match_io(io, op+ch)
- ret
- else
- io.ungetc ch
- if @postproc and @preproc.nil? || @preproc.call(op, io)
- DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect}
- @postproc.call(op, io)
- else
- nil
- end
- end
- else
- io.ungetc ch
- if @postproc and @preproc.nil? || @preproc.call(op, io)
- D_DETAIL.printf("op3: %s\n", op)
- @postproc.call(op, io)
- else
- nil
- end
- end
- end
- end
- end
- end
-end
-# :startdoc:
-
-if $0 == __FILE__
- case $1
- when "1"
- tr = SLex.new
- print "0: ", tr.inspect, "\n"
- tr.def_rule("=") {print "=\n"}
- print "1: ", tr.inspect, "\n"
- tr.def_rule("==") {print "==\n"}
- print "2: ", tr.inspect, "\n"
-
- print "case 1:\n"
- print tr.match("="), "\n"
- print "case 2:\n"
- print tr.match("=="), "\n"
- print "case 3:\n"
- print tr.match("=>"), "\n"
-
- when "2"
- tr = SLex.new
- print "0: ", tr.inspect, "\n"
- tr.def_rule("=") {print "=\n"}
- print "1: ", tr.inspect, "\n"
- tr.def_rule("==", proc{false}) {print "==\n"}
- print "2: ", tr.inspect, "\n"
-
- print "case 1:\n"
- print tr.match("="), "\n"
- print "case 2:\n"
- print tr.match("=="), "\n"
- print "case 3:\n"
- print tr.match("=>"), "\n"
- end
- exit
-end
diff --git a/lib/irb/version.rb b/lib/irb/version.rb
index 094cb33c05..0014bdda74 100644
--- a/lib/irb/version.rb
+++ b/lib/irb/version.rb
@@ -11,6 +11,7 @@
#
module IRB # :nodoc:
- @RELEASE_VERSION = "0.9.6"
- @LAST_UPDATE_DATE = "09/06/30"
+ VERSION = "1.3.5"
+ @RELEASE_VERSION = VERSION
+ @LAST_UPDATE_DATE = "2021-04-03"
end
diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb
index 9051f96df0..78d434d106 100644
--- a/lib/irb/workspace.rb
+++ b/lib/irb/workspace.rb
@@ -9,6 +9,9 @@
#
#
#
+
+require "delegate"
+
module IRB # :nodoc:
class WorkSpace
# Creates a new workspace.
@@ -48,18 +51,24 @@ EOF
end
@binding = BINDING_QUEUE.pop
- when 3 # binding in function on TOPLEVEL_BINDING(default)
- @binding = eval("def irb_binding; private; binding; end; irb_binding",
+ when 3 # binding in function on TOPLEVEL_BINDING
+ @binding = eval("self.class.remove_method(:irb_binding) if defined?(irb_binding); private; def irb_binding; binding; end; irb_binding",
TOPLEVEL_BINDING,
__FILE__,
__LINE__ - 3)
+ when 4 # binding is a copy of TOPLEVEL_BINDING (default)
+ @binding = TOPLEVEL_BINDING.dup
end
end
+
if main.empty?
@main = eval("self", @binding)
else
@main = main[0]
- IRB.conf[:__MAIN__] = @main
+ end
+ IRB.conf[:__MAIN__] = @main
+
+ unless main.empty?
case @main
when Module
@binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
@@ -67,11 +76,33 @@ EOF
begin
@binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
rescue TypeError
- IRB.fail CantChangeBinding, @main.inspect
+ fail CantChangeBinding, @main.inspect
+ end
+ end
+ end
+
+ case @main
+ when Object
+ use_delegator = @main.frozen?
+ else
+ use_delegator = true
+ end
+
+ if use_delegator
+ @main = SimpleDelegator.new(@main)
+ IRB.conf[:__MAIN__] = @main
+ @main.singleton_class.class_eval do
+ private
+ define_method(:exit) do |*a, &b|
+ # Do nothing, will be overridden
end
+ define_method(:binding, Kernel.instance_method(:binding))
+ define_method(:local_variables, Kernel.instance_method(:local_variables))
end
+ @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
end
- eval("_=nil", @binding)
+
+ @binding.local_variable_set(:_, nil)
end
# The Binding of this workspace
@@ -85,28 +116,68 @@ EOF
eval(statements, @binding, file, line)
end
+ def local_variable_set(name, value)
+ @binding.local_variable_set(name, value)
+ end
+
+ def local_variable_get(name)
+ @binding.local_variable_get(name)
+ end
+
# error message manipulator
def filter_backtrace(bt)
+ return nil if bt =~ /\/irb\/.*\.rb/
+ return nil if bt =~ /\/irb\.rb/
+ return nil if bt =~ /tool\/lib\/.*\.rb|runner\.rb/ # for tests in Ruby repository
case IRB.conf[:CONTEXT_MODE]
- when 0
- return nil if bt =~ /\(irb_local_binding\)/
when 1
- if(bt =~ %r!/tmp/irb-binding! or
- bt =~ %r!irb/.*\.rb! or
- bt =~ /irb\.rb/)
- return nil
- end
- when 2
- return nil if bt =~ /irb\/.*\.rb/
- return nil if bt =~ /irb\.rb/
+ return nil if bt =~ %r!/tmp/irb-binding!
when 3
- return nil if bt =~ /irb\/.*\.rb/
- return nil if bt =~ /irb\.rb/
bt = bt.sub(/:\s*in `irb_binding'/, '')
end
bt
end
+ def code_around_binding
+ if @binding.respond_to?(:source_location)
+ file, pos = @binding.source_location
+ else
+ file, pos = @binding.eval('[__FILE__, __LINE__]')
+ end
+
+ if defined?(::SCRIPT_LINES__[file]) && lines = ::SCRIPT_LINES__[file]
+ code = ::SCRIPT_LINES__[file].join('')
+ else
+ begin
+ code = File.read(file)
+ rescue SystemCallError
+ return
+ end
+ end
+
+ # NOT using #use_colorize? of IRB.conf[:MAIN_CONTEXT] because this method may be called before IRB::Irb#run
+ use_colorize = IRB.conf.fetch(:USE_COLORIZE, true)
+ if use_colorize
+ lines = Color.colorize_code(code).lines
+ else
+ lines = code.lines
+ end
+ pos -= 1
+
+ start_pos = [pos - 5, 0].max
+ end_pos = [pos + 5, lines.size - 1].min
+
+ if use_colorize
+ fmt = " %2s #{Color.colorize("%#{end_pos.to_s.length}d", [:BLUE, :BOLD])}: %s"
+ else
+ fmt = " %2s %#{end_pos.to_s.length}d: %s"
+ end
+ body = (start_pos..end_pos).map do |current_pos|
+ sprintf(fmt, pos == current_pos ? '=>' : '', current_pos + 1, lines[current_pos])
+ end.join("")
+ "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear if use_colorize}\n"
+ end
+
def IRB.delete_caller
end
end
diff --git a/lib/irb/xmp.rb b/lib/irb/xmp.rb
index 3234cff7f3..88cbd88525 100644
--- a/lib/irb/xmp.rb
+++ b/lib/irb/xmp.rb
@@ -10,8 +10,8 @@
#
#
-require "irb"
-require "irb/frame"
+require_relative "../irb"
+require_relative "frame"
# An example printer for irb.
#
diff --git a/lib/logger.rb b/lib/logger.rb
index f572921db4..5e88574aa5 100644
--- a/lib/logger.rb
+++ b/lib/logger.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
# logger.rb - simple logging utility
# Copyright (C) 2000-2003, 2005, 2008, 2011 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
#
@@ -12,6 +12,12 @@
require 'monitor'
+require_relative 'logger/version'
+require_relative 'logger/formatter'
+require_relative 'logger/log_device'
+require_relative 'logger/severity'
+require_relative 'logger/errors'
+
# == Description
#
# The Logger class provides a simple but sophisticated logging utility that
@@ -109,7 +115,7 @@ require 'monitor'
# 3. Create a logger for the specified file.
#
# file = File.open('foo.log', File::WRONLY | File::APPEND)
-# # To create new (and to remove old) logfile, add File::CREAT like:
+# # To create new logfile, add File::CREAT like:
# # file = File.open('foo.log', File::WRONLY | File::APPEND | File::CREAT)
# logger = Logger.new(file)
#
@@ -224,7 +230,6 @@ require 'monitor'
# })
#
class Logger
- VERSION = "1.2.7"
_, name, rev = %w$Id$
if name
name = name.chomp(",v")
@@ -232,29 +237,8 @@ class Logger
name = File.basename(__FILE__)
end
rev ||= "v#{VERSION}"
- ProgName = "#{name}/#{rev}".freeze
-
- class Error < RuntimeError # :nodoc:
- end
- # not used after 1.2.7. just for compat.
- class ShiftingError < Error # :nodoc:
- end
+ ProgName = "#{name}/#{rev}"
- # Logging severity.
- module Severity
- # Low-level information, mostly for developers.
- DEBUG = 0
- # Generic (useful) information about system operation.
- INFO = 1
- # A warning.
- WARN = 2
- # A handleable error condition.
- ERROR = 3
- # An unhandleable error that results in a program crash.
- FATAL = 4
- # An unknown message that should always be logged.
- UNKNOWN = 5
- end
include Severity
# Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
@@ -320,23 +304,38 @@ class Logger
# Returns +true+ iff the current severity level allows for the printing of
# +DEBUG+ messages.
- def debug?; @level <= DEBUG; end
+ def debug?; level <= DEBUG; end
+
+ # Sets the severity to DEBUG.
+ def debug!; self.level = DEBUG; end
# Returns +true+ iff the current severity level allows for the printing of
# +INFO+ messages.
- def info?; @level <= INFO; end
+ def info?; level <= INFO; end
+
+ # Sets the severity to INFO.
+ def info!; self.level = INFO; end
# Returns +true+ iff the current severity level allows for the printing of
# +WARN+ messages.
- def warn?; @level <= WARN; end
+ def warn?; level <= WARN; end
+
+ # Sets the severity to WARN.
+ def warn!; self.level = WARN; end
# Returns +true+ iff the current severity level allows for the printing of
# +ERROR+ messages.
- def error?; @level <= ERROR; end
+ def error?; level <= ERROR; end
+
+ # Sets the severity to ERROR.
+ def error!; self.level = ERROR; end
# Returns +true+ iff the current severity level allows for the printing of
# +FATAL+ messages.
- def fatal?; @level <= FATAL; end
+ def fatal?; level <= FATAL; end
+
+ # Sets the severity to FATAL.
+ def fatal!; self.level = FATAL; end
#
# :call-seq:
@@ -350,14 +349,16 @@ class Logger
# === Args
#
# +logdev+::
- # The log device. This is a filename (String) or IO object (typically
- # +STDOUT+, +STDERR+, or an open file).
+ # The log device. This is a filename (String), IO object (typically
+ # +STDOUT+, +STDERR+, or an open file), +nil+ (it writes nothing) or
+ # +File::NULL+ (same as +nil+).
# +shift_age+::
# Number of old log files to keep, *or* frequency of rotation (+daily+,
- # +weekly+ or +monthly+). Default value is 0.
+ # +weekly+ or +monthly+). Default value is 0, which disables log file
+ # rotation.
# +shift_size+::
- # Maximum logfile size in bytes (only applies when +shift_age+ is a number).
- # Defaults to +1048576+ (1MB).
+ # Maximum logfile size in bytes (only applies when +shift_age+ is a positive
+ # Integer). Defaults to +1048576+ (1MB).
# +level+::
# Logging severity threshold. Default values is Logger::DEBUG.
# +progname+::
@@ -366,6 +367,8 @@ class Logger
# Logging formatter. Default values is an instance of Logger::Formatter.
# +datetime_format+::
# Date and time format. Default value is '%Y-%m-%d %H:%M:%S'.
+ # +binmode+::
+ # Use binary mode on the log device. Default value is false.
# +shift_period_suffix+::
# The log file suffix format for +daily+, +weekly+ or +monthly+ rotation.
# Default is '%Y%m%d'.
@@ -376,17 +379,18 @@ class Logger
#
def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
progname: nil, formatter: nil, datetime_format: nil,
- shift_period_suffix: '%Y%m%d')
+ binmode: false, shift_period_suffix: '%Y%m%d')
self.level = level
self.progname = progname
@default_formatter = Formatter.new
self.datetime_format = datetime_format
self.formatter = formatter
@logdev = nil
- if logdev
- @logdev = LogDevice.new(logdev, :shift_age => shift_age,
- :shift_size => shift_size,
- :shift_period_suffix => shift_period_suffix)
+ if logdev && logdev != File::NULL
+ @logdev = LogDevice.new(logdev, shift_age: shift_age,
+ shift_size: shift_size,
+ shift_period_suffix: shift_period_suffix,
+ binmode: binmode)
end
end
@@ -407,7 +411,7 @@ class Logger
# Reopen a log device.
#
def reopen(logdev = nil)
- @logdev.reopen(logdev)
+ @logdev&.reopen(logdev)
self
end
@@ -454,7 +458,7 @@ class Logger
#
def add(severity, message = nil, progname = nil)
severity ||= UNKNOWN
- if @logdev.nil? or severity < @level
+ if @logdev.nil? or severity < level
return true
end
if progname.nil?
@@ -479,9 +483,7 @@ class Logger
# device exists, return +nil+.
#
def <<(msg)
- unless @logdev.nil?
- @logdev.write(msg)
- end
+ @logdev&.write(msg)
end
#
@@ -568,13 +570,13 @@ class Logger
# Close the logging device.
#
def close
- @logdev.close if @logdev
+ @logdev&.close
end
private
# Severity label for logging (max 5 chars).
- SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY).each(&:freeze).freeze
+ SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY).freeze
def format_severity(severity)
SEV_LABEL[severity] || 'ANY'
@@ -583,273 +585,4 @@ private
def format_message(severity, datetime, progname, msg)
(@formatter || @default_formatter).call(severity, datetime, progname, msg)
end
-
-
- # Default formatter for log messages.
- class Formatter
- Format = "%s, [%s#%d] %5s -- %s: %s\n".freeze
-
- attr_accessor :datetime_format
-
- def initialize
- @datetime_format = nil
- end
-
- def call(severity, time, progname, msg)
- Format % [severity[0..0], format_datetime(time), $$, severity, progname,
- msg2str(msg)]
- end
-
- private
-
- def format_datetime(time)
- time.strftime(@datetime_format || "%Y-%m-%dT%H:%M:%S.%6N ".freeze)
- end
-
- def msg2str(msg)
- case msg
- when ::String
- msg
- when ::Exception
- "#{ msg.message } (#{ msg.class })\n" <<
- (msg.backtrace || []).join("\n")
- else
- msg.inspect
- end
- end
- end
-
- module Period
- module_function
-
- SiD = 24 * 60 * 60
-
- def next_rotate_time(now, shift_age)
- case shift_age
- when 'daily'
- t = Time.mktime(now.year, now.month, now.mday) + SiD
- when 'weekly'
- t = Time.mktime(now.year, now.month, now.mday) + SiD * (7 - now.wday)
- when 'monthly'
- t = Time.mktime(now.year, now.month, 1) + SiD * 32
- return Time.mktime(t.year, t.month, 1)
- else
- return now
- end
- if t.hour.nonzero? or t.min.nonzero? or t.sec.nonzero?
- hour = t.hour
- t = Time.mktime(t.year, t.month, t.mday)
- t += SiD if hour > 12
- end
- t
- end
-
- def previous_period_end(now, shift_age)
- case shift_age
- when 'daily'
- t = Time.mktime(now.year, now.month, now.mday) - SiD / 2
- when 'weekly'
- t = Time.mktime(now.year, now.month, now.mday) - (SiD * now.wday + SiD / 2)
- when 'monthly'
- t = Time.mktime(now.year, now.month, 1) - SiD / 2
- else
- return now
- end
- Time.mktime(t.year, t.month, t.mday, 23, 59, 59)
- end
- end
-
- # Device used for logging messages.
- class LogDevice
- include Period
-
- attr_reader :dev
- attr_reader :filename
- include MonitorMixin
-
- def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil)
- @dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil
- mon_initialize
- set_dev(log)
- if @filename
- @shift_age = shift_age || 7
- @shift_size = shift_size || 1048576
- @shift_period_suffix = shift_period_suffix || '%Y%m%d'
-
- unless @shift_age.is_a?(Integer)
- base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now
- @next_rotate_time = next_rotate_time(base_time, @shift_age)
- end
- end
- end
-
- def write(message)
- begin
- synchronize do
- if @shift_age and @dev.respond_to?(:stat)
- begin
- check_shift_log
- rescue
- warn("log shifting failed. #{$!}")
- end
- end
- begin
- @dev.write(message)
- rescue
- warn("log writing failed. #{$!}")
- end
- end
- rescue Exception => ignored
- warn("log writing failed. #{ignored}")
- end
- end
-
- def close
- begin
- synchronize do
- @dev.close rescue nil
- end
- rescue Exception
- @dev.close rescue nil
- end
- end
-
- def reopen(log = nil)
- # reopen the same filename if no argument, do nothing for IO
- log ||= @filename if @filename
- if log
- synchronize do
- if @filename and @dev
- @dev.close rescue nil # close only file opened by Logger
- @filename = nil
- end
- set_dev(log)
- end
- end
- self
- end
-
- private
-
- def set_dev(log)
- if log.respond_to?(:write) and log.respond_to?(:close)
- @dev = log
- else
- @dev = open_logfile(log)
- @dev.sync = true
- @filename = log
- end
- end
-
- def open_logfile(filename)
- begin
- open(filename, (File::WRONLY | File::APPEND))
- rescue Errno::ENOENT
- create_logfile(filename)
- end
- end
-
- def create_logfile(filename)
- begin
- logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT | File::EXCL))
- logdev.flock(File::LOCK_EX)
- logdev.sync = true
- add_log_header(logdev)
- logdev.flock(File::LOCK_UN)
- rescue Errno::EEXIST
- # file is created by another process
- logdev = open_logfile(filename)
- logdev.sync = true
- end
- logdev
- end
-
- def add_log_header(file)
- file.write(
- "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
- ) if file.size == 0
- end
-
- def check_shift_log
- if @shift_age.is_a?(Integer)
- # Note: always returns false if '0'.
- if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size)
- lock_shift_log { shift_log_age }
- end
- else
- now = Time.now
- if now >= @next_rotate_time
- @next_rotate_time = next_rotate_time(now, @shift_age)
- lock_shift_log { shift_log_period(previous_period_end(now, @shift_age)) }
- end
- end
- end
-
- if /mswin|mingw/ =~ RUBY_PLATFORM
- def lock_shift_log
- yield
- end
- else
- def lock_shift_log
- retry_limit = 8
- retry_sleep = 0.1
- begin
- File.open(@filename, File::WRONLY | File::APPEND) do |lock|
- lock.flock(File::LOCK_EX) # inter-process locking. will be unlocked at closing file
- if File.identical?(@filename, lock) and File.identical?(lock, @dev)
- yield # log shifting
- else
- # log shifted by another process (i-node before locking and i-node after locking are different)
- @dev.close rescue nil
- @dev = open_logfile(@filename)
- @dev.sync = true
- end
- end
- rescue Errno::ENOENT
- # @filename file would not exist right after #rename and before #create_logfile
- if retry_limit <= 0
- warn("log rotation inter-process lock failed. #{$!}")
- else
- sleep retry_sleep
- retry_limit -= 1
- retry_sleep *= 2
- retry
- end
- end
- rescue
- warn("log rotation inter-process lock failed. #{$!}")
- end
- end
-
- def shift_log_age
- (@shift_age-3).downto(0) do |i|
- if FileTest.exist?("#{@filename}.#{i}")
- File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}")
- end
- end
- @dev.close rescue nil
- File.rename("#{@filename}", "#{@filename}.0")
- @dev = create_logfile(@filename)
- return true
- end
-
- def shift_log_period(period_end)
- suffix = period_end.strftime(@shift_period_suffix)
- age_file = "#{@filename}.#{suffix}"
- if FileTest.exist?(age_file)
- # try to avoid filename crash caused by Timestamp change.
- idx = 0
- # .99 can be overridden; avoid too much file search with 'loop do'
- while idx < 100
- idx += 1
- age_file = "#{@filename}.#{suffix}.#{idx}"
- break unless FileTest.exist?(age_file)
- end
- end
- @dev.close rescue nil
- File.rename("#{@filename}", age_file)
- @dev = create_logfile(@filename)
- return true
- end
- end
end
diff --git a/lib/logger/errors.rb b/lib/logger/errors.rb
new file mode 100644
index 0000000000..e8925e14ac
--- /dev/null
+++ b/lib/logger/errors.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+# not used after 1.2.7. just for compat.
+class Logger
+ class Error < RuntimeError # :nodoc:
+ end
+ class ShiftingError < Error # :nodoc:
+ end
+end
diff --git a/lib/logger/formatter.rb b/lib/logger/formatter.rb
new file mode 100644
index 0000000000..6a135b6fab
--- /dev/null
+++ b/lib/logger/formatter.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+class Logger
+ # Default formatter for log messages.
+ class Formatter
+ Format = "%s, [%s#%d] %5s -- %s: %s\n"
+
+ attr_accessor :datetime_format
+
+ def initialize
+ @datetime_format = nil
+ end
+
+ def call(severity, time, progname, msg)
+ Format % [severity[0..0], format_datetime(time), Process.pid, severity, progname,
+ msg2str(msg)]
+ end
+
+ private
+
+ def format_datetime(time)
+ time.strftime(@datetime_format || "%Y-%m-%dT%H:%M:%S.%6N ")
+ end
+
+ def msg2str(msg)
+ case msg
+ when ::String
+ msg
+ when ::Exception
+ "#{ msg.message } (#{ msg.class })\n#{ msg.backtrace.join("\n") if msg.backtrace }"
+ else
+ msg.inspect
+ end
+ end
+ end
+end
diff --git a/lib/logger/log_device.rb b/lib/logger/log_device.rb
new file mode 100644
index 0000000000..96d77b7b6a
--- /dev/null
+++ b/lib/logger/log_device.rb
@@ -0,0 +1,205 @@
+# frozen_string_literal: true
+
+require_relative 'period'
+
+class Logger
+ # Device used for logging messages.
+ class LogDevice
+ include Period
+
+ attr_reader :dev
+ attr_reader :filename
+ include MonitorMixin
+
+ def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: false)
+ @dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil
+ @binmode = binmode
+ mon_initialize
+ set_dev(log)
+ if @filename
+ @shift_age = shift_age || 7
+ @shift_size = shift_size || 1048576
+ @shift_period_suffix = shift_period_suffix || '%Y%m%d'
+
+ unless @shift_age.is_a?(Integer)
+ base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now
+ @next_rotate_time = next_rotate_time(base_time, @shift_age)
+ end
+ end
+ end
+
+ def write(message)
+ begin
+ synchronize do
+ if @shift_age and @dev.respond_to?(:stat)
+ begin
+ check_shift_log
+ rescue
+ warn("log shifting failed. #{$!}")
+ end
+ end
+ begin
+ @dev.write(message)
+ rescue
+ warn("log writing failed. #{$!}")
+ end
+ end
+ rescue Exception => ignored
+ warn("log writing failed. #{ignored}")
+ end
+ end
+
+ def close
+ begin
+ synchronize do
+ @dev.close rescue nil
+ end
+ rescue Exception
+ @dev.close rescue nil
+ end
+ end
+
+ def reopen(log = nil)
+ # reopen the same filename if no argument, do nothing for IO
+ log ||= @filename if @filename
+ if log
+ synchronize do
+ if @filename and @dev
+ @dev.close rescue nil # close only file opened by Logger
+ @filename = nil
+ end
+ set_dev(log)
+ end
+ end
+ self
+ end
+
+ private
+
+ def set_dev(log)
+ if log.respond_to?(:write) and log.respond_to?(:close)
+ @dev = log
+ if log.respond_to?(:path)
+ @filename = log.path
+ end
+ else
+ @dev = open_logfile(log)
+ @dev.sync = true
+ @dev.binmode if @binmode
+ @filename = log
+ end
+ end
+
+ def open_logfile(filename)
+ begin
+ File.open(filename, (File::WRONLY | File::APPEND))
+ rescue Errno::ENOENT
+ create_logfile(filename)
+ end
+ end
+
+ def create_logfile(filename)
+ begin
+ logdev = File.open(filename, (File::WRONLY | File::APPEND | File::CREAT | File::EXCL))
+ logdev.flock(File::LOCK_EX)
+ logdev.sync = true
+ logdev.binmode if @binmode
+ add_log_header(logdev)
+ logdev.flock(File::LOCK_UN)
+ rescue Errno::EEXIST
+ # file is created by another process
+ logdev = open_logfile(filename)
+ logdev.sync = true
+ end
+ logdev
+ end
+
+ def add_log_header(file)
+ file.write(
+ "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
+ ) if file.size == 0
+ end
+
+ def check_shift_log
+ if @shift_age.is_a?(Integer)
+ # Note: always returns false if '0'.
+ if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size)
+ lock_shift_log { shift_log_age }
+ end
+ else
+ now = Time.now
+ if now >= @next_rotate_time
+ @next_rotate_time = next_rotate_time(now, @shift_age)
+ lock_shift_log { shift_log_period(previous_period_end(now, @shift_age)) }
+ end
+ end
+ end
+
+ if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
+ def lock_shift_log
+ yield
+ end
+ else
+ def lock_shift_log
+ retry_limit = 8
+ retry_sleep = 0.1
+ begin
+ File.open(@filename, File::WRONLY | File::APPEND) do |lock|
+ lock.flock(File::LOCK_EX) # inter-process locking. will be unlocked at closing file
+ if File.identical?(@filename, lock) and File.identical?(lock, @dev)
+ yield # log shifting
+ else
+ # log shifted by another process (i-node before locking and i-node after locking are different)
+ @dev.close rescue nil
+ @dev = open_logfile(@filename)
+ @dev.sync = true
+ end
+ end
+ rescue Errno::ENOENT
+ # @filename file would not exist right after #rename and before #create_logfile
+ if retry_limit <= 0
+ warn("log rotation inter-process lock failed. #{$!}")
+ else
+ sleep retry_sleep
+ retry_limit -= 1
+ retry_sleep *= 2
+ retry
+ end
+ end
+ rescue
+ warn("log rotation inter-process lock failed. #{$!}")
+ end
+ end
+
+ def shift_log_age
+ (@shift_age-3).downto(0) do |i|
+ if FileTest.exist?("#{@filename}.#{i}")
+ File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}")
+ end
+ end
+ @dev.close rescue nil
+ File.rename("#{@filename}", "#{@filename}.0")
+ @dev = create_logfile(@filename)
+ return true
+ end
+
+ def shift_log_period(period_end)
+ suffix = period_end.strftime(@shift_period_suffix)
+ age_file = "#{@filename}.#{suffix}"
+ if FileTest.exist?(age_file)
+ # try to avoid filename crash caused by Timestamp change.
+ idx = 0
+ # .99 can be overridden; avoid too much file search with 'loop do'
+ while idx < 100
+ idx += 1
+ age_file = "#{@filename}.#{suffix}.#{idx}"
+ break unless FileTest.exist?(age_file)
+ end
+ end
+ @dev.close rescue nil
+ File.rename("#{@filename}", age_file)
+ @dev = create_logfile(@filename)
+ return true
+ end
+ end
+end
diff --git a/lib/logger/logger.gemspec b/lib/logger/logger.gemspec
new file mode 100644
index 0000000000..cd6d97de3d
--- /dev/null
+++ b/lib/logger/logger.gemspec
@@ -0,0 +1,29 @@
+begin
+ require_relative "lib/logger/version"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "logger"
+ spec.version = Logger::VERSION
+ spec.authors = ["Naotoshi Seo", "SHIBATA Hiroshi"]
+ spec.email = ["sonots@gmail.com", "hsbt@ruby-lang.org"]
+
+ spec.summary = %q{Provides a simple logging utility for outputting messages.}
+ spec.description = %q{Provides a simple logging utility for outputting messages.}
+ spec.homepage = "https://github.com/ruby/logger"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.files = Dir.glob("lib/**/*.rb") + ["logger.gemspec"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.required_ruby_version = ">= 2.3.0"
+
+ spec.add_development_dependency "bundler", ">= 0"
+ spec.add_development_dependency "rake", ">= 12.3.3"
+ spec.add_development_dependency "test-unit"
+ spec.add_development_dependency "rdoc"
+end
diff --git a/lib/logger/period.rb b/lib/logger/period.rb
new file mode 100644
index 0000000000..0a291dbbbe
--- /dev/null
+++ b/lib/logger/period.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+class Logger
+ module Period
+ module_function
+
+ SiD = 24 * 60 * 60
+
+ def next_rotate_time(now, shift_age)
+ case shift_age
+ when 'daily'
+ t = Time.mktime(now.year, now.month, now.mday) + SiD
+ when 'weekly'
+ t = Time.mktime(now.year, now.month, now.mday) + SiD * (7 - now.wday)
+ when 'monthly'
+ t = Time.mktime(now.year, now.month, 1) + SiD * 32
+ return Time.mktime(t.year, t.month, 1)
+ when 'now', 'everytime'
+ return now
+ else
+ raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime"
+ end
+ if t.hour.nonzero? or t.min.nonzero? or t.sec.nonzero?
+ hour = t.hour
+ t = Time.mktime(t.year, t.month, t.mday)
+ t += SiD if hour > 12
+ end
+ t
+ end
+
+ def previous_period_end(now, shift_age)
+ case shift_age
+ when 'daily'
+ t = Time.mktime(now.year, now.month, now.mday) - SiD / 2
+ when 'weekly'
+ t = Time.mktime(now.year, now.month, now.mday) - (SiD * now.wday + SiD / 2)
+ when 'monthly'
+ t = Time.mktime(now.year, now.month, 1) - SiD / 2
+ when 'now', 'everytime'
+ return now
+ else
+ raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime"
+ end
+ Time.mktime(t.year, t.month, t.mday, 23, 59, 59)
+ end
+ end
+end
diff --git a/lib/logger/severity.rb b/lib/logger/severity.rb
new file mode 100644
index 0000000000..b38afb7d22
--- /dev/null
+++ b/lib/logger/severity.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Logger
+ # Logging severity.
+ module Severity
+ # Low-level information, mostly for developers.
+ DEBUG = 0
+ # Generic (useful) information about system operation.
+ INFO = 1
+ # A warning.
+ WARN = 2
+ # A handleable error condition.
+ ERROR = 3
+ # An unhandleable error that results in a program crash.
+ FATAL = 4
+ # An unknown message that should always be logged.
+ UNKNOWN = 5
+ end
+end
diff --git a/lib/logger/version.rb b/lib/logger/version.rb
new file mode 100644
index 0000000000..e0f71830d2
--- /dev/null
+++ b/lib/logger/version.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+class Logger
+ VERSION = "1.4.3"
+end
diff --git a/lib/matrix.rb b/lib/matrix.rb
index 77c35b3475..32f1e233ce 100644
--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -12,126 +12,51 @@
# Original Documentation:: Gavin Sinclair (sourced from <i>Ruby in a Nutshell</i> (Matsumoto, O'Reilly))
##
-require "e2mmap.rb"
+require_relative "matrix/version"
module ExceptionForMatrix # :nodoc:
- extend Exception2MessageMapper
- def_e2message(TypeError, "wrong argument type %s (expected %s)")
- def_e2message(ArgumentError, "Wrong # of arguments(%d for %d)")
-
- def_exception("ErrDimensionMismatch", "\#{self.name} dimension mismatch")
- def_exception("ErrNotRegular", "Not Regular Matrix")
- def_exception("ErrOperationNotDefined", "Operation(%s) can\\'t be defined: %s op %s")
- def_exception("ErrOperationNotImplemented", "Sorry, Operation(%s) not implemented: %s op %s")
+ class ErrDimensionMismatch < StandardError
+ def initialize(val = nil)
+ if val
+ super(val)
+ else
+ super("Dimension mismatch")
+ end
+ end
+ end
+
+ class ErrNotRegular < StandardError
+ def initialize(val = nil)
+ if val
+ super(val)
+ else
+ super("Not Regular Matrix")
+ end
+ end
+ end
+
+ class ErrOperationNotDefined < StandardError
+ def initialize(vals)
+ if vals.is_a?(Array)
+ super("Operation(#{vals[0]}) can't be defined: #{vals[1]} op #{vals[2]}")
+ else
+ super(vals)
+ end
+ end
+ end
+
+ class ErrOperationNotImplemented < StandardError
+ def initialize(vals)
+ super("Sorry, Operation(#{vals[0]}) not implemented: #{vals[1]} op #{vals[2]}")
+ end
+ end
end
#
# The +Matrix+ class represents a mathematical matrix. It provides methods for creating
# matrices, operating on them arithmetically and algebraically,
-# and determining their mathematical properties (trace, rank, inverse, determinant).
-#
-# == Method Catalogue
-#
-# To create a matrix:
-# * Matrix[*rows]
-# * Matrix.[](*rows)
-# * Matrix.rows(rows, copy = true)
-# * Matrix.columns(columns)
-# * Matrix.build(row_count, column_count, &block)
-# * Matrix.diagonal(*values)
-# * Matrix.scalar(n, value)
-# * Matrix.identity(n)
-# * Matrix.unit(n)
-# * Matrix.I(n)
-# * Matrix.zero(n)
-# * Matrix.row_vector(row)
-# * Matrix.column_vector(column)
-# * Matrix.empty(row_count, column_count)
-# * Matrix.hstack(*matrices)
-# * Matrix.vstack(*matrices)
-#
-# To access Matrix elements/columns/rows/submatrices/properties:
-# * #[](i, j)
-# * #row_count (row_size)
-# * #column_count (column_size)
-# * #row(i)
-# * #column(j)
-# * #collect
-# * #map
-# * #each
-# * #each_with_index
-# * #find_index
-# * #minor(*param)
-# * #first_minor(row, column)
-# * #cofactor(row, column)
-# * #adjugate
-# * #laplace_expansion(row_or_column: num)
-# * #cofactor_expansion(row_or_column: num)
-#
-# Properties of a matrix:
-# * #diagonal?
-# * #empty?
-# * #hermitian?
-# * #lower_triangular?
-# * #normal?
-# * #orthogonal?
-# * #permutation?
-# * #real?
-# * #regular?
-# * #singular?
-# * #square?
-# * #symmetric?
-# * #unitary?
-# * #upper_triangular?
-# * #zero?
-#
-# Matrix arithmetic:
-# * #*(m)
-# * #+(m)
-# * #-(m)
-# * #/(m)
-# * #inverse
-# * #inv
-# * #**
-# * #+@
-# * #-@
-#
-# Matrix functions:
-# * #determinant
-# * #det
-# * #hstack(*matrices)
-# * #rank
-# * #round
-# * #trace
-# * #tr
-# * #transpose
-# * #t
-# * #vstack(*matrices)
-#
-# Matrix decompositions:
-# * #eigen
-# * #eigensystem
-# * #lup
-# * #lup_decomposition
-#
-# Complex arithmetic:
-# * conj
-# * conjugate
-# * imag
-# * imaginary
-# * real
-# * rect
-# * rectangular
-#
-# Conversion to other data types:
-# * #coerce(other)
-# * #row_vectors
-# * #column_vectors
-# * #to_a
-#
-# String representations:
-# * #to_s
-# * #inspect
+# and determining their mathematical properties such as trace, rank, inverse, determinant,
+# or eigensystem.
#
class Matrix
include Enumerable
@@ -147,8 +72,8 @@ class Matrix
#
# Creates a matrix where each argument is a row.
# Matrix[ [25, 93], [-1, 66] ]
- # => 25 93
- # -1 66
+ # # => 25 93
+ # # -1 66
#
def Matrix.[](*rows)
rows(rows, false)
@@ -159,8 +84,8 @@ class Matrix
# of the matrix. If the optional argument +copy+ is false, use the given
# arrays as the internal structure of the matrix without copying.
# Matrix.rows([[25, 93], [-1, 66]])
- # => 25 93
- # -1 66
+ # # => 25 93
+ # # -1 66
#
def Matrix.rows(rows, copy = true)
rows = convert_to_array(rows, copy)
@@ -177,8 +102,8 @@ class Matrix
#
# Creates a matrix using +columns+ as an array of column vectors.
# Matrix.columns([[25, 93], [-1, 66]])
- # => 25 -1
- # 93 66
+ # # => 25 -1
+ # # 93 66
#
def Matrix.columns(columns)
rows(columns, false).transpose
@@ -191,9 +116,9 @@ class Matrix
# Returns an enumerator if no block is given.
#
# m = Matrix.build(2, 4) {|row, col| col - row }
- # => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
+ # # => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
# m = Matrix.build(3) { rand }
- # => a 3x3 matrix with random elements
+ # # => a 3x3 matrix with random elements
#
def Matrix.build(row_count, column_count = row_count)
row_count = CoercionHelper.coerce_to_int(row_count)
@@ -211,9 +136,9 @@ class Matrix
#
# Creates a matrix where the diagonal elements are composed of +values+.
# Matrix.diagonal(9, 5, -3)
- # => 9 0 0
- # 0 5 0
- # 0 0 -3
+ # # => 9 0 0
+ # # 0 5 0
+ # # 0 0 -3
#
def Matrix.diagonal(*values)
size = values.size
@@ -230,8 +155,8 @@ class Matrix
# Creates an +n+ by +n+ diagonal matrix where each diagonal element is
# +value+.
# Matrix.scalar(2, 5)
- # => 5 0
- # 0 5
+ # # => 5 0
+ # # 0 5
#
def Matrix.scalar(n, value)
diagonal(*Array.new(n, value))
@@ -240,22 +165,22 @@ class Matrix
#
# Creates an +n+ by +n+ identity matrix.
# Matrix.identity(2)
- # => 1 0
- # 0 1
+ # # => 1 0
+ # # 0 1
#
def Matrix.identity(n)
scalar(n, 1)
end
class << Matrix
- alias unit identity
- alias I identity
+ alias_method :unit, :identity
+ alias_method :I, :identity
end
#
# Creates a zero matrix.
# Matrix.zero(2)
- # => 0 0
- # 0 0
+ # # => 0 0
+ # # 0 0
#
def Matrix.zero(row_count, column_count = row_count)
rows = Array.new(row_count){Array.new(column_count, 0)}
@@ -266,7 +191,7 @@ class Matrix
# Creates a single-row matrix where the values of that row are as given in
# +row+.
# Matrix.row_vector([4,5,6])
- # => 4 5 6
+ # # => 4 5 6
#
def Matrix.row_vector(row)
row = convert_to_array(row)
@@ -277,9 +202,9 @@ class Matrix
# Creates a single-column matrix where the values of that column are as given
# in +column+.
# Matrix.column_vector([4,5,6])
- # => 4
- # 5
- # 6
+ # # => 4
+ # # 5
+ # # 6
#
def Matrix.column_vector(column)
column = convert_to_array(column)
@@ -292,12 +217,12 @@ class Matrix
#
# m = Matrix.empty(2, 0)
# m == Matrix[ [], [] ]
- # => true
+ # # => true
# n = Matrix.empty(0, 3)
# n == Matrix.columns([ [], [], [] ])
- # => true
+ # # => true
# m * n
- # => Matrix[[0, 0, 0], [0, 0, 0]]
+ # # => Matrix[[0, 0, 0], [0, 0, 0]]
#
def Matrix.empty(row_count = 0, column_count = 0)
raise ArgumentError, "One size must be 0" if column_count != 0 && row_count != 0
@@ -314,10 +239,10 @@ class Matrix
# Matrix.vstack(x, y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]]
#
def Matrix.vstack(x, *matrices)
- raise TypeError, "Expected a Matrix, got a #{x.class}" unless x.is_a?(Matrix)
+ x = CoercionHelper.coerce_to_matrix(x)
result = x.send(:rows).map(&:dup)
matrices.each do |m|
- raise TypeError, "Expected a Matrix, got a #{m.class}" unless m.is_a?(Matrix)
+ m = CoercionHelper.coerce_to_matrix(m)
if m.column_count != x.column_count
raise ErrDimensionMismatch, "The given matrices must have #{x.column_count} columns, but one has #{m.column_count}"
end
@@ -335,11 +260,11 @@ class Matrix
# Matrix.hstack(x, y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]]
#
def Matrix.hstack(x, *matrices)
- raise TypeError, "Expected a Matrix, got a #{x.class}" unless x.is_a?(Matrix)
+ x = CoercionHelper.coerce_to_matrix(x)
result = x.send(:rows).map(&:dup)
total_column_count = x.column_count
matrices.each do |m|
- raise TypeError, "Expected a Matrix, got a #{m.class}" unless m.is_a?(Matrix)
+ m = CoercionHelper.coerce_to_matrix(m)
if m.row_count != x.row_count
raise ErrDimensionMismatch, "The given matrices must have #{x.row_count} rows, but one has #{m.row_count}"
end
@@ -351,8 +276,48 @@ class Matrix
new result, total_column_count
end
+ # :call-seq:
+ # Matrix.combine(*matrices) { |*elements| ... }
+ #
+ # Create a matrix by combining matrices entrywise, using the given block
#
- # Matrix.new is private; use Matrix.rows, columns, [], etc... to create.
+ # x = Matrix[[6, 6], [4, 4]]
+ # y = Matrix[[1, 2], [3, 4]]
+ # Matrix.combine(x, y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
+ #
+ def Matrix.combine(*matrices)
+ return to_enum(__method__, *matrices) unless block_given?
+
+ return Matrix.empty if matrices.empty?
+ matrices.map!(&CoercionHelper.method(:coerce_to_matrix))
+ x = matrices.first
+ matrices.each do |m|
+ raise ErrDimensionMismatch unless x.row_count == m.row_count && x.column_count == m.column_count
+ end
+
+ rows = Array.new(x.row_count) do |i|
+ Array.new(x.column_count) do |j|
+ yield matrices.map{|m| m[i,j]}
+ end
+ end
+ new rows, x.column_count
+ end
+
+ # :call-seq:
+ # combine(*other_matrices) { |*elements| ... }
+ #
+ # Creates new matrix by combining with <i>other_matrices</i> entrywise,
+ # using the given block.
+ #
+ # x = Matrix[[6, 6], [4, 4]]
+ # y = Matrix[[1, 2], [3, 4]]
+ # x.combine(y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
+ def combine(*matrices, &block)
+ Matrix.combine(self, *matrices, &block)
+ end
+
+ #
+ # Matrix.new is private; use ::rows, ::columns, ::[], etc... to create.
#
def initialize(rows, column_count = rows[0].size)
# No checking is done at this point. rows must be an Array of Arrays.
@@ -362,10 +327,9 @@ class Matrix
@column_count = column_count
end
- def new_matrix(rows, column_count = rows[0].size) # :nodoc:
+ private def new_matrix(rows, column_count = rows[0].size) # :nodoc:
self.class.send(:new, rows, column_count) # bypass privacy of Matrix.new
end
- private :new_matrix
#
# Returns element (+i+,+j+) of the matrix. That is: row +i+, column +j+.
@@ -376,12 +340,107 @@ class Matrix
alias element []
alias component []
+ #
+ # :call-seq:
+ # matrix[range, range] = matrix/element
+ # matrix[range, integer] = vector/column_matrix/element
+ # matrix[integer, range] = vector/row_matrix/element
+ # matrix[integer, integer] = element
+ #
+ # Set element or elements of matrix.
def []=(i, j, v)
- @rows[i][j] = v
+ raise FrozenError, "can't modify frozen Matrix" if frozen?
+ rows = check_range(i, :row) or row = check_int(i, :row)
+ columns = check_range(j, :column) or column = check_int(j, :column)
+ if rows && columns
+ set_row_and_col_range(rows, columns, v)
+ elsif rows
+ set_row_range(rows, column, v)
+ elsif columns
+ set_col_range(row, columns, v)
+ else
+ set_value(row, column, v)
+ end
end
alias set_element []=
alias set_component []=
- private :[]=, :set_element, :set_component
+ private :set_element, :set_component
+
+ # Returns range or nil
+ private def check_range(val, direction)
+ return unless val.is_a?(Range)
+ count = direction == :row ? row_count : column_count
+ CoercionHelper.check_range(val, count, direction)
+ end
+
+ private def check_int(val, direction)
+ count = direction == :row ? row_count : column_count
+ CoercionHelper.check_int(val, count, direction)
+ end
+
+ private def set_value(row, col, value)
+ raise ErrDimensionMismatch, "Expected a a value, got a #{value.class}" if value.respond_to?(:to_matrix)
+
+ @rows[row][col] = value
+ end
+
+ private def set_row_and_col_range(row_range, col_range, value)
+ if value.is_a?(Matrix)
+ if row_range.size != value.row_count || col_range.size != value.column_count
+ raise ErrDimensionMismatch, [
+ 'Expected a Matrix of dimensions',
+ "#{row_range.size}x#{col_range.size}",
+ 'got',
+ "#{value.row_count}x#{value.column_count}",
+ ].join(' ')
+ end
+ source = value.instance_variable_get :@rows
+ row_range.each_with_index do |row, i|
+ @rows[row][col_range] = source[i]
+ end
+ elsif value.is_a?(Vector)
+ raise ErrDimensionMismatch, 'Expected a Matrix or a value, got a Vector'
+ else
+ value_to_set = Array.new(col_range.size, value)
+ row_range.each do |i|
+ @rows[i][col_range] = value_to_set
+ end
+ end
+ end
+
+ private def set_row_range(row_range, col, value)
+ if value.is_a?(Vector)
+ raise ErrDimensionMismatch unless row_range.size == value.size
+ set_column_vector(row_range, col, value)
+ elsif value.is_a?(Matrix)
+ raise ErrDimensionMismatch unless value.column_count == 1
+ value = value.column(0)
+ raise ErrDimensionMismatch unless row_range.size == value.size
+ set_column_vector(row_range, col, value)
+ else
+ @rows[row_range].each{|e| e[col] = value }
+ end
+ end
+
+ private def set_column_vector(row_range, col, value)
+ value.each_with_index do |e, index|
+ r = row_range.begin + index
+ @rows[r][col] = e
+ end
+ end
+
+ private def set_col_range(row, col_range, value)
+ value = if value.is_a?(Vector)
+ value.to_a
+ elsif value.is_a?(Matrix)
+ raise ErrDimensionMismatch unless value.row_count == 1
+ value.row(0).to_a
+ else
+ Array.new(col_range.size, value)
+ end
+ raise ErrDimensionMismatch unless col_range.size == value.size
+ @rows[row][col_range] = value
+ end
#
# Returns the number of rows.
@@ -434,16 +493,49 @@ class Matrix
#
# Returns a matrix that is the result of iteration of the given block over all
# elements of the matrix.
+ # Elements can be restricted by passing an argument:
+ # * :all (default): yields all elements
+ # * :diagonal: yields only elements on the diagonal
+ # * :off_diagonal: yields all elements except on the diagonal
+ # * :lower: yields only elements on or below the diagonal
+ # * :strict_lower: yields only elements below the diagonal
+ # * :strict_upper: yields only elements above the diagonal
+ # * :upper: yields only elements on or above the diagonal
# Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
- # => 1 4
- # 9 16
+ # # => 1 4
+ # # 9 16
#
- def collect(&block) # :yield: e
- return to_enum(:collect) unless block_given?
- rows = @rows.collect{|row| row.collect(&block)}
- new_matrix rows, column_count
+ def collect(which = :all, &block) # :yield: e
+ return to_enum(:collect, which) unless block_given?
+ dup.collect!(which, &block)
+ end
+ alias_method :map, :collect
+
+ #
+ # Invokes the given block for each element of matrix, replacing the element with the value
+ # returned by the block.
+ # Elements can be restricted by passing an argument:
+ # * :all (default): yields all elements
+ # * :diagonal: yields only elements on the diagonal
+ # * :off_diagonal: yields all elements except on the diagonal
+ # * :lower: yields only elements on or below the diagonal
+ # * :strict_lower: yields only elements below the diagonal
+ # * :strict_upper: yields only elements above the diagonal
+ # * :upper: yields only elements on or above the diagonal
+ #
+ def collect!(which = :all)
+ return to_enum(:collect!, which) unless block_given?
+ raise FrozenError, "can't modify frozen Matrix" if frozen?
+ each_with_index(which){ |e, row_index, col_index| @rows[row_index][col_index] = yield e }
+ end
+
+ alias map! collect!
+
+ def freeze
+ @rows.each(&:freeze).freeze
+
+ super
end
- alias map collect
#
# Yields all elements of the matrix, starting with those of the first row,
@@ -457,16 +549,15 @@ class Matrix
# * :strict_upper: yields only elements above the diagonal
# * :upper: yields only elements on or above the diagonal
#
- # Matrix[ [1,2], [3,4] ].each { |e| puts e }
- # # => prints the numbers 1 to 4
- # Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
+ # Matrix[ [1,2], [3,4] ].each { |e| puts e }
+ # # => prints the numbers 1 to 4
+ # Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
#
- def each(which = :all) # :yield: e
+ def each(which = :all, &block) # :yield: e
return to_enum :each, which unless block_given?
last = column_count - 1
case which
when :all
- block = Proc.new
@rows.each do |row|
row.each(&block)
end
@@ -609,8 +700,8 @@ class Matrix
# * row_range, col_range
#
# Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
- # => 9 0 0
- # 0 5 0
+ # # => 9 0 0
+ # # 0 5 0
#
# Like Array#[], negative indices count backward from the end of the
# row or column (-1 is the last element). Returns nil if the starting
@@ -653,9 +744,9 @@ class Matrix
# Returns the submatrix obtained by deleting the specified row and column.
#
# Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
- # => 9 0 0
- # 0 0 0
- # 0 0 4
+ # # => 9 0 0
+ # # 0 0 0
+ # # 0 0 4
#
def first_minor(row, column)
raise RuntimeError, "first_minor of empty matrix is not defined" if empty?
@@ -682,11 +773,11 @@ class Matrix
# the first minor by (-1)**(row + column).
#
# Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
- # => -108
+ # # => -108
#
def cofactor(row, column)
raise RuntimeError, "cofactor of empty matrix is not defined" if empty?
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
det_of_minor = first_minor(row, column).determinant
det_of_minor * (-1) ** (row + column)
@@ -696,11 +787,11 @@ class Matrix
# Returns the adjugate of the matrix.
#
# Matrix[ [7,6],[3,9] ].adjugate
- # => 9 -6
- # -3 7
+ # # => 9 -6
+ # # -3 7
#
def adjugate
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
Matrix.build(row_count, column_count) do |row, column|
cofactor(column, row)
end
@@ -710,10 +801,10 @@ class Matrix
# Returns the Laplace expansion along given row or column.
#
# Matrix[[7,6], [3,9]].laplace_expansion(column: 1)
- # => 45
+ # # => 45
#
# Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0)
- # => Vector[3, -2]
+ # # => Vector[3, -2]
#
#
def laplace_expansion(row: nil, column: nil)
@@ -723,7 +814,7 @@ class Matrix
raise ArgumentError, "exactly one the row or column arguments must be specified"
end
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
raise RuntimeError, "laplace_expansion of empty matrix is not defined" if empty?
unless 0 <= num && num < row_count
@@ -746,7 +837,7 @@ class Matrix
# Raises an error if matrix is not square.
#
def diagonal?
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
each(:off_diagonal).all?(&:zero?)
end
@@ -763,7 +854,7 @@ class Matrix
# Raises an error if matrix is not square.
#
def hermitian?
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
each_with_index(:upper).all? do |e, row, col|
e == rows[col][row].conj
end
@@ -781,7 +872,7 @@ class Matrix
# Raises an error if matrix is not square.
#
def normal?
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
rows.each_with_index do |row_i, i|
rows.each_with_index do |row_j, j|
s = 0
@@ -799,12 +890,13 @@ class Matrix
# Raises an error if matrix is not square.
#
def orthogonal?
- Matrix.Raise ErrDimensionMismatch unless square?
- rows.each_with_index do |row, i|
- column_count.times do |j|
+ raise ErrDimensionMismatch unless square?
+
+ rows.each_with_index do |row_i, i|
+ rows.each_with_index do |row_j, j|
s = 0
row_count.times do |k|
- s += row[k] * rows[k][j]
+ s += row_i[k] * row_j[k]
end
return false unless s == (i == j ? 1 : 0)
end
@@ -817,7 +909,7 @@ class Matrix
# Raises an error if matrix is not square.
#
def permutation?
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
cols = Array.new(column_count)
rows.each_with_index do |row, i|
found = false
@@ -867,7 +959,7 @@ class Matrix
# Raises an error if matrix is not square.
#
def symmetric?
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
each_with_index(:strict_upper) do |e, row, col|
return false if e != rows[col][row]
end
@@ -875,16 +967,29 @@ class Matrix
end
#
+ # Returns +true+ if this is an antisymmetric matrix.
+ # Raises an error if matrix is not square.
+ #
+ def antisymmetric?
+ raise ErrDimensionMismatch unless square?
+ each_with_index(:upper) do |e, row, col|
+ return false unless e == -rows[col][row]
+ end
+ true
+ end
+ alias_method :skew_symmetric?, :antisymmetric?
+
+ #
# Returns +true+ if this is a unitary matrix
# Raises an error if matrix is not square.
#
def unitary?
- Matrix.Raise ErrDimensionMismatch unless square?
- rows.each_with_index do |row, i|
- column_count.times do |j|
+ raise ErrDimensionMismatch unless square?
+ rows.each_with_index do |row_i, i|
+ rows.each_with_index do |row_j, j|
s = 0
row_count.times do |k|
- s += row[k].conj * rows[k][j]
+ s += row_i[k].conj * row_j[k]
end
return false unless s == (i == j ? 1 : 0)
end
@@ -926,12 +1031,11 @@ class Matrix
end
#
- # Returns a clone of the matrix, so that the contents of each do not reference
- # identical objects.
- # There should be no good reason to do this since Matrices are immutable.
+ # Called for dup & clone.
#
- def clone
- new_matrix @rows.map(&:dup), column_count
+ private def initialize_copy(m)
+ super
+ @rows = @rows.map(&:dup) unless frozen?
end
#
@@ -948,31 +1052,33 @@ class Matrix
#
# Matrix multiplication.
# Matrix[[2,4], [6,8]] * Matrix.identity(2)
- # => 2 4
- # 6 8
+ # # => 2 4
+ # # 6 8
#
def *(m) # m is matrix or vector or number
case(m)
when Numeric
- rows = @rows.collect {|row|
+ new_rows = @rows.collect {|row|
row.collect {|e| e * m }
}
- return new_matrix rows, column_count
+ return new_matrix new_rows, column_count
when Vector
m = self.class.column_vector(m)
r = self * m
return r.column(0)
when Matrix
- Matrix.Raise ErrDimensionMismatch if column_count != m.row_count
-
- rows = Array.new(row_count) {|i|
- Array.new(m.column_count) {|j|
- (0 ... column_count).inject(0) do |vij, k|
- vij + self[i, k] * m[k, j]
+ raise ErrDimensionMismatch if column_count != m.row_count
+ m_rows = m.rows
+ new_rows = rows.map do |row_i|
+ Array.new(m.column_count) do |j|
+ vij = 0
+ column_count.times do |k|
+ vij += row_i[k] * m_rows[k][j]
end
- }
- }
- return new_matrix rows, m.column_count
+ vij
+ end
+ end
+ return new_matrix new_rows, m.column_count
else
return apply_through_coercion(m, __method__)
end
@@ -981,13 +1087,13 @@ class Matrix
#
# Matrix addition.
# Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
- # => 6 0
- # -4 12
+ # # => 6 0
+ # # -4 12
#
def +(m)
case m
when Numeric
- Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class
+ raise ErrOperationNotDefined, ["+", self.class, m.class]
when Vector
m = self.class.column_vector(m)
when Matrix
@@ -995,7 +1101,7 @@ class Matrix
return apply_through_coercion(m, __method__)
end
- Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
+ raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
rows = Array.new(row_count) {|i|
Array.new(column_count) {|j|
@@ -1008,13 +1114,13 @@ class Matrix
#
# Matrix subtraction.
# Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
- # => -8 2
- # 8 1
+ # # => -8 2
+ # # 8 1
#
def -(m)
case m
when Numeric
- Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class
+ raise ErrOperationNotDefined, ["-", self.class, m.class]
when Vector
m = self.class.column_vector(m)
when Matrix
@@ -1022,7 +1128,7 @@ class Matrix
return apply_through_coercion(m, __method__)
end
- Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
+ raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
rows = Array.new(row_count) {|i|
Array.new(column_count) {|j|
@@ -1035,8 +1141,8 @@ class Matrix
#
# Matrix division (multiplication by the inverse).
# Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
- # => -7 1
- # -3 -6
+ # # => -7 1
+ # # -3 -6
#
def /(other)
case other
@@ -1053,18 +1159,29 @@ class Matrix
end
#
+ # Hadamard product
+ # Matrix[[1,2], [3,4]].hadamard_product(Matrix[[1,2], [3,2]])
+ # # => 1 4
+ # # 9 8
+ #
+ def hadamard_product(m)
+ combine(m){|a, b| a * b}
+ end
+ alias_method :entrywise_product, :hadamard_product
+
+ #
# Returns the inverse of the matrix.
# Matrix[[-1, -1], [0, -1]].inverse
- # => -1 1
- # 0 -1
+ # # => -1 1
+ # # 0 -1
#
def inverse
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
self.class.I(row_count).send(:inverse_from, self)
end
- alias inv inverse
+ alias_method :inv, :inverse
- def inverse_from(src) # :nodoc:
+ private def inverse_from(src) # :nodoc:
last = row_count - 1
a = src.to_a
@@ -1078,7 +1195,7 @@ class Matrix
akk = v
end
end
- Matrix.Raise ErrNotRegular if akk == 0
+ raise ErrNotRegular if akk == 0
if i != k
a[i], a[k] = a[k], a[i]
@rows[i], @rows[k] = @rows[k], @rows[i]
@@ -1107,7 +1224,6 @@ class Matrix
end
self
end
- private :inverse_from
#
# Matrix exponentiation.
@@ -1115,29 +1231,52 @@ class Matrix
# Non integer exponents will be handled by diagonalizing the matrix.
#
# Matrix[[7,6], [3,9]] ** 2
- # => 67 96
- # 48 99
+ # # => 67 96
+ # # 48 99
#
- def **(other)
- case other
+ def **(exp)
+ case exp
when Integer
- x = self
- if other <= 0
- x = self.inverse
- return self.class.identity(self.column_count) if other == 0
- other = -other
- end
- z = nil
- loop do
- z = z ? z * x : x if other[0] == 1
- return z if (other >>= 1).zero?
- x *= x
+ case
+ when exp == 0
+ _make_sure_it_is_invertible = inverse
+ self.class.identity(column_count)
+ when exp < 0
+ inverse.power_int(-exp)
+ else
+ power_int(exp)
end
when Numeric
v, d, v_inv = eigensystem
- v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** other}) * v_inv
+ v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** exp}) * v_inv
+ else
+ raise ErrOperationNotDefined, ["**", self.class, exp.class]
+ end
+ end
+
+ protected def power_int(exp)
+ # assumes `exp` is an Integer > 0
+ #
+ # Previous algorithm:
+ # build M**2, M**4 = (M**2)**2, M**8, ... and multiplying those you need
+ # e.g. M**0b1011 = M**11 = M * M**2 * M**8
+ # ^ ^
+ # (highlighted the 2 out of 5 multiplications involving `M * x`)
+ #
+ # Current algorithm has same number of multiplications but with lower exponents:
+ # M**11 = M * (M * M**4)**2
+ # ^ ^ ^
+ # (highlighted the 3 out of 5 multiplications involving `M * x`)
+ #
+ # This should be faster for all (non nil-potent) matrices.
+ case
+ when exp == 1
+ self
+ when exp.odd?
+ self * power_int(exp - 1)
else
- Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class
+ sqrt = power_int(exp / 2)
+ sqrt * sqrt
end
end
@@ -1145,10 +1284,22 @@ class Matrix
self
end
+ # Unary matrix negation.
+ #
+ # -Matrix[[1,5], [4,2]]
+ # # => -1 -5
+ # # -4 -2
def -@
collect {|e| -e }
end
+ #
+ # Returns the absolute value elementwise
+ #
+ def abs
+ collect(&:abs)
+ end
+
#--
# MATRIX FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#++
@@ -1161,10 +1312,10 @@ class Matrix
# Consider using exact types like Rational or BigDecimal instead.
#
# Matrix[[7,6], [3,9]].determinant
- # => 45
+ # # => 45
#
def determinant
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
m = @rows
case row_count
# Up to 4x4, give result using Laplacian expansion by minors.
@@ -1214,7 +1365,7 @@ class Matrix
# with smaller bignums (if any), while a matrix of Float will usually have
# intermediate results with better precision.
#
- def determinant_bareiss
+ private def determinant_bareiss
size = row_count
last = size - 1
a = to_a
@@ -1240,16 +1391,15 @@ class Matrix
end
sign * pivot
end
- private :determinant_bareiss
#
# deprecated; use Matrix#determinant
#
def determinant_e
- warn "#{caller(1)[0]}: warning: Matrix#determinant_e is deprecated; use #determinant"
+ warn "Matrix#determinant_e is deprecated; use #determinant", uplevel: 1
determinant
end
- alias det_e determinant_e
+ alias_method :det_e, :determinant_e
#
# Returns a new matrix resulting by stacking horizontally
@@ -1270,7 +1420,7 @@ class Matrix
# Consider using exact types like Rational or BigDecimal instead.
#
# Matrix[[7,6], [3,9]].rank
- # => 2
+ # # => 2
#
def rank
# We currently use Bareiss' multistep integer-preserving gaussian elimination
@@ -1304,7 +1454,7 @@ class Matrix
# deprecated; use Matrix#rank
#
def rank_e
- warn "#{caller(1)[0]}: warning: Matrix#rank_e is deprecated; use #rank"
+ warn "Matrix#rank_e is deprecated; use #rank", uplevel: 1
rank
end
@@ -1318,31 +1468,31 @@ class Matrix
#
# Returns the trace (sum of diagonal elements) of the matrix.
# Matrix[[7,6], [3,9]].trace
- # => 16
+ # # => 16
#
def trace
- Matrix.Raise ErrDimensionMismatch unless square?
+ raise ErrDimensionMismatch unless square?
(0...column_count).inject(0) do |tr, i|
tr + @rows[i][i]
end
end
- alias tr trace
+ alias_method :tr, :trace
#
# Returns the transpose of the matrix.
# Matrix[[1,2], [3,4], [5,6]]
- # => 1 2
- # 3 4
- # 5 6
+ # # => 1 2
+ # # 3 4
+ # # 5 6
# Matrix[[1,2], [3,4], [5,6]].transpose
- # => 1 3 5
- # 2 4 6
+ # # => 1 3 5
+ # # 2 4 6
#
def transpose
return self.class.empty(column_count, 0) if row_count.zero?
new_matrix @rows.transpose, row_count
end
- alias t transpose
+ alias_method :t, :transpose
#
# Returns a new matrix resulting by stacking vertically
@@ -1371,7 +1521,7 @@ class Matrix
def eigensystem
EigenvalueDecomposition.new(self)
end
- alias eigen eigensystem
+ alias_method :eigen, :eigensystem
#
# Returns the LUP decomposition of the matrix; see +LUPDecomposition+.
@@ -1386,7 +1536,7 @@ class Matrix
def lup
LUPDecomposition.new(self)
end
- alias lup_decomposition lup
+ alias_method :lup_decomposition, :lup
#--
# COMPLEX ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
@@ -1395,39 +1545,50 @@ class Matrix
#
# Returns the conjugate of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
- # => 1+2i i 0
- # 1 2 3
+ # # => 1+2i i 0
+ # # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].conjugate
- # => 1-2i -i 0
- # 1 2 3
+ # # => 1-2i -i 0
+ # # 1 2 3
#
def conjugate
collect(&:conjugate)
end
- alias conj conjugate
+ alias_method :conj, :conjugate
+
+ #
+ # Returns the adjoint of the matrix.
+ #
+ # Matrix[ [i,1],[2,-i] ].adjoint
+ # # => -i 2
+ # # 1 i
+ #
+ def adjoint
+ conjugate.transpose
+ end
#
# Returns the imaginary part of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
- # => 1+2i i 0
- # 1 2 3
+ # # => 1+2i i 0
+ # # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
- # => 2i i 0
- # 0 0 0
+ # # => 2i i 0
+ # # 0 0 0
#
def imaginary
collect(&:imaginary)
end
- alias imag imaginary
+ alias_method :imag, :imaginary
#
# Returns the real part of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
- # => 1+2i i 0
- # 1 2 3
+ # # => 1+2i i 0
+ # # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real
- # => 1 0 0
- # 1 2 3
+ # # => 1 0 0
+ # # 1 2 3
#
def real
collect(&:real)
@@ -1437,12 +1598,12 @@ class Matrix
# Returns an array containing matrices corresponding to the real and imaginary
# parts of the matrix
#
- # m.rect == [m.real, m.imag] # ==> true for all matrices m
+ # m.rect == [m.real, m.imag] # ==> true for all matrices m
#
def rect
[real, imag]
end
- alias rectangular rect
+ alias_method :rectangular, :rect
#--
# CONVERTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@@ -1483,24 +1644,40 @@ class Matrix
end
#
+ # Explicit conversion to a Matrix. Returns self
+ #
+ def to_matrix
+ self
+ end
+
+ #
# Returns an array of arrays that describe the rows of the matrix.
#
def to_a
@rows.collect(&:dup)
end
+ # Deprecated.
+ #
+ # Use <code>map(&:to_f)</code>
def elements_to_f
- warn "#{caller(1)[0]}: warning: Matrix#elements_to_f is deprecated, use map(&:to_f)"
+ warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1
map(&:to_f)
end
+ # Deprecated.
+ #
+ # Use <code>map(&:to_i)</code>
def elements_to_i
- warn "#{caller(1)[0]}: warning: Matrix#elements_to_i is deprecated, use map(&:to_i)"
+ warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1
map(&:to_i)
end
+ # Deprecated.
+ #
+ # Use <code>map(&:to_r)</code>
def elements_to_r
- warn "#{caller(1)[0]}: warning: Matrix#elements_to_r is deprecated, use map(&:to_r)"
+ warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1
map(&:to_r)
end
@@ -1539,7 +1716,7 @@ class Matrix
# Converts the obj to an Array. If copy is set to true
# a copy of obj will be made if necessary.
#
- def convert_to_array(obj, copy = false) # :nodoc:
+ private def convert_to_array(obj, copy = false) # :nodoc:
case obj
when Array
copy ? obj.dup : obj
@@ -1555,7 +1732,6 @@ class Matrix
converted
end
end
- private :convert_to_array
end
extend ConversionHelper
@@ -1565,14 +1741,13 @@ class Matrix
# Applies the operator +oper+ with argument +obj+
# through coercion of +obj+
#
- def apply_through_coercion(obj, oper)
+ private def apply_through_coercion(obj, oper)
coercion = obj.coerce(self)
raise TypeError unless coercion.is_a?(Array) && coercion.length == 2
coercion[0].public_send(oper, coercion[1])
rescue
raise TypeError, "#{obj.inspect} can't be coerced into #{self.class}"
end
- private :apply_through_coercion
#
# Helper method to coerce a value into a specific class.
@@ -1582,7 +1757,7 @@ class Matrix
#
def self.coerce_to(obj, cls, meth) # :nodoc:
return obj if obj.kind_of?(cls)
-
+ raise TypeError, "Expected a #{cls} but got a #{obj.class}" unless obj.respond_to? meth
begin
ret = obj.__send__(meth)
rescue Exception => e
@@ -1596,6 +1771,30 @@ class Matrix
def self.coerce_to_int(obj)
coerce_to(obj, Integer, :to_int)
end
+
+ def self.coerce_to_matrix(obj)
+ coerce_to(obj, Matrix, :to_matrix)
+ end
+
+ # Returns `nil` for non Ranges
+ # Checks range validity, return canonical range with 0 <= begin <= end < count
+ def self.check_range(val, count, kind)
+ canonical = (val.begin + (val.begin < 0 ? count : 0))..
+ (val.end ? val.end + (val.end < 0 ? count : 0) - (val.exclude_end? ? 1 : 0)
+ : count - 1)
+ unless 0 <= canonical.begin && canonical.begin <= canonical.end && canonical.end < count
+ raise IndexError, "given range #{val} is outside of #{kind} dimensions: 0...#{count}"
+ end
+ canonical
+ end
+
+ def self.check_int(val, count, kind)
+ val = CoercionHelper.coerce_to_int(val)
+ if val >= count || val < -count
+ raise IndexError, "given #{kind} #{val} is outside of #{-count}...#{count}"
+ end
+ val
+ end
end
include CoercionHelper
@@ -1616,7 +1815,7 @@ class Matrix
when Numeric
Scalar.new(@value + other)
when Vector, Matrix
- Scalar.Raise ErrOperationNotDefined, "+", @value.class, other.class
+ raise ErrOperationNotDefined, ["+", @value.class, other.class]
else
apply_through_coercion(other, __method__)
end
@@ -1627,7 +1826,7 @@ class Matrix
when Numeric
Scalar.new(@value - other)
when Vector, Matrix
- Scalar.Raise ErrOperationNotDefined, "-", @value.class, other.class
+ raise ErrOperationNotDefined, ["-", @value.class, other.class]
else
apply_through_coercion(other, __method__)
end
@@ -1649,7 +1848,7 @@ class Matrix
when Numeric
Scalar.new(@value / other)
when Vector
- Scalar.Raise ErrOperationNotDefined, "/", @value.class, other.class
+ raise ErrOperationNotDefined, ["/", @value.class, other.class]
when Matrix
self * other.inverse
else
@@ -1662,10 +1861,10 @@ class Matrix
when Numeric
Scalar.new(@value ** other)
when Vector
- Scalar.Raise ErrOperationNotDefined, "**", @value.class, other.class
+ raise ErrOperationNotDefined, ["**", @value.class, other.class]
when Matrix
#other.powered_by(self)
- Scalar.Raise ErrOperationNotImplemented, "**", @value.class, other.class
+ raise ErrOperationNotImplemented, ["**", @value.class, other.class]
else
apply_through_coercion(other, __method__)
end
@@ -1690,6 +1889,9 @@ end
# To access elements:
# * #[](i)
#
+# To set elements:
+# * #[]=(i, v)
+#
# To enumerate the elements:
# * #each2(v)
# * #collect2(v)
@@ -1709,11 +1911,13 @@ end
# * #-@
#
# Vector functions:
-# * #inner_product(v), dot(v)
-# * #cross_product(v), cross(v)
+# * #inner_product(v), #dot(v)
+# * #cross_product(v), #cross(v)
# * #collect
+# * #collect!
# * #magnitude
# * #map
+# * #map!
# * #map2(v)
# * #norm
# * #normalize
@@ -1773,7 +1977,7 @@ class Vector
#
# Return a zero vector.
#
- # Vector.zero(3) => Vector[0, 0, 0]
+ # Vector.zero(3) # => Vector[0, 0, 0]
#
def Vector.zero(size)
raise ArgumentError, "invalid size (#{size} for 0..)" if size < 0
@@ -1792,7 +1996,11 @@ class Vector
# ACCESSING
#
- # Returns element number +i+ (starting at zero) of the vector.
+ # :call-seq:
+ # vector[range]
+ # vector[integer]
+ #
+ # Returns element or elements of the vector.
#
def [](i)
@elements[i]
@@ -1800,12 +2008,44 @@ class Vector
alias element []
alias component []
+ #
+ # :call-seq:
+ # vector[range] = new_vector
+ # vector[range] = row_matrix
+ # vector[range] = new_element
+ # vector[integer] = new_element
+ #
+ # Set element or elements of vector.
+ #
def []=(i, v)
- @elements[i]= v
+ raise FrozenError, "can't modify frozen Vector" if frozen?
+ if i.is_a?(Range)
+ range = Matrix::CoercionHelper.check_range(i, size, :vector)
+ set_range(range, v)
+ else
+ index = Matrix::CoercionHelper.check_int(i, size, :index)
+ set_value(index, v)
+ end
end
alias set_element []=
alias set_component []=
- private :[]=, :set_element, :set_component
+ private :set_element, :set_component
+
+ private def set_value(index, value)
+ @elements[index] = value
+ end
+
+ private def set_range(range, value)
+ if value.is_a?(Vector)
+ raise ArgumentError, "vector to be set has wrong size" unless range.size == value.size
+ @elements[range] = value.elements
+ elsif value.is_a?(Matrix)
+ raise ErrDimensionMismatch unless value.row_count == 1
+ @elements[range] = value.row(0).elements
+ else
+ @elements[range] = Array.new(range.size, value)
+ end
+ end
# Returns a vector with entries rounded to the given precision
# (see Float#round)
@@ -1839,7 +2079,7 @@ class Vector
#
def each2(v) # :yield: e1, e2
raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer)
- Vector.Raise ErrDimensionMismatch if size != v.size
+ raise ErrDimensionMismatch if size != v.size
return to_enum(:each2, v) unless block_given?
size.times do |i|
yield @elements[i], v[i]
@@ -1853,7 +2093,7 @@ class Vector
#
def collect2(v) # :yield: e1, e2
raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer)
- Vector.Raise ErrDimensionMismatch if size != v.size
+ raise ErrDimensionMismatch if size != v.size
return to_enum(:collect2, v) unless block_given?
Array.new(size) do |i|
yield @elements[i], v[i]
@@ -1868,15 +2108,15 @@ class Vector
# Returns +true+ iff all of vectors are linearly independent.
#
# Vector.independent?(Vector[1,0], Vector[0,1])
- # => true
+ # # => true
#
# Vector.independent?(Vector[1,2], Vector[2,4])
- # => false
+ # # => false
#
def Vector.independent?(*vs)
vs.each do |v|
raise TypeError, "expected Vector, got #{v.class}" unless v.is_a?(Vector)
- Vector.Raise ErrDimensionMismatch unless v.size == vs.first.size
+ raise ErrDimensionMismatch unless v.size == vs.first.size
end
return false if vs.count > vs.first.size
Matrix[*vs].rank.eql?(vs.count)
@@ -1886,10 +2126,10 @@ class Vector
# Returns +true+ iff all of vectors are linearly independent.
#
# Vector[1,0].independent?(Vector[0,1])
- # => true
+ # # => true
#
# Vector[1,2].independent?(Vector[2,4])
- # => false
+ # # => false
#
def independent?(*vs)
self.class.independent?(self, *vs)
@@ -1902,6 +2142,23 @@ class Vector
all?(&:zero?)
end
+ #
+ # Makes the matrix frozen and Ractor-shareable
+ #
+ def freeze
+ @elements.freeze
+ super
+ end
+
+ #
+ # Called for dup & clone.
+ #
+ private def initialize_copy(v)
+ super
+ @elements = @elements.dup unless frozen?
+ end
+
+
#--
# COMPARING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#++
@@ -1920,13 +2177,6 @@ class Vector
end
#
- # Returns a copy of the vector.
- #
- def clone
- self.class.elements(@elements)
- end
-
- #
# Returns a hash-code for the vector.
#
def hash
@@ -1948,7 +2198,7 @@ class Vector
when Matrix
Matrix.column_vector(self) * x
when Vector
- Vector.Raise ErrOperationNotDefined, "*", self.class, x.class
+ raise ErrOperationNotDefined, ["*", self.class, x.class]
else
apply_through_coercion(x, __method__)
end
@@ -1960,7 +2210,7 @@ class Vector
def +(v)
case v
when Vector
- Vector.Raise ErrDimensionMismatch if size != v.size
+ raise ErrDimensionMismatch if size != v.size
els = collect2(v) {|v1, v2|
v1 + v2
}
@@ -1978,7 +2228,7 @@ class Vector
def -(v)
case v
when Vector
- Vector.Raise ErrDimensionMismatch if size != v.size
+ raise ErrDimensionMismatch if size != v.size
els = collect2(v) {|v1, v2|
v1 - v2
}
@@ -1999,7 +2249,7 @@ class Vector
els = @elements.collect{|e| e / x}
self.class.elements(els, false)
when Matrix, Vector
- Vector.Raise ErrOperationNotDefined, "/", self.class, x.class
+ raise ErrOperationNotDefined, ["/", self.class, x.class]
else
apply_through_coercion(x, __method__)
end
@@ -2019,10 +2269,10 @@ class Vector
#
# Returns the inner product of this vector with the other.
- # Vector[4,7].inner_product Vector[10,1] => 47
+ # Vector[4,7].inner_product Vector[10,1] # => 47
#
def inner_product(v)
- Vector.Raise ErrDimensionMismatch if size != v.size
+ raise ErrDimensionMismatch if size != v.size
p = 0
each2(v) {|v1, v2|
@@ -2034,7 +2284,7 @@ class Vector
#
# Returns the cross product of this vector with the others.
- # Vector[1, 0, 0].cross_product Vector[0, 1, 0] => Vector[0, 0, 1]
+ # Vector[1, 0, 0].cross_product Vector[0, 1, 0] # => Vector[0, 0, 1]
#
# It is generalized to other dimensions to return a vector perpendicular
# to the arguments.
@@ -2049,7 +2299,7 @@ class Vector
raise ArgumentError, "wrong number of arguments (#{vs.size} for #{size - 2})" unless vs.size == size - 2
vs.each do |v|
raise TypeError, "expected Vector, got #{v.class}" unless v.is_a? Vector
- Vector.Raise ErrDimensionMismatch unless v.size == size
+ raise ErrDimensionMismatch unless v.size == size
end
case size
when 2
@@ -2074,17 +2324,28 @@ class Vector
els = @elements.collect(&block)
self.class.elements(els, false)
end
- alias map collect
+ alias_method :map, :collect
+
+ #
+ # Like Array#collect!
+ #
+ def collect!(&block)
+ return to_enum(:collect!) unless block_given?
+ raise FrozenError, "can't modify frozen Vector" if frozen?
+ @elements.collect!(&block)
+ self
+ end
+ alias map! collect!
#
# Returns the modulus (Pythagorean distance) of the vector.
- # Vector[5,8,2].r => 9.643650761
+ # Vector[5,8,2].r # => 9.643650761
#
def magnitude
Math.sqrt(@elements.inject(0) {|v, e| v + e.abs2})
end
- alias r magnitude
- alias norm magnitude
+ alias_method :r, :magnitude
+ alias_method :norm, :magnitude
#
# Like Vector#collect2, but returns a Vector instead of an Array.
@@ -2101,7 +2362,7 @@ class Vector
# Returns a new vector with the same direction but with norm 1.
# v = Vector[5,8,2].normalize
# # => Vector[0.5184758473652127, 0.8295613557843402, 0.20739033894608505]
- # v.norm => 1.0
+ # v.norm # => 1.0
#
def normalize
n = magnitude
@@ -2110,17 +2371,21 @@ class Vector
end
#
- # Returns an angle with another vector. Result is within the [0...Math::PI].
+ # Returns an angle with another vector. Result is within the [0..Math::PI].
# Vector[1,0].angle_with(Vector[0,1])
# # => Math::PI / 2
#
def angle_with(v)
raise TypeError, "Expected a Vector, got a #{v.class}" unless v.is_a?(Vector)
- Vector.Raise ErrDimensionMismatch if size != v.size
+ raise ErrDimensionMismatch if size != v.size
prod = magnitude * v.magnitude
raise ZeroVectorError, "Can't get angle of zero vector" if prod == 0
-
- Math.acos( inner_product(v) / prod )
+ dot = inner_product(v)
+ if dot.abs >= prod
+ dot.positive? ? 0 : Math::PI
+ else
+ Math.acos(dot / prod)
+ end
end
#--
@@ -2141,18 +2406,25 @@ class Vector
@elements.dup
end
+ #
+ # Return a single-column matrix from this vector
+ #
+ def to_matrix
+ Matrix.column_vector(self)
+ end
+
def elements_to_f
- warn "#{caller(1)[0]}: warning: Vector#elements_to_f is deprecated"
+ warn "Vector#elements_to_f is deprecated", uplevel: 1
map(&:to_f)
end
def elements_to_i
- warn "#{caller(1)[0]}: warning: Vector#elements_to_i is deprecated"
+ warn "Vector#elements_to_i is deprecated", uplevel: 1
map(&:to_i)
end
def elements_to_r
- warn "#{caller(1)[0]}: warning: Vector#elements_to_r is deprecated"
+ warn "Vector#elements_to_r is deprecated", uplevel: 1
map(&:to_r)
end
diff --git a/lib/matrix/eigenvalue_decomposition.rb b/lib/matrix/eigenvalue_decomposition.rb
index 919db9e83d..bf6637635a 100644
--- a/lib/matrix/eigenvalue_decomposition.rb
+++ b/lib/matrix/eigenvalue_decomposition.rb
@@ -43,7 +43,7 @@ class Matrix
def eigenvector_matrix
Matrix.send(:new, build_eigenvectors.transpose)
end
- alias v eigenvector_matrix
+ alias_method :v, :eigenvector_matrix
# Returns the inverse of the eigenvector matrix +V+
#
@@ -52,7 +52,7 @@ class Matrix
r = r.transpose.inverse unless @symmetric
r
end
- alias v_inv eigenvector_matrix_inv
+ alias_method :v_inv, :eigenvector_matrix_inv
# Returns the eigenvalues in an array
#
@@ -73,7 +73,7 @@ class Matrix
def eigenvalue_matrix
Matrix.diagonal(*eigenvalues)
end
- alias d eigenvalue_matrix
+ alias_method :d, :eigenvalue_matrix
# Returns [eigenvector_matrix, eigenvalue_matrix, eigenvector_matrix_inv]
#
@@ -82,8 +82,8 @@ class Matrix
end
alias_method :to_a, :to_ary
- private
- def build_eigenvectors
+
+ private def build_eigenvectors
# JAMA stores complex eigenvectors in a strange way
# See http://web.archive.org/web/20111016032731/http://cio.nist.gov/esd/emaildir/lists/jama/msg01021.html
@e.each_with_index.map do |imag, i|
@@ -96,9 +96,10 @@ class Matrix
end
end
end
+
# Complex scalar division.
- def cdiv(xr, xi, yr, yi)
+ private def cdiv(xr, xi, yr, yi)
if (yr.abs > yi.abs)
r = yi/yr
d = yr + r*yi
@@ -113,7 +114,7 @@ class Matrix
# Symmetric Householder reduction to tridiagonal form.
- def tridiagonalize
+ private def tridiagonalize
# This is derived from the Algol procedures tred2 by
# Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
@@ -231,7 +232,7 @@ class Matrix
# Symmetric tridiagonal QL algorithm.
- def diagonalize
+ private def diagonalize
# This is derived from the Algol procedures tql2, by
# Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
# Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
@@ -350,7 +351,7 @@ class Matrix
# Nonsymmetric reduction to Hessenberg form.
- def reduce_to_hessenberg
+ private def reduce_to_hessenberg
# This is derived from the Algol procedures orthes and ortran,
# by Martin and Wilkinson, Handbook for Auto. Comp.,
# Vol.ii-Linear Algebra, and the corresponding
@@ -440,11 +441,9 @@ class Matrix
end
end
-
-
# Nonsymmetric reduction from Hessenberg to real Schur form.
- def hessenberg_to_real_schur
+ private def hessenberg_to_real_schur
# This is derived from the Algol procedure hqr2,
# by Martin and Wilkinson, Handbook for Auto. Comp.,
diff --git a/lib/matrix/lup_decomposition.rb b/lib/matrix/lup_decomposition.rb
index c001770a12..e37def75f6 100644
--- a/lib/matrix/lup_decomposition.rb
+++ b/lib/matrix/lup_decomposition.rb
@@ -78,7 +78,7 @@ class Matrix
def det
if (@row_count != @column_count)
- Matrix.Raise Matrix::ErrDimensionMismatch
+ raise Matrix::ErrDimensionMismatch
end
d = @pivot_sign
@column_count.times do |j|
@@ -94,11 +94,11 @@ class Matrix
def solve b
if (singular?)
- Matrix.Raise Matrix::ErrNotRegular, "Matrix is singular."
+ raise Matrix::ErrNotRegular, "Matrix is singular."
end
if b.is_a? Matrix
if (b.row_count != @row_count)
- Matrix.Raise Matrix::ErrDimensionMismatch
+ raise Matrix::ErrDimensionMismatch
end
# Copy right hand side with pivoting
@@ -128,7 +128,7 @@ class Matrix
else # same algorithm, specialized for simpler case of a vector
b = convert_to_array(b)
if (b.size != @row_count)
- Matrix.Raise Matrix::ErrDimensionMismatch
+ raise Matrix::ErrDimensionMismatch
end
# Copy right hand side with pivoting
diff --git a/lib/matrix/matrix.gemspec b/lib/matrix/matrix.gemspec
new file mode 100644
index 0000000000..d2ff9ce7c6
--- /dev/null
+++ b/lib/matrix/matrix.gemspec
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+begin
+ require_relative "lib/matrix/version"
+rescue LoadError
+ # for Ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "matrix"
+ spec.version = Matrix::VERSION
+ spec.authors = ["Marc-Andre Lafortune"]
+ spec.email = ["ruby-core@marc-andre.ca"]
+
+ spec.summary = %q{An implementation of Matrix and Vector classes.}
+ spec.description = %q{An implementation of Matrix and Vector classes.}
+ spec.homepage = "https://github.com/ruby/matrix"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = ">= 2.5.0"
+
+ spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/matrix.rb", "lib/matrix/eigenvalue_decomposition.rb", "lib/matrix/lup_decomposition.rb", "lib/matrix/version.rb", "matrix.gemspec"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_development_dependency "bundler"
+ spec.add_development_dependency "rake"
+end
diff --git a/lib/matrix/version.rb b/lib/matrix/version.rb
new file mode 100644
index 0000000000..4a8bc36aaa
--- /dev/null
+++ b/lib/matrix/version.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+class Matrix
+ VERSION = "0.3.1"
+end
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 7e40c2d193..66f2960cb8 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -7,8 +7,9 @@ require 'rbconfig'
require 'fileutils'
require 'shellwords'
-# :stopdoc:
class String
+ # :stopdoc:
+
# Wraps a string in escaped quotes if it contains whitespace.
def quote
/\s/ =~ self ? "\"#{self}\"" : "#{self}"
@@ -31,15 +32,20 @@ class String
def sans_arguments
self[/\A[^()]+/]
end
+
+ # :startdoc:
end
class Array
+ # :stopdoc:
+
# Wraps all strings in escaped quotes if they contain whitespace.
def quote
map {|s| s.quote}
end
+
+ # :startdoc:
end
-# :startdoc:
##
# mkmf.rb is used by Ruby C extensions to generate a Makefile which will
@@ -129,7 +135,6 @@ module MakeMakefile
$vendorarchdir = CONFIG["vendorarchdir"]
$mswin = /mswin/ =~ RUBY_PLATFORM
- $bccwin = /bccwin/ =~ RUBY_PLATFORM
$mingw = /mingw/ =~ RUBY_PLATFORM
$cygwin = /cygwin/ =~ RUBY_PLATFORM
$netbsd = /netbsd/ =~ RUBY_PLATFORM
@@ -202,8 +207,8 @@ module MakeMakefile
['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'],
['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'],
- ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'],
- ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
+ ['HDRDIR', '$(vendorhdrdir)$(target_prefix)'],
+ ['ARCHHDRDIR', '$(vendorarchhdrdir)$(target_prefix)'],
]
else
dirs = [
@@ -211,8 +216,8 @@ module MakeMakefile
['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'],
['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'],
- ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'],
- ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
+ ['HDRDIR', '$(sitehdrdir)$(target_prefix)'],
+ ['ARCHHDRDIR', '$(sitearchhdrdir)$(target_prefix)'],
]
end
dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
@@ -242,7 +247,12 @@ module MakeMakefile
$topdir ||= RbConfig::CONFIG["topdir"]
$arch_hdrdir = "$(extout)/include/$(arch)"
else
- abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
+ abort <<MESSAGE
+mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h
+
+You might have to install separate package for the ruby development
+environment, ruby-dev or ruby-devel for example.
+MESSAGE
end
CONFTEST = "conftest".freeze
@@ -424,6 +434,10 @@ EOM
EOM
end
+ def conftest_source
+ CONFTEST_C
+ end
+
def create_tmpsrc(src)
src = "#{COMMON_HEADERS}\n#{src}"
src = yield(src) if block_given?
@@ -432,7 +446,7 @@ EOM
src.sub!(/[^\n]\z/, "\\&\n")
count = 0
begin
- open(CONFTEST_C, "wb") do |cfile|
+ open(conftest_source, "wb") do |cfile|
cfile.print src
end
rescue Errno::EACCES
@@ -467,10 +481,10 @@ MSG
end
end
- def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
+ def link_config(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
- 'src' => "#{CONFTEST_C}",
+ 'src' => "#{conftest_source}",
'arch_hdrdir' => $arch_hdrdir.quote,
'top_srcdir' => $top_srcdir.quote,
'INCFLAGS' => "#$INCFLAGS",
@@ -481,21 +495,29 @@ MSG
'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
'LIBS' => "#{librubyarg} #{opt} #$LIBS")
conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
+ conf
+ end
+
+ def link_command(ldflags, *opts)
+ conf = link_config(ldflags, *opts)
RbConfig::expand(TRY_LINK.dup, conf)
end
- def cc_command(opt="")
+ def cc_config(opt="")
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
'arch_hdrdir' => $arch_hdrdir.quote,
'top_srcdir' => $top_srcdir.quote)
+ conf
+ end
+
+ def cc_command(opt="")
+ conf = cc_config(opt)
RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
conf)
end
def cpp_command(outfile, opt="")
- conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
- 'arch_hdrdir' => $arch_hdrdir.quote,
- 'top_srcdir' => $top_srcdir.quote)
+ conf = cc_config(opt)
if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
end
@@ -658,7 +680,8 @@ MSG
end
def try_ldflags(flags, opts = {})
- try_link(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
+ opts = {:werror => true}.update(opts) if $mswin
+ try_link(MAIN_DOES_NOTHING, flags, opts)
end
def append_ldflags(flags, *opts)
@@ -761,7 +784,7 @@ int main() {printf("%"PRI_CONFTEST_PREFIX"#{neg ? 'd' : 'u'}\\n", conftest_const
if opt and !opt.empty?
[[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
if opt.respond_to?(meth)
- break opt = opt.send(meth, *args)
+ break opt = opt.__send__(meth, *args)
end
end
opt = "#{opt} #{libs}"
@@ -959,7 +982,7 @@ SRC
if noun
[[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
if noun.respond_to?(meth)
- break noun = noun.send(meth, *args)
+ break noun = noun.__send__(meth, *args)
end
end
unless noun.empty?
@@ -996,6 +1019,7 @@ SRC
# <code>--with-FOOlib</code> configuration option.
#
def have_library(lib, func = nil, headers = nil, opt = "", &b)
+ dir_config(lib)
lib = with_config(lib+'lib', lib)
checking_for checking_message(func && func.funcall_style, LIBARG%lib, opt) do
if COMMON_LIBS.include?(lib)
@@ -1021,6 +1045,7 @@ SRC
# library paths searched and linked against.
#
def find_library(lib, func, *paths, &b)
+ dir_config(lib)
lib = with_config(lib+'lib', lib)
paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
checking_for checking_message(func && func.funcall_style, LIBARG%lib) do
@@ -1094,6 +1119,7 @@ SRC
# +HAVE_FOO_H+ preprocessor macro would be passed to the compiler.
#
def have_header(header, preheaders = nil, opt = "", &b)
+ dir_config(header[/.*?(?=\/)|.*?(?=\.)/])
checking_for header do
if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b)
$defs.push(format("-DHAVE_%s", header.tr_cpp))
@@ -1737,6 +1763,10 @@ SRC
# application.
#
def dir_config(target, idefault=nil, ldefault=nil)
+ if conf = $config_dirs[target]
+ return conf
+ end
+
if dir = with_config(target + "-dir", (idefault unless ldefault))
defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
idefault = ldefault = nil
@@ -1767,7 +1797,7 @@ SRC
end
$LIBPATH = ldirs | $LIBPATH
- [idir, ldir]
+ $config_dirs[target] = [idir, ldir]
end
# Returns compile/link information about an installed library in a
@@ -1783,7 +1813,7 @@ SRC
#
# Where {option} is, for instance, <code>--cflags</code>.
#
- # The values obtained are appended to +$CFLAGS+, +$LDFLAGS+ and
+ # The values obtained are appended to +$INCFLAGS+, +$CFLAGS+, +$LDFLAGS+ and
# +$libs+.
#
# If an <code>option</code> argument is given, the config command is
@@ -1839,9 +1869,9 @@ SRC
$LDFLAGS = [orig_ldflags, ldflags].join(' ')
Logging::message "package configuration for %s\n", pkg
- Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
- cflags, ldflags, libs
- [cflags, ldflags, libs]
+ Logging::message "incflags: %s\ncflags: %s\nldflags: %s\nlibs: %s\n\n",
+ incflags, cflags, ldflags, libs
+ [[incflags, cflags].join(' '), ldflags, libs]
else
Logging::message "package configuration for %s is not found\n", pkg
nil
@@ -1912,7 +1942,7 @@ NULLCMD = #{CONFIG['NULLCMD']}
srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2]).unspace}}
topdir = #{mkintpath(topdir = $extmk ? CONFIG["topdir"] : $topdir).unspace}
hdrdir = #{(hdrdir = CONFIG["hdrdir"]) == topdir ? "$(topdir)" : mkintpath(hdrdir).unspace}
-arch_hdrdir = #{$arch_hdrdir.quote}
+arch_hdrdir = #{mkintpath($arch_hdrdir).unspace}
PATH_SEPARATOR = #{CONFIG['PATH_SEPARATOR']}
VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
}
@@ -1940,7 +1970,7 @@ VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
else
sep = ""
end
- possible_command = (proc {|s| s if /top_srcdir/ !~ s} unless $extmk)
+ possible_command = (proc {|s| s if /top_srcdir|tooldir/ !~ s} unless $extmk)
extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ") << " "
headers = %w[
$(hdrdir)/ruby.h
@@ -1960,6 +1990,7 @@ VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
headers << '$(RUBY_EXTCONF_H)' if $extconf_h
mk << %{
+CC_WRAPPER = #{CONFIG['CC_WRAPPER']}
CC = #{CONFIG['CC']}
CXX = #{CONFIG['CXX']}
LIBRUBY = #{CONFIG['LIBRUBY']}
@@ -1977,6 +2008,7 @@ cxxflags = #{CONFIG['cxxflags']}
optflags = #{CONFIG['optflags']}
debugflags = #{CONFIG['debugflags']}
warnflags = #{$warnflags}
+cppflags = #{CONFIG['cppflags']}
CCDLFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']}
CFLAGS = $(CCDLFLAGS) #$CFLAGS $(ARCH_FLAG)
INCFLAGS = -I. #$INCFLAGS
@@ -2002,6 +2034,11 @@ sitearch = #{CONFIG['sitearch']}
ruby_version = #{RbConfig::CONFIG['ruby_version']}
ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}}
RUBY = $(ruby#{sep})
+BUILTRUBY = #{if defined?($builtruby) && $builtruby
+ $builtruby
+ else
+ File.join('$(bindir)', CONFIG["RUBY_INSTALL_NAME"] + CONFIG['EXEEXT'])
+ end}
ruby_headers = #{headers.join(' ')}
RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'}
@@ -2102,7 +2139,6 @@ RULES
line.gsub!(/\.o\b/, ".#{$OBJEXT}")
line.gsub!(/\{\$\(VPATH\)\}/, "") unless $nmake
line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
- line.gsub!(%r"\$\(hdrdir\)/(?!ruby(?![^:;/\s]))(?=[-\w]+\.h)", '\&ruby/')
if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
line.gsub!(%r"[-\w\./]{2,}"){$&.tr("/", "\\")}
line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\\')
@@ -2124,7 +2160,10 @@ RULES
unless suffixes.empty?
depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n")
end
- depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n") if $extconf_h
+ if $extconf_h
+ depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n")
+ depout.unshift("$(OBJS): $(hdrdir)/ruby/win32.h\n\n") if $mswin or $mingw
+ end
depout.flatten!
depout
end
@@ -2188,7 +2227,7 @@ RULES
message "creating Makefile\n"
MakeMakefile.rm_f "#{CONFTEST}*"
if CONFIG["DLEXT"] == $OBJEXT
- for lib in libs = $libs.split
+ for lib in libs = $libs.split(' ')
lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
end
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
@@ -2248,7 +2287,7 @@ RULES
origdef ||= ''
if $extout and $INSTALLFILES
- $cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.sub(/\A\.\//, ''))})
+ $cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.delete_prefix('./'))})
$distcleandirs.concat($INSTALLFILES.collect {|files, dir| dir})
end
@@ -2492,6 +2531,8 @@ site-install-rb: install-rb
$enable_shared = config['ENABLE_SHARED'] == 'yes'
$defs = []
$extconf_h = nil
+ $config_dirs = {}
+
if $warnflags = CONFIG['warnflags'] and CONFIG['GCC'] == 'yes'
# turn warnings into errors only for bundled extensions.
config['warnflags'] = $warnflags.gsub(/(\A|\s)-Werror[-=]/, '\1-W')
@@ -2504,6 +2545,9 @@ site-install-rb: install-rb
end
$warnflags = config['warnflags'] unless $extmk
end
+ if (w = rbconfig['CC_WRAPPER']) and !w.empty? and !File.executable?(w)
+ rbconfig['CC_WRAPPER'] = config['CC_WRAPPER'] = ''
+ end
$CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
$CXXFLAGS = (with_config("cxxflags", arg_config("CXXFLAGS", config["CXXFLAGS"]))||'').dup
$ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
@@ -2513,6 +2557,7 @@ site-install-rb: install-rb
$INCFLAGS << " -I$(hdrdir)/ruby/backward" unless $extmk
$INCFLAGS << " -I$(hdrdir) -I$(srcdir)"
$DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
+ config_string("ADDITIONAL_DLDFLAGS") {|flags| $DLDFLAGS << " " << flags} unless $extmk
$LIBEXT = config['LIBEXT'].dup
$OBJEXT = config["OBJEXT"].dup
$EXEEXT = config["EXEEXT"].dup
@@ -2547,6 +2592,7 @@ site-install-rb: install-rb
$extout_prefix ||= nil
$arg_config.clear
+ $config_dirs.clear
dir_config("opt")
end
@@ -2582,7 +2628,8 @@ MESSAGE
src = src.sub(/\{/) do
$& +
"\n if (argc > 1000000) {\n" +
- refs.map {|n|" printf(\"%p\", &#{n});\n"}.join("") +
+ refs.map {|n|" int (* volatile #{n}p)(void)=(int (*)(void))&#{n};\n"}.join("") +
+ refs.map {|n|" printf(\"%d\", (*#{n}p)());\n"}.join("") +
" }\n"
end
end
@@ -2706,7 +2753,7 @@ MESSAGE
##
# A C main function which does no work
- MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return 0;\n}"
+ MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return !!argv[argc];\n}"
UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
%w[int short long long\ long]
@@ -2734,9 +2781,59 @@ distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
realclean: distclean
"
+
+ @lang = Hash.new(self)
+
+ def self.[](name)
+ @lang.fetch(name)
+ end
+
+ def self.[]=(name, mod)
+ @lang[name] = mod
+ end
+
+ self["C++"] = Module.new do
+ include MakeMakefile
+ extend self
+
+ CONFTEST_CXX = "#{CONFTEST}.#{config_string('CXX_EXT') || CXX_EXT[0]}"
+
+ TRY_LINK_CXX = config_string('TRY_LINK_CXX') ||
+ ((cmd = TRY_LINK.gsub(/\$\(C(?:C|(FLAGS))\)/, '$(CXX\1)')) != TRY_LINK && cmd) ||
+ "$(CXX) #{OUTFLAG}#{CONFTEST}#{$EXEEXT} $(INCFLAGS) $(CPPFLAGS) " \
+ "$(CXXFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
+
+ def have_devel?
+ unless defined? @have_devel
+ @have_devel = true
+ @have_devel = try_link(MAIN_DOES_NOTHING)
+ end
+ @have_devel
+ end
+
+ def conftest_source
+ CONFTEST_CXX
+ end
+
+ def cc_command(opt="")
+ conf = cc_config(opt)
+ RbConfig::expand("$(CXX) #$INCFLAGS #$CPPFLAGS #$CXXFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_CXX}",
+ conf)
+ end
+
+ def link_command(ldflags, *opts)
+ conf = link_config(ldflags, *opts)
+ RbConfig::expand(TRY_LINK_CXX.dup, conf)
+ end
+ end
end
-include MakeMakefile
+# MakeMakefile::Global = #
+m = Module.new {
+ include(MakeMakefile)
+ private(*MakeMakefile.public_instance_methods(false))
+}
+include m
if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
END {mkmf_failed($0)}
diff --git a/lib/monitor.rb b/lib/monitor.rb
deleted file mode 100644
index 288ed755ea..0000000000
--- a/lib/monitor.rb
+++ /dev/null
@@ -1,315 +0,0 @@
-# frozen_string_literal: false
-# = monitor.rb
-#
-# Copyright (C) 2001 Shugo Maeda <shugo@ruby-lang.org>
-#
-# This library is distributed under the terms of the Ruby license.
-# You can freely distribute/modify this library.
-#
-
-#
-# In concurrent programming, a monitor is an object or module intended to be
-# used safely by more than one thread. The defining characteristic of a
-# monitor is that its methods are executed with mutual exclusion. That is, at
-# each point in time, at most one thread may be executing any of its methods.
-# This mutual exclusion greatly simplifies reasoning about the implementation
-# of monitors compared to reasoning about parallel code that updates a data
-# structure.
-#
-# You can read more about the general principles on the Wikipedia page for
-# Monitors[http://en.wikipedia.org/wiki/Monitor_%28synchronization%29]
-#
-# == Examples
-#
-# === Simple object.extend
-#
-# require 'monitor.rb'
-#
-# buf = []
-# buf.extend(MonitorMixin)
-# empty_cond = buf.new_cond
-#
-# # consumer
-# Thread.start do
-# loop do
-# buf.synchronize do
-# empty_cond.wait_while { buf.empty? }
-# print buf.shift
-# end
-# end
-# end
-#
-# # producer
-# while line = ARGF.gets
-# buf.synchronize do
-# buf.push(line)
-# empty_cond.signal
-# end
-# end
-#
-# The consumer thread waits for the producer thread to push a line to buf
-# while <tt>buf.empty?</tt>. The producer thread (main thread) reads a
-# line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt>
-# to notify the consumer thread of new data.
-#
-# === Simple Class include
-#
-# require 'monitor'
-#
-# class SynchronizedArray < Array
-#
-# include MonitorMixin
-#
-# def initialize(*args)
-# super(*args)
-# end
-#
-# alias :old_shift :shift
-# alias :old_unshift :unshift
-#
-# def shift(n=1)
-# self.synchronize do
-# self.old_shift(n)
-# end
-# end
-#
-# def unshift(item)
-# self.synchronize do
-# self.old_unshift(item)
-# end
-# end
-#
-# # other methods ...
-# end
-#
-# +SynchronizedArray+ implements an Array with synchronized access to items.
-# This Class is implemented as subclass of Array which includes the
-# MonitorMixin module.
-#
-module MonitorMixin
- #
- # FIXME: This isn't documented in Nutshell.
- #
- # Since MonitorMixin.new_cond returns a ConditionVariable, and the example
- # above calls while_wait and signal, this class should be documented.
- #
- class ConditionVariable
- class Timeout < Exception; end
-
- #
- # Releases the lock held in the associated monitor and waits; reacquires the lock on wakeup.
- #
- # If +timeout+ is given, this method returns after +timeout+ seconds passed,
- # even if no other thread doesn't signal.
- #
- def wait(timeout = nil)
- @monitor.__send__(:mon_check_owner)
- count = @monitor.__send__(:mon_exit_for_cond)
- begin
- @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
- return true
- ensure
- @monitor.__send__(:mon_enter_for_cond, count)
- end
- end
-
- #
- # Calls wait repeatedly while the given block yields a truthy value.
- #
- def wait_while
- while yield
- wait
- end
- end
-
- #
- # Calls wait repeatedly until the given block yields a truthy value.
- #
- def wait_until
- until yield
- wait
- end
- end
-
- #
- # Wakes up the first thread in line waiting for this lock.
- #
- def signal
- @monitor.__send__(:mon_check_owner)
- @cond.signal
- end
-
- #
- # Wakes up all threads waiting for this lock.
- #
- def broadcast
- @monitor.__send__(:mon_check_owner)
- @cond.broadcast
- end
-
- private
-
- def initialize(monitor)
- @monitor = monitor
- @cond = Thread::ConditionVariable.new
- end
- end
-
- def self.extend_object(obj)
- super(obj)
- obj.__send__(:mon_initialize)
- end
-
- #
- # Attempts to enter exclusive section. Returns +false+ if lock fails.
- #
- def mon_try_enter
- if @mon_owner != Thread.current
- unless @mon_mutex.try_lock
- return false
- end
- @mon_owner = Thread.current
- @mon_count = 0
- end
- @mon_count += 1
- return true
- end
- # For backward compatibility
- alias try_mon_enter mon_try_enter
-
- #
- # Enters exclusive section.
- #
- def mon_enter
- if @mon_owner != Thread.current
- @mon_mutex.lock
- @mon_owner = Thread.current
- @mon_count = 0
- end
- @mon_count += 1
- end
-
- #
- # Leaves exclusive section.
- #
- def mon_exit
- mon_check_owner
- @mon_count -=1
- if @mon_count == 0
- @mon_owner = nil
- @mon_mutex.unlock
- end
- end
-
- #
- # Returns true if this monitor is locked by any thread
- #
- def mon_locked?
- @mon_mutex.locked?
- end
-
- #
- # Returns true if this monitor is locked by current thread.
- #
- def mon_owned?
- @mon_mutex.locked? && @mon_owner == Thread.current
- end
-
- #
- # Enters exclusive section and executes the block. Leaves the exclusive
- # section automatically when the block exits. See example under
- # +MonitorMixin+.
- #
- def mon_synchronize
- mon_enter
- begin
- yield
- ensure
- mon_exit
- end
- end
- alias synchronize mon_synchronize
-
- #
- # Creates a new MonitorMixin::ConditionVariable associated with the
- # receiver.
- #
- def new_cond
- return ConditionVariable.new(self)
- end
-
- private
-
- # Use <tt>extend MonitorMixin</tt> or <tt>include MonitorMixin</tt> instead
- # of this constructor. Have look at the examples above to understand how to
- # use this module.
- def initialize(*args)
- super
- mon_initialize
- end
-
- # Initializes the MonitorMixin after being included in a class or when an
- # object has been extended with the MonitorMixin
- def mon_initialize
- @mon_owner = nil
- @mon_count = 0
- @mon_mutex = Thread::Mutex.new
- end
-
- def mon_check_owner
- if @mon_owner != Thread.current
- raise ThreadError, "current thread not owner"
- end
- end
-
- def mon_enter_for_cond(count)
- @mon_owner = Thread.current
- @mon_count = count
- end
-
- def mon_exit_for_cond
- count = @mon_count
- @mon_owner = nil
- @mon_count = 0
- return count
- end
-end
-
-# Use the Monitor class when you want to have a lock object for blocks with
-# mutual exclusion.
-#
-# require 'monitor'
-#
-# lock = Monitor.new
-# lock.synchronize do
-# # exclusive access
-# end
-#
-class Monitor
- include MonitorMixin
- alias try_enter try_mon_enter
- alias enter mon_enter
- alias exit mon_exit
-end
-
-
-# Documentation comments:
-# - All documentation comes from Nutshell.
-# - MonitorMixin.new_cond appears in the example, but is not documented in
-# Nutshell.
-# - All the internals (internal modules Accessible and Initializable, class
-# ConditionVariable) appear in RDoc. It might be good to hide them, by
-# making them private, or marking them :nodoc:, etc.
-# - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but
-# not synchronize.
-# - mon_owner is in Nutshell, but appears as an accessor in a separate module
-# here, so is hard/impossible to RDoc. Some other useful accessors
-# (mon_count and some queue stuff) are also in this module, and don't appear
-# directly in the RDoc output.
-# - in short, it may be worth changing the code layout in this file to make the
-# documentation easier
-
-# Local variables:
-# mode: Ruby
-# tab-width: 8
-# End:
diff --git a/lib/mutex_m.gemspec b/lib/mutex_m.gemspec
new file mode 100644
index 0000000000..f614dcd9a0
--- /dev/null
+++ b/lib/mutex_m.gemspec
@@ -0,0 +1,27 @@
+begin
+ require_relative "lib/mutex_m"
+rescue LoadError
+ # for Ruby core repository
+ require_relative "mutex_m"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "mutex_m"
+ spec.version = Mutex_m::VERSION
+ spec.authors = ["Keiju ISHITSUKA"]
+ spec.email = ["keiju@ruby-lang.org"]
+
+ spec.summary = %q{Mixin to extend objects to be handled like a Mutex.}
+ spec.description = %q{Mixin to extend objects to be handled like a Mutex.}
+ spec.homepage = "https://github.com/ruby/mutex_m"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.files = ["Gemfile", "LICENSE.txt", "README.md", "Rakefile", "lib/mutex_m.rb", "mutex_m.gemspec"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_development_dependency "bundler"
+ spec.add_development_dependency "rake"
+ spec.add_development_dependency "test-unit"
+end
diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb
index 592e3842c8..18b6256595 100644
--- a/lib/mutex_m.rb
+++ b/lib/mutex_m.rb
@@ -25,16 +25,23 @@
# obj.extend Mutex_m
#
# Or mixin Mutex_m into your module to your class inherit Mutex instance
-# methods.
+# methods --- remember to call super() in your class initialize method.
#
# class Foo
# include Mutex_m
+# def initialize
+# # ...
+# super()
+# end
# # ...
# end
# obj = Foo.new
# # this obj can be handled like Mutex
#
module Mutex_m
+
+ VERSION = "0.1.1"
+
def Mutex_m.define_aliases(cl) # :nodoc:
cl.module_eval %q{
alias locked? mu_locked?
@@ -106,4 +113,5 @@ module Mutex_m
mu_initialize
super
end
+ ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
end
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
index cafe39fad0..2161d30d7c 100644
--- a/lib/net/ftp.rb
+++ b/lib/net/ftp.rb
@@ -85,6 +85,7 @@ module Net
end
# :stopdoc:
+ VERSION = "0.1.2"
FTP_PORT = 21
CRLF = "\r\n"
DEFAULT_BLOCKSIZE = BufferedIO::BUFSIZE
@@ -97,6 +98,10 @@ module Net
# When +true+, the connection is in passive mode. Default: +true+.
attr_accessor :passive
+ # When +true+, use the IP address in PASV responses. Otherwise, it uses
+ # the same IP address for the control connection. Default: +false+.
+ attr_accessor :use_pasv_ip
+
# When +true+, all traffic to and from the server is written
# to +$stdout+. Default: +false+.
attr_accessor :debug_mode
@@ -182,16 +187,16 @@ module Net
# The available options are:
#
# port:: Port number (default value is 21)
- # ssl:: If options[:ssl] is true, then an attempt will be made
+ # ssl:: If +options+[:ssl] is true, then an attempt will be made
# to use SSL (now TLS) to connect to the server. For this
# to work OpenSSL [OSSL] and the Ruby OpenSSL [RSSL]
- # extensions need to be installed. If options[:ssl] is a
+ # extensions need to be installed. If +options+[:ssl] is a
# hash, it's passed to OpenSSL::SSL::SSLContext#set_params
# as parameters.
# private_data_connection:: If true, TLS is used for data connections.
- # Default: +true+ when options[:ssl] is true.
- # username:: Username for login. If options[:username] is the string
- # "anonymous" and the options[:password] is +nil+,
+ # Default: +true+ when +options+[:ssl] is true.
+ # username:: Username for login. If +options+[:username] is the string
+ # "anonymous" and the +options+[:password] is +nil+,
# "anonymous@" is used as a password.
# password:: Password for login.
# account:: Account information for ACCT.
@@ -205,6 +210,9 @@ module Net
# handshake.
# See Net::FTP#ssl_handshake_timeout for
# details. Default: +nil+.
+ # use_pasv_ip:: When +true+, use the IP address in PASV responses.
+ # Otherwise, it uses the same IP address for the control
+ # connection. Default: +false+.
# debug_mode:: When +true+, all traffic to and from the server is
# written to +$stdout+. Default: +false+.
#
@@ -230,6 +238,10 @@ module Net
if defined?(VerifyCallbackProc)
@ssl_context.verify_callback = VerifyCallbackProc
end
+ @ssl_context.session_cache_mode =
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
+ @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
@ssl_session = nil
if options[:private_data_connection].nil?
@private_data_connection = true
@@ -261,6 +273,7 @@ module Net
@open_timeout = options[:open_timeout]
@ssl_handshake_timeout = options[:ssl_handshake_timeout]
@read_timeout = options[:read_timeout] || 60
+ @use_pasv_ip = options[:use_pasv_ip] || false
if host
connect(host, options[:port] || FTP_PORT)
if options[:username]
@@ -310,13 +323,13 @@ module Net
# Obsolete
def return_code # :nodoc:
- $stderr.puts("warning: Net::FTP#return_code is obsolete and do nothing")
+ warn("Net::FTP#return_code is obsolete and do nothing", uplevel: 1)
return "\n"
end
# Obsolete
def return_code=(s) # :nodoc:
- $stderr.puts("warning: Net::FTP#return_code= is obsolete and do nothing")
+ warn("Net::FTP#return_code= is obsolete and do nothing", uplevel: 1)
end
# Constructs a socket with +host+ and +port+.
@@ -325,14 +338,19 @@ module Net
# SOCKS_SERVER, then a SOCKSSocket is returned, else a Socket is
# returned.
def open_socket(host, port) # :nodoc:
- return Timeout.timeout(@open_timeout, OpenTimeout) {
- if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
- @passive = true
- sock = SOCKSSocket.open(host, port)
- else
- sock = Socket.tcp(host, port)
+ if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
+ @passive = true
+ Timeout.timeout(@open_timeout, OpenTimeout) do
+ SOCKSSocket.open(host, port)
end
- }
+ else
+ begin
+ Socket.tcp host, port, nil, nil, connect_timeout: @open_timeout
+ rescue Errno::ETIMEDOUT #raise Net:OpenTimeout instead for compatibility with previous versions
+ raise Net::OpenTimeout, "Timeout to open TCP connection to "\
+ "#{host}:#{port} (exceeds #{@open_timeout} seconds)"
+ end
+ end
end
private :open_socket
@@ -349,7 +367,6 @@ module Net
if @ssl_context.verify_mode != VERIFY_NONE
ssl_sock.post_connection_check(@host)
end
- @ssl_session = ssl_sock.session
return ssl_sock
end
private :start_tls_session
@@ -538,18 +555,22 @@ module Net
def transfercmd(cmd, rest_offset = nil) # :nodoc:
if @passive
host, port = makepasv
- conn = open_socket(host, port)
- if @resume and rest_offset
- resp = sendcmd("REST " + rest_offset.to_s)
- if !resp.start_with?("3")
+ begin
+ conn = open_socket(host, port)
+ if @resume and rest_offset
+ resp = sendcmd("REST " + rest_offset.to_s)
+ if !resp.start_with?("3")
+ raise FTPReplyError, resp
+ end
+ end
+ resp = sendcmd(cmd)
+ # skip 2XX for some ftp servers
+ resp = getresp if resp.start_with?("2")
+ if !resp.start_with?("1")
raise FTPReplyError, resp
end
- end
- resp = sendcmd(cmd)
- # skip 2XX for some ftp servers
- resp = getresp if resp.start_with?("2")
- if !resp.start_with?("1")
- raise FTPReplyError, resp
+ ensure
+ conn.close if conn && $!
end
else
sock = makeport
@@ -628,14 +649,12 @@ module Net
with_binary(true) do
begin
conn = transfercmd(cmd, rest_offset)
- loop do
- data = conn.read(blocksize)
- break if data == nil
+ while data = conn.read(blocksize)
yield(data)
end
- conn.shutdown(Socket::SHUT_WR)
+ conn.shutdown(Socket::SHUT_WR) rescue nil
conn.read_timeout = 1
- conn.read
+ conn.read rescue nil
ensure
conn.close if conn
end
@@ -655,14 +674,12 @@ module Net
with_binary(false) do
begin
conn = transfercmd(cmd)
- loop do
- line = conn.gets
- break if line == nil
+ while line = conn.gets
yield(line.sub(/\r?\n\z/, ""), !line.match(/\n\z/).nil?)
end
- conn.shutdown(Socket::SHUT_WR)
+ conn.shutdown(Socket::SHUT_WR) rescue nil
conn.read_timeout = 1
- conn.read
+ conn.read rescue nil
ensure
conn.close if conn
end
@@ -683,14 +700,18 @@ module Net
end
synchronize do
with_binary(true) do
- conn = transfercmd(cmd)
- loop do
- buf = file.read(blocksize)
- break if buf == nil
- conn.write(buf)
- yield(buf) if block_given?
+ begin
+ conn = transfercmd(cmd)
+ while buf = file.read(blocksize)
+ conn.write(buf)
+ yield(buf) if block_given?
+ end
+ conn.shutdown(Socket::SHUT_WR) rescue nil
+ conn.read_timeout = 1
+ conn.read rescue nil
+ ensure
+ conn.close if conn
end
- conn.close
voidresp
end
end
@@ -712,17 +733,21 @@ module Net
def storlines(cmd, file) # :yield: line
synchronize do
with_binary(false) do
- conn = transfercmd(cmd)
- loop do
- buf = file.gets
- break if buf == nil
- if buf[-2, 2] != CRLF
- buf = buf.chomp + CRLF
+ begin
+ conn = transfercmd(cmd)
+ while buf = file.gets
+ if buf[-2, 2] != CRLF
+ buf = buf.chomp + CRLF
+ end
+ conn.write(buf)
+ yield(buf) if block_given?
end
- conn.write(buf)
- yield(buf) if block_given?
+ conn.shutdown(Socket::SHUT_WR) rescue nil
+ conn.read_timeout = 1
+ conn.read rescue nil
+ ensure
+ conn.close if conn
end
- conn.close
voidresp
end
end
@@ -748,10 +773,10 @@ module Net
if localfile
if @resume
rest_offset = File.size?(localfile)
- f = open(localfile, "a")
+ f = File.open(localfile, "a")
else
rest_offset = nil
- f = open(localfile, "w")
+ f = File.open(localfile, "w")
end
elsif !block_given?
result = String.new
@@ -781,7 +806,7 @@ module Net
f = nil
result = nil
if localfile
- f = open(localfile, "w")
+ f = File.open(localfile, "w")
elsif !block_given?
result = String.new
end
@@ -827,7 +852,7 @@ module Net
else
rest_offset = nil
end
- f = open(localfile)
+ f = File.open(localfile)
begin
f.binmode
if rest_offset
@@ -846,7 +871,7 @@ module Net
# passing in the transmitted data one line at a time.
#
def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line
- f = open(localfile)
+ f = File.open(localfile)
begin
storlines("STOR #{remotefile}", f, &block)
ensure
@@ -1037,11 +1062,12 @@ module Net
TIME_PARSER = ->(value, local = false) {
unless /\A(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})
(?<hour>\d{2})(?<min>\d{2})(?<sec>\d{2})
- (\.(?<fractions>\d+))?/x =~ value
+ (?:\.(?<fractions>\d{1,17}))?/x =~ value
+ value = value[0, 97] + "..." if value.size > 100
raise FTPProtoError, "invalid time-val: #{value}"
end
- usec = fractions.to_i * 10 ** (6 - fractions.to_s.size)
- Time.send(local ? :local : :utc, year, month, day, hour, min, sec, usec)
+ usec = ".#{fractions}".to_r * 1_000_000 if fractions
+ Time.public_send(local ? :local : :utc, year, month, day, hour, min, sec, usec)
}
FACT_PARSERS = Hash.new(CASE_DEPENDENT_PARSER)
FACT_PARSERS["size"] = DECIMAL_PARSER
@@ -1233,8 +1259,9 @@ module Net
#
# Returns the status (STAT command).
- # pathname - when stat is invoked with pathname as a parameter it acts like
- # list but alot faster and over the same tcp session.
+ #
+ # pathname:: when stat is invoked with pathname as a parameter it acts like
+ # list but a lot faster and over the same tcp session.
#
def status(pathname = nil)
line = pathname ? "STAT #{pathname}" : "STAT"
@@ -1295,6 +1322,41 @@ module Net
end
#
+ # Issues a FEAT command
+ #
+ # Returns an array of supported optional features
+ #
+ def features
+ resp = sendcmd("FEAT")
+ if !resp.start_with?("211")
+ raise FTPReplyError, resp
+ end
+
+ feats = []
+ resp.split("\n").each do |line|
+ next if !line.start_with?(' ') # skip status lines
+
+ feats << line.strip
+ end
+
+ return feats
+ end
+
+ #
+ # Issues an OPTS command
+ # - name Should be the name of the option to set
+ # - params is any optional parameters to supply with the option
+ #
+ # example: option('UTF8', 'ON') => 'OPTS UTF8 ON'
+ #
+ def option(name, params = nil)
+ cmd = "OPTS #{name}"
+ cmd += " #{params}" if params
+
+ voidcmd(cmd)
+ end
+
+ #
# Closes the connection. Further operations are impossible until you open
# a new connection with #connect.
#
@@ -1312,7 +1374,7 @@ module Net
end
#
- # Returns +true+ iff the connection is closed.
+ # Returns +true+ if and only if the connection is closed.
#
def closed?
@sock == nil or @sock.closed?
@@ -1326,8 +1388,13 @@ module Net
if !resp.start_with?("227")
raise FTPReplyError, resp
end
- if m = /\((?<host>\d+(,\d+){3}),(?<port>\d+,\d+)\)/.match(resp)
- return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
+ if m = /\((?<host>\d+(?:,\d+){3}),(?<port>\d+,\d+)\)/.match(resp)
+ if @use_pasv_ip
+ host = parse_pasv_ipv4_host(m["host"])
+ else
+ host = @bare_sock.remote_address.ip_address
+ end
+ return host, parse_pasv_port(m["port"])
else
raise FTPProtoError, resp
end
@@ -1342,9 +1409,9 @@ module Net
if !resp.start_with?("228")
raise FTPReplyError, resp
end
- if m = /\(4,4,(?<host>\d+(,\d+){3}),2,(?<port>\d+,\d+)\)/.match(resp)
+ if m = /\(4,4,(?<host>\d+(?:,\d+){3}),2,(?<port>\d+,\d+)\)/.match(resp)
return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
- elsif m = /\(6,16,(?<host>\d+(,(\d+)){15}),2,(?<port>\d+,\d+)\)/.match(resp)
+ elsif m = /\(6,16,(?<host>\d+(?:,\d+){15}),2,(?<port>\d+,\d+)\)/.match(resp)
return parse_pasv_ipv6_host(m["host"]), parse_pasv_port(m["port"])
else
raise FTPProtoError, resp
@@ -1428,7 +1495,7 @@ module Net
s = super(len, String.new, true)
return s.empty? ? nil : s
else
- result = ""
+ result = String.new
while s = super(DEFAULT_BLOCKSIZE, String.new, true)
break if s.empty?
result << s
@@ -1453,7 +1520,7 @@ module Net
if defined?(OpenSSL::SSL::SSLSocket)
class BufferedSSLSocket < BufferedSocket
- def initialize(*args)
+ def initialize(*args, **options)
super
@is_shutdown = false
end
diff --git a/lib/net/http.rb b/lib/net/http.rb
index bfc6d4535d..34fc635a4d 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -22,9 +22,9 @@
require 'net/protocol'
require 'uri'
+autoload :OpenSSL, 'openssl'
module Net #:nodoc:
- autoload :OpenSSL, 'openssl'
# :stopdoc:
class HTTPBadResponse < StandardError; end
@@ -35,7 +35,7 @@ module Net #:nodoc:
#
# Net::HTTP provides a rich library which can be used to build HTTP
# user-agents. For more details about HTTP see
- # [RFC2616](http://www.ietf.org/rfc/rfc2616.txt)
+ # [RFC2616](http://www.ietf.org/rfc/rfc2616.txt).
#
# Net::HTTP is designed to work closely with URI. URI::HTTP#host,
# URI::HTTP#port and URI::HTTP#request_uri are designed to work with
@@ -87,7 +87,7 @@ module Net #:nodoc:
#
# == How to use Net::HTTP
#
- # The following example code can be used as the basis of a HTTP user-agent
+ # The following example code can be used as the basis of an HTTP user-agent
# which can perform a variety of request types using persistent
# connections.
#
@@ -104,14 +104,13 @@ module Net #:nodoc:
# open for multiple requests in the block if the server indicates it
# supports persistent connections.
#
+ # If you wish to re-use a connection across multiple HTTP requests without
+ # automatically closing it you can use ::new and then call #start and
+ # #finish manually.
+ #
# The request types Net::HTTP supports are listed below in the section "HTTP
# Request Classes".
#
- # If you wish to re-use a connection across multiple HTTP requests without
- # automatically closing it you can use ::new instead of ::start. #request
- # will automatically open a connection to the server if one is not currently
- # open. You can manually close the connection with #finish.
- #
# For all the Net::HTTP request objects and shortcut request methods you may
# supply either a String for the request path or a URI from which Net::HTTP
# will extract the request path.
@@ -170,7 +169,7 @@ module Net #:nodoc:
# === POST
#
# A POST can be made using the Net::HTTP::Post request class. This example
- # creates a urlencoded POST body:
+ # creates a URL encoded POST body:
#
# uri = URI('http://www.example.com/todo.cgi')
# req = Net::HTTP::Post.new(uri)
@@ -187,13 +186,10 @@ module Net #:nodoc:
# res.value
# end
#
- # At this time Net::HTTP does not support multipart/form-data. To send
- # multipart/form-data use Net::HTTPRequest#body= and
- # Net::HTTPRequest#content_type=:
+ # To send multipart/form-data use Net::HTTPHeader#set_form:
#
# req = Net::HTTP::Post.new(uri)
- # req.body = multipart_data
- # req.content_type = 'multipart/form-data'
+ # req.set_form([['upload', File.open('foo.bar')]], 'multipart/form-data')
#
# Other requests that can contain a body such as PUT can be created in the
# same way using the corresponding request class (Net::HTTP::Put).
@@ -222,7 +218,7 @@ module Net #:nodoc:
# === Basic Authentication
#
# Basic authentication is performed according to
- # [RFC2617](http://www.ietf.org/rfc/rfc2617.txt)
+ # [RFC2617](http://www.ietf.org/rfc/rfc2617.txt).
#
# uri = URI('http://example.com/index.html?key=value')
#
@@ -266,7 +262,7 @@ module Net #:nodoc:
# end
#
# Or if you simply want to make a GET request, you may pass in an URI
- # object that has a HTTPS URL. Net::HTTP automatically turn on TLS
+ # object that has an HTTPS URL. Net::HTTP automatically turns on TLS
# verification if the URI object has a 'https' URI scheme.
#
# uri = URI('https://example.com/')
@@ -392,6 +388,7 @@ module Net #:nodoc:
class HTTP < Protocol
# :stopdoc:
+ VERSION = "0.1.1"
Revision = %q$Revision$.split[1]
HTTPVersion = '1.1'
begin
@@ -431,7 +428,7 @@ module Net #:nodoc:
#
# Gets the body text from the target and outputs it to $stdout. The
# target can either be specified as
- # (+uri+), or as (+host+, +path+, +port+ = 80); so:
+ # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
#
# Net::HTTP.get_print URI('http://www.example.com/index.html')
#
@@ -439,8 +436,12 @@ module Net #:nodoc:
#
# Net::HTTP.get_print 'www.example.com', '/index.html'
#
- def HTTP.get_print(uri_or_host, path = nil, port = nil)
- get_response(uri_or_host, path, port) {|res|
+ # you can also specify request headers:
+ #
+ # Net::HTTP.get_print URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' }
+ #
+ def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
+ get_response(uri_or_host, path_or_headers, port) {|res|
res.read_body do |chunk|
$stdout.print chunk
end
@@ -450,7 +451,7 @@ module Net #:nodoc:
# Sends a GET request to the target and returns the HTTP response
# as a string. The target can either be specified as
- # (+uri+), or as (+host+, +path+, +port+ = 80); so:
+ # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
#
# print Net::HTTP.get(URI('http://www.example.com/index.html'))
#
@@ -458,13 +459,17 @@ module Net #:nodoc:
#
# print Net::HTTP.get('www.example.com', '/index.html')
#
- def HTTP.get(uri_or_host, path = nil, port = nil)
- get_response(uri_or_host, path, port).body
+ # you can also specify request headers:
+ #
+ # Net::HTTP.get(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
+ #
+ def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
+ get_response(uri_or_host, path_or_headers, port).body
end
# Sends a GET request to the target and returns the HTTP response
# as a Net::HTTPResponse object. The target can either be specified as
- # (+uri+), or as (+host+, +path+, +port+ = 80); so:
+ # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
#
# res = Net::HTTP.get_response(URI('http://www.example.com/index.html'))
# print res.body
@@ -474,17 +479,23 @@ module Net #:nodoc:
# res = Net::HTTP.get_response('www.example.com', '/index.html')
# print res.body
#
- def HTTP.get_response(uri_or_host, path = nil, port = nil, &block)
- if path
+ # you can also specify request headers:
+ #
+ # Net::HTTP.get_response(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
+ #
+ def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
+ if path_or_headers && !path_or_headers.is_a?(Hash)
host = uri_or_host
+ path = path_or_headers
new(host, port || HTTP.default_port).start {|http|
return http.request_get(path, &block)
}
else
uri = uri_or_host
+ headers = path_or_headers
start(uri.hostname, uri.port,
:use_ssl => uri.scheme == 'https') {|http|
- return http.request_get(uri, &block)
+ return http.request_get(uri, headers, &block)
}
end
end
@@ -575,8 +586,8 @@ module Net #:nodoc:
# _opt_ :: optional hash
#
# _opt_ sets following values by its accessor.
- # The keys are ca_file, ca_path, cert, cert_store, ciphers,
- # close_on_empty_response, key, open_timeout, read_timeout, ssl_timeout,
+ # The keys are ipaddr, ca_file, ca_path, cert, cert_store, ciphers, keep_alive_timeout,
+ # close_on_empty_response, key, open_timeout, read_timeout, write_timeout, ssl_timeout,
# ssl_version, use_ssl, verify_callback, verify_depth and verify_mode.
# If you set :use_ssl as true, you can use https and default value of
# verify_mode is set as OpenSSL::SSL::VERIFY_PEER.
@@ -594,6 +605,7 @@ module Net #:nodoc:
p_addr = :ENV if arg.size < 2
port = https_default_port if !port && opt && opt[:use_ssl]
http = new(address, port, p_addr, p_port, p_user, p_pass)
+ http.ipaddr = opt[:ipaddr] if opt && opt[:ipaddr]
if opt
if opt[:use_ssl]
@@ -627,10 +639,10 @@ module Net #:nodoc:
# detection from the environment. To disable proxy detection set +p_addr+
# to nil.
#
- # If you are connecting to a custom proxy, +p_addr+ the DNS name or IP
- # address of the proxy host, +p_port+ the port to use to access the proxy,
- # +p_user+ and +p_pass+ the username and password if authorization is
- # required to use the proxy, and p_no_proxy spcifies hosts which doesn't
+ # If you are connecting to a custom proxy, +p_addr+ specifies the DNS name
+ # or IP address of the proxy host, +p_port+ the port to use to access the
+ # proxy, +p_user+ and +p_pass+ the username and password if authorization
+ # is required to use the proxy, and p_no_proxy hosts which do not
# use the proxy.
#
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
@@ -664,6 +676,7 @@ module Net #:nodoc:
def initialize(address, port = nil)
@address = address
@port = (port || HTTP.default_port)
+ @ipaddr = nil
@local_host = nil
@local_port = nil
@curr_http_version = HTTPVersion
@@ -674,6 +687,7 @@ module Net #:nodoc:
@started = false
@open_timeout = 60
@read_timeout = 60
+ @write_timeout = 60
@continue_timeout = nil
@max_retries = 1
@debug_output = nil
@@ -708,7 +722,7 @@ module Net #:nodoc:
# http.start { .... }
#
def set_debug_output(output)
- warn 'Net::HTTP#set_debug_output called after HTTP started' if started?
+ warn 'Net::HTTP#set_debug_output called after HTTP started', uplevel: 1 if started?
@debug_output = output
end
@@ -730,6 +744,17 @@ module Net #:nodoc:
attr_writer :proxy_user
attr_writer :proxy_pass
+ # The IP address to connect to/used to connect to
+ def ipaddr
+ started? ? @socket.io.peeraddr[3] : @ipaddr
+ end
+
+ # Set the IP address to connect to
+ def ipaddr=(addr)
+ raise IOError, "ipaddr value changed, but session already started" if started?
+ @ipaddr = addr
+ end
+
# Number of seconds to wait for the connection to open. Any number
# may be used, including Floats for fractional seconds. If the HTTP
# object cannot open a connection in this many seconds, it raises a
@@ -742,11 +767,18 @@ module Net #:nodoc:
# it raises a Net::ReadTimeout exception. The default value is 60 seconds.
attr_reader :read_timeout
+ # Number of seconds to wait for one block to be written (via one write(2)
+ # call). Any number may be used, including Floats for fractional
+ # seconds. If the HTTP object cannot write data in this many seconds,
+ # it raises a Net::WriteTimeout exception. The default value is 60 seconds.
+ # Net::WriteTimeout is not raised on Windows.
+ attr_reader :write_timeout
+
# Maximum number of times to retry an idempotent request in case of
# Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET,
# Errno::ECONNABORTED, Errno::EPIPE, OpenSSL::SSL::SSLError,
# Timeout::Error.
- # Should be non-negative integer number. Zero means no retries.
+ # Should be a non-negative integer number. Zero means no retries.
# The default value is 1.
def max_retries=(retries)
retries = retries.to_int
@@ -764,6 +796,12 @@ module Net #:nodoc:
@read_timeout = sec
end
+ # Setter for the write_timeout attribute.
+ def write_timeout=(sec)
+ @socket.write_timeout = sec if @socket
+ @write_timeout = sec
+ end
+
# Seconds to wait for 100 Continue response. If the HTTP object does not
# receive a response in this many seconds it sends the request body. The
# default value is +nil+.
@@ -813,12 +851,16 @@ module Net #:nodoc:
:@cert,
:@cert_store,
:@ciphers,
+ :@extra_chain_cert,
:@key,
:@ssl_timeout,
:@ssl_version,
+ :@min_version,
+ :@max_version,
:@verify_callback,
:@verify_depth,
:@verify_mode,
+ :@verify_hostname,
]
SSL_ATTRIBUTES = [
:ca_file,
@@ -826,12 +868,16 @@ module Net #:nodoc:
:cert,
:cert_store,
:ciphers,
+ :extra_chain_cert,
:key,
:ssl_timeout,
:ssl_version,
+ :min_version,
+ :max_version,
:verify_callback,
:verify_depth,
:verify_mode,
+ :verify_hostname,
]
# Sets path of a CA certification file in PEM format.
@@ -853,6 +899,10 @@ module Net #:nodoc:
# Sets the available ciphers. See OpenSSL::SSL::SSLContext#ciphers=
attr_accessor :ciphers
+ # Sets the extra X509 certificates to be added to the certificate chain.
+ # See OpenSSL::SSL::SSLContext#extra_chain_cert=
+ attr_accessor :extra_chain_cert
+
# Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
# (This method is appeared in Michal Rokos's OpenSSL extension.)
attr_accessor :key
@@ -863,6 +913,12 @@ module Net #:nodoc:
# Sets the SSL version. See OpenSSL::SSL::SSLContext#ssl_version=
attr_accessor :ssl_version
+ # Sets the minimum SSL version. See OpenSSL::SSL::SSLContext#min_version=
+ attr_accessor :min_version
+
+ # Sets the maximum SSL version. See OpenSSL::SSL::SSLContext#max_version=
+ attr_accessor :max_version
+
# Sets the verify callback for the server certification verification.
attr_accessor :verify_callback
@@ -875,6 +931,10 @@ module Net #:nodoc:
# OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER are acceptable.
attr_accessor :verify_mode
+ # Sets to check the server certificate is valid for the hostname.
+ # See OpenSSL::SSL::SSLContext#verify_hostname=
+ attr_accessor :verify_hostname
+
# Returns the X.509 certificates the server presented.
def peer_cert
if not use_ssl? or not @socket
@@ -914,20 +974,20 @@ module Net #:nodoc:
def connect
if proxy? then
- conn_address = proxy_address
- conn_port = proxy_port
+ conn_addr = proxy_address
+ conn_port = proxy_port
else
- conn_address = address
- conn_port = port
+ conn_addr = conn_address
+ conn_port = port
end
- D "opening connection to #{conn_address}:#{conn_port}..."
+ D "opening connection to #{conn_addr}:#{conn_port}..."
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
begin
- TCPSocket.open(conn_address, conn_port, @local_host, @local_port)
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
rescue => e
raise e, "Failed to open TCP connection to " +
- "#{conn_address}:#{conn_port} (#{e.message})"
+ "#{conn_addr}:#{conn_port} (#{e.message})"
end
}
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
@@ -935,9 +995,10 @@ module Net #:nodoc:
if use_ssl?
if proxy?
plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
+ write_timeout: @write_timeout,
continue_timeout: @continue_timeout,
debug_output: @debug_output)
- buf = "CONNECT #{@address}:#{@port} HTTP/#{HTTPVersion}\r\n"
+ buf = "CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n"
buf << "Host: #{@address}:#{@port}\r\n"
if proxy_user
credential = ["#{proxy_user}:#{proxy_pass}"].pack('m0')
@@ -952,30 +1013,36 @@ module Net #:nodoc:
ssl_parameters = Hash.new
iv_list = instance_variables
SSL_IVNAMES.each_with_index do |ivname, i|
- if iv_list.include?(ivname) and
+ if iv_list.include?(ivname)
value = instance_variable_get(ivname)
- ssl_parameters[SSL_ATTRIBUTES[i]] = value if value
+ unless value.nil?
+ ssl_parameters[SSL_ATTRIBUTES[i]] = value
+ end
end
end
@ssl_context = OpenSSL::SSL::SSLContext.new
@ssl_context.set_params(ssl_parameters)
- D "starting SSL for #{conn_address}:#{conn_port}..."
+ @ssl_context.session_cache_mode =
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
+ @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
+ D "starting SSL for #{conn_addr}:#{conn_port}..."
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
s.sync_close = true
# Server Name Indication (SNI) RFC 3546
s.hostname = @address if s.respond_to? :hostname=
if @ssl_session and
Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
- s.session = @ssl_session if @ssl_session
+ s.session = @ssl_session
end
ssl_socket_connect(s, @open_timeout)
- if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
+ if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && @ssl_context.verify_hostname
s.post_connection_check(@address)
end
- @ssl_session = s.session
- D "SSL established"
+ D "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
end
@socket = BufferedIO.new(s, read_timeout: @read_timeout,
+ write_timeout: @write_timeout,
continue_timeout: @continue_timeout,
debug_output: @debug_output)
on_connect
@@ -1136,7 +1203,7 @@ module Net #:nodoc:
# without proxy, obsolete
def conn_address # :nodoc:
- address()
+ @ipaddr || address()
end
def conn_port # :nodoc:
@@ -1479,7 +1546,13 @@ module Net #:nodoc:
begin
begin_transport req
res = catch(:response) {
- req.exec @socket, @curr_http_version, edit_path(req.path)
+ begin
+ req.exec @socket, @curr_http_version, edit_path(req.path)
+ rescue Errno::EPIPE
+ # Failure when writing full request, but we can probably
+ # still read the received response.
+ end
+
begin
res = HTTPResponse.read_new(@socket)
res.decode_content = req.decode_content
@@ -1495,7 +1568,7 @@ module Net #:nodoc:
rescue Net::OpenTimeout
raise
rescue Net::ReadTimeout, IOError, EOFError,
- Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE,
+ Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE, Errno::ETIMEDOUT,
# avoid a dependency on OpenSSL
defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : IOError,
Timeout::Error => exception
@@ -1602,11 +1675,10 @@ module Net #:nodoc:
private
def addr_port
- if use_ssl?
- address() + (port == HTTP.https_default_port ? '' : ":#{port()}")
- else
- address() + (port == HTTP.http_default_port ? '' : ":#{port()}")
- end
+ addr = address
+ addr = "[#{addr}]" if addr.include?(":")
+ default_port = use_ssl? ? HTTP.https_default_port : HTTP.http_default_port
+ default_port == port ? addr : "#{addr}:#{port}"
end
def D(msg)
@@ -1618,17 +1690,17 @@ module Net #:nodoc:
end
-require 'net/http/exceptions'
+require_relative 'http/exceptions'
-require 'net/http/header'
+require_relative 'http/header'
-require 'net/http/generic_request'
-require 'net/http/request'
-require 'net/http/requests'
+require_relative 'http/generic_request'
+require_relative 'http/request'
+require_relative 'http/requests'
-require 'net/http/response'
-require 'net/http/responses'
+require_relative 'http/response'
+require_relative 'http/responses'
-require 'net/http/proxy_delta'
+require_relative 'http/proxy_delta'
-require 'net/http/backward'
+require_relative 'http/backward'
diff --git a/lib/net/http/exceptions.rb b/lib/net/http/exceptions.rb
index 0d34526616..da5f7a70fc 100644
--- a/lib/net/http/exceptions.rb
+++ b/lib/net/http/exceptions.rb
@@ -20,7 +20,14 @@ class Net::HTTPServerException < Net::ProtoServerError
# We cannot use the name "HTTPServerError", it is the name of the response.
include Net::HTTPExceptions
end
+
+# for compatibility
+Net::HTTPClientException = Net::HTTPServerException
+
class Net::HTTPFatalError < Net::ProtoFatalError
include Net::HTTPExceptions
end
+module Net
+ deprecate_constant(:HTTPServerException)
+end
diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb
index 6c5ceafe61..003f59d0ac 100644
--- a/lib/net/http/generic_request.rb
+++ b/lib/net/http/generic_request.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: false
-# HTTPGenericRequest is the parent of the HTTPRequest class.
-# Do not use this directly; use a subclass of HTTPRequest.
+# HTTPGenericRequest is the parent of the Net::HTTPRequest class.
+# Do not use this directly; use a subclass of Net::HTTPRequest.
#
-# Mixes in the HTTPHeader module to provide easier access to HTTP headers.
+# Mixes in the Net::HTTPHeader module to provide easier access to HTTP headers.
#
class Net::HTTPGenericRequest
@@ -14,6 +14,8 @@ class Net::HTTPGenericRequest
@response_has_body = resbody
if URI === uri_or_path then
+ raise ArgumentError, "not an HTTP URI" unless URI::HTTP === uri_or_path
+ raise ArgumentError, "no host component for URI" unless uri_or_path.hostname
@uri = uri_or_path.dup
host = @uri.hostname.dup
host << ":".freeze << @uri.port.to_s if @uri.port != @uri.default_port
@@ -82,7 +84,7 @@ class Net::HTTPGenericRequest
end
def body_exist?
- warn "Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?" if $VERBOSE
+ warn "Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?", uplevel: 1 if $VERBOSE
response_body_permitted?
end
@@ -168,9 +170,8 @@ class Net::HTTPGenericRequest
def write(buf)
# avoid memcpy() of buf, buf can huge and eat memory bandwidth
- @sock.write("#{buf.bytesize.to_s(16)}\r\n")
- rv = @sock.write(buf)
- @sock.write("\r\n")
+ rv = buf.bytesize
+ @sock.write("#{rv.to_s(16)}\r\n", buf, "\r\n")
rv
end
@@ -299,7 +300,7 @@ class Net::HTTPGenericRequest
def supply_default_content_type
return if content_type()
- warn 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
+ warn 'net/http: Content-Type did not set; using application/x-www-form-urlencoded', uplevel: 1 if $VERBOSE
set_content_type 'application/x-www-form-urlencoded'
end
diff --git a/lib/net/http/header.rb b/lib/net/http/header.rb
index 8f3206d363..495425d148 100644
--- a/lib/net/http/header.rb
+++ b/lib/net/http/header.rb
@@ -9,16 +9,28 @@
# convenient formats.
#
module Net::HTTPHeader
+ MAX_KEY_LENGTH = 1024
+ MAX_FIELD_LENGTH = 65536
def initialize_http_header(initheader)
@header = {}
return unless initheader
initheader.each do |key, value|
- warn "net/http: warning: duplicated HTTP header: #{key}" if key?(key) and $VERBOSE
+ warn "net/http: duplicated HTTP header: #{key}", uplevel: 3 if key?(key) and $VERBOSE
if value.nil?
- warn "net/http: warning: nil HTTP header: #{key}" if $VERBOSE
+ warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE
else
- @header[key.downcase] = [value.strip]
+ value = value.strip # raise error for invalid byte sequences
+ if key.to_s.bytesize > MAX_KEY_LENGTH
+ raise ArgumentError, "too long (#{key.bytesize} bytes) header: #{key[0, 30].inspect}..."
+ end
+ if value.to_s.bytesize > MAX_FIELD_LENGTH
+ raise ArgumentError, "header #{key} has too long field vallue: #{value.bytesize}"
+ end
+ if value.count("\r\n") > 0
+ raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF"
+ end
+ @header[key.downcase.to_s] = [value]
end
end
end
@@ -32,14 +44,14 @@ module Net::HTTPHeader
# Returns the header field corresponding to the case-insensitive key.
# For example, a key of "Content-Type" might return "text/html"
def [](key)
- a = @header[key.downcase] or return nil
+ a = @header[key.downcase.to_s] or return nil
a.join(', ')
end
# Sets the header field corresponding to the case-insensitive key.
def []=(key, val)
unless val
- @header.delete key.downcase
+ @header.delete key.downcase.to_s
return val
end
set_field(key, val)
@@ -61,8 +73,9 @@ module Net::HTTPHeader
# p request.get_fields('X-My-Header') #=> ["a", "b", "c"]
#
def add_field(key, val)
- if @header.key?(key.downcase)
- append_field_value(@header[key.downcase], val)
+ stringified_downcased_key = key.downcase.to_s
+ if @header.key?(stringified_downcased_key)
+ append_field_value(@header[stringified_downcased_key], val)
else
set_field(key, val)
end
@@ -73,13 +86,13 @@ module Net::HTTPHeader
when Enumerable
ary = []
append_field_value(ary, val)
- @header[key.downcase] = ary
+ @header[key.downcase.to_s] = ary
else
- val = val.to_s
- if /[\r\n]/n.match?(val.b)
- raise ArgumentError, 'header field value cannnot include CR/LF'
+ val = val.to_s # for compatibility use to_s instead of to_str
+ if val.b.count("\r\n") > 0
+ raise ArgumentError, 'header field value cannot include CR/LF'
end
- @header[key.downcase] = [val]
+ @header[key.downcase.to_s] = [val]
end
end
@@ -90,7 +103,7 @@ module Net::HTTPHeader
else
val = val.to_s
if /[\r\n]/n.match?(val.b)
- raise ArgumentError, 'header field value cannnot include CR/LF'
+ raise ArgumentError, 'header field value cannot include CR/LF'
end
ary.push val
end
@@ -108,8 +121,9 @@ module Net::HTTPHeader
# #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"
#
def get_fields(key)
- return nil unless @header[key.downcase]
- @header[key.downcase].dup
+ stringified_downcased_key = key.downcase.to_s
+ return nil unless @header[stringified_downcased_key]
+ @header[stringified_downcased_key].dup
end
# Returns the header field corresponding to the case-insensitive key.
@@ -117,7 +131,7 @@ module Net::HTTPHeader
# raises an IndexError if there's no header field named +key+
# See Hash#fetch
def fetch(key, *args, &block) #:yield: +key+
- a = @header.fetch(key.downcase, *args, &block)
+ a = @header.fetch(key.downcase.to_s, *args, &block)
a.kind_of?(Array) ? a.join(', ') : a
end
@@ -178,12 +192,12 @@ module Net::HTTPHeader
# Removes a header field, specified by case-insensitive key.
def delete(key)
- @header.delete(key.downcase)
+ @header.delete(key.downcase.to_s)
end
# true if +key+ header exists.
def key?(key)
- @header.key?(key.downcase)
+ @header.key?(key.downcase.to_s)
end
# Returns a Hash consisting of header names and array of values.
@@ -317,7 +331,7 @@ module Net::HTTPHeader
end
# Returns "true" if the "transfer-encoding" header is present and
- # set to "chunked". This is an HTTP/1.1 feature, allowing the
+ # set to "chunked". This is an HTTP/1.1 feature, allowing
# the content to be sent in "chunks" without at the outset
# stating the entire content length.
def chunked?
@@ -417,30 +431,50 @@ module Net::HTTPHeader
alias form_data= set_form_data
# Set an HTML form data set.
- # +params+ is the form data set; it is an Array of Arrays or a Hash
- # +enctype is the type to encode the form data set.
- # It is application/x-www-form-urlencoded or multipart/form-data.
- # +formopt+ is an optional hash to specify the detail.
- #
- # boundary:: the boundary of the multipart message
- # charset:: the charset of the message. All names and the values of
- # non-file fields are encoded as the charset.
+ # +params+ :: The form data to set, which should be an enumerable.
+ # See below for more details.
+ # +enctype+ :: The content type to use to encode the form submission,
+ # which should be application/x-www-form-urlencoded or
+ # multipart/form-data.
+ # +formopt+ :: An options hash, supporting the following options:
+ # :boundary :: The boundary of the multipart message. If
+ # not given, a random boundary will be used.
+ # :charset :: The charset of the form submission. All
+ # field names and values of non-file fields
+ # should be encoded with this charset.
#
- # Each item of params is an array and contains following items:
- # +name+:: the name of the field
- # +value+:: the value of the field, it should be a String or a File
- # +opt+:: an optional hash to specify additional information
+ # Each item of params should respond to +each+ and yield 2-3 arguments,
+ # or an array of 2-3 elements. The arguments yielded should be:
+ # * The name of the field.
+ # * The value of the field, it should be a String or a File or IO-like.
+ # * An options hash, supporting the following options, only
+ # used for file uploads:
+ # :filename :: The name of the file to use.
+ # :content_type :: The content type of the uploaded file.
#
# Each item is a file field or a normal field.
- # If +value+ is a File object or the +opt+ have a filename key,
+ # If +value+ is a File object or the +opt+ hash has a :filename key,
# the item is treated as a file field.
#
- # If Transfer-Encoding is set as chunked, this send the request in
+ # If Transfer-Encoding is set as chunked, this sends the request using
# chunked encoding. Because chunked encoding is HTTP/1.1 feature,
- # you must confirm the server to support HTTP/1.1 before sending it.
+ # you should confirm that the server supports HTTP/1.1 before using
+ # chunked encoding.
#
# Example:
- # http.set_form([["q", "ruby"], ["lang", "en"]])
+ # req.set_form([["q", "ruby"], ["lang", "en"]])
+ #
+ # req.set_form({"f"=>File.open('/path/to/filename')},
+ # "multipart/form-data",
+ # charset: "UTF-8",
+ # )
+ #
+ # req.set_form([["f",
+ # File.open('/path/to/filename.bar'),
+ # {filename: "other-filename.foo"}
+ # ]],
+ # "multipart/form-data",
+ # )
#
# See also RFC 2388, RFC 2616, HTML 4.01, and HTML5
#
diff --git a/lib/net/http/net-http.gemspec b/lib/net/http/net-http.gemspec
new file mode 100644
index 0000000000..f5ef4045e8
--- /dev/null
+++ b/lib/net/http/net-http.gemspec
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["NARUSE, Yui"]
+ spec.email = ["naruse@airemix.jp"]
+
+ spec.summary = %q{HTTP client api for Ruby.}
+ spec.description = %q{HTTP client api for Ruby.}
+ spec.homepage = "https://github.com/ruby/net-http"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "net-protocol"
+ spec.add_dependency "uri"
+end
diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb
index 1351d7b2d2..08eaeb2cac 100644
--- a/lib/net/http/response.rb
+++ b/lib/net/http/response.rb
@@ -8,11 +8,13 @@
# header values both via hash-like methods and via individual readers.
#
# Note that each possible HTTP response code defines its own
-# HTTPResponse subclass. These are listed below.
+# HTTPResponse subclass. All classes are defined under the Net module.
+# Indentation indicates inheritance. For a list of the classes see Net::HTTP.
#
-# All classes are defined under the Net module. Indentation indicates
-# inheritance. For a list of the classes see Net::HTTP.
+# Correspondence <code>HTTP code => class</code> is stored in CODE_TO_OBJ
+# constant:
#
+# Net::HTTPResponse::CODE_TO_OBJ['404'] #=> Net::HTTPNotFound
#
class Net::HTTPResponse
class << self
@@ -140,17 +142,17 @@ class Net::HTTPResponse
#
def response #:nodoc:
- warn "#{caller(1)[0]}: warning: Net::HTTPResponse#response is obsolete" if $VERBOSE
+ warn "Net::HTTPResponse#response is obsolete", uplevel: 1 if $VERBOSE
self
end
def header #:nodoc:
- warn "#{caller(1)[0]}: warning: Net::HTTPResponse#header is obsolete" if $VERBOSE
+ warn "Net::HTTPResponse#header is obsolete", uplevel: 1 if $VERBOSE
self
end
def read_header #:nodoc:
- warn "#{caller(1)[0]}: warning: Net::HTTPResponse#read_header is obsolete" if $VERBOSE
+ warn "Net::HTTPResponse#read_header is obsolete", uplevel: 1 if $VERBOSE
self
end
@@ -174,6 +176,10 @@ class Net::HTTPResponse
# If a block is given, the body is passed to the block, and
# the body is provided in fragments, as it is read in from the socket.
#
+ # If +dest+ argument is given, response is read into that variable,
+ # with <code>dest#<<</code> method (it could be String or IO, or any
+ # other object responding to <code><<</code>).
+ #
# Calling this method a second or subsequent time for the same
# HTTPResponse object will return the value already read.
#
@@ -262,12 +268,13 @@ class Net::HTTPResponse
begin
yield inflate_body_io
+ success = true
ensure
- orig_err = $!
begin
inflate_body_io.finish
rescue => err
- raise orig_err || err
+ # Ignore #finish's error if there is an exception from yield
+ raise err if success
end
end
when 'none', 'identity' then
@@ -380,6 +387,7 @@ class Net::HTTPResponse
end
block = proc do |compressed_chunk|
@inflate.inflate(compressed_chunk) do |chunk|
+ compressed_chunk.clear
dest << chunk
end
end
diff --git a/lib/net/http/responses.rb b/lib/net/http/responses.rb
index c4259e1a02..50352032df 100644
--- a/lib/net/http/responses.rb
+++ b/lib/net/http/responses.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
# :stopdoc:
# https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
class Net::HTTPUnknownResponse < Net::HTTPResponse
@@ -19,7 +19,7 @@ class Net::HTTPRedirection < Net::HTTPResponse # 3xx
end
class Net::HTTPClientError < Net::HTTPResponse # 4xx
HAS_BODY = true
- EXCEPTION_TYPE = Net::HTTPServerException # for backward compatibility
+ EXCEPTION_TYPE = Net::HTTPClientException # for backward compatibility
end
class Net::HTTPServerError < Net::HTTPResponse # 5xx
HAS_BODY = true
@@ -35,6 +35,9 @@ end
class Net::HTTPProcessing < Net::HTTPInformation # 102
HAS_BODY = false
end
+class Net::HTTPEarlyHints < Net::HTTPInformation # 103 - RFC 8297
+ HAS_BODY = false
+end
class Net::HTTPOK < Net::HTTPSuccess # 200
HAS_BODY = true
@@ -119,9 +122,10 @@ end
class Net::HTTPProxyAuthenticationRequired < Net::HTTPClientError # 407
HAS_BODY = true
end
-class Net::HTTPRequestTimeOut < Net::HTTPClientError # 408
+class Net::HTTPRequestTimeout < Net::HTTPClientError # 408
HAS_BODY = true
end
+Net::HTTPRequestTimeOut = Net::HTTPRequestTimeout
class Net::HTTPConflict < Net::HTTPClientError # 409
HAS_BODY = true
end
@@ -134,19 +138,22 @@ end
class Net::HTTPPreconditionFailed < Net::HTTPClientError # 412
HAS_BODY = true
end
-class Net::HTTPRequestEntityTooLarge < Net::HTTPClientError # 413
+class Net::HTTPPayloadTooLarge < Net::HTTPClientError # 413
HAS_BODY = true
end
-class Net::HTTPRequestURITooLong < Net::HTTPClientError # 414
+Net::HTTPRequestEntityTooLarge = Net::HTTPPayloadTooLarge
+class Net::HTTPURITooLong < Net::HTTPClientError # 414
HAS_BODY = true
end
+Net::HTTPRequestURITooLong = Net::HTTPURITooLong
Net::HTTPRequestURITooLarge = Net::HTTPRequestURITooLong
class Net::HTTPUnsupportedMediaType < Net::HTTPClientError # 415
HAS_BODY = true
end
-class Net::HTTPRequestedRangeNotSatisfiable < Net::HTTPClientError # 416
+class Net::HTTPRangeNotSatisfiable < Net::HTTPClientError # 416
HAS_BODY = true
end
+Net::HTTPRequestedRangeNotSatisfiable = Net::HTTPRangeNotSatisfiable
class Net::HTTPExpectationFailed < Net::HTTPClientError # 417
HAS_BODY = true
end
@@ -197,9 +204,10 @@ end
class Net::HTTPServiceUnavailable < Net::HTTPServerError # 503
HAS_BODY = true
end
-class Net::HTTPGatewayTimeOut < Net::HTTPServerError # 504
+class Net::HTTPGatewayTimeout < Net::HTTPServerError # 504
HAS_BODY = true
end
+Net::HTTPGatewayTimeOut = Net::HTTPGatewayTimeout
class Net::HTTPVersionNotSupported < Net::HTTPServerError # 505
HAS_BODY = true
end
@@ -232,6 +240,7 @@ class Net::HTTPResponse
'100' => Net::HTTPContinue,
'101' => Net::HTTPSwitchProtocol,
'102' => Net::HTTPProcessing,
+ '103' => Net::HTTPEarlyHints,
'200' => Net::HTTPOK,
'201' => Net::HTTPCreated,
@@ -261,15 +270,15 @@ class Net::HTTPResponse
'405' => Net::HTTPMethodNotAllowed,
'406' => Net::HTTPNotAcceptable,
'407' => Net::HTTPProxyAuthenticationRequired,
- '408' => Net::HTTPRequestTimeOut,
+ '408' => Net::HTTPRequestTimeout,
'409' => Net::HTTPConflict,
'410' => Net::HTTPGone,
'411' => Net::HTTPLengthRequired,
'412' => Net::HTTPPreconditionFailed,
- '413' => Net::HTTPRequestEntityTooLarge,
- '414' => Net::HTTPRequestURITooLong,
+ '413' => Net::HTTPPayloadTooLarge,
+ '414' => Net::HTTPURITooLong,
'415' => Net::HTTPUnsupportedMediaType,
- '416' => Net::HTTPRequestedRangeNotSatisfiable,
+ '416' => Net::HTTPRangeNotSatisfiable,
'417' => Net::HTTPExpectationFailed,
'421' => Net::HTTPMisdirectedRequest,
'422' => Net::HTTPUnprocessableEntity,
@@ -285,7 +294,7 @@ class Net::HTTPResponse
'501' => Net::HTTPNotImplemented,
'502' => Net::HTTPBadGateway,
'503' => Net::HTTPServiceUnavailable,
- '504' => Net::HTTPGatewayTimeOut,
+ '504' => Net::HTTPGatewayTimeout,
'505' => Net::HTTPVersionNotSupported,
'506' => Net::HTTPVariantAlsoNegotiates,
'507' => Net::HTTPInsufficientStorage,
@@ -296,4 +305,3 @@ class Net::HTTPResponse
end
# :startdoc:
-
diff --git a/lib/net/http/status.rb b/lib/net/http/status.rb
index c7a4c0cee3..8db3f7d9e3 100644
--- a/lib/net/http/status.rb
+++ b/lib/net/http/status.rb
@@ -1,7 +1,6 @@
-#!/usr/bin/env ruby
# frozen_string_literal: true
-require 'net/http'
+require_relative '../http'
if $0 == __FILE__
require 'open-uri'
@@ -24,6 +23,7 @@ Net::HTTP::STATUS_CODES = {
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
+ 103 => 'Early Hints',
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
diff --git a/lib/net/https.rb b/lib/net/https.rb
index 58cb6ddf19..d46721c82a 100644
--- a/lib/net/https.rb
+++ b/lib/net/https.rb
@@ -19,5 +19,5 @@
=end
-require 'net/http'
+require_relative 'http'
require 'openssl'
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index bb6754c732..d45304f289 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -201,6 +201,8 @@ module Net
# Unicode", RFC 2152, May 1997.
#
class IMAP < Protocol
+ VERSION = "0.1.1"
+
include MonitorMixin
if defined?(OpenSSL::SSL)
include OpenSSL
@@ -903,8 +905,9 @@ module Net
# end
# }
#
- def add_response_handler(handler = Proc.new)
- @response_handlers.push(handler)
+ def add_response_handler(handler = nil, &block)
+ raise ArgumentError, "two Procs are passed" if handler && block
+ @response_handlers.push(block || handler)
end
# Removes the response handler.
@@ -959,7 +962,7 @@ module Net
put_string("#{tag} IDLE#{CRLF}")
begin
- add_response_handler(response_handler)
+ add_response_handler(&response_handler)
@idle_done_cond = new_cond
@idle_done_cond.wait(timeout)
@idle_done_cond = nil
@@ -999,7 +1002,7 @@ module Net
def self.decode_utf7(s)
return s.gsub(/&([^-]+)?-/n) {
if $1
- ($1.tr(",", "/") + "===").unpack("m")[0].encode(Encoding::UTF_8, Encoding::UTF_16BE)
+ ($1.tr(",", "/") + "===").unpack1("m").encode(Encoding::UTF_8, Encoding::UTF_16BE)
else
"&"
end
@@ -1129,7 +1132,9 @@ module Net
end
def tcp_socket(host, port)
- Socket.tcp(host, port, :connect_timeout => @open_timeout)
+ s = Socket.tcp(host, port, :connect_timeout => @open_timeout)
+ s.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, true)
+ s
rescue Errno::ETIMEDOUT
raise Net::OpenTimeout, "Timeout to open TCP connection to " +
"#{host}:#{port} (exceeds #{@open_timeout} seconds)"
@@ -1213,12 +1218,14 @@ module Net
end
resp = @tagged_responses.delete(tag)
case resp.name
+ when /\A(?:OK)\z/ni
+ return resp
when /\A(?:NO)\z/ni
raise NoResponseError, resp
when /\A(?:BAD)\z/ni
raise BadResponseError, resp
else
- return resp
+ raise UnknownResponseError, resp
end
end
@@ -1265,7 +1272,7 @@ module Net
@logout_command_tag = tag
end
if block
- add_response_handler(block)
+ add_response_handler(&block)
end
begin
return get_tagged_response(tag, cmd)
@@ -1323,11 +1330,11 @@ module Net
when nil
put_string("NIL")
when String
- send_string_data(data)
+ send_string_data(data, tag)
when Integer
send_number_data(data)
when Array
- send_list_data(data)
+ send_list_data(data, tag)
when Time
send_time_data(data)
when Symbol
@@ -1337,13 +1344,13 @@ module Net
end
end
- def send_string_data(str)
+ def send_string_data(str, tag = nil)
case str
when ""
put_string('""')
when /[\x80-\xff\r\n]/n
# literal
- send_literal(str)
+ send_literal(str, tag)
when /[(){ \x00-\x1f\x7f%*"\\]/n
# quoted string
send_quoted_string(str)
@@ -1356,7 +1363,7 @@ module Net
put_string('"' + str.gsub(/["\\]/n, "\\\\\\&") + '"')
end
- def send_literal(str, tag)
+ def send_literal(str, tag = nil)
synchronize do
put_string("{" + str.bytesize.to_s + "}" + CRLF)
@continued_command_tag = tag
@@ -1377,7 +1384,7 @@ module Net
put_string(num.to_s)
end
- def send_list_data(list)
+ def send_list_data(list, tag = nil)
put_string("(")
first = true
list.each do |i|
@@ -1386,7 +1393,7 @@ module Net
else
put_string(" ")
end
- send_data(i)
+ send_data(i, tag)
end
put_string(")")
end
@@ -1528,6 +1535,7 @@ module Net
end
@sock = SSLSocket.new(@sock, context)
@sock.sync_close = true
+ @sock.hostname = @host if @sock.respond_to? :hostname=
ssl_socket_connect(@sock, @open_timeout)
if context.verify_mode != VERIFY_NONE
@sock.post_connection_check(@host)
@@ -1536,7 +1544,7 @@ module Net
class RawData # :nodoc:
def send_data(imap, tag)
- imap.send(:put_string, @data)
+ imap.__send__(:put_string, @data)
end
def validate
@@ -1551,7 +1559,7 @@ module Net
class Atom # :nodoc:
def send_data(imap, tag)
- imap.send(:put_string, @data)
+ imap.__send__(:put_string, @data)
end
def validate
@@ -1566,7 +1574,7 @@ module Net
class QuotedString # :nodoc:
def send_data(imap, tag)
- imap.send(:send_quoted_string, @data)
+ imap.__send__(:send_quoted_string, @data)
end
def validate
@@ -1581,7 +1589,7 @@ module Net
class Literal # :nodoc:
def send_data(imap, tag)
- imap.send(:send_literal, @data, tag)
+ imap.__send__(:send_literal, @data, tag)
end
def validate
@@ -1596,7 +1604,7 @@ module Net
class MessageSet # :nodoc:
def send_data(imap, tag)
- imap.send(:put_string, format_internal(@data))
+ imap.__send__(:put_string, format_internal(@data))
end
def validate
@@ -2032,8 +2040,7 @@ module Net
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
- $stderr.printf("warning: media_subtype is obsolete.\n")
- $stderr.printf(" use subtype instead.\n")
+ warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
@@ -2060,8 +2067,7 @@ module Net
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
- $stderr.printf("warning: media_subtype is obsolete.\n")
- $stderr.printf(" use subtype instead.\n")
+ warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
@@ -2090,8 +2096,7 @@ module Net
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
- $stderr.printf("warning: media_subtype is obsolete.\n")
- $stderr.printf(" use subtype instead.\n")
+ warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
@@ -2151,8 +2156,7 @@ module Net
# generate a warning message to +stderr+, then return
# the value of +subtype+.
def media_subtype
- $stderr.printf("warning: media_subtype is obsolete.\n")
- $stderr.printf(" use subtype instead.\n")
+ warn("media_subtype is obsolete, use subtype instead.\n", uplevel: 1)
return subtype
end
end
@@ -3239,7 +3243,7 @@ module Net
if atom
atom
else
- symbol = flag.capitalize.untaint.intern
+ symbol = flag.capitalize.intern
@flag_symbols[symbol] = true
if @flag_symbols.length > IMAP.max_flag_count
raise FlagCountError, "number of flag symbols exceeded"
@@ -3717,6 +3721,10 @@ module Net
class ByeResponseError < ResponseError
end
+ # Error raised upon an unknown response from the server.
+ class UnknownResponseError < ResponseError
+ end
+
RESPONSE_ERRORS = Hash.new(ResponseError)
RESPONSE_ERRORS["NO"] = NoResponseError
RESPONSE_ERRORS["BAD"] = BadResponseError
diff --git a/lib/net/net-ftp.gemspec b/lib/net/net-ftp.gemspec
new file mode 100644
index 0000000000..f5eb098135
--- /dev/null
+++ b/lib/net/net-ftp.gemspec
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-"), "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Shugo Maeda"]
+ spec.email = ["shugo@ruby-lang.org"]
+
+ spec.summary = %q{Support for the File Transfer Protocol.}
+ spec.description = %q{Support for the File Transfer Protocol.}
+ spec.homepage = "https://github.com/ruby/net-ftp"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "net-protocol"
+ spec.add_dependency "time"
+end
diff --git a/lib/net/net-imap.gemspec b/lib/net/net-imap.gemspec
new file mode 100644
index 0000000000..d7c341cd92
--- /dev/null
+++ b/lib/net/net-imap.gemspec
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-"), "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Shugo Maeda"]
+ spec.email = ["shugo@ruby-lang.org"]
+
+ spec.summary = %q{Ruby client api for Internet Message Access Protocol}
+ spec.description = %q{Ruby client api for Internet Message Access Protocol}
+ spec.homepage = "https://github.com/ruby/net-imap"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "net-protocol"
+ spec.add_dependency "digest"
+ spec.add_dependency "strscan"
+end
diff --git a/lib/net/net-pop.gemspec b/lib/net/net-pop.gemspec
new file mode 100644
index 0000000000..2a89f6086d
--- /dev/null
+++ b/lib/net/net-pop.gemspec
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-"), "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Ruby client library for POP3.}
+ spec.description = %q{Ruby client library for POP3.}
+ spec.homepage = "https://github.com/ruby/net-pop"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "net-protocol"
+ spec.add_dependency "digest"
+ spec.add_dependency "timeout"
+end
diff --git a/lib/net/net-protocol.gemspec b/lib/net/net-protocol.gemspec
new file mode 100644
index 0000000000..767a7d48e2
--- /dev/null
+++ b/lib/net/net-protocol.gemspec
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-"), "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{The abstruct interface for net-* client.}
+ spec.description = %q{The abstruct interface for net-* client.}
+ spec.homepage = "https://github.com/ruby/net-protocol"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "timeout"
+ spec.add_dependency "io-wait"
+end
diff --git a/lib/net/net-smtp.gemspec b/lib/net/net-smtp.gemspec
new file mode 100644
index 0000000000..bd0a2dd84c
--- /dev/null
+++ b/lib/net/net-smtp.gemspec
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-"), "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Simple Mail Transfer Protocol client library for Ruby.}
+ spec.description = %q{Simple Mail Transfer Protocol client library for Ruby.}
+ spec.homepage = "https://github.com/ruby/net-smtp"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = ">= 2.5.0"
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "net-protocol"
+ spec.add_dependency "digest"
+ spec.add_dependency "timeout"
+end
diff --git a/lib/net/pop.rb b/lib/net/pop.rb
index 55597f2fab..8e75846820 100644
--- a/lib/net/pop.rb
+++ b/lib/net/pop.rb
@@ -194,9 +194,8 @@ module Net
# String. Normally the unique-id is a hash of the message.
#
class POP3 < Protocol
-
- # svn revision of this library
- Revision = %q$Revision$.split[1]
+ # version of this library
+ VERSION = "0.1.1"
#
# Class Parameters
@@ -467,7 +466,7 @@ module Net
# Provide human-readable stringification of class state.
def inspect
- "#<#{self.class} #{@address}:#{@port} open=#{@started}>"
+ +"#<#{self.class} #{@address}:#{@port} open=#{@started}>"
end
# *WARNING*: This method causes a serious security hole.
@@ -549,6 +548,7 @@ module Net
context = OpenSSL::SSL::SSLContext.new
context.set_params(@ssl_params)
s = OpenSSL::SSL::SSLSocket.new(s, context)
+ s.hostname = @address
s.sync_close = true
ssl_socket_connect(s, @open_timeout)
if context.verify_mode != OpenSSL::SSL::VERIFY_NONE
@@ -758,7 +758,7 @@ module Net
# Provide human-readable stringification of class state.
def inspect
- "#<#{self.class} #{@number}#{@deleted ? ' deleted' : ''}>"
+ +"#<#{self.class} #{@number}#{@deleted ? ' deleted' : ''}>"
end
#
@@ -799,7 +799,7 @@ module Net
#
# This method raises a POPError if an error occurs.
#
- def pop( dest = '', &block ) # :yield: message_chunk
+ def pop( dest = +'', &block ) # :yield: message_chunk
if block_given?
@command.retr(@number, &block)
nil
@@ -819,7 +819,7 @@ module Net
# The optional +dest+ argument is obsolete.
#
# This method raises a POPError if an error occurs.
- def top(lines, dest = '')
+ def top(lines, dest = +'')
@command.top(@number, lines) do |chunk|
dest << chunk
end
@@ -831,7 +831,7 @@ module Net
# The optional +dest+ argument is obsolete.
#
# This method raises a POPError if an error occurs.
- def header(dest = '')
+ def header(dest = +'')
top(0, dest)
end
@@ -898,7 +898,7 @@ module Net
attr_reader :socket
def inspect
- "#<#{self.class} socket=#{@socket}>"
+ +"#<#{self.class} socket=#{@socket}>"
end
def auth(account, password)
@@ -969,7 +969,7 @@ module Net
getok('UIDL')
table = {}
@socket.each_list_item do |line|
- num, uid = line.split
+ num, uid = line.split(' ')
table[num.to_i] = uid
end
return table
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 0e887d5aa9..edf2ed5a00 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -26,6 +26,8 @@ require 'io/wait'
module Net # :nodoc:
class Protocol #:nodoc: internal use only
+ VERSION = "0.1.1"
+
private
def Protocol.protocol_param(name, val)
module_eval(<<-End, __FILE__, __LINE__ + 1)
@@ -75,20 +77,54 @@ module Net # :nodoc:
# ReadTimeout, a subclass of Timeout::Error, is raised if a chunk of the
# response cannot be read within the read_timeout.
- class ReadTimeout < Timeout::Error; end
+ class ReadTimeout < Timeout::Error
+ def initialize(io = nil)
+ @io = io
+ end
+ attr_reader :io
+
+ def message
+ msg = super
+ if @io
+ msg = "#{msg} with #{@io.inspect}"
+ end
+ msg
+ end
+ end
+
+ ##
+ # WriteTimeout, a subclass of Timeout::Error, is raised if a chunk of the
+ # response cannot be written within the write_timeout. Not raised on Windows.
+
+ class WriteTimeout < Timeout::Error
+ def initialize(io = nil)
+ @io = io
+ end
+ attr_reader :io
+
+ def message
+ msg = super
+ if @io
+ msg = "#{msg} with #{@io.inspect}"
+ end
+ msg
+ end
+ end
class BufferedIO #:nodoc: internal use only
- def initialize(io, read_timeout: 60, continue_timeout: nil, debug_output: nil)
+ def initialize(io, read_timeout: 60, write_timeout: 60, continue_timeout: nil, debug_output: nil)
@io = io
@read_timeout = read_timeout
+ @write_timeout = write_timeout
@continue_timeout = continue_timeout
@debug_output = debug_output
- @rbuf = ''.dup
+ @rbuf = ''.b
end
attr_reader :io
attr_accessor :read_timeout
+ attr_accessor :write_timeout
attr_accessor :continue_timeout
attr_accessor :debug_output
@@ -114,7 +150,7 @@ module Net # :nodoc:
public
- def read(len, dest = ''.dup, ignore_eof = false)
+ def read(len, dest = ''.b, ignore_eof = false)
LOG "reading #{len} bytes..."
read_bytes = 0
begin
@@ -134,7 +170,7 @@ module Net # :nodoc:
dest
end
- def read_all(dest = ''.dup)
+ def read_all(dest = ''.b)
LOG 'reading all...'
read_bytes = 0
begin
@@ -172,18 +208,20 @@ module Net # :nodoc:
BUFSIZE = 1024 * 16
def rbuf_fill
- case rv = @io.read_nonblock(BUFSIZE, exception: false)
+ tmp = @rbuf.empty? ? @rbuf : nil
+ case rv = @io.read_nonblock(BUFSIZE, tmp, exception: false)
when String
+ return if rv.equal?(tmp)
@rbuf << rv
rv.clear
return
when :wait_readable
- @io.to_io.wait_readable(@read_timeout) or raise Net::ReadTimeout
+ (io = @io.to_io).wait_readable(@read_timeout) or raise Net::ReadTimeout.new(io)
# continue looping
when :wait_writable
# OpenSSL::Buffering#read_nonblock may fail with IO::WaitWritable.
# http://www.openssl.org/support/faq.html#PROG10
- @io.to_io.wait_writable(@read_timeout) or raise Net::ReadTimeout
+ (io = @io.to_io).wait_writable(@read_timeout) or raise Net::ReadTimeout.new(io)
# continue looping
when nil
raise EOFError, 'end of file reached'
@@ -191,7 +229,12 @@ module Net # :nodoc:
end
def rbuf_consume(len)
- s = @rbuf.slice!(0, len)
+ if len == @rbuf.size
+ s = @rbuf
+ @rbuf = ''.b
+ else
+ s = @rbuf.slice!(0, len)
+ end
@debug_output << %Q[-> #{s.dump}\n] if @debug_output
s
end
@@ -202,9 +245,9 @@ module Net # :nodoc:
public
- def write(str)
+ def write(*strs)
writing {
- write0 str
+ write0(*strs)
}
end
@@ -228,11 +271,34 @@ module Net # :nodoc:
bytes
end
- def write0(str)
- @debug_output << str.dump if @debug_output
- len = @io.write(str)
- @written_bytes += len
- len
+ def write0(*strs)
+ @debug_output << strs.map(&:dump).join if @debug_output
+ orig_written_bytes = @written_bytes
+ strs.each_with_index do |str, i|
+ need_retry = true
+ case len = @io.write_nonblock(str, exception: false)
+ when Integer
+ @written_bytes += len
+ len -= str.bytesize
+ if len == 0
+ if strs.size == i+1
+ return @written_bytes - orig_written_bytes
+ else
+ need_retry = false
+ # next string
+ end
+ elsif len < 0
+ str = str.byteslice(len, -len)
+ else # len > 0
+ need_retry = false
+ # next string
+ end
+ # continue looping
+ when :wait_writable
+ (io = @io.to_io).wait_writable(@write_timeout) or raise Net::WriteTimeout.new(io)
+ # continue looping
+ end while need_retry
+ end
end
#
@@ -258,7 +324,7 @@ module Net # :nodoc:
class InternetMessageIO < BufferedIO #:nodoc: internal use only
- def initialize(*)
+ def initialize(*, **)
super
@wbuf = nil
end
@@ -273,7 +339,7 @@ module Net # :nodoc:
read_bytes = 0
while (line = readuntil("\r\n")) != ".\r\n"
read_bytes += line.size
- yield line.sub(/\A\./, '')
+ yield line.delete_prefix('.')
end
LOG_on()
LOG "read message (#{read_bytes} bytes)"
@@ -335,7 +401,7 @@ module Net # :nodoc:
end
def using_each_crlf_line
- @wbuf = ''.dup
+ @wbuf = ''.b
yield
if not @wbuf.empty? # unterminated last line
write0 dot_stuff(@wbuf.chomp) + "\r\n"
diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb
index 1777a7fa7e..a97c0c3395 100644
--- a/lib/net/smtp.rb
+++ b/lib/net/smtp.rb
@@ -38,7 +38,7 @@ module Net
include SMTPError
end
- # Represents SMTP error code 420 or 450, a temporary error.
+ # Represents SMTP error code 4xx, a temporary error.
class SMTPServerBusy < ProtoServerError
include SMTPError
end
@@ -146,8 +146,8 @@ module Net
# The SMTP server will judge whether it should send or reject
# the SMTP session by inspecting the HELO domain.
#
- # Net::SMTP.start('your.smtp.server', 25,
- # 'mail.from.domain') { |smtp| ... }
+ # Net::SMTP.start('your.smtp.server', 25
+ # helo: 'mail.from.domain') { |smtp| ... }
#
# === SMTP Authentication
#
@@ -157,17 +157,18 @@ module Net
# SMTP.start/SMTP#start.
#
# # PLAIN
- # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
- # 'Your Account', 'Your Password', :plain)
+ # Net::SMTP.start('your.smtp.server', 25
+ # user: 'Your Account', secret: 'Your Password', authtype: :plain)
# # LOGIN
- # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
- # 'Your Account', 'Your Password', :login)
+ # Net::SMTP.start('your.smtp.server', 25
+ # user: 'Your Account', secret: 'Your Password', authtype: :login)
#
# # CRAM MD5
- # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
- # 'Your Account', 'Your Password', :cram_md5)
+ # Net::SMTP.start('your.smtp.server', 25
+ # user: 'Your Account', secret: 'Your Password', authtype: :cram_md5)
#
class SMTP < Protocol
+ VERSION = "0.2.1"
Revision = %q$Revision$.split[1]
@@ -190,8 +191,13 @@ module Net
alias default_ssl_port default_tls_port
end
- def SMTP.default_ssl_context
- OpenSSL::SSL::SSLContext.new
+ def SMTP.default_ssl_context(verify_peer=true)
+ context = OpenSSL::SSL::SSLContext.new
+ context.verify_mode = verify_peer ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
+ store = OpenSSL::X509::Store.new
+ store.set_default_paths
+ context.cert_store = store
+ context
end
#
@@ -217,8 +223,9 @@ module Net
@error_occurred = false
@debug_output = nil
@tls = false
- @starttls = false
- @ssl_context = nil
+ @starttls = :auto
+ @ssl_context_tls = nil
+ @ssl_context_starttls = nil
end
# Provide human-readable stringification of class state.
@@ -293,11 +300,11 @@ module Net
# Enables SMTP/TLS (SMTPS: SMTP over direct TLS connection) for
# this object. Must be called before the connection is established
# to have any effect. +context+ is a OpenSSL::SSL::SSLContext object.
- def enable_tls(context = SMTP.default_ssl_context)
+ def enable_tls(context = nil)
raise 'openssl library not installed' unless defined?(OpenSSL)
- raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls
+ raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls == :always
@tls = true
- @ssl_context = context
+ @ssl_context_tls = context
end
alias enable_ssl enable_tls
@@ -306,7 +313,7 @@ module Net
# connection is established to have any effect.
def disable_tls
@tls = false
- @ssl_context = nil
+ @ssl_context_tls = nil
end
alias disable_ssl disable_tls
@@ -330,27 +337,27 @@ module Net
# Enables SMTP/TLS (STARTTLS) for this object.
# +context+ is a OpenSSL::SSL::SSLContext object.
- def enable_starttls(context = SMTP.default_ssl_context)
+ def enable_starttls(context = nil)
raise 'openssl library not installed' unless defined?(OpenSSL)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
@starttls = :always
- @ssl_context = context
+ @ssl_context_starttls = context
end
# Enables SMTP/TLS (STARTTLS) for this object if server accepts.
# +context+ is a OpenSSL::SSL::SSLContext object.
- def enable_starttls_auto(context = SMTP.default_ssl_context)
+ def enable_starttls_auto(context = nil)
raise 'openssl library not installed' unless defined?(OpenSSL)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
@starttls = :auto
- @ssl_context = context
+ @ssl_context_starttls = context
end
# Disables SMTP/TLS (STARTTLS) for this object. Must be called
# before the connection is established to have any effect.
def disable_starttls
@starttls = false
- @ssl_context = nil
+ @ssl_context_starttls = nil
end
# The address of the SMTP server to connect to.
@@ -401,11 +408,15 @@ module Net
#
#
+ # :call-seq:
+ # start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
+ # start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
+ #
# Creates a new Net::SMTP object and connects to the server.
#
# This method is equivalent to:
#
- # Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)
+ # Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname)
#
# === Example
#
@@ -435,6 +446,9 @@ module Net
# or other authentication token; and +authtype+ is the authentication
# type, one of :plain, :login, or :cram_md5. See the discussion of
# SMTP Authentication in the overview notes.
+ # If +tls_verify+ is true, verify the server's certificate. The default is true.
+ # If the hostname in the server certificate is different from +address+,
+ # it can be specified with +tls_hostname+.
#
# === Errors
#
@@ -449,10 +463,16 @@ module Net
# * Net::ReadTimeout
# * IOError
#
- def SMTP.start(address, port = nil, helo = 'localhost',
- user = nil, secret = nil, authtype = nil,
- &block) # :yield: smtp
- new(address, port).start(helo, user, secret, authtype, &block)
+ def SMTP.start(address, port = nil, *args, helo: nil,
+ user: nil, secret: nil, password: nil, authtype: nil,
+ tls_verify: true, tls_hostname: nil,
+ &block)
+ raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 1..6)" if args.size > 4
+ helo ||= args[0] || 'localhost'
+ user ||= args[1]
+ secret ||= password || args[2]
+ authtype ||= args[3]
+ new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype, tls_verify: tls_verify, tls_hostname: tls_hostname, &block)
end
# +true+ if the SMTP session has been started.
@@ -461,6 +481,10 @@ module Net
end
#
+ # :call-seq:
+ # start(helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
+ # start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
+ #
# Opens a TCP connection and starts the SMTP session.
#
# === Parameters
@@ -473,6 +497,9 @@ module Net
# the type of authentication to attempt; it must be one of
# :login, :plain, and :cram_md5. See the notes on SMTP Authentication
# in the overview.
+ # If +tls_verify+ is true, verify the server's certificate. The default is true.
+ # If the hostname in the server certificate is different from +address+,
+ # it can be specified with +tls_hostname+.
#
# === Block Usage
#
@@ -487,7 +514,7 @@ module Net
#
# require 'net/smtp'
# smtp = Net::SMTP.new('smtp.mail.server', 25)
- # smtp.start(helo_domain, account, password, authtype) do |smtp|
+ # smtp.start(helo: helo_domain, user: account, secret: password, authtype: authtype) do |smtp|
# smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
# end
#
@@ -511,8 +538,20 @@ module Net
# * Net::ReadTimeout
# * IOError
#
- def start(helo = 'localhost',
- user = nil, secret = nil, authtype = nil) # :yield: smtp
+ def start(*args, helo: nil,
+ user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true, tls_hostname: nil)
+ raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
+ helo ||= args[0] || 'localhost'
+ user ||= args[1]
+ secret ||= password || args[2]
+ authtype ||= args[3]
+ if @tls && @ssl_context_tls.nil?
+ @ssl_context_tls = SMTP.default_ssl_context(tls_verify)
+ end
+ if @starttls && @ssl_context_starttls.nil?
+ @ssl_context_starttls = SMTP.default_ssl_context(tls_verify)
+ end
+ @tls_hostname = tls_hostname
if block_given?
begin
do_start helo, user, secret, authtype
@@ -549,16 +588,16 @@ module Net
tcp_socket(@address, @port)
end
logging "Connection opened: #{@address}:#{@port}"
- @socket = new_internet_message_io(tls? ? tlsconnect(s) : s)
+ @socket = new_internet_message_io(tls? ? tlsconnect(s, @ssl_context_tls) : s)
check_response critical { recv_response() }
do_helo helo_domain
- if starttls_always? or (capable_starttls? and starttls_auto?)
+ if ! tls? and (starttls_always? or (capable_starttls? and starttls_auto?))
unless capable_starttls?
raise SMTPUnsupportedCommand,
"STARTTLS is not supported on this server"
end
starttls
- @socket = new_internet_message_io(tlsconnect(s))
+ @socket = new_internet_message_io(tlsconnect(s, @ssl_context_starttls))
# helo response may be different after STARTTLS
do_helo helo_domain
end
@@ -576,14 +615,15 @@ module Net
OpenSSL::SSL::SSLSocket.new socket, context
end
- def tlsconnect(s)
+ def tlsconnect(s, context)
verified = false
- s = ssl_socket(s, @ssl_context)
+ s = ssl_socket(s, context)
logging "TLS connection started"
s.sync_close = true
+ s.hostname = @tls_hostname || @address if s.respond_to? :hostname=
ssl_socket_connect(s, @open_timeout)
- if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
- s.post_connection_check(@address)
+ if context.verify_mode && context.verify_mode != OpenSSL::SSL::VERIFY_NONE
+ s.post_connection_check(@tls_hostname || @address)
end
verified = true
s
@@ -725,7 +765,7 @@ module Net
def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
check_auth_method authtype
check_auth_args user, secret
- send auth_method(authtype), user, secret
+ public_send auth_method(authtype), user, secret
end
def auth_plain(user, secret)
@@ -831,9 +871,6 @@ module Net
end
def mailfrom(from_addr)
- if $SAFE > 0
- raise SecurityError, 'tainted from_addr' if from_addr.tainted?
- end
getok("MAIL FROM:<#{from_addr}>")
end
@@ -859,9 +896,6 @@ module Net
end
def rcptto(to_addr)
- if $SAFE > 0
- raise SecurityError, 'tainted to_addr' if to_addr.tainted?
- end
getok("RCPT TO:<#{to_addr}>")
end
@@ -1048,7 +1082,7 @@ module Net
return {} unless @string[3, 1] == '-'
h = {}
@string.lines.drop(1).each do |line|
- k, *v = line[4..-1].chomp.split
+ k, *v = line[4..-1].split(' ')
h[k] = v
end
h
diff --git a/lib/observer.rb b/lib/observer.rb
index acfe654301..ef70e39dd8 100644
--- a/lib/observer.rb
+++ b/lib/observer.rb
@@ -111,7 +111,32 @@
# Current price: 112
# Current price: 79
# --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79
+#
+# === Usage with procs
+#
+# The +#notify_observers+ method can also be used with +proc+s by using
+# the +:call+ as +func+ parameter.
+#
+# The following example illustrates the use of a lambda:
+#
+# require 'observer'
+#
+# class Ticker
+# include Observable
+#
+# def run
+# # logic to retrieve the price (here 77.0)
+# changed
+# notify_observers(77.0)
+# end
+# end
+#
+# ticker = Ticker.new
+# warner = ->(price) { puts "New price received: #{price}" }
+# ticker.add_observer(warner, :call)
+# ticker.run
module Observable
+ VERSION = "0.1.1"
#
# Add +observer+ as an observer on this object. So that it will receive
@@ -194,7 +219,7 @@ module Observable
if defined? @observer_state and @observer_state
if defined? @observer_peers
@observer_peers.each do |k, v|
- k.send v, *arg
+ k.__send__(v, *arg)
end
end
@observer_state = false
diff --git a/lib/observer/observer.gemspec b/lib/observer/observer.gemspec
new file mode 100644
index 0000000000..46538e881a
--- /dev/null
+++ b/lib/observer/observer.gemspec
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Implementation of the Observer object-oriented design pattern.}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/observer"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/open-uri.gemspec b/lib/open-uri.gemspec
new file mode 100644
index 0000000000..853049f7ec
--- /dev/null
+++ b/lib/open-uri.gemspec
@@ -0,0 +1,26 @@
+Gem::Specification.new do |spec|
+ spec.name = "open-uri"
+ spec.version = "0.1.0"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{An easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP.}
+ spec.description = %q{An easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP.}
+ spec.homepage = "https://github.com/ruby/open-uri"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "uri"
+ spec.add_dependency "stringio"
+ spec.add_dependency "time"
+end
diff --git a/lib/open-uri.rb b/lib/open-uri.rb
index b09c18efd9..421a82ed0d 100644
--- a/lib/open-uri.rb
+++ b/lib/open-uri.rb
@@ -3,30 +3,24 @@ require 'uri'
require 'stringio'
require 'time'
-module Kernel
- private
- alias open_uri_original_open open # :nodoc:
- class << self
- alias open_uri_original_open open # :nodoc:
- end
-
+module URI
# Allows the opening of various resources including URIs.
#
# If the first argument responds to the 'open' method, 'open' is called on
# it with the rest of the arguments.
#
- # If the first argument is a string that begins with xxx://, it is parsed by
+ # If the first argument is a string that begins with <code>(protocol)://<code>, it is parsed by
# URI.parse. If the parsed object responds to the 'open' method,
# 'open' is called on it with the rest of the arguments.
#
- # Otherwise, the original Kernel#open is called.
+ # Otherwise, Kernel#open is called.
#
# OpenURI::OpenRead#open provides URI::HTTP#open, URI::HTTPS#open and
# URI::FTP#open, Kernel#open.
#
# We can accept URIs and strings that begin with http://, https:// and
# ftp://. In these cases, the opened file object is extended by OpenURI::Meta.
- def open(name, *rest, &block) # :doc:
+ def self.open(name, *rest, &block)
if name.respond_to?(:open)
name.open(*rest, &block)
elsif name.respond_to?(:to_str) &&
@@ -34,10 +28,9 @@ module Kernel
(uri = URI.parse(name)).respond_to?(:open)
uri.open(*rest, &block)
else
- open_uri_original_open(name, *rest, &block)
+ super
end
end
- module_function :open
end
# OpenURI is an easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP.
@@ -46,14 +39,14 @@ end
#
# It is possible to open an http, https or ftp URL as though it were a file:
#
-# open("http://www.ruby-lang.org/") {|f|
+# URI.open("http://www.ruby-lang.org/") {|f|
# f.each_line {|line| p line}
# }
#
# The opened file has several getter methods for its meta-information, as
# follows, since it is extended by OpenURI::Meta.
#
-# open("http://www.ruby-lang.org/en") {|f|
+# URI.open("http://www.ruby-lang.org/en") {|f|
# f.each_line {|line| p line}
# p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
# p f.content_type # "text/html"
@@ -64,7 +57,7 @@ end
#
# Additional header fields can be specified by an optional hash argument.
#
-# open("http://www.ruby-lang.org/en/",
+# URI.open("http://www.ruby-lang.org/en/",
# "User-Agent" => "Ruby/#{RUBY_VERSION}",
# "From" => "foo@bar.invalid",
# "Referer" => "http://www.ruby-lang.org/") {|f|
@@ -74,11 +67,11 @@ end
# The environment variables such as http_proxy, https_proxy and ftp_proxy
# are in effect by default. Here we disable proxy:
#
-# open("http://www.ruby-lang.org/en/", :proxy => nil) {|f|
+# URI.open("http://www.ruby-lang.org/en/", :proxy => nil) {|f|
# # ...
# }
#
-# See OpenURI::OpenRead.open and Kernel#open for more on available options.
+# See OpenURI::OpenRead.open and URI.open for more on available options.
#
# URI objects can be opened in a similar way.
#
@@ -108,6 +101,7 @@ module OpenURI
:ssl_verify_mode => nil,
:ftp_active_mode => false,
:redirect => true,
+ :encoding => nil,
}
def OpenURI.check_options(options) # :nodoc:
@@ -141,6 +135,12 @@ module OpenURI
encoding, = $1,Encoding.find($1) if $1
mode = nil
end
+ if options.has_key? :encoding
+ if !encoding.nil?
+ raise ArgumentError, "encoding specified twice"
+ end
+ encoding = Encoding.find(options[:encoding])
+ end
unless mode == nil ||
mode == 'r' || mode == 'rb' ||
@@ -340,6 +340,7 @@ module OpenURI
if options[:progress_proc] && Net::HTTPSuccess === resp
options[:progress_proc].call(buf.size)
end
+ str.clear
}
}
}
@@ -528,17 +529,16 @@ module OpenURI
# It can be used to guess charset.
#
# If charset parameter and block is not given,
- # nil is returned except text type in HTTP.
- # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.
+ # nil is returned except text type.
+ # In that case, "utf-8" is returned as defined by RFC6838 4.2.1
def charset
type, *parameters = content_type_parse
if pair = parameters.assoc('charset')
pair.last.downcase
elsif block_given?
yield
- elsif type && %r{\Atext/} =~ type &&
- @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
- "iso-8859-1" # RFC2616 3.7.1
+ elsif type && %r{\Atext/} =~ type
+ "utf-8" # RFC6838 4.2.1
else
nil
end
@@ -721,7 +721,7 @@ module OpenURI
OpenURI.open_uri(self, *rest, &block)
end
- # OpenURI::OpenRead#read([options]) reads a content referenced by self and
+ # OpenURI::OpenRead#read([ options ]) reads a content referenced by self and
# returns the content as string.
# The string is extended with OpenURI::Meta.
# The argument +options+ is same as OpenURI::OpenRead#open.
diff --git a/lib/open3.gemspec b/lib/open3.gemspec
new file mode 100644
index 0000000000..ad9485adc7
--- /dev/null
+++ b/lib/open3.gemspec
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-"), "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Popen, but with stderr, too}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/open3"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = ">= 2.6.0"
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/open3.rb b/lib/open3.rb
index 5ff1012b70..c574696bb1 100644
--- a/lib/open3.rb
+++ b/lib/open3.rb
@@ -30,6 +30,7 @@
#
module Open3
+ VERSION = "0.1.1"
# Open stdin, stdout, and stderr streams and start external executable.
# In addition, a thread to wait for the started process is created.
@@ -81,7 +82,13 @@ module Open3
# If merged stdout and stderr output is not a problem, you can use Open3.popen2e.
# If you really need stdout and stderr output as separate strings, you can consider Open3.capture3.
#
- def popen3(*cmd, **opts, &block)
+ def popen3(*cmd, &block)
+ if Hash === cmd.last
+ opts = cmd.pop.dup
+ else
+ opts = {}
+ end
+
in_r, in_w = IO.pipe
opts[:in] = in_r
in_w.sync = true
@@ -136,7 +143,13 @@ module Open3
# p o.read #=> "*"
# }
#
- def popen2(*cmd, **opts, &block)
+ def popen2(*cmd, &block)
+ if Hash === cmd.last
+ opts = cmd.pop.dup
+ else
+ opts = {}
+ end
+
in_r, in_w = IO.pipe
opts[:in] = in_r
in_w.sync = true
@@ -179,7 +192,13 @@ module Open3
# }
# }
#
- def popen2e(*cmd, **opts, &block)
+ def popen2e(*cmd, &block)
+ if Hash === cmd.last
+ opts = cmd.pop.dup
+ else
+ opts = {}
+ end
+
in_r, in_w = IO.pipe
opts[:in] = in_r
in_w.sync = true
@@ -188,14 +207,17 @@ module Open3
opts[[:out, :err]] = out_w
popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block)
+ ensure
+ if block
+ in_r.close
+ in_w.close
+ out_r.close
+ out_w.close
+ end
end
module_function :popen2e
def popen_run(cmd, opts, child_io, parent_io) # :nodoc:
- if last = Hash.try_convert(cmd.last)
- opts = opts.merge(last)
- cmd.pop
- end
pid = spawn(*cmd, opts)
wait_thr = Process.detach(pid)
child_io.each(&:close)
@@ -254,7 +276,16 @@ module Open3
# STDOUT.binmode; print thumbnail
# end
#
- def capture3(*cmd, stdin_data: '', binmode: false, **opts)
+ def capture3(*cmd)
+ if Hash === cmd.last
+ opts = cmd.pop.dup
+ else
+ opts = {}
+ end
+
+ stdin_data = opts.delete(:stdin_data) || ''
+ binmode = opts.delete(:binmode)
+
popen3(*cmd, opts) {|i, o, e, t|
if binmode
i.binmode
@@ -264,7 +295,11 @@ module Open3
out_reader = Thread.new { o.read }
err_reader = Thread.new { e.read }
begin
- i.write stdin_data
+ if stdin_data.respond_to? :readpartial
+ IO.copy_stream(stdin_data, i)
+ else
+ i.write stdin_data
+ end
rescue Errno::EPIPE
end
i.close
@@ -302,7 +337,16 @@ module Open3
# End
# image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true)
#
- def capture2(*cmd, stdin_data: nil, binmode: false, **opts)
+ def capture2(*cmd)
+ if Hash === cmd.last
+ opts = cmd.pop.dup
+ else
+ opts = {}
+ end
+
+ stdin_data = opts.delete(:stdin_data)
+ binmode = opts.delete(:binmode)
+
popen2(*cmd, opts) {|i, o, t|
if binmode
i.binmode
@@ -311,7 +355,11 @@ module Open3
out_reader = Thread.new { o.read }
if stdin_data
begin
- i.write stdin_data
+ if stdin_data.respond_to? :readpartial
+ IO.copy_stream(stdin_data, i)
+ else
+ i.write stdin_data
+ end
rescue Errno::EPIPE
end
end
@@ -337,7 +385,16 @@ module Open3
# # capture make log
# make_log, s = Open3.capture2e("make")
#
- def capture2e(*cmd, stdin_data: nil, binmode: false, **opts)
+ def capture2e(*cmd)
+ if Hash === cmd.last
+ opts = cmd.pop.dup
+ else
+ opts = {}
+ end
+
+ stdin_data = opts.delete(:stdin_data)
+ binmode = opts.delete(:binmode)
+
popen2e(*cmd, opts) {|i, oe, t|
if binmode
i.binmode
@@ -346,7 +403,11 @@ module Open3
outerr_reader = Thread.new { oe.read }
if stdin_data
begin
- i.write stdin_data
+ if stdin_data.respond_to? :readpartial
+ IO.copy_stream(stdin_data, i)
+ else
+ i.write stdin_data
+ end
rescue Errno::EPIPE
end
end
@@ -398,7 +459,13 @@ module Open3
# stdin.close # send EOF to sort.
# p stdout.read #=> " 1\tbar\n 2\tbaz\n 3\tfoo\n"
# }
- def pipeline_rw(*cmds, **opts, &block)
+ def pipeline_rw(*cmds, &block)
+ if Hash === cmds.last
+ opts = cmds.pop.dup
+ else
+ opts = {}
+ end
+
in_r, in_w = IO.pipe
opts[:in] = in_r
in_w.sync = true
@@ -448,7 +515,13 @@ module Open3
# p ts[1].value #=> #<Process::Status: pid 24913 exit 0>
# }
#
- def pipeline_r(*cmds, **opts, &block)
+ def pipeline_r(*cmds, &block)
+ if Hash === cmds.last
+ opts = cmds.pop.dup
+ else
+ opts = {}
+ end
+
out_r, out_w = IO.pipe
opts[:out] = out_w
@@ -484,7 +557,13 @@ module Open3
# i.puts "hello"
# }
#
- def pipeline_w(*cmds, **opts, &block)
+ def pipeline_w(*cmds, &block)
+ if Hash === cmds.last
+ opts = cmds.pop.dup
+ else
+ opts = {}
+ end
+
in_r, in_w = IO.pipe
opts[:in] = in_r
in_w.sync = true
@@ -537,7 +616,13 @@ module Open3
# p err_r.read # error messages of pdftops and lpr.
# }
#
- def pipeline_start(*cmds, **opts, &block)
+ def pipeline_start(*cmds, &block)
+ if Hash === cmds.last
+ opts = cmds.pop.dup
+ else
+ opts = {}
+ end
+
if block
pipeline_run(cmds, opts, [], [], &block)
else
@@ -599,7 +684,13 @@ module Open3
# # 106
# # 202
#
- def pipeline(*cmds, **opts)
+ def pipeline(*cmds)
+ if Hash === cmds.last
+ opts = cmds.pop.dup
+ else
+ opts = {}
+ end
+
pipeline_run(cmds, opts, [], []) {|ts|
ts.map(&:value)
}
@@ -645,8 +736,8 @@ module Open3
end
pid = spawn(*cmd, cmd_opts)
wait_thrs << Process.detach(pid)
- r.close if r
- w2.close if w2
+ r&.close
+ w2&.close
r = r2
}
result = parent_io + [wait_thrs]
diff --git a/lib/optparse.rb b/lib/optparse.rb
index 05415901a3..598ebd12bd 100644
--- a/lib/optparse.rb
+++ b/lib/optparse.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#
# optparse.rb - command-line option analysis with the OptionParser class.
#
@@ -72,10 +72,10 @@
# require 'optparse'
#
# options = {}
-# OptionParser.new do |opts|
-# opts.banner = "Usage: example.rb [options]"
+# OptionParser.new do |parser|
+# parser.banner = "Usage: example.rb [options]"
#
-# opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
+# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
# options[:verbose] = v
# end
# end.parse!
@@ -96,15 +96,15 @@
# def self.parse(options)
# args = Options.new("world")
#
-# opt_parser = OptionParser.new do |opts|
-# opts.banner = "Usage: example.rb [options]"
+# opt_parser = OptionParser.new do |parser|
+# parser.banner = "Usage: example.rb [options]"
#
-# opts.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
+# parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
# args.name = n
# end
#
-# opts.on("-h", "--help", "Prints this help") do
-# puts opts
+# parser.on("-h", "--help", "Prints this help") do
+# puts parser
# exit
# end
# end
@@ -125,6 +125,7 @@
# For options that require an argument, option specification strings may include an
# option name in all caps. If an option is used without the required argument,
# an exception will be raised.
+#
# require 'optparse'
#
# options = {}
@@ -137,9 +138,9 @@
#
# Used:
#
-# bash-3.2$ ruby optparse-test.rb -r
+# $ ruby optparse-test.rb -r
# optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument)
-# bash-3.2$ ruby optparse-test.rb -r my-library
+# $ ruby optparse-test.rb -r my-library
# You required my-library!
#
# === Type Coercion
@@ -168,7 +169,7 @@
# - Array -- Strings separated by ',' (e.g. 1,2,3)
# - Regexp -- Regular expressions. Also includes options.
#
-# We can also add our own coercions, which we will cover soon.
+# We can also add our own coercions, which we will cover below.
#
# ==== Using Built-in Conversions
#
@@ -187,13 +188,12 @@
# end.parse!
#
# Used:
-# bash-3.2$ ruby optparse-test.rb -t nonsense
+#
+# $ ruby optparse-test.rb -t nonsense
# ... invalid argument: -t nonsense (OptionParser::InvalidArgument)
-# from ... time.rb:5:in `block in <top (required)>'
-# from optparse-test.rb:31:in `<main>'
-# bash-3.2$ ruby optparse-test.rb -t 10-11-12
+# $ ruby optparse-test.rb -t 10-11-12
# 2010-11-12 00:00:00 -0500
-# bash-3.2$ ruby optparse-test.rb -t 9:30
+# $ ruby optparse-test.rb -t 9:30
# 2014-08-13 09:30:00 -0400
#
# ==== Creating Custom Conversions
@@ -225,13 +225,39 @@
#
# op.parse!
#
-# output:
-# bash-3.2$ ruby optparse-test.rb --user 1
+# Used:
+#
+# $ ruby optparse-test.rb --user 1
# #<struct User id=1, name="Sam">
-# bash-3.2$ ruby optparse-test.rb --user 2
+# $ ruby optparse-test.rb --user 2
# #<struct User id=2, name="Gandalf">
-# bash-3.2$ ruby optparse-test.rb --user 3
+# $ ruby optparse-test.rb --user 3
# optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
+#
+# === Store options to a Hash
+#
+# The +into+ option of +order+, +parse+ and so on methods stores command line options into a Hash.
+#
+# require 'optparse'
+#
+# params = {}
+# OptionParser.new do |parser|
+# parser.on('-a')
+# parser.on('-b NUM', Integer)
+# parser.on('-v', '--verbose')
+# end.parse!(into: params)
+#
+# p params
+#
+# Used:
+#
+# $ ruby optparse-test.rb -a
+# {:a=>true}
+# $ ruby optparse-test.rb -a -v
+# {:a=>true, :verbose=>true}
+# $ ruby optparse-test.rb -a -b 100
+# {:a=>true, :b=>100}
+#
# === Complete example
#
# The following example is a complete Ruby program. You can run it and see the
@@ -393,6 +419,8 @@
# have any questions, file a ticket at http://bugs.ruby-lang.org.
#
class OptionParser
+ OptionParser::Version = "0.1.1"
+
# :stopdoc:
NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
@@ -413,7 +441,7 @@ class OptionParser
candidates = []
block.call do |k, *v|
(if Regexp === k
- kn = "".freeze
+ kn = ""
k === key
else
kn = defined?(k.id2name) ? k.id2name : k
@@ -508,8 +536,9 @@ class OptionParser
def initialize(pattern = nil, conv = nil,
short = nil, long = nil, arg = nil,
- desc = ([] if short or long), block = Proc.new)
+ desc = ([] if short or long), block = nil, &_block)
raise if Array === pattern
+ block ||= _block
@pattern, @conv, @short, @long, @arg, @desc, @block =
pattern, conv, short, long, arg, desc, block
end
@@ -565,7 +594,7 @@ class OptionParser
# +max+ columns.
# +indent+:: Prefix string indents all summarized lines.
#
- def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = "")
+ def summarize(sdone = {}, ldone = {}, width = 1, max = width - 1, indent = "")
sopts, lopts = [], [], nil
@short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
@long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
@@ -577,7 +606,7 @@ class OptionParser
while s = lopts.shift
l = left[-1].length + s.length
l += arg.length if left.size == 1 && arg
- l < max or sopts.empty? or left << ''
+ l < max or sopts.empty? or left << +''
left[-1] << (left[-1].empty? ? ' ' * 4 : ', ') << s
end
@@ -628,7 +657,7 @@ class OptionParser
return if sopts.empty? and lopts.empty? # completely hidden
(sopts+lopts).each do |opt|
- # "(-x -c -r)-l[left justify]" \
+ # "(-x -c -r)-l[left justify]"
if /^--\[no-\](.+)$/ =~ opt
o = $1
yield("--#{o}", desc.join(""))
@@ -839,6 +868,10 @@ class OptionParser
__send__(id).complete(opt, icase, *pat, &block)
end
+ def get_candidates(id)
+ yield __send__(id).keys
+ end
+
#
# Iterates over each option, passing the option to the +block+.
#
@@ -1058,6 +1091,7 @@ XXX
@summary_width = width
@summary_indent = indent
@default_argv = ARGV
+ @require_exact = false
add_officious
yield self if block_given?
end
@@ -1131,12 +1165,16 @@ XXX
# Strings to be parsed in default.
attr_accessor :default_argv
+ # Whether to require that options match exactly (disallows providing
+ # abbreviated long option as short option).
+ attr_accessor :require_exact
+
#
# Heading banner preceding summary.
#
def banner
unless @banner
- @banner = "Usage: #{program_name} [options]"
+ @banner = +"Usage: #{program_name} [options]"
visit(:add_banner, @banner)
end
@banner
@@ -1165,14 +1203,14 @@ XXX
# Version
#
def version
- @version || (defined?(::Version) && ::Version)
+ (defined?(@version) && @version) || (defined?(::Version) && ::Version)
end
#
# Release code
#
def release
- @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
+ (defined?(@release) && @release) || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
end
#
@@ -1180,7 +1218,7 @@ XXX
#
def ver
if v = version
- str = "#{program_name} #{[v].join('.')}"
+ str = +"#{program_name} #{[v].join('.')}"
str << " (#{v})" if v = release
str
end
@@ -1237,7 +1275,8 @@ XXX
# +indent+:: Indentation, defaults to @summary_indent.
#
def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
- blk ||= proc {|l| to << (l.index($/, -1) ? l : l + $/)}
+ nl = "\n"
+ blk ||= proc {|l| to << (l.index(nl, -1) ? l : l + nl)}
visit(:summarize, {}, {}, width, max, indent, &blk)
to
end
@@ -1271,13 +1310,16 @@ XXX
private :notwice
SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc:
+
+ # :call-seq:
+ # make_switch(params, block = nil)
#
# Creates an OptionParser::Switch from the parameters. The parsed argument
# value is passed to the given block, where it can be processed.
#
# See at the beginning of OptionParser for some full examples.
#
- # +opts+ can include the following elements:
+ # +params+ can include the following elements:
#
# [Argument style:]
# One of the following:
@@ -1324,6 +1366,8 @@ XXX
# [Description:]
# Description string for the option.
# "Run verbosely"
+ # If you give multiple description strings, each string will be printed
+ # line by line.
#
# [Handler:]
# Handler for the parsed argument value. Either give a block or pass a
@@ -1462,11 +1506,16 @@ XXX
nolong
end
+ # :call-seq:
+ # define(*params, &block)
+ #
def define(*opts, &block)
top.append(*(sw = make_switch(opts, block)))
sw[0]
end
+ # :call-seq:
+ # on(*params, &block)
#
# Add option switch and handler. See #make_switch for an explanation of
# parameters.
@@ -1477,11 +1526,16 @@ XXX
end
alias def_option define
+ # :call-seq:
+ # define_head(*params, &block)
+ #
def define_head(*opts, &block)
top.prepend(*(sw = make_switch(opts, block)))
sw[0]
end
+ # :call-seq:
+ # on_head(*params, &block)
#
# Add option switch like with #on, but at head of summary.
#
@@ -1491,12 +1545,18 @@ XXX
end
alias def_head_option define_head
+ # :call-seq:
+ # define_tail(*params, &block)
+ #
def define_tail(*opts, &block)
base.append(*(sw = make_switch(opts, block)))
sw[0]
end
#
+ # :call-seq:
+ # on_tail(*params, &block)
+ #
# Add option switch like with #on, but at tail of summary.
#
def on_tail(*opts, &block)
@@ -1514,7 +1574,10 @@ XXX
#
# Parses command line arguments +argv+ in order. When a block is given,
- # each non-option argument is yielded.
+ # each non-option argument is yielded. When optional +into+ keyword
+ # argument is provided, the parsed option values are stored there via
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
+ # similar object).
#
# Returns the rest of +argv+ left unparsed.
#
@@ -1544,6 +1607,9 @@ XXX
opt.tr!('_', '-')
begin
sw, = complete(:long, opt, true)
+ if require_exact && !sw.long.include?(arg)
+ raise InvalidOption, arg
+ end
rescue ParseError
raise $!.set_option(arg, true)
end
@@ -1565,9 +1631,10 @@ XXX
begin
sw, = complete(:short, opt)
# short option matched.
- val = arg.sub(/\A-/, '')
+ val = arg.delete_prefix('-')
has_arg = true
rescue InvalidOption
+ raise if require_exact
# if no short options match, try completion with long
# options.
sw, = complete(:long, opt)
@@ -1579,7 +1646,12 @@ XXX
end
begin
opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
+ rescue ParseError
+ raise $!.set_option(arg, arg.length > 2)
+ else
raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}"
+ end
+ begin
argv.unshift(opt) if opt and (!rest or (opt = opt.sub(/\A-*/, '-')) != '-')
val = cb.call(val) if cb
setter.call(sw.switch_name, val) if setter
@@ -1610,7 +1682,10 @@ XXX
#
# Parses command line arguments +argv+ in permutation mode and returns
- # list of non-option arguments.
+ # list of non-option arguments. When optional +into+ keyword
+ # argument is provided, the parsed option values are stored there via
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
+ # similar object).
#
def permute(*argv, into: nil)
argv = argv[0].dup if argv.size == 1 and Array === argv[0]
@@ -1631,6 +1706,9 @@ XXX
#
# Parses command line arguments +argv+ in order when environment variable
# POSIXLY_CORRECT is set, and in permutation mode otherwise.
+ # When optional +into+ keyword argument is provided, the parsed option
+ # values are stored there via <code>[]=</code> method (so it can be Hash,
+ # or OpenStruct, or other similar object).
#
def parse(*argv, into: nil)
argv = argv[0].dup if argv.size == 1 and Array === argv[0]
@@ -1704,7 +1782,7 @@ XXX
#
def visit(id, *args, &block)
@stack.reverse_each do |el|
- el.send(id, *args, &block)
+ el.__send__(id, *args, &block)
end
nil
end
@@ -1734,13 +1812,28 @@ XXX
if pat.empty?
search(typ, opt) {|sw| return [sw, opt]} # exact match or...
end
- raise AmbiguousOption, catch(:ambiguous) {
+ ambiguous = catch(:ambiguous) {
visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
- raise InvalidOption, opt
}
+ exc = ambiguous ? AmbiguousOption : InvalidOption
+ raise exc.new(opt, additional: self.method(:additional_message).curry[typ])
end
private :complete
+ #
+ # Returns additional info.
+ #
+ def additional_message(typ, opt)
+ return unless typ and opt and defined?(DidYouMean::SpellChecker)
+ all_candidates = []
+ visit(:get_candidates, typ) do |candidates|
+ all_candidates.concat(candidates)
+ end
+ all_candidates.select! {|cand| cand.is_a?(String) }
+ checker = DidYouMean::SpellChecker.new(dictionary: all_candidates)
+ DidYouMean.formatter.message_for(all_candidates & checker.correct(opt))
+ end
+
def candidate(word)
list = []
case word
@@ -1776,13 +1869,26 @@ XXX
# is not present. Returns whether successfully loaded.
#
# +filename+ defaults to basename of the program without suffix in a
- # directory ~/.options.
+ # directory ~/.options, then the basename with '.options' suffix
+ # under XDG and Haiku standard places.
#
def load(filename = nil)
- begin
- filename ||= File.expand_path(File.basename($0, '.*'), '~/.options')
- rescue
- return false
+ unless filename
+ basename = File.basename($0, '.*')
+ return true if load(File.expand_path(basename, '~/.options')) rescue nil
+ basename << ".options"
+ return [
+ # XDG
+ ENV['XDG_CONFIG_HOME'],
+ '~/.config',
+ *ENV['XDG_CONFIG_DIRS']&.split(File::PATH_SEPARATOR),
+
+ # Haiku
+ '~/config/settings',
+ ].any? {|dir|
+ next if !dir or dir.empty?
+ load(File.expand_path(basename, dir)) rescue nil
+ }
end
begin
parse(*IO.readlines(filename).each {|s| s.chomp!})
@@ -1952,15 +2058,18 @@ XXX
#
class ParseError < RuntimeError
# Reason which caused the error.
- Reason = 'parse error'.freeze
+ Reason = 'parse error'
- def initialize(*args)
+ def initialize(*args, additional: nil)
+ @additional = additional
+ @arg0, = args
@args = args
@reason = nil
end
attr_reader :args
attr_writer :reason
+ attr_accessor :additional
#
# Pushes back erred argument(s) to +argv+.
@@ -2005,7 +2114,7 @@ XXX
# Default stringizing method to emit standard error message.
#
def message
- reason + ': ' + args.join(' ')
+ "#{reason}: #{args.join(' ')}#{additional[@arg0] if additional}"
end
alias to_s message
@@ -2015,42 +2124,42 @@ XXX
# Raises when ambiguously completable string is encountered.
#
class AmbiguousOption < ParseError
- const_set(:Reason, 'ambiguous option'.freeze)
+ const_set(:Reason, 'ambiguous option')
end
#
# Raises when there is an argument for a switch which takes no argument.
#
class NeedlessArgument < ParseError
- const_set(:Reason, 'needless argument'.freeze)
+ const_set(:Reason, 'needless argument')
end
#
# Raises when a switch with mandatory argument has no argument.
#
class MissingArgument < ParseError
- const_set(:Reason, 'missing argument'.freeze)
+ const_set(:Reason, 'missing argument')
end
#
# Raises when switch is undefined.
#
class InvalidOption < ParseError
- const_set(:Reason, 'invalid option'.freeze)
+ const_set(:Reason, 'invalid option')
end
#
# Raises when the given argument does not match required format.
#
class InvalidArgument < ParseError
- const_set(:Reason, 'invalid argument'.freeze)
+ const_set(:Reason, 'invalid argument')
end
#
# Raises when the given argument word can't be completed uniquely.
#
class AmbiguousArgument < InvalidArgument
- const_set(:Reason, 'ambiguous argument'.freeze)
+ const_set(:Reason, 'ambiguous argument')
end
#
diff --git a/lib/optparse/ac.rb b/lib/optparse/ac.rb
index fb0883f97a..9d520101aa 100644
--- a/lib/optparse/ac.rb
+++ b/lib/optparse/ac.rb
@@ -13,6 +13,8 @@ class OptionParser::AC < OptionParser
end
end
+ ARG_CONV = proc {|val| val.nil? ? true : val}
+
def _ac_arg_enable(prefix, name, help_string, block)
_check_ac_args(name, block)
@@ -20,8 +22,9 @@ class OptionParser::AC < OptionParser
ldesc = ["--#{prefix}-#{name}"]
desc = [help_string]
q = name.downcase
- enable = Switch::NoArgument.new(nil, proc {true}, sdesc, ldesc, nil, desc, block)
- disable = Switch::NoArgument.new(nil, proc {false}, sdesc, ldesc, nil, desc, block)
+ ac_block = proc {|val| block.call(ARG_CONV.call(val))}
+ enable = Switch::PlacedArgument.new(nil, ARG_CONV, sdesc, ldesc, nil, desc, ac_block)
+ disable = Switch::NoArgument.new(nil, proc {false}, sdesc, ldesc, nil, desc, ac_block)
top.append(enable, [], ["enable-" + q], disable, ['disable-' + q])
enable
end
diff --git a/lib/optparse/kwargs.rb b/lib/optparse/kwargs.rb
index ed58cc142b..5a2def4747 100644
--- a/lib/optparse/kwargs.rb
+++ b/lib/optparse/kwargs.rb
@@ -2,6 +2,9 @@
require 'optparse'
class OptionParser
+ # :call-seq:
+ # define_by_keywords(options, method, **params)
+ #
def define_by_keywords(options, meth, **opts)
meth.parameters.each do |type, name|
case type
diff --git a/lib/optparse/optparse.gemspec b/lib/optparse/optparse.gemspec
new file mode 100644
index 0000000000..831c787ac7
--- /dev/null
+++ b/lib/optparse/optparse.gemspec
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*OptionParser::Version\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Nobu Nakada"]
+ spec.email = ["nobu@ruby-lang.org"]
+
+ spec.summary = %q{OptionParser is a class for command-line option analysis.}
+ spec.description = %q{OptionParser is a class for command-line option analysis.}
+ spec.homepage = "https://github.com/ruby/optparse"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f|
+ f.match(%r{\A(?:(?:test|spec|features)/|Gemfile|\.(?:editor|git))})
+ }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/ostruct.rb b/lib/ostruct.rb
index 2edb2edeb4..a5a5140d10 100644
--- a/lib/ostruct.rb
+++ b/lib/ostruct.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#
# = ostruct.rb: OpenStruct implementation
#
@@ -36,9 +36,10 @@
# Hash keys with spaces or characters that could normally not be used for
# method calls (e.g. <code>()[]*</code>) will not be immediately available
# on the OpenStruct object as a method for retrieval or assignment, but can
-# still be reached through the Object#send method.
+# still be reached through the Object#send method or using [].
#
# measurements = OpenStruct.new("length (in inches)" => 24)
+# measurements[:"length (in inches)"] # => 24
# measurements.send("length (in inches)") # => 24
#
# message = OpenStruct.new(:queued? => true)
@@ -61,8 +62,9 @@
# first_pet # => #<OpenStruct name="Rowdy">
# first_pet == second_pet # => true
#
+# Ractor compatibility: A frozen OpenStruct with shareable values is itself shareable.
#
-# == Implementation
+# == Caveats
#
# An OpenStruct utilizes Ruby's method lookup structure to find and define the
# necessary methods for properties. This is accomplished through the methods
@@ -71,8 +73,41 @@
# This should be a consideration if there is a concern about the performance of
# the objects that are created, as there is much more overhead in the setting
# of these properties compared to using a Hash or a Struct.
+# Creating an open struct from a small Hash and accessing a few of the
+# entries can be 200 times slower than accessing the hash directly.
+#
+# This is a potential security issue; building OpenStruct from untrusted user data
+# (e.g. JSON web request) may be susceptible to a "symbol denial of service" attack
+# since the keys create methods and names of methods are never garbage collected.
+#
+# This may also be the source of incompatibilities between Ruby versions:
+#
+# o = OpenStruct.new
+# o.then # => nil in Ruby < 2.6, enumerator for Ruby >= 2.6
+#
+# Builtin methods may be overwritten this way, which may be a source of bugs
+# or security issues:
+#
+# o = OpenStruct.new
+# o.methods # => [:to_h, :marshal_load, :marshal_dump, :each_pair, ...
+# o.methods = [:foo, :bar]
+# o.methods # => [:foo, :bar]
+#
+# To help remedy clashes, OpenStruct uses only protected/private methods ending with `!`
+# and defines aliases for builtin public methods by adding a `!`:
+#
+# o = OpenStruct.new(make: 'Bentley', class: :luxury)
+# o.class # => :luxury
+# o.class! # => OpenStruct
+#
+# It is recommended (but not enforced) to not use fields ending in `!`;
+# Note that a subclass' methods may not be overwritten, nor can OpenStruct's own methods
+# ending with `!`.
+#
+# For all these reasons, consider not using OpenStruct at all.
#
class OpenStruct
+ VERSION = "0.3.1"
#
# Creates a new OpenStruct object. By default, the resulting OpenStruct
@@ -89,31 +124,54 @@ class OpenStruct
# data # => #<OpenStruct country="Australia", capital="Canberra">
#
def initialize(hash=nil)
- @table = {}
if hash
- hash.each_pair do |k, v|
- k = k.to_sym
- @table[k] = v
- end
+ update_to_values!(hash)
+ else
+ @table = {}
end
end
# Duplicates an OpenStruct object's Hash table.
- def initialize_copy(orig) # :nodoc:
+ private def initialize_clone(orig) # :nodoc:
+ super # clones the singleton class for us
+ @table = @table.dup unless @table.frozen?
+ end
+
+ private def initialize_dup(orig) # :nodoc:
super
- @table = @table.dup
+ update_to_values!(@table)
end
+ private def update_to_values!(hash) # :nodoc:
+ @table = {}
+ hash.each_pair do |k, v|
+ set_ostruct_member_value!(k, v)
+ end
+ end
+
+ #
+ # call-seq:
+ # ostruct.to_h -> hash
+ # ostruct.to_h {|name, value| block } -> hash
#
# Converts the OpenStruct to a hash with keys representing
# each attribute (as symbols) and their corresponding values.
#
+ # If a block is given, the results of the block on each pair of
+ # the receiver will be used as pairs.
+ #
# require "ostruct"
# data = OpenStruct.new("country" => "Australia", :capital => "Canberra")
# data.to_h # => {:country => "Australia", :capital => "Canberra" }
+ # data.to_h {|name, value| [name.to_s, value.upcase] }
+ # # => {"country" => "AUSTRALIA", "capital" => "CANBERRA" }
#
- def to_h
- @table.dup
+ def to_h(&block)
+ if block
+ @table.to_h(&block)
+ else
+ @table.dup
+ end
end
#
@@ -137,34 +195,14 @@ class OpenStruct
#
# Provides marshalling support for use by the Marshal library.
#
- def marshal_dump
+ def marshal_dump # :nodoc:
@table
end
#
# Provides marshalling support for use by the Marshal library.
#
- def marshal_load(x)
- @table = x
- end
-
- #
- # Used internally to check if the OpenStruct is able to be
- # modified before granting access to the internal Hash table to be modified.
- #
- def modifiable? # :nodoc:
- begin
- @modifiable = true
- rescue
- raise RuntimeError, "can't modify frozen #{self.class}", caller(3)
- end
- @table
- end
- private :modifiable?
-
- # ::Kernel.warn("#{caller(1, 1)[0]}: do not use OpenStruct#modifiable")
- alias modifiable modifiable? # :nodoc:
- protected :modifiable
+ alias_method :marshal_load, :update_to_values! # :nodoc:
#
# Used internally to defined properties on the
@@ -172,47 +210,42 @@ class OpenStruct
# define_singleton_method for both the getter method and the setter method.
#
def new_ostruct_member!(name) # :nodoc:
- name = name.to_sym
- unless singleton_class.method_defined?(name)
- define_singleton_method(name) { @table[name] }
- define_singleton_method("#{name}=") {|x| modifiable?[name] = x}
+ unless @table.key?(name) || is_method_protected!(name)
+ define_singleton_method!(name) { @table[name] }
+ define_singleton_method!("#{name}=") {|x| @table[name] = x}
end
- name
end
private :new_ostruct_member!
- # ::Kernel.warn("#{caller(1, 1)[0]}: do not use OpenStruct#new_ostruct_member")
- alias new_ostruct_member new_ostruct_member! # :nodoc:
- protected :new_ostruct_member
+ private def is_method_protected!(name) # :nodoc:
+ if !respond_to?(name, true)
+ false
+ elsif name.end_with?('!')
+ true
+ else
+ method!(name).owner < OpenStruct
+ end
+ end
def freeze
- @table.each_key {|key| new_ostruct_member!(key)}
+ @table.freeze
super
end
- def respond_to_missing?(mid, include_private = false) # :nodoc:
- mname = mid.to_s.chomp("=").to_sym
- @table&.key?(mname) || super
- end
-
- def method_missing(mid, *args) # :nodoc:
+ private def method_missing(mid, *args) # :nodoc:
len = args.length
if mname = mid[/.*(?==\z)/m]
if len != 1
- raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
- end
- modifiable?[new_ostruct_member!(mname)] = args[0]
- elsif len == 0 # and /\A[a-z_]\w*\z/ =~ mid #
- if @table.key?(mid)
- new_ostruct_member!(mid) unless frozen?
- @table[mid]
+ raise! ArgumentError, "wrong number of arguments (given #{len}, expected 1)", caller(1)
end
+ set_ostruct_member_value!(mname, args[0])
+ elsif len == 0
else
begin
super
rescue NoMethodError => err
err.backtrace.shift
- raise
+ raise!
end
end
end
@@ -221,7 +254,7 @@ class OpenStruct
# :call-seq:
# ostruct[name] -> object
#
- # Returns the value of an attribute.
+ # Returns the value of an attribute, or `nil` if there is no such attribute.
#
# require "ostruct"
# person = OpenStruct.new("name" => "John Smith", "age" => 70)
@@ -243,34 +276,32 @@ class OpenStruct
# person.age # => 42
#
def []=(name, value)
- modifiable?[new_ostruct_member!(name)] = value
+ name = name.to_sym
+ new_ostruct_member!(name)
+ @table[name] = value
end
+ alias_method :set_ostruct_member_value!, :[]=
+ private :set_ostruct_member_value!
- #
# :call-seq:
- # ostruct.dig(name, ...) -> object
+ # ostruct.dig(name, *identifiers) -> object
#
- # Extracts the nested value specified by the sequence of +name+
- # objects by calling +dig+ at each step, returning +nil+ if any
- # intermediate step is +nil+.
+ # Finds and returns the object in nested objects
+ # that is specified by +name+ and +identifiers+.
+ # The nested objects may be instances of various classes.
+ # See {Dig Methods}[rdoc-ref:doc/dig_methods.rdoc].
#
+ # Examples:
# require "ostruct"
# address = OpenStruct.new("city" => "Anytown NC", "zip" => 12345)
# person = OpenStruct.new("name" => "John Smith", "address" => address)
- #
- # person.dig(:address, "zip") # => 12345
- # person.dig(:business_address, "zip") # => nil
- #
- # data = OpenStruct.new(:array => [1, [2, 3]])
- #
- # data.dig(:array, 1, 0) # => 2
- # data.dig(:array, 0, 0) # TypeError: Integer does not have #dig method
- #
+ # person.dig(:address, "zip") # => 12345
+ # person.dig(:business_address, "zip") # => nil
def dig(name, *names)
begin
name = name.to_sym
rescue NoMethodError
- raise TypeError, "#{name} is not a symbol nor a string"
+ raise! TypeError, "#{name} is not a symbol nor a string"
end
@table.dig(name, *names)
end
@@ -283,7 +314,7 @@ class OpenStruct
#
# person = OpenStruct.new(name: "John", age: 70, pension: 300)
#
- # person.delete_field("age") # => 70
+ # person.delete_field!("age") # => 70
# person # => #<OpenStruct name="John", pension=300>
#
# Setting the value to +nil+ will not remove the attribute:
@@ -294,11 +325,11 @@ class OpenStruct
def delete_field(name)
sym = name.to_sym
begin
- singleton_class.__send__(:remove_method, sym, "#{sym}=")
+ singleton_class.remove_method(sym, "#{sym}=")
rescue NameError
end
@table.delete(sym) do
- raise NameError.new("no field `#{sym}' in #{self}", sym)
+ raise! NameError.new("no field `#{sym}' in #{self}", sym)
end
end
@@ -308,31 +339,26 @@ class OpenStruct
# Returns a string containing a detailed summary of the keys and values.
#
def inspect
- str = "#<#{self.class}"
-
ids = (Thread.current[InspectKey] ||= [])
if ids.include?(object_id)
- return str << ' ...>'
- end
-
- ids << object_id
- begin
- first = true
- for k,v in @table
- str << "," unless first
- first = false
- str << " #{k}=#{v.inspect}"
+ detail = ' ...'
+ else
+ ids << object_id
+ begin
+ detail = @table.map do |key, value|
+ " #{key}=#{value.inspect}"
+ end.join(',')
+ ensure
+ ids.pop
end
- return str << '>'
- ensure
- ids.pop
end
+ ['#<', self.class!, detail, '>'].join
end
alias :to_s :inspect
attr_reader :table # :nodoc:
- protected :table
alias table! table
+ protected :table!
#
# Compares this object and +other+ for equality. An OpenStruct is equal to
@@ -363,11 +389,43 @@ class OpenStruct
end
# Computes a hash code for this OpenStruct.
- # Two OpenStruct objects with the same content will have the same hash code
- # (and will compare using #eql?).
- #
- # See also Object#hash.
- def hash
+ def hash # :nodoc:
@table.hash
end
+
+ #
+ # Provides marshalling support for use by the YAML library.
+ #
+ def encode_with(coder) # :nodoc:
+ @table.each_pair do |key, value|
+ coder[key.to_s] = value
+ end
+ if @table.size == 1 && @table.key?(:table) # support for legacy format
+ # in the very unlikely case of a single entry called 'table'
+ coder['legacy_support!'] = true # add a bogus second entry
+ end
+ end
+
+ #
+ # Provides marshalling support for use by the YAML library.
+ #
+ def init_with(coder) # :nodoc:
+ h = coder.map
+ if h.size == 1 # support for legacy format
+ key, val = h.first
+ if key == 'table'
+ h = val
+ end
+ end
+ update_to_values!(h)
+ end
+
+ # Make all public methods (builtin or our own) accessible with `!`:
+ instance_methods.each do |method|
+ new_name = "#{method}!"
+ alias_method new_name, method
+ end
+ # Other builtin private methods we use:
+ alias_method :raise!, :raise
+ private :raise!
end
diff --git a/lib/ostruct/ostruct.gemspec b/lib/ostruct/ostruct.gemspec
new file mode 100644
index 0000000000..f69a858aa2
--- /dev/null
+++ b/lib/ostruct/ostruct.gemspec
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Marc-Andre Lafortune"]
+ spec.email = ["ruby-core@marc-andre.ca"]
+
+ spec.summary = %q{Class to build custom data structures, similar to a Hash.}
+ spec.description = %q{Class to build custom data structures, similar to a Hash.}
+ spec.homepage = "https://github.com/ruby/ostruct"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = ">= 2.5.0"
+
+ spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/ostruct.rb", "ostruct.gemspec"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_development_dependency "bundler"
+ spec.add_development_dependency "rake"
+end
diff --git a/lib/pp.gemspec b/lib/pp.gemspec
new file mode 100644
index 0000000000..b81df28bee
--- /dev/null
+++ b/lib/pp.gemspec
@@ -0,0 +1,27 @@
+Gem::Specification.new do |spec|
+ spec.name = "pp"
+ spec.version = "0.2.1"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Provides a PrettyPrinter for Ruby objects}
+ spec.description = %q{Provides a PrettyPrinter for Ruby objects}
+ spec.homepage = "https://github.com/ruby/pp"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = %w[
+ LICENSE.txt
+ lib/pp.rb
+ pp.gemspec
+ ]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "prettyprint"
+end
diff --git a/lib/pp.rb b/lib/pp.rb
index 7d1c502817..72480e5304 100644
--- a/lib/pp.rb
+++ b/lib/pp.rb
@@ -2,36 +2,9 @@
require 'prettyprint'
-module Kernel
- # Returns a pretty printed object as a string.
- #
- # In order to use this method you must first require the PP module:
- #
- # require 'pp'
- #
- # See the PP module for more information.
- def pretty_inspect
- PP.pp(self, ''.dup)
- end
-
- # prints arguments in pretty form.
- #
- # pp returns argument(s).
- def pp(*objs)
- objs.each {|obj|
- PP.pp(obj)
- }
- objs.size <= 1 ? objs.first : objs
- end
- module_function :pp
-end
-
##
# A pretty-printer for Ruby objects.
#
-# All examples assume you have loaded the PP class with:
-# require 'pp'
-#
##
# == What PP Does
#
@@ -116,15 +89,29 @@ class PP < PrettyPrint
# :stopdoc:
def PP.mcall(obj, mod, meth, *args, &block)
- mod.instance_method(meth).bind(obj).call(*args, &block)
+ mod.instance_method(meth).bind_call(obj, *args, &block)
end
# :startdoc:
- @sharing_detection = false
- class << self
- # Returns the sharing detection flag as a boolean value.
- # It is false by default.
- attr_accessor :sharing_detection
+ if defined? ::Ractor
+ class << self
+ # Returns the sharing detection flag as a boolean value.
+ # It is false (nil) by default.
+ def sharing_detection
+ Ractor.current[:pp_sharing_detection]
+ end
+ # Sets the sharing detection flag to b.
+ def sharing_detection=(b)
+ Ractor.current[:pp_sharing_detection] = b
+ end
+ end
+ else
+ @sharing_detection = false
+ class << self
+ # Returns the sharing detection flag as a boolean value.
+ # It is false by default.
+ attr_accessor :sharing_detection
+ end
end
module PPMethods
@@ -133,17 +120,17 @@ class PP < PrettyPrint
# and preserves the previous set of objects being printed.
def guard_inspect_key
if Thread.current[:__recursive_key__] == nil
- Thread.current[:__recursive_key__] = {}.taint
+ Thread.current[:__recursive_key__] = {}.compare_by_identity
end
if Thread.current[:__recursive_key__][:inspect] == nil
- Thread.current[:__recursive_key__][:inspect] = {}.taint
+ Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity
end
save = Thread.current[:__recursive_key__][:inspect]
begin
- Thread.current[:__recursive_key__][:inspect] = {}.taint
+ Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity
yield
ensure
Thread.current[:__recursive_key__][:inspect] = save
@@ -176,18 +163,20 @@ class PP < PrettyPrint
# Object#pretty_print_cycle is used when +obj+ is already
# printed, a.k.a the object reference chain has a cycle.
def pp(obj)
- id = obj.object_id
+ # If obj is a Delegator then use the object being delegated to for cycle
+ # detection
+ obj = obj.__getobj__ if defined?(::Delegator) and obj.is_a?(::Delegator)
- if check_inspect_key(id)
+ if check_inspect_key(obj)
group {obj.pretty_print_cycle self}
return
end
begin
- push_inspect_key(id)
+ push_inspect_key(obj)
group {obj.pretty_print self}
ensure
- pop_inspect_key(id) unless PP.sharing_detection
+ pop_inspect_key(obj) unless PP.sharing_detection
end
end
@@ -201,7 +190,7 @@ class PP < PrettyPrint
# A convenience method, like object_group, but also reformats the Object's
# object_id.
def object_address_group(obj, &block)
- str = Kernel.instance_method(:to_s).bind(obj).call
+ str = Kernel.instance_method(:to_s).bind_call(obj)
str.chomp!('>')
group(1, str, '>', &block)
end
@@ -248,7 +237,7 @@ class PP < PrettyPrint
else
sep.call
end
- yield(*v)
+ RUBY_VERSION >= "3.0" ? yield(*v, **{}) : yield(*v)
}
end
@@ -306,9 +295,9 @@ class PP < PrettyPrint
# This module provides predefined #pretty_print methods for some of
# the most commonly used built-in classes for convenience.
def pretty_print(q)
- method_method = Object.instance_method(:method).bind(self)
+ umethod_method = Object.instance_method(:method)
begin
- inspect_method = method_method.call(:inspect)
+ inspect_method = umethod_method.bind_call(self, :inspect)
rescue NameError
end
if inspect_method && inspect_method.owner != Kernel
@@ -345,7 +334,7 @@ class PP < PrettyPrint
# However, doing this requires that every class that #inspect is called on
# implement #pretty_print, or a RuntimeError will be raised.
def pretty_print_inspect
- if Object.instance_method(:method).bind(self).call(:pretty_print).owner == PP::ObjectMixin
+ if Object.instance_method(:method).bind_call(self, :pretty_print).owner == PP::ObjectMixin
raise "pretty_print is not overridden for #{self.class}"
end
PP.singleline_pp(self, ''.dup)
@@ -413,7 +402,7 @@ class Range # :nodoc:
q.breakable ''
q.text(self.exclude_end? ? '...' : '..')
q.breakable ''
- q.pp self.end
+ q.pp self.end if self.end
end
end
@@ -541,6 +530,40 @@ class MatchData # :nodoc:
end
end
+class RubyVM::AbstractSyntaxTree::Node
+ def pretty_print_children(q, names = [])
+ children.zip(names) do |c, n|
+ if n
+ q.breakable
+ q.text "#{n}:"
+ end
+ q.group(2) do
+ q.breakable
+ q.pp c
+ end
+ end
+ end
+
+ def pretty_print(q)
+ q.group(1, "(#{type}@#{first_lineno}:#{first_column}-#{last_lineno}:#{last_column}", ")") {
+ case type
+ when :SCOPE
+ pretty_print_children(q, %w"tbl args body")
+ when :ARGS
+ pretty_print_children(q, %w[pre_num pre_init opt first_post post_num post_init rest kw kwrest block])
+ when :DEFN
+ pretty_print_children(q, %w[mid body])
+ when :ARYPTN
+ pretty_print_children(q, %w[const pre rest post])
+ when :HSHPTN
+ pretty_print_children(q, %w[const kw kwrest])
+ else
+ pretty_print_children(q)
+ end
+ }
+ end
+end
+
class Object < BasicObject # :nodoc:
include PP::ObjectMixin
end
@@ -560,3 +583,27 @@ end
end
}
}
+
+module Kernel
+ # Returns a pretty printed object as a string.
+ #
+ # In order to use this method you must first require the PP module:
+ #
+ # require 'pp'
+ #
+ # See the PP module for more information.
+ def pretty_inspect
+ PP.pp(self, ''.dup)
+ end
+
+ # prints arguments in pretty form.
+ #
+ # pp returns argument(s).
+ def pp(*objs)
+ objs.each {|obj|
+ PP.pp(obj)
+ }
+ objs.size <= 1 ? objs.first : objs
+ end
+ module_function :pp
+end
diff --git a/lib/prettyprint.gemspec b/lib/prettyprint.gemspec
new file mode 100644
index 0000000000..eae2227d60
--- /dev/null
+++ b/lib/prettyprint.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "prettyprint"
+ spec.version = "0.1.1"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Implements a pretty printing algorithm for readable structure.}
+ spec.description = %q{Implements a pretty printing algorithm for readable structure.}
+ spec.homepage = "https://github.com/ruby/prettyprint"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/prettyprint.rb b/lib/prettyprint.rb
index 2a3ca90dc1..188c2e6db0 100644
--- a/lib/prettyprint.rb
+++ b/lib/prettyprint.rb
@@ -102,7 +102,7 @@ class PrettyPrint
# The maximum width of a line, before it is separated in to a newline
#
- # This defaults to 79, and should be a Fixnum
+ # This defaults to 79, and should be an Integer
attr_reader :maxwidth
# The value that is appended to +output+ to add a new line.
@@ -110,7 +110,7 @@ class PrettyPrint
# This defaults to "\n", and should be String
attr_reader :newline
- # A lambda or Proc, that takes one argument, of a Fixnum, and returns
+ # A lambda or Proc, that takes one argument, of an Integer, and returns
# the corresponding number of spaces.
#
# By default this is:
@@ -340,7 +340,7 @@ class PrettyPrint
#
# Arguments:
# * +sep+ String of the separator
- # * +width+ Fixnum width of the +sep+
+ # * +width+ Integer width of the +sep+
# * +q+ parent PrettyPrint object, to base from
def initialize(sep, width, q)
@obj = sep
diff --git a/lib/prime.gemspec b/lib/prime.gemspec
new file mode 100644
index 0000000000..8369d4d3d5
--- /dev/null
+++ b/lib/prime.gemspec
@@ -0,0 +1,28 @@
+begin
+ require_relative "lib/prime"
+rescue LoadError
+ # for Ruby core repository
+ require_relative "prime"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "prime"
+ spec.version = Prime::VERSION
+ spec.authors = ["Marc-Andre Lafortune"]
+ spec.email = ["ruby-core@marc-andre.ca"]
+
+ spec.summary = %q{Prime numbers and factorization library.}
+ spec.description = %q{Prime numbers and factorization library.}
+ spec.homepage = "https://github.com/ruby/prime"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/prime.rb", "prime.gemspec"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.required_ruby_version = ">= 2.5.0"
+
+ spec.add_dependency "singleton"
+ spec.add_dependency "forwardable"
+end
diff --git a/lib/prime.rb b/lib/prime.rb
index 2cd22da3a8..fd9d6ac7be 100644
--- a/lib/prime.rb
+++ b/lib/prime.rb
@@ -31,8 +31,14 @@ class Integer
end
# Returns true if +self+ is a prime number, else returns false.
+ # Not recommended for very big integers (> 10**23).
def prime?
return self >= 2 if self <= 3
+
+ if (bases = miller_rabin_bases)
+ return miller_rabin_test(bases)
+ end
+
return true if self == 5
return false unless 30.gcd(self) == 1
(7..Integer.sqrt(self)).step(30) do |p|
@@ -43,6 +49,73 @@ class Integer
true
end
+ MILLER_RABIN_BASES = [
+ [2],
+ [2,3],
+ [31,73],
+ [2,3,5],
+ [2,3,5,7],
+ [2,7,61],
+ [2,13,23,1662803],
+ [2,3,5,7,11],
+ [2,3,5,7,11,13],
+ [2,3,5,7,11,13,17],
+ [2,3,5,7,11,13,17,19,23],
+ [2,3,5,7,11,13,17,19,23,29,31,37],
+ [2,3,5,7,11,13,17,19,23,29,31,37,41],
+ ].map!(&:freeze).freeze
+ private_constant :MILLER_RABIN_BASES
+
+ private def miller_rabin_bases
+ # Miller-Rabin's complexity is O(k log^3n).
+ # So we can reduce the complexity by reducing the number of bases tested.
+ # Using values from https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
+ i = case
+ when self < 0xffff then
+ # For small integers, Miller Rabin can be slower
+ # There is no mathematical significance to 0xffff
+ return nil
+ # when self < 2_047 then 0
+ when self < 1_373_653 then 1
+ when self < 9_080_191 then 2
+ when self < 25_326_001 then 3
+ when self < 3_215_031_751 then 4
+ when self < 4_759_123_141 then 5
+ when self < 1_122_004_669_633 then 6
+ when self < 2_152_302_898_747 then 7
+ when self < 3_474_749_660_383 then 8
+ when self < 341_550_071_728_321 then 9
+ when self < 3_825_123_056_546_413_051 then 10
+ when self < 318_665_857_834_031_151_167_461 then 11
+ when self < 3_317_044_064_679_887_385_961_981 then 12
+ else return nil
+ end
+ MILLER_RABIN_BASES[i]
+ end
+
+ private def miller_rabin_test(bases)
+ return false if even?
+
+ r = 0
+ d = self >> 1
+ while d.even?
+ d >>= 1
+ r += 1
+ end
+
+ self_minus_1 = self-1
+ bases.each do |a|
+ x = a.pow(d, self)
+ next if x == 1 || x == self_minus_1 || a == self
+
+ return false if r.times do
+ x = x.pow(2, self)
+ break if x == self_minus_1
+ end
+ end
+ true
+ end
+
# Iterates the given block over all prime numbers.
#
# See +Prime+#each for more details.
@@ -84,7 +157,7 @@ end
# There are few implementations of generator.
#
# [+Prime+::+EratosthenesGenerator+]
-# Uses eratosthenes' sieve.
+# Uses Eratosthenes' sieve.
# [+Prime+::+TrialDivisionGenerator+]
# Uses the trial division method.
# [+Prime+::+Generator23+]
@@ -95,6 +168,9 @@ end
# has many prime factors. e.g. for Prime#prime? .
class Prime
+
+ VERSION = "0.1.2"
+
include Enumerable
include Singleton
@@ -138,8 +214,22 @@ class Prime
generator.each(&block)
end
+ # Returns true if +obj+ is an Integer and is prime. Also returns
+ # true if +obj+ is a Module that is an ancestor of +Prime+.
+ # Otherwise returns false.
+ def include?(obj)
+ case obj
+ when Integer
+ prime?(obj)
+ when Module
+ Module.instance_method(:include?).bind(Prime).call(obj)
+ else
+ false
+ end
+ end
# Returns true if +value+ is a prime number, else returns false.
+ # Integer#prime? is much more performant.
#
# == Parameters
#
@@ -158,17 +248,23 @@ class Prime
# Re-composes a prime factorization and returns the product.
#
+ # For the decomposition:
+ #
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]],
+ #
+ # it returns:
+ #
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n.
+ #
# == Parameters
- # +pd+:: Array of pairs of integers. The each internal
- # pair consists of a prime number -- a prime factor --
- # and a natural number -- an exponent.
+ # +pd+:: Array of pairs of integers.
+ # Each pair consists of a prime number -- a prime factor --
+ # and a natural number -- its exponent (multiplicity).
#
# == Example
- # For <tt>[[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]]</tt>, it returns:
+ # Prime.int_from_prime_division([[3, 2], [5, 1]]) #=> 45
+ # 3**2 * 5 #=> 45
#
- # p_1**e_1 * p_2**e_2 * .... * p_n**e_n.
- #
- # Prime.int_from_prime_division([[2,2], [3,1]]) #=> 12
def int_from_prime_division(pd)
pd.inject(1){|value, (prime, index)|
value * prime**index
@@ -177,27 +273,32 @@ class Prime
# Returns the factorization of +value+.
#
+ # For an arbitrary integer:
+ #
+ # p_1**e_1 * p_2**e_2 * ... * p_n**e_n,
+ #
+ # prime_division returns an array of pairs of integers:
+ #
+ # [[p_1, e_1], [p_2, e_2], ..., [p_n, e_n]].
+ #
+ # Each pair consists of a prime number -- a prime factor --
+ # and a natural number -- its exponent (multiplicity).
+ #
# == Parameters
# +value+:: An arbitrary integer.
# +generator+:: Optional. A pseudo-prime generator.
# +generator+.succ must return the next
- # pseudo-prime number in the ascending
- # order. It must generate all prime numbers,
- # but may also generate non prime numbers too.
+ # pseudo-prime number in ascending order.
+ # It must generate all prime numbers,
+ # but may also generate non-prime numbers, too.
#
# === Exceptions
# +ZeroDivisionError+:: when +value+ is zero.
#
# == Example
- # For an arbitrary integer:
- #
- # n = p_1**e_1 * p_2**e_2 * .... * p_n**e_n,
#
- # prime_division(n) returns:
- #
- # [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].
- #
- # Prime.prime_division(12) #=> [[2,2], [3,1]]
+ # Prime.prime_division(45) #=> [[3, 2], [5, 1]]
+ # 3**2 * 5 #=> 45
#
def prime_division(value, generator = Prime::Generator23.new)
raise ZeroDivisionError if value == 0
@@ -280,9 +381,9 @@ class Prime
end
# see +Enumerator+#with_index.
- def with_index(offset = 0)
- return enum_for(:with_index, offset) { Float::INFINITY } unless block_given?
- return each_with_index(&proc) if offset == 0
+ def with_index(offset = 0, &block)
+ return enum_for(:with_index, offset) { Float::INFINITY } unless block
+ return each_with_index(&block) if offset == 0
each do |prime|
yield prime, offset
@@ -388,13 +489,6 @@ class Prime
@ulticheck_next_squared = 121 # @primes[@ulticheck_index + 1] ** 2
end
- # Returns the cached prime numbers.
- def cache
- @primes
- end
- alias primes cache
- alias primes_so_far cache
-
# Returns the +index+th prime number.
#
# +index+ is a 0-based index.
diff --git a/lib/profile.rb b/lib/profile.rb
deleted file mode 100644
index e58c92125b..0000000000
--- a/lib/profile.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-require 'profiler'
-
-RubyVM::InstructionSequence.compile_option = {
- :trace_instruction => true,
- :specialized_instruction => false
-}
-END {
- Profiler__::print_profile(STDERR)
-}
-Profiler__::start_profile
diff --git a/lib/profiler.rb b/lib/profiler.rb
deleted file mode 100644
index b3c9f7f46a..0000000000
--- a/lib/profiler.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-# frozen_string_literal: true
-# Profile provides a way to Profile your Ruby application.
-#
-# Profiling your program is a way of determining which methods are called and
-# how long each method takes to complete. This way you can detect which
-# methods are possible bottlenecks.
-#
-# Profiling your program will slow down your execution time considerably,
-# so activate it only when you need it. Don't confuse benchmarking with
-# profiling.
-#
-# There are two ways to activate Profiling:
-#
-# == Command line
-#
-# Run your Ruby script with <code>-rprofile</code>:
-#
-# ruby -rprofile example.rb
-#
-# If you're profiling an executable in your <code>$PATH</code> you can use
-# <code>ruby -S</code>:
-#
-# ruby -rprofile -S some_executable
-#
-# == From code
-#
-# Just require 'profile':
-#
-# require 'profile'
-#
-# def slow_method
-# 5000.times do
-# 9999999999999999*999999999
-# end
-# end
-#
-# def fast_method
-# 5000.times do
-# 9999999999999999+999999999
-# end
-# end
-#
-# slow_method
-# fast_method
-#
-# The output in both cases is a report when the execution is over:
-#
-# ruby -rprofile example.rb
-#
-# % cumulative self self total
-# time seconds seconds calls ms/call ms/call name
-# 68.42 0.13 0.13 2 65.00 95.00 Integer#times
-# 15.79 0.16 0.03 5000 0.01 0.01 Fixnum#*
-# 15.79 0.19 0.03 5000 0.01 0.01 Fixnum#+
-# 0.00 0.19 0.00 2 0.00 0.00 IO#set_encoding
-# 0.00 0.19 0.00 1 0.00 100.00 Object#slow_method
-# 0.00 0.19 0.00 2 0.00 0.00 Module#method_added
-# 0.00 0.19 0.00 1 0.00 90.00 Object#fast_method
-# 0.00 0.19 0.00 1 0.00 190.00 #toplevel
-
-module Profiler__
- class Wrapper < Struct.new(:defined_class, :method_id, :hash) # :nodoc:
- private :defined_class=, :method_id=, :hash=
-
- def initialize(klass, mid)
- super(klass, mid, nil)
- self.hash = Struct.instance_method(:hash).bind(self).call
- end
-
- def to_s
- "#{defined_class.inspect}#".sub(/\A\#<Class:(.*)>#\z/, '\1.') << method_id.to_s
- end
- alias inspect to_s
- end
-
- # internal values
- @@start = nil # the start time that profiling began
- @@stacks = nil # the map of stacks keyed by thread
- @@maps = nil # the map of call data keyed by thread, class and id. Call data contains the call count, total time,
- PROFILE_CALL_PROC = TracePoint.new(*%i[call c_call b_call]) {|tp| # :nodoc:
- now = Process.times[0]
- stack = (@@stacks[Thread.current] ||= [])
- stack.push [now, 0.0]
- }
- PROFILE_RETURN_PROC = TracePoint.new(*%i[return c_return b_return]) {|tp| # :nodoc:
- now = Process.times[0]
- key = Wrapper.new(tp.defined_class, tp.method_id)
- stack = (@@stacks[Thread.current] ||= [])
- if tick = stack.pop
- threadmap = (@@maps[Thread.current] ||= {})
- data = (threadmap[key] ||= [0, 0.0, 0.0, key])
- data[0] += 1
- cost = now - tick[0]
- data[1] += cost
- data[2] += cost - tick[1]
- stack[-1][1] += cost if stack[-1]
- end
- }
-module_function
- # Starts the profiler.
- #
- # See Profiler__ for more information.
- def start_profile
- @@start = Process.times[0]
- @@stacks = {}
- @@maps = {}
- PROFILE_CALL_PROC.enable
- PROFILE_RETURN_PROC.enable
- end
- # Stops the profiler.
- #
- # See Profiler__ for more information.
- def stop_profile
- PROFILE_CALL_PROC.disable
- PROFILE_RETURN_PROC.disable
- end
- # Outputs the results from the profiler.
- #
- # See Profiler__ for more information.
- def print_profile(f)
- stop_profile
- total = Process.times[0] - @@start
- if total == 0 then total = 0.01 end
- totals = {}
- @@maps.values.each do |threadmap|
- threadmap.each do |key, data|
- total_data = (totals[key] ||= [0, 0.0, 0.0, key])
- total_data[0] += data[0]
- total_data[1] += data[1]
- total_data[2] += data[2]
- end
- end
-
- # Maybe we should show a per thread output and a totals view?
-
- data = totals.values
- data = data.sort_by{|x| -x[2]}
- sum = 0
- f.printf " %% cumulative self self total\n"
- f.printf " time seconds seconds calls ms/call ms/call name\n"
- for d in data
- sum += d[2]
- f.printf "%6.2f %8.2f %8.2f %8d ", d[2]/total*100, sum, d[2], d[0]
- f.printf "%8.2f %8.2f %s\n", d[2]*1000/d[0], d[1]*1000/d[0], d[3]
- end
- f.printf "%6.2f %8.2f %8.2f %8d ", 0.0, total, 0.0, 1 # ???
- f.printf "%8.2f %8.2f %s\n", 0.0, total*1000, "#toplevel" # ???
- end
-end
diff --git a/lib/pstore.rb b/lib/pstore.rb
index 4daa2e003f..a46bcb84bc 100644
--- a/lib/pstore.rb
+++ b/lib/pstore.rb
@@ -92,6 +92,8 @@ require "digest"
# Needless to say, if you're storing valuable data with PStore, then you should
# backup the PStore files from time to time.
class PStore
+ VERSION = "0.1.1"
+
RDWR_ACCESS = {mode: IO::RDWR | IO::CREAT | IO::BINARY, encoding: Encoding::ASCII_8BIT}.freeze
RD_ACCESS = {mode: IO::RDONLY | IO::BINARY, encoding: Encoding::ASCII_8BIT}.freeze
WR_ACCESS = {mode: IO::WRONLY | IO::CREAT | IO::TRUNC | IO::BINARY, encoding: Encoding::ASCII_8BIT}.freeze
@@ -374,7 +376,7 @@ class PStore
def open_and_lock_file(filename, read_only)
if read_only
begin
- file = File.new(filename, RD_ACCESS)
+ file = File.new(filename, **RD_ACCESS)
begin
file.flock(File::LOCK_SH)
return file
@@ -386,7 +388,7 @@ class PStore
return nil
end
else
- file = File.new(filename, RDWR_ACCESS)
+ file = File.new(filename, **RDWR_ACCESS)
file.flock(File::LOCK_EX)
return file
end
@@ -449,7 +451,7 @@ class PStore
def save_data_with_atomic_file_rename_strategy(data, file)
temp_filename = "#{@filename}.tmp.#{Process.pid}.#{rand 1000000}"
- temp_file = File.new(temp_filename, WR_ACCESS)
+ temp_file = File.new(temp_filename, **WR_ACCESS)
begin
temp_file.flock(File::LOCK_EX)
temp_file.write(data)
diff --git a/lib/pstore/pstore.gemspec b/lib/pstore/pstore.gemspec
new file mode 100644
index 0000000000..8425795afe
--- /dev/null
+++ b/lib/pstore/pstore.gemspec
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Transactional File Storage for Ruby Objects}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/pstore"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = "https://github.com/ruby/pstore"
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/racc.rb b/lib/racc.rb
new file mode 100644
index 0000000000..f6e4ac03a8
--- /dev/null
+++ b/lib/racc.rb
@@ -0,0 +1,6 @@
+require 'racc/compat'
+require 'racc/debugflags'
+require 'racc/grammar'
+require 'racc/state'
+require 'racc/exception'
+require 'racc/info'
diff --git a/lib/racc/compat.rb b/lib/racc/compat.rb
new file mode 100644
index 0000000000..62f4f630be
--- /dev/null
+++ b/lib/racc/compat.rb
@@ -0,0 +1,33 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+unless Object.method_defined?(:__send)
+ class Object
+ alias __send __send__
+ end
+end
+
+unless Object.method_defined?(:__send!)
+ class Object
+ alias __send! __send__
+ end
+end
+
+unless Array.method_defined?(:map!)
+ class Array
+ if Array.method_defined?(:collect!)
+ alias map! collect!
+ else
+ alias map! filter
+ end
+ end
+end
diff --git a/lib/racc/debugflags.rb b/lib/racc/debugflags.rb
new file mode 100644
index 0000000000..ee34cf2314
--- /dev/null
+++ b/lib/racc/debugflags.rb
@@ -0,0 +1,60 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ class DebugFlags
+ def DebugFlags.parse_option_string(s)
+ parse = rule = token = state = la = prec = conf = false
+ s.split(//).each do |ch|
+ case ch
+ when 'p' then parse = true
+ when 'r' then rule = true
+ when 't' then token = true
+ when 's' then state = true
+ when 'l' then la = true
+ when 'c' then prec = true
+ when 'o' then conf = true
+ else
+ raise "unknown debug flag char: #{ch.inspect}"
+ end
+ end
+ new(parse, rule, token, state, la, prec, conf)
+ end
+
+ def initialize(parse = false, rule = false, token = false, state = false,
+ la = false, prec = false, conf = false)
+ @parse = parse
+ @rule = rule
+ @token = token
+ @state = state
+ @la = la
+ @prec = prec
+ @any = (parse || rule || token || state || la || prec)
+ @status_logging = conf
+ end
+
+ attr_reader :parse
+ attr_reader :rule
+ attr_reader :token
+ attr_reader :state
+ attr_reader :la
+ attr_reader :prec
+
+ def any?
+ @any
+ end
+
+ attr_reader :status_logging
+ end
+
+end
diff --git a/lib/racc/exception.rb b/lib/racc/exception.rb
new file mode 100644
index 0000000000..c11dc2e43e
--- /dev/null
+++ b/lib/racc/exception.rb
@@ -0,0 +1,16 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+ class Error < StandardError; end
+ class CompileError < Error; end
+end
diff --git a/lib/racc/grammar.rb b/lib/racc/grammar.rb
new file mode 100644
index 0000000000..3444dfcce3
--- /dev/null
+++ b/lib/racc/grammar.rb
@@ -0,0 +1,1118 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/compat'
+require 'racc/iset'
+require 'racc/sourcetext'
+require 'racc/logfilegenerator'
+require 'racc/exception'
+require 'forwardable'
+
+module Racc
+
+ class Grammar
+
+ def initialize(debug_flags = DebugFlags.new)
+ @symboltable = SymbolTable.new
+ @debug_symbol = debug_flags.token
+ @rules = [] # :: [Rule]
+ @start = nil
+ @n_expected_srconflicts = nil
+ @prec_table = []
+ @prec_table_closed = false
+ @closed = false
+ @states = nil
+ end
+
+ attr_reader :start
+ attr_reader :symboltable
+ attr_accessor :n_expected_srconflicts
+
+ def [](x)
+ @rules[x]
+ end
+
+ def each_rule(&block)
+ @rules.each(&block)
+ end
+
+ alias each each_rule
+
+ def each_index(&block)
+ @rules.each_index(&block)
+ end
+
+ def each_with_index(&block)
+ @rules.each_with_index(&block)
+ end
+
+ def size
+ @rules.size
+ end
+
+ def to_s
+ "<Racc::Grammar>"
+ end
+
+ extend Forwardable
+
+ def_delegator "@symboltable", :each, :each_symbol
+ def_delegator "@symboltable", :each_terminal
+ def_delegator "@symboltable", :each_nonterminal
+
+ def intern(value, dummy = false)
+ @symboltable.intern(value, dummy)
+ end
+
+ def symbols
+ @symboltable.symbols
+ end
+
+ def nonterminal_base
+ @symboltable.nt_base
+ end
+
+ def useless_nonterminal_exist?
+ n_useless_nonterminals() != 0
+ end
+
+ def n_useless_nonterminals
+ @n_useless_nonterminals ||= each_useless_nonterminal.count
+ end
+
+ def each_useless_nonterminal
+ return to_enum __method__ unless block_given?
+
+ @symboltable.each_nonterminal do |sym|
+ yield sym if sym.useless?
+ end
+ end
+
+ def useless_rule_exist?
+ n_useless_rules() != 0
+ end
+
+ def n_useless_rules
+ @n_useless_rules ||= each_useless_rule.count
+ end
+
+ def each_useless_rule
+ return to_enum __method__ unless block_given?
+
+ each do |r|
+ yield r if r.useless?
+ end
+ end
+
+ def nfa
+ (@states ||= States.new(self)).nfa
+ end
+
+ def dfa
+ (@states ||= States.new(self)).dfa
+ end
+
+ alias states dfa
+
+ def state_transition_table
+ states().state_transition_table
+ end
+
+ def parser_class
+ states = states() # cache
+ if $DEBUG
+ srcfilename = caller(1).first.slice(/\A(.*?):/, 1)
+ begin
+ write_log srcfilename + ".output"
+ rescue SystemCallError
+ end
+ report = lambda {|s| $stderr.puts "racc: #{srcfilename}: #{s}" }
+ if states.should_report_srconflict?
+ report["#{states.n_srconflicts} shift/reduce conflicts"]
+ end
+ if states.rrconflict_exist?
+ report["#{states.n_rrconflicts} reduce/reduce conflicts"]
+ end
+ g = states.grammar
+ if g.useless_nonterminal_exist?
+ report["#{g.n_useless_nonterminals} useless nonterminals"]
+ end
+ if g.useless_rule_exist?
+ report["#{g.n_useless_rules} useless rules"]
+ end
+ end
+ states.state_transition_table.parser_class
+ end
+
+ def write_log(path)
+ File.open(path, 'w') {|f|
+ LogFileGenerator.new(states()).output f
+ }
+ end
+
+ #
+ # Grammar Definition Interface
+ #
+
+ def add(rule)
+ raise ArgumentError, "rule added after the Grammar closed" if @closed
+ @rules.push rule
+ end
+
+ def added?(sym)
+ @rules.detect {|r| r.target == sym }
+ end
+
+ def start_symbol=(s)
+ raise CompileError, "start symbol set twice'" if @start
+ @start = s
+ end
+
+ def declare_precedence(assoc, syms)
+ raise CompileError, "precedence table defined twice" if @prec_table_closed
+ @prec_table.push [assoc, syms]
+ end
+
+ def end_precedence_declaration(reverse)
+ @prec_table_closed = true
+ return if @prec_table.empty?
+ table = reverse ? @prec_table.reverse : @prec_table
+ table.each_with_index do |(assoc, syms), idx|
+ syms.each do |sym|
+ sym.assoc = assoc
+ sym.precedence = idx
+ end
+ end
+ end
+
+ #
+ # Dynamic Generation Interface
+ #
+
+ def Grammar.define(&block)
+ env = DefinitionEnv.new
+ env.instance_eval(&block)
+ env.grammar
+ end
+
+ class DefinitionEnv
+ def initialize
+ @grammar = Grammar.new
+ @seqs = Hash.new(0)
+ @delayed = []
+ end
+
+ def grammar
+ flush_delayed
+ @grammar.each do |rule|
+ if rule.specified_prec
+ rule.specified_prec = @grammar.intern(rule.specified_prec)
+ end
+ end
+ @grammar.init
+ @grammar
+ end
+
+ def precedence_table(&block)
+ env = PrecedenceDefinitionEnv.new(@grammar)
+ env.instance_eval(&block)
+ @grammar.end_precedence_declaration env.reverse
+ end
+
+ def method_missing(mid, *args, &block)
+ unless mid.to_s[-1,1] == '='
+ super # raises NoMethodError
+ end
+ target = @grammar.intern(mid.to_s.chop.intern)
+ unless args.size == 1
+ raise ArgumentError, "too many arguments for #{mid} (#{args.size} for 1)"
+ end
+ _add target, args.first
+ end
+
+ def _add(target, x)
+ case x
+ when Sym
+ @delayed.each do |rule|
+ rule.replace x, target if rule.target == x
+ end
+ @grammar.symboltable.delete x
+ else
+ x.each_rule do |r|
+ r.target = target
+ @grammar.add r
+ end
+ end
+ flush_delayed
+ end
+
+ def _delayed_add(rule)
+ @delayed.push rule
+ end
+
+ def _added?(sym)
+ @grammar.added?(sym) or @delayed.detect {|r| r.target == sym }
+ end
+
+ def flush_delayed
+ return if @delayed.empty?
+ @delayed.each do |rule|
+ @grammar.add rule
+ end
+ @delayed.clear
+ end
+
+ def seq(*list, &block)
+ Rule.new(nil, list.map {|x| _intern(x) }, UserAction.proc(block))
+ end
+
+ def null(&block)
+ seq(&block)
+ end
+
+ def action(&block)
+ id = "@#{@seqs["action"] += 1}".intern
+ _delayed_add Rule.new(@grammar.intern(id), [], UserAction.proc(block))
+ id
+ end
+
+ alias _ action
+
+ def option(sym, default = nil, &block)
+ _defmetasyntax("option", _intern(sym), block) {|target|
+ seq() { default } | seq(sym)
+ }
+ end
+
+ def many(sym, &block)
+ _defmetasyntax("many", _intern(sym), block) {|target|
+ seq() { [] }\
+ | seq(target, sym) {|list, x| list.push x; list }
+ }
+ end
+
+ def many1(sym, &block)
+ _defmetasyntax("many1", _intern(sym), block) {|target|
+ seq(sym) {|x| [x] }\
+ | seq(target, sym) {|list, x| list.push x; list }
+ }
+ end
+
+ def separated_by(sep, sym, &block)
+ option(separated_by1(sep, sym), [], &block)
+ end
+
+ def separated_by1(sep, sym, &block)
+ _defmetasyntax("separated_by1", _intern(sym), block) {|target|
+ seq(sym) {|x| [x] }\
+ | seq(target, sep, sym) {|list, _, x| list.push x; list }
+ }
+ end
+
+ def _intern(x)
+ case x
+ when Symbol, String
+ @grammar.intern(x)
+ when Racc::Sym
+ x
+ else
+ raise TypeError, "wrong type #{x.class} (expected Symbol/String/Racc::Sym)"
+ end
+ end
+
+ private
+
+ def _defmetasyntax(type, id, action, &block)
+ if action
+ idbase = "#{type}@#{id}-#{@seqs[type] += 1}"
+ target = _wrap(idbase, "#{idbase}-core", action)
+ _regist("#{idbase}-core", &block)
+ else
+ target = _regist("#{type}@#{id}", &block)
+ end
+ @grammar.intern(target)
+ end
+
+ def _regist(target_name)
+ target = target_name.intern
+ unless _added?(@grammar.intern(target))
+ yield(target).each_rule do |rule|
+ rule.target = @grammar.intern(target)
+ _delayed_add rule
+ end
+ end
+ target
+ end
+
+ def _wrap(target_name, sym, block)
+ target = target_name.intern
+ _delayed_add Rule.new(@grammar.intern(target),
+ [@grammar.intern(sym.intern)],
+ UserAction.proc(block))
+ target
+ end
+ end
+
+ class PrecedenceDefinitionEnv
+ def initialize(g)
+ @grammar = g
+ @prechigh_seen = false
+ @preclow_seen = false
+ @reverse = false
+ end
+
+ attr_reader :reverse
+
+ def higher
+ if @prechigh_seen
+ raise CompileError, "prechigh used twice"
+ end
+ @prechigh_seen = true
+ end
+
+ def lower
+ if @preclow_seen
+ raise CompileError, "preclow used twice"
+ end
+ if @prechigh_seen
+ @reverse = true
+ end
+ @preclow_seen = true
+ end
+
+ def left(*syms)
+ @grammar.declare_precedence :Left, syms.map {|s| @grammar.intern(s) }
+ end
+
+ def right(*syms)
+ @grammar.declare_precedence :Right, syms.map {|s| @grammar.intern(s) }
+ end
+
+ def nonassoc(*syms)
+ @grammar.declare_precedence :Nonassoc, syms.map {|s| @grammar.intern(s)}
+ end
+ end
+
+ #
+ # Computation
+ #
+
+ def init
+ return if @closed
+ @closed = true
+ @start ||= @rules.map {|r| r.target }.detect {|sym| not sym.dummy? }
+ raise CompileError, 'no rule in input' if @rules.empty?
+ add_start_rule
+ @rules.freeze
+ fix_ident
+ compute_hash
+ compute_heads
+ determine_terminals
+ compute_nullable_0
+ @symboltable.fix
+ compute_locate
+ @symboltable.each_nonterminal {|t| compute_expand t }
+ compute_nullable
+ compute_useless
+ end
+
+ private
+
+ def add_start_rule
+ r = Rule.new(@symboltable.dummy,
+ [@start, @symboltable.anchor, @symboltable.anchor],
+ UserAction.empty)
+ r.ident = 0
+ r.hash = 0
+ r.precedence = nil
+ @rules.unshift r
+ end
+
+ # Rule#ident
+ # LocationPointer#ident
+ def fix_ident
+ @rules.each_with_index do |rule, idx|
+ rule.ident = idx
+ end
+ end
+
+ # Rule#hash
+ def compute_hash
+ hash = 4 # size of dummy rule
+ @rules.each do |rule|
+ rule.hash = hash
+ hash += (rule.size + 1)
+ end
+ end
+
+ # Sym#heads
+ def compute_heads
+ @rules.each do |rule|
+ rule.target.heads.push rule.ptrs[0]
+ end
+ end
+
+ # Sym#terminal?
+ def determine_terminals
+ @symboltable.each do |s|
+ s.term = s.heads.empty?
+ end
+ end
+
+ # Sym#self_null?
+ def compute_nullable_0
+ @symboltable.each do |s|
+ if s.terminal?
+ s.snull = false
+ else
+ s.snull = s.heads.any? {|loc| loc.reduce? }
+ end
+ end
+ end
+
+ # Sym#locate
+ def compute_locate
+ @rules.each do |rule|
+ t = nil
+ rule.ptrs.each do |ptr|
+ unless ptr.reduce?
+ tok = ptr.dereference
+ tok.locate.push ptr
+ t = tok if tok.terminal?
+ end
+ end
+ rule.precedence = t
+ end
+ end
+
+ # Sym#expand
+ def compute_expand(t)
+ puts "expand> #{t.to_s}" if @debug_symbol
+ t.expand = _compute_expand(t, ISet.new, [])
+ puts "expand< #{t.to_s}: #{t.expand.to_s}" if @debug_symbol
+ end
+
+ def _compute_expand(t, set, lock)
+ if tmp = t.expand
+ set.update tmp
+ return set
+ end
+ tok = nil
+ set.update_a t.heads
+ t.heads.each do |ptr|
+ tok = ptr.dereference
+ if tok and tok.nonterminal?
+ unless lock[tok.ident]
+ lock[tok.ident] = true
+ _compute_expand tok, set, lock
+ end
+ end
+ end
+ set
+ end
+
+ # Sym#nullable?, Rule#nullable?
+ def compute_nullable
+ @rules.each {|r| r.null = false }
+ @symboltable.each {|t| t.null = false }
+ r = @rules.dup
+ s = @symboltable.nonterminals
+ begin
+ rs = r.size
+ ss = s.size
+ check_rules_nullable r
+ check_symbols_nullable s
+ end until rs == r.size and ss == s.size
+ end
+
+ def check_rules_nullable(rules)
+ rules.delete_if do |rule|
+ rule.null = true
+ rule.symbols.each do |t|
+ unless t.nullable?
+ rule.null = false
+ break
+ end
+ end
+ rule.nullable?
+ end
+ end
+
+ def check_symbols_nullable(symbols)
+ symbols.delete_if do |sym|
+ sym.heads.each do |ptr|
+ if ptr.rule.nullable?
+ sym.null = true
+ break
+ end
+ end
+ sym.nullable?
+ end
+ end
+
+ # Sym#useless?, Rule#useless?
+ # FIXME: what means "useless"?
+ def compute_useless
+ @symboltable.each_terminal {|sym| sym.useless = false }
+ @symboltable.each_nonterminal {|sym| sym.useless = true }
+ @rules.each {|rule| rule.useless = true }
+ r = @rules.dup
+ s = @symboltable.nonterminals
+ begin
+ rs = r.size
+ ss = s.size
+ check_rules_useless r
+ check_symbols_useless s
+ end until r.size == rs and s.size == ss
+ end
+
+ def check_rules_useless(rules)
+ rules.delete_if do |rule|
+ rule.useless = false
+ rule.symbols.each do |sym|
+ if sym.useless?
+ rule.useless = true
+ break
+ end
+ end
+ not rule.useless?
+ end
+ end
+
+ def check_symbols_useless(s)
+ s.delete_if do |t|
+ t.heads.each do |ptr|
+ unless ptr.rule.useless?
+ t.useless = false
+ break
+ end
+ end
+ not t.useless?
+ end
+ end
+
+ end # class Grammar
+
+
+ class Rule
+
+ def initialize(target, syms, act)
+ @target = target
+ @symbols = syms
+ @action = act
+ @alternatives = []
+
+ @ident = nil
+ @hash = nil
+ @ptrs = nil
+ @precedence = nil
+ @specified_prec = nil
+ @null = nil
+ @useless = nil
+ end
+
+ attr_accessor :target
+ attr_reader :symbols
+ attr_reader :action
+
+ def |(x)
+ @alternatives.push x.rule
+ self
+ end
+
+ def rule
+ self
+ end
+
+ def each_rule(&block)
+ yield self
+ @alternatives.each(&block)
+ end
+
+ attr_accessor :ident
+
+ attr_reader :hash
+ attr_reader :ptrs
+
+ def hash=(n)
+ @hash = n
+ ptrs = []
+ @symbols.each_with_index do |sym, idx|
+ ptrs.push LocationPointer.new(self, idx, sym)
+ end
+ ptrs.push LocationPointer.new(self, @symbols.size, nil)
+ @ptrs = ptrs
+ end
+
+ def precedence
+ @specified_prec || @precedence
+ end
+
+ def precedence=(sym)
+ @precedence ||= sym
+ end
+
+ def prec(sym, &block)
+ @specified_prec = sym
+ if block
+ unless @action.empty?
+ raise CompileError, 'both of rule action block and prec block given'
+ end
+ @action = UserAction.proc(block)
+ end
+ self
+ end
+
+ attr_accessor :specified_prec
+
+ def nullable?() @null end
+ def null=(n) @null = n end
+
+ def useless?() @useless end
+ def useless=(u) @useless = u end
+
+ def inspect
+ "#<Racc::Rule id=#{@ident} (#{@target})>"
+ end
+
+ def ==(other)
+ other.kind_of?(Rule) and @ident == other.ident
+ end
+
+ def [](idx)
+ @symbols[idx]
+ end
+
+ def size
+ @symbols.size
+ end
+
+ def empty?
+ @symbols.empty?
+ end
+
+ def to_s
+ "#<rule#{@ident}>"
+ end
+
+ def accept?
+ if tok = @symbols[-1]
+ tok.anchor?
+ else
+ false
+ end
+ end
+
+ def each(&block)
+ @symbols.each(&block)
+ end
+
+ def replace(src, dest)
+ @target = dest
+ @symbols = @symbols.map {|s| s == src ? dest : s }
+ end
+
+ end # class Rule
+
+
+ class UserAction
+
+ def UserAction.source_text(src)
+ new(src, nil)
+ end
+
+ def UserAction.proc(pr = nil, &block)
+ if pr and block
+ raise ArgumentError, "both of argument and block given"
+ end
+ new(nil, pr || block)
+ end
+
+ def UserAction.empty
+ new(nil, nil)
+ end
+
+ private_class_method :new
+
+ def initialize(src, proc)
+ @source = src
+ @proc = proc
+ end
+
+ attr_reader :source
+ attr_reader :proc
+
+ def source?
+ not @proc
+ end
+
+ def proc?
+ not @source
+ end
+
+ def empty?
+ not @proc and not @source
+ end
+
+ def name
+ "{action type=#{@source || @proc || 'nil'}}"
+ end
+
+ alias inspect name
+
+ end
+
+
+ class OrMark
+ def initialize(lineno)
+ @lineno = lineno
+ end
+
+ def name
+ '|'
+ end
+
+ alias inspect name
+
+ attr_reader :lineno
+ end
+
+
+ class Prec
+ def initialize(symbol, lineno)
+ @symbol = symbol
+ @lineno = lineno
+ end
+
+ def name
+ "=#{@symbol}"
+ end
+
+ alias inspect name
+
+ attr_reader :symbol
+ attr_reader :lineno
+ end
+
+
+ #
+ # A set of rule and position in it's RHS.
+ # Note that the number of pointers is more than rule's RHS array,
+ # because pointer points right edge of the final symbol when reducing.
+ #
+ class LocationPointer
+
+ def initialize(rule, i, sym)
+ @rule = rule
+ @index = i
+ @symbol = sym
+ @ident = @rule.hash + i
+ @reduce = sym.nil?
+ end
+
+ attr_reader :rule
+ attr_reader :index
+ attr_reader :symbol
+
+ alias dereference symbol
+
+ attr_reader :ident
+ alias hash ident
+ attr_reader :reduce
+ alias reduce? reduce
+
+ def to_s
+ sprintf('(%d,%d %s)',
+ @rule.ident, @index, (reduce?() ? '#' : @symbol.to_s))
+ end
+
+ alias inspect to_s
+
+ def eql?(ot)
+ @hash == ot.hash
+ end
+
+ alias == eql?
+
+ def head?
+ @index == 0
+ end
+
+ def next
+ @rule.ptrs[@index + 1] or ptr_bug!
+ end
+
+ alias increment next
+
+ def before(len)
+ @rule.ptrs[@index - len] or ptr_bug!
+ end
+
+ private
+
+ def ptr_bug!
+ raise "racc: fatal: pointer not exist: self: #{to_s}"
+ end
+
+ end # class LocationPointer
+
+
+ class SymbolTable
+
+ include Enumerable
+
+ def initialize
+ @symbols = [] # :: [Racc::Sym]
+ @cache = {} # :: {(String|Symbol) => Racc::Sym}
+ @dummy = intern(:$start, true)
+ @anchor = intern(false, true) # Symbol ID = 0
+ @error = intern(:error, false) # Symbol ID = 1
+ end
+
+ attr_reader :dummy
+ attr_reader :anchor
+ attr_reader :error
+
+ def [](id)
+ @symbols[id]
+ end
+
+ def intern(val, dummy = false)
+ @cache[val] ||=
+ begin
+ sym = Sym.new(val, dummy)
+ @symbols.push sym
+ sym
+ end
+ end
+
+ attr_reader :symbols
+ alias to_a symbols
+
+ def delete(sym)
+ @symbols.delete sym
+ @cache.delete sym.value
+ end
+
+ attr_reader :nt_base
+
+ def nt_max
+ @symbols.size
+ end
+
+ def each(&block)
+ @symbols.each(&block)
+ end
+
+ def terminals(&block)
+ @symbols[0, @nt_base]
+ end
+
+ def each_terminal(&block)
+ @terms.each(&block)
+ end
+
+ def nonterminals
+ @symbols[@nt_base, @symbols.size - @nt_base]
+ end
+
+ def each_nonterminal(&block)
+ @nterms.each(&block)
+ end
+
+ def fix
+ terms, nterms = @symbols.partition {|s| s.terminal? }
+ @symbols = terms + nterms
+ @terms = terms
+ @nterms = nterms
+ @nt_base = terms.size
+ fix_ident
+ check_terminals
+ end
+
+ private
+
+ def fix_ident
+ @symbols.each_with_index do |t, i|
+ t.ident = i
+ end
+ end
+
+ def check_terminals
+ return unless @symbols.any? {|s| s.should_terminal? }
+ @anchor.should_terminal
+ @error.should_terminal
+ each_terminal do |t|
+ t.should_terminal if t.string_symbol?
+ end
+ each do |s|
+ s.should_terminal if s.assoc
+ end
+ terminals().reject {|t| t.should_terminal? }.each do |t|
+ raise CompileError, "terminal #{t} not declared as terminal"
+ end
+ nonterminals().select {|n| n.should_terminal? }.each do |n|
+ raise CompileError, "symbol #{n} declared as terminal but is not terminal"
+ end
+ end
+
+ end # class SymbolTable
+
+
+ # Stands terminal and nonterminal symbols.
+ class Sym
+
+ def initialize(value, dummyp)
+ @ident = nil
+ @value = value
+ @dummyp = dummyp
+
+ @term = nil
+ @nterm = nil
+ @should_terminal = false
+ @precedence = nil
+ case value
+ when Symbol
+ @to_s = value.to_s
+ @serialized = value.inspect
+ @string = false
+ when String
+ @to_s = value.inspect
+ @serialized = value.dump
+ @string = true
+ when false
+ @to_s = '$end'
+ @serialized = 'false'
+ @string = false
+ when ErrorSymbolValue
+ @to_s = 'error'
+ @serialized = 'Object.new'
+ @string = false
+ else
+ raise ArgumentError, "unknown symbol value: #{value.class}"
+ end
+
+ @heads = []
+ @locate = []
+ @snull = nil
+ @null = nil
+ @expand = nil
+ @useless = nil
+ end
+
+ class << self
+ def once_writer(nm)
+ nm = nm.id2name
+ module_eval(<<-EOS)
+ def #{nm}=(v)
+ raise 'racc: fatal: @#{nm} != nil' unless @#{nm}.nil?
+ @#{nm} = v
+ end
+ EOS
+ end
+ end
+
+ once_writer :ident
+ attr_reader :ident
+
+ alias hash ident
+
+ attr_reader :value
+
+ def dummy?
+ @dummyp
+ end
+
+ def terminal?
+ @term
+ end
+
+ def nonterminal?
+ @nterm
+ end
+
+ def term=(t)
+ raise 'racc: fatal: term= called twice' unless @term.nil?
+ @term = t
+ @nterm = !t
+ end
+
+ def should_terminal
+ @should_terminal = true
+ end
+
+ def should_terminal?
+ @should_terminal
+ end
+
+ def string_symbol?
+ @string
+ end
+
+ def serialize
+ @serialized
+ end
+
+ attr_writer :serialized
+
+ attr_accessor :precedence
+ attr_accessor :assoc
+
+ def to_s
+ @to_s.dup
+ end
+
+ alias inspect to_s
+
+ def |(x)
+ rule() | x.rule
+ end
+
+ def rule
+ Rule.new(nil, [self], UserAction.empty)
+ end
+
+ #
+ # cache
+ #
+
+ attr_reader :heads
+ attr_reader :locate
+
+ def self_null?
+ @snull
+ end
+
+ once_writer :snull
+
+ def nullable?
+ @null
+ end
+
+ def null=(n)
+ @null = n
+ end
+
+ attr_reader :expand
+ once_writer :expand
+
+ def useless?
+ @useless
+ end
+
+ def useless=(f)
+ @useless = f
+ end
+
+ end # class Sym
+
+end # module Racc
diff --git a/lib/racc/grammarfileparser.rb b/lib/racc/grammarfileparser.rb
new file mode 100644
index 0000000000..419495113b
--- /dev/null
+++ b/lib/racc/grammarfileparser.rb
@@ -0,0 +1,561 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc'
+require 'racc/compat'
+require 'racc/grammar'
+require 'racc/parserfilegenerator'
+require 'racc/sourcetext'
+require 'stringio'
+
+module Racc
+
+ grammar = Grammar.define {
+ g = self
+
+ g.class = seq(:CLASS, :cname, many(:param), :RULE, :rules, option(:END))
+
+ g.cname = seq(:rubyconst) {|name|
+ @result.params.classname = name
+ }\
+ | seq(:rubyconst, "<", :rubyconst) {|c, _, s|
+ @result.params.classname = c
+ @result.params.superclass = s
+ }
+
+ g.rubyconst = separated_by1(:colon2, :SYMBOL) {|syms|
+ syms.map {|s| s.to_s }.join('::')
+ }
+
+ g.colon2 = seq(':', ':')
+
+ g.param = seq(:CONV, many1(:convdef), :END) {|*|
+ #@grammar.end_convert_block # FIXME
+ }\
+ | seq(:PRECHIGH, many1(:precdef), :PRECLOW) {|*|
+ @grammar.end_precedence_declaration true
+ }\
+ | seq(:PRECLOW, many1(:precdef), :PRECHIGH) {|*|
+ @grammar.end_precedence_declaration false
+ }\
+ | seq(:START, :symbol) {|_, sym|
+ @grammar.start_symbol = sym
+ }\
+ | seq(:TOKEN, :symbols) {|_, syms|
+ syms.each do |s|
+ s.should_terminal
+ end
+ }\
+ | seq(:OPTION, :options) {|_, syms|
+ syms.each do |opt|
+ case opt
+ when 'result_var'
+ @result.params.result_var = true
+ when 'no_result_var'
+ @result.params.result_var = false
+ when 'omit_action_call'
+ @result.params.omit_action_call = true
+ when 'no_omit_action_call'
+ @result.params.omit_action_call = false
+ else
+ raise CompileError, "unknown option: #{opt}"
+ end
+ end
+ }\
+ | seq(:EXPECT, :DIGIT) {|_, num|
+ if @grammar.n_expected_srconflicts
+ raise CompileError, "`expect' seen twice"
+ end
+ @grammar.n_expected_srconflicts = num
+ }
+
+ g.convdef = seq(:symbol, :STRING) {|sym, code|
+ sym.serialized = code
+ }
+
+ g.precdef = seq(:LEFT, :symbols) {|_, syms|
+ @grammar.declare_precedence :Left, syms
+ }\
+ | seq(:RIGHT, :symbols) {|_, syms|
+ @grammar.declare_precedence :Right, syms
+ }\
+ | seq(:NONASSOC, :symbols) {|_, syms|
+ @grammar.declare_precedence :Nonassoc, syms
+ }
+
+ g.symbols = seq(:symbol) {|sym|
+ [sym]
+ }\
+ | seq(:symbols, :symbol) {|list, sym|
+ list.push sym
+ list
+ }\
+ | seq(:symbols, "|")
+
+ g.symbol = seq(:SYMBOL) {|sym| @grammar.intern(sym) }\
+ | seq(:STRING) {|str| @grammar.intern(str) }
+
+ g.options = many(:SYMBOL) {|syms| syms.map {|s| s.to_s } }
+
+ g.rules = option(:rules_core) {|list|
+ add_rule_block list unless list.empty?
+ nil
+ }
+
+ g.rules_core = seq(:symbol) {|sym|
+ [sym]
+ }\
+ | seq(:rules_core, :rule_item) {|list, i|
+ list.push i
+ list
+ }\
+ | seq(:rules_core, ';') {|list, *|
+ add_rule_block list unless list.empty?
+ list.clear
+ list
+ }\
+ | seq(:rules_core, ':') {|list, *|
+ next_target = list.pop
+ add_rule_block list unless list.empty?
+ [next_target]
+ }
+
+ g.rule_item = seq(:symbol)\
+ | seq("|") {|*|
+ OrMark.new(@scanner.lineno)
+ }\
+ | seq("=", :symbol) {|_, sym|
+ Prec.new(sym, @scanner.lineno)
+ }\
+ | seq(:ACTION) {|src|
+ UserAction.source_text(src)
+ }
+ }
+
+ GrammarFileParser = grammar.parser_class
+
+ if grammar.states.srconflict_exist?
+ raise 'Racc boot script fatal: S/R conflict in build'
+ end
+ if grammar.states.rrconflict_exist?
+ raise 'Racc boot script fatal: R/R conflict in build'
+ end
+
+ class GrammarFileParser # reopen
+
+ class Result
+ def initialize(grammar)
+ @grammar = grammar
+ @params = ParserFileGenerator::Params.new
+ end
+
+ attr_reader :grammar
+ attr_reader :params
+ end
+
+ def GrammarFileParser.parse_file(filename)
+ parse(File.read(filename), filename, 1)
+ end
+
+ def GrammarFileParser.parse(src, filename = '-', lineno = 1)
+ new().parse(src, filename, lineno)
+ end
+
+ def initialize(debug_flags = DebugFlags.new)
+ @yydebug = debug_flags.parse
+ end
+
+ def parse(src, filename = '-', lineno = 1)
+ @filename = filename
+ @lineno = lineno
+ @scanner = GrammarFileScanner.new(src, @filename)
+ @scanner.debug = @yydebug
+ @grammar = Grammar.new
+ @result = Result.new(@grammar)
+ @embedded_action_seq = 0
+ yyparse @scanner, :yylex
+ parse_user_code
+ @result.grammar.init
+ @result
+ end
+
+ private
+
+ def next_token
+ @scanner.scan
+ end
+
+ def on_error(tok, val, _values)
+ if val.respond_to?(:id2name)
+ v = val.id2name
+ elsif val.kind_of?(String)
+ v = val
+ else
+ v = val.inspect
+ end
+ raise CompileError, "#{location()}: unexpected token '#{v}'"
+ end
+
+ def location
+ "#{@filename}:#{@lineno - 1 + @scanner.lineno}"
+ end
+
+ def add_rule_block(list)
+ sprec = nil
+ target = list.shift
+ case target
+ when OrMark, UserAction, Prec
+ raise CompileError, "#{target.lineno}: unexpected symbol #{target.name}"
+ end
+ curr = []
+ list.each do |i|
+ case i
+ when OrMark
+ add_rule target, curr, sprec
+ curr = []
+ sprec = nil
+ when Prec
+ raise CompileError, "'=<prec>' used twice in one rule" if sprec
+ sprec = i.symbol
+ else
+ curr.push i
+ end
+ end
+ add_rule target, curr, sprec
+ end
+
+ def add_rule(target, list, sprec)
+ if list.last.kind_of?(UserAction)
+ act = list.pop
+ else
+ act = UserAction.empty
+ end
+ list.map! {|s| s.kind_of?(UserAction) ? embedded_action(s) : s }
+ rule = Rule.new(target, list, act)
+ rule.specified_prec = sprec
+ @grammar.add rule
+ end
+
+ def embedded_action(act)
+ sym = @grammar.intern("@#{@embedded_action_seq += 1}".intern, true)
+ @grammar.add Rule.new(sym, [], act)
+ sym
+ end
+
+ #
+ # User Code Block
+ #
+
+ def parse_user_code
+ line = @scanner.lineno
+ _, *blocks = *@scanner.epilogue.split(/^----/)
+ blocks.each do |block|
+ header, *body = block.lines.to_a
+ label0, pathes = *header.sub(/\A-+/, '').split('=', 2)
+ label = canonical_label(label0)
+ (pathes ? pathes.strip.split(' ') : []).each do |path|
+ add_user_code label, SourceText.new(File.read(path), path, 1)
+ end
+ add_user_code label, SourceText.new(body.join(''), @filename, line + 1)
+ line += (1 + body.size)
+ end
+ end
+
+ USER_CODE_LABELS = {
+ 'header' => :header,
+ 'prepare' => :header, # obsolete
+ 'inner' => :inner,
+ 'footer' => :footer,
+ 'driver' => :footer # obsolete
+ }
+
+ def canonical_label(src)
+ label = src.to_s.strip.downcase.slice(/\w+/)
+ unless USER_CODE_LABELS.key?(label)
+ raise CompileError, "unknown user code type: #{label.inspect}"
+ end
+ label
+ end
+
+ def add_user_code(label, src)
+ @result.params.public_send(USER_CODE_LABELS[label]).push src
+ end
+
+ end
+
+
+ class GrammarFileScanner
+
+ def initialize(str, filename = '-')
+ @lines = str.b.split(/\n|\r\n|\r/)
+ @filename = filename
+ @lineno = -1
+ @line_head = true
+ @in_rule_blk = false
+ @in_conv_blk = false
+ @in_block = nil
+ @epilogue = ''
+ @debug = false
+ next_line
+ end
+
+ attr_reader :epilogue
+
+ def lineno
+ @lineno + 1
+ end
+
+ attr_accessor :debug
+
+ def yylex(&block)
+ unless @debug
+ yylex0(&block)
+ else
+ yylex0 do |sym, tok|
+ $stderr.printf "%7d %-10s %s\n", lineno(), sym.inspect, tok.inspect
+ yield [sym, tok]
+ end
+ end
+ end
+
+ private
+
+ def yylex0
+ begin
+ until @line.empty?
+ @line.sub!(/\A\s+/, '')
+ if /\A\#/ =~ @line
+ break
+ elsif /\A\/\*/ =~ @line
+ skip_comment
+ elsif s = reads(/\A[a-zA-Z_]\w*/)
+ yield [atom_symbol(s), s.intern]
+ elsif s = reads(/\A\d+/)
+ yield [:DIGIT, s.to_i]
+ elsif ch = reads(/\A./)
+ case ch
+ when '"', "'"
+ yield [:STRING, eval(scan_quoted(ch))]
+ when '{'
+ lineno = lineno()
+ yield [:ACTION, SourceText.new(scan_action(), @filename, lineno)]
+ else
+ if ch == '|'
+ @line_head = false
+ end
+ yield [ch, ch]
+ end
+ else
+ end
+ end
+ end while next_line()
+ yield nil
+ end
+
+ def next_line
+ @lineno += 1
+ @line = @lines[@lineno]
+ if not @line or /\A----/ =~ @line
+ @epilogue = @lines.join("\n")
+ @lines.clear
+ @line = nil
+ if @in_block
+ @lineno -= 1
+ scan_error! sprintf('unterminated %s', @in_block)
+ end
+ false
+ else
+ @line.sub!(/(?:\n|\r\n|\r)\z/, '')
+ @line_head = true
+ true
+ end
+ end
+
+ ReservedWord = {
+ 'right' => :RIGHT,
+ 'left' => :LEFT,
+ 'nonassoc' => :NONASSOC,
+ 'preclow' => :PRECLOW,
+ 'prechigh' => :PRECHIGH,
+ 'token' => :TOKEN,
+ 'convert' => :CONV,
+ 'options' => :OPTION,
+ 'start' => :START,
+ 'expect' => :EXPECT,
+ 'class' => :CLASS,
+ 'rule' => :RULE,
+ 'end' => :END
+ }
+
+ def atom_symbol(token)
+ if token == 'end'
+ symbol = :END
+ @in_conv_blk = false
+ @in_rule_blk = false
+ else
+ if @line_head and not @in_conv_blk and not @in_rule_blk
+ symbol = ReservedWord[token] || :SYMBOL
+ else
+ symbol = :SYMBOL
+ end
+ case symbol
+ when :RULE then @in_rule_blk = true
+ when :CONV then @in_conv_blk = true
+ end
+ end
+ @line_head = false
+ symbol
+ end
+
+ def skip_comment
+ @in_block = 'comment'
+ until m = /\*\//.match(@line)
+ next_line
+ end
+ @line = m.post_match
+ @in_block = nil
+ end
+
+ $raccs_print_type = false
+
+ def scan_action
+ buf = String.new
+ nest = 1
+ pre = nil
+ @in_block = 'action'
+ begin
+ pre = nil
+ if s = reads(/\A\s+/)
+ # does not set 'pre'
+ buf << s
+ end
+ until @line.empty?
+ if s = reads(/\A[^'"`{}%#\/\$]+/)
+ buf << (pre = s)
+ next
+ end
+ case ch = read(1)
+ when '{'
+ nest += 1
+ buf << (pre = ch)
+ when '}'
+ nest -= 1
+ if nest == 0
+ @in_block = nil
+ buf.sub!(/[ \t\f]+\z/, '')
+ return buf
+ end
+ buf << (pre = ch)
+ when '#' # comment
+ buf << ch << @line
+ break
+ when "'", '"', '`'
+ buf << (pre = scan_quoted(ch))
+ when '%'
+ if literal_head? pre, @line
+ # % string, regexp, array
+ buf << ch
+ case ch = read(1)
+ when /[qQx]/n
+ buf << ch << (pre = scan_quoted(read(1), '%string'))
+ when /wW/n
+ buf << ch << (pre = scan_quoted(read(1), '%array'))
+ when /s/n
+ buf << ch << (pre = scan_quoted(read(1), '%symbol'))
+ when /r/n
+ buf << ch << (pre = scan_quoted(read(1), '%regexp'))
+ when /[a-zA-Z0-9= ]/n # does not include "_"
+ scan_error! "unknown type of % literal '%#{ch}'"
+ else
+ buf << (pre = scan_quoted(ch, '%string'))
+ end
+ else
+ # operator
+ buf << '||op->' if $raccs_print_type
+ buf << (pre = ch)
+ end
+ when '/'
+ if literal_head? pre, @line
+ # regexp
+ buf << (pre = scan_quoted(ch, 'regexp'))
+ else
+ # operator
+ buf << '||op->' if $raccs_print_type
+ buf << (pre = ch)
+ end
+ when '$' # gvar
+ buf << ch << (pre = read(1))
+ else
+ raise 'racc: fatal: must not happen'
+ end
+ end
+ buf << "\n"
+ end while next_line()
+ raise 'racc: fatal: scan finished before parser finished'
+ end
+
+ def literal_head?(pre, post)
+ (!pre || /[a-zA-Z_0-9]/n !~ pre[-1,1]) &&
+ !post.empty? && /\A[\s\=]/n !~ post
+ end
+
+ def read(len)
+ s = @line[0, len]
+ @line = @line[len .. -1]
+ s
+ end
+
+ def reads(re)
+ m = re.match(@line) or return nil
+ @line = m.post_match
+ m[0]
+ end
+
+ def scan_quoted(left, tag = 'string')
+ buf = left.dup
+ buf = "||#{tag}->" + buf if $raccs_print_type
+ re = get_quoted_re(left)
+ sv, @in_block = @in_block, tag
+ begin
+ if s = reads(re)
+ buf << s
+ break
+ else
+ buf << @line
+ end
+ end while next_line()
+ @in_block = sv
+ buf << "<-#{tag}||" if $raccs_print_type
+ buf
+ end
+
+ LEFT_TO_RIGHT = {
+ '(' => ')',
+ '{' => '}',
+ '[' => ']',
+ '<' => '>'
+ }
+
+ CACHE = {}
+
+ def get_quoted_re(left)
+ term = Regexp.quote(LEFT_TO_RIGHT[left] || left)
+ CACHE[left] ||= /\A[^#{term}\\]*(?:\\.[^\\#{term}]*)*#{term}/
+ end
+
+ def scan_error!(msg)
+ raise CompileError, "#{lineno()}: #{msg}"
+ end
+
+ end
+
+end # module Racc
diff --git a/lib/racc/info.rb b/lib/racc/info.rb
new file mode 100644
index 0000000000..f599b13cbb
--- /dev/null
+++ b/lib/racc/info.rb
@@ -0,0 +1,17 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+ VERSION = '1.5.2'
+ Version = VERSION
+ Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
+end
diff --git a/lib/racc/iset.rb b/lib/racc/iset.rb
new file mode 100644
index 0000000000..339221d21b
--- /dev/null
+++ b/lib/racc/iset.rb
@@ -0,0 +1,92 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ # An "indexed" set. All items must respond to :ident.
+ class ISet
+
+ def initialize(a = [])
+ @set = a
+ end
+
+ attr_reader :set
+
+ def add(i)
+ @set[i.ident] = i
+ end
+
+ def [](key)
+ @set[key.ident]
+ end
+
+ def []=(key, val)
+ @set[key.ident] = val
+ end
+
+ alias include? []
+ alias key? []
+
+ def update(other)
+ s = @set
+ o = other.set
+ o.each_index do |idx|
+ if t = o[idx]
+ s[idx] = t
+ end
+ end
+ end
+
+ def update_a(a)
+ s = @set
+ a.each {|i| s[i.ident] = i }
+ end
+
+ def delete(key)
+ i = @set[key.ident]
+ @set[key.ident] = nil
+ i
+ end
+
+ def each(&block)
+ @set.compact.each(&block)
+ end
+
+ def to_a
+ @set.compact
+ end
+
+ def to_s
+ "[#{@set.compact.join(' ')}]"
+ end
+
+ alias inspect to_s
+
+ def size
+ @set.nitems
+ end
+
+ def empty?
+ @set.nitems == 0
+ end
+
+ def clear
+ @set.clear
+ end
+
+ def dup
+ ISet.new(@set.dup)
+ end
+
+ end # class ISet
+
+end # module Racc
diff --git a/lib/racc/logfilegenerator.rb b/lib/racc/logfilegenerator.rb
new file mode 100644
index 0000000000..2f5aa0c8b0
--- /dev/null
+++ b/lib/racc/logfilegenerator.rb
@@ -0,0 +1,212 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ class LogFileGenerator
+
+ def initialize(states, debug_flags = DebugFlags.new)
+ @states = states
+ @grammar = states.grammar
+ @debug_flags = debug_flags
+ end
+
+ def output(out)
+ output_conflict out; out.puts
+ output_useless out; out.puts
+ output_rule out; out.puts
+ output_token out; out.puts
+ output_state out
+ end
+
+ #
+ # Warnings
+ #
+
+ def output_conflict(out)
+ @states.each do |state|
+ if state.srconf
+ out.printf "state %d contains %d shift/reduce conflicts\n",
+ state.stateid, state.srconf.size
+ end
+ if state.rrconf
+ out.printf "state %d contains %d reduce/reduce conflicts\n",
+ state.stateid, state.rrconf.size
+ end
+ end
+ end
+
+ def output_useless(out)
+ @grammar.each do |rl|
+ if rl.useless?
+ out.printf "rule %d (%s) never reduced\n",
+ rl.ident, rl.target.to_s
+ end
+ end
+ @grammar.each_nonterminal do |t|
+ if t.useless?
+ out.printf "useless nonterminal %s\n", t.to_s
+ end
+ end
+ end
+
+ #
+ # States
+ #
+
+ def output_state(out)
+ out << "--------- State ---------\n"
+
+ showall = @debug_flags.la || @debug_flags.state
+ @states.each do |state|
+ out << "\nstate #{state.ident}\n\n"
+
+ (showall ? state.closure : state.core).each do |ptr|
+ pointer_out(out, ptr) if ptr.rule.ident != 0 or showall
+ end
+ out << "\n"
+
+ action_out out, state
+ end
+ end
+
+ def pointer_out(out, ptr)
+ buf = sprintf("%4d) %s :", ptr.rule.ident, ptr.rule.target.to_s)
+ ptr.rule.symbols.each_with_index do |tok, idx|
+ buf << ' _' if idx == ptr.index
+ buf << ' ' << tok.to_s
+ end
+ buf << ' _' if ptr.reduce?
+ out.puts buf
+ end
+
+ def action_out(f, state)
+ sr = state.srconf && state.srconf.dup
+ rr = state.rrconf && state.rrconf.dup
+ acts = state.action
+ keys = acts.keys
+ keys.sort! {|a,b| a.ident <=> b.ident }
+
+ [ Shift, Reduce, Error, Accept ].each do |klass|
+ keys.delete_if do |tok|
+ act = acts[tok]
+ if act.kind_of?(klass)
+ outact f, tok, act
+ if sr and c = sr.delete(tok)
+ outsrconf f, c
+ end
+ if rr and c = rr.delete(tok)
+ outrrconf f, c
+ end
+
+ true
+ else
+ false
+ end
+ end
+ end
+ sr.each {|tok, c| outsrconf f, c } if sr
+ rr.each {|tok, c| outrrconf f, c } if rr
+
+ act = state.defact
+ if not act.kind_of?(Error) or @debug_flags.any?
+ outact f, '$default', act
+ end
+
+ f.puts
+ state.goto_table.each do |t, st|
+ if t.nonterminal?
+ f.printf " %-12s go to state %d\n", t.to_s, st.ident
+ end
+ end
+ end
+
+ def outact(f, t, act)
+ case act
+ when Shift
+ f.printf " %-12s shift, and go to state %d\n",
+ t.to_s, act.goto_id
+ when Reduce
+ f.printf " %-12s reduce using rule %d (%s)\n",
+ t.to_s, act.ruleid, act.rule.target.to_s
+ when Accept
+ f.printf " %-12s accept\n", t.to_s
+ when Error
+ f.printf " %-12s error\n", t.to_s
+ else
+ raise "racc: fatal: wrong act for outact: act=#{act}(#{act.class})"
+ end
+ end
+
+ def outsrconf(f, confs)
+ confs.each do |c|
+ r = c.reduce
+ f.printf " %-12s [reduce using rule %d (%s)]\n",
+ c.shift.to_s, r.ident, r.target.to_s
+ end
+ end
+
+ def outrrconf(f, confs)
+ confs.each do |c|
+ r = c.low_prec
+ f.printf " %-12s [reduce using rule %d (%s)]\n",
+ c.token.to_s, r.ident, r.target.to_s
+ end
+ end
+
+ #
+ # Rules
+ #
+
+ def output_rule(out)
+ out.print "-------- Grammar --------\n\n"
+ @grammar.each do |rl|
+ if @debug_flags.any? or rl.ident != 0
+ out.printf "rule %d %s: %s\n",
+ rl.ident, rl.target.to_s, rl.symbols.join(' ')
+ end
+ end
+ end
+
+ #
+ # Tokens
+ #
+
+ def output_token(out)
+ out.print "------- Symbols -------\n\n"
+
+ out.print "**Nonterminals, with rules where they appear\n\n"
+ @grammar.each_nonterminal do |t|
+ tmp = <<SRC
+ %s (%d)
+ on right: %s
+ on left : %s
+SRC
+ out.printf tmp, t.to_s, t.ident,
+ symbol_locations(t.locate).join(' '),
+ symbol_locations(t.heads).join(' ')
+ end
+
+ out.print "\n**Terminals, with rules where they appear\n\n"
+ @grammar.each_terminal do |t|
+ out.printf " %s (%d) %s\n",
+ t.to_s, t.ident, symbol_locations(t.locate).join(' ')
+ end
+ end
+
+ def symbol_locations(locs)
+ locs.map {|loc| loc.rule.ident }.reject {|n| n == 0 }.uniq
+ end
+
+ end
+
+end # module Racc
diff --git a/lib/racc/parser-text.rb b/lib/racc/parser-text.rb
new file mode 100644
index 0000000000..7090c6a01a
--- /dev/null
+++ b/lib/racc/parser-text.rb
@@ -0,0 +1,637 @@
+module Racc
+ PARSER_TEXT = <<'__end_of_file__'
+# frozen_string_literal: false
+#--
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+#
+# As a special exception, when this code is copied by Racc
+# into a Racc output file, you may use that output file
+# without restriction.
+#++
+
+require 'racc/info'
+
+unless defined?(NotImplementedError)
+ NotImplementedError = NotImplementError # :nodoc:
+end
+
+module Racc
+ class ParseError < StandardError; end
+end
+unless defined?(::ParseError)
+ ParseError = Racc::ParseError
+end
+
+# Racc is a LALR(1) parser generator.
+# It is written in Ruby itself, and generates Ruby programs.
+#
+# == Command-line Reference
+#
+# racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
+# [-e<var>rubypath</var>] [--executable=<var>rubypath</var>]
+# [-v] [--verbose]
+# [-O<var>filename</var>] [--log-file=<var>filename</var>]
+# [-g] [--debug]
+# [-E] [--embedded]
+# [-l] [--no-line-convert]
+# [-c] [--line-convert-all]
+# [-a] [--no-omit-actions]
+# [-C] [--check-only]
+# [-S] [--output-status]
+# [--version] [--copyright] [--help] <var>grammarfile</var>
+#
+# [+grammarfile+]
+# Racc grammar file. Any extension is permitted.
+# [-o+outfile+, --output-file=+outfile+]
+# A filename for output. default is <+filename+>.tab.rb
+# [-O+filename+, --log-file=+filename+]
+# Place logging output in file +filename+.
+# Default log file name is <+filename+>.output.
+# [-e+rubypath+, --executable=+rubypath+]
+# output executable file(mode 755). where +path+ is the Ruby interpreter.
+# [-v, --verbose]
+# verbose mode. create +filename+.output file, like yacc's y.output file.
+# [-g, --debug]
+# add debug code to parser class. To display debuggin information,
+# use this '-g' option and set @yydebug true in parser class.
+# [-E, --embedded]
+# Output parser which doesn't need runtime files (racc/parser.rb).
+# [-C, --check-only]
+# Check syntax of racc grammar file and quit.
+# [-S, --output-status]
+# Print messages time to time while compiling.
+# [-l, --no-line-convert]
+# turns off line number converting.
+# [-c, --line-convert-all]
+# Convert line number of actions, inner, header and footer.
+# [-a, --no-omit-actions]
+# Call all actions, even if an action is empty.
+# [--version]
+# print Racc version and quit.
+# [--copyright]
+# Print copyright and quit.
+# [--help]
+# Print usage and quit.
+#
+# == Generating Parser Using Racc
+#
+# To compile Racc grammar file, simply type:
+#
+# $ racc parse.y
+#
+# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
+#
+# == Writing A Racc Grammar File
+#
+# If you want your own parser, you have to write a grammar file.
+# A grammar file contains the name of your parser class, grammar for the parser,
+# user code, and anything else.
+# When writing a grammar file, yacc's knowledge is helpful.
+# If you have not used yacc before, Racc is not too difficult.
+#
+# Here's an example Racc grammar file.
+#
+# class Calcparser
+# rule
+# target: exp { print val[0] }
+#
+# exp: exp '+' exp
+# | exp '*' exp
+# | '(' exp ')'
+# | NUMBER
+# end
+#
+# Racc grammar files resemble yacc files.
+# But (of course), this is Ruby code.
+# yacc's $$ is the 'result', $0, $1... is
+# an array called 'val', and $-1, $-2... is an array called '_values'.
+#
+# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
+# more information on grammar files.
+#
+# == Parser
+#
+# Then you must prepare the parse entry method. There are two types of
+# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
+#
+# Racc::Parser#do_parse is simple.
+#
+# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
+# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
+# EOF is [false, false].
+# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
+# If you want to change this, see the grammar reference.
+#
+# Racc::Parser#yyparse is little complicated, but useful.
+# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
+#
+# For example, <code>yyparse(obj, :scan)</code> causes
+# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
+#
+# == Debugging
+#
+# When debugging, "-v" or/and the "-g" option is helpful.
+#
+# "-v" creates verbose log file (.output).
+# "-g" creates a "Verbose Parser".
+# Verbose Parser prints the internal status when parsing.
+# But it's _not_ automatic.
+# You must use -g option and set +@yydebug+ to +true+ in order to get output.
+# -g option only creates the verbose parser.
+#
+# === Racc reported syntax error.
+#
+# Isn't there too many "end"?
+# grammar of racc file is changed in v0.10.
+#
+# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
+#
+# === Racc reported "XXXX conflicts".
+#
+# Try "racc -v xxxx.y".
+# It causes producing racc's internal log file, xxxx.output.
+#
+# === Generated parsers does not work correctly
+#
+# Try "racc -g xxxx.y".
+# This command let racc generate "debugging parser".
+# Then set @yydebug=true in your parser.
+# It produces a working log of your parser.
+#
+# == Re-distributing Racc runtime
+#
+# A parser, which is created by Racc, requires the Racc runtime module;
+# racc/parser.rb.
+#
+# Ruby 1.8.x comes with Racc runtime module,
+# you need NOT distribute Racc runtime files.
+#
+# If you want to include the Racc runtime module with your parser.
+# This can be done by using '-E' option:
+#
+# $ racc -E -omyparser.rb myparser.y
+#
+# This command creates myparser.rb which `includes' Racc runtime.
+# Only you must do is to distribute your parser file (myparser.rb).
+#
+# Note: parser.rb is ruby license, but your parser is not.
+# Your own parser is completely yours.
+module Racc
+
+ unless defined?(Racc_No_Extensions)
+ Racc_No_Extensions = false # :nodoc:
+ end
+
+ class Parser
+
+ Racc_Runtime_Version = ::Racc::VERSION
+ Racc_Runtime_Core_Version_R = ::Racc::VERSION
+
+ begin
+ if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
+ require 'jruby'
+ require 'racc/cparse-jruby.jar'
+ com.headius.racc.Cparse.new.load(JRuby.runtime, false)
+ else
+ require 'racc/cparse'
+ end
+
+ unless new.respond_to?(:_racc_do_parse_c, true)
+ raise LoadError, 'old cparse.so'
+ end
+ if Racc_No_Extensions
+ raise LoadError, 'selecting ruby version of racc runtime core'
+ end
+
+ Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:
+ Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:
+ Racc_Runtime_Type = 'c' # :nodoc:
+ rescue LoadError
+ Racc_Main_Parsing_Routine = :_racc_do_parse_rb
+ Racc_YY_Parse_Method = :_racc_yyparse_rb
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
+ Racc_Runtime_Type = 'ruby'
+ end
+
+ def Parser.racc_runtime_type # :nodoc:
+ Racc_Runtime_Type
+ end
+
+ def _racc_setup
+ @yydebug = false unless self.class::Racc_debug_parser
+ @yydebug = false unless defined?(@yydebug)
+ if @yydebug
+ @racc_debug_out = $stderr unless defined?(@racc_debug_out)
+ @racc_debug_out ||= $stderr
+ end
+ arg = self.class::Racc_arg
+ arg[13] = true if arg.size < 14
+ arg
+ end
+
+ def _racc_init_sysvars
+ @racc_state = [0]
+ @racc_tstack = []
+ @racc_vstack = []
+
+ @racc_t = nil
+ @racc_val = nil
+
+ @racc_read_next = true
+
+ @racc_user_yyerror = false
+ @racc_error_status = 0
+ end
+
+ # The entry point of the parser. This method is used with #next_token.
+ # If Racc wants to get token (and its value), calls next_token.
+ #
+ # Example:
+ # def parse
+ # @q = [[1,1],
+ # [2,2],
+ # [3,3],
+ # [false, '$']]
+ # do_parse
+ # end
+ #
+ # def next_token
+ # @q.shift
+ # end
+ class_eval %{
+ def do_parse
+ #{Racc_Main_Parsing_Routine}(_racc_setup(), false)
+ end
+ }
+
+ # The method to fetch next token.
+ # If you use #do_parse method, you must implement #next_token.
+ #
+ # The format of return value is [TOKEN_SYMBOL, VALUE].
+ # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
+ # for 'IDENT'. ";" (String) for ';'.
+ #
+ # The final symbol (End of file) must be false.
+ def next_token
+ raise NotImplementedError, "#{self.class}\#next_token is not defined"
+ end
+
+ def _racc_do_parse_rb(arg, in_debug)
+ action_table, action_check, action_default, action_pointer,
+ _, _, _, _,
+ _, _, token_table, * = arg
+
+ _racc_init_sysvars
+ tok = act = i = nil
+
+ catch(:racc_end_parse) {
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ if @racc_read_next
+ if @racc_t != 0 # not EOF
+ tok, @racc_val = next_token()
+ unless tok # EOF
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ racc_read_token(@racc_t, tok, @racc_val) if @yydebug
+ @racc_read_next = false
+ end
+ end
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ else
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ }
+ end
+
+ # Another entry point for the parser.
+ # If you use this method, you must implement RECEIVER#METHOD_ID method.
+ #
+ # RECEIVER#METHOD_ID is a method to get next token.
+ # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
+ class_eval %{
+ def yyparse(recv, mid)
+ #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)
+ end
+ }
+
+ def _racc_yyparse_rb(recv, mid, arg, c_debug)
+ action_table, action_check, action_default, action_pointer,
+ _, _, _, _,
+ _, _, token_table, * = arg
+
+ _racc_init_sysvars
+
+ catch(:racc_end_parse) {
+ until i = action_pointer[@racc_state[-1]]
+ while act = _racc_evalact(action_default[@racc_state[-1]], arg)
+ ;
+ end
+ end
+ recv.__send__(mid) do |tok, val|
+ unless tok
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ @racc_val = val
+ @racc_read_next = false
+
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+
+ while !(i = action_pointer[@racc_state[-1]]) ||
+ ! @racc_read_next ||
+ @racc_t == 0 # $
+ unless i and i += @racc_t and
+ i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ end
+ }
+ end
+
+ ###
+ ### common
+ ###
+
+ def _racc_evalact(act, arg)
+ action_table, action_check, _, action_pointer,
+ _, _, _, _,
+ _, _, _, shift_n,
+ reduce_n, * = arg
+ nerr = 0 # tmp
+
+ if act > 0 and act < shift_n
+ #
+ # shift
+ #
+ if @racc_error_status > 0
+ @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
+ end
+ @racc_vstack.push @racc_val
+ @racc_state.push act
+ @racc_read_next = true
+ if @yydebug
+ @racc_tstack.push @racc_t
+ racc_shift @racc_t, @racc_tstack, @racc_vstack
+ end
+
+ elsif act < 0 and act > -reduce_n
+ #
+ # reduce
+ #
+ code = catch(:racc_jump) {
+ @racc_state.push _racc_do_reduce(arg, act)
+ false
+ }
+ if code
+ case code
+ when 1 # yyerror
+ @racc_user_yyerror = true # user_yyerror
+ return -reduce_n
+ when 2 # yyaccept
+ return shift_n
+ else
+ raise '[Racc Bug] unknown jump code'
+ end
+ end
+
+ elsif act == shift_n
+ #
+ # accept
+ #
+ racc_accept if @yydebug
+ throw :racc_end_parse, @racc_vstack[0]
+
+ elsif act == -reduce_n
+ #
+ # error
+ #
+ case @racc_error_status
+ when 0
+ unless arg[21] # user_yyerror
+ nerr += 1
+ on_error @racc_t, @racc_val, @racc_vstack
+ end
+ when 3
+ if @racc_t == 0 # is $
+ # We're at EOF, and another error occurred immediately after
+ # attempting auto-recovery
+ throw :racc_end_parse, nil
+ end
+ @racc_read_next = true
+ end
+ @racc_user_yyerror = false
+ @racc_error_status = 3
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ i += 1 # error token
+ if i >= 0 and
+ (act = action_table[i]) and
+ action_check[i] == @racc_state[-1]
+ break
+ end
+ end
+ throw :racc_end_parse, nil if @racc_state.size <= 1
+ @racc_state.pop
+ @racc_vstack.pop
+ if @yydebug
+ @racc_tstack.pop
+ racc_e_pop @racc_state, @racc_tstack, @racc_vstack
+ end
+ end
+ return act
+
+ else
+ raise "[Racc Bug] unknown action #{act.inspect}"
+ end
+
+ racc_next_state(@racc_state[-1], @racc_state) if @yydebug
+
+ nil
+ end
+
+ def _racc_do_reduce(arg, act)
+ _, _, _, _,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, _, _,
+ _, use_result, * = arg
+
+ state = @racc_state
+ vstack = @racc_vstack
+ tstack = @racc_tstack
+
+ i = act * -3
+ len = reduce_table[i]
+ reduce_to = reduce_table[i+1]
+ method_id = reduce_table[i+2]
+ void_array = []
+
+ tmp_t = tstack[-len, len] if @yydebug
+ tmp_v = vstack[-len, len]
+ tstack[-len, len] = void_array if @yydebug
+ vstack[-len, len] = void_array
+ state[-len, len] = void_array
+
+ # tstack must be updated AFTER method call
+ if use_result
+ vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
+ else
+ vstack.push __send__(method_id, tmp_v, vstack)
+ end
+ tstack.push reduce_to
+
+ racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
+
+ k1 = reduce_to - nt_base
+ if i = goto_pointer[k1]
+ i += state[-1]
+ if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
+ return curstate
+ end
+ end
+ goto_default[k1]
+ end
+
+ # This method is called when a parse error is found.
+ #
+ # ERROR_TOKEN_ID is an internal ID of token which caused error.
+ # You can get string representation of this ID by calling
+ # #token_to_str.
+ #
+ # ERROR_VALUE is a value of error token.
+ #
+ # value_stack is a stack of symbol values.
+ # DO NOT MODIFY this object.
+ #
+ # This method raises ParseError by default.
+ #
+ # If this method returns, parsers enter "error recovering mode".
+ def on_error(t, val, vstack)
+ raise ParseError, sprintf("\nparse error on value %s (%s)",
+ val.inspect, token_to_str(t) || '?')
+ end
+
+ # Enter error recovering mode.
+ # This method does not call #on_error.
+ def yyerror
+ throw :racc_jump, 1
+ end
+
+ # Exit parser.
+ # Return value is Symbol_Value_Stack[0].
+ def yyaccept
+ throw :racc_jump, 2
+ end
+
+ # Leave error recovering mode.
+ def yyerrok
+ @racc_error_status = 0
+ end
+
+ # For debugging output
+ def racc_read_token(t, tok, val)
+ @racc_debug_out.print 'read '
+ @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
+ @racc_debug_out.puts val.inspect
+ @racc_debug_out.puts
+ end
+
+ def racc_shift(tok, tstack, vstack)
+ @racc_debug_out.puts "shift #{racc_token2str tok}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_reduce(toks, sim, tstack, vstack)
+ out = @racc_debug_out
+ out.print 'reduce '
+ if toks.empty?
+ out.print ' <none>'
+ else
+ toks.each {|t| out.print ' ', racc_token2str(t) }
+ end
+ out.puts " --> #{racc_token2str(sim)}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_accept
+ @racc_debug_out.puts 'accept'
+ @racc_debug_out.puts
+ end
+
+ def racc_e_pop(state, tstack, vstack)
+ @racc_debug_out.puts 'error recovering mode: pop token'
+ racc_print_states state
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_next_state(curstate, state)
+ @racc_debug_out.puts "goto #{curstate}"
+ racc_print_states state
+ @racc_debug_out.puts
+ end
+
+ def racc_print_stacks(t, v)
+ out = @racc_debug_out
+ out.print ' ['
+ t.each_index do |i|
+ out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
+ end
+ out.puts ' ]'
+ end
+
+ def racc_print_states(s)
+ out = @racc_debug_out
+ out.print ' ['
+ s.each {|st| out.print ' ', st }
+ out.puts ' ]'
+ end
+
+ def racc_token2str(tok)
+ self.class::Racc_token_to_s_table[tok] or
+ raise "[Racc Bug] can't convert token #{tok} to string"
+ end
+
+ # Convert internal ID of token symbol to the string.
+ def token_to_str(t)
+ self.class::Racc_token_to_s_table[t]
+ end
+
+ end
+
+end
+
+__end_of_file__
+end
diff --git a/lib/racc/parser.rb b/lib/racc/parser.rb
index 0cdb42e49d..df94e85eb7 100644
--- a/lib/racc/parser.rb
+++ b/lib/racc/parser.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: false
#--
-# $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $
-#
# Copyright (c) 1999-2006 Minero Aoki
#
# This program is free software.
@@ -12,6 +10,12 @@
# without restriction.
#++
+require 'racc/info'
+
+unless defined?(NotImplementedError)
+ NotImplementedError = NotImplementError # :nodoc:
+end
+
module Racc
class ParseError < StandardError; end
end
@@ -25,7 +29,7 @@ end
# == Command-line Reference
#
# racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
-# [-e<var>rubypath</var>] [--embedded=<var>rubypath</var>]
+# [-e<var>rubypath</var>] [--executable=<var>rubypath</var>]
# [-v] [--verbose]
# [-O<var>filename</var>] [--log-file=<var>filename</var>]
# [-g] [--debug]
@@ -37,7 +41,7 @@ end
# [-S] [--output-status]
# [--version] [--copyright] [--help] <var>grammarfile</var>
#
-# [+filename+]
+# [+grammarfile+]
# Racc grammar file. Any extension is permitted.
# [-o+outfile+, --output-file=+outfile+]
# A filename for output. default is <+filename+>.tab.rb
@@ -49,7 +53,7 @@ end
# [-v, --verbose]
# verbose mode. create +filename+.output file, like yacc's y.output file.
# [-g, --debug]
-# add debug code to parser class. To display debugging information,
+# add debug code to parser class. To display debuggin information,
# use this '-g' option and set @yydebug true in parser class.
# [-E, --embedded]
# Output parser which doesn't need runtime files (racc/parser.rb).
@@ -171,7 +175,7 @@ end
# This command creates myparser.rb which `includes' Racc runtime.
# Only you must do is to distribute your parser file (myparser.rb).
#
-# Note: parser.rb is LGPL, but your parser is not.
+# Note: parser.rb is ruby license, but your parser is not.
# Your own parser is completely yours.
module Racc
@@ -181,15 +185,18 @@ module Racc
class Parser
- Racc_Runtime_Version = '1.4.6'
- Racc_Runtime_Revision = %w$originalRevision: 1.8 $[1]
+ Racc_Runtime_Version = ::Racc::VERSION
+ Racc_Runtime_Core_Version_R = ::Racc::VERSION
- Racc_Runtime_Core_Version_R = '1.4.6'
- Racc_Runtime_Core_Revision_R = %w$originalRevision: 1.8 $[1]
begin
- require 'racc/cparse'
- # Racc_Runtime_Core_Version_C = (defined in extension)
- Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
+ if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
+ require 'jruby'
+ require 'racc/cparse-jruby.jar'
+ com.headius.racc.Cparse.new.load(JRuby.runtime, false)
+ else
+ require 'racc/cparse'
+ end
+
unless new.respond_to?(:_racc_do_parse_c, true)
raise LoadError, 'old cparse.so'
end
@@ -200,13 +207,11 @@ module Racc
Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:
Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:
Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:
- Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C # :nodoc:
Racc_Runtime_Type = 'c' # :nodoc:
rescue LoadError
Racc_Main_Parsing_Routine = :_racc_do_parse_rb
Racc_YY_Parse_Method = :_racc_yyparse_rb
Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
- Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
Racc_Runtime_Type = 'ruby'
end
@@ -255,9 +260,11 @@ module Racc
# def next_token
# @q.shift
# end
+ class_eval %{
def do_parse
- __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
+ #{Racc_Main_Parsing_Routine}(_racc_setup(), false)
end
+ }
# The method to fetch next token.
# If you use #do_parse method, you must implement #next_token.
@@ -274,8 +281,7 @@ module Racc
def _racc_do_parse_rb(arg, in_debug)
action_table, action_check, action_default, action_pointer,
_, _, _, _,
- _, _, token_table, _,
- _, _, * = arg
+ _, _, token_table, * = arg
_racc_init_sysvars
tok = act = i = nil
@@ -316,19 +322,18 @@ module Racc
#
# RECEIVER#METHOD_ID is a method to get next token.
# It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
+ class_eval %{
def yyparse(recv, mid)
- __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
+ #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)
end
+ }
def _racc_yyparse_rb(recv, mid, arg, c_debug)
action_table, action_check, action_default, action_pointer,
- _, _, _, _,
- _, _, token_table, _,
- _, _, * = arg
+ _, _, _, _,
+ _, _, token_table, * = arg
_racc_init_sysvars
- act = nil
- i = nil
catch(:racc_end_parse) {
until i = action_pointer[@racc_state[-1]]
@@ -355,9 +360,9 @@ module Racc
;
end
- while not(i = action_pointer[@racc_state[-1]]) or
- not @racc_read_next or
- @racc_t == 0 # $
+ while !(i = action_pointer[@racc_state[-1]]) ||
+ ! @racc_read_next ||
+ @racc_t == 0 # $
unless i and i += @racc_t and
i >= 0 and
act = action_table[i] and
@@ -378,16 +383,17 @@ module Racc
def _racc_evalact(act, arg)
action_table, action_check, _, action_pointer,
- _, _, _, _,
- _, _, _, shift_n, reduce_n,
- _, _, * = arg
+ _, _, _, _,
+ _, _, _, shift_n,
+ reduce_n, * = arg
+ nerr = 0 # tmp
if act > 0 and act < shift_n
#
# shift
#
if @racc_error_status > 0
- @racc_error_status -= 1 unless @racc_t == 1 # error token
+ @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
end
@racc_vstack.push @racc_val
@racc_state.push act
@@ -431,10 +437,13 @@ module Racc
case @racc_error_status
when 0
unless arg[21] # user_yyerror
+ nerr += 1
on_error @racc_t, @racc_val, @racc_vstack
end
when 3
if @racc_t == 0 # is $
+ # We're at EOF, and another error occurred immediately after
+ # attempting auto-recovery
throw :racc_end_parse, nil
end
@racc_read_next = true
@@ -470,10 +479,11 @@ module Racc
end
def _racc_do_reduce(arg, act)
- _, _, _, _,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, _, _,
- _, use_result, * = arg
+ _, _, _, _,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, _, _,
+ _, use_result, * = arg
+
state = @racc_state
vstack = @racc_vstack
tstack = @racc_tstack
@@ -569,7 +579,6 @@ module Racc
toks.each {|t| out.print ' ', racc_token2str(t) }
end
out.puts " --> #{racc_token2str(sim)}"
-
racc_print_stacks tstack, vstack
@racc_debug_out.puts
end
diff --git a/lib/racc/parserfilegenerator.rb b/lib/racc/parserfilegenerator.rb
new file mode 100644
index 0000000000..fb6c209536
--- /dev/null
+++ b/lib/racc/parserfilegenerator.rb
@@ -0,0 +1,512 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/compat'
+require 'racc/sourcetext'
+require 'racc/parser-text'
+require 'rbconfig'
+
+module Racc
+
+ class ParserFileGenerator
+
+ class Params
+ def self.bool_attr(name)
+ module_eval(<<-End)
+ def #{name}?
+ @#{name}
+ end
+
+ def #{name}=(b)
+ @#{name} = b
+ end
+ End
+ end
+
+ attr_accessor :filename
+ attr_accessor :classname
+ attr_accessor :superclass
+ bool_attr :omit_action_call
+ bool_attr :result_var
+ attr_accessor :header
+ attr_accessor :inner
+ attr_accessor :footer
+
+ bool_attr :debug_parser
+ bool_attr :convert_line
+ bool_attr :convert_line_all
+ bool_attr :embed_runtime
+ bool_attr :make_executable
+ attr_accessor :interpreter
+
+ def initialize
+ # Parameters derived from parser
+ self.filename = nil
+ self.classname = nil
+ self.superclass = 'Racc::Parser'
+ self.omit_action_call = true
+ self.result_var = true
+ self.header = []
+ self.inner = []
+ self.footer = []
+
+ # Parameters derived from command line options
+ self.debug_parser = false
+ self.convert_line = true
+ self.convert_line_all = false
+ self.embed_runtime = false
+ self.make_executable = false
+ self.interpreter = nil
+ end
+ end
+
+ def initialize(states, params)
+ @states = states
+ @grammar = states.grammar
+ @params = params
+ end
+
+ def generate_parser
+ string_io = StringIO.new
+
+ init_line_conversion_system
+ @f = string_io
+ parser_file
+
+ string_io.rewind
+ string_io.read
+ end
+
+ def generate_parser_file(destpath)
+ init_line_conversion_system
+ File.open(destpath, 'w') {|f|
+ @f = f
+ parser_file
+ }
+ File.chmod 0755, destpath if @params.make_executable?
+ end
+
+ private
+
+ def parser_file
+ shebang @params.interpreter if @params.make_executable?
+ notice
+ line
+ if @params.embed_runtime?
+ embed_library runtime_source()
+ else
+ require 'racc/parser.rb'
+ end
+ header
+ parser_class(@params.classname, @params.superclass) {
+ inner
+ state_transition_table
+ }
+ footer
+ end
+
+ c = ::RbConfig::CONFIG
+ RUBY_PATH = "#{c['bindir']}/#{c['ruby_install_name']}#{c['EXEEXT']}"
+
+ def shebang(path)
+ line '#!' + (path == 'ruby' ? RUBY_PATH : path)
+ end
+
+ def notice
+ line %q[#]
+ line %q[# DO NOT MODIFY!!!!]
+ line %Q[# This file is automatically generated by Racc #{Racc::Version}]
+ line %Q[# from Racc grammar file "#{@params.filename}".]
+ line %q[#]
+ end
+
+ def runtime_source
+ SourceText.new(::Racc::PARSER_TEXT, 'racc/parser.rb', 1)
+ end
+
+ def embed_library(src)
+ line %[###### #{src.filename} begin]
+ line %[unless $".index '#{src.filename}']
+ line %[$".push '#{src.filename}']
+ put src, @params.convert_line?
+ line %[end]
+ line %[###### #{src.filename} end]
+ end
+
+ def require(feature)
+ line "require '#{feature}'"
+ end
+
+ def parser_class(classname, superclass)
+ mods = classname.split('::')
+ classid = mods.pop
+ mods.each do |mod|
+ indent; line "module #{mod}"
+ cref_push mod
+ end
+ indent; line "class #{classid} < #{superclass}"
+ cref_push classid
+ yield
+ cref_pop
+ indent; line "end \# class #{classid}"
+ mods.reverse_each do |mod|
+ cref_pop
+ indent; line "end \# module #{mod}"
+ end
+ end
+
+ def header
+ @params.header.each do |src|
+ line
+ put src, @params.convert_line_all?
+ end
+ end
+
+ def inner
+ @params.inner.each do |src|
+ line
+ put src, @params.convert_line?
+ end
+ end
+
+ def footer
+ @params.footer.each do |src|
+ line
+ put src, @params.convert_line_all?
+ end
+ end
+
+ # Low Level Routines
+
+ def put(src, convert_line = false)
+ if convert_line
+ replace_location(src) {
+ @f.puts src.text
+ }
+ else
+ @f.puts src.text
+ end
+ end
+
+ def line(str = '')
+ @f.puts str
+ end
+
+ def init_line_conversion_system
+ @cref = []
+ @used_separator = {}
+ end
+
+ def cref_push(name)
+ @cref.push name
+ end
+
+ def cref_pop
+ @cref.pop
+ end
+
+ def indent
+ @f.print ' ' * @cref.size
+ end
+
+ def toplevel?
+ @cref.empty?
+ end
+
+ def replace_location(src)
+ sep = make_separator(src)
+ @f.print 'self.class.' if toplevel?
+ @f.puts "module_eval(<<'#{sep}', '#{src.filename}', #{src.lineno})"
+ yield
+ @f.puts sep
+ end
+
+ def make_separator(src)
+ sep = unique_separator(src.filename)
+ sep *= 2 while src.text.index(sep)
+ sep
+ end
+
+ def unique_separator(id)
+ sep = String.new "...end #{id}/module_eval..."
+ while @used_separator.key?(sep)
+ sep.concat sprintf('%02x', rand(255))
+ end
+ @used_separator[sep] = true
+ sep
+ end
+
+ #
+ # State Transition Table Serialization
+ #
+
+ public
+
+ def put_state_transition_table(f)
+ @f = f
+ state_transition_table
+ end
+
+ private
+
+ def state_transition_table
+ table = @states.state_transition_table
+ table.use_result_var = @params.result_var?
+ table.debug_parser = @params.debug_parser?
+
+ line "##### State transition tables begin ###"
+ line
+ integer_list 'racc_action_table', table.action_table
+ line
+ integer_list 'racc_action_check', table.action_check
+ line
+ integer_list 'racc_action_pointer', table.action_pointer
+ line
+ integer_list 'racc_action_default', table.action_default
+ line
+ integer_list 'racc_goto_table', table.goto_table
+ line
+ integer_list 'racc_goto_check', table.goto_check
+ line
+ integer_list 'racc_goto_pointer', table.goto_pointer
+ line
+ integer_list 'racc_goto_default', table.goto_default
+ line
+ i_i_sym_list 'racc_reduce_table', table.reduce_table
+ line
+ line "racc_reduce_n = #{table.reduce_n}"
+ line
+ line "racc_shift_n = #{table.shift_n}"
+ line
+ sym_int_hash 'racc_token_table', table.token_table
+ line
+ line "racc_nt_base = #{table.nt_base}"
+ line
+ line "racc_use_result_var = #{table.use_result_var}"
+ line
+ @f.print(unindent_auto(<<-End))
+ Racc_arg = [
+ racc_action_table,
+ racc_action_check,
+ racc_action_default,
+ racc_action_pointer,
+ racc_goto_table,
+ racc_goto_check,
+ racc_goto_default,
+ racc_goto_pointer,
+ racc_nt_base,
+ racc_reduce_table,
+ racc_token_table,
+ racc_shift_n,
+ racc_reduce_n,
+ racc_use_result_var ]
+ End
+ line
+ string_list 'Racc_token_to_s_table', table.token_to_s_table
+ line
+ line "Racc_debug_parser = #{table.debug_parser}"
+ line
+ line '##### State transition tables end #####'
+ actions
+ end
+
+ def integer_list(name, table)
+ if table.size > 2000
+ serialize_integer_list_compressed name, table
+ else
+ serialize_integer_list_std name, table
+ end
+ end
+
+ def serialize_integer_list_compressed(name, table)
+ # TODO: this can be made a LOT more clean with a simple split/map
+ sep = "\n"
+ nsep = ",\n"
+ buf = String.new
+ com = ''
+ ncom = ','
+ co = com
+ @f.print 'clist = ['
+ table.each do |i|
+ buf << co << i.to_s; co = ncom
+ if buf.size > 66
+ @f.print sep; sep = nsep
+ @f.print "'", buf, "'"
+ buf = String.new
+ co = com
+ end
+ end
+ unless buf.empty?
+ @f.print sep
+ @f.print "'", buf, "'"
+ end
+ line ' ]'
+
+ @f.print(<<-End)
+ #{name} = arr = ::Array.new(#{table.size}, nil)
+ idx = 0
+ clist.each do |str|
+ str.split(',', -1).each do |i|
+ arr[idx] = i.to_i unless i.empty?
+ idx += 1
+ end
+ end
+ End
+ end
+
+ def serialize_integer_list_std(name, table)
+ sep = ''
+ line "#{name} = ["
+ table.each_slice(10) do |ns|
+ @f.print sep; sep = ",\n"
+ @f.print ns.map {|n| sprintf('%6s', n ? n.to_s : 'nil') }.join(',')
+ end
+ line ' ]'
+ end
+
+ def i_i_sym_list(name, table)
+ sep = ''
+ line "#{name} = ["
+ table.each_slice(3) do |len, target, mid|
+ @f.print sep; sep = ",\n"
+ @f.printf ' %d, %d, %s', len, target, mid.inspect
+ end
+ line " ]"
+ end
+
+ def sym_int_hash(name, h)
+ sep = "\n"
+ @f.print "#{name} = {"
+ h.to_a.sort_by {|sym, i| i }.each do |sym, i|
+ @f.print sep; sep = ",\n"
+ @f.printf " %s => %d", sym.serialize, i
+ end
+ line " }"
+ end
+
+ def string_list(name, list)
+ sep = " "
+ line "#{name} = ["
+ list.each do |s|
+ @f.print sep; sep = ",\n "
+ @f.print s.dump
+ end
+ line ' ]'
+ end
+
+ def actions
+ @grammar.each do |rule|
+ unless rule.action.source?
+ raise "racc: fatal: cannot generate parser file when any action is a Proc"
+ end
+ end
+
+ if @params.result_var?
+ decl = ', result'
+ retval = "\n result"
+ default_body = ''
+ else
+ decl = ''
+ retval = ''
+ default_body = 'val[0]'
+ end
+ @grammar.each do |rule|
+ line
+ if rule.action.empty? and @params.omit_action_call?
+ line "# reduce #{rule.ident} omitted"
+ else
+ src0 = rule.action.source || SourceText.new(default_body, __FILE__, 0)
+ if @params.convert_line?
+ src = remove_blank_lines(src0)
+ delim = make_delimiter(src.text)
+ @f.printf unindent_auto(<<-End),
+ module_eval(<<'%s', '%s', %d)
+ def _reduce_%d(val, _values%s)
+ %s%s
+ end
+ %s
+ End
+ delim, src.filename, src.lineno - 1,
+ rule.ident, decl,
+ src.text, retval,
+ delim
+ else
+ src = remove_blank_lines(src0)
+ @f.printf unindent_auto(<<-End),
+ def _reduce_%d(val, _values%s)
+ %s%s
+ end
+ End
+ rule.ident, decl,
+ src.text, retval
+ end
+ end
+ end
+ line
+ @f.printf unindent_auto(<<-'End'), decl
+ def _reduce_none(val, _values%s)
+ val[0]
+ end
+ End
+ line
+ end
+
+ def remove_blank_lines(src)
+ body = src.text.dup
+ line = src.lineno
+ while body.slice!(/\A[ \t\f]*(?:\n|\r\n|\r)/)
+ line += 1
+ end
+ SourceText.new(body, src.filename, line)
+ end
+
+ def make_delimiter(body)
+ delim = '.,.,'
+ while body.index(delim)
+ delim *= 2
+ end
+ delim
+ end
+
+ def unindent_auto(str)
+ lines = str.lines.to_a
+ n = minimum_indent(lines)
+ lines.map {|line| detab(line).sub(indent_re(n), '').rstrip + "\n" }.join('')
+ end
+
+ def minimum_indent(lines)
+ lines.map {|line| n_indent(line) }.min
+ end
+
+ def n_indent(line)
+ line.slice(/\A\s+/).size
+ end
+
+ RE_CACHE = {}
+
+ def indent_re(n)
+ RE_CACHE[n] ||= /\A {#{n}}/
+ end
+
+ def detab(str, ts = 8)
+ add = 0
+ len = nil
+ str.gsub(/\t/) {
+ len = ts - ($`.size + add) % ts
+ add += len - 1
+ ' ' * len
+ }
+ end
+
+ end
+
+end
diff --git a/lib/racc/pre-setup b/lib/racc/pre-setup
new file mode 100644
index 0000000000..5027d865b7
--- /dev/null
+++ b/lib/racc/pre-setup
@@ -0,0 +1,13 @@
+def generate_parser_text_rb(target)
+ return if File.exist?(srcfile(target))
+ $stderr.puts "generating #{target}..."
+ File.open(target, 'w') {|f|
+ f.puts "module Racc"
+ f.puts " PARSER_TEXT = <<'__end_of_file__'"
+ f.puts File.read(srcfile('parser.rb'))
+ f.puts "__end_of_file__"
+ f.puts "end"
+ }
+end
+
+generate_parser_text_rb 'parser-text.rb'
diff --git a/lib/racc/racc.gemspec b/lib/racc/racc.gemspec
new file mode 100644
index 0000000000..5c345891ad
--- /dev/null
+++ b/lib/racc/racc.gemspec
@@ -0,0 +1,107 @@
+# -*- encoding: utf-8 -*-
+
+begin
+ require_relative "lib/racc/info"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "info"
+end
+
+Gem::Specification.new do |s|
+ s.name = "racc"
+ s.version = Racc::VERSION
+ s.summary = "Racc is a LALR(1) parser generator"
+ s.description = <<DESC
+Racc is a LALR(1) parser generator.
+ It is written in Ruby itself, and generates Ruby program.
+
+ NOTE: Ruby 1.8.x comes with Racc runtime module. You
+ can run your parsers generated by racc 1.4.x out of the
+ box.
+DESC
+ s.authors = ["Minero Aoki", "Aaron Patterson"]
+ s.email = [nil, "aaron@tenderlovemaking.com"]
+ s.homepage = "http://i.loveruby.net/en/projects/racc/"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
+ s.executables = ["racc"]
+ s.files = [
+ "COPYING", "ChangeLog",
+ "README.ja.rdoc", "README.rdoc", "Rakefile", "TODO", "bin/racc",
+ "ext/racc/MANIFEST",
+ "ext/racc/com/headius/racc/Cparse.java", "ext/racc/cparse/cparse.c",
+ "ext/racc/cparse/extconf.rb",
+ "lib/racc.rb", "lib/racc/compat.rb",
+ "lib/racc/debugflags.rb", "lib/racc/exception.rb",
+ "lib/racc/grammar.rb", "lib/racc/grammarfileparser.rb",
+ "lib/racc/info.rb", "lib/racc/iset.rb",
+ "lib/racc/logfilegenerator.rb", "lib/racc/parser-text.rb",
+ "lib/racc/parser.rb", "lib/racc/parserfilegenerator.rb",
+ "lib/racc/pre-setup", "lib/racc/sourcetext.rb",
+ "lib/racc/state.rb", "lib/racc/statetransitiontable.rb",
+ "lib/racc/static.rb", "rdoc/en/NEWS.en.rdoc",
+ "rdoc/en/grammar.en.rdoc", "rdoc/ja/NEWS.ja.rdoc",
+ "rdoc/ja/command.ja.html", "rdoc/ja/debug.ja.rdoc",
+ "rdoc/ja/grammar.ja.rdoc", "rdoc/ja/index.ja.html",
+ "rdoc/ja/parser.ja.rdoc", "rdoc/ja/usage.ja.html",
+ "sample/array.y", "sample/array2.y", "sample/calc-ja.y",
+ "sample/calc.y", "sample/conflict.y", "sample/hash.y",
+ "sample/lalr.y", "sample/lists.y", "sample/syntax.y",
+ "sample/yyerr.y",
+ "test/assets/cadenza.y", "test/assets/cast.y",
+ "test/assets/chk.y", "test/assets/conf.y",
+ "test/assets/csspool.y", "test/assets/digraph.y",
+ "test/assets/echk.y", "test/assets/edtf.y", "test/assets/err.y",
+ "test/assets/error_recovery.y", "test/assets/expect.y",
+ "test/assets/firstline.y", "test/assets/huia.y",
+ "test/assets/ichk.y", "test/assets/intp.y",
+ "test/assets/journey.y", "test/assets/liquor.y",
+ "test/assets/machete.y", "test/assets/macruby.y",
+ "test/assets/mailp.y", "test/assets/mediacloth.y",
+ "test/assets/mof.y", "test/assets/namae.y", "test/assets/nasl.y",
+ "test/assets/newsyn.y", "test/assets/noend.y",
+ "test/assets/nokogiri-css.y", "test/assets/nonass.y",
+ "test/assets/normal.y", "test/assets/norule.y",
+ "test/assets/nullbug1.y", "test/assets/nullbug2.y",
+ "test/assets/opal.y", "test/assets/opt.y",
+ "test/assets/percent.y", "test/assets/php_serialization.y",
+ "test/assets/recv.y", "test/assets/riml.y",
+ "test/assets/rrconf.y", "test/assets/ruby18.y",
+ "test/assets/ruby19.y", "test/assets/ruby20.y",
+ "test/assets/ruby21.y", "test/assets/ruby22.y",
+ "test/assets/scan.y", "test/assets/syntax.y",
+ "test/assets/tp_plus.y", "test/assets/twowaysql.y",
+ "test/assets/unterm.y", "test/assets/useless.y",
+ "test/assets/yyerr.y", "test/bench.y", "test/helper.rb",
+ "test/infini.y", "test/regress/cadenza", "test/regress/cast",
+ "test/regress/csspool", "test/regress/edtf", "test/regress/huia",
+ "test/regress/journey", "test/regress/liquor",
+ "test/regress/machete", "test/regress/mediacloth",
+ "test/regress/mof", "test/regress/namae", "test/regress/nasl",
+ "test/regress/nokogiri-css", "test/regress/opal",
+ "test/regress/php_serialization", "test/regress/riml",
+ "test/regress/ruby18", "test/regress/ruby22",
+ "test/regress/tp_plus", "test/regress/twowaysql",
+ "test/scandata/brace", "test/scandata/gvar",
+ "test/scandata/normal", "test/scandata/percent",
+ "test/scandata/slash", "test/src.intp", "test/start.y",
+ "test/test_chk_y.rb", "test/test_grammar_file_parser.rb",
+ "test/test_racc_command.rb", "test/test_scan_y.rb",
+ "test/testscanner.rb", "web/racc.en.rhtml", "web/racc.ja.rhtml"
+ ]
+ s.require_paths = ["lib"]
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.rdoc_options = ["--main", "README.rdoc"]
+ s.extra_rdoc_files = [
+ "README.ja.rdoc", "README.rdoc",
+ "rdoc/en/NEWS.en.rdoc", "rdoc/en/grammar.en.rdoc",
+ "rdoc/ja/NEWS.ja.rdoc", "rdoc/ja/debug.ja.rdoc",
+ "rdoc/ja/grammar.ja.rdoc", "rdoc/ja/parser.ja.rdoc",
+ "README.ja.rdoc", "README.rdoc"
+ ]
+
+ if RUBY_PLATFORM =~ /java/
+ s.files << 'lib/racc/cparse-jruby.jar'
+ s.platform = 'java'
+ else
+ s.extensions = ["ext/racc/cparse/extconf.rb"]
+ end
+end
diff --git a/lib/racc/rdoc/grammar.en.rdoc b/lib/racc/rdoc/grammar.en.rdoc
index c00e19daff..af10803f3a 100644
--- a/lib/racc/rdoc/grammar.en.rdoc
+++ b/lib/racc/rdoc/grammar.en.rdoc
@@ -16,7 +16,7 @@ You can insert comments about all places. Two styles of comments can be used, Ru
The class block is formed like this:
class CLASS_NAME
- [precedance table]
+ [precedence table]
[token declarations]
[expected number of S/R conflicts]
[options]
diff --git a/lib/racc/sourcetext.rb b/lib/racc/sourcetext.rb
new file mode 100644
index 0000000000..de52dcae9b
--- /dev/null
+++ b/lib/racc/sourcetext.rb
@@ -0,0 +1,35 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ class SourceText
+ def initialize(text, filename, lineno)
+ @text = text
+ @filename = filename
+ @lineno = lineno
+ end
+
+ attr_reader :text
+ attr_reader :filename
+ attr_reader :lineno
+
+ def to_s
+ "#<SourceText #{location()}>"
+ end
+
+ def location
+ "#{@filename}:#{@lineno}"
+ end
+ end
+
+end
diff --git a/lib/racc/state.rb b/lib/racc/state.rb
new file mode 100644
index 0000000000..f85809fbeb
--- /dev/null
+++ b/lib/racc/state.rb
@@ -0,0 +1,972 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/iset'
+require 'racc/statetransitiontable'
+require 'racc/exception'
+require 'forwardable'
+
+module Racc
+
+ # A table of LALR states.
+ class States
+
+ include Enumerable
+
+ def initialize(grammar, debug_flags = DebugFlags.new)
+ @grammar = grammar
+ @symboltable = grammar.symboltable
+ @d_state = debug_flags.state
+ @d_la = debug_flags.la
+ @d_prec = debug_flags.prec
+ @states = []
+ @statecache = {}
+ @actions = ActionTable.new(@grammar, self)
+ @nfa_computed = false
+ @dfa_computed = false
+ end
+
+ attr_reader :grammar
+ attr_reader :actions
+
+ def size
+ @states.size
+ end
+
+ def inspect
+ '#<state table>'
+ end
+
+ alias to_s inspect
+
+ def [](i)
+ @states[i]
+ end
+
+ def each_state(&block)
+ @states.each(&block)
+ end
+
+ alias each each_state
+
+ def each_index(&block)
+ @states.each_index(&block)
+ end
+
+ extend Forwardable
+
+ def_delegator "@actions", :shift_n
+ def_delegator "@actions", :reduce_n
+ def_delegator "@actions", :nt_base
+
+ def should_report_srconflict?
+ srconflict_exist? and
+ (n_srconflicts() != @grammar.n_expected_srconflicts)
+ end
+
+ def srconflict_exist?
+ n_srconflicts() != 0
+ end
+
+ def n_srconflicts
+ @n_srconflicts ||= inject(0) {|sum, st| sum + st.n_srconflicts }
+ end
+
+ def rrconflict_exist?
+ n_rrconflicts() != 0
+ end
+
+ def n_rrconflicts
+ @n_rrconflicts ||= inject(0) {|sum, st| sum + st.n_rrconflicts }
+ end
+
+ def state_transition_table
+ @state_transition_table ||= StateTransitionTable.generate(self.dfa)
+ end
+
+ #
+ # NFA (Non-deterministic Finite Automaton) Computation
+ #
+
+ public
+
+ def nfa
+ return self if @nfa_computed
+ compute_nfa
+ @nfa_computed = true
+ self
+ end
+
+ private
+
+ def compute_nfa
+ @grammar.init
+ # add state 0
+ core_to_state [ @grammar[0].ptrs[0] ]
+ # generate LALR states
+ cur = 0
+ @gotos = []
+ while cur < @states.size
+ generate_states @states[cur] # state is added here
+ cur += 1
+ end
+ @actions.init
+ end
+
+ def generate_states(state)
+ puts "dstate: #{state}" if @d_state
+
+ table = {}
+ state.closure.each do |ptr|
+ if sym = ptr.dereference
+ addsym table, sym, ptr.next
+ end
+ end
+ table.each do |sym, core|
+ puts "dstate: sym=#{sym} ncore=#{core}" if @d_state
+
+ dest = core_to_state(core.to_a)
+ state.goto_table[sym] = dest
+ id = sym.nonterminal?() ? @gotos.size : nil
+ g = Goto.new(id, sym, state, dest)
+ @gotos.push g if sym.nonterminal?
+ state.gotos[sym] = g
+ puts "dstate: #{state.ident} --#{sym}--> #{dest.ident}" if @d_state
+
+ # check infinite recursion
+ if state.ident == dest.ident and state.closure.size == 1
+ raise CompileError,
+ sprintf("Infinite recursion: state %d, with rule %d",
+ state.ident, state.ptrs[0].rule.ident)
+ end
+ end
+ end
+
+ def addsym(table, sym, ptr)
+ unless s = table[sym]
+ table[sym] = s = ISet.new
+ end
+ s.add ptr
+ end
+
+ def core_to_state(core)
+ #
+ # convert CORE to a State object.
+ # If matching state does not exist, create it and add to the table.
+ #
+
+ k = fingerprint(core)
+ unless dest = @statecache[k]
+ # not registered yet
+ dest = State.new(@states.size, core)
+ @states.push dest
+
+ @statecache[k] = dest
+
+ puts "core_to_state: create state ID #{dest.ident}" if @d_state
+ else
+ if @d_state
+ puts "core_to_state: dest is cached ID #{dest.ident}"
+ puts "core_to_state: dest core #{dest.core.join(' ')}"
+ end
+ end
+
+ dest
+ end
+
+ def fingerprint(arr)
+ arr.map {|i| i.ident }.pack('L*')
+ end
+
+ #
+ # DFA (Deterministic Finite Automaton) Generation
+ #
+
+ public
+
+ def dfa
+ return self if @dfa_computed
+ nfa
+ compute_dfa
+ @dfa_computed = true
+ self
+ end
+
+ private
+
+ def compute_dfa
+ la = lookahead()
+ @states.each do |state|
+ state.la = la
+ resolve state
+ end
+ set_accept
+ @states.each do |state|
+ pack state
+ end
+ check_useless
+ end
+
+ def lookahead
+ #
+ # lookahead algorithm ver.3 -- from bison 1.26
+ #
+
+ gotos = @gotos
+ if @d_la
+ puts "\n--- goto ---"
+ gotos.each_with_index {|g, i| print i, ' '; p g }
+ end
+
+ ### initialize_LA()
+ ### set_goto_map()
+ la_rules = []
+ @states.each do |state|
+ state.check_la la_rules
+ end
+
+ ### initialize_F()
+ f = create_tmap(gotos.size)
+ reads = []
+ edge = []
+ gotos.each do |goto|
+ goto.to_state.goto_table.each do |t, st|
+ if t.terminal?
+ f[goto.ident] |= (1 << t.ident)
+ elsif t.nullable?
+ edge.push goto.to_state.gotos[t].ident
+ end
+ end
+ if edge.empty?
+ reads.push nil
+ else
+ reads.push edge
+ edge = []
+ end
+ end
+ digraph f, reads
+ if @d_la
+ puts "\n--- F1 (reads) ---"
+ print_tab gotos, reads, f
+ end
+
+ ### build_relations()
+ ### compute_FOLLOWS
+ path = nil
+ edge = []
+ lookback = Array.new(la_rules.size, nil)
+ includes = []
+ gotos.each do |goto|
+ goto.symbol.heads.each do |ptr|
+ path = record_path(goto.from_state, ptr.rule)
+ lastgoto = path.last
+ st = lastgoto ? lastgoto.to_state : goto.from_state
+ if st.conflict?
+ addrel lookback, st.rruleid(ptr.rule), goto
+ end
+ path.reverse_each do |g|
+ break if g.symbol.terminal?
+ edge.push g.ident
+ break unless g.symbol.nullable?
+ end
+ end
+ if edge.empty?
+ includes.push nil
+ else
+ includes.push edge
+ edge = []
+ end
+ end
+ includes = transpose(includes)
+ digraph f, includes
+ if @d_la
+ puts "\n--- F2 (includes) ---"
+ print_tab gotos, includes, f
+ end
+
+ ### compute_lookaheads
+ la = create_tmap(la_rules.size)
+ lookback.each_with_index do |arr, i|
+ if arr
+ arr.each do |g|
+ la[i] |= f[g.ident]
+ end
+ end
+ end
+ if @d_la
+ puts "\n--- LA (lookback) ---"
+ print_tab la_rules, lookback, la
+ end
+
+ la
+ end
+
+ def create_tmap(size)
+ Array.new(size, 0) # use Integer as bitmap
+ end
+
+ def addrel(tbl, i, item)
+ if a = tbl[i]
+ a.push item
+ else
+ tbl[i] = [item]
+ end
+ end
+
+ def record_path(begst, rule)
+ st = begst
+ path = []
+ rule.symbols.each do |t|
+ goto = st.gotos[t]
+ path.push goto
+ st = goto.to_state
+ end
+ path
+ end
+
+ def transpose(rel)
+ new = Array.new(rel.size, nil)
+ rel.each_with_index do |arr, idx|
+ if arr
+ arr.each do |i|
+ addrel new, i, idx
+ end
+ end
+ end
+ new
+ end
+
+ def digraph(map, relation)
+ n = relation.size
+ index = Array.new(n, nil)
+ vertices = []
+ @infinity = n + 2
+
+ index.each_index do |i|
+ if not index[i] and relation[i]
+ traverse i, index, vertices, map, relation
+ end
+ end
+ end
+
+ def traverse(i, index, vertices, map, relation)
+ vertices.push i
+ index[i] = height = vertices.size
+
+ if rp = relation[i]
+ rp.each do |proci|
+ unless index[proci]
+ traverse proci, index, vertices, map, relation
+ end
+ if index[i] > index[proci]
+ # circulative recursion !!!
+ index[i] = index[proci]
+ end
+ map[i] |= map[proci]
+ end
+ end
+
+ if index[i] == height
+ while true
+ proci = vertices.pop
+ index[proci] = @infinity
+ break if i == proci
+
+ map[proci] |= map[i]
+ end
+ end
+ end
+
+ # for debug
+ def print_atab(idx, tab)
+ tab.each_with_index do |i,ii|
+ printf '%-20s', idx[ii].inspect
+ p i
+ end
+ end
+
+ def print_tab(idx, rel, tab)
+ tab.each_with_index do |bin,i|
+ print i, ' ', idx[i].inspect, ' << '; p rel[i]
+ print ' '
+ each_t(@symboltable, bin) {|t| print ' ', t }
+ puts
+ end
+ end
+
+ # for debug
+ def print_tab_i(idx, rel, tab, i)
+ bin = tab[i]
+ print i, ' ', idx[i].inspect, ' << '; p rel[i]
+ print ' '
+ each_t(@symboltable, bin) {|t| print ' ', t }
+ end
+
+ # for debug
+ def printb(i)
+ each_t(@symboltable, i) do |t|
+ print t, ' '
+ end
+ puts
+ end
+
+ def each_t(tbl, set)
+ 0.upto( set.size ) do |i|
+ (0..7).each do |ii|
+ if set[idx = i * 8 + ii] == 1
+ yield tbl[idx]
+ end
+ end
+ end
+ end
+
+ #
+ # resolve
+ #
+
+ def resolve(state)
+ if state.conflict?
+ resolve_rr state, state.ritems
+ resolve_sr state, state.stokens
+ else
+ if state.rrules.empty?
+ # shift
+ state.stokens.each do |t|
+ state.action[t] = @actions.shift(state.goto_table[t])
+ end
+ else
+ # reduce
+ state.defact = @actions.reduce(state.rrules[0])
+ end
+ end
+ end
+
+ def resolve_rr(state, r)
+ r.each do |item|
+ item.each_la(@symboltable) do |t|
+ act = state.action[t]
+ if act
+ unless act.kind_of?(Reduce)
+ raise "racc: fatal: #{act.class} in action table"
+ end
+ # Cannot resolve R/R conflict (on t).
+ # Reduce with upper rule as default.
+ state.rr_conflict act.rule, item.rule, t
+ else
+ # No conflict.
+ state.action[t] = @actions.reduce(item.rule)
+ end
+ end
+ end
+ end
+
+ def resolve_sr(state, s)
+ s.each do |stok|
+ goto = state.goto_table[stok]
+ act = state.action[stok]
+
+ unless act
+ # no conflict
+ state.action[stok] = @actions.shift(goto)
+ else
+ unless act.kind_of?(Reduce)
+ puts 'DEBUG -------------------------------'
+ p stok
+ p act
+ state.action.each do |k,v|
+ print k.inspect, ' ', v.inspect, "\n"
+ end
+ raise "racc: fatal: #{act.class} in action table"
+ end
+
+ # conflict on stok
+
+ rtok = act.rule.precedence
+ case do_resolve_sr(stok, rtok)
+ when :Reduce
+ # action is already set
+
+ when :Shift
+ # overwrite
+ act.decref
+ state.action[stok] = @actions.shift(goto)
+
+ when :Error
+ act.decref
+ state.action[stok] = @actions.error
+
+ when :CantResolve
+ # shift as default
+ act.decref
+ state.action[stok] = @actions.shift(goto)
+ state.sr_conflict stok, act.rule
+ end
+ end
+ end
+ end
+
+ ASSOC = {
+ :Left => :Reduce,
+ :Right => :Shift,
+ :Nonassoc => :Error
+ }
+
+ def do_resolve_sr(stok, rtok)
+ puts "resolve_sr: s/r conflict: rtok=#{rtok}, stok=#{stok}" if @d_prec
+
+ unless rtok and rtok.precedence
+ puts "resolve_sr: no prec for #{rtok}(R)" if @d_prec
+ return :CantResolve
+ end
+ rprec = rtok.precedence
+
+ unless stok and stok.precedence
+ puts "resolve_sr: no prec for #{stok}(S)" if @d_prec
+ return :CantResolve
+ end
+ sprec = stok.precedence
+
+ ret = if rprec == sprec
+ ASSOC[rtok.assoc] or
+ raise "racc: fatal: #{rtok}.assoc is not Left/Right/Nonassoc"
+ else
+ (rprec > sprec) ? (:Reduce) : (:Shift)
+ end
+
+ puts "resolve_sr: resolved as #{ret.id2name}" if @d_prec
+ ret
+ end
+
+ #
+ # complete
+ #
+
+ def set_accept
+ anch = @symboltable.anchor
+ init_state = @states[0].goto_table[@grammar.start]
+ targ_state = init_state.action[anch].goto_state
+ acc_state = targ_state.action[anch].goto_state
+
+ acc_state.action.clear
+ acc_state.goto_table.clear
+ acc_state.defact = @actions.accept
+ end
+
+ def pack(state)
+ ### find most frequently used reduce rule
+ act = state.action
+ arr = Array.new(@grammar.size, 0)
+ act.each do |t, a|
+ arr[a.ruleid] += 1 if a.kind_of?(Reduce)
+ end
+ i = arr.max
+ s = (i > 0) ? arr.index(i) : nil
+
+ ### set & delete default action
+ if s
+ r = @actions.reduce(s)
+ if not state.defact or state.defact == r
+ act.delete_if {|t, a| a == r }
+ state.defact = r
+ end
+ else
+ state.defact ||= @actions.error
+ end
+ end
+
+ def check_useless
+ used = []
+ @actions.each_reduce do |act|
+ if not act or act.refn == 0
+ act.rule.useless = true
+ else
+ t = act.rule.target
+ used[t.ident] = t
+ end
+ end
+ @symboltable.nt_base.upto(@symboltable.nt_max - 1) do |n|
+ unless used[n]
+ @symboltable[n].useless = true
+ end
+ end
+ end
+
+ end # class StateTable
+
+
+ # A LALR state.
+ class State
+
+ def initialize(ident, core)
+ @ident = ident
+ @core = core
+ @goto_table = {}
+ @gotos = {}
+ @stokens = nil
+ @ritems = nil
+ @action = {}
+ @defact = nil
+ @rrconf = nil
+ @srconf = nil
+
+ @closure = make_closure(@core)
+ end
+
+ attr_reader :ident
+ alias stateid ident
+ alias hash ident
+
+ attr_reader :core
+ attr_reader :closure
+
+ attr_reader :goto_table
+ attr_reader :gotos
+
+ attr_reader :stokens
+ attr_reader :ritems
+ attr_reader :rrules
+
+ attr_reader :action
+ attr_accessor :defact # default action
+
+ attr_reader :rrconf
+ attr_reader :srconf
+
+ def inspect
+ "<state #{@ident}>"
+ end
+
+ alias to_s inspect
+
+ def ==(oth)
+ @ident == oth.ident
+ end
+
+ alias eql? ==
+
+ def make_closure(core)
+ set = ISet.new
+ core.each do |ptr|
+ set.add ptr
+ if t = ptr.dereference and t.nonterminal?
+ set.update_a t.expand
+ end
+ end
+ set.to_a
+ end
+
+ def check_la(la_rules)
+ @conflict = false
+ s = []
+ r = []
+ @closure.each do |ptr|
+ if t = ptr.dereference
+ if t.terminal?
+ s[t.ident] = t
+ if t.ident == 1 # $error
+ @conflict = true
+ end
+ end
+ else
+ r.push ptr.rule
+ end
+ end
+ unless r.empty?
+ if not s.empty? or r.size > 1
+ @conflict = true
+ end
+ end
+ s.compact!
+ @stokens = s
+ @rrules = r
+
+ if @conflict
+ @la_rules_i = la_rules.size
+ @la_rules = r.map {|i| i.ident }
+ la_rules.concat r
+ else
+ @la_rules_i = @la_rules = nil
+ end
+ end
+
+ def conflict?
+ @conflict
+ end
+
+ def rruleid(rule)
+ if i = @la_rules.index(rule.ident)
+ @la_rules_i + i
+ else
+ puts '/// rruleid'
+ p self
+ p rule
+ p @rrules
+ p @la_rules_i
+ raise 'racc: fatal: cannot get reduce rule id'
+ end
+ end
+
+ def la=(la)
+ return unless @conflict
+ i = @la_rules_i
+ @ritems = r = []
+ @rrules.each do |rule|
+ r.push Item.new(rule, la[i])
+ i += 1
+ end
+ end
+
+ def rr_conflict(high, low, ctok)
+ c = RRconflict.new(@ident, high, low, ctok)
+
+ @rrconf ||= {}
+ if a = @rrconf[ctok]
+ a.push c
+ else
+ @rrconf[ctok] = [c]
+ end
+ end
+
+ def sr_conflict(shift, reduce)
+ c = SRconflict.new(@ident, shift, reduce)
+
+ @srconf ||= {}
+ if a = @srconf[shift]
+ a.push c
+ else
+ @srconf[shift] = [c]
+ end
+ end
+
+ def n_srconflicts
+ @srconf ? @srconf.size : 0
+ end
+
+ def n_rrconflicts
+ @rrconf ? @rrconf.size : 0
+ end
+
+ end # class State
+
+
+ #
+ # Represents a transition on the grammar.
+ # "Real goto" means a transition by nonterminal,
+ # but this class treats also terminal's.
+ # If one is a terminal transition, .ident returns nil.
+ #
+ class Goto
+ def initialize(ident, sym, from, to)
+ @ident = ident
+ @symbol = sym
+ @from_state = from
+ @to_state = to
+ end
+
+ attr_reader :ident
+ attr_reader :symbol
+ attr_reader :from_state
+ attr_reader :to_state
+
+ def inspect
+ "(#{@from_state.ident}-#{@symbol}->#{@to_state.ident})"
+ end
+ end
+
+
+ # LALR item. A set of rule and its lookahead tokens.
+ class Item
+ def initialize(rule, la)
+ @rule = rule
+ @la = la
+ end
+
+ attr_reader :rule
+ attr_reader :la
+
+ def each_la(tbl)
+ la = @la
+ 0.upto(la.size - 1) do |i|
+ (0..7).each do |ii|
+ if la[idx = i * 8 + ii] == 1
+ yield tbl[idx]
+ end
+ end
+ end
+ end
+ end
+
+
+ # The table of LALR actions. Actions are either of
+ # Shift, Reduce, Accept and Error.
+ class ActionTable
+
+ def initialize(rt, st)
+ @grammar = rt
+ @statetable = st
+
+ @reduce = []
+ @shift = []
+ @accept = nil
+ @error = nil
+ end
+
+ def init
+ @grammar.each do |rule|
+ @reduce.push Reduce.new(rule)
+ end
+ @statetable.each do |state|
+ @shift.push Shift.new(state)
+ end
+ @accept = Accept.new
+ @error = Error.new
+ end
+
+ def reduce_n
+ @reduce.size
+ end
+
+ def reduce(i)
+ case i
+ when Rule then i = i.ident
+ when Integer then ;
+ else
+ raise "racc: fatal: wrong class #{i.class} for reduce"
+ end
+
+ r = @reduce[i] or raise "racc: fatal: reduce action #{i.inspect} not exist"
+ r.incref
+ r
+ end
+
+ def each_reduce(&block)
+ @reduce.each(&block)
+ end
+
+ def shift_n
+ @shift.size
+ end
+
+ def shift(i)
+ case i
+ when State then i = i.ident
+ when Integer then ;
+ else
+ raise "racc: fatal: wrong class #{i.class} for shift"
+ end
+
+ @shift[i] or raise "racc: fatal: shift action #{i} does not exist"
+ end
+
+ def each_shift(&block)
+ @shift.each(&block)
+ end
+
+ attr_reader :accept
+ attr_reader :error
+
+ end
+
+
+ class Shift
+ def initialize(goto)
+ @goto_state = goto
+ end
+
+ attr_reader :goto_state
+
+ def goto_id
+ @goto_state.ident
+ end
+
+ def inspect
+ "<shift #{@goto_state.ident}>"
+ end
+ end
+
+
+ class Reduce
+ def initialize(rule)
+ @rule = rule
+ @refn = 0
+ end
+
+ attr_reader :rule
+ attr_reader :refn
+
+ def ruleid
+ @rule.ident
+ end
+
+ def inspect
+ "<reduce #{@rule.ident}>"
+ end
+
+ def incref
+ @refn += 1
+ end
+
+ def decref
+ @refn -= 1
+ raise 'racc: fatal: act.refn < 0' if @refn < 0
+ end
+ end
+
+ class Accept
+ def inspect
+ "<accept>"
+ end
+ end
+
+ class Error
+ def inspect
+ "<error>"
+ end
+ end
+
+ class SRconflict
+ def initialize(sid, shift, reduce)
+ @stateid = sid
+ @shift = shift
+ @reduce = reduce
+ end
+
+ attr_reader :stateid
+ attr_reader :shift
+ attr_reader :reduce
+
+ def to_s
+ sprintf('state %d: S/R conflict rule %d reduce and shift %s',
+ @stateid, @reduce.ruleid, @shift.to_s)
+ end
+ end
+
+ class RRconflict
+ def initialize(sid, high, low, tok)
+ @stateid = sid
+ @high_prec = high
+ @low_prec = low
+ @token = tok
+ end
+
+ attr_reader :stateid
+ attr_reader :high_prec
+ attr_reader :low_prec
+ attr_reader :token
+
+ def to_s
+ sprintf('state %d: R/R conflict with rule %d and %d on %s',
+ @stateid, @high_prec.ident, @low_prec.ident, @token.to_s)
+ end
+ end
+
+end
diff --git a/lib/racc/statetransitiontable.rb b/lib/racc/statetransitiontable.rb
new file mode 100644
index 0000000000..4252ba0184
--- /dev/null
+++ b/lib/racc/statetransitiontable.rb
@@ -0,0 +1,317 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/parser'
+
+unless Object.method_defined?(:funcall)
+ class Object
+ alias funcall __send__
+ end
+end
+
+module Racc
+
+ StateTransitionTable = Struct.new(:action_table,
+ :action_check,
+ :action_default,
+ :action_pointer,
+ :goto_table,
+ :goto_check,
+ :goto_default,
+ :goto_pointer,
+ :token_table,
+ :reduce_table,
+ :reduce_n,
+ :shift_n,
+ :nt_base,
+ :token_to_s_table,
+ :use_result_var,
+ :debug_parser)
+ class StateTransitionTable # reopen
+ def StateTransitionTable.generate(states)
+ StateTransitionTableGenerator.new(states).generate
+ end
+
+ def initialize(states)
+ super()
+ @states = states
+ @grammar = states.grammar
+ self.use_result_var = true
+ self.debug_parser = true
+ end
+
+ attr_reader :states
+ attr_reader :grammar
+
+ def parser_class
+ ParserClassGenerator.new(@states).generate
+ end
+
+ def token_value_table
+ h = {}
+ token_table().each do |sym, i|
+ h[sym.value] = i
+ end
+ h
+ end
+ end
+
+
+ class StateTransitionTableGenerator
+
+ def initialize(states)
+ @states = states
+ @grammar = states.grammar
+ end
+
+ def generate
+ t = StateTransitionTable.new(@states)
+ gen_action_tables t, @states
+ gen_goto_tables t, @grammar
+ t.token_table = token_table(@grammar)
+ t.reduce_table = reduce_table(@grammar)
+ t.reduce_n = @states.reduce_n
+ t.shift_n = @states.shift_n
+ t.nt_base = @grammar.nonterminal_base
+ t.token_to_s_table = @grammar.symbols.map {|sym| sym.to_s }
+ t
+ end
+
+ def reduce_table(grammar)
+ t = [0, 0, :racc_error]
+ grammar.each_with_index do |rule, idx|
+ next if idx == 0
+ t.push rule.size
+ t.push rule.target.ident
+ t.push(if rule.action.empty? # and @params.omit_action_call?
+ then :_reduce_none
+ else "_reduce_#{idx}".intern
+ end)
+ end
+ t
+ end
+
+ def token_table(grammar)
+ h = {}
+ grammar.symboltable.terminals.each do |t|
+ h[t] = t.ident
+ end
+ h
+ end
+
+ def gen_action_tables(t, states)
+ t.action_table = yytable = []
+ t.action_check = yycheck = []
+ t.action_default = yydefact = []
+ t.action_pointer = yypact = []
+ e1 = []
+ e2 = []
+ states.each do |state|
+ yydefact.push act2actid(state.defact)
+ if state.action.empty?
+ yypact.push nil
+ next
+ end
+ vector = []
+ state.action.each do |tok, act|
+ vector[tok.ident] = act2actid(act)
+ end
+ addent e1, vector, state.ident, yypact
+ end
+ set_table e1, e2, yytable, yycheck, yypact
+ end
+
+ def gen_goto_tables(t, grammar)
+ t.goto_table = yytable2 = []
+ t.goto_check = yycheck2 = []
+ t.goto_pointer = yypgoto = []
+ t.goto_default = yydefgoto = []
+ e1 = []
+ e2 = []
+ grammar.each_nonterminal do |tok|
+ tmp = []
+
+ # decide default
+ freq = Array.new(@states.size, 0)
+ @states.each do |state|
+ st = state.goto_table[tok]
+ if st
+ st = st.ident
+ freq[st] += 1
+ end
+ tmp[state.ident] = st
+ end
+ max = freq.max
+ if max > 1
+ default = freq.index(max)
+ tmp.map! {|i| default == i ? nil : i }
+ else
+ default = nil
+ end
+ yydefgoto.push default
+
+ # delete default value
+ tmp.pop until tmp.last or tmp.empty?
+ if tmp.compact.empty?
+ # only default
+ yypgoto.push nil
+ next
+ end
+
+ addent e1, tmp, (tok.ident - grammar.nonterminal_base), yypgoto
+ end
+ set_table e1, e2, yytable2, yycheck2, yypgoto
+ end
+
+ def addent(all, arr, chkval, ptr)
+ max = arr.size
+ min = nil
+ arr.each_with_index do |item, idx|
+ if item
+ min ||= idx
+ end
+ end
+ ptr.push(-7777) # mark
+ arr = arr[min...max]
+ all.push [arr, chkval, mkmapexp(arr), min, ptr.size - 1]
+ end
+
+ n = 2 ** 16
+ begin
+ Regexp.compile("a{#{n}}")
+ RE_DUP_MAX = n
+ rescue RegexpError
+ n /= 2
+ retry
+ end
+
+ def mkmapexp(arr)
+ i = ii = 0
+ as = arr.size
+ map = String.new
+ maxdup = RE_DUP_MAX
+ curr = nil
+ while i < as
+ ii = i + 1
+ if arr[i]
+ ii += 1 while ii < as and arr[ii]
+ curr = '-'
+ else
+ ii += 1 while ii < as and not arr[ii]
+ curr = '.'
+ end
+
+ offset = ii - i
+ if offset == 1
+ map << curr
+ else
+ while offset > maxdup
+ map << "#{curr}{#{maxdup}}"
+ offset -= maxdup
+ end
+ map << "#{curr}{#{offset}}" if offset > 1
+ end
+ i = ii
+ end
+ Regexp.compile(map, 'n')
+ end
+
+ def set_table(entries, dummy, tbl, chk, ptr)
+ upper = 0
+ map = '-' * 10240
+
+ # sort long to short
+ entries.sort_by!.with_index {|a,i| [-a[0].size, i] }
+
+ entries.each do |arr, chkval, expr, min, ptri|
+ if upper + arr.size > map.size
+ map << '-' * (arr.size + 1024)
+ end
+ idx = map.index(expr)
+ ptr[ptri] = idx - min
+ arr.each_with_index do |item, i|
+ if item
+ i += idx
+ tbl[i] = item
+ chk[i] = chkval
+ map[i] = ?o
+ end
+ end
+ upper = idx + arr.size
+ end
+ end
+
+ def act2actid(act)
+ case act
+ when Shift then act.goto_id
+ when Reduce then -act.ruleid
+ when Accept then @states.shift_n
+ when Error then @states.reduce_n * -1
+ else
+ raise "racc: fatal: wrong act type #{act.class} in action table"
+ end
+ end
+
+ end
+
+
+ class ParserClassGenerator
+
+ def initialize(states)
+ @states = states
+ @grammar = states.grammar
+ end
+
+ def generate
+ table = @states.state_transition_table
+ c = Class.new(::Racc::Parser)
+ c.const_set :Racc_arg, [table.action_table,
+ table.action_check,
+ table.action_default,
+ table.action_pointer,
+ table.goto_table,
+ table.goto_check,
+ table.goto_default,
+ table.goto_pointer,
+ table.nt_base,
+ table.reduce_table,
+ table.token_value_table,
+ table.shift_n,
+ table.reduce_n,
+ false]
+ c.const_set :Racc_token_to_s_table, table.token_to_s_table
+ c.const_set :Racc_debug_parser, true
+ define_actions c
+ c
+ end
+
+ private
+
+ def define_actions(c)
+ c.module_eval "def _reduce_none(vals, vstack) vals[0] end"
+ @grammar.each do |rule|
+ if rule.action.empty?
+ c.funcall(:alias_method, "_reduce_#{rule.ident}", :_reduce_none)
+ else
+ c.funcall(:define_method, "_racc_action_#{rule.ident}", &rule.action.proc)
+ c.module_eval(<<-End, __FILE__, __LINE__ + 1)
+ def _reduce_#{rule.ident}(vals, vstack)
+ _racc_action_#{rule.ident}(*vals)
+ end
+ End
+ end
+ end
+ end
+
+ end
+
+end # module Racc
diff --git a/lib/racc/static.rb b/lib/racc/static.rb
new file mode 100644
index 0000000000..bebbeb5aa6
--- /dev/null
+++ b/lib/racc/static.rb
@@ -0,0 +1,5 @@
+require 'racc'
+require 'racc/parser'
+require 'racc/grammarfileparser'
+require 'racc/parserfilegenerator'
+require 'racc/logfilegenerator'
diff --git a/lib/rdoc.rb b/lib/rdoc.rb
index af05b57116..2d3f8c1122 100644
--- a/lib/rdoc.rb
+++ b/lib/rdoc.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
$DEBUG_RDOC = nil
# :main: README.rdoc
@@ -62,10 +62,7 @@ module RDoc
class Error < RuntimeError; end
- ##
- # RDoc version you are using
-
- VERSION = '6.0.0.beta3'
+ require 'rdoc/version'
##
# Method visibilities
@@ -123,9 +120,28 @@ module RDoc
end
end
- autoload :RDoc, 'rdoc/rdoc'
+ def self.home
+ rdoc_dir = begin
+ File.expand_path('~/.rdoc')
+ rescue ArgumentError
+ end
+
+ if File.directory?(rdoc_dir)
+ rdoc_dir
+ else
+ begin
+ # XDG
+ xdg_data_home = ENV["XDG_DATA_HOME"] || File.join(File.expand_path("~"), '.local', 'share')
+ unless File.exist?(xdg_data_home)
+ FileUtils.mkdir_p xdg_data_home
+ end
+ File.join xdg_data_home, "rdoc"
+ rescue Errno::EACCES
+ end
+ end
+ end
- autoload :TestCase, 'rdoc/test_case'
+ autoload :RDoc, 'rdoc/rdoc'
autoload :CrossReference, 'rdoc/cross_reference'
autoload :ERBIO, 'rdoc/erbio'
@@ -148,12 +164,11 @@ module RDoc
autoload :KNOWN_CLASSES, 'rdoc/known_classes'
- autoload :RipperStateLex, 'rdoc/parser/ripper_state_lex'
autoload :TokenStream, 'rdoc/token_stream'
autoload :Comment, 'rdoc/comment'
- autoload :I18n, 'rdoc/i18n'
+ require 'rdoc/i18n'
# code objects
#
diff --git a/lib/rdoc/.document b/lib/rdoc/.document
index 41333c6411..6b5e1b21a5 100644
--- a/lib/rdoc/.document
+++ b/lib/rdoc/.document
@@ -1 +1,2 @@
*.rb
+parser
diff --git a/lib/rdoc/alias.rb b/lib/rdoc/alias.rb
index 1e06fb96e5..858e053049 100644
--- a/lib/rdoc/alias.rb
+++ b/lib/rdoc/alias.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Represent an alias, which is an old_name/new_name pair associated with a
# particular context
diff --git a/lib/rdoc/anon_class.rb b/lib/rdoc/anon_class.rb
index 098bfdfcf9..d02a38c2cf 100644
--- a/lib/rdoc/anon_class.rb
+++ b/lib/rdoc/anon_class.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# An anonymous class like:
#
diff --git a/lib/rdoc/any_method.rb b/lib/rdoc/any_method.rb
index c5cb9c079a..562e68461c 100644
--- a/lib/rdoc/any_method.rb
+++ b/lib/rdoc/any_method.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# AnyMethod is the base class for objects representing methods
@@ -26,12 +26,6 @@ class RDoc::AnyMethod < RDoc::MethodAttr
attr_accessor :c_function
- ##
- # Different ways to call this method
-
- attr_reader :call_seq
-
- ##
# Parameters for this method
attr_accessor :params
@@ -94,6 +88,19 @@ class RDoc::AnyMethod < RDoc::MethodAttr
end
##
+ # Different ways to call this method
+
+ def call_seq
+ unless call_seq = _call_seq
+ call_seq = is_alias_for._call_seq if is_alias_for
+ end
+
+ return unless call_seq
+
+ deduplicate_call_seq(call_seq)
+ end
+
+ ##
# Sets the different ways you can call this method. If an empty +call_seq+
# is given nil is assumed.
#
@@ -244,9 +251,9 @@ class RDoc::AnyMethod < RDoc::MethodAttr
if @block_params then
# If this method has explicit block parameters, remove any explicit
# &block
- params.sub!(/,?\s*&\w+/, '')
+ params = params.sub(/,?\s*&\w+/, '')
else
- params.sub!(/\&(\w+)/, '\1')
+ params = params.sub(/\&(\w+)/, '\1')
end
params = params.gsub(/\s+/, '').split(',').reject(&:empty?)
@@ -265,7 +272,7 @@ class RDoc::AnyMethod < RDoc::MethodAttr
params = params.sub(/(\|[^|]+\|)\s*\.\.\.\s*(end|\})/, '\1 \2')
elsif @params then
params = @params.gsub(/\s*\#.*/, '')
- params = params.tr("\n", " ").squeeze(" ")
+ params = params.tr_s("\n ", " ")
params = "(#{params})" unless params[0] == ?(
else
params = ''
@@ -274,11 +281,11 @@ class RDoc::AnyMethod < RDoc::MethodAttr
if @block_params then
# If this method has explicit block parameters, remove any explicit
# &block
- params.sub!(/,?\s*&\w+/, '')
+ params = params.sub(/,?\s*&\w+/, '')
- block = @block_params.tr("\n", " ").squeeze(" ")
+ block = @block_params.tr_s("\n ", " ")
if block[0] == ?(
- block.sub!(/^\(/, '').sub!(/\)/, '')
+ block = block.sub(/^\(/, '').sub(/\)/, '')
end
params << " { |#{block}| ... }"
end
@@ -312,5 +319,43 @@ class RDoc::AnyMethod < RDoc::MethodAttr
@superclass_method
end
-end
+ protected
+
+ ##
+ # call_seq without deduplication and alias lookup.
+
+ def _call_seq
+ @call_seq if defined?(@call_seq) && @call_seq
+ end
+
+ private
+
+ ##
+ # call_seq with alias examples information removed, if this
+ # method is an alias method.
+
+ def deduplicate_call_seq(call_seq)
+ return call_seq unless is_alias_for || !aliases.empty?
+
+ method_name = self.name
+ method_name = method_name[0, 1] if method_name =~ /\A\[/
+ entries = call_seq.split "\n"
+
+ ignore = aliases.map(&:name)
+ if is_alias_for
+ ignore << is_alias_for.name
+ ignore.concat is_alias_for.aliases.map(&:name)
+ end
+ ignore.map! { |n| n =~ /\A\[/ ? n[0, 1] : n}
+ ignore.delete(method_name)
+ ignore = Regexp.union(ignore)
+
+ matching = entries.reject do |entry|
+ entry =~ /^\w*\.?#{ignore}/ or
+ entry =~ /\s#{ignore}\s/
+ end
+
+ matching.join "\n"
+ end
+end
diff --git a/lib/rdoc/attr.rb b/lib/rdoc/attr.rb
index f77a5c04a7..f780b3b976 100644
--- a/lib/rdoc/attr.rb
+++ b/lib/rdoc/attr.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# An attribute created by \#attr, \#attr_reader, \#attr_writer or
# \#attr_accessor
diff --git a/lib/rdoc/class_module.rb b/lib/rdoc/class_module.rb
index 5881d6cf24..7609080fbf 100644
--- a/lib/rdoc/class_module.rb
+++ b/lib/rdoc/class_module.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# ClassModule is the base class for objects representing either a class or a
# module.
@@ -136,7 +136,9 @@ class RDoc::ClassModule < RDoc::Context
normalize_comment comment
end
- @comment_location.delete_if { |(_, l)| l == location }
+ if location.parser == RDoc::Parser::C
+ @comment_location.delete_if { |(_, l)| l == location }
+ end
@comment_location << [comment, location]
@@ -208,7 +210,7 @@ class RDoc::ClassModule < RDoc::Context
normalize_comment comment
end
- comment = "#{@comment}\n---\n#{comment}" unless @comment.empty?
+ comment = "#{@comment.to_s}\n---\n#{comment.to_s}" unless @comment.empty?
super comment
end
diff --git a/lib/rdoc/code_object.rb b/lib/rdoc/code_object.rb
index 11c682b7fa..aeb4b4762e 100644
--- a/lib/rdoc/code_object.rb
+++ b/lib/rdoc/code_object.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Base class for the RDoc code tree.
#
@@ -144,7 +144,7 @@ class RDoc::CodeObject
# HACK correct fix is to have #initialize create @comment
# with the correct encoding
if String === @comment and @comment.empty? then
- @comment.force_encoding comment.encoding
+ @comment = RDoc::Encoding.change_encoding @comment, comment.encoding
end
@comment
end
diff --git a/lib/rdoc/code_objects.rb b/lib/rdoc/code_objects.rb
index 564849e1d1..434a25ac7f 100644
--- a/lib/rdoc/code_objects.rb
+++ b/lib/rdoc/code_objects.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
# This file was used to load all the RDoc::CodeObject subclasses at once. Now
# autoload handles this.
diff --git a/lib/rdoc/comment.rb b/lib/rdoc/comment.rb
index c655763b3e..9e90999eac 100644
--- a/lib/rdoc/comment.rb
+++ b/lib/rdoc/comment.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A comment holds the text comment for a RDoc::CodeObject and provides a
# unified way of cleaning it up and parsing it into an RDoc::Markup::Document.
@@ -24,6 +24,11 @@ class RDoc::Comment
attr_accessor :location
##
+ # Line where this Comment was written
+
+ attr_accessor :line
+
+ ##
# For duck-typing when merging classes at load time
alias file location # :nodoc:
@@ -34,6 +39,11 @@ class RDoc::Comment
attr_reader :text
##
+ # Alias for text
+
+ alias to_s text
+
+ ##
# Overrides the content returned by #parse. Use when there is no #text
# source for this comment
@@ -43,9 +53,10 @@ class RDoc::Comment
# Creates a new comment with +text+ that is found in the RDoc::TopLevel
# +location+.
- def initialize text = nil, location = nil
+ def initialize text = nil, location = nil, language = nil
@location = location
- @text = text
+ @text = text.nil? ? nil : text.dup
+ @language = language
@document = nil
@format = 'rdoc'
@@ -114,10 +125,14 @@ class RDoc::Comment
method.call_seq = seq.chomp
- elsif @text.sub!(/^\s*:?call-seq:(.*?)(^\s*$|\z)/m, '') then
- seq = $1
- seq.gsub!(/^\s*/, '')
- method.call_seq = seq
+ else
+ regexp = /^\s*:?call-seq:(.*?)(^\s*$|\z)/m
+ if regexp =~ @text then
+ @text = @text.sub(regexp, '')
+ seq = $1
+ seq.gsub!(/^\s*/, '')
+ method.call_seq = seq
+ end
end
method
@@ -133,8 +148,14 @@ class RDoc::Comment
##
# HACK dubious
- def force_encoding encoding
- @text.force_encoding encoding
+ def encode! encoding
+ # TODO: Remove this condition after Ruby 2.2 EOL
+ if RUBY_VERSION < '2.3.0'
+ @text = @text.force_encoding encoding
+ else
+ @text = String.new @text, encoding: encoding
+ end
+ self
end
##
@@ -200,7 +221,7 @@ class RDoc::Comment
def remove_private
# Workaround for gsub encoding for Ruby 1.9.2 and earlier
empty = ''
- empty.force_encoding @text.encoding
+ empty = RDoc::Encoding.change_encoding empty, @text.encoding
@text = @text.gsub(%r%^\s*([#*]?)--.*?^\s*(\1)\+\+\n?%m, empty)
@text = @text.sub(%r%^\s*[#*]?--.*%m, '')
@@ -216,7 +237,7 @@ class RDoc::Comment
@text.nil? and @document
@document = nil
- @text = text
+ @text = text.nil? ? nil : text.dup
end
##
diff --git a/lib/rdoc/constant.rb b/lib/rdoc/constant.rb
index 7e1e10da72..0c3d7505a1 100644
--- a/lib/rdoc/constant.rb
+++ b/lib/rdoc/constant.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A constant
diff --git a/lib/rdoc/context.rb b/lib/rdoc/context.rb
index 3294b2561c..b3caa53aa1 100644
--- a/lib/rdoc/context.rb
+++ b/lib/rdoc/context.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'cgi'
##
@@ -239,7 +239,7 @@ class RDoc::Context < RDoc::CodeObject
if known then
known.comment = attribute.comment if known.comment.empty?
- elsif registered = @methods_hash[attribute.pretty_name << '='] and
+ elsif registered = @methods_hash[attribute.pretty_name + '='] and
RDoc::Attr === registered then
registered.rw = 'RW'
else
@@ -249,7 +249,7 @@ class RDoc::Context < RDoc::CodeObject
end
if attribute.rw.index 'W' then
- key = attribute.pretty_name << '='
+ key = attribute.pretty_name + '='
known = @methods_hash[key]
if known then
@@ -407,6 +407,7 @@ class RDoc::Context < RDoc::CodeObject
mod.section = current_section # TODO declaring context? something is
# wrong here...
mod.parent = self
+ mod.full_name = nil
mod.store = @store
unless @done_documenting then
@@ -414,6 +415,10 @@ class RDoc::Context < RDoc::CodeObject
# this must be done AFTER adding mod to its parent, so that the full
# name is correct:
all_hash[mod.full_name] = mod
+ if @store.unmatched_constant_alias[mod.full_name] then
+ to, file = @store.unmatched_constant_alias[mod.full_name]
+ add_module_alias mod, mod.name, to, file
+ end
end
mod
@@ -511,40 +516,52 @@ class RDoc::Context < RDoc::CodeObject
end
##
+ # Adds a module by +RDoc::NormalModule+ instance. See also #add_module.
+
+ def add_module_by_normal_module(mod)
+ add_class_or_module mod, @modules, @store.modules_hash
+ end
+
+ ##
# Adds an alias from +from+ (a class or module) to +name+ which was defined
# in +file+.
- def add_module_alias from, name, file
+ def add_module_alias from, from_name, to, file
return from if @done_documenting
- to_name = child_name name
+ to_full_name = child_name to.name
# if we already know this name, don't register an alias:
# see the metaprogramming in lib/active_support/basic_object.rb,
# where we already know BasicObject is a class when we find
# BasicObject = BlankSlate
- return from if @store.find_class_or_module to_name
+ return from if @store.find_class_or_module to_full_name
+
+ unless from
+ @store.unmatched_constant_alias[child_name(from_name)] = [to, file]
+ return to
+ end
- to = from.dup
- to.name = name
- to.full_name = nil
+ new_to = from.dup
+ new_to.name = to.name
+ new_to.full_name = nil
- if to.module? then
- @store.modules_hash[to_name] = to
- @modules[name] = to
+ if new_to.module? then
+ @store.modules_hash[to_full_name] = new_to
+ @modules[to.name] = new_to
else
- @store.classes_hash[to_name] = to
- @classes[name] = to
+ @store.classes_hash[to_full_name] = new_to
+ @classes[to.name] = new_to
end
# Registers a constant for this alias. The constant value and comment
# will be updated later, when the Ruby parser adds the constant
- const = RDoc::Constant.new name, nil, to.comment
+ const = RDoc::Constant.new to.name, nil, new_to.comment
const.record_location file
const.is_alias_for = from
add_constant const
- to
+ new_to
end
##
@@ -863,7 +880,13 @@ class RDoc::Context < RDoc::CodeObject
# Finds a method named +name+ with singleton value +singleton+.
def find_method(name, singleton)
- @method_list.find { |m| m.name == name && m.singleton == singleton }
+ @method_list.find { |m|
+ if m.singleton
+ m.name == name && m.singleton == singleton
+ else
+ m.name == name && !m.singleton && !singleton
+ end
+ }
end
##
@@ -969,11 +992,19 @@ class RDoc::Context < RDoc::CodeObject
##
# Instance methods
+
+ def instance_methods
+ @instance_methods ||= method_list.reject { |a| a.singleton }
+ end
+
+ ##
+ # Instance methods
#--
- # TODO rename to instance_methods
+ # TODO remove this later
def instance_method_list
- @instance_method_list ||= method_list.reject { |a| a.singleton }
+ warn '#instance_method_list is obsoleted, please use #instance_methods'
+ @instance_methods ||= method_list.reject { |a| a.singleton }
end
##
diff --git a/lib/rdoc/context/section.rb b/lib/rdoc/context/section.rb
index 7c3c8c603d..5fef4a9ffc 100644
--- a/lib/rdoc/context/section.rb
+++ b/lib/rdoc/context/section.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A section of documentation like:
#
@@ -34,8 +34,6 @@ class RDoc::Context::Section
attr_reader :title
- @@sequence = "SEC00000"
-
##
# Creates a new section with +title+ and +comment+
@@ -43,9 +41,6 @@ class RDoc::Context::Section
@parent = parent
@title = title ? title.strip : title
- @@sequence.succ!
- @sequence = @@sequence.dup
-
@comments = []
add_comment comment
@@ -233,13 +228,5 @@ class RDoc::Context::Section
end
end
- ##
- # Section sequence number (deprecated)
-
- def sequence
- warn "RDoc::Context::Section#sequence is deprecated, use #aref"
- @sequence
- end
-
end
diff --git a/lib/rdoc/cross_reference.rb b/lib/rdoc/cross_reference.rb
index 0e40d23159..99a64cd99a 100644
--- a/lib/rdoc/cross_reference.rb
+++ b/lib/rdoc/cross_reference.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# RDoc::CrossReference is a reusable way to create cross references for names.
@@ -19,16 +19,16 @@ class RDoc::CrossReference
#
# See CLASS_REGEXP_STR
- METHOD_REGEXP_STR = '([a-z]\w*[!?=]?|%|===|\[\]=?|<<|>>)(?:\([\w.+*/=<>-]*\))?'
+ METHOD_REGEXP_STR = '([a-z]\w*[!?=]?|%|===|\[\]=?|<<|>>|\+@|-@|-|\+|\*)(?:\([\w.+*/=<>-]*\))?'
##
# Regular expressions matching text that should potentially have
- # cross-reference links generated are passed to add_special. Note that
- # these expressions are meant to pick up text for which cross-references
+ # cross-reference links generated are passed to add_regexp_handling. Note
+ # that these expressions are meant to pick up text for which cross-references
# have been suppressed, since the suppression characters are removed by the
# code that is triggered.
- CROSSREF_REGEXP = /(?:^|\s)
+ CROSSREF_REGEXP = /(?:^|[\s()])
(
(?:
# A::B::C.meth
@@ -76,7 +76,7 @@ class RDoc::CrossReference
# Version of CROSSREF_REGEXP used when <tt>--hyperlink-all</tt> is specified.
ALL_CROSSREF_REGEXP = /
- (?:^|\s)
+ (?:^|[\s()])
(
(?:
# A::B::C.meth
@@ -127,23 +127,41 @@ class RDoc::CrossReference
if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then
type = $2
- type = '' if type == '.' # will find either #method or ::method
- method = "#{type}#{$3}"
+ if '.' == type # will find either #method or ::method
+ method = $3
+ else
+ method = "#{type}#{$3}"
+ end
container = @context.find_symbol_module($1)
elsif /^([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then
type = $1
- type = '' if type == '.'
- method = "#{type}#{$2}"
+ if '.' == type
+ method = $2
+ else
+ method = "#{type}#{$2}"
+ end
container = @context
else
+ type = nil
container = nil
end
if container then
- ref = container.find_local_symbol method
-
- unless ref || RDoc::TopLevel === container then
- ref = container.find_ancestor_local_symbol method
+ unless RDoc::TopLevel === container then
+ if '.' == type then
+ if 'new' == method then # AnyClassName.new will be class method
+ ref = container.find_local_symbol method
+ ref = container.find_ancestor_local_symbol method unless ref
+ else
+ ref = container.find_local_symbol "::#{method}"
+ ref = container.find_ancestor_local_symbol "::#{method}" unless ref
+ ref = container.find_local_symbol "##{method}" unless ref
+ ref = container.find_ancestor_local_symbol "##{method}" unless ref
+ end
+ else
+ ref = container.find_local_symbol method
+ ref = container.find_ancestor_local_symbol method unless ref
+ end
end
end
@@ -155,7 +173,7 @@ class RDoc::CrossReference
end unless ref
# Try a page name
- ref = @store.page name if not ref and name =~ /^\w+$/
+ ref = @store.page name if not ref and name =~ /^[\w.]+$/
ref = nil if RDoc::Alias === ref # external alias, can't link to it
diff --git a/lib/rdoc/encoding.rb b/lib/rdoc/encoding.rb
index 44881d043c..cf60badd24 100644
--- a/lib/rdoc/encoding.rb
+++ b/lib/rdoc/encoding.rb
@@ -1,5 +1,5 @@
# coding: US-ASCII
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# This class is a wrapper around File IO and Encoding that helps RDoc load
@@ -7,6 +7,18 @@
module RDoc::Encoding
+ HEADER_REGEXP = /^
+ (?:
+ \A\#!.*\n
+ |
+ ^\#\s+frozen[-_]string[-_]literal[=:].+\n
+ |
+ ^\#[^\n]+\b(?:en)?coding[=:]\s*(?<name>[^\s;]+).*\n
+ |
+ <\?xml[^?]*encoding=(?<quote>["'])(?<name>.*?)\k<quote>.*\n
+ )+
+ /xi # :nodoc:
+
##
# Reads the contents of +filename+ and handles any encoding directives in
# the file.
@@ -18,31 +30,32 @@ module RDoc::Encoding
# unknown character in the target encoding will be replaced with '?'
def self.read_file filename, encoding, force_transcode = false
- content = open filename, "rb" do |f| f.read end
+ content = File.open filename, "rb" do |f| f.read end
content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/
utf8 = content.sub!(/\A\xef\xbb\xbf/, '')
- RDoc::Encoding.set_encoding content
+ enc = RDoc::Encoding.detect_encoding content
+ content = RDoc::Encoding.change_encoding content, enc if enc
begin
encoding ||= Encoding.default_external
orig_encoding = content.encoding
if not orig_encoding.ascii_compatible? then
- content.encode! encoding
+ content = content.encode encoding
elsif utf8 then
- content.force_encoding Encoding::UTF_8
- content.encode! encoding
+ content = RDoc::Encoding.change_encoding content, Encoding::UTF_8
+ content = content.encode encoding
else
# assume the content is in our output encoding
- content.force_encoding encoding
+ content = RDoc::Encoding.change_encoding content, encoding
end
unless content.valid_encoding? then
# revert and try to transcode
- content.force_encoding orig_encoding
- content.encode! encoding
+ content = RDoc::Encoding.change_encoding content, orig_encoding
+ content = content.encode encoding
end
unless content.valid_encoding? then
@@ -52,10 +65,11 @@ module RDoc::Encoding
rescue Encoding::InvalidByteSequenceError,
Encoding::UndefinedConversionError => e
if force_transcode then
- content.force_encoding orig_encoding
- content.encode!(encoding,
- :invalid => :replace, :undef => :replace,
- :replace => '?')
+ content = RDoc::Encoding.change_encoding content, orig_encoding
+ content = content.encode(encoding,
+ :invalid => :replace,
+ :undef => :replace,
+ :replace => '?')
return content
else
warn "unable to convert #{e.message} for #{filename}, skipping"
@@ -77,32 +91,46 @@ module RDoc::Encoding
first_line = $1
if first_line =~ /\A# +frozen[-_]string[-_]literal[=:].+$/i
- string.sub! first_line, ''
+ string = string.sub first_line, ''
end
+
+ string
end
##
- # Sets the encoding of +string+ based on the magic comment
+ # Detects the encoding of +string+ based on the magic comment
- def self.set_encoding string
- remove_frozen_string_literal string
-
- string =~ /\A(?:#!.*\n)?(.*\n)/
+ def self.detect_encoding string
+ result = HEADER_REGEXP.match string
+ name = result && result[:name]
- first_line = $1
-
- name = case first_line
- when /^<\?xml[^?]*encoding=(["'])(.*?)\1/ then $2
- when /\b(?:en)?coding[=:]\s*([^\s;]+)/i then $1
- else return
- end
+ name ? Encoding.find(name) : nil
+ end
- string.sub! first_line, ''
+ ##
+ # Removes magic comments and shebang
- remove_frozen_string_literal string
+ def self.remove_magic_comment string
+ string.sub HEADER_REGEXP do |s|
+ s.gsub(/[^\n]/, '')
+ end
+ end
- enc = Encoding.find name
- string.force_encoding enc if enc
+ ##
+ # Changes encoding based on +encoding+ without converting and returns new
+ # string
+
+ def self.change_encoding text, encoding
+ if text.kind_of? RDoc::Comment
+ text.encode! encoding
+ else
+ # TODO: Remove this condition after Ruby 2.2 EOL
+ if RUBY_VERSION < '2.3.0'
+ text.force_encoding encoding
+ else
+ String.new text, encoding: encoding
+ end
+ end
end
end
diff --git a/lib/rdoc/erb_partial.rb b/lib/rdoc/erb_partial.rb
index d17dda20a9..d6e3f41b7e 100644
--- a/lib/rdoc/erb_partial.rb
+++ b/lib/rdoc/erb_partial.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Allows an ERB template to be rendered in the context (binding) of an
# existing ERB template evaluation.
@@ -12,7 +12,7 @@ class RDoc::ERBPartial < ERB
def set_eoutvar compiler, eoutvar = '_erbout'
super
- compiler.pre_cmd = ["#{eoutvar} ||= ''"]
+ compiler.pre_cmd = ["#{eoutvar} ||= +''"]
end
end
diff --git a/lib/rdoc/erbio.rb b/lib/rdoc/erbio.rb
index a2aaa90e67..0d5f96e133 100644
--- a/lib/rdoc/erbio.rb
+++ b/lib/rdoc/erbio.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'erb'
##
@@ -9,7 +9,7 @@ require 'erb'
#
# erbio = RDoc::ERBIO.new '<%= "hello world" %>', nil, nil
#
-# open 'hello.txt', 'w' do |io|
+# File.open 'hello.txt', 'w' do |io|
# erbio.result binding
# end
#
@@ -20,8 +20,12 @@ class RDoc::ERBIO < ERB
##
# Defaults +eoutvar+ to 'io', otherwise is identical to ERB's initialize
- def initialize str, safe_level = nil, trim_mode = nil, eoutvar = 'io'
- super
+ def initialize str, safe_level = nil, legacy_trim_mode = nil, legacy_eoutvar = 'io', trim_mode: nil, eoutvar: 'io'
+ if RUBY_VERSION >= '2.6'
+ super(str, trim_mode: trim_mode, eoutvar: eoutvar)
+ else
+ super(str, safe_level, legacy_trim_mode, legacy_eoutvar)
+ end
end
##
diff --git a/lib/rdoc/extend.rb b/lib/rdoc/extend.rb
index 30b51a1dbd..e1b182902e 100644
--- a/lib/rdoc/extend.rb
+++ b/lib/rdoc/extend.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A Module extension to a class with \#extend
#
diff --git a/lib/rdoc/generator.rb b/lib/rdoc/generator.rb
index 6efc5e4474..340dcbf7ae 100644
--- a/lib/rdoc/generator.rb
+++ b/lib/rdoc/generator.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# RDoc uses generators to turn parsed source code in the form of an
# RDoc::CodeObject tree into some form of output. RDoc comes with the HTML
diff --git a/lib/rdoc/generator/darkfish.rb b/lib/rdoc/generator/darkfish.rb
index e961518fcc..b46861d009 100644
--- a/lib/rdoc/generator/darkfish.rb
+++ b/lib/rdoc/generator/darkfish.rb
@@ -1,10 +1,10 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
# -*- mode: ruby; ruby-indent-level: 2; tab-width: 2 -*-
require 'erb'
require 'fileutils'
require 'pathname'
-require 'rdoc/generator/markup'
+require_relative 'markup'
##
# Darkfish RDoc HTML Generator
@@ -269,7 +269,7 @@ class RDoc::Generator::Darkfish
@options.static_path.each do |path|
unless File.directory? path then
- FileUtils.install path, @outputdir, fu_options.merge(:mode => 0644)
+ FileUtils.install path, @outputdir, **fu_options.merge(:mode => 0644)
next
end
@@ -278,9 +278,9 @@ class RDoc::Generator::Darkfish
dest_file = @outputdir + entry
if File.directory? entry then
- FileUtils.mkdir_p entry, fu_options
+ FileUtils.mkdir_p entry, **fu_options
else
- FileUtils.install entry, dest_file, fu_options.merge(:mode => 0644)
+ FileUtils.install entry, dest_file, **fu_options.merge(:mode => 0644)
end
end
end
@@ -313,12 +313,16 @@ class RDoc::Generator::Darkfish
search_index_rel_prefix = rel_prefix
search_index_rel_prefix += @asset_rel_path if @file_output
- # suppress 1.9.3 warning
- asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path
+ asset_rel_prefix = rel_prefix + @asset_rel_path
@title = @options.title
- render_template template_file, out_file do |io| binding end
+ render_template template_file, out_file do |io|
+ here = binding
+ # suppress 1.9.3 warning
+ here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
+ here
+ end
rescue => e
error = RDoc::Error.new \
"error generating index.html: #{e.message} (#{e.class})"
@@ -343,14 +347,19 @@ class RDoc::Generator::Darkfish
search_index_rel_prefix = rel_prefix
search_index_rel_prefix += @asset_rel_path if @file_output
- # suppress 1.9.3 warning
- asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path
- svninfo = svninfo = get_svninfo(current)
+ asset_rel_prefix = rel_prefix + @asset_rel_path
+ svninfo = get_svninfo(current)
@title = "#{klass.type} #{klass.full_name} - #{@options.title}"
debug_msg " rendering #{out_file}"
- render_template template_file, out_file do |io| binding end
+ render_template template_file, out_file do |io|
+ here = binding
+ # suppress 1.9.3 warning
+ here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
+ here.local_variable_set(:svninfo, svninfo)
+ here
+ end
end
##
@@ -416,8 +425,7 @@ class RDoc::Generator::Darkfish
search_index_rel_prefix = rel_prefix
search_index_rel_prefix += @asset_rel_path if @file_output
- # suppress 1.9.3 warning
- asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path
+ asset_rel_prefix = rel_prefix + @asset_rel_path
unless filepage_file then
if file.text? then
@@ -434,7 +442,13 @@ class RDoc::Generator::Darkfish
@title += " - #{@options.title}"
template_file ||= filepage_file
- render_template template_file, out_file do |io| binding end
+ render_template template_file, out_file do |io|
+ here = binding
+ # suppress 1.9.3 warning
+ here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
+ here.local_variable_set(:current, current)
+ here
+ end
end
rescue => e
error =
@@ -458,14 +472,19 @@ class RDoc::Generator::Darkfish
search_index_rel_prefix = rel_prefix
search_index_rel_prefix += @asset_rel_path if @file_output
- # suppress 1.9.3 warning
- current = current = file
- asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path
+ current = file
+ asset_rel_prefix = rel_prefix + @asset_rel_path
@title = "#{file.page_name} - #{@options.title}"
debug_msg " rendering #{out_file}"
- render_template template_file, out_file do |io| binding end
+ render_template template_file, out_file do |io|
+ here = binding
+ # suppress 1.9.3 warning
+ here.local_variable_set(:current, current)
+ here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
+ here
+ end
end
##
@@ -483,12 +502,16 @@ class RDoc::Generator::Darkfish
search_index_rel_prefix = rel_prefix
search_index_rel_prefix += @asset_rel_path if @file_output
- # suppress 1.9.3 warning
- asset_rel_prefix = asset_rel_prefix = ''
+ asset_rel_prefix = ''
@title = 'Not Found'
- render_template template_file do |io| binding end
+ render_template template_file do |io|
+ here = binding
+ # suppress 1.9.3 warning
+ here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
+ here
+ end
rescue => e
error = RDoc::Error.new \
"error generating servlet_not_found: #{e.message} (#{e.class})"
@@ -540,12 +563,16 @@ class RDoc::Generator::Darkfish
search_index_rel_prefix = rel_prefix
search_index_rel_prefix += @asset_rel_path if @file_output
- # suppress 1.9.3 warning
- asset_rel_prefix = asset_rel_prefix = rel_prefix + @asset_rel_path
+ asset_rel_prefix = rel_prefix + @asset_rel_path
@title = "Table of Contents - #{@options.title}"
- render_template template_file, out_file do |io| binding end
+ render_template template_file, out_file do |io|
+ here = binding
+ # suppress 1.9.3 warning
+ here.local_variable_set(:asset_rel_prefix, asset_rel_prefix)
+ here
+ end
rescue => e
error = RDoc::Error.new \
"error generating table_of_contents.html: #{e.message} (#{e.class})"
@@ -558,16 +585,16 @@ class RDoc::Generator::Darkfish
return unless source.exist?
begin
- FileUtils.mkdir_p File.dirname(destination), options
+ FileUtils.mkdir_p File.dirname(destination), **options
begin
- FileUtils.ln source, destination, options
+ FileUtils.ln source, destination, **options
rescue Errno::EEXIST
FileUtils.rm destination
retry
end
rescue
- FileUtils.cp source, destination, options
+ FileUtils.cp source, destination, **options
end
end
@@ -751,7 +778,11 @@ class RDoc::Generator::Darkfish
erbout = "_erbout_#{file_var}"
end
- template = klass.new template, nil, '<>', erbout
+ if RUBY_VERSION >= '2.6'
+ template = klass.new template, trim_mode: '-', eoutvar: erbout
+ else
+ template = klass.new template, nil, '-', erbout
+ end
@template_cache[file] = template
template
end
diff --git a/lib/rdoc/generator/json_index.rb b/lib/rdoc/generator/json_index.rb
index ea9384e6d3..3a1000033d 100644
--- a/lib/rdoc/generator/json_index.rb
+++ b/lib/rdoc/generator/json_index.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'json'
begin
require 'zlib'
@@ -147,12 +147,15 @@ class RDoc::Generator::JsonIndex
JSON.dump data, io, 0
end
+ unless ENV['SOURCE_DATE_EPOCH'].nil?
+ index_file.utime index_file.atime, Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime
+ end
Dir.chdir @template_dir do
Dir['**/*.js'].each do |source|
dest = File.join out_dir, source
- FileUtils.install source, dest, :mode => 0644, :verbose => $DEBUG_RDOC
+ FileUtils.install source, dest, :mode => 0644, :preserve => true, :verbose => $DEBUG_RDOC
end
end
end
@@ -161,7 +164,7 @@ class RDoc::Generator::JsonIndex
# Compress the search_index.js file using gzip
def generate_gzipped
- return unless defined?(Zlib)
+ return if @options.dry_run or not defined?(Zlib)
debug_msg "Compressing generated JSON index"
out_dir = @base_dir + @options.op_dir
diff --git a/lib/rdoc/generator/markup.rb b/lib/rdoc/generator/markup.rb
index 3ca423bb69..41e132450d 100644
--- a/lib/rdoc/generator/markup.rb
+++ b/lib/rdoc/generator/markup.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Handle common RDoc::Markup tasks for various CodeObjects
#
@@ -65,16 +65,6 @@ end
class RDoc::MethodAttr
- @add_line_numbers = false
-
- class << self
- ##
- # Allows controlling whether <tt>#markup_code</tt> adds line numbers to
- # the source code.
-
- attr_accessor :add_line_numbers
- end
-
##
# Prepend +src+ with line numbers. Relies on the first line of a source
# code listing having:
@@ -106,7 +96,7 @@ class RDoc::MethodAttr
##
# Turns the method's token stream into HTML.
#
- # Prepends line numbers if +add_line_numbers+ is true.
+ # Prepends line numbers if +options.line_numbers+ is true.
def markup_code
return '' unless @token_stream
@@ -126,7 +116,7 @@ class RDoc::MethodAttr
end
src.gsub!(/^#{' ' * indent}/, '') if indent > 0
- add_line_numbers(src) if RDoc::MethodAttr.add_line_numbers
+ add_line_numbers(src) if options.line_numbers
src
end
diff --git a/lib/rdoc/generator/pot.rb b/lib/rdoc/generator/pot.rb
index e2cf22d730..bee1133b07 100644
--- a/lib/rdoc/generator/pot.rb
+++ b/lib/rdoc/generator/pot.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Generates a POT file.
#
@@ -91,8 +91,8 @@ class RDoc::Generator::POT
extractor.extract
end
- autoload :MessageExtractor, 'rdoc/generator/pot/message_extractor'
- autoload :PO, 'rdoc/generator/pot/po'
- autoload :POEntry, 'rdoc/generator/pot/po_entry'
+ require_relative 'pot/message_extractor'
+ require_relative 'pot/po'
+ require_relative 'pot/po_entry'
end
diff --git a/lib/rdoc/generator/pot/message_extractor.rb b/lib/rdoc/generator/pot/message_extractor.rb
index 0dd2497c26..313dfd2dc7 100644
--- a/lib/rdoc/generator/pot/message_extractor.rb
+++ b/lib/rdoc/generator/pot/message_extractor.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Extracts message from RDoc::Store
diff --git a/lib/rdoc/generator/pot/po.rb b/lib/rdoc/generator/pot/po.rb
index 60e14db831..37d45e5258 100644
--- a/lib/rdoc/generator/pot/po.rb
+++ b/lib/rdoc/generator/pot/po.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Generates a PO format text
@@ -29,8 +29,8 @@ class RDoc::Generator::POT::PO
def to_s
po = ''
sort_entries.each do |entry|
- po << "\n" unless po.empty?
- po << entry.to_s
+ po += "\n" unless po.empty?
+ po += entry.to_s
end
po
end
diff --git a/lib/rdoc/generator/pot/po_entry.rb b/lib/rdoc/generator/pot/po_entry.rb
index 515d02b48d..3c278826f4 100644
--- a/lib/rdoc/generator/pot/po_entry.rb
+++ b/lib/rdoc/generator/pot/po_entry.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A PO entry in PO
@@ -40,11 +40,11 @@ class RDoc::Generator::POT::POEntry
def to_s
entry = ''
- entry << format_translator_comment
- entry << format_extracted_comment
- entry << format_references
- entry << format_flags
- entry << <<-ENTRY
+ entry += format_translator_comment
+ entry += format_extracted_comment
+ entry += format_references
+ entry += format_flags
+ entry += <<-ENTRY
msgid #{format_message(@msgid)}
msgstr #{format_message(@msgstr)}
ENTRY
@@ -75,9 +75,9 @@ msgstr #{format_message(@msgstr)}
formatted_comment = ''
comment.each_line do |line|
- formatted_comment << "#{mark} #{line}"
+ formatted_comment += "#{mark} #{line}"
end
- formatted_comment << "\n" unless formatted_comment.end_with?("\n")
+ formatted_comment += "\n" unless formatted_comment.end_with?("\n")
formatted_comment
end
@@ -94,7 +94,7 @@ msgstr #{format_message(@msgstr)}
formatted_references = ''
@references.sort.each do |file, line|
- formatted_references << "\#: #{file}:#{line}\n"
+ formatted_references += "\#: #{file}:#{line}\n"
end
formatted_references
end
@@ -111,8 +111,8 @@ msgstr #{format_message(@msgstr)}
formatted_message = '""'
message.each_line do |line|
- formatted_message << "\n"
- formatted_message << "\"#{escape(line)}\""
+ formatted_message += "\n"
+ formatted_message += "\"#{escape(line)}\""
end
formatted_message
end
diff --git a/lib/rdoc/generator/ri.rb b/lib/rdoc/generator/ri.rb
index 830777e587..0eef1d03f5 100644
--- a/lib/rdoc/generator/ri.rb
+++ b/lib/rdoc/generator/ri.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Generates ri data files
diff --git a/lib/rdoc/generator/template/darkfish/_head.rhtml b/lib/rdoc/generator/template/darkfish/_head.rhtml
index f308526823..e61fce1b9a 100644
--- a/lib/rdoc/generator/template/darkfish/_head.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_head.rhtml
@@ -7,14 +7,16 @@
var index_rel_prefix = "<%= rel_prefix %>/";
</script>
-<script src="<%= asset_rel_prefix %>/js/jquery.js"></script>
-<script src="<%= asset_rel_prefix %>/js/darkfish.js"></script>
+<script src="<%= asset_rel_prefix %>/js/navigation.js" defer></script>
+<script src="<%= asset_rel_prefix %>/js/search.js" defer></script>
+<script src="<%= asset_rel_prefix %>/js/search_index.js" defer></script>
+<script src="<%= asset_rel_prefix %>/js/searcher.js" defer></script>
+<script src="<%= asset_rel_prefix %>/js/darkfish.js" defer></script>
<link href="<%= asset_rel_prefix %>/css/fonts.css" rel="stylesheet">
<link href="<%= asset_rel_prefix %>/css/rdoc.css" rel="stylesheet">
-<% if @options.template_stylesheets.flatten.any? then %>
-<% @options.template_stylesheets.flatten.each do |stylesheet| %>
+<%- if @options.template_stylesheets.flatten.any? then -%>
+<%- @options.template_stylesheets.flatten.each do |stylesheet| -%>
<link href="<%= asset_rel_prefix %>/<%= File.basename stylesheet %>" rel="stylesheet">
-<% end %>
-<% end %>
-
+<%- end -%>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml
index e889f8063d..22a12d9e95 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml
@@ -1,4 +1,4 @@
-<% if !svninfo.empty? then %>
+<%- if !svninfo.empty? then %>
<div id="file-svninfo-section" class="nav-section">
<h3>VCS Info</h3>
@@ -16,4 +16,4 @@
</dl>
</div>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml
index fe54d8339f..530f25c762 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml
@@ -2,8 +2,8 @@
<h3>Class and Module Index</h3>
<ul class="link-list">
- <% @modsort.each do |index_klass| %>
+ <%- @modsort.each do |index_klass| -%>
<li><a href="<%= rel_prefix %>/<%= index_klass.path %>"><%= index_klass.full_name %></a>
- <% end %>
+ <%- end -%>
</ul>
</div>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml
index 2bd8efee99..7602076c96 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml
@@ -1,15 +1,15 @@
-<% unless klass.extends.empty? then %>
+<%- unless klass.extends.empty? then %>
<div id="extends-section" class="nav-section">
<h3>Extended With Modules</h3>
<ul class="link-list">
- <% klass.each_extend do |ext| %>
- <% unless String === ext.module then %>
+ <%- klass.each_extend do |ext| -%>
+ <%- unless String === ext.module then -%>
<li><a class="extend" href="<%= klass.aref_to ext.module.path %>"><%= ext.module.full_name %></a>
- <% else %>
+ <%- else -%>
<li><span class="extend"><%= ext.name %></span>
- <% end %>
- <% end %>
+ <%- end -%>
+ <%- end -%>
</ul>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml
index 0ba1d2be80..74869a4b51 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml
@@ -2,8 +2,8 @@
<h3>Defined In</h3>
<ul>
-<% klass.in_files.each do |tl| %>
+<%- klass.in_files.each do |tl| -%>
<li><%= h tl.relative_name %>
-<% end %>
+<%- end -%>
</ul>
</div>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml
index d141098ecd..5b600e5975 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml
@@ -1,15 +1,15 @@
-<% unless klass.includes.empty? then %>
+<%- unless klass.includes.empty? then %>
<div id="includes-section" class="nav-section">
<h3>Included Modules</h3>
<ul class="link-list">
- <% klass.each_include do |inc| %>
- <% unless String === inc.module then %>
+ <%- klass.each_include do |inc| -%>
+ <%- unless String === inc.module then -%>
<li><a class="include" href="<%= klass.aref_to inc.module.path %>"><%= inc.module.full_name %></a>
- <% else %>
+ <%- else -%>
<li><span class="include"><%= inc.name %></span>
- <% end %>
- <% end %>
+ <%- end -%>
+ <%- end -%>
</ul>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml
index 1285bfd732..faed7e0a94 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml
@@ -2,14 +2,14 @@
<h3>Documentation</h3>
<ul>
- <% installed.each do |name, href, exists, type, _| %>
- <% next if type == :extra %>
+ <%- installed.each do |name, href, exists, type, _| -%>
+ <%- next if type == :extra -%>
<li class="folder">
- <% if exists then %>
+ <%- if exists then -%>
<a href="<%= href %>"><%= h name %></a>
- <% else %>
+ <%- else -%>
<%= h name %>
- <% end %>
- <% end %>
+ <%- end -%>
+ <%- end -%>
</ul>
</div>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml
index 45df08d8fe..5b4c295bed 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml
@@ -1,12 +1,12 @@
-<% unless klass.method_list.empty? then %>
+<%- unless klass.method_list.empty? then %>
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
<h3>Methods</h3>
<ul class="link-list" role="directory">
- <% klass.each_method do |meth| %>
- <li <% if meth.calls_super %>class="calls-super" <% end %>><a href="#<%= meth.aref %>"><%= meth.singleton ? '::' : '#' %><%= h meth.name %></a>
- <% end %>
+ <%- klass.each_method do |meth| -%>
+ <li <%- if meth.calls_super %>class="calls-super" <%- end %>><a href="#<%= meth.aref %>"><%= meth.singleton ? '::' : '#' %><%= h meth.name -%></a>
+ <%- end -%>
</ul>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml
index 5f39825f08..8ec83abda2 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml
@@ -1,12 +1,12 @@
-<% simple_files = @files.select { |f| f.text? } %>
-<% unless simple_files.empty? then %>
+<%- simple_files = @files.select { |f| f.text? } %>
+<%- unless simple_files.empty? then -%>
<div id="fileindex-section" class="nav-section">
<h3>Pages</h3>
<ul class="link-list">
- <% simple_files.each do |f| %>
+ <%- simple_files.each do |f| -%>
<li><a href="<%= rel_prefix %>/<%= f.path %>"><%= h f.page_name %></a>
- <% end %>
+ <%- end -%>
</ul>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml
index cc04852652..1420da3201 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml
@@ -1,11 +1,11 @@
-<% if klass.type == 'class' then %>
+<%- if klass.type == 'class' then %>
<div id="parent-class-section" class="nav-section">
<h3>Parent</h3>
- <% if klass.superclass and not String === klass.superclass then %>
+ <%- if klass.superclass and not String === klass.superclass then -%>
<p class="link"><a href="<%= klass.aref_to klass.superclass.path %>"><%= klass.superclass.full_name %></a>
- <% else %>
+ <%- else -%>
<p class="link"><%= klass.superclass %>
- <% end %>
+ <%- end -%>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml
index 15ff78ba91..6dcd2ae81f 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml
@@ -1,11 +1,11 @@
-<% unless klass.sections.length == 1 then %>
+<%- unless klass.sections.length == 1 then %>
<div id="sections-section" class="nav-section">
<h3>Sections</h3>
<ul class="link-list" role="directory">
- <% klass.sort_sections.each do |section| %>
+ <%- klass.sort_sections.each do |section| -%>
<li><a href="#<%= section.aref %>"><%= h section.title %></a></li>
- <% end %>
+ <%- end -%>
</ul>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml
index b58e6b3c61..bf70819f64 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml
@@ -1,4 +1,4 @@
-<% comment = if current.respond_to? :comment_location then
+<%- comment = if current.respond_to? :comment_location then
current.comment_location
else
current.comment
@@ -10,9 +10,9 @@
<h3>Table of Contents</h3>
<ul class="link-list" role="directory">
-<% table.each do |heading| %>
+<%- table.each do |heading| -%>
<li><a href="#<%= heading.label current %>"><%= heading.plain_html %></a>
-<% end %>
+<%- end -%>
</ul>
</div>
-<% end %>
+<%- end -%>
diff --git a/lib/rdoc/generator/template/darkfish/class.rhtml b/lib/rdoc/generator/template/darkfish/class.rhtml
index 7733095086..5d7b6a1b80 100644
--- a/lib/rdoc/generator/template/darkfish/class.rhtml
+++ b/lib/rdoc/generator/template/darkfish/class.rhtml
@@ -25,9 +25,9 @@
<%= klass.description %>
</section>
- <% klass.each_section do |section, constants, attributes| %>
+ <%- klass.each_section do |section, constants, attributes| -%>
<section id="<%= section.aref %>" class="documentation-section">
- <% if section.title then %>
+ <%- if section.title then -%>
<header class="documentation-section-title">
<h2>
<%= section.title %>
@@ -36,39 +36,39 @@
<a href="#top">&uarr; top</a>
</span>
</header>
- <% end %>
+ <%- end -%>
- <% if section.comment then %>
+ <%- if section.comment then -%>
<div>
<%= section.description %>
</div>
- <% end %>
+ <%- end -%>
- <% unless constants.empty? then %>
+ <%- unless constants.empty? then -%>
<section class="constants-list">
<header>
<h3>Constants</h3>
</header>
<dl>
- <% constants.each do |const| %>
+ <%- constants.each do |const| -%>
<dt id="<%= const.name %>"><%= const.name %>
- <% if const.comment then %>
+ <%- if const.comment then -%>
<dd><%= const.description.strip %>
- <% else %>
+ <%- else -%>
<dd class="missing-docs">(Not documented)
- <% end %>
- <% end %>
+ <%- end -%>
+ <%- end -%>
</dl>
</section>
- <% end %>
+ <%- end -%>
- <% unless attributes.empty? then %>
+ <%- unless attributes.empty? then -%>
<section class="attribute-method-details" class="method-section">
<header>
<h3>Attributes</h3>
</header>
- <% attributes.each do |attrib| %>
+ <%- attributes.each do |attrib| -%>
<div id="<%= attrib.aref %>" class="method-detail">
<div class="method-heading attribute-method-heading">
<span class="method-name"><%= h attrib.name %></span><span
@@ -76,18 +76,18 @@
</div>
<div class="method-description">
- <% if attrib.comment then %>
+ <%- if attrib.comment then -%>
<%= attrib.description.strip %>
- <% else %>
+ <%- else -%>
<p class="missing-docs">(Not documented)
- <% end %>
+ <%- end -%>
</div>
</div>
- <% end %>
+ <%- end -%>
</section>
- <% end %>
+ <%- end -%>
- <% klass.methods_by_type(section).each do |type, visibilities|
+ <%- klass.methods_by_type(section).each do |type, visibilities|
next if visibilities.empty?
visibilities.each do |visibility, methods|
next if methods.empty? %>
@@ -96,38 +96,38 @@
<h3><%= visibility.to_s.capitalize %> <%= type.capitalize %> Methods</h3>
</header>
- <% methods.each do |method| %>
+ <%- methods.each do |method| -%>
<div id="<%= method.aref %>" class="method-detail <%= method.is_alias_for ? "method-alias" : '' %>">
- <% if method.call_seq then %>
- <% method.call_seq.strip.split("\n").each_with_index do |call_seq, i| %>
+ <%- if (call_seq = method.call_seq) then -%>
+ <%- call_seq.strip.split("\n").each_with_index do |call_seq, i| -%>
<div class="method-heading">
<span class="method-callseq">
<%= h(call_seq.strip.
gsub( /^\w+\./m, '')).
gsub(/(.*)[-=]&gt;/, '\1&rarr;') %>
</span>
- <% if i == 0 and method.token_stream then %>
+ <%- if i == 0 and method.token_stream then -%>
<span class="method-click-advice">click to toggle source</span>
- <% end %>
+ <%- end -%>
</div>
- <% end %>
- <% else %>
+ <%- end -%>
+ <%- else -%>
<div class="method-heading">
<span class="method-name"><%= h method.name %></span><span
class="method-args"><%= h method.param_seq %></span>
- <% if method.token_stream then %>
+ <%- if method.token_stream then -%>
<span class="method-click-advice">click to toggle source</span>
- <% end %>
+ <%- end -%>
</div>
- <% end %>
+ <%- end -%>
<div class="method-description">
- <% if method.comment then %>
+ <%- if method.comment then -%>
<%= method.description.strip %>
- <% else %>
+ <%- else -%>
<p class="missing-docs">(Not documented)
- <% end %>
- <% if method.calls_super then %>
+ <%- end -%>
+ <%- if method.calls_super then -%>
<div class="method-calls-super">
Calls superclass method
<%=
@@ -135,16 +135,16 @@
method.formatter.link(method.superclass_method.full_name, method.superclass_method.full_name) : nil
%>
</div>
- <% end %>
+ <%- end -%>
- <% if method.token_stream then %>
+ <%- if method.token_stream then -%>
<div class="method-source-code" id="<%= method.html_name %>-source">
<pre><%= method.markup_code %></pre>
</div>
- <% end %>
+ <%- end -%>
</div>
- <% unless method.aliases.empty? then %>
+ <%- unless method.aliases.empty? then -%>
<div class="aliases">
Also aliased as: <%= method.aliases.map do |aka|
if aka.parent then # HACK lib/rexml/encodings
@@ -154,19 +154,19 @@
end
end.join ", " %>
</div>
- <% end %>
+ <%- end -%>
- <% if method.is_alias_for then %>
+ <%- if method.is_alias_for then -%>
<div class="aliases">
Alias for: <a href="<%= klass.aref_to method.is_alias_for.path %>"><%= h method.is_alias_for.name %></a>
</div>
- <% end %>
+ <%- end -%>
</div>
- <% end %>
+ <%- end -%>
</section>
- <% end
+ <%- end
end %>
</section>
-<% end %>
+<%- end -%>
</main>
diff --git a/lib/rdoc/generator/template/darkfish/css/rdoc.css b/lib/rdoc/generator/template/darkfish/css/rdoc.css
index 2f4dca7e08..ebe2e93af6 100644
--- a/lib/rdoc/generator/template/darkfish/css/rdoc.css
+++ b/lib/rdoc/generator/template/darkfish/css/rdoc.css
@@ -9,6 +9,8 @@
/* vim: ft=css et sw=2 ts=2 sts=2 */
/* Base Green is: #6C8C22 */
+.hide { display: none !important; }
+
* { padding: 0; margin: 0; }
body {
@@ -48,6 +50,16 @@ h6:hover span {
display: inline;
}
+h1:target,
+h2:target,
+h3:target,
+h4:target,
+h5:target,
+h6:target {
+ margin-left: -10px;
+ border-left: 10px solid #f1edba;
+}
+
:link,
:visited {
color: #6C8C22;
@@ -62,6 +74,28 @@ h6:hover span {
code,
pre {
font-family: "Source Code Pro", Monaco, monospace;
+ background-color: rgba(27,31,35,0.05);
+ padding: 0em 0.2em;
+ border-radius: 0.2em;
+}
+
+table {
+ margin: 0;
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+table tr th, table tr td {
+ padding: 0.2em 0.4em;
+ border: 1px solid #ccc;
+}
+
+table tr th {
+ background-color: #eceaed;
+}
+
+table tr:nth-child(even) td {
+ background-color: #f5f4f6;
}
/* @group Generic Classes */
@@ -91,7 +125,7 @@ pre {
.missing-docs {
font-size: 120%;
- background: white url(images/wrench_orange.png) no-repeat 4px center;
+ background: white url(../images/wrench_orange.png) no-repeat 4px center;
color: #ccc;
line-height: 2em;
border: 1px solid #d00;
@@ -135,11 +169,11 @@ pre {
.table-of-contents li .toc-toggle {
width: 16px;
height: 16px;
- background: url(images/add.png) no-repeat;
+ background: url(../images/add.png) no-repeat;
}
.table-of-contents li .toc-toggle.open {
- background: url(images/delete.png) no-repeat;
+ background: url(../images/delete.png) no-repeat;
}
/* @end */
@@ -151,6 +185,7 @@ nav {
width: 260px;
font-family: Helvetica, sans-serif;
font-size: 14px;
+ border-right: 1px solid #ccc;
}
main {
@@ -261,8 +296,13 @@ ul.link-list .type {
-webkit-border-radius: 5px;
}
+dl.note-list dt {
+ float: left;
+ margin-right: 1em;
+}
+
.calls-super {
- background: url(images/arrow_up.png) no-repeat right center;
+ background: url(../images/arrow_up.png) no-repeat right center;
}
/* @end */
@@ -441,7 +481,16 @@ main header h3 {
/* @group Method Details */
main .method-source-code {
- display: none;
+ max-height: 0;
+ overflow: hidden;
+ transition-duration: 200ms;
+ transition-delay: 0ms;
+ transition-property: all;
+ transition-timing-function: ease-in-out;
+}
+
+main .method-source-code.active-menu {
+ max-height: 100vh;
}
main .method-description .method-calls-super {
@@ -479,7 +528,7 @@ main .method-click-advice {
visibility: hidden;
padding-right: 20px;
line-height: 20px;
- background: url(images/zoom.png) no-repeat right top;
+ background: url(../images/zoom.png) no-repeat right top;
}
main .method-heading:hover .method-click-advice {
visibility: visible;
diff --git a/lib/rdoc/generator/template/darkfish/index.rhtml b/lib/rdoc/generator/template/darkfish/index.rhtml
index 7d1c74807b..13fa3dcc7f 100644
--- a/lib/rdoc/generator/template/darkfish/index.rhtml
+++ b/lib/rdoc/generator/template/darkfish/index.rhtml
@@ -13,11 +13,10 @@
</nav>
<main role="main">
-<% if @options.main_page and
+<%- if @options.main_page and
main_page = @files.find { |f| f.full_name == @options.main_page } then %>
<%= main_page.description %>
-<% else %>
+<%- else -%>
<p>This is the API documentation for <%= @title %>.
-<% end %>
+<%- end -%>
</main>
-
diff --git a/lib/rdoc/generator/template/darkfish/js/darkfish.js b/lib/rdoc/generator/template/darkfish/js/darkfish.js
index 38f877ed40..111bbf8eb9 100644
--- a/lib/rdoc/generator/template/darkfish/js/darkfish.js
+++ b/lib/rdoc/generator/template/darkfish/js/darkfish.js
@@ -8,6 +8,7 @@
*/
/* Provide console simulation for firebug-less environments */
+/*
if (!("console" in window) || !("firebug" in console)) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
@@ -16,41 +17,35 @@ if (!("console" in window) || !("firebug" in console)) {
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
};
-
-
-/**
- * Unwrap the first element that matches the given @expr@ from the targets and return them.
- */
-$.fn.unwrap = function( expr ) {
- return this.each( function() {
- $(this).parents( expr ).eq( 0 ).after( this ).remove();
- });
-};
+*/
function showSource( e ) {
var target = e.target;
- var codeSections = $(target).
- parents('.method-detail').
- find('.method-source-code');
-
- $(target).
- parents('.method-detail').
- find('.method-source-code').
- slideToggle();
+ while (!target.classList.contains('method-detail')) {
+ target = target.parentNode;
+ }
+ if (typeof target !== "undefined" && target !== null) {
+ target = target.querySelector('.method-source-code');
+ }
+ if (typeof target !== "undefined" && target !== null) {
+ target.classList.toggle('active-menu')
+ }
};
function hookSourceViews() {
- $('.method-heading').click( showSource );
+ document.querySelectorAll('.method-heading').forEach(function (codeObject) {
+ codeObject.addEventListener('click', showSource);
+ });
};
function hookSearch() {
- var input = $('#search-field').eq(0);
- var result = $('#search-results').eq(0);
- $(result).show();
+ var input = document.querySelector('#search-field');
+ var result = document.querySelector('#search-results');
+ result.classList.remove("initially-hidden");
- var search_section = $('#search-section').get(0);
- $(search_section).show();
+ var search_section = document.querySelector('#search-section');
+ search_section.classList.remove("initially-hidden");
var search = new Search(search_data, input, result);
@@ -77,85 +72,13 @@ function hookSearch() {
}
search.select = function(result) {
- var result_element = result.get(0);
- window.location.href = result_element.firstChild.firstChild.href;
+ window.location.href = result.firstChild.firstChild.href;
}
search.scrollIntoView = search.scrollInWindow;
};
-function highlightTarget( anchor ) {
- console.debug( "Highlighting target '%s'.", anchor );
-
- $("a[name]").each( function() {
- if ( $(this).attr("name") == anchor ) {
- if ( !$(this).parent().parent().hasClass('target-section') ) {
- console.debug( "Wrapping the target-section" );
- $('div.method-detail').unwrap( 'div.target-section' );
- $(this).parent().wrap( '<div class="target-section"></div>' );
- } else {
- console.debug( "Already wrapped." );
- }
- }
- });
-};
-
-function highlightLocationTarget() {
- console.debug( "Location hash: %s", window.location.hash );
- if ( ! window.location.hash || window.location.hash.length == 0 ) return;
-
- var anchor = window.location.hash.substring(1);
- console.debug( "Found anchor: %s; matching %s", anchor, "a[name=" + anchor + "]" );
-
- highlightTarget( anchor );
-};
-
-function highlightClickTarget( event ) {
- console.debug( "Highlighting click target for event %o", event.target );
- try {
- var anchor = $(event.target).attr( 'href' ).substring(1);
- console.debug( "Found target anchor: %s", anchor );
- highlightTarget( anchor );
- } catch ( err ) {
- console.error( "Exception while highlighting: %o", err );
- };
-};
-
-function loadAsync(path, success, prefix) {
- $.ajax({
- url: prefix + path,
- dataType: 'script',
- success: success,
- cache: true
- });
-};
-
-$(document).ready( function() {
+document.addEventListener('DOMContentLoaded', function() {
hookSourceViews();
- highlightLocationTarget();
- $('ul.link-list a').bind( "click", highlightClickTarget );
-
- var search_scripts_loaded = {
- navigation_loaded: false,
- search_loaded: false,
- search_index_loaded: false,
- searcher_loaded: false,
- }
-
- var search_success_function = function(variable) {
- return (function (data, status, xhr) {
- search_scripts_loaded[variable] = true;
-
- if (search_scripts_loaded['navigation_loaded'] == true &&
- search_scripts_loaded['search_loaded'] == true &&
- search_scripts_loaded['search_index_loaded'] == true &&
- search_scripts_loaded['searcher_loaded'] == true)
- hookSearch();
- });
- }
-
- loadAsync('js/navigation.js', search_success_function('navigation_loaded'), rdoc_rel_prefix);
- loadAsync('js/search.js', search_success_function('search_loaded'), rdoc_rel_prefix);
- loadAsync('js/search_index.js', search_success_function('search_index_loaded'), index_rel_prefix);
- loadAsync('js/searcher.js', search_success_function('searcher_loaded'), rdoc_rel_prefix);
+ hookSearch();
});
diff --git a/lib/rdoc/generator/template/darkfish/js/jquery.js b/lib/rdoc/generator/template/darkfish/js/jquery.js
deleted file mode 100644
index 628ed9b316..0000000000
--- a/lib/rdoc/generator/template/darkfish/js/jquery.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */
-(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bA.test(a)?d(a,e):bY(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bY(a+"["+e+"]",b[e],c,d);else d(a,b)}function bX(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bW(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bP,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bW(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bW(a,c,d,e,"*",g));return l}function bV(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bL),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function by(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bt:bu;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bf(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function V(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(Q.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(w,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:H?function(a){return a==null?"":H.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?F.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(!b)return-1;if(I)return I.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=G.call(arguments,2),g=function(){return a.apply(c,f.concat(G.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){J["[object "+b+"]"]=b.toLowerCase()}),A=e.uaMatch(z),A.browser&&(e.browser[A.browser]=!0,e.browser.version=A.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?C=function(){c.removeEventListener("DOMContentLoaded",C,!1),e.ready()}:c.attachEvent&&(C=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",C),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g+"With"](this===b?d:this,[h])}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u,v;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(o);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(o);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(n," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete
-t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,M(a.origType,a.selector),f.extend({},a,{handler:L,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,M(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?D:C):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=D;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=D;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=D,this.stopPropagation()},isDefaultPrevented:C,isPropagationStopped:C,isImmediatePropagationStopped:C};var E=function(a){var b=a.relatedTarget,c=!1,d=a.type;a.type=a.data,b!==this&&(b&&(c=f.contains(this,b)),c||(f.event.handle.apply(this,arguments),a.type=d))},F=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?F:E,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?F:E)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="submit"||c==="image")&&f(b).closest("form").length&&J("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&J("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var G,H=function(a){var b=f.nodeName(a,"input")?a.type:"",c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var K={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||C,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=w.exec(h),k="",j&&(k=j[0],h=h.replace(w,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,K[h]?(a.push(K[h]+k),h=h+k):h=(K[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+M(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+M(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var N=/Until$/,O=/^(?:parents|prevUntil|prevAll)/,P=/,/,Q=/^.[^:#\[\.,]*$/,R=Array.prototype.slice,S=f.expr.match.POS,T={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(V(this,a,!1),"not",a)},filter:function(a){return this.pushStack(V(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=S.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|object|embed|option|style)/i,bb=/checked\s*(?:[^=]|=\s*.checked.)/i,bc=/\/(java|ecma)script/i,bd=/^\s*<!(?:\[CDATA\[|\-\-)/,be={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bb.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bf(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bl)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i;b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!ba.test(a[0])&&(f.support.checkClone||!bb.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean
-(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bk(k[i]);else bk(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bc.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bm=/alpha\([^)]*\)/i,bn=/opacity=([^)]*)/,bo=/([A-Z]|^ms)/g,bp=/^-?\d+(?:px)?$/i,bq=/^-?\d/,br=/^([\-+])=([\-+.\de]+)/,bs={position:"absolute",visibility:"hidden",display:"block"},bt=["Left","Right"],bu=["Top","Bottom"],bv,bw,bx;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bv(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=br.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bv)return bv(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return by(a,b,d);f.swap(a,bs,function(){e=by(a,b,d)});return e}},set:function(a,b){if(!bp.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bJ,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bK.test(this.nodeName)||bE.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bT},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bV(bP),ajaxTransport:bV(bQ),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?bZ(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=b$(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bD.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bT+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bW(bQ,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cr(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cq("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cq("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cr(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cj.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=ck.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cq("show",1),slideUp:cq("hide",1),slideToggle:cq("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return d.step(a)}var d=this,e=f.fx;this.startTime=cn||co(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&f.timers.push(g)&&!cl&&(cl=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cn||co(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cl),cl=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cs=/^t(?:able|d|h)$/i,ct=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cu(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cs.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=ct.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!ct.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cu(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cu(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file
diff --git a/lib/rdoc/generator/template/darkfish/js/search.js b/lib/rdoc/generator/template/darkfish/js/search.js
index 60ac295e6c..b558ca5b4f 100644
--- a/lib/rdoc/generator/template/darkfish/js/search.js
+++ b/lib/rdoc/generator/template/darkfish/js/search.js
@@ -1,29 +1,29 @@
Search = function(data, input, result) {
this.data = data;
- this.$input = $(input);
- this.$result = $(result);
+ this.input = input;
+ this.result = result;
- this.$current = null;
- this.$view = this.$result.parent();
+ this.current = null;
+ this.view = this.result.parentNode;
this.searcher = new Searcher(data.index);
this.init();
}
-Search.prototype = $.extend({}, Navigation, new function() {
+Search.prototype = Object.assign({}, Navigation, new function() {
var suid = 1;
this.init = function() {
var _this = this;
var observer = function(e) {
- switch(e.originalEvent.keyCode) {
+ switch(e.keyCode) {
case 38: // Event.KEY_UP
case 40: // Event.KEY_DOWN
return;
}
- _this.search(_this.$input[0].value);
+ _this.search(_this.input.value);
};
- this.$input.keyup(observer);
- this.$input.click(observer); // mac's clear field
+ this.input.addEventListener('keyup', observer);
+ this.input.addEventListener('click', observer); // mac's clear field
this.searcher.ready(function(results, isLast) {
_this.addResults(results, isLast);
@@ -34,7 +34,7 @@ Search.prototype = $.extend({}, Navigation, new function() {
}
this.search = function(value, selectFirstMatch) {
- value = jQuery.trim(value).toLowerCase();
+ value = value.trim().toLowerCase();
if (value) {
this.setNavigationActive(true);
} else {
@@ -43,23 +43,23 @@ Search.prototype = $.extend({}, Navigation, new function() {
if (value == '') {
this.lastQuery = value;
- this.$result.empty();
- this.$result.attr('aria-expanded', 'false');
+ this.result.innerHTML = '';
+ this.result.setAttribute('aria-expanded', 'false');
this.setNavigationActive(false);
} else if (value != this.lastQuery) {
this.lastQuery = value;
- this.$result.attr('aria-busy', 'true');
- this.$result.attr('aria-expanded', 'true');
+ this.result.setAttribute('aria-busy', 'true');
+ this.result.setAttribute('aria-expanded', 'true');
this.firstRun = true;
this.searcher.find(value);
}
}
this.addResults = function(results, isLast) {
- var target = this.$result.get(0);
+ var target = this.result;
if (this.firstRun && (results.length > 0 || isLast)) {
- this.$current = null;
- this.$result.empty();
+ this.current = null;
+ this.result.innerHTML = '';
}
for (var i=0, l = results.length; i < l; i++) {
@@ -70,25 +70,26 @@ Search.prototype = $.extend({}, Navigation, new function() {
if (this.firstRun && results.length > 0) {
this.firstRun = false;
- this.$current = $(target.firstChild);
- this.$current.addClass('search-selected');
+ this.current = target.firstChild;
+ this.current.classList.add('search-selected');
}
- if (jQuery.browser.msie) this.$element[0].className += '';
+ //TODO: ECMAScript
+ //if (jQuery.browser.msie) this.$element[0].className += '';
- if (isLast) this.$result.attr('aria-busy', 'false');
+ if (isLast) this.result.setAttribute('aria-busy', 'false');
}
this.move = function(isDown) {
- if (!this.$current) return;
- var $next = this.$current[isDown ? 'next' : 'prev']();
- if ($next.length) {
- this.$current.removeClass('search-selected');
- $next.addClass('search-selected');
- this.$input.attr('aria-activedescendant', $next.attr('id'));
- this.scrollIntoView($next[0], this.$view[0]);
- this.$current = $next;
- this.$input.val($next[0].firstChild.firstChild.text);
- this.$input.select();
+ if (!this.current) return;
+ var next = isDown ? this.current.nextElementSibling : this.current.previousElementSibling;
+ if (next) {
+ this.current.classList.remove('search-selected');
+ next.classList.add('search-selected');
+ this.input.setAttribute('aria-activedescendant', next.getAttribute('id'));
+ this.scrollIntoView(next, this.view);
+ this.current = next;
+ this.input.value = next.firstChild.firstChild.text;
+ this.input.select();
}
return true;
}
diff --git a/lib/rdoc/generator/template/darkfish/servlet_root.rhtml b/lib/rdoc/generator/template/darkfish/servlet_root.rhtml
index 3a33659aea..cab3092b17 100644
--- a/lib/rdoc/generator/template/darkfish/servlet_root.rhtml
+++ b/lib/rdoc/generator/template/darkfish/servlet_root.rhtml
@@ -19,28 +19,28 @@
<p>Here you can browse local documentation from the ruby standard library and
your installed gems.
-<% extra_dirs = installed.select { |_, _, _, type,| type == :extra } %>
-<% unless extra_dirs.empty? %>
+<%- extra_dirs = installed.select { |_, _, _, type,| type == :extra } -%>
+<%- unless extra_dirs.empty? -%>
<h2>Extra Documentation Directories</h2>
<p>The following additional documentation directories are available:</p>
<ol>
- <% extra_dirs.each do |name, href, exists, _, path| %>
+ <%- extra_dirs.each do |name, href, exists, _, path| -%>
<li>
- <% if exists %>
+ <%- if exists -%>
<a href="<%= href %>"><%= h name %></a> (<%= h path %>)
- <% else %>
+ <%- else -%>
<%= h name %> (<%= h path %>; <i>not available</i>)
- <% end %>
+ <%- end -%>
</li>
- <% end %>
+ <%- end -%>
</ol>
-<% end %>
+<%- end -%>
-<% gems = installed.select { |_, _, _, type,| type == :gem } %>
-<% missing = gems.reject { |_, _, exists,| exists } %>
-<% unless missing.empty? then %>
+<%- gems = installed.select { |_, _, _, type,| type == :gem } -%>
+<%- missing = gems.reject { |_, _, exists,| exists } -%>
+<%- unless missing.empty? then -%>
<h2>Missing Gem Documentation</h2>
<p>You are missing documentation for some of your installed gems.
@@ -53,11 +53,10 @@
the following commands.
<ul>
- <% names = missing.map { |name,| name.sub(/-([^-]*)$/, '') }.uniq %>
- <% names.each do |name| %>
+ <%- names = missing.map { |name,| name.sub(/-([^-]*)$/, '') }.uniq -%>
+ <%- names.each do |name| -%>
<li><kbd>gem rdoc <%=h name %></kbd>
- <% end %>
+ <%- end -%>
</ul>
-<% end %>
+<%- end -%>
</main>
-
diff --git a/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml b/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml
index 7ff1a9e93e..303d7016cc 100644
--- a/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml
+++ b/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml
@@ -2,11 +2,11 @@
<main role="main">
<h1 class="class"><%= h @title %></h1>
-<% simple_files = @files.select { |f| f.text? } %>
-<% unless simple_files.empty? then %>
+<%- simple_files = @files.select { |f| f.text? } -%>
+<%- unless simple_files.empty? then -%>
<h2 id="pages">Pages</h2>
<ul>
-<% simple_files.sort.each do |file| %>
+<%- simple_files.sort.each do |file| -%>
<li class="file">
<a href="<%= file.path %>"><%= h file.page_name %></a>
<%
@@ -14,45 +14,45 @@
table = file.parse(file.comment).table_of_contents
unless table.empty? then %>
<ul>
-<% table.each do |heading| %>
+<%- table.each do |heading| -%>
<li><a href="<%= file.path %>#<%= heading.aref %>"><%= heading.plain_html %></a>
-<% end %>
+<%- end -%>
</ul>
-<% end %>
+<%- end -%>
</li>
- <% end %>
+ <%- end -%>
</ul>
-<% end %>
+<%- end -%>
<h2 id="classes">Classes and Modules</h2>
<ul>
-<% @modsort.each do |klass| %>
+<%- @modsort.each do |klass| -%>
<li class="<%= klass.type %>">
<a href="<%= klass.path %>"><%= klass.full_name %></a>
-<% table = []
+<%- table = []
table.concat klass.parse(klass.comment_location).table_of_contents
table.concat klass.section_contents
unless table.empty? then %>
<ul>
-<% table.each do |item| %>
+<%- table.each do |item| -%>
<li><a href="<%= klass.path %>#<%= item.aref %>"><%= item.plain_html %></a>
-<% end %>
+<%- end -%>
</ul>
-<% end %>
+<%- end -%>
</li>
-<% end %>
+<%- end -%>
</ul>
<h2 id="methods">Methods</h2>
<ul>
-<% @store.all_classes_and_modules.map do |mod|
+<%- @store.all_classes_and_modules.map do |mod|
mod.method_list
end.flatten.sort.each do |method| %>
<li class="method">
<a href="<%= method.path %>"><%= h method.pretty_name %></a>
&mdash;
<span class="container"><%= method.parent.full_name %></span>
-<% end %>
+<%- end -%>
</ul>
</main>
diff --git a/lib/rdoc/generator/template/json_index/js/navigation.js b/lib/rdoc/generator/template/json_index/js/navigation.js
index e41268123e..dfad74b1ae 100644
--- a/lib/rdoc/generator/template/json_index/js/navigation.js
+++ b/lib/rdoc/generator/template/json_index/js/navigation.js
@@ -10,10 +10,8 @@ Navigation = new function() {
this.initNavigation = function() {
var _this = this;
- $(document).keydown(function(e) {
+ document.addEventListener('keydown', function(e) {
_this.onkeydown(e);
- }).keyup(function(e) {
- _this.onkeyup(e);
});
this.navigationActive = true;
@@ -21,20 +19,6 @@ Navigation = new function() {
this.setNavigationActive = function(state) {
this.navigationActive = state;
- this.clearMoveTimeout();
- }
-
- this.onkeyup = function(e) {
- if (!this.navigationActive) return;
-
- switch(e.keyCode) {
- case 37: //Event.KEY_LEFT:
- case 38: //Event.KEY_UP:
- case 39: //Event.KEY_RIGHT:
- case 40: //Event.KEY_DOWN:
- this.clearMoveTimeout();
- break;
- }
}
this.onkeydown = function(e) {
@@ -46,7 +30,6 @@ Navigation = new function() {
case 38: //Event.KEY_UP:
if (e.keyCode == 38 || e.ctrlKey) {
if (this.moveUp()) e.preventDefault();
- this.startMoveTimeout(false);
}
break;
case 39: //Event.KEY_RIGHT:
@@ -55,34 +38,14 @@ Navigation = new function() {
case 40: //Event.KEY_DOWN:
if (e.keyCode == 40 || e.ctrlKey) {
if (this.moveDown()) e.preventDefault();
- this.startMoveTimeout(true);
}
break;
case 13: //Event.KEY_RETURN:
- if (this.$current)
- e.preventDefault();
- this.select(this.$current);
+ if (this.current) e.preventDefault();
+ this.select(this.current);
break;
}
- if (e.ctrlKey && e.shiftKey) this.select(this.$current);
- }
-
- this.clearMoveTimeout = function() {
- clearTimeout(this.moveTimeout);
- this.moveTimeout = null;
- }
-
- this.startMoveTimeout = function(isDown) {
- if (!$.browser.mozilla && !$.browser.opera) return;
- if (this.moveTimeout) this.clearMoveTimeout();
- var _this = this;
-
- var go = function() {
- if (!_this.moveTimeout) return;
- _this[isDown ? 'moveDown' : 'moveUp']();
- _this.moveTimout = setTimeout(go, 100);
- }
- this.moveTimeout = setTimeout(go, 200);
+ if (e.ctrlKey && e.shiftKey) this.select(this.current);
}
this.moveRight = function() {
diff --git a/lib/rdoc/generator/template/json_index/js/searcher.js b/lib/rdoc/generator/template/json_index/js/searcher.js
index b3b1c58a0f..e200a168b0 100644
--- a/lib/rdoc/generator/template/json_index/js/searcher.js
+++ b/lib/rdoc/generator/template/json_index/js/searcher.js
@@ -51,20 +51,20 @@ Searcher.prototype = new function() {
/* ----- Utilities ------ */
function splitQuery(query) {
- return jQuery.grep(query.split(/(\s+|::?|\(\)?)/), function(string) {
+ return query.split(/(\s+|::?|\(\)?)/).filter(function(string) {
return string.match(/\S/);
});
}
function buildRegexps(queries) {
- return jQuery.map(queries, function(query) {
+ return queries.map(function(query) {
return new RegExp(query.replace(/(.)/g, '([$1])([^$1]*?)'), 'i');
});
}
function buildHilighters(queries) {
- return jQuery.map(queries, function(query) {
- return jQuery.map(query.split(''), function(l, i) {
+ return queries.map(function(query) {
+ return query.split('').map(function(l, i) {
return '\u0001$' + (i*2+1) + '\u0002$' + (i*2+2);
}).join('');
});
@@ -221,9 +221,9 @@ Searcher.prototype = new function() {
}
function triggerResults(results, isLast) {
- jQuery.each(this.handlers, function(i, fn) {
+ this.handlers.forEach(function(fn) {
fn.call(this, results, isLast)
- })
+ });
}
}
diff --git a/lib/rdoc/ghost_method.rb b/lib/rdoc/ghost_method.rb
index a1f75bfe4b..2488feb9d7 100644
--- a/lib/rdoc/ghost_method.rb
+++ b/lib/rdoc/ghost_method.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# GhostMethod represents a method referenced only by a comment
diff --git a/lib/rdoc/i18n.rb b/lib/rdoc/i18n.rb
index 14a3739c1c..a32fd848a0 100644
--- a/lib/rdoc/i18n.rb
+++ b/lib/rdoc/i18n.rb
@@ -1,10 +1,10 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# This module provides i18n related features.
module RDoc::I18n
autoload :Locale, 'rdoc/i18n/locale'
- autoload :Text, 'rdoc/i18n/text'
+ require_relative 'i18n/text'
end
diff --git a/lib/rdoc/i18n/locale.rb b/lib/rdoc/i18n/locale.rb
index 4d55f6965d..6a70d6c986 100644
--- a/lib/rdoc/i18n/locale.rb
+++ b/lib/rdoc/i18n/locale.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A message container for a locale.
#
diff --git a/lib/rdoc/i18n/text.rb b/lib/rdoc/i18n/text.rb
index fcfe7611bc..7ea6664442 100644
--- a/lib/rdoc/i18n/text.rb
+++ b/lib/rdoc/i18n/text.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# An i18n supported text.
#
@@ -46,9 +46,9 @@ class RDoc::I18n::Text
parse do |part|
case part[:type]
when :paragraph
- translated_text << locale.translate(part[:paragraph])
+ translated_text += locale.translate(part[:paragraph])
when :empty_line
- translated_text << part[:line]
+ translated_text += part[:line]
else
raise "should not reach here: unexpected type: #{type}"
end
@@ -69,14 +69,14 @@ class RDoc::I18n::Text
if paragraph.empty?
emit_empty_line_event(line, line_no, &block)
else
- paragraph << line
+ paragraph += line
emit_paragraph_event(paragraph, paragraph_start_line, line_no,
&block)
paragraph = ''
end
else
paragraph_start_line = line_no if paragraph.empty?
- paragraph << line
+ paragraph += line
end
end
diff --git a/lib/rdoc/include.rb b/lib/rdoc/include.rb
index efce43bffb..b3ad610649 100644
--- a/lib/rdoc/include.rb
+++ b/lib/rdoc/include.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A Module included in a class with \#include
#
diff --git a/lib/rdoc/known_classes.rb b/lib/rdoc/known_classes.rb
index 8d9421255b..4d7f4aa995 100644
--- a/lib/rdoc/known_classes.rb
+++ b/lib/rdoc/known_classes.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
module RDoc
##
diff --git a/lib/rdoc/markdown.rb b/lib/rdoc/markdown.rb
index a7f1bb0c24..3442f76b1b 100644
--- a/lib/rdoc/markdown.rb
+++ b/lib/rdoc/markdown.rb
@@ -1,4 +1,5 @@
# coding: UTF-8
+# frozen_string_literal: true
# :markup: markdown
##
@@ -81,6 +82,18 @@
# : A little insect that is known
# to enjoy picnics
#
+# ### Strike
+#
+# Example:
+#
+# ```
+# This is ~~striked~~.
+# ```
+#
+# Produces:
+#
+# This is ~~striked~~.
+#
# ### Github
#
# The #github extension enables a partial set of [Github Flavored Markdown]
@@ -160,7 +173,7 @@
# The port to kpeg was performed by Eric Hodel and Evan Phoenix
#
# [dingus]: http://daringfireball.net/projects/markdown/dingus
-# [GFM]: http://github.github.com/github-flavored-markdown/
+# [GFM]: https://github.github.com/gfm/
# [pegmarkdown]: https://github.com/jgm/peg-markdown
# [PHPE]: http://michelf.com/projects/php-markdown/extra/#def-list
# [syntax]: http://daringfireball.net/projects/markdown/syntax
@@ -331,9 +344,8 @@ class RDoc::Markdown
end
def scan(reg)
- if m = reg.match(@string[@pos..-1])
- width = m.end(0)
- @pos += width
+ if m = reg.match(@string, @pos)
+ @pos = m.end(0)
return true
end
@@ -540,6 +552,7 @@ class RDoc::Markdown
:github,
:html,
:notes,
+ :strike,
]
# :section: Extensions
@@ -590,6 +603,11 @@ class RDoc::Markdown
extension :notes
+ ##
+ # Enables the strike extension
+
+ extension :strike
+
# :section:
##
@@ -678,7 +696,7 @@ class RDoc::Markdown
# with the linking `text` (usually whitespace).
def link_to content, label = content, text = nil
- raise 'enable notes extension' if
+ raise ParseError, 'enable notes extension' if
content.start_with? '^' and label.equal? content
if ref = @references[label] then
@@ -814,6 +832,17 @@ class RDoc::Markdown
end
end
+ ##
+ # Wraps `text` in strike markup for rdoc inline formatting
+
+ def strike text
+ if text =~ /\A[a-z\d.\/-]+\z/i then
+ "~#{text}~"
+ else
+ "<s>#{text}</s>"
+ end
+ end
+
# :stopdoc:
def setup_foreign_grammar
@@ -867,7 +896,7 @@ class RDoc::Markdown
return _tmp
end
- # Block = @BlankLine* (BlockQuote | Verbatim | CodeFence | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain)
+ # Block = @BlankLine* (BlockQuote | Verbatim | CodeFence | Table | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain)
def _Block
_save = self.pos
@@ -893,6 +922,9 @@ class RDoc::Markdown
_tmp = apply(:_CodeFence)
break if _tmp
self.pos = _save2
+ _tmp = apply(:_Table)
+ break if _tmp
+ self.pos = _save2
_tmp = apply(:_Note)
break if _tmp
self.pos = _save2
@@ -1005,7 +1037,7 @@ class RDoc::Markdown
return _tmp
end
- # AtxInline = !@Newline !(@Sp? /#*/ @Sp @Newline) Inline
+ # AtxInline = !@Newline !(@Sp /#*/ @Sp @Newline) Inline
def _AtxInline
_save = self.pos
@@ -1022,17 +1054,12 @@ class RDoc::Markdown
_save3 = self.pos
while true # sequence
- _save4 = self.pos
_tmp = _Sp()
unless _tmp
- _tmp = true
- self.pos = _save4
- end
- unless _tmp
self.pos = _save3
break
end
- _tmp = scan(/\A(?-mix:#*)/)
+ _tmp = scan(/\G(?-mix:#*)/)
unless _tmp
self.pos = _save3
break
@@ -1072,7 +1099,7 @@ class RDoc::Markdown
_save = self.pos
while true # sequence
_text_start = self.pos
- _tmp = scan(/\A(?-mix:\#{1,6})/)
+ _tmp = scan(/\G(?-mix:\#{1,6})/)
if _tmp
text = get_text(_text_start)
end
@@ -1092,7 +1119,7 @@ class RDoc::Markdown
return _tmp
end
- # AtxHeading = AtxStart:s @Sp? AtxInline+:a (@Sp? /#*/ @Sp)? @Newline { RDoc::Markup::Heading.new(s, a.join) }
+ # AtxHeading = AtxStart:s @Sp AtxInline+:a (@Sp /#*/ @Sp)? @Newline { RDoc::Markup::Heading.new(s, a.join) }
def _AtxHeading
_save = self.pos
@@ -1103,17 +1130,12 @@ class RDoc::Markdown
self.pos = _save
break
end
- _save1 = self.pos
_tmp = _Sp()
unless _tmp
- _tmp = true
- self.pos = _save1
- end
- unless _tmp
self.pos = _save
break
end
- _save2 = self.pos
+ _save1 = self.pos
_ary = []
_tmp = apply(:_AtxInline)
if _tmp
@@ -1126,42 +1148,37 @@ class RDoc::Markdown
_tmp = true
@result = _ary
else
- self.pos = _save2
+ self.pos = _save1
end
a = @result
unless _tmp
self.pos = _save
break
end
- _save3 = self.pos
+ _save2 = self.pos
- _save4 = self.pos
+ _save3 = self.pos
while true # sequence
- _save5 = self.pos
_tmp = _Sp()
unless _tmp
- _tmp = true
- self.pos = _save5
- end
- unless _tmp
- self.pos = _save4
+ self.pos = _save3
break
end
- _tmp = scan(/\A(?-mix:#*)/)
+ _tmp = scan(/\G(?-mix:#*)/)
unless _tmp
- self.pos = _save4
+ self.pos = _save3
break
end
_tmp = _Sp()
unless _tmp
- self.pos = _save4
+ self.pos = _save3
end
break
end # end sequence
unless _tmp
_tmp = true
- self.pos = _save3
+ self.pos = _save2
end
unless _tmp
self.pos = _save
@@ -1202,12 +1219,12 @@ class RDoc::Markdown
return _tmp
end
- # SetextBottom1 = /={3,}/ @Newline
+ # SetextBottom1 = /={1,}/ @Newline
def _SetextBottom1
_save = self.pos
while true # sequence
- _tmp = scan(/\A(?-mix:={3,})/)
+ _tmp = scan(/\G(?-mix:={1,})/)
unless _tmp
self.pos = _save
break
@@ -1223,12 +1240,12 @@ class RDoc::Markdown
return _tmp
end
- # SetextBottom2 = /-{3,}/ @Newline
+ # SetextBottom2 = /-{1,}/ @Newline
def _SetextBottom2
_save = self.pos
while true # sequence
- _tmp = scan(/\A(?-mix:-{3,})/)
+ _tmp = scan(/\G(?-mix:-{1,})/)
unless _tmp
self.pos = _save
break
@@ -1244,7 +1261,7 @@ class RDoc::Markdown
return _tmp
end
- # SetextHeading1 = &(@RawLine SetextBottom1) @StartList:a (!@Endline Inline:b { a << b })+ @Sp? @Newline SetextBottom1 { RDoc::Markup::Heading.new(1, a.join) }
+ # SetextHeading1 = &(@RawLine SetextBottom1) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom1 { RDoc::Markup::Heading.new(1, a.join) }
def _SetextHeading1
_save = self.pos
@@ -1339,13 +1356,8 @@ class RDoc::Markdown
self.pos = _save
break
end
- _save8 = self.pos
_tmp = _Sp()
unless _tmp
- _tmp = true
- self.pos = _save8
- end
- unless _tmp
self.pos = _save
break
end
@@ -1371,7 +1383,7 @@ class RDoc::Markdown
return _tmp
end
- # SetextHeading2 = &(@RawLine SetextBottom2) @StartList:a (!@Endline Inline:b { a << b })+ @Sp? @Newline SetextBottom2 { RDoc::Markup::Heading.new(2, a.join) }
+ # SetextHeading2 = &(@RawLine SetextBottom2) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom2 { RDoc::Markup::Heading.new(2, a.join) }
def _SetextHeading2
_save = self.pos
@@ -1466,13 +1478,8 @@ class RDoc::Markdown
self.pos = _save
break
end
- _save8 = self.pos
_tmp = _Sp()
unless _tmp
- _tmp = true
- self.pos = _save8
- end
- unless _tmp
self.pos = _save
break
end
@@ -2122,7 +2129,7 @@ class RDoc::Markdown
self.pos = _save
break
end
- _tmp = scan(/\A(?-mix:[+*-])/)
+ _tmp = scan(/\G(?-mix:[+*-])/)
unless _tmp
self.pos = _save
break
@@ -8446,7 +8453,162 @@ class RDoc::Markdown
return _tmp
end
- # HtmlBlockInTags = (HtmlAnchor | HtmlBlockAddress | HtmlBlockBlockquote | HtmlBlockCenter | HtmlBlockDir | HtmlBlockDiv | HtmlBlockDl | HtmlBlockFieldset | HtmlBlockForm | HtmlBlockH1 | HtmlBlockH2 | HtmlBlockH3 | HtmlBlockH4 | HtmlBlockH5 | HtmlBlockH6 | HtmlBlockMenu | HtmlBlockNoframes | HtmlBlockNoscript | HtmlBlockOl | HtmlBlockP | HtmlBlockPre | HtmlBlockTable | HtmlBlockUl | HtmlBlockDd | HtmlBlockDt | HtmlBlockFrameset | HtmlBlockLi | HtmlBlockTbody | HtmlBlockTd | HtmlBlockTfoot | HtmlBlockTh | HtmlBlockThead | HtmlBlockTr | HtmlBlockScript)
+ # HtmlBlockOpenHead = "<" Spnl ("head" | "HEAD") Spnl HtmlAttribute* ">"
+ def _HtmlBlockOpenHead
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("<")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Spnl)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+
+ _save1 = self.pos
+ while true # choice
+ _tmp = match_string("head")
+ break if _tmp
+ self.pos = _save1
+ _tmp = match_string("HEAD")
+ break if _tmp
+ self.pos = _save1
+ break
+ end # end choice
+
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Spnl)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ while true
+ _tmp = apply(:_HtmlAttribute)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string(">")
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_HtmlBlockOpenHead unless _tmp
+ return _tmp
+ end
+
+ # HtmlBlockCloseHead = "<" Spnl "/" ("head" | "HEAD") Spnl ">"
+ def _HtmlBlockCloseHead
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("<")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Spnl)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("/")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+
+ _save1 = self.pos
+ while true # choice
+ _tmp = match_string("head")
+ break if _tmp
+ self.pos = _save1
+ _tmp = match_string("HEAD")
+ break if _tmp
+ self.pos = _save1
+ break
+ end # end choice
+
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Spnl)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string(">")
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_HtmlBlockCloseHead unless _tmp
+ return _tmp
+ end
+
+ # HtmlBlockHead = HtmlBlockOpenHead (!HtmlBlockCloseHead .)* HtmlBlockCloseHead
+ def _HtmlBlockHead
+
+ _save = self.pos
+ while true # sequence
+ _tmp = apply(:_HtmlBlockOpenHead)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ while true
+
+ _save2 = self.pos
+ while true # sequence
+ _save3 = self.pos
+ _tmp = apply(:_HtmlBlockCloseHead)
+ _tmp = _tmp ? nil : true
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = get_byte
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_HtmlBlockCloseHead)
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_HtmlBlockHead unless _tmp
+ return _tmp
+ end
+
+ # HtmlBlockInTags = (HtmlAnchor | HtmlBlockAddress | HtmlBlockBlockquote | HtmlBlockCenter | HtmlBlockDir | HtmlBlockDiv | HtmlBlockDl | HtmlBlockFieldset | HtmlBlockForm | HtmlBlockH1 | HtmlBlockH2 | HtmlBlockH3 | HtmlBlockH4 | HtmlBlockH5 | HtmlBlockH6 | HtmlBlockMenu | HtmlBlockNoframes | HtmlBlockNoscript | HtmlBlockOl | HtmlBlockP | HtmlBlockPre | HtmlBlockTable | HtmlBlockUl | HtmlBlockDd | HtmlBlockDt | HtmlBlockFrameset | HtmlBlockLi | HtmlBlockTbody | HtmlBlockTd | HtmlBlockTfoot | HtmlBlockTh | HtmlBlockThead | HtmlBlockTr | HtmlBlockScript | HtmlBlockHead)
def _HtmlBlockInTags
_save = self.pos
@@ -8553,6 +8715,9 @@ class RDoc::Markdown
_tmp = apply(:_HtmlBlockScript)
break if _tmp
self.pos = _save
+ _tmp = apply(:_HtmlBlockHead)
+ break if _tmp
+ self.pos = _save
break
end # end choice
@@ -9157,7 +9322,7 @@ class RDoc::Markdown
return _tmp
end
- # Inlines = (!@Endline Inline:i { i } | @Endline:c &Inline { c })+:chunks @Endline? { chunks }
+ # Inlines = (!@Endline Inline:i { i } | @Endline:c !(&{ github? } Ticks3 /[^`\n]*$/) &Inline { c })+:chunks @Endline? { chunks }
def _Inlines
_save = self.pos
@@ -9204,12 +9369,41 @@ class RDoc::Markdown
break
end
_save6 = self.pos
- _tmp = apply(:_Inline)
+
+ _save7 = self.pos
+ while true # sequence
+ _save8 = self.pos
+ _tmp = begin; github? ; end
+ self.pos = _save8
+ unless _tmp
+ self.pos = _save7
+ break
+ end
+ _tmp = apply(:_Ticks3)
+ unless _tmp
+ self.pos = _save7
+ break
+ end
+ _tmp = scan(/\G(?-mix:[^`\n]*$)/)
+ unless _tmp
+ self.pos = _save7
+ end
+ break
+ end # end sequence
+
+ _tmp = _tmp ? nil : true
self.pos = _save6
unless _tmp
self.pos = _save5
break
end
+ _save9 = self.pos
+ _tmp = apply(:_Inline)
+ self.pos = _save9
+ unless _tmp
+ self.pos = _save5
+ break
+ end
@result = begin; c ; end
_tmp = true
unless _tmp
@@ -9227,61 +9421,90 @@ class RDoc::Markdown
_ary << @result
while true
- _save7 = self.pos
+ _save10 = self.pos
while true # choice
- _save8 = self.pos
+ _save11 = self.pos
while true # sequence
- _save9 = self.pos
+ _save12 = self.pos
_tmp = _Endline()
_tmp = _tmp ? nil : true
- self.pos = _save9
+ self.pos = _save12
unless _tmp
- self.pos = _save8
+ self.pos = _save11
break
end
_tmp = apply(:_Inline)
i = @result
unless _tmp
- self.pos = _save8
+ self.pos = _save11
break
end
@result = begin; i ; end
_tmp = true
unless _tmp
- self.pos = _save8
+ self.pos = _save11
end
break
end # end sequence
break if _tmp
- self.pos = _save7
+ self.pos = _save10
- _save10 = self.pos
+ _save13 = self.pos
while true # sequence
_tmp = _Endline()
c = @result
unless _tmp
- self.pos = _save10
+ self.pos = _save13
break
end
- _save11 = self.pos
+ _save14 = self.pos
+
+ _save15 = self.pos
+ while true # sequence
+ _save16 = self.pos
+ _tmp = begin; github? ; end
+ self.pos = _save16
+ unless _tmp
+ self.pos = _save15
+ break
+ end
+ _tmp = apply(:_Ticks3)
+ unless _tmp
+ self.pos = _save15
+ break
+ end
+ _tmp = scan(/\G(?-mix:[^`\n]*$)/)
+ unless _tmp
+ self.pos = _save15
+ end
+ break
+ end # end sequence
+
+ _tmp = _tmp ? nil : true
+ self.pos = _save14
+ unless _tmp
+ self.pos = _save13
+ break
+ end
+ _save17 = self.pos
_tmp = apply(:_Inline)
- self.pos = _save11
+ self.pos = _save17
unless _tmp
- self.pos = _save10
+ self.pos = _save13
break
end
@result = begin; c ; end
_tmp = true
unless _tmp
- self.pos = _save10
+ self.pos = _save13
end
break
end # end sequence
break if _tmp
- self.pos = _save7
+ self.pos = _save10
break
end # end choice
@@ -9298,11 +9521,11 @@ class RDoc::Markdown
self.pos = _save
break
end
- _save12 = self.pos
+ _save18 = self.pos
_tmp = _Endline()
unless _tmp
_tmp = true
- self.pos = _save12
+ self.pos = _save18
end
unless _tmp
self.pos = _save
@@ -9320,7 +9543,7 @@ class RDoc::Markdown
return _tmp
end
- # Inline = (Str | @Endline | UlOrStarLine | @Space | Strong | Emph | Image | Link | NoteReference | InlineNote | Code | RawHtml | Entity | EscapedChar | Symbol)
+ # Inline = (Str | @Endline | UlOrStarLine | @Space | Strong | Emph | Strike | Image | Link | NoteReference | InlineNote | Code | RawHtml | Entity | EscapedChar | Symbol)
def _Inline
_save = self.pos
@@ -9343,6 +9566,9 @@ class RDoc::Markdown
_tmp = apply(:_Emph)
break if _tmp
self.pos = _save
+ _tmp = apply(:_Strike)
+ break if _tmp
+ self.pos = _save
_tmp = apply(:_Image)
break if _tmp
self.pos = _save
@@ -9498,7 +9724,7 @@ class RDoc::Markdown
_save3 = self.pos
while true # sequence
- _tmp = scan(/\A(?-mix:_+)/)
+ _tmp = scan(/\G(?-mix:_+)/)
unless _tmp
self.pos = _save3
break
@@ -9528,7 +9754,7 @@ class RDoc::Markdown
_save6 = self.pos
while true # sequence
- _tmp = scan(/\A(?-mix:_+)/)
+ _tmp = scan(/\G(?-mix:_+)/)
unless _tmp
self.pos = _save6
break
@@ -9591,7 +9817,7 @@ class RDoc::Markdown
break
end
_text_start = self.pos
- _tmp = scan(/\A(?-mix:[:\\`|*_{}\[\]()#+.!><-])/)
+ _tmp = scan(/\G(?-mix:[:\\`|*_{}\[\]()#+.!><-])/)
if _tmp
text = get_text(_text_start)
end
@@ -9669,7 +9895,7 @@ class RDoc::Markdown
return _tmp
end
- # NormalEndline = @Sp @Newline !@BlankLine !">" !AtxStart !(Line /={3,}|-{3,}=/ @Newline) { "\n" }
+ # NormalEndline = @Sp @Newline !@BlankLine !">" !AtxStart !(Line /={1,}|-{1,}/ @Newline) { "\n" }
def _NormalEndline
_save = self.pos
@@ -9717,7 +9943,7 @@ class RDoc::Markdown
self.pos = _save5
break
end
- _tmp = scan(/\A(?-mix:={3,}|-{3,}=)/)
+ _tmp = scan(/\G(?-mix:={1,}|-{1,})/)
unless _tmp
self.pos = _save5
break
@@ -9869,7 +10095,7 @@ class RDoc::Markdown
_save1 = self.pos
while true # sequence
_text_start = self.pos
- _tmp = scan(/\A(?-mix:\*{4,})/)
+ _tmp = scan(/\G(?-mix:\*{4,})/)
if _tmp
text = get_text(_text_start)
end
@@ -9899,7 +10125,7 @@ class RDoc::Markdown
self.pos = _save3
break
end
- _tmp = scan(/\A(?-mix:\*+)/)
+ _tmp = scan(/\G(?-mix:\*+)/)
unless _tmp
self.pos = _save3
break
@@ -9946,7 +10172,7 @@ class RDoc::Markdown
_save1 = self.pos
while true # sequence
_text_start = self.pos
- _tmp = scan(/\A(?-mix:_{4,})/)
+ _tmp = scan(/\G(?-mix:_{4,})/)
if _tmp
text = get_text(_text_start)
end
@@ -9976,7 +10202,7 @@ class RDoc::Markdown
self.pos = _save3
break
end
- _tmp = scan(/\A(?-mix:_+)/)
+ _tmp = scan(/\G(?-mix:_+)/)
unless _tmp
self.pos = _save3
break
@@ -10032,96 +10258,38 @@ class RDoc::Markdown
return _tmp
end
- # OneStarOpen = !StarLine "*" !@Spacechar !@Newline
- def _OneStarOpen
+ # Whitespace = (@Spacechar | @Newline)
+ def _Whitespace
_save = self.pos
- while true # sequence
- _save1 = self.pos
- _tmp = apply(:_StarLine)
- _tmp = _tmp ? nil : true
- self.pos = _save1
- unless _tmp
- self.pos = _save
- break
- end
- _tmp = match_string("*")
- unless _tmp
- self.pos = _save
- break
- end
- _save2 = self.pos
+ while true # choice
_tmp = _Spacechar()
- _tmp = _tmp ? nil : true
- self.pos = _save2
- unless _tmp
- self.pos = _save
- break
- end
- _save3 = self.pos
+ break if _tmp
+ self.pos = _save
_tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save3
- unless _tmp
- self.pos = _save
- end
+ break if _tmp
+ self.pos = _save
break
- end # end sequence
+ end # end choice
- set_failed_rule :_OneStarOpen unless _tmp
+ set_failed_rule :_Whitespace unless _tmp
return _tmp
end
- # OneStarClose = !@Spacechar !@Newline Inline:a "*" { a }
- def _OneStarClose
+ # EmphStar = "*" !@Whitespace @StartList:a (!"*" Inline:b { a << b } | StrongStar:b { a << b })+ "*" { emphasis a.join }
+ def _EmphStar
_save = self.pos
while true # sequence
- _save1 = self.pos
- _tmp = _Spacechar()
- _tmp = _tmp ? nil : true
- self.pos = _save1
- unless _tmp
- self.pos = _save
- break
- end
- _save2 = self.pos
- _tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save2
- unless _tmp
- self.pos = _save
- break
- end
- _tmp = apply(:_Inline)
- a = @result
- unless _tmp
- self.pos = _save
- break
- end
_tmp = match_string("*")
unless _tmp
self.pos = _save
break
end
- @result = begin; a ; end
- _tmp = true
- unless _tmp
- self.pos = _save
- end
- break
- end # end sequence
-
- set_failed_rule :_OneStarClose unless _tmp
- return _tmp
- end
-
- # EmphStar = OneStarOpen @StartList:a (!OneStarClose Inline:l { a << l })* OneStarClose:l { a << l } { emphasis a.join }
- def _EmphStar
-
- _save = self.pos
- while true # sequence
- _tmp = apply(:_OneStarOpen)
+ _save1 = self.pos
+ _tmp = _Whitespace()
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
unless _tmp
self.pos = _save
break
@@ -10132,47 +10300,124 @@ class RDoc::Markdown
self.pos = _save
break
end
- while true
+ _save2 = self.pos
- _save2 = self.pos
+ _save3 = self.pos
+ while true # choice
+
+ _save4 = self.pos
while true # sequence
- _save3 = self.pos
- _tmp = apply(:_OneStarClose)
+ _save5 = self.pos
+ _tmp = match_string("*")
_tmp = _tmp ? nil : true
- self.pos = _save3
+ self.pos = _save5
unless _tmp
- self.pos = _save2
+ self.pos = _save4
break
end
_tmp = apply(:_Inline)
- l = @result
+ b = @result
unless _tmp
- self.pos = _save2
+ self.pos = _save4
break
end
- @result = begin; a << l ; end
+ @result = begin; a << b ; end
_tmp = true
unless _tmp
- self.pos = _save2
+ self.pos = _save4
end
break
end # end sequence
- break unless _tmp
- end
- _tmp = true
- unless _tmp
- self.pos = _save
+ break if _tmp
+ self.pos = _save3
+
+ _save6 = self.pos
+ while true # sequence
+ _tmp = apply(:_StrongStar)
+ b = @result
+ unless _tmp
+ self.pos = _save6
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save6
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save3
break
+ end # end choice
+
+ if _tmp
+ while true
+
+ _save7 = self.pos
+ while true # choice
+
+ _save8 = self.pos
+ while true # sequence
+ _save9 = self.pos
+ _tmp = match_string("*")
+ _tmp = _tmp ? nil : true
+ self.pos = _save9
+ unless _tmp
+ self.pos = _save8
+ break
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save8
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save8
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save7
+
+ _save10 = self.pos
+ while true # sequence
+ _tmp = apply(:_StrongStar)
+ b = @result
+ unless _tmp
+ self.pos = _save10
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save10
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save7
+ break
+ end # end choice
+
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
end
- _tmp = apply(:_OneStarClose)
- l = @result
unless _tmp
self.pos = _save
break
end
- @result = begin; a << l ; end
- _tmp = true
+ _tmp = match_string("*")
unless _tmp
self.pos = _save
break
@@ -10189,147 +10434,148 @@ class RDoc::Markdown
return _tmp
end
- # OneUlOpen = !UlLine "_" !@Spacechar !@Newline
- def _OneUlOpen
+ # EmphUl = "_" !@Whitespace @StartList:a (!"_" Inline:b { a << b } | StrongUl:b { a << b })+ "_" { emphasis a.join }
+ def _EmphUl
_save = self.pos
while true # sequence
- _save1 = self.pos
- _tmp = apply(:_UlLine)
- _tmp = _tmp ? nil : true
- self.pos = _save1
- unless _tmp
- self.pos = _save
- break
- end
_tmp = match_string("_")
unless _tmp
self.pos = _save
break
end
- _save2 = self.pos
- _tmp = _Spacechar()
- _tmp = _tmp ? nil : true
- self.pos = _save2
- unless _tmp
- self.pos = _save
- break
- end
- _save3 = self.pos
- _tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save3
- unless _tmp
- self.pos = _save
- end
- break
- end # end sequence
-
- set_failed_rule :_OneUlOpen unless _tmp
- return _tmp
- end
-
- # OneUlClose = !@Spacechar !@Newline Inline:a "_" { a }
- def _OneUlClose
-
- _save = self.pos
- while true # sequence
_save1 = self.pos
- _tmp = _Spacechar()
+ _tmp = _Whitespace()
_tmp = _tmp ? nil : true
self.pos = _save1
unless _tmp
self.pos = _save
break
end
- _save2 = self.pos
- _tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save2
- unless _tmp
- self.pos = _save
- break
- end
- _tmp = apply(:_Inline)
- a = @result
- unless _tmp
- self.pos = _save
- break
- end
- _tmp = match_string("_")
- unless _tmp
- self.pos = _save
- break
- end
- @result = begin; a ; end
- _tmp = true
- unless _tmp
- self.pos = _save
- end
- break
- end # end sequence
-
- set_failed_rule :_OneUlClose unless _tmp
- return _tmp
- end
-
- # EmphUl = OneUlOpen @StartList:a (!OneUlClose Inline:l { a << l })* OneUlClose:l { a << l } { emphasis a.join }
- def _EmphUl
-
- _save = self.pos
- while true # sequence
- _tmp = apply(:_OneUlOpen)
- unless _tmp
- self.pos = _save
- break
- end
_tmp = _StartList()
a = @result
unless _tmp
self.pos = _save
break
end
- while true
+ _save2 = self.pos
- _save2 = self.pos
+ _save3 = self.pos
+ while true # choice
+
+ _save4 = self.pos
while true # sequence
- _save3 = self.pos
- _tmp = apply(:_OneUlClose)
+ _save5 = self.pos
+ _tmp = match_string("_")
_tmp = _tmp ? nil : true
- self.pos = _save3
+ self.pos = _save5
unless _tmp
- self.pos = _save2
+ self.pos = _save4
break
end
_tmp = apply(:_Inline)
- l = @result
+ b = @result
unless _tmp
- self.pos = _save2
+ self.pos = _save4
break
end
- @result = begin; a << l ; end
+ @result = begin; a << b ; end
_tmp = true
unless _tmp
- self.pos = _save2
+ self.pos = _save4
end
break
end # end sequence
- break unless _tmp
- end
- _tmp = true
- unless _tmp
- self.pos = _save
+ break if _tmp
+ self.pos = _save3
+
+ _save6 = self.pos
+ while true # sequence
+ _tmp = apply(:_StrongUl)
+ b = @result
+ unless _tmp
+ self.pos = _save6
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save6
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save3
break
+ end # end choice
+
+ if _tmp
+ while true
+
+ _save7 = self.pos
+ while true # choice
+
+ _save8 = self.pos
+ while true # sequence
+ _save9 = self.pos
+ _tmp = match_string("_")
+ _tmp = _tmp ? nil : true
+ self.pos = _save9
+ unless _tmp
+ self.pos = _save8
+ break
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save8
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save8
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save7
+
+ _save10 = self.pos
+ while true # sequence
+ _tmp = apply(:_StrongUl)
+ b = @result
+ unless _tmp
+ self.pos = _save10
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save10
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save7
+ break
+ end # end choice
+
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
end
- _tmp = apply(:_OneUlClose)
- l = @result
unless _tmp
self.pos = _save
break
end
- @result = begin; a << l ; end
- _tmp = true
+ _tmp = match_string("_")
unless _tmp
self.pos = _save
break
@@ -10364,69 +10610,89 @@ class RDoc::Markdown
return _tmp
end
- # TwoStarOpen = !StarLine "**" !@Spacechar !@Newline
- def _TwoStarOpen
+ # StrongStar = "**" !@Whitespace @StartList:a (!"**" Inline:b { a << b })+ "**" { strong a.join }
+ def _StrongStar
_save = self.pos
while true # sequence
- _save1 = self.pos
- _tmp = apply(:_StarLine)
- _tmp = _tmp ? nil : true
- self.pos = _save1
- unless _tmp
- self.pos = _save
- break
- end
_tmp = match_string("**")
unless _tmp
self.pos = _save
break
end
- _save2 = self.pos
- _tmp = _Spacechar()
+ _save1 = self.pos
+ _tmp = _Whitespace()
_tmp = _tmp ? nil : true
- self.pos = _save2
+ self.pos = _save1
unless _tmp
self.pos = _save
break
end
- _save3 = self.pos
- _tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save3
- unless _tmp
- self.pos = _save
- end
- break
- end # end sequence
-
- set_failed_rule :_TwoStarOpen unless _tmp
- return _tmp
- end
-
- # TwoStarClose = !@Spacechar !@Newline Inline:a "**" { a }
- def _TwoStarClose
-
- _save = self.pos
- while true # sequence
- _save1 = self.pos
- _tmp = _Spacechar()
- _tmp = _tmp ? nil : true
- self.pos = _save1
+ _tmp = _StartList()
+ a = @result
unless _tmp
self.pos = _save
break
end
_save2 = self.pos
- _tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save2
- unless _tmp
- self.pos = _save
+
+ _save3 = self.pos
+ while true # sequence
+ _save4 = self.pos
+ _tmp = match_string("**")
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
break
+ end # end sequence
+
+ if _tmp
+ while true
+
+ _save5 = self.pos
+ while true # sequence
+ _save6 = self.pos
+ _tmp = match_string("**")
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
end
- _tmp = apply(:_Inline)
- a = @result
unless _tmp
self.pos = _save
break
@@ -10436,7 +10702,7 @@ class RDoc::Markdown
self.pos = _save
break
end
- @result = begin; a ; end
+ @result = begin; strong a.join ; end
_tmp = true
unless _tmp
self.pos = _save
@@ -10444,16 +10710,24 @@ class RDoc::Markdown
break
end # end sequence
- set_failed_rule :_TwoStarClose unless _tmp
+ set_failed_rule :_StrongStar unless _tmp
return _tmp
end
- # StrongStar = TwoStarOpen @StartList:a (!TwoStarClose Inline:l { a << l })* TwoStarClose:l { a << l } { strong a.join }
- def _StrongStar
+ # StrongUl = "__" !@Whitespace @StartList:a (!"__" Inline:b { a << b })+ "__" { strong a.join }
+ def _StrongUl
_save = self.pos
while true # sequence
- _tmp = apply(:_TwoStarOpen)
+ _tmp = match_string("__")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save1 = self.pos
+ _tmp = _Whitespace()
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
unless _tmp
self.pos = _save
break
@@ -10464,47 +10738,70 @@ class RDoc::Markdown
self.pos = _save
break
end
- while true
+ _save2 = self.pos
- _save2 = self.pos
- while true # sequence
- _save3 = self.pos
- _tmp = apply(:_TwoStarClose)
- _tmp = _tmp ? nil : true
+ _save3 = self.pos
+ while true # sequence
+ _save4 = self.pos
+ _tmp = match_string("__")
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
self.pos = _save3
- unless _tmp
- self.pos = _save2
- break
- end
- _tmp = apply(:_Inline)
- l = @result
- unless _tmp
- self.pos = _save2
- break
- end
- @result = begin; a << l ; end
- _tmp = true
- unless _tmp
- self.pos = _save2
- end
break
- end # end sequence
-
- break unless _tmp
- end
- _tmp = true
- unless _tmp
- self.pos = _save
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
break
+ end # end sequence
+
+ if _tmp
+ while true
+
+ _save5 = self.pos
+ while true # sequence
+ _save6 = self.pos
+ _tmp = match_string("__")
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
end
- _tmp = apply(:_TwoStarClose)
- l = @result
unless _tmp
self.pos = _save
break
end
- @result = begin; a << l ; end
- _tmp = true
+ _tmp = match_string("__")
unless _tmp
self.pos = _save
break
@@ -10517,156 +10814,110 @@ class RDoc::Markdown
break
end # end sequence
- set_failed_rule :_StrongStar unless _tmp
+ set_failed_rule :_StrongUl unless _tmp
return _tmp
end
- # TwoUlOpen = !UlLine "__" !@Spacechar !@Newline
- def _TwoUlOpen
+ # Strike = &{ strike? } "~~" !@Whitespace @StartList:a (!"~~" Inline:b { a << b })+ "~~" { strike a.join }
+ def _Strike
_save = self.pos
while true # sequence
_save1 = self.pos
- _tmp = apply(:_UlLine)
- _tmp = _tmp ? nil : true
+ _tmp = begin; strike? ; end
self.pos = _save1
unless _tmp
self.pos = _save
break
end
- _tmp = match_string("__")
+ _tmp = match_string("~~")
unless _tmp
self.pos = _save
break
end
_save2 = self.pos
- _tmp = _Spacechar()
+ _tmp = _Whitespace()
_tmp = _tmp ? nil : true
self.pos = _save2
unless _tmp
self.pos = _save
break
end
- _save3 = self.pos
- _tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save3
- unless _tmp
- self.pos = _save
- end
- break
- end # end sequence
-
- set_failed_rule :_TwoUlOpen unless _tmp
- return _tmp
- end
-
- # TwoUlClose = !@Spacechar !@Newline Inline:a "__" { a }
- def _TwoUlClose
-
- _save = self.pos
- while true # sequence
- _save1 = self.pos
- _tmp = _Spacechar()
- _tmp = _tmp ? nil : true
- self.pos = _save1
- unless _tmp
- self.pos = _save
- break
- end
- _save2 = self.pos
- _tmp = _Newline()
- _tmp = _tmp ? nil : true
- self.pos = _save2
- unless _tmp
- self.pos = _save
- break
- end
- _tmp = apply(:_Inline)
+ _tmp = _StartList()
a = @result
unless _tmp
self.pos = _save
break
end
- _tmp = match_string("__")
- unless _tmp
- self.pos = _save
- break
- end
- @result = begin; a ; end
- _tmp = true
- unless _tmp
- self.pos = _save
- end
- break
- end # end sequence
-
- set_failed_rule :_TwoUlClose unless _tmp
- return _tmp
- end
-
- # StrongUl = TwoUlOpen @StartList:a (!TwoUlClose Inline:i { a << i })* TwoUlClose:l { a << l } { strong a.join }
- def _StrongUl
+ _save3 = self.pos
- _save = self.pos
- while true # sequence
- _tmp = apply(:_TwoUlOpen)
- unless _tmp
- self.pos = _save
- break
- end
- _tmp = _StartList()
- a = @result
- unless _tmp
- self.pos = _save
+ _save4 = self.pos
+ while true # sequence
+ _save5 = self.pos
+ _tmp = match_string("~~")
+ _tmp = _tmp ? nil : true
+ self.pos = _save5
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save4
+ end
break
- end
- while true
+ end # end sequence
- _save2 = self.pos
- while true # sequence
- _save3 = self.pos
- _tmp = apply(:_TwoUlClose)
- _tmp = _tmp ? nil : true
- self.pos = _save3
- unless _tmp
- self.pos = _save2
- break
- end
- _tmp = apply(:_Inline)
- i = @result
- unless _tmp
- self.pos = _save2
+ if _tmp
+ while true
+
+ _save6 = self.pos
+ while true # sequence
+ _save7 = self.pos
+ _tmp = match_string("~~")
+ _tmp = _tmp ? nil : true
+ self.pos = _save7
+ unless _tmp
+ self.pos = _save6
+ break
+ end
+ _tmp = apply(:_Inline)
+ b = @result
+ unless _tmp
+ self.pos = _save6
+ break
+ end
+ @result = begin; a << b ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save6
+ end
break
- end
- @result = begin; a << i ; end
- _tmp = true
- unless _tmp
- self.pos = _save2
- end
- break
- end # end sequence
+ end # end sequence
- break unless _tmp
- end
- _tmp = true
- unless _tmp
- self.pos = _save
- break
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save3
end
- _tmp = apply(:_TwoUlClose)
- l = @result
unless _tmp
self.pos = _save
break
end
- @result = begin; a << l ; end
- _tmp = true
+ _tmp = match_string("~~")
unless _tmp
self.pos = _save
break
end
- @result = begin; strong a.join ; end
+ @result = begin; strike a.join ; end
_tmp = true
unless _tmp
self.pos = _save
@@ -10674,7 +10925,7 @@ class RDoc::Markdown
break
end # end sequence
- set_failed_rule :_StrongUl unless _tmp
+ set_failed_rule :_Strike unless _tmp
return _tmp
end
@@ -10853,7 +11104,7 @@ class RDoc::Markdown
return _tmp
end
- # ExplicitLink = Label:l Spnl "(" @Sp Source:s Spnl Title @Sp ")" { "{#{l}}[#{s}]" }
+ # ExplicitLink = Label:l "(" @Sp Source:s Spnl Title @Sp ")" { "{#{l}}[#{s}]" }
def _ExplicitLink
_save = self.pos
@@ -10864,11 +11115,6 @@ class RDoc::Markdown
self.pos = _save
break
end
- _tmp = apply(:_Spnl)
- unless _tmp
- self.pos = _save
- break
- end
_tmp = match_string("(")
unless _tmp
self.pos = _save
@@ -10977,130 +11223,119 @@ class RDoc::Markdown
return _tmp
end
- # SourceContents = (((!"(" !")" !">" Nonspacechar)+ | "(" SourceContents ")")* | "")
+ # SourceContents = ((!"(" !")" !">" Nonspacechar)+ | "(" SourceContents ")")*
def _SourceContents
+ while true
- _save = self.pos
- while true # choice
- while true
-
+ _save1 = self.pos
+ while true # choice
_save2 = self.pos
- while true # choice
- _save3 = self.pos
+ _save3 = self.pos
+ while true # sequence
_save4 = self.pos
- while true # sequence
- _save5 = self.pos
- _tmp = match_string("(")
- _tmp = _tmp ? nil : true
- self.pos = _save5
- unless _tmp
- self.pos = _save4
- break
- end
- _save6 = self.pos
- _tmp = match_string(")")
- _tmp = _tmp ? nil : true
- self.pos = _save6
- unless _tmp
- self.pos = _save4
- break
- end
- _save7 = self.pos
- _tmp = match_string(">")
- _tmp = _tmp ? nil : true
- self.pos = _save7
- unless _tmp
- self.pos = _save4
- break
- end
- _tmp = apply(:_Nonspacechar)
- unless _tmp
- self.pos = _save4
- end
+ _tmp = match_string("(")
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save3
break
- end # end sequence
+ end
+ _save5 = self.pos
+ _tmp = match_string(")")
+ _tmp = _tmp ? nil : true
+ self.pos = _save5
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _save6 = self.pos
+ _tmp = match_string(">")
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _tmp = apply(:_Nonspacechar)
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
- if _tmp
- while true
+ if _tmp
+ while true
+ _save7 = self.pos
+ while true # sequence
_save8 = self.pos
- while true # sequence
- _save9 = self.pos
- _tmp = match_string("(")
- _tmp = _tmp ? nil : true
- self.pos = _save9
- unless _tmp
- self.pos = _save8
- break
- end
- _save10 = self.pos
- _tmp = match_string(")")
- _tmp = _tmp ? nil : true
- self.pos = _save10
- unless _tmp
- self.pos = _save8
- break
- end
- _save11 = self.pos
- _tmp = match_string(">")
- _tmp = _tmp ? nil : true
- self.pos = _save11
- unless _tmp
- self.pos = _save8
- break
- end
- _tmp = apply(:_Nonspacechar)
- unless _tmp
- self.pos = _save8
- end
+ _tmp = match_string("(")
+ _tmp = _tmp ? nil : true
+ self.pos = _save8
+ unless _tmp
+ self.pos = _save7
break
- end # end sequence
+ end
+ _save9 = self.pos
+ _tmp = match_string(")")
+ _tmp = _tmp ? nil : true
+ self.pos = _save9
+ unless _tmp
+ self.pos = _save7
+ break
+ end
+ _save10 = self.pos
+ _tmp = match_string(">")
+ _tmp = _tmp ? nil : true
+ self.pos = _save10
+ unless _tmp
+ self.pos = _save7
+ break
+ end
+ _tmp = apply(:_Nonspacechar)
+ unless _tmp
+ self.pos = _save7
+ end
+ break
+ end # end sequence
- break unless _tmp
- end
- _tmp = true
- else
- self.pos = _save3
+ break unless _tmp
end
- break if _tmp
+ _tmp = true
+ else
self.pos = _save2
+ end
+ break if _tmp
+ self.pos = _save1
- _save12 = self.pos
- while true # sequence
- _tmp = match_string("(")
- unless _tmp
- self.pos = _save12
- break
- end
- _tmp = apply(:_SourceContents)
- unless _tmp
- self.pos = _save12
- break
- end
- _tmp = match_string(")")
- unless _tmp
- self.pos = _save12
- end
+ _save11 = self.pos
+ while true # sequence
+ _tmp = match_string("(")
+ unless _tmp
+ self.pos = _save11
break
- end # end sequence
-
- break if _tmp
- self.pos = _save2
+ end
+ _tmp = apply(:_SourceContents)
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = match_string(")")
+ unless _tmp
+ self.pos = _save11
+ end
break
- end # end choice
+ end # end sequence
- break unless _tmp
- end
- _tmp = true
- break if _tmp
- self.pos = _save
- _tmp = match_string("")
- break if _tmp
- self.pos = _save
- break
- end # end choice
+ break if _tmp
+ self.pos = _save1
+ break
+ end # end choice
+ break unless _tmp
+ end
+ _tmp = true
set_failed_rule :_SourceContents unless _tmp
return _tmp
end
@@ -11328,7 +11563,7 @@ class RDoc::Markdown
_save1 = self.pos
while true # sequence
- _tmp = scan(/\A(?-mix:[A-Za-z]+)/)
+ _tmp = scan(/\G(?-mix:[A-Za-z]+)/)
unless _tmp
self.pos = _save1
break
@@ -11453,7 +11688,7 @@ class RDoc::Markdown
_save2 = self.pos
while true # sequence
- _tmp = scan(/\A(?i-mx:[\w+.\/!%~$-]+)/)
+ _tmp = scan(/\G(?i-mx:[\w+.\/!%~$-]+)/)
unless _tmp
self.pos = _save2
break
@@ -12317,7 +12552,7 @@ class RDoc::Markdown
self.pos = _save10
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save10
end
@@ -12454,7 +12689,7 @@ class RDoc::Markdown
self.pos = _save24
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save24
end
@@ -12631,7 +12866,7 @@ class RDoc::Markdown
self.pos = _save40
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save40
end
@@ -12768,7 +13003,7 @@ class RDoc::Markdown
self.pos = _save54
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save54
end
@@ -12945,7 +13180,7 @@ class RDoc::Markdown
self.pos = _save70
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save70
end
@@ -13082,7 +13317,7 @@ class RDoc::Markdown
self.pos = _save84
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save84
end
@@ -13259,7 +13494,7 @@ class RDoc::Markdown
self.pos = _save100
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save100
end
@@ -13396,7 +13631,7 @@ class RDoc::Markdown
self.pos = _save114
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save114
end
@@ -13573,7 +13808,7 @@ class RDoc::Markdown
self.pos = _save130
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save130
end
@@ -13710,7 +13945,7 @@ class RDoc::Markdown
self.pos = _save144
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save144
end
@@ -14357,12 +14592,12 @@ class RDoc::Markdown
return _tmp
end
- # SpecialChar = (/[*_`&\[\]()<!#\\'"]/ | @ExtendedSpecialChar)
+ # SpecialChar = (/[~*_`&\[\]()<!#\\'"]/ | @ExtendedSpecialChar)
def _SpecialChar
_save = self.pos
while true # choice
- _tmp = scan(/\A(?-mix:[*_`&\[\]()<!#\\'"])/)
+ _tmp = scan(/\G(?-mix:[~*_`&\[\]()<!#\\'"])/)
break if _tmp
self.pos = _save
_tmp = _ExtendedSpecialChar()
@@ -14455,13 +14690,6 @@ class RDoc::Markdown
return _tmp
end
- # NonAlphanumeric = %literals.NonAlphanumeric
- def _NonAlphanumeric
- _tmp = @_grammar_literals.external_invoke(self, :_NonAlphanumeric)
- set_failed_rule :_NonAlphanumeric unless _tmp
- return _tmp
- end
-
# Spacechar = %literals.Spacechar
def _Spacechar
_tmp = @_grammar_literals.external_invoke(self, :_Spacechar)
@@ -14474,13 +14702,13 @@ class RDoc::Markdown
_save = self.pos
while true # sequence
- _tmp = scan(/\A(?i-mx:&#x)/)
+ _tmp = scan(/\G(?i-mx:&#x)/)
unless _tmp
self.pos = _save
break
end
_text_start = self.pos
- _tmp = scan(/\A(?-mix:[0-9a-fA-F]+)/)
+ _tmp = scan(/\G(?-mix:[0-9a-fA-F]+)/)
if _tmp
text = get_text(_text_start)
end
@@ -14516,7 +14744,7 @@ class RDoc::Markdown
break
end
_text_start = self.pos
- _tmp = scan(/\A(?-mix:[0-9]+)/)
+ _tmp = scan(/\G(?-mix:[0-9]+)/)
if _tmp
text = get_text(_text_start)
end
@@ -14552,7 +14780,7 @@ class RDoc::Markdown
break
end
_text_start = self.pos
- _tmp = scan(/\A(?-mix:[A-Za-z0-9]+)/)
+ _tmp = scan(/\G(?-mix:[A-Za-z0-9]+)/)
if _tmp
text = get_text(_text_start)
end
@@ -14584,14 +14812,14 @@ class RDoc::Markdown
# NonindentSpace = / {0,3}/
def _NonindentSpace
- _tmp = scan(/\A(?-mix: {0,3})/)
+ _tmp = scan(/\G(?-mix: {0,3})/)
set_failed_rule :_NonindentSpace unless _tmp
return _tmp
end
# Indent = /\t| /
def _Indent
- _tmp = scan(/\A(?-mix:\t| )/)
+ _tmp = scan(/\G(?-mix:\t| )/)
set_failed_rule :_Indent unless _tmp
return _tmp
end
@@ -15189,7 +15417,7 @@ class RDoc::Markdown
return _tmp
end
- # InlineNote = &{ notes? } "^[" @StartList:a (!"]" Inline:l { a << l })+ "]" { ref = [:inline, @note_order.length] @footnotes[ref] = paragraph a note_for ref }
+ # InlineNote = &{ notes? } "^[" @StartList:a (!"]" Inline:l { a << l })+ "]" { ref = [:inline, @note_order.length] @footnotes[ref] = paragraph a note_for ref }
def _InlineNote
_save = self.pos
@@ -15280,8 +15508,7 @@ class RDoc::Markdown
self.pos = _save
break
end
- @result = begin;
- ref = [:inline, @note_order.length]
+ @result = begin; ref = [:inline, @note_order.length]
@footnotes[ref] = paragraph a
note_for ref
@@ -15534,7 +15761,7 @@ class RDoc::Markdown
self.pos = _save11
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save11
end
@@ -15615,7 +15842,7 @@ class RDoc::Markdown
self.pos = _save19
break
end
- _tmp = scan(/\A(?-mix:`+)/)
+ _tmp = scan(/\G(?-mix:`+)/)
unless _tmp
self.pos = _save19
end
@@ -15680,6 +15907,338 @@ class RDoc::Markdown
return _tmp
end
+ # Table = &{ github? } TableRow:header TableLine:line TableRow+:body { table = RDoc::Markup::Table.new(header, line, body) }
+ def _Table
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = begin; github? ; end
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_TableRow)
+ header = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_TableLine)
+ line = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _ary = []
+ _tmp = apply(:_TableRow)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_TableRow)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save2
+ end
+ body = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; table = RDoc::Markup::Table.new(header, line, body) ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Table unless _tmp
+ return _tmp
+ end
+
+ # TableRow = TableItem+:row "|" @Newline { row }
+ def _TableRow
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_TableItem)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_TableItem)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ row = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("|")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = _Newline()
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; row ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_TableRow unless _tmp
+ return _tmp
+ end
+
+ # TableItem = "|" < (!"|" !@Newline .)+ > { text.strip }
+ def _TableItem
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("|")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _text_start = self.pos
+ _save1 = self.pos
+
+ _save2 = self.pos
+ while true # sequence
+ _save3 = self.pos
+ _tmp = match_string("|")
+ _tmp = _tmp ? nil : true
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _save4 = self.pos
+ _tmp = _Newline()
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = get_byte
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ if _tmp
+ while true
+
+ _save5 = self.pos
+ while true # sequence
+ _save6 = self.pos
+ _tmp = match_string("|")
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _save7 = self.pos
+ _tmp = _Newline()
+ _tmp = _tmp ? nil : true
+ self.pos = _save7
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = get_byte
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save1
+ end
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text.strip ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_TableItem unless _tmp
+ return _tmp
+ end
+
+ # TableLine = TableColumn+:line "|" @Newline { line }
+ def _TableLine
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_TableColumn)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_TableColumn)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ line = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("|")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = _Newline()
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; line ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_TableLine unless _tmp
+ return _tmp
+ end
+
+ # TableColumn = "|" < ("-"+ ":"? | ":" "-"*) > { text.start_with?(":") ? :left : text.end_with?(":") ? :right : nil }
+ def _TableColumn
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("|")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _text_start = self.pos
+
+ _save1 = self.pos
+ while true # choice
+
+ _save2 = self.pos
+ while true # sequence
+ _save3 = self.pos
+ _tmp = match_string("-")
+ if _tmp
+ while true
+ _tmp = match_string("-")
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save3
+ end
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _save4 = self.pos
+ _tmp = match_string(":")
+ unless _tmp
+ _tmp = true
+ self.pos = _save4
+ end
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save1
+
+ _save5 = self.pos
+ while true # sequence
+ _tmp = match_string(":")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ while true
+ _tmp = match_string("-")
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save1
+ break
+ end # end choice
+
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text.start_with?(":") ? :left :
+ text.end_with?(":") ? :right : nil
+ ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_TableColumn unless _tmp
+ return _tmp
+ end
+
# DefinitionList = &{ definition_lists? } DefinitionListItem+:list { RDoc::Markup::List.new :NOTE, *list.flatten }
def _DefinitionList
@@ -15879,17 +16438,17 @@ class RDoc::Markdown
Rules = {}
Rules[:_root] = rule_info("root", "Doc")
Rules[:_Doc] = rule_info("Doc", "BOM? Block*:a { RDoc::Markup::Document.new(*a.compact) }")
- Rules[:_Block] = rule_info("Block", "@BlankLine* (BlockQuote | Verbatim | CodeFence | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain)")
+ Rules[:_Block] = rule_info("Block", "@BlankLine* (BlockQuote | Verbatim | CodeFence | Table | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain)")
Rules[:_Para] = rule_info("Para", "@NonindentSpace Inlines:a @BlankLine+ { paragraph a }")
Rules[:_Plain] = rule_info("Plain", "Inlines:a { paragraph a }")
- Rules[:_AtxInline] = rule_info("AtxInline", "!@Newline !(@Sp? /\#*/ @Sp @Newline) Inline")
+ Rules[:_AtxInline] = rule_info("AtxInline", "!@Newline !(@Sp /\#*/ @Sp @Newline) Inline")
Rules[:_AtxStart] = rule_info("AtxStart", "< /\\\#{1,6}/ > { text.length }")
- Rules[:_AtxHeading] = rule_info("AtxHeading", "AtxStart:s @Sp? AtxInline+:a (@Sp? /\#*/ @Sp)? @Newline { RDoc::Markup::Heading.new(s, a.join) }")
+ Rules[:_AtxHeading] = rule_info("AtxHeading", "AtxStart:s @Sp AtxInline+:a (@Sp /\#*/ @Sp)? @Newline { RDoc::Markup::Heading.new(s, a.join) }")
Rules[:_SetextHeading] = rule_info("SetextHeading", "(SetextHeading1 | SetextHeading2)")
- Rules[:_SetextBottom1] = rule_info("SetextBottom1", "/={3,}/ @Newline")
- Rules[:_SetextBottom2] = rule_info("SetextBottom2", "/-{3,}/ @Newline")
- Rules[:_SetextHeading1] = rule_info("SetextHeading1", "&(@RawLine SetextBottom1) @StartList:a (!@Endline Inline:b { a << b })+ @Sp? @Newline SetextBottom1 { RDoc::Markup::Heading.new(1, a.join) }")
- Rules[:_SetextHeading2] = rule_info("SetextHeading2", "&(@RawLine SetextBottom2) @StartList:a (!@Endline Inline:b { a << b })+ @Sp? @Newline SetextBottom2 { RDoc::Markup::Heading.new(2, a.join) }")
+ Rules[:_SetextBottom1] = rule_info("SetextBottom1", "/={1,}/ @Newline")
+ Rules[:_SetextBottom2] = rule_info("SetextBottom2", "/-{1,}/ @Newline")
+ Rules[:_SetextHeading1] = rule_info("SetextHeading1", "&(@RawLine SetextBottom1) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom1 { RDoc::Markup::Heading.new(1, a.join) }")
+ Rules[:_SetextHeading2] = rule_info("SetextHeading2", "&(@RawLine SetextBottom2) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom2 { RDoc::Markup::Heading.new(2, a.join) }")
Rules[:_Heading] = rule_info("Heading", "(SetextHeading | AtxHeading)")
Rules[:_BlockQuote] = rule_info("BlockQuote", "BlockQuoteRaw:a { RDoc::Markup::BlockQuote.new(*a) }")
Rules[:_BlockQuoteRaw] = rule_info("BlockQuoteRaw", "@StartList:a (\">\" \" \"? Line:l { a << l } (!\">\" !@BlankLine Line:c { a << c })* (@BlankLine:n { a << n })*)+ { inner_parse a.join }")
@@ -16010,7 +16569,10 @@ class RDoc::Markdown
Rules[:_HtmlBlockOpenScript] = rule_info("HtmlBlockOpenScript", "\"<\" Spnl (\"script\" | \"SCRIPT\") Spnl HtmlAttribute* \">\"")
Rules[:_HtmlBlockCloseScript] = rule_info("HtmlBlockCloseScript", "\"<\" Spnl \"/\" (\"script\" | \"SCRIPT\") Spnl \">\"")
Rules[:_HtmlBlockScript] = rule_info("HtmlBlockScript", "HtmlBlockOpenScript (!HtmlBlockCloseScript .)* HtmlBlockCloseScript")
- Rules[:_HtmlBlockInTags] = rule_info("HtmlBlockInTags", "(HtmlAnchor | HtmlBlockAddress | HtmlBlockBlockquote | HtmlBlockCenter | HtmlBlockDir | HtmlBlockDiv | HtmlBlockDl | HtmlBlockFieldset | HtmlBlockForm | HtmlBlockH1 | HtmlBlockH2 | HtmlBlockH3 | HtmlBlockH4 | HtmlBlockH5 | HtmlBlockH6 | HtmlBlockMenu | HtmlBlockNoframes | HtmlBlockNoscript | HtmlBlockOl | HtmlBlockP | HtmlBlockPre | HtmlBlockTable | HtmlBlockUl | HtmlBlockDd | HtmlBlockDt | HtmlBlockFrameset | HtmlBlockLi | HtmlBlockTbody | HtmlBlockTd | HtmlBlockTfoot | HtmlBlockTh | HtmlBlockThead | HtmlBlockTr | HtmlBlockScript)")
+ Rules[:_HtmlBlockOpenHead] = rule_info("HtmlBlockOpenHead", "\"<\" Spnl (\"head\" | \"HEAD\") Spnl HtmlAttribute* \">\"")
+ Rules[:_HtmlBlockCloseHead] = rule_info("HtmlBlockCloseHead", "\"<\" Spnl \"/\" (\"head\" | \"HEAD\") Spnl \">\"")
+ Rules[:_HtmlBlockHead] = rule_info("HtmlBlockHead", "HtmlBlockOpenHead (!HtmlBlockCloseHead .)* HtmlBlockCloseHead")
+ Rules[:_HtmlBlockInTags] = rule_info("HtmlBlockInTags", "(HtmlAnchor | HtmlBlockAddress | HtmlBlockBlockquote | HtmlBlockCenter | HtmlBlockDir | HtmlBlockDiv | HtmlBlockDl | HtmlBlockFieldset | HtmlBlockForm | HtmlBlockH1 | HtmlBlockH2 | HtmlBlockH3 | HtmlBlockH4 | HtmlBlockH5 | HtmlBlockH6 | HtmlBlockMenu | HtmlBlockNoframes | HtmlBlockNoscript | HtmlBlockOl | HtmlBlockP | HtmlBlockPre | HtmlBlockTable | HtmlBlockUl | HtmlBlockDd | HtmlBlockDt | HtmlBlockFrameset | HtmlBlockLi | HtmlBlockTbody | HtmlBlockTd | HtmlBlockTfoot | HtmlBlockTh | HtmlBlockThead | HtmlBlockTr | HtmlBlockScript | HtmlBlockHead)")
Rules[:_HtmlBlock] = rule_info("HtmlBlock", "< (HtmlBlockInTags | HtmlComment | HtmlBlockSelfClosing | HtmlUnclosed) > @BlankLine+ { if html? then RDoc::Markup::Raw.new text end }")
Rules[:_HtmlUnclosed] = rule_info("HtmlUnclosed", "\"<\" Spnl HtmlUnclosedType Spnl HtmlAttribute* Spnl \">\"")
Rules[:_HtmlUnclosedType] = rule_info("HtmlUnclosedType", "(\"HR\" | \"hr\")")
@@ -16020,15 +16582,15 @@ class RDoc::Markdown
Rules[:_StyleClose] = rule_info("StyleClose", "\"<\" Spnl \"/\" (\"style\" | \"STYLE\") Spnl \">\"")
Rules[:_InStyleTags] = rule_info("InStyleTags", "StyleOpen (!StyleClose .)* StyleClose")
Rules[:_StyleBlock] = rule_info("StyleBlock", "< InStyleTags > @BlankLine* { if css? then RDoc::Markup::Raw.new text end }")
- Rules[:_Inlines] = rule_info("Inlines", "(!@Endline Inline:i { i } | @Endline:c &Inline { c })+:chunks @Endline? { chunks }")
- Rules[:_Inline] = rule_info("Inline", "(Str | @Endline | UlOrStarLine | @Space | Strong | Emph | Image | Link | NoteReference | InlineNote | Code | RawHtml | Entity | EscapedChar | Symbol)")
+ Rules[:_Inlines] = rule_info("Inlines", "(!@Endline Inline:i { i } | @Endline:c !(&{ github? } Ticks3 /[^`\\n]*$/) &Inline { c })+:chunks @Endline? { chunks }")
+ Rules[:_Inline] = rule_info("Inline", "(Str | @Endline | UlOrStarLine | @Space | Strong | Emph | Strike | Image | Link | NoteReference | InlineNote | Code | RawHtml | Entity | EscapedChar | Symbol)")
Rules[:_Space] = rule_info("Space", "@Spacechar+ { \" \" }")
Rules[:_Str] = rule_info("Str", "@StartList:a < @NormalChar+ > { a = text } (StrChunk:c { a << c })* { a }")
Rules[:_StrChunk] = rule_info("StrChunk", "< (@NormalChar | /_+/ &Alphanumeric)+ > { text }")
Rules[:_EscapedChar] = rule_info("EscapedChar", "\"\\\\\" !@Newline < /[:\\\\`|*_{}\\[\\]()\#+.!><-]/ > { text }")
Rules[:_Entity] = rule_info("Entity", "(HexEntity | DecEntity | CharEntity):a { a }")
Rules[:_Endline] = rule_info("Endline", "(@LineBreak | @TerminalEndline | @NormalEndline)")
- Rules[:_NormalEndline] = rule_info("NormalEndline", "@Sp @Newline !@BlankLine !\">\" !AtxStart !(Line /={3,}|-{3,}=/ @Newline) { \"\\n\" }")
+ Rules[:_NormalEndline] = rule_info("NormalEndline", "@Sp @Newline !@BlankLine !\">\" !AtxStart !(Line /={1,}|-{1,}/ @Newline) { \"\\n\" }")
Rules[:_TerminalEndline] = rule_info("TerminalEndline", "@Sp @Newline @Eof")
Rules[:_LineBreak] = rule_info("LineBreak", "\" \" @NormalEndline { RDoc::Markup::HardBreak.new }")
Rules[:_Symbol] = rule_info("Symbol", "< @SpecialChar > { text }")
@@ -16036,27 +16598,21 @@ class RDoc::Markdown
Rules[:_StarLine] = rule_info("StarLine", "(< /\\*{4,}/ > { text } | < @Spacechar /\\*+/ &@Spacechar > { text })")
Rules[:_UlLine] = rule_info("UlLine", "(< /_{4,}/ > { text } | < @Spacechar /_+/ &@Spacechar > { text })")
Rules[:_Emph] = rule_info("Emph", "(EmphStar | EmphUl)")
- Rules[:_OneStarOpen] = rule_info("OneStarOpen", "!StarLine \"*\" !@Spacechar !@Newline")
- Rules[:_OneStarClose] = rule_info("OneStarClose", "!@Spacechar !@Newline Inline:a \"*\" { a }")
- Rules[:_EmphStar] = rule_info("EmphStar", "OneStarOpen @StartList:a (!OneStarClose Inline:l { a << l })* OneStarClose:l { a << l } { emphasis a.join }")
- Rules[:_OneUlOpen] = rule_info("OneUlOpen", "!UlLine \"_\" !@Spacechar !@Newline")
- Rules[:_OneUlClose] = rule_info("OneUlClose", "!@Spacechar !@Newline Inline:a \"_\" { a }")
- Rules[:_EmphUl] = rule_info("EmphUl", "OneUlOpen @StartList:a (!OneUlClose Inline:l { a << l })* OneUlClose:l { a << l } { emphasis a.join }")
+ Rules[:_Whitespace] = rule_info("Whitespace", "(@Spacechar | @Newline)")
+ Rules[:_EmphStar] = rule_info("EmphStar", "\"*\" !@Whitespace @StartList:a (!\"*\" Inline:b { a << b } | StrongStar:b { a << b })+ \"*\" { emphasis a.join }")
+ Rules[:_EmphUl] = rule_info("EmphUl", "\"_\" !@Whitespace @StartList:a (!\"_\" Inline:b { a << b } | StrongUl:b { a << b })+ \"_\" { emphasis a.join }")
Rules[:_Strong] = rule_info("Strong", "(StrongStar | StrongUl)")
- Rules[:_TwoStarOpen] = rule_info("TwoStarOpen", "!StarLine \"**\" !@Spacechar !@Newline")
- Rules[:_TwoStarClose] = rule_info("TwoStarClose", "!@Spacechar !@Newline Inline:a \"**\" { a }")
- Rules[:_StrongStar] = rule_info("StrongStar", "TwoStarOpen @StartList:a (!TwoStarClose Inline:l { a << l })* TwoStarClose:l { a << l } { strong a.join }")
- Rules[:_TwoUlOpen] = rule_info("TwoUlOpen", "!UlLine \"__\" !@Spacechar !@Newline")
- Rules[:_TwoUlClose] = rule_info("TwoUlClose", "!@Spacechar !@Newline Inline:a \"__\" { a }")
- Rules[:_StrongUl] = rule_info("StrongUl", "TwoUlOpen @StartList:a (!TwoUlClose Inline:i { a << i })* TwoUlClose:l { a << l } { strong a.join }")
+ Rules[:_StrongStar] = rule_info("StrongStar", "\"**\" !@Whitespace @StartList:a (!\"**\" Inline:b { a << b })+ \"**\" { strong a.join }")
+ Rules[:_StrongUl] = rule_info("StrongUl", "\"__\" !@Whitespace @StartList:a (!\"__\" Inline:b { a << b })+ \"__\" { strong a.join }")
+ Rules[:_Strike] = rule_info("Strike", "&{ strike? } \"~~\" !@Whitespace @StartList:a (!\"~~\" Inline:b { a << b })+ \"~~\" { strike a.join }")
Rules[:_Image] = rule_info("Image", "\"!\" (ExplicitLink | ReferenceLink):a { \"rdoc-image:\#{a[/\\[(.*)\\]/, 1]}\" }")
Rules[:_Link] = rule_info("Link", "(ExplicitLink | ReferenceLink | AutoLink)")
Rules[:_ReferenceLink] = rule_info("ReferenceLink", "(ReferenceLinkDouble | ReferenceLinkSingle)")
Rules[:_ReferenceLinkDouble] = rule_info("ReferenceLinkDouble", "Label:content < Spnl > !\"[]\" Label:label { link_to content, label, text }")
Rules[:_ReferenceLinkSingle] = rule_info("ReferenceLinkSingle", "Label:content < (Spnl \"[]\")? > { link_to content, content, text }")
- Rules[:_ExplicitLink] = rule_info("ExplicitLink", "Label:l Spnl \"(\" @Sp Source:s Spnl Title @Sp \")\" { \"{\#{l}}[\#{s}]\" }")
+ Rules[:_ExplicitLink] = rule_info("ExplicitLink", "Label:l \"(\" @Sp Source:s Spnl Title @Sp \")\" { \"{\#{l}}[\#{s}]\" }")
Rules[:_Source] = rule_info("Source", "(\"<\" < SourceContents > \">\" | < SourceContents >) { text }")
- Rules[:_SourceContents] = rule_info("SourceContents", "(((!\"(\" !\")\" !\">\" Nonspacechar)+ | \"(\" SourceContents \")\")* | \"\")")
+ Rules[:_SourceContents] = rule_info("SourceContents", "((!\"(\" !\")\" !\">\" Nonspacechar)+ | \"(\" SourceContents \")\")*")
Rules[:_Title] = rule_info("Title", "(TitleSingle | TitleDouble | \"\"):a { a }")
Rules[:_TitleSingle] = rule_info("TitleSingle", "\"'\" (!(\"'\" @Sp (\")\" | @Newline)) .)* \"'\"")
Rules[:_TitleDouble] = rule_info("TitleDouble", "\"\\\"\" (!(\"\\\"\" @Sp (\")\" | @Newline)) .)* \"\\\"\"")
@@ -16088,14 +16644,13 @@ class RDoc::Markdown
Rules[:_Nonspacechar] = rule_info("Nonspacechar", "!@Spacechar !@Newline .")
Rules[:_Sp] = rule_info("Sp", "@Spacechar*")
Rules[:_Spnl] = rule_info("Spnl", "@Sp (@Newline @Sp)?")
- Rules[:_SpecialChar] = rule_info("SpecialChar", "(/[*_`&\\[\\]()<!\#\\\\'\"]/ | @ExtendedSpecialChar)")
+ Rules[:_SpecialChar] = rule_info("SpecialChar", "(/[~*_`&\\[\\]()<!\#\\\\'\"]/ | @ExtendedSpecialChar)")
Rules[:_NormalChar] = rule_info("NormalChar", "!(@SpecialChar | @Spacechar | @Newline) .")
Rules[:_Digit] = rule_info("Digit", "[0-9]")
Rules[:_Alphanumeric] = rule_info("Alphanumeric", "%literals.Alphanumeric")
Rules[:_AlphanumericAscii] = rule_info("AlphanumericAscii", "%literals.AlphanumericAscii")
Rules[:_BOM] = rule_info("BOM", "%literals.BOM")
Rules[:_Newline] = rule_info("Newline", "%literals.Newline")
- Rules[:_NonAlphanumeric] = rule_info("NonAlphanumeric", "%literals.NonAlphanumeric")
Rules[:_Spacechar] = rule_info("Spacechar", "%literals.Spacechar")
Rules[:_HexEntity] = rule_info("HexEntity", "/&\#x/i < /[0-9a-fA-F]+/ > \";\" { [text.to_i(16)].pack 'U' }")
Rules[:_DecEntity] = rule_info("DecEntity", "\"&\#\" < /[0-9]+/ > \";\" { [text.to_i].pack 'U' }")
@@ -16112,10 +16667,15 @@ class RDoc::Markdown
Rules[:_NoteReference] = rule_info("NoteReference", "&{ notes? } RawNoteReference:ref { note_for ref }")
Rules[:_RawNoteReference] = rule_info("RawNoteReference", "\"[^\" < (!@Newline !\"]\" .)+ > \"]\" { text }")
Rules[:_Note] = rule_info("Note", "&{ notes? } @NonindentSpace RawNoteReference:ref \":\" @Sp @StartList:a RawNoteBlock:i { a.concat i } (&Indent RawNoteBlock:i { a.concat i })* { @footnotes[ref] = paragraph a nil }")
- Rules[:_InlineNote] = rule_info("InlineNote", "&{ notes? } \"^[\" @StartList:a (!\"]\" Inline:l { a << l })+ \"]\" { ref = [:inline, @note_order.length] @footnotes[ref] = paragraph a note_for ref }")
+ Rules[:_InlineNote] = rule_info("InlineNote", "&{ notes? } \"^[\" @StartList:a (!\"]\" Inline:l { a << l })+ \"]\" { ref = [:inline, @note_order.length] @footnotes[ref] = paragraph a note_for ref }")
Rules[:_Notes] = rule_info("Notes", "(Note | SkipBlock)*")
Rules[:_RawNoteBlock] = rule_info("RawNoteBlock", "@StartList:a (!@BlankLine OptionallyIndentedLine:l { a << l })+ < @BlankLine* > { a << text } { a }")
Rules[:_CodeFence] = rule_info("CodeFence", "&{ github? } Ticks3 (@Sp StrChunk:format)? Spnl < ((!\"`\" Nonspacechar)+ | !Ticks3 /`+/ | Spacechar | @Newline)+ > Ticks3 @Sp @Newline* { verbatim = RDoc::Markup::Verbatim.new text verbatim.format = format.intern if format.instance_of?(String) verbatim }")
+ Rules[:_Table] = rule_info("Table", "&{ github? } TableRow:header TableLine:line TableRow+:body { table = RDoc::Markup::Table.new(header, line, body) }")
+ Rules[:_TableRow] = rule_info("TableRow", "TableItem+:row \"|\" @Newline { row }")
+ Rules[:_TableItem] = rule_info("TableItem", "\"|\" < (!\"|\" !@Newline .)+ > { text.strip }")
+ Rules[:_TableLine] = rule_info("TableLine", "TableColumn+:line \"|\" @Newline { line }")
+ Rules[:_TableColumn] = rule_info("TableColumn", "\"|\" < (\"-\"+ \":\"? | \":\" \"-\"*) > { text.start_with?(\":\") ? :left : text.end_with?(\":\") ? :right : nil }")
Rules[:_DefinitionList] = rule_info("DefinitionList", "&{ definition_lists? } DefinitionListItem+:list { RDoc::Markup::List.new :NOTE, *list.flatten }")
Rules[:_DefinitionListItem] = rule_info("DefinitionListItem", "DefinitionListLabel+:label DefinitionListDefinition+:defns { list_items = [] list_items << RDoc::Markup::ListItem.new(label, defns.shift) list_items.concat defns.map { |defn| RDoc::Markup::ListItem.new nil, defn } unless list_items.empty? list_items }")
Rules[:_DefinitionListLabel] = rule_info("DefinitionListLabel", "StrChunk:label @Sp @Newline { label }")
diff --git a/lib/rdoc/markdown/entities.rb b/lib/rdoc/markdown/entities.rb
index d32ae51053..d2cf610293 100644
--- a/lib/rdoc/markdown/entities.rb
+++ b/lib/rdoc/markdown/entities.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# HTML entity name map for RDoc::Markdown
diff --git a/lib/rdoc/markdown/literals.rb b/lib/rdoc/markdown/literals.rb
index b6bb89e0c6..943c2d268a 100644
--- a/lib/rdoc/markdown/literals.rb
+++ b/lib/rdoc/markdown/literals.rb
@@ -1,5 +1,5 @@
# coding: UTF-8
-# frozen_string_literal: false
+# frozen_string_literal: true
# :markup: markdown
##
@@ -174,23 +174,34 @@ class RDoc::Markdown::Literals
end
def scan(reg)
- if m = reg.match(@string[@pos..-1])
- width = m.end(0)
- @pos += width
+ if m = reg.match(@string, @pos)
+ @pos = m.end(0)
return true
end
return nil
end
- def get_byte
- if @pos >= @string_size
- return nil
+ if "".respond_to? :ord
+ def get_byte
+ if @pos >= @string_size
+ return nil
+ end
+
+ s = @string[@pos].ord
+ @pos += 1
+ s
end
+ else
+ def get_byte
+ if @pos >= @string_size
+ return nil
+ end
- s = @string[@pos].ord
- @pos += 1
- s
+ s = @string[@pos]
+ @pos += 1
+ s
+ end
end
def parse(rule=nil)
@@ -354,14 +365,14 @@ class RDoc::Markdown::Literals
# Alphanumeric = /\p{Word}/
def _Alphanumeric
- _tmp = scan(/\A(?-mix:\p{Word})/)
+ _tmp = scan(/\G(?-mix:\p{Word})/)
set_failed_rule :_Alphanumeric unless _tmp
return _tmp
end
# AlphanumericAscii = /[A-Za-z0-9]/
def _AlphanumericAscii
- _tmp = scan(/\A(?-mix:[A-Za-z0-9])/)
+ _tmp = scan(/\G(?-mix:[A-Za-z0-9])/)
set_failed_rule :_AlphanumericAscii unless _tmp
return _tmp
end
@@ -375,21 +386,21 @@ class RDoc::Markdown::Literals
# Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/
def _Newline
- _tmp = scan(/\A(?-mix:\n|\r\n?|\p{Zl}|\p{Zp})/)
+ _tmp = scan(/\G(?-mix:\n|\r\n?|\p{Zl}|\p{Zp})/)
set_failed_rule :_Newline unless _tmp
return _tmp
end
# NonAlphanumeric = /\p{^Word}/
def _NonAlphanumeric
- _tmp = scan(/\A(?-mix:\p{^Word})/)
+ _tmp = scan(/\G(?-mix:\p{^Word})/)
set_failed_rule :_NonAlphanumeric unless _tmp
return _tmp
end
# Spacechar = /\t|\p{Zs}/
def _Spacechar
- _tmp = scan(/\A(?-mix:\t|\p{Zs})/)
+ _tmp = scan(/\G(?-mix:\t|\p{Zs})/)
set_failed_rule :_Spacechar unless _tmp
return _tmp
end
diff --git a/lib/rdoc/markup.rb b/lib/rdoc/markup.rb
index 982bc13e88..92aed757cf 100644
--- a/lib/rdoc/markup.rb
+++ b/lib/rdoc/markup.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# RDoc::Markup parses plain text documents and attempts to decompose them into
# their constituent parts. Some of these parts are high-level: paragraphs,
@@ -65,17 +65,16 @@
# puts h.convert(input_string)
#
# You can extend the RDoc::Markup parser to recognize new markup
-# sequences, and to add special processing for text that matches a
-# regular expression. Here we make WikiWords significant to the parser,
-# and also make the sequences {word} and \<no>text...</no> signify
+# sequences, and to add regexp handling. Here we make WikiWords significant to
+# the parser, and also make the sequences {word} and \<no>text...</no> signify
# strike-through text. We then subclass the HTML output class to deal
# with these:
#
# require 'rdoc'
#
# class WikiHtml < RDoc::Markup::ToHtml
-# def handle_special_WIKIWORD(special)
-# "<font color=red>" + special.text + "</font>"
+# def handle_regexp_WIKIWORD(target)
+# "<font color=red>" + target.text + "</font>"
# end
# end
#
@@ -83,7 +82,7 @@
# markup.add_word_pair("{", "}", :STRIKE)
# markup.add_html("no", :STRIKE)
#
-# markup.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
+# markup.add_regexp_handling(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
#
# wh = WikiHtml.new RDoc::Options.new, markup
# wh.add_tag(:STRIKE, "<strike>", "</strike>")
@@ -800,13 +799,12 @@ https://github.com/ruby/rdoc/issues
# Add to other inline sequences. For example, we could add WikiWords using
# something like:
#
- # parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
+ # parser.add_regexp_handling(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
#
- # Each wiki word will be presented to the output formatter via the
- # accept_special method.
+ # Each wiki word will be presented to the output formatter.
- def add_special(pattern, name)
- @attribute_manager.add_special(pattern, name)
+ def add_regexp_handling(pattern, name)
+ @attribute_manager.add_regexp_handling(pattern, name)
end
##
@@ -832,7 +830,7 @@ https://github.com/ruby/rdoc/issues
autoload :AttrSpan, 'rdoc/markup/attr_span'
autoload :Attributes, 'rdoc/markup/attributes'
autoload :AttributeManager, 'rdoc/markup/attribute_manager'
- autoload :Special, 'rdoc/markup/special'
+ autoload :RegexpHandling, 'rdoc/markup/regexp_handling'
# RDoc::Markup AST
autoload :BlankLine, 'rdoc/markup/blank_line'
@@ -845,14 +843,13 @@ https://github.com/ruby/rdoc/issues
autoload :List, 'rdoc/markup/list'
autoload :ListItem, 'rdoc/markup/list_item'
autoload :Paragraph, 'rdoc/markup/paragraph'
+ autoload :Table, 'rdoc/markup/table'
autoload :Raw, 'rdoc/markup/raw'
autoload :Rule, 'rdoc/markup/rule'
autoload :Verbatim, 'rdoc/markup/verbatim'
# Formatters
autoload :Formatter, 'rdoc/markup/formatter'
- autoload :FormatterTestCase, 'rdoc/markup/formatter_test_case'
- autoload :TextFormatterTestCase, 'rdoc/markup/text_formatter_test_case'
autoload :ToAnsi, 'rdoc/markup/to_ansi'
autoload :ToBs, 'rdoc/markup/to_bs'
diff --git a/lib/rdoc/markup/attr_changer.rb b/lib/rdoc/markup/attr_changer.rb
index 9a1a9c8c66..4c4bc6479e 100644
--- a/lib/rdoc/markup/attr_changer.rb
+++ b/lib/rdoc/markup/attr_changer.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
class RDoc::Markup
AttrChanger = Struct.new :turn_on, :turn_off # :nodoc:
diff --git a/lib/rdoc/markup/attr_span.rb b/lib/rdoc/markup/attr_span.rb
index 4d9e5b0217..20ef11cd6d 100644
--- a/lib/rdoc/markup/attr_span.rb
+++ b/lib/rdoc/markup/attr_span.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# An array of attributes which parallels the characters in a string.
@@ -7,16 +7,22 @@ class RDoc::Markup::AttrSpan
##
# Creates a new AttrSpan for +length+ characters
- def initialize(length)
+ def initialize(length, exclusive)
@attrs = Array.new(length, 0)
+ @exclusive = exclusive
end
##
# Toggles +bits+ from +start+ to +length+
def set_attrs(start, length, bits)
+ updated = false
for i in start ... (start+length)
- @attrs[i] |= bits
+ if (@exclusive & @attrs[i]) == 0 || (@exclusive & bits) != 0
+ @attrs[i] |= bits
+ updated = true
+ end
end
+ updated
end
##
diff --git a/lib/rdoc/markup/attribute_manager.rb b/lib/rdoc/markup/attribute_manager.rb
index 3296d17af2..50764510f3 100644
--- a/lib/rdoc/markup/attribute_manager.rb
+++ b/lib/rdoc/markup/attribute_manager.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Manages changes of attributes in a block of text
@@ -53,10 +53,14 @@ class RDoc::Markup::AttributeManager
attr_reader :protectable
##
- # And this maps _special_ sequences to a name. A special sequence is
- # something like a WikiWord
+ # And this maps _regexp handling_ sequences to a name. A regexp handling
+ # sequence is something like a WikiWord
- attr_reader :special
+ attr_reader :regexp_handlings
+
+ ##
+ # A bits of exclusive maps
+ attr_reader :exclusive_bitmap
##
# Creates a new attribute manager that understands bold, emphasized and
@@ -66,19 +70,20 @@ class RDoc::Markup::AttributeManager
@html_tags = {}
@matching_word_pairs = {}
@protectable = %w[<]
- @special = []
+ @regexp_handlings = []
@word_pair_map = {}
+ @exclusive_bitmap = 0
@attributes = RDoc::Markup::Attributes.new
- add_word_pair "*", "*", :BOLD
- add_word_pair "_", "_", :EM
- add_word_pair "+", "+", :TT
+ add_word_pair "*", "*", :BOLD, true
+ add_word_pair "_", "_", :EM, true
+ add_word_pair "+", "+", :TT, true
- add_html "em", :EM
- add_html "i", :EM
- add_html "b", :BOLD
- add_html "tt", :TT
- add_html "code", :TT
+ add_html "em", :EM, true
+ add_html "i", :EM, true
+ add_html "b", :BOLD, true
+ add_html "tt", :TT, true
+ add_html "code", :TT, true
end
##
@@ -122,29 +127,67 @@ class RDoc::Markup::AttributeManager
res
end
+ def exclusive?(attr)
+ (attr & @exclusive_bitmap) != 0
+ end
+
+ NON_PRINTING_START = "\1" # :nodoc:
+ NON_PRINTING_END = "\2" # :nodoc:
+
##
# Map attributes like <b>text</b>to the sequence
# \001\002<char>\001\003<char>, where <char> is a per-attribute specific
# character
- def convert_attrs(str, attrs)
+ def convert_attrs(str, attrs, exclusive = false)
+ convert_attrs_matching_word_pairs(str, attrs, exclusive)
+ convert_attrs_word_pair_map(str, attrs, exclusive)
+ end
+
+ def convert_attrs_matching_word_pairs(str, attrs, exclusive)
# first do matching ones
- tags = @matching_word_pairs.keys.join("")
+ tags = @matching_word_pairs.select { |start, bitmap|
+ if exclusive && exclusive?(bitmap)
+ true
+ elsif !exclusive && !exclusive?(bitmap)
+ true
+ else
+ false
+ end
+ }.keys
+ return if tags.empty?
+ all_tags = @matching_word_pairs.keys
- re = /(^|\W)([#{tags}])([#\\]?[\w:.\/-]+?\S?)\2(\W|$)/
+ re = /(^|\W|[#{all_tags.join("")}])([#{tags.join("")}])(\2*[#\\]?[\w:.\/\[\]-]+?\S?)\2(?!\2)([#{all_tags.join("")}]|\W|$)/
- 1 while str.gsub!(re) do
+ 1 while str.gsub!(re) { |orig|
attr = @matching_word_pairs[$2]
- attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)
- $1 + NULL * $2.length + $3 + NULL * $2.length + $4
- end
+ attr_updated = attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)
+ if attr_updated
+ $1 + NULL * $2.length + $3 + NULL * $2.length + $4
+ else
+ $1 + NON_PRINTING_START + $2 + NON_PRINTING_END + $3 + NON_PRINTING_START + $2 + NON_PRINTING_END + $4
+ end
+ }
+ str.delete!(NON_PRINTING_START + NON_PRINTING_END)
+ end
+ def convert_attrs_word_pair_map(str, attrs, exclusive)
# then non-matching
unless @word_pair_map.empty? then
@word_pair_map.each do |regexp, attr|
- str.gsub!(regexp) {
- attrs.set_attrs($`.length + $1.length, $2.length, attr)
- NULL * $1.length + $2 + NULL * $3.length
+ if !exclusive
+ next if exclusive?(attr)
+ else
+ next if !exclusive?(attr)
+ end
+ 1 while str.gsub!(regexp) { |orig|
+ updated = attrs.set_attrs($`.length + $1.length, $2.length, attr)
+ if updated
+ NULL * $1.length + $2 + NULL * $3.length
+ else
+ orig
+ end
}
end
end
@@ -153,10 +196,18 @@ class RDoc::Markup::AttributeManager
##
# Converts HTML tags to RDoc attributes
- def convert_html(str, attrs)
- tags = @html_tags.keys.join '|'
+ def convert_html(str, attrs, exclusive = false)
+ tags = @html_tags.select { |start, bitmap|
+ if exclusive && exclusive?(bitmap)
+ true
+ elsif !exclusive && !exclusive?(bitmap)
+ true
+ else
+ false
+ end
+ }.keys.join '|'
- 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) {
+ 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { |orig|
attr = @html_tags[$1.downcase]
html_length = $1.length + 2
seq = NULL * html_length
@@ -166,22 +217,27 @@ class RDoc::Markup::AttributeManager
end
##
- # Converts special sequences to RDoc attributes
-
- def convert_specials str, attrs
- @special.each do |regexp, attribute|
+ # Converts regexp handling sequences to RDoc attributes
+
+ def convert_regexp_handlings str, attrs, exclusive = false
+ @regexp_handlings.each do |regexp, attribute|
+ if exclusive
+ next if !exclusive?(attribute)
+ else
+ next if exclusive?(attribute)
+ end
str.scan(regexp) do
capture = $~.size == 1 ? 0 : 1
s, e = $~.offset capture
- attrs.set_attrs s, e - s, attribute | @attributes.special
+ attrs.set_attrs s, e - s, attribute | @attributes.regexp_handling
end
end
end
##
- # Escapes special sequences of text to prevent conversion to RDoc
+ # Escapes regexp handling sequences of text to prevent conversion to RDoc
def mask_protected_sequences
# protect __send__, __FILE__, etc.
@@ -193,7 +249,7 @@ class RDoc::Markup::AttributeManager
end
##
- # Unescapes special sequences of text
+ # Unescapes regexp handling sequences of text
def unmask_protected_sequences
@str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000")
@@ -205,7 +261,7 @@ class RDoc::Markup::AttributeManager
#
# am.add_word_pair '*', '*', :BOLD
- def add_word_pair(start, stop, name)
+ def add_word_pair(start, stop, name, exclusive = false)
raise ArgumentError, "Word flags may not start with '<'" if
start[0,1] == '<'
@@ -220,6 +276,8 @@ class RDoc::Markup::AttributeManager
@protectable << start[0,1]
@protectable.uniq!
+
+ @exclusive_bitmap |= bitmap if exclusive
end
##
@@ -228,33 +286,40 @@ class RDoc::Markup::AttributeManager
#
# am.add_html 'em', :EM
- def add_html(tag, name)
- @html_tags[tag.downcase] = @attributes.bitmap_for name
+ def add_html(tag, name, exclusive = false)
+ bitmap = @attributes.bitmap_for name
+ @html_tags[tag.downcase] = bitmap
+ @exclusive_bitmap |= bitmap if exclusive
end
##
- # Adds a special handler for +pattern+ with +name+. A simple URL handler
+ # Adds a regexp handling for +pattern+ with +name+. A simple URL handler
# would be:
#
- # @am.add_special(/((https?:)\S+\w)/, :HYPERLINK)
+ # @am.add_regexp_handling(/((https?:)\S+\w)/, :HYPERLINK)
- def add_special pattern, name
- @special << [pattern, @attributes.bitmap_for(name)]
+ def add_regexp_handling pattern, name, exclusive = false
+ bitmap = @attributes.bitmap_for(name)
+ @regexp_handlings << [pattern, bitmap]
+ @exclusive_bitmap |= bitmap if exclusive
end
##
- # Processes +str+ converting attributes, HTML and specials
+ # Processes +str+ converting attributes, HTML and regexp handlings
def flow str
- @str = str
+ @str = str.dup
mask_protected_sequences
- @attrs = RDoc::Markup::AttrSpan.new @str.length
+ @attrs = RDoc::Markup::AttrSpan.new @str.length, @exclusive_bitmap
- convert_attrs @str, @attrs
- convert_html @str, @attrs
- convert_specials @str, @attrs
+ convert_attrs @str, @attrs, true
+ convert_html @str, @attrs, true
+ convert_regexp_handlings @str, @attrs, true
+ convert_attrs @str, @attrs
+ convert_html @str, @attrs
+ convert_regexp_handlings @str, @attrs
unmask_protected_sequences
@@ -312,12 +377,12 @@ class RDoc::Markup::AttributeManager
res << change_attribute(current_attr, new_attr)
current_attr = new_attr
- if (current_attr & @attributes.special) != 0 then
+ if (current_attr & @attributes.regexp_handling) != 0 then
i += 1 while
- i < str_len and (@attrs[i] & @attributes.special) != 0
+ i < str_len and (@attrs[i] & @attributes.regexp_handling) != 0
- res << RDoc::Markup::Special.new(current_attr,
- copy_string(start_pos, i))
+ res << RDoc::Markup::RegexpHandling.new(current_attr,
+ copy_string(start_pos, i))
start_pos = i
next
end
diff --git a/lib/rdoc/markup/attributes.rb b/lib/rdoc/markup/attributes.rb
index 8776c4ed29..ce014ce928 100644
--- a/lib/rdoc/markup/attributes.rb
+++ b/lib/rdoc/markup/attributes.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# We manage a set of attributes. Each attribute has a symbol name and a bit
# value.
@@ -6,21 +6,21 @@
class RDoc::Markup::Attributes
##
- # The special attribute type. See RDoc::Markup#add_special
+ # The regexp handling attribute type. See RDoc::Markup#add_regexp_handling
- attr_reader :special
+ attr_reader :regexp_handling
##
# Creates a new attributes set.
def initialize
- @special = 1
+ @regexp_handling = 1
@name_to_bitmap = [
- [:_SPECIAL_, @special],
+ [:_REGEXP_HANDLING_, @regexp_handling],
]
- @next_bitmap = @special << 1
+ @next_bitmap = @regexp_handling << 1
end
##
@@ -61,7 +61,7 @@ class RDoc::Markup::Attributes
return enum_for __method__, bitmap unless block_given?
@name_to_bitmap.each do |name, bit|
- next if bit == @special
+ next if bit == @regexp_handling
yield name.to_s if (bitmap & bit) != 0
end
diff --git a/lib/rdoc/markup/blank_line.rb b/lib/rdoc/markup/blank_line.rb
index 2b1ab91b47..3129ab5e7f 100644
--- a/lib/rdoc/markup/blank_line.rb
+++ b/lib/rdoc/markup/blank_line.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# An empty line. This class is a singleton.
diff --git a/lib/rdoc/markup/block_quote.rb b/lib/rdoc/markup/block_quote.rb
index 3be022f9dd..7a4b3e36b0 100644
--- a/lib/rdoc/markup/block_quote.rb
+++ b/lib/rdoc/markup/block_quote.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A quoted section which contains markup items.
diff --git a/lib/rdoc/markup/document.rb b/lib/rdoc/markup/document.rb
index 0692c3522f..f3a5de1fc3 100644
--- a/lib/rdoc/markup/document.rb
+++ b/lib/rdoc/markup/document.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A Document containing lists, headings, paragraphs, etc.
diff --git a/lib/rdoc/markup/formatter.rb b/lib/rdoc/markup/formatter.rb
index 197ff003e3..2bac76e838 100644
--- a/lib/rdoc/markup/formatter.rb
+++ b/lib/rdoc/markup/formatter.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Base class for RDoc markup formatters
#
@@ -50,7 +50,7 @@ class RDoc::Markup::Formatter
@markup = markup || RDoc::Markup.new
@am = @markup.attribute_manager
- @am.add_special(/<br>/, :HARD_BREAK)
+ @am.add_regexp_handling(/<br>/, :HARD_BREAK)
@attributes = @am.attributes
@@ -78,23 +78,24 @@ class RDoc::Markup::Formatter
end
##
- # Adds a special for links of the form rdoc-...:
+ # Adds a regexp handling for links of the form rdoc-...:
- def add_special_RDOCLINK
- @markup.add_special(/rdoc-[a-z]+:[^\s\]]+/, :RDOCLINK)
+ def add_regexp_handling_RDOCLINK
+ @markup.add_regexp_handling(/rdoc-[a-z]+:[^\s\]]+/, :RDOCLINK)
end
##
- # Adds a special for links of the form {<text>}[<url>] and <word>[<url>]
+ # Adds a regexp handling for links of the form {<text>}[<url>] and
+ # <word>[<url>]
- def add_special_TIDYLINK
- @markup.add_special(/(?:
- \{.*?\} | # multi-word label
- \b[^\s{}]+? # single-word label
- )
+ def add_regexp_handling_TIDYLINK
+ @markup.add_regexp_handling(/(?:
+ \{.*?\} | # multi-word label
+ \b[^\s{}]+? # single-word label
+ )
- \[\S+?\] # link target
- /x, :TIDYLINK)
+ \[\S+?\] # link target
+ /x, :TIDYLINK)
end
##
@@ -133,8 +134,8 @@ class RDoc::Markup::Formatter
when RDoc::Markup::AttrChanger then
off_tags res, item
on_tags res, item
- when RDoc::Markup::Special then
- res << convert_special(item)
+ when RDoc::Markup::RegexpHandling then
+ res << convert_regexp_handling(item)
else
raise "Unknown flow element: #{item.inspect}"
end
@@ -144,29 +145,29 @@ class RDoc::Markup::Formatter
end
##
- # Converts added specials. See RDoc::Markup#add_special
+ # Converts added regexp handlings. See RDoc::Markup#add_regexp_handling
- def convert_special special
- return special.text if in_tt?
+ def convert_regexp_handling target
+ return target.text if in_tt?
handled = false
- @attributes.each_name_of special.type do |name|
- method_name = "handle_special_#{name}"
+ @attributes.each_name_of target.type do |name|
+ method_name = "handle_regexp_#{name}"
if respond_to? method_name then
- special.text = send method_name, special
+ target.text = public_send method_name, target
handled = true
end
end
unless handled then
- special_name = @attributes.as_string special.type
+ target_name = @attributes.as_string target.type
- raise RDoc::Error, "Unhandled special #{special_name}: #{special}"
+ raise RDoc::Error, "Unhandled regexp handling #{target_name}: #{target}"
end
- special.text
+ target.text
end
##
diff --git a/lib/rdoc/markup/formatter_test_case.rb b/lib/rdoc/markup/formatter_test_case.rb
deleted file mode 100644
index a5b4933de4..0000000000
--- a/lib/rdoc/markup/formatter_test_case.rb
+++ /dev/null
@@ -1,764 +0,0 @@
-# frozen_string_literal: false
-require 'minitest/unit'
-
-##
-# Test case for creating new RDoc::Markup formatters. See
-# test/test_rdoc_markup_to_*.rb for examples.
-#
-# This test case adds a variety of tests to your subclass when
-# #add_visitor_tests is called. Most tests set up a scenario then call a
-# method you will provide to perform the assertion on the output.
-#
-# Your subclass must instantiate a visitor and assign it to <tt>@to</tt>.
-#
-# For example, test_accept_blank_line sets up a RDoc::Markup::BlockLine then
-# calls accept_blank_line on your visitor. You are responsible for asserting
-# that the output is correct.
-#
-# Example:
-#
-# class TestRDocMarkupToNewFormat < RDoc::Markup::FormatterTestCase
-#
-# add_visitor_tests
-#
-# def setup
-# super
-#
-# @to = RDoc::Markup::ToNewFormat.new
-# end
-#
-# def accept_blank_line
-# assert_equal :junk, @to.res.join
-# end
-#
-# # ...
-#
-# end
-
-class RDoc::Markup::FormatterTestCase < RDoc::TestCase
-
- ##
- # Call #setup when inheriting from this test case.
- #
- # Provides the following instance variables:
- #
- # +@m+:: RDoc::Markup.new
- # +@RM+:: RDoc::Markup # to reduce typing
- # +@bullet_list+:: @RM::List.new :BULLET, # ...
- # +@label_list+:: @RM::List.new :LABEL, # ...
- # +@lalpha_list+:: @RM::List.new :LALPHA, # ...
- # +@note_list+:: @RM::List.new :NOTE, # ...
- # +@number_list+:: @RM::List.new :NUMBER, # ...
- # +@ualpha_list+:: @RM::List.new :UALPHA, # ...
-
- def setup
- super
-
- @options = RDoc::Options.new
-
- @m = @RM.new
-
- @bullet_list = @RM::List.new(:BULLET,
- @RM::ListItem.new(nil, @RM::Paragraph.new('l1')),
- @RM::ListItem.new(nil, @RM::Paragraph.new('l2')))
-
- @label_list = @RM::List.new(:LABEL,
- @RM::ListItem.new('cat', @RM::Paragraph.new('cats are cool')),
- @RM::ListItem.new('dog', @RM::Paragraph.new('dogs are cool too')))
-
- @lalpha_list = @RM::List.new(:LALPHA,
- @RM::ListItem.new(nil, @RM::Paragraph.new('l1')),
- @RM::ListItem.new(nil, @RM::Paragraph.new('l2')))
-
- @note_list = @RM::List.new(:NOTE,
- @RM::ListItem.new('cat', @RM::Paragraph.new('cats are cool')),
- @RM::ListItem.new('dog', @RM::Paragraph.new('dogs are cool too')))
-
- @number_list = @RM::List.new(:NUMBER,
- @RM::ListItem.new(nil, @RM::Paragraph.new('l1')),
- @RM::ListItem.new(nil, @RM::Paragraph.new('l2')))
-
- @ualpha_list = @RM::List.new(:UALPHA,
- @RM::ListItem.new(nil, @RM::Paragraph.new('l1')),
- @RM::ListItem.new(nil, @RM::Paragraph.new('l2')))
- end
-
- ##
- # Call to add the visitor tests to your test case
-
- def self.add_visitor_tests
- class_eval do
-
- ##
- # Calls start_accepting which needs to verify startup state
-
- def test_start_accepting
- @to.start_accepting
-
- start_accepting
- end
-
- ##
- # Calls end_accepting on your test case which needs to call
- # <tt>@to.end_accepting</tt> and verify document generation
-
- def test_end_accepting
- @to.start_accepting
- @to.res << 'hi'
-
- end_accepting
- end
-
- ##
- # Calls accept_blank_line
-
- def test_accept_blank_line
- @to.start_accepting
-
- @to.accept_blank_line @RM::BlankLine.new
-
- accept_blank_line
- end
-
- ##
- # Calls accept_block_quote
-
- def test_accept_block_quote
- @to.start_accepting
-
- @to.accept_block_quote block para 'quote'
-
- accept_block_quote
- end
- ##
- # Test case that calls <tt>@to.accept_document</tt>
-
- def test_accept_document
- @to.start_accepting
- @to.accept_document @RM::Document.new @RM::Paragraph.new 'hello'
-
- accept_document
- end
-
- ##
- # Calls accept_heading with a level 5 RDoc::Markup::Heading
-
- def test_accept_heading
- @to.start_accepting
-
- @to.accept_heading @RM::Heading.new(5, 'Hello')
-
- accept_heading
- end
-
- ##
- # Calls accept_heading_1 with a level 1 RDoc::Markup::Heading
-
- def test_accept_heading_1
- @to.start_accepting
-
- @to.accept_heading @RM::Heading.new(1, 'Hello')
-
- accept_heading_1
- end
-
- ##
- # Calls accept_heading_2 with a level 2 RDoc::Markup::Heading
-
- def test_accept_heading_2
- @to.start_accepting
-
- @to.accept_heading @RM::Heading.new(2, 'Hello')
-
- accept_heading_2
- end
-
- ##
- # Calls accept_heading_3 with a level 3 RDoc::Markup::Heading
-
- def test_accept_heading_3
- @to.start_accepting
-
- @to.accept_heading @RM::Heading.new(3, 'Hello')
-
- accept_heading_3
- end
-
- ##
- # Calls accept_heading_4 with a level 4 RDoc::Markup::Heading
-
- def test_accept_heading_4
- @to.start_accepting
-
- @to.accept_heading @RM::Heading.new(4, 'Hello')
-
- accept_heading_4
- end
-
- ##
- # Calls accept_heading_b with a bold level 1 RDoc::Markup::Heading
-
- def test_accept_heading_b
- @to.start_accepting
-
- @to.accept_heading @RM::Heading.new(1, '*Hello*')
-
- accept_heading_b
- end
-
- ##
- # Calls accept_heading_suppressed_crossref with a level 1
- # RDoc::Markup::Heading containing a suppressed crossref
-
- def test_accept_heading_suppressed_crossref # HACK to_html_crossref test
- @to.start_accepting
-
- @to.accept_heading @RM::Heading.new(1, '\\Hello')
-
- accept_heading_suppressed_crossref
- end
-
- ##
- # Calls accept_paragraph
-
- def test_accept_paragraph
- @to.start_accepting
-
- @to.accept_paragraph @RM::Paragraph.new('hi')
-
- accept_paragraph
- end
-
- ##
- # Calls accept_paragraph_b with a RDoc::Markup::Paragraph containing
- # bold words
-
- def test_accept_paragraph_b
- @to.start_accepting
-
- @to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
-
- accept_paragraph_b
- end
-
- ##
- # Calls accept_paragraph_br with a RDoc::Markup::Paragraph containing
- # a \<br>
-
- def test_accept_paragraph_br
- @to.start_accepting
-
- @to.accept_paragraph para 'one<br>two'
-
- accept_paragraph_br
- end
-
- ##
- # Calls accept_paragraph with a Paragraph containing a hard break
-
- def test_accept_paragraph_break
- @to.start_accepting
-
- @to.accept_paragraph para('hello', hard_break, 'world')
-
- accept_paragraph_break
- end
-
- ##
- # Calls accept_paragraph_i with a RDoc::Markup::Paragraph containing
- # emphasized words
-
- def test_accept_paragraph_i
- @to.start_accepting
-
- @to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
-
- accept_paragraph_i
- end
-
- ##
- # Calls accept_paragraph_plus with a RDoc::Markup::Paragraph containing
- # teletype words
-
- def test_accept_paragraph_plus
- @to.start_accepting
-
- @to.accept_paragraph @RM::Paragraph.new('reg +teletype+ reg')
-
- accept_paragraph_plus
- end
-
- ##
- # Calls accept_paragraph_star with a RDoc::Markup::Paragraph containing
- # bold words
-
- def test_accept_paragraph_star
- @to.start_accepting
-
- @to.accept_paragraph @RM::Paragraph.new('reg *bold* reg')
-
- accept_paragraph_star
- end
-
- ##
- # Calls accept_paragraph_underscore with a RDoc::Markup::Paragraph
- # containing emphasized words
-
- def test_accept_paragraph_underscore
- @to.start_accepting
-
- @to.accept_paragraph @RM::Paragraph.new('reg _italic_ reg')
-
- accept_paragraph_underscore
- end
-
- ##
- # Calls accept_verbatim with a RDoc::Markup::Verbatim
-
- def test_accept_verbatim
- @to.start_accepting
-
- @to.accept_verbatim @RM::Verbatim.new("hi\n", " world\n")
-
- accept_verbatim
- end
-
- ##
- # Calls accept_raw with a RDoc::Markup::Raw
-
- def test_accept_raw
- @to.start_accepting
-
- @to.accept_raw @RM::Raw.new("<table>",
- "<tr><th>Name<th>Count",
- "<tr><td>a<td>1",
- "<tr><td>b<td>2",
- "</table>")
-
- accept_raw
- end
-
- ##
- # Calls accept_rule with a RDoc::Markup::Rule
-
- def test_accept_rule
- @to.start_accepting
-
- @to.accept_rule @RM::Rule.new(4)
-
- accept_rule
- end
-
- ##
- # Calls accept_list_item_start_bullet
-
- def test_accept_list_item_start_bullet
- @to.start_accepting
-
- @to.accept_list_start @bullet_list
-
- @to.accept_list_item_start @bullet_list.items.first
-
- accept_list_item_start_bullet
- end
-
- ##
- # Calls accept_list_item_start_label
-
- def test_accept_list_item_start_label
- @to.start_accepting
-
- @to.accept_list_start @label_list
-
- @to.accept_list_item_start @label_list.items.first
-
- accept_list_item_start_label
- end
-
- ##
- # Calls accept_list_item_start_lalpha
-
- def test_accept_list_item_start_lalpha
- @to.start_accepting
-
- @to.accept_list_start @lalpha_list
-
- @to.accept_list_item_start @lalpha_list.items.first
-
- accept_list_item_start_lalpha
- end
-
- ##
- # Calls accept_list_item_start_note
-
- def test_accept_list_item_start_note
- @to.start_accepting
-
- @to.accept_list_start @note_list
-
- @to.accept_list_item_start @note_list.items.first
-
- accept_list_item_start_note
- end
-
- ##
- # Calls accept_list_item_start_note_2
-
- def test_accept_list_item_start_note_2
- list = list(:NOTE,
- item('<tt>teletype</tt>',
- para('teletype description')))
-
- @to.start_accepting
-
- list.accept @to
-
- @to.end_accepting
-
- accept_list_item_start_note_2
- end
-
- ##
- # Calls accept_list_item_start_note_multi_description
-
- def test_accept_list_item_start_note_multi_description
- list = list(:NOTE,
- item(%w[label],
- para('description one')),
- item(nil, para('description two')))
-
- @to.start_accepting
-
- list.accept @to
-
- @to.end_accepting
-
- accept_list_item_start_note_multi_description
- end
-
- ##
- # Calls accept_list_item_start_note_multi_label
-
- def test_accept_list_item_start_note_multi_label
- list = list(:NOTE,
- item(%w[one two],
- para('two headers')))
-
- @to.start_accepting
-
- list.accept @to
-
- @to.end_accepting
-
- accept_list_item_start_note_multi_label
- end
-
- ##
- # Calls accept_list_item_start_number
-
- def test_accept_list_item_start_number
- @to.start_accepting
-
- @to.accept_list_start @number_list
-
- @to.accept_list_item_start @number_list.items.first
-
- accept_list_item_start_number
- end
-
- ##
- # Calls accept_list_item_start_ualpha
-
- def test_accept_list_item_start_ualpha
- @to.start_accepting
-
- @to.accept_list_start @ualpha_list
-
- @to.accept_list_item_start @ualpha_list.items.first
-
- accept_list_item_start_ualpha
- end
-
- ##
- # Calls accept_list_item_end_bullet
-
- def test_accept_list_item_end_bullet
- @to.start_accepting
-
- @to.accept_list_start @bullet_list
-
- @to.accept_list_item_start @bullet_list.items.first
-
- @to.accept_list_item_end @bullet_list.items.first
-
- accept_list_item_end_bullet
- end
-
- ##
- # Calls accept_list_item_end_label
-
- def test_accept_list_item_end_label
- @to.start_accepting
-
- @to.accept_list_start @label_list
-
- @to.accept_list_item_start @label_list.items.first
-
- @to.accept_list_item_end @label_list.items.first
-
- accept_list_item_end_label
- end
-
- ##
- # Calls accept_list_item_end_lalpha
-
- def test_accept_list_item_end_lalpha
- @to.start_accepting
-
- @to.accept_list_start @lalpha_list
-
- @to.accept_list_item_start @lalpha_list.items.first
-
- @to.accept_list_item_end @lalpha_list.items.first
-
- accept_list_item_end_lalpha
- end
-
- ##
- # Calls accept_list_item_end_note
-
- def test_accept_list_item_end_note
- @to.start_accepting
-
- @to.accept_list_start @note_list
-
- @to.accept_list_item_start @note_list.items.first
-
- @to.accept_list_item_end @note_list.items.first
-
- accept_list_item_end_note
- end
-
- ##
- # Calls accept_list_item_end_number
-
- def test_accept_list_item_end_number
- @to.start_accepting
-
- @to.accept_list_start @number_list
-
- @to.accept_list_item_start @number_list.items.first
-
- @to.accept_list_item_end @number_list.items.first
-
- accept_list_item_end_number
- end
-
- ##
- # Calls accept_list_item_end_ualpha
-
- def test_accept_list_item_end_ualpha
- @to.start_accepting
-
- @to.accept_list_start @ualpha_list
-
- @to.accept_list_item_start @ualpha_list.items.first
-
- @to.accept_list_item_end @ualpha_list.items.first
-
- accept_list_item_end_ualpha
- end
-
- ##
- # Calls accept_list_start_bullet
-
- def test_accept_list_start_bullet
- @to.start_accepting
-
- @to.accept_list_start @bullet_list
-
- accept_list_start_bullet
- end
-
- ##
- # Calls accept_list_start_label
-
- def test_accept_list_start_label
- @to.start_accepting
-
- @to.accept_list_start @label_list
-
- accept_list_start_label
- end
-
- ##
- # Calls accept_list_start_lalpha
-
- def test_accept_list_start_lalpha
- @to.start_accepting
-
- @to.accept_list_start @lalpha_list
-
- accept_list_start_lalpha
- end
-
- ##
- # Calls accept_list_start_note
-
- def test_accept_list_start_note
- @to.start_accepting
-
- @to.accept_list_start @note_list
-
- accept_list_start_note
- end
-
- ##
- # Calls accept_list_start_number
-
- def test_accept_list_start_number
- @to.start_accepting
-
- @to.accept_list_start @number_list
-
- accept_list_start_number
- end
-
- ##
- # Calls accept_list_start_ualpha
-
- def test_accept_list_start_ualpha
- @to.start_accepting
-
- @to.accept_list_start @ualpha_list
-
- accept_list_start_ualpha
- end
-
- ##
- # Calls accept_list_end_bullet
-
- def test_accept_list_end_bullet
- @to.start_accepting
-
- @to.accept_list_start @bullet_list
-
- @to.accept_list_end @bullet_list
-
- accept_list_end_bullet
- end
-
- ##
- # Calls accept_list_end_label
-
- def test_accept_list_end_label
- @to.start_accepting
-
- @to.accept_list_start @label_list
-
- @to.accept_list_end @label_list
-
- accept_list_end_label
- end
-
- ##
- # Calls accept_list_end_lalpha
-
- def test_accept_list_end_lalpha
- @to.start_accepting
-
- @to.accept_list_start @lalpha_list
-
- @to.accept_list_end @lalpha_list
-
- accept_list_end_lalpha
- end
-
- ##
- # Calls accept_list_end_number
-
- def test_accept_list_end_number
- @to.start_accepting
-
- @to.accept_list_start @number_list
-
- @to.accept_list_end @number_list
-
- accept_list_end_number
- end
-
- ##
- # Calls accept_list_end_note
-
- def test_accept_list_end_note
- @to.start_accepting
-
- @to.accept_list_start @note_list
-
- @to.accept_list_end @note_list
-
- accept_list_end_note
- end
-
- ##
- # Calls accept_list_end_ualpha
-
- def test_accept_list_end_ualpha
- @to.start_accepting
-
- @to.accept_list_start @ualpha_list
-
- @to.accept_list_end @ualpha_list
-
- accept_list_end_ualpha
- end
-
- ##
- # Calls list_nested with a two-level list
-
- def test_list_nested
- doc = @RM::Document.new(
- @RM::List.new(:BULLET,
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1'),
- @RM::List.new(:BULLET,
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1.1')))),
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l2'))))
-
- doc.accept @to
-
- list_nested
- end
-
- ##
- # Calls list_verbatim with a list containing a verbatim block
-
- def test_list_verbatim # HACK overblown
- doc =
- doc(
- list(:BULLET,
- item(nil,
- para('list stuff'),
- blank_line,
- verb("* list\n",
- " with\n",
- "\n",
- " second\n",
- "\n",
- " 1. indented\n",
- " 2. numbered\n",
- "\n",
- " third\n",
- "\n",
- "* second\n"))))
-
- doc.accept @to
-
- list_verbatim
- end
- end
- end
-
-end
diff --git a/lib/rdoc/markup/hard_break.rb b/lib/rdoc/markup/hard_break.rb
index 5898bfb644..046068d5c2 100644
--- a/lib/rdoc/markup/hard_break.rb
+++ b/lib/rdoc/markup/hard_break.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A hard-break in the middle of a paragraph.
diff --git a/lib/rdoc/markup/heading.rb b/lib/rdoc/markup/heading.rb
index 5229287d5b..93a3a52000 100644
--- a/lib/rdoc/markup/heading.rb
+++ b/lib/rdoc/markup/heading.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A heading with a level (1-6) and text
@@ -23,12 +23,12 @@ RDoc::Markup::Heading =
return @to_html if @to_html
markup = RDoc::Markup.new
- markup.add_special RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
+ markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
@to_html = RDoc::Markup::ToHtml.new nil
- def @to_html.handle_special_CROSSREF special
- special.text.sub(/^\\/, '')
+ def @to_html.handle_regexp_CROSSREF target
+ target.text.sub(/^\\/, '')
end
@to_html
diff --git a/lib/rdoc/markup/include.rb b/lib/rdoc/markup/include.rb
index 891be71b85..ad7c4a9640 100644
--- a/lib/rdoc/markup/include.rb
+++ b/lib/rdoc/markup/include.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A file included at generation time. Objects of this class are created by
# RDoc::RD for an extension-less include.
diff --git a/lib/rdoc/markup/indented_paragraph.rb b/lib/rdoc/markup/indented_paragraph.rb
index 56a96bd3c9..d42b2e52b8 100644
--- a/lib/rdoc/markup/indented_paragraph.rb
+++ b/lib/rdoc/markup/indented_paragraph.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# An Indented Paragraph of text
diff --git a/lib/rdoc/markup/inline.rb b/lib/rdoc/markup/inline.rb
deleted file mode 100644
index 58072fef06..0000000000
--- a/lib/rdoc/markup/inline.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-# frozen_string_literal: false
-warn "requiring rdoc/markup/inline is deprecated and will be removed in RDoc 4." if $-w
diff --git a/lib/rdoc/markup/list.rb b/lib/rdoc/markup/list.rb
index bcaea7d7c1..05c3609202 100644
--- a/lib/rdoc/markup/list.rb
+++ b/lib/rdoc/markup/list.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A List is a homogeneous set of ListItems.
#
diff --git a/lib/rdoc/markup/list_item.rb b/lib/rdoc/markup/list_item.rb
index 115ec0412c..d22554ee73 100644
--- a/lib/rdoc/markup/list_item.rb
+++ b/lib/rdoc/markup/list_item.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# An item within a List that contains paragraphs, headings, etc.
#
diff --git a/lib/rdoc/markup/paragraph.rb b/lib/rdoc/markup/paragraph.rb
index fefa12f9ef..a2e45ef009 100644
--- a/lib/rdoc/markup/paragraph.rb
+++ b/lib/rdoc/markup/paragraph.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A Paragraph of text
diff --git a/lib/rdoc/markup/parser.rb b/lib/rdoc/markup/parser.rb
index 22cca20420..1b54a519d1 100644
--- a/lib/rdoc/markup/parser.rb
+++ b/lib/rdoc/markup/parser.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'strscan'
##
@@ -9,8 +9,9 @@ require 'strscan'
# RDoc::Markup::ToHTML.
#
# The parser only handles the block-level constructs Paragraph, List,
-# ListItem, Heading, Verbatim, BlankLine and Rule. Inline markup such as
-# <tt>\+blah\+</tt> is handled separately by RDoc::Markup::AttributeManager.
+# ListItem, Heading, Verbatim, BlankLine, Rule and BlockQuote.
+# Inline markup such as <tt>\+blah\+</tt> is handled separately by
+# RDoc::Markup::AttributeManager.
#
# To see what markup the Parser implements read RDoc. To see how to use
# RDoc markup to format text in your program read RDoc::Markup.
@@ -79,10 +80,6 @@ class RDoc::Markup::Parser
@binary_input = nil
@current_token = nil
@debug = false
- @input = nil
- @input_encoding = nil
- @line = 0
- @line_pos = 0
@s = nil
@tokens = []
end
@@ -249,7 +246,7 @@ class RDoc::Markup::Parser
min_indent = nil
generate_leading_spaces = true
- line = ''
+ line = ''.dup
until @tokens.empty? do
type, data, column, = get
@@ -257,7 +254,7 @@ class RDoc::Markup::Parser
if type == :NEWLINE then
line << data
verbatim << line
- line = ''
+ line = ''.dup
generate_leading_spaces = true
next
end
@@ -319,13 +316,6 @@ class RDoc::Markup::Parser
end
##
- # The character offset for the input string at the given +byte_offset+
-
- def char_pos byte_offset
- @input.byteslice(0, byte_offset).length
- end
-
- ##
# Pulls the next token from the stream.
def get
@@ -381,6 +371,17 @@ class RDoc::Markup::Parser
when :TEXT then
unget
parse_text parent, indent
+ when :BLOCKQUOTE then
+ type, _, column = get
+ if type == :NEWLINE
+ type, _, column = get
+ end
+ unget if type
+ bq = RDoc::Markup::BlockQuote.new
+ p :blockquote_start => [data, column] if @debug
+ parse bq, column
+ p :blockquote_end => indent if @debug
+ parent << bq
when *LIST_TOKENS then
unget
parent << build_list(indent)
@@ -413,14 +414,52 @@ class RDoc::Markup::Parser
end
##
+ # A simple wrapper of StringScanner that is aware of the current column and lineno
+
+ class MyStringScanner
+ def initialize(input)
+ @line = @column = 0
+ @s = StringScanner.new input
+ end
+
+ def scan(re)
+ ret = @s.scan(re)
+ @column += ret.length if ret
+ ret
+ end
+
+ def unscan(s)
+ @s.pos -= s.bytesize
+ @column -= s.length
+ end
+
+ def pos
+ [@column, @line]
+ end
+
+ def newline!
+ @column = 0
+ @line += 1
+ end
+
+ def eos?
+ @s.eos?
+ end
+
+ def matched
+ @s.matched
+ end
+
+ def [](i)
+ @s[i]
+ end
+ end
+
+ ##
# Creates the StringScanner
def setup_scanner input
- @line = 0
- @line_pos = 0
- @input = input.dup
-
- @s = StringScanner.new input
+ @s = MyStringScanner.new input
end
##
@@ -455,31 +494,30 @@ class RDoc::Markup::Parser
@tokens << case
# [CR]LF => :NEWLINE
when @s.scan(/\r?\n/) then
- token = [:NEWLINE, @s.matched, *token_pos(pos)]
- @line_pos = char_pos @s.pos
- @line += 1
+ token = [:NEWLINE, @s.matched, *pos]
+ @s.newline!
token
# === text => :HEADER then :TEXT
when @s.scan(/(=+)(\s*)/) then
level = @s[1].length
- header = [:HEADER, level, *token_pos(pos)]
+ header = [:HEADER, level, *pos]
if @s[2] =~ /^\r?\n/ then
- @s.pos -= @s[2].length
+ @s.unscan(@s[2])
header
else
pos = @s.pos
@s.scan(/.*/)
@tokens << header
- [:TEXT, @s.matched.sub(/\r$/, ''), *token_pos(pos)]
+ [:TEXT, @s.matched.sub(/\r$/, ''), *pos]
end
# --- (at least 3) and nothing else on the line => :RULE
when @s.scan(/(-{3,}) *\r?$/) then
- [:RULE, @s[1].length - 2, *token_pos(pos)]
+ [:RULE, @s[1].length - 2, *pos]
# * or - followed by white space and text => :BULLET
when @s.scan(/([*-]) +(\S)/) then
- @s.pos -= @s[2].bytesize # unget \S
- [:BULLET, @s[1], *token_pos(pos)]
+ @s.unscan(@s[2])
+ [:BULLET, @s[1], *pos]
# A. text, a. text, 12. text => :UALPHA, :LALPHA, :NUMBER
when @s.scan(/([a-z]|\d+)\. +(\S)/i) then
# FIXME if tab(s), the column will be wrong
@@ -488,7 +526,7 @@ class RDoc::Markup::Parser
# before (and provide a check for that at least in debug
# mode)
list_label = @s[1]
- @s.pos -= @s[2].bytesize # unget \S
+ @s.unscan(@s[2])
list_type =
case list_label
when /[a-z]/ then :LALPHA
@@ -497,20 +535,24 @@ class RDoc::Markup::Parser
else
raise ParseError, "BUG token #{list_label}"
end
- [list_type, list_label, *token_pos(pos)]
+ [list_type, list_label, *pos]
# [text] followed by spaces or end of line => :LABEL
when @s.scan(/\[(.*?)\]( +|\r?$)/) then
- [:LABEL, @s[1], *token_pos(pos)]
+ [:LABEL, @s[1], *pos]
# text:: followed by spaces or end of line => :NOTE
when @s.scan(/(.*?)::( +|\r?$)/) then
- [:NOTE, @s[1], *token_pos(pos)]
+ [:NOTE, @s[1], *pos]
+ # >>> followed by end of line => :BLOCKQUOTE
+ when @s.scan(/>>> *(\w+)?$/) then
+ [:BLOCKQUOTE, @s[1], *pos]
# anything else: :TEXT
- else @s.scan(/(.*?)( )?\r?$/)
- token = [:TEXT, @s[1], *token_pos(pos)]
+ else
+ @s.scan(/(.*?)( )?\r?$/)
+ token = [:TEXT, @s[1], *pos]
if @s[2] then
@tokens << token
- [:BREAK, @s[2], *token_pos(pos + @s[1].length)]
+ [:BREAK, @s[2], pos[0] + @s[1].length, pos[1]]
else
token
end
@@ -521,16 +563,6 @@ class RDoc::Markup::Parser
end
##
- # Calculates the column (by character) and line of the current token based
- # on +byte_offset+.
-
- def token_pos byte_offset
- offset = char_pos byte_offset
-
- [offset - @line_pos, @line]
- end
-
- ##
# Returns the current token to the token stream
def unget
diff --git a/lib/rdoc/markup/pre_process.rb b/lib/rdoc/markup/pre_process.rb
index 6ce523be89..3080ae3578 100644
--- a/lib/rdoc/markup/pre_process.rb
+++ b/lib/rdoc/markup/pre_process.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Handle common directives that can occur in a block of text:
#
@@ -105,7 +105,7 @@ class RDoc::Markup::PreProcess
# regexp helper (square brackets for optional)
# $1 $2 $3 $4 $5
# [prefix][\]:directive:[spaces][param]newline
- text.gsub!(/^([ \t]*(?:#|\/?\*)?[ \t]*)(\\?):(\w+):([ \t]*)(.+)?(\r?\n|$)/) do
+ text = text.gsub(/^([ \t]*(?:#|\/?\*)?[ \t]*)(\\?):(\w+):([ \t]*)(.+)?(\r?\n|$)/) do
# skip something like ':toto::'
next $& if $4.empty? and $5 and $5[0, 1] == ':'
@@ -123,7 +123,11 @@ class RDoc::Markup::PreProcess
handle_directive $1, $3, $5, code_object, text.encoding, &block
end
- comment = text unless comment
+ if comment then
+ comment.text = text
+ else
+ comment = text
+ end
self.class.post_processors.each do |handler|
handler.call comment, code_object
@@ -150,7 +154,7 @@ class RDoc::Markup::PreProcess
case directive
when 'arg', 'args' then
- return "#{prefix}:#{directive}: #{param}\n" unless code_object
+ return "#{prefix}:#{directive}: #{param}\n" unless code_object && code_object.kind_of?(RDoc::AnyMethod)
code_object.params = param
@@ -174,7 +178,7 @@ class RDoc::Markup::PreProcess
blankline
when 'include' then
- filename = param.split.first
+ filename = param.split(' ', 2).first
include_file filename, prefix, encoding
when 'main' then
@options.main_page = param if @options.respond_to? :main_page
@@ -212,7 +216,7 @@ class RDoc::Markup::PreProcess
when 'yield', 'yields' then
return blankline unless code_object
# remove parameter &block
- code_object.params.sub!(/,?\s*&\w+/, '') if code_object.params
+ code_object.params = code_object.params.sub(/,?\s*&\w+/, '') if code_object.params
code_object.block_params = param
@@ -262,6 +266,7 @@ class RDoc::Markup::PreProcess
end
content = RDoc::Encoding.read_file full_name, encoding, true
+ content = RDoc::Encoding.remove_magic_comment content
# strip magic comment
content = content.sub(/\A# .*coding[=:].*$/, '').lstrip
diff --git a/lib/rdoc/markup/raw.rb b/lib/rdoc/markup/raw.rb
index 8012d2cea6..85e2c8b825 100644
--- a/lib/rdoc/markup/raw.rb
+++ b/lib/rdoc/markup/raw.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A section of text that is added to the output document as-is
diff --git a/lib/rdoc/markup/regexp_handling.rb b/lib/rdoc/markup/regexp_handling.rb
new file mode 100644
index 0000000000..6ed868c2c1
--- /dev/null
+++ b/lib/rdoc/markup/regexp_handling.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+##
+# Hold details of a regexp handling sequence
+
+class RDoc::Markup::RegexpHandling
+
+ ##
+ # Regexp handling type
+
+ attr_reader :type
+
+ ##
+ # Regexp handling text
+
+ attr_accessor :text
+
+ ##
+ # Creates a new regexp handling sequence of +type+ with +text+
+
+ def initialize(type, text)
+ @type, @text = type, text
+ end
+
+ ##
+ # Regexp handlings are equal when the have the same text and type
+
+ def ==(o)
+ self.text == o.text && self.type == o.type
+ end
+
+ def inspect # :nodoc:
+ "#<RDoc::Markup::RegexpHandling:0x%x @type=%p, @text=%p>" % [
+ object_id, @type, text.dump]
+ end
+
+ def to_s # :nodoc:
+ "RegexpHandling: type=#{type} text=#{text.dump}"
+ end
+
+end
+
diff --git a/lib/rdoc/markup/rule.rb b/lib/rdoc/markup/rule.rb
index b96d4fb293..38c1dc7f56 100644
--- a/lib/rdoc/markup/rule.rb
+++ b/lib/rdoc/markup/rule.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A horizontal rule with a weight
diff --git a/lib/rdoc/markup/special.rb b/lib/rdoc/markup/special.rb
deleted file mode 100644
index 4d834b9e37..0000000000
--- a/lib/rdoc/markup/special.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: false
-##
-# Hold details of a special sequence
-
-class RDoc::Markup::Special
-
- ##
- # Special type
-
- attr_reader :type
-
- ##
- # Special text
-
- attr_accessor :text
-
- ##
- # Creates a new special sequence of +type+ with +text+
-
- def initialize(type, text)
- @type, @text = type, text
- end
-
- ##
- # Specials are equal when the have the same text and type
-
- def ==(o)
- self.text == o.text && self.type == o.type
- end
-
- def inspect # :nodoc:
- "#<RDoc::Markup::Special:0x%x @type=%p, @text=%p>" % [
- object_id, @type, text.dump]
- end
-
- def to_s # :nodoc:
- "Special: type=#{type} text=#{text.dump}"
- end
-
-end
-
diff --git a/lib/rdoc/markup/table.rb b/lib/rdoc/markup/table.rb
new file mode 100644
index 0000000000..7bcb10aff3
--- /dev/null
+++ b/lib/rdoc/markup/table.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+##
+# A section of table
+
+class RDoc::Markup::Table
+ attr_accessor :header, :align, :body
+
+ def initialize header, align, body
+ @header, @align, @body = header, align, body
+ end
+
+ def == other
+ self.class == other.class and
+ @header == other.header and
+ @align == other.align and
+ @body == other.body
+ end
+
+ def accept visitor
+ visitor.accept_table @header, @body, @align
+ end
+
+ def pretty_print q # :nodoc:
+ q.group 2, '[Table: ', ']' do
+ q.group 2, '[Head: ', ']' do
+ q.seplist @header.zip(@align) do |text, align|
+ q.pp text
+ if align
+ q.text ":"
+ q.breakable
+ q.text align.to_s
+ end
+ end
+ end
+ q.breakable
+ q.group 2, '[Body: ', ']' do
+ q.seplist @body do |body|
+ q.group 2, '[', ']' do
+ q.seplist body do |text|
+ q.pp text
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/rdoc/markup/text_formatter_test_case.rb b/lib/rdoc/markup/text_formatter_test_case.rb
deleted file mode 100644
index 1c8882aa36..0000000000
--- a/lib/rdoc/markup/text_formatter_test_case.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-# frozen_string_literal: false
-##
-# Test case for creating new plain-text RDoc::Markup formatters. See also
-# RDoc::Markup::FormatterTestCase
-#
-# See test_rdoc_markup_to_rdoc.rb for a complete example.
-#
-# Example:
-#
-# class TestRDocMarkupToNewTextFormat < RDoc::Markup::TextFormatterTestCase
-#
-# add_visitor_tests
-# add_text_tests
-#
-# def setup
-# super
-#
-# @to = RDoc::Markup::ToNewTextFormat.new
-# end
-#
-# def accept_blank_line
-# assert_equal :junk, @to.res.join
-# end
-#
-# # ...
-#
-# end
-
-class RDoc::Markup::TextFormatterTestCase < RDoc::Markup::FormatterTestCase
-
- ##
- # Adds test cases to the calling TestCase.
-
- def self.add_text_tests
- self.class_eval do
-
- ##
- # Test case that calls <tt>@to.accept_heading</tt>
-
- def test_accept_heading_indent
- @to.start_accepting
- @to.indent = 3
- @to.accept_heading @RM::Heading.new(1, 'Hello')
-
- accept_heading_indent
- end
-
- ##
- # Test case that calls <tt>@to.accept_rule</tt>
-
- def test_accept_rule_indent
- @to.start_accepting
- @to.indent = 3
- @to.accept_rule @RM::Rule.new(1)
-
- accept_rule_indent
- end
-
- ##
- # Test case that calls <tt>@to.accept_verbatim</tt>
-
- def test_accept_verbatim_indent
- @to.start_accepting
- @to.indent = 2
- @to.accept_verbatim @RM::Verbatim.new("hi\n", " world\n")
-
- accept_verbatim_indent
- end
-
- ##
- # Test case that calls <tt>@to.accept_verbatim</tt> with a big indent
-
- def test_accept_verbatim_big_indent
- @to.start_accepting
- @to.indent = 2
- @to.accept_verbatim @RM::Verbatim.new("hi\n", "world\n")
-
- accept_verbatim_big_indent
- end
-
- ##
- # Test case that calls <tt>@to.accept_paragraph</tt> with an indent
-
- def test_accept_paragraph_indent
- @to.start_accepting
- @to.indent = 3
- @to.accept_paragraph @RM::Paragraph.new(('words ' * 30).strip)
-
- accept_paragraph_indent
- end
-
- ##
- # Test case that calls <tt>@to.accept_paragraph</tt> with a long line
-
- def test_accept_paragraph_wrap
- @to.start_accepting
- @to.accept_paragraph @RM::Paragraph.new(('words ' * 30).strip)
-
- accept_paragraph_wrap
- end
-
- ##
- # Test case that calls <tt>@to.attributes</tt> with an escaped
- # cross-reference. If this test doesn't pass something may be very
- # wrong.
-
- def test_attributes
- assert_equal 'Dog', @to.attributes("\\Dog")
- end
-
- end
- end
-
-end
-
diff --git a/lib/rdoc/markup/to_ansi.rb b/lib/rdoc/markup/to_ansi.rb
index 56cd1fe446..6cc3b70e93 100644
--- a/lib/rdoc/markup/to_ansi.rb
+++ b/lib/rdoc/markup/to_ansi.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Outputs RDoc markup with vibrant ANSI color!
diff --git a/lib/rdoc/markup/to_bs.rb b/lib/rdoc/markup/to_bs.rb
index 9a1c7c6ccd..f9b86487db 100644
--- a/lib/rdoc/markup/to_bs.rb
+++ b/lib/rdoc/markup/to_bs.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Outputs RDoc markup with hot backspace action! You will probably need a
# pager to use this output format.
@@ -41,7 +41,7 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
end
##
- # Turns on or off special handling for +convert_string+
+ # Turns on or off regexp handling for +convert_string+
def annotate tag
case tag
@@ -54,9 +54,9 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
end
##
- # Calls convert_string on the result of convert_special
+ # Calls convert_string on the result of convert_regexp_handling
- def convert_special special
+ def convert_regexp_handling target
convert_string super
end
diff --git a/lib/rdoc/markup/to_html.rb b/lib/rdoc/markup/to_html.rb
index d2c9a23a79..8ae4dd4720 100644
--- a/lib/rdoc/markup/to_html.rb
+++ b/lib/rdoc/markup/to_html.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'cgi'
##
@@ -52,19 +52,32 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
@th = nil
@hard_break = "<br>\n"
- # external links
- @markup.add_special(/(?:link:|https?:|mailto:|ftp:|irc:|www\.)\S+\w/,
- :HYPERLINK)
-
- add_special_RDOCLINK
- add_special_TIDYLINK
+ init_regexp_handlings
init_tags
end
- # :section: Special Handling
+ # :section: Regexp Handling
#
- # These methods handle special markup added by RDoc::Markup#add_special.
+ # These methods are used by regexp handling markup added by RDoc::Markup#add_regexp_handling.
+
+ ##
+ # Adds regexp handlings.
+
+ def init_regexp_handlings
+ # external links
+ @markup.add_regexp_handling(/(?:link:|https?:|mailto:|ftp:|irc:|www\.)\S+\w/,
+ :HYPERLINK)
+ init_link_notation_regexp_handlings
+ end
+
+ ##
+ # Adds regexp handlings about link notations.
+
+ def init_link_notation_regexp_handlings
+ add_regexp_handling_RDOCLINK
+ add_regexp_handling_TIDYLINK
+ end
def handle_RDOCLINK url # :nodoc:
case url
@@ -91,14 +104,14 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
end
##
- # +special+ is a <code><br></code>
+ # +target+ is a <code><br></code>
- def handle_special_HARD_BREAK special
+ def handle_regexp_HARD_BREAK target
'<br>'
end
##
- # +special+ is a potential link. The following schemes are handled:
+ # +target+ is a potential link. The following schemes are handled:
#
# <tt>mailto:</tt>::
# Inserted as-is.
@@ -109,14 +122,14 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
# <tt>link:</tt>::
# Reference to a local file relative to the output directory.
- def handle_special_HYPERLINK(special)
- url = special.text
+ def handle_regexp_HYPERLINK(target)
+ url = target.text
gen_url url, url
end
##
- # +special+ is an rdoc-schemed link that will be converted into a hyperlink.
+ # +target+ is an rdoc-schemed link that will be converted into a hyperlink.
#
# For the +rdoc-ref+ scheme the named reference will be returned without
# creating a link.
@@ -124,16 +137,16 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
# For the +rdoc-label+ scheme the footnote and label prefixes are stripped
# when creating a link. All other contents will be linked verbatim.
- def handle_special_RDOCLINK special
- handle_RDOCLINK special.text
+ def handle_regexp_RDOCLINK target
+ handle_RDOCLINK target.text
end
##
- # This +special+ is a link where the label is different from the URL
+ # This +target+ is a link where the label is different from the URL
# <tt>label[url]</tt> or <tt>{long label}[url]</tt>
- def handle_special_TIDYLINK(special)
- text = special.text
+ def handle_regexp_TIDYLINK(target)
+ text = target.text
return text unless
text =~ /^\{(.*)\}\[(.*?)\]$/ or text =~ /^(\S+)\[(.*?)\]$/
@@ -186,7 +199,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
@res << "\n<p>"
text = paragraph.text @hard_break
text = text.gsub(/\r?\n/, ' ')
- @res << wrap(to_html(text))
+ @res << to_html(text)
@res << "</p>\n"
end
@@ -200,7 +213,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
content = if verbatim.ruby? or parseable? text then
begin
- tokens = RDoc::RipperStateLex.parse text
+ tokens = RDoc::Parser::RipperStateLex.parse text
klass = ' class="ruby"'
result = RDoc::TokenStream.to_html tokens
@@ -301,6 +314,29 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
@res << raw.parts.join("\n")
end
+ ##
+ # Adds +table+ to the output
+
+ def accept_table header, body, aligns
+ @res << "\n<table role=\"table\">\n<thead>\n<tr>\n"
+ header.zip(aligns) do |text, align|
+ @res << '<th'
+ @res << ' align="' << align << '"' if align
+ @res << '>' << CGI.escapeHTML(text) << "</th>\n"
+ end
+ @res << "</tr>\n</thead>\n<tbody>\n"
+ body.each do |row|
+ @res << "<tr>\n"
+ row.zip(aligns) do |text, align|
+ @res << '<td'
+ @res << ' align="' << align << '"' if align
+ @res << '>' << CGI.escapeHTML(text) << "</td>\n"
+ end
+ @res << "</tr>\n"
+ end
+ @res << "</tbody>\n</table>\n"
+ end
+
# :section: Utilities
##
@@ -312,7 +348,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
##
# Generate a link to +url+ with content +text+. Handles the special cases
- # for img: and link: described under handle_special_HYPERLINK
+ # for img: and link: described under handle_regexp_HYPERLINK
def gen_url url, text
scheme, url, id = parse_url url
@@ -321,6 +357,10 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
"<img src=\"#{url}\" />"
else
+ if scheme != 'link' and /\.(?:rb|rdoc|md)\z/i =~ url
+ url = url.sub(%r%\A([./]*)(.*)\z%) { "#$1#{$2.tr('.', '_')}.html" }
+ end
+
text = text.sub %r%^#{scheme}:/*%i, ''
text = text.sub %r%^[*\^](\d+)$%, '\1'
diff --git a/lib/rdoc/markup/to_html_crossref.rb b/lib/rdoc/markup/to_html_crossref.rb
index 3f03c65898..a9fd09df41 100644
--- a/lib/rdoc/markup/to_html_crossref.rb
+++ b/lib/rdoc/markup/to_html_crossref.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Subclass of the RDoc::Markup::ToHtml class that supports looking up method
# names, classes, etc to create links. RDoc::CrossReference is used to
@@ -39,26 +39,37 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
@hyperlink_all = @options.hyperlink_all
@show_hash = @options.show_hash
- crossref_re = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
- @markup.add_special crossref_re, :CROSSREF
-
@cross_reference = RDoc::CrossReference.new @context
end
+ def init_link_notation_regexp_handlings
+ add_regexp_handling_RDOCLINK
+
+ # The crossref must be linked before tidylink because Klass.method[:sym]
+ # will be processed as a tidylink first and will be broken.
+ crossref_re = @options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
+ @markup.add_regexp_handling crossref_re, :CROSSREF
+
+ add_regexp_handling_TIDYLINK
+ end
+
##
# Creates a link to the reference +name+ if the name exists. If +text+ is
# given it is used as the link text, otherwise +name+ is used.
- def cross_reference name, text = nil
+ def cross_reference name, text = nil, code = true
lookup = name
name = name[1..-1] unless @show_hash if name[0, 1] == '#'
- name = "#{CGI.unescape $'} at #{$1}" if name =~ /(.*[^#:])@/
-
- text = name unless text
+ if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])@/
+ text ||= "#{CGI.unescape $'} at <code>#{$1}</code>"
+ code = false
+ else
+ text ||= name
+ end
- link lookup, text
+ link lookup, text, code
end
##
@@ -68,8 +79,8 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
# example, ToHtml is found, even without the <tt>RDoc::Markup::</tt> prefix,
# because we look for it in module Markup first.
- def handle_special_CROSSREF(special)
- name = special.text
+ def handle_regexp_CROSSREF(target)
+ name = target.text
return name if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails
@@ -87,22 +98,22 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
# Handles <tt>rdoc-ref:</tt> scheme links and allows RDoc::Markup::ToHtml to
# handle other schemes.
- def handle_special_HYPERLINK special
- return cross_reference $' if special.text =~ /\Ardoc-ref:/
+ def handle_regexp_HYPERLINK target
+ return cross_reference $' if target.text =~ /\Ardoc-ref:/
super
end
##
- # +special+ is an rdoc-schemed link that will be converted into a hyperlink.
+ # +target+ is an rdoc-schemed link that will be converted into a hyperlink.
# For the rdoc-ref scheme the cross-reference will be looked up and the
# given name will be used.
#
# All other contents are handled by
- # {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_special_RDOCLINK]
+ # {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK]
- def handle_special_RDOCLINK special
- url = special.text
+ def handle_regexp_RDOCLINK target
+ url = target.text
case url
when /\Ardoc-ref:/ then
@@ -119,38 +130,42 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
def gen_url url, text
return super unless url =~ /\Ardoc-ref:/
- cross_reference $', text
+ name = $'
+ cross_reference name, text, name == text
end
##
# Creates an HTML link to +name+ with the given +text+.
- def link name, text
- original_name = name
-
- if name =~ /(.*[^#:])@/ then
+ def link name, text, code = true
+ if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])@/
name = $1
label = $'
end
ref = @cross_reference.resolve name, text
- text = ref.output_name @context if
- RDoc::MethodAttr === ref and text == original_name
-
case ref
when String then
ref
else
path = ref.as_href @from_path
+ if code and RDoc::CodeObject === ref and !(RDoc::TopLevel === ref)
+ text = "<code>#{CGI.escapeHTML text}</code>"
+ end
+
if path =~ /#/ then
path << "-label-#{label}"
elsif ref.sections and
ref.sections.any? { |section| label == section.title } then
path << "##{label}"
else
- path << "#label-#{label}"
+ if ref.respond_to?(:aref)
+ path << "##{ref.aref}-label-#{label}"
+ else
+ path << "#label-#{label}"
+ end
end if label
"<a href=\"#{path}\">#{text}</a>"
diff --git a/lib/rdoc/markup/to_html_snippet.rb b/lib/rdoc/markup/to_html_snippet.rb
index 75c1df94d9..4eb36592b7 100644
--- a/lib/rdoc/markup/to_html_snippet.rb
+++ b/lib/rdoc/markup/to_html_snippet.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Outputs RDoc markup as paragraphs with inline markup only.
@@ -44,7 +44,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
@mask = 0
@paragraphs = 0
- @markup.add_special RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
+ @markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
end
##
@@ -71,7 +71,7 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
text = paragraph.text @hard_break
- @res << "#{para}#{wrap to_html text}\n"
+ @res << "#{para}#{to_html text}\n"
add_paragraph
end
@@ -123,16 +123,16 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
end
##
- # Removes escaping from the cross-references in +special+
+ # Removes escaping from the cross-references in +target+
- def handle_special_CROSSREF special
- special.text.sub(/\A\\/, '')
+ def handle_regexp_CROSSREF target
+ target.text.sub(/\A\\/, '')
end
##
- # +special+ is a <code><br></code>
+ # +target+ is a <code><br></code>
- def handle_special_HARD_BREAK special
+ def handle_regexp_HARD_BREAK target
@characters -= 4
'<br>'
end
@@ -226,8 +226,8 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
when String then
text = convert_string item
res << truncate(text)
- when RDoc::Markup::Special then
- text = convert_special item
+ when RDoc::Markup::RegexpHandling then
+ text = convert_regexp_handling item
res << truncate(text)
else
raise "Unknown flow element: #{item.inspect}"
diff --git a/lib/rdoc/markup/to_joined_paragraph.rb b/lib/rdoc/markup/to_joined_paragraph.rb
index 293258c092..46e07c94ad 100644
--- a/lib/rdoc/markup/to_joined_paragraph.rb
+++ b/lib/rdoc/markup/to_joined_paragraph.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Joins the parts of an RDoc::Markup::Paragraph into a single String.
#
@@ -23,37 +23,11 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter
# Converts the parts of +paragraph+ to a single entry.
def accept_paragraph paragraph
- parts = []
- string = false
-
- paragraph.parts.each do |part|
- if String === part then
- if string then
- string << part
- else
- parts << part
- string = part
- end
- else
- parts << part
- string = false
- end
- end
-
- parts = parts.map do |part|
- if String === part then
- part.rstrip
- else
- part
- end
- end
-
- # TODO use Enumerable#chunk when Ruby 1.8 support is dropped
- #parts = paragraph.parts.chunk do |part|
- # String === part
- #end.map do |string, chunk|
- # string ? chunk.join.rstrip : chunk
- #end.flatten
+ parts = paragraph.parts.chunk do |part|
+ String === part
+ end.map do |string, chunk|
+ string ? chunk.join.rstrip : chunk
+ end.flatten
paragraph.parts.replace parts
end
@@ -67,6 +41,7 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter
alias accept_raw ignore
alias accept_rule ignore
alias accept_verbatim ignore
+ alias accept_table ignore
end
diff --git a/lib/rdoc/markup/to_label.rb b/lib/rdoc/markup/to_label.rb
index bdf08b7aee..3d95ccc2e2 100644
--- a/lib/rdoc/markup/to_label.rb
+++ b/lib/rdoc/markup/to_label.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'cgi'
##
@@ -16,8 +16,8 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
def initialize markup = nil
super nil, markup
- @markup.add_special RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
- @markup.add_special(/(((\{.*?\})|\b\S+?)\[\S+?\])/, :TIDYLINK)
+ @markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
+ @markup.add_regexp_handling(/(((\{.*?\})|\b\S+?)\[\S+?\])/, :TIDYLINK)
add_tag :BOLD, '', ''
add_tag :TT, '', ''
@@ -36,20 +36,20 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
end
##
- # Converts the CROSSREF +special+ to plain text, removing the suppression
+ # Converts the CROSSREF +target+ to plain text, removing the suppression
# marker, if any
- def handle_special_CROSSREF special
- text = special.text
+ def handle_regexp_CROSSREF target
+ text = target.text
text.sub(/^\\/, '')
end
##
- # Converts the TIDYLINK +special+ to just the text part
+ # Converts the TIDYLINK +target+ to just the text part
- def handle_special_TIDYLINK special
- text = special.text
+ def handle_regexp_TIDYLINK target
+ text = target.text
return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/
@@ -68,7 +68,7 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
alias accept_rule ignore
alias accept_verbatim ignore
alias end_accepting ignore
- alias handle_special_HARD_BREAK ignore
+ alias handle_regexp_HARD_BREAK ignore
alias start_accepting ignore
end
diff --git a/lib/rdoc/markup/to_markdown.rb b/lib/rdoc/markup/to_markdown.rb
index 9074547b4c..3ee48becb0 100644
--- a/lib/rdoc/markup/to_markdown.rb
+++ b/lib/rdoc/markup/to_markdown.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
# :markup: markdown
##
@@ -19,8 +19,8 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
@headings[5] = ['##### ', '']
@headings[6] = ['###### ', '']
- add_special_RDOCLINK
- add_special_TIDYLINK
+ add_regexp_handling_RDOCLINK
+ add_regexp_handling_TIDYLINK
@hard_break = " \n"
end
@@ -37,7 +37,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
##
# Adds a newline to the output
- def handle_special_HARD_BREAK special
+ def handle_regexp_HARD_BREAK target
" \n"
end
@@ -131,7 +131,7 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
@res << part
end
- @res << "\n" unless @res =~ /\n\z/
+ @res << "\n"
end
##
@@ -166,8 +166,8 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
##
# Converts the RDoc markup tidylink into a Markdown.style link.
- def handle_special_TIDYLINK special
- text = special.text
+ def handle_regexp_TIDYLINK target
+ text = target.text
return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/
@@ -184,8 +184,8 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
##
# Converts the rdoc-...: links into a Markdown.style links.
- def handle_special_RDOCLINK special
- handle_rdoc_link special.text
+ def handle_regexp_RDOCLINK target
+ handle_rdoc_link target.text
end
end
diff --git a/lib/rdoc/markup/to_rdoc.rb b/lib/rdoc/markup/to_rdoc.rb
index a40c09859f..3cdf4fd08b 100644
--- a/lib/rdoc/markup/to_rdoc.rb
+++ b/lib/rdoc/markup/to_rdoc.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Outputs RDoc markup as RDoc markup! (mostly)
@@ -45,7 +45,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
def initialize markup = nil
super nil, markup
- @markup.add_special(/\\\S/, :SUPPRESSED_CROSSREF)
+ @markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF)
@width = 78
init_tags
@@ -234,7 +234,35 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
@res << part
end
- @res << "\n" unless @res =~ /\n\z/
+ @res << "\n"
+ end
+
+ ##
+ # Adds +table+ to the output
+
+ def accept_table header, body, aligns
+ widths = header.zip(body) do |h, b|
+ [h.size, b.size].max
+ end
+ aligns = aligns.map do |a|
+ case a
+ when nil
+ :center
+ when :left
+ :ljust
+ when :right
+ :rjust
+ end
+ end
+ @res << header.zip(widths, aligns) do |h, w, a|
+ h.__send__(a, w)
+ end.join("|").rstrip << "\n"
+ @res << widths.map {|w| "-" * w }.join("|") << "\n"
+ body.each do |row|
+ @res << row.zip(widths, aligns) do |t, w, a|
+ t.__send__(a, w)
+ end.join("|").rstrip << "\n"
+ end
end
##
@@ -253,10 +281,10 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
end
##
- # Removes preceding \\ from the suppressed crossref +special+
+ # Removes preceding \\ from the suppressed crossref +target+
- def handle_special_SUPPRESSED_CROSSREF special
- text = special.text
+ def handle_regexp_SUPPRESSED_CROSSREF target
+ text = target.text
text = text.sub('\\', '') unless in_tt?
text
end
@@ -264,7 +292,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
##
# Adds a newline to the output
- def handle_special_HARD_BREAK special
+ def handle_regexp_HARD_BREAK target
"\n"
end
diff --git a/lib/rdoc/markup/to_table_of_contents.rb b/lib/rdoc/markup/to_table_of_contents.rb
index eae7c59d94..eb8e8faa16 100644
--- a/lib/rdoc/markup/to_table_of_contents.rb
+++ b/lib/rdoc/markup/to_table_of_contents.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Extracts just the RDoc::Markup::Heading elements from a
# RDoc::Markup::Document to help build a table of contents
@@ -82,6 +82,7 @@ class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter
alias accept_list_item_end ignore
alias accept_list_end_bullet ignore
alias accept_list_start ignore
+ alias accept_table ignore
# :startdoc:
end
diff --git a/lib/rdoc/markup/to_test.rb b/lib/rdoc/markup/to_test.rb
index 7b1fa8c630..61d3cffaf0 100644
--- a/lib/rdoc/markup/to_test.rb
+++ b/lib/rdoc/markup/to_test.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# This Markup outputter is used for testing purposes.
diff --git a/lib/rdoc/markup/to_tt_only.rb b/lib/rdoc/markup/to_tt_only.rb
index ba20fcdd00..9235d33f04 100644
--- a/lib/rdoc/markup/to_tt_only.rb
+++ b/lib/rdoc/markup/to_tt_only.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Extracts sections of text enclosed in plus, tt or code. Used to discover
# undocumented parameters.
@@ -91,8 +91,8 @@ class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter
when RDoc::Markup::AttrChanger then
off_tags res, item
on_tags res, item
- when RDoc::Markup::Special then
- @res << convert_special(item) if in_tt? # TODO can this happen?
+ when RDoc::Markup::RegexpHandling then
+ @res << convert_regexp_handling(item) if in_tt? # TODO can this happen?
else
raise "Unknown flow element: #{item.inspect}"
end
diff --git a/lib/rdoc/markup/verbatim.rb b/lib/rdoc/markup/verbatim.rb
index a0b1d05928..7f1bc29a09 100644
--- a/lib/rdoc/markup/verbatim.rb
+++ b/lib/rdoc/markup/verbatim.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A section of verbatim text
diff --git a/lib/rdoc/meta_method.rb b/lib/rdoc/meta_method.rb
index 408c089dd1..7927a9ce9c 100644
--- a/lib/rdoc/meta_method.rb
+++ b/lib/rdoc/meta_method.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# MetaMethod represents a meta-programmed method
diff --git a/lib/rdoc/method_attr.rb b/lib/rdoc/method_attr.rb
index 50eab141be..3cef78c4a5 100644
--- a/lib/rdoc/method_attr.rb
+++ b/lib/rdoc/method_attr.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Abstract class representing either a method or an attribute.
@@ -188,7 +188,7 @@ class RDoc::MethodAttr < RDoc::CodeObject
next if String === ancestor
next if parent == ancestor
- other = ancestor.find_method_named('#' << name) ||
+ other = ancestor.find_method_named('#' + name) ||
ancestor.find_attribute_named(name)
return other if other
diff --git a/lib/rdoc/mixin.rb b/lib/rdoc/mixin.rb
index 14f04c15e7..379d7cc526 100644
--- a/lib/rdoc/mixin.rb
+++ b/lib/rdoc/mixin.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A Mixin adds features from a module into another context. RDoc::Include and
# RDoc::Extend are both mixins.
diff --git a/lib/rdoc/normal_class.rb b/lib/rdoc/normal_class.rb
index eb53e964dd..6729b18448 100644
--- a/lib/rdoc/normal_class.rb
+++ b/lib/rdoc/normal_class.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A normal class, neither singleton nor anonymous
@@ -47,9 +47,9 @@ class RDoc::NormalClass < RDoc::ClassModule
def to_s # :nodoc:
display = "#{self.class.name} #{self.full_name}"
if superclass
- display << ' < ' << (superclass.is_a?(String) ? superclass : superclass.full_name)
+ display += ' < ' + (superclass.is_a?(String) ? superclass : superclass.full_name)
end
- display << ' -> ' << is_alias_for.to_s if is_alias_for
+ display += ' -> ' + is_alias_for.to_s if is_alias_for
display
end
diff --git a/lib/rdoc/normal_module.rb b/lib/rdoc/normal_module.rb
index d046c8cbfe..8f364be41c 100644
--- a/lib/rdoc/normal_module.rb
+++ b/lib/rdoc/normal_module.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A normal module, like NormalClass
diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb
index 60cfb5e553..13b7ba5c6c 100644
--- a/lib/rdoc/options.rb
+++ b/lib/rdoc/options.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'optparse'
require 'pathname'
@@ -164,7 +164,7 @@ class RDoc::Options
##
# Files matching this pattern will be excluded
- attr_accessor :exclude
+ attr_writer :exclude
##
# The list of files to be processed
@@ -338,13 +338,17 @@ class RDoc::Options
attr_reader :visibility
- def initialize # :nodoc:
+ def initialize loaded_options = nil # :nodoc:
init_ivars
+ override loaded_options if loaded_options
end
def init_ivars # :nodoc:
@dry_run = false
- @exclude = []
+ @exclude = %w[
+ ~\z \.orig\z \.rej\z \.bak\z
+ \.gemspec\z
+ ]
@files = nil
@force_output = false
@force_update = true
@@ -414,6 +418,37 @@ class RDoc::Options
init_with map
end
+ def override map # :nodoc:
+ if map.has_key?('encoding')
+ encoding = map['encoding']
+ @encoding = encoding ? Encoding.find(encoding) : encoding
+ end
+
+ @charset = map['charset'] if map.has_key?('charset')
+ @exclude = map['exclude'] if map.has_key?('exclude')
+ @generator_name = map['generator_name'] if map.has_key?('generator_name')
+ @hyperlink_all = map['hyperlink_all'] if map.has_key?('hyperlink_all')
+ @line_numbers = map['line_numbers'] if map.has_key?('line_numbers')
+ @locale_name = map['locale_name'] if map.has_key?('locale_name')
+ @locale_dir = map['locale_dir'] if map.has_key?('locale_dir')
+ @main_page = map['main_page'] if map.has_key?('main_page')
+ @markup = map['markup'] if map.has_key?('markup')
+ @op_dir = map['op_dir'] if map.has_key?('op_dir')
+ @show_hash = map['show_hash'] if map.has_key?('show_hash')
+ @tab_width = map['tab_width'] if map.has_key?('tab_width')
+ @template_dir = map['template_dir'] if map.has_key?('template_dir')
+ @title = map['title'] if map.has_key?('title')
+ @visibility = map['visibility'] if map.has_key?('visibility')
+ @webcvs = map['webcvs'] if map.has_key?('webcvs')
+
+ if map.has_key?('rdoc_include')
+ @rdoc_include = sanitize_path map['rdoc_include']
+ end
+ if map.has_key?('static_path')
+ @static_path = sanitize_path map['static_path']
+ end
+ end
+
def == other # :nodoc:
self.class === other and
@encoding == other.encoding and
@@ -494,6 +529,20 @@ class RDoc::Options
end
##
+ # Create a regexp for #exclude
+
+ def exclude
+ if @exclude.nil? or Regexp === @exclude then
+ # done, #finish is being re-run
+ @exclude
+ elsif @exclude.empty? then
+ nil
+ else
+ Regexp.new(@exclude.join("|"))
+ end
+ end
+
+ ##
# Completes any unfinished option setup business such as filtering for
# existent files, creating a regexp for #exclude and setting a default
# #template.
@@ -505,13 +554,7 @@ class RDoc::Options
root = @root.to_s
@rdoc_include << root unless @rdoc_include.include?(root)
- if @exclude.nil? or Regexp === @exclude then
- # done, #finish is being re-run
- elsif @exclude.empty? then
- @exclude = nil
- else
- @exclude = Regexp.new(@exclude.join("|"))
- end
+ @exclude = self.exclude
finish_page_dir
@@ -544,7 +587,13 @@ class RDoc::Options
@files << @page_dir.to_s
- page_dir = @page_dir.expand_path.relative_path_from @root
+ page_dir = nil
+ begin
+ page_dir = @page_dir.expand_path.relative_path_from @root
+ rescue ArgumentError
+ # On Windows, sometimes crosses different drive letters.
+ page_dir = @page_dir.expand_path
+ end
@page_dir = page_dir
end
@@ -624,16 +673,16 @@ Usage: #{opt.program_name} [options] [names...]
end
parsers.sort.each do |parser, regexp|
- opt.banner << " - #{parser}: #{regexp.join ', '}\n"
+ opt.banner += " - #{parser}: #{regexp.join ', '}\n"
end
- opt.banner << " - TomDoc: Only in ruby files\n"
+ opt.banner += " - TomDoc: Only in ruby files\n"
- opt.banner << "\n The following options are deprecated:\n\n"
+ opt.banner += "\n The following options are deprecated:\n\n"
name_length = DEPRECATED.keys.sort_by { |k| k.length }.last.length
DEPRECATED.sort_by { |k,| k }.each do |name, reason|
- opt.banner << " %*1$2$s %3$s\n" % [-name_length, name, reason]
+ opt.banner += " %*1$2$s %3$s\n" % [-name_length, name, reason]
end
opt.accept Template do |template|
@@ -738,7 +787,7 @@ Usage: #{opt.program_name} [options] [names...]
opt.on("--[no-]force-update", "-U",
"Forces rdoc to scan all sources even if",
- "newer than the flag file.") do |value|
+ "no files are newer than the flag file.") do |value|
@force_update = value
end
@@ -1087,7 +1136,7 @@ Usage: #{opt.program_name} [options] [names...]
unless quiet then
deprecated.each do |opt|
- $stderr.puts 'option ' << opt << ' is deprecated: ' << DEPRECATED[opt]
+ $stderr.puts 'option ' + opt + ' is deprecated: ' + DEPRECATED[opt]
end
end
@@ -1143,8 +1192,17 @@ Usage: #{opt.program_name} [options] [names...]
path.reject do |item|
path = Pathname.new(item).expand_path
- relative = path.relative_path_from(dot).to_s
- relative.start_with? '..'
+ is_reject = nil
+ relative = nil
+ begin
+ relative = path.relative_path_from(dot).to_s
+ rescue ArgumentError
+ # On Windows, sometimes crosses different drive letters.
+ is_reject = true
+ else
+ is_reject = relative.start_with? '..'
+ end
+ is_reject
end
end
@@ -1217,7 +1275,7 @@ Usage: #{opt.program_name} [options] [names...]
def write_options
RDoc.load_yaml
- open '.rdoc_options', 'w' do |io|
+ File.open '.rdoc_options', 'w' do |io|
io.set_encoding Encoding::UTF_8
YAML.dump self, io
diff --git a/lib/rdoc/parser.rb b/lib/rdoc/parser.rb
index 823a6d014c..425bc48632 100644
--- a/lib/rdoc/parser.rb
+++ b/lib/rdoc/parser.rb
@@ -1,5 +1,5 @@
# -*- coding: us-ascii -*-
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A parser is simple a class that subclasses RDoc::Parser and implements #scan
@@ -78,7 +78,7 @@ class RDoc::Parser
return true if s[0, 2] == Marshal.dump('')[0, 2] or s.index("\x00")
- mode = 'r:utf-8' # default source encoding has been chagened to utf-8
+ mode = 'r:utf-8' # default source encoding has been changed to utf-8
s.sub!(/\A#!.*\n/, '') # assume shebang line isn't longer than 1024.
encoding = s[/^\s*\#\s*(?:-\*-\s*)?(?:en)?coding:\s*([^\s;]+?)(?:-\*-|[\s;])/, 1]
mode = "rb:#{encoding}" if encoding
@@ -139,7 +139,7 @@ class RDoc::Parser
# Returns the file type from the modeline in +file_name+
def self.check_modeline file_name
- line = open file_name do |io|
+ line = File.open file_name do |io|
io.gets
end
@@ -269,9 +269,9 @@ class RDoc::Parser
end
# simple must come first in order to show up last in the parsers list
-require 'rdoc/parser/simple'
-require 'rdoc/parser/c'
-require 'rdoc/parser/changelog'
-require 'rdoc/parser/markdown'
-require 'rdoc/parser/rd'
-require 'rdoc/parser/ruby'
+require_relative 'parser/simple'
+require_relative 'parser/c'
+require_relative 'parser/changelog'
+require_relative 'parser/markdown'
+require_relative 'parser/rd'
+require_relative 'parser/ruby'
diff --git a/lib/rdoc/parser/c.rb b/lib/rdoc/parser/c.rb
index 5c940ab28e..9d8db6cdee 100644
--- a/lib/rdoc/parser/c.rb
+++ b/lib/rdoc/parser/c.rb
@@ -1,17 +1,17 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'tsort'
##
# RDoc::Parser::C attempts to parse C extension files. It looks for
-# the standard patterns that you find in extensions: <tt>rb_define_class,
-# rb_define_method</tt> and so on. It tries to find the corresponding
+# the standard patterns that you find in extensions: +rb_define_class+,
+# +rb_define_method+ and so on. It tries to find the corresponding
# C source for the methods and extract comments, but if we fail
# we don't worry too much.
#
# The comments associated with a Ruby method are extracted from the C
# comment block associated with the routine that _implements_ that
# method, that is to say the method whose name is given in the
-# <tt>rb_define_method</tt> call. For example, you might write:
+# +rb_define_method+ call. For example, you might write:
#
# /*
# * Returns a new array that is a one-dimensional flattening of this
@@ -24,8 +24,7 @@ require 'tsort'
# * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# */
# static VALUE
-# rb_ary_flatten(ary)
-# VALUE ary;
+# rb_ary_flatten(VALUE ary)
# {
# ary = rb_obj_dup(ary);
# rb_ary_flatten_bang(ary);
@@ -35,16 +34,16 @@ require 'tsort'
# ...
#
# void
-# Init_Array()
+# Init_Array(void)
# {
# ...
# rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
#
-# Here RDoc will determine from the rb_define_method line that there's a
+# Here RDoc will determine from the +rb_define_method+ line that there's a
# method called "flatten" in class Array, and will look for the implementation
-# in the method rb_ary_flatten. It will then use the comment from that
+# in the method +rb_ary_flatten+. It will then use the comment from that
# method in the HTML output. This method must be in the same source file
-# as the rb_define_method.
+# as the +rb_define_method+.
#
# The comment blocks may include special directives:
#
@@ -70,15 +69,15 @@ require 'tsort'
# [Document-variable: +name+]
# Documentation for the named +rb_define_variable+
#
-# [Document-method: +method_name+]
+# [Document-method\: +method_name+]
# Documentation for the named method. Use this when the method name is
# unambiguous.
#
-# [Document-method: <tt>ClassName::method_name<tt>]
+# [Document-method\: <tt>ClassName::method_name</tt>]
# Documentation for a singleton method in the given class. Use this when
# the method name alone is ambiguous.
#
-# [Document-method: <tt>ClassName#method_name<tt>]
+# [Document-method\: <tt>ClassName#method_name</tt>]
# Documentation for a instance method in the given class. Use this when the
# method name alone is ambiguous.
#
@@ -211,47 +210,6 @@ class RDoc::Parser::C < RDoc::Parser
end
##
- # Removes duplicate call-seq entries for methods using the same
- # implementation.
-
- def deduplicate_call_seq
- @methods.each do |var_name, functions|
- class_name = @known_classes[var_name]
- class_obj = find_class var_name, class_name
-
- functions.each_value do |method_names|
- next if method_names.length == 1
-
- method_names.each do |method_name|
- deduplicate_method_name class_obj, method_name
- end
- end
- end
- end
-
- ##
- # If two ruby methods share a C implementation (and comment) this
- # deduplicates the examples in the call_seq for the method to reduce
- # confusion in the output.
-
- def deduplicate_method_name class_obj, method_name # :nodoc:
- return unless
- method = class_obj.method_list.find { |m| m.name == method_name }
- return unless call_seq = method.call_seq
-
- method_name = method_name[0, 1] if method_name =~ /\A\[/
-
- entries = call_seq.split "\n"
-
- matching = entries.select do |entry|
- entry =~ /^\w*\.?#{Regexp.escape method_name}/ or
- entry =~ /\s#{Regexp.escape method_name}\s/
- end
-
- method.call_seq = matching.join "\n"
- end
-
- ##
# Scans #content for rb_define_alias
def do_aliases
@@ -269,24 +227,30 @@ class RDoc::Parser::C < RDoc::Parser
end
class_obj = find_class var_name, class_name
-
- al = RDoc::Alias.new '', old_name, new_name, ''
- al.singleton = @singleton_classes.key? var_name
-
comment = find_alias_comment var_name, new_name, old_name
-
comment.normalize
-
- al.comment = comment
-
- al.record_location @top_level
-
- class_obj.add_alias al
- @stats.add_alias al
+ if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name}
+ comment = existing_method.comment
+ end
+ add_alias(var_name, class_obj, old_name, new_name, comment)
end
end
##
+ # Add alias, either from a direct alias definition, or from two
+ # method that reference the same function.
+
+ def add_alias(var_name, class_obj, old_name, new_name, comment)
+ al = RDoc::Alias.new '', old_name, new_name, ''
+ al.singleton = @singleton_classes.key? var_name
+ al.comment = comment
+ al.record_location @top_level
+ class_obj.add_alias al
+ @stats.add_alias al
+ al
+ end
+
+ ##
# Scans #content for rb_attr and rb_define_attr
def do_attrs
@@ -324,12 +288,100 @@ class RDoc::Parser::C < RDoc::Parser
# Scans #content for rb_define_class, boot_defclass, rb_define_class_under
# and rb_singleton_class
- def do_classes
- do_boot_defclass
- do_define_class
- do_define_class_under
- do_singleton_class
- do_struct_define_without_accessor
+ def do_classes_and_modules
+ do_boot_defclass if @file_name == "class.c"
+
+ @content.scan(
+ %r(
+ (?<var_name>[\w\.]+)\s* =
+ \s*rb_(?:
+ define_(?:
+ class(?: # rb_define_class(class_name_1, parent_name_1)
+ \s*\(
+ \s*"(?<class_name_1>\w+)",
+ \s*(?<parent_name_1>\w+)\s*
+ \)
+ |
+ _under\s*\( # rb_define_class_under(class_under, class_name2, parent_name2...)
+ \s* (?<class_under>\w+),
+ \s* "(?<class_name_2>\w+)",
+ \s*
+ (?:
+ (?<parent_name_2>[\w\*\s\(\)\.\->]+) |
+ rb_path2class\("(?<path>[\w:]+)"\)
+ )
+ \s*\)
+ )
+ |
+ module(?: # rb_define_module(module_name_1)
+ \s*\(
+ \s*"(?<module_name_1>\w+)"\s*
+ \)
+ |
+ _under\s*\( # rb_define_module_under(module_under, module_name_2)
+ \s*(?<module_under>\w+),
+ \s*"(?<module_name_2>\w+)"
+ \s*\)
+ )
+ )
+ |
+ struct_define_without_accessor\s*\( # rb_struct_define_without_accessor(class_name_3, parent_name_3, ...)
+ \s*"(?<class_name_3>\w+)",
+ \s*(?<parent_name_3>\w+),
+ \s*\w+, # Allocation function
+ (?:\s*"\w+",)* # Attributes
+ \s*NULL
+ \)
+ |
+ singleton_class\s*\( # rb_singleton_class(target_class_name)
+ \s*(?<target_class_name>\w+)
+ \)
+ )
+ )mx
+ ) do
+ class_name = $~[:class_name_1]
+ type = :class
+ if class_name
+ # rb_define_class(class_name_1, parent_name_1)
+ parent_name = $~[:parent_name_1]
+ #under = nil
+ else
+ class_name = $~[:class_name_2]
+ if class_name
+ # rb_define_class_under(class_under, class_name2, parent_name2...)
+ parent_name = $~[:parent_name_2] || $~[:path]
+ under = $~[:class_under]
+ else
+ class_name = $~[:class_name_3]
+ if class_name
+ # rb_struct_define_without_accessor(class_name_3, parent_name_3, ...)
+ parent_name = $~[:parent_name_3]
+ #under = nil
+ else
+ type = :module
+ class_name = $~[:module_name_1]
+ #parent_name = nil
+ if class_name
+ # rb_define_module(module_name_1)
+ #under = nil
+ else
+ class_name = $~[:module_name_2]
+ if class_name
+ # rb_define_module_under(module_under, module_name_1)
+ under = $~[:module_under]
+ else
+ # rb_singleton_class(target_class_name)
+ target_class_name = $~[:target_class_name]
+ handle_singleton $~[:var_name], target_class_name
+ next
+ end
+ end
+ end
+ end
+ end
+
+ handle_class_module($~[:var_name], type, class_name, parent_name, under)
+ end
end
##
@@ -378,65 +430,6 @@ class RDoc::Parser::C < RDoc::Parser
end
end
- ##
- # Scans #content for rb_define_class
-
- def do_define_class
- # The '.' lets us handle SWIG-generated files
- @content.scan(/([\w\.]+)\s* = \s*rb_define_class\s*
- \(
- \s*"(\w+)",
- \s*(\w+)\s*
- \)/mx) do |var_name, class_name, parent|
- handle_class_module(var_name, :class, class_name, parent, nil)
- end
- end
-
- ##
- # Scans #content for rb_define_class_under
-
- def do_define_class_under
- @content.scan(/([\w\.]+)\s* = # var_name
- \s*rb_define_class_under\s*
- \(
- \s* (\w+), # under
- \s* "(\w+)", # class_name
- \s*
- (?:
- ([\w\*\s\(\)\.\->]+) | # parent_name
- rb_path2class\("([\w:]+)"\) # path
- )
- \s*
- \)
- /mx) do |var_name, under, class_name, parent_name, path|
- parent = path || parent_name
-
- handle_class_module var_name, :class, class_name, parent, under
- end
- end
-
- ##
- # Scans #content for rb_define_module
-
- def do_define_module
- @content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
- |var_name, class_name|
- handle_class_module(var_name, :module, class_name, nil, nil)
- end
- end
-
- ##
- # Scans #content for rb_define_module_under
-
- def do_define_module_under
- @content.scan(/(\w+)\s* = \s*rb_define_module_under\s*
- \(
- \s*(\w+),
- \s*"(\w+)"
- \s*\)/mx) do |var_name, in_module, class_name|
- handle_class_module(var_name, :module, class_name, nil, in_module)
- end
- end
##
# Scans #content for rb_include_module
@@ -446,7 +439,7 @@ class RDoc::Parser::C < RDoc::Parser
next unless cls = @classes[c]
m = @known_classes[m] || m
- comment = RDoc::Comment.new '', @top_level
+ comment = RDoc::Comment.new '', @top_level, :c
incl = cls.add_include RDoc::Include.new(m, comment)
incl.record_location @top_level
end
@@ -519,42 +512,6 @@ class RDoc::Parser::C < RDoc::Parser
end
##
- # Scans #content for rb_define_module and rb_define_module_under
-
- def do_modules
- do_define_module
- do_define_module_under
- end
-
- ##
- # Scans #content for rb_singleton_class
-
- def do_singleton_class
- @content.scan(/([\w\.]+)\s* = \s*rb_singleton_class\s*
- \(
- \s*(\w+)
- \s*\)/mx) do |sclass_var, class_var|
- handle_singleton sclass_var, class_var
- end
- end
-
- ##
- # Scans #content for struct_define_without_accessor
-
- def do_struct_define_without_accessor
- @content.scan(/([\w\.]+)\s* = \s*rb_struct_define_without_accessor\s*
- \(
- \s*"(\w+)", # Class name
- \s*(\w+), # Parent class
- \s*\w+, # Allocation function
- (\s*"\w+",)* # Attributes
- \s*NULL
- \)/mx) do |var_name, class_name, parent|
- handle_class_module(var_name, :class, class_name, parent, nil)
- end
- end
-
- ##
# Finds the comment for an alias on +class_name+ from +new_name+ to
# +old_name+
@@ -564,7 +521,7 @@ class RDoc::Parser::C < RDoc::Parser
\s*"#{Regexp.escape new_name}"\s*,
\s*"#{Regexp.escape old_name}"\s*\);%xm
- RDoc::Comment.new($1 || '', @top_level)
+ RDoc::Comment.new($1 || '', @top_level, :c)
end
##
@@ -603,7 +560,7 @@ class RDoc::Parser::C < RDoc::Parser
''
end
- RDoc::Comment.new comment, @top_level
+ RDoc::Comment.new comment, @top_level, :c
end
##
@@ -615,7 +572,7 @@ class RDoc::Parser::C < RDoc::Parser
((?>/\*.*?\*/\s*)?)
((?:(?:\w+)\s+)?
(?:intern\s+)?VALUE\s+(\w+)
- \s*(?:\([^)]*\))(?:[^;]|$))
+ \s*(?:\([^)]*\))(?:[^\);]|$))
| ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+))
| ^\s*\#\s*define\s+(\w+)\s+(\w+)
}xm) do
@@ -643,7 +600,7 @@ class RDoc::Parser::C < RDoc::Parser
case type
when :func_def
- comment = RDoc::Comment.new args[0], @top_level
+ comment = RDoc::Comment.new args[0], @top_level, :c
body = args[1]
offset, = args[2]
@@ -673,7 +630,7 @@ class RDoc::Parser::C < RDoc::Parser
body
when :macro_def
- comment = RDoc::Comment.new args[0], @top_level
+ comment = RDoc::Comment.new args[0], @top_level, :c
body = args[1]
offset, = args[2]
@@ -780,7 +737,7 @@ class RDoc::Parser::C < RDoc::Parser
comment = ''
end
- comment = RDoc::Comment.new comment, @top_level
+ comment = RDoc::Comment.new comment, @top_level, :c
comment.normalize
look_for_directives_in class_mod, comment
@@ -825,7 +782,7 @@ class RDoc::Parser::C < RDoc::Parser
table[const_name] ||
''
- RDoc::Comment.new comment, @top_level
+ RDoc::Comment.new comment, @top_level, :c
end
##
@@ -856,7 +813,7 @@ class RDoc::Parser::C < RDoc::Parser
return unless comment
- RDoc::Comment.new comment, @top_level
+ RDoc::Comment.new comment, @top_level, :c
end
##
@@ -865,8 +822,8 @@ class RDoc::Parser::C < RDoc::Parser
def handle_attr(var_name, attr_name, read, write)
rw = ''
- rw << 'R' if '1' == read
- rw << 'W' if '1' == write
+ rw += 'R' if '1' == read
+ rw += 'W' if '1' == write
class_name = @known_classes[var_name]
@@ -952,7 +909,7 @@ class RDoc::Parser::C < RDoc::Parser
# can override the C value of the comment to give a friendly definition.
#
# /* 300: The perfect score in bowling */
- # rb_define_const(cFoo, "PERFECT", INT2FIX(300);
+ # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
#
# Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
# RDoc. Values may include quotes and escaped colons (\:).
@@ -982,15 +939,15 @@ class RDoc::Parser::C < RDoc::Parser
if new_definition.empty? then # Default to literal C definition
new_definition = definition
else
- new_definition.gsub!("\:", ":")
- new_definition.gsub!("\\", '\\')
+ new_definition = new_definition.gsub("\:", ":")
+ new_definition = new_definition.gsub("\\", '\\')
end
new_definition.sub!(/\A(\s+)/, '')
new_comment = "#{$1}#{new_comment.lstrip}"
- new_comment = RDoc::Comment.new new_comment, @top_level
+ new_comment = RDoc::Comment.new new_comment, @top_level, :c
con = RDoc::Constant.new const_name, new_definition, new_comment
else
@@ -1028,6 +985,10 @@ class RDoc::Parser::C < RDoc::Parser
class_obj = find_class var_name, class_name
+ if existing_method = class_obj.method_list.find { |m| m.c_function == function }
+ add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment)
+ end
+
if class_obj then
if meth_name == 'initialize' then
meth_name = 'new'
@@ -1237,7 +1198,7 @@ class RDoc::Parser::C < RDoc::Parser
# when scanning for classes and methods
def remove_commented_out_lines
- @content.gsub!(%r%//.*rb_define_%, '//')
+ @content = @content.gsub(%r%//.*rb_define_%, '//')
end
##
@@ -1247,8 +1208,7 @@ class RDoc::Parser::C < RDoc::Parser
def scan
remove_commented_out_lines
- do_modules
- do_classes
+ do_classes_and_modules
do_missing
do_constants
@@ -1257,12 +1217,9 @@ class RDoc::Parser::C < RDoc::Parser
do_aliases
do_attrs
- deduplicate_call_seq
-
@store.add_c_variables self
@top_level
end
end
-
diff --git a/lib/rdoc/parser/changelog.rb b/lib/rdoc/parser/changelog.rb
index c6c2d2bb23..9245d49376 100644
--- a/lib/rdoc/parser/changelog.rb
+++ b/lib/rdoc/parser/changelog.rb
@@ -1,5 +1,4 @@
-# frozen_string_literal: false
-require 'time'
+# frozen_string_literal: true
##
# A ChangeLog file parser.
@@ -29,13 +28,13 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
if last =~ /\)\s*\z/ and continuation =~ /\A\(/ then
last.sub!(/\)\s*\z/, ',')
- continuation.sub!(/\A\(/, '')
+ continuation = continuation.sub(/\A\(/, '')
end
if last =~ /\s\z/ then
last << continuation
else
- last << ' ' << continuation
+ last << ' ' + continuation
end
end
@@ -106,15 +105,33 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
entries.group_by do |title, _|
begin
time = @time_cache[title]
- (time || Time.parse(title)).strftime '%Y-%m-%d'
+ (time || parse_date(title)).strftime '%Y-%m-%d'
rescue NoMethodError, ArgumentError
time, = title.split ' ', 2
- Time.parse(time).strftime '%Y-%m-%d'
+ parse_date(time).strftime '%Y-%m-%d'
end
end
end
##
+ # Parse date in ISO-8601, RFC-2822, or default of Git
+
+ def parse_date(date)
+ case date
+ when /\A\s*(\d+)-(\d+)-(\d+)(?:[ T](\d+):(\d+):(\d+) *([-+]\d\d):?(\d\d))?\b/
+ Time.new($1, $2, $3, $4, $5, $6, ("#{$7}:#{$8}" if $7))
+ when /\A\s*\w{3}, +(\d+) (\w{3}) (\d+) (\d+):(\d+):(\d+) *(?:([-+]\d\d):?(\d\d))\b/
+ Time.new($3, $2, $1, $4, $5, $6, ("#{$7}:#{$8}" if $7))
+ when /\A\s*\w{3} (\w{3}) +(\d+) (\d+) (\d+):(\d+):(\d+) *(?:([-+]\d\d):?(\d\d))\b/
+ Time.new($3, $1, $2, $4, $5, $6, ("#{$7}:#{$8}" if $7))
+ when /\A\s*\w{3} (\w{3}) +(\d+) (\d+):(\d+):(\d+) (\d+)\b/
+ Time.new($6, $1, $2, $3, $4, $5)
+ else
+ raise ArgumentError, "bad date: #{date}"
+ end
+ end
+
+ ##
# Parses the entries in the ChangeLog.
#
# Returns an Array of each ChangeLog entry in order of parsing.
@@ -131,6 +148,13 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
def parse_entries
@time_cache ||= {}
+
+ if /\A((?:.*\n){,3})commit\s/ =~ @content
+ class << self; prepend Git; end
+ parse_info($1)
+ return parse_entries
+ end
+
entries = []
entry_name = nil
entry_body = []
@@ -145,29 +169,20 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
entry_name = $&
begin
- time = Time.parse entry_name
+ time = parse_date entry_name
@time_cache[entry_name] = time
- # HACK Ruby 1.8 does not raise ArgumentError for Time.parse "Other"
- entry_name = nil unless entry_name =~ /#{time.year}/
- rescue NoMethodError
- # HACK Ruby 2.1.2 and earlier raises NoMethodError if time part is absent
- entry_name.split ' ', 2
rescue ArgumentError
- if /out of range/ =~ $!.message
- Time.parse(entry_name.split(' ', 2)[0]) rescue entry_name = nil
- else
- entry_name = nil
- end
+ entry_name = nil
end
entry_body = []
when /^(\t| {8})?\*\s*(.*)/ then # "\t* file.c (func): ..."
- entry_body << $2
+ entry_body << $2.dup
when /^(\t| {8})?\s*(\(.*)/ then # "\t(func): ..."
entry = $2
if entry_body.last =~ /:/ then
- entry_body << entry
+ entry_body << entry.dup
else
continue_entry_body entry_body, entry
end
@@ -190,6 +205,7 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
def scan
@time_cache = {}
+
entries = parse_entries
grouped_entries = group_entries entries
@@ -200,5 +216,120 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
@top_level
end
+ module Git
+ def parse_info(info)
+ /^\s*base-url\s*=\s*(.*\S)/ =~ info
+ @base_url = $1
+ end
+
+ def parse_entries
+ entries = []
+
+ @content.scan(/^commit\s+(\h{20})\h*\n((?:.+\n)*)\n((?: {4}.*\n+)*)/) do
+ entry_name, header, entry_body = $1, $2, $3.gsub(/^ {4}/, '')
+ # header = header.scan(/^ *(\S+?): +(.*)/).to_h
+ # date = header["CommitDate"] || header["Date"]
+ date = header[/^ *(?:Author)?Date: +(.*)/, 1]
+ author = header[/^ *Author: +(.*)/, 1]
+ begin
+ time = parse_date(header[/^ *CommitDate: +(.*)/, 1] || date)
+ @time_cache[entry_name] = time
+ author.sub!(/\s*<(.*)>/, '')
+ email = $1
+ entries << [entry_name, [author, email, date, entry_body]]
+ rescue ArgumentError
+ end
+ end
+
+ entries
+ end
+
+ def create_entries entries
+ # git log entries have no strictly itemized style like the old
+ # style, just assume Markdown.
+ entries.map do |commit, entry|
+ LogEntry.new(@base_url, commit, *entry)
+ end
+ end
+
+ LogEntry = Struct.new(:base, :commit, :author, :email, :date, :contents) do
+ HEADING_LEVEL = 3
+
+ def initialize(base, commit, author, email, date, contents)
+ case contents
+ when String
+ contents = RDoc::Markdown.parse(contents).parts.each do |body|
+ case body
+ when RDoc::Markup::Heading
+ body.level += HEADING_LEVEL + 1
+ end
+ end
+ case first = contents[0]
+ when RDoc::Markup::Paragraph
+ contents[0] = RDoc::Markup::Heading.new(HEADING_LEVEL + 1, first.text)
+ end
+ end
+ super
+ end
+
+ def level
+ HEADING_LEVEL
+ end
+
+ def aref
+ "label-#{commit}"
+ end
+
+ def label context = nil
+ aref
+ end
+
+ def text
+ case base
+ when nil
+ "#{date}"
+ when /%s/
+ "{#{date}}[#{base % commit}]"
+ else
+ "{#{date}}[#{base}#{commit}]"
+ end + " {#{author}}[mailto:#{email}]"
+ end
+
+ def accept visitor
+ visitor.accept_heading self
+ begin
+ if visitor.respond_to?(:code_object=)
+ code_object = visitor.code_object
+ visitor.code_object = self
+ end
+ contents.each do |body|
+ body.accept visitor
+ end
+ ensure
+ if visitor.respond_to?(:code_object)
+ visitor.code_object = code_object
+ end
+ end
+ end
+
+ def pretty_print q # :nodoc:
+ q.group(2, '[log_entry: ', ']') do
+ q.text commit
+ q.text ','
+ q.breakable
+ q.group(2, '[date: ', ']') { q.text date }
+ q.text ','
+ q.breakable
+ q.group(2, '[author: ', ']') { q.text author }
+ q.text ','
+ q.breakable
+ q.group(2, '[email: ', ']') { q.text email }
+ q.text ','
+ q.breakable
+ q.pp contents
+ end
+ end
+ end
+ end
end
diff --git a/lib/rdoc/parser/markdown.rb b/lib/rdoc/parser/markdown.rb
index feffb26ced..9ff478f872 100644
--- a/lib/rdoc/parser/markdown.rb
+++ b/lib/rdoc/parser/markdown.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Parse a Markdown format file. The parsed RDoc::Markup::Document is attached
# as a file comment.
diff --git a/lib/rdoc/parser/rd.rb b/lib/rdoc/parser/rd.rb
index e6693b9ac8..25f5711731 100644
--- a/lib/rdoc/parser/rd.rb
+++ b/lib/rdoc/parser/rd.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Parse a RD format file. The parsed RDoc::Markup::Document is attached as a
# file comment.
diff --git a/lib/rdoc/parser/ripper_state_lex.rb b/lib/rdoc/parser/ripper_state_lex.rb
index c9a0f5a21e..5492f08726 100644
--- a/lib/rdoc/parser/ripper_state_lex.rb
+++ b/lib/rdoc/parser/ripper_state_lex.rb
@@ -1,6 +1,12 @@
+# frozen_string_literal: true
require 'ripper'
-class RDoc::RipperStateLex
+class RDoc::Parser::RipperStateLex
+ # TODO: Remove this constants after Ruby 2.4 EOL
+ RIPPER_HAS_LEX_STATE = Ripper::Filter.method_defined?(:state)
+
+ Token = Struct.new(:line_no, :char_no, :kind, :text, :state)
+
EXPR_NONE = 0
EXPR_BEG = 1
EXPR_END = 2
@@ -44,7 +50,7 @@ class RDoc::RipperStateLex
@continue = false
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
end
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_ignored_nl(tok, data)
@@ -55,7 +61,7 @@ class RDoc::RipperStateLex
@continue = false
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
end
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_op(tok, data)
@@ -80,6 +86,15 @@ class RDoc::RipperStateLex
when '&&', '||', '+=', '-=', '*=', '**=',
'&=', '|=', '^=', '<<=', '>>=', '||=', '&&='
@lex_state = EXPR_BEG
+ when '::'
+ case @lex_state
+ when EXPR_ARG, EXPR_CMDARG
+ @lex_state = EXPR_DOT
+ when EXPR_FNAME, EXPR_DOT
+ @lex_state = EXPR_ARG
+ else
+ @lex_state = EXPR_BEG
+ end
else
case @lex_state
when EXPR_FNAME, EXPR_DOT
@@ -88,7 +103,7 @@ class RDoc::RipperStateLex
@lex_state = EXPR_BEG
end
end
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_kw(tok, data)
@@ -101,13 +116,15 @@ class RDoc::RipperStateLex
@continue = true
@in_fname = true
when 'if', 'unless', 'while', 'until'
- if ((EXPR_END | EXPR_ENDARG | EXPR_ENDFN | EXPR_ARG | EXPR_CMDARG) & @lex_state) != 0 # postfix if
+ if ((EXPR_MID | EXPR_END | EXPR_ENDARG | EXPR_ENDFN | EXPR_ARG | EXPR_CMDARG) & @lex_state) != 0 # postfix if
@lex_state = EXPR_BEG | EXPR_LABEL
else
@lex_state = EXPR_BEG
end
- when 'begin'
+ when 'begin', 'case', 'when'
@lex_state = EXPR_BEG
+ when 'return', 'break'
+ @lex_state = EXPR_MID
else
if @lex_state == EXPR_FNAME
@lex_state = EXPR_END
@@ -115,54 +132,54 @@ class RDoc::RipperStateLex
@lex_state = EXPR_END
end
end
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_tstring_beg(tok, data)
@lex_state = EXPR_BEG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_tstring_end(tok, data)
@lex_state = EXPR_END | EXPR_ENDARG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_CHAR(tok, data)
@lex_state = EXPR_END
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_period(tok, data)
@lex_state = EXPR_DOT
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_int(tok, data)
@lex_state = EXPR_END | EXPR_ENDARG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_float(tok, data)
@lex_state = EXPR_END | EXPR_ENDARG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_rational(tok, data)
@lex_state = EXPR_END | EXPR_ENDARG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_imaginary(tok, data)
@lex_state = EXPR_END | EXPR_ENDARG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_symbeg(tok, data)
@lex_state = EXPR_FNAME
@continue = true
@in_fname = true
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
private def on_variables(event, tok, data)
@@ -181,7 +198,7 @@ class RDoc::RipperStateLex
else
@lex_state = EXPR_CMDARG
end
- @callback.call({ :line_no => lineno, :char_no => column, :kind => event, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, event, tok, @lex_state)
end
def on_ident(tok, data)
@@ -210,97 +227,110 @@ class RDoc::RipperStateLex
def on_lparen(tok, data)
@lex_state = EXPR_LABEL | EXPR_BEG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_rparen(tok, data)
@lex_state = EXPR_ENDFN
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_lbrace(tok, data)
@lex_state = EXPR_LABEL | EXPR_BEG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_rbrace(tok, data)
@lex_state = EXPR_ENDARG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_lbracket(tok, data)
@lex_state = EXPR_LABEL | EXPR_BEG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_rbracket(tok, data)
@lex_state = EXPR_ENDARG
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_const(tok, data)
case @lex_state
when EXPR_FNAME
@lex_state = EXPR_ENDFN
- when EXPR_CLASS
+ when EXPR_CLASS, EXPR_CMDARG, EXPR_MID
@lex_state = EXPR_ARG
else
@lex_state = EXPR_CMDARG
end
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_sp(tok, data)
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_comma(tok, data)
@lex_state = EXPR_BEG | EXPR_LABEL if (EXPR_ARG_ANY & @lex_state) != 0
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_comment(tok, data)
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
end
def on_ignored_sp(tok, data)
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
+ end
+
+ def on_heredoc_beg(tok, data)
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
+ @lex_state = EXPR_END
+ data
end
def on_heredoc_end(tok, data)
- @callback.call({ :line_no => lineno, :char_no => column, :kind => __method__, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, __method__, tok, @lex_state)
@lex_state = EXPR_BEG
+ data
end
def on_default(event, tok, data)
reset
- @callback.call({ :line_no => lineno, :char_no => column, :kind => event, :text => tok, :state => @lex_state})
+ data << Token.new(lineno, column, event, tok, @lex_state)
end
+ end unless RIPPER_HAS_LEX_STATE
- def each(&block)
- @callback = block
- parse
+ class InnerStateLex < Ripper::Filter
+ def initialize(code)
+ super(code)
end
- end
+
+ def on_default(event, tok, data)
+ data << Token.new(lineno, column, event, tok, state)
+ end
+ end if RIPPER_HAS_LEX_STATE
def get_squashed_tk
if @buf.empty?
- tk = @inner_lex_enumerator.next
+ tk = @tokens.shift
else
tk = @buf.shift
end
+ return nil if tk.nil?
case tk[:kind]
when :on_symbeg then
tk = get_symbol_tk(tk)
when :on_tstring_beg then
tk = get_string_tk(tk)
when :on_backtick then
- if (EXPR_FNAME & tk[:state]) != 0
- @inner_lex.lex_state = EXPR_ARG
+ if (tk[:state] & (EXPR_FNAME | EXPR_ENDFN)) != 0
+ @inner_lex.lex_state = EXPR_ARG unless RIPPER_HAS_LEX_STATE
tk[:kind] = :on_ident
- tk[:state] = @inner_lex.lex_state
+ tk[:state] = Ripper::Lexer.const_defined?(:State) ? Ripper::Lexer::State.new(EXPR_ARG) : EXPR_ARG
else
tk = get_string_tk(tk)
end
@@ -310,10 +340,12 @@ class RDoc::RipperStateLex
tk = get_embdoc_tk(tk)
when :on_heredoc_beg then
@heredoc_queue << retrieve_heredoc_info(tk)
- @inner_lex.lex_state = EXPR_END
+ @inner_lex.lex_state = EXPR_END unless RIPPER_HAS_LEX_STATE
when :on_nl, :on_ignored_nl, :on_comment, :on_heredoc_end then
- unless @heredoc_queue.empty?
+ if !@heredoc_queue.empty?
get_heredoc_tk(*@heredoc_queue.shift)
+ elsif tk[:text].nil? # :on_ignored_nl sometimes gives nil
+ tk[:text] = ''
end
when :on_words_beg then
tk = get_words_tk(tk)
@@ -335,7 +367,7 @@ class RDoc::RipperStateLex
private def get_symbol_tk(tk)
is_symbol = true
- symbol_tk = { :line_no => tk[:line_no], :char_no => tk[:char_no], :kind => :on_symbol }
+ symbol_tk = Token.new(tk.line_no, tk.char_no, :on_symbol)
if ":'" == tk[:text] or ':"' == tk[:text]
tk1 = get_string_tk(tk)
symbol_tk[:text] = tk1[:text]
@@ -404,13 +436,7 @@ class RDoc::RipperStateLex
end
end
end
- {
- :line_no => tk[:line_no],
- :char_no => tk[:char_no],
- :kind => kind,
- :text => string,
- :state => state
- }
+ Token.new(tk.line_no, tk.char_no, kind, string, state)
end
private def get_regexp_tk(tk)
@@ -428,13 +454,7 @@ class RDoc::RipperStateLex
string = string + inner_str_tk[:text]
end
end
- {
- :line_no => tk[:line_no],
- :char_no => tk[:char_no],
- :kind => :on_regexp,
- :text => string,
- :state => state
- }
+ Token.new(tk.line_no, tk.char_no, :on_regexp, string, state)
end
private def get_embdoc_tk(tk)
@@ -443,20 +463,14 @@ class RDoc::RipperStateLex
string = string + embdoc_tk[:text]
end
string = string + embdoc_tk[:text]
- {
- :line_no => tk[:line_no],
- :char_no => tk[:char_no],
- :kind => :on_embdoc,
- :text => string,
- :state => embdoc_tk[:state]
- }
+ Token.new(tk.line_no, tk.char_no, :on_embdoc, string, embdoc_tk.state)
end
private def get_heredoc_tk(heredoc_name, indent)
string = ''
start_tk = nil
prev_tk = nil
- until heredoc_end?(heredoc_name, indent, tk = @inner_lex_enumerator.next) do
+ until heredoc_end?(heredoc_name, indent, tk = @tokens.shift) do
start_tk = tk unless start_tk
if (prev_tk.nil? or "\n" == prev_tk[:text][-1]) and 0 != tk[:char_no]
string = string + (' ' * tk[:char_no])
@@ -467,13 +481,7 @@ class RDoc::RipperStateLex
start_tk = tk unless start_tk
prev_tk = tk unless prev_tk
@buf.unshift tk # closing heredoc
- heredoc_tk = {
- :line_no => start_tk[:line_no],
- :char_no => start_tk[:char_no],
- :kind => :on_heredoc,
- :text => string,
- :state => prev_tk[:state]
- }
+ heredoc_tk = Token.new(start_tk.line_no, start_tk.char_no, :on_heredoc, string, prev_tk.state)
@buf.unshift heredoc_tk
end
@@ -486,7 +494,8 @@ class RDoc::RipperStateLex
private def heredoc_end?(name, indent, tk)
result = false
if :on_heredoc_end == tk[:kind] then
- tk_name = (indent ? tk[:text].gsub(/^ *(.+)\n?$/, '\1') : tk[:text].gsub(/\n\z/, ''))
+ tk_name = tk[:text].chomp
+ tk_name.lstrip! if indent
if name == tk_name
result = true
end
@@ -529,21 +538,15 @@ class RDoc::RipperStateLex
end
end
text = "#{start_token}#{string}#{end_token}"
- {
- :line_no => line_no,
- :char_no => char_no,
- :kind => :on_dstring,
- :text => text,
- :state => state
- }
+ Token.new(line_no, char_no, :on_dstring, text, state)
end
private def get_op_tk(tk)
redefinable_operators = %w[! != !~ % & * ** + +@ - -@ / < << <= <=> == === =~ > >= >> [] []= ^ ` | ~]
- if redefinable_operators.include?(tk[:text]) and EXPR_ARG == tk[:state] then
- @inner_lex.lex_state = EXPR_ARG
+ if redefinable_operators.include?(tk[:text]) and tk[:state] == EXPR_ARG then
+ @inner_lex.lex_state = EXPR_ARG unless RIPPER_HAS_LEX_STATE
+ tk[:state] = Ripper::Lexer.const_defined?(:State) ? Ripper::Lexer::State.new(EXPR_ARG) : EXPR_ARG
tk[:kind] = :on_ident
- tk[:state] = @inner_lex.lex_state
elsif tk[:text] =~ /^[-+]$/ then
tk_ahead = get_squashed_tk
case tk_ahead[:kind]
@@ -551,6 +554,10 @@ class RDoc::RipperStateLex
tk[:text] += tk_ahead[:text]
tk[:kind] = tk_ahead[:kind]
tk[:state] = tk_ahead[:state]
+ when :on_heredoc_beg, :on_tstring, :on_dstring # frozen/non-frozen string literal
+ tk[:text] += tk_ahead[:text]
+ tk[:kind] = tk_ahead[:kind]
+ tk[:state] = tk_ahead[:state]
else
@buf.unshift tk_ahead
end
@@ -562,11 +569,7 @@ class RDoc::RipperStateLex
@buf = []
@heredoc_queue = []
@inner_lex = InnerStateLex.new(code)
- @inner_lex_enumerator = Enumerator.new do |y|
- @inner_lex.each do |tk|
- y << tk
- end
- end
+ @tokens = @inner_lex.parse([])
end
def self.parse(code)
diff --git a/lib/rdoc/parser/ruby.rb b/lib/rdoc/parser/ruby.rb
index c81f152b56..8d021f3c6d 100644
--- a/lib/rdoc/parser/ruby.rb
+++ b/lib/rdoc/parser/ruby.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# This file contains stuff stolen outright from:
#
@@ -8,8 +8,6 @@
# by Keiju ISHITSUKA (Nippon Rational Inc.)
#
-$TOKEN_DEBUG ||= nil
-
##
# Extracts code elements from a source file returning a TopLevel object
# containing the constituent file elements.
@@ -141,6 +139,7 @@ $TOKEN_DEBUG ||= nil
# standard rdocable item following it.
require 'ripper'
+require_relative 'ripper_state_lex'
class RDoc::Parser::Ruby < RDoc::Parser
@@ -177,7 +176,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
@size = 0
@token_listeners = nil
- @scanner = RDoc::RipperStateLex.parse(content)
+ content = RDoc::Encoding.remove_magic_comment content
+ @scanner = RDoc::Parser::RipperStateLex.parse(content)
+ @content = content
@scanner_point = 0
@prev_seek = nil
@markup = @options.markup
@@ -239,18 +240,20 @@ class RDoc::Parser::Ruby < RDoc::Parser
def collect_first_comment
skip_tkspace
- comment = ''
- comment.force_encoding @encoding if @encoding
+ comment = ''.dup
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
first_line = true
first_comment_tk_kind = nil
+ line_no = nil
tk = get_tk
while tk && (:on_comment == tk[:kind] or :on_embdoc == tk[:kind])
- if first_line and tk[:text] =~ /\A#!/ then
+ comment_body = retrieve_comment_body(tk)
+ if first_line and comment_body =~ /\A#!/ then
skip_tkspace
tk = get_tk
- elsif first_line and tk[:text] =~ /\A#\s*-\*-/ then
+ elsif first_line and comment_body =~ /\A#\s*-\*-/ then
first_line = false
skip_tkspace
tk = get_tk
@@ -258,12 +261,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
break if first_comment_tk_kind and not first_comment_tk_kind === tk[:kind]
first_comment_tk_kind = tk[:kind]
+ line_no = tk[:line_no] if first_line
first_line = false
- comment << tk[:text]
+ comment << comment_body
tk = get_tk
if :on_nl === tk then
- skip_tkspace false
+ skip_tkspace_without_nl
tk = get_tk
end
end
@@ -271,14 +275,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
unget_tk tk
- new_comment comment
+ new_comment comment, line_no
end
##
# Consumes trailing whitespace from the token stream
def consume_trailing_spaces # :nodoc:
- skip_tkspace false
+ skip_tkspace_without_nl
end
##
@@ -305,7 +309,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
container.find_module_named rhs_name
end
- container.add_module_alias mod, constant.name, @top_level if mod
+ container.add_module_alias mod, rhs_name, constant, @top_level
end
##
@@ -318,8 +322,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
##
- # Looks for a true or false token. Returns false if TkFALSE or TkNIL are
- # found.
+ # Looks for a true or false token.
def get_bool
skip_tkspace
@@ -342,7 +345,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
def get_class_or_module container, ignore_constants = false
skip_tkspace
name_t = get_tk
- given_name = ''
+ given_name = ''.dup
# class ::A -> A is in the top level
if :on_op == name_t[:kind] and '::' == name_t[:text] then # bug
@@ -351,16 +354,20 @@ class RDoc::Parser::Ruby < RDoc::Parser
given_name << '::'
end
- skip_tkspace false
+ skip_tkspace_without_nl
given_name << name_t[:text]
is_self = name_t[:kind] == :on_op && name_t[:text] == '<<'
+ new_modules = []
while !is_self && (tk = peek_tk) and :on_op == tk[:kind] and '::' == tk[:text] do
prev_container = container
container = container.find_module_named name_t[:text]
container ||=
if ignore_constants then
- RDoc::Context.new
+ c = RDoc::NormalModule.new name_t[:text]
+ c.store = @store
+ new_modules << [prev_container, c]
+ c
else
c = prev_container.add_module RDoc::NormalModule, name_t[:text]
c.ignore unless prev_container.document_children
@@ -371,7 +378,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
record_location container
get_tk
- skip_tkspace false
+ skip_tkspace
+ if :on_lparen == peek_tk[:kind] # ProcObjectInConstant::()
+ parse_method_or_yield_parameters
+ break
+ end
name_t = get_tk
unless :on_const == name_t[:kind] || :on_ident == name_t[:kind]
raise RDoc::Error, "Invalid class or module definition: #{given_name}"
@@ -379,13 +390,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
if prev_container == container and !ignore_constants
given_name = name_t[:text]
else
- given_name << '::' << name_t[:text]
+ given_name << '::' + name_t[:text]
end
end
- skip_tkspace false
+ skip_tkspace_without_nl
- return [container, name_t, given_name]
+ return [container, name_t, given_name, new_modules]
end
##
@@ -403,7 +414,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
res = get_constant
- skip_tkspace false
+ skip_tkspace_without_nl
get_tkread # empty out read buffer
@@ -426,7 +437,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
def get_constant
res = ""
- skip_tkspace false
+ skip_tkspace_without_nl
tk = get_tk
while tk && ((:on_op == tk[:kind] && '::' == tk[:text]) || :on_const == tk[:kind]) do
@@ -439,28 +450,83 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
##
- # Get a constant that may be surrounded by parens
+ # Get an included module that may be surrounded by parens
- def get_constant_with_optional_parens
- skip_tkspace false
+ def get_included_module_with_optional_parens
+ skip_tkspace_without_nl
+ get_tkread
+ tk = get_tk
+ end_token = get_end_token tk
+ return '' unless end_token
nest = 0
+ continue = false
+ only_constant = true
- while :on_lparen == (tk = peek_tk)[:kind] do
- get_tk
- skip_tkspace
- nest += 1
- end
-
- name = get_constant
-
- while nest > 0
- skip_tkspace
+ while tk != nil do
+ is_element_of_constant = false
+ case tk[:kind]
+ when :on_semicolon then
+ break if nest == 0
+ when :on_lbracket then
+ nest += 1
+ when :on_rbracket then
+ nest -= 1
+ when :on_lbrace then
+ nest += 1
+ when :on_rbrace then
+ nest -= 1
+ if nest <= 0
+ # we might have a.each { |i| yield i }
+ unget_tk(tk) if nest < 0
+ break
+ end
+ when :on_lparen then
+ nest += 1
+ when end_token[:kind] then
+ if end_token[:kind] == :on_rparen
+ nest -= 1
+ break if nest <= 0
+ else
+ break if nest <= 0
+ end
+ when :on_rparen then
+ nest -= 1
+ when :on_comment, :on_embdoc then
+ @read.pop
+ if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and
+ (!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then
+ break if !continue and nest <= 0
+ end
+ when :on_comma then
+ continue = true
+ when :on_ident then
+ continue = false if continue
+ when :on_kw then
+ case tk[:text]
+ when 'def', 'do', 'case', 'for', 'begin', 'class', 'module'
+ nest += 1
+ when 'if', 'unless', 'while', 'until', 'rescue'
+ # postfix if/unless/while/until/rescue must be EXPR_LABEL
+ nest += 1 unless (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0
+ when 'end'
+ nest -= 1
+ break if nest == 0
+ end
+ when :on_const then
+ is_element_of_constant = true
+ when :on_op then
+ is_element_of_constant = true if '::' == tk[:text]
+ end
+ only_constant = false unless is_element_of_constant
tk = get_tk
- nest -= 1 if :on_rparen == tk[:kind]
end
- name
+ if only_constant
+ get_tkread_clean(/\s+/, ' ')
+ else
+ ''
+ end
end
##
@@ -474,17 +540,17 @@ class RDoc::Parser::Ruby < RDoc::Parser
def get_end_token tk # :nodoc:
case tk[:kind]
when :on_lparen
- {
- :kind => :on_rparen,
- :text => ')'
- }
+ token = RDoc::Parser::RipperStateLex::Token.new
+ token[:kind] = :on_rparen
+ token[:text] = ')'
+ token
when :on_rparen
nil
else
- {
- :kind => :on_nl,
- :text => "\n"
- }
+ token = RDoc::Parser::RipperStateLex::Token.new
+ token[:kind] = :on_nl
+ token[:text] = "\n"
+ token
end
end
@@ -574,27 +640,28 @@ class RDoc::Parser::Ruby < RDoc::Parser
#
# This routine modifies its +comment+ parameter.
- def look_for_directives_in context, comment
- @preprocess.handle comment, context do |directive, param|
+ def look_for_directives_in container, comment
+ @preprocess.handle comment, container do |directive, param|
case directive
when 'method', 'singleton-method',
'attr', 'attr_accessor', 'attr_reader', 'attr_writer' then
false # handled elsewhere
when 'section' then
- context.set_current_section param, comment.dup
+ break unless container.kind_of?(RDoc::Context)
+ container.set_current_section param, comment.dup
comment.text = ''
break
end
end
- remove_private_comments comment
+ comment.remove_private
end
##
# Adds useful info about the parser to +message+
def make_message message
- prefix = "#{@file_name}:"
+ prefix = "#{@file_name}:".dup
tk = peek_tk
prefix << "#{tk[:line_no]}:#{tk[:char_no]}:" if tk
@@ -605,8 +672,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
##
# Creates a comment with the correct format
- def new_comment comment
- c = RDoc::Comment.new comment, @top_level
+ def new_comment comment, line_no = nil
+ c = RDoc::Comment.new comment, @top_level, :ruby
+ c.line = line_no
c.format = @markup
c
end
@@ -622,7 +690,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
if args.size > 0 then
name = args[0]
rw = "R"
- skip_tkspace false
+ skip_tkspace_without_nl
tk = get_tk
if :on_comma == tk[:kind] then
@@ -733,9 +801,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
when end_token
if end_token == :on_rparen
nest -= 1
- break if RDoc::RipperStateLex.end?(tk) and nest <= 0
+ break if RDoc::Parser::RipperStateLex.end?(tk) and nest <= 0
else
- break if RDoc::RipperStateLex.end?(tk)
+ break if RDoc::Parser::RipperStateLex.end?(tk)
end
when :on_comment, :on_embdoc
unget_tk(tk)
@@ -759,7 +827,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
line_no = tk[:line_no]
declaration_context = container
- container, name_t, given_name = get_class_or_module container
+ container, name_t, given_name, = get_class_or_module container
if name_t[:kind] == :on_const
cls = parse_class_regular container, declaration_context, single,
@@ -872,14 +940,15 @@ class RDoc::Parser::Ruby < RDoc::Parser
line_no = tk[:line_no]
name = tk[:text]
- skip_tkspace false
+ skip_tkspace_without_nl
return unless name =~ /^\w+$/
+ new_modules = []
if :on_op == peek_tk[:kind] && '::' == peek_tk[:text] then
unget_tk tk
- container, name_t, = get_class_or_module container, ignore_constants
+ container, name_t, _, new_modules = get_class_or_module container, true
name = name_t[:text]
end
@@ -897,7 +966,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
break if nest == 0
end
end
- skip_tkspace false
+ skip_tkspace_without_nl
is_array_or_hash = true
end
@@ -906,6 +975,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
get_tk
+ unless ignore_constants
+ new_modules.each do |prev_c, new_module|
+ prev_c.add_module_by_normal_module new_module
+ new_module.ignore unless prev_c.document_children
+ @top_level.add_to_classes_or_modules new_module
+ end
+ end
+
value = ''
con = RDoc::Constant.new name, value, comment
@@ -913,7 +990,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
return unless body
- value.replace body
+ con.value = body
record_location con
con.line = line_no
read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
@@ -928,7 +1005,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
def parse_constant_body container, constant, is_array_or_hash # :nodoc:
nest = 0
- rhs_name = ''
+ rhs_name = ''.dup
get_tkread
@@ -944,7 +1021,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
elsif (:on_kw == tk[:kind] && 'def' == tk[:text]) then
nest += 1
elsif (:on_kw == tk[:kind] && %w{do if unless case begin}.include?(tk[:text])) then
- if (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) == 0
+ if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
nest += 1
end
elsif [:on_rparen, :on_rbrace, :on_rbracket].include?(tk[:kind]) ||
@@ -952,7 +1029,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
nest -= 1
elsif (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then
unget_tk tk
- if nest <= 0 and RDoc::RipperStateLex.end?(tk) then
+ if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then
body = get_tkread_clean(/^[ \t]+/, '')
read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS
break
@@ -968,7 +1045,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
break
end
elsif :on_nl == tk[:kind] then
- if nest <= 0 and RDoc::RipperStateLex.end?(tk) then
+ if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then
unget_tk tk
break
end
@@ -988,16 +1065,16 @@ class RDoc::Parser::Ruby < RDoc::Parser
def parse_comment container, tk, comment
return parse_comment_tomdoc container, tk, comment if @markup == 'tomdoc'
column = tk[:char_no]
- line_no = tk[:line_no]
-
- text = comment.text
+ line_no = comment.line.nil? ? tk[:line_no] : comment.line
- singleton = !!text.sub!(/(^# +:?)(singleton-)(method:)/, '\1\3')
+ comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3')
+ singleton = !!$~
co =
- if text.sub!(/^# +:?method: *(\S*).*?\n/i, '') then
- parse_comment_ghost container, text, $1, column, line_no, comment
- elsif text.sub!(/# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '') then
+ if (comment.text = comment.text.sub(/^# +:?method: *(\S*).*?\n/i, '')) && !!$~ then
+ line_no += $`.count("\n")
+ parse_comment_ghost container, comment.text, $1, column, line_no, comment
+ elsif (comment.text = comment.text.sub(/# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '')) && !!$~ then
parse_comment_attr container, $1, $3, comment
end
@@ -1033,10 +1110,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
record_location meth
meth.start_collecting_tokens
- indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
- position_comment = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
+ position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
- newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
meth.add_tokens [position_comment, newline, indent]
meth.params =
@@ -1076,10 +1153,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
meth.line = line_no
meth.start_collecting_tokens
- indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
- position_comment = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
+ position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
- newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
meth.add_tokens [position_comment, newline, indent]
meth.call_seq = signature
@@ -1103,7 +1180,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
loop do
skip_tkspace_comment
- name = get_constant_with_optional_parens
+ name = get_included_module_with_optional_parens
unless name.empty? then
obj = container.add klass, name, comment
@@ -1194,7 +1271,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
tmp = RDoc::CodeObject.new
read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS
- if comment.text.sub!(/^# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '') then
+ regexp = /^# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i
+ if regexp =~ comment.text then
+ comment.text = comment.text.sub(regexp, '')
rw = case $1
when 'attr_reader' then 'R'
when 'attr_writer' then 'W'
@@ -1225,9 +1304,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
add_token tk
add_token_listener self
- skip_tkspace false
+ skip_tkspace_without_nl
- singleton = !!comment.text.sub!(/(^# +:?)(singleton-)(method:)/, '\1\3')
+ comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3')
+ singleton = !!$~
name = parse_meta_method_name comment, tk
@@ -1241,10 +1321,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
remove_token_listener self
meth.start_collecting_tokens
- indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
- position_comment = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
+ position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
- newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
meth.add_tokens [position_comment, newline, indent]
meth.add_tokens @token_stream
@@ -1290,6 +1370,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
token_listener meth do
meth.params = ''
+ look_for_directives_in meth, comment
comment.normalize
comment.extract_call_seq meth
@@ -1336,16 +1417,17 @@ class RDoc::Parser::Ruby < RDoc::Parser
return unless name
meth = RDoc::AnyMethod.new get_tkread, name
+ look_for_directives_in meth, comment
meth.singleton = single == SINGLE ? true : singleton
record_location meth
meth.line = line_no
meth.start_collecting_tokens
- indent = { :line_no => 1, :char_no => 1, :kind => :on_sp, :text => ' ' * column }
- token = { :line_no => line_no, :char_no => 1, :kind => :on_comment }
+ indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
+ token = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
token[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
- newline = { :line_no => 0, :char_no => 0, :kind => :on_nl, :text => "\n" }
+ newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
meth.add_tokens [token, newline, indent]
meth.add_tokens @token_stream
@@ -1411,7 +1493,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
def parse_method_name container # :nodoc:
skip_tkspace
name_t = get_tk
- back_tk = skip_tkspace(false)
+ back_tk = skip_tkspace_without_nl
singleton = false
dot = get_tk
@@ -1458,8 +1540,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
name_t2 = get_tk
if (:on_kw == name_t[:kind] && 'self' == name_t[:text]) || (:on_op == name_t[:kind] && '%' == name_t[:text]) then
- # NOTE: work around '[' being consumed early and not being re-tokenized
- # as a TkAREF
+ # NOTE: work around '[' being consumed early
if :on_lbracket == name_t2[:kind]
get_tk
name = '[]'
@@ -1500,7 +1581,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
def parse_method_or_yield_parameters(method = nil,
modifiers = RDoc::METHOD_MODIFIERS)
- skip_tkspace false
+ skip_tkspace_without_nl
tk = get_tk
end_token = get_end_token tk
return '' unless end_token
@@ -1512,6 +1593,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
case tk[:kind]
when :on_semicolon then
break if nest == 0
+ when :on_lbracket then
+ nest += 1
+ when :on_rbracket then
+ nest -= 1
when :on_lbrace then
nest += 1
when :on_rbrace then
@@ -1535,7 +1620,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
when :on_comment, :on_embdoc then
@read.pop
if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and
- (!continue or (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) != 0) then
+ (!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then
if method && method.block_params.nil? then
unget_tk tk
read_documentation_modifiers method, modifiers
@@ -1569,7 +1654,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
return if method.block_params
- skip_tkspace false
+ skip_tkspace_without_nl
read_documentation_modifiers method, RDoc::METHOD_MODIFIERS
end
@@ -1620,19 +1705,30 @@ class RDoc::Parser::Ruby < RDoc::Parser
# Parses a rescue
def parse_rescue
- skip_tkspace false
+ skip_tkspace_without_nl
while tk = get_tk
case tk[:kind]
when :on_nl, :on_semicolon, :on_comment then
break
when :on_comma then
- skip_tkspace false
+ skip_tkspace_without_nl
get_tk if :on_nl == peek_tk[:kind]
end
- skip_tkspace false
+ skip_tkspace_without_nl
+ end
+ end
+
+ ##
+ # Retrieve comment body without =begin/=end
+
+ def retrieve_comment_body(tk)
+ if :on_embdoc == tk[:kind]
+ tk[:text].gsub(/\A=begin.*\n/, '').gsub(/=end\n?\z/, '')
+ else
+ tk[:text]
end
end
@@ -1642,7 +1738,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
def parse_statements(container, single = NORMAL, current_method = nil,
comment = new_comment(''))
raise 'no' unless RDoc::Comment === comment
- comment.force_encoding @encoding if @encoding
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
nest = 1
save_visibility = container.visibility
@@ -1685,20 +1781,23 @@ class RDoc::Parser::Ruby < RDoc::Parser
comment.empty?
comment = ''
- comment.force_encoding @encoding if @encoding
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
end
+ line_no = nil
while tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) do
- comment << tk[:text]
- comment << "\n" unless "\n" == tk[:text].chars.to_a.last
+ comment_body = retrieve_comment_body(tk)
+ line_no = tk[:line_no] if comment.empty?
+ comment += comment_body
+ comment << "\n" unless comment_body =~ /\n\z/
- if tk[:text].size > 1 && "\n" == tk[:text].chars.to_a.last then
- skip_tkspace false # leading spaces
+ if comment_body.size > 1 && comment_body =~ /\n\z/ then
+ skip_tkspace_without_nl # leading spaces
end
tk = get_tk
end
- comment = new_comment comment
+ comment = new_comment comment, line_no
unless comment.empty? then
look_for_directives_in container, comment
@@ -1740,7 +1839,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
when 'until', 'while' then
- if (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) == 0
+ if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
nest += 1
skip_optional_do_after_expression
end
@@ -1756,7 +1855,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
skip_optional_do_after_expression
when 'case', 'do', 'if', 'unless', 'begin' then
- if (RDoc::RipperStateLex::EXPR_LABEL & tk[:state]) == 0
+ if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
nest += 1
end
@@ -1809,7 +1908,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
unless keep_comment then
comment = new_comment ''
- comment.force_encoding @encoding if @encoding
+ comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
container.params = nil
container.block_params = nil
end
@@ -1877,7 +1976,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
loop do
- skip_tkspace false
+ skip_tkspace_without_nl
tk1 = get_tk
if tk1.nil? || :on_comma != tk1[:kind] then
@@ -2026,7 +2125,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# See also RDoc::Markup::PreProcess#handle_directive
def read_documentation_modifiers context, allowed
- skip_tkspace(false)
+ skip_tkspace_without_nl
directive, value = read_directive allowed
return unless directive
@@ -2054,15 +2153,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
end
##
- # Removes private comments from +comment+
- #--
- # TODO remove
-
- def remove_private_comments comment
- comment.remove_private
- end
-
- ##
# Scans this Ruby file for Ruby constructs
def scan
@@ -2073,13 +2163,22 @@ class RDoc::Parser::Ruby < RDoc::Parser
parse_top_level_statements @top_level
rescue StandardError => e
- bytes = ''
+ if @content.include?('<%') and @content.include?('%>') then
+ # Maybe, this is ERB.
+ $stderr.puts "\033[2KRDoc detects ERB file. Skips it for compatibility:"
+ $stderr.puts @file_name
+ return
+ end
if @scanner_point >= @scanner.size
now_line_no = @scanner[@scanner.size - 1][:line_no]
else
now_line_no = peek_tk[:line_no]
end
+ first_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no }
+ last_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no + 1 }
+ last_tk_index = last_tk_index ? last_tk_index - 1 : @scanner.size - 1
+ code = @scanner[first_tk_index..last_tk_index].map{ |t| t[:text] }.join
$stderr.puts <<-EOF
@@ -2088,12 +2187,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
EOF
- unless bytes.empty? then
+ unless code.empty? then
+ $stderr.puts code
$stderr.puts
- now_line_no = peek_tk[:line_no]
- start_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no }
- end_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no + 1 } - 1
- $stderr.puts @scanner[start_index..end_index].join
end
raise e
@@ -2107,7 +2203,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
# while, until, and for have an optional do
def skip_optional_do_after_expression
- skip_tkspace false
+ skip_tkspace_without_nl
tk = get_tk
b_nest = 0
@@ -2139,7 +2235,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
tk = get_tk
end
- skip_tkspace false
+ skip_tkspace_without_nl
get_tk if peek_tk && :on_kw == peek_tk[:kind] && 'do' == peek_tk[:text]
end
@@ -2148,9 +2244,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
# skip the var [in] part of a 'for' statement
def skip_for_variable
- skip_tkspace false
+ skip_tkspace_without_nl
get_tk
- skip_tkspace false
+ skip_tkspace_without_nl
tk = get_tk
unget_tk(tk) unless :on_kw == tk[:kind] and 'in' == tk[:text]
end
@@ -2169,7 +2265,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
def skip_tkspace_comment(skip_nl = true)
loop do
- skip_tkspace skip_nl
+ skip_nl ? skip_tkspace : skip_tkspace_without_nl
next_tk = peek_tk
return if next_tk.nil? || (:on_comment != next_tk[:kind] and :on_embdoc != next_tk[:kind])
get_tk
diff --git a/lib/rdoc/parser/ruby_tools.rb b/lib/rdoc/parser/ruby_tools.rb
index 0a566827a5..681d7166ce 100644
--- a/lib/rdoc/parser/ruby_tools.rb
+++ b/lib/rdoc/parser/ruby_tools.rb
@@ -1,7 +1,6 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
-# Collection of methods for writing parsers against RDoc::RubyLex and
-# RDoc::RubyToken
+# Collection of methods for writing parsers
module RDoc::Parser::RubyTools
@@ -26,12 +25,10 @@ module RDoc::Parser::RubyTools
tk = @scanner[@scanner_point]
@scanner_point += 1
@read.push tk[:text]
- puts "get_tk1 => #{tk.inspect}" if $TOKEN_DEBUG
end
else
@read.push @unget_read.shift
tk = @tokens.shift
- puts "get_tk2 => #{tk.inspect}" if $TOKEN_DEBUG
end
if tk == nil || :on___end__ == tk[:kind]
@@ -112,17 +109,27 @@ module RDoc::Parser::RubyTools
@scanner_point = 0
end
- def tk_nl?(tk)
- :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
+ ##
+ # Skips whitespace tokens including newlines
+
+ def skip_tkspace
+ tokens = []
+
+ while (tk = get_tk) and (:on_sp == tk[:kind] or :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]) do
+ tokens.push(tk)
+ end
+
+ unget_tk(tk)
+ tokens
end
##
- # Skips whitespace tokens including newlines if +skip_nl+ is true
+ # Skips whitespace tokens excluding newlines
- def skip_tkspace(skip_nl = true)
+ def skip_tkspace_without_nl
tokens = []
- while (tk = get_tk) and (:on_sp == tk[:kind] or (skip_nl and tk_nl?(tk))) do
+ while (tk = get_tk) and :on_sp == tk[:kind] do
tokens.push(tk)
end
diff --git a/lib/rdoc/parser/simple.rb b/lib/rdoc/parser/simple.rb
index f2ab27a92e..b1dabad0f8 100644
--- a/lib/rdoc/parser/simple.rb
+++ b/lib/rdoc/parser/simple.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Parse a non-source file. We basically take the whole thing as one big
# comment.
@@ -19,7 +19,7 @@ class RDoc::Parser::Simple < RDoc::Parser
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
- preprocess.handle @content, @top_level
+ @content = preprocess.handle @content, @top_level
end
##
@@ -52,7 +52,7 @@ class RDoc::Parser::Simple < RDoc::Parser
def remove_private_comment comment
# Workaround for gsub encoding for Ruby 1.9.2 and earlier
empty = ''
- empty.force_encoding comment.encoding
+ empty = RDoc::Encoding.change_encoding empty, comment.encoding
comment = comment.gsub(%r%^--\n.*?^\+\+\n?%m, empty)
comment.sub(%r%^--\n.*%m, empty)
diff --git a/lib/rdoc/parser/text.rb b/lib/rdoc/parser/text.rb
index 1a13fd1186..01de0cc595 100644
--- a/lib/rdoc/parser/text.rb
+++ b/lib/rdoc/parser/text.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Indicates this parser is text and doesn't contain code constructs.
#
diff --git a/lib/rdoc/rd.rb b/lib/rdoc/rd.rb
index 39af3294f5..0d3d3cea85 100644
--- a/lib/rdoc/rd.rb
+++ b/lib/rdoc/rd.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# RDoc::RD implements the RD format from the rdtool gem.
#
diff --git a/lib/rdoc/rd/block_parser.rb b/lib/rdoc/rd/block_parser.rb
index 3f4941168f..462ba869a2 100644
--- a/lib/rdoc/rd/block_parser.rb
+++ b/lib/rdoc/rd/block_parser.rb
@@ -1,7 +1,8 @@
+# frozen_string_literal: true
#
# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.4.14
-# from Racc grammer file "".
+# This file is automatically generated by Racc 1.5.2
+# from Racc grammar file "".
#
require 'racc/parser.rb'
@@ -207,7 +208,7 @@ def next_token # :nodoc:
if @in_verbatim
[:STRINGLINE, line]
else
- @indent_stack.push("\s" << newIndent)
+ @indent_stack.push("\s" + newIndent)
[:ITEMLISTLINE, rest]
end
end
@@ -219,7 +220,7 @@ def next_token # :nodoc:
if @in_verbatim
[:STRINGLINE, line]
else
- @indent_stack.push("\s" * mark.size << newIndent)
+ @indent_stack.push("\s" * mark.size + newIndent)
[:ENUMLISTLINE, rest]
end
end
@@ -419,52 +420,52 @@ end
racc_action_table = [
34, 35, 30, 33, 40, 34, 35, 30, 33, 40,
- 65, 34, 35, 30, 33, 14, 73, 14, 54, 76,
- 15, 88, 34, 35, 30, 33, 14, 73, 77, 33,
- 54, 15, 34, 35, 30, 33, 14, 73, 81, 38,
- 38, 15, 34, 35, 30, 33, 14, 73, 40, 36,
- 83, 15, 34, 35, 30, 33, 54, 47, 30, 35,
- 34, 15, 34, 35, 30, 33, 14, 73, 38, 67,
- 59, 15, 34, 35, 30, 33, 14, 9, 10, 11,
- 12, 15, 34, 35, 30, 33, 14, 73, 14, nil,
+ 65, 34, 35, 30, 33, 14, 73, 36, 38, 34,
+ 15, 88, 34, 35, 30, 33, 14, 9, 10, 11,
+ 12, 15, 34, 35, 30, 33, 14, 9, 10, 11,
+ 12, 15, 34, 35, 30, 33, 35, 47, 30, 54,
+ 33, 15, 34, 35, 30, 33, 54, 47, 14, 14,
+ 59, 15, 34, 35, 30, 33, 14, 73, 67, 76,
+ 77, 15, 34, 35, 30, 33, 14, 73, 54, 81,
+ 38, 15, 34, 35, 30, 33, 14, 73, 38, 40,
+ 83, 15, 34, 35, 30, 33, 14, 73, nil, nil,
nil, 15, 34, 35, 30, 33, 14, 73, nil, nil,
- nil, 15, 34, 35, 30, 33, nil, 47, nil, nil,
nil, 15, 34, 35, 30, 33, 14, 73, nil, nil,
nil, 15, 34, 35, 30, 33, 14, 73, nil, nil,
- nil, 15, 34, 35, 30, 33, 14, 9, 10, 11,
- 12, 15, 34, 35, 30, 33, 14, 73, 61, 63,
+ nil, 15, 34, 35, 30, 33, 14, 73, nil, nil,
+ nil, 15, 34, 35, 30, 33, 14, 73, 61, 63,
nil, 15, 14, 62, 60, 61, 63, 79, 61, 63,
62, 87, nil, 62, 34, 35, 30, 33 ]
racc_action_check = [
41, 41, 41, 41, 41, 15, 15, 15, 15, 15,
- 41, 86, 86, 86, 86, 86, 86, 34, 33, 49,
- 86, 86, 85, 85, 85, 85, 85, 85, 51, 31,
- 54, 85, 79, 79, 79, 79, 79, 79, 56, 57,
- 58, 79, 78, 78, 78, 78, 78, 78, 62, 1,
- 66, 78, 24, 24, 24, 24, 30, 24, 28, 25,
- 22, 24, 75, 75, 75, 75, 75, 75, 13, 44,
- 36, 75, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 46, 46, 46, 46, 46, 46, 35, nil,
- nil, 46, 45, 45, 45, 45, 45, 45, nil, nil,
- nil, 45, 27, 27, 27, 27, nil, 27, nil, nil,
- nil, 27, 74, 74, 74, 74, 74, 74, nil, nil,
- nil, 74, 68, 68, 68, 68, 68, 68, nil, nil,
- nil, 68, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 47, 47, 47, 47, 47, 47, 39, 39,
- nil, 47, 52, 39, 39, 82, 82, 52, 64, 64,
+ 41, 86, 86, 86, 86, 86, 86, 1, 13, 22,
+ 86, 86, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 24, 24, 24, 24, 25, 24, 28, 30,
+ 31, 24, 27, 27, 27, 27, 33, 27, 34, 35,
+ 36, 27, 45, 45, 45, 45, 45, 45, 44, 49,
+ 51, 45, 46, 46, 46, 46, 46, 46, 54, 56,
+ 57, 46, 47, 47, 47, 47, 47, 47, 58, 62,
+ 66, 47, 68, 68, 68, 68, 68, 68, nil, nil,
+ nil, 68, 74, 74, 74, 74, 74, 74, nil, nil,
+ nil, 74, 75, 75, 75, 75, 75, 75, nil, nil,
+ nil, 75, 78, 78, 78, 78, 78, 78, nil, nil,
+ nil, 78, 79, 79, 79, 79, 79, 79, nil, nil,
+ nil, 79, 85, 85, 85, 85, 85, 85, 39, 39,
+ nil, 85, 52, 39, 39, 82, 82, 52, 64, 64,
82, 82, nil, 64, 20, 20, 20, 20 ]
racc_action_pointer = [
- 129, 49, 69, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 61, nil, 2, nil, nil, nil, nil,
- 161, nil, 57, nil, 49, 55, nil, 99, 53, nil,
- 48, 23, nil, 10, 10, 81, 70, nil, nil, 141,
- nil, -3, nil, nil, 56, 89, 79, 139, nil, 6,
- nil, 15, 145, nil, 22, nil, 25, 32, 33, nil,
- nil, nil, 41, nil, 151, nil, 37, nil, 119, nil,
- nil, nil, nil, nil, 109, 59, nil, nil, 39, 29,
- nil, nil, 148, nil, nil, 19, 8, nil, nil ]
+ 19, 17, 29, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, 11, nil, 2, nil, nil, nil, nil,
+ 161, nil, 16, nil, 39, 42, nil, 49, 43, nil,
+ 41, 44, nil, 48, 51, 52, 60, nil, nil, 141,
+ nil, -3, nil, nil, 55, 59, 69, 79, nil, 56,
+ nil, 57, 145, nil, 70, nil, 66, 73, 81, nil,
+ nil, nil, 82, nil, 151, nil, 77, nil, 89, nil,
+ nil, nil, nil, nil, 99, 109, nil, nil, 119, 129,
+ nil, nil, 148, nil, nil, 139, 8, nil, nil ]
racc_action_default = [
-2, -73, -1, -4, -5, -6, -7, -8, -9, -10,
@@ -478,26 +479,26 @@ racc_action_default = [
-60, -47, -73, -29, -52, -48, -73, -20, -50 ]
racc_goto_table = [
- 4, 39, 4, 68, 74, 75, 6, 5, 6, 5,
- 44, 42, 51, 49, 3, 56, 37, 57, 58, 80,
+ 4, 39, 4, 68, 74, 75, 5, 6, 5, 6,
+ 44, 42, 51, 49, 3, 56, 37, 57, 58, 1,
2, 66, 84, 41, 43, 48, 50, 64, 84, 84,
- 46, 45, 42, 46, 45, 55, 85, 86, 1, 84,
+ 45, 46, 42, 45, 46, 55, 85, 86, 80, 84,
84, nil, nil, nil, nil, nil, nil, nil, 82, nil,
nil, nil, 78 ]
racc_goto_check = [
- 4, 10, 4, 31, 31, 31, 6, 5, 6, 5,
- 21, 12, 27, 21, 3, 27, 3, 9, 9, 33,
+ 4, 10, 4, 31, 31, 31, 5, 6, 5, 6,
+ 21, 12, 27, 21, 3, 27, 3, 9, 9, 1,
2, 11, 32, 17, 19, 23, 26, 10, 32, 32,
- 6, 5, 12, 6, 5, 29, 31, 31, 1, 32,
+ 5, 6, 12, 5, 6, 29, 31, 31, 33, 32,
32, nil, nil, nil, nil, nil, nil, nil, 10, nil,
nil, nil, 4 ]
racc_goto_pointer = [
- nil, 38, 20, 14, 0, 7, 6, nil, nil, -17,
+ nil, 19, 20, 14, 0, 6, 7, nil, nil, -17,
-14, -20, -9, nil, nil, nil, nil, 8, nil, 2,
nil, -14, nil, 0, nil, nil, -2, -18, nil, 4,
- nil, -42, -46, -35 ]
+ nil, -42, -46, -16 ]
racc_goto_default = [
nil, nil, nil, nil, 70, 71, 72, 7, 8, 13,
diff --git a/lib/rdoc/rd/inline.rb b/lib/rdoc/rd/inline.rb
index 011ec67e33..e5cb545728 100644
--- a/lib/rdoc/rd/inline.rb
+++ b/lib/rdoc/rd/inline.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Inline keeps track of markup and labels to create proper links.
@@ -50,11 +50,11 @@ class RDoc::RD::Inline
def append more
case more
when String then
- @reference << more
- @rdoc << more
+ @reference += more
+ @rdoc += more
when RDoc::RD::Inline then
- @reference << more.reference
- @rdoc << more.rdoc
+ @reference += more.reference
+ @rdoc += more.rdoc
else
raise "unknown thingy #{more}"
end
diff --git a/lib/rdoc/rd/inline_parser.rb b/lib/rdoc/rd/inline_parser.rb
index cc63ea6f70..8f4c2c31ef 100644
--- a/lib/rdoc/rd/inline_parser.rb
+++ b/lib/rdoc/rd/inline_parser.rb
@@ -1,7 +1,8 @@
+# frozen_string_literal: true
#
# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.4.14
-# from Racc grammer file "".
+# This file is automatically generated by Racc 1.5.2
+# from Racc grammar file "".
#
require 'racc/parser.rb'
@@ -96,7 +97,7 @@ end
def parse inline
@inline = inline
@src = StringScanner.new inline
- @pre = ""
+ @pre = "".dup
@yydebug = true
do_parse.to_s
end
@@ -243,23 +244,34 @@ end
##### State transition tables begin ###
racc_action_table = [
- 104, 103, 102, 100, 101, 99, 115, 116, 117, 86,
+ 104, 103, 102, 100, 101, 99, 115, 116, 117, 29,
105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
- 164, 118, 119, 104, 103, 102, 100, 101, 99, 115,
- 116, 117, 175, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 85, 118, 119, 63, 64, 65, 61,
- 81, 62, 76, 78, 79, 84, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 77, 80, 149, 104,
- 103, 102, 100, 101, 99, 115, 116, 117, 29, 105,
- 106, 107, 108, 109, 110, 111, 112, 113, 114, 173,
+ 84, 118, 119, 63, 64, 65, 61, 81, 62, 76,
+ 78, 79, 85, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 77, 80, 149, 63, 64, 65, 153,
+ 81, 62, 76, 78, 79, 86, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 77, 80, 152, 104,
+ 103, 102, 100, 101, 99, 115, 116, 117, 87, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 88,
118, 119, 104, 103, 102, 100, 101, 99, 115, 116,
- 117, 137, 105, 106, 107, 108, 109, 110, 111, 112,
- 113, 114, 177, 118, 119, 63, 64, 65, 153, 81,
- 62, 76, 78, 79, 148, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 77, 80, 152, 22, 23,
- 24, 25, 26, 21, 18, 19, 176, 177, 13, 124,
- 14, 96, 15, 89, 16, 154, 17, 88, 137, 20,
- 22, 23, 24, 25, 26, 21, 18, 19, 87, 161,
+ 117, 89, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 96, 118, 119, 104, 103, 102, 100, 101,
+ 99, 115, 116, 117, 124, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 137, 118, 119, 22, 23,
+ 24, 25, 26, 21, 18, 19, 176, 177, 13, 148,
+ 14, 154, 15, 137, 16, 161, 17, 164, 173, 20,
+ 22, 23, 24, 25, 26, 21, 18, 19, 175, 177,
+ 13, nil, 14, nil, 15, nil, 16, nil, 17, nil,
+ nil, 20, 22, 23, 24, 25, 26, 21, 18, 19,
+ nil, nil, 13, nil, 14, nil, 15, nil, 16, nil,
+ 17, nil, nil, 20, 22, 23, 24, 25, 26, 21,
+ 18, 19, nil, nil, 13, nil, 14, nil, 15, nil,
+ 16, nil, 17, nil, nil, 20, 22, 23, 24, 25,
+ 26, 21, 18, 19, nil, nil, 13, nil, 14, nil,
+ 15, nil, 16, nil, 17, nil, nil, 20, 22, 23,
+ 24, 25, 26, 21, 18, 19, nil, nil, 13, nil,
+ 14, nil, 15, nil, 16, nil, 17, nil, nil, 20,
+ 22, 23, 24, 25, 26, 21, 18, 19, nil, nil,
13, nil, 14, nil, 15, nil, 16, nil, 17, 42,
nil, 20, 54, 38, 53, 55, 56, 57, nil, 13,
nil, 14, nil, 15, nil, 16, nil, 17, nil, nil,
@@ -267,63 +279,63 @@ racc_action_table = [
nil, 13, nil, 14, nil, 15, nil, 16, nil, 17,
nil, nil, 20, 63, 64, 65, 61, 81, 62, 76,
78, 79, nil, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 77, 80, 145, nil, nil, 54, 133,
- 53, 55, 56, 57, nil, 13, nil, 14, nil, 15,
- nil, 16, nil, 17, 145, nil, 20, 54, 133, 53,
- 55, 56, 57, nil, 13, nil, 14, nil, 15, nil,
- 16, nil, 17, nil, nil, 20, 22, 23, 24, 25,
- 26, 21, 18, 19, nil, nil, 13, nil, 14, nil,
- 15, nil, 16, nil, 17, 145, nil, 20, 54, 133,
+ 73, 74, 75, 77, 80, 122, nil, nil, 54, nil,
53, 55, 56, 57, nil, 13, nil, 14, nil, 15,
nil, 16, nil, 17, 145, nil, 20, 54, 133, 53,
55, 56, 57, nil, 13, nil, 14, nil, 15, nil,
- 16, nil, 17, nil, nil, 20, 22, 23, 24, 25,
- 26, 21, 18, 19, nil, nil, 13, nil, 14, nil,
- 15, nil, 16, nil, 17, nil, nil, 20, 22, 23,
- 24, 25, 26, 21, 18, 19, nil, nil, 13, nil,
- 14, nil, 15, nil, 16, nil, 17, nil, nil, 20,
- 22, 23, 24, 25, 26, 21, 18, 19, nil, nil,
- 13, nil, 14, nil, 15, nil, 16, nil, 17, nil,
- nil, 20, 22, 23, 24, 25, 26, 21, 18, 19,
- nil, nil, 13, nil, 14, nil, 15, nil, 16, 122,
- 17, nil, 54, 20, 53, 55, 56, 57, nil, 13,
- nil, 14, nil, 15, nil, 16, nil, 17, nil, nil,
- 20, 135, 136, 54, 133, 53, 55, 56, 57, nil,
- 13, nil, 14, nil, 15, nil, 16, nil, 17, nil,
- nil, 20, 135, 136, 54, 133, 53, 55, 56, 57,
+ 16, nil, 17, 145, nil, 20, 54, 133, 53, 55,
+ 56, 57, nil, 13, nil, 14, nil, 15, nil, 16,
+ nil, 17, 145, nil, 20, 54, 133, 53, 55, 56,
+ 57, nil, 13, nil, 14, nil, 15, nil, 16, nil,
+ 17, 145, nil, 20, 54, 133, 53, 55, 56, 57,
nil, 13, nil, 14, nil, 15, nil, 16, nil, 17,
nil, nil, 20, 135, 136, 54, 133, 53, 55, 56,
- 57, nil, 13, nil, 14, nil, 15, nil, 16, 158,
- 17, nil, 54, 20, 53, 55, 56, 57, 95, nil,
- nil, 54, 91, 53, 55, 56, 57, 145, nil, nil,
- 54, 133, 53, 55, 56, 57, 165, 135, 136, 54,
- 133, 53, 55, 56, 57, 145, nil, nil, 54, 133,
- 53, 55, 56, 57, 172, 135, 136, 54, 133, 53,
- 55, 56, 57, 174, 135, 136, 54, 133, 53, 55,
- 56, 57, 178, 135, 136, 54, 133, 53, 55, 56,
- 57, 135, 136, 54, 133, 53, 55, 56, 57, 135,
- 136, 54, 133, 53, 55, 56, 57, 135, 136, 54,
- 133, 53, 55, 56, 57, 22, 23, 24, 25, 26,
- 21 ]
+ 57, nil, 13, nil, 14, nil, 15, nil, 16, nil,
+ 17, nil, nil, 20, 135, 136, 54, 133, 53, 55,
+ 56, 57, nil, 13, nil, 14, nil, 15, nil, 16,
+ nil, 17, nil, nil, 20, 135, 136, 54, 133, 53,
+ 55, 56, 57, nil, 13, nil, 14, nil, 15, nil,
+ 16, nil, 17, 95, nil, 20, 54, 91, 53, 55,
+ 56, 57, 145, nil, nil, 54, 133, 53, 55, 56,
+ 57, 158, nil, nil, 54, nil, 53, 55, 56, 57,
+ 165, 135, 136, 54, 133, 53, 55, 56, 57, 145,
+ nil, nil, 54, 133, 53, 55, 56, 57, 172, 135,
+ 136, 54, 133, 53, 55, 56, 57, 174, 135, 136,
+ 54, 133, 53, 55, 56, 57, 178, 135, 136, 54,
+ 133, 53, 55, 56, 57, 135, 136, 54, 133, 53,
+ 55, 56, 57, 135, 136, 54, 133, 53, 55, 56,
+ 57, 135, 136, 54, 133, 53, 55, 56, 57, 22,
+ 23, 24, 25, 26, 21 ]
racc_action_check = [
- 38, 38, 38, 38, 38, 38, 38, 38, 38, 32,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 1,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
- 125, 38, 38, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 164, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 97, 31, 97, 97, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 29, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 91,
- 91, 91, 91, 91, 91, 91, 91, 91, 1, 91,
- 91, 91, 91, 91, 91, 91, 91, 91, 91, 162,
- 91, 91, 155, 155, 155, 155, 155, 155, 155, 155,
- 155, 43, 155, 155, 155, 155, 155, 155, 155, 155,
- 155, 155, 172, 155, 155, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 58, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 16, 16,
- 16, 16, 16, 16, 16, 16, 165, 165, 16, 41,
- 16, 37, 16, 35, 16, 90, 16, 34, 94, 16,
- 17, 17, 17, 17, 17, 17, 17, 17, 33, 100,
+ 29, 38, 38, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 31, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 32, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 33, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 34,
+ 91, 91, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 35, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 37, 97, 97, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 41, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 43, 155, 155, 0, 0,
+ 0, 0, 0, 0, 0, 0, 165, 165, 0, 58,
+ 0, 90, 0, 94, 0, 100, 0, 125, 162, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 164, 172,
+ 2, nil, 2, nil, 2, nil, 2, nil, 2, nil,
+ nil, 2, 13, 13, 13, 13, 13, 13, 13, 13,
+ nil, nil, 13, nil, 13, nil, 13, nil, 13, nil,
+ 13, nil, nil, 13, 14, 14, 14, 14, 14, 14,
+ 14, 14, nil, nil, 14, nil, 14, nil, 14, nil,
+ 14, nil, 14, nil, nil, 14, 15, 15, 15, 15,
+ 15, 15, 15, 15, nil, nil, 15, nil, 15, nil,
+ 15, nil, 15, nil, 15, nil, nil, 15, 16, 16,
+ 16, 16, 16, 16, 16, 16, nil, nil, 16, nil,
+ 16, nil, 16, nil, 16, nil, 16, nil, nil, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17, nil, nil,
17, nil, 17, nil, 17, nil, 17, nil, 17, 18,
nil, 17, 18, 18, 18, 18, 18, 18, nil, 18,
nil, 18, nil, 18, nil, 18, nil, 18, nil, nil,
@@ -331,64 +343,53 @@ racc_action_check = [
nil, 19, nil, 19, nil, 19, nil, 19, nil, 19,
nil, nil, 19, 20, 20, 20, 20, 20, 20, 20,
20, 20, nil, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 146, nil, nil, 146, 146,
- 146, 146, 146, 146, nil, 146, nil, 146, nil, 146,
- nil, 146, nil, 146, 138, nil, 146, 138, 138, 138,
- 138, 138, 138, nil, 138, nil, 138, nil, 138, nil,
- 138, nil, 138, nil, nil, 138, 0, 0, 0, 0,
- 0, 0, 0, 0, nil, nil, 0, nil, 0, nil,
- 0, nil, 0, nil, 0, 45, nil, 0, 45, 45,
- 45, 45, 45, 45, nil, 45, nil, 45, nil, 45,
- nil, 45, nil, 45, 44, nil, 45, 44, 44, 44,
+ 20, 20, 20, 20, 20, 39, nil, nil, 39, nil,
+ 39, 39, 39, 39, nil, 39, nil, 39, nil, 39,
+ nil, 39, nil, 39, 44, nil, 39, 44, 44, 44,
44, 44, 44, nil, 44, nil, 44, nil, 44, nil,
- 44, nil, 44, nil, nil, 44, 2, 2, 2, 2,
- 2, 2, 2, 2, nil, nil, 2, nil, 2, nil,
- 2, nil, 2, nil, 2, nil, nil, 2, 13, 13,
- 13, 13, 13, 13, 13, 13, nil, nil, 13, nil,
- 13, nil, 13, nil, 13, nil, 13, nil, nil, 13,
- 14, 14, 14, 14, 14, 14, 14, 14, nil, nil,
- 14, nil, 14, nil, 14, nil, 14, nil, 14, nil,
- nil, 14, 15, 15, 15, 15, 15, 15, 15, 15,
- nil, nil, 15, nil, 15, nil, 15, nil, 15, 39,
- 15, nil, 39, 15, 39, 39, 39, 39, nil, 39,
- nil, 39, nil, 39, nil, 39, nil, 39, nil, nil,
- 39, 42, 42, 42, 42, 42, 42, 42, 42, nil,
+ 44, nil, 44, 45, nil, 44, 45, 45, 45, 45,
+ 45, 45, nil, 45, nil, 45, nil, 45, nil, 45,
+ nil, 45, 138, nil, 45, 138, 138, 138, 138, 138,
+ 138, nil, 138, nil, 138, nil, 138, nil, 138, nil,
+ 138, 146, nil, 138, 146, 146, 146, 146, 146, 146,
+ nil, 146, nil, 146, nil, 146, nil, 146, nil, 146,
+ nil, nil, 146, 42, 42, 42, 42, 42, 42, 42,
42, nil, 42, nil, 42, nil, 42, nil, 42, nil,
- nil, 42, 127, 127, 127, 127, 127, 127, 127, 127,
- nil, 127, nil, 127, nil, 127, nil, 127, nil, 127,
- nil, nil, 127, 122, 122, 122, 122, 122, 122, 122,
- 122, nil, 122, nil, 122, nil, 122, nil, 122, 92,
- 122, nil, 92, 122, 92, 92, 92, 92, 36, nil,
- nil, 36, 36, 36, 36, 36, 36, 52, nil, nil,
- 52, 52, 52, 52, 52, 52, 126, 126, 126, 126,
- 126, 126, 126, 126, 126, 142, nil, nil, 142, 142,
- 142, 142, 142, 142, 159, 159, 159, 159, 159, 159,
- 159, 159, 159, 163, 163, 163, 163, 163, 163, 163,
- 163, 163, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 95, 95, 95, 95, 95, 95, 95, 95, 158,
- 158, 158, 158, 158, 158, 158, 158, 168, 168, 168,
- 168, 168, 168, 168, 168, 27, 27, 27, 27, 27,
- 27 ]
+ 42, nil, nil, 42, 122, 122, 122, 122, 122, 122,
+ 122, 122, nil, 122, nil, 122, nil, 122, nil, 122,
+ nil, 122, nil, nil, 122, 127, 127, 127, 127, 127,
+ 127, 127, 127, nil, 127, nil, 127, nil, 127, nil,
+ 127, nil, 127, 36, nil, 127, 36, 36, 36, 36,
+ 36, 36, 52, nil, nil, 52, 52, 52, 52, 52,
+ 52, 92, nil, nil, 92, nil, 92, 92, 92, 92,
+ 126, 126, 126, 126, 126, 126, 126, 126, 126, 142,
+ nil, nil, 142, 142, 142, 142, 142, 142, 159, 159,
+ 159, 159, 159, 159, 159, 159, 159, 163, 163, 163,
+ 163, 163, 163, 163, 163, 163, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 95, 95, 95, 95, 95,
+ 95, 95, 95, 158, 158, 158, 158, 158, 158, 158,
+ 158, 168, 168, 168, 168, 168, 168, 168, 168, 27,
+ 27, 27, 27, 27, 27 ]
racc_action_pointer = [
- 283, 78, 343, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 365, 387, 409, 135, 157, 176, 198,
- 220, nil, nil, nil, nil, nil, nil, 602, nil, 55,
- nil, 29, -7, 150, 137, 131, 515, 128, -3, 426,
- nil, 145, 447, 96, 321, 302, nil, nil, nil, nil,
- nil, nil, 524, nil, nil, nil, nil, nil, 113, 43,
- nil, 112, nil, nil, nil, nil, nil, nil, nil, nil,
+ 135, 9, 157, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, 179, 201, 223, 245, 267, 286, 308,
+ 330, nil, nil, nil, nil, nil, nil, 606, nil, 20,
+ nil, 18, 39, 60, 69, 79, 510, 89, -3, 352,
+ nil, 120, 449, 130, 371, 390, nil, nil, nil, nil,
+ nil, nil, 519, nil, nil, nil, nil, nil, 138, 20,
+ nil, 43, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 132, 66, 506, nil, 153, 577, nil, 20, nil, nil,
- 163, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ 128, 66, 528, nil, 148, 581, nil, 89, nil, nil,
+ 149, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 489, nil, nil, 17, 533, 468, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 261, nil,
- nil, nil, 542, nil, nil, nil, 242, nil, nil, nil,
- nil, nil, nil, nil, nil, 89, nil, nil, 585, 551,
- nil, nil, 86, 560, 28, 142, nil, nil, 593, nil,
- nil, 569, 107, nil, nil, nil, nil, nil, nil ]
+ nil, nil, 470, nil, nil, 154, 537, 491, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 409, nil,
+ nil, nil, 546, nil, nil, nil, 428, nil, nil, nil,
+ nil, nil, nil, nil, nil, 112, nil, nil, 589, 555,
+ nil, nil, 155, 564, 164, 142, nil, nil, 597, nil,
+ nil, 573, 164, nil, nil, nil, nil, nil, nil ]
racc_action_default = [
-138, -138, -1, -3, -4, -5, -6, -7, -8, -9,
@@ -411,15 +412,15 @@ racc_action_default = [
-60, -138, -34, -36, -37, -29, -30, -32, -34 ]
racc_goto_table = [
- 126, 44, 125, 52, 144, 144, 160, 93, 97, 43,
- 166, 82, 144, 40, 41, 39, 138, 146, 169, 90,
- 36, 52, 44, 1, 52, 129, 169, 94, 59, 83,
- 123, 30, 151, 92, 120, 121, 31, 32, 33, 34,
- 35, 170, 58, 166, 167, 147, 170, 166, 37, nil,
+ 126, 44, 125, 43, 144, 144, 160, 93, 97, 52,
+ 166, 82, 144, 40, 41, 39, 138, 146, 169, 30,
+ 36, 94, 44, 1, 123, 129, 169, 52, 90, 37,
+ 52, 167, 147, 92, 120, 121, 31, 32, 33, 34,
+ 35, 170, 58, 166, 59, 83, 170, 166, 151, nil,
150, nil, 166, 159, 4, 166, 4, nil, nil, nil,
nil, 155, nil, 156, 160, nil, nil, 4, 4, 4,
- 4, 4, nil, 4, 5, nil, 5, 52, nil, nil,
- 163, nil, 162, 157, nil, 168, nil, 5, 5, 5,
+ 4, 4, nil, 4, 5, nil, 5, 157, nil, nil,
+ 163, nil, 162, 52, nil, 168, nil, 5, 5, 5,
5, 5, nil, 5, nil, nil, nil, nil, 144, nil,
nil, nil, 144, nil, nil, 129, 144, 144, nil, 6,
129, 6, nil, nil, nil, nil, 171, 7, nil, 7,
@@ -429,15 +430,15 @@ racc_goto_table = [
11, 11, 11, nil, 11 ]
racc_goto_check = [
- 22, 24, 21, 34, 36, 36, 37, 18, 16, 23,
- 35, 41, 36, 19, 20, 17, 25, 25, 28, 14,
- 13, 34, 24, 1, 34, 24, 28, 23, 38, 39,
- 23, 3, 42, 17, 19, 20, 1, 1, 1, 1,
- 1, 33, 1, 35, 29, 32, 33, 35, 15, nil,
+ 22, 24, 21, 23, 36, 36, 37, 18, 16, 34,
+ 35, 41, 36, 19, 20, 17, 25, 25, 28, 3,
+ 13, 23, 24, 1, 23, 24, 28, 34, 14, 15,
+ 34, 29, 32, 17, 19, 20, 1, 1, 1, 1,
+ 1, 33, 1, 35, 38, 39, 33, 35, 42, nil,
41, nil, 35, 22, 4, 35, 4, nil, nil, nil,
nil, 16, nil, 18, 37, nil, nil, 4, 4, 4,
- 4, 4, nil, 4, 5, nil, 5, 34, nil, nil,
- 22, nil, 21, 23, nil, 22, nil, 5, 5, 5,
+ 4, 4, nil, 4, 5, nil, 5, 23, nil, nil,
+ 22, nil, 21, 34, nil, 22, nil, 5, 5, 5,
5, 5, nil, 5, nil, nil, nil, nil, 36, nil,
nil, nil, 36, nil, nil, 24, 36, 36, nil, 6,
24, 6, nil, nil, nil, nil, 22, 7, nil, 7,
@@ -447,11 +448,11 @@ racc_goto_check = [
11, 11, 11, nil, 11 ]
racc_goto_pointer = [
- nil, 23, nil, 29, 54, 74, 109, 117, 127, nil,
- nil, 135, nil, 2, -17, 30, -30, -3, -29, -5,
- -4, -40, -42, -9, -17, -28, nil, nil, -120, -83,
- nil, nil, -7, -101, -15, -116, -40, -91, 8, 2,
- nil, -9, -29 ]
+ nil, 23, nil, 17, 54, 74, 109, 117, 127, nil,
+ nil, 135, nil, 2, -8, 11, -30, -3, -29, -5,
+ -4, -40, -42, -15, -17, -28, nil, nil, -120, -96,
+ nil, nil, -20, -101, -9, -116, -40, -91, 24, 18,
+ nil, -9, -13 ]
racc_goto_default = [
nil, nil, 2, 3, 46, 47, 48, 49, 50, 9,
diff --git a/lib/rdoc/rdoc.gemspec b/lib/rdoc/rdoc.gemspec
index 2787f07654..7725e40b22 100644
--- a/lib/rdoc/rdoc.gemspec
+++ b/lib/rdoc/rdoc.gemspec
@@ -1,14 +1,13 @@
begin
- require_relative "lib/rdoc"
+ require_relative "lib/rdoc/version"
rescue LoadError
# for Ruby repository
- require_relative "../rdoc"
+ require_relative "version"
end
Gem::Specification.new do |s|
s.name = "rdoc"
s.version = RDoc::VERSION
- s.date = "2017-10-10"
s.authors = [
"Eric Hodel",
@@ -32,10 +31,202 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat
s.bindir = "exe"
s.executables = ["rdoc", "ri"]
s.require_paths = ["lib"]
- # for ruby core repository. It was generated by `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- s.files = [".document", ".gitignore", ".travis.yml", "CONTRIBUTING.rdoc", "CVE-2013-0256.rdoc", "ExampleMarkdown.md", "ExampleRDoc.rdoc", "Gemfile", "History.rdoc", "LEGAL.rdoc", "LICENSE.rdoc", "README.rdoc", "RI.rdoc", "Rakefile", "TODO.rdoc", "appveyor.yml", "bin/console", "bin/setup", "exe/rdoc", "exe/ri", "lib/rdoc.rb", "lib/rdoc/alias.rb", "lib/rdoc/anon_class.rb", "lib/rdoc/any_method.rb", "lib/rdoc/attr.rb", "lib/rdoc/class_module.rb", "lib/rdoc/code_object.rb", "lib/rdoc/code_objects.rb", "lib/rdoc/comment.rb", "lib/rdoc/constant.rb", "lib/rdoc/context.rb", "lib/rdoc/context/section.rb", "lib/rdoc/cross_reference.rb", "lib/rdoc/encoding.rb", "lib/rdoc/erb_partial.rb", "lib/rdoc/erbio.rb", "lib/rdoc/extend.rb", "lib/rdoc/generator.rb", "lib/rdoc/generator/darkfish.rb", "lib/rdoc/generator/json_index.rb", "lib/rdoc/generator/markup.rb", "lib/rdoc/generator/pot.rb", "lib/rdoc/generator/pot/message_extractor.rb", "lib/rdoc/generator/pot/po.rb", "lib/rdoc/generator/pot/po_entry.rb", "lib/rdoc/generator/ri.rb", "lib/rdoc/generator/template/darkfish/.document", "lib/rdoc/generator/template/darkfish/_footer.rhtml", "lib/rdoc/generator/template/darkfish/_head.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml", "lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml", "lib/rdoc/generator/template/darkfish/class.rhtml", "lib/rdoc/generator/template/darkfish/css/fonts.css", "lib/rdoc/generator/template/darkfish/css/rdoc.css", "lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf", "lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf", "lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf", "lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf", "lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf", "lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf", "lib/rdoc/generator/template/darkfish/images/add.png", "lib/rdoc/generator/template/darkfish/images/arrow_up.png", "lib/rdoc/generator/template/darkfish/images/brick.png", "lib/rdoc/generator/template/darkfish/images/brick_link.png", "lib/rdoc/generator/template/darkfish/images/bug.png", "lib/rdoc/generator/template/darkfish/images/bullet_black.png", "lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png", "lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png", "lib/rdoc/generator/template/darkfish/images/date.png", "lib/rdoc/generator/template/darkfish/images/delete.png", "lib/rdoc/generator/template/darkfish/images/find.png", "lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif", "lib/rdoc/generator/template/darkfish/images/macFFBgHack.png", "lib/rdoc/generator/template/darkfish/images/package.png", "lib/rdoc/generator/template/darkfish/images/page_green.png", "lib/rdoc/generator/template/darkfish/images/page_white_text.png", "lib/rdoc/generator/template/darkfish/images/page_white_width.png", "lib/rdoc/generator/template/darkfish/images/plugin.png", "lib/rdoc/generator/template/darkfish/images/ruby.png", "lib/rdoc/generator/template/darkfish/images/tag_blue.png", "lib/rdoc/generator/template/darkfish/images/tag_green.png", "lib/rdoc/generator/template/darkfish/images/transparent.png", "lib/rdoc/generator/template/darkfish/images/wrench.png", "lib/rdoc/generator/template/darkfish/images/wrench_orange.png", "lib/rdoc/generator/template/darkfish/images/zoom.png", "lib/rdoc/generator/template/darkfish/index.rhtml", "lib/rdoc/generator/template/darkfish/js/darkfish.js", "lib/rdoc/generator/template/darkfish/js/jquery.js", "lib/rdoc/generator/template/darkfish/js/search.js", "lib/rdoc/generator/template/darkfish/page.rhtml", "lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml", "lib/rdoc/generator/template/darkfish/servlet_root.rhtml", "lib/rdoc/generator/template/darkfish/table_of_contents.rhtml", "lib/rdoc/generator/template/json_index/.document", "lib/rdoc/generator/template/json_index/js/navigation.js", "lib/rdoc/generator/template/json_index/js/searcher.js", "lib/rdoc/ghost_method.rb", "lib/rdoc/i18n.rb", "lib/rdoc/i18n/locale.rb", "lib/rdoc/i18n/text.rb", "lib/rdoc/include.rb", "lib/rdoc/known_classes.rb", "lib/rdoc/markdown.kpeg", "lib/rdoc/markdown/entities.rb", "lib/rdoc/markdown/literals.kpeg", "lib/rdoc/markdown/literals.rb", "lib/rdoc/markup.rb", "lib/rdoc/markup/attr_changer.rb", "lib/rdoc/markup/attr_span.rb", "lib/rdoc/markup/attribute_manager.rb", "lib/rdoc/markup/attributes.rb", "lib/rdoc/markup/blank_line.rb", "lib/rdoc/markup/block_quote.rb", "lib/rdoc/markup/document.rb", "lib/rdoc/markup/formatter.rb", "lib/rdoc/markup/formatter_test_case.rb", "lib/rdoc/markup/hard_break.rb", "lib/rdoc/markup/heading.rb", "lib/rdoc/markup/include.rb", "lib/rdoc/markup/indented_paragraph.rb", "lib/rdoc/markup/inline.rb", "lib/rdoc/markup/list.rb", "lib/rdoc/markup/list_item.rb", "lib/rdoc/markup/paragraph.rb", "lib/rdoc/markup/parser.rb", "lib/rdoc/markup/pre_process.rb", "lib/rdoc/markup/raw.rb", "lib/rdoc/markup/rule.rb", "lib/rdoc/markup/special.rb", "lib/rdoc/markup/text_formatter_test_case.rb", "lib/rdoc/markup/to_ansi.rb", "lib/rdoc/markup/to_bs.rb", "lib/rdoc/markup/to_html.rb", "lib/rdoc/markup/to_html_crossref.rb", "lib/rdoc/markup/to_html_snippet.rb", "lib/rdoc/markup/to_joined_paragraph.rb", "lib/rdoc/markup/to_label.rb", "lib/rdoc/markup/to_markdown.rb", "lib/rdoc/markup/to_rdoc.rb", "lib/rdoc/markup/to_table_of_contents.rb", "lib/rdoc/markup/to_test.rb", "lib/rdoc/markup/to_tt_only.rb", "lib/rdoc/markup/verbatim.rb", "lib/rdoc/meta_method.rb", "lib/rdoc/method_attr.rb", "lib/rdoc/mixin.rb", "lib/rdoc/normal_class.rb", "lib/rdoc/normal_module.rb", "lib/rdoc/options.rb", "lib/rdoc/parser.rb", "lib/rdoc/parser/c.rb", "lib/rdoc/parser/changelog.rb", "lib/rdoc/parser/markdown.rb", "lib/rdoc/parser/rd.rb", "lib/rdoc/parser/ripper_state_lex.rb", "lib/rdoc/parser/ruby.rb", "lib/rdoc/parser/ruby_tools.rb", "lib/rdoc/parser/simple.rb", "lib/rdoc/parser/text.rb", "lib/rdoc/rd.rb", "lib/rdoc/rd/block_parser.ry", "lib/rdoc/rd/inline.rb", "lib/rdoc/rd/inline_parser.ry", "lib/rdoc/rdoc.rb", "lib/rdoc/require.rb", "lib/rdoc/ri.rb", "lib/rdoc/ri/driver.rb", "lib/rdoc/ri/formatter.rb", "lib/rdoc/ri/paths.rb", "lib/rdoc/ri/store.rb", "lib/rdoc/ri/task.rb", "lib/rdoc/rubygems_hook.rb", "lib/rdoc/servlet.rb", "lib/rdoc/single_class.rb", "lib/rdoc/stats.rb", "lib/rdoc/stats/normal.rb", "lib/rdoc/stats/quiet.rb", "lib/rdoc/stats/verbose.rb", "lib/rdoc/store.rb", "lib/rdoc/task.rb", "lib/rdoc/test_case.rb", "lib/rdoc/text.rb", "lib/rdoc/token_stream.rb", "lib/rdoc/tom_doc.rb", "lib/rdoc/top_level.rb", "rdoc.gemspec"]
+ # for ruby core repository. It was generated by
+ # `git ls-files -z`.split("\x0").each {|f| puts " #{f.dump}," unless f.start_with?(*%W[test/ spec/ features/ .]) }
+ s.files = [
+ "CONTRIBUTING.rdoc",
+ "CVE-2013-0256.rdoc",
+ "ExampleMarkdown.md",
+ "ExampleRDoc.rdoc",
+ "Gemfile",
+ "History.rdoc",
+ "LEGAL.rdoc",
+ "LICENSE.rdoc",
+ "README.rdoc",
+ "RI.rdoc",
+ "Rakefile",
+ "TODO.rdoc",
+ "bin/console",
+ "bin/setup",
+ "exe/rdoc",
+ "exe/ri",
+ "lib/rdoc.rb",
+ "lib/rdoc/alias.rb",
+ "lib/rdoc/anon_class.rb",
+ "lib/rdoc/any_method.rb",
+ "lib/rdoc/attr.rb",
+ "lib/rdoc/class_module.rb",
+ "lib/rdoc/code_object.rb",
+ "lib/rdoc/code_objects.rb",
+ "lib/rdoc/comment.rb",
+ "lib/rdoc/constant.rb",
+ "lib/rdoc/context.rb",
+ "lib/rdoc/context/section.rb",
+ "lib/rdoc/cross_reference.rb",
+ "lib/rdoc/encoding.rb",
+ "lib/rdoc/erb_partial.rb",
+ "lib/rdoc/erbio.rb",
+ "lib/rdoc/extend.rb",
+ "lib/rdoc/generator.rb",
+ "lib/rdoc/generator/darkfish.rb",
+ "lib/rdoc/generator/json_index.rb",
+ "lib/rdoc/generator/markup.rb",
+ "lib/rdoc/generator/pot.rb",
+ "lib/rdoc/generator/pot/message_extractor.rb",
+ "lib/rdoc/generator/pot/po.rb",
+ "lib/rdoc/generator/pot/po_entry.rb",
+ "lib/rdoc/generator/ri.rb",
+ "lib/rdoc/generator/template/darkfish/.document",
+ "lib/rdoc/generator/template/darkfish/_footer.rhtml",
+ "lib/rdoc/generator/template/darkfish/_head.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml",
+ "lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml",
+ "lib/rdoc/generator/template/darkfish/class.rhtml",
+ "lib/rdoc/generator/template/darkfish/css/fonts.css",
+ "lib/rdoc/generator/template/darkfish/css/rdoc.css",
+ "lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf",
+ "lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf",
+ "lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf",
+ "lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf",
+ "lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf",
+ "lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf",
+ "lib/rdoc/generator/template/darkfish/images/add.png",
+ "lib/rdoc/generator/template/darkfish/images/arrow_up.png",
+ "lib/rdoc/generator/template/darkfish/images/brick.png",
+ "lib/rdoc/generator/template/darkfish/images/brick_link.png",
+ "lib/rdoc/generator/template/darkfish/images/bug.png",
+ "lib/rdoc/generator/template/darkfish/images/bullet_black.png",
+ "lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png",
+ "lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png",
+ "lib/rdoc/generator/template/darkfish/images/date.png",
+ "lib/rdoc/generator/template/darkfish/images/delete.png",
+ "lib/rdoc/generator/template/darkfish/images/find.png",
+ "lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif",
+ "lib/rdoc/generator/template/darkfish/images/macFFBgHack.png",
+ "lib/rdoc/generator/template/darkfish/images/package.png",
+ "lib/rdoc/generator/template/darkfish/images/page_green.png",
+ "lib/rdoc/generator/template/darkfish/images/page_white_text.png",
+ "lib/rdoc/generator/template/darkfish/images/page_white_width.png",
+ "lib/rdoc/generator/template/darkfish/images/plugin.png",
+ "lib/rdoc/generator/template/darkfish/images/ruby.png",
+ "lib/rdoc/generator/template/darkfish/images/tag_blue.png",
+ "lib/rdoc/generator/template/darkfish/images/tag_green.png",
+ "lib/rdoc/generator/template/darkfish/images/transparent.png",
+ "lib/rdoc/generator/template/darkfish/images/wrench.png",
+ "lib/rdoc/generator/template/darkfish/images/wrench_orange.png",
+ "lib/rdoc/generator/template/darkfish/images/zoom.png",
+ "lib/rdoc/generator/template/darkfish/index.rhtml",
+ "lib/rdoc/generator/template/darkfish/js/darkfish.js",
+ "lib/rdoc/generator/template/darkfish/js/search.js",
+ "lib/rdoc/generator/template/darkfish/page.rhtml",
+ "lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml",
+ "lib/rdoc/generator/template/darkfish/servlet_root.rhtml",
+ "lib/rdoc/generator/template/darkfish/table_of_contents.rhtml",
+ "lib/rdoc/generator/template/json_index/.document",
+ "lib/rdoc/generator/template/json_index/js/navigation.js",
+ "lib/rdoc/generator/template/json_index/js/searcher.js",
+ "lib/rdoc/ghost_method.rb",
+ "lib/rdoc/i18n.rb",
+ "lib/rdoc/i18n/locale.rb",
+ "lib/rdoc/i18n/text.rb",
+ "lib/rdoc/include.rb",
+ "lib/rdoc/known_classes.rb",
+ "lib/rdoc/markdown.kpeg",
+ "lib/rdoc/markdown/entities.rb",
+ "lib/rdoc/markdown/literals.kpeg",
+ "lib/rdoc/markup.rb",
+ "lib/rdoc/markup/attr_changer.rb",
+ "lib/rdoc/markup/attr_span.rb",
+ "lib/rdoc/markup/attribute_manager.rb",
+ "lib/rdoc/markup/attributes.rb",
+ "lib/rdoc/markup/blank_line.rb",
+ "lib/rdoc/markup/block_quote.rb",
+ "lib/rdoc/markup/document.rb",
+ "lib/rdoc/markup/formatter.rb",
+ "lib/rdoc/markup/hard_break.rb",
+ "lib/rdoc/markup/heading.rb",
+ "lib/rdoc/markup/include.rb",
+ "lib/rdoc/markup/indented_paragraph.rb",
+ "lib/rdoc/markup/list.rb",
+ "lib/rdoc/markup/list_item.rb",
+ "lib/rdoc/markup/paragraph.rb",
+ "lib/rdoc/markup/parser.rb",
+ "lib/rdoc/markup/pre_process.rb",
+ "lib/rdoc/markup/raw.rb",
+ "lib/rdoc/markup/regexp_handling.rb",
+ "lib/rdoc/markup/rule.rb",
+ "lib/rdoc/markup/table.rb",
+ "lib/rdoc/markup/to_ansi.rb",
+ "lib/rdoc/markup/to_bs.rb",
+ "lib/rdoc/markup/to_html.rb",
+ "lib/rdoc/markup/to_html_crossref.rb",
+ "lib/rdoc/markup/to_html_snippet.rb",
+ "lib/rdoc/markup/to_joined_paragraph.rb",
+ "lib/rdoc/markup/to_label.rb",
+ "lib/rdoc/markup/to_markdown.rb",
+ "lib/rdoc/markup/to_rdoc.rb",
+ "lib/rdoc/markup/to_table_of_contents.rb",
+ "lib/rdoc/markup/to_test.rb",
+ "lib/rdoc/markup/to_tt_only.rb",
+ "lib/rdoc/markup/verbatim.rb",
+ "lib/rdoc/meta_method.rb",
+ "lib/rdoc/method_attr.rb",
+ "lib/rdoc/mixin.rb",
+ "lib/rdoc/normal_class.rb",
+ "lib/rdoc/normal_module.rb",
+ "lib/rdoc/options.rb",
+ "lib/rdoc/parser.rb",
+ "lib/rdoc/parser/c.rb",
+ "lib/rdoc/parser/changelog.rb",
+ "lib/rdoc/parser/markdown.rb",
+ "lib/rdoc/parser/rd.rb",
+ "lib/rdoc/parser/ripper_state_lex.rb",
+ "lib/rdoc/parser/ruby.rb",
+ "lib/rdoc/parser/ruby_tools.rb",
+ "lib/rdoc/parser/simple.rb",
+ "lib/rdoc/parser/text.rb",
+ "lib/rdoc/rd.rb",
+ "lib/rdoc/rd/block_parser.ry",
+ "lib/rdoc/rd/inline.rb",
+ "lib/rdoc/rd/inline_parser.ry",
+ "lib/rdoc/rdoc.rb",
+ "lib/rdoc/require.rb",
+ "lib/rdoc/ri.rb",
+ "lib/rdoc/ri/driver.rb",
+ "lib/rdoc/ri/formatter.rb",
+ "lib/rdoc/ri/paths.rb",
+ "lib/rdoc/ri/store.rb",
+ "lib/rdoc/ri/task.rb",
+ "lib/rdoc/rubygems_hook.rb",
+ "lib/rdoc/servlet.rb",
+ "lib/rdoc/single_class.rb",
+ "lib/rdoc/stats.rb",
+ "lib/rdoc/stats/normal.rb",
+ "lib/rdoc/stats/quiet.rb",
+ "lib/rdoc/stats/verbose.rb",
+ "lib/rdoc/store.rb",
+ "lib/rdoc/task.rb",
+ "lib/rdoc/text.rb",
+ "lib/rdoc/token_stream.rb",
+ "lib/rdoc/tom_doc.rb",
+ "lib/rdoc/top_level.rb",
+ "lib/rdoc/version.rb",
+ "man/ri.1",
+ "rdoc.gemspec",
+ ]
# files from .gitignore
- s.files << "lib/rdoc/rd/block_parser.rb" << "lib/rdoc/rd/inline_parser.rb" << "lib/rdoc/markdown.rb"
+ s.files << "lib/rdoc/rd/block_parser.rb" << "lib/rdoc/rd/inline_parser.rb" << "lib/rdoc/markdown.rb" << "lib/rdoc/markdown/literals.rb"
s.rdoc_options = ["--main", "README.rdoc"]
s.extra_rdoc_files += %w[
@@ -51,13 +242,8 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat
TODO.rdoc
]
- s.required_ruby_version = Gem::Requirement.new(">= 2.2.2")
- s.rubygems_version = "2.5.2"
+ s.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
s.required_rubygems_version = Gem::Requirement.new(">= 2.2")
- s.add_development_dependency("rake")
- s.add_development_dependency("racc", "> 1.4.10")
- s.add_development_dependency("kpeg")
- s.add_development_dependency("minitest", "~> 4")
- s.add_development_dependency("json")
+ s.add_development_dependency("gettext")
end
diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
index adcb65b13b..6c69553588 100644
--- a/lib/rdoc/rdoc.rb
+++ b/lib/rdoc/rdoc.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'rdoc'
require 'find'
@@ -24,7 +24,7 @@ require 'time'
# rdoc.document argv
#
# Where +argv+ is an array of strings, each corresponding to an argument you'd
-# give rdoc on the command line. See <tt>rdoc --help<tt> for details.
+# give rdoc on the command line. See <tt>rdoc --help</tt> for details.
class RDoc::RDoc
@@ -36,11 +36,6 @@ class RDoc::RDoc
GENERATORS = {}
##
- # File pattern to exclude
-
- attr_accessor :exclude
-
- ##
# Generator instance used for creating output
attr_accessor :generator
@@ -93,7 +88,6 @@ class RDoc::RDoc
def initialize
@current = nil
- @exclude = nil
@generator = nil
@last_modified = {}
@old_siginfo = nil
@@ -116,13 +110,19 @@ class RDoc::RDoc
def gather_files files
files = ["."] if files.empty?
- file_list = normalized_file_list files, true, @exclude
+ file_list = normalized_file_list files, true, @options.exclude
- file_list = file_list.uniq
+ file_list = remove_unparseable(file_list)
- file_list = remove_unparseable file_list
-
- file_list.sort
+ if file_list.count {|name, mtime|
+ file_list[name] = @last_modified[name] unless mtime
+ mtime
+ } > 0
+ @last_modified.replace file_list
+ file_list.keys.sort
+ else
+ []
+ end
end
##
@@ -162,12 +162,20 @@ class RDoc::RDoc
RDoc.load_yaml
begin
- options = YAML.load_file '.rdoc_options'
+ options = YAML.safe_load_file '.rdoc_options', permitted_classes: [RDoc::Options, Symbol]
rescue Psych::SyntaxError
+ raise RDoc::Error, "#{options_file} is not a valid rdoc options file"
end
+ return RDoc::Options.new unless options # Allow empty file.
+
raise RDoc::Error, "#{options_file} is not a valid rdoc options file" unless
- RDoc::Options === options
+ RDoc::Options === options or Hash === options
+
+ if Hash === options
+ # Override the default values with the contents of YAML file.
+ options = RDoc::Options.new options
+ end
options
end
@@ -188,7 +196,7 @@ class RDoc::RDoc
error "#{dir} exists and is not a directory" unless File.directory? dir
begin
- open flag_file do |io|
+ File.open flag_file do |io|
unless force then
Time.parse io.gets
@@ -232,8 +240,11 @@ option)
def update_output_dir(op_dir, time, last = {})
return if @options.dry_run or not @options.update_output_dir
+ unless ENV['SOURCE_DATE_EPOCH'].nil?
+ time = Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime
+ end
- open output_flag_file(op_dir), "w" do |f|
+ File.open output_flag_file(op_dir), "w" do |f|
f.puts time.rfc2822
last.each do |n, t|
f.puts "#{n}\t#{t.rfc2822}"
@@ -257,11 +268,11 @@ option)
# read and strip comments
patterns = File.read(filename).gsub(/#.*/, '')
- result = []
+ result = {}
- patterns.split.each do |patt|
+ patterns.split(' ').each do |patt|
candidates = Dir.glob(File.join(in_dir, patt))
- result.concat normalized_file_list(candidates)
+ result.update normalized_file_list(candidates, false, @options.exclude)
end
result
@@ -281,21 +292,21 @@ option)
def normalized_file_list(relative_files, force_doc = false,
exclude_pattern = nil)
- file_list = []
+ file_list = {}
relative_files.each do |rel_file_name|
+ rel_file_name = rel_file_name.sub(/^\.\//, '')
next if rel_file_name.end_with? 'created.rid'
next if exclude_pattern && exclude_pattern =~ rel_file_name
stat = File.stat rel_file_name rescue next
case type = stat.ftype
when "file" then
- next if last_modified = @last_modified[rel_file_name] and
- stat.mtime.to_i <= last_modified.to_i
+ mtime = (stat.mtime unless (last_modified = @last_modified[rel_file_name] and
+ stat.mtime.to_i <= last_modified.to_i))
if force_doc or RDoc::Parser.can_parse(rel_file_name) then
- file_list << rel_file_name.sub(/^\.\//, '')
- @last_modified[rel_file_name] = stat.mtime
+ file_list[rel_file_name] = mtime
end
when "directory" then
next if rel_file_name == "CVS" || rel_file_name == ".svn"
@@ -306,16 +317,16 @@ option)
dot_doc = File.join rel_file_name, RDoc::DOT_DOC_FILENAME
if File.file? dot_doc then
- file_list << parse_dot_doc_file(rel_file_name, dot_doc)
+ file_list.update(parse_dot_doc_file(rel_file_name, dot_doc))
else
- file_list << list_files_in_directory(rel_file_name)
+ file_list.update(list_files_in_directory(rel_file_name))
end
else
warn "rdoc can't parse the #{type} #{rel_file_name}"
end
end
- file_list.flatten
+ file_list
end
##
@@ -358,7 +369,7 @@ option)
relative_path.relative_path_from @options.page_dir
end
- top_level = @store.add_file filename, relative_path.to_s
+ top_level = @store.add_file filename, relative_name: relative_path.to_s
parser = RDoc::Parser.for top_level, filename, content, @options, @stats
@@ -430,10 +441,10 @@ The internal error was:
# files for emacs and vim.
def remove_unparseable files
- files.reject do |file|
+ files.reject do |file, *|
file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or
(file =~ /tags$/i and
- open(file, 'rb') { |io|
+ File.open(file, 'rb') { |io|
io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/
})
end
@@ -469,8 +480,6 @@ The internal error was:
exit
end
- @exclude = @options.exclude
-
unless @options.coverage_report then
@last_modified = setup_output_dir @options.op_dir, @options.force_update
end
@@ -521,13 +530,18 @@ The internal error was:
# by the RDoc options
def generate
- Dir.chdir @options.op_dir do
- unless @options.quiet then
- $stderr.puts "\nGenerating #{@generator.class.name.sub(/^.*::/, '')} format into #{Dir.pwd}..."
- end
-
+ if @options.dry_run then
+ # do nothing
@generator.generate
- update_output_dir '.', @start_time, @last_modified
+ else
+ Dir.chdir @options.op_dir do
+ unless @options.quiet then
+ $stderr.puts "\nGenerating #{@generator.class.name.sub(/^.*::/, '')} format into #{Dir.pwd}..."
+ end
+
+ @generator.generate
+ update_output_dir '.', @start_time, @last_modified
+ end
end
end
@@ -561,6 +575,6 @@ rescue LoadError
end
# require built-in generators after discovery in case they've been replaced
-require 'rdoc/generator/darkfish'
-require 'rdoc/generator/ri'
-require 'rdoc/generator/pot'
+require_relative 'generator/darkfish'
+require_relative 'generator/ri'
+require_relative 'generator/pot'
diff --git a/lib/rdoc/require.rb b/lib/rdoc/require.rb
index f565ffad78..91f9c24e5d 100644
--- a/lib/rdoc/require.rb
+++ b/lib/rdoc/require.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A file loaded by \#require
diff --git a/lib/rdoc/ri.rb b/lib/rdoc/ri.rb
index 388cb12c70..c798c1fc49 100644
--- a/lib/rdoc/ri.rb
+++ b/lib/rdoc/ri.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'rdoc'
##
diff --git a/lib/rdoc/ri/driver.rb b/lib/rdoc/ri/driver.rb
index 51d633be58..a4b70b8f56 100644
--- a/lib/rdoc/ri/driver.rb
+++ b/lib/rdoc/ri/driver.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'abbrev'
require 'optparse'
@@ -17,7 +17,7 @@ require 'rdoc'
##
# For RubyGems backwards compatibility
-require 'rdoc/ri/formatter'
+require_relative 'formatter'
##
# The RI driver implements the command-line ri tool.
@@ -110,7 +110,7 @@ class RDoc::RI::Driver
def self.dump data_path
require 'pp'
- open data_path, 'rb' do |io|
+ File.open data_path, 'rb' do |io|
pp Marshal.load(io.read)
end
end
@@ -356,7 +356,7 @@ or the PAGER environment variable.
end
end
- argv = ENV['RI'].to_s.split.concat argv
+ argv = ENV['RI'].to_s.split(' ').concat argv
opts.parse! argv
@@ -425,6 +425,7 @@ or the PAGER environment variable.
@server = options[:server]
@use_stdout = options[:use_stdout]
@show_all = options[:show_all]
+ @width = options[:width]
# pager process for jruby
@jruby_pager_process = nil
@@ -795,7 +796,9 @@ or the PAGER environment variable.
def display document
page do |io|
- text = document.accept formatter(io)
+ f = formatter(io)
+ f.width = @width if @width and f.respond_to?(:width)
+ text = document.accept f
io.write text
end
@@ -1225,7 +1228,7 @@ or the PAGER environment variable.
# +cache+ indicate if it is a class or instance method.
def load_method store, cache, klass, type, name
- methods = store.send(cache)[klass]
+ methods = store.public_send(cache)[klass]
return unless methods
@@ -1440,7 +1443,13 @@ or the PAGER environment variable.
render_method_arguments out, method.arglists
render_method_superclass out, method
- render_method_comment out, method
+ if method.is_alias_for
+ al = method.is_alias_for
+ alias_for = store.load_method al.parent_name, "#{al.name_prefix}#{al.name}"
+ render_method_comment out, method, alias_for
+ else
+ render_method_comment out, method
+ end
end
def render_method_arguments out, arglists # :nodoc:
@@ -1452,10 +1461,22 @@ or the PAGER environment variable.
out << RDoc::Markup::Rule.new(1)
end
- def render_method_comment out, method # :nodoc:
- out << RDoc::Markup::BlankLine.new
- out << method.comment
- out << RDoc::Markup::BlankLine.new
+ def render_method_comment out, method, alias_for = nil# :nodoc:
+ if alias_for
+ unless method.comment.nil? or method.comment.empty?
+ out << RDoc::Markup::BlankLine.new
+ out << method.comment
+ end
+ out << RDoc::Markup::BlankLine.new
+ out << RDoc::Markup::Paragraph.new("(This method is an alias for #{alias_for.full_name}.)")
+ out << RDoc::Markup::BlankLine.new
+ out << alias_for.comment
+ out << RDoc::Markup::BlankLine.new
+ else
+ out << RDoc::Markup::BlankLine.new
+ out << method.comment
+ out << RDoc::Markup::BlankLine.new
+ end
end
def render_method_superclass out, method # :nodoc:
@@ -1500,7 +1521,7 @@ or the PAGER environment variable.
pagers.compact.uniq.each do |pager|
next unless pager
- pager_cmd = pager.split.first
+ pager_cmd = pager.split(' ').first
next unless in_path? pager_cmd
@@ -1530,7 +1551,11 @@ or the PAGER environment variable.
# Starts a WEBrick server for ri.
def start_server
- require 'webrick'
+ begin
+ require 'webrick'
+ rescue LoadError
+ abort "webrick is not found. You may need to `gem install webrick` to install webrick."
+ end
server = WEBrick::HTTPServer.new :Port => @server
diff --git a/lib/rdoc/ri/formatter.rb b/lib/rdoc/ri/formatter.rb
index d0c85dbe6b..832a101e6c 100644
--- a/lib/rdoc/ri/formatter.rb
+++ b/lib/rdoc/ri/formatter.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# For RubyGems backwards compatibility
diff --git a/lib/rdoc/ri/paths.rb b/lib/rdoc/ri/paths.rb
index 94db2216a2..8e89b04e54 100644
--- a/lib/rdoc/ri/paths.rb
+++ b/lib/rdoc/ri/paths.rb
@@ -1,5 +1,5 @@
-# frozen_string_literal: false
-require 'rdoc/ri'
+# frozen_string_literal: true
+require_relative '../rdoc'
##
# The directories where ri data lives. Paths can be enumerated via ::each, or
@@ -12,23 +12,9 @@ module RDoc::RI::Paths
version = RbConfig::CONFIG['ruby_version']
- BASE = if RbConfig::CONFIG.key? 'ridir' then
- File.join RbConfig::CONFIG['ridir'], version
- else
- File.join RbConfig::CONFIG['datadir'], 'ri', version
- end
+ BASE = File.join RbConfig::CONFIG['ridir'], version
- homedir = begin
- File.expand_path('~')
- rescue ArgumentError
- end
-
- homedir ||= ENV['HOME'] ||
- ENV['USERPROFILE'] || ENV['HOMEPATH'] # for 1.8 compatibility
-
- HOMEDIR = if homedir then
- File.join homedir, ".rdoc"
- end
+ HOMEDIR = RDoc.home
#:startdoc:
##
diff --git a/lib/rdoc/ri/store.rb b/lib/rdoc/ri/store.rb
index 66e234f521..9f4b03734a 100644
--- a/lib/rdoc/ri/store.rb
+++ b/lib/rdoc/ri/store.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
module RDoc::RI
Store = RDoc::Store # :nodoc:
diff --git a/lib/rdoc/ri/task.rb b/lib/rdoc/ri/task.rb
index cc0a85d4b7..1122ea3775 100644
--- a/lib/rdoc/ri/task.rb
+++ b/lib/rdoc/ri/task.rb
@@ -1,10 +1,10 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
begin
gem 'rdoc'
rescue Gem::LoadError
end unless defined?(RDoc)
-require 'rdoc/task'
+require_relative '../task'
##
# RDoc::RI::Task creates ri data in <code>./.rdoc</code> for your project.
diff --git a/lib/rdoc/rubygems_hook.rb b/lib/rdoc/rubygems_hook.rb
index e9351b7280..f4aa9655ae 100644
--- a/lib/rdoc/rubygems_hook.rb
+++ b/lib/rdoc/rubygems_hook.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'rubygems/user_interaction'
require 'fileutils'
require 'rdoc'
@@ -70,7 +70,7 @@ class RDoc::RubygemsHook
def self.load_rdoc
return if @rdoc_version
- require 'rdoc/rdoc'
+ require_relative 'rdoc'
@rdoc_version = Gem::Version.new ::RDoc::VERSION
end
@@ -158,7 +158,7 @@ class RDoc::RubygemsHook
case config_args = Gem.configuration[:rdoc]
when String then
- args = args.concat config_args.split
+ args = args.concat config_args.split(' ')
when Array then
args = args.concat config_args
end
diff --git a/lib/rdoc/servlet.rb b/lib/rdoc/servlet.rb
index dfc71436b8..0ab1eaf19d 100644
--- a/lib/rdoc/servlet.rb
+++ b/lib/rdoc/servlet.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'rdoc'
+require 'erb'
require 'time'
require 'json'
-require 'webrick'
+
+begin
+ require 'webrick'
+rescue LoadError
+ abort "webrick is not found. You may need to `gem install webrick` to install webrick."
+end
##
# This is a WEBrick servlet that allows you to browse ri documentation.
@@ -101,9 +107,9 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
res.body = File.read asset_path
res.content_type = case req.path
- when /css$/ then 'text/css'
- when /js$/ then 'application/javascript'
- else 'application/octet-stream'
+ when /\.css\z/ then 'text/css'
+ when /\.js\z/ then 'application/javascript'
+ else 'application/octet-stream'
end
end
@@ -111,7 +117,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
# GET request entry point. Fills in +res+ for the path, etc. in +req+.
def do_GET req, res
- req.path.sub!(/^#{Regexp.escape @mount_path}/o, '') if @mount_path
+ req.path.sub!(/\A#{Regexp.escape @mount_path}/, '') if @mount_path
case req.path
when '/' then
@@ -144,11 +150,14 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
# +generator+ is used to create the page.
def documentation_page store, generator, path, req, res
- name = path.sub(/.html$/, '').gsub '/', '::'
+ text_name = path.chomp '.html'
+ name = text_name.gsub '/', '::'
if klass = store.find_class_or_module(name) then
res.body = generator.generate_class klass
- elsif page = store.find_text_page(name.sub(/_([^_]*)$/, '.\1')) then
+ elsif page = store.find_text_page(name.sub(/_([^_]*)\z/, '.\1')) then
+ res.body = generator.generate_page page
+ elsif page = store.find_text_page(text_name.sub(/_([^_]*)\z/, '.\1')) then
res.body = generator.generate_page page
else
not_found generator, req, res
@@ -415,7 +424,7 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
RDoc::Store.new RDoc::RI::Paths.system_dir, :system
when 'site' then
RDoc::Store.new RDoc::RI::Paths.site_dir, :site
- when /^extra-(\d+)$/ then
+ when /\Aextra-(\d+)\z/ then
index = $1.to_i - 1
ri_dir = installed_docs[index][4]
RDoc::Store.new ri_dir, :extra
@@ -427,14 +436,14 @@ version. If you're viewing Ruby's documentation, include the version of ruby.
end
raise WEBrick::HTTPStatus::NotFound,
- "Could not find gem \"#{source_name}\". Are you sure you installed it?" unless ri_dir
+ "Could not find gem \"#{ERB::Util.html_escape(source_name)}\". Are you sure you installed it?" unless ri_dir
store = RDoc::Store.new ri_dir, type
return store if File.exist? store.cache_path
raise WEBrick::HTTPStatus::NotFound,
- "Could not find documentation for \"#{source_name}\". Please run `gem rdoc --ri gem_name`"
+ "Could not find documentation for \"#{ERB::Util.html_escape(source_name)}\". Please run `gem rdoc --ri gem_name`"
end
end
diff --git a/lib/rdoc/single_class.rb b/lib/rdoc/single_class.rb
index 7affa027e1..6a7b67deb3 100644
--- a/lib/rdoc/single_class.rb
+++ b/lib/rdoc/single_class.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A singleton class
diff --git a/lib/rdoc/stats.rb b/lib/rdoc/stats.rb
index 354e904b19..bd6c0ef23a 100644
--- a/lib/rdoc/stats.rb
+++ b/lib/rdoc/stats.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# RDoc statistics collector which prints a summary and report of a project's
# documentation totals.
diff --git a/lib/rdoc/stats/normal.rb b/lib/rdoc/stats/normal.rb
index 9f7ca59c34..0a22f0582b 100644
--- a/lib/rdoc/stats/normal.rb
+++ b/lib/rdoc/stats/normal.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
begin
require 'io/console/size'
rescue LoadError
@@ -26,28 +26,28 @@ class RDoc::Stats::Normal < RDoc::Stats::Quiet
files_so_far,
@num_files)
- # Print a progress bar, but make sure it fits on a single line. Filename
- # will be truncated if necessary.
- size = IO.respond_to?(:console_size) ? IO.console_size : IO.console.winsize
- terminal_width = size[1].to_i.nonzero? || 80
- max_filename_size = terminal_width - progress_bar.size
-
- if filename.size > max_filename_size then
- # Turn "some_long_filename.rb" to "...ong_filename.rb"
- filename = filename[(filename.size - max_filename_size) .. -1]
- filename[0..2] = "..."
- end
-
- line = "#{progress_bar}#{filename}"
if $stdout.tty?
+ # Print a progress bar, but make sure it fits on a single line. Filename
+ # will be truncated if necessary.
+ size = IO.respond_to?(:console_size) ? IO.console_size : IO.console.winsize
+ terminal_width = size[1].to_i.nonzero? || 80
+ max_filename_size = (terminal_width - progress_bar.size) - 1
+
+ if filename.size > max_filename_size then
+ # Turn "some_long_filename.rb" to "...ong_filename.rb"
+ filename = filename[(filename.size - max_filename_size) .. -1]
+ filename[0..2] = "..."
+ end
+
# Clean the line with whitespaces so that leftover output from the
# previous line doesn't show up.
- $stdout.print("\r" << (" " * @last_width) << ("\b" * @last_width) << "\r") if @last_width && @last_width > 0
- @last_width = line.size
- $stdout.print("#{line}\r")
+ $stdout.print("\r\e[K") if @last_width && @last_width > 0
+ @last_width = progress_bar.size + filename.size
+ term = "\r"
else
- $stdout.puts(line)
+ term = "\n"
end
+ $stdout.print(progress_bar, filename, term)
$stdout.flush
end
diff --git a/lib/rdoc/stats/quiet.rb b/lib/rdoc/stats/quiet.rb
index 561c272ef7..bc4161b2d4 100644
--- a/lib/rdoc/stats/quiet.rb
+++ b/lib/rdoc/stats/quiet.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Stats printer that prints nothing
diff --git a/lib/rdoc/stats/verbose.rb b/lib/rdoc/stats/verbose.rb
index e04edade52..6ace8937a2 100644
--- a/lib/rdoc/stats/verbose.rb
+++ b/lib/rdoc/stats/verbose.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# Stats printer that prints everything documented, including the documented
# status
diff --git a/lib/rdoc/store.rb b/lib/rdoc/store.rb
index aaefff8f13..c793e49ed8 100644
--- a/lib/rdoc/store.rb
+++ b/lib/rdoc/store.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'fileutils'
##
@@ -117,6 +117,11 @@ class RDoc::Store
attr_accessor :encoding
##
+ # The lazy constants alias will be discovered in passing
+
+ attr_reader :unmatched_constant_alias
+
+ ##
# Creates a new Store of +type+ that will load or save to +path+
def initialize path = nil, type = nil
@@ -143,6 +148,7 @@ class RDoc::Store
@classes_hash = {}
@modules_hash = {}
@files_hash = {}
+ @text_files_hash = {}
@c_enclosure_classes = {}
@c_enclosure_names = {}
@@ -152,6 +158,8 @@ class RDoc::Store
@unique_classes = nil
@unique_modules = nil
+
+ @unmatched_constant_alias = {}
end
##
@@ -177,16 +185,24 @@ class RDoc::Store
# Adds the file with +name+ as an RDoc::TopLevel to the store. Returns the
# created RDoc::TopLevel.
- def add_file absolute_name, relative_name = absolute_name
+ def add_file absolute_name, relative_name: absolute_name, parser: nil
unless top_level = @files_hash[relative_name] then
top_level = RDoc::TopLevel.new absolute_name, relative_name
+ top_level.parser = parser if parser
top_level.store = self
@files_hash[relative_name] = top_level
+ @text_files_hash[relative_name] = top_level if top_level.text?
end
top_level
end
+ def update_parser_of_file(absolute_name, parser)
+ if top_level = @files_hash[absolute_name] then
+ @text_files_hash[absolute_name] = top_level if top_level.text?
+ end
+ end
+
##
# Returns all classes discovered by RDoc
@@ -421,8 +437,8 @@ class RDoc::Store
# +file_name+
def find_text_page file_name
- @files_hash.each_value.find do |file|
- file.text? and file.full_name == file_name
+ @text_files_hash.each_value.find do |file|
+ file.full_name == file_name
end
end
@@ -466,7 +482,7 @@ class RDoc::Store
when :gem then
parent = File.expand_path '..', @path
"gem #{File.basename parent}"
- when :home then '~/.rdoc'
+ when :home then RDoc.home
when :site then 'ruby site'
when :system then 'ruby core'
else @path
@@ -530,6 +546,7 @@ class RDoc::Store
@cache[:pages].each do |page_name|
page = load_page page_name
@files_hash[page_name] = page
+ @text_files_hash[page_name] = page if page.text?
end
end
@@ -539,9 +556,7 @@ class RDoc::Store
def load_cache
#orig_enc = @encoding
- open cache_path, 'rb' do |io|
- @cache = Marshal.load io.read
- end
+ @cache = marshal_load(cache_path)
load_enc = @cache[:encoding]
@@ -585,6 +600,8 @@ class RDoc::Store
case obj
when RDoc::NormalClass then
@classes_hash[klass_name] = obj
+ when RDoc::SingleClass then
+ @classes_hash[klass_name] = obj
when RDoc::NormalModule then
@modules_hash[klass_name] = obj
end
@@ -596,9 +613,7 @@ class RDoc::Store
def load_class_data klass_name
file = class_file klass_name
- open file, 'rb' do |io|
- Marshal.load io.read
- end
+ marshal_load(file)
rescue Errno::ENOENT => e
error = MissingFileError.new(self, file, klass_name)
error.set_backtrace e.backtrace
@@ -611,14 +626,10 @@ class RDoc::Store
def load_method klass_name, method_name
file = method_file klass_name, method_name
- open file, 'rb' do |io|
- obj = Marshal.load io.read
- obj.store = self
- obj.parent =
- find_class_or_module(klass_name) || load_class(klass_name) unless
- obj.parent
- obj
- end
+ obj = marshal_load(file)
+ obj.store = self
+ obj.parent ||= find_class_or_module(klass_name) || load_class(klass_name)
+ obj
rescue Errno::ENOENT => e
error = MissingFileError.new(self, file, klass_name + method_name)
error.set_backtrace e.backtrace
@@ -631,11 +642,9 @@ class RDoc::Store
def load_page page_name
file = page_file page_name
- open file, 'rb' do |io|
- obj = Marshal.load io.read
- obj.store = self
- obj
- end
+ obj = marshal_load(file)
+ obj.store = self
+ obj
rescue Errno::ENOENT => e
error = MissingFileError.new(self, file, page_name)
error.set_backtrace e.backtrace
@@ -703,8 +712,8 @@ class RDoc::Store
# Returns the RDoc::TopLevel that is a text file and has the given +name+
def page name
- @files_hash.each_value.find do |file|
- file.text? and file.page_name == name
+ @text_files_hash.each_value.find do |file|
+ file.page_name == name or file.base_name == name
end
end
@@ -776,10 +785,8 @@ class RDoc::Store
return if @dry_run
- marshal = Marshal.dump @cache
-
- open cache_path, 'wb' do |io|
- io.write marshal
+ File.open cache_path, 'wb' do |io|
+ Marshal.dump @cache, io
end
end
@@ -852,10 +859,8 @@ class RDoc::Store
FileUtils.rm_f to_delete
- marshal = Marshal.dump klass
-
- open path, 'wb' do |io|
- io.write marshal
+ File.open path, 'wb' do |io|
+ Marshal.dump klass, io
end
end
@@ -877,10 +882,8 @@ class RDoc::Store
return if @dry_run
- marshal = Marshal.dump method
-
- open method_file(full_name, method.full_name), 'wb' do |io|
- io.write marshal
+ File.open method_file(full_name, method.full_name), 'wb' do |io|
+ Marshal.dump method, io
end
end
@@ -899,10 +902,8 @@ class RDoc::Store
return if @dry_run
- marshal = Marshal.dump page
-
- open path, 'wb' do |io|
- io.write marshal
+ File.open path, 'wb' do |io|
+ Marshal.dump page, io
end
end
@@ -965,4 +966,21 @@ class RDoc::Store
@unique_modules
end
+ private
+ def marshal_load(file)
+ File.open(file, 'rb') {|io| Marshal.load(io, MarshalFilter)}
+ end
+
+ MarshalFilter = proc do |obj|
+ case obj
+ when true, false, nil, Array, Class, Encoding, Hash, Integer, String, Symbol, RDoc::Text
+ else
+ unless obj.class.name.start_with?("RDoc::")
+ raise TypeError, "not permitted class: #{obj.class.name}"
+ end
+ end
+ obj
+ end
+ private_constant :MarshalFilter
+
end
diff --git a/lib/rdoc/task.rb b/lib/rdoc/task.rb
index 1074de0197..0bedaa50b0 100644
--- a/lib/rdoc/task.rb
+++ b/lib/rdoc/task.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
# Copyright (c) 2003, 2004 Jim Weirich, 2009 Eric Hodel
#
@@ -128,7 +128,7 @@ class RDoc::Task < Rake::TaskLib
attr_accessor :template
##
- # Name of format generator (<tt>--format<tt>) used by rdoc. (defaults to
+ # Name of format generator (<tt>--format</tt>) used by rdoc. (defaults to
# rdoc's default)
attr_accessor :generator
diff --git a/lib/rdoc/test_case.rb b/lib/rdoc/test_case.rb
deleted file mode 100644
index 594fb31272..0000000000
--- a/lib/rdoc/test_case.rb
+++ /dev/null
@@ -1,204 +0,0 @@
-# frozen_string_literal: false
-begin
- gem 'minitest', '~> 4.0' unless defined?(Test::Unit)
-rescue NoMethodError, Gem::LoadError
- # for ruby tests
-end
-
-require 'minitest/autorun'
-require 'minitest/benchmark' unless ENV['NOBENCHMARK']
-
-require 'fileutils'
-require 'pp'
-require 'tempfile'
-require 'tmpdir'
-require 'stringio'
-
-require 'rdoc'
-
-##
-# RDoc::TestCase is an abstract TestCase to provide common setup and teardown
-# across all RDoc tests. The test case uses minitest, so all the assertions
-# of minitest may be used.
-#
-# The testcase provides the following:
-#
-# * A reset code-object tree
-# * A reset markup preprocessor (RDoc::Markup::PreProcess)
-# * The <code>@RM</code> alias of RDoc::Markup (for less typing)
-# * <code>@pwd</code> containing the current working directory
-# * FileUtils, pp, Tempfile, Dir.tmpdir and StringIO
-
-class RDoc::TestCase < MiniTest::Unit::TestCase
-
- ##
- # Abstract test-case setup
-
- def setup
- super
-
- @top_level = nil
-
- @RM = RDoc::Markup
-
- RDoc::Markup::PreProcess.reset
-
- @pwd = Dir.pwd
-
- @store = RDoc::Store.new
-
- @rdoc = RDoc::RDoc.new
- @rdoc.store = @store
- @rdoc.options = RDoc::Options.new
-
- g = Object.new
- def g.class_dir() end
- def g.file_dir() end
- @rdoc.generator = g
- end
-
- ##
- # Asserts +path+ is a file
-
- def assert_file path
- assert File.file?(path), "#{path} is not a file"
- end
-
- ##
- # Asserts +path+ is a directory
-
- def assert_directory path
- assert File.directory?(path), "#{path} is not a directory"
- end
-
- ##
- # Refutes +path+ exists
-
- def refute_file path
- refute File.exist?(path), "#{path} exists"
- end
-
- ##
- # Shortcut for RDoc::Markup::BlankLine.new
-
- def blank_line
- @RM::BlankLine.new
- end
-
- ##
- # Shortcut for RDoc::Markup::BlockQuote.new with +contents+
-
- def block *contents
- @RM::BlockQuote.new(*contents)
- end
-
- ##
- # Creates an RDoc::Comment with +text+ which was defined on +top_level+.
- # By default the comment has the 'rdoc' format.
-
- def comment text, top_level = @top_level
- RDoc::Comment.new text, top_level
- end
-
- ##
- # Shortcut for RDoc::Markup::Document.new with +contents+
-
- def doc *contents
- @RM::Document.new(*contents)
- end
-
- ##
- # Shortcut for RDoc::Markup::HardBreak.new
-
- def hard_break
- @RM::HardBreak.new
- end
-
- ##
- # Shortcut for RDoc::Markup::Heading.new with +level+ and +text+
-
- def head level, text
- @RM::Heading.new level, text
- end
-
- ##
- # Shortcut for RDoc::Markup::ListItem.new with +label+ and +parts+
-
- def item label = nil, *parts
- @RM::ListItem.new label, *parts
- end
-
- ##
- # Shortcut for RDoc::Markup::List.new with +type+ and +items+
-
- def list type = nil, *items
- @RM::List.new type, *items
- end
-
- ##
- # Enables pretty-print output
-
- def mu_pp obj # :nodoc:
- s = ''
- s = PP.pp obj, s
- s = s.force_encoding Encoding.default_external
- s.chomp
- end
-
- ##
- # Shortcut for RDoc::Markup::Paragraph.new with +contents+
-
- def para *a
- @RM::Paragraph.new(*a)
- end
-
- ##
- # Shortcut for RDoc::Markup::Rule.new with +weight+
-
- def rule weight
- @RM::Rule.new weight
- end
-
- ##
- # Shortcut for RDoc::Markup::Raw.new with +contents+
-
- def raw *contents
- @RM::Raw.new(*contents)
- end
-
- ##
- # Creates a temporary directory changes the current directory to it for the
- # duration of the block.
- #
- # Depends upon Dir.mktmpdir
-
- def temp_dir
- Dir.mktmpdir do |temp_dir|
- Dir.chdir temp_dir do
- yield temp_dir
- end
- end
- end
-
- ##
- # Shortcut for RDoc::Markup::Verbatim.new with +parts+
-
- def verb *parts
- @RM::Verbatim.new(*parts)
- end
-
- ##
- # run capture_io with setting $VERBOSE = true
-
- def verbose_capture_io
- capture_io do
- begin
- orig_verbose = $VERBOSE
- $VERBOSE = true
- yield
- ensure
- $VERBOSE = orig_verbose
- end
- end
- end
-end
diff --git a/lib/rdoc/text.rb b/lib/rdoc/text.rb
index 88ff255f01..c3218fdb2f 100644
--- a/lib/rdoc/text.rb
+++ b/lib/rdoc/text.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# For RDoc::Text#to_html
@@ -10,6 +10,8 @@ require 'strscan'
module RDoc::Text
+ attr_accessor :language
+
##
# Maps markup formats to classes that can parse them. If the format is
# unknown, "rdoc" format is used.
@@ -60,7 +62,7 @@ module RDoc::Text
text.each_line do |line|
nil while line.gsub!(/(?:\G|\r)((?:.{8})*?)([^\t\r\n]{0,7})\t/) do
r = "#{$1}#{$2}#{' ' * (8 - $2.size)}"
- r.force_encoding text.encoding
+ r = RDoc::Encoding.change_encoding r, text.encoding
r
end
@@ -82,7 +84,7 @@ module RDoc::Text
end
empty = ''
- empty.force_encoding text.encoding
+ empty = RDoc::Encoding.change_encoding empty, text.encoding
text.gsub(/^ {0,#{indent}}/, empty)
end
@@ -111,8 +113,12 @@ module RDoc::Text
def normalize_comment text
return text if text.empty?
- text = strip_stars text
- text = strip_hashes text
+ case language
+ when :ruby
+ text = strip_hashes text
+ when :c
+ text = strip_stars text
+ end
text = expand_tabs text
text = flush_left text
text = strip_newlines text
@@ -149,7 +155,7 @@ module RDoc::Text
return text if text =~ /^(?>\s*)[^\#]/
empty = ''
- empty.force_encoding text.encoding
+ empty = RDoc::Encoding.change_encoding empty, text.encoding
text.gsub(/^\s*(#+)/) { $1.tr '#', ' ' }.gsub(/^\s+$/, empty)
end
@@ -169,17 +175,17 @@ module RDoc::Text
encoding = text.encoding
- text = text.gsub %r%Document-method:\s+[\w:.#=!?]+%, ''
+ text = text.gsub %r%Document-method:\s+[\w:.#=!?|^&<>~+\-/*\%@`\[\]]+%, ''
space = ' '
- space.force_encoding encoding if encoding
+ space = RDoc::Encoding.change_encoding space, encoding if encoding
text.sub! %r%/\*+% do space * $&.length end
text.sub! %r%\*+/% do space * $&.length end
text.gsub! %r%^[ \t]*\*%m do space * $&.length end
empty = ''
- empty.force_encoding encoding if encoding
+ empty = RDoc::Encoding.change_encoding empty, encoding if encoding
text.gsub(/^\s+$/, empty)
end
@@ -188,7 +194,7 @@ module RDoc::Text
# trademark symbols in +text+ to properly encoded characters.
def to_html text
- html = ''.encode text.encoding
+ html = (''.encode text.encoding).dup
encoded = RDoc::Text::TO_HTML_CHARACTERS[text.encoding]
diff --git a/lib/rdoc/token_stream.rb b/lib/rdoc/token_stream.rb
index 2b69e943cd..f428e2400c 100644
--- a/lib/rdoc/token_stream.rb
+++ b/lib/rdoc/token_stream.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A TokenStream is a list of tokens, gathered during the parse of some entity
# (say a method). Entities populate these streams by being registered with the
@@ -14,6 +14,8 @@ module RDoc::TokenStream
# with the given class names. Other token types are not wrapped in spans.
def self.to_html token_stream
+ starting_title = false
+
token_stream.map do |t|
next unless t
@@ -23,12 +25,8 @@ module RDoc::TokenStream
when :on_ivar then 'ruby-ivar'
when :on_cvar then 'ruby-identifier'
when :on_gvar then 'ruby-identifier'
- when '=' != t[:text] && :on_op then
- if RDoc::RipperStateLex::EXPR_ARG == t[:state] then
- 'ruby-identifier'
- else
- 'ruby-operator'
- end
+ when '=' != t[:text] && :on_op
+ then 'ruby-operator'
when :on_tlambda then 'ruby-operator'
when :on_ident then 'ruby-identifier'
when :on_label then 'ruby-value'
@@ -53,6 +51,16 @@ module RDoc::TokenStream
else
text = t[:text]
end
+
+ if :on_ident == t[:kind] && starting_title
+ starting_title = false
+ style = 'ruby-identifier ruby-title'
+ end
+
+ if :on_kw == t[:kind] and 'def' == t[:text]
+ starting_title = true
+ end
+
text = CGI.escapeHTML text
if style then
@@ -66,11 +74,16 @@ module RDoc::TokenStream
##
# Adds +tokens+ to the collected tokens
- def add_tokens(*tokens)
- tokens.flatten.each { |token| @token_stream << token }
+ def add_tokens(tokens)
+ @token_stream.concat(tokens)
end
- alias add_token add_tokens
+ ##
+ # Adds one +token+ to the collected tokens
+
+ def add_token(token)
+ @token_stream.push(token)
+ end
##
# Starts collecting tokens
@@ -99,7 +112,7 @@ module RDoc::TokenStream
# Returns a string representation of the token stream
def tokens_to_s
- token_stream.compact.map { |token| token.text }.join ''
+ token_stream.compact.map { |token| token[:text] }.join ''
end
end
diff --git a/lib/rdoc/tom_doc.rb b/lib/rdoc/tom_doc.rb
index d760849938..e161fcf42f 100644
--- a/lib/rdoc/tom_doc.rb
+++ b/lib/rdoc/tom_doc.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
# :markup: tomdoc
# A parser for TomDoc based on TomDoc 1.0.0-rc1 (02adef9b5a)
@@ -180,12 +180,19 @@ class RDoc::TomDoc < RDoc::Markup::Parser
case type
when :TEXT then
- @section = 'Returns' if data =~ /\AReturns/
+ @section = 'Returns' if data =~ /\A(Returns|Raises)/
paragraph << data
when :NEWLINE then
if :TEXT == peek_token[0] then
- paragraph << ' '
+ # Lines beginning with 'Raises' in the Returns section should not be
+ # treated as multiline text
+ if 'Returns' == @section and
+ peek_token[1].start_with?('Raises') then
+ break
+ else
+ paragraph << ' '
+ end
else
break
end
@@ -222,7 +229,7 @@ class RDoc::TomDoc < RDoc::Markup::Parser
# Returns self.
def tokenize text
- text.sub!(/\A(Public|Internal|Deprecated):\s+/, '')
+ text = text.sub(/\A(Public|Internal|Deprecated):\s+/, '')
setup_scanner text
@@ -235,19 +242,18 @@ class RDoc::TomDoc < RDoc::Markup::Parser
@tokens << case
when @s.scan(/\r?\n/) then
- token = [:NEWLINE, @s.matched, *token_pos(pos)]
- @line_pos = char_pos @s.pos
- @line += 1
+ token = [:NEWLINE, @s.matched, *pos]
+ @s.newline!
token
when @s.scan(/(Examples|Signature)$/) then
- @tokens << [:HEADER, 3, *token_pos(pos)]
+ @tokens << [:HEADER, 3, *pos]
- [:TEXT, @s[1], *token_pos(pos)]
+ [:TEXT, @s[1], *pos]
when @s.scan(/([:\w][\w\[\]]*)[ ]+- /) then
- [:NOTE, @s[1], *token_pos(pos)]
+ [:NOTE, @s[1], *pos]
else
@s.scan(/.*/)
- [:TEXT, @s.matched.sub(/\r$/, ''), *token_pos(pos)]
+ [:TEXT, @s.matched.sub(/\r$/, ''), *pos]
end
end
@@ -255,4 +261,3 @@ class RDoc::TomDoc < RDoc::Markup::Parser
end
end
-
diff --git a/lib/rdoc/top_level.rb b/lib/rdoc/top_level.rb
index 38be646ad0..b8b6110bb2 100644
--- a/lib/rdoc/top_level.rb
+++ b/lib/rdoc/top_level.rb
@@ -1,4 +1,4 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
##
# A TopLevel context is a representation of the contents of a single file
@@ -33,7 +33,7 @@ class RDoc::TopLevel < RDoc::Context
##
# The parser class that processed this file
- attr_accessor :parser
+ attr_reader :parser
##
# Creates a new TopLevel for the file at +absolute_name+. If documentation
@@ -52,6 +52,12 @@ class RDoc::TopLevel < RDoc::Context
@classes_or_modules = []
end
+ def parser=(val)
+ @parser = val
+ @store.update_parser_of_file(absolute_name, val) if @store
+ @parser
+ end
+
##
# An RDoc::TopLevel is equal to another with the same relative_name
@@ -272,7 +278,7 @@ class RDoc::TopLevel < RDoc::Context
# Is this TopLevel from a text file instead of a source code file?
def text?
- @parser and @parser.ancestors.include? RDoc::Parser::Text
+ @parser and @parser.include? RDoc::Parser::Text
end
def to_s # :nodoc:
diff --git a/lib/rdoc/version.rb b/lib/rdoc/version.rb
new file mode 100644
index 0000000000..8d6ae1012c
--- /dev/null
+++ b/lib/rdoc/version.rb
@@ -0,0 +1,8 @@
+module RDoc
+
+ ##
+ # RDoc version you are using
+
+ VERSION = '6.3.4.1'
+
+end
diff --git a/lib/readline.gemspec b/lib/readline.gemspec
new file mode 100644
index 0000000000..dddac020a4
--- /dev/null
+++ b/lib/readline.gemspec
@@ -0,0 +1,35 @@
+Gem::Specification.new do |spec|
+ spec.name = 'readline'
+ spec.version = '0.0.2'
+ spec.authors = ['aycabta']
+ spec.email = ['aycabta@gmail.com']
+
+ spec.summary = %q{It's a loader for "readline".}
+ spec.description = <<~EOD
+ This is just a loader for "readline". If Ruby has "readline-ext" gem that
+ is a native extension, this gem will load it first. If Ruby doesn't have
+ the "readline-ext" gem this gem will load "reline" that is a compatible
+ library with "readline-ext" gem and is implemented by pure Ruby.
+ EOD
+ spec.homepage = 'https://github.com/ruby/readline'
+ spec.license = 'Ruby'
+
+ spec.files = Dir['BSDL', 'COPYING', 'README.md', 'lib/readline.rb']
+ spec.require_paths = ['lib']
+
+ spec.post_install_message = <<~EOM
+ +---------------------------------------------------------------------------+
+ | This is just a loader for "readline". If Ruby has "readline-ext" gem that |
+ | is a native extension, this gem will load it first. If Ruby doesn't have |
+ | the "readline-ext" gem this gem will load "reline" that is a compatible   |
+ | library with "readline-ext" gem and is implemented by pure Ruby.          |
+ |                                                                           |
+ | If you intend to use GNU Readline by `require 'readline'`, please install |
+ | "readline-ext" gem.                                                       |
+ +---------------------------------------------------------------------------+
+ EOM
+
+ spec.add_runtime_dependency 'reline'
+ spec.add_development_dependency 'bundler'
+ spec.add_development_dependency 'rake'
+end
diff --git a/lib/readline.rb b/lib/readline.rb
new file mode 100644
index 0000000000..6cc923cb2f
--- /dev/null
+++ b/lib/readline.rb
@@ -0,0 +1,6 @@
+begin
+ require 'readline.so'
+rescue LoadError
+ require 'reline' unless defined? Reline
+ Readline = Reline
+end
diff --git a/lib/reline.rb b/lib/reline.rb
new file mode 100644
index 0000000000..a7bd4d9280
--- /dev/null
+++ b/lib/reline.rb
@@ -0,0 +1,471 @@
+require 'io/console'
+require 'timeout'
+require 'forwardable'
+require 'reline/version'
+require 'reline/config'
+require 'reline/key_actor'
+require 'reline/key_stroke'
+require 'reline/line_editor'
+require 'reline/history'
+require 'rbconfig'
+
+module Reline
+ FILENAME_COMPLETION_PROC = nil
+ USERNAME_COMPLETION_PROC = nil
+
+ Key = Struct.new('Key', :char, :combined_char, :with_meta)
+ CursorPos = Struct.new(:x, :y)
+
+ class Core
+ ATTR_READER_NAMES = %i(
+ completion_append_character
+ basic_word_break_characters
+ completer_word_break_characters
+ basic_quote_characters
+ completer_quote_characters
+ filename_quote_characters
+ special_prefixes
+ completion_proc
+ output_modifier_proc
+ prompt_proc
+ auto_indent_proc
+ pre_input_hook
+ dig_perfect_match_proc
+ ).each(&method(:attr_reader))
+
+ attr_accessor :config
+ attr_accessor :key_stroke
+ attr_accessor :line_editor
+ attr_accessor :last_incremental_search
+ attr_reader :output
+
+ def initialize
+ self.output = STDOUT
+ yield self
+ @completion_quote_character = nil
+ @bracketed_paste_finished = false
+ end
+
+ def encoding
+ Reline::IOGate.encoding
+ end
+
+ def completion_append_character=(val)
+ if val.nil?
+ @completion_append_character = nil
+ elsif val.size == 1
+ @completion_append_character = val.encode(Reline::IOGate.encoding)
+ elsif val.size > 1
+ @completion_append_character = val[0].encode(Reline::IOGate.encoding)
+ else
+ @completion_append_character = nil
+ end
+ end
+
+ def basic_word_break_characters=(v)
+ @basic_word_break_characters = v.encode(Reline::IOGate.encoding)
+ end
+
+ def completer_word_break_characters=(v)
+ @completer_word_break_characters = v.encode(Reline::IOGate.encoding)
+ end
+
+ def basic_quote_characters=(v)
+ @basic_quote_characters = v.encode(Reline::IOGate.encoding)
+ end
+
+ def completer_quote_characters=(v)
+ @completer_quote_characters = v.encode(Reline::IOGate.encoding)
+ end
+
+ def filename_quote_characters=(v)
+ @filename_quote_characters = v.encode(Reline::IOGate.encoding)
+ end
+
+ def special_prefixes=(v)
+ @special_prefixes = v.encode(Reline::IOGate.encoding)
+ end
+
+ def completion_case_fold=(v)
+ @config.completion_ignore_case = v
+ end
+
+ def completion_case_fold
+ @config.completion_ignore_case
+ end
+
+ def completion_quote_character
+ @completion_quote_character
+ end
+
+ def completion_proc=(p)
+ raise ArgumentError unless p.respond_to?(:call) or p.nil?
+ @completion_proc = p
+ end
+
+ def output_modifier_proc=(p)
+ raise ArgumentError unless p.respond_to?(:call) or p.nil?
+ @output_modifier_proc = p
+ end
+
+ def prompt_proc=(p)
+ raise ArgumentError unless p.respond_to?(:call) or p.nil?
+ @prompt_proc = p
+ end
+
+ def auto_indent_proc=(p)
+ raise ArgumentError unless p.respond_to?(:call) or p.nil?
+ @auto_indent_proc = p
+ end
+
+ def pre_input_hook=(p)
+ @pre_input_hook = p
+ end
+
+ def dig_perfect_match_proc=(p)
+ raise ArgumentError unless p.respond_to?(:call) or p.nil?
+ @dig_perfect_match_proc = p
+ end
+
+ def input=(val)
+ raise TypeError unless val.respond_to?(:getc) or val.nil?
+ if val.respond_to?(:getc)
+ if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
+ Reline::ANSI.input = val
+ elsif Reline::IOGate == Reline::GeneralIO
+ Reline::GeneralIO.input = val
+ end
+ end
+ end
+
+ def output=(val)
+ raise TypeError unless val.respond_to?(:write) or val.nil?
+ @output = val
+ if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
+ Reline::ANSI.output = val
+ end
+ end
+
+ def vi_editing_mode
+ config.editing_mode = :vi_insert
+ nil
+ end
+
+ def emacs_editing_mode
+ config.editing_mode = :emacs
+ nil
+ end
+
+ def vi_editing_mode?
+ config.editing_mode_is?(:vi_insert, :vi_command)
+ end
+
+ def emacs_editing_mode?
+ config.editing_mode_is?(:emacs)
+ end
+
+ def get_screen_size
+ Reline::IOGate.get_screen_size
+ end
+
+ def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
+ unless confirm_multiline_termination
+ raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
+ end
+ inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
+
+ whole_buffer = line_editor.whole_buffer.dup
+ whole_buffer.taint if RUBY_VERSION < '2.7'
+ if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
+ Reline::HISTORY << whole_buffer
+ end
+
+ line_editor.reset_line if line_editor.whole_buffer.nil?
+ whole_buffer
+ end
+
+ def readline(prompt = '', add_hist = false)
+ inner_readline(prompt, add_hist, false)
+
+ line = line_editor.line.dup
+ line.taint if RUBY_VERSION < '2.7'
+ if add_hist and line and line.chomp("\n").size > 0
+ Reline::HISTORY << line.chomp("\n")
+ end
+
+ line_editor.reset_line if line_editor.line.nil?
+ line
+ end
+
+ private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
+ if ENV['RELINE_STDERR_TTY']
+ if Reline::IOGate.win?
+ $stderr = File.open(ENV['RELINE_STDERR_TTY'], 'a')
+ else
+ $stderr.reopen(ENV['RELINE_STDERR_TTY'], 'w')
+ end
+ $stderr.sync = true
+ $stderr.puts "Reline is used by #{Process.pid}"
+ end
+ otio = Reline::IOGate.prep
+
+ may_req_ambiguous_char_width
+ line_editor.reset(prompt, encoding: Reline::IOGate.encoding)
+ if multiline
+ line_editor.multiline_on
+ if block_given?
+ line_editor.confirm_multiline_termination_proc = confirm_multiline_termination
+ end
+ else
+ line_editor.multiline_off
+ end
+ line_editor.output = output
+ line_editor.completion_proc = completion_proc
+ line_editor.completion_append_character = completion_append_character
+ line_editor.output_modifier_proc = output_modifier_proc
+ line_editor.prompt_proc = prompt_proc
+ line_editor.auto_indent_proc = auto_indent_proc
+ line_editor.dig_perfect_match_proc = dig_perfect_match_proc
+ line_editor.pre_input_hook = pre_input_hook
+
+ unless config.test_mode
+ config.read
+ config.reset_default_key_bindings
+ Reline::IOGate::RAW_KEYSTROKE_CONFIG.each_pair do |key, func|
+ config.add_default_key_binding(key, func)
+ end
+ end
+
+ line_editor.rerender
+
+ begin
+ prev_pasting_state = false
+ loop do
+ prev_pasting_state = Reline::IOGate.in_pasting?
+ read_io(config.keyseq_timeout) { |inputs|
+ line_editor.set_pasting_state(Reline::IOGate.in_pasting?)
+ inputs.each { |c|
+ line_editor.input_key(c)
+ line_editor.rerender
+ }
+ if @bracketed_paste_finished
+ line_editor.rerender_all
+ @bracketed_paste_finished = false
+ end
+ }
+ if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished?
+ line_editor.set_pasting_state(false)
+ prev_pasting_state = false
+ line_editor.rerender_all
+ end
+ break if line_editor.finished?
+ end
+ Reline::IOGate.move_cursor_column(0)
+ rescue Errno::EIO
+ # Maybe the I/O has been closed.
+ rescue StandardError => e
+ line_editor.finalize
+ Reline::IOGate.deprep(otio)
+ raise e
+ end
+
+ line_editor.finalize
+ Reline::IOGate.deprep(otio)
+ end
+
+ # Keystrokes of GNU Readline will timeout it with the specification of
+ # "keyseq-timeout" when waiting for the 2nd character after the 1st one.
+ # If the 2nd character comes after 1st ESC without timeout it has a
+ # meta-property of meta-key to discriminate modified key with meta-key
+ # from multibyte characters that come with 8th bit on.
+ #
+ # GNU Readline will wait for the 2nd character with "keyseq-timeout"
+ # milli-seconds but wait forever after 3rd characters.
+ private def read_io(keyseq_timeout, &block)
+ buffer = []
+ loop do
+ c = Reline::IOGate.getc
+ if c == -1
+ result = :unmatched
+ @bracketed_paste_finished = true
+ else
+ buffer << c
+ result = key_stroke.match_status(buffer)
+ end
+ case result
+ when :matched
+ expanded = key_stroke.expand(buffer).map{ |expanded_c|
+ Reline::Key.new(expanded_c, expanded_c, false)
+ }
+ block.(expanded)
+ break
+ when :matching
+ if buffer.size == 1
+ begin
+ succ_c = nil
+ Timeout.timeout(keyseq_timeout / 1000.0) {
+ succ_c = Reline::IOGate.getc
+ }
+ rescue Timeout::Error # cancel matching only when first byte
+ block.([Reline::Key.new(c, c, false)])
+ break
+ else
+ if key_stroke.match_status(buffer.dup.push(succ_c)) == :unmatched
+ if c == "\e".ord
+ block.([Reline::Key.new(succ_c, succ_c | 0b10000000, true)])
+ else
+ block.([Reline::Key.new(c, c, false), Reline::Key.new(succ_c, succ_c, false)])
+ end
+ break
+ else
+ Reline::IOGate.ungetc(succ_c)
+ end
+ end
+ end
+ when :unmatched
+ if buffer.size == 1 and c == "\e".ord
+ read_escaped_key(keyseq_timeout, c, block)
+ else
+ expanded = buffer.map{ |expanded_c|
+ Reline::Key.new(expanded_c, expanded_c, false)
+ }
+ block.(expanded)
+ end
+ break
+ end
+ end
+ end
+
+ private def read_escaped_key(keyseq_timeout, c, block)
+ begin
+ escaped_c = nil
+ Timeout.timeout(keyseq_timeout / 1000.0) {
+ escaped_c = Reline::IOGate.getc
+ }
+ rescue Timeout::Error # independent ESC
+ block.([Reline::Key.new(c, c, false)])
+ else
+ if escaped_c.nil?
+ block.([Reline::Key.new(c, c, false)])
+ elsif escaped_c >= 128 # maybe, first byte of multi byte
+ block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
+ elsif escaped_c == "\e".ord # escape twice
+ block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
+ else
+ block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
+ end
+ end
+ end
+
+ def ambiguous_width
+ may_req_ambiguous_char_width unless defined? @ambiguous_width
+ @ambiguous_width
+ end
+
+ private def may_req_ambiguous_char_width
+ @ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
+ return if @ambiguous_width
+ Reline::IOGate.move_cursor_column(0)
+ begin
+ output.write "\u{25bd}"
+ rescue Encoding::UndefinedConversionError
+ # LANG=C
+ @ambiguous_width = 1
+ else
+ @ambiguous_width = Reline::IOGate.cursor_pos.x
+ end
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
+ end
+ end
+
+ extend Forwardable
+ extend SingleForwardable
+
+ #--------------------------------------------------------
+ # Documented API
+ #--------------------------------------------------------
+
+ (Core::ATTR_READER_NAMES).each { |name|
+ def_single_delegators :core, "#{name}", "#{name}="
+ }
+ def_single_delegators :core, :input=, :output=
+ def_single_delegators :core, :vi_editing_mode, :emacs_editing_mode
+ def_single_delegators :core, :readline
+ def_single_delegators :core, :completion_case_fold, :completion_case_fold=
+ def_single_delegators :core, :completion_quote_character
+ def_instance_delegators self, :readline
+ private :readline
+
+
+ #--------------------------------------------------------
+ # Undocumented API
+ #--------------------------------------------------------
+
+ # Testable in original
+ def_single_delegators :core, :get_screen_size
+ def_single_delegators :line_editor, :eof?
+ def_instance_delegators self, :eof?
+ def_single_delegators :line_editor, :delete_text
+ def_single_delegator :line_editor, :line, :line_buffer
+ def_single_delegator :line_editor, :byte_pointer, :point
+ def_single_delegator :line_editor, :byte_pointer=, :point=
+
+ def self.insert_text(*args, &block)
+ line_editor.insert_text(*args, &block)
+ self
+ end
+
+ # Untestable in original
+ def_single_delegator :line_editor, :rerender, :redisplay
+ def_single_delegators :core, :vi_editing_mode?, :emacs_editing_mode?
+ def_single_delegators :core, :ambiguous_width
+ def_single_delegators :core, :last_incremental_search
+ def_single_delegators :core, :last_incremental_search=
+
+ def_single_delegators :core, :readmultiline
+ def_instance_delegators self, :readmultiline
+ private :readmultiline
+
+ def self.encoding_system_needs
+ self.core.encoding
+ end
+
+ def self.core
+ @core ||= Core.new { |core|
+ core.config = Reline::Config.new
+ core.key_stroke = Reline::KeyStroke.new(core.config)
+ core.line_editor = Reline::LineEditor.new(core.config, Reline::IOGate.encoding)
+
+ core.basic_word_break_characters = " \t\n`><=;|&{("
+ core.completer_word_break_characters = " \t\n`><=;|&{("
+ core.basic_quote_characters = '"\''
+ core.completer_quote_characters = '"\''
+ core.filename_quote_characters = ""
+ core.special_prefixes = ""
+ }
+ end
+
+ def self.ungetc(c)
+ Reline::IOGate.ungetc(c)
+ end
+
+ def self.line_editor
+ core.line_editor
+ end
+end
+
+if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
+ require 'reline/windows'
+ if Reline::Windows.msys_tty?
+ require 'reline/ansi'
+ Reline::IOGate = Reline::ANSI
+ else
+ Reline::IOGate = Reline::Windows
+ end
+else
+ require 'reline/ansi'
+ Reline::IOGate = Reline::ANSI
+end
+Reline::HISTORY = Reline::History.new(Reline.core.config)
+require 'reline/general_io'
diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb
new file mode 100644
index 0000000000..b2d7e7d910
--- /dev/null
+++ b/lib/reline/ansi.rb
@@ -0,0 +1,259 @@
+require 'io/console'
+require 'timeout'
+
+class Reline::ANSI
+ def self.encoding
+ Encoding.default_external
+ end
+
+ def self.win?
+ false
+ end
+
+ RAW_KEYSTROKE_CONFIG = {
+ # Console (80x25)
+ [27, 91, 49, 126] => :ed_move_to_beg, # Home
+ [27, 91, 52, 126] => :ed_move_to_end, # End
+ [27, 91, 51, 126] => :key_delete, # Del
+ [27, 91, 65] => :ed_prev_history, # ↑
+ [27, 91, 66] => :ed_next_history, # ↓
+ [27, 91, 67] => :ed_next_char, # →
+ [27, 91, 68] => :ed_prev_char, # â†
+
+ # KDE
+ [27, 91, 72] => :ed_move_to_beg, # Home
+ [27, 91, 70] => :ed_move_to_end, # End
+ # Del is 0x08
+ [27, 71, 65] => :ed_prev_history, # ↑
+ [27, 71, 66] => :ed_next_history, # ↓
+ [27, 71, 67] => :ed_next_char, # →
+ [27, 71, 68] => :ed_prev_char, # â†
+
+ # urxvt / exoterm
+ [27, 91, 55, 126] => :ed_move_to_beg, # Home
+ [27, 91, 56, 126] => :ed_move_to_end, # End
+
+ # GNOME
+ [27, 79, 72] => :ed_move_to_beg, # Home
+ [27, 79, 70] => :ed_move_to_end, # End
+ # Del is 0x08
+ # Arrow keys are the same of KDE
+
+ # iTerm2
+ [27, 27, 91, 67] => :em_next_word, # Option+→
+ [27, 27, 91, 68] => :ed_prev_word, # Option+â†
+ [195, 166] => :em_next_word, # Option+f
+ [195, 162] => :ed_prev_word, # Option+b
+
+ # others
+ [27, 32] => :em_set_mark, # M-<space>
+ [24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
+ [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
+ [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+â†
+
+ [27, 79, 65] => :ed_prev_history, # ↑
+ [27, 79, 66] => :ed_next_history, # ↓
+ [27, 79, 67] => :ed_next_char, # →
+ [27, 79, 68] => :ed_prev_char, # â†
+ }
+
+ @@input = STDIN
+ def self.input=(val)
+ @@input = val
+ end
+
+ @@output = STDOUT
+ def self.output=(val)
+ @@output = val
+ end
+
+ @@buf = []
+ def self.inner_getc
+ unless @@buf.empty?
+ return @@buf.shift
+ end
+ until c = @@input.raw(intr: true, &:getbyte)
+ sleep 0.1
+ end
+ (c == 0x16 && @@input.raw(min: 0, tim: 0, &:getbyte)) || c
+ rescue Errno::EIO
+ # Maybe the I/O has been closed.
+ nil
+ end
+
+ @@in_bracketed_paste_mode = false
+ START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
+ END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
+ def self.getc_with_bracketed_paste
+ buffer = String.new(encoding: Encoding::ASCII_8BIT)
+ buffer << inner_getc
+ while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
+ if START_BRACKETED_PASTE == buffer
+ @@in_bracketed_paste_mode = true
+ return inner_getc
+ elsif END_BRACKETED_PASTE == buffer
+ @@in_bracketed_paste_mode = false
+ ungetc(-1)
+ return inner_getc
+ end
+ begin
+ succ_c = nil
+ Timeout.timeout(Reline.core.config.keyseq_timeout * 100) {
+ succ_c = inner_getc
+ }
+ rescue Timeout::Error
+ break
+ else
+ buffer << succ_c
+ end
+ end
+ buffer.bytes.reverse_each do |ch|
+ ungetc ch
+ end
+ inner_getc
+ end
+
+ def self.getc
+ if Reline.core.config.enable_bracketed_paste
+ getc_with_bracketed_paste
+ else
+ inner_getc
+ end
+ end
+
+ def self.in_pasting?
+ @@in_bracketed_paste_mode or (not Reline::IOGate.empty_buffer?)
+ end
+
+ def self.empty_buffer?
+ unless @@buf.empty?
+ return false
+ end
+ rs, = IO.select([@@input], [], [], 0.00001)
+ if rs and rs[0]
+ false
+ else
+ true
+ end
+ end
+
+ def self.ungetc(c)
+ @@buf.unshift(c)
+ end
+
+ def self.retrieve_keybuffer
+ begin
+ result = select([@@input], [], [], 0.001)
+ return if result.nil?
+ str = @@input.read_nonblock(1024)
+ str.bytes.each do |c|
+ @@buf.push(c)
+ end
+ rescue EOFError
+ end
+ end
+
+ def self.get_screen_size
+ s = @@input.winsize
+ return s if s[0] > 0 && s[1] > 0
+ s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
+ return s if s[0] > 0 && s[1] > 0
+ [24, 80]
+ rescue Errno::ENOTTY
+ [24, 80]
+ end
+
+ def self.set_screen_size(rows, columns)
+ @@input.winsize = [rows, columns]
+ self
+ rescue Errno::ENOTTY
+ self
+ end
+
+ def self.cursor_pos
+ begin
+ res = +''
+ m = nil
+ @@input.raw do |stdin|
+ @@output << "\e[6n"
+ @@output.flush
+ loop do
+ c = stdin.getc
+ next if c.nil?
+ res << c
+ m = res.match(/\e\[(?<row>\d+);(?<column>\d+)R/)
+ break if m
+ end
+ (m.pre_match + m.post_match).chars.reverse_each do |ch|
+ stdin.ungetc ch
+ end
+ end
+ column = m[:column].to_i - 1
+ row = m[:row].to_i - 1
+ rescue Errno::ENOTTY
+ begin
+ buf = @@output.pread(@@output.pos, 0)
+ row = buf.count("\n")
+ column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
+ rescue Errno::ESPIPE
+ # Just returns column 1 for ambiguous width because this I/O is not
+ # tty and can't seek.
+ row = 0
+ column = 1
+ end
+ end
+ Reline::CursorPos.new(column, row)
+ end
+
+ def self.move_cursor_column(x)
+ @@output.write "\e[#{x + 1}G"
+ end
+
+ def self.move_cursor_up(x)
+ if x > 0
+ @@output.write "\e[#{x}A" if x > 0
+ elsif x < 0
+ move_cursor_down(-x)
+ end
+ end
+
+ def self.move_cursor_down(x)
+ if x > 0
+ @@output.write "\e[#{x}B" if x > 0
+ elsif x < 0
+ move_cursor_up(-x)
+ end
+ end
+
+ def self.erase_after_cursor
+ @@output.write "\e[K"
+ end
+
+ def self.scroll_down(x)
+ return if x.zero?
+ @@output.write "\e[#{x}S"
+ end
+
+ def self.clear_screen
+ @@output.write "\e[2J"
+ @@output.write "\e[1;1H"
+ end
+
+ @@old_winch_handler = nil
+ def self.set_winch_handler(&handler)
+ @@old_winch_handler = Signal.trap('WINCH', &handler)
+ end
+
+ def self.prep
+ retrieve_keybuffer
+ int_handle = Signal.trap('INT', 'IGNORE')
+ Signal.trap('INT', int_handle)
+ nil
+ end
+
+ def self.deprep(otio)
+ int_handle = Signal.trap('INT', 'IGNORE')
+ Signal.trap('INT', int_handle)
+ Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
+ end
+end
diff --git a/lib/reline/config.rb b/lib/reline/config.rb
new file mode 100644
index 0000000000..63ab7b7402
--- /dev/null
+++ b/lib/reline/config.rb
@@ -0,0 +1,347 @@
+class Reline::Config
+ attr_reader :test_mode
+
+ KEYSEQ_PATTERN = /\\(?:C|Control)-[A-Za-z_]|\\(?:M|Meta)-[0-9A-Za-z_]|\\(?:C|Control)-(?:M|Meta)-[A-Za-z_]|\\(?:M|Meta)-(?:C|Control)-[A-Za-z_]|\\e|\\[\\\"\'abdfnrtv]|\\\d{1,3}|\\x\h{1,2}|./
+
+ class InvalidInputrc < RuntimeError
+ attr_accessor :file, :lineno
+ end
+
+ VARIABLE_NAMES = %w{
+ bind-tty-special-chars
+ blink-matching-paren
+ byte-oriented
+ completion-ignore-case
+ convert-meta
+ disable-completion
+ enable-keypad
+ expand-tilde
+ history-preserve-point
+ history-size
+ horizontal-scroll-mode
+ input-meta
+ keyseq-timeout
+ mark-directories
+ mark-modified-lines
+ mark-symlinked-directories
+ match-hidden-files
+ meta-flag
+ output-meta
+ page-completions
+ prefer-visible-bell
+ print-completions-horizontally
+ show-all-if-ambiguous
+ show-all-if-unmodified
+ visible-stats
+ show-mode-in-prompt
+ vi-cmd-mode-string
+ vi-ins-mode-string
+ emacs-mode-string
+ enable-bracketed-paste
+ isearch-terminators
+ }
+ VARIABLE_NAME_SYMBOLS = VARIABLE_NAMES.map { |v| :"#{v.tr(?-, ?_)}" }
+ VARIABLE_NAME_SYMBOLS.each do |v|
+ attr_accessor v
+ end
+
+ def initialize
+ @additional_key_bindings = {} # from inputrc
+ @default_key_bindings = {} # environment-dependent
+ @skip_section = nil
+ @if_stack = nil
+ @editing_mode_label = :emacs
+ @keymap_label = :emacs
+ @key_actors = {}
+ @key_actors[:emacs] = Reline::KeyActor::Emacs.new
+ @key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
+ @key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
+ @vi_cmd_mode_string = '(cmd)'
+ @vi_ins_mode_string = '(ins)'
+ @emacs_mode_string = '@'
+ # https://tiswww.case.edu/php/chet/readline/readline.html#IDX25
+ @history_size = -1 # unlimited
+ @keyseq_timeout = 500
+ @test_mode = false
+ end
+
+ def reset
+ if editing_mode_is?(:vi_command)
+ @editing_mode_label = :vi_insert
+ end
+ @additional_key_bindings = {}
+ @default_key_bindings = {}
+ end
+
+ def editing_mode
+ @key_actors[@editing_mode_label]
+ end
+
+ def editing_mode=(val)
+ @editing_mode_label = val
+ end
+
+ def editing_mode_is?(*val)
+ (val.respond_to?(:any?) ? val : [val]).any?(@editing_mode_label)
+ end
+
+ def keymap
+ @key_actors[@keymap_label]
+ end
+
+ def inputrc_path
+ case ENV['INPUTRC']
+ when nil, ''
+ else
+ return File.expand_path(ENV['INPUTRC'])
+ end
+
+ # In the XDG Specification, if ~/.config/readline/inputrc exists, then
+ # ~/.inputrc should not be read, but for compatibility with GNU Readline,
+ # if ~/.inputrc exists, then it is given priority.
+ home_rc_path = File.expand_path('~/.inputrc')
+ return home_rc_path if File.exist?(home_rc_path)
+
+ case path = ENV['XDG_CONFIG_HOME']
+ when nil, ''
+ else
+ path = File.join(path, 'readline/inputrc')
+ return path if File.exist?(path) and path == File.expand_path(path)
+ end
+
+ path = File.expand_path('~/.config/readline/inputrc')
+ return path if File.exist?(path)
+
+ return home_rc_path
+ end
+
+ def read(file = nil)
+ file ||= inputrc_path
+ begin
+ if file.respond_to?(:readlines)
+ lines = file.readlines
+ else
+ lines = File.readlines(file)
+ end
+ rescue Errno::ENOENT
+ return nil
+ end
+
+ read_lines(lines, file)
+ self
+ rescue InvalidInputrc => e
+ warn e.message
+ nil
+ end
+
+ def key_bindings
+ # override @default_key_bindings with @additional_key_bindings
+ @default_key_bindings.merge(@additional_key_bindings)
+ end
+
+ def add_default_key_binding(keystroke, target)
+ @default_key_bindings[keystroke] = target
+ end
+
+ def reset_default_key_bindings
+ @default_key_bindings = {}
+ end
+
+ def read_lines(lines, file = nil)
+ conditions = [@skip_section, @if_stack]
+ @skip_section = nil
+ @if_stack = []
+
+ lines.each_with_index do |line, no|
+ next if line.match(/\A\s*#/)
+
+ no += 1
+
+ line = line.chomp.lstrip
+ if line.start_with?('$')
+ handle_directive(line[1..-1], file, no)
+ next
+ end
+
+ next if @skip_section
+
+ case line
+ when /^set +([^ ]+) +([^ ]+)/i
+ var, value = $1.downcase, $2
+ bind_variable(var, value)
+ next
+ when /\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
+ key, func_name = $1, $2
+ keystroke, func = bind_key(key, func_name)
+ next unless keystroke
+ @additional_key_bindings[keystroke] = func
+ end
+ end
+ unless @if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{@if_stack.last[1]}: unclosed if"
+ end
+ ensure
+ @skip_section, @if_stack = conditions
+ end
+
+ def handle_directive(directive, file, no)
+ directive, args = directive.split(' ')
+ case directive
+ when 'if'
+ condition = false
+ case args
+ when 'mode'
+ when 'term'
+ when 'version'
+ else # application name
+ condition = true if args == 'Ruby'
+ condition = true if args == 'Reline'
+ end
+ @if_stack << [file, no, @skip_section]
+ @skip_section = !condition
+ when 'else'
+ if @if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{no}: unmatched else"
+ end
+ @skip_section = !@skip_section
+ when 'endif'
+ if @if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{no}: unmatched endif"
+ end
+ @skip_section = @if_stack.pop
+ when 'include'
+ read(args)
+ end
+ end
+
+ def bind_variable(name, value)
+ case name
+ when 'history-size'
+ begin
+ @history_size = Integer(value)
+ rescue ArgumentError
+ @history_size = 500
+ end
+ when 'bell-style'
+ @bell_style =
+ case value
+ when 'none', 'off'
+ :none
+ when 'audible', 'on'
+ :audible
+ when 'visible'
+ :visible
+ else
+ :audible
+ end
+ when 'comment-begin'
+ @comment_begin = value.dup
+ when 'completion-query-items'
+ @completion_query_items = value.to_i
+ when 'isearch-terminators'
+ @isearch_terminators = retrieve_string(value)
+ when 'editing-mode'
+ case value
+ when 'emacs'
+ @editing_mode_label = :emacs
+ @keymap_label = :emacs
+ when 'vi'
+ @editing_mode_label = :vi_insert
+ @keymap_label = :vi_insert
+ end
+ when 'keymap'
+ case value
+ when 'emacs', 'emacs-standard', 'emacs-meta', 'emacs-ctlx'
+ @keymap_label = :emacs
+ when 'vi', 'vi-move', 'vi-command'
+ @keymap_label = :vi_command
+ when 'vi-insert'
+ @keymap_label = :vi_insert
+ end
+ when 'keyseq-timeout'
+ @keyseq_timeout = value.to_i
+ when 'show-mode-in-prompt'
+ case value
+ when 'off'
+ @show_mode_in_prompt = false
+ when 'on'
+ @show_mode_in_prompt = true
+ else
+ @show_mode_in_prompt = false
+ end
+ when 'vi-cmd-mode-string'
+ @vi_cmd_mode_string = retrieve_string(value)
+ when 'vi-ins-mode-string'
+ @vi_ins_mode_string = retrieve_string(value)
+ when 'emacs-mode-string'
+ @emacs_mode_string = retrieve_string(value)
+ when *VARIABLE_NAMES then
+ variable_name = :"@#{name.tr(?-, ?_)}"
+ instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
+ end
+ end
+
+ def retrieve_string(str)
+ if str =~ /\A"(.*)"\z/
+ parse_keyseq($1).map(&:chr).join
+ else
+ parse_keyseq(str).map(&:chr).join
+ end
+ end
+
+ def bind_key(key, func_name)
+ if key =~ /\A"(.*)"\z/
+ keyseq = parse_keyseq($1)
+ else
+ keyseq = nil
+ end
+ if func_name =~ /"(.*)"/
+ func = parse_keyseq($1)
+ else
+ func = func_name.tr(?-, ?_).to_sym # It must be macro.
+ end
+ [keyseq, func]
+ end
+
+ def key_notation_to_code(notation)
+ case notation
+ when /\\(?:C|Control)-([A-Za-z_])/
+ (1 + $1.downcase.ord - ?a.ord)
+ when /\\(?:M|Meta)-([0-9A-Za-z_])/
+ modified_key = $1
+ case $1
+ when /[0-9]/
+ ?\M-0.bytes.first + (modified_key.ord - ?0.ord)
+ when /[A-Z]/
+ ?\M-A.bytes.first + (modified_key.ord - ?A.ord)
+ when /[a-z]/
+ ?\M-a.bytes.first + (modified_key.ord - ?a.ord)
+ end
+ when /\\(?:C|Control)-(?:M|Meta)-[A-Za-z_]/, /\\(?:M|Meta)-(?:C|Control)-[A-Za-z_]/
+ # 129 M-^A
+ when /\\(\d{1,3})/ then $1.to_i(8) # octal
+ when /\\x(\h{1,2})/ then $1.to_i(16) # hexadecimal
+ when "\\e" then ?\e.ord
+ when "\\\\" then ?\\.ord
+ when "\\\"" then ?".ord
+ when "\\'" then ?'.ord
+ when "\\a" then ?\a.ord
+ when "\\b" then ?\b.ord
+ when "\\d" then ?\d.ord
+ when "\\f" then ?\f.ord
+ when "\\n" then ?\n.ord
+ when "\\r" then ?\r.ord
+ when "\\t" then ?\t.ord
+ when "\\v" then ?\v.ord
+ else notation.ord
+ end
+ end
+
+ def parse_keyseq(str)
+ ret = []
+ str.scan(KEYSEQ_PATTERN) do
+ ret << key_notation_to_code($&)
+ end
+ ret
+ end
+end
diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb
new file mode 100644
index 0000000000..01a592e038
--- /dev/null
+++ b/lib/reline/general_io.rb
@@ -0,0 +1,93 @@
+require 'timeout'
+
+class Reline::GeneralIO
+ def self.reset
+ @@pasting = false
+ end
+
+ def self.encoding
+ RUBY_PLATFORM =~ /mswin|mingw/ ? Encoding::UTF_8 : Encoding::default_external
+ end
+
+ def self.win?
+ false
+ end
+
+ RAW_KEYSTROKE_CONFIG = {}
+
+ @@buf = []
+
+ def self.input=(val)
+ @@input = val
+ end
+
+ def self.getc
+ unless @@buf.empty?
+ return @@buf.shift
+ end
+ c = nil
+ loop do
+ result = select([@@input], [], [], 0.1)
+ next if result.nil?
+ c = @@input.read(1)
+ break
+ end
+ c&.ord
+ end
+
+ def self.ungetc(c)
+ @@buf.unshift(c)
+ end
+
+ def self.get_screen_size
+ [1, 1]
+ end
+
+ def self.cursor_pos
+ Reline::CursorPos.new(1, 1)
+ end
+
+ def self.move_cursor_column(val)
+ end
+
+ def self.move_cursor_up(val)
+ end
+
+ def self.move_cursor_down(val)
+ end
+
+ def self.erase_after_cursor
+ end
+
+ def self.scroll_down(val)
+ end
+
+ def self.clear_screen
+ end
+
+ def self.set_screen_size(rows, columns)
+ end
+
+ def self.set_winch_handler(&handler)
+ end
+
+ @@pasting = false
+
+ def self.in_pasting?
+ @@pasting
+ end
+
+ def self.start_pasting
+ @@pasting = true
+ end
+
+ def self.finish_pasting
+ @@pasting = false
+ end
+
+ def self.prep
+ end
+
+ def self.deprep(otio)
+ end
+end
diff --git a/lib/reline/history.rb b/lib/reline/history.rb
new file mode 100644
index 0000000000..7a1ed6b90b
--- /dev/null
+++ b/lib/reline/history.rb
@@ -0,0 +1,76 @@
+class Reline::History < Array
+ def initialize(config)
+ @config = config
+ end
+
+ def to_s
+ 'HISTORY'
+ end
+
+ def delete_at(index)
+ index = check_index(index)
+ super(index)
+ end
+
+ def [](index)
+ index = check_index(index) unless index.is_a?(Range)
+ super(index)
+ end
+
+ def []=(index, val)
+ index = check_index(index)
+ super(index, String.new(val, encoding: Reline.encoding_system_needs))
+ end
+
+ def concat(*val)
+ val.each do |v|
+ push(*v)
+ end
+ end
+
+ def push(*val)
+ # If history_size is zero, all histories are dropped.
+ return self if @config.history_size.zero?
+ # If history_size is negative, history size is unlimited.
+ if @config.history_size.positive?
+ diff = size + val.size - @config.history_size
+ if diff > 0
+ if diff <= size
+ shift(diff)
+ else
+ diff -= size
+ clear
+ val.shift(diff)
+ end
+ end
+ end
+ super(*(val.map{ |v|
+ String.new(v, encoding: Reline.encoding_system_needs)
+ }))
+ end
+
+ def <<(val)
+ # If history_size is zero, all histories are dropped.
+ return self if @config.history_size.zero?
+ # If history_size is negative, history size is unlimited.
+ if @config.history_size.positive?
+ shift if size + 1 > @config.history_size
+ end
+ super(String.new(val, encoding: Reline.encoding_system_needs))
+ end
+
+ private def check_index(index)
+ index += size if index < 0
+ if index < -2147483648 or 2147483647 < index
+ raise RangeError.new("integer #{index} too big to convert to `int'")
+ end
+ # If history_size is negative, history size is unlimited.
+ if @config.history_size.positive?
+ if index < -@config.history_size or @config.history_size < index
+ raise RangeError.new("index=<#{index}>")
+ end
+ end
+ raise IndexError.new("index=<#{index}>") if index < 0 or size <= index
+ index
+ end
+end
diff --git a/lib/reline/key_actor.rb b/lib/reline/key_actor.rb
new file mode 100644
index 0000000000..ebe09d2009
--- /dev/null
+++ b/lib/reline/key_actor.rb
@@ -0,0 +1,7 @@
+module Reline::KeyActor
+end
+
+require 'reline/key_actor/base'
+require 'reline/key_actor/emacs'
+require 'reline/key_actor/vi_command'
+require 'reline/key_actor/vi_insert'
diff --git a/lib/reline/key_actor/base.rb b/lib/reline/key_actor/base.rb
new file mode 100644
index 0000000000..f4abac55d4
--- /dev/null
+++ b/lib/reline/key_actor/base.rb
@@ -0,0 +1,7 @@
+class Reline::KeyActor::Base
+ MAPPING = Array.new(256)
+
+ def get_method(key)
+ self.class::MAPPING[key]
+ end
+end
diff --git a/lib/reline/key_actor/emacs.rb b/lib/reline/key_actor/emacs.rb
new file mode 100644
index 0000000000..cad97a7d04
--- /dev/null
+++ b/lib/reline/key_actor/emacs.rb
@@ -0,0 +1,517 @@
+class Reline::KeyActor::Emacs < Reline::KeyActor::Base
+ MAPPING = [
+ # 0 ^@
+ :em_set_mark,
+ # 1 ^A
+ :ed_move_to_beg,
+ # 2 ^B
+ :ed_prev_char,
+ # 3 ^C
+ :ed_ignore,
+ # 4 ^D
+ :em_delete,
+ # 5 ^E
+ :ed_move_to_end,
+ # 6 ^F
+ :ed_next_char,
+ # 7 ^G
+ :ed_unassigned,
+ # 8 ^H
+ :em_delete_prev_char,
+ # 9 ^I
+ :ed_unassigned,
+ # 10 ^J
+ :ed_newline,
+ # 11 ^K
+ :ed_kill_line,
+ # 12 ^L
+ :ed_clear_screen,
+ # 13 ^M
+ :ed_newline,
+ # 14 ^N
+ :ed_next_history,
+ # 15 ^O
+ :ed_ignore,
+ # 16 ^P
+ :ed_prev_history,
+ # 17 ^Q
+ :ed_quoted_insert,
+ # 18 ^R
+ :vi_search_prev,
+ # 19 ^S
+ :vi_search_next,
+ # 20 ^T
+ :ed_transpose_chars,
+ # 21 ^U
+ :em_kill_line,
+ # 22 ^V
+ :ed_quoted_insert,
+ # 23 ^W
+ :em_kill_region,
+ # 24 ^X
+ :ed_sequence_lead_in,
+ # 25 ^Y
+ :em_yank,
+ # 26 ^Z
+ :ed_ignore,
+ # 27 ^[
+ :em_meta_next,
+ # 28 ^\
+ :ed_ignore,
+ # 29 ^]
+ :ed_ignore,
+ # 30 ^^
+ :ed_unassigned,
+ # 31 ^_
+ :ed_unassigned,
+ # 32 SPACE
+ :ed_insert,
+ # 33 !
+ :ed_insert,
+ # 34 "
+ :ed_insert,
+ # 35 #
+ :ed_insert,
+ # 36 $
+ :ed_insert,
+ # 37 %
+ :ed_insert,
+ # 38 &
+ :ed_insert,
+ # 39 '
+ :ed_insert,
+ # 40 (
+ :ed_insert,
+ # 41 )
+ :ed_insert,
+ # 42 *
+ :ed_insert,
+ # 43 +
+ :ed_insert,
+ # 44 ,
+ :ed_insert,
+ # 45 -
+ :ed_insert,
+ # 46 .
+ :ed_insert,
+ # 47 /
+ :ed_insert,
+ # 48 0
+ :ed_digit,
+ # 49 1
+ :ed_digit,
+ # 50 2
+ :ed_digit,
+ # 51 3
+ :ed_digit,
+ # 52 4
+ :ed_digit,
+ # 53 5
+ :ed_digit,
+ # 54 6
+ :ed_digit,
+ # 55 7
+ :ed_digit,
+ # 56 8
+ :ed_digit,
+ # 57 9
+ :ed_digit,
+ # 58 :
+ :ed_insert,
+ # 59 ;
+ :ed_insert,
+ # 60 <
+ :ed_insert,
+ # 61 =
+ :ed_insert,
+ # 62 >
+ :ed_insert,
+ # 63 ?
+ :ed_insert,
+ # 64 @
+ :ed_insert,
+ # 65 A
+ :ed_insert,
+ # 66 B
+ :ed_insert,
+ # 67 C
+ :ed_insert,
+ # 68 D
+ :ed_insert,
+ # 69 E
+ :ed_insert,
+ # 70 F
+ :ed_insert,
+ # 71 G
+ :ed_insert,
+ # 72 H
+ :ed_insert,
+ # 73 I
+ :ed_insert,
+ # 74 J
+ :ed_insert,
+ # 75 K
+ :ed_insert,
+ # 76 L
+ :ed_insert,
+ # 77 M
+ :ed_insert,
+ # 78 N
+ :ed_insert,
+ # 79 O
+ :ed_insert,
+ # 80 P
+ :ed_insert,
+ # 81 Q
+ :ed_insert,
+ # 82 R
+ :ed_insert,
+ # 83 S
+ :ed_insert,
+ # 84 T
+ :ed_insert,
+ # 85 U
+ :ed_insert,
+ # 86 V
+ :ed_insert,
+ # 87 W
+ :ed_insert,
+ # 88 X
+ :ed_insert,
+ # 89 Y
+ :ed_insert,
+ # 90 Z
+ :ed_insert,
+ # 91 [
+ :ed_insert,
+ # 92 \
+ :ed_insert,
+ # 93 ]
+ :ed_insert,
+ # 94 ^
+ :ed_insert,
+ # 95 _
+ :ed_insert,
+ # 96 `
+ :ed_insert,
+ # 97 a
+ :ed_insert,
+ # 98 b
+ :ed_insert,
+ # 99 c
+ :ed_insert,
+ # 100 d
+ :ed_insert,
+ # 101 e
+ :ed_insert,
+ # 102 f
+ :ed_insert,
+ # 103 g
+ :ed_insert,
+ # 104 h
+ :ed_insert,
+ # 105 i
+ :ed_insert,
+ # 106 j
+ :ed_insert,
+ # 107 k
+ :ed_insert,
+ # 108 l
+ :ed_insert,
+ # 109 m
+ :ed_insert,
+ # 110 n
+ :ed_insert,
+ # 111 o
+ :ed_insert,
+ # 112 p
+ :ed_insert,
+ # 113 q
+ :ed_insert,
+ # 114 r
+ :ed_insert,
+ # 115 s
+ :ed_insert,
+ # 116 t
+ :ed_insert,
+ # 117 u
+ :ed_insert,
+ # 118 v
+ :ed_insert,
+ # 119 w
+ :ed_insert,
+ # 120 x
+ :ed_insert,
+ # 121 y
+ :ed_insert,
+ # 122 z
+ :ed_insert,
+ # 123 {
+ :ed_insert,
+ # 124 |
+ :ed_insert,
+ # 125 }
+ :ed_insert,
+ # 126 ~
+ :ed_insert,
+ # 127 ^?
+ :em_delete_prev_char,
+ # 128 M-^@
+ :ed_unassigned,
+ # 129 M-^A
+ :ed_unassigned,
+ # 130 M-^B
+ :ed_unassigned,
+ # 131 M-^C
+ :ed_unassigned,
+ # 132 M-^D
+ :ed_unassigned,
+ # 133 M-^E
+ :ed_unassigned,
+ # 134 M-^F
+ :ed_unassigned,
+ # 135 M-^G
+ :ed_unassigned,
+ # 136 M-^H
+ :ed_delete_prev_word,
+ # 137 M-^I
+ :ed_unassigned,
+ # 138 M-^J
+ :key_newline,
+ # 139 M-^K
+ :ed_unassigned,
+ # 140 M-^L
+ :ed_clear_screen,
+ # 141 M-^M
+ :key_newline,
+ # 142 M-^N
+ :ed_unassigned,
+ # 143 M-^O
+ :ed_unassigned,
+ # 144 M-^P
+ :ed_unassigned,
+ # 145 M-^Q
+ :ed_unassigned,
+ # 146 M-^R
+ :ed_unassigned,
+ # 147 M-^S
+ :ed_unassigned,
+ # 148 M-^T
+ :ed_unassigned,
+ # 149 M-^U
+ :ed_unassigned,
+ # 150 M-^V
+ :ed_unassigned,
+ # 151 M-^W
+ :ed_unassigned,
+ # 152 M-^X
+ :ed_unassigned,
+ # 153 M-^Y
+ :em_yank_pop,
+ # 154 M-^Z
+ :ed_unassigned,
+ # 155 M-^[
+ :ed_unassigned,
+ # 156 M-^\
+ :ed_unassigned,
+ # 157 M-^]
+ :ed_unassigned,
+ # 158 M-^^
+ :ed_unassigned,
+ # 159 M-^_
+ :em_copy_prev_word,
+ # 160 M-SPACE
+ :ed_unassigned,
+ # 161 M-!
+ :ed_unassigned,
+ # 162 M-"
+ :ed_unassigned,
+ # 163 M-#
+ :ed_unassigned,
+ # 164 M-$
+ :ed_unassigned,
+ # 165 M-%
+ :ed_unassigned,
+ # 166 M-&
+ :ed_unassigned,
+ # 167 M-'
+ :ed_unassigned,
+ # 168 M-(
+ :ed_unassigned,
+ # 169 M-)
+ :ed_unassigned,
+ # 170 M-*
+ :ed_unassigned,
+ # 171 M-+
+ :ed_unassigned,
+ # 172 M-,
+ :ed_unassigned,
+ # 173 M--
+ :ed_unassigned,
+ # 174 M-.
+ :ed_unassigned,
+ # 175 M-/
+ :ed_unassigned,
+ # 176 M-0
+ :ed_argument_digit,
+ # 177 M-1
+ :ed_argument_digit,
+ # 178 M-2
+ :ed_argument_digit,
+ # 179 M-3
+ :ed_argument_digit,
+ # 180 M-4
+ :ed_argument_digit,
+ # 181 M-5
+ :ed_argument_digit,
+ # 182 M-6
+ :ed_argument_digit,
+ # 183 M-7
+ :ed_argument_digit,
+ # 184 M-8
+ :ed_argument_digit,
+ # 185 M-9
+ :ed_argument_digit,
+ # 186 M-:
+ :ed_unassigned,
+ # 187 M-;
+ :ed_unassigned,
+ # 188 M-<
+ :ed_unassigned,
+ # 189 M-=
+ :ed_unassigned,
+ # 190 M->
+ :ed_unassigned,
+ # 191 M-?
+ :ed_unassigned,
+ # 192 M-@
+ :ed_unassigned,
+ # 193 M-A
+ :ed_unassigned,
+ # 194 M-B
+ :ed_prev_word,
+ # 195 M-C
+ :em_capitol_case,
+ # 196 M-D
+ :em_delete_next_word,
+ # 197 M-E
+ :ed_unassigned,
+ # 198 M-F
+ :em_next_word,
+ # 199 M-G
+ :ed_unassigned,
+ # 200 M-H
+ :ed_unassigned,
+ # 201 M-I
+ :ed_unassigned,
+ # 202 M-J
+ :ed_unassigned,
+ # 203 M-K
+ :ed_unassigned,
+ # 204 M-L
+ :em_lower_case,
+ # 205 M-M
+ :ed_unassigned,
+ # 206 M-N
+ :vi_search_next,
+ # 207 M-O
+ :ed_sequence_lead_in,
+ # 208 M-P
+ :vi_search_prev,
+ # 209 M-Q
+ :ed_unassigned,
+ # 210 M-R
+ :ed_unassigned,
+ # 211 M-S
+ :ed_unassigned,
+ # 212 M-T
+ :ed_unassigned,
+ # 213 M-U
+ :em_upper_case,
+ # 214 M-V
+ :ed_unassigned,
+ # 215 M-W
+ :em_copy_region,
+ # 216 M-X
+ :ed_command,
+ # 217 M-Y
+ :ed_unassigned,
+ # 218 M-Z
+ :ed_unassigned,
+ # 219 M-[
+ :ed_sequence_lead_in,
+ # 220 M-\
+ :ed_unassigned,
+ # 221 M-]
+ :ed_unassigned,
+ # 222 M-^
+ :ed_unassigned,
+ # 223 M-_
+ :ed_unassigned,
+ # 224 M-`
+ :ed_unassigned,
+ # 225 M-a
+ :ed_unassigned,
+ # 226 M-b
+ :ed_prev_word,
+ # 227 M-c
+ :em_capitol_case,
+ # 228 M-d
+ :em_delete_next_word,
+ # 229 M-e
+ :ed_unassigned,
+ # 230 M-f
+ :em_next_word,
+ # 231 M-g
+ :ed_unassigned,
+ # 232 M-h
+ :ed_unassigned,
+ # 233 M-i
+ :ed_unassigned,
+ # 234 M-j
+ :ed_unassigned,
+ # 235 M-k
+ :ed_unassigned,
+ # 236 M-l
+ :em_lower_case,
+ # 237 M-m
+ :ed_unassigned,
+ # 238 M-n
+ :vi_search_next,
+ # 239 M-o
+ :ed_unassigned,
+ # 240 M-p
+ :vi_search_prev,
+ # 241 M-q
+ :ed_unassigned,
+ # 242 M-r
+ :ed_unassigned,
+ # 243 M-s
+ :ed_unassigned,
+ # 244 M-t
+ :ed_transpose_words,
+ # 245 M-u
+ :em_upper_case,
+ # 246 M-v
+ :ed_unassigned,
+ # 247 M-w
+ :em_copy_region,
+ # 248 M-x
+ :ed_command,
+ # 249 M-y
+ :ed_unassigned,
+ # 250 M-z
+ :ed_unassigned,
+ # 251 M-{
+ :ed_unassigned,
+ # 252 M-|
+ :ed_unassigned,
+ # 253 M-}
+ :ed_unassigned,
+ # 254 M-~
+ :ed_unassigned,
+ # 255 M-^?
+ :ed_delete_prev_word
+ # EOF
+ ]
+end
diff --git a/lib/reline/key_actor/vi_command.rb b/lib/reline/key_actor/vi_command.rb
new file mode 100644
index 0000000000..98146d2f77
--- /dev/null
+++ b/lib/reline/key_actor/vi_command.rb
@@ -0,0 +1,518 @@
+class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
+ MAPPING = [
+ # 0 ^@
+ :ed_unassigned,
+ # 1 ^A
+ :ed_move_to_beg,
+ # 2 ^B
+ :ed_unassigned,
+ # 3 ^C
+ :ed_ignore,
+ # 4 ^D
+ :vi_end_of_transmission,
+ # 5 ^E
+ :ed_move_to_end,
+ # 6 ^F
+ :ed_unassigned,
+ # 7 ^G
+ :ed_unassigned,
+ # 8 ^H
+ :ed_unassigned,
+ # 9 ^I
+ :ed_unassigned,
+ # 10 ^J
+ :ed_newline,
+ # 11 ^K
+ :ed_kill_line,
+ # 12 ^L
+ :ed_clear_screen,
+ # 13 ^M
+ :ed_newline,
+ # 14 ^N
+ :ed_next_history,
+ # 15 ^O
+ :ed_ignore,
+ # 16 ^P
+ :ed_prev_history,
+ # 17 ^Q
+ :ed_ignore,
+ # 18 ^R
+ :vi_search_prev,
+ # 19 ^S
+ :ed_ignore,
+ # 20 ^T
+ :ed_unassigned,
+ # 21 ^U
+ :vi_kill_line_prev,
+ # 22 ^V
+ :ed_quoted_insert,
+ # 23 ^W
+ :ed_delete_prev_word,
+ # 24 ^X
+ :ed_unassigned,
+ # 25 ^Y
+ :ed_unassigned,
+ # 26 ^Z
+ :ed_unassigned,
+ # 27 ^[
+ :ed_unassigned,
+ # 28 ^\
+ :ed_ignore,
+ # 29 ^]
+ :ed_unassigned,
+ # 30 ^^
+ :ed_unassigned,
+ # 31 ^_
+ :ed_unassigned,
+ # 32 SPACE
+ :ed_next_char,
+ # 33 !
+ :ed_unassigned,
+ # 34 "
+ :ed_unassigned,
+ # 35 #
+ :vi_comment_out,
+ # 36 $
+ :ed_move_to_end,
+ # 37 %
+ :vi_match,
+ # 38 &
+ :ed_unassigned,
+ # 39 '
+ :ed_unassigned,
+ # 40 (
+ :ed_unassigned,
+ # 41 )
+ :ed_unassigned,
+ # 42 *
+ :ed_unassigned,
+ # 43 +
+ :ed_next_history,
+ # 44 ,
+ :vi_repeat_prev_char,
+ # 45 -
+ :ed_prev_history,
+ # 46 .
+ :vi_redo,
+ # 47 /
+ :vi_search_prev,
+ # 48 0
+ :vi_zero,
+ # 49 1
+ :ed_argument_digit,
+ # 50 2
+ :ed_argument_digit,
+ # 51 3
+ :ed_argument_digit,
+ # 52 4
+ :ed_argument_digit,
+ # 53 5
+ :ed_argument_digit,
+ # 54 6
+ :ed_argument_digit,
+ # 55 7
+ :ed_argument_digit,
+ # 56 8
+ :ed_argument_digit,
+ # 57 9
+ :ed_argument_digit,
+ # 58 :
+ :ed_command,
+ # 59 ;
+ :vi_repeat_next_char,
+ # 60 <
+ :ed_unassigned,
+ # 61 =
+ :ed_unassigned,
+ # 62 >
+ :ed_unassigned,
+ # 63 ?
+ :vi_search_next,
+ # 64 @
+ :vi_alias,
+ # 65 A
+ :vi_add_at_eol,
+ # 66 B
+ :vi_prev_big_word,
+ # 67 C
+ :vi_change_to_eol,
+ # 68 D
+ :ed_kill_line,
+ # 69 E
+ :vi_end_big_word,
+ # 70 F
+ :vi_prev_char,
+ # 71 G
+ :vi_to_history_line,
+ # 72 H
+ :ed_unassigned,
+ # 73 I
+ :vi_insert_at_bol,
+ # 74 J
+ :vi_join_lines,
+ # 75 K
+ :vi_search_prev,
+ # 76 L
+ :ed_unassigned,
+ # 77 M
+ :ed_unassigned,
+ # 78 N
+ :vi_repeat_search_prev,
+ # 79 O
+ :ed_sequence_lead_in,
+ # 80 P
+ :vi_paste_prev,
+ # 81 Q
+ :ed_unassigned,
+ # 82 R
+ :vi_replace_mode,
+ # 83 S
+ :vi_substitute_line,
+ # 84 T
+ :vi_to_prev_char,
+ # 85 U
+ :vi_undo_line,
+ # 86 V
+ :ed_unassigned,
+ # 87 W
+ :vi_next_big_word,
+ # 88 X
+ :ed_delete_prev_char,
+ # 89 Y
+ :vi_yank_end,
+ # 90 Z
+ :ed_unassigned,
+ # 91 [
+ :ed_sequence_lead_in,
+ # 92 \
+ :ed_unassigned,
+ # 93 ]
+ :ed_unassigned,
+ # 94 ^
+ :vi_first_print,
+ # 95 _
+ :vi_history_word,
+ # 96 `
+ :ed_unassigned,
+ # 97 a
+ :vi_add,
+ # 98 b
+ :vi_prev_word,
+ # 99 c
+ :vi_change_meta,
+ # 100 d
+ :vi_delete_meta,
+ # 101 e
+ :vi_end_word,
+ # 102 f
+ :vi_next_char,
+ # 103 g
+ :ed_unassigned,
+ # 104 h
+ :ed_prev_char,
+ # 105 i
+ :vi_insert,
+ # 106 j
+ :ed_next_history,
+ # 107 k
+ :ed_prev_history,
+ # 108 l
+ :ed_next_char,
+ # 109 m
+ :ed_unassigned,
+ # 110 n
+ :vi_repeat_search_next,
+ # 111 o
+ :ed_unassigned,
+ # 112 p
+ :vi_paste_next,
+ # 113 q
+ :ed_unassigned,
+ # 114 r
+ :vi_replace_char,
+ # 115 s
+ :vi_substitute_char,
+ # 116 t
+ :vi_to_next_char,
+ # 117 u
+ :vi_undo,
+ # 118 v
+ :vi_histedit,
+ # 119 w
+ :vi_next_word,
+ # 120 x
+ :ed_delete_next_char,
+ # 121 y
+ :vi_yank,
+ # 122 z
+ :ed_unassigned,
+ # 123 {
+ :ed_unassigned,
+ # 124 |
+ :vi_to_column,
+ # 125 }
+ :ed_unassigned,
+ # 126 ~
+ :vi_change_case,
+ # 127 ^?
+ :ed_unassigned,
+ # 128 M-^@
+ :ed_unassigned,
+ # 129 M-^A
+ :ed_unassigned,
+ # 130 M-^B
+ :ed_unassigned,
+ # 131 M-^C
+ :ed_unassigned,
+ # 132 M-^D
+ :ed_unassigned,
+ # 133 M-^E
+ :ed_unassigned,
+ # 134 M-^F
+ :ed_unassigned,
+ # 135 M-^G
+ :ed_unassigned,
+ # 136 M-^H
+ :ed_unassigned,
+ # 137 M-^I
+ :ed_unassigned,
+ # 138 M-^J
+ :ed_unassigned,
+ # 139 M-^K
+ :ed_unassigned,
+ # 140 M-^L
+ :ed_unassigned,
+ # 141 M-^M
+ :ed_unassigned,
+ # 142 M-^N
+ :ed_unassigned,
+ # 143 M-^O
+ :ed_unassigned,
+ # 144 M-^P
+ :ed_unassigned,
+ # 145 M-^Q
+ :ed_unassigned,
+ # 146 M-^R
+ :ed_unassigned,
+ # 147 M-^S
+ :ed_unassigned,
+ # 148 M-^T
+ :ed_unassigned,
+ # 149 M-^U
+ :ed_unassigned,
+ # 150 M-^V
+ :ed_unassigned,
+ # 151 M-^W
+ :ed_unassigned,
+ # 152 M-^X
+ :ed_unassigned,
+ # 153 M-^Y
+ :ed_unassigned,
+ # 154 M-^Z
+ :ed_unassigned,
+ # 155 M-^[
+ :ed_unassigned,
+ # 156 M-^\
+ :ed_unassigned,
+ # 157 M-^]
+ :ed_unassigned,
+ # 158 M-^^
+ :ed_unassigned,
+ # 159 M-^_
+ :ed_unassigned,
+ # 160 M-SPACE
+ :ed_unassigned,
+ # 161 M-!
+ :ed_unassigned,
+ # 162 M-"
+ :ed_unassigned,
+ # 163 M-#
+ :ed_unassigned,
+ # 164 M-$
+ :ed_unassigned,
+ # 165 M-%
+ :ed_unassigned,
+ # 166 M-&
+ :ed_unassigned,
+ # 167 M-'
+ :ed_unassigned,
+ # 168 M-(
+ :ed_unassigned,
+ # 169 M-)
+ :ed_unassigned,
+ # 170 M-*
+ :ed_unassigned,
+ # 171 M-+
+ :ed_unassigned,
+ # 172 M-,
+ :ed_unassigned,
+ # 173 M--
+ :ed_unassigned,
+ # 174 M-.
+ :ed_unassigned,
+ # 175 M-/
+ :ed_unassigned,
+ # 176 M-0
+ :ed_unassigned,
+ # 177 M-1
+ :ed_unassigned,
+ # 178 M-2
+ :ed_unassigned,
+ # 179 M-3
+ :ed_unassigned,
+ # 180 M-4
+ :ed_unassigned,
+ # 181 M-5
+ :ed_unassigned,
+ # 182 M-6
+ :ed_unassigned,
+ # 183 M-7
+ :ed_unassigned,
+ # 184 M-8
+ :ed_unassigned,
+ # 185 M-9
+ :ed_unassigned,
+ # 186 M-:
+ :ed_unassigned,
+ # 187 M-;
+ :ed_unassigned,
+ # 188 M-<
+ :ed_unassigned,
+ # 189 M-=
+ :ed_unassigned,
+ # 190 M->
+ :ed_unassigned,
+ # 191 M-?
+ :ed_unassigned,
+ # 192 M-@
+ :ed_unassigned,
+ # 193 M-A
+ :ed_unassigned,
+ # 194 M-B
+ :ed_unassigned,
+ # 195 M-C
+ :ed_unassigned,
+ # 196 M-D
+ :ed_unassigned,
+ # 197 M-E
+ :ed_unassigned,
+ # 198 M-F
+ :ed_unassigned,
+ # 199 M-G
+ :ed_unassigned,
+ # 200 M-H
+ :ed_unassigned,
+ # 201 M-I
+ :ed_unassigned,
+ # 202 M-J
+ :ed_unassigned,
+ # 203 M-K
+ :ed_unassigned,
+ # 204 M-L
+ :ed_unassigned,
+ # 205 M-M
+ :ed_unassigned,
+ # 206 M-N
+ :ed_unassigned,
+ # 207 M-O
+ :ed_sequence_lead_in,
+ # 208 M-P
+ :ed_unassigned,
+ # 209 M-Q
+ :ed_unassigned,
+ # 210 M-R
+ :ed_unassigned,
+ # 211 M-S
+ :ed_unassigned,
+ # 212 M-T
+ :ed_unassigned,
+ # 213 M-U
+ :ed_unassigned,
+ # 214 M-V
+ :ed_unassigned,
+ # 215 M-W
+ :ed_unassigned,
+ # 216 M-X
+ :ed_unassigned,
+ # 217 M-Y
+ :ed_unassigned,
+ # 218 M-Z
+ :ed_unassigned,
+ # 219 M-[
+ :ed_sequence_lead_in,
+ # 220 M-\
+ :ed_unassigned,
+ # 221 M-]
+ :ed_unassigned,
+ # 222 M-^
+ :ed_unassigned,
+ # 223 M-_
+ :ed_unassigned,
+ # 224 M-`
+ :ed_unassigned,
+ # 225 M-a
+ :ed_unassigned,
+ # 226 M-b
+ :ed_unassigned,
+ # 227 M-c
+ :ed_unassigned,
+ # 228 M-d
+ :ed_unassigned,
+ # 229 M-e
+ :ed_unassigned,
+ # 230 M-f
+ :ed_unassigned,
+ # 231 M-g
+ :ed_unassigned,
+ # 232 M-h
+ :ed_unassigned,
+ # 233 M-i
+ :ed_unassigned,
+ # 234 M-j
+ :ed_unassigned,
+ # 235 M-k
+ :ed_unassigned,
+ # 236 M-l
+ :ed_unassigned,
+ # 237 M-m
+ :ed_unassigned,
+ # 238 M-n
+ :ed_unassigned,
+ # 239 M-o
+ :ed_unassigned,
+ # 240 M-p
+ :ed_unassigned,
+ # 241 M-q
+ :ed_unassigned,
+ # 242 M-r
+ :ed_unassigned,
+ # 243 M-s
+ :ed_unassigned,
+ # 244 M-t
+ :ed_unassigned,
+ # 245 M-u
+ :ed_unassigned,
+ # 246 M-v
+ :ed_unassigned,
+ # 247 M-w
+ :ed_unassigned,
+ # 248 M-x
+ :ed_unassigned,
+ # 249 M-y
+ :ed_unassigned,
+ # 250 M-z
+ :ed_unassigned,
+ # 251 M-{
+ :ed_unassigned,
+ # 252 M-|
+ :ed_unassigned,
+ # 253 M-}
+ :ed_unassigned,
+ # 254 M-~
+ :ed_unassigned,
+ # 255 M-^?
+ :ed_unassigned
+ # EOF
+ ]
+end
+
diff --git a/lib/reline/key_actor/vi_insert.rb b/lib/reline/key_actor/vi_insert.rb
new file mode 100644
index 0000000000..b8e89f81d8
--- /dev/null
+++ b/lib/reline/key_actor/vi_insert.rb
@@ -0,0 +1,517 @@
+class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
+ MAPPING = [
+ # 0 ^@
+ :ed_unassigned,
+ # 1 ^A
+ :ed_insert,
+ # 2 ^B
+ :ed_insert,
+ # 3 ^C
+ :ed_insert,
+ # 4 ^D
+ :vi_list_or_eof,
+ # 5 ^E
+ :ed_insert,
+ # 6 ^F
+ :ed_insert,
+ # 7 ^G
+ :ed_insert,
+ # 8 ^H
+ :vi_delete_prev_char,
+ # 9 ^I
+ :ed_insert,
+ # 10 ^J
+ :ed_newline,
+ # 11 ^K
+ :ed_insert,
+ # 12 ^L
+ :ed_insert,
+ # 13 ^M
+ :ed_newline,
+ # 14 ^N
+ :ed_insert,
+ # 15 ^O
+ :ed_insert,
+ # 16 ^P
+ :ed_insert,
+ # 17 ^Q
+ :ed_ignore,
+ # 18 ^R
+ :vi_search_prev,
+ # 19 ^S
+ :vi_search_next,
+ # 20 ^T
+ :ed_insert,
+ # 21 ^U
+ :vi_kill_line_prev,
+ # 22 ^V
+ :ed_quoted_insert,
+ # 23 ^W
+ :ed_delete_prev_word,
+ # 24 ^X
+ :ed_insert,
+ # 25 ^Y
+ :ed_insert,
+ # 26 ^Z
+ :ed_insert,
+ # 27 ^[
+ :vi_command_mode,
+ # 28 ^\
+ :ed_ignore,
+ # 29 ^]
+ :ed_insert,
+ # 30 ^^
+ :ed_insert,
+ # 31 ^_
+ :ed_insert,
+ # 32 SPACE
+ :ed_insert,
+ # 33 !
+ :ed_insert,
+ # 34 "
+ :ed_insert,
+ # 35 #
+ :ed_insert,
+ # 36 $
+ :ed_insert,
+ # 37 %
+ :ed_insert,
+ # 38 &
+ :ed_insert,
+ # 39 '
+ :ed_insert,
+ # 40 (
+ :ed_insert,
+ # 41 )
+ :ed_insert,
+ # 42 *
+ :ed_insert,
+ # 43 +
+ :ed_insert,
+ # 44 ,
+ :ed_insert,
+ # 45 -
+ :ed_insert,
+ # 46 .
+ :ed_insert,
+ # 47 /
+ :ed_insert,
+ # 48 0
+ :ed_insert,
+ # 49 1
+ :ed_insert,
+ # 50 2
+ :ed_insert,
+ # 51 3
+ :ed_insert,
+ # 52 4
+ :ed_insert,
+ # 53 5
+ :ed_insert,
+ # 54 6
+ :ed_insert,
+ # 55 7
+ :ed_insert,
+ # 56 8
+ :ed_insert,
+ # 57 9
+ :ed_insert,
+ # 58 :
+ :ed_insert,
+ # 59 ;
+ :ed_insert,
+ # 60 <
+ :ed_insert,
+ # 61 =
+ :ed_insert,
+ # 62 >
+ :ed_insert,
+ # 63 ?
+ :ed_insert,
+ # 64 @
+ :ed_insert,
+ # 65 A
+ :ed_insert,
+ # 66 B
+ :ed_insert,
+ # 67 C
+ :ed_insert,
+ # 68 D
+ :ed_insert,
+ # 69 E
+ :ed_insert,
+ # 70 F
+ :ed_insert,
+ # 71 G
+ :ed_insert,
+ # 72 H
+ :ed_insert,
+ # 73 I
+ :ed_insert,
+ # 74 J
+ :ed_insert,
+ # 75 K
+ :ed_insert,
+ # 76 L
+ :ed_insert,
+ # 77 M
+ :ed_insert,
+ # 78 N
+ :ed_insert,
+ # 79 O
+ :ed_insert,
+ # 80 P
+ :ed_insert,
+ # 81 Q
+ :ed_insert,
+ # 82 R
+ :ed_insert,
+ # 83 S
+ :ed_insert,
+ # 84 T
+ :ed_insert,
+ # 85 U
+ :ed_insert,
+ # 86 V
+ :ed_insert,
+ # 87 W
+ :ed_insert,
+ # 88 X
+ :ed_insert,
+ # 89 Y
+ :ed_insert,
+ # 90 Z
+ :ed_insert,
+ # 91 [
+ :ed_insert,
+ # 92 \
+ :ed_insert,
+ # 93 ]
+ :ed_insert,
+ # 94 ^
+ :ed_insert,
+ # 95 _
+ :ed_insert,
+ # 96 `
+ :ed_insert,
+ # 97 a
+ :ed_insert,
+ # 98 b
+ :ed_insert,
+ # 99 c
+ :ed_insert,
+ # 100 d
+ :ed_insert,
+ # 101 e
+ :ed_insert,
+ # 102 f
+ :ed_insert,
+ # 103 g
+ :ed_insert,
+ # 104 h
+ :ed_insert,
+ # 105 i
+ :ed_insert,
+ # 106 j
+ :ed_insert,
+ # 107 k
+ :ed_insert,
+ # 108 l
+ :ed_insert,
+ # 109 m
+ :ed_insert,
+ # 110 n
+ :ed_insert,
+ # 111 o
+ :ed_insert,
+ # 112 p
+ :ed_insert,
+ # 113 q
+ :ed_insert,
+ # 114 r
+ :ed_insert,
+ # 115 s
+ :ed_insert,
+ # 116 t
+ :ed_insert,
+ # 117 u
+ :ed_insert,
+ # 118 v
+ :ed_insert,
+ # 119 w
+ :ed_insert,
+ # 120 x
+ :ed_insert,
+ # 121 y
+ :ed_insert,
+ # 122 z
+ :ed_insert,
+ # 123 {
+ :ed_insert,
+ # 124 |
+ :ed_insert,
+ # 125 }
+ :ed_insert,
+ # 126 ~
+ :ed_insert,
+ # 127 ^?
+ :vi_delete_prev_char,
+ # 128 M-^@
+ :ed_unassigned,
+ # 129 M-^A
+ :ed_unassigned,
+ # 130 M-^B
+ :ed_unassigned,
+ # 131 M-^C
+ :ed_unassigned,
+ # 132 M-^D
+ :ed_unassigned,
+ # 133 M-^E
+ :ed_unassigned,
+ # 134 M-^F
+ :ed_unassigned,
+ # 135 M-^G
+ :ed_unassigned,
+ # 136 M-^H
+ :ed_unassigned,
+ # 137 M-^I
+ :ed_unassigned,
+ # 138 M-^J
+ :key_newline,
+ # 139 M-^K
+ :ed_unassigned,
+ # 140 M-^L
+ :ed_unassigned,
+ # 141 M-^M
+ :key_newline,
+ # 142 M-^N
+ :ed_unassigned,
+ # 143 M-^O
+ :ed_unassigned,
+ # 144 M-^P
+ :ed_unassigned,
+ # 145 M-^Q
+ :ed_unassigned,
+ # 146 M-^R
+ :ed_unassigned,
+ # 147 M-^S
+ :ed_unassigned,
+ # 148 M-^T
+ :ed_unassigned,
+ # 149 M-^U
+ :ed_unassigned,
+ # 150 M-^V
+ :ed_unassigned,
+ # 151 M-^W
+ :ed_unassigned,
+ # 152 M-^X
+ :ed_unassigned,
+ # 153 M-^Y
+ :ed_unassigned,
+ # 154 M-^Z
+ :ed_unassigned,
+ # 155 M-^[
+ :ed_unassigned,
+ # 156 M-^\
+ :ed_unassigned,
+ # 157 M-^]
+ :ed_unassigned,
+ # 158 M-^^
+ :ed_unassigned,
+ # 159 M-^_
+ :ed_unassigned,
+ # 160 M-SPACE
+ :ed_unassigned,
+ # 161 M-!
+ :ed_unassigned,
+ # 162 M-"
+ :ed_unassigned,
+ # 163 M-#
+ :ed_unassigned,
+ # 164 M-$
+ :ed_unassigned,
+ # 165 M-%
+ :ed_unassigned,
+ # 166 M-&
+ :ed_unassigned,
+ # 167 M-'
+ :ed_unassigned,
+ # 168 M-(
+ :ed_unassigned,
+ # 169 M-)
+ :ed_unassigned,
+ # 170 M-*
+ :ed_unassigned,
+ # 171 M-+
+ :ed_unassigned,
+ # 172 M-,
+ :ed_unassigned,
+ # 173 M--
+ :ed_unassigned,
+ # 174 M-.
+ :ed_unassigned,
+ # 175 M-/
+ :ed_unassigned,
+ # 176 M-0
+ :ed_unassigned,
+ # 177 M-1
+ :ed_unassigned,
+ # 178 M-2
+ :ed_unassigned,
+ # 179 M-3
+ :ed_unassigned,
+ # 180 M-4
+ :ed_unassigned,
+ # 181 M-5
+ :ed_unassigned,
+ # 182 M-6
+ :ed_unassigned,
+ # 183 M-7
+ :ed_unassigned,
+ # 184 M-8
+ :ed_unassigned,
+ # 185 M-9
+ :ed_unassigned,
+ # 186 M-:
+ :ed_unassigned,
+ # 187 M-;
+ :ed_unassigned,
+ # 188 M-<
+ :ed_unassigned,
+ # 189 M-=
+ :ed_unassigned,
+ # 190 M->
+ :ed_unassigned,
+ # 191 M-?
+ :ed_unassigned,
+ # 192 M-@
+ :ed_unassigned,
+ # 193 M-A
+ :ed_unassigned,
+ # 194 M-B
+ :ed_unassigned,
+ # 195 M-C
+ :ed_unassigned,
+ # 196 M-D
+ :ed_unassigned,
+ # 197 M-E
+ :ed_unassigned,
+ # 198 M-F
+ :ed_unassigned,
+ # 199 M-G
+ :ed_unassigned,
+ # 200 M-H
+ :ed_unassigned,
+ # 201 M-I
+ :ed_unassigned,
+ # 202 M-J
+ :ed_unassigned,
+ # 203 M-K
+ :ed_unassigned,
+ # 204 M-L
+ :ed_unassigned,
+ # 205 M-M
+ :ed_unassigned,
+ # 206 M-N
+ :ed_unassigned,
+ # 207 M-O
+ :ed_unassigned,
+ # 208 M-P
+ :ed_unassigned,
+ # 209 M-Q
+ :ed_unassigned,
+ # 210 M-R
+ :ed_unassigned,
+ # 211 M-S
+ :ed_unassigned,
+ # 212 M-T
+ :ed_unassigned,
+ # 213 M-U
+ :ed_unassigned,
+ # 214 M-V
+ :ed_unassigned,
+ # 215 M-W
+ :ed_unassigned,
+ # 216 M-X
+ :ed_unassigned,
+ # 217 M-Y
+ :ed_unassigned,
+ # 218 M-Z
+ :ed_unassigned,
+ # 219 M-[
+ :ed_unassigned,
+ # 220 M-\
+ :ed_unassigned,
+ # 221 M-]
+ :ed_unassigned,
+ # 222 M-^
+ :ed_unassigned,
+ # 223 M-_
+ :ed_unassigned,
+ # 224 M-`
+ :ed_unassigned,
+ # 225 M-a
+ :ed_unassigned,
+ # 226 M-b
+ :ed_unassigned,
+ # 227 M-c
+ :ed_unassigned,
+ # 228 M-d
+ :ed_unassigned,
+ # 229 M-e
+ :ed_unassigned,
+ # 230 M-f
+ :ed_unassigned,
+ # 231 M-g
+ :ed_unassigned,
+ # 232 M-h
+ :ed_unassigned,
+ # 233 M-i
+ :ed_unassigned,
+ # 234 M-j
+ :ed_unassigned,
+ # 235 M-k
+ :ed_unassigned,
+ # 236 M-l
+ :ed_unassigned,
+ # 237 M-m
+ :ed_unassigned,
+ # 238 M-n
+ :ed_unassigned,
+ # 239 M-o
+ :ed_unassigned,
+ # 240 M-p
+ :ed_unassigned,
+ # 241 M-q
+ :ed_unassigned,
+ # 242 M-r
+ :ed_unassigned,
+ # 243 M-s
+ :ed_unassigned,
+ # 244 M-t
+ :ed_unassigned,
+ # 245 M-u
+ :ed_unassigned,
+ # 246 M-v
+ :ed_unassigned,
+ # 247 M-w
+ :ed_unassigned,
+ # 248 M-x
+ :ed_unassigned,
+ # 249 M-y
+ :ed_unassigned,
+ # 250 M-z
+ :ed_unassigned,
+ # 251 M-{
+ :ed_unassigned,
+ # 252 M-|
+ :ed_unassigned,
+ # 253 M-}
+ :ed_unassigned,
+ # 254 M-~
+ :ed_unassigned,
+ # 255 M-^?
+ :ed_unassigned
+ # EOF
+ ]
+end
diff --git a/lib/reline/key_stroke.rb b/lib/reline/key_stroke.rb
new file mode 100644
index 0000000000..017e3db00a
--- /dev/null
+++ b/lib/reline/key_stroke.rb
@@ -0,0 +1,55 @@
+class Reline::KeyStroke
+ using Module.new {
+ refine Array do
+ def start_with?(other)
+ other.size <= size && other == self.take(other.size)
+ end
+
+ def bytes
+ self
+ end
+ end
+ }
+
+ def initialize(config)
+ @config = config
+ end
+
+ def match_status(input)
+ key_mapping.keys.select { |lhs|
+ lhs.start_with? input
+ }.tap { |it|
+ return :matched if it.size == 1 && (it.max_by(&:size)&.size&.== input.size)
+ return :matching if it.size == 1 && (it.max_by(&:size)&.size&.!= input.size)
+ return :matched if it.max_by(&:size)&.size&.< input.size
+ return :matching if it.size > 1
+ }
+ key_mapping.keys.select { |lhs|
+ input.start_with? lhs
+ }.tap { |it|
+ return it.size > 0 ? :matched : :unmatched
+ }
+ end
+
+ def expand(input)
+ lhs = key_mapping.keys.select { |item| input.start_with? item }.sort_by(&:size).reverse.first
+ return input unless lhs
+ rhs = key_mapping[lhs]
+
+ case rhs
+ when String
+ rhs_bytes = rhs.bytes
+ expand(expand(rhs_bytes) + expand(input.drop(lhs.size)))
+ when Symbol
+ [rhs] + expand(input.drop(lhs.size))
+ when Array
+ rhs
+ end
+ end
+
+ private
+
+ def key_mapping
+ @config.key_bindings
+ end
+end
diff --git a/lib/reline/kill_ring.rb b/lib/reline/kill_ring.rb
new file mode 100644
index 0000000000..bb3684b42b
--- /dev/null
+++ b/lib/reline/kill_ring.rb
@@ -0,0 +1,125 @@
+class Reline::KillRing
+ include Enumerable
+
+ module State
+ FRESH = :fresh
+ CONTINUED = :continued
+ PROCESSED = :processed
+ YANK = :yank
+ end
+
+ RingPoint = Struct.new(:backward, :forward, :str) do
+ def initialize(str)
+ super(nil, nil, str)
+ end
+
+ def ==(other)
+ object_id == other.object_id
+ end
+ end
+
+ class RingBuffer
+ attr_reader :size
+ attr_reader :head
+
+ def initialize(max = 1024)
+ @max = max
+ @size = 0
+ @head = nil # reading head of ring-shaped tape
+ end
+
+ def <<(point)
+ if @size.zero?
+ @head = point
+ @head.backward = @head
+ @head.forward = @head
+ @size = 1
+ elsif @size >= @max
+ tail = @head.forward
+ new_tail = tail.forward
+ @head.forward = point
+ point.backward = @head
+ new_tail.backward = point
+ point.forward = new_tail
+ @head = point
+ else
+ tail = @head.forward
+ @head.forward = point
+ point.backward = @head
+ tail.backward = point
+ point.forward = tail
+ @head = point
+ @size += 1
+ end
+ end
+
+ def empty?
+ @size.zero?
+ end
+ end
+
+ def initialize(max = 1024)
+ @ring = RingBuffer.new(max)
+ @ring_pointer = nil
+ @buffer = nil
+ @state = State::FRESH
+ end
+
+ def append(string, before_p = false)
+ case @state
+ when State::FRESH, State::YANK
+ @ring << RingPoint.new(string)
+ @state = State::CONTINUED
+ when State::CONTINUED, State::PROCESSED
+ if before_p
+ @ring.head.str.prepend(string)
+ else
+ @ring.head.str.concat(string)
+ end
+ @state = State::CONTINUED
+ end
+ end
+
+ def process
+ case @state
+ when State::FRESH
+ # nothing to do
+ when State::CONTINUED
+ @state = State::PROCESSED
+ when State::PROCESSED
+ @state = State::FRESH
+ when State::YANK
+ # nothing to do
+ end
+ end
+
+ def yank
+ unless @ring.empty?
+ @state = State::YANK
+ @ring_pointer = @ring.head
+ @ring_pointer.str
+ else
+ nil
+ end
+ end
+
+ def yank_pop
+ if @state == State::YANK
+ prev_yank = @ring_pointer.str
+ @ring_pointer = @ring_pointer.backward
+ [@ring_pointer.str, prev_yank]
+ else
+ nil
+ end
+ end
+
+ def each
+ start = head = @ring.head
+ loop do
+ break if head.nil?
+ yield head.str
+ head = head.backward
+ break if head == start
+ end
+ end
+end
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
new file mode 100644
index 0000000000..7d71e62d63
--- /dev/null
+++ b/lib/reline/line_editor.rb
@@ -0,0 +1,2781 @@
+require 'reline/kill_ring'
+require 'reline/unicode'
+
+require 'tempfile'
+
+class Reline::LineEditor
+ # TODO: undo
+ attr_reader :line
+ attr_reader :byte_pointer
+ attr_accessor :confirm_multiline_termination_proc
+ attr_accessor :completion_proc
+ attr_accessor :completion_append_character
+ attr_accessor :output_modifier_proc
+ attr_accessor :prompt_proc
+ attr_accessor :auto_indent_proc
+ attr_accessor :pre_input_hook
+ attr_accessor :dig_perfect_match_proc
+ attr_writer :output
+
+ VI_MOTIONS = %i{
+ ed_prev_char
+ ed_next_char
+ vi_zero
+ ed_move_to_beg
+ ed_move_to_end
+ vi_to_column
+ vi_next_char
+ vi_prev_char
+ vi_next_word
+ vi_prev_word
+ vi_to_next_char
+ vi_to_prev_char
+ vi_end_word
+ vi_next_big_word
+ vi_prev_big_word
+ vi_end_big_word
+ vi_repeat_next_char
+ vi_repeat_prev_char
+ }
+
+ module CompletionState
+ NORMAL = :normal
+ COMPLETION = :completion
+ MENU = :menu
+ JOURNEY = :journey
+ MENU_WITH_PERFECT_MATCH = :menu_with_perfect_match
+ PERFECT_MATCH = :perfect_match
+ end
+
+ CompletionJourneyData = Struct.new('CompletionJourneyData', :preposing, :postposing, :list, :pointer)
+ MenuInfo = Struct.new('MenuInfo', :target, :list)
+
+ PROMPT_LIST_CACHE_TIMEOUT = 0.5
+
+ def initialize(config, encoding)
+ @config = config
+ @completion_append_character = ''
+ reset_variables(encoding: encoding)
+ end
+
+ def set_pasting_state(in_pasting)
+ @in_pasting = in_pasting
+ end
+
+ def simplified_rendering?
+ if finished?
+ false
+ elsif @just_cursor_moving and not @rerender_all
+ true
+ else
+ not @rerender_all and not finished? and @in_pasting
+ end
+ end
+
+ private def check_mode_string
+ mode_string = nil
+ if @config.show_mode_in_prompt
+ if @config.editing_mode_is?(:vi_command)
+ mode_string = @config.vi_cmd_mode_string
+ elsif @config.editing_mode_is?(:vi_insert)
+ mode_string = @config.vi_ins_mode_string
+ elsif @config.editing_mode_is?(:emacs)
+ mode_string = @config.emacs_mode_string
+ else
+ mode_string = '?'
+ end
+ end
+ if mode_string != @prev_mode_string
+ @rerender_all = true
+ end
+ @prev_mode_string = mode_string
+ mode_string
+ end
+
+ private def check_multiline_prompt(buffer, prompt)
+ if @vi_arg
+ prompt = "(arg: #{@vi_arg}) "
+ @rerender_all = true
+ elsif @searching_prompt
+ prompt = @searching_prompt
+ @rerender_all = true
+ else
+ prompt = @prompt
+ end
+ if simplified_rendering?
+ mode_string = check_mode_string
+ prompt = mode_string + prompt if mode_string
+ return [prompt, calculate_width(prompt, true), [prompt] * buffer.size]
+ end
+ if @prompt_proc
+ use_cached_prompt_list = false
+ if @cached_prompt_list
+ if @just_cursor_moving
+ use_cached_prompt_list = true
+ elsif Time.now.to_f < (@prompt_cache_time + PROMPT_LIST_CACHE_TIMEOUT) and buffer.size == @cached_prompt_list.size
+ use_cached_prompt_list = true
+ end
+ end
+ use_cached_prompt_list = false if @rerender_all
+ if use_cached_prompt_list
+ prompt_list = @cached_prompt_list
+ else
+ prompt_list = @cached_prompt_list = @prompt_proc.(buffer)
+ @prompt_cache_time = Time.now.to_f
+ end
+ prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
+ prompt_list = [prompt] if prompt_list.empty?
+ mode_string = check_mode_string
+ prompt_list = prompt_list.map{ |pr| mode_string + pr } if mode_string
+ prompt = prompt_list[@line_index]
+ prompt = prompt_list[0] if prompt.nil?
+ prompt = prompt_list.last if prompt.nil?
+ if buffer.size > prompt_list.size
+ (buffer.size - prompt_list.size).times do
+ prompt_list << prompt_list.last
+ end
+ end
+ prompt_width = calculate_width(prompt, true)
+ [prompt, prompt_width, prompt_list]
+ else
+ mode_string = check_mode_string
+ prompt = mode_string + prompt if mode_string
+ prompt_width = calculate_width(prompt, true)
+ [prompt, prompt_width, nil]
+ end
+ end
+
+ def reset(prompt = '', encoding:)
+ @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
+ @screen_size = Reline::IOGate.get_screen_size
+ @screen_height = @screen_size.first
+ reset_variables(prompt, encoding: encoding)
+ @old_trap = Signal.trap('SIGINT') {
+ if @scroll_partial_screen
+ move_cursor_down(@screen_height - (@line_index - @scroll_partial_screen) - 1)
+ else
+ move_cursor_down(@highest_in_all - @line_index - 1)
+ end
+ Reline::IOGate.move_cursor_column(0)
+ scroll_down(1)
+ @old_trap.call if @old_trap.respond_to?(:call) # can also be string, ex: "DEFAULT"
+ raise Interrupt
+ }
+ Reline::IOGate.set_winch_handler do
+ @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
+ old_screen_size = @screen_size
+ @screen_size = Reline::IOGate.get_screen_size
+ @screen_height = @screen_size.first
+ if old_screen_size.last < @screen_size.last # columns increase
+ @rerender_all = true
+ rerender
+ else
+ back = 0
+ new_buffer = whole_lines
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer, prompt)
+ new_buffer.each_with_index do |line, index|
+ prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
+ width = prompt_width + calculate_width(line)
+ height = calculate_height_by_width(width)
+ back += height
+ end
+ @highest_in_all = back
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @first_line_started_from =
+ if @line_index.zero?
+ 0
+ else
+ calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ if @prompt_proc
+ prompt = prompt_list[@line_index]
+ prompt_width = calculate_width(prompt, true)
+ end
+ calculate_nearest_cursor
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @rerender_all = true
+ end
+ end
+ end
+
+ def finalize
+ Signal.trap('SIGINT', @old_trap)
+ end
+
+ def eof?
+ @eof
+ end
+
+ def reset_variables(prompt = '', encoding:)
+ @prompt = prompt
+ @mark_pointer = nil
+ @encoding = encoding
+ @is_multiline = false
+ @finished = false
+ @cleared = false
+ @rerender_all = false
+ @history_pointer = nil
+ @kill_ring ||= Reline::KillRing.new
+ @vi_clipboard = ''
+ @vi_arg = nil
+ @waiting_proc = nil
+ @waiting_operator_proc = nil
+ @waiting_operator_vi_arg = nil
+ @completion_journey_data = nil
+ @completion_state = CompletionState::NORMAL
+ @perfect_matched = nil
+ @menu_info = nil
+ @first_prompt = true
+ @searching_prompt = nil
+ @first_char = true
+ @add_newline_to_end_of_buffer = false
+ @just_cursor_moving = nil
+ @cached_prompt_list = nil
+ @prompt_cache_time = nil
+ @eof = false
+ @continuous_insertion_buffer = String.new(encoding: @encoding)
+ @scroll_partial_screen = nil
+ @prev_mode_string = nil
+ @drop_terminate_spaces = false
+ @in_pasting = false
+ @auto_indent_proc = nil
+ reset_line
+ end
+
+ def reset_line
+ @cursor = 0
+ @cursor_max = 0
+ @byte_pointer = 0
+ @buffer_of_lines = [String.new(encoding: @encoding)]
+ @line_index = 0
+ @previous_line_index = nil
+ @line = @buffer_of_lines[0]
+ @first_line_started_from = 0
+ @move_up = 0
+ @started_from = 0
+ @highest_in_this = 1
+ @highest_in_all = 1
+ @line_backup_in_history = nil
+ @multibyte_buffer = String.new(encoding: 'ASCII-8BIT')
+ @check_new_auto_indent = false
+ end
+
+ def multiline_on
+ @is_multiline = true
+ end
+
+ def multiline_off
+ @is_multiline = false
+ end
+
+ private def calculate_height_by_lines(lines, prompt)
+ result = 0
+ prompt_list = prompt.is_a?(Array) ? prompt : nil
+ lines.each_with_index { |line, i|
+ prompt = prompt_list[i] if prompt_list and prompt_list[i]
+ result += calculate_height_by_width(calculate_width(prompt, true) + calculate_width(line))
+ }
+ result
+ end
+
+ private def insert_new_line(cursor_line, next_line)
+ @line = cursor_line
+ @buffer_of_lines.insert(@line_index + 1, String.new(next_line, encoding: @encoding))
+ @previous_line_index = @line_index
+ @line_index += 1
+ @just_cursor_moving = false
+ end
+
+ private def calculate_height_by_width(width)
+ width.div(@screen_size.last) + 1
+ end
+
+ private def split_by_width(str, max_width)
+ Reline::Unicode.split_by_width(str, max_width, @encoding)
+ end
+
+ private def scroll_down(val)
+ if val <= @rest_height
+ Reline::IOGate.move_cursor_down(val)
+ @rest_height -= val
+ else
+ Reline::IOGate.move_cursor_down(@rest_height)
+ Reline::IOGate.scroll_down(val - @rest_height)
+ @rest_height = 0
+ end
+ end
+
+ private def move_cursor_up(val)
+ if val > 0
+ Reline::IOGate.move_cursor_up(val)
+ @rest_height += val
+ elsif val < 0
+ move_cursor_down(-val)
+ end
+ end
+
+ private def move_cursor_down(val)
+ if val > 0
+ Reline::IOGate.move_cursor_down(val)
+ @rest_height -= val
+ @rest_height = 0 if @rest_height < 0
+ elsif val < 0
+ move_cursor_up(-val)
+ end
+ end
+
+ private def calculate_nearest_cursor(line_to_calc = @line, cursor = @cursor, started_from = @started_from, byte_pointer = @byte_pointer, update = true)
+ new_cursor_max = calculate_width(line_to_calc)
+ new_cursor = 0
+ new_byte_pointer = 0
+ height = 1
+ max_width = @screen_size.last
+ if @config.editing_mode_is?(:vi_command)
+ last_byte_size = Reline::Unicode.get_prev_mbchar_size(line_to_calc, line_to_calc.bytesize)
+ if last_byte_size > 0
+ last_mbchar = line_to_calc.byteslice(line_to_calc.bytesize - last_byte_size, last_byte_size)
+ last_width = Reline::Unicode.get_mbchar_width(last_mbchar)
+ end_of_line_cursor = new_cursor_max - last_width
+ else
+ end_of_line_cursor = new_cursor_max
+ end
+ else
+ end_of_line_cursor = new_cursor_max
+ end
+ line_to_calc.grapheme_clusters.each do |gc|
+ mbchar = gc.encode(Encoding::UTF_8)
+ mbchar_width = Reline::Unicode.get_mbchar_width(mbchar)
+ now = new_cursor + mbchar_width
+ if now > end_of_line_cursor or now > cursor
+ break
+ end
+ new_cursor += mbchar_width
+ if new_cursor > max_width * height
+ height += 1
+ end
+ new_byte_pointer += gc.bytesize
+ end
+ new_started_from = height - 1
+ if update
+ @cursor = new_cursor
+ @cursor_max = new_cursor_max
+ @started_from = new_started_from
+ @byte_pointer = new_byte_pointer
+ else
+ [new_cursor, new_cursor_max, new_started_from, new_byte_pointer]
+ end
+ end
+
+ def rerender_all
+ @rerender_all = true
+ process_insert(force: true)
+ rerender
+ end
+
+ def rerender
+ return if @line.nil?
+ if @menu_info
+ scroll_down(@highest_in_all - @first_line_started_from)
+ @rerender_all = true
+ end
+ if @menu_info
+ show_menu
+ @menu_info = nil
+ end
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines, prompt)
+ if @cleared
+ clear_screen_buffer(prompt, prompt_list, prompt_width)
+ @cleared = false
+ return
+ end
+ if @is_multiline and finished? and @scroll_partial_screen
+ # Re-output all code higher than the screen when finished.
+ Reline::IOGate.move_cursor_up(@first_line_started_from + @started_from - @scroll_partial_screen)
+ Reline::IOGate.move_cursor_column(0)
+ @scroll_partial_screen = nil
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines, prompt)
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ new_lines = whole_lines
+ end
+ modify_lines(new_lines).each_with_index do |line, index|
+ @output.write "#{prompt_list ? prompt_list[index] : prompt}#{line}\n"
+ Reline::IOGate.erase_after_cursor
+ end
+ @output.flush
+ return
+ end
+ new_highest_in_this = calculate_height_by_width(prompt_width + calculate_width(@line.nil? ? '' : @line))
+ # FIXME: end of logical line sometimes breaks
+ rendered = false
+ if @add_newline_to_end_of_buffer
+ rerender_added_newline(prompt, prompt_width)
+ @add_newline_to_end_of_buffer = false
+ else
+ if @just_cursor_moving and not @rerender_all
+ rendered = just_move_cursor
+ @just_cursor_moving = false
+ return
+ elsif @previous_line_index or new_highest_in_this != @highest_in_this
+ rerender_changed_current_line
+ @previous_line_index = nil
+ rendered = true
+ elsif @rerender_all
+ rerender_all_lines
+ @rerender_all = false
+ rendered = true
+ else
+ end
+ end
+ if @is_multiline
+ if finished?
+ # Always rerender on finish because output_modifier_proc may return a different output.
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ new_lines = whole_lines
+ end
+ line = modify_lines(new_lines)[@line_index]
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines, prompt)
+ render_partial(prompt, prompt_width, line, @first_line_started_from)
+ move_cursor_down(@highest_in_all - (@first_line_started_from + @highest_in_this - 1) - 1)
+ scroll_down(1)
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
+ elsif not rendered
+ unless @in_pasting
+ line = modify_lines(whole_lines)[@line_index]
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines, prompt)
+ render_partial(prompt, prompt_width, line, @first_line_started_from)
+ end
+ end
+ @buffer_of_lines[@line_index] = @line
+ @rest_height = 0 if @scroll_partial_screen
+ else
+ line = modify_lines(whole_lines)[@line_index]
+ render_partial(prompt, prompt_width, line, 0)
+ if finished?
+ scroll_down(1)
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
+ end
+ end
+ end
+
+ private def calculate_scroll_partial_screen(highest_in_all, cursor_y)
+ if @screen_height < highest_in_all
+ old_scroll_partial_screen = @scroll_partial_screen
+ if cursor_y == 0
+ @scroll_partial_screen = 0
+ elsif cursor_y == (highest_in_all - 1)
+ @scroll_partial_screen = highest_in_all - @screen_height
+ else
+ if @scroll_partial_screen
+ if cursor_y <= @scroll_partial_screen
+ @scroll_partial_screen = cursor_y
+ elsif (@scroll_partial_screen + @screen_height - 1) < cursor_y
+ @scroll_partial_screen = cursor_y - (@screen_height - 1)
+ end
+ else
+ if cursor_y > (@screen_height - 1)
+ @scroll_partial_screen = cursor_y - (@screen_height - 1)
+ else
+ @scroll_partial_screen = 0
+ end
+ end
+ end
+ if @scroll_partial_screen != old_scroll_partial_screen
+ @rerender_all = true
+ end
+ else
+ if @scroll_partial_screen
+ @rerender_all = true
+ end
+ @scroll_partial_screen = nil
+ end
+ end
+
+ private def rerender_added_newline(prompt, prompt_width)
+ scroll_down(1)
+ @buffer_of_lines[@previous_line_index] = @line
+ @line = @buffer_of_lines[@line_index]
+ unless @in_pasting
+ render_partial(prompt, prompt_width, @line, @first_line_started_from + @started_from + 1, with_control: false)
+ end
+ @cursor = @cursor_max = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @highest_in_all += @highest_in_this
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @first_line_started_from += @started_from + 1
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ @previous_line_index = nil
+ end
+
+ def just_move_cursor
+ prompt, prompt_width, prompt_list = check_multiline_prompt(@buffer_of_lines, prompt)
+ move_cursor_up(@started_from)
+ new_first_line_started_from =
+ if @line_index.zero?
+ 0
+ else
+ calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ first_line_diff = new_first_line_started_from - @first_line_started_from
+ new_cursor, new_cursor_max, new_started_from, new_byte_pointer = calculate_nearest_cursor(@buffer_of_lines[@line_index], @cursor, @started_from, @byte_pointer, false)
+ new_started_from = calculate_height_by_width(prompt_width + new_cursor) - 1
+ calculate_scroll_partial_screen(@highest_in_all, new_first_line_started_from + new_started_from)
+ @previous_line_index = nil
+ if @rerender_all
+ @line = @buffer_of_lines[@line_index]
+ rerender_all_lines
+ @rerender_all = false
+ true
+ else
+ @line = @buffer_of_lines[@line_index]
+ @first_line_started_from = new_first_line_started_from
+ @started_from = new_started_from
+ @cursor = new_cursor
+ @cursor_max = new_cursor_max
+ @byte_pointer = new_byte_pointer
+ move_cursor_down(first_line_diff + @started_from)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ false
+ end
+ end
+
+ private def rerender_changed_current_line
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ new_lines = whole_lines
+ end
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines, prompt)
+ all_height = calculate_height_by_lines(new_lines, prompt_list || prompt)
+ diff = all_height - @highest_in_all
+ move_cursor_down(@highest_in_all - @first_line_started_from - @started_from - 1)
+ if diff > 0
+ scroll_down(diff)
+ move_cursor_up(all_height - 1)
+ elsif diff < 0
+ (-diff).times do
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
+ move_cursor_up(1)
+ end
+ move_cursor_up(all_height - 1)
+ else
+ move_cursor_up(all_height - 1)
+ end
+ @highest_in_all = all_height
+ back = render_whole_lines(new_lines, prompt_list || prompt, prompt_width)
+ move_cursor_up(back)
+ if @previous_line_index
+ @buffer_of_lines[@previous_line_index] = @line
+ @line = @buffer_of_lines[@line_index]
+ end
+ @first_line_started_from =
+ if @line_index.zero?
+ 0
+ else
+ calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ if @prompt_proc
+ prompt = prompt_list[@line_index]
+ prompt_width = calculate_width(prompt, true)
+ end
+ move_cursor_down(@first_line_started_from)
+ calculate_nearest_cursor
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ move_cursor_down(@started_from)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ end
+
+ private def rerender_all_lines
+ move_cursor_up(@first_line_started_from + @started_from)
+ Reline::IOGate.move_cursor_column(0)
+ back = 0
+ new_buffer = whole_lines
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer, prompt)
+ new_buffer.each_with_index do |line, index|
+ prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
+ width = prompt_width + calculate_width(line)
+ height = calculate_height_by_width(width)
+ back += height
+ end
+ old_highest_in_all = @highest_in_all
+ if @line_index.zero?
+ new_first_line_started_from = 0
+ else
+ new_first_line_started_from = calculate_height_by_lines(new_buffer[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ new_started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ calculate_scroll_partial_screen(back, new_first_line_started_from + new_started_from)
+ if @scroll_partial_screen
+ move_cursor_up(@first_line_started_from + @started_from)
+ scroll_down(@screen_height - 1)
+ move_cursor_up(@screen_height)
+ Reline::IOGate.move_cursor_column(0)
+ elsif back > old_highest_in_all
+ scroll_down(back - 1)
+ move_cursor_up(back - 1)
+ elsif back < old_highest_in_all
+ scroll_down(back)
+ Reline::IOGate.erase_after_cursor
+ (old_highest_in_all - back - 1).times do
+ scroll_down(1)
+ Reline::IOGate.erase_after_cursor
+ end
+ move_cursor_up(old_highest_in_all - 1)
+ end
+ render_whole_lines(new_buffer, prompt_list || prompt, prompt_width)
+ if @prompt_proc
+ prompt = prompt_list[@line_index]
+ prompt_width = calculate_width(prompt, true)
+ end
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @highest_in_all = back
+ @first_line_started_from = new_first_line_started_from
+ @started_from = new_started_from
+ if @scroll_partial_screen
+ Reline::IOGate.move_cursor_up(@screen_height - (@first_line_started_from + @started_from - @scroll_partial_screen) - 1)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ else
+ move_cursor_down(@first_line_started_from + @started_from - back + 1)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ end
+ end
+
+ private def render_whole_lines(lines, prompt, prompt_width)
+ rendered_height = 0
+ modify_lines(lines).each_with_index do |line, index|
+ if prompt.is_a?(Array)
+ line_prompt = prompt[index]
+ prompt_width = calculate_width(line_prompt, true)
+ else
+ line_prompt = prompt
+ end
+ height = render_partial(line_prompt, prompt_width, line, rendered_height, with_control: false)
+ if index < (lines.size - 1)
+ if @scroll_partial_screen
+ if (@scroll_partial_screen - height) < rendered_height and (@scroll_partial_screen + @screen_height - 1) >= (rendered_height + height)
+ move_cursor_down(1)
+ end
+ else
+ scroll_down(1)
+ end
+ rendered_height += height
+ else
+ rendered_height += height - 1
+ end
+ end
+ rendered_height
+ end
+
+ private def render_partial(prompt, prompt_width, line_to_render, this_started_from, with_control: true)
+ visual_lines, height = split_by_width(line_to_render.nil? ? prompt : prompt + line_to_render, @screen_size.last)
+ cursor_up_from_last_line = 0
+ # TODO: This logic would be sometimes buggy if this logical line isn't the current @line_index.
+ if @scroll_partial_screen
+ last_visual_line = this_started_from + (height - 1)
+ last_screen_line = @scroll_partial_screen + (@screen_height - 1)
+ if (@scroll_partial_screen - this_started_from) >= height
+ # Render nothing because this line is before the screen.
+ visual_lines = []
+ elsif this_started_from > last_screen_line
+ # Render nothing because this line is after the screen.
+ visual_lines = []
+ else
+ deleted_lines_before_screen = []
+ if @scroll_partial_screen > this_started_from and last_visual_line >= @scroll_partial_screen
+ # A part of visual lines are before the screen.
+ deleted_lines_before_screen = visual_lines.shift((@scroll_partial_screen - this_started_from) * 2)
+ deleted_lines_before_screen.compact!
+ end
+ if this_started_from <= last_screen_line and last_screen_line < last_visual_line
+ # A part of visual lines are after the screen.
+ visual_lines.pop((last_visual_line - last_screen_line) * 2)
+ end
+ move_cursor_up(deleted_lines_before_screen.size - @started_from)
+ cursor_up_from_last_line = @started_from - deleted_lines_before_screen.size
+ end
+ end
+ if with_control
+ if height > @highest_in_this
+ diff = height - @highest_in_this
+ scroll_down(diff)
+ @highest_in_all += diff
+ @highest_in_this = height
+ move_cursor_up(diff)
+ elsif height < @highest_in_this
+ diff = @highest_in_this - height
+ @highest_in_all -= diff
+ @highest_in_this = height
+ end
+ move_cursor_up(@started_from)
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ cursor_up_from_last_line = height - 1 - @started_from
+ end
+ if Reline::Unicode::CSI_REGEXP.match?(prompt + line_to_render)
+ @output.write "\e[0m" # clear character decorations
+ end
+ visual_lines.each_with_index do |line, index|
+ Reline::IOGate.move_cursor_column(0)
+ if line.nil?
+ if calculate_width(visual_lines[index - 1], true) == Reline::IOGate.get_screen_size.last
+ # reaches the end of line
+ if Reline::IOGate.win? and Reline::IOGate.win_legacy_console?
+ # A newline is automatically inserted if a character is rendered at
+ # eol on command prompt.
+ else
+ # When the cursor is at the end of the line and erases characters
+ # after the cursor, some terminals delete the character at the
+ # cursor position.
+ move_cursor_down(1)
+ Reline::IOGate.move_cursor_column(0)
+ end
+ else
+ Reline::IOGate.erase_after_cursor
+ move_cursor_down(1)
+ Reline::IOGate.move_cursor_column(0)
+ end
+ next
+ end
+ @output.write line
+ if Reline::IOGate.win? and Reline::IOGate.win_legacy_console? and calculate_width(line, true) == Reline::IOGate.get_screen_size.last
+ # A newline is automatically inserted if a character is rendered at eol on command prompt.
+ @rest_height -= 1 if @rest_height > 0
+ end
+ @output.flush
+ if @first_prompt
+ @first_prompt = false
+ @pre_input_hook&.call
+ end
+ end
+ unless visual_lines.empty?
+ Reline::IOGate.erase_after_cursor
+ Reline::IOGate.move_cursor_column(0)
+ end
+ if with_control
+ # Just after rendring, so the cursor is on the last line.
+ if finished?
+ Reline::IOGate.move_cursor_column(0)
+ else
+ # Moves up from bottom of lines to the cursor position.
+ move_cursor_up(cursor_up_from_last_line)
+ # This logic is buggy if a fullwidth char is wrapped because there is only one halfwidth at end of a line.
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ end
+ end
+ height
+ end
+
+ private def modify_lines(before)
+ return before if before.nil? || before.empty? || simplified_rendering?
+
+ if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: finished?)
+ after.lines("\n").map { |l| l.chomp('') }
+ else
+ before
+ end
+ end
+
+ private def show_menu
+ scroll_down(@highest_in_all - @first_line_started_from)
+ @rerender_all = true
+ @menu_info.list.sort!.each do |item|
+ Reline::IOGate.move_cursor_column(0)
+ @output.write item
+ @output.flush
+ scroll_down(1)
+ end
+ scroll_down(@highest_in_all - 1)
+ move_cursor_up(@highest_in_all - 1 - @first_line_started_from)
+ end
+
+ private def clear_screen_buffer(prompt, prompt_list, prompt_width)
+ Reline::IOGate.clear_screen
+ back = 0
+ modify_lines(whole_lines).each_with_index do |line, index|
+ if @prompt_proc
+ pr = prompt_list[index]
+ height = render_partial(pr, calculate_width(pr), line, back, with_control: false)
+ else
+ height = render_partial(prompt, prompt_width, line, back, with_control: false)
+ end
+ if index < (@buffer_of_lines.size - 1)
+ move_cursor_down(height)
+ back += height
+ end
+ end
+ move_cursor_up(back)
+ move_cursor_down(@first_line_started_from + @started_from)
+ @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ end
+
+ def editing_mode
+ @config.editing_mode
+ end
+
+ private def menu(target, list)
+ @menu_info = MenuInfo.new(target, list)
+ end
+
+ private def complete_internal_proc(list, is_menu)
+ preposing, target, postposing = retrieve_completion_block
+ list = list.select { |i|
+ if i and not Encoding.compatible?(target.encoding, i.encoding)
+ raise Encoding::CompatibilityError, "#{target.encoding.name} is not compatible with #{i.encoding.name}"
+ end
+ if @config.completion_ignore_case
+ i&.downcase&.start_with?(target.downcase)
+ else
+ i&.start_with?(target)
+ end
+ }.uniq
+ if is_menu
+ menu(target, list)
+ return nil
+ end
+ completed = list.inject { |memo, item|
+ begin
+ memo_mbchars = memo.unicode_normalize.grapheme_clusters
+ item_mbchars = item.unicode_normalize.grapheme_clusters
+ rescue Encoding::CompatibilityError
+ memo_mbchars = memo.grapheme_clusters
+ item_mbchars = item.grapheme_clusters
+ end
+ size = [memo_mbchars.size, item_mbchars.size].min
+ result = ''
+ size.times do |i|
+ if @config.completion_ignore_case
+ if memo_mbchars[i].casecmp?(item_mbchars[i])
+ result << memo_mbchars[i]
+ else
+ break
+ end
+ else
+ if memo_mbchars[i] == item_mbchars[i]
+ result << memo_mbchars[i]
+ else
+ break
+ end
+ end
+ end
+ result
+ }
+ [target, preposing, completed, postposing]
+ end
+
+ private def complete(list, just_show_list = false)
+ case @completion_state
+ when CompletionState::NORMAL, CompletionState::JOURNEY
+ @completion_state = CompletionState::COMPLETION
+ when CompletionState::PERFECT_MATCH
+ @dig_perfect_match_proc&.(@perfect_matched)
+ end
+ if just_show_list
+ is_menu = true
+ elsif @completion_state == CompletionState::MENU
+ is_menu = true
+ elsif @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH
+ is_menu = true
+ else
+ is_menu = false
+ end
+ result = complete_internal_proc(list, is_menu)
+ if @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH
+ @completion_state = CompletionState::PERFECT_MATCH
+ end
+ return if result.nil?
+ target, preposing, completed, postposing = result
+ return if completed.nil?
+ if target <= completed and (@completion_state == CompletionState::COMPLETION)
+ if list.include?(completed)
+ if list.one?
+ @completion_state = CompletionState::PERFECT_MATCH
+ else
+ @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
+ end
+ @perfect_matched = completed
+ else
+ @completion_state = CompletionState::MENU
+ end
+ if not just_show_list and target < completed
+ @line = preposing + completed + completion_append_character.to_s + postposing
+ line_to_pointer = preposing + completed + completion_append_character.to_s
+ @cursor_max = calculate_width(@line)
+ @cursor = calculate_width(line_to_pointer)
+ @byte_pointer = line_to_pointer.bytesize
+ end
+ end
+ end
+
+ private def move_completed_list(list, direction)
+ case @completion_state
+ when CompletionState::NORMAL, CompletionState::COMPLETION,
+ CompletionState::MENU, CompletionState::MENU_WITH_PERFECT_MATCH
+ @completion_state = CompletionState::JOURNEY
+ result = retrieve_completion_block
+ return if result.nil?
+ preposing, target, postposing = result
+ @completion_journey_data = CompletionJourneyData.new(
+ preposing, postposing,
+ [target] + list.select{ |item| item.start_with?(target) }, 0)
+ @completion_state = CompletionState::JOURNEY
+ else
+ case direction
+ when :up
+ @completion_journey_data.pointer -= 1
+ if @completion_journey_data.pointer < 0
+ @completion_journey_data.pointer = @completion_journey_data.list.size - 1
+ end
+ when :down
+ @completion_journey_data.pointer += 1
+ if @completion_journey_data.pointer >= @completion_journey_data.list.size
+ @completion_journey_data.pointer = 0
+ end
+ end
+ completed = @completion_journey_data.list[@completion_journey_data.pointer]
+ @line = @completion_journey_data.preposing + completed + @completion_journey_data.postposing
+ line_to_pointer = @completion_journey_data.preposing + completed
+ @cursor_max = calculate_width(@line)
+ @cursor = calculate_width(line_to_pointer)
+ @byte_pointer = line_to_pointer.bytesize
+ end
+ end
+
+ private def run_for_operators(key, method_symbol, &block)
+ if @waiting_operator_proc
+ if VI_MOTIONS.include?(method_symbol)
+ old_cursor, old_byte_pointer = @cursor, @byte_pointer
+ @vi_arg = @waiting_operator_vi_arg if @waiting_operator_vi_arg > 1
+ block.(true)
+ unless @waiting_proc
+ cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer
+ @cursor, @byte_pointer = old_cursor, old_byte_pointer
+ @waiting_operator_proc.(cursor_diff, byte_pointer_diff)
+ else
+ old_waiting_proc = @waiting_proc
+ old_waiting_operator_proc = @waiting_operator_proc
+ current_waiting_operator_proc = @waiting_operator_proc
+ @waiting_proc = proc { |k|
+ old_cursor, old_byte_pointer = @cursor, @byte_pointer
+ old_waiting_proc.(k)
+ cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer
+ @cursor, @byte_pointer = old_cursor, old_byte_pointer
+ current_waiting_operator_proc.(cursor_diff, byte_pointer_diff)
+ @waiting_operator_proc = old_waiting_operator_proc
+ }
+ end
+ else
+ # Ignores operator when not motion is given.
+ block.(false)
+ end
+ @waiting_operator_proc = nil
+ @waiting_operator_vi_arg = nil
+ @vi_arg = nil
+ else
+ block.(false)
+ end
+ end
+
+ private def argumentable?(method_obj)
+ method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :arg }
+ end
+
+ private def inclusive?(method_obj)
+ # If a motion method with the keyword argument "inclusive" follows the
+ # operator, it must contain the character at the cursor position.
+ method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :inclusive }
+ end
+
+ def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
+ if @config.editing_mode_is?(:emacs, :vi_insert) and @waiting_proc.nil? and @waiting_operator_proc.nil?
+ not_insertion = method_symbol != :ed_insert
+ process_insert(force: not_insertion)
+ end
+ if @vi_arg and argumentable?(method_obj)
+ if with_operator and inclusive?(method_obj)
+ method_obj.(key, arg: @vi_arg, inclusive: true)
+ else
+ method_obj.(key, arg: @vi_arg)
+ end
+ else
+ if with_operator and inclusive?(method_obj)
+ method_obj.(key, inclusive: true)
+ else
+ method_obj.(key)
+ end
+ end
+ end
+
+ private def process_key(key, method_symbol)
+ if method_symbol and respond_to?(method_symbol, true)
+ method_obj = method(method_symbol)
+ else
+ method_obj = nil
+ end
+ if method_symbol and key.is_a?(Symbol)
+ if @vi_arg and argumentable?(method_obj)
+ run_for_operators(key, method_symbol) do |with_operator|
+ wrap_method_call(method_symbol, method_obj, key, with_operator)
+ end
+ else
+ wrap_method_call(method_symbol, method_obj, key) if method_obj
+ end
+ @kill_ring.process
+ @vi_arg = nil
+ elsif @vi_arg
+ if key.chr =~ /[0-9]/
+ ed_argument_digit(key)
+ else
+ if argumentable?(method_obj)
+ run_for_operators(key, method_symbol) do |with_operator|
+ wrap_method_call(method_symbol, method_obj, key, with_operator)
+ end
+ elsif @waiting_proc
+ @waiting_proc.(key)
+ elsif method_obj
+ wrap_method_call(method_symbol, method_obj, key)
+ else
+ ed_insert(key) unless @config.editing_mode_is?(:vi_command)
+ end
+ @kill_ring.process
+ @vi_arg = nil
+ end
+ elsif @waiting_proc
+ @waiting_proc.(key)
+ @kill_ring.process
+ elsif method_obj
+ if method_symbol == :ed_argument_digit
+ wrap_method_call(method_symbol, method_obj, key)
+ else
+ run_for_operators(key, method_symbol) do |with_operator|
+ wrap_method_call(method_symbol, method_obj, key, with_operator)
+ end
+ end
+ @kill_ring.process
+ else
+ ed_insert(key) unless @config.editing_mode_is?(:vi_command)
+ end
+ end
+
+ private def normal_char(key)
+ method_symbol = method_obj = nil
+ if key.combined_char.is_a?(Symbol)
+ process_key(key.combined_char, key.combined_char)
+ return
+ end
+ @multibyte_buffer << key.combined_char
+ if @multibyte_buffer.size > 1
+ if @multibyte_buffer.dup.force_encoding(@encoding).valid_encoding?
+ process_key(@multibyte_buffer.dup.force_encoding(@encoding), nil)
+ @multibyte_buffer.clear
+ else
+ # invalid
+ return
+ end
+ else # single byte
+ return if key.char >= 128 # maybe, first byte of multi byte
+ method_symbol = @config.editing_mode.get_method(key.combined_char)
+ if key.with_meta and method_symbol == :ed_unassigned
+ # split ESC + key
+ method_symbol = @config.editing_mode.get_method("\e".ord)
+ process_key("\e".ord, method_symbol)
+ method_symbol = @config.editing_mode.get_method(key.char)
+ process_key(key.char, method_symbol)
+ else
+ process_key(key.combined_char, method_symbol)
+ end
+ @multibyte_buffer.clear
+ end
+ if @config.editing_mode_is?(:vi_command) and @cursor > 0 and @cursor == @cursor_max
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ end
+ end
+
+ def input_key(key)
+ @just_cursor_moving = nil
+ if key.char.nil?
+ if @first_char
+ @line = nil
+ end
+ finish
+ return
+ end
+ old_line = @line.dup
+ @first_char = false
+ completion_occurs = false
+ if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
+ unless @config.disable_completion
+ result = call_completion_proc
+ if result.is_a?(Array)
+ completion_occurs = true
+ process_insert
+ complete(result)
+ end
+ end
+ elsif not @config.disable_completion and @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
+ unless @config.disable_completion
+ result = call_completion_proc
+ if result.is_a?(Array)
+ completion_occurs = true
+ process_insert
+ move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
+ end
+ end
+ elsif Symbol === key.char and respond_to?(key.char, true)
+ process_key(key.char, key.char)
+ else
+ normal_char(key)
+ end
+ unless completion_occurs
+ @completion_state = CompletionState::NORMAL
+ end
+ if not @in_pasting and @just_cursor_moving.nil?
+ if @previous_line_index and @buffer_of_lines[@previous_line_index] == @line
+ @just_cursor_moving = true
+ elsif @previous_line_index.nil? and @buffer_of_lines[@line_index] == @line and old_line == @line
+ @just_cursor_moving = true
+ else
+ @just_cursor_moving = false
+ end
+ else
+ @just_cursor_moving = false
+ end
+ if @is_multiline and @auto_indent_proc and not simplified_rendering?
+ process_auto_indent
+ end
+ end
+
+ def call_completion_proc
+ result = retrieve_completion_block(true)
+ preposing, target, postposing = result
+ if @completion_proc and target
+ argnum = @completion_proc.parameters.inject(0) { |result, item|
+ case item.first
+ when :req, :opt
+ result + 1
+ when :rest
+ break 3
+ end
+ }
+ case argnum
+ when 1
+ result = @completion_proc.(target)
+ when 2
+ result = @completion_proc.(target, preposing)
+ when 3..Float::INFINITY
+ result = @completion_proc.(target, preposing, postposing)
+ end
+ end
+ Reline.core.instance_variable_set(:@completion_quote_character, nil)
+ result
+ end
+
+ private def process_auto_indent
+ return if not @check_new_auto_indent and @previous_line_index # move cursor up or down
+ if @check_new_auto_indent and @previous_line_index and @previous_line_index > 0 and @line_index > @previous_line_index
+ # Fix indent of a line when a newline is inserted to the next
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ new_indent = @auto_indent_proc.(new_lines[0..-3].push(''), @line_index - 1, 0, true)
+ md = @line.match(/\A */)
+ prev_indent = md[0].count(' ')
+ @line = ' ' * new_indent + @line.lstrip
+
+ new_indent = nil
+ result = @auto_indent_proc.(new_lines[0..-2], @line_index - 1, (new_lines[-2].size + 1), false)
+ if result
+ new_indent = result
+ end
+ if new_indent&.>= 0
+ @line = ' ' * new_indent + @line.lstrip
+ end
+ end
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ new_lines = whole_lines
+ end
+ new_indent = @auto_indent_proc.(new_lines, @line_index, @byte_pointer, @check_new_auto_indent)
+ new_indent = @cursor_max if new_indent&.> @cursor_max
+ if new_indent&.>= 0
+ md = new_lines[@line_index].match(/\A */)
+ prev_indent = md[0].count(' ')
+ if @check_new_auto_indent
+ @buffer_of_lines[@line_index] = ' ' * new_indent + @buffer_of_lines[@line_index].lstrip
+ @cursor = new_indent
+ @byte_pointer = new_indent
+ else
+ @line = ' ' * new_indent + @line.lstrip
+ @cursor += new_indent - prev_indent
+ @byte_pointer += new_indent - prev_indent
+ end
+ end
+ @check_new_auto_indent = false
+ end
+
+ def retrieve_completion_block(set_completion_quote_character = false)
+ if Reline.completer_word_break_characters.empty?
+ word_break_regexp = nil
+ else
+ word_break_regexp = /\A[#{Regexp.escape(Reline.completer_word_break_characters)}]/
+ end
+ if Reline.completer_quote_characters.empty?
+ quote_characters_regexp = nil
+ else
+ quote_characters_regexp = /\A[#{Regexp.escape(Reline.completer_quote_characters)}]/
+ end
+ before = @line.byteslice(0, @byte_pointer)
+ rest = nil
+ break_pointer = nil
+ quote = nil
+ closing_quote = nil
+ escaped_quote = nil
+ i = 0
+ while i < @byte_pointer do
+ slice = @line.byteslice(i, @byte_pointer - i)
+ unless slice.valid_encoding?
+ i += 1
+ next
+ end
+ if quote and slice.start_with?(closing_quote)
+ quote = nil
+ i += 1
+ rest = nil
+ elsif quote and slice.start_with?(escaped_quote)
+ # skip
+ i += 2
+ elsif quote_characters_regexp and slice =~ quote_characters_regexp # find new "
+ rest = $'
+ quote = $&
+ closing_quote = /(?!\\)#{Regexp.escape(quote)}/
+ escaped_quote = /\\#{Regexp.escape(quote)}/
+ i += 1
+ break_pointer = i - 1
+ elsif word_break_regexp and not quote and slice =~ word_break_regexp
+ rest = $'
+ i += 1
+ before = @line.byteslice(i, @byte_pointer - i)
+ break_pointer = i
+ else
+ i += 1
+ end
+ end
+ postposing = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
+ if rest
+ preposing = @line.byteslice(0, break_pointer)
+ target = rest
+ if set_completion_quote_character and quote
+ Reline.core.instance_variable_set(:@completion_quote_character, quote)
+ if postposing !~ /(?!\\)#{Regexp.escape(quote)}/ # closing quote
+ insert_text(quote)
+ end
+ end
+ else
+ preposing = ''
+ if break_pointer
+ preposing = @line.byteslice(0, break_pointer)
+ else
+ preposing = ''
+ end
+ target = before
+ end
+ if @is_multiline
+ if @previous_line_index
+ lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ lines = whole_lines
+ end
+ if @line_index > 0
+ preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
+ end
+ if (lines.size - 1) > @line_index
+ postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
+ end
+ end
+ [preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
+ end
+
+ def confirm_multiline_termination
+ temp_buffer = @buffer_of_lines.dup
+ if @previous_line_index and @line_index == (@buffer_of_lines.size - 1)
+ temp_buffer[@previous_line_index] = @line
+ else
+ temp_buffer[@line_index] = @line
+ end
+ @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
+ end
+
+ def insert_text(text)
+ width = calculate_width(text)
+ if @cursor == @cursor_max
+ @line += text
+ else
+ @line = byteinsert(@line, @byte_pointer, text)
+ end
+ @byte_pointer += text.bytesize
+ @cursor += width
+ @cursor_max += width
+ end
+
+ def delete_text(start = nil, length = nil)
+ if start.nil? and length.nil?
+ if @is_multiline
+ if @buffer_of_lines.size == 1
+ @line&.clear
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = 0
+ elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0
+ @buffer_of_lines.pop
+ @line_index -= 1
+ @line = @buffer_of_lines[@line_index]
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = calculate_width(@line)
+ elsif @line_index < (@buffer_of_lines.size - 1)
+ @buffer_of_lines.delete_at(@line_index)
+ @line = @buffer_of_lines[@line_index]
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = calculate_width(@line)
+ end
+ else
+ @line&.clear
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = 0
+ end
+ elsif not start.nil? and not length.nil?
+ if @line
+ before = @line.byteslice(0, start)
+ after = @line.byteslice(start + length, @line.bytesize)
+ @line = before + after
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ end
+ elsif start.is_a?(Range)
+ range = start
+ first = range.first
+ last = range.last
+ last = @line.bytesize - 1 if last > @line.bytesize
+ last += @line.bytesize if last < 0
+ first += @line.bytesize if first < 0
+ range = range.exclude_end? ? first...last : first..last
+ @line = @line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(@encoding)
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ else
+ @line = @line.byteslice(0, start)
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ end
+ end
+
+ def byte_pointer=(val)
+ @byte_pointer = val
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
+ end
+
+ def whole_lines(index: @line_index, line: @line)
+ temp_lines = @buffer_of_lines.dup
+ temp_lines[index] = line
+ temp_lines
+ end
+
+ def whole_buffer
+ if @buffer_of_lines.size == 1 and @line.nil?
+ nil
+ else
+ if @previous_line_index
+ whole_lines(index: @previous_line_index, line: @line).join("\n")
+ else
+ whole_lines.join("\n")
+ end
+ end
+ end
+
+ def finished?
+ @finished
+ end
+
+ def finish
+ @finished = true
+ @rerender_all = true
+ @config.reset
+ end
+
+ private def byteslice!(str, byte_pointer, size)
+ new_str = str.byteslice(0, byte_pointer)
+ new_str << str.byteslice(byte_pointer + size, str.bytesize)
+ [new_str, str.byteslice(byte_pointer, size)]
+ end
+
+ private def byteinsert(str, byte_pointer, other)
+ new_str = str.byteslice(0, byte_pointer)
+ new_str << other
+ new_str << str.byteslice(byte_pointer, str.bytesize)
+ new_str
+ end
+
+ private def calculate_width(str, allow_escape_code = false)
+ Reline::Unicode.calculate_width(str, allow_escape_code)
+ end
+
+ private def key_delete(key)
+ if @config.editing_mode_is?(:vi_insert, :emacs)
+ ed_delete_next_char(key)
+ end
+ end
+
+ private def key_newline(key)
+ if @is_multiline
+ if (@buffer_of_lines.size - 1) == @line_index and @line.bytesize == @byte_pointer
+ @add_newline_to_end_of_buffer = true
+ end
+ next_line = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
+ cursor_line = @line.byteslice(0, @byte_pointer)
+ insert_new_line(cursor_line, next_line)
+ @cursor = 0
+ @check_new_auto_indent = true unless @in_pasting
+ end
+ end
+
+ private def ed_unassigned(key) end # do nothing
+
+ private def process_insert(force: false)
+ return if @continuous_insertion_buffer.empty? or (@in_pasting and not force)
+ width = Reline::Unicode.calculate_width(@continuous_insertion_buffer)
+ bytesize = @continuous_insertion_buffer.bytesize
+ if @cursor == @cursor_max
+ @line += @continuous_insertion_buffer
+ else
+ @line = byteinsert(@line, @byte_pointer, @continuous_insertion_buffer)
+ end
+ @byte_pointer += bytesize
+ @cursor += width
+ @cursor_max += width
+ @continuous_insertion_buffer.clear
+ end
+
+ private def ed_insert(key)
+ str = nil
+ width = nil
+ bytesize = nil
+ if key.instance_of?(String)
+ begin
+ key.encode(Encoding::UTF_8)
+ rescue Encoding::UndefinedConversionError
+ return
+ end
+ str = key
+ bytesize = key.bytesize
+ else
+ begin
+ key.chr.encode(Encoding::UTF_8)
+ rescue Encoding::UndefinedConversionError
+ return
+ end
+ str = key.chr
+ bytesize = 1
+ end
+ if @in_pasting
+ @continuous_insertion_buffer << str
+ return
+ elsif not @continuous_insertion_buffer.empty?
+ process_insert
+ end
+ width = Reline::Unicode.get_mbchar_width(str)
+ if @cursor == @cursor_max
+ @line += str
+ else
+ @line = byteinsert(@line, @byte_pointer, str)
+ end
+ last_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer += bytesize
+ last_mbchar = @line.byteslice((@byte_pointer - bytesize - last_byte_size), last_byte_size)
+ if last_byte_size != 0 and (last_mbchar + str).grapheme_clusters.size == 1
+ width = 0
+ end
+ @cursor += width
+ @cursor_max += width
+ end
+ alias_method :ed_digit, :ed_insert
+ alias_method :self_insert, :ed_insert
+
+ private def ed_quoted_insert(str, arg: 1)
+ @waiting_proc = proc { |key|
+ arg.times do
+ if key == "\C-j".ord or key == "\C-m".ord
+ key_newline(key)
+ else
+ ed_insert(key)
+ end
+ end
+ @waiting_proc = nil
+ }
+ end
+ alias_method :quoted_insert, :ed_quoted_insert
+
+ private def ed_next_char(key, arg: 1)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ if (@byte_pointer < @line.bytesize)
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor += width if width
+ @byte_pointer += byte_size
+ elsif @is_multiline and @config.editing_mode_is?(:emacs) and @byte_pointer == @line.bytesize and @line_index < @buffer_of_lines.size - 1
+ next_line = @buffer_of_lines[@line_index + 1]
+ @cursor = 0
+ @byte_pointer = 0
+ @cursor_max = calculate_width(next_line)
+ @previous_line_index = @line_index
+ @line_index += 1
+ end
+ arg -= 1
+ ed_next_char(key, arg: arg) if arg > 0
+ end
+ alias_method :forward_char, :ed_next_char
+
+ private def ed_prev_char(key, arg: 1)
+ if @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ elsif @is_multiline and @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0
+ prev_line = @buffer_of_lines[@line_index - 1]
+ @cursor = calculate_width(prev_line)
+ @byte_pointer = prev_line.bytesize
+ @cursor_max = calculate_width(prev_line)
+ @previous_line_index = @line_index
+ @line_index -= 1
+ end
+ arg -= 1
+ ed_prev_char(key, arg: arg) if arg > 0
+ end
+ alias_method :backward_char, :ed_prev_char
+
+ private def vi_first_print(key)
+ @byte_pointer, @cursor = Reline::Unicode.vi_first_print(@line)
+ end
+
+ private def ed_move_to_beg(key)
+ @byte_pointer = @cursor = 0
+ end
+ alias_method :beginning_of_line, :ed_move_to_beg
+
+ private def ed_move_to_end(key)
+ @byte_pointer = 0
+ @cursor = 0
+ byte_size = 0
+ while @byte_pointer < @line.bytesize
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ if byte_size > 0
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ @cursor += Reline::Unicode.get_mbchar_width(mbchar)
+ end
+ @byte_pointer += byte_size
+ end
+ end
+ alias_method :end_of_line, :ed_move_to_end
+
+ private def generate_searcher
+ Fiber.new do |first_key|
+ prev_search_key = first_key
+ search_word = String.new(encoding: @encoding)
+ multibyte_buf = String.new(encoding: 'ASCII-8BIT')
+ last_hit = nil
+ case first_key
+ when "\C-r".ord
+ prompt_name = 'reverse-i-search'
+ when "\C-s".ord
+ prompt_name = 'i-search'
+ end
+ loop do
+ key = Fiber.yield(search_word)
+ search_again = false
+ case key
+ when -1 # determined
+ Reline.last_incremental_search = search_word
+ break
+ when "\C-h".ord, "\C-?".ord
+ grapheme_clusters = search_word.grapheme_clusters
+ if grapheme_clusters.size > 0
+ grapheme_clusters.pop
+ search_word = grapheme_clusters.join
+ end
+ when "\C-r".ord, "\C-s".ord
+ search_again = true if prev_search_key == key
+ prev_search_key = key
+ else
+ multibyte_buf << key
+ if multibyte_buf.dup.force_encoding(@encoding).valid_encoding?
+ search_word << multibyte_buf.dup.force_encoding(@encoding)
+ multibyte_buf.clear
+ end
+ end
+ hit = nil
+ if not search_word.empty? and @line_backup_in_history&.include?(search_word)
+ @history_pointer = nil
+ hit = @line_backup_in_history
+ else
+ if search_again
+ if search_word.empty? and Reline.last_incremental_search
+ search_word = Reline.last_incremental_search
+ end
+ if @history_pointer
+ case prev_search_key
+ when "\C-r".ord
+ history_pointer_base = 0
+ history = Reline::HISTORY[0..(@history_pointer - 1)]
+ when "\C-s".ord
+ history_pointer_base = @history_pointer + 1
+ history = Reline::HISTORY[(@history_pointer + 1)..-1]
+ end
+ else
+ history_pointer_base = 0
+ history = Reline::HISTORY
+ end
+ elsif @history_pointer
+ case prev_search_key
+ when "\C-r".ord
+ history_pointer_base = 0
+ history = Reline::HISTORY[0..@history_pointer]
+ when "\C-s".ord
+ history_pointer_base = @history_pointer
+ history = Reline::HISTORY[@history_pointer..-1]
+ end
+ else
+ history_pointer_base = 0
+ history = Reline::HISTORY
+ end
+ case prev_search_key
+ when "\C-r".ord
+ hit_index = history.rindex { |item|
+ item.include?(search_word)
+ }
+ when "\C-s".ord
+ hit_index = history.index { |item|
+ item.include?(search_word)
+ }
+ end
+ if hit_index
+ @history_pointer = history_pointer_base + hit_index
+ hit = Reline::HISTORY[@history_pointer]
+ end
+ end
+ case prev_search_key
+ when "\C-r".ord
+ prompt_name = 'reverse-i-search'
+ when "\C-s".ord
+ prompt_name = 'i-search'
+ end
+ if hit
+ if @is_multiline
+ @buffer_of_lines = hit.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ @searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
+ else
+ @line = hit
+ @searching_prompt = "(%s)`%s': %s" % [prompt_name, search_word, hit]
+ end
+ last_hit = hit
+ else
+ if @is_multiline
+ @rerender_all = true
+ @searching_prompt = "(failed %s)`%s'" % [prompt_name, search_word]
+ else
+ @searching_prompt = "(failed %s)`%s': %s" % [prompt_name, search_word, last_hit]
+ end
+ end
+ end
+ end
+ end
+
+ private def incremental_search_history(key)
+ unless @history_pointer
+ if @is_multiline
+ @line_backup_in_history = whole_buffer
+ else
+ @line_backup_in_history = @line
+ end
+ end
+ searcher = generate_searcher
+ searcher.resume(key)
+ @searching_prompt = "(reverse-i-search)`': "
+ termination_keys = ["\C-j".ord]
+ termination_keys.concat(@config.isearch_terminators&.chars&.map(&:ord)) if @config.isearch_terminators
+ @waiting_proc = ->(k) {
+ case k
+ when *termination_keys
+ if @history_pointer
+ buffer = Reline::HISTORY[@history_pointer]
+ else
+ buffer = @line_backup_in_history
+ end
+ if @is_multiline
+ @buffer_of_lines = buffer.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line = buffer
+ end
+ @searching_prompt = nil
+ @waiting_proc = nil
+ @cursor_max = calculate_width(@line)
+ @cursor = @byte_pointer = 0
+ @rerender_all = true
+ @cached_prompt_list = nil
+ searcher.resume(-1)
+ when "\C-g".ord
+ if @is_multiline
+ @buffer_of_lines = @line_backup_in_history.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line = @line_backup_in_history
+ end
+ @history_pointer = nil
+ @searching_prompt = nil
+ @waiting_proc = nil
+ @line_backup_in_history = nil
+ @cursor_max = calculate_width(@line)
+ @cursor = @byte_pointer = 0
+ @rerender_all = true
+ else
+ chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
+ if chr.match?(/[[:print:]]/) or k == "\C-h".ord or k == "\C-?".ord or k == "\C-r".ord or k == "\C-s".ord
+ searcher.resume(k)
+ else
+ if @history_pointer
+ line = Reline::HISTORY[@history_pointer]
+ else
+ line = @line_backup_in_history
+ end
+ if @is_multiline
+ @line_backup_in_history = whole_buffer
+ @buffer_of_lines = line.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line_backup_in_history = @line
+ @line = line
+ end
+ @searching_prompt = nil
+ @waiting_proc = nil
+ @cursor_max = calculate_width(@line)
+ @cursor = @byte_pointer = 0
+ @rerender_all = true
+ @cached_prompt_list = nil
+ searcher.resume(-1)
+ end
+ end
+ }
+ end
+
+ private def vi_search_prev(key)
+ incremental_search_history(key)
+ end
+ alias_method :reverse_search_history, :vi_search_prev
+
+ private def vi_search_next(key)
+ incremental_search_history(key)
+ end
+ alias_method :forward_search_history, :vi_search_next
+
+ private def ed_search_prev_history(key, arg: 1)
+ history = nil
+ h_pointer = nil
+ line_no = nil
+ substr = @line.slice(0, @byte_pointer)
+ if @history_pointer.nil?
+ return if not @line.empty? and substr.empty?
+ history = Reline::HISTORY
+ elsif @history_pointer.zero?
+ history = nil
+ h_pointer = nil
+ else
+ history = Reline::HISTORY.slice(0, @history_pointer)
+ end
+ return if history.nil?
+ if @is_multiline
+ h_pointer = history.rindex { |h|
+ h.split("\n").each_with_index { |l, i|
+ if l.start_with?(substr)
+ line_no = i
+ break
+ end
+ }
+ not line_no.nil?
+ }
+ else
+ h_pointer = history.rindex { |l|
+ l.start_with?(substr)
+ }
+ end
+ return if h_pointer.nil?
+ @history_pointer = h_pointer
+ if @is_multiline
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = line_no
+ @line = @buffer_of_lines[@line_index]
+ @rerender_all = true
+ else
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ @cursor_max = calculate_width(@line)
+ arg -= 1
+ ed_search_prev_history(key, arg: arg) if arg > 0
+ end
+ alias_method :history_search_backward, :ed_search_prev_history
+
+ private def ed_search_next_history(key, arg: 1)
+ substr = @line.slice(0, @byte_pointer)
+ if @history_pointer.nil?
+ return
+ elsif @history_pointer == (Reline::HISTORY.size - 1) and not substr.empty?
+ return
+ end
+ history = Reline::HISTORY.slice((@history_pointer + 1)..-1)
+ h_pointer = nil
+ line_no = nil
+ if @is_multiline
+ h_pointer = history.index { |h|
+ h.split("\n").each_with_index { |l, i|
+ if l.start_with?(substr)
+ line_no = i
+ break
+ end
+ }
+ not line_no.nil?
+ }
+ else
+ h_pointer = history.index { |l|
+ l.start_with?(substr)
+ }
+ end
+ h_pointer += @history_pointer + 1 if h_pointer and @history_pointer
+ return if h_pointer.nil? and not substr.empty?
+ @history_pointer = h_pointer
+ if @is_multiline
+ if @history_pointer.nil? and substr.empty?
+ @buffer_of_lines = []
+ @line_index = 0
+ else
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @line_index = line_no
+ end
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line = @buffer_of_lines[@line_index]
+ @rerender_all = true
+ else
+ if @history_pointer.nil? and substr.empty?
+ @line = ''
+ else
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ end
+ @cursor_max = calculate_width(@line)
+ arg -= 1
+ ed_search_next_history(key, arg: arg) if arg > 0
+ end
+ alias_method :history_search_forward, :ed_search_next_history
+
+ private def ed_prev_history(key, arg: 1)
+ if @is_multiline and @line_index > 0
+ @previous_line_index = @line_index
+ @line_index -= 1
+ return
+ end
+ if Reline::HISTORY.empty?
+ return
+ end
+ if @history_pointer.nil?
+ @history_pointer = Reline::HISTORY.size - 1
+ if @is_multiline
+ @line_backup_in_history = whole_buffer
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line_backup_in_history = @line
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ elsif @history_pointer.zero?
+ return
+ else
+ if @is_multiline
+ Reline::HISTORY[@history_pointer] = whole_buffer
+ @history_pointer -= 1
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer -= 1
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ end
+ if @config.editing_mode_is?(:emacs, :vi_insert)
+ @cursor_max = @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ elsif @config.editing_mode_is?(:vi_command)
+ @byte_pointer = @cursor = 0
+ @cursor_max = calculate_width(@line)
+ end
+ arg -= 1
+ ed_prev_history(key, arg: arg) if arg > 0
+ end
+
+ private def ed_next_history(key, arg: 1)
+ if @is_multiline and @line_index < (@buffer_of_lines.size - 1)
+ @previous_line_index = @line_index
+ @line_index += 1
+ return
+ end
+ if @history_pointer.nil?
+ return
+ elsif @history_pointer == (Reline::HISTORY.size - 1)
+ if @is_multiline
+ @history_pointer = nil
+ @buffer_of_lines = @line_backup_in_history.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = 0
+ @line = @buffer_of_lines.first
+ @rerender_all = true
+ else
+ @history_pointer = nil
+ @line = @line_backup_in_history
+ end
+ else
+ if @is_multiline
+ Reline::HISTORY[@history_pointer] = whole_buffer
+ @history_pointer += 1
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = 0
+ @line = @buffer_of_lines.first
+ @rerender_all = true
+ else
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer += 1
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ end
+ @line = '' unless @line
+ if @config.editing_mode_is?(:emacs, :vi_insert)
+ @cursor_max = @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ elsif @config.editing_mode_is?(:vi_command)
+ @byte_pointer = @cursor = 0
+ @cursor_max = calculate_width(@line)
+ end
+ arg -= 1
+ ed_next_history(key, arg: arg) if arg > 0
+ end
+
+ private def ed_newline(key)
+ process_insert(force: true)
+ if @is_multiline
+ if @config.editing_mode_is?(:vi_command)
+ if @line_index < (@buffer_of_lines.size - 1)
+ ed_next_history(key) # means cursor down
+ else
+ # should check confirm_multiline_termination to finish?
+ finish
+ end
+ else
+ if @line_index == (@buffer_of_lines.size - 1)
+ if confirm_multiline_termination
+ finish
+ else
+ key_newline(key)
+ end
+ else
+ # should check confirm_multiline_termination to finish?
+ @previous_line_index = @line_index
+ @line_index = @buffer_of_lines.size - 1
+ finish
+ end
+ end
+ else
+ if @history_pointer
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer = nil
+ end
+ finish
+ end
+ end
+
+ private def em_delete_prev_char(key)
+ if @is_multiline and @cursor == 0 and @line_index > 0
+ @buffer_of_lines[@line_index] = @line
+ @cursor = calculate_width(@buffer_of_lines[@line_index - 1])
+ @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
+ @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
+ @line_index -= 1
+ @line = @buffer_of_lines[@line_index]
+ @cursor_max = calculate_width(@line)
+ @rerender_all = true
+ elsif @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ @cursor_max -= width
+ end
+ end
+ alias_method :backward_delete_char, :em_delete_prev_char
+
+ private def ed_kill_line(key)
+ if @line.bytesize > @byte_pointer
+ @line, deleted = byteslice!(@line, @byte_pointer, @line.bytesize - @byte_pointer)
+ @byte_pointer = @line.bytesize
+ @cursor = @cursor_max = calculate_width(@line)
+ @kill_ring.append(deleted)
+ elsif @is_multiline and @byte_pointer == @line.bytesize and @buffer_of_lines.size > @line_index + 1
+ @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @line += @buffer_of_lines.delete_at(@line_index + 1)
+ @cursor_max = calculate_width(@line)
+ @buffer_of_lines[@line_index] = @line
+ @rerender_all = true
+ @rest_height += 1
+ end
+ end
+
+ private def em_kill_line(key)
+ if @byte_pointer > 0
+ @line, deleted = byteslice!(@line, 0, @byte_pointer)
+ @byte_pointer = 0
+ @kill_ring.append(deleted, true)
+ @cursor_max = calculate_width(@line)
+ @cursor = 0
+ end
+ end
+ alias_method :kill_line, :em_kill_line
+
+ private def em_delete(key)
+ if (not @is_multiline and @line.empty?) or (@is_multiline and @line.empty? and @buffer_of_lines.size == 1)
+ @line = nil
+ if @buffer_of_lines.size > 1
+ scroll_down(@highest_in_all - @first_line_started_from)
+ end
+ Reline::IOGate.move_cursor_column(0)
+ @eof = true
+ finish
+ elsif @byte_pointer < @line.bytesize
+ splitted_last = @line.byteslice(@byte_pointer, @line.bytesize)
+ mbchar = splitted_last.grapheme_clusters.first
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor_max -= width
+ @line, = byteslice!(@line, @byte_pointer, mbchar.bytesize)
+ elsif @is_multiline and @byte_pointer == @line.bytesize and @buffer_of_lines.size > @line_index + 1
+ @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @line += @buffer_of_lines.delete_at(@line_index + 1)
+ @cursor_max = calculate_width(@line)
+ @buffer_of_lines[@line_index] = @line
+ @rerender_all = true
+ @rest_height += 1
+ end
+ end
+ alias_method :delete_char, :em_delete
+
+ private def em_delete_or_list(key)
+ if @line.empty? or @byte_pointer < @line.bytesize
+ em_delete(key)
+ else # show completed list
+ result = call_completion_proc
+ if result.is_a?(Array)
+ complete(result, true)
+ end
+ end
+ end
+ alias_method :delete_char_or_list, :em_delete_or_list
+
+ private def em_yank(key)
+ yanked = @kill_ring.yank
+ if yanked
+ @line = byteinsert(@line, @byte_pointer, yanked)
+ yanked_width = calculate_width(yanked)
+ @cursor += yanked_width
+ @cursor_max += yanked_width
+ @byte_pointer += yanked.bytesize
+ end
+ end
+ alias_method :yank, :em_yank
+
+ private def em_yank_pop(key)
+ yanked, prev_yank = @kill_ring.yank_pop
+ if yanked
+ prev_yank_width = calculate_width(prev_yank)
+ @cursor -= prev_yank_width
+ @cursor_max -= prev_yank_width
+ @byte_pointer -= prev_yank.bytesize
+ @line, = byteslice!(@line, @byte_pointer, prev_yank.bytesize)
+ @line = byteinsert(@line, @byte_pointer, yanked)
+ yanked_width = calculate_width(yanked)
+ @cursor += yanked_width
+ @cursor_max += yanked_width
+ @byte_pointer += yanked.bytesize
+ end
+ end
+ alias_method :yank_pop, :em_yank_pop
+
+ private def ed_clear_screen(key)
+ @cleared = true
+ end
+ alias_method :clear_screen, :ed_clear_screen
+
+ private def em_next_word(key)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.em_forward_word(@line, @byte_pointer)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ end
+ alias_method :forward_word, :em_next_word
+
+ private def ed_prev_word(key)
+ if @byte_pointer > 0
+ byte_size, width = Reline::Unicode.em_backward_word(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ end
+ end
+ alias_method :backward_word, :ed_prev_word
+
+ private def em_delete_next_word(key)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.em_forward_word(@line, @byte_pointer)
+ @line, word = byteslice!(@line, @byte_pointer, byte_size)
+ @kill_ring.append(word)
+ @cursor_max -= width
+ end
+ end
+
+ private def ed_delete_prev_word(key)
+ if @byte_pointer > 0
+ byte_size, width = Reline::Unicode.em_backward_word(@line, @byte_pointer)
+ @line, word = byteslice!(@line, @byte_pointer - byte_size, byte_size)
+ @kill_ring.append(word, true)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ @cursor_max -= width
+ end
+ end
+
+ private def ed_transpose_chars(key)
+ if @byte_pointer > 0
+ if @cursor_max > @cursor
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor += width
+ @byte_pointer += byte_size
+ end
+ back1_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ if (@byte_pointer - back1_byte_size) > 0
+ back2_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer - back1_byte_size)
+ back2_pointer = @byte_pointer - back1_byte_size - back2_byte_size
+ @line, back2_mbchar = byteslice!(@line, back2_pointer, back2_byte_size)
+ @line = byteinsert(@line, @byte_pointer - back2_byte_size, back2_mbchar)
+ end
+ end
+ end
+ alias_method :transpose_chars, :ed_transpose_chars
+
+ private def ed_transpose_words(key)
+ left_word_start, middle_start, right_word_start, after_start = Reline::Unicode.ed_transpose_words(@line, @byte_pointer)
+ before = @line.byteslice(0, left_word_start)
+ left_word = @line.byteslice(left_word_start, middle_start - left_word_start)
+ middle = @line.byteslice(middle_start, right_word_start - middle_start)
+ right_word = @line.byteslice(right_word_start, after_start - right_word_start)
+ after = @line.byteslice(after_start, @line.bytesize - after_start)
+ return if left_word.empty? or right_word.empty?
+ @line = before + right_word + middle + left_word + after
+ from_head_to_left_word = before + right_word + middle + left_word
+ @byte_pointer = from_head_to_left_word.bytesize
+ @cursor = calculate_width(from_head_to_left_word)
+ end
+ alias_method :transpose_words, :ed_transpose_words
+
+ private def em_capitol_case(key)
+ if @line.bytesize > @byte_pointer
+ byte_size, _, new_str = Reline::Unicode.em_forward_word_with_capitalization(@line, @byte_pointer)
+ before = @line.byteslice(0, @byte_pointer)
+ after = @line.byteslice((@byte_pointer + byte_size)..-1)
+ @line = before + new_str + after
+ @byte_pointer += new_str.bytesize
+ @cursor += calculate_width(new_str)
+ end
+ end
+ alias_method :capitalize_word, :em_capitol_case
+
+ private def em_lower_case(key)
+ if @line.bytesize > @byte_pointer
+ byte_size, = Reline::Unicode.em_forward_word(@line, @byte_pointer)
+ part = @line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
+ mbchar =~ /[A-Z]/ ? mbchar.downcase : mbchar
+ }.join
+ rest = @line.byteslice((@byte_pointer + byte_size)..-1)
+ @line = @line.byteslice(0, @byte_pointer) + part
+ @byte_pointer = @line.bytesize
+ @cursor = calculate_width(@line)
+ @cursor_max = @cursor + calculate_width(rest)
+ @line += rest
+ end
+ end
+ alias_method :downcase_word, :em_lower_case
+
+ private def em_upper_case(key)
+ if @line.bytesize > @byte_pointer
+ byte_size, = Reline::Unicode.em_forward_word(@line, @byte_pointer)
+ part = @line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
+ mbchar =~ /[a-z]/ ? mbchar.upcase : mbchar
+ }.join
+ rest = @line.byteslice((@byte_pointer + byte_size)..-1)
+ @line = @line.byteslice(0, @byte_pointer) + part
+ @byte_pointer = @line.bytesize
+ @cursor = calculate_width(@line)
+ @cursor_max = @cursor + calculate_width(rest)
+ @line += rest
+ end
+ end
+ alias_method :upcase_word, :em_upper_case
+
+ private def em_kill_region(key)
+ if @byte_pointer > 0
+ byte_size, width = Reline::Unicode.em_big_backward_word(@line, @byte_pointer)
+ @line, deleted = byteslice!(@line, @byte_pointer - byte_size, byte_size)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ @cursor_max -= width
+ @kill_ring.append(deleted, true)
+ end
+ end
+ alias_method :unix_word_rubout, :em_kill_region
+
+ private def copy_for_vi(text)
+ if @config.editing_mode_is?(:vi_insert) or @config.editing_mode_is?(:vi_command)
+ @vi_clipboard = text
+ end
+ end
+
+ private def vi_insert(key)
+ @config.editing_mode = :vi_insert
+ end
+
+ private def vi_add(key)
+ @config.editing_mode = :vi_insert
+ ed_next_char(key)
+ end
+
+ private def vi_command_mode(key)
+ ed_prev_char(key)
+ @config.editing_mode = :vi_command
+ end
+ alias_method :vi_movement_mode, :vi_command_mode
+
+ private def vi_next_word(key, arg: 1)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_forward_word(@line, @byte_pointer, @drop_terminate_spaces)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ arg -= 1
+ vi_next_word(key, arg: arg) if arg > 0
+ end
+
+ private def vi_prev_word(key, arg: 1)
+ if @byte_pointer > 0
+ byte_size, width = Reline::Unicode.vi_backward_word(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ end
+ arg -= 1
+ vi_prev_word(key, arg: arg) if arg > 0
+ end
+
+ private def vi_end_word(key, arg: 1, inclusive: false)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_forward_end_word(@line, @byte_pointer)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ arg -= 1
+ if inclusive and arg.zero?
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ if byte_size > 0
+ c = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(c)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ end
+ vi_end_word(key, arg: arg) if arg > 0
+ end
+
+ private def vi_next_big_word(key, arg: 1)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_big_forward_word(@line, @byte_pointer)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ arg -= 1
+ vi_next_big_word(key, arg: arg) if arg > 0
+ end
+
+ private def vi_prev_big_word(key, arg: 1)
+ if @byte_pointer > 0
+ byte_size, width = Reline::Unicode.vi_big_backward_word(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ end
+ arg -= 1
+ vi_prev_big_word(key, arg: arg) if arg > 0
+ end
+
+ private def vi_end_big_word(key, arg: 1, inclusive: false)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_big_forward_end_word(@line, @byte_pointer)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ arg -= 1
+ if inclusive and arg.zero?
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ if byte_size > 0
+ c = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(c)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ end
+ vi_end_big_word(key, arg: arg) if arg > 0
+ end
+
+ private def vi_delete_prev_char(key)
+ if @is_multiline and @cursor == 0 and @line_index > 0
+ @buffer_of_lines[@line_index] = @line
+ @cursor = calculate_width(@buffer_of_lines[@line_index - 1])
+ @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
+ @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
+ @line_index -= 1
+ @line = @buffer_of_lines[@line_index]
+ @cursor_max = calculate_width(@line)
+ @rerender_all = true
+ elsif @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ @cursor_max -= width
+ end
+ end
+
+ private def vi_insert_at_bol(key)
+ ed_move_to_beg(key)
+ @config.editing_mode = :vi_insert
+ end
+
+ private def vi_add_at_eol(key)
+ ed_move_to_end(key)
+ @config.editing_mode = :vi_insert
+ end
+
+ private def ed_delete_prev_char(key, arg: 1)
+ deleted = ''
+ arg.times do
+ if @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
+ deleted.prepend(mbchar)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ @cursor_max -= width
+ end
+ end
+ copy_for_vi(deleted)
+ end
+
+ private def vi_zero(key)
+ @byte_pointer = 0
+ @cursor = 0
+ end
+
+ private def vi_change_meta(key, arg: 1)
+ @drop_terminate_spaces = true
+ @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
+ if byte_pointer_diff > 0
+ @line, cut = byteslice!(@line, @byte_pointer, byte_pointer_diff)
+ elsif byte_pointer_diff < 0
+ @line, cut = byteslice!(@line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
+ end
+ copy_for_vi(cut)
+ @cursor += cursor_diff if cursor_diff < 0
+ @cursor_max -= cursor_diff.abs
+ @byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
+ @config.editing_mode = :vi_insert
+ @drop_terminate_spaces = false
+ }
+ @waiting_operator_vi_arg = arg
+ end
+
+ private def vi_delete_meta(key, arg: 1)
+ @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
+ if byte_pointer_diff > 0
+ @line, cut = byteslice!(@line, @byte_pointer, byte_pointer_diff)
+ elsif byte_pointer_diff < 0
+ @line, cut = byteslice!(@line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
+ end
+ copy_for_vi(cut)
+ @cursor += cursor_diff if cursor_diff < 0
+ @cursor_max -= cursor_diff.abs
+ @byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
+ }
+ @waiting_operator_vi_arg = arg
+ end
+
+ private def vi_yank(key, arg: 1)
+ @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
+ if byte_pointer_diff > 0
+ cut = @line.byteslice(@byte_pointer, byte_pointer_diff)
+ elsif byte_pointer_diff < 0
+ cut = @line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
+ end
+ copy_for_vi(cut)
+ }
+ @waiting_operator_vi_arg = arg
+ end
+
+ private def vi_list_or_eof(key)
+ if (not @is_multiline and @line.empty?) or (@is_multiline and @line.empty? and @buffer_of_lines.size == 1)
+ @line = nil
+ if @buffer_of_lines.size > 1
+ scroll_down(@highest_in_all - @first_line_started_from)
+ end
+ Reline::IOGate.move_cursor_column(0)
+ @eof = true
+ finish
+ else
+ ed_newline(key)
+ end
+ end
+ alias_method :vi_end_of_transmission, :vi_list_or_eof
+ alias_method :vi_eof_maybe, :vi_list_or_eof
+
+ private def ed_delete_next_char(key, arg: 1)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ unless @line.empty? || byte_size == 0
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
+ copy_for_vi(mbchar)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor_max -= width
+ if @cursor > 0 and @cursor >= @cursor_max
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ mbchar = @line.byteslice(@byte_pointer - byte_size, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ end
+ end
+ arg -= 1
+ ed_delete_next_char(key, arg: arg) if arg > 0
+ end
+
+ private def vi_to_history_line(key)
+ if Reline::HISTORY.empty?
+ return
+ end
+ if @history_pointer.nil?
+ @history_pointer = 0
+ @line_backup_in_history = @line
+ @line = Reline::HISTORY[@history_pointer]
+ @cursor_max = calculate_width(@line)
+ @cursor = 0
+ @byte_pointer = 0
+ elsif @history_pointer.zero?
+ return
+ else
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer = 0
+ @line = Reline::HISTORY[@history_pointer]
+ @cursor_max = calculate_width(@line)
+ @cursor = 0
+ @byte_pointer = 0
+ end
+ end
+
+ private def vi_histedit(key)
+ path = Tempfile.open { |fp|
+ if @is_multiline
+ fp.write whole_lines.join("\n")
+ else
+ fp.write @line
+ end
+ fp.path
+ }
+ system("#{ENV['EDITOR']} #{path}")
+ if @is_multiline
+ @buffer_of_lines = File.read(path).split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = 0
+ @line = @buffer_of_lines[@line_index]
+ @rerender_all = true
+ else
+ @line = File.read(path)
+ end
+ finish
+ end
+
+ private def vi_paste_prev(key, arg: 1)
+ if @vi_clipboard.size > 0
+ @line = byteinsert(@line, @byte_pointer, @vi_clipboard)
+ @cursor_max += calculate_width(@vi_clipboard)
+ cursor_point = @vi_clipboard.grapheme_clusters[0..-2].join
+ @cursor += calculate_width(cursor_point)
+ @byte_pointer += cursor_point.bytesize
+ end
+ arg -= 1
+ vi_paste_prev(key, arg: arg) if arg > 0
+ end
+
+ private def vi_paste_next(key, arg: 1)
+ if @vi_clipboard.size > 0
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ @line = byteinsert(@line, @byte_pointer + byte_size, @vi_clipboard)
+ @cursor_max += calculate_width(@vi_clipboard)
+ @cursor += calculate_width(@vi_clipboard)
+ @byte_pointer += @vi_clipboard.bytesize
+ end
+ arg -= 1
+ vi_paste_next(key, arg: arg) if arg > 0
+ end
+
+ private def ed_argument_digit(key)
+ if @vi_arg.nil?
+ unless key.chr.to_i.zero?
+ @vi_arg = key.chr.to_i
+ end
+ else
+ @vi_arg = @vi_arg * 10 + key.chr.to_i
+ end
+ end
+
+ private def vi_to_column(key, arg: 0)
+ @byte_pointer, @cursor = @line.grapheme_clusters.inject([0, 0]) { |total, gc|
+ # total has [byte_size, cursor]
+ mbchar_width = Reline::Unicode.get_mbchar_width(gc)
+ if (total.last + mbchar_width) >= arg
+ break total
+ elsif (total.last + mbchar_width) >= @cursor_max
+ break total
+ else
+ total = [total.first + gc.bytesize, total.last + mbchar_width]
+ total
+ end
+ }
+ end
+
+ private def vi_replace_char(key, arg: 1)
+ @waiting_proc = ->(k) {
+ if arg == 1
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ before = @line.byteslice(0, @byte_pointer)
+ remaining_point = @byte_pointer + byte_size
+ after = @line.byteslice(remaining_point, @line.bytesize - remaining_point)
+ @line = before + k.chr + after
+ @cursor_max = calculate_width(@line)
+ @waiting_proc = nil
+ elsif arg > 1
+ byte_size = 0
+ arg.times do
+ byte_size += Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer + byte_size)
+ end
+ before = @line.byteslice(0, @byte_pointer)
+ remaining_point = @byte_pointer + byte_size
+ after = @line.byteslice(remaining_point, @line.bytesize - remaining_point)
+ replaced = k.chr * arg
+ @line = before + replaced + after
+ @byte_pointer += replaced.bytesize
+ @cursor += calculate_width(replaced)
+ @cursor_max = calculate_width(@line)
+ @waiting_proc = nil
+ end
+ }
+ end
+
+ private def vi_next_char(key, arg: 1, inclusive: false)
+ @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, inclusive: inclusive) }
+ end
+
+ private def vi_to_next_char(key, arg: 1, inclusive: false)
+ @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, need_prev_char: true, inclusive: inclusive) }
+ end
+
+ private def search_next_char(key, arg, need_prev_char: false, inclusive: false)
+ if key.instance_of?(String)
+ inputed_char = key
+ else
+ inputed_char = key.chr
+ end
+ prev_total = nil
+ total = nil
+ found = false
+ @line.byteslice(@byte_pointer..-1).grapheme_clusters.each do |mbchar|
+ # total has [byte_size, cursor]
+ unless total
+ # skip cursor point
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ total = [mbchar.bytesize, width]
+ else
+ if inputed_char == mbchar
+ arg -= 1
+ if arg.zero?
+ found = true
+ break
+ end
+ end
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ prev_total = total
+ total = [total.first + mbchar.bytesize, total.last + width]
+ end
+ end
+ if not need_prev_char and found and total
+ byte_size, width = total
+ @byte_pointer += byte_size
+ @cursor += width
+ elsif need_prev_char and found and prev_total
+ byte_size, width = prev_total
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ if inclusive
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ if byte_size > 0
+ c = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(c)
+ @byte_pointer += byte_size
+ @cursor += width
+ end
+ end
+ @waiting_proc = nil
+ end
+
+ private def vi_prev_char(key, arg: 1)
+ @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg) }
+ end
+
+ private def vi_to_prev_char(key, arg: 1)
+ @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg, true) }
+ end
+
+ private def search_prev_char(key, arg, need_next_char = false)
+ if key.instance_of?(String)
+ inputed_char = key
+ else
+ inputed_char = key.chr
+ end
+ prev_total = nil
+ total = nil
+ found = false
+ @line.byteslice(0..@byte_pointer).grapheme_clusters.reverse_each do |mbchar|
+ # total has [byte_size, cursor]
+ unless total
+ # skip cursor point
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ total = [mbchar.bytesize, width]
+ else
+ if inputed_char == mbchar
+ arg -= 1
+ if arg.zero?
+ found = true
+ break
+ end
+ end
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ prev_total = total
+ total = [total.first + mbchar.bytesize, total.last + width]
+ end
+ end
+ if not need_next_char and found and total
+ byte_size, width = total
+ @byte_pointer -= byte_size
+ @cursor -= width
+ elsif need_next_char and found and prev_total
+ byte_size, width = prev_total
+ @byte_pointer -= byte_size
+ @cursor -= width
+ end
+ @waiting_proc = nil
+ end
+
+ private def vi_join_lines(key, arg: 1)
+ if @is_multiline and @buffer_of_lines.size > @line_index + 1
+ @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @line += ' ' + @buffer_of_lines.delete_at(@line_index + 1).lstrip
+ @cursor_max = calculate_width(@line)
+ @buffer_of_lines[@line_index] = @line
+ @rerender_all = true
+ @rest_height += 1
+ end
+ arg -= 1
+ vi_join_lines(key, arg: arg) if arg > 0
+ end
+
+ private def em_set_mark(key)
+ @mark_pointer = [@byte_pointer, @line_index]
+ end
+ alias_method :set_mark, :em_set_mark
+
+ private def em_exchange_mark(key)
+ return unless @mark_pointer
+ new_pointer = [@byte_pointer, @line_index]
+ @previous_line_index = @line_index
+ @byte_pointer, @line_index = @mark_pointer
+ @cursor = calculate_width(@line.byteslice(0, @byte_pointer))
+ @cursor_max = calculate_width(@line)
+ @mark_pointer = new_pointer
+ end
+ alias_method :exchange_point_and_mark, :em_exchange_mark
+end
diff --git a/lib/reline/reline.gemspec b/lib/reline/reline.gemspec
new file mode 100644
index 0000000000..763c0f8bc3
--- /dev/null
+++ b/lib/reline/reline.gemspec
@@ -0,0 +1,27 @@
+
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'reline/version'
+
+Gem::Specification.new do |spec|
+ spec.name = 'reline'
+ spec.version = Reline::VERSION
+ spec.authors = ['aycabta']
+ spec.email = ['aycabta@gmail.com']
+
+ spec.summary = %q{Alternative GNU Readline or Editline implementation by pure Ruby.}
+ spec.description = %q{Alternative GNU Readline or Editline implementation by pure Ruby.}
+ spec.homepage = 'https://github.com/ruby/reline'
+ spec.license = 'Ruby'
+
+ spec.files = Dir['BSDL', 'COPYING', 'README.md', 'license_of_rb-readline', 'lib/**/*']
+ spec.require_paths = ['lib']
+
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5')
+
+ spec.add_dependency 'io-console', '~> 0.5'
+ spec.add_development_dependency 'bundler'
+ spec.add_development_dependency 'rake'
+ spec.add_development_dependency 'test-unit'
+ spec.add_development_dependency 'yamatanooroti', '>= 0.0.6'
+end
diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb
new file mode 100644
index 0000000000..7dbe8a12a5
--- /dev/null
+++ b/lib/reline/unicode.rb
@@ -0,0 +1,626 @@
+class Reline::Unicode
+ EscapedPairs = {
+ 0x00 => '^@',
+ 0x01 => '^A', # C-a
+ 0x02 => '^B',
+ 0x03 => '^C',
+ 0x04 => '^D',
+ 0x05 => '^E',
+ 0x06 => '^F',
+ 0x07 => '^G',
+ 0x08 => '^H', # Backspace
+ 0x09 => '^I',
+ 0x0A => '^J',
+ 0x0B => '^K',
+ 0x0C => '^L',
+ 0x0D => '^M', # Enter
+ 0x0E => '^N',
+ 0x0F => '^O',
+ 0x10 => '^P',
+ 0x11 => '^Q',
+ 0x12 => '^R',
+ 0x13 => '^S',
+ 0x14 => '^T',
+ 0x15 => '^U',
+ 0x16 => '^V',
+ 0x17 => '^W',
+ 0x18 => '^X',
+ 0x19 => '^Y',
+ 0x1A => '^Z', # C-z
+ 0x1B => '^[', # C-[ C-3
+ 0x1D => '^]', # C-]
+ 0x1E => '^^', # C-~ C-6
+ 0x1F => '^_', # C-_ C-7
+ 0x7F => '^?', # C-? C-8
+ }
+ EscapedChars = EscapedPairs.keys.map(&:chr)
+
+ NON_PRINTING_START = "\1"
+ NON_PRINTING_END = "\2"
+ CSI_REGEXP = /\e\[[\d;]*[ABCDEFGHJKSTfminsuhl]/
+ OSC_REGEXP = /\e\]\d+(?:;[^;]+)*\a/
+ WIDTH_SCANNER = /\G(?:(#{NON_PRINTING_START})|(#{NON_PRINTING_END})|(#{CSI_REGEXP})|(#{OSC_REGEXP})|(\X))/o
+ NON_PRINTING_START_INDEX = 0
+ NON_PRINTING_END_INDEX = 1
+ CSI_REGEXP_INDEX = 2
+ OSC_REGEXP_INDEX = 3
+ GRAPHEME_CLUSTER_INDEX = 4
+
+ def self.get_mbchar_byte_size_by_first_char(c)
+ # Checks UTF-8 character byte size
+ case c.ord
+ # 0b0xxxxxxx
+ when ->(code) { (code ^ 0b10000000).allbits?(0b10000000) } then 1
+ # 0b110xxxxx
+ when ->(code) { (code ^ 0b00100000).allbits?(0b11100000) } then 2
+ # 0b1110xxxx
+ when ->(code) { (code ^ 0b00010000).allbits?(0b11110000) } then 3
+ # 0b11110xxx
+ when ->(code) { (code ^ 0b00001000).allbits?(0b11111000) } then 4
+ # 0b111110xx
+ when ->(code) { (code ^ 0b00000100).allbits?(0b11111100) } then 5
+ # 0b1111110x
+ when ->(code) { (code ^ 0b00000010).allbits?(0b11111110) } then 6
+ # successor of mbchar
+ else 0
+ end
+ end
+
+ def self.escape_for_print(str)
+ str.chars.map! { |gr|
+ escaped = EscapedPairs[gr.ord]
+ if escaped && gr != -"\n" && gr != -"\t"
+ escaped
+ else
+ gr
+ end
+ }.join
+ end
+
+ require 'reline/unicode/east_asian_width'
+
+ MBCharWidthRE = /
+ (?<width_2_1>
+ [#{ EscapedChars.map {|c| "\\x%02x" % c.ord }.join }] (?# ^ + char, such as ^M, ^H, ^[, ...)
+ )
+ | (?<width_3>^\u{2E3B}) (?# THREE-EM DASH)
+ | (?<width_0>^\p{M})
+ | (?<width_2_2>
+ #{ EastAsianWidth::TYPE_F }
+ | #{ EastAsianWidth::TYPE_W }
+ )
+ | (?<width_1>
+ #{ EastAsianWidth::TYPE_H }
+ | #{ EastAsianWidth::TYPE_NA }
+ | #{ EastAsianWidth::TYPE_N }
+ )
+ | (?<ambiguous_width>
+ #{EastAsianWidth::TYPE_A}
+ )
+ /x
+
+ def self.get_mbchar_width(mbchar)
+ ord = mbchar.ord
+ if (0x00 <= ord and ord <= 0x1F)
+ return 2
+ elsif (0x20 <= ord and ord <= 0x7E)
+ return 1
+ end
+ m = mbchar.encode(Encoding::UTF_8).match(MBCharWidthRE)
+ case
+ when m.nil? then 1 # TODO should be U+FFFD � REPLACEMENT CHARACTER
+ when m[:width_2_1], m[:width_2_2] then 2
+ when m[:width_3] then 3
+ when m[:width_0] then 0
+ when m[:width_1] then 1
+ when m[:ambiguous_width] then Reline.ambiguous_width
+ else
+ nil
+ end
+ end
+
+ def self.calculate_width(str, allow_escape_code = false)
+ if allow_escape_code
+ width = 0
+ rest = str.encode(Encoding::UTF_8)
+ in_zero_width = false
+ rest.scan(WIDTH_SCANNER) do |gc|
+ case
+ when gc[NON_PRINTING_START_INDEX]
+ in_zero_width = true
+ when gc[NON_PRINTING_END_INDEX]
+ in_zero_width = false
+ when gc[CSI_REGEXP_INDEX], gc[OSC_REGEXP_INDEX]
+ when gc[GRAPHEME_CLUSTER_INDEX]
+ gc = gc[GRAPHEME_CLUSTER_INDEX]
+ unless in_zero_width
+ width += get_mbchar_width(gc)
+ end
+ end
+ end
+ width
+ else
+ str.encode(Encoding::UTF_8).grapheme_clusters.inject(0) { |w, gc|
+ w + get_mbchar_width(gc)
+ }
+ end
+ end
+
+ def self.split_by_width(str, max_width, encoding = str.encoding)
+ lines = [String.new(encoding: encoding)]
+ height = 1
+ width = 0
+ rest = str.encode(Encoding::UTF_8)
+ in_zero_width = false
+ rest.scan(WIDTH_SCANNER) do |gc|
+ case
+ when gc[NON_PRINTING_START_INDEX]
+ in_zero_width = true
+ when gc[NON_PRINTING_END_INDEX]
+ in_zero_width = false
+ when gc[CSI_REGEXP_INDEX]
+ lines.last << gc[CSI_REGEXP_INDEX]
+ when gc[OSC_REGEXP_INDEX]
+ lines.last << gc[OSC_REGEXP_INDEX]
+ when gc[GRAPHEME_CLUSTER_INDEX]
+ gc = gc[GRAPHEME_CLUSTER_INDEX]
+ unless in_zero_width
+ mbchar_width = get_mbchar_width(gc)
+ if (width += mbchar_width) > max_width
+ width = mbchar_width
+ lines << nil
+ lines << String.new(encoding: encoding)
+ height += 1
+ end
+ end
+ lines.last << gc
+ end
+ end
+ # The cursor moves to next line in first
+ if width == max_width
+ lines << nil
+ lines << String.new(encoding: encoding)
+ height += 1
+ end
+ [lines, height]
+ end
+
+ def self.get_next_mbchar_size(line, byte_pointer)
+ grapheme = line.byteslice(byte_pointer..-1).grapheme_clusters.first
+ grapheme ? grapheme.bytesize : 0
+ end
+
+ def self.get_prev_mbchar_size(line, byte_pointer)
+ if byte_pointer.zero?
+ 0
+ else
+ grapheme = line.byteslice(0..(byte_pointer - 1)).grapheme_clusters.last
+ grapheme ? grapheme.bytesize : 0
+ end
+ end
+
+ def self.em_forward_word(line, byte_pointer)
+ width = 0
+ byte_size = 0
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+
+ def self.em_forward_word_with_capitalization(line, byte_pointer)
+ width = 0
+ byte_size = 0
+ new_str = String.new
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ new_str += mbchar
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ first = true
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ if first
+ new_str += mbchar.upcase
+ first = false
+ else
+ new_str += mbchar.downcase
+ end
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width, new_str]
+ end
+
+ def self.em_backward_word(line, byte_pointer)
+ width = 0
+ byte_size = 0
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+
+ def self.em_big_backward_word(line, byte_pointer)
+ width = 0
+ byte_size = 0
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ break if mbchar =~ /\S/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ break if mbchar =~ /\s/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+
+ def self.ed_transpose_words(line, byte_pointer)
+ right_word_start = nil
+ size = get_next_mbchar_size(line, byte_pointer)
+ mbchar = line.byteslice(byte_pointer, size)
+ if size.zero?
+ # ' aaa bbb [cursor]'
+ byte_size = 0
+ while 0 < (byte_pointer + byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ byte_size -= size
+ end
+ while 0 < (byte_pointer + byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ byte_size -= size
+ end
+ right_word_start = byte_pointer + byte_size
+ byte_size = 0
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ byte_size += size
+ end
+ after_start = byte_pointer + byte_size
+ elsif mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ # ' aaa bb[cursor]b'
+ byte_size = 0
+ while 0 < (byte_pointer + byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ byte_size -= size
+ end
+ right_word_start = byte_pointer + byte_size
+ byte_size = 0
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ byte_size += size
+ end
+ after_start = byte_pointer + byte_size
+ else
+ byte_size = 0
+ while (line.bytesize - 1) > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ byte_size += size
+ end
+ if (byte_pointer + byte_size) == (line.bytesize - 1)
+ # ' aaa bbb [cursor] '
+ after_start = line.bytesize
+ while 0 < (byte_pointer + byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ byte_size -= size
+ end
+ while 0 < (byte_pointer + byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ byte_size -= size
+ end
+ right_word_start = byte_pointer + byte_size
+ else
+ # ' aaa [cursor] bbb '
+ right_word_start = byte_pointer + byte_size
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ byte_size += size
+ end
+ after_start = byte_pointer + byte_size
+ end
+ end
+ byte_size = right_word_start - byte_pointer
+ while 0 < (byte_pointer + byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
+ byte_size -= size
+ end
+ middle_start = byte_pointer + byte_size
+ byte_size = middle_start - byte_pointer
+ while 0 < (byte_pointer + byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size - size, size)
+ break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
+ byte_size -= size
+ end
+ left_word_start = byte_pointer + byte_size
+ [left_word_start, middle_start, right_word_start, after_start]
+ end
+
+ def self.vi_big_forward_word(line, byte_pointer)
+ width = 0
+ byte_size = 0
+ while (line.bytesize - 1) > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar =~ /\s/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ while (line.bytesize - 1) > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar =~ /\S/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+
+ def self.vi_big_forward_end_word(line, byte_pointer)
+ if (line.bytesize - 1) > byte_pointer
+ size = get_next_mbchar_size(line, byte_pointer)
+ mbchar = line.byteslice(byte_pointer, size)
+ width = get_mbchar_width(mbchar)
+ byte_size = size
+ else
+ return [0, 0]
+ end
+ while (line.bytesize - 1) > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar =~ /\S/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ prev_width = width
+ prev_byte_size = byte_size
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar =~ /\s/
+ prev_width = width
+ prev_byte_size = byte_size
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [prev_byte_size, prev_width]
+ end
+
+ def self.vi_big_backward_word(line, byte_pointer)
+ width = 0
+ byte_size = 0
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ break if mbchar =~ /\S/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ break if mbchar =~ /\s/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+
+ def self.vi_forward_word(line, byte_pointer, drop_terminate_spaces = false)
+ if line.bytesize > byte_pointer
+ size = get_next_mbchar_size(line, byte_pointer)
+ mbchar = line.byteslice(byte_pointer, size)
+ if mbchar =~ /\w/
+ started_by = :word
+ elsif mbchar =~ /\s/
+ started_by = :space
+ else
+ started_by = :non_word_printable
+ end
+ width = get_mbchar_width(mbchar)
+ byte_size = size
+ else
+ return [0, 0]
+ end
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ case started_by
+ when :word
+ break if mbchar =~ /\W/
+ when :space
+ break if mbchar =~ /\S/
+ when :non_word_printable
+ break if mbchar =~ /\w|\s/
+ end
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ return [byte_size, width] if drop_terminate_spaces
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ break if mbchar =~ /\S/
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+
+ def self.vi_forward_end_word(line, byte_pointer)
+ if (line.bytesize - 1) > byte_pointer
+ size = get_next_mbchar_size(line, byte_pointer)
+ mbchar = line.byteslice(byte_pointer, size)
+ if mbchar =~ /\w/
+ started_by = :word
+ elsif mbchar =~ /\s/
+ started_by = :space
+ else
+ started_by = :non_word_printable
+ end
+ width = get_mbchar_width(mbchar)
+ byte_size = size
+ else
+ return [0, 0]
+ end
+ if (line.bytesize - 1) > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ if mbchar =~ /\w/
+ second = :word
+ elsif mbchar =~ /\s/
+ second = :space
+ else
+ second = :non_word_printable
+ end
+ second_width = get_mbchar_width(mbchar)
+ second_byte_size = size
+ else
+ return [byte_size, width]
+ end
+ if second == :space
+ width += second_width
+ byte_size += second_byte_size
+ while (line.bytesize - 1) > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ if mbchar =~ /\S/
+ if mbchar =~ /\w/
+ started_by = :word
+ else
+ started_by = :non_word_printable
+ end
+ break
+ end
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ else
+ case [started_by, second]
+ when [:word, :non_word_printable], [:non_word_printable, :word]
+ started_by = second
+ else
+ width += second_width
+ byte_size += second_byte_size
+ started_by = second
+ end
+ end
+ prev_width = width
+ prev_byte_size = byte_size
+ while line.bytesize > (byte_pointer + byte_size)
+ size = get_next_mbchar_size(line, byte_pointer + byte_size)
+ mbchar = line.byteslice(byte_pointer + byte_size, size)
+ case started_by
+ when :word
+ break if mbchar =~ /\W/
+ when :non_word_printable
+ break if mbchar =~ /[\w\s]/
+ end
+ prev_width = width
+ prev_byte_size = byte_size
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [prev_byte_size, prev_width]
+ end
+
+ def self.vi_backward_word(line, byte_pointer)
+ width = 0
+ byte_size = 0
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ if mbchar =~ /\S/
+ if mbchar =~ /\w/
+ started_by = :word
+ else
+ started_by = :non_word_printable
+ end
+ break
+ end
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ while 0 < (byte_pointer - byte_size)
+ size = get_prev_mbchar_size(line, byte_pointer - byte_size)
+ mbchar = line.byteslice(byte_pointer - byte_size - size, size)
+ case started_by
+ when :word
+ break if mbchar =~ /\W/
+ when :non_word_printable
+ break if mbchar =~ /[\w\s]/
+ end
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+
+ def self.vi_first_print(line)
+ width = 0
+ byte_size = 0
+ while (line.bytesize - 1) > byte_size
+ size = get_next_mbchar_size(line, byte_size)
+ mbchar = line.byteslice(byte_size, size)
+ if mbchar =~ /\S/
+ break
+ end
+ width += get_mbchar_width(mbchar)
+ byte_size += size
+ end
+ [byte_size, width]
+ end
+end
diff --git a/lib/reline/unicode/east_asian_width.rb b/lib/reline/unicode/east_asian_width.rb
new file mode 100644
index 0000000000..89bc9d9435
--- /dev/null
+++ b/lib/reline/unicode/east_asian_width.rb
@@ -0,0 +1,1164 @@
+class Reline::Unicode::EastAsianWidth
+ # This is based on EastAsianWidth.txt
+ # EastAsianWidth.txt
+
+ # Fullwidth
+ TYPE_F = /^[#{ %W(
+ \u{3000}
+ \u{FF01}-\u{FF60}
+ \u{FFE0}-\u{FFE6}
+ ).join }]/
+
+ # Halfwidth
+ TYPE_H = /^[#{ %W(
+ \u{20A9}
+ \u{FF61}-\u{FFBE}
+ \u{FFC2}-\u{FFC7}
+ \u{FFCA}-\u{FFCF}
+ \u{FFD2}-\u{FFD7}
+ \u{FFDA}-\u{FFDC}
+ \u{FFE8}-\u{FFEE}
+ ).join }]/
+
+ # Wide
+ TYPE_W = /^[#{ %W(
+ \u{1100}-\u{115F}
+ \u{231A}-\u{231B}
+ \u{2329}-\u{232A}
+ \u{23E9}-\u{23EC}
+ \u{23F0}
+ \u{23F3}
+ \u{25FD}-\u{25FE}
+ \u{2614}-\u{2615}
+ \u{2648}-\u{2653}
+ \u{267F}
+ \u{2693}
+ \u{26A1}
+ \u{26AA}-\u{26AB}
+ \u{26BD}-\u{26BE}
+ \u{26C4}-\u{26C5}
+ \u{26CE}
+ \u{26D4}
+ \u{26EA}
+ \u{26F2}-\u{26F3}
+ \u{26F5}
+ \u{26FA}
+ \u{26FD}
+ \u{2705}
+ \u{270A}-\u{270B}
+ \u{2728}
+ \u{274C}
+ \u{274E}
+ \u{2753}-\u{2755}
+ \u{2757}
+ \u{2795}-\u{2797}
+ \u{27B0}
+ \u{27BF}
+ \u{2B1B}-\u{2B1C}
+ \u{2B50}
+ \u{2B55}
+ \u{2E80}-\u{2E99}
+ \u{2E9B}-\u{2EF3}
+ \u{2F00}-\u{2FD5}
+ \u{2FF0}-\u{2FFB}
+ \u{3001}-\u{303E}
+ \u{3041}-\u{3096}
+ \u{3099}-\u{30FF}
+ \u{3105}-\u{312F}
+ \u{3131}-\u{318E}
+ \u{3190}-\u{31E3}
+ \u{31F0}-\u{321E}
+ \u{3220}-\u{3247}
+ \u{3250}-\u{4DBF}
+ \u{4E00}-\u{A48C}
+ \u{A490}-\u{A4C6}
+ \u{A960}-\u{A97C}
+ \u{AC00}-\u{D7A3}
+ \u{F900}-\u{FAFF}
+ \u{FE10}-\u{FE19}
+ \u{FE30}-\u{FE52}
+ \u{FE54}-\u{FE66}
+ \u{FE68}-\u{FE6B}
+ \u{16FE0}-\u{16FE4}
+ \u{16FF0}-\u{16FF1}
+ \u{17000}-\u{187F7}
+ \u{18800}-\u{18CD5}
+ \u{18D00}-\u{18D08}
+ \u{1B000}-\u{1B11E}
+ \u{1B150}-\u{1B152}
+ \u{1B164}-\u{1B167}
+ \u{1B170}-\u{1B2FB}
+ \u{1F004}
+ \u{1F0CF}
+ \u{1F18E}
+ \u{1F191}-\u{1F19A}
+ \u{1F200}-\u{1F202}
+ \u{1F210}-\u{1F23B}
+ \u{1F240}-\u{1F248}
+ \u{1F250}-\u{1F251}
+ \u{1F260}-\u{1F265}
+ \u{1F300}-\u{1F320}
+ \u{1F32D}-\u{1F335}
+ \u{1F337}-\u{1F37C}
+ \u{1F37E}-\u{1F393}
+ \u{1F3A0}-\u{1F3CA}
+ \u{1F3CF}-\u{1F3D3}
+ \u{1F3E0}-\u{1F3F0}
+ \u{1F3F4}
+ \u{1F3F8}-\u{1F43E}
+ \u{1F440}
+ \u{1F442}-\u{1F4FC}
+ \u{1F4FF}-\u{1F53D}
+ \u{1F54B}-\u{1F54E}
+ \u{1F550}-\u{1F567}
+ \u{1F57A}
+ \u{1F595}-\u{1F596}
+ \u{1F5A4}
+ \u{1F5FB}-\u{1F64F}
+ \u{1F680}-\u{1F6C5}
+ \u{1F6CC}
+ \u{1F6D0}-\u{1F6D2}
+ \u{1F6D5}-\u{1F6D7}
+ \u{1F6EB}-\u{1F6EC}
+ \u{1F6F4}-\u{1F6FC}
+ \u{1F7E0}-\u{1F7EB}
+ \u{1F90C}-\u{1F93A}
+ \u{1F93C}-\u{1F945}
+ \u{1F947}-\u{1F978}
+ \u{1F97A}-\u{1F9CB}
+ \u{1F9CD}-\u{1F9FF}
+ \u{1FA70}-\u{1FA74}
+ \u{1FA78}-\u{1FA7A}
+ \u{1FA80}-\u{1FA86}
+ \u{1FA90}-\u{1FAA8}
+ \u{1FAB0}-\u{1FAB6}
+ \u{1FAC0}-\u{1FAC2}
+ \u{1FAD0}-\u{1FAD6}
+ \u{20000}-\u{2FFFD}
+ \u{30000}-\u{3FFFD}
+ ).join }]/
+
+ # Narrow
+ TYPE_NA = /^[#{ %W(
+ \u{0020}-\u{007E}
+ \u{00A2}-\u{00A3}
+ \u{00A5}-\u{00A6}
+ \u{00AC}
+ \u{00AF}
+ \u{27E6}-\u{27ED}
+ \u{2985}-\u{2986}
+ ).join }]/
+
+ # Ambiguous
+ TYPE_A = /^[#{ %W(
+ \u{00A1}
+ \u{00A4}
+ \u{00A7}-\u{00A8}
+ \u{00AA}
+ \u{00AD}-\u{00AE}
+ \u{00B0}-\u{00B4}
+ \u{00B6}-\u{00BA}
+ \u{00BC}-\u{00BF}
+ \u{00C6}
+ \u{00D0}
+ \u{00D7}-\u{00D8}
+ \u{00DE}-\u{00E1}
+ \u{00E6}
+ \u{00E8}-\u{00EA}
+ \u{00EC}-\u{00ED}
+ \u{00F0}
+ \u{00F2}-\u{00F3}
+ \u{00F7}-\u{00FA}
+ \u{00FC}
+ \u{00FE}
+ \u{0101}
+ \u{0111}
+ \u{0113}
+ \u{011B}
+ \u{0126}-\u{0127}
+ \u{012B}
+ \u{0131}-\u{0133}
+ \u{0138}
+ \u{013F}-\u{0142}
+ \u{0144}
+ \u{0148}-\u{014B}
+ \u{014D}
+ \u{0152}-\u{0153}
+ \u{0166}-\u{0167}
+ \u{016B}
+ \u{01CE}
+ \u{01D0}
+ \u{01D2}
+ \u{01D4}
+ \u{01D6}
+ \u{01D8}
+ \u{01DA}
+ \u{01DC}
+ \u{0251}
+ \u{0261}
+ \u{02C4}
+ \u{02C7}
+ \u{02C9}-\u{02CB}
+ \u{02CD}
+ \u{02D0}
+ \u{02D8}-\u{02DB}
+ \u{02DD}
+ \u{02DF}
+ \u{0300}-\u{036F}
+ \u{0391}-\u{03A1}
+ \u{03A3}-\u{03A9}
+ \u{03B1}-\u{03C1}
+ \u{03C3}-\u{03C9}
+ \u{0401}
+ \u{0410}-\u{044F}
+ \u{0451}
+ \u{2010}
+ \u{2013}-\u{2016}
+ \u{2018}-\u{2019}
+ \u{201C}-\u{201D}
+ \u{2020}-\u{2022}
+ \u{2024}-\u{2027}
+ \u{2030}
+ \u{2032}-\u{2033}
+ \u{2035}
+ \u{203B}
+ \u{203E}
+ \u{2074}
+ \u{207F}
+ \u{2081}-\u{2084}
+ \u{20AC}
+ \u{2103}
+ \u{2105}
+ \u{2109}
+ \u{2113}
+ \u{2116}
+ \u{2121}-\u{2122}
+ \u{2126}
+ \u{212B}
+ \u{2153}-\u{2154}
+ \u{215B}-\u{215E}
+ \u{2160}-\u{216B}
+ \u{2170}-\u{2179}
+ \u{2189}
+ \u{2190}-\u{2199}
+ \u{21B8}-\u{21B9}
+ \u{21D2}
+ \u{21D4}
+ \u{21E7}
+ \u{2200}
+ \u{2202}-\u{2203}
+ \u{2207}-\u{2208}
+ \u{220B}
+ \u{220F}
+ \u{2211}
+ \u{2215}
+ \u{221A}
+ \u{221D}-\u{2220}
+ \u{2223}
+ \u{2225}
+ \u{2227}-\u{222C}
+ \u{222E}
+ \u{2234}-\u{2237}
+ \u{223C}-\u{223D}
+ \u{2248}
+ \u{224C}
+ \u{2252}
+ \u{2260}-\u{2261}
+ \u{2264}-\u{2267}
+ \u{226A}-\u{226B}
+ \u{226E}-\u{226F}
+ \u{2282}-\u{2283}
+ \u{2286}-\u{2287}
+ \u{2295}
+ \u{2299}
+ \u{22A5}
+ \u{22BF}
+ \u{2312}
+ \u{2460}-\u{24E9}
+ \u{24EB}-\u{254B}
+ \u{2550}-\u{2573}
+ \u{2580}-\u{258F}
+ \u{2592}-\u{2595}
+ \u{25A0}-\u{25A1}
+ \u{25A3}-\u{25A9}
+ \u{25B2}-\u{25B3}
+ \u{25B6}-\u{25B7}
+ \u{25BC}-\u{25BD}
+ \u{25C0}-\u{25C1}
+ \u{25C6}-\u{25C8}
+ \u{25CB}
+ \u{25CE}-\u{25D1}
+ \u{25E2}-\u{25E5}
+ \u{25EF}
+ \u{2605}-\u{2606}
+ \u{2609}
+ \u{260E}-\u{260F}
+ \u{261C}
+ \u{261E}
+ \u{2640}
+ \u{2642}
+ \u{2660}-\u{2661}
+ \u{2663}-\u{2665}
+ \u{2667}-\u{266A}
+ \u{266C}-\u{266D}
+ \u{266F}
+ \u{269E}-\u{269F}
+ \u{26BF}
+ \u{26C6}-\u{26CD}
+ \u{26CF}-\u{26D3}
+ \u{26D5}-\u{26E1}
+ \u{26E3}
+ \u{26E8}-\u{26E9}
+ \u{26EB}-\u{26F1}
+ \u{26F4}
+ \u{26F6}-\u{26F9}
+ \u{26FB}-\u{26FC}
+ \u{26FE}-\u{26FF}
+ \u{273D}
+ \u{2776}-\u{277F}
+ \u{2B56}-\u{2B59}
+ \u{3248}-\u{324F}
+ \u{E000}-\u{F8FF}
+ \u{FE00}-\u{FE0F}
+ \u{FFFD}
+ \u{1F100}-\u{1F10A}
+ \u{1F110}-\u{1F12D}
+ \u{1F130}-\u{1F169}
+ \u{1F170}-\u{1F18D}
+ \u{1F18F}-\u{1F190}
+ \u{1F19B}-\u{1F1AC}
+ \u{E0100}-\u{E01EF}
+ \u{F0000}-\u{FFFFD}
+ \u{100000}-\u{10FFFD}
+ ).join }]/
+
+ # Neutral
+ TYPE_N = /^[#{ %W(
+ \u{0000}-\u{001F}
+ \u{007F}-\u{00A0}
+ \u{00A9}
+ \u{00AB}
+ \u{00B5}
+ \u{00BB}
+ \u{00C0}-\u{00C5}
+ \u{00C7}-\u{00CF}
+ \u{00D1}-\u{00D6}
+ \u{00D9}-\u{00DD}
+ \u{00E2}-\u{00E5}
+ \u{00E7}
+ \u{00EB}
+ \u{00EE}-\u{00EF}
+ \u{00F1}
+ \u{00F4}-\u{00F6}
+ \u{00FB}
+ \u{00FD}
+ \u{00FF}-\u{0100}
+ \u{0102}-\u{0110}
+ \u{0112}
+ \u{0114}-\u{011A}
+ \u{011C}-\u{0125}
+ \u{0128}-\u{012A}
+ \u{012C}-\u{0130}
+ \u{0134}-\u{0137}
+ \u{0139}-\u{013E}
+ \u{0143}
+ \u{0145}-\u{0147}
+ \u{014C}
+ \u{014E}-\u{0151}
+ \u{0154}-\u{0165}
+ \u{0168}-\u{016A}
+ \u{016C}-\u{01CD}
+ \u{01CF}
+ \u{01D1}
+ \u{01D3}
+ \u{01D5}
+ \u{01D7}
+ \u{01D9}
+ \u{01DB}
+ \u{01DD}-\u{0250}
+ \u{0252}-\u{0260}
+ \u{0262}-\u{02C3}
+ \u{02C5}-\u{02C6}
+ \u{02C8}
+ \u{02CC}
+ \u{02CE}-\u{02CF}
+ \u{02D1}-\u{02D7}
+ \u{02DC}
+ \u{02DE}
+ \u{02E0}-\u{02FF}
+ \u{0370}-\u{0377}
+ \u{037A}-\u{037F}
+ \u{0384}-\u{038A}
+ \u{038C}
+ \u{038E}-\u{0390}
+ \u{03AA}-\u{03B0}
+ \u{03C2}
+ \u{03CA}-\u{0400}
+ \u{0402}-\u{040F}
+ \u{0450}
+ \u{0452}-\u{052F}
+ \u{0531}-\u{0556}
+ \u{0559}-\u{058A}
+ \u{058D}-\u{058F}
+ \u{0591}-\u{05C7}
+ \u{05D0}-\u{05EA}
+ \u{05EF}-\u{05F4}
+ \u{0600}-\u{061C}
+ \u{061E}-\u{070D}
+ \u{070F}-\u{074A}
+ \u{074D}-\u{07B1}
+ \u{07C0}-\u{07FA}
+ \u{07FD}-\u{082D}
+ \u{0830}-\u{083E}
+ \u{0840}-\u{085B}
+ \u{085E}
+ \u{0860}-\u{086A}
+ \u{08A0}-\u{08B4}
+ \u{08B6}-\u{08C7}
+ \u{08D3}-\u{0983}
+ \u{0985}-\u{098C}
+ \u{098F}-\u{0990}
+ \u{0993}-\u{09A8}
+ \u{09AA}-\u{09B0}
+ \u{09B2}
+ \u{09B6}-\u{09B9}
+ \u{09BC}-\u{09C4}
+ \u{09C7}-\u{09C8}
+ \u{09CB}-\u{09CE}
+ \u{09D7}
+ \u{09DC}-\u{09DD}
+ \u{09DF}-\u{09E3}
+ \u{09E6}-\u{09FE}
+ \u{0A01}-\u{0A03}
+ \u{0A05}-\u{0A0A}
+ \u{0A0F}-\u{0A10}
+ \u{0A13}-\u{0A28}
+ \u{0A2A}-\u{0A30}
+ \u{0A32}-\u{0A33}
+ \u{0A35}-\u{0A36}
+ \u{0A38}-\u{0A39}
+ \u{0A3C}
+ \u{0A3E}-\u{0A42}
+ \u{0A47}-\u{0A48}
+ \u{0A4B}-\u{0A4D}
+ \u{0A51}
+ \u{0A59}-\u{0A5C}
+ \u{0A5E}
+ \u{0A66}-\u{0A76}
+ \u{0A81}-\u{0A83}
+ \u{0A85}-\u{0A8D}
+ \u{0A8F}-\u{0A91}
+ \u{0A93}-\u{0AA8}
+ \u{0AAA}-\u{0AB0}
+ \u{0AB2}-\u{0AB3}
+ \u{0AB5}-\u{0AB9}
+ \u{0ABC}-\u{0AC5}
+ \u{0AC7}-\u{0AC9}
+ \u{0ACB}-\u{0ACD}
+ \u{0AD0}
+ \u{0AE0}-\u{0AE3}
+ \u{0AE6}-\u{0AF1}
+ \u{0AF9}-\u{0AFF}
+ \u{0B01}-\u{0B03}
+ \u{0B05}-\u{0B0C}
+ \u{0B0F}-\u{0B10}
+ \u{0B13}-\u{0B28}
+ \u{0B2A}-\u{0B30}
+ \u{0B32}-\u{0B33}
+ \u{0B35}-\u{0B39}
+ \u{0B3C}-\u{0B44}
+ \u{0B47}-\u{0B48}
+ \u{0B4B}-\u{0B4D}
+ \u{0B55}-\u{0B57}
+ \u{0B5C}-\u{0B5D}
+ \u{0B5F}-\u{0B63}
+ \u{0B66}-\u{0B77}
+ \u{0B82}-\u{0B83}
+ \u{0B85}-\u{0B8A}
+ \u{0B8E}-\u{0B90}
+ \u{0B92}-\u{0B95}
+ \u{0B99}-\u{0B9A}
+ \u{0B9C}
+ \u{0B9E}-\u{0B9F}
+ \u{0BA3}-\u{0BA4}
+ \u{0BA8}-\u{0BAA}
+ \u{0BAE}-\u{0BB9}
+ \u{0BBE}-\u{0BC2}
+ \u{0BC6}-\u{0BC8}
+ \u{0BCA}-\u{0BCD}
+ \u{0BD0}
+ \u{0BD7}
+ \u{0BE6}-\u{0BFA}
+ \u{0C00}-\u{0C0C}
+ \u{0C0E}-\u{0C10}
+ \u{0C12}-\u{0C28}
+ \u{0C2A}-\u{0C39}
+ \u{0C3D}-\u{0C44}
+ \u{0C46}-\u{0C48}
+ \u{0C4A}-\u{0C4D}
+ \u{0C55}-\u{0C56}
+ \u{0C58}-\u{0C5A}
+ \u{0C60}-\u{0C63}
+ \u{0C66}-\u{0C6F}
+ \u{0C77}-\u{0C8C}
+ \u{0C8E}-\u{0C90}
+ \u{0C92}-\u{0CA8}
+ \u{0CAA}-\u{0CB3}
+ \u{0CB5}-\u{0CB9}
+ \u{0CBC}-\u{0CC4}
+ \u{0CC6}-\u{0CC8}
+ \u{0CCA}-\u{0CCD}
+ \u{0CD5}-\u{0CD6}
+ \u{0CDE}
+ \u{0CE0}-\u{0CE3}
+ \u{0CE6}-\u{0CEF}
+ \u{0CF1}-\u{0CF2}
+ \u{0D00}-\u{0D0C}
+ \u{0D0E}-\u{0D10}
+ \u{0D12}-\u{0D44}
+ \u{0D46}-\u{0D48}
+ \u{0D4A}-\u{0D4F}
+ \u{0D54}-\u{0D63}
+ \u{0D66}-\u{0D7F}
+ \u{0D81}-\u{0D83}
+ \u{0D85}-\u{0D96}
+ \u{0D9A}-\u{0DB1}
+ \u{0DB3}-\u{0DBB}
+ \u{0DBD}
+ \u{0DC0}-\u{0DC6}
+ \u{0DCA}
+ \u{0DCF}-\u{0DD4}
+ \u{0DD6}
+ \u{0DD8}-\u{0DDF}
+ \u{0DE6}-\u{0DEF}
+ \u{0DF2}-\u{0DF4}
+ \u{0E01}-\u{0E3A}
+ \u{0E3F}-\u{0E5B}
+ \u{0E81}-\u{0E82}
+ \u{0E84}
+ \u{0E86}-\u{0E8A}
+ \u{0E8C}-\u{0EA3}
+ \u{0EA5}
+ \u{0EA7}-\u{0EBD}
+ \u{0EC0}-\u{0EC4}
+ \u{0EC6}
+ \u{0EC8}-\u{0ECD}
+ \u{0ED0}-\u{0ED9}
+ \u{0EDC}-\u{0EDF}
+ \u{0F00}-\u{0F47}
+ \u{0F49}-\u{0F6C}
+ \u{0F71}-\u{0F97}
+ \u{0F99}-\u{0FBC}
+ \u{0FBE}-\u{0FCC}
+ \u{0FCE}-\u{0FDA}
+ \u{1000}-\u{10C5}
+ \u{10C7}
+ \u{10CD}
+ \u{10D0}-\u{10FF}
+ \u{1160}-\u{1248}
+ \u{124A}-\u{124D}
+ \u{1250}-\u{1256}
+ \u{1258}
+ \u{125A}-\u{125D}
+ \u{1260}-\u{1288}
+ \u{128A}-\u{128D}
+ \u{1290}-\u{12B0}
+ \u{12B2}-\u{12B5}
+ \u{12B8}-\u{12BE}
+ \u{12C0}
+ \u{12C2}-\u{12C5}
+ \u{12C8}-\u{12D6}
+ \u{12D8}-\u{1310}
+ \u{1312}-\u{1315}
+ \u{1318}-\u{135A}
+ \u{135D}-\u{137C}
+ \u{1380}-\u{1399}
+ \u{13A0}-\u{13F5}
+ \u{13F8}-\u{13FD}
+ \u{1400}-\u{169C}
+ \u{16A0}-\u{16F8}
+ \u{1700}-\u{170C}
+ \u{170E}-\u{1714}
+ \u{1720}-\u{1736}
+ \u{1740}-\u{1753}
+ \u{1760}-\u{176C}
+ \u{176E}-\u{1770}
+ \u{1772}-\u{1773}
+ \u{1780}-\u{17DD}
+ \u{17E0}-\u{17E9}
+ \u{17F0}-\u{17F9}
+ \u{1800}-\u{180E}
+ \u{1810}-\u{1819}
+ \u{1820}-\u{1878}
+ \u{1880}-\u{18AA}
+ \u{18B0}-\u{18F5}
+ \u{1900}-\u{191E}
+ \u{1920}-\u{192B}
+ \u{1930}-\u{193B}
+ \u{1940}
+ \u{1944}-\u{196D}
+ \u{1970}-\u{1974}
+ \u{1980}-\u{19AB}
+ \u{19B0}-\u{19C9}
+ \u{19D0}-\u{19DA}
+ \u{19DE}-\u{1A1B}
+ \u{1A1E}-\u{1A5E}
+ \u{1A60}-\u{1A7C}
+ \u{1A7F}-\u{1A89}
+ \u{1A90}-\u{1A99}
+ \u{1AA0}-\u{1AAD}
+ \u{1AB0}-\u{1AC0}
+ \u{1B00}-\u{1B4B}
+ \u{1B50}-\u{1B7C}
+ \u{1B80}-\u{1BF3}
+ \u{1BFC}-\u{1C37}
+ \u{1C3B}-\u{1C49}
+ \u{1C4D}-\u{1C88}
+ \u{1C90}-\u{1CBA}
+ \u{1CBD}-\u{1CC7}
+ \u{1CD0}-\u{1CFA}
+ \u{1D00}-\u{1DF9}
+ \u{1DFB}-\u{1F15}
+ \u{1F18}-\u{1F1D}
+ \u{1F20}-\u{1F45}
+ \u{1F48}-\u{1F4D}
+ \u{1F50}-\u{1F57}
+ \u{1F59}
+ \u{1F5B}
+ \u{1F5D}
+ \u{1F5F}-\u{1F7D}
+ \u{1F80}-\u{1FB4}
+ \u{1FB6}-\u{1FC4}
+ \u{1FC6}-\u{1FD3}
+ \u{1FD6}-\u{1FDB}
+ \u{1FDD}-\u{1FEF}
+ \u{1FF2}-\u{1FF4}
+ \u{1FF6}-\u{1FFE}
+ \u{2000}-\u{200F}
+ \u{2011}-\u{2012}
+ \u{2017}
+ \u{201A}-\u{201B}
+ \u{201E}-\u{201F}
+ \u{2023}
+ \u{2028}-\u{202F}
+ \u{2031}
+ \u{2034}
+ \u{2036}-\u{203A}
+ \u{203C}-\u{203D}
+ \u{203F}-\u{2064}
+ \u{2066}-\u{2071}
+ \u{2075}-\u{207E}
+ \u{2080}
+ \u{2085}-\u{208E}
+ \u{2090}-\u{209C}
+ \u{20A0}-\u{20A8}
+ \u{20AA}-\u{20AB}
+ \u{20AD}-\u{20BF}
+ \u{20D0}-\u{20F0}
+ \u{2100}-\u{2102}
+ \u{2104}
+ \u{2106}-\u{2108}
+ \u{210A}-\u{2112}
+ \u{2114}-\u{2115}
+ \u{2117}-\u{2120}
+ \u{2123}-\u{2125}
+ \u{2127}-\u{212A}
+ \u{212C}-\u{2152}
+ \u{2155}-\u{215A}
+ \u{215F}
+ \u{216C}-\u{216F}
+ \u{217A}-\u{2188}
+ \u{218A}-\u{218B}
+ \u{219A}-\u{21B7}
+ \u{21BA}-\u{21D1}
+ \u{21D3}
+ \u{21D5}-\u{21E6}
+ \u{21E8}-\u{21FF}
+ \u{2201}
+ \u{2204}-\u{2206}
+ \u{2209}-\u{220A}
+ \u{220C}-\u{220E}
+ \u{2210}
+ \u{2212}-\u{2214}
+ \u{2216}-\u{2219}
+ \u{221B}-\u{221C}
+ \u{2221}-\u{2222}
+ \u{2224}
+ \u{2226}
+ \u{222D}
+ \u{222F}-\u{2233}
+ \u{2238}-\u{223B}
+ \u{223E}-\u{2247}
+ \u{2249}-\u{224B}
+ \u{224D}-\u{2251}
+ \u{2253}-\u{225F}
+ \u{2262}-\u{2263}
+ \u{2268}-\u{2269}
+ \u{226C}-\u{226D}
+ \u{2270}-\u{2281}
+ \u{2284}-\u{2285}
+ \u{2288}-\u{2294}
+ \u{2296}-\u{2298}
+ \u{229A}-\u{22A4}
+ \u{22A6}-\u{22BE}
+ \u{22C0}-\u{2311}
+ \u{2313}-\u{2319}
+ \u{231C}-\u{2328}
+ \u{232B}-\u{23E8}
+ \u{23ED}-\u{23EF}
+ \u{23F1}-\u{23F2}
+ \u{23F4}-\u{2426}
+ \u{2440}-\u{244A}
+ \u{24EA}
+ \u{254C}-\u{254F}
+ \u{2574}-\u{257F}
+ \u{2590}-\u{2591}
+ \u{2596}-\u{259F}
+ \u{25A2}
+ \u{25AA}-\u{25B1}
+ \u{25B4}-\u{25B5}
+ \u{25B8}-\u{25BB}
+ \u{25BE}-\u{25BF}
+ \u{25C2}-\u{25C5}
+ \u{25C9}-\u{25CA}
+ \u{25CC}-\u{25CD}
+ \u{25D2}-\u{25E1}
+ \u{25E6}-\u{25EE}
+ \u{25F0}-\u{25FC}
+ \u{25FF}-\u{2604}
+ \u{2607}-\u{2608}
+ \u{260A}-\u{260D}
+ \u{2610}-\u{2613}
+ \u{2616}-\u{261B}
+ \u{261D}
+ \u{261F}-\u{263F}
+ \u{2641}
+ \u{2643}-\u{2647}
+ \u{2654}-\u{265F}
+ \u{2662}
+ \u{2666}
+ \u{266B}
+ \u{266E}
+ \u{2670}-\u{267E}
+ \u{2680}-\u{2692}
+ \u{2694}-\u{269D}
+ \u{26A0}
+ \u{26A2}-\u{26A9}
+ \u{26AC}-\u{26BC}
+ \u{26C0}-\u{26C3}
+ \u{26E2}
+ \u{26E4}-\u{26E7}
+ \u{2700}-\u{2704}
+ \u{2706}-\u{2709}
+ \u{270C}-\u{2727}
+ \u{2729}-\u{273C}
+ \u{273E}-\u{274B}
+ \u{274D}
+ \u{274F}-\u{2752}
+ \u{2756}
+ \u{2758}-\u{2775}
+ \u{2780}-\u{2794}
+ \u{2798}-\u{27AF}
+ \u{27B1}-\u{27BE}
+ \u{27C0}-\u{27E5}
+ \u{27EE}-\u{2984}
+ \u{2987}-\u{2B1A}
+ \u{2B1D}-\u{2B4F}
+ \u{2B51}-\u{2B54}
+ \u{2B5A}-\u{2B73}
+ \u{2B76}-\u{2B95}
+ \u{2B97}-\u{2C2E}
+ \u{2C30}-\u{2C5E}
+ \u{2C60}-\u{2CF3}
+ \u{2CF9}-\u{2D25}
+ \u{2D27}
+ \u{2D2D}
+ \u{2D30}-\u{2D67}
+ \u{2D6F}-\u{2D70}
+ \u{2D7F}-\u{2D96}
+ \u{2DA0}-\u{2DA6}
+ \u{2DA8}-\u{2DAE}
+ \u{2DB0}-\u{2DB6}
+ \u{2DB8}-\u{2DBE}
+ \u{2DC0}-\u{2DC6}
+ \u{2DC8}-\u{2DCE}
+ \u{2DD0}-\u{2DD6}
+ \u{2DD8}-\u{2DDE}
+ \u{2DE0}-\u{2E52}
+ \u{303F}
+ \u{4DC0}-\u{4DFF}
+ \u{A4D0}-\u{A62B}
+ \u{A640}-\u{A6F7}
+ \u{A700}-\u{A7BF}
+ \u{A7C2}-\u{A7CA}
+ \u{A7F5}-\u{A82C}
+ \u{A830}-\u{A839}
+ \u{A840}-\u{A877}
+ \u{A880}-\u{A8C5}
+ \u{A8CE}-\u{A8D9}
+ \u{A8E0}-\u{A953}
+ \u{A95F}
+ \u{A980}-\u{A9CD}
+ \u{A9CF}-\u{A9D9}
+ \u{A9DE}-\u{A9FE}
+ \u{AA00}-\u{AA36}
+ \u{AA40}-\u{AA4D}
+ \u{AA50}-\u{AA59}
+ \u{AA5C}-\u{AAC2}
+ \u{AADB}-\u{AAF6}
+ \u{AB01}-\u{AB06}
+ \u{AB09}-\u{AB0E}
+ \u{AB11}-\u{AB16}
+ \u{AB20}-\u{AB26}
+ \u{AB28}-\u{AB2E}
+ \u{AB30}-\u{AB6B}
+ \u{AB70}-\u{ABED}
+ \u{ABF0}-\u{ABF9}
+ \u{D7B0}-\u{D7C6}
+ \u{D7CB}-\u{D7FB}
+ \u{FB00}-\u{FB06}
+ \u{FB13}-\u{FB17}
+ \u{FB1D}-\u{FB36}
+ \u{FB38}-\u{FB3C}
+ \u{FB3E}
+ \u{FB40}-\u{FB41}
+ \u{FB43}-\u{FB44}
+ \u{FB46}-\u{FBC1}
+ \u{FBD3}-\u{FD3F}
+ \u{FD50}-\u{FD8F}
+ \u{FD92}-\u{FDC7}
+ \u{FDF0}-\u{FDFD}
+ \u{FE20}-\u{FE2F}
+ \u{FE70}-\u{FE74}
+ \u{FE76}-\u{FEFC}
+ \u{FEFF}
+ \u{FFF9}-\u{FFFC}
+ \u{10000}-\u{1000B}
+ \u{1000D}-\u{10026}
+ \u{10028}-\u{1003A}
+ \u{1003C}-\u{1003D}
+ \u{1003F}-\u{1004D}
+ \u{10050}-\u{1005D}
+ \u{10080}-\u{100FA}
+ \u{10100}-\u{10102}
+ \u{10107}-\u{10133}
+ \u{10137}-\u{1018E}
+ \u{10190}-\u{1019C}
+ \u{101A0}
+ \u{101D0}-\u{101FD}
+ \u{10280}-\u{1029C}
+ \u{102A0}-\u{102D0}
+ \u{102E0}-\u{102FB}
+ \u{10300}-\u{10323}
+ \u{1032D}-\u{1034A}
+ \u{10350}-\u{1037A}
+ \u{10380}-\u{1039D}
+ \u{1039F}-\u{103C3}
+ \u{103C8}-\u{103D5}
+ \u{10400}-\u{1049D}
+ \u{104A0}-\u{104A9}
+ \u{104B0}-\u{104D3}
+ \u{104D8}-\u{104FB}
+ \u{10500}-\u{10527}
+ \u{10530}-\u{10563}
+ \u{1056F}
+ \u{10600}-\u{10736}
+ \u{10740}-\u{10755}
+ \u{10760}-\u{10767}
+ \u{10800}-\u{10805}
+ \u{10808}
+ \u{1080A}-\u{10835}
+ \u{10837}-\u{10838}
+ \u{1083C}
+ \u{1083F}-\u{10855}
+ \u{10857}-\u{1089E}
+ \u{108A7}-\u{108AF}
+ \u{108E0}-\u{108F2}
+ \u{108F4}-\u{108F5}
+ \u{108FB}-\u{1091B}
+ \u{1091F}-\u{10939}
+ \u{1093F}
+ \u{10980}-\u{109B7}
+ \u{109BC}-\u{109CF}
+ \u{109D2}-\u{10A03}
+ \u{10A05}-\u{10A06}
+ \u{10A0C}-\u{10A13}
+ \u{10A15}-\u{10A17}
+ \u{10A19}-\u{10A35}
+ \u{10A38}-\u{10A3A}
+ \u{10A3F}-\u{10A48}
+ \u{10A50}-\u{10A58}
+ \u{10A60}-\u{10A9F}
+ \u{10AC0}-\u{10AE6}
+ \u{10AEB}-\u{10AF6}
+ \u{10B00}-\u{10B35}
+ \u{10B39}-\u{10B55}
+ \u{10B58}-\u{10B72}
+ \u{10B78}-\u{10B91}
+ \u{10B99}-\u{10B9C}
+ \u{10BA9}-\u{10BAF}
+ \u{10C00}-\u{10C48}
+ \u{10C80}-\u{10CB2}
+ \u{10CC0}-\u{10CF2}
+ \u{10CFA}-\u{10D27}
+ \u{10D30}-\u{10D39}
+ \u{10E60}-\u{10E7E}
+ \u{10E80}-\u{10EA9}
+ \u{10EAB}-\u{10EAD}
+ \u{10EB0}-\u{10EB1}
+ \u{10F00}-\u{10F27}
+ \u{10F30}-\u{10F59}
+ \u{10FB0}-\u{10FCB}
+ \u{10FE0}-\u{10FF6}
+ \u{11000}-\u{1104D}
+ \u{11052}-\u{1106F}
+ \u{1107F}-\u{110C1}
+ \u{110CD}
+ \u{110D0}-\u{110E8}
+ \u{110F0}-\u{110F9}
+ \u{11100}-\u{11134}
+ \u{11136}-\u{11147}
+ \u{11150}-\u{11176}
+ \u{11180}-\u{111DF}
+ \u{111E1}-\u{111F4}
+ \u{11200}-\u{11211}
+ \u{11213}-\u{1123E}
+ \u{11280}-\u{11286}
+ \u{11288}
+ \u{1128A}-\u{1128D}
+ \u{1128F}-\u{1129D}
+ \u{1129F}-\u{112A9}
+ \u{112B0}-\u{112EA}
+ \u{112F0}-\u{112F9}
+ \u{11300}-\u{11303}
+ \u{11305}-\u{1130C}
+ \u{1130F}-\u{11310}
+ \u{11313}-\u{11328}
+ \u{1132A}-\u{11330}
+ \u{11332}-\u{11333}
+ \u{11335}-\u{11339}
+ \u{1133B}-\u{11344}
+ \u{11347}-\u{11348}
+ \u{1134B}-\u{1134D}
+ \u{11350}
+ \u{11357}
+ \u{1135D}-\u{11363}
+ \u{11366}-\u{1136C}
+ \u{11370}-\u{11374}
+ \u{11400}-\u{1145B}
+ \u{1145D}-\u{11461}
+ \u{11480}-\u{114C7}
+ \u{114D0}-\u{114D9}
+ \u{11580}-\u{115B5}
+ \u{115B8}-\u{115DD}
+ \u{11600}-\u{11644}
+ \u{11650}-\u{11659}
+ \u{11660}-\u{1166C}
+ \u{11680}-\u{116B8}
+ \u{116C0}-\u{116C9}
+ \u{11700}-\u{1171A}
+ \u{1171D}-\u{1172B}
+ \u{11730}-\u{1173F}
+ \u{11800}-\u{1183B}
+ \u{118A0}-\u{118F2}
+ \u{118FF}-\u{11906}
+ \u{11909}
+ \u{1190C}-\u{11913}
+ \u{11915}-\u{11916}
+ \u{11918}-\u{11935}
+ \u{11937}-\u{11938}
+ \u{1193B}-\u{11946}
+ \u{11950}-\u{11959}
+ \u{119A0}-\u{119A7}
+ \u{119AA}-\u{119D7}
+ \u{119DA}-\u{119E4}
+ \u{11A00}-\u{11A47}
+ \u{11A50}-\u{11AA2}
+ \u{11AC0}-\u{11AF8}
+ \u{11C00}-\u{11C08}
+ \u{11C0A}-\u{11C36}
+ \u{11C38}-\u{11C45}
+ \u{11C50}-\u{11C6C}
+ \u{11C70}-\u{11C8F}
+ \u{11C92}-\u{11CA7}
+ \u{11CA9}-\u{11CB6}
+ \u{11D00}-\u{11D06}
+ \u{11D08}-\u{11D09}
+ \u{11D0B}-\u{11D36}
+ \u{11D3A}
+ \u{11D3C}-\u{11D3D}
+ \u{11D3F}-\u{11D47}
+ \u{11D50}-\u{11D59}
+ \u{11D60}-\u{11D65}
+ \u{11D67}-\u{11D68}
+ \u{11D6A}-\u{11D8E}
+ \u{11D90}-\u{11D91}
+ \u{11D93}-\u{11D98}
+ \u{11DA0}-\u{11DA9}
+ \u{11EE0}-\u{11EF8}
+ \u{11FB0}
+ \u{11FC0}-\u{11FF1}
+ \u{11FFF}-\u{12399}
+ \u{12400}-\u{1246E}
+ \u{12470}-\u{12474}
+ \u{12480}-\u{12543}
+ \u{13000}-\u{1342E}
+ \u{13430}-\u{13438}
+ \u{14400}-\u{14646}
+ \u{16800}-\u{16A38}
+ \u{16A40}-\u{16A5E}
+ \u{16A60}-\u{16A69}
+ \u{16A6E}-\u{16A6F}
+ \u{16AD0}-\u{16AED}
+ \u{16AF0}-\u{16AF5}
+ \u{16B00}-\u{16B45}
+ \u{16B50}-\u{16B59}
+ \u{16B5B}-\u{16B61}
+ \u{16B63}-\u{16B77}
+ \u{16B7D}-\u{16B8F}
+ \u{16E40}-\u{16E9A}
+ \u{16F00}-\u{16F4A}
+ \u{16F4F}-\u{16F87}
+ \u{16F8F}-\u{16F9F}
+ \u{1BC00}-\u{1BC6A}
+ \u{1BC70}-\u{1BC7C}
+ \u{1BC80}-\u{1BC88}
+ \u{1BC90}-\u{1BC99}
+ \u{1BC9C}-\u{1BCA3}
+ \u{1D000}-\u{1D0F5}
+ \u{1D100}-\u{1D126}
+ \u{1D129}-\u{1D1E8}
+ \u{1D200}-\u{1D245}
+ \u{1D2E0}-\u{1D2F3}
+ \u{1D300}-\u{1D356}
+ \u{1D360}-\u{1D378}
+ \u{1D400}-\u{1D454}
+ \u{1D456}-\u{1D49C}
+ \u{1D49E}-\u{1D49F}
+ \u{1D4A2}
+ \u{1D4A5}-\u{1D4A6}
+ \u{1D4A9}-\u{1D4AC}
+ \u{1D4AE}-\u{1D4B9}
+ \u{1D4BB}
+ \u{1D4BD}-\u{1D4C3}
+ \u{1D4C5}-\u{1D505}
+ \u{1D507}-\u{1D50A}
+ \u{1D50D}-\u{1D514}
+ \u{1D516}-\u{1D51C}
+ \u{1D51E}-\u{1D539}
+ \u{1D53B}-\u{1D53E}
+ \u{1D540}-\u{1D544}
+ \u{1D546}
+ \u{1D54A}-\u{1D550}
+ \u{1D552}-\u{1D6A5}
+ \u{1D6A8}-\u{1D7CB}
+ \u{1D7CE}-\u{1DA8B}
+ \u{1DA9B}-\u{1DA9F}
+ \u{1DAA1}-\u{1DAAF}
+ \u{1E000}-\u{1E006}
+ \u{1E008}-\u{1E018}
+ \u{1E01B}-\u{1E021}
+ \u{1E023}-\u{1E024}
+ \u{1E026}-\u{1E02A}
+ \u{1E100}-\u{1E12C}
+ \u{1E130}-\u{1E13D}
+ \u{1E140}-\u{1E149}
+ \u{1E14E}-\u{1E14F}
+ \u{1E2C0}-\u{1E2F9}
+ \u{1E2FF}
+ \u{1E800}-\u{1E8C4}
+ \u{1E8C7}-\u{1E8D6}
+ \u{1E900}-\u{1E94B}
+ \u{1E950}-\u{1E959}
+ \u{1E95E}-\u{1E95F}
+ \u{1EC71}-\u{1ECB4}
+ \u{1ED01}-\u{1ED3D}
+ \u{1EE00}-\u{1EE03}
+ \u{1EE05}-\u{1EE1F}
+ \u{1EE21}-\u{1EE22}
+ \u{1EE24}
+ \u{1EE27}
+ \u{1EE29}-\u{1EE32}
+ \u{1EE34}-\u{1EE37}
+ \u{1EE39}
+ \u{1EE3B}
+ \u{1EE42}
+ \u{1EE47}
+ \u{1EE49}
+ \u{1EE4B}
+ \u{1EE4D}-\u{1EE4F}
+ \u{1EE51}-\u{1EE52}
+ \u{1EE54}
+ \u{1EE57}
+ \u{1EE59}
+ \u{1EE5B}
+ \u{1EE5D}
+ \u{1EE5F}
+ \u{1EE61}-\u{1EE62}
+ \u{1EE64}
+ \u{1EE67}-\u{1EE6A}
+ \u{1EE6C}-\u{1EE72}
+ \u{1EE74}-\u{1EE77}
+ \u{1EE79}-\u{1EE7C}
+ \u{1EE7E}
+ \u{1EE80}-\u{1EE89}
+ \u{1EE8B}-\u{1EE9B}
+ \u{1EEA1}-\u{1EEA3}
+ \u{1EEA5}-\u{1EEA9}
+ \u{1EEAB}-\u{1EEBB}
+ \u{1EEF0}-\u{1EEF1}
+ \u{1F000}-\u{1F003}
+ \u{1F005}-\u{1F02B}
+ \u{1F030}-\u{1F093}
+ \u{1F0A0}-\u{1F0AE}
+ \u{1F0B1}-\u{1F0BF}
+ \u{1F0C1}-\u{1F0CE}
+ \u{1F0D1}-\u{1F0F5}
+ \u{1F10B}-\u{1F10F}
+ \u{1F12E}-\u{1F12F}
+ \u{1F16A}-\u{1F16F}
+ \u{1F1AD}
+ \u{1F1E6}-\u{1F1FF}
+ \u{1F321}-\u{1F32C}
+ \u{1F336}
+ \u{1F37D}
+ \u{1F394}-\u{1F39F}
+ \u{1F3CB}-\u{1F3CE}
+ \u{1F3D4}-\u{1F3DF}
+ \u{1F3F1}-\u{1F3F3}
+ \u{1F3F5}-\u{1F3F7}
+ \u{1F43F}
+ \u{1F441}
+ \u{1F4FD}-\u{1F4FE}
+ \u{1F53E}-\u{1F54A}
+ \u{1F54F}
+ \u{1F568}-\u{1F579}
+ \u{1F57B}-\u{1F594}
+ \u{1F597}-\u{1F5A3}
+ \u{1F5A5}-\u{1F5FA}
+ \u{1F650}-\u{1F67F}
+ \u{1F6C6}-\u{1F6CB}
+ \u{1F6CD}-\u{1F6CF}
+ \u{1F6D3}-\u{1F6D4}
+ \u{1F6E0}-\u{1F6EA}
+ \u{1F6F0}-\u{1F6F3}
+ \u{1F700}-\u{1F773}
+ \u{1F780}-\u{1F7D8}
+ \u{1F800}-\u{1F80B}
+ \u{1F810}-\u{1F847}
+ \u{1F850}-\u{1F859}
+ \u{1F860}-\u{1F887}
+ \u{1F890}-\u{1F8AD}
+ \u{1F8B0}-\u{1F8B1}
+ \u{1F900}-\u{1F90B}
+ \u{1F93B}
+ \u{1F946}
+ \u{1FA00}-\u{1FA53}
+ \u{1FA60}-\u{1FA6D}
+ \u{1FB00}-\u{1FB92}
+ \u{1FB94}-\u{1FBCA}
+ \u{1FBF0}-\u{1FBF9}
+ \u{E0001}
+ \u{E0020}-\u{E007F}
+ ).join }]/
+end
diff --git a/lib/reline/version.rb b/lib/reline/version.rb
new file mode 100644
index 0000000000..44db465a2f
--- /dev/null
+++ b/lib/reline/version.rb
@@ -0,0 +1,3 @@
+module Reline
+ VERSION = '0.2.5'
+end
diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb
new file mode 100644
index 0000000000..6edc68e780
--- /dev/null
+++ b/lib/reline/windows.rb
@@ -0,0 +1,328 @@
+require 'fiddle/import'
+
+class Reline::Windows
+ def self.encoding
+ Encoding::UTF_8
+ end
+
+ def self.win?
+ true
+ end
+
+ def self.win_legacy_console?
+ @@legacy_console
+ end
+
+ RAW_KEYSTROKE_CONFIG = {
+ [224, 72] => :ed_prev_history, # ↑
+ [224, 80] => :ed_next_history, # ↓
+ [224, 77] => :ed_next_char, # →
+ [224, 75] => :ed_prev_char, # â†
+ [224, 83] => :key_delete, # Del
+ [224, 71] => :ed_move_to_beg, # Home
+ [224, 79] => :ed_move_to_end, # End
+ [ 0, 41] => :ed_unassigned, # input method on/off
+ [ 0, 72] => :ed_prev_history, # ↑
+ [ 0, 80] => :ed_next_history, # ↓
+ [ 0, 77] => :ed_next_char, # →
+ [ 0, 75] => :ed_prev_char, # â†
+ [ 0, 83] => :key_delete, # Del
+ [ 0, 71] => :ed_move_to_beg, # Home
+ [ 0, 79] => :ed_move_to_end # End
+ }
+
+ if defined? JRUBY_VERSION
+ require 'win32api'
+ else
+ class Win32API
+ DLL = {}
+ TYPEMAP = {"0" => Fiddle::TYPE_VOID, "S" => Fiddle::TYPE_VOIDP, "I" => Fiddle::TYPE_LONG}
+ POINTER_TYPE = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
+
+ WIN32_TYPES = "VPpNnLlIi"
+ DL_TYPES = "0SSI"
+
+ def initialize(dllname, func, import, export = "0", calltype = :stdcall)
+ @proto = [import].join.tr(WIN32_TYPES, DL_TYPES).sub(/^(.)0*$/, '\1')
+ import = @proto.chars.map {|win_type| TYPEMAP[win_type.tr(WIN32_TYPES, DL_TYPES)]}
+ export = TYPEMAP[export.tr(WIN32_TYPES, DL_TYPES)]
+ calltype = Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[calltype]
+
+ handle = DLL[dllname] ||=
+ begin
+ Fiddle.dlopen(dllname)
+ rescue Fiddle::DLError
+ raise unless File.extname(dllname).empty?
+ Fiddle.dlopen(dllname + ".dll")
+ end
+
+ @func = Fiddle::Function.new(handle[func], import, export, calltype)
+ rescue Fiddle::DLError => e
+ raise LoadError, e.message, e.backtrace
+ end
+
+ def call(*args)
+ import = @proto.split("")
+ args.each_with_index do |x, i|
+ args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
+ args[i], = [x].pack("I").unpack("i") if import[i] == "I"
+ end
+ ret, = @func.call(*args)
+ return ret || 0
+ end
+ end
+ end
+
+ VK_MENU = 0x12
+ VK_LMENU = 0xA4
+ VK_CONTROL = 0x11
+ VK_SHIFT = 0x10
+ STD_INPUT_HANDLE = -10
+ STD_OUTPUT_HANDLE = -11
+ WINDOW_BUFFER_SIZE_EVENT = 0x04
+ FILE_TYPE_PIPE = 0x0003
+ FILE_NAME_INFO = 2
+ @@getwch = Win32API.new('msvcrt', '_getwch', [], 'I')
+ @@kbhit = Win32API.new('msvcrt', '_kbhit', [], 'I')
+ @@GetKeyState = Win32API.new('user32', 'GetKeyState', ['L'], 'L')
+ @@GetConsoleScreenBufferInfo = Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L')
+ @@SetConsoleCursorPosition = Win32API.new('kernel32', 'SetConsoleCursorPosition', ['L', 'L'], 'L')
+ @@GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
+ @@FillConsoleOutputCharacter = Win32API.new('kernel32', 'FillConsoleOutputCharacter', ['L', 'L', 'L', 'L', 'P'], 'L')
+ @@ScrollConsoleScreenBuffer = Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', ['L', 'P', 'P', 'L', 'P'], 'L')
+ @@hConsoleHandle = @@GetStdHandle.call(STD_OUTPUT_HANDLE)
+ @@hConsoleInputHandle = @@GetStdHandle.call(STD_INPUT_HANDLE)
+ @@GetNumberOfConsoleInputEvents = Win32API.new('kernel32', 'GetNumberOfConsoleInputEvents', ['L', 'P'], 'L')
+ @@ReadConsoleInput = Win32API.new('kernel32', 'ReadConsoleInput', ['L', 'P', 'L', 'P'], 'L')
+ @@GetFileType = Win32API.new('kernel32', 'GetFileType', ['L'], 'L')
+ @@GetFileInformationByHandleEx = Win32API.new('kernel32', 'GetFileInformationByHandleEx', ['L', 'I', 'P', 'L'], 'I')
+ @@FillConsoleOutputAttribute = Win32API.new('kernel32', 'FillConsoleOutputAttribute', ['L', 'L', 'L', 'L', 'P'], 'L')
+
+ @@GetConsoleMode = Win32API.new('kernel32', 'GetConsoleMode', ['L', 'P'], 'L')
+ @@SetConsoleMode = Win32API.new('kernel32', 'SetConsoleMode', ['L', 'L'], 'L')
+ ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
+
+ private_class_method def self.getconsolemode
+ mode = "\000\000\000\000"
+ @@GetConsoleMode.call(@@hConsoleHandle, mode)
+ mode.unpack1('L')
+ end
+
+ private_class_method def self.setconsolemode(mode)
+ @@SetConsoleMode.call(@@hConsoleHandle, mode)
+ end
+
+ @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
+ #if @@legacy_console
+ # setconsolemode(getconsolemode() | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+ # @@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
+ #end
+
+ @@input_buf = []
+ @@output_buf = []
+
+ def self.msys_tty?(io=@@hConsoleInputHandle)
+ # check if fd is a pipe
+ if @@GetFileType.call(io) != FILE_TYPE_PIPE
+ return false
+ end
+
+ bufsize = 1024
+ p_buffer = "\0" * bufsize
+ res = @@GetFileInformationByHandleEx.call(io, FILE_NAME_INFO, p_buffer, bufsize - 2)
+ return false if res == 0
+
+ # get pipe name: p_buffer layout is:
+ # struct _FILE_NAME_INFO {
+ # DWORD FileNameLength;
+ # WCHAR FileName[1];
+ # } FILE_NAME_INFO
+ len = p_buffer[0, 4].unpack("L")[0]
+ name = p_buffer[4, len].encode(Encoding::UTF_8, Encoding::UTF_16LE, invalid: :replace)
+
+ # Check if this could be a MSYS2 pty pipe ('\msys-XXXX-ptyN-XX')
+ # or a cygwin pty pipe ('\cygwin-XXXX-ptyN-XX')
+ name =~ /(msys-|cygwin-).*-pty/ ? true : false
+ end
+
+ def self.getwch
+ unless @@input_buf.empty?
+ return @@input_buf.shift
+ end
+ while @@kbhit.call == 0
+ sleep(0.001)
+ end
+ until @@kbhit.call == 0
+ ret = @@getwch.call
+ if ret == 0 or ret == 0xE0
+ @@input_buf << ret
+ ret = @@getwch.call
+ @@input_buf << ret
+ return @@input_buf.shift
+ end
+ begin
+ bytes = ret.chr(Encoding::UTF_8).bytes
+ @@input_buf.push(*bytes)
+ rescue Encoding::UndefinedConversionError
+ @@input_buf << ret
+ @@input_buf << @@getwch.call if ret == 224
+ end
+ end
+ @@input_buf.shift
+ end
+
+ def self.getc
+ num_of_events = 0.chr * 8
+ while @@GetNumberOfConsoleInputEvents.(@@hConsoleInputHandle, num_of_events) != 0 and num_of_events.unpack('L').first > 0
+ input_record = 0.chr * 18
+ read_event = 0.chr * 4
+ if @@ReadConsoleInput.(@@hConsoleInputHandle, input_record, 1, read_event) != 0
+ event = input_record[0, 2].unpack('s*').first
+ if event == WINDOW_BUFFER_SIZE_EVENT
+ @@winch_handler.()
+ end
+ end
+ end
+ unless @@output_buf.empty?
+ return @@output_buf.shift
+ end
+ input = getwch
+ meta = (@@GetKeyState.call(VK_LMENU) & 0x80) != 0
+ control = (@@GetKeyState.call(VK_CONTROL) & 0x80) != 0
+ shift = (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0
+ force_enter = !input.instance_of?(Array) && (control or shift) && input == 0x0D
+ if force_enter
+ # It's treated as Meta+Enter on Windows
+ @@output_buf.push("\e".ord)
+ @@output_buf.push(input)
+ else
+ case input
+ when 0x00
+ meta = false
+ @@output_buf.push(input)
+ input = getwch
+ @@output_buf.push(*input)
+ when 0xE0
+ @@output_buf.push(input)
+ input = getwch
+ @@output_buf.push(*input)
+ when 0x03
+ @@output_buf.push(input)
+ else
+ @@output_buf.push(input)
+ end
+ end
+ if meta
+ "\e".ord
+ else
+ @@output_buf.shift
+ end
+ end
+
+ def self.ungetc(c)
+ @@output_buf.unshift(c)
+ end
+
+ def self.in_pasting?
+ not self.empty_buffer?
+ end
+
+ def self.empty_buffer?
+ if not @@input_buf.empty?
+ false
+ elsif @@kbhit.call == 0
+ true
+ else
+ false
+ end
+ end
+
+ def self.get_screen_size
+ csbi = 0.chr * 22
+ @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
+ csbi[0, 4].unpack('SS').reverse
+ end
+
+ def self.cursor_pos
+ csbi = 0.chr * 22
+ @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
+ x = csbi[4, 2].unpack('s*').first
+ y = csbi[6, 2].unpack('s*').first
+ Reline::CursorPos.new(x, y)
+ end
+
+ def self.move_cursor_column(val)
+ @@SetConsoleCursorPosition.call(@@hConsoleHandle, cursor_pos.y * 65536 + val)
+ end
+
+ def self.move_cursor_up(val)
+ if val > 0
+ y = cursor_pos.y - val
+ y = 0 if y < 0
+ @@SetConsoleCursorPosition.call(@@hConsoleHandle, y * 65536 + cursor_pos.x)
+ elsif val < 0
+ move_cursor_down(-val)
+ end
+ end
+
+ def self.move_cursor_down(val)
+ if val > 0
+ screen_height = get_screen_size.first
+ y = cursor_pos.y + val
+ y = screen_height - 1 if y > (screen_height - 1)
+ @@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
+ elsif val < 0
+ move_cursor_up(-val)
+ end
+ end
+
+ def self.erase_after_cursor
+ csbi = 0.chr * 24
+ @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
+ cursor = csbi[4, 4].unpack('L').first
+ written = 0.chr * 4
+ @@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, get_screen_size.last - cursor_pos.x, cursor, written)
+ @@FillConsoleOutputAttribute.call(@@hConsoleHandle, 0, get_screen_size.last - cursor_pos.x, cursor, written)
+ end
+
+ def self.scroll_down(val)
+ return if val.zero?
+ screen_height = get_screen_size.first
+ val = screen_height - 1 if val > (screen_height - 1)
+ scroll_rectangle = [0, val, get_screen_size.last, get_screen_size.first].pack('s4')
+ destination_origin = 0 # y * 65536 + x
+ fill = [' '.ord, 0].pack('SS')
+ @@ScrollConsoleScreenBuffer.call(@@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
+ end
+
+ def self.clear_screen
+ csbi = 0.chr * 22
+ return if @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) == 0
+ buffer_width = csbi[0, 2].unpack('S').first
+ attributes = csbi[8, 2].unpack('S').first
+ _window_left, window_top, _window_right, window_bottom = *csbi[10,8].unpack('S*')
+ fill_length = buffer_width * (window_bottom - window_top + 1)
+ screen_topleft = window_top * 65536
+ written = 0.chr * 4
+ @@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, fill_length, screen_topleft, written)
+ @@FillConsoleOutputAttribute.call(@@hConsoleHandle, attributes, fill_length, screen_topleft, written)
+ @@SetConsoleCursorPosition.call(@@hConsoleHandle, screen_topleft)
+ end
+
+ def self.set_screen_size(rows, columns)
+ raise NotImplementedError
+ end
+
+ def self.set_winch_handler(&handler)
+ @@winch_handler = handler
+ end
+
+ def self.prep
+ # do nothing
+ nil
+ end
+
+ def self.deprep(otio)
+ # do nothing
+ end
+end
diff --git a/lib/resolv-replace.gemspec b/lib/resolv-replace.gemspec
new file mode 100644
index 0000000000..0dadb19007
--- /dev/null
+++ b/lib/resolv-replace.gemspec
@@ -0,0 +1,24 @@
+Gem::Specification.new do |spec|
+ spec.name = "resolv-replace"
+ spec.version = "0.1.0"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Replace Socket DNS with Resolv.}
+ spec.description = %q{Replace Socket DNS with Resolv.}
+ spec.homepage = "https://github.com/ruby/resolv-replace"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "resolv"
+end
diff --git a/lib/resolv.gemspec b/lib/resolv.gemspec
new file mode 100644
index 0000000000..c6a0609b51
--- /dev/null
+++ b/lib/resolv.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "resolv"
+ spec.version = "0.2.1"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Thread-aware DNS resolver library in Ruby.}
+ spec.description = %q{Thread-aware DNS resolver library in Ruby.}
+ spec.homepage = "https://github.com/ruby/resolv"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = []
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/resolv.rb b/lib/resolv.rb
index ae9223e751..b69c7045ca 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -166,13 +166,14 @@ class Resolv
# Resolv::Hosts is a hostname resolver that uses the system hosts file.
class Hosts
- begin
- raise LoadError unless /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
- require 'win32/resolv'
- DefaultFileName = Win32::Resolv.get_hosts_path
- rescue LoadError
- DefaultFileName = '/etc/hosts'
+ if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM and
+ begin
+ require 'win32/resolv'
+ DefaultFileName = Win32::Resolv.get_hosts_path || IO::NULL
+ rescue LoadError
+ end
end
+ DefaultFileName ||= '/etc/hosts'
##
# Creates a new Resolv::Hosts, using +filename+ for its data source.
@@ -188,20 +189,17 @@ class Resolv
unless @initialized
@name2addr = {}
@addr2name = {}
- open(@filename, 'rb') {|f|
+ File.open(@filename, 'rb') {|f|
f.each {|line|
line.sub!(/#.*/, '')
addr, hostname, *aliases = line.split(/\s+/)
next unless addr
- addr.untaint
- hostname.untaint
@addr2name[addr] = [] unless @addr2name.include? addr
@addr2name[addr] << hostname
@addr2name[addr] += aliases
@name2addr[hostname] = [] unless @name2addr.include? hostname
@name2addr[hostname] << addr
aliases.each {|n|
- n.untaint
@name2addr[n] = [] unless @name2addr.include? n
@name2addr[n] << addr
}
@@ -236,9 +234,7 @@ class Resolv
def each_address(name, &proc)
lazy_initialize
- if @name2addr.include?(name)
- @name2addr[name].each(&proc)
- end
+ @name2addr[name]&.each(&proc)
end
##
@@ -453,6 +449,8 @@ class Resolv
case address
when Name
ptr = address
+ when IPv4, IPv6
+ ptr = address.to_name
when IPv4::Regex
ptr = IPv4.create(address).to_name
when IPv6::Regex
@@ -513,10 +511,15 @@ class Resolv
def fetch_resource(name, typeclass)
lazy_initialize
- requester = make_udp_requester
+ begin
+ requester = make_udp_requester
+ rescue Errno::EACCES
+ # fall back to TCP
+ end
senders = {}
begin
@config.resolv(name) {|candidate, tout, nameserver, port|
+ requester ||= make_tcp_requester(nameserver, port)
msg = Message.new
msg.rd = 1
msg.add_question(candidate, typeclass)
@@ -549,7 +552,7 @@ class Resolv
end
}
ensure
- requester.close
+ requester&.close
end
end
@@ -611,16 +614,6 @@ class Resolv
end
end
-
- def self.rangerand(range) # :nodoc:
- base = range.begin
- len = range.end - range.begin
- if !range.exclude_end?
- len += 1
- end
- base + random(len)
- end
-
RequestID = {} # :nodoc:
RequestIDMutex = Thread::Mutex.new # :nodoc:
@@ -629,7 +622,7 @@ class Resolv
RequestIDMutex.synchronize {
h = (RequestID[[host, port]] ||= {})
begin
- id = rangerand(0x0000..0xffff)
+ id = random(0x0000..0xffff)
end while h[id]
h[id] = true
}
@@ -650,7 +643,7 @@ class Resolv
def self.bind_random_port(udpsock, bind_host="0.0.0.0") # :nodoc:
begin
- port = rangerand(1024..65535)
+ port = random(1024..65535)
udpsock.bind(bind_host, port)
rescue Errno::EADDRINUSE, # POSIX
Errno::EACCES, # SunOS: See PRIV_SYS_NFS in privileges(5)
@@ -703,13 +696,13 @@ class Resolv
rescue DecodeError
next # broken DNS message ignored
end
- if s = sender_for(from, msg)
+ if sender == sender_for(from, msg)
break
else
# unexpected DNS message ignored
end
end
- return msg, s.data
+ return msg, sender.data
end
def sender_for(addr, msg)
@@ -734,35 +727,48 @@ class Resolv
def initialize(*nameserver_port)
super()
@nameserver_port = nameserver_port
- @socks_hash = {}
- @socks = []
- nameserver_port.each {|host, port|
- if host.index(':')
- bind_host = "::"
- af = Socket::AF_INET6
- else
- bind_host = "0.0.0.0"
- af = Socket::AF_INET
- end
- next if @socks_hash[bind_host]
- begin
- sock = UDPSocket.new(af)
- rescue Errno::EAFNOSUPPORT
- next # The kernel doesn't support the address family.
- end
- sock.do_not_reverse_lookup = true
- DNS.bind_random_port(sock, bind_host)
- @socks << sock
- @socks_hash[bind_host] = sock
+ @initialized = false
+ @mutex = Thread::Mutex.new
+ end
+
+ def lazy_initialize
+ @mutex.synchronize {
+ next if @initialized
+ @initialized = true
+ @socks_hash = {}
+ @socks = []
+ @nameserver_port.each {|host, port|
+ if host.index(':')
+ bind_host = "::"
+ af = Socket::AF_INET6
+ else
+ bind_host = "0.0.0.0"
+ af = Socket::AF_INET
+ end
+ next if @socks_hash[bind_host]
+ begin
+ sock = UDPSocket.new(af)
+ rescue Errno::EAFNOSUPPORT
+ next # The kernel doesn't support the address family.
+ end
+ @socks << sock
+ @socks_hash[bind_host] = sock
+ sock.do_not_reverse_lookup = true
+ DNS.bind_random_port(sock, bind_host)
+ }
}
+ self
end
def recv_reply(readable_socks)
+ lazy_initialize
reply, from = readable_socks[0].recvfrom(UDPSize)
return reply, [from[3],from[1]]
end
def sender(msg, data, host, port=Port)
+ host = Addrinfo.ip(host).ip_address
+ lazy_initialize
sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
return nil if !sock
service = [host, port]
@@ -774,9 +780,14 @@ class Resolv
end
def close
- super
- @senders.each_key {|service, id|
- DNS.free_request_id(service[0], service[1], id)
+ @mutex.synchronize {
+ if @initialized
+ super
+ @senders.each_key {|service, id|
+ DNS.free_request_id(service[0], service[1], id)
+ }
+ @initialized = false
+ end
}
end
@@ -800,20 +811,32 @@ class Resolv
super()
@host = host
@port = port
- is_ipv6 = host.index(':')
- sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
- @socks = [sock]
- sock.do_not_reverse_lookup = true
- DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0")
- sock.connect(host, port)
+ @mutex = Thread::Mutex.new
+ @initialized = false
+ end
+
+ def lazy_initialize
+ @mutex.synchronize {
+ next if @initialized
+ @initialized = true
+ is_ipv6 = @host.index(':')
+ sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
+ @socks = [sock]
+ sock.do_not_reverse_lookup = true
+ DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0")
+ sock.connect(@host, @port)
+ }
+ self
end
def recv_reply(readable_socks)
+ lazy_initialize
reply = readable_socks[0].recv(UDPSize)
return reply, nil
end
def sender(msg, data, host=@host, port=@port)
+ lazy_initialize
unless host == @host && port == @port
raise RequestError.new("host/port don't match: #{host}:#{port}")
end
@@ -824,10 +847,15 @@ class Resolv
end
def close
- super
- @senders.each_key {|from, id|
- DNS.free_request_id(@host, @port, id)
- }
+ @mutex.synchronize do
+ if @initialized
+ super
+ @senders.each_key {|from, id|
+ DNS.free_request_id(@host, @port, id)
+ }
+ @initialized = false
+ end
+ end
end
class Sender < Requester::Sender # :nodoc:
@@ -841,6 +869,7 @@ class Resolv
class MDNSOneShot < UnconnectedUDP # :nodoc:
def sender(msg, data, host, port=Port)
+ lazy_initialize
id = DNS.allocate_request_id(host, port)
request = msg.encode
request[0,2] = [id].pack('n')
@@ -850,6 +879,7 @@ class Resolv
end
def sender_for(addr, msg)
+ lazy_initialize
@senders[msg.id]
end
end
@@ -928,11 +958,10 @@ class Resolv
nameserver = []
search = nil
ndots = 1
- open(filename, 'rb') {|f|
+ File.open(filename, 'rb') {|f|
f.each {|line|
line.sub!(/[#;].*/, '')
keyword, *args = line.split(/\s+/)
- args.each(&:untaint)
next unless keyword
case keyword
when 'nameserver'
@@ -2431,13 +2460,38 @@ class Resolv
\z/x
##
+ # IPv6 link local address format fe80:b:c:d:e:f:g:h%em1
+ Regex_8HexLinkLocal = /\A
+ [Ff][Ee]80
+ (?::[0-9A-Fa-f]{1,4}){7}
+ %[0-9A-Za-z]+
+ \z/x
+
+ ##
+ # Compressed IPv6 link local address format fe80::b%em1
+
+ Regex_CompressedHexLinkLocal = /\A
+ [Ff][Ee]80:
+ (?:
+ ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
+ ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
+ |
+ :((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
+ )?
+ :[0-9A-Fa-f]{1,4}%[0-9A-Za-z.]+
+ \z/x
+
+ ##
# A composite IPv6 address Regexp.
Regex = /
(?:#{Regex_8Hex}) |
(?:#{Regex_CompressedHex}) |
(?:#{Regex_6Hex4Dec}) |
- (?:#{Regex_CompressedHex4Dec})/x
+ (?:#{Regex_CompressedHex4Dec}) |
+ (?:#{Regex_8HexLinkLocal}) |
+ (?:#{Regex_CompressedHexLinkLocal})
+ /x
##
# Creates a new IPv6 address from +arg+ which may be:
@@ -2504,7 +2558,7 @@ class Resolv
attr_reader :address
def to_s # :nodoc:
- address = sprintf("%X:%X:%X:%X:%X:%X:%X:%X", *@address.unpack("nnnnnnnn"))
+ address = sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn"))
unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')
address.sub!(/(^|:)0(:|$)/, '::')
end
@@ -2603,7 +2657,7 @@ class Resolv
def each_address(name)
name = Resolv::DNS::Name.create(name)
- return unless name.to_a.last == 'local'
+ return unless name[-1].to_s == 'local'
super(name)
end
diff --git a/lib/rexml/attlistdecl.rb b/lib/rexml/attlistdecl.rb
deleted file mode 100644
index dc1d2add0b..0000000000
--- a/lib/rexml/attlistdecl.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: false
-#vim:ts=2 sw=2 noexpandtab:
-require 'rexml/child'
-require 'rexml/source'
-
-module REXML
- # This class needs:
- # * Documentation
- # * Work! Not all types of attlists are intelligently parsed, so we just
- # spew back out what we get in. This works, but it would be better if
- # we formatted the output ourselves.
- #
- # AttlistDecls provide *just* enough support to allow namespace
- # declarations. If you need some sort of generalized support, or have an
- # interesting idea about how to map the hideous, terrible design of DTD
- # AttlistDecls onto an intuitive Ruby interface, let me know. I'm desperate
- # for anything to make DTDs more palateable.
- class AttlistDecl < Child
- include Enumerable
-
- # What is this? Got me.
- attr_reader :element_name
-
- # Create an AttlistDecl, pulling the information from a Source. Notice
- # that this isn't very convenient; to create an AttlistDecl, you basically
- # have to format it yourself, and then have the initializer parse it.
- # Sorry, but for the foreseeable future, DTD support in REXML is pretty
- # weak on convenience. Have I mentioned how much I hate DTDs?
- def initialize(source)
- super()
- if (source.kind_of? Array)
- @element_name, @pairs, @contents = *source
- end
- end
-
- # Access the attlist attribute/value pairs.
- # value = attlist_decl[ attribute_name ]
- def [](key)
- @pairs[key]
- end
-
- # Whether an attlist declaration includes the given attribute definition
- # if attlist_decl.include? "xmlns:foobar"
- def include?(key)
- @pairs.keys.include? key
- end
-
- # Iterate over the key/value pairs:
- # attlist_decl.each { |attribute_name, attribute_value| ... }
- def each(&block)
- @pairs.each(&block)
- end
-
- # Write out exactly what we got in.
- def write out, indent=-1
- out << @contents
- end
-
- def node_type
- :attlistdecl
- end
- end
-end
diff --git a/lib/rexml/attribute.rb b/lib/rexml/attribute.rb
deleted file mode 100644
index ca5984e178..0000000000
--- a/lib/rexml/attribute.rb
+++ /dev/null
@@ -1,192 +0,0 @@
-# frozen_string_literal: false
-require "rexml/namespace"
-require 'rexml/text'
-
-module REXML
- # Defines an Element Attribute; IE, a attribute=value pair, as in:
- # <element attribute="value"/>. Attributes can be in their own
- # namespaces. General users of REXML will not interact with the
- # Attribute class much.
- class Attribute
- include Node
- include Namespace
-
- # The element to which this attribute belongs
- attr_reader :element
- # The normalized value of this attribute. That is, the attribute with
- # entities intact.
- attr_writer :normalized
- PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um
-
- NEEDS_A_SECOND_CHECK = /(<|&((#{Entity::NAME});|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));)?)/um
-
- # Constructor.
- # FIXME: The parser doesn't catch illegal characters in attributes
- #
- # first::
- # Either: an Attribute, which this new attribute will become a
- # clone of; or a String, which is the name of this attribute
- # second::
- # If +first+ is an Attribute, then this may be an Element, or nil.
- # If nil, then the Element parent of this attribute is the parent
- # of the +first+ Attribute. If the first argument is a String,
- # then this must also be a String, and is the content of the attribute.
- # If this is the content, it must be fully normalized (contain no
- # illegal characters).
- # parent::
- # Ignored unless +first+ is a String; otherwise, may be the Element
- # parent of this attribute, or nil.
- #
- #
- # Attribute.new( attribute_to_clone )
- # Attribute.new( attribute_to_clone, parent_element )
- # Attribute.new( "attr", "attr_value" )
- # Attribute.new( "attr", "attr_value", parent_element )
- def initialize( first, second=nil, parent=nil )
- @normalized = @unnormalized = @element = nil
- if first.kind_of? Attribute
- self.name = first.expanded_name
- @unnormalized = first.value
- if second.kind_of? Element
- @element = second
- else
- @element = first.element
- end
- elsif first.kind_of? String
- @element = parent
- self.name = first
- @normalized = second.to_s
- else
- raise "illegal argument #{first.class.name} to Attribute constructor"
- end
- end
-
- # Returns the namespace of the attribute.
- #
- # e = Element.new( "elns:myelement" )
- # e.add_attribute( "nsa:a", "aval" )
- # e.add_attribute( "b", "bval" )
- # e.attributes.get_attribute( "a" ).prefix # -> "nsa"
- # e.attributes.get_attribute( "b" ).prefix # -> "elns"
- # a = Attribute.new( "x", "y" )
- # a.prefix # -> ""
- def prefix
- pf = super
- if pf == ""
- pf = @element.prefix if @element
- end
- pf
- end
-
- # Returns the namespace URL, if defined, or nil otherwise
- #
- # e = Element.new("el")
- # e.add_namespace("ns", "http://url")
- # e.add_attribute("ns:a", "b")
- # e.add_attribute("nsx:a", "c")
- # e.attribute("ns:a").namespace # => "http://url"
- # e.attribute("nsx:a").namespace # => nil
- def namespace arg=nil
- arg = prefix if arg.nil?
- @element.namespace arg
- end
-
- # Returns true if other is an Attribute and has the same name and value,
- # false otherwise.
- def ==( other )
- other.kind_of?(Attribute) and other.name==name and other.value==value
- end
-
- # Creates (and returns) a hash from both the name and value
- def hash
- name.hash + value.hash
- end
-
- # Returns this attribute out as XML source, expanding the name
- #
- # a = Attribute.new( "x", "y" )
- # a.to_string # -> "x='y'"
- # b = Attribute.new( "ns:x", "y" )
- # b.to_string # -> "ns:x='y'"
- def to_string
- if @element and @element.context and @element.context[:attribute_quote] == :quote
- %Q^#@expanded_name="#{to_s().gsub(/"/, '&quot;')}"^
- else
- "#@expanded_name='#{to_s().gsub(/'/, '&apos;')}'"
- end
- end
-
- def doctype
- if @element
- doc = @element.document
- doc.doctype if doc
- end
- end
-
- # Returns the attribute value, with entities replaced
- def to_s
- return @normalized if @normalized
-
- @normalized = Text::normalize( @unnormalized, doctype )
- @unnormalized = nil
- @normalized
- end
-
- # Returns the UNNORMALIZED value of this attribute. That is, entities
- # have been expanded to their values
- def value
- return @unnormalized if @unnormalized
- @unnormalized = Text::unnormalize( @normalized, doctype )
- @normalized = nil
- @unnormalized
- end
-
- # Returns a copy of this attribute
- def clone
- Attribute.new self
- end
-
- # Sets the element of which this object is an attribute. Normally, this
- # is not directly called.
- #
- # Returns this attribute
- def element=( element )
- @element = element
-
- if @normalized
- Text.check( @normalized, NEEDS_A_SECOND_CHECK, doctype )
- end
-
- self
- end
-
- # Removes this Attribute from the tree, and returns true if successful
- #
- # This method is usually not called directly.
- def remove
- @element.attributes.delete self.name unless @element.nil?
- end
-
- # Writes this attribute (EG, puts 'key="value"' to the output)
- def write( output, indent=-1 )
- output << to_string
- end
-
- def node_type
- :attribute
- end
-
- def inspect
- rv = ""
- write( rv )
- rv
- end
-
- def xpath
- path = @element.xpath
- path += "/@#{self.expanded_name}"
- return path
- end
- end
-end
-#vim:ts=2 sw=2 noexpandtab:
diff --git a/lib/rexml/cdata.rb b/lib/rexml/cdata.rb
deleted file mode 100644
index fe9b49b5f7..0000000000
--- a/lib/rexml/cdata.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-# frozen_string_literal: false
-require "rexml/text"
-
-module REXML
- class CData < Text
- START = '<![CDATA['
- STOP = ']]>'
- ILLEGAL = /(\]\]>)/
-
- # Constructor. CData is data between <![CDATA[ ... ]]>
- #
- # _Examples_
- # CData.new( source )
- # CData.new( "Here is some CDATA" )
- # CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
- def initialize( first, whitespace=true, parent=nil )
- super( first, whitespace, parent, false, true, ILLEGAL )
- end
-
- # Make a copy of this object
- #
- # _Examples_
- # c = CData.new( "Some text" )
- # d = c.clone
- # d.to_s # -> "Some text"
- def clone
- CData.new self
- end
-
- # Returns the content of this CData object
- #
- # _Examples_
- # c = CData.new( "Some text" )
- # c.to_s # -> "Some text"
- def to_s
- @string
- end
-
- def value
- @string
- end
-
- # == DEPRECATED
- # See the rexml/formatters package
- #
- # Generates XML output of this object
- #
- # output::
- # Where to write the string. Defaults to $stdout
- # indent::
- # The amount to indent this node by
- # transitive::
- # Ignored
- # ie_hack::
- # Ignored
- #
- # _Examples_
- # c = CData.new( " Some text " )
- # c.write( $stdout ) #-> <![CDATA[ Some text ]]>
- def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
- Kernel.warn( "#{self.class.name}.write is deprecated" )
- indent( output, indent )
- output << START
- output << @string
- output << STOP
- end
- end
-end
diff --git a/lib/rexml/child.rb b/lib/rexml/child.rb
deleted file mode 100644
index d23451e71e..0000000000
--- a/lib/rexml/child.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-# frozen_string_literal: false
-require "rexml/node"
-
-module REXML
- ##
- # A Child object is something contained by a parent, and this class
- # contains methods to support that. Most user code will not use this
- # class directly.
- class Child
- include Node
- attr_reader :parent # The Parent of this object
-
- # Constructor. Any inheritors of this class should call super to make
- # sure this method is called.
- # parent::
- # if supplied, the parent of this child will be set to the
- # supplied value, and self will be added to the parent
- def initialize( parent = nil )
- @parent = nil
- # Declare @parent, but don't define it. The next line sets the
- # parent.
- parent.add( self ) if parent
- end
-
- # Replaces this object with another object. Basically, calls
- # Parent.replace_child
- #
- # Returns:: self
- def replace_with( child )
- @parent.replace_child( self, child )
- self
- end
-
- # Removes this child from the parent.
- #
- # Returns:: self
- def remove
- unless @parent.nil?
- @parent.delete self
- end
- self
- end
-
- # Sets the parent of this child to the supplied argument.
- #
- # other::
- # Must be a Parent object. If this object is the same object as the
- # existing parent of this child, no action is taken. Otherwise, this
- # child is removed from the current parent (if one exists), and is added
- # to the new parent.
- # Returns:: The parent added
- def parent=( other )
- return @parent if @parent == other
- @parent.delete self if defined? @parent and @parent
- @parent = other
- end
-
- alias :next_sibling :next_sibling_node
- alias :previous_sibling :previous_sibling_node
-
- # Sets the next sibling of this child. This can be used to insert a child
- # after some other child.
- # a = Element.new("a")
- # b = a.add_element("b")
- # c = Element.new("c")
- # b.next_sibling = c
- # # => <a><b/><c/></a>
- def next_sibling=( other )
- parent.insert_after self, other
- end
-
- # Sets the previous sibling of this child. This can be used to insert a
- # child before some other child.
- # a = Element.new("a")
- # b = a.add_element("b")
- # c = Element.new("c")
- # b.previous_sibling = c
- # # => <a><b/><c/></a>
- def previous_sibling=(other)
- parent.insert_before self, other
- end
-
- # Returns:: the document this child belongs to, or nil if this child
- # belongs to no document
- def document
- return parent.document unless parent.nil?
- nil
- end
-
- # This doesn't yet handle encodings
- def bytes
- document.encoding
-
- to_s
- end
- end
-end
diff --git a/lib/rexml/comment.rb b/lib/rexml/comment.rb
deleted file mode 100644
index 746af77296..0000000000
--- a/lib/rexml/comment.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: false
-require "rexml/child"
-
-module REXML
- ##
- # Represents an XML comment; that is, text between \<!-- ... -->
- class Comment < Child
- include Comparable
- START = "<!--"
- STOP = "-->"
-
- # The content text
-
- attr_accessor :string
-
- ##
- # Constructor. The first argument can be one of three types:
- # @param first If String, the contents of this comment are set to the
- # argument. If Comment, the argument is duplicated. If
- # Source, the argument is scanned for a comment.
- # @param second If the first argument is a Source, this argument
- # should be nil, not supplied, or a Parent to be set as the parent
- # of this object
- def initialize( first, second = nil )
- super(second)
- if first.kind_of? String
- @string = first
- elsif first.kind_of? Comment
- @string = first.string
- end
- end
-
- def clone
- Comment.new self
- end
-
- # == DEPRECATED
- # See REXML::Formatters
- #
- # output::
- # Where to write the string
- # indent::
- # An integer. If -1, no indenting will be used; otherwise, the
- # indentation will be this number of spaces, and children will be
- # indented an additional amount.
- # transitive::
- # Ignored by this class. The contents of comments are never modified.
- # ie_hack::
- # Needed for conformity to the child API, but not used by this class.
- def write( output, indent=-1, transitive=false, ie_hack=false )
- Kernel.warn("Comment.write is deprecated. See REXML::Formatters")
- indent( output, indent )
- output << START
- output << @string
- output << STOP
- end
-
- alias :to_s :string
-
- ##
- # Compares this Comment to another; the contents of the comment are used
- # in the comparison.
- def <=>(other)
- other.to_s <=> @string
- end
-
- ##
- # Compares this Comment to another; the contents of the comment are used
- # in the comparison.
- def ==( other )
- other.kind_of? Comment and
- (other <=> self) == 0
- end
-
- def node_type
- :comment
- end
- end
-end
-#vim:ts=2 sw=2 noexpandtab:
diff --git a/lib/rexml/doctype.rb b/lib/rexml/doctype.rb
deleted file mode 100644
index 1eb1f5b4e1..0000000000
--- a/lib/rexml/doctype.rb
+++ /dev/null
@@ -1,270 +0,0 @@
-# frozen_string_literal: false
-require "rexml/parent"
-require "rexml/parseexception"
-require "rexml/namespace"
-require 'rexml/entity'
-require 'rexml/attlistdecl'
-require 'rexml/xmltokens'
-
-module REXML
- # Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE
- # ... >. DOCTYPES can be used to declare the DTD of a document, as well as
- # being used to declare entities used in the document.
- class DocType < Parent
- include XMLTokens
- START = "<!DOCTYPE"
- STOP = ">"
- SYSTEM = "SYSTEM"
- PUBLIC = "PUBLIC"
- DEFAULT_ENTITIES = {
- 'gt'=>EntityConst::GT,
- 'lt'=>EntityConst::LT,
- 'quot'=>EntityConst::QUOT,
- "apos"=>EntityConst::APOS
- }
-
- # name is the name of the doctype
- # external_id is the referenced DTD, if given
- attr_reader :name, :external_id, :entities, :namespaces
-
- # Constructor
- #
- # dt = DocType.new( 'foo', '-//I/Hate/External/IDs' )
- # # <!DOCTYPE foo '-//I/Hate/External/IDs'>
- # dt = DocType.new( doctype_to_clone )
- # # Incomplete. Shallow clone of doctype
- #
- # +Note+ that the constructor:
- #
- # Doctype.new( Source.new( "<!DOCTYPE foo 'bar'>" ) )
- #
- # is _deprecated_. Do not use it. It will probably disappear.
- def initialize( first, parent=nil )
- @entities = DEFAULT_ENTITIES
- @long_name = @uri = nil
- if first.kind_of? String
- super()
- @name = first
- @external_id = parent
- elsif first.kind_of? DocType
- super( parent )
- @name = first.name
- @external_id = first.external_id
- elsif first.kind_of? Array
- super( parent )
- @name = first[0]
- @external_id = first[1]
- @long_name = first[2]
- @uri = first[3]
- elsif first.kind_of? Source
- super( parent )
- parser = Parsers::BaseParser.new( first )
- event = parser.pull
- if event[0] == :start_doctype
- @name, @external_id, @long_name, @uri, = event[1..-1]
- end
- else
- super()
- end
- end
-
- def node_type
- :doctype
- end
-
- def attributes_of element
- rv = []
- each do |child|
- child.each do |key,val|
- rv << Attribute.new(key,val)
- end if child.kind_of? AttlistDecl and child.element_name == element
- end
- rv
- end
-
- def attribute_of element, attribute
- att_decl = find do |child|
- child.kind_of? AttlistDecl and
- child.element_name == element and
- child.include? attribute
- end
- return nil unless att_decl
- att_decl[attribute]
- end
-
- def clone
- DocType.new self
- end
-
- # output::
- # Where to write the string
- # indent::
- # An integer. If -1, no indentation will be used; otherwise, the
- # indentation will be this number of spaces, and children will be
- # indented an additional amount.
- # transitive::
- # Ignored
- # ie_hack::
- # Ignored
- def write( output, indent=0, transitive=false, ie_hack=false )
- f = REXML::Formatters::Default.new
- indent( output, indent )
- output << START
- output << ' '
- output << @name
- output << " #@external_id" if @external_id
- output << " #{@long_name.inspect}" if @long_name
- output << " #{@uri.inspect}" if @uri
- unless @children.empty?
- output << ' ['
- @children.each { |child|
- output << "\n"
- f.write( child, output )
- }
- output << "\n]"
- end
- output << STOP
- end
-
- def context
- @parent.context
- end
-
- def entity( name )
- @entities[name].unnormalized if @entities[name]
- end
-
- def add child
- super(child)
- @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES
- @entities[ child.name ] = child if child.kind_of? Entity
- end
-
- # This method retrieves the public identifier identifying the document's
- # DTD.
- #
- # Method contributed by Henrik Martensson
- def public
- case @external_id
- when "SYSTEM"
- nil
- when "PUBLIC"
- strip_quotes(@long_name)
- end
- end
-
- # This method retrieves the system identifier identifying the document's DTD
- #
- # Method contributed by Henrik Martensson
- def system
- case @external_id
- when "SYSTEM"
- strip_quotes(@long_name)
- when "PUBLIC"
- @uri.kind_of?(String) ? strip_quotes(@uri) : nil
- end
- end
-
- # This method returns a list of notations that have been declared in the
- # _internal_ DTD subset. Notations in the external DTD subset are not
- # listed.
- #
- # Method contributed by Henrik Martensson
- def notations
- children().select {|node| node.kind_of?(REXML::NotationDecl)}
- end
-
- # Retrieves a named notation. Only notations declared in the internal
- # DTD subset can be retrieved.
- #
- # Method contributed by Henrik Martensson
- def notation(name)
- notations.find { |notation_decl|
- notation_decl.name == name
- }
- end
-
- private
-
- # Method contributed by Henrik Martensson
- def strip_quotes(quoted_string)
- quoted_string =~ /^[\'\"].*[\'\"]$/ ?
- quoted_string[1, quoted_string.length-2] :
- quoted_string
- end
- end
-
- # We don't really handle any of these since we're not a validating
- # parser, so we can be pretty dumb about them. All we need to be able
- # to do is spew them back out on a write()
-
- # This is an abstract class. You never use this directly; it serves as a
- # parent class for the specific declarations.
- class Declaration < Child
- def initialize src
- super()
- @string = src
- end
-
- def to_s
- @string+'>'
- end
-
- # == DEPRECATED
- # See REXML::Formatters
- #
- def write( output, indent )
- output << to_s
- end
- end
-
- public
- class ElementDecl < Declaration
- def initialize( src )
- super
- end
- end
-
- class ExternalEntity < Child
- def initialize( src )
- super()
- @entity = src
- end
- def to_s
- @entity
- end
- def write( output, indent )
- output << @entity
- end
- end
-
- class NotationDecl < Child
- attr_accessor :public, :system
- def initialize name, middle, pub, sys
- super(nil)
- @name = name
- @middle = middle
- @public = pub
- @system = sys
- end
-
- def to_s
- notation = "<!NOTATION #{@name} #{@middle}"
- notation << " #{@public.inspect}" if @public
- notation << " #{@system.inspect}" if @system
- notation << ">"
- notation
- end
-
- def write( output, indent=-1 )
- output << to_s
- end
-
- # This method retrieves the name of the notation.
- #
- # Method contributed by Henrik Martensson
- def name
- @name
- end
- end
-end
diff --git a/lib/rexml/document.rb b/lib/rexml/document.rb
deleted file mode 100644
index 806bc499cd..0000000000
--- a/lib/rexml/document.rb
+++ /dev/null
@@ -1,291 +0,0 @@
-# frozen_string_literal: false
-require "rexml/security"
-require "rexml/element"
-require "rexml/xmldecl"
-require "rexml/source"
-require "rexml/comment"
-require "rexml/doctype"
-require "rexml/instruction"
-require "rexml/rexml"
-require "rexml/parseexception"
-require "rexml/output"
-require "rexml/parsers/baseparser"
-require "rexml/parsers/streamparser"
-require "rexml/parsers/treeparser"
-
-module REXML
- # Represents a full XML document, including PIs, a doctype, etc. A
- # Document has a single child that can be accessed by root().
- # Note that if you want to have an XML declaration written for a document
- # you create, you must add one; REXML documents do not write a default
- # declaration for you. See |DECLARATION| and |write|.
- class Document < Element
- # A convenient default XML declaration. If you want an XML declaration,
- # the easiest way to add one is mydoc << Document::DECLARATION
- # +DEPRECATED+
- # Use: mydoc << XMLDecl.default
- DECLARATION = XMLDecl.default
-
- # Constructor
- # @param source if supplied, must be a Document, String, or IO.
- # Documents have their context and Element attributes cloned.
- # Strings are expected to be valid XML documents. IOs are expected
- # to be sources of valid XML documents.
- # @param context if supplied, contains the context of the document;
- # this should be a Hash.
- def initialize( source = nil, context = {} )
- @entity_expansion_count = 0
- super()
- @context = context
- return if source.nil?
- if source.kind_of? Document
- @context = source.context
- super source
- else
- build( source )
- end
- end
-
- def node_type
- :document
- end
-
- # Should be obvious
- def clone
- Document.new self
- end
-
- # According to the XML spec, a root node has no expanded name
- def expanded_name
- ''
- #d = doc_type
- #d ? d.name : "UNDEFINED"
- end
-
- alias :name :expanded_name
-
- # We override this, because XMLDecls and DocTypes must go at the start
- # of the document
- def add( child )
- if child.kind_of? XMLDecl
- if @children[0].kind_of? XMLDecl
- @children[0] = child
- else
- @children.unshift child
- end
- child.parent = self
- elsif child.kind_of? DocType
- # Find first Element or DocType node and insert the decl right
- # before it. If there is no such node, just insert the child at the
- # end. If there is a child and it is an DocType, then replace it.
- insert_before_index = @children.find_index { |x|
- x.kind_of?(Element) || x.kind_of?(DocType)
- }
- if insert_before_index # Not null = not end of list
- if @children[ insert_before_index ].kind_of? DocType
- @children[ insert_before_index ] = child
- else
- @children[ insert_before_index-1, 0 ] = child
- end
- else # Insert at end of list
- @children << child
- end
- child.parent = self
- else
- rv = super
- raise "attempted adding second root element to document" if @elements.size > 1
- rv
- end
- end
- alias :<< :add
-
- def add_element(arg=nil, arg2=nil)
- rv = super
- raise "attempted adding second root element to document" if @elements.size > 1
- rv
- end
-
- # @return the root Element of the document, or nil if this document
- # has no children.
- def root
- elements[1]
- #self
- #@children.find { |item| item.kind_of? Element }
- end
-
- # @return the DocType child of the document, if one exists,
- # and nil otherwise.
- def doctype
- @children.find { |item| item.kind_of? DocType }
- end
-
- # @return the XMLDecl of this document; if no XMLDecl has been
- # set, the default declaration is returned.
- def xml_decl
- rv = @children[0]
- return rv if rv.kind_of? XMLDecl
- @children.unshift(XMLDecl.default)[0]
- end
-
- # @return the XMLDecl version of this document as a String.
- # If no XMLDecl has been set, returns the default version.
- def version
- xml_decl().version
- end
-
- # @return the XMLDecl encoding of this document as an
- # Encoding object.
- # If no XMLDecl has been set, returns the default encoding.
- def encoding
- xml_decl().encoding
- end
-
- # @return the XMLDecl standalone value of this document as a String.
- # If no XMLDecl has been set, returns the default setting.
- def stand_alone?
- xml_decl().stand_alone?
- end
-
- # :call-seq:
- # doc.write(output=$stdout, indent=-1, transtive=false, ie_hack=false, encoding=nil)
- # doc.write(options={:output => $stdout, :indent => -1, :transtive => false, :ie_hack => false, :encoding => nil})
- #
- # Write the XML tree out, optionally with indent. This writes out the
- # entire XML document, including XML declarations, doctype declarations,
- # and processing instructions (if any are given).
- #
- # A controversial point is whether Document should always write the XML
- # declaration (<?xml version='1.0'?>) whether or not one is given by the
- # user (or source document). REXML does not write one if one was not
- # specified, because it adds unnecessary bandwidth to applications such
- # as XML-RPC.
- #
- # Accept Nth argument style and options Hash style as argument.
- # The recommended style is options Hash style for one or more
- # arguments case.
- #
- # _Examples_
- # Document.new("<a><b/></a>").write
- #
- # output = ""
- # Document.new("<a><b/></a>").write(output)
- #
- # output = ""
- # Document.new("<a><b/></a>").write(:output => output, :indent => 2)
- #
- # See also the classes in the rexml/formatters package for the proper way
- # to change the default formatting of XML output.
- #
- # _Examples_
- #
- # output = ""
- # tr = Transitive.new
- # tr.write(Document.new("<a><b/></a>"), output)
- #
- # output::
- # output an object which supports '<< string'; this is where the
- # document will be written.
- # indent::
- # An integer. If -1, no indenting will be used; otherwise, the
- # indentation will be twice this number of spaces, and children will be
- # indented an additional amount. For a value of 3, every item will be
- # indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1
- # transitive::
- # If transitive is true and indent is >= 0, then the output will be
- # pretty-printed in such a way that the added whitespace does not affect
- # the absolute *value* of the document -- that is, it leaves the value
- # and number of Text nodes in the document unchanged.
- # ie_hack::
- # This hack inserts a space before the /> on empty tags to address
- # a limitation of Internet Explorer. Defaults to false
- # encoding::
- # Encoding name as String. Change output encoding to specified encoding
- # instead of encoding in XML declaration.
- # Defaults to nil. It means encoding in XML declaration is used.
- def write(*arguments)
- if arguments.size == 1 and arguments[0].class == Hash
- options = arguments[0]
-
- output = options[:output]
- indent = options[:indent]
- transitive = options[:transitive]
- ie_hack = options[:ie_hack]
- encoding = options[:encoding]
- else
- output, indent, transitive, ie_hack, encoding, = *arguments
- end
-
- output ||= $stdout
- indent ||= -1
- transitive = false if transitive.nil?
- ie_hack = false if ie_hack.nil?
- encoding ||= xml_decl.encoding
-
- if encoding != 'UTF-8' && !output.kind_of?(Output)
- output = Output.new( output, encoding )
- end
- formatter = if indent > -1
- if transitive
- require "rexml/formatters/transitive"
- REXML::Formatters::Transitive.new( indent, ie_hack )
- else
- REXML::Formatters::Pretty.new( indent, ie_hack )
- end
- else
- REXML::Formatters::Default.new( ie_hack )
- end
- formatter.write( self, output )
- end
-
-
- def Document::parse_stream( source, listener )
- Parsers::StreamParser.new( source, listener ).parse
- end
-
- # Set the entity expansion limit. By default the limit is set to 10000.
- #
- # Deprecated. Use REXML::Security.entity_expansion_limit= instead.
- def Document::entity_expansion_limit=( val )
- Security.entity_expansion_limit = val
- end
-
- # Get the entity expansion limit. By default the limit is set to 10000.
- #
- # Deprecated. Use REXML::Security.entity_expansion_limit= instead.
- def Document::entity_expansion_limit
- return Security.entity_expansion_limit
- end
-
- # Set the entity expansion limit. By default the limit is set to 10240.
- #
- # Deprecated. Use REXML::Security.entity_expansion_text_limit= instead.
- def Document::entity_expansion_text_limit=( val )
- Security.entity_expansion_text_limit = val
- end
-
- # Get the entity expansion limit. By default the limit is set to 10240.
- #
- # Deprecated. Use REXML::Security.entity_expansion_text_limit instead.
- def Document::entity_expansion_text_limit
- return Security.entity_expansion_text_limit
- end
-
- attr_reader :entity_expansion_count
-
- def record_entity_expansion
- @entity_expansion_count += 1
- if @entity_expansion_count > Security.entity_expansion_limit
- raise "number of entity expansions exceeded, processing aborted."
- end
- end
-
- def document
- self
- end
-
- private
- def build( source )
- Parsers::TreeParser.new( source, self ).parse
- end
- end
-end
diff --git a/lib/rexml/dtd/attlistdecl.rb b/lib/rexml/dtd/attlistdecl.rb
deleted file mode 100644
index 32847daadb..0000000000
--- a/lib/rexml/dtd/attlistdecl.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: false
-require "rexml/child"
-module REXML
- module DTD
- class AttlistDecl < Child
- START = "<!ATTLIST"
- START_RE = /^\s*#{START}/um
- PATTERN_RE = /\s*(#{START}.*?>)/um
- end
- end
-end
diff --git a/lib/rexml/dtd/dtd.rb b/lib/rexml/dtd/dtd.rb
deleted file mode 100644
index 927d5d847b..0000000000
--- a/lib/rexml/dtd/dtd.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: false
-require "rexml/dtd/elementdecl"
-require "rexml/dtd/entitydecl"
-require "rexml/comment"
-require "rexml/dtd/notationdecl"
-require "rexml/dtd/attlistdecl"
-require "rexml/parent"
-
-module REXML
- module DTD
- class Parser
- def Parser.parse( input )
- case input
- when String
- parse_helper input
- when File
- parse_helper input.read
- end
- end
-
- # Takes a String and parses it out
- def Parser.parse_helper( input )
- contents = Parent.new
- while input.size > 0
- case input
- when ElementDecl.PATTERN_RE
- match = $&
- contents << ElementDecl.new( match )
- when AttlistDecl.PATTERN_RE
- matchdata = $~
- contents << AttlistDecl.new( matchdata )
- when EntityDecl.PATTERN_RE
- matchdata = $~
- contents << EntityDecl.new( matchdata )
- when Comment.PATTERN_RE
- matchdata = $~
- contents << Comment.new( matchdata )
- when NotationDecl.PATTERN_RE
- matchdata = $~
- contents << NotationDecl.new( matchdata )
- end
- end
- contents
- end
- end
- end
-end
diff --git a/lib/rexml/dtd/elementdecl.rb b/lib/rexml/dtd/elementdecl.rb
deleted file mode 100644
index 119fd41a8f..0000000000
--- a/lib/rexml/dtd/elementdecl.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: false
-require "rexml/child"
-module REXML
- module DTD
- class ElementDecl < Child
- START = "<!ELEMENT"
- START_RE = /^\s*#{START}/um
- # PATTERN_RE = /^\s*(#{START}.*?)>/um
- PATTERN_RE = /^\s*#{START}\s+((?:[:\w][-\.\w]*:)?[-!\*\.\w]*)(.*?)>/
- #\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true)
-
- def initialize match
- @name = match[1]
- @rest = match[2]
- end
- end
- end
-end
diff --git a/lib/rexml/dtd/entitydecl.rb b/lib/rexml/dtd/entitydecl.rb
deleted file mode 100644
index 45707e2f42..0000000000
--- a/lib/rexml/dtd/entitydecl.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: false
-require "rexml/child"
-module REXML
- module DTD
- class EntityDecl < Child
- START = "<!ENTITY"
- START_RE = /^\s*#{START}/um
- PUBLIC = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+PUBLIC\s+((["']).*?\3)\s+((["']).*?\5)\s*>/um
- SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um
- PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um
- PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um
- # <!ENTITY name SYSTEM "...">
- # <!ENTITY name "...">
- def initialize src
- super()
- md = nil
- if src.match( PUBLIC )
- md = src.match( PUBLIC, true )
- @middle = "PUBLIC"
- @content = "#{md[2]} #{md[4]}"
- elsif src.match( SYSTEM )
- md = src.match( SYSTEM, true )
- @middle = "SYSTEM"
- @content = md[2]
- elsif src.match( PLAIN )
- md = src.match( PLAIN, true )
- @middle = ""
- @content = md[2]
- elsif src.match( PERCENT )
- md = src.match( PERCENT, true )
- @middle = ""
- @content = md[2]
- end
- raise ParseException.new("failed Entity match", src) if md.nil?
- @name = md[1]
- end
-
- def to_s
- rv = "<!ENTITY #@name "
- rv << "#@middle " if @middle.size > 0
- rv << @content
- rv
- end
-
- def write( output, indent )
- indent( output, indent )
- output << to_s
- end
-
- def EntityDecl.parse_source source, listener
- md = source.match( PATTERN_RE, true )
- thing = md[0].squeeze(" \t\n\r")
- listener.send inspect.downcase, thing
- end
- end
- end
-end
diff --git a/lib/rexml/dtd/notationdecl.rb b/lib/rexml/dtd/notationdecl.rb
deleted file mode 100644
index cfdf0b9b74..0000000000
--- a/lib/rexml/dtd/notationdecl.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: false
-require "rexml/child"
-module REXML
- module DTD
- class NotationDecl < Child
- START = "<!NOTATION"
- START_RE = /^\s*#{START}/um
- PUBLIC = /^\s*#{START}\s+(\w[\w-]*)\s+(PUBLIC)\s+((["']).*?\4)\s*>/um
- SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um
- def initialize src
- super()
- if src.match( PUBLIC )
- md = src.match( PUBLIC, true )
- elsif src.match( SYSTEM )
- md = src.match( SYSTEM, true )
- else
- raise ParseException.new( "error parsing notation: no matching pattern", src )
- end
- @name = md[1]
- @middle = md[2]
- @rest = md[3]
- end
-
- def to_s
- "<!NOTATION #@name #@middle #@rest>"
- end
-
- def write( output, indent )
- indent( output, indent )
- output << to_s
- end
-
- def NotationDecl.parse_source source, listener
- md = source.match( PATTERN_RE, true )
- thing = md[0].squeeze(" \t\n\r")
- listener.send inspect.downcase, thing
- end
- end
- end
-end
diff --git a/lib/rexml/element.rb b/lib/rexml/element.rb
deleted file mode 100644
index a9811bcba3..0000000000
--- a/lib/rexml/element.rb
+++ /dev/null
@@ -1,1265 +0,0 @@
-# frozen_string_literal: false
-require "rexml/parent"
-require "rexml/namespace"
-require "rexml/attribute"
-require "rexml/cdata"
-require "rexml/xpath"
-require "rexml/parseexception"
-
-module REXML
- # An implementation note about namespaces:
- # As we parse, when we find namespaces we put them in a hash and assign
- # them a unique ID. We then convert the namespace prefix for the node
- # to the unique ID. This makes namespace lookup much faster for the
- # cost of extra memory use. We save the namespace prefix for the
- # context node and convert it back when we write it.
- @@namespaces = {}
-
- # Represents a tagged XML element. Elements are characterized by
- # having children, attributes, and names, and can themselves be
- # children.
- class Element < Parent
- include Namespace
-
- UNDEFINED = "UNDEFINED"; # The default name
-
- # Mechanisms for accessing attributes and child elements of this
- # element.
- attr_reader :attributes, :elements
- # The context holds information about the processing environment, such as
- # whitespace handling.
- attr_accessor :context
-
- # Constructor
- # arg::
- # if not supplied, will be set to the default value.
- # If a String, the name of this object will be set to the argument.
- # If an Element, the object will be shallowly cloned; name,
- # attributes, and namespaces will be copied. Children will +not+ be
- # copied.
- # parent::
- # if supplied, must be a Parent, and will be used as
- # the parent of this object.
- # context::
- # If supplied, must be a hash containing context items. Context items
- # include:
- # * <tt>:respect_whitespace</tt> the value of this is :+all+ or an array of
- # strings being the names of the elements to respect
- # whitespace for. Defaults to :+all+.
- # * <tt>:compress_whitespace</tt> the value can be :+all+ or an array of
- # strings being the names of the elements to ignore whitespace on.
- # Overrides :+respect_whitespace+.
- # * <tt>:ignore_whitespace_nodes</tt> the value can be :+all+ or an array
- # of strings being the names of the elements in which to ignore
- # whitespace-only nodes. If this is set, Text nodes which contain only
- # whitespace will not be added to the document tree.
- # * <tt>:raw</tt> can be :+all+, or an array of strings being the names of
- # the elements to process in raw mode. In raw mode, special
- # characters in text is not converted to or from entities.
- def initialize( arg = UNDEFINED, parent=nil, context=nil )
- super(parent)
-
- @elements = Elements.new(self)
- @attributes = Attributes.new(self)
- @context = context
-
- if arg.kind_of? String
- self.name = arg
- elsif arg.kind_of? Element
- self.name = arg.expanded_name
- arg.attributes.each_attribute{ |attribute|
- @attributes << Attribute.new( attribute )
- }
- @context = arg.context
- end
- end
-
- def inspect
- rv = "<#@expanded_name"
-
- @attributes.each_attribute do |attr|
- rv << " "
- attr.write( rv, 0 )
- end
-
- if children.size > 0
- rv << "> ... </>"
- else
- rv << "/>"
- end
- end
-
-
- # Creates a shallow copy of self.
- # d = Document.new "<a><b/><b/><c><d/></c></a>"
- # new_a = d.root.clone
- # puts new_a # => "<a/>"
- def clone
- self.class.new self
- end
-
- # Evaluates to the root node of the document that this element
- # belongs to. If this element doesn't belong to a document, but does
- # belong to another Element, the parent's root will be returned, until the
- # earliest ancestor is found.
- #
- # Note that this is not the same as the document element.
- # In the following example, <a> is the document element, and the root
- # node is the parent node of the document element. You may ask yourself
- # why the root node is useful: consider the doctype and XML declaration,
- # and any processing instructions before the document element... they
- # are children of the root node, or siblings of the document element.
- # The only time this isn't true is when an Element is created that is
- # not part of any Document. In this case, the ancestor that has no
- # parent acts as the root node.
- # d = Document.new '<a><b><c/></b></a>'
- # a = d[1] ; c = a[1][1]
- # d.root_node == d # TRUE
- # a.root_node # namely, d
- # c.root_node # again, d
- def root_node
- parent.nil? ? self : parent.root_node
- end
-
- def root
- return elements[1] if self.kind_of? Document
- return self if parent.kind_of? Document or parent.nil?
- return parent.root
- end
-
- # Evaluates to the document to which this element belongs, or nil if this
- # element doesn't belong to a document.
- def document
- rt = root
- rt.parent if rt
- end
-
- # Evaluates to +true+ if whitespace is respected for this element. This
- # is the case if:
- # 1. Neither :+respect_whitespace+ nor :+compress_whitespace+ has any value
- # 2. The context has :+respect_whitespace+ set to :+all+ or
- # an array containing the name of this element, and
- # :+compress_whitespace+ isn't set to :+all+ or an array containing the
- # name of this element.
- # The evaluation is tested against +expanded_name+, and so is namespace
- # sensitive.
- def whitespace
- @whitespace = nil
- if @context
- if @context[:respect_whitespace]
- @whitespace = (@context[:respect_whitespace] == :all or
- @context[:respect_whitespace].include? expanded_name)
- end
- @whitespace = false if (@context[:compress_whitespace] and
- (@context[:compress_whitespace] == :all or
- @context[:compress_whitespace].include? expanded_name)
- )
- end
- @whitespace = true unless @whitespace == false
- @whitespace
- end
-
- def ignore_whitespace_nodes
- @ignore_whitespace_nodes = false
- if @context
- if @context[:ignore_whitespace_nodes]
- @ignore_whitespace_nodes =
- (@context[:ignore_whitespace_nodes] == :all or
- @context[:ignore_whitespace_nodes].include? expanded_name)
- end
- end
- end
-
- # Evaluates to +true+ if raw mode is set for this element. This
- # is the case if the context has :+raw+ set to :+all+ or
- # an array containing the name of this element.
- #
- # The evaluation is tested against +expanded_name+, and so is namespace
- # sensitive.
- def raw
- @raw = (@context and @context[:raw] and
- (@context[:raw] == :all or
- @context[:raw].include? expanded_name))
- @raw
- end
-
- #once :whitespace, :raw, :ignore_whitespace_nodes
-
- #################################################
- # Namespaces #
- #################################################
-
- # Evaluates to an +Array+ containing the prefixes (names) of all defined
- # namespaces at this context node.
- # doc = Document.new("<a xmlns:x='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
- # doc.elements['//b'].prefixes # -> ['x', 'y']
- def prefixes
- prefixes = []
- prefixes = parent.prefixes if parent
- prefixes |= attributes.prefixes
- return prefixes
- end
-
- def namespaces
- namespaces = {}
- namespaces = parent.namespaces if parent
- namespaces = namespaces.merge( attributes.namespaces )
- return namespaces
- end
-
- # Evaluates to the URI for a prefix, or the empty string if no such
- # namespace is declared for this element. Evaluates recursively for
- # ancestors. Returns the default namespace, if there is one.
- # prefix::
- # the prefix to search for. If not supplied, returns the default
- # namespace if one exists
- # Returns::
- # the namespace URI as a String, or nil if no such namespace
- # exists. If the namespace is undefined, returns an empty string
- # doc = Document.new("<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
- # b = doc.elements['//b']
- # b.namespace # -> '1'
- # b.namespace("y") # -> '2'
- def namespace(prefix=nil)
- if prefix.nil?
- prefix = prefix()
- end
- if prefix == ''
- prefix = "xmlns"
- else
- prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns'
- end
- ns = attributes[ prefix ]
- ns = parent.namespace(prefix) if ns.nil? and parent
- ns = '' if ns.nil? and prefix == 'xmlns'
- return ns
- end
-
- # Adds a namespace to this element.
- # prefix::
- # the prefix string, or the namespace URI if +uri+ is not
- # supplied
- # uri::
- # the namespace URI. May be nil, in which +prefix+ is used as
- # the URI
- # Evaluates to: this Element
- # a = Element.new("a")
- # a.add_namespace("xmlns:foo", "bar" )
- # a.add_namespace("foo", "bar") # shorthand for previous line
- # a.add_namespace("twiddle")
- # puts a #-> <a xmlns:foo='bar' xmlns='twiddle'/>
- def add_namespace( prefix, uri=nil )
- unless uri
- @attributes["xmlns"] = prefix
- else
- prefix = "xmlns:#{prefix}" unless prefix =~ /^xmlns:/
- @attributes[ prefix ] = uri
- end
- self
- end
-
- # Removes a namespace from this node. This only works if the namespace is
- # actually declared in this node. If no argument is passed, deletes the
- # default namespace.
- #
- # Evaluates to: this element
- # doc = Document.new "<a xmlns:foo='bar' xmlns='twiddle'/>"
- # doc.root.delete_namespace
- # puts doc # -> <a xmlns:foo='bar'/>
- # doc.root.delete_namespace 'foo'
- # puts doc # -> <a/>
- def delete_namespace namespace="xmlns"
- namespace = "xmlns:#{namespace}" unless namespace == 'xmlns'
- attribute = attributes.get_attribute(namespace)
- attribute.remove unless attribute.nil?
- self
- end
-
- #################################################
- # Elements #
- #################################################
-
- # Adds a child to this element, optionally setting attributes in
- # the element.
- # element::
- # optional. If Element, the element is added.
- # Otherwise, a new Element is constructed with the argument (see
- # Element.initialize).
- # attrs::
- # If supplied, must be a Hash containing String name,value
- # pairs, which will be used to set the attributes of the new Element.
- # Returns:: the Element that was added
- # el = doc.add_element 'my-tag'
- # el = doc.add_element 'my-tag', {'attr1'=>'val1', 'attr2'=>'val2'}
- # el = Element.new 'my-tag'
- # doc.add_element el
- def add_element element, attrs=nil
- raise "First argument must be either an element name, or an Element object" if element.nil?
- el = @elements.add(element)
- attrs.each do |key, value|
- el.attributes[key]=value
- end if attrs.kind_of? Hash
- el
- end
-
- # Deletes a child element.
- # element::
- # Must be an +Element+, +String+, or +Integer+. If Element,
- # the element is removed. If String, the element is found (via XPath)
- # and removed. <em>This means that any parent can remove any
- # descendant.<em> If Integer, the Element indexed by that number will be
- # removed.
- # Returns:: the element that was removed.
- # doc.delete_element "/a/b/c[@id='4']"
- # doc.delete_element doc.elements["//k"]
- # doc.delete_element 1
- def delete_element element
- @elements.delete element
- end
-
- # Evaluates to +true+ if this element has at least one child Element
- # doc = Document.new "<a><b/><c>Text</c></a>"
- # doc.root.has_elements # -> true
- # doc.elements["/a/b"].has_elements # -> false
- # doc.elements["/a/c"].has_elements # -> false
- def has_elements?
- !@elements.empty?
- end
-
- # Iterates through the child elements, yielding for each Element that
- # has a particular attribute set.
- # key::
- # the name of the attribute to search for
- # value::
- # the value of the attribute
- # max::
- # (optional) causes this method to return after yielding
- # for this number of matching children
- # name::
- # (optional) if supplied, this is an XPath that filters
- # the children to check.
- #
- # doc = Document.new "<a><b @id='1'/><c @id='2'/><d @id='1'/><e/></a>"
- # # Yields b, c, d
- # doc.root.each_element_with_attribute( 'id' ) {|e| p e}
- # # Yields b, d
- # doc.root.each_element_with_attribute( 'id', '1' ) {|e| p e}
- # # Yields b
- # doc.root.each_element_with_attribute( 'id', '1', 1 ) {|e| p e}
- # # Yields d
- # doc.root.each_element_with_attribute( 'id', '1', 0, 'd' ) {|e| p e}
- def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element
- each_with_something( proc {|child|
- if value.nil?
- child.attributes[key] != nil
- else
- child.attributes[key]==value
- end
- }, max, name, &block )
- end
-
- # Iterates through the children, yielding for each Element that
- # has a particular text set.
- # text::
- # the text to search for. If nil, or not supplied, will iterate
- # over all +Element+ children that contain at least one +Text+ node.
- # max::
- # (optional) causes this method to return after yielding
- # for this number of matching children
- # name::
- # (optional) if supplied, this is an XPath that filters
- # the children to check.
- #
- # doc = Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>'
- # # Yields b, c, d
- # doc.each_element_with_text {|e|p e}
- # # Yields b, c
- # doc.each_element_with_text('b'){|e|p e}
- # # Yields b
- # doc.each_element_with_text('b', 1){|e|p e}
- # # Yields d
- # doc.each_element_with_text(nil, 0, 'd'){|e|p e}
- def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element
- each_with_something( proc {|child|
- if text.nil?
- child.has_text?
- else
- child.text == text
- end
- }, max, name, &block )
- end
-
- # Synonym for Element.elements.each
- def each_element( xpath=nil, &block ) # :yields: Element
- @elements.each( xpath, &block )
- end
-
- # Synonym for Element.to_a
- # This is a little slower than calling elements.each directly.
- # xpath:: any XPath by which to search for elements in the tree
- # Returns:: an array of Elements that match the supplied path
- def get_elements( xpath )
- @elements.to_a( xpath )
- end
-
- # Returns the next sibling that is an element, or nil if there is
- # no Element sibling after this one
- # doc = Document.new '<a><b/>text<c/></a>'
- # doc.root.elements['b'].next_element #-> <c/>
- # doc.root.elements['c'].next_element #-> nil
- def next_element
- element = next_sibling
- element = element.next_sibling until element.nil? or element.kind_of? Element
- return element
- end
-
- # Returns the previous sibling that is an element, or nil if there is
- # no Element sibling prior to this one
- # doc = Document.new '<a><b/>text<c/></a>'
- # doc.root.elements['c'].previous_element #-> <b/>
- # doc.root.elements['b'].previous_element #-> nil
- def previous_element
- element = previous_sibling
- element = element.previous_sibling until element.nil? or element.kind_of? Element
- return element
- end
-
-
- #################################################
- # Text #
- #################################################
-
- # Evaluates to +true+ if this element has at least one Text child
- def has_text?
- not text().nil?
- end
-
- # A convenience method which returns the String value of the _first_
- # child text element, if one exists, and +nil+ otherwise.
- #
- # <em>Note that an element may have multiple Text elements, perhaps
- # separated by other children</em>. Be aware that this method only returns
- # the first Text node.
- #
- # This method returns the +value+ of the first text child node, which
- # ignores the +raw+ setting, so always returns normalized text. See
- # the Text::value documentation.
- #
- # doc = Document.new "<p>some text <b>this is bold!</b> more text</p>"
- # # The element 'p' has two text elements, "some text " and " more text".
- # doc.root.text #-> "some text "
- def text( path = nil )
- rv = get_text(path)
- return rv.value unless rv.nil?
- nil
- end
-
- # Returns the first child Text node, if any, or +nil+ otherwise.
- # This method returns the actual +Text+ node, rather than the String content.
- # doc = Document.new "<p>some text <b>this is bold!</b> more text</p>"
- # # The element 'p' has two text elements, "some text " and " more text".
- # doc.root.get_text.value #-> "some text "
- def get_text path = nil
- rv = nil
- if path
- element = @elements[ path ]
- rv = element.get_text unless element.nil?
- else
- rv = @children.find { |node| node.kind_of? Text }
- end
- return rv
- end
-
- # Sets the first Text child of this object. See text() for a
- # discussion about Text children.
- #
- # If a Text child already exists, the child is replaced by this
- # content. This means that Text content can be deleted by calling
- # this method with a nil argument. In this case, the next Text
- # child becomes the first Text child. In no case is the order of
- # any siblings disturbed.
- # text::
- # If a String, a new Text child is created and added to
- # this Element as the first Text child. If Text, the text is set
- # as the first Child element. If nil, then any existing first Text
- # child is removed.
- # Returns:: this Element.
- # doc = Document.new '<a><b/></a>'
- # doc.root.text = 'Sean' #-> '<a><b/>Sean</a>'
- # doc.root.text = 'Elliott' #-> '<a><b/>Elliott</a>'
- # doc.root.add_element 'c' #-> '<a><b/>Elliott<c/></a>'
- # doc.root.text = 'Russell' #-> '<a><b/>Russell<c/></a>'
- # doc.root.text = nil #-> '<a><b/><c/></a>'
- def text=( text )
- if text.kind_of? String
- text = Text.new( text, whitespace(), nil, raw() )
- elsif !text.nil? and !text.kind_of? Text
- text = Text.new( text.to_s, whitespace(), nil, raw() )
- end
- old_text = get_text
- if text.nil?
- old_text.remove unless old_text.nil?
- else
- if old_text.nil?
- self << text
- else
- old_text.replace_with( text )
- end
- end
- return self
- end
-
- # A helper method to add a Text child. Actual Text instances can
- # be added with regular Parent methods, such as add() and <<()
- # text::
- # if a String, a new Text instance is created and added
- # to the parent. If Text, the object is added directly.
- # Returns:: this Element
- # e = Element.new('a') #-> <e/>
- # e.add_text 'foo' #-> <e>foo</e>
- # e.add_text Text.new(' bar') #-> <e>foo bar</e>
- # Note that at the end of this example, the branch has <b>3</b> nodes; the 'e'
- # element and <b>2</b> Text node children.
- def add_text( text )
- if text.kind_of? String
- if @children[-1].kind_of? Text
- @children[-1] << text
- return
- end
- text = Text.new( text, whitespace(), nil, raw() )
- end
- self << text unless text.nil?
- return self
- end
-
- def node_type
- :element
- end
-
- def xpath
- path_elements = []
- cur = self
- path_elements << __to_xpath_helper( self )
- while cur.parent
- cur = cur.parent
- path_elements << __to_xpath_helper( cur )
- end
- return path_elements.reverse.join( "/" )
- end
-
- #################################################
- # Attributes #
- #################################################
-
- # Fetches an attribute value or a child.
- #
- # If String or Symbol is specified, it's treated as attribute
- # name. Attribute value as String or +nil+ is returned. This case
- # is shortcut of +attributes[name]+.
- #
- # If Integer is specified, it's treated as the index of
- # child. It returns Nth child.
- #
- # doc = REXML::Document.new("<a attr='1'><b/><c/></a>")
- # doc.root["attr"] # => "1"
- # doc.root.attributes["attr"] # => "1"
- # doc.root[1] # => <c/>
- def [](name_or_index)
- case name_or_index
- when String
- attributes[name_or_index]
- when Symbol
- attributes[name_or_index.to_s]
- else
- super
- end
- end
-
- def attribute( name, namespace=nil )
- prefix = nil
- if namespaces.respond_to? :key
- prefix = namespaces.key(namespace) if namespace
- else
- prefix = namespaces.index(namespace) if namespace
- end
- prefix = nil if prefix == 'xmlns'
-
- ret_val =
- attributes.get_attribute( "#{prefix ? prefix + ':' : ''}#{name}" )
-
- return ret_val unless ret_val.nil?
- return nil if prefix.nil?
-
- # now check that prefix'es namespace is not the same as the
- # default namespace
- return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] )
-
- attributes.get_attribute( name )
-
- end
-
- # Evaluates to +true+ if this element has any attributes set, false
- # otherwise.
- def has_attributes?
- return !@attributes.empty?
- end
-
- # Adds an attribute to this element, overwriting any existing attribute
- # by the same name.
- # key::
- # can be either an Attribute or a String. If an Attribute,
- # the attribute is added to the list of Element attributes. If String,
- # the argument is used as the name of the new attribute, and the value
- # parameter must be supplied.
- # value::
- # Required if +key+ is a String, and ignored if the first argument is
- # an Attribute. This is a String, and is used as the value
- # of the new Attribute. This should be the unnormalized value of the
- # attribute (without entities).
- # Returns:: the Attribute added
- # e = Element.new 'e'
- # e.add_attribute( 'a', 'b' ) #-> <e a='b'/>
- # e.add_attribute( 'x:a', 'c' ) #-> <e a='b' x:a='c'/>
- # e.add_attribute Attribute.new('b', 'd') #-> <e a='b' x:a='c' b='d'/>
- def add_attribute( key, value=nil )
- if key.kind_of? Attribute
- @attributes << key
- else
- @attributes[key] = value
- end
- end
-
- # Add multiple attributes to this element.
- # hash:: is either a hash, or array of arrays
- # el.add_attributes( {"name1"=>"value1", "name2"=>"value2"} )
- # el.add_attributes( [ ["name1","value1"], ["name2"=>"value2"] ] )
- def add_attributes hash
- if hash.kind_of? Hash
- hash.each_pair {|key, value| @attributes[key] = value }
- elsif hash.kind_of? Array
- hash.each { |value| @attributes[ value[0] ] = value[1] }
- end
- end
-
- # Removes an attribute
- # key::
- # either an Attribute or a String. In either case, the
- # attribute is found by matching the attribute name to the argument,
- # and then removed. If no attribute is found, no action is taken.
- # Returns::
- # the attribute removed, or nil if this Element did not contain
- # a matching attribute
- # e = Element.new('E')
- # e.add_attribute( 'name', 'Sean' ) #-> <E name='Sean'/>
- # r = e.add_attribute( 'sur:name', 'Russell' ) #-> <E name='Sean' sur:name='Russell'/>
- # e.delete_attribute( 'name' ) #-> <E sur:name='Russell'/>
- # e.delete_attribute( r ) #-> <E/>
- def delete_attribute(key)
- attr = @attributes.get_attribute(key)
- attr.remove unless attr.nil?
- end
-
- #################################################
- # Other Utilities #
- #################################################
-
- # Get an array of all CData children.
- # IMMUTABLE
- def cdatas
- find_all { |child| child.kind_of? CData }.freeze
- end
-
- # Get an array of all Comment children.
- # IMMUTABLE
- def comments
- find_all { |child| child.kind_of? Comment }.freeze
- end
-
- # Get an array of all Instruction children.
- # IMMUTABLE
- def instructions
- find_all { |child| child.kind_of? Instruction }.freeze
- end
-
- # Get an array of all Text children.
- # IMMUTABLE
- def texts
- find_all { |child| child.kind_of? Text }.freeze
- end
-
- # == DEPRECATED
- # See REXML::Formatters
- #
- # Writes out this element, and recursively, all children.
- # output::
- # output an object which supports '<< string'; this is where the
- # document will be written.
- # indent::
- # An integer. If -1, no indenting will be used; otherwise, the
- # indentation will be this number of spaces, and children will be
- # indented an additional amount. Defaults to -1
- # transitive::
- # If transitive is true and indent is >= 0, then the output will be
- # pretty-printed in such a way that the added whitespace does not affect
- # the parse tree of the document
- # ie_hack::
- # This hack inserts a space before the /> on empty tags to address
- # a limitation of Internet Explorer. Defaults to false
- #
- # out = ''
- # doc.write( out ) #-> doc is written to the string 'out'
- # doc.write( $stdout ) #-> doc written to the console
- def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
- Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
- formatter = if indent > -1
- if transitive
- require "rexml/formatters/transitive"
- REXML::Formatters::Transitive.new( indent, ie_hack )
- else
- REXML::Formatters::Pretty.new( indent, ie_hack )
- end
- else
- REXML::Formatters::Default.new( ie_hack )
- end
- formatter.write( self, output )
- end
-
-
- private
- def __to_xpath_helper node
- rv = node.expanded_name.clone
- if node.parent
- results = node.parent.find_all {|n|
- n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name
- }
- if results.length > 1
- idx = results.index( node )
- rv << "[#{idx+1}]"
- end
- end
- rv
- end
-
- # A private helper method
- def each_with_something( test, max=0, name=nil )
- num = 0
- @elements.each( name ){ |child|
- yield child if test.call(child) and num += 1
- return if max>0 and num == max
- }
- end
- end
-
- ########################################################################
- # ELEMENTS #
- ########################################################################
-
- # A class which provides filtering of children for Elements, and
- # XPath search support. You are expected to only encounter this class as
- # the <tt>element.elements</tt> object. Therefore, you are
- # _not_ expected to instantiate this yourself.
- class Elements
- include Enumerable
- # Constructor
- # parent:: the parent Element
- def initialize parent
- @element = parent
- end
-
- # Fetches a child element. Filters only Element children, regardless of
- # the XPath match.
- # index::
- # the search parameter. This is either an Integer, which
- # will be used to find the index'th child Element, or an XPath,
- # which will be used to search for the Element. <em>Because
- # of the nature of XPath searches, any element in the connected XML
- # document can be fetched through any other element.</em> <b>The
- # Integer index is 1-based, not 0-based.</b> This means that the first
- # child element is at index 1, not 0, and the +n+th element is at index
- # +n+, not <tt>n-1</tt>. This is because XPath indexes element children
- # starting from 1, not 0, and the indexes should be the same.
- # name::
- # optional, and only used in the first argument is an
- # Integer. In that case, the index'th child Element that has the
- # supplied name will be returned. Note again that the indexes start at 1.
- # Returns:: the first matching Element, or nil if no child matched
- # doc = Document.new '<a><b/><c id="1"/><c id="2"/><d/></a>'
- # doc.root.elements[1] #-> <b/>
- # doc.root.elements['c'] #-> <c id="1"/>
- # doc.root.elements[2,'c'] #-> <c id="2"/>
- def []( index, name=nil)
- if index.kind_of? Integer
- raise "index (#{index}) must be >= 1" if index < 1
- name = literalize(name) if name
- num = 0
- @element.find { |child|
- child.kind_of? Element and
- (name.nil? ? true : child.has_name?( name )) and
- (num += 1) == index
- }
- else
- return XPath::first( @element, index )
- #{ |element|
- # return element if element.kind_of? Element
- #}
- #return nil
- end
- end
-
- # Sets an element, replacing any previous matching element. If no
- # existing element is found ,the element is added.
- # index:: Used to find a matching element to replace. See []().
- # element::
- # The element to replace the existing element with
- # the previous element
- # Returns:: nil if no previous element was found.
- #
- # doc = Document.new '<a/>'
- # doc.root.elements[10] = Element.new('b') #-> <a><b/></a>
- # doc.root.elements[1] #-> <b/>
- # doc.root.elements[1] = Element.new('c') #-> <a><c/></a>
- # doc.root.elements['c'] = Element.new('d') #-> <a><d/></a>
- def []=( index, element )
- previous = self[index]
- if previous.nil?
- @element.add element
- else
- previous.replace_with element
- end
- return previous
- end
-
- # Returns +true+ if there are no +Element+ children, +false+ otherwise
- def empty?
- @element.find{ |child| child.kind_of? Element}.nil?
- end
-
- # Returns the index of the supplied child (starting at 1), or -1 if
- # the element is not a child
- # element:: an +Element+ child
- def index element
- rv = 0
- found = @element.find do |child|
- child.kind_of? Element and
- (rv += 1) and
- child == element
- end
- return rv if found == element
- return -1
- end
-
- # Deletes a child Element
- # element::
- # Either an Element, which is removed directly; an
- # xpath, where the first matching child is removed; or an Integer,
- # where the n'th Element is removed.
- # Returns:: the removed child
- # doc = Document.new '<a><b/><c/><c id="1"/></a>'
- # b = doc.root.elements[1]
- # doc.root.elements.delete b #-> <a><c/><c id="1"/></a>
- # doc.elements.delete("a/c[@id='1']") #-> <a><c/></a>
- # doc.root.elements.delete 1 #-> <a/>
- def delete element
- if element.kind_of? Element
- @element.delete element
- else
- el = self[element]
- el.remove if el
- end
- end
-
- # Removes multiple elements. Filters for Element children, regardless of
- # XPath matching.
- # xpath:: all elements matching this String path are removed.
- # Returns:: an Array of Elements that have been removed
- # doc = Document.new '<a><c/><c/><c/><c/></a>'
- # deleted = doc.elements.delete_all 'a/c' #-> [<c/>, <c/>, <c/>, <c/>]
- def delete_all( xpath )
- rv = []
- XPath::each( @element, xpath) {|element|
- rv << element if element.kind_of? Element
- }
- rv.each do |element|
- @element.delete element
- element.remove
- end
- return rv
- end
-
- # Adds an element
- # element::
- # if supplied, is either an Element, String, or
- # Source (see Element.initialize). If not supplied or nil, a
- # new, default Element will be constructed
- # Returns:: the added Element
- # a = Element.new('a')
- # a.elements.add(Element.new('b')) #-> <a><b/></a>
- # a.elements.add('c') #-> <a><b/><c/></a>
- def add element=nil
- if element.nil?
- Element.new("", self, @element.context)
- elsif not element.kind_of?(Element)
- Element.new(element, self, @element.context)
- else
- @element << element
- element.context = @element.context
- element
- end
- end
-
- alias :<< :add
-
- # Iterates through all of the child Elements, optionally filtering
- # them by a given XPath
- # xpath::
- # optional. If supplied, this is a String XPath, and is used to
- # filter the children, so that only matching children are yielded. Note
- # that XPaths are automatically filtered for Elements, so that
- # non-Element children will not be yielded
- # doc = Document.new '<a><b/><c/><d/>sean<b/><c/><d/></a>'
- # doc.root.elements.each {|e|p e} #-> Yields b, c, d, b, c, d elements
- # doc.root.elements.each('b') {|e|p e} #-> Yields b, b elements
- # doc.root.elements.each('child::node()') {|e|p e}
- # #-> Yields <b/>, <c/>, <d/>, <b/>, <c/>, <d/>
- # XPath.each(doc.root, 'child::node()', &block)
- # #-> Yields <b/>, <c/>, <d/>, sean, <b/>, <c/>, <d/>
- def each( xpath=nil )
- XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element }
- end
-
- def collect( xpath=nil )
- collection = []
- XPath::each( @element, xpath ) {|e|
- collection << yield(e) if e.kind_of?(Element)
- }
- collection
- end
-
- def inject( xpath=nil, initial=nil )
- first = true
- XPath::each( @element, xpath ) {|e|
- if (e.kind_of? Element)
- if (first and initial == nil)
- initial = e
- first = false
- else
- initial = yield( initial, e ) if e.kind_of? Element
- end
- end
- }
- initial
- end
-
- # Returns the number of +Element+ children of the parent object.
- # doc = Document.new '<a>sean<b/>elliott<b/>russell<b/></a>'
- # doc.root.size #-> 6, 3 element and 3 text nodes
- # doc.root.elements.size #-> 3
- def size
- count = 0
- @element.each {|child| count+=1 if child.kind_of? Element }
- count
- end
-
- # Returns an Array of Element children. An XPath may be supplied to
- # filter the children. Only Element children are returned, even if the
- # supplied XPath matches non-Element children.
- # doc = Document.new '<a>sean<b/>elliott<c/></a>'
- # doc.root.elements.to_a #-> [ <b/>, <c/> ]
- # doc.root.elements.to_a("child::node()") #-> [ <b/>, <c/> ]
- # XPath.match(doc.root, "child::node()") #-> [ sean, <b/>, elliott, <c/> ]
- def to_a( xpath=nil )
- rv = XPath.match( @element, xpath )
- return rv.find_all{|e| e.kind_of? Element} if xpath
- rv
- end
-
- private
- # Private helper class. Removes quotes from quoted strings
- def literalize name
- name = name[1..-2] if name[0] == ?' or name[0] == ?" #'
- name
- end
- end
-
- ########################################################################
- # ATTRIBUTES #
- ########################################################################
-
- # A class that defines the set of Attributes of an Element and provides
- # operations for accessing elements in that set.
- class Attributes < Hash
- # Constructor
- # element:: the Element of which this is an Attribute
- def initialize element
- @element = element
- end
-
- # Fetches an attribute value. If you want to get the Attribute itself,
- # use get_attribute()
- # name:: an XPath attribute name. Namespaces are relevant here.
- # Returns::
- # the String value of the matching attribute, or +nil+ if no
- # matching attribute was found. This is the unnormalized value
- # (with entities expanded).
- #
- # doc = Document.new "<a foo:att='1' bar:att='2' att='&lt;'/>"
- # doc.root.attributes['att'] #-> '<'
- # doc.root.attributes['bar:att'] #-> '2'
- def [](name)
- attr = get_attribute(name)
- return attr.value unless attr.nil?
- return nil
- end
-
- def to_a
- enum_for(:each_attribute).to_a
- end
-
- # Returns the number of attributes the owning Element contains.
- # doc = Document "<a x='1' y='2' foo:x='3'/>"
- # doc.root.attributes.length #-> 3
- def length
- c = 0
- each_attribute { c+=1 }
- c
- end
- alias :size :length
-
- # Iterates over the attributes of an Element. Yields actual Attribute
- # nodes, not String values.
- #
- # doc = Document.new '<a x="1" y="2"/>'
- # doc.root.attributes.each_attribute {|attr|
- # p attr.expanded_name+" => "+attr.value
- # }
- def each_attribute # :yields: attribute
- each_value do |val|
- if val.kind_of? Attribute
- yield val
- else
- val.each_value { |atr| yield atr }
- end
- end
- end
-
- # Iterates over each attribute of an Element, yielding the expanded name
- # and value as a pair of Strings.
- #
- # doc = Document.new '<a x="1" y="2"/>'
- # doc.root.attributes.each {|name, value| p name+" => "+value }
- def each
- each_attribute do |attr|
- yield [attr.expanded_name, attr.value]
- end
- end
-
- # Fetches an attribute
- # name::
- # the name by which to search for the attribute. Can be a
- # <tt>prefix:name</tt> namespace name.
- # Returns:: The first matching attribute, or nil if there was none. This
- # value is an Attribute node, not the String value of the attribute.
- # doc = Document.new '<a x:foo="1" foo="2" bar="3"/>'
- # doc.root.attributes.get_attribute("foo").value #-> "2"
- # doc.root.attributes.get_attribute("x:foo").value #-> "1"
- def get_attribute( name )
- attr = fetch( name, nil )
- if attr.nil?
- return nil if name.nil?
- # Look for prefix
- name =~ Namespace::NAMESPLIT
- prefix, n = $1, $2
- if prefix
- attr = fetch( n, nil )
- # check prefix
- if attr == nil
- elsif attr.kind_of? Attribute
- return attr if prefix == attr.prefix
- else
- attr = attr[ prefix ]
- return attr
- end
- end
- element_document = @element.document
- if element_document and element_document.doctype
- expn = @element.expanded_name
- expn = element_document.doctype.name if expn.size == 0
- attr_val = element_document.doctype.attribute_of(expn, name)
- return Attribute.new( name, attr_val ) if attr_val
- end
- return nil
- end
- if attr.kind_of? Hash
- attr = attr[ @element.prefix ]
- end
- return attr
- end
-
- # Sets an attribute, overwriting any existing attribute value by the
- # same name. Namespace is significant.
- # name:: the name of the attribute
- # value::
- # (optional) If supplied, the value of the attribute. If
- # nil, any existing matching attribute is deleted.
- # Returns::
- # Owning element
- # doc = Document.new "<a x:foo='1' foo='3'/>"
- # doc.root.attributes['y:foo'] = '2'
- # doc.root.attributes['foo'] = '4'
- # doc.root.attributes['x:foo'] = nil
- def []=( name, value )
- if value.nil? # Delete the named attribute
- attr = get_attribute(name)
- delete attr
- return
- end
-
- unless value.kind_of? Attribute
- if @element.document and @element.document.doctype
- value = Text::normalize( value, @element.document.doctype )
- else
- value = Text::normalize( value, nil )
- end
- value = Attribute.new(name, value)
- end
- value.element = @element
- old_attr = fetch(value.name, nil)
- if old_attr.nil?
- store(value.name, value)
- elsif old_attr.kind_of? Hash
- old_attr[value.prefix] = value
- elsif old_attr.prefix != value.prefix
- # Check for conflicting namespaces
- raise ParseException.new(
- "Namespace conflict in adding attribute \"#{value.name}\": "+
- "Prefix \"#{old_attr.prefix}\" = "+
- "\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
- "\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if
- value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
- @element.namespace( old_attr.prefix ) ==
- @element.namespace( value.prefix )
- store value.name, { old_attr.prefix => old_attr,
- value.prefix => value }
- else
- store value.name, value
- end
- return @element
- end
-
- # Returns an array of Strings containing all of the prefixes declared
- # by this set of # attributes. The array does not include the default
- # namespace declaration, if one exists.
- # doc = Document.new("<a xmlns='foo' xmlns:x='bar' xmlns:y='twee' "+
- # "z='glorp' p:k='gru'/>")
- # prefixes = doc.root.attributes.prefixes #-> ['x', 'y']
- def prefixes
- ns = []
- each_attribute do |attribute|
- ns << attribute.name if attribute.prefix == 'xmlns'
- end
- if @element.document and @element.document.doctype
- expn = @element.expanded_name
- expn = @element.document.doctype.name if expn.size == 0
- @element.document.doctype.attributes_of(expn).each {
- |attribute|
- ns << attribute.name if attribute.prefix == 'xmlns'
- }
- end
- ns
- end
-
- def namespaces
- namespaces = {}
- each_attribute do |attribute|
- namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
- end
- if @element.document and @element.document.doctype
- expn = @element.expanded_name
- expn = @element.document.doctype.name if expn.size == 0
- @element.document.doctype.attributes_of(expn).each {
- |attribute|
- namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
- }
- end
- namespaces
- end
-
- # Removes an attribute
- # attribute::
- # either a String, which is the name of the attribute to remove --
- # namespaces are significant here -- or the attribute to remove.
- # Returns:: the owning element
- # doc = Document.new "<a y:foo='0' x:foo='1' foo='3' z:foo='4'/>"
- # doc.root.attributes.delete 'foo' #-> <a y:foo='0' x:foo='1' z:foo='4'/>"
- # doc.root.attributes.delete 'x:foo' #-> <a y:foo='0' z:foo='4'/>"
- # attr = doc.root.attributes.get_attribute('y:foo')
- # doc.root.attributes.delete attr #-> <a z:foo='4'/>"
- def delete( attribute )
- name = nil
- prefix = nil
- if attribute.kind_of? Attribute
- name = attribute.name
- prefix = attribute.prefix
- else
- attribute =~ Namespace::NAMESPLIT
- prefix, name = $1, $2
- prefix = '' unless prefix
- end
- old = fetch(name, nil)
- if old.kind_of? Hash # the supplied attribute is one of many
- old.delete(prefix)
- if old.size == 1
- repl = nil
- old.each_value{|v| repl = v}
- store name, repl
- end
- elsif old.nil?
- return @element
- else # the supplied attribute is a top-level one
- super(name)
- end
- @element
- end
-
- # Adds an attribute, overriding any existing attribute by the
- # same name. Namespaces are significant.
- # attribute:: An Attribute
- def add( attribute )
- self[attribute.name] = attribute
- end
-
- alias :<< :add
-
- # Deletes all attributes matching a name. Namespaces are significant.
- # name::
- # A String; all attributes that match this path will be removed
- # Returns:: an Array of the Attributes that were removed
- def delete_all( name )
- rv = []
- each_attribute { |attribute|
- rv << attribute if attribute.expanded_name == name
- }
- rv.each{ |attr| attr.remove }
- return rv
- end
-
- # The +get_attribute_ns+ method retrieves a method by its namespace
- # and name. Thus it is possible to reliably identify an attribute
- # even if an XML processor has changed the prefix.
- #
- # Method contributed by Henrik Martensson
- def get_attribute_ns(namespace, name)
- result = nil
- each_attribute() { |attribute|
- if name == attribute.name &&
- namespace == attribute.namespace() &&
- ( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
- # foo will match xmlns:foo, but only if foo isn't also an attribute
- result = attribute if !result or !namespace.empty? or
- !attribute.fully_expanded_name.index(':')
- end
- }
- result
- end
- end
-end
diff --git a/lib/rexml/encoding.rb b/lib/rexml/encoding.rb
deleted file mode 100644
index da2d70d6c9..0000000000
--- a/lib/rexml/encoding.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# coding: US-ASCII
-# frozen_string_literal: false
-module REXML
- module Encoding
- # ID ---> Encoding name
- attr_reader :encoding
- def encoding=(encoding)
- encoding = encoding.name if encoding.is_a?(Encoding)
- if encoding.is_a?(String)
- original_encoding = encoding
- encoding = find_encoding(encoding)
- unless encoding
- raise ArgumentError, "Bad encoding name #{original_encoding}"
- end
- end
- return false if defined?(@encoding) and encoding == @encoding
- if encoding
- @encoding = encoding.upcase
- else
- @encoding = 'UTF-8'
- end
- true
- end
-
- def encode(string)
- string.encode(@encoding)
- end
-
- def decode(string)
- string.encode(::Encoding::UTF_8, @encoding)
- end
-
- private
- def find_encoding(name)
- case name
- when /\Ashift-jis\z/i
- return "SHIFT_JIS"
- when /\ACP-(\d+)\z/
- name = "CP#{$1}"
- when /\AUTF-8\z/i
- return name
- end
- begin
- ::Encoding::Converter.search_convpath(name, 'UTF-8')
- rescue ::Encoding::ConverterNotFoundError
- return nil
- end
- name
- end
- end
-end
diff --git a/lib/rexml/entity.rb b/lib/rexml/entity.rb
deleted file mode 100644
index 3f44c9109a..0000000000
--- a/lib/rexml/entity.rb
+++ /dev/null
@@ -1,172 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/child'
-require 'rexml/source'
-require 'rexml/xmltokens'
-
-module REXML
- class Entity < Child
- include XMLTokens
- PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#"
- SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))}
- PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')}
- EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
- NDATADECL = "\\s+NDATA\\s+#{NAME}"
- PEREFERENCE = "%#{NAME};"
- ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
- PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
- ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
- PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
- GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
- ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
-
- attr_reader :name, :external, :ref, :ndata, :pubid
-
- # Create a new entity. Simple entities can be constructed by passing a
- # name, value to the constructor; this creates a generic, plain entity
- # reference. For anything more complicated, you have to pass a Source to
- # the constructor with the entity definition, or use the accessor methods.
- # +WARNING+: There is no validation of entity state except when the entity
- # is read from a stream. If you start poking around with the accessors,
- # you can easily create a non-conformant Entity. The best thing to do is
- # dump the stupid DTDs and use XMLSchema instead.
- #
- # e = Entity.new( 'amp', '&' )
- def initialize stream, value=nil, parent=nil, reference=false
- super(parent)
- @ndata = @pubid = @value = @external = nil
- if stream.kind_of? Array
- @name = stream[1]
- if stream[-1] == '%'
- @reference = true
- stream.pop
- else
- @reference = false
- end
- if stream[2] =~ /SYSTEM|PUBLIC/
- @external = stream[2]
- if @external == 'SYSTEM'
- @ref = stream[3]
- @ndata = stream[4] if stream.size == 5
- else
- @pubid = stream[3]
- @ref = stream[4]
- end
- else
- @value = stream[2]
- end
- else
- @reference = reference
- @external = nil
- @name = stream
- @value = value
- end
- end
-
- # Evaluates whether the given string matches an entity definition,
- # returning true if so, and false otherwise.
- def Entity::matches? string
- (ENTITYDECL =~ string) == 0
- end
-
- # Evaluates to the unnormalized value of this entity; that is, replacing
- # all entities -- both %ent; and &ent; entities. This differs from
- # +value()+ in that +value+ only replaces %ent; entities.
- def unnormalized
- document.record_entity_expansion unless document.nil?
- v = value()
- return nil if v.nil?
- @unnormalized = Text::unnormalize(v, parent)
- @unnormalized
- end
-
- #once :unnormalized
-
- # Returns the value of this entity unprocessed -- raw. This is the
- # normalized value; that is, with all %ent; and &ent; entities intact
- def normalized
- @value
- end
-
- # Write out a fully formed, correct entity definition (assuming the Entity
- # object itself is valid.)
- #
- # out::
- # An object implementing <TT>&lt;&lt;<TT> to which the entity will be
- # output
- # indent::
- # *DEPRECATED* and ignored
- def write out, indent=-1
- out << '<!ENTITY '
- out << '% ' if @reference
- out << @name
- out << ' '
- if @external
- out << @external << ' '
- if @pubid
- q = @pubid.include?('"')?"'":'"'
- out << q << @pubid << q << ' '
- end
- q = @ref.include?('"')?"'":'"'
- out << q << @ref << q
- out << ' NDATA ' << @ndata if @ndata
- else
- q = @value.include?('"')?"'":'"'
- out << q << @value << q
- end
- out << '>'
- end
-
- # Returns this entity as a string. See write().
- def to_s
- rv = ''
- write rv
- rv
- end
-
- PEREFERENCE_RE = /#{PEREFERENCE}/um
- # Returns the value of this entity. At the moment, only internal entities
- # are processed. If the value contains internal references (IE,
- # %blah;), those are replaced with their values. IE, if the doctype
- # contains:
- # <!ENTITY % foo "bar">
- # <!ENTITY yada "nanoo %foo; nanoo>
- # then:
- # doctype.entity('yada').value #-> "nanoo bar nanoo"
- def value
- if @value
- matches = @value.scan(PEREFERENCE_RE)
- rv = @value.clone
- if @parent
- sum = 0
- matches.each do |entity_reference|
- entity_value = @parent.entity( entity_reference[0] )
- if sum + entity_value.bytesize > Security.entity_expansion_text_limit
- raise "entity expansion has grown too large"
- else
- sum += entity_value.bytesize
- end
- rv.gsub!( /%#{entity_reference.join};/um, entity_value )
- end
- end
- return rv
- end
- nil
- end
- end
-
- # This is a set of entity constants -- the ones defined in the XML
- # specification. These are +gt+, +lt+, +amp+, +quot+ and +apos+.
- # CAUTION: these entities does not have parent and document
- module EntityConst
- # +>+
- GT = Entity.new( 'gt', '>' )
- # +<+
- LT = Entity.new( 'lt', '<' )
- # +&+
- AMP = Entity.new( 'amp', '&' )
- # +"+
- QUOT = Entity.new( 'quot', '"' )
- # +'+
- APOS = Entity.new( 'apos', "'" )
- end
-end
diff --git a/lib/rexml/formatters/default.rb b/lib/rexml/formatters/default.rb
deleted file mode 100644
index c375f1468b..0000000000
--- a/lib/rexml/formatters/default.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# frozen_string_literal: false
-module REXML
- module Formatters
- class Default
- # Prints out the XML document with no formatting -- except if ie_hack is
- # set.
- #
- # ie_hack::
- # If set to true, then inserts whitespace before the close of an empty
- # tag, so that IE's bad XML parser doesn't choke.
- def initialize( ie_hack=false )
- @ie_hack = ie_hack
- end
-
- # Writes the node to some output.
- #
- # node::
- # The node to write
- # output::
- # A class implementing <TT>&lt;&lt;</TT>. Pass in an Output object to
- # change the output encoding.
- def write( node, output )
- case node
-
- when Document
- if node.xml_decl.encoding != 'UTF-8' && !output.kind_of?(Output)
- output = Output.new( output, node.xml_decl.encoding )
- end
- write_document( node, output )
-
- when Element
- write_element( node, output )
-
- when Declaration, ElementDecl, NotationDecl, ExternalEntity, Entity,
- Attribute, AttlistDecl
- node.write( output,-1 )
-
- when Instruction
- write_instruction( node, output )
-
- when DocType, XMLDecl
- node.write( output )
-
- when Comment
- write_comment( node, output )
-
- when CData
- write_cdata( node, output )
-
- when Text
- write_text( node, output )
-
- else
- raise Exception.new("XML FORMATTING ERROR")
-
- end
- end
-
- protected
- def write_document( node, output )
- node.children.each { |child| write( child, output ) }
- end
-
- def write_element( node, output )
- output << "<#{node.expanded_name}"
-
- node.attributes.to_a.map { |a|
- Hash === a ? a.values : a
- }.flatten.sort_by {|attr| attr.name}.each do |attr|
- output << " "
- attr.write( output )
- end unless node.attributes.empty?
-
- if node.children.empty?
- output << " " if @ie_hack
- output << "/"
- else
- output << ">"
- node.children.each { |child|
- write( child, output )
- }
- output << "</#{node.expanded_name}"
- end
- output << ">"
- end
-
- def write_text( node, output )
- output << node.to_s()
- end
-
- def write_comment( node, output )
- output << Comment::START
- output << node.to_s
- output << Comment::STOP
- end
-
- def write_cdata( node, output )
- output << CData::START
- output << node.to_s
- output << CData::STOP
- end
-
- def write_instruction( node, output )
- output << Instruction::START.sub(/\\/u, '')
- output << node.target
- output << ' '
- output << node.content
- output << Instruction::STOP.sub(/\\/u, '')
- end
- end
- end
-end
diff --git a/lib/rexml/formatters/pretty.rb b/lib/rexml/formatters/pretty.rb
deleted file mode 100644
index a80274bdad..0000000000
--- a/lib/rexml/formatters/pretty.rb
+++ /dev/null
@@ -1,142 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/formatters/default'
-
-module REXML
- module Formatters
- # Pretty-prints an XML document. This destroys whitespace in text nodes
- # and will insert carriage returns and indentations.
- #
- # TODO: Add an option to print attributes on new lines
- class Pretty < Default
-
- # If compact is set to true, then the formatter will attempt to use as
- # little space as possible
- attr_accessor :compact
- # The width of a page. Used for formatting text
- attr_accessor :width
-
- # Create a new pretty printer.
- #
- # output::
- # An object implementing '<<(String)', to which the output will be written.
- # indentation::
- # An integer greater than 0. The indentation of each level will be
- # this number of spaces. If this is < 1, the behavior of this object
- # is undefined. Defaults to 2.
- # ie_hack::
- # If true, the printer will insert whitespace before closing empty
- # tags, thereby allowing Internet Explorer's XML parser to
- # function. Defaults to false.
- def initialize( indentation=2, ie_hack=false )
- @indentation = indentation
- @level = 0
- @ie_hack = ie_hack
- @width = 80
- @compact = false
- end
-
- protected
- def write_element(node, output)
- output << ' '*@level
- output << "<#{node.expanded_name}"
-
- node.attributes.each_attribute do |attr|
- output << " "
- attr.write( output )
- end unless node.attributes.empty?
-
- if node.children.empty?
- if @ie_hack
- output << " "
- end
- output << "/"
- else
- output << ">"
- # If compact and all children are text, and if the formatted output
- # is less than the specified width, then try to print everything on
- # one line
- skip = false
- if compact
- if node.children.inject(true) {|s,c| s & c.kind_of?(Text)}
- string = ""
- old_level = @level
- @level = 0
- node.children.each { |child| write( child, string ) }
- @level = old_level
- if string.length < @width
- output << string
- skip = true
- end
- end
- end
- unless skip
- output << "\n"
- @level += @indentation
- node.children.each { |child|
- next if child.kind_of?(Text) and child.to_s.strip.length == 0
- write( child, output )
- output << "\n"
- }
- @level -= @indentation
- output << ' '*@level
- end
- output << "</#{node.expanded_name}"
- end
- output << ">"
- end
-
- def write_text( node, output )
- s = node.to_s()
- s.gsub!(/\s/,' ')
- s.squeeze!(" ")
- s = wrap(s, @width - @level)
- s = indent_text(s, @level, " ", true)
- output << (' '*@level + s)
- end
-
- def write_comment( node, output)
- output << ' ' * @level
- super
- end
-
- def write_cdata( node, output)
- output << ' ' * @level
- super
- end
-
- def write_document( node, output )
- # Ok, this is a bit odd. All XML documents have an XML declaration,
- # but it may not write itself if the user didn't specifically add it,
- # either through the API or in the input document. If it doesn't write
- # itself, then we don't need a carriage return... which makes this
- # logic more complex.
- node.children.each { |child|
- next if child == node.children[-1] and child.instance_of?(Text)
- unless child == node.children[0] or child.instance_of?(Text) or
- (child == node.children[1] and !node.children[0].writethis)
- output << "\n"
- end
- write( child, output )
- }
- end
-
- private
- def indent_text(string, level=1, style="\t", indentfirstline=true)
- return string if level < 0
- string.gsub(/\n/, "\n#{style*level}")
- end
-
- def wrap(string, width)
- parts = []
- while string.length > width and place = string.rindex(' ', width)
- parts << string[0...place]
- string = string[place+1..-1]
- end
- parts << string
- parts.join("\n")
- end
-
- end
- end
-end
-
diff --git a/lib/rexml/formatters/transitive.rb b/lib/rexml/formatters/transitive.rb
deleted file mode 100644
index 81e67f3274..0000000000
--- a/lib/rexml/formatters/transitive.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/formatters/pretty'
-
-module REXML
- module Formatters
- # The Transitive formatter writes an XML document that parses to an
- # identical document as the source document. This means that no extra
- # whitespace nodes are inserted, and whitespace within text nodes is
- # preserved. Within these constraints, the document is pretty-printed,
- # with whitespace inserted into the metadata to introduce formatting.
- #
- # Note that this is only useful if the original XML is not already
- # formatted. Since this formatter does not alter whitespace nodes, the
- # results of formatting already formatted XML will be odd.
- class Transitive < Default
- def initialize( indentation=2, ie_hack=false )
- @indentation = indentation
- @level = 0
- @ie_hack = ie_hack
- end
-
- protected
- def write_element( node, output )
- output << "<#{node.expanded_name}"
-
- node.attributes.each_attribute do |attr|
- output << " "
- attr.write( output )
- end unless node.attributes.empty?
-
- output << "\n"
- output << ' '*@level
- if node.children.empty?
- output << " " if @ie_hack
- output << "/"
- else
- output << ">"
- # If compact and all children are text, and if the formatted output
- # is less than the specified width, then try to print everything on
- # one line
- @level += @indentation
- node.children.each { |child|
- write( child, output )
- }
- @level -= @indentation
- output << "</#{node.expanded_name}"
- output << "\n"
- output << ' '*@level
- end
- output << ">"
- end
-
- def write_text( node, output )
- output << node.to_s()
- end
- end
- end
-end
diff --git a/lib/rexml/functions.rb b/lib/rexml/functions.rb
deleted file mode 100644
index cd879fdd28..0000000000
--- a/lib/rexml/functions.rb
+++ /dev/null
@@ -1,421 +0,0 @@
-# frozen_string_literal: false
-module REXML
- # If you add a method, keep in mind two things:
- # (1) the first argument will always be a list of nodes from which to
- # filter. In the case of context methods (such as position), the function
- # should return an array with a value for each child in the array.
- # (2) all method calls from XML will have "-" replaced with "_".
- # Therefore, in XML, "local-name()" is identical (and actually becomes)
- # "local_name()"
- module Functions
- @@available_functions = {}
- @@context = nil
- @@namespace_context = {}
- @@variables = {}
-
- INTERNAL_METHODS = [
- :namespace_context,
- :namespace_context=,
- :variables,
- :variables=,
- :context=,
- :get_namespace,
- :send,
- ]
- class << self
- def singleton_method_added(name)
- unless INTERNAL_METHODS.include?(name)
- @@available_functions[name] = true
- end
- end
- end
-
- def Functions::namespace_context=(x) ; @@namespace_context=x ; end
- def Functions::variables=(x) ; @@variables=x ; end
- def Functions::namespace_context ; @@namespace_context ; end
- def Functions::variables ; @@variables ; end
-
- def Functions::context=(value); @@context = value; end
-
- def Functions::text( )
- if @@context[:node].node_type == :element
- return @@context[:node].find_all{|n| n.node_type == :text}.collect{|n| n.value}
- elsif @@context[:node].node_type == :text
- return @@context[:node].value
- else
- return false
- end
- end
-
- # Returns the last node of the given list of nodes.
- def Functions::last( )
- @@context[:size]
- end
-
- def Functions::position( )
- @@context[:index]
- end
-
- # Returns the size of the given list of nodes.
- def Functions::count( node_set )
- node_set.size
- end
-
- # Since REXML is non-validating, this method is not implemented as it
- # requires a DTD
- def Functions::id( object )
- end
-
- # UNTESTED
- def Functions::local_name( node_set=nil )
- get_namespace( node_set ) do |node|
- return node.local_name
- end
- end
-
- def Functions::namespace_uri( node_set=nil )
- get_namespace( node_set ) {|node| node.namespace}
- end
-
- def Functions::name( node_set=nil )
- get_namespace( node_set ) do |node|
- node.expanded_name
- end
- end
-
- # Helper method.
- def Functions::get_namespace( node_set = nil )
- if node_set == nil
- yield @@context[:node] if defined? @@context[:node].namespace
- else
- if node_set.respond_to? :each
- node_set.each { |node| yield node if defined? node.namespace }
- elsif node_set.respond_to? :namespace
- yield node_set
- end
- end
- end
-
- # A node-set is converted to a string by returning the string-value of the
- # node in the node-set that is first in document order. If the node-set is
- # empty, an empty string is returned.
- #
- # A number is converted to a string as follows
- #
- # NaN is converted to the string NaN
- #
- # positive zero is converted to the string 0
- #
- # negative zero is converted to the string 0
- #
- # positive infinity is converted to the string Infinity
- #
- # negative infinity is converted to the string -Infinity
- #
- # if the number is an integer, the number is represented in decimal form
- # as a Number with no decimal point and no leading zeros, preceded by a
- # minus sign (-) if the number is negative
- #
- # otherwise, the number is represented in decimal form as a Number
- # including a decimal point with at least one digit before the decimal
- # point and at least one digit after the decimal point, preceded by a
- # minus sign (-) if the number is negative; there must be no leading zeros
- # before the decimal point apart possibly from the one required digit
- # immediately before the decimal point; beyond the one required digit
- # after the decimal point there must be as many, but only as many, more
- # digits as are needed to uniquely distinguish the number from all other
- # IEEE 754 numeric values.
- #
- # The boolean false value is converted to the string false. The boolean
- # true value is converted to the string true.
- #
- # An object of a type other than the four basic types is converted to a
- # string in a way that is dependent on that type.
- def Functions::string( object=nil )
- #object = @context unless object
- if object.instance_of? Array
- string( object[0] )
- elsif defined? object.node_type
- if object.node_type == :attribute
- object.value
- elsif object.node_type == :element || object.node_type == :document
- string_value(object)
- else
- object.to_s
- end
- elsif object.nil?
- return ""
- else
- object.to_s
- end
- end
-
- # A node-set is converted to a string by
- # returning the concatenation of the string-value
- # of each of the children of the node in the
- # node-set that is first in document order.
- # If the node-set is empty, an empty string is returned.
- def Functions::string_value( o )
- rv = ""
- o.children.each { |e|
- if e.node_type == :text
- rv << e.to_s
- elsif e.node_type == :element
- rv << string_value( e )
- end
- }
- rv
- end
-
- # UNTESTED
- def Functions::concat( *objects )
- objects.join
- end
-
- # Fixed by Mike Stok
- def Functions::starts_with( string, test )
- string(string).index(string(test)) == 0
- end
-
- # Fixed by Mike Stok
- def Functions::contains( string, test )
- string(string).include?(string(test))
- end
-
- # Kouhei fixed this
- def Functions::substring_before( string, test )
- ruby_string = string(string)
- ruby_index = ruby_string.index(string(test))
- if ruby_index.nil?
- ""
- else
- ruby_string[ 0...ruby_index ]
- end
- end
-
- # Kouhei fixed this too
- def Functions::substring_after( string, test )
- ruby_string = string(string)
- return $1 if ruby_string =~ /#{test}(.*)/
- ""
- end
-
- # Take equal portions of Mike Stok and Sean Russell; mix
- # vigorously, and pour into a tall, chilled glass. Serves 10,000.
- def Functions::substring( string, start, length=nil )
- ruby_string = string(string)
- ruby_length = if length.nil?
- ruby_string.length.to_f
- else
- number(length)
- end
- ruby_start = number(start)
-
- # Handle the special cases
- return '' if (
- ruby_length.nan? or
- ruby_start.nan? or
- ruby_start.infinite?
- )
-
- infinite_length = ruby_length.infinite? == 1
- ruby_length = ruby_string.length if infinite_length
-
- # Now, get the bounds. The XPath bounds are 1..length; the ruby bounds
- # are 0..length. Therefore, we have to offset the bounds by one.
- ruby_start = round(ruby_start) - 1
- ruby_length = round(ruby_length)
-
- if ruby_start < 0
- ruby_length += ruby_start unless infinite_length
- ruby_start = 0
- end
- return '' if ruby_length <= 0
- ruby_string[ruby_start,ruby_length]
- end
-
- # UNTESTED
- def Functions::string_length( string )
- string(string).length
- end
-
- # UNTESTED
- def Functions::normalize_space( string=nil )
- string = string(@@context[:node]) if string.nil?
- if string.kind_of? Array
- string.collect{|x| string.to_s.strip.gsub(/\s+/um, ' ') if string}
- else
- string.to_s.strip.gsub(/\s+/um, ' ')
- end
- end
-
- # This is entirely Mike Stok's beast
- def Functions::translate( string, tr1, tr2 )
- from = string(tr1)
- to = string(tr2)
-
- # the map is our translation table.
- #
- # if a character occurs more than once in the
- # from string then we ignore the second &
- # subsequent mappings
- #
- # if a character maps to nil then we delete it
- # in the output. This happens if the from
- # string is longer than the to string
- #
- # there's nothing about - or ^ being special in
- # http://www.w3.org/TR/xpath#function-translate
- # so we don't build ranges or negated classes
-
- map = Hash.new
- 0.upto(from.length - 1) { |pos|
- from_char = from[pos]
- unless map.has_key? from_char
- map[from_char] =
- if pos < to.length
- to[pos]
- else
- nil
- end
- end
- }
-
- if ''.respond_to? :chars
- string(string).chars.collect { |c|
- if map.has_key? c then map[c] else c end
- }.compact.join
- else
- string(string).unpack('U*').collect { |c|
- if map.has_key? c then map[c] else c end
- }.compact.pack('U*')
- end
- end
-
- # UNTESTED
- def Functions::boolean( object=nil )
- if object.kind_of? String
- if object =~ /\d+/u
- return object.to_f != 0
- else
- return object.size > 0
- end
- elsif object.kind_of? Array
- object = object.find{|x| x and true}
- end
- return object ? true : false
- end
-
- # UNTESTED
- def Functions::not( object )
- not boolean( object )
- end
-
- # UNTESTED
- def Functions::true( )
- true
- end
-
- # UNTESTED
- def Functions::false( )
- false
- end
-
- # UNTESTED
- def Functions::lang( language )
- lang = false
- node = @@context[:node]
- attr = nil
- until node.nil?
- if node.node_type == :element
- attr = node.attributes["xml:lang"]
- unless attr.nil?
- lang = compare_language(string(language), attr)
- break
- else
- end
- end
- node = node.parent
- end
- lang
- end
-
- def Functions::compare_language lang1, lang2
- lang2.downcase.index(lang1.downcase) == 0
- end
-
- # a string that consists of optional whitespace followed by an optional
- # minus sign followed by a Number followed by whitespace is converted to
- # the IEEE 754 number that is nearest (according to the IEEE 754
- # round-to-nearest rule) to the mathematical value represented by the
- # string; any other string is converted to NaN
- #
- # boolean true is converted to 1; boolean false is converted to 0
- #
- # a node-set is first converted to a string as if by a call to the string
- # function and then converted in the same way as a string argument
- #
- # an object of a type other than the four basic types is converted to a
- # number in a way that is dependent on that type
- def Functions::number( object=nil )
- object = @@context[:node] unless object
- case object
- when true
- Float(1)
- when false
- Float(0)
- when Array
- number(string( object ))
- when Numeric
- object.to_f
- else
- str = string( object )
- # If XPath ever gets scientific notation...
- #if str =~ /^\s*-?(\d*\.?\d+|\d+\.)([Ee]\d*)?\s*$/
- if str =~ /^\s*-?(\d*\.?\d+|\d+\.)\s*$/
- str.to_f
- else
- (0.0 / 0.0)
- end
- end
- end
-
- def Functions::sum( nodes )
- nodes = [nodes] unless nodes.kind_of? Array
- nodes.inject(0) { |r,n| r + number(string(n)) }
- end
-
- def Functions::floor( number )
- number(number).floor
- end
-
- def Functions::ceiling( number )
- number(number).ceil
- end
-
- def Functions::round( number )
- number = number(number)
- begin
- neg = number.negative?
- number = number.abs.round(half: :up)
- neg ? -number : number
- rescue FloatDomainError
- number
- end
- end
-
- def Functions::processing_instruction( node )
- node.node_type == :processing_instruction
- end
-
- def Functions::send(name, *args)
- if @@available_functions[name.to_sym]
- super
- else
- # TODO: Maybe, this is not XPath spec behavior.
- # This behavior must be reconsidered.
- XPath.match(@@context[:node], name.to_s)
- end
- end
- end
-end
diff --git a/lib/rexml/instruction.rb b/lib/rexml/instruction.rb
deleted file mode 100644
index 576939ca2b..0000000000
--- a/lib/rexml/instruction.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: false
-require "rexml/child"
-require "rexml/source"
-
-module REXML
- # Represents an XML Instruction; IE, <? ... ?>
- # TODO: Add parent arg (3rd arg) to constructor
- class Instruction < Child
- START = '<\?'
- STOP = '\?>'
-
- # target is the "name" of the Instruction; IE, the "tag" in <?tag ...?>
- # content is everything else.
- attr_accessor :target, :content
-
- # Constructs a new Instruction
- # @param target can be one of a number of things. If String, then
- # the target of this instruction is set to this. If an Instruction,
- # then the Instruction is shallowly cloned (target and content are
- # copied). If a Source, then the source is scanned and parsed for
- # an Instruction declaration.
- # @param content Must be either a String, or a Parent. Can only
- # be a Parent if the target argument is a Source. Otherwise, this
- # String is set as the content of this instruction.
- def initialize(target, content=nil)
- if target.kind_of? String
- super()
- @target = target
- @content = content
- elsif target.kind_of? Instruction
- super(content)
- @target = target.target
- @content = target.content
- end
- @content.strip! if @content
- end
-
- def clone
- Instruction.new self
- end
-
- # == DEPRECATED
- # See the rexml/formatters package
- #
- def write writer, indent=-1, transitive=false, ie_hack=false
- Kernel.warn( "#{self.class.name}.write is deprecated" )
- indent(writer, indent)
- writer << START.sub(/\\/u, '')
- writer << @target
- writer << ' '
- writer << @content
- writer << STOP.sub(/\\/u, '')
- end
-
- # @return true if other is an Instruction, and the content and target
- # of the other matches the target and content of this object.
- def ==( other )
- other.kind_of? Instruction and
- other.target == @target and
- other.content == @content
- end
-
- def node_type
- :processing_instruction
- end
-
- def inspect
- "<?p-i #{target} ...?>"
- end
- end
-end
diff --git a/lib/rexml/light/node.rb b/lib/rexml/light/node.rb
deleted file mode 100644
index d58119a3a4..0000000000
--- a/lib/rexml/light/node.rb
+++ /dev/null
@@ -1,196 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/xmltokens'
-
-# [ :element, parent, name, attributes, children* ]
- # a = Node.new
- # a << "B" # => <a>B</a>
- # a.b # => <a>B<b/></a>
- # a.b[1] # => <a>B<b/><b/><a>
- # a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
- # a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
- # a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
-module REXML
- module Light
- # Represents a tagged XML element. Elements are characterized by
- # having children, attributes, and names, and can themselves be
- # children.
- class Node
- NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
- PARENTS = [ :element, :document, :doctype ]
- # Create a new element.
- def initialize node=nil
- @node = node
- if node.kind_of? String
- node = [ :text, node ]
- elsif node.nil?
- node = [ :document, nil, nil ]
- elsif node[0] == :start_element
- node[0] = :element
- elsif node[0] == :start_doctype
- node[0] = :doctype
- elsif node[0] == :start_document
- node[0] = :document
- end
- end
-
- def size
- if PARENTS.include? @node[0]
- @node[-1].size
- else
- 0
- end
- end
-
- def each
- size.times { |x| yield( at(x+4) ) }
- end
-
- def name
- at(2)
- end
-
- def name=( name_str, ns=nil )
- pfx = ''
- pfx = "#{prefix(ns)}:" if ns
- _old_put(2, "#{pfx}#{name_str}")
- end
-
- def parent=( node )
- _old_put(1,node)
- end
-
- def local_name
- namesplit
- @name
- end
-
- def local_name=( name_str )
- _old_put( 1, "#@prefix:#{name_str}" )
- end
-
- def prefix( namespace=nil )
- prefix_of( self, namespace )
- end
-
- def namespace( prefix=prefix() )
- namespace_of( self, prefix )
- end
-
- def namespace=( namespace )
- @prefix = prefix( namespace )
- pfx = ''
- pfx = "#@prefix:" if @prefix.size > 0
- _old_put(1, "#{pfx}#@name")
- end
-
- def []( reference, ns=nil )
- if reference.kind_of? String
- pfx = ''
- pfx = "#{prefix(ns)}:" if ns
- at(3)["#{pfx}#{reference}"]
- elsif reference.kind_of? Range
- _old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
- else
- _old_get( 4+reference )
- end
- end
-
- def =~( path )
- XPath.match( self, path )
- end
-
- # Doesn't handle namespaces yet
- def []=( reference, ns, value=nil )
- if reference.kind_of? String
- value = ns unless value
- at( 3 )[reference] = value
- elsif reference.kind_of? Range
- _old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
- else
- if value
- _old_put( 4+reference, ns, value )
- else
- _old_put( 4+reference, ns )
- end
- end
- end
-
- # Append a child to this element, optionally under a provided namespace.
- # The namespace argument is ignored if the element argument is an Element
- # object. Otherwise, the element argument is a string, the namespace (if
- # provided) is the namespace the element is created in.
- def << element
- if node_type() == :text
- at(-1) << element
- else
- newnode = Node.new( element )
- newnode.parent = self
- self.push( newnode )
- end
- at(-1)
- end
-
- def node_type
- _old_get(0)
- end
-
- def text=( foo )
- replace = at(4).kind_of?(String)? 1 : 0
- self._old_put(4,replace, normalizefoo)
- end
-
- def root
- context = self
- context = context.at(1) while context.at(1)
- end
-
- def has_name?( name, namespace = '' )
- at(3) == name and namespace() == namespace
- end
-
- def children
- self
- end
-
- def parent
- at(1)
- end
-
- def to_s
-
- end
-
- private
-
- def namesplit
- return if @name.defined?
- at(2) =~ NAMESPLIT
- @prefix = '' || $1
- @name = $2
- end
-
- def namespace_of( node, prefix=nil )
- if not prefix
- name = at(2)
- name =~ NAMESPLIT
- prefix = $1
- end
- to_find = 'xmlns'
- to_find = "xmlns:#{prefix}" if not prefix.nil?
- ns = at(3)[ to_find ]
- ns ? ns : namespace_of( @node[0], prefix )
- end
-
- def prefix_of( node, namespace=nil )
- if not namespace
- name = node.name
- name =~ NAMESPLIT
- $1
- else
- ns = at(3).find { |k,v| v == namespace }
- ns ? ns : prefix_of( node.parent, namespace )
- end
- end
- end
- end
-end
diff --git a/lib/rexml/namespace.rb b/lib/rexml/namespace.rb
deleted file mode 100644
index 90ba7cc635..0000000000
--- a/lib/rexml/namespace.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/xmltokens'
-
-module REXML
- # Adds named attributes to an object.
- module Namespace
- # The name of the object, valid if set
- attr_reader :name, :expanded_name
- # The expanded name of the object, valid if name is set
- attr_accessor :prefix
- include XMLTokens
- NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u
-
- # Sets the name and the expanded name
- def name=( name )
- @expanded_name = name
- name =~ NAMESPLIT
- if $1
- @prefix = $1
- else
- @prefix = ""
- @namespace = ""
- end
- @name = $2
- end
-
- # Compares names optionally WITH namespaces
- def has_name?( other, ns=nil )
- if ns
- return (namespace() == ns and name() == other)
- elsif other.include? ":"
- return fully_expanded_name == other
- else
- return name == other
- end
- end
-
- alias :local_name :name
-
- # Fully expand the name, even if the prefix wasn't specified in the
- # source file.
- def fully_expanded_name
- ns = prefix
- return "#{ns}:#@name" if ns.size > 0
- return @name
- end
- end
-end
diff --git a/lib/rexml/node.rb b/lib/rexml/node.rb
deleted file mode 100644
index c7a3936799..0000000000
--- a/lib/rexml/node.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-# frozen_string_literal: false
-require "rexml/parseexception"
-require "rexml/formatters/pretty"
-require "rexml/formatters/default"
-
-module REXML
- # Represents a node in the tree. Nodes are never encountered except as
- # superclasses of other objects. Nodes have siblings.
- module Node
- # @return the next sibling (nil if unset)
- def next_sibling_node
- return nil if @parent.nil?
- @parent[ @parent.index(self) + 1 ]
- end
-
- # @return the previous sibling (nil if unset)
- def previous_sibling_node
- return nil if @parent.nil?
- ind = @parent.index(self)
- return nil if ind == 0
- @parent[ ind - 1 ]
- end
-
- # indent::
- # *DEPRECATED* This parameter is now ignored. See the formatters in the
- # REXML::Formatters package for changing the output style.
- def to_s indent=nil
- unless indent.nil?
- Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated" )
- f = REXML::Formatters::Pretty.new( indent )
- f.write( self, rv = "" )
- else
- f = REXML::Formatters::Default.new
- f.write( self, rv = "" )
- end
- return rv
- end
-
- def indent to, ind
- if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
- indentstyle = @parent.context[:indentstyle]
- else
- indentstyle = ' '
- end
- to << indentstyle*ind unless ind<1
- end
-
- def parent?
- false;
- end
-
-
- # Visit all subnodes of +self+ recursively
- def each_recursive(&block) # :yields: node
- self.elements.each {|node|
- block.call(node)
- node.each_recursive(&block)
- }
- end
-
- # Find (and return) first subnode (recursively) for which the block
- # evaluates to true. Returns +nil+ if none was found.
- def find_first_recursive(&block) # :yields: node
- each_recursive {|node|
- return node if block.call(node)
- }
- return nil
- end
-
- # Returns the position that +self+ holds in its parent's array, indexed
- # from 1.
- def index_in_parent
- parent.index(self)+1
- end
- end
-end
diff --git a/lib/rexml/output.rb b/lib/rexml/output.rb
deleted file mode 100644
index 96dfea570e..0000000000
--- a/lib/rexml/output.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/encoding'
-
-module REXML
- class Output
- include Encoding
-
- attr_reader :encoding
-
- def initialize real_IO, encd="iso-8859-1"
- @output = real_IO
- self.encoding = encd
-
- @to_utf = encoding != 'UTF-8'
-
- if encoding == "UTF-16"
- @output << "\ufeff".encode("UTF-16BE")
- self.encoding = "UTF-16BE"
- end
- end
-
- def <<( content )
- @output << (@to_utf ? self.encode(content) : content)
- end
-
- def to_s
- "Output[#{encoding}]"
- end
- end
-end
diff --git a/lib/rexml/parent.rb b/lib/rexml/parent.rb
deleted file mode 100644
index 3bd0a96255..0000000000
--- a/lib/rexml/parent.rb
+++ /dev/null
@@ -1,166 +0,0 @@
-# frozen_string_literal: false
-require "rexml/child"
-
-module REXML
- # A parent has children, and has methods for accessing them. The Parent
- # class is never encountered except as the superclass for some other
- # object.
- class Parent < Child
- include Enumerable
-
- # Constructor
- # @param parent if supplied, will be set as the parent of this object
- def initialize parent=nil
- super(parent)
- @children = []
- end
-
- def add( object )
- object.parent = self
- @children << object
- object
- end
-
- alias :push :add
- alias :<< :push
-
- def unshift( object )
- object.parent = self
- @children.unshift object
- end
-
- def delete( object )
- found = false
- @children.delete_if {|c| c.equal?(object) and found = true }
- object.parent = nil if found
- found ? object : nil
- end
-
- def each(&block)
- @children.each(&block)
- end
-
- def delete_if( &block )
- @children.delete_if(&block)
- end
-
- def delete_at( index )
- @children.delete_at index
- end
-
- def each_index( &block )
- @children.each_index(&block)
- end
-
- # Fetches a child at a given index
- # @param index the Integer index of the child to fetch
- def []( index )
- @children[index]
- end
-
- alias :each_child :each
-
-
-
- # Set an index entry. See Array.[]=
- # @param index the index of the element to set
- # @param opt either the object to set, or an Integer length
- # @param child if opt is an Integer, this is the child to set
- # @return the parent (self)
- def []=( *args )
- args[-1].parent = self
- @children[*args[0..-2]] = args[-1]
- end
-
- # Inserts an child before another child
- # @param child1 this is either an xpath or an Element. If an Element,
- # child2 will be inserted before child1 in the child list of the parent.
- # If an xpath, child2 will be inserted before the first child to match
- # the xpath.
- # @param child2 the child to insert
- # @return the parent (self)
- def insert_before( child1, child2 )
- if child1.kind_of? String
- child1 = XPath.first( self, child1 )
- child1.parent.insert_before child1, child2
- else
- ind = index(child1)
- child2.parent.delete(child2) if child2.parent
- @children[ind,0] = child2
- child2.parent = self
- end
- self
- end
-
- # Inserts an child after another child
- # @param child1 this is either an xpath or an Element. If an Element,
- # child2 will be inserted after child1 in the child list of the parent.
- # If an xpath, child2 will be inserted after the first child to match
- # the xpath.
- # @param child2 the child to insert
- # @return the parent (self)
- def insert_after( child1, child2 )
- if child1.kind_of? String
- child1 = XPath.first( self, child1 )
- child1.parent.insert_after child1, child2
- else
- ind = index(child1)+1
- child2.parent.delete(child2) if child2.parent
- @children[ind,0] = child2
- child2.parent = self
- end
- self
- end
-
- def to_a
- @children.dup
- end
-
- # Fetches the index of a given child
- # @param child the child to get the index of
- # @return the index of the child, or nil if the object is not a child
- # of this parent.
- def index( child )
- count = -1
- @children.find { |i| count += 1 ; i.hash == child.hash }
- count
- end
-
- # @return the number of children of this parent
- def size
- @children.size
- end
-
- alias :length :size
-
- # Replaces one child with another, making sure the nodelist is correct
- # @param to_replace the child to replace (must be a Child)
- # @param replacement the child to insert into the nodelist (must be a
- # Child)
- def replace_child( to_replace, replacement )
- @children.map! {|c| c.equal?( to_replace ) ? replacement : c }
- to_replace.parent = nil
- replacement.parent = self
- end
-
- # Deeply clones this object. This creates a complete duplicate of this
- # Parent, including all descendants.
- def deep_clone
- cl = clone()
- each do |child|
- if child.kind_of? Parent
- cl << child.deep_clone
- else
- cl << child.clone
- end
- end
- cl
- end
-
- alias :children :to_a
-
- def parent?
- true
- end
- end
-end
diff --git a/lib/rexml/parseexception.rb b/lib/rexml/parseexception.rb
deleted file mode 100644
index 7b16cd1a41..0000000000
--- a/lib/rexml/parseexception.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: false
-module REXML
- class ParseException < RuntimeError
- attr_accessor :source, :parser, :continued_exception
-
- def initialize( message, source=nil, parser=nil, exception=nil )
- super(message)
- @source = source
- @parser = parser
- @continued_exception = exception
- end
-
- def to_s
- # Quote the original exception, if there was one
- if @continued_exception
- err = @continued_exception.inspect
- err << "\n"
- err << @continued_exception.backtrace.join("\n")
- err << "\n...\n"
- else
- err = ""
- end
-
- # Get the stack trace and error message
- err << super
-
- # Add contextual information
- if @source
- err << "\nLine: #{line}\n"
- err << "Position: #{position}\n"
- err << "Last 80 unconsumed characters:\n"
- err << @source.buffer[0..80].force_encoding("ASCII-8BIT").gsub(/\n/, ' ')
- end
-
- err
- end
-
- def position
- @source.current_line[0] if @source and defined? @source.current_line and
- @source.current_line
- end
-
- def line
- @source.current_line[2] if @source and defined? @source.current_line and
- @source.current_line
- end
-
- def context
- @source.current_line
- end
- end
-end
diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
deleted file mode 100644
index 80eeb0fa79..0000000000
--- a/lib/rexml/parsers/baseparser.rb
+++ /dev/null
@@ -1,533 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/parseexception'
-require 'rexml/undefinednamespaceexception'
-require 'rexml/source'
-require 'set'
-
-module REXML
- module Parsers
- # = Using the Pull Parser
- # <em>This API is experimental, and subject to change.</em>
- # parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
- # while parser.has_next?
- # res = parser.next
- # puts res[1]['att'] if res.start_tag? and res[0] == 'b'
- # end
- # See the PullEvent class for information on the content of the results.
- # The data is identical to the arguments passed for the various events to
- # the StreamListener API.
- #
- # Notice that:
- # parser = PullParser.new( "<a>BAD DOCUMENT" )
- # while parser.has_next?
- # res = parser.next
- # raise res[1] if res.error?
- # end
- #
- # Nat Price gave me some good ideas for the API.
- class BaseParser
- LETTER = '[:alpha:]'
- DIGIT = '[:digit:]'
-
- COMBININGCHAR = '' # TODO
- EXTENDER = '' # TODO
-
- NCNAME_STR= "[#{LETTER}_:][-[:alnum:]._:#{COMBININGCHAR}#{EXTENDER}]*"
- NAME_STR= "(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})"
- UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
-
- NAMECHAR = '[\-\w\.:]'
- NAME = "([\\w:]#{NAMECHAR}*)"
- NMTOKEN = "(?:#{NAMECHAR})+"
- NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
- REFERENCE = "&(?:#{NAME};|#\\d+;|#x[0-9a-fA-F]+;)"
- REFERENCE_RE = /#{REFERENCE}/
-
- DOCTYPE_START = /\A\s*<!DOCTYPE\s/um
- DOCTYPE_END = /\A\s*\]\s*>/um
- DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um
- ATTRIBUTE_PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\4/um
- COMMENT_START = /\A<!--/u
- COMMENT_PATTERN = /<!--(.*?)-->/um
- CDATA_START = /\A<!\[CDATA\[/u
- CDATA_END = /\A\s*\]\s*>/um
- CDATA_PATTERN = /<!\[CDATA\[(.*?)\]\]>/um
- XMLDECL_START = /\A<\?xml\s/u;
- XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>/um
- INSTRUCTION_START = /\A<\?/u
- INSTRUCTION_PATTERN = /<\?(.*?)(\s+.*?)?\?>/um
- TAG_MATCH = /^<((?>#{NAME_STR}))\s*((?>\s+#{UNAME_STR}\s*=\s*(["']).*?\5)*)\s*(\/)?>/um
- CLOSE_MATCH = /^\s*<\/(#{NAME_STR})\s*>/um
-
- VERSION = /\bversion\s*=\s*["'](.*?)['"]/um
- ENCODING = /\bencoding\s*=\s*["'](.*?)['"]/um
- STANDALONE = /\bstandalone\s*=\s*["'](.*?)['"]/um
-
- ENTITY_START = /\A\s*<!ENTITY/
- IDENTITY = /^([!\*\w\-]+)(\s+#{NCNAME_STR})?(\s+["'](.*?)['"])?(\s+['"](.*?)["'])?/u
- ELEMENTDECL_START = /\A\s*<!ELEMENT/um
- ELEMENTDECL_PATTERN = /\A\s*(<!ELEMENT.*?)>/um
- SYSTEMENTITY = /\A\s*(%.*?;)\s*$/um
- ENUMERATION = "\\(\\s*#{NMTOKEN}(?:\\s*\\|\\s*#{NMTOKEN})*\\s*\\)"
- NOTATIONTYPE = "NOTATION\\s+\\(\\s*#{NAME}(?:\\s*\\|\\s*#{NAME})*\\s*\\)"
- ENUMERATEDTYPE = "(?:(?:#{NOTATIONTYPE})|(?:#{ENUMERATION}))"
- ATTTYPE = "(CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|#{ENUMERATEDTYPE})"
- ATTVALUE = "(?:\"((?:[^<&\"]|#{REFERENCE})*)\")|(?:'((?:[^<&']|#{REFERENCE})*)')"
- DEFAULTDECL = "(#REQUIRED|#IMPLIED|(?:(#FIXED\\s+)?#{ATTVALUE}))"
- ATTDEF = "\\s+#{NAME}\\s+#{ATTTYPE}\\s+#{DEFAULTDECL}"
- ATTDEF_RE = /#{ATTDEF}/
- ATTLISTDECL_START = /\A\s*<!ATTLIST/um
- ATTLISTDECL_PATTERN = /\A\s*<!ATTLIST\s+#{NAME}(?:#{ATTDEF})*\s*>/um
- NOTATIONDECL_START = /\A\s*<!NOTATION/um
- PUBLIC = /\A\s*<!NOTATION\s+(\w[\-\w]*)\s+(PUBLIC)\s+(["'])(.*?)\3(?:\s+(["'])(.*?)\5)?\s*>/um
- SYSTEM = /\A\s*<!NOTATION\s+(\w[\-\w]*)\s+(SYSTEM)\s+(["'])(.*?)\3\s*>/um
-
- TEXT_PATTERN = /\A([^<]*)/um
-
- # Entity constants
- PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#"
- SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))}
- PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')}
- EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
- NDATADECL = "\\s+NDATA\\s+#{NAME}"
- PEREFERENCE = "%#{NAME};"
- ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
- PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
- ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
- PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
- GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
- ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
-
- EREFERENCE = /&(?!#{NAME};)/
-
- DEFAULT_ENTITIES = {
- 'gt' => [/&gt;/, '&gt;', '>', />/],
- 'lt' => [/&lt;/, '&lt;', '<', /</],
- 'quot' => [/&quot;/, '&quot;', '"', /"/],
- "apos" => [/&apos;/, "&apos;", "'", /'/]
- }
-
-
- ######################################################################
- # These are patterns to identify common markup errors, to make the
- # error messages more informative.
- ######################################################################
- MISSING_ATTRIBUTE_QUOTES = /^<#{NAME_STR}\s+#{NAME_STR}\s*=\s*[^"']/um
-
- def initialize( source )
- self.stream = source
- @listeners = []
- end
-
- def add_listener( listener )
- @listeners << listener
- end
-
- attr_reader :source
-
- def stream=( source )
- @source = SourceFactory.create_from( source )
- @closed = nil
- @document_status = nil
- @tags = []
- @stack = []
- @entities = []
- @nsstack = []
- end
-
- def position
- if @source.respond_to? :position
- @source.position
- else
- # FIXME
- 0
- end
- end
-
- # Returns true if there are no more events
- def empty?
- return (@source.empty? and @stack.empty?)
- end
-
- # Returns true if there are more events. Synonymous with !empty?
- def has_next?
- return !(@source.empty? and @stack.empty?)
- end
-
- # Push an event back on the head of the stream. This method
- # has (theoretically) infinite depth.
- def unshift token
- @stack.unshift(token)
- end
-
- # Peek at the +depth+ event in the stack. The first element on the stack
- # is at depth 0. If +depth+ is -1, will parse to the end of the input
- # stream and return the last event, which is always :end_document.
- # Be aware that this causes the stream to be parsed up to the +depth+
- # event, so you can effectively pre-parse the entire document (pull the
- # entire thing into memory) using this method.
- def peek depth=0
- raise %Q[Illegal argument "#{depth}"] if depth < -1
- temp = []
- if depth == -1
- temp.push(pull()) until empty?
- else
- while @stack.size+temp.size < depth+1
- temp.push(pull())
- end
- end
- @stack += temp if temp.size > 0
- @stack[depth]
- end
-
- # Returns the next event. This is a +PullEvent+ object.
- def pull
- pull_event.tap do |event|
- @listeners.each do |listener|
- listener.receive event
- end
- end
- end
-
- def pull_event
- if @closed
- x, @closed = @closed, nil
- return [ :end_element, x ]
- end
- return [ :end_document ] if empty?
- return @stack.shift if @stack.size > 0
- #STDERR.puts @source.encoding
- @source.read if @source.buffer.size<2
- #STDERR.puts "BUFFER = #{@source.buffer.inspect}"
- if @document_status == nil
- #@source.consume( /^\s*/um )
- word = @source.match( /^((?:\s+)|(?:<[^>]*>))/um )
- word = word[1] unless word.nil?
- #STDERR.puts "WORD = #{word.inspect}"
- case word
- when COMMENT_START
- return [ :comment, @source.match( COMMENT_PATTERN, true )[1] ]
- when XMLDECL_START
- #STDERR.puts "XMLDECL"
- results = @source.match( XMLDECL_PATTERN, true )[1]
- version = VERSION.match( results )
- version = version[1] unless version.nil?
- encoding = ENCODING.match(results)
- encoding = encoding[1] unless encoding.nil?
- if need_source_encoding_update?(encoding)
- @source.encoding = encoding
- end
- if encoding.nil? and /\AUTF-16(?:BE|LE)\z/i =~ @source.encoding
- encoding = "UTF-16"
- end
- standalone = STANDALONE.match(results)
- standalone = standalone[1] unless standalone.nil?
- return [ :xmldecl, version, encoding, standalone ]
- when INSTRUCTION_START
- return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ]
- when DOCTYPE_START
- md = @source.match( DOCTYPE_PATTERN, true )
- @nsstack.unshift(curr_ns=Set.new)
- identity = md[1]
- close = md[2]
- identity =~ IDENTITY
- name = $1
- raise REXML::ParseException.new("DOCTYPE is missing a name") if name.nil?
- pub_sys = $2.nil? ? nil : $2.strip
- long_name = $4.nil? ? nil : $4.strip
- uri = $6.nil? ? nil : $6.strip
- args = [ :start_doctype, name, pub_sys, long_name, uri ]
- if close == ">"
- @document_status = :after_doctype
- @source.read if @source.buffer.size<2
- md = @source.match(/^\s*/um, true)
- @stack << [ :end_doctype ]
- else
- @document_status = :in_doctype
- end
- return args
- when /^\s+/
- else
- @document_status = :after_doctype
- @source.read if @source.buffer.size<2
- md = @source.match(/\s*/um, true)
- if @source.encoding == "UTF-8"
- @source.buffer.force_encoding(::Encoding::UTF_8)
- end
- end
- end
- if @document_status == :in_doctype
- md = @source.match(/\s*(.*?>)/um)
- case md[1]
- when SYSTEMENTITY
- match = @source.match( SYSTEMENTITY, true )[1]
- return [ :externalentity, match ]
-
- when ELEMENTDECL_START
- return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ]
-
- when ENTITY_START
- match = @source.match( ENTITYDECL, true ).to_a.compact
- match[0] = :entitydecl
- ref = false
- if match[1] == '%'
- ref = true
- match.delete_at 1
- end
- # Now we have to sort out what kind of entity reference this is
- if match[2] == 'SYSTEM'
- # External reference
- match[3] = match[3][1..-2] # PUBID
- match.delete_at(4) if match.size > 4 # Chop out NDATA decl
- # match is [ :entity, name, SYSTEM, pubid(, ndata)? ]
- elsif match[2] == 'PUBLIC'
- # External reference
- match[3] = match[3][1..-2] # PUBID
- match[4] = match[4][1..-2] # HREF
- match.delete_at(5) if match.size > 5 # Chop out NDATA decl
- # match is [ :entity, name, PUBLIC, pubid, href(, ndata)? ]
- else
- match[2] = match[2][1..-2]
- match.pop if match.size == 4
- # match is [ :entity, name, value ]
- end
- match << '%' if ref
- return match
- when ATTLISTDECL_START
- md = @source.match( ATTLISTDECL_PATTERN, true )
- raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil?
- element = md[1]
- contents = md[0]
-
- pairs = {}
- values = md[0].scan( ATTDEF_RE )
- values.each do |attdef|
- unless attdef[3] == "#IMPLIED"
- attdef.compact!
- val = attdef[3]
- val = attdef[4] if val == "#FIXED "
- pairs[attdef[0]] = val
- if attdef[0] =~ /^xmlns:(.*)/
- @nsstack[0] << $1
- end
- end
- end
- return [ :attlistdecl, element, pairs, contents ]
- when NOTATIONDECL_START
- md = nil
- if @source.match( PUBLIC )
- md = @source.match( PUBLIC, true )
- vals = [md[1],md[2],md[4],md[6]]
- elsif @source.match( SYSTEM )
- md = @source.match( SYSTEM, true )
- vals = [md[1],md[2],nil,md[4]]
- else
- raise REXML::ParseException.new( "error parsing notation: no matching pattern", @source )
- end
- return [ :notationdecl, *vals ]
- when DOCTYPE_END
- @document_status = :after_doctype
- @source.match( DOCTYPE_END, true )
- return [ :end_doctype ]
- end
- end
- begin
- if @source.buffer[0] == ?<
- if @source.buffer[1] == ?/
- @nsstack.shift
- last_tag = @tags.pop
- #md = @source.match_to_consume( '>', CLOSE_MATCH)
- md = @source.match( CLOSE_MATCH, true )
- raise REXML::ParseException.new( "Missing end tag for "+
- "'#{last_tag}' (got \"#{md[1]}\")",
- @source) unless last_tag == md[1]
- return [ :end_element, last_tag ]
- elsif @source.buffer[1] == ?!
- md = @source.match(/\A(\s*[^>]*>)/um)
- #STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}"
- raise REXML::ParseException.new("Malformed node", @source) unless md
- if md[0][2] == ?-
- md = @source.match( COMMENT_PATTERN, true )
-
- case md[1]
- when /--/, /-\z/
- raise REXML::ParseException.new("Malformed comment", @source)
- end
-
- return [ :comment, md[1] ] if md
- else
- md = @source.match( CDATA_PATTERN, true )
- return [ :cdata, md[1] ] if md
- end
- raise REXML::ParseException.new( "Declarations can only occur "+
- "in the doctype declaration.", @source)
- elsif @source.buffer[1] == ??
- md = @source.match( INSTRUCTION_PATTERN, true )
- return [ :processing_instruction, md[1], md[2] ] if md
- raise REXML::ParseException.new( "Bad instruction declaration",
- @source)
- else
- # Get the next tag
- md = @source.match(TAG_MATCH, true)
- unless md
- # Check for missing attribute quotes
- raise REXML::ParseException.new("missing attribute quote", @source) if @source.match(MISSING_ATTRIBUTE_QUOTES )
- raise REXML::ParseException.new("malformed XML: missing tag start", @source)
- end
- attributes = {}
- prefixes = Set.new
- prefixes << md[2] if md[2]
- @nsstack.unshift(curr_ns=Set.new)
- if md[4].size > 0
- attrs = md[4].scan( ATTRIBUTE_PATTERN )
- raise REXML::ParseException.new( "error parsing attributes: [#{attrs.join ', '}], excess = \"#$'\"", @source) if $' and $'.strip.size > 0
- attrs.each do |attr_name, prefix, local_part, quote, value|
- if prefix == "xmlns"
- if local_part == "xml"
- if value != "http://www.w3.org/XML/1998/namespace"
- msg = "The 'xml' prefix must not be bound to any other namespace "+
- "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
- raise REXML::ParseException.new( msg, @source, self )
- end
- elsif local_part == "xmlns"
- msg = "The 'xmlns' prefix must not be declared "+
- "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
- raise REXML::ParseException.new( msg, @source, self)
- end
- curr_ns << local_part
- elsif prefix
- prefixes << prefix unless prefix == "xml"
- end
-
- if attributes.has_key?(attr_name)
- msg = "Duplicate attribute #{attr_name.inspect}"
- raise REXML::ParseException.new(msg, @source, self)
- end
-
- attributes[attr_name] = value
- end
- end
-
- # Verify that all of the prefixes have been defined
- for prefix in prefixes
- unless @nsstack.find{|k| k.member?(prefix)}
- raise UndefinedNamespaceException.new(prefix,@source,self)
- end
- end
-
- if md[6]
- @closed = md[1]
- @nsstack.shift
- else
- @tags.push( md[1] )
- end
- return [ :start_element, md[1], attributes ]
- end
- else
- md = @source.match( TEXT_PATTERN, true )
- if md[0].length == 0
- @source.match( /(\s+)/, true )
- end
- #STDERR.puts "GOT #{md[1].inspect}" unless md[0].length == 0
- #return [ :text, "" ] if md[0].length == 0
- # unnormalized = Text::unnormalize( md[1], self )
- # return PullEvent.new( :text, md[1], unnormalized )
- return [ :text, md[1] ]
- end
- rescue REXML::UndefinedNamespaceException
- raise
- rescue REXML::ParseException
- raise
- rescue Exception, NameError => error
- raise REXML::ParseException.new( "Exception parsing",
- @source, self, (error ? error : $!) )
- end
- return [ :dummy ]
- end
- private :pull_event
-
- def entity( reference, entities )
- value = nil
- value = entities[ reference ] if entities
- if not value
- value = DEFAULT_ENTITIES[ reference ]
- value = value[2] if value
- end
- unnormalize( value, entities ) if value
- end
-
- # Escapes all possible entities
- def normalize( input, entities=nil, entity_filter=nil )
- copy = input.clone
- # Doing it like this rather than in a loop improves the speed
- copy.gsub!( EREFERENCE, '&amp;' )
- entities.each do |key, value|
- copy.gsub!( value, "&#{key};" ) unless entity_filter and
- entity_filter.include?(entity)
- end if entities
- copy.gsub!( EREFERENCE, '&amp;' )
- DEFAULT_ENTITIES.each do |key, value|
- copy.gsub!( value[3], value[1] )
- end
- copy
- end
-
- # Unescapes all possible entities
- def unnormalize( string, entities=nil, filter=nil )
- rv = string.clone
- rv.gsub!( /\r\n?/, "\n" )
- matches = rv.scan( REFERENCE_RE )
- return rv if matches.size == 0
- rv.gsub!( /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {
- m=$1
- m = "0#{m}" if m[0] == ?x
- [Integer(m)].pack('U*')
- }
- matches.collect!{|x|x[0]}.compact!
- if matches.size > 0
- matches.each do |entity_reference|
- unless filter and filter.include?(entity_reference)
- entity_value = entity( entity_reference, entities )
- if entity_value
- re = /&#{entity_reference};/
- rv.gsub!( re, entity_value )
- else
- er = DEFAULT_ENTITIES[entity_reference]
- rv.gsub!( er[0], er[2] ) if er
- end
- end
- end
- rv.gsub!( /&amp;/, '&' )
- end
- rv
- end
-
- private
- def need_source_encoding_update?(xml_declaration_encoding)
- return false if xml_declaration_encoding.nil?
- return false if /\AUTF-16\z/i =~ xml_declaration_encoding
- true
- end
- end
- end
-end
-
-=begin
- case event[0]
- when :start_element
- when :text
- when :end_element
- when :processing_instruction
- when :cdata
- when :comment
- when :xmldecl
- when :start_doctype
- when :end_doctype
- when :externalentity
- when :elementdecl
- when :entity
- when :attlistdecl
- when :notationdecl
- when :end_doctype
- end
-=end
diff --git a/lib/rexml/parsers/lightparser.rb b/lib/rexml/parsers/lightparser.rb
deleted file mode 100644
index f0601ae51b..0000000000
--- a/lib/rexml/parsers/lightparser.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/parsers/streamparser'
-require 'rexml/parsers/baseparser'
-require 'rexml/light/node'
-
-module REXML
- module Parsers
- class LightParser
- def initialize stream
- @stream = stream
- @parser = REXML::Parsers::BaseParser.new( stream )
- end
-
- def add_listener( listener )
- @parser.add_listener( listener )
- end
-
- def rewind
- @stream.rewind
- @parser.stream = @stream
- end
-
- def parse
- root = context = [ :document ]
- while true
- event = @parser.pull
- case event[0]
- when :end_document
- break
- when :start_element, :start_doctype
- new_node = event
- context << new_node
- new_node[1,0] = [context]
- context = new_node
- when :end_element, :end_doctype
- context = context[1]
- else
- new_node = event
- context << new_node
- new_node[1,0] = [context]
- end
- end
- root
- end
- end
-
- # An element is an array. The array contains:
- # 0 The parent element
- # 1 The tag name
- # 2 A hash of attributes
- # 3..-1 The child elements
- # An element is an array of size > 3
- # Text is a String
- # PIs are [ :processing_instruction, target, data ]
- # Comments are [ :comment, data ]
- # DocTypes are DocType structs
- # The root is an array with XMLDecls, Text, DocType, Array, Text
- end
-end
diff --git a/lib/rexml/parsers/pullparser.rb b/lib/rexml/parsers/pullparser.rb
deleted file mode 100644
index 8c49217553..0000000000
--- a/lib/rexml/parsers/pullparser.rb
+++ /dev/null
@@ -1,197 +0,0 @@
-# frozen_string_literal: false
-require 'forwardable'
-
-require 'rexml/parseexception'
-require 'rexml/parsers/baseparser'
-require 'rexml/xmltokens'
-
-module REXML
- module Parsers
- # = Using the Pull Parser
- # <em>This API is experimental, and subject to change.</em>
- # parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
- # while parser.has_next?
- # res = parser.next
- # puts res[1]['att'] if res.start_tag? and res[0] == 'b'
- # end
- # See the PullEvent class for information on the content of the results.
- # The data is identical to the arguments passed for the various events to
- # the StreamListener API.
- #
- # Notice that:
- # parser = PullParser.new( "<a>BAD DOCUMENT" )
- # while parser.has_next?
- # res = parser.next
- # raise res[1] if res.error?
- # end
- #
- # Nat Price gave me some good ideas for the API.
- class PullParser
- include XMLTokens
- extend Forwardable
-
- def_delegators( :@parser, :has_next? )
- def_delegators( :@parser, :entity )
- def_delegators( :@parser, :empty? )
- def_delegators( :@parser, :source )
-
- def initialize stream
- @entities = {}
- @listeners = nil
- @parser = BaseParser.new( stream )
- @my_stack = []
- end
-
- def add_listener( listener )
- @listeners = [] unless @listeners
- @listeners << listener
- end
-
- def each
- while has_next?
- yield self.pull
- end
- end
-
- def peek depth=0
- if @my_stack.length <= depth
- (depth - @my_stack.length + 1).times {
- e = PullEvent.new(@parser.pull)
- @my_stack.push(e)
- }
- end
- @my_stack[depth]
- end
-
- def pull
- return @my_stack.shift if @my_stack.length > 0
-
- event = @parser.pull
- case event[0]
- when :entitydecl
- @entities[ event[1] ] =
- event[2] unless event[2] =~ /PUBLIC|SYSTEM/
- when :text
- unnormalized = @parser.unnormalize( event[1], @entities )
- event << unnormalized
- end
- PullEvent.new( event )
- end
-
- def unshift token
- @my_stack.unshift token
- end
- end
-
- # A parsing event. The contents of the event are accessed as an +Array?,
- # and the type is given either by the ...? methods, or by accessing the
- # +type+ accessor. The contents of this object vary from event to event,
- # but are identical to the arguments passed to +StreamListener+s for each
- # event.
- class PullEvent
- # The type of this event. Will be one of :tag_start, :tag_end, :text,
- # :processing_instruction, :comment, :doctype, :attlistdecl, :entitydecl,
- # :notationdecl, :entity, :cdata, :xmldecl, or :error.
- def initialize(arg)
- @contents = arg
- end
-
- def []( start, endd=nil)
- if start.kind_of? Range
- @contents.slice( start.begin+1 .. start.end )
- elsif start.kind_of? Numeric
- if endd.nil?
- @contents.slice( start+1 )
- else
- @contents.slice( start+1, endd )
- end
- else
- raise "Illegal argument #{start.inspect} (#{start.class})"
- end
- end
-
- def event_type
- @contents[0]
- end
-
- # Content: [ String tag_name, Hash attributes ]
- def start_element?
- @contents[0] == :start_element
- end
-
- # Content: [ String tag_name ]
- def end_element?
- @contents[0] == :end_element
- end
-
- # Content: [ String raw_text, String unnormalized_text ]
- def text?
- @contents[0] == :text
- end
-
- # Content: [ String text ]
- def instruction?
- @contents[0] == :processing_instruction
- end
-
- # Content: [ String text ]
- def comment?
- @contents[0] == :comment
- end
-
- # Content: [ String name, String pub_sys, String long_name, String uri ]
- def doctype?
- @contents[0] == :start_doctype
- end
-
- # Content: [ String text ]
- def attlistdecl?
- @contents[0] == :attlistdecl
- end
-
- # Content: [ String text ]
- def elementdecl?
- @contents[0] == :elementdecl
- end
-
- # Due to the wonders of DTDs, an entity declaration can be just about
- # anything. There's no way to normalize it; you'll have to interpret the
- # content yourself. However, the following is true:
- #
- # * If the entity declaration is an internal entity:
- # [ String name, String value ]
- # Content: [ String text ]
- def entitydecl?
- @contents[0] == :entitydecl
- end
-
- # Content: [ String text ]
- def notationdecl?
- @contents[0] == :notationdecl
- end
-
- # Content: [ String text ]
- def entity?
- @contents[0] == :entity
- end
-
- # Content: [ String text ]
- def cdata?
- @contents[0] == :cdata
- end
-
- # Content: [ String version, String encoding, String standalone ]
- def xmldecl?
- @contents[0] == :xmldecl
- end
-
- def error?
- @contents[0] == :error
- end
-
- def inspect
- @contents[0].to_s + ": " + @contents[1..-1].inspect
- end
- end
- end
-end
diff --git a/lib/rexml/parsers/sax2parser.rb b/lib/rexml/parsers/sax2parser.rb
deleted file mode 100644
index 1386f69c83..0000000000
--- a/lib/rexml/parsers/sax2parser.rb
+++ /dev/null
@@ -1,273 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/parsers/baseparser'
-require 'rexml/parseexception'
-require 'rexml/namespace'
-require 'rexml/text'
-
-module REXML
- module Parsers
- # SAX2Parser
- class SAX2Parser
- def initialize source
- @parser = BaseParser.new(source)
- @listeners = []
- @procs = []
- @namespace_stack = []
- @has_listeners = false
- @tag_stack = []
- @entities = {}
- end
-
- def source
- @parser.source
- end
-
- def add_listener( listener )
- @parser.add_listener( listener )
- end
-
- # Listen arguments:
- #
- # Symbol, Array, Block
- # Listen to Symbol events on Array elements
- # Symbol, Block
- # Listen to Symbol events
- # Array, Listener
- # Listen to all events on Array elements
- # Array, Block
- # Listen to :start_element events on Array elements
- # Listener
- # Listen to All events
- #
- # Symbol can be one of: :start_element, :end_element,
- # :start_prefix_mapping, :end_prefix_mapping, :characters,
- # :processing_instruction, :doctype, :attlistdecl, :elementdecl,
- # :entitydecl, :notationdecl, :cdata, :xmldecl, :comment
- #
- # There is an additional symbol that can be listened for: :progress.
- # This will be called for every event generated, passing in the current
- # stream position.
- #
- # Array contains regular expressions or strings which will be matched
- # against fully qualified element names.
- #
- # Listener must implement the methods in SAX2Listener
- #
- # Block will be passed the same arguments as a SAX2Listener method would
- # be, where the method name is the same as the matched Symbol.
- # See the SAX2Listener for more information.
- def listen( *args, &blok )
- if args[0].kind_of? Symbol
- if args.size == 2
- args[1].each { |match| @procs << [args[0], match, blok] }
- else
- add( [args[0], nil, blok] )
- end
- elsif args[0].kind_of? Array
- if args.size == 2
- args[0].each { |match| add( [nil, match, args[1]] ) }
- else
- args[0].each { |match| add( [ :start_element, match, blok ] ) }
- end
- else
- add([nil, nil, args[0]])
- end
- end
-
- def deafen( listener=nil, &blok )
- if listener
- @listeners.delete_if {|item| item[-1] == listener }
- @has_listeners = false if @listeners.size == 0
- else
- @procs.delete_if {|item| item[-1] == blok }
- end
- end
-
- def parse
- @procs.each { |sym,match,block| block.call if sym == :start_document }
- @listeners.each { |sym,match,block|
- block.start_document if sym == :start_document or sym.nil?
- }
- context = []
- while true
- event = @parser.pull
- case event[0]
- when :end_document
- handle( :end_document )
- break
- when :start_doctype
- handle( :doctype, *event[1..-1])
- when :end_doctype
- context = context[1]
- when :start_element
- @tag_stack.push(event[1])
- # find the observers for namespaces
- procs = get_procs( :start_prefix_mapping, event[1] )
- listeners = get_listeners( :start_prefix_mapping, event[1] )
- if procs or listeners
- # break out the namespace declarations
- # The attributes live in event[2]
- event[2].each {|n, v| event[2][n] = @parser.normalize(v)}
- nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }
- nsdecl.collect! { |n, value| [ n[6..-1], value ] }
- @namespace_stack.push({})
- nsdecl.each do |n,v|
- @namespace_stack[-1][n] = v
- # notify observers of namespaces
- procs.each { |ob| ob.call( n, v ) } if procs
- listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners
- end
- end
- event[1] =~ Namespace::NAMESPLIT
- prefix = $1
- local = $2
- uri = get_namespace(prefix)
- # find the observers for start_element
- procs = get_procs( :start_element, event[1] )
- listeners = get_listeners( :start_element, event[1] )
- # notify observers
- procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs
- listeners.each { |ob|
- ob.start_element( uri, local, event[1], event[2] )
- } if listeners
- when :end_element
- @tag_stack.pop
- event[1] =~ Namespace::NAMESPLIT
- prefix = $1
- local = $2
- uri = get_namespace(prefix)
- # find the observers for start_element
- procs = get_procs( :end_element, event[1] )
- listeners = get_listeners( :end_element, event[1] )
- # notify observers
- procs.each { |ob| ob.call( uri, local, event[1] ) } if procs
- listeners.each { |ob|
- ob.end_element( uri, local, event[1] )
- } if listeners
-
- namespace_mapping = @namespace_stack.pop
- # find the observers for namespaces
- procs = get_procs( :end_prefix_mapping, event[1] )
- listeners = get_listeners( :end_prefix_mapping, event[1] )
- if procs or listeners
- namespace_mapping.each do |ns_prefix, ns_uri|
- # notify observers of namespaces
- procs.each { |ob| ob.call( ns_prefix ) } if procs
- listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners
- end
- end
- when :text
- #normalized = @parser.normalize( event[1] )
- #handle( :characters, normalized )
- copy = event[1].clone
-
- esub = proc { |match|
- if @entities.has_key?($1)
- @entities[$1].gsub(Text::REFERENCE, &esub)
- else
- match
- end
- }
-
- copy.gsub!( Text::REFERENCE, &esub )
- copy.gsub!( Text::NUMERICENTITY ) {|m|
- m=$1
- m = "0#{m}" if m[0] == ?x
- [Integer(m)].pack('U*')
- }
- handle( :characters, copy )
- when :entitydecl
- handle_entitydecl( event )
- when :processing_instruction, :comment, :attlistdecl,
- :elementdecl, :cdata, :notationdecl, :xmldecl
- handle( *event )
- end
- handle( :progress, @parser.position )
- end
- end
-
- private
- def handle( symbol, *arguments )
- tag = @tag_stack[-1]
- procs = get_procs( symbol, tag )
- listeners = get_listeners( symbol, tag )
- # notify observers
- procs.each { |ob| ob.call( *arguments ) } if procs
- listeners.each { |l|
- l.send( symbol.to_s, *arguments )
- } if listeners
- end
-
- def handle_entitydecl( event )
- @entities[ event[1] ] = event[2] if event.size == 3
- parameter_reference_p = false
- case event[2]
- when "SYSTEM"
- if event.size == 5
- if event.last == "%"
- parameter_reference_p = true
- else
- event[4, 0] = "NDATA"
- end
- end
- when "PUBLIC"
- if event.size == 6
- if event.last == "%"
- parameter_reference_p = true
- else
- event[5, 0] = "NDATA"
- end
- end
- else
- parameter_reference_p = (event.size == 4)
- end
- event[1, 0] = event.pop if parameter_reference_p
- handle( event[0], event[1..-1] )
- end
-
- # The following methods are duplicates, but it is faster than using
- # a helper
- def get_procs( symbol, name )
- return nil if @procs.size == 0
- @procs.find_all do |sym, match, block|
- (
- (sym.nil? or symbol == sym) and
- ((name.nil? and match.nil?) or match.nil? or (
- (name == match) or
- (match.kind_of? Regexp and name =~ match)
- )
- )
- )
- end.collect{|x| x[-1]}
- end
- def get_listeners( symbol, name )
- return nil if @listeners.size == 0
- @listeners.find_all do |sym, match, block|
- (
- (sym.nil? or symbol == sym) and
- ((name.nil? and match.nil?) or match.nil? or (
- (name == match) or
- (match.kind_of? Regexp and name =~ match)
- )
- )
- )
- end.collect{|x| x[-1]}
- end
-
- def add( pair )
- if pair[-1].respond_to? :call
- @procs << pair unless @procs.include? pair
- else
- @listeners << pair unless @listeners.include? pair
- @has_listeners = true
- end
- end
-
- def get_namespace( prefix )
- uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) ||
- (@namespace_stack.find { |ns| not ns[nil].nil? })
- uris[-1][prefix] unless uris.nil? or 0 == uris.size
- end
- end
- end
-end
diff --git a/lib/rexml/parsers/streamparser.rb b/lib/rexml/parsers/streamparser.rb
deleted file mode 100644
index f6a8bfa802..0000000000
--- a/lib/rexml/parsers/streamparser.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: false
-require "rexml/parsers/baseparser"
-
-module REXML
- module Parsers
- class StreamParser
- def initialize source, listener
- @listener = listener
- @parser = BaseParser.new( source )
- @tag_stack = []
- end
-
- def add_listener( listener )
- @parser.add_listener( listener )
- end
-
- def parse
- # entity string
- while true
- event = @parser.pull
- case event[0]
- when :end_document
- unless @tag_stack.empty?
- tag_path = "/" + @tag_stack.join("/")
- raise ParseException.new("Missing end tag for '#{tag_path}'",
- @parser.source)
- end
- return
- when :start_element
- @tag_stack << event[1]
- attrs = event[2].each do |n, v|
- event[2][n] = @parser.unnormalize( v )
- end
- @listener.tag_start( event[1], attrs )
- when :end_element
- @listener.tag_end( event[1] )
- @tag_stack.pop
- when :text
- normalized = @parser.unnormalize( event[1] )
- @listener.text( normalized )
- when :processing_instruction
- @listener.instruction( *event[1,2] )
- when :start_doctype
- @listener.doctype( *event[1..-1] )
- when :end_doctype
- # FIXME: remove this condition for milestone:3.2
- @listener.doctype_end if @listener.respond_to? :doctype_end
- when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl
- @listener.send( event[0].to_s, *event[1..-1] )
- when :entitydecl, :notationdecl
- @listener.send( event[0].to_s, event[1..-1] )
- when :externalentity
- entity_reference = event[1]
- content = entity_reference.gsub(/\A%|;\z/, "")
- @listener.entity(content)
- end
- end
- end
- end
- end
-end
diff --git a/lib/rexml/parsers/treeparser.rb b/lib/rexml/parsers/treeparser.rb
deleted file mode 100644
index fc0993c72a..0000000000
--- a/lib/rexml/parsers/treeparser.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/validation/validationexception'
-require 'rexml/undefinednamespaceexception'
-
-module REXML
- module Parsers
- class TreeParser
- def initialize( source, build_context = Document.new )
- @build_context = build_context
- @parser = Parsers::BaseParser.new( source )
- end
-
- def add_listener( listener )
- @parser.add_listener( listener )
- end
-
- def parse
- tag_stack = []
- in_doctype = false
- entities = nil
- begin
- while true
- event = @parser.pull
- #STDERR.puts "TREEPARSER GOT #{event.inspect}"
- case event[0]
- when :end_document
- unless tag_stack.empty?
- raise ParseException.new("No close tag for #{@build_context.xpath}",
- @parser.source, @parser)
- end
- return
- when :start_element
- tag_stack.push(event[1])
- el = @build_context = @build_context.add_element( event[1] )
- event[2].each do |key, value|
- el.attributes[key]=Attribute.new(key,value,self)
- end
- when :end_element
- tag_stack.pop
- @build_context = @build_context.parent
- when :text
- if not in_doctype
- if @build_context[-1].instance_of? Text
- @build_context[-1] << event[1]
- else
- @build_context.add(
- Text.new(event[1], @build_context.whitespace, nil, true)
- ) unless (
- @build_context.ignore_whitespace_nodes and
- event[1].strip.size==0
- )
- end
- end
- when :comment
- c = Comment.new( event[1] )
- @build_context.add( c )
- when :cdata
- c = CData.new( event[1] )
- @build_context.add( c )
- when :processing_instruction
- @build_context.add( Instruction.new( event[1], event[2] ) )
- when :end_doctype
- in_doctype = false
- entities.each { |k,v| entities[k] = @build_context.entities[k].value }
- @build_context = @build_context.parent
- when :start_doctype
- doctype = DocType.new( event[1..-1], @build_context )
- @build_context = doctype
- entities = {}
- in_doctype = true
- when :attlistdecl
- n = AttlistDecl.new( event[1..-1] )
- @build_context.add( n )
- when :externalentity
- n = ExternalEntity.new( event[1] )
- @build_context.add( n )
- when :elementdecl
- n = ElementDecl.new( event[1] )
- @build_context.add(n)
- when :entitydecl
- entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/
- @build_context.add(Entity.new(event))
- when :notationdecl
- n = NotationDecl.new( *event[1..-1] )
- @build_context.add( n )
- when :xmldecl
- x = XMLDecl.new( event[1], event[2], event[3] )
- @build_context.add( x )
- end
- end
- rescue REXML::Validation::ValidationException
- raise
- rescue REXML::ParseException
- raise
- rescue
- raise ParseException.new( $!.message, @parser.source, @parser, $! )
- end
- end
- end
- end
-end
diff --git a/lib/rexml/parsers/ultralightparser.rb b/lib/rexml/parsers/ultralightparser.rb
deleted file mode 100644
index 6571d119bd..0000000000
--- a/lib/rexml/parsers/ultralightparser.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/parsers/streamparser'
-require 'rexml/parsers/baseparser'
-
-module REXML
- module Parsers
- class UltraLightParser
- def initialize stream
- @stream = stream
- @parser = REXML::Parsers::BaseParser.new( stream )
- end
-
- def add_listener( listener )
- @parser.add_listener( listener )
- end
-
- def rewind
- @stream.rewind
- @parser.stream = @stream
- end
-
- def parse
- root = context = []
- while true
- event = @parser.pull
- case event[0]
- when :end_document
- break
- when :end_doctype
- context = context[1]
- when :start_element, :start_doctype
- context << event
- event[1,0] = [context]
- context = event
- when :end_element
- context = context[1]
- else
- context << event
- end
- end
- root
- end
- end
-
- # An element is an array. The array contains:
- # 0 The parent element
- # 1 The tag name
- # 2 A hash of attributes
- # 3..-1 The child elements
- # An element is an array of size > 3
- # Text is a String
- # PIs are [ :processing_instruction, target, data ]
- # Comments are [ :comment, data ]
- # DocTypes are DocType structs
- # The root is an array with XMLDecls, Text, DocType, Array, Text
- end
-end
diff --git a/lib/rexml/parsers/xpathparser.rb b/lib/rexml/parsers/xpathparser.rb
deleted file mode 100644
index 32b70bb798..0000000000
--- a/lib/rexml/parsers/xpathparser.rb
+++ /dev/null
@@ -1,657 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/namespace'
-require 'rexml/xmltokens'
-
-module REXML
- module Parsers
- # You don't want to use this class. Really. Use XPath, which is a wrapper
- # for this class. Believe me. You don't want to poke around in here.
- # There is strange, dark magic at work in this code. Beware. Go back! Go
- # back while you still can!
- class XPathParser
- include XMLTokens
- LITERAL = /^'([^']*)'|^"([^"]*)"/u
-
- def namespaces=( namespaces )
- Functions::namespace_context = namespaces
- @namespaces = namespaces
- end
-
- def parse path
- path = path.dup
- path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces
- path.gsub!( /\s+([\]\)])/, '\1')
- parsed = []
- OrExpr(path, parsed)
- parsed
- end
-
- def predicate path
- parsed = []
- Predicate( "[#{path}]", parsed )
- parsed
- end
-
- def abbreviate( path )
- path = path.kind_of?(String) ? parse( path ) : path
- string = ""
- document = false
- while path.size > 0
- op = path.shift
- case op
- when :node
- when :attribute
- string << "/" if string.size > 0
- string << "@"
- when :child
- string << "/" if string.size > 0
- when :descendant_or_self
- string << "/"
- when :self
- string << "."
- when :parent
- string << ".."
- when :any
- string << "*"
- when :text
- string << "text()"
- when :following, :following_sibling,
- :ancestor, :ancestor_or_self, :descendant,
- :namespace, :preceding, :preceding_sibling
- string << "/" unless string.size == 0
- string << op.to_s.tr("_", "-")
- string << "::"
- when :qname
- prefix = path.shift
- name = path.shift
- string << prefix+":" if prefix.size > 0
- string << name
- when :predicate
- string << '['
- string << predicate_to_string( path.shift ) {|x| abbreviate( x ) }
- string << ']'
- when :document
- document = true
- when :function
- string << path.shift
- string << "( "
- string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}
- string << " )"
- when :literal
- string << %Q{ "#{path.shift}" }
- else
- string << "/" unless string.size == 0
- string << "UNKNOWN("
- string << op.inspect
- string << ")"
- end
- end
- string = "/"+string if document
- return string
- end
-
- def expand( path )
- path = path.kind_of?(String) ? parse( path ) : path
- string = ""
- document = false
- while path.size > 0
- op = path.shift
- case op
- when :node
- string << "node()"
- when :attribute, :child, :following, :following_sibling,
- :ancestor, :ancestor_or_self, :descendant, :descendant_or_self,
- :namespace, :preceding, :preceding_sibling, :self, :parent
- string << "/" unless string.size == 0
- string << op.to_s.tr("_", "-")
- string << "::"
- when :any
- string << "*"
- when :qname
- prefix = path.shift
- name = path.shift
- string << prefix+":" if prefix.size > 0
- string << name
- when :predicate
- string << '['
- string << predicate_to_string( path.shift ) { |x| expand(x) }
- string << ']'
- when :document
- document = true
- else
- string << "/" unless string.size == 0
- string << "UNKNOWN("
- string << op.inspect
- string << ")"
- end
- end
- string = "/"+string if document
- return string
- end
-
- def predicate_to_string( path, &block )
- string = ""
- case path[0]
- when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union
- op = path.shift
- case op
- when :eq
- op = "="
- when :lt
- op = "<"
- when :gt
- op = ">"
- when :lteq
- op = "<="
- when :gteq
- op = ">="
- when :neq
- op = "!="
- when :union
- op = "|"
- end
- left = predicate_to_string( path.shift, &block )
- right = predicate_to_string( path.shift, &block )
- string << " "
- string << left
- string << " "
- string << op.to_s
- string << " "
- string << right
- string << " "
- when :function
- path.shift
- name = path.shift
- string << name
- string << "( "
- string << predicate_to_string( path.shift, &block )
- string << " )"
- when :literal
- path.shift
- string << " "
- string << path.shift.inspect
- string << " "
- else
- string << " "
- string << yield( path )
- string << " "
- end
- return string.squeeze(" ")
- end
-
- private
- #LocationPath
- # | RelativeLocationPath
- # | '/' RelativeLocationPath?
- # | '//' RelativeLocationPath
- def LocationPath path, parsed
- path = path.strip
- if path[0] == ?/
- parsed << :document
- if path[1] == ?/
- parsed << :descendant_or_self
- parsed << :node
- path = path[2..-1]
- else
- path = path[1..-1]
- end
- end
- return RelativeLocationPath( path, parsed ) if path.size > 0
- end
-
- #RelativeLocationPath
- # | Step
- # | (AXIS_NAME '::' | '@' | '') AxisSpecifier
- # NodeTest
- # Predicate
- # | '.' | '..' AbbreviatedStep
- # | RelativeLocationPath '/' Step
- # | RelativeLocationPath '//' Step
- AXIS = /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/
- def RelativeLocationPath path, parsed
- while path.size > 0
- # (axis or @ or <child::>) nodetest predicate >
- # OR > / Step
- # (. or ..) >
- if path[0] == ?.
- if path[1] == ?.
- parsed << :parent
- parsed << :node
- path = path[2..-1]
- else
- parsed << :self
- parsed << :node
- path = path[1..-1]
- end
- else
- if path[0] == ?@
- parsed << :attribute
- path = path[1..-1]
- # Goto Nodetest
- elsif path =~ AXIS
- parsed << $1.tr('-','_').intern
- path = $'
- # Goto Nodetest
- else
- parsed << :child
- end
-
- n = []
- path = NodeTest( path, n)
-
- if path[0] == ?[
- path = Predicate( path, n )
- end
-
- parsed.concat(n)
- end
-
- if path.size > 0
- if path[0] == ?/
- if path[1] == ?/
- parsed << :descendant_or_self
- parsed << :node
- path = path[2..-1]
- else
- path = path[1..-1]
- end
- else
- return path
- end
- end
- end
- return path
- end
-
- # Returns a 1-1 map of the nodeset
- # The contents of the resulting array are either:
- # true/false, if a positive match
- # String, if a name match
- #NodeTest
- # | ('*' | NCNAME ':' '*' | QNAME) NameTest
- # | NODE_TYPE '(' ')' NodeType
- # | PI '(' LITERAL ')' PI
- # | '[' expr ']' Predicate
- NCNAMETEST= /^(#{NCNAME_STR}):\*/u
- QNAME = Namespace::NAMESPLIT
- NODE_TYPE = /^(comment|text|node)\(\s*\)/m
- PI = /^processing-instruction\(/
- def NodeTest path, parsed
- case path
- when /^\*/
- path = $'
- parsed << :any
- when NODE_TYPE
- type = $1
- path = $'
- parsed << type.tr('-', '_').intern
- when PI
- path = $'
- literal = nil
- if path !~ /^\s*\)/
- path =~ LITERAL
- literal = $1
- path = $'
- raise ParseException.new("Missing ')' after processing instruction") if path[0] != ?)
- path = path[1..-1]
- end
- parsed << :processing_instruction
- parsed << (literal || '')
- when NCNAMETEST
- prefix = $1
- path = $'
- parsed << :namespace
- parsed << prefix
- when QNAME
- prefix = $1
- name = $2
- path = $'
- prefix = "" unless prefix
- parsed << :qname
- parsed << prefix
- parsed << name
- end
- return path
- end
-
- # Filters the supplied nodeset on the predicate(s)
- def Predicate path, parsed
- return nil unless path[0] == ?[
- predicates = []
- while path[0] == ?[
- path, expr = get_group(path)
- predicates << expr[1..-2] if expr
- end
- predicates.each{ |pred|
- preds = []
- parsed << :predicate
- parsed << preds
- OrExpr(pred, preds)
- }
- path
- end
-
- # The following return arrays of true/false, a 1-1 mapping of the
- # supplied nodeset, except for axe(), which returns a filtered
- # nodeset
-
- #| OrExpr S 'or' S AndExpr
- #| AndExpr
- def OrExpr path, parsed
- n = []
- rest = AndExpr( path, n )
- if rest != path
- while rest =~ /^\s*( or )/
- n = [ :or, n, [] ]
- rest = AndExpr( $', n[-1] )
- end
- end
- if parsed.size == 0 and n.size != 0
- parsed.replace(n)
- elsif n.size > 0
- parsed << n
- end
- rest
- end
-
- #| AndExpr S 'and' S EqualityExpr
- #| EqualityExpr
- def AndExpr path, parsed
- n = []
- rest = EqualityExpr( path, n )
- if rest != path
- while rest =~ /^\s*( and )/
- n = [ :and, n, [] ]
- rest = EqualityExpr( $', n[-1] )
- end
- end
- if parsed.size == 0 and n.size != 0
- parsed.replace(n)
- elsif n.size > 0
- parsed << n
- end
- rest
- end
-
- #| EqualityExpr ('=' | '!=') RelationalExpr
- #| RelationalExpr
- def EqualityExpr path, parsed
- n = []
- rest = RelationalExpr( path, n )
- if rest != path
- while rest =~ /^\s*(!?=)\s*/
- if $1[0] == ?!
- n = [ :neq, n, [] ]
- else
- n = [ :eq, n, [] ]
- end
- rest = RelationalExpr( $', n[-1] )
- end
- end
- if parsed.size == 0 and n.size != 0
- parsed.replace(n)
- elsif n.size > 0
- parsed << n
- end
- rest
- end
-
- #| RelationalExpr ('<' | '>' | '<=' | '>=') AdditiveExpr
- #| AdditiveExpr
- def RelationalExpr path, parsed
- n = []
- rest = AdditiveExpr( path, n )
- if rest != path
- while rest =~ /^\s*([<>]=?)\s*/
- if $1[0] == ?<
- sym = "lt"
- else
- sym = "gt"
- end
- sym << "eq" if $1[-1] == ?=
- n = [ sym.intern, n, [] ]
- rest = AdditiveExpr( $', n[-1] )
- end
- end
- if parsed.size == 0 and n.size != 0
- parsed.replace(n)
- elsif n.size > 0
- parsed << n
- end
- rest
- end
-
- #| AdditiveExpr ('+' | S '-') MultiplicativeExpr
- #| MultiplicativeExpr
- def AdditiveExpr path, parsed
- n = []
- rest = MultiplicativeExpr( path, n )
- if rest != path
- while rest =~ /^\s*(\+| -)\s*/
- if $1[0] == ?+
- n = [ :plus, n, [] ]
- else
- n = [ :minus, n, [] ]
- end
- rest = MultiplicativeExpr( $', n[-1] )
- end
- end
- if parsed.size == 0 and n.size != 0
- parsed.replace(n)
- elsif n.size > 0
- parsed << n
- end
- rest
- end
-
- #| MultiplicativeExpr ('*' | S ('div' | 'mod') S) UnaryExpr
- #| UnaryExpr
- def MultiplicativeExpr path, parsed
- n = []
- rest = UnaryExpr( path, n )
- if rest != path
- while rest =~ /^\s*(\*| div | mod )\s*/
- if $1[0] == ?*
- n = [ :mult, n, [] ]
- elsif $1.include?( "div" )
- n = [ :div, n, [] ]
- else
- n = [ :mod, n, [] ]
- end
- rest = UnaryExpr( $', n[-1] )
- end
- end
- if parsed.size == 0 and n.size != 0
- parsed.replace(n)
- elsif n.size > 0
- parsed << n
- end
- rest
- end
-
- #| '-' UnaryExpr
- #| UnionExpr
- def UnaryExpr path, parsed
- path =~ /^(\-*)/
- path = $'
- if $1 and (($1.size % 2) != 0)
- mult = -1
- else
- mult = 1
- end
- parsed << :neg if mult < 0
-
- n = []
- path = UnionExpr( path, n )
- parsed.concat( n )
- path
- end
-
- #| UnionExpr '|' PathExpr
- #| PathExpr
- def UnionExpr path, parsed
- n = []
- rest = PathExpr( path, n )
- if rest != path
- while rest =~ /^\s*(\|)\s*/
- n = [ :union, n, [] ]
- rest = PathExpr( $', n[-1] )
- end
- end
- if parsed.size == 0 and n.size != 0
- parsed.replace( n )
- elsif n.size > 0
- parsed << n
- end
- rest
- end
-
- #| LocationPath
- #| FilterExpr ('/' | '//') RelativeLocationPath
- def PathExpr path, parsed
- path =~ /^\s*/
- path = $'
- n = []
- rest = FilterExpr( path, n )
- if rest != path
- if rest and rest[0] == ?/
- return RelativeLocationPath(rest, n)
- end
- end
- rest = LocationPath(rest, n) if rest =~ /\A[\/\.\@\[\w*]/
- parsed.concat(n)
- return rest
- end
-
- #| FilterExpr Predicate
- #| PrimaryExpr
- def FilterExpr path, parsed
- n = []
- path = PrimaryExpr( path, n )
- path = Predicate(path, n) if path and path[0] == ?[
- parsed.concat(n)
- path
- end
-
- #| VARIABLE_REFERENCE
- #| '(' expr ')'
- #| LITERAL
- #| NUMBER
- #| FunctionCall
- VARIABLE_REFERENCE = /^\$(#{NAME_STR})/u
- NUMBER = /^(\d*\.?\d+)/
- NT = /^comment|text|processing-instruction|node$/
- def PrimaryExpr path, parsed
- case path
- when VARIABLE_REFERENCE
- varname = $1
- path = $'
- parsed << :variable
- parsed << varname
- #arry << @variables[ varname ]
- when /^(\w[-\w]*)(?:\()/
- fname = $1
- tmp = $'
- return path if fname =~ NT
- path = tmp
- parsed << :function
- parsed << fname
- path = FunctionCall(path, parsed)
- when NUMBER
- varname = $1.nil? ? $2 : $1
- path = $'
- parsed << :literal
- parsed << (varname.include?('.') ? varname.to_f : varname.to_i)
- when LITERAL
- varname = $1.nil? ? $2 : $1
- path = $'
- parsed << :literal
- parsed << varname
- when /^\(/ #/
- path, contents = get_group(path)
- contents = contents[1..-2]
- n = []
- OrExpr( contents, n )
- parsed.concat(n)
- end
- path
- end
-
- #| FUNCTION_NAME '(' ( expr ( ',' expr )* )? ')'
- def FunctionCall rest, parsed
- path, arguments = parse_args(rest)
- argset = []
- for argument in arguments
- args = []
- OrExpr( argument, args )
- argset << args
- end
- parsed << argset
- path
- end
-
- # get_group( '[foo]bar' ) -> ['bar', '[foo]']
- def get_group string
- ind = 0
- depth = 0
- st = string[0,1]
- en = (st == "(" ? ")" : "]")
- begin
- case string[ind,1]
- when st
- depth += 1
- when en
- depth -= 1
- end
- ind += 1
- end while depth > 0 and ind < string.length
- return nil unless depth==0
- [string[ind..-1], string[0..ind-1]]
- end
-
- def parse_args( string )
- arguments = []
- ind = 0
- inquot = false
- inapos = false
- depth = 1
- begin
- case string[ind]
- when ?"
- inquot = !inquot unless inapos
- when ?'
- inapos = !inapos unless inquot
- else
- unless inquot or inapos
- case string[ind]
- when ?(
- depth += 1
- if depth == 1
- string = string[1..-1]
- ind -= 1
- end
- when ?)
- depth -= 1
- if depth == 0
- s = string[0,ind].strip
- arguments << s unless s == ""
- string = string[ind+1..-1]
- end
- when ?,
- if depth == 1
- s = string[0,ind].strip
- arguments << s unless s == ""
- string = string[ind+1..-1]
- ind = -1
- end
- end
- end
- end
- ind += 1
- end while depth > 0 and ind < string.length
- return nil unless depth==0
- [string,arguments]
- end
- end
- end
-end
diff --git a/lib/rexml/quickpath.rb b/lib/rexml/quickpath.rb
deleted file mode 100644
index 5d6c77ca38..0000000000
--- a/lib/rexml/quickpath.rb
+++ /dev/null
@@ -1,266 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/functions'
-require 'rexml/xmltokens'
-
-module REXML
- class QuickPath
- include Functions
- include XMLTokens
-
- # A base Hash object to be used when initializing a
- # default empty namespaces set.
- EMPTY_HASH = {}
-
- def QuickPath::first element, path, namespaces=EMPTY_HASH
- match(element, path, namespaces)[0]
- end
-
- def QuickPath::each element, path, namespaces=EMPTY_HASH, &block
- path = "*" unless path
- match(element, path, namespaces).each( &block )
- end
-
- def QuickPath::match element, path, namespaces=EMPTY_HASH
- raise "nil is not a valid xpath" unless path
- results = nil
- Functions::namespace_context = namespaces
- case path
- when /^\/([^\/]|$)/u
- # match on root
- path = path[1..-1]
- return [element.root.parent] if path == ''
- results = filter([element.root], path)
- when /^[-\w]*::/u
- results = filter([element], path)
- when /^\*/u
- results = filter(element.to_a, path)
- when /^[\[!\w:]/u
- # match on child
- children = element.to_a
- results = filter(children, path)
- else
- results = filter([element], path)
- end
- return results
- end
-
- # Given an array of nodes it filters the array based on the path. The
- # result is that when this method returns, the array will contain elements
- # which match the path
- def QuickPath::filter elements, path
- return elements if path.nil? or path == '' or elements.size == 0
- case path
- when /^\/\//u # Descendant
- return axe( elements, "descendant-or-self", $' )
- when /^\/?\b(\w[-\w]*)\b::/u # Axe
- return axe( elements, $1, $' )
- when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
- rest = $'
- results = []
- elements.each do |element|
- results |= filter( element.to_a, rest )
- end
- return results
- when /^\/?(\w[-\w]*)\(/u # / Function
- return function( elements, $1, $' )
- when Namespace::NAMESPLIT # Element name
- name = $2
- ns = $1
- rest = $'
- elements.delete_if do |element|
- !(element.kind_of? Element and
- (element.expanded_name == name or
- (element.name == name and
- element.namespace == Functions.namespace_context[ns])))
- end
- return filter( elements, rest )
- when /^\/\[/u
- matches = []
- elements.each do |element|
- matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
- end
- return matches
- when /^\[/u # Predicate
- return predicate( elements, path )
- when /^\/?\.\.\./u # Ancestor
- return axe( elements, "ancestor", $' )
- when /^\/?\.\./u # Parent
- return filter( elements.collect{|e|e.parent}, $' )
- when /^\/?\./u # Self
- return filter( elements, $' )
- when /^\*/u # Any
- results = []
- elements.each do |element|
- results |= filter( [element], $' ) if element.kind_of? Element
- #if element.kind_of? Element
- # children = element.to_a
- # children.delete_if { |child| !child.kind_of?(Element) }
- # results |= filter( children, $' )
- #end
- end
- return results
- end
- return []
- end
-
- def QuickPath::axe( elements, axe_name, rest )
- matches = []
- matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u
- case axe_name
- when /^descendant/u
- elements.each do |element|
- matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element
- end
- when /^ancestor/u
- elements.each do |element|
- while element.parent
- matches << element.parent
- element = element.parent
- end
- end
- matches = filter( matches, rest )
- when "self"
- matches = filter( elements, rest )
- when "child"
- elements.each do |element|
- matches |= filter( element.to_a, rest ) if element.kind_of? Element
- end
- when "attribute"
- elements.each do |element|
- matches << element.attributes[ rest ] if element.kind_of? Element
- end
- when "parent"
- matches = filter(elements.collect{|element| element.parent}.uniq, rest)
- when "following-sibling"
- matches = filter(elements.collect{|element| element.next_sibling}.uniq,
- rest)
- when "previous-sibling"
- matches = filter(elements.collect{|element|
- element.previous_sibling}.uniq, rest )
- end
- return matches.uniq
- end
-
- OPERAND_ = '((?=(?:(?!and|or).)*[^\s<>=])[^\s<>=]+)'
- # A predicate filters a node-set with respect to an axis to produce a
- # new node-set. For each node in the node-set to be filtered, the
- # PredicateExpr is evaluated with that node as the context node, with
- # the number of nodes in the node-set as the context size, and with the
- # proximity position of the node in the node-set with respect to the
- # axis as the context position; if PredicateExpr evaluates to true for
- # that node, the node is included in the new node-set; otherwise, it is
- # not included.
- #
- # A PredicateExpr is evaluated by evaluating the Expr and converting
- # the result to a boolean. If the result is a number, the result will
- # be converted to true if the number is equal to the context position
- # and will be converted to false otherwise; if the result is not a
- # number, then the result will be converted as if by a call to the
- # boolean function. Thus a location path para[3] is equivalent to
- # para[position()=3].
- def QuickPath::predicate( elements, path )
- ind = 1
- bcount = 1
- while bcount > 0
- bcount += 1 if path[ind] == ?[
- bcount -= 1 if path[ind] == ?]
- ind += 1
- end
- ind -= 1
- predicate = path[1..ind-1]
- rest = path[ind+1..-1]
-
- # have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c'
- #
- predicate.gsub!(
- /#{OPERAND_}\s*([<>=])\s*#{OPERAND_}\s*([<>=])\s*#{OPERAND_}/u,
- '\1 \2 \3 and \3 \4 \5' )
- # Let's do some Ruby trickery to avoid some work:
- predicate.gsub!( /&/u, "&&" )
- predicate.gsub!( /=/u, "==" )
- predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
- predicate.gsub!( /\bmod\b/u, "%" )
- predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
- fname = $1
- fname.gsub( /-/u, "_" )
- }
-
- Functions.pair = [ 0, elements.size ]
- results = []
- elements.each do |element|
- Functions.pair[0] += 1
- Functions.node = element
- res = eval( predicate )
- case res
- when true
- results << element
- when Integer
- results << element if Functions.pair[0] == res
- when String
- results << element
- end
- end
- return filter( results, rest )
- end
-
- def QuickPath::attribute( name )
- return Functions.node.attributes[name] if Functions.node.kind_of? Element
- end
-
- def QuickPath::name()
- return Functions.node.name if Functions.node.kind_of? Element
- end
-
- def QuickPath::method_missing( id, *args )
- begin
- Functions.send( id.id2name, *args )
- rescue Exception
- raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}"
- end
- end
-
- def QuickPath::function( elements, fname, rest )
- args = parse_args( elements, rest )
- Functions.pair = [0, elements.size]
- results = []
- elements.each do |element|
- Functions.pair[0] += 1
- Functions.node = element
- res = Functions.send( fname, *args )
- case res
- when true
- results << element
- when Integer
- results << element if Functions.pair[0] == res
- end
- end
- return results
- end
-
- def QuickPath::parse_args( element, string )
- # /.*?(?:\)|,)/
- arguments = []
- buffer = ""
- while string and string != ""
- c = string[0]
- string.sub!(/^./u, "")
- case c
- when ?,
- # if depth = 1, then we start a new argument
- arguments << evaluate( buffer )
- #arguments << evaluate( string[0..count] )
- when ?(
- # start a new method call
- function( element, buffer, string )
- buffer = ""
- when ?)
- # close the method call and return arguments
- return arguments
- else
- buffer << c
- end
- end
- ""
- end
- end
-end
diff --git a/lib/rexml/rexml.rb b/lib/rexml/rexml.rb
deleted file mode 100644
index fbc0d339d8..0000000000
--- a/lib/rexml/rexml.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- encoding: utf-8 -*-
-# frozen_string_literal: false
-# REXML is an XML toolkit for Ruby[http://www.ruby-lang.org], in Ruby.
-#
-# REXML is a _pure_ Ruby, XML 1.0 conforming,
-# non-validating[http://www.w3.org/TR/2004/REC-xml-20040204/#sec-conformance]
-# toolkit with an intuitive API. REXML passes 100% of the non-validating Oasis
-# tests[http://www.oasis-open.org/committees/xml-conformance/xml-test-suite.shtml],
-# and provides tree, stream, SAX2, pull, and lightweight APIs. REXML also
-# includes a full XPath[http://www.w3c.org/tr/xpath] 1.0 implementation. Since
-# Ruby 1.8, REXML is included in the standard Ruby distribution.
-#
-# Main page:: http://www.germane-software.com/software/rexml
-# Author:: Sean Russell <serATgermaneHYPHENsoftwareDOTcom>
-# Date:: 2008/019
-# Version:: 3.1.7.3
-#
-# This API documentation can be downloaded from the REXML home page, or can
-# be accessed online[http://www.germane-software.com/software/rexml_doc]
-#
-# A tutorial is available in the REXML distribution in docs/tutorial.html,
-# or can be accessed
-# online[http://www.germane-software.com/software/rexml/docs/tutorial.html]
-module REXML
- COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
- DATE = "2008/019"
- VERSION = "3.1.7.3"
- REVISION = %w$Revision$[1] || ''
-
- Copyright = COPYRIGHT
- Version = VERSION
-end
diff --git a/lib/rexml/sax2listener.rb b/lib/rexml/sax2listener.rb
deleted file mode 100644
index 5afdc80890..0000000000
--- a/lib/rexml/sax2listener.rb
+++ /dev/null
@@ -1,98 +0,0 @@
-# frozen_string_literal: false
-module REXML
- # A template for stream parser listeners.
- # Note that the declarations (attlistdecl, elementdecl, etc) are trivially
- # processed; REXML doesn't yet handle doctype entity declarations, so you
- # have to parse them out yourself.
- # === Missing methods from SAX2
- # ignorable_whitespace
- # === Methods extending SAX2
- # +WARNING+
- # These methods are certainly going to change, until DTDs are fully
- # supported. Be aware of this.
- # start_document
- # end_document
- # doctype
- # elementdecl
- # attlistdecl
- # entitydecl
- # notationdecl
- # cdata
- # xmldecl
- # comment
- module SAX2Listener
- def start_document
- end
- def end_document
- end
- def start_prefix_mapping prefix, uri
- end
- def end_prefix_mapping prefix
- end
- def start_element uri, localname, qname, attributes
- end
- def end_element uri, localname, qname
- end
- def characters text
- end
- def processing_instruction target, data
- end
- # Handles a doctype declaration. Any attributes of the doctype which are
- # not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar">
- # @p name the name of the doctype; EG, "me"
- # @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC"
- # @p long_name the supplied long name, or nil. EG, "foo"
- # @p uri the uri of the doctype, or nil. EG, "bar"
- def doctype name, pub_sys, long_name, uri
- end
- # If a doctype includes an ATTLIST declaration, it will cause this
- # method to be called. The content is the declaration itself, unparsed.
- # EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
- # attr CDATA #REQUIRED". This is the same for all of the .*decl
- # methods.
- def attlistdecl(element, pairs, contents)
- end
- # <!ELEMENT ...>
- def elementdecl content
- end
- # <!ENTITY ...>
- # The argument passed to this method is an array of the entity
- # declaration. It can be in a number of formats, but in general it
- # returns (example, result):
- # <!ENTITY % YN '"Yes"'>
- # ["%", "YN", "\"Yes\""]
- # <!ENTITY % YN 'Yes'>
- # ["%", "YN", "Yes"]
- # <!ENTITY WhatHeSaid "He said %YN;">
- # ["WhatHeSaid", "He said %YN;"]
- # <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
- # ["open-hatch", "SYSTEM", "http://www.textuality.com/boilerplate/OpenHatch.xml"]
- # <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
- # ["open-hatch", "PUBLIC", "-//Textuality//TEXT Standard open-hatch boilerplate//EN", "http://www.textuality.com/boilerplate/OpenHatch.xml"]
- # <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
- # ["hatch-pic", "SYSTEM", "../grafix/OpenHatch.gif", "NDATA", "gif"]
- def entitydecl declaration
- end
- # <!NOTATION ...>
- def notationdecl name, public_or_system, public_id, system_id
- end
- # Called when <![CDATA[ ... ]]> is encountered in a document.
- # @p content "..."
- def cdata content
- end
- # Called when an XML PI is encountered in the document.
- # EG: <?xml version="1.0" encoding="utf"?>
- # @p version the version attribute value. EG, "1.0"
- # @p encoding the encoding attribute value, or nil. EG, "utf"
- # @p standalone the standalone attribute value, or nil. EG, nil
- # @p spaced the declaration is followed by a line break
- def xmldecl version, encoding, standalone
- end
- # Called when a comment is encountered.
- # @p comment The content of the comment
- def comment comment
- end
- def progress position
- end
- end
-end
diff --git a/lib/rexml/security.rb b/lib/rexml/security.rb
deleted file mode 100644
index 99b7460772..0000000000
--- a/lib/rexml/security.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: false
-module REXML
- module Security
- @@entity_expansion_limit = 10_000
-
- # Set the entity expansion limit. By default the limit is set to 10000.
- def self.entity_expansion_limit=( val )
- @@entity_expansion_limit = val
- end
-
- # Get the entity expansion limit. By default the limit is set to 10000.
- def self.entity_expansion_limit
- return @@entity_expansion_limit
- end
-
- @@entity_expansion_text_limit = 10_240
-
- # Set the entity expansion limit. By default the limit is set to 10240.
- def self.entity_expansion_text_limit=( val )
- @@entity_expansion_text_limit = val
- end
-
- # Get the entity expansion limit. By default the limit is set to 10240.
- def self.entity_expansion_text_limit
- return @@entity_expansion_text_limit
- end
- end
-end
diff --git a/lib/rexml/source.rb b/lib/rexml/source.rb
deleted file mode 100644
index af65cf4751..0000000000
--- a/lib/rexml/source.rb
+++ /dev/null
@@ -1,297 +0,0 @@
-# coding: US-ASCII
-# frozen_string_literal: false
-require 'rexml/encoding'
-
-module REXML
- # Generates Source-s. USE THIS CLASS.
- class SourceFactory
- # Generates a Source object
- # @param arg Either a String, or an IO
- # @return a Source, or nil if a bad argument was given
- def SourceFactory::create_from(arg)
- if arg.respond_to? :read and
- arg.respond_to? :readline and
- arg.respond_to? :nil? and
- arg.respond_to? :eof?
- IOSource.new(arg)
- elsif arg.respond_to? :to_str
- require 'stringio'
- IOSource.new(StringIO.new(arg))
- elsif arg.kind_of? Source
- arg
- else
- raise "#{arg.class} is not a valid input stream. It must walk \n"+
- "like either a String, an IO, or a Source."
- end
- end
- end
-
- # A Source can be searched for patterns, and wraps buffers and other
- # objects and provides consumption of text
- class Source
- include Encoding
- # The current buffer (what we're going to read next)
- attr_reader :buffer
- # The line number of the last consumed text
- attr_reader :line
- attr_reader :encoding
-
- # Constructor
- # @param arg must be a String, and should be a valid XML document
- # @param encoding if non-null, sets the encoding of the source to this
- # value, overriding all encoding detection
- def initialize(arg, encoding=nil)
- @orig = @buffer = arg
- if encoding
- self.encoding = encoding
- else
- detect_encoding
- end
- @line = 0
- end
-
-
- # Inherited from Encoding
- # Overridden to support optimized en/decoding
- def encoding=(enc)
- return unless super
- encoding_updated
- end
-
- # Scans the source for a given pattern. Note, that this is not your
- # usual scan() method. For one thing, the pattern argument has some
- # requirements; for another, the source can be consumed. You can easily
- # confuse this method. Originally, the patterns were easier
- # to construct and this method more robust, because this method
- # generated search regexps on the fly; however, this was
- # computationally expensive and slowed down the entire REXML package
- # considerably, since this is by far the most commonly called method.
- # @param pattern must be a Regexp, and must be in the form of
- # /^\s*(#{your pattern, with no groups})(.*)/. The first group
- # will be returned; the second group is used if the consume flag is
- # set.
- # @param consume if true, the pattern returned will be consumed, leaving
- # everything after it in the Source.
- # @return the pattern, if found, or nil if the Source is empty or the
- # pattern is not found.
- def scan(pattern, cons=false)
- return nil if @buffer.nil?
- rv = @buffer.scan(pattern)
- @buffer = $' if cons and rv.size>0
- rv
- end
-
- def read
- end
-
- def consume( pattern )
- @buffer = $' if pattern.match( @buffer )
- end
-
- def match_to( char, pattern )
- return pattern.match(@buffer)
- end
-
- def match_to_consume( char, pattern )
- md = pattern.match(@buffer)
- @buffer = $'
- return md
- end
-
- def match(pattern, cons=false)
- md = pattern.match(@buffer)
- @buffer = $' if cons and md
- return md
- end
-
- # @return true if the Source is exhausted
- def empty?
- @buffer == ""
- end
-
- def position
- @orig.index( @buffer )
- end
-
- # @return the current line in the source
- def current_line
- lines = @orig.split
- res = lines.grep @buffer[0..30]
- res = res[-1] if res.kind_of? Array
- lines.index( res ) if res
- end
-
- private
- def detect_encoding
- buffer_encoding = @buffer.encoding
- detected_encoding = "UTF-8"
- begin
- @buffer.force_encoding("ASCII-8BIT")
- if @buffer[0, 2] == "\xfe\xff"
- @buffer[0, 2] = ""
- detected_encoding = "UTF-16BE"
- elsif @buffer[0, 2] == "\xff\xfe"
- @buffer[0, 2] = ""
- detected_encoding = "UTF-16LE"
- elsif @buffer[0, 3] == "\xef\xbb\xbf"
- @buffer[0, 3] = ""
- detected_encoding = "UTF-8"
- end
- ensure
- @buffer.force_encoding(buffer_encoding)
- end
- self.encoding = detected_encoding
- end
-
- def encoding_updated
- if @encoding != 'UTF-8'
- @buffer = decode(@buffer)
- @to_utf = true
- else
- @to_utf = false
- @buffer.force_encoding ::Encoding::UTF_8
- end
- end
- end
-
- # A Source that wraps an IO. See the Source class for method
- # documentation
- class IOSource < Source
- #attr_reader :block_size
-
- # block_size has been deprecated
- def initialize(arg, block_size=500, encoding=nil)
- @er_source = @source = arg
- @to_utf = false
- @pending_buffer = nil
-
- if encoding
- super("", encoding)
- else
- super(@source.read(3) || "")
- end
-
- if !@to_utf and
- @buffer.respond_to?(:force_encoding) and
- @source.respond_to?(:external_encoding) and
- @source.external_encoding != ::Encoding::UTF_8
- @force_utf8 = true
- else
- @force_utf8 = false
- end
- end
-
- def scan(pattern, cons=false)
- rv = super
- # You'll notice that this next section is very similar to the same
- # section in match(), but just a liiittle different. This is
- # because it is a touch faster to do it this way with scan()
- # than the way match() does it; enough faster to warrant duplicating
- # some code
- if rv.size == 0
- until @buffer =~ pattern or @source.nil?
- begin
- @buffer << readline
- rescue Iconv::IllegalSequence
- raise
- rescue
- @source = nil
- end
- end
- rv = super
- end
- rv.taint
- rv
- end
-
- def read
- begin
- @buffer << readline
- rescue Exception, NameError
- @source = nil
- end
- end
-
- def consume( pattern )
- match( pattern, true )
- end
-
- def match( pattern, cons=false )
- rv = pattern.match(@buffer)
- @buffer = $' if cons and rv
- while !rv and @source
- begin
- @buffer << readline
- rv = pattern.match(@buffer)
- @buffer = $' if cons and rv
- rescue
- @source = nil
- end
- end
- rv.taint
- rv
- end
-
- def empty?
- super and ( @source.nil? || @source.eof? )
- end
-
- def position
- @er_source.pos rescue 0
- end
-
- # @return the current line in the source
- def current_line
- begin
- pos = @er_source.pos # The byte position in the source
- lineno = @er_source.lineno # The XML < position in the source
- @er_source.rewind
- line = 0 # The \r\n position in the source
- begin
- while @er_source.pos < pos
- @er_source.readline
- line += 1
- end
- rescue
- end
- rescue IOError
- pos = -1
- line = -1
- end
- [pos, lineno, line]
- end
-
- private
- def readline
- str = @source.readline(@line_break)
- if @pending_buffer
- if str.nil?
- str = @pending_buffer
- else
- str = @pending_buffer + str
- end
- @pending_buffer = nil
- end
- return nil if str.nil?
-
- if @to_utf
- decode(str)
- else
- str.force_encoding(::Encoding::UTF_8) if @force_utf8
- str
- end
- end
-
- def encoding_updated
- case @encoding
- when "UTF-16BE", "UTF-16LE"
- @source.binmode
- @source.set_encoding(@encoding, @encoding)
- end
- @line_break = encode(">")
- @pending_buffer, @buffer = @buffer, ""
- @pending_buffer.force_encoding(@encoding)
- super
- end
- end
-end
diff --git a/lib/rexml/streamlistener.rb b/lib/rexml/streamlistener.rb
deleted file mode 100644
index 30c8945179..0000000000
--- a/lib/rexml/streamlistener.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# frozen_string_literal: false
-module REXML
- # A template for stream parser listeners.
- # Note that the declarations (attlistdecl, elementdecl, etc) are trivially
- # processed; REXML doesn't yet handle doctype entity declarations, so you
- # have to parse them out yourself.
- module StreamListener
- # Called when a tag is encountered.
- # @p name the tag name
- # @p attrs an array of arrays of attribute/value pairs, suitable for
- # use with assoc or rassoc. IE, <tag attr1="value1" attr2="value2">
- # will result in
- # tag_start( "tag", # [["attr1","value1"],["attr2","value2"]])
- def tag_start name, attrs
- end
- # Called when the end tag is reached. In the case of <tag/>, tag_end
- # will be called immediately after tag_start
- # @p the name of the tag
- def tag_end name
- end
- # Called when text is encountered in the document
- # @p text the text content.
- def text text
- end
- # Called when an instruction is encountered. EG: <?xsl sheet='foo'?>
- # @p name the instruction name; in the example, "xsl"
- # @p instruction the rest of the instruction. In the example,
- # "sheet='foo'"
- def instruction name, instruction
- end
- # Called when a comment is encountered.
- # @p comment The content of the comment
- def comment comment
- end
- # Handles a doctype declaration. Any attributes of the doctype which are
- # not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar">
- # @p name the name of the doctype; EG, "me"
- # @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC"
- # @p long_name the supplied long name, or nil. EG, "foo"
- # @p uri the uri of the doctype, or nil. EG, "bar"
- def doctype name, pub_sys, long_name, uri
- end
- # Called when the doctype is done
- def doctype_end
- end
- # If a doctype includes an ATTLIST declaration, it will cause this
- # method to be called. The content is the declaration itself, unparsed.
- # EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
- # attr CDATA #REQUIRED". This is the same for all of the .*decl
- # methods.
- def attlistdecl element_name, attributes, raw_content
- end
- # <!ELEMENT ...>
- def elementdecl content
- end
- # <!ENTITY ...>
- # The argument passed to this method is an array of the entity
- # declaration. It can be in a number of formats, but in general it
- # returns (example, result):
- # <!ENTITY % YN '"Yes"'>
- # ["YN", "\"Yes\"", "%"]
- # <!ENTITY % YN 'Yes'>
- # ["YN", "Yes", "%"]
- # <!ENTITY WhatHeSaid "He said %YN;">
- # ["WhatHeSaid", "He said %YN;"]
- # <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
- # ["open-hatch", "SYSTEM", "http://www.textuality.com/boilerplate/OpenHatch.xml"]
- # <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
- # ["open-hatch", "PUBLIC", "-//Textuality//TEXT Standard open-hatch boilerplate//EN", "http://www.textuality.com/boilerplate/OpenHatch.xml"]
- # <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
- # ["hatch-pic", "SYSTEM", "../grafix/OpenHatch.gif", "gif"]
- def entitydecl content
- end
- # <!NOTATION ...>
- def notationdecl content
- end
- # Called when %foo; is encountered in a doctype declaration.
- # @p content "foo"
- def entity content
- end
- # Called when <![CDATA[ ... ]]> is encountered in a document.
- # @p content "..."
- def cdata content
- end
- # Called when an XML PI is encountered in the document.
- # EG: <?xml version="1.0" encoding="utf"?>
- # @p version the version attribute value. EG, "1.0"
- # @p encoding the encoding attribute value, or nil. EG, "utf"
- # @p standalone the standalone attribute value, or nil. EG, nil
- def xmldecl version, encoding, standalone
- end
- end
-end
diff --git a/lib/rexml/syncenumerator.rb b/lib/rexml/syncenumerator.rb
deleted file mode 100644
index a9d2ad7f9c..0000000000
--- a/lib/rexml/syncenumerator.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: false
-module REXML
- class SyncEnumerator
- include Enumerable
-
- # Creates a new SyncEnumerator which enumerates rows of given
- # Enumerable objects.
- def initialize(*enums)
- @gens = enums
- @length = @gens.collect {|x| x.size }.max
- end
-
- # Returns the number of enumerated Enumerable objects, i.e. the size
- # of each row.
- def size
- @gens.size
- end
-
- # Returns the number of enumerated Enumerable objects, i.e. the size
- # of each row.
- def length
- @gens.length
- end
-
- # Enumerates rows of the Enumerable objects.
- def each
- @length.times {|i|
- yield @gens.collect {|x| x[i]}
- }
- self
- end
- end
-end
diff --git a/lib/rexml/text.rb b/lib/rexml/text.rb
deleted file mode 100644
index 9ea8ba9df3..0000000000
--- a/lib/rexml/text.rb
+++ /dev/null
@@ -1,426 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/security'
-require 'rexml/entity'
-require 'rexml/doctype'
-require 'rexml/child'
-require 'rexml/doctype'
-require 'rexml/parseexception'
-
-module REXML
- # Represents text nodes in an XML document
- class Text < Child
- include Comparable
- # The order in which the substitutions occur
- SPECIALS = [ /&(?!#?[\w-]+;)/u, /</u, />/u, /"/u, /'/u, /\r/u ]
- SUBSTITUTES = ['&amp;', '&lt;', '&gt;', '&quot;', '&apos;', '&#13;']
- # Characters which are substituted in written strings
- SLAICEPS = [ '<', '>', '"', "'", '&' ]
- SETUTITSBUS = [ /&lt;/u, /&gt;/u, /&quot;/u, /&apos;/u, /&amp;/u ]
-
- # If +raw+ is true, then REXML leaves the value alone
- attr_accessor :raw
-
- NEEDS_A_SECOND_CHECK = /(<|&((#{Entity::NAME});|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));)?)/um
- NUMERICENTITY = /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/
- VALID_CHAR = [
- 0x9, 0xA, 0xD,
- (0x20..0xD7FF),
- (0xE000..0xFFFD),
- (0x10000..0x10FFFF)
- ]
-
- if String.method_defined? :encode
- VALID_XML_CHARS = Regexp.new('^['+
- VALID_CHAR.map { |item|
- case item
- when Integer
- [item].pack('U').force_encoding('utf-8')
- when Range
- [item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8')
- end
- }.join +
- ']*$')
- else
- VALID_XML_CHARS = /^(
- [\x09\x0A\x0D\x20-\x7E] # ASCII
- | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
- | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
- | [\xE1-\xEC\xEE][\x80-\xBF]{2} # straight 3-byte
- | \xEF[\x80-\xBE]{2} #
- | \xEF\xBF[\x80-\xBD] # excluding U+fffe and U+ffff
- | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
- | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
- | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
- | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
- )*$/nx;
- end
-
- # Constructor
- # +arg+ if a String, the content is set to the String. If a Text,
- # the object is shallowly cloned.
- #
- # +respect_whitespace+ (boolean, false) if true, whitespace is
- # respected
- #
- # +parent+ (nil) if this is a Parent object, the parent
- # will be set to this.
- #
- # +raw+ (nil) This argument can be given three values.
- # If true, then the value of used to construct this object is expected to
- # contain no unescaped XML markup, and REXML will not change the text. If
- # this value is false, the string may contain any characters, and REXML will
- # escape any and all defined entities whose values are contained in the
- # text. If this value is nil (the default), then the raw value of the
- # parent will be used as the raw value for this node. If there is no raw
- # value for the parent, and no value is supplied, the default is false.
- # Use this field if you have entities defined for some text, and you don't
- # want REXML to escape that text in output.
- # Text.new( "<&", false, nil, false ) #-> "&lt;&amp;"
- # Text.new( "&lt;&amp;", false, nil, false ) #-> "&amp;lt;&amp;amp;"
- # Text.new( "<&", false, nil, true ) #-> Parse exception
- # Text.new( "&lt;&amp;", false, nil, true ) #-> "&lt;&amp;"
- # # Assume that the entity "s" is defined to be "sean"
- # # and that the entity "r" is defined to be "russell"
- # Text.new( "sean russell" ) #-> "&s; &r;"
- # Text.new( "sean russell", false, nil, true ) #-> "sean russell"
- #
- # +entity_filter+ (nil) This can be an array of entities to match in the
- # supplied text. This argument is only useful if +raw+ is set to false.
- # Text.new( "sean russell", false, nil, false, ["s"] ) #-> "&s; russell"
- # Text.new( "sean russell", false, nil, true, ["s"] ) #-> "sean russell"
- # In the last example, the +entity_filter+ argument is ignored.
- #
- # +illegal+ INTERNAL USE ONLY
- def initialize(arg, respect_whitespace=false, parent=nil, raw=nil,
- entity_filter=nil, illegal=NEEDS_A_SECOND_CHECK )
-
- @raw = false
- @parent = nil
-
- if parent
- super( parent )
- @raw = parent.raw
- end
-
- @raw = raw unless raw.nil?
- @entity_filter = entity_filter
- clear_cache
-
- if arg.kind_of? String
- @string = arg.dup
- @string.squeeze!(" \n\t") unless respect_whitespace
- elsif arg.kind_of? Text
- @string = arg.to_s
- @raw = arg.raw
- elsif
- raise "Illegal argument of type #{arg.type} for Text constructor (#{arg})"
- end
-
- @string.gsub!( /\r\n?/, "\n" )
-
- Text.check(@string, illegal, doctype) if @raw
- end
-
- def parent= parent
- super(parent)
- Text.check(@string, NEEDS_A_SECOND_CHECK, doctype) if @raw and @parent
- end
-
- # check for illegal characters
- def Text.check string, pattern, doctype
-
- # illegal anywhere
- if string !~ VALID_XML_CHARS
- if String.method_defined? :encode
- string.chars.each do |c|
- case c.ord
- when *VALID_CHAR
- else
- raise "Illegal character #{c.inspect} in raw string \"#{string}\""
- end
- end
- else
- string.scan(/[\x00-\x7F]|[\x80-\xBF][\xC0-\xF0]*|[\xC0-\xF0]/n) do |c|
- case c.unpack('U')
- when *VALID_CHAR
- else
- raise "Illegal character #{c.inspect} in raw string \"#{string}\""
- end
- end
- end
- end
-
- # context sensitive
- string.scan(pattern) do
- if $1[-1] != ?;
- raise "Illegal character '#{$1}' in raw string \"#{string}\""
- elsif $1[0] == ?&
- if $5 and $5[0] == ?#
- case ($5[1] == ?x ? $5[2..-1].to_i(16) : $5[1..-1].to_i)
- when *VALID_CHAR
- else
- raise "Illegal character '#{$1}' in raw string \"#{string}\""
- end
- # FIXME: below can't work but this needs API change.
- # elsif @parent and $3 and !SUBSTITUTES.include?($1)
- # if !doctype or !doctype.entities.has_key?($3)
- # raise "Undeclared entity '#{$1}' in raw string \"#{string}\""
- # end
- end
- end
- end
- end
-
- def node_type
- :text
- end
-
- def empty?
- @string.size==0
- end
-
-
- def clone
- return Text.new(self)
- end
-
-
- # Appends text to this text node. The text is appended in the +raw+ mode
- # of this text node.
- #
- # +returns+ the text itself to enable method chain like
- # 'text << "XXX" << "YYY"'.
- def <<( to_append )
- @string << to_append.gsub( /\r\n?/, "\n" )
- clear_cache
- self
- end
-
-
- # +other+ a String or a Text
- # +returns+ the result of (to_s <=> arg.to_s)
- def <=>( other )
- to_s() <=> other.to_s
- end
-
- def doctype
- if @parent
- doc = @parent.document
- doc.doctype if doc
- end
- end
-
- REFERENCE = /#{Entity::REFERENCE}/
- # Returns the string value of this text node. This string is always
- # escaped, meaning that it is a valid XML text node string, and all
- # entities that can be escaped, have been inserted. This method respects
- # the entity filter set in the constructor.
- #
- # # Assume that the entity "s" is defined to be "sean", and that the
- # # entity "r" is defined to be "russell"
- # t = Text.new( "< & sean russell", false, nil, false, ['s'] )
- # t.to_s #-> "&lt; &amp; &s; russell"
- # t = Text.new( "< & &s; russell", false, nil, false )
- # t.to_s #-> "&lt; &amp; &s; russell"
- # u = Text.new( "sean russell", false, nil, true )
- # u.to_s #-> "sean russell"
- def to_s
- return @string if @raw
- return @normalized if @normalized
-
- @normalized = Text::normalize( @string, doctype, @entity_filter )
- end
-
- def inspect
- @string.inspect
- end
-
- # Returns the string value of this text. This is the text without
- # entities, as it might be used programmatically, or printed to the
- # console. This ignores the 'raw' attribute setting, and any
- # entity_filter.
- #
- # # Assume that the entity "s" is defined to be "sean", and that the
- # # entity "r" is defined to be "russell"
- # t = Text.new( "< & sean russell", false, nil, false, ['s'] )
- # t.value #-> "< & sean russell"
- # t = Text.new( "< & &s; russell", false, nil, false )
- # t.value #-> "< & sean russell"
- # u = Text.new( "sean russell", false, nil, true )
- # u.value #-> "sean russell"
- def value
- return @unnormalized if @unnormalized
- @unnormalized = Text::unnormalize( @string, doctype )
- end
-
- # Sets the contents of this text node. This expects the text to be
- # unnormalized. It returns self.
- #
- # e = Element.new( "a" )
- # e.add_text( "foo" ) # <a>foo</a>
- # e[0].value = "bar" # <a>bar</a>
- # e[0].value = "<a>" # <a>&lt;a&gt;</a>
- def value=( val )
- @string = val.gsub( /\r\n?/, "\n" )
- clear_cache
- @raw = false
- end
-
- def wrap(string, width, addnewline=false)
- # Recursively wrap string at width.
- return string if string.length <= width
- place = string.rindex(' ', width) # Position in string with last ' ' before cutoff
- if addnewline then
- return "\n" + string[0,place] + "\n" + wrap(string[place+1..-1], width)
- else
- return string[0,place] + "\n" + wrap(string[place+1..-1], width)
- end
- end
-
- def indent_text(string, level=1, style="\t", indentfirstline=true)
- return string if level < 0
- new_string = ''
- string.each_line { |line|
- indent_string = style * level
- new_line = (indent_string + line).sub(/[\s]+$/,'')
- new_string << new_line
- }
- new_string.strip! unless indentfirstline
- return new_string
- end
-
- # == DEPRECATED
- # See REXML::Formatters
- #
- def write( writer, indent=-1, transitive=false, ie_hack=false )
- Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
- formatter = if indent > -1
- REXML::Formatters::Pretty.new( indent )
- else
- REXML::Formatters::Default.new
- end
- formatter.write( self, writer )
- end
-
- # FIXME
- # This probably won't work properly
- def xpath
- path = @parent.xpath
- path += "/text()"
- return path
- end
-
- # Writes out text, substituting special characters beforehand.
- # +out+ A String, IO, or any other object supporting <<( String )
- # +input+ the text to substitute and the write out
- #
- # z=utf8.unpack("U*")
- # ascOut=""
- # z.each{|r|
- # if r < 0x100
- # ascOut.concat(r.chr)
- # else
- # ascOut.concat(sprintf("&#x%x;", r))
- # end
- # }
- # puts ascOut
- def write_with_substitution out, input
- copy = input.clone
- # Doing it like this rather than in a loop improves the speed
- copy.gsub!( SPECIALS[0], SUBSTITUTES[0] )
- copy.gsub!( SPECIALS[1], SUBSTITUTES[1] )
- copy.gsub!( SPECIALS[2], SUBSTITUTES[2] )
- copy.gsub!( SPECIALS[3], SUBSTITUTES[3] )
- copy.gsub!( SPECIALS[4], SUBSTITUTES[4] )
- copy.gsub!( SPECIALS[5], SUBSTITUTES[5] )
- out << copy
- end
-
- private
- def clear_cache
- @normalized = nil
- @unnormalized = nil
- end
-
- # Reads text, substituting entities
- def Text::read_with_substitution( input, illegal=nil )
- copy = input.clone
-
- if copy =~ illegal
- raise ParseException.new( "malformed text: Illegal character #$& in \"#{copy}\"" )
- end if illegal
-
- copy.gsub!( /\r\n?/, "\n" )
- if copy.include? ?&
- copy.gsub!( SETUTITSBUS[0], SLAICEPS[0] )
- copy.gsub!( SETUTITSBUS[1], SLAICEPS[1] )
- copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] )
- copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] )
- copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] )
- copy.gsub!( /&#0*((?:\d+)|(?:x[a-f0-9]+));/ ) {
- m=$1
- #m='0' if m==''
- m = "0#{m}" if m[0] == ?x
- [Integer(m)].pack('U*')
- }
- end
- copy
- end
-
- EREFERENCE = /&(?!#{Entity::NAME};)/
- # Escapes all possible entities
- def Text::normalize( input, doctype=nil, entity_filter=nil )
- copy = input.to_s
- # Doing it like this rather than in a loop improves the speed
- #copy = copy.gsub( EREFERENCE, '&amp;' )
- copy = copy.gsub( "&", "&amp;" )
- if doctype
- # Replace all ampersands that aren't part of an entity
- doctype.entities.each_value do |entity|
- copy = copy.gsub( entity.value,
- "&#{entity.name};" ) if entity.value and
- not( entity_filter and entity_filter.include?(entity.name) )
- end
- else
- # Replace all ampersands that aren't part of an entity
- DocType::DEFAULT_ENTITIES.each_value do |entity|
- copy = copy.gsub(entity.value, "&#{entity.name};" )
- end
- end
- copy
- end
-
- # Unescapes all possible entities
- def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
- sum = 0
- string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
- s = Text.expand($&, doctype, filter)
- if sum + s.bytesize > Security.entity_expansion_text_limit
- raise "entity expansion has grown too large"
- else
- sum += s.bytesize
- end
- s
- }
- end
-
- def Text.expand(ref, doctype, filter)
- if ref[1] == ?#
- if ref[2] == ?x
- [ref[3...-1].to_i(16)].pack('U*')
- else
- [ref[2...-1].to_i].pack('U*')
- end
- elsif ref == '&amp;'
- '&'
- elsif filter and filter.include?( ref[1...-1] )
- ref
- elsif doctype
- doctype.entity( ref[1...-1] ) or ref
- else
- entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
- entity_value ? entity_value.value : ref
- end
- end
- end
-end
diff --git a/lib/rexml/undefinednamespaceexception.rb b/lib/rexml/undefinednamespaceexception.rb
deleted file mode 100644
index e522ed57ea..0000000000
--- a/lib/rexml/undefinednamespaceexception.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/parseexception'
-module REXML
- class UndefinedNamespaceException < ParseException
- def initialize( prefix, source, parser )
- super( "Undefined prefix #{prefix} found" )
- end
- end
-end
diff --git a/lib/rexml/validation/relaxng.rb b/lib/rexml/validation/relaxng.rb
deleted file mode 100644
index fb52438290..0000000000
--- a/lib/rexml/validation/relaxng.rb
+++ /dev/null
@@ -1,539 +0,0 @@
-# frozen_string_literal: false
-require "rexml/validation/validation"
-require "rexml/parsers/baseparser"
-
-module REXML
- module Validation
- # Implemented:
- # * empty
- # * element
- # * attribute
- # * text
- # * optional
- # * choice
- # * oneOrMore
- # * zeroOrMore
- # * group
- # * value
- # * interleave
- # * mixed
- # * ref
- # * grammar
- # * start
- # * define
- #
- # Not implemented:
- # * data
- # * param
- # * include
- # * externalRef
- # * notAllowed
- # * anyName
- # * nsName
- # * except
- # * name
- class RelaxNG
- include Validator
-
- INFINITY = 1.0 / 0.0
- EMPTY = Event.new( nil )
- TEXT = [:start_element, "text"]
- attr_accessor :current
- attr_accessor :count
- attr_reader :references
-
- # FIXME: Namespaces
- def initialize source
- parser = REXML::Parsers::BaseParser.new( source )
-
- @count = 0
- @references = {}
- @root = @current = Sequence.new(self)
- @root.previous = true
- states = [ @current ]
- begin
- event = parser.pull
- case event[0]
- when :start_element
- case event[1]
- when "empty"
- when "element", "attribute", "text", "value"
- states[-1] << event
- when "optional"
- states << Optional.new( self )
- states[-2] << states[-1]
- when "choice"
- states << Choice.new( self )
- states[-2] << states[-1]
- when "oneOrMore"
- states << OneOrMore.new( self )
- states[-2] << states[-1]
- when "zeroOrMore"
- states << ZeroOrMore.new( self )
- states[-2] << states[-1]
- when "group"
- states << Sequence.new( self )
- states[-2] << states[-1]
- when "interleave"
- states << Interleave.new( self )
- states[-2] << states[-1]
- when "mixed"
- states << Interleave.new( self )
- states[-2] << states[-1]
- states[-1] << TEXT
- when "define"
- states << [ event[2]["name"] ]
- when "ref"
- states[-1] << Ref.new( event[2]["name"] )
- when "anyName"
- states << AnyName.new( self )
- states[-2] << states[-1]
- when "nsName"
- when "except"
- when "name"
- when "data"
- when "param"
- when "include"
- when "grammar"
- when "start"
- when "externalRef"
- when "notAllowed"
- end
- when :end_element
- case event[1]
- when "element", "attribute"
- states[-1] << event
- when "zeroOrMore", "oneOrMore", "choice", "optional",
- "interleave", "group", "mixed"
- states.pop
- when "define"
- ref = states.pop
- @references[ ref.shift ] = ref
- #when "empty"
- end
- when :end_document
- states[-1] << event
- when :text
- states[-1] << event
- end
- end while event[0] != :end_document
- end
-
- def receive event
- validate( event )
- end
- end
-
- class State
- def initialize( context )
- @previous = []
- @events = []
- @current = 0
- @count = context.count += 1
- @references = context.references
- @value = false
- end
-
- def reset
- return if @current == 0
- @current = 0
- @events.each {|s| s.reset if s.kind_of? State }
- end
-
- def previous=( previous )
- @previous << previous
- end
-
- def next( event )
- #print "In next with #{event.inspect}. "
- #p @previous
- return @previous.pop.next( event ) if @events[@current].nil?
- expand_ref_in( @events, @current ) if @events[@current].class == Ref
- if ( @events[@current].kind_of? State )
- @current += 1
- @events[@current-1].previous = self
- return @events[@current-1].next( event )
- end
- if ( @events[@current].matches?(event) )
- @current += 1
- if @events[@current].nil?
- return @previous.pop
- elsif @events[@current].kind_of? State
- @current += 1
- @events[@current-1].previous = self
- return @events[@current-1]
- else
- return self
- end
- else
- return nil
- end
- end
-
- def to_s
- # Abbreviated:
- self.class.name =~ /(?:::)(\w)\w+$/
- # Full:
- #self.class.name =~ /(?:::)(\w+)$/
- "#$1.#@count"
- end
-
- def inspect
- "< #{to_s} #{@events.collect{|e|
- pre = e == @events[@current] ? '#' : ''
- pre + e.inspect unless self == e
- }.join(', ')} >"
- end
-
- def expected
- return [@events[@current]]
- end
-
- def <<( event )
- add_event_to_arry( @events, event )
- end
-
-
- protected
- def expand_ref_in( arry, ind )
- new_events = []
- @references[ arry[ind].to_s ].each{ |evt|
- add_event_to_arry(new_events,evt)
- }
- arry[ind,1] = new_events
- end
-
- def add_event_to_arry( arry, evt )
- evt = generate_event( evt )
- if evt.kind_of? String
- arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value
- @value = false
- else
- arry << evt
- end
- end
-
- def generate_event( event )
- return event if event.kind_of? State or event.class == Ref
- evt = nil
- arg = nil
- case event[0]
- when :start_element
- case event[1]
- when "element"
- evt = :start_element
- arg = event[2]["name"]
- when "attribute"
- evt = :start_attribute
- arg = event[2]["name"]
- when "text"
- evt = :text
- when "value"
- evt = :text
- @value = true
- end
- when :text
- return event[1]
- when :end_document
- return Event.new( event[0] )
- else # then :end_element
- case event[1]
- when "element"
- evt = :end_element
- when "attribute"
- evt = :end_attribute
- end
- end
- return Event.new( evt, arg )
- end
- end
-
-
- class Sequence < State
- def matches?(event)
- @events[@current].matches?( event )
- end
- end
-
-
- class Optional < State
- def next( event )
- if @current == 0
- rv = super
- return rv if rv
- @prior = @previous.pop
- return @prior.next( event )
- end
- super
- end
-
- def matches?(event)
- @events[@current].matches?(event) ||
- (@current == 0 and @previous[-1].matches?(event))
- end
-
- def expected
- return [ @prior.expected, @events[0] ].flatten if @current == 0
- return [@events[@current]]
- end
- end
-
-
- class ZeroOrMore < Optional
- def next( event )
- expand_ref_in( @events, @current ) if @events[@current].class == Ref
- if ( @events[@current].matches?(event) )
- @current += 1
- if @events[@current].nil?
- @current = 0
- return self
- elsif @events[@current].kind_of? State
- @current += 1
- @events[@current-1].previous = self
- return @events[@current-1]
- else
- return self
- end
- else
- @prior = @previous.pop
- return @prior.next( event ) if @current == 0
- return nil
- end
- end
-
- def expected
- return [ @prior.expected, @events[0] ].flatten if @current == 0
- return [@events[@current]]
- end
- end
-
-
- class OneOrMore < State
- def initialize context
- super
- @ord = 0
- end
-
- def reset
- super
- @ord = 0
- end
-
- def next( event )
- expand_ref_in( @events, @current ) if @events[@current].class == Ref
- if ( @events[@current].matches?(event) )
- @current += 1
- @ord += 1
- if @events[@current].nil?
- @current = 0
- return self
- elsif @events[@current].kind_of? State
- @current += 1
- @events[@current-1].previous = self
- return @events[@current-1]
- else
- return self
- end
- else
- return @previous.pop.next( event ) if @current == 0 and @ord > 0
- return nil
- end
- end
-
- def matches?( event )
- @events[@current].matches?(event) ||
- (@current == 0 and @ord > 0 and @previous[-1].matches?(event))
- end
-
- def expected
- if @current == 0 and @ord > 0
- return [@previous[-1].expected, @events[0]].flatten
- else
- return [@events[@current]]
- end
- end
- end
-
-
- class Choice < State
- def initialize context
- super
- @choices = []
- end
-
- def reset
- super
- @events = []
- @choices.each { |c| c.each { |s| s.reset if s.kind_of? State } }
- end
-
- def <<( event )
- add_event_to_arry( @choices, event )
- end
-
- def next( event )
- # Make the choice if we haven't
- if @events.size == 0
- c = 0 ; max = @choices.size
- while c < max
- if @choices[c][0].class == Ref
- expand_ref_in( @choices[c], 0 )
- @choices += @choices[c]
- @choices.delete( @choices[c] )
- max -= 1
- else
- c += 1
- end
- end
- @events = @choices.find { |evt| evt[0].matches? event }
- # Remove the references
- # Find the events
- end
- unless @events
- @events = []
- return nil
- end
- super
- end
-
- def matches?( event )
- return @events[@current].matches?( event ) if @events.size > 0
- !@choices.find{|evt| evt[0].matches?(event)}.nil?
- end
-
- def expected
- return [@events[@current]] if @events.size > 0
- return @choices.collect do |x|
- if x[0].kind_of? State
- x[0].expected
- else
- x[0]
- end
- end.flatten
- end
-
- def inspect
- "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' or ')} >"
- end
-
- protected
- def add_event_to_arry( arry, evt )
- if evt.kind_of? State or evt.class == Ref
- arry << [evt]
- elsif evt[0] == :text
- if arry[-1] and
- arry[-1][-1].kind_of?( Event ) and
- arry[-1][-1].event_type == :text and @value
-
- arry[-1][-1].event_arg = evt[1]
- @value = false
- end
- else
- arry << [] if evt[0] == :start_element
- arry[-1] << generate_event( evt )
- end
- end
- end
-
-
- class Interleave < Choice
- def initialize context
- super
- @choice = 0
- end
-
- def reset
- @choice = 0
- end
-
- def next_current( event )
- # Expand references
- c = 0 ; max = @choices.size
- while c < max
- if @choices[c][0].class == Ref
- expand_ref_in( @choices[c], 0 )
- @choices += @choices[c]
- @choices.delete( @choices[c] )
- max -= 1
- else
- c += 1
- end
- end
- @events = @choices[@choice..-1].find { |evt| evt[0].matches? event }
- @current = 0
- if @events
- # reorder the choices
- old = @choices[@choice]
- idx = @choices.index( @events )
- @choices[@choice] = @events
- @choices[idx] = old
- @choice += 1
- end
-
- @events = [] unless @events
- end
-
-
- def next( event )
- # Find the next series
- next_current(event) unless @events[@current]
- return nil unless @events[@current]
-
- expand_ref_in( @events, @current ) if @events[@current].class == Ref
- if ( @events[@current].kind_of? State )
- @current += 1
- @events[@current-1].previous = self
- return @events[@current-1].next( event )
- end
- return @previous.pop.next( event ) if @events[@current].nil?
- if ( @events[@current].matches?(event) )
- @current += 1
- if @events[@current].nil?
- return self unless @choices[@choice].nil?
- return @previous.pop
- elsif @events[@current].kind_of? State
- @current += 1
- @events[@current-1].previous = self
- return @events[@current-1]
- else
- return self
- end
- else
- return nil
- end
- end
-
- def matches?( event )
- return @events[@current].matches?( event ) if @events[@current]
- !@choices[@choice..-1].find{|evt| evt[0].matches?(event)}.nil?
- end
-
- def expected
- return [@events[@current]] if @events[@current]
- return @choices[@choice..-1].collect do |x|
- if x[0].kind_of? State
- x[0].expected
- else
- x[0]
- end
- end.flatten
- end
-
- def inspect
- "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' and ')} >"
- end
- end
-
- class Ref
- def initialize value
- @value = value
- end
- def to_s
- @value
- end
- def inspect
- "{#{to_s}}"
- end
- end
- end
-end
diff --git a/lib/rexml/validation/validation.rb b/lib/rexml/validation/validation.rb
deleted file mode 100644
index f0c76f976c..0000000000
--- a/lib/rexml/validation/validation.rb
+++ /dev/null
@@ -1,144 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/validation/validationexception'
-
-module REXML
- module Validation
- module Validator
- NILEVENT = [ nil ]
- def reset
- @current = @root
- @root.reset
- @root.previous = true
- @attr_stack = []
- self
- end
- def dump
- puts @root.inspect
- end
- def validate( event )
- @attr_stack = [] unless defined? @attr_stack
- match = @current.next(event)
- raise ValidationException.new( "Validation error. Expected: "+
- @current.expected.join( " or " )+" from #{@current.inspect} "+
- " but got #{Event.new( event[0], event[1] ).inspect}" ) unless match
- @current = match
-
- # Check for attributes
- case event[0]
- when :start_element
- @attr_stack << event[2]
- begin
- sattr = [:start_attribute, nil]
- eattr = [:end_attribute]
- text = [:text, nil]
- k, = event[2].find { |key,value|
- sattr[1] = key
- m = @current.next( sattr )
- if m
- # If the state has text children...
- if m.matches?( eattr )
- @current = m
- else
- text[1] = value
- m = m.next( text )
- text[1] = nil
- return false unless m
- @current = m if m
- end
- m = @current.next( eattr )
- if m
- @current = m
- true
- else
- false
- end
- else
- false
- end
- }
- event[2].delete(k) if k
- end while k
- when :end_element
- attrs = @attr_stack.pop
- raise ValidationException.new( "Validation error. Illegal "+
- " attributes: #{attrs.inspect}") if attrs.length > 0
- end
- end
- end
-
- class Event
- def initialize(event_type, event_arg=nil )
- @event_type = event_type
- @event_arg = event_arg
- end
-
- attr_reader :event_type
- attr_accessor :event_arg
-
- def done?
- @done
- end
-
- def single?
- return (@event_type != :start_element and @event_type != :start_attribute)
- end
-
- def matches?( event )
- return false unless event[0] == @event_type
- case event[0]
- when nil
- return true
- when :start_element
- return true if event[1] == @event_arg
- when :end_element
- return true
- when :start_attribute
- return true if event[1] == @event_arg
- when :end_attribute
- return true
- when :end_document
- return true
- when :text
- return (@event_arg.nil? or @event_arg == event[1])
-=begin
- when :processing_instruction
- false
- when :xmldecl
- false
- when :start_doctype
- false
- when :end_doctype
- false
- when :externalentity
- false
- when :elementdecl
- false
- when :entity
- false
- when :attlistdecl
- false
- when :notationdecl
- false
- when :end_doctype
- false
-=end
- else
- false
- end
- end
-
- def ==( other )
- return false unless other.kind_of? Event
- @event_type == other.event_type and @event_arg == other.event_arg
- end
-
- def to_s
- inspect
- end
-
- def inspect
- "#{@event_type.inspect}( #@event_arg )"
- end
- end
- end
-end
diff --git a/lib/rexml/validation/validationexception.rb b/lib/rexml/validation/validationexception.rb
deleted file mode 100644
index 78cd63fd04..0000000000
--- a/lib/rexml/validation/validationexception.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: false
-module REXML
- module Validation
- class ValidationException < RuntimeError
- def initialize msg
- super
- end
- end
- end
-end
diff --git a/lib/rexml/xmldecl.rb b/lib/rexml/xmldecl.rb
deleted file mode 100644
index a37e9f3ddc..0000000000
--- a/lib/rexml/xmldecl.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/encoding'
-require 'rexml/source'
-
-module REXML
- # NEEDS DOCUMENTATION
- class XMLDecl < Child
- include Encoding
-
- DEFAULT_VERSION = "1.0";
- DEFAULT_ENCODING = "UTF-8";
- DEFAULT_STANDALONE = "no";
- START = '<\?xml';
- STOP = '\?>';
-
- attr_accessor :version, :standalone
- attr_reader :writeencoding, :writethis
-
- def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
- @writethis = true
- @writeencoding = !encoding.nil?
- if version.kind_of? XMLDecl
- super()
- @version = version.version
- self.encoding = version.encoding
- @writeencoding = version.writeencoding
- @standalone = version.standalone
- else
- super()
- @version = version
- self.encoding = encoding
- @standalone = standalone
- end
- @version = DEFAULT_VERSION if @version.nil?
- end
-
- def clone
- XMLDecl.new(self)
- end
-
- # indent::
- # Ignored. There must be no whitespace before an XML declaration
- # transitive::
- # Ignored
- # ie_hack::
- # Ignored
- def write(writer, indent=-1, transitive=false, ie_hack=false)
- return nil unless @writethis or writer.kind_of? Output
- writer << START.sub(/\\/u, '')
- writer << " #{content encoding}"
- writer << STOP.sub(/\\/u, '')
- end
-
- def ==( other )
- other.kind_of?(XMLDecl) and
- other.version == @version and
- other.encoding == self.encoding and
- other.standalone == @standalone
- end
-
- def xmldecl version, encoding, standalone
- @version = version
- self.encoding = encoding
- @standalone = standalone
- end
-
- def node_type
- :xmldecl
- end
-
- alias :stand_alone? :standalone
- alias :old_enc= :encoding=
-
- def encoding=( enc )
- if enc.nil?
- self.old_enc = "UTF-8"
- @writeencoding = false
- else
- self.old_enc = enc
- @writeencoding = true
- end
- self.dowrite
- end
-
- # Only use this if you do not want the XML declaration to be written;
- # this object is ignored by the XML writer. Otherwise, instantiate your
- # own XMLDecl and add it to the document.
- #
- # Note that XML 1.1 documents *must* include an XML declaration
- def XMLDecl.default
- rv = XMLDecl.new( "1.0" )
- rv.nowrite
- rv
- end
-
- def nowrite
- @writethis = false
- end
-
- def dowrite
- @writethis = true
- end
-
- def inspect
- START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
- end
-
- private
- def content(enc)
- rv = "version='#@version'"
- rv << " encoding='#{enc}'" if @writeencoding || enc !~ /\Autf-8\z/i
- rv << " standalone='#@standalone'" if @standalone
- rv
- end
- end
-end
diff --git a/lib/rexml/xmltokens.rb b/lib/rexml/xmltokens.rb
deleted file mode 100644
index 392b47b1d3..0000000000
--- a/lib/rexml/xmltokens.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: false
-module REXML
- # Defines a number of tokens used for parsing XML. Not for general
- # consumption.
- module XMLTokens
- # From http://www.w3.org/TR/REC-xml/#sec-common-syn
- #
- # [4] NameStartChar ::=
- # ":" |
- # [A-Z] |
- # "_" |
- # [a-z] |
- # [#xC0-#xD6] |
- # [#xD8-#xF6] |
- # [#xF8-#x2FF] |
- # [#x370-#x37D] |
- # [#x37F-#x1FFF] |
- # [#x200C-#x200D] |
- # [#x2070-#x218F] |
- # [#x2C00-#x2FEF] |
- # [#x3001-#xD7FF] |
- # [#xF900-#xFDCF] |
- # [#xFDF0-#xFFFD] |
- # [#x10000-#xEFFFF]
- name_start_chars = [
- ":",
- "A-Z",
- "_",
- "a-z",
- "\\u00C0-\\u00D6",
- "\\u00D8-\\u00F6",
- "\\u00F8-\\u02FF",
- "\\u0370-\\u037D",
- "\\u037F-\\u1FFF",
- "\\u200C-\\u200D",
- "\\u2070-\\u218F",
- "\\u2C00-\\u2FEF",
- "\\u3001-\\uD7FF",
- "\\uF900-\\uFDCF",
- "\\uFDF0-\\uFFFD",
- "\\u{10000}-\\u{EFFFF}",
- ]
- # From http://www.w3.org/TR/REC-xml/#sec-common-syn
- #
- # [4a] NameChar ::=
- # NameStartChar |
- # "-" |
- # "." |
- # [0-9] |
- # #xB7 |
- # [#x0300-#x036F] |
- # [#x203F-#x2040]
- name_chars = name_start_chars + [
- "\\-",
- "\\.",
- "0-9",
- "\\u00B7",
- "\\u0300-\\u036F",
- "\\u203F-\\u2040",
- ]
- NAME_START_CHAR = "[#{name_start_chars.join('')}]"
- NAME_CHAR = "[#{name_chars.join('')}]"
- NAMECHAR = NAME_CHAR # deprecated. Use NAME_CHAR instead.
-
- # From http://www.w3.org/TR/xml-names11/#NT-NCName
- #
- # [6] NCNameStartChar ::= NameStartChar - ':'
- ncname_start_chars = name_start_chars - [":"]
- # From http://www.w3.org/TR/xml-names11/#NT-NCName
- #
- # [5] NCNameChar ::= NameChar - ':'
- ncname_chars = name_chars - [":"]
- NCNAME_STR = "[#{ncname_start_chars.join('')}][#{ncname_chars.join('')}]*"
- NAME_STR = "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
-
- NAME = "(#{NAME_START_CHAR}#{NAME_CHAR}*)"
- NMTOKEN = "(?:#{NAME_CHAR})+"
- NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
- REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)"
-
- #REFERENCE = "(?:#{ENTITYREF}|#{CHARREF})"
- #ENTITYREF = "&#{NAME};"
- #CHARREF = "&#\\d+;|&#x[0-9a-fA-F]+;"
- end
-end
diff --git a/lib/rexml/xpath.rb b/lib/rexml/xpath.rb
deleted file mode 100644
index f1cb99baea..0000000000
--- a/lib/rexml/xpath.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/functions'
-require 'rexml/xpath_parser'
-
-module REXML
- # Wrapper class. Use this class to access the XPath functions.
- class XPath
- include Functions
- # A base Hash object, supposing to be used when initializing a
- # default empty namespaces set, but is currently unused.
- # TODO: either set the namespaces=EMPTY_HASH, or deprecate this.
- EMPTY_HASH = {}
-
- # Finds and returns the first node that matches the supplied xpath.
- # element::
- # The context element
- # path::
- # The xpath to search for. If not supplied or nil, returns the first
- # node matching '*'.
- # namespaces::
- # If supplied, a Hash which defines a namespace mapping.
- # variables::
- # If supplied, a Hash which maps $variables in the query
- # to values. This can be used to avoid XPath injection attacks
- # or to automatically handle escaping string values.
- #
- # XPath.first( node )
- # XPath.first( doc, "//b"} )
- # XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
- # XPath.first( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})
- def XPath::first element, path=nil, namespaces=nil, variables={}
- raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
- raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
- parser = XPathParser.new
- parser.namespaces = namespaces
- parser.variables = variables
- path = "*" unless path
- element = [element] unless element.kind_of? Array
- parser.parse(path, element).flatten[0]
- end
-
- # Iterates over nodes that match the given path, calling the supplied
- # block with the match.
- # element::
- # The context element
- # path::
- # The xpath to search for. If not supplied or nil, defaults to '*'
- # namespaces::
- # If supplied, a Hash which defines a namespace mapping
- # variables::
- # If supplied, a Hash which maps $variables in the query
- # to values. This can be used to avoid XPath injection attacks
- # or to automatically handle escaping string values.
- #
- # XPath.each( node ) { |el| ... }
- # XPath.each( node, '/*[@attr='v']' ) { |el| ... }
- # XPath.each( node, 'ancestor::x' ) { |el| ... }
- # XPath.each( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) \
- # {|el| ... }
- def XPath::each element, path=nil, namespaces=nil, variables={}, &block
- raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
- raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
- parser = XPathParser.new
- parser.namespaces = namespaces
- parser.variables = variables
- path = "*" unless path
- element = [element] unless element.kind_of? Array
- parser.parse(path, element).each( &block )
- end
-
- # Returns an array of nodes matching a given XPath.
- def XPath::match element, path=nil, namespaces=nil, variables={}
- parser = XPathParser.new
- parser.namespaces = namespaces
- parser.variables = variables
- path = "*" unless path
- element = [element] unless element.kind_of? Array
- parser.parse(path,element)
- end
- end
-end
diff --git a/lib/rexml/xpath_parser.rb b/lib/rexml/xpath_parser.rb
deleted file mode 100644
index 181b2b6e85..0000000000
--- a/lib/rexml/xpath_parser.rb
+++ /dev/null
@@ -1,704 +0,0 @@
-# frozen_string_literal: false
-require 'rexml/namespace'
-require 'rexml/xmltokens'
-require 'rexml/attribute'
-require 'rexml/syncenumerator'
-require 'rexml/parsers/xpathparser'
-
-class Object
- # provides a unified +clone+ operation, for REXML::XPathParser
- # to use across multiple Object types
- def dclone
- clone
- end
-end
-class Symbol
- # provides a unified +clone+ operation, for REXML::XPathParser
- # to use across multiple Object types
- def dclone ; self ; end
-end
-class Integer
- # provides a unified +clone+ operation, for REXML::XPathParser
- # to use across multiple Object types
- def dclone ; self ; end
-end
-class Float
- # provides a unified +clone+ operation, for REXML::XPathParser
- # to use across multiple Object types
- def dclone ; self ; end
-end
-class Array
- # provides a unified +clone+ operation, for REXML::XPathParser
- # to use across multiple Object+ types
- def dclone
- klone = self.clone
- klone.clear
- self.each{|v| klone << v.dclone}
- klone
- end
-end
-
-module REXML
- # You don't want to use this class. Really. Use XPath, which is a wrapper
- # for this class. Believe me. You don't want to poke around in here.
- # There is strange, dark magic at work in this code. Beware. Go back! Go
- # back while you still can!
- class XPathParser
- include XMLTokens
- LITERAL = /^'([^']*)'|^"([^"]*)"/u
-
- def initialize( )
- @parser = REXML::Parsers::XPathParser.new
- @namespaces = nil
- @variables = {}
- end
-
- def namespaces=( namespaces={} )
- Functions::namespace_context = namespaces
- @namespaces = namespaces
- end
-
- def variables=( vars={} )
- Functions::variables = vars
- @variables = vars
- end
-
- def parse path, nodeset
- path_stack = @parser.parse( path )
- match( path_stack, nodeset )
- end
-
- def get_first path, nodeset
- path_stack = @parser.parse( path )
- first( path_stack, nodeset )
- end
-
- def predicate path, nodeset
- path_stack = @parser.parse( path )
- expr( path_stack, nodeset )
- end
-
- def []=( variable_name, value )
- @variables[ variable_name ] = value
- end
-
-
- # Performs a depth-first (document order) XPath search, and returns the
- # first match. This is the fastest, lightest way to return a single result.
- #
- # FIXME: This method is incomplete!
- def first( path_stack, node )
- return nil if path.size == 0
-
- case path[0]
- when :document
- # do nothing
- return first( path[1..-1], node )
- when :child
- for c in node.children
- r = first( path[1..-1], c )
- return r if r
- end
- when :qname
- name = path[2]
- if node.name == name
- return node if path.size == 3
- return first( path[3..-1], node )
- else
- return nil
- end
- when :descendant_or_self
- r = first( path[1..-1], node )
- return r if r
- for c in node.children
- r = first( path, c )
- return r if r
- end
- when :node
- return first( path[1..-1], node )
- when :any
- return first( path[1..-1], node )
- end
- return nil
- end
-
-
- def match( path_stack, nodeset )
- r = expr( path_stack, nodeset )
- r
- end
-
- private
-
-
- # Returns a String namespace for a node, given a prefix
- # The rules are:
- #
- # 1. Use the supplied namespace mapping first.
- # 2. If no mapping was supplied, use the context node to look up the namespace
- def get_namespace( node, prefix )
- if @namespaces
- return @namespaces[prefix] || ''
- else
- return node.namespace( prefix ) if node.node_type == :element
- return ''
- end
- end
-
-
- # Expr takes a stack of path elements and a set of nodes (either a Parent
- # or an Array and returns an Array of matching nodes
- ALL = [ :attribute, :element, :text, :processing_instruction, :comment ]
- ELEMENTS = [ :element ]
- def expr( path_stack, nodeset, context=nil )
- node_types = ELEMENTS
- return nodeset if path_stack.length == 0 || nodeset.length == 0
- while path_stack.length > 0
- if nodeset.length == 0
- path_stack.clear
- return []
- end
- case (op = path_stack.shift)
- when :document
- nodeset = [ nodeset[0].root_node ]
-
- when :qname
- prefix = path_stack.shift
- name = path_stack.shift
- nodeset.delete_if do |node|
- # FIXME: This DOUBLES the time XPath searches take
- ns = get_namespace( node, prefix )
- if node.node_type == :element
- if node.name == name
- end
- end
- !(node.node_type == :element and
- node.name == name and
- node.namespace == ns )
- end
- node_types = ELEMENTS
-
- when :any
- nodeset.delete_if { |node| !node_types.include?(node.node_type) }
-
- when :self
- # This space left intentionally blank
-
- when :processing_instruction
- target = path_stack.shift
- nodeset.delete_if do |node|
- (node.node_type != :processing_instruction) or
- ( target!='' and ( node.target != target ) )
- end
-
- when :text
- nodeset.delete_if { |node| node.node_type != :text }
-
- when :comment
- nodeset.delete_if { |node| node.node_type != :comment }
-
- when :node
- # This space left intentionally blank
- node_types = ALL
-
- when :child
- new_nodeset = []
- nt = nil
- nodeset.each do |node|
- nt = node.node_type
- new_nodeset += node.children if nt == :element or nt == :document
- end
- nodeset = new_nodeset
- node_types = ELEMENTS
-
- when :literal
- return path_stack.shift
-
- when :attribute
- new_nodeset = []
- case path_stack.shift
- when :qname
- prefix = path_stack.shift
- name = path_stack.shift
- for element in nodeset
- if element.node_type == :element
- attrib = element.attribute( name, get_namespace(element, prefix) )
- new_nodeset << attrib if attrib
- end
- end
- when :any
- for element in nodeset
- if element.node_type == :element
- new_nodeset += element.attributes.to_a
- end
- end
- end
- nodeset = new_nodeset
-
- when :parent
- nodeset = nodeset.collect{|n| n.parent}.compact
- #nodeset = expr(path_stack.dclone, nodeset.collect{|n| n.parent}.compact)
- node_types = ELEMENTS
-
- when :ancestor
- new_nodeset = []
- nodeset.each do |node|
- while node.parent
- node = node.parent
- new_nodeset << node unless new_nodeset.include? node
- end
- end
- nodeset = new_nodeset
- node_types = ELEMENTS
-
- when :ancestor_or_self
- new_nodeset = []
- nodeset.each do |node|
- if node.node_type == :element
- new_nodeset << node
- while ( node.parent )
- node = node.parent
- new_nodeset << node unless new_nodeset.include? node
- end
- end
- end
- nodeset = new_nodeset
- node_types = ELEMENTS
-
- when :predicate
- new_nodeset = []
- subcontext = { :size => nodeset.size }
- pred = path_stack.shift
- nodeset.each_with_index { |node, index|
- subcontext[ :node ] = node
- subcontext[ :index ] = index+1
- pc = pred.dclone
- result = expr( pc, [node], subcontext )
- result = result[0] if result.kind_of? Array and result.length == 1
- if result.kind_of? Numeric
- new_nodeset << node if result == (index+1)
- elsif result.instance_of? Array
- if result.size > 0 and result.inject(false) {|k,s| s or k}
- new_nodeset << node if result.size > 0
- end
- else
- new_nodeset << node if result
- end
- }
- nodeset = new_nodeset
-=begin
- predicate = path_stack.shift
- ns = nodeset.clone
- result = expr( predicate, ns )
- if result.kind_of? Array
- nodeset = result.zip(ns).collect{|m,n| n if m}.compact
- else
- nodeset = result ? nodeset : []
- end
-=end
-
- when :descendant_or_self
- rv = descendant_or_self( path_stack, nodeset )
- path_stack.clear
- nodeset = rv
- node_types = ELEMENTS
-
- when :descendant
- results = []
- nt = nil
- nodeset.each do |node|
- nt = node.node_type
- results += expr( path_stack.dclone.unshift( :descendant_or_self ),
- node.children ) if nt == :element or nt == :document
- end
- nodeset = results
- node_types = ELEMENTS
-
- when :following_sibling
- results = []
- nodeset.each do |node|
- next if node.parent.nil?
- all_siblings = node.parent.children
- current_index = all_siblings.index( node )
- following_siblings = all_siblings[ current_index+1 .. -1 ]
- results += expr( path_stack.dclone, following_siblings )
- end
- nodeset = results
-
- when :preceding_sibling
- results = []
- nodeset.each do |node|
- next if node.parent.nil?
- all_siblings = node.parent.children
- current_index = all_siblings.index( node )
- preceding_siblings = all_siblings[ 0, current_index ].reverse
- results += preceding_siblings
- end
- nodeset = results
- node_types = ELEMENTS
-
- when :preceding
- new_nodeset = []
- nodeset.each do |node|
- new_nodeset += preceding( node )
- end
- nodeset = new_nodeset
- node_types = ELEMENTS
-
- when :following
- new_nodeset = []
- nodeset.each do |node|
- new_nodeset += following( node )
- end
- nodeset = new_nodeset
- node_types = ELEMENTS
-
- when :namespace
- new_nodeset = []
- prefix = path_stack.shift
- nodeset.each do |node|
- if (node.node_type == :element or node.node_type == :attribute)
- if @namespaces
- namespaces = @namespaces
- elsif (node.node_type == :element)
- namespaces = node.namespaces
- else
- namespaces = node.element.namesapces
- end
- if (node.namespace == namespaces[prefix])
- new_nodeset << node
- end
- end
- end
- nodeset = new_nodeset
-
- when :variable
- var_name = path_stack.shift
- return @variables[ var_name ]
-
- # :and, :or, :eq, :neq, :lt, :lteq, :gt, :gteq
- # TODO: Special case for :or and :and -- not evaluate the right
- # operand if the left alone determines result (i.e. is true for
- # :or and false for :and).
- when :eq, :neq, :lt, :lteq, :gt, :gteq, :or
- left = expr( path_stack.shift, nodeset.dup, context )
- right = expr( path_stack.shift, nodeset.dup, context )
- res = equality_relational_compare( left, op, right )
- return res
-
- when :and
- left = expr( path_stack.shift, nodeset.dup, context )
- return [] unless left
- if left.respond_to?(:inject) and !left.inject(false) {|a,b| a | b}
- return []
- end
- right = expr( path_stack.shift, nodeset.dup, context )
- res = equality_relational_compare( left, op, right )
- return res
-
- when :div
- left = Functions::number(expr(path_stack.shift, nodeset, context)).to_f
- right = Functions::number(expr(path_stack.shift, nodeset, context)).to_f
- return (left / right)
-
- when :mod
- left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- return (left % right)
-
- when :mult
- left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- return (left * right)
-
- when :plus
- left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- return (left + right)
-
- when :minus
- left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f
- return (left - right)
-
- when :union
- left = expr( path_stack.shift, nodeset, context )
- right = expr( path_stack.shift, nodeset, context )
- return (left | right)
-
- when :neg
- res = expr( path_stack, nodeset, context )
- return -(res.to_f)
-
- when :not
- when :function
- func_name = path_stack.shift.tr('-','_')
- arguments = path_stack.shift
- subcontext = context ? nil : { :size => nodeset.size }
-
- res = []
- cont = context
- nodeset.each_with_index { |n, i|
- if subcontext
- subcontext[:node] = n
- subcontext[:index] = i
- cont = subcontext
- end
- arg_clone = arguments.dclone
- args = arg_clone.collect { |arg|
- expr( arg, [n], cont )
- }
- Functions.context = cont
- res << Functions.send( func_name, *args )
- }
- return res
-
- end
- end # while
- return nodeset
- end
-
-
- ##########################################################
- # FIXME
- # The next two methods are BAD MOJO!
- # This is my achilles heel. If anybody thinks of a better
- # way of doing this, be my guest. This really sucks, but
- # it is a wonder it works at all.
- # ########################################################
-
- def descendant_or_self( path_stack, nodeset )
- rs = []
- d_o_s( path_stack, nodeset, rs )
- document_order(rs.flatten.compact)
- #rs.flatten.compact
- end
-
- def d_o_s( p, ns, r )
- nt = nil
- ns.each_index do |i|
- n = ns[i]
- x = expr( p.dclone, [ n ] )
- nt = n.node_type
- d_o_s( p, n.children, x ) if nt == :element or nt == :document and n.children.size > 0
- r.concat(x) if x.size > 0
- end
- end
-
-
- # Reorders an array of nodes so that they are in document order
- # It tries to do this efficiently.
- #
- # FIXME: I need to get rid of this, but the issue is that most of the XPath
- # interpreter functions as a filter, which means that we lose context going
- # in and out of function calls. If I knew what the index of the nodes was,
- # I wouldn't have to do this. Maybe add a document IDX for each node?
- # Problems with mutable documents. Or, rewrite everything.
- def document_order( array_of_nodes )
- new_arry = []
- array_of_nodes.each { |node|
- node_idx = []
- np = node.node_type == :attribute ? node.element : node
- while np.parent and np.parent.node_type == :element
- node_idx << np.parent.index( np )
- np = np.parent
- end
- new_arry << [ node_idx.reverse, node ]
- }
- new_arry.sort{ |s1, s2| s1[0] <=> s2[0] }.collect{ |s| s[1] }
- end
-
-
- def recurse( nodeset, &block )
- for node in nodeset
- yield node
- recurse( node, &block ) if node.node_type == :element
- end
- end
-
-
-
- # Builds a nodeset of all of the preceding nodes of the supplied node,
- # in reverse document order
- # preceding:: includes every element in the document that precedes this node,
- # except for ancestors
- def preceding( node )
- ancestors = []
- p = node.parent
- while p
- ancestors << p
- p = p.parent
- end
-
- acc = []
- p = preceding_node_of( node )
- while p
- if ancestors.include? p
- ancestors.delete(p)
- else
- acc << p
- end
- p = preceding_node_of( p )
- end
- acc
- end
-
- def preceding_node_of( node )
- psn = node.previous_sibling_node
- if psn.nil?
- if node.parent.nil? or node.parent.class == Document
- return nil
- end
- return node.parent
- #psn = preceding_node_of( node.parent )
- end
- while psn and psn.kind_of? Element and psn.children.size > 0
- psn = psn.children[-1]
- end
- psn
- end
-
- def following( node )
- acc = []
- p = next_sibling_node( node )
- while p
- acc << p
- p = following_node_of( p )
- end
- acc
- end
-
- def following_node_of( node )
- if node.kind_of? Element and node.children.size > 0
- return node.children[0]
- end
- return next_sibling_node(node)
- end
-
- def next_sibling_node(node)
- psn = node.next_sibling_node
- while psn.nil?
- if node.parent.nil? or node.parent.class == Document
- return nil
- end
- node = node.parent
- psn = node.next_sibling_node
- end
- return psn
- end
-
- def norm b
- case b
- when true, false
- return b
- when 'true', 'false'
- return Functions::boolean( b )
- when /^\d+(\.\d+)?$/
- return Functions::number( b )
- else
- return Functions::string( b )
- end
- end
-
- def equality_relational_compare( set1, op, set2 )
- if set1.kind_of? Array and set2.kind_of? Array
- if set1.size == 1 and set2.size == 1
- set1 = set1[0]
- set2 = set2[0]
- elsif set1.size == 0 or set2.size == 0
- nd = set1.size==0 ? set2 : set1
- rv = nd.collect { |il| compare( il, op, nil ) }
- return rv
- else
- res = []
- SyncEnumerator.new( set1, set2 ).each { |i1, i2|
- i1 = norm( i1 )
- i2 = norm( i2 )
- res << compare( i1, op, i2 )
- }
- return res
- end
- end
- # If one is nodeset and other is number, compare number to each item
- # in nodeset s.t. number op number(string(item))
- # If one is nodeset and other is string, compare string to each item
- # in nodeset s.t. string op string(item)
- # If one is nodeset and other is boolean, compare boolean to each item
- # in nodeset s.t. boolean op boolean(item)
- if set1.kind_of? Array or set2.kind_of? Array
- if set1.kind_of? Array
- a = set1
- b = set2
- else
- a = set2
- b = set1
- end
-
- case b
- when true, false
- return a.collect {|v| compare( Functions::boolean(v), op, b ) }
- when Numeric
- return a.collect {|v| compare( Functions::number(v), op, b )}
- when /^\d+(\.\d+)?$/
- b = Functions::number( b )
- return a.collect {|v| compare( Functions::number(v), op, b )}
- else
- b = Functions::string( b )
- return a.collect { |v| compare( Functions::string(v), op, b ) }
- end
- else
- # If neither is nodeset,
- # If op is = or !=
- # If either boolean, convert to boolean
- # If either number, convert to number
- # Else, convert to string
- # Else
- # Convert both to numbers and compare
- s1 = set1.to_s
- s2 = set2.to_s
- if s1 == 'true' or s1 == 'false' or s2 == 'true' or s2 == 'false'
- set1 = Functions::boolean( set1 )
- set2 = Functions::boolean( set2 )
- else
- if op == :eq or op == :neq
- if s1 =~ /^\d+(\.\d+)?$/ or s2 =~ /^\d+(\.\d+)?$/
- set1 = Functions::number( s1 )
- set2 = Functions::number( s2 )
- else
- set1 = Functions::string( set1 )
- set2 = Functions::string( set2 )
- end
- else
- set1 = Functions::number( set1 )
- set2 = Functions::number( set2 )
- end
- end
- return compare( set1, op, set2 )
- end
- return false
- end
-
- def compare a, op, b
- case op
- when :eq
- a == b
- when :neq
- a != b
- when :lt
- a < b
- when :lteq
- a <= b
- when :gt
- a > b
- when :gteq
- a >= b
- when :and
- a and b
- when :or
- a or b
- else
- false
- end
- end
- end
-end
diff --git a/lib/rinda/rinda.gemspec b/lib/rinda/rinda.gemspec
new file mode 100644
index 0000000000..0c13e3c2df
--- /dev/null
+++ b/lib/rinda/rinda.gemspec
@@ -0,0 +1,28 @@
+Gem::Specification.new do |spec|
+ spec.name = "rinda"
+ spec.version = "0.1.1"
+ spec.authors = ["Masatoshi SEKI"]
+ spec.email = ["seki@ruby-lang.org"]
+
+ spec.summary = %q{The Linda distributed computing paradigm in Ruby.}
+ spec.description = %q{The Linda distributed computing paradigm in Ruby.}
+ spec.homepage = "https://github.com/ruby/rinda"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "drb"
+ spec.add_dependency "ipaddr"
+ spec.add_dependency "forwardable"
+end
diff --git a/lib/rinda/ring.rb b/lib/rinda/ring.rb
index 34dc245122..948cfaf208 100644
--- a/lib/rinda/ring.rb
+++ b/lib/rinda/ring.rb
@@ -3,7 +3,7 @@
# Note: Rinda::Ring API is unstable.
#
require 'drb/drb'
-require 'rinda/rinda'
+require_relative 'rinda'
require 'ipaddr'
module Rinda
diff --git a/lib/rinda/tuplespace.rb b/lib/rinda/tuplespace.rb
index 47860bc8ae..6a41a7ba75 100644
--- a/lib/rinda/tuplespace.rb
+++ b/lib/rinda/tuplespace.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require 'monitor'
require 'drb/drb'
-require 'rinda/rinda'
+require_relative 'rinda'
require 'forwardable'
module Rinda
diff --git a/lib/rss.rb b/lib/rss.rb
deleted file mode 100644
index 1c7d72b9f7..0000000000
--- a/lib/rss.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-# frozen_string_literal: false
-##
-# = RSS reading and writing
-#
-# Really Simple Syndication (RSS) is a family of formats that describe 'feeds,'
-# specially constructed XML documents that allow an interested person to
-# subscribe and receive updates from a particular web service. This portion of
-# the standard library provides tooling to read and create these feeds.
-#
-# The standard library supports RSS 0.91, 1.0, 2.0, and Atom, a related format.
-# Here are some links to the standards documents for these formats:
-#
-# * RSS
-# * 0.9.1[http://www.rssboard.org/rss-0-9-1-netscape]
-# * 1.0[http://web.resource.org/rss/1.0/]
-# * 2.0[http://www.rssboard.org/rss-specification]
-# * Atom[http://tools.ietf.org/html/rfc4287]
-#
-# == Consuming RSS
-#
-# If you'd like to read someone's RSS feed with your Ruby code, you've come to
-# the right place. It's really easy to do this, but we'll need the help of
-# open-uri:
-#
-# require 'rss'
-# require 'open-uri'
-#
-# url = 'http://www.ruby-lang.org/en/feeds/news.rss'
-# open(url) do |rss|
-# feed = RSS::Parser.parse(rss)
-# puts "Title: #{feed.channel.title}"
-# feed.items.each do |item|
-# puts "Item: #{item.title}"
-# end
-# end
-#
-# As you can see, the workhorse is RSS::Parser#parse, which takes the source of
-# the feed and a parameter that performs validation on the feed. We get back an
-# object that has all of the data from our feed, accessible through methods.
-# This example shows getting the title out of the channel element, and looping
-# through the list of items.
-#
-# == Producing RSS
-#
-# Producing our own RSS feeds is easy as well. Let's make a very basic feed:
-#
-# require "rss"
-#
-# rss = RSS::Maker.make("atom") do |maker|
-# maker.channel.author = "matz"
-# maker.channel.updated = Time.now.to_s
-# maker.channel.about = "http://www.ruby-lang.org/en/feeds/news.rss"
-# maker.channel.title = "Example Feed"
-#
-# maker.items.new_item do |item|
-# item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/"
-# item.title = "Ruby 1.9.2-p136 is released"
-# item.updated = Time.now.to_s
-# end
-# end
-#
-# puts rss
-#
-# As you can see, this is a very Builder-like DSL. This code will spit out an
-# Atom feed with one item. If we needed a second item, we'd make another block
-# with maker.items.new_item and build a second one.
-#
-# == Copyright
-#
-# Copyright (c) 2003-2007 Kouhei Sutou <kou@cozmixng.org>
-#
-# You can redistribute it and/or modify it under the same terms as Ruby.
-#
-# There is an additional tutorial by the author of RSS at:
-# http://www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser%3A%3ATutorial.en
-
-module RSS
-end
-
-require 'rss/1.0'
-require 'rss/2.0'
-require 'rss/atom'
-require 'rss/content'
-require 'rss/dublincore'
-require 'rss/image'
-require 'rss/itunes'
-require 'rss/slash'
-require 'rss/syndication'
-require 'rss/taxonomy'
-require 'rss/trackback'
-
-require "rss/maker"
diff --git a/lib/rss/0.9.rb b/lib/rss/0.9.rb
deleted file mode 100644
index d852a6a85e..0000000000
--- a/lib/rss/0.9.rb
+++ /dev/null
@@ -1,462 +0,0 @@
-# frozen_string_literal: false
-require "rss/parser"
-
-module RSS
-
- ##
- # = RSS 0.9 support
- #
- # RSS has three different versions. This module contains support for version
- # 0.9.1[http://www.rssboard.org/rss-0-9-1-netscape].
- #
- # == Producing RSS 0.9
- #
- # Producing our own RSS feeds is easy as well. Let's make a very basic feed:
- #
- # require "rss"
- #
- # rss = RSS::Maker.make("0.91") do |maker|
- # maker.channel.language = "en"
- # maker.channel.author = "matz"
- # maker.channel.updated = Time.now.to_s
- # maker.channel.link = "http://www.ruby-lang.org/en/feeds/news.rss"
- # maker.channel.title = "Example Feed"
- # maker.channel.description = "A longer description of my feed."
- # maker.image.url = "http://www.ruby-lang.org/images/logo.gif"
- # maker.image.title = "An image"
- # maker.items.new_item do |item|
- # item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/"
- # item.title = "Ruby 1.9.2-p136 is released"
- # item.updated = Time.now.to_s
- # end
- # end
- #
- # puts rss
- #
- # As you can see, this is a very Builder-like DSL. This code will spit out an
- # RSS 0.9 feed with one item. If we needed a second item, we'd make another
- # block with maker.items.new_item and build a second one.
- module RSS09
- NSPOOL = {}
- ELEMENTS = []
-
- def self.append_features(klass)
- super
-
- klass.install_must_call_validator('', "")
- end
- end
-
- class Rss < Element
-
- include RSS09
- include RootElementMixin
-
- %w(channel).each do |name|
- install_have_child_element(name, "", nil)
- end
-
- attr_writer :feed_version
- alias_method(:rss_version, :feed_version)
- alias_method(:rss_version=, :feed_version=)
-
- def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
- super
- @feed_type = "rss"
- end
-
- def items
- if @channel
- @channel.items
- else
- []
- end
- end
-
- def image
- if @channel
- @channel.image
- else
- nil
- end
- end
-
- def textinput
- if @channel
- @channel.textInput
- else
- nil
- end
- end
-
- def setup_maker_elements(maker)
- super
- items.each do |item|
- item.setup_maker(maker.items)
- end
- image.setup_maker(maker) if image
- textinput.setup_maker(maker) if textinput
- end
-
- private
- def _attrs
- [
- ["version", true, "feed_version"],
- ]
- end
-
- class Channel < Element
-
- include RSS09
-
- [
- ["title", nil, :text],
- ["link", nil, :text],
- ["description", nil, :text],
- ["language", nil, :text],
- ["copyright", "?", :text],
- ["managingEditor", "?", :text],
- ["webMaster", "?", :text],
- ["rating", "?", :text],
- ["pubDate", "?", :date, :rfc822],
- ["lastBuildDate", "?", :date, :rfc822],
- ["docs", "?", :text],
- ["cloud", "?", :have_attribute],
- ["skipDays", "?", :have_child],
- ["skipHours", "?", :have_child],
- ["image", nil, :have_child],
- ["item", "*", :have_children],
- ["textInput", "?", :have_child],
- ].each do |name, occurs, type, *args|
- __send__("install_#{type}_element", name, "", occurs, name, *args)
- end
- alias date pubDate
- alias date= pubDate=
-
- private
- def maker_target(maker)
- maker.channel
- end
-
- def setup_maker_elements(channel)
- super
- [
- [skipDays, "day"],
- [skipHours, "hour"],
- ].each do |skip, key|
- if skip
- skip.__send__("#{key}s").each do |val|
- target_skips = channel.__send__("skip#{key.capitalize}s")
- new_target = target_skips.__send__("new_#{key}")
- new_target.content = val.content
- end
- end
- end
- end
-
- def not_need_to_call_setup_maker_variables
- %w(image textInput)
- end
-
- class SkipDays < Element
- include RSS09
-
- [
- ["day", "*"]
- ].each do |name, occurs|
- install_have_children_element(name, "", occurs)
- end
-
- class Day < Element
- include RSS09
-
- content_setup
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.content = args[0]
- end
- end
-
- end
-
- end
-
- class SkipHours < Element
- include RSS09
-
- [
- ["hour", "*"]
- ].each do |name, occurs|
- install_have_children_element(name, "", occurs)
- end
-
- class Hour < Element
- include RSS09
-
- content_setup(:integer)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.content = args[0]
- end
- end
- end
-
- end
-
- class Image < Element
-
- include RSS09
-
- %w(url title link).each do |name|
- install_text_element(name, "", nil)
- end
- [
- ["width", :integer],
- ["height", :integer],
- ["description"],
- ].each do |name, type|
- install_text_element(name, "", "?", name, type)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.url = args[0]
- self.title = args[1]
- self.link = args[2]
- self.width = args[3]
- self.height = args[4]
- self.description = args[5]
- end
- end
-
- private
- def maker_target(maker)
- maker.image
- end
- end
-
- class Cloud < Element
-
- include RSS09
-
- [
- ["domain", "", true],
- ["port", "", true, :integer],
- ["path", "", true],
- ["registerProcedure", "", true],
- ["protocol", "", true],
- ].each do |name, uri, required, type|
- install_get_attribute(name, uri, required, type)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.domain = args[0]
- self.port = args[1]
- self.path = args[2]
- self.registerProcedure = args[3]
- self.protocol = args[4]
- end
- end
- end
-
- class Item < Element
-
- include RSS09
-
- [
- ["title", '?', :text],
- ["link", '?', :text],
- ["description", '?', :text],
- ["category", '*', :have_children, "categories"],
- ["source", '?', :have_child],
- ["enclosure", '?', :have_child],
- ].each do |tag, occurs, type, *args|
- __send__("install_#{type}_element", tag, "", occurs, tag, *args)
- end
-
- private
- def maker_target(items)
- if items.respond_to?("items")
- # For backward compatibility
- items = items.items
- end
- items.new_item
- end
-
- def setup_maker_element(item)
- super
- @enclosure.setup_maker(item) if @enclosure
- @source.setup_maker(item) if @source
- end
-
- class Source < Element
-
- include RSS09
-
- [
- ["url", "", true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required)
- end
-
- content_setup
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.url = args[0]
- self.content = args[1]
- end
- end
-
- private
- def maker_target(item)
- item.source
- end
-
- def setup_maker_attributes(source)
- source.url = url
- source.content = content
- end
- end
-
- class Enclosure < Element
-
- include RSS09
-
- [
- ["url", "", true],
- ["length", "", true, :integer],
- ["type", "", true],
- ].each do |name, uri, required, type|
- install_get_attribute(name, uri, required, type)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.url = args[0]
- self.length = args[1]
- self.type = args[2]
- end
- end
-
- private
- def maker_target(item)
- item.enclosure
- end
-
- def setup_maker_attributes(enclosure)
- enclosure.url = url
- enclosure.length = length
- enclosure.type = type
- end
- end
-
- class Category < Element
-
- include RSS09
-
- [
- ["domain", "", false]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required)
- end
-
- content_setup
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.domain = args[0]
- self.content = args[1]
- end
- end
-
- private
- def maker_target(item)
- item.new_category
- end
-
- def setup_maker_attributes(category)
- category.domain = domain
- category.content = content
- end
-
- end
-
- end
-
- class TextInput < Element
-
- include RSS09
-
- %w(title description name link).each do |name|
- install_text_element(name, "", nil)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.title = args[0]
- self.description = args[1]
- self.name = args[2]
- self.link = args[3]
- end
- end
-
- private
- def maker_target(maker)
- maker.textinput
- end
- end
-
- end
-
- end
-
- RSS09::ELEMENTS.each do |name|
- BaseListener.install_get_text_element("", name, name)
- end
-
- module ListenerMixin
- private
- def initial_start_rss(tag_name, prefix, attrs, ns)
- check_ns(tag_name, prefix, ns, "", false)
-
- @rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
- @rss.do_validate = @do_validate
- @rss.xml_stylesheets = @xml_stylesheets
- @last_element = @rss
- pr = Proc.new do |text, tags|
- @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
- end
- @proc_stack.push(pr)
- end
-
- end
-
-end
diff --git a/lib/rss/1.0.rb b/lib/rss/1.0.rb
deleted file mode 100644
index fb63937c5e..0000000000
--- a/lib/rss/1.0.rb
+++ /dev/null
@@ -1,485 +0,0 @@
-# frozen_string_literal: false
-require "rss/parser"
-
-module RSS
-
- ##
- # = RSS 1.0 support
- #
- # RSS has three different versions. This module contains support for version
- # 1.0[http://web.resource.org/rss/1.0/]
- #
- # == Producing RSS 1.0
- #
- # Producing our own RSS feeds is easy as well. Let's make a very basic feed:
- #
- # require "rss"
- #
- # rss = RSS::Maker.make("1.0") do |maker|
- # maker.channel.language = "en"
- # maker.channel.author = "matz"
- # maker.channel.about = "About my feed."
- # maker.channel.updated = Time.now.to_s
- # maker.channel.link = "http://www.ruby-lang.org/en/feeds/news.rss"
- # maker.channel.title = "Example Feed"
- # maker.channel.description = "A longer description of my feed."
- # maker.items.new_item do |item|
- # item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/"
- # item.title = "Ruby 1.9.2-p136 is released"
- # item.updated = Time.now.to_s
- # end
- # end
- #
- # puts rss
- #
- # As you can see, this is a very Builder-like DSL. This code will spit out an
- # RSS 1.0 feed with one item. If we needed a second item, we'd make another
- # block with maker.items.new_item and build a second one.
- module RSS10
- NSPOOL = {}
- ELEMENTS = []
-
- def self.append_features(klass)
- super
-
- klass.install_must_call_validator('', ::RSS::URI)
- end
-
- end
-
- class RDF < Element
-
- include RSS10
- include RootElementMixin
-
- class << self
-
- def required_uri
- URI
- end
-
- end
-
- @tag_name = 'RDF'
-
- PREFIX = 'rdf'
- URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-
- install_ns('', ::RSS::URI)
- install_ns(PREFIX, URI)
-
- [
- ["channel", nil],
- ["image", "?"],
- ["item", "+", :children],
- ["textinput", "?"],
- ].each do |tag, occurs, type|
- type ||= :child
- __send__("install_have_#{type}_element", tag, ::RSS::URI, occurs)
- end
-
- alias_method(:rss_version, :feed_version)
- def initialize(version=nil, encoding=nil, standalone=nil)
- super('1.0', version, encoding, standalone)
- @feed_type = "rss"
- end
-
- def full_name
- tag_name_with_prefix(PREFIX)
- end
-
- class Li < Element
-
- include RSS10
-
- class << self
- def required_uri
- URI
- end
- end
-
- [
- ["resource", [URI, ""], true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.resource = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(PREFIX)
- end
- end
-
- class Seq < Element
-
- include RSS10
-
- Li = ::RSS::RDF::Li
-
- class << self
- def required_uri
- URI
- end
- end
-
- @tag_name = 'Seq'
-
- install_have_children_element("li", URI, "*")
- install_must_call_validator('rdf', ::RSS::RDF::URI)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- @li = args[0] if args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(PREFIX)
- end
-
- def setup_maker(target)
- lis.each do |li|
- target << li.resource
- end
- end
- end
-
- class Bag < Element
-
- include RSS10
-
- Li = ::RSS::RDF::Li
-
- class << self
- def required_uri
- URI
- end
- end
-
- @tag_name = 'Bag'
-
- install_have_children_element("li", URI, "*")
- install_must_call_validator('rdf', URI)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- @li = args[0] if args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(PREFIX)
- end
-
- def setup_maker(target)
- lis.each do |li|
- target << li.resource
- end
- end
- end
-
- class Channel < Element
-
- include RSS10
-
- class << self
-
- def required_uri
- ::RSS::URI
- end
-
- end
-
- [
- ["about", URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{PREFIX}:#{name}")
- end
-
- [
- ['title', nil, :text],
- ['link', nil, :text],
- ['description', nil, :text],
- ['image', '?', :have_child],
- ['items', nil, :have_child],
- ['textinput', '?', :have_child],
- ].each do |tag, occurs, type|
- __send__("install_#{type}_element", tag, ::RSS::URI, occurs)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.about = args[0]
- end
- end
-
- private
- def maker_target(maker)
- maker.channel
- end
-
- def setup_maker_attributes(channel)
- channel.about = about
- end
-
- class Image < Element
-
- include RSS10
-
- class << self
-
- def required_uri
- ::RSS::URI
- end
-
- end
-
- [
- ["resource", URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{PREFIX}:#{name}")
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.resource = args[0]
- end
- end
- end
-
- class Textinput < Element
-
- include RSS10
-
- class << self
-
- def required_uri
- ::RSS::URI
- end
-
- end
-
- [
- ["resource", URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{PREFIX}:#{name}")
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.resource = args[0]
- end
- end
- end
-
- class Items < Element
-
- include RSS10
-
- Seq = ::RSS::RDF::Seq
-
- class << self
-
- def required_uri
- ::RSS::URI
- end
-
- end
-
- install_have_child_element("Seq", URI, nil)
- install_must_call_validator('rdf', URI)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.Seq = args[0]
- end
- self.Seq ||= Seq.new
- end
-
- def resources
- if @Seq
- @Seq.lis.collect do |li|
- li.resource
- end
- else
- []
- end
- end
- end
- end
-
- class Image < Element
-
- include RSS10
-
- class << self
-
- def required_uri
- ::RSS::URI
- end
-
- end
-
- [
- ["about", URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{PREFIX}:#{name}")
- end
-
- %w(title url link).each do |name|
- install_text_element(name, ::RSS::URI, nil)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.about = args[0]
- end
- end
-
- private
- def maker_target(maker)
- maker.image
- end
- end
-
- class Item < Element
-
- include RSS10
-
- class << self
-
- def required_uri
- ::RSS::URI
- end
-
- end
-
-
- [
- ["about", URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{PREFIX}:#{name}")
- end
-
- [
- ["title", nil],
- ["link", nil],
- ["description", "?"],
- ].each do |tag, occurs|
- install_text_element(tag, ::RSS::URI, occurs)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.about = args[0]
- end
- end
-
- private
- def maker_target(items)
- if items.respond_to?("items")
- # For backward compatibility
- items = items.items
- end
- items.new_item
- end
- end
-
- class Textinput < Element
-
- include RSS10
-
- class << self
-
- def required_uri
- ::RSS::URI
- end
-
- end
-
- [
- ["about", URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{PREFIX}:#{name}")
- end
-
- %w(title description name link).each do |name|
- install_text_element(name, ::RSS::URI, nil)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.about = args[0]
- end
- end
-
- private
- def maker_target(maker)
- maker.textinput
- end
- end
-
- end
-
- RSS10::ELEMENTS.each do |name|
- BaseListener.install_get_text_element(URI, name, name)
- end
-
- module ListenerMixin
- private
- def initial_start_RDF(tag_name, prefix, attrs, ns)
- check_ns(tag_name, prefix, ns, RDF::URI, false)
-
- @rss = RDF.new(@version, @encoding, @standalone)
- @rss.do_validate = @do_validate
- @rss.xml_stylesheets = @xml_stylesheets
- @last_element = @rss
- pr = Proc.new do |text, tags|
- @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
- end
- @proc_stack.push(pr)
- end
- end
-
-end
diff --git a/lib/rss/2.0.rb b/lib/rss/2.0.rb
deleted file mode 100644
index 13f9ade918..0000000000
--- a/lib/rss/2.0.rb
+++ /dev/null
@@ -1,143 +0,0 @@
-# frozen_string_literal: false
-require "rss/0.9"
-
-module RSS
-
- ##
- # = RSS 2.0 support
- #
- # RSS has three different versions. This module contains support for version
- # 2.0[http://www.rssboard.org/rss-specification]
- #
- # == Producing RSS 2.0
- #
- # Producing our own RSS feeds is easy as well. Let's make a very basic feed:
- #
- # require "rss"
- #
- # rss = RSS::Maker.make("2.0") do |maker|
- # maker.channel.language = "en"
- # maker.channel.author = "matz"
- # maker.channel.updated = Time.now.to_s
- # maker.channel.link = "http://www.ruby-lang.org/en/feeds/news.rss"
- # maker.channel.title = "Example Feed"
- # maker.channel.description = "A longer description of my feed."
- # maker.items.new_item do |item|
- # item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/"
- # item.title = "Ruby 1.9.2-p136 is released"
- # item.updated = Time.now.to_s
- # end
- # end
- #
- # puts rss
- #
- # As you can see, this is a very Builder-like DSL. This code will spit out an
- # RSS 2.0 feed with one item. If we needed a second item, we'd make another
- # block with maker.items.new_item and build a second one.
- class Rss
-
- class Channel
-
- [
- ["generator"],
- ["ttl", :integer],
- ].each do |name, type|
- install_text_element(name, "", "?", name, type)
- end
-
- [
- %w(category categories),
- ].each do |name, plural_name|
- install_have_children_element(name, "", "*", name, plural_name)
- end
-
- [
- ["image", "?"],
- ["language", "?"],
- ].each do |name, occurs|
- install_model(name, "", occurs)
- end
-
- Category = Item::Category
-
- class Item
-
- [
- ["comments", "?"],
- ["author", "?"],
- ].each do |name, occurs|
- install_text_element(name, "", occurs)
- end
-
- [
- ["pubDate", '?'],
- ].each do |name, occurs|
- install_date_element(name, "", occurs, name, 'rfc822')
- end
- alias date pubDate
- alias date= pubDate=
-
- [
- ["guid", '?'],
- ].each do |name, occurs|
- install_have_child_element(name, "", occurs)
- end
-
- private
- alias _setup_maker_element setup_maker_element
- def setup_maker_element(item)
- _setup_maker_element(item)
- @guid.setup_maker(item) if @guid
- end
-
- class Guid < Element
-
- include RSS09
-
- [
- ["isPermaLink", "", false, :boolean]
- ].each do |name, uri, required, type|
- install_get_attribute(name, uri, required, type)
- end
-
- content_setup
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.isPermaLink = args[0]
- self.content = args[1]
- end
- end
-
- alias_method :_PermaLink?, :PermaLink?
- private :_PermaLink?
- def PermaLink?
- perma = _PermaLink?
- perma or perma.nil?
- end
-
- private
- def maker_target(item)
- item.guid
- end
-
- def setup_maker_attributes(guid)
- guid.isPermaLink = isPermaLink
- guid.content = content
- end
- end
-
- end
-
- end
-
- end
-
- RSS09::ELEMENTS.each do |name|
- BaseListener.install_get_text_element("", name, name)
- end
-
-end
diff --git a/lib/rss/atom.rb b/lib/rss/atom.rb
deleted file mode 100644
index 38e927478c..0000000000
--- a/lib/rss/atom.rb
+++ /dev/null
@@ -1,1025 +0,0 @@
-# frozen_string_literal: false
-require 'rss/parser'
-
-module RSS
- ##
- # Atom is an XML-based document format that is used to describe 'feeds' of related information.
- # A typical use is in a news feed where the information is periodically updated and which users
- # can subscribe to. The Atom format is described in http://tools.ietf.org/html/rfc4287
- #
- # The Atom module provides support in reading and creating feeds.
- #
- # See the RSS module for examples consuming and creating feeds.
- module Atom
-
- ##
- # The Atom URI W3C Namespace
-
- URI = "http://www.w3.org/2005/Atom"
-
- ##
- # The XHTML URI W3C Namespace
-
- XHTML_URI = "http://www.w3.org/1999/xhtml"
-
- module CommonModel
- NSPOOL = {}
- ELEMENTS = []
-
- def self.append_features(klass)
- super
- klass.install_must_call_validator("atom", URI)
- [
- ["lang", :xml],
- ["base", :xml],
- ].each do |name, uri, required|
- klass.install_get_attribute(name, uri, required, [nil, :inherit])
- end
- klass.class_eval do
- class << self
- # Returns the Atom URI W3C Namespace
- def required_uri
- URI
- end
-
- # Returns true
- def need_parent?
- true
- end
- end
- end
- end
- end
-
- module ContentModel
- module ClassMethods
- def content_type
- @content_type ||= nil
- end
- end
-
- class << self
- def append_features(klass)
- super
- klass.extend(ClassMethods)
- klass.content_setup(klass.content_type, klass.tag_name)
- end
- end
-
- def maker_target(target)
- target
- end
-
- private
- def setup_maker_element_writer
- "#{self.class.name.split(/::/).last.downcase}="
- end
-
- def setup_maker_element(target)
- target.__send__(setup_maker_element_writer, content)
- super
- end
- end
-
- module URIContentModel
- class << self
- def append_features(klass)
- super
- klass.class_eval do
- @content_type = [nil, :uri]
- include(ContentModel)
- end
- end
- end
- end
-
- # The TextConstruct module is used to define a Text construct Atom element,
- # which is used to store small quantities of human-readable text.
- #
- # The TextConstruct has a type attribute, e.g. text, html, xhtml
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#text.constructs
- module TextConstruct
- def self.append_features(klass)
- super
- klass.class_eval do
- [
- ["type", ""],
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, :text_type)
- end
-
- content_setup
- add_need_initialize_variable("xhtml")
-
- class << self
- def xml_getter
- "xhtml"
- end
-
- def xml_setter
- "xhtml="
- end
- end
- end
- end
-
- attr_writer :xhtml
-
- # Returns or builds the XHTML content.
- def xhtml
- return @xhtml if @xhtml.nil?
- if @xhtml.is_a?(XML::Element) and
- [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
- return @xhtml
- end
-
- children = @xhtml
- children = [children] unless children.is_a?(Array)
- XML::Element.new("div", nil, XHTML_URI,
- {"xmlns" => XHTML_URI}, children)
- end
-
- # Returns true if type is "xhtml".
- def have_xml_content?
- @type == "xhtml"
- end
-
- # Raises a MissingTagError or NotExpectedTagError
- # if the element is not properly formatted.
- def atom_validate(ignore_unknown_element, tags, uri)
- if have_xml_content?
- if @xhtml.nil?
- raise MissingTagError.new("div", tag_name)
- end
- unless [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
- raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name)
- end
- end
- end
-
- private
- def maker_target(target)
- target.__send__(self.class.name.split(/::/).last.downcase) {|x| x}
- end
-
- def setup_maker_attributes(target)
- target.type = type
- target.content = content
- target.xml_content = @xhtml
- end
- end
-
- # The PersonConstruct module is used to define a person Atom element that can be
- # used to describe a person, corporation or similar entity.
- #
- # The PersonConstruct has a Name, Uri and Email child elements.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#atomPersonConstruct
- module PersonConstruct
-
- # Adds attributes for name, uri, and email to the +klass+
- def self.append_features(klass)
- super
- klass.class_eval do
- [
- ["name", nil],
- ["uri", "?"],
- ["email", "?"],
- ].each do |tag, occurs|
- install_have_attribute_element(tag, URI, occurs, nil, :content)
- end
- end
- end
-
- def maker_target(target)
- target.__send__("new_#{self.class.name.split(/::/).last.downcase}")
- end
-
- # The name of the person or entity.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.name
- class Name < RSS::Element
- include CommonModel
- include ContentModel
- end
-
- # The URI of the person or entity.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.uri
- class Uri < RSS::Element
- include CommonModel
- include URIContentModel
- end
-
- # The email of the person or entity.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.email
- class Email < RSS::Element
- include CommonModel
- include ContentModel
- end
- end
-
- # Element used to describe an Atom date and time in the ISO 8601 format
- #
- # Examples:
- # * 2013-03-04T15:30:02Z
- # * 2013-03-04T10:30:02-05:00
- module DateConstruct
- def self.append_features(klass)
- super
- klass.class_eval do
- @content_type = :w3cdtf
- include(ContentModel)
- end
- end
-
- # Raises NotAvailableValueError if element content is nil
- def atom_validate(ignore_unknown_element, tags, uri)
- raise NotAvailableValueError.new(tag_name, "") if content.nil?
- end
- end
-
- module DuplicateLinkChecker
- # Checks if there are duplicate links with the same type and hreflang attributes
- # that have an alternate (or empty) rel attribute
- #
- # Raises a TooMuchTagError if there are duplicates found
- def validate_duplicate_links(links)
- link_infos = {}
- links.each do |link|
- rel = link.rel || "alternate"
- next unless rel == "alternate"
- key = [link.hreflang, link.type]
- if link_infos.has_key?(key)
- raise TooMuchTagError.new("link", tag_name)
- end
- link_infos[key] = true
- end
- end
- end
-
- # Defines the top-level element of an Atom Feed Document.
- # It consists of a number of children Entry elements,
- # and has the following attributes:
- #
- # * author
- # * categories
- # * category
- # * content
- # * contributor
- # * entries (aliased as items)
- # * entry
- # * generator
- # * icon
- # * id
- # * link
- # * logo
- # * rights
- # * subtitle
- # * title
- # * updated
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.feed
- class Feed < RSS::Element
- include RootElementMixin
- include CommonModel
- include DuplicateLinkChecker
-
- install_ns('', URI)
-
- [
- ["author", "*", :children],
- ["category", "*", :children, "categories"],
- ["contributor", "*", :children],
- ["generator", "?"],
- ["icon", "?", nil, :content],
- ["id", nil, nil, :content],
- ["link", "*", :children],
- ["logo", "?"],
- ["rights", "?"],
- ["subtitle", "?", nil, :content],
- ["title", nil, nil, :content],
- ["updated", nil, nil, :content],
- ["entry", "*", :children, "entries"],
- ].each do |tag, occurs, type, *args|
- type ||= :child
- __send__("install_have_#{type}_element",
- tag, URI, occurs, tag, *args)
- end
-
- # Creates a new Atom feed
- def initialize(version=nil, encoding=nil, standalone=nil)
- super("1.0", version, encoding, standalone)
- @feed_type = "atom"
- @feed_subtype = "feed"
- end
-
- alias_method :items, :entries
-
- # Returns true if there are any authors for the feed or any of the Entry
- # child elements have an author
- def have_author?
- authors.any? {|author| !author.to_s.empty?} or
- entries.any? {|entry| entry.have_author?(false)}
- end
-
- private
- def atom_validate(ignore_unknown_element, tags, uri)
- unless have_author?
- raise MissingTagError.new("author", tag_name)
- end
- validate_duplicate_links(links)
- end
-
- def have_required_elements?
- super and have_author?
- end
-
- def maker_target(maker)
- maker.channel
- end
-
- def setup_maker_element(channel)
- prev_dc_dates = channel.dc_dates.to_a.dup
- super
- channel.about = id.content if id
- channel.dc_dates.replace(prev_dc_dates)
- end
-
- def setup_maker_elements(channel)
- super
- items = channel.maker.items
- entries.each do |entry|
- entry.setup_maker(items)
- end
- end
-
- # PersonConstruct that contains information regarding the author
- # of a Feed or Entry.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.author
- class Author < RSS::Element
- include CommonModel
- include PersonConstruct
- end
-
- # Contains information about a category associated with a Feed or Entry.
- # It has the following attributes:
- #
- # * term
- # * scheme
- # * label
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.category
- class Category < RSS::Element
- include CommonModel
-
- [
- ["term", "", true],
- ["scheme", "", false, [nil, :uri]],
- ["label", ""],
- ].each do |name, uri, required, type|
- install_get_attribute(name, uri, required, type)
- end
-
- private
- def maker_target(target)
- target.new_category
- end
- end
-
- # PersonConstruct that contains information regarding the
- # contributors of a Feed or Entry.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.contributor
- class Contributor < RSS::Element
- include CommonModel
- include PersonConstruct
- end
-
- # Contains information on the agent used to generate the feed.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.generator
- class Generator < RSS::Element
- include CommonModel
- include ContentModel
-
- [
- ["uri", "", false, [nil, :uri]],
- ["version", ""],
- ].each do |name, uri, required, type|
- install_get_attribute(name, uri, required, type)
- end
-
- private
- def setup_maker_attributes(target)
- target.generator do |generator|
- generator.uri = uri if uri
- generator.version = version if version
- end
- end
- end
-
- # Defines an image that provides a visual identification for a eed.
- # The image should have an aspect ratio of 1:1.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.icon
- class Icon < RSS::Element
- include CommonModel
- include URIContentModel
- end
-
- # Defines the Universally Unique Identifier (UUID) for a Feed or Entry.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.id
- class Id < RSS::Element
- include CommonModel
- include URIContentModel
- end
-
- # Defines a reference to a Web resource. It has the following
- # attributes:
- #
- # * href
- # * rel
- # * type
- # * hreflang
- # * title
- # * length
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.link
- class Link < RSS::Element
- include CommonModel
-
- [
- ["href", "", true, [nil, :uri]],
- ["rel", ""],
- ["type", ""],
- ["hreflang", ""],
- ["title", ""],
- ["length", ""],
- ].each do |name, uri, required, type|
- install_get_attribute(name, uri, required, type)
- end
-
- private
- def maker_target(target)
- target.new_link
- end
- end
-
- # Defines an image that provides a visual identification for the Feed.
- # The image should have an aspect ratio of 2:1 (horizontal:vertical).
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.logo
- class Logo < RSS::Element
- include CommonModel
- include URIContentModel
-
- def maker_target(target)
- target.maker.image
- end
-
- private
- def setup_maker_element_writer
- "url="
- end
- end
-
- # TextConstruct that contains copyright information regarding
- # the content in an Entry or Feed. It should not be used to
- # convey machine readable licensing information.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.rights
- class Rights < RSS::Element
- include CommonModel
- include TextConstruct
- end
-
- # TextConstruct that conveys a description or subtitle for a Feed.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.subtitle
- class Subtitle < RSS::Element
- include CommonModel
- include TextConstruct
- end
-
- # TextConstruct that conveys a description or title for a Feed or Entry.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.title
- class Title < RSS::Element
- include CommonModel
- include TextConstruct
- end
-
- # DateConstruct indicating the most recent time when a Feed or
- # Entry was modified in a way the publisher considers
- # significant.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.updated
- class Updated < RSS::Element
- include CommonModel
- include DateConstruct
- end
-
- # Defines a child Atom Entry element of an Atom Feed element.
- # It has the following attributes:
- #
- # * author
- # * category
- # * categories
- # * content
- # * contributor
- # * id
- # * link
- # * published
- # * rights
- # * source
- # * summary
- # * title
- # * updated
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.entry
- class Entry < RSS::Element
- include CommonModel
- include DuplicateLinkChecker
-
- [
- ["author", "*", :children],
- ["category", "*", :children, "categories"],
- ["content", "?", :child],
- ["contributor", "*", :children],
- ["id", nil, nil, :content],
- ["link", "*", :children],
- ["published", "?", :child, :content],
- ["rights", "?", :child],
- ["source", "?"],
- ["summary", "?", :child],
- ["title", nil],
- ["updated", nil, :child, :content],
- ].each do |tag, occurs, type, *args|
- type ||= :attribute
- __send__("install_have_#{type}_element",
- tag, URI, occurs, tag, *args)
- end
-
- # Returns whether any of the following are true:
- #
- # * There are any authors in the feed
- # * If the parent element has an author and the +check_parent+
- # parameter was given.
- # * There is a source element that has an author
- def have_author?(check_parent=true)
- authors.any? {|author| !author.to_s.empty?} or
- (check_parent and @parent and @parent.have_author?) or
- (source and source.have_author?)
- end
-
- private
- def atom_validate(ignore_unknown_element, tags, uri)
- unless have_author?
- raise MissingTagError.new("author", tag_name)
- end
- validate_duplicate_links(links)
- end
-
- def have_required_elements?
- super and have_author?
- end
-
- def maker_target(items)
- if items.respond_to?("items")
- # For backward compatibility
- items = items.items
- end
- items.new_item
- end
-
- # Feed::Author
- Author = Feed::Author
- # Feed::Category
- Category = Feed::Category
-
- # Contains or links to the content of the Entry.
- # It has the following attributes:
- #
- # * type
- # * src
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.content
- class Content < RSS::Element
- include CommonModel
-
- class << self
- def xml_setter
- "xml="
- end
-
- def xml_getter
- "xml"
- end
- end
-
- [
- ["type", ""],
- ["src", "", false, [nil, :uri]],
- ].each do |name, uri, required, type|
- install_get_attribute(name, uri, required, type)
- end
-
- content_setup
- add_need_initialize_variable("xml")
-
- # Returns the element content in XML.
- attr_writer :xml
-
- # Returns true if the element has inline XML content.
- def have_xml_content?
- inline_xhtml? or inline_other_xml?
- end
-
- # Returns or builds the element content in XML.
- def xml
- return @xml unless inline_xhtml?
- return @xml if @xml.nil?
- if @xml.is_a?(XML::Element) and
- [@xml.name, @xml.uri] == ["div", XHTML_URI]
- return @xml
- end
-
- children = @xml
- children = [children] unless children.is_a?(Array)
- XML::Element.new("div", nil, XHTML_URI,
- {"xmlns" => XHTML_URI}, children)
- end
-
- # Returns the element content in XHTML.
- def xhtml
- if inline_xhtml?
- xml
- else
- nil
- end
- end
-
- # Raises a MissingAttributeError, NotAvailableValueError,
- # MissingTagError or NotExpectedTagError if the element is
- # not properly formatted.
- def atom_validate(ignore_unknown_element, tags, uri)
- if out_of_line?
- raise MissingAttributeError.new(tag_name, "type") if @type.nil?
- unless (content.nil? or content.empty?)
- raise NotAvailableValueError.new(tag_name, content)
- end
- elsif inline_xhtml?
- if @xml.nil?
- raise MissingTagError.new("div", tag_name)
- end
- unless @xml.name == "div" and @xml.uri == XHTML_URI
- raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name)
- end
- end
- end
-
- # Returns true if the element contains inline content
- # that has a text or HTML media type, or no media type at all.
- def inline_text?
- !out_of_line? and [nil, "text", "html"].include?(@type)
- end
-
- # Returns true if the element contains inline content that
- # has a HTML media type.
- def inline_html?
- return false if out_of_line?
- @type == "html" or mime_split == ["text", "html"]
- end
-
- # Returns true if the element contains inline content that
- # has a XHTML media type.
- def inline_xhtml?
- !out_of_line? and @type == "xhtml"
- end
-
- # Returns true if the element contains inline content that
- # has a MIME media type.
- def inline_other?
- return false if out_of_line?
- media_type, subtype = mime_split
- return false if media_type.nil? or subtype.nil?
- true
- end
-
- # Returns true if the element contains inline content that
- # has a text media type.
- def inline_other_text?
- return false unless inline_other?
- return false if inline_other_xml?
-
- media_type, = mime_split
- return true if "text" == media_type.downcase
- false
- end
-
- # Returns true if the element contains inline content that
- # has a XML media type.
- def inline_other_xml?
- return false unless inline_other?
-
- media_type, subtype = mime_split
- normalized_mime_type = "#{media_type}/#{subtype}".downcase
- if /(?:\+xml|^xml)$/ =~ subtype or
- %w(text/xml-external-parsed-entity
- application/xml-external-parsed-entity
- application/xml-dtd).find {|x| x == normalized_mime_type}
- return true
- end
- false
- end
-
- # Returns true if the element contains inline content
- # encoded in base64.
- def inline_other_base64?
- inline_other? and !inline_other_text? and !inline_other_xml?
- end
-
- # Returns true if the element contains linked content.
- def out_of_line?
- not @src.nil?
- end
-
- # Splits the type attribute into an array, e.g. ["text", "xml"]
- def mime_split
- media_type = subtype = nil
- if /\A\s*([a-z]+)\/([a-z\+]+)\s*(?:;.*)?\z/i =~ @type.to_s
- media_type = $1.downcase
- subtype = $2.downcase
- end
- [media_type, subtype]
- end
-
- # Returns true if the content needs to be encoded in base64.
- def need_base64_encode?
- inline_other_base64?
- end
-
- private
- def empty_content?
- out_of_line? or super
- end
- end
-
- # Feed::Contributor
- Contributor = Feed::Contributor
- # Feed::Id
- Id = Feed::Id
- # Feed::Link
- Link = Feed::Link
-
- # DateConstruct that usually indicates the time of the initial
- # creation of an Entry.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.published
- class Published < RSS::Element
- include CommonModel
- include DateConstruct
- end
-
- # Feed::Rights
- Rights = Feed::Rights
-
- # Defines a Atom Source element. It has the following attributes:
- #
- # * author
- # * category
- # * categories
- # * content
- # * contributor
- # * generator
- # * icon
- # * id
- # * link
- # * logo
- # * rights
- # * subtitle
- # * title
- # * updated
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.source
- class Source < RSS::Element
- include CommonModel
-
- [
- ["author", "*", :children],
- ["category", "*", :children, "categories"],
- ["contributor", "*", :children],
- ["generator", "?"],
- ["icon", "?"],
- ["id", "?", nil, :content],
- ["link", "*", :children],
- ["logo", "?"],
- ["rights", "?"],
- ["subtitle", "?"],
- ["title", "?"],
- ["updated", "?", nil, :content],
- ].each do |tag, occurs, type, *args|
- type ||= :attribute
- __send__("install_have_#{type}_element",
- tag, URI, occurs, tag, *args)
- end
-
- # Returns true if the Source element has an author.
- def have_author?
- !author.to_s.empty?
- end
-
- # Feed::Author
- Author = Feed::Author
- # Feed::Category
- Category = Feed::Category
- # Feed::Contributor
- Contributor = Feed::Contributor
- # Feed::Generator
- Generator = Feed::Generator
- # Feed::Icon
- Icon = Feed::Icon
- # Feed::Id
- Id = Feed::Id
- # Feed::Link
- Link = Feed::Link
- # Feed::Logo
- Logo = Feed::Logo
- # Feed::Rights
- Rights = Feed::Rights
- # Feed::Subtitle
- Subtitle = Feed::Subtitle
- # Feed::Title
- Title = Feed::Title
- # Feed::Updated
- Updated = Feed::Updated
- end
-
- # TextConstruct that describes a summary of the Entry.
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.summary
- class Summary < RSS::Element
- include CommonModel
- include TextConstruct
- end
-
- # Feed::Title
- Title = Feed::Title
- # Feed::Updated
- Updated = Feed::Updated
- end
- end
-
- # Defines a top-level Atom Entry element,
- # used as the document element of a stand-alone Atom Entry Document.
- # It has the following attributes:
- #
- # * author
- # * category
- # * categories
- # * content
- # * contributor
- # * id
- # * link
- # * published
- # * rights
- # * source
- # * summary
- # * title
- # * updated
- #
- # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.entry]
- class Entry < RSS::Element
- include RootElementMixin
- include CommonModel
- include DuplicateLinkChecker
-
- [
- ["author", "*", :children],
- ["category", "*", :children, "categories"],
- ["content", "?"],
- ["contributor", "*", :children],
- ["id", nil, nil, :content],
- ["link", "*", :children],
- ["published", "?", :child, :content],
- ["rights", "?"],
- ["source", "?"],
- ["summary", "?"],
- ["title", nil],
- ["updated", nil, nil, :content],
- ].each do |tag, occurs, type, *args|
- type ||= :attribute
- __send__("install_have_#{type}_element",
- tag, URI, occurs, tag, *args)
- end
-
- # Creates a new Atom Entry element.
- def initialize(version=nil, encoding=nil, standalone=nil)
- super("1.0", version, encoding, standalone)
- @feed_type = "atom"
- @feed_subtype = "entry"
- end
-
- # Returns the Entry in an array.
- def items
- [self]
- end
-
- # Sets up the +maker+ for constructing Entry elements.
- def setup_maker(maker)
- maker = maker.maker if maker.respond_to?("maker")
- super(maker)
- end
-
- # Returns where there are any authors present or there is a
- # source with an author.
- def have_author?
- authors.any? {|author| !author.to_s.empty?} or
- (source and source.have_author?)
- end
-
- private
- def atom_validate(ignore_unknown_element, tags, uri)
- unless have_author?
- raise MissingTagError.new("author", tag_name)
- end
- validate_duplicate_links(links)
- end
-
- def have_required_elements?
- super and have_author?
- end
-
- def maker_target(maker)
- maker.items.new_item
- end
-
- # Feed::Entry::Author
- Author = Feed::Entry::Author
- # Feed::Entry::Category
- Category = Feed::Entry::Category
- # Feed::Entry::Content
- Content = Feed::Entry::Content
- # Feed::Entry::Contributor
- Contributor = Feed::Entry::Contributor
- # Feed::Entry::Id
- Id = Feed::Entry::Id
- # Feed::Entry::Link
- Link = Feed::Entry::Link
- # Feed::Entry::Published
- Published = Feed::Entry::Published
- # Feed::Entry::Rights
- Rights = Feed::Entry::Rights
- # Feed::Entry::Source
- Source = Feed::Entry::Source
- # Feed::Entry::Summary
- Summary = Feed::Entry::Summary
- # Feed::Entry::Title
- Title = Feed::Entry::Title
- # Feed::Entry::Updated
- Updated = Feed::Entry::Updated
- end
- end
-
- Atom::CommonModel::ELEMENTS.each do |name|
- BaseListener.install_get_text_element(Atom::URI, name, "#{name}=")
- end
-
- module ListenerMixin
- private
- def initial_start_feed(tag_name, prefix, attrs, ns)
- check_ns(tag_name, prefix, ns, Atom::URI, false)
-
- @rss = Atom::Feed.new(@version, @encoding, @standalone)
- @rss.do_validate = @do_validate
- @rss.xml_stylesheets = @xml_stylesheets
- @rss.lang = attrs["xml:lang"]
- @rss.base = attrs["xml:base"]
- @last_element = @rss
- pr = Proc.new do |text, tags|
- @rss.validate_for_stream(tags) if @do_validate
- end
- @proc_stack.push(pr)
- end
-
- def initial_start_entry(tag_name, prefix, attrs, ns)
- check_ns(tag_name, prefix, ns, Atom::URI, false)
-
- @rss = Atom::Entry.new(@version, @encoding, @standalone)
- @rss.do_validate = @do_validate
- @rss.xml_stylesheets = @xml_stylesheets
- @rss.lang = attrs["xml:lang"]
- @rss.base = attrs["xml:base"]
- @last_element = @rss
- pr = Proc.new do |text, tags|
- @rss.validate_for_stream(tags) if @do_validate
- end
- @proc_stack.push(pr)
- end
- end
-end
diff --git a/lib/rss/content.rb b/lib/rss/content.rb
deleted file mode 100644
index d35311075a..0000000000
--- a/lib/rss/content.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: false
-require "rss/rss"
-
-module RSS
- # The prefix for the Content XML namespace.
- CONTENT_PREFIX = 'content'
- # The URI of the Content specification.
- CONTENT_URI = "http://purl.org/rss/1.0/modules/content/"
-
- module ContentModel
- extend BaseModel
-
- ELEMENTS = ["#{CONTENT_PREFIX}_encoded"]
-
- def self.append_features(klass)
- super
-
- klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)
- ELEMENTS.each do |full_name|
- name = full_name[(CONTENT_PREFIX.size + 1)..-1]
- klass.install_text_element(name, CONTENT_URI, "?", full_name)
- end
- end
- end
-
- prefix_size = CONTENT_PREFIX.size + 1
- ContentModel::ELEMENTS.each do |full_name|
- name = full_name[prefix_size..-1]
- BaseListener.install_get_text_element(CONTENT_URI, name, full_name)
- end
-end
-
-require 'rss/content/1.0'
-require 'rss/content/2.0'
diff --git a/lib/rss/content/1.0.rb b/lib/rss/content/1.0.rb
deleted file mode 100644
index 1367dfe092..0000000000
--- a/lib/rss/content/1.0.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: false
-require 'rss/1.0'
-
-module RSS
- RDF.install_ns(CONTENT_PREFIX, CONTENT_URI)
-
- class RDF
- class Item; include ContentModel; end
- end
-end
diff --git a/lib/rss/content/2.0.rb b/lib/rss/content/2.0.rb
deleted file mode 100644
index 3b468248ac..0000000000
--- a/lib/rss/content/2.0.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: false
-require "rss/2.0"
-
-module RSS
- Rss.install_ns(CONTENT_PREFIX, CONTENT_URI)
-
- class Rss
- class Channel
- class Item; include ContentModel; end
- end
- end
-end
diff --git a/lib/rss/converter.rb b/lib/rss/converter.rb
deleted file mode 100644
index b92e35a051..0000000000
--- a/lib/rss/converter.rb
+++ /dev/null
@@ -1,171 +0,0 @@
-# frozen_string_literal: false
-require "rss/utils"
-
-module RSS
-
- class Converter
-
- include Utils
-
- def initialize(to_enc, from_enc=nil)
- if "".respond_to?(:encode)
- @to_encoding = to_enc
- return
- end
- normalized_to_enc = to_enc.downcase.gsub(/-/, '_')
- from_enc ||= 'utf-8'
- normalized_from_enc = from_enc.downcase.gsub(/-/, '_')
- if normalized_to_enc == normalized_from_enc
- def_same_enc()
- else
- def_diff_enc = "def_to_#{normalized_to_enc}_from_#{normalized_from_enc}"
- if respond_to?(def_diff_enc)
- __send__(def_diff_enc)
- else
- def_else_enc(to_enc, from_enc)
- end
- end
- end
-
- def convert(value)
- if value.is_a?(String) and value.respond_to?(:encode)
- value.encode(@to_encoding)
- else
- value
- end
- end
-
- def def_convert(depth=0)
- instance_eval(<<-EOC, *get_file_and_line_from_caller(depth))
- def convert(value)
- if value.kind_of?(String)
- #{yield('value')}
- else
- value
- end
- end
- EOC
- end
-
- def def_iconv_convert(to_enc, from_enc, depth=0)
- begin
- require "iconv"
- @iconv = Iconv.new(to_enc, from_enc)
- def_convert(depth+1) do |value|
- <<-EOC
- begin
- @iconv.iconv(#{value})
- rescue Iconv::Failure
- raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
- end
- EOC
- end
- rescue LoadError, ArgumentError, SystemCallError
- raise UnknownConversionMethodError.new(to_enc, from_enc)
- end
- end
-
- def def_else_enc(to_enc, from_enc)
- def_iconv_convert(to_enc, from_enc, 0)
- end
-
- def def_same_enc()
- def_convert do |value|
- value
- end
- end
-
- def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg)
- begin
- require "uconv"
- def_convert(1) do |value|
- <<-EOC
- begin
- Uconv.#{meth}(#{value})
- rescue Uconv::Error
- raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
- end
- EOC
- end
- rescue LoadError
- require 'nkf'
- if NKF.const_defined?(:UTF8)
- def_convert(1) do |value|
- "NKF.nkf(#{nkf_arg.dump}, #{value})"
- end
- else
- def_iconv_convert(to_enc, from_enc, 1)
- end
- end
- end
-
- def def_to_euc_jp_from_utf_8
- def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We')
- end
-
- def def_to_utf_8_from_euc_jp
- def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew')
- end
-
- def def_to_shift_jis_from_utf_8
- def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws')
- end
-
- def def_to_utf_8_from_shift_jis
- def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw')
- end
-
- def def_to_euc_jp_from_shift_jis
- require "nkf"
- def_convert do |value|
- "NKF.nkf('-Se', #{value})"
- end
- end
-
- def def_to_shift_jis_from_euc_jp
- require "nkf"
- def_convert do |value|
- "NKF.nkf('-Es', #{value})"
- end
- end
-
- def def_to_euc_jp_from_iso_2022_jp
- require "nkf"
- def_convert do |value|
- "NKF.nkf('-Je', #{value})"
- end
- end
-
- def def_to_iso_2022_jp_from_euc_jp
- require "nkf"
- def_convert do |value|
- "NKF.nkf('-Ej', #{value})"
- end
- end
-
- def def_to_utf_8_from_iso_8859_1
- def_convert do |value|
- "#{value}.unpack('C*').pack('U*')"
- end
- end
-
- def def_to_iso_8859_1_from_utf_8
- def_convert do |value|
- <<-EOC
- array_utf8 = #{value}.unpack('U*')
- array_enc = []
- array_utf8.each do |num|
- if num <= 0xFF
- array_enc << num
- else
- array_enc.concat "&\#\#{num};".unpack('C*')
- end
- end
- array_enc.pack('C*')
- EOC
- end
- end
-
- end
-
-end
diff --git a/lib/rss/dublincore.rb b/lib/rss/dublincore.rb
deleted file mode 100644
index 8d1a551947..0000000000
--- a/lib/rss/dublincore.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-# frozen_string_literal: false
-require "rss/rss"
-
-module RSS
- # The prefix for the Dublin Core XML namespace.
- DC_PREFIX = 'dc'
- # The URI of the Dublin Core specification.
- DC_URI = "http://purl.org/dc/elements/1.1/"
-
- module BaseDublinCoreModel
- def append_features(klass)
- super
-
- return if klass.instance_of?(Module)
- DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
- plural = plural_name || "#{name}s"
- full_name = "#{DC_PREFIX}_#{name}"
- full_plural_name = "#{DC_PREFIX}_#{plural}"
- klass_name = "DublinCore#{Utils.to_class_name(name)}"
- klass.install_must_call_validator(DC_PREFIX, DC_URI)
- klass.install_have_children_element(name, DC_URI, "*",
- full_name, full_plural_name)
- klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
- remove_method :#{full_name}
- remove_method :#{full_name}=
- remove_method :set_#{full_name}
-
- def #{full_name}
- @#{full_name}.first and @#{full_name}.first.value
- end
-
- def #{full_name}=(new_value)
- @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value)
- end
- alias set_#{full_name} #{full_name}=
- EOC
- end
- klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
- if method_defined?(:date)
- alias date_without_#{DC_PREFIX}_date= date=
-
- def date=(value)
- self.date_without_#{DC_PREFIX}_date = value
- self.#{DC_PREFIX}_date = value
- end
- else
- alias date #{DC_PREFIX}_date
- alias date= #{DC_PREFIX}_date=
- end
-
- # For backward compatibility
- alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
- EOC
- end
- end
-
- module DublinCoreModel
-
- extend BaseModel
- extend BaseDublinCoreModel
-
- TEXT_ELEMENTS = {
- "title" => nil,
- "description" => nil,
- "creator" => nil,
- "subject" => nil,
- "publisher" => nil,
- "contributor" => nil,
- "type" => nil,
- "format" => nil,
- "identifier" => nil,
- "source" => nil,
- "language" => nil,
- "relation" => nil,
- "coverage" => nil,
- "rights" => "rights_list"
- }
-
- DATE_ELEMENTS = {
- "date" => "w3cdtf",
- }
-
- ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a
- DublinCoreModel::DATE_ELEMENTS.each do |name, |
- ELEMENT_NAME_INFOS << [name, nil]
- end
-
- ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys
-
- ELEMENTS.each do |name, plural_name|
- module_eval(<<-EOC, *get_file_and_line_from_caller(0))
- class DublinCore#{Utils.to_class_name(name)} < Element
- include RSS10
-
- content_setup
-
- class << self
- def required_prefix
- DC_PREFIX
- end
-
- def required_uri
- DC_URI
- end
- end
-
- @tag_name = #{name.dump}
-
- alias_method(:value, :content)
- alias_method(:value=, :content=)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.content = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(DC_PREFIX)
- end
-
- def maker_target(target)
- target.new_#{name}
- end
-
- def setup_maker_attributes(#{name})
- #{name}.content = content
- end
- end
- EOC
- end
-
- DATE_ELEMENTS.each do |name, type|
- tag_name = "#{DC_PREFIX}:#{name}"
- module_eval(<<-EOC, *get_file_and_line_from_caller(0))
- class DublinCore#{Utils.to_class_name(name)} < Element
- remove_method(:content=)
- remove_method(:value=)
-
- date_writer("content", #{type.dump}, #{tag_name.dump})
-
- alias_method(:value=, :content=)
- end
- EOC
- end
- end
-
- # For backward compatibility
- DublincoreModel = DublinCoreModel
-
- DublinCoreModel::ELEMENTS.each do |name|
- class_name = Utils.to_class_name(name)
- BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}")
- end
-
- DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"}
-end
-
-require 'rss/dublincore/1.0'
-require 'rss/dublincore/2.0'
-require 'rss/dublincore/atom'
diff --git a/lib/rss/dublincore/1.0.rb b/lib/rss/dublincore/1.0.rb
deleted file mode 100644
index 1d96fab9b9..0000000000
--- a/lib/rss/dublincore/1.0.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: false
-require "rss/1.0"
-
-module RSS
- RDF.install_ns(DC_PREFIX, DC_URI)
-
- class RDF
- class Channel; include DublinCoreModel; end
- class Image; include DublinCoreModel; end
- class Item; include DublinCoreModel; end
- class Textinput; include DublinCoreModel; end
- end
-end
diff --git a/lib/rss/dublincore/2.0.rb b/lib/rss/dublincore/2.0.rb
deleted file mode 100644
index e3011fef6a..0000000000
--- a/lib/rss/dublincore/2.0.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: false
-require "rss/2.0"
-
-module RSS
- Rss.install_ns(DC_PREFIX, DC_URI)
-
- class Rss
- class Channel
- include DublinCoreModel
- class Item; include DublinCoreModel; end
- end
- end
-end
diff --git a/lib/rss/dublincore/atom.rb b/lib/rss/dublincore/atom.rb
deleted file mode 100644
index 0b8b11e440..0000000000
--- a/lib/rss/dublincore/atom.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: false
-require "rss/atom"
-
-module RSS
- module Atom
- Feed.install_ns(DC_PREFIX, DC_URI)
-
- class Feed
- include DublinCoreModel
- class Entry; include DublinCoreModel; end
- end
-
- class Entry
- include DublinCoreModel
- end
- end
-end
diff --git a/lib/rss/image.rb b/lib/rss/image.rb
deleted file mode 100644
index 6b86ec0e5b..0000000000
--- a/lib/rss/image.rb
+++ /dev/null
@@ -1,198 +0,0 @@
-# frozen_string_literal: false
-require 'rss/1.0'
-require 'rss/dublincore'
-
-module RSS
-
- # The prefix for the Image XML namespace.
- IMAGE_PREFIX = 'image'
- # The URI for the Image specification.
- IMAGE_URI = 'http://purl.org/rss/1.0/modules/image/'
-
- RDF.install_ns(IMAGE_PREFIX, IMAGE_URI)
-
- # This constant holds strings which contain the names of
- # image elements, with the appropriate prefix.
- IMAGE_ELEMENTS = []
-
- %w(item favicon).each do |name|
- class_name = Utils.to_class_name(name)
- BaseListener.install_class_name(IMAGE_URI, name, "Image#{class_name}")
- IMAGE_ELEMENTS << "#{IMAGE_PREFIX}_#{name}"
- end
-
- module ImageModelUtils
- def validate_one_tag_name(ignore_unknown_element, name, tags)
- if !ignore_unknown_element
- invalid = tags.find {|tag| tag != name}
- raise UnknownTagError.new(invalid, IMAGE_URI) if invalid
- end
- raise TooMuchTagError.new(name, tag_name) if tags.size > 1
- end
- end
-
- module ImageItemModel
- include ImageModelUtils
- extend BaseModel
-
- def self.append_features(klass)
- super
-
- klass.install_have_child_element("item", IMAGE_URI, "?",
- "#{IMAGE_PREFIX}_item")
- klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
- end
-
- class ImageItem < Element
- include RSS10
- include DublinCoreModel
-
- @tag_name = "item"
-
- class << self
- def required_prefix
- IMAGE_PREFIX
- end
-
- def required_uri
- IMAGE_URI
- end
- end
-
- install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
-
- [
- ["about", ::RSS::RDF::URI, true],
- ["resource", ::RSS::RDF::URI, false],
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{::RSS::RDF::PREFIX}:#{name}")
- end
-
- %w(width height).each do |tag|
- full_name = "#{IMAGE_PREFIX}_#{tag}"
- disp_name = "#{IMAGE_PREFIX}:#{tag}"
- install_text_element(tag, IMAGE_URI, "?",
- full_name, :integer, disp_name)
- BaseListener.install_get_text_element(IMAGE_URI, tag, full_name)
- end
-
- alias width= image_width=
- alias width image_width
- alias height= image_height=
- alias height image_height
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.about = args[0]
- self.resource = args[1]
- end
- end
-
- def full_name
- tag_name_with_prefix(IMAGE_PREFIX)
- end
-
- private
- def maker_target(target)
- target.image_item
- end
-
- def setup_maker_attributes(item)
- item.about = self.about
- item.resource = self.resource
- end
- end
- end
-
- module ImageFaviconModel
- include ImageModelUtils
- extend BaseModel
-
- def self.append_features(klass)
- super
-
- unless klass.class == Module
- klass.install_have_child_element("favicon", IMAGE_URI, "?",
- "#{IMAGE_PREFIX}_favicon")
- klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
- end
- end
-
- class ImageFavicon < Element
- include RSS10
- include DublinCoreModel
-
- @tag_name = "favicon"
-
- class << self
- def required_prefix
- IMAGE_PREFIX
- end
-
- def required_uri
- IMAGE_URI
- end
- end
-
- [
- ["about", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX],
- ["size", IMAGE_URI, true, IMAGE_PREFIX],
- ].each do |name, uri, required, prefix|
- install_get_attribute(name, uri, required, nil, nil,
- "#{prefix}:#{name}")
- end
-
- AVAILABLE_SIZES = %w(small medium large)
- alias_method :set_size, :size=
- private :set_size
- def size=(new_value)
- if @do_validate and !new_value.nil?
- new_value = new_value.strip
- unless AVAILABLE_SIZES.include?(new_value)
- attr_name = "#{IMAGE_PREFIX}:size"
- raise NotAvailableValueError.new(full_name, new_value, attr_name)
- end
- end
- set_size(new_value)
- end
-
- alias image_size= size=
- alias image_size size
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.about = args[0]
- self.size = args[1]
- end
- end
-
- def full_name
- tag_name_with_prefix(IMAGE_PREFIX)
- end
-
- private
- def maker_target(target)
- target.image_favicon
- end
-
- def setup_maker_attributes(favicon)
- favicon.about = self.about
- favicon.size = self.size
- end
- end
-
- end
-
- class RDF
- class Channel; include ImageFaviconModel; end
- class Item; include ImageItemModel; end
- end
-
-end
diff --git a/lib/rss/itunes.rb b/lib/rss/itunes.rb
deleted file mode 100644
index 827970c209..0000000000
--- a/lib/rss/itunes.rb
+++ /dev/null
@@ -1,413 +0,0 @@
-# frozen_string_literal: false
-require 'rss/2.0'
-
-module RSS
- # The prefix for the iTunes XML namespace.
- ITUNES_PREFIX = 'itunes'
- # The URI of the iTunes specification.
- ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
-
- Rss.install_ns(ITUNES_PREFIX, ITUNES_URI)
-
- module ITunesModelUtils
- include Utils
-
- def def_class_accessor(klass, name, type, *args)
- normalized_name = name.gsub(/-/, "_")
- full_name = "#{ITUNES_PREFIX}_#{normalized_name}"
- klass_name = "ITunes#{Utils.to_class_name(normalized_name)}"
-
- case type
- when :element, :attribute
- klass::ELEMENTS << full_name
- def_element_class_accessor(klass, name, full_name, klass_name, *args)
- when :elements
- klass::ELEMENTS << full_name
- def_elements_class_accessor(klass, name, full_name, klass_name, *args)
- else
- klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
- klass.install_text_element(normalized_name, ITUNES_URI, "?",
- full_name, type, name)
- end
- end
-
- def def_element_class_accessor(klass, name, full_name, klass_name,
- recommended_attribute_name=nil)
- klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name)
- end
-
- def def_elements_class_accessor(klass, name, full_name, klass_name,
- plural_name, recommended_attribute_name=nil)
- full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}"
- klass.install_have_children_element(name, ITUNES_PREFIX, "*",
- full_name, full_plural_name)
- end
- end
-
- module ITunesBaseModel
- extend ITunesModelUtils
-
- ELEMENTS = []
-
- ELEMENT_INFOS = [["author"],
- ["block", :yes_other],
- ["explicit", :yes_clean_other],
- ["keywords", :csv],
- ["subtitle"],
- ["summary"]]
- end
-
- module ITunesChannelModel
- extend BaseModel
- extend ITunesModelUtils
- include ITunesBaseModel
-
- ELEMENTS = []
-
- class << self
- def append_features(klass)
- super
-
- return if klass.instance_of?(Module)
- ELEMENT_INFOS.each do |name, type, *additional_infos|
- def_class_accessor(klass, name, type, *additional_infos)
- end
- end
- end
-
- ELEMENT_INFOS = [
- ["category", :elements, "categories", "text"],
- ["image", :attribute, "href"],
- ["owner", :element],
- ["new-feed-url"],
- ] + ITunesBaseModel::ELEMENT_INFOS
-
- class ITunesCategory < Element
- include RSS09
-
- @tag_name = "category"
-
- class << self
- def required_prefix
- ITUNES_PREFIX
- end
-
- def required_uri
- ITUNES_URI
- end
- end
-
- [
- ["text", "", true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required)
- end
-
- ITunesCategory = self
- install_have_children_element("category", ITUNES_URI, "*",
- "#{ITUNES_PREFIX}_category",
- "#{ITUNES_PREFIX}_categories")
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.text = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(ITUNES_PREFIX)
- end
-
- private
- def maker_target(categories)
- if text or !itunes_categories.empty?
- categories.new_category
- else
- nil
- end
- end
-
- def setup_maker_attributes(category)
- category.text = text if text
- end
-
- def setup_maker_elements(category)
- super(category)
- itunes_categories.each do |sub_category|
- sub_category.setup_maker(category)
- end
- end
- end
-
- class ITunesImage < Element
- include RSS09
-
- @tag_name = "image"
-
- class << self
- def required_prefix
- ITUNES_PREFIX
- end
-
- def required_uri
- ITUNES_URI
- end
- end
-
- [
- ["href", "", true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required)
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.href = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(ITUNES_PREFIX)
- end
-
- private
- def maker_target(target)
- if href
- target.itunes_image {|image| image}
- else
- nil
- end
- end
-
- def setup_maker_attributes(image)
- image.href = href
- end
- end
-
- class ITunesOwner < Element
- include RSS09
-
- @tag_name = "owner"
-
- class << self
- def required_prefix
- ITUNES_PREFIX
- end
-
- def required_uri
- ITUNES_URI
- end
- end
-
- install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
- [
- ["name"],
- ["email"],
- ].each do |name,|
- ITunesBaseModel::ELEMENT_INFOS << name
- install_text_element(name, ITUNES_URI, nil, "#{ITUNES_PREFIX}_#{name}")
- end
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.itunes_name = args[0]
- self.itunes_email = args[1]
- end
- end
-
- def full_name
- tag_name_with_prefix(ITUNES_PREFIX)
- end
-
- private
- def maker_target(target)
- target.itunes_owner
- end
-
- def setup_maker_element(owner)
- super(owner)
- owner.itunes_name = itunes_name
- owner.itunes_email = itunes_email
- end
- end
- end
-
- module ITunesItemModel
- extend BaseModel
- extend ITunesModelUtils
- include ITunesBaseModel
-
- class << self
- def append_features(klass)
- super
-
- return if klass.instance_of?(Module)
- ELEMENT_INFOS.each do |name, type|
- def_class_accessor(klass, name, type)
- end
- end
- end
-
- ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS +
- [["duration", :element, "content"]]
-
- class ITunesDuration < Element
- include RSS09
-
- @tag_name = "duration"
-
- class << self
- def required_prefix
- ITUNES_PREFIX
- end
-
- def required_uri
- ITUNES_URI
- end
-
- def parse(duration, do_validate=true)
- if do_validate and /\A(?:
- \d?\d:[0-5]\d:[0-5]\d|
- [0-5]?\d:[0-5]\d
- )\z/x !~ duration
- raise ArgumentError,
- "must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " +
- duration.inspect
- end
-
- components = duration.split(':')
- components[3..-1] = nil if components.size > 3
-
- components.unshift("00") until components.size == 3
-
- components.collect do |component|
- component.to_i
- end
- end
-
- def construct(hour, minute, second)
- components = [minute, second]
- if components.include?(nil)
- nil
- else
- components.unshift(hour) if hour and hour > 0
- components.collect do |component|
- "%02d" % component
- end.join(":")
- end
- end
- end
-
- content_setup
- alias_method(:value, :content)
- remove_method(:content=)
-
- attr_reader :hour, :minute, :second
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- args = args[0] if args.size == 1 and args[0].is_a?(Array)
- if args.size == 1
- self.content = args[0]
- elsif args.size > 3
- raise ArgumentError,
- "must be (do_validate, params), (content), " +
- "(minute, second), ([minute, second]), " +
- "(hour, minute, second) or ([hour, minute, second]): " +
- args.inspect
- else
- @second, @minute, @hour = args.reverse
- update_content
- end
- end
- end
-
- def content=(value)
- if value.nil?
- @content = nil
- elsif value.is_a?(self.class)
- self.content = value.content
- else
- begin
- @hour, @minute, @second = self.class.parse(value, @do_validate)
- rescue ArgumentError
- raise NotAvailableValueError.new(tag_name, value)
- end
- @content = value
- end
- end
- alias_method(:value=, :content=)
-
- def hour=(hour)
- @hour = @do_validate ? Integer(hour) : hour.to_i
- update_content
- hour
- end
-
- def minute=(minute)
- @minute = @do_validate ? Integer(minute) : minute.to_i
- update_content
- minute
- end
-
- def second=(second)
- @second = @do_validate ? Integer(second) : second.to_i
- update_content
- second
- end
-
- def full_name
- tag_name_with_prefix(ITUNES_PREFIX)
- end
-
- private
- def update_content
- @content = self.class.construct(hour, minute, second)
- end
-
- def maker_target(target)
- if @content
- target.itunes_duration {|duration| duration}
- else
- nil
- end
- end
-
- def setup_maker_element(duration)
- super(duration)
- duration.content = @content
- end
- end
- end
-
- class Rss
- class Channel
- include ITunesChannelModel
- class Item; include ITunesItemModel; end
- end
- end
-
- element_infos =
- ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS
- element_infos.each do |name, type|
- case type
- when :element, :elements, :attribute
- class_name = Utils.to_class_name(name)
- BaseListener.install_class_name(ITUNES_URI, name, "ITunes#{class_name}")
- else
- accessor_base = "#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}"
- BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base)
- end
- end
-end
diff --git a/lib/rss/maker.rb b/lib/rss/maker.rb
deleted file mode 100644
index 33d285f6af..0000000000
--- a/lib/rss/maker.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-# frozen_string_literal: false
-require "rss/rss"
-
-module RSS
- ##
- #
- # Provides a set of builders for various RSS objects
- #
- # * Feeds
- # * RSS 0.91
- # * RSS 1.0
- # * RSS 2.0
- # * Atom 1.0
- #
- # * Elements
- # * Atom::Entry
-
- module Maker
-
- # Collection of supported makers
- MAKERS = {}
-
- class << self
- # Builder for an RSS object
- # Creates an object of the type passed in +args+
- #
- # Executes the +block+ to populate elements of the created RSS object
- def make(version, &block)
- self[version].make(&block)
- end
-
- # Returns the maker for the +version+
- def [](version)
- maker_info = maker(version)
- raise UnsupportedMakerVersionError.new(version) if maker_info.nil?
- maker_info[:maker]
- end
-
- # Adds a maker to the set of supported makers
- def add_maker(version, normalized_version, maker)
- MAKERS[version] = {:maker => maker, :version => normalized_version}
- end
-
- # Returns collection of supported maker versions
- def versions
- MAKERS.keys.uniq.sort
- end
-
- # Returns collection of supported makers
- def makers
- MAKERS.values.collect { |info| info[:maker] }.uniq
- end
-
- # Returns true if the version is supported
- def supported?(version)
- versions.include?(version)
- end
-
- private
- # Can I remove this method?
- def maker(version)
- MAKERS[version]
- end
- end
- end
-end
-
-require "rss/maker/1.0"
-require "rss/maker/2.0"
-require "rss/maker/feed"
-require "rss/maker/entry"
-require "rss/maker/content"
-require "rss/maker/dublincore"
-require "rss/maker/slash"
-require "rss/maker/syndication"
-require "rss/maker/taxonomy"
-require "rss/maker/trackback"
-require "rss/maker/image"
-require "rss/maker/itunes"
diff --git a/lib/rss/maker/0.9.rb b/lib/rss/maker/0.9.rb
deleted file mode 100644
index 622a4c30b4..0000000000
--- a/lib/rss/maker/0.9.rb
+++ /dev/null
@@ -1,509 +0,0 @@
-# frozen_string_literal: false
-require "rss/0.9"
-
-require "rss/maker/base"
-
-module RSS
- module Maker
-
- class RSS09 < RSSBase
-
- def initialize(feed_version)
- super
- @feed_type = "rss"
- end
-
- private
- def make_feed
- Rss.new(@feed_version, @version, @encoding, @standalone)
- end
-
- def setup_elements(rss)
- setup_channel(rss)
- end
-
- class Channel < ChannelBase
- def to_feed(rss)
- channel = Rss::Channel.new
- setup_values(channel)
- _not_set_required_variables = not_set_required_variables
- if _not_set_required_variables.empty?
- rss.channel = channel
- set_parent(channel, rss)
- setup_items(rss)
- setup_image(rss)
- setup_textinput(rss)
- setup_other_elements(rss, channel)
- rss
- else
- raise NotSetError.new("maker.channel", _not_set_required_variables)
- end
- end
-
- private
- def setup_items(rss)
- @maker.items.to_feed(rss)
- end
-
- def setup_image(rss)
- @maker.image.to_feed(rss)
- end
-
- def setup_textinput(rss)
- @maker.textinput.to_feed(rss)
- end
-
- def variables
- super + ["pubDate"]
- end
-
- def required_variable_names
- %w(link language)
- end
-
- def not_set_required_variables
- vars = super
- vars << "description" unless description {|d| d.have_required_values?}
- vars << "title" unless title {|t| t.have_required_values?}
- vars
- end
-
- class SkipDays < SkipDaysBase
- def to_feed(rss, channel)
- unless @days.empty?
- skipDays = Rss::Channel::SkipDays.new
- channel.skipDays = skipDays
- set_parent(skipDays, channel)
- @days.each do |day|
- day.to_feed(rss, skipDays.days)
- end
- end
- end
-
- class Day < DayBase
- def to_feed(rss, days)
- day = Rss::Channel::SkipDays::Day.new
- set = setup_values(day)
- if set
- days << day
- set_parent(day, days)
- setup_other_elements(rss, day)
- end
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
-
- class SkipHours < SkipHoursBase
- def to_feed(rss, channel)
- unless @hours.empty?
- skipHours = Rss::Channel::SkipHours.new
- channel.skipHours = skipHours
- set_parent(skipHours, channel)
- @hours.each do |hour|
- hour.to_feed(rss, skipHours.hours)
- end
- end
- end
-
- class Hour < HourBase
- def to_feed(rss, hours)
- hour = Rss::Channel::SkipHours::Hour.new
- set = setup_values(hour)
- if set
- hours << hour
- set_parent(hour, hours)
- setup_other_elements(rss, hour)
- end
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
-
- class Cloud < CloudBase
- def to_feed(*args)
- end
- end
-
- class Categories < CategoriesBase
- def to_feed(*args)
- end
-
- class Category < CategoryBase
- end
- end
-
- class Links < LinksBase
- def to_feed(rss, channel)
- return if @links.empty?
- @links.first.to_feed(rss, channel)
- end
-
- class Link < LinkBase
- def to_feed(rss, channel)
- if have_required_values?
- channel.link = href
- else
- raise NotSetError.new("maker.channel.link",
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(href)
- end
- end
- end
-
- class Authors < AuthorsBase
- def to_feed(rss, channel)
- end
-
- class Author < AuthorBase
- def to_feed(rss, channel)
- end
- end
- end
-
- class Contributors < ContributorsBase
- def to_feed(rss, channel)
- end
-
- class Contributor < ContributorBase
- end
- end
-
- class Generator < GeneratorBase
- def to_feed(rss, channel)
- end
- end
-
- class Copyright < CopyrightBase
- def to_feed(rss, channel)
- channel.copyright = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
-
- class Description < DescriptionBase
- def to_feed(rss, channel)
- channel.description = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
-
- class Title < TitleBase
- def to_feed(rss, channel)
- channel.title = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
-
- class Image < ImageBase
- def to_feed(rss)
- image = Rss::Channel::Image.new
- set = setup_values(image)
- if set
- image.link = link
- rss.channel.image = image
- set_parent(image, rss.channel)
- setup_other_elements(rss, image)
- elsif required_element?
- raise NotSetError.new("maker.image", not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(url title link)
- end
-
- def required_element?
- true
- end
- end
-
- class Items < ItemsBase
- def to_feed(rss)
- if rss.channel
- normalize.each do |item|
- item.to_feed(rss)
- end
- setup_other_elements(rss, rss.items)
- end
- end
-
- class Item < ItemBase
- def to_feed(rss)
- item = Rss::Channel::Item.new
- setup_values(item)
- _not_set_required_variables = not_set_required_variables
- if _not_set_required_variables.empty?
- rss.items << item
- set_parent(item, rss.channel)
- setup_other_elements(rss, item)
- elsif variable_is_set?
- raise NotSetError.new("maker.items", _not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- []
- end
-
- def not_set_required_variables
- vars = super
- if @maker.feed_version == "0.91"
- vars << "title" unless title {|t| t.have_required_values?}
- vars << "link" unless link {|l| l.have_required_values?}
- end
- vars
- end
-
- class Guid < GuidBase
- def to_feed(*args)
- end
- end
-
- class Enclosure < EnclosureBase
- def to_feed(*args)
- end
- end
-
- class Source < SourceBase
- def to_feed(*args)
- end
-
- class Authors < AuthorsBase
- def to_feed(*args)
- end
-
- class Author < AuthorBase
- end
- end
-
- class Categories < CategoriesBase
- def to_feed(*args)
- end
-
- class Category < CategoryBase
- end
- end
-
- class Contributors < ContributorsBase
- def to_feed(*args)
- end
-
- class Contributor < ContributorBase
- end
- end
-
- class Generator < GeneratorBase
- def to_feed(*args)
- end
- end
-
- class Icon < IconBase
- def to_feed(*args)
- end
- end
-
- class Links < LinksBase
- def to_feed(*args)
- end
-
- class Link < LinkBase
- end
- end
-
- class Logo < LogoBase
- def to_feed(*args)
- end
- end
-
- class Rights < RightsBase
- def to_feed(*args)
- end
- end
-
- class Subtitle < SubtitleBase
- def to_feed(*args)
- end
- end
-
- class Title < TitleBase
- def to_feed(*args)
- end
- end
- end
-
- class Categories < CategoriesBase
- def to_feed(*args)
- end
-
- class Category < CategoryBase
- end
- end
-
- class Authors < AuthorsBase
- def to_feed(*args)
- end
-
- class Author < AuthorBase
- end
- end
-
- class Links < LinksBase
- def to_feed(rss, item)
- return if @links.empty?
- @links.first.to_feed(rss, item)
- end
-
- class Link < LinkBase
- def to_feed(rss, item)
- if have_required_values?
- item.link = href
- else
- raise NotSetError.new("maker.link",
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(href)
- end
- end
- end
-
- class Contributors < ContributorsBase
- def to_feed(rss, item)
- end
-
- class Contributor < ContributorBase
- end
- end
-
- class Rights < RightsBase
- def to_feed(rss, item)
- end
- end
-
- class Description < DescriptionBase
- def to_feed(rss, item)
- item.description = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
-
- class Content < ContentBase
- def to_feed(rss, item)
- end
- end
-
- class Title < TitleBase
- def to_feed(rss, item)
- item.title = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
- end
-
- class Textinput < TextinputBase
- def to_feed(rss)
- textInput = Rss::Channel::TextInput.new
- set = setup_values(textInput)
- if set
- rss.channel.textInput = textInput
- set_parent(textInput, rss.channel)
- setup_other_elements(rss, textInput)
- end
- end
-
- private
- def required_variable_names
- %w(title description name link)
- end
- end
- end
-
- class RSS091 < RSS09
- def initialize(feed_version="0.91")
- super
- end
-
- class Channel < RSS09::Channel
- end
-
- class Items < RSS09::Items
- class Item < RSS09::Items::Item
- end
- end
-
- class Image < RSS09::Image
- end
-
- class Textinput < RSS09::Textinput
- end
- end
-
- class RSS092 < RSS09
- def initialize(feed_version="0.92")
- super
- end
-
- class Channel < RSS09::Channel
- end
-
- class Items < RSS09::Items
- class Item < RSS09::Items::Item
- end
- end
-
- class Image < RSS09::Image
- end
-
- class Textinput < RSS09::Textinput
- end
- end
-
- add_maker("0.9", "0.92", RSS092)
- add_maker("0.91", "0.91", RSS091)
- add_maker("0.92", "0.92", RSS092)
- add_maker("rss0.9", "0.92", RSS092)
- add_maker("rss0.91", "0.91", RSS091)
- add_maker("rss0.92", "0.92", RSS092)
- end
-end
diff --git a/lib/rss/maker/1.0.rb b/lib/rss/maker/1.0.rb
deleted file mode 100644
index 3aee77e913..0000000000
--- a/lib/rss/maker/1.0.rb
+++ /dev/null
@@ -1,436 +0,0 @@
-# frozen_string_literal: false
-require "rss/1.0"
-
-require "rss/maker/base"
-
-module RSS
- module Maker
-
- class RSS10 < RSSBase
-
- def initialize(feed_version="1.0")
- super
- @feed_type = "rss"
- end
-
- private
- def make_feed
- RDF.new(@version, @encoding, @standalone)
- end
-
- def setup_elements(rss)
- setup_channel(rss)
- setup_image(rss)
- setup_items(rss)
- setup_textinput(rss)
- end
-
- class Channel < ChannelBase
- include SetupDefaultLanguage
-
- def to_feed(rss)
- set_default_values do
- _not_set_required_variables = not_set_required_variables
- if _not_set_required_variables.empty?
- channel = RDF::Channel.new(@about)
- setup_values(channel)
- channel.dc_dates.clear
- rss.channel = channel
- set_parent(channel, rss)
- setup_items(rss)
- setup_image(rss)
- setup_textinput(rss)
- setup_other_elements(rss, channel)
- else
- raise NotSetError.new("maker.channel", _not_set_required_variables)
- end
- end
- end
-
- private
- def setup_items(rss)
- items = RDF::Channel::Items.new
- seq = items.Seq
- set_parent(items, seq)
- target_items = @maker.items.normalize
- raise NotSetError.new("maker", ["items"]) if target_items.empty?
- target_items.each do |item|
- li = RDF::Channel::Items::Seq::Li.new(item.link)
- seq.lis << li
- set_parent(li, seq)
- end
- rss.channel.items = items
- set_parent(rss.channel, items)
- end
-
- def setup_image(rss)
- if @maker.image.have_required_values?
- image = RDF::Channel::Image.new(@maker.image.url)
- rss.channel.image = image
- set_parent(image, rss.channel)
- end
- end
-
- def setup_textinput(rss)
- if @maker.textinput.have_required_values?
- textinput = RDF::Channel::Textinput.new(@maker.textinput.link)
- rss.channel.textinput = textinput
- set_parent(textinput, rss.channel)
- end
- end
-
- def required_variable_names
- %w(about link)
- end
-
- def not_set_required_variables
- vars = super
- vars << "description" unless description {|d| d.have_required_values?}
- vars << "title" unless title {|t| t.have_required_values?}
- vars
- end
-
- class SkipDays < SkipDaysBase
- def to_feed(*args)
- end
-
- class Day < DayBase
- end
- end
-
- class SkipHours < SkipHoursBase
- def to_feed(*args)
- end
-
- class Hour < HourBase
- end
- end
-
- class Cloud < CloudBase
- def to_feed(*args)
- end
- end
-
- class Categories < CategoriesBase
- def to_feed(*args)
- end
-
- class Category < CategoryBase
- end
- end
-
- class Links < LinksBase
- def to_feed(rss, channel)
- return if @links.empty?
- @links.first.to_feed(rss, channel)
- end
-
- class Link < LinkBase
- def to_feed(rss, channel)
- if have_required_values?
- channel.link = href
- else
- raise NotSetError.new("maker.channel.link",
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(href)
- end
- end
- end
-
- class Authors < AuthorsBase
- def to_feed(rss, channel)
- end
-
- class Author < AuthorBase
- def to_feed(rss, channel)
- end
- end
- end
-
- class Contributors < ContributorsBase
- def to_feed(rss, channel)
- end
-
- class Contributor < ContributorBase
- end
- end
-
- class Generator < GeneratorBase
- def to_feed(rss, channel)
- end
- end
-
- class Copyright < CopyrightBase
- def to_feed(rss, channel)
- end
- end
-
- class Description < DescriptionBase
- def to_feed(rss, channel)
- channel.description = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
-
- class Title < TitleBase
- def to_feed(rss, channel)
- channel.title = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
-
- class Image < ImageBase
- def to_feed(rss)
- if @url
- image = RDF::Image.new(@url)
- set = setup_values(image)
- if set
- rss.image = image
- set_parent(image, rss)
- setup_other_elements(rss, image)
- end
- end
- end
-
- def have_required_values?
- super and @maker.channel.have_required_values?
- end
-
- private
- def variables
- super + ["link"]
- end
-
- def required_variable_names
- %w(url title link)
- end
- end
-
- class Items < ItemsBase
- def to_feed(rss)
- if rss.channel
- normalize.each do |item|
- item.to_feed(rss)
- end
- setup_other_elements(rss, rss.items)
- end
- end
-
- class Item < ItemBase
- def to_feed(rss)
- set_default_values do
- item = RDF::Item.new(link)
- set = setup_values(item)
- if set
- item.dc_dates.clear
- rss.items << item
- set_parent(item, rss)
- setup_other_elements(rss, item)
- elsif !have_required_values?
- raise NotSetError.new("maker.item", not_set_required_variables)
- end
- end
- end
-
- private
- def required_variable_names
- %w(link)
- end
-
- def variables
- super + %w(link)
- end
-
- def not_set_required_variables
- set_default_values do
- vars = super
- vars << "title" unless title {|t| t.have_required_values?}
- vars
- end
- end
-
- class Guid < GuidBase
- def to_feed(*args)
- end
- end
-
- class Enclosure < EnclosureBase
- def to_feed(*args)
- end
- end
-
- class Source < SourceBase
- def to_feed(*args)
- end
-
- class Authors < AuthorsBase
- def to_feed(*args)
- end
-
- class Author < AuthorBase
- end
- end
-
- class Categories < CategoriesBase
- def to_feed(*args)
- end
-
- class Category < CategoryBase
- end
- end
-
- class Contributors < ContributorsBase
- def to_feed(*args)
- end
-
- class Contributor < ContributorBase
- end
- end
-
- class Generator < GeneratorBase
- def to_feed(*args)
- end
- end
-
- class Icon < IconBase
- def to_feed(*args)
- end
- end
-
- class Links < LinksBase
- def to_feed(*args)
- end
-
- class Link < LinkBase
- end
- end
-
- class Logo < LogoBase
- def to_feed(*args)
- end
- end
-
- class Rights < RightsBase
- def to_feed(*args)
- end
- end
-
- class Subtitle < SubtitleBase
- def to_feed(*args)
- end
- end
-
- class Title < TitleBase
- def to_feed(*args)
- end
- end
- end
-
- class Categories < CategoriesBase
- def to_feed(*args)
- end
-
- class Category < CategoryBase
- end
- end
-
- class Authors < AuthorsBase
- def to_feed(*args)
- end
-
- class Author < AuthorBase
- end
- end
-
- class Links < LinksBase
- def to_feed(*args)
- end
-
- class Link < LinkBase
- end
- end
-
- class Contributors < ContributorsBase
- def to_feed(rss, item)
- end
-
- class Contributor < ContributorBase
- end
- end
-
- class Rights < RightsBase
- def to_feed(rss, item)
- end
- end
-
- class Description < DescriptionBase
- def to_feed(rss, item)
- item.description = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
-
- class Content < ContentBase
- def to_feed(rss, item)
- end
- end
-
- class Title < TitleBase
- def to_feed(rss, item)
- item.title = content if have_required_values?
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
- end
-
- class Textinput < TextinputBase
- def to_feed(rss)
- if @link
- textinput = RDF::Textinput.new(@link)
- set = setup_values(textinput)
- if set
- rss.textinput = textinput
- set_parent(textinput, rss)
- setup_other_elements(rss, textinput)
- end
- end
- end
-
- def have_required_values?
- super and @maker.channel.have_required_values?
- end
-
- private
- def required_variable_names
- %w(title description name link)
- end
- end
- end
-
- add_maker("1.0", "1.0", RSS10)
- add_maker("rss1.0", "1.0", RSS10)
- end
-end
diff --git a/lib/rss/maker/2.0.rb b/lib/rss/maker/2.0.rb
deleted file mode 100644
index 1f77a014d1..0000000000
--- a/lib/rss/maker/2.0.rb
+++ /dev/null
@@ -1,224 +0,0 @@
-# frozen_string_literal: false
-require "rss/2.0"
-
-require "rss/maker/0.9"
-
-module RSS
- module Maker
-
- class RSS20 < RSS09
-
- def initialize(feed_version="2.0")
- super
- end
-
- class Channel < RSS09::Channel
-
- private
- def required_variable_names
- %w(link)
- end
-
- class SkipDays < RSS09::Channel::SkipDays
- class Day < RSS09::Channel::SkipDays::Day
- end
- end
-
- class SkipHours < RSS09::Channel::SkipHours
- class Hour < RSS09::Channel::SkipHours::Hour
- end
- end
-
- class Cloud < RSS09::Channel::Cloud
- def to_feed(rss, channel)
- cloud = Rss::Channel::Cloud.new
- set = setup_values(cloud)
- if set
- channel.cloud = cloud
- set_parent(cloud, channel)
- setup_other_elements(rss, cloud)
- end
- end
-
- private
- def required_variable_names
- %w(domain port path registerProcedure protocol)
- end
- end
-
- class Categories < RSS09::Channel::Categories
- def to_feed(rss, channel)
- @categories.each do |category|
- category.to_feed(rss, channel)
- end
- end
-
- class Category < RSS09::Channel::Categories::Category
- def to_feed(rss, channel)
- category = Rss::Channel::Category.new
- set = setup_values(category)
- if set
- channel.categories << category
- set_parent(category, channel)
- setup_other_elements(rss, category)
- end
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
-
- class Generator < GeneratorBase
- def to_feed(rss, channel)
- channel.generator = content
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
-
- class Image < RSS09::Image
- private
- def required_element?
- false
- end
- end
-
- class Items < RSS09::Items
- class Item < RSS09::Items::Item
- private
- def required_variable_names
- []
- end
-
- def not_set_required_variables
- vars = super
- if !title {|t| t.have_required_values?} and
- !description {|d| d.have_required_values?}
- vars << "title or description"
- end
- vars
- end
-
- def variables
- super + ["pubDate"]
- end
-
- class Guid < RSS09::Items::Item::Guid
- def to_feed(rss, item)
- guid = Rss::Channel::Item::Guid.new
- set = setup_values(guid)
- if set
- item.guid = guid
- set_parent(guid, item)
- setup_other_elements(rss, guid)
- end
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
-
- class Enclosure < RSS09::Items::Item::Enclosure
- def to_feed(rss, item)
- enclosure = Rss::Channel::Item::Enclosure.new
- set = setup_values(enclosure)
- if set
- item.enclosure = enclosure
- set_parent(enclosure, item)
- setup_other_elements(rss, enclosure)
- end
- end
-
- private
- def required_variable_names
- %w(url length type)
- end
- end
-
- class Source < RSS09::Items::Item::Source
- def to_feed(rss, item)
- source = Rss::Channel::Item::Source.new
- set = setup_values(source)
- if set
- item.source = source
- set_parent(source, item)
- setup_other_elements(rss, source)
- end
- end
-
- private
- def required_variable_names
- %w(url content)
- end
-
- class Links < RSS09::Items::Item::Source::Links
- def to_feed(rss, source)
- return if @links.empty?
- @links.first.to_feed(rss, source)
- end
-
- class Link < RSS09::Items::Item::Source::Links::Link
- def to_feed(rss, source)
- source.url = href
- end
- end
- end
- end
-
- class Categories < RSS09::Items::Item::Categories
- def to_feed(rss, item)
- @categories.each do |category|
- category.to_feed(rss, item)
- end
- end
-
- class Category < RSS09::Items::Item::Categories::Category
- def to_feed(rss, item)
- category = Rss::Channel::Item::Category.new
- set = setup_values(category)
- if set
- item.categories << category
- set_parent(category, item)
- setup_other_elements(rss)
- end
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
- end
-
- class Authors < RSS09::Items::Item::Authors
- def to_feed(rss, item)
- return if @authors.empty?
- @authors.first.to_feed(rss, item)
- end
-
- class Author < RSS09::Items::Item::Authors::Author
- def to_feed(rss, item)
- item.author = name
- end
- end
- end
- end
- end
-
- class Textinput < RSS09::Textinput
- end
- end
-
- add_maker("2.0", "2.0", RSS20)
- add_maker("rss2.0", "2.0", RSS20)
- end
-end
diff --git a/lib/rss/maker/atom.rb b/lib/rss/maker/atom.rb
deleted file mode 100644
index e0cd7623c8..0000000000
--- a/lib/rss/maker/atom.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-# frozen_string_literal: false
-require "rss/atom"
-
-require "rss/maker/base"
-
-module RSS
- module Maker
- module AtomPersons
- module_function
- def def_atom_persons(klass, name, maker_name, plural=nil)
- plural ||= "#{name}s"
- klass_name = Utils.to_class_name(name)
- plural_klass_name = Utils.to_class_name(plural)
-
- klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class #{plural_klass_name} < #{plural_klass_name}Base
- class #{klass_name} < #{klass_name}Base
- def to_feed(feed, current)
- #{name} = feed.class::#{klass_name}.new
- set = setup_values(#{name})
- unless set
- raise NotSetError.new(#{maker_name.dump},
- not_set_required_variables)
- end
- current.#{plural} << #{name}
- set_parent(#{name}, current)
- setup_other_elements(#{name})
- end
-
- private
- def required_variable_names
- %w(name)
- end
- end
- end
-EOC
- end
- end
-
- module AtomTextConstruct
- class << self
- def def_atom_text_construct(klass, name, maker_name, klass_name=nil,
- atom_klass_name=nil)
- klass_name ||= Utils.to_class_name(name)
- atom_klass_name ||= Utils.to_class_name(name)
-
- klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class #{klass_name} < #{klass_name}Base
- include #{self.name}
- def to_feed(feed, current)
- #{name} = current.class::#{atom_klass_name}.new
- if setup_values(#{name})
- current.#{name} = #{name}
- set_parent(#{name}, current)
- setup_other_elements(feed)
- elsif variable_is_set?
- raise NotSetError.new(#{maker_name.dump},
- not_set_required_variables)
- end
- end
- end
- EOC
- end
- end
-
- private
- def required_variable_names
- if type == "xhtml"
- %w(xml_content)
- else
- %w(content)
- end
- end
-
- def variables
- if type == "xhtml"
- super + %w(xhtml)
- else
- super
- end
- end
- end
-
- module AtomCategory
- def to_feed(feed, current)
- category = feed.class::Category.new
- set = setup_values(category)
- if set
- current.categories << category
- set_parent(category, current)
- setup_other_elements(feed)
- else
- raise NotSetError.new(self.class.not_set_name,
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(term)
- end
-
- def variables
- super + ["term", "scheme"]
- end
- end
-
- module AtomLink
- def to_feed(feed, current)
- link = feed.class::Link.new
- set = setup_values(link)
- if set
- current.links << link
- set_parent(link, current)
- setup_other_elements(feed)
- else
- raise NotSetError.new(self.class.not_set_name,
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(href)
- end
- end
-
- module AtomGenerator
- def to_feed(feed, current)
- generator = current.class::Generator.new
- if setup_values(generator)
- current.generator = generator
- set_parent(generator, current)
- setup_other_elements(feed)
- elsif variable_is_set?
- raise NotSetError.new(self.class.not_set_name,
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(content)
- end
- end
-
- module AtomLogo
- def to_feed(feed, current)
- logo = current.class::Logo.new
- class << logo
- alias_method(:uri=, :content=)
- end
- set = setup_values(logo)
- class << logo
- remove_method(:uri=)
- end
- if set
- current.logo = logo
- set_parent(logo, current)
- setup_other_elements(feed)
- elsif variable_is_set?
- raise NotSetError.new(self.class.not_set_name,
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(uri)
- end
- end
- end
-end
diff --git a/lib/rss/maker/base.rb b/lib/rss/maker/base.rb
deleted file mode 100644
index bc4ca84141..0000000000
--- a/lib/rss/maker/base.rb
+++ /dev/null
@@ -1,945 +0,0 @@
-# frozen_string_literal: false
-require 'forwardable'
-
-require 'rss/rss'
-
-module RSS
- module Maker
- class Base
- extend Utils::InheritedReader
-
- OTHER_ELEMENTS = []
- NEED_INITIALIZE_VARIABLES = []
-
- class << self
- def other_elements
- inherited_array_reader("OTHER_ELEMENTS")
- end
- def need_initialize_variables
- inherited_array_reader("NEED_INITIALIZE_VARIABLES")
- end
-
- def inherited_base
- ::RSS::Maker::Base
- end
-
- def inherited(subclass)
- subclass.const_set(:OTHER_ELEMENTS, [])
- subclass.const_set(:NEED_INITIALIZE_VARIABLES, [])
- end
-
- def add_other_element(variable_name)
- self::OTHER_ELEMENTS << variable_name
- end
-
- def add_need_initialize_variable(variable_name, init_value=nil,
- &init_block)
- init_value ||= init_block
- self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value]
- end
-
- def def_array_element(name, plural=nil, klass_name=nil)
- include Enumerable
- extend Forwardable
-
- plural ||= "#{name}s"
- klass_name ||= Utils.to_class_name(name)
- def_delegators("@#{plural}", :<<, :[], :[]=, :first, :last)
- def_delegators("@#{plural}", :push, :pop, :shift, :unshift)
- def_delegators("@#{plural}", :each, :size, :empty?, :clear)
-
- add_need_initialize_variable(plural) {[]}
-
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def new_#{name}
- #{name} = self.class::#{klass_name}.new(@maker)
- @#{plural} << #{name}
- if block_given?
- yield #{name}
- else
- #{name}
- end
- end
- alias new_child new_#{name}
-
- def to_feed(*args)
- @#{plural}.each do |#{name}|
- #{name}.to_feed(*args)
- end
- end
-
- def replace(elements)
- @#{plural}.replace(elements.to_a)
- end
- EOC
- end
-
- def def_classed_element_without_accessor(name, class_name=nil)
- class_name ||= Utils.to_class_name(name)
- add_other_element(name)
- add_need_initialize_variable(name) do |object|
- object.send("make_#{name}")
- end
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- private
- def setup_#{name}(feed, current)
- @#{name}.to_feed(feed, current)
- end
-
- def make_#{name}
- self.class::#{class_name}.new(@maker)
- end
- EOC
- end
-
- def def_classed_element(name, class_name=nil, attribute_name=nil)
- def_classed_element_without_accessor(name, class_name)
- if attribute_name
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{name}
- if block_given?
- yield(@#{name})
- else
- @#{name}.#{attribute_name}
- end
- end
-
- def #{name}=(new_value)
- @#{name}.#{attribute_name} = new_value
- end
- EOC
- else
- attr_reader name
- end
- end
-
- def def_classed_elements(name, attribute, plural_class_name=nil,
- plural_name=nil, new_name=nil)
- plural_name ||= "#{name}s"
- new_name ||= name
- def_classed_element(plural_name, plural_class_name)
- local_variable_name = "_#{name}"
- new_value_variable_name = "new_value"
- additional_setup_code = nil
- if block_given?
- additional_setup_code = yield(local_variable_name,
- new_value_variable_name)
- end
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{name}
- #{local_variable_name} = #{plural_name}.first
- #{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
- end
-
- def #{name}=(#{new_value_variable_name})
- #{local_variable_name} =
- #{plural_name}.first || #{plural_name}.new_#{new_name}
- #{additional_setup_code}
- #{local_variable_name}.#{attribute} = #{new_value_variable_name}
- end
- EOC
- end
-
- def def_other_element(name)
- attr_accessor name
- def_other_element_without_accessor(name)
- end
-
- def def_other_element_without_accessor(name)
- add_need_initialize_variable(name)
- add_other_element(name)
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def setup_#{name}(feed, current)
- if !@#{name}.nil? and current.respond_to?(:#{name}=)
- current.#{name} = @#{name}
- end
- end
- EOC
- end
-
- def def_csv_element(name, type=nil)
- def_other_element_without_accessor(name)
- attr_reader(name)
- converter = ""
- if type == :integer
- converter = "{|v| Integer(v)}"
- end
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{name}=(value)
- @#{name} = Utils::CSV.parse(value)#{converter}
- end
- EOC
- end
- end
-
- attr_reader :maker
- def initialize(maker)
- @maker = maker
- @default_values_are_set = false
- initialize_variables
- end
-
- def have_required_values?
- not_set_required_variables.empty?
- end
-
- def variable_is_set?
- variables.any? {|var| not __send__(var).nil?}
- end
-
- private
- def initialize_variables
- self.class.need_initialize_variables.each do |variable_name, init_value|
- if init_value.nil?
- value = nil
- else
- if init_value.respond_to?(:call)
- value = init_value.call(self)
- elsif init_value.is_a?(String)
- # just for backward compatibility
- value = instance_eval(init_value, __FILE__, __LINE__)
- else
- value = init_value
- end
- end
- instance_variable_set("@#{variable_name}", value)
- end
- end
-
- def setup_other_elements(feed, current=nil)
- current ||= current_element(feed)
- self.class.other_elements.each do |element|
- __send__("setup_#{element}", feed, current)
- end
- end
-
- def current_element(feed)
- feed
- end
-
- def set_default_values(&block)
- return yield if @default_values_are_set
-
- begin
- @default_values_are_set = true
- _set_default_values(&block)
- ensure
- @default_values_are_set = false
- end
- end
-
- def _set_default_values(&block)
- yield
- end
-
- def setup_values(target)
- set = false
- if have_required_values?
- variables.each do |var|
- setter = "#{var}="
- if target.respond_to?(setter)
- value = __send__(var)
- unless value.nil?
- target.__send__(setter, value)
- set = true
- end
- end
- end
- end
- set
- end
-
- def set_parent(target, parent)
- target.parent = parent if target.class.need_parent?
- end
-
- def variables
- self.class.need_initialize_variables.find_all do |name, init|
- # init == "nil" is just for backward compatibility
- init.nil? or init == "nil"
- end.collect do |name, init|
- name
- end
- end
-
- def not_set_required_variables
- required_variable_names.find_all do |var|
- __send__(var).nil?
- end
- end
-
- def required_variables_are_set?
- required_variable_names.each do |var|
- return false if __send__(var).nil?
- end
- true
- end
- end
-
- module AtomPersonConstructBase
- def self.append_features(klass)
- super
-
- klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
- %w(name uri email).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- EOC
- end
- end
-
- module AtomTextConstructBase
- module EnsureXMLContent
- class << self
- def included(base)
- super
- base.class_eval do
- %w(type content xml_content).each do |element|
- attr_reader element
- attr_writer element if element != "xml_content"
- add_need_initialize_variable(element)
- end
-
- alias_method(:xhtml, :xml_content)
- end
- end
- end
-
- def ensure_xml_content(content)
- xhtml_uri = ::RSS::Atom::XHTML_URI
- unless content.is_a?(RSS::XML::Element) and
- ["div", xhtml_uri] == [content.name, content.uri]
- children = content
- children = [children] unless content.is_a?(Array)
- children = set_xhtml_uri_as_default_uri(children)
- content = RSS::XML::Element.new("div", nil, xhtml_uri,
- {"xmlns" => xhtml_uri},
- children)
- end
- content
- end
-
- def xml_content=(content)
- @xml_content = ensure_xml_content(content)
- end
-
- def xhtml=(content)
- self.xml_content = content
- end
-
- private
- def set_xhtml_uri_as_default_uri(children)
- children.collect do |child|
- if child.is_a?(RSS::XML::Element) and
- child.prefix.nil? and child.uri.nil?
- RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI,
- child.attributes.dup,
- set_xhtml_uri_as_default_uri(child.children))
- else
- child
- end
- end
- end
- end
-
- def self.append_features(klass)
- super
-
- klass.class_eval do
- include EnsureXMLContent
- end
- end
- end
-
- module SetupDefaultDate
- private
- def _set_default_values
- keep = {
- :date => date,
- :dc_dates => dc_dates.to_a.dup,
- }
- _date = _parse_date_if_needed(date)
- if _date and !dc_dates.any? {|dc_date| dc_date.value == _date}
- dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self)
- dc_date.value = _date.dup
- dc_dates.unshift(dc_date)
- end
- self.date ||= self.dc_date
- super
- ensure
- self.date = keep[:date]
- dc_dates.replace(keep[:dc_dates])
- end
-
- def _parse_date_if_needed(date_value)
- date_value = Time.parse(date_value) if date_value.is_a?(String)
- date_value
- end
- end
-
- module SetupDefaultLanguage
- private
- def _set_default_values
- keep = {
- :dc_languages => dc_languages.to_a.dup,
- }
- _language = language
- if _language and
- !dc_languages.any? {|dc_language| dc_language.value == _language}
- dc_language = self.class::DublinCoreLanguages::DublinCoreLanguage.new(self)
- dc_language.value = _language.dup
- dc_languages.unshift(dc_language)
- end
- super
- ensure
- dc_languages.replace(keep[:dc_languages])
- end
- end
-
- class RSSBase < Base
- class << self
- def make(*args, &block)
- new(*args).make(&block)
- end
- end
-
- %w(xml_stylesheets channel image items textinput).each do |element|
- attr_reader element
- add_need_initialize_variable(element) do |object|
- object.send("make_#{element}")
- end
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- private
- def setup_#{element}(feed)
- @#{element}.to_feed(feed)
- end
-
- def make_#{element}
- self.class::#{Utils.to_class_name(element)}.new(self)
- end
- EOC
- end
-
- attr_reader :feed_version
- alias_method(:rss_version, :feed_version)
- attr_accessor :version, :encoding, :standalone
-
- def initialize(feed_version)
- super(self)
- @feed_type = nil
- @feed_subtype = nil
- @feed_version = feed_version
- @version = "1.0"
- @encoding = "UTF-8"
- @standalone = nil
- end
-
- def make
- yield(self)
- to_feed
- end
-
- def to_feed
- feed = make_feed
- setup_xml_stylesheets(feed)
- setup_elements(feed)
- setup_other_elements(feed)
- feed.validate
- feed
- end
-
- private
- remove_method :make_xml_stylesheets
- def make_xml_stylesheets
- XMLStyleSheets.new(self)
- end
- end
-
- class XMLStyleSheets < Base
- def_array_element("xml_stylesheet", nil, "XMLStyleSheet")
-
- class XMLStyleSheet < Base
-
- ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute|
- attr_accessor attribute
- add_need_initialize_variable(attribute)
- end
-
- def to_feed(feed)
- xss = ::RSS::XMLStyleSheet.new
- guess_type_if_need(xss)
- set = setup_values(xss)
- if set
- feed.xml_stylesheets << xss
- end
- end
-
- private
- def guess_type_if_need(xss)
- if @type.nil?
- xss.href = @href
- @type = xss.type
- end
- end
-
- def required_variable_names
- %w(href type)
- end
- end
- end
-
- class ChannelBase < Base
- include SetupDefaultDate
-
- %w(cloud categories skipDays skipHours).each do |name|
- def_classed_element(name)
- end
-
- %w(generator copyright description title).each do |name|
- def_classed_element(name, nil, "content")
- end
-
- [
- ["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
- ["author", "name"],
- ["contributor", "name"],
- ].each do |name, attribute, additional_setup_maker|
- def_classed_elements(name, attribute, &additional_setup_maker)
- end
-
- %w(id about language
- managingEditor webMaster rating docs ttl).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
-
- %w(date lastBuildDate).each do |date_element|
- attr_reader date_element
- add_need_initialize_variable(date_element)
- end
-
- def date=(_date)
- @date = _parse_date_if_needed(_date)
- end
-
- def lastBuildDate=(_date)
- @lastBuildDate = _parse_date_if_needed(_date)
- end
-
- def pubDate
- date
- end
-
- def pubDate=(date)
- self.date = date
- end
-
- def updated
- date
- end
-
- def updated=(date)
- self.date = date
- end
-
- alias_method(:rights, :copyright)
- alias_method(:rights=, :copyright=)
-
- alias_method(:subtitle, :description)
- alias_method(:subtitle=, :description=)
-
- def icon
- image_favicon.about
- end
-
- def icon=(url)
- image_favicon.about = url
- end
-
- def logo
- maker.image.url
- end
-
- def logo=(url)
- maker.image.url = url
- end
-
- class SkipDaysBase < Base
- def_array_element("day")
-
- class DayBase < Base
- %w(content).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
- end
-
- class SkipHoursBase < Base
- def_array_element("hour")
-
- class HourBase < Base
- %w(content).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
- end
-
- class CloudBase < Base
- %w(domain port path registerProcedure protocol).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
-
- class CategoriesBase < Base
- def_array_element("category", "categories")
-
- class CategoryBase < Base
- %w(domain content label).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
-
- alias_method(:term, :domain)
- alias_method(:term=, :domain=)
- alias_method(:scheme, :content)
- alias_method(:scheme=, :content=)
- end
- end
-
- class LinksBase < Base
- def_array_element("link")
-
- class LinkBase < Base
- %w(href rel type hreflang title length).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
- end
-
- class AuthorsBase < Base
- def_array_element("author")
-
- class AuthorBase < Base
- include AtomPersonConstructBase
- end
- end
-
- class ContributorsBase < Base
- def_array_element("contributor")
-
- class ContributorBase < Base
- include AtomPersonConstructBase
- end
- end
-
- class GeneratorBase < Base
- %w(uri version content).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
-
- class CopyrightBase < Base
- include AtomTextConstructBase
- end
-
- class DescriptionBase < Base
- include AtomTextConstructBase
- end
-
- class TitleBase < Base
- include AtomTextConstructBase
- end
- end
-
- class ImageBase < Base
- %w(title url width height description).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
-
- def link
- @maker.channel.link
- end
- end
-
- class ItemsBase < Base
- def_array_element("item")
-
- attr_accessor :do_sort, :max_size
-
- def initialize(maker)
- super
- @do_sort = false
- @max_size = -1
- end
-
- def normalize
- if @max_size >= 0
- sort_if_need[0...@max_size]
- else
- sort_if_need[0..@max_size]
- end
- end
-
- private
- def sort_if_need
- if @do_sort.respond_to?(:call)
- @items.sort do |x, y|
- @do_sort.call(x, y)
- end
- elsif @do_sort
- @items.sort do |x, y|
- y <=> x
- end
- else
- @items
- end
- end
-
- class ItemBase < Base
- include SetupDefaultDate
-
- %w(guid enclosure source categories content).each do |name|
- def_classed_element(name)
- end
-
- %w(rights description title).each do |name|
- def_classed_element(name, nil, "content")
- end
-
- [
- ["author", "name"],
- ["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
- ["contributor", "name"],
- ].each do |name, attribute|
- def_classed_elements(name, attribute)
- end
-
- %w(comments id published).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
-
- %w(date).each do |date_element|
- attr_reader date_element
- add_need_initialize_variable(date_element)
- end
-
- def date=(_date)
- @date = _parse_date_if_needed(_date)
- end
-
- def pubDate
- date
- end
-
- def pubDate=(date)
- self.date = date
- end
-
- def updated
- date
- end
-
- def updated=(date)
- self.date = date
- end
-
- alias_method(:summary, :description)
- alias_method(:summary=, :description=)
-
- def <=>(other)
- _date = date || dc_date
- _other_date = other.date || other.dc_date
- if _date and _other_date
- _date <=> _other_date
- elsif _date
- 1
- elsif _other_date
- -1
- else
- 0
- end
- end
-
- class GuidBase < Base
- %w(isPermaLink content).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
-
- def permanent_link?
- isPermaLink
- end
-
- def permanent_link=(bool)
- self.isPermaLink = bool
- end
- end
-
- class EnclosureBase < Base
- %w(url length type).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
-
- class SourceBase < Base
- include SetupDefaultDate
-
- %w(authors categories contributors generator icon
- logo rights subtitle title).each do |name|
- def_classed_element(name)
- end
-
- [
- ["link", "href"],
- ].each do |name, attribute|
- def_classed_elements(name, attribute)
- end
-
- %w(id content).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
-
- alias_method(:url, :link)
- alias_method(:url=, :link=)
-
- %w(date).each do |date_element|
- attr_reader date_element
- add_need_initialize_variable(date_element)
- end
-
- def date=(_date)
- @date = _parse_date_if_needed(_date)
- end
-
- def updated
- date
- end
-
- def updated=(date)
- self.date = date
- end
-
- private
- AuthorsBase = ChannelBase::AuthorsBase
- CategoriesBase = ChannelBase::CategoriesBase
- ContributorsBase = ChannelBase::ContributorsBase
- GeneratorBase = ChannelBase::GeneratorBase
-
- class IconBase < Base
- %w(url).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
-
- LinksBase = ChannelBase::LinksBase
-
- class LogoBase < Base
- %w(uri).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
-
- class RightsBase < Base
- include AtomTextConstructBase
- end
-
- class SubtitleBase < Base
- include AtomTextConstructBase
- end
-
- class TitleBase < Base
- include AtomTextConstructBase
- end
- end
-
- CategoriesBase = ChannelBase::CategoriesBase
- AuthorsBase = ChannelBase::AuthorsBase
- LinksBase = ChannelBase::LinksBase
- ContributorsBase = ChannelBase::ContributorsBase
-
- class RightsBase < Base
- include AtomTextConstructBase
- end
-
- class DescriptionBase < Base
- include AtomTextConstructBase
- end
-
- class ContentBase < Base
- include AtomTextConstructBase::EnsureXMLContent
-
- %w(src).each do |element|
- attr_accessor(element)
- add_need_initialize_variable(element)
- end
-
- def xml_content=(content)
- content = ensure_xml_content(content) if inline_xhtml?
- @xml_content = content
- end
-
- alias_method(:xml, :xml_content)
- alias_method(:xml=, :xml_content=)
-
- def inline_text?
- [nil, "text", "html"].include?(@type)
- end
-
- def inline_html?
- @type == "html"
- end
-
- def inline_xhtml?
- @type == "xhtml"
- end
-
- def inline_other?
- !out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type)
- end
-
- def inline_other_text?
- return false if @type.nil? or out_of_line?
- /\Atext\//i.match(@type) ? true : false
- end
-
- def inline_other_xml?
- return false if @type.nil? or out_of_line?
- /[\+\/]xml\z/i.match(@type) ? true : false
- end
-
- def inline_other_base64?
- return false if @type.nil? or out_of_line?
- @type.include?("/") and !inline_other_text? and !inline_other_xml?
- end
-
- def out_of_line?
- not @src.nil? and @content.nil?
- end
- end
-
- class TitleBase < Base
- include AtomTextConstructBase
- end
- end
- end
-
- class TextinputBase < Base
- %w(title description name link).each do |element|
- attr_accessor element
- add_need_initialize_variable(element)
- end
- end
- end
-end
diff --git a/lib/rss/maker/content.rb b/lib/rss/maker/content.rb
deleted file mode 100644
index 3559a45ad0..0000000000
--- a/lib/rss/maker/content.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: false
-require 'rss/content'
-require 'rss/maker/1.0'
-require 'rss/maker/2.0'
-
-module RSS
- module Maker
- module ContentModel
- def self.append_features(klass)
- super
-
- ::RSS::ContentModel::ELEMENTS.each do |name|
- klass.def_other_element(name)
- end
- end
- end
-
- class ItemsBase
- class ItemBase; include ContentModel; end
- end
- end
-end
diff --git a/lib/rss/maker/dublincore.rb b/lib/rss/maker/dublincore.rb
deleted file mode 100644
index 988209c045..0000000000
--- a/lib/rss/maker/dublincore.rb
+++ /dev/null
@@ -1,122 +0,0 @@
-# frozen_string_literal: false
-require 'rss/dublincore'
-require 'rss/maker/1.0'
-
-module RSS
- module Maker
- module DublinCoreModel
- def self.append_features(klass)
- super
-
- ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
- plural_name ||= "#{name}s"
- full_name = "#{RSS::DC_PREFIX}_#{name}"
- full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}"
- plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
- klass.def_classed_elements(full_name, "value", plural_klass_name,
- full_plural_name, name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def new_#{full_name}(value=nil)
- _#{full_name} = #{full_plural_name}.new_#{name}
- _#{full_name}.value = value
- if block_given?
- yield _#{full_name}
- else
- _#{full_name}
- end
- end
- EOC
- end
-
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- # For backward compatibility
- alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
- EOC
- end
-
- ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
- plural_name ||= "#{name}s"
- full_name ||= "#{DC_PREFIX}_#{name}"
- full_plural_name ||= "#{DC_PREFIX}_#{plural_name}"
- klass_name = Utils.to_class_name(name)
- full_klass_name = "DublinCore#{klass_name}"
- plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class #{plural_klass_name}Base < Base
- def_array_element(#{name.dump}, #{full_plural_name.dump},
- #{full_klass_name.dump})
-
- class #{full_klass_name}Base < Base
- attr_accessor :value
- add_need_initialize_variable("value")
- alias_method(:content, :value)
- alias_method(:content=, :value=)
-
- def have_required_values?
- @value
- end
-
- def to_feed(feed, current)
- if value and current.respond_to?(:#{full_name})
- new_item = current.class::#{full_klass_name}.new(value)
- current.#{full_plural_name} << new_item
- end
- end
- end
- #{klass_name}Base = #{full_klass_name}Base
- end
- EOC
- end
-
- def self.install_dublin_core(klass)
- ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
- plural_name ||= "#{name}s"
- klass_name = Utils.to_class_name(name)
- full_klass_name = "DublinCore#{klass_name}"
- plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class #{plural_klass_name} < #{plural_klass_name}Base
- class #{full_klass_name} < #{full_klass_name}Base
- end
- #{klass_name} = #{full_klass_name}
- end
-EOC
- end
- end
- end
-
- class ChannelBase
- include DublinCoreModel
- end
-
- class ImageBase; include DublinCoreModel; end
- class ItemsBase
- class ItemBase
- include DublinCoreModel
- end
- end
- class TextinputBase; include DublinCoreModel; end
-
- makers.each do |maker|
- maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class Channel
- DublinCoreModel.install_dublin_core(self)
- end
-
- class Image
- DublinCoreModel.install_dublin_core(self)
- end
-
- class Items
- class Item
- DublinCoreModel.install_dublin_core(self)
- end
- end
-
- class Textinput
- DublinCoreModel.install_dublin_core(self)
- end
- EOC
- end
- end
-end
diff --git a/lib/rss/maker/entry.rb b/lib/rss/maker/entry.rb
deleted file mode 100644
index f806cbcaae..0000000000
--- a/lib/rss/maker/entry.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-# frozen_string_literal: false
-require "rss/maker/atom"
-require "rss/maker/feed"
-
-module RSS
- module Maker
- module Atom
- class Entry < RSSBase
- def initialize(feed_version="1.0")
- super
- @feed_type = "atom"
- @feed_subtype = "entry"
- end
-
- private
- def make_feed
- ::RSS::Atom::Entry.new(@version, @encoding, @standalone)
- end
-
- def setup_elements(entry)
- setup_items(entry)
- end
-
- class Channel < ChannelBase
- class SkipDays < SkipDaysBase
- class Day < DayBase
- end
- end
-
- class SkipHours < SkipHoursBase
- class Hour < HourBase
- end
- end
-
- class Cloud < CloudBase
- end
-
- Categories = Feed::Channel::Categories
- Links = Feed::Channel::Links
- Authors = Feed::Channel::Authors
- Contributors = Feed::Channel::Contributors
-
- class Generator < GeneratorBase
- include AtomGenerator
-
- def self.not_set_name
- "maker.channel.generator"
- end
- end
-
- Copyright = Feed::Channel::Copyright
-
- class Description < DescriptionBase
- end
-
- Title = Feed::Channel::Title
- end
-
- class Image < ImageBase
- end
-
- class Items < ItemsBase
- def to_feed(entry)
- (normalize.first || Item.new(@maker)).to_feed(entry)
- end
-
- class Item < ItemBase
- def to_feed(entry)
- set_default_values do
- setup_values(entry)
- entry.dc_dates.clear
- setup_other_elements(entry)
- unless have_required_values?
- raise NotSetError.new("maker.item", not_set_required_variables)
- end
- end
- end
-
- private
- def required_variable_names
- %w(id updated)
- end
-
- def variables
- super + ["updated"]
- end
-
- def variable_is_set?
- super or !authors.empty?
- end
-
- def not_set_required_variables
- set_default_values do
- vars = super
- if authors.all? {|author| !author.have_required_values?}
- vars << "author"
- end
- vars << "title" unless title {|t| t.have_required_values?}
- vars
- end
- end
-
- def _set_default_values
- keep = {
- :authors => authors.to_a.dup,
- :contributors => contributors.to_a.dup,
- :categories => categories.to_a.dup,
- :id => id,
- :links => links.to_a.dup,
- :rights => @rights,
- :title => @title,
- :updated => updated,
- }
- authors.replace(@maker.channel.authors) if keep[:authors].empty?
- if keep[:contributors].empty?
- contributors.replace(@maker.channel.contributors)
- end
- if keep[:categories].empty?
- categories.replace(@maker.channel.categories)
- end
- self.id ||= link || @maker.channel.id
- links.replace(@maker.channel.links) if keep[:links].empty?
- unless keep[:rights].variable_is_set?
- @maker.channel.rights {|r| @rights = r}
- end
- unless keep[:title].variable_is_set?
- @maker.channel.title {|t| @title = t}
- end
- self.updated ||= @maker.channel.updated
- super
- ensure
- authors.replace(keep[:authors])
- contributors.replace(keep[:contributors])
- categories.replace(keep[:categories])
- links.replace(keep[:links])
- self.id = keep[:id]
- @rights = keep[:rights]
- @title = keep[:title]
- self.updated = keep[:updated]
- end
-
- Guid = Feed::Items::Item::Guid
- Enclosure = Feed::Items::Item::Enclosure
- Source = Feed::Items::Item::Source
- Categories = Feed::Items::Item::Categories
- Authors = Feed::Items::Item::Authors
- Contributors = Feed::Items::Item::Contributors
- Links = Feed::Items::Item::Links
- Rights = Feed::Items::Item::Rights
- Description = Feed::Items::Item::Description
- Title = Feed::Items::Item::Title
- Content = Feed::Items::Item::Content
- end
- end
-
- class Textinput < TextinputBase
- end
- end
- end
-
- add_maker("atom:entry", "1.0", Atom::Entry)
- add_maker("atom1.0:entry", "1.0", Atom::Entry)
- end
-end
diff --git a/lib/rss/maker/feed.rb b/lib/rss/maker/feed.rb
deleted file mode 100644
index fdef7ad643..0000000000
--- a/lib/rss/maker/feed.rb
+++ /dev/null
@@ -1,427 +0,0 @@
-# frozen_string_literal: false
-require "rss/maker/atom"
-
-module RSS
- module Maker
- module Atom
- class Feed < RSSBase
- def initialize(feed_version="1.0")
- super
- @feed_type = "atom"
- @feed_subtype = "feed"
- end
-
- private
- def make_feed
- ::RSS::Atom::Feed.new(@version, @encoding, @standalone)
- end
-
- def setup_elements(feed)
- setup_channel(feed)
- setup_image(feed)
- setup_items(feed)
- end
-
- class Channel < ChannelBase
- include SetupDefaultLanguage
-
- def to_feed(feed)
- set_default_values do
- setup_values(feed)
- feed.dc_dates.clear
- setup_other_elements(feed)
- if image_favicon.about
- icon = feed.class::Icon.new
- icon.content = image_favicon.about
- feed.icon = icon
- end
- unless have_required_values?
- raise NotSetError.new("maker.channel",
- not_set_required_variables)
- end
- end
- end
-
- def have_required_values?
- super and
- (!authors.empty? or
- @maker.items.any? {|item| !item.authors.empty?})
- end
-
- private
- def required_variable_names
- %w(id updated)
- end
-
- def variables
- super + %w(id updated)
- end
-
- def variable_is_set?
- super or !authors.empty?
- end
-
- def not_set_required_variables
- vars = super
- if authors.empty? and
- @maker.items.all? {|item| item.author.to_s.empty?}
- vars << "author"
- end
- vars << "title" unless title {|t| t.have_required_values?}
- vars
- end
-
- def _set_default_values(&block)
- keep = {
- :id => id,
- }
- self.id ||= about
- super(&block)
- ensure
- self.id = keep[:id]
- end
-
- class SkipDays < SkipDaysBase
- def to_feed(*args)
- end
-
- class Day < DayBase
- end
- end
-
- class SkipHours < SkipHoursBase
- def to_feed(*args)
- end
-
- class Hour < HourBase
- end
- end
-
- class Cloud < CloudBase
- def to_feed(*args)
- end
- end
-
- class Categories < CategoriesBase
- class Category < CategoryBase
- include AtomCategory
-
- def self.not_set_name
- "maker.channel.category"
- end
- end
- end
-
- class Links < LinksBase
- class Link < LinkBase
- include AtomLink
-
- def self.not_set_name
- "maker.channel.link"
- end
- end
- end
-
- AtomPersons.def_atom_persons(self, "author", "maker.channel.author")
- AtomPersons.def_atom_persons(self, "contributor",
- "maker.channel.contributor")
-
- class Generator < GeneratorBase
- include AtomGenerator
-
- def self.not_set_name
- "maker.channel.generator"
- end
- end
-
- AtomTextConstruct.def_atom_text_construct(self, "rights",
- "maker.channel.copyright",
- "Copyright")
- AtomTextConstruct.def_atom_text_construct(self, "subtitle",
- "maker.channel.description",
- "Description")
- AtomTextConstruct.def_atom_text_construct(self, "title",
- "maker.channel.title")
- end
-
- class Image < ImageBase
- def to_feed(feed)
- logo = feed.class::Logo.new
- class << logo
- alias_method(:url=, :content=)
- end
- set = setup_values(logo)
- class << logo
- remove_method(:url=)
- end
- if set
- feed.logo = logo
- set_parent(logo, feed)
- setup_other_elements(feed, logo)
- elsif variable_is_set?
- raise NotSetError.new("maker.image", not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(url)
- end
- end
-
- class Items < ItemsBase
- def to_feed(feed)
- normalize.each do |item|
- item.to_feed(feed)
- end
- setup_other_elements(feed, feed.entries)
- end
-
- class Item < ItemBase
- def to_feed(feed)
- set_default_values do
- entry = feed.class::Entry.new
- set = setup_values(entry)
- entry.dc_dates.clear
- setup_other_elements(feed, entry)
- if set
- feed.entries << entry
- set_parent(entry, feed)
- elsif variable_is_set?
- raise NotSetError.new("maker.item", not_set_required_variables)
- end
- end
- end
-
- def have_required_values?
- set_default_values do
- super and title {|t| t.have_required_values?}
- end
- end
-
- private
- def required_variable_names
- %w(id updated)
- end
-
- def variables
- super + ["updated"]
- end
-
- def not_set_required_variables
- vars = super
- vars << "title" unless title {|t| t.have_required_values?}
- vars
- end
-
- def _set_default_values(&block)
- keep = {
- :id => id,
- }
- self.id ||= link
- super(&block)
- ensure
- self.id = keep[:id]
- end
-
- class Guid < GuidBase
- def to_feed(feed, current)
- end
- end
-
- class Enclosure < EnclosureBase
- def to_feed(feed, current)
- end
- end
-
- class Source < SourceBase
- def to_feed(feed, current)
- source = current.class::Source.new
- setup_values(source)
- current.source = source
- set_parent(source, current)
- setup_other_elements(feed, source)
- current.source = nil if source.to_s == "<source/>"
- end
-
- private
- def required_variable_names
- []
- end
-
- def variables
- super + ["updated"]
- end
-
- AtomPersons.def_atom_persons(self, "author",
- "maker.item.source.author")
- AtomPersons.def_atom_persons(self, "contributor",
- "maker.item.source.contributor")
-
- class Categories < CategoriesBase
- class Category < CategoryBase
- include AtomCategory
-
- def self.not_set_name
- "maker.item.source.category"
- end
- end
- end
-
- class Generator < GeneratorBase
- include AtomGenerator
-
- def self.not_set_name
- "maker.item.source.generator"
- end
- end
-
- class Icon < IconBase
- def to_feed(feed, current)
- icon = current.class::Icon.new
- class << icon
- alias_method(:url=, :content=)
- end
- set = setup_values(icon)
- class << icon
- remove_method(:url=)
- end
- if set
- current.icon = icon
- set_parent(icon, current)
- setup_other_elements(feed, icon)
- elsif variable_is_set?
- raise NotSetError.new("maker.item.source.icon",
- not_set_required_variables)
- end
- end
-
- private
- def required_variable_names
- %w(url)
- end
- end
-
- class Links < LinksBase
- class Link < LinkBase
- include AtomLink
-
- def self.not_set_name
- "maker.item.source.link"
- end
- end
- end
-
- class Logo < LogoBase
- include AtomLogo
-
- def self.not_set_name
- "maker.item.source.logo"
- end
- end
-
- maker_name_base = "maker.item.source."
- maker_name = "#{maker_name_base}rights"
- AtomTextConstruct.def_atom_text_construct(self, "rights",
- maker_name)
- maker_name = "#{maker_name_base}subtitle"
- AtomTextConstruct.def_atom_text_construct(self, "subtitle",
- maker_name)
- maker_name = "#{maker_name_base}title"
- AtomTextConstruct.def_atom_text_construct(self, "title",
- maker_name)
- end
-
- class Categories < CategoriesBase
- class Category < CategoryBase
- include AtomCategory
-
- def self.not_set_name
- "maker.item.category"
- end
- end
- end
-
- AtomPersons.def_atom_persons(self, "author", "maker.item.author")
- AtomPersons.def_atom_persons(self, "contributor",
- "maker.item.contributor")
-
- class Links < LinksBase
- class Link < LinkBase
- include AtomLink
-
- def self.not_set_name
- "maker.item.link"
- end
- end
- end
-
- AtomTextConstruct.def_atom_text_construct(self, "rights",
- "maker.item.rights")
- AtomTextConstruct.def_atom_text_construct(self, "summary",
- "maker.item.description",
- "Description")
- AtomTextConstruct.def_atom_text_construct(self, "title",
- "maker.item.title")
-
- class Content < ContentBase
- def to_feed(feed, current)
- content = current.class::Content.new
- if setup_values(content)
- content.src = nil if content.src and content.content
- current.content = content
- set_parent(content, current)
- setup_other_elements(feed, content)
- elsif variable_is_set?
- raise NotSetError.new("maker.item.content",
- not_set_required_variables)
- end
- end
-
- alias_method(:xml, :xml_content)
-
- private
- def required_variable_names
- if out_of_line?
- %w(type)
- elsif xml_type?
- %w(xml_content)
- else
- %w(content)
- end
- end
-
- def variables
- if out_of_line?
- super
- elsif xml_type?
- super + %w(xml)
- else
- super
- end
- end
-
- def xml_type?
- _type = type
- return false if _type.nil?
- _type == "xhtml" or
- /(?:\+xml|\/xml)$/i =~ _type or
- %w(text/xml-external-parsed-entity
- application/xml-external-parsed-entity
- application/xml-dtd).include?(_type.downcase)
- end
- end
- end
- end
-
- class Textinput < TextinputBase
- end
- end
- end
-
- add_maker("atom", "1.0", Atom::Feed)
- add_maker("atom:feed", "1.0", Atom::Feed)
- add_maker("atom1.0", "1.0", Atom::Feed)
- add_maker("atom1.0:feed", "1.0", Atom::Feed)
- end
-end
diff --git a/lib/rss/maker/image.rb b/lib/rss/maker/image.rb
deleted file mode 100644
index 1957ba8689..0000000000
--- a/lib/rss/maker/image.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# frozen_string_literal: false
-require 'rss/image'
-require 'rss/maker/1.0'
-require 'rss/maker/dublincore'
-
-module RSS
- module Maker
- module ImageItemModel
- def self.append_features(klass)
- super
-
- name = "#{RSS::IMAGE_PREFIX}_item"
- klass.def_classed_element(name)
- end
-
- def self.install_image_item(klass)
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class ImageItem < ImageItemBase
- DublinCoreModel.install_dublin_core(self)
- end
-EOC
- end
-
- class ImageItemBase < Base
- include Maker::DublinCoreModel
-
- attr_accessor :about, :resource, :image_width, :image_height
- add_need_initialize_variable("about")
- add_need_initialize_variable("resource")
- add_need_initialize_variable("image_width")
- add_need_initialize_variable("image_height")
- alias width= image_width=
- alias width image_width
- alias height= image_height=
- alias height image_height
-
- def have_required_values?
- @about
- end
-
- def to_feed(feed, current)
- if current.respond_to?(:image_item=) and have_required_values?
- item = current.class::ImageItem.new
- setup_values(item)
- setup_other_elements(item)
- current.image_item = item
- end
- end
- end
- end
-
- module ImageFaviconModel
- def self.append_features(klass)
- super
-
- name = "#{RSS::IMAGE_PREFIX}_favicon"
- klass.def_classed_element(name)
- end
-
- def self.install_image_favicon(klass)
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class ImageFavicon < ImageFaviconBase
- DublinCoreModel.install_dublin_core(self)
- end
- EOC
- end
-
- class ImageFaviconBase < Base
- include Maker::DublinCoreModel
-
- attr_accessor :about, :image_size
- add_need_initialize_variable("about")
- add_need_initialize_variable("image_size")
- alias size image_size
- alias size= image_size=
-
- def have_required_values?
- @about and @image_size
- end
-
- def to_feed(feed, current)
- if current.respond_to?(:image_favicon=) and have_required_values?
- favicon = current.class::ImageFavicon.new
- setup_values(favicon)
- setup_other_elements(favicon)
- current.image_favicon = favicon
- end
- end
- end
- end
-
- class ChannelBase; include Maker::ImageFaviconModel; end
-
- class ItemsBase
- class ItemBase; include Maker::ImageItemModel; end
- end
-
- makers.each do |maker|
- maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class Channel
- ImageFaviconModel.install_image_favicon(self)
- end
-
- class Items
- class Item
- ImageItemModel.install_image_item(self)
- end
- end
- EOC
- end
- end
-end
diff --git a/lib/rss/maker/itunes.rb b/lib/rss/maker/itunes.rb
deleted file mode 100644
index cc1051ae0c..0000000000
--- a/lib/rss/maker/itunes.rb
+++ /dev/null
@@ -1,243 +0,0 @@
-# frozen_string_literal: false
-require 'rss/itunes'
-require 'rss/maker/2.0'
-
-module RSS
- module Maker
- module ITunesBaseModel
- def def_class_accessor(klass, name, type, *args)
- name = name.gsub(/-/, "_").gsub(/^itunes_/, '')
- full_name = "#{RSS::ITUNES_PREFIX}_#{name}"
- case type
- when nil
- klass.def_other_element(full_name)
- when :yes_other
- def_yes_other_accessor(klass, full_name)
- when :yes_clean_other
- def_yes_clean_other_accessor(klass, full_name)
- when :csv
- def_csv_accessor(klass, full_name)
- when :element, :attribute
- recommended_attribute_name, = *args
- klass_name = "ITunes#{Utils.to_class_name(name)}"
- klass.def_classed_element(full_name, klass_name,
- recommended_attribute_name)
- when :elements
- plural_name, recommended_attribute_name = args
- plural_name ||= "#{name}s"
- full_plural_name = "#{RSS::ITUNES_PREFIX}_#{plural_name}"
- klass_name = "ITunes#{Utils.to_class_name(name)}"
- plural_klass_name = "ITunes#{Utils.to_class_name(plural_name)}"
- def_elements_class_accessor(klass, name, full_name, full_plural_name,
- klass_name, plural_klass_name,
- recommended_attribute_name)
- end
- end
-
- def def_yes_other_accessor(klass, full_name)
- klass.def_other_element(full_name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{full_name}?
- Utils::YesOther.parse(@#{full_name})
- end
- EOC
- end
-
- def def_yes_clean_other_accessor(klass, full_name)
- klass.def_other_element(full_name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{full_name}?
- Utils::YesCleanOther.parse(#{full_name})
- end
- EOC
- end
-
- def def_csv_accessor(klass, full_name)
- klass.def_csv_element(full_name)
- end
-
- def def_elements_class_accessor(klass, name, full_name, full_plural_name,
- klass_name, plural_klass_name,
- recommended_attribute_name=nil)
- if recommended_attribute_name
- klass.def_classed_elements(full_name, recommended_attribute_name,
- plural_klass_name, full_plural_name)
- else
- klass.def_classed_element(full_plural_name, plural_klass_name)
- end
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def new_#{full_name}(text=nil)
- #{full_name} = @#{full_plural_name}.new_#{name}
- #{full_name}.text = text
- if block_given?
- yield #{full_name}
- else
- #{full_name}
- end
- end
- EOC
- end
- end
-
- module ITunesChannelModel
- extend ITunesBaseModel
-
- class << self
- def append_features(klass)
- super
-
- ::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args|
- def_class_accessor(klass, name, type, *args)
- end
- end
- end
-
- class ITunesCategoriesBase < Base
- def_array_element("category", "itunes_categories",
- "ITunesCategory")
- class ITunesCategoryBase < Base
- attr_accessor :text
- add_need_initialize_variable("text")
- def_array_element("category", "itunes_categories",
- "ITunesCategory")
-
- def have_required_values?
- text
- end
-
- alias_method :to_feed_for_categories, :to_feed
- def to_feed(feed, current)
- if text and current.respond_to?(:itunes_category)
- new_item = current.class::ITunesCategory.new(text)
- to_feed_for_categories(feed, new_item)
- current.itunes_categories << new_item
- end
- end
- end
- end
-
- class ITunesImageBase < Base
- add_need_initialize_variable("href")
- attr_accessor("href")
-
- def to_feed(feed, current)
- if @href and current.respond_to?(:itunes_image)
- current.itunes_image ||= current.class::ITunesImage.new
- current.itunes_image.href = @href
- end
- end
- end
-
- class ITunesOwnerBase < Base
- %w(itunes_name itunes_email).each do |name|
- add_need_initialize_variable(name)
- attr_accessor(name)
- end
-
- def to_feed(feed, current)
- if current.respond_to?(:itunes_owner=)
- _not_set_required_variables = not_set_required_variables
- if (required_variable_names - _not_set_required_variables).empty?
- return
- end
-
- unless have_required_values?
- raise NotSetError.new("maker.channel.itunes_owner",
- _not_set_required_variables)
- end
- current.itunes_owner ||= current.class::ITunesOwner.new
- current.itunes_owner.itunes_name = @itunes_name
- current.itunes_owner.itunes_email = @itunes_email
- end
- end
-
- private
- def required_variable_names
- %w(itunes_name itunes_email)
- end
- end
- end
-
- module ITunesItemModel
- extend ITunesBaseModel
-
- class << self
- def append_features(klass)
- super
-
- ::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args|
- def_class_accessor(klass, name, type, *args)
- end
- end
- end
-
- class ITunesDurationBase < Base
- attr_reader :content
- add_need_initialize_variable("content")
-
- %w(hour minute second).each do |name|
- attr_reader(name)
- add_need_initialize_variable(name, 0)
- end
-
- def content=(content)
- if content.nil?
- @hour, @minute, @second, @content = nil
- else
- @hour, @minute, @second =
- ::RSS::ITunesItemModel::ITunesDuration.parse(content)
- @content = content
- end
- end
-
- def hour=(hour)
- @hour = Integer(hour)
- update_content
- end
-
- def minute=(minute)
- @minute = Integer(minute)
- update_content
- end
-
- def second=(second)
- @second = Integer(second)
- update_content
- end
-
- def to_feed(feed, current)
- if @content and current.respond_to?(:itunes_duration=)
- current.itunes_duration ||= current.class::ITunesDuration.new
- current.itunes_duration.content = @content
- end
- end
-
- private
- def update_content
- components = [@hour, @minute, @second]
- @content =
- ::RSS::ITunesItemModel::ITunesDuration.construct(*components)
- end
- end
- end
-
- class ChannelBase
- include Maker::ITunesChannelModel
- class ITunesCategories < ITunesCategoriesBase
- class ITunesCategory < ITunesCategoryBase
- ITunesCategory = self
- end
- end
-
- class ITunesImage < ITunesImageBase; end
- class ITunesOwner < ITunesOwnerBase; end
- end
-
- class ItemsBase
- class ItemBase
- include Maker::ITunesItemModel
- class ITunesDuration < ITunesDurationBase; end
- end
- end
- end
-end
diff --git a/lib/rss/maker/slash.rb b/lib/rss/maker/slash.rb
deleted file mode 100644
index 3bd82d3057..0000000000
--- a/lib/rss/maker/slash.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: false
-require 'rss/slash'
-require 'rss/maker/1.0'
-
-module RSS
- module Maker
- module SlashModel
- def self.append_features(klass)
- super
-
- ::RSS::SlashModel::ELEMENT_INFOS.each do |name, type|
- full_name = "#{RSS::SLASH_PREFIX}_#{name}"
- case type
- when :csv_integer
- klass.def_csv_element(full_name, :integer)
- else
- klass.def_other_element(full_name)
- end
- end
-
- klass.module_eval do
- alias_method(:slash_hit_parades, :slash_hit_parade)
- alias_method(:slash_hit_parades=, :slash_hit_parade=)
- end
- end
- end
-
- class ItemsBase
- class ItemBase
- include SlashModel
- end
- end
- end
-end
diff --git a/lib/rss/maker/syndication.rb b/lib/rss/maker/syndication.rb
deleted file mode 100644
index 840b70229a..0000000000
--- a/lib/rss/maker/syndication.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: false
-require 'rss/syndication'
-require 'rss/maker/1.0'
-
-module RSS
- module Maker
- module SyndicationModel
- def self.append_features(klass)
- super
-
- ::RSS::SyndicationModel::ELEMENTS.each do |name|
- klass.def_other_element(name)
- end
- end
- end
-
- class ChannelBase; include SyndicationModel; end
- end
-end
diff --git a/lib/rss/maker/taxonomy.rb b/lib/rss/maker/taxonomy.rb
deleted file mode 100644
index 76a2d1600d..0000000000
--- a/lib/rss/maker/taxonomy.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-# frozen_string_literal: false
-require 'rss/taxonomy'
-require 'rss/maker/1.0'
-require 'rss/maker/dublincore'
-
-module RSS
- module Maker
- module TaxonomyTopicsModel
- def self.append_features(klass)
- super
-
- klass.def_classed_element("#{RSS::TAXO_PREFIX}_topics",
- "TaxonomyTopics")
- end
-
- def self.install_taxo_topics(klass)
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class TaxonomyTopics < TaxonomyTopicsBase
- def to_feed(feed, current)
- if current.respond_to?(:taxo_topics)
- topics = current.class::TaxonomyTopics.new
- bag = topics.Bag
- @resources.each do |resource|
- bag.lis << RDF::Bag::Li.new(resource)
- end
- current.taxo_topics = topics
- end
- end
- end
-EOC
- end
-
- class TaxonomyTopicsBase < Base
- attr_reader :resources
- def_array_element("resource")
- remove_method :new_resource
- end
- end
-
- module TaxonomyTopicModel
- def self.append_features(klass)
- super
-
- class_name = "TaxonomyTopics"
- klass.def_classed_elements("#{TAXO_PREFIX}_topic", "value", class_name)
- end
-
- def self.install_taxo_topic(klass)
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class TaxonomyTopics < TaxonomyTopicsBase
- class TaxonomyTopic < TaxonomyTopicBase
- DublinCoreModel.install_dublin_core(self)
- TaxonomyTopicsModel.install_taxo_topics(self)
-
- def to_feed(feed, current)
- if current.respond_to?(:taxo_topics)
- topic = current.class::TaxonomyTopic.new(value)
- topic.taxo_link = value
- taxo_topics.to_feed(feed, topic) if taxo_topics
- current.taxo_topics << topic
- setup_other_elements(feed, topic)
- end
- end
- end
- end
-EOC
- end
-
- class TaxonomyTopicsBase < Base
- def_array_element("topic", nil, "TaxonomyTopic")
- alias_method(:new_taxo_topic, :new_topic) # For backward compatibility
-
- class TaxonomyTopicBase < Base
- include DublinCoreModel
- include TaxonomyTopicsModel
-
- attr_accessor :value
- add_need_initialize_variable("value")
- alias_method(:taxo_link, :value)
- alias_method(:taxo_link=, :value=)
-
- def have_required_values?
- @value
- end
- end
- end
- end
-
- class RSSBase
- include TaxonomyTopicModel
- end
-
- class ChannelBase
- include TaxonomyTopicsModel
- end
-
- class ItemsBase
- class ItemBase
- include TaxonomyTopicsModel
- end
- end
-
- makers.each do |maker|
- maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- TaxonomyTopicModel.install_taxo_topic(self)
-
- class Channel
- TaxonomyTopicsModel.install_taxo_topics(self)
- end
-
- class Items
- class Item
- TaxonomyTopicsModel.install_taxo_topics(self)
- end
- end
- EOC
- end
- end
-end
diff --git a/lib/rss/maker/trackback.rb b/lib/rss/maker/trackback.rb
deleted file mode 100644
index f97691c608..0000000000
--- a/lib/rss/maker/trackback.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: false
-require 'rss/trackback'
-require 'rss/maker/1.0'
-require 'rss/maker/2.0'
-
-module RSS
- module Maker
- module TrackBackModel
- def self.append_features(klass)
- super
-
- klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping")
- klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value",
- "TrackBackAbouts")
- end
-
- class TrackBackAboutsBase < Base
- def_array_element("about", nil, "TrackBackAbout")
-
- class TrackBackAboutBase < Base
- attr_accessor :value
- add_need_initialize_variable("value")
-
- alias_method(:resource, :value)
- alias_method(:resource=, :value=)
- alias_method(:content, :value)
- alias_method(:content=, :value=)
-
- def have_required_values?
- @value
- end
-
- def to_feed(feed, current)
- if current.respond_to?(:trackback_abouts) and have_required_values?
- about = current.class::TrackBackAbout.new
- setup_values(about)
- setup_other_elements(about)
- current.trackback_abouts << about
- end
- end
- end
- end
- end
-
- class ItemsBase
- class ItemBase; include TrackBackModel; end
- end
-
- makers.each do |maker|
- maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- class Items
- class Item
- class TrackBackAbouts < TrackBackAboutsBase
- class TrackBackAbout < TrackBackAboutBase
- end
- end
- end
- end
- EOC
- end
- end
-end
diff --git a/lib/rss/parser.rb b/lib/rss/parser.rb
deleted file mode 100644
index a9842e6d40..0000000000
--- a/lib/rss/parser.rb
+++ /dev/null
@@ -1,571 +0,0 @@
-# frozen_string_literal: false
-require "forwardable"
-require "open-uri"
-
-require "rss/rss"
-require "rss/xml"
-
-module RSS
-
- class NotWellFormedError < Error
- attr_reader :line, :element
-
- # Create a new NotWellFormedError for an error at +line+
- # in +element+. If a block is given the return value of
- # the block ends up in the error message.
- def initialize(line=nil, element=nil)
- message = "This is not well formed XML"
- if element or line
- message << "\nerror occurred"
- message << " in #{element}" if element
- message << " at about #{line} line" if line
- end
- message << "\n#{yield}" if block_given?
- super(message)
- end
- end
-
- class XMLParserNotFound < Error
- def initialize
- super("available XML parser was not found in " <<
- "#{AVAILABLE_PARSER_LIBRARIES.inspect}.")
- end
- end
-
- class NotValidXMLParser < Error
- def initialize(parser)
- super("#{parser} is not an available XML parser. " <<
- "Available XML parser" <<
- (AVAILABLE_PARSERS.size > 1 ? "s are " : " is ") <<
- "#{AVAILABLE_PARSERS.inspect}.")
- end
- end
-
- class NSError < InvalidRSSError
- attr_reader :tag, :prefix, :uri
- def initialize(tag, prefix, require_uri)
- @tag, @prefix, @uri = tag, prefix, require_uri
- super("prefix <#{prefix}> doesn't associate uri " <<
- "<#{require_uri}> in tag <#{tag}>")
- end
- end
-
- class Parser
-
- extend Forwardable
-
- class << self
-
- @@default_parser = nil
-
- def default_parser
- @@default_parser || AVAILABLE_PARSERS.first
- end
-
- # Set @@default_parser to new_value if it is one of the
- # available parsers. Else raise NotValidXMLParser error.
- def default_parser=(new_value)
- if AVAILABLE_PARSERS.include?(new_value)
- @@default_parser = new_value
- else
- raise NotValidXMLParser.new(new_value)
- end
- end
-
- def parse(rss, do_validate=true, ignore_unknown_element=true,
- parser_class=default_parser)
- parser = new(rss, parser_class)
- parser.do_validate = do_validate
- parser.ignore_unknown_element = ignore_unknown_element
- parser.parse
- end
- end
-
- def_delegators(:@parser, :parse, :rss,
- :ignore_unknown_element,
- :ignore_unknown_element=, :do_validate,
- :do_validate=)
-
- def initialize(rss, parser_class=self.class.default_parser)
- @parser = parser_class.new(normalize_rss(rss))
- end
-
- private
-
- # Try to get the XML associated with +rss+.
- # Return +rss+ if it already looks like XML, or treat it as a URI,
- # or a file to get the XML,
- def normalize_rss(rss)
- return rss if maybe_xml?(rss)
-
- uri = to_uri(rss)
-
- if uri.respond_to?(:read)
- uri.read
- elsif !rss.tainted? and File.readable?(rss)
- File.open(rss) {|f| f.read}
- else
- rss
- end
- end
-
- # maybe_xml? tests if source is a string that looks like XML.
- def maybe_xml?(source)
- source.is_a?(String) and /</ =~ source
- end
-
- # Attempt to convert rss to a URI, but just return it if
- # there's a ::URI::Error
- def to_uri(rss)
- return rss if rss.is_a?(::URI::Generic)
-
- begin
- ::URI.parse(rss)
- rescue ::URI::Error
- rss
- end
- end
- end
-
- class BaseParser
-
- class << self
- def raise_for_undefined_entity?
- listener.raise_for_undefined_entity?
- end
- end
-
- def initialize(rss)
- @listener = self.class.listener.new
- @rss = rss
- end
-
- def rss
- @listener.rss
- end
-
- def ignore_unknown_element
- @listener.ignore_unknown_element
- end
-
- def ignore_unknown_element=(new_value)
- @listener.ignore_unknown_element = new_value
- end
-
- def do_validate
- @listener.do_validate
- end
-
- def do_validate=(new_value)
- @listener.do_validate = new_value
- end
-
- def parse
- if @listener.rss.nil?
- _parse
- end
- @listener.rss
- end
-
- end
-
- class BaseListener
-
- extend Utils
-
- class << self
-
- @@accessor_bases = {}
- @@registered_uris = {}
- @@class_names = {}
-
- # return the setter for the uri, tag_name pair, or nil.
- def setter(uri, tag_name)
- _getter = getter(uri, tag_name)
- if _getter
- "#{_getter}="
- else
- nil
- end
- end
-
- def getter(uri, tag_name)
- (@@accessor_bases[uri] || {})[tag_name]
- end
-
- # return the tag_names for setters associated with uri
- def available_tags(uri)
- (@@accessor_bases[uri] || {}).keys
- end
-
- # register uri against this name.
- def register_uri(uri, name)
- @@registered_uris[name] ||= {}
- @@registered_uris[name][uri] = nil
- end
-
- # test if this uri is registered against this name
- def uri_registered?(uri, name)
- @@registered_uris[name].has_key?(uri)
- end
-
- # record class_name for the supplied uri and tag_name
- def install_class_name(uri, tag_name, class_name)
- @@class_names[uri] ||= {}
- @@class_names[uri][tag_name] = class_name
- end
-
- # retrieve class_name for the supplied uri and tag_name
- # If it doesn't exist, capitalize the tag_name
- def class_name(uri, tag_name)
- name = (@@class_names[uri] || {})[tag_name]
- return name if name
-
- tag_name = tag_name.gsub(/[_\-]([a-z]?)/) {$1.upcase}
- tag_name[0, 1].upcase + tag_name[1..-1]
- end
-
- def install_get_text_element(uri, name, accessor_base)
- install_accessor_base(uri, name, accessor_base)
- def_get_text_element(uri, name, *get_file_and_line_from_caller(1))
- end
-
- def raise_for_undefined_entity?
- true
- end
-
- private
- # set the accessor for the uri, tag_name pair
- def install_accessor_base(uri, tag_name, accessor_base)
- @@accessor_bases[uri] ||= {}
- @@accessor_bases[uri][tag_name] = accessor_base.chomp("=")
- end
-
- def def_get_text_element(uri, element_name, file, line)
- register_uri(uri, element_name)
- method_name = "start_#{element_name}"
- unless private_method_defined?(method_name)
- define_method(method_name) do |name, prefix, attrs, ns|
- uri = _ns(ns, prefix)
- if self.class.uri_registered?(uri, element_name)
- start_get_text_element(name, prefix, ns, uri)
- else
- start_else_element(name, prefix, attrs, ns)
- end
- end
- private(method_name)
- end
- end
- end
- end
-
- module ListenerMixin
- attr_reader :rss
-
- attr_accessor :ignore_unknown_element
- attr_accessor :do_validate
-
- def initialize
- @rss = nil
- @ignore_unknown_element = true
- @do_validate = true
- @ns_stack = [{"xml" => :xml}]
- @tag_stack = [[]]
- @text_stack = ['']
- @proc_stack = []
- @last_element = nil
- @version = @encoding = @standalone = nil
- @xml_stylesheets = []
- @xml_child_mode = false
- @xml_element = nil
- @last_xml_element = nil
- end
-
- # set instance vars for version, encoding, standalone
- def xmldecl(version, encoding, standalone)
- @version, @encoding, @standalone = version, encoding, standalone
- end
-
- def instruction(name, content)
- if name == "xml-stylesheet"
- params = parse_pi_content(content)
- if params.has_key?("href")
- @xml_stylesheets << XMLStyleSheet.new(params)
- end
- end
- end
-
- def tag_start(name, attributes)
- @text_stack.push('')
-
- ns = @ns_stack.last.dup
- attrs = {}
- attributes.each do |n, v|
- if /\Axmlns(?:\z|:)/ =~ n
- ns[$POSTMATCH] = v
- else
- attrs[n] = v
- end
- end
- @ns_stack.push(ns)
-
- prefix, local = split_name(name)
- @tag_stack.last.push([_ns(ns, prefix), local])
- @tag_stack.push([])
- if @xml_child_mode
- previous = @last_xml_element
- element_attrs = attributes.dup
- unless previous
- ns.each do |ns_prefix, value|
- next if ns_prefix == "xml"
- key = ns_prefix.empty? ? "xmlns" : "xmlns:#{ns_prefix}"
- element_attrs[key] ||= value
- end
- end
- next_element = XML::Element.new(local,
- prefix.empty? ? nil : prefix,
- _ns(ns, prefix),
- element_attrs)
- previous << next_element if previous
- @last_xml_element = next_element
- pr = Proc.new do |text, tags|
- if previous
- @last_xml_element = previous
- else
- @xml_element = @last_xml_element
- @last_xml_element = nil
- end
- end
- @proc_stack.push(pr)
- else
- if @rss.nil? and respond_to?("initial_start_#{local}", true)
- __send__("initial_start_#{local}", local, prefix, attrs, ns.dup)
- elsif respond_to?("start_#{local}", true)
- __send__("start_#{local}", local, prefix, attrs, ns.dup)
- else
- start_else_element(local, prefix, attrs, ns.dup)
- end
- end
- end
-
- def tag_end(name)
- if DEBUG
- p "end tag #{name}"
- p @tag_stack
- end
- text = @text_stack.pop
- tags = @tag_stack.pop
- pr = @proc_stack.pop
- pr.call(text, tags) unless pr.nil?
- @ns_stack.pop
- end
-
- def text(data)
- if @xml_child_mode
- @last_xml_element << data if @last_xml_element
- else
- @text_stack.last << data
- end
- end
-
- private
- def _ns(ns, prefix)
- ns.fetch(prefix, "")
- end
-
- CONTENT_PATTERN = /\s*([^=]+)=(["'])([^\2]+?)\2/
- # Extract the first name="value" pair from content.
- # Works with single quotes according to the constant
- # CONTENT_PATTERN. Return a Hash.
- def parse_pi_content(content)
- params = {}
- content.scan(CONTENT_PATTERN) do |name, quote, value|
- params[name] = value
- end
- params
- end
-
- def start_else_element(local, prefix, attrs, ns)
- class_name = self.class.class_name(_ns(ns, prefix), local)
- current_class = @last_element.class
- if known_class?(current_class, class_name)
- next_class = current_class.const_get(class_name)
- start_have_something_element(local, prefix, attrs, ns, next_class)
- else
- if !@do_validate or @ignore_unknown_element
- @proc_stack.push(setup_next_element_in_unknown_element)
- else
- parent = "ROOT ELEMENT???"
- if current_class.tag_name
- parent = current_class.tag_name
- end
- raise NotExpectedTagError.new(local, _ns(ns, prefix), parent)
- end
- end
- end
-
- if Module.method(:const_defined?).arity == -1
- def known_class?(target_class, class_name)
- class_name and
- (target_class.const_defined?(class_name, false) or
- target_class.constants.include?(class_name.to_sym))
- end
- else
- def known_class?(target_class, class_name)
- class_name and
- (target_class.const_defined?(class_name) or
- target_class.constants.include?(class_name))
- end
- end
-
- NAMESPLIT = /^(?:([\w:][-\w.]*):)?([\w:][-\w.]*)/
- def split_name(name)
- name =~ NAMESPLIT
- [$1 || '', $2]
- end
-
- def check_ns(tag_name, prefix, ns, require_uri, ignore_unknown_element=nil)
- if _ns(ns, prefix) == require_uri
- true
- else
- if ignore_unknown_element.nil?
- ignore_unknown_element = @ignore_unknown_element
- end
-
- if ignore_unknown_element
- false
- elsif @do_validate
- raise NSError.new(tag_name, prefix, require_uri)
- else
- # Force bind required URI with prefix
- @ns_stack.last[prefix] = require_uri
- true
- end
- end
- end
-
- def start_get_text_element(tag_name, prefix, ns, required_uri)
- pr = Proc.new do |text, tags|
- setter = self.class.setter(required_uri, tag_name)
- if setter and @last_element.respond_to?(setter)
- if @do_validate
- getter = self.class.getter(required_uri, tag_name)
- if @last_element.__send__(getter)
- raise TooMuchTagError.new(tag_name, @last_element.tag_name)
- end
- end
- @last_element.__send__(setter, text.to_s)
- else
- if @do_validate and !@ignore_unknown_element
- raise NotExpectedTagError.new(tag_name, _ns(ns, prefix),
- @last_element.tag_name)
- end
- end
- end
- @proc_stack.push(pr)
- end
-
- def start_have_something_element(tag_name, prefix, attrs, ns, klass)
- if check_ns(tag_name, prefix, ns, klass.required_uri)
- attributes = collect_attributes(tag_name, prefix, attrs, ns, klass)
- @proc_stack.push(setup_next_element(tag_name, klass, attributes))
- else
- @proc_stack.push(setup_next_element_in_unknown_element)
- end
- end
-
- def collect_attributes(tag_name, prefix, attrs, ns, klass)
- attributes = {}
- klass.get_attributes.each do |a_name, a_uri, required, element_name|
- if a_uri.is_a?(String) or !a_uri.respond_to?(:include?)
- a_uri = [a_uri]
- end
- unless a_uri == [""]
- for prefix, uri in ns
- if a_uri.include?(uri)
- val = attrs["#{prefix}:#{a_name}"]
- break if val
- end
- end
- end
- if val.nil? and a_uri.include?("")
- val = attrs[a_name]
- end
-
- if @do_validate and required and val.nil?
- unless a_uri.include?("")
- for prefix, uri in ns
- if a_uri.include?(uri)
- a_name = "#{prefix}:#{a_name}"
- end
- end
- end
- raise MissingAttributeError.new(tag_name, a_name)
- end
-
- attributes[a_name] = val
- end
- attributes
- end
-
- def setup_next_element(tag_name, klass, attributes)
- previous = @last_element
- next_element = klass.new(@do_validate, attributes)
- previous.set_next_element(tag_name, next_element)
- @last_element = next_element
- @last_element.parent = previous if klass.need_parent?
- @xml_child_mode = @last_element.have_xml_content?
-
- Proc.new do |text, tags|
- p(@last_element.class) if DEBUG
- if @xml_child_mode
- @last_element.content = @xml_element.to_s
- xml_setter = @last_element.class.xml_setter
- @last_element.__send__(xml_setter, @xml_element)
- @xml_element = nil
- @xml_child_mode = false
- else
- if klass.have_content?
- if @last_element.need_base64_encode?
- text = text.lstrip.unpack("m").first
- end
- @last_element.content = text
- end
- end
- if @do_validate
- @last_element.validate_for_stream(tags, @ignore_unknown_element)
- end
- @last_element = previous
- end
- end
-
- def setup_next_element_in_unknown_element
- current_element, @last_element = @last_element, nil
- Proc.new {@last_element = current_element}
- end
- end
-
- unless const_defined? :AVAILABLE_PARSER_LIBRARIES
- # The list of all available libraries for parsing.
- AVAILABLE_PARSER_LIBRARIES = [
- ["rss/xmlparser", :XMLParserParser],
- ["rss/xmlscanner", :XMLScanParser],
- ["rss/rexmlparser", :REXMLParser],
- ]
- end
-
- # The list of all available parsers, in constant form.
- AVAILABLE_PARSERS = []
-
- AVAILABLE_PARSER_LIBRARIES.each do |lib, parser|
- begin
- require lib
- AVAILABLE_PARSERS.push(const_get(parser))
- rescue LoadError
- end
- end
-
- if AVAILABLE_PARSERS.empty?
- raise XMLParserNotFound
- end
-end
diff --git a/lib/rss/rexmlparser.rb b/lib/rss/rexmlparser.rb
deleted file mode 100644
index ef0595e447..0000000000
--- a/lib/rss/rexmlparser.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: false
-require "rexml/document"
-require "rexml/streamlistener"
-
-module RSS
-
- class REXMLParser < BaseParser
-
- class << self
- def listener
- REXMLListener
- end
- end
-
- private
- def _parse
- begin
- REXML::Document.parse_stream(@rss, @listener)
- rescue RuntimeError => e
- raise NotWellFormedError.new{e.message}
- rescue REXML::ParseException => e
- context = e.context
- line = context[0] if context
- raise NotWellFormedError.new(line){e.message}
- end
- end
-
- end
-
- class REXMLListener < BaseListener
-
- include REXML::StreamListener
- include ListenerMixin
-
- class << self
- def raise_for_undefined_entity?
- false
- end
- end
-
- def xmldecl(version, encoding, standalone)
- super(version, encoding, standalone == "yes")
- # Encoding is converted to UTF-8 when REXML parse XML.
- @encoding = 'UTF-8'
- end
-
- alias_method(:cdata, :text)
- end
-
-end
diff --git a/lib/rss/rss.rb b/lib/rss/rss.rb
deleted file mode 100644
index 00db219d4e..0000000000
--- a/lib/rss/rss.rb
+++ /dev/null
@@ -1,1347 +0,0 @@
-# frozen_string_literal: false
-require "time"
-
-class Time
- class << self
- unless respond_to?(:w3cdtf)
- # This method converts a W3CDTF string date/time format to Time object.
- #
- # The W3CDTF format is defined here: http://www.w3.org/TR/NOTE-datetime
- #
- # Time.w3cdtf('2003-02-15T13:50:05-05:00')
- # # => 2003-02-15 10:50:05 -0800
- # Time.w3cdtf('2003-02-15T13:50:05-05:00').class
- # # => Time
- def w3cdtf(date)
- if /\A\s*
- (-?\d+)-(\d\d)-(\d\d)
- (?:T
- (\d\d):(\d\d)(?::(\d\d))?
- (\.\d+)?
- (Z|[+-]\d\d:\d\d)?)?
- \s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8))
- datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
- usec = 0
- usec = $7.to_f * 1000000 if $7
- zone = $8
- if zone
- off = zone_offset(zone, datetime[0])
- datetime = apply_offset(*(datetime + [off]))
- datetime << usec
- time = Time.utc(*datetime)
- force_zone!(time, zone, off)
- time
- else
- datetime << usec
- Time.local(*datetime)
- end
- else
- raise ArgumentError.new("invalid date: #{date.inspect}")
- end
- end
- end
- end
-
- unless method_defined?(:w3cdtf)
- # This method converts a Time object to a String. The String contains the
- # time in W3CDTF date/time format.
- #
- # The W3CDTF format is defined here: http://www.w3.org/TR/NOTE-datetime
- #
- # Time.now.w3cdtf
- # # => "2013-08-26T14:12:10.817124-07:00"
- def w3cdtf
- if usec.zero?
- fraction_digits = 0
- else
- fraction_digits = strftime('%6N').index(/0*\z/)
- end
- xmlschema(fraction_digits)
- end
- end
-end
-
-
-require "English"
-require "rss/utils"
-require "rss/converter"
-require "rss/xml-stylesheet"
-
-module RSS
-
- # The current version of RSS
- VERSION = "0.2.7"
-
- # The URI of the RSS 1.0 specification
- URI = "http://purl.org/rss/1.0/"
-
- DEBUG = false # :nodoc:
-
- # The basic error all other RSS errors stem from. Rescue this error if you
- # want to handle any given RSS error and you don't care about the details.
- class Error < StandardError; end
-
- # RSS, being an XML-based format, has namespace support. If two namespaces are
- # declared with the same name, an OverlappedPrefixError will be raised.
- class OverlappedPrefixError < Error
- attr_reader :prefix
- def initialize(prefix)
- @prefix = prefix
- end
- end
-
- # The InvalidRSSError error is the base class for a variety of errors
- # related to a poorly-formed RSS feed. Rescue this error if you only
- # care that a file could be invalid, but don't care how it is invalid.
- class InvalidRSSError < Error; end
-
- # Since RSS is based on XML, it must have opening and closing tags that
- # match. If they don't, a MissingTagError will be raised.
- class MissingTagError < InvalidRSSError
- attr_reader :tag, :parent
- def initialize(tag, parent)
- @tag, @parent = tag, parent
- super("tag <#{tag}> is missing in tag <#{parent}>")
- end
- end
-
- # Some tags must only exist a specific number of times in a given RSS feed.
- # If a feed has too many occurrences of one of these tags, a TooMuchTagError
- # will be raised.
- class TooMuchTagError < InvalidRSSError
- attr_reader :tag, :parent
- def initialize(tag, parent)
- @tag, @parent = tag, parent
- super("tag <#{tag}> is too much in tag <#{parent}>")
- end
- end
-
- # Certain attributes are required on specific tags in an RSS feed. If a feed
- # is missing one of these attributes, a MissingAttributeError is raised.
- class MissingAttributeError < InvalidRSSError
- attr_reader :tag, :attribute
- def initialize(tag, attribute)
- @tag, @attribute = tag, attribute
- super("attribute <#{attribute}> is missing in tag <#{tag}>")
- end
- end
-
- # RSS does not allow for free-form tag names, so if an RSS feed contains a
- # tag that we don't know about, an UnknownTagError is raised.
- class UnknownTagError < InvalidRSSError
- attr_reader :tag, :uri
- def initialize(tag, uri)
- @tag, @uri = tag, uri
- super("tag <#{tag}> is unknown in namespace specified by uri <#{uri}>")
- end
- end
-
- # Raised when an unexpected tag is encountered.
- class NotExpectedTagError < InvalidRSSError
- attr_reader :tag, :uri, :parent
- def initialize(tag, uri, parent)
- @tag, @uri, @parent = tag, uri, parent
- super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>")
- end
- end
- # For backward compatibility :X
- NotExceptedTagError = NotExpectedTagError # :nodoc:
-
- # Attributes are in key-value form, and if there's no value provided for an
- # attribute, a NotAvailableValueError will be raised.
- class NotAvailableValueError < InvalidRSSError
- attr_reader :tag, :value, :attribute
- def initialize(tag, value, attribute=nil)
- @tag, @value, @attribute = tag, value, attribute
- message = "value <#{value}> of "
- message << "attribute <#{attribute}> of " if attribute
- message << "tag <#{tag}> is not available."
- super(message)
- end
- end
-
- # Raised when an unknown conversion error occurs.
- class UnknownConversionMethodError < Error
- attr_reader :to, :from
- def initialize(to, from)
- @to = to
- @from = from
- super("can't convert to #{to} from #{from}.")
- end
- end
- # for backward compatibility
- UnknownConvertMethod = UnknownConversionMethodError # :nodoc:
-
- # Raised when a conversion failure occurs.
- class ConversionError < Error
- attr_reader :string, :to, :from
- def initialize(string, to, from)
- @string = string
- @to = to
- @from = from
- super("can't convert #{@string} to #{to} from #{from}.")
- end
- end
-
- # Raised when a required variable is not set.
- class NotSetError < Error
- attr_reader :name, :variables
- def initialize(name, variables)
- @name = name
- @variables = variables
- super("required variables of #{@name} are not set: #{@variables.join(', ')}")
- end
- end
-
- # Raised when a RSS::Maker attempts to use an unknown maker.
- class UnsupportedMakerVersionError < Error
- attr_reader :version
- def initialize(version)
- @version = version
- super("Maker doesn't support version: #{@version}")
- end
- end
-
- module BaseModel
- include Utils
-
- def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil)
- name ||= tag_name
- add_need_initialize_variable(name)
- install_model(tag_name, uri, occurs, name)
-
- writer_type, reader_type = type
- def_corresponded_attr_writer name, writer_type
- def_corresponded_attr_reader name, reader_type
- install_element(name) do |n, elem_name|
- <<-EOC
- if @#{n}
- "\#{@#{n}.to_s(need_convert, indent)}"
- else
- ''
- end
-EOC
- end
- end
- alias_method(:install_have_attribute_element, :install_have_child_element)
-
- def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil)
- name ||= tag_name
- plural_name ||= "#{name}s"
- add_have_children_element(name, plural_name)
- add_plural_form(name, plural_name)
- install_model(tag_name, uri, occurs, plural_name, true)
-
- def_children_accessor(name, plural_name)
- install_element(name, "s") do |n, elem_name|
- <<-EOC
- rv = []
- @#{n}.each do |x|
- value = "\#{x.to_s(need_convert, indent)}"
- rv << value if /\\A\\s*\\z/ !~ value
- end
- rv.join("\n")
-EOC
- end
- end
-
- def install_text_element(tag_name, uri, occurs, name=nil, type=nil,
- disp_name=nil)
- name ||= tag_name
- disp_name ||= name
- self::ELEMENTS << name unless self::ELEMENTS.include?(name)
- add_need_initialize_variable(name)
- install_model(tag_name, uri, occurs, name)
-
- def_corresponded_attr_writer(name, type, disp_name)
- def_corresponded_attr_reader(name, type || :convert)
- install_element(name) do |n, elem_name|
- <<-EOC
- if respond_to?(:#{n}_content)
- content = #{n}_content
- else
- content = @#{n}
- end
- if content
- rv = "\#{indent}<#{elem_name}>"
- value = html_escape(content)
- if need_convert
- rv << convert(value)
- else
- rv << value
- end
- rv << "</#{elem_name}>"
- rv
- else
- ''
- end
-EOC
- end
- end
-
- def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
- name ||= tag_name
- type ||= :w3cdtf
- disp_name ||= name
- self::ELEMENTS << name
- add_need_initialize_variable(name)
- install_model(tag_name, uri, occurs, name)
-
- # accessor
- convert_attr_reader name
- date_writer(name, type, disp_name)
-
- install_element(name) do |n, elem_name|
- <<-EOC
- if @#{n}
- rv = "\#{indent}<#{elem_name}>"
- value = html_escape(@#{n}.#{type})
- if need_convert
- rv << convert(value)
- else
- rv << value
- end
- rv << "</#{elem_name}>"
- rv
- else
- ''
- end
-EOC
- end
-
- end
-
- private
- def install_element(name, postfix="")
- elem_name = name.sub('_', ':')
- method_name = "#{name}_element#{postfix}"
- add_to_element_method(method_name)
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{method_name}(need_convert=true, indent='')
- #{yield(name, elem_name)}
- end
- private :#{method_name}
-EOC
- end
-
- def inherit_convert_attr_reader(*attrs)
- attrs.each do |attr|
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{attr}_without_inherit
- convert(@#{attr})
- end
-
- def #{attr}
- if @#{attr}
- #{attr}_without_inherit
- elsif @parent
- @parent.#{attr}
- else
- nil
- end
- end
-EOC
- end
- end
-
- def uri_convert_attr_reader(*attrs)
- attrs.each do |attr|
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{attr}_without_base
- convert(@#{attr})
- end
-
- def #{attr}
- value = #{attr}_without_base
- return nil if value.nil?
- if /\\A[a-z][a-z0-9+.\\-]*:/i =~ value
- value
- else
- "\#{base}\#{value}"
- end
- end
-EOC
- end
- end
-
- def convert_attr_reader(*attrs)
- attrs.each do |attr|
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{attr}
- convert(@#{attr})
- end
-EOC
- end
- end
-
- def yes_clean_other_attr_reader(*attrs)
- attrs.each do |attr|
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- attr_reader(:#{attr})
- def #{attr}?
- YesCleanOther.parse(@#{attr})
- end
- EOC
- end
- end
-
- def yes_other_attr_reader(*attrs)
- attrs.each do |attr|
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- attr_reader(:#{attr})
- def #{attr}?
- Utils::YesOther.parse(@#{attr})
- end
- EOC
- end
- end
-
- def csv_attr_reader(*attrs)
- separator = nil
- if attrs.last.is_a?(Hash)
- options = attrs.pop
- separator = options[:separator]
- end
- separator ||= ", "
- attrs.each do |attr|
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- attr_reader(:#{attr})
- def #{attr}_content
- if @#{attr}.nil?
- @#{attr}
- else
- @#{attr}.join(#{separator.dump})
- end
- end
- EOC
- end
- end
-
- def date_writer(name, type, disp_name=name)
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{name}=(new_value)
- if new_value.nil?
- @#{name} = new_value
- elsif new_value.kind_of?(Time)
- @#{name} = new_value.dup
- else
- if @do_validate
- begin
- @#{name} = Time.__send__('#{type}', new_value)
- rescue ArgumentError
- raise NotAvailableValueError.new('#{disp_name}', new_value)
- end
- else
- @#{name} = nil
- if /\\A\\s*\\z/ !~ new_value.to_s
- begin
- unless Date._parse(new_value, false).empty?
- @#{name} = Time.parse(new_value)
- end
- rescue ArgumentError
- end
- end
- end
- end
-
- # Is it need?
- if @#{name}
- class << @#{name}
- undef_method(:to_s)
- alias_method(:to_s, :#{type})
- end
- end
-
- end
-EOC
- end
-
- def integer_writer(name, disp_name=name)
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{name}=(new_value)
- if new_value.nil?
- @#{name} = new_value
- else
- if @do_validate
- begin
- @#{name} = Integer(new_value)
- rescue ArgumentError
- raise NotAvailableValueError.new('#{disp_name}', new_value)
- end
- else
- @#{name} = new_value.to_i
- end
- end
- end
-EOC
- end
-
- def positive_integer_writer(name, disp_name=name)
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{name}=(new_value)
- if new_value.nil?
- @#{name} = new_value
- else
- if @do_validate
- begin
- tmp = Integer(new_value)
- raise ArgumentError if tmp <= 0
- @#{name} = tmp
- rescue ArgumentError
- raise NotAvailableValueError.new('#{disp_name}', new_value)
- end
- else
- @#{name} = new_value.to_i
- end
- end
- end
-EOC
- end
-
- def boolean_writer(name, disp_name=name)
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{name}=(new_value)
- if new_value.nil?
- @#{name} = new_value
- else
- if @do_validate and
- ![true, false, "true", "false"].include?(new_value)
- raise NotAvailableValueError.new('#{disp_name}', new_value)
- end
- if [true, false].include?(new_value)
- @#{name} = new_value
- else
- @#{name} = new_value == "true"
- end
- end
- end
-EOC
- end
-
- def text_type_writer(name, disp_name=name)
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{name}=(new_value)
- if @do_validate and
- !["text", "html", "xhtml", nil].include?(new_value)
- raise NotAvailableValueError.new('#{disp_name}', new_value)
- end
- @#{name} = new_value
- end
-EOC
- end
-
- def content_writer(name, disp_name=name)
- klass_name = "self.class::#{Utils.to_class_name(name)}"
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{name}=(new_value)
- if new_value.is_a?(#{klass_name})
- @#{name} = new_value
- else
- @#{name} = #{klass_name}.new
- @#{name}.content = new_value
- end
- end
-EOC
- end
-
- def yes_clean_other_writer(name, disp_name=name)
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{name}=(value)
- value = (value ? "yes" : "no") if [true, false].include?(value)
- @#{name} = value
- end
- EOC
- end
-
- def yes_other_writer(name, disp_name=name)
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{name}=(new_value)
- if [true, false].include?(new_value)
- new_value = new_value ? "yes" : "no"
- end
- @#{name} = new_value
- end
- EOC
- end
-
- def csv_writer(name, disp_name=name)
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{name}=(new_value)
- @#{name} = Utils::CSV.parse(new_value)
- end
- EOC
- end
-
- def csv_integer_writer(name, disp_name=name)
- module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- def #{name}=(new_value)
- @#{name} = Utils::CSV.parse(new_value) {|v| Integer(v)}
- end
- EOC
- end
-
- def def_children_accessor(accessor_name, plural_name)
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{plural_name}
- @#{accessor_name}
- end
-
- def #{accessor_name}(*args)
- if args.empty?
- @#{accessor_name}.first
- else
- @#{accessor_name}[*args]
- end
- end
-
- def #{accessor_name}=(*args)
- receiver = self.class.name
- warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \
- "Don't use `\#{receiver}\##{accessor_name} = XXX'/" \
- "`\#{receiver}\#set_#{accessor_name}(XXX)'. " \
- "Those APIs are not sense of Ruby. " \
- "Use `\#{receiver}\##{plural_name} << XXX' instead of them.")
- if args.size == 1
- @#{accessor_name}.push(args[0])
- else
- @#{accessor_name}.__send__("[]=", *args)
- end
- end
- alias_method(:set_#{accessor_name}, :#{accessor_name}=)
-EOC
- end
- end
-
- module SetupMaker
- def setup_maker(maker)
- target = maker_target(maker)
- unless target.nil?
- setup_maker_attributes(target)
- setup_maker_element(target)
- setup_maker_elements(target)
- end
- end
-
- private
- def maker_target(maker)
- nil
- end
-
- def setup_maker_attributes(target)
- end
-
- def setup_maker_element(target)
- self.class.need_initialize_variables.each do |var|
- value = __send__(var)
- next if value.nil?
- if value.respond_to?("setup_maker") and
- !not_need_to_call_setup_maker_variables.include?(var)
- value.setup_maker(target)
- else
- setter = "#{var}="
- if target.respond_to?(setter)
- target.__send__(setter, value)
- end
- end
- end
- end
-
- def not_need_to_call_setup_maker_variables
- []
- end
-
- def setup_maker_elements(parent)
- self.class.have_children_elements.each do |name, plural_name|
- if parent.respond_to?(plural_name)
- target = parent.__send__(plural_name)
- __send__(plural_name).each do |elem|
- elem.setup_maker(target)
- end
- end
- end
- end
- end
-
- class Element
- extend BaseModel
- include Utils
- extend Utils::InheritedReader
- include SetupMaker
-
- INDENT = " "
-
- MUST_CALL_VALIDATORS = {}
- MODELS = []
- GET_ATTRIBUTES = []
- HAVE_CHILDREN_ELEMENTS = []
- TO_ELEMENT_METHODS = []
- NEED_INITIALIZE_VARIABLES = []
- PLURAL_FORMS = {}
-
- class << self
- def must_call_validators
- inherited_hash_reader("MUST_CALL_VALIDATORS")
- end
- def models
- inherited_array_reader("MODELS")
- end
- def get_attributes
- inherited_array_reader("GET_ATTRIBUTES")
- end
- def have_children_elements
- inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
- end
- def to_element_methods
- inherited_array_reader("TO_ELEMENT_METHODS")
- end
- def need_initialize_variables
- inherited_array_reader("NEED_INITIALIZE_VARIABLES")
- end
- def plural_forms
- inherited_hash_reader("PLURAL_FORMS")
- end
-
- def inherited_base
- ::RSS::Element
- end
-
- def inherited(klass)
- klass.const_set(:MUST_CALL_VALIDATORS, {})
- klass.const_set(:MODELS, [])
- klass.const_set(:GET_ATTRIBUTES, [])
- klass.const_set(:HAVE_CHILDREN_ELEMENTS, [])
- klass.const_set(:TO_ELEMENT_METHODS, [])
- klass.const_set(:NEED_INITIALIZE_VARIABLES, [])
- klass.const_set(:PLURAL_FORMS, {})
-
- tag_name = klass.name.split(/::/).last
- tag_name[0, 1] = tag_name[0, 1].downcase
- klass.instance_variable_set(:@tag_name, tag_name)
- klass.instance_variable_set(:@have_content, false)
- end
-
- def install_must_call_validator(prefix, uri)
- self::MUST_CALL_VALIDATORS[uri] = prefix
- end
-
- def install_model(tag, uri, occurs=nil, getter=nil, plural=false)
- getter ||= tag
- if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri}
- m[2] = occurs
- else
- self::MODELS << [tag, uri, occurs, getter, plural]
- end
- end
-
- def install_get_attribute(name, uri, required=true,
- type=nil, disp_name=nil,
- element_name=nil)
- disp_name ||= name
- element_name ||= name
- writer_type, reader_type = type
- def_corresponded_attr_writer name, writer_type, disp_name
- def_corresponded_attr_reader name, reader_type
- if type == :boolean and /^is/ =~ name
- alias_method "#{$POSTMATCH}?", name
- end
- self::GET_ATTRIBUTES << [name, uri, required, element_name]
- add_need_initialize_variable(disp_name)
- end
-
- def def_corresponded_attr_writer(name, type=nil, disp_name=nil)
- disp_name ||= name
- case type
- when :integer
- integer_writer name, disp_name
- when :positive_integer
- positive_integer_writer name, disp_name
- when :boolean
- boolean_writer name, disp_name
- when :w3cdtf, :rfc822, :rfc2822
- date_writer name, type, disp_name
- when :text_type
- text_type_writer name, disp_name
- when :content
- content_writer name, disp_name
- when :yes_clean_other
- yes_clean_other_writer name, disp_name
- when :yes_other
- yes_other_writer name, disp_name
- when :csv
- csv_writer name
- when :csv_integer
- csv_integer_writer name
- else
- attr_writer name
- end
- end
-
- def def_corresponded_attr_reader(name, type=nil)
- case type
- when :inherit
- inherit_convert_attr_reader name
- when :uri
- uri_convert_attr_reader name
- when :yes_clean_other
- yes_clean_other_attr_reader name
- when :yes_other
- yes_other_attr_reader name
- when :csv
- csv_attr_reader name
- when :csv_integer
- csv_attr_reader name, :separator => ","
- else
- convert_attr_reader name
- end
- end
-
- def content_setup(type=nil, disp_name=nil)
- writer_type, reader_type = type
- def_corresponded_attr_writer :content, writer_type, disp_name
- def_corresponded_attr_reader :content, reader_type
- @have_content = true
- end
-
- def have_content?
- @have_content
- end
-
- def add_have_children_element(variable_name, plural_name)
- self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
- end
-
- def add_to_element_method(method_name)
- self::TO_ELEMENT_METHODS << method_name
- end
-
- def add_need_initialize_variable(variable_name)
- self::NEED_INITIALIZE_VARIABLES << variable_name
- end
-
- def add_plural_form(singular, plural)
- self::PLURAL_FORMS[singular] = plural
- end
-
- def required_prefix
- nil
- end
-
- def required_uri
- ""
- end
-
- def need_parent?
- false
- end
-
- def install_ns(prefix, uri)
- if self::NSPOOL.has_key?(prefix)
- raise OverlappedPrefixError.new(prefix)
- end
- self::NSPOOL[prefix] = uri
- end
-
- def tag_name
- @tag_name
- end
- end
-
- attr_accessor :parent, :do_validate
-
- def initialize(do_validate=true, attrs=nil)
- @parent = nil
- @converter = nil
- if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array))
- do_validate, attrs = true, do_validate
- end
- @do_validate = do_validate
- initialize_variables(attrs || {})
- end
-
- def tag_name
- self.class.tag_name
- end
-
- def full_name
- tag_name
- end
-
- def converter=(converter)
- @converter = converter
- targets = children.dup
- self.class.have_children_elements.each do |variable_name, plural_name|
- targets.concat(__send__(plural_name))
- end
- targets.each do |target|
- target.converter = converter unless target.nil?
- end
- end
-
- def convert(value)
- if @converter
- @converter.convert(value)
- else
- value
- end
- end
-
- def valid?(ignore_unknown_element=true)
- validate(ignore_unknown_element)
- true
- rescue RSS::Error
- false
- end
-
- def validate(ignore_unknown_element=true)
- do_validate = @do_validate
- @do_validate = true
- validate_attribute
- __validate(ignore_unknown_element)
- ensure
- @do_validate = do_validate
- end
-
- def validate_for_stream(tags, ignore_unknown_element=true)
- validate_attribute
- __validate(ignore_unknown_element, tags, false)
- end
-
- def to_s(need_convert=true, indent='')
- if self.class.have_content?
- return "" if !empty_content? and !content_is_set?
- rv = tag(indent) do |next_indent|
- if empty_content?
- ""
- else
- xmled_content
- end
- end
- else
- rv = tag(indent) do |next_indent|
- self.class.to_element_methods.collect do |method_name|
- __send__(method_name, false, next_indent)
- end
- end
- end
- rv = convert(rv) if need_convert
- rv
- end
-
- def have_xml_content?
- false
- end
-
- def need_base64_encode?
- false
- end
-
- def set_next_element(tag_name, next_element)
- klass = next_element.class
- prefix = ""
- prefix << "#{klass.required_prefix}_" if klass.required_prefix
- key = "#{prefix}#{tag_name.gsub(/-/, '_')}"
- if self.class.plural_forms.has_key?(key)
- ary = __send__("#{self.class.plural_forms[key]}")
- ary << next_element
- else
- __send__("#{key}=", next_element)
- end
- end
-
- protected
- def have_required_elements?
- self.class::MODELS.all? do |tag, uri, occurs, getter|
- if occurs.nil? or occurs == "+"
- child = __send__(getter)
- if child.is_a?(Array)
- children = child
- children.any? {|c| c.have_required_elements?}
- else
- not child.nil?
- end
- else
- true
- end
- end
- end
-
- private
- def initialize_variables(attrs)
- normalized_attrs = {}
- attrs.each do |key, value|
- normalized_attrs[key.to_s] = value
- end
- self.class.need_initialize_variables.each do |variable_name|
- value = normalized_attrs[variable_name.to_s]
- if value
- __send__("#{variable_name}=", value)
- else
- instance_variable_set("@#{variable_name}", nil)
- end
- end
- initialize_have_children_elements
- @content = normalized_attrs["content"] if self.class.have_content?
- end
-
- def initialize_have_children_elements
- self.class.have_children_elements.each do |variable_name, plural_name|
- instance_variable_set("@#{variable_name}", [])
- end
- end
-
- def tag(indent, additional_attrs={}, &block)
- next_indent = indent + INDENT
-
- attrs = collect_attrs
- return "" if attrs.nil?
-
- return "" unless have_required_elements?
-
- attrs.update(additional_attrs)
- start_tag = make_start_tag(indent, next_indent, attrs.dup)
-
- if block
- content = block.call(next_indent)
- else
- content = []
- end
-
- if content.is_a?(String)
- content = [content]
- start_tag << ">"
- end_tag = "</#{full_name}>"
- else
- content = content.reject{|x| x.empty?}
- if content.empty?
- return "" if attrs.empty?
- end_tag = "/>"
- else
- start_tag << ">\n"
- end_tag = "\n#{indent}</#{full_name}>"
- end
- end
-
- start_tag + content.join("\n") + end_tag
- end
-
- def make_start_tag(indent, next_indent, attrs)
- start_tag = ["#{indent}<#{full_name}"]
- unless attrs.empty?
- start_tag << attrs.collect do |key, value|
- %Q[#{h key}="#{h value}"]
- end.join("\n#{next_indent}")
- end
- start_tag.join(" ")
- end
-
- def collect_attrs
- attrs = {}
- _attrs.each do |name, required, alias_name|
- value = __send__(alias_name || name)
- return nil if required and value.nil?
- next if value.nil?
- return nil if attrs.has_key?(name)
- attrs[name] = value
- end
- attrs
- end
-
- def tag_name_with_prefix(prefix)
- "#{prefix}:#{tag_name}"
- end
-
- # For backward compatibility
- def calc_indent
- ''
- end
-
- def children
- rv = []
- self.class.models.each do |name, uri, occurs, getter|
- value = __send__(getter)
- next if value.nil?
- value = [value] unless value.is_a?(Array)
- value.each do |v|
- rv << v if v.is_a?(Element)
- end
- end
- rv
- end
-
- def _tags
- rv = []
- self.class.models.each do |name, uri, occurs, getter, plural|
- value = __send__(getter)
- next if value.nil?
- if plural and value.is_a?(Array)
- rv.concat([[uri, name]] * value.size)
- else
- rv << [uri, name]
- end
- end
- rv
- end
-
- def _attrs
- self.class.get_attributes.collect do |name, uri, required, element_name|
- [element_name, required, name]
- end
- end
-
- def __validate(ignore_unknown_element, tags=_tags, recursive=true)
- if recursive
- children.compact.each do |child|
- child.validate
- end
- end
- must_call_validators = self.class.must_call_validators
- tags = tag_filter(tags.dup)
- p tags if DEBUG
- must_call_validators.each do |uri, prefix|
- _validate(ignore_unknown_element, tags[uri], uri)
- meth = "#{prefix}_validate"
- if !prefix.empty? and respond_to?(meth, true)
- __send__(meth, ignore_unknown_element, tags[uri], uri)
- end
- end
- end
-
- def validate_attribute
- _attrs.each do |a_name, required, alias_name|
- value = instance_variable_get("@#{alias_name || a_name}")
- if required and value.nil?
- raise MissingAttributeError.new(tag_name, a_name)
- end
- __send__("#{alias_name || a_name}=", value)
- end
- end
-
- def _validate(ignore_unknown_element, tags, uri, models=self.class.models)
- count = 1
- do_redo = false
- not_shift = false
- tag = nil
- models = models.find_all {|model| model[1] == uri}
- element_names = models.collect {|model| model[0]}
- if tags
- tags_size = tags.size
- tags = tags.sort_by {|x| element_names.index(x) || tags_size}
- end
-
- models.each_with_index do |model, i|
- name, _, occurs, = model
-
- if DEBUG
- p "before"
- p tags
- p model
- end
-
- if not_shift
- not_shift = false
- elsif tags
- tag = tags.shift
- end
-
- if DEBUG
- p "mid"
- p count
- end
-
- case occurs
- when '?'
- if count > 2
- raise TooMuchTagError.new(name, tag_name)
- else
- if name == tag
- do_redo = true
- else
- not_shift = true
- end
- end
- when '*'
- if name == tag
- do_redo = true
- else
- not_shift = true
- end
- when '+'
- if name == tag
- do_redo = true
- else
- if count > 1
- not_shift = true
- else
- raise MissingTagError.new(name, tag_name)
- end
- end
- else
- if name == tag
- if models[i+1] and models[i+1][0] != name and
- tags and tags.first == name
- raise TooMuchTagError.new(name, tag_name)
- end
- else
- raise MissingTagError.new(name, tag_name)
- end
- end
-
- if DEBUG
- p "after"
- p not_shift
- p do_redo
- p tag
- end
-
- if do_redo
- do_redo = false
- count += 1
- redo
- else
- count = 1
- end
-
- end
-
- if !ignore_unknown_element and !tags.nil? and !tags.empty?
- raise NotExpectedTagError.new(tags.first, uri, tag_name)
- end
-
- end
-
- def tag_filter(tags)
- rv = {}
- tags.each do |tag|
- rv[tag[0]] = [] unless rv.has_key?(tag[0])
- rv[tag[0]].push(tag[1])
- end
- rv
- end
-
- def empty_content?
- false
- end
-
- def content_is_set?
- if have_xml_content?
- __send__(self.class.xml_getter)
- else
- content
- end
- end
-
- def xmled_content
- if have_xml_content?
- __send__(self.class.xml_getter).to_s
- else
- _content = content
- _content = [_content].pack("m0") if need_base64_encode?
- h(_content)
- end
- end
- end
-
- module RootElementMixin
-
- include XMLStyleSheetMixin
-
- attr_reader :output_encoding
- attr_reader :feed_type, :feed_subtype, :feed_version
- attr_accessor :version, :encoding, :standalone
- def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
- super()
- @feed_type = nil
- @feed_subtype = nil
- @feed_version = feed_version
- @version = version || '1.0'
- @encoding = encoding
- @standalone = standalone
- @output_encoding = nil
- end
-
- def feed_info
- [@feed_type, @feed_version, @feed_subtype]
- end
-
- def output_encoding=(enc)
- @output_encoding = enc
- self.converter = Converter.new(@output_encoding, @encoding)
- end
-
- def setup_maker(maker)
- maker.version = version
- maker.encoding = encoding
- maker.standalone = standalone
-
- xml_stylesheets.each do |xss|
- xss.setup_maker(maker)
- end
-
- super
- end
-
- def to_feed(type, &block)
- Maker.make(type) do |maker|
- setup_maker(maker)
- block.call(maker) if block
- end
- end
-
- def to_rss(type, &block)
- to_feed("rss#{type}", &block)
- end
-
- def to_atom(type, &block)
- to_feed("atom:#{type}", &block)
- end
-
- def to_xml(type=nil, &block)
- if type.nil? or same_feed_type?(type)
- to_s
- else
- to_feed(type, &block).to_s
- end
- end
-
- private
- def same_feed_type?(type)
- if /^(atom|rss)?(\d+\.\d+)?(?::(.+))?$/i =~ type
- feed_type = ($1 || @feed_type).downcase
- feed_version = $2 || @feed_version
- feed_subtype = $3 || @feed_subtype
- [feed_type, feed_version, feed_subtype] == feed_info
- else
- false
- end
- end
-
- def tag(indent, attrs={}, &block)
- rv = super(indent, ns_declarations.merge(attrs), &block)
- return rv if rv.empty?
- "#{xmldecl}#{xml_stylesheet_pi}#{rv}"
- end
-
- def xmldecl
- rv = %Q[<?xml version="#{@version}"]
- if @output_encoding or @encoding
- rv << %Q[ encoding="#{@output_encoding or @encoding}"]
- end
- rv << %Q[ standalone="yes"] if @standalone
- rv << "?>\n"
- rv
- end
-
- def ns_declarations
- decls = {}
- self.class::NSPOOL.collect do |prefix, uri|
- prefix = ":#{prefix}" unless prefix.empty?
- decls["xmlns#{prefix}"] = uri
- end
- decls
- end
-
- def maker_target(target)
- target
- end
- end
-end
diff --git a/lib/rss/slash.rb b/lib/rss/slash.rb
deleted file mode 100644
index 0055fc9f88..0000000000
--- a/lib/rss/slash.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: false
-require 'rss/1.0'
-
-module RSS
- # The prefix for the Slash XML namespace.
- SLASH_PREFIX = 'slash'
- # The URI of the Slash specification.
- SLASH_URI = "http://purl.org/rss/1.0/modules/slash/"
-
- RDF.install_ns(SLASH_PREFIX, SLASH_URI)
-
- module SlashModel
- extend BaseModel
-
- ELEMENT_INFOS = \
- [
- ["section"],
- ["department"],
- ["comments", :positive_integer],
- ["hit_parade", :csv_integer],
- ]
-
- class << self
- def append_features(klass)
- super
-
- return if klass.instance_of?(Module)
- klass.install_must_call_validator(SLASH_PREFIX, SLASH_URI)
- ELEMENT_INFOS.each do |name, type, *additional_infos|
- full_name = "#{SLASH_PREFIX}_#{name}"
- klass.install_text_element(full_name, SLASH_URI, "?",
- full_name, type, name)
- end
-
- klass.module_eval do
- alias_method(:slash_hit_parades, :slash_hit_parade)
- undef_method(:slash_hit_parade)
- alias_method(:slash_hit_parade, :slash_hit_parade_content)
- end
- end
- end
- end
-
- class RDF
- class Item; include SlashModel; end
- end
-
- SlashModel::ELEMENT_INFOS.each do |name, type|
- accessor_base = "#{SLASH_PREFIX}_#{name}"
- BaseListener.install_get_text_element(SLASH_URI, name, accessor_base)
- end
-end
diff --git a/lib/rss/syndication.rb b/lib/rss/syndication.rb
deleted file mode 100644
index 8f9620f9f3..0000000000
--- a/lib/rss/syndication.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: false
-require "rss/1.0"
-
-module RSS
- # The prefix for the Syndication XML namespace.
- SY_PREFIX = 'sy'
- # The URI of the Syndication specification.
- SY_URI = "http://purl.org/rss/1.0/modules/syndication/"
-
- RDF.install_ns(SY_PREFIX, SY_URI)
-
- module SyndicationModel
-
- extend BaseModel
-
- ELEMENTS = []
-
- def self.append_features(klass)
- super
-
- klass.install_must_call_validator(SY_PREFIX, SY_URI)
- klass.module_eval do
- [
- ["updatePeriod"],
- ["updateFrequency", :positive_integer]
- ].each do |name, type|
- install_text_element(name, SY_URI, "?",
- "#{SY_PREFIX}_#{name}", type,
- "#{SY_PREFIX}:#{name}")
- end
-
- %w(updateBase).each do |name|
- install_date_element(name, SY_URI, "?",
- "#{SY_PREFIX}_#{name}", 'w3cdtf',
- "#{SY_PREFIX}:#{name}")
- end
- end
-
- klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
- alias_method(:_sy_updatePeriod=, :sy_updatePeriod=)
- def sy_updatePeriod=(new_value)
- new_value = new_value.strip
- validate_sy_updatePeriod(new_value) if @do_validate
- self._sy_updatePeriod = new_value
- end
- EOC
- end
-
- private
- SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly)
- def validate_sy_updatePeriod(value) # :nodoc:
- unless SY_UPDATEPERIOD_AVAILABLE_VALUES.include?(value)
- raise NotAvailableValueError.new("updatePeriod", value)
- end
- end
- end
-
- class RDF
- class Channel; include SyndicationModel; end
- end
-
- prefix_size = SY_PREFIX.size + 1
- SyndicationModel::ELEMENTS.uniq!
- SyndicationModel::ELEMENTS.each do |full_name|
- name = full_name[prefix_size..-1]
- BaseListener.install_get_text_element(SY_URI, name, full_name)
- end
-
-end
diff --git a/lib/rss/taxonomy.rb b/lib/rss/taxonomy.rb
deleted file mode 100644
index b7ea219e8c..0000000000
--- a/lib/rss/taxonomy.rb
+++ /dev/null
@@ -1,148 +0,0 @@
-# frozen_string_literal: false
-require "rss/1.0"
-require "rss/dublincore"
-
-module RSS
- # The prefix for the Taxonomy XML namespace.
- TAXO_PREFIX = "taxo"
- # The URI for the specification of the Taxonomy XML namespace.
- TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/"
-
- RDF.install_ns(TAXO_PREFIX, TAXO_URI)
-
- # The listing of all the taxonomy elements, with the appropriate namespace.
- TAXO_ELEMENTS = []
-
- %w(link).each do |name|
- full_name = "#{TAXO_PREFIX}_#{name}"
- BaseListener.install_get_text_element(TAXO_URI, name, full_name)
- TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
- end
-
- %w(topic topics).each do |name|
- class_name = Utils.to_class_name(name)
- BaseListener.install_class_name(TAXO_URI, name, "Taxonomy#{class_name}")
- TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
- end
-
- module TaxonomyTopicsModel
- extend BaseModel
-
- def self.append_features(klass)
- super
-
- klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI)
- %w(topics).each do |name|
- klass.install_have_child_element(name, TAXO_URI, "?",
- "#{TAXO_PREFIX}_#{name}")
- end
- end
-
- class TaxonomyTopics < Element
- include RSS10
-
- Bag = ::RSS::RDF::Bag
-
- class << self
- def required_prefix
- TAXO_PREFIX
- end
-
- def required_uri
- TAXO_URI
- end
- end
-
- @tag_name = "topics"
-
- install_have_child_element("Bag", RDF::URI, nil)
- install_must_call_validator('rdf', RDF::URI)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.Bag = args[0]
- end
- self.Bag ||= Bag.new
- end
-
- def full_name
- tag_name_with_prefix(TAXO_PREFIX)
- end
-
- def maker_target(target)
- target.taxo_topics
- end
-
- def resources
- if @Bag
- @Bag.lis.collect do |li|
- li.resource
- end
- else
- []
- end
- end
- end
- end
-
- module TaxonomyTopicModel
- extend BaseModel
-
- def self.append_features(klass)
- super
- var_name = "#{TAXO_PREFIX}_topic"
- klass.install_have_children_element("topic", TAXO_URI, "*", var_name)
- end
-
- class TaxonomyTopic < Element
- include RSS10
-
- include DublinCoreModel
- include TaxonomyTopicsModel
-
- class << self
- def required_prefix
- TAXO_PREFIX
- end
-
- def required_uri
- TAXO_URI
- end
- end
-
- @tag_name = "topic"
-
- install_get_attribute("about", ::RSS::RDF::URI, true, nil, nil,
- "#{RDF::PREFIX}:about")
- install_text_element("link", TAXO_URI, "?", "#{TAXO_PREFIX}_link")
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.about = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(TAXO_PREFIX)
- end
-
- def maker_target(target)
- target.new_taxo_topic
- end
- end
- end
-
- class RDF
- include TaxonomyTopicModel
- class Channel
- include TaxonomyTopicsModel
- end
- class Item; include TaxonomyTopicsModel; end
- end
-end
diff --git a/lib/rss/trackback.rb b/lib/rss/trackback.rb
deleted file mode 100644
index 1a3c3849b5..0000000000
--- a/lib/rss/trackback.rb
+++ /dev/null
@@ -1,291 +0,0 @@
-# frozen_string_literal: false
-# This file contains the implementation of trackbacks. It is entirely internal
-# and not useful to outside developers.
-require 'rss/1.0'
-require 'rss/2.0'
-
-module RSS # :nodoc: all
-
- TRACKBACK_PREFIX = 'trackback'
- TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/'
-
- RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)
- Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)
-
- module TrackBackUtils
- private
- def trackback_validate(ignore_unknown_element, tags, uri)
- return if tags.nil?
- if tags.find {|tag| tag == "about"} and
- !tags.find {|tag| tag == "ping"}
- raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name)
- end
- end
- end
-
- module BaseTrackBackModel
-
- ELEMENTS = %w(ping about)
-
- def append_features(klass)
- super
-
- unless klass.class == Module
- klass.module_eval {include TrackBackUtils}
-
- klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI)
- %w(ping).each do |name|
- var_name = "#{TRACKBACK_PREFIX}_#{name}"
- klass_name = "TrackBack#{Utils.to_class_name(name)}"
- klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__)
- remove_method :#{var_name}
- def #{var_name}
- @#{var_name} and @#{var_name}.value
- end
-
- remove_method :#{var_name}=
- def #{var_name}=(value)
- @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value)
- end
- EOC
- end
-
- [%w(about s)].each do |name, postfix|
- var_name = "#{TRACKBACK_PREFIX}_#{name}"
- klass_name = "TrackBack#{Utils.to_class_name(name)}"
- klass.install_have_children_element(name, TRACKBACK_URI, "*",
- var_name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__)
- remove_method :#{var_name}
- def #{var_name}(*args)
- if args.empty?
- @#{var_name}.first and @#{var_name}.first.value
- else
- ret = @#{var_name}.__send__("[]", *args)
- if ret.is_a?(Array)
- ret.collect {|x| x.value}
- else
- ret.value
- end
- end
- end
-
- remove_method :#{var_name}=
- remove_method :set_#{var_name}
- def #{var_name}=(*args)
- if args.size == 1
- item = Utils.new_with_value_if_need(#{klass_name}, args[0])
- @#{var_name}.push(item)
- else
- new_val = args.last
- if new_val.is_a?(Array)
- new_val = new_value.collect do |val|
- Utils.new_with_value_if_need(#{klass_name}, val)
- end
- else
- new_val = Utils.new_with_value_if_need(#{klass_name}, new_val)
- end
- @#{var_name}.__send__("[]=", *(args[0..-2] + [new_val]))
- end
- end
- alias set_#{var_name} #{var_name}=
- EOC
- end
- end
- end
- end
-
- module TrackBackModel10
- extend BaseModel
- extend BaseTrackBackModel
-
- class TrackBackPing < Element
- include RSS10
-
- class << self
-
- def required_prefix
- TRACKBACK_PREFIX
- end
-
- def required_uri
- TRACKBACK_URI
- end
-
- end
-
- @tag_name = "ping"
-
- [
- ["resource", ::RSS::RDF::URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{::RSS::RDF::PREFIX}:#{name}")
- end
-
- alias_method(:value, :resource)
- alias_method(:value=, :resource=)
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.resource = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(TRACKBACK_PREFIX)
- end
- end
-
- class TrackBackAbout < Element
- include RSS10
-
- class << self
-
- def required_prefix
- TRACKBACK_PREFIX
- end
-
- def required_uri
- TRACKBACK_URI
- end
-
- end
-
- @tag_name = "about"
-
- [
- ["resource", ::RSS::RDF::URI, true]
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required, nil, nil,
- "#{::RSS::RDF::PREFIX}:#{name}")
- end
-
- alias_method(:value, :resource)
- alias_method(:value=, :resource=)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.resource = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(TRACKBACK_PREFIX)
- end
-
- private
- def maker_target(abouts)
- abouts.new_about
- end
-
- def setup_maker_attributes(about)
- about.resource = self.resource
- end
-
- end
- end
-
- module TrackBackModel20
- extend BaseModel
- extend BaseTrackBackModel
-
- class TrackBackPing < Element
- include RSS09
-
- @tag_name = "ping"
-
- content_setup
-
- class << self
-
- def required_prefix
- TRACKBACK_PREFIX
- end
-
- def required_uri
- TRACKBACK_URI
- end
-
- end
-
- alias_method(:value, :content)
- alias_method(:value=, :content=)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.content = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(TRACKBACK_PREFIX)
- end
-
- end
-
- class TrackBackAbout < Element
- include RSS09
-
- @tag_name = "about"
-
- content_setup
-
- class << self
-
- def required_prefix
- TRACKBACK_PREFIX
- end
-
- def required_uri
- TRACKBACK_URI
- end
-
- end
-
- alias_method(:value, :content)
- alias_method(:value=, :content=)
-
- def initialize(*args)
- if Utils.element_initialize_arguments?(args)
- super
- else
- super()
- self.content = args[0]
- end
- end
-
- def full_name
- tag_name_with_prefix(TRACKBACK_PREFIX)
- end
-
- end
- end
-
- class RDF
- class Item; include TrackBackModel10; end
- end
-
- class Rss
- class Channel
- class Item; include TrackBackModel20; end
- end
- end
-
- BaseTrackBackModel::ELEMENTS.each do |name|
- class_name = Utils.to_class_name(name)
- BaseListener.install_class_name(TRACKBACK_URI, name,
- "TrackBack#{class_name}")
- end
-
- BaseTrackBackModel::ELEMENTS.collect! {|name| "#{TRACKBACK_PREFIX}_#{name}"}
-end
diff --git a/lib/rss/utils.rb b/lib/rss/utils.rb
deleted file mode 100644
index ce7dbf1b02..0000000000
--- a/lib/rss/utils.rb
+++ /dev/null
@@ -1,200 +0,0 @@
-# frozen_string_literal: false
-module RSS
-
- ##
- # RSS::Utils is a module that holds various utility functions that are used
- # across many parts of the rest of the RSS library. Like most modules named
- # some variant of 'util', its methods are probably not particularly useful
- # to those who aren't developing the library itself.
- module Utils
- module_function
-
- # Given a +name+ in a name_with_underscores or a name-with-dashes format,
- # returns the CamelCase version of +name+.
- #
- # If the +name+ is already CamelCased, nothing happens.
- #
- # Examples:
- #
- # require 'rss/utils'
- #
- # RSS::Utils.to_class_name("sample_name")
- # # => "SampleName"
- # RSS::Utils.to_class_name("with-dashes")
- # # => "WithDashes"
- # RSS::Utils.to_class_name("CamelCase")
- # # => "CamelCase"
- def to_class_name(name)
- name.split(/[_\-]/).collect do |part|
- "#{part[0, 1].upcase}#{part[1..-1]}"
- end.join("")
- end
-
- # Returns an array of two elements: the filename where the calling method
- # is located, and the line number where it is defined.
- #
- # Takes an optional argument +i+, which specifies how many callers up the
- # stack to look.
- #
- # Examples:
- #
- # require 'rss/utils'
- #
- # def foo
- # p RSS::Utils.get_file_and_line_from_caller
- # p RSS::Utils.get_file_and_line_from_caller(1)
- # end
- #
- # def bar
- # foo
- # end
- #
- # def baz
- # bar
- # end
- #
- # baz
- # # => ["test.rb", 5]
- # # => ["test.rb", 9]
- #
- # If +i+ is not given, or is the default value of 0, it attempts to figure
- # out the correct value. This is useful when in combination with
- # instance_eval. For example:
- #
- # require 'rss/utils'
- #
- # def foo
- # p RSS::Utils.get_file_and_line_from_caller(1)
- # end
- #
- # def bar
- # foo
- # end
- #
- # instance_eval <<-RUBY, *RSS::Utils.get_file_and_line_from_caller
- # def baz
- # bar
- # end
- # RUBY
- #
- # baz
- #
- # # => ["test.rb", 8]
- def get_file_and_line_from_caller(i=0)
- file, line, = caller[i].split(':')
- line = line.to_i
- line += 1 if i.zero?
- [file, line]
- end
-
- # Takes a string +s+ with some HTML in it, and escapes '&', '"', '<' and '>', by
- # replacing them with the appropriate entities.
- #
- # This method is also aliased to h, for convenience.
- #
- # Examples:
- #
- # require 'rss/utils'
- #
- # RSS::Utils.html_escape("Dungeons & Dragons")
- # # => "Dungeons &amp; Dragons"
- # RSS::Utils.h(">_>")
- # # => "&gt;_&gt;"
- def html_escape(s)
- s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
- end
- alias h html_escape
-
- # If +value+ is an instance of class +klass+, return it, else
- # create a new instance of +klass+ with value +value+.
- def new_with_value_if_need(klass, value)
- if value.is_a?(klass)
- value
- else
- klass.new(value)
- end
- end
-
- # This method is used inside of several different objects to determine
- # if special behavior is needed in the constructor.
- #
- # Special behavior is needed if the array passed in as +args+ has
- # +true+ or +false+ as its value, and if the second element of +args+
- # is a hash.
- def element_initialize_arguments?(args)
- [true, false].include?(args[0]) and args[1].is_a?(Hash)
- end
-
- module YesCleanOther
- module_function
- def parse(value)
- if [true, false, nil].include?(value)
- value
- else
- case value.to_s
- when /\Ayes\z/i
- true
- when /\Aclean\z/i
- false
- else
- nil
- end
- end
- end
- end
-
- module YesOther
- module_function
- def parse(value)
- if [true, false].include?(value)
- value
- else
- /\Ayes\z/i.match(value.to_s) ? true : false
- end
- end
- end
-
- module CSV
- module_function
- def parse(value, &block)
- if value.is_a?(String)
- value = value.strip.split(/\s*,\s*/)
- value = value.collect(&block) if block_given?
- value
- else
- value
- end
- end
- end
-
- module InheritedReader
- def inherited_reader(constant_name)
- base_class = inherited_base
- result = base_class.const_get(constant_name)
- found_base_class = false
- ancestors.reverse_each do |klass|
- if found_base_class
- if klass.const_defined?(constant_name)
- result = yield(result, klass.const_get(constant_name))
- end
- else
- found_base_class = klass == base_class
- end
- end
- result
- end
-
- def inherited_array_reader(constant_name)
- inherited_reader(constant_name) do |result, current|
- current + result
- end
- end
-
- def inherited_hash_reader(constant_name)
- inherited_reader(constant_name) do |result, current|
- result.merge(current)
- end
- end
- end
- end
-end
diff --git a/lib/rss/xml-stylesheet.rb b/lib/rss/xml-stylesheet.rb
deleted file mode 100644
index be9cfaaf64..0000000000
--- a/lib/rss/xml-stylesheet.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-# frozen_string_literal: false
-require "rss/utils"
-
-module RSS
-
- module XMLStyleSheetMixin
- attr_accessor :xml_stylesheets
- def initialize(*args)
- super
- @xml_stylesheets = []
- end
-
- private
- def xml_stylesheet_pi
- xsss = @xml_stylesheets.collect do |xss|
- pi = xss.to_s
- pi = nil if /\A\s*\z/ =~ pi
- pi
- end.compact
- xsss.push("") unless xsss.empty?
- xsss.join("\n")
- end
- end
-
- class XMLStyleSheet
-
- include Utils
-
- ATTRIBUTES = %w(href type title media charset alternate)
-
- GUESS_TABLE = {
- "xsl" => "text/xsl",
- "css" => "text/css",
- }
-
- attr_accessor(*ATTRIBUTES)
- attr_accessor(:do_validate)
- def initialize(*attrs)
- if attrs.size == 1 and
- (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array))
- attrs = attrs.first
- end
- @do_validate = true
- ATTRIBUTES.each do |attr|
- __send__("#{attr}=", nil)
- end
- vars = ATTRIBUTES.dup
- vars.unshift(:do_validate)
- attrs.each do |name, value|
- if vars.include?(name.to_s)
- __send__("#{name}=", value)
- end
- end
- end
-
- def to_s
- rv = ""
- if @href
- rv << %Q[<?xml-stylesheet]
- ATTRIBUTES.each do |name|
- if __send__(name)
- rv << %Q[ #{name}="#{h __send__(name)}"]
- end
- end
- rv << %Q[?>]
- end
- rv
- end
-
- remove_method(:href=)
- def href=(value)
- @href = value
- if @href and @type.nil?
- @type = guess_type(@href)
- end
- @href
- end
-
- remove_method(:alternate=)
- def alternate=(value)
- if value.nil? or /\A(?:yes|no)\z/ =~ value
- @alternate = value
- else
- if @do_validate
- args = ["?xml-stylesheet?", %Q[alternate="#{value}"]]
- raise NotAvailableValueError.new(*args)
- end
- end
- @alternate
- end
-
- def setup_maker(maker)
- xss = maker.xml_stylesheets.new_xml_stylesheet
- ATTRIBUTES.each do |attr|
- xss.__send__("#{attr}=", __send__(attr))
- end
- end
-
- private
- def guess_type(filename)
- /\.([^.]+)$/ =~ filename
- GUESS_TABLE[$1]
- end
-
- end
-end
diff --git a/lib/rss/xml.rb b/lib/rss/xml.rb
deleted file mode 100644
index cda8668044..0000000000
--- a/lib/rss/xml.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: false
-require "rss/utils"
-
-module RSS
- module XML
- class Element
- include Enumerable
-
- attr_reader :name, :prefix, :uri, :attributes, :children
- def initialize(name, prefix=nil, uri=nil, attributes={}, children=[])
- @name = name
- @prefix = prefix
- @uri = uri
- @attributes = attributes
- if children.is_a?(String) or !children.respond_to?(:each)
- @children = [children]
- else
- @children = children
- end
- end
-
- def [](name)
- @attributes[name]
- end
-
- def []=(name, value)
- @attributes[name] = value
- end
-
- def <<(child)
- @children << child
- end
-
- def each(&block)
- @children.each(&block)
- end
-
- def ==(other)
- other.kind_of?(self.class) and
- @name == other.name and
- @uri == other.uri and
- @attributes == other.attributes and
- @children == other.children
- end
-
- def to_s
- rv = "<#{full_name}"
- attributes.each do |key, value|
- rv << " #{Utils.html_escape(key)}=\"#{Utils.html_escape(value)}\""
- end
- if children.empty?
- rv << "/>"
- else
- rv << ">"
- children.each do |child|
- rv << child.to_s
- end
- rv << "</#{full_name}>"
- end
- rv
- end
-
- def full_name
- if @prefix
- "#{@prefix}:#{@name}"
- else
- @name
- end
- end
- end
- end
-end
diff --git a/lib/rss/xmlparser.rb b/lib/rss/xmlparser.rb
deleted file mode 100644
index cb2dd2afdd..0000000000
--- a/lib/rss/xmlparser.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# frozen_string_literal: false
-begin
- require "xml/parser"
-rescue LoadError
- require "xmlparser"
-end
-
-begin
- require "xml/encoding-ja"
-rescue LoadError
- require "xmlencoding-ja"
- if defined?(Kconv)
- module XMLEncoding_ja
- class SJISHandler
- include Kconv
- end
- end
- end
-end
-
-module XML
- class Parser
- unless defined?(Error)
- # This error is legacy, so we just set it to the new one
- Error = ::XMLParserError # :nodoc:
- end
- end
-end
-
-module RSS
-
- class REXMLLikeXMLParser < ::XML::Parser
-
- include ::XML::Encoding_ja
-
- def listener=(listener)
- @listener = listener
- end
-
- def startElement(name, attrs)
- @listener.tag_start(name, attrs)
- end
-
- def endElement(name)
- @listener.tag_end(name)
- end
-
- def character(data)
- @listener.text(data)
- end
-
- def xmlDecl(version, encoding, standalone)
- @listener.xmldecl(version, encoding, standalone == 1)
- end
-
- def processingInstruction(target, content)
- @listener.instruction(target, content)
- end
-
- end
-
- class XMLParserParser < BaseParser
-
- class << self
- def listener
- XMLParserListener
- end
- end
-
- private
- def _parse
- begin
- parser = REXMLLikeXMLParser.new
- parser.listener = @listener
- parser.parse(@rss)
- rescue ::XML::Parser::Error => e
- raise NotWellFormedError.new(parser.line){e.message}
- end
- end
-
- end
-
- class XMLParserListener < BaseListener
-
- include ListenerMixin
-
- def xmldecl(version, encoding, standalone)
- super
- # Encoding is converted to UTF-8 when XMLParser parses XML.
- @encoding = 'UTF-8'
- end
-
- end
-
-end
diff --git a/lib/rss/xmlscanner.rb b/lib/rss/xmlscanner.rb
deleted file mode 100644
index 6e3b13d2f5..0000000000
--- a/lib/rss/xmlscanner.rb
+++ /dev/null
@@ -1,122 +0,0 @@
-# frozen_string_literal: false
-require 'xmlscan/scanner'
-require 'stringio'
-
-module RSS
-
- class XMLScanParser < BaseParser
-
- class << self
- def listener
- XMLScanListener
- end
- end
-
- private
- def _parse
- begin
- if @rss.is_a?(String)
- input = StringIO.new(@rss)
- else
- input = @rss
- end
- scanner = XMLScan::XMLScanner.new(@listener)
- scanner.parse(input)
- rescue XMLScan::Error => e
- lineno = e.lineno || scanner.lineno || input.lineno
- raise NotWellFormedError.new(lineno){e.message}
- end
- end
-
- end
-
- class XMLScanListener < BaseListener
-
- include XMLScan::Visitor
- include ListenerMixin
-
- ENTITIES = {
- 'lt' => '<',
- 'gt' => '>',
- 'amp' => '&',
- 'quot' => '"',
- 'apos' => '\''
- }
-
- def on_xmldecl_version(str)
- @version = str
- end
-
- def on_xmldecl_encoding(str)
- @encoding = str
- end
-
- def on_xmldecl_standalone(str)
- @standalone = str
- end
-
- def on_xmldecl_end
- xmldecl(@version, @encoding, @standalone == "yes")
- end
-
- alias_method(:on_pi, :instruction)
- alias_method(:on_chardata, :text)
- alias_method(:on_cdata, :text)
-
- def on_etag(name)
- tag_end(name)
- end
-
- def on_entityref(ref)
- text(entity(ref))
- end
-
- def on_charref(code)
- text([code].pack('U'))
- end
-
- alias_method(:on_charref_hex, :on_charref)
-
- def on_stag(name)
- @attrs = {}
- end
-
- def on_attribute(name)
- @attrs[name] = @current_attr = ''
- end
-
- def on_attr_value(str)
- @current_attr << str
- end
-
- def on_attr_entityref(ref)
- @current_attr << entity(ref)
- end
-
- def on_attr_charref(code)
- @current_attr << [code].pack('U')
- end
-
- alias_method(:on_attr_charref_hex, :on_attr_charref)
-
- def on_stag_end(name)
- tag_start(name, @attrs)
- end
-
- def on_stag_end_empty(name)
- tag_start(name, @attrs)
- tag_end(name)
- end
-
- private
- def entity(ref)
- ent = ENTITIES[ref]
- if ent
- ent
- else
- wellformed_error("undefined entity: #{ref}")
- end
- end
- end
-
-end
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index c8f43e3805..6a7e56fa3c 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-# -*- ruby -*-
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -7,18 +6,17 @@
#++
require 'rbconfig'
-require 'thread'
module Gem
- VERSION = "2.6.14"
+ VERSION = "3.2.33".freeze
end
# Must be first since it unloads the prelude from 1.9.2
-require 'rubygems/compatibility'
+require_relative 'rubygems/compatibility'
-require 'rubygems/defaults'
-require 'rubygems/deprecate'
-require 'rubygems/errors'
+require_relative 'rubygems/defaults'
+require_relative 'rubygems/deprecate'
+require_relative 'rubygems/errors'
##
# RubyGems is the Ruby standard for publishing and managing third party
@@ -27,29 +25,27 @@ require 'rubygems/errors'
# For user documentation, see:
#
# * <tt>gem help</tt> and <tt>gem help [command]</tt>
-# * {RubyGems User Guide}[http://guides.rubygems.org/]
-# * {Frequently Asked Questions}[http://guides.rubygems.org/faqs]
+# * {RubyGems User Guide}[https://guides.rubygems.org/]
+# * {Frequently Asked Questions}[https://guides.rubygems.org/faqs]
#
# For gem developer documentation see:
#
-# * {Creating Gems}[http://guides.rubygems.org/make-your-own-gem]
+# * {Creating Gems}[https://guides.rubygems.org/make-your-own-gem]
# * Gem::Specification
# * Gem::Version for version dependency notes
#
# Further RubyGems documentation can be found at:
#
-# * {RubyGems Guides}[http://guides.rubygems.org]
-# * {RubyGems API}[http://www.rubydoc.info/github/rubygems/rubygems] (also available from
+# * {RubyGems Guides}[https://guides.rubygems.org]
+# * {RubyGems API}[https://www.rubydoc.info/github/rubygems/rubygems] (also available from
# <tt>gem server</tt>)
#
# == RubyGems Plugins
#
-# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or
+# RubyGems will load plugins in the latest version of each installed gem or
# $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and
-# placed at the root of your gem's #require_path. Plugins are discovered via
-# Gem::find_files and then loaded. Take care when implementing a plugin as your
-# plugin file may be loaded multiple times if multiple versions of your gem
-# are installed.
+# placed at the root of your gem's #require_path. Plugins are installed at a
+# special location and loaded on boot.
#
# For an example plugin, see the {Graph gem}[https://github.com/seattlerb/graph]
# which adds a `gem graph` command.
@@ -115,10 +111,18 @@ require 'rubygems/errors'
#
# -The RubyGems Team
-
module Gem
RUBYGEMS_DIR = File.dirname File.expand_path(__FILE__)
+ # Taint support is deprecated in Ruby 2.7.
+ # This allows switching ".untaint" to ".tap(&Gem::UNTAINT)",
+ # to avoid deprecation warnings in Ruby 2.7.
+ UNTAINT = RUBY_VERSION < '2.7' ? :untaint.to_sym : proc{}
+
+ # When https://bugs.ruby-lang.org/issues/17259 is available, there is no need to override Kernel#warn
+ KERNEL_WARN_IGNORES_INTERNAL_ENTRIES = RUBY_ENGINE == "truffleruby" ||
+ (RUBY_ENGINE == "ruby" && RUBY_VERSION >= '3.0')
+
##
# An Array of Regexps that match windows Ruby platforms.
@@ -129,14 +133,14 @@ module Gem
/mingw/i,
/mswin/i,
/wince/i,
- ]
+ ].freeze
GEM_DEP_FILES = %w[
gem.deps.rb
gems.rb
Gemfile
Isolate
- ]
+ ].freeze
##
# Subdirectories in a gem repository
@@ -147,8 +151,9 @@ module Gem
doc
extensions
gems
+ plugins
specifications
- ]
+ ].freeze
##
# Subdirectories in a gem repository for default gems
@@ -156,36 +161,24 @@ module Gem
REPOSITORY_DEFAULT_GEM_SUBDIRECTORIES = %w[
gems
specifications/default
- ]
+ ].freeze
##
- # Exception classes used in a Gem.read_binary +rescue+ statement. Not all of
- # these are defined in Ruby 1.8.7, hence the need for this convoluted setup.
+ # Exception classes used in a Gem.read_binary +rescue+ statement
- READ_BINARY_ERRORS = begin
- read_binary_errors = [Errno::EACCES, Errno::EROFS]
- read_binary_errors << Errno::ENOTSUP if Errno.const_defined?(:ENOTSUP)
- read_binary_errors
- end.freeze
+ READ_BINARY_ERRORS = [Errno::EACCES, Errno::EROFS, Errno::ENOSYS, Errno::ENOTSUP].freeze
##
- # Exception classes used in Gem.write_binary +rescue+ statement. Not all of
- # these are defined in Ruby 1.8.7.
+ # Exception classes used in Gem.write_binary +rescue+ statement
- WRITE_BINARY_ERRORS = begin
- write_binary_errors = []
- write_binary_errors << Errno::ENOTSUP if Errno.const_defined?(:ENOTSUP)
- write_binary_errors
- end.freeze
-
- USE_BUNDLER_FOR_GEMDEPS = true # :nodoc:
+ WRITE_BINARY_ERRORS = [Errno::ENOSYS, Errno::ENOTSUP].freeze
@@win_platform = nil
@configuration = nil
@gemdeps = nil
@loaded_specs = {}
- LOADED_SPECS_MUTEX = Mutex.new
+ LOADED_SPECS_MUTEX = Thread::Mutex.new
@path_to_default_spec_map = {}
@platforms = []
@ruby = nil
@@ -200,12 +193,14 @@ module Gem
@pre_reset_hooks ||= []
@post_reset_hooks ||= []
+ @default_source_date_epoch = nil
+
##
# Try to activate a gem containing +path+. Returns true if
# activation succeeded or wasn't needed because it was already
# activated. Returns false if it can't find the path in a gem.
- def self.try_activate path
+ def self.try_activate(path)
# finds the _latest_ version... regardless of loaded specs and their deps
# if another gem had a requirement that would mean we shouldn't
# activate the latest version, then either it would already be activated
@@ -249,43 +244,35 @@ module Gem
##
# Find the full path to the executable for gem +name+. If the +exec_name+
- # is not given, the gem's default_executable is chosen, otherwise the
+ # is not given, an exception will be raised, otherwise the
# specified executable's path is returned. +requirements+ allows
# you to specify specific gem versions.
def self.bin_path(name, exec_name = nil, *requirements)
- # TODO: fails test_self_bin_path_bin_file_gone_in_latest
- # Gem::Specification.find_by_name(name, *requirements).bin_file exec_name
-
- raise ArgumentError, "you must supply exec_name" unless exec_name
-
requirements = Gem::Requirement.default if
requirements.empty?
find_spec_for_exe(name, exec_name, requirements).bin_file exec_name
end
- def self.find_spec_for_exe name, exec_name, requirements
+ def self.find_spec_for_exe(name, exec_name, requirements)
+ raise ArgumentError, "you must supply exec_name" unless exec_name
+
dep = Gem::Dependency.new name, requirements
loaded = Gem.loaded_specs[name]
return loaded if loaded && dep.matches_spec?(loaded)
- find_specs = proc { dep.matching_specs(true) }
- if dep.to_s == "bundler (>= 0.a)"
- specs = Gem::BundlerVersionFinder.without_filtering(&find_specs)
- else
- specs = find_specs.call
- end
+ specs = dep.matching_specs(true)
- specs = specs.find_all { |spec|
+ specs = specs.find_all do |spec|
spec.executables.include? exec_name
- } if exec_name
+ end if exec_name
unless spec = specs.first
msg = "can't find gem #{dep} with executable #{exec_name}"
- if name == "bundler" && bundler_message = Gem::BundlerVersionFinder.missing_version_message
+ if dep.filters_bundler? && bundler_message = Gem::BundlerVersionFinder.missing_version_message
msg = bundler_message
end
raise Gem::GemNotFoundException, msg
@@ -297,7 +284,7 @@ module Gem
##
# Find the full path to the executable for gem +name+. If the +exec_name+
- # is not given, the gem's default_executable is chosen, otherwise the
+ # is not given, an exception will be raised, otherwise the
# specified executable's path is returned. +requirements+ allows
# you to specify specific gem versions.
#
@@ -306,8 +293,8 @@ module Gem
#
# This method should *only* be used in bin stub files.
- def self.activate_bin_path name, exec_name, requirement # :nodoc:
- spec = find_spec_for_exe name, exec_name, [requirement]
+ def self.activate_bin_path(name, exec_name = nil, *requirements) # :nodoc:
+ spec = find_spec_for_exe name, exec_name, requirements
Gem::LOADED_SPECS_MUTEX.synchronize do
spec.activate
finish_resolve
@@ -332,6 +319,13 @@ module Gem
end
##
+ # The path were rubygems plugins are to be installed.
+
+ def self.plugindir(install_dir=Gem.dir)
+ File.join install_dir, 'plugins'
+ end
+
+ ##
# Reset the +dir+ and +path+ values. The next time +dir+ or +path+
# is requested, the values will be calculated from scratch. This is
# mainly used by the unit tests to provide test isolation.
@@ -344,13 +338,6 @@ module Gem
end
##
- # The path to standard location of the user's .gemrc file.
-
- def self.config_file
- @config_file ||= File.join Gem.user_home, '.gemrc'
- end
-
- ##
# The standard configuration object for gems.
def self.configuration
@@ -375,11 +362,6 @@ module Gem
spec.datadir
end
- class << self
- extend Gem::Deprecate
- deprecate :datadir, "spec.datadir", 2016, 10
- end
-
##
# A Zlib::Deflate.deflate wrapper
@@ -412,11 +394,11 @@ module Gem
target[k] = v
when Array
unless Gem::Deprecate.skip
- warn <<-eowarn
+ warn <<-EOWARN
Array values in the parameter to `Gem.paths=` are deprecated.
Please use a String or nil.
An Array (#{env.inspect}) was passed in from #{caller[3]}
- eowarn
+ EOWARN
end
target[k] = v.join File::PATH_SEPARATOR
end
@@ -430,8 +412,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# The path where gems are to be installed.
- #--
- # FIXME deprecate these once everything else has been done -ebh
def self.dir
paths.home
@@ -454,7 +434,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
#
# World-writable directories will never be created.
- def self.ensure_gem_subdirectories dir = Gem.dir, mode = nil
+ def self.ensure_gem_subdirectories(dir = Gem.dir, mode = nil)
ensure_subdirectories(dir, mode, REPOSITORY_SUBDIRECTORIES)
end
@@ -467,11 +447,11 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
#
# World-writable directories will never be created.
- def self.ensure_default_gem_subdirectories dir = Gem.dir, mode = nil
+ def self.ensure_default_gem_subdirectories(dir = Gem.dir, mode = nil)
ensure_subdirectories(dir, mode, REPOSITORY_DEFAULT_GEM_SUBDIRECTORIES)
end
- def self.ensure_subdirectories dir, mode, subdirs # :nodoc:
+ def self.ensure_subdirectories(dir, mode, subdirs) # :nodoc:
old_umask = File.umask
File.umask old_umask | 002
@@ -484,7 +464,10 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
subdirs.each do |name|
subdir = File.join dir, name
next if File.exist? subdir
- FileUtils.mkdir_p subdir, options rescue nil
+ begin
+ FileUtils.mkdir_p subdir, **options
+ rescue SystemCallError
+ end
end
ensure
File.umask old_umask
@@ -495,7 +478,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# distinction as extensions cannot be shared between the two.
def self.extension_api_version # :nodoc:
- if 'no' == RbConfig::CONFIG['ENABLE_SHARED'] then
+ if 'no' == RbConfig::CONFIG['ENABLE_SHARED']
"#{ruby_api_version}-static"
else
ruby_api_version
@@ -521,7 +504,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
gem_specifications = @gemdeps ? Gem.loaded_specs.values : Gem::Specification.stubs
- files.concat gem_specifications.map { |spec|
+ files.concat gem_specifications.map {|spec|
spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
}.flatten
@@ -532,10 +515,11 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
return files
end
- def self.find_files_from_load_path glob # :nodoc:
- $LOAD_PATH.map { |load_path|
- Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"]
- }.flatten.select { |file| File.file? file.untaint }
+ def self.find_files_from_load_path(glob) # :nodoc:
+ glob_with_suffixes = "#{glob}#{Gem.suffix_pattern}"
+ $LOAD_PATH.map do |load_path|
+ Gem::Util.glob_files_in_dir(glob_with_suffixes, load_path)
+ end.flatten.select {|file| File.file? file.tap(&Gem::UNTAINT) }
end
##
@@ -555,7 +539,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
files = find_files_from_load_path glob if check_load_path
- files.concat Gem::Specification.latest_specs(true).map { |spec|
+ files.concat Gem::Specification.latest_specs(true).map {|spec|
spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
}.flatten
@@ -567,78 +551,15 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
##
- # Finds the user's home directory.
- #--
- # Some comments from the ruby-talk list regarding finding the home
- # directory:
- #
- # I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
- # to be depending on HOME in those code samples. I propose that
- # it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
- # least on Win32).
- #++
- #--
- #
- # FIXME move to pathsupport
- #
- #++
-
- def self.find_home
- windows = File::ALT_SEPARATOR
- if not windows or RUBY_VERSION >= '1.9' then
- File.expand_path "~"
- else
- ['HOME', 'USERPROFILE'].each do |key|
- return File.expand_path ENV[key] if ENV[key]
- end
-
- if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
- File.expand_path "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
- end
- end
- rescue
- if windows then
- File.expand_path File.join(ENV['HOMEDRIVE'] || ENV['SystemDrive'], '/')
- else
- File.expand_path "/"
- end
- end
-
- private_class_method :find_home
-
- # FIXME deprecate these in 3.0
-
- ##
- # Zlib::GzipReader wrapper that unzips +data+.
-
- def self.gunzip(data)
- Gem::Util.gunzip data
- end
-
- ##
- # Zlib::GzipWriter wrapper that zips +data+.
-
- def self.gzip(data)
- Gem::Util.gzip data
- end
-
- ##
- # A Zlib::Inflate#inflate wrapper
-
- def self.inflate(data)
- Gem::Util.inflate data
- end
-
- ##
# Top level install helper method. Allows you to install gems interactively:
#
# % irb
# >> Gem.install "minitest"
- # Fetching: minitest-3.0.1.gem (100%)
+ # Fetching: minitest-5.14.0.gem (100%)
# => [#<Gem::Specification:0x1013b4528 @name="minitest", ...>]
- def self.install name, version = Gem::Requirement.default, *options
- require "rubygems/dependency_installer"
+ def self.install(name, version = Gem::Requirement.default, *options)
+ require_relative "rubygems/dependency_installer"
inst = Gem::DependencyInstaller.new(*options)
inst.install name, version
inst.installed_gems
@@ -649,14 +570,12 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# <tt>https://rubygems.org</tt>.
def self.host
- # TODO: move to utils
@host ||= Gem::DEFAULT_HOST
end
## Set the default RubyGems API host.
- def self.host= host
- # TODO: move to utils
+ def self.host=(host)
@host = host
end
@@ -671,60 +590,47 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
index = $LOAD_PATH.index RbConfig::CONFIG['sitelibdir']
- index
+ index || 0
end
- @yaml_loaded = false
-
##
- # Loads YAML, preferring Psych
+ # The number of paths in the `$LOAD_PATH` from activated gems. Used to
+ # prioritize `-I` and `ENV['RUBYLIB`]` entries during `require`.
- def self.load_yaml
- return if @yaml_loaded
- return unless defined?(gem)
+ def self.activated_gem_paths
+ @activated_gem_paths ||= 0
+ end
- test_syck = ENV['TEST_SYCK']
+ ##
+ # Add a list of paths to the $LOAD_PATH at the proper place.
- # Only Ruby 1.8 and 1.9 have syck
- test_syck = false unless /^1\./ =~ RUBY_VERSION
+ def self.add_to_load_path(*paths)
+ @activated_gem_paths = activated_gem_paths + paths.size
- unless test_syck
- begin
- gem 'psych', '>= 2.0.0'
- rescue Gem::LoadError
- # It's OK if the user does not have the psych gem installed. We will
- # attempt to require the stdlib version
- end
+ # gem directories must come after -I and ENV['RUBYLIB']
+ $LOAD_PATH.insert(Gem.load_path_insert_index, *paths)
+ end
- begin
- # Try requiring the gem version *or* stdlib version of psych.
- require 'psych'
- rescue ::LoadError
- # If we can't load psych, thats fine, go on.
- else
- # If 'yaml' has already been required, then we have to
- # be sure to switch it over to the newly loaded psych.
- if defined?(YAML::ENGINE) && YAML::ENGINE.yamler != "psych"
- YAML::ENGINE.yamler = "psych"
- end
+ @yaml_loaded = false
- require 'rubygems/psych_additions'
- require 'rubygems/psych_tree'
- end
- end
+ ##
+ # Loads YAML, preferring Psych
- require 'yaml'
- require 'rubygems/safe_yaml'
+ def self.load_yaml
+ return if @yaml_loaded
- # If we're supposed to be using syck, then we may have to force
- # activate it via the YAML::ENGINE API.
- if test_syck and defined?(YAML::ENGINE)
- YAML::ENGINE.yamler = "syck" unless YAML::ENGINE.syck?
+ begin
+ # Try requiring the gem version *or* stdlib version of psych.
+ require 'psych'
+ rescue ::LoadError
+ # If we can't load psych, that's fine, go on.
+ else
+ require_relative 'rubygems/psych_additions'
+ require_relative 'rubygems/psych_tree'
end
- # Now that we're sure some kind of yaml library is loaded, pull
- # in our hack to deal with Syck's DefaultKey ugliness.
- require 'rubygems/syck_hack'
+ require 'yaml'
+ require_relative 'rubygems/safe_yaml'
@yaml_loaded = true
end
@@ -857,7 +763,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
if prefix != File.expand_path(RbConfig::CONFIG['sitelibdir']) and
prefix != File.expand_path(RbConfig::CONFIG['libdir']) and
- 'lib' == File.basename(RUBYGEMS_DIR) then
+ 'lib' == File.basename(RUBYGEMS_DIR)
prefix
end
end
@@ -873,19 +779,19 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Safely read a file in binary mode on all platforms.
def self.read_binary(path)
- open path, 'rb+' do |f|
+ File.open path, 'rb+' do |f|
f.flock(File::LOCK_EX)
f.read
end
rescue *READ_BINARY_ERRORS
- open path, 'rb' do |f|
+ File.open path, 'rb' do |f|
f.read
end
rescue Errno::ENOLCK # NFS
if Thread.main != Thread.current
raise
else
- open path, 'rb' do |f|
+ File.open path, 'rb' do |f|
f.read
end
end
@@ -894,18 +800,18 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# Safely write a file in binary mode on all platforms.
def self.write_binary(path, data)
- open(path, 'wb') do |io|
- begin
- io.flock(File::LOCK_EX)
- rescue *WRITE_BINARY_ERRORS
- end
+ File.open(path, File::RDWR | File::CREAT | File::BINARY | File::LOCK_EX) do |io|
+ io.write data
+ end
+ rescue *WRITE_BINARY_ERRORS
+ File.open(path, 'wb') do |io|
io.write data
end
rescue Errno::ENOLCK # NFS
if Thread.main != Thread.current
raise
else
- open(path, 'wb') do |io|
+ File.open(path, 'wb') do |io|
io.write data
end
end
@@ -915,9 +821,8 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# The path to the running Ruby interpreter.
def self.ruby
- if @ruby.nil? then
- @ruby = File.join(RbConfig::CONFIG['bindir'],
- "#{RbConfig::CONFIG['ruby_install_name']}#{RbConfig::CONFIG['EXEEXT']}")
+ if @ruby.nil?
+ @ruby = RbConfig.ruby
@ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
end
@@ -944,7 +849,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# Returns the latest release-version specification for the gem +name+.
- def self.latest_spec_for name
+ def self.latest_spec_for(name)
dependency = Gem::Dependency.new name
fetcher = Gem::SpecFetcher.fetcher
spec_tuples, = fetcher.spec_for_dependency dependency
@@ -965,7 +870,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# Returns the version of the latest release-version of gem +name+
- def self.latest_version_for name
+ def self.latest_version_for(name)
spec = latest_spec_for name
spec and spec.version
end
@@ -977,10 +882,15 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
return @ruby_version if defined? @ruby_version
version = RUBY_VERSION.dup
- if defined?(RUBY_PATCHLEVEL) && RUBY_PATCHLEVEL != -1 then
+ if defined?(RUBY_PATCHLEVEL) && RUBY_PATCHLEVEL != -1
version << ".#{RUBY_PATCHLEVEL}"
- elsif defined?(RUBY_REVISION) then
- version << ".dev.#{RUBY_REVISION}"
+ elsif defined?(RUBY_DESCRIPTION)
+ if RUBY_ENGINE == "ruby"
+ desc = RUBY_DESCRIPTION[/\Aruby #{Regexp.quote(RUBY_VERSION)}([^ ]+) /, 1]
+ else
+ desc = RUBY_DESCRIPTION[/\A#{RUBY_ENGINE} #{Regexp.quote(RUBY_ENGINE_VERSION)} \(#{RUBY_VERSION}([^ ]+)\) /, 1]
+ end
+ version << ".#{desc}" if desc
end
@ruby_version = Gem::Version.new version
@@ -1010,7 +920,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# DOC: This comment is not documentation about the method itself, it's
# more of a code comment about the implementation.
- def self.sources= new_sources
+ def self.sources=(new_sources)
if !new_sources
@sources = nil
else
@@ -1026,16 +936,37 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
##
+ # Regexp for require-able path suffixes.
+
+ def self.suffix_regexp
+ @suffix_regexp ||= /#{Regexp.union(suffixes)}\z/
+ end
+
+ ##
+ # Glob pattern for require-able plugin suffixes.
+
+ def self.plugin_suffix_pattern
+ @plugin_suffix_pattern ||= "_plugin#{suffix_pattern}"
+ end
+
+ ##
+ # Regexp for require-able plugin suffixes.
+
+ def self.plugin_suffix_regexp
+ @plugin_suffix_regexp ||= /_plugin#{suffix_regexp}\z/
+ end
+
+ ##
# Suffixes for require-able paths.
def self.suffixes
@suffixes ||= ['',
'.rb',
- *%w(DLEXT DLEXT2).map { |key|
+ *%w[DLEXT DLEXT2].map do |key|
val = RbConfig::CONFIG[key]
next unless val and not val.empty?
".#{val}"
- }
+ end,
].compact.uniq
end
@@ -1059,7 +990,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Lazily loads DefaultUserInteraction and returns the default UI.
def self.ui
- require 'rubygems/user_interaction'
+ require_relative 'rubygems/user_interaction'
Gem::DefaultUserInteraction.ui
end
@@ -1072,33 +1003,33 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
paths.flatten!
paths.compact!
hash = { "GEM_HOME" => home, "GEM_PATH" => paths.empty? ? home : paths.join(File::PATH_SEPARATOR) }
- hash.delete_if { |_, v| v.nil? }
+ hash.delete_if {|_, v| v.nil? }
self.paths = hash
end
##
- # The home directory for the user.
-
- def self.user_home
- @user_home ||= find_home.untaint
- end
-
- ##
# Is this a windows platform?
def self.win_platform?
- if @@win_platform.nil? then
+ if @@win_platform.nil?
ruby_platform = RbConfig::CONFIG['host_os']
- @@win_platform = !!WIN_PATTERNS.find { |r| ruby_platform =~ r }
+ @@win_platform = !!WIN_PATTERNS.find {|r| ruby_platform =~ r }
end
@@win_platform
end
##
+ # Is this a java platform?
+
+ def self.java_platform?
+ RUBY_PLATFORM == "java"
+ end
+
+ ##
# Load +plugins+ as Ruby files
- def self.load_plugin_files plugins # :nodoc:
+ def self.load_plugin_files(plugins) # :nodoc:
plugins.each do |plugin|
# Skip older versions of the GemCutter plugin: Its commands are in
@@ -1116,15 +1047,11 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
##
- # Find the 'rubygems_plugin' files in the latest installed gems and load
- # them
+ # Find rubygems plugin files in the standard location and load them
def self.load_plugins
- # Remove this env var by at least 3.0
- if ENV['RUBYGEMS_LOAD_ALL_PLUGINS']
- load_plugin_files find_files('rubygems_plugin', false)
- else
- load_plugin_files find_latest_files('rubygems_plugin', false)
+ Gem.path.each do |gem_path|
+ load_plugin_files Gem::Util.glob_files_in_dir("*#{Gem.plugin_suffix_pattern}", plugindir(gem_path))
end
end
@@ -1132,18 +1059,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Find all 'rubygems_plugin' files in $LOAD_PATH and load them
def self.load_env_plugins
- path = "rubygems_plugin"
-
- files = []
- $LOAD_PATH.each do |load_path|
- globbed = Dir["#{File.expand_path path, load_path}#{Gem.suffix_pattern}"]
-
- globbed.each do |load_path_file|
- files << load_path_file if File.file?(load_path_file.untaint)
- end
- end
-
- load_plugin_files files
+ load_plugin_files find_files_from_load_path("rubygems_plugin")
end
##
@@ -1166,7 +1082,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# execution of arbitrary code when used from directories outside your
# control.
- def self.use_gemdeps path = nil
+ def self.use_gemdeps(path = nil)
raise_exception = path
path ||= ENV['RUBYGEMS_GEMDEPS']
@@ -1174,9 +1090,9 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
path = path.dup
- if path == "-" then
+ if path == "-"
Gem::Util.traverse_parents Dir.pwd do |directory|
- dep_file = GEM_DEP_FILES.find { |f| File.file?(f) }
+ dep_file = GEM_DEP_FILES.find {|f| File.file?(f) }
next unless dep_file
@@ -1185,57 +1101,83 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
end
- path.untaint
+ path.tap(&Gem::UNTAINT)
- unless File.file? path then
+ unless File.file? path
return unless raise_exception
raise ArgumentError, "Unable to find gem dependencies file at #{path}"
end
- if USE_BUNDLER_FOR_GEMDEPS
-
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(path)
- require 'rubygems/user_interaction'
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(path)
+ require_relative 'rubygems/user_interaction'
+ require "bundler"
+ begin
Gem::DefaultUserInteraction.use_ui(ui) do
- require "bundler"
- @gemdeps = Bundler.setup
- Bundler.ui = nil
- @gemdeps.requested_specs.map(&:to_spec).sort_by(&:name)
+ begin
+ Bundler.ui.silence do
+ @gemdeps = Bundler.setup
+ end
+ ensure
+ Gem::DefaultUserInteraction.ui.close
+ end
end
+ rescue Bundler::BundlerError => e
+ warn e.message
+ warn "You may need to `bundle install` to install missing gems"
+ warn ""
+ end
+ end
- else
+ ##
+ # If the SOURCE_DATE_EPOCH environment variable is set, returns it's value.
+ # Otherwise, returns the time that `Gem.source_date_epoch_string` was
+ # first called in the same format as SOURCE_DATE_EPOCH.
+ #
+ # NOTE(@duckinator): The implementation is a tad weird because we want to:
+ # 1. Make builds reproducible by default, by having this function always
+ # return the same result during a given run.
+ # 2. Allow changing ENV['SOURCE_DATE_EPOCH'] at runtime, since multiple
+ # tests that set this variable will be run in a single process.
+ #
+ # If you simplify this function and a lot of tests fail, that is likely
+ # due to #2 above.
+ #
+ # Details on SOURCE_DATE_EPOCH:
+ # https://reproducible-builds.org/specs/source-date-epoch/
- rs = Gem::RequestSet.new
- @gemdeps = rs.load_gemdeps path
+ def self.source_date_epoch_string
+ # The value used if $SOURCE_DATE_EPOCH is not set.
+ @default_source_date_epoch ||= Time.now.to_i.to_s
- rs.resolve_current.map do |s|
- s.full_spec.tap(&:activate)
- end
+ specified_epoch = ENV["SOURCE_DATE_EPOCH"]
- end
- rescue => e
- case e
- when Gem::LoadError, Gem::UnsatisfiableDependencyError, (defined?(Bundler::GemNotFound) ? Bundler::GemNotFound : Gem::LoadError)
- warn e.message
- warn "You may need to `gem install -g` to install missing gems"
- warn ""
- else
- raise
- end
+ # If it's empty or just whitespace, treat it like it wasn't set at all.
+ specified_epoch = nil if !specified_epoch.nil? && specified_epoch.strip.empty?
+
+ epoch = specified_epoch || @default_source_date_epoch
+
+ epoch.strip
end
- class << self
- ##
- # TODO remove with RubyGems 3.0
+ ##
+ # Returns the value of Gem.source_date_epoch_string, as a Time object.
+ #
+ # This is used throughout RubyGems for enabling reproducible builds.
- alias detect_gemdeps use_gemdeps # :nodoc:
+ def self.source_date_epoch
+ Time.at(self.source_date_epoch_string.to_i).utc.freeze
end
# FIX: Almost everywhere else we use the `def self.` way of defining class
# methods, and then we switch over to `class << self` here. Pick one or the
# other.
class << self
+ ##
+ # RubyGems distributors (like operating system package managers) can
+ # disable RubyGems update by setting this to error message printed to
+ # end-users on gem update --system instead of actual update.
+ attr_accessor :disable_system_update_message
##
# Hash of loaded Gem::Specification keyed by name
@@ -1261,23 +1203,24 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
#
def register_default_spec(spec)
- new_format = Gem.default_gems_use_full_paths? || spec.require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } }
+ extended_require_paths = spec.require_paths.map {|f| f + "/" }
+ new_format = extended_require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } }
if new_format
- prefix_group = spec.require_paths.map {|f| f + "/"}.join("|")
+ prefix_group = extended_require_paths.join("|")
prefix_pattern = /^(#{prefix_group})/
end
- suffix_pattern = /#{Regexp.union(Gem.suffixes)}\z/
-
spec.files.each do |file|
if new_format
file = file.sub(prefix_pattern, "")
next unless $~
end
+ spec.activate if already_loaded?(file)
+
@path_to_default_spec_map[file] = spec
- @path_to_default_spec_map[file.sub(suffix_pattern, "")] = spec
+ @path_to_default_spec_map[file.sub(suffix_regexp, "")] = spec
end
end
@@ -1285,17 +1228,8 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Find a Gem::Specification of default gem from +path+
def find_unresolved_default_spec(path)
- @path_to_default_spec_map[path]
- end
-
- ##
- # Remove needless Gem::Specification of default gem from
- # unresolved default gem list
-
- def remove_unresolved_default_spec(spec)
- spec.files.each do |file|
- @path_to_default_spec_map.delete(file)
- end
+ default_spec = @path_to_default_spec_map[path]
+ return default_spec if default_spec && loaded_specs[default_spec.name] != default_spec
end
##
@@ -1349,64 +1283,76 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# work
attr_reader :pre_uninstall_hooks
+
+ private
+
+ def already_loaded?(file)
+ $LOADED_FEATURES.any? do |feature_path|
+ feature_path.end_with?(file) && default_gem_load_paths.any? {|load_path_entry| feature_path == "#{load_path_entry}/#{file}" }
+ end
+ end
+
+ def default_gem_load_paths
+ @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1]
+ end
end
##
# Location of Marshal quick gemspecs on remote repositories
- MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
-
- autoload :BundlerVersionFinder, 'rubygems/bundler_version_finder'
- autoload :ConfigFile, 'rubygems/config_file'
- autoload :Dependency, 'rubygems/dependency'
- autoload :DependencyList, 'rubygems/dependency_list'
- autoload :DependencyResolver, 'rubygems/resolver'
- autoload :Installer, 'rubygems/installer'
- autoload :Licenses, 'rubygems/util/licenses'
- autoload :PathSupport, 'rubygems/path_support'
- autoload :Platform, 'rubygems/platform'
- autoload :RequestSet, 'rubygems/request_set'
- autoload :Requirement, 'rubygems/requirement'
- autoload :Resolver, 'rubygems/resolver'
- autoload :Source, 'rubygems/source'
- autoload :SourceList, 'rubygems/source_list'
- autoload :SpecFetcher, 'rubygems/spec_fetcher'
- autoload :Specification, 'rubygems/specification'
- autoload :Util, 'rubygems/util'
- autoload :Version, 'rubygems/version'
-
- require "rubygems/specification"
+ MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/".freeze
+
+ autoload :BundlerVersionFinder, File.expand_path('rubygems/bundler_version_finder', __dir__)
+ autoload :ConfigFile, File.expand_path('rubygems/config_file', __dir__)
+ autoload :Dependency, File.expand_path('rubygems/dependency', __dir__)
+ autoload :DependencyList, File.expand_path('rubygems/dependency_list', __dir__)
+ autoload :Installer, File.expand_path('rubygems/installer', __dir__)
+ autoload :Licenses, File.expand_path('rubygems/util/licenses', __dir__)
+ autoload :NameTuple, File.expand_path('rubygems/name_tuple', __dir__)
+ autoload :PathSupport, File.expand_path('rubygems/path_support', __dir__)
+ autoload :Platform, File.expand_path('rubygems/platform', __dir__)
+ autoload :RequestSet, File.expand_path('rubygems/request_set', __dir__)
+ autoload :Requirement, File.expand_path('rubygems/requirement', __dir__)
+ autoload :Resolver, File.expand_path('rubygems/resolver', __dir__)
+ autoload :Source, File.expand_path('rubygems/source', __dir__)
+ autoload :SourceList, File.expand_path('rubygems/source_list', __dir__)
+ autoload :SpecFetcher, File.expand_path('rubygems/spec_fetcher', __dir__)
+ autoload :Specification, File.expand_path('rubygems/specification', __dir__)
+ autoload :Util, File.expand_path('rubygems/util', __dir__)
+ autoload :Version, File.expand_path('rubygems/version', __dir__)
end
-require 'rubygems/exceptions'
+require_relative 'rubygems/exceptions'
# REFACTOR: This should be pulled out into some kind of hacks file.
-gem_preluded = Gem::GEM_PRELUDE_SUCKAGE and defined? Gem
-unless gem_preluded then # TODO: remove guard after 1.9.2 dropped
- begin
- ##
- # Defaults the operating system (or packager) wants to provide for RubyGems.
-
- require 'rubygems/defaults/operating_system'
- rescue LoadError
- end
-
- if defined?(RUBY_ENGINE) then
- begin
- ##
- # Defaults the Ruby implementation wants to provide for RubyGems
+begin
+ ##
+ # Defaults the Ruby implementation wants to provide for RubyGems
- require "rubygems/defaults/#{RUBY_ENGINE}"
- rescue LoadError
- end
- end
+ require "rubygems/defaults/#{RUBY_ENGINE}"
+rescue LoadError
end
##
# Loads the default specs.
Gem::Specification.load_defaults
-require 'rubygems/core_ext/kernel_gem'
-require 'rubygems/core_ext/kernel_require'
+require_relative 'rubygems/core_ext/kernel_gem'
+require_relative 'rubygems/core_ext/kernel_require'
+require_relative 'rubygems/core_ext/kernel_warn'
-Gem.use_gemdeps
+begin
+ ##
+ # Defaults the operating system (or packager) wants to provide for RubyGems.
+
+ require 'rubygems/defaults/operating_system'
+rescue LoadError
+ # Ignored
+rescue StandardError => e
+ msg = "#{e.message}\n" \
+ "Loading the rubygems/defaults/operating_system.rb file caused an error. " \
+ "This file is owned by your OS, not by rubygems upstream. " \
+ "Please find out which OS package this file belongs to and follow the guidelines from your OS to report " \
+ "the problem and ask for help."
+ raise e.class, msg
+end
diff --git a/lib/rubygems/available_set.rb b/lib/rubygems/available_set.rb
index 49b5d5fd06..499483d9e9 100644
--- a/lib/rubygems/available_set.rb
+++ b/lib/rubygems/available_set.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
class Gem::AvailableSet
-
include Enumerable
Tuple = Struct.new(:spec, :source)
@@ -70,11 +69,11 @@ class Gem::AvailableSet
end
def all_specs
- @set.map { |t| t.spec }
+ @set.map {|t| t.spec }
end
def match_platform!
- @set.reject! { |t| !Gem::Platform.match(t.spec.platform) }
+ @set.reject! {|t| !Gem::Platform.match_spec?(t.spec) }
@sorted = nil
self
end
@@ -91,7 +90,7 @@ class Gem::AvailableSet
end
def source_for(spec)
- f = @set.find { |t| t.spec == spec }
+ f = @set.find {|t| t.spec == spec }
f.source
end
@@ -103,7 +102,7 @@ class Gem::AvailableSet
# Other options are :shallow for only direct development dependencies of the
# gems in this set or :all for all development dependencies.
- def to_request_set development = :none
+ def to_request_set(development = :none)
request_set = Gem::RequestSet.new
request_set.development = :all == development
@@ -160,6 +159,6 @@ class Gem::AvailableSet
end
def inject_into_list(dep_list)
- @set.each { |t| dep_list.add t.spec }
+ @set.each {|t| dep_list.add t.spec }
end
end
diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb
index 0d50a93230..665b87fc0e 100644
--- a/lib/rubygems/basic_specification.rb
+++ b/lib/rubygems/basic_specification.rb
@@ -4,7 +4,6 @@
# used by both Specification and StubSpecification.
class Gem::BasicSpecification
-
##
# Allows installation of extensions for git: gems.
@@ -35,7 +34,12 @@ class Gem::BasicSpecification
end
def self.default_specifications_dir
- File.join(Gem.default_dir, "specifications", "default")
+ Gem.default_specifications_dir
+ end
+
+ class << self
+ extend Gem::Deprecate
+ rubygems_deprecate :default_specifications_dir, "Gem.default_specifications_dir"
end
##
@@ -65,14 +69,17 @@ class Gem::BasicSpecification
##
# Return true if this spec can require +file+.
- def contains_requirable_file? file
- if @ignored then
+ def contains_requirable_file?(file)
+ if @ignored
return false
- elsif missing_extensions? then
+ elsif missing_extensions?
@ignored = true
- warn "Ignoring #{full_name} because its extensions are not built. " +
- "Try: gem pristine #{name} --version #{version}"
+ if Gem::Platform::RUBY == platform || Gem::Platform.local === platform
+ warn "Ignoring #{full_name} because its extensions are not built. " +
+ "Try: gem pristine #{name} --version #{version}"
+ end
+
return false
end
@@ -81,14 +88,14 @@ class Gem::BasicSpecification
def default_gem?
loaded_from &&
- File.dirname(loaded_from) == self.class.default_specifications_dir
+ File.dirname(loaded_from) == Gem.default_specifications_dir
end
##
# Returns full path to the directory where gem's extensions are installed.
def extension_dir
- @extension_dir ||= File.expand_path(File.join(extensions_dir, full_name)).untaint
+ @extension_dir ||= File.expand_path(File.join(extensions_dir, full_name)).tap(&Gem::UNTAINT)
end
##
@@ -103,7 +110,7 @@ class Gem::BasicSpecification
def find_full_gem_path # :nodoc:
# TODO: also, shouldn't it default to full_name if it hasn't been written?
path = File.expand_path File.join(gems_dir, full_name)
- path.untaint
+ path.tap(&Gem::UNTAINT)
path
end
@@ -124,10 +131,10 @@ class Gem::BasicSpecification
# default Ruby platform.
def full_name
- if platform == Gem::Platform::RUBY or platform.nil? then
- "#{name}-#{version}".dup.untaint
+ if platform == Gem::Platform::RUBY or platform.nil?
+ "#{name}-#{version}".dup.tap(&Gem::UNTAINT)
else
- "#{name}-#{version}-#{platform}".dup.untaint
+ "#{name}-#{version}-#{platform}".dup.tap(&Gem::UNTAINT)
end
end
@@ -139,7 +146,7 @@ class Gem::BasicSpecification
@full_require_paths ||=
begin
full_paths = raw_require_paths.map do |path|
- File.join full_gem_path, path.untaint
+ File.join full_gem_path, path.tap(&Gem::UNTAINT)
end
full_paths << extension_dir if have_extensions?
@@ -152,16 +159,16 @@ class Gem::BasicSpecification
# The path to the data directory for this gem.
def datadir
-# TODO: drop the extra ", gem_name" which is uselessly redundant
- File.expand_path(File.join(gems_dir, full_name, "data", name)).untaint
+ # TODO: drop the extra ", gem_name" which is uselessly redundant
+ File.expand_path(File.join(gems_dir, full_name, "data", name)).tap(&Gem::UNTAINT)
end
##
# Full path of the target library file.
# If the file is not in this gem, return nil.
- def to_fullpath path
- if activated? then
+ def to_fullpath(path)
+ if activated?
@paths_map ||= {}
@paths_map[path] ||=
begin
@@ -196,8 +203,8 @@ class Gem::BasicSpecification
def internal_init # :nodoc:
@extension_dir = nil
- @full_gem_path = nil
- @gem_dir = nil
+ @full_gem_path = nil
+ @gem_dir = nil
@ignored = nil
end
@@ -249,7 +256,7 @@ class Gem::BasicSpecification
def source_paths
paths = raw_require_paths.dup
- if have_extensions? then
+ if have_extensions?
ext_dirs = extensions.map do |extension|
extension.split(File::SEPARATOR, 2).first
end.uniq
@@ -263,11 +270,17 @@ class Gem::BasicSpecification
##
# Return all files in this gem that match for +glob+.
- def matches_for_glob glob # TODO: rename?
- # TODO: do we need these?? Kill it
+ def matches_for_glob(glob) # TODO: rename?
glob = File.join(self.lib_dirs_glob, glob)
- Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1
+ Dir[glob].map {|f| f.tap(&Gem::UNTAINT) } # FIX our tests are broken, run w/ SAFE=1
+ end
+
+ ##
+ # Returns the list of plugins in this spec.
+
+ def plugins
+ matches_for_glob("rubygems#{Gem.plugin_suffix_pattern}")
end
##
@@ -275,13 +288,17 @@ class Gem::BasicSpecification
# for this spec.
def lib_dirs_glob
- dirs = if self.raw_require_paths.size > 1 then
- "{#{self.raw_require_paths.join(',')}}"
+ dirs = if self.raw_require_paths
+ if self.raw_require_paths.size > 1
+ "{#{self.raw_require_paths.join(',')}}"
+ else
+ self.raw_require_paths.first
+ end
else
- self.raw_require_paths.first
+ "lib" # default value for require_paths for bundler/inline
end
- "#{self.full_gem_path}/#{dirs}".dup.untaint
+ "#{self.full_gem_path}/#{dirs}".dup.tap(&Gem::UNTAINT)
end
##
@@ -312,15 +329,15 @@ class Gem::BasicSpecification
def have_extensions?; !extensions.empty?; end
- def have_file? file, suffixes
+ def have_file?(file, suffixes)
return true if raw_require_paths.any? do |path|
- base = File.join(gems_dir, full_name, path.untaint, file).untaint
- suffixes.any? { |suf| File.file? base + suf }
+ base = File.join(gems_dir, full_name, path.tap(&Gem::UNTAINT), file).tap(&Gem::UNTAINT)
+ suffixes.any? {|suf| File.file? base + suf }
end
if have_extensions?
base = File.join extension_dir, file
- suffixes.any? { |suf| File.file? base + suf }
+ suffixes.any? {|suf| File.file? base + suf }
else
false
end
diff --git a/lib/rubygems/bundler_version_finder.rb b/lib/rubygems/bundler_version_finder.rb
index baca170840..9ce0a2378e 100644
--- a/lib/rubygems/bundler_version_finder.rb
+++ b/lib/rubygems/bundler_version_finder.rb
@@ -1,13 +1,6 @@
-module Gem::BundlerVersionFinder
- @without_filtering = false
-
- def self.without_filtering
- without_filtering, @without_filtering = true, @without_filtering
- yield
- ensure
- @without_filtering = without_filtering
- end
+# frozen_string_literal: true
+module Gem::BundlerVersionFinder
def self.bundler_version
version, _ = bundler_version_with_reason
@@ -17,8 +10,6 @@ module Gem::BundlerVersionFinder
end
def self.bundler_version_with_reason
- return if @without_filtering
-
if v = ENV["BUNDLER_VERSION"]
return [v, "`$BUNDLER_VERSION`"]
end
@@ -36,7 +27,7 @@ module Gem::BundlerVersionFinder
return unless vr = bundler_version_with_reason
<<-EOS
Could not find 'bundler' (#{vr.first}) required by #{vr.last}.
-To update to the lastest version installed on your system, run `bundle update --bundler`.
+To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:#{vr.first}`
EOS
end
@@ -44,20 +35,19 @@ To install the missing version, run `gem install bundler:#{vr.first}`
def self.compatible?(spec)
return true unless spec.name == "bundler".freeze
return true unless bundler_version = self.bundler_version
- if bundler_version.segments.first >= 2
- spec.version == bundler_version
- else # 1.x
- spec.version.segments.first < 2
- end
+
+ spec.version.segments.first == bundler_version.segments.first
end
def self.filter!(specs)
return unless bundler_version = self.bundler_version
- if bundler_version.segments.first >= 2
- specs.reject! { |spec| spec.version != bundler_version }
- else # 1.x
- specs.reject! { |spec| spec.version.segments.first >= 2}
- end
+
+ specs.reject! {|spec| spec.version.segments.first != bundler_version.segments.first }
+
+ exact_match_index = specs.find_index {|spec| spec.version == bundler_version }
+ return unless exact_match_index
+
+ specs.unshift(specs.delete_at(exact_match_index))
end
def self.bundle_update_bundler_version
@@ -90,19 +80,26 @@ To install the missing version, run `gem install bundler:#{vr.first}`
def self.lockfile_contents
gemfile = ENV["BUNDLE_GEMFILE"]
gemfile = nil if gemfile && gemfile.empty?
- Gem::Util.traverse_parents Dir.pwd do |directory|
- next unless gemfile = Gem::GEM_DEP_FILES.find { |f| File.file?(f.untaint) }
- gemfile = File.join directory, gemfile
- break
- end unless gemfile
+ unless gemfile
+ begin
+ Gem::Util.traverse_parents(Dir.pwd) do |directory|
+ next unless gemfile = Gem::GEM_DEP_FILES.find {|f| File.file?(f.tap(&Gem::UNTAINT)) }
+
+ gemfile = File.join directory, gemfile
+ break
+ end
+ rescue Errno::ENOENT
+ return
+ end
+ end
return unless gemfile
lockfile = case gemfile
- when "gems.rb" then "gems.locked"
- else "#{gemfile}.lock"
- end.untaint
+ when "gems.rb" then "gems.locked"
+ else "#{gemfile}.lock"
+ end.dup.tap(&Gem::UNTAINT)
return unless File.file?(lockfile)
diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb
index 3bdca656b3..abdaa8e7c6 100644
--- a/lib/rubygems/command.rb
+++ b/lib/rubygems/command.rb
@@ -5,9 +5,9 @@
# See LICENSE.txt for permissions.
#++
-require 'optparse'
-require 'rubygems/requirement'
-require 'rubygems/user_interaction'
+require_relative 'optparse'
+require_relative 'requirement'
+require_relative 'user_interaction'
##
# Base class for all Gem commands. When creating a new gem command, define
@@ -17,9 +17,12 @@ require 'rubygems/user_interaction'
# A very good example to look at is Gem::Commands::ContentsCommand
class Gem::Command
-
include Gem::UserInteraction
+ Gem::OptionParser.accept Symbol do |value|
+ value.to_sym
+ end
+
##
# The name of the command.
@@ -73,7 +76,7 @@ class Gem::Command
when Array
@extra_args = value
when String
- @extra_args = value.split
+ @extra_args = value.split(' ')
end
end
@@ -121,7 +124,8 @@ class Gem::Command
@program_name = "gem #{command}"
@defaults = defaults
@options = defaults.dup
- @option_groups = Hash.new { |h,k| h[k] = [] }
+ @option_groups = Hash.new {|h,k| h[k] = [] }
+ @deprecated_options = { command => {} }
@parser = nil
@when_invoked = nil
end
@@ -150,20 +154,26 @@ class Gem::Command
##
# Display to the user that a gem couldn't be found and reasons why
#--
- # TODO: replace +domain+ with a parameter to suppress suggestions
- def show_lookup_failure(gem_name, version, errors, domain)
+ def show_lookup_failure(gem_name, version, errors, suppress_suggestions = false, required_by = nil)
+ gem = "'#{gem_name}' (#{version})"
+ msg = String.new "Could not find a valid gem #{gem}"
+
if errors and !errors.empty?
- msg = "Could not find a valid gem '#{gem_name}' (#{version}), here is why:\n".dup
- errors.each { |x| msg << " #{x.wordy}\n" }
- alert_error msg
+ msg << ", here is why:\n"
+ errors.each {|x| msg << " #{x.wordy}\n" }
else
- alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository"
+ if required_by and gem != required_by
+ msg << " (required by #{required_by}) in any repository"
+ else
+ msg << " in any repository"
+ end
end
- unless domain == :local then # HACK
- suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name gem_name
+ alert_error msg
+ unless suppress_suggestions
+ suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name(gem_name, :latest, 10)
unless suggestions.empty?
alert_error "Possible alternatives: #{suggestions.join(", ")}"
end
@@ -176,12 +186,12 @@ class Gem::Command
def get_all_gem_names
args = options[:args]
- if args.nil? or args.empty? then
+ if args.nil? or args.empty?
raise Gem::CommandLineError,
"Please specify at least one gem name (e.g. gem build GEMNAME)"
end
- args.select { |arg| arg !~ /^-/ }
+ args.select {|arg| arg !~ /^-/ }
end
##
@@ -206,12 +216,12 @@ class Gem::Command
def get_one_gem_name
args = options[:args]
- if args.nil? or args.empty? then
+ if args.nil? or args.empty?
raise Gem::CommandLineError,
"Please specify a gem name on the command line (e.g. gem build GEMNAME)"
end
- if args.size > 1 then
+ if args.size > 1
raise Gem::CommandLineError,
"Too many gem names (#{args.join(', ')}); please specify only one"
end
@@ -300,15 +310,23 @@ class Gem::Command
options[:build_args] = build_args
- self.ui = Gem::SilentUI.new if options[:silent]
+ if options[:silent]
+ old_ui = self.ui
+ self.ui = ui = Gem::SilentUI.new
+ end
- if options[:help] then
+ if options[:help]
show_help
- elsif @when_invoked then
+ elsif @when_invoked
@when_invoked.call options
else
execute
end
+ ensure
+ if ui
+ self.ui = old_ui
+ ui.close
+ end
end
##
@@ -326,7 +344,7 @@ class Gem::Command
##
# Add a command-line option and handler to the command.
#
- # See OptionParser#make_switch for an explanation of +opts+.
+ # See Gem::OptionParser#make_switch for an explanation of +opts+.
#
# +handler+ will be called with two values, the value of the argument and
# the options hash.
@@ -337,6 +355,8 @@ class Gem::Command
def add_option(*opts, &handler) # :yields: value, options
group_name = Symbol === opts.first ? opts.shift : :options
+ raise "Do not pass an empty string in opts" if opts.include?("")
+
@option_groups[group_name] << [opts, handler]
end
@@ -345,7 +365,50 @@ class Gem::Command
def remove_option(name)
@option_groups.each do |_, option_list|
- option_list.reject! { |args, _| args.any? { |x| x =~ /^#{name}/ } }
+ option_list.reject! {|args, _| args.any? {|x| x.is_a?(String) && x =~ /^#{name}/ } }
+ end
+ end
+
+ ##
+ # Mark a command-line option as deprecated, and optionally specify a
+ # deprecation horizon.
+ #
+ # Note that with the current implementation, every version of the option needs
+ # to be explicitly deprecated, so to deprecate an option defined as
+ #
+ # add_option('-t', '--[no-]test', 'Set test mode') do |value, options|
+ # # ... stuff ...
+ # end
+ #
+ # you would need to explicitly add a call to `deprecate_option` for every
+ # version of the option you want to deprecate, like
+ #
+ # deprecate_option('-t')
+ # deprecate_option('--test')
+ # deprecate_option('--no-test')
+
+ def deprecate_option(name, version: nil, extra_msg: nil)
+ @deprecated_options[command].merge!({ name => { "rg_version_to_expire" => version, "extra_msg" => extra_msg } })
+ end
+
+ def check_deprecated_options(options)
+ options.each do |option|
+ if option_is_deprecated?(option)
+ deprecation = @deprecated_options[command][option]
+ version_to_expire = deprecation["rg_version_to_expire"]
+
+ deprecate_option_msg = if version_to_expire
+ "The \"#{option}\" option has been deprecated and will be removed in Rubygems #{version_to_expire}."
+ else
+ "The \"#{option}\" option has been deprecated and will be removed in future versions of Rubygems."
+ end
+
+ extra_msg = deprecation["extra_msg"]
+
+ deprecate_option_msg += " #{extra_msg}" if extra_msg
+
+ alert_warning(deprecate_option_msg)
+ end
end
end
@@ -355,7 +418,7 @@ class Gem::Command
def merge_options(new_options)
@options = @defaults.clone
- new_options.each do |k,v| @options[k] = v end
+ new_options.each {|k,v| @options[k] = v }
end
##
@@ -376,6 +439,7 @@ class Gem::Command
def handle_options(args)
args = add_extra_args(args)
+ check_deprecated_options(args)
@options = Marshal.load Marshal.dump @defaults # deep copy
parser.parse!(args)
@options[:args] = args
@@ -393,7 +457,7 @@ class Gem::Command
until extra.empty? do
ex = []
ex << extra.shift
- ex << extra.shift if extra.first.to_s =~ /^[^-]/
+ ex << extra.shift if extra.first.to_s =~ /^[^-]/ # rubocop:disable Performance/StartWith
result << ex if handles?(ex)
end
@@ -402,8 +466,16 @@ class Gem::Command
result
end
+ def deprecated?
+ false
+ end
+
private
+ def option_is_deprecated?(option)
+ @deprecated_options[command].has_key?(option)
+ end
+
def add_parser_description # :nodoc:
return unless description
@@ -425,7 +497,7 @@ class Gem::Command
configure_options "", regular_options
- @option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list|
+ @option_groups.sort_by {|n,_| n.to_s }.each do |group_name, option_list|
@parser.separator nil
configure_options group_name, option_list
end
@@ -435,7 +507,7 @@ class Gem::Command
# Adds a section with +title+ and +content+ to the parser help view. Used
# for adding command arguments and default arguments.
- def add_parser_run_info title, content
+ def add_parser_run_info(title, content)
return if content.empty?
@parser.separator nil
@@ -468,7 +540,7 @@ class Gem::Command
# command.
def create_option_parser
- @parser = OptionParser.new
+ @parser = Gem::OptionParser.new
add_parser_options
@@ -488,7 +560,6 @@ class Gem::Command
@parser.separator " #{header}Options:"
option_list.each do |args, handler|
- args.select { |arg| arg =~ /^-/ }
@parser.on(*args) do |value|
handler.call(value, @options)
end
@@ -515,7 +586,7 @@ class Gem::Command
add_common_option('-V', '--[no-]verbose',
'Set the verbose level of output') do |value, options|
# Set us to "really verbose" so the progress meter works
- if Gem.configuration.verbose and value then
+ if Gem.configuration.verbose and value
Gem.configuration.verbose = 1
else
Gem.configuration.verbose = value
@@ -551,12 +622,10 @@ class Gem::Command
'Avoid loading any .gemrc file') do
end
-
# :stopdoc:
- HELP = <<-HELP
-RubyGems is a sophisticated package manager for Ruby. This is a
-basic help message containing pointers to more information.
+ HELP = <<-HELP.freeze
+RubyGems is a package manager for Ruby.
Usage:
gem -h/--help
@@ -567,6 +636,7 @@ basic help message containing pointers to more information.
gem install rake
gem list --local
gem build package.gemspec
+ gem push package-0.0.1.gem
gem help install
Further help:
@@ -580,11 +650,10 @@ basic help message containing pointers to more information.
http://localhost:8808/
with info about installed gems
Further information:
- http://guides.rubygems.org
+ https://guides.rubygems.org
HELP
# :startdoc:
-
end
##
diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb
index 887272378e..cb07757700 100644
--- a/lib/rubygems/command_manager.rb
+++ b/lib/rubygems/command_manager.rb
@@ -5,8 +5,9 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems/command'
-require 'rubygems/user_interaction'
+require_relative 'command'
+require_relative 'user_interaction'
+require_relative 'text'
##
# The command manager registers and installs all the individual sub-commands
@@ -31,7 +32,7 @@ require 'rubygems/user_interaction'
# See Gem::Command for instructions on writing gem commands.
class Gem::CommandManager
-
+ include Gem::Text
include Gem::UserInteraction
BUILTIN_COMMANDS = [ # :nodoc:
@@ -45,6 +46,7 @@ class Gem::CommandManager
:fetch,
:generate_index,
:help,
+ :info,
:install,
:list,
:lock,
@@ -68,7 +70,13 @@ class Gem::CommandManager
:update,
:which,
:yank,
- ]
+ ].freeze
+
+ ALIAS_COMMANDS = {
+ 'i' => 'install',
+ 'login' => 'signin',
+ 'logout' => 'signout',
+ }.freeze
##
# Return the authoritative instance of the command manager.
@@ -131,7 +139,7 @@ class Gem::CommandManager
# Return a sorted list of all command names as strings.
def command_names
- @commands.keys.collect {|key| key.to_s}.sort
+ @commands.keys.collect {|key| key.to_s }.sort
end
##
@@ -140,17 +148,17 @@ class Gem::CommandManager
def run(args, build_args=nil)
process_args(args, build_args)
rescue StandardError, Timeout::Error => ex
- alert_error "While executing gem ... (#{ex.class})\n #{ex}"
+ alert_error clean_text("While executing gem ... (#{ex.class})\n #{ex}")
ui.backtrace ex
terminate_interaction(1)
rescue Interrupt
- alert_error "Interrupted"
+ alert_error clean_text("Interrupted")
terminate_interaction(1)
end
def process_args(args, build_args=nil)
- if args.empty? then
+ if args.empty?
say Gem::Command::HELP
terminate_interaction 1
end
@@ -163,34 +171,42 @@ class Gem::CommandManager
say Gem::VERSION
terminate_interaction 0
when /^-/ then
- alert_error "Invalid option: #{args.first}. See 'gem --help'."
+ alert_error clean_text("Invalid option: #{args.first}. See 'gem --help'.")
terminate_interaction 1
else
cmd_name = args.shift.downcase
cmd = find_command cmd_name
+ cmd.deprecation_warning if cmd.deprecated?
cmd.invoke_with_build_args args, build_args
end
end
def find_command(cmd_name)
+ cmd_name = find_alias_command cmd_name
+
possibilities = find_command_possibilities cmd_name
- if possibilities.size > 1 then
+ if possibilities.size > 1
raise Gem::CommandLineError,
"Ambiguous command #{cmd_name} matches [#{possibilities.join(', ')}]"
- elsif possibilities.empty? then
+ elsif possibilities.empty?
raise Gem::CommandLineError, "Unknown command #{cmd_name}"
end
self[possibilities.first]
end
+ def find_alias_command(cmd_name)
+ alias_name = ALIAS_COMMANDS[cmd_name]
+ alias_name ? alias_name : cmd_name
+ end
+
def find_command_possibilities(cmd_name)
len = cmd_name.length
- found = command_names.select { |name| cmd_name == name[0, len] }
+ found = command_names.select {|name| cmd_name == name[0, len] }
- exact = found.find { |name| name == cmd_name }
+ exact = found.find {|name| name == cmd_name }
exact ? [exact] : found
end
@@ -212,10 +228,8 @@ class Gem::CommandManager
rescue Exception => e
e = load_error if load_error
- alert_error "Loading command: #{command_name} (#{e.class})\n\t#{e}"
+ alert_error clean_text("Loading command: #{command_name} (#{e.class})\n\t#{e}")
ui.backtrace e
end
end
-
end
-
diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb
index 38c45e46f0..6d1a057dfa 100644
--- a/lib/rubygems/commands/build_command.rb
+++ b/lib/rubygems/commands/build_command.rb
@@ -1,15 +1,31 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/package'
+require_relative '../command'
+require_relative '../package'
+require_relative '../version_option'
class Gem::Commands::BuildCommand < Gem::Command
+ include Gem::VersionOption
def initialize
super 'build', 'Build a gem from a gemspec'
+ add_platform_option
+
add_option '--force', 'skip validation of the spec' do |value, options|
options[:force] = true
end
+
+ add_option '--strict', 'consider warnings as errors when validating the spec' do |value, options|
+ options[:strict] = true
+ end
+
+ add_option '-o', '--output FILE', 'output gem with the given filename' do |value, options|
+ options[:output] = value
+ end
+
+ add_option '-C PATH', 'Run as if gem build was started in <PATH> instead of the current working directory.' do |value, options|
+ options[:build_path] = value
+ end
end
def arguments # :nodoc:
@@ -32,6 +48,11 @@ with gem spec:
$ cd my_gem-1.0
[edit gem contents]
$ gem build my_gem-1.0.gemspec
+
+Gems can be saved to a specified filename with the output option:
+
+ $ gem build my_gem-1.0.gemspec --output=release.gem
+
EOF
end
@@ -40,26 +61,72 @@ with gem spec:
end
def execute
- gemspec = get_one_gem_name
+ if build_path = options[:build_path]
+ Dir.chdir(build_path) { build_gem }
+ return
+ end
+
+ build_gem
+ end
+
+ private
- unless File.exist? gemspec
- gemspec += '.gemspec' if File.exist? gemspec + '.gemspec'
+ def find_gemspec(glob = "*.gemspec")
+ gemspecs = Dir.glob(glob).sort
+
+ if gemspecs.size > 1
+ alert_error "Multiple gemspecs found: #{gemspecs}, please specify one"
+ terminate_interaction(1)
end
- if File.exist? gemspec then
- spec = Gem::Specification.load gemspec
+ gemspecs.first
+ end
+
+ def build_gem
+ gemspec = resolve_gem_name
+
+ if gemspec
+ build_package(gemspec)
+ else
+ alert_error error_message
+ terminate_interaction(1)
+ end
+ end
- if spec then
- Gem::Package.build spec, options[:force]
- else
- alert_error "Error loading gemspec. Aborting."
- terminate_interaction 1
- end
+ def build_package(gemspec)
+ spec = Gem::Specification.load(gemspec)
+ if spec
+ Gem::Package.build(
+ spec,
+ options[:force],
+ options[:strict],
+ options[:output]
+ )
else
- alert_error "Gemspec file not found: #{gemspec}"
+ alert_error "Error loading gemspec. Aborting."
terminate_interaction 1
end
end
-end
+ def resolve_gem_name
+ return find_gemspec unless gem_name
+
+ if File.exist?(gem_name)
+ gem_name
+ else
+ find_gemspec("#{gem_name}.gemspec") || find_gemspec(gem_name)
+ end
+ end
+
+ def error_message
+ if gem_name
+ "Couldn't find a gemspec file matching '#{gem_name}' in #{Dir.pwd}"
+ else
+ "Couldn't find a gemspec file in #{Dir.pwd}"
+ end
+ end
+ def gem_name
+ get_one_optional_argument
+ end
+end
diff --git a/lib/rubygems/commands/cert_command.rb b/lib/rubygems/commands/cert_command.rb
index 5542262a50..b59564d575 100644
--- a/lib/rubygems/commands/cert_command.rb
+++ b/lib/rubygems/commands/cert_command.rb
@@ -1,49 +1,15 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/security'
-begin
- require 'openssl'
-rescue LoadError => e
- raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
- e.message =~ / -- openssl$/
-end
+require_relative '../command'
+require_relative '../security'
class Gem::Commands::CertCommand < Gem::Command
-
def initialize
super 'cert', 'Manage RubyGems certificates and signing settings',
:add => [], :remove => [], :list => [], :build => [], :sign => []
- OptionParser.accept OpenSSL::X509::Certificate do |certificate|
- begin
- OpenSSL::X509::Certificate.new File.read certificate
- rescue Errno::ENOENT
- raise OptionParser::InvalidArgument, "#{certificate}: does not exist"
- rescue OpenSSL::X509::CertificateError
- raise OptionParser::InvalidArgument,
- "#{certificate}: invalid X509 certificate"
- end
- end
-
- OptionParser.accept OpenSSL::PKey::RSA do |key_file|
- begin
- passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
- key = OpenSSL::PKey::RSA.new File.read(key_file), passphrase
- rescue Errno::ENOENT
- raise OptionParser::InvalidArgument, "#{key_file}: does not exist"
- rescue OpenSSL::PKey::RSAError
- raise OptionParser::InvalidArgument, "#{key_file}: invalid RSA key"
- end
-
- raise OptionParser::InvalidArgument,
- "#{key_file}: private key not found" unless key.private?
-
- key
- end
-
- add_option('-a', '--add CERT', OpenSSL::X509::Certificate,
- 'Add a trusted certificate.') do |cert, options|
- options[:add] << cert
+ add_option('-a', '--add CERT',
+ 'Add a trusted certificate.') do |cert_file, options|
+ options[:add] << open_cert(cert_file)
end
add_option('-l', '--list [FILTER]',
@@ -66,20 +32,26 @@ class Gem::Commands::CertCommand < Gem::Command
options[:build] << email_address
end
- add_option('-C', '--certificate CERT', OpenSSL::X509::Certificate,
- 'Signing certificate for --sign') do |cert, options|
- options[:issuer_cert] = cert
+ add_option('-C', '--certificate CERT',
+ 'Signing certificate for --sign') do |cert_file, options|
+ options[:issuer_cert] = open_cert(cert_file)
+ options[:issuer_cert_file] = cert_file
+ end
+
+ add_option('-K', '--private-key KEY',
+ 'Key for --sign or --build') do |key_file, options|
+ options[:key] = open_private_key(key_file)
end
- add_option('-K', '--private-key KEY', OpenSSL::PKey::RSA,
- 'Key for --sign or --build') do |key, options|
- options[:key] = key
+ add_option('-A', '--key-algorithm ALGORITHM',
+ 'Select which key algorithm to use for --build') do |algorithm, options|
+ options[:key_algorithm] = algorithm
end
add_option('-s', '--sign CERT',
'Signs CERT with the key from -K',
'and the certificate from -C') do |cert_file, options|
- raise OptionParser::InvalidArgument, "#{cert_file}: does not exist" unless
+ raise Gem::OptionParser::InvalidArgument, "#{cert_file}: does not exist" unless
File.file? cert_file
options[:sign] << cert_file
@@ -87,17 +59,54 @@ class Gem::Commands::CertCommand < Gem::Command
add_option('-d', '--days NUMBER_OF_DAYS',
'Days before the certificate expires') do |days, options|
- options[:expiration_length_days] = days.to_i
+ options[:expiration_length_days] = days.to_i
+ end
+
+ add_option('-R', '--re-sign',
+ 'Re-signs the certificate from -C with the key from -K') do |resign, options|
+ options[:resign] = resign
end
end
- def add_certificate certificate # :nodoc:
+ def add_certificate(certificate) # :nodoc:
Gem::Security.trust_dir.trust_cert certificate
say "Added '#{certificate.subject}'"
end
+ def check_openssl
+ return if Gem::HAVE_OPENSSL
+
+ alert_error "OpenSSL library is required for the cert command"
+ terminate_interaction 1
+ end
+
+ def open_cert(certificate_file)
+ check_openssl
+ OpenSSL::X509::Certificate.new File.read certificate_file
+ rescue Errno::ENOENT
+ raise Gem::OptionParser::InvalidArgument, "#{certificate_file}: does not exist"
+ rescue OpenSSL::X509::CertificateError
+ raise Gem::OptionParser::InvalidArgument,
+ "#{certificate_file}: invalid X509 certificate"
+ end
+
+ def open_private_key(key_file)
+ check_openssl
+ passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
+ key = OpenSSL::PKey.read File.read(key_file), passphrase
+ raise Gem::OptionParser::InvalidArgument,
+ "#{key_file}: private key not found" unless key.private?
+ key
+ rescue Errno::ENOENT
+ raise Gem::OptionParser::InvalidArgument, "#{key_file}: does not exist"
+ rescue OpenSSL::PKey::PKeyError, ArgumentError
+ raise Gem::OptionParser::InvalidArgument, "#{key_file}: invalid RSA, DSA, or EC key"
+ end
+
def execute
+ check_openssl
+
options[:add].each do |certificate|
add_certificate certificate
end
@@ -114,10 +123,18 @@ class Gem::Commands::CertCommand < Gem::Command
build email
end
+ if options[:resign]
+ re_sign_cert(
+ options[:issuer_cert],
+ options[:issuer_cert_file],
+ options[:key]
+ )
+ end
+
sign_certificates unless options[:sign].empty?
end
- def build email
+ def build(email)
if !valid_email?(email)
raise Gem::CommandLineError, "Invalid email address #{email}"
end
@@ -133,16 +150,16 @@ class Gem::Commands::CertCommand < Gem::Command
end
end
- def build_cert email, key # :nodoc:
- expiration_length_days = options[:expiration_length_days]
- age =
- if expiration_length_days.nil? || expiration_length_days == 0
- Gem::Security::ONE_YEAR
- else
- Gem::Security::ONE_DAY * expiration_length_days
- end
+ def build_cert(email, key) # :nodoc:
+ expiration_length_days = options[:expiration_length_days] ||
+ Gem.configuration.cert_expiration_length_days
+
+ cert = Gem::Security.create_cert_email(
+ email,
+ key,
+ (Gem::Security::ONE_DAY * expiration_length_days)
+ )
- cert = Gem::Security.create_cert_email email, key, age
Gem::Security.write cert, "gem-public_cert.pem"
end
@@ -158,20 +175,21 @@ class Gem::Commands::CertCommand < Gem::Command
raise Gem::CommandLineError,
"Passphrase and passphrase confirmation don't match" unless passphrase == passphrase_confirmation
- key = Gem::Security.create_key
+ algorithm = options[:key_algorithm] || Gem::Security::DEFAULT_KEY_ALGORITHM
+ key = Gem::Security.create_key(algorithm)
key_path = Gem::Security.write key, "gem-private_key.pem", 0600, passphrase
return key, key_path
end
- def certificates_matching filter
+ def certificates_matching(filter)
return enum_for __method__, filter unless block_given?
Gem::Security.trusted_certificates.select do |certificate, _|
subject = certificate.subject.to_s
subject.downcase.index filter
end.sort_by do |certificate, _|
- certificate.subject.to_a.map { |name, data,| [name, data] }
+ certificate.subject.to_a.map {|name, data,| [name, data] }
end.each do |certificate, path|
yield certificate, path
end
@@ -216,7 +234,7 @@ For further reading on signing gems see `ri Gem::Security`.
EOF
end
- def list_certificates_matching filter # :nodoc:
+ def list_certificates_matching(filter) # :nodoc:
certificates_matching filter do |certificate, _|
# this could probably be formatted more gracefully
say certificate.subject.to_s
@@ -243,13 +261,14 @@ For further reading on signing gems see `ri Gem::Security`.
key_file = File.join Gem.default_key_path
key = File.read key_file
passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
- options[:key] = OpenSSL::PKey::RSA.new key, passphrase
+ options[:key] = OpenSSL::PKey.read key, passphrase
+
rescue Errno::ENOENT
alert_error \
"--private-key not specified and ~/.gem/gem-private_key.pem does not exist"
terminate_interaction 1
- rescue OpenSSL::PKey::RSAError
+ rescue OpenSSL::PKey::PKeyError
alert_error \
"--private-key not specified and ~/.gem/gem-private_key.pem is not valid"
@@ -261,14 +280,14 @@ For further reading on signing gems see `ri Gem::Security`.
load_default_key unless options[:key]
end
- def remove_certificates_matching filter # :nodoc:
+ def remove_certificates_matching(filter) # :nodoc:
certificates_matching filter do |certificate, path|
FileUtils.rm path
say "Removed '#{certificate.subject}'"
end
end
- def sign cert_file
+ def sign(cert_file)
cert = File.read cert_file
cert = OpenSSL::X509::Certificate.new cert
@@ -290,13 +309,17 @@ For further reading on signing gems see `ri Gem::Security`.
end
end
+ def re_sign_cert(cert, cert_path, private_key)
+ Gem::Security::Signer.re_sign_cert(cert, cert_path, private_key) do |expired_cert_path, new_expired_cert_path|
+ alert("Your certificate #{expired_cert_path} has been re-signed")
+ alert("Your expired certificate will be located at: #{new_expired_cert_path}")
+ end
+ end
+
private
- def valid_email? email
+ def valid_email?(email)
# It's simple, but is all we need
email =~ /\A.+@.+\z/
end
-
-
-end if defined?(OpenSSL::SSL)
-
+end
diff --git a/lib/rubygems/commands/check_command.rb b/lib/rubygems/commands/check_command.rb
index 818cb05f55..3b6b97ae3b 100644
--- a/lib/rubygems/commands/check_command.rb
+++ b/lib/rubygems/commands/check_command.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/version_option'
-require 'rubygems/validator'
-require 'rubygems/doctor'
+require_relative '../command'
+require_relative '../version_option'
+require_relative '../validator'
+require_relative '../doctor'
class Gem::Commands::CheckCommand < Gem::Command
-
include Gem::VersionOption
def initialize
@@ -44,7 +43,7 @@ class Gem::Commands::CheckCommand < Gem::Command
gems = get_all_gem_names rescue []
Gem::Validator.new.alien(gems).sort.each do |key, val|
- unless val.empty? then
+ unless val.empty?
say "#{key} has #{val.size} problems"
val.each do |error_entry|
say " #{error_entry.path}:"
@@ -90,5 +89,4 @@ specifications and will clean up gems that have been partially uninstalled.
def usage # :nodoc:
"#{program_name} [OPTIONS] [GEMNAME ...]"
end
-
end
diff --git a/lib/rubygems/commands/cleanup_command.rb b/lib/rubygems/commands/cleanup_command.rb
index db1bf3a794..c965085880 100644
--- a/lib/rubygems/commands/cleanup_command.rb
+++ b/lib/rubygems/commands/cleanup_command.rb
@@ -1,19 +1,37 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/dependency_list'
-require 'rubygems/uninstaller'
+require_relative '../command'
+require_relative '../dependency_list'
+require_relative '../uninstaller'
class Gem::Commands::CleanupCommand < Gem::Command
-
def initialize
super 'cleanup',
'Clean up old versions of installed gems',
- :force => false, :install_dir => Gem.dir
+ :force => false, :install_dir => Gem.dir,
+ :check_dev => true
+
+ add_option('-n', '-d', '--dry-run',
+ 'Do not uninstall gems') do |value, options|
+ options[:dryrun] = true
+ end
- add_option('-n', '-d', '--dryrun',
+ add_option(:Deprecated, '--dryrun',
'Do not uninstall gems') do |value, options|
options[:dryrun] = true
end
+ deprecate_option('--dryrun', extra_msg: 'Use --dry-run instead')
+
+ add_option('-D', '--[no-]check-development',
+ 'Check development dependencies while uninstalling',
+ '(default: true)') do |value, options|
+ options[:check_dev] = value
+ end
+
+ add_option('--[no-]user-install',
+ 'Cleanup in user\'s home directory instead',
+ 'of GEM_HOME.') do |value, options|
+ options[:user_install] = value
+ end
@candidate_gems = nil
@default_gems = []
@@ -29,7 +47,7 @@ class Gem::Commands::CleanupCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--no-dryrun"
+ "--no-dry-run"
end
def description # :nodoc:
@@ -49,14 +67,14 @@ If no gems are named all gems in GEM_HOME are cleaned.
def execute
say "Cleaning up installed gems..."
- if options[:args].empty? then
+ if options[:args].empty?
done = false
last_set = nil
until done do
clean_gems
- this_set = @gems_to_cleanup.map { |spec| spec.full_name }.sort
+ this_set = @gems_to_cleanup.map {|spec| spec.full_name }.sort
done = this_set.empty? || last_set == this_set
@@ -69,7 +87,7 @@ If no gems are named all gems in GEM_HOME are cleaned.
say "Clean up complete"
verbose do
- skipped = @default_gems.map { |spec| spec.full_name }
+ skipped = @default_gems.map {|spec| spec.full_name }
"Skipped default gems: #{skipped.join ', '}"
end
@@ -86,7 +104,7 @@ If no gems are named all gems in GEM_HOME are cleaned.
@full = Gem::DependencyList.from_specs
deplist = Gem::DependencyList.new
- @gems_to_cleanup.each do |spec| deplist.add spec end
+ @gems_to_cleanup.each {|spec| deplist.add spec }
deps = deplist.strongly_connected_components.flatten
@@ -98,7 +116,7 @@ If no gems are named all gems in GEM_HOME are cleaned.
end
def get_candidate_gems
- @candidate_gems = unless options[:args].empty? then
+ @candidate_gems = unless options[:args].empty?
options[:args].map do |gem_name|
Gem::Specification.find_all_by_name gem_name
end.flatten
@@ -108,18 +126,19 @@ If no gems are named all gems in GEM_HOME are cleaned.
end
def get_gems_to_cleanup
-
- gems_to_cleanup = @candidate_gems.select { |spec|
+ gems_to_cleanup = @candidate_gems.select do |spec|
@primary_gems[spec.name].version != spec.version
- }
+ end
- default_gems, gems_to_cleanup = gems_to_cleanup.partition { |spec|
+ default_gems, gems_to_cleanup = gems_to_cleanup.partition do |spec|
spec.default_gem?
- }
+ end
- gems_to_cleanup = gems_to_cleanup.select { |spec|
- spec.base_dir == @original_home
- }
+ uninstall_from = options[:user_install] ? Gem.user_dir : @original_home
+
+ gems_to_cleanup = gems_to_cleanup.select do |spec|
+ spec.base_dir == uninstall_from
+ end
@default_gems += default_gems
@default_gems.uniq!
@@ -131,16 +150,16 @@ If no gems are named all gems in GEM_HOME are cleaned.
Gem::Specification.each do |spec|
if @primary_gems[spec.name].nil? or
- @primary_gems[spec.name].version < spec.version then
+ @primary_gems[spec.name].version < spec.version
@primary_gems[spec.name] = spec
end
end
end
- def uninstall_dep spec
- return unless @full.ok_to_remove?(spec.full_name)
+ def uninstall_dep(spec)
+ return unless @full.ok_to_remove?(spec.full_name, options[:check_dev])
- if options[:dryrun] then
+ if options[:dryrun]
say "Dry Run Mode: Would uninstall #{spec.full_name}"
return
end
@@ -167,5 +186,4 @@ If no gems are named all gems in GEM_HOME are cleaned.
# Restore path Gem::Uninstaller may have changed
Gem.use_paths @original_home, *@original_path
end
-
end
diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb
index e0f2eedb5d..716022c458 100644
--- a/lib/rubygems/commands/contents_command.rb
+++ b/lib/rubygems/commands/contents_command.rb
@@ -1,10 +1,8 @@
# frozen_string_literal: true
-require 'English'
-require 'rubygems/command'
-require 'rubygems/version_option'
+require_relative '../command'
+require_relative '../version_option'
class Gem::Commands::ContentsCommand < Gem::Command
-
include Gem::VersionOption
def initialize
@@ -14,7 +12,7 @@ class Gem::Commands::ContentsCommand < Gem::Command
add_version_option
- add_option( '--all',
+ add_option('--all',
"Contents for all gems") do |all, options|
options[:all] = all
end
@@ -29,12 +27,12 @@ class Gem::Commands::ContentsCommand < Gem::Command
options[:lib_only] = lib_only
end
- add_option( '--[no-]prefix',
+ add_option('--[no-]prefix',
"Don't include installed path prefix") do |prefix, options|
options[:prefix] = prefix
end
- add_option( '--[no-]show-install-dir',
+ add_option('--[no-]show-install-dir',
'Show only the gem install dir') do |show, options|
options[:show_install_dir] = show
end
@@ -73,7 +71,7 @@ prefix or only the files that are requireable.
names.each do |name|
found =
- if options[:show_install_dir] then
+ if options[:show_install_dir]
gem_install_dir name
else
gem_contents name
@@ -83,15 +81,15 @@ prefix or only the files that are requireable.
end
end
- def files_in spec
- if spec.default_gem? then
+ def files_in(spec)
+ if spec.default_gem?
files_in_default_gem spec
else
files_in_gem spec
end
end
- def files_in_gem spec
+ def files_in_gem(spec)
gem_path = spec.full_gem_path
extra = "/{#{spec.require_paths.join ','}}" if options[:lib_only]
glob = "#{gem_path}#{extra}/**/*"
@@ -102,11 +100,12 @@ prefix or only the files that are requireable.
end
end
- def files_in_default_gem spec
+ def files_in_default_gem(spec)
spec.files.map do |file|
case file
when /\A#{spec.bindir}\//
- [RbConfig::CONFIG['bindir'], $POSTMATCH]
+ # $' is POSTMATCH
+ [RbConfig::CONFIG['bindir'], $']
when /\.so\z/
[RbConfig::CONFIG['archdir'], file]
else
@@ -115,7 +114,7 @@ prefix or only the files that are requireable.
end
end
- def gem_contents name
+ def gem_contents(name)
spec = spec_for name
return false unless spec
@@ -127,7 +126,7 @@ prefix or only the files that are requireable.
true
end
- def gem_install_dir name
+ def gem_install_dir(name)
spec = spec_for name
return false unless spec
@@ -138,27 +137,27 @@ prefix or only the files that are requireable.
end
def gem_names # :nodoc:
- if options[:all] then
+ if options[:all]
Gem::Specification.map(&:name)
else
get_all_gem_names
end
end
- def path_description spec_dirs # :nodoc:
- if spec_dirs.empty? then
+ def path_description(spec_dirs) # :nodoc:
+ if spec_dirs.empty?
"default gem paths"
else
"specified path"
end
end
- def show_files files
+ def show_files(files)
files.sort.each do |prefix, basename|
absolute_path = File.join(prefix, basename)
next if File.directory? absolute_path
- if options[:prefix] then
+ if options[:prefix]
say absolute_path
else
say basename
@@ -166,16 +165,16 @@ prefix or only the files that are requireable.
end
end
- def spec_for name
- spec = Gem::Specification.find_all_by_name(name, @version).last
+ def spec_for(name)
+ spec = Gem::Specification.find_all_by_name(name, @version).first
return spec if spec
say "Unable to find gem '#{name}' in #{@path_kind}"
- if Gem.configuration.verbose then
+ if Gem.configuration.verbose
say "\nDirectories searched:"
- @spec_dirs.sort.each { |dir| say dir }
+ @spec_dirs.sort.each {|dir| say dir }
end
return nil
@@ -186,6 +185,4 @@ prefix or only the files that are requireable.
[i, File.join(i, "specifications")]
end.flatten
end
-
end
-
diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb
index 97fd812ffa..7d217076a5 100644
--- a/lib/rubygems/commands/dependency_command.rb
+++ b/lib/rubygems/commands/dependency_command.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/version_option'
+require_relative '../command'
+require_relative '../local_remote_options'
+require_relative '../version_option'
class Gem::Commands::DependencyCommand < Gem::Command
-
include Gem::LocalRemoteOptions
include Gem::VersionOption
@@ -54,19 +53,19 @@ use with other commands.
"#{program_name} REGEXP"
end
- def fetch_remote_specs dependency # :nodoc:
+ def fetch_remote_specs(dependency) # :nodoc:
fetcher = Gem::SpecFetcher.fetcher
ss, = fetcher.spec_for_dependency dependency
- ss.map { |spec, _| spec }
+ ss.map {|spec, _| spec }
end
- def fetch_specs name_pattern, dependency # :nodoc:
+ def fetch_specs(name_pattern, dependency) # :nodoc:
specs = []
if local?
- specs.concat Gem::Specification.stubs.find_all { |spec|
+ specs.concat Gem::Specification.stubs.find_all {|spec|
name_pattern =~ spec.name and
dependency.requirement.satisfied_by? spec.version
}.map(&:to_spec)
@@ -79,32 +78,32 @@ use with other commands.
specs.uniq.sort
end
- def gem_dependency pattern, version, prerelease # :nodoc:
- dependency = Gem::Deprecate.skip_during {
+ def gem_dependency(pattern, version, prerelease) # :nodoc:
+ dependency = Gem::Deprecate.skip_during do
Gem::Dependency.new pattern, version
- }
+ end
dependency.prerelease = prerelease
dependency
end
- def display_pipe specs # :nodoc:
+ def display_pipe(specs) # :nodoc:
specs.each do |spec|
- unless spec.dependencies.empty? then
- spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
+ unless spec.dependencies.empty?
+ spec.dependencies.sort_by {|dep| dep.name }.each do |dep|
say "#{dep.name} --version '#{dep.requirement}'"
end
end
end
end
- def display_readable specs, reverse # :nodoc:
+ def display_readable(specs, reverse) # :nodoc:
response = String.new
specs.each do |spec|
response << print_dependencies(spec)
- unless reverse[spec.full_name].empty? then
+ unless reverse[spec.full_name].empty?
response << " Used by\n"
reverse[spec.full_name].each do |sp, dep|
response << " #{sp} (#{dep})\n"
@@ -128,7 +127,7 @@ use with other commands.
reverse = reverse_dependencies specs
- if options[:pipe_format] then
+ if options[:pipe_format]
display_pipe specs
else
display_readable specs, reverse
@@ -136,13 +135,13 @@ use with other commands.
end
def ensure_local_only_reverse_dependencies # :nodoc:
- if options[:reverse_dependencies] and remote? and not local? then
+ if options[:reverse_dependencies] and remote? and not local?
alert_error 'Only reverse dependencies for local gems are supported.'
terminate_interaction 1
end
end
- def ensure_specs specs # :nodoc:
+ def ensure_specs(specs) # :nodoc:
return unless specs.empty?
patterns = options[:args].join ','
@@ -155,24 +154,24 @@ use with other commands.
def print_dependencies(spec, level = 0) # :nodoc:
response = String.new
response << ' ' * level + "Gem #{spec.full_name}\n"
- unless spec.dependencies.empty? then
- spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
+ unless spec.dependencies.empty?
+ spec.dependencies.sort_by {|dep| dep.name }.each do |dep|
response << ' ' * level + " #{dep}\n"
end
end
response
end
- def remote_specs dependency # :nodoc:
+ def remote_specs(dependency) # :nodoc:
fetcher = Gem::SpecFetcher.fetcher
ss, _ = fetcher.spec_for_dependency dependency
- ss.map { |s,o| s }
+ ss.map {|s,o| s }
end
- def reverse_dependencies specs # :nodoc:
- reverse = Hash.new { |h, k| h[k] = [] }
+ def reverse_dependencies(specs) # :nodoc:
+ reverse = Hash.new {|h, k| h[k] = [] }
return reverse unless options[:reverse_dependencies]
@@ -186,7 +185,7 @@ use with other commands.
##
# Returns an Array of [specification, dep] that are satisfied by +spec+.
- def find_reverse_dependencies spec # :nodoc:
+ def find_reverse_dependencies(spec) # :nodoc:
result = []
Gem::Specification.each do |sp|
@@ -194,7 +193,7 @@ use with other commands.
dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep
if spec.name == dep.name and
- dep.requirement.satisfied_by?(spec.version) then
+ dep.requirement.satisfied_by?(spec.version)
result << [sp.full_name, dep]
end
end
@@ -205,10 +204,10 @@ use with other commands.
private
- def name_pattern args
+ def name_pattern(args)
args << '' if args.empty?
- if args.length == 1 and args.first =~ /\A\/(.*)\/(i)?\z/m then
+ if args.length == 1 and args.first =~ /\A(.*)(i)?\z/m
flags = $2 ? Regexp::IGNORECASE : nil
Regexp.new $1, flags
else
diff --git a/lib/rubygems/commands/environment_command.rb b/lib/rubygems/commands/environment_command.rb
index e825c761ad..b6eeb620bd 100644
--- a/lib/rubygems/commands/environment_command.rb
+++ b/lib/rubygems/commands/environment_command.rb
@@ -1,15 +1,13 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
class Gem::Commands::EnvironmentCommand < Gem::Command
-
def initialize
super 'environment', 'Display information about the RubyGems environment'
end
def arguments # :nodoc:
args = <<-EOF
- packageversion display the package version
gemdir display the path where gems are installed
gempath display path used to search for gems
version display the gem format version
@@ -76,8 +74,6 @@ lib/rubygems/defaults/operating_system.rb
arg = options[:args][0]
out <<
case arg
- when /^packageversion/ then
- Gem::RubyGemsPackageVersion
when /^version/ then
Gem::VERSION
when /^gemdir/, /^gemhome/, /^home/, /^GEM_HOME/ then
@@ -97,7 +93,7 @@ lib/rubygems/defaults/operating_system.rb
true
end
- def add_path out, path
+ def add_path(out, path)
path.each do |component|
out << " - #{component}\n"
end
@@ -120,6 +116,8 @@ lib/rubygems/defaults/operating_system.rb
out << " - RUBY EXECUTABLE: #{Gem.ruby}\n"
+ out << " - GIT EXECUTABLE: #{git_path}\n"
+
out << " - EXECUTABLE DIRECTORY: #{Gem.bindir}\n"
out << " - SPEC CACHE DIRECTORY: #{Gem.spec_cache_dir}\n"
@@ -128,7 +126,7 @@ lib/rubygems/defaults/operating_system.rb
out << " - RUBYGEMS PLATFORMS:\n"
Gem.platforms.each do |platform|
- out << " - #{platform}\n"
+ out << " - #{platform}\n"
end
out << " - GEM PATHS:\n"
@@ -157,4 +155,20 @@ lib/rubygems/defaults/operating_system.rb
out
end
+ private
+
+ ##
+ # Git binary path
+
+ def git_path
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
+ ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
+ exts.each do |ext|
+ exe = File.join(path, "git#{ext}")
+ return exe if File.executable?(exe) && !File.directory?(exe)
+ end
+ end
+
+ return nil
+ end
end
diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb
index 19559a7774..373851643d 100644
--- a/lib/rubygems/commands/fetch_command.rb
+++ b/lib/rubygems/commands/fetch_command.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/version_option'
+require_relative '../command'
+require_relative '../local_remote_options'
+require_relative '../version_option'
class Gem::Commands::FetchCommand < Gem::Command
-
include Gem::LocalRemoteOptions
include Gem::VersionOption
@@ -56,14 +55,14 @@ then repackaging it.
specs_and_sources, errors =
Gem::SpecFetcher.fetcher.spec_for_dependency dep
- if platform then
- filtered = specs_and_sources.select { |s,| s.platform == platform }
+ if platform
+ filtered = specs_and_sources.select {|s,| s.platform == platform }
specs_and_sources = filtered unless filtered.empty?
end
- spec, source = specs_and_sources.max_by { |s,| s.version }
+ spec, source = specs_and_sources.max_by {|s,| s }
- if spec.nil? then
+ if spec.nil?
show_lookup_failure gem_name, version, errors, options[:domain]
next
end
@@ -73,6 +72,4 @@ then repackaging it.
say "Downloaded #{spec.full_name}"
end
end
-
end
-
diff --git a/lib/rubygems/commands/generate_index_command.rb b/lib/rubygems/commands/generate_index_command.rb
index 01f1f88405..87200dab91 100644
--- a/lib/rubygems/commands/generate_index_command.rb
+++ b/lib/rubygems/commands/generate_index_command.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/indexer'
+require_relative '../command'
+require_relative '../indexer'
##
# Generates a index files for use as a gem server.
@@ -8,7 +8,6 @@ require 'rubygems/indexer'
# See `gem help generate_index`
class Gem::Commands::GenerateIndexCommand < Gem::Command
-
def initialize
super 'generate_index',
'Generates the index files for a gem server directory',
@@ -25,6 +24,9 @@ class Gem::Commands::GenerateIndexCommand < Gem::Command
options[:build_modern] = value
end
+ deprecate_option('--modern', version: '4.0', extra_msg: 'Modern indexes (specs, latest_specs, and prerelease_specs) are always generated, so this option is not needed.')
+ deprecate_option('--no-modern', version: '4.0', extra_msg: 'The `--no-modern` option is currently ignored. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated.')
+
add_option '--update',
'Update modern indexes with gems added',
'since the last update' do |value, options|
@@ -67,19 +69,17 @@ Marshal::MINOR_VERSION constants. It is used to ensure compatibility.
options[:build_modern] = true
if not File.exist?(options[:directory]) or
- not File.directory?(options[:directory]) then
- alert_error "unknown directory name #{directory}."
+ not File.directory?(options[:directory])
+ alert_error "unknown directory name #{options[:directory]}."
terminate_interaction 1
else
indexer = Gem::Indexer.new options.delete(:directory), options
- if options[:update] then
+ if options[:update]
indexer.update_index
else
indexer.generate_index
end
end
end
-
end
-
diff --git a/lib/rubygems/commands/help_command.rb b/lib/rubygems/commands/help_command.rb
index 7d02022369..7f3383c9f3 100644
--- a/lib/rubygems/commands/help_command.rb
+++ b/lib/rubygems/commands/help_command.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
class Gem::Commands::HelpCommand < Gem::Command
-
# :stopdoc:
- EXAMPLES = <<-EOF
+ EXAMPLES = <<-EOF.freeze
Some examples of 'gem' usage.
* Install 'rake', either from local directory or remote server:
@@ -38,7 +37,7 @@ Some examples of 'gem' usage.
* Create a gem:
- See http://guides.rubygems.org/make-your-own-gem/
+ See https://guides.rubygems.org/make-your-own-gem/
* See information about RubyGems:
@@ -53,7 +52,7 @@ Some examples of 'gem' usage.
gem update --system
EOF
- GEM_DEPENDENCIES = <<-EOF
+ GEM_DEPENDENCIES = <<-EOF.freeze
A gem dependencies file allows installation of a consistent set of gems across
multiple environments. The RubyGems implementation is designed to be
compatible with Bundler's Gemfile format. You can see additional
@@ -230,7 +229,7 @@ default. This may be overridden with the :development_group option:
EOF
- PLATFORMS = <<-'EOF'
+ PLATFORMS = <<-'EOF'.freeze
RubyGems platforms are composed of three parts, a CPU, an OS, and a
version. These values are taken from values in rbconfig.rb. You can view
your current platform by running `gem environment`.
@@ -277,7 +276,7 @@ platform.
["examples", EXAMPLES],
["gem_dependencies", GEM_DEPENDENCIES],
["platforms", PLATFORMS],
- ]
+ ].freeze
# :startdoc:
def initialize
@@ -297,8 +296,8 @@ platform.
begins? command, arg
end
- if help then
- if Symbol === help then
+ if help
+ if Symbol === help
send help
else
say help
@@ -306,10 +305,10 @@ platform.
return
end
- if options[:help] then
+ if options[:help]
show_help
- elsif arg then
+ elsif arg
show_command_help arg
else
@@ -324,7 +323,7 @@ platform.
margin_width = 4
- desc_width = @command_manager.command_names.map { |n| n.size }.max + 4
+ desc_width = @command_manager.command_names.map {|n| n.size }.max + 4
summary_width = 80 - margin_width - desc_width
wrap_indent = ' ' * (margin_width + desc_width)
@@ -333,8 +332,10 @@ platform.
@command_manager.command_names.each do |cmd_name|
command = @command_manager[cmd_name]
+ next if command.deprecated?
+
summary =
- if command then
+ if command
command.summary
else
"[No command found for #{cmd_name}]"
@@ -356,20 +357,18 @@ platform.
say out.join("\n")
end
- def show_command_help command_name # :nodoc:
+ def show_command_help(command_name) # :nodoc:
command_name = command_name.downcase
possibilities = @command_manager.find_command_possibilities command_name
- if possibilities.size == 1 then
+ if possibilities.size == 1
command = @command_manager[possibilities.first]
command.invoke("--help")
- elsif possibilities.size > 1 then
+ elsif possibilities.size > 1
alert_warning "Ambiguous command #{command_name} (#{possibilities.join(', ')})"
else
alert_warning "Unknown command #{command_name}. Try: gem help commands"
end
end
-
end
-
diff --git a/lib/rubygems/commands/info_command.rb b/lib/rubygems/commands/info_command.rb
new file mode 100644
index 0000000000..3f2dd4ae0b
--- /dev/null
+++ b/lib/rubygems/commands/info_command.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require_relative '../command'
+require_relative '../query_utils'
+
+class Gem::Commands::InfoCommand < Gem::Command
+ include Gem::QueryUtils
+
+ def initialize
+ super "info", "Show information for the given gem",
+ :name => //, :domain => :local, :details => false, :versions => true,
+ :installed => nil, :version => Gem::Requirement.default
+
+ add_query_options
+
+ remove_option('-d')
+
+ defaults[:details] = true
+ defaults[:exact] = true
+ end
+
+ def description # :nodoc:
+ "Info prints information about the gem such as name,"\
+ " description, website, license and installed paths"
+ end
+
+ def usage # :nodoc:
+ "#{program_name} GEMNAME"
+ end
+
+ def arguments # :nodoc:
+ "GEMNAME name of the gem to print information about"
+ end
+
+ def defaults_str
+ "--local"
+ end
+end
diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb
index 3a7d50517f..7af5060129 100644
--- a/lib/rubygems/commands/install_command.rb
+++ b/lib/rubygems/commands/install_command.rb
@@ -1,10 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/install_update_options'
-require 'rubygems/dependency_installer'
-require 'rubygems/local_remote_options'
-require 'rubygems/validator'
-require 'rubygems/version_option'
+require_relative '../command'
+require_relative '../install_update_options'
+require_relative '../dependency_installer'
+require_relative '../local_remote_options'
+require_relative '../validator'
+require_relative '../version_option'
##
# Gem installer command line tool
@@ -12,7 +12,6 @@ require 'rubygems/version_option'
# See `gem help install`
class Gem::Commands::InstallCommand < Gem::Command
-
attr_reader :installed_specs # :nodoc:
include Gem::VersionOption
@@ -117,15 +116,22 @@ to write the specification by hand. For example:
some_extension_gem (1.0)
$
+Command Alias
+==========================
+
+You can use `i` command instead of `install`.
+
+ $ gem i GEMNAME
+
EOF
end
def usage # :nodoc:
- "#{program_name} GEMNAME [GEMNAME ...] [options] -- --build-flags"
+ "#{program_name} [options] GEMNAME [GEMNAME ...] -- --build-flags"
end
def check_install_dir # :nodoc:
- if options[:install_dir] and options[:user_install] then
+ if options[:install_dir] and options[:user_install]
alert_error "Use --install-dir or --user-install but not both"
terminate_interaction 1
end
@@ -133,22 +139,22 @@ to write the specification by hand. For example:
def check_version # :nodoc:
if options[:version] != Gem::Requirement.default and
- get_all_gem_names.size > 1 then
- alert_error "Can't use --version w/ multiple gems. Use name:ver instead."
+ get_all_gem_names.size > 1
+ alert_error "Can't use --version with multiple gems. You can specify multiple gems with" \
+ " version requirements using `gem install 'my_gem:1.0.0' 'my_other_gem:~>2.0.0'`"
terminate_interaction 1
end
end
def execute
-
- if options.include? :gemdeps then
+ if options.include? :gemdeps
install_from_gemdeps
return # not reached
end
@installed_specs = []
- ENV.delete 'GEM_PATH' if options[:install_dir].nil? and RUBY_VERSION > '1.9'
+ ENV.delete 'GEM_PATH' if options[:install_dir].nil?
check_install_dir
check_version
@@ -163,7 +169,7 @@ to write the specification by hand. For example:
end
def install_from_gemdeps # :nodoc:
- require 'rubygems/request_set'
+ require_relative '../request_set'
rs = Gem::RequestSet.new
specs = rs.install_from_gemdeps options do |req, inst|
@@ -181,68 +187,27 @@ to write the specification by hand. For example:
terminate_interaction
end
- def install_gem name, version # :nodoc:
+ def install_gem(name, version) # :nodoc:
return if options[:conservative] and
not Gem::Dependency.new(name, version).matching_specs.empty?
req = Gem::Requirement.create(version)
- if options[:ignore_dependencies] then
- install_gem_without_dependencies name, req
- else
- inst = Gem::DependencyInstaller.new options
- request_set = inst.resolve_dependencies name, req
-
- if options[:explain]
- puts "Gems to install:"
-
- request_set.sorted_requests.each do |s|
- puts " #{s.full_name}"
- end
-
- return
- else
- @installed_specs.concat request_set.install options
- end
+ dinst = Gem::DependencyInstaller.new options
- show_install_errors inst.errors
- end
- end
+ request_set = dinst.resolve_dependencies name, req
- def install_gem_without_dependencies name, req # :nodoc:
- gem = nil
+ if options[:explain]
+ say "Gems to install:"
- if local? then
- if name =~ /\.gem$/ and File.file? name then
- source = Gem::Source::SpecificFile.new name
- spec = source.spec
- else
- source = Gem::Source::Local.new
- spec = source.find_gem name, req
+ request_set.sorted_requests.each do |activation_request|
+ say " #{activation_request.full_name}"
end
- gem = source.download spec if spec
- end
-
- if remote? and not gem then
- dependency = Gem::Dependency.new name, req
- dependency.prerelease = options[:prerelease]
-
- fetcher = Gem::RemoteFetcher.fetcher
- gem = fetcher.download_to_cache dependency
+ else
+ @installed_specs.concat request_set.install options
end
- inst = Gem::Installer.at gem, options
- inst.install
-
- require 'rubygems/dependency_installer'
- dinst = Gem::DependencyInstaller.new options
- dinst.installed_gems.replace [inst.spec]
-
- Gem.done_installing_hooks.each do |hook|
- hook.call dinst, [inst.spec]
- end unless Gem.done_installing_hooks.empty?
-
- @installed_specs.push(inst.spec)
+ show_install_errors dinst.errors
end
def install_gems # :nodoc:
@@ -250,16 +215,22 @@ to write the specification by hand. For example:
get_all_gem_names_and_versions.each do |gem_name, gem_version|
gem_version ||= options[:version]
+ domain = options[:domain]
+ domain = :local unless options[:suggest_alternate]
+ suppress_suggestions = (domain == :local)
begin
install_gem gem_name, gem_version
rescue Gem::InstallError => e
alert_error "Error installing #{gem_name}:\n\t#{e.message}"
exit_code |= 1
- rescue Gem::GemNotFoundException, Gem::UnsatisfiableDependencyError => e
- domain = options[:domain]
- domain = :local unless options[:suggest_alternate]
- show_lookup_failure e.name, e.version, e.errors, domain
+ rescue Gem::GemNotFoundException => e
+ show_lookup_failure e.name, e.version, e.errors, suppress_suggestions
+
+ exit_code |= 2
+ rescue Gem::UnsatisfiableDependencyError => e
+ show_lookup_failure e.name, e.version, e.errors, suppress_suggestions,
+ "'#{gem_name}' (#{gem_version})"
exit_code |= 2
end
@@ -273,20 +244,21 @@ to write the specification by hand. For example:
def load_hooks # :nodoc:
if options[:install_as_default]
- require 'rubygems/install_default_message'
+ require_relative '../install_default_message'
else
- require 'rubygems/install_message'
+ require_relative '../install_message'
end
- require 'rubygems/rdoc'
+ require_relative '../rdoc'
end
- def show_install_errors errors # :nodoc:
+ def show_install_errors(errors) # :nodoc:
return unless errors
errors.each do |x|
return unless Gem::SourceFetchProblem === x
- msg = "Unable to pull data from '#{x.source.uri}': #{x.error.message}"
+ require_relative "../uri"
+ msg = "Unable to pull data from '#{Gem::Uri.new(x.source.uri).redacted}': #{x.error.message}"
alert_warning msg
end
@@ -298,6 +270,4 @@ to write the specification by hand. For example:
gems = @installed_specs.length == 1 ? 'gem' : 'gems'
say "#{@installed_specs.length} #{gems} installed"
end
-
end
-
diff --git a/lib/rubygems/commands/list_command.rb b/lib/rubygems/commands/list_command.rb
index 1acb49e5fb..dea11111c9 100644
--- a/lib/rubygems/commands/list_command.rb
+++ b/lib/rubygems/commands/list_command.rb
@@ -1,17 +1,19 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/commands/query_command'
+require_relative '../command'
+require_relative '../query_utils'
##
-# An alternate to Gem::Commands::QueryCommand that searches for gems starting
-# with the supplied argument.
+# Searches for gems starting with the supplied argument.
-class Gem::Commands::ListCommand < Gem::Commands::QueryCommand
+class Gem::Commands::ListCommand < Gem::Command
+ include Gem::QueryUtils
def initialize
- super 'list', 'Display local gems whose name matches REGEXP'
+ super 'list', 'Display local gems whose name matches REGEXP',
+ :name => //, :domain => :local, :details => false, :versions => true,
+ :installed => nil, :version => Gem::Requirement.default
- remove_option('--name-matches')
+ add_query_options
end
def arguments # :nodoc:
@@ -36,6 +38,4 @@ To search for remote gems use the search command.
def usage # :nodoc:
"#{program_name} [REGEXP ...]"
end
-
end
-
diff --git a/lib/rubygems/commands/lock_command.rb b/lib/rubygems/commands/lock_command.rb
index 3eebfadc05..cb6229a2cb 100644
--- a/lib/rubygems/commands/lock_command.rb
+++ b/lib/rubygems/commands/lock_command.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
class Gem::Commands::LockCommand < Gem::Command
-
def initialize
super 'lock', 'Generate a lockdown list of gems',
:strict => false
@@ -59,7 +58,7 @@ lock it down to the exact version.
end
def complain(message)
- if options[:strict] then
+ if options[:strict]
raise Gem::Exception, message
else
say "# #{message}"
@@ -78,7 +77,7 @@ lock it down to the exact version.
spec = Gem::Specification.load spec_path(full_name)
- if spec.nil? then
+ if spec.nil?
complain "Could not find gem #{full_name}, try using the full name"
next
end
@@ -90,7 +89,7 @@ lock it down to the exact version.
next if locked[dep.name]
candidates = dep.matching_specs
- if candidates.empty? then
+ if candidates.empty?
complain "Unable to satisfy '#{dep}' from currently installed gems"
else
pending << candidates.last.full_name
@@ -100,12 +99,10 @@ lock it down to the exact version.
end
def spec_path(gem_full_name)
- gemspecs = Gem.path.map { |path|
+ gemspecs = Gem.path.map do |path|
File.join path, "specifications", "#{gem_full_name}.gemspec"
- }
+ end
- gemspecs.find { |path| File.exist? path }
+ gemspecs.find {|path| File.exist? path }
end
-
end
-
diff --git a/lib/rubygems/commands/mirror_command.rb b/lib/rubygems/commands/mirror_command.rb
index 801c9c8927..7daa47e2f0 100644
--- a/lib/rubygems/commands/mirror_command.rb
+++ b/lib/rubygems/commands/mirror_command.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
unless defined? Gem::Commands::MirrorCommand
class Gem::Commands::MirrorCommand < Gem::Command
@@ -21,6 +21,5 @@ The mirror command has been moved to the rubygems-mirror gem.
def execute
alert_error "Install the rubygems-mirror gem for the mirror command"
end
-
end
end
diff --git a/lib/rubygems/commands/open_command.rb b/lib/rubygems/commands/open_command.rb
index 059635e835..1e616fd68f 100644
--- a/lib/rubygems/commands/open_command.rb
+++ b/lib/rubygems/commands/open_command.rb
@@ -1,23 +1,20 @@
# frozen_string_literal: true
-require 'English'
-require 'rubygems/command'
-require 'rubygems/version_option'
-require 'rubygems/util'
+require_relative '../command'
+require_relative '../version_option'
class Gem::Commands::OpenCommand < Gem::Command
-
include Gem::VersionOption
def initialize
super 'open', 'Open gem sources in editor'
- add_option('-e', '--editor EDITOR', String,
- "Opens gem sources in EDITOR") do |editor, options|
- options[:editor] = editor || get_env_editor
+ add_option('-e', '--editor COMMAND', String,
+ "Prepends COMMAND to gem path. Could be used to specify editor.") do |command, options|
+ options[:editor] = command || get_env_editor
end
add_option('-v', '--version VERSION', String,
"Opens specific gem version") do |version|
- options[:version] = version
+ options[:version] = version
end
end
@@ -32,14 +29,14 @@ class Gem::Commands::OpenCommand < Gem::Command
def description # :nodoc:
<<-EOF
The open command opens gem in editor and changes current path
- to gem's source directory. Editor can be specified with -e option,
- otherwise rubygems will look for editor in $EDITOR, $VISUAL and
- $GEM_EDITOR variables.
+ to gem's source directory.
+ Editor command can be specified with -e option, otherwise rubygems
+ will look for editor in $EDITOR, $VISUAL and $GEM_EDITOR variables.
EOF
end
def usage # :nodoc:
- "#{program_name} GEMNAME [-e EDITOR]"
+ "#{program_name} [-e COMMAND] GEMNAME"
end
def get_env_editor
@@ -58,20 +55,26 @@ class Gem::Commands::OpenCommand < Gem::Command
terminate_interaction 1 unless found
end
- def open_gem name
+ def open_gem(name)
spec = spec_for name
+
return false unless spec
+ if spec.default_gem?
+ say "'#{name}' is a default gem and can't be opened."
+ return false
+ end
+
open_editor(spec.full_gem_path)
end
- def open_editor path
+ def open_editor(path)
Dir.chdir(path) do
system(*@editor.split(/\s+/) + [path])
end
end
- def spec_for name
+ def spec_for(name)
spec = Gem::Specification.find_all_by_name(name, @version).first
return spec if spec
diff --git a/lib/rubygems/commands/outdated_command.rb b/lib/rubygems/commands/outdated_command.rb
index 70f6c02801..162d338320 100644
--- a/lib/rubygems/commands/outdated_command.rb
+++ b/lib/rubygems/commands/outdated_command.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/spec_fetcher'
-require 'rubygems/version_option'
+require_relative '../command'
+require_relative '../local_remote_options'
+require_relative '../spec_fetcher'
+require_relative '../version_option'
class Gem::Commands::OutdatedCommand < Gem::Command
-
include Gem::LocalRemoteOptions
include Gem::VersionOption
diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb
index 8e2271657a..0a5665228f 100644
--- a/lib/rubygems/commands/owner_command.rb
+++ b/lib/rubygems/commands/owner_command.rb
@@ -1,9 +1,11 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/gemcutter_utilities'
+require_relative '../command'
+require_relative '../local_remote_options'
+require_relative '../gemcutter_utilities'
+require_relative '../text'
class Gem::Commands::OwnerCommand < Gem::Command
+ include Gem::Text
include Gem::LocalRemoteOptions
include Gem::GemcutterUtilities
@@ -30,6 +32,7 @@ permission to.
super 'owner', 'Manage gem owners of a gem on the push server'
add_proxy_option
add_key_option
+ add_otp_option
defaults.merge! :add => [], :remove => []
add_option '-a', '--add EMAIL', 'Add an owner' do |value, options|
@@ -50,7 +53,7 @@ permission to.
def execute
@host = options[:host]
- sign_in
+ sign_in(scope: get_owner_scope)
name = get_one_gem_name
add_owners name, options[:add]
@@ -58,13 +61,15 @@ permission to.
show_owners name
end
- def show_owners name
+ def show_owners(name)
+ Gem.load_yaml
+
response = rubygems_api_request :get, "api/v1/gems/#{name}/owners.yaml" do |request|
request.add_field "Authorization", api_key
end
with_response response do |resp|
- owners = YAML.load resp.body
+ owners = Gem::SafeYAML.load clean_text(resp.body)
say "Owners for gem: #{name}"
owners.each do |owner|
@@ -73,22 +78,18 @@ permission to.
end
end
- def add_owners name, owners
+ def add_owners(name, owners)
manage_owners :post, name, owners
end
- def remove_owners name, owners
+ def remove_owners(name, owners)
manage_owners :delete, name, owners
end
- def manage_owners method, name, owners
+ def manage_owners(method, name, owners)
owners.each do |owner|
begin
- response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request|
- request.set_form_data 'email' => owner
- request.add_field "Authorization", api_key
- end
-
+ response = send_owner_request(method, name, owner)
action = method == :delete ? "Removing" : "Adding"
with_response response, "#{action} #{owner}"
@@ -98,4 +99,20 @@ permission to.
end
end
+ private
+
+ def send_owner_request(method, name, owner)
+ rubygems_api_request method, "api/v1/gems/#{name}/owners", scope: get_owner_scope(method: method) do |request|
+ request.set_form_data 'email' => owner
+ request.add_field "Authorization", api_key
+ end
+ end
+
+ def get_owner_scope(method: nil)
+ if method == :post || options.any? && options[:add].any?
+ :add_owner
+ elsif method == :delete || options.any? && options[:remove].any?
+ :remove_owner
+ end
+ end
end
diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb
index fafe35bec1..13979b0a59 100644
--- a/lib/rubygems/commands/pristine_command.rb
+++ b/lib/rubygems/commands/pristine_command.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/package'
-require 'rubygems/installer'
-require 'rubygems/version_option'
+require_relative '../command'
+require_relative '../package'
+require_relative '../installer'
+require_relative '../version_option'
class Gem::Commands::PristineCommand < Gem::Command
-
include Gem::VersionOption
def initialize
@@ -24,7 +23,8 @@ class Gem::Commands::PristineCommand < Gem::Command
add_option('--skip=gem_name',
'used on --all, skip if name == gem_name') do |value, options|
- options[:skip] = value
+ options[:skip] ||= []
+ options[:skip] << value
end
add_option('--[no-]extensions',
@@ -39,12 +39,28 @@ class Gem::Commands::PristineCommand < Gem::Command
options[:only_executables] = value
end
+ add_option('--only-plugins',
+ 'Only restore plugins') do |value, options|
+ options[:only_plugins] = value
+ end
+
add_option('-E', '--[no-]env-shebang',
'Rewrite executables with a shebang',
'of /usr/bin/env') do |value, options|
options[:env_shebang] = value
end
+ add_option('-i', '--install-dir DIR',
+ 'Gem repository to get binstubs and plugins installed') do |value, options|
+ options[:install_dir] = File.expand_path(value)
+ end
+
+ add_option('-n', '--bindir DIR',
+ 'Directory where executables are',
+ 'located') do |value, options|
+ options[:bin_dir] = File.expand_path(value)
+ end
+
add_version_option('restore to', 'pristine condition')
end
@@ -81,13 +97,13 @@ extensions will be restored.
end
def execute
- specs = if options[:all] then
+ specs = if options[:all]
Gem::Specification.map
# `--extensions` must be explicitly given to pristine only gems
# with extensions.
elsif options[:extensions_set] and
- options[:extensions] and options[:args].empty? then
+ options[:extensions] and options[:args].empty?
Gem::Specification.select do |spec|
spec.extensions and not spec.extensions.empty?
end
@@ -97,16 +113,13 @@ extensions will be restored.
end.flatten
end
- if specs.to_a.empty? then
+ specs = specs.select{|spec| RUBY_ENGINE == spec.platform || Gem::Platform.local === spec.platform || spec.platform == Gem::Platform::RUBY }
+
+ if specs.to_a.empty?
raise Gem::Exception,
"Failed to find gems #{options[:args]} #{options[:version]}"
end
- install_dir = Gem.dir # TODO use installer option
-
- raise Gem::FilePermissionError.new(install_dir) unless
- File.writable?(install_dir)
-
say "Restoring gems to pristine condition..."
specs.each do |spec|
@@ -115,25 +128,22 @@ extensions will be restored.
next
end
- if spec.name == options[:skip]
- say "Skipped #{spec.full_name}, it was given through options"
- next
- end
-
- if spec.bundled_gem_in_old_ruby?
- say "Skipped #{spec.full_name}, it is bundled with old Ruby"
- next
+ if options.has_key? :skip
+ if options[:skip].include? spec.name
+ say "Skipped #{spec.full_name}, it was given through options"
+ next
+ end
end
- unless spec.extensions.empty? or options[:extensions] or options[:only_executables] then
+ unless spec.extensions.empty? or options[:extensions] or options[:only_executables] or options[:only_plugins]
say "Skipped #{spec.full_name}, it needs to compile an extension"
next
end
gem = spec.cache_file
- unless File.exist? gem or options[:only_executables] then
- require 'rubygems/remote_fetcher'
+ unless File.exist? gem or options[:only_executables] or options[:only_plugins]
+ require_relative '../remote_fetcher'
say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
@@ -150,24 +160,31 @@ extensions will be restored.
end
env_shebang =
- if options.include? :env_shebang then
+ if options.include? :env_shebang
options[:env_shebang]
else
install_defaults = Gem::ConfigFile::PLATFORM_DEFAULTS['install']
install_defaults.to_s['--env-shebang']
end
+ bin_dir = options[:bin_dir] if options[:bin_dir]
+ install_dir = options[:install_dir] if options[:install_dir]
+
installer_options = {
:wrappers => true,
:force => true,
- :install_dir => spec.base_dir,
+ :install_dir => install_dir || spec.base_dir,
:env_shebang => env_shebang,
:build_args => spec.build_args,
+ :bin_dir => bin_dir,
}
- if options[:only_executables] then
+ if options[:only_executables]
installer = Gem::Installer.for_spec(spec, installer_options)
installer.generate_bin
+ elsif options[:only_plugins]
+ installer = Gem::Installer.for_spec(spec, installer_options)
+ installer.generate_plugins
else
installer = Gem::Installer.at(gem, installer_options)
installer.install
diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb
index d294cbc8df..1864b4b095 100644
--- a/lib/rubygems/commands/push_command.rb
+++ b/lib/rubygems/commands/push_command.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/gemcutter_utilities'
-require 'rubygems/package'
+require_relative '../command'
+require_relative '../local_remote_options'
+require_relative '../gemcutter_utilities'
+require_relative '../package'
class Gem::Commands::PushCommand < Gem::Command
include Gem::LocalRemoteOptions
@@ -13,8 +13,10 @@ class Gem::Commands::PushCommand < Gem::Command
The push command uploads a gem to the push server (the default is
https://rubygems.org) and adds it to the index.
-The gem can be removed from the index (but only the index) using the yank
+The gem can be removed from the index and deleted from the server using the yank
command. For further discussion see the help for the yank command.
+
+The push command will use ~/.gem/credentials to authenticate to a server, but you can use the RubyGems environment variable GEM_HOST_API_KEY to set the api key to authenticate.
EOF
end
@@ -29,59 +31,45 @@ command. For further discussion see the help for the yank command.
def initialize
super 'push', 'Push a gem up to the gem server', :host => self.host
+ @user_defined_host = false
+
add_proxy_option
add_key_option
+ add_otp_option
add_option('--host HOST',
'Push to another gemcutter-compatible host',
' (e.g. https://rubygems.org)') do |value, options|
options[:host] = value
+ @user_defined_host = true
end
@host = nil
end
def execute
- @host = options[:host]
-
- sign_in @host
-
- send_gem get_one_gem_name
+ gem_name = get_one_gem_name
+ default_gem_server, push_host = get_hosts_for(gem_name)
+
+ @host = if @user_defined_host
+ options[:host]
+ elsif default_gem_server
+ default_gem_server
+ elsif push_host
+ push_host
+ else
+ options[:host]
+ end
+
+ sign_in @host, scope: get_push_scope
+
+ send_gem(gem_name)
end
- def send_gem name
+ def send_gem(name)
args = [:post, "api/v1/gems"]
- latest_rubygems_version = Gem.latest_rubygems_version
-
- if latest_rubygems_version < Gem.rubygems_version and
- Gem.rubygems_version.prerelease? and
- Gem::Version.new('2.0.0.rc.2') != Gem.rubygems_version then
- alert_error <<-ERROR
-You are using a beta release of RubyGems (#{Gem::VERSION}) which is not
-allowed to push gems. Please downgrade or upgrade to a release version.
-
-The latest released RubyGems version is #{latest_rubygems_version}
-
-You can upgrade or downgrade to the latest release version with:
-
- gem update --system=#{latest_rubygems_version}
-
- ERROR
- terminate_interaction 1
- end
-
- gem_data = Gem::Package.new(name)
-
- unless @host then
- @host = gem_data.spec.metadata['default_gem_server']
- end
-
- push_host = nil
-
- if gem_data.spec.metadata.has_key?('allowed_push_host')
- push_host = gem_data.spec.metadata['allowed_push_host']
- end
+ _, push_host = get_hosts_for(name)
@host ||= push_host
@@ -90,15 +78,32 @@ You can upgrade or downgrade to the latest release version with:
say "Pushing gem to #{@host || Gem.host}..."
- response = rubygems_api_request(*args) do |request|
+ response = send_push_request(name, args)
+
+ with_response response
+ end
+
+ private
+
+ def send_push_request(name, args)
+ rubygems_api_request(*args, scope: get_push_scope) do |request|
request.body = Gem.read_binary name
request.add_field "Content-Length", request.body.size
request.add_field "Content-Type", "application/octet-stream"
request.add_field "Authorization", api_key
end
+ end
- with_response response
+ def get_hosts_for(name)
+ gem_metadata = Gem::Package.new(name).spec.metadata
+
+ [
+ gem_metadata["default_gem_server"],
+ gem_metadata["allowed_push_host"],
+ ]
end
+ def get_push_scope
+ :push_rubygem
+ end
end
-
diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb
index 4624e5a1e9..5896bec44e 100644
--- a/lib/rubygems/commands/query_command.rb
+++ b/lib/rubygems/commands/query_command.rb
@@ -1,15 +1,21 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/spec_fetcher'
-require 'rubygems/version_option'
-require 'rubygems/text'
+require_relative '../command'
+require_relative '../query_utils'
+require_relative '../deprecate'
class Gem::Commands::QueryCommand < Gem::Command
+ extend Gem::Deprecate
+ rubygems_deprecate_command
- include Gem::Text
- include Gem::LocalRemoteOptions
- include Gem::VersionOption
+ include Gem::QueryUtils
+
+ alias warning_without_suggested_alternatives deprecation_warning
+ def deprecation_warning
+ warning_without_suggested_alternatives
+
+ message = "It is recommended that you use `gem search` or `gem list` instead.\n"
+ alert_warning message unless Gem::Deprecate.skip
+ end
def initialize(name = 'query',
summary = 'Query gem information in local or remote repositories')
@@ -17,55 +23,13 @@ class Gem::Commands::QueryCommand < Gem::Command
:name => //, :domain => :local, :details => false, :versions => true,
:installed => nil, :version => Gem::Requirement.default
- add_option('-i', '--[no-]installed',
- 'Check for installed gem') do |value, options|
- options[:installed] = value
- end
-
- add_option('-I', 'Equivalent to --no-installed') do |value, options|
- options[:installed] = false
- end
-
- add_version_option command, "for use with --installed"
-
add_option('-n', '--name-matches REGEXP',
'Name of gem(s) to query on matches the',
'provided REGEXP') do |value, options|
options[:name] = /#{value}/i
end
- add_option('-d', '--[no-]details',
- 'Display detailed information of gem(s)') do |value, options|
- options[:details] = value
- end
-
- add_option( '--[no-]versions',
- 'Display only gem names') do |value, options|
- options[:versions] = value
- options[:details] = false unless value
- end
-
- add_option('-a', '--all',
- 'Display all gem versions') do |value, options|
- options[:all] = value
- end
-
- add_option('-e', '--exact',
- 'Name of gem(s) to query on matches the',
- 'provided STRING') do |value, options|
- options[:exact] = value
- end
-
- add_option( '--[no-]prerelease',
- 'Display prerelease versions') do |value, options|
- options[:prerelease] = value
- end
-
- add_local_remote_options
- end
-
- def defaults_str # :nodoc:
- "--local --name-matches // --no-details --versions --no-installed"
+ add_query_options
end
def description # :nodoc:
@@ -76,284 +40,4 @@ You should really use the list and search commands instead. This command
is too hard to use.
EOF
end
-
- def execute
- exit_code = 0
- if options[:args].to_a.empty? and options[:name].source.empty?
- name = options[:name]
- no_name = true
- elsif !options[:name].source.empty?
- name = Array(options[:name])
- else
- args = options[:args].to_a
- name = options[:exact] ? args.map{|arg| /\A#{Regexp.escape(arg)}\Z/ } : args.map{|arg| /#{arg}/i }
- end
-
- prerelease = options[:prerelease]
-
- unless options[:installed].nil? then
- if no_name then
- alert_error "You must specify a gem name"
- exit_code |= 4
- elsif name.count > 1
- alert_error "You must specify only ONE gem!"
- exit_code |= 4
- else
- installed = installed? name.first, options[:version]
- installed = !installed unless options[:installed]
-
- if installed then
- say "true"
- else
- say "false"
- exit_code |= 1
- end
- end
-
- terminate_interaction exit_code
- end
-
- names = Array(name)
- names.each { |n| show_gems n, prerelease }
- end
-
- private
-
- def display_header type
- if (ui.outs.tty? and Gem.configuration.verbose) or both? then
- say
- say "*** #{type} GEMS ***"
- say
- end
- end
-
- #Guts of original execute
- def show_gems name, prerelease
- req = Gem::Requirement.default
- # TODO: deprecate for real
- dep = Gem::Deprecate.skip_during { Gem::Dependency.new name, req }
- dep.prerelease = prerelease
-
- if local? then
- if prerelease and not both? then
- alert_warning "prereleases are always shown locally"
- end
-
- display_header 'LOCAL'
-
- specs = Gem::Specification.find_all { |s|
- s.name =~ name and req =~ s.version
- }
-
- spec_tuples = specs.map do |spec|
- [spec.name_tuple, spec]
- end
-
- output_query_results spec_tuples
- end
-
- if remote? then
- display_header 'REMOTE'
-
- fetcher = Gem::SpecFetcher.fetcher
-
- type = if options[:all]
- if options[:prerelease]
- :complete
- else
- :released
- end
- elsif options[:prerelease]
- :prerelease
- else
- :latest
- end
-
- if name.respond_to?(:source) && name.source.empty?
- spec_tuples = fetcher.detect(type) { true }
- else
- spec_tuples = fetcher.detect(type) do |name_tuple|
- name === name_tuple.name
- end
- end
-
- output_query_results spec_tuples
- end
- end
-
- ##
- # Check if gem +name+ version +version+ is installed.
-
- def installed?(name, req = Gem::Requirement.default)
- Gem::Specification.any? { |s| s.name =~ name and req =~ s.version }
- end
-
- def output_query_results(spec_tuples)
- output = []
- versions = Hash.new { |h,name| h[name] = [] }
-
- spec_tuples.each do |spec_tuple, source|
- versions[spec_tuple.name] << [spec_tuple, source]
- end
-
- versions = versions.sort_by do |(n,_),_|
- n.downcase
- end
-
- output_versions output, versions
-
- say output.join(options[:details] ? "\n\n" : "\n")
- end
-
- def output_versions output, versions
- versions.each do |gem_name, matching_tuples|
- matching_tuples = matching_tuples.sort_by { |n,_| n.version }.reverse
-
- platforms = Hash.new { |h,version| h[version] = [] }
-
- matching_tuples.each do |n, _|
- platforms[n.version] << n.platform if n.platform
- end
-
- seen = {}
-
- matching_tuples.delete_if do |n,_|
- if seen[n.version] then
- true
- else
- seen[n.version] = true
- false
- end
- end
-
- output << clean_text(make_entry(matching_tuples, platforms))
- end
- end
-
- def entry_details entry, detail_tuple, specs, platforms
- return unless options[:details]
-
- name_tuple, spec = detail_tuple
-
- spec = spec.fetch_spec name_tuple if spec.respond_to? :fetch_spec
-
- entry << "\n"
-
- spec_platforms entry, platforms
- spec_authors entry, spec
- spec_homepage entry, spec
- spec_license entry, spec
- spec_loaded_from entry, spec, specs
- spec_summary entry, spec
- end
-
- def entry_versions entry, name_tuples, platforms, specs
- return unless options[:versions]
-
- list =
- if platforms.empty? or options[:details] then
- name_tuples.map { |n| n.version }.uniq
- else
- platforms.sort.reverse.map do |version, pls|
- out = version.to_s
-
- if options[:domain] == :local
- default = specs.any? do |s|
- !s.is_a?(Gem::Source) && s.version == version && s.default_gem?
- end
- out = "default: #{out}" if default
- end
-
- if pls != [Gem::Platform::RUBY] then
- platform_list = [pls.delete(Gem::Platform::RUBY), *pls.sort].compact
- out = platform_list.unshift(out).join(' ')
- end
-
- out
- end
- end
-
- entry << " (#{list.join ', '})"
- end
-
- def make_entry entry_tuples, platforms
- detail_tuple = entry_tuples.first
-
- name_tuples, specs = entry_tuples.flatten.partition do |item|
- Gem::NameTuple === item
- end
-
- entry = [name_tuples.first.name]
-
- entry_versions entry, name_tuples, platforms, specs
- entry_details entry, detail_tuple, specs, platforms
-
- entry.join
- end
-
- def spec_authors entry, spec
- authors = "Author#{spec.authors.length > 1 ? 's' : ''}: ".dup
- authors << spec.authors.join(', ')
- entry << format_text(authors, 68, 4)
- end
-
- def spec_homepage entry, spec
- return if spec.homepage.nil? or spec.homepage.empty?
-
- entry << "\n" << format_text("Homepage: #{spec.homepage}", 68, 4)
- end
-
- def spec_license entry, spec
- return if spec.license.nil? or spec.license.empty?
-
- licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: ".dup
- licenses << spec.licenses.join(', ')
- entry << "\n" << format_text(licenses, 68, 4)
- end
-
- def spec_loaded_from entry, spec, specs
- return unless spec.loaded_from
-
- if specs.length == 1 then
- default = spec.default_gem? ? ' (default)' : nil
- entry << "\n" << " Installed at#{default}: #{spec.base_dir}"
- else
- label = 'Installed at'
- specs.each do |s|
- version = s.version.to_s
- version << ', default' if s.default_gem?
- entry << "\n" << " #{label} (#{version}): #{s.base_dir}"
- label = ' ' * label.length
- end
- end
- end
-
- def spec_platforms entry, platforms
- non_ruby = platforms.any? do |_, pls|
- pls.any? { |pl| pl != Gem::Platform::RUBY }
- end
-
- return unless non_ruby
-
- if platforms.length == 1 then
- title = platforms.values.length == 1 ? 'Platform' : 'Platforms'
- entry << " #{title}: #{platforms.values.sort.join ', '}\n"
- else
- entry << " Platforms:\n"
- platforms.sort_by do |version,|
- version
- end.each do |version, pls|
- label = " #{version}: "
- data = format_text pls.sort.join(', '), 68, label.length
- data[0, label.length] = label
- entry << data << "\n"
- end
- end
- end
-
- def spec_summary entry, spec
- summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
- entry << "\n\n" << format_text(summary, 68, 4)
- end
-
end
diff --git a/lib/rubygems/commands/rdoc_command.rb b/lib/rubygems/commands/rdoc_command.rb
index 6992040dca..305c80ccfe 100644
--- a/lib/rubygems/commands/rdoc_command.rb
+++ b/lib/rubygems/commands/rdoc_command.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/version_option'
-require 'rubygems/rdoc'
+require_relative '../command'
+require_relative '../version_option'
+require_relative '../rdoc'
require 'fileutils'
class Gem::Commands::RdocCommand < Gem::Command
@@ -60,7 +60,7 @@ Use --overwrite to force rebuilding of documentation.
end
def execute
- specs = if options[:all] then
+ specs = if options[:all]
Gem::Specification.to_a
else
get_all_gem_names.map do |name|
@@ -68,7 +68,7 @@ Use --overwrite to force rebuilding of documentation.
end.flatten.uniq
end
- if specs.empty? then
+ if specs.empty?
alert_error 'No matching gems found'
terminate_interaction 1
end
@@ -78,7 +78,7 @@ Use --overwrite to force rebuilding of documentation.
doc.force = options[:overwrite]
- if options[:overwrite] then
+ if options[:overwrite]
FileUtils.rm_rf File.join(spec.doc_dir, 'ri')
FileUtils.rm_rf File.join(spec.doc_dir, 'rdoc')
end
@@ -92,6 +92,4 @@ Use --overwrite to force rebuilding of documentation.
end
end
end
-
end
-
diff --git a/lib/rubygems/commands/search_command.rb b/lib/rubygems/commands/search_command.rb
index 933436d84d..488d777939 100644
--- a/lib/rubygems/commands/search_command.rb
+++ b/lib/rubygems/commands/search_command.rb
@@ -1,15 +1,16 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/commands/query_command'
+require_relative '../command'
+require_relative '../query_utils'
-class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand
+class Gem::Commands::SearchCommand < Gem::Command
+ include Gem::QueryUtils
def initialize
- super 'search', 'Display remote gems whose name matches REGEXP'
+ super 'search', 'Display remote gems whose name matches REGEXP',
+ :name => //, :domain => :remote, :details => false, :versions => true,
+ :installed => nil, :version => Gem::Requirement.default
- remove_option '--name-matches'
-
- defaults[:domain] = :remote
+ add_query_options
end
def arguments # :nodoc:
@@ -36,6 +37,4 @@ To list local gems use the list command.
def usage # :nodoc:
"#{program_name} [REGEXP]"
end
-
end
-
diff --git a/lib/rubygems/commands/server_command.rb b/lib/rubygems/commands/server_command.rb
index 245156d50d..79c682e8f4 100644
--- a/lib/rubygems/commands/server_command.rb
+++ b/lib/rubygems/commands/server_command.rb
@@ -1,17 +1,20 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/server'
+require_relative '../command'
+require_relative '../server'
+require_relative '../deprecate'
class Gem::Commands::ServerCommand < Gem::Command
+ extend Gem::Deprecate
+ rubygems_deprecate_command
def initialize
super 'server', 'Documentation and gem repository HTTP server',
:port => 8808, :gemdir => [], :daemon => false
- OptionParser.accept :Port do |port|
- if port =~ /\A\d+\z/ then
+ Gem::OptionParser.accept :Port do |port|
+ if port =~ /\A\d+\z/
port = Integer port
- raise OptionParser::InvalidArgument, "#{port}: not a port number" if
+ raise Gem::OptionParser::InvalidArgument, "#{port}: not a port number" if
port > 65535
port
@@ -19,7 +22,7 @@ class Gem::Commands::ServerCommand < Gem::Command
begin
Socket.getservbyname port
rescue SocketError
- raise OptionParser::InvalidArgument, "#{port}: no such named service"
+ raise Gem::OptionParser::InvalidArgument, "#{port}: no such named service"
end
end
end
@@ -82,6 +85,4 @@ You can set up a shortcut to gem server documentation using the URL:
options[:gemdir] = Gem.path if options[:gemdir].empty?
Gem::Server.run options
end
-
end
-
diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb
index f322ca9df5..894f94b484 100644
--- a/lib/rubygems/commands/setup_command.rb
+++ b/lib/rubygems/commands/setup_command.rb
@@ -1,22 +1,26 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
##
# Installs RubyGems itself. This command is ordinarily only available from a
# RubyGems checkout or tarball.
class Gem::Commands::SetupCommand < Gem::Command
- HISTORY_HEADER = /^===\s*[\d.]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/
- VERSION_MATCHER = /^===\s*([\d.]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/
+ HISTORY_HEADER = /^#\s*[\d.a-zA-Z]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/.freeze
+ VERSION_MATCHER = /^#\s*([\d.a-zA-Z]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/.freeze
+
+ ENV_PATHS = %w[/usr/bin/env /bin/env].freeze
def initialize
require 'tmpdir'
super 'setup', 'Install RubyGems',
- :format_executable => true, :document => %w[ri],
+ :format_executable => false, :document => %w[ri],
+ :force => true,
:site_or_vendor => 'sitelibdir',
:destdir => '', :prefix => '', :previous_version => '',
- :regenerate_binstubs => true
+ :regenerate_binstubs => true,
+ :regenerate_plugins => true
add_option '--previous-version=VERSION',
'Previous version of RubyGems',
@@ -60,7 +64,7 @@ class Gem::Commands::SetupCommand < Gem::Command
add_option '--[no-]rdoc',
'Generate RDoc documentation for RubyGems' do |value, options|
- if value then
+ if value
options[:document] << 'rdoc'
else
options[:document].delete 'rdoc'
@@ -71,7 +75,7 @@ class Gem::Commands::SetupCommand < Gem::Command
add_option '--[no-]ri',
'Generate RI documentation for RubyGems' do |value, options|
- if value then
+ if value
options[:document] << 'ri'
else
options[:document].delete 'ri'
@@ -82,20 +86,32 @@ class Gem::Commands::SetupCommand < Gem::Command
add_option '--[no-]regenerate-binstubs',
'Regenerate gem binstubs' do |value, options|
- if value then
- options[:regenerate_binstubs] = true
- else
- options.delete(:regenerate_binstubs)
- end
- end
+ options[:regenerate_binstubs] = value
+ end
+
+ add_option '--[no-]regenerate-plugins',
+ 'Regenerate gem plugins' do |value, options|
+ options[:regenerate_plugins] = value
+ end
+
+ add_option '-f', '--[no-]force',
+ 'Forcefully overwrite binstubs' do |value, options|
+ options[:force] = value
+ end
+
+ add_option('-E', '--[no-]env-shebang',
+ 'Rewrite executables with a shebang',
+ 'of /usr/bin/env') do |value, options|
+ options[:env_shebang] = value
+ end
@verbose = nil
end
def check_ruby_version
- required_version = Gem::Requirement.new '>= 1.8.7'
+ required_version = Gem::Requirement.new '>= 2.3.0'
- unless required_version.satisfied_by? Gem.ruby_version then
+ unless required_version.satisfied_by? Gem.ruby_version
alert_error "Expected Ruby version #{required_version}, is #{Gem.ruby_version}"
terminate_interaction 1
end
@@ -123,26 +139,28 @@ By default, this RubyGems will install gem as:
EOF
end
+ module MakeDirs
+ def mkdir_p(path, **opts)
+ super
+ (@mkdirs ||= []) << path
+ end
+ end
+
def execute
@verbose = Gem.configuration.really_verbose
- install_destdir = options[:destdir]
-
- unless install_destdir.empty? then
- ENV['GEM_HOME'] ||= File.join(install_destdir,
- Gem.default_dir.gsub(/^[a-zA-Z]:/, ''))
- end
-
check_ruby_version
require 'fileutils'
- if Gem.configuration.really_verbose then
+ if Gem.configuration.really_verbose
extend FileUtils::Verbose
else
extend FileUtils
end
+ extend MakeDirs
- lib_dir, bin_dir = make_destination_dirs install_destdir
+ lib_dir, bin_dir = make_destination_dirs
+ man_dir = generate_default_man_dir
install_lib lib_dir
@@ -152,18 +170,27 @@ By default, this RubyGems will install gem as:
remove_old_lib_files lib_dir
- install_default_bundler_gem
+ # Can be removed one we drop support for bundler 2.2.3 (the last version installing man files to man_dir)
+ remove_old_man_files man_dir if man_dir && File.exist?(man_dir)
+
+ install_default_bundler_gem bin_dir
+
+ if mode = options[:dir_mode]
+ @mkdirs.uniq!
+ File.chmod(mode, @mkdirs)
+ end
say "RubyGems #{Gem::VERSION} installed"
- regenerate_binstubs
+ regenerate_binstubs(bin_dir) if options[:regenerate_binstubs]
+ regenerate_plugins(bin_dir) if options[:regenerate_plugins]
uninstall_old_gemcutter
documentation_success = install_rdoc
say
- if @verbose then
+ if @verbose
say "-" * 78
say
end
@@ -181,17 +208,17 @@ By default, this RubyGems will install gem as:
say
say "RubyGems installed the following executables:"
- say @bin_file_names.map { |name| "\t#{name}\n" }
+ say bin_file_names.map {|name| "\t#{name}\n" }
say
- unless @bin_file_names.grep(/#{File::SEPARATOR}gem$/) then
+ unless bin_file_names.grep(/#{File::SEPARATOR}gem$/)
say "If `gem` was installed by a previous RubyGems installation, you may need"
say "to remove it by hand."
say
end
if documentation_success
- if options[:document].include? 'rdoc' then
+ if options[:document].include? 'rdoc'
say "Rdoc documentation was installed. You may now invoke:"
say " gem server"
say "and then peruse beautifully formatted documentation for your gems"
@@ -202,7 +229,7 @@ By default, this RubyGems will install gem as:
say
end
- if options[:document].include? 'ri' then
+ if options[:document].include? 'ri'
say "Ruby Interactive (ri) documentation was installed. ri is kind of like man "
say "pages for Ruby libraries. You may access it like this:"
say " ri Classname"
@@ -216,51 +243,40 @@ By default, this RubyGems will install gem as:
end
end
-
def install_executables(bin_dir)
- @bin_file_names = []
+ prog_mode = options[:prog_mode] || 0755
executables = { 'gem' => 'bin' }
- executables['bundler'] = 'bundler/exe' if Gem::USE_BUNDLER_FOR_GEMDEPS
executables.each do |tool, path|
say "Installing #{tool} executable" if @verbose
Dir.chdir path do
- bin_files = Dir['*']
-
- bin_files -= %w[update_rubygems bundler bundle_ruby]
+ bin_file = "gem"
- bin_files.each do |bin_file|
- bin_file_formatted = if options[:format_executable] then
- Gem.default_exec_format % bin_file
- else
- bin_file
- end
+ dest_file = target_bin_path(bin_dir, bin_file)
+ bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
- dest_file = File.join bin_dir, bin_file_formatted
- bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
+ begin
+ bin = File.readlines bin_file
+ bin[0] = shebang
- begin
- bin = File.readlines bin_file
- bin[0] = "#!#{Gem.ruby}\n"
-
- File.open bin_tmp_file, 'w' do |fp|
- fp.puts bin.join
- end
-
- install bin_tmp_file, dest_file, :mode => 0755
- @bin_file_names << dest_file
- ensure
- rm bin_tmp_file
+ File.open bin_tmp_file, 'w' do |fp|
+ fp.puts bin.join
end
- next unless Gem.win_platform?
+ install bin_tmp_file, dest_file, :mode => prog_mode
+ bin_file_names << dest_file
+ ensure
+ rm bin_tmp_file
+ end
+
+ next unless Gem.win_platform?
- begin
- bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"
+ begin
+ bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"
- File.open bin_cmd_file, 'w' do |file|
- file.puts <<-TEXT
+ File.open bin_cmd_file, 'w' do |file|
+ file.puts <<-TEXT
@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"#{File.basename(Gem.ruby).chomp('"')}" "#{dest_file}" %1 %2 %3 %4 %5 %6 %7 %8 %9
@@ -268,42 +284,36 @@ By default, this RubyGems will install gem as:
:WinNT
@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
TEXT
- end
-
- install bin_cmd_file, "#{dest_file}.bat", :mode => 0755
- ensure
- rm bin_cmd_file
end
+
+ install bin_cmd_file, "#{dest_file}.bat", :mode => prog_mode
+ ensure
+ rm bin_cmd_file
end
end
end
end
- def install_file file, dest_dir
- dest_file = File.join dest_dir, file
- dest_dir = File.dirname dest_file
- mkdir_p dest_dir unless File.directory? dest_dir
-
- install file, dest_file, :mode => 0644
+ def shebang
+ if options[:env_shebang]
+ ruby_name = RbConfig::CONFIG['ruby_install_name']
+ @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
+ "#!#{@env_path} #{ruby_name}\n"
+ else
+ "#!#{Gem.ruby}\n"
+ end
end
def install_lib(lib_dir)
libs = { 'RubyGems' => 'lib' }
- libs['Bundler'] = 'bundler/lib' if Gem::USE_BUNDLER_FOR_GEMDEPS
+ libs['Bundler'] = 'bundler/lib'
libs.each do |tool, path|
say "Installing #{tool}" if @verbose
- lib_files = rb_files_in path
- pem_files = pem_files_in path
+ lib_files = files_in path
Dir.chdir path do
- lib_files.each do |lib_file|
- install_file lib_file, lib_dir
- end
-
- pem_files.each do |pem_file|
- install_file pem_file, lib_dir
- end
+ install_file_list(lib_files, lib_dir)
end
end
end
@@ -321,13 +331,13 @@ By default, this RubyGems will install gem as:
if File.writable? gem_doc_dir and
(not File.exist? rubygems_doc_dir or
- File.writable? rubygems_doc_dir) then
+ File.writable? rubygems_doc_dir)
say "Removing old RubyGems RDoc and ri" if @verbose
Dir[File.join(Gem.dir, 'doc', 'rubygems-[0-9]*')].each do |dir|
rm_rf dir
end
- require 'rubygems/rdoc'
+ require_relative '../rdoc'
fake_spec = Gem::Specification.new 'rubygems', Gem::VERSION
def fake_spec.full_gem_path
@@ -341,7 +351,7 @@ By default, this RubyGems will install gem as:
rdoc.generate
return true
- elsif @verbose then
+ elsif @verbose
say "Skipping RDoc generation, #{gem_doc_dir} not writable"
say "Set the GEM_HOME environment variable if you want RDoc generated"
end
@@ -349,47 +359,109 @@ By default, this RubyGems will install gem as:
return false
end
- def install_default_bundler_gem
- return unless Gem::USE_BUNDLER_FOR_GEMDEPS
+ def install_default_bundler_gem(bin_dir)
+ specs_dir = File.join(default_dir, "specifications", "default")
+ mkdir_p specs_dir, :mode => 0755
+
+ bundler_spec = Dir.chdir("bundler") { Gem::Specification.load("bundler.gemspec") }
- bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
- bundler_spec.files = Dir["bundler/{*.md,{lib,exe,man}/**/*}"]
- bundler_spec.executables -= %w[bundler bundle_ruby]
- Dir.entries(Gem::Specification.default_specifications_dir).
+ # Remove bundler-*.gemspec in default specification directory.
+ Dir.entries(specs_dir).
select {|gs| gs.start_with?("bundler-") }.
- each {|gs| File.delete(File.join(Gem::Specification.default_specifications_dir, gs)) }
+ each {|gs| File.delete(File.join(specs_dir, gs)) }
- default_spec_path = File.join(Gem::Specification.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
+ default_spec_path = File.join(specs_dir, "#{bundler_spec.full_name}.gemspec")
Gem.write_binary(default_spec_path, bundler_spec.to_ruby)
bundler_spec = Gem::Specification.load(default_spec_path)
- Dir.entries(bundler_spec.gems_dir).
- select {|default_gem| default_gem.start_with?("bundler-") }.
- each {|default_gem| rm_r File.join(bundler_spec.gems_dir, default_gem) }
+ # The base_dir value for a specification is inferred by walking up from the
+ # folder where the spec was `loaded_from`. In the case of default gems, we
+ # walk up two levels, because they live at `specifications/default/`, whereas
+ # in the case of regular gems we walk up just one level because they live at
+ # `specifications/`. However, in this case, the gem we are installing is
+ # misdetected as a regular gem, when it's a default gem in reality. This is
+ # because when there's a `:destdir`, the `loaded_from` path has changed and
+ # doesn't match `Gem.default_specifications_dir` which is the criteria to
+ # tag a gem as a default gem. So, in that case, write the correct
+ # `@base_dir` directly.
+ bundler_spec.instance_variable_set(:@base_dir, File.dirname(File.dirname(specs_dir)))
+
+ # Remove gemspec that was same version of vendored bundler.
+ normal_gemspec = File.join(default_dir, "specifications", "bundler-#{bundler_spec.version}.gemspec")
+ if File.file? normal_gemspec
+ File.delete normal_gemspec
+ end
+
+ # Remove gem files that were same version of vendored bundler.
+ if File.directory? bundler_spec.gems_dir
+ Dir.entries(bundler_spec.gems_dir).
+ select {|default_gem| File.basename(default_gem) == "bundler-#{bundler_spec.version}" }.
+ each {|default_gem| rm_r File.join(bundler_spec.gems_dir, default_gem) }
+ end
+
+ bundler_bin_dir = bundler_spec.bin_dir
+ mkdir_p bundler_bin_dir, :mode => 0755
+ bundler_spec.executables.each do |e|
+ cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_bin_dir, e)
+ end
- mkdir_p bundler_spec.bin_dir
- bundler_spec.executables.each {|e| cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_spec.bin_dir, e) }
+ require_relative '../installer'
+
+ Dir.chdir("bundler") do
+ built_gem = Gem::Package.build(bundler_spec)
+ begin
+ Gem::Installer.at(
+ built_gem,
+ env_shebang: options[:env_shebang],
+ format_executable: options[:format_executable],
+ force: options[:force],
+ install_as_default: true,
+ bin_dir: bin_dir,
+ install_dir: default_dir,
+ wrappers: true
+ ).install
+ ensure
+ FileUtils.rm_f built_gem
+ end
+ end
+
+ bundler_spec.executables.each {|executable| bin_file_names << target_bin_path(bin_dir, executable) }
+
+ say "Bundler #{bundler_spec.version} installed"
end
- def make_destination_dirs(install_destdir)
+ def make_destination_dirs
lib_dir, bin_dir = Gem.default_rubygems_dirs
unless lib_dir
- lib_dir, bin_dir = generate_default_dirs(install_destdir)
+ lib_dir, bin_dir = generate_default_dirs
end
- mkdir_p lib_dir
- mkdir_p bin_dir
+ mkdir_p lib_dir, :mode => 0755
+ mkdir_p bin_dir, :mode => 0755
return lib_dir, bin_dir
end
- def generate_default_dirs(install_destdir)
+ def generate_default_man_dir
+ prefix = options[:prefix]
+
+ if prefix.empty?
+ man_dir = RbConfig::CONFIG['mandir']
+ return unless man_dir
+ else
+ man_dir = File.join prefix, 'man'
+ end
+
+ prepend_destdir_if_present(man_dir)
+ end
+
+ def generate_default_dirs
prefix = options[:prefix]
site_or_vendor = options[:site_or_vendor]
- if prefix.empty? then
+ if prefix.empty?
lib_dir = RbConfig::CONFIG[site_or_vendor]
bin_dir = RbConfig::CONFIG['bindir']
else
@@ -400,32 +472,22 @@ By default, this RubyGems will install gem as:
# just in case Apple and RubyGems don't get this patched up proper.
(prefix == RbConfig::CONFIG['libdir'] or
# this one is important
- prefix == File.join(RbConfig::CONFIG['libdir'], 'ruby')) then
- lib_dir = RbConfig::CONFIG[site_or_vendor]
- bin_dir = RbConfig::CONFIG['bindir']
+ prefix == File.join(RbConfig::CONFIG['libdir'], 'ruby'))
+ lib_dir = RbConfig::CONFIG[site_or_vendor]
+ bin_dir = RbConfig::CONFIG['bindir']
else
lib_dir = File.join prefix, 'lib'
bin_dir = File.join prefix, 'bin'
end
end
- unless install_destdir.empty? then
- lib_dir = File.join install_destdir, lib_dir.gsub(/^[a-zA-Z]:/, '')
- bin_dir = File.join install_destdir, bin_dir.gsub(/^[a-zA-Z]:/, '')
- end
-
- [lib_dir, bin_dir]
+ [prepend_destdir_if_present(lib_dir), prepend_destdir_if_present(bin_dir)]
end
- def pem_files_in dir
+ def files_in(dir)
Dir.chdir dir do
- Dir[File.join('**', '*pem')]
- end
- end
-
- def rb_files_in dir
- Dir.chdir dir do
- Dir[File.join('**', '*rb')]
+ Dir.glob(File.join('**', '*'), File::FNM_DOTMATCH).
+ select{|f| !File.directory?(f) }
end
end
@@ -456,47 +518,58 @@ abort "#{deprecation_message}"
next unless Gem.win_platform?
File.open "#{old_bin_path}.bat", 'w' do |fp|
- fp.puts %{@ECHO.#{deprecation_message}}
+ fp.puts %(@ECHO.#{deprecation_message})
end
end
end
- def remove_old_lib_files lib_dir
+ def remove_old_lib_files(lib_dir)
lib_dirs = { File.join(lib_dir, 'rubygems') => 'lib/rubygems' }
- lib_dirs[File.join(lib_dir, 'bundler')] = 'bundler/lib/bundler' if Gem::USE_BUNDLER_FOR_GEMDEPS
+ lib_dirs[File.join(lib_dir, 'bundler')] = 'bundler/lib/bundler'
lib_dirs.each do |old_lib_dir, new_lib_dir|
- lib_files = rb_files_in(new_lib_dir)
+ lib_files = files_in(new_lib_dir)
- old_lib_files = rb_files_in(old_lib_dir)
+ old_lib_files = files_in(old_lib_dir)
to_remove = old_lib_files - lib_files
+ gauntlet_rubygems = File.join(lib_dir, 'gauntlet_rubygems.rb')
+ to_remove << gauntlet_rubygems if File.exist? gauntlet_rubygems
+
to_remove.delete_if do |file|
file.start_with? 'defaults'
end
- Dir.chdir old_lib_dir do
- to_remove.each do |file|
- FileUtils.rm_f file
+ remove_file_list(to_remove, old_lib_dir)
+ end
+ end
+
+ def remove_old_man_files(old_man_dir)
+ old_man1_dir = "#{old_man_dir}/man1"
- warn "unable to remove old file #{file} please remove it by hand" if
- File.exist? file
- end
- end
+ if File.exist?(old_man1_dir)
+ man1_to_remove = Dir.chdir(old_man1_dir) { Dir["bundle*.1{,.txt,.ronn}"] }
+
+ remove_file_list(man1_to_remove, old_man1_dir)
+ end
+
+ old_man5_dir = "#{old_man_dir}/man5"
+
+ if File.exist?(old_man5_dir)
+ man5_to_remove = Dir.chdir(old_man5_dir) { Dir["gemfile.5{,.txt,.ronn}"] }
+
+ remove_file_list(man5_to_remove, old_man5_dir)
end
end
def show_release_notes
- release_notes = File.join Dir.pwd, 'History.txt'
+ release_notes = File.join Dir.pwd, 'CHANGELOG.md'
release_notes =
- if File.exist? release_notes then
+ if File.exist? release_notes
history = File.read release_notes
- history.force_encoding Encoding::UTF_8 if
- Object.const_defined? :Encoding
-
- history = history.sub(/^# coding:.*?(?=^=)/m, '')
+ history.force_encoding Encoding::UTF_8
text = history.split(HISTORY_HEADER)
text.shift # correct an off-by-one generated by split
@@ -508,7 +581,7 @@ abort "#{deprecation_message}"
history_string = ""
until versions.length == 0 or
- versions.shift < options[:previous_version] do
+ versions.shift <= options[:previous_version] do
history_string += version_lines.shift + text.shift
end
@@ -521,7 +594,7 @@ abort "#{deprecation_message}"
end
def uninstall_old_gemcutter
- require 'rubygems/uninstaller'
+ require_relative '../uninstaller'
ui = Gem::Uninstaller.new('gemcutter', :all => true, :ignore => true,
:version => '< 0.4')
@@ -529,11 +602,90 @@ abort "#{deprecation_message}"
rescue Gem::InstallError
end
- def regenerate_binstubs
- require "rubygems/commands/pristine_command"
+ def regenerate_binstubs(bindir)
+ require_relative "pristine_command"
say "Regenerating binstubs"
+
+ args = %w[--all --only-executables --silent]
+ args << "--bindir=#{bindir}"
+ if options[:env_shebang]
+ args << "--env-shebang"
+ end
+
command = Gem::Commands::PristineCommand.new
- command.invoke(*%w[--all --only-executables --silent])
+ command.invoke(*args)
end
+ def regenerate_plugins(bindir)
+ require_relative "pristine_command"
+ say "Regenerating plugins"
+
+ args = %w[--all --only-plugins --silent]
+ args << "--bindir=#{bindir}"
+ args << "--install-dir=#{default_dir}"
+
+ command = Gem::Commands::PristineCommand.new
+ command.invoke(*args)
+ end
+
+ private
+
+ def default_dir
+ prefix = options[:prefix]
+
+ if prefix.empty?
+ dir = Gem.default_dir
+ else
+ dir = prefix
+ end
+
+ prepend_destdir_if_present(dir)
+ end
+
+ def prepend_destdir_if_present(path)
+ destdir = options[:destdir]
+ return path if destdir.empty?
+
+ File.join(options[:destdir], path.gsub(/^[a-zA-Z]:/, ''))
+ end
+
+ def install_file_list(files, dest_dir)
+ files.each do |file|
+ install_file file, dest_dir
+ end
+ end
+
+ def install_file(file, dest_dir)
+ dest_file = File.join dest_dir, file
+ dest_dir = File.dirname dest_file
+ unless File.directory? dest_dir
+ mkdir_p dest_dir, :mode => 0755
+ end
+
+ install file, dest_file, :mode => options[:data_mode] || 0644
+ end
+
+ def remove_file_list(files, dir)
+ Dir.chdir dir do
+ files.each do |file|
+ FileUtils.rm_f file
+
+ warn "unable to remove old file #{file} please remove it by hand" if
+ File.exist? file
+ end
+ end
+ end
+
+ def target_bin_path(bin_dir, bin_file)
+ bin_file_formatted = if options[:format_executable]
+ Gem.default_exec_format % bin_file
+ else
+ bin_file
+ end
+ File.join bin_dir, bin_file_formatted
+ end
+
+ def bin_file_names
+ @bin_file_names ||= []
+ end
end
diff --git a/lib/rubygems/commands/signin_command.rb b/lib/rubygems/commands/signin_command.rb
index 6556db5a89..23bb2f937f 100644
--- a/lib/rubygems/commands/signin_command.rb
+++ b/lib/rubygems/commands/signin_command.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/gemcutter_utilities'
+require_relative '../command'
+require_relative '../gemcutter_utilities'
class Gem::Commands::SigninCommand < Gem::Command
include Gem::GemcutterUtilities
@@ -10,9 +10,10 @@ class Gem::Commands::SigninCommand < Gem::Command
'It defaults to https://rubygems.org'
add_option('--host HOST', 'Push to another gemcutter-compatible host') do |value, options|
- options[:host] = value
+ options[:host] = value
end
+ add_otp_option
end
def description # :nodoc:
@@ -29,5 +30,4 @@ class Gem::Commands::SigninCommand < Gem::Command
def execute
sign_in options[:host]
end
-
end
diff --git a/lib/rubygems/commands/signout_command.rb b/lib/rubygems/commands/signout_command.rb
index 2452e8cae1..c9485e0c1b 100644
--- a/lib/rubygems/commands/signout_command.rb
+++ b/lib/rubygems/commands/signout_command.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
class Gem::Commands::SignoutCommand < Gem::Command
-
def initialize
super 'signout', 'Sign out from all the current sessions.'
end
@@ -19,9 +18,9 @@ class Gem::Commands::SignoutCommand < Gem::Command
def execute
credentials_path = Gem.configuration.credentials_path
- if !File.exist?(credentials_path) then
+ if !File.exist?(credentials_path)
alert_error 'You are not currently signed in.'
- elsif !File.writable?(credentials_path) then
+ elsif !File.writable?(credentials_path)
alert_error "File '#{Gem.configuration.credentials_path}' is read-only."\
' Please make sure it is writable.'
else
@@ -29,5 +28,4 @@ class Gem::Commands::SignoutCommand < Gem::Command
say 'You have successfully signed out from all sessions.'
end
end
-
end
diff --git a/lib/rubygems/commands/sources_command.rb b/lib/rubygems/commands/sources_command.rb
index 7e46963a4c..9e74f3c47d 100644
--- a/lib/rubygems/commands/sources_command.rb
+++ b/lib/rubygems/commands/sources_command.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/remote_fetcher'
-require 'rubygems/spec_fetcher'
-require 'rubygems/local_remote_options'
+require_relative '../command'
+require_relative '../remote_fetcher'
+require_relative '../spec_fetcher'
+require_relative '../local_remote_options'
class Gem::Commands::SourcesCommand < Gem::Command
-
include Gem::LocalRemoteOptions
def initialize
@@ -35,16 +34,22 @@ class Gem::Commands::SourcesCommand < Gem::Command
options[:update] = value
end
+ add_option '-f', '--[no-]force', "Do not show any confirmation prompts and behave as if 'yes' was always answered" do |value, options|
+ options[:force] = value
+ end
+
add_proxy_option
end
- def add_source source_uri # :nodoc:
+ def add_source(source_uri) # :nodoc:
check_rubygems_https source_uri
source = Gem::Source.new source_uri
+ check_typo_squatting(source)
+
begin
- if Gem.sources.include? source then
+ if Gem.sources.include? source
say "source #{source_uri} already present in the cache"
else
source.load_specs :released
@@ -62,18 +67,30 @@ class Gem::Commands::SourcesCommand < Gem::Command
end
end
- def check_rubygems_https source_uri # :nodoc:
+ def check_typo_squatting(source)
+ if source.typo_squatting?("rubygems.org")
+ question = <<-QUESTION.chomp
+#{source.uri.to_s} is too similar to https://rubygems.org
+
+Do you want to add this source?
+ QUESTION
+
+ terminate_interaction 1 unless options[:force] || ask_yes_no(question)
+ end
+ end
+
+ def check_rubygems_https(source_uri) # :nodoc:
uri = URI source_uri
if uri.scheme and uri.scheme.downcase == 'http' and
- uri.host.downcase == 'rubygems.org' then
+ uri.host.downcase == 'rubygems.org'
question = <<-QUESTION.chomp
https://rubygems.org is recommended for security over #{uri}
Do you want to add this insecure source?
QUESTION
- terminate_interaction 1 unless ask_yes_no question
+ terminate_interaction 1 unless options[:force] || ask_yes_no(question)
end
end
@@ -81,10 +98,10 @@ Do you want to add this insecure source?
path = Gem.spec_cache_dir
FileUtils.rm_rf path
- unless File.exist? path then
+ unless File.exist? path
say "*** Removed specs cache ***"
else
- unless File.writable? path then
+ unless File.writable? path
say "*** Unable to remove source cache (write protected) ***"
else
say "*** Unable to remove source cache ***"
@@ -122,7 +139,7 @@ RubyGems has been configured to serve gems via the following URLs through
its history:
* http://gems.rubyforge.org (RubyGems 1.3.6 and earlier)
-* http://rubygems.org (RubyGems 1.3.7 through 1.8.25)
+* https://rubygems.org/ (RubyGems 1.3.7 through 1.8.25)
* https://rubygems.org (RubyGems 2.0.1 and newer)
Since all of these sources point to the same set of gems you only need one
@@ -139,8 +156,8 @@ before it is added.
To remove a source use the --remove argument:
- $ gem sources --remove http://rubygems.org
- http://rubygems.org removed from sources
+ $ gem sources --remove https://rubygems.org/
+ https://rubygems.org/ removed from sources
EOF
end
@@ -175,8 +192,8 @@ To remove a source use the --remove argument:
list if list?
end
- def remove_source source_uri # :nodoc:
- unless Gem.sources.include? source_uri then
+ def remove_source(source_uri) # :nodoc:
+ unless Gem.sources.include? source_uri
say "source #{source_uri} not present in cache"
else
Gem.sources.delete source_uri
@@ -195,17 +212,15 @@ To remove a source use the --remove argument:
say "source cache successfully updated"
end
- def remove_cache_file desc, path # :nodoc:
+ def remove_cache_file(desc, path) # :nodoc:
FileUtils.rm_rf path
- if not File.exist?(path) then
+ if not File.exist?(path)
say "*** Removed #{desc} source cache ***"
- elsif not File.writable?(path) then
+ elsif not File.writable?(path)
say "*** Unable to remove #{desc} source cache (write protected) ***"
else
say "*** Unable to remove #{desc} source cache ***"
end
end
-
end
-
diff --git a/lib/rubygems/commands/specification_command.rb b/lib/rubygems/commands/specification_command.rb
index ad8840adc2..473b6e7b19 100644
--- a/lib/rubygems/commands/specification_command.rb
+++ b/lib/rubygems/commands/specification_command.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/version_option'
-require 'rubygems/package'
+require_relative '../command'
+require_relative '../local_remote_options'
+require_relative '../version_option'
+require_relative '../package'
class Gem::Commands::SpecificationCommand < Gem::Command
-
include Gem::LocalRemoteOptions
include Gem::VersionOption
@@ -75,7 +74,7 @@ Specific fields in the specification can be extracted in YAML format:
specs = []
gem = options[:args].shift
- unless gem then
+ unless gem
raise Gem::CommandLineError,
"Please specify a gem name or file on the command line"
end
@@ -105,30 +104,36 @@ Specific fields in the specification can be extracted in YAML format:
raise Gem::CommandLineError, "--ruby and FIELD are mutually exclusive" if
field and options[:format] == :ruby
- if local? then
- if File.exist? gem then
+ if local?
+ if File.exist? gem
specs << Gem::Package.new(gem).spec rescue nil
end
- if specs.empty? then
+ if specs.empty?
specs.push(*dep.matching_specs)
end
end
- if remote? then
+ if remote?
dep.prerelease = options[:prerelease]
found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep
- specs.push(*found.map { |spec,| spec })
+ specs.push(*found.map {|spec,| spec })
end
- if specs.empty? then
+ if specs.empty?
alert_error "No gem matching '#{dep}' found"
terminate_interaction 1
end
- unless options[:all] then
- specs = [specs.max_by { |s| s.version }]
+ platform = get_platform_from_requirements(options)
+
+ if platform
+ specs = specs.select{|s| s.platform.to_s == platform }
+ end
+
+ unless options[:all]
+ specs = [specs.max_by {|s| s.version }]
end
specs.each do |s|
diff --git a/lib/rubygems/commands/stale_command.rb b/lib/rubygems/commands/stale_command.rb
index 0524ee1e2b..62a97966f1 100644
--- a/lib/rubygems/commands/stale_command.rb
+++ b/lib/rubygems/commands/stale_command.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
class Gem::Commands::StaleCommand < Gem::Command
def initialize
@@ -32,7 +32,7 @@ longer using.
end
end
- gem_to_atime.sort_by { |_, atime| atime }.each do |name, atime|
+ gem_to_atime.sort_by {|_, atime| atime }.each do |name, atime|
say "#{name} at #{atime.strftime '%c'}"
end
end
diff --git a/lib/rubygems/commands/uninstall_command.rb b/lib/rubygems/commands/uninstall_command.rb
index 20b3a7a1e4..467c8bf7ed 100644
--- a/lib/rubygems/commands/uninstall_command.rb
+++ b/lib/rubygems/commands/uninstall_command.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/version_option'
-require 'rubygems/uninstaller'
+require_relative '../command'
+require_relative '../version_option'
+require_relative '../uninstaller'
require 'fileutils'
##
@@ -10,7 +10,6 @@ require 'fileutils'
# See `gem help uninstall`
class Gem::Commands::UninstallCommand < Gem::Command
-
include Gem::VersionOption
def initialize
@@ -20,7 +19,7 @@ class Gem::Commands::UninstallCommand < Gem::Command
add_option('-a', '--[no-]all',
'Uninstall all matching versions'
- ) do |value, options|
+ ) do |value, options|
options[:all] = value
end
@@ -48,7 +47,7 @@ class Gem::Commands::UninstallCommand < Gem::Command
end
add_option('-n', '--bindir DIR',
- 'Directory to remove binaries from') do |value, options|
+ 'Directory to remove executables from') do |value, options|
options[:bin_dir] = File.expand_path(value)
end
@@ -81,8 +80,8 @@ class Gem::Commands::UninstallCommand < Gem::Command
add_option('--vendor',
'Uninstall gem from the vendor directory.',
'Only for use by gem repackagers.') do |value, options|
- unless Gem.vendor_dir then
- raise OptionParser::InvalidOption.new 'your platform is not supported'
+ unless Gem.vendor_dir
+ raise Gem::OptionParser::InvalidOption.new 'your platform is not supported'
end
alert_warning 'Use your OS package manager to uninstall vendor gems'
@@ -114,10 +113,21 @@ that is a dependency of an existing gem. You can use the
"#{program_name} GEMNAME [GEMNAME ...]"
end
+ def check_version # :nodoc:
+ if options[:version] != Gem::Requirement.default and
+ get_all_gem_names.size > 1
+ alert_error "Can't use --version with multiple gems. You can specify multiple gems with" \
+ " version requirements using `gem uninstall 'my_gem:1.0.0' 'my_other_gem:~>2.0.0'`"
+ terminate_interaction 1
+ end
+ end
+
def execute
- if options[:all] and not options[:args].empty? then
+ check_version
+
+ if options[:all] and not options[:args].empty?
uninstall_specific
- elsif options[:all] then
+ elsif options[:all]
uninstall_all
else
uninstall_specific
@@ -125,25 +135,25 @@ that is a dependency of an existing gem. You can use the
end
def uninstall_all
- specs = Gem::Specification.reject { |spec| spec.default_gem? }
+ specs = Gem::Specification.reject {|spec| spec.default_gem? }
specs.each do |spec|
options[:version] = spec.version
-
- begin
- Gem::Uninstaller.new(spec.name, options).uninstall
- rescue Gem::InstallError
- end
+ uninstall_gem spec.name
end
- alert "Uninstalled all gems in #{options[:install_dir]}"
+ alert "Uninstalled all gems in #{options[:install_dir] || Gem.dir}"
end
def uninstall_specific
deplist = Gem::DependencyList.new
+ original_gem_version = {}
+
+ get_all_gem_names_and_versions.each do |name, version|
+ original_gem_version[name] = version || options[:version]
+
+ gem_specs = Gem::Specification.find_all_by_name(name, original_gem_version[name])
- get_all_gem_names.uniq.each do |name|
- gem_specs = Gem::Specification.find_all_by_name(name)
say("Gem '#{name}' is not installed") if gem_specs.empty?
gem_specs.each do |spec|
deplist.add spec
@@ -152,15 +162,36 @@ that is a dependency of an existing gem. You can use the
deps = deplist.strongly_connected_components.flatten.reverse
- deps.map(&:name).uniq.each do |gem_name|
- begin
- Gem::Uninstaller.new(gem_name, options).uninstall
- rescue Gem::GemNotInHomeException => e
- spec = e.spec
- alert("In order to remove #{spec.name}, please execute:\n" +
- "\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}")
+ gems_to_uninstall = {}
+
+ deps.each do |dep|
+ unless gems_to_uninstall[dep.name]
+ gems_to_uninstall[dep.name] = true
+
+ unless original_gem_version[dep.name] == Gem::Requirement.default
+ options[:version] = dep.version
+ end
+
+ uninstall_gem(dep.name)
end
end
end
+ def uninstall_gem(gem_name)
+ uninstall(gem_name)
+ rescue Gem::GemNotInHomeException => e
+ spec = e.spec
+ alert("In order to remove #{spec.name}, please execute:\n" +
+ "\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}")
+ rescue Gem::UninstallError => e
+ spec = e.spec
+ alert_error("Error: unable to successfully uninstall '#{spec.name}' which is " +
+ "located at '#{spec.full_gem_path}'. This is most likely because" +
+ "the current user does not have the appropriate permissions")
+ terminate_interaction 1
+ end
+
+ def uninstall(gem_name)
+ Gem::Uninstaller.new(gem_name, options).uninstall
+ end
end
diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb
index eb7f550673..3f1708375f 100644
--- a/lib/rubygems/commands/unpack_command.rb
+++ b/lib/rubygems/commands/unpack_command.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/installer'
-require 'rubygems/version_option'
-require 'rubygems/security_option'
-require 'rubygems/remote_fetcher'
+require_relative '../command'
+require_relative '../version_option'
+require_relative '../security_option'
+require_relative '../remote_fetcher'
+require_relative '../package'
# forward-declare
@@ -13,7 +13,6 @@ module Gem::Security # :nodoc:
end
class Gem::Commands::UnpackCommand < Gem::Command
-
include Gem::VersionOption
include Gem::SecurityOption
@@ -79,22 +78,32 @@ command help for an example.
dependency = Gem::Dependency.new name, options[:version]
path = get_path dependency
- unless path then
+ unless path
alert_error "Gem '#{name}' not installed nor fetchable."
next
end
- if @options[:spec] then
- spec, metadata = get_metadata path, security_policy
+ if @options[:spec]
+ spec, metadata = Gem::Package.raw_spec(path, security_policy)
- if metadata.nil? then
+ if metadata.nil?
alert_error "--spec is unsupported on '#{name}' (old format gem)"
next
end
spec_file = File.basename spec.spec_file
- open spec_file, 'w' do |io|
+ FileUtils.mkdir_p @options[:target] if @options[:target]
+
+ destination = begin
+ if @options[:target]
+ File.join @options[:target], spec_file
+ else
+ spec_file
+ end
+ end
+
+ File.open destination, 'w' do |io|
io.write metadata
end
else
@@ -142,12 +151,12 @@ command help for an example.
# TODO: It just uses Gem.dir for now. What's an easy way to get the list of
# source directories?
- def get_path dependency
+ def get_path(dependency)
return dependency.name if dependency.name =~ /\.gem$/i
specs = dependency.matching_specs
- selected = specs.max_by { |s| s.version }
+ selected = specs.max_by {|s| s.version }
return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
selected
@@ -163,33 +172,4 @@ command help for an example.
path
end
-
- ##
- # Extracts the Gem::Specification and raw metadata from the .gem file at
- # +path+.
- #--
- # TODO move to Gem::Package as #raw_spec or something
-
- def get_metadata path, security_policy = nil
- format = Gem::Package.new path, security_policy
- spec = format.spec
-
- metadata = nil
-
- open path, Gem.binary_mode do |io|
- tar = Gem::Package::TarReader.new io
- tar.each_entry do |entry|
- case entry.full_name
- when 'metadata' then
- metadata = entry.read
- when 'metadata.gz' then
- metadata = Gem.gunzip entry.read
- end
- end
- end
-
- return spec, metadata
- end
-
end
-
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index 93ee60e1ab..bb356fd610 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -1,16 +1,15 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/command_manager'
-require 'rubygems/dependency_installer'
-require 'rubygems/install_update_options'
-require 'rubygems/local_remote_options'
-require 'rubygems/spec_fetcher'
-require 'rubygems/version_option'
-require 'rubygems/install_message' # must come before rdoc for messaging
-require 'rubygems/rdoc'
+require_relative '../command'
+require_relative '../command_manager'
+require_relative '../dependency_installer'
+require_relative '../install_update_options'
+require_relative '../local_remote_options'
+require_relative '../spec_fetcher'
+require_relative '../version_option'
+require_relative '../install_message' # must come before rdoc for messaging
+require_relative '../rdoc'
class Gem::Commands::UpdateCommand < Gem::Command
-
include Gem::InstallUpdateOptions
include Gem::LocalRemoteOptions
include Gem::VersionOption
@@ -26,7 +25,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
add_install_update_options
- OptionParser.accept Gem::Version do |value|
+ Gem::OptionParser.accept Gem::Version do |value|
Gem::Version.new value
value
@@ -68,41 +67,56 @@ command to remove old versions.
"#{program_name} GEMNAME [GEMNAME ...]"
end
- def check_latest_rubygems version # :nodoc:
- if Gem.rubygems_version == version then
+ def check_latest_rubygems(version) # :nodoc:
+ if Gem.rubygems_version == version
say "Latest version already installed. Done."
terminate_interaction
end
+ end
- options[:user_install] = false
+ def check_oldest_rubygems(version) # :nodoc:
+ if oldest_supported_version > version
+ alert_error "rubygems #{version} is not supported on #{RUBY_VERSION}. The oldest version supported by this ruby is #{oldest_supported_version}"
+ terminate_interaction 1
+ end
end
def check_update_arguments # :nodoc:
- unless options[:args].empty? then
+ unless options[:args].empty?
alert_error "Gem names are not allowed with the --system option"
terminate_interaction 1
end
end
def execute
-
- if options[:system] then
+ if options[:system]
update_rubygems
return
end
- say "Updating installed gems"
+ gems_to_update = which_to_update(
+ highest_installed_gems,
+ options[:args].uniq
+ )
- hig = highest_installed_gems
+ if options[:explain]
+ say "Gems to update:"
- gems_to_update = which_to_update hig, options[:args].uniq
+ gems_to_update.each do |name_tuple|
+ say " #{name_tuple.full_name}"
+ end
+
+ return
+ end
+
+ say "Updating installed gems"
updated = update_gems gems_to_update
- updated_names = updated.map { |spec| spec.name }
+ updated_names = updated.map {|spec| spec.name }
not_updated_names = options[:args].uniq - updated_names
- if updated.empty? then
+ if updated.empty?
say "Nothing to update"
else
say "Gems updated: #{updated_names.join(' ')}"
@@ -110,7 +124,7 @@ command to remove old versions.
end
end
- def fetch_remote_gems spec # :nodoc:
+ def fetch_remote_gems(spec) # :nodoc:
dependency = Gem::Dependency.new spec.name, "> #{spec.version}"
dependency.prerelease = options[:prerelease]
@@ -118,7 +132,7 @@ command to remove old versions.
spec_tuples, errors = fetcher.search_for_dependency dependency
- error = errors.find { |e| e.respond_to? :exception }
+ error = errors.find {|e| e.respond_to? :exception }
raise error if error
@@ -128,8 +142,11 @@ command to remove old versions.
def highest_installed_gems # :nodoc:
hig = {} # highest installed gems
+ # Get only gem specifications installed as --user-install
+ Gem::Specification.dirs = Gem.user_dir if options[:user_install]
+
Gem::Specification.each do |spec|
- if hig[spec.name].nil? or hig[spec.name].version < spec.version then
+ if hig[spec.name].nil? or hig[spec.name].version < spec.version
hig[spec.name] = spec
end
end
@@ -137,34 +154,53 @@ command to remove old versions.
hig
end
- def highest_remote_version spec # :nodoc:
+ def highest_remote_name_tuple(spec) # :nodoc:
spec_tuples = fetch_remote_gems spec
matching_gems = spec_tuples.select do |g,_|
g.name == spec.name and g.match_platform?
end
- highest_remote_gem = matching_gems.max_by { |g,_| g.version }
+ highest_remote_gem = matching_gems.max
highest_remote_gem ||= [Gem::NameTuple.null]
- highest_remote_gem.first.version
+ highest_remote_gem.first
end
- def install_rubygems version # :nodoc:
+ def install_rubygems(version) # :nodoc:
args = update_rubygems_arguments
update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}"
Dir.chdir update_dir do
- say "Installing RubyGems #{version}"
-
- # Make sure old rubygems isn't loaded
- old = ENV["RUBYOPT"]
- ENV.delete("RUBYOPT") if old
- installed = system Gem.ruby, 'setup.rb', *args
- say "RubyGems system software updated" if installed
- ENV["RUBYOPT"] = old if old
+ say "Installing RubyGems #{version}" unless options[:silent]
+
+ installed = preparing_gem_layout_for(version) do
+ system Gem.ruby, '--disable-gems', 'setup.rb', *args
+ end
+
+ say "RubyGems system software updated" if installed unless options[:silent]
+ end
+ end
+
+ def preparing_gem_layout_for(version)
+ if Gem::Version.new(version) >= Gem::Version.new("3.2.a")
+ yield
+ else
+ require "tmpdir"
+ tmpdir = Dir.mktmpdir
+ FileUtils.mv Gem.plugindir, tmpdir
+
+ status = yield
+
+ if status
+ FileUtils.rm_rf tmpdir
+ else
+ FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugindir
+ end
+
+ status
end
end
@@ -172,7 +208,7 @@ command to remove old versions.
version = options[:system]
update_latest = version == true
- if update_latest then
+ if update_latest
version = Gem::Version.new Gem::VERSION
requirement = Gem::Requirement.new ">= #{Gem::VERSION}"
else
@@ -185,13 +221,13 @@ command to remove old versions.
rubygems_update.version = version
hig = {
- 'rubygems-update' => rubygems_update
+ 'rubygems-update' => rubygems_update,
}
gems_to_update = which_to_update hig, options[:args], :system
- _, up_ver = gems_to_update.first
+ up_ver = gems_to_update.first.version
- target = if update_latest then
+ target = if update_latest
up_ver
else
version
@@ -200,15 +236,15 @@ command to remove old versions.
return target, requirement
end
- def update_gem name, version = Gem::Requirement.default
- return if @updated.any? { |spec| spec.name == name }
+ def update_gem(name, version = Gem::Requirement.default)
+ return if @updated.any? {|spec| spec.name == name }
update_options = options.dup
update_options[:prerelease] = version.prerelease?
@installer = Gem::DependencyInstaller.new update_options
- say "Updating #{name}"
+ say "Updating #{name}" unless options[:system] && options[:silent]
begin
@installer.install name, Gem::Requirement.new(version)
rescue Gem::InstallError, Gem::DependencyError => e
@@ -220,9 +256,9 @@ command to remove old versions.
end
end
- def update_gems gems_to_update
- gems_to_update.uniq.sort.each do |(name, version)|
- update_gem name, version
+ def update_gems(gems_to_update)
+ gems_to_update.uniq.sort.each do |name_tuple|
+ update_gem name_tuple.name, name_tuple.version
end
@updated
@@ -232,12 +268,19 @@ command to remove old versions.
# Update RubyGems software to the latest version.
def update_rubygems
+ if Gem.disable_system_update_message
+ alert_error Gem.disable_system_update_message
+ terminate_interaction 1
+ end
+
check_update_arguments
version, requirement = rubygems_target_version
check_latest_rubygems version
+ check_oldest_rubygems version
+
update_gem 'rubygems-update', version
installed_gems = Gem::Specification.find_all_by_name 'rubygems-update', requirement
@@ -248,10 +291,9 @@ command to remove old versions.
def update_rubygems_arguments # :nodoc:
args = []
+ args << '--silent' if options[:silent]
args << '--prefix' << Gem.prefix if Gem.prefix
- # TODO use --document for >= 1.9 , --no-rdoc --no-ri < 1.9
- args << '--no-rdoc' unless options[:document].include? 'rdoc'
- args << '--no-ri' unless options[:document].include? 'ri'
+ args << '--no-document' unless options[:document].include?('rdoc') || options[:document].include?('ri')
args << '--no-format-executable' if options[:no_format_executable]
args << '--previous-version' << Gem::VERSION if
options[:system] == true or
@@ -259,21 +301,47 @@ command to remove old versions.
args
end
- def which_to_update highest_installed_gems, gem_names, system = false
+ def which_to_update(highest_installed_gems, gem_names, system = false)
result = []
highest_installed_gems.each do |l_name, l_spec|
next if not gem_names.empty? and
- gem_names.none? { |name| name == l_spec.name }
+ gem_names.none? {|name| name == l_spec.name }
- highest_remote_ver = highest_remote_version l_spec
+ highest_remote_tup = highest_remote_name_tuple l_spec
+ highest_remote_ver = highest_remote_tup.version
+ highest_installed_ver = l_spec.version
- if system or (l_spec.version < highest_remote_ver) then
- result << [l_spec.name, [l_spec.version, highest_remote_ver].max]
+ if system or (highest_installed_ver < highest_remote_ver)
+ result << Gem::NameTuple.new(l_spec.name, [highest_installed_ver, highest_remote_ver].max, highest_remote_tup.platform)
end
end
result
end
+ private
+
+ #
+ # Oldest version we support downgrading to. This is the version that
+ # originally ships with the first patch version of each ruby, because we never
+ # test each ruby against older rubygems, so we can't really guarantee it
+ # works. Version list can be checked here: https://stdgems.org/rubygems
+ #
+ def oldest_supported_version
+ @oldest_supported_version ||=
+ if Gem.ruby_version > Gem::Version.new("3.0.a")
+ Gem::Version.new("3.2.3")
+ elsif Gem.ruby_version > Gem::Version.new("2.7.a")
+ Gem::Version.new("3.1.2")
+ elsif Gem.ruby_version > Gem::Version.new("2.6.a")
+ Gem::Version.new("3.0.1")
+ elsif Gem.ruby_version > Gem::Version.new("2.5.a")
+ Gem::Version.new("2.7.3")
+ elsif Gem.ruby_version > Gem::Version.new("2.4.a")
+ Gem::Version.new("2.6.8")
+ else
+ Gem::Version.new("2.5.2")
+ end
+ end
end
diff --git a/lib/rubygems/commands/which_command.rb b/lib/rubygems/commands/which_command.rb
index 704d79fc60..44e87a2b98 100644
--- a/lib/rubygems/commands/which_command.rb
+++ b/lib/rubygems/commands/which_command.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require 'rubygems/command'
+require_relative '../command'
class Gem::Commands::WhichCommand < Gem::Command
def initialize
@@ -44,21 +44,19 @@ requiring to see why it does not behave as you expect.
spec = Gem::Specification.find_by_path arg
- if spec then
- if options[:search_gems_first] then
+ if spec
+ if options[:search_gems_first]
dirs = spec.full_require_paths + $LOAD_PATH
else
dirs = $LOAD_PATH + spec.full_require_paths
end
end
- # TODO: this is totally redundant and stupid
paths = find_paths arg, dirs
- if paths.empty? then
+ if paths.empty?
alert_error "Can't find Ruby library file or shared library #{arg}"
-
- found &&= false
+ found = false
else
say paths
end
@@ -73,7 +71,7 @@ requiring to see why it does not behave as you expect.
dirs.each do |dir|
Gem.suffixes.each do |ext|
full_path = File.join dir, "#{package_name}#{ext}"
- if File.exist? full_path and not File.directory? full_path then
+ if File.exist? full_path and not File.directory? full_path
result << full_path
return result unless options[:show_all]
end
@@ -86,6 +84,4 @@ requiring to see why it does not behave as you expect.
def usage # :nodoc:
"#{program_name} FILE [FILE ...]"
end
-
end
-
diff --git a/lib/rubygems/commands/yank_command.rb b/lib/rubygems/commands/yank_command.rb
index ebf24e5c77..cad78aec5f 100644
--- a/lib/rubygems/commands/yank_command.rb
+++ b/lib/rubygems/commands/yank_command.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require 'rubygems/command'
-require 'rubygems/local_remote_options'
-require 'rubygems/version_option'
-require 'rubygems/gemcutter_utilities'
+require_relative '../command'
+require_relative '../local_remote_options'
+require_relative '../version_option'
+require_relative '../gemcutter_utilities'
class Gem::Commands::YankCommand < Gem::Command
include Gem::LocalRemoteOptions
@@ -24,7 +24,7 @@ data you will need to change them immediately and yank your gem.
end
def usage # :nodoc:
- "#{program_name} GEM -v VERSION [-p PLATFORM] [--key KEY_NAME] [--host HOST]"
+ "#{program_name} -v VERSION [-p PLATFORM] [--key KEY_NAME] [--host HOST] GEM"
end
def initialize
@@ -32,6 +32,7 @@ data you will need to change them immediately and yank your gem.
add_version_option("remove")
add_platform_option("remove")
+ add_otp_option
add_option('--host HOST',
'Yank from another gemcutter-compatible host',
@@ -46,12 +47,12 @@ data you will need to change them immediately and yank your gem.
def execute
@host = options[:host]
- sign_in @host
+ sign_in @host, scope: get_yank_scope
version = get_version_from_requirements(options[:version])
platform = get_platform_from_requirements(options)
- if version then
+ if version
yank_gem(version, platform)
else
say "A version argument is required: #{usage}"
@@ -61,14 +62,17 @@ data you will need to change them immediately and yank your gem.
def yank_gem(version, platform)
say "Yanking gem from #{self.host}..."
- yank_api_request(:delete, version, platform, "api/v1/gems/yank")
+ args = [:delete, version, platform, "api/v1/gems/yank"]
+ response = yank_api_request(*args)
+
+ say response.body
end
private
def yank_api_request(method, version, platform, api)
name = get_one_gem_name
- response = rubygems_api_request(method, api, host) do |request|
+ response = rubygems_api_request(method, api, host, scope: get_yank_scope) do |request|
request.add_field("Authorization", api_key)
data = {
@@ -79,7 +83,7 @@ data you will need to change them immediately and yank your gem.
request.set_form_data data
end
- say response.body
+ response
end
def get_version_from_requirements(requirements)
@@ -88,9 +92,7 @@ data you will need to change them immediately and yank your gem.
nil
end
- def get_platform_from_requirements(requirements)
- Gem.platforms[1].to_s if requirements.key? :added_platform
+ def get_yank_scope
+ :yank_rubygem
end
-
end
-
diff --git a/lib/rubygems/compatibility.rb b/lib/rubygems/compatibility.rb
index 2056b5b53a..f1d452ea04 100644
--- a/lib/rubygems/compatibility.rb
+++ b/lib/rubygems/compatibility.rb
@@ -9,31 +9,11 @@
# Ruby 1.9.x has introduced some things that are awkward, and we need to
# support them, so we define some constants to use later.
#++
-module Gem
- # Only MRI 1.9.2 has the custom prelude.
- GEM_PRELUDE_SUCKAGE = RUBY_VERSION =~ /^1\.9\.2/ and RUBY_ENGINE == "ruby"
-end
-
-# Gem::QuickLoader exists in the gem prelude code in ruby 1.9.2 itself.
-# We gotta get rid of it if it's there, before we do anything else.
-if Gem::GEM_PRELUDE_SUCKAGE and defined?(Gem::QuickLoader) then
- Gem::QuickLoader.remove
-
- $LOADED_FEATURES.delete Gem::QuickLoader.path_to_full_rubygems_library
-
- if path = $LOADED_FEATURES.find {|n| n.end_with? '/rubygems.rb'} then
- raise LoadError, "another rubygems is already loaded from #{path}"
- end
-
- class << Gem
- remove_method :try_activate if Gem.respond_to?(:try_activate, true)
- end
-end
+# TODO remove at RubyGems 4
module Gem
RubyGemsVersion = VERSION
-
- # TODO remove at RubyGems 3
+ deprecate_constant(:RubyGemsVersion)
RbConfigPriorities = %w[
MAJOR
@@ -42,19 +22,19 @@ module Gem
EXEEXT RUBY_SO_NAME arch bindir datadir libdir ruby_install_name
ruby_version rubylibprefix sitedir sitelibdir vendordir vendorlibdir
rubylibdir
- ]
+ ].freeze
unless defined?(ConfigMap)
##
# Configuration settings from ::RbConfig
- ConfigMap = Hash.new do |cm, key| # TODO remove at RubyGems 3
+ ConfigMap = Hash.new do |cm, key|
cm[key] = RbConfig::CONFIG[key.to_s]
end
+ deprecate_constant(:ConfigMap)
else
RbConfigPriorities.each do |key|
ConfigMap[key.to_sym] = RbConfig::CONFIG[key]
end
end
- RubyGemsPackageVersion = VERSION
end
diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb
index a4efed0f5a..60c1d50ba9 100644
--- a/lib/rubygems/config_file.rb
+++ b/lib/rubygems/config_file.rb
@@ -5,7 +5,7 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems/user_interaction'
+require_relative 'user_interaction'
require 'rbconfig'
##
@@ -27,6 +27,7 @@ require 'rbconfig'
# +:backtrace+:: See #backtrace
# +:sources+:: Sets Gem::sources
# +:verbose+:: See #verbose
+# +:concurrent_downloads+:: See #concurrent_downloads
#
# gemrc files may exist in various locations and are read and merged in
# the following order:
@@ -36,19 +37,21 @@ require 'rbconfig'
# - per environment (gemrc files listed in the GEMRC environment variable)
class Gem::ConfigFile
-
include Gem::UserInteraction
DEFAULT_BACKTRACE = false
DEFAULT_BULK_THRESHOLD = 1000
DEFAULT_VERBOSITY = true
DEFAULT_UPDATE_SOURCES = true
+ DEFAULT_CONCURRENT_DOWNLOADS = 8
+ DEFAULT_CERT_EXPIRATION_LENGTH_DAYS = 365
+ DEFAULT_IPV4_FALLBACK_ENABLED = false
##
# For Ruby packagers to set configuration defaults. Set in
# rubygems/defaults/operating_system.rb
- OPERATING_SYSTEM_DEFAULTS = {}
+ OPERATING_SYSTEM_DEFAULTS = Gem.operating_system_defaults
##
# For Ruby implementers to set configuration defaults. Set in
@@ -63,26 +66,7 @@ class Gem::ConfigFile
require "etc"
Etc.sysconfdir
rescue LoadError, NoMethodError
- begin
- # TODO: remove after we drop 1.8.7 and 1.9.1
- require 'Win32API'
-
- CSIDL_COMMON_APPDATA = 0x0023
- path = 0.chr * 260
- if RUBY_VERSION > '1.9' then
- SHGetFolderPath = Win32API.new 'shell32', 'SHGetFolderPath', 'PLPLP',
- 'L', :stdcall
- SHGetFolderPath.call nil, CSIDL_COMMON_APPDATA, nil, 1, path
- else
- SHGetFolderPath = Win32API.new 'shell32', 'SHGetFolderPath', 'LLLLP',
- 'L'
- SHGetFolderPath.call 0, CSIDL_COMMON_APPDATA, 0, 1, path
- end
-
- path.strip
- rescue LoadError
- RbConfig::CONFIG["sysconfdir"] || "/etc"
- end
+ RbConfig::CONFIG["sysconfdir"] || "/etc"
end
# :startdoc:
@@ -124,6 +108,11 @@ class Gem::ConfigFile
attr_accessor :verbose
##
+ # Number of gem downloads that should be performed concurrently.
+
+ attr_accessor :concurrent_downloads
+
+ ##
# True if we want to update the SourceInfoCache every time, false otherwise
attr_accessor :update_sources
@@ -148,6 +137,17 @@ class Gem::ConfigFile
attr_accessor :sources
##
+ # Expiration length to sign a certificate
+
+ attr_accessor :cert_expiration_length_days
+
+ ##
+ # == Experimental ==
+ # Fallback to IPv4 when IPv6 is not reachable or slow (default: false)
+
+ attr_accessor :ipv4_fallback_enabled
+
+ ##
# Path name of directory or file of openssl client certificate, used for remote https connection with client authentication
attr_reader :ssl_client_cert
@@ -174,53 +174,44 @@ class Gem::ConfigFile
# TODO: parse options upstream, pass in options directly
def initialize(args)
- @config_file_name = nil
- need_config_file_name = false
-
- arg_list = []
-
- args.each do |arg|
- if need_config_file_name then
- @config_file_name = arg
- need_config_file_name = false
- elsif arg =~ /^--config-file=(.*)/ then
- @config_file_name = $1
- elsif arg =~ /^--config-file$/ then
- need_config_file_name = true
- else
- arg_list << arg
- end
- end
+ set_config_file_name(args)
@backtrace = DEFAULT_BACKTRACE
@bulk_threshold = DEFAULT_BULK_THRESHOLD
@verbose = DEFAULT_VERBOSITY
@update_sources = DEFAULT_UPDATE_SOURCES
+ @concurrent_downloads = DEFAULT_CONCURRENT_DOWNLOADS
+ @cert_expiration_length_days = DEFAULT_CERT_EXPIRATION_LENGTH_DAYS
+ @ipv4_fallback_enabled = ENV['IPV4_FALLBACK_ENABLED'] == 'true' || DEFAULT_IPV4_FALLBACK_ENABLED
operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
system_config = load_file SYSTEM_WIDE_CONFIG_FILE
- user_config = load_file config_file_name.dup.untaint
- environment_config = (ENV['GEMRC'] || '').split(/[:;]/).inject({}) do |result, file|
- result.merge load_file file
- end
+ user_config = load_file config_file_name.dup.tap(&Gem::UNTAINT)
+
+ environment_config = (ENV['GEMRC'] || '')
+ .split(File::PATH_SEPARATOR).inject({}) do |result, file|
+ result.merge load_file file
+ end
@hash = operating_system_config.merge platform_config
- unless arg_list.index '--norc'
+ unless args.index '--norc'
@hash = @hash.merge system_config
@hash = @hash.merge user_config
@hash = @hash.merge environment_config
end
# HACK these override command-line args, which is bad
- @backtrace = @hash[:backtrace] if @hash.key? :backtrace
- @bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold
- @home = @hash[:gemhome] if @hash.key? :gemhome
- @path = @hash[:gempath] if @hash.key? :gempath
- @update_sources = @hash[:update_sources] if @hash.key? :update_sources
- @verbose = @hash[:verbose] if @hash.key? :verbose
- @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
- @sources = @hash[:sources] if @hash.key? :sources
+ @backtrace = @hash[:backtrace] if @hash.key? :backtrace
+ @bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold
+ @home = @hash[:gemhome] if @hash.key? :gemhome
+ @path = @hash[:gempath] if @hash.key? :gempath
+ @update_sources = @hash[:update_sources] if @hash.key? :update_sources
+ @verbose = @hash[:verbose] if @hash.key? :verbose
+ @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
+ @sources = @hash[:sources] if @hash.key? :sources
+ @cert_expiration_length_days = @hash[:cert_expiration_length_days] if @hash.key? :cert_expiration_length_days
+ @ipv4_fallback_enabled = @hash[:ipv4_fallback_enabled] if @hash.key? :ipv4_fallback_enabled
@ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
@ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
@@ -229,7 +220,7 @@ class Gem::ConfigFile
@api_keys = nil
@rubygems_api_key = nil
- handle_arguments arg_list
+ handle_arguments args
end
##
@@ -278,19 +269,24 @@ if you believe they were disclosed to a third party.
# Location of RubyGems.org credentials
def credentials_path
- File.join Gem.user_home, '.gem', 'credentials'
+ credentials = File.join Gem.user_home, '.gem', 'credentials'
+ if File.exist? credentials
+ credentials
+ else
+ File.join Gem.data_home, "gem", "credentials"
+ end
end
def load_api_keys
check_credentials_permissions
- @api_keys = if File.exist? credentials_path then
+ @api_keys = if File.exist? credentials_path
load_file(credentials_path)
else
@hash
end
- if @api_keys.key? :rubygems_api_key then
+ if @api_keys.key? :rubygems_api_key
@rubygems_api_key = @api_keys[:rubygems_api_key]
@api_keys[:rubygems] = @api_keys.delete :rubygems_api_key unless
@api_keys.key? :rubygems
@@ -309,7 +305,7 @@ if you believe they were disclosed to a third party.
##
# Sets the RubyGems.org API key to +api_key+
- def rubygems_api_key= api_key
+ def rubygems_api_key=(api_key)
set_api_key :rubygems_api_key, api_key
@rubygems_api_key = api_key
@@ -318,13 +314,14 @@ if you believe they were disclosed to a third party.
##
# Set a specific host's API key to +api_key+
- def set_api_key host, api_key
+ def set_api_key(host, api_key)
check_credentials_permissions
config = load_file(credentials_path).merge(host => api_key)
dirname = File.dirname credentials_path
- Dir.mkdir(dirname) unless File.exist? dirname
+ require 'fileutils'
+ FileUtils.mkdir_p(dirname)
Gem.load_yaml
@@ -351,7 +348,7 @@ if you believe they were disclosed to a third party.
yaml_errors = [ArgumentError]
yaml_errors << Psych::SyntaxError if defined?(Psych::SyntaxError)
- return {} unless filename and File.exist? filename
+ return {} unless filename && !filename.empty? && File.exist?(filename)
begin
content = Gem::SafeYAML.load(File.read(filename))
@@ -434,6 +431,9 @@ if you believe they were disclosed to a third party.
yaml_hash[:update_sources] = @hash.fetch(:update_sources, DEFAULT_UPDATE_SOURCES)
yaml_hash[:verbose] = @hash.fetch(:verbose, DEFAULT_VERBOSITY)
+ yaml_hash[:concurrent_downloads] =
+ @hash.fetch(:concurrent_downloads, DEFAULT_CONCURRENT_DOWNLOADS)
+
yaml_hash[:ssl_verify_mode] =
@hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
@@ -443,7 +443,7 @@ if you believe they were disclosed to a third party.
yaml_hash[:ssl_client_cert] =
@hash[:ssl_client_cert] if @hash.key? :ssl_client_cert
- keys = yaml_hash.keys.map { |key| key.to_s }
+ keys = yaml_hash.keys.map {|key| key.to_s }
keys << 'debug'
re = Regexp.union(*keys)
@@ -458,7 +458,10 @@ if you believe they were disclosed to a third party.
# Writes out this config file, replacing its source.
def write
- open config_file_name, 'w' do |io|
+ require 'fileutils'
+ FileUtils.mkdir_p File.dirname(config_file_name)
+
+ File.open config_file_name, 'w' do |io|
io.write to_yaml
end
end
@@ -484,4 +487,22 @@ if you believe they were disclosed to a third party.
attr_reader :hash
protected :hash
+
+ private
+
+ def set_config_file_name(args)
+ @config_file_name = ENV["GEMRC"]
+ need_config_file_name = false
+
+ args.each do |arg|
+ if need_config_file_name
+ @config_file_name = arg
+ need_config_file_name = false
+ elsif arg =~ /^--config-file=(.*)/
+ @config_file_name = $1
+ elsif arg =~ /^--config-file$/
+ need_config_file_name = true
+ end
+ end
+ end
end
diff --git a/lib/rubygems/core_ext/kernel_gem.rb b/lib/rubygems/core_ext/kernel_gem.rb
index b0dd69bfcc..e722225739 100644
--- a/lib/rubygems/core_ext/kernel_gem.rb
+++ b/lib/rubygems/core_ext/kernel_gem.rb
@@ -7,9 +7,6 @@
module Kernel
- # REFACTOR: This should be pulled out into some kind of hacks file.
- remove_method :gem if 'method' == defined? gem # from gem_prelude.rb on 1.9
-
##
# Use Kernel#gem to activate a specific version of +gem_name+.
#
@@ -64,9 +61,13 @@ module Kernel
spec = dep.to_spec
- Gem::LOADED_SPECS_MUTEX.synchronize {
- spec.activate
- } if spec
+ if spec
+ if Gem::LOADED_SPECS_MUTEX.owned?
+ spec.activate
+ else
+ Gem::LOADED_SPECS_MUTEX.synchronize { spec.activate }
+ end
+ end
end
private :gem
diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb
index d3df9d85f9..4b867c55e9 100755..100644
--- a/lib/rubygems/core_ext/kernel_require.rb
+++ b/lib/rubygems/core_ext/kernel_require.rb
@@ -11,17 +11,14 @@ module Kernel
RUBYGEMS_ACTIVATION_MONITOR = Monitor.new # :nodoc:
- if defined?(gem_original_require) then
- # Ruby ships with a custom_require, override its require
- remove_method :require
- else
- ##
- # The Kernel#require from before RubyGems was loaded.
-
+ # Make sure we have a reference to Ruby's original Kernel#require
+ unless defined?(gem_original_require)
alias gem_original_require require
private :gem_original_require
end
+ file = Gem::KERNEL_WARN_IGNORES_INTERNAL_ENTRIES ? "<internal:#{__FILE__}>" : __FILE__
+ module_eval <<'RUBY', file, __LINE__ + 1
##
# When RubyGems is required, Kernel#require is replaced with our own which
# is capable of loading gems on demand.
@@ -36,25 +33,54 @@ module Kernel
# The normal <tt>require</tt> functionality of returning false if
# that file has already been loaded is preserved.
- def require path
+ def require(path)
+ if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
+ monitor_owned = RUBYGEMS_ACTIVATION_MONITOR.mon_owned?
+ end
RUBYGEMS_ACTIVATION_MONITOR.enter
path = path.to_path if path.respond_to? :to_path
if spec = Gem.find_unresolved_default_spec(path)
- Gem.remove_unresolved_default_spec(spec)
+ # Ensure -I beats a default gem
+ resolved_path = begin
+ rp = nil
+ load_path_check_index = Gem.load_path_insert_index - Gem.activated_gem_paths
+ Gem.suffixes.each do |s|
+ $LOAD_PATH[0...load_path_check_index].each do |lp|
+ safe_lp = lp.dup.tap(&Gem::UNTAINT)
+ begin
+ if File.symlink? safe_lp # for backward compatibility
+ next
+ end
+ rescue SecurityError
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ raise
+ end
+
+ full_path = File.expand_path(File.join(safe_lp, "#{path}#{s}"))
+ if File.file?(full_path)
+ rp = full_path
+ break
+ end
+ end
+ break if rp
+ end
+ rp
+ end
+
begin
- Kernel.send(:gem, spec.name)
+ Kernel.send(:gem, spec.name, Gem::Requirement.default_prerelease)
rescue Exception
RUBYGEMS_ACTIVATION_MONITOR.exit
raise
- end
+ end unless resolved_path
end
# If there are no unresolved deps, then we can use just try
# normal require handle loading a gem from the rescue below.
- if Gem::Specification.unresolved_deps.empty? then
+ if Gem::Specification.unresolved_deps.empty?
RUBYGEMS_ACTIVATION_MONITOR.exit
return gem_original_require(path)
end
@@ -84,7 +110,7 @@ module Kernel
# requested, then find_in_unresolved_tree will find d.rb in d because
# it's a dependency of c.
#
- if found_specs.empty? then
+ if found_specs.empty?
found_specs = Gem::Specification.find_in_unresolved_tree path
found_specs.each do |found_spec|
@@ -99,16 +125,16 @@ module Kernel
# versions of the same gem
names = found_specs.map(&:name).uniq
- if names.size > 1 then
+ if names.size > 1
RUBYGEMS_ACTIVATION_MONITOR.exit
raise Gem::LoadError, "#{path} found in multiple gems: #{names.join ', '}"
end
# Ok, now find a gem that has no conflicts, starting
# at the highest version.
- valid = found_specs.find { |s| !s.has_conflicts? }
+ valid = found_specs.find {|s| !s.has_conflicts? }
- unless valid then
+ unless valid
le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate"
le.name = names.first
RUBYGEMS_ACTIVATION_MONITOR.exit
@@ -124,8 +150,7 @@ module Kernel
RUBYGEMS_ACTIVATION_MONITOR.enter
begin
- if load_error.message.start_with?("Could not find") or
- (load_error.message.end_with?(path) and Gem.try_activate(path)) then
+ if load_error.path == path and Gem.try_activate(path)
require_again = true
end
ensure
@@ -135,7 +160,15 @@ module Kernel
return gem_original_require(path) if require_again
raise load_error
+ ensure
+ if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
+ if monitor_owned != (ow = RUBYGEMS_ACTIVATION_MONITOR.mon_owned?)
+ STDERR.puts [$$, Thread.current, $!, $!.backtrace].inspect if $!
+ raise "CRITICAL: RUBYGEMS_ACTIVATION_MONITOR.owned?: before #{monitor_owned} -> after #{ow}"
+ end
+ end
end
+RUBY
private :require
diff --git a/lib/rubygems/core_ext/kernel_warn.rb b/lib/rubygems/core_ext/kernel_warn.rb
new file mode 100644
index 0000000000..3373cfdd3b
--- /dev/null
+++ b/lib/rubygems/core_ext/kernel_warn.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# `uplevel` keyword argument of Kernel#warn is available since ruby 2.5.
+if RUBY_VERSION >= "2.5" && !Gem::KERNEL_WARN_IGNORES_INTERNAL_ENTRIES
+
+ module Kernel
+ rubygems_path = "#{__dir__}/" # Frames to be skipped start with this path.
+
+ original_warn = instance_method(:warn)
+
+ remove_method :warn
+
+ class << self
+ remove_method :warn
+ end
+
+ module_function define_method(:warn) {|*messages, **kw|
+ unless uplevel = kw[:uplevel]
+ if Gem.java_platform?
+ return original_warn.bind(self).call(*messages)
+ else
+ return original_warn.bind(self).call(*messages, **kw)
+ end
+ end
+
+ # Ensure `uplevel` fits a `long`
+ uplevel, = [uplevel].pack("l!").unpack("l!")
+
+ if uplevel >= 0
+ start = 0
+ while uplevel >= 0
+ loc, = caller_locations(start, 1)
+ unless loc
+ # No more backtrace
+ start += uplevel
+ break
+ end
+
+ start += 1
+
+ if path = loc.path
+ unless path.start_with?(rubygems_path) or path.start_with?('<internal:')
+ # Non-rubygems frames
+ uplevel -= 1
+ end
+ end
+ end
+ kw[:uplevel] = start
+ end
+
+ original_warn.bind(self).call(*messages, **kw)
+ }
+ end
+end
diff --git a/lib/rubygems/core_ext/tcpsocket_init.rb b/lib/rubygems/core_ext/tcpsocket_init.rb
new file mode 100644
index 0000000000..2a79b63bd6
--- /dev/null
+++ b/lib/rubygems/core_ext/tcpsocket_init.rb
@@ -0,0 +1,52 @@
+require 'socket'
+
+module CoreExtensions
+ module TCPSocketExt
+ def self.prepended(base)
+ base.prepend Initializer
+ end
+
+ module Initializer
+ CONNECTION_TIMEOUT = 5
+ IPV4_DELAY_SECONDS = 0.1
+
+ def initialize(host, serv, *rest)
+ mutex = Thread::Mutex.new
+ addrs = []
+ threads = []
+ cond_var = Thread::ConditionVariable.new
+
+ Addrinfo.foreach(host, serv, nil, :STREAM) do |addr|
+ Thread.report_on_exception = false if defined? Thread.report_on_exception = ()
+
+ threads << Thread.new(addr) do
+ # give head start to ipv6 addresses
+ sleep IPV4_DELAY_SECONDS if addr.ipv4?
+
+ # raises Errno::ECONNREFUSED when ip:port is unreachable
+ Socket.tcp(addr.ip_address, serv, connect_timeout: CONNECTION_TIMEOUT).close
+ mutex.synchronize do
+ addrs << addr.ip_address
+ cond_var.signal
+ end
+ end
+ end
+
+ mutex.synchronize do
+ timeout_time = CONNECTION_TIMEOUT + Time.now.to_f
+ while addrs.empty? && (remaining_time = timeout_time - Time.now.to_f) > 0
+ cond_var.wait(mutex, remaining_time)
+ end
+
+ host = addrs.shift unless addrs.empty?
+ end
+
+ threads.each {|t| t.kill.join if t.alive? }
+
+ super(host, serv, *rest)
+ end
+ end
+ end
+end
+
+TCPSocket.prepend CoreExtensions::TCPSocketExt
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index 43d57fc808..923b60f31f 100644
--- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module Gem
- DEFAULT_HOST = "https://rubygems.org"
+ DEFAULT_HOST = "https://rubygems.org".freeze
- @post_install_hooks ||= []
- @done_installing_hooks ||= []
+ @post_install_hooks ||= []
+ @done_installing_hooks ||= []
@post_uninstall_hooks ||= []
@pre_uninstall_hooks ||= []
@pre_install_hooks ||= []
@@ -20,7 +20,13 @@ module Gem
# specified in the environment
def self.default_spec_cache_dir
- File.join Gem.user_home, '.gem', 'specs'
+ default_spec_cache_dir = File.join Gem.user_home, '.gem', 'specs'
+
+ unless File.exist?(default_spec_cache_dir)
+ default_spec_cache_dir = File.join Gem.data_home, 'gem', 'specs'
+ end
+
+ default_spec_cache_dir
end
##
@@ -28,24 +34,17 @@ module Gem
# specified in the environment
def self.default_dir
- path = if defined? RUBY_FRAMEWORK_VERSION then
+ path = if defined? RUBY_FRAMEWORK_VERSION
[
File.dirname(RbConfig::CONFIG['sitedir']),
'Gems',
- RbConfig::CONFIG['ruby_version']
- ]
- elsif RbConfig::CONFIG['rubylibprefix'] then
- [
- RbConfig::CONFIG['rubylibprefix'],
- 'gems',
- RbConfig::CONFIG['ruby_version']
+ RbConfig::CONFIG['ruby_version'],
]
else
[
- RbConfig::CONFIG['libdir'],
- ruby_engine,
+ RbConfig::CONFIG['rubylibprefix'],
'gems',
- RbConfig::CONFIG['ruby_version']
+ RbConfig::CONFIG['ruby_version'],
]
end
@@ -59,7 +58,7 @@ module Gem
# By default, the binary extensions are located side by side with their
# Ruby counterparts, therefore nil is returned
- def self.default_ext_dir_for base_dir
+ def self.default_ext_dir_for(base_dir)
nil
end
@@ -71,15 +70,98 @@ module Gem
end
##
+ # Path to specification files of default gems.
+
+ def self.default_specifications_dir
+ @default_specifications_dir ||= File.join(Gem.default_dir, "specifications", "default")
+ end
+
+ ##
+ # Finds the user's home directory.
+ #--
+ # Some comments from the ruby-talk list regarding finding the home
+ # directory:
+ #
+ # I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
+ # to be depending on HOME in those code samples. I propose that
+ # it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
+ # least on Win32).
+ #++
+ #--
+ #
+ #++
+
+ def self.find_home
+ Dir.home.dup
+ rescue
+ if Gem.win_platform?
+ File.expand_path File.join(ENV['HOMEDRIVE'] || ENV['SystemDrive'], '/')
+ else
+ File.expand_path "/"
+ end
+ end
+
+ private_class_method :find_home
+
+ ##
+ # The home directory for the user.
+
+ def self.user_home
+ @user_home ||= find_home.tap(&Gem::UNTAINT)
+ end
+
+ ##
# Path for gems in the user's home directory
def self.user_dir
- parts = [Gem.user_home, '.gem', ruby_engine]
+ gem_dir = File.join(Gem.user_home, ".gem")
+ gem_dir = File.join(Gem.data_home, "gem") unless File.exist?(gem_dir)
+ parts = [gem_dir, ruby_engine]
parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty?
File.join parts
end
##
+ # The path to standard location of the user's configuration directory.
+
+ def self.config_home
+ @config_home ||= (ENV["XDG_CONFIG_HOME"] || File.join(Gem.user_home, '.config'))
+ end
+
+ ##
+ # Finds the user's config file
+
+ def self.find_config_file
+ gemrc = File.join Gem.user_home, '.gemrc'
+ if File.exist? gemrc
+ gemrc
+ else
+ File.join Gem.config_home, "gem", "gemrc"
+ end
+ end
+
+ ##
+ # The path to standard location of the user's .gemrc file.
+
+ def self.config_file
+ @config_file ||= find_config_file.tap(&Gem::UNTAINT)
+ end
+
+ ##
+ # The path to standard location of the user's cache directory.
+
+ def self.cache_home
+ @cache_home ||= (ENV["XDG_CACHE_HOME"] || File.join(Gem.user_home, '.cache'))
+ end
+
+ ##
+ # The path to standard location of the user's data directory.
+
+ def self.data_home
+ @data_home ||= (ENV["XDG_DATA_HOME"] || File.join(Gem.user_home, '.local', 'share'))
+ end
+
+ ##
# How String Gem paths should be split. Overridable for esoteric platforms.
def self.path_separator
@@ -103,7 +185,7 @@ module Gem
def self.default_exec_format
exec_format = RbConfig::CONFIG['ruby_install_name'].sub('ruby', '%s') rescue '%s'
- unless exec_format =~ /%s/ then
+ unless exec_format =~ /%s/
raise Gem::Exception,
"[BUG] invalid exec_format #{exec_format.inspect}, no %s"
end
@@ -115,43 +197,41 @@ module Gem
# The default directory for binaries
def self.default_bindir
- if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
- '/usr/bin'
+ if defined? RUBY_FRAMEWORK_VERSION # mac framework support
+ '/usr/local/bin'
else # generic install
RbConfig::CONFIG['bindir']
end
end
- ##
- # A wrapper around RUBY_ENGINE const that may not be defined
-
def self.ruby_engine
- if defined? RUBY_ENGINE then
- RUBY_ENGINE
- else
- 'ruby'
- end
+ RUBY_ENGINE
end
##
# The default signing key path
def self.default_key_path
- File.join Gem.user_home, ".gem", "gem-private_key.pem"
+ default_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem"
+
+ unless File.exist?(default_key_path)
+ default_key_path = File.join Gem.data_home, "gem", "gem-private_key.pem"
+ end
+
+ default_key_path
end
##
# The default signing certificate chain path
def self.default_cert_path
- File.join Gem.user_home, ".gem", "gem-public_cert.pem"
- end
+ default_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem"
- ##
- # Whether to expect full paths in default gems - true for non-MRI
- # ruby implementations
- def self.default_gems_use_full_paths?
- ruby_engine != 'ruby'
+ unless File.exist?(default_cert_path)
+ default_cert_path = File.join Gem.data_home, "gem", "gem-public_cert.pem"
+ end
+
+ default_cert_path
end
##
@@ -165,7 +245,7 @@ module Gem
# Directory where vendor gems are installed.
def self.vendor_dir # :nodoc:
- if vendor_dir = ENV['GEM_VENDOR'] then
+ if vendor_dir = ENV['GEM_VENDOR']
return vendor_dir.dup
end
@@ -176,7 +256,26 @@ module Gem
end
##
- # Default options for gem commands.
+ # Default options for gem commands for Ruby packagers.
+ #
+ # The options here should be structured as an array of string "gem"
+ # command names as keys and a string of the default options as values.
+ #
+ # Example:
+ #
+ # def self.operating_system_defaults
+ # {
+ # 'install' => '--no-rdoc --no-ri --env-shebang',
+ # 'update' => '--no-rdoc --no-ri --env-shebang'
+ # }
+ # end
+
+ def self.operating_system_defaults
+ {}
+ end
+
+ ##
+ # Default options for gem commands for Ruby implementers.
#
# The options here should be structured as an array of string "gem"
# command names as keys and a string of the default options as values.
diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb
index 55873c71e8..3721204ab2 100644
--- a/lib/rubygems/dependency.rb
+++ b/lib/rubygems/dependency.rb
@@ -2,10 +2,7 @@
##
# The Dependency class holds a Gem name and a Gem::Requirement.
-require "rubygems/requirement"
-
class Gem::Dependency
-
##
# Valid dependency types.
#--
@@ -18,7 +15,7 @@ class Gem::Dependency
TYPES = [
:development,
:runtime,
- ]
+ ].freeze
##
# Dependency name or regular expression.
@@ -35,7 +32,7 @@ class Gem::Dependency
# argument can optionally be the dependency type, which defaults to
# <tt>:runtime</tt>.
- def initialize name, *requirements
+ def initialize(name, *requirements)
case name
when String then # ok
when Regexp then
@@ -75,7 +72,7 @@ class Gem::Dependency
end
def inspect # :nodoc:
- if prerelease? then
+ if prerelease?
"<%s type=%p name=%p requirements=%p prerelease=ok>" %
[self.class, self.type, self.name, requirement.to_s]
else
@@ -99,7 +96,7 @@ class Gem::Dependency
@requirement.none?
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 1, 'Gem::Dependency.new(', ')' do
q.pp name
q.text ','
@@ -139,7 +136,7 @@ class Gem::Dependency
if defined?(@version_requirement) && @version_requirement
version = @version_requirement.instance_variable_get :@version
- @version_requirement = nil
+ @version_requirement = nil
@version_requirements = Gem::Requirement.new version
end
@@ -151,7 +148,7 @@ class Gem::Dependency
end
def to_s # :nodoc:
- if type != :runtime then
+ if type != :runtime
"#{name} (#{requirement}, #{type})"
else
"#{name} (#{requirement})"
@@ -169,7 +166,7 @@ class Gem::Dependency
@type == :runtime || !@type
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
Gem::Dependency === other &&
self.name == other.name &&
self.type == other.type &&
@@ -179,7 +176,7 @@ class Gem::Dependency
##
# Dependencies are ordered by name.
- def <=> other
+ def <=>(other)
self.name <=> other.name
end
@@ -189,7 +186,7 @@ class Gem::Dependency
# other has only an equal version requirement that satisfies this
# dependency.
- def =~ other
+ def =~(other)
unless Gem::Dependency === other
return unless other.respond_to?(:name) && other.respond_to?(:version)
other = Gem::Dependency.new other.name, other.version
@@ -221,7 +218,7 @@ class Gem::Dependency
# NOTE: Unlike #matches_spec? this method does not return true when the
# version is a prerelease version unless this is a prerelease dependency.
- def match? obj, version=nil, allow_prerelease=false
+ def match?(obj, version=nil, allow_prerelease=false)
if !version
name = obj.name
version = obj.version
@@ -248,7 +245,7 @@ class Gem::Dependency
# returns true when +spec+ is a prerelease version even if this dependency
# is not a prerelease dependency.
- def matches_spec? spec
+ def matches_spec?(spec)
return false unless name === spec.name
return true if requirement.none?
@@ -258,14 +255,14 @@ class Gem::Dependency
##
# Merges the requirements of +other+ into this dependency
- def merge other
- unless name == other.name then
+ def merge(other)
+ unless name == other.name
raise ArgumentError,
"#{self} and #{other} have different names"
end
default = Gem::Requirement.default
- self_req = self.requirement
+ self_req = self.requirement
other_req = other.requirement
return self.class.new name, self_req if other_req == default
@@ -274,18 +271,18 @@ class Gem::Dependency
self.class.new name, self_req.as_list.concat(other_req.as_list)
end
- def matching_specs platform_only = false
+ def matching_specs(platform_only = false)
env_req = Gem.env_requirement(name)
- matches = Gem::Specification.stubs_for(name).find_all { |spec|
+ matches = Gem::Specification.stubs_for(name).find_all do |spec|
requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
- }.map(&:to_spec)
+ end.map(&:to_spec)
- Gem::BundlerVersionFinder.filter!(matches) if name == "bundler".freeze
+ Gem::BundlerVersionFinder.filter!(matches) if filters_bundler?
if platform_only
- matches.reject! { |spec|
- spec.nil? || !Gem::Platform.match(spec.platform)
- }
+ matches.reject! do |spec|
+ spec.nil? || !Gem::Platform.match_spec?(spec)
+ end
end
matches
@@ -298,12 +295,16 @@ class Gem::Dependency
@requirement.specific?
end
+ def filters_bundler?
+ name == "bundler".freeze && !specific?
+ end
+
def to_specs
matches = matching_specs true
# TODO: check Gem.activated_spec[self.name] in case matches falls outside
- if matches.empty? then
+ if matches.empty?
specs = Gem::Specification.stubs_for name
if specs.empty?
@@ -321,15 +322,29 @@ class Gem::Dependency
def to_spec
matches = self.to_specs.compact
- active = matches.find { |spec| spec.activated? }
+ active = matches.find {|spec| spec.activated? }
return active if active
return matches.first if prerelease?
# Move prereleases to the end of the list for >= 0 requirements
- pre, matches = matches.partition { |spec| spec.version.prerelease? }
+ pre, matches = matches.partition {|spec| spec.version.prerelease? }
matches += pre if requirement == Gem::Requirement.default
matches.first
end
+
+ def identity
+ if prerelease?
+ if specific?
+ :complete
+ else
+ :abs_latest
+ end
+ elsif latest_version?
+ :latest
+ else
+ :released
+ end
+ end
end
diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb
index 5a87f50956..913bba32eb 100644
--- a/lib/rubygems/dependency_installer.rb
+++ b/lib/rubygems/dependency_installer.rb
@@ -1,20 +1,19 @@
# frozen_string_literal: true
-require 'rubygems'
-require 'rubygems/dependency_list'
-require 'rubygems/package'
-require 'rubygems/installer'
-require 'rubygems/spec_fetcher'
-require 'rubygems/user_interaction'
-require 'rubygems/source'
-require 'rubygems/available_set'
-require 'rubygems/deprecate'
+require_relative '../rubygems'
+require_relative 'dependency_list'
+require_relative 'package'
+require_relative 'installer'
+require_relative 'spec_fetcher'
+require_relative 'user_interaction'
+require_relative 'available_set'
+require_relative 'deprecate'
##
# Installs a gem along with all its dependencies from local and remote gems.
class Gem::DependencyInstaller
-
include Gem::UserInteraction
+ extend Gem::Deprecate
DEFAULT_OPTIONS = { # :nodoc:
:env_shebang => false,
@@ -28,7 +27,7 @@ class Gem::DependencyInstaller
:wrappers => true,
:build_args => nil,
:build_docs_in_background => false,
- :install_as_default => false
+ :install_as_default => false,
}.freeze
##
@@ -42,15 +41,6 @@ class Gem::DependencyInstaller
attr_reader :errors
##
- #--
- # TODO remove, no longer used
-
- attr_reader :gems_to_install # :nodoc:
-
- extend Gem::Deprecate
- deprecate :gems_to_install, :none, 2016, 10
-
- ##
# List of gems installed by #install in alphabetic order
attr_reader :installed_gems
@@ -74,7 +64,7 @@ class Gem::DependencyInstaller
# :wrappers:: See Gem::Installer::new
# :build_args:: See Gem::Installer::new
- def initialize options = {}
+ def initialize(options = {})
@only_install_dir = !!options[:install_dir]
@install_dir = options[:install_dir] || Gem.dir
@build_root = options[:build_root]
@@ -96,11 +86,14 @@ class Gem::DependencyInstaller
@wrappers = options[:wrappers]
@build_args = options[:build_args]
@build_docs_in_background = options[:build_docs_in_background]
- @install_as_default = options[:install_as_default]
+ @install_as_default = options[:install_as_default]
+ @dir_mode = options[:dir_mode]
+ @data_mode = options[:data_mode]
+ @prog_mode = options[:prog_mode]
# Indicates that we should not try to update any deps unless
# we absolutely must.
- @minimal_deps = options[:minimal_deps]
+ @minimal_deps = options[:minimal_deps]
@available = nil
@installed_gems = []
@@ -112,75 +105,6 @@ class Gem::DependencyInstaller
end
##
- #--
- # TODO remove, no longer used
-
- def add_found_dependencies to_do, dependency_list # :nodoc:
- seen = {}
- dependencies = Hash.new { |h, name| h[name] = Gem::Dependency.new name }
-
- until to_do.empty? do
- spec = to_do.shift
-
- # HACK why is spec nil?
- next if spec.nil? or seen[spec.name]
- seen[spec.name] = true
-
- deps = spec.runtime_dependencies
-
- if @development
- if @dev_shallow
- if @toplevel_specs.include? spec.full_name
- deps |= spec.development_dependencies
- end
- else
- deps |= spec.development_dependencies
- end
- end
-
- deps.each do |dep|
- dependencies[dep.name] = dependencies[dep.name].merge dep
-
- if @minimal_deps
- next if Gem::Specification.any? do |installed_spec|
- dep.name == installed_spec.name and
- dep.requirement.satisfied_by? installed_spec.version
- end
- end
-
- results = find_gems_with_sources(dep)
-
- results.sorted.each do |t|
- to_do.push t.spec
- end
-
- results.remove_installed! dep
-
- @available << results
- results.inject_into_list dependency_list
- end
- end
-
- dependency_list.remove_specs_unsatisfied_by dependencies
- end
-
- ##
- # Creates an AvailableSet to install from based on +dep_or_name+ and
- # +version+
-
- def available_set_for dep_or_name, version # :nodoc:
- if String === dep_or_name then
- find_spec_by_name_and_version dep_or_name, version, @prerelease
- else
- dep = dep_or_name.dup
- dep.prerelease = @prerelease
- @available = find_gems_with_sources dep
- end
-
- @available.pick_best!
- end
-
- ##
# Indicated, based on the requested domain, if local
# gems should be considered.
@@ -202,7 +126,7 @@ class Gem::DependencyInstaller
# sources. Gems are sorted with newer gems preferred over older gems, and
# local gems preferred over remote gems.
- def find_gems_with_sources dep, best_only=false # :nodoc:
+ def find_gems_with_sources(dep, best_only=false) # :nodoc:
set = Gem::AvailableSet.new
if consider_local?
@@ -217,9 +141,8 @@ class Gem::DependencyInstaller
if consider_remote?
begin
- # TODO this is pulled from #spec_for_dependency to allow
+ # This is pulled from #spec_for_dependency to allow
# us to filter tuples before fetching specs.
- #
tuples, errors = Gem::SpecFetcher.fetcher.search_for_dependency dep
if best_only && !tuples.empty?
@@ -270,92 +193,9 @@ class Gem::DependencyInstaller
set
end
+ rubygems_deprecate :find_gems_with_sources
- ##
- # Finds a spec and the source_uri it came from for gem +gem_name+ and
- # +version+. Returns an Array of specs and sources required for
- # installation of the gem.
-
- def find_spec_by_name_and_version gem_name,
- version = Gem::Requirement.default,
- prerelease = false
- set = Gem::AvailableSet.new
-
- if consider_local?
- if gem_name =~ /\.gem$/ and File.file? gem_name then
- src = Gem::Source::SpecificFile.new(gem_name)
- set.add src.spec, src
- elsif gem_name =~ /\.gem$/ then
- Dir[gem_name].each do |name|
- begin
- src = Gem::Source::SpecificFile.new name
- set.add src.spec, src
- rescue Gem::Package::FormatError
- end
- end
- else
- local = Gem::Source::Local.new
-
- if s = local.find_gem(gem_name, version)
- set.add s, local
- end
- end
- end
-
- if set.empty?
- dep = Gem::Dependency.new gem_name, version
- dep.prerelease = true if prerelease
-
- set = find_gems_with_sources(dep, true)
- set.match_platform!
- end
-
- if set.empty?
- raise Gem::SpecificGemNotFoundException.new(gem_name, version, @errors)
- end
-
- @available = set
- end
-
- ##
- # Gathers all dependencies necessary for the installation from local and
- # remote sources unless the ignore_dependencies was given.
- #--
- # TODO remove at RubyGems 3
-
- def gather_dependencies # :nodoc:
- specs = @available.all_specs
-
- # these gems were listed by the user, always install them
- keep_names = specs.map { |spec| spec.full_name }
-
- if @dev_shallow
- @toplevel_specs = keep_names
- end
-
- dependency_list = Gem::DependencyList.new @development
- dependency_list.add(*specs)
- to_do = specs.dup
- add_found_dependencies to_do, dependency_list unless @ignore_dependencies
-
- # REFACTOR maybe abstract away using Gem::Specification.include? so
- # that this isn't dependent only on the currently installed gems
- dependency_list.specs.reject! { |spec|
- not keep_names.include?(spec.full_name) and
- Gem::Specification.include?(spec)
- }
-
- unless dependency_list.ok? or @ignore_dependencies or @force then
- reason = dependency_list.why_not_ok?.map { |k,v|
- "#{k} requires #{v.join(", ")}"
- }.join("; ")
- raise Gem::DependencyError, "Unable to resolve dependencies: #{reason}"
- end
-
- @gems_to_install = dependency_list.dependency_order.reverse
- end
-
- def in_background what # :nodoc:
+ def in_background(what) # :nodoc:
fork_happened = false
if @build_docs_in_background and Process.respond_to?(:fork)
begin
@@ -384,7 +224,7 @@ class Gem::DependencyInstaller
# c-1.a, b-1 and a-1.a will be installed. b-1.a will need to be installed
# separately.
- def install dep_or_name, version = Gem::Requirement.default
+ def install(dep_or_name, version = Gem::Requirement.default)
request_set = resolve_dependencies dep_or_name, version
@installed_gems = []
@@ -402,7 +242,10 @@ class Gem::DependencyInstaller
:user_install => @user_install,
:wrappers => @wrappers,
:build_root => @build_root,
- :install_as_default => @install_as_default
+ :install_as_default => @install_as_default,
+ :dir_mode => @dir_mode,
+ :data_mode => @data_mode,
+ :prog_mode => @prog_mode,
}
options[:install_dir] = @install_dir if @only_install_dir
@@ -425,32 +268,32 @@ class Gem::DependencyInstaller
end
def install_development_deps # :nodoc:
- if @development and @dev_shallow then
+ if @development and @dev_shallow
:shallow
- elsif @development then
+ elsif @development
:all
else
:none
end
end
- def resolve_dependencies dep_or_name, version # :nodoc:
+ def resolve_dependencies(dep_or_name, version) # :nodoc:
request_set = Gem::RequestSet.new
request_set.development = @development
request_set.development_shallow = @dev_shallow
request_set.soft_missing = @force
request_set.prerelease = @prerelease
- request_set.remote = false unless consider_remote?
installer_set = Gem::Resolver::InstallerSet.new @domain
- installer_set.ignore_installed = @only_install_dir
+ installer_set.ignore_installed = (@minimal_deps == false) || @only_install_dir
+ installer_set.force = @force
if consider_local?
- if dep_or_name =~ /\.gem$/ and File.file? dep_or_name then
+ if dep_or_name =~ /\.gem$/ and File.file? dep_or_name
src = Gem::Source::SpecificFile.new dep_or_name
installer_set.add_local dep_or_name, src.spec, src
version = src.spec.version if version == Gem::Requirement.default
- elsif dep_or_name =~ /\.gem$/ then
+ elsif dep_or_name =~ /\.gem$/
Dir[dep_or_name].each do |name|
begin
src = Gem::Source::SpecificFile.new name
@@ -458,14 +301,15 @@ class Gem::DependencyInstaller
rescue Gem::Package::FormatError
end
end
- # else This is a dependency. InstallerSet handles this case
+ # else This is a dependency. InstallerSet handles this case
end
end
dependency =
- if spec = installer_set.local?(dep_or_name) then
+ if spec = installer_set.local?(dep_or_name)
+ installer_set.remote = nil if spec.dependencies.none?
Gem::Dependency.new spec.name, version
- elsif String === dep_or_name then
+ elsif String === dep_or_name
Gem::Dependency.new dep_or_name, version
else
dep_or_name
@@ -478,8 +322,9 @@ class Gem::DependencyInstaller
installer_set.add_always_install dependency
request_set.always_install = installer_set.always_install
+ request_set.remote = installer_set.consider_remote?
- if @ignore_dependencies then
+ if @ignore_dependencies
installer_set.ignore_dependencies = true
request_set.ignore_dependencies = true
request_set.soft_missing = true
@@ -491,5 +336,4 @@ class Gem::DependencyInstaller
request_set
end
-
end
diff --git a/lib/rubygems/dependency_list.rb b/lib/rubygems/dependency_list.rb
index d8314eaf60..10e08fc703 100644
--- a/lib/rubygems/dependency_list.rb
+++ b/lib/rubygems/dependency_list.rb
@@ -5,8 +5,8 @@
# See LICENSE.txt for permissions.
#++
-require 'tsort'
-require 'rubygems/deprecate'
+require_relative 'tsort'
+require_relative 'deprecate'
##
# Gem::DependencyList is used for installing and uninstalling gems in the
@@ -20,7 +20,7 @@ class Gem::DependencyList
attr_reader :specs
include Enumerable
- include TSort
+ include Gem::TSort
##
# Allows enabling/disabling use of development dependencies
@@ -40,7 +40,7 @@ class Gem::DependencyList
# Creates a new DependencyList. If +development+ is true, development
# dependencies will be included.
- def initialize development = false
+ def initialize(development = false)
@specs = []
@development = development
@@ -79,8 +79,8 @@ class Gem::DependencyList
seen = {}
sorted.each do |spec|
- if index = seen[spec.name] then
- if result[index].version < spec.version then
+ if index = seen[spec.name]
+ if result[index].version < spec.version
result[index] = spec
end
else
@@ -100,11 +100,11 @@ class Gem::DependencyList
end
def find_name(full_name)
- @specs.find { |spec| spec.full_name == full_name }
+ @specs.find {|spec| spec.full_name == full_name }
end
def inspect # :nodoc:
- "%s %p>" % [super[0..-2], map { |s| s.full_name }]
+ "%s %p>" % [super[0..-2], map {|s| s.full_name }]
end
##
@@ -114,16 +114,16 @@ class Gem::DependencyList
why_not_ok?(:quick).empty?
end
- def why_not_ok? quick = false
- unsatisfied = Hash.new { |h,k| h[k] = [] }
+ def why_not_ok?(quick = false)
+ unsatisfied = Hash.new {|h,k| h[k] = [] }
each do |spec|
spec.runtime_dependencies.each do |dep|
- inst = Gem::Specification.any? { |installed_spec|
+ inst = Gem::Specification.any? do |installed_spec|
dep.name == installed_spec.name and
dep.requirement.satisfied_by? installed_spec.version
- }
+ end
- unless inst or @specs.find { |s| s.satisfies_requirement? dep } then
+ unless inst or @specs.find {|s| s.satisfies_requirement? dep }
unsatisfied[spec.name] << dep
return unsatisfied if quick
end
@@ -134,7 +134,7 @@ class Gem::DependencyList
end
##
- # Is is ok to remove a gemspec from the dependency list?
+ # It is ok to remove a gemspec from the dependency list?
#
# If removing the gemspec creates breaks a currently ok dependency, then it
# is NOT ok to remove the gemspec.
@@ -145,10 +145,10 @@ class Gem::DependencyList
# If the state is inconsistent, at least don't crash
return true unless gem_to_remove
- siblings = @specs.find_all { |s|
+ siblings = @specs.find_all do |s|
s.name == gem_to_remove.name &&
s.full_name != gem_to_remove.full_name
- }
+ end
deps = []
@@ -160,11 +160,11 @@ class Gem::DependencyList
end
end
- deps.all? { |dep|
- siblings.any? { |s|
+ deps.all? do |dep|
+ siblings.any? do |s|
s.satisfies_requirement? dep
- }
- }
+ end
+ end
end
##
@@ -172,18 +172,18 @@ class Gem::DependencyList
# satisfy items in +dependencies+ (a hash of gem names to arrays of
# dependencies).
- def remove_specs_unsatisfied_by dependencies
- specs.reject! { |spec|
+ def remove_specs_unsatisfied_by(dependencies)
+ specs.reject! do |spec|
dep = dependencies[spec.name]
dep and not dep.requirement.satisfied_by? spec.version
- }
+ end
end
##
# Removes the gemspec matching +full_name+ from the dependency list
def remove_by_name(full_name)
- @specs.delete_if { |spec| spec.full_name == full_name }
+ @specs.delete_if {|spec| spec.full_name == full_name }
end
##
@@ -191,7 +191,7 @@ class Gem::DependencyList
# gemspecs that have a dependency satisfied by the named gemspec.
def spec_predecessors
- result = Hash.new { |h,k| h[k] = [] }
+ result = Hash.new {|h,k| h[k] = [] }
specs = @specs.sort.reverse
@@ -200,7 +200,7 @@ class Gem::DependencyList
next if spec == other
other.dependencies.each do |dep|
- if spec.satisfies_requirement? dep then
+ if spec.satisfies_requirement? dep
result[spec] << other
end
end
@@ -222,7 +222,7 @@ class Gem::DependencyList
dependencies.each do |dep|
specs.each do |spec|
- if spec.satisfies_requirement? dep then
+ if spec.satisfies_requirement? dep
yield spec
break
end
@@ -237,8 +237,6 @@ class Gem::DependencyList
# +ignored+.
def active_count(specs, ignored)
- specs.count { |spec| ignored[spec.full_name].nil? }
+ specs.count {|spec| ignored[spec.full_name].nil? }
end
-
end
-
diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb
index 375194c1e8..8c822cda95 100644
--- a/lib/rubygems/deprecate.rb
+++ b/lib/rubygems/deprecate.rb
@@ -27,7 +27,7 @@ module Gem::Deprecate
@skip ||= false
end
- def self.skip= v # :nodoc:
+ def self.skip=(v) # :nodoc:
@skip = v
end
@@ -41,31 +41,77 @@ module Gem::Deprecate
Gem::Deprecate.skip = original
end
+ def self.next_rubygems_major_version # :nodoc:
+ Gem::Version.new(Gem.rubygems_version.segments.first).bump
+ end
+
##
# Simple deprecation method that deprecates +name+ by wrapping it up
# in a dummy method. It warns on each call to the dummy method
# telling the user of +repl+ (unless +repl+ is :none) and the
# year/month that it is planned to go away.
- def deprecate name, repl, year, month
- class_eval {
+ def deprecate(name, repl, year, month)
+ class_eval do
old = "_deprecated_#{name}"
alias_method old, name
define_method name do |*args, &block|
klass = self.kind_of? Module
target = klass ? "#{self}." : "#{self.class}#"
msg = [ "NOTE: #{target}#{name} is deprecated",
- repl == :none ? " with no replacement" : "; use #{repl} instead",
- ". It will be removed on or after %4d-%02d-01." % [year, month],
- "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
+ repl == :none ? " with no replacement" : "; use #{repl} instead",
+ ". It will be removed on or after %4d-%02d." % [year, month],
+ "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
]
warn "#{msg.join}." unless Gem::Deprecate.skip
send old, *args, &block
end
- }
+ ruby2_keywords name if respond_to?(:ruby2_keywords, true)
+ end
end
- module_function :deprecate, :skip_during
+ ##
+ # Simple deprecation method that deprecates +name+ by wrapping it up
+ # in a dummy method. It warns on each call to the dummy method
+ # telling the user of +repl+ (unless +repl+ is :none) and the
+ # Rubygems version that it is planned to go away.
-end
+ def rubygems_deprecate(name, replacement=:none)
+ class_eval do
+ old = "_deprecated_#{name}"
+ alias_method old, name
+ define_method name do |*args, &block|
+ klass = self.kind_of? Module
+ target = klass ? "#{self}." : "#{self.class}#"
+ msg = [ "NOTE: #{target}#{name} is deprecated",
+ replacement == :none ? " with no replacement" : "; use #{replacement} instead",
+ ". It will be removed in Rubygems #{Gem::Deprecate.next_rubygems_major_version}",
+ "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
+ ]
+ warn "#{msg.join}." unless Gem::Deprecate.skip
+ send old, *args, &block
+ end
+ ruby2_keywords name if respond_to?(:ruby2_keywords, true)
+ end
+ end
+ # Deprecation method to deprecate Rubygems commands
+ def rubygems_deprecate_command
+ class_eval do
+ define_method "deprecated?" do
+ true
+ end
+
+ define_method "deprecation_warning" do
+ msg = [ "#{self.command} command is deprecated",
+ ". It will be removed in Rubygems #{Gem::Deprecate.next_rubygems_major_version}.\n",
+ ]
+
+ alert_warning "#{msg.join}" unless Gem::Deprecate.skip
+ end
+ end
+ end
+
+ module_function :rubygems_deprecate, :rubygems_deprecate_command, :skip_during
+
+end
diff --git a/lib/rubygems/doctor.rb b/lib/rubygems/doctor.rb
index ec4a16c3f8..41bcda9804 100644
--- a/lib/rubygems/doctor.rb
+++ b/lib/rubygems/doctor.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'rubygems'
-require 'rubygems/user_interaction'
+require_relative '../rubygems'
+require_relative 'user_interaction'
##
# Cleans up after a partially-failed uninstall or for an invalid
@@ -12,7 +12,6 @@ require 'rubygems/user_interaction'
# removing the bogus specification.
class Gem::Doctor
-
include Gem::UserInteraction
##
@@ -26,11 +25,12 @@ class Gem::Doctor
['doc', ''],
['extensions', ''],
['gems', ''],
- ]
+ ['plugins', ''],
+ ].freeze
missing =
Gem::REPOSITORY_SUBDIRECTORIES.sort -
- REPOSITORY_EXTENSION_MAP.map { |(k,_)| k }.sort
+ REPOSITORY_EXTENSION_MAP.map {|(k,_)| k }.sort
raise "Update REPOSITORY_EXTENSION_MAP, missing: #{missing.join ', '}" unless
missing.empty?
@@ -41,7 +41,7 @@ class Gem::Doctor
#
# If +dry_run+ is true no files or directories will be removed.
- def initialize gem_repository, dry_run = false
+ def initialize(gem_repository, dry_run = false)
@gem_repository = gem_repository
@dry_run = dry_run
@@ -52,7 +52,7 @@ class Gem::Doctor
# Specs installed in this gem repository
def installed_specs # :nodoc:
- @installed_specs ||= Gem::Specification.map { |s| s.full_name }
+ @installed_specs ||= Gem::Specification.map {|s| s.full_name }
end
##
@@ -73,7 +73,7 @@ class Gem::Doctor
Gem.use_paths @gem_repository.to_s
- unless gem_repository? then
+ unless gem_repository?
say 'This directory does not appear to be a RubyGems repository, ' +
'skipping'
say
@@ -99,7 +99,7 @@ class Gem::Doctor
##
# Removes files in +sub_directory+ with +extension+
- def doctor_child sub_directory, extension # :nodoc:
+ def doctor_child(sub_directory, extension) # :nodoc:
directory = File.join(@gem_repository, sub_directory)
Dir.entries(directory).sort.each do |ent|
@@ -112,10 +112,11 @@ class Gem::Doctor
next if installed_specs.include? basename
next if /^rubygems-\d/ =~ basename
next if 'specifications' == sub_directory and 'default' == basename
+ next if 'plugins' == sub_directory and Gem.plugin_suffix_regexp =~ basename
type = File.directory?(child) ? 'directory' : 'file'
- action = if @dry_run then
+ action = if @dry_run
'Extra'
else
FileUtils.rm_r(child)
@@ -127,6 +128,4 @@ class Gem::Doctor
rescue Errno::ENOENT
# ignore
end
-
end
-
diff --git a/lib/rubygems/errors.rb b/lib/rubygems/errors.rb
index 6f2847d548..86f0d1da14 100644
--- a/lib/rubygems/errors.rb
+++ b/lib/rubygems/errors.rb
@@ -25,14 +25,15 @@ module Gem
# system. Instead of rescuing from this class, make sure to rescue from the
# superclass Gem::LoadError to catch all types of load errors.
class MissingSpecError < Gem::LoadError
- def initialize name, requirement
+ def initialize(name, requirement, extra_message=nil)
@name = name
@requirement = requirement
+ @extra_message = extra_message
end
def message # :nodoc:
build_message +
- "Checked in 'GEM_PATH=#{Gem.path.join(File::PATH_SEPARATOR)}', execute `gem env` for more information"
+ "Checked in 'GEM_PATH=#{Gem.path.join(File::PATH_SEPARATOR)}' #{@extra_message}, execute `gem env` for more information"
end
private
@@ -50,7 +51,7 @@ module Gem
class MissingSpecVersionError < MissingSpecError
attr_reader :specs
- def initialize name, requirement, specs
+ def initialize(name, requirement, specs)
super(name, requirement)
@specs = specs
end
@@ -69,7 +70,6 @@ module Gem
# Raised when there are conflicting gem specs loaded
class ConflictError < LoadError
-
##
# A Hash mapping conflicting specifications to the dependencies that
# caused the conflict
@@ -81,14 +81,14 @@ module Gem
attr_reader :target
- def initialize target, conflicts
+ def initialize(target, conflicts)
@target = target
@conflicts = conflicts
@name = target.name
- reason = conflicts.map { |act, dependencies|
+ reason = conflicts.map do |act, dependencies|
"#{act.full_name} conflicts with #{dependencies.join(", ")}"
- }.join ", "
+ end.join ", "
# TODO: improve message by saying who activated `con`
@@ -105,7 +105,6 @@ module Gem
# in figuring out why a gem couldn't be installed.
#
class PlatformMismatch < ErrorReason
-
##
# the name of the gem
attr_reader :name
@@ -150,7 +149,6 @@ module Gem
# data from a source
class SourceFetchProblem < ErrorReason
-
##
# Creates a new SourceFetchProblem for the given +source+ and +error+.
@@ -173,8 +171,7 @@ module Gem
# An English description of the error.
def wordy
- @source.uri.password = 'REDACTED' unless @source.uri.password.nil?
- "Unable to download data from #{@source.uri} - #{@error.message}"
+ "Unable to download data from #{Gem::Uri.new(@source.uri).redacted} - #{@error.message}"
end
##
diff --git a/lib/rubygems/exceptions.rb b/lib/rubygems/exceptions.rb
index b7528761fc..5f20dfaed0 100644
--- a/lib/rubygems/exceptions.rb
+++ b/lib/rubygems/exceptions.rb
@@ -1,21 +1,11 @@
# frozen_string_literal: true
-# TODO: the documentation in here is terrible.
-#
-# Each exception needs a brief description and the scenarios where it is
-# likely to be raised
+
+require_relative 'deprecate'
##
# Base exception class for RubyGems. All exception raised by RubyGems are a
# subclass of this one.
-class Gem::Exception < RuntimeError
-
- ##
- #--
- # TODO: remove in RubyGems 3, nobody sets this
-
- attr_accessor :source_exception # :nodoc:
-
-end
+class Gem::Exception < RuntimeError; end
class Gem::CommandLineError < Gem::Exception; end
@@ -29,10 +19,9 @@ class Gem::DependencyRemovalException < Gem::Exception; end
# and #conflicting_dependencies
class Gem::DependencyResolutionError < Gem::DependencyError
-
attr_reader :conflict
- def initialize conflict
+ def initialize(conflict)
@conflict = conflict
a, b = conflicting_dependencies
@@ -42,7 +31,6 @@ class Gem::DependencyResolutionError < Gem::DependencyError
def conflicting_dependencies
@conflict.conflicting_dependencies
end
-
end
##
@@ -52,6 +40,13 @@ class Gem::GemNotInHomeException < Gem::Exception
attr_accessor :spec
end
+###
+# Raised when removing a gem with the uninstall command fails
+
+class Gem::UninstallError < Gem::Exception
+ attr_accessor :spec
+end
+
class Gem::DocumentError < Gem::Exception; end
##
@@ -63,15 +58,13 @@ class Gem::EndOfYAMLException < Gem::Exception; end
# operating on the given directory.
class Gem::FilePermissionError < Gem::Exception
-
attr_reader :directory
- def initialize directory
+ def initialize(directory)
@directory = directory
super "You don't have write permissions for the #{directory} directory."
end
-
end
##
@@ -86,7 +79,6 @@ class Gem::GemNotFoundException < Gem::Exception; end
# Raised by the DependencyInstaller when a specific gem cannot be found
class Gem::SpecificGemNotFoundException < Gem::GemNotFoundException
-
##
# Creates a new SpecificGemNotFoundException for a gem with the given +name+
# and +version+. Any +errors+ encountered when attempting to find the gem
@@ -114,7 +106,6 @@ class Gem::SpecificGemNotFoundException < Gem::GemNotFoundException
# Errors encountered attempting to find the gem.
attr_reader :errors
-
end
##
@@ -122,11 +113,10 @@ end
# inability to find a valid possible spec for a request.
class Gem::ImpossibleDependenciesError < Gem::Exception
-
attr_reader :conflicts
attr_reader :request
- def initialize request, conflicts
+ def initialize(request, conflicts)
@request = request
@conflicts = conflicts
@@ -150,7 +140,6 @@ class Gem::ImpossibleDependenciesError < Gem::Exception
def dependency
@request.dependency
end
-
end
class Gem::InstallError < Gem::Exception; end
@@ -200,7 +189,6 @@ class Gem::VerificationError < Gem::Exception; end
# exit_code
class Gem::SystemExitException < SystemExit
-
##
# The exit code for the process
@@ -214,7 +202,6 @@ class Gem::SystemExitException < SystemExit
super "Exiting RubyGems with exit_code #{exit_code}"
end
-
end
##
@@ -222,7 +209,6 @@ end
# there is no spec.
class Gem::UnsatisfiableDependencyError < Gem::DependencyError
-
##
# The unsatisfiable dependency. This is a
# Gem::Resolver::DependencyRequest, not a Gem::Dependency
@@ -238,9 +224,9 @@ class Gem::UnsatisfiableDependencyError < Gem::DependencyError
# Creates a new UnsatisfiableDependencyError for the unsatisfiable
# Gem::Resolver::DependencyRequest +dep+
- def initialize dep, platform_mismatch=nil
+ def initialize(dep, platform_mismatch=nil)
if platform_mismatch and !platform_mismatch.empty?
- plats = platform_mismatch.map { |x| x.platform.to_s }.sort.uniq
+ plats = platform_mismatch.map {|x| x.platform.to_s }.sort.uniq
super "Unable to resolve dependency: No match for '#{dep}' on this platform. Found: #{plats.join(', ')}"
else
if dep.explicit?
@@ -267,10 +253,10 @@ class Gem::UnsatisfiableDependencyError < Gem::DependencyError
def version
@dependency.requirement
end
-
end
##
# Backwards compatible typo'd exception class for early RubyGems 2.0.x
Gem::UnsatisfiableDepedencyError = Gem::UnsatisfiableDependencyError # :nodoc:
+Gem.deprecate_constant :UnsatisfiableDepedencyError
diff --git a/lib/rubygems/ext.rb b/lib/rubygems/ext.rb
index 18d2bc233a..bdd5bd9d82 100644
--- a/lib/rubygems/ext.rb
+++ b/lib/rubygems/ext.rb
@@ -10,10 +10,9 @@
module Gem::Ext; end
-require 'rubygems/ext/build_error'
-require 'rubygems/ext/builder'
-require 'rubygems/ext/configure_builder'
-require 'rubygems/ext/ext_conf_builder'
-require 'rubygems/ext/rake_builder'
-require 'rubygems/ext/cmake_builder'
-
+require_relative 'ext/build_error'
+require_relative 'ext/builder'
+require_relative 'ext/configure_builder'
+require_relative 'ext/ext_conf_builder'
+require_relative 'ext/rake_builder'
+require_relative 'ext/cmake_builder'
diff --git a/lib/rubygems/ext/build_error.rb b/lib/rubygems/ext/build_error.rb
index 0b3c17a9a0..8ef57ed91a 100644
--- a/lib/rubygems/ext/build_error.rb
+++ b/lib/rubygems/ext/build_error.rb
@@ -2,6 +2,7 @@
##
# Raised when there is an error while building extensions.
+require_relative '../exceptions'
+
class Gem::Ext::BuildError < Gem::InstallError
end
-
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb
index a1619c97d7..c1a1bc9c00 100644
--- a/lib/rubygems/ext/builder.rb
+++ b/lib/rubygems/ext/builder.rb
@@ -5,21 +5,11 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems/user_interaction'
-require 'thread'
+require_relative '../user_interaction'
class Gem::Ext::Builder
-
include Gem::UserInteraction
- ##
- # The builder shells-out to run various commands after changing the
- # directory. This means multiple installations cannot be allowed to build
- # extensions in parallel as they may change each other's directories leading
- # to broken extensions or failed installations.
-
- CHDIR_MUTEX = Mutex.new # :nodoc:
-
attr_accessor :build_args # :nodoc:
def self.class_name
@@ -27,66 +17,77 @@ class Gem::Ext::Builder
$1.downcase
end
- def self.make(dest_path, results)
- unless File.exist? 'Makefile' then
+ def self.make(dest_path, results, make_dir = Dir.pwd)
+ unless File.exist? File.join(make_dir, 'Makefile')
raise Gem::InstallError, 'Makefile not found'
end
# try to find make program from Ruby configure arguments first
RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
- make_program = ENV['MAKE'] || ENV['make'] || $1
- unless make_program then
- make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
+ make_program_name = ENV['MAKE'] || ENV['make'] || $1
+ unless make_program_name
+ make_program_name = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
end
+ make_program = Shellwords.split(make_program_name)
- destdir = '"DESTDIR=%s"' % ENV['DESTDIR'] if RUBY_VERSION > '2.0'
+ # The installation of the bundled gems is failed when DESTDIR is empty in mswin platform.
+ destdir = (/\bnmake/i !~ make_program_name || ENV['DESTDIR'] && ENV['DESTDIR'] != "") ? 'DESTDIR=%s' % ENV['DESTDIR'] : ''
['clean', '', 'install'].each do |target|
# Pass DESTDIR via command line to override what's in MAKEFLAGS
cmd = [
- make_program,
+ *make_program,
destdir,
- target
- ].join(' ').rstrip
+ target,
+ ].reject(&:empty?)
begin
- run(cmd, results, "make #{target}".rstrip)
+ run(cmd, results, "make #{target}".rstrip, make_dir)
rescue Gem::InstallError
raise unless target == 'clean' # ignore clean failure
end
end
end
- def self.redirector
- '2>&1'
- end
-
- def self.run(command, results, command_name = nil)
+ def self.run(command, results, command_name = nil, dir = Dir.pwd)
verbose = Gem.configuration.really_verbose
begin
- # TODO use Process.spawn when ruby 1.8 support is dropped.
rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil
if verbose
- puts("current directory: #{Dir.pwd}")
- puts(command)
- system(command)
+ puts("current directory: #{dir}")
+ p(command)
+ end
+ results << "current directory: #{dir}"
+ require "shellwords"
+ results << command.shelljoin
+
+ require "open3"
+ # Set $SOURCE_DATE_EPOCH for the subprocess.
+ env = {'SOURCE_DATE_EPOCH' => Gem.source_date_epoch_string}
+ output, status = Open3.capture2e(env, *command, :chdir => dir)
+ if verbose
+ puts output
else
- results << "current directory: #{Dir.pwd}"
- results << command
- results << `#{command} #{redirector}`
+ results << output
end
+ rescue => error
+ raise Gem::InstallError, "#{command_name || class_name} failed#{error.message}"
ensure
ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
end
- unless $?.success? then
+ unless status.success?
results << "Building has failed. See above output for more information on the failure." if verbose
+ end
+
+ yield(status, results) if block_given?
+ unless status.success?
exit_reason =
- if $?.exited? then
- ", exit code #{$?.exitstatus}"
- elsif $?.signaled? then
- ", uncaught signal #{$?.termsig}"
+ if status.exited?
+ ", exit code #{status.exitstatus}"
+ elsif status.signaled?
+ ", uncaught signal #{status.termsig}"
end
raise Gem::InstallError, "#{command_name || class_name} failed#{exit_reason}"
@@ -98,18 +99,18 @@ class Gem::Ext::Builder
# have build arguments, saved, set +build_args+ which is an ARGV-style
# array.
- def initialize spec, build_args = spec.build_args
+ def initialize(spec, build_args = spec.build_args)
@spec = spec
@build_args = build_args
@gem_dir = spec.full_gem_path
- @ran_rake = nil
+ @ran_rake = false
end
##
# Chooses the extension builder class for +extension+
- def builder_for extension # :nodoc:
+ def builder_for(extension) # :nodoc:
case extension
when /extconf/ then
Gem::Ext::ExtConfBuilder
@@ -121,17 +122,14 @@ class Gem::Ext::Builder
when /CMakeLists.txt/ then
Gem::Ext::CmakeBuilder
else
- extension_dir = File.join @gem_dir, File.dirname(extension)
-
- message = "No builder for extension '#{extension}'"
- build_error extension_dir, message
+ build_error("No builder for extension '#{extension}'")
end
end
##
- # Logs the build +output+ in +build_dir+, then raises Gem::Ext::BuildError.
+ # Logs the build +output+, then raises Gem::Ext::BuildError.
- def build_error build_dir, output, backtrace = nil # :nodoc:
+ def build_error(output, backtrace = nil) # :nodoc:
gem_make_out = write_gem_make_out output
message = <<-EOF
@@ -146,32 +144,27 @@ EOF
raise Gem::Ext::BuildError, message, backtrace
end
- def build_extension extension, dest_path # :nodoc:
+ def build_extension(extension, dest_path) # :nodoc:
results = []
- extension ||= '' # I wish I knew why this line existed
+ builder = builder_for(extension)
+
extension_dir =
- File.expand_path File.join @gem_dir, File.dirname(extension)
+ File.expand_path File.join(@gem_dir, File.dirname(extension))
lib_dir = File.join @spec.full_gem_path, @spec.raw_require_paths.first
- builder = builder_for extension
-
begin
FileUtils.mkdir_p dest_path
- CHDIR_MUTEX.synchronize do
- Dir.chdir extension_dir do
- results = builder.build(extension, @gem_dir, dest_path,
- results, @build_args, lib_dir)
+ results = builder.build(extension, dest_path,
+ results, @build_args, lib_dir, extension_dir)
- verbose { results.join("\n") }
- end
- end
+ verbose { results.join("\n") }
write_gem_make_out results.join "\n"
rescue => e
results << e.message
- build_error extension_dir, results.join("\n"), $@
+ build_error(results.join("\n"), $@)
end
end
@@ -191,10 +184,9 @@ EOF
dest_path = @spec.extension_dir
+ require "fileutils"
FileUtils.rm_f @spec.gem_build_complete_path
- @ran_rake = false # only run rake once
-
@spec.extensions.each do |extension|
break if @ran_rake
@@ -207,15 +199,15 @@ EOF
##
# Writes +output+ to gem_make.out in the extension install directory.
- def write_gem_make_out output # :nodoc:
+ def write_gem_make_out(output) # :nodoc:
destination = File.join @spec.extension_dir, 'gem_make.out'
FileUtils.mkdir_p @spec.extension_dir
- open destination, 'wb' do |io| io.puts output end
+ File.open destination, 'wb' do |io|
+ io.puts output
+ end
destination
end
-
end
-
diff --git a/lib/rubygems/ext/cmake_builder.rb b/lib/rubygems/ext/cmake_builder.rb
index efa3bd1d88..e47cabef84 100644
--- a/lib/rubygems/ext/cmake_builder.rb
+++ b/lib/rubygems/ext/cmake_builder.rb
@@ -1,16 +1,15 @@
# frozen_string_literal: true
-require 'rubygems/command'
class Gem::Ext::CmakeBuilder < Gem::Ext::Builder
- def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
- unless File.exist?('Makefile') then
- cmd = "cmake . -DCMAKE_INSTALL_PREFIX=#{dest_path}"
- cmd << " #{Gem::Command.build_args.join ' '}" unless Gem::Command.build_args.empty?
+ def self.build(extension, dest_path, results, args=[], lib_dir=nil, cmake_dir=Dir.pwd)
+ unless File.exist?(File.join(cmake_dir, 'Makefile'))
+ require_relative '../command'
+ cmd = ["cmake", ".", "-DCMAKE_INSTALL_PREFIX=#{dest_path}", *Gem::Command.build_args]
- run cmd, results
+ run cmd, results, class_name, cmake_dir
end
- make dest_path, results
+ make dest_path, results, cmake_dir
results
end
diff --git a/lib/rubygems/ext/configure_builder.rb b/lib/rubygems/ext/configure_builder.rb
index 8b42bf7ee9..eb2f9fce61 100644
--- a/lib/rubygems/ext/configure_builder.rb
+++ b/lib/rubygems/ext/configure_builder.rb
@@ -6,19 +6,15 @@
#++
class Gem::Ext::ConfigureBuilder < Gem::Ext::Builder
+ def self.build(extension, dest_path, results, args=[], lib_dir=nil, configure_dir=Dir.pwd)
+ unless File.exist?(File.join(configure_dir, 'Makefile'))
+ cmd = ["sh", "./configure", "--prefix=#{dest_path}", *args]
- def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
- unless File.exist?('Makefile') then
- cmd = "sh ./configure --prefix=#{dest_path}"
- cmd << " #{args.join ' '}" unless args.empty?
-
- run cmd, results
+ run cmd, results, class_name, configure_dir
end
- make dest_path, results
+ make dest_path, results, configure_dir
results
end
-
end
-
diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb
index 965b728278..3ca3463615 100644
--- a/lib/rubygems/ext/ext_conf_builder.rb
+++ b/lib/rubygems/ext/ext_conf_builder.rb
@@ -5,14 +5,12 @@
# See LICENSE.txt for permissions.
#++
-require 'fileutils'
-require 'tempfile'
-
class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
- FileEntry = FileUtils::Entry_ # :nodoc:
+ def self.build(extension, dest_path, results, args=[], lib_dir=nil, extension_dir=Dir.pwd)
+ require 'fileutils'
+ require 'tempfile'
- def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
- tmp_dest = Dir.mktmpdir(".gem.", ".")
+ tmp_dest = Dir.mktmpdir(".gem.", extension_dir)
# Some versions of `mktmpdir` return absolute paths, which will break make
# if the paths contain spaces. However, on Ruby 1.9.x on Windows, relative
@@ -23,13 +21,11 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
# spaces do not work.
#
# Details: https://github.com/rubygems/rubygems/issues/977#issuecomment-171544940
- #
- # TODO: Make this unconditional when rubygems no longer supports Ruby 1.9.x.
- tmp_dest = get_relative_path(tmp_dest) unless Gem.win_platform? && RUBY_VERSION <= '2.0'
+ tmp_dest_relative = get_relative_path(tmp_dest.clone, extension_dir)
- Tempfile.open %w"siteconf .rb", "." do |siteconf|
+ Tempfile.open %w[siteconf .rb], extension_dir do |siteconf|
siteconf.puts "require 'rbconfig'"
- siteconf.puts "dest_path = #{tmp_dest.dump}"
+ siteconf.puts "dest_path = #{tmp_dest_relative.dump}"
%w[sitearchdir sitelibdir].each do |dir|
siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
@@ -40,36 +36,44 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
destdir = ENV["DESTDIR"]
begin
- cmd = [Gem.ruby, "-r", get_relative_path(siteconf.path), File.basename(extension), *args].join ' '
+ # workaround for https://github.com/oracle/truffleruby/issues/2115
+ siteconf_path = RUBY_ENGINE == "truffleruby" ? siteconf.path.dup : siteconf.path
+ require "shellwords"
+ cmd = Gem.ruby.shellsplit << "-I" << File.expand_path("../../..", __FILE__) <<
+ "-r" << get_relative_path(siteconf_path, extension_dir) << File.basename(extension)
+ cmd.push(*args)
begin
- run cmd, results
- ensure
- if File.exist? 'mkmf.log'
- unless $?.success? then
- results << "To see why this extension failed to compile, please check" \
- " the mkmf.log which can be found here:\n"
- results << " " + File.join(dest_path, 'mkmf.log') + "\n"
+ run(cmd, results, class_name, extension_dir) do |s, r|
+ mkmf_log = File.join(extension_dir, 'mkmf.log')
+ if File.exist? mkmf_log
+ unless s.success?
+ r << "To see why this extension failed to compile, please check" \
+ " the mkmf.log which can be found here:\n"
+ r << " " + File.join(dest_path, 'mkmf.log') + "\n"
+ end
+ FileUtils.mv mkmf_log, dest_path
end
- FileUtils.mv 'mkmf.log', dest_path
end
siteconf.unlink
end
ENV["DESTDIR"] = nil
- make dest_path, results
+ make dest_path, results, extension_dir
+
+ if tmp_dest_relative
+ full_tmp_dest = File.join(extension_dir, tmp_dest_relative)
- if tmp_dest
# TODO remove in RubyGems 3
- if Gem.install_extension_in_lib and lib_dir then
+ if Gem.install_extension_in_lib and lib_dir
FileUtils.mkdir_p lib_dir
- entries = Dir.entries(tmp_dest) - %w[. ..]
- entries = entries.map { |entry| File.join tmp_dest, entry }
+ entries = Dir.entries(full_tmp_dest) - %w[. ..]
+ entries = entries.map {|entry| File.join full_tmp_dest, entry }
FileUtils.cp_r entries, lib_dir, :remove_destination => true
end
- FileEntry.new(tmp_dest).traverse do |ent|
+ FileUtils::Entry_.new(full_tmp_dest).traverse do |ent|
destent = ent.class.new(dest_path, ent.rel)
destent.exist? or FileUtils.mv(ent.path, destent.path)
end
@@ -86,9 +90,9 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
end
private
- def self.get_relative_path(path)
- path[0..Dir.pwd.length-1] = '.' if path.start_with?(Dir.pwd)
+
+ def self.get_relative_path(path, base)
+ path[0..base.length - 1] = '.' if path.start_with?(base)
path
end
-
end
diff --git a/lib/rubygems/ext/rake_builder.rb b/lib/rubygems/ext/rake_builder.rb
index 4b3534bf35..fed98e741c 100644
--- a/lib/rubygems/ext/rake_builder.rb
+++ b/lib/rubygems/ext/rake_builder.rb
@@ -6,32 +6,27 @@
#++
class Gem::Ext::RakeBuilder < Gem::Ext::Builder
-
- def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
- if File.basename(extension) =~ /mkrf_conf/i then
- cmd = "#{Gem.ruby} #{File.basename extension}".dup
- cmd << " #{args.join " "}" unless args.empty?
- run cmd, results
+ def self.build(extension, dest_path, results, args=[], lib_dir=nil, extension_dir=Dir.pwd)
+ if File.basename(extension) =~ /mkrf_conf/i
+ run([Gem.ruby, File.basename(extension), *args], results, class_name, extension_dir)
end
- # Deal with possible spaces in the path, e.g. C:/Program Files
- dest_path = '"' + dest_path.to_s + '"' if dest_path.to_s.include?(' ')
-
rake = ENV['rake']
- rake ||= begin
- "#{Gem.ruby} -rrubygems #{Gem.bin_path('rake', 'rake')}"
- rescue Gem::Exception
- end
-
- rake ||= Gem.default_exec_format % 'rake'
-
- cmd = "#{rake} RUBYARCHDIR=#{dest_path} RUBYLIBDIR=#{dest_path}" # ENV is frozen
+ if rake
+ require "shellwords"
+ rake = rake.shellsplit
+ else
+ begin
+ rake = [Gem.ruby, "-I#{File.expand_path("../..", __dir__)}", "-rrubygems", Gem.bin_path('rake', 'rake')]
+ rescue Gem::Exception
+ rake = [Gem.default_exec_format % 'rake']
+ end
+ end
- run cmd, results
+ rake_args = ["RUBYARCHDIR=#{dest_path}", "RUBYLIBDIR=#{dest_path}", *args]
+ run(rake + rake_args, results, class_name, extension_dir)
results
end
-
end
-
diff --git a/lib/rubygems/gem_runner.rb b/lib/rubygems/gem_runner.rb
index 349d49d66e..55b5a7d067 100644
--- a/lib/rubygems/gem_runner.rb
+++ b/lib/rubygems/gem_runner.rb
@@ -5,10 +5,9 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems'
-require 'rubygems/command_manager'
-require 'rubygems/config_file'
-require 'rubygems/deprecate'
+require_relative '../rubygems'
+require_relative 'command_manager'
+require_relative 'deprecate'
##
# Load additional plugins from $LOAD_PATH
@@ -25,20 +24,15 @@ Gem.load_env_plugins rescue nil
# classes they call directly.
class Gem::GemRunner
-
- def initialize(options={})
- if !options.empty? && !Gem::Deprecate.skip
- Kernel.warn "NOTE: passing options to Gem::GemRunner.new is deprecated with no replacement. It will be removed on or after 2016-10-01."
- end
-
- @command_manager_class = options[:command_manager] || Gem::CommandManager
- @config_file_class = options[:config_file] || Gem::ConfigFile
+ def initialize
+ @command_manager_class = Gem::CommandManager
+ @config_file_class = Gem::ConfigFile
end
##
# Run the gem command with the following arguments.
- def run args
+ def run(args)
build_args = extract_build_args args
do_configuration args
@@ -63,7 +57,7 @@ class Gem::GemRunner
# Separates the build arguments (those following <code>--</code>) from the
# other arguments in the list.
- def extract_build_args args # :nodoc:
+ def extract_build_args(args) # :nodoc:
return [] unless offset = args.index('--')
build_args = args.slice!(offset...args.length)
@@ -80,7 +74,6 @@ class Gem::GemRunner
Gem.use_paths Gem.configuration[:gemhome], Gem.configuration[:gempath]
Gem::Command.extra_args = Gem.configuration[:gem]
end
-
end
Gem.load_plugins
diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb
index 7c6d6bb364..0968e1a6f9 100644
--- a/lib/rubygems/gemcutter_utilities.rb
+++ b/lib/rubygems/gemcutter_utilities.rb
@@ -1,17 +1,19 @@
# frozen_string_literal: true
-require 'rubygems/remote_fetcher'
+require_relative 'remote_fetcher'
+require_relative 'text'
##
# Utility methods for using the RubyGems API.
module Gem::GemcutterUtilities
- # TODO: move to Gem::Command
- OptionParser.accept Symbol do |value|
- value.to_sym
- end
+ ERROR_CODE = 1
+ API_SCOPES = %i[index_rubygems push_rubygem yank_rubygem add_owner remove_owner access_webhooks show_dashboard].freeze
+
+ include Gem::Text
attr_writer :host
+ attr_writer :scope
##
# Add the --key option
@@ -19,16 +21,29 @@ module Gem::GemcutterUtilities
def add_key_option
add_option('-k', '--key KEYNAME', Symbol,
'Use the given API key',
- 'from ~/.gem/credentials') do |value,options|
+ "from #{Gem.configuration.credentials_path}") do |value,options|
options[:key] = value
end
end
##
+ # Add the --otp option
+
+ def add_otp_option
+ add_option('--otp CODE',
+ 'Digit code for multifactor authentication',
+ 'You can also use the environment variable GEM_HOST_OTP_CODE') do |value, options|
+ options[:otp] = value
+ end
+ end
+
+ ##
# The API key from the command options or from the user's configuration.
def api_key
- if options[:key] then
+ if ENV["GEM_HOST_API_KEY"]
+ ENV["GEM_HOST_API_KEY"]
+ elsif options[:key]
verify_api_key options[:key]
elsif Gem.configuration.api_keys.key?(host)
Gem.configuration.api_keys[host]
@@ -38,6 +53,13 @@ module Gem::GemcutterUtilities
end
##
+ # The OTP code from the command options or from the user's configuration.
+
+ def otp
+ options[:otp] || ENV["GEM_HOST_OTP_CODE"]
+ end
+
+ ##
# The host to connect to either from the RUBYGEMS_HOST environment variable
# or from the user's configuration
@@ -51,7 +73,7 @@ module Gem::GemcutterUtilities
env_rubygems_host = nil if
env_rubygems_host and env_rubygems_host.empty?
- env_rubygems_host|| configured_host
+ env_rubygems_host || configured_host
end
end
@@ -60,13 +82,13 @@ module Gem::GemcutterUtilities
#
# If +allowed_push_host+ metadata is present, then it will only allow that host.
- def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, &block)
+ def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, scope: nil, &block)
require 'net/http'
self.host = host if host
unless self.host
alert_error "You must specify a gem server"
- terminate_interaction 1 # TODO: question this
+ terminate_interaction(ERROR_CODE)
end
if allowed_push_host
@@ -75,46 +97,82 @@ module Gem::GemcutterUtilities
unless (host_uri.scheme == allowed_host_uri.scheme) && (host_uri.host == allowed_host_uri.host)
alert_error "#{self.host.inspect} is not allowed by the gemspec, which only allows #{allowed_push_host.inspect}"
- terminate_interaction 1
+ terminate_interaction(ERROR_CODE)
end
end
uri = URI.parse "#{self.host}/#{path}"
+ response = request_with_otp(method, uri, &block)
- request_method = Net::HTTP.const_get method.to_s.capitalize
+ if mfa_unauthorized?(response)
+ ask_otp
+ response = request_with_otp(method, uri, &block)
+ end
- Gem::RemoteFetcher.fetcher.request(uri, request_method, &block)
+ if api_key_forbidden?(response)
+ update_scope(scope)
+ request_with_otp(method, uri, &block)
+ else
+ response
+ end
+ end
+
+ def mfa_unauthorized?(response)
+ response.kind_of?(Net::HTTPUnauthorized) && response.body.start_with?('You have enabled multifactor authentication')
+ end
+
+ def update_scope(scope)
+ sign_in_host = self.host
+ pretty_host = pretty_host(sign_in_host)
+ update_scope_params = { scope => true }
+
+ say "The existing key doesn't have access of #{scope} on #{pretty_host}. Please sign in to update access."
+
+ email = ask " Email: "
+ password = ask_for_password "Password: "
+
+ response = rubygems_api_request(:put, "api/v1/api_key",
+ sign_in_host, scope: scope) do |request|
+ request.basic_auth email, password
+ request["OTP"] = otp if otp
+ request.body = URI.encode_www_form({:api_key => api_key }.merge(update_scope_params))
+ end
+
+ with_response response do |resp|
+ say "Added #{scope} scope to the existing API key"
+ end
end
##
# Signs in with the RubyGems API at +sign_in_host+ and sets the rubygems API
# key.
- def sign_in sign_in_host = nil
+ def sign_in(sign_in_host = nil, scope: nil)
sign_in_host ||= self.host
return if api_key
- pretty_host = if Gem::DEFAULT_HOST == sign_in_host then
- 'RubyGems.org'
- else
- sign_in_host
- end
+ pretty_host = pretty_host(sign_in_host)
say "Enter your #{pretty_host} credentials."
say "Don't have an account yet? " +
"Create one at #{sign_in_host}/sign_up"
- email = ask " Email: "
+ email = ask " Email: "
password = ask_for_password "Password: "
say "\n"
- response = rubygems_api_request(:get, "api/v1/api_key",
- sign_in_host) do |request|
+ key_name = get_key_name(scope)
+ scope_params = get_scope_params(scope)
+
+ response = rubygems_api_request(:post, "api/v1/api_key",
+ sign_in_host, scope: scope) do |request|
request.basic_auth email, password
+ request["OTP"] = otp if otp
+ request.body = URI.encode_www_form({ name: key_name }.merge(scope_params))
end
with_response response do |resp|
- say "Signed in."
+ say "Signed in with API key: #{key_name}."
set_api_key host, resp.body
end
end
@@ -124,11 +182,11 @@ module Gem::GemcutterUtilities
# an error.
def verify_api_key(key)
- if Gem.configuration.api_keys.key? key then
+ if Gem.configuration.api_keys.key? key
Gem.configuration.api_keys[key]
else
alert_error "No such API key. Please add it to your configuration (done automatically on initial `gem push`)."
- terminate_interaction 1 # TODO: question this
+ terminate_interaction(ERROR_CODE)
end
end
@@ -139,24 +197,28 @@ module Gem::GemcutterUtilities
# If the response was not successful, shows an error to the user including
# the +error_prefix+ and the response body.
- def with_response response, error_prefix = nil
+ def with_response(response, error_prefix = nil)
case response
when Net::HTTPSuccess then
- if block_given? then
+ if block_given?
yield response
else
- say response.body
+ say clean_text(response.body)
end
else
message = response.body
message = "#{error_prefix}: #{message}" if error_prefix
- say message
- terminate_interaction 1 # TODO: question this
+ say clean_text(message)
+ terminate_interaction(ERROR_CODE)
end
end
- def set_api_key host, key
+ ##
+ # Returns true when the user has enabled multifactor authentication from
+ # +response+ text and no otp provided by options.
+
+ def set_api_key(host, key)
if host == Gem::DEFAULT_HOST
Gem.configuration.rubygems_api_key = key
else
@@ -164,5 +226,62 @@ module Gem::GemcutterUtilities
end
end
-end
+ private
+
+ def request_with_otp(method, uri, &block)
+ request_method = Net::HTTP.const_get method.to_s.capitalize
+
+ Gem::RemoteFetcher.fetcher.request(uri, request_method) do |req|
+ req["OTP"] = otp if otp
+ block.call(req)
+ end
+ end
+
+ def ask_otp
+ say 'You have enabled multi-factor authentication. Please enter OTP code.'
+ options[:otp] = ask 'Code: '
+ end
+
+ def pretty_host(host)
+ if Gem::DEFAULT_HOST == host
+ 'RubyGems.org'
+ else
+ host
+ end
+ end
+ def get_scope_params(scope)
+ scope_params = {}
+
+ if scope
+ scope_params = { scope => true }
+ else
+ say "Please select scopes you want to enable for the API key (y/n)"
+ API_SCOPES.each do |scope|
+ selected = ask "#{scope} [y/N]: "
+ scope_params[scope] = true if selected =~ /^[yY](es)?$/
+ end
+ say "\n"
+ end
+
+ scope_params
+ end
+
+ def get_key_name(scope)
+ hostname = Socket.gethostname || "unknown-host"
+ user = ENV["USER"] || ENV["USERNAME"] || "unknown-user"
+ ts = Time.now.strftime("%Y%m%d%H%M%S")
+ default_key_name = "#{hostname}-#{user}-#{ts}"
+
+ key_name = ask "API Key name [#{default_key_name}]: " unless scope
+ if key_name.nil? || key_name.empty?
+ default_key_name
+ else
+ key_name
+ end
+ end
+
+ def api_key_forbidden?(response)
+ response.kind_of?(Net::HTTPForbidden) && response.body.start_with?("The API key doesn't have access")
+ end
+end
diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb
index 871cc09d8d..6e8dade640 100644
--- a/lib/rubygems/indexer.rb
+++ b/lib/rubygems/indexer.rb
@@ -1,19 +1,12 @@
# frozen_string_literal: true
-require 'rubygems'
-require 'rubygems/package'
-require 'time'
-
-begin
- gem 'builder'
- require 'builder/xchar'
-rescue LoadError
-end
+require_relative '../rubygems'
+require_relative 'package'
+require 'tmpdir'
##
# Top level class for building the gem repository index.
class Gem::Indexer
-
include Gem::UserInteraction
##
@@ -54,17 +47,12 @@ class Gem::Indexer
require 'tmpdir'
require 'zlib'
- unless defined?(Builder::XChar) then
- raise "Gem::Indexer requires that the XML Builder library be installed:" +
- "\n\tgem install builder"
- end
-
options = { :build_modern => true }.merge options
@build_modern = options[:build_modern]
@dest_directory = directory
- @directory = File.join(Dir.tmpdir, "gem_generate_index_#{$$}")
+ @directory = Dir.mktmpdir 'gem_generate_index'
marshal_name = "Marshal.#{Gem.marshal_version}"
@@ -108,7 +96,7 @@ class Gem::Indexer
##
# Builds Marshal quick index gemspecs.
- def build_marshal_gemspecs specs
+ def build_marshal_gemspecs(specs)
count = specs.count
progress = ui.progress_reporter count,
"Generating Marshal quick index gemspecs for #{count} gems",
@@ -123,7 +111,10 @@ class Gem::Indexer
marshal_name = File.join @quick_marshal_dir, spec_file_name
marshal_zipped = Gem.deflate Marshal.dump(spec)
- open marshal_name, 'wb' do |io| io.write marshal_zipped end
+
+ File.open marshal_name, 'wb' do |io|
+ io.write marshal_zipped
+ end
files << marshal_name
@@ -145,7 +136,7 @@ class Gem::Indexer
say "Generating #{name} index"
Gem.time "Generated #{name} index" do
- open(file, 'wb') do |io|
+ File.open(file, 'wb') do |io|
specs = index.map do |*spec|
# We have to splat here because latest_specs is an array, while the
# others are hashes.
@@ -153,7 +144,7 @@ class Gem::Indexer
platform = spec.original_platform
# win32-api-1.0.4-x86-mswin32-60
- unless String === platform then
+ unless String === platform
alert_warning "Skipping invalid platform in gem: #{spec.full_name}"
next
end
@@ -171,10 +162,10 @@ class Gem::Indexer
##
# Builds indices for RubyGems 1.2 and newer. Handles full, latest, prerelease
- def build_modern_indices specs
- prerelease, released = specs.partition { |s|
+ def build_modern_indices(specs)
+ prerelease, released = specs.partition do |s|
s.version.prerelease?
- }
+ end
latest_specs =
Gem::Specification._latest_specs specs
@@ -191,9 +182,9 @@ class Gem::Indexer
"#{@prerelease_specs_index}.gz"]
end
- def map_gems_to_specs gems
- gems.map { |gemfile|
- if File.size(gemfile) == 0 then
+ def map_gems_to_specs(gems)
+ gems.map do |gemfile|
+ if File.size(gemfile) == 0
alert_warning "Skipping zero-length gem: #{gemfile}"
next
end
@@ -215,7 +206,7 @@ class Gem::Indexer
"\t#{e.backtrace.join "\n\t"}"].join("\n")
alert_error msg
end
- }.compact
+ end.compact
end
##
@@ -227,7 +218,7 @@ class Gem::Indexer
say "Compressing indices"
Gem.time 'Compressed indices' do
- if @build_modern then
+ if @build_modern
gzip @specs_index
gzip @latest_specs_index
gzip @prerelease_specs_index
@@ -261,7 +252,7 @@ class Gem::Indexer
zipped = Gem.deflate data
- open "#{filename}.#{extension}", 'wb' do |io|
+ File.open "#{filename}.#{extension}", 'wb' do |io|
io.write zipped
end
end
@@ -270,7 +261,7 @@ class Gem::Indexer
# List of gem file names to index.
def gem_file_list
- Dir[File.join(@dest_directory, "gems", '*.gem')]
+ Gem::Util.glob_files_in_dir("*.gem", File.join(@dest_directory, "gems"))
end
##
@@ -305,7 +296,7 @@ class Gem::Indexer
files = @files
files.delete @quick_marshal_dir if files.include? @quick_dir
- if files.include? @quick_marshal_dir and not files.include? @quick_dir then
+ if files.include? @quick_marshal_dir and not files.include? @quick_dir
files.delete @quick_marshal_dir
dst_name = File.join(@dest_directory, @quick_marshal_dir_base)
@@ -346,7 +337,7 @@ class Gem::Indexer
data = Gem.read_binary path
compressed_data = Gem.read_binary "#{path}.#{extension}"
- unless data == Gem.inflate(compressed_data) then
+ unless data == Gem::Util.inflate(compressed_data)
raise "Compressed file #{compressed_path} does not match uncompressed file #{path}"
end
end
@@ -366,13 +357,13 @@ class Gem::Indexer
gem_mtime >= specs_mtime
end
- if updated_gems.empty? then
+ if updated_gems.empty?
say 'No new gems'
terminate_interaction 0
end
specs = map_gems_to_specs updated_gems
- prerelease, released = specs.partition { |s| s.version.prerelease? }
+ prerelease, released = specs.partition {|s| s.version.prerelease? }
files = build_marshal_gemspecs specs
@@ -427,7 +418,7 @@ class Gem::Indexer
specs_index = compact_specs specs_index.uniq.sort
- open dest, 'wb' do |io|
+ File.open dest, 'wb' do |io|
Marshal.dump specs_index, io
end
end
diff --git a/lib/rubygems/install_default_message.rb b/lib/rubygems/install_default_message.rb
index dc73fd962b..052ef528e1 100644
--- a/lib/rubygems/install_default_message.rb
+++ b/lib/rubygems/install_default_message.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'rubygems'
-require 'rubygems/user_interaction'
+require_relative '../rubygems'
+require_relative 'user_interaction'
##
# A post-install hook that displays "Successfully installed
@@ -10,4 +10,3 @@ Gem.post_install do |installer|
ui = Gem::DefaultUserInteraction.ui
ui.say "Successfully installed #{installer.spec.full_name} as a default gem"
end
-
diff --git a/lib/rubygems/install_message.rb b/lib/rubygems/install_message.rb
index 6880db583e..861ead3770 100644
--- a/lib/rubygems/install_message.rb
+++ b/lib/rubygems/install_message.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'rubygems'
-require 'rubygems/user_interaction'
+require_relative '../rubygems'
+require_relative 'user_interaction'
##
# A default post-install hook that displays "Successfully installed
@@ -10,4 +10,3 @@ Gem.post_install do |installer|
ui = Gem::DefaultUserInteraction.ui
ui.say "Successfully installed #{installer.spec.full_name}"
end
-
diff --git a/lib/rubygems/install_update_options.rb b/lib/rubygems/install_update_options.rb
index 190372739b..d890c526bc 100644
--- a/lib/rubygems/install_update_options.rb
+++ b/lib/rubygems/install_update_options.rb
@@ -5,8 +5,8 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems'
-require 'rubygems/security_option'
+require_relative '../rubygems'
+require_relative 'security_option'
##
# Mixin methods for install and update options for Gem::Commands
@@ -25,12 +25,12 @@ module Gem::InstallUpdateOptions
end
add_option(:"Install/Update", '-n', '--bindir DIR',
- 'Directory where binary files are',
- 'located') do |value, options|
+ 'Directory where executables will be',
+ 'placed when the gem is installed') do |value, options|
options[:bin_dir] = File.expand_path(value)
end
- add_option(:"Install/Update", '--[no-]document [TYPES]', Array,
+ add_option(:"Install/Update", '--document [TYPES]', Array,
'Generate documentation for installed gems',
'List the documentation types you wish to',
'generate. For example: rdoc,ri') do |value, options|
@@ -50,8 +50,8 @@ module Gem::InstallUpdateOptions
add_option(:"Install/Update", '--vendor',
'Install gem into the vendor directory.',
'Only for use by gem repackagers.') do |value, options|
- unless Gem.vendor_dir then
- raise OptionParser::InvalidOption.new 'your platform is not supported'
+ unless Gem.vendor_dir
+ raise Gem::OptionParser::InvalidOption.new 'your platform is not supported'
end
options[:vendor] = true
@@ -63,30 +63,6 @@ module Gem::InstallUpdateOptions
options[:document] = []
end
- add_option(:Deprecated, '--[no-]rdoc',
- 'Generate RDoc for installed gems',
- 'Use --document instead') do |value, options|
- if value then
- options[:document] << 'rdoc'
- else
- options[:document].delete 'rdoc'
- end
-
- options[:document].uniq!
- end
-
- add_option(:Deprecated, '--[no-]ri',
- 'Generate ri data for installed gems.',
- 'Use --document instead') do |value, options|
- if value then
- options[:document] << 'ri'
- else
- options[:document].delete 'ri'
- end
-
- options[:document].uniq!
- end
-
add_option(:"Install/Update", '-E', '--[no-]env-shebang',
"Rewrite the shebang line on installed",
"scripts to use /usr/bin/env") do |value, options|
@@ -112,7 +88,7 @@ module Gem::InstallUpdateOptions
options[:ignore_dependencies] = value
end
- add_option(:"Install/Update", '--[no-]format-executable',
+ add_option(:"Install/Update", '--[no-]format-executable',
'Make installed executable names match Ruby.',
'If Ruby is ruby18, foo_exec will be',
'foo_exec18') do |value, options|
@@ -146,10 +122,10 @@ module Gem::InstallUpdateOptions
options[:minimal_deps] = true
end
- add_option(:"Install/Update", "--minimal-deps",
+ add_option(:"Install/Update", "--[no-]minimal-deps",
"Don't upgrade any dependencies that already",
"meet version requirements") do |value, options|
- options[:minimal_deps] = true
+ options[:minimal_deps] = value
end
add_option(:"Install/Update", "--[no-]post-install-message",
@@ -164,10 +140,10 @@ module Gem::InstallUpdateOptions
File.exist? file
end unless v
- unless v then
+ unless v
message = v ? v : "(tried #{Gem::GEM_DEP_FILES.join ', '})"
- raise OptionParser::InvalidArgument,
+ raise Gem::OptionParser::InvalidArgument,
"cannot find gem dependencies file #{message}"
end
@@ -178,7 +154,7 @@ module Gem::InstallUpdateOptions
'Omit the named groups (comma separated)',
'when installing from a gem dependencies',
'file') do |v,o|
- options[:without_groups].concat v.map { |without| without.intern }
+ options[:without_groups].concat v.map {|without| without.intern }
end
add_option(:"Install/Update", '--default',
@@ -202,7 +178,6 @@ module Gem::InstallUpdateOptions
'Suggest alternates when gems are not found') do |v,o|
options[:suggest_alternate] = v
end
-
end
##
@@ -213,4 +188,3 @@ module Gem::InstallUpdateOptions
end
end
-
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 0cbca0791b..8e3965ef92 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -5,12 +5,12 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems/command'
-require 'rubygems/exceptions'
-require 'rubygems/package'
-require 'rubygems/ext'
-require 'rubygems/user_interaction'
-require 'fileutils'
+require_relative 'installer_uninstaller_utils'
+require_relative 'exceptions'
+require_relative 'deprecate'
+require_relative 'package'
+require_relative 'ext'
+require_relative 'user_interaction'
##
# The installer installs the files contained in the .gem into the Gem.home.
@@ -26,12 +26,13 @@ require 'fileutils'
# file. See Gem.pre_install and Gem.post_install for details.
class Gem::Installer
+ extend Gem::Deprecate
##
# Paths where env(1) might live. Some systems are broken and have it in
# /bin
- ENV_PATHS = %w[/usr/bin/env /bin/env]
+ ENV_PATHS = %w[/usr/bin/env /bin/env].freeze
##
# Deprecated in favor of Gem::Ext::BuildError
@@ -40,10 +41,7 @@ class Gem::Installer
include Gem::UserInteraction
- ##
- # Filename of the gem being installed.
-
- attr_reader :gem
+ include Gem::InstallerUninstallerUtils
##
# The directory a gem's executables will be installed into
@@ -62,22 +60,35 @@ class Gem::Installer
attr_reader :options
- @path_warning = false
+ ##
+ # The gem package instance.
+
+ attr_reader :package
- @install_lock = Mutex.new
+ @path_warning = false
class << self
+ #
+ # Changes in rubygems to lazily loading `rubygems/command` (in order to
+ # lazily load `optparse` as a side effect) affect bundler's custom installer
+ # which uses `Gem::Command` without requiring it (up until bundler 2.2.29).
+ # This hook is to compensate for that missing require.
+ #
+ # TODO: Remove when rubygems no longer supports running on bundler older
+ # than 2.2.29.
- ##
- # True if we've warned about PATH not including Gem.bindir
+ def inherited(klass)
+ if klass.name == "Bundler::RubyGemsGemInstaller"
+ require "rubygems/command"
+ end
- attr_accessor :path_warning
+ super(klass)
+ end
##
- # Certain aspects of the install process are not thread-safe. This lock is
- # used to allow multiple threads to install Gems at the same time.
+ # True if we've warned about PATH not including Gem.bindir
- attr_reader :install_lock
+ attr_accessor :path_warning
##
# Overrides the executable format.
@@ -92,13 +103,12 @@ class Gem::Installer
def exec_format
@exec_format ||= Gem.default_exec_format
end
-
end
##
# Construct an installer object for the gem file located at +path+
- def self.at path, options = {}
+ def self.at(path, options = {})
security_policy = options[:security_policy]
package = Gem::Package.new path, security_policy
new package, options
@@ -107,22 +117,28 @@ class Gem::Installer
class FakePackage
attr_accessor :spec
+ attr_accessor :dir_mode
+ attr_accessor :prog_mode
+ attr_accessor :data_mode
+
def initialize(spec)
@spec = spec
end
- def extract_files destination_dir, pattern = '*'
+ def extract_files(destination_dir, pattern = '*')
FileUtils.mkdir_p destination_dir
spec.files.each do |file|
file = File.join destination_dir, file
next if File.exist? file
FileUtils.mkdir_p File.dirname(file)
- File.open file, 'w' do |fp| fp.puts "# #{file}" end
+ File.open file, 'w' do |fp|
+ fp.puts "# #{file}"
+ end
end
end
- def copy_to path
+ def copy_to(path)
end
end
@@ -130,7 +146,7 @@ class Gem::Installer
# Construct an installer object for an ephemeral gem (one where we don't
# actually have a .gem file, just a spec)
- def self.for_spec spec, options = {}
+ def self.for_spec(spec, options = {})
# FIXME: we should have a real Package class for this
new FakePackage.new(spec), options
end
@@ -164,21 +180,18 @@ class Gem::Installer
require 'fileutils'
@options = options
- if package.is_a? String
- security_policy = options[:security_policy]
- @package = Gem::Package.new package, security_policy
- if $VERBOSE
- warn "constructing an Installer object with a string is deprecated. Please use Gem::Installer.at (called from: #{caller.first})"
- end
- else
- @package = package
- end
+ @package = package
process_options
- if options[:user_install] and not options[:unpack] then
+ @package.dir_mode = options[:dir_mode]
+ @package.prog_mode = options[:prog_mode]
+ @package.data_mode = options[:data_mode]
+
+ if options[:user_install]
@gem_home = Gem.user_dir
@bin_dir = Gem.bindir gem_home unless options[:bin_dir]
+ @plugins_dir = Gem.plugindir(gem_home)
check_that_user_bin_dir_is_in_path
end
end
@@ -196,7 +209,7 @@ class Gem::Installer
#
# Otherwise +filename+ is overwritten.
- def check_executable_overwrite filename # :nodoc:
+ def check_executable_overwrite(filename) # :nodoc:
return if @force
generated_bin = File.join @bin_dir, formatted_program_filename(filename)
@@ -206,7 +219,7 @@ class Gem::Installer
ruby_executable = false
existing = nil
- open generated_bin, 'rb' do |io|
+ File.open generated_bin, 'rb' do |io|
next unless io.gets =~ /^#!/ # shebang
io.gets # blankline
@@ -232,7 +245,7 @@ class Gem::Installer
question = "#{spec.name}'s executable \"#{filename}\" conflicts with ".dup
- if ruby_executable then
+ if ruby_executable
question << (existing || 'an unknown executable')
return if ask_yes_no "#{question}\nOverwrite the executable?", false
@@ -280,12 +293,10 @@ class Gem::Installer
def install
pre_install_checks
- FileUtils.rm_f File.join gem_home, 'specifications', spec.spec_name
-
run_pre_install_hooks
# Set loaded_from to ensure extension_dir is correct
- if @options[:install_as_default] then
+ if @options[:install_as_default]
spec.loaded_from = default_spec_file
else
spec.loaded_from = spec_file
@@ -295,9 +306,10 @@ class Gem::Installer
FileUtils.rm_rf gem_dir
FileUtils.rm_rf spec.extension_dir
- FileUtils.mkdir_p gem_dir
+ dir_mode = options[:dir_mode]
+ FileUtils.mkdir_p gem_dir, :mode => dir_mode && 0755
- if @options[:install_as_default] then
+ if @options[:install_as_default]
extract_bin
write_default_spec
else
@@ -306,15 +318,21 @@ class Gem::Installer
build_extensions
write_build_info_file
run_post_build_hooks
+ end
+
+ generate_bin
+ generate_plugins
- generate_bin
+ unless @options[:install_as_default]
write_spec
write_cache_file
end
+ File.chmod(dir_mode, gem_dir) if dir_mode
+
say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil?
- Gem::Installer.install_lock.synchronize { Gem::Specification.reset }
+ Gem::Specification.reset
run_post_install_hooks
@@ -328,8 +346,8 @@ class Gem::Installer
def run_pre_install_hooks # :nodoc:
Gem.pre_install_hooks.each do |hook|
- if hook.call(self) == false then
- location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
+ if hook.call(self) == false
+ location = " at #{$1}" if hook.inspect =~ /[ @](.*:\d+)/
message = "pre-install hook#{location} failed for #{spec.full_name}"
raise Gem::InstallError, message
@@ -339,10 +357,10 @@ class Gem::Installer
def run_post_build_hooks # :nodoc:
Gem.post_build_hooks.each do |hook|
- if hook.call(self) == false then
+ if hook.call(self) == false
FileUtils.rm_rf gem_dir
- location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
+ location = " at #{$1}" if hook.inspect =~ /[ @](.*:\d+)/
message = "post-build hook#{location} failed for #{spec.full_name}"
raise Gem::InstallError, message
@@ -365,8 +383,8 @@ class Gem::Installer
@specs ||= begin
specs = []
- Dir[File.join(gem_home, "specifications", "*.gemspec")].each do |path|
- spec = Gem::Specification.load path.untaint
+ Gem::Util.glob_files_in_dir("*.gemspec", File.join(gem_home, "specifications")).each do |path|
+ spec = Gem::Specification.load path.tap(&Gem::UNTAINT)
specs << spec if spec
end
@@ -382,7 +400,7 @@ class Gem::Installer
# dependency :: Gem::Dependency
def ensure_dependency(spec, dependency)
- unless installation_satisfies_dependency? dependency then
+ unless installation_satisfies_dependency? dependency
raise Gem::InstallError, "#{spec.name} requires #{dependency}"
end
true
@@ -393,7 +411,7 @@ class Gem::Installer
def installation_satisfies_dependency?(dependency)
return true if @options[:development] and dependency.type == :development
- return true if installed_specs.detect { |s| dependency.matches_spec? s }
+ return true if installed_specs.detect {|s| dependency.matches_spec? s }
return false if @only_install_dir
not dependency.matching_specs.empty?
end
@@ -405,6 +423,7 @@ class Gem::Installer
@gem_dir = directory
extract_files
end
+ rubygems_deprecate :unpack
##
# The location of the spec file that is installed.
@@ -419,7 +438,7 @@ class Gem::Installer
#
def default_spec_file
- File.join Gem::Specification.default_specifications_dir, "#{spec.full_name}.gemspec"
+ File.join gem_home, "specifications", "default", "#{spec.full_name}.gemspec"
end
##
@@ -427,13 +446,9 @@ class Gem::Installer
# specifications directory.
def write_spec
- open spec_file, 'w' do |file|
- spec.installed_by_version = Gem.rubygems_version
-
- file.puts spec.to_ruby_for_cache
+ spec.installed_by_version = Gem.rubygems_version
- file.fsync rescue nil # for filesystems without fsync(2)
- end
+ Gem.write_binary(spec_file, spec.to_ruby_for_cache)
end
##
@@ -441,17 +456,15 @@ class Gem::Installer
# specifications/default directory.
def write_default_spec
- File.open(default_spec_file, "w") do |file|
- file.puts spec.to_ruby
- end
+ Gem.write_binary(default_spec_file, spec.to_ruby)
end
##
# Creates windows .bat files for easy running of commands
def generate_windows_script(filename, bindir)
- if Gem.win_platform? then
- script_name = filename + ".bat"
+ if Gem.win_platform?
+ script_name = formatted_program_filename(filename) + ".bat"
script_path = File.join bindir, File.basename(script_name)
File.open script_path, 'w' do |file|
file.puts windows_stub_script(bindir, filename)
@@ -464,30 +477,49 @@ class Gem::Installer
def generate_bin # :nodoc:
return if spec.executables.nil? or spec.executables.empty?
- Dir.mkdir @bin_dir unless File.exist? @bin_dir
- raise Gem::FilePermissionError.new(@bin_dir) unless File.writable? @bin_dir
+ ensure_writable_dir @bin_dir
spec.executables.each do |filename|
- filename.untaint
+ filename.tap(&Gem::UNTAINT)
bin_path = File.join gem_dir, spec.bindir, filename
- unless File.exist? bin_path then
- # TODO change this to a more useful warning
- warn "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?"
+ unless File.exist? bin_path
+ if File.symlink? bin_path
+ alert_warning "`#{bin_path}` is dangling symlink pointing to `#{File.readlink bin_path}`"
+ else
+ alert_warning "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?"
+ end
next
end
mode = File.stat(bin_path).mode
- FileUtils.chmod mode | 0111, bin_path unless (mode | 0111) == mode
+ dir_mode = options[:prog_mode] || (mode | 0111)
+
+ unless dir_mode == mode
+ require 'fileutils'
+ FileUtils.chmod dir_mode, bin_path
+ end
check_executable_overwrite filename
- if @wrappers then
+ if @wrappers
generate_bin_script filename, @bin_dir
else
generate_bin_symlink filename, @bin_dir
end
+ end
+ end
+
+ def generate_plugins # :nodoc:
+ latest = Gem::Specification.latest_spec_for(spec.name)
+ return if latest && latest.version > spec.version
+ ensure_writable_dir @plugins_dir
+
+ if spec.plugins.empty?
+ remove_plugins_for(spec, @plugins_dir)
+ else
+ regenerate_plugins_for(spec, @plugins_dir)
end
end
@@ -501,10 +533,12 @@ class Gem::Installer
def generate_bin_script(filename, bindir)
bin_script_path = File.join bindir, formatted_program_filename(filename)
+ require 'fileutils'
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
File.open bin_script_path, 'wb', 0755 do |file|
file.print app_script_text(filename)
+ file.chmod(options[:prog_mode] || 0755)
end
verbose bin_script_path
@@ -520,8 +554,8 @@ class Gem::Installer
src = File.join gem_dir, spec.bindir, filename
dst = File.join bindir, formatted_program_filename(filename)
- if File.exist? dst then
- if File.symlink? dst then
+ if File.exist? dst
+ if File.symlink? dst
link = File.readlink(dst).split File::SEPARATOR
cur_version = Gem::Version.create(link[-3].sub(/^.*-/, ''))
return if spec.version < cur_version
@@ -553,9 +587,9 @@ class Gem::Installer
def shebang(bin_file_name)
ruby_name = RbConfig::CONFIG['ruby_install_name'] if @env_shebang
path = File.join gem_dir, spec.bindir, bin_file_name
- first_line = File.open(path, "rb") {|file| file.gets}
+ first_line = File.open(path, "rb") {|file| file.gets } || ""
- if /\A#!/ =~ first_line then
+ if first_line.start_with?("#!")
# Preserve extra words on shebang line, like "-w". Thanks RPA.
shebang = first_line.sub(/\A\#!.*?ruby\S*((\s+\S+)+)/, "#!#{Gem.ruby}")
opts = $1
@@ -580,9 +614,9 @@ class Gem::Installer
end
"#!#{which}"
- elsif not ruby_name then
+ elsif not ruby_name
"#!#{Gem.ruby}#{opts}"
- elsif opts then
+ elsif opts
"#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
else
# Create a plain shebang line.
@@ -597,7 +631,7 @@ class Gem::Installer
def ensure_loadable_spec
ruby = spec.to_ruby_for_cache
- ruby.untaint
+ ruby.tap(&Gem::UNTAINT)
begin
eval ruby
@@ -607,27 +641,6 @@ class Gem::Installer
end
end
- def ensure_required_ruby_version_met # :nodoc:
- if rrv = spec.required_ruby_version then
- unless rrv.satisfied_by? Gem.ruby_version then
- ruby_version = Gem.ruby_api_version
- raise Gem::RuntimeRequirementNotMetError,
- "#{spec.name} requires Ruby version #{rrv}. The current ruby version is #{ruby_version}."
- end
- end
- end
-
- def ensure_required_rubygems_version_met # :nodoc:
- if rrgv = spec.required_rubygems_version then
- unless rrgv.satisfied_by? Gem.rubygems_version then
- rg_version = Gem::VERSION
- raise Gem::RuntimeRequirementNotMetError,
- "#{spec.name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " +
- "Try 'gem update --system' to update RubyGems itself."
- end
- end
- end
-
def ensure_dependencies_met # :nodoc:
deps = spec.runtime_dependencies
deps |= spec.development_dependencies if @development
@@ -643,13 +656,14 @@ class Gem::Installer
:env_shebang => false,
:force => false,
:only_install_dir => false,
- :post_install_message => true
+ :post_install_message => true,
}.merge options
@env_shebang = options[:env_shebang]
@force = options[:force]
@install_dir = options[:install_dir]
@gem_home = options[:install_dir] || Gem.dir
+ @plugins_dir = Gem.plugindir(@gem_home)
@ignore_dependencies = options[:ignore_dependencies]
@format_executable = options[:format_executable]
@wrappers = options[:wrappers]
@@ -662,49 +676,73 @@ class Gem::Installer
@development = options[:development]
@build_root = options[:build_root]
- @build_args = options[:build_args] || Gem::Command.build_args
+ @build_args = options[:build_args]
unless @build_root.nil?
- require 'pathname'
- @build_root = Pathname.new(@build_root).expand_path
- @bin_dir = File.join(@build_root, options[:bin_dir] || Gem.bindir(@gem_home))
- @gem_home = File.join(@build_root, @gem_home)
- alert_warning "You build with buildroot.\n Build root: #{@build_root}\n Bin dir: #{@bin_dir}\n Gem home: #{@gem_home}"
+ @bin_dir = File.join(@build_root, @bin_dir.gsub(/^[a-zA-Z]:/, ''))
+ @gem_home = File.join(@build_root, @gem_home.gsub(/^[a-zA-Z]:/, ''))
+ @plugins_dir = File.join(@build_root, @plugins_dir.gsub(/^[a-zA-Z]:/, ''))
+ alert_warning "You build with buildroot.\n Build root: #{@build_root}\n Bin dir: #{@bin_dir}\n Gem home: #{@gem_home}\n Plugins dir: #{@plugins_dir}"
end
end
def check_that_user_bin_dir_is_in_path # :nodoc:
+ return if self.class.path_warning
+
user_bin_dir = @bin_dir || Gem.bindir(gem_home)
- user_bin_dir = user_bin_dir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if
- File::ALT_SEPARATOR
+ user_bin_dir = user_bin_dir.tr(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
path = ENV['PATH']
- if Gem.win_platform? then
+ path = path.tr(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
+
+ if Gem.win_platform?
path = path.downcase
user_bin_dir = user_bin_dir.downcase
end
path = path.split(File::PATH_SEPARATOR)
- unless path.include? user_bin_dir then
+ unless path.include? user_bin_dir
unless !Gem.win_platform? && (path.include? user_bin_dir.sub(ENV['HOME'], '~'))
- unless self.class.path_warning then
- alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
- self.class.path_warning = true
- end
+ alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
+ self.class.path_warning = true
end
end
end
- def verify_gem_home(unpack = false) # :nodoc:
- FileUtils.mkdir_p gem_home
- raise Gem::FilePermissionError, gem_home unless
- unpack or File.writable?(gem_home)
+ def verify_gem_home # :nodoc:
+ FileUtils.mkdir_p gem_home, :mode => options[:dir_mode] && 0755
+ raise Gem::FilePermissionError, gem_home unless File.writable?(gem_home)
end
- def verify_spec_name
- return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN
- raise Gem::InstallError, "#{spec} has an invalid name"
+ def verify_spec
+ unless spec.name =~ Gem::Specification::VALID_NAME_PATTERN
+ raise Gem::InstallError, "#{spec} has an invalid name"
+ end
+
+ if spec.raw_require_paths.any?{|path| path =~ /\R/ }
+ raise Gem::InstallError, "#{spec} has an invalid require_paths"
+ end
+
+ if spec.extensions.any?{|ext| ext =~ /\R/ }
+ raise Gem::InstallError, "#{spec} has an invalid extensions"
+ end
+
+ if spec.platform.to_s =~ /\R/
+ raise Gem::InstallError, "#{spec.platform} is an invalid platform"
+ end
+
+ unless spec.specification_version.to_s =~ /\A\d+\z/
+ raise Gem::InstallError, "#{spec} has an invalid specification_version"
+ end
+
+ if spec.dependencies.any? {|dep| dep.type != :runtime && dep.type != :development }
+ raise Gem::InstallError, "#{spec} has an invalid dependencies"
+ end
+
+ if spec.dependencies.any? {|dep| dep.name =~ /(?:\R|[<>])/ }
+ raise Gem::InstallError, "#{spec} has an invalid dependencies"
+ end
end
##
@@ -723,14 +761,14 @@ class Gem::Installer
#
require 'rubygems'
-
-version = "#{Gem::Requirement.default}.a"
-
-if ARGV.first
- str = ARGV.first
- str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
- if str =~ /\\A_(.*)_\\z/ and Gem::Version.correct?($1) then
- version = $1
+#{gemdeps_load(spec.name)}
+version = "#{Gem::Requirement.default_prerelease}"
+
+str = ARGV.first
+if str
+ str = str.b[/\\A_(.*)_\\z/, 1]
+ if str and Gem::Version.correct?(str)
+ version = str
ARGV.shift
end
end
@@ -744,43 +782,62 @@ end
TEXT
end
+ def gemdeps_load(name)
+ return '' if name == "bundler"
+
+ <<-TEXT
+
+Gem.use_gemdeps
+TEXT
+ end
+
##
# return the stub script text used to launch the true Ruby script
def windows_stub_script(bindir, bin_file_name)
- ruby = Gem.ruby.gsub(/^\"|\"$/, "").tr(File::SEPARATOR, "\\")
- return <<-TEXT
+ rb_config = RbConfig::CONFIG
+ rb_topdir = RbConfig::TOPDIR || File.dirname(rb_config["bindir"])
+
+ # get ruby executable file name from RbConfig
+ ruby_exe = "#{rb_config['RUBY_INSTALL_NAME']}#{rb_config['EXEEXT']}"
+ ruby_exe = "ruby.exe" if ruby_exe.empty?
+
+ if File.exist?(File.join bindir, ruby_exe)
+ # stub & ruby.exe within same folder. Portable
+ <<-TEXT
@ECHO OFF
-IF NOT "%~f0" == "~f0" GOTO :WinNT
-@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
-GOTO :EOF
-:WinNT
-@"#{ruby}" "%~dpn0" %*
-TEXT
+@"%~dp0#{ruby_exe}" "%~dpn0" %*
+ TEXT
+ elsif bindir.downcase.start_with? rb_topdir.downcase
+ # stub within ruby folder, but not standard bin. Portable
+ require 'pathname'
+ from = Pathname.new bindir
+ to = Pathname.new "#{rb_topdir}/bin"
+ rel = to.relative_path_from from
+ <<-TEXT
+@ECHO OFF
+@"%~dp0#{rel}/#{ruby_exe}" "%~dpn0" %*
+ TEXT
+ else
+ # outside ruby folder, maybe -user-install or bundler. Portable, but ruby
+ # is dependent on PATH
+ <<-TEXT
+@ECHO OFF
+@#{ruby_exe} "%~dpn0" %*
+ TEXT
+ end
end
-
##
# Builds extensions. Valid types of extensions are extconf.rb files,
# configure scripts and rakefiles or mkrf_conf files.
def build_extensions
- builder = Gem::Ext::Builder.new spec, @build_args
+ builder = Gem::Ext::Builder.new spec, build_args
builder.build_extensions
end
##
- # Logs the build +output+ in +build_dir+, then raises Gem::Ext::BuildError.
- #
- # TODO: Delete this for RubyGems 3. It remains for API compatibility
-
- def extension_build_error(build_dir, output, backtrace = nil) # :nodoc:
- builder = Gem::Ext::Builder.new spec, @build_args
-
- builder.build_error build_dir, output, backtrace
- end
-
- ##
# Reads the file index and extracts each file into the gem directory.
#
# Ensures that files can't be installed outside the gem directory.
@@ -795,14 +852,14 @@ TEXT
# without the full gem installed.
def extract_bin
- @package.extract_files gem_dir, "bin/*"
+ @package.extract_files gem_dir, "#{spec.bindir}/*"
end
##
# Prefix and suffix the program filename the same as ruby.
def formatted_program_filename(filename)
- if @format_executable then
+ if @format_executable
self.class.exec_format % File.basename(filename)
else
filename
@@ -820,6 +877,13 @@ TEXT
end
##
+ # Filename of the gem being installed.
+
+ def gem
+ @package.gem.path
+ end
+
+ ##
# Performs various checks before installing the gem such as the install
# repository is writable and its directories exist, required Ruby and
# rubygems versions are met and that dependencies are installed.
@@ -829,11 +893,13 @@ TEXT
# The dependent check will be skipped if the install is ignoring dependencies.
def pre_install_checks
- verify_gem_home options[:unpack]
+ verify_gem_home
- ensure_loadable_spec
+ # The name and require_paths must be verified first, since it could contain
+ # ruby code that would be eval'ed in #ensure_loadable_spec
+ verify_spec
- verify_spec_name
+ ensure_loadable_spec
if options[:install_as_default]
Gem.ensure_default_gem_subdirectories gem_home
@@ -843,8 +909,6 @@ TEXT
return true if @force
- ensure_required_ruby_version_met
- ensure_required_rubygems_version_met
ensure_dependencies_met unless @ignore_dependencies
true
@@ -855,19 +919,22 @@ TEXT
# extensions.
def write_build_info_file
- return if @build_args.empty?
+ return if build_args.empty?
build_info_dir = File.join gem_home, 'build_info'
- FileUtils.mkdir_p build_info_dir
+ dir_mode = options[:dir_mode]
+ FileUtils.mkdir_p build_info_dir, :mode => dir_mode && 0755
build_info_file = File.join build_info_dir, "#{spec.full_name}.info"
- open build_info_file, 'w' do |io|
- @build_args.each do |arg|
+ File.open build_info_file, 'w' do |io|
+ build_args.each do |arg|
io.puts arg
end
end
+
+ File.chmod(dir_mode, build_info_dir) if dir_mode
end
##
@@ -878,4 +945,22 @@ TEXT
@package.copy_to cache_file
end
+ def ensure_writable_dir(dir) # :nodoc:
+ begin
+ Dir.mkdir dir, *[options[:dir_mode] && 0755].compact
+ rescue SystemCallError
+ raise unless File.directory? dir
+ end
+
+ raise Gem::FilePermissionError.new(dir) unless File.writable? dir
+ end
+
+ private
+
+ def build_args
+ @build_args ||= begin
+ require_relative "command"
+ Gem::Command.build_args
+ end
+ end
end
diff --git a/lib/rubygems/installer_test_case.rb b/lib/rubygems/installer_test_case.rb
deleted file mode 100644
index 4cec5da3f4..0000000000
--- a/lib/rubygems/installer_test_case.rb
+++ /dev/null
@@ -1,199 +0,0 @@
-# frozen_string_literal: true
-require 'rubygems/test_case'
-require 'rubygems/installer'
-require 'rubygems/deprecate'
-
-class Gem::Installer
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :bin_dir
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :build_args
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :gem_dir
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :force
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :format
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :gem_home
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :env_shebang
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :ignore_dependencies
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :format_executable
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :security_policy
-
- ##
- # Available through requiring rubygems/installer_test_case
-
- attr_writer :wrappers
-end
-
-##
-# A test case for Gem::Installer.
-
-class Gem::InstallerTestCase < Gem::TestCase
-
- ##
- # Creates the following instance variables:
- #
- # @spec::
- # a spec named 'a', intended for regular installs
- # @user_spec::
- # a spec named 'b', intended for user installs
- #
- # @gem::
- # the path to a built gem from @spec
- # @user_spec::
- # the path to a built gem from @user_spec
- #
- # @installer::
- # a Gem::Installer for the @spec that installs into @gemhome
- # @user_installer::
- # a Gem::Installer for the @user_spec that installs into Gem.user_dir
-
- def setup
- super
-
- @spec = quick_gem 'a' do |spec|
- util_make_exec spec
- end
-
- @user_spec = quick_gem 'b' do |spec|
- util_make_exec spec
- end
-
- util_build_gem @spec
- util_build_gem @user_spec
-
- @gem = @spec.cache_file
- @user_gem = @user_spec.cache_file
-
- @installer = util_installer @spec, @gemhome
- @user_installer = util_installer @user_spec, Gem.user_dir, :user
-
- Gem::Installer.path_warning = false
- end
-
- def util_gem_bindir spec = @spec # :nodoc:
- spec.bin_dir
- end
-
- def util_gem_dir spec = @spec # :nodoc:
- spec.gem_dir
- end
-
- extend Gem::Deprecate
- deprecate :util_gem_bindir, "@spec.bin_dir", 2016, 10
- deprecate :util_gem_dir, "@spec.gem_dir", 2016, 10
-
- ##
- # The path where installed executables live
-
- def util_inst_bindir
- File.join @gemhome, "bin"
- end
-
- ##
- # Adds an executable named "executable" to +spec+ with the given +shebang+.
- #
- # The executable is also written to the bin dir in @tmpdir and the installed
- # gem directory for +spec+.
-
- def util_make_exec(spec = @spec, shebang = "#!/usr/bin/ruby")
- spec.executables = %w[executable]
- spec.files << 'bin/executable'
-
- exec_path = spec.bin_file "executable"
- write_file exec_path do |io|
- io.puts shebang
- end
-
- bin_path = File.join @tempdir, "bin", "executable"
- write_file bin_path do |io|
- io.puts shebang
- end
- end
-
- ##
- # Builds the @spec gem and returns an installer for it. The built gem
- # includes:
- #
- # bin/executable
- # lib/code.rb
- # ext/a/mkrf_conf.rb
-
- def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic
- @spec.files << File.join('lib', 'code.rb')
- @spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb')
-
- Dir.chdir @tempdir do
- FileUtils.mkdir_p 'bin'
- FileUtils.mkdir_p 'lib'
- FileUtils.mkdir_p File.join('ext', 'a')
- File.open File.join('bin', 'executable'), 'w' do |f|
- f.puts "raise 'ran executable'"
- end
- File.open File.join('lib', 'code.rb'), 'w' do |f| f.puts '1' end
- File.open File.join('ext', 'a', 'mkrf_conf.rb'), 'w' do |f|
- f << <<-EOF
- File.open 'Rakefile', 'w' do |rf| rf.puts "task :default" end
- EOF
- end
-
- yield @spec if block_given?
-
- use_ui ui do
- FileUtils.rm_f @gem
-
- @gem = Gem::Package.build @spec
- end
- end
-
- @installer = Gem::Installer.at @gem
- end
-
- ##
- # Creates an installer for +spec+ that will install into +gem_home+. If
- # +user+ is true a user-install will be performed.
-
- def util_installer(spec, gem_home, user=false)
- Gem::Installer.at(spec.cache_file,
- :install_dir => gem_home,
- :user_install => user)
- end
-
-end
-
diff --git a/lib/rubygems/installer_uninstaller_utils.rb b/lib/rubygems/installer_uninstaller_utils.rb
new file mode 100644
index 0000000000..2c8b7c635e
--- /dev/null
+++ b/lib/rubygems/installer_uninstaller_utils.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+##
+# Helper methods for both Gem::Installer and Gem::Uninstaller
+
+module Gem::InstallerUninstallerUtils
+
+ def regenerate_plugins_for(spec, plugins_dir)
+ plugins = spec.plugins
+ return if plugins.empty?
+
+ require 'pathname'
+
+ spec.plugins.each do |plugin|
+ plugin_script_path = File.join plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}"
+
+ File.open plugin_script_path, 'wb' do |file|
+ file.puts "require_relative '#{Pathname.new(plugin).relative_path_from(Pathname.new(plugins_dir))}'"
+ end
+
+ verbose plugin_script_path
+ end
+ end
+
+ def remove_plugins_for(spec, plugins_dir)
+ FileUtils.rm_f Gem::Util.glob_files_in_dir("#{spec.name}#{Gem.plugin_suffix_pattern}", plugins_dir)
+ end
+
+end
diff --git a/lib/rubygems/local_remote_options.rb b/lib/rubygems/local_remote_options.rb
index 597b87ea03..0b8b0ee1a6 100644
--- a/lib/rubygems/local_remote_options.rb
+++ b/lib/rubygems/local_remote_options.rb
@@ -6,7 +6,7 @@
#++
require 'uri'
-require 'rubygems'
+require_relative '../rubygems'
##
# Mixin methods for local and remote Gem::Command options.
@@ -14,18 +14,20 @@ require 'rubygems'
module Gem::LocalRemoteOptions
##
- # Allows OptionParser to handle HTTP URIs.
+ # Allows Gem::OptionParser to handle HTTP URIs.
def accept_uri_http
- OptionParser.accept URI::HTTP do |value|
+ Gem::OptionParser.accept URI::HTTP do |value|
begin
uri = URI.parse value
rescue URI::InvalidURIError
- raise OptionParser::InvalidArgument, value
+ raise Gem::OptionParser::InvalidArgument, value
end
- unless ['http', 'https', 'file', 's3'].include?(uri.scheme)
- raise OptionParser::InvalidArgument, value
+ valid_uri_schemes = ["http", "https", "file", "s3"]
+ unless valid_uri_schemes.include?(uri.scheme)
+ msg = "Invalid uri scheme for #{value}\nPreface URLs with one of #{valid_uri_schemes.map{|s| "#{s}://" }}"
+ raise ArgumentError, msg
end
value
@@ -106,7 +108,7 @@ module Gem::LocalRemoteOptions
source << '/' if source !~ /\/\z/
- if options.delete :sources_cleared then
+ if options.delete :sources_cleared
Gem.sources = [source]
else
Gem.sources << source unless Gem.sources.include?(source)
@@ -146,4 +148,3 @@ module Gem::LocalRemoteOptions
end
end
-
diff --git a/lib/rubygems/mock_gem_ui.rb b/lib/rubygems/mock_gem_ui.rb
index 0223f8c35d..914ecb9a71 100644
--- a/lib/rubygems/mock_gem_ui.rb
+++ b/lib/rubygems/mock_gem_ui.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require 'stringio'
-require 'rubygems/user_interaction'
+require_relative 'user_interaction'
##
# This Gem::StreamUI subclass records input and output to StringIO for
@@ -11,17 +10,15 @@ class Gem::MockGemUi < Gem::StreamUI
# Raised when you haven't provided enough input to your MockGemUi
class InputEOFError < RuntimeError
-
- def initialize question
+ def initialize(question)
super "Out of input for MockGemUi on #{question.inspect}"
end
-
end
class TermError < RuntimeError
attr_reader :exit_code
- def initialize exit_code
+ def initialize(exit_code)
super
@exit_code = exit_code
end
@@ -43,6 +40,7 @@ class Gem::MockGemUi < Gem::StreamUI
end
def initialize(input = "")
+ require 'stringio'
ins = StringIO.new input
outs = StringIO.new
errs = StringIO.new
@@ -56,7 +54,7 @@ class Gem::MockGemUi < Gem::StreamUI
@terminated = false
end
- def ask question
+ def ask(question)
raise InputEOFError, question if @ins.eof?
super
@@ -84,6 +82,4 @@ class Gem::MockGemUi < Gem::StreamUI
raise TermError, status if status != 0
raise SystemExitException
end
-
end
-
diff --git a/lib/rubygems/name_tuple.rb b/lib/rubygems/name_tuple.rb
index 316329a0bd..3d0afa3094 100644
--- a/lib/rubygems/name_tuple.rb
+++ b/lib/rubygems/name_tuple.rb
@@ -4,8 +4,6 @@
# Represents a gem of name +name+ at +version+ of +platform+. These
# wrap the data returned from the indexes.
-require 'rubygems/platform'
-
class Gem::NameTuple
def initialize(name, version, platform="ruby")
@name = name
@@ -24,16 +22,16 @@ class Gem::NameTuple
# Turn an array of [name, version, platform] into an array of
# NameTuple objects.
- def self.from_list list
- list.map { |t| new(*t) }
+ def self.from_list(list)
+ list.map {|t| new(*t) }
end
##
# Turn an array of NameTuple objects back into an array of
# [name, version, platform] tuples.
- def self.to_basic list
- list.map { |t| t.to_a }
+ def self.to_basic(list)
+ list.map {|t| t.to_a }
end
##
@@ -54,14 +52,14 @@ class Gem::NameTuple
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{@platform}"
- end.dup.untaint
+ end.dup.tap(&Gem::UNTAINT)
end
##
# Indicate if this NameTuple matches the current platform.
def match_platform?
- Gem::Platform.match @platform
+ Gem::Platform.match_gem? @platform, @name
end
##
@@ -90,7 +88,7 @@ class Gem::NameTuple
alias to_s inspect # :nodoc:
- def <=> other
+ def <=>(other)
[@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1] <=>
[other.name, other.version,
other.platform == Gem::Platform::RUBY ? -1 : 1]
@@ -102,7 +100,7 @@ class Gem::NameTuple
# Compare with +other+. Supports another NameTuple or an Array
# in the [name, version, platform] format.
- def == other
+ def ==(other)
case other
when self.class
@name == other.name and
@@ -120,5 +118,4 @@ class Gem::NameTuple
def hash
to_a.hash
end
-
end
diff --git a/lib/rubygems/openssl.rb b/lib/rubygems/openssl.rb
new file mode 100644
index 0000000000..c44f619c4c
--- /dev/null
+++ b/lib/rubygems/openssl.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+autoload :OpenSSL, "openssl"
+
+module Gem
+ HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
+end
diff --git a/lib/rubygems/optparse.rb b/lib/rubygems/optparse.rb
new file mode 100644
index 0000000000..65be9f6b74
--- /dev/null
+++ b/lib/rubygems/optparse.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+require_relative 'optparse/lib/optparse'
diff --git a/lib/rubygems/optparse/.document b/lib/rubygems/optparse/.document
new file mode 100644
index 0000000000..0c43bbd6b3
--- /dev/null
+++ b/lib/rubygems/optparse/.document
@@ -0,0 +1 @@
+# Vendored files do not need to be documented
diff --git a/lib/rubygems/optparse/COPYING b/lib/rubygems/optparse/COPYING
new file mode 100644
index 0000000000..48e5a96de7
--- /dev/null
+++ b/lib/rubygems/optparse/COPYING
@@ -0,0 +1,56 @@
+Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
+You can redistribute it and/or modify it under either the terms of the
+2-clause BSDL (see the file BSDL), or the conditions below:
+
+1. You may make and give away verbatim copies of the source form of the
+ software without restriction, provided that you duplicate all of the
+ original copyright notices and associated disclaimers.
+
+2. You may modify your copy of the software in any way, provided that
+ you do at least ONE of the following:
+
+ a. place your modifications in the Public Domain or otherwise
+ make them Freely Available, such as by posting said
+ modifications to Usenet or an equivalent medium, or by allowing
+ the author to include your modifications in the software.
+
+ b. use the modified software only within your corporation or
+ organization.
+
+ c. give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
+
+ d. make other distribution arrangements with the author.
+
+3. You may distribute the software in object code or binary form,
+ provided that you do at least ONE of the following:
+
+ a. distribute the binaries and library files of the software,
+ together with instructions (in the manual page or equivalent)
+ on where to get the original distribution.
+
+ b. accompany the distribution with the machine-readable source of
+ the software.
+
+ c. give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
+
+ d. make other distribution arrangements with the author.
+
+4. You may modify and include the part of the software into any other
+ software (possibly commercial). But some files in the distribution
+ are not written by the author, so that they are not under these terms.
+
+ For the list of those files and their copying conditions, see the
+ file LEGAL.
+
+5. The scripts and library files supplied as input to or produced as
+ output from the software do not automatically fall under the
+ copyright of the software, but belong to whomever generated them,
+ and may be sold commercially, and may be aggregated with this
+ software.
+
+6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE.
diff --git a/lib/rubygems/optparse/lib/optionparser.rb b/lib/rubygems/optparse/lib/optionparser.rb
new file mode 100644
index 0000000000..4b9b40d82a
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optionparser.rb
@@ -0,0 +1,2 @@
+# frozen_string_literal: false
+require_relative 'optparse'
diff --git a/lib/rubygems/optparse/lib/optparse.rb b/lib/rubygems/optparse/lib/optparse.rb
new file mode 100644
index 0000000000..e4b1c61f79
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse.rb
@@ -0,0 +1,2230 @@
+# frozen_string_literal: true
+#
+# optparse.rb - command-line option analysis with the Gem::OptionParser class.
+#
+# Author:: Nobu Nakada
+# Documentation:: Nobu Nakada and Gavin Sinclair.
+#
+# See Gem::OptionParser for documentation.
+#
+
+
+#--
+# == Developer Documentation (not for RDoc output)
+#
+# === Class tree
+#
+# - Gem::OptionParser:: front end
+# - Gem::OptionParser::Switch:: each switches
+# - Gem::OptionParser::List:: options list
+# - Gem::OptionParser::ParseError:: errors on parsing
+# - Gem::OptionParser::AmbiguousOption
+# - Gem::OptionParser::NeedlessArgument
+# - Gem::OptionParser::MissingArgument
+# - Gem::OptionParser::InvalidOption
+# - Gem::OptionParser::InvalidArgument
+# - Gem::OptionParser::AmbiguousArgument
+#
+# === Object relationship diagram
+#
+# +--------------+
+# | Gem::OptionParser |<>-----+
+# +--------------+ | +--------+
+# | ,-| Switch |
+# on_head -------->+---------------+ / +--------+
+# accept/reject -->| List |<|>-
+# | |<|>- +----------+
+# on ------------->+---------------+ `-| argument |
+# : : | class |
+# +---------------+ |==========|
+# on_tail -------->| | |pattern |
+# +---------------+ |----------|
+# Gem::OptionParser.accept ->| DefaultList | |converter |
+# reject |(shared between| +----------+
+# | all instances)|
+# +---------------+
+#
+#++
+#
+# == Gem::OptionParser
+#
+# === New to \Gem::OptionParser?
+#
+# See the {Tutorial}[./doc/optparse/tutorial_rdoc.html].
+#
+# === Introduction
+#
+# Gem::OptionParser is a class for command-line option analysis. It is much more
+# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented
+# solution.
+#
+# === Features
+#
+# 1. The argument specification and the code to handle it are written in the
+# same place.
+# 2. It can output an option summary; you don't need to maintain this string
+# separately.
+# 3. Optional and mandatory arguments are specified very gracefully.
+# 4. Arguments can be automatically converted to a specified class.
+# 5. Arguments can be restricted to a certain set.
+#
+# All of these features are demonstrated in the examples below. See
+# #make_switch for full documentation.
+#
+# === Minimal example
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# options = {}
+# Gem::OptionParser.new do |parser|
+# parser.banner = "Usage: example.rb [options]"
+#
+# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
+# options[:verbose] = v
+# end
+# end.parse!
+#
+# p options
+# p ARGV
+#
+# === Generating Help
+#
+# Gem::OptionParser can be used to automatically generate help for the commands you
+# write:
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# Options = Struct.new(:name)
+#
+# class Parser
+# def self.parse(options)
+# args = Options.new("world")
+#
+# opt_parser = Gem::OptionParser.new do |parser|
+# parser.banner = "Usage: example.rb [options]"
+#
+# parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
+# args.name = n
+# end
+#
+# parser.on("-h", "--help", "Prints this help") do
+# puts parser
+# exit
+# end
+# end
+#
+# opt_parser.parse!(options)
+# return args
+# end
+# end
+# options = Parser.parse %w[--help]
+#
+# #=>
+# # Usage: example.rb [options]
+# # -n, --name=NAME Name to say hello to
+# # -h, --help Prints this help
+#
+# === Required Arguments
+#
+# For options that require an argument, option specification strings may include an
+# option name in all caps. If an option is used without the required argument,
+# an exception will be raised.
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# options = {}
+# Gem::OptionParser.new do |parser|
+# parser.on("-r", "--require LIBRARY",
+# "Require the LIBRARY before executing your script") do |lib|
+# puts "You required #{lib}!"
+# end
+# end.parse!
+#
+# Used:
+#
+# $ ruby optparse-test.rb -r
+# optparse-test.rb:9:in `<main>': missing argument: -r (Gem::OptionParser::MissingArgument)
+# $ ruby optparse-test.rb -r my-library
+# You required my-library!
+#
+# === Type Coercion
+#
+# Gem::OptionParser supports the ability to coerce command line arguments
+# into objects for us.
+#
+# Gem::OptionParser comes with a few ready-to-use kinds of type
+# coercion. They are:
+#
+# - Date -- Anything accepted by +Date.parse+
+# - DateTime -- Anything accepted by +DateTime.parse+
+# - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+
+# - URI -- Anything accepted by +URI.parse+
+# - Shellwords -- Anything accepted by +Shellwords.shellwords+
+# - String -- Any non-empty string
+# - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040)
+# - Float -- Any float. (e.g. 10, 3.14, -100E+13)
+# - Numeric -- Any integer, float, or rational (1, 3.4, 1/3)
+# - DecimalInteger -- Like +Integer+, but no octal format.
+# - OctalInteger -- Like +Integer+, but no decimal format.
+# - DecimalNumeric -- Decimal integer or float.
+# - TrueClass -- Accepts '+, yes, true, -, no, false' and
+# defaults as +true+
+# - FalseClass -- Same as +TrueClass+, but defaults to +false+
+# - Array -- Strings separated by ',' (e.g. 1,2,3)
+# - Regexp -- Regular expressions. Also includes options.
+#
+# We can also add our own coercions, which we will cover below.
+#
+# ==== Using Built-in Conversions
+#
+# As an example, the built-in +Time+ conversion is used. The other built-in
+# conversions behave in the same way.
+# Gem::OptionParser will attempt to parse the argument
+# as a +Time+. If it succeeds, that time will be passed to the
+# handler block. Otherwise, an exception will be raised.
+#
+# require 'rubygems/optparse/lib/optparse'
+# require 'rubygems/optparse/lib/optparse/time'
+# Gem::OptionParser.new do |parser|
+# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
+# p time
+# end
+# end.parse!
+#
+# Used:
+#
+# $ ruby optparse-test.rb -t nonsense
+# ... invalid argument: -t nonsense (Gem::OptionParser::InvalidArgument)
+# $ ruby optparse-test.rb -t 10-11-12
+# 2010-11-12 00:00:00 -0500
+# $ ruby optparse-test.rb -t 9:30
+# 2014-08-13 09:30:00 -0400
+#
+# ==== Creating Custom Conversions
+#
+# The +accept+ method on Gem::OptionParser may be used to create converters.
+# It specifies which conversion block to call whenever a class is specified.
+# The example below uses it to fetch a +User+ object before the +on+ handler receives it.
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# User = Struct.new(:id, :name)
+#
+# def find_user id
+# not_found = ->{ raise "No User Found for id #{id}" }
+# [ User.new(1, "Sam"),
+# User.new(2, "Gandalf") ].find(not_found) do |u|
+# u.id == id
+# end
+# end
+#
+# op = Gem::OptionParser.new
+# op.accept(User) do |user_id|
+# find_user user_id.to_i
+# end
+#
+# op.on("--user ID", User) do |user|
+# puts user
+# end
+#
+# op.parse!
+#
+# Used:
+#
+# $ ruby optparse-test.rb --user 1
+# #<struct User id=1, name="Sam">
+# $ ruby optparse-test.rb --user 2
+# #<struct User id=2, name="Gandalf">
+# $ ruby optparse-test.rb --user 3
+# optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
+#
+# === Store options to a Hash
+#
+# The +into+ option of +order+, +parse+ and so on methods stores command line options into a Hash.
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# options = {}
+# Gem::OptionParser.new do |parser|
+# parser.on('-a')
+# parser.on('-b NUM', Integer)
+# parser.on('-v', '--verbose')
+# end.parse!(into: options)
+#
+# p options
+#
+# Used:
+#
+# $ ruby optparse-test.rb -a
+# {:a=>true}
+# $ ruby optparse-test.rb -a -v
+# {:a=>true, :verbose=>true}
+# $ ruby optparse-test.rb -a -b 100
+# {:a=>true, :b=>100}
+#
+# === Complete example
+#
+# The following example is a complete Ruby program. You can run it and see the
+# effect of specifying various options. This is probably the best way to learn
+# the features of +optparse+.
+#
+# require 'rubygems/optparse/lib/optparse'
+# require 'rubygems/optparse/lib/optparse/time'
+# require 'ostruct'
+# require 'pp'
+#
+# class OptparseExample
+# Version = '1.0.0'
+#
+# CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
+# CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
+#
+# class ScriptOptions
+# attr_accessor :library, :inplace, :encoding, :transfer_type,
+# :verbose, :extension, :delay, :time, :record_separator,
+# :list
+#
+# def initialize
+# self.library = []
+# self.inplace = false
+# self.encoding = "utf8"
+# self.transfer_type = :auto
+# self.verbose = false
+# end
+#
+# def define_options(parser)
+# parser.banner = "Usage: example.rb [options]"
+# parser.separator ""
+# parser.separator "Specific options:"
+#
+# # add additional options
+# perform_inplace_option(parser)
+# delay_execution_option(parser)
+# execute_at_time_option(parser)
+# specify_record_separator_option(parser)
+# list_example_option(parser)
+# specify_encoding_option(parser)
+# optional_option_argument_with_keyword_completion_option(parser)
+# boolean_verbose_option(parser)
+#
+# parser.separator ""
+# parser.separator "Common options:"
+# # No argument, shows at tail. This will print an options summary.
+# # Try it and see!
+# parser.on_tail("-h", "--help", "Show this message") do
+# puts parser
+# exit
+# end
+# # Another typical switch to print the version.
+# parser.on_tail("--version", "Show version") do
+# puts Version
+# exit
+# end
+# end
+#
+# def perform_inplace_option(parser)
+# # Specifies an optional option argument
+# parser.on("-i", "--inplace [EXTENSION]",
+# "Edit ARGV files in place",
+# "(make backup if EXTENSION supplied)") do |ext|
+# self.inplace = true
+# self.extension = ext || ''
+# self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
+# end
+# end
+#
+# def delay_execution_option(parser)
+# # Cast 'delay' argument to a Float.
+# parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
+# self.delay = n
+# end
+# end
+#
+# def execute_at_time_option(parser)
+# # Cast 'time' argument to a Time object.
+# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
+# self.time = time
+# end
+# end
+#
+# def specify_record_separator_option(parser)
+# # Cast to octal integer.
+# parser.on("-F", "--irs [OCTAL]", Gem::OptionParser::OctalInteger,
+# "Specify record separator (default \\0)") do |rs|
+# self.record_separator = rs
+# end
+# end
+#
+# def list_example_option(parser)
+# # List of arguments.
+# parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
+# self.list = list
+# end
+# end
+#
+# def specify_encoding_option(parser)
+# # Keyword completion. We are specifying a specific set of arguments (CODES
+# # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
+# # the shortest unambiguous text.
+# code_list = (CODE_ALIASES.keys + CODES).join(', ')
+# parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
+# "(#{code_list})") do |encoding|
+# self.encoding = encoding
+# end
+# end
+#
+# def optional_option_argument_with_keyword_completion_option(parser)
+# # Optional '--type' option argument with keyword completion.
+# parser.on("--type [TYPE]", [:text, :binary, :auto],
+# "Select transfer type (text, binary, auto)") do |t|
+# self.transfer_type = t
+# end
+# end
+#
+# def boolean_verbose_option(parser)
+# # Boolean switch.
+# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
+# self.verbose = v
+# end
+# end
+# end
+#
+# #
+# # Return a structure describing the options.
+# #
+# def parse(args)
+# # The options specified on the command line will be collected in
+# # *options*.
+#
+# @options = ScriptOptions.new
+# @args = Gem::OptionParser.new do |parser|
+# @options.define_options(parser)
+# parser.parse!(args)
+# end
+# @options
+# end
+#
+# attr_reader :parser, :options
+# end # class OptparseExample
+#
+# example = OptparseExample.new
+# options = example.parse(ARGV)
+# pp options # example.options
+# pp ARGV
+#
+# === Shell Completion
+#
+# For modern shells (e.g. bash, zsh, etc.), you can use shell
+# completion for command line options.
+#
+# === Further documentation
+#
+# The above examples, along with the accompanying
+# {Tutorial}[./doc/optparse/tutorial_rdoc.html],
+# should be enough to learn how to use this class.
+# If you have any questions, file a ticket at http://bugs.ruby-lang.org.
+#
+class Gem::OptionParser
+ Gem::OptionParser::Version = "0.2.0"
+
+ # :stopdoc:
+ NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
+ RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
+ OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze
+ # :startdoc:
+
+ #
+ # Keyword completion module. This allows partial arguments to be specified
+ # and resolved against a list of acceptable values.
+ #
+ module Completion
+ def self.regexp(key, icase)
+ Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), icase)
+ end
+
+ def self.candidate(key, icase = false, pat = nil, &block)
+ pat ||= Completion.regexp(key, icase)
+ candidates = []
+ block.call do |k, *v|
+ (if Regexp === k
+ kn = ""
+ k === key
+ else
+ kn = defined?(k.id2name) ? k.id2name : k
+ pat === kn
+ end) or next
+ v << k if v.empty?
+ candidates << [k, v, kn]
+ end
+ candidates
+ end
+
+ def candidate(key, icase = false, pat = nil)
+ Completion.candidate(key, icase, pat, &method(:each))
+ end
+
+ public
+ def complete(key, icase = false, pat = nil)
+ candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}
+ if candidates.size == 1
+ canon, sw, * = candidates[0]
+ elsif candidates.size > 1
+ canon, sw, cn = candidates.shift
+ candidates.each do |k, v, kn|
+ next if sw == v
+ if String === cn and String === kn
+ if cn.rindex(kn, 0)
+ canon, sw, cn = k, v, kn
+ next
+ elsif kn.rindex(cn, 0)
+ next
+ end
+ end
+ throw :ambiguous, key
+ end
+ end
+ if canon
+ block_given? or return key, *sw
+ yield(key, *sw)
+ end
+ end
+
+ def convert(opt = nil, val = nil, *)
+ val
+ end
+ end
+
+
+ #
+ # Map from option/keyword string to object with completion.
+ #
+ class OptionMap < Hash
+ include Completion
+ end
+
+
+ #
+ # Individual switch class. Not important to the user.
+ #
+ # Defined within Switch are several Switch-derived classes: NoArgument,
+ # RequiredArgument, etc.
+ #
+ class Switch
+ attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block
+
+ #
+ # Guesses argument style from +arg+. Returns corresponding
+ # Gem::OptionParser::Switch class (OptionalArgument, etc.).
+ #
+ def self.guess(arg)
+ case arg
+ when ""
+ t = self
+ when /\A=?\[/
+ t = Switch::OptionalArgument
+ when /\A\s+\[/
+ t = Switch::PlacedArgument
+ else
+ t = Switch::RequiredArgument
+ end
+ self >= t or incompatible_argument_styles(arg, t)
+ t
+ end
+
+ def self.incompatible_argument_styles(arg, t)
+ raise(ArgumentError, "#{arg}: incompatible argument styles\n #{self}, #{t}",
+ ParseError.filter_backtrace(caller(2)))
+ end
+
+ def self.pattern
+ NilClass
+ end
+
+ def initialize(pattern = nil, conv = nil,
+ short = nil, long = nil, arg = nil,
+ desc = ([] if short or long), block = nil, &_block)
+ raise if Array === pattern
+ block ||= _block
+ @pattern, @conv, @short, @long, @arg, @desc, @block =
+ pattern, conv, short, long, arg, desc, block
+ end
+
+ #
+ # Parses +arg+ and returns rest of +arg+ and matched portion to the
+ # argument pattern. Yields when the pattern doesn't match substring.
+ #
+ def parse_arg(arg) # :nodoc:
+ pattern or return nil, [arg]
+ unless m = pattern.match(arg)
+ yield(InvalidArgument, arg)
+ return arg, []
+ end
+ if String === m
+ m = [s = m]
+ else
+ m = m.to_a
+ s = m[0]
+ return nil, m unless String === s
+ end
+ raise InvalidArgument, arg unless arg.rindex(s, 0)
+ return nil, m if s.length == arg.length
+ yield(InvalidArgument, arg) # didn't match whole arg
+ return arg[s.length..-1], m
+ end
+ private :parse_arg
+
+ #
+ # Parses argument, converts and returns +arg+, +block+ and result of
+ # conversion. Yields at semi-error condition instead of raising an
+ # exception.
+ #
+ def conv_arg(arg, val = []) # :nodoc:
+ if conv
+ val = conv.call(*val)
+ else
+ val = proc {|v| v}.call(*val)
+ end
+ return arg, block, val
+ end
+ private :conv_arg
+
+ #
+ # Produces the summary text. Each line of the summary is yielded to the
+ # block (without newline).
+ #
+ # +sdone+:: Already summarized short style options keyed hash.
+ # +ldone+:: Already summarized long style options keyed hash.
+ # +width+:: Width of left side (option part). In other words, the right
+ # side (description part) starts after +width+ columns.
+ # +max+:: Maximum width of left side -> the options are filled within
+ # +max+ columns.
+ # +indent+:: Prefix string indents all summarized lines.
+ #
+ def summarize(sdone = {}, ldone = {}, width = 1, max = width - 1, indent = "")
+ sopts, lopts = [], [], nil
+ @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
+ @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
+ return if sopts.empty? and lopts.empty? # completely hidden
+
+ left = [sopts.join(', ')]
+ right = desc.dup
+
+ while s = lopts.shift
+ l = left[-1].length + s.length
+ l += arg.length if left.size == 1 && arg
+ l < max or sopts.empty? or left << +''
+ left[-1] << (left[-1].empty? ? ' ' * 4 : ', ') << s
+ end
+
+ if arg
+ left[0] << (left[1] ? arg.sub(/\A(\[?)=/, '\1') + ',' : arg)
+ end
+ mlen = left.collect {|ss| ss.length}.max.to_i
+ while mlen > width and l = left.shift
+ mlen = left.collect {|ss| ss.length}.max.to_i if l.length == mlen
+ if l.length < width and (r = right[0]) and !r.empty?
+ l = l.to_s.ljust(width) + ' ' + r
+ right.shift
+ end
+ yield(indent + l)
+ end
+
+ while begin l = left.shift; r = right.shift; l or r end
+ l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?
+ yield(indent + l)
+ end
+
+ self
+ end
+
+ def add_banner(to) # :nodoc:
+ unless @short or @long
+ s = desc.join
+ to << " [" + s + "]..." unless s.empty?
+ end
+ to
+ end
+
+ def match_nonswitch?(str) # :nodoc:
+ @pattern =~ str unless @short or @long
+ end
+
+ #
+ # Main name of the switch.
+ #
+ def switch_name
+ (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
+ end
+
+ def compsys(sdone, ldone) # :nodoc:
+ sopts, lopts = [], []
+ @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
+ @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
+ return if sopts.empty? and lopts.empty? # completely hidden
+
+ (sopts+lopts).each do |opt|
+ # "(-x -c -r)-l[left justify]"
+ if /^--\[no-\](.+)$/ =~ opt
+ o = $1
+ yield("--#{o}", desc.join(""))
+ yield("--no-#{o}", desc.join(""))
+ else
+ yield("#{opt}", desc.join(""))
+ end
+ end
+ end
+
+ #
+ # Switch that takes no arguments.
+ #
+ class NoArgument < self
+
+ #
+ # Raises an exception if any arguments given.
+ #
+ def parse(arg, argv)
+ yield(NeedlessArgument, arg) if arg
+ conv_arg(arg)
+ end
+
+ def self.incompatible_argument_styles(*)
+ end
+
+ def self.pattern
+ Object
+ end
+ end
+
+ #
+ # Switch that takes an argument.
+ #
+ class RequiredArgument < self
+
+ #
+ # Raises an exception if argument is not present.
+ #
+ def parse(arg, argv)
+ unless arg
+ raise MissingArgument if argv.empty?
+ arg = argv.shift
+ end
+ conv_arg(*parse_arg(arg, &method(:raise)))
+ end
+ end
+
+ #
+ # Switch that can omit argument.
+ #
+ class OptionalArgument < self
+
+ #
+ # Parses argument if given, or uses default value.
+ #
+ def parse(arg, argv, &error)
+ if arg
+ conv_arg(*parse_arg(arg, &error))
+ else
+ conv_arg(arg)
+ end
+ end
+ end
+
+ #
+ # Switch that takes an argument, which does not begin with '-'.
+ #
+ class PlacedArgument < self
+
+ #
+ # Returns nil if argument is not present or begins with '-'.
+ #
+ def parse(arg, argv, &error)
+ if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
+ return nil, block, nil
+ end
+ opt = (val = parse_arg(val, &error))[1]
+ val = conv_arg(*val)
+ if opt and !arg
+ argv.shift
+ else
+ val[0] = nil
+ end
+ val
+ end
+ end
+ end
+
+ #
+ # Simple option list providing mapping from short and/or long option
+ # string to Gem::OptionParser::Switch and mapping from acceptable argument to
+ # matching pattern and converter pair. Also provides summary feature.
+ #
+ class List
+ # Map from acceptable argument types to pattern and converter pairs.
+ attr_reader :atype
+
+ # Map from short style option switches to actual switch objects.
+ attr_reader :short
+
+ # Map from long style option switches to actual switch objects.
+ attr_reader :long
+
+ # List of all switches and summary string.
+ attr_reader :list
+
+ #
+ # Just initializes all instance variables.
+ #
+ def initialize
+ @atype = {}
+ @short = OptionMap.new
+ @long = OptionMap.new
+ @list = []
+ end
+
+ #
+ # See Gem::OptionParser.accept.
+ #
+ def accept(t, pat = /.*/m, &block)
+ if pat
+ pat.respond_to?(:match) or
+ raise TypeError, "has no `match'", ParseError.filter_backtrace(caller(2))
+ else
+ pat = t if t.respond_to?(:match)
+ end
+ unless block
+ block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
+ end
+ @atype[t] = [pat, block]
+ end
+
+ #
+ # See Gem::OptionParser.reject.
+ #
+ def reject(t)
+ @atype.delete(t)
+ end
+
+ #
+ # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.
+ #
+ # +sw+:: Gem::OptionParser::Switch instance to be added.
+ # +sopts+:: Short style option list.
+ # +lopts+:: Long style option list.
+ # +nlopts+:: Negated long style options list.
+ #
+ def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
+ sopts.each {|o| @short[o] = sw} if sopts
+ lopts.each {|o| @long[o] = sw} if lopts
+ nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
+ used = @short.invert.update(@long.invert)
+ @list.delete_if {|o| Switch === o and !used[o]}
+ end
+ private :update
+
+ #
+ # Inserts +switch+ at the head of the list, and associates short, long
+ # and negated long options. Arguments are:
+ #
+ # +switch+:: Gem::OptionParser::Switch instance to be inserted.
+ # +short_opts+:: List of short style options.
+ # +long_opts+:: List of long style options.
+ # +nolong_opts+:: List of long style options with "no-" prefix.
+ #
+ # prepend(switch, short_opts, long_opts, nolong_opts)
+ #
+ def prepend(*args)
+ update(*args)
+ @list.unshift(args[0])
+ end
+
+ #
+ # Appends +switch+ at the tail of the list, and associates short, long
+ # and negated long options. Arguments are:
+ #
+ # +switch+:: Gem::OptionParser::Switch instance to be inserted.
+ # +short_opts+:: List of short style options.
+ # +long_opts+:: List of long style options.
+ # +nolong_opts+:: List of long style options with "no-" prefix.
+ #
+ # append(switch, short_opts, long_opts, nolong_opts)
+ #
+ def append(*args)
+ update(*args)
+ @list.push(args[0])
+ end
+
+ #
+ # Searches +key+ in +id+ list. The result is returned or yielded if a
+ # block is given. If it isn't found, nil is returned.
+ #
+ def search(id, key)
+ if list = __send__(id)
+ val = list.fetch(key) {return nil}
+ block_given? ? yield(val) : val
+ end
+ end
+
+ #
+ # Searches list +id+ for +opt+ and the optional patterns for completion
+ # +pat+. If +icase+ is true, the search is case insensitive. The result
+ # is returned or yielded if a block is given. If it isn't found, nil is
+ # returned.
+ #
+ def complete(id, opt, icase = false, *pat, &block)
+ __send__(id).complete(opt, icase, *pat, &block)
+ end
+
+ def get_candidates(id)
+ yield __send__(id).keys
+ end
+
+ #
+ # Iterates over each option, passing the option to the +block+.
+ #
+ def each_option(&block)
+ list.each(&block)
+ end
+
+ #
+ # Creates the summary table, passing each line to the +block+ (without
+ # newline). The arguments +args+ are passed along to the summarize
+ # method which is called on every option.
+ #
+ def summarize(*args, &block)
+ sum = []
+ list.reverse_each do |opt|
+ if opt.respond_to?(:summarize) # perhaps Gem::OptionParser::Switch
+ s = []
+ opt.summarize(*args) {|l| s << l}
+ sum.concat(s.reverse)
+ elsif !opt or opt.empty?
+ sum << ""
+ elsif opt.respond_to?(:each_line)
+ sum.concat([*opt.each_line].reverse)
+ else
+ sum.concat([*opt.each].reverse)
+ end
+ end
+ sum.reverse_each(&block)
+ end
+
+ def add_banner(to) # :nodoc:
+ list.each do |opt|
+ if opt.respond_to?(:add_banner)
+ opt.add_banner(to)
+ end
+ end
+ to
+ end
+
+ def compsys(*args, &block) # :nodoc:
+ list.each do |opt|
+ if opt.respond_to?(:compsys)
+ opt.compsys(*args, &block)
+ end
+ end
+ end
+ end
+
+ #
+ # Hash with completion search feature. See Gem::OptionParser::Completion.
+ #
+ class CompletingHash < Hash
+ include Completion
+
+ #
+ # Completion for hash key.
+ #
+ def match(key)
+ *values = fetch(key) {
+ raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}
+ }
+ return key, *values
+ end
+ end
+
+ # :stopdoc:
+
+ #
+ # Enumeration of acceptable argument styles. Possible values are:
+ #
+ # NO_ARGUMENT:: The switch takes no arguments. (:NONE)
+ # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)
+ # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)
+ #
+ # Use like --switch=argument (long style) or -Xargument (short style). For
+ # short style, only portion matched to argument pattern is treated as
+ # argument.
+ #
+ ArgumentStyle = {}
+ NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}
+ RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}
+ OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}
+ ArgumentStyle.freeze
+
+ #
+ # Switches common used such as '--', and also provides default
+ # argument classes
+ #
+ DefaultList = List.new
+ DefaultList.short['-'] = Switch::NoArgument.new {}
+ DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}
+
+
+ COMPSYS_HEADER = <<'XXX' # :nodoc:
+
+typeset -A opt_args
+local context state line
+
+_arguments -s -S \
+XXX
+
+ def compsys(to, name = File.basename($0)) # :nodoc:
+ to << "#compdef #{name}\n"
+ to << COMPSYS_HEADER
+ visit(:compsys, {}, {}) {|o, d|
+ to << %Q[ "#{o}[#{d.gsub(/[\"\[\]]/, '\\\\\&')}]" \\\n]
+ }
+ to << " '*:file:_files' && return 0\n"
+ end
+
+ #
+ # Default options for ARGV, which never appear in option summary.
+ #
+ Officious = {}
+
+ #
+ # --help
+ # Shows option summary.
+ #
+ Officious['help'] = proc do |parser|
+ Switch::NoArgument.new do |arg|
+ puts parser.help
+ exit
+ end
+ end
+
+ #
+ # --*-completion-bash=WORD
+ # Shows candidates for command line completion.
+ #
+ Officious['*-completion-bash'] = proc do |parser|
+ Switch::RequiredArgument.new do |arg|
+ puts parser.candidate(arg)
+ exit
+ end
+ end
+
+ #
+ # --*-completion-zsh[=NAME:FILE]
+ # Creates zsh completion file.
+ #
+ Officious['*-completion-zsh'] = proc do |parser|
+ Switch::OptionalArgument.new do |arg|
+ parser.compsys(STDOUT, arg)
+ exit
+ end
+ end
+
+ #
+ # --version
+ # Shows version string if Version is defined.
+ #
+ Officious['version'] = proc do |parser|
+ Switch::OptionalArgument.new do |pkg|
+ if pkg
+ begin
+ require 'rubygems/optparse/lib/optparse/version'
+ rescue LoadError
+ else
+ show_version(*pkg.split(/,/)) or
+ abort("#{parser.program_name}: no version found in package #{pkg}")
+ exit
+ end
+ end
+ v = parser.ver or abort("#{parser.program_name}: version unknown")
+ puts v
+ exit
+ end
+ end
+
+ # :startdoc:
+
+ #
+ # Class methods
+ #
+
+ #
+ # Initializes a new instance and evaluates the optional block in context
+ # of the instance. Arguments +args+ are passed to #new, see there for
+ # description of parameters.
+ #
+ # This method is *deprecated*, its behavior corresponds to the older #new
+ # method.
+ #
+ def self.with(*args, &block)
+ opts = new(*args)
+ opts.instance_eval(&block)
+ opts
+ end
+
+ #
+ # Returns an incremented value of +default+ according to +arg+.
+ #
+ def self.inc(arg, default = nil)
+ case arg
+ when Integer
+ arg.nonzero?
+ when nil
+ default.to_i + 1
+ end
+ end
+ def inc(*args)
+ self.class.inc(*args)
+ end
+
+ #
+ # Initializes the instance and yields itself if called with a block.
+ #
+ # +banner+:: Banner message.
+ # +width+:: Summary width.
+ # +indent+:: Summary indent.
+ #
+ def initialize(banner = nil, width = 32, indent = ' ' * 4)
+ @stack = [DefaultList, List.new, List.new]
+ @program_name = nil
+ @banner = banner
+ @summary_width = width
+ @summary_indent = indent
+ @default_argv = ARGV
+ @require_exact = false
+ add_officious
+ yield self if block_given?
+ end
+
+ def add_officious # :nodoc:
+ list = base()
+ Officious.each do |opt, block|
+ list.long[opt] ||= block.call(self)
+ end
+ end
+
+ #
+ # Terminates option parsing. Optional parameter +arg+ is a string pushed
+ # back to be the first non-option argument.
+ #
+ def terminate(arg = nil)
+ self.class.terminate(arg)
+ end
+ def self.terminate(arg = nil)
+ throw :terminate, arg
+ end
+
+ @stack = [DefaultList]
+ def self.top() DefaultList end
+
+ #
+ # Directs to accept specified class +t+. The argument string is passed to
+ # the block in which it should be converted to the desired class.
+ #
+ # +t+:: Argument class specifier, any object including Class.
+ # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.
+ #
+ # accept(t, pat, &block)
+ #
+ def accept(*args, &blk) top.accept(*args, &blk) end
+ #
+ # See #accept.
+ #
+ def self.accept(*args, &blk) top.accept(*args, &blk) end
+
+ #
+ # Directs to reject specified class argument.
+ #
+ # +t+:: Argument class specifier, any object including Class.
+ #
+ # reject(t)
+ #
+ def reject(*args, &blk) top.reject(*args, &blk) end
+ #
+ # See #reject.
+ #
+ def self.reject(*args, &blk) top.reject(*args, &blk) end
+
+ #
+ # Instance methods
+ #
+
+ # Heading banner preceding summary.
+ attr_writer :banner
+
+ # Program name to be emitted in error message and default banner,
+ # defaults to $0.
+ attr_writer :program_name
+
+ # Width for option list portion of summary. Must be Numeric.
+ attr_accessor :summary_width
+
+ # Indentation for summary. Must be String (or have + String method).
+ attr_accessor :summary_indent
+
+ # Strings to be parsed in default.
+ attr_accessor :default_argv
+
+ # Whether to require that options match exactly (disallows providing
+ # abbreviated long option as short option).
+ attr_accessor :require_exact
+
+ #
+ # Heading banner preceding summary.
+ #
+ def banner
+ unless @banner
+ @banner = +"Usage: #{program_name} [options]"
+ visit(:add_banner, @banner)
+ end
+ @banner
+ end
+
+ #
+ # Program name to be emitted in error message and default banner, defaults
+ # to $0.
+ #
+ def program_name
+ @program_name || File.basename($0, '.*')
+ end
+
+ # for experimental cascading :-)
+ alias set_banner banner=
+ alias set_program_name program_name=
+ alias set_summary_width summary_width=
+ alias set_summary_indent summary_indent=
+
+ # Version
+ attr_writer :version
+ # Release code
+ attr_writer :release
+
+ #
+ # Version
+ #
+ def version
+ (defined?(@version) && @version) || (defined?(::Version) && ::Version)
+ end
+
+ #
+ # Release code
+ #
+ def release
+ (defined?(@release) && @release) || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
+ end
+
+ #
+ # Returns version string from program_name, version and release.
+ #
+ def ver
+ if v = version
+ str = +"#{program_name} #{[v].join('.')}"
+ str << " (#{v})" if v = release
+ str
+ end
+ end
+
+ def warn(mesg = $!)
+ super("#{program_name}: #{mesg}")
+ end
+
+ def abort(mesg = $!)
+ super("#{program_name}: #{mesg}")
+ end
+
+ #
+ # Subject of #on / #on_head, #accept / #reject
+ #
+ def top
+ @stack[-1]
+ end
+
+ #
+ # Subject of #on_tail.
+ #
+ def base
+ @stack[1]
+ end
+
+ #
+ # Pushes a new List.
+ #
+ def new
+ @stack.push(List.new)
+ if block_given?
+ yield self
+ else
+ self
+ end
+ end
+
+ #
+ # Removes the last List.
+ #
+ def remove
+ @stack.pop
+ end
+
+ #
+ # Puts option summary into +to+ and returns +to+. Yields each line if
+ # a block is given.
+ #
+ # +to+:: Output destination, which must have method <<. Defaults to [].
+ # +width+:: Width of left side, defaults to @summary_width.
+ # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.
+ # +indent+:: Indentation, defaults to @summary_indent.
+ #
+ def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
+ nl = "\n"
+ blk ||= proc {|l| to << (l.index(nl, -1) ? l : l + nl)}
+ visit(:summarize, {}, {}, width, max, indent, &blk)
+ to
+ end
+
+ #
+ # Returns option summary string.
+ #
+ def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end
+ alias to_s help
+
+ #
+ # Returns option summary list.
+ #
+ def to_a; summarize("#{banner}".split(/^/)) end
+
+ #
+ # Checks if an argument is given twice, in which case an ArgumentError is
+ # raised. Called from Gem::OptionParser#switch only.
+ #
+ # +obj+:: New argument.
+ # +prv+:: Previously specified argument.
+ # +msg+:: Exception message.
+ #
+ def notwice(obj, prv, msg) # :nodoc:
+ unless !prv or prv == obj
+ raise(ArgumentError, "argument #{msg} given twice: #{obj}",
+ ParseError.filter_backtrace(caller(2)))
+ end
+ obj
+ end
+ private :notwice
+
+ SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc:
+
+ # :call-seq:
+ # make_switch(params, block = nil)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def make_switch(opts, block = nil)
+ short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
+ ldesc, sdesc, desc, arg = [], [], []
+ default_style = Switch::NoArgument
+ default_pattern = nil
+ klass = nil
+ q, a = nil
+ has_arg = false
+
+ opts.each do |o|
+ # argument class
+ next if search(:atype, o) do |pat, c|
+ klass = notwice(o, klass, 'type')
+ if not_style and not_style != Switch::NoArgument
+ not_pattern, not_conv = pat, c
+ else
+ default_pattern, conv = pat, c
+ end
+ end
+
+ # directly specified pattern(any object possible to match)
+ if (!(String === o || Symbol === o)) and o.respond_to?(:match)
+ pattern = notwice(o, pattern, 'pattern')
+ if pattern.respond_to?(:convert)
+ conv = pattern.method(:convert).to_proc
+ else
+ conv = SPLAT_PROC
+ end
+ next
+ end
+
+ # anything others
+ case o
+ when Proc, Method
+ block = notwice(o, block, 'block')
+ when Array, Hash
+ case pattern
+ when CompletingHash
+ when nil
+ pattern = CompletingHash.new
+ conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
+ else
+ raise ArgumentError, "argument pattern given twice"
+ end
+ o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}}
+ when Module
+ raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4))
+ when *ArgumentStyle.keys
+ style = notwice(ArgumentStyle[o], style, 'style')
+ when /^--no-([^\[\]=\s]*)(.+)?/
+ q, a = $1, $2
+ o = notwice(a ? Object : TrueClass, klass, 'type')
+ not_pattern, not_conv = search(:atype, o) unless not_style
+ not_style = (not_style || default_style).guess(arg = a) if a
+ default_style = Switch::NoArgument
+ default_pattern, conv = search(:atype, FalseClass) unless default_pattern
+ ldesc << "--no-#{q}"
+ (q = q.downcase).tr!('_', '-')
+ long << "no-#{q}"
+ nolong << q
+ when /^--\[no-\]([^\[\]=\s]*)(.+)?/
+ q, a = $1, $2
+ o = notwice(a ? Object : TrueClass, klass, 'type')
+ if a
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ end
+ ldesc << "--[no-]#{q}"
+ (o = q.downcase).tr!('_', '-')
+ long << o
+ not_pattern, not_conv = search(:atype, FalseClass) unless not_style
+ not_style = Switch::NoArgument
+ nolong << "no-#{o}"
+ when /^--([^\[\]=\s]*)(.+)?/
+ q, a = $1, $2
+ if a
+ o = notwice(NilClass, klass, 'type')
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ end
+ ldesc << "--#{q}"
+ (o = q.downcase).tr!('_', '-')
+ long << o
+ when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
+ q, a = $1, $2
+ o = notwice(Object, klass, 'type')
+ if a
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ else
+ has_arg = true
+ end
+ sdesc << "-#{q}"
+ short << Regexp.new(q)
+ when /^-(.)(.+)?/
+ q, a = $1, $2
+ if a
+ o = notwice(NilClass, klass, 'type')
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ end
+ sdesc << "-#{q}"
+ short << q
+ when /^=/
+ style = notwice(default_style.guess(arg = o), style, 'style')
+ default_pattern, conv = search(:atype, Object) unless default_pattern
+ else
+ desc.push(o)
+ end
+ end
+
+ default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
+ if !(short.empty? and long.empty?)
+ if has_arg and default_style == Switch::NoArgument
+ default_style = Switch::RequiredArgument
+ end
+ s = (style || default_style).new(pattern || default_pattern,
+ conv, sdesc, ldesc, arg, desc, block)
+ elsif !block
+ if style or pattern
+ raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller)
+ end
+ s = desc
+ else
+ short << pattern
+ s = (style || default_style).new(pattern,
+ conv, nil, nil, arg, desc, block)
+ end
+ return s, short, long,
+ (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
+ nolong
+ end
+
+ # :call-seq:
+ # define(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def define(*opts, &block)
+ top.append(*(sw = make_switch(opts, block)))
+ sw[0]
+ end
+
+ # :call-seq:
+ # on(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def on(*opts, &block)
+ define(*opts, &block)
+ self
+ end
+ alias def_option define
+
+ # :call-seq:
+ # define_head(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def define_head(*opts, &block)
+ top.prepend(*(sw = make_switch(opts, block)))
+ sw[0]
+ end
+
+ # :call-seq:
+ # on_head(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ # The new option is added at the head of the summary.
+ #
+ def on_head(*opts, &block)
+ define_head(*opts, &block)
+ self
+ end
+ alias def_head_option define_head
+
+ # :call-seq:
+ # define_tail(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def define_tail(*opts, &block)
+ base.append(*(sw = make_switch(opts, block)))
+ sw[0]
+ end
+
+ #
+ # :call-seq:
+ # on_tail(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ # The new option is added at the tail of the summary.
+ #
+ def on_tail(*opts, &block)
+ define_tail(*opts, &block)
+ self
+ end
+ alias def_tail_option define_tail
+
+ #
+ # Add separator in summary.
+ #
+ def separator(string)
+ top.append(string, nil, nil)
+ end
+
+ #
+ # Parses command line arguments +argv+ in order. When a block is given,
+ # each non-option argument is yielded. When optional +into+ keyword
+ # argument is provided, the parsed option values are stored there via
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
+ # similar object).
+ #
+ # Returns the rest of +argv+ left unparsed.
+ #
+ def order(*argv, into: nil, &nonopt)
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
+ order!(argv, into: into, &nonopt)
+ end
+
+ #
+ # Same as #order, but removes switches destructively.
+ # Non-option arguments remain in +argv+.
+ #
+ def order!(argv = default_argv, into: nil, &nonopt)
+ setter = ->(name, val) {into[name.to_sym] = val} if into
+ parse_in_order(argv, setter, &nonopt)
+ end
+
+ def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc:
+ opt, arg, val, rest = nil
+ nonopt ||= proc {|a| throw :terminate, a}
+ argv.unshift(arg) if arg = catch(:terminate) {
+ while arg = argv.shift
+ case arg
+ # long option
+ when /\A--([^=]*)(?:=(.*))?/m
+ opt, rest = $1, $2
+ opt.tr!('_', '-')
+ begin
+ sw, = complete(:long, opt, true)
+ if require_exact && !sw.long.include?(arg)
+ raise InvalidOption, arg
+ end
+ rescue ParseError
+ raise $!.set_option(arg, true)
+ end
+ begin
+ opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}
+ val = cb.call(val) if cb
+ setter.call(sw.switch_name, val) if setter
+ rescue ParseError
+ raise $!.set_option(arg, rest)
+ end
+
+ # short option
+ when /\A-(.)((=).*|.+)?/m
+ eq, rest, opt = $3, $2, $1
+ has_arg, val = eq, rest
+ begin
+ sw, = search(:short, opt)
+ unless sw
+ begin
+ sw, = complete(:short, opt)
+ # short option matched.
+ val = arg.delete_prefix('-')
+ has_arg = true
+ rescue InvalidOption
+ raise if require_exact
+ # if no short options match, try completion with long
+ # options.
+ sw, = complete(:long, opt)
+ eq ||= !rest
+ end
+ end
+ rescue ParseError
+ raise $!.set_option(arg, true)
+ end
+ begin
+ opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
+ rescue ParseError
+ raise $!.set_option(arg, arg.length > 2)
+ else
+ raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}"
+ end
+ begin
+ argv.unshift(opt) if opt and (!rest or (opt = opt.sub(/\A-*/, '-')) != '-')
+ val = cb.call(val) if cb
+ setter.call(sw.switch_name, val) if setter
+ rescue ParseError
+ raise $!.set_option(arg, arg.length > 2)
+ end
+
+ # non-option argument
+ else
+ catch(:prune) do
+ visit(:each_option) do |sw0|
+ sw = sw0
+ sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)
+ end
+ nonopt.call(arg)
+ end
+ end
+ end
+
+ nil
+ }
+
+ visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}
+
+ argv
+ end
+ private :parse_in_order
+
+ #
+ # Parses command line arguments +argv+ in permutation mode and returns
+ # list of non-option arguments. When optional +into+ keyword
+ # argument is provided, the parsed option values are stored there via
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
+ # similar object).
+ #
+ def permute(*argv, into: nil)
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
+ permute!(argv, into: into)
+ end
+
+ #
+ # Same as #permute, but removes switches destructively.
+ # Non-option arguments remain in +argv+.
+ #
+ def permute!(argv = default_argv, into: nil)
+ nonopts = []
+ order!(argv, into: into, &nonopts.method(:<<))
+ argv[0, 0] = nonopts
+ argv
+ end
+
+ #
+ # Parses command line arguments +argv+ in order when environment variable
+ # POSIXLY_CORRECT is set, and in permutation mode otherwise.
+ # When optional +into+ keyword argument is provided, the parsed option
+ # values are stored there via <code>[]=</code> method (so it can be Hash,
+ # or OpenStruct, or other similar object).
+ #
+ def parse(*argv, into: nil)
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
+ parse!(argv, into: into)
+ end
+
+ #
+ # Same as #parse, but removes switches destructively.
+ # Non-option arguments remain in +argv+.
+ #
+ def parse!(argv = default_argv, into: nil)
+ if ENV.include?('POSIXLY_CORRECT')
+ order!(argv, into: into)
+ else
+ permute!(argv, into: into)
+ end
+ end
+
+ #
+ # Wrapper method for getopts.rb.
+ #
+ # params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option")
+ # # params["a"] = true # -a
+ # # params["b"] = "1" # -b1
+ # # params["foo"] = "1" # --foo
+ # # params["bar"] = "x" # --bar x
+ # # params["zot"] = "z" # --zot Z
+ #
+ def getopts(*args)
+ argv = Array === args.first ? args.shift : default_argv
+ single_options, *long_options = *args
+
+ result = {}
+
+ single_options.scan(/(.)(:)?/) do |opt, val|
+ if val
+ result[opt] = nil
+ define("-#{opt} VAL")
+ else
+ result[opt] = false
+ define("-#{opt}")
+ end
+ end if single_options
+
+ long_options.each do |arg|
+ arg, desc = arg.split(';', 2)
+ opt, val = arg.split(':', 2)
+ if val
+ result[opt] = val.empty? ? nil : val
+ define("--#{opt}=#{result[opt] || "VAL"}", *[desc].compact)
+ else
+ result[opt] = false
+ define("--#{opt}", *[desc].compact)
+ end
+ end
+
+ parse_in_order(argv, result.method(:[]=))
+ result
+ end
+
+ #
+ # See #getopts.
+ #
+ def self.getopts(*args)
+ new.getopts(*args)
+ end
+
+ #
+ # Traverses @stack, sending each element method +id+ with +args+ and
+ # +block+.
+ #
+ def visit(id, *args, &block) # :nodoc:
+ @stack.reverse_each do |el|
+ el.__send__(id, *args, &block)
+ end
+ nil
+ end
+ private :visit
+
+ #
+ # Searches +key+ in @stack for +id+ hash and returns or yields the result.
+ #
+ def search(id, key) # :nodoc:
+ block_given = block_given?
+ visit(:search, id, key) do |k|
+ return block_given ? yield(k) : k
+ end
+ end
+ private :search
+
+ #
+ # Completes shortened long style option switch and returns pair of
+ # canonical switch and switch descriptor Gem::OptionParser::Switch.
+ #
+ # +typ+:: Searching table.
+ # +opt+:: Searching key.
+ # +icase+:: Search case insensitive if true.
+ # +pat+:: Optional pattern for completion.
+ #
+ def complete(typ, opt, icase = false, *pat) # :nodoc:
+ if pat.empty?
+ search(typ, opt) {|sw| return [sw, opt]} # exact match or...
+ end
+ ambiguous = catch(:ambiguous) {
+ visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
+ }
+ exc = ambiguous ? AmbiguousOption : InvalidOption
+ raise exc.new(opt, additional: self.method(:additional_message).curry[typ])
+ end
+ private :complete
+
+ #
+ # Returns additional info.
+ #
+ def additional_message(typ, opt)
+ return unless typ and opt and defined?(DidYouMean::SpellChecker)
+ all_candidates = []
+ visit(:get_candidates, typ) do |candidates|
+ all_candidates.concat(candidates)
+ end
+ all_candidates.select! {|cand| cand.is_a?(String) }
+ checker = DidYouMean::SpellChecker.new(dictionary: all_candidates)
+ suggestions = all_candidates & checker.correct(opt)
+ if DidYouMean.respond_to?(:formatter)
+ DidYouMean.formatter.message_for(suggestions)
+ else
+ "\nDid you mean? #{suggestions.join("\n ")}"
+ end
+ end
+
+ def candidate(word)
+ list = []
+ case word
+ when '-'
+ long = short = true
+ when /\A--/
+ word, arg = word.split(/=/, 2)
+ argpat = Completion.regexp(arg, false) if arg and !arg.empty?
+ long = true
+ when /\A-/
+ short = true
+ end
+ pat = Completion.regexp(word, long)
+ visit(:each_option) do |opt|
+ next unless Switch === opt
+ opts = (long ? opt.long : []) + (short ? opt.short : [])
+ opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat
+ if /\A=/ =~ opt.arg
+ opts.map! {|sw| sw + "="}
+ if arg and CompletingHash === opt.pattern
+ if opts = opt.pattern.candidate(arg, false, argpat)
+ opts.map!(&:last)
+ end
+ end
+ end
+ list.concat(opts)
+ end
+ list
+ end
+
+ #
+ # Loads options from file names as +filename+. Does nothing when the file
+ # is not present. Returns whether successfully loaded.
+ #
+ # +filename+ defaults to basename of the program without suffix in a
+ # directory ~/.options, then the basename with '.options' suffix
+ # under XDG and Haiku standard places.
+ #
+ def load(filename = nil)
+ unless filename
+ basename = File.basename($0, '.*')
+ return true if load(File.expand_path(basename, '~/.options')) rescue nil
+ basename << ".options"
+ return [
+ # XDG
+ ENV['XDG_CONFIG_HOME'],
+ '~/.config',
+ *ENV['XDG_CONFIG_DIRS']&.split(File::PATH_SEPARATOR),
+
+ # Haiku
+ '~/config/settings',
+ ].any? {|dir|
+ next if !dir or dir.empty?
+ load(File.expand_path(basename, dir)) rescue nil
+ }
+ end
+ begin
+ parse(*IO.readlines(filename).each {|s| s.chomp!})
+ true
+ rescue Errno::ENOENT, Errno::ENOTDIR
+ false
+ end
+ end
+
+ #
+ # Parses environment variable +env+ or its uppercase with splitting like a
+ # shell.
+ #
+ # +env+ defaults to the basename of the program.
+ #
+ def environment(env = File.basename($0, '.*'))
+ env = ENV[env] || ENV[env.upcase] or return
+ require 'shellwords'
+ parse(*Shellwords.shellwords(env))
+ end
+
+ #
+ # Acceptable argument classes
+ #
+
+ #
+ # Any string and no conversion. This is fall-back.
+ #
+ accept(Object) {|s,|s or s.nil?}
+
+ accept(NilClass) {|s,|s}
+
+ #
+ # Any non-empty string, and no conversion.
+ #
+ accept(String, /.+/m) {|s,*|s}
+
+ #
+ # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal
+ # for 0x, and decimal for others; with optional sign prefix. Converts to
+ # Integer.
+ #
+ decimal = '\d+(?:_\d+)*'
+ binary = 'b[01]+(?:_[01]+)*'
+ hex = 'x[\da-f]+(?:_[\da-f]+)*'
+ octal = "0(?:[0-7]+(?:_[0-7]+)*|#{binary}|#{hex})?"
+ integer = "#{octal}|#{decimal}"
+
+ accept(Integer, %r"\A[-+]?(?:#{integer})\z"io) {|s,|
+ begin
+ Integer(s)
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Float number format, and converts to Float.
+ #
+ float = "(?:#{decimal}(?=(.)?)(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?"
+ floatpat = %r"\A[-+]?#{float}\z"io
+ accept(Float, floatpat) {|s,| s.to_f if s}
+
+ #
+ # Generic numeric format, converts to Integer for integer format, Float
+ # for float format, and Rational for rational format.
+ #
+ real = "[-+]?(?:#{octal}|#{float})"
+ accept(Numeric, /\A(#{real})(?:\/(#{real}))?\z/io) {|s, d, f, n,|
+ if n
+ Rational(d, n)
+ elsif f
+ Float(s)
+ else
+ Integer(s)
+ end
+ }
+
+ #
+ # Decimal integer format, to be converted to Integer.
+ #
+ DecimalInteger = /\A[-+]?#{decimal}\z/io
+ accept(DecimalInteger, DecimalInteger) {|s,|
+ begin
+ Integer(s, 10)
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Ruby/C like octal/hexadecimal/binary integer format, to be converted to
+ # Integer.
+ #
+ OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))\z/io
+ accept(OctalInteger, OctalInteger) {|s,|
+ begin
+ Integer(s, 8)
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Decimal integer/float number format, to be converted to Integer for
+ # integer format, Float for float format.
+ #
+ DecimalNumeric = floatpat # decimal integer is allowed as float also.
+ accept(DecimalNumeric, floatpat) {|s, f|
+ begin
+ if f
+ Float(s)
+ else
+ Integer(s)
+ end
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Boolean switch, which means whether it is present or not, whether it is
+ # absent or not with prefix no-, or it takes an argument
+ # yes/no/true/false/+/-.
+ #
+ yesno = CompletingHash.new
+ %w[- no false].each {|el| yesno[el] = false}
+ %w[+ yes true].each {|el| yesno[el] = true}
+ yesno['nil'] = false # should be nil?
+ accept(TrueClass, yesno) {|arg, val| val == nil or val}
+ #
+ # Similar to TrueClass, but defaults to false.
+ #
+ accept(FalseClass, yesno) {|arg, val| val != nil and val}
+
+ #
+ # List of strings separated by ",".
+ #
+ accept(Array) do |s, |
+ if s
+ s = s.split(',').collect {|ss| ss unless ss.empty?}
+ end
+ s
+ end
+
+ #
+ # Regular expression with options.
+ #
+ accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o|
+ f = 0
+ if o
+ f |= Regexp::IGNORECASE if /i/ =~ o
+ f |= Regexp::MULTILINE if /m/ =~ o
+ f |= Regexp::EXTENDED if /x/ =~ o
+ k = o.delete("imx")
+ k = nil if k.empty?
+ end
+ Regexp.new(s || all, f, k)
+ end
+
+ #
+ # Exceptions
+ #
+
+ #
+ # Base class of exceptions from Gem::OptionParser.
+ #
+ class ParseError < RuntimeError
+ # Reason which caused the error.
+ Reason = 'parse error'
+
+ def initialize(*args, additional: nil)
+ @additional = additional
+ @arg0, = args
+ @args = args
+ @reason = nil
+ end
+
+ attr_reader :args
+ attr_writer :reason
+ attr_accessor :additional
+
+ #
+ # Pushes back erred argument(s) to +argv+.
+ #
+ def recover(argv)
+ argv[0, 0] = @args
+ argv
+ end
+
+ def self.filter_backtrace(array)
+ unless $DEBUG
+ array.delete_if(&%r"\A#{Regexp.quote(__FILE__)}:"o.method(:=~))
+ end
+ array
+ end
+
+ def set_backtrace(array)
+ super(self.class.filter_backtrace(array))
+ end
+
+ def set_option(opt, eq)
+ if eq
+ @args[0] = opt
+ else
+ @args.unshift(opt)
+ end
+ self
+ end
+
+ #
+ # Returns error reason. Override this for I18N.
+ #
+ def reason
+ @reason || self.class::Reason
+ end
+
+ def inspect
+ "#<#{self.class}: #{args.join(' ')}>"
+ end
+
+ #
+ # Default stringizing method to emit standard error message.
+ #
+ def message
+ "#{reason}: #{args.join(' ')}#{additional[@arg0] if additional}"
+ end
+
+ alias to_s message
+ end
+
+ #
+ # Raises when ambiguously completable string is encountered.
+ #
+ class AmbiguousOption < ParseError
+ const_set(:Reason, 'ambiguous option')
+ end
+
+ #
+ # Raises when there is an argument for a switch which takes no argument.
+ #
+ class NeedlessArgument < ParseError
+ const_set(:Reason, 'needless argument')
+ end
+
+ #
+ # Raises when a switch with mandatory argument has no argument.
+ #
+ class MissingArgument < ParseError
+ const_set(:Reason, 'missing argument')
+ end
+
+ #
+ # Raises when switch is undefined.
+ #
+ class InvalidOption < ParseError
+ const_set(:Reason, 'invalid option')
+ end
+
+ #
+ # Raises when the given argument does not match required format.
+ #
+ class InvalidArgument < ParseError
+ const_set(:Reason, 'invalid argument')
+ end
+
+ #
+ # Raises when the given argument word can't be completed uniquely.
+ #
+ class AmbiguousArgument < InvalidArgument
+ const_set(:Reason, 'ambiguous argument')
+ end
+
+ #
+ # Miscellaneous
+ #
+
+ #
+ # Extends command line arguments array (ARGV) to parse itself.
+ #
+ module Arguable
+
+ #
+ # Sets Gem::OptionParser object, when +opt+ is +false+ or +nil+, methods
+ # Gem::OptionParser::Arguable#options and Gem::OptionParser::Arguable#options= are
+ # undefined. Thus, there is no ways to access the Gem::OptionParser object
+ # via the receiver object.
+ #
+ def options=(opt)
+ unless @optparse = opt
+ class << self
+ undef_method(:options)
+ undef_method(:options=)
+ end
+ end
+ end
+
+ #
+ # Actual Gem::OptionParser object, automatically created if nonexistent.
+ #
+ # If called with a block, yields the Gem::OptionParser object and returns the
+ # result of the block. If an Gem::OptionParser::ParseError exception occurs
+ # in the block, it is rescued, a error message printed to STDERR and
+ # +nil+ returned.
+ #
+ def options
+ @optparse ||= Gem::OptionParser.new
+ @optparse.default_argv = self
+ block_given? or return @optparse
+ begin
+ yield @optparse
+ rescue ParseError
+ @optparse.warn $!
+ nil
+ end
+ end
+
+ #
+ # Parses +self+ destructively in order and returns +self+ containing the
+ # rest arguments left unparsed.
+ #
+ def order!(&blk) options.order!(self, &blk) end
+
+ #
+ # Parses +self+ destructively in permutation mode and returns +self+
+ # containing the rest arguments left unparsed.
+ #
+ def permute!() options.permute!(self) end
+
+ #
+ # Parses +self+ destructively and returns +self+ containing the
+ # rest arguments left unparsed.
+ #
+ def parse!() options.parse!(self) end
+
+ #
+ # Substitution of getopts is possible as follows. Also see
+ # Gem::OptionParser#getopts.
+ #
+ # def getopts(*args)
+ # ($OPT = ARGV.getopts(*args)).each do |opt, val|
+ # eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val"
+ # end
+ # rescue Gem::OptionParser::ParseError
+ # end
+ #
+ def getopts(*args)
+ options.getopts(self, *args)
+ end
+
+ #
+ # Initializes instance variable.
+ #
+ def self.extend_object(obj)
+ super
+ obj.instance_eval {@optparse = nil}
+ end
+ def initialize(*args)
+ super
+ @optparse = nil
+ end
+ end
+
+ #
+ # Acceptable argument classes. Now contains DecimalInteger, OctalInteger
+ # and DecimalNumeric. See Acceptable argument classes (in source code).
+ #
+ module Acceptables
+ const_set(:DecimalInteger, Gem::OptionParser::DecimalInteger)
+ const_set(:OctalInteger, Gem::OptionParser::OctalInteger)
+ const_set(:DecimalNumeric, Gem::OptionParser::DecimalNumeric)
+ end
+end
+
+# ARGV is arguable by Gem::OptionParser
+ARGV.extend(Gem::OptionParser::Arguable)
diff --git a/lib/rubygems/optparse/lib/optparse/ac.rb b/lib/rubygems/optparse/lib/optparse/ac.rb
new file mode 100644
index 0000000000..ff2f4c2dc3
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/ac.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: false
+require 'rubygems/optparse/lib/optparse'
+
+class Gem::OptionParser::AC < Gem::OptionParser
+ private
+
+ def _check_ac_args(name, block)
+ unless /\A\w[-\w]*\z/ =~ name
+ raise ArgumentError, name
+ end
+ unless block
+ raise ArgumentError, "no block given", ParseError.filter_backtrace(caller)
+ end
+ end
+
+ ARG_CONV = proc {|val| val.nil? ? true : val}
+
+ def _ac_arg_enable(prefix, name, help_string, block)
+ _check_ac_args(name, block)
+
+ sdesc = []
+ ldesc = ["--#{prefix}-#{name}"]
+ desc = [help_string]
+ q = name.downcase
+ ac_block = proc {|val| block.call(ARG_CONV.call(val))}
+ enable = Switch::PlacedArgument.new(nil, ARG_CONV, sdesc, ldesc, nil, desc, ac_block)
+ disable = Switch::NoArgument.new(nil, proc {false}, sdesc, ldesc, nil, desc, ac_block)
+ top.append(enable, [], ["enable-" + q], disable, ['disable-' + q])
+ enable
+ end
+
+ public
+
+ def ac_arg_enable(name, help_string, &block)
+ _ac_arg_enable("enable", name, help_string, block)
+ end
+
+ def ac_arg_disable(name, help_string, &block)
+ _ac_arg_enable("disable", name, help_string, block)
+ end
+
+ def ac_arg_with(name, help_string, &block)
+ _check_ac_args(name, block)
+
+ sdesc = []
+ ldesc = ["--with-#{name}"]
+ desc = [help_string]
+ q = name.downcase
+ with = Switch::PlacedArgument.new(*search(:atype, String), sdesc, ldesc, nil, desc, block)
+ without = Switch::NoArgument.new(nil, proc {}, sdesc, ldesc, nil, desc, block)
+ top.append(with, [], ["with-" + q], without, ['without-' + q])
+ with
+ end
+end
diff --git a/lib/rubygems/optparse/lib/optparse/date.rb b/lib/rubygems/optparse/lib/optparse/date.rb
new file mode 100644
index 0000000000..11131e92c2
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/date.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: false
+require 'rubygems/optparse/lib/optparse'
+require 'date'
+
+Gem::OptionParser.accept(DateTime) do |s,|
+ begin
+ DateTime.parse(s) if s
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end
+end
+Gem::OptionParser.accept(Date) do |s,|
+ begin
+ Date.parse(s) if s
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end
+end
diff --git a/lib/rubygems/optparse/lib/optparse/kwargs.rb b/lib/rubygems/optparse/lib/optparse/kwargs.rb
new file mode 100644
index 0000000000..9290344c39
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/kwargs.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+require 'rubygems/optparse/lib/optparse'
+
+class Gem::OptionParser
+ # :call-seq:
+ # define_by_keywords(options, method, **params)
+ #
+ # :include: ../../doc/optparse/creates_option.rdoc
+ #
+ def define_by_keywords(options, meth, **opts)
+ meth.parameters.each do |type, name|
+ case type
+ when :key, :keyreq
+ op, cl = *(type == :key ? %w"[ ]" : ["", ""])
+ define("--#{name}=#{op}#{name.upcase}#{cl}", *opts[name]) do |o|
+ options[name] = o
+ end
+ end
+ end
+ options
+ end
+end
diff --git a/lib/rubygems/optparse/lib/optparse/shellwords.rb b/lib/rubygems/optparse/lib/optparse/shellwords.rb
new file mode 100644
index 0000000000..60dd91990c
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/shellwords.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: false
+# -*- ruby -*-
+
+require 'shellwords'
+require 'rubygems/optparse/lib/optparse'
+
+Gem::OptionParser.accept(Shellwords) {|s,| Shellwords.shellwords(s)}
diff --git a/lib/rubygems/optparse/lib/optparse/time.rb b/lib/rubygems/optparse/lib/optparse/time.rb
new file mode 100644
index 0000000000..cb19f6e998
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/time.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: false
+require 'rubygems/optparse/lib/optparse'
+require 'time'
+
+Gem::OptionParser.accept(Time) do |s,|
+ begin
+ (Time.httpdate(s) rescue Time.parse(s)) if s
+ rescue
+ raise Gem::OptionParser::InvalidArgument, s
+ end
+end
diff --git a/lib/rubygems/optparse/lib/optparse/uri.rb b/lib/rubygems/optparse/lib/optparse/uri.rb
new file mode 100644
index 0000000000..088f309992
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/uri.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: false
+# -*- ruby -*-
+
+require 'rubygems/optparse/lib/optparse'
+require 'uri'
+
+Gem::OptionParser.accept(URI) {|s,| URI.parse(s) if s}
diff --git a/lib/rubygems/optparse/lib/optparse/version.rb b/lib/rubygems/optparse/lib/optparse/version.rb
new file mode 100644
index 0000000000..5d79e9db44
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/version.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: false
+# Gem::OptionParser internal utility
+
+class << Gem::OptionParser
+ def show_version(*pkgs)
+ progname = ARGV.options.program_name
+ result = false
+ show = proc do |klass, cname, version|
+ str = "#{progname}"
+ unless klass == ::Object and cname == :VERSION
+ version = version.join(".") if Array === version
+ str << ": #{klass}" unless klass == Object
+ str << " version #{version}"
+ end
+ [:Release, :RELEASE].find do |rel|
+ if klass.const_defined?(rel)
+ str << " (#{klass.const_get(rel)})"
+ end
+ end
+ puts str
+ result = true
+ end
+ if pkgs.size == 1 and pkgs[0] == "all"
+ self.search_const(::Object, /\AV(?:ERSION|ersion)\z/) do |klass, cname, version|
+ unless cname[1] == ?e and klass.const_defined?(:Version)
+ show.call(klass, cname.intern, version)
+ end
+ end
+ else
+ pkgs.each do |pkg|
+ begin
+ pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)}
+ v = case
+ when pkg.const_defined?(:Version)
+ pkg.const_get(n = :Version)
+ when pkg.const_defined?(:VERSION)
+ pkg.const_get(n = :VERSION)
+ else
+ n = nil
+ "unknown"
+ end
+ show.call(pkg, n, v)
+ rescue NameError
+ end
+ end
+ end
+ result
+ end
+
+ def each_const(path, base = ::Object)
+ path.split(/::|\//).inject(base) do |klass, name|
+ raise NameError, path unless Module === klass
+ klass.constants.grep(/#{name}/i) do |c|
+ klass.const_defined?(c) or next
+ klass.const_get(c)
+ end
+ end
+ end
+
+ def search_const(klass, name)
+ klasses = [klass]
+ while klass = klasses.shift
+ klass.constants.each do |cname|
+ klass.const_defined?(cname) or next
+ const = klass.const_get(cname)
+ yield klass, cname, const if name === cname
+ klasses << const if Module === const and const != ::Object
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb
index 77811ed5ec..94705914af 100644
--- a/lib/rubygems/package.rb
+++ b/lib/rubygems/package.rb
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
@@ -8,7 +7,8 @@
# Example using a Gem::Package
#
# Builds a .gem file given a Gem::Specification. A .gem file is a tarball
-# which contains a data.tar.gz and metadata.gz, and possibly signatures.
+# which contains a data.tar.gz, metadata.gz, checksums.yaml.gz and possibly
+# signatures.
#
# require 'rubygems'
# require 'rubygems/package'
@@ -41,13 +41,11 @@
# #files are the files in the .gem tar file, not the Ruby files in the gem
# #extract_files and #contents automatically call #verify
-require 'rubygems/security'
-require 'rubygems/specification'
-require 'rubygems/user_interaction'
-require 'zlib'
+require_relative "../rubygems"
+require_relative 'security'
+require_relative 'user_interaction'
class Gem::Package
-
include Gem::UserInteraction
class Error < Gem::Exception; end
@@ -55,7 +53,7 @@ class Gem::Package
class FormatError < Error
attr_reader :path
- def initialize message, source = nil
+ def initialize(message, source = nil)
if source
@path = source.path
@@ -64,16 +62,22 @@ class Gem::Package
super message
end
-
end
class PathError < Error
- def initialize destination, destination_dir
+ def initialize(destination, destination_dir)
super "installing into parent path %s of %s is not allowed" %
[destination, destination_dir]
end
end
+ class SymlinkError < Error
+ def initialize(name, destination, destination_dir)
+ super "installing symlink '%s' pointing to parent path %s of %s is not allowed" %
+ [name, destination, destination_dir]
+ end
+ end
+
class NonSeekableIO < Error; end
class TooLongFileName < Error; end
@@ -83,7 +87,6 @@ class Gem::Package
class TarInvalidError < Error; end
-
attr_accessor :build_time # :nodoc:
##
@@ -98,6 +101,11 @@ class Gem::Package
attr_reader :files
##
+ # Reference to the gem being packaged.
+
+ attr_reader :gem
+
+ ##
# The security policy used for verifying the contents of this package.
attr_accessor :security_policy
@@ -107,12 +115,24 @@ class Gem::Package
attr_writer :spec
- def self.build spec, skip_validation=false
- gem_file = spec.file_name
+ ##
+ # Permission for directories
+ attr_accessor :dir_mode
+
+ ##
+ # Permission for program files
+ attr_accessor :prog_mode
+
+ ##
+ # Permission for other files
+ attr_accessor :data_mode
+
+ def self.build(spec, skip_validation = false, strict_validation = false, file_name = nil)
+ gem_file = file_name || spec.file_name
package = new gem_file
package.spec = spec
- package.build skip_validation
+ package.build skip_validation, strict_validation
gem_file
end
@@ -124,7 +144,7 @@ class Gem::Package
# If +gem+ is an existing file in the old format a Gem::Package::Old will be
# returned.
- def self.new gem, security_policy = nil
+ def self.new(gem, security_policy = nil)
gem = if gem.is_a?(Gem::Package::Source)
gem
elsif gem.respond_to? :read
@@ -143,15 +163,43 @@ class Gem::Package
end
##
+ # Extracts the Gem::Specification and raw metadata from the .gem file at
+ # +path+.
+ #--
+
+ def self.raw_spec(path, security_policy = nil)
+ format = new(path, security_policy)
+ spec = format.spec
+
+ metadata = nil
+
+ File.open path, Gem.binary_mode do |io|
+ tar = Gem::Package::TarReader.new io
+ tar.each_entry do |entry|
+ case entry.full_name
+ when 'metadata' then
+ metadata = entry.read
+ when 'metadata.gz' then
+ metadata = Gem::Util.gunzip entry.read
+ end
+ end
+ end
+
+ return spec, metadata
+ end
+
+ ##
# Creates a new package that will read or write to the file +gem+.
- def initialize gem, security_policy # :notnew:
+ def initialize(gem, security_policy) # :notnew:
+ require 'zlib'
+
@gem = gem
- @build_time = Time.now
+ @build_time = Gem.source_date_epoch
@checksums = {}
@contents = nil
- @digests = Hash.new { |h, algorithm| h[algorithm] = {} }
+ @digests = Hash.new {|h, algorithm| h[algorithm] = {} }
@files = nil
@security_policy = security_policy
@signatures = {}
@@ -162,17 +210,17 @@ class Gem::Package
##
# Copies this package to +path+ (if possible)
- def copy_to path
+ def copy_to(path)
FileUtils.cp @gem.path, path unless File.exist? path
end
##
# Adds a checksum for each entry in the gem to checksums.yaml.gz.
- def add_checksums tar
+ def add_checksums(tar)
Gem.load_yaml
- checksums_by_algorithm = Hash.new { |h, algorithm| h[algorithm] = {} }
+ checksums_by_algorithm = Hash.new {|h, algorithm| h[algorithm] = {} }
@checksums.each do |name, digests|
digests.each do |algorithm, digest|
@@ -191,7 +239,7 @@ class Gem::Package
# Adds the files listed in the packages's Gem::Specification to data.tar.gz
# and adds this file to the +tar+.
- def add_contents tar # :nodoc:
+ def add_contents(tar) # :nodoc:
digests = tar.add_file_signed 'data.tar.gz', 0444, @signer do |io|
gzip_to io do |gz_io|
Gem::Package::TarWriter.new gz_io do |data_tar|
@@ -206,20 +254,18 @@ class Gem::Package
##
# Adds files included the package's Gem::Specification to the +tar+ file
- def add_files tar # :nodoc:
+ def add_files(tar) # :nodoc:
@spec.files.each do |file|
stat = File.lstat file
if stat.symlink?
- relative_dir = File.dirname(file).sub("#{Dir.pwd}/", '')
- target_path = File.join(relative_dir, File.readlink(file))
- tar.add_symlink file, target_path, stat.mode
+ tar.add_symlink file, File.readlink(file), stat.mode
end
next unless stat.file?
tar.add_file_simple file, stat.mode, stat.size do |dst_io|
- open file, 'rb' do |src_io|
+ File.open file, 'rb' do |src_io|
dst_io.write src_io.read 16384 until src_io.eof?
end
end
@@ -229,7 +275,7 @@ class Gem::Package
##
# Adds the package's Gem::Specification to the +tar+ file
- def add_metadata tar # :nodoc:
+ def add_metadata(tar) # :nodoc:
digests = tar.add_file_signed 'metadata.gz', 0444, @signer do |io|
gzip_to io do |gz_io|
gz_io.write @spec.to_yaml
@@ -242,14 +288,19 @@ class Gem::Package
##
# Builds this package based on the specification set by #spec=
- def build skip_validation = false
+ def build(skip_validation = false, strict_validation = false)
+ raise ArgumentError, "skip_validation = true and strict_validation = true are incompatible" if skip_validation && strict_validation
+
Gem.load_yaml
- require 'rubygems/security'
@spec.mark_version
- @spec.validate unless skip_validation
+ @spec.validate true, strict_validation unless skip_validation
- setup_signer
+ setup_signer(
+ signer_options: {
+ expiration_length_days: Gem.configuration.cert_expiration_length_days,
+ }
+ )
@gem.with_write_io do |gem_io|
Gem::Package::TarWriter.new gem_io do |gem|
@@ -263,7 +314,7 @@ class Gem::Package
Successfully built RubyGem
Name: #{@spec.name}
Version: #{@spec.version}
- File: #{File.basename @spec.cache_file}
+ File: #{File.basename @gem.path}
EOM
ensure
@signer = nil
@@ -300,20 +351,15 @@ EOM
# Creates a digest of the TarEntry +entry+ from the digest algorithm set by
# the security policy.
- def digest entry # :nodoc:
- algorithms = if @checksums then
+ def digest(entry) # :nodoc:
+ algorithms = if @checksums
@checksums.keys
else
[Gem::Security::DIGEST_NAME].compact
end
algorithms.each do |algorithm|
- digester =
- if defined?(OpenSSL::Digest) then
- OpenSSL::Digest.new algorithm
- else
- Digest.const_get(algorithm).new
- end
+ digester = Gem::Security.create_digest(algorithm)
digester << entry.read(16384) until entry.eof?
@@ -331,10 +377,10 @@ EOM
# If +pattern+ is specified, only entries matching that glob will be
# extracted.
- def extract_files destination_dir, pattern = "*"
+ def extract_files(destination_dir, pattern = "*")
verify unless @spec
- FileUtils.mkdir_p destination_dir
+ FileUtils.mkdir_p destination_dir, :mode => dir_mode && 0755
@gem.with_read_io do |io|
reader = Gem::Package::TarReader.new io
@@ -360,29 +406,41 @@ EOM
# If +pattern+ is specified, only entries matching that glob will be
# extracted.
- def extract_tar_gz io, destination_dir, pattern = "*" # :nodoc:
+ def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc:
+ directories = []
open_tar_gz io do |tar|
tar.each do |entry|
next unless File.fnmatch pattern, entry.full_name, File::FNM_DOTMATCH
destination = install_location entry.full_name, destination_dir
+ if entry.symlink?
+ link_target = entry.header.linkname
+ real_destination = link_target.start_with?("/") ? link_target : File.expand_path(link_target, File.dirname(destination))
+
+ raise Gem::Package::SymlinkError.new(entry.full_name, real_destination, destination_dir) unless
+ normalize_path(real_destination).start_with? normalize_path(destination_dir + '/')
+ end
+
FileUtils.rm_rf destination
mkdir_options = {}
- mkdir_options[:mode] = entry.header.mode if entry.directory?
+ mkdir_options[:mode] = dir_mode ? 0755 : (entry.header.mode if entry.directory?)
mkdir =
- if entry.directory? then
+ if entry.directory?
destination
else
File.dirname destination
end
- FileUtils.mkdir_p mkdir, mkdir_options
+ unless directories.include?(mkdir)
+ FileUtils.mkdir_p mkdir, **mkdir_options
+ directories << mkdir
+ end
- open destination, 'wb' do |out|
+ File.open destination, 'wb' do |out|
out.write entry.read
- FileUtils.chmod entry.header.mode, destination
+ FileUtils.chmod file_mode(entry.header.mode), destination
end if entry.file?
File.symlink(entry.header.linkname, destination) if entry.symlink?
@@ -390,6 +448,14 @@ EOM
verbose destination
end
end
+
+ if dir_mode
+ File.chmod(dir_mode, *directories)
+ end
+ end
+
+ def file_mode(mode) # :nodoc:
+ ((mode & 0111).zero? ? data_mode : prog_mode) || mode
end
##
@@ -398,7 +464,7 @@ EOM
# Also sets the gzip modification time to the package build time to ease
# testing.
- def gzip_to io # :yields: gz_io
+ def gzip_to(io) # :yields: gz_io
gz_io = Zlib::GzipWriter.new io, Zlib::BEST_COMPRESSION
gz_io.mtime = @build_time
@@ -412,38 +478,37 @@ EOM
#
# If +filename+ is not inside +destination_dir+ an exception is raised.
- def install_location filename, destination_dir # :nodoc:
+ def install_location(filename, destination_dir) # :nodoc:
raise Gem::Package::PathError.new(filename, destination_dir) if
filename.start_with? '/'
- destination_dir = File.realpath destination_dir if
- File.respond_to? :realpath
- destination_dir = File.expand_path destination_dir
-
- destination = File.join destination_dir, filename
- destination = File.expand_path destination
+ destination_dir = File.realpath(destination_dir)
+ destination = File.expand_path(filename, destination_dir)
raise Gem::Package::PathError.new(destination, destination_dir) unless
- destination.start_with? destination_dir
+ normalize_path(destination).start_with? normalize_path(destination_dir + '/')
- destination.untaint
+ destination.tap(&Gem::UNTAINT)
destination
end
+ def normalize_path(pathname)
+ if Gem.win_platform?
+ pathname.downcase
+ else
+ pathname
+ end
+ end
+
##
# Loads a Gem::Specification from the TarEntry +entry+
- def load_spec entry # :nodoc:
+ def load_spec(entry) # :nodoc:
case entry.full_name
when 'metadata' then
@spec = Gem::Specification.from_yaml entry.read
when 'metadata.gz' then
- args = [entry]
- args << { :external_encoding => Encoding::UTF_8 } if
- Object.const_defined?(:Encoding) &&
- Zlib::GzipReader.method(:wrap).arity != 1
-
- Zlib::GzipReader.wrap(*args) do |gzio|
+ Zlib::GzipReader.wrap(entry, external_encoding: Encoding::UTF_8) do |gzio|
@spec = Gem::Specification.from_yaml gzio.read
end
end
@@ -452,7 +517,7 @@ EOM
##
# Opens +io+ as a gzipped tar archive
- def open_tar_gz io # :nodoc:
+ def open_tar_gz(io) # :nodoc:
Zlib::GzipReader.wrap io do |gzio|
tar = Gem::Package::TarReader.new gzio
@@ -463,7 +528,7 @@ EOM
##
# Reads and loads checksums.yaml.gz from the tar file +gem+
- def read_checksums gem
+ def read_checksums(gem)
Gem.load_yaml
@checksums = gem.seek 'checksums.yaml.gz' do |entry|
@@ -477,15 +542,22 @@ EOM
# Prepares the gem for signing and checksum generation. If a signing
# certificate and key are not present only checksum generation is set up.
- def setup_signer
+ def setup_signer(signer_options: {})
passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
- if @spec.signing_key then
- @signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain, passphrase
+ if @spec.signing_key
+ @signer =
+ Gem::Security::Signer.new(
+ @spec.signing_key,
+ @spec.cert_chain,
+ passphrase,
+ signer_options
+ )
+
@spec.signing_key = nil
- @spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s }
+ @spec.cert_chain = @signer.cert_chain.map {|cert| cert.to_s }
else
@signer = Gem::Security::Signer.new nil, nil, passphrase
- @spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_pem } if
+ @spec.cert_chain = @signer.cert_chain.map {|cert| cert.to_pem } if
@signer.cert_chain
end
end
@@ -545,14 +617,14 @@ EOM
# Verifies the +checksums+ against the +digests+. This check is not
# cryptographically secure. Missing checksums are ignored.
- def verify_checksums digests, checksums # :nodoc:
+ def verify_checksums(digests, checksums) # :nodoc:
return unless checksums
checksums.sort.each do |algorithm, gem_digests|
gem_digests.sort.each do |file_name, gem_hexdigest|
computed_digest = digests[algorithm][file_name]
- unless computed_digest.hexdigest == gem_hexdigest then
+ unless computed_digest.hexdigest == gem_hexdigest
raise Gem::Package::FormatError.new \
"#{algorithm} checksum mismatch for #{file_name}", @gem
end
@@ -563,7 +635,7 @@ EOM
##
# Verifies +entry+ in a .gem file.
- def verify_entry entry
+ def verify_entry(entry)
file_name = entry.full_name
@files << file_name
@@ -576,54 +648,56 @@ EOM
end
case file_name
- when /^metadata(.gz)?$/ then
+ when "metadata", "metadata.gz" then
load_spec entry
when 'data.tar.gz' then
verify_gz entry
end
- rescue => e
- message = "package is corrupt, exception while verifying: " +
- "#{e.message} (#{e.class})"
- raise Gem::Package::FormatError.new message, @gem
+ rescue
+ warn "Exception while verifying #{@gem.path}"
+ raise
end
##
# Verifies the files of the +gem+
- def verify_files gem
+ def verify_files(gem)
gem.each do |entry|
verify_entry entry
end
- unless @spec then
+ unless @spec
raise Gem::Package::FormatError.new 'package metadata is missing', @gem
end
- unless @files.include? 'data.tar.gz' then
+ unless @files.include? 'data.tar.gz'
raise Gem::Package::FormatError.new \
'package content (data.tar.gz) is missing', @gem
end
+
+ if duplicates = @files.group_by {|f| f }.select {|k,v| v.size > 1 }.map(&:first) and duplicates.any?
+ raise Gem::Security::Exception, "duplicate files in the package: (#{duplicates.map(&:inspect).join(', ')})"
+ end
end
##
# Verifies that +entry+ is a valid gzipped file.
- def verify_gz entry # :nodoc:
+ def verify_gz(entry) # :nodoc:
Zlib::GzipReader.wrap entry do |gzio|
gzio.read 16384 until gzio.eof? # gzip checksum verification
end
rescue Zlib::GzipFile::Error => e
raise Gem::Package::FormatError.new(e.message, entry.full_name)
end
-
end
-require 'rubygems/package/digest_io'
-require 'rubygems/package/source'
-require 'rubygems/package/file_source'
-require 'rubygems/package/io_source'
-require 'rubygems/package/old'
-require 'rubygems/package/tar_header'
-require 'rubygems/package/tar_reader'
-require 'rubygems/package/tar_reader/entry'
-require 'rubygems/package/tar_writer'
+require_relative 'package/digest_io'
+require_relative 'package/source'
+require_relative 'package/file_source'
+require_relative 'package/io_source'
+require_relative 'package/old'
+require_relative 'package/tar_header'
+require_relative 'package/tar_reader'
+require_relative 'package/tar_reader/entry'
+require_relative 'package/tar_writer'
diff --git a/lib/rubygems/package/digest_io.rb b/lib/rubygems/package/digest_io.rb
index 4930c9aa7d..4736f76d93 100644
--- a/lib/rubygems/package/digest_io.rb
+++ b/lib/rubygems/package/digest_io.rb
@@ -3,7 +3,6 @@
# IO wrapper that creates digests of contents written to the IO it wraps.
class Gem::Package::DigestIO
-
##
# Collected digests for wrapped writes.
#
@@ -31,7 +30,7 @@ class Gem::Package::DigestIO
# digests['SHA1'].hexdigest #=> "aaf4c61d[...]"
# digests['SHA512'].hexdigest #=> "9b71d224[...]"
- def self.wrap io, digests
+ def self.wrap(io, digests)
digest_io = new io, digests
yield digest_io
@@ -43,7 +42,7 @@ class Gem::Package::DigestIO
# Creates a new DigestIO instance. Using ::wrap is recommended, see the
# ::wrap documentation for documentation of +io+ and +digests+.
- def initialize io, digests
+ def initialize(io, digests)
@io = io
@digests = digests
end
@@ -51,7 +50,7 @@ class Gem::Package::DigestIO
##
# Writes +data+ to the underlying IO and updates the digests
- def write data
+ def write(data)
result = @io.write data
@digests.each do |_, digest|
@@ -60,6 +59,4 @@ class Gem::Package::DigestIO
result
end
-
end
-
diff --git a/lib/rubygems/package/file_source.rb b/lib/rubygems/package/file_source.rb
index 1a4dc4c824..114a950c77 100644
--- a/lib/rubygems/package/file_source.rb
+++ b/lib/rubygems/package/file_source.rb
@@ -7,10 +7,9 @@
# object to `Gem::Package.new`.
class Gem::Package::FileSource < Gem::Package::Source # :nodoc: all
-
attr_reader :path
- def initialize path
+ def initialize(path)
@path = path
end
@@ -22,13 +21,11 @@ class Gem::Package::FileSource < Gem::Package::Source # :nodoc: all
File.exist? path
end
- def with_write_io &block
- open path, 'wb', &block
+ def with_write_io(&block)
+ File.open path, 'wb', &block
end
- def with_read_io &block
- open path, 'rb', &block
+ def with_read_io(&block)
+ File.open path, 'rb', &block
end
-
end
-
diff --git a/lib/rubygems/package/io_source.rb b/lib/rubygems/package/io_source.rb
index ee79a21083..03d7714524 100644
--- a/lib/rubygems/package/io_source.rb
+++ b/lib/rubygems/package/io_source.rb
@@ -8,10 +8,9 @@
# object to `Gem::Package.new`.
class Gem::Package::IOSource < Gem::Package::Source # :nodoc: all
-
attr_reader :io
- def initialize io
+ def initialize(io)
@io = io
end
@@ -33,14 +32,16 @@ class Gem::Package::IOSource < Gem::Package::Source # :nodoc: all
def with_read_io
yield io
+ ensure
+ io.rewind
end
def with_write_io
yield io
+ ensure
+ io.rewind
end
def path
end
-
end
-
diff --git a/lib/rubygems/package/old.rb b/lib/rubygems/package/old.rb
index f6e6e67c38..25317ef23f 100644
--- a/lib/rubygems/package/old.rb
+++ b/lib/rubygems/package/old.rb
@@ -12,14 +12,13 @@
# Please pretend this doesn't exist.
class Gem::Package::Old < Gem::Package
-
undef_method :spec=
##
# Creates a new old-format package reader for +gem+. Old-format packages
# cannot be written.
- def initialize gem, security_policy
+ def initialize(gem, security_policy)
require 'fileutils'
require 'zlib'
Gem.load_yaml
@@ -42,14 +41,14 @@ class Gem::Package::Old < Gem::Package
read_until_dashes io # spec
header = file_list io
- @contents = header.map { |file| file['path'] }
+ @contents = header.map {|file| file['path'] }
end
end
##
# Extracts the files in this package into +destination_dir+
- def extract_files destination_dir
+ def extract_files(destination_dir)
verify
errstr = "Error reading files from gem"
@@ -78,9 +77,9 @@ class Gem::Package::Old < Gem::Package
FileUtils.rm_rf destination
- FileUtils.mkdir_p File.dirname destination
+ FileUtils.mkdir_p File.dirname(destination), :mode => dir_mode && 0755
- open destination, 'wb', entry['mode'] do |out|
+ File.open destination, 'wb', file_mode(entry['mode']) do |out|
out.write file_data
end
@@ -94,7 +93,7 @@ class Gem::Package::Old < Gem::Package
##
# Reads the file list section from the old-format gem +io+
- def file_list io # :nodoc:
+ def file_list(io) # :nodoc:
header = String.new
read_until_dashes io do |line|
@@ -107,7 +106,7 @@ class Gem::Package::Old < Gem::Package
##
# Reads lines until a "---" separator is found
- def read_until_dashes io # :nodoc:
+ def read_until_dashes(io) # :nodoc:
while (line = io.gets) && line.chomp.strip != "---" do
yield line if block_given?
end
@@ -116,7 +115,7 @@ class Gem::Package::Old < Gem::Package
##
# Skips the Ruby self-install header in +io+.
- def skip_ruby io # :nodoc:
+ def skip_ruby(io) # :nodoc:
loop do
line = io.gets
@@ -144,17 +143,9 @@ class Gem::Package::Old < Gem::Package
end
end
- yaml_error = if RUBY_VERSION < '1.9' then
- YAML::ParseError
- elsif YAML.const_defined?(:ENGINE) && YAML::ENGINE.yamler == 'syck' then
- YAML::ParseError
- else
- YAML::SyntaxError
- end
-
begin
@spec = Gem::Specification.from_yaml yaml
- rescue yaml_error
+ rescue YAML::SyntaxError
raise Gem::Exception, "Failed to parse gem specification out of gem file"
end
rescue ArgumentError
@@ -174,5 +165,4 @@ class Gem::Package::Old < Gem::Package
true
end
-
end
diff --git a/lib/rubygems/package/source.rb b/lib/rubygems/package/source.rb
index fe19776c38..69701e55e9 100644
--- a/lib/rubygems/package/source.rb
+++ b/lib/rubygems/package/source.rb
@@ -1,4 +1,3 @@
# frozen_string_literal: true
class Gem::Package::Source # :nodoc:
end
-
diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb
index c54bd14d57..ce9b49e3eb 100644
--- a/lib/rubygems/package/tar_header.rb
+++ b/lib/rubygems/package/tar_header.rb
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
@@ -29,7 +28,6 @@
# A header for a tar file
class Gem::Package::TarHeader
-
##
# Fields in the tar header
@@ -50,7 +48,7 @@ class Gem::Package::TarHeader
:uid,
:uname,
:version,
- ]
+ ].freeze
##
# Pack format for a tar header
@@ -94,40 +92,57 @@ class Gem::Package::TarHeader
attr_reader(*FIELDS)
+ EMPTY_HEADER = ("\0" * 512).freeze # :nodoc:
+
##
# Creates a tar header from IO +stream+
def self.from(stream)
header = stream.read 512
- empty = (header == "\0" * 512)
+ empty = (EMPTY_HEADER == header)
fields = header.unpack UNPACK_FORMAT
new :name => fields.shift,
- :mode => fields.shift.oct,
- :uid => fields.shift.oct,
- :gid => fields.shift.oct,
- :size => fields.shift.oct,
- :mtime => fields.shift.oct,
- :checksum => fields.shift.oct,
+ :mode => strict_oct(fields.shift),
+ :uid => oct_or_256based(fields.shift),
+ :gid => oct_or_256based(fields.shift),
+ :size => strict_oct(fields.shift),
+ :mtime => strict_oct(fields.shift),
+ :checksum => strict_oct(fields.shift),
:typeflag => fields.shift,
:linkname => fields.shift,
:magic => fields.shift,
- :version => fields.shift.oct,
+ :version => strict_oct(fields.shift),
:uname => fields.shift,
:gname => fields.shift,
- :devmajor => fields.shift.oct,
- :devminor => fields.shift.oct,
+ :devmajor => strict_oct(fields.shift),
+ :devminor => strict_oct(fields.shift),
:prefix => fields.shift,
:empty => empty
end
+ def self.strict_oct(str)
+ return str.strip.oct if str.strip =~ /\A[0-7]*\z/
+
+ raise ArgumentError, "#{str.inspect} is not an octal string"
+ end
+
+ def self.oct_or_256based(str)
+ # \x80 flags a positive 256-based number
+ # \ff flags a negative 256-based number
+ # In case we have a match, parse it as a signed binary value
+ # in big-endian order, except that the high-order bit is ignored.
+ return str.unpack('N2').last if str =~ /\A[\x80\xff]/n
+ strict_oct(str)
+ end
+
##
# Creates a new TarHeader using +vals+
def initialize(vals)
- unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode] then
+ unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode]
raise ArgumentError, ":name, :size, :prefix and :mode required"
end
@@ -193,7 +208,7 @@ class Gem::Package::TarHeader
private
def calculate_checksum(header)
- header.unpack("C*").inject { |a, b| a + b }
+ header.unpack("C*").inject {|a, b| a + b }
end
def header(checksum = @checksum)
@@ -214,7 +229,7 @@ class Gem::Package::TarHeader
gname,
oct(devmajor, 7),
oct(devminor, 7),
- prefix
+ prefix,
]
header = header.pack PACK_FORMAT
@@ -225,5 +240,4 @@ class Gem::Package::TarHeader
def oct(num, len)
"%0#{len}o" % num
end
-
end
diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb
index 1098336e36..41121f3bfb 100644
--- a/lib/rubygems/package/tar_reader.rb
+++ b/lib/rubygems/package/tar_reader.rb
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
@@ -9,7 +8,6 @@
# TarReader reads tar files and allows iteration over their items
class Gem::Package::TarReader
-
include Enumerable
##
@@ -55,6 +53,8 @@ class Gem::Package::TarReader
def each
return enum_for __method__ unless block_given?
+ use_seek = @io.respond_to?(:seek)
+
until @io.eof? do
header = Gem::Package::TarHeader.from @io
return if header.empty?
@@ -67,18 +67,22 @@ class Gem::Package::TarReader
skip = (512 - (size % 512)) % 512
pending = size - entry.bytes_read
- begin
- # avoid reading...
- @io.seek pending, IO::SEEK_CUR
- pending = 0
- rescue Errno::EINVAL, NameError
- while pending > 0 do
- bytes_read = @io.read([pending, 4096].min).size
- raise UnexpectedEOF if @io.eof?
- pending -= bytes_read
+ if use_seek
+ begin
+ # avoid reading if the @io supports seeking
+ @io.seek pending, IO::SEEK_CUR
+ pending = 0
+ rescue Errno::EINVAL
end
end
+ # if seeking isn't supported or failed
+ while pending > 0 do
+ bytes_read = @io.read([pending, 4096].min).size
+ raise UnexpectedEOF if @io.eof?
+ pending -= bytes_read
+ end
+
@io.read skip # discard trailing zeros
# make sure nobody can use #read, #getc or #rewind anymore
@@ -92,11 +96,9 @@ class Gem::Package::TarReader
# NOTE: Do not call #rewind during #each
def rewind
- if @init_pos == 0 then
- raise Gem::Package::NonSeekableIO unless @io.respond_to? :rewind
+ if @init_pos == 0
@io.rewind
else
- raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=
@io.pos = @init_pos
end
end
@@ -106,7 +108,7 @@ class Gem::Package::TarReader
# yields it. Rewinds the tar file to the beginning when the block
# terminates.
- def seek name # :yields: entry
+ def seek(name) # :yields: entry
found = find do |entry|
entry.full_name == name
end
@@ -117,7 +119,6 @@ class Gem::Package::TarReader
ensure
rewind
end
-
end
-require 'rubygems/package/tar_reader/entry'
+require_relative 'tar_reader/entry'
diff --git a/lib/rubygems/package/tar_reader/entry.rb b/lib/rubygems/package/tar_reader/entry.rb
index 5f958edc2f..5865599d3a 100644
--- a/lib/rubygems/package/tar_reader/entry.rb
+++ b/lib/rubygems/package/tar_reader/entry.rb
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# frozen_string_literal: true
#++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
@@ -9,7 +8,6 @@
# Class for reading entries out of a tar file
class Gem::Package::TarReader::Entry
-
##
# Header for this tar entry
@@ -64,7 +62,7 @@ class Gem::Package::TarReader::Entry
# Full name of the tar entry
def full_name
- if @header.prefix != "" then
+ if @header.prefix != ""
File.join @header.prefix, @header.name
else
@header.name
@@ -119,6 +117,12 @@ class Gem::Package::TarReader::Entry
bytes_read
end
+ def size
+ @header.size
+ end
+
+ alias length size
+
##
# Reads +len+ bytes from the tar file entry, or the rest of the entry if
# nil
@@ -137,7 +141,19 @@ class Gem::Package::TarReader::Entry
ret
end
- alias readpartial read # :nodoc:
+ def readpartial(maxlen = nil, outbuf = "".b)
+ check_closed
+
+ raise EOFError if @read >= @header.size
+
+ maxlen ||= @header.size - @read
+ max_read = [maxlen, @header.size - @read].min
+
+ @io.readpartial(max_read, outbuf)
+ @read += outbuf.size
+
+ outbuf
+ end
##
# Rewinds to the beginning of the tar file entry
@@ -145,10 +161,7 @@ class Gem::Package::TarReader::Entry
def rewind
check_closed
- raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=
-
@io.pos = @orig_pos
@read = 0
end
-
end
diff --git a/lib/rubygems/package/tar_test_case.rb b/lib/rubygems/package/tar_test_case.rb
deleted file mode 100644
index 46ac949587..0000000000
--- a/lib/rubygems/package/tar_test_case.rb
+++ /dev/null
@@ -1,147 +0,0 @@
-# frozen_string_literal: true
-require 'rubygems/test_case'
-require 'rubygems/package'
-
-##
-# A test case for Gem::Package::Tar* classes
-
-class Gem::Package::TarTestCase < Gem::TestCase
-
- def ASCIIZ(str, length)
- str + "\0" * (length - str.length)
- end
-
- def SP(s)
- s + " "
- end
-
- def SP_Z(s)
- s + " \0"
- end
-
- def Z(s)
- s + "\0"
- end
-
- def assert_headers_equal(expected, actual)
- expected = expected.to_s unless String === expected
- actual = actual.to_s unless String === actual
-
- fields = %w[
- name 100
- mode 8
- uid 8
- gid 8
- size 12
- mtime 12
- checksum 8
- typeflag 1
- linkname 100
- magic 6
- version 2
- uname 32
- gname 32
- devmajor 8
- devminor 8
- prefix 155
- ]
-
- offset = 0
-
- until fields.empty? do
- name = fields.shift
- length = fields.shift.to_i
-
- if name == "checksum" then
- chksum_off = offset
- offset += length
- next
- end
-
- assert_equal expected[offset, length], actual[offset, length],
- "Field #{name} of the tar header differs."
-
- offset += length
- end
-
- assert_equal expected[chksum_off, 8], actual[chksum_off, 8]
- end
-
- def calc_checksum(header)
- sum = header.unpack("C*").inject{|s,a| s + a}
- SP(Z(to_oct(sum, 6)))
- end
-
- def header(type, fname, dname, length, mode, mtime, checksum = nil, linkname = "")
- checksum ||= " " * 8
-
- arr = [ # struct tarfile_entry_posix
- ASCIIZ(fname, 100), # char name[100]; ASCII + (Z unless filled)
- Z(to_oct(mode, 7)), # char mode[8]; 0 padded, octal null
- Z(to_oct(0, 7)), # char uid[8]; ditto
- Z(to_oct(0, 7)), # char gid[8]; ditto
- Z(to_oct(length, 11)), # char size[12]; 0 padded, octal, null
- Z(to_oct(mtime, 11)), # char mtime[12]; 0 padded, octal, null
- checksum, # char checksum[8]; 0 padded, octal, null, space
- type, # char typeflag[1]; file: "0" dir: "5"
- ASCIIZ(linkname, 100), # char linkname[100]; ASCII + (Z unless filled)
- "ustar\0", # char magic[6]; "ustar\0"
- "00", # char version[2]; "00"
- ASCIIZ("wheel", 32), # char uname[32]; ASCIIZ
- ASCIIZ("wheel", 32), # char gname[32]; ASCIIZ
- Z(to_oct(0, 7)), # char devmajor[8]; 0 padded, octal, null
- Z(to_oct(0, 7)), # char devminor[8]; 0 padded, octal, null
- ASCIIZ(dname, 155) # char prefix[155]; ASCII + (Z unless filled)
- ]
-
- format = "C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155"
- h = if RUBY_VERSION >= "1.9" then
- arr.join
- else
- arr = arr.join("").split(//).map{|x| x[0]}
- arr.pack format
- end
- ret = h + "\0" * (512 - h.size)
- assert_equal(512, ret.size)
- ret
- end
-
- def tar_dir_header(name, prefix, mode, mtime)
- h = header("5", name, prefix, 0, mode, mtime)
- checksum = calc_checksum(h)
- header("5", name, prefix, 0, mode, mtime, checksum)
- end
-
- def tar_file_header(fname, dname, mode, length, mtime)
- h = header("0", fname, dname, length, mode, mtime)
- checksum = calc_checksum(h)
- header("0", fname, dname, length, mode, mtime, checksum)
- end
-
- def tar_symlink_header(fname, prefix, mode, mtime, linkname)
- h = header("2", fname, prefix, 0, mode, mtime, nil, linkname)
- checksum = calc_checksum(h)
- header("2", fname, prefix, 0, mode, mtime, checksum, linkname)
- end
-
- def to_oct(n, pad_size)
- "%0#{pad_size}o" % n
- end
-
- def util_entry(tar)
- io = TempIO.new tar
-
- header = Gem::Package::TarHeader.from io
-
- Gem::Package::TarReader::Entry.new header, io
- end
-
- def util_dir_entry
- util_entry tar_dir_header("foo", "bar", 0, Time.now)
- end
-
- def util_symlink_entry
- util_entry tar_symlink_header("foo", "bar", 0, Time.now, "link")
- end
-
-end
diff --git a/lib/rubygems/package/tar_writer.rb b/lib/rubygems/package/tar_writer.rb
index f68b8d4c5e..877cc167c9 100644
--- a/lib/rubygems/package/tar_writer.rb
+++ b/lib/rubygems/package/tar_writer.rb
@@ -1,24 +1,19 @@
-# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
#++
-require 'digest'
-
##
# Allows writing of tar files
class Gem::Package::TarWriter
-
class FileOverflow < StandardError; end
##
# IO wrapper that allows writing a limited amount of data
class BoundedStream
-
##
# Maximum number of bytes that can be written
@@ -50,14 +45,12 @@ class Gem::Package::TarWriter
@written += data.bytesize
data.bytesize
end
-
end
##
# IO wrapper that provides only #write
class RestrictedStream
-
##
# Creates a new RestrictedStream wrapping +io+
@@ -71,7 +64,6 @@ class Gem::Package::TarWriter
def write(data)
@io.write data
end
-
end
##
@@ -106,12 +98,10 @@ class Gem::Package::TarWriter
def add_file(name, mode) # :yields: io
check_closed
- raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=
-
name, prefix = split_name name
init_pos = @io.pos
- @io.write "\0" * 512 # placeholder for the header
+ @io.write Gem::Package::TarHeader::EMPTY_HEADER # placeholder for the header
yield RestrictedStream.new(@io) if block_given?
@@ -125,7 +115,7 @@ class Gem::Package::TarWriter
header = Gem::Package::TarHeader.new :name => name, :mode => mode,
:size => size, :prefix => prefix,
- :mtime => Time.now
+ :mtime => Gem.source_date_epoch
@io.write header
@io.pos = final_pos
@@ -141,15 +131,14 @@ class Gem::Package::TarWriter
#
# The created digest object is returned.
- def add_file_digest name, mode, digest_algorithms # :yields: io
+ def add_file_digest(name, mode, digest_algorithms) # :yields: io
digests = digest_algorithms.map do |digest_algorithm|
digest = digest_algorithm.new
digest_name =
- if digest.respond_to? :name then
+ if digest.respond_to? :name
digest.name
else
- /::([^:]+)$/ =~ digest_algorithm.name
- $1
+ digest_algorithm.class.name[/::([^:]+)\z/, 1]
end
[digest_name, digest]
@@ -174,10 +163,10 @@ class Gem::Package::TarWriter
#
# Returns the digest.
- def add_file_signed name, mode, signer
+ def add_file_signed(name, mode, signer)
digest_algorithms = [
signer.digest_algorithm,
- Digest::SHA512,
+ Gem::Security.create_digest('SHA512'),
].compact.uniq
digests = add_file_digest name, mode, digest_algorithms do |io|
@@ -186,17 +175,18 @@ class Gem::Package::TarWriter
signature_digest = digests.values.compact.find do |digest|
digest_name =
- if digest.respond_to? :name then
+ if digest.respond_to? :name
digest.name
else
- /::([^:]+)$/ =~ digest.class.name
- $1
+ digest.class.name[/::([^:]+)\z/, 1]
end
digest_name == signer.digest_name
end
- if signer.key then
+ raise "no #{signer.digest_name} in #{digests.values.compact}" unless signature_digest
+
+ if signer.key
signature = signer.sign signature_digest.digest
add_file_simple "#{name}.sig", 0444, signature.length do |io|
@@ -218,7 +208,7 @@ class Gem::Package::TarWriter
header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
:size => size, :prefix => prefix,
- :mtime => Time.now).to_s
+ :mtime => Gem.source_date_epoch).to_s
@io.write header
os = BoundedStream.new @io, size
@@ -246,7 +236,7 @@ class Gem::Package::TarWriter
:size => 0, :typeflag => "2",
:linkname => target,
:prefix => prefix,
- :mtime => Time.now).to_s
+ :mtime => Gem.source_date_epoch).to_s
@io.write header
@@ -299,7 +289,7 @@ class Gem::Package::TarWriter
header = Gem::Package::TarHeader.new :name => name, :mode => mode,
:typeflag => "5", :size => 0,
:prefix => prefix,
- :mtime => Time.now
+ :mtime => Gem.source_date_epoch
@io.write header
@@ -310,12 +300,12 @@ class Gem::Package::TarWriter
# Splits +name+ into a name and prefix that can fit in the TarHeader
def split_name(name) # :nodoc:
- if name.bytesize > 256 then
+ if name.bytesize > 256
raise Gem::Package::TooLongFileName.new("File \"#{name}\" has a too long path (should be 256 or less)")
end
prefix = ''
- if name.bytesize > 100 then
+ if name.bytesize > 100
parts = name.split('/', -1) # parts are never empty here
name = parts.pop # initially empty for names with a trailing slash ("foo/.../bar/")
prefix = parts.join('/') # if empty, then it's impossible to split (parts is empty too)
@@ -324,16 +314,15 @@ class Gem::Package::TarWriter
prefix = parts.join('/')
end
- if name.bytesize > 100 or prefix.empty? then
+ if name.bytesize > 100 or prefix.empty?
raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long name (should be 100 or less)")
end
- if prefix.bytesize > 155 then
+ if prefix.bytesize > 155
raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long base path (should be 155 or less)")
end
end
return name, prefix
end
-
end
diff --git a/lib/rubygems/package_task.rb b/lib/rubygems/package_task.rb
index d554e3697b..bb48616b0e 100644
--- a/lib/rubygems/package_task.rb
+++ b/lib/rubygems/package_task.rb
@@ -20,13 +20,8 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-require 'rubygems'
-require 'rubygems/package'
-begin
- gem 'rake'
-rescue Gem::LoadError
-end
-
+require_relative '../rubygems'
+require_relative 'package'
require 'rake/packagetask'
##
@@ -62,7 +57,6 @@ require 'rake/packagetask'
# end
class Gem::PackageTask < Rake::PackageTask
-
##
# Ruby Gem::Specification containing the metadata for this package. The
# name, version and package_files are automatically determined from the
@@ -88,6 +82,7 @@ class Gem::PackageTask < Rake::PackageTask
super gem.full_name, :noversion
@gem_spec = gem
@package_files += gem_spec.files if gem_spec.files
+ @fileutils_output = $stdout
end
##
@@ -124,6 +119,4 @@ class Gem::PackageTask < Rake::PackageTask
end
end
end
-
end
-
diff --git a/lib/rubygems/path_support.rb b/lib/rubygems/path_support.rb
index 618bc793c4..8103caf324 100644
--- a/lib/rubygems/path_support.rb
+++ b/lib/rubygems/path_support.rb
@@ -23,17 +23,19 @@ class Gem::PathSupport
# hashtable, or defaults to ENV, the system environment.
#
def initialize(env)
- @home = env["GEM_HOME"] || Gem.default_dir
+ @home = env["GEM_HOME"] || Gem.default_dir
- if File::ALT_SEPARATOR then
- @home = @home.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
+ if File::ALT_SEPARATOR
+ @home = @home.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
end
+ @home = expand(@home)
+
@path = split_gem_path env["GEM_PATH"], @home
@spec_cache_dir = env["GEM_SPEC_CACHE"] || Gem.default_spec_cache_dir
- @spec_cache_dir = @spec_cache_dir.dup.untaint
+ @spec_cache_dir = @spec_cache_dir.dup.tap(&Gem::UNTAINT)
end
private
@@ -41,7 +43,7 @@ class Gem::PathSupport
##
# Split the Gem search path (as reported by Gem.path).
- def split_gem_path gpaths, home
+ def split_gem_path(gpaths, home)
# FIX: it should be [home, *path], not [*path, home]
gem_path = []
@@ -54,7 +56,7 @@ class Gem::PathSupport
gem_path += default_path
end
- if File::ALT_SEPARATOR then
+ if File::ALT_SEPARATOR
gem_path.map! do |this_path|
this_path.gsub File::ALT_SEPARATOR, File::SEPARATOR
end
@@ -65,7 +67,7 @@ class Gem::PathSupport
gem_path = default_path
end
- gem_path.uniq
+ gem_path.map {|path| expand(path) }.uniq
end
# Return the default Gem path
@@ -77,4 +79,12 @@ class Gem::PathSupport
end
gem_path
end
+
+ def expand(path)
+ if File.directory?(path)
+ File.realpath(path)
+ else
+ path
+ end
+ end
end
diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index 2dd9ed5782..efb046c7aa 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "rubygems/deprecate"
+require_relative "deprecate"
##
# Available list of platforms for targeting Gem installations.
@@ -7,14 +7,9 @@ require "rubygems/deprecate"
# See `gem help platform` for information on platform matching.
class Gem::Platform
-
@local = nil
- attr_accessor :cpu
-
- attr_accessor :os
-
- attr_accessor :version
+ attr_accessor :cpu, :os, :version
def self.local
arch = RbConfig::CONFIG['arch']
@@ -23,18 +18,33 @@ class Gem::Platform
end
def self.match(platform)
- Gem.platforms.any? do |local_platform|
+ match_platforms?(platform, Gem.platforms)
+ end
+
+ def self.match_platforms?(platform, platforms)
+ platforms.any? do |local_platform|
platform.nil? or
local_platform == platform or
(local_platform != Gem::Platform::RUBY and local_platform =~ platform)
end
end
+ private_class_method :match_platforms?
+
+ def self.match_spec?(spec)
+ match_gem?(spec.platform, spec.name)
+ end
+
+ def self.match_gem?(platform, gem_name)
+ # Note: this method might be redefined by Ruby implementations to
+ # customize behavior per RUBY_ENGINE, gem_name or other criteria.
+ match_platforms?(platform, Gem.platforms)
+ end
def self.installable?(spec)
if spec.respond_to? :installable_platform?
spec.installable_platform?
else
- match spec.platform
+ match_spec? spec
end
end
@@ -56,7 +66,7 @@ class Gem::Platform
when String then
arch = arch.split '-'
- if arch.length > 2 and arch.last !~ /\d/ then # reassemble x86-linux-gnu
+ if arch.length > 2 and arch.last !~ /\d/ # reassemble x86-linux-gnu
extra = arch.pop
arch.last << "-#{extra}"
end
@@ -68,7 +78,7 @@ class Gem::Platform
else cpu
end
- if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ then # for command-line
+ if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ # for command-line
@os, @version = arch
return
end
@@ -88,8 +98,9 @@ class Gem::Platform
when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ]
when /^dotnet$/ then [ 'dotnet', nil ]
when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ]
- when /linux/ then [ 'linux', $1 ]
+ when /linux-?((?!gnu)\w+)?/ then [ 'linux', $1 ]
when /mingw32/ then [ 'mingw32', nil ]
+ when /mingw-?(\w+)?/ then [ 'mingw', $1 ]
when /(mswin\d+)(\_(\d+))?/ then
os, version = $1, $3
@cpu = 'x86' if @cpu.nil? and os =~ /32$/
@@ -111,10 +122,6 @@ class Gem::Platform
end
end
- def inspect
- "%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a]
- end
-
def to_a
[@cpu, @os, @version]
end
@@ -150,7 +157,7 @@ class Gem::Platform
# cpu
([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or
- (@cpu == 'arm' and other.cpu =~ /\Aarm/)) and
+ (@cpu == 'arm' and other.cpu.start_with?("arm"))) and
# os
@os == other.os and
@@ -195,12 +202,11 @@ class Gem::Platform
# A pure-Ruby gem that may use Gem::Specification#extensions to build
# binary files.
- RUBY = 'ruby'
+ RUBY = 'ruby'.freeze
##
# A platform-specific gem that is built for the packaging Ruby's platform.
# This will be replaced with Gem::Platform::local.
- CURRENT = 'current'
+ CURRENT = 'current'.freeze
end
-
diff --git a/lib/rubygems/psych_tree.rb b/lib/rubygems/psych_tree.rb
index 41a7314b53..6f399a289e 100644
--- a/lib/rubygems/psych_tree.rb
+++ b/lib/rubygems/psych_tree.rb
@@ -18,7 +18,7 @@ module Gem
end
# This is ported over from the yaml_tree in 1.9.3
- def format_time time
+ def format_time(time)
if time.utc?
time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
else
diff --git a/lib/rubygems/query_utils.rb b/lib/rubygems/query_utils.rb
new file mode 100644
index 0000000000..0acd5bf9c8
--- /dev/null
+++ b/lib/rubygems/query_utils.rb
@@ -0,0 +1,353 @@
+# frozen_string_literal: true
+
+require_relative 'local_remote_options'
+require_relative 'spec_fetcher'
+require_relative 'version_option'
+require_relative 'text'
+
+module Gem::QueryUtils
+
+ include Gem::Text
+ include Gem::LocalRemoteOptions
+ include Gem::VersionOption
+
+ def add_query_options
+ add_option('-i', '--[no-]installed',
+ 'Check for installed gem') do |value, options|
+ options[:installed] = value
+ end
+
+ add_option('-I', 'Equivalent to --no-installed') do |value, options|
+ options[:installed] = false
+ end
+
+ add_version_option command, "for use with --installed"
+
+ add_option('-d', '--[no-]details',
+ 'Display detailed information of gem(s)') do |value, options|
+ options[:details] = value
+ end
+
+ add_option('--[no-]versions',
+ 'Display only gem names') do |value, options|
+ options[:versions] = value
+ options[:details] = false unless value
+ end
+
+ add_option('-a', '--all',
+ 'Display all gem versions') do |value, options|
+ options[:all] = value
+ end
+
+ add_option('-e', '--exact',
+ 'Name of gem(s) to query on matches the',
+ 'provided STRING') do |value, options|
+ options[:exact] = value
+ end
+
+ add_option('--[no-]prerelease',
+ 'Display prerelease versions') do |value, options|
+ options[:prerelease] = value
+ end
+
+ add_local_remote_options
+ end
+
+ def defaults_str # :nodoc:
+ "--local --name-matches // --no-details --versions --no-installed"
+ end
+
+ def execute
+ gem_names = Array(options[:name])
+
+ if !args.empty?
+ gem_names = options[:exact] ? args.map{|arg| /\A#{Regexp.escape(arg)}\Z/ } : args.map{|arg| /#{arg}/i }
+ end
+
+ terminate_interaction(check_installed_gems(gem_names)) if check_installed_gems?
+
+ gem_names.each {|n| show_gems(n) }
+ end
+
+ private
+
+ def check_installed_gems(gem_names)
+ exit_code = 0
+
+ if args.empty? && !gem_name?
+ alert_error "You must specify a gem name"
+ exit_code = 4
+ elsif gem_names.count > 1
+ alert_error "You must specify only ONE gem!"
+ exit_code = 4
+ else
+ installed = installed?(gem_names.first, options[:version])
+ installed = !installed unless options[:installed]
+
+ say(installed)
+ exit_code = 1 if !installed
+ end
+
+ exit_code
+ end
+
+ def check_installed_gems?
+ !options[:installed].nil?
+ end
+
+ def gem_name?
+ !options[:name].source.empty?
+ end
+
+ def prerelease
+ options[:prerelease]
+ end
+
+ def show_prereleases?
+ prerelease.nil? || prerelease
+ end
+
+ def args
+ options[:args].to_a
+ end
+
+ def display_header(type)
+ if (ui.outs.tty? and Gem.configuration.verbose) or both?
+ say
+ say "*** #{type} GEMS ***"
+ say
+ end
+ end
+
+ #Guts of original execute
+ def show_gems(name)
+ show_local_gems(name) if local?
+ show_remote_gems(name) if remote?
+ end
+
+ def show_local_gems(name, req = Gem::Requirement.default)
+ display_header("LOCAL")
+
+ specs = Gem::Specification.find_all do |s|
+ s.name =~ name and req =~ s.version
+ end
+
+ dep = Gem::Deprecate.skip_during { Gem::Dependency.new name, req }
+ specs.select! do |s|
+ dep.match?(s.name, s.version, show_prereleases?)
+ end
+
+ spec_tuples = specs.map do |spec|
+ [spec.name_tuple, spec]
+ end
+
+ output_query_results(spec_tuples)
+ end
+
+ def show_remote_gems(name)
+ display_header("REMOTE")
+
+ fetcher = Gem::SpecFetcher.fetcher
+
+ spec_tuples = if name.respond_to?(:source) && name.source.empty?
+ fetcher.detect(specs_type) { true }
+ else
+ fetcher.detect(specs_type) do |name_tuple|
+ name === name_tuple.name
+ end
+ end
+
+ output_query_results(spec_tuples)
+ end
+
+ def specs_type
+ if options[:all]
+ if options[:prerelease]
+ :complete
+ else
+ :released
+ end
+ elsif options[:prerelease]
+ :prerelease
+ else
+ :latest
+ end
+ end
+
+ ##
+ # Check if gem +name+ version +version+ is installed.
+
+ def installed?(name, req = Gem::Requirement.default)
+ Gem::Specification.any? {|s| s.name =~ name and req =~ s.version }
+ end
+
+ def output_query_results(spec_tuples)
+ output = []
+ versions = Hash.new {|h,name| h[name] = [] }
+
+ spec_tuples.each do |spec_tuple, source|
+ versions[spec_tuple.name] << [spec_tuple, source]
+ end
+
+ versions = versions.sort_by do |(n,_),_|
+ n.downcase
+ end
+
+ output_versions output, versions
+
+ say output.join(options[:details] ? "\n\n" : "\n")
+ end
+
+ def output_versions(output, versions)
+ versions.each do |gem_name, matching_tuples|
+ matching_tuples = matching_tuples.sort_by {|n,_| n.version }.reverse
+
+ platforms = Hash.new {|h,version| h[version] = [] }
+
+ matching_tuples.each do |n, _|
+ platforms[n.version] << n.platform if n.platform
+ end
+
+ seen = {}
+
+ matching_tuples.delete_if do |n,_|
+ if seen[n.version]
+ true
+ else
+ seen[n.version] = true
+ false
+ end
+ end
+
+ output << clean_text(make_entry(matching_tuples, platforms))
+ end
+ end
+
+ def entry_details(entry, detail_tuple, specs, platforms)
+ return unless options[:details]
+
+ name_tuple, spec = detail_tuple
+
+ spec = spec.fetch_spec(name_tuple)if spec.respond_to?(:fetch_spec)
+
+ entry << "\n"
+
+ spec_platforms entry, platforms
+ spec_authors entry, spec
+ spec_homepage entry, spec
+ spec_license entry, spec
+ spec_loaded_from entry, spec, specs
+ spec_summary entry, spec
+ end
+
+ def entry_versions(entry, name_tuples, platforms, specs)
+ return unless options[:versions]
+
+ list =
+ if platforms.empty? or options[:details]
+ name_tuples.map {|n| n.version }.uniq
+ else
+ platforms.sort.reverse.map do |version, pls|
+ out = version.to_s
+
+ if options[:domain] == :local
+ default = specs.any? do |s|
+ !s.is_a?(Gem::Source) && s.version == version && s.default_gem?
+ end
+ out = "default: #{out}" if default
+ end
+
+ if pls != [Gem::Platform::RUBY]
+ platform_list = [pls.delete(Gem::Platform::RUBY), *pls.sort].compact
+ out = platform_list.unshift(out).join(' ')
+ end
+
+ out
+ end
+ end
+
+ entry << " (#{list.join ', '})"
+ end
+
+ def make_entry(entry_tuples, platforms)
+ detail_tuple = entry_tuples.first
+
+ name_tuples, specs = entry_tuples.flatten.partition do |item|
+ Gem::NameTuple === item
+ end
+
+ entry = [name_tuples.first.name]
+
+ entry_versions(entry, name_tuples, platforms, specs)
+ entry_details(entry, detail_tuple, specs, platforms)
+
+ entry.join
+ end
+
+ def spec_authors(entry, spec)
+ authors = "Author#{spec.authors.length > 1 ? 's' : ''}: ".dup
+ authors << spec.authors.join(', ')
+ entry << format_text(authors, 68, 4)
+ end
+
+ def spec_homepage(entry, spec)
+ return if spec.homepage.nil? or spec.homepage.empty?
+
+ entry << "\n" << format_text("Homepage: #{spec.homepage}", 68, 4)
+ end
+
+ def spec_license(entry, spec)
+ return if spec.license.nil? or spec.license.empty?
+
+ licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: ".dup
+ licenses << spec.licenses.join(', ')
+ entry << "\n" << format_text(licenses, 68, 4)
+ end
+
+ def spec_loaded_from(entry, spec, specs)
+ return unless spec.loaded_from
+
+ if specs.length == 1
+ default = spec.default_gem? ? ' (default)' : nil
+ entry << "\n" << " Installed at#{default}: #{spec.base_dir}"
+ else
+ label = 'Installed at'
+ specs.each do |s|
+ version = s.version.to_s
+ version << ', default' if s.default_gem?
+ entry << "\n" << " #{label} (#{version}): #{s.base_dir}"
+ label = ' ' * label.length
+ end
+ end
+ end
+
+ def spec_platforms(entry, platforms)
+ non_ruby = platforms.any? do |_, pls|
+ pls.any? {|pl| pl != Gem::Platform::RUBY }
+ end
+
+ return unless non_ruby
+
+ if platforms.length == 1
+ title = platforms.values.length == 1 ? 'Platform' : 'Platforms'
+ entry << " #{title}: #{platforms.values.sort.join(', ')}\n"
+ else
+ entry << " Platforms:\n"
+
+ sorted_platforms = platforms.sort_by {|version,| version }
+
+ sorted_platforms.each do |version, pls|
+ label = " #{version}: "
+ data = format_text pls.sort.join(', '), 68, label.length
+ data[0, label.length] = label
+ entry << data << "\n"
+ end
+ end
+ end
+
+ def spec_summary(entry, spec)
+ summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
+ entry << "\n\n" << format_text(summary, 68, 4)
+ end
+
+end
diff --git a/lib/rubygems/rdoc.rb b/lib/rubygems/rdoc.rb
index 7043bd2a31..ac5e8f0822 100644
--- a/lib/rubygems/rdoc.rb
+++ b/lib/rubygems/rdoc.rb
@@ -1,335 +1,12 @@
# frozen_string_literal: true
-require 'rubygems'
-require 'rubygems/user_interaction'
-require 'fileutils'
-
-begin
- gem 'rdoc'
-rescue Gem::LoadError
- # swallow
-else
- # This will force any deps that 'rdoc' might have
- # (such as json) that are ambiguous to be activated, which
- # is important because we end up using Specification.reset
- # and we don't want the warning it pops out.
- Gem.finish_resolve
-end
-
-loaded_hook = false
+require_relative '../rubygems'
begin
require 'rdoc/rubygems_hook'
- loaded_hook = true
module Gem
RDoc = ::RDoc::RubygemsHook
end
+
+ Gem.done_installing(&Gem::RDoc.method(:generation_hook))
rescue LoadError
end
-
-##
-# Gem::RDoc provides methods to generate RDoc and ri data for installed gems.
-# It works for RDoc 1.0.1 (in Ruby 1.8) up to RDoc 3.6.
-#
-# This implementation is considered obsolete. The RDoc project is the
-# appropriate location to find this functionality. This file provides the
-# hooks to load RDoc generation code from the "rdoc" gem and a fallback in
-# case the installed version of RDoc does not have them.
-
-class Gem::RDoc # :nodoc: all
-
- include Gem::UserInteraction
- extend Gem::UserInteraction
-
- @rdoc_version = nil
- @specs = []
-
- ##
- # Force installation of documentation?
-
- attr_accessor :force
-
- ##
- # Generate rdoc?
-
- attr_accessor :generate_rdoc
-
- ##
- # Generate ri data?
-
- attr_accessor :generate_ri
-
- class << self
-
- ##
- # Loaded version of RDoc. Set by ::load_rdoc
-
- attr_reader :rdoc_version
-
- end
-
- ##
- # Post installs hook that generates documentation for each specification in
- # +specs+
-
- def self.generation_hook installer, specs
- start = Time.now
- types = installer.document
-
- generate_rdoc = types.include? 'rdoc'
- generate_ri = types.include? 'ri'
-
- specs.each do |spec|
- new(spec, generate_rdoc, generate_ri).generate
- end
-
- return unless generate_rdoc or generate_ri
-
- duration = (Time.now - start).to_i
- names = specs.map(&:name).join ', '
-
- say "Done installing documentation for #{names} after #{duration} seconds"
- end
-
- ##
- # Loads the RDoc generator
-
- def self.load_rdoc
- return if @rdoc_version
-
- require 'rdoc/rdoc'
-
- @rdoc_version = if ::RDoc.const_defined? :VERSION then
- Gem::Version.new ::RDoc::VERSION
- else
- Gem::Version.new '1.0.1'
- end
-
- rescue LoadError => e
- raise Gem::DocumentError, "RDoc is not installed: #{e}"
- end
-
- ##
- # Creates a new documentation generator for +spec+. RDoc and ri data
- # generation can be enabled or disabled through +generate_rdoc+ and
- # +generate_ri+ respectively.
- #
- # Only +generate_ri+ is enabled by default.
-
- def initialize spec, generate_rdoc = true, generate_ri = true
- @doc_dir = spec.doc_dir
- @file_info = nil
- @force = false
- @rdoc = nil
- @spec = spec
-
- @generate_rdoc = generate_rdoc
- @generate_ri = generate_ri
-
- @rdoc_dir = spec.doc_dir 'rdoc'
- @ri_dir = spec.doc_dir 'ri'
- end
-
- ##
- # Removes legacy rdoc arguments from +args+
- #--
- # TODO move to RDoc::Options
-
- def delete_legacy_args args
- args.delete '--inline-source'
- args.delete '--promiscuous'
- args.delete '-p'
- args.delete '--one-file'
- end
-
- ##
- # Generates documentation using the named +generator+ ("darkfish" or "ri")
- # and following the given +options+.
- #
- # Documentation will be generated into +destination+
-
- def document generator, options, destination
- generator_name = generator
-
- options = options.dup
- options.exclude ||= [] # TODO maybe move to RDoc::Options#finish
- options.setup_generator generator
- options.op_dir = destination
- options.finish
-
- generator = options.generator.new @rdoc.store, options
-
- @rdoc.options = options
- @rdoc.generator = generator
-
- say "Installing #{generator_name} documentation for #{@spec.full_name}"
-
- FileUtils.mkdir_p options.op_dir
-
- Dir.chdir options.op_dir do
- begin
- @rdoc.class.current = @rdoc
- @rdoc.generator.generate @file_info
- ensure
- @rdoc.class.current = nil
- end
- end
- end
-
- ##
- # Generates RDoc and ri data
-
- def generate
- return unless @generate_ri or @generate_rdoc
-
- setup
-
- options = nil
-
- if Gem::Requirement.new('< 3').satisfied_by? self.class.rdoc_version then
- generate_legacy
- return
- end
-
- ::RDoc::TopLevel.reset # TODO ::RDoc::RDoc.reset
- ::RDoc::Parser::C.reset
-
- args = @spec.rdoc_options
- args.concat @spec.source_paths
- args.concat @spec.extra_rdoc_files
-
- case config_args = Gem.configuration[:rdoc]
- when String then
- args = args.concat config_args.split
- when Array then
- args = args.concat config_args
- end
-
- delete_legacy_args args
-
- Dir.chdir @spec.full_gem_path do
- options = ::RDoc::Options.new
- options.default_title = "#{@spec.full_name} Documentation"
- options.parse args
- end
-
- options.quiet = !Gem.configuration.really_verbose
-
- @rdoc = new_rdoc
- @rdoc.options = options
-
- say "Parsing documentation for #{@spec.full_name}"
-
- Dir.chdir @spec.full_gem_path do
- @file_info = @rdoc.parse_files options.files
- end
-
- document 'ri', options, @ri_dir if
- @generate_ri and (@force or not File.exist? @ri_dir)
-
- document 'darkfish', options, @rdoc_dir if
- @generate_rdoc and (@force or not File.exist? @rdoc_dir)
- end
-
- ##
- # Generates RDoc and ri data for legacy RDoc versions. This method will not
- # exist in future versions.
-
- def generate_legacy
- if @generate_rdoc then
- FileUtils.rm_rf @rdoc_dir
- say "Installing RDoc documentation for #{@spec.full_name}"
- legacy_rdoc '--op', @rdoc_dir
- end
-
- if @generate_ri then
- FileUtils.rm_rf @ri_dir
- say "Installing ri documentation for #{@spec.full_name}"
- legacy_rdoc '--ri', '--op', @ri_dir
- end
- end
-
- ##
- # Generates RDoc using a legacy version of RDoc from the ARGV-like +args+.
- # This method will not exist in future versions.
-
- def legacy_rdoc *args
- args << @spec.rdoc_options
- args << '--quiet'
- args << @spec.require_paths.clone
- args << @spec.extra_rdoc_files
- args << '--title' << "#{@spec.full_name} Documentation"
- args = args.flatten.map do |arg| arg.to_s end
-
- delete_legacy_args args if
- Gem::Requirement.new('>= 2.4.0') =~ self.class.rdoc_version
-
- r = new_rdoc
- verbose { "rdoc #{args.join ' '}" }
-
- Dir.chdir @spec.full_gem_path do
- begin
- r.document args
- rescue Errno::EACCES => e
- dirname = File.dirname e.message.split("-")[1].strip
- raise Gem::FilePermissionError, dirname
- rescue Interrupt => e
- raise e
- rescue Exception => ex
- alert_error "While generating documentation for #{@spec.full_name}"
- ui.errs.puts "... MESSAGE: #{ex}"
- ui.errs.puts "... RDOC args: #{args.join(' ')}"
- ui.backtrace ex
- ui.errs.puts "(continuing with the rest of the installation)"
- end
- end
- end
-
- ##
- # #new_rdoc creates a new RDoc instance. This method is provided only to
- # make testing easier.
-
- def new_rdoc # :nodoc:
- ::RDoc::RDoc.new
- end
-
- ##
- # Is rdoc documentation installed?
-
- def rdoc_installed?
- File.exist? @rdoc_dir
- end
-
- ##
- # Removes generated RDoc and ri data
-
- def remove
- base_dir = @spec.base_dir
-
- raise Gem::FilePermissionError, base_dir unless File.writable? base_dir
-
- FileUtils.rm_rf @rdoc_dir
- FileUtils.rm_rf @ri_dir
- end
-
- ##
- # Is ri data installed?
-
- def ri_installed?
- File.exist? @ri_dir
- end
-
- ##
- # Prepares the spec for documentation generation
-
- def setup
- self.class.load_rdoc
-
- raise Gem::FilePermissionError, @doc_dir if
- File.exist?(@doc_dir) and not File.writable?(@doc_dir)
-
- FileUtils.mkdir_p @doc_dir unless File.exist? @doc_dir
- end
-
-end unless loaded_hook
-
-Gem.done_installing(&Gem::RDoc.method(:generation_hook))
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb
index 8f0cf0b402..de6f88f39a 100644
--- a/lib/rubygems/remote_fetcher.rb
+++ b/lib/rubygems/remote_fetcher.rb
@@ -1,17 +1,17 @@
# frozen_string_literal: true
-require 'rubygems'
-require 'rubygems/request'
-require 'rubygems/uri_formatter'
-require 'rubygems/user_interaction'
-require 'rubygems/request/connection_pools'
-require 'resolv'
+require_relative '../rubygems'
+require_relative 'request'
+require_relative 'request/connection_pools'
+require_relative 's3_uri_signer'
+require_relative 'uri_formatter'
+require_relative 'uri'
+require_relative 'user_interaction'
##
# RemoteFetcher handles the details of fetching gems and gem information from
# a remote source.
class Gem::RemoteFetcher
-
include Gem::UserInteraction
##
@@ -19,27 +19,23 @@ class Gem::RemoteFetcher
# that could happen while downloading from the internet.
class FetchError < Gem::Exception
-
##
# The URI which was being accessed when the exception happened.
- attr_accessor :uri
+ attr_accessor :uri, :original_uri
def initialize(message, uri)
- super message
- begin
- uri = URI(uri)
- uri.password = 'REDACTED' if uri.password
- @uri = uri.to_s
- rescue URI::InvalidURIError, ArgumentError
- @uri = uri
- end
+ uri = Gem::Uri.new(uri)
+
+ super uri.redact_credentials_from(message)
+
+ @original_uri = uri.to_s
+ @uri = uri.redacted.to_s
end
def to_s # :nodoc:
"#{super} (#{uri})"
end
-
end
##
@@ -48,6 +44,7 @@ class Gem::RemoteFetcher
class UnknownHostError < FetchError
end
+ deprecate_constant(:UnknownHostError)
@fetcher = nil
@@ -71,68 +68,40 @@ class Gem::RemoteFetcher
# HTTP_PROXY_PASS)
# * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy
#
- # +dns+: An object to use for DNS resolution of the API endpoint.
- # By default, use Resolv::DNS.
- #
# +headers+: A set of additional HTTP headers to be sent to the server when
# fetching the gem.
- def initialize(proxy=nil, dns=Resolv::DNS.new, headers={})
+ def initialize(proxy=nil, dns=nil, headers={})
+ require_relative 'core_ext/tcpsocket_init' if Gem.configuration.ipv4_fallback_enabled
require 'net/http'
require 'stringio'
- require 'time'
require 'uri'
Socket.do_not_reverse_lookup = true
@proxy = proxy
@pools = {}
- @pool_lock = Mutex.new
+ @pool_lock = Thread::Mutex.new
@cert_files = Gem::Request.get_cert_files
- @dns = dns
@headers = headers
end
##
- # Given a source at +uri+, calculate what hostname to actually
- # connect to query the data for it.
-
- def api_endpoint(uri)
- host = uri.host
-
- begin
- res = @dns.getresource "_rubygems._tcp.#{host}",
- Resolv::DNS::Resource::IN::SRV
- rescue Resolv::ResolvError => e
- verbose "Getting SRV record failed: #{e}"
- uri
- else
- target = res.target.to_s.strip
-
- if URI("http://" + target).host.end_with?(".#{host}")
- return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
- end
-
- uri
- end
- end
-
- ##
# Given a name and requirement, downloads this gem into cache and returns the
# filename. Returns nil if the gem cannot be located.
#--
# Should probably be integrated with #download below, but that will be a
# larger, more encompassing effort. -erikh
- def download_to_cache dependency
+ def download_to_cache(dependency)
found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency
return if found.empty?
- spec, source = found.max_by { |(s,_)| s.version }
+ spec, source = found.max_by {|(s,_)| s.version }
- download spec, source.uri.to_s
+ download spec, source.uri
end
##
@@ -141,11 +110,12 @@ class Gem::RemoteFetcher
# always replaced.
def download(spec, source_uri, install_dir = Gem.dir)
+ install_cache_dir = File.join install_dir, "cache"
cache_dir =
- if Dir.pwd == install_dir then # see fetch_command
+ if Dir.pwd == install_dir # see fetch_command
install_dir
- elsif File.writable? install_dir then
- File.join install_dir, "cache"
+ elsif File.writable?(install_cache_dir) || (File.writable?(install_dir) && (not File.exist?(install_cache_dir)))
+ install_cache_dir
else
File.join Gem.user_dir, "cache"
end
@@ -153,22 +123,10 @@ class Gem::RemoteFetcher
gem_file_name = File.basename spec.cache_file
local_gem_path = File.join cache_dir, gem_file_name
+ require "fileutils"
FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
- # Always escape URI's to deal with potential spaces and such
- # It should also be considered that source_uri may already be
- # a valid URI with escaped characters. e.g. "{DESede}" is encoded
- # as "%7BDESede%7D". If this is escaped again the percentage
- # symbols will be escaped.
- unless source_uri.is_a?(URI::Generic)
- begin
- source_uri = URI.parse(source_uri)
- rescue
- source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ?
- URI::DEFAULT_PARSER.escape(source_uri.to_s) :
- URI.escape(source_uri.to_s))
- end
- end
+ source_uri = Gem::Uri.new(source_uri)
scheme = source_uri.scheme
@@ -179,14 +137,14 @@ class Gem::RemoteFetcher
# REFACTOR: be sure to clean up fake fetcher when you do this... cleaner
case scheme
when 'http', 'https', 's3' then
- unless File.exist? local_gem_path then
+ unless File.exist? local_gem_path
begin
verbose "Downloading gem #{gem_file_name}"
remote_gem_path = source_uri + "gems/#{gem_file_name}"
self.cache_update_path remote_gem_path, local_gem_path
- rescue Gem::RemoteFetcher::FetchError
+ rescue FetchError
raise if spec.original_platform == spec.platform
alternate_name = "#{spec.original_name}.gem"
@@ -203,7 +161,7 @@ class Gem::RemoteFetcher
path = source_uri.path
path = File.dirname(path) if File.extname(path) == '.gem'
- remote_gem_path = correct_for_windows_path(File.join(path, 'gems', gem_file_name))
+ remote_gem_path = Gem::Util.correct_for_windows_path(File.join(path, 'gems', gem_file_name))
FileUtils.cp(remote_gem_path, local_gem_path)
rescue Errno::EACCES
@@ -213,7 +171,7 @@ class Gem::RemoteFetcher
verbose "Using local gem #{local_gem_path}"
when nil then # TODO test for local overriding cache
source_path = if Gem.win_platform? && source_uri.scheme &&
- !source_uri.path.include?(':') then
+ !source_uri.path.include?(':')
"#{source_uri.scheme}:#{source_uri.path}"
else
source_uri.path
@@ -239,22 +197,22 @@ class Gem::RemoteFetcher
##
# File Fetcher. Dispatched by +fetch_path+. Use it instead.
- def fetch_file uri, *_
- Gem.read_binary correct_for_windows_path uri.path
+ def fetch_file(uri, *_)
+ Gem.read_binary Gem::Util.correct_for_windows_path uri.path
end
##
# HTTP Fetcher. Dispatched by +fetch_path+. Use it instead.
- def fetch_http uri, last_modified = nil, head = false, depth = 0
+ def fetch_http(uri, last_modified = nil, head = false, depth = 0)
fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
response = request uri, fetch_type, last_modified do |req|
- headers.each { |k,v| req.add_field(k,v) }
+ headers.each {|k,v| req.add_field(k,v) }
end
case response
when Net::HTTPOK, Net::HTTPNotModified then
- response.uri = uri if response.respond_to? :uri
+ response.uri = uri
head ? response : response.body
when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
Net::HTTPTemporaryRedirect then
@@ -263,7 +221,7 @@ class Gem::RemoteFetcher
unless location = response['Location']
raise FetchError.new("redirecting but no redirect location was given", uri)
end
- location = URI.parse response['Location']
+ location = Gem::Uri.new location
if https?(uri) && !https?(location)
raise FetchError.new("redirecting to non-https resource: #{location}", uri)
@@ -281,9 +239,7 @@ class Gem::RemoteFetcher
# Downloads +uri+ and returns it as a String.
def fetch_path(uri, mtime = nil, head = false)
- uri = URI.parse uri unless URI::Generic === uri
-
- raise ArgumentError, "bad uri: #{uri}" unless uri
+ uri = Gem::Uri.new uri
unless uri.scheme
raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}"
@@ -291,37 +247,39 @@ class Gem::RemoteFetcher
data = send "fetch_#{uri.scheme}", uri, mtime, head
- if data and !head and uri.to_s =~ /\.gz$/
+ if data and !head and uri.to_s.end_with?(".gz")
begin
- data = Gem.gunzip data
+ data = Gem::Util.gunzip data
rescue Zlib::GzipFile::Error
- raise FetchError.new("server did not return a valid file", uri.to_s)
+ raise FetchError.new("server did not return a valid file", uri)
end
end
data
- rescue FetchError
- raise
- rescue Timeout::Error
- raise UnknownHostError.new('timed out', uri.to_s)
- rescue IOError, SocketError, SystemCallError => e
- if e.message =~ /getaddrinfo/
- raise UnknownHostError.new('no such name', uri.to_s)
- else
- raise FetchError.new("#{e.class}: #{e}", uri.to_s)
- end
+ rescue Timeout::Error, IOError, SocketError, SystemCallError,
+ *(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e
+ raise FetchError.new("#{e.class}: #{e}", uri)
end
def fetch_s3(uri, mtime = nil, head = false)
- public_uri = sign_s3_url(uri)
+ begin
+ public_uri = s3_uri_signer(uri).sign
+ rescue Gem::S3URISigner::ConfigurationError, Gem::S3URISigner::InstanceProfileError => e
+ raise FetchError.new(e.message, "s3://#{uri.host}")
+ end
fetch_https public_uri, mtime, head
end
+ # we have our own signing code here to avoid a dependency on the aws-sdk gem
+ def s3_uri_signer(uri)
+ Gem::S3URISigner.new(uri)
+ end
+
##
# Downloads +uri+ to +path+ if necessary. If no path is given, it just
# passes the data.
- def cache_update_path uri, path = nil, update = true
+ def cache_update_path(uri, path = nil, update = true)
mtime = path && File.stat(path).mtime rescue nil
data = fetch_path(uri, mtime)
@@ -338,23 +296,6 @@ class Gem::RemoteFetcher
end
##
- # Returns the size of +uri+ in bytes.
-
- def fetch_size(uri) # TODO: phase this out
- response = fetch_path(uri, nil, true)
-
- response['content-length'].to_i
- end
-
- def correct_for_windows_path(path)
- if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
- path[1..-1]
- else
- path
- end
- end
-
- ##
# Performs a Net::HTTP request of type +request_class+ on +uri+ returning
# a Net::HTTP response object. request maintains a table of persistent
# connections to reduce connect overhead.
@@ -375,43 +316,16 @@ class Gem::RemoteFetcher
end
def close_all
- @pools.each_value {|pool| pool.close_all}
- end
-
- protected
-
- # we have our own signing code here to avoid a dependency on the aws-sdk gem
- # fortunately, a simple GET request isn't too complex to sign properly
- def sign_s3_url(uri, expiration = nil)
- require 'base64'
- require 'openssl'
-
- unless uri.user && uri.password
- raise FetchError.new("credentials needed in s3 source, like s3://key:secret@bucket-name/", uri.to_s)
- end
-
- expiration ||= s3_expiration
- canonical_path = "/#{uri.host}#{uri.path}"
- payload = "GET\n\n\n#{expiration}\n#{canonical_path}"
- digest = OpenSSL::HMAC.digest('sha1', uri.password, payload)
- # URI.escape is deprecated, and there isn't yet a replacement that does quite what we want
- signature = Base64.encode64(digest).gsub("\n", '').gsub(/[\+\/=]/) { |c| BASE64_URI_TRANSLATE[c] }
- URI.parse("https://#{uri.host}.s3.amazonaws.com#{uri.path}?AWSAccessKeyId=#{uri.user}&Expires=#{expiration}&Signature=#{signature}")
+ @pools.each_value {|pool| pool.close_all }
end
- def s3_expiration
- (Time.now + 3600).to_i # one hour from now
- end
-
- BASE64_URI_TRANSLATE = { '+' => '%2B', '/' => '%2F', '=' => '%3D' }.freeze
-
private
- def proxy_for proxy, uri
+ def proxy_for(proxy, uri)
Gem::Request.proxy_uri(proxy || Gem::Request.get_proxy_from_env(uri.scheme))
end
- def pools_for proxy
+ def pools_for(proxy)
@pool_lock.synchronize do
@pools[proxy] ||= Gem::Request::ConnectionPools.new proxy, @cert_files
end
diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb
index 81699b98fe..d6100c914b 100644
--- a/lib/rubygems/request.rb
+++ b/lib/rubygems/request.rb
@@ -1,25 +1,23 @@
# frozen_string_literal: true
require 'net/http'
-require 'thread'
-require 'time'
-require 'rubygems/user_interaction'
+require_relative 'user_interaction'
class Gem::Request
-
extend Gem::UserInteraction
include Gem::UserInteraction
###
# Legacy. This is used in tests.
- def self.create_with_proxy uri, request_class, last_modified, proxy # :nodoc:
+ def self.create_with_proxy(uri, request_class, last_modified, proxy) # :nodoc:
cert_files = get_cert_files
proxy ||= get_proxy_from_env(uri.scheme)
- pool = ConnectionPools.new proxy_uri(proxy), cert_files
+ pool = ConnectionPools.new proxy_uri(proxy), cert_files
new(uri, request_class, last_modified, pool.pool_for(uri))
end
- def self.proxy_uri proxy # :nodoc:
+ def self.proxy_uri(proxy) # :nodoc:
+ require "uri"
case proxy
when :no_proxy then nil
when URI::HTTP then proxy
@@ -46,13 +44,14 @@ class Gem::Request
end
def self.configure_connection_for_https(connection, cert_files)
- require 'net/https'
+ raise Gem::Exception.new('OpenSSL is not available. Install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources') unless Gem::HAVE_OPENSSL
+
connection.use_ssl = true
connection.verify_mode =
Gem.configuration.ssl_verify_mode || OpenSSL::SSL::VERIFY_PEER
store = OpenSSL::X509::Store.new
- if Gem.configuration.ssl_client_cert then
+ if Gem.configuration.ssl_client_cert
pem = File.read Gem.configuration.ssl_client_cert
connection.cert = OpenSSL::X509::Certificate.new pem
connection.key = OpenSSL::PKey::RSA.new pem
@@ -78,15 +77,9 @@ class Gem::Request
end
connection
- rescue LoadError => e
- raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
- e.message =~ / -- openssl$/
-
- raise Gem::Exception.new(
- 'Unable to require openssl, install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources')
end
- def self.verify_certificate store_context
+ def self.verify_certificate(store_context)
depth = store_context.error_depth
error = store_context.error_string
number = store_context.error
@@ -99,12 +92,14 @@ class Gem::Request
ui.alert_error extra_message if extra_message
end
- def self.verify_certificate_message error_number, cert
+ def self.verify_certificate_message(error_number, cert)
return unless cert
case error_number
when OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED then
+ require 'time'
"Certificate #{cert.subject} expired at #{cert.not_after.iso8601}"
when OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID then
+ require 'time'
"Certificate #{cert.subject} not valid until #{cert.not_before.iso8601}"
when OpenSSL::X509::V_ERR_CERT_REJECTED then
"Certificate #{cert.subject} is rejected"
@@ -118,9 +113,11 @@ class Gem::Request
"Certificate #{cert.subject} has an invalid purpose"
when OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN then
"Root certificate is not trusted (#{cert.subject})"
- when OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
- OpenSSL::X509::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE then
+ when OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY then
"You must add #{cert.issuer} to your local trusted store"
+ when
+ OpenSSL::X509::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE then
+ "Cannot verify certificate issued by #{cert.issuer}"
end
end
@@ -130,7 +127,7 @@ class Gem::Request
def connection_for(uri)
@connection_pool.checkout
- rescue defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : Errno::EHOSTDOWN,
+ rescue Gem::HAVE_OPENSSL ? OpenSSL::SSL::SSLError : Errno::EHOSTDOWN,
Errno::EHOSTDOWN => e
raise Gem::RemoteFetcher::FetchError.new(e.message, uri)
end
@@ -138,7 +135,7 @@ class Gem::Request
def fetch
request = @request_class.new @uri.request_uri
- unless @uri.nil? || @uri.user.nil? || @uri.user.empty? then
+ unless @uri.nil? || @uri.user.nil? || @uri.user.empty?
request.basic_auth Gem::UriFormatter.new(@uri.user).unescape,
Gem::UriFormatter.new(@uri.password).unescape
end
@@ -147,7 +144,8 @@ class Gem::Request
request.add_field 'Connection', 'keep-alive'
request.add_field 'Keep-Alive', '30'
- if @last_modified then
+ if @last_modified
+ require 'time'
request.add_field 'If-Modified-Since', @last_modified.httpdate
end
@@ -160,19 +158,22 @@ class Gem::Request
# Returns a proxy URI for the given +scheme+ if one is set in the
# environment variables.
- def self.get_proxy_from_env scheme = 'http'
+ def self.get_proxy_from_env(scheme = 'http')
_scheme = scheme.downcase
_SCHEME = scheme.upcase
env_proxy = ENV["#{_scheme}_proxy"] || ENV["#{_SCHEME}_PROXY"]
no_env_proxy = env_proxy.nil? || env_proxy.empty?
- return get_proxy_from_env 'http' if no_env_proxy and _scheme != 'http'
- return :no_proxy if no_env_proxy
+ if no_env_proxy
+ return (_scheme == 'https' || _scheme == 'http') ?
+ :no_proxy : get_proxy_from_env('http')
+ end
+ require "uri"
uri = URI(Gem::UriFormatter.new(env_proxy).normalize)
- if uri and uri.user.nil? and uri.password.nil? then
+ if uri and uri.user.nil? and uri.password.nil?
user = ENV["#{_scheme}_proxy_user"] || ENV["#{_SCHEME}_PROXY_USER"]
password = ENV["#{_scheme}_proxy_pass"] || ENV["#{_SCHEME}_PROXY_PASS"]
@@ -183,7 +184,7 @@ class Gem::Request
uri
end
- def perform_request request # :nodoc:
+ def perform_request(request) # :nodoc:
connection = connection_for @uri
retried = false
@@ -192,7 +193,7 @@ class Gem::Request
begin
@requests[connection.object_id] += 1
- verbose "#{request.method} #{@uri}"
+ verbose "#{request.method} #{Gem::Uri.new(@uri).redacted}"
file_name = File.basename(@uri.path)
# perform download progress reporter only for gems
@@ -275,20 +276,19 @@ class Gem::Request
ruby_version += 'dev' if RUBY_PATCHLEVEL == -1
ua << " Ruby/#{ruby_version} (#{RUBY_RELEASE_DATE}"
- if RUBY_PATCHLEVEL >= 0 then
+ if RUBY_PATCHLEVEL >= 0
ua << " patchlevel #{RUBY_PATCHLEVEL}"
- elsif defined?(RUBY_REVISION) then
+ elsif defined?(RUBY_REVISION)
ua << " revision #{RUBY_REVISION}"
end
ua << ")"
- ua << " #{RUBY_ENGINE}" if defined?(RUBY_ENGINE) and RUBY_ENGINE != 'ruby'
+ ua << " #{RUBY_ENGINE}" if RUBY_ENGINE != 'ruby'
ua
end
-
end
-require 'rubygems/request/http_pool'
-require 'rubygems/request/https_pool'
-require 'rubygems/request/connection_pools'
+require_relative 'request/http_pool'
+require_relative 'request/https_pool'
+require_relative 'request/connection_pools'
diff --git a/lib/rubygems/request/connection_pools.rb b/lib/rubygems/request/connection_pools.rb
index 31fc609800..a4c2929b38 100644
--- a/lib/rubygems/request/connection_pools.rb
+++ b/lib/rubygems/request/connection_pools.rb
@@ -1,27 +1,25 @@
# frozen_string_literal: true
-require 'thread'
class Gem::Request::ConnectionPools # :nodoc:
-
@client = Net::HTTP
class << self
attr_accessor :client
end
- def initialize proxy_uri, cert_files
+ def initialize(proxy_uri, cert_files)
@proxy_uri = proxy_uri
@cert_files = cert_files
@pools = {}
- @pool_mutex = Mutex.new
+ @pool_mutex = Thread::Mutex.new
end
- def pool_for uri
+ def pool_for(uri)
http_args = net_http_args(uri, @proxy_uri)
key = http_args + [https?(uri)]
@pool_mutex.synchronize do
@pools[key] ||=
- if https? uri then
+ if https? uri
Gem::Request::HTTPSPool.new(http_args, @cert_files, @proxy_uri)
else
Gem::Request::HTTPPool.new(http_args, @cert_files, @proxy_uri)
@@ -30,7 +28,7 @@ class Gem::Request::ConnectionPools # :nodoc:
end
def close_all
- @pools.each_value {|pool| pool.close_all}
+ @pools.each_value {|pool| pool.close_all }
end
private
@@ -41,35 +39,46 @@ class Gem::Request::ConnectionPools # :nodoc:
def get_no_proxy_from_env
env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
- return [] if env_no_proxy.nil? or env_no_proxy.empty?
+ return [] if env_no_proxy.nil? or env_no_proxy.empty?
env_no_proxy.split(/\s*,\s*/)
end
- def https? uri
+ def https?(uri)
uri.scheme.downcase == 'https'
end
- def no_proxy? host, env_no_proxy
+ def no_proxy?(host, env_no_proxy)
host = host.downcase
env_no_proxy.any? do |pattern|
- pattern = pattern.downcase
+ env_no_proxy_pattern = pattern.downcase.dup
+
+ # Remove dot in front of pattern for wildcard matching
+ env_no_proxy_pattern[0] = "" if env_no_proxy_pattern[0] == "."
+
+ host_tokens = host.split(".")
+ pattern_tokens = env_no_proxy_pattern.split(".")
+
+ intersection = (host_tokens - pattern_tokens) | (pattern_tokens - host_tokens)
- host[-pattern.length, pattern.length] == pattern or
- (pattern.start_with? '.' and pattern[1..-1] == host)
+ # When we do the split into tokens we miss a dot character, so add it back if we need it
+ missing_dot = intersection.length > 0 ? 1 : 0
+ start = intersection.join(".").size + missing_dot
+
+ no_proxy_host = host[start..-1]
+
+ env_no_proxy_pattern == no_proxy_host
end
end
- def net_http_args uri, proxy_uri
- # URI::Generic#hostname was added in ruby 1.9.3, use it if exists, otherwise
- # don't support IPv6 literals and use host.
- hostname = uri.respond_to?(:hostname) ? uri.hostname : uri.host
+ def net_http_args(uri, proxy_uri)
+ hostname = uri.hostname
net_http_args = [hostname, uri.port]
no_proxy = get_no_proxy_from_env
- if proxy_uri and not no_proxy?(hostname, no_proxy) then
+ if proxy_uri and not no_proxy?(hostname, no_proxy)
proxy_hostname = proxy_uri.respond_to?(:hostname) ? proxy_uri.hostname : proxy_uri.host
net_http_args + [
proxy_hostname,
@@ -77,12 +86,10 @@ class Gem::Request::ConnectionPools # :nodoc:
Gem::UriFormatter.new(proxy_uri.user).unescape,
Gem::UriFormatter.new(proxy_uri.password).unescape,
]
- elsif no_proxy? hostname, no_proxy then
+ elsif no_proxy? hostname, no_proxy
net_http_args + [nil, nil]
else
net_http_args
end
end
-
end
-
diff --git a/lib/rubygems/request/http_pool.rb b/lib/rubygems/request/http_pool.rb
index bfcd15399d..f028516db8 100644
--- a/lib/rubygems/request/http_pool.rb
+++ b/lib/rubygems/request/http_pool.rb
@@ -8,11 +8,11 @@
class Gem::Request::HTTPPool # :nodoc:
attr_reader :cert_files, :proxy_uri
- def initialize http_args, cert_files, proxy_uri
+ def initialize(http_args, cert_files, proxy_uri)
@http_args = http_args
@cert_files = cert_files
@proxy_uri = proxy_uri
- @queue = SizedQueue.new 1
+ @queue = Thread::SizedQueue.new 1
@queue << nil
end
@@ -20,7 +20,7 @@ class Gem::Request::HTTPPool # :nodoc:
@queue.pop || make_connection
end
- def checkin connection
+ def checkin(connection)
@queue.push connection
end
@@ -39,10 +39,8 @@ class Gem::Request::HTTPPool # :nodoc:
setup_connection Gem::Request::ConnectionPools.client.new(*@http_args)
end
- def setup_connection connection
+ def setup_connection(connection)
connection.start
connection
end
-
end
-
diff --git a/lib/rubygems/request/https_pool.rb b/lib/rubygems/request/https_pool.rb
index e82c2440e1..50f42d9e0d 100644
--- a/lib/rubygems/request/https_pool.rb
+++ b/lib/rubygems/request/https_pool.rb
@@ -2,10 +2,8 @@
class Gem::Request::HTTPSPool < Gem::Request::HTTPPool # :nodoc:
private
- def setup_connection connection
+ def setup_connection(connection)
Gem::Request.configure_connection_for_https(connection, @cert_files)
super
end
end
-
-
diff --git a/lib/rubygems/request_set.rb b/lib/rubygems/request_set.rb
index 95a8eed1af..01b01599a8 100644
--- a/lib/rubygems/request_set.rb
+++ b/lib/rubygems/request_set.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require 'tsort'
+require_relative 'tsort'
##
# A RequestSet groups a request to activate a set of dependencies.
@@ -15,8 +15,7 @@ require 'tsort'
# #=> ["nokogiri-1.6.0", "mini_portile-0.5.1", "pg-0.17.0"]
class Gem::RequestSet
-
- include TSort
+ include Gem::TSort
##
# Array of gems to install even if already installed
@@ -91,7 +90,7 @@ class Gem::RequestSet
#
# set = Gem::RequestSet.new nokogiri, pg
- def initialize *deps
+ def initialize(*deps)
@dependencies = deps
@always_install = []
@@ -119,8 +118,8 @@ class Gem::RequestSet
##
# Declare that a gem of name +name+ with +reqs+ requirements is needed.
- def gem name, *reqs
- if dep = @dependency_names[name] then
+ def gem(name, *reqs)
+ if dep = @dependency_names[name]
dep.requirement.concat reqs
else
dep = Gem::Dependency.new name, *reqs
@@ -132,7 +131,7 @@ class Gem::RequestSet
##
# Add +deps+ Gem::Dependency objects to the set.
- def import deps
+ def import(deps)
@dependencies.concat deps
end
@@ -143,7 +142,7 @@ class Gem::RequestSet
# The +installer+ will be +nil+ if a gem matching the request was already
# installed.
- def install options, &block # :yields: request, installer
+ def install(options, &block) # :yields: request, installer
if dir = options[:install_dir]
requests = install_into dir, false, options, &block
return requests
@@ -152,12 +151,39 @@ class Gem::RequestSet
@prerelease = options[:prerelease]
requests = []
+ download_queue = Thread::Queue.new
+
+ # Create a thread-safe list of gems to download
+ sorted_requests.each do |req|
+ download_queue << req
+ end
+
+ # Create N threads in a pool, have them download all the gems
+ threads = Gem.configuration.concurrent_downloads.times.map do
+ # When a thread pops this item, it knows to stop running. The symbol
+ # is queued here so that there will be one symbol per thread.
+ download_queue << :stop
+
+ Thread.new do
+ # The pop method will block waiting for items, so the only way
+ # to stop a thread from running is to provide a final item that
+ # means the thread should stop.
+ while req = download_queue.pop
+ break if req == :stop
+ req.spec.download options unless req.installed?
+ end
+ end
+ end
+
+ # Wait for all the downloads to finish before continuing
+ threads.each(&:value)
+ # Install requested gems after they have been downloaded
sorted_requests.each do |req|
- if req.installed? then
+ if req.installed?
req.spec.spec.build_extensions
- if @always_install.none? { |spec| spec == req.spec.spec } then
+ if @always_install.none? {|spec| spec == req.spec.spec }
yield req, nil if block_given?
next
end
@@ -169,17 +195,8 @@ class Gem::RequestSet
yield req, installer if block_given?
end
rescue Gem::RuntimeRequirementNotMetError => e
- recent_match = req.spec.set.find_all(req.request).sort_by(&:version).reverse_each.find do |s|
- s = s.spec
- s.required_ruby_version.satisfied_by?(Gem.ruby_version) && s.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
- end
- if recent_match
- suggestion = "The last version of #{req.request} to support your Ruby & RubyGems was #{recent_match.version}. Try installing it with `gem install #{recent_match.name} -v #{recent_match.version}`"
- suggestion += " and then running the current command again" unless @always_install.include?(req.spec.spec)
- else
- suggestion = "There are no versions of #{req.request} compatible with your Ruby & RubyGems"
- suggestion += ". Maybe try installing an older version of the gem you're looking for?" unless @always_install.include?(req.spec.spec)
- end
+ suggestion = "There are no versions of #{req.request} compatible with your Ruby & RubyGems"
+ suggestion += ". Maybe try installing an older version of the gem you're looking for?" unless @always_install.include?(req.spec.spec)
e.suggestion = suggestion
raise
end
@@ -189,22 +206,7 @@ class Gem::RequestSet
return requests if options[:gemdeps]
- specs = requests.map do |request|
- case request
- when Gem::Resolver::ActivationRequest then
- request.spec.spec
- else
- request
- end
- end
-
- require 'rubygems/dependency_installer'
- inst = Gem::DependencyInstaller.new options
- inst.installed_gems.replace specs
-
- Gem.done_installing_hooks.each do |hook|
- hook.call inst, specs
- end unless Gem.done_installing_hooks.empty?
+ install_hooks requests, options
requests
end
@@ -216,7 +218,7 @@ class Gem::RequestSet
# If +:without_groups+ is given in the +options+, those groups in the gem
# dependencies file are not used. See Gem::Installer for other +options+.
- def install_from_gemdeps options, &block
+ def install_from_gemdeps(options, &block)
gemdeps = options[:gemdeps]
@install_dir = options[:install_dir] || Gem.dir
@@ -241,7 +243,7 @@ class Gem::RequestSet
else
installed = install options, &block
- if options.fetch :lock, true then
+ if options.fetch :lock, true
lockfile =
Gem::RequestSet::Lockfile.build self, gemdeps, gem_deps_api.dependencies
lockfile.write
@@ -251,11 +253,11 @@ class Gem::RequestSet
end
end
- def install_into dir, force = true, options = {}
+ def install_into(dir, force = true, options = {})
gem_home, ENV['GEM_HOME'] = ENV['GEM_HOME'], dir
existing = force ? [] : specs_in(dir)
- existing.delete_if { |s| @always_install.include? s }
+ existing.delete_if {|s| @always_install.include? s }
dir = File.expand_path dir
@@ -269,7 +271,7 @@ class Gem::RequestSet
sorted_requests.each do |request|
spec = request.spec
- if existing.find { |s| s.full_name == spec.full_name } then
+ if existing.find {|s| s.full_name == spec.full_name }
yield request, nil if block_given?
next
end
@@ -281,22 +283,46 @@ class Gem::RequestSet
installed << request
end
+ install_hooks installed, options
+
installed
ensure
ENV['GEM_HOME'] = gem_home
end
##
+ # Call hooks on installed gems
+
+ def install_hooks(requests, options)
+ specs = requests.map do |request|
+ case request
+ when Gem::Resolver::ActivationRequest then
+ request.spec.spec
+ else
+ request
+ end
+ end
+
+ require_relative "dependency_installer"
+ inst = Gem::DependencyInstaller.new options
+ inst.installed_gems.replace specs
+
+ Gem.done_installing_hooks.each do |hook|
+ hook.call inst, specs
+ end unless Gem.done_installing_hooks.empty?
+ end
+
+ ##
# Load a dependency management file.
- def load_gemdeps path, without_groups = [], installing = false
+ def load_gemdeps(path, without_groups = [], installing = false)
@git_set = Gem::Resolver::GitSet.new
@vendor_set = Gem::Resolver::VendorSet.new
@source_set = Gem::Resolver::SourceSet.new
@git_set.root_dir = @install_dir
- lock_file = "#{File.expand_path(path)}.lock".dup.untaint
+ lock_file = "#{File.expand_path(path)}.lock".dup.tap(&Gem::UNTAINT)
begin
tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file lock_file
parser = tokenizer.make_parser self, []
@@ -310,29 +336,29 @@ class Gem::RequestSet
gf.load
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[RequestSet:', ']' do
q.breakable
- if @remote then
+ if @remote
q.text 'remote'
q.breakable
end
- if @prerelease then
+ if @prerelease
q.text 'prerelease'
q.breakable
end
- if @development_shallow then
+ if @development_shallow
q.text 'shallow development'
q.breakable
- elsif @development then
+ elsif @development
q.text 'development'
q.breakable
end
- if @soft_missing then
+ if @soft_missing
q.text 'soft missing'
end
@@ -348,7 +374,7 @@ class Gem::RequestSet
q.text 'sets:'
q.breakable
- q.pp @sets.map { |set| set.class }
+ q.pp @sets.map {|set| set.class }
end
end
@@ -356,7 +382,7 @@ class Gem::RequestSet
# Resolve the requested dependencies and return an Array of Specification
# objects to be activated.
- def resolve set = Gem::Resolver::BestSet.new
+ def resolve(set = Gem::Resolver::BestSet.new)
@sets << set
@sets << @git_set
@sets << @vendor_set
@@ -402,28 +428,28 @@ class Gem::RequestSet
end
def specs
- @specs ||= @requests.map { |r| r.full_spec }
+ @specs ||= @requests.map {|r| r.full_spec }
end
- def specs_in dir
- Dir["#{dir}/specifications/*.gemspec"].map do |g|
+ def specs_in(dir)
+ Gem::Util.glob_files_in_dir("*.gemspec", File.join(dir, "specifications")).map do |g|
Gem::Specification.load g
end
end
- def tsort_each_node &block # :nodoc:
+ def tsort_each_node(&block) # :nodoc:
@requests.each(&block)
end
- def tsort_each_child node # :nodoc:
+ def tsort_each_child(node) # :nodoc:
node.spec.dependencies.each do |dep|
next if dep.type == :development and not @development
- match = @requests.find { |r|
+ match = @requests.find do |r|
dep.match? r.spec.name, r.spec.version, @prerelease
- }
+ end
- unless match then
+ unless match
next if dep.type == :development and @development_shallow
next if @soft_missing
raise Gem::DependencyError,
@@ -433,9 +459,8 @@ class Gem::RequestSet
yield match
end
end
-
end
-require 'rubygems/request_set/gem_dependency_api'
-require 'rubygems/request_set/lockfile'
-require 'rubygems/request_set/lockfile/tokenizer'
+require_relative 'request_set/gem_dependency_api'
+require_relative 'request_set/lockfile'
+require_relative 'request_set/lockfile/tokenizer'
diff --git a/lib/rubygems/request_set/gem_dependency_api.rb b/lib/rubygems/request_set/gem_dependency_api.rb
index 867086cc0e..7188b07346 100644
--- a/lib/rubygems/request_set/gem_dependency_api.rb
+++ b/lib/rubygems/request_set/gem_dependency_api.rb
@@ -31,7 +31,6 @@
# See `gem help install` and `gem help gem_dependencies` for further details.
class Gem::RequestSet::GemDependencyAPI
-
ENGINE_MAP = { # :nodoc:
:jruby => %w[jruby],
:jruby_18 => %w[jruby],
@@ -43,12 +42,13 @@ class Gem::RequestSet::GemDependencyAPI
:mri_20 => %w[ruby],
:mri_21 => %w[ruby],
:rbx => %w[rbx],
- :ruby => %w[ruby rbx maglev],
- :ruby_18 => %w[ruby rbx maglev],
- :ruby_19 => %w[ruby rbx maglev],
- :ruby_20 => %w[ruby rbx maglev],
- :ruby_21 => %w[ruby rbx maglev],
- }
+ :truffleruby => %w[truffleruby],
+ :ruby => %w[ruby rbx maglev truffleruby],
+ :ruby_18 => %w[ruby rbx maglev truffleruby],
+ :ruby_19 => %w[ruby rbx maglev truffleruby],
+ :ruby_20 => %w[ruby rbx maglev truffleruby],
+ :ruby_21 => %w[ruby rbx maglev truffleruby],
+ }.freeze
mswin = Gem::Platform.new 'x86-mswin32'
mswin64 = Gem::Platform.new 'x64-mswin64'
@@ -85,10 +85,11 @@ class Gem::RequestSet::GemDependencyAPI
:ruby_19 => Gem::Platform::RUBY,
:ruby_20 => Gem::Platform::RUBY,
:ruby_21 => Gem::Platform::RUBY,
+ :truffleruby => Gem::Platform::RUBY,
:x64_mingw => x64_mingw,
:x64_mingw_20 => x64_mingw,
- :x64_mingw_21 => x64_mingw
- }
+ :x64_mingw_21 => x64_mingw,
+ }.freeze
gt_eq_0 = Gem::Requirement.new '>= 0'
tilde_gt_1_8_0 = Gem::Requirement.new '~> 1.8.0'
@@ -126,10 +127,11 @@ class Gem::RequestSet::GemDependencyAPI
:ruby_19 => tilde_gt_1_9_0,
:ruby_20 => tilde_gt_2_0_0,
:ruby_21 => tilde_gt_2_1_0,
+ :truffleruby => gt_eq_0,
:x64_mingw => gt_eq_0,
:x64_mingw_20 => tilde_gt_2_0_0,
:x64_mingw_21 => tilde_gt_2_1_0,
- }
+ }.freeze
WINDOWS = { # :nodoc:
:mingw => :only,
@@ -160,7 +162,7 @@ class Gem::RequestSet::GemDependencyAPI
:x64_mingw => :only,
:x64_mingw_20 => :only,
:x64_mingw_21 => :only,
- }
+ }.freeze
##
# The gems required by #gem statements in the gem.deps.rb file
@@ -191,7 +193,7 @@ class Gem::RequestSet::GemDependencyAPI
# Creates a new GemDependencyAPI that will add dependencies to the
# Gem::RequestSet +set+ based on the dependency API description in +path+.
- def initialize set, path
+ def initialize(set, path)
@set = set
@path = path
@@ -203,7 +205,7 @@ class Gem::RequestSet::GemDependencyAPI
@git_set = @set.git_set
@git_sources = {}
@installing = false
- @requires = Hash.new { |h, name| h[name] = [] }
+ @requires = Hash.new {|h, name| h[name] = [] }
@vendor_set = @set.vendor_set
@source_set = @set.source_set
@gem_sources = {}
@@ -228,11 +230,11 @@ class Gem::RequestSet::GemDependencyAPI
# Adds +dependencies+ to the request set if any of the +groups+ are allowed.
# This is used for gemspec dependencies.
- def add_dependencies groups, dependencies # :nodoc:
+ def add_dependencies(groups, dependencies) # :nodoc:
return unless (groups & @without_groups).empty?
dependencies.each do |dep|
- @set.gem dep.name, *dep.requirement
+ @set.gem dep.name, *dep.requirement.as_list
end
end
@@ -241,7 +243,7 @@ class Gem::RequestSet::GemDependencyAPI
##
# Finds a gemspec with the given +name+ that lives at +path+.
- def find_gemspec name, path # :nodoc:
+ def find_gemspec(name, path) # :nodoc:
glob = File.join path, "#{name}.gemspec"
spec_files = Dir[glob]
@@ -269,7 +271,7 @@ class Gem::RequestSet::GemDependencyAPI
# In installing mode certain restrictions are ignored such as ruby version
# mismatch checks.
- def installing= installing # :nodoc:
+ def installing=(installing) # :nodoc:
@installing = installing
end
@@ -277,7 +279,7 @@ class Gem::RequestSet::GemDependencyAPI
# Loads the gem dependency file and returns self.
def load
- instance_eval File.read(@path).untaint, @path, 1
+ instance_eval File.read(@path).tap(&Gem::UNTAINT), @path, 1
self
end
@@ -353,7 +355,7 @@ class Gem::RequestSet::GemDependencyAPI
# tag: ::
# Use the given tag for git:, gist: and github: dependencies.
- def gem name, *requirements
+ def gem(name, *requirements)
options = requirements.pop if requirements.last.kind_of?(Hash)
options ||= {}
@@ -369,15 +371,15 @@ class Gem::RequestSet::GemDependencyAPI
duplicate = @dependencies.include? name
@dependencies[name] =
- if requirements.empty? and not source_set then
+ if requirements.empty? and not source_set
Gem::Requirement.default
- elsif source_set then
+ elsif source_set
Gem::Requirement.source_set
else
Gem::Requirement.create requirements
end
- return unless gem_platforms options
+ return unless gem_platforms name, options
groups = gem_group name, options
@@ -387,7 +389,7 @@ class Gem::RequestSet::GemDependencyAPI
gem_requires name, options
- if duplicate then
+ if duplicate
warn <<-WARNING
Gem dependencies file #{@path} requires #{name} more than once.
WARNING
@@ -401,8 +403,8 @@ Gem dependencies file #{@path} requires #{name} more than once.
#
# Returns +true+ if the gist or git option was handled.
- def gem_git name, options # :nodoc:
- if gist = options.delete(:gist) then
+ def gem_git(name, options) # :nodoc:
+ if gist = options.delete(:gist)
options[:git] = "https://gist.github.com/#{gist}.git"
end
@@ -424,7 +426,7 @@ Gem dependencies file #{@path} requires #{name} more than once.
#
# Returns reference for the git gem.
- def gem_git_reference options # :nodoc:
+ def gem_git_reference(options) # :nodoc:
ref = options.delete :ref
branch = options.delete :branch
tag = options.delete :tag
@@ -440,7 +442,7 @@ Gem dependencies file #{@path} requires #{name} more than once.
Gem dependencies file #{@path} includes git reference for both ref and branch but only ref is used.
WARNING
end
- if (ref||branch) && tag
+ if (ref || branch) && tag
warn <<-WARNING
Gem dependencies file #{@path} includes git reference for both ref/branch and tag but only ref/branch is used.
WARNING
@@ -457,7 +459,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
#
# Returns +true+ if the custom source option was handled.
- def gem_git_source name, options # :nodoc:
+ def gem_git_source(name, options) # :nodoc:
return unless git_source = (@git_sources.keys & options.keys).last
source_callback = @git_sources[git_source]
@@ -478,9 +480,9 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# Handles the :group and :groups +options+ for the gem with the given
# +name+.
- def gem_group name, options # :nodoc:
+ def gem_group(name, options) # :nodoc:
g = options.delete :group
- all_groups = g ? Array(g) : []
+ all_groups = g ? Array(g) : []
groups = options.delete :groups
all_groups |= groups if groups
@@ -497,7 +499,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
#
# Returns +true+ if the path option was handled.
- def gem_path name, options # :nodoc:
+ def gem_path(name, options) # :nodoc:
return unless directory = options.delete(:path)
pin_gem_source name, :path, directory
@@ -514,7 +516,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
#
# Returns +true+ if the source option was handled.
- def gem_source name, options # :nodoc:
+ def gem_source(name, options) # :nodoc:
return unless source = options.delete(:source)
pin_gem_source name, :source, source
@@ -530,7 +532,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# Handles the platforms: option from +options+. Returns true if the
# platform matches the current platform.
- def gem_platforms options # :nodoc:
+ def gem_platforms(name, options) # :nodoc:
platform_names = Array(options.delete :platform)
platform_names.concat Array(options.delete :platforms)
platform_names.concat @current_platforms if @current_platforms
@@ -541,9 +543,9 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
raise ArgumentError, "unknown platform #{platform_name.inspect}" unless
platform = PLATFORM_MAP[platform_name]
- next false unless Gem::Platform.match platform
+ next false unless Gem::Platform.match_gem? platform, name
- if engines = ENGINE_MAP[platform_name] then
+ if engines = ENGINE_MAP[platform_name]
next false unless engines.include? Gem.ruby_engine
end
@@ -564,9 +566,9 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# Records the require: option from +options+ and adds those files, or the
# default file to the require list for +name+.
- def gem_requires name, options # :nodoc:
- if options.include? :require then
- if requires = options.delete(:require) then
+ def gem_requires(name, options) # :nodoc:
+ if options.include? :require
+ if requires = options.delete(:require)
@requires[name].concat Array requires
end
else
@@ -587,7 +589,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# gem 'activerecord'
# end
- def git repository
+ def git(repository)
@current_repository = repository
yield
@@ -601,7 +603,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# for use in gems built from git repositories. You must provide a block
# that accepts a git repository name for expansion.
- def git_source name, &callback
+ def git_source(name, &callback)
@git_sources[name] = callback
end
@@ -634,7 +636,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# The group to add development dependencies to. By default this is
# :development. Only one group may be specified.
- def gemspec options = {}
+ def gemspec(options = {})
name = options.delete(:name) || '{,*}'
path = options.delete(:path) || '.'
development_group = options.delete(:development_group) || :development
@@ -679,7 +681,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# development`. See `gem help install` and `gem help gem_dependencies` for
# further details.
- def group *groups
+ def group(*groups)
@current_groups = groups
yield
@@ -692,7 +694,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# Pins the gem +name+ to the given +source+. Adding a gem with the same
# name from a different +source+ will raise an exception.
- def pin_gem_source name, type = :default, source = nil
+ def pin_gem_source(name, type = :default, source = nil)
source_description =
case type
when :default then '(default)'
@@ -754,7 +756,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# NOTE: There is inconsistency in what environment a platform matches. You
# may need to read the source to know the exact details.
- def platform *platforms
+ def platform(*platforms)
@current_platforms = platforms
yield
@@ -779,9 +781,9 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# You may also provide +engine:+ and +engine_version:+ options to restrict
# this gem dependencies file to a particular ruby engine and its engine
# version. This matching is performed by using the RUBY_ENGINE and
- # engine_specific VERSION constants. (For JRuby, JRUBY_VERSION).
+ # RUBY_ENGINE_VERSION constants.
- def ruby version, options = {}
+ def ruby(version, options = {})
engine = options[:engine]
engine_version = options[:engine_version]
@@ -791,26 +793,24 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
return true if @installing
- unless RUBY_VERSION == version then
+ unless RUBY_VERSION == version
message = "Your Ruby version is #{RUBY_VERSION}, " +
"but your #{gem_deps_file} requires #{version}"
raise Gem::RubyVersionMismatch, message
end
- if engine and engine != Gem.ruby_engine then
+ if engine and engine != Gem.ruby_engine
message = "Your Ruby engine is #{Gem.ruby_engine}, " +
"but your #{gem_deps_file} requires #{engine}"
raise Gem::RubyVersionMismatch, message
end
- if engine_version then
- my_engine_version = Object.const_get "#{Gem.ruby_engine.upcase}_VERSION"
-
- if engine_version != my_engine_version then
+ if engine_version
+ if engine_version != RUBY_ENGINE_VERSION
message =
- "Your Ruby engine version is #{Gem.ruby_engine} #{my_engine_version}, " +
+ "Your Ruby engine version is #{Gem.ruby_engine} #{RUBY_ENGINE_VERSION}, " +
"but your #{gem_deps_file} requires #{engine} #{engine_version}"
raise Gem::RubyVersionMismatch, message
@@ -834,16 +834,11 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# * The +prepend:+ option is not supported. If you wish to order sources
# then list them in your preferred order.
- def source url
+ def source(url)
Gem.sources.clear if @default_sources
@default_sources = false
Gem.sources << url
end
-
- # TODO: remove this typo name at RubyGems 3.0
-
- Gem::RequestSet::GemDepedencyAPI = self # :nodoc:
-
end
diff --git a/lib/rubygems/request_set/lockfile.rb b/lib/rubygems/request_set/lockfile.rb
index 7f6eadb939..bec29ef1b9 100644
--- a/lib/rubygems/request_set/lockfile.rb
+++ b/lib/rubygems/request_set/lockfile.rb
@@ -9,7 +9,6 @@ class Gem::RequestSet::Lockfile
# Raised when a lockfile cannot be parsed
class ParseError < Gem::Exception
-
##
# The column where the error was encountered
@@ -29,7 +28,7 @@ class Gem::RequestSet::Lockfile
# Raises a ParseError with the given +message+ which was encountered at a
# +line+ and +column+ while parsing.
- def initialize message, column, line, path
+ def initialize(message, column, line, path)
@line = line
@column = column
@path = path
@@ -41,13 +40,13 @@ class Gem::RequestSet::Lockfile
# Creates a new Lockfile for the given +request_set+ and +gem_deps_file+
# location.
- def self.build request_set, gem_deps_file, dependencies = nil
+ def self.build(request_set, gem_deps_file, dependencies = nil)
request_set.resolve
dependencies ||= requests_to_deps request_set.sorted_requests
new request_set, gem_deps_file, dependencies
end
- def self.requests_to_deps requests # :nodoc:
+ def self.requests_to_deps(requests) # :nodoc:
deps = {}
requests.each do |request|
@@ -56,7 +55,7 @@ class Gem::RequestSet::Lockfile
requirement = request.request.dependency.requirement
deps[name] = if [Gem::Resolver::VendorSpecification,
- Gem::Resolver::GitSpecification].include? spec.class then
+ Gem::Resolver::GitSpecification].include? spec.class
Gem::Requirement.source_set
else
requirement
@@ -71,40 +70,42 @@ class Gem::RequestSet::Lockfile
attr_reader :platforms
- def initialize request_set, gem_deps_file, dependencies
+ def initialize(request_set, gem_deps_file, dependencies)
@set = request_set
@dependencies = dependencies
@gem_deps_file = File.expand_path(gem_deps_file)
@gem_deps_dir = File.dirname(@gem_deps_file)
- @gem_deps_file.untaint unless gem_deps_file.tainted?
+ if RUBY_VERSION < '2.7'
+ @gem_deps_file.untaint unless gem_deps_file.tainted?
+ end
- @platforms = []
+ @platforms = []
end
- def add_DEPENDENCIES out # :nodoc:
+ def add_DEPENDENCIES(out) # :nodoc:
out << "DEPENDENCIES"
- out.concat @dependencies.sort_by { |name,| name }.map { |name, requirement|
+ out.concat @dependencies.sort_by {|name,| name }.map {|name, requirement|
" #{name}#{requirement.for_lockfile}"
}
out << nil
end
- def add_GEM out, spec_groups # :nodoc:
+ def add_GEM(out, spec_groups) # :nodoc:
return if spec_groups.empty?
source_groups = spec_groups.values.flatten.group_by do |request|
request.spec.source.uri
end
- source_groups.sort_by { |group,| group.to_s }.map do |group, requests|
+ source_groups.sort_by {|group,| group.to_s }.map do |group, requests|
out << "GEM"
out << " remote: #{group}"
out << " specs:"
- requests.sort_by { |request| request.name }.each do |request|
+ requests.sort_by {|request| request.name }.each do |request|
next if request.spec.name == 'bundler'
platform = "-#{request.spec.platform}" unless
Gem::Platform::RUBY == request.spec.platform
@@ -122,7 +123,7 @@ class Gem::RequestSet::Lockfile
end
end
- def add_GIT out, git_requests
+ def add_GIT(out, git_requests)
return if git_requests.empty?
by_repository_revision = git_requests.group_by do |request|
@@ -136,10 +137,10 @@ class Gem::RequestSet::Lockfile
out << " revision: #{revision}"
out << " specs:"
- requests.sort_by { |request| request.name }.each do |request|
+ requests.sort_by {|request| request.name }.each do |request|
out << " #{request.name} (#{request.version})"
- dependencies = request.spec.dependencies.sort_by { |dep| dep.name }
+ dependencies = request.spec.dependencies.sort_by {|dep| dep.name }
dependencies.each do |dep|
out << " #{dep.name}#{dep.requirement.for_lockfile}"
end
@@ -148,12 +149,12 @@ class Gem::RequestSet::Lockfile
end
end
- def relative_path_from dest, base # :nodoc:
+ def relative_path_from(dest, base) # :nodoc:
dest = File.expand_path(dest)
base = File.expand_path(base)
- if dest.index(base) == 0 then
- offset = dest[base.size+1..-1]
+ if dest.index(base) == 0
+ offset = dest[base.size + 1..-1]
return '.' unless offset
@@ -163,7 +164,7 @@ class Gem::RequestSet::Lockfile
end
end
- def add_PATH out, path_requests # :nodoc:
+ def add_PATH(out, path_requests) # :nodoc:
return if path_requests.empty?
out << "PATH"
@@ -178,12 +179,12 @@ class Gem::RequestSet::Lockfile
out << nil
end
- def add_PLATFORMS out # :nodoc:
+ def add_PLATFORMS(out) # :nodoc:
out << "PLATFORMS"
- platforms = requests.map { |request| request.spec.platform }.uniq
+ platforms = requests.map {|request| request.spec.platform }.uniq
- platforms = platforms.sort_by { |platform| platform.to_s }
+ platforms = platforms.sort_by {|platform| platform.to_s }
platforms.each do |platform|
out << " #{platform}"
@@ -193,7 +194,7 @@ class Gem::RequestSet::Lockfile
end
def spec_groups
- requests.group_by { |request| request.spec.class }
+ requests.group_by {|request| request.spec.class }
end
##
@@ -223,7 +224,7 @@ class Gem::RequestSet::Lockfile
def write
content = to_s
- open "#{@gem_deps_file}.lock", 'w' do |io|
+ File.open "#{@gem_deps_file}.lock", 'w' do |io|
io.write content
end
end
@@ -235,4 +236,4 @@ class Gem::RequestSet::Lockfile
end
end
-require 'rubygems/request_set/lockfile/tokenizer'
+require_relative 'lockfile/tokenizer'
diff --git a/lib/rubygems/request_set/lockfile/parser.rb b/lib/rubygems/request_set/lockfile/parser.rb
index ebea940188..8c12b435af 100644
--- a/lib/rubygems/request_set/lockfile/parser.rb
+++ b/lib/rubygems/request_set/lockfile/parser.rb
@@ -3,7 +3,7 @@ class Gem::RequestSet::Lockfile::Parser
###
# Parses lockfiles
- def initialize tokenizer, set, platforms, filename = nil
+ def initialize(tokenizer, set, platforms, filename = nil)
@tokens = tokenizer
@filename = filename
@set = set
@@ -41,10 +41,10 @@ class Gem::RequestSet::Lockfile::Parser
##
# Gets the next token for a Lockfile
- def get expected_types = nil, expected_value = nil # :nodoc:
+ def get(expected_types = nil, expected_value = nil) # :nodoc:
token = @tokens.shift
- if expected_types and not Array(expected_types).include? token.type then
+ if expected_types and not Array(expected_types).include? token.type
unget token
message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " +
@@ -53,7 +53,7 @@ class Gem::RequestSet::Lockfile::Parser
raise Gem::RequestSet::Lockfile::ParseError.new message, token.column, token.line, @filename
end
- if expected_value and expected_value != token.value then
+ if expected_value and expected_value != token.value
unget token
message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " +
@@ -93,7 +93,7 @@ class Gem::RequestSet::Lockfile::Parser
get :r_paren
- if peek[0] == :bang then
+ if peek[0] == :bang
requirements.clear
requirements << pinned_requirement(token.value)
@@ -144,7 +144,7 @@ class Gem::RequestSet::Lockfile::Parser
type = token.type
data = token.value
- if type == :text and column == 4 then
+ if type == :text and column == 4
version, platform = data.split '-', 2
platform =
@@ -183,7 +183,7 @@ class Gem::RequestSet::Lockfile::Parser
type = peek.type
value = peek.value
- if type == :entry and %w[branch ref tag].include? value then
+ if type == :entry and %w[branch ref tag].include? value
get
get :text
@@ -214,7 +214,7 @@ class Gem::RequestSet::Lockfile::Parser
type = token.type
data = token.value
- if type == :text and column == 4 then
+ if type == :text and column == 4
last_spec = set.add_git_spec name, data, repository, revision, true
else
dependency = parse_dependency name, data
@@ -261,7 +261,7 @@ class Gem::RequestSet::Lockfile::Parser
type = token.type
data = token.value
- if type == :text and column == 4 then
+ if type == :text and column == 4
last_spec = set.add_vendor_gem name, directory
else
dependency = parse_dependency name, data
@@ -294,7 +294,7 @@ class Gem::RequestSet::Lockfile::Parser
# Parses the requirements following the dependency +name+ and the +op+ for
# the first token of the requirements and returns a Gem::Dependency object.
- def parse_dependency name, op # :nodoc:
+ def parse_dependency(name, op) # :nodoc:
return Gem::Dependency.new name, op unless peek[0] == :text
version = get(:text).value
@@ -314,7 +314,7 @@ class Gem::RequestSet::Lockfile::Parser
private
- def skip type # :nodoc:
+ def skip(type) # :nodoc:
@tokens.skip type
end
@@ -325,30 +325,19 @@ class Gem::RequestSet::Lockfile::Parser
@tokens.peek
end
- if [].respond_to? :flat_map
- def pinned_requirement name # :nodoc:
- requirement = Gem::Dependency.new name
- specification = @set.sets.flat_map { |set|
- set.find_all(requirement)
- }.compact.first
+ def pinned_requirement(name) # :nodoc:
+ requirement = Gem::Dependency.new name
+ specification = @set.sets.flat_map do |set|
+ set.find_all(requirement)
+ end.compact.first
- specification && specification.version
- end
- else # FIXME: remove when 1.8 is dropped
- def pinned_requirement name # :nodoc:
- requirement = Gem::Dependency.new name
- specification = @set.sets.map { |set|
- set.find_all(requirement)
- }.flatten(1).compact.first
-
- specification && specification.version
- end
+ specification && specification.version
end
##
# Ungets the last token retrieved by #get
- def unget token # :nodoc:
+ def unget(token) # :nodoc:
@tokens.unshift token
end
end
diff --git a/lib/rubygems/request_set/lockfile/tokenizer.rb b/lib/rubygems/request_set/lockfile/tokenizer.rb
index a758743dda..cb8030c143 100644
--- a/lib/rubygems/request_set/lockfile/tokenizer.rb
+++ b/lib/rubygems/request_set/lockfile/tokenizer.rb
@@ -1,15 +1,15 @@
# frozen_string_literal: true
-require 'rubygems/request_set/lockfile/parser'
+require_relative 'parser'
class Gem::RequestSet::Lockfile::Tokenizer
Token = Struct.new :type, :value, :column, :line
EOF = Token.new :EOF
- def self.from_file file
+ def self.from_file(file)
new File.read(file), file
end
- def initialize input, filename = nil, line = 0, pos = 0
+ def initialize(input, filename = nil, line = 0, pos = 0)
@line = line
@line_pos = pos
@tokens = []
@@ -17,15 +17,15 @@ class Gem::RequestSet::Lockfile::Tokenizer
tokenize input
end
- def make_parser set, platforms
+ def make_parser(set, platforms)
Gem::RequestSet::Lockfile::Parser.new self, set, platforms, @filename
end
def to_a
- @tokens.map { |token| [token.type, token.value, token.column, token.line] }
+ @tokens.map {|token| [token.type, token.value, token.column, token.line] }
end
- def skip type
+ def skip(type)
@tokens.shift while not @tokens.empty? and peek.type == type
end
@@ -33,7 +33,7 @@ class Gem::RequestSet::Lockfile::Tokenizer
# Calculates the column (by byte) and the line of the current token based on
# +byte_offset+.
- def token_pos byte_offset # :nodoc:
+ def token_pos(byte_offset) # :nodoc:
[byte_offset - @line_pos, @line]
end
@@ -41,7 +41,7 @@ class Gem::RequestSet::Lockfile::Tokenizer
@tokens.empty?
end
- def unshift token
+ def unshift(token)
@tokens.unshift token
end
@@ -56,7 +56,7 @@ class Gem::RequestSet::Lockfile::Tokenizer
private
- def tokenize input
+ def tokenize(input)
require 'strscan'
s = StringScanner.new input
@@ -65,7 +65,7 @@ class Gem::RequestSet::Lockfile::Tokenizer
pos = s.pos if leading_whitespace = s.scan(/ +/)
- if s.scan(/[<|=>]{7}/) then
+ if s.scan(/[<|=>]{7}/)
message = "your #{@filename} contains merge conflict markers"
column, line = token_pos pos
@@ -80,7 +80,7 @@ class Gem::RequestSet::Lockfile::Tokenizer
@line += 1
token
when s.scan(/[A-Z]+/) then
- if leading_whitespace then
+ if leading_whitespace
text = s.matched
text += s.scan(/[^\s)]*/).to_s # in case of no match
Token.new(:text, text, *token_pos(pos))
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
index 2a60c86e69..d2e28fab5b 100644
--- a/lib/rubygems/requirement.rb
+++ b/lib/rubygems/requirement.rb
@@ -1,10 +1,5 @@
# frozen_string_literal: true
-require "rubygems/version"
-require "rubygems/deprecate"
-
-# If we're being loaded after yaml was already required, then
-# load our yaml + workarounds now.
-Gem.load_yaml if defined? ::YAML
+require_relative "deprecate"
##
# A Requirement is a set of one or more version restrictions. It supports a
@@ -15,29 +10,34 @@ Gem.load_yaml if defined? ::YAML
class Gem::Requirement
OPS = { #:nodoc:
- "=" => lambda { |v, r| v == r },
- "!=" => lambda { |v, r| v != r },
- ">" => lambda { |v, r| v > r },
- "<" => lambda { |v, r| v < r },
- ">=" => lambda { |v, r| v >= r },
- "<=" => lambda { |v, r| v <= r },
- "~>" => lambda { |v, r| v >= r && v.release < r.bump }
- }
+ "=" => lambda {|v, r| v == r },
+ "!=" => lambda {|v, r| v != r },
+ ">" => lambda {|v, r| v > r },
+ "<" => lambda {|v, r| v < r },
+ ">=" => lambda {|v, r| v >= r },
+ "<=" => lambda {|v, r| v <= r },
+ "~>" => lambda {|v, r| v >= r && v.release < r.bump },
+ }.freeze
SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
- quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
- PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*" # :nodoc:
+ quoted = OPS.keys.map {|k| Regexp.quote k }.join "|"
+ PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*".freeze # :nodoc:
##
# A regular expression that matches a requirement
- PATTERN = /\A#{PATTERN_RAW}\z/
+ PATTERN = /\A#{PATTERN_RAW}\z/.freeze
+
+ ##
+ # The default requirement matches any non-prerelease version
+
+ DefaultRequirement = [">=", Gem::Version.new(0)].freeze
##
# The default requirement matches any version
- DefaultRequirement = [">=", Gem::Version.new(0)]
+ DefaultPrereleaseRequirement = [">=", Gem::Version.new("0.a")].freeze
##
# Raised when a bad requirement is encountered
@@ -51,7 +51,7 @@ class Gem::Requirement
# If the input is "weird", the default version requirement is
# returned.
- def self.create *inputs
+ def self.create(*inputs)
return new inputs if inputs.length > 1
input = inputs.shift
@@ -64,7 +64,7 @@ class Gem::Requirement
when '!' then
source_set
else
- if input.respond_to? :to_str then
+ if input.respond_to? :to_str
new [input.to_str]
else
default
@@ -72,13 +72,14 @@ class Gem::Requirement
end
end
- ##
- # A default "version requirement" can surely _only_ be '>= 0'.
-
def self.default
new '>= 0'
end
+ def self.default_prerelease
+ new '>= 0.a'
+ end
+
###
# A source set requirement, used for Gemfiles and lockfiles
@@ -98,7 +99,7 @@ class Gem::Requirement
# parse("1.0") # => ["=", Gem::Version.new("1.0")]
# parse(Gem::Version.new("1.0")) # => ["=, Gem::Version.new("1.0")]
- def self.parse obj
+ def self.parse(obj)
return ["=", obj] if Gem::Version === obj
unless PATTERN =~ obj.to_s
@@ -107,8 +108,10 @@ class Gem::Requirement
if $1 == ">=" && $2 == "0"
DefaultRequirement
+ elsif $1 == ">=" && $2 == "0.a"
+ DefaultPrereleaseRequirement
else
- [$1 || "=", Gem::Version.new($2)]
+ [-($1 || "="), Gem::Version.new($2)]
end
end
@@ -124,7 +127,7 @@ class Gem::Requirement
# requirements are ignored. An empty set of +requirements+ is the
# same as <tt>">= 0"</tt>.
- def initialize *requirements
+ def initialize(*requirements)
requirements = requirements.flatten
requirements.compact!
requirements.uniq!
@@ -132,18 +135,18 @@ class Gem::Requirement
if requirements.empty?
@requirements = [DefaultRequirement]
else
- @requirements = requirements.map! { |r| self.class.parse r }
+ @requirements = requirements.map! {|r| self.class.parse r }
end
end
##
# Concatenates the +new+ requirements onto this requirement.
- def concat new
+ def concat(new)
new = new.flatten
new.compact!
new.uniq!
- new = new.map { |r| self.class.parse r }
+ new = new.map {|r| self.class.parse r }
@requirements.concat new
end
@@ -154,11 +157,11 @@ class Gem::Requirement
def for_lockfile # :nodoc:
return if [DefaultRequirement] == @requirements
- list = requirements.sort_by { |_, version|
+ list = requirements.sort_by do |_, version|
version
- }.map { |op, version|
+ end.map do |op, version|
"#{op} #{version}"
- }.uniq
+ end.uniq
" (#{list.join ', '})"
end
@@ -183,35 +186,30 @@ class Gem::Requirement
end
def as_list # :nodoc:
- requirements.map { |op, version| "#{op} #{version}" }.sort
+ requirements.map {|op, version| "#{op} #{version}" }
end
def hash # :nodoc:
- requirements.sort.hash
+ requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
end
def marshal_dump # :nodoc:
- fix_syck_default_key_in_requirements
-
[@requirements]
end
- def marshal_load array # :nodoc:
+ def marshal_load(array) # :nodoc:
@requirements = array[0]
- fix_syck_default_key_in_requirements
+ raise TypeError, "wrong @requirements" unless Array === @requirements
end
def yaml_initialize(tag, vals) # :nodoc:
vals.each do |ivar, val|
instance_variable_set "@#{ivar}", val
end
-
- Gem.load_yaml
- fix_syck_default_key_in_requirements
end
- def init_with coder # :nodoc:
+ def init_with(coder) # :nodoc:
yaml_initialize coder.tag, coder.map
end
@@ -219,7 +217,7 @@ class Gem::Requirement
["@requirements"]
end
- def encode_with coder # :nodoc:
+ def encode_with(coder) # :nodoc:
coder.add 'requirements', @requirements
end
@@ -228,10 +226,10 @@ class Gem::Requirement
# are prereleases
def prerelease?
- requirements.any? { |r| r.last.prerelease? }
+ requirements.any? {|r| r.last.prerelease? }
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 1, 'Gem::Requirement.new(', ')' do
q.pp as_list
end
@@ -240,11 +238,10 @@ class Gem::Requirement
##
# True if +version+ satisfies this Requirement.
- def satisfied_by? version
+ def satisfied_by?(version)
raise ArgumentError, "Need a Gem::Version: #{version.inspect}" unless
Gem::Version === version
- # #28965: syck has a bug with unquoted '=' YAML.loading as YAML::DefaultKey
- requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv }
+ requirements.all? {|op, rv| OPS[op].call version, rv }
end
alias :=== :satisfied_by?
@@ -263,21 +260,28 @@ class Gem::Requirement
as_list.join ", "
end
- def == other # :nodoc:
- Gem::Requirement === other and to_s == other.to_s
+ def ==(other) # :nodoc:
+ return unless Gem::Requirement === other
+
+ # An == check is always necessary
+ return false unless _sorted_requirements == other._sorted_requirements
+
+ # An == check is sufficient unless any requirements use ~>
+ return true unless _tilde_requirements.any?
+
+ # If any requirements use ~> we use the stricter `#eql?` that also checks
+ # that version precision is the same
+ _tilde_requirements.eql?(other._tilde_requirements)
end
- private
+ protected
- def fix_syck_default_key_in_requirements # :nodoc:
- Gem.load_yaml
+ def _sorted_requirements
+ @_sorted_requirements ||= requirements.sort_by(&:to_s)
+ end
- # Fixup the Syck DefaultKey bug
- @requirements.each do |r|
- if r[0].kind_of? Gem::SyckDefaultKey
- r[0] = "="
- end
- end
+ def _tilde_requirements
+ @_tilde_requirements ||= _sorted_requirements.select {|r| r.first == "~>" }
end
end
diff --git a/lib/rubygems/resolver.rb b/lib/rubygems/resolver.rb
index 13ee035e4c..51a11fed47 100644
--- a/lib/rubygems/resolver.rb
+++ b/lib/rubygems/resolver.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
-require 'rubygems/dependency'
-require 'rubygems/exceptions'
-require 'rubygems/util'
-require 'rubygems/util/list'
+require_relative 'dependency'
+require_relative 'exceptions'
+require_relative 'util/list'
##
# Given a set of Gem::Dependency objects as +needed+ and a way to query the
@@ -11,7 +10,7 @@ require 'rubygems/util/list'
# all the requirements.
class Gem::Resolver
- require 'rubygems/resolver/molinillo'
+ require_relative 'resolver/molinillo'
##
# If the DEBUG_RESOLVER environment variable is set then debugging mode is
@@ -59,7 +58,7 @@ class Gem::Resolver
# uniform manner. If one of the +sets+ is itself a ComposedSet its sets are
# flattened into the result ComposedSet.
- def self.compose_sets *sets
+ def self.compose_sets(*sets)
sets.compact!
sets = sets.map do |set|
@@ -87,7 +86,7 @@ class Gem::Resolver
# Creates a Resolver that queries only against the already installed gems
# for the +needed+ dependencies.
- def self.for_current_gems needed
+ def self.for_current_gems(needed)
new needed, Gem::Resolver::CurrentSet.new
end
@@ -99,7 +98,7 @@ class Gem::Resolver
# satisfy the Dependencies. This defaults to IndexSet, which will query
# rubygems.org.
- def initialize needed, set = nil
+ def initialize(needed, set = nil)
@set = set || Gem::Resolver::IndexSet.new
@needed = needed
@@ -112,19 +111,22 @@ class Gem::Resolver
@stats = Gem::Resolver::Stats.new
end
- def explain stage, *data # :nodoc:
+ def explain(stage, *data) # :nodoc:
return unless DEBUG_RESOLVER
- d = data.map { |x| x.pretty_inspect }.join(", ")
+ d = data.map {|x| x.pretty_inspect }.join(", ")
$stderr.printf "%10s %s\n", stage.to_s.upcase, d
end
- def explain_list stage # :nodoc:
+ def explain_list(stage) # :nodoc:
return unless DEBUG_RESOLVER
data = yield
$stderr.printf "%10s (%d entries)\n", stage.to_s.upcase, data.size
- PP.pp data, $stderr unless data.empty?
+ unless data.empty?
+ require 'pp'
+ PP.pp data, $stderr
+ end
end
##
@@ -133,7 +135,7 @@ class Gem::Resolver
#
# Returns the Specification and the ActivationRequest
- def activation_request dep, possible # :nodoc:
+ def activation_request(dep, possible) # :nodoc:
spec = possible.pop
explain :activate, [spec.full_name, possible.size]
@@ -145,7 +147,7 @@ class Gem::Resolver
return spec, activation_request
end
- def requests s, act, reqs=[] # :nodoc:
+ def requests(s, act, reqs=[]) # :nodoc:
return reqs if @ignore_dependencies
s.fetch_development_dependencies if @development
@@ -171,7 +173,7 @@ class Gem::Resolver
include Molinillo::UI
def output
- @output ||= debug? ? $stdout : File.open(Gem::Util::NULL_DEVICE, 'w')
+ @output ||= debug? ? $stdout : File.open(IO::NULL, 'w')
end
def debug?
@@ -185,7 +187,7 @@ class Gem::Resolver
def resolve
locking_dg = Molinillo::DependencyGraph.new
- Molinillo::Resolver.new(self, self).resolve(@needed.map { |d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload).compact
+ Molinillo::Resolver.new(self, self).resolve(@needed.map {|d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload).compact
rescue Molinillo::VersionConflict => e
conflict = e.conflicts.values.first
raise Gem::DependencyResolutionError, Conflict.new(conflict.requirement_trees.first.first, conflict.existing, conflict.requirement)
@@ -197,12 +199,12 @@ class Gem::Resolver
# Extracts the specifications that may be able to fulfill +dependency+ and
# returns those that match the local platform and all those that match.
- def find_possible dependency # :nodoc:
+ def find_possible(dependency) # :nodoc:
all = @set.find_all dependency
if (skip_dep_gems = skip_gems[dependency.name]) && !skip_dep_gems.empty?
matching = all.select do |api_spec|
- skip_dep_gems.any? { |s| api_spec.version == s.version }
+ skip_dep_gems.any? {|s| api_spec.version == s.version }
end
all = matching unless matching.empty?
@@ -216,7 +218,7 @@ class Gem::Resolver
##
# Returns the gems in +specs+ that match the local platform.
- def select_local_platforms specs # :nodoc:
+ def select_local_platforms(specs) # :nodoc:
specs.select do |spec|
Gem::Platform.installable? spec
end
@@ -231,24 +233,22 @@ class Gem::Resolver
raise exc
end
- sources = []
-
- groups = Hash.new { |hash, key| hash[key] = [] }
+ groups = Hash.new {|hash, key| hash[key] = [] }
# create groups & sources in the same loop
- sources = possibles.map { |spec|
+ sources = possibles.map do |spec|
source = spec.source
groups[source] << spec
source
- }.uniq.reverse
+ end.uniq.reverse
activation_requests = []
sources.each do |source|
groups[source].
- sort_by { |spec| [spec.version, Gem::Platform.local =~ spec.platform ? 1 : 0] }.
- map { |spec| ActivationRequest.new spec, dependency, [] }.
- each { |activation_request| activation_requests << activation_request }
+ sort_by {|spec| [spec.version, Gem::Platform.local =~ spec.platform ? 1 : 0] }.
+ map {|spec| ActivationRequest.new spec, dependency }.
+ each {|activation_request| activation_requests << activation_request }
end
activation_requests
@@ -261,7 +261,12 @@ class Gem::Resolver
end
def requirement_satisfied_by?(requirement, activated, spec)
- requirement.matches_spec? spec
+ matches_spec = requirement.matches_spec? spec
+ return matches_spec if @soft_missing
+
+ matches_spec &&
+ spec.spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
+ spec.spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
end
def name_for(dependency)
@@ -281,7 +286,7 @@ class Gem::Resolver
amount_constrained(dependency),
conflicts[name] ? 0 : 1,
activated.vertex_named(name).payload ? 0 : search_for(dependency).count,
- i # for stable sort
+ i, # for stable sort
]
end
end
@@ -311,38 +316,32 @@ class Gem::Resolver
end
end
private :amount_constrained
-
end
-##
-# TODO remove in RubyGems 3
-
-Gem::DependencyResolver = Gem::Resolver # :nodoc:
-
-require 'rubygems/resolver/activation_request'
-require 'rubygems/resolver/conflict'
-require 'rubygems/resolver/dependency_request'
-require 'rubygems/resolver/requirement_list'
-require 'rubygems/resolver/stats'
-
-require 'rubygems/resolver/set'
-require 'rubygems/resolver/api_set'
-require 'rubygems/resolver/composed_set'
-require 'rubygems/resolver/best_set'
-require 'rubygems/resolver/current_set'
-require 'rubygems/resolver/git_set'
-require 'rubygems/resolver/index_set'
-require 'rubygems/resolver/installer_set'
-require 'rubygems/resolver/lock_set'
-require 'rubygems/resolver/vendor_set'
-require 'rubygems/resolver/source_set'
-
-require 'rubygems/resolver/specification'
-require 'rubygems/resolver/spec_specification'
-require 'rubygems/resolver/api_specification'
-require 'rubygems/resolver/git_specification'
-require 'rubygems/resolver/index_specification'
-require 'rubygems/resolver/installed_specification'
-require 'rubygems/resolver/local_specification'
-require 'rubygems/resolver/lock_specification'
-require 'rubygems/resolver/vendor_specification'
+require_relative 'resolver/activation_request'
+require_relative 'resolver/conflict'
+require_relative 'resolver/dependency_request'
+require_relative 'resolver/requirement_list'
+require_relative 'resolver/stats'
+
+require_relative 'resolver/set'
+require_relative 'resolver/api_set'
+require_relative 'resolver/composed_set'
+require_relative 'resolver/best_set'
+require_relative 'resolver/current_set'
+require_relative 'resolver/git_set'
+require_relative 'resolver/index_set'
+require_relative 'resolver/installer_set'
+require_relative 'resolver/lock_set'
+require_relative 'resolver/vendor_set'
+require_relative 'resolver/source_set'
+
+require_relative 'resolver/specification'
+require_relative 'resolver/spec_specification'
+require_relative 'resolver/api_specification'
+require_relative 'resolver/git_specification'
+require_relative 'resolver/index_specification'
+require_relative 'resolver/installed_specification'
+require_relative 'resolver/local_specification'
+require_relative 'resolver/lock_specification'
+require_relative 'resolver/vendor_specification'
diff --git a/lib/rubygems/resolver/activation_request.rb b/lib/rubygems/resolver/activation_request.rb
index 135d75d6bc..ae35681db9 100644
--- a/lib/rubygems/resolver/activation_request.rb
+++ b/lib/rubygems/resolver/activation_request.rb
@@ -4,7 +4,6 @@
# dependency that was used to introduce this activation.
class Gem::Resolver::ActivationRequest
-
##
# The parent request for this activation request.
@@ -18,27 +17,31 @@ class Gem::Resolver::ActivationRequest
##
# Creates a new ActivationRequest that will activate +spec+. The parent
# +request+ is used to provide diagnostics in case of conflicts.
- #
- # +others_possible+ indicates that other specifications may also match this
- # activation request.
- def initialize spec, request, others_possible = true
+ def initialize(spec, request)
@spec = spec
@request = request
- @others_possible = others_possible
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
case other
when Gem::Specification
@spec == other
when Gem::Resolver::ActivationRequest
- @spec == other.spec && @request == other.request
+ @spec == other.spec
else
false
end
end
+ def eql?(other)
+ self == other
+ end
+
+ def hash
+ @spec.hash
+ end
+
##
# Is this activation request for a development dependency?
@@ -49,17 +52,17 @@ class Gem::Resolver::ActivationRequest
##
# Downloads a gem at +path+ and returns the file path.
- def download path
+ def download(path)
Gem.ensure_gem_subdirectories path
if @spec.respond_to? :sources
exception = nil
- path = @spec.sources.find{ |source|
+ path = @spec.sources.find do |source|
begin
source.download full_spec, path
rescue exception
end
- }
+ end
return path if path
raise exception if exception
@@ -77,7 +80,7 @@ class Gem::Resolver::ActivationRequest
# The full name of the specification to be activated.
def full_name
- @spec.full_name
+ name_tuple.full_name
end
alias_method :to_s, :full_name
@@ -90,21 +93,8 @@ class Gem::Resolver::ActivationRequest
end
def inspect # :nodoc:
- others =
- case @others_possible
- when true then # TODO remove at RubyGems 3
- ' (others possible)'
- when false then # TODO remove at RubyGems 3
- nil
- else
- unless @others_possible.empty? then
- others = @others_possible.map { |s| s.full_name }
- " (others possible: #{others.join ', '})"
- end
- end
-
- '#<%s for %p from %s%s>' % [
- self.class, @spec, @request, others
+ '#<%s for %p from %s>' % [
+ self.class, @spec, @request
]
end
@@ -132,19 +122,6 @@ class Gem::Resolver::ActivationRequest
end
##
- # Indicate if this activation is one of a set of possible
- # requests for the same Dependency request.
-
- def others_possible?
- case @others_possible
- when true, false then
- @others_possible
- else
- not @others_possible.empty?
- end
- end
-
- ##
# Return the ActivationRequest that contained the dependency
# that we were activated for.
@@ -152,7 +129,7 @@ class Gem::Resolver::ActivationRequest
@request.requester
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[Activation request', ']' do
q.breakable
q.pp @spec
@@ -160,19 +137,6 @@ class Gem::Resolver::ActivationRequest
q.breakable
q.text ' for '
q.pp @request
-
- case @others_possible
- when false then
- when true then
- q.breakable
- q.text 'others possible'
- else
- unless @others_possible.empty? then
- q.breakable
- q.text 'others '
- q.pp @others_possible.map { |s| s.full_name }
- end
- end
end
end
@@ -183,4 +147,16 @@ class Gem::Resolver::ActivationRequest
@spec.version
end
+ ##
+ # The platform of this activation request's specification
+
+ def platform
+ @spec.platform
+ end
+
+ private
+
+ def name_tuple
+ @name_tuple ||= Gem::NameTuple.new(name, version, platform)
+ end
end
diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb
index ee3046af63..21c9b8920c 100644
--- a/lib/rubygems/resolver/api_set.rb
+++ b/lib/rubygems/resolver/api_set.rb
@@ -4,6 +4,7 @@
# Returns instances of APISpecification.
class Gem::Resolver::APISet < Gem::Resolver::Set
+ autoload :GemParser, File.expand_path("api_set/gem_parser", __dir__)
##
# The URI for the dependency API this APISet uses.
@@ -23,17 +24,17 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
##
# Creates a new APISet that will retrieve gems from +uri+ using the RubyGems
# API URL +dep_uri+ which is described at
- # http://guides.rubygems.org/rubygems-org-api
+ # https://guides.rubygems.org/rubygems-org-api
- def initialize dep_uri = 'https://rubygems.org/api/v1/dependencies'
+ def initialize(dep_uri = 'https://index.rubygems.org/info/')
super()
- dep_uri = URI dep_uri unless URI === dep_uri # for ruby 1.8
+ dep_uri = URI dep_uri unless URI === dep_uri
@dep_uri = dep_uri
- @uri = dep_uri + '../..'
+ @uri = dep_uri + '..'
- @data = Hash.new { |h,k| h[k] = [] }
+ @data = Hash.new {|h,k| h[k] = [] }
@source = Gem::Source.new @uri
@to_fetch = []
@@ -43,7 +44,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
# Return an array of APISpecification objects matching
# DependencyRequest +req+.
- def find_all req
+ def find_all(req)
res = []
return res unless @remote
@@ -53,7 +54,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
end
versions(req.name).each do |ver|
- if req.dependency.match? req.name, ver[:number]
+ if req.dependency.match? req.name, ver[:number], @prerelease
res << Gem::Resolver::APISpecification.new(self, ver)
end
end
@@ -65,9 +66,9 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
# A hint run by the resolver to allow the Set to fetch
# data for DependencyRequests +reqs+.
- def prefetch reqs
+ def prefetch(reqs)
return unless @remote
- names = reqs.map { |r| r.dependency.name }
+ names = reqs.map {|r| r.dependency.name }
needed = names - @data.keys - @to_fetch
@to_fetch += needed
@@ -76,24 +77,12 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
def prefetch_now # :nodoc:
needed, @to_fetch = @to_fetch, []
- uri = @dep_uri + "?gems=#{needed.sort.join ','}"
- str = Gem::RemoteFetcher.fetcher.fetch_path uri
-
- loaded = []
-
- Marshal.load(str).each do |ver|
- name = ver[:name]
-
- @data[name] << ver
- loaded << name
- end
-
- (needed - loaded).each do |missing|
- @data[missing] = []
+ needed.sort.each do |name|
+ versions(name)
end
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[APISet', ']' do
q.breakable
q.text "URI: #{@dep_uri}"
@@ -107,20 +96,37 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
##
# Return data for all versions of the gem +name+.
- def versions name # :nodoc:
+ def versions(name) # :nodoc:
if @data.key?(name)
return @data[name]
end
- uri = @dep_uri + "?gems=#{name}"
+ uri = @dep_uri + name
str = Gem::RemoteFetcher.fetcher.fetch_path uri
- Marshal.load(str).each do |ver|
- @data[ver[:name]] << ver
+ lines(str).each do |ver|
+ number, platform, dependencies, requirements = parse_gem(ver)
+
+ platform ||= "ruby"
+ dependencies = dependencies.map {|dep_name, reqs| [dep_name, reqs.join(", ")] }
+ requirements = requirements.map {|req_name, reqs| [req_name.to_sym, reqs] }.to_h
+
+ @data[name] << { name: name, number: number, platform: platform, dependencies: dependencies, requirements: requirements }
end
@data[name]
end
-end
+ private
+
+ def lines(str)
+ lines = str.split("\n")
+ header = lines.index("---")
+ header ? lines[header + 1..-1] : lines
+ end
+ def parse_gem(string)
+ @gem_parser ||= GemParser.new
+ @gem_parser.parse(string)
+ end
+end
diff --git a/lib/rubygems/resolver/api_set/gem_parser.rb b/lib/rubygems/resolver/api_set/gem_parser.rb
new file mode 100644
index 0000000000..685c39558d
--- /dev/null
+++ b/lib/rubygems/resolver/api_set/gem_parser.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class Gem::Resolver::APISet::GemParser
+ def parse(line)
+ version_and_platform, rest = line.split(" ", 2)
+ version, platform = version_and_platform.split("-", 2)
+ dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
+ dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
+ requirements = requirements ? requirements.map {|d| parse_dependency(d) } : []
+ [version, platform, dependencies, requirements]
+ end
+
+ private
+
+ def parse_dependency(string)
+ dependency = string.split(":")
+ dependency[-1] = dependency[-1].split("&") if dependency.size > 1
+ dependency
+ end
+end
diff --git a/lib/rubygems/resolver/api_specification.rb b/lib/rubygems/resolver/api_specification.rb
index 1e22dd0b6f..b5aa0b71d4 100644
--- a/lib/rubygems/resolver/api_specification.rb
+++ b/lib/rubygems/resolver/api_specification.rb
@@ -6,12 +6,22 @@
# is the name, version, and dependencies.
class Gem::Resolver::APISpecification < Gem::Resolver::Specification
+ ##
+ # We assume that all instances of this class are immutable;
+ # so avoid duplicated generation for performance.
+ @@cache = {}
+ def self.new(set, api_data)
+ cache_key = [set, api_data]
+ cache = @@cache[cache_key]
+ return cache if cache
+ @@cache[cache_key] = super
+ end
##
# Creates an APISpecification for the given +set+ from the rubygems.org
# +api_data+.
#
- # See http://guides.rubygems.org/rubygems-org-api/#misc_methods for the
+ # See https://guides.rubygems.org/rubygems-org-api/#misc_methods for the
# format of the +api_data+.
def initialize(set, api_data)
@@ -19,20 +29,26 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
@set = set
@name = api_data[:name]
- @version = Gem::Version.new api_data[:number]
- @platform = Gem::Platform.new api_data[:platform]
+ @version = Gem::Version.new(api_data[:number]).freeze
+ @platform = Gem::Platform.new(api_data[:platform]).freeze
+ @original_platform = api_data[:platform].freeze
@dependencies = api_data[:dependencies].map do |name, ver|
- Gem::Dependency.new name, ver.split(/\s*,\s*/)
- end
+ Gem::Dependency.new(name, ver.split(/\s*,\s*/)).freeze
+ end.freeze
+ @required_ruby_version = Gem::Requirement.new(api_data.dig(:requirements, :ruby)).freeze
+ @required_rubygems_version = Gem::Requirement.new(api_data.dig(:requirements, :rubygems)).freeze
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
self.class === other and
@set == other.set and
@name == other.name and
@version == other.version and
- @platform == other.platform and
- @dependencies == other.dependencies
+ @platform == other.platform
+ end
+
+ def hash
+ @set.hash ^ @name.hash ^ @version.hash ^ @platform.hash
end
def fetch_development_dependencies # :nodoc:
@@ -42,10 +58,10 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
end
def installable_platform? # :nodoc:
- Gem::Platform.match @platform
+ Gem::Platform.match_gem? @platform, @name
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[APISpecification', ']' do
q.breakable
q.text "name: #{name}"
@@ -73,7 +89,11 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
@spec ||=
begin
tuple = Gem::NameTuple.new @name, @version, @platform
+ source.fetch_spec tuple
+ rescue Gem::RemoteFetcher::FetchError
+ raise if @original_platform == @platform
+ tuple = Gem::NameTuple.new @name, @version, @original_platform
source.fetch_spec tuple
end
end
@@ -81,6 +101,4 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
def source # :nodoc:
@set.source
end
-
end
-
diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb
index 4479535abe..300ea8015c 100644
--- a/lib/rubygems/resolver/best_set.rb
+++ b/lib/rubygems/resolver/best_set.rb
@@ -5,12 +5,11 @@
# It combines IndexSet and APISet
class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
-
##
# Creates a BestSet for the given +sources+ or Gem::sources if none are
# specified. +sources+ must be a Gem::SourceList.
- def initialize sources = Gem.sources
+ def initialize(sources = Gem.sources)
super()
@sources = sources
@@ -25,7 +24,7 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
end
end
- def find_all req # :nodoc:
+ def find_all(req) # :nodoc:
pick_sets if @remote and @sets.empty?
super
@@ -35,13 +34,13 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
retry
end
- def prefetch reqs # :nodoc:
+ def prefetch(reqs) # :nodoc:
pick_sets if @remote and @sets.empty?
super
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[BestSet', ']' do
q.breakable
q.text 'sets:'
@@ -58,14 +57,14 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
#
# The calling method must retry the exception to repeat the lookup.
- def replace_failed_api_set error # :nodoc:
- uri = error.uri
+ def replace_failed_api_set(error) # :nodoc:
+ uri = error.original_uri
uri = URI uri unless URI === uri
- uri.query = nil
+ uri = uri + "."
- raise error unless api_set = @sets.find { |set|
+ raise error unless api_set = @sets.find do |set|
Gem::Resolver::APISet === set and set.dep_uri == uri
- }
+ end
index_set = Gem::Resolver::IndexSet.new api_set.source
@@ -74,6 +73,4 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
index_set
end
end
-
end
-
diff --git a/lib/rubygems/resolver/composed_set.rb b/lib/rubygems/resolver/composed_set.rb
index 0b65942dca..226da1e1e0 100644
--- a/lib/rubygems/resolver/composed_set.rb
+++ b/lib/rubygems/resolver/composed_set.rb
@@ -9,14 +9,13 @@
# This method will eliminate nesting of composed sets.
class Gem::Resolver::ComposedSet < Gem::Resolver::Set
-
attr_reader :sets # :nodoc:
##
# Creates a new ComposedSet containing +sets+. Use
# Gem::Resolver::compose_sets instead.
- def initialize *sets
+ def initialize(*sets)
super()
@sets = sets
@@ -26,7 +25,7 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
# When +allow_prerelease+ is set to +true+ prereleases gems are allowed to
# match dependencies.
- def prerelease= allow_prerelease
+ def prerelease=(allow_prerelease)
super
sets.each do |set|
@@ -37,20 +36,20 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
##
# Sets the remote network access for all composed sets.
- def remote= remote
+ def remote=(remote)
super
- @sets.each { |set| set.remote = remote }
+ @sets.each {|set| set.remote = remote }
end
def errors
- @errors + @sets.map { |set| set.errors }.flatten
+ @errors + @sets.map {|set| set.errors }.flatten
end
##
# Finds all specs matching +req+ in all sets.
- def find_all req
+ def find_all(req)
@sets.map do |s|
s.find_all req
end.flatten
@@ -59,9 +58,7 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
##
# Prefetches +reqs+ in all sets.
- def prefetch reqs
- @sets.each { |s| s.prefetch(reqs) }
+ def prefetch(reqs)
+ @sets.each {|s| s.prefetch(reqs) }
end
-
end
-
diff --git a/lib/rubygems/resolver/conflict.rb b/lib/rubygems/resolver/conflict.rb
index 7997f92950..4c4588d7e8 100644
--- a/lib/rubygems/resolver/conflict.rb
+++ b/lib/rubygems/resolver/conflict.rb
@@ -4,7 +4,6 @@
# with a spec that would be activated.
class Gem::Resolver::Conflict
-
##
# The specification that was activated prior to the conflict
@@ -27,7 +26,7 @@ class Gem::Resolver::Conflict
@failed_dep = failed_dep
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
self.class === other and
@dependency == other.dependency and
@activated == other.activated and
@@ -55,9 +54,9 @@ class Gem::Resolver::Conflict
activated = @activated.spec.full_name
dependency = @failed_dep.dependency
requirement = dependency.requirement
- alternates = dependency.matching_specs.map { |spec| spec.full_name }
+ alternates = dependency.matching_specs.map {|spec| spec.full_name }
- unless alternates.empty? then
+ unless alternates.empty?
matching = <<-MATCHING.chomp
Gems matching %s:
@@ -86,7 +85,7 @@ class Gem::Resolver::Conflict
activated, requirement,
request_path(@activated).reverse.join(", depends on\n "),
request_path(@failed_dep).reverse.join(", depends on\n "),
- matching,
+ matching
]
end
@@ -97,7 +96,7 @@ class Gem::Resolver::Conflict
@dependency.name == spec.name
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[Dependency conflict: ', ']' do
q.breakable
@@ -109,7 +108,7 @@ class Gem::Resolver::Conflict
q.pp @dependency
q.breakable
- if @dependency == @failed_dep then
+ if @dependency == @failed_dep
q.text ' failed'
else
q.text ' failed dependency '
@@ -121,7 +120,7 @@ class Gem::Resolver::Conflict
##
# Path of activations from the +current+ list.
- def request_path current
+ def request_path(current)
path = []
while current do
@@ -151,10 +150,4 @@ class Gem::Resolver::Conflict
def requester
@failed_dep.requester
end
-
end
-
-##
-# TODO: Remove in RubyGems 3
-
-Gem::Resolver::DependencyConflict = Gem::Resolver::Conflict # :nodoc:
diff --git a/lib/rubygems/resolver/current_set.rb b/lib/rubygems/resolver/current_set.rb
index 265c639f15..c3aa3a2c37 100644
--- a/lib/rubygems/resolver/current_set.rb
+++ b/lib/rubygems/resolver/current_set.rb
@@ -5,10 +5,7 @@
# for installed gems.
class Gem::Resolver::CurrentSet < Gem::Resolver::Set
-
- def find_all req
+ def find_all(req)
req.dependency.matching_specs
end
-
end
-
diff --git a/lib/rubygems/resolver/dependency_request.rb b/lib/rubygems/resolver/dependency_request.rb
index c2918911cd..356aadb3b2 100644
--- a/lib/rubygems/resolver/dependency_request.rb
+++ b/lib/rubygems/resolver/dependency_request.rb
@@ -4,7 +4,6 @@
# contained the Dependency.
class Gem::Resolver::DependencyRequest
-
##
# The wrapped Gem::Dependency
@@ -19,17 +18,17 @@ class Gem::Resolver::DependencyRequest
# Creates a new DependencyRequest for +dependency+ from +requester+.
# +requester may be nil if the request came from a user.
- def initialize dependency, requester
+ def initialize(dependency, requester)
@dependency = dependency
@requester = requester
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
case other
when Gem::Dependency
@dependency == other
when Gem::Resolver::DependencyRequest
- @dependency == other.dependency && @requester == other.requester
+ @dependency == other.dependency
else
false
end
@@ -48,7 +47,7 @@ class Gem::Resolver::DependencyRequest
# NOTE: #match? only matches prerelease versions when #dependency is a
# prerelease dependency.
- def match? spec, allow_prerelease = false
+ def match?(spec, allow_prerelease = false)
@dependency.match? spec, nil, allow_prerelease
end
@@ -95,7 +94,7 @@ class Gem::Resolver::DependencyRequest
@requester ? @requester.request : "(unknown)"
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[Dependency request ', ']' do
q.breakable
q.text @dependency.to_s
@@ -116,5 +115,4 @@ class Gem::Resolver::DependencyRequest
def to_s # :nodoc:
@dependency.to_s
end
-
end
diff --git a/lib/rubygems/resolver/git_set.rb b/lib/rubygems/resolver/git_set.rb
index 723a202d7a..eac51f15ad 100644
--- a/lib/rubygems/resolver/git_set.rb
+++ b/lib/rubygems/resolver/git_set.rb
@@ -10,7 +10,6 @@
# set.add_git_gem 'rake', 'git://example/rake.git', tag: 'rake-10.1.0'
class Gem::Resolver::GitSet < Gem::Resolver::Set
-
##
# The root directory for git gems in this set. This is usually Gem.dir, the
# installation directory for regular gems.
@@ -43,7 +42,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
@specs = {}
end
- def add_git_gem name, repository, reference, submodules # :nodoc:
+ def add_git_gem(name, repository, reference, submodules) # :nodoc:
@repositories[name] = [repository, reference]
@need_submodules[repository] = submodules
end
@@ -56,7 +55,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
# This fills in the prefetch information as enough information about the gem
# is present in the arguments.
- def add_git_spec name, version, repository, reference, submodules # :nodoc:
+ def add_git_spec(name, version, repository, reference, submodules) # :nodoc:
add_git_gem name, repository, reference, submodules
source = Gem::Source::Git.new name, repository, reference
@@ -77,7 +76,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
##
# Finds all git gems matching +req+
- def find_all req
+ def find_all(req)
prefetch nil
specs.values.select do |spec|
@@ -88,7 +87,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
##
# Prefetches specifications from the git repositories in this set.
- def prefetch reqs
+ def prefetch(reqs)
return unless @specs.empty?
@repositories.each do |name, (repository, reference)|
@@ -104,7 +103,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
end
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[GitSet', ']' do
next if @repositories.empty?
q.breakable
@@ -118,6 +117,4 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
end
end
end
-
end
-
diff --git a/lib/rubygems/resolver/git_specification.rb b/lib/rubygems/resolver/git_specification.rb
index 2448797d3f..ee47080ab4 100644
--- a/lib/rubygems/resolver/git_specification.rb
+++ b/lib/rubygems/resolver/git_specification.rb
@@ -5,15 +5,14 @@
# option.
class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
-
- def == other # :nodoc:
+ def ==(other) # :nodoc:
self.class === other and
@set == other.set and
@spec == other.spec and
@source == other.source
end
- def add_dependency dependency # :nodoc:
+ def add_dependency(dependency) # :nodoc:
spec.dependencies << dependency
end
@@ -21,8 +20,8 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
# Installing a git gem only involves building the extensions and generating
# the executables.
- def install options = {}
- require 'rubygems/installer'
+ def install(options = {})
+ require_relative '../installer'
installer = Gem::Installer.for_spec spec, options
@@ -35,7 +34,7 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
installer.run_post_install_hooks
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[GitSpecification', ']' do
q.breakable
q.text "name: #{name}"
@@ -54,6 +53,4 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
q.pp @source
end
end
-
end
-
diff --git a/lib/rubygems/resolver/index_set.rb b/lib/rubygems/resolver/index_set.rb
index 2450f14b4f..9390e34255 100644
--- a/lib/rubygems/resolver/index_set.rb
+++ b/lib/rubygems/resolver/index_set.rb
@@ -4,12 +4,11 @@
# source index.
class Gem::Resolver::IndexSet < Gem::Resolver::Set
-
- def initialize source = nil # :nodoc:
+ def initialize(source = nil) # :nodoc:
super()
@f =
- if source then
+ if source
sources = Gem::SourceList.from [source]
Gem::SpecFetcher.new sources
@@ -17,7 +16,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
Gem::SpecFetcher.fetcher
end
- @all = Hash.new { |h,k| h[k] = [] }
+ @all = Hash.new {|h,k| h[k] = [] }
list, errors = @f.available_specs :complete
@@ -36,7 +35,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
# Return an array of IndexSpecification objects matching
# DependencyRequest +req+.
- def find_all req
+ def find_all(req)
res = []
return res unless @remote
@@ -44,7 +43,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
name = req.dependency.name
@all[name].each do |uri, n|
- if req.match? n, @prerelease then
+ if req.match? n, @prerelease
res << Gem::Resolver::IndexSpecification.new(
self, n.name, n.version, uri, n.platform)
end
@@ -53,7 +52,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
res
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[IndexSet', ']' do
q.breakable
q.text 'sources:'
@@ -76,6 +75,4 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
end
end
end
-
end
-
diff --git a/lib/rubygems/resolver/index_specification.rb b/lib/rubygems/resolver/index_specification.rb
index 4340f46943..9ea76f40ba 100644
--- a/lib/rubygems/resolver/index_specification.rb
+++ b/lib/rubygems/resolver/index_specification.rb
@@ -5,7 +5,6 @@
# and +version+ are needed.
class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
-
##
# An IndexSpecification is created from the index format described in `gem
# help generate_index`.
@@ -15,7 +14,7 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
# The +name+, +version+ and +platform+ are the name, version and platform of
# the gem.
- def initialize set, name, version, source, platform
+ def initialize(set, name, version, source, platform)
super()
@set = set
@@ -34,16 +33,48 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
spec.dependencies
end
+ ##
+ # The required_ruby_version constraint for this specification
+ #
+ # A fallback is included because when generated, some marshalled specs have it
+ # set to +nil+.
+
+ def required_ruby_version
+ spec.required_ruby_version || Gem::Requirement.default
+ end
+
+ ##
+ # The required_rubygems_version constraint for this specification
+ #
+ # A fallback is included because the original version of the specification
+ # API didn't include that field, so some marshalled specs in the index have it
+ # set to +nil+.
+
+ def required_rubygems_version
+ spec.required_rubygems_version || Gem::Requirement.default
+ end
+
+ def ==(other)
+ self.class === other &&
+ @name == other.name &&
+ @version == other.version &&
+ @platform == other.platform
+ end
+
+ def hash
+ @name.hash ^ @version.hash ^ @platform.hash
+ end
+
def inspect # :nodoc:
'#<%s %s source %s>' % [self.class, full_name, @source]
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[Index specification', ']' do
q.breakable
q.text full_name
- unless Gem::Platform::RUBY == @platform then
+ unless Gem::Platform::RUBY == @platform
q.breakable
q.text @platform.to_s
end
@@ -65,6 +96,4 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
@source.fetch_spec tuple
end
end
-
end
-
diff --git a/lib/rubygems/resolver/installed_specification.rb b/lib/rubygems/resolver/installed_specification.rb
index d9c6a5e5cf..167ba1439e 100644
--- a/lib/rubygems/resolver/installed_specification.rb
+++ b/lib/rubygems/resolver/installed_specification.rb
@@ -4,8 +4,7 @@
# locally.
class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
-
- def == other # :nodoc:
+ def ==(other) # :nodoc:
self.class === other and
@set == other.set and
@spec == other.spec
@@ -15,7 +14,7 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
# This is a null install as this specification is already installed.
# +options+ are ignored.
- def install options = {}
+ def install(options = {})
yield nil
end
@@ -30,7 +29,7 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
super
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[InstalledSpecification', ']' do
q.breakable
q.text "name: #{name}"
@@ -54,6 +53,4 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
def source
@source ||= Gem::Source::Installed.new
end
-
end
-
diff --git a/lib/rubygems/resolver/installer_set.rb b/lib/rubygems/resolver/installer_set.rb
index f24293c0a0..f4fee351a5 100644
--- a/lib/rubygems/resolver/installer_set.rb
+++ b/lib/rubygems/resolver/installer_set.rb
@@ -4,7 +4,6 @@
# files
class Gem::Resolver::InstallerSet < Gem::Resolver::Set
-
##
# List of Gem::Specification objects that must always be installed.
@@ -27,13 +26,18 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
attr_reader :remote_set # :nodoc:
##
+ # Ignore ruby & rubygems specification constraints.
+ #
+
+ attr_accessor :force # :nodoc:
+
+ ##
# Creates a new InstallerSet that will look for gems in +domain+.
- def initialize domain
+ def initialize(domain)
super()
@domain = domain
- @remote = consider_remote?
@f = Gem::SpecFetcher.fetcher
@@ -43,6 +47,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
@local = {}
@local_source = Gem::Source::Local.new
@remote_set = Gem::Resolver::BestSet.new
+ @force = false
@specs = {}
end
@@ -50,14 +55,14 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
# Looks up the latest specification for +dependency+ and adds it to the
# always_install list.
- def add_always_install dependency
+ def add_always_install(dependency)
request = Gem::Resolver::DependencyRequest.new dependency, nil
found = find_all request
- found.delete_if { |s|
+ found.delete_if do |s|
s.version.prerelease? and not s.local?
- } unless dependency.prerelease?
+ end unless dependency.prerelease?
found = found.select do |s|
Gem::Source::SpecificFile === s.source or
@@ -65,15 +70,30 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
Gem::Platform.local === s.platform
end
- if found.empty? then
- exc = Gem::UnsatisfiableDependencyError.new request
- exc.errors = errors
-
- raise exc
+ found = found.sort_by do |s|
+ [s.version, s.platform == Gem::Platform::RUBY ? -1 : 1]
end
- newest = found.max_by do |s|
- [s.version, s.platform == Gem::Platform::RUBY ? -1 : 1]
+ newest = found.last
+
+ unless @force
+ found_matching_metadata = found.reverse.find do |spec|
+ metadata_satisfied?(spec)
+ end
+
+ if found_matching_metadata.nil?
+ if newest
+ ensure_required_ruby_version_met(newest.spec)
+ ensure_required_rubygems_version_met(newest.spec)
+ else
+ exc = Gem::UnsatisfiableDependencyError.new request
+ exc.errors = errors
+
+ raise exc
+ end
+ else
+ newest = found_matching_metadata
+ end
end
@always_install << newest.spec
@@ -83,7 +103,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
# Adds a local gem requested using +dep_name+ with the given +spec+ that can
# be loaded and installed using the +source+.
- def add_local dep_name, spec, source
+ def add_local(dep_name, spec, source)
@local[dep_name] = [spec, source]
end
@@ -112,23 +132,23 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
# Returns an array of IndexSpecification objects matching DependencyRequest
# +req+.
- def find_all req
+ def find_all(req)
res = []
- dep = req.dependency
+ dep = req.dependency
return res if @ignore_dependencies and
- @always_install.none? { |spec| dep.match? spec }
+ @always_install.none? {|spec| dep.match? spec }
name = dep.name
dep.matching_specs.each do |gemspec|
- next if @always_install.any? { |spec| spec.name == gemspec.name }
+ next if @always_install.any? {|spec| spec.name == gemspec.name }
res << Gem::Resolver::InstalledSpecification.new(self, gemspec)
end unless @ignore_installed
- if consider_local? then
+ if consider_local?
matching_local = @local.values.select do |spec, _|
req.match? spec
end.map do |spec, source|
@@ -138,7 +158,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
res.concat matching_local
begin
- if local_spec = @local_source.find_gem(name, dep.requirement) then
+ if local_spec = @local_source.find_gem(name, dep.requirement)
res << Gem::Resolver::IndexSpecification.new(
self, local_spec.name, local_spec.version,
@local_source, local_spec.platform)
@@ -161,17 +181,17 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
@remote_set.prefetch(reqs) if consider_remote?
end
- def prerelease= allow_prerelease
+ def prerelease=(allow_prerelease)
super
@remote_set.prerelease = allow_prerelease
end
def inspect # :nodoc:
- always_install = @always_install.map { |s| s.full_name }
+ always_install = @always_install.map {|s| s.full_name }
'#<%s domain: %s specs: %p always install: %p>' % [
- self.class, @domain, @specs.keys, always_install,
+ self.class, @domain, @specs.keys, always_install
]
end
@@ -179,7 +199,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
# Called from IndexSpecification to get a true Specification
# object.
- def load_spec name, ver, platform, source # :nodoc:
+ def load_spec(name, ver, platform, source) # :nodoc:
key = "#{name}-#{ver}-#{platform}"
@specs.fetch key do
@@ -192,13 +212,13 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
##
# Has a local gem for +dep_name+ been added to this set?
- def local? dep_name # :nodoc:
+ def local?(dep_name) # :nodoc:
spec, _ = @local[dep_name]
spec
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[InstallerSet', ']' do
q.breakable
q.text "domain: #{@domain}"
@@ -213,7 +233,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
end
end
- def remote= remote # :nodoc:
+ def remote=(remote) # :nodoc:
case @domain
when :local then
@domain = :both if remote
@@ -224,4 +244,31 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
end
end
+ private
+
+ def metadata_satisfied?(spec)
+ spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
+ spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
+ end
+
+ def ensure_required_ruby_version_met(spec) # :nodoc:
+ if rrv = spec.required_ruby_version
+ ruby_version = Gem.ruby_version
+ unless rrv.satisfied_by? ruby_version
+ raise Gem::RuntimeRequirementNotMetError,
+ "#{spec.full_name} requires Ruby version #{rrv}. The current ruby version is #{ruby_version}."
+ end
+ end
+ end
+
+ def ensure_required_rubygems_version_met(spec) # :nodoc:
+ if rrgv = spec.required_rubygems_version
+ unless rrgv.satisfied_by? Gem.rubygems_version
+ rg_version = Gem::VERSION
+ raise Gem::RuntimeRequirementNotMetError,
+ "#{spec.full_name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " +
+ "Try 'gem update --system' to update RubyGems itself."
+ end
+ end
+ end
end
diff --git a/lib/rubygems/resolver/local_specification.rb b/lib/rubygems/resolver/local_specification.rb
index 1d9d22f0ac..9c69c4ab74 100644
--- a/lib/rubygems/resolver/local_specification.rb
+++ b/lib/rubygems/resolver/local_specification.rb
@@ -3,7 +3,6 @@
# A LocalSpecification comes from a .gem file on the local filesystem.
class Gem::Resolver::LocalSpecification < Gem::Resolver::SpecSpecification
-
##
# Returns +true+ if this gem is installable for the current platform.
@@ -17,7 +16,7 @@ class Gem::Resolver::LocalSpecification < Gem::Resolver::SpecSpecification
true
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[LocalSpecification', ']' do
q.breakable
q.text "name: #{name}"
@@ -37,6 +36,4 @@ class Gem::Resolver::LocalSpecification < Gem::Resolver::SpecSpecification
q.text "source: #{@source.path}"
end
end
-
end
-
diff --git a/lib/rubygems/resolver/lock_set.rb b/lib/rubygems/resolver/lock_set.rb
index 7fddc93e1c..eabf217aba 100644
--- a/lib/rubygems/resolver/lock_set.rb
+++ b/lib/rubygems/resolver/lock_set.rb
@@ -3,20 +3,19 @@
# A set of gems from a gem dependencies lockfile.
class Gem::Resolver::LockSet < Gem::Resolver::Set
-
attr_reader :specs # :nodoc:
##
# Creates a new LockSet from the given +sources+
- def initialize sources
+ def initialize(sources)
super()
@sources = sources.map do |source|
Gem::Source::Lock.new source
end
- @specs = []
+ @specs = []
end
##
@@ -26,10 +25,10 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
# The specification's set will be the current set, and the source will be
# the current set's source.
- def add name, version, platform # :nodoc:
+ def add(name, version, platform) # :nodoc:
version = Gem::Version.new version
specs = [
- Gem::Resolver::LockSpecification.new(self, name, version, @sources, platform)
+ Gem::Resolver::LockSpecification.new(self, name, version, @sources, platform),
]
@specs.concat specs
@@ -41,7 +40,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
# Returns an Array of IndexSpecification objects matching the
# DependencyRequest +req+.
- def find_all req
+ def find_all(req)
@specs.select do |spec|
req.match? spec
end
@@ -51,7 +50,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
# Loads a Gem::Specification with the given +name+, +version+ and
# +platform+. +source+ is ignored.
- def load_spec name, version, platform, source # :nodoc:
+ def load_spec(name, version, platform, source) # :nodoc:
dep = Gem::Dependency.new name, version
found = @specs.find do |spec|
@@ -63,7 +62,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
found.source.fetch_spec tuple
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[LockSet', ']' do
q.breakable
q.text 'source:'
@@ -75,9 +74,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
q.text 'specs:'
q.breakable
- q.pp @specs.map { |spec| spec.full_name }
+ q.pp @specs.map {|spec| spec.full_name }
end
end
-
end
-
diff --git a/lib/rubygems/resolver/lock_specification.rb b/lib/rubygems/resolver/lock_specification.rb
index f485675673..cdb8e4e425 100644
--- a/lib/rubygems/resolver/lock_specification.rb
+++ b/lib/rubygems/resolver/lock_specification.rb
@@ -6,10 +6,9 @@
# lockfile.
class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
-
attr_reader :sources
- def initialize set, name, version, sources, platform
+ def initialize(set, name, version, sources, platform)
super()
@name = name
@@ -27,10 +26,10 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
# This is a null install as a locked specification is considered installed.
# +options+ are ignored.
- def install options = {}
+ def install(options = {})
destination = options[:install_dir] || Gem.dir
- if File.exist? File.join(destination, 'specifications', spec.spec_name) then
+ if File.exist? File.join(destination, 'specifications', spec.spec_name)
yield nil
return
end
@@ -41,11 +40,11 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
##
# Adds +dependency+ from the lockfile to this specification
- def add_dependency dependency # :nodoc:
+ def add_dependency(dependency) # :nodoc:
@dependencies << dependency
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[LockSpecification', ']' do
q.breakable
q.text "name: #{@name}"
@@ -53,12 +52,12 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
q.breakable
q.text "version: #{@version}"
- unless @platform == Gem::Platform::RUBY then
+ unless @platform == Gem::Platform::RUBY
q.breakable
q.text "platform: #{@platform}"
end
- unless @dependencies.empty? then
+ unless @dependencies.empty?
q.breakable
q.text 'dependencies:'
q.breakable
@@ -71,9 +70,9 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
# A specification constructed from the lockfile is returned
def spec
- @spec ||= Gem::Specification.find { |spec|
+ @spec ||= Gem::Specification.find do |spec|
spec.name == @name and spec.version == @version
- }
+ end
@spec ||= Gem::Specification.new do |s|
s.name = @name
@@ -83,6 +82,4 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
s.dependencies.concat @dependencies
end
end
-
end
-
diff --git a/lib/rubygems/resolver/molinillo.rb b/lib/rubygems/resolver/molinillo.rb
index 2357f41bee..12ca740e5a 100644
--- a/lib/rubygems/resolver/molinillo.rb
+++ b/lib/rubygems/resolver/molinillo.rb
@@ -1,2 +1,2 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo'
+require_relative 'molinillo/lib/molinillo'
diff --git a/lib/rubygems/resolver/molinillo/LICENSE b/lib/rubygems/resolver/molinillo/LICENSE
new file mode 100644
index 0000000000..01feffa088
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/LICENSE
@@ -0,0 +1,9 @@
+This project is licensed under the MIT license.
+
+Copyright (c) 2014 Samuel E. Giddins segiddins@segiddins.me
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo.rb b/lib/rubygems/resolver/molinillo/lib/molinillo.rb
index 0ae4b6a912..f67badbde7 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/gem_metadata'
-require 'rubygems/resolver/molinillo/lib/molinillo/errors'
-require 'rubygems/resolver/molinillo/lib/molinillo/resolver'
-require 'rubygems/resolver/molinillo/lib/molinillo/modules/ui'
-require 'rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider'
+
+require_relative 'molinillo/gem_metadata'
+require_relative 'molinillo/errors'
+require_relative 'molinillo/resolver'
+require_relative 'molinillo/modules/ui'
+require_relative 'molinillo/modules/specification_provider'
# Gem::Resolver::Molinillo is a generic dependency resolution algorithm.
module Gem::Resolver::Molinillo
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb
index 1bbc72c1f6..d540d3baff 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
# @!visibility private
module Delegates
@@ -45,6 +46,12 @@ module Gem::Resolver::Molinillo
current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
current_state.conflicts
end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#unused_unwind_options)
+ def unused_unwind_options
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.unused_unwind_options
+ end
end
end
end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb
index 71903c7e86..b765226fb0 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
module Delegates
# Delegates all {Gem::Resolver::Molinillo::SpecificationProvider} methods to a
@@ -25,6 +26,13 @@ module Gem::Resolver::Molinillo
end
end
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#dependencies_equal?)
+ def dependencies_equal?(dependencies, other_dependencies)
+ with_no_such_dependency_error_handling do
+ specification_provider.dependencies_equal?(dependencies, other_dependencies)
+ end
+ end
+
# (see Gem::Resolver::Molinillo::SpecificationProvider#name_for)
def name_for(dependency)
with_no_such_dependency_error_handling do
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb
index b413e3ab6a..95f8416b96 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require 'set'
-require 'tsort'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex'
+require_relative '../../../../tsort'
+
+require_relative 'dependency_graph/log'
+require_relative 'dependency_graph/vertex'
module Gem::Resolver::Molinillo
# A directed acyclic graph that is tuned to hold named dependencies
@@ -17,7 +17,7 @@ module Gem::Resolver::Molinillo
vertices.values.each { |v| yield v }
end
- include TSort
+ include Gem::TSort
# @!visibility private
alias tsort_each_node each
@@ -123,6 +123,7 @@ module Gem::Resolver::Molinillo
dot.join("\n")
end
+ # @param [DependencyGraph] other
# @return [Boolean] whether the two dependency graphs are equal, determined
# by a recursive traversal of each {#root_vertices} and its
# {Vertex#successors}
@@ -147,8 +148,8 @@ module Gem::Resolver::Molinillo
vertex = add_vertex(name, payload, root)
vertex.explicit_requirements << requirement if root
parent_names.each do |parent_name|
- parent_node = vertex_named(parent_name)
- add_edge(parent_node, vertex, requirement)
+ parent_vertex = vertex_named(parent_name)
+ add_edge(parent_vertex, vertex, requirement)
end
vertex
end
@@ -189,7 +190,7 @@ module Gem::Resolver::Molinillo
# @return [Edge] the added edge
def add_edge(origin, destination, requirement)
if destination.path_to?(origin)
- raise CircularDependencyError.new([origin, destination])
+ raise CircularDependencyError.new(path(destination, origin))
end
add_edge_no_circular(origin, destination, requirement)
end
@@ -218,5 +219,37 @@ module Gem::Resolver::Molinillo
def add_edge_no_circular(origin, destination, requirement)
log.add_edge_no_circular(self, origin.name, destination.name, requirement)
end
+
+ # Returns the path between two vertices
+ # @raise [ArgumentError] if there is no path between the vertices
+ # @param [Vertex] from
+ # @param [Vertex] to
+ # @return [Array<Vertex>] the shortest path from `from` to `to`
+ def path(from, to)
+ distances = Hash.new(vertices.size + 1)
+ distances[from.name] = 0
+ predecessors = {}
+ each do |vertex|
+ vertex.successors.each do |successor|
+ if distances[successor.name] > distances[vertex.name] + 1
+ distances[successor.name] = distances[vertex.name] + 1
+ predecessors[successor] = vertex
+ end
+ end
+ end
+
+ path = [to]
+ while before = predecessors[to]
+ path << before
+ to = before
+ break if to == from
+ end
+
+ unless path.last.equal?(from)
+ raise ArgumentError, "There is no path from #{from.name} to #{to.name}"
+ end
+
+ path.reverse
+ end
end
end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb
index eeedabb069..cc140031b3 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
class DependencyGraph
# An action that modifies a {DependencyGraph} that is reversible.
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
index e994e59d05..5570483253 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
index 6cde933080..f1411d5efa 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
index d44aaf1f06..3b48d77a50 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
index fa03e2d365..92f60d5be8 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb
index 5cdd84b5c1..7aeb8847ec 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag'
+
+require_relative 'add_edge_no_circular'
+require_relative 'add_vertex'
+require_relative 'delete_edge'
+require_relative 'detach_vertex_named'
+require_relative 'set_payload'
+require_relative 'tag'
module Gem::Resolver::Molinillo
class DependencyGraph
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb
index 02cfba64a7..726292a2c3 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb
index 0cb08075ca..bfe6fd31f8 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
+
+require_relative 'action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
@@ -13,11 +14,11 @@ module Gem::Resolver::Molinillo
end
# (see Action#up)
- def up(_graph)
+ def up(graph)
end
# (see Action#down)
- def down(_graph)
+ def down(graph)
end
# @!group Tag
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb
index cebd9cafdd..77114951b2 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
class DependencyGraph
# A vertex in a {DependencyGraph} that encapsulates a {#name} and a
@@ -32,7 +33,7 @@ module Gem::Resolver::Molinillo
# @return [Array<Object>] all of the requirements that required
# this vertex
def requirements
- incoming_edges.map(&:requirement) + explicit_requirements
+ (incoming_edges.map(&:requirement) + explicit_requirements).uniq
end
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
@@ -49,14 +50,25 @@ module Gem::Resolver::Molinillo
incoming_edges.map(&:origin)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is a
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
# {#descendent?}
def recursive_predecessors
- vertices = predecessors
- vertices += vertices.map(&:recursive_predecessors).flatten(1)
- vertices.uniq!
+ _recursive_predecessors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the predecessors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
+ # {#descendent?}
+ def _recursive_predecessors(vertices = new_vertex_set)
+ incoming_edges.each do |edge|
+ vertex = edge.origin
+ next unless vertices.add?(vertex)
+ vertex._recursive_predecessors(vertices)
+ end
+
vertices
end
+ protected :_recursive_predecessors
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
# `self` as their {Edge#origin}
@@ -64,14 +76,25 @@ module Gem::Resolver::Molinillo
outgoing_edges.map(&:destination)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is an
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
# {#ancestor?}
def recursive_successors
- vertices = successors
- vertices += vertices.map(&:recursive_successors).flatten(1)
- vertices.uniq!
+ _recursive_successors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the successors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
+ # {#ancestor?}
+ def _recursive_successors(vertices = new_vertex_set)
+ outgoing_edges.each do |edge|
+ vertex = edge.destination
+ next unless vertices.add?(vertex)
+ vertex._recursive_successors(vertices)
+ end
+
vertices
end
+ protected :_recursive_successors
# @return [String] a string suitable for debugging
def inspect
@@ -105,21 +128,37 @@ module Gem::Resolver::Molinillo
# Is there a path from `self` to `other` following edges in the
# dependency graph?
- # @return true iff there is a path following edges within this {#graph}
+ # @return whether there is a path following edges within this {#graph}
def path_to?(other)
- equal?(other) || successors.any? { |v| v.path_to?(other) }
+ _path_to?(other)
end
alias descendent? path_to?
+ # @param [Vertex] other the vertex to check if there's a path to
+ # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
+ # @return [Boolean] whether there is a path to `other` from `self`
+ def _path_to?(other, visited = new_vertex_set)
+ return false unless visited.add?(self)
+ return true if equal?(other)
+ successors.any? { |v| v._path_to?(other, visited) }
+ end
+ protected :_path_to?
+
# Is there a path from `other` to `self` following edges in the
# dependency graph?
- # @return true iff there is a path following edges within this {#graph}
+ # @return whether there is a path following edges within this {#graph}
def ancestor?(other)
other.path_to?(self)
end
alias is_reachable_from? ancestor?
+
+ def new_vertex_set
+ require 'set'
+ Set.new
+ end
+ private :new_vertex_set
end
end
end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb
index 129246bf4a..ada03a901c 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
# An error that occurred during the resolution process
class ResolverError < StandardError; end
@@ -17,7 +18,7 @@ module Gem::Resolver::Molinillo
# @param [Array<Object>] required_by @see {#required_by}
def initialize(dependency, required_by = [])
@dependency = dependency
- @required_by = required_by
+ @required_by = required_by.uniq
super()
end
@@ -33,7 +34,7 @@ module Gem::Resolver::Molinillo
# An error caused by attempting to fulfil a dependency that was circular
#
- # @note This exception will be thrown iff a {Vertex} is added to a
+ # @note This exception will be thrown if and only if a {Vertex} is added to a
# {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
# existing {DependencyGraph::Vertex}
class CircularDependencyError < ResolverError
@@ -41,11 +42,11 @@ module Gem::Resolver::Molinillo
attr_reader :dependencies
# Initializes a new error with the given circular vertices.
- # @param [Array<DependencyGraph::Vertex>] nodes the nodes in the dependency
+ # @param [Array<DependencyGraph::Vertex>] vertices the vertices in the dependency
# that caused the error
- def initialize(nodes)
- super "There is a circular dependency between #{nodes.map(&:name).join(' and ')}"
- @dependencies = nodes.map(&:payload).to_set
+ def initialize(vertices)
+ super "There is a circular dependency between #{vertices.map(&:name).join(' and ')}"
+ @dependencies = vertices.map { |vertex| vertex.payload.possibilities.last }.to_set
end
end
@@ -55,11 +56,16 @@ module Gem::Resolver::Molinillo
# resolution to fail
attr_reader :conflicts
+ # @return [SpecificationProvider] the specification provider used during
+ # resolution
+ attr_reader :specification_provider
+
# Initializes a new error with the given version conflicts.
# @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
- def initialize(conflicts)
+ # @param [SpecificationProvider] specification_provider see {#specification_provider}
+ def initialize(conflicts, specification_provider)
pairs = []
- conflicts.values.flatten.map(&:requirements).flatten.each do |conflicting|
+ conflicts.values.flat_map(&:requirements).each do |conflicting|
conflicting.each do |source, conflict_requirements|
conflict_requirements.each do |c|
pairs << [c, source]
@@ -69,7 +75,69 @@ module Gem::Resolver::Molinillo
super "Unable to satisfy the following requirements:\n\n" \
"#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"
+
@conflicts = conflicts
+ @specification_provider = specification_provider
+ end
+
+ require_relative 'delegates/specification_provider'
+ include Delegates::SpecificationProvider
+
+ # @return [String] An error message that includes requirement trees,
+ # which is much more detailed & customizable than the default message
+ # @param [Hash] opts the options to create a message with.
+ # @option opts [String] :solver_name The user-facing name of the solver
+ # @option opts [String] :possibility_type The generic name of a possibility
+ # @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees
+ # @option opts [Proc] :printable_requirement A proc that pretty-prints requirements
+ # @option opts [Proc] :additional_message_for_conflict A proc that appends additional
+ # messages for each conflict
+ # @option opts [Proc] :version_for_spec A proc that returns the version number for a
+ # possibility
+ def message_with_trees(opts = {})
+ solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
+ possibility_type = opts.delete(:possibility_type) { 'possibility named' }
+ reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } }
+ printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
+ additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
+ version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
+ incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do
+ proc do |name, _conflict|
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
+ end
+ end
+
+ conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
+ o << "\n" << incompatible_version_message_for_conflict.call(name, conflict) << "\n"
+ if conflict.locked_requirement
+ o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
+ o << %( #{printable_requirement.call(conflict.locked_requirement)}\n)
+ o << %(\n)
+ end
+ o << %( In #{name_for_explicit_dependency_source}:\n)
+ trees = reduce_trees.call(conflict.requirement_trees)
+
+ o << trees.map do |tree|
+ t = ''.dup
+ depth = 2
+ tree.each do |req|
+ t << ' ' * depth << printable_requirement.call(req)
+ unless tree.last == req
+ if spec = conflict.activated_by_name[name_for(req)]
+ t << %( was resolved to #{version_for_spec.call(spec)}, which)
+ end
+ t << %( depends on)
+ end
+ t << %(\n)
+ depth += 1
+ end
+ t
+ end.join("\n")
+
+ additional_message_for_conflict.call(o, name, conflict)
+
+ o
+ end.strip
end
end
end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb
index c5b5bd729f..6b5ada7ade 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
# The version of Gem::Resolver::Molinillo.
- VERSION = '0.5.7'.freeze
+ VERSION = '0.7.0'.freeze
end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb
index 916345b12a..1067bf7439 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
- # Provides information about specifcations and dependencies to the resolver,
+ # Provides information about specifications and dependencies to the resolver,
# allowing the {Resolver} class to remain generic while still providing power
# and flexibility.
#
@@ -44,6 +45,17 @@ module Gem::Resolver::Molinillo
true
end
+ # Determines whether two arrays of dependencies are equal, and thus can be
+ # grouped.
+ #
+ # @param [Array<Object>] dependencies
+ # @param [Array<Object>] other_dependencies
+ # @return [Boolean] whether `dependencies` and `other_dependencies` should
+ # be considered equal.
+ def dependencies_equal?(dependencies, other_dependencies)
+ dependencies == other_dependencies
+ end
+
# Returns the name for the given `dependency`.
# @note This method should be 'pure', i.e. the return value should depend
# only on the `dependency` parameter.
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb
index dbc4e000e4..a810fd519c 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
# Conveys information about the resolution process to a user.
module UI
@@ -48,7 +49,8 @@ module Gem::Resolver::Molinillo
if debug?
debug_info = yield
debug_info = debug_info.inspect unless debug_info.is_a?(String)
- output.puts debug_info.split("\n").map { |s| ' ' * depth + s }
+ debug_info = debug_info.split("\n").map { |s| ":#{depth.to_s.rjust 4}: #{s}" }
+ output.puts debug_info
end
end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb
index 73a4242157..8b40e59e42 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
class Resolver
# A specific resolution from a given {Resolver}
@@ -8,22 +9,125 @@ module Gem::Resolver::Molinillo
# @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict
# @attr [Object, nil] existing the existing spec that was in conflict with
# the {#possibility}
- # @attr [Object] possibility the spec that was unable to be activated due
- # to a conflict
+ # @attr [Object] possibility_set the set of specs that was unable to be
+ # activated due to a conflict.
# @attr [Object] locked_requirement the relevant locking requirement.
# @attr [Array<Array<Object>>] requirement_trees the different requirement
# trees that led to every requirement for the conflicting name.
# @attr [{String=>Object}] activated_by_name the already-activated specs.
+ # @attr [Object] underlying_error an error that has occurred during resolution, and
+ # will be raised at the end of it if no resolution is found.
Conflict = Struct.new(
:requirement,
:requirements,
:existing,
- :possibility,
+ :possibility_set,
:locked_requirement,
:requirement_trees,
- :activated_by_name
+ :activated_by_name,
+ :underlying_error
)
+ class Conflict
+ # @return [Object] a spec that was unable to be activated due to a conflict
+ def possibility
+ possibility_set && possibility_set.latest_version
+ end
+ end
+
+ # A collection of possibility states that share the same dependencies
+ # @attr [Array] dependencies the dependencies for this set of possibilities
+ # @attr [Array] possibilities the possibilities
+ PossibilitySet = Struct.new(:dependencies, :possibilities)
+
+ class PossibilitySet
+ # String representation of the possibility set, for debugging
+ def to_s
+ "[#{possibilities.join(', ')}]"
+ end
+
+ # @return [Object] most up-to-date dependency in the possibility set
+ def latest_version
+ possibilities.last
+ end
+ end
+
+ # Details of the state to unwind to when a conflict occurs, and the cause of the unwind
+ # @attr [Integer] state_index the index of the state to unwind to
+ # @attr [Object] state_requirement the requirement of the state we're unwinding to
+ # @attr [Array] requirement_tree for the requirement we're relaxing
+ # @attr [Array] conflicting_requirements the requirements that combined to cause the conflict
+ # @attr [Array] requirement_trees for the conflict
+ # @attr [Array] requirements_unwound_to_instead array of unwind requirements that were chosen over this unwind
+ UnwindDetails = Struct.new(
+ :state_index,
+ :state_requirement,
+ :requirement_tree,
+ :conflicting_requirements,
+ :requirement_trees,
+ :requirements_unwound_to_instead
+ )
+
+ class UnwindDetails
+ include Comparable
+
+ # We compare UnwindDetails when choosing which state to unwind to. If
+ # two options have the same state_index we prefer the one most
+ # removed from a requirement that caused the conflict. Both options
+ # would unwind to the same state, but a `grandparent` option will
+ # filter out fewer of its possibilities after doing so - where a state
+ # is both a `parent` and a `grandparent` to requirements that have
+ # caused a conflict this is the correct behaviour.
+ # @param [UnwindDetail] other UnwindDetail to be compared
+ # @return [Integer] integer specifying ordering
+ def <=>(other)
+ if state_index > other.state_index
+ 1
+ elsif state_index == other.state_index
+ reversed_requirement_tree_index <=> other.reversed_requirement_tree_index
+ else
+ -1
+ end
+ end
+
+ # @return [Integer] index of state requirement in reversed requirement tree
+ # (the conflicting requirement itself will be at position 0)
+ def reversed_requirement_tree_index
+ @reversed_requirement_tree_index ||=
+ if state_requirement
+ requirement_tree.reverse.index(state_requirement)
+ else
+ 999_999
+ end
+ end
+
+ # @return [Boolean] where the requirement of the state we're unwinding
+ # to directly caused the conflict. Note: in this case, it is
+ # impossible for the state we're unwinding to to be a parent of
+ # any of the other conflicting requirements (or we would have
+ # circularity)
+ def unwinding_to_primary_requirement?
+ requirement_tree.last == state_requirement
+ end
+
+ # @return [Array] array of sub-dependencies to avoid when choosing a
+ # new possibility for the state we've unwound to. Only relevant for
+ # non-primary unwinds
+ def sub_dependencies_to_avoid
+ @requirements_to_avoid ||=
+ requirement_trees.map do |tree|
+ index = tree.index(state_requirement)
+ tree[index + 1] if index
+ end.compact
+ end
+
+ # @return [Array] array of all the requirements that led to the need for
+ # this unwind
+ def all_requirements
+ @all_requirements ||= requirement_trees.flatten(1)
+ end
+ end
+
# @return [SpecificationProvider] the provider that knows about
# dependencies, requirements, specifications, versions, etc.
attr_reader :specification_provider
@@ -64,7 +168,7 @@ module Gem::Resolver::Molinillo
start_resolution
while state
- break unless state.requirements.any? || state.requirement
+ break if !state.requirement && state.requirements.empty?
indicate_progress
if state.respond_to?(:pop_possibility_state) # DependencyState
debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
@@ -78,7 +182,7 @@ module Gem::Resolver::Molinillo
process_topmost_state
end
- activated.freeze
+ resolve_activated_specs
ensure
end_resolution
end
@@ -103,12 +207,25 @@ module Gem::Resolver::Molinillo
def start_resolution
@started_at = Time.now
- handle_missing_or_push_dependency_state(initial_state)
+ push_initial_state
debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
resolver_ui.before_resolution
end
+ def resolve_activated_specs
+ activated.vertices.each do |_, vertex|
+ next unless vertex.payload
+
+ latest_version = vertex.payload.possibilities.reverse_each.find do |possibility|
+ vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
+ end
+
+ activated.set_payload(vertex.name, latest_version)
+ end
+ activated.freeze
+ end
+
# Ends the resolution process
# @return [void]
def end_resolution
@@ -121,11 +238,11 @@ module Gem::Resolver::Molinillo
debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
end
- require 'rubygems/resolver/molinillo/lib/molinillo/state'
- require 'rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider'
+ require_relative 'state'
+ require_relative 'modules/specification_provider'
- require 'rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state'
- require 'rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider'
+ require_relative 'delegates/resolution_state'
+ require_relative 'delegates/specification_provider'
include Gem::Resolver::Molinillo::Delegates::ResolutionState
include Gem::Resolver::Molinillo::Delegates::SpecificationProvider
@@ -136,9 +253,12 @@ module Gem::Resolver::Molinillo
if possibility
attempt_to_activate
else
- create_conflict if state.is_a? PossibilityState
- unwind_for_conflict until possibility && state.is_a?(DependencyState)
+ create_conflict
+ unwind_for_conflict
end
+ rescue CircularDependencyError => underlying_error
+ create_conflict(underlying_error)
+ unwind_for_conflict
end
# @return [Object] the current possibility that the resolution is trying
@@ -153,63 +273,296 @@ module Gem::Resolver::Molinillo
states.last
end
- # Creates the initial state for the resolution, based upon the
+ # Creates and pushes the initial state for the resolution, based upon the
# {#requested} dependencies
- # @return [DependencyState] the initial state for the resolution
- def initial_state
+ # @return [void]
+ def push_initial_state
graph = DependencyGraph.new.tap do |dg|
- original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } }
+ original_requested.each do |requested|
+ vertex = dg.add_vertex(name_for(requested), nil, true)
+ vertex.explicit_requirements << requested
+ end
dg.tag(:initial_state)
end
- requirements = sort_dependencies(original_requested, graph, {})
- initial_requirement = requirements.shift
- DependencyState.new(
- initial_requirement && name_for(initial_requirement),
- requirements,
- graph,
- initial_requirement,
- initial_requirement && search_for(initial_requirement),
- 0,
- {}
- )
+ push_state_for_requirements(original_requested, true, graph)
end
# Unwinds the states stack because a conflict has been encountered
# @return [void]
def unwind_for_conflict
- debug(depth) { "Unwinding for conflict: #{requirement} to #{state_index_for_unwind / 2}" }
+ details_for_unwind = build_details_for_unwind
+ unwind_options = unused_unwind_options
+ debug(depth) { "Unwinding for conflict: #{requirement} to #{details_for_unwind.state_index / 2}" }
conflicts.tap do |c|
- sliced_states = states.slice!((state_index_for_unwind + 1)..-1)
- raise VersionConflict.new(c) unless state
+ sliced_states = states.slice!((details_for_unwind.state_index + 1)..-1)
+ raise_error_unless_state(c)
activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
state.conflicts = c
+ state.unused_unwind_options = unwind_options
+ filter_possibilities_after_unwind(details_for_unwind)
index = states.size - 1
@parents_of.each { |_, a| a.reject! { |i| i >= index } }
+ state.unused_unwind_options.reject! { |uw| uw.state_index >= index }
+ end
+ end
+
+ # Raises a VersionConflict error, or any underlying error, if there is no
+ # current state
+ # @return [void]
+ def raise_error_unless_state(conflicts)
+ return if state
+
+ error = conflicts.values.map(&:underlying_error).compact.first
+ raise error || VersionConflict.new(conflicts, specification_provider)
+ end
+
+ # @return [UnwindDetails] Details of the nearest index to which we could unwind
+ def build_details_for_unwind
+ # Get the possible unwinds for the current conflict
+ current_conflict = conflicts[name]
+ binding_requirements = binding_requirements_for_conflict(current_conflict)
+ unwind_details = unwind_options_for_requirements(binding_requirements)
+
+ last_detail_for_current_unwind = unwind_details.sort.last
+ current_detail = last_detail_for_current_unwind
+
+ # Look for past conflicts that could be unwound to affect the
+ # requirement tree for the current conflict
+ all_reqs = last_detail_for_current_unwind.all_requirements
+ all_reqs_size = all_reqs.size
+ relevant_unused_unwinds = unused_unwind_options.select do |alternative|
+ diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
+ next if diff_reqs.size == all_reqs_size
+ # Find the highest index unwind whilst looping through
+ current_detail = alternative if alternative > current_detail
+ alternative
+ end
+
+ # Add the current unwind options to the `unused_unwind_options` array.
+ # The "used" option will be filtered out during `unwind_for_conflict`.
+ state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
+
+ # Update the requirements_unwound_to_instead on any relevant unused unwinds
+ relevant_unused_unwinds.each do |d|
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
+ end
+ unwind_details.each do |d|
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
+ end
+
+ current_detail
+ end
+
+ # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
+ # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
+ # of resolving the passed requirements
+ def unwind_options_for_requirements(binding_requirements)
+ unwind_details = []
+
+ trees = []
+ binding_requirements.reverse_each do |r|
+ partial_tree = [r]
+ trees << partial_tree
+ unwind_details << UnwindDetails.new(-1, nil, partial_tree, binding_requirements, trees, [])
+
+ # If this requirement has alternative possibilities, check if any would
+ # satisfy the other requirements that created this conflict
+ requirement_state = find_state_for(r)
+ if conflict_fixing_possibilities?(requirement_state, binding_requirements)
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+
+ # Next, look at the parent of this requirement, and check if the requirement
+ # could have been avoided if an alternative PossibilitySet had been chosen
+ parent_r = parent_of(r)
+ next if parent_r.nil?
+ partial_tree.unshift(parent_r)
+ requirement_state = find_state_for(parent_r)
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(r) }
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ parent_r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+
+ # Finally, look at the grandparent and up of this requirement, looking
+ # for any possibilities that wouldn't create their parent requirement
+ grandparent_r = parent_of(parent_r)
+ until grandparent_r.nil?
+ partial_tree.unshift(grandparent_r)
+ requirement_state = find_state_for(grandparent_r)
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(parent_r) }
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ grandparent_r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+ parent_r = grandparent_r
+ grandparent_r = parent_of(parent_r)
+ end
+ end
+
+ unwind_details
+ end
+
+ # @param [DependencyState] state
+ # @param [Array] binding_requirements array of requirements
+ # @return [Boolean] whether or not the given state has any possibilities
+ # that could satisfy the given requirements
+ def conflict_fixing_possibilities?(state, binding_requirements)
+ return false unless state
+
+ state.possibilities.any? do |possibility_set|
+ possibility_set.possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, binding_requirements)
+ end
+ end
+ end
+
+ # Filter's a state's possibilities to remove any that would not fix the
+ # conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just
+ # unwound from
+ # @return [void]
+ def filter_possibilities_after_unwind(unwind_details)
+ return unless state && !state.possibilities.empty?
+
+ if unwind_details.unwinding_to_primary_requirement?
+ filter_possibilities_for_primary_unwind(unwind_details)
+ else
+ filter_possibilities_for_parent_unwind(unwind_details)
end
end
- # @return [Integer] The index to which the resolution should unwind in the
- # case of conflict.
- def state_index_for_unwind
- current_requirement = requirement
- existing_requirement = requirement_for_existing_name(name)
- index = -1
- [current_requirement, existing_requirement].each do |r|
- until r.nil?
- current_state = find_state_for(r)
- if state_any?(current_state)
- current_index = states.index(current_state)
- index = current_index if current_index > index
- break
+ # Filter's a state's possibilities to remove any that would not satisfy
+ # the requirements in the conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
+ # @return [void]
+ def filter_possibilities_for_primary_unwind(unwind_details)
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
+ unwinds_to_state << unwind_details
+ unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements)
+
+ state.possibilities.reject! do |possibility_set|
+ possibility_set.possibilities.none? do |poss|
+ unwind_requirement_sets.any? do |requirements|
+ possibility_satisfies_requirements?(poss, requirements)
end
- r = parent_of(r)
end
end
+ end
+
+ # @param [Object] possibility a single possibility
+ # @param [Array] requirements an array of requirements
+ # @return [Boolean] whether the possibility satisfies all of the
+ # given requirements
+ def possibility_satisfies_requirements?(possibility, requirements)
+ name = name_for(possibility)
+
+ activated.tag(:swap)
+ activated.set_payload(name, possibility) if activated.vertex_named(name)
+ satisfied = requirements.all? { |r| requirement_satisfied_by?(r, activated, possibility) }
+ activated.rewind_to(:swap)
+
+ satisfied
+ end
+
+ # Filter's a state's possibilities to remove any that would (eventually)
+ # create a requirement in the conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
+ # @return [void]
+ def filter_possibilities_for_parent_unwind(unwind_details)
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
+ unwinds_to_state << unwind_details
+
+ primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
+ parent_unwinds = unwinds_to_state.uniq - primary_unwinds
+
+ allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
+ states[unwind.state_index].possibilities.select do |possibility_set|
+ possibility_set.possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
+ end
+ end
+ end
+
+ requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
+
+ state.possibilities.reject! do |possibility_set|
+ !allowed_possibility_sets.include?(possibility_set) &&
+ (requirements_to_avoid - possibility_set.dependencies).empty?
+ end
+ end
+
+ # @param [Conflict] conflict
+ # @return [Array] minimal array of requirements that would cause the passed
+ # conflict to occur.
+ def binding_requirements_for_conflict(conflict)
+ return [conflict.requirement] if conflict.possibility.nil?
+
+ possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
+
+ # When there's a `CircularDependency` error the conflicting requirement
+ # (the one causing the circular) won't be `conflict.requirement`
+ # (which won't be for the right state, because we won't have created it,
+ # because it's circular).
+ # We need to make sure we have that requirement in the conflict's list,
+ # otherwise we won't be able to unwind properly, so we just return all
+ # the requirements for the conflict.
+ return possible_binding_requirements if conflict.underlying_error
+
+ possibilities = search_for(conflict.requirement)
+
+ # If all the requirements together don't filter out all possibilities,
+ # then the only two requirements we need to consider are the initial one
+ # (where the dependency's version was first chosen) and the last
+ if binding_requirement_in_set?(nil, possible_binding_requirements, possibilities)
+ return [conflict.requirement, requirement_for_existing_name(name_for(conflict.requirement))].compact
+ end
+
+ # Loop through the possible binding requirements, removing each one
+ # that doesn't bind. Use a `reverse_each` as we want the earliest set of
+ # binding requirements, and don't use `reject!` as we wish to refine the
+ # array *on each iteration*.
+ binding_requirements = possible_binding_requirements.dup
+ possible_binding_requirements.reverse_each do |req|
+ next if req == conflict.requirement
+ unless binding_requirement_in_set?(req, binding_requirements, possibilities)
+ binding_requirements -= [req]
+ end
+ end
+
+ binding_requirements
+ end
- index
+ # @param [Object] requirement we wish to check
+ # @param [Array] possible_binding_requirements array of requirements
+ # @param [Array] possibilities array of possibilities the requirements will be used to filter
+ # @return [Boolean] whether or not the given requirement is required to filter
+ # out all elements of the array of possibilities.
+ def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
+ possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, possible_binding_requirements - [requirement])
+ end
end
+ # @param [Object] requirement
# @return [Object] the requirement that led to `requirement` being added
# to the list of requirements.
def parent_of(requirement)
@@ -219,29 +572,27 @@ module Gem::Resolver::Molinillo
parent_state.requirement
end
+ # @param [String] name
# @return [Object] the requirement that led to a version of a possibility
# with the given name being activated.
def requirement_for_existing_name(name)
- return nil unless activated.vertex_named(name).payload
+ return nil unless vertex = activated.vertex_named(name)
+ return nil unless vertex.payload
states.find { |s| s.name == name }.requirement
end
+ # @param [Object] requirement
# @return [ResolutionState] the state whose `requirement` is the given
# `requirement`.
def find_state_for(requirement)
return nil unless requirement
- states.reverse_each.find { |i| requirement == i.requirement && i.is_a?(DependencyState) }
- end
-
- # @return [Boolean] whether or not the given state has any possibilities
- # left.
- def state_any?(state)
- state && state.possibilities.any?
+ states.find { |i| requirement == i.requirement }
end
+ # @param [Object] underlying_error
# @return [Conflict] a {Conflict} that reflects the failure to activate
# the {#possibility} in conjunction with the current {#state}
- def create_conflict
+ def create_conflict(underlying_error = nil)
vertex = activated.vertex_named(name)
locked_requirement = locked_requirement_named(name)
@@ -250,18 +601,21 @@ module Gem::Resolver::Molinillo
requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
end
requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
- vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) }
+ vertex.incoming_edges.each do |edge|
+ (requirements[edge.origin.payload.latest_version] ||= []).unshift(edge.requirement)
+ end
activated_by_name = {}
- activated.each { |v| activated_by_name[v.name] = v.payload if v.payload }
+ activated.each { |v| activated_by_name[v.name] = v.payload.latest_version if v.payload }
conflicts[name] = Conflict.new(
requirement,
requirements,
- vertex.payload,
+ vertex.payload && vertex.payload.latest_version,
possibility,
locked_requirement,
requirement_trees,
- activated_by_name
+ activated_by_name,
+ underlying_error
)
end
@@ -272,6 +626,7 @@ module Gem::Resolver::Molinillo
vertex.requirements.map { |r| requirement_tree_for(r) }
end
+ # @param [Object] requirement
# @return [Array<Object>] the list of requirements that led to
# `requirement` being required.
def requirement_tree_for(requirement)
@@ -311,116 +666,47 @@ module Gem::Resolver::Molinillo
# @return [void]
def attempt_to_activate
debug(depth) { 'Attempting to activate ' + possibility.to_s }
- existing_node = activated.vertex_named(name)
- if existing_node.payload
- debug(depth) { "Found existing spec (#{existing_node.payload})" }
- attempt_to_activate_existing_spec(existing_node)
+ existing_vertex = activated.vertex_named(name)
+ if existing_vertex.payload
+ debug(depth) { "Found existing spec (#{existing_vertex.payload})" }
+ attempt_to_filter_existing_spec(existing_vertex)
else
- attempt_to_activate_new_spec
- end
- end
-
- # Attempts to activate the current {#possibility} (given that it has
- # already been activated)
- # @return [void]
- def attempt_to_activate_existing_spec(existing_node)
- existing_spec = existing_node.payload
- if requirement_satisfied_by?(requirement, activated, existing_spec)
- new_requirements = requirements.dup
- push_state_for_requirements(new_requirements, false)
- else
- return if attempt_to_swap_possibility
- create_conflict
- debug(depth) { "Unsatisfied by existing spec (#{existing_node.payload})" }
- unwind_for_conflict
- end
- end
-
- # Attempts to swp the current {#possibility} with the already-activated
- # spec with the given name
- # @return [Boolean] Whether the possibility was swapped into {#activated}
- def attempt_to_swap_possibility
- activated.tag(:swap)
- vertex = activated.vertex_named(name)
- activated.set_payload(name, possibility)
- if !vertex.requirements.
- all? { |r| requirement_satisfied_by?(r, activated, possibility) } ||
- !new_spec_satisfied?
- activated.rewind_to(:swap)
- return
- end
- fixup_swapped_children(vertex)
- activate_spec
- end
-
- # Ensures there are no orphaned successors to the given {vertex}.
- # @param [DependencyGraph::Vertex] vertex the vertex to fix up.
- # @return [void]
- def fixup_swapped_children(vertex) # rubocop:disable Metrics/CyclomaticComplexity
- payload = vertex.payload
- deps = dependencies_for(payload).group_by(&method(:name_for))
- vertex.outgoing_edges.each do |outgoing_edge|
- requirement = outgoing_edge.requirement
- parent_index = @parents_of[requirement].last
- succ = outgoing_edge.destination
- matching_deps = Array(deps[succ.name])
- dep_matched = matching_deps.include?(requirement)
-
- # only push the current index when it was originally required by the
- # same named spec
- if parent_index && states[parent_index].name == name
- @parents_of[requirement].push(states.size - 1)
+ latest = possibility.latest_version
+ possibility.possibilities.select! do |possibility|
+ requirement_satisfied_by?(requirement, activated, possibility)
end
-
- if matching_deps.empty? && !succ.root? && succ.predecessors.to_a == [vertex]
- debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
- succ.requirements.each { |r| @parents_of.delete(r) }
-
- removed_names = activated.detach_vertex_named(succ.name).map(&:name)
- requirements.delete_if do |r|
- # the only removed vertices are those with no other requirements,
- # so it's safe to delete only based upon name here
- removed_names.include?(name_for(r))
- end
- elsif !dep_matched
- debug(depth) { "Removing orphaned dependency #{requirement} after swapping #{name}" }
- # also reset if we're removing the edge, but only if its parent has
- # already been fixed up
- @parents_of[requirement].push(states.size - 1) if @parents_of[requirement].empty?
-
- activated.delete_edge(outgoing_edge)
- requirements.delete(requirement)
+ if possibility.latest_version.nil?
+ # ensure there's a possibility for better error messages
+ possibility.possibilities << latest if latest
+ create_conflict
+ unwind_for_conflict
+ else
+ activate_new_spec
end
end
end
- # Attempts to activate the current {#possibility} (given that it hasn't
- # already been activated)
+ # Attempts to update the existing vertex's `PossibilitySet` with a filtered version
# @return [void]
- def attempt_to_activate_new_spec
- if new_spec_satisfied?
- activate_spec
+ def attempt_to_filter_existing_spec(vertex)
+ filtered_set = filtered_possibility_set(vertex)
+ if !filtered_set.possibilities.empty?
+ activated.set_payload(name, filtered_set)
+ new_requirements = requirements.dup
+ push_state_for_requirements(new_requirements, false)
else
create_conflict
+ debug(depth) { "Unsatisfied by existing spec (#{vertex.payload})" }
unwind_for_conflict
end
end
- # @return [Boolean] whether the current spec is satisfied as a new
- # possibility.
- def new_spec_satisfied?
- unless requirement_satisfied_by?(requirement, activated, possibility)
- debug(depth) { 'Unsatisfied by requested spec' }
- return false
- end
-
- locked_requirement = locked_requirement_named(name)
-
- locked_spec_satisfied = !locked_requirement ||
- requirement_satisfied_by?(locked_requirement, activated, possibility)
- debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
-
- locked_spec_satisfied
+ # Generates a filtered version of the existing vertex's `PossibilitySet` using the
+ # current state's `requirement`
+ # @param [Object] vertex existing vertex
+ # @return [PossibilitySet] filtered possibility set
+ def filtered_possibility_set(vertex)
+ PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
end
# @param [String] requirement_name the spec name to search for
@@ -434,7 +720,7 @@ module Gem::Resolver::Molinillo
# Add the current {#possibility} to the dependency graph of the current
# {#state}
# @return [void]
- def activate_spec
+ def activate_new_spec
conflicts.delete(name)
debug(depth) { "Activated #{name} at #{possibility}" }
activated.set_payload(name, possibility)
@@ -442,14 +728,14 @@ module Gem::Resolver::Molinillo
end
# Requires the dependencies that the recently activated spec has
- # @param [Object] activated_spec the specification that has just been
+ # @param [Object] possibility_set the PossibilitySet that has just been
# activated
# @return [void]
- def require_nested_dependencies_for(activated_spec)
- nested_dependencies = dependencies_for(activated_spec)
+ def require_nested_dependencies_for(possibility_set)
+ nested_dependencies = dependencies_for(possibility_set.latest_version)
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
nested_dependencies.each do |d|
- activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d)
+ activated.add_child_vertex(name_for(d), nil, [name_for(possibility_set.latest_version)], d)
parent_index = states.size - 1
parents = @parents_of[d]
parents << parent_index if parents.empty?
@@ -461,23 +747,82 @@ module Gem::Resolver::Molinillo
# Pushes a new {DependencyState} that encapsulates both existing and new
# requirements
# @param [Array] new_requirements
+ # @param [Boolean] requires_sort
+ # @param [Object] new_activated
# @return [void]
def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
- new_requirement = new_requirements.shift
+ new_requirement = nil
+ loop do
+ new_requirement = new_requirements.shift
+ break if new_requirement.nil? || states.none? { |s| s.requirement == new_requirement }
+ end
new_name = new_requirement ? name_for(new_requirement) : ''.freeze
- possibilities = new_requirement ? search_for(new_requirement) : []
+ possibilities = possibilities_for_requirement(new_requirement)
handle_missing_or_push_dependency_state DependencyState.new(
new_name, new_requirements, new_activated,
- new_requirement, possibilities, depth, conflicts.dup
+ new_requirement, possibilities, depth, conflicts.dup, unused_unwind_options.dup
)
end
+ # Checks a proposed requirement with any existing locked requirement
+ # before generating an array of possibilities for it.
+ # @param [Object] requirement the proposed requirement
+ # @param [Object] activated
+ # @return [Array] possibilities
+ def possibilities_for_requirement(requirement, activated = self.activated)
+ return [] unless requirement
+ if locked_requirement_named(name_for(requirement))
+ return locked_requirement_possibility_set(requirement, activated)
+ end
+
+ group_possibilities(search_for(requirement))
+ end
+
+ # @param [Object] requirement the proposed requirement
+ # @param [Object] activated
+ # @return [Array] possibility set containing only the locked requirement, if any
+ def locked_requirement_possibility_set(requirement, activated = self.activated)
+ all_possibilities = search_for(requirement)
+ locked_requirement = locked_requirement_named(name_for(requirement))
+
+ # Longwinded way to build a possibilities array with either the locked
+ # requirement or nothing in it. Required, since the API for
+ # locked_requirement isn't guaranteed.
+ locked_possibilities = all_possibilities.select do |possibility|
+ requirement_satisfied_by?(locked_requirement, activated, possibility)
+ end
+
+ group_possibilities(locked_possibilities)
+ end
+
+ # Build an array of PossibilitySets, with each element representing a group of
+ # dependency versions that all have the same sub-dependency version constraints
+ # and are contiguous.
+ # @param [Array] possibilities an array of possibilities
+ # @return [Array<PossibilitySet>] an array of possibility sets
+ def group_possibilities(possibilities)
+ possibility_sets = []
+ current_possibility_set = nil
+
+ possibilities.reverse_each do |possibility|
+ dependencies = dependencies_for(possibility)
+ if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
+ current_possibility_set.possibilities.unshift(possibility)
+ else
+ possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
+ current_possibility_set = possibility_sets.first
+ end
+ end
+
+ possibility_sets
+ end
+
# Pushes a new {DependencyState}.
# If the {#specification_provider} says to
# {SpecificationProvider#allow_missing?} that particular requirement, and
# there are no possibilities for that requirement, then `state` is not
- # pushed, and the node in {#activated} is removed, and we continue
+ # pushed, and the vertex in {#activated} is removed, and we continue
# resolving the remaining requirements.
# @param [DependencyState] state
# @return [void]
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb
index 5c59a45c3d..d43121f8ca 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph'
+
+require_relative 'dependency_graph'
module Gem::Resolver::Molinillo
# This class encapsulates a dependency resolver.
@@ -8,7 +9,7 @@ module Gem::Resolver::Molinillo
#
#
class Resolver
- require 'rubygems/resolver/molinillo/lib/molinillo/resolution'
+ require_relative 'resolution'
# @return [SpecificationProvider] the specification provider used
# in the resolution process
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb
index c20de98854..6e7c715fce 100644
--- a/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gem::Resolver::Molinillo
# A state that a {Resolution} can be in
# @attr [String] name the name of the current requirement
@@ -7,7 +8,8 @@ module Gem::Resolver::Molinillo
# @attr [Object] requirement the current requirement
# @attr [Object] possibilities the possibilities to satisfy the current requirement
# @attr [Integer] depth the depth of the resolution
- # @attr [Set<Object>] conflicts unresolved conflicts
+ # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name
+ # @attr [Array<UnwindDetails>] unused_unwind_options unwinds for previous conflicts that weren't explored
ResolutionState = Struct.new(
:name,
:requirements,
@@ -15,14 +17,15 @@ module Gem::Resolver::Molinillo
:requirement,
:possibilities,
:depth,
- :conflicts
+ :conflicts,
+ :unused_unwind_options
)
class ResolutionState
# Returns an empty resolution state
# @return [ResolutionState] an empty state
def self.empty
- new(nil, [], DependencyGraph.new, nil, nil, 0, Set.new)
+ new(nil, [], DependencyGraph.new, nil, nil, 0, {}, [])
end
end
@@ -40,7 +43,8 @@ module Gem::Resolver::Molinillo
requirement,
[possibilities.pop],
depth + 1,
- conflicts.dup
+ conflicts.dup,
+ unused_unwind_options.dup
).tap do |state|
state.activated.tag(state)
end
diff --git a/lib/rubygems/resolver/requirement_list.rb b/lib/rubygems/resolver/requirement_list.rb
index 2768c80170..5b51493c9a 100644
--- a/lib/rubygems/resolver/requirement_list.rb
+++ b/lib/rubygems/resolver/requirement_list.rb
@@ -7,7 +7,6 @@
# first.
class Gem::Resolver::RequirementList
-
include Enumerable
##
@@ -18,7 +17,7 @@ class Gem::Resolver::RequirementList
@list = []
end
- def initialize_copy other # :nodoc:
+ def initialize_copy(other) # :nodoc:
@exact = @exact.dup
@list = @list.dup
end
diff --git a/lib/rubygems/resolver/set.rb b/lib/rubygems/resolver/set.rb
index 11704d5c4c..5d8dd51eaa 100644
--- a/lib/rubygems/resolver/set.rb
+++ b/lib/rubygems/resolver/set.rb
@@ -4,7 +4,6 @@
# dependencies) used in resolution. This set is abstract.
class Gem::Resolver::Set
-
##
# Set to true to disable network access for this set
@@ -21,7 +20,6 @@ class Gem::Resolver::Set
attr_accessor :prerelease
def initialize # :nodoc:
- require 'uri'
@prerelease = false
@remote = true
@errors = []
@@ -31,7 +29,7 @@ class Gem::Resolver::Set
# The find_all method must be implemented. It returns all Resolver
# Specification objects matching the given DependencyRequest +req+.
- def find_all req
+ def find_all(req)
raise NotImplementedError
end
@@ -43,7 +41,7 @@ class Gem::Resolver::Set
# When overridden, the #prefetch method should look up specifications
# matching +reqs+.
- def prefetch reqs
+ def prefetch(reqs)
end
##
@@ -53,5 +51,4 @@ class Gem::Resolver::Set
def remote? # :nodoc:
@remote
end
-
end
diff --git a/lib/rubygems/resolver/source_set.rb b/lib/rubygems/resolver/source_set.rb
index 66f5963e54..bf8c23184e 100644
--- a/lib/rubygems/resolver/source_set.rb
+++ b/lib/rubygems/resolver/source_set.rb
@@ -4,7 +4,6 @@
# Kind off like BestSet but filters the sources for gems
class Gem::Resolver::SourceSet < Gem::Resolver::Set
-
##
# Creates a SourceSet for the given +sources+ or Gem::sources if none are
# specified. +sources+ must be a Gem::SourceList.
@@ -16,7 +15,7 @@ class Gem::Resolver::SourceSet < Gem::Resolver::Set
@sets = {}
end
- def find_all req # :nodoc:
+ def find_all(req) # :nodoc:
if set = get_set(req.dependency.name)
set.find_all req
else
@@ -25,7 +24,7 @@ class Gem::Resolver::SourceSet < Gem::Resolver::Set
end
# potentially no-op
- def prefetch reqs # :nodoc:
+ def prefetch(reqs) # :nodoc:
reqs.each do |req|
if set = get_set(req.dependency.name)
set.prefetch reqs
@@ -33,16 +32,14 @@ class Gem::Resolver::SourceSet < Gem::Resolver::Set
end
end
- def add_source_gem name, source
+ def add_source_gem(name, source)
@links[name] = source
end
-private
+ private
def get_set(name)
link = @links[name]
@sets[link] ||= Gem::Source.new(link).dependency_resolver_set if link
end
-
end
-
diff --git a/lib/rubygems/resolver/spec_specification.rb b/lib/rubygems/resolver/spec_specification.rb
index 35ee8cc247..7b665fe876 100644
--- a/lib/rubygems/resolver/spec_specification.rb
+++ b/lib/rubygems/resolver/spec_specification.rb
@@ -4,13 +4,12 @@
# Resolver specifications that are backed by a Gem::Specification.
class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
-
##
# A SpecSpecification is created for a +set+ for a Gem::Specification in
# +spec+. The +source+ is either where the +spec+ came from, or should be
# loaded from.
- def initialize set, spec, source = nil
+ def initialize(set, spec, source = nil)
@set = set
@source = source
@spec = spec
@@ -24,6 +23,20 @@ class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
end
##
+ # The required_ruby_version constraint for this specification
+
+ def required_ruby_version
+ spec.required_ruby_version
+ end
+
+ ##
+ # The required_rubygems_version constraint for this specification
+
+ def required_rubygems_version
+ spec.required_rubygems_version
+ end
+
+ ##
# The name and version of the specification.
#
# Unlike Gem::Specification#full_name, the platform is not included.
@@ -52,6 +65,4 @@ class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
def version
spec.version
end
-
end
-
diff --git a/lib/rubygems/resolver/specification.rb b/lib/rubygems/resolver/specification.rb
index 44989d39ae..dfcb7eb057 100644
--- a/lib/rubygems/resolver/specification.rb
+++ b/lib/rubygems/resolver/specification.rb
@@ -5,7 +5,6 @@
# dependency resolution in the resolver is included.
class Gem::Resolver::Specification
-
##
# The dependencies of the gem for this specification
@@ -45,6 +44,16 @@ class Gem::Resolver::Specification
attr_reader :version
##
+ # The required_ruby_version constraint for this specification.
+
+ attr_reader :required_ruby_version
+
+ ##
+ # The required_ruby_version constraint for this specification.
+
+ attr_reader :required_rubygems_version
+
+ ##
# Sets default instance variables for the specification.
def initialize
@@ -54,6 +63,8 @@ class Gem::Resolver::Specification
@set = nil
@source = nil
@version = nil
+ @required_ruby_version = Gem::Requirement.default
+ @required_rubygems_version = Gem::Requirement.default
end
##
@@ -81,14 +92,10 @@ class Gem::Resolver::Specification
# After installation #spec is updated to point to the just-installed
# specification.
- def install options = {}
- require 'rubygems/installer'
+ def install(options = {})
+ require_relative '../installer'
- destination = options[:install_dir] || Gem.dir
-
- Gem.ensure_gem_subdirectories destination
-
- gem = source.download spec, destination
+ gem = download options
installer = Gem::Installer.at gem, options
@@ -97,15 +104,22 @@ class Gem::Resolver::Specification
@spec = installer.install
end
+ def download(options)
+ dir = options[:install_dir] || Gem.dir
+
+ Gem.ensure_gem_subdirectories dir
+
+ source.download spec, dir
+ end
+
##
# Returns true if this specification is installable on this platform.
def installable_platform?
- Gem::Platform.match spec.platform
+ Gem::Platform.match_spec? spec
end
def local? # :nodoc:
false
end
end
-
diff --git a/lib/rubygems/resolver/stats.rb b/lib/rubygems/resolver/stats.rb
index 3b95efebf7..64b458f504 100644
--- a/lib/rubygems/resolver/stats.rb
+++ b/lib/rubygems/resolver/stats.rb
@@ -32,7 +32,7 @@ class Gem::Resolver::Stats
@iterations += 1
end
- PATTERN = "%20s: %d\n"
+ PATTERN = "%20s: %d\n".freeze
def display
$stdout.puts "=== Resolver Statistics ==="
diff --git a/lib/rubygems/resolver/vendor_set.rb b/lib/rubygems/resolver/vendor_set.rb
index f30ce534af..48c640d8c9 100644
--- a/lib/rubygems/resolver/vendor_set.rb
+++ b/lib/rubygems/resolver/vendor_set.rb
@@ -15,7 +15,6 @@
# rake.gemspec (watching the given name).
class Gem::Resolver::VendorSet < Gem::Resolver::Set
-
##
# The specifications for this set.
@@ -32,7 +31,7 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
# Adds a specification to the set with the given +name+ which has been
# unpacked into the given +directory+.
- def add_vendor_gem name, directory # :nodoc:
+ def add_vendor_gem(name, directory) # :nodoc:
gemspec = File.join directory, "#{name}.gemspec"
spec = Gem::Specification.load gemspec
@@ -52,7 +51,7 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
# Returns an Array of VendorSpecification objects matching the
# DependencyRequest +req+.
- def find_all req
+ def find_all(req)
@specs.values.select do |spec|
req.match? spec
end.map do |spec|
@@ -65,11 +64,11 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
# Loads a spec with the given +name+. +version+, +platform+ and +source+ are
# ignored.
- def load_spec name, version, platform, source # :nodoc:
+ def load_spec(name, version, platform, source) # :nodoc:
@specs.fetch name
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[VendorSet', ']' do
next if @directories.empty?
q.breakable
@@ -83,6 +82,4 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
end
end
end
-
end
-
diff --git a/lib/rubygems/resolver/vendor_specification.rb b/lib/rubygems/resolver/vendor_specification.rb
index c624f3e834..8dfe5940f2 100644
--- a/lib/rubygems/resolver/vendor_specification.rb
+++ b/lib/rubygems/resolver/vendor_specification.rb
@@ -5,8 +5,7 @@
# option.
class Gem::Resolver::VendorSpecification < Gem::Resolver::SpecSpecification
-
- def == other # :nodoc:
+ def ==(other) # :nodoc:
self.class === other and
@set == other.set and
@spec == other.spec and
@@ -17,9 +16,7 @@ class Gem::Resolver::VendorSpecification < Gem::Resolver::SpecSpecification
# This is a null install as this gem was unpacked into a directory.
# +options+ are ignored.
- def install options = {}
+ def install(options = {})
yield nil
end
-
end
-
diff --git a/lib/rubygems/s3_uri_signer.rb b/lib/rubygems/s3_uri_signer.rb
new file mode 100644
index 0000000000..4d1deee997
--- /dev/null
+++ b/lib/rubygems/s3_uri_signer.rb
@@ -0,0 +1,175 @@
+require_relative 'openssl'
+
+##
+# S3URISigner implements AWS SigV4 for S3 Source to avoid a dependency on the aws-sdk-* gems
+# More on AWS SigV4: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
+class Gem::S3URISigner
+ class ConfigurationError < Gem::Exception
+ def initialize(message)
+ super message
+ end
+
+ def to_s # :nodoc:
+ "#{super}"
+ end
+ end
+
+ class InstanceProfileError < Gem::Exception
+ def initialize(message)
+ super message
+ end
+
+ def to_s # :nodoc:
+ "#{super}"
+ end
+ end
+
+ attr_accessor :uri
+
+ def initialize(uri)
+ @uri = uri
+ end
+
+ ##
+ # Signs S3 URI using query-params according to the reference: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
+ def sign(expiration = 86400)
+ s3_config = fetch_s3_config
+
+ current_time = Time.now.utc
+ date_time = current_time.strftime("%Y%m%dT%H%m%SZ")
+ date = date_time[0,8]
+
+ credential_info = "#{date}/#{s3_config.region}/s3/aws4_request"
+ canonical_host = "#{uri.host}.s3.#{s3_config.region}.amazonaws.com"
+
+ query_params = generate_canonical_query_params(s3_config, date_time, credential_info, expiration)
+ canonical_request = generate_canonical_request(canonical_host, query_params)
+ string_to_sign = generate_string_to_sign(date_time, credential_info, canonical_request)
+ signature = generate_signature(s3_config, date, string_to_sign)
+
+ URI.parse("https://#{canonical_host}#{uri.path}?#{query_params}&X-Amz-Signature=#{signature}")
+ end
+
+ private
+
+ S3Config = Struct.new :access_key_id, :secret_access_key, :security_token, :region
+
+ def generate_canonical_query_params(s3_config, date_time, credential_info, expiration)
+ canonical_params = {}
+ canonical_params["X-Amz-Algorithm"] = "AWS4-HMAC-SHA256"
+ canonical_params["X-Amz-Credential"] = "#{s3_config.access_key_id}/#{credential_info}"
+ canonical_params["X-Amz-Date"] = date_time
+ canonical_params["X-Amz-Expires"] = expiration.to_s
+ canonical_params["X-Amz-SignedHeaders"] = "host"
+ canonical_params["X-Amz-Security-Token"] = s3_config.security_token if s3_config.security_token
+
+ # Sorting is required to generate proper signature
+ canonical_params.sort.to_h.map do |key, value|
+ "#{base64_uri_escape(key)}=#{base64_uri_escape(value)}"
+ end.join("&")
+ end
+
+ def generate_canonical_request(canonical_host, query_params)
+ [
+ "GET",
+ uri.path,
+ query_params,
+ "host:#{canonical_host}",
+ "", # empty params
+ "host",
+ "UNSIGNED-PAYLOAD",
+ ].join("\n")
+ end
+
+ def generate_string_to_sign(date_time, credential_info, canonical_request)
+ [
+ "AWS4-HMAC-SHA256",
+ date_time,
+ credential_info,
+ OpenSSL::Digest::SHA256.hexdigest(canonical_request),
+ ].join("\n")
+ end
+
+ def generate_signature(s3_config, date, string_to_sign)
+ date_key = OpenSSL::HMAC.digest("sha256", "AWS4" + s3_config.secret_access_key, date)
+ date_region_key = OpenSSL::HMAC.digest("sha256", date_key, s3_config.region)
+ date_region_service_key = OpenSSL::HMAC.digest("sha256", date_region_key, "s3")
+ signing_key = OpenSSL::HMAC.digest("sha256", date_region_service_key, "aws4_request")
+ OpenSSL::HMAC.hexdigest("sha256", signing_key, string_to_sign)
+ end
+
+ ##
+ # Extracts S3 configuration for S3 bucket
+ def fetch_s3_config
+ return S3Config.new(uri.user, uri.password, nil, "us-east-1") if uri.user && uri.password
+
+ s3_source = Gem.configuration[:s3_source] || Gem.configuration["s3_source"]
+ host = uri.host
+ raise ConfigurationError.new("no s3_source key exists in .gemrc") unless s3_source
+
+ auth = s3_source[host] || s3_source[host.to_sym]
+ raise ConfigurationError.new("no key for host #{host} in s3_source in .gemrc") unless auth
+
+ provider = auth[:provider] || auth["provider"]
+ case provider
+ when "env"
+ id = ENV["AWS_ACCESS_KEY_ID"]
+ secret = ENV["AWS_SECRET_ACCESS_KEY"]
+ security_token = ENV["AWS_SESSION_TOKEN"]
+ when "instance_profile"
+ credentials = ec2_metadata_credentials_json
+ id = credentials["AccessKeyId"]
+ secret = credentials["SecretAccessKey"]
+ security_token = credentials["Token"]
+ else
+ id = auth[:id] || auth["id"]
+ secret = auth[:secret] || auth["secret"]
+ security_token = auth[:security_token] || auth["security_token"]
+ end
+
+ raise ConfigurationError.new("s3_source for #{host} missing id or secret") unless id && secret
+
+ region = auth[:region] || auth["region"] || "us-east-1"
+ S3Config.new(id, secret, security_token, region)
+ end
+
+ def base64_uri_escape(str)
+ str.gsub(/[\+\/=\n]/, BASE64_URI_TRANSLATE)
+ end
+
+ def ec2_metadata_credentials_json
+ require 'net/http'
+ require_relative 'request'
+ require_relative 'request/connection_pools'
+ require 'json'
+
+ iam_info = ec2_metadata_request(EC2_IAM_INFO)
+ # Expected format: arn:aws:iam::<id>:instance-profile/<role_name>
+ role_name = iam_info['InstanceProfileArn'].split('/').last
+ ec2_metadata_request(EC2_IAM_SECURITY_CREDENTIALS + role_name)
+ end
+
+ def ec2_metadata_request(url)
+ uri = URI(url)
+ @request_pool ||= create_request_pool(uri)
+ request = Gem::Request.new(uri, Net::HTTP::Get, nil, @request_pool)
+ response = request.fetch
+
+ case response
+ when Net::HTTPOK then
+ JSON.parse(response.body)
+ else
+ raise InstanceProfileError.new("Unable to fetch AWS metadata from #{uri}: #{response.message} #{response.code}")
+ end
+ end
+
+ def create_request_pool(uri)
+ proxy_uri = Gem::Request.proxy_uri(Gem::Request.get_proxy_from_env(uri.scheme))
+ certs = Gem::Request.get_cert_files
+ Gem::Request::ConnectionPools.new(proxy_uri, certs).pool_for(uri)
+ end
+
+ BASE64_URI_TRANSLATE = { "+" => "%2B", "/" => "%2F", "=" => "%3D", "\n" => "" }.freeze
+ EC2_IAM_INFO = "http://169.254.169.254/latest/meta-data/iam/info".freeze
+ EC2_IAM_SECURITY_CREDENTIALS = "http://169.254.169.254/latest/meta-data/iam/security-credentials/".freeze
+end
diff --git a/lib/rubygems/safe_yaml.rb b/lib/rubygems/safe_yaml.rb
index b98cfaa5e6..e905052e1c 100644
--- a/lib/rubygems/safe_yaml.rb
+++ b/lib/rubygems/safe_yaml.rb
@@ -7,7 +7,7 @@ module Gem
# Psych.safe_load
module SafeYAML
- WHITELISTED_CLASSES = %w(
+ PERMITTED_CLASSES = %w[
Symbol
Time
Date
@@ -17,30 +17,39 @@ module Gem
Gem::Specification
Gem::Version
Gem::Version::Requirement
- YAML::Syck::DefaultKey
- Syck::DefaultKey
- )
+ ].freeze
- WHITELISTED_SYMBOLS = %w(
+ PERMITTED_SYMBOLS = %w[
development
runtime
- )
+ ].freeze
if ::YAML.respond_to? :safe_load
- def self.safe_load input
- ::YAML.safe_load(input, WHITELISTED_CLASSES, WHITELISTED_SYMBOLS, true)
+ def self.safe_load(input)
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0.pre1')
+ ::YAML.safe_load(input, permitted_classes: PERMITTED_CLASSES, permitted_symbols: PERMITTED_SYMBOLS, aliases: true)
+ else
+ ::YAML.safe_load(input, PERMITTED_CLASSES, PERMITTED_SYMBOLS, true)
+ end
end
- def self.load input
- ::YAML.safe_load(input, [::Symbol])
+ def self.load(input)
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0.pre1')
+ ::YAML.safe_load(input, permitted_classes: [::Symbol])
+ else
+ ::YAML.safe_load(input, [::Symbol])
+ end
end
else
- warn "YAML safe loading is not available. Please upgrade psych to a version that supports safe loading (>= 2.0)."
- def self.safe_load input, *args
+ unless Gem::Deprecate.skip
+ warn "YAML safe loading is not available. Please upgrade psych to a version that supports safe loading (>= 2.0)."
+ end
+
+ def self.safe_load(input, *args)
::YAML.load input
end
- def self.load input
+ def self.load(input)
::YAML.load input
end
end
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
index 4690dd9230..8240a1a059 100644
--- a/lib/rubygems/security.rb
+++ b/lib/rubygems/security.rb
@@ -5,15 +5,8 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems/exceptions'
-require 'fileutils'
-
-begin
- require 'openssl'
-rescue LoadError => e
- raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
- e.message =~ / -- openssl$/
-end
+require_relative 'exceptions'
+require_relative 'openssl'
##
# = Signing gems
@@ -62,11 +55,11 @@ end
#
# $ tar tf your-gem-1.0.gem
# metadata.gz
-# metadata.gz.sum
# metadata.gz.sig # metadata signature
# data.tar.gz
-# data.tar.gz.sum
# data.tar.gz.sig # data signature
+# checksums.yaml.gz
+# checksums.yaml.gz.sig # checksums signature
#
# === Manually signing gems
#
@@ -159,8 +152,11 @@ end
# certificate for EMAIL_ADDR
# -C, --certificate CERT Signing certificate for --sign
# -K, --private-key KEY Key for --sign or --build
+# -A, --key-algorithm ALGORITHM Select key algorithm for --build from RSA, DSA, or EC. Defaults to RSA.
# -s, --sign CERT Signs CERT with the key from -K
# and the certificate from -C
+# -d, --days NUMBER_OF_DAYS Days before the certificate expires
+# -R, --re-sign Re-signs the certificate from -C with the key from -K
#
# We've already covered the <code>--build</code> option, and the
# <code>--add</code>, <code>--list</code>, and <code>--remove</code> commands
@@ -265,7 +261,7 @@ end
# 2. Grab the public key from the gemspec
#
# gem spec some_signed_gem-1.0.gem cert_chain | \
-# ruby -ryaml -e 'puts YAML.load_documents($stdin)' > public_key.crt
+# ruby -ryaml -e 'puts YAML.load($stdin)' > public_key.crt
#
# 3. Generate a SHA1 hash of the data.tar.gz
#
@@ -322,7 +318,6 @@ end
# * Honor extension restrictions
# * Might be better to store the certificate chain as a PKCS#7 or PKCS#12
# file, instead of an array embedded in the metadata.
-# * Flexible signature and key algorithms, not hard-coded to RSA and SHA1.
#
# == Original author
#
@@ -337,35 +332,24 @@ module Gem::Security
class Exception < Gem::Exception; end
##
- # Digest algorithm used to sign gems
+ # Used internally to select the signing digest from all computed digests
- DIGEST_ALGORITHM =
- if defined?(OpenSSL::Digest::SHA256) then
- OpenSSL::Digest::SHA256
- elsif defined?(OpenSSL::Digest::SHA1) then
- OpenSSL::Digest::SHA1
- end
+ DIGEST_NAME = 'SHA256' # :nodoc:
##
- # Used internally to select the signing digest from all computed digests
+ # Length of keys created by RSA and DSA keys
- DIGEST_NAME = # :nodoc:
- if DIGEST_ALGORITHM then
- DIGEST_ALGORITHM.new.name
- end
+ RSA_DSA_KEY_LENGTH = 3072
##
- # Algorithm for creating the key pair used to sign gems
+ # Default algorithm to use when building a key pair
- KEY_ALGORITHM =
- if defined?(OpenSSL::PKey::RSA) then
- OpenSSL::PKey::RSA
- end
+ DEFAULT_KEY_ALGORITHM = 'RSA'
##
- # Length of keys created by KEY_ALGORITHM
+ # Named curve used for Elliptic Curve
- KEY_LENGTH = 3072
+ EC_NAME = 'secp384r1'
##
# Cipher used to encrypt the key pair used to sign gems.
@@ -396,9 +380,9 @@ module Gem::Security
'keyUsage' =>
'keyEncipherment,dataEncipherment,digitalSignature',
'subjectKeyIdentifier' => 'hash',
- }
+ }.freeze
- def self.alt_name_or_x509_entry certificate, x509_entry
+ def self.alt_name_or_x509_entry(certificate, x509_entry)
alt_name = certificate.extensions.find do |extension|
extension.oid == "#{x509_entry}AltName"
end
@@ -414,11 +398,11 @@ module Gem::Security
#
# The +extensions+ restrict the key to the indicated uses.
- def self.create_cert subject, key, age = ONE_YEAR, extensions = EXTENSIONS,
- serial = 1
+ def self.create_cert(subject, key, age = ONE_YEAR, extensions = EXTENSIONS,
+ serial = 1)
cert = OpenSSL::X509::Certificate.new
- cert.public_key = key.public_key
+ cert.public_key = get_public_key(key)
cert.version = 2
cert.serial = serial
@@ -437,11 +421,29 @@ module Gem::Security
end
##
+ # Gets the right public key from a PKey instance
+
+ def self.get_public_key(key)
+ return key.public_key unless key.is_a?(OpenSSL::PKey::EC)
+
+ ec_key = OpenSSL::PKey::EC.new(key.group.curve_name)
+ ec_key.public_key = key.public_key
+ ec_key
+ end
+
+ ##
+ # In Ruby 2.3 EC doesn't implement the private_key? but not the private? method
+
+ if defined?(OpenSSL::PKey::EC) && Gem::Version.new(String.new(RUBY_VERSION)) < Gem::Version.new("2.4.0")
+ OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
+ end
+
+ ##
# Creates a self-signed certificate with an issuer and subject from +email+,
# a subject alternative name of +email+ and the given +extensions+ for the
# +key+.
- def self.create_cert_email email, key, age = ONE_YEAR, extensions = EXTENSIONS
+ def self.create_cert_email(email, key, age = ONE_YEAR, extensions = EXTENSIONS)
subject = email_to_name email
extensions = extensions.merge "subjectAltName" => "email:#{email}"
@@ -453,32 +455,62 @@ module Gem::Security
# Creates a self-signed certificate with an issuer and subject of +subject+
# and the given +extensions+ for the +key+.
- def self.create_cert_self_signed subject, key, age = ONE_YEAR,
- extensions = EXTENSIONS, serial = 1
+ def self.create_cert_self_signed(subject, key, age = ONE_YEAR,
+ extensions = EXTENSIONS, serial = 1)
certificate = create_cert subject, key, age, extensions
sign certificate, key, certificate, age, extensions, serial
end
##
- # Creates a new key pair of the specified +length+ and +algorithm+. The
- # default is a 3072 bit RSA key.
+ # Creates a new digest instance using the specified +algorithm+. The default
+ # is SHA256.
+
+ if defined?(OpenSSL::Digest)
+ def self.create_digest(algorithm = DIGEST_NAME)
+ OpenSSL::Digest.new(algorithm)
+ end
+ else
+ require 'digest'
+
+ def self.create_digest(algorithm = DIGEST_NAME)
+ Digest.const_get(algorithm).new
+ end
+ end
- def self.create_key length = KEY_LENGTH, algorithm = KEY_ALGORITHM
- algorithm.new length
+ ##
+ # Creates a new key pair of the specified +algorithm+. RSA, DSA, and EC
+ # are supported.
+
+ def self.create_key(algorithm)
+ if defined?(OpenSSL::PKey)
+ case algorithm.downcase
+ when 'dsa'
+ OpenSSL::PKey::DSA.new(RSA_DSA_KEY_LENGTH)
+ when 'rsa'
+ OpenSSL::PKey::RSA.new(RSA_DSA_KEY_LENGTH)
+ when 'ec'
+ domain_key = OpenSSL::PKey::EC.new(EC_NAME)
+ domain_key.generate_key
+ domain_key
+ else
+ raise Gem::Security::Exception,
+ "#{algorithm} algorithm not found. RSA, DSA, and EC algorithms are supported."
+ end
+ end
end
##
# Turns +email_address+ into an OpenSSL::X509::Name
- def self.email_to_name email_address
+ def self.email_to_name(email_address)
email_address = email_address.gsub(/[^\w@.-]+/i, '_')
cn, dcs = email_address.split '@'
dcs = dcs.split '.'
- name = "CN=#{cn}/#{dcs.map { |dc| "DC=#{dc}" }.join '/'}"
+ name = "CN=#{cn}/#{dcs.map {|dc| "DC=#{dc}" }.join '/'}"
OpenSSL::X509::Name.parse name
end
@@ -489,15 +521,15 @@ module Gem::Security
#--
# TODO increment serial
- def self.re_sign expired_certificate, private_key, age = ONE_YEAR,
- extensions = EXTENSIONS
+ def self.re_sign(expired_certificate, private_key, age = ONE_YEAR,
+ extensions = EXTENSIONS)
raise Gem::Security::Exception,
"incorrect signing key for re-signing " +
"#{expired_certificate.subject}" unless
- expired_certificate.public_key.to_pem == private_key.public_key.to_pem
+ expired_certificate.public_key.to_pem == get_public_key(private_key).to_pem
unless expired_certificate.subject.to_s ==
- expired_certificate.issuer.to_s then
+ expired_certificate.issuer.to_s
subject = alt_name_or_x509_entry expired_certificate, :subject
issuer = alt_name_or_x509_entry expired_certificate, :issuer
@@ -521,13 +553,13 @@ module Gem::Security
##
# Sign the public key from +certificate+ with the +signing_key+ and
- # +signing_cert+, using the Gem::Security::DIGEST_ALGORITHM. Uses the
+ # +signing_cert+, using the Gem::Security::DIGEST_NAME. Uses the
# default certificate validity range and extensions.
#
# Returns the newly signed certificate.
- def self.sign certificate, signing_key, signing_cert,
- age = ONE_YEAR, extensions = EXTENSIONS, serial = 1
+ def self.sign(certificate, signing_key, signing_cert,
+ age = ONE_YEAR, extensions = EXTENSIONS, serial = 1)
signee_subject = certificate.subject
signee_key = certificate.public_key
@@ -548,7 +580,7 @@ module Gem::Security
signed = create_cert signee_subject, signee_key, age, extensions, serial
signed.issuer = signing_cert.subject
- signed.sign signing_key, Gem::Security::DIGEST_ALGORITHM.new
+ signed.sign signing_key, Gem::Security::DIGEST_NAME
end
##
@@ -566,7 +598,7 @@ module Gem::Security
##
# Enumerates the trusted certificates via Gem::Security::TrustDir.
- def self.trusted_certificates &block
+ def self.trusted_certificates(&block)
trust_dir.each_certificate(&block)
end
@@ -575,10 +607,10 @@ module Gem::Security
# +permissions+. If passed +cipher+ and +passphrase+ those arguments will be
# passed to +to_pem+.
- def self.write pemmable, path, permissions = 0600, passphrase = nil, cipher = KEY_CIPHER
+ def self.write(pemmable, path, permissions = 0600, passphrase = nil, cipher = KEY_CIPHER)
path = File.expand_path path
- open path, 'wb', permissions do |io|
+ File.open path, 'wb', permissions do |io|
if passphrase and cipher
io.write pemmable.to_pem cipher, passphrase
else
@@ -593,11 +625,10 @@ module Gem::Security
end
-if defined?(OpenSSL::SSL) then
- require 'rubygems/security/policy'
- require 'rubygems/security/policies'
- require 'rubygems/security/trust_dir'
+if Gem::HAVE_OPENSSL
+ require_relative 'security/policy'
+ require_relative 'security/policies'
+ require_relative 'security/trust_dir'
end
-require 'rubygems/security/signer'
-
+require_relative 'security/signer'
diff --git a/lib/rubygems/security/policies.rb b/lib/rubygems/security/policies.rb
index f16c46306a..8f6ad99316 100644
--- a/lib/rubygems/security/policies.rb
+++ b/lib/rubygems/security/policies.rb
@@ -110,7 +110,6 @@ module Gem::Security
'MediumSecurity' => MediumSecurity,
'HighSecurity' => HighSecurity,
# SigningPolicy is not intended for use by `gem -P` so do not list it
- }
+ }.freeze
end
-
diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb
index f43e6c8c96..3c3cb647ee 100644
--- a/lib/rubygems/security/policy.rb
+++ b/lib/rubygems/security/policy.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require 'rubygems/user_interaction'
+require_relative '../user_interaction'
##
# A Gem::Security::Policy object encapsulates the settings for verifying
@@ -8,7 +8,6 @@ require 'rubygems/user_interaction'
# Gem::Security::Policies.
class Gem::Security::Policy
-
include Gem::UserInteraction
attr_reader :name
@@ -24,9 +23,7 @@ class Gem::Security::Policy
# Create a new Gem::Security::Policy object with the given mode and
# options.
- def initialize name, policy = {}, opt = {}
- require 'openssl'
-
+ def initialize(name, policy = {}, opt = {})
@name = name
@opt = opt
@@ -55,7 +52,7 @@ class Gem::Security::Policy
# Verifies each certificate in +chain+ has signed the following certificate
# and is valid for the given +time+.
- def check_chain chain, time
+ def check_chain(chain, time)
raise Gem::Security::Exception, 'missing signing chain' unless chain
raise Gem::Security::Exception, 'empty signing chain' if chain.empty?
@@ -74,9 +71,9 @@ class Gem::Security::Policy
# Verifies that +data+ matches the +signature+ created by +public_key+ and
# the +digest+ algorithm.
- def check_data public_key, digest, signature, data
+ def check_data(public_key, digest, signature, data)
raise Gem::Security::Exception, "invalid signature" unless
- public_key.verify digest.new, signature, data.digest
+ public_key.verify digest, signature, data.digest
true
end
@@ -85,22 +82,22 @@ class Gem::Security::Policy
# Ensures that +signer+ is valid for +time+ and was signed by the +issuer+.
# If the +issuer+ is +nil+ no verification is performed.
- def check_cert signer, issuer, time
+ def check_cert(signer, issuer, time)
raise Gem::Security::Exception, 'missing signing certificate' unless
signer
message = "certificate #{signer.subject}"
- if not_before = signer.not_before and not_before > time then
+ if not_before = signer.not_before and not_before > time
raise Gem::Security::Exception,
"#{message} not valid before #{not_before}"
end
- if not_after = signer.not_after and not_after < time then
+ if not_after = signer.not_after and not_after < time
raise Gem::Security::Exception, "#{message} not valid after #{not_after}"
end
- if issuer and not signer.verify issuer.public_key then
+ if issuer and not signer.verify issuer.public_key
raise Gem::Security::Exception,
"#{message} was not issued by #{issuer.subject}"
end
@@ -111,16 +108,18 @@ class Gem::Security::Policy
##
# Ensures the public key of +key+ matches the public key in +signer+
- def check_key signer, key
- unless signer and key then
+ def check_key(signer, key)
+ unless signer and key
return true unless @only_signed
raise Gem::Security::Exception, 'missing key or signature'
end
+ public_key = Gem::Security.get_public_key(key)
+
raise Gem::Security::Exception,
"certificate #{signer.subject} does not match the signing key" unless
- signer.public_key.to_pem == key.public_key.to_pem
+ signer.public_key.to_pem == public_key.to_pem
true
end
@@ -129,7 +128,7 @@ class Gem::Security::Policy
# Ensures the root certificate in +chain+ is self-signed and valid for
# +time+.
- def check_root chain, time
+ def check_root(chain, time)
raise Gem::Security::Exception, 'missing signing chain' unless chain
root = chain.first
@@ -139,7 +138,7 @@ class Gem::Security::Policy
raise Gem::Security::Exception,
"root certificate #{root.subject} is not self-signed " +
"(issuer #{root.issuer})" if
- root.issuer.to_s != root.subject.to_s # HACK to_s is for ruby 1.8
+ root.issuer != root.subject
check_cert root, root, time
end
@@ -148,7 +147,7 @@ class Gem::Security::Policy
# Ensures the root of +chain+ has a trusted certificate in +trust_dir+ and
# the digests of the two certificates match according to +digester+
- def check_trust chain, digester, trust_dir
+ def check_trust(chain, digester, trust_dir)
raise Gem::Security::Exception, 'missing signing chain' unless chain
root = chain.first
@@ -157,7 +156,7 @@ class Gem::Security::Policy
path = Gem::Security.trust_dir.cert_path root
- unless File.exist? path then
+ unless File.exist? path
message = "root cert #{root.subject} is not trusted".dup
message << " (root of signing cert #{chain.last.subject})" if
@@ -167,9 +166,9 @@ class Gem::Security::Policy
end
save_cert = OpenSSL::X509::Certificate.new File.read path
- save_dgst = digester.digest save_cert.public_key.to_s
+ save_dgst = digester.digest save_cert.public_key.to_pem
- pkey_str = root.public_key.to_s
+ pkey_str = root.public_key.to_pem
cert_dgst = digester.digest pkey_str
raise Gem::Security::Exception,
@@ -183,7 +182,7 @@ class Gem::Security::Policy
##
# Extracts the email or subject from +certificate+
- def subject certificate # :nodoc:
+ def subject(certificate) # :nodoc:
certificate.extensions.each do |extension|
next unless extension.oid == 'subjectAltName'
@@ -196,9 +195,9 @@ class Gem::Security::Policy
def inspect # :nodoc:
("[Policy: %s - data: %p signer: %p chain: %p root: %p " +
"signed-only: %p trusted-only: %p]") % [
- @name, @verify_chain, @verify_data, @verify_root, @verify_signer,
- @only_signed, @only_trusted,
- ]
+ @name, @verify_chain, @verify_data, @verify_root, @verify_signer,
+ @only_signed, @only_trusted
+ ]
end
##
@@ -208,13 +207,13 @@ class Gem::Security::Policy
#
# If +key+ is given it is used to validate the signing certificate.
- def verify chain, key = nil, digests = {}, signatures = {},
- full_name = '(unknown)'
- if signatures.empty? then
- if @only_signed then
+ def verify(chain, key = nil, digests = {}, signatures = {},
+ full_name = '(unknown)')
+ if signatures.empty?
+ if @only_signed
raise Gem::Security::Exception,
"unsigned gems are not allowed by the #{name} policy"
- elsif digests.empty? then
+ elsif digests.empty?
# lack of signatures is irrelevant if there is nothing to check
# against
else
@@ -224,7 +223,7 @@ class Gem::Security::Policy
end
opt = @opt
- digester = Gem::Security::DIGEST_ALGORITHM
+ digester = Gem::Security.create_digest
trust_dir = opt[:trust_dir]
time = Time.now
@@ -232,7 +231,7 @@ class Gem::Security::Policy
file_digests.values.first.name == Gem::Security::DIGEST_NAME
end
- if @verify_data then
+ if @verify_data
raise Gem::Security::Exception, 'no digests provided (probable bug)' if
signer_digests.nil? or signer_digests.empty?
else
@@ -249,9 +248,9 @@ class Gem::Security::Policy
check_root chain, time if @verify_root
- if @only_trusted then
+ if @only_trusted
check_trust chain, digester, trust_dir
- elsif signatures.empty? and digests.empty? then
+ elsif signatures.empty? and digests.empty?
# trust is irrelevant if there's no signatures to verify
else
alert_warning "#{subject signer} is not trusted for #{full_name}"
@@ -280,7 +279,7 @@ class Gem::Security::Policy
# Extracts the certificate chain from the +spec+ and calls #verify to ensure
# the signatures and certificate chain is valid according to the policy..
- def verify_signatures spec, digests, signatures
+ def verify_signatures(spec, digests, signatures)
chain = spec.cert_chain.map do |cert_pem|
OpenSSL::X509::Certificate.new cert_pem
end
@@ -291,5 +290,4 @@ class Gem::Security::Policy
end
alias to_s name # :nodoc:
-
end
diff --git a/lib/rubygems/security/signer.rb b/lib/rubygems/security/signer.rb
index 0c6ef60a9a..968cf88973 100644
--- a/lib/rubygems/security/signer.rb
+++ b/lib/rubygems/security/signer.rb
@@ -2,7 +2,10 @@
##
# Basic OpenSSL-based package signing class.
+require_relative "../user_interaction"
+
class Gem::Security::Signer
+ include Gem::UserInteraction
##
# The chain of certificates for signing including the signing certificate
@@ -26,31 +29,65 @@ class Gem::Security::Signer
attr_reader :digest_name # :nodoc:
##
+ # Gem::Security::Signer options
+
+ attr_reader :options
+
+ DEFAULT_OPTIONS = {
+ expiration_length_days: 365,
+ }.freeze
+
+ ##
+ # Attempts to re-sign an expired cert with a given private key
+ def self.re_sign_cert(expired_cert, expired_cert_path, private_key)
+ return unless expired_cert.not_after < Time.now
+
+ expiry = expired_cert.not_after.strftime('%Y%m%d%H%M%S')
+ expired_cert_file = "#{File.basename(expired_cert_path)}.expired.#{expiry}"
+ new_expired_cert_path = File.join(Gem.user_home, ".gem", expired_cert_file)
+
+ Gem::Security.write(expired_cert, new_expired_cert_path)
+
+ re_signed_cert = Gem::Security.re_sign(
+ expired_cert,
+ private_key,
+ (Gem::Security::ONE_DAY * Gem.configuration.cert_expiration_length_days)
+ )
+
+ Gem::Security.write(re_signed_cert, expired_cert_path)
+
+ yield(expired_cert_path, new_expired_cert_path) if block_given?
+ end
+
+ ##
# Creates a new signer with an RSA +key+ or path to a key, and a certificate
# +chain+ containing X509 certificates, encoding certificates or paths to
# certificates.
- def initialize key, cert_chain, passphrase = nil
+ def initialize(key, cert_chain, passphrase = nil, options = {})
@cert_chain = cert_chain
@key = key
+ @passphrase = passphrase
+ @options = DEFAULT_OPTIONS.merge(options)
- unless @key then
- default_key = File.join Gem.default_key_path
+ unless @key
+ default_key = File.join Gem.default_key_path
@key = default_key if File.exist? default_key
end
- unless @cert_chain then
+ unless @cert_chain
default_cert = File.join Gem.default_cert_path
@cert_chain = [default_cert] if File.exist? default_cert
end
- @digest_algorithm = Gem::Security::DIGEST_ALGORITHM
@digest_name = Gem::Security::DIGEST_NAME
+ @digest_algorithm = Gem::Security.create_digest(@digest_name)
- @key = OpenSSL::PKey::RSA.new File.read(@key), passphrase if
- @key and not OpenSSL::PKey::RSA === @key
+ if @key && !@key.is_a?(OpenSSL::PKey::PKey)
+ @key = OpenSSL::PKey.read(File.read(@key), @passphrase)
+ end
- if @cert_chain then
+ if @cert_chain
@cert_chain = @cert_chain.compact.map do |cert|
next cert if OpenSSL::X509::Certificate === cert
@@ -67,11 +104,11 @@ class Gem::Security::Signer
# Extracts the full name of +cert+. If the certificate has a subjectAltName
# this value is preferred, otherwise the subject is used.
- def extract_name cert # :nodoc:
- subject_alt_name = cert.extensions.find { |e| 'subjectAltName' == e.oid }
+ def extract_name(cert) # :nodoc:
+ subject_alt_name = cert.extensions.find {|e| 'subjectAltName' == e.oid }
- if subject_alt_name then
- /\Aemail:/ =~ subject_alt_name.value
+ if subject_alt_name
+ /\Aemail:/ =~ subject_alt_name.value # rubocop:disable Performance/StartWith
$' || subject_alt_name.value
else
@@ -99,13 +136,17 @@ class Gem::Security::Signer
##
# Sign data with given digest algorithm
- def sign data
+ def sign(data)
return unless @key
raise Gem::Security::Exception, 'no certs provided' if @cert_chain.empty?
- if @cert_chain.length == 1 and @cert_chain.last.not_after < Time.now then
- re_sign_key
+ if @cert_chain.length == 1 and @cert_chain.last.not_after < Time.now
+ alert("Your certificate has expired, trying to re-sign it...")
+
+ re_sign_key(
+ expiration_length: (Gem::Security::ONE_DAY * options[:expiration_length_days])
+ )
end
full_name = extract_name @cert_chain.last
@@ -121,6 +162,7 @@ class Gem::Security::Signer
# The key will be re-signed if:
# * The expired certificate is self-signed
# * The expired certificate is saved at ~/.gem/gem-public_cert.pem
+ # and the private key is saved at ~/.gem/gem-private_key.pem
# * There is no file matching the expiry date at
# ~/.gem/gem-public_cert.pem.expired.%Y%m%d%H%M%S
#
@@ -128,30 +170,34 @@ class Gem::Security::Signer
# be saved as ~/.gem/gem-public_cert.pem.expired.%Y%m%d%H%M%S where the
# expiry time (not after) is used for the timestamp.
- def re_sign_key # :nodoc:
+ def re_sign_key(expiration_length: Gem::Security::ONE_YEAR) # :nodoc:
old_cert = @cert_chain.last
- disk_cert_path = File.join Gem.default_cert_path
- disk_cert = File.read disk_cert_path rescue nil
- disk_key =
- File.read File.join(Gem.default_key_path) rescue nil
+ disk_cert_path = File.join(Gem.default_cert_path)
+ disk_cert = File.read(disk_cert_path) rescue nil
- if disk_key == @key.to_pem and disk_cert == old_cert.to_pem then
- expiry = old_cert.not_after.strftime '%Y%m%d%H%M%S'
+ disk_key_path = File.join(Gem.default_key_path)
+ disk_key = OpenSSL::PKey.read(File.read(disk_key_path), @passphrase) rescue nil
+
+ return unless disk_key
+
+ if disk_key.to_pem == @key.to_pem && disk_cert == old_cert.to_pem
+ expiry = old_cert.not_after.strftime('%Y%m%d%H%M%S')
old_cert_file = "gem-public_cert.pem.expired.#{expiry}"
- old_cert_path = File.join Gem.user_home, ".gem", old_cert_file
+ old_cert_path = File.join(Gem.user_home, ".gem", old_cert_file)
+
+ unless File.exist?(old_cert_path)
+ Gem::Security.write(old_cert, old_cert_path)
- unless File.exist? old_cert_path then
- Gem::Security.write old_cert, old_cert_path
+ cert = Gem::Security.re_sign(old_cert, @key, expiration_length)
- cert = Gem::Security.re_sign old_cert, @key
+ Gem::Security.write(cert, disk_cert_path)
- Gem::Security.write cert, disk_cert_path
+ alert("Your cert: #{disk_cert_path} has been auto re-signed with the key: #{disk_key_path}")
+ alert("Your expired cert will be located at: #{old_cert_path}")
@cert_chain = [cert]
end
end
end
-
end
-
diff --git a/lib/rubygems/security/trust_dir.rb b/lib/rubygems/security/trust_dir.rb
index bf44975cc6..456947274c 100644
--- a/lib/rubygems/security/trust_dir.rb
+++ b/lib/rubygems/security/trust_dir.rb
@@ -4,14 +4,13 @@
# verification.
class Gem::Security::TrustDir
-
##
# Default permissions for the trust directory and its contents
DEFAULT_PERMISSIONS = {
:trust_dir => 0700,
:trusted_cert => 0600,
- }
+ }.freeze
##
# The directory where trusted certificates will be stored.
@@ -22,17 +21,17 @@ class Gem::Security::TrustDir
# Creates a new TrustDir using +dir+ where the directory and file
# permissions will be checked according to +permissions+
- def initialize dir, permissions = DEFAULT_PERMISSIONS
+ def initialize(dir, permissions = DEFAULT_PERMISSIONS)
@dir = dir
@permissions = permissions
- @digester = Gem::Security::DIGEST_ALGORITHM
+ @digester = Gem::Security.create_digest
end
##
# Returns the path to the trusted +certificate+
- def cert_path certificate
+ def cert_path(certificate)
name_path certificate.subject
end
@@ -59,7 +58,7 @@ class Gem::Security::TrustDir
# Returns the issuer certificate of the given +certificate+ if it exists in
# the trust directory.
- def issuer_of certificate
+ def issuer_of(certificate)
path = name_path certificate.issuer
return unless File.exist? path
@@ -70,7 +69,7 @@ class Gem::Security::TrustDir
##
# Returns the path to the trusted certificate with the given ASN.1 +name+
- def name_path name
+ def name_path(name)
digest = @digester.hexdigest name.to_s
File.join @dir, "cert-#{digest}.pem"
@@ -79,7 +78,7 @@ class Gem::Security::TrustDir
##
# Loads the given +certificate_file+
- def load_certificate certificate_file
+ def load_certificate(certificate_file)
pem = File.read certificate_file
OpenSSL::X509::Certificate.new pem
@@ -88,13 +87,14 @@ class Gem::Security::TrustDir
##
# Add a certificate to trusted certificate list.
- def trust_cert certificate
+ def trust_cert(certificate)
verify
destination = cert_path certificate
- open destination, 'wb', @permissions[:trusted_cert] do |io|
+ File.open destination, 'wb', 0600 do |io|
io.write certificate.to_pem
+ io.chmod(@permissions[:trusted_cert])
end
end
@@ -104,7 +104,8 @@ class Gem::Security::TrustDir
# permissions.
def verify
- if File.exist? @dir then
+ require 'fileutils'
+ if File.exist? @dir
raise Gem::Security::Exception,
"trust directory #{@dir} is not a directory" unless
File.directory? @dir
@@ -114,6 +115,4 @@ class Gem::Security::TrustDir
FileUtils.mkdir_p @dir, :mode => @permissions[:trust_dir]
end
end
-
end
-
diff --git a/lib/rubygems/security_option.rb b/lib/rubygems/security_option.rb
index 4e3473acb4..a4c570ded5 100644
--- a/lib/rubygems/security_option.rb
+++ b/lib/rubygems/security_option.rb
@@ -5,7 +5,7 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems'
+require_relative '../rubygems'
# forward-declare
@@ -19,17 +19,16 @@ end
module Gem::SecurityOption
def add_security_option
- # TODO: use @parser.accept
- OptionParser.accept Gem::Security::Policy do |value|
- require 'rubygems/security'
+ Gem::OptionParser.accept Gem::Security::Policy do |value|
+ require_relative 'security'
- raise OptionParser::InvalidArgument, 'OpenSSL not installed' unless
+ raise Gem::OptionParser::InvalidArgument, 'OpenSSL not installed' unless
defined?(Gem::Security::HighSecurity)
policy = Gem::Security::Policies[value]
unless policy
valid = Gem::Security::Policies.keys.sort
- raise OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)"
+ raise Gem::OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)"
end
policy
end
diff --git a/lib/rubygems/server.rb b/lib/rubygems/server.rb
index 93b3af36f8..45be05bcda 100644
--- a/lib/rubygems/server.rb
+++ b/lib/rubygems/server.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require 'webrick'
require 'zlib'
require 'erb'
require 'uri'
-require 'rubygems'
-require 'rubygems/rdoc'
+require_relative '../rubygems'
+require_relative 'rdoc'
##
# Gem::Server and allows users to serve gems for consumption by
@@ -29,13 +28,12 @@ require 'rubygems/rdoc'
# TODO Refactor into a real WEBrick servlet to remove code duplication.
class Gem::Server
-
attr_reader :spec_dirs
include ERB::Util
include Gem::UserInteraction
- SEARCH = <<-ERB
+ SEARCH = <<-ERB.freeze
<form class="headerSearch" name="headerSearchForm" method="get" action="/rdoc">
<div id="search" style="float:right">
<label for="q">Filter/Search</label>
@@ -45,7 +43,7 @@ class Gem::Server
</form>
ERB
- DOC_TEMPLATE = <<-'ERB'
+ DOC_TEMPLATE = <<-'ERB'.freeze
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@@ -129,7 +127,7 @@ class Gem::Server
ERB
# CSS is copy & paste from rdoc-style.css, RDoc V1.0.1 - 20041108
- RDOC_CSS = <<-CSS
+ RDOC_CSS = <<-CSS.freeze
body {
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 90%;
@@ -339,7 +337,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
.ruby-value { color: #7fffd4; background: transparent; }
CSS
- RDOC_NO_DOCUMENTATION = <<-'ERB'
+ RDOC_NO_DOCUMENTATION = <<-'ERB'.freeze
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -373,7 +371,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
</html>
ERB
- RDOC_SEARCH_TEMPLATE = <<-'ERB'
+ RDOC_SEARCH_TEMPLATE = <<-'ERB'.freeze
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -430,6 +428,12 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end
def initialize(gem_dirs, port, daemon, launch = nil, addresses = nil)
+ begin
+ require 'webrick'
+ rescue LoadError
+ abort "webrick is not found. You may need to `gem install webrick` to install webrick."
+ end
+
Gem::RDoc.load_rdoc
Socket.do_not_reverse_lookup = true
@@ -442,15 +446,15 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL
@server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger
- @spec_dirs = @gem_dirs.map { |gem_dir| File.join gem_dir, 'specifications' }
- @spec_dirs.reject! { |spec_dir| !File.directory? spec_dir }
+ @spec_dirs = @gem_dirs.map {|gem_dir| File.join gem_dir, 'specifications' }
+ @spec_dirs.reject! {|spec_dir| !File.directory? spec_dir }
reset_gems
@have_rdoc_4_plus = nil
end
- def add_date res
+ def add_date(res)
res['date'] = @spec_dirs.map do |spec_dir|
File.stat(spec_dir).mtime
end.max
@@ -458,12 +462,12 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
def uri_encode(str)
str.gsub(URI::UNSAFE) do |match|
- match.each_byte.map { |c| sprintf('%%%02X', c.ord) }.join
+ match.each_byte.map {|c| sprintf('%%%02X', c.ord) }.join
end
end
- def doc_root gem_name
- if have_rdoc_4_plus? then
+ def doc_root(gem_name)
+ if have_rdoc_4_plus?
"/doc_root/#{u gem_name}/"
else
"/doc_root/#{u gem_name}/rdoc/index.html"
@@ -491,14 +495,14 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
specs = Marshal.dump specs
- if req.path =~ /\.gz$/ then
- specs = Gem.gzip specs
+ if req.path =~ /\.gz$/
+ specs = Gem::Util.gzip specs
res['content-type'] = 'application/x-gzip'
else
res['content-type'] = 'application/octet-stream'
end
- if req.request_method == 'HEAD' then
+ if req.request_method == 'HEAD'
res['content-length'] = specs.length
else
res.body << specs
@@ -509,7 +513,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
# Creates server sockets based on the addresses option. If no addresses
# were given a server socket for all interfaces is created.
- def listen addresses = @addresses
+ def listen(addresses = @addresses)
addresses = [nil] unless addresses
listeners = 0
@@ -529,14 +533,14 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end
end
- if @server.listeners.empty? then
+ if @server.listeners.empty?
say "Unable to start a server."
say "Check for running servers or your --bind and --port arguments"
terminate_interaction 1
end
end
- def prerelease_specs req, res
+ def prerelease_specs(req, res)
reset_gems
res['content-type'] = 'application/x-gzip'
@@ -552,14 +556,14 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
specs = Marshal.dump specs
- if req.path =~ /\.gz$/ then
- specs = Gem.gzip specs
+ if req.path =~ /\.gz$/
+ specs = Gem::Util.gzip specs
res['content-type'] = 'application/x-gzip'
else
res['content-type'] = 'application/octet-stream'
end
- if req.request_method == 'HEAD' then
+ if req.request_method == 'HEAD'
res['content-length'] = specs.length
else
res.body << specs
@@ -573,19 +577,19 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
add_date res
case req.request_uri.path
- when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)\.gemspec\.rz$| then
+ when %r{^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)\.gemspec\.rz$} then
marshal_format, full_name = $1, $2
specs = Gem::Specification.find_all_by_full_name(full_name)
selector = full_name.inspect
- if specs.empty? then
+ if specs.empty?
res.status = 404
res.body = "No gems found matching #{selector}"
- elsif specs.length > 1 then
+ elsif specs.length > 1
res.status = 500
res.body = "Multiple gems found matching #{selector}"
- elsif marshal_format then
+ elsif marshal_format
res['content-type'] = 'application/x-deflate'
res.body << Gem.deflate(Marshal.dump(specs.first))
end
@@ -607,22 +611,34 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
Gem::Specification.each do |spec|
total_file_count += spec.files.size
- deps = spec.dependencies.map { |dep|
+ deps = spec.dependencies.map do |dep|
{
"name" => dep.name,
"type" => dep.type,
"version" => dep.requirement.to_s,
}
- }
+ end
- deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] }
+ deps = deps.sort_by {|dep| [dep["name"].downcase, dep["version"]] }
deps.last["is_last"] = true unless deps.empty?
# executables
- executables = spec.executables.sort.collect { |exec| {"executable" => exec} }
+ executables = spec.executables.sort.collect {|exec| {"executable" => exec} }
executables = nil if executables.empty?
executables.last["is_last"] = true if executables
+ # Pre-process spec homepage for safety reasons
+ begin
+ homepage_uri = URI.parse(spec.homepage)
+ if [URI::HTTP, URI::HTTPS].member? homepage_uri.class
+ homepage_uri = spec.homepage
+ else
+ homepage_uri = "."
+ end
+ rescue URI::InvalidURIError
+ homepage_uri = "."
+ end
+
specs << {
"authors" => spec.authors.sort.join(", "),
"date" => spec.date.to_s,
@@ -632,7 +648,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
"only_one_executable" => (executables && executables.size == 1),
"full_name" => spec.full_name,
"has_deps" => !deps.empty?,
- "homepage" => spec.homepage,
+ "homepage" => homepage_uri,
"name" => spec.name,
"rdoc_installed" => Gem::RDoc.new(spec).rdoc_installed?,
"ri_installed" => Gem::RDoc.new(spec).ri_installed?,
@@ -649,14 +665,14 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
"only_one_executable" => true,
"full_name" => "rubygems-#{Gem::VERSION}",
"has_deps" => false,
- "homepage" => "http://guides.rubygems.org/",
+ "homepage" => "https://guides.rubygems.org/",
"name" => 'rubygems',
"ri_installed" => true,
"summary" => "RubyGems itself",
"version" => Gem::VERSION,
}
- specs = specs.sort_by { |spec| [spec["name"].downcase, spec["version"]] }
+ specs = specs.sort_by {|spec| [spec["name"].downcase, spec["version"]] }
specs.last["is_last"] = true
# tag all specs with first_name_entry
@@ -742,9 +758,9 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
# documentation - just put it underneath the main doc folder.
def show_rdoc_for_pattern(pattern, res)
- found_gems = Dir.glob("{#{@gem_dirs.join ','}}/doc/#{pattern}").select {|path|
+ found_gems = Dir.glob("{#{@gem_dirs.join ','}}/doc/#{pattern}").select do |path|
File.exist? File.join(path, 'rdoc/index.html')
- }
+ end
case found_gems.length
when 0
return false
@@ -760,7 +776,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
doc_items << {
:name => base_name,
:url => doc_root(new_path),
- :summary => ''
+ :summary => '',
}
end
@@ -806,7 +822,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
'/gems' => '/cache/',
}
- if have_rdoc_4_plus? then
+ if have_rdoc_4_plus?
@server.mount '/doc_root', RDoc::Servlet, '/doc_root'
else
file_handlers['/doc_root'] = '/doc/'
@@ -839,14 +855,14 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
specs = Marshal.dump specs
- if req.path =~ /\.gz$/ then
- specs = Gem.gzip specs
+ if req.path =~ /\.gz$/
+ specs = Gem::Util.gzip specs
res['content-type'] = 'application/x-gzip'
else
res['content-type'] = 'application/octet-stream'
end
- if req.request_method == 'HEAD' then
+ if req.request_method == 'HEAD'
res['content-length'] = specs.length
else
res.body << specs
@@ -857,7 +873,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
listeners = @server.listeners.map{|l| l.addr[2] }
# TODO: 0.0.0.0 == any, not localhost.
- host = listeners.any?{|l| l == '0.0.0.0'} ? 'localhost' : listeners.first
+ host = listeners.any?{|l| l == '0.0.0.0' } ? 'localhost' : listeners.first
say "Launching browser to http://#{host}:#{@port}"
diff --git a/lib/rubygems/source.rb b/lib/rubygems/source.rb
index bd84c217a7..b5bd6b80e6 100644
--- a/lib/rubygems/source.rb
+++ b/lib/rubygems/source.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
-autoload :FileUtils, 'fileutils'
-autoload :URI, 'uri'
+require_relative "text"
##
# A Source knows how to list and fetch gems from a RubyGems marshal index.
#
@@ -9,14 +8,14 @@ autoload :URI, 'uri'
# bundler dependency API and so-forth.
class Gem::Source
-
include Comparable
+ include Gem::Text
FILES = { # :nodoc:
:released => 'specs',
:latest => 'latest_specs',
:prerelease => 'prerelease_specs',
- }
+ }.freeze
##
# The URI this source will fetch gems from.
@@ -36,15 +35,6 @@ class Gem::Source
end
@uri = uri
- @api_uri = nil
- end
-
- ##
- # Use an SRV record on the host to look up the true endpoint for the index.
-
- def api_uri # :nodoc:
- require 'rubygems/remote_fetcher'
- @api_uri ||= Gem::RemoteFetcher.fetcher.api_endpoint uri
end
##
@@ -77,7 +67,7 @@ class Gem::Source
end
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
self.class === other and @uri == other.uri
end
@@ -87,9 +77,17 @@ class Gem::Source
# Returns a Set that can fetch specifications from this source.
def dependency_resolver_set # :nodoc:
- return Gem::Resolver::IndexSet.new self if 'file' == api_uri.scheme
+ return Gem::Resolver::IndexSet.new self if 'file' == uri.scheme
+
+ fetch_uri = if uri.host == "rubygems.org"
+ index_uri = uri.dup
+ index_uri.host = "index.rubygems.org"
+ index_uri
+ else
+ uri
+ end
- bundler_api_uri = api_uri + './api/v1/dependencies'
+ bundler_api_uri = enforce_trailing_slash(fetch_uri)
begin
fetcher = Gem::RemoteFetcher.fetcher
@@ -97,11 +95,7 @@ class Gem::Source
rescue Gem::RemoteFetcher::FetchError
Gem::Resolver::IndexSet.new self
else
- if response.respond_to? :uri then
- Gem::Resolver::APISet.new response.uri
- else
- Gem::Resolver::APISet.new bundler_api_uri
- end
+ Gem::Resolver::APISet.new response.uri + "./info/"
end
end
@@ -115,7 +109,7 @@ class Gem::Source
def cache_dir(uri)
# Correct for windows paths
escaped_path = uri.path.sub(/^\/([a-z]):\//i, '/\\1-/')
- escaped_path.untaint
+ escaped_path.tap(&Gem::UNTAINT)
File.join Gem.spec_cache_dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path)
end
@@ -135,32 +129,33 @@ class Gem::Source
##
# Fetches a specification for the given +name_tuple+.
- def fetch_spec name_tuple
+ def fetch_spec(name_tuple)
fetcher = Gem::RemoteFetcher.fetcher
spec_file_name = name_tuple.spec_name
- uri = api_uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
+ source_uri = enforce_trailing_slash(uri) + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
- cache_dir = cache_dir uri
+ cache_dir = cache_dir source_uri
local_spec = File.join cache_dir, spec_file_name
- if File.exist? local_spec then
+ if File.exist? local_spec
spec = Gem.read_binary local_spec
spec = Marshal.load(spec) rescue nil
return spec if spec
end
- uri.path << '.rz'
+ source_uri.path << '.rz'
- spec = fetcher.fetch_path uri
- spec = Gem.inflate spec
+ spec = fetcher.fetch_path source_uri
+ spec = Gem::Util.inflate spec
- if update_cache? then
+ if update_cache?
+ require "fileutils"
FileUtils.mkdir_p cache_dir
- open local_spec, 'wb' do |io|
+ File.open local_spec, 'wb' do |io|
io.write spec
end
end
@@ -184,12 +179,15 @@ class Gem::Source
file = FILES[type]
fetcher = Gem::RemoteFetcher.fetcher
file_name = "#{file}.#{Gem.marshal_version}"
- spec_path = api_uri + "#{file_name}.gz"
+ spec_path = enforce_trailing_slash(uri) + "#{file_name}.gz"
cache_dir = cache_dir spec_path
local_file = File.join(cache_dir, file_name)
retried = false
- FileUtils.mkdir_p cache_dir if update_cache?
+ if update_cache?
+ require "fileutils"
+ FileUtils.mkdir_p cache_dir
+ end
spec_dump = fetcher.cache_update_path spec_path, local_file, update_cache?
@@ -212,15 +210,15 @@ class Gem::Source
def download(spec, dir=Dir.pwd)
fetcher = Gem::RemoteFetcher.fetcher
- fetcher.download spec, api_uri.to_s, dir
+ fetcher.download spec, uri.to_s, dir
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[Remote:', ']' do
q.breakable
q.text @uri.to_s
- if api = api_uri
+ if api = uri
q.breakable
q.text 'API URI: '
q.text api.to_s
@@ -228,11 +226,21 @@ class Gem::Source
end
end
+ def typo_squatting?(host, distance_threshold=4)
+ return if @uri.host.nil?
+ levenshtein_distance(@uri.host, host).between? 1, distance_threshold
+ end
+
+ private
+
+ def enforce_trailing_slash(uri)
+ uri.merge(uri.path.gsub(/\/+$/, '') + '/')
+ end
end
-require 'rubygems/source/git'
-require 'rubygems/source/installed'
-require 'rubygems/source/specific_file'
-require 'rubygems/source/local'
-require 'rubygems/source/lock'
-require 'rubygems/source/vendor'
+require_relative 'source/git'
+require_relative 'source/installed'
+require_relative 'source/specific_file'
+require_relative 'source/local'
+require_relative 'source/lock'
+require_relative 'source/vendor'
diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb
index 23f8928a4e..cda5aa8073 100644
--- a/lib/rubygems/source/git.rb
+++ b/lib/rubygems/source/git.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require 'rubygems/util'
##
# A git gem for use in a gem dependencies file.
@@ -12,7 +11,6 @@ require 'rubygems/util'
# source.specs
class Gem::Source::Git < Gem::Source
-
##
# The name of the gem created by this git gem.
@@ -50,7 +48,7 @@ class Gem::Source::Git < Gem::Source
# repository may contain multiple gems. If +submodules+ is true, submodules
# will be checked out when the gem is installed.
- def initialize name, repository, reference, submodules = false
+ def initialize(name, repository, reference, submodules = false)
super repository
@name = name
@@ -63,7 +61,7 @@ class Gem::Source::Git < Gem::Source
@git = ENV['git'] || 'git'
end
- def <=> other
+ def <=>(other)
case other
when Gem::Source::Git then
0
@@ -77,7 +75,7 @@ class Gem::Source::Git < Gem::Source
end
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
super and
@name == other.name and
@repository == other.repository and
@@ -93,7 +91,7 @@ class Gem::Source::Git < Gem::Source
return false unless File.exist? repo_cache_dir
- unless File.exist? install_dir then
+ unless File.exist? install_dir
system @git, 'clone', '--quiet', '--no-checkout',
repo_cache_dir, install_dir
end
@@ -103,9 +101,11 @@ class Gem::Source::Git < Gem::Source
success = system @git, 'reset', '--quiet', '--hard', rev_parse
- success &&=
- Gem::Util.silent_system @git, 'submodule', 'update',
- '--quiet', '--init', '--recursive' if @need_submodules
+ if @need_submodules
+ _, status = Open3.capture2e(@git, 'submodule', 'update', '--quiet', '--init', '--recursive')
+
+ success &&= status.success?
+ end
success
end
@@ -117,7 +117,7 @@ class Gem::Source::Git < Gem::Source
def cache # :nodoc:
return unless @remote
- if File.exist? repo_cache_dir then
+ if File.exist? repo_cache_dir
Dir.chdir repo_cache_dir do
system @git, 'fetch', '--quiet', '--force', '--tags',
@repository, 'refs/heads/*:refs/heads/*'
@@ -145,7 +145,7 @@ class Gem::Source::Git < Gem::Source
##
# Nothing to download for git gems
- def download full_spec, path # :nodoc:
+ def download(full_spec, path) # :nodoc:
end
##
@@ -157,7 +157,7 @@ class Gem::Source::Git < Gem::Source
File.join base_dir, 'gems', "#{@name}-#{dir_shortref}"
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[Git: ', ']' do
q.breakable
q.text @repository
@@ -206,7 +206,7 @@ class Gem::Source::Git < Gem::Source
Dir.chdir directory do
spec = Gem::Specification.load file
- if spec then
+ if spec
spec.base_dir = base_dir
spec.extension_dir =
@@ -225,18 +225,16 @@ class Gem::Source::Git < Gem::Source
# A hash for the git gem based on the git repository URI.
def uri_hash # :nodoc:
- require 'digest' # required here to avoid deadlocking in Gem.activate_bin_path (because digest is a gem on 2.5+)
+ require_relative '../openssl'
normalized =
- if @repository =~ %r%^\w+://(\w+@)?% then
- uri = URI(@repository).normalize.to_s.sub %r%/$%,''
+ if @repository =~ %r{^\w+://(\w+@)?}
+ uri = URI(@repository).normalize.to_s.sub %r{/$},''
uri.sub(/\A(\w+)/) { $1.downcase }
else
@repository
end
- Digest::SHA1.hexdigest normalized
+ OpenSSL::Digest::SHA1.hexdigest normalized
end
-
end
-
diff --git a/lib/rubygems/source/installed.rb b/lib/rubygems/source/installed.rb
index 300491e467..7e1dd7af5a 100644
--- a/lib/rubygems/source/installed.rb
+++ b/lib/rubygems/source/installed.rb
@@ -3,7 +3,6 @@
# Represents an installed gem. This is used for dependency resolution.
class Gem::Source::Installed < Gem::Source
-
def initialize # :nodoc:
@uri = nil
end
@@ -11,7 +10,7 @@ class Gem::Source::Installed < Gem::Source
##
# Installed sources sort before all other sources
- def <=> other
+ def <=>(other)
case other
when Gem::Source::Git,
Gem::Source::Lock,
@@ -29,13 +28,11 @@ class Gem::Source::Installed < Gem::Source
##
# We don't need to download an installed gem
- def download spec, path
+ def download(spec, path)
nil
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.text '[Installed]'
end
-
end
-
diff --git a/lib/rubygems/source/local.rb b/lib/rubygems/source/local.rb
index 5ab7a467b5..078b06203f 100644
--- a/lib/rubygems/source/local.rb
+++ b/lib/rubygems/source/local.rb
@@ -4,7 +4,6 @@
# dependencies.
class Gem::Source::Local < Gem::Source
-
def initialize # :nodoc:
@specs = nil
@api_uri = nil
@@ -15,7 +14,7 @@ class Gem::Source::Local < Gem::Source
##
# Local sorts before Gem::Source and after Gem::Source::Installed
- def <=> other
+ def <=>(other)
case other
when Gem::Source::Installed,
Gem::Source::Lock then
@@ -34,7 +33,7 @@ class Gem::Source::Local < Gem::Source
"#<%s specs: %p>" % [self.class, keys]
end
- def load_specs type # :nodoc:
+ def load_specs(type) # :nodoc:
@load_specs_names[type] ||= begin
names = []
@@ -61,7 +60,7 @@ class Gem::Source::Local < Gem::Source
when :latest
tup = pkg.spec.name_tuple
- cur = names.find { |x| x.name == tup.name }
+ cur = names.find {|x| x.name == tup.name }
if !cur
names << tup
elsif cur.version < tup.version
@@ -78,8 +77,8 @@ class Gem::Source::Local < Gem::Source
end
end
- def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
- prerelease = false
+ def find_gem(gem_name, version = Gem::Requirement.default, # :nodoc:
+ prerelease = false)
load_specs :complete
found = []
@@ -98,10 +97,10 @@ class Gem::Source::Local < Gem::Source
end
end
- found.max_by { |s| s.version }
+ found.max_by {|s| s.version }
end
- def fetch_spec name # :nodoc:
+ def fetch_spec(name) # :nodoc:
load_specs :complete
if data = @specs[name]
@@ -111,7 +110,7 @@ class Gem::Source::Local < Gem::Source
end
end
- def download spec, cache_dir = nil # :nodoc:
+ def download(spec, cache_dir = nil) # :nodoc:
load_specs :complete
@specs.each do |name, data|
@@ -121,7 +120,7 @@ class Gem::Source::Local < Gem::Source
raise Gem::Exception, "Unable to find file for '#{spec.full_name}'"
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[Local gems:', ']' do
q.breakable
q.seplist @specs.keys do |v|
@@ -129,5 +128,4 @@ class Gem::Source::Local < Gem::Source
end
end
end
-
end
diff --git a/lib/rubygems/source/lock.rb b/lib/rubygems/source/lock.rb
index 59717be2c0..49f097467b 100644
--- a/lib/rubygems/source/lock.rb
+++ b/lib/rubygems/source/lock.rb
@@ -5,7 +5,6 @@
# dependency lock files.
class Gem::Source::Lock < Gem::Source
-
##
# The wrapped Gem::Source
@@ -15,11 +14,11 @@ class Gem::Source::Lock < Gem::Source
# Creates a new Lock source that wraps +source+ and moves it earlier in the
# sort list.
- def initialize source
+ def initialize(source)
@wrapped = source
end
- def <=> other # :nodoc:
+ def <=>(other) # :nodoc:
case other
when Gem::Source::Lock then
@wrapped <=> other.wrapped
@@ -30,7 +29,7 @@ class Gem::Source::Lock < Gem::Source
end
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
0 == (self <=> other)
end
@@ -41,12 +40,11 @@ class Gem::Source::Lock < Gem::Source
##
# Delegates to the wrapped source's fetch_spec method.
- def fetch_spec name_tuple
+ def fetch_spec(name_tuple)
@wrapped.fetch_spec name_tuple
end
def uri # :nodoc:
@wrapped.uri
end
-
end
diff --git a/lib/rubygems/source/specific_file.rb b/lib/rubygems/source/specific_file.rb
index 459c803e1a..24db1440dd 100644
--- a/lib/rubygems/source/specific_file.rb
+++ b/lib/rubygems/source/specific_file.rb
@@ -4,7 +4,6 @@
# local gems.
class Gem::Source::SpecificFile < Gem::Source
-
##
# The path to the gem for this specific file.
@@ -27,22 +26,22 @@ class Gem::Source::SpecificFile < Gem::Source
attr_reader :spec
- def load_specs *a # :nodoc:
+ def load_specs(*a) # :nodoc:
[@name]
end
- def fetch_spec name # :nodoc:
+ def fetch_spec(name) # :nodoc:
return @spec if name == @name
raise Gem::Exception, "Unable to find '#{name}'"
@spec
end
- def download spec, dir = nil # :nodoc:
+ def download(spec, dir = nil) # :nodoc:
return @path if spec == @spec
raise Gem::Exception, "Unable to download '#{spec.full_name}'"
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.group 2, '[SpecificFile:', ']' do
q.breakable
q.text @path
@@ -59,7 +58,7 @@ class Gem::Source::SpecificFile < Gem::Source
#
# Otherwise Gem::Source#<=> is used.
- def <=> other
+ def <=>(other)
case other
when Gem::Source::SpecificFile then
return nil if @spec.name != other.spec.name
@@ -69,5 +68,4 @@ class Gem::Source::SpecificFile < Gem::Source
super
end
end
-
end
diff --git a/lib/rubygems/source/vendor.rb b/lib/rubygems/source/vendor.rb
index e1b3698607..543acf1388 100644
--- a/lib/rubygems/source/vendor.rb
+++ b/lib/rubygems/source/vendor.rb
@@ -3,15 +3,14 @@
# This represents a vendored source that is similar to an installed gem.
class Gem::Source::Vendor < Gem::Source::Installed
-
##
# Creates a new Vendor source for a gem that was unpacked at +path+.
- def initialize path
+ def initialize(path)
@uri = path
end
- def <=> other
+ def <=>(other)
case other
when Gem::Source::Lock then
-1
@@ -23,6 +22,4 @@ class Gem::Source::Vendor < Gem::Source::Installed
nil
end
end
-
end
-
diff --git a/lib/rubygems/source_list.rb b/lib/rubygems/source_list.rb
index 66ce4d57ed..13b25b63dc 100644
--- a/lib/rubygems/source_list.rb
+++ b/lib/rubygems/source_list.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require 'rubygems/source'
##
# The SourceList represents the sources rubygems has been configured to use.
@@ -15,7 +14,6 @@ require 'rubygems/source'
# The most common way to get a SourceList is Gem.sources.
class Gem::SourceList
-
include Enumerable
##
@@ -50,6 +48,8 @@ class Gem::SourceList
# String.
def <<(obj)
+ require "uri"
+
src = case obj
when URI
Gem::Source.new(obj)
@@ -88,7 +88,7 @@ class Gem::SourceList
# Yields each source URI in the list.
def each
- @sources.each { |s| yield s.uri.to_s }
+ @sources.each {|s| yield s.uri.to_s }
end
##
@@ -105,7 +105,7 @@ class Gem::SourceList
@sources.empty?
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
to_a == other
end
@@ -113,7 +113,7 @@ class Gem::SourceList
# Returns an Array of source URI Strings.
def to_a
- @sources.map { |x| x.uri.to_s }
+ @sources.map {|x| x.uri.to_s }
end
alias_method :to_ary, :to_a
@@ -133,18 +133,18 @@ class Gem::SourceList
if other.kind_of? Gem::Source
@sources.include? other
else
- @sources.find { |x| x.uri.to_s == other.to_s }
+ @sources.find {|x| x.uri.to_s == other.to_s }
end
end
##
# Deletes +source+ from the source list which may be a Gem::Source or a URI.
- def delete source
+ def delete(source)
if source.kind_of? Gem::Source
@sources.delete source
else
- @sources.delete_if { |x| x.uri.to_s == source.to_s }
+ @sources.delete_if {|x| x.uri.to_s == source.to_s }
end
end
end
diff --git a/lib/rubygems/source_local.rb b/lib/rubygems/source_local.rb
deleted file mode 100644
index 9869158e7d..0000000000
--- a/lib/rubygems/source_local.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# frozen_string_literal: true
-require 'rubygems/source'
-require 'rubygems/source_local'
-
-unless Gem::Deprecate.skip
- Kernel.warn "#{Gem.location_of_caller(3).join(':')}: Warning: Requiring rubygems/source_local is deprecated; please use rubygems/source/local instead."
-end
-
diff --git a/lib/rubygems/source_specific_file.rb b/lib/rubygems/source_specific_file.rb
deleted file mode 100644
index b676b1d3a2..0000000000
--- a/lib/rubygems/source_specific_file.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# frozen_string_literal: true
-require 'rubygems/source/specific_file'
-
-unless Gem::Deprecate.skip
- Kernel.warn "#{Gem.location_of_caller(3).join(':')}: Warning: Requiring rubygems/source_specific_file is deprecated; please use rubygems/source/specific_file instead."
-end
diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb
index 919276e113..68ff605a83 100644
--- a/lib/rubygems/spec_fetcher.rb
+++ b/lib/rubygems/spec_fetcher.rb
@@ -1,15 +1,14 @@
# frozen_string_literal: true
-require 'rubygems/remote_fetcher'
-require 'rubygems/user_interaction'
-require 'rubygems/errors'
-require 'rubygems/text'
-require 'rubygems/name_tuple'
+require_relative 'remote_fetcher'
+require_relative 'user_interaction'
+require_relative 'errors'
+require_relative 'text'
+require_relative 'name_tuple'
##
# SpecFetcher handles metadata updates from remote gem repositories.
class Gem::SpecFetcher
-
include Gem::UserInteraction
include Gem::Text
@@ -54,7 +53,7 @@ class Gem::SpecFetcher
# If you need to retrieve specifications from a different +source+, you can
# send it as an argument.
- def initialize sources = nil
+ def initialize(sources = nil)
@sources = sources || Gem.sources
@update_cache =
@@ -88,29 +87,18 @@ class Gem::SpecFetcher
rejected_specs = {}
- if dependency.prerelease?
- if dependency.specific?
- type = :complete
- else
- type = :abs_latest
- end
- elsif dependency.latest_version?
- type = :latest
- else
- type = :released
- end
+ list, errors = available_specs(dependency.identity)
- list, errors = available_specs(type)
list.each do |source, specs|
if dependency.name.is_a?(String) && specs.respond_to?(:bsearch)
- start_index = (0 ... specs.length).bsearch{ |i| specs[i].name >= dependency.name }
- end_index = (0 ... specs.length).bsearch{ |i| specs[i].name > dependency.name }
+ start_index = (0 ... specs.length).bsearch{|i| specs[i].name >= dependency.name }
+ end_index = (0 ... specs.length).bsearch{|i| specs[i].name > dependency.name }
specs = specs[start_index ... end_index] if start_index && end_index
end
found[source] = specs.select do |tup|
if dependency.match?(tup)
- if matching_platform and !Gem::Platform.match(tup.platform)
+ if matching_platform and !Gem::Platform.match_gem?(tup.platform, tup.name)
pm = (
rejected_specs[dependency] ||= \
Gem::PlatformMismatch.new(tup.name, tup.version))
@@ -133,12 +121,11 @@ class Gem::SpecFetcher
end
end
- tuples = tuples.sort_by { |x| x[0] }
+ tuples = tuples.sort_by {|x| x[0] }
return [tuples, errors]
end
-
##
# Return all gem name tuples who's names match +obj+
@@ -157,7 +144,6 @@ class Gem::SpecFetcher
tuples
end
-
##
# Find and fetch specs that match +dependency+.
#
@@ -184,30 +170,33 @@ class Gem::SpecFetcher
# Suggests gems based on the supplied +gem_name+. Returns an array of
# alternative gem names.
- def suggest_gems_from_name(gem_name, type = :latest)
+ def suggest_gems_from_name(gem_name, type = :latest, num_results = 5)
gem_name = gem_name.downcase.tr('_-', '')
max = gem_name.size / 2
names = available_specs(type).first.values.flatten(1)
- matches = names.map { |n|
+ matches = names.map do |n|
next unless n.match_platform?
-
- distance = levenshtein_distance gem_name, n.name.downcase.tr('_-', '')
-
- next if distance >= max
-
- return [n.name] if distance == 0
-
- [n.name, distance]
- }.compact
+ [n.name, 0] if n.name.downcase.tr('_-', '').include?(gem_name)
+ end.compact
+
+ if matches.length < num_results
+ matches += names.map do |n|
+ next unless n.match_platform?
+ distance = levenshtein_distance gem_name, n.name.downcase.tr('_-', '')
+ next if distance >= max
+ return [n.name] if distance == 0
+ [n.name, distance]
+ end.compact
+ end
matches = if matches.empty? && type != :prerelease
- suggest_gems_from_name gem_name, :prerelease
- else
- matches.uniq.sort_by { |name, dist| dist }
- end
+ suggest_gems_from_name gem_name, :prerelease
+ else
+ matches.uniq.sort_by {|name, dist| dist }
+ end
- matches.first(5).map { |name, dist| name }
+ matches.map {|name, dist| name }.uniq.first(num_results)
end
##
@@ -264,11 +253,9 @@ class Gem::SpecFetcher
def tuples_for(source, type, gracefully_ignore=false) # :nodoc:
@caches[type][source.uri] ||=
- source.load_specs(type).sort_by { |tup| tup.name }
+ source.load_specs(type).sort_by {|tup| tup.name }
rescue Gem::RemoteFetcher::FetchError
raise unless gracefully_ignore
[]
end
-
end
-
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index efc08c4738..b493a47ef0 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -1,23 +1,19 @@
-# -*- coding: utf-8 -*-
# frozen_string_literal: true
+# -*- coding: utf-8 -*-
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
-
-require 'rubygems/version'
-require 'rubygems/requirement'
-require 'rubygems/platform'
-require 'rubygems/deprecate'
-require 'rubygems/basic_specification'
-require 'rubygems/stub_specification'
-require 'rubygems/util/list'
-require 'stringio'
+require_relative 'deprecate'
+require_relative 'basic_specification'
+require_relative 'stub_specification'
+require_relative 'specification_policy'
+require_relative 'util/list'
##
-# The Specification class contains the information for a Gem. Typically
+# The Specification class contains the information for a gem. Typically
# defined in a .gemspec file or a Rakefile, and looks like this:
#
# Gem::Specification.new do |s|
@@ -38,6 +34,7 @@ require 'stringio'
# items you may add to a specification.
class Gem::Specification < Gem::BasicSpecification
+ extend Gem::Deprecate
# REFACTOR: Consider breaking out this version stuff into a separate
# module. There's enough special stuff around it that it may justify
@@ -80,19 +77,19 @@ class Gem::Specification < Gem::BasicSpecification
-1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'],
1 => [
'Deprecated "test_suite_file" in favor of the new, but equivalent, "test_files"',
- '"test_file=x" is a shortcut for "test_files=[x]"'
+ '"test_file=x" is a shortcut for "test_files=[x]"',
],
- 2 => [
+ 2 => [
'Added "required_rubygems_version"',
'Now forward-compatible with future versions',
],
3 => [
- 'Added Fixnum validation to the specification_version'
+ 'Added Fixnum validation to the specification_version',
],
4 => [
- 'Added sandboxed freeform metadata to the specification version.'
- ]
- }
+ 'Added sandboxed freeform metadata to the specification version.',
+ ],
+ }.freeze
MARSHAL_FIELDS = { # :nodoc:
-1 => 16,
@@ -100,16 +97,15 @@ class Gem::Specification < Gem::BasicSpecification
2 => 16,
3 => 17,
4 => 18,
- }
+ }.freeze
today = Time.now.utc
TODAY = Time.utc(today.year, today.month, today.day) # :nodoc:
- LOAD_CACHE = {} # :nodoc:
+ @load_cache = {} # :nodoc:
+ @load_cache_mutex = Thread::Mutex.new
- private_constant :LOAD_CACHE if defined? private_constant
-
- VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:
+ VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/.freeze # :nodoc:
# :startdoc:
@@ -132,7 +128,7 @@ class Gem::Specification < Gem::BasicSpecification
:autorequire => nil,
:bindir => 'bin',
:cert_chain => [],
- :date => TODAY,
+ :date => nil,
:dependencies => [],
:description => nil,
:email => nil,
@@ -151,7 +147,6 @@ class Gem::Specification < Gem::BasicSpecification
:required_ruby_version => Gem::Requirement.default,
:required_rubygems_version => Gem::Requirement.default,
:requirements => [],
- :rubyforge_project => nil,
:rubygems_version => Gem::VERSION,
:signing_key => nil,
:specification_version => CURRENT_SPECIFICATION_VERSION,
@@ -160,33 +155,52 @@ class Gem::Specification < Gem::BasicSpecification
:version => nil,
}.freeze
+ # rubocop:disable Style/MutableConstant
INITIALIZE_CODE_FOR_DEFAULTS = { } # :nodoc:
+ # rubocop:enable Style/MutableConstant
@@default_value.each do |k,v|
INITIALIZE_CODE_FOR_DEFAULTS[k] = case v
- when [], {}, true, false, nil, Numeric, Symbol
- v.inspect
- when String
- v.dump
- when Numeric
- "default_value(:#{k})"
- else
- "default_value(:#{k}).dup"
+ when [], {}, true, false, nil, Numeric, Symbol
+ v.inspect
+ when String
+ v.dump
+ when Numeric
+ "default_value(:#{k})"
+ else
+ "default_value(:#{k}).dup"
+ end
+ end
+
+ @@attributes = @@default_value.keys.sort_by {|s| s.to_s }
+ @@array_attributes = @@default_value.reject {|k,v| v != [] }.keys
+ @@nil_attributes, @@non_nil_attributes = @@default_value.keys.partition do |k|
+ @@default_value[k].nil?
+ end
+
+ def self.clear_specs # :nodoc:
+ @@all_specs_mutex.synchronize do
+ @@all = nil
+ @@stubs = nil
+ @@stubs_by_name = {}
+ @@spec_with_requirable_file = {}
+ @@active_stub_with_requirable_file = {}
end
end
+ private_class_method :clear_specs
- @@attributes = @@default_value.keys.sort_by { |s| s.to_s }
- @@array_attributes = @@default_value.reject { |k,v| v != [] }.keys
- @@nil_attributes, @@non_nil_attributes = @@default_value.keys.partition { |k|
- @@default_value[k].nil?
- }
+ @@all_specs_mutex = Thread::Mutex.new
- @@stubs_by_name = {}
+ clear_specs
# Sentinel object to represent "not found" stubs
NOT_FOUND = Struct.new(:to_spec, :this).new # :nodoc:
- @@spec_with_requirable_file = {}
- @@active_stub_with_requirable_file = {}
+
+ # Tracking removed method calls to warn users during build time.
+ REMOVED_METHODS = [:rubyforge_project=].freeze # :nodoc:
+ def removed_method_calls
+ @removed_method_calls ||= []
+ end
######################################################################
# :section: Required gemspec attributes
@@ -238,12 +252,11 @@ class Gem::Specification < Gem::BasicSpecification
# require 'rake'
# spec.files = FileList['lib/**/*.rb',
# 'bin/*',
- # '[A-Z]*',
- # 'test/**/*'].to_a
+ # '[A-Z]*'].to_a
#
# # or without Rake...
# spec.files = Dir['lib/**/*.rb'] + Dir['bin/*']
- # spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
+ # spec.files += Dir['[A-Z]*']
# spec.files.reject! { |fn| fn.include? "CVS" }
def files
@@ -257,30 +270,31 @@ class Gem::Specification < Gem::BasicSpecification
].flatten.compact.uniq.sort
end
- ######################################################################
- # :section: Recommended gemspec attributes
-
##
- # Singular writer for #authors
+ # A list of authors for this gem.
+ #
+ # Alternatively, a single author can be specified by assigning a string to
+ # `spec.author`
#
# Usage:
#
- # spec.author = 'John Jones'
+ # spec.authors = ['John Jones', 'Mary Smith']
- def author= o
- self.authors = [o]
+ def authors=(value)
+ @authors = Array(value).flatten.grep(String)
end
+ ######################################################################
+ # :section: Recommended gemspec attributes
+
##
- # Sets the list of authors, ensuring it is an array.
+ # The version of Ruby required by this gem
#
# Usage:
#
- # spec.authors = ['John Jones', 'Mary Smith']
+ # spec.required_ruby_version = '>= 2.7.0'
- def authors= value
- @authors = Array(value).flatten.grep(String)
- end
+ attr_reader :required_ruby_version
##
# A long description of this gem
@@ -325,17 +339,21 @@ class Gem::Specification < Gem::BasicSpecification
# This should just be the name of your license. The full text of the license
# should be inside of the gem (at the top level) when you build it.
#
- # The simplest way, is to specify the standard SPDX ID
+ # The simplest way is to specify the standard SPDX ID
# https://spdx.org/licenses/ for the license.
- # Ideally you should pick one that is OSI (Open Source Initiative)
+ # Ideally, you should pick one that is OSI (Open Source Initiative)
# http://opensource.org/licenses/alphabetical approved.
#
- # The most commonly used OSI approved licenses are MIT and Apache-2.0.
+ # The most commonly used OSI-approved licenses are MIT and Apache-2.0.
# GitHub also provides a license picker at http://choosealicense.com/.
#
+ # You can also use a custom license file along with your gemspec and specify
+ # a LicenseRef-<idstring>, where idstring is the name of the file containing
+ # the license text.
+ #
# You should specify a license for your gem so that people know how they are
- # permitted to use it, and any restrictions you're placing on it. Not
- # specifying a license means all rights are reserved; others have no rights
+ # permitted to use it and any restrictions you're placing on it. Not
+ # specifying a license means all rights are reserved; others have no right
# to use the code for any purpose.
#
# You can set multiple licenses with #licenses=
@@ -343,7 +361,7 @@ class Gem::Specification < Gem::BasicSpecification
# Usage:
# spec.license = 'MIT'
- def license=o
+ def license=(o)
self.licenses = [o]
end
@@ -360,14 +378,13 @@ class Gem::Specification < Gem::BasicSpecification
# Usage:
# spec.licenses = ['MIT', 'GPL-2.0']
- def licenses= licenses
+ def licenses=(licenses)
@licenses = Array licenses
end
##
# The metadata holds extra data for this gem that may be useful to other
- # consumers and is settable by gem authors without requiring an update to
- # the rubygems software.
+ # consumers and is settable by gem authors.
#
# Metadata items have the following restrictions:
#
@@ -388,6 +405,7 @@ class Gem::Specification < Gem::BasicSpecification
# "mailing_list_uri" => "https://groups.example.com/bestgemever",
# "source_code_uri" => "https://example.com/user/bestgemever",
# "wiki_uri" => "https://example.com/user/bestgemever/wiki"
+ # "funding_uri" => "https://example.com/donate"
# }
#
# These links will be used on your gem's page on rubygems.org and must pass
@@ -401,6 +419,17 @@ class Gem::Specification < Gem::BasicSpecification
# :section: Optional gemspec attributes
##
+ # Singular (alternative) writer for #authors
+ #
+ # Usage:
+ #
+ # spec.author = 'John Jones'
+
+ def author=(o)
+ self.authors = [o]
+ end
+
+ ##
# The path in the gem for executable scripts. Usually 'bin'
#
# Usage:
@@ -447,9 +476,9 @@ class Gem::Specification < Gem::BasicSpecification
#
# spec.platform = Gem::Platform.local
- def platform= platform
+ def platform=(platform)
if @original_platform.nil? or
- @original_platform == Gem::Platform::RUBY then
+ @original_platform == Gem::Platform::RUBY
@original_platform = platform
end
@@ -503,11 +532,6 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # The version of Ruby required by this gem
-
- attr_reader :required_ruby_version
-
- ##
# The RubyGems version required by this gem
attr_reader :required_rubygems_version
@@ -547,6 +571,10 @@ class Gem::Specification < Gem::BasicSpecification
# spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
def add_runtime_dependency(gem, *requirements)
+ if requirements.uniq.size != requirements.size
+ warn "WARNING: duplicated #{gem} dependency #{requirements}"
+ end
+
add_dependency_with_type(gem, :runtime, requirements)
end
@@ -615,7 +643,7 @@ class Gem::Specification < Gem::BasicSpecification
# Sets the version of RubyGems that installed this gem. See also
# #installed_by_version.
- def installed_by_version= version # :nodoc:
+ def installed_by_version=(version) # :nodoc:
@installed_by_version = Gem::Version.new version
end
@@ -640,29 +668,30 @@ class Gem::Specification < Gem::BasicSpecification
# ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
# #<Gem::Version "2.0.0.247">
#
- # Because patch-level is taken into account, be very careful specifying using
- # `<=`: `<= 2.2.2` will not match any patch-level of 2.2.2 after the `p0`
- # release. It is much safer to specify `< 2.2.3` instead
+ # Prereleases can also be specified.
#
# Usage:
#
# # This gem will work with 1.8.6 or greater...
# spec.required_ruby_version = '>= 1.8.6'
#
- # # Only with ruby 2.0.x
- # spec.required_ruby_version = '~> 2.0'
+ # # Only with final releases of major version 2 where minor version is at least 3
+ # spec.required_ruby_version = '~> 2.3'
#
- # # Only with ruby between 2.2.0 and 2.2.2
- # spec.required_ruby_version = ['>= 2.2.0', '< 2.2.3']
+ # # Only prereleases or final releases after 2.6.0.preview2
+ # spec.required_ruby_version = '> 2.6.0.preview2'
+ #
+ # # This gem will work with 2.3.0 or greater, including major version 3, but lesser than 4.0.0
+ # spec.required_ruby_version = '>= 2.3', '< 4'
- def required_ruby_version= req
+ def required_ruby_version=(req)
@required_ruby_version = Gem::Requirement.create req
end
##
# The RubyGems version required by this gem
- def required_rubygems_version= req
+ def required_rubygems_version=(req)
@required_rubygems_version = Gem::Requirement.create req
end
@@ -687,7 +716,7 @@ class Gem::Specification < Gem::BasicSpecification
# spec.test_files = Dir.glob('test/tc_*.rb')
# spec.test_files = ['tests/test-suite.rb']
- def test_files= files # :nodoc:
+ def test_files=(files) # :nodoc:
@test_files = Array files
end
@@ -714,6 +743,7 @@ class Gem::Specification < Gem::BasicSpecification
# Deprecated: You must now specify the executable name to Gem.bin_path.
attr_writer :default_executable
+ rubygems_deprecate :default_executable=
##
# Allows deinstallation of gems with legacy platforms.
@@ -721,14 +751,6 @@ class Gem::Specification < Gem::BasicSpecification
attr_writer :original_platform # :nodoc:
##
- # The rubyforge project this gem lives under. i.e. RubyGems'
- # rubyforge_project is "rubygems".
- #
- # This option is deprecated.
-
- attr_accessor :rubyforge_project
-
- ##
# The Gem::Specification version of this gemspec.
#
# Do not set this, it is set automatically when the gem is packaged.
@@ -736,103 +758,45 @@ class Gem::Specification < Gem::BasicSpecification
attr_accessor :specification_version
def self._all # :nodoc:
- unless defined?(@@all) && @@all then
- @@all = stubs.map(&:to_spec)
- if @@all.any?(&:nil?) # TODO: remove once we're happy
- raise "pid: #{$$} nil spec! included in #{stubs.inspect}"
- end
-
- # After a reset, make sure already loaded specs
- # are still marked as activated.
- specs = {}
- Gem.loaded_specs.each_value{|s| specs[s] = true}
- @@all.each{|s| s.activated = true if specs[s]}
- end
- @@all
+ @@all_specs_mutex.synchronize { @@all ||= Gem.loaded_specs.values | stubs.map(&:to_spec) }
end
- def self._clear_load_cache # :nodoc:
- LOAD_CACHE.clear
+ def self.clear_load_cache # :nodoc:
+ @load_cache_mutex.synchronize do
+ @load_cache.clear
+ end
end
+ private_class_method :clear_load_cache
def self.each_gemspec(dirs) # :nodoc:
dirs.each do |dir|
- Dir[File.join(dir, "*.gemspec")].each do |path|
- yield path.untaint
+ Gem::Util.glob_files_in_dir("*.gemspec", dir).each do |path|
+ yield path.tap(&Gem::UNTAINT)
end
end
end
- def self.gemspec_stubs_in dir, pattern
- Dir[File.join(dir, pattern)].map { |path| yield path }.select(&:valid?)
+ def self.gemspec_stubs_in(dir, pattern)
+ Gem::Util.glob_files_in_dir(pattern, dir).map {|path| yield path }.select(&:valid?)
end
private_class_method :gemspec_stubs_in
- def self.default_stubs pattern
- base_dir = Gem.default_dir
- gems_dir = File.join base_dir, "gems"
- gemspec_stubs_in(default_specifications_dir, pattern) do |path|
- Gem::StubSpecification.default_gemspec_stub(path, base_dir, gems_dir)
- end
- end
- private_class_method :default_stubs
-
- def self.installed_stubs dirs, pattern
+ def self.installed_stubs(dirs, pattern)
map_stubs(dirs, pattern) do |path, base_dir, gems_dir|
Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir)
end
end
private_class_method :installed_stubs
- if [].respond_to? :flat_map
- def self.map_stubs(dirs, pattern) # :nodoc:
- dirs.flat_map { |dir|
- base_dir = File.dirname dir
- gems_dir = File.join base_dir, "gems"
- gemspec_stubs_in(dir, pattern) { |path| yield path, base_dir, gems_dir }
- }
- end
- else # FIXME: remove when 1.8 is dropped
- def self.map_stubs(dirs, pattern) # :nodoc:
- dirs.map { |dir|
- base_dir = File.dirname dir
- gems_dir = File.join base_dir, "gems"
- gemspec_stubs_in(dir, pattern) { |path| yield path, base_dir, gems_dir }
- }.flatten 1
+ def self.map_stubs(dirs, pattern) # :nodoc:
+ dirs.flat_map do |dir|
+ base_dir = File.dirname dir
+ gems_dir = File.join base_dir, "gems"
+ gemspec_stubs_in(dir, pattern) {|path| yield path, base_dir, gems_dir }
end
end
private_class_method :map_stubs
- uniq_takes_a_block = false
- [1,2].uniq { uniq_takes_a_block = true }
-
- if uniq_takes_a_block
- def self.uniq_by(list, &block) # :nodoc:
- list.uniq(&block)
- end
- else # FIXME: remove when 1.8 is dropped
- def self.uniq_by(list) # :nodoc:
- values = {}
- list.each { |item|
- value = yield item
- values[value] ||= item
- }
- values.values
- end
- end
- private_class_method :uniq_by
-
- if [].respond_to? :sort_by!
- def self.sort_by! list, &block
- list.sort_by!(&block)
- end
- else # FIXME: remove when 1.8 is dropped
- def self.sort_by! list, &block
- list.replace list.sort_by(&block)
- end
- end
- private_class_method :sort_by!
-
def self.each_spec(dirs) # :nodoc:
each_gemspec(dirs) do |path|
spec = self.load path
@@ -846,47 +810,66 @@ class Gem::Specification < Gem::BasicSpecification
def self.stubs
@@stubs ||= begin
pattern = "*.gemspec"
- stubs = default_stubs(pattern).concat installed_stubs(dirs, pattern)
- stubs = uniq_by(stubs) { |stub| stub.full_name }
+ stubs = stubs_for_pattern(pattern, false)
- _resort!(stubs)
- @@stubs_by_name = stubs.group_by(&:name)
+ @@stubs_by_name = stubs.select {|s| Gem::Platform.match_spec? s }.group_by(&:name)
stubs
end
end
- EMPTY = [].freeze # :nodoc:
+ ##
+ # Returns a Gem::StubSpecification for default gems
+
+ def self.default_stubs(pattern = "*.gemspec")
+ base_dir = Gem.default_dir
+ gems_dir = File.join base_dir, "gems"
+ gemspec_stubs_in(Gem.default_specifications_dir, pattern) do |path|
+ Gem::StubSpecification.default_gemspec_stub(path, base_dir, gems_dir)
+ end
+ end
##
# Returns a Gem::StubSpecification for installed gem named +name+
+ # only returns stubs that match Gem.platforms
- def self.stubs_for name
+ def self.stubs_for(name)
if @@stubs
@@stubs_by_name[name] || []
else
- pattern = "#{name}-*.gemspec"
- stubs = default_stubs(pattern) + installed_stubs(dirs, pattern)
- stubs = uniq_by(stubs) { |stub| stub.full_name }.group_by(&:name)
- stubs.each_value { |v| _resort!(v) }
-
- @@stubs_by_name.merge! stubs
- @@stubs_by_name[name] ||= EMPTY
+ @@stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s|
+ s.name == name
+ end
end
end
+ ##
+ # Finds stub specifications matching a pattern from the standard locations,
+ # optionally filtering out specs not matching the current platform
+ #
+ def self.stubs_for_pattern(pattern, match_platform = true) # :nodoc:
+ installed_stubs = installed_stubs(Gem::Specification.dirs, pattern)
+ installed_stubs.select! {|s| Gem::Platform.match_spec? s } if match_platform
+ stubs = installed_stubs + default_stubs(pattern)
+ stubs = stubs.uniq {|stub| stub.full_name }
+ _resort!(stubs)
+ stubs
+ end
+
def self._resort!(specs) # :nodoc:
- specs.sort! { |a, b|
+ specs.sort! do |a, b|
names = a.name <=> b.name
next names if names.nonzero?
- b.version <=> a.version
- }
+ versions = b.version <=> a.version
+ next versions if versions.nonzero?
+ b.platform == Gem::Platform::RUBY ? -1 : 1
+ end
end
##
# Loads the default specifications. It should be called only once.
def self.load_defaults
- each_spec([default_specifications_dir]) do |spec|
+ each_spec([Gem.default_specifications_dir]) do |spec|
# #load returns nil if the spec is bad, so we just ignore
# it at this stage
Gem.register_default_spec(spec)
@@ -894,51 +877,6 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # Adds +spec+ to the known specifications, keeping the collection
- # properly sorted.
-
- def self.add_spec spec
- warn "Gem::Specification.add_spec is deprecated and will be removed in RubyGems 3.0" unless Gem::Deprecate.skip
- # TODO: find all extraneous adds
- # puts
- # p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }]
-
- # TODO: flush the rest of the crap from the tests
- # raise "no dupes #{spec.full_name} in #{all_names.inspect}" if
- # _all.include? spec
-
- raise "nil spec!" unless spec # TODO: remove once we're happy with tests
-
- return if _all.include? spec
-
- _all << spec
- stubs << spec
- (@@stubs_by_name[spec.name] ||= []) << spec
- sort_by!(@@stubs_by_name[spec.name]) { |s| s.version }
- _resort!(_all)
- _resort!(stubs)
- end
-
- ##
- # Adds multiple specs to the known specifications.
-
- def self.add_specs *specs
- warn "Gem::Specification.add_specs is deprecated and will be removed in RubyGems 3.0" unless Gem::Deprecate.skip
-
- raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy
-
- # TODO: this is much more efficient, but we need the extra checks for now
- # _all.concat specs
- # _resort!
-
- Gem::Deprecate.skip_during do
- specs.each do |spec| # TODO: slow
- add_spec spec
- end
- end
- end
-
- ##
# Returns all specifications. This method is discouraged from use.
# You probably want to use one of the Enumerable methods instead.
@@ -960,8 +898,7 @@ class Gem::Specification < Gem::BasicSpecification
#
# -- wilsonb
- def self.all= specs
- raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy
+ def self.all=(specs)
@@stubs_by_name = specs.group_by(&:name)
@@all = @@stubs = specs
end
@@ -995,19 +932,19 @@ class Gem::Specification < Gem::BasicSpecification
# Return the directories that Specification uses to find specs.
def self.dirs
- @@dirs ||= Gem.path.collect { |dir|
- File.join dir.dup.untaint, "specifications"
- }
+ @@dirs ||= Gem.path.collect do |dir|
+ File.join dir.dup.tap(&Gem::UNTAINT), "specifications"
+ end
end
##
# Set the directories that Specification uses to find specs. Setting
# this resets the list of known specs.
- def self.dirs= dirs
+ def self.dirs=(dirs)
self.reset
- @@dirs = Array(dirs).map { |dir| File.join dir, "specifications" }
+ @@dirs = Array(dirs).map {|dir| File.join dir, "specifications" }
end
extend Enumerable
@@ -1027,7 +964,7 @@ class Gem::Specification < Gem::BasicSpecification
##
# Returns every spec that matches +name+ and optional +requirements+.
- def self.find_all_by_name name, *requirements
+ def self.find_all_by_name(name, *requirements)
requirements = Gem::Requirement.default if requirements.empty?
# TODO: maybe try: find_all { |s| spec === dep }
@@ -1046,7 +983,7 @@ class Gem::Specification < Gem::BasicSpecification
# Find the best specification matching a +name+ and +requirements+. Raises
# if the dependency doesn't resolve to a valid specification.
- def self.find_by_name name, *requirements
+ def self.find_by_name(name, *requirements)
requirements = Gem::Requirement.default if requirements.empty?
# TODO: maybe try: find { |s| spec === dep }
@@ -1057,12 +994,12 @@ class Gem::Specification < Gem::BasicSpecification
##
# Return the best specification that contains the file matching +path+.
- def self.find_by_path path
+ def self.find_by_path(path)
path = path.dup.freeze
- spec = @@spec_with_requirable_file[path] ||= (stubs.find { |s|
+ spec = @@spec_with_requirable_file[path] ||= (stubs.find do |s|
next unless Gem::BundlerVersionFinder.compatible?(s)
s.contains_requirable_file? path
- } || NOT_FOUND)
+ end || NOT_FOUND)
spec.to_spec
end
@@ -1070,40 +1007,35 @@ class Gem::Specification < Gem::BasicSpecification
# Return the best specification that contains the file matching +path+
# amongst the specs that are not activated.
- def self.find_inactive_by_path path
- stub = stubs.find { |s|
+ def self.find_inactive_by_path(path)
+ stub = stubs.find do |s|
next if s.activated?
next unless Gem::BundlerVersionFinder.compatible?(s)
s.contains_requirable_file? path
- }
+ end
stub && stub.to_spec
end
- def self.find_active_stub_by_path path
- stub = @@active_stub_with_requirable_file[path] ||= (stubs.find { |s|
+ def self.find_active_stub_by_path(path)
+ stub = @@active_stub_with_requirable_file[path] ||= (stubs.find do |s|
s.activated? and s.contains_requirable_file? path
- } || NOT_FOUND)
+ end || NOT_FOUND)
stub.this
end
##
# Return currently unresolved specs that contain the file matching +path+.
- def self.find_in_unresolved path
- # TODO: do we need these?? Kill it
- specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten
-
- specs.find_all { |spec| spec.contains_requirable_file? path }
+ def self.find_in_unresolved(path)
+ unresolved_specs.find_all {|spec| spec.contains_requirable_file? path }
end
##
# Search through all unresolved deps and sub-dependencies and return
# specs that contain the file matching +path+.
- def self.find_in_unresolved_tree path
- specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten
-
- specs.each do |spec|
+ def self.find_in_unresolved_tree(path)
+ unresolved_specs.each do |spec|
spec.traverse do |from_spec, dep, to_spec, trail|
if to_spec.has_conflicts? || to_spec.conficts_when_loaded_with?(trail)
:next
@@ -1116,6 +1048,11 @@ class Gem::Specification < Gem::BasicSpecification
[]
end
+ def self.unresolved_specs
+ unresolved_deps.values.map {|dep| dep.to_specs }.flatten
+ end
+ private_class_method :unresolved_specs
+
##
# Special loader for YAML files. When a Specification object is loaded
# from a YAML file, it bypasses the normal Ruby object initialization
@@ -1130,11 +1067,11 @@ class Gem::Specification < Gem::BasicSpecification
input = normalize_yaml_input input
spec = Gem::SafeYAML.safe_load input
- if spec && spec.class == FalseClass then
+ if spec && spec.class == FalseClass
raise Gem::EndOfYAMLException
end
- unless Gem::Specification === spec then
+ unless Gem::Specification === spec
raise Gem::Exception, "YAML data doesn't evaluate to gem specification"
end
@@ -1148,53 +1085,58 @@ class Gem::Specification < Gem::BasicSpecification
# Return the latest specs, optionally including prerelease specs if
# +prerelease+ is true.
- def self.latest_specs prerelease = false
+ def self.latest_specs(prerelease = false)
_latest_specs Gem::Specification._all, prerelease
end
- def self._latest_specs specs, prerelease = false # :nodoc:
- result = Hash.new { |h,k| h[k] = {} }
- native = {}
+ ##
+ # Return the latest installed spec for gem +name+.
+
+ def self.latest_spec_for(name)
+ latest_specs(true).find {|installed_spec| installed_spec.name == name }
+ end
+
+ def self._latest_specs(specs, prerelease = false) # :nodoc:
+ result = {}
specs.reverse_each do |spec|
next if spec.version.prerelease? unless prerelease
- native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY
- result[spec.name][spec.platform] = spec
+ result[spec.name] = spec
end
- result.map(&:last).map(&:values).flatten.reject { |spec|
- minimum = native[spec.name]
- minimum && spec.version < minimum
- }.sort_by{ |tup| tup.name }
+ result.map(&:last).flatten.sort_by{|tup| tup.name }
end
##
# Loads Ruby format gemspec from +file+.
- def self.load file
+ def self.load(file)
return unless file
- _spec = LOAD_CACHE[file]
+ _spec = @load_cache_mutex.synchronize { @load_cache[file] }
return _spec if _spec
- file = file.dup.untaint
+ file = file.dup.tap(&Gem::UNTAINT)
return unless File.file?(file)
- code = if defined? Encoding
- File.read file, :mode => 'r:UTF-8:-'
- else
- File.read file
- end
+ code = File.read file, :mode => 'r:UTF-8:-'
- code.untaint
+ code.tap(&Gem::UNTAINT)
begin
_spec = eval code, binding, file
if Gem::Specification === _spec
_spec.loaded_from = File.expand_path file.to_s
- LOAD_CACHE[file] = _spec
+ @load_cache_mutex.synchronize do
+ prev = @load_cache[file]
+ if prev
+ _spec = prev
+ else
+ @load_cache[file] = _spec
+ end
+ end
return _spec
end
@@ -1220,7 +1162,7 @@ class Gem::Specification < Gem::BasicSpecification
def self.normalize_yaml_input(input)
result = input.respond_to?(:read) ? input.read : input
- result = "--- " + result unless result =~ /\A--- /
+ result = "--- " + result unless result.start_with?("--- ")
result = result.dup
result.gsub!(/ !!null \n/, " \n")
# date: 2011-04-26 00:00:00.000000000Z
@@ -1237,7 +1179,7 @@ class Gem::Specification < Gem::BasicSpecification
# version as well.
def self.outdated
- outdated_and_latest_version.map { |local, _| local.name }
+ outdated_and_latest_version.map {|local, _| local.name }
end
##
@@ -1258,7 +1200,7 @@ class Gem::Specification < Gem::BasicSpecification
Gem::Dependency.new local_spec.name, ">= #{local_spec.version}"
remotes, = fetcher.search_for_dependency dependency
- remotes = remotes.map { |n, _| n.version }
+ remotes = remotes.map {|n, _| n.version }
latest_remote = remotes.sort.last
@@ -1270,17 +1212,6 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # Removes +spec+ from the known specs.
-
- def self.remove_spec spec
- warn "Gem::Specification.remove_spec is deprecated and will be removed in RubyGems 3.0" unless Gem::Deprecate.skip
- _all.delete spec
- stubs.delete_if { |s| s.full_name == spec.full_name }
- (@@stubs_by_name[spec.name] || []).delete_if { |s| s.full_name == spec.full_name }
- reset
- end
-
- ##
# Is +name+ a required attribute?
def self.required_attribute?(name)
@@ -1300,36 +1231,40 @@ class Gem::Specification < Gem::BasicSpecification
def self.reset
@@dirs = nil
- Gem.pre_reset_hooks.each { |hook| hook.call }
- @@all = nil
- @@stubs = nil
- @@stubs_by_name = {}
- @@spec_with_requirable_file = {}
- @@active_stub_with_requirable_file = {}
- _clear_load_cache
+ Gem.pre_reset_hooks.each {|hook| hook.call }
+ clear_specs
+ clear_load_cache
unresolved = unresolved_deps
- unless unresolved.empty? then
+ unless unresolved.empty?
w = "W" + "ARN"
- warn "#{w}: Unresolved specs during Gem::Specification.reset:"
+ warn "#{w}: Unresolved or ambiguous specs during Gem::Specification.reset:"
unresolved.values.each do |dep|
warn " #{dep}"
+
+ versions = find_all_by_name(dep.name)
+ unless versions.empty?
+ warn " Available/installed versions of this gem:"
+ versions.each {|s| warn " - #{s.version}" }
+ end
end
- warn "#{w}: Clearing out unresolved specs."
+ warn "#{w}: Clearing out unresolved specs. Try 'gem cleanup <gem>'"
warn "Please report a bug if this causes problems."
unresolved.clear
end
- Gem.post_reset_hooks.each { |hook| hook.call }
+ Gem.post_reset_hooks.each {|hook| hook.call }
end
# DOC: This method needs documented or nodoc'd
def self.unresolved_deps
- @unresolved_deps ||= Hash.new { |h, n| h[n] = Gem::Dependency.new n }
+ @unresolved_deps ||= Hash.new {|h, n| h[n] = Gem::Dependency.new n }
end
##
# Load custom marshal format, re-initializing defaults as needed
def self._load(str)
+ Gem.load_yaml
+
array = Marshal.load str
spec = Gem::Specification.new
@@ -1337,7 +1272,7 @@ class Gem::Specification < Gem::BasicSpecification
current_version = CURRENT_SPECIFICATION_VERSION
- field_count = if spec.specification_version > current_version then
+ field_count = if spec.specification_version > current_version
spec.instance_variable_set :@specification_version,
current_version
MARSHAL_FIELDS[current_version]
@@ -1345,14 +1280,14 @@ class Gem::Specification < Gem::BasicSpecification
MARSHAL_FIELDS[spec.specification_version]
end
- if array.size < field_count then
+ if array.size < field_count
raise TypeError, "invalid Gem::Specification format #{array.inspect}"
end
# Cleanup any YAML::PrivateType. They only show up for an old bug
# where nil => null, so just convert them to nil based on the type.
- array.map! { |e| e.kind_of?(YAML::PrivateType) ? nil : e }
+ array.map! {|e| e.kind_of?(YAML::PrivateType) ? nil : e }
spec.instance_variable_set :@rubygems_version, array[0]
# spec version
@@ -1364,7 +1299,7 @@ class Gem::Specification < Gem::BasicSpecification
spec.instance_variable_set :@required_rubygems_version, array[7]
spec.instance_variable_set :@original_platform, array[8]
spec.instance_variable_set :@dependencies, array[9]
- spec.instance_variable_set :@rubyforge_project, array[10]
+ # offset due to rubyforge_project removal
spec.instance_variable_set :@email, array[11]
spec.instance_variable_set :@authors, array[12]
spec.instance_variable_set :@description, array[13]
@@ -1384,7 +1319,7 @@ class Gem::Specification < Gem::BasicSpecification
sort_obj <=> other.sort_obj
end
- def == other # :nodoc:
+ def ==(other) # :nodoc:
self.class === other &&
name == other.name &&
version == other.version &&
@@ -1409,7 +1344,7 @@ class Gem::Specification < Gem::BasicSpecification
@required_rubygems_version,
@original_platform,
@dependencies,
- @rubyforge_project,
+ '', # rubyforge_project
@email,
@authors,
@description,
@@ -1417,7 +1352,7 @@ class Gem::Specification < Gem::BasicSpecification
true, # has_rdoc
@new_platform,
@licenses,
- @metadata
+ @metadata,
]
end
@@ -1429,7 +1364,7 @@ class Gem::Specification < Gem::BasicSpecification
def activate
other = Gem.loaded_specs[self.name]
- if other then
+ if other
check_version_conflict other
return false
end
@@ -1465,9 +1400,13 @@ class Gem::Specification < Gem::BasicSpecification
raise e
end
- specs = spec_dep.to_specs
+ begin
+ specs = spec_dep.to_specs
+ rescue Gem::MissingSpecError => e
+ raise Gem::MissingSpecError.new(e.name, e.requirement, "at: #{self.spec_file}")
+ end
- if specs.size == 1 then
+ if specs.size == 1
specs.first.activate
else
name = spec_dep.name
@@ -1501,7 +1440,7 @@ class Gem::Specification < Gem::BasicSpecification
self.summary = sanitize_string(summary)
self.description = sanitize_string(description)
self.post_install_message = sanitize_string(post_install_message)
- self.authors = authors.collect { |a| sanitize_string(a) }
+ self.authors = authors.collect {|a| sanitize_string(a) }
end
##
@@ -1513,13 +1452,7 @@ class Gem::Specification < Gem::BasicSpecification
# HACK the #to_s is in here because RSpec has an Array of Arrays of
# Strings for authors. Need a way to disallow bad values on gemspec
# generation. (Probably won't happen.)
- string = string.to_s
-
- begin
- Builder::XChar.encode string
- rescue NameError, NoMethodError
- string.to_xs
- end
+ string.to_s
end
##
@@ -1529,8 +1462,8 @@ class Gem::Specification < Gem::BasicSpecification
def add_bindir(executables)
return nil if executables.nil?
- if @bindir then
- Array(executables).map { |e| File.join(@bindir, e) }
+ if @bindir
+ Array(executables).map {|e| File.join(@bindir, e) }
else
executables
end
@@ -1544,7 +1477,7 @@ class Gem::Specification < Gem::BasicSpecification
# <tt>:development</tt>.
def add_dependency_with_type(dependency, type, requirements)
- requirements = if requirements.empty? then
+ requirements = if requirements.empty?
Gem::Requirement.default
else
requirements.flatten
@@ -1570,16 +1503,7 @@ class Gem::Specification < Gem::BasicSpecification
paths = full_require_paths
- # gem directories must come after -I and ENV['RUBYLIB']
- insert_index = Gem.load_path_insert_index
-
- if insert_index then
- # gem directories must come after -I and ENV['RUBYLIB']
- $LOAD_PATH.insert(insert_index, *paths)
- else
- # we are probably testing in core, -I and RUBYLIB don't apply
- $LOAD_PATH.unshift(*paths)
- end
+ Gem.add_to_load_path(*paths)
end
##
@@ -1605,13 +1529,13 @@ class Gem::Specification < Gem::BasicSpecification
# a full path.
def bin_dir
- @bin_dir ||= File.join gem_dir, bindir # TODO: this is unfortunate
+ @bin_dir ||= File.join gem_dir, bindir
end
##
# Returns the full path to an executable named +name+ in this gem.
- def bin_file name
+ def bin_file(name)
File.join bin_dir, name
end
@@ -1621,7 +1545,7 @@ class Gem::Specification < Gem::BasicSpecification
def build_args
if File.exist? build_info_file
build_info = File.readlines build_info_file
- build_info = build_info.map { |x| x.strip }
+ build_info = build_info.map {|x| x.strip }
build_info.delete ""
build_info
else
@@ -1634,9 +1558,8 @@ class Gem::Specification < Gem::BasicSpecification
# the gem.build_complete file is missing.
def build_extensions # :nodoc:
- return if default_gem?
return if extensions.empty?
- return if installed_by_version < Gem::Version.new('2.2.0.preview.2')
+ return if default_gem?
return if File.exist? gem_build_complete_path
return if !File.writable?(base_dir)
return if !File.exist?(File.join(base_dir, 'extensions'))
@@ -1647,9 +1570,9 @@ class Gem::Specification < Gem::BasicSpecification
unresolved_deps = Gem::Specification.unresolved_deps.dup
Gem::Specification.unresolved_deps.clear
- require 'rubygems/config_file'
- require 'rubygems/ext'
- require 'rubygems/user_interaction'
+ require_relative 'config_file'
+ require_relative 'ext'
+ require_relative 'user_interaction'
ui = Gem::SilentUI.new
Gem::DefaultUserInteraction.use_ui ui do
@@ -1678,16 +1601,6 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # Used to detect if the gem is bundled in older version of Ruby, but not
- # detectable as default gem (see BasicSpecification#default_gem?).
-
- def bundled_gem_in_old_ruby?
- !default_gem? &&
- RUBY_VERSION < "2.0.0" &&
- summary == "This #{name} is bundled with Ruby"
- end
-
- ##
# Returns the full path to the cache directory containing this
# spec's cached gem.
@@ -1707,12 +1620,12 @@ class Gem::Specification < Gem::BasicSpecification
def conflicts
conflicts = {}
- self.runtime_dependencies.each { |dep|
+ self.runtime_dependencies.each do |dep|
spec = Gem.loaded_specs[dep.name]
if spec and not spec.satisfies_requirement? dep
(conflicts[spec] ||= []) << dep
end
- }
+ end
env_req = Gem.env_requirement(name)
(conflicts[self] ||= []) << env_req unless env_req.satisfied_by? version
conflicts
@@ -1722,9 +1635,9 @@ class Gem::Specification < Gem::BasicSpecification
# return true if there will be conflict when spec if loaded together with the list of specs.
def conficts_when_loaded_with?(list_of_specs) # :nodoc:
- result = list_of_specs.any? { |spec|
- spec.dependencies.any? { |dep| dep.runtime? && (dep.name == name) && !satisfies_requirement?(dep) }
- }
+ result = list_of_specs.any? do |spec|
+ spec.dependencies.any? {|dep| dep.runtime? && (dep.name == name) && !satisfies_requirement?(dep) }
+ end
result
end
@@ -1733,23 +1646,26 @@ class Gem::Specification < Gem::BasicSpecification
def has_conflicts?
return true unless Gem.env_requirement(name).satisfied_by?(version)
- self.dependencies.any? { |dep|
- if dep.runtime? then
+ self.dependencies.any? do |dep|
+ if dep.runtime?
spec = Gem.loaded_specs[dep.name]
spec and not spec.satisfies_requirement? dep
else
false
end
- }
+ end
end
- ##
- # The date this gem was created. Lazily defaults to the current UTC date.
+ # The date this gem was created.
+ #
+ # If SOURCE_DATE_EPOCH is set as an environment variable, use that to support
+ # reproducible builds; otherwise, default to the current UTC date.
#
- # There is no need to set this in your gem specification.
+ # Details on SOURCE_DATE_EPOCH:
+ # https://reproducible-builds.org/specs/source-date-epoch/
def date
- @date ||= TODAY
+ @date ||= Time.utc(*Gem.source_date_epoch.utc.to_a[3..5].reverse)
end
DateLike = Object.new # :nodoc:
@@ -1761,26 +1677,20 @@ class Gem::Specification < Gem::BasicSpecification
/\A
(\d{4})-(\d{2})-(\d{2})
(\s+ \d{2}:\d{2}:\d{2}\.\d+ \s* (Z | [-+]\d\d:\d\d) )?
- \Z/x
+ \Z/x.freeze
##
# The date this gem was created
#
# DO NOT set this, it is set automatically when the gem is packaged.
- def date= date
+ def date=(date)
# We want to end up with a Time object with one-day resolution.
# This is the cleanest, most-readable, faster-than-using-Date
# way to do it.
@date = case date
when String then
- if DateTimeFormat =~ date then
- Time.utc($1.to_i, $2.to_i, $3.to_i)
-
- # Workaround for where the date format output from psych isn't
- # parsed as a Time object by syck and thus comes through as a
- # string.
- elsif /\A(\d{4})-(\d{2})-(\d{2}) \d{2}:\d{2}:\d{2}\.\d+?Z\z/ =~ date then
+ if DateTimeFormat =~ date
Time.utc($1.to_i, $2.to_i, $3.to_i)
else
raise(Gem::InvalidSpecificationException,
@@ -1809,11 +1719,12 @@ class Gem::Specification < Gem::BasicSpecification
end
result
end
+ rubygems_deprecate :default_executable
##
# The default value for specification attribute +name+
- def default_value name
+ def default_value(name)
@@default_value[name]
end
@@ -1833,11 +1744,12 @@ class Gem::Specification < Gem::BasicSpecification
#
# [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
- def dependent_gems
+ def dependent_gems(check_dev=true)
out = []
Gem::Specification.each do |spec|
- spec.dependencies.each do |dep|
- if self.satisfies_requirement?(dep) then
+ deps = check_dev ? spec.dependencies : spec.runtime_dependencies
+ deps.each do |dep|
+ if self.satisfies_requirement?(dep)
sats = []
find_all_satisfiers(dep) do |sat|
sats << sat
@@ -1853,13 +1765,13 @@ class Gem::Specification < Gem::BasicSpecification
# Returns all specs that matches this spec's runtime dependencies.
def dependent_specs
- runtime_dependencies.map { |dep| dep.to_specs }.flatten
+ runtime_dependencies.map {|dep| dep.to_specs }.flatten
end
##
# A detailed description of this gem. See also #summary
- def description= str
+ def description=(str)
@description = str.to_s
end
@@ -1867,7 +1779,7 @@ class Gem::Specification < Gem::BasicSpecification
# List of dependencies that are used for development
def development_dependencies
- dependencies.select { |d| d.type == :development }
+ dependencies.select {|d| d.type == :development }
end
##
@@ -1878,17 +1790,17 @@ class Gem::Specification < Gem::BasicSpecification
#
# spec.doc_dir 'ri' # => "/path/to/gem_repo/doc/a-1/ri"
- def doc_dir type = nil
+ def doc_dir(type = nil)
@doc_dir ||= File.join base_dir, 'doc', full_name
- if type then
+ if type
File.join @doc_dir, type
else
@doc_dir
end
end
- def encode_with coder # :nodoc:
+ def encode_with(coder) # :nodoc:
mark_version
coder.add 'name', @name
@@ -1909,7 +1821,7 @@ class Gem::Specification < Gem::BasicSpecification
end
end
- def eql? other # :nodoc:
+ def eql?(other) # :nodoc:
self.class === other && same_attributes?(other)
end
@@ -1923,34 +1835,28 @@ class Gem::Specification < Gem::BasicSpecification
##
# Singular accessor for #executables
- def executable=o
+ def executable=(o)
self.executables = [o]
end
##
- # Sets executables to +value+, ensuring it is an array. Don't
- # use this, push onto the array instead.
+ # Sets executables to +value+, ensuring it is an array.
- def executables= value
- # TODO: warn about setting instead of pushing
+ def executables=(value)
@executables = Array(value)
end
##
- # Sets extensions to +extensions+, ensuring it is an array. Don't
- # use this, push onto the array instead.
+ # Sets extensions to +extensions+, ensuring it is an array.
- def extensions= extensions
- # TODO: warn about setting instead of pushing
+ def extensions=(extensions)
@extensions = Array extensions
end
##
- # Sets extra_rdoc_files to +files+, ensuring it is an array. Don't
- # use this, push onto the array instead.
+ # Sets extra_rdoc_files to +files+, ensuring it is an array.
- def extra_rdoc_files= files
- # TODO: warn about setting instead of pushing
+ def extra_rdoc_files=(files)
@extra_rdoc_files = Array files
end
@@ -1966,14 +1872,14 @@ class Gem::Specification < Gem::BasicSpecification
##
# Sets files to +files+, ensuring it is an array.
- def files= files
+ def files=(files)
@files = Array files
end
##
# Finds all gems that satisfy +dep+
- def find_all_satisfiers dep
+ def find_all_satisfiers(dep)
Gem::Specification.each do |spec|
yield spec if spec.satisfies_requirement? dep
end
@@ -2005,8 +1911,7 @@ class Gem::Specification < Gem::BasicSpecification
end
def gems_dir
- # TODO: this logic seems terribly broken, but tests fail if just base_dir
- @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems")
+ @gems_dir ||= File.join(base_dir, "gems")
end
##
@@ -2017,17 +1922,20 @@ class Gem::Specification < Gem::BasicSpecification
def has_rdoc # :nodoc:
true
end
+ rubygems_deprecate :has_rdoc
##
# Deprecated and ignored.
#
# Formerly used to indicate this gem was RDoc-capable.
- def has_rdoc= ignored # :nodoc:
+ def has_rdoc=(ignored) # :nodoc:
@has_rdoc = true
end
+ rubygems_deprecate :has_rdoc=
alias :has_rdoc? :has_rdoc # :nodoc:
+ rubygems_deprecate :has_rdoc?
##
# True if this gem has files in test_files
@@ -2044,14 +1952,14 @@ class Gem::Specification < Gem::BasicSpecification
name.hash ^ version.hash
end
- def init_with coder # :nodoc:
+ def init_with(coder) # :nodoc:
@installed_by_version ||= nil
yaml_initialize coder.tag, coder.map
end
+ eval <<-RUBY, binding, __FILE__, __LINE__ + 1
+ # frozen_string_literal: true
-
- eval <<-RB, binding, __FILE__, __LINE__ + 1
def set_nil_attributes_to_nil
#{@@nil_attributes.map {|key| "@#{key} = nil" }.join "; "}
end
@@ -2061,14 +1969,14 @@ class Gem::Specification < Gem::BasicSpecification
#{@@non_nil_attributes.map {|key| "@#{key} = #{INITIALIZE_CODE_FOR_DEFAULTS[key]}" }.join ";"}
end
private :set_not_nil_attributes_to_default_values
- RB
+ RUBY
##
# Specification constructor. Assigns the default values to the attributes
# and yields itself for further initialization. Optionally takes +name+ and
# +version+.
- def initialize name = nil, version = nil
+ def initialize(name = nil, version = nil)
super()
@gems_dir = nil
@base_dir = nil
@@ -2086,20 +1994,24 @@ class Gem::Specification < Gem::BasicSpecification
self.name = name if name
self.version = version if version
+ if platform = Gem.platforms.last and platform != Gem::Platform::RUBY and platform != Gem::Platform.local
+ self.platform = platform
+ end
+
yield self if block_given?
end
##
# Duplicates array_attributes from +other_spec+ so state isn't shared.
- def initialize_copy other_spec
+ def initialize_copy(other_spec)
self.class.array_attributes.each do |name|
name = :"@#{name}"
next unless other_spec.instance_variable_defined? name
begin
val = other_spec.instance_variable_get(name)
- if val then
+ if val
instance_variable_set name, val.dup
elsif Gem.configuration.really_verbose
warn "WARNING: #{full_name} has an invalid nil value for #{name}"
@@ -2116,7 +2028,7 @@ class Gem::Specification < Gem::BasicSpecification
def base_dir
return Gem.dir unless loaded_from
- @base_dir ||= if default_gem? then
+ @base_dir ||= if default_gem?
File.dirname File.dirname File.dirname loaded_from
else
File.dirname File.dirname loaded_from
@@ -2188,11 +2100,17 @@ class Gem::Specification < Gem::BasicSpecification
end
##
+ # Track removed method calls to warn about during build time.
# Warn about unknown attributes while loading a spec.
def method_missing(sym, *a, &b) # :nodoc:
+ if REMOVED_METHODS.include?(sym)
+ removed_method_calls << sym
+ return
+ end
+
if @specification_version > CURRENT_SPECIFICATION_VERSION and
- sym.to_s =~ /=$/ then
+ sym.to_s.end_with?("=")
warn "ignoring #{sym} loading #{full_name}" if $DEBUG
else
super
@@ -2204,9 +2122,8 @@ class Gem::Specification < Gem::BasicSpecification
# probably want to build_extensions
def missing_extensions?
- return false if default_gem?
return false if extensions.empty?
- return false if installed_by_version < Gem::Version.new('2.2.0.preview.2')
+ return false if default_gem?
return false if File.exist? gem_build_complete_path
true
@@ -2219,7 +2136,7 @@ class Gem::Specification < Gem::BasicSpecification
# file list.
def normalize
- if defined?(@extra_rdoc_files) and @extra_rdoc_files then
+ if defined?(@extra_rdoc_files) and @extra_rdoc_files
@extra_rdoc_files.uniq!
@files ||= []
@files.concat(@extra_rdoc_files)
@@ -2244,7 +2161,7 @@ class Gem::Specification < Gem::BasicSpecification
# platform. For use with legacy gems.
def original_name # :nodoc:
- if platform == Gem::Platform::RUBY or platform.nil? then
+ if platform == Gem::Platform::RUBY or platform.nil?
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{@original_platform}"
@@ -2276,12 +2193,13 @@ class Gem::Specification < Gem::BasicSpecification
attributes.each do |attr_name|
current_value = self.send attr_name
+ current_value = current_value.sort if %i[files test_files].include? attr_name
if current_value != default_value(attr_name) or
- self.class.required_attribute? attr_name then
+ self.class.required_attribute? attr_name
q.text "s.#{attr_name} = "
- if attr_name == :date then
+ if attr_name == :date
current_value = current_value.utc
q.text "Time.utc(#{current_value.year}, #{current_value.month}, #{current_value.day})"
@@ -2299,7 +2217,7 @@ class Gem::Specification < Gem::BasicSpecification
# Raise an exception if the version of this spec conflicts with the one
# that is already loaded (+other+)
- def check_version_conflict other # :nodoc:
+ def check_version_conflict(other) # :nodoc:
return if self.version == other.version
# This gem is already loaded. If the currently loaded gem is not in the
@@ -2309,7 +2227,6 @@ class Gem::Specification < Gem::BasicSpecification
e = Gem::LoadError.new msg
e.name = self.name
- # TODO: e.requirement = dep.requirement
raise e
end
@@ -2320,17 +2237,15 @@ class Gem::Specification < Gem::BasicSpecification
# Check the spec for possible conflicts and freak out if there are any.
def raise_if_conflicts # :nodoc:
- if has_conflicts? then
+ if has_conflicts?
raise Gem::ConflictError.new self, conflicts
end
end
##
- # Sets rdoc_options to +value+, ensuring it is an array. Don't
- # use this, push onto the array instead.
+ # Sets rdoc_options to +value+, ensuring it is an array.
- def rdoc_options= options
- # TODO: warn about setting instead of pushing
+ def rdoc_options=(options)
@rdoc_options = Array options
end
@@ -2344,20 +2259,18 @@ class Gem::Specification < Gem::BasicSpecification
##
# Singular accessor for #require_paths
- def require_path= path
+ def require_path=(path)
self.require_paths = Array(path)
end
##
- # Set requirements to +req+, ensuring it is an array. Don't
- # use this, push onto the array instead.
+ # Set requirements to +req+, ensuring it is an array.
- def requirements= req
- # TODO: warn about setting instead of pushing
+ def requirements=(req)
@requirements = Array req
end
- def respond_to_missing? m, include_private = false # :nodoc:
+ def respond_to_missing?(m, include_private = false) # :nodoc:
false
end
@@ -2374,18 +2287,18 @@ class Gem::Specification < Gem::BasicSpecification
def ruby_code(obj)
case obj
- when String then obj.dump + ".freeze"
- when Array then '[' + obj.map { |x| ruby_code x }.join(", ") + ']'
- when Hash then
- seg = obj.keys.sort.map { |k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" }
+ when String then obj.dump + ".freeze"
+ when Array then '[' + obj.map {|x| ruby_code x }.join(", ") + ']'
+ when Hash then
+ seg = obj.keys.sort.map {|k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" }
"{ #{seg.join(', ')} }"
- when Gem::Version then obj.to_s.dump
- when DateLike then obj.strftime('%Y-%m-%d').dump
- when Time then obj.strftime('%Y-%m-%d').dump
- when Numeric then obj.inspect
- when true, false, nil then obj.inspect
- when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
- when Gem::Requirement then
+ when Gem::Version then obj.to_s.dump
+ when DateLike then obj.strftime('%Y-%m-%d').dump
+ when Time then obj.strftime('%Y-%m-%d').dump
+ when Numeric then obj.inspect
+ when true, false, nil then obj.inspect
+ when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
+ when Gem::Requirement then
list = obj.as_list
"Gem::Requirement.new(#{ruby_code(list.size == 1 ? obj.to_s : list)})"
else raise Gem::Exception, "ruby_code case not handled: #{obj.class}"
@@ -2404,8 +2317,8 @@ class Gem::Specification < Gem::BasicSpecification
##
# True if this gem has the same attributes as +other+.
- def same_attributes? spec
- @@attributes.all? { |name, default| self.send(name) == spec.send(name) }
+ def same_attributes?(spec)
+ @@attributes.all? {|name, default| self.send(name) == spec.send(name) }
end
private :same_attributes?
@@ -2413,7 +2326,7 @@ class Gem::Specification < Gem::BasicSpecification
##
# Checks if this specification meets the requirement of +dependency+.
- def satisfies_requirement? dependency
+ def satisfies_requirement?(dependency)
return @name == dependency.name &&
dependency.requirement.satisfied_by?(@version)
end
@@ -2460,7 +2373,7 @@ class Gem::Specification < Gem::BasicSpecification
##
# A short summary of this gem's description.
- def summary= str
+ def summary=(str)
@summary = str.to_s.strip.
gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird.
end
@@ -2475,7 +2388,7 @@ class Gem::Specification < Gem::BasicSpecification
##
# Singular mutator for #test_files
- def test_file= file # :nodoc:
+ def test_file=(file) # :nodoc:
self.test_files = [file]
end
@@ -2487,11 +2400,11 @@ class Gem::Specification < Gem::BasicSpecification
# Handle the possibility that we have @test_suite_file but not
# @test_files. This will happen when an old gem is loaded via
# YAML.
- if defined? @test_suite_file then
+ if defined? @test_suite_file
@test_files = [@test_suite_file].flatten
@test_suite_file = nil
end
- if defined?(@test_files) and @test_files then
+ if defined?(@test_files) and @test_files
@test_files
else
@test_files = []
@@ -2515,7 +2428,7 @@ class Gem::Specification < Gem::BasicSpecification
result << " s.name = #{ruby_code name}"
result << " s.version = #{ruby_code version}"
- unless platform.nil? or platform == Gem::Platform::RUBY then
+ unless platform.nil? or platform == Gem::Platform::RUBY
result << " s.platform = #{ruby_code original_platform}"
end
result << ""
@@ -2536,46 +2449,42 @@ class Gem::Specification < Gem::BasicSpecification
:version,
:has_rdoc,
:default_executable,
- :metadata
+ :metadata,
+ :signing_key,
]
@@attributes.each do |attr_name|
next if handled.include? attr_name
current_value = self.send(attr_name)
- if current_value != default_value(attr_name) or
- self.class.required_attribute? attr_name then
+ if current_value != default_value(attr_name) || self.class.required_attribute?(attr_name)
result << " s.#{attr_name} = #{ruby_code current_value}"
end
end
- if @installed_by_version then
+ if String === signing_key
+ result << " s.signing_key = #{signing_key.dump}.freeze"
+ end
+
+ if @installed_by_version
result << nil
result << " s.installed_by_version = \"#{Gem::VERSION}\" if s.respond_to? :installed_by_version"
end
- unless dependencies.empty? then
+ unless dependencies.empty?
result << nil
result << " if s.respond_to? :specification_version then"
result << " s.specification_version = #{specification_version}"
+ result << " end"
result << nil
- result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then"
+ result << " if s.respond_to? :add_runtime_dependency then"
dependencies.each do |dep|
req = dep.requirements_list.inspect
dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
- result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>.freeze, #{req})"
- end
-
- result << " else"
-
- dependencies.each do |dep|
- version_reqs_param = dep.requirements_list.inspect
- result << " s.add_dependency(%q<#{dep.name}>.freeze, #{version_reqs_param})"
+ result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>.freeze, #{req})"
end
- result << ' end'
-
result << " else"
dependencies.each do |dep|
version_reqs_param = dep.requirements_list.inspect
@@ -2612,44 +2521,38 @@ class Gem::Specification < Gem::BasicSpecification
end
def to_yaml(opts = {}) # :nodoc:
- if (YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck?) ||
- (defined?(Psych) && YAML == Psych) then
- # Because the user can switch the YAML engine behind our
- # back, we have to check again here to make sure that our
- # psych code was properly loaded, and load it if not.
- unless Gem.const_defined?(:NoAliasYAMLTree)
- require 'rubygems/psych_tree'
- end
+ Gem.load_yaml
- builder = Gem::NoAliasYAMLTree.create
- builder << self
- ast = builder.tree
+ # Because the user can switch the YAML engine behind our
+ # back, we have to check again here to make sure that our
+ # psych code was properly loaded, and load it if not.
+ unless Gem.const_defined?(:NoAliasYAMLTree)
+ require_relative 'psych_tree'
+ end
- io = StringIO.new
- io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
+ builder = Gem::NoAliasYAMLTree.create
+ builder << self
+ ast = builder.tree
- Psych::Visitors::Emitter.new(io).accept(ast)
+ require 'stringio'
+ io = StringIO.new
+ io.set_encoding Encoding::UTF_8
- io.string.gsub(/ !!null \n/, " \n")
- else
- YAML.quick_emit object_id, opts do |out|
- out.map taguri, to_yaml_style do |map|
- encode_with map
- end
- end
- end
+ Psych::Visitors::Emitter.new(io).accept(ast)
+
+ io.string.gsub(/ !!null \n/, " \n")
end
##
# Recursively walk dependencies of this spec, executing the +block+ for each
# hop.
- def traverse trail = [], visited = {}, &block
+ def traverse(trail = [], visited = {}, &block)
trail.push(self)
begin
dependencies.each do |dep|
next unless dep.runtime?
- dep.to_specs.each do |dep_spec|
+ dep.matching_specs(true).each do |dep_spec|
next if visited.has_key?(dep_spec)
visited[dep_spec] = true
trail.push(dep_spec)
@@ -2661,7 +2564,7 @@ class Gem::Specification < Gem::BasicSpecification
unless result == :next
spec_name = dep_spec.name
dep_spec.traverse(trail, visited, &block) unless
- trail.any? { |s| s.name == spec_name }
+ trail.any? {|s| s.name == spec_name }
end
end
end
@@ -2677,340 +2580,49 @@ class Gem::Specification < Gem::BasicSpecification
# Raises InvalidSpecificationException if the spec does not pass the
# checks..
- def validate packaging = true
- @warnings = 0
- require 'rubygems/user_interaction'
- extend Gem::UserInteraction
+ def validate(packaging = true, strict = false)
normalize
- nil_attributes = self.class.non_nil_attributes.find_all do |attrname|
- instance_variable_get("@#{attrname}").nil?
- end
-
- unless nil_attributes.empty? then
- raise Gem::InvalidSpecificationException,
- "#{nil_attributes.join ', '} must not be nil"
- end
-
- if packaging and rubygems_version != Gem::VERSION then
- raise Gem::InvalidSpecificationException,
- "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
- end
-
- @@required_attributes.each do |symbol|
- unless self.send symbol then
- raise Gem::InvalidSpecificationException,
- "missing value for attribute #{symbol}"
- end
- end
-
- if !name.is_a?(String) then
- raise Gem::InvalidSpecificationException,
- "invalid value for attribute name: \"#{name.inspect}\" must be a string"
- elsif name !~ /[a-zA-Z]/ then
- raise Gem::InvalidSpecificationException,
- "invalid value for attribute name: #{name.dump} must include at least one letter"
- elsif name !~ VALID_NAME_PATTERN then
- raise Gem::InvalidSpecificationException,
- "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
- end
-
- if raw_require_paths.empty? then
- raise Gem::InvalidSpecificationException,
- 'specification must have at least one require_path'
- end
-
- @files.delete_if { |x| File.directory?(x) && !File.symlink?(x) }
- @test_files.delete_if { |x| File.directory?(x) && !File.symlink?(x) }
- @executables.delete_if { |x| File.directory?(File.join(@bindir, x)) }
- @extra_rdoc_files.delete_if { |x| File.directory?(x) && !File.symlink?(x) }
- @extensions.delete_if { |x| File.directory?(x) && !File.symlink?(x) }
-
- non_files = files.reject { |x| File.file?(x) || File.symlink?(x) }
-
- unless not packaging or non_files.empty? then
- raise Gem::InvalidSpecificationException,
- "[\"#{non_files.join "\", \""}\"] are not files"
- end
-
- if files.include? file_name then
- raise Gem::InvalidSpecificationException,
- "#{full_name} contains itself (#{file_name}), check your files list"
- end
-
- unless specification_version.is_a?(Integer)
- raise Gem::InvalidSpecificationException,
- 'specification_version must be an Integer (did you mean version?)'
- end
-
- case platform
- when Gem::Platform, Gem::Platform::RUBY then # ok
- else
- raise Gem::InvalidSpecificationException,
- "invalid platform #{platform.inspect}, see Gem::Platform"
- end
-
- self.class.array_attributes.each do |field|
- val = self.send field
- klass = case field
- when :dependencies
- Gem::Dependency
- else
- String
- end
-
- unless Array === val and val.all? { |x| x.kind_of?(klass) } then
- raise(Gem::InvalidSpecificationException,
- "#{field} must be an Array of #{klass}")
- end
- end
-
- [:authors].each do |field|
- val = self.send field
- raise Gem::InvalidSpecificationException, "#{field} may not be empty" if
- val.empty?
- end
-
- unless Hash === metadata
- raise Gem::InvalidSpecificationException,
- 'metadata must be a hash'
- end
-
- validate_metadata
-
- licenses.each { |license|
- if license.length > 64
- raise Gem::InvalidSpecificationException,
- "each license must be 64 characters or less"
- end
-
- if !Gem::Licenses.match?(license)
- suggestions = Gem::Licenses.suggestions(license)
- message = <<-warning
-license value '#{license}' is invalid. Use a license identifier from
-http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
- warning
- message += "Did you mean #{suggestions.map { |s| "'#{s}'"}.join(', ')}?\n" unless suggestions.nil?
- warning(message)
- end
- }
-
- warning <<-warning if licenses.empty?
-licenses is empty, but is recommended. Use a license identifier from
-http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
- warning
-
- validate_permissions
-
- # reject lazy developers:
-
- lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')
-
- unless authors.grep(/FI XME|TO DO/x).empty? then
- raise Gem::InvalidSpecificationException, "#{lazy} is not an author"
- end
-
- unless Array(email).grep(/FI XME|TO DO/x).empty? then
- raise Gem::InvalidSpecificationException, "#{lazy} is not an email"
- end
-
- if description =~ /FI XME|TO DO/x then
- raise Gem::InvalidSpecificationException, "#{lazy} is not a description"
- end
-
- if summary =~ /FI XME|TO DO/x then
- raise Gem::InvalidSpecificationException, "#{lazy} is not a summary"
- end
-
- if homepage and not homepage.empty? and
- homepage !~ /\A[a-z][a-z\d+.-]*:/i then
- raise Gem::InvalidSpecificationException,
- "\"#{homepage}\" is not a URI"
- end
-
- # Warnings
-
- %w[author homepage summary files].each do |attribute|
- value = self.send attribute
- warning "no #{attribute} specified" if value.nil? or value.empty?
- end
-
- if description == summary then
- warning 'description and summary are identical'
- end
-
- # TODO: raise at some given date
- warning "deprecated autorequire specified" if autorequire
-
- executables.each do |executable|
- executable_path = File.join(bindir, executable)
- shebang = File.read(executable_path, 2) == '#!'
-
- warning "#{executable_path} is missing #! line" unless shebang
- end
-
- files.each do |file|
- next unless File.symlink?(file)
- warning "#{file} is a symlink, which is not supported on all platforms"
- end
-
- validate_dependencies
+ validation_policy = Gem::SpecificationPolicy.new(self)
+ validation_policy.packaging = packaging
+ validation_policy.validate(strict)
+ end
- true
- ensure
- if $! or @warnings > 0 then
- alert_warning "See http://guides.rubygems.org/specification-reference/ for help"
- end
+ def keep_only_files_and_directories
+ @executables.delete_if {|x| File.directory?(File.join(@bindir, x)) }
+ @extensions.delete_if {|x| File.directory?(x) && !File.symlink?(x) }
+ @extra_rdoc_files.delete_if {|x| File.directory?(x) && !File.symlink?(x) }
+ @files.delete_if {|x| File.directory?(x) && !File.symlink?(x) }
+ @test_files.delete_if {|x| File.directory?(x) && !File.symlink?(x) }
end
def validate_metadata
- url_validation_regex = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}
- link_keys = %w(
- bug_tracker_uri
- changelog_uri
- documentation_uri
- homepage_uri
- mailing_list_uri
- source_code_uri
- wiki_uri
- )
-
- metadata.each do|key, value|
- if !key.kind_of?(String)
- raise Gem::InvalidSpecificationException,
- "metadata keys must be a String"
- end
-
- if key.size > 128
- raise Gem::InvalidSpecificationException,
- "metadata key too large (#{key.size} > 128)"
- end
-
- if !value.kind_of?(String)
- raise Gem::InvalidSpecificationException,
- "metadata values must be a String"
- end
-
- if value.size > 1024
- raise Gem::InvalidSpecificationException,
- "metadata value too large (#{value.size} > 1024)"
- end
-
- if link_keys.include? key
- if value !~ url_validation_regex
- raise Gem::InvalidSpecificationException,
- "metadata['#{key}'] has invalid link: #{value.inspect}"
- end
- end
- end
+ Gem::SpecificationPolicy.new(self).validate_metadata
end
+ rubygems_deprecate :validate_metadata
- ##
- # Checks that dependencies use requirements as we recommend. Warnings are
- # issued when dependencies are open-ended or overly strict for semantic
- # versioning.
-
- def validate_dependencies # :nodoc:
- # NOTE: see REFACTOR note in Gem::Dependency about types - this might be brittle
- seen = Gem::Dependency::TYPES.inject({}) { |types, type| types.merge({ type => {}}) }
-
- error_messages = []
- warning_messages = []
- dependencies.each do |dep|
- if prev = seen[dep.type][dep.name] then
- error_messages << <<-MESSAGE
-duplicate dependency on #{dep}, (#{prev.requirement}) use:
- add_#{dep.type}_dependency '#{dep.name}', '#{dep.requirement}', '#{prev.requirement}'
- MESSAGE
- end
-
- seen[dep.type][dep.name] = dep
-
- prerelease_dep = dep.requirements_list.any? do |req|
- Gem::Requirement.new(req).prerelease?
- end
-
- warning_messages << "prerelease dependency on #{dep} is not recommended" if
- prerelease_dep && !version.prerelease?
-
- overly_strict = dep.requirement.requirements.length == 1 &&
- dep.requirement.requirements.any? do |op, version|
- op == '~>' and
- not version.prerelease? and
- version.segments.length > 2 and
- version.segments.first != 0
- end
-
- if overly_strict then
- _, dep_version = dep.requirement.requirements.first
-
- base = dep_version.segments.first 2
-
- warning_messages << <<-WARNING
-pessimistic dependency on #{dep} may be overly strict
- if #{dep.name} is semantically versioned, use:
- add_#{dep.type}_dependency '#{dep.name}', '~> #{base.join '.'}', '>= #{dep_version}'
- WARNING
- end
-
- open_ended = dep.requirement.requirements.all? do |op, version|
- not version.prerelease? and (op == '>' or op == '>=')
- end
-
- if open_ended then
- op, dep_version = dep.requirement.requirements.first
-
- base = dep_version.segments.first 2
-
- bugfix = if op == '>' then
- ", '> #{dep_version}'"
- elsif op == '>=' and base != dep_version.segments then
- ", '>= #{dep_version}'"
- end
-
- warning_messages << <<-WARNING
-open-ended dependency on #{dep} is not recommended
- if #{dep.name} is semantically versioned, use:
- add_#{dep.type}_dependency '#{dep.name}', '~> #{base.join '.'}'#{bugfix}
- WARNING
- end
- end
- if error_messages.any?
- raise Gem::InvalidSpecificationException, error_messages.join
- end
- if warning_messages.any?
- warning_messages.each { |warning_message| warning warning_message }
- end
+ def validate_dependencies
+ Gem::SpecificationPolicy.new(self).validate_dependencies
end
-
- ##
- # Checks to see if the files to be packaged are world-readable.
+ rubygems_deprecate :validate_dependencies
def validate_permissions
- return if Gem.win_platform?
-
- files.each do |file|
- next unless File.file?(file)
- next if File.stat(file).mode & 0444 == 0444
- warning "#{file} is not world-readable"
- end
-
- executables.each do |name|
- exec = File.join @bindir, name
- next unless File.file?(exec)
- next if File.stat(exec).executable?
- warning "#{exec} is not executable"
- end
+ Gem::SpecificationPolicy.new(self).validate_permissions
end
+ rubygems_deprecate :validate_permissions
##
# Set the version to +version+, potentially also setting
# required_rubygems_version if +version+ indicates it is a
# prerelease.
- def version= version
+ def version=(version)
@version = Gem::Version.create(version)
- self.required_rubygems_version = '> 1.3.1' if @version.prerelease?
+ # skip to set required_ruby_version when pre-released rubygems.
+ # It caused to raise CircularDependencyError
+ if @version.prerelease? && (@name.nil? || @name.strip != "rubygems")
+ self.required_rubygems_version = '> 1.3.1'
+ end
invalidate_memoized_attributes
return @version
@@ -3025,9 +2637,9 @@ open-ended dependency on #{dep} is not recommended
case ivar
when "date"
# Force Date to go through the extra coerce logic in date=
- self.date = val.untaint
+ self.date = val.tap(&Gem::UNTAINT)
else
- instance_variable_set "@#{ivar}", val.untaint
+ instance_variable_set "@#{ivar}", val.tap(&Gem::UNTAINT)
end
end
@@ -3057,27 +2669,7 @@ open-ended dependency on #{dep} is not recommended
@installed_by_version ||= nil
end
- def warning statement # :nodoc:
- @warnings += 1
-
- alert_warning statement
- end
-
def raw_require_paths # :nodoc:
@require_paths
end
-
- extend Gem::Deprecate
-
- # TODO:
- # deprecate :has_rdoc, :none, 2011, 10
- # deprecate :has_rdoc?, :none, 2011, 10
- # deprecate :has_rdoc=, :none, 2011, 10
- # deprecate :default_executable, :none, 2011, 10
- # deprecate :default_executable=, :none, 2011, 10
- # deprecate :file_name, :cache_file, 2011, 10
- # deprecate :full_gem_path, :cache_file, 2011, 10
end
-
-# DOC: What is this and why is it here, randomly, at the end of this file?
-Gem.clear_paths
diff --git a/lib/rubygems/specification_policy.rb b/lib/rubygems/specification_policy.rb
new file mode 100644
index 0000000000..73bd31970c
--- /dev/null
+++ b/lib/rubygems/specification_policy.rb
@@ -0,0 +1,486 @@
+require_relative 'user_interaction'
+
+class Gem::SpecificationPolicy
+ include Gem::UserInteraction
+
+ VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/.freeze # :nodoc:
+
+ SPECIAL_CHARACTERS = /\A[#{Regexp.escape('.-_')}]+/.freeze # :nodoc:
+
+ VALID_URI_PATTERN = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}.freeze # :nodoc:
+
+ METADATA_LINK_KEYS = %w[
+ bug_tracker_uri
+ changelog_uri
+ documentation_uri
+ homepage_uri
+ mailing_list_uri
+ source_code_uri
+ wiki_uri
+ funding_uri
+ ].freeze # :nodoc:
+
+ def initialize(specification)
+ @warnings = 0
+
+ @specification = specification
+ end
+
+ ##
+ # If set to true, run packaging-specific checks, as well.
+
+ attr_accessor :packaging
+
+ ##
+ # Does a sanity check on the specification.
+ #
+ # Raises InvalidSpecificationException if the spec does not pass the
+ # checks.
+ #
+ # It also performs some validations that do not raise but print warning
+ # messages instead.
+
+ def validate(strict = false)
+ validate_required!
+
+ validate_optional(strict) if packaging || strict
+
+ true
+ end
+
+ ##
+ # Does a sanity check on the specification.
+ #
+ # Raises InvalidSpecificationException if the spec does not pass the
+ # checks.
+ #
+ # Only runs checks that are considered necessary for the specification to be
+ # functional.
+
+ def validate_required!
+ validate_nil_attributes
+
+ validate_rubygems_version
+
+ validate_required_attributes
+
+ validate_name
+
+ validate_require_paths
+
+ @specification.keep_only_files_and_directories
+
+ validate_non_files
+
+ validate_self_inclusion_in_files_list
+
+ validate_specification_version
+
+ validate_platform
+
+ validate_array_attributes
+
+ validate_authors_field
+
+ validate_metadata
+
+ validate_licenses_length
+
+ validate_lazy_metadata
+
+ validate_duplicate_dependencies
+ end
+
+ def validate_optional(strict)
+ validate_licenses
+
+ validate_permissions
+
+ validate_values
+
+ validate_dependencies
+
+ validate_extensions
+
+ validate_removed_attributes
+
+ if @warnings > 0
+ if strict
+ error "specification has warnings"
+ else
+ alert_warning help_text
+ end
+ end
+ end
+
+ ##
+ # Implementation for Specification#validate_metadata
+
+ def validate_metadata
+ metadata = @specification.metadata
+
+ unless Hash === metadata
+ error 'metadata must be a hash'
+ end
+
+ metadata.each do |key, value|
+ entry = "metadata['#{key}']"
+ if !key.kind_of?(String)
+ error "metadata keys must be a String"
+ end
+
+ if key.size > 128
+ error "metadata key is too large (#{key.size} > 128)"
+ end
+
+ if !value.kind_of?(String)
+ error "#{entry} value must be a String"
+ end
+
+ if value.size > 1024
+ error "#{entry} value is too large (#{value.size} > 1024)"
+ end
+
+ if METADATA_LINK_KEYS.include? key
+ if value !~ VALID_URI_PATTERN
+ error "#{entry} has invalid link: #{value.inspect}"
+ end
+ end
+ end
+ end
+
+ ##
+ # Checks that no duplicate dependencies are specified.
+
+ def validate_duplicate_dependencies # :nodoc:
+ # NOTE: see REFACTOR note in Gem::Dependency about types - this might be brittle
+ seen = Gem::Dependency::TYPES.inject({}) {|types, type| types.merge({ type => {}}) }
+
+ error_messages = []
+ @specification.dependencies.each do |dep|
+ if prev = seen[dep.type][dep.name]
+ error_messages << <<-MESSAGE
+duplicate dependency on #{dep}, (#{prev.requirement}) use:
+ add_#{dep.type}_dependency '#{dep.name}', '#{dep.requirement}', '#{prev.requirement}'
+ MESSAGE
+ end
+
+ seen[dep.type][dep.name] = dep
+ end
+ if error_messages.any?
+ error error_messages.join
+ end
+ end
+
+ ##
+ # Checks that dependencies use requirements as we recommend. Warnings are
+ # issued when dependencies are open-ended or overly strict for semantic
+ # versioning.
+
+ def validate_dependencies # :nodoc:
+ warning_messages = []
+ @specification.dependencies.each do |dep|
+ prerelease_dep = dep.requirements_list.any? do |req|
+ Gem::Requirement.new(req).prerelease?
+ end
+
+ warning_messages << "prerelease dependency on #{dep} is not recommended" if
+ prerelease_dep && !@specification.version.prerelease?
+
+ open_ended = dep.requirement.requirements.all? do |op, version|
+ not version.prerelease? and (op == '>' or op == '>=')
+ end
+
+ if open_ended
+ op, dep_version = dep.requirement.requirements.first
+
+ segments = dep_version.segments
+
+ base = segments.first 2
+
+ recommendation = if (op == '>' || op == '>=') && segments == [0]
+ " use a bounded requirement, such as '~> x.y'"
+ else
+ bugfix = if op == '>'
+ ", '> #{dep_version}'"
+ elsif op == '>=' and base != segments
+ ", '>= #{dep_version}'"
+ end
+
+ " if #{dep.name} is semantically versioned, use:\n" \
+ " add_#{dep.type}_dependency '#{dep.name}', '~> #{base.join '.'}'#{bugfix}"
+ end
+
+ warning_messages << ["open-ended dependency on #{dep} is not recommended", recommendation].join("\n") + "\n"
+ end
+ end
+ if warning_messages.any?
+ warning_messages.each {|warning_message| warning warning_message }
+ end
+ end
+
+ ##
+ # Issues a warning for each file to be packaged which is world-readable.
+ #
+ # Implementation for Specification#validate_permissions
+
+ def validate_permissions
+ return if Gem.win_platform?
+
+ @specification.files.each do |file|
+ next unless File.file?(file)
+ next if File.stat(file).mode & 0444 == 0444
+ warning "#{file} is not world-readable"
+ end
+
+ @specification.executables.each do |name|
+ exec = File.join @specification.bindir, name
+ next unless File.file?(exec)
+ next if File.stat(exec).executable?
+ warning "#{exec} is not executable"
+ end
+ end
+
+ private
+
+ def validate_nil_attributes
+ nil_attributes = Gem::Specification.non_nil_attributes.select do |attrname|
+ @specification.instance_variable_get("@#{attrname}").nil?
+ end
+ return if nil_attributes.empty?
+ error "#{nil_attributes.join ', '} must not be nil"
+ end
+
+ def validate_rubygems_version
+ return unless packaging
+
+ rubygems_version = @specification.rubygems_version
+
+ return if rubygems_version == Gem::VERSION
+
+ error "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
+ end
+
+ def validate_required_attributes
+ Gem::Specification.required_attributes.each do |symbol|
+ unless @specification.send symbol
+ error "missing value for attribute #{symbol}"
+ end
+ end
+ end
+
+ def validate_name
+ name = @specification.name
+
+ if !name.is_a?(String)
+ error "invalid value for attribute name: \"#{name.inspect}\" must be a string"
+ elsif name !~ /[a-zA-Z]/
+ error "invalid value for attribute name: #{name.dump} must include at least one letter"
+ elsif name !~ VALID_NAME_PATTERN
+ error "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
+ elsif name =~ SPECIAL_CHARACTERS
+ error "invalid value for attribute name: #{name.dump} can not begin with a period, dash, or underscore"
+ end
+ end
+
+ def validate_require_paths
+ return unless @specification.raw_require_paths.empty?
+
+ error 'specification must have at least one require_path'
+ end
+
+ def validate_non_files
+ return unless packaging
+
+ non_files = @specification.files.reject {|x| File.file?(x) || File.symlink?(x) }
+
+ unless non_files.empty?
+ error "[\"#{non_files.join "\", \""}\"] are not files"
+ end
+ end
+
+ def validate_self_inclusion_in_files_list
+ file_name = @specification.file_name
+
+ return unless @specification.files.include?(file_name)
+
+ error "#{@specification.full_name} contains itself (#{file_name}), check your files list"
+ end
+
+ def validate_specification_version
+ return if @specification.specification_version.is_a?(Integer)
+
+ error 'specification_version must be an Integer (did you mean version?)'
+ end
+
+ def validate_platform
+ platform = @specification.platform
+
+ case platform
+ when Gem::Platform, Gem::Platform::RUBY # ok
+ else
+ error "invalid platform #{platform.inspect}, see Gem::Platform"
+ end
+ end
+
+ def validate_array_attributes
+ Gem::Specification.array_attributes.each do |field|
+ validate_array_attribute(field)
+ end
+ end
+
+ def validate_array_attribute(field)
+ val = @specification.send(field)
+ klass = case field
+ when :dependencies then
+ Gem::Dependency
+ else
+ String
+ end
+
+ unless Array === val and val.all? {|x| x.kind_of?(klass) }
+ error "#{field} must be an Array of #{klass}"
+ end
+ end
+
+ def validate_authors_field
+ return unless @specification.authors.empty?
+
+ error "authors may not be empty"
+ end
+
+ def validate_licenses_length
+ licenses = @specification.licenses
+
+ licenses.each do |license|
+ if license.length > 64
+ error "each license must be 64 characters or less"
+ end
+ end
+ end
+
+ def validate_licenses
+ licenses = @specification.licenses
+
+ licenses.each do |license|
+ if !Gem::Licenses.match?(license)
+ suggestions = Gem::Licenses.suggestions(license)
+ message = <<-WARNING
+license value '#{license}' is invalid. Use a license identifier from
+http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
+ WARNING
+ message += "Did you mean #{suggestions.map {|s| "'#{s}'" }.join(', ')}?\n" unless suggestions.nil?
+ warning(message)
+ end
+ end
+
+ warning <<-WARNING if licenses.empty?
+licenses is empty, but is recommended. Use a license identifier from
+http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
+ WARNING
+ end
+
+ LAZY = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')
+ LAZY_PATTERN = /\AFI XME|\ATO DO/x.freeze
+ HOMEPAGE_URI_PATTERN = /\A[a-z][a-z\d+.-]*:/i.freeze
+
+ def validate_lazy_metadata
+ unless @specification.authors.grep(LAZY_PATTERN).empty?
+ error "#{LAZY} is not an author"
+ end
+
+ unless Array(@specification.email).grep(LAZY_PATTERN).empty?
+ error "#{LAZY} is not an email"
+ end
+
+ if @specification.description =~ LAZY_PATTERN
+ error "#{LAZY} is not a description"
+ end
+
+ if @specification.summary =~ LAZY_PATTERN
+ error "#{LAZY} is not a summary"
+ end
+
+ homepage = @specification.homepage
+
+ # Make sure a homepage is valid HTTP/HTTPS URI
+ if homepage and not homepage.empty?
+ require 'uri'
+ begin
+ homepage_uri = URI.parse(homepage)
+ unless [URI::HTTP, URI::HTTPS].member? homepage_uri.class
+ error "\"#{homepage}\" is not a valid HTTP URI"
+ end
+ rescue URI::InvalidURIError
+ error "\"#{homepage}\" is not a valid HTTP URI"
+ end
+ end
+ end
+
+ def validate_values
+ %w[author homepage summary files].each do |attribute|
+ validate_attribute_present(attribute)
+ end
+
+ if @specification.description == @specification.summary
+ warning "description and summary are identical"
+ end
+
+ # TODO: raise at some given date
+ warning "deprecated autorequire specified" if @specification.autorequire
+
+ @specification.executables.each do |executable|
+ validate_shebang_line_in(executable)
+ end
+
+ @specification.files.select {|f| File.symlink?(f) }.each do |file|
+ warning "#{file} is a symlink, which is not supported on all platforms"
+ end
+ end
+
+ def validate_attribute_present(attribute)
+ value = @specification.send attribute
+ warning("no #{attribute} specified") if value.nil? || value.empty?
+ end
+
+ def validate_shebang_line_in(executable)
+ executable_path = File.join(@specification.bindir, executable)
+ return if File.read(executable_path, 2) == '#!'
+
+ warning "#{executable_path} is missing #! line"
+ end
+
+ def validate_removed_attributes # :nodoc:
+ @specification.removed_method_calls.each do |attr|
+ warning("#{attr} is deprecated and ignored. Please remove this from your gemspec to ensure that your gem continues to build in the future.")
+ end
+ end
+
+ def validate_extensions # :nodoc:
+ require_relative 'ext'
+ builder = Gem::Ext::Builder.new(@specification)
+
+ rake_extension = @specification.extensions.any? {|s| builder.builder_for(s) == Gem::Ext::RakeBuilder }
+ rake_dependency = @specification.dependencies.any? {|d| d.name == 'rake' }
+
+ warning <<-WARNING if rake_extension && !rake_dependency
+You have specified rake based extension, but rake is not added as dependency. It is recommended to add rake as a dependency in gemspec since there's no guarantee rake will be already installed.
+ WARNING
+ end
+
+ def warning(statement) # :nodoc:
+ @warnings += 1
+
+ alert_warning statement
+ end
+
+ def error(statement) # :nodoc:
+ raise Gem::InvalidSpecificationException, statement
+ ensure
+ alert_warning help_text
+ end
+
+ def help_text # :nodoc:
+ "See https://guides.rubygems.org/specification-reference/ for help"
+ end
+end
diff --git a/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem b/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem
deleted file mode 100644
index f4ce4ca43d..0000000000
--- a/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
-MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
-aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
-jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
-xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
-1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
-snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
-U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
-9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
-AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
-yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
-38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
-AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
-DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
-HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
------END CERTIFICATE-----
diff --git a/lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem b/lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem
deleted file mode 100644
index 9e6810ab70..0000000000
--- a/lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----
diff --git a/lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem b/lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem
deleted file mode 100644
index 20585f1c01..0000000000
--- a/lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem
+++ /dev/null
@@ -1,25 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
diff --git a/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem b/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem
index f4ce4ca43d..f4ce4ca43d 100644
--- a/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem
+++ b/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem
diff --git a/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem b/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem
new file mode 100644
index 0000000000..8afb219058
--- /dev/null
+++ b/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
diff --git a/lib/rubygems/stub_specification.rb b/lib/rubygems/stub_specification.rb
index 8337375ab4..4246f9de86 100644
--- a/lib/rubygems/stub_specification.rb
+++ b/lib/rubygems/stub_specification.rb
@@ -6,14 +6,10 @@
class Gem::StubSpecification < Gem::BasicSpecification
# :nodoc:
- PREFIX = "# stub: "
+ PREFIX = "# stub: ".freeze
- OPEN_MODE = # :nodoc:
- if Object.const_defined? :Encoding then
- 'r:UTF-8:-'
- else
- 'r'
- end
+ # :nodoc:
+ OPEN_MODE = 'r:UTF-8:-'.freeze
class StubLine # :nodoc: all
attr_reader :name, :version, :platform, :require_paths, :extensions,
@@ -26,17 +22,17 @@ class Gem::StubSpecification < Gem::BasicSpecification
'lib' => 'lib'.freeze,
'test' => 'test'.freeze,
'ext' => 'ext'.freeze,
- }
+ }.freeze
# These are common require path lists. This hash is used to optimize
# and consolidate require_path objects. Most specs just specify "lib"
# in their require paths, so lets take advantage of that by pre-allocating
# a require path list for that case.
REQUIRE_PATH_LIST = { # :nodoc:
- 'lib' => ['lib'].freeze
- }
+ 'lib' => ['lib'].freeze,
+ }.freeze
- def initialize data, extensions
+ def initialize(data, extensions)
parts = data[PREFIX.length..-1].split(" ".freeze, 4)
@name = parts[0].freeze
@version = if Gem::Version.correct?(parts[1])
@@ -54,25 +50,25 @@ class Gem::StubSpecification < Gem::BasicSpecification
end
path_list = parts.last
- @require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0".freeze).map! { |x|
+ @require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0".freeze).map! do |x|
REQUIRE_PATHS[x] || x
- }
+ end
end
end
- def self.default_gemspec_stub filename, base_dir, gems_dir
+ def self.default_gemspec_stub(filename, base_dir, gems_dir)
new filename, base_dir, gems_dir, true
end
- def self.gemspec_stub filename, base_dir, gems_dir
+ def self.gemspec_stub(filename, base_dir, gems_dir)
new filename, base_dir, gems_dir, false
end
attr_reader :base_dir, :gems_dir
- def initialize filename, base_dir, gems_dir, default_gem
+ def initialize(filename, base_dir, gems_dir, default_gem)
super()
- filename.untaint
+ filename.tap(&Gem::UNTAINT)
self.loaded_from = filename
@data = nil
@@ -113,11 +109,12 @@ class Gem::StubSpecification < Gem::BasicSpecification
unless @data
begin
saved_lineno = $.
- open loaded_from, OPEN_MODE do |file|
+
+ File.open loaded_from, OPEN_MODE do |file|
begin
file.readline # discard encoding line
stubline = file.readline.chomp
- if stubline.start_with?(PREFIX) then
+ if stubline.start_with?(PREFIX)
extensions = if /\A#{PREFIX}/ =~ file.readline.chomp
$'.split "\0"
else
@@ -187,7 +184,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
# The full Gem::Specification for this gem, loaded from evalling its gemspec
def to_spec
- @spec ||= if @data then
+ @spec ||= if @data
loaded = Gem.loaded_specs[name]
loaded if loaded && loaded.version == version
end
@@ -212,5 +209,4 @@ class Gem::StubSpecification < Gem::BasicSpecification
def stubbed?
data.is_a? StubLine
end
-
end
diff --git a/lib/rubygems/syck_hack.rb b/lib/rubygems/syck_hack.rb
deleted file mode 100644
index 051483eac8..0000000000
--- a/lib/rubygems/syck_hack.rb
+++ /dev/null
@@ -1,77 +0,0 @@
-# frozen_string_literal: true
-# :stopdoc:
-
-# Hack to handle syck's DefaultKey bug
-#
-# This file is always loaded AFTER either syck or psych are already
-# loaded. It then looks at what constants are available and creates
-# a consistent view on all rubys.
-#
-# All this is so that there is always a YAML::Syck::DefaultKey
-# class no matter if the full yaml library has loaded or not.
-#
-
-module YAML # :nodoc:
- # In newer 1.9.2, there is a Syck toplevel constant instead of it
- # being underneath YAML. If so, reference it back under YAML as
- # well.
- if defined? ::Syck
- # for tests that change YAML::ENGINE
- # 1.8 does not support the second argument to const_defined?
- remove_const :Syck rescue nil
-
- Syck = ::Syck
-
- # JRuby's "Syck" is called "Yecht"
- elsif defined? YAML::Yecht
- Syck = YAML::Yecht
-
- # Otherwise, if there is no YAML::Syck, then we've got just psych
- # loaded, so lets define a stub for DefaultKey.
- elsif !defined? YAML::Syck
- module Syck
- class DefaultKey # :nodoc:
- end
- end
- end
-
- # Now that we've got something that is always here, define #to_s
- # so when code tries to use this, it at least just shows up like it
- # should.
- module Syck
- class DefaultKey
- remove_method :to_s rescue nil
-
- def to_s
- '='
- end
- end
- end
-
- SyntaxError = Error unless defined? SyntaxError
-end
-
-# Sometime in the 1.9 dev cycle, the Syck constant was moved from under YAML
-# to be a toplevel constant. So gemspecs created under these versions of Syck
-# will have references to Syck::DefaultKey.
-#
-# So we need to be sure that we reference Syck at the toplevel too so that
-# we can always load these kind of gemspecs.
-#
-if !defined?(Syck)
- Syck = YAML::Syck
-end
-
-# Now that we've got Syck setup in all the right places, store
-# a reference to the DefaultKey class inside Gem. We do this so that
-# if later on YAML, etc are redefined, we've still got a consistent
-# place to find the DefaultKey class for comparison.
-
-module Gem
- # for tests that change YAML::ENGINE
- remove_const :SyckDefaultKey if const_defined? :SyckDefaultKey
-
- SyckDefaultKey = YAML::Syck::DefaultKey
-end
-
-# :startdoc:
diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb
deleted file mode 100644
index efc78edea2..0000000000
--- a/lib/rubygems/test_case.rb
+++ /dev/null
@@ -1,1529 +0,0 @@
-# frozen_string_literal: true
-# TODO: $SAFE = 1
-
-begin
- gem 'minitest', '~> 4.0'
-rescue NoMethodError, Gem::LoadError
- # for ruby tests
-end
-
-if defined? Gem::QuickLoader
- Gem::QuickLoader.load_full_rubygems_library
-else
- require 'rubygems'
-end
-
-begin
- gem 'minitest'
-rescue Gem::LoadError
-end
-
-# We have to load these up front because otherwise we'll try to load
-# them while we're testing rubygems, and thus we can't actually load them.
-unless Gem::Dependency.new('rdoc', '>= 3.10').matching_specs.empty?
- gem 'rdoc'
- gem 'json'
-end
-
-require 'bundler'
-require 'minitest/autorun'
-
-require 'rubygems/deprecate'
-
-require 'fileutils'
-require 'pathname'
-require 'pp'
-require 'rubygems/package'
-require 'shellwords'
-require 'tmpdir'
-require 'uri'
-require 'zlib'
-require 'benchmark' # stdlib
-require 'rubygems/mock_gem_ui'
-
-module Gem
-
- ##
- # Allows setting the gem path searcher. This method is available when
- # requiring 'rubygems/test_case'
-
- def self.searcher=(searcher)
- @searcher = searcher
- end
-
- ##
- # Allows toggling Windows behavior. This method is available when requiring
- # 'rubygems/test_case'
-
- def self.win_platform=(val)
- @@win_platform = val
- end
-
- ##
- # Allows setting path to Ruby. This method is available when requiring
- # 'rubygems/test_case'
-
- def self.ruby= ruby
- @ruby = ruby
- end
-
- ##
- # When rubygems/test_case is required the default user interaction is a
- # MockGemUi.
-
- module DefaultUserInteraction
- @ui = Gem::MockGemUi.new
- end
-end
-
-##
-# RubyGemTestCase provides a variety of methods for testing rubygems and
-# gem-related behavior in a sandbox. Through RubyGemTestCase you can install
-# and uninstall gems, fetch remote gems through a stub fetcher and be assured
-# your normal set of gems is not affected.
-#
-# Tests are always run at a safe level of 1.
-
-class Gem::TestCase < MiniTest::Unit::TestCase
-
- attr_accessor :fetcher # :nodoc:
-
- attr_accessor :gem_repo # :nodoc:
-
- attr_accessor :uri # :nodoc:
-
- def assert_activate expected, *specs
- specs.each do |spec|
- case spec
- when String then
- Gem::Specification.find_by_name(spec).activate
- when Gem::Specification then
- spec.activate
- else
- flunk spec.inspect
- end
- end
-
- loaded = Gem.loaded_specs.values.map(&:full_name)
-
- assert_equal expected.sort, loaded.sort if expected
- end
-
- # TODO: move to minitest
- def assert_path_exists path, msg = nil
- msg = message(msg) { "Expected path '#{path}' to exist" }
- assert File.exist?(path), msg
- end
-
- ##
- # Sets the ENABLE_SHARED entry in RbConfig::CONFIG to +value+ and restores
- # the original value when the block ends
-
- def enable_shared value
- enable_shared = RbConfig::CONFIG['ENABLE_SHARED']
- RbConfig::CONFIG['ENABLE_SHARED'] = value
-
- yield
- ensure
- if enable_shared then
- RbConfig::CONFIG['enable_shared'] = enable_shared
- else
- RbConfig::CONFIG.delete 'enable_shared'
- end
- end
-
- # TODO: move to minitest
- def refute_path_exists path, msg = nil
- msg = message(msg) { "Expected path '#{path}' to not exist" }
- refute File.exist?(path), msg
- end
-
- def scan_make_command_lines(output)
- output.scan(/^#{Regexp.escape make_command}(?:[[:blank:]].*)?$/)
- end
-
- def parse_make_command_line(line)
- command, *args = line.shellsplit
-
- targets = []
- macros = {}
-
- args.each do |arg|
- case arg
- when /\A(\w+)=/
- macros[$1] = $'
- else
- targets << arg
- end
- end
-
- targets << '' if targets.empty?
-
- {
- :command => command,
- :targets => targets,
- :macros => macros,
- }
- end
-
- def assert_contains_make_command(target, output, msg = nil)
- if output.match(/\n/)
- msg = message(msg) {
- 'Expected output containing make command "%s": %s' % [
- ('%s %s' % [make_command, target]).rstrip,
- output.inspect
- ]
- }
- else
- msg = message(msg) {
- 'Expected make command "%s": %s' % [
- ('%s %s' % [make_command, target]).rstrip,
- output.inspect
- ]
- }
- end
-
- assert scan_make_command_lines(output).any? { |line|
- make = parse_make_command_line(line)
-
- if make[:targets].include?(target)
- yield make, line if block_given?
- true
- else
- false
- end
- }, msg
- end
-
- include Gem::DefaultUserInteraction
-
- undef_method :default_test if instance_methods.include? 'default_test' or
- instance_methods.include? :default_test
-
- @@project_dir = Dir.pwd.untaint unless defined?(@@project_dir)
-
- @@initial_reset = false
-
- ##
- # #setup prepares a sandboxed location to install gems. All installs are
- # directed to a temporary directory. All install plugins are removed.
- #
- # If the +RUBY+ environment variable is set the given path is used for
- # Gem::ruby. The local platform is set to <tt>i386-mswin32</tt> for Windows
- # or <tt>i686-darwin8.10.1</tt> otherwise.
- #
- # If the +KEEP_FILES+ environment variable is set the files will not be
- # removed from <tt>/tmp/test_rubygems_#{$$}.#{Time.now.to_i}</tt>.
-
- def setup
- super
-
- @orig_gem_home = ENV['GEM_HOME']
- @orig_gem_path = ENV['GEM_PATH']
- @orig_gem_vendor = ENV['GEM_VENDOR']
- @orig_gem_spec_cache = ENV['GEM_SPEC_CACHE']
- @orig_rubygems_gemdeps = ENV['RUBYGEMS_GEMDEPS']
- @orig_bundle_gemfile = ENV['BUNDLE_GEMFILE']
- @orig_rubygems_host = ENV['RUBYGEMS_HOST']
- ENV.keys.find_all { |k| k.start_with?('GEM_REQUIREMENT_') }.each do |k|
- ENV.delete k
- end
- @orig_gem_env_requirements = ENV.to_hash
-
- ENV['GEM_VENDOR'] = nil
-
- @current_dir = Dir.pwd
- @fetcher = nil
-
- Bundler.ui = Bundler::UI::Silent.new
- @ui = Gem::MockGemUi.new
- # This needs to be a new instance since we call use_ui(@ui) when we want to
- # capture output
- Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new
-
- tmpdir = File.expand_path Dir.tmpdir
- tmpdir.untaint
-
- if ENV['KEEP_FILES'] then
- @tempdir = File.join(tmpdir, "test_rubygems_#{$$}.#{Time.now.to_i}")
- else
- @tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
- end
- @tempdir.untaint
-
- FileUtils.mkdir_p @tempdir
-
- # This makes the tempdir consistent on OS X.
- # File.expand_path Dir.tmpdir #=> "/var/..."
- # Dir.chdir Dir.tmpdir do File.expand_path '.' end #=> "/private/var/..."
- # TODO use File#realpath above instead of #expand_path once 1.8 support is
- # dropped.
- Dir.chdir @tempdir do
- @tempdir = File.expand_path '.'
- @tempdir.untaint
- end
-
- # This makes the tempdir consistent on Windows.
- # Dir.tmpdir may return short path name, but Dir[Dir.tmpdir] returns long
- # path name. https://bugs.ruby-lang.org/issues/10819
- # File.expand_path or File.realpath doesn't convert path name to long path
- # name. Only Dir[] (= Dir.glob) works.
- # Short and long path name is specific to Windows filesystem.
- if win_platform?
- @tempdir = Dir[@tempdir][0]
- @tempdir.untaint
- end
-
- @gemhome = File.join @tempdir, 'gemhome'
- @userhome = File.join @tempdir, 'userhome'
- ENV["GEM_SPEC_CACHE"] = File.join @tempdir, 'spec_cache'
-
- @orig_ruby = if ENV['RUBY'] then
- ruby = Gem.ruby
- Gem.ruby = ENV['RUBY']
- ruby
- end
-
- @git = ENV['GIT'] || 'git'
-
- Gem.ensure_gem_subdirectories @gemhome
-
- @orig_LOAD_PATH = $LOAD_PATH.dup
- $LOAD_PATH.map! { |s|
- (expand_path = File.expand_path(s)) == s ? s : expand_path.untaint
- }
-
- Dir.chdir @tempdir
-
- @orig_ENV_HOME = ENV['HOME']
- ENV['HOME'] = @userhome
- Gem.instance_variable_set :@user_home, nil
- Gem.instance_variable_set :@gemdeps, nil
- Gem.instance_variable_set :@env_requirements_by_name, nil
- Gem.send :remove_instance_variable, :@ruby_version if
- Gem.instance_variables.include? :@ruby_version
-
- FileUtils.mkdir_p @gemhome
- FileUtils.mkdir_p @userhome
-
- @orig_gem_private_key_passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
- ENV['GEM_PRIVATE_KEY_PASSPHRASE'] = PRIVATE_KEY_PASSPHRASE
-
- @default_dir = File.join @tempdir, 'default'
- @default_spec_dir = File.join @default_dir, "specifications", "default"
- Gem.instance_variable_set :@default_dir, @default_dir
- FileUtils.mkdir_p @default_spec_dir
-
- # We use Gem::Specification.reset the first time only so that if there
- # are unresolved deps that leak into the whole test suite, they're at least
- # reported once.
- if @@initial_reset
- Gem::Specification.unresolved_deps.clear # done to avoid cross-test warnings
- else
- @@initial_reset = true
- Gem::Specification.reset
- end
- Gem.use_paths(@gemhome)
-
- Gem::Security.reset
-
- Gem.loaded_specs.clear
- Gem.clear_default_specs
- Gem::Specification.unresolved_deps.clear
- Bundler.reset!
-
- Gem.configuration.verbose = true
- Gem.configuration.update_sources = true
-
- Gem::RemoteFetcher.fetcher = Gem::FakeFetcher.new
-
- @gem_repo = "http://gems.example.com/"
- @uri = URI.parse @gem_repo
- Gem.sources.replace [@gem_repo]
-
- Gem.searcher = nil
- Gem::SpecFetcher.fetcher = nil
- @orig_BASERUBY = RbConfig::CONFIG['BASERUBY']
- RbConfig::CONFIG['BASERUBY'] = RbConfig::CONFIG['ruby_install_name']
-
- @orig_arch = RbConfig::CONFIG['arch']
-
- if win_platform?
- util_set_arch 'i386-mswin32'
- else
- util_set_arch 'i686-darwin8.10.1'
- end
-
- @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
- @orig_LOADED_FEATURES = $LOADED_FEATURES.dup
- end
-
- ##
- # #teardown restores the process to its original state and removes the
- # tempdir unless the +KEEP_FILES+ environment variable was set.
-
- def teardown
- $LOAD_PATH.replace @orig_LOAD_PATH if @orig_LOAD_PATH
- if @orig_LOADED_FEATURES
- if @orig_LOAD_PATH
- paths = @orig_LOAD_PATH.map {|path| File.join(File.expand_path(path), "/")}
- ($LOADED_FEATURES - @orig_LOADED_FEATURES).each do |feat|
- unless paths.any? {|path| feat.start_with?(path)}
- $LOADED_FEATURES.delete(feat)
- end
- end
- else
- $LOADED_FEATURES.replace @orig_LOADED_FEATURES
- end
- end
-
- if @orig_BASERUBY
- RbConfig::CONFIG['BASERUBY'] = @orig_BASERUBY
- else
- RbConfig::CONFIG.delete('BASERUBY')
- end
- RbConfig::CONFIG['arch'] = @orig_arch
-
- if defined? Gem::RemoteFetcher then
- Gem::RemoteFetcher.fetcher = nil
- end
-
- Dir.chdir @current_dir
-
- FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES']
-
- ENV.clear
- @orig_gem_env_requirements.each do |k,v|
- ENV[k] = v
- end
-
- ENV['GEM_HOME'] = @orig_gem_home
- ENV['GEM_PATH'] = @orig_gem_path
- ENV['GEM_VENDOR'] = @orig_gem_vendor
- ENV['GEM_SPEC_CACHE'] = @orig_gem_spec_cache
- ENV['RUBYGEMS_GEMDEPS'] = @orig_rubygems_gemdeps
- ENV['BUNDLE_GEMFILE'] = @orig_bundle_gemfile
- ENV['RUBYGEMS_HOST'] = @orig_rubygems_host
-
- Gem.ruby = @orig_ruby if @orig_ruby
-
- if @orig_ENV_HOME then
- ENV['HOME'] = @orig_ENV_HOME
- else
- ENV.delete 'HOME'
- end
-
- Gem.instance_variable_set :@default_dir, nil
-
- ENV['GEM_PRIVATE_KEY_PASSPHRASE'] = @orig_gem_private_key_passphrase
-
- Gem::Specification._clear_load_cache
- Gem::Specification.unresolved_deps.clear
- Gem::refresh
- end
-
- def common_installer_setup
- common_installer_teardown
-
- Gem.post_build do |installer|
- @post_build_hook_arg = installer
- true
- end
-
- Gem.post_install do |installer|
- @post_install_hook_arg = installer
- end
-
- Gem.post_uninstall do |uninstaller|
- @post_uninstall_hook_arg = uninstaller
- end
-
- Gem.pre_install do |installer|
- @pre_install_hook_arg = installer
- true
- end
-
- Gem.pre_uninstall do |uninstaller|
- @pre_uninstall_hook_arg = uninstaller
- end
- end
-
- def common_installer_teardown
- Gem.post_build_hooks.clear
- Gem.post_install_hooks.clear
- Gem.done_installing_hooks.clear
- Gem.post_reset_hooks.clear
- Gem.post_uninstall_hooks.clear
- Gem.pre_install_hooks.clear
- Gem.pre_reset_hooks.clear
- Gem.pre_uninstall_hooks.clear
- end
-
- ##
- # A git_gem is used with a gem dependencies file. The gem created here
- # has no files, just a gem specification for the given +name+ and +version+.
- #
- # Yields the +specification+ to the block, if given
-
- def git_gem name = 'a', version = 1
- have_git?
-
- directory = File.join 'git', name
- directory = File.expand_path directory
-
- git_spec = Gem::Specification.new name, version do |specification|
- yield specification if block_given?
- end
-
- FileUtils.mkdir_p directory
-
- gemspec = "#{name}.gemspec"
-
- open File.join(directory, gemspec), 'w' do |io|
- io.write git_spec.to_ruby
- end
-
- head = nil
-
- Dir.chdir directory do
- unless File.exist? '.git' then
- system @git, 'init', '--quiet'
- system @git, 'config', 'user.name', 'RubyGems Tests'
- system @git, 'config', 'user.email', 'rubygems@example'
- end
-
- system @git, 'add', gemspec
- system @git, 'commit', '-a', '-m', 'a non-empty commit message', '--quiet'
- head = Gem::Util.popen(@git, 'rev-parse', 'master').strip
- end
-
- return name, git_spec.version, directory, head
- end
-
- ##
- # Skips this test unless you have a git executable
-
- def have_git?
- return if in_path? @git
-
- skip 'cannot find git executable, use GIT environment variable to set'
- end
-
- def in_path? executable # :nodoc:
- return true if %r%\A([A-Z]:|/)% =~ executable and File.exist? executable
-
- ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory|
- File.exist? File.join directory, executable
- end
- end
-
- ##
- # Builds and installs the Gem::Specification +spec+
-
- def install_gem spec, options = {}
- require 'rubygems/installer'
-
- gem = File.join @tempdir, "gems", "#{spec.full_name}.gem"
-
- unless File.exist? gem then
- use_ui Gem::MockGemUi.new do
- Dir.chdir @tempdir do
- Gem::Package.build spec
- end
- end
-
- gem = File.join(@tempdir, File.basename(spec.cache_file)).untaint
- end
-
- Gem::Installer.at(gem, options.merge({:wrappers => true})).install
- end
-
- ##
- # Builds and installs the Gem::Specification +spec+ into the user dir
-
- def install_gem_user spec
- install_gem spec, :user_install => true
- end
-
- ##
- # Uninstalls the Gem::Specification +spec+
- def uninstall_gem spec
- require 'rubygems/uninstaller'
-
- Class.new(Gem::Uninstaller) {
- def ask_if_ok spec
- true
- end
- }.new(spec.name, :executables => true, :user_install => true).uninstall
- end
-
- ##
- # creates a temporary directory with hax
- # TODO: deprecate and remove
-
- def create_tmpdir
- tmpdir = nil
- Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
- tmpdir = File.join tmpdir, "test_rubygems_#{$$}"
- FileUtils.mkdir_p tmpdir
- return tmpdir
- end
-
- ##
- # Enables pretty-print for all tests
-
- def mu_pp(obj)
- s = String.new
- s = PP.pp obj, s
- s = s.force_encoding(Encoding.default_external) if defined? Encoding
- s.chomp
- end
-
- ##
- # Reads a Marshal file at +path+
-
- def read_cache(path)
- open path.dup.untaint, 'rb' do |io|
- Marshal.load io.read
- end
- end
-
- ##
- # Reads a binary file at +path+
-
- def read_binary(path)
- Gem.read_binary path
- end
-
- ##
- # Writes a binary file to +path+ which is relative to +@gemhome+
-
- def write_file(path)
- path = File.join @gemhome, path unless Pathname.new(path).absolute?
- dir = File.dirname path
- FileUtils.mkdir_p dir unless File.directory? dir
-
- open path, 'wb' do |io|
- yield io if block_given?
- end
-
- path
- end
-
- def all_spec_names
- Gem::Specification.map(&:full_name)
- end
-
- ##
- # Creates a Gem::Specification with a minimum of extra work. +name+ and
- # +version+ are the gem's name and version, platform, author, email,
- # homepage, summary and description are defaulted. The specification is
- # yielded for customization.
- #
- # The gem is added to the installed gems in +@gemhome+ and the runtime.
- #
- # Use this with #write_file to build an installed gem.
-
- def quick_gem(name, version='2')
- require 'rubygems/specification'
-
- spec = Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = name
- s.version = version
- s.author = 'A User'
- s.email = 'example@example.com'
- s.homepage = 'http://example.com'
- s.summary = "this is a summary"
- s.description = "This is a test description"
-
- yield(s) if block_given?
- end
-
- Gem::Specification.map # HACK: force specs to (re-)load before we write
-
- written_path = write_file spec.spec_file do |io|
- io.write spec.to_ruby_for_cache
- end
-
- spec.loaded_from = spec.loaded_from = written_path
-
- Gem::Specification.reset
-
- return spec
- end
-
- ##
- # TODO: remove in RubyGems 3.0
-
- def quick_spec name, version = '2' # :nodoc:
- util_spec name, version
- end
-
- ##
- # Builds a gem from +spec+ and places it in <tt>File.join @gemhome,
- # 'cache'</tt>. Automatically creates files based on +spec.files+
-
- def util_build_gem(spec)
- dir = spec.gem_dir
- FileUtils.mkdir_p dir
-
- Dir.chdir dir do
- spec.files.each do |file|
- next if File.exist? file
- FileUtils.mkdir_p File.dirname(file)
- File.open file, 'w' do |fp| fp.puts "# #{file}" end
- end
-
- use_ui Gem::MockGemUi.new do
- Gem::Package.build spec
- end
-
- cache = spec.cache_file
- FileUtils.mv File.basename(cache), cache
- end
- end
-
- def util_remove_gem(spec)
- FileUtils.rm_rf spec.cache_file
- FileUtils.rm_rf spec.spec_file
- end
-
- ##
- # Removes all installed gems from +@gemhome+.
-
- def util_clear_gems
- FileUtils.rm_rf File.join(@gemhome, "gems") # TODO: use Gem::Dirs
- FileUtils.mkdir File.join(@gemhome, "gems")
- FileUtils.rm_rf File.join(@gemhome, "specifications")
- FileUtils.mkdir File.join(@gemhome, "specifications")
- Gem::Specification.reset
- end
-
- ##
- # Install the provided specs
-
- def install_specs(*specs)
- specs.each do |spec|
- Gem::Installer.for_spec(spec).install
- end
-
- Gem.searcher = nil
- end
-
- ##
- # Installs the provided default specs including writing the spec file
-
- def install_default_gems(*specs)
- install_default_specs(*specs)
-
- specs.each do |spec|
- open spec.loaded_from, 'w' do |io|
- io.write spec.to_ruby_for_cache
- end
- end
- end
-
- ##
- # Install the provided default specs
-
- def install_default_specs(*specs)
- specs.each do |spec|
- installer = Gem::Installer.for_spec(spec, :install_as_default => true)
- installer.install
- Gem.register_default_spec(spec)
- end
- end
-
- def loaded_spec_names
- Gem.loaded_specs.values.map(&:full_name).sort
- end
-
- def unresolved_names
- Gem::Specification.unresolved_deps.values.map(&:to_s).sort
- end
-
- def save_loaded_features
- old_loaded_features = $LOADED_FEATURES.dup
- yield
- ensure
- $LOADED_FEATURES.replace old_loaded_features
- end
-
- ##
- # new_spec is deprecated as it is never used.
- #
- # TODO: remove in RubyGems 3.0
-
- def new_spec name, version, deps = nil, *files # :nodoc:
- require 'rubygems/specification'
-
- spec = Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = name
- s.version = version
- s.author = 'A User'
- s.email = 'example@example.com'
- s.homepage = 'http://example.com'
- s.summary = "this is a summary"
- s.description = "This is a test description"
-
- Array(deps).each do |n, req|
- s.add_dependency n, (req || '>= 0')
- end
-
- s.files.push(*files) unless files.empty?
-
- yield s if block_given?
- end
-
- spec.loaded_from = spec.spec_file
-
- unless files.empty? then
- write_file spec.spec_file do |io|
- io.write spec.to_ruby_for_cache
- end
-
- util_build_gem spec
-
- cache_file = File.join @tempdir, 'gems', "#{spec.full_name}.gem"
- FileUtils.mkdir_p File.dirname cache_file
- FileUtils.mv spec.cache_file, cache_file
- FileUtils.rm spec.spec_file
- end
-
- spec
- end
-
- def new_default_spec(name, version, deps = nil, *files)
- spec = util_spec name, version, deps
-
- spec.loaded_from = File.join(@default_spec_dir, spec.spec_name)
- spec.files = files
-
- lib_dir = File.join(@tempdir, "default_gems", "lib")
- $LOAD_PATH.unshift(lib_dir)
- files.each do |file|
- rb_path = File.join(lib_dir, file)
- FileUtils.mkdir_p(File.dirname(rb_path))
- File.open(rb_path, "w") do |rb|
- rb << "# #{file}"
- end
- end
-
- spec
- end
-
- ##
- # Creates a spec with +name+, +version+. +deps+ can specify the dependency
- # or a +block+ can be given for full customization of the specification.
-
- def util_spec name, version = 2, deps = nil # :yields: specification
- raise "deps or block, not both" if deps and block_given?
-
- spec = Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = name
- s.version = version
- s.author = 'A User'
- s.email = 'example@example.com'
- s.homepage = 'http://example.com'
- s.summary = "this is a summary"
- s.description = "This is a test description"
-
- yield s if block_given?
- end
-
- if deps then
- # Since Hash#each is unordered in 1.8, sort the keys and iterate that
- # way so the tests are deterministic on all implementations.
- deps.keys.sort.each do |n|
- spec.add_dependency n, (deps[n] || '>= 0')
- end
- end
-
- Gem::Specification.reset
-
- return spec
- end
-
- ##
- # Creates a gem with +name+, +version+ and +deps+. The specification will
- # be yielded before gem creation for customization. The gem will be placed
- # in <tt>File.join @tempdir, 'gems'</tt>. The specification and .gem file
- # location are returned.
-
- def util_gem(name, version, deps = nil, &block)
- # TODO: deprecate
- raise "deps or block, not both" if deps and block
-
- if deps then
- block = proc do |s|
- # Since Hash#each is unordered in 1.8, sort
- # the keys and iterate that way so the tests are
- # deterministic on all implementations.
- deps.keys.sort.each do |n|
- s.add_dependency n, (deps[n] || '>= 0')
- end
- end
- end
-
- spec = quick_gem(name, version, &block)
-
- util_build_gem spec
-
- cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
- FileUtils.mkdir_p File.dirname cache_file
- FileUtils.mv spec.cache_file, cache_file
- FileUtils.rm spec.spec_file
-
- spec.loaded_from = nil
-
- [spec, cache_file]
- end
-
- ##
- # Gzips +data+.
-
- def util_gzip(data)
- out = StringIO.new
-
- Zlib::GzipWriter.wrap out do |io|
- io.write data
- end
-
- out.string
- end
-
- ##
- # Creates several default gems which all have a lib/code.rb file. The gems
- # are not installed but are available in the cache dir.
- #
- # +@a1+:: gem a version 1, this is the best-described gem.
- # +@a2+:: gem a version 2
- # +@a3a:: gem a version 3.a
- # +@a_evil9+:: gem a_evil version 9, use this to ensure similarly-named gems
- # don't collide with a.
- # +@b2+:: gem b version 2
- # +@c1_2+:: gem c version 1.2
- # +@pl1+:: gem pl version 1, this gem has a legacy platform of i386-linux.
- #
- # Additional +prerelease+ gems may also be created:
- #
- # +@a2_pre+:: gem a version 2.a
- # TODO: nuke this and fix tests. this should speed up a lot
-
- def util_make_gems(prerelease = false)
- @a1 = quick_gem 'a', '1' do |s|
- s.files = %w[lib/code.rb]
- s.require_paths = %w[lib]
- s.date = Gem::Specification::TODAY - 86400
- s.homepage = 'http://a.example.com'
- s.email = %w[example@example.com example2@example.com]
- s.authors = %w[Example Example2]
- s.description = <<-DESC
-This line is really, really long. So long, in fact, that it is more than eighty characters long! The purpose of this line is for testing wrapping behavior because sometimes people don't wrap their text to eighty characters. Without the wrapping, the text might not look good in the RSS feed.
-
-Also, a list:
- * An entry that\'s actually kind of sort
- * an entry that\'s really long, which will probably get wrapped funny. That's ok, somebody wasn't thinking straight when they made it more than eighty characters.
- DESC
- end
-
- init = proc do |s|
- s.files = %w[lib/code.rb]
- s.require_paths = %w[lib]
- end
-
- @a2 = quick_gem('a', '2', &init)
- @a3a = quick_gem('a', '3.a', &init)
- @a_evil9 = quick_gem('a_evil', '9', &init)
- @b2 = quick_gem('b', '2', &init)
- @c1_2 = quick_gem('c', '1.2', &init)
- @x = quick_gem('x', '1', &init)
- @dep_x = quick_gem('dep_x', '1') do |s|
- s.files = %w[lib/code.rb]
- s.require_paths = %w[lib]
- s.add_dependency 'x', '>= 1'
- end
-
- @pl1 = quick_gem 'pl', '1' do |s| # l for legacy
- s.files = %w[lib/code.rb]
- s.require_paths = %w[lib]
- s.platform = Gem::Platform.new 'i386-linux'
- s.instance_variable_set :@original_platform, 'i386-linux'
- end
-
- if prerelease
- @a2_pre = quick_gem('a', '2.a', &init)
- write_file File.join(*%W[gems #{@a2_pre.original_name} lib code.rb])
- util_build_gem @a2_pre
- end
-
- write_file File.join(*%W[gems #{@a1.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@a2.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@a3a.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@a_evil9.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@b2.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@x.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@dep_x.original_name} lib code.rb])
-
- [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1, @x, @dep_x].each do |spec|
- util_build_gem spec
- end
-
- FileUtils.rm_r File.join(@gemhome, "gems", @pl1.original_name)
- end
-
- ##
- # Set the platform to +arch+
-
- def util_set_arch(arch)
- RbConfig::CONFIG['arch'] = arch
- platform = Gem::Platform.new arch
-
- Gem.instance_variable_set :@platforms, nil
- Gem::Platform.instance_variable_set :@local, nil
-
- platform
- end
-
- ##
- # Sets up a fake fetcher using the gems from #util_make_gems. Optionally
- # additional +prerelease+ gems may be included.
- #
- # Gems created by this method may be fetched using Gem::RemoteFetcher.
-
- def util_setup_fake_fetcher(prerelease = false)
- require 'zlib'
- require 'socket'
- require 'rubygems/remote_fetcher'
-
- @fetcher = Gem::FakeFetcher.new
-
- util_make_gems(prerelease)
- Gem::Specification.reset
-
- @all_gems = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2].sort
- @all_gem_names = @all_gems.map { |gem| gem.full_name }
-
- gem_names = [@a1.full_name, @a2.full_name, @a3a.full_name, @b2.full_name]
- @gem_names = gem_names.sort.join("\n")
-
- Gem::RemoteFetcher.fetcher = @fetcher
- end
-
- ##
- # Add +spec+ to +@fetcher+ serving the data in the file +path+.
- # +repo+ indicates which repo to make +spec+ appear to be in.
-
- def add_to_fetcher(spec, path=nil, repo=@gem_repo)
- path ||= spec.cache_file
- @fetcher.data["#{@gem_repo}gems/#{spec.file_name}"] = read_binary(path)
- end
-
- ##
- # Sets up Gem::SpecFetcher to return information from the gems in +specs+.
- # Best used with +@all_gems+ from #util_setup_fake_fetcher.
-
- def util_setup_spec_fetcher(*specs)
- all_specs = Gem::Specification.to_a + specs
- Gem::Specification._resort! all_specs
-
- spec_fetcher = Gem::SpecFetcher.fetcher
-
- prerelease, all = all_specs.partition { |spec| spec.version.prerelease? }
- latest = Gem::Specification._latest_specs all_specs
-
- spec_fetcher.specs[@uri] = []
- all.each do |spec|
- spec_fetcher.specs[@uri] << spec.name_tuple
- end
-
- spec_fetcher.latest_specs[@uri] = []
- latest.each do |spec|
- spec_fetcher.latest_specs[@uri] << spec.name_tuple
- end
-
- spec_fetcher.prerelease_specs[@uri] = []
- prerelease.each do |spec|
- spec_fetcher.prerelease_specs[@uri] << spec.name_tuple
- end
-
- # HACK for test_download_to_cache
- unless Gem::RemoteFetcher === @fetcher then
- v = Gem.marshal_version
-
- specs = all.map { |spec| spec.name_tuple }
- s_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic specs
-
- latest_specs = latest.map do |spec|
- spec.name_tuple
- end
-
- l_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic latest_specs
-
- prerelease_specs = prerelease.map { |spec| spec.name_tuple }
- p_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic prerelease_specs
-
- @fetcher.data["#{@gem_repo}specs.#{v}.gz"] = s_zip
- @fetcher.data["#{@gem_repo}latest_specs.#{v}.gz"] = l_zip
- @fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip
-
- v = Gem.marshal_version
-
- all_specs.each do |spec|
- path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
- data = Marshal.dump spec
- data_deflate = Zlib::Deflate.deflate data
- @fetcher.data[path] = data_deflate
- end
- end
-
- nil # force errors
- end
-
- ##
- # Deflates +data+
-
- def util_zip(data)
- Zlib::Deflate.deflate data
- end
-
- def util_set_RUBY_VERSION(version, patchlevel = nil, revision = nil)
- if Gem.instance_variables.include? :@ruby_version or
- Gem.instance_variables.include? '@ruby_version' then
- Gem.send :remove_instance_variable, :@ruby_version
- end
-
- @RUBY_VERSION = RUBY_VERSION
- @RUBY_PATCHLEVEL = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
- @RUBY_REVISION = RUBY_REVISION if defined?(RUBY_REVISION)
-
- Object.send :remove_const, :RUBY_VERSION
- Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
- Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
-
- Object.const_set :RUBY_VERSION, version
- Object.const_set :RUBY_PATCHLEVEL, patchlevel if patchlevel
- Object.const_set :RUBY_REVISION, revision if revision
- end
-
- def util_restore_RUBY_VERSION
- Object.send :remove_const, :RUBY_VERSION
- Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
- Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
-
- Object.const_set :RUBY_VERSION, @RUBY_VERSION
- Object.const_set :RUBY_PATCHLEVEL, @RUBY_PATCHLEVEL if
- defined?(@RUBY_PATCHLEVEL)
- Object.const_set :RUBY_REVISION, @RUBY_REVISION if
- defined?(@RUBY_REVISION)
- end
-
- ##
- # Is this test being run on a Windows platform?
-
- def self.win_platform?
- Gem.win_platform?
- end
-
- ##
- # Is this test being run on a Windows platform?
-
- def win_platform?
- Gem.win_platform?
- end
-
- ##
- # Returns whether or not we're on a version of Ruby built with VC++ (or
- # Borland) versus Cygwin, Mingw, etc.
-
- def self.vc_windows?
- RUBY_PLATFORM.match('mswin')
- end
-
- ##
- # Returns whether or not we're on a version of Ruby built with VC++ (or
- # Borland) versus Cygwin, Mingw, etc.
-
- def vc_windows?
- RUBY_PLATFORM.match('mswin')
- end
-
- ##
- # Returns the make command for the current platform. For versions of Ruby
- # built on MS Windows with VC++ or Borland it will return 'nmake'. On all
- # other platforms, including Cygwin, it will return 'make'.
-
- def self.make_command
- ENV["make"] || ENV["MAKE"] || (vc_windows? ? 'nmake' : 'make')
- end
-
- ##
- # Returns the make command for the current platform. For versions of Ruby
- # built on MS Windows with VC++ or Borland it will return 'nmake'. On all
- # other platforms, including Cygwin, it will return 'make'.
-
- def make_command
- ENV["make"] || ENV["MAKE"] || (vc_windows? ? 'nmake' : 'make')
- end
-
- ##
- # Returns whether or not the nmake command could be found.
-
- def nmake_found?
- system('nmake /? 1>NUL 2>&1')
- end
-
- # In case we're building docs in a background process, this method waits for
- # that process to exit (or if it's already been reaped, or never happened,
- # swallows the Errno::ECHILD error).
- def wait_for_child_process_to_exit
- Process.wait if Process.respond_to?(:fork)
- rescue Errno::ECHILD
- end
-
- ##
- # Allows tests to use a random (but controlled) port number instead of
- # a hardcoded one. This helps CI tools when running parallels builds on
- # the same builder slave.
-
- def self.process_based_port
- @@process_based_port ||= 8000 + $$ % 1000
- end
-
- ##
- # See ::process_based_port
-
- def process_based_port
- self.class.process_based_port
- end
-
- ##
- # Allows the proper version of +rake+ to be used for the test.
-
- def build_rake_in(good=true)
- gem_ruby = Gem.ruby
- Gem.ruby = @@ruby
- env_rake = ENV["rake"]
- rake = (good ? @@good_rake : @@bad_rake)
- ENV["rake"] = rake
- yield rake
- ensure
- Gem.ruby = gem_ruby
- if env_rake
- ENV["rake"] = env_rake
- else
- ENV.delete("rake")
- end
- end
-
- ##
- # Finds the path to the Ruby executable
-
- def self.rubybin
- ruby = ENV["RUBY"]
- return ruby if ruby
- ruby = "ruby"
- rubyexe = "#{ruby}.exe"
-
- 3.times do
- if File.exist? ruby and File.executable? ruby and !File.directory? ruby
- return File.expand_path(ruby)
- end
- if File.exist? rubyexe and File.executable? rubyexe
- return File.expand_path(rubyexe)
- end
- ruby = File.join("..", ruby)
- end
-
- begin
- require "rbconfig"
- File.join(RbConfig::CONFIG["bindir"],
- RbConfig::CONFIG["ruby_install_name"] +
- RbConfig::CONFIG["EXEEXT"])
- rescue LoadError
- "ruby"
- end
- end
-
- @@ruby = rubybin
- @@good_rake = "#{rubybin} \"#{File.expand_path('../../../test/rubygems/good_rake.rb', __FILE__)}\""
- @@bad_rake = "#{rubybin} \"#{File.expand_path('../../../test/rubygems/bad_rake.rb', __FILE__)}\""
-
- ##
- # Construct a new Gem::Dependency.
-
- def dep name, *requirements
- Gem::Dependency.new name, *requirements
- end
-
- ##
- # Constructs a Gem::Resolver::DependencyRequest from a
- # Gem::Dependency +dep+, a +from_name+ and +from_version+ requesting the
- # dependency and a +parent+ DependencyRequest
-
- def dependency_request dep, from_name, from_version, parent = nil
- remote = Gem::Source.new @uri
-
- unless parent then
- parent_dep = dep from_name, from_version
- parent = Gem::Resolver::DependencyRequest.new parent_dep, nil
- end
-
- spec = Gem::Resolver::IndexSpecification.new \
- nil, from_name, from_version, remote, Gem::Platform::RUBY
- activation = Gem::Resolver::ActivationRequest.new spec, parent
-
- Gem::Resolver::DependencyRequest.new dep, activation
- end
-
- ##
- # Constructs a new Gem::Requirement.
-
- def req *requirements
- return requirements.first if Gem::Requirement === requirements.first
- Gem::Requirement.create requirements
- end
-
- ##
- # Constructs a new Gem::Specification.
-
- def spec name, version, &block
- Gem::Specification.new name, v(version), &block
- end
-
- ##
- # Creates a SpecFetcher pre-filled with the gems or specs defined in the
- # block.
- #
- # Yields a +fetcher+ object that responds to +spec+ and +gem+. +spec+ adds
- # a specification to the SpecFetcher while +gem+ adds both a specification
- # and the gem data to the RemoteFetcher so the built gem can be downloaded.
- #
- # If only the a-3 gem is supposed to be downloaded you can save setup
- # time by creating only specs for the other versions:
- #
- # spec_fetcher do |fetcher|
- # fetcher.spec 'a', 1
- # fetcher.spec 'a', 2, 'b' => 3 # dependency on b = 3
- # fetcher.gem 'a', 3 do |spec|
- # # spec is a Gem::Specification
- # # ...
- # end
- # end
-
- def spec_fetcher repository = @gem_repo
- Gem::TestCase::SpecFetcherSetup.declare self, repository do |spec_fetcher_setup|
- yield spec_fetcher_setup if block_given?
- end
- end
-
- ##
- # Construct a new Gem::Version.
-
- def v string
- Gem::Version.create string
- end
-
- ##
- # A vendor_gem is used with a gem dependencies file. The gem created here
- # has no files, just a gem specification for the given +name+ and +version+.
- #
- # Yields the +specification+ to the block, if given
-
- def vendor_gem name = 'a', version = 1
- directory = File.join 'vendor', name
-
- FileUtils.mkdir_p directory
-
- save_gemspec name, version, directory
- end
-
- ##
- # create_gemspec creates gem specification in given +directory+ or '.'
- # for the given +name+ and +version+.
- #
- # Yields the +specification+ to the block, if given
-
- def save_gemspec name = 'a', version = 1, directory = '.'
- vendor_spec = Gem::Specification.new name, version do |specification|
- yield specification if block_given?
- end
-
- open File.join(directory, "#{name}.gemspec"), 'w' do |io|
- io.write vendor_spec.to_ruby
- end
-
- return name, vendor_spec.version, directory
- end
-
- ##
- # The StaticSet is a static set of gem specifications used for testing only.
- # It is available by requiring Gem::TestCase.
-
- class StaticSet < Gem::Resolver::Set
-
- ##
- # A StaticSet ignores remote because it has a fixed set of gems.
-
- attr_accessor :remote
-
- ##
- # Creates a new StaticSet for the given +specs+
-
- def initialize(specs)
- super()
-
- @specs = specs
-
- @remote = true
- end
-
- ##
- # Adds +spec+ to this set.
-
- def add spec
- @specs << spec
- end
-
- ##
- # Finds +dep+ in this set.
-
- def find_spec(dep)
- @specs.reverse_each do |s|
- return s if dep.matches_spec? s
- end
- end
-
- ##
- # Finds all gems matching +dep+ in this set.
-
- def find_all(dep)
- @specs.find_all { |s| dep.match? s, @prerelease }
- end
-
- ##
- # Loads a Gem::Specification from this set which has the given +name+,
- # version +ver+, +platform+. The +source+ is ignored.
-
- def load_spec name, ver, platform, source
- dep = Gem::Dependency.new name, ver
- spec = find_spec dep
-
- Gem::Specification.new spec.name, spec.version do |s|
- s.platform = spec.platform
- end
- end
-
- def prefetch reqs # :nodoc:
- end
- end
-
- ##
- # Loads certificate named +cert_name+ from <tt>test/rubygems/</tt>.
-
- def self.load_cert cert_name
- cert_file = cert_path cert_name
-
- cert = File.read cert_file
-
- OpenSSL::X509::Certificate.new cert
- end
-
- ##
- # Returns the path to the certificate named +cert_name+ from
- # <tt>test/rubygems/</tt>.
-
- def self.cert_path cert_name
- if 32 == (Time.at(2**32) rescue 32) then
- cert_file =
- File.expand_path "../../../test/rubygems/#{cert_name}_cert_32.pem",
- __FILE__
-
- return cert_file if File.exist? cert_file
- end
-
- File.expand_path "../../../test/rubygems/#{cert_name}_cert.pem", __FILE__
- end
-
- ##
- # Loads an RSA private key named +key_name+ with +passphrase+ in <tt>test/rubygems/</tt>
-
- def self.load_key key_name, passphrase = nil
- key_file = key_path key_name
-
- key = File.read key_file
-
- OpenSSL::PKey::RSA.new key, passphrase
- end
-
- ##
- # Returns the path to the key named +key_name+ from <tt>test/rubygems</tt>
-
- def self.key_path key_name
- File.expand_path "../../../test/rubygems/#{key_name}_key.pem", __FILE__
- end
-
- # :stopdoc:
- # only available in RubyGems tests
-
- PRIVATE_KEY_PASSPHRASE = 'Foo bar'
-
- begin
- PRIVATE_KEY = load_key 'private'
- PRIVATE_KEY_PATH = key_path 'private'
-
- # ENCRYPTED_PRIVATE_KEY is PRIVATE_KEY encrypted with PRIVATE_KEY_PASSPHRASE
- ENCRYPTED_PRIVATE_KEY = load_key 'encrypted_private', PRIVATE_KEY_PASSPHRASE
- ENCRYPTED_PRIVATE_KEY_PATH = key_path 'encrypted_private'
-
- PUBLIC_KEY = PRIVATE_KEY.public_key
-
- PUBLIC_CERT = load_cert 'public'
- PUBLIC_CERT_PATH = cert_path 'public'
- rescue Errno::ENOENT
- PRIVATE_KEY = nil
- PUBLIC_KEY = nil
- PUBLIC_CERT = nil
- end if defined?(OpenSSL::SSL)
-
-end
-
-# require dependencies that are not discoverable once GEM_HOME and GEM_PATH
-# are wiped
-begin
- gem 'rake'
-rescue Gem::LoadError
-end
-
-begin
- require 'rake/packagetask'
-rescue LoadError
-end
-
-begin
- gem 'rdoc'
- require 'rdoc'
-
- require 'rubygems/rdoc'
-rescue LoadError, Gem::LoadError
-end
-
-begin
- gem 'builder'
- require 'builder/xchar'
-rescue LoadError, Gem::LoadError
-end
-
-require 'rubygems/test_utilities'
-tmpdirs = []
-tmpdirs << (ENV['GEM_HOME'] = Dir.mktmpdir("home"))
-tmpdirs << (ENV['GEM_PATH'] = Dir.mktmpdir("path"))
-pid = $$
-END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid}
-Gem.clear_paths
-Gem.loaded_specs.clear
diff --git a/lib/rubygems/test_utilities.rb b/lib/rubygems/test_utilities.rb
deleted file mode 100644
index 686916ea02..0000000000
--- a/lib/rubygems/test_utilities.rb
+++ /dev/null
@@ -1,384 +0,0 @@
-# frozen_string_literal: true
-require 'tempfile'
-require 'rubygems'
-require 'rubygems/remote_fetcher'
-
-##
-# A fake Gem::RemoteFetcher for use in tests or to avoid real live HTTP
-# requests when testing code that uses RubyGems.
-#
-# Example:
-#
-# @fetcher = Gem::FakeFetcher.new
-# @fetcher.data['http://gems.example.com/yaml'] = source_index.to_yaml
-# Gem::RemoteFetcher.fetcher = @fetcher
-#
-# # invoke RubyGems code
-#
-# paths = @fetcher.paths
-# assert_equal 'http://gems.example.com/yaml', paths.shift
-# assert paths.empty?, paths.join(', ')
-#
-# See RubyGems' tests for more examples of FakeFetcher.
-
-class Gem::FakeFetcher
-
- attr_reader :data
- attr_reader :last_request
- attr_reader :api_endpoints
- attr_accessor :paths
-
- def initialize
- @data = {}
- @paths = []
- @api_endpoints = {}
- end
-
- def api_endpoint(uri)
- @api_endpoints[uri] || uri
- end
-
- def find_data(path)
- return File.read path.path if URI === path and 'file' == path.scheme
-
- if URI === path and "URI::#{path.scheme.upcase}" != path.class.name then
- raise ArgumentError,
- "mismatch for scheme #{path.scheme} and class #{path.class}"
- end
-
- path = path.to_s
- @paths << path
- raise ArgumentError, 'need full URI' unless path =~ %r'^https?://'
-
- unless @data.key? path then
- raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
- end
-
- @data[path]
- end
-
- def fetch_path path, mtime = nil, head = false
- data = find_data(path)
-
- if data.respond_to?(:call) then
- data.call
- else
- if path.to_s =~ /gz$/ and not data.nil? and not data.empty? then
- data = Gem.gunzip data
- end
-
- data
- end
- end
-
- def cache_update_path uri, path = nil, update = true
- if data = fetch_path(uri)
- open(path, 'wb') { |io| io.write data } if path and update
- data
- else
- Gem.read_binary(path) if path
- end
- end
-
- # Thanks, FakeWeb!
- def open_uri_or_path(path)
- data = find_data(path)
- body, code, msg = data
-
- response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
- response.instance_variable_set(:@body, body)
- response.instance_variable_set(:@read, true)
- response
- end
-
- def request(uri, request_class, last_modified = nil)
- data = find_data(uri)
- body, code, msg = data
-
- @last_request = request_class.new uri.request_uri
- yield @last_request if block_given?
-
- response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
- response.instance_variable_set(:@body, body)
- response.instance_variable_set(:@read, true)
- response
- end
-
- def pretty_print q # :nodoc:
- q.group 2, '[FakeFetcher', ']' do
- q.breakable
- q.text 'URIs:'
-
- q.breakable
- q.pp @data.keys
-
- unless @api_endpoints.empty? then
- q.breakable
- q.text 'API endpoints:'
-
- q.breakable
- q.pp @api_endpoints.keys
- end
- end
- end
-
- def fetch_size(path)
- path = path.to_s
- @paths << path
-
- raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
-
- unless @data.key? path then
- raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
- end
-
- data = @data[path]
-
- data.respond_to?(:call) ? data.call : data.length
- end
-
- def download spec, source_uri, install_dir = Gem.dir
- name = File.basename spec.cache_file
- path = if Dir.pwd == install_dir then # see fetch_command
- install_dir
- else
- File.join install_dir, "cache"
- end
-
- path = File.join path, name
-
- if source_uri =~ /^http/ then
- File.open(path, "wb") do |f|
- f.write fetch_path(File.join(source_uri, "gems", name))
- end
- else
- FileUtils.cp source_uri, path
- end
-
- path
- end
-
- def download_to_cache dependency
- found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency
-
- return if found.empty?
-
- spec, source = found.first
-
- download spec, source.uri.to_s
- end
-
-end
-
-# :stopdoc:
-class Gem::RemoteFetcher
-
- def self.fetcher=(fetcher)
- @fetcher = fetcher
- end
-
-end
-# :startdoc:
-
-##
-# The SpecFetcherSetup allows easy setup of a remote source in RubyGems tests:
-#
-# spec_fetcher do |f|
-# f.gem 'a', 1
-# f.spec 'a', 2
-# f.gem 'b', 1' 'a' => '~> 1.0'
-# end
-#
-# The above declaration creates two gems, a-1 and b-1, with a dependency from
-# b to a. The declaration creates an additional spec a-2, but no gem for it
-# (so it cannot be installed).
-#
-# After the gems are created they are removed from Gem.dir.
-
-class Gem::TestCase::SpecFetcherSetup
-
- ##
- # Executes a SpecFetcher setup block. Yields an instance then creates the
- # gems and specifications defined in the instance.
-
- def self.declare test, repository
- setup = new test, repository
-
- yield setup
-
- setup.execute
- end
-
- def initialize test, repository # :nodoc:
- @test = test
- @repository = repository
-
- @gems = {}
- @downloaded = []
- @installed = []
- @operations = []
- end
-
- ##
- # Returns a Hash of created Specification full names and the corresponding
- # Specification.
-
- def created_specs
- created = {}
-
- @gems.keys.each do |spec|
- created[spec.full_name] = spec
- end
-
- created
- end
-
- ##
- # Creates any defined gems or specifications
-
- def execute # :nodoc:
- execute_operations
-
- setup_fetcher
-
- created_specs
- end
-
- def execute_operations # :nodoc:
- @operations.each do |operation, *arguments|
- case operation
- when :gem then
- spec, gem = @test.util_gem(*arguments, &arguments.pop)
-
- write_spec spec
-
- @gems[spec] = gem
- @installed << spec
- when :download then
- spec, gem = @test.util_gem(*arguments, &arguments.pop)
-
- @gems[spec] = gem
- @downloaded << spec
- when :spec then
- spec = @test.util_spec(*arguments, &arguments.pop)
-
- write_spec spec
-
- @gems[spec] = nil
- @installed << spec
- end
- end
- end
-
- ##
- # Creates a gem with +name+, +version+ and +deps+. The created gem can be
- # downloaded and installed.
- #
- # The specification will be yielded before gem creation for customization,
- # but only the block or the dependencies may be set, not both.
-
- def gem name, version, dependencies = nil, &block
- @operations << [:gem, name, version, dependencies, block]
- end
-
- ##
- # Creates a gem with +name+, +version+ and +deps+. The created gem is
- # downloaded in to the cache directory but is not installed
- #
- # The specification will be yielded before gem creation for customization,
- # but only the block or the dependencies may be set, not both.
-
- def download name, version, dependencies = nil, &block
- @operations << [:download, name, version, dependencies, block]
- end
-
- ##
- # Creates a legacy platform spec with the name 'pl' and version 1
-
- def legacy_platform
- spec 'pl', 1 do |s|
- s.platform = Gem::Platform.new 'i386-linux'
- s.instance_variable_set :@original_platform, 'i386-linux'
- end
- end
-
- def setup_fetcher # :nodoc:
- require 'zlib'
- require 'socket'
- require 'rubygems/remote_fetcher'
-
- unless @test.fetcher then
- @test.fetcher = Gem::FakeFetcher.new
- Gem::RemoteFetcher.fetcher = @test.fetcher
- end
-
- Gem::Specification.reset
-
- begin
- gem_repo, @test.gem_repo = @test.gem_repo, @repository
- @test.uri = URI @repository
-
- @test.util_setup_spec_fetcher(*@downloaded)
- ensure
- @test.gem_repo = gem_repo
- @test.uri = URI gem_repo
- end
-
- @gems.each do |spec, gem|
- next unless gem
-
- @test.fetcher.data["#{@repository}gems/#{spec.file_name}"] =
- Gem.read_binary(gem)
-
- FileUtils.cp gem, spec.cache_file
- end
- end
-
- ##
- # Creates a spec with +name+, +version+ and +deps+. The created gem can be
- # downloaded and installed.
- #
- # The specification will be yielded before creation for customization,
- # but only the block or the dependencies may be set, not both.
-
- def spec name, version, dependencies = nil, &block
- @operations << [:spec, name, version, dependencies, block]
- end
-
- def write_spec spec # :nodoc:
- open spec.spec_file, 'w' do |io|
- io.write spec.to_ruby_for_cache
- end
- end
-
-end
-
-##
-# A StringIO duck-typed class that uses Tempfile instead of String as the
-# backing store.
-#
-# This is available when rubygems/test_utilities is required.
-#--
-# This class was added to flush out problems in Rubinius' IO implementation.
-
-class TempIO < Tempfile
-
- ##
- # Creates a new TempIO that will be initialized to contain +string+.
-
- def initialize(string = '')
- super "TempIO"
- binmode
- write string
- rewind
- end
-
- ##
- # The content of the TempIO as a String.
-
- def string
- flush
- Gem.read_binary path
- end
-end
-
diff --git a/lib/rubygems/text.rb b/lib/rubygems/text.rb
index b944b62c27..667811192d 100644
--- a/lib/rubygems/text.rb
+++ b/lib/rubygems/text.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require 'rubygems'
##
# A collection of text-wrangling methods
@@ -28,7 +27,7 @@ module Gem::Text
work = clean_text(text)
while work.length > wrap do
- if work =~ /^(.{0,#{wrap}})[ \n]/ then
+ if work =~ /^(.{0,#{wrap}})[ \n]/
result << $1.rstrip
work.slice!(0, $&.length)
else
@@ -40,10 +39,10 @@ module Gem::Text
result.join("\n").gsub(/^/, " " * indent)
end
- def min3 a, b, c # :nodoc:
- if a < b && a < c then
+ def min3(a, b, c) # :nodoc:
+ if a < b && a < c
a
- elsif b < c then
+ elsif b < c
b
else
c
@@ -52,7 +51,7 @@ module Gem::Text
# This code is based directly on the Text gem implementation
# Returns a value representing the "cost" of transforming str1 into str2
- def levenshtein_distance str1, str2
+ def levenshtein_distance(str1, str2)
s = str1
t = str2
n = s.length
@@ -65,15 +64,15 @@ module Gem::Text
x = nil
str1.each_char.each_with_index do |char1,i|
- e = i+1
+ e = i + 1
str2.each_char.each_with_index do |char2,j|
cost = (char1 == char2) ? 0 : 1
x = min3(
- d[j+1] + 1, # insertion
+ d[j + 1] + 1, # insertion
e + 1, # deletion
d[j] + cost # substitution
- )
+ )
d[j] = e
e = x
end
diff --git a/lib/rubygems/tsort.rb b/lib/rubygems/tsort.rb
new file mode 100644
index 0000000000..ebe7c3364b
--- /dev/null
+++ b/lib/rubygems/tsort.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+require_relative 'tsort/lib/tsort'
diff --git a/lib/rubygems/tsort/.document b/lib/rubygems/tsort/.document
new file mode 100644
index 0000000000..0c43bbd6b3
--- /dev/null
+++ b/lib/rubygems/tsort/.document
@@ -0,0 +1 @@
+# Vendored files do not need to be documented
diff --git a/lib/rubygems/tsort/LICENSE.txt b/lib/rubygems/tsort/LICENSE.txt
new file mode 100644
index 0000000000..a009caefea
--- /dev/null
+++ b/lib/rubygems/tsort/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/lib/rubygems/tsort/lib/tsort.rb b/lib/rubygems/tsort/lib/tsort.rb
new file mode 100644
index 0000000000..f68c5947d3
--- /dev/null
+++ b/lib/rubygems/tsort/lib/tsort.rb
@@ -0,0 +1,454 @@
+# frozen_string_literal: true
+
+#--
+# tsort.rb - provides a module for topological sorting and strongly connected components.
+#++
+#
+
+#
+# Gem::TSort implements topological sorting using Tarjan's algorithm for
+# strongly connected components.
+#
+# Gem::TSort is designed to be able to be used with any object which can be
+# interpreted as a directed graph.
+#
+# Gem::TSort requires two methods to interpret an object as a graph,
+# tsort_each_node and tsort_each_child.
+#
+# * tsort_each_node is used to iterate for all nodes over a graph.
+# * tsort_each_child is used to iterate for child nodes of a given node.
+#
+# The equality of nodes are defined by eql? and hash since
+# Gem::TSort uses Hash internally.
+#
+# == A Simple Example
+#
+# The following example demonstrates how to mix the Gem::TSort module into an
+# existing class (in this case, Hash). Here, we're treating each key in
+# the hash as a node in the graph, and so we simply alias the required
+# #tsort_each_node method to Hash's #each_key method. For each key in the
+# hash, the associated value is an array of the node's child nodes. This
+# choice in turn leads to our implementation of the required #tsort_each_child
+# method, which fetches the array of child nodes and then iterates over that
+# array using the user-supplied block.
+#
+# require 'rubygems/tsort/lib/tsort'
+#
+# class Hash
+# include Gem::TSort
+# alias tsort_each_node each_key
+# def tsort_each_child(node, &block)
+# fetch(node).each(&block)
+# end
+# end
+#
+# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
+# #=> [3, 2, 1, 4]
+#
+# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
+# #=> [[4], [2, 3], [1]]
+#
+# == A More Realistic Example
+#
+# A very simple `make' like tool can be implemented as follows:
+#
+# require 'rubygems/tsort/lib/tsort'
+#
+# class Make
+# def initialize
+# @dep = {}
+# @dep.default = []
+# end
+#
+# def rule(outputs, inputs=[], &block)
+# triple = [outputs, inputs, block]
+# outputs.each {|f| @dep[f] = [triple]}
+# @dep[triple] = inputs
+# end
+#
+# def build(target)
+# each_strongly_connected_component_from(target) {|ns|
+# if ns.length != 1
+# fs = ns.delete_if {|n| Array === n}
+# raise Gem::TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
+# end
+# n = ns.first
+# if Array === n
+# outputs, inputs, block = n
+# inputs_time = inputs.map {|f| File.mtime f}.max
+# begin
+# outputs_time = outputs.map {|f| File.mtime f}.min
+# rescue Errno::ENOENT
+# outputs_time = nil
+# end
+# if outputs_time == nil ||
+# inputs_time != nil && outputs_time <= inputs_time
+# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
+# block.call
+# end
+# end
+# }
+# end
+#
+# def tsort_each_child(node, &block)
+# @dep[node].each(&block)
+# end
+# include Gem::TSort
+# end
+#
+# def command(arg)
+# print arg, "\n"
+# system arg
+# end
+#
+# m = Make.new
+# m.rule(%w[t1]) { command 'date > t1' }
+# m.rule(%w[t2]) { command 'date > t2' }
+# m.rule(%w[t3]) { command 'date > t3' }
+# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
+# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
+# m.build('t5')
+#
+# == Bugs
+#
+# * 'tsort.rb' is wrong name because this library uses
+# Tarjan's algorithm for strongly connected components.
+# Although 'strongly_connected_components.rb' is correct but too long.
+#
+# == References
+#
+# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms",
+# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
+#
+
+module Gem
+ module TSort
+ class Cyclic < StandardError
+ end
+
+ # Returns a topologically sorted array of nodes.
+ # The array is sorted from children to parents, i.e.
+ # the first element has no child and the last node has no parent.
+ #
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # p graph.tsort #=> [4, 2, 3, 1]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # p graph.tsort # raises Gem::TSort::Cyclic
+ #
+ def tsort
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.tsort(each_node, each_child)
+ end
+
+ # Returns a topologically sorted array of nodes.
+ # The array is sorted from children to parents, i.e.
+ # the first element has no child and the last node has no parent.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.tsort(each_node, each_child) # raises Gem::TSort::Cyclic
+ #
+ def TSort.tsort(each_node, each_child)
+ Gem::TSort.tsort_each(each_node, each_child).to_a
+ end
+
+ # The iterator version of the #tsort method.
+ # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
+ # modification of _obj_ during the iteration may lead to unexpected results.
+ #
+ # #tsort_each returns +nil+.
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.tsort_each {|n| p n }
+ # #=> 4
+ # # 2
+ # # 3
+ # # 1
+ #
+ def tsort_each(&block) # :yields: node
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.tsort_each(each_node, each_child, &block)
+ end
+
+ # The iterator version of the Gem::TSort.tsort method.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # Gem::TSort.tsort_each(each_node, each_child) {|n| p n }
+ # #=> 4
+ # # 2
+ # # 3
+ # # 1
+ #
+ def TSort.tsort_each(each_node, each_child) # :yields: node
+ return to_enum(__method__, each_node, each_child) unless block_given?
+
+ Gem::TSort.each_strongly_connected_component(each_node, each_child) {|component|
+ if component.size == 1
+ yield component.first
+ else
+ raise Cyclic.new("topological sort failed: #{component.inspect}")
+ end
+ }
+ end
+
+ # Returns strongly connected components as an array of arrays of nodes.
+ # The array is sorted from children to parents.
+ # Each elements of the array represents a strongly connected component.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
+ #
+ def strongly_connected_components
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.strongly_connected_components(each_node, each_child)
+ end
+
+ # Returns strongly connected components as an array of arrays of nodes.
+ # The array is sorted from children to parents.
+ # Each elements of the array represents a strongly connected component.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.strongly_connected_components(each_node, each_child)
+ # #=> [[4], [2], [3], [1]]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.strongly_connected_components(each_node, each_child)
+ # #=> [[4], [2, 3], [1]]
+ #
+ def TSort.strongly_connected_components(each_node, each_child)
+ Gem::TSort.each_strongly_connected_component(each_node, each_child).to_a
+ end
+
+ # The iterator version of the #strongly_connected_components method.
+ # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
+ # <tt><em>obj</em>.strongly_connected_components.each</tt>, but
+ # modification of _obj_ during the iteration may lead to unexpected results.
+ #
+ # #each_strongly_connected_component returns +nil+.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.each_strongly_connected_component {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ # # [3]
+ # # [1]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # graph.each_strongly_connected_component {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def each_strongly_connected_component(&block) # :yields: nodes
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.each_strongly_connected_component(each_node, each_child, &block)
+ end
+
+ # The iterator version of the Gem::TSort.strongly_connected_components method.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ # # [3]
+ # # [1]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def TSort.each_strongly_connected_component(each_node, each_child) # :yields: nodes
+ return to_enum(__method__, each_node, each_child) unless block_given?
+
+ id_map = {}
+ stack = []
+ each_node.call {|node|
+ unless id_map.include? node
+ Gem::TSort.each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
+ yield c
+ }
+ end
+ }
+ nil
+ end
+
+ # Iterates over strongly connected component in the subgraph reachable from
+ # _node_.
+ #
+ # Return value is unspecified.
+ #
+ # #each_strongly_connected_component_from doesn't call #tsort_each_node.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ #
+ def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
+ Gem::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
+ end
+
+ # Iterates over strongly connected components in a graph.
+ # The graph is represented by _node_ and _each_child_.
+ #
+ # _node_ is the first node.
+ # _each_child_ should have +call+ method which takes a node argument
+ # and yields for each child node.
+ #
+ # Return value is unspecified.
+ #
+ # #Gem::TSort.each_strongly_connected_component_from is a class method and
+ # it doesn't need a class to represent a graph which includes Gem::TSort.
+ #
+ # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_child = lambda {|n, &b| graph[n].each(&b) }
+ # Gem::TSort.each_strongly_connected_component_from(1, each_child) {|scc|
+ # p scc
+ # }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def TSort.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
+ return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
+
+ minimum_id = node_id = id_map[node] = id_map.size
+ stack_length = stack.length
+ stack << node
+
+ each_child.call(node) {|child|
+ if id_map.include? child
+ child_id = id_map[child]
+ minimum_id = child_id if child_id && child_id < minimum_id
+ else
+ sub_minimum_id =
+ Gem::TSort.each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
+ yield c
+ }
+ minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
+ end
+ }
+
+ if node_id == minimum_id
+ component = stack.slice!(stack_length .. -1)
+ component.each {|n| id_map[n] = nil}
+ yield component
+ end
+
+ minimum_id
+ end
+
+ # Should be implemented by a extended class.
+ #
+ # #tsort_each_node is used to iterate for all nodes over a graph.
+ #
+ def tsort_each_node # :yields: node
+ raise NotImplementedError.new
+ end
+
+ # Should be implemented by a extended class.
+ #
+ # #tsort_each_child is used to iterate for child nodes of _node_.
+ #
+ def tsort_each_child(node) # :yields: child
+ raise NotImplementedError.new
+ end
+ end
+end
diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb
index 89f47a45fe..1c3bf260c2 100644
--- a/lib/rubygems/uninstaller.rb
+++ b/lib/rubygems/uninstaller.rb
@@ -6,10 +6,11 @@
#++
require 'fileutils'
-require 'rubygems'
-require 'rubygems/dependency_list'
-require 'rubygems/rdoc'
-require 'rubygems/user_interaction'
+require_relative '../rubygems'
+require_relative 'installer_uninstaller_utils'
+require_relative 'dependency_list'
+require_relative 'rdoc'
+require_relative 'user_interaction'
##
# An Uninstaller.
@@ -20,9 +21,10 @@ require 'rubygems/user_interaction'
# file. See Gem.pre_uninstall and Gem.post_uninstall for details.
class Gem::Uninstaller
-
include Gem::UserInteraction
+ include Gem::InstallerUninstallerUtils
+
##
# The directory a gem's executables will be installed into
@@ -46,7 +48,8 @@ class Gem::Uninstaller
# TODO document the valid options
@gem = gem
@version = options[:version] || Gem::Requirement.default
- @gem_home = File.expand_path(options[:install_dir] || Gem.dir)
+ @gem_home = File.realpath(options[:install_dir] || Gem.dir)
+ @plugins_dir = Gem.plugindir(@gem_home)
@force_executables = options[:executables]
@force_all = options[:all]
@force_ignore = options[:ignore]
@@ -57,7 +60,7 @@ class Gem::Uninstaller
# Indicate if development dependencies should be checked when
# uninstalling. (default: false)
#
- @check_dev = options[:check_dev]
+ @check_dev = options[:check_dev]
if options[:force]
@force_all = true
@@ -67,6 +70,9 @@ class Gem::Uninstaller
# only add user directory if install_dir is not set
@user_install = false
@user_install = options[:user_install] unless options[:install_dir]
+
+ # Optimization: populated during #uninstall
+ @default_specs_matching_uninstall_params = []
end
##
@@ -80,7 +86,7 @@ class Gem::Uninstaller
dirs =
Gem::Specification.dirs +
- [Gem::Specification.default_specifications_dir]
+ [Gem.default_specifications_dir]
Gem::Specification.each_spec dirs do |spec|
next unless dependency.matches_spec? spec
@@ -88,9 +94,15 @@ class Gem::Uninstaller
list << spec
end
+ if list.empty?
+ raise Gem::InstallError, "gem #{@gem.inspect} is not installed"
+ end
+
default_specs, list = list.partition do |spec|
spec.default_gem?
end
+ warn_cannot_uninstall_default_gems(default_specs - list)
+ @default_specs_matching_uninstall_params = default_specs
list, other_repo_specs = list.partition do |spec|
@gem_home == spec.base_dir or
@@ -99,42 +111,33 @@ class Gem::Uninstaller
list.sort!
- if list.empty? then
- if other_repo_specs.empty?
- if default_specs.empty?
- raise Gem::InstallError, "gem #{@gem.inspect} is not installed"
- else
- message =
- "gem #{@gem.inspect} cannot be uninstalled " +
- "because it is a default gem"
- raise Gem::InstallError, message
- end
- end
+ if list.empty?
+ return unless other_repo_specs.any?
- other_repos = other_repo_specs.map { |spec| spec.base_dir }.uniq
+ other_repos = other_repo_specs.map {|spec| spec.base_dir }.uniq
message = ["#{@gem} is not installed in GEM_HOME, try:"]
- message.concat other_repos.map { |repo|
+ message.concat other_repos.map {|repo|
"\tgem uninstall -i #{repo} #{@gem}"
}
raise Gem::InstallError, message.join("\n")
- elsif @force_all then
+ elsif @force_all
remove_all list
- elsif list.size > 1 then
- gem_names = list.map { |gem| gem.full_name }
+ elsif list.size > 1
+ gem_names = list.map {|gem| gem.full_name }
gem_names << "All versions"
say
_, index = choose_from_list "Select gem to uninstall:", gem_names
- if index == list.size then
+ if index == list.size
remove_all list
- elsif index >= 0 && index < list.size then
+ elsif index >= 0 && index < list.size
uninstall_gem list[index]
else
- say "Error: must enter a number [1-#{list.size+1}]"
+ say "Error: must enter a number [1-#{list.size + 1}]"
end
else
uninstall_gem list.first
@@ -159,8 +162,11 @@ class Gem::Uninstaller
end
remove_executables @spec
+ remove_plugins @spec
remove @spec
+ regenerate_plugins
+
Gem.post_uninstall_hooks.each do |hook|
hook.call self
end
@@ -169,20 +175,19 @@ class Gem::Uninstaller
end
##
- # Removes installed executables and batch files (windows only) for
- # +gemspec+.
+ # Removes installed executables and batch files (windows only) for +spec+.
def remove_executables(spec)
- return if spec.nil? or spec.executables.empty?
+ return if spec.executables.empty?
executables = spec.executables.clone
# Leave any executables created by other installed versions
# of this gem installed.
- list = Gem::Specification.find_all { |s|
+ list = Gem::Specification.find_all do |s|
s.name == spec.name && s.version != spec.version
- }
+ end
list.each do |s|
s.executables.each do |exe_name|
@@ -192,9 +197,9 @@ class Gem::Uninstaller
return if executables.empty?
- executables = executables.map { |exec| formatted_program_filename exec }
+ executables = executables.map {|exec| formatted_program_filename exec }
- remove = if @force_executables.nil? then
+ remove = if @force_executables.nil?
ask_yes_no("Remove executables:\n" +
"\t#{executables.join ', '}\n\n" +
"in addition to the gem?",
@@ -203,7 +208,7 @@ class Gem::Uninstaller
@force_executables
end
- if remove then
+ if remove
bin_dir = @bin_dir || Gem.bindir(spec.base_dir)
raise Gem::FilePermissionError, bin_dir unless File.writable? bin_dir
@@ -213,8 +218,8 @@ class Gem::Uninstaller
exe_file = File.join bin_dir, exe_name
- FileUtils.rm_f exe_file
- FileUtils.rm_f "#{exe_file}.bat"
+ safe_delete { FileUtils.rm exe_file }
+ safe_delete { FileUtils.rm "#{exe_file}.bat" }
end
else
say "Executables and scripts will remain installed."
@@ -227,19 +232,15 @@ class Gem::Uninstaller
# NOTE: removes uninstalled gems from +list+.
def remove_all(list)
- list.each { |spec| uninstall_gem spec }
+ list.each {|spec| uninstall_gem spec }
end
##
# spec:: the spec of the gem to be uninstalled
- # list:: the list of all such gems
- #
- # Warning: this method modifies the +list+ parameter. Once it has
- # uninstalled a gem, it is removed from that list.
def remove(spec)
unless path_ok?(@gem_home, spec) or
- (@user_install and path_ok?(Gem.user_dir, spec)) then
+ (@user_install and path_ok?(Gem.user_dir, spec))
e = Gem::GemNotInHomeException.new \
"Gem '#{spec.full_name}' is not installed in directory #{@gem_home}"
e.spec = spec
@@ -250,32 +251,51 @@ class Gem::Uninstaller
raise Gem::FilePermissionError, spec.base_dir unless
File.writable?(spec.base_dir)
- FileUtils.rm_rf spec.full_gem_path
- FileUtils.rm_rf spec.extension_dir
+ safe_delete { FileUtils.rm_r spec.full_gem_path }
+ safe_delete { FileUtils.rm_r spec.extension_dir }
old_platform_name = spec.original_name
- gemspec = spec.spec_file
-
- unless File.exist? gemspec then
- gemspec = File.join(File.dirname(gemspec), "#{old_platform_name}.gemspec")
- end
-
- FileUtils.rm_rf gemspec
gem = spec.cache_file
gem = File.join(spec.cache_dir, "#{old_platform_name}.gem") unless
File.exist? gem
- FileUtils.rm_rf gem
+ safe_delete { FileUtils.rm_r gem }
Gem::RDoc.new(spec).remove
- say "Successfully uninstalled #{spec.full_name}"
+ gemspec = spec.spec_file
+
+ unless File.exist? gemspec
+ gemspec = File.join(File.dirname(gemspec), "#{old_platform_name}.gemspec")
+ end
+
+ safe_delete { FileUtils.rm_r gemspec }
+ announce_deletion_of(spec)
Gem::Specification.reset
end
##
+ # Remove any plugin wrappers for +spec+.
+
+ def remove_plugins(spec) # :nodoc:
+ return if spec.plugins.empty?
+
+ remove_plugins_for(spec, @plugins_dir)
+ end
+
+ ##
+ # Regenerates plugin wrappers after removal.
+
+ def regenerate_plugins
+ latest = Gem::Specification.latest_spec_for(@spec.name)
+ return if latest.nil?
+
+ regenerate_plugins_for(latest, @plugins_dir)
+ end
+
+ ##
# Is +spec+ in +gem_dir+?
def path_ok?(gem_dir, spec)
@@ -289,7 +309,7 @@ class Gem::Uninstaller
# Returns true if it is OK to remove +spec+ or this is a forced
# uninstallation.
- def dependencies_ok? spec # :nodoc:
+ def dependencies_ok?(spec) # :nodoc:
return true if @force_ignore
deplist = Gem::DependencyList.from_specs
@@ -308,18 +328,18 @@ class Gem::Uninstaller
##
# Asks if it is OK to remove +spec+. Returns true if it is OK.
- def ask_if_ok spec # :nodoc:
+ def ask_if_ok(spec) # :nodoc:
msg = ['']
msg << 'You have requested to uninstall the gem:'
msg << "\t#{spec.full_name}"
msg << ''
siblings = Gem::Specification.select do |s|
- s.name == spec.name && s.full_name != spec.full_name
- end
+ s.name == spec.name && s.full_name != spec.full_name
+ end
- spec.dependent_gems.each do |dep_spec, dep, satlist|
- unless siblings.any? { |s| s.satisfies_requirement? dep }
+ spec.dependent_gems(@check_dev).each do |dep_spec, dep, satlist|
+ unless siblings.any? {|s| s.satisfies_requirement? dep }
msg << "#{dep_spec.name}-#{dep_spec.version} depends on #{dep}"
end
end
@@ -332,15 +352,56 @@ class Gem::Uninstaller
##
# Returns the formatted version of the executable +filename+
- def formatted_program_filename filename # :nodoc:
+ def formatted_program_filename(filename) # :nodoc:
# TODO perhaps the installer should leave a small manifest
# of what it did for us to find rather than trying to recreate
# it again.
- if @format_executable then
- require 'rubygems/installer'
+ if @format_executable
+ require_relative 'installer'
Gem::Installer.exec_format % File.basename(filename)
else
filename
end
end
+
+ def safe_delete(&block)
+ block.call
+ rescue Errno::ENOENT
+ nil
+ rescue Errno::EPERM
+ e = Gem::UninstallError.new
+ e.spec = @spec
+
+ raise e
+ end
+
+ private
+
+ def announce_deletion_of(spec)
+ name = spec.full_name
+ say "Successfully uninstalled #{name}"
+ if default_spec_matches?(spec)
+ say(
+ "There was both a regular copy and a default copy of #{name}. The " \
+ "regular copy was successfully uninstalled, but the default copy " \
+ "was left around because default gems can't be removed."
+ )
+ end
+ end
+
+ # @return true if the specs of any default gems are `==` to the given `spec`.
+ def default_spec_matches?(spec)
+ !default_specs_that_match(spec).empty?
+ end
+
+ # @return [Array] specs of default gems that are `==` to the given `spec`.
+ def default_specs_that_match(spec)
+ @default_specs_matching_uninstall_params.select {|default_spec| spec == default_spec }
+ end
+
+ def warn_cannot_uninstall_default_gems(specs)
+ specs.each do |spec|
+ say "Gem #{spec.full_name} cannot be uninstalled because it is a default gem"
+ end
+ end
end
diff --git a/lib/rubygems/uri.rb b/lib/rubygems/uri.rb
new file mode 100644
index 0000000000..ba30fac2f5
--- /dev/null
+++ b/lib/rubygems/uri.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+##
+# The Uri handles rubygems source URIs.
+#
+
+class Gem::Uri
+ def initialize(source_uri)
+ @parsed_uri = parse(source_uri)
+ end
+
+ def redacted
+ return self unless valid_uri?
+
+ if token? || oauth_basic?
+ with_redacted_user
+ elsif password?
+ with_redacted_password
+ else
+ self
+ end
+ end
+
+ def to_s
+ @parsed_uri.to_s
+ end
+
+ def redact_credentials_from(text)
+ return text unless valid_uri? && password?
+
+ text.sub(password, 'REDACTED')
+ end
+
+ def method_missing(method_name, *args, &blk)
+ if @parsed_uri.respond_to?(method_name)
+ @parsed_uri.send(method_name, *args, &blk)
+ else
+ super
+ end
+ end
+
+ def respond_to_missing?(method_name, include_private = false)
+ @parsed_uri.respond_to?(method_name, include_private) || super
+ end
+
+ protected
+
+ # Add a protected reader for the cloned instance to access the original object's parsed uri
+ attr_reader :parsed_uri
+
+ private
+
+ ##
+ # Parses the #uri, raising if it's invalid
+
+ def parse!(uri)
+ require "uri"
+
+ raise URI::InvalidURIError unless uri
+
+ # Always escape URI's to deal with potential spaces and such
+ # It should also be considered that source_uri may already be
+ # a valid URI with escaped characters. e.g. "{DESede}" is encoded
+ # as "%7BDESede%7D". If this is escaped again the percentage
+ # symbols will be escaped.
+ begin
+ URI.parse(uri)
+ rescue URI::InvalidURIError
+ URI.parse(URI::DEFAULT_PARSER.escape(uri))
+ end
+ end
+
+ ##
+ # Parses the #uri, returning the original uri if it's invalid
+
+ def parse(uri)
+ return uri unless uri.is_a?(String)
+
+ parse!(uri)
+ rescue URI::InvalidURIError
+ uri
+ end
+
+ def with_redacted_user
+ clone.tap {|uri| uri.user = 'REDACTED' }
+ end
+
+ def with_redacted_password
+ clone.tap {|uri| uri.password = 'REDACTED' }
+ end
+
+ def valid_uri?
+ !@parsed_uri.is_a?(String)
+ end
+
+ def password?
+ !!password
+ end
+
+ def oauth_basic?
+ password == 'x-oauth-basic'
+ end
+
+ def token?
+ !user.nil? && password.nil?
+ end
+
+ def initialize_copy(original)
+ @parsed_uri = original.parsed_uri.clone
+ end
+end
diff --git a/lib/rubygems/uri_formatter.rb b/lib/rubygems/uri_formatter.rb
index bb128e4ef9..3bda896875 100644
--- a/lib/rubygems/uri_formatter.rb
+++ b/lib/rubygems/uri_formatter.rb
@@ -1,6 +1,4 @@
# frozen_string_literal: true
-require 'cgi'
-require 'uri'
##
# The UriFormatter handles URIs from user-input and escaping.
@@ -10,7 +8,6 @@ require 'uri'
# p uf.normalize #=> 'http://example.com'
class Gem::UriFormatter
-
##
# The URI to be formatted.
@@ -19,7 +16,9 @@ class Gem::UriFormatter
##
# Creates a new URI formatter for +uri+.
- def initialize uri
+ def initialize(uri)
+ require 'cgi'
+
@uri = uri
end
@@ -45,6 +44,4 @@ class Gem::UriFormatter
return unless @uri
CGI.unescape @uri
end
-
end
-
diff --git a/lib/rubygems/user_interaction.rb b/lib/rubygems/user_interaction.rb
index cacd782e08..0ab44fbf6c 100644
--- a/lib/rubygems/user_interaction.rb
+++ b/lib/rubygems/user_interaction.rb
@@ -5,7 +5,8 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems/util'
+require_relative 'deprecate'
+require_relative 'text'
##
# Module that defines the default UserInteraction. Any class including this
@@ -13,6 +14,8 @@ require 'rubygems/util'
module Gem::DefaultUserInteraction
+ include Gem::Text
+
##
# The default UI is a class variable of the singleton class for this
# module.
@@ -94,7 +97,7 @@ module Gem::UserInteraction
##
# Displays an alert +statement+. Asks a +question+ if given.
- def alert statement, question = nil
+ def alert(statement, question = nil)
ui.alert statement, question
end
@@ -102,7 +105,7 @@ module Gem::UserInteraction
# Displays an error +statement+ to the error output location. Asks a
# +question+ if given.
- def alert_error statement, question = nil
+ def alert_error(statement, question = nil)
ui.alert_error statement, question
end
@@ -110,49 +113,49 @@ module Gem::UserInteraction
# Displays a warning +statement+ to the warning output location. Asks a
# +question+ if given.
- def alert_warning statement, question = nil
+ def alert_warning(statement, question = nil)
ui.alert_warning statement, question
end
##
# Asks a +question+ and returns the answer.
- def ask question
+ def ask(question)
ui.ask question
end
##
# Asks for a password with a +prompt+
- def ask_for_password prompt
+ def ask_for_password(prompt)
ui.ask_for_password prompt
end
##
# Asks a yes or no +question+. Returns true for yes, false for no.
- def ask_yes_no question, default = nil
+ def ask_yes_no(question, default = nil)
ui.ask_yes_no question, default
end
##
# Asks the user to answer +question+ with an answer from the given +list+.
- def choose_from_list question, list
+ def choose_from_list(question, list)
ui.choose_from_list question, list
end
##
# Displays the given +statement+ on the standard output (or equivalent).
- def say statement = ''
+ def say(statement = '')
ui.say statement
end
##
# Terminates the RubyGems process with the given +exit_code+
- def terminate_interaction exit_code = 0
+ def terminate_interaction(exit_code = 0)
ui.terminate_interaction exit_code
end
@@ -160,8 +163,8 @@ module Gem::UserInteraction
# Calls +say+ with +msg+ or the results of the block if really_verbose
# is true.
- def verbose msg = nil
- say(msg || yield) if Gem.configuration.really_verbose
+ def verbose(msg = nil)
+ say(clean_text(msg || yield)) if Gem.configuration.really_verbose
end
end
@@ -169,6 +172,7 @@ end
# Gem::StreamUI implements a simple stream based user interface.
class Gem::StreamUI
+ extend Gem::Deprecate
##
# The input stream
@@ -202,18 +206,14 @@ class Gem::StreamUI
# Returns true if TTY methods should be used on this StreamUI.
def tty?
- if RUBY_VERSION < '1.9.3' and RUBY_PLATFORM =~ /mingw|mswin/ then
- @usetty
- else
- @usetty && @ins.tty?
- end
+ @usetty && @ins.tty?
end
##
# Prints a formatted backtrace to the errors stream if backtraces are
# enabled.
- def backtrace exception
+ def backtrace(exception)
return unless Gem.configuration.backtrace
@errs.puts "\t#{exception.backtrace.join "\n\t"}"
@@ -228,7 +228,7 @@ class Gem::StreamUI
@outs.puts question
list.each_with_index do |item, index|
- @outs.puts " #{index+1}. #{item}"
+ @outs.puts " #{index + 1}. #{item}"
end
@outs.print "> "
@@ -248,8 +248,8 @@ class Gem::StreamUI
# default.
def ask_yes_no(question, default=nil)
- unless tty? then
- if default.nil? then
+ unless tty?
+ if default.nil?
raise Gem::OperationNotSupportedError,
"Not connected to a tty and no default specified"
else
@@ -321,29 +321,7 @@ class Gem::StreamUI
def _gets_noecho
require_io_console
- if IO.method_defined?(:noecho) then
- @ins.noecho {@ins.gets}
- elsif Gem.win_platform?
- require "Win32API"
- password = ''
-
- while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
- break if char == 10 || char == 13 # received carriage return or newline
- if char == 127 || char == 8 # backspace and delete
- password.slice!(-1, 1)
- else
- password << char.chr
- end
- end
- password
- else
- system "stty -echo"
- begin
- @ins.gets
- ensure
- system "stty echo"
- end
- end
+ @ins.noecho { @ins.gets }
end
##
@@ -379,13 +357,6 @@ class Gem::StreamUI
end
##
- # Display a debug message on the same location as error messages.
-
- def debug(statement)
- @errs.puts statement
- end
-
- ##
# Terminate the application with exit code +status+, running any exit
# handlers that might have been defined.
@@ -415,7 +386,6 @@ class Gem::StreamUI
# An absolutely silent progress reporter.
class SilentProgressReporter
-
##
# The count of items is never updated for the silent progress reporter.
@@ -446,7 +416,6 @@ class Gem::StreamUI
# A basic dotted progress reporter.
class SimpleProgressReporter
-
include Gem::DefaultUserInteraction
##
@@ -484,14 +453,12 @@ class Gem::StreamUI
def done
@out.puts "\n#{@terminal_message}"
end
-
end
##
# A progress reporter that prints out messages about the current progress.
class VerboseProgressReporter
-
include Gem::DefaultUserInteraction
##
@@ -534,11 +501,10 @@ class Gem::StreamUI
# Return a download reporter object chosen from the current verbosity
def download_reporter(*args)
- case Gem.configuration.verbose
- when nil, false
+ if [nil, false].include?(Gem.configuration.verbose) || !@outs.tty?
SilentDownloadReporter.new(@outs, *args)
else
- VerboseDownloadReporter.new(@outs, *args)
+ ThreadedDownloadReporter.new(@outs, *args)
end
end
@@ -546,7 +512,6 @@ class Gem::StreamUI
# An absolutely silent download reporter.
class SilentDownloadReporter
-
##
# The silent download reporter ignores all arguments
@@ -575,9 +540,10 @@ class Gem::StreamUI
end
##
- # A progress reporter that prints out messages about the current progress.
+ # A progress reporter that behaves nicely with threaded downloading.
- class VerboseDownloadReporter
+ class ThreadedDownloadReporter
+ MUTEX = Thread::Mutex.new
##
# The current file name being displayed
@@ -585,71 +551,45 @@ class Gem::StreamUI
attr_reader :file_name
##
- # The total bytes in the file
-
- attr_reader :total_bytes
-
- ##
- # The current progress (0 to 100)
-
- attr_reader :progress
-
- ##
- # Creates a new verbose download reporter that will display on
+ # Creates a new threaded download reporter that will display on
# +out_stream+. The other arguments are ignored.
def initialize(out_stream, *args)
+ @file_name = nil
@out = out_stream
- @progress = 0
end
##
- # Tells the download reporter that the +file_name+ is being fetched and
- # contains +total_bytes+.
-
- def fetch(file_name, total_bytes)
- @file_name = file_name
- @total_bytes = total_bytes.to_i
- @units = @total_bytes.zero? ? 'B' : '%'
+ # Tells the download reporter that the +file_name+ is being fetched.
+ # The other arguments are ignored.
- update_display(false)
+ def fetch(file_name, *args)
+ if @file_name.nil?
+ @file_name = file_name
+ locked_puts "Fetching #{@file_name}"
+ end
end
##
- # Updates the verbose download reporter for the given number of +bytes+.
+ # Updates the threaded download reporter for the given number of +bytes+.
def update(bytes)
- new_progress = if @units == 'B' then
- bytes
- else
- ((bytes.to_f * 100) / total_bytes.to_f).ceil
- end
-
- return if new_progress == @progress
-
- @progress = new_progress
- update_display
+ # Do nothing.
end
##
# Indicates the download is complete.
def done
- @progress = 100 if @units == '%'
- update_display(true, true)
+ # Do nothing.
end
private
- def update_display(show_progress = true, new_line = false) # :nodoc:
- return unless @out.tty?
-
- if show_progress then
- @out.print "\rFetching: %s (%3d%s)" % [@file_name, @progress, @units]
- else
- @out.print "Fetching: %s" % @file_name
+ def locked_puts(message)
+ MUTEX.synchronize do
+ @out.puts message
end
- @out.puts if new_line
end
end
end
@@ -659,7 +599,6 @@ end
# STDOUT, and STDERR.
class Gem::ConsoleUI < Gem::StreamUI
-
##
# The Console UI has no arguments as it defaults to reading input from
# stdin, output to stdout and warnings or errors to stderr.
@@ -673,15 +612,14 @@ end
# SilentUI is a UI choice that is absolutely silent.
class Gem::SilentUI < Gem::StreamUI
-
##
# The SilentUI has no arguments as it does not use any stream.
def initialize
reader, writer = nil, nil
- reader = File.open(Gem::Util::NULL_DEVICE, 'r')
- writer = File.open(Gem::Util::NULL_DEVICE, 'w')
+ reader = File.open(IO::NULL, 'r')
+ writer = File.open(IO::NULL, 'w')
super reader, writer, writer, false
end
diff --git a/lib/rubygems/util.rb b/lib/rubygems/util.rb
index 2de45c900b..4363c5adce 100644
--- a/lib/rubygems/util.rb
+++ b/lib/rubygems/util.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
+require_relative 'deprecate'
+
##
# This module contains various utility methods as module methods.
module Gem::Util
- @silent_mutex = nil
-
##
# Zlib::GzipReader wrapper that unzips +data+.
@@ -14,8 +14,14 @@ module Gem::Util
require 'stringio'
data = StringIO.new(data, 'r')
- unzipped = Zlib::GzipReader.new(data).read
- unzipped.force_encoding Encoding::BINARY if Object.const_defined? :Encoding
+ gzip_reader = begin
+ Zlib::GzipReader.new(data)
+ rescue Zlib::GzipFile::Error => e
+ raise e.class, e.inspect, e.backtrace
+ end
+
+ unzipped = gzip_reader.read
+ unzipped.force_encoding Encoding::BINARY
unzipped
end
@@ -26,9 +32,11 @@ module Gem::Util
require 'zlib'
require 'stringio'
zipped = StringIO.new(String.new, 'w')
- zipped.set_encoding Encoding::BINARY if Object.const_defined? :Encoding
+ zipped.set_encoding Encoding::BINARY
- Zlib::GzipWriter.wrap zipped do |io| io.write data end
+ Zlib::GzipWriter.wrap zipped do |io|
+ io.write data
+ end
zipped.string
end
@@ -42,83 +50,70 @@ module Gem::Util
end
##
- # This calls IO.popen where it accepts an array for a +command+ (Ruby 1.9+)
- # and implements an IO.popen-like behavior where it does not accept an array
- # for a command.
+ # This calls IO.popen and reads the result
- def self.popen *command
+ def self.popen(*command)
IO.popen command, &:read
- rescue TypeError # ruby 1.8 only supports string command
- r, w = IO.pipe
-
- pid = fork do
- STDIN.close
- STDOUT.reopen w
-
- exec(*command)
- end
-
- w.close
-
- begin
- return r.read
- ensure
- Process.wait pid
- end
end
- NULL_DEVICE = defined?(IO::NULL) ? IO::NULL : Gem.win_platform? ? 'NUL' : '/dev/null'
-
##
# Invokes system, but silences all output.
- def self.silent_system *command
- opt = {:out => NULL_DEVICE, :err => [:child, :out]}
+ def self.silent_system(*command)
+ opt = {:out => IO::NULL, :err => [:child, :out]}
if Hash === command.last
opt.update(command.last)
cmds = command[0...-1]
else
cmds = command.dup
end
- return system(*(cmds << opt))
- rescue TypeError
- require 'thread'
-
- @silent_mutex ||= Mutex.new
-
- null_device = NULL_DEVICE
-
- @silent_mutex.synchronize do
- begin
- stdout = STDOUT.dup
- stderr = STDERR.dup
+ system(*(cmds << opt))
+ end
- STDOUT.reopen null_device, 'w'
- STDERR.reopen null_device, 'w'
+ class << self
+ extend Gem::Deprecate
- return system(*command)
- ensure
- STDOUT.reopen stdout
- STDERR.reopen stderr
- stdout.close
- stderr.close
- end
- end
+ rubygems_deprecate :silent_system
end
##
# Enumerates the parents of +directory+.
- def self.traverse_parents directory, &block
+ def self.traverse_parents(directory, &block)
return enum_for __method__, directory unless block_given?
here = File.expand_path directory
loop do
- Dir.chdir here, &block
+ Dir.chdir here, &block rescue Errno::EACCES
+
new_here = File.expand_path('..', here)
return if new_here == here # toplevel
here = new_here
end
end
+ ##
+ # Globs for files matching +pattern+ inside of +directory+,
+ # returning absolute paths to the matching files.
+
+ def self.glob_files_in_dir(glob, base_path)
+ if RUBY_VERSION >= "2.5"
+ Dir.glob(glob, base: base_path).map! {|f| File.expand_path(f, base_path) }
+ else
+ Dir.glob(File.expand_path(glob, base_path))
+ end
+ end
+
+ ##
+ # Corrects +path+ (usually returned by `URI.parse().path` on Windows), that
+ # comes with a leading slash.
+
+ def self.correct_for_windows_path(path)
+ if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
+ path[1..-1]
+ else
+ path
+ end
+ end
+
end
diff --git a/lib/rubygems/util/licenses.rb b/lib/rubygems/util/licenses.rb
index f4a99af39e..3f4178c6e0 100644
--- a/lib/rubygems/util/licenses.rb
+++ b/lib/rubygems/util/licenses.rb
@@ -1,329 +1,530 @@
# frozen_string_literal: true
-require 'rubygems/text'
+require_relative '../text'
class Gem::Licenses
extend Gem::Text
NONSTANDARD = 'Nonstandard'.freeze
+ LICENSE_REF = 'LicenseRef-.+'.freeze
# Software Package Data Exchange (SPDX) standard open-source software
# license identifiers
- IDENTIFIERS = %w(
- 0BSD
- AAL
- ADSL
- AFL-1.1
- AFL-1.2
- AFL-2.0
- AFL-2.1
- AFL-3.0
- AGPL-1.0
- AGPL-3.0
- AMDPLPA
- AML
- AMPAS
- ANTLR-PD
- APAFML
- APL-1.0
- APSL-1.0
- APSL-1.1
- APSL-1.2
- APSL-2.0
- Abstyles
- Adobe-2006
- Adobe-Glyph
- Afmparse
- Aladdin
- Apache-1.0
- Apache-1.1
- Apache-2.0
- Artistic-1.0
- Artistic-1.0-Perl
- Artistic-1.0-cl8
- Artistic-2.0
- BSD-2-Clause
- BSD-2-Clause-FreeBSD
- BSD-2-Clause-NetBSD
- BSD-3-Clause
- BSD-3-Clause-Attribution
- BSD-3-Clause-Clear
- BSD-3-Clause-LBNL
- BSD-4-Clause
- BSD-4-Clause-UC
- BSD-Protection
- BSL-1.0
- Bahyph
- Barr
- Beerware
- BitTorrent-1.0
- BitTorrent-1.1
- Borceux
- CATOSL-1.1
- CC-BY-1.0
- CC-BY-2.0
- CC-BY-2.5
- CC-BY-3.0
- CC-BY-4.0
- CC-BY-NC-1.0
- CC-BY-NC-2.0
- CC-BY-NC-2.5
- CC-BY-NC-3.0
- CC-BY-NC-4.0
- CC-BY-NC-ND-1.0
- CC-BY-NC-ND-2.0
- CC-BY-NC-ND-2.5
- CC-BY-NC-ND-3.0
- CC-BY-NC-ND-4.0
- CC-BY-NC-SA-1.0
- CC-BY-NC-SA-2.0
- CC-BY-NC-SA-2.5
- CC-BY-NC-SA-3.0
- CC-BY-NC-SA-4.0
- CC-BY-ND-1.0
- CC-BY-ND-2.0
- CC-BY-ND-2.5
- CC-BY-ND-3.0
- CC-BY-ND-4.0
- CC-BY-SA-1.0
- CC-BY-SA-2.0
- CC-BY-SA-2.5
- CC-BY-SA-3.0
- CC-BY-SA-4.0
- CC0-1.0
- CDDL-1.0
- CDDL-1.1
- CECILL-1.0
- CECILL-1.1
- CECILL-2.0
- CECILL-2.1
- CECILL-B
- CECILL-C
- CNRI-Jython
- CNRI-Python
- CNRI-Python-GPL-Compatible
- CPAL-1.0
- CPL-1.0
- CPOL-1.02
- CUA-OPL-1.0
- Caldera
- ClArtistic
- Condor-1.1
- Crossword
- CrystalStacker
- Cube
- D-FSL-1.0
- DOC
- DSDP
- Dotseqn
- ECL-1.0
- ECL-2.0
- EFL-1.0
- EFL-2.0
- EPL-1.0
- EUDatagrid
- EUPL-1.0
- EUPL-1.1
- Entessa
- ErlPL-1.1
- Eurosym
- FSFUL
- FSFULLR
- FTL
- Fair
- Frameworx-1.0
- FreeImage
- GFDL-1.1
- GFDL-1.2
- GFDL-1.3
- GL2PS
- GPL-1.0
- GPL-2.0
- GPL-3.0
- Giftware
- Glide
- Glulxe
- HPND
- HaskellReport
- IBM-pibs
- ICU
- IJG
- IPA
- IPL-1.0
- ISC
- ImageMagick
- Imlib2
- Intel
- Intel-ACPI
- Interbase-1.0
- JSON
- JasPer-2.0
- LGPL-2.0
- LGPL-2.1
- LGPL-3.0
- LGPLLR
- LPL-1.0
- LPL-1.02
- LPPL-1.0
- LPPL-1.1
- LPPL-1.2
- LPPL-1.3a
- LPPL-1.3c
- Latex2e
- Leptonica
- Libpng
- MIT
- MIT-CMU
- MIT-advertising
- MIT-enna
- MIT-feh
- MITNFA
- MPL-1.0
- MPL-1.1
- MPL-2.0
- MPL-2.0-no-copyleft-exception
- MS-PL
- MS-RL
- MTLL
- MakeIndex
- MirOS
- Motosoto
- Multics
- Mup
- NASA-1.3
- NBPL-1.0
- NCSA
- NGPL
- NLPL
- NOSL
- NPL-1.0
- NPL-1.1
- NPOSL-3.0
- NRL
- NTP
- Naumen
- NetCDF
- Newsletr
- Nokia
- Noweb
- Nunit
- OCLC-2.0
- ODbL-1.0
- OFL-1.0
- OFL-1.1
- OGTSL
- OLDAP-1.1
- OLDAP-1.2
- OLDAP-1.3
- OLDAP-1.4
- OLDAP-2.0
- OLDAP-2.0.1
- OLDAP-2.1
- OLDAP-2.2
- OLDAP-2.2.1
- OLDAP-2.2.2
- OLDAP-2.3
- OLDAP-2.4
- OLDAP-2.5
- OLDAP-2.6
- OLDAP-2.7
- OLDAP-2.8
- OML
- OPL-1.0
- OSL-1.0
- OSL-1.1
- OSL-2.0
- OSL-2.1
- OSL-3.0
- OpenSSL
- PDDL-1.0
- PHP-3.0
- PHP-3.01
- Plexus
- PostgreSQL
- Python-2.0
- QPL-1.0
- Qhull
- RHeCos-1.1
- RPL-1.1
- RPL-1.5
- RPSL-1.0
- RSA-MD
- RSCPL
- Rdisc
- Ruby
- SAX-PD
- SCEA
- SGI-B-1.0
- SGI-B-1.1
- SGI-B-2.0
- SISSL
- SISSL-1.2
- SMLNJ
- SNIA
- SPL-1.0
- SWL
- Saxpath
- Sendmail
- SimPL-2.0
- Sleepycat
- Spencer-86
- Spencer-94
- Spencer-99
- SugarCRM-1.1.3
- TCL
- TMate
- TORQUE-1.1
- TOSL
- UPL-1.0
- Unicode-TOU
- Unlicense
- VOSTROM
- VSL-1.0
- Vim
- W3C
- W3C-19980720
- WTFPL
- Watcom-1.0
- Wsuipa
- X11
- XFree86-1.1
- XSkat
- Xerox
- Xnet
- YPL-1.0
- YPL-1.1
- ZPL-1.1
- ZPL-2.0
- ZPL-2.1
- Zed
- Zend-2.0
- Zimbra-1.3
- Zimbra-1.4
- Zlib
- bzip2-1.0.5
- bzip2-1.0.6
- diffmark
- dvipdfm
- eGenix
- gSOAP-1.3b
- gnuplot
- iMatix
- libtiff
- mpich2
- psfrag
- psutils
- xinetd
- xpp
- zlib-acknowledgement
- ).freeze
+ LICENSE_IDENTIFIERS = %w[
+ 0BSD
+ AAL
+ ADSL
+ AFL-1.1
+ AFL-1.2
+ AFL-2.0
+ AFL-2.1
+ AFL-3.0
+ AGPL-1.0
+ AGPL-1.0-only
+ AGPL-1.0-or-later
+ AGPL-3.0
+ AGPL-3.0-only
+ AGPL-3.0-or-later
+ AMDPLPA
+ AML
+ AMPAS
+ ANTLR-PD
+ ANTLR-PD-fallback
+ APAFML
+ APL-1.0
+ APSL-1.0
+ APSL-1.1
+ APSL-1.2
+ APSL-2.0
+ Abstyles
+ Adobe-2006
+ Adobe-Glyph
+ Afmparse
+ Aladdin
+ Apache-1.0
+ Apache-1.1
+ Apache-2.0
+ Artistic-1.0
+ Artistic-1.0-Perl
+ Artistic-1.0-cl8
+ Artistic-2.0
+ BSD-1-Clause
+ BSD-2-Clause
+ BSD-2-Clause-FreeBSD
+ BSD-2-Clause-NetBSD
+ BSD-2-Clause-Patent
+ BSD-2-Clause-Views
+ BSD-3-Clause
+ BSD-3-Clause-Attribution
+ BSD-3-Clause-Clear
+ BSD-3-Clause-LBNL
+ BSD-3-Clause-Modification
+ BSD-3-Clause-No-Military-License
+ BSD-3-Clause-No-Nuclear-License
+ BSD-3-Clause-No-Nuclear-License-2014
+ BSD-3-Clause-No-Nuclear-Warranty
+ BSD-3-Clause-Open-MPI
+ BSD-4-Clause
+ BSD-4-Clause-Shortened
+ BSD-4-Clause-UC
+ BSD-Protection
+ BSD-Source-Code
+ BSL-1.0
+ BUSL-1.1
+ Bahyph
+ Barr
+ Beerware
+ BitTorrent-1.0
+ BitTorrent-1.1
+ BlueOak-1.0.0
+ Borceux
+ C-UDA-1.0
+ CAL-1.0
+ CAL-1.0-Combined-Work-Exception
+ CATOSL-1.1
+ CC-BY-1.0
+ CC-BY-2.0
+ CC-BY-2.5
+ CC-BY-3.0
+ CC-BY-3.0-AT
+ CC-BY-3.0-US
+ CC-BY-4.0
+ CC-BY-NC-1.0
+ CC-BY-NC-2.0
+ CC-BY-NC-2.5
+ CC-BY-NC-3.0
+ CC-BY-NC-4.0
+ CC-BY-NC-ND-1.0
+ CC-BY-NC-ND-2.0
+ CC-BY-NC-ND-2.5
+ CC-BY-NC-ND-3.0
+ CC-BY-NC-ND-3.0-IGO
+ CC-BY-NC-ND-4.0
+ CC-BY-NC-SA-1.0
+ CC-BY-NC-SA-2.0
+ CC-BY-NC-SA-2.5
+ CC-BY-NC-SA-3.0
+ CC-BY-NC-SA-4.0
+ CC-BY-ND-1.0
+ CC-BY-ND-2.0
+ CC-BY-ND-2.5
+ CC-BY-ND-3.0
+ CC-BY-ND-4.0
+ CC-BY-SA-1.0
+ CC-BY-SA-2.0
+ CC-BY-SA-2.0-UK
+ CC-BY-SA-2.1-JP
+ CC-BY-SA-2.5
+ CC-BY-SA-3.0
+ CC-BY-SA-3.0-AT
+ CC-BY-SA-4.0
+ CC-PDDC
+ CC0-1.0
+ CDDL-1.0
+ CDDL-1.1
+ CDL-1.0
+ CDLA-Permissive-1.0
+ CDLA-Sharing-1.0
+ CECILL-1.0
+ CECILL-1.1
+ CECILL-2.0
+ CECILL-2.1
+ CECILL-B
+ CECILL-C
+ CERN-OHL-1.1
+ CERN-OHL-1.2
+ CERN-OHL-P-2.0
+ CERN-OHL-S-2.0
+ CERN-OHL-W-2.0
+ CNRI-Jython
+ CNRI-Python
+ CNRI-Python-GPL-Compatible
+ CPAL-1.0
+ CPL-1.0
+ CPOL-1.02
+ CUA-OPL-1.0
+ Caldera
+ ClArtistic
+ Condor-1.1
+ Crossword
+ CrystalStacker
+ Cube
+ D-FSL-1.0
+ DOC
+ DRL-1.0
+ DSDP
+ Dotseqn
+ ECL-1.0
+ ECL-2.0
+ EFL-1.0
+ EFL-2.0
+ EPICS
+ EPL-1.0
+ EPL-2.0
+ EUDatagrid
+ EUPL-1.0
+ EUPL-1.1
+ EUPL-1.2
+ Entessa
+ ErlPL-1.1
+ Eurosym
+ FSFAP
+ FSFUL
+ FSFULLR
+ FTL
+ Fair
+ Frameworx-1.0
+ FreeBSD-DOC
+ FreeImage
+ GD
+ GFDL-1.1
+ GFDL-1.1-invariants-only
+ GFDL-1.1-invariants-or-later
+ GFDL-1.1-no-invariants-only
+ GFDL-1.1-no-invariants-or-later
+ GFDL-1.1-only
+ GFDL-1.1-or-later
+ GFDL-1.2
+ GFDL-1.2-invariants-only
+ GFDL-1.2-invariants-or-later
+ GFDL-1.2-no-invariants-only
+ GFDL-1.2-no-invariants-or-later
+ GFDL-1.2-only
+ GFDL-1.2-or-later
+ GFDL-1.3
+ GFDL-1.3-invariants-only
+ GFDL-1.3-invariants-or-later
+ GFDL-1.3-no-invariants-only
+ GFDL-1.3-no-invariants-or-later
+ GFDL-1.3-only
+ GFDL-1.3-or-later
+ GL2PS
+ GLWTPL
+ GPL-1.0
+ GPL-1.0+
+ GPL-1.0-only
+ GPL-1.0-or-later
+ GPL-2.0
+ GPL-2.0+
+ GPL-2.0-only
+ GPL-2.0-or-later
+ GPL-2.0-with-GCC-exception
+ GPL-2.0-with-autoconf-exception
+ GPL-2.0-with-bison-exception
+ GPL-2.0-with-classpath-exception
+ GPL-2.0-with-font-exception
+ GPL-3.0
+ GPL-3.0+
+ GPL-3.0-only
+ GPL-3.0-or-later
+ GPL-3.0-with-GCC-exception
+ GPL-3.0-with-autoconf-exception
+ Giftware
+ Glide
+ Glulxe
+ HPND
+ HPND-sell-variant
+ HTMLTIDY
+ HaskellReport
+ Hippocratic-2.1
+ IBM-pibs
+ ICU
+ IJG
+ IPA
+ IPL-1.0
+ ISC
+ ImageMagick
+ Imlib2
+ Info-ZIP
+ Intel
+ Intel-ACPI
+ Interbase-1.0
+ JPNIC
+ JSON
+ JasPer-2.0
+ LAL-1.2
+ LAL-1.3
+ LGPL-2.0
+ LGPL-2.0+
+ LGPL-2.0-only
+ LGPL-2.0-or-later
+ LGPL-2.1
+ LGPL-2.1+
+ LGPL-2.1-only
+ LGPL-2.1-or-later
+ LGPL-3.0
+ LGPL-3.0+
+ LGPL-3.0-only
+ LGPL-3.0-or-later
+ LGPLLR
+ LPL-1.0
+ LPL-1.02
+ LPPL-1.0
+ LPPL-1.1
+ LPPL-1.2
+ LPPL-1.3a
+ LPPL-1.3c
+ Latex2e
+ Leptonica
+ LiLiQ-P-1.1
+ LiLiQ-R-1.1
+ LiLiQ-Rplus-1.1
+ Libpng
+ Linux-OpenIB
+ MIT
+ MIT-0
+ MIT-CMU
+ MIT-Modern-Variant
+ MIT-advertising
+ MIT-enna
+ MIT-feh
+ MIT-open-group
+ MITNFA
+ MPL-1.0
+ MPL-1.1
+ MPL-2.0
+ MPL-2.0-no-copyleft-exception
+ MS-PL
+ MS-RL
+ MTLL
+ MakeIndex
+ MirOS
+ Motosoto
+ MulanPSL-1.0
+ MulanPSL-2.0
+ Multics
+ Mup
+ NAIST-2003
+ NASA-1.3
+ NBPL-1.0
+ NCGL-UK-2.0
+ NCSA
+ NGPL
+ NIST-PD
+ NIST-PD-fallback
+ NLOD-1.0
+ NLPL
+ NOSL
+ NPL-1.0
+ NPL-1.1
+ NPOSL-3.0
+ NRL
+ NTP
+ NTP-0
+ Naumen
+ Net-SNMP
+ NetCDF
+ Newsletr
+ Nokia
+ Noweb
+ Nunit
+ O-UDA-1.0
+ OCCT-PL
+ OCLC-2.0
+ ODC-By-1.0
+ ODbL-1.0
+ OFL-1.0
+ OFL-1.0-RFN
+ OFL-1.0-no-RFN
+ OFL-1.1
+ OFL-1.1-RFN
+ OFL-1.1-no-RFN
+ OGC-1.0
+ OGDL-Taiwan-1.0
+ OGL-Canada-2.0
+ OGL-UK-1.0
+ OGL-UK-2.0
+ OGL-UK-3.0
+ OGTSL
+ OLDAP-1.1
+ OLDAP-1.2
+ OLDAP-1.3
+ OLDAP-1.4
+ OLDAP-2.0
+ OLDAP-2.0.1
+ OLDAP-2.1
+ OLDAP-2.2
+ OLDAP-2.2.1
+ OLDAP-2.2.2
+ OLDAP-2.3
+ OLDAP-2.4
+ OLDAP-2.5
+ OLDAP-2.6
+ OLDAP-2.7
+ OLDAP-2.8
+ OML
+ OPL-1.0
+ OSET-PL-2.1
+ OSL-1.0
+ OSL-1.1
+ OSL-2.0
+ OSL-2.1
+ OSL-3.0
+ OpenSSL
+ PDDL-1.0
+ PHP-3.0
+ PHP-3.01
+ PSF-2.0
+ Parity-6.0.0
+ Parity-7.0.0
+ Plexus
+ PolyForm-Noncommercial-1.0.0
+ PolyForm-Small-Business-1.0.0
+ PostgreSQL
+ Python-2.0
+ QPL-1.0
+ Qhull
+ RHeCos-1.1
+ RPL-1.1
+ RPL-1.5
+ RPSL-1.0
+ RSA-MD
+ RSCPL
+ Rdisc
+ Ruby
+ SAX-PD
+ SCEA
+ SGI-B-1.0
+ SGI-B-1.1
+ SGI-B-2.0
+ SHL-0.5
+ SHL-0.51
+ SISSL
+ SISSL-1.2
+ SMLNJ
+ SMPPL
+ SNIA
+ SPL-1.0
+ SSH-OpenSSH
+ SSH-short
+ SSPL-1.0
+ SWL
+ Saxpath
+ Sendmail
+ Sendmail-8.23
+ SimPL-2.0
+ Sleepycat
+ Spencer-86
+ Spencer-94
+ Spencer-99
+ StandardML-NJ
+ SugarCRM-1.1.3
+ TAPR-OHL-1.0
+ TCL
+ TCP-wrappers
+ TMate
+ TORQUE-1.1
+ TOSL
+ TU-Berlin-1.0
+ TU-Berlin-2.0
+ UCL-1.0
+ UPL-1.0
+ Unicode-DFS-2015
+ Unicode-DFS-2016
+ Unicode-TOU
+ Unlicense
+ VOSTROM
+ VSL-1.0
+ Vim
+ W3C
+ W3C-19980720
+ W3C-20150513
+ WTFPL
+ Watcom-1.0
+ Wsuipa
+ X11
+ XFree86-1.1
+ XSkat
+ Xerox
+ Xnet
+ YPL-1.0
+ YPL-1.1
+ ZPL-1.1
+ ZPL-2.0
+ ZPL-2.1
+ Zed
+ Zend-2.0
+ Zimbra-1.3
+ Zimbra-1.4
+ Zlib
+ blessing
+ bzip2-1.0.5
+ bzip2-1.0.6
+ copyleft-next-0.3.0
+ copyleft-next-0.3.1
+ curl
+ diffmark
+ dvipdfm
+ eCos-2.0
+ eGenix
+ etalab-2.0
+ gSOAP-1.3b
+ gnuplot
+ iMatix
+ libpng-2.0
+ libselinux-1.0
+ libtiff
+ mpich2
+ psfrag
+ psutils
+ wxWindows
+ xinetd
+ xpp
+ zlib-acknowledgement
+ ].freeze
+
+ # exception identifiers
+ EXCEPTION_IDENTIFIERS = %w[
+ 389-exception
+ Autoconf-exception-2.0
+ Autoconf-exception-3.0
+ Bison-exception-2.2
+ Bootloader-exception
+ CLISP-exception-2.0
+ Classpath-exception-2.0
+ DigiRule-FOSS-exception
+ FLTK-exception
+ Fawkes-Runtime-exception
+ Font-exception-2.0
+ GCC-exception-2.0
+ GCC-exception-3.1
+ GPL-3.0-linking-exception
+ GPL-3.0-linking-source-exception
+ GPL-CC-1.0
+ LGPL-3.0-linking-exception
+ LLVM-exception
+ LZMA-exception
+ Libtool-exception
+ Linux-syscall-note
+ Nokia-Qt-exception-1.1
+ OCCT-exception-1.0
+ OCaml-LGPL-linking-exception
+ OpenJDK-assembly-exception-1.0
+ PS-or-PDF-font-exception-20170817
+ Qt-GPL-exception-1.0
+ Qt-LGPL-exception-1.1
+ Qwt-exception-1.0
+ SHL-2.0
+ SHL-2.1
+ Swift-exception
+ Universal-FOSS-exception-1.0
+ WxWindows-exception-3.1
+ eCos-exception-2.0
+ freertos-exception-2.0
+ gnu-javamail-exception
+ i2p-gpl-java-exception
+ mif-exception
+ openvpn-openssl-exception
+ u-boot-exception-2.0
+ ].freeze
REGEXP = %r{
\A
- (
- #{Regexp.union(IDENTIFIERS)}
+ (?:
+ #{Regexp.union(LICENSE_IDENTIFIERS)}
\+?
- (\s WITH \s .+)?
+ (?:\s WITH \s #{Regexp.union(EXCEPTION_IDENTIFIERS)})?
| #{NONSTANDARD}
+ | #{LICENSE_REF}
)
\Z
}ox.freeze
@@ -333,7 +534,7 @@ class Gem::Licenses
end
def self.suggestions(license)
- by_distance = IDENTIFIERS.group_by do |identifier|
+ by_distance = LICENSE_IDENTIFIERS.group_by do |identifier|
levenshtein_distance(identifier, license)
end
lowest = by_distance.keys.min
diff --git a/lib/rubygems/util/list.rb b/lib/rubygems/util/list.rb
index 9c25f6b6dc..33c40af4bb 100644
--- a/lib/rubygems/util/list.rb
+++ b/lib/rubygems/util/list.rb
@@ -25,7 +25,7 @@ module Gem
List.new value, self
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.pp to_a
end
diff --git a/lib/rubygems/validator.rb b/lib/rubygems/validator.rb
index 83448229bb..728595e778 100644
--- a/lib/rubygems/validator.rb
+++ b/lib/rubygems/validator.rb
@@ -5,50 +5,26 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems/package'
-require 'rubygems/installer'
+require_relative 'package'
+require_relative 'installer'
##
# Validator performs various gem file and gem database validation
class Gem::Validator
-
include Gem::UserInteraction
def initialize # :nodoc:
require 'find'
end
- ##
- # Given a gem file's contents, validates against its own MD5 checksum
- # gem_data:: [String] Contents of the gem file
-
- def verify_gem(gem_data)
- # TODO remove me? The code here only validate an MD5SUM that was
- # in some old formatted gems, but hasn't been for a long time.
- end
-
- ##
- # Given the path to a gem file, validates against its own MD5 checksum
- #
- # gem_path:: [String] Path to gem file
-
- def verify_gem_file(gem_path)
- open gem_path, Gem.binary_mode do |file|
- gem_data = file.read
- verify_gem gem_data
- end
- rescue Errno::ENOENT, Errno::EINVAL
- raise Gem::VerificationError, "missing gem file #{gem_path}"
- end
-
private
def find_files_for_gem(gem_directory)
installed_files = []
Find.find gem_directory do |file_name|
- fn = file_name[gem_directory.size..file_name.size-1].sub(/^\//, "")
+ fn = file_name[gem_directory.size..file_name.size - 1].sub(/^\//, "")
installed_files << fn unless
fn =~ /CVS/ || fn.empty? || File.directory?(file_name)
end
@@ -62,7 +38,7 @@ class Gem::Validator
# Describes a problem with a file in a gem.
ErrorData = Struct.new :path, :problem do
- def <=> other # :nodoc:
+ def <=>(other) # :nodoc:
return nil unless self.class === other
[path, problem] <=> [other.path, other.problem]
@@ -83,7 +59,7 @@ class Gem::Validator
# TODO needs further cleanup
def alien(gems=[])
- errors = Hash.new { |h,k| h[k] = {} }
+ errors = Hash.new {|h,k| h[k] = {} }
Gem::Specification.each do |spec|
next unless gems.include? spec.name unless gems.empty?
@@ -94,35 +70,37 @@ class Gem::Validator
spec_path = spec.spec_file
gem_directory = spec.full_gem_path
- unless File.directory? gem_directory then
+ unless File.directory? gem_directory
errors[gem_name][spec.full_name] =
"Gem registered but doesn't exist at #{gem_directory}"
next
end
- unless File.exist? spec_path then
+ unless File.exist? spec_path
errors[gem_name][spec_path] = "Spec file missing for installed gem"
end
begin
- verify_gem_file(gem_path)
+ unless File.readable?(gem_path)
+ raise Gem::VerificationError, "missing gem file #{gem_path}"
+ end
good, gone, unreadable = nil, nil, nil, nil
- open gem_path, Gem.binary_mode do |file|
+ File.open gem_path, Gem.binary_mode do |file|
package = Gem::Package.new gem_path
- good, gone = package.contents.partition { |file_name|
+ good, gone = package.contents.partition do |file_name|
File.exist? File.join(gem_directory, file_name)
- }
+ end
gone.sort.each do |path|
errors[gem_name][path] = "Missing file"
end
- good, unreadable = good.partition { |file_name|
+ good, unreadable = good.partition do |file_name|
File.readable? File.join(gem_directory, file_name)
- }
+ end
unreadable.sort.each do |path|
errors[gem_name][path] = "Unreadable file"
@@ -134,8 +112,8 @@ class Gem::Validator
source = File.join gem_directory, entry['path']
- open source, Gem.binary_mode do |f|
- unless f.read == data then
+ File.open source, Gem.binary_mode do |f|
+ unless f.read == data
errors[gem_name][entry['path']] = "Modified from original"
end
end
@@ -163,4 +141,3 @@ class Gem::Validator
errors
end
end
-
diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb
index ff5c1c1e72..20bbff4fdd 100644
--- a/lib/rubygems/version.rb
+++ b/lib/rubygems/version.rb
@@ -150,12 +150,12 @@
# a zero to give a sensible result.
class Gem::Version
- autoload :Requirement, 'rubygems/requirement'
+ autoload :Requirement, File.expand_path('requirement', __dir__)
include Comparable
- VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
- ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/ # :nodoc:
+ VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?'.freeze # :nodoc:
+ ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze # :nodoc:
##
# A string representation of this Version.
@@ -169,7 +169,11 @@ class Gem::Version
##
# True if the +version+ string matches RubyGems' requirements.
- def self.correct? version
+ def self.correct?(version)
+ unless Gem::Deprecate.skip
+ warn "nil versions are discouraged and will be deprecated in Rubygems 4" if version.nil?
+ end
+
!!(version.to_s =~ ANCHORED_VERSION_PATTERN)
end
@@ -181,10 +185,10 @@ class Gem::Version
# ver2 = Version.create(ver1) # -> (ver1)
# ver3 = Version.create(nil) # -> nil
- def self.create input
- if self === input then # check yourself before you wreck yourself
+ def self.create(input)
+ if self === input # check yourself before you wreck yourself
input
- elsif input.nil? then
+ elsif input.nil?
nil
else
new input
@@ -192,8 +196,10 @@ class Gem::Version
end
@@all = {}
+ @@bump = {}
+ @@release = {}
- def self.new version # :nodoc:
+ def self.new(version) # :nodoc:
return super unless Gem::Version == self
@@all[version] ||= super
@@ -203,13 +209,13 @@ class Gem::Version
# Constructs a Version from the +version+ string. A version string is a
# series of digits or ASCII letters separated by dots.
- def initialize version
+ def initialize(version)
unless self.class.correct?(version)
raise ArgumentError, "Malformed version number string #{version}"
end
# If version is an empty string convert it to 0
- version = 0 if version =~ /\A\s*\Z/
+ version = 0 if version.is_a?(String) && version =~ /\A\s*\Z/
@version = version.to_s.strip.gsub("-",".pre.")
@segments = nil
@@ -222,21 +228,21 @@ class Gem::Version
# Pre-release (alpha) parts, e.g, 5.3.1.b.2 => 5.4, are ignored.
def bump
- @bump ||= begin
- segments = self.segments
- segments.pop while segments.any? { |s| String === s }
- segments.pop if segments.size > 1
-
- segments[-1] = segments[-1].succ
- self.class.new segments.join(".")
- end
+ @@bump[self] ||= begin
+ segments = self.segments
+ segments.pop while segments.any? {|s| String === s }
+ segments.pop if segments.size > 1
+
+ segments[-1] = segments[-1].succ
+ self.class.new segments.join(".")
+ end
end
##
# A Version is only eql? to another version if it's specified to the
# same precision. Version "1.0" is not the same as version "1".
- def eql? other
+ def eql?(other)
self.class === other and @version == other._version
end
@@ -244,7 +250,7 @@ class Gem::Version
canonical_segments.hash
end
- def init_with coder # :nodoc:
+ def init_with(coder) # :nodoc:
yaml_initialize coder.tag, coder.map
end
@@ -264,7 +270,7 @@ class Gem::Version
# Load custom marshal format. It's a string for backwards (RubyGems
# 1.3.5 and earlier) compatibility.
- def marshal_load array
+ def marshal_load(array)
initialize array[0]
end
@@ -278,7 +284,7 @@ class Gem::Version
["@version"]
end
- def encode_with coder # :nodoc:
+ def encode_with(coder) # :nodoc:
coder.add 'version', @version
end
@@ -292,7 +298,7 @@ class Gem::Version
@prerelease
end
- def pretty_print q # :nodoc:
+ def pretty_print(q) # :nodoc:
q.text "Gem::Version.new(#{version.inspect})"
end
@@ -301,13 +307,13 @@ class Gem::Version
# Non-prerelease versions return themselves.
def release
- @release ||= if prerelease?
- segments = self.segments
- segments.pop while segments.any? { |s| String === s }
- self.class.new segments.join('.')
- else
- self
- end
+ @@release[self] ||= if prerelease?
+ segments = self.segments
+ segments.pop while segments.any? {|s| String === s }
+ self.class.new segments.join('.')
+ else
+ self
+ end
end
def segments # :nodoc:
@@ -320,11 +326,13 @@ class Gem::Version
def approximate_recommendation
segments = self.segments
- segments.pop while segments.any? { |s| String === s }
+ segments.pop while segments.any? {|s| String === s }
segments.pop while segments.size > 2
segments.push 0 while segments.size < 2
- "~> #{segments.join(".")}"
+ recommendation = "~> #{segments.join(".")}"
+ recommendation += ".a" if prerelease?
+ recommendation
end
##
@@ -333,12 +341,12 @@ class Gem::Version
# one. Attempts to compare to something that's not a
# <tt>Gem::Version</tt> return +nil+.
- def <=> other
+ def <=>(other)
return unless Gem::Version === other
return 0 if @version == other._version || canonical_segments == other.canonical_segments
- lhsegments = _segments
- rhsegments = other._segments
+ lhsegments = canonical_segments
+ rhsegments = other.canonical_segments
lhsize = lhsegments.size
rhsize = rhsegments.size
@@ -367,6 +375,12 @@ class Gem::Version
end.reduce(&:concat)
end
+ def freeze
+ prerelease?
+ canonical_segments
+ super
+ end
+
protected
def _version
@@ -385,7 +399,7 @@ class Gem::Version
def _split_segments
string_start = _segments.index {|s| s.is_a?(String) }
- string_segments = segments
+ string_segments = segments
numeric_segments = string_segments.slice!(0, string_start || string_segments.size)
return numeric_segments, string_segments
end
diff --git a/lib/rubygems/version_option.rb b/lib/rubygems/version_option.rb
index c4d3306652..1db382fa7f 100644
--- a/lib/rubygems/version_option.rb
+++ b/lib/rubygems/version_option.rb
@@ -5,7 +5,7 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems'
+require_relative '../rubygems'
##
# Mixin methods for --version and --platform Gem::Command options.
@@ -16,8 +16,8 @@ module Gem::VersionOption
# Add the --platform option to the option parser.
def add_platform_option(task = command, *wrap)
- OptionParser.accept Gem::Platform do |value|
- if value == Gem::Platform::RUBY then
+ Gem::OptionParser.accept Gem::Platform do |value|
+ if value == Gem::Platform::RUBY
value
else
Gem::Platform.new value
@@ -27,7 +27,7 @@ module Gem::VersionOption
add_option('--platform PLATFORM', Gem::Platform,
"Specify the platform of gem to #{task}", *wrap) do
|value, options|
- unless options[:added_platform] then
+ unless options[:added_platform]
Gem.platforms = [Gem::Platform::RUBY]
options[:added_platform] = true
end
@@ -51,7 +51,7 @@ module Gem::VersionOption
# Add the --version option to the option parser.
def add_version_option(task = command, *wrap)
- OptionParser.accept Gem::Requirement do |value|
+ Gem::OptionParser.accept Gem::Requirement do |value|
Gem::Requirement.new(*value.split(/\s*,\s*/))
end
@@ -73,5 +73,10 @@ module Gem::VersionOption
end
end
-end
+ ##
+ # Extract platform given on the command line
+ def get_platform_from_requirements(requirements)
+ Gem.platforms[1].to_s if requirements.key? :added_platform
+ end
+end
diff --git a/lib/scanf.gemspec b/lib/scanf.gemspec
deleted file mode 100644
index d861f78e28..0000000000
--- a/lib/scanf.gemspec
+++ /dev/null
@@ -1,25 +0,0 @@
-# coding: utf-8
-# frozen_string_literal: true
-
-Gem::Specification.new do |spec|
- spec.name = "scanf"
- spec.version = "0.0.1"
- spec.date = '2017-02-14'
- spec.authors = ["David Alan Black"]
- spec.email = ['dblack@superlink.net']
-
- spec.summary = "scanf is an implementation of the C function scanf(3)."
- spec.description = "scanf is an implementation of the C function scanf(3)."
- spec.homepage = "https://github.com/ruby/scanf"
- spec.license = "BSD-2-Clause"
-
- spec.files = ["lib/scanf.rb"]
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
- spec.required_ruby_version = ">= 2.5.0dev"
-
- spec.add_development_dependency "bundler", "~> 1.14"
- spec.add_development_dependency "rake", "~> 10.0"
- spec.add_development_dependency "test-unit"
-end
diff --git a/lib/scanf.rb b/lib/scanf.rb
deleted file mode 100644
index a98c359573..0000000000
--- a/lib/scanf.rb
+++ /dev/null
@@ -1,776 +0,0 @@
-# frozen_string_literal: false
-# scanf for Ruby
-#
-#--
-# $Release Version: 1.1.2 $
-# $Revision$
-# $Id$
-# $Author$
-#++
-#
-# == Description
-#
-# scanf is an implementation of the C function scanf(3), modified as necessary
-# for Ruby compatibility.
-#
-# the methods provided are String#scanf, IO#scanf, and
-# Kernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf. IO#scanf
-# can be used on any IO stream, including file handles and sockets.
-# scanf can be called either with or without a block.
-#
-# Scanf scans an input string or stream according to a <b>format</b>, as
-# described below in Conversions, and returns an array of matches between
-# the format and the input. The format is defined in a string, and is
-# similar (though not identical) to the formats used in Kernel#printf and
-# Kernel#sprintf.
-#
-# The format may contain <b>conversion specifiers</b>, which tell scanf
-# what form (type) each particular matched substring should be converted
-# to (e.g., decimal integer, floating point number, literal string,
-# etc.) The matches and conversions take place from left to right, and
-# the conversions themselves are returned as an array.
-#
-# The format string may also contain characters other than those in the
-# conversion specifiers. White space (blanks, tabs, or newlines) in the
-# format string matches any amount of white space, including none, in
-# the input. Everything else matches only itself.
-#
-# Scanning stops, and scanf returns, when any input character fails to
-# match the specifications in the format string, or when input is
-# exhausted, or when everything in the format string has been
-# matched. All matches found up to the stopping point are returned in
-# the return array (or yielded to the block, if a block was given).
-#
-#
-# == Basic usage
-#
-# require 'scanf'
-#
-# # String#scanf and IO#scanf take a single argument, the format string
-# array = a_string.scanf("%d%s")
-# array = an_io.scanf("%d%s")
-#
-# # Kernel#scanf reads from STDIN
-# array = scanf("%d%s")
-#
-# == Block usage
-#
-# When called with a block, scanf keeps scanning the input, cycling back
-# to the beginning of the format string, and yields a new array of
-# conversions to the block every time the format string is matched
-# (including partial matches, but not including complete failures). The
-# actual return value of scanf when called with a block is an array
-# containing the results of all the executions of the block.
-#
-# str = "123 abc 456 def 789 ghi"
-# str.scanf("%d%s") { |num,str| [ num * 2, str.upcase ] }
-# # => [[246, "ABC"], [912, "DEF"], [1578, "GHI"]]
-#
-# == Conversions
-#
-# The single argument to scanf is a format string, which generally
-# includes one or more conversion specifiers. Conversion specifiers
-# begin with the percent character ('%') and include information about
-# what scanf should next scan for (string, decimal number, single
-# character, etc.).
-#
-# There may be an optional maximum field width, expressed as a decimal
-# integer, between the % and the conversion. If no width is given, a
-# default of `infinity' is used (with the exception of the %c specifier;
-# see below). Otherwise, given a field width of <em>n</em> for a given
-# conversion, at most <em>n</em> characters are scanned in processing
-# that conversion. Before conversion begins, most conversions skip
-# white space in the input string; this white space is not counted
-# against the field width.
-#
-# The following conversions are available.
-#
-# [%]
-# Matches a literal `%'. That is, `%%' in the format string matches a
-# single input `%' character. No conversion is done, and the resulting
-# '%' is not included in the return array.
-#
-# [d]
-# Matches an optionally signed decimal integer.
-#
-# [u]
-# Same as d.
-#
-# [i]
-# Matches an optionally signed integer. The integer is read in base
-# 16 if it begins with `0x' or `0X', in base 8 if it begins with `0',
-# and in base 10 other- wise. Only characters that correspond to the
-# base are recognized.
-#
-# [o]
-# Matches an optionally signed octal integer.
-#
-# [x, X]
-# Matches an optionally signed hexadecimal integer,
-#
-# [a, e, f, g, A, E, F, G]
-# Matches an optionally signed floating-point number.
-#
-# [s]
-# Matches a sequence of non-white-space character. The input string stops at
-# white space or at the maximum field width, whichever occurs first.
-#
-# [c]
-# Matches a single character, or a sequence of <em>n</em> characters if a
-# field width of <em>n</em> is specified. The usual skip of leading white
-# space is suppressed. To skip white space first, use an explicit space in
-# the format.
-#
-# [[]
-# Matches a nonempty sequence of characters from the specified set
-# of accepted characters. The usual skip of leading white space is
-# suppressed. This bracketed sub-expression is interpreted exactly like a
-# character class in a Ruby regular expression. (In fact, it is placed as-is
-# in a regular expression.) The matching against the input string ends with
-# the appearance of a character not in (or, with a circumflex, in) the set,
-# or when the field width runs out, whichever comes first.
-#
-# === Assignment suppression
-#
-# To require that a particular match occur, but without including the result
-# in the return array, place the <b>assignment suppression flag</b>, which is
-# the star character ('*'), immediately after the leading '%' of a format
-# specifier (just before the field width, if any).
-#
-# == scanf for Ruby compared with scanf in C
-#
-# scanf for Ruby is based on the C function scanf(3), but with modifications,
-# dictated mainly by the underlying differences between the languages.
-#
-# === Unimplemented flags and specifiers
-#
-# * The only flag implemented in scanf for Ruby is '<tt>*</tt>' (ignore
-# upcoming conversion). Many of the flags available in C versions of
-# scanf(3) have to do with the type of upcoming pointer arguments, and are
-# meaningless in Ruby.
-#
-# * The <tt>n</tt> specifier (store number of characters consumed so far in
-# next pointer) is not implemented.
-#
-# * The <tt>p</tt> specifier (match a pointer value) is not implemented.
-#
-# === Altered specifiers
-#
-# [o, u, x, X]
-# In scanf for Ruby, all of these specifiers scan for an optionally signed
-# integer, rather than for an unsigned integer like their C counterparts.
-#
-# === Return values
-#
-# scanf for Ruby returns an array of successful conversions, whereas
-# scanf(3) returns the number of conversions successfully
-# completed. (See below for more details on scanf for Ruby's return
-# values.)
-#
-# == Return values
-#
-# Without a block, scanf returns an array containing all the conversions
-# it has found. If none are found, scanf will return an empty array. An
-# unsuccessful match is never ignored, but rather always signals the end
-# of the scanning operation. If the first unsuccessful match takes place
-# after one or more successful matches have already taken place, the
-# returned array will contain the results of those successful matches.
-#
-# With a block scanf returns a 'map'-like array of transformations from
-# the block -- that is, an array reflecting what the block did with each
-# yielded result from the iterative scanf operation. (See "Block
-# usage", above.)
-#
-# == Current limitations and bugs
-#
-# When using IO#scanf under Windows, make sure you open your files in
-# binary mode:
-#
-# File.open("filename", "rb")
-#
-# so that scanf can keep track of characters correctly.
-#
-# Support for character classes is reasonably complete (since it
-# essentially piggy-backs on Ruby's regular expression handling of
-# character classes), but users are advised that character class testing
-# has not been exhaustive, and that they should exercise some caution
-# in using any of the more complex and/or arcane character class
-# idioms.
-#
-# == License and copyright
-#
-# Copyright:: (c) 2002-2003 David Alan Black
-# License:: Distributed on the same licensing terms as Ruby itself
-#
-# == Warranty disclaimer
-#
-# This software is provided "as is" and without any express or implied
-# warranties, including, without limitation, the implied warranties of
-# merchantability and fitness for a particular purpose.
-#
-# == Credits and acknowledgements
-#
-# scanf was developed as the major activity of the Austin Ruby Codefest
-# (Austin, Texas, August 2002).
-#
-# Principal author:: David Alan Black (mailto:dblack@superlink.net)
-# Co-author:: Hal Fulton (mailto:hal9000@hypermetrics.com)
-# Project contributors:: Nolan Darilek, Jason Johnston
-#
-# Thanks to Hal Fulton for hosting the Codefest.
-#
-# Thanks to Matz for suggestions about the class design.
-#
-# Thanks to Gavin Sinclair for some feedback on the documentation.
-#
-# The text for parts of this document, especially the Description and
-# Conversions sections, above, were adapted from the Linux Programmer's
-# Manual manpage for scanf(3), dated 1995-11-01.
-#
-# == Bugs and bug reports
-#
-# scanf for Ruby is based on something of an amalgam of C scanf
-# implementations and documentation, rather than on a single canonical
-# description. Suggestions for features and behaviors which appear in
-# other scanfs, and would be meaningful in Ruby, are welcome, as are
-# reports of suspicious behaviors and/or bugs. (Please see "Credits and
-# acknowledgements", above, for email addresses.)
-
-module Scanf
- # :stopdoc:
-
- # ==Technical notes
- #
- # ===Rationale behind scanf for Ruby
- #
- # The impetus for a scanf implementation in Ruby comes chiefly from the fact
- # that existing pattern matching operations, such as Regexp#match and
- # String#scan, return all results as strings, which have to be converted to
- # integers or floats explicitly in cases where what's ultimately wanted are
- # integer or float values.
- #
- # ===Design of scanf for Ruby
- #
- # scanf for Ruby is essentially a <format string>-to-<regular
- # expression> converter.
- #
- # When scanf is called, a FormatString object is generated from the
- # format string ("%d%s...") argument. The FormatString object breaks the
- # format string down into atoms ("%d", "%5f", "blah", etc.), and from
- # each atom it creates a FormatSpecifier object, which it
- # saves.
- #
- # Each FormatSpecifier has a regular expression fragment and a "handler"
- # associated with it. For example, the regular expression fragment
- # associated with the format "%d" is "([-+]?\d+)", and the handler
- # associated with it is a wrapper around String#to_i. scanf itself calls
- # FormatString#match, passing in the input string. FormatString#match
- # iterates through its FormatSpecifiers; for each one, it matches the
- # corresponding regular expression fragment against the string. If
- # there's a match, it sends the matched string to the handler associated
- # with the FormatSpecifier.
- #
- # Thus, to follow up the "%d" example: if "123" occurs in the input
- # string when a FormatSpecifier consisting of "%d" is reached, the "123"
- # will be matched against "([-+]?\d+)", and the matched string will be
- # rendered into an integer by a call to to_i.
- #
- # The rendered match is then saved to an accumulator array, and the
- # input string is reduced to the post-match substring. Thus the string
- # is "eaten" from the left as the FormatSpecifiers are applied in
- # sequence. (This is done to a duplicate string; the original string is
- # not altered.)
- #
- # As soon as a regular expression fragment fails to match the string, or
- # when the FormatString object runs out of FormatSpecifiers, scanning
- # stops and results accumulated so far are returned in an array.
-
- class FormatSpecifier
-
- attr_reader :re_string, :matched_string, :conversion, :matched
-
- private
-
- def skip; /^\s*%\*/.match(@spec_string); end
-
- def extract_float(s)
- return nil unless s &&! skip
- if /\A(?<sign>[-+]?)0[xX](?<frac>\.\h+|\h+(?:\.\h*)?)[pP](?<exp>[-+]\d+)/ =~ s
- f1, f2 = frac.split('.')
- f = f1.hex
- if f2
- len = f2.length
- if len > 0
- f += f2.hex / (16.0 ** len)
- end
- end
- (sign == ?- ? -1 : 1) * Math.ldexp(f, exp.to_i)
- elsif /\A([-+]?\d+)\.([eE][-+]\d+)/ =~ s
- ($1 << $2).to_f
- else
- s.to_f
- end
- end
- def extract_decimal(s); s.to_i if s &&! skip; end
- def extract_hex(s); s.hex if s &&! skip; end
- def extract_octal(s); s.oct if s &&! skip; end
- def extract_integer(s); Integer(s) if s &&! skip; end
- def extract_plain(s); s unless skip; end
-
- def nil_proc(s); nil; end
-
- public
-
- def to_s
- @spec_string
- end
-
- def count_space?
- /(?:\A|\S)%\*?\d*c|%\d*\[/.match(@spec_string)
- end
-
- def initialize(str)
- @spec_string = str
- h = '[A-Fa-f0-9]'
-
- @re_string, @handler =
- case @spec_string
-
- # %[[:...:]]
- when /%\*?(\[\[:[a-z]+:\]\])/
- [ "(#{$1}+)", :extract_plain ]
-
- # %5[[:...:]]
- when /%\*?(\d+)(\[\[:[a-z]+:\]\])/
- [ "(#{$2}{1,#{$1}})", :extract_plain ]
-
- # %[...]
- when /%\*?\[([^\]]*)\]/
- yes = $1
- if /^\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end
- [ "([#{yes}]+)(?=[#{no}]|\\z)", :extract_plain ]
-
- # %5[...]
- when /%\*?(\d+)\[([^\]]*)\]/
- yes = $2
- w = $1
- [ "([#{yes}]{1,#{w}})", :extract_plain ]
-
- # %i
- when /%\*?i/
- [ "([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\d*)))", :extract_integer ]
-
- # %5i
- when /%\*?(\d+)i/
- n = $1.to_i
- s = "("
- if n > 1 then s += "[1-9]\\d{1,#{n-1}}|" end
- if n > 1 then s += "0[0-7]{1,#{n-1}}|" end
- if n > 2 then s += "[-+]0[0-7]{1,#{n-2}}|" end
- if n > 2 then s += "[-+][1-9]\\d{1,#{n-2}}|" end
- if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
- if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
- s += "\\d"
- s += ")"
- [ s, :extract_integer ]
-
- # %d, %u
- when /%\*?[du]/
- [ '([-+]?\d+)', :extract_decimal ]
-
- # %5d, %5u
- when /%\*?(\d+)[du]/
- n = $1.to_i
- s = "("
- if n > 1 then s += "[-+]\\d{1,#{n-1}}|" end
- s += "\\d{1,#{$1}})"
- [ s, :extract_decimal ]
-
- # %x
- when /%\*?[Xx]/
- [ "([-+]?(?:0[Xx])?#{h}+)", :extract_hex ]
-
- # %5x
- when /%\*?(\d+)[Xx]/
- n = $1.to_i
- s = "("
- if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
- if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
- if n > 1 then s += "[-+]#{h}{1,#{n-1}}|" end
- s += "#{h}{1,#{n}}"
- s += ")"
- [ s, :extract_hex ]
-
- # %o
- when /%\*?o/
- [ '([-+]?[0-7]+)', :extract_octal ]
-
- # %5o
- when /%\*?(\d+)o/
- [ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ]
-
- # %f
- when /%\*?[aefgAEFG]/
- [ '([-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))', :extract_float ]
-
- # %5f
- when /%\*?(\d+)[aefgAEFG]/
- [ '(?=[-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))' +
- "(\\S{1,#{$1}})", :extract_float ]
-
- # %5s
- when /%\*?(\d+)s/
- [ "(\\S{1,#{$1}})", :extract_plain ]
-
- # %s
- when /%\*?s/
- [ '(\S+)', :extract_plain ]
-
- # %c
- when /\s%\*?c/
- [ "\\s*(.)", :extract_plain ]
-
- # %c
- when /%\*?c/
- [ "(.)", :extract_plain ]
-
- # %5c (whitespace issues are handled by the count_*_space? methods)
- when /%\*?(\d+)c/
- [ "(.{1,#{$1}})", :extract_plain ]
-
- # %%
- when /%%/
- [ '(\s*%)', :nil_proc ]
-
- # literal characters
- else
- [ "(#{Regexp.escape(@spec_string)})", :nil_proc ]
- end
-
- @re_string = '\A' + @re_string
- end
-
- def to_re
- Regexp.new(@re_string,Regexp::MULTILINE)
- end
-
- def match(str)
- @matched = false
- s = str.dup
- s.sub!(/\A\s+/,'') unless count_space?
- res = to_re.match(s)
- if res
- @conversion = send(@handler, res[1])
- @matched_string = @conversion.to_s
- @matched = true
- end
- res
- end
-
- def letter
- @spec_string[/%\*?\d*([a-z\[])/, 1]
- end
-
- def width
- @spec_string[/%\*?(\d+)/, 1]&.to_i
- end
-
- def mid_match?
- return false unless @matched
- cc_no_width = letter == '[' &&! width
- c_or_cc_width = (letter == 'c' || letter == '[') && width
- width_left = c_or_cc_width && (matched_string.size < width)
-
- return width_left || cc_no_width
- end
-
- end
-
- class FormatString
-
- attr_reader :string_left, :last_spec_tried,
- :last_match_tried, :matched_count, :space
-
- SPECIFIERS = 'diuXxofFeEgGscaA'
- REGEX = /
- # possible space, followed by...
- (?:\s*
- # percent sign, followed by...
- %
- # another percent sign, or...
- (?:%|
- # optional assignment suppression flag
- \*?
- # optional maximum field width
- \d*
- # named character class, ...
- (?:\[\[:\w+:\]\]|
- # traditional character class, or...
- \[[^\]]*\]|
- # specifier letter.
- [#{SPECIFIERS}])))|
- # or miscellaneous characters
- [^%\s]+/ix
-
- def initialize(str)
- @specs = []
- @i = 1
- s = str.to_s
- return unless /\S/.match(s)
- @space = true if /\s\z/.match(s)
- @specs.replace s.scan(REGEX).map {|spec| FormatSpecifier.new(spec) }
- end
-
- def to_s
- @specs.join('')
- end
-
- def prune(n=matched_count)
- n.times { @specs.shift }
- end
-
- def spec_count
- @specs.size
- end
-
- def last_spec
- @i == spec_count - 1
- end
-
- def match(str)
- accum = []
- @string_left = str
- @matched_count = 0
-
- @specs.each_with_index do |spec,i|
- @i=i
- @last_spec_tried = spec
- @last_match_tried = spec.match(@string_left)
- break unless @last_match_tried
- @matched_count += 1
-
- accum << spec.conversion
-
- @string_left = @last_match_tried.post_match
- break if @string_left.empty?
- end
- return accum.compact
- end
- end
- # :startdoc:
-end
-
-class IO
-
- #:stopdoc:
- # The trick here is doing a match where you grab one *line*
- # of input at a time. The linebreak may or may not occur
- # at the boundary where the string matches a format specifier.
- # And if it does, some rule about whitespace may or may not
- # be in effect...
- #
- # That's why this is much more elaborate than the string
- # version.
- #
- # For each line:
- #
- # Match succeeds (non-emptily)
- # and the last attempted spec/string sub-match succeeded:
- #
- # could the last spec keep matching?
- # yes: save interim results and continue (next line)
- #
- # The last attempted spec/string did not match:
- #
- # are we on the next-to-last spec in the string?
- # yes:
- # is fmt_string.string_left all spaces?
- # yes: does current spec care about input space?
- # yes: fatal failure
- # no: save interim results and continue
- # no: continue [this state could be analyzed further]
- #
- #:startdoc:
-
- # Scans the current string until the match is exhausted,
- # yielding each match as it is encountered in the string.
- # A block is not necessary though, as the results will simply
- # be aggregated into the final array.
- #
- # "123 456".block_scanf("%d")
- # # => [123, 456]
- #
- # If a block is given, the value from that is returned from
- # the yield is added to an output array.
- #
- # "123 456".block_scanf("%d") do |digit,| # the ',' unpacks the Array
- # digit + 100
- # end
- # # => [223, 556]
- #
- # See Scanf for details on creating a format string.
- #
- # You will need to require 'scanf' to use IO#scanf.
- def scanf(str,&b) #:yield: current_match
- return block_scanf(str,&b) if b
- return [] unless str.size > 0
-
- start_position = pos rescue 0
- matched_so_far = 0
- source_buffer = ""
- result_buffer = []
- final_result = []
-
- fstr = Scanf::FormatString.new(str)
-
- loop do
- if eof || (tty? &&! fstr.match(source_buffer))
- final_result.concat(result_buffer)
- break
- end
-
- source_buffer << gets
-
- current_match = fstr.match(source_buffer)
-
- spec = fstr.last_spec_tried
-
- if spec.matched
- if spec.mid_match?
- result_buffer.replace(current_match)
- next
- end
-
- elsif (fstr.matched_count == fstr.spec_count - 1)
- if /\A\s*\z/.match(fstr.string_left)
- break if spec.count_space?
- result_buffer.replace(current_match)
- next
- end
- end
-
- final_result.concat(current_match)
-
- matched_so_far += source_buffer.size
- source_buffer.replace(fstr.string_left)
- matched_so_far -= source_buffer.size
- break if fstr.last_spec
- fstr.prune
- end
-
- begin
- seek(start_position + matched_so_far, IO::SEEK_SET)
- rescue Errno::ESPIPE
- end
-
- soak_up_spaces if fstr.last_spec && fstr.space
-
- return final_result
- end
-
- private
-
- def soak_up_spaces
- c = getc
- ungetc(c) if c
- until eof ||! c || /\S/.match(c.chr)
- c = getc
- end
- ungetc(c) if (c && /\S/.match(c.chr))
- end
-
- def block_scanf(str)
- final = []
-# Sub-ideal, since another FS gets created in scanf.
-# But used here to determine the number of specifiers.
- fstr = Scanf::FormatString.new(str)
- last_spec = fstr.last_spec
- begin
- current = scanf(str)
- break if current.empty?
- final.push(yield(current))
- end until eof || fstr.last_spec_tried == last_spec
- return final
- end
-end
-
-class String
-
- # :section: scanf
- #
- # You will need to require 'scanf' to use these methods
-
- # Scans the current string. If a block is given, it
- # functions exactly like block_scanf.
- #
- # arr = "123 456".scanf("%d%d")
- # # => [123, 456]
- #
- # require 'pp'
- #
- # "this 123 read that 456 other".scanf("%s%d%s") {|m| pp m}
- #
- # # ["this", 123, "read"]
- # # ["that", 456, "other"]
- # # => [["this", 123, "read"], ["that", 456, "other"]]
- #
- # See Scanf for details on creating a format string.
- #
- # You will need to require 'scanf' to use String#scanf
- def scanf(fstr,&b) #:yield: current_match
- if b
- block_scanf(fstr,&b)
- else
- fs =
- if fstr.is_a? Scanf::FormatString
- fstr
- else
- Scanf::FormatString.new(fstr)
- end
- fs.match(self)
- end
- end
-
- # Scans the current string until the match is exhausted
- # yielding each match as it is encountered in the string.
- # A block is not necessary as the results will simply
- # be aggregated into the final array.
- #
- # "123 456".block_scanf("%d")
- # # => [123, 456]
- #
- # If a block is given, the value from that is returned from
- # the yield is added to an output array.
- #
- # "123 456".block_scanf("%d) do |digit,| # the ',' unpacks the Array
- # digit + 100
- # end
- # # => [223, 556]
- #
- # See Scanf for details on creating a format string.
- #
- # You will need to require 'scanf' to use String#block_scanf
- def block_scanf(fstr) #:yield: current_match
- fs = Scanf::FormatString.new(fstr)
- str = self.dup
- final = []
- begin
- current = str.scanf(fs)
- final.push(yield(current)) unless current.empty?
- str = fs.string_left
- end until current.empty? || str.empty?
- return final
- end
-end
-
-module Kernel
- private
- # Scans STDIN for data matching +format+. See IO#scanf for details.
- #
- # See Scanf for details on creating a format string.
- #
- # You will need to require 'scanf' to use Kernel#scanf.
- def scanf(format, &b) #:doc:
- STDIN.scanf(format ,&b)
- end
-end
diff --git a/lib/securerandom.gemspec b/lib/securerandom.gemspec
new file mode 100644
index 0000000000..358dc58056
--- /dev/null
+++ b/lib/securerandom.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "securerandom"
+ spec.version = "0.1.0"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Interface for secure random number generator.}
+ spec.description = %q{Interface for secure random number generator.}
+ spec.homepage = "https://github.com/ruby/securerandom"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/securerandom.rb b/lib/securerandom.rb
index 2140a7e1fc..241fde98ce 100644
--- a/lib/securerandom.rb
+++ b/lib/securerandom.rb
@@ -16,68 +16,61 @@
# * /dev/urandom
# * Win32
#
+# SecureRandom is extended by the Random::Formatter module which
+# defines the following methods:
+#
+# * alphanumeric
+# * base64
+# * choose
+# * gen_random
+# * hex
+# * rand
+# * random_bytes
+# * random_number
+# * urlsafe_base64
+# * uuid
+#
+# These methods are usable as class methods of SecureRandom such as
+# `SecureRandom.hex`.
+#
# === Examples
#
# Generate random hexadecimal strings:
#
# require 'securerandom'
#
-# p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
-# p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
-# p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
+# SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
+# SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
+# SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
#
# Generate random base64 strings:
#
-# p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
-# p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
-# p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
+# SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
+# SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
+# SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
#
# Generate random binary strings:
#
-# p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
-# p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
+# SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
+# SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
+#
+# Generate alphanumeric strings:
+#
+# SecureRandom.alphanumeric(10) #=> "S8baxMJnPl"
+# SecureRandom.alphanumeric(10) #=> "aOxAg8BAJe"
#
# Generate UUIDs:
#
-# p SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
-# p SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
+# SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
+# SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
#
module SecureRandom
- @rng_chooser = Mutex.new # :nodoc:
-
class << self
def bytes(n)
return gen_random(n)
end
- def gen_random(n)
- ret = Random.urandom(1)
- if ret.nil?
- begin
- require 'openssl'
- rescue NoMethodError
- raise NotImplementedError, "No random device"
- else
- @rng_chooser.synchronize do
- class << self
- remove_method :gen_random
- alias gen_random gen_random_openssl
- end
- end
- return gen_random(n)
- end
- else
- @rng_chooser.synchronize do
- class << self
- remove_method :gen_random
- alias gen_random gen_random_urandom
- end
- end
- return gen_random(n)
- end
- end
-
private
def gen_random_openssl(n)
@@ -105,6 +98,21 @@ module SecureRandom
end
ret
end
+
+ ret = Random.urandom(1)
+ if ret.nil?
+ begin
+ require 'openssl'
+ rescue NoMethodError
+ raise NotImplementedError, "No random device"
+ else
+ alias gen_random gen_random_openssl
+ end
+ else
+ alias gen_random gen_random_urandom
+ end
+
+ public :gen_random
end
end
@@ -119,8 +127,10 @@ module Random::Formatter
#
# The result may contain any byte: "\x00" - "\xff".
#
- # p SecureRandom.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
- # p SecureRandom.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
+ # require 'securerandom'
+ #
+ # SecureRandom.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
+ # SecureRandom.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
#
# If a secure random number generator is not available,
# +NotImplementedError+ is raised.
@@ -139,8 +149,10 @@ module Random::Formatter
#
# The result may contain 0-9 and a-f.
#
- # p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
- # p SecureRandom.hex #=> "91dc3bfb4de5b11d029d376634589b61"
+ # require 'securerandom'
+ #
+ # SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
+ # SecureRandom.hex #=> "91dc3bfb4de5b11d029d376634589b61"
#
# If a secure random number generator is not available,
# +NotImplementedError+ is raised.
@@ -158,8 +170,10 @@ module Random::Formatter
#
# The result may contain A-Z, a-z, 0-9, "+", "/" and "=".
#
- # p SecureRandom.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
- # p SecureRandom.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
+ # require 'securerandom'
+ #
+ # SecureRandom.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
+ # SecureRandom.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
#
# If a secure random number generator is not available,
# +NotImplementedError+ is raised.
@@ -185,11 +199,13 @@ module Random::Formatter
# The result may contain A-Z, a-z, 0-9, "-" and "_".
# "=" is also used if _padding_ is true.
#
- # p SecureRandom.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
- # p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
+ # require 'securerandom'
+ #
+ # SecureRandom.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
+ # SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
#
- # p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
- # p SecureRandom.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
+ # SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
+ # SecureRandom.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
#
# If a secure random number generator is not available,
# +NotImplementedError+ is raised.
@@ -204,9 +220,11 @@ module Random::Formatter
# SecureRandom.uuid generates a random v4 UUID (Universally Unique IDentifier).
#
- # p SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
- # p SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
- # p SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
+ # require 'securerandom'
+ #
+ # SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
+ # SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
+ # SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
#
# The version 4 UUID is purely random (except the version).
# It doesn't contain meaningful information such as MAC addresses, timestamps, etc.
@@ -222,10 +240,78 @@ module Random::Formatter
"%08x-%04x-%04x-%04x-%04x%08x" % ary
end
- private
- def gen_random(n)
+ private def gen_random(n)
self.bytes(n)
end
+
+ # SecureRandom.choose generates a string that randomly draws from a
+ # source array of characters.
+ #
+ # The argument _source_ specifies the array of characters from which
+ # to generate the string.
+ # The argument _n_ specifies the length, in characters, of the string to be
+ # generated.
+ #
+ # The result may contain whatever characters are in the source array.
+ #
+ # require 'securerandom'
+ #
+ # SecureRandom.choose([*'l'..'r'], 16) #=> "lmrqpoonmmlqlron"
+ # SecureRandom.choose([*'0'..'9'], 5) #=> "27309"
+ #
+ # If a secure random number generator is not available,
+ # +NotImplementedError+ is raised.
+ private def choose(source, n)
+ size = source.size
+ m = 1
+ limit = size
+ while limit * size <= 0x100000000
+ limit *= size
+ m += 1
+ end
+ result = ''.dup
+ while m <= n
+ rs = random_number(limit)
+ is = rs.digits(size)
+ (m-is.length).times { is << 0 }
+ result << source.values_at(*is).join('')
+ n -= m
+ end
+ if 0 < n
+ rs = random_number(limit)
+ is = rs.digits(size)
+ if is.length < n
+ (n-is.length).times { is << 0 }
+ else
+ is.pop while n < is.length
+ end
+ result.concat source.values_at(*is).join('')
+ end
+ result
+ end
+
+ ALPHANUMERIC = [*'A'..'Z', *'a'..'z', *'0'..'9']
+ # SecureRandom.alphanumeric generates a random alphanumeric string.
+ #
+ # The argument _n_ specifies the length, in characters, of the alphanumeric
+ # string to be generated.
+ #
+ # If _n_ is not specified or is nil, 16 is assumed.
+ # It may be larger in the future.
+ #
+ # The result may contain A-Z, a-z and 0-9.
+ #
+ # require 'securerandom'
+ #
+ # SecureRandom.alphanumeric #=> "2BuBuLf3WfSKyQbR"
+ # SecureRandom.alphanumeric(10) #=> "i6K93NdqiH"
+ #
+ # If a secure random number generator is not available,
+ # +NotImplementedError+ is raised.
+ def alphanumeric(n=nil)
+ n = 16 if n.nil?
+ choose(ALPHANUMERIC, n)
+ end
end
SecureRandom.extend(Random::Formatter)
diff --git a/lib/set.rb b/lib/set.rb
index 009721381b..09c5595727 100644
--- a/lib/set.rb
+++ b/lib/set.rb
@@ -1,38 +1,31 @@
-#--
# frozen_string_literal: true
+# :markup: markdown
#
# set.rb - defines the Set class
-#++
-# Copyright (c) 2002-2016 Akinori MUSHA <knu@iDaemons.org>
+#
+# Copyright (c) 2002-2020 Akinori MUSHA <knu@iDaemons.org>
#
# Documentation by Akinori MUSHA and Gavin Sinclair.
#
# All rights reserved. You can redistribute and/or modify it under the same
# terms as Ruby.
-#
-# $Id$
-#
-# == Overview
-#
+
+
+##
# This library provides the Set class, which deals with a collection
# of unordered values with no duplicates. It is a hybrid of Array's
-# intuitive inter-operation facilities and Hash's fast lookup. If you
-# need to keep values sorted in some order, use the SortedSet class.
+# intuitive inter-operation facilities and Hash's fast lookup.
#
-# The method +to_set+ is added to Enumerable for convenience.
-#
-# See the Set and SortedSet documentation for examples of usage.
-
-
+# The method `to_set` is added to Enumerable for convenience.
#
# Set implements a collection of unordered values with no duplicates.
# This is a hybrid of Array's intuitive inter-operation facilities and
# Hash's fast lookup.
#
-# Set is easy to use with Enumerable objects (implementing +each+).
+# Set is easy to use with Enumerable objects (implementing `each`).
# Most of the initializer methods and binary operators accept generic
# Enumerable objects besides sets and arrays. An Enumerable object
-# can be converted to Set using the +to_set+ method.
+# can be converted to Set using the `to_set` method.
#
# Set uses Hash as storage, so you must note the following points:
#
@@ -45,32 +38,38 @@
# * When a string is to be stored, a frozen copy of the string is
# stored instead unless the original string is already frozen.
#
-# == Comparison
+# ## Comparison
#
-# The comparison operators <, >, <= and >= are implemented as
-# shorthand for the {proper_,}{subset?,superset?} methods. However,
-# the <=> operator is intentionally left out because not every pair of
-# sets is comparable. ({x,y} vs. {x,z} for example)
+# The comparison operators `<`, `>`, `<=`, and `>=` are implemented as
+# shorthand for the {proper_,}{subset?,superset?} methods. The `<=>`
+# operator reflects this order, or return `nil` for sets that both
+# have distinct elements (`{x, y}` vs. `{x, z}` for example).
#
-# == Example
+# ## Example
#
-# require 'set'
-# s1 = Set.new [1, 2] # -> #<Set: {1, 2}>
-# s2 = [1, 2].to_set # -> #<Set: {1, 2}>
-# s1 == s2 # -> true
-# s1.add("foo") # -> #<Set: {1, 2, "foo"}>
-# s1.merge([2, 6]) # -> #<Set: {1, 2, "foo", 6}>
-# s1.subset? s2 # -> false
-# s2.subset? s1 # -> true
+# ```ruby
+# require 'set'
+# s1 = Set[1, 2] #=> #<Set: {1, 2}>
+# s2 = [1, 2].to_set #=> #<Set: {1, 2}>
+# s1 == s2 #=> true
+# s1.add("foo") #=> #<Set: {1, 2, "foo"}>
+# s1.merge([2, 6]) #=> #<Set: {1, 2, "foo", 6}>
+# s1.subset?(s2) #=> false
+# s2.subset?(s1) #=> true
+# ```
#
-# == Contact
+# ## Contact
#
-# - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
+# - Akinori MUSHA <<knu@iDaemons.org>> (current maintainer)
#
class Set
include Enumerable
# Creates a new set containing the given objects.
+ #
+ # Set[1, 2] # => #<Set: {1, 2}>
+ # Set[1, 2, 1] # => #<Set: {1, 2}>
+ # Set[1, 'c', :s] # => #<Set: {1, "c", :s}>
def self.[](*ary)
new(ary)
end
@@ -80,6 +79,12 @@ class Set
#
# If a block is given, the elements of enum are preprocessed by the
# given block.
+ #
+ # Set.new([1, 2]) #=> #<Set: {1, 2}>
+ # Set.new([1, 2, 1]) #=> #<Set: {1, 2}>
+ # Set.new([1, 'c', :s]) #=> #<Set: {1, "c", :s}>
+ # Set.new(1..5) #=> #<Set: {1, 2, 3, 4, 5}>
+ # Set.new([1, 2, 3]) { |x| x * x } #=> #<Set: {1, 4, 9}>
def initialize(enum = nil, &block) # :yields: o
@hash ||= Hash.new(false)
@@ -126,10 +131,18 @@ class Set
@hash = orig.instance_variable_get(:@hash).dup
end
- # Clone internal hash.
- def initialize_clone(orig)
- super
- @hash = orig.instance_variable_get(:@hash).clone
+ if Kernel.instance_method(:initialize_clone).arity != 1
+ # Clone internal hash.
+ def initialize_clone(orig, **options)
+ super
+ @hash = orig.instance_variable_get(:@hash).clone(**options)
+ end
+ else
+ # Clone internal hash.
+ def initialize_clone(orig)
+ super
+ @hash = orig.instance_variable_get(:@hash).clone
+ end
end
def freeze # :nodoc:
@@ -137,16 +150,6 @@ class Set
super
end
- def taint # :nodoc:
- @hash.taint
- super
- end
-
- def untaint # :nodoc:
- @hash.untaint
- super
- end
-
# Returns the number of elements.
def size
@hash.size
@@ -159,6 +162,10 @@ class Set
end
# Removes all elements and returns self.
+ #
+ # set = Set[1, 'c', :s] #=> #<Set: {1, "c", :s}>
+ # set.clear #=> #<Set: {}>
+ # set #=> #<Set: {}>
def clear
@hash.clear
self
@@ -166,6 +173,10 @@ class Set
# Replaces the contents of the set with the contents of the given
# enumerable object and returns self.
+ #
+ # set = Set[1, 'c', :s] #=> #<Set: {1, "c", :s}>
+ # set.replace([1, 2]) #=> #<Set: {1, 2}>
+ # set #=> #<Set: {1, 2}>
def replace(enum)
if enum.instance_of?(self.class)
@hash.replace(enum.instance_variable_get(:@hash))
@@ -178,14 +189,17 @@ class Set
end
# Converts the set to an array. The order of elements is uncertain.
+ #
+ # Set[1, 2].to_a #=> [1, 2]
+ # Set[1, 'c', :s].to_a #=> [1, "c", :s]
def to_a
@hash.keys
end
# Returns self if no arguments are given. Otherwise, converts the
- # set to another with klass.new(self, *args, &block).
+ # set to another with `klass.new(self, *args, &block)`.
#
- # In subclasses, returns klass.new(self, *args, &block) unless
+ # In subclasses, returns `klass.new(self, *args, &block)` unless
# overridden.
def to_set(klass = Set, *args, &block)
return self if instance_of?(Set) && klass == Set && block.nil? && args.empty?
@@ -237,7 +251,7 @@ class Set
# Returns true if the set is a superset of the given set.
def superset?(set)
case
- when set.instance_of?(self.class)
+ when set.instance_of?(self.class) && @hash.respond_to?(:>=)
@hash >= set.instance_variable_get(:@hash)
when set.is_a?(Set)
size >= set.size && set.all? { |o| include?(o) }
@@ -250,7 +264,7 @@ class Set
# Returns true if the set is a proper superset of the given set.
def proper_superset?(set)
case
- when set.instance_of?(self.class)
+ when set.instance_of?(self.class) && @hash.respond_to?(:>)
@hash > set.instance_variable_get(:@hash)
when set.is_a?(Set)
size > set.size && set.all? { |o| include?(o) }
@@ -263,7 +277,7 @@ class Set
# Returns true if the set is a subset of the given set.
def subset?(set)
case
- when set.instance_of?(self.class)
+ when set.instance_of?(self.class) && @hash.respond_to?(:<=)
@hash <= set.instance_variable_get(:@hash)
when set.is_a?(Set)
size <= set.size && all? { |o| set.include?(o) }
@@ -276,7 +290,7 @@ class Set
# Returns true if the set is a proper subset of the given set.
def proper_subset?(set)
case
- when set.instance_of?(self.class)
+ when set.instance_of?(self.class) && @hash.respond_to?(:<)
@hash < set.instance_variable_get(:@hash)
when set.is_a?(Set)
size < set.size && all? { |o| set.include?(o) }
@@ -286,14 +300,24 @@ class Set
end
alias < proper_subset?
+ # Returns 0 if the set are equal,
+ # -1 / +1 if the set is a proper subset / superset of the given set,
+ # or nil if they both have unique elements.
+ def <=>(set)
+ return unless set.is_a?(Set)
+
+ case size <=> set.size
+ when -1 then -1 if proper_subset?(set)
+ when +1 then +1 if proper_superset?(set)
+ else 0 if self.==(set)
+ end
+ end
+
# Returns true if the set and the given set have at least one
# element in common.
#
- # e.g.:
- #
- # require 'set'
- # Set[1, 2, 3].intersect? Set[4, 5] # => false
- # Set[1, 2, 3].intersect? Set[3, 4] # => true
+ # Set[1, 2, 3].intersect? Set[4, 5] #=> false
+ # Set[1, 2, 3].intersect? Set[3, 4] #=> true
def intersect?(set)
set.is_a?(Set) or raise ArgumentError, "value must be a set"
if size < set.size
@@ -304,14 +328,10 @@ class Set
end
# Returns true if the set and the given set have no element in
- # common. This method is the opposite of +intersect?+.
- #
- # e.g.:
+ # common. This method is the opposite of `intersect?`.
#
- # require 'set'
- # Set[1, 2, 3].disjoint? Set[3, 4] # => false
- # Set[1, 2, 3].disjoint? Set[4, 5] # => true
-
+ # Set[1, 2, 3].disjoint? Set[3, 4] #=> false
+ # Set[1, 2, 3].disjoint? Set[4, 5] #=> true
def disjoint?(set)
!intersect?(set)
end
@@ -325,8 +345,12 @@ class Set
self
end
- # Adds the given object to the set and returns self. Use +merge+ to
+ # Adds the given object to the set and returns self. Use `merge` to
# add many elements at once.
+ #
+ # Set[1, 2].add(3) #=> #<Set: {1, 2, 3}>
+ # Set[1, 2].add([3, 4]) #=> #<Set: {1, 2, [3, 4]}>
+ # Set[1, 2].add(2) #=> #<Set: {1, 2}>
def add(o)
@hash[o] = true
self
@@ -335,12 +359,16 @@ class Set
# Adds the given object to the set and returns self. If the
# object is already in the set, returns nil.
+ #
+ # Set[1, 2].add?(3) #=> #<Set: {1, 2, 3}>
+ # Set[1, 2].add?([3, 4]) #=> #<Set: {1, 2, [3, 4]}>
+ # Set[1, 2].add?(2) #=> nil
def add?(o)
add(o) unless include?(o)
end
- # Deletes the given object from the set and returns self. Use +subtract+ to
- # delete many items at once.
+ # Deletes the given object from the set and returns self. Use
+ # `subtract` to delete many items at once.
def delete(o)
@hash.delete(o)
self
@@ -374,11 +402,13 @@ class Set
self
end
- # Replaces the elements with ones returned by collect().
+ # Replaces the elements with ones returned by `collect()`.
# Returns an enumerator if no block is given.
def collect!
block_given? or return enum_for(__method__) { size }
- replace(self.class.new(self) { |o| yield(o) })
+ set = self.class.new
+ each { |o| set << yield(o) }
+ replace(set)
end
alias map! collect!
@@ -400,6 +430,9 @@ class Set
self if size != n
end
+ # Equivalent to Set#select!
+ alias filter! select!
+
# Merges the elements of the given enumerable object to the set and
# returns self.
def merge(enum)
@@ -421,31 +454,51 @@ class Set
# Returns a new set built by merging the set and the elements of the
# given enumerable object.
+ #
+ # Set[1, 2, 3] | Set[2, 4, 5] #=> #<Set: {1, 2, 3, 4, 5}>
+ # Set[1, 5, 'z'] | (1..6) #=> #<Set: {1, 5, "z", 2, 3, 4, 6}>
def |(enum)
dup.merge(enum)
end
- alias + | ##
- alias union | ##
+ alias + |
+ alias union |
# Returns a new set built by duplicating the set, removing every
# element that appears in the given enumerable object.
+ #
+ # Set[1, 3, 5] - Set[1, 5] #=> #<Set: {3}>
+ # Set['a', 'b', 'z'] - ['a', 'c'] #=> #<Set: {"b", "z"}>
def -(enum)
dup.subtract(enum)
end
- alias difference - ##
+ alias difference -
# Returns a new set containing elements common to the set and the
# given enumerable object.
+ #
+ # Set[1, 3, 5] & Set[3, 2, 1] #=> #<Set: {3, 1}>
+ # Set['a', 'b', 'z'] & ['a', 'b', 'c'] #=> #<Set: {"a", "b"}>
def &(enum)
n = self.class.new
- do_with_enum(enum) { |o| n.add(o) if include?(o) }
+ if enum.is_a?(Set)
+ if enum.size > size
+ each { |o| n.add(o) if enum.include?(o) }
+ else
+ enum.each { |o| n.add(o) if include?(o) }
+ end
+ else
+ do_with_enum(enum) { |o| n.add(o) if include?(o) }
+ end
n
end
- alias intersection & ##
+ alias intersection &
# Returns a new set containing elements exclusive between the set
- # and the given enumerable object. (set ^ enum) is equivalent to
- # ((set | enum) - (set & enum)).
+ # and the given enumerable object. `(set ^ enum)` is equivalent to
+ # `((set | enum) - (set & enum))`.
+ #
+ # Set[1, 2] ^ Set[2, 3] #=> #<Set: {3, 1}>
+ # Set[1, 'b', 'c'] ^ ['b', 'd'] #=> #<Set: {"d", 1, "c"}>
def ^(enum)
n = Set.new(enum)
each { |o| n.add(o) unless n.delete?(o) }
@@ -454,6 +507,11 @@ class Set
# Returns true if two sets are equal. The equality of each couple
# of elements is defined according to Object#eql?.
+ #
+ # Set[1, 2] == Set[2, 1] #=> true
+ # Set[1, 3, 5] == Set[1, 5] #=> false
+ # Set['a', 'b', 'c'] == Set['a', 'c', 'b'] #=> true
+ # Set['a', 'b', 'c'] == ['a', 'c', 'b'] #=> false
def ==(other)
if self.equal?(other)
true
@@ -475,20 +533,38 @@ class Set
@hash.eql?(o.instance_variable_get(:@hash))
end
- # Returns true if obj is a member of the set, and false otherwise.
+ # Resets the internal state after modification to existing elements
+ # and returns self.
+ #
+ # Elements will be reindexed and deduplicated.
+ def reset
+ if @hash.respond_to?(:rehash)
+ @hash.rehash # This should perform frozenness check.
+ else
+ raise FrozenError, "can't modify frozen #{self.class.name}" if frozen?
+ end
+ self
+ end
+
+ # Returns true if the given object is a member of the set,
+ # and false otherwise.
#
# Used in case statements:
#
- # case :apple
- # when Set[:potato, :carrot] then 'vegetable'
- # when Set[:apple, :banana] then 'fruit'
- # end
- # #=> "fruit"
+ # require 'set'
+ #
+ # case :apple
+ # when Set[:potato, :carrot]
+ # "vegetable"
+ # when Set[:apple, :banana]
+ # "fruit"
+ # end
+ # # => "fruit"
#
# Or by itself:
#
- # Set[1, 2, 3] === 2 #=> true
- # Set[1, 2, 3] === 4 #=> false
+ # Set[1, 2, 3] === 2 #=> true
+ # Set[1, 2, 3] === 4 #=> false
#
alias === include?
@@ -497,14 +573,12 @@ class Set
# called once for each element of the set, passing the element as
# parameter.
#
- # e.g.:
- #
- # require 'set'
- # files = Set.new(Dir.glob("*.rb"))
- # hash = files.classify { |f| File.mtime(f).year }
- # p hash # => {2000=>#<Set: {"a.rb", "b.rb"}>,
- # # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
- # # 2002=>#<Set: {"f.rb"}>}
+ # require 'set'
+ # files = Set.new(Dir.glob("*.rb"))
+ # hash = files.classify { |f| File.mtime(f).year }
+ # hash #=> {2000=>#<Set: {"a.rb", "b.rb"}>,
+ # # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
+ # # 2002=>#<Set: {"f.rb"}>}
#
# Returns an enumerator if no block is given.
def classify # :yields: o
@@ -526,15 +600,13 @@ class Set
# if block.call(o1, o2) is true. Otherwise, elements o1 and o2 are
# in common if block.call(o1) == block.call(o2).
#
- # e.g.:
- #
- # require 'set'
- # numbers = Set[1, 3, 4, 6, 9, 10, 11]
- # set = numbers.divide { |i,j| (i - j).abs == 1 }
- # p set # => #<Set: {#<Set: {1}>,
- # # #<Set: {11, 9, 10}>,
- # # #<Set: {3, 4}>,
- # # #<Set: {6}>}>
+ # require 'set'
+ # numbers = Set[1, 3, 4, 6, 9, 10, 11]
+ # set = numbers.divide { |i,j| (i - j).abs == 1 }
+ # set #=> #<Set: {#<Set: {1}>,
+ # # #<Set: {11, 9, 10}>,
+ # # #<Set: {3, 4}>,
+ # # #<Set: {6}>}>
#
# Returns an enumerator if no block is given.
def divide(&func)
@@ -567,10 +639,16 @@ class Set
end
end
+ # Returns a string created by converting each element of the set to a string
+ # See also: Array#join
+ def join(separator=nil)
+ to_a.join(separator)
+ end
+
InspectKey = :__inspect_key__ # :nodoc:
# Returns a string containing a human-readable representation of the
- # set. ("#<Set: {element1, element2, ...}>")
+ # set ("#<Set: {element1, element2, ...}>").
def inspect
ids = (Thread.current[InspectKey] ||= [])
@@ -603,241 +681,12 @@ class Set
end
end
-#
-# SortedSet implements a Set that guarantees that its elements are
-# yielded in sorted order (according to the return values of their
-# #<=> methods) when iterating over them.
-#
-# All elements that are added to a SortedSet must respond to the <=>
-# method for comparison.
-#
-# Also, all elements must be <em>mutually comparable</em>: <tt>el1 <=>
-# el2</tt> must not return <tt>nil</tt> for any elements <tt>el1</tt>
-# and <tt>el2</tt>, else an ArgumentError will be raised when
-# iterating over the SortedSet.
-#
-# == Example
-#
-# require "set"
-#
-# set = SortedSet.new([2, 1, 5, 6, 4, 5, 3, 3, 3])
-# ary = []
-#
-# set.each do |obj|
-# ary << obj
-# end
-#
-# p ary # => [1, 2, 3, 4, 5, 6]
-#
-# set2 = SortedSet.new([1, 2, "3"])
-# set2.each { |obj| } # => raises ArgumentError: comparison of Fixnum with String failed
-#
-class SortedSet < Set
- @@setup = false
-
- class << self
- def [](*ary) # :nodoc:
- new(ary)
- end
-
- def setup # :nodoc:
- @@setup and return
-
- module_eval {
- # a hack to shut up warning
- alias old_init initialize
- }
- begin
- require 'rbtree'
-
- module_eval <<-END, __FILE__, __LINE__+1
- def initialize(*args)
- @hash = RBTree.new
- super
- end
-
- def add(o)
- o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
- super
- end
- alias << add
- END
- rescue LoadError
- module_eval <<-END, __FILE__, __LINE__+1
- def initialize(*args)
- @keys = nil
- super
- end
-
- def clear
- @keys = nil
- super
- end
-
- def replace(enum)
- @keys = nil
- super
- end
-
- def add(o)
- o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
- @keys = nil
- super
- end
- alias << add
-
- def delete(o)
- @keys = nil
- @hash.delete(o)
- self
- end
-
- def delete_if
- block_given? or return enum_for(__method__) { size }
- n = @hash.size
- super
- @keys = nil if @hash.size != n
- self
- end
-
- def keep_if
- block_given? or return enum_for(__method__) { size }
- n = @hash.size
- super
- @keys = nil if @hash.size != n
- self
- end
-
- def merge(enum)
- @keys = nil
- super
- end
-
- def each(&block)
- block or return enum_for(__method__) { size }
- to_a.each(&block)
- self
- end
-
- def to_a
- (@keys = @hash.keys).sort! unless @keys
- @keys
- end
- END
- end
- module_eval {
- # a hack to shut up warning
- remove_method :old_init
- }
-
- @@setup = true
- end
- end
-
- def initialize(*args, &block) # :nodoc:
- SortedSet.setup
- initialize(*args, &block)
- end
-end
-
module Enumerable
# Makes a set from the enumerable object with given arguments.
- # Needs to +require "set"+ to use this method.
+ # Needs to `require "set"` to use this method.
def to_set(klass = Set, *args, &block)
klass.new(self, *args, &block)
end
end
-# =begin
-# == RestricedSet class
-# RestricedSet implements a set with restrictions defined by a given
-# block.
-#
-# === Super class
-# Set
-#
-# === Class Methods
-# --- RestricedSet::new(enum = nil) { |o| ... }
-# --- RestricedSet::new(enum = nil) { |rset, o| ... }
-# Creates a new restricted set containing the elements of the given
-# enumerable object. Restrictions are defined by the given block.
-#
-# If the block's arity is 2, it is called with the RestrictedSet
-# itself and an object to see if the object is allowed to be put in
-# the set.
-#
-# Otherwise, the block is called with an object to see if the object
-# is allowed to be put in the set.
-#
-# === Instance Methods
-# --- restriction_proc
-# Returns the restriction procedure of the set.
-#
-# =end
-#
-# class RestricedSet < Set
-# def initialize(*args, &block)
-# @proc = block or raise ArgumentError, "missing a block"
-#
-# if @proc.arity == 2
-# instance_eval %{
-# def add(o)
-# @hash[o] = true if @proc.call(self, o)
-# self
-# end
-# alias << add
-#
-# def add?(o)
-# if include?(o) || !@proc.call(self, o)
-# nil
-# else
-# @hash[o] = true
-# self
-# end
-# end
-#
-# def replace(enum)
-# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
-# clear
-# enum.each_entry { |o| add(o) }
-#
-# self
-# end
-#
-# def merge(enum)
-# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
-# enum.each_entry { |o| add(o) }
-#
-# self
-# end
-# }
-# else
-# instance_eval %{
-# def add(o)
-# if @proc.call(o)
-# @hash[o] = true
-# end
-# self
-# end
-# alias << add
-#
-# def add?(o)
-# if include?(o) || !@proc.call(o)
-# nil
-# else
-# @hash[o] = true
-# self
-# end
-# end
-# }
-# end
-#
-# super(*args)
-# end
-#
-# def restriction_proc
-# @proc
-# end
-# end
-
-# Tests have been moved to test/test_set.rb.
+autoload :SortedSet, "#{__dir__}/set/sorted_set"
diff --git a/lib/set/set.gemspec b/lib/set/set.gemspec
new file mode 100644
index 0000000000..53b614ba22
--- /dev/null
+++ b/lib/set/set.gemspec
@@ -0,0 +1,25 @@
+Gem::Specification.new do |spec|
+ spec.name = "set"
+ spec.version = "1.0.1"
+ spec.authors = ["Akinori MUSHA"]
+ spec.email = ["knu@idaemons.org"]
+
+ spec.summary = %q{Provides a class to deal with collections of unordered, unique values}
+ spec.description = %q{Provides a class to deal with collections of unordered, unique values}
+ spec.homepage = "https://github.com/ruby/set"
+ spec.license = "BSD-2-Clause"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+ spec.metadata["changelog_uri"] = "https://github.com/ruby/set/blob/v#{spec.version}/CHANGELOG.md"
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/set/sorted_set.rb b/lib/set/sorted_set.rb
new file mode 100644
index 0000000000..e4e01ba4a8
--- /dev/null
+++ b/lib/set/sorted_set.rb
@@ -0,0 +1,6 @@
+begin
+ require 'sorted_set'
+rescue ::LoadError
+ raise "The `SortedSet` class has been extracted from the `set` library." \
+ "You must use the `sorted_set` gem or other alternatives."
+end
diff --git a/lib/shell.rb b/lib/shell.rb
deleted file mode 100644
index fb63717391..0000000000
--- a/lib/shell.rb
+++ /dev/null
@@ -1,461 +0,0 @@
-# frozen_string_literal: false
-#
-# shell.rb -
-# $Release Version: 0.7 $
-# $Revision: 1.9 $
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-require "e2mmap"
-
-require "forwardable"
-
-require "shell/error"
-require "shell/command-processor"
-require "shell/process-controller"
-
-# Shell implements an idiomatic Ruby interface for common UNIX shell commands.
-#
-# It provides users the ability to execute commands with filters and pipes,
-# like +sh+/+csh+ by using native facilities of Ruby.
-#
-# == Examples
-#
-# === Temp file creation
-#
-# In this example we will create three +tmpFile+'s in three different folders
-# under the +/tmp+ directory.
-#
-# sh = Shell.cd("/tmp") # Change to the /tmp directory
-# sh.mkdir "shell-test-1" unless sh.exists?("shell-test-1")
-# # make the 'shell-test-1' directory if it doesn't already exist
-# sh.cd("shell-test-1") # Change to the /tmp/shell-test-1 directory
-# for dir in ["dir1", "dir3", "dir5"]
-# if !sh.exists?(dir)
-# sh.mkdir dir # make dir if it doesn't already exist
-# sh.cd(dir) do
-# # change to the `dir` directory
-# f = sh.open("tmpFile", "w") # open a new file in write mode
-# f.print "TEST\n" # write to the file
-# f.close # close the file handler
-# end
-# print sh.pwd # output the process working directory
-# end
-# end
-#
-# === Temp file creation with self
-#
-# This example is identical to the first, except we're using
-# CommandProcessor#transact.
-#
-# CommandProcessor#transact executes the given block against self, in this case
-# +sh+; our Shell object. Within the block we can substitute +sh.cd+ to +cd+,
-# because the scope within the block uses +sh+ already.
-#
-# sh = Shell.cd("/tmp")
-# sh.transact do
-# mkdir "shell-test-1" unless exists?("shell-test-1")
-# cd("shell-test-1")
-# for dir in ["dir1", "dir3", "dir5"]
-# if !exists?(dir)
-# mkdir dir
-# cd(dir) do
-# f = open("tmpFile", "w")
-# f.print "TEST\n"
-# f.close
-# end
-# print pwd
-# end
-# end
-# end
-#
-# === Pipe /etc/printcap into a file
-#
-# In this example we will read the operating system file +/etc/printcap+,
-# generated by +cupsd+, and then output it to a new file relative to the +pwd+
-# of +sh+.
-#
-# sh = Shell.new
-# sh.cat("/etc/printcap") | sh.tee("tee1") > "tee2"
-# (sh.cat < "/etc/printcap") | sh.tee("tee11") > "tee12"
-# sh.cat("/etc/printcap") | sh.tee("tee1") >> "tee2"
-# (sh.cat < "/etc/printcap") | sh.tee("tee11") >> "tee12"
-#
-class Shell
-
- include Error
- extend Exception2MessageMapper
-
- # debug: true -> normal debug
- # debug: 1 -> eval definition debug
- # debug: 2 -> detail inspect debug
- @debug = false
- @verbose = true
-
- @debug_display_process_id = false
- @debug_display_thread_id = true
- @debug_output_mutex = Thread::Mutex.new
- @default_system_path = nil
- @default_record_separator = nil
-
- class << Shell
- extend Forwardable
-
- attr_accessor :cascade, :verbose
- attr_reader :debug
-
- alias debug? debug
- alias verbose? verbose
- @verbose = true
-
- def debug=(val)
- @debug = val
- @verbose = val if val
- end
-
-
- # call-seq:
- # Shell.cd(path)
- #
- # Creates a new Shell instance with the current working directory
- # set to +path+.
- def cd(path)
- new(path)
- end
-
- # Returns the directories in the current shell's PATH environment variable
- # as an array of directory names. This sets the system_path for all
- # instances of Shell.
- #
- # Example: If in your current shell, you did:
- #
- # $ echo $PATH
- # /usr/bin:/bin:/usr/local/bin
- #
- # Running this method in the above shell would then return:
- #
- # ["/usr/bin", "/bin", "/usr/local/bin"]
- #
- def default_system_path
- if @default_system_path
- @default_system_path
- else
- ENV["PATH"].split(":")
- end
- end
-
- # Sets the system_path that new instances of Shell should have as their
- # initial system_path.
- #
- # +path+ should be an array of directory name strings.
- def default_system_path=(path)
- @default_system_path = path
- end
-
- def default_record_separator
- if @default_record_separator
- @default_record_separator
- else
- $/
- end
- end
-
- def default_record_separator=(rs)
- @default_record_separator = rs
- end
-
- # os resource mutex
- mutex_methods = ["unlock", "lock", "locked?", "synchronize", "try_lock"]
- for m in mutex_methods
- def_delegator("@debug_output_mutex", m, "debug_output_"+m.to_s)
- end
-
- end
-
- # call-seq:
- # Shell.new(pwd, umask) -> obj
- #
- # Creates a Shell object which current directory is set to the process
- # current directory, unless otherwise specified by the +pwd+ argument.
- def initialize(pwd = Dir.pwd, umask = nil)
- @cwd = File.expand_path(pwd)
- @dir_stack = []
- @umask = umask
-
- @system_path = Shell.default_system_path
- @record_separator = Shell.default_record_separator
-
- @command_processor = CommandProcessor.new(self)
- @process_controller = ProcessController.new(self)
-
- @verbose = Shell.verbose
- @debug = Shell.debug
- end
-
- # Returns the command search path in an array
- attr_reader :system_path
-
- # Sets the system path (the Shell instance's PATH environment variable).
- #
- # +path+ should be an array of directory name strings.
- def system_path=(path)
- @system_path = path
- rehash
- end
-
-
- # Returns the umask
- attr_accessor :umask
- attr_accessor :record_separator
- attr_accessor :verbose
- attr_reader :debug
-
- def debug=(val)
- @debug = val
- @verbose = val if val
- end
-
- alias verbose? verbose
- alias debug? debug
-
- attr_reader :command_processor
- attr_reader :process_controller
-
- def expand_path(path)
- File.expand_path(path, @cwd)
- end
-
- # Most Shell commands are defined via CommandProcessor
-
- #
- # Dir related methods
- #
- # Shell#cwd/dir/getwd/pwd
- # Shell#chdir/cd
- # Shell#pushdir/pushd
- # Shell#popdir/popd
- # Shell#mkdir
- # Shell#rmdir
-
- # Returns the current working directory.
- attr_reader :cwd
- alias dir cwd
- alias getwd cwd
- alias pwd cwd
-
- attr_reader :dir_stack
- alias dirs dir_stack
-
- # call-seq:
- # Shell.chdir(path)
- #
- # Creates a Shell object which current directory is set to +path+.
- #
- # If a block is given, it restores the current directory when the block ends.
- #
- # If called as iterator, it restores the current directory when the
- # block ends.
- def chdir(path = nil, verbose = @verbose)
- check_point
-
- if iterator?
- notify("chdir(with block) #{path}") if verbose
- cwd_old = @cwd
- begin
- chdir(path, nil)
- yield
- ensure
- chdir(cwd_old, nil)
- end
- else
- notify("chdir #{path}") if verbose
- path = "~" unless path
- @cwd = expand_path(path)
- notify "current dir: #{@cwd}"
- rehash
- Void.new(self)
- end
- end
- alias cd chdir
-
- # call-seq:
- # pushdir(path)
- # pushdir(path) { &block }
- #
- # Pushes the current directory to the directory stack, changing the current
- # directory to +path+.
- #
- # If +path+ is omitted, it exchanges its current directory and the top of its
- # directory stack.
- #
- # If a block is given, it restores the current directory when the block ends.
- def pushdir(path = nil, verbose = @verbose)
- check_point
-
- if iterator?
- notify("pushdir(with block) #{path}") if verbose
- pushdir(path, nil)
- begin
- yield
- ensure
- popdir
- end
- elsif path
- notify("pushdir #{path}") if verbose
- @dir_stack.push @cwd
- chdir(path, nil)
- notify "dir stack: [#{@dir_stack.join ', '}]"
- self
- else
- notify("pushdir") if verbose
- if pop = @dir_stack.pop
- @dir_stack.push @cwd
- chdir pop
- notify "dir stack: [#{@dir_stack.join ', '}]"
- self
- else
- Shell.Fail DirStackEmpty
- end
- end
- Void.new(self)
- end
- alias pushd pushdir
-
- # Pops a directory from the directory stack, and sets the current directory
- # to it.
- def popdir
- check_point
-
- notify("popdir")
- if pop = @dir_stack.pop
- chdir pop
- notify "dir stack: [#{@dir_stack.join ', '}]"
- self
- else
- Shell.Fail DirStackEmpty
- end
- Void.new(self)
- end
- alias popd popdir
-
- # Returns a list of scheduled jobs.
- def jobs
- @process_controller.jobs
- end
-
- # call-seq:
- # kill(signal, job)
- #
- # Sends the given +signal+ to the given +job+
- def kill(sig, command)
- @process_controller.kill_job(sig, command)
- end
-
- # call-seq:
- # def_system_command(command, path = command)
- #
- # Convenience method for Shell::CommandProcessor.def_system_command.
- # Defines an instance method which will execute the given shell command.
- # If the executable is not in Shell.default_system_path, you must
- # supply the path to it.
- #
- # Shell.def_system_command('hostname')
- # Shell.new.hostname # => localhost
- #
- # # How to use an executable that's not in the default path
- #
- # Shell.def_system_command('run_my_program', "~/hello")
- # Shell.new.run_my_program # prints "Hello from a C program!"
- #
- def Shell.def_system_command(command, path = command)
- CommandProcessor.def_system_command(command, path)
- end
-
- # Convenience method for Shell::CommandProcessor.undef_system_command
- def Shell.undef_system_command(command)
- CommandProcessor.undef_system_command(command)
- end
-
- # call-seq:
- # alias_command(alias, command, *opts, &block)
- #
- # Convenience method for Shell::CommandProcessor.alias_command.
- # Defines an instance method which will execute a command under
- # an alternative name.
- #
- # Shell.def_system_command('date')
- # Shell.alias_command('date_in_utc', 'date', '-u')
- # Shell.new.date_in_utc # => Sat Jan 25 16:59:57 UTC 2014
- #
- def Shell.alias_command(ali, command, *opts, &block)
- CommandProcessor.alias_command(ali, command, *opts, &block)
- end
-
- # Convenience method for Shell::CommandProcessor.unalias_command
- def Shell.unalias_command(ali)
- CommandProcessor.unalias_command(ali)
- end
-
- # call-seq:
- # install_system_commands(pre = "sys_")
- #
- # Convenience method for Shell::CommandProcessor.install_system_commands.
- # Defines instance methods representing all the executable files found in
- # Shell.default_system_path, with the given prefix prepended to their
- # names.
- #
- # Shell.install_system_commands
- # Shell.new.sys_echo("hello") # => hello
- #
- def Shell.install_system_commands(pre = "sys_")
- CommandProcessor.install_system_commands(pre)
- end
-
- #
- def inspect
- if debug.kind_of?(Integer) && debug > 2
- super
- else
- to_s
- end
- end
-
- def self.notify(*opts)
- Shell::debug_output_synchronize do
- if opts[-1].kind_of?(String)
- yorn = verbose?
- else
- yorn = opts.pop
- end
- return unless yorn
-
- if @debug_display_thread_id
- if @debug_display_process_id
- prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
- else
- prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
- end
- else
- prefix = "shell: "
- end
- _head = true
- STDERR.print opts.collect{|mes|
- mes = mes.dup
- yield mes if iterator?
- if _head
- _head = false
- prefix + mes
- else
- " "* prefix.size + mes
- end
- }.join("\n")+"\n"
- end
- end
-
- CommandProcessor.initialize
- CommandProcessor.run_config
-end
diff --git a/lib/shell/builtin-command.rb b/lib/shell/builtin-command.rb
deleted file mode 100644
index e419a68c33..0000000000
--- a/lib/shell/builtin-command.rb
+++ /dev/null
@@ -1,147 +0,0 @@
-# frozen_string_literal: false
-#
-# shell/builtin-command.rb -
-# $Release Version: 0.7 $
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-require "shell/filter"
-
-class Shell
- class BuiltInCommand < Filter
- def wait?
- false
- end
- def active?
- true
- end
- end
-
- class Void < BuiltInCommand
- def initialize(sh, *opts)
- super sh
- end
-
- def each(rs = nil)
- # do nothing
- end
- end
-
- class Echo < BuiltInCommand
- def initialize(sh, *strings)
- super sh
- @strings = strings
- end
-
- def each(rs = nil)
- rs = @shell.record_separator unless rs
- for str in @strings
- yield str + rs
- end
- end
- end
-
- class Cat < BuiltInCommand
- def initialize(sh, *filenames)
- super sh
- @cat_files = filenames
- end
-
- def each(rs = nil)
- if @cat_files.empty?
- super
- else
- for src in @cat_files
- @shell.foreach(src, rs){|l| yield l}
- end
- end
- end
- end
-
- class Glob < BuiltInCommand
- def initialize(sh, pattern)
- super sh
-
- @pattern = pattern
- end
-
- def each(rs = nil)
- if @pattern[0] == ?/
- @files = Dir[@pattern]
- else
- prefix = @shell.pwd+"/"
- @files = Dir[prefix+@pattern].collect{|p| p.sub(prefix, "")}
- end
- rs = @shell.record_separator unless rs
- for f in @files
- yield f+rs
- end
- end
- end
-
- class AppendIO < BuiltInCommand
- def initialize(sh, io, filter)
- super sh
- @input = filter
- @io = io
- end
-
- def input=(filter)
- @input.input=filter
- for l in @input
- @io << l
- end
- end
-
- end
-
- class AppendFile < AppendIO
- def initialize(sh, to_filename, filter)
- @file_name = to_filename
- io = sh.open(to_filename, "a")
- super(sh, io, filter)
- end
-
- def input=(filter)
- begin
- super
- ensure
- @io.close
- end
- end
- end
-
- class Tee < BuiltInCommand
- def initialize(sh, filename)
- super sh
- @to_filename = filename
- end
-
- def each(rs = nil)
- to = @shell.open(@to_filename, "w")
- begin
- super{|l| to << l; yield l}
- ensure
- to.close
- end
- end
- end
-
- class Concat < BuiltInCommand
- def initialize(sh, *jobs)
- super(sh)
- @jobs = jobs
- end
-
- def each(rs = nil)
- while job = @jobs.shift
- job.each{|l| yield l}
- end
- end
- end
-end
diff --git a/lib/shell/command-processor.rb b/lib/shell/command-processor.rb
deleted file mode 100644
index b52cb0043f..0000000000
--- a/lib/shell/command-processor.rb
+++ /dev/null
@@ -1,668 +0,0 @@
-# frozen_string_literal: false
-#
-# shell/command-controller.rb -
-# $Release Version: 0.7 $
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-require "e2mmap"
-
-require "shell/error"
-require "shell/filter"
-require "shell/system-command"
-require "shell/builtin-command"
-
-class Shell
- # In order to execute a command on your OS, you need to define it as a
- # Shell method.
- #
- # Alternatively, you can execute any command via
- # Shell::CommandProcessor#system even if it is not defined.
- class CommandProcessor
-
- #
- # initialize of Shell and related classes.
- #
- m = [:initialize, :expand_path]
- if Object.methods.first.kind_of?(String)
- NoDelegateMethods = m.collect{|x| x.id2name}
- else
- NoDelegateMethods = m
- end
-
- def self.initialize
-
- install_builtin_commands
-
- # define CommandProcessor#methods to Shell#methods and Filter#methods
- for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
- add_delegate_command_to_shell(m)
- end
-
- def self.method_added(id)
- add_delegate_command_to_shell(id)
- end
- end
-
- #
- # include run file.
- #
- def self.run_config
- rc = "~/.rb_shell"
- begin
- load File.expand_path(rc) if ENV.key?("HOME")
- rescue LoadError, Errno::ENOENT
- rescue
- print "load error: #{rc}\n"
- print $!.class, ": ", $!, "\n"
- for err in $@[0, $@.size - 2]
- print "\t", err, "\n"
- end
- end
- end
-
- def initialize(shell)
- @shell = shell
- @system_commands = {}
- end
-
- #
- # CommandProcessor#expand_path(path)
- # path: String
- # return: String
- # returns the absolute path for <path>
- #
- def expand_path(path)
- @shell.expand_path(path)
- end
-
- # call-seq:
- # foreach(path, record_separator) -> Enumerator
- # foreach(path, record_separator) { block }
- #
- # See IO.foreach when +path+ is a file.
- #
- # See Dir.foreach when +path+ is a directory.
- #
- def foreach(path = nil, *rs)
- path = "." unless path
- path = expand_path(path)
-
- if File.directory?(path)
- Dir.foreach(path){|fn| yield fn}
- else
- IO.foreach(path, *rs){|l| yield l}
- end
- end
-
- # call-seq:
- # open(path, mode, permissions) -> Enumerator
- # open(path, mode, permissions) { block }
- #
- # See IO.open when +path+ is a file.
- #
- # See Dir.open when +path+ is a directory.
- #
- def open(path, mode = nil, perm = 0666, &b)
- path = expand_path(path)
- if File.directory?(path)
- Dir.open(path, &b)
- else
- if @shell.umask
- f = File.open(path, mode, perm)
- File.chmod(perm & ~@shell.umask, path)
- if block_given?
- f.each(&b)
- end
- f
- else
- File.open(path, mode, perm, &b)
- end
- end
- end
-
- # call-seq:
- # unlink(path)
- #
- # See IO.unlink when +path+ is a file.
- #
- # See Dir.unlink when +path+ is a directory.
- #
- def unlink(path)
- @shell.check_point
-
- path = expand_path(path)
- if File.directory?(path)
- Dir.unlink(path)
- else
- IO.unlink(path)
- end
- Void.new(@shell)
- end
-
- # See Shell::CommandProcessor#test
- alias top_level_test test
- # call-seq:
- # test(command, file1, file2) -> true or false
- # [command, file1, file2] -> true or false
- #
- # Tests if the given +command+ exists in +file1+, or optionally +file2+.
- #
- # Example:
- # sh[?e, "foo"]
- # sh[:e, "foo"]
- # sh["e", "foo"]
- # sh[:exists?, "foo"]
- # sh["exists?", "foo"]
- #
- def test(command, file1, file2=nil)
- file1 = expand_path(file1)
- file2 = expand_path(file2) if file2
- command = command.id2name if command.kind_of?(Symbol)
-
- case command
- when Integer
- if file2
- top_level_test(command, file1, file2)
- else
- top_level_test(command, file1)
- end
- when String
- if command.size == 1
- if file2
- top_level_test(command, file1, file2)
- else
- top_level_test(command, file1)
- end
- else
- if file2
- FileTest.send(command, file1, file2)
- else
- FileTest.send(command, file1)
- end
- end
- end
- end
- # See Shell::CommandProcessor#test
- alias [] test
-
- # call-seq:
- # mkdir(path)
- #
- # Same as Dir.mkdir, except multiple directories are allowed.
- def mkdir(*path)
- @shell.check_point
- notify("mkdir #{path.join(' ')}")
-
- perm = nil
- if path.last.kind_of?(Integer)
- perm = path.pop
- end
- for dir in path
- d = expand_path(dir)
- if perm
- Dir.mkdir(d, perm)
- else
- Dir.mkdir(d)
- end
- File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
- end
- Void.new(@shell)
- end
-
- # call-seq:
- # rmdir(path)
- #
- # Same as Dir.rmdir, except multiple directories are allowed.
- def rmdir(*path)
- @shell.check_point
- notify("rmdir #{path.join(' ')}")
-
- for dir in path
- Dir.rmdir(expand_path(dir))
- end
- Void.new(@shell)
- end
-
- # call-seq:
- # system(command, *options) -> SystemCommand
- #
- # Executes the given +command+ with the +options+ parameter.
- #
- # Example:
- # print sh.system("ls", "-l")
- # sh.system("ls", "-l") | sh.head > STDOUT
- #
- def system(command, *opts)
- if opts.empty?
- if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
- return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
- else
- command, *opts = command.split(/\s+/)
- end
- end
- SystemCommand.new(@shell, find_system_command(command), *opts)
- end
-
- # call-seq:
- # rehash
- #
- # Clears the command hash table.
- def rehash
- @system_commands = {}
- end
-
- def check_point # :nodoc:
- @shell.process_controller.wait_all_jobs_execution
- end
- alias finish_all_jobs check_point # :nodoc:
-
- # call-seq:
- # transact { block }
- #
- # Executes a block as self
- #
- # Example:
- # sh.transact { system("ls", "-l") | head > STDOUT }
- def transact(&block)
- begin
- @shell.instance_eval(&block)
- ensure
- check_point
- end
- end
-
- # call-seq:
- # out(device) { block }
- #
- # Calls <code>device.print</code> on the result passing the _block_ to
- # #transact
- def out(dev = STDOUT, &block)
- dev.print transact(&block)
- end
-
- # call-seq:
- # echo(*strings) -> Echo
- #
- # Returns a Echo object, for the given +strings+
- def echo(*strings)
- Echo.new(@shell, *strings)
- end
-
- # call-seq:
- # cat(*filename) -> Cat
- #
- # Returns a Cat object, for the given +filenames+
- def cat(*filenames)
- Cat.new(@shell, *filenames)
- end
-
- # def sort(*filenames)
- # Sort.new(self, *filenames)
- # end
- # call-seq:
- # glob(pattern) -> Glob
- #
- # Returns a Glob filter object, with the given +pattern+ object
- def glob(pattern)
- Glob.new(@shell, pattern)
- end
-
- def append(to, filter)
- case to
- when String
- AppendFile.new(@shell, to, filter)
- when IO
- AppendIO.new(@shell, to, filter)
- else
- Shell.Fail Error::CantApplyMethod, "append", to.class
- end
- end
-
- # call-seq:
- # tee(file) -> Tee
- #
- # Returns a Tee filter object, with the given +file+ command
- def tee(file)
- Tee.new(@shell, file)
- end
-
- # call-seq:
- # concat(*jobs) -> Concat
- #
- # Returns a Concat object, for the given +jobs+
- def concat(*jobs)
- Concat.new(@shell, *jobs)
- end
-
- # %pwd, %cwd -> @pwd
- def notify(*opts)
- Shell.notify(*opts) {|mes|
- yield mes if iterator?
-
- mes.gsub!("%pwd", "#{@cwd}")
- mes.gsub!("%cwd", "#{@cwd}")
- }
- end
-
- #
- # private functions
- #
- def find_system_command(command)
- return command if /^\// =~ command
- case path = @system_commands[command]
- when String
- if exists?(path)
- return path
- else
- Shell.Fail Error::CommandNotFound, command
- end
- when false
- Shell.Fail Error::CommandNotFound, command
- end
-
- for p in @shell.system_path
- path = join(p, command)
- begin
- st = File.stat(path)
- rescue SystemCallError
- next
- else
- next unless st.executable? and !st.directory?
- @system_commands[command] = path
- return path
- end
- end
- @system_commands[command] = false
- Shell.Fail Error::CommandNotFound, command
- end
-
- # call-seq:
- # def_system_command(command, path) -> Shell::SystemCommand
- #
- # Defines a command, registering +path+ as a Shell method for the given
- # +command+.
- #
- # Shell::CommandProcessor.def_system_command "ls"
- # #=> Defines ls.
- #
- # Shell::CommandProcessor.def_system_command "sys_sort", "sort"
- # #=> Defines sys_sort as sort
- #
- def self.def_system_command(command, path = command)
- begin
- eval((d = %Q[def #{command}(*opts)
- SystemCommand.new(@shell, '#{path}', *opts)
- end]), nil, __FILE__, __LINE__ - 1)
- rescue SyntaxError
- Shell.notify "warn: Can't define #{command} path: #{path}."
- end
- Shell.notify "Define #{command} path: #{path}.", Shell.debug?
- Shell.notify("Definition of #{command}: ", d,
- Shell.debug.kind_of?(Integer) && Shell.debug > 1)
- end
-
- # call-seq:
- # undef_system_command(command) -> self
- #
- # Undefines a command
- def self.undef_system_command(command)
- command = command.id2name if command.kind_of?(Symbol)
- remove_method(command)
- Shell.module_eval{remove_method(command)}
- Filter.module_eval{remove_method(command)}
- self
- end
-
- @alias_map = {}
- # Returns a list of aliased commands
- def self.alias_map
- @alias_map
- end
- # call-seq:
- # alias_command(alias, command, *options) -> self
- #
- # Creates a command alias at the given +alias+ for the given +command+,
- # passing any +options+ along with it.
- #
- # Shell::CommandProcessor.alias_command "lsC", "ls", "-CBF", "--show-control-chars"
- # Shell::CommandProcessor.alias_command("lsC", "ls"){|*opts| ["-CBF", "--show-control-chars", *opts]}
- #
- def self.alias_command(ali, command, *opts)
- ali = ali.id2name if ali.kind_of?(Symbol)
- command = command.id2name if command.kind_of?(Symbol)
- begin
- if iterator?
- @alias_map[ali.intern] = proc
-
- eval((d = %Q[def #{ali}(*opts)
- @shell.__send__(:#{command},
- *(CommandProcessor.alias_map[:#{ali}].call *opts))
- end]), nil, __FILE__, __LINE__ - 1)
-
- else
- args = opts.collect{|opt| '"' + opt + '"'}.join(",")
- eval((d = %Q[def #{ali}(*opts)
- @shell.__send__(:#{command}, #{args}, *opts)
- end]), nil, __FILE__, __LINE__ - 1)
- end
- rescue SyntaxError
- Shell.notify "warn: Can't alias #{ali} command: #{command}."
- Shell.notify("Definition of #{ali}: ", d)
- raise
- end
- Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
- Shell.notify("Definition of #{ali}: ", d,
- Shell.debug.kind_of?(Integer) && Shell.debug > 1)
- self
- end
-
- # call-seq:
- # unalias_command(alias) -> self
- #
- # Unaliases the given +alias+ command.
- def self.unalias_command(ali)
- ali = ali.id2name if ali.kind_of?(Symbol)
- @alias_map.delete ali.intern
- undef_system_command(ali)
- end
-
- # :nodoc:
- #
- # Delegates File and FileTest methods into Shell, including the following
- # commands:
- #
- # * Shell#blockdev?(file)
- # * Shell#chardev?(file)
- # * Shell#directory?(file)
- # * Shell#executable?(file)
- # * Shell#executable_real?(file)
- # * Shell#exist?(file)/Shell#exists?(file)
- # * Shell#file?(file)
- # * Shell#grpowned?(file)
- # * Shell#owned?(file)
- # * Shell#pipe?(file)
- # * Shell#readable?(file)
- # * Shell#readable_real?(file)
- # * Shell#setgid?(file)
- # * Shell#setuid?(file)
- # * Shell#size(file)/Shell#size?(file)
- # * Shell#socket?(file)
- # * Shell#sticky?(file)
- # * Shell#symlink?(file)
- # * Shell#writable?(file)
- # * Shell#writable_real?(file)
- # * Shell#zero?(file)
- # * Shell#syscopy(filename_from, filename_to)
- # * Shell#copy(filename_from, filename_to)
- # * Shell#move(filename_from, filename_to)
- # * Shell#compare(filename_from, filename_to)
- # * Shell#safe_unlink(*filenames)
- # * Shell#makedirs(*filenames)
- # * Shell#install(filename_from, filename_to, mode)
- #
- # And also, there are some aliases for convenience:
- #
- # * Shell#cmp <- Shell#compare
- # * Shell#mv <- Shell#move
- # * Shell#cp <- Shell#copy
- # * Shell#rm_f <- Shell#safe_unlink
- # * Shell#mkpath <- Shell#makedirs
- #
- def self.def_builtin_commands(delegation_class, command_specs)
- for meth, args in command_specs
- arg_str = args.collect{|arg| arg.downcase}.join(", ")
- call_arg_str = args.collect{
- |arg|
- case arg
- when /^(FILENAME.*)$/
- format("expand_path(%s)", $1.downcase)
- when /^(\*FILENAME.*)$/
- # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
- $1.downcase + '.collect{|fn| expand_path(fn)}'
- else
- arg
- end
- }.join(", ")
- d = %Q[def #{meth}(#{arg_str})
- #{delegation_class}.#{meth}(#{call_arg_str})
- end]
- Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
- Shell.notify("Definition of #{meth}: ", d,
- Shell.debug.kind_of?(Integer) && Shell.debug > 1)
- eval d
- end
- end
-
- # call-seq:
- # install_system_commands(prefix = "sys_")
- #
- # Defines all commands in the Shell.default_system_path as Shell method,
- # all with given +prefix+ appended to their names.
- #
- # Any invalid character names are converted to +_+, and errors are passed
- # to Shell.notify.
- #
- # Methods already defined are skipped.
- def self.install_system_commands(pre = "sys_")
- defined_meth = {}
- for m in Shell.methods
- defined_meth[m] = true
- end
- sh = Shell.new
- for path in Shell.default_system_path
- next unless sh.directory? path
- sh.cd path
- sh.foreach do
- |cn|
- if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
- command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
- begin
- def_system_command(command, sh.expand_path(cn))
- rescue
- Shell.notify "warn: Can't define #{command} path: #{cn}"
- end
- defined_meth[command] = command
- end
- end
- end
- end
-
- def self.add_delegate_command_to_shell(id) # :nodoc:
- id = id.intern if id.kind_of?(String)
- name = id.id2name
- if Shell.method_defined?(id)
- Shell.notify "warn: override definition of Shell##{name}."
- Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
- Shell.module_eval "alias #{name}_org #{name}"
- end
- Shell.notify "method added: Shell##{name}.", Shell.debug?
- Shell.module_eval(%Q[def #{name}(*args, &block)
- begin
- @command_processor.__send__(:#{name}, *args, &block)
- rescue Exception
- $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
- $@.delete_if{|s| /^\\(eval\\):/ =~ s}
- raise
- end
- end], __FILE__, __LINE__)
-
- if Shell::Filter.method_defined?(id)
- Shell.notify "warn: override definition of Shell::Filter##{name}."
- Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
- Filter.module_eval "alias #{name}_org #{name}"
- end
- Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
- Filter.module_eval(%Q[def #{name}(*args, &block)
- begin
- self | @shell.__send__(:#{name}, *args, &block)
- rescue Exception
- $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
- $@.delete_if{|s| /^\\(eval\\):/ =~ s}
- raise
- end
- end], __FILE__, __LINE__)
- end
-
- # Delegates File methods into Shell, including the following commands:
- #
- # * Shell#atime(file)
- # * Shell#basename(file, *opt)
- # * Shell#chmod(mode, *files)
- # * Shell#chown(owner, group, *file)
- # * Shell#ctime(file)
- # * Shell#delete(*file)
- # * Shell#dirname(file)
- # * Shell#ftype(file)
- # * Shell#join(*file)
- # * Shell#link(file_from, file_to)
- # * Shell#lstat(file)
- # * Shell#mtime(file)
- # * Shell#readlink(file)
- # * Shell#rename(file_from, file_to)
- # * Shell#split(file)
- # * Shell#stat(file)
- # * Shell#symlink(file_from, file_to)
- # * Shell#truncate(file, length)
- # * Shell#utime(atime, mtime, *file)
- #
- def self.install_builtin_commands
- # method related File.
- # (exclude open/foreach/unlink)
- normal_delegation_file_methods = [
- ["atime", ["FILENAME"]],
- ["basename", ["fn", "*opts"]],
- ["chmod", ["mode", "*FILENAMES"]],
- ["chown", ["owner", "group", "*FILENAME"]],
- ["ctime", ["FILENAMES"]],
- ["delete", ["*FILENAMES"]],
- ["dirname", ["FILENAME"]],
- ["ftype", ["FILENAME"]],
- ["join", ["*items"]],
- ["link", ["FILENAME_O", "FILENAME_N"]],
- ["lstat", ["FILENAME"]],
- ["mtime", ["FILENAME"]],
- ["readlink", ["FILENAME"]],
- ["rename", ["FILENAME_FROM", "FILENAME_TO"]],
- ["split", ["pathname"]],
- ["stat", ["FILENAME"]],
- ["symlink", ["FILENAME_O", "FILENAME_N"]],
- ["truncate", ["FILENAME", "length"]],
- ["utime", ["atime", "mtime", "*FILENAMES"]]]
-
- def_builtin_commands(File, normal_delegation_file_methods)
- alias_method :rm, :delete
-
- # method related FileTest
- def_builtin_commands(FileTest,
- FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
-
- end
-
- end
-end
diff --git a/lib/shell/error.rb b/lib/shell/error.rb
deleted file mode 100644
index 677c424baf..0000000000
--- a/lib/shell/error.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: false
-#
-# shell/error.rb -
-# $Release Version: 0.7 $
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-require "e2mmap"
-
-class Shell
- module Error
- extend Exception2MessageMapper
- def_e2message TypeError, "wrong argument type %s (expected %s)"
-
- def_exception :DirStackEmpty, "Directory stack empty."
- def_exception :CantDefine, "Can't define method(%s, %s)."
- def_exception :CantApplyMethod, "This method(%s) does not apply to this type(%s)."
- def_exception :CommandNotFound, "Command not found(%s)."
- end
-end
-
diff --git a/lib/shell/filter.rb b/lib/shell/filter.rb
deleted file mode 100644
index caa976ae3e..0000000000
--- a/lib/shell/filter.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# frozen_string_literal: false
-#
-# shell/filter.rb -
-# $Release Version: 0.7 $
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-class Shell #:nodoc:
- # Any result of command execution is a Filter.
- #
- # This class includes Enumerable, therefore a Filter object can use all
- # Enumerable
- # facilities.
- #
- class Filter
- include Enumerable
-
- def initialize(sh)
- @shell = sh # parent shell
- @input = nil # input filter
- end
-
- attr_reader :input
-
- def input=(filter)
- @input = filter
- end
-
- # call-seq:
- # each(record_separator=nil) { block }
- #
- # Iterates a block for each line.
- def each(rs = nil)
- rs = @shell.record_separator unless rs
- if @input
- @input.each(rs){|l| yield l}
- end
- end
-
- # call-seq:
- # < source
- #
- # Inputs from +source+, which is either a string of a file name or an IO
- # object.
- def <(src)
- case src
- when String
- cat = Cat.new(@shell, src)
- cat | self
- when IO
- self.input = src
- self
- else
- Shell.Fail Error::CantApplyMethod, "<", src.class
- end
- end
-
- # call-seq:
- # > source
- #
- # Outputs from +source+, which is either a string of a file name or an IO
- # object.
- def >(to)
- case to
- when String
- dst = @shell.open(to, "w")
- begin
- each(){|l| dst << l}
- ensure
- dst.close
- end
- when IO
- each(){|l| to << l}
- else
- Shell.Fail Error::CantApplyMethod, ">", to.class
- end
- self
- end
-
- # call-seq:
- # >> source
- #
- # Appends the output to +source+, which is either a string of a file name
- # or an IO object.
- def >>(to)
- begin
- Shell.cd(@shell.pwd).append(to, self)
- rescue CantApplyMethod
- Shell.Fail Error::CantApplyMethod, ">>", to.class
- end
- end
-
- # call-seq:
- # | filter
- #
- # Processes a pipeline.
- def |(filter)
- filter.input = self
- if active?
- @shell.process_controller.start_job filter
- end
- filter
- end
-
- # call-seq:
- # filter1 + filter2
- #
- # Outputs +filter1+, and then +filter2+ using Join.new
- def +(filter)
- Join.new(@shell, self, filter)
- end
-
- def to_a
- ary = []
- each(){|l| ary.push l}
- ary
- end
-
- def to_s
- str = ""
- each(){|l| str.concat l}
- str
- end
-
- def inspect
- if @shell.debug.kind_of?(Integer) && @shell.debug > 2
- super
- else
- to_s
- end
- end
- end
-end
diff --git a/lib/shell/process-controller.rb b/lib/shell/process-controller.rb
deleted file mode 100644
index d54da68cb0..0000000000
--- a/lib/shell/process-controller.rb
+++ /dev/null
@@ -1,309 +0,0 @@
-# frozen_string_literal: false
-#
-# shell/process-controller.rb -
-# $Release Version: 0.7 $
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-require "forwardable"
-require "sync"
-
-class Shell
- class ProcessController
-
- @ProcessControllers = {}
- @ProcessControllersMonitor = Thread::Mutex.new
- @ProcessControllersCV = Thread::ConditionVariable.new
-
- @BlockOutputMonitor = Thread::Mutex.new
- @BlockOutputCV = Thread::ConditionVariable.new
-
- class << self
- extend Forwardable
-
- def_delegator("@ProcessControllersMonitor",
- "synchronize", "process_controllers_exclusive")
-
- def active_process_controllers
- process_controllers_exclusive do
- @ProcessControllers.dup
- end
- end
-
- def activate(pc)
- process_controllers_exclusive do
- @ProcessControllers[pc] ||= 0
- @ProcessControllers[pc] += 1
- end
- end
-
- def inactivate(pc)
- process_controllers_exclusive do
- if @ProcessControllers[pc]
- if (@ProcessControllers[pc] -= 1) == 0
- @ProcessControllers.delete(pc)
- @ProcessControllersCV.signal
- end
- end
- end
- end
-
- def each_active_object
- process_controllers_exclusive do
- for ref in @ProcessControllers.keys
- yield ref
- end
- end
- end
-
- def block_output_synchronize(&b)
- @BlockOutputMonitor.synchronize(&b)
- end
-
- def wait_to_finish_all_process_controllers
- process_controllers_exclusive do
- while !@ProcessControllers.empty?
- Shell::notify("Process finishing, but active shell exists",
- "You can use Shell#transact or Shell#check_point for more safe execution.")
- if Shell.debug?
- for pc in @ProcessControllers.keys
- Shell::notify(" Not finished jobs in "+pc.shell.to_s)
- for com in pc.jobs
- com.notify(" Jobs: %id")
- end
- end
- end
- @ProcessControllersCV.wait(@ProcessControllersMonitor)
- end
- end
- end
- end
-
- # for shell-command complete finish at this process exit.
- USING_AT_EXIT_WHEN_PROCESS_EXIT = true
- at_exit do
- wait_to_finish_all_process_controllers unless $@
- end
-
- def initialize(shell)
- @shell = shell
- @waiting_jobs = []
- @active_jobs = []
- @jobs_sync = Sync.new
-
- @job_monitor = Thread::Mutex.new
- @job_condition = Thread::ConditionVariable.new
- end
-
- attr_reader :shell
-
- def jobs
- jobs = []
- @jobs_sync.synchronize(:SH) do
- jobs.concat @waiting_jobs
- jobs.concat @active_jobs
- end
- jobs
- end
-
- def active_jobs
- @active_jobs
- end
-
- def waiting_jobs
- @waiting_jobs
- end
-
- def jobs_exist?
- @jobs_sync.synchronize(:SH) do
- @active_jobs.empty? or @waiting_jobs.empty?
- end
- end
-
- def active_jobs_exist?
- @jobs_sync.synchronize(:SH) do
- @active_jobs.empty?
- end
- end
-
- def waiting_jobs_exist?
- @jobs_sync.synchronize(:SH) do
- @waiting_jobs.empty?
- end
- end
-
- # schedule a command
- def add_schedule(command)
- @jobs_sync.synchronize(:EX) do
- ProcessController.activate(self)
- if @active_jobs.empty?
- start_job command
- else
- @waiting_jobs.push(command)
- end
- end
- end
-
- # start a job
- def start_job(command = nil)
- @jobs_sync.synchronize(:EX) do
- if command
- return if command.active?
- @waiting_jobs.delete command
- else
- command = @waiting_jobs.shift
-
- return unless command
- end
- @active_jobs.push command
- command.start
-
- # start all jobs that input from the job
- for job in @waiting_jobs.dup
- start_job(job) if job.input == command
- end
- end
- end
-
- def waiting_job?(job)
- @jobs_sync.synchronize(:SH) do
- @waiting_jobs.include?(job)
- end
- end
-
- def active_job?(job)
- @jobs_sync.synchronize(:SH) do
- @active_jobs.include?(job)
- end
- end
-
- # terminate a job
- def terminate_job(command)
- @jobs_sync.synchronize(:EX) do
- @active_jobs.delete command
- ProcessController.inactivate(self)
- if @active_jobs.empty?
- command.notify("start_job in terminate_job(%id)", Shell::debug?)
- start_job
- end
- end
- end
-
- # kill a job
- def kill_job(sig, command)
- @jobs_sync.synchronize(:EX) do
- if @waiting_jobs.delete command
- ProcessController.inactivate(self)
- return
- elsif @active_jobs.include?(command)
- begin
- r = command.kill(sig)
- ProcessController.inactivate(self)
- rescue
- print "Shell: Warn: $!\n" if @shell.verbose?
- return nil
- end
- @active_jobs.delete command
- r
- end
- end
- end
-
- # wait for all jobs to terminate
- def wait_all_jobs_execution
- @job_monitor.synchronize do
- begin
- while !jobs.empty?
- @job_condition.wait(@job_monitor)
- for job in jobs
- job.notify("waiting job(%id)", Shell::debug?)
- end
- end
- ensure
- redo unless jobs.empty?
- end
- end
- end
-
- # simple fork
- def sfork(command)
- pipe_me_in, pipe_peer_out = IO.pipe
- pipe_peer_in, pipe_me_out = IO.pipe
-
-
- pid = nil
- pid_mutex = Thread::Mutex.new
- pid_cv = Thread::ConditionVariable.new
-
- Thread.start do
- ProcessController.block_output_synchronize do
- STDOUT.flush
- ProcessController.each_active_object do |pc|
- for jobs in pc.active_jobs
- jobs.flush
- end
- end
-
- pid = fork {
- Thread.list.each do |th|
- th.kill unless Thread.current == th
- end
-
- STDIN.reopen(pipe_peer_in)
- STDOUT.reopen(pipe_peer_out)
-
- ObjectSpace.each_object(IO) do |io|
- if ![STDIN, STDOUT, STDERR].include?(io)
- io.close
- end
- end
-
- yield
- }
- end
- pid_cv.signal
-
- pipe_peer_in.close
- pipe_peer_out.close
- command.notify "job(%name:##{pid}) start", @shell.debug?
-
- begin
- _pid = nil
- command.notify("job(%id) start to waiting finish.", @shell.debug?)
- _pid = Process.waitpid(pid, nil)
- rescue Errno::ECHILD
- command.notify "warn: job(%id) was done already waitpid."
- _pid = true
- ensure
- command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?)
- # when the process ends, wait until the command terminates
- if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid
- else
- command.notify("notice: Process finishing...",
- "wait for Job[%id] to finish.",
- "You can use Shell#transact or Shell#check_point for more safe execution.")
- redo
- end
-
- @job_monitor.synchronize do
- terminate_job(command)
- @job_condition.signal
- command.notify "job(%id) finish.", @shell.debug?
- end
- end
- end
-
- pid_mutex.synchronize do
- while !pid
- pid_cv.wait(pid_mutex)
- end
- end
-
- return pid, pipe_me_in, pipe_me_out
- end
- end
-end
diff --git a/lib/shell/system-command.rb b/lib/shell/system-command.rb
deleted file mode 100644
index af22ed90d7..0000000000
--- a/lib/shell/system-command.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-# frozen_string_literal: false
-#
-# shell/system-command.rb -
-# $Release Version: 0.7 $
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-require "shell/filter"
-
-class Shell
- class SystemCommand < Filter
- def initialize(sh, command, *opts)
- if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
- Shell.Fail TypeError, t.class, "String"
- end
- super(sh)
- @command = command
- @opts = opts
-
- @input_queue = Thread::Queue.new
- @pid = nil
-
- sh.process_controller.add_schedule(self)
- end
-
- attr_reader :command
- alias name command
-
- def wait?
- @shell.process_controller.waiting_job?(self)
- end
-
- def active?
- @shell.process_controller.active_job?(self)
- end
-
- def input=(inp)
- super
- if active?
- start_export
- end
- end
-
- def start
- notify([@command, *@opts].join(" "))
-
- @pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
- Dir.chdir @shell.pwd
- $0 = @command
- exec(@command, *@opts)
- }
- if @input
- start_export
- end
- start_import
- end
-
- def flush
- @pipe_out.flush if @pipe_out and !@pipe_out.closed?
- end
-
- def terminate
- begin
- @pipe_in.close
- rescue IOError
- end
- begin
- @pipe_out.close
- rescue IOError
- end
- end
-
- def kill(sig)
- if @pid
- Process.kill(sig, @pid)
- end
- end
-
- def start_import
- notify "Job(%id) start imp-pipe.", @shell.debug?
- _eop = true
- Thread.start {
- begin
- while l = @pipe_in.gets
- @input_queue.push l
- end
- _eop = false
- rescue Errno::EPIPE
- _eop = false
- ensure
- if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
- notify("warn: Process finishing...",
- "wait for Job[%id] to finish pipe importing.",
- "You can use Shell#transact or Shell#check_point for more safe execution.")
- redo
- end
- notify "job(%id}) close imp-pipe.", @shell.debug?
- @input_queue.push :EOF
- @pipe_in.close
- end
- }
- end
-
- def start_export
- notify "job(%id) start exp-pipe.", @shell.debug?
- _eop = true
- Thread.start{
- begin
- @input.each do |l|
- ProcessController::block_output_synchronize do
- @pipe_out.print l
- end
- end
- _eop = false
- rescue Errno::EPIPE, Errno::EIO
- _eop = false
- ensure
- if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
- notify("shell: warn: Process finishing...",
- "wait for Job(%id) to finish pipe exporting.",
- "You can use Shell#transact or Shell#check_point for more safe execution.")
- redo
- end
- notify "job(%id) close exp-pipe.", @shell.debug?
- @pipe_out.close
- end
- }
- end
-
- alias super_each each
- def each(rs = nil)
- while (l = @input_queue.pop) != :EOF
- yield l
- end
- end
-
- # ex)
- # if you wish to output:
- # "shell: job(#{@command}:#{@pid}) close pipe-out."
- # then
- # mes: "job(%id) close pipe-out."
- # yorn: Boolean(@shell.debug? or @shell.verbose?)
- def notify(*opts)
- @shell.notify(*opts) do |mes|
- yield mes if iterator?
-
- mes.gsub!("%id", "#{@command}:##{@pid}")
- mes.gsub!("%name", "#{@command}")
- mes.gsub!("%pid", "#{@pid}")
- mes
- end
- end
- end
-end
diff --git a/lib/shell/version.rb b/lib/shell/version.rb
deleted file mode 100644
index bb4e7dfb8e..0000000000
--- a/lib/shell/version.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: false
-#
-# version.rb - shell version definition file
-# $Release Version: 0.7$
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-# --
-#
-#
-#
-
-class Shell # :nodoc:
- @RELEASE_VERSION = "0.7"
- @LAST_UPDATE_DATE = "07/03/20"
-end
diff --git a/lib/shellwords.gemspec b/lib/shellwords.gemspec
new file mode 100644
index 0000000000..8ae87b230e
--- /dev/null
+++ b/lib/shellwords.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "shellwords"
+ spec.version = "0.1.0"
+ spec.authors = ["Akinori MUSHA"]
+ spec.email = ["knu@idaemons.org"]
+
+ spec.summary = %q{Manipulates strings with word parsing rules of UNIX Bourne shell.}
+ spec.description = %q{Manipulates strings with word parsing rules of UNIX Bourne shell.}
+ spec.homepage = "https://github.com/ruby/shellwords"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/shellwords.rb b/lib/shellwords.rb
index eb5fa2d226..4368a53ea8 100644
--- a/lib/shellwords.rb
+++ b/lib/shellwords.rb
@@ -24,28 +24,37 @@
# argv = "see how they run".shellsplit
# argv #=> ["see", "how", "they", "run"]
#
-# Be careful you don't leave a quote unmatched.
+# They treat quotes as special characters, so an unmatched quote will
+# cause an ArgumentError.
#
# argv = "they all ran after the farmer's wife".shellsplit
-# #=> ArgumentError: Unmatched double quote: ...
+# #=> ArgumentError: Unmatched quote: ...
#
-# In this case, you might want to use Shellwords.escape, or its alias
-# String#shellescape.
+# Shellwords also provides methods that do the opposite.
+# Shellwords.escape, or its alias, String#shellescape, escapes
+# shell metacharacters in a string for use in a command line.
#
-# This method will escape the String for you to safely use with a Bourne shell.
+# filename = "special's.txt"
#
-# argv = Shellwords.escape("special's.txt")
-# argv #=> "special\\'s.txt"
-# system("cat " + argv)
+# system("cat -- #{filename.shellescape}")
+# # runs "cat -- special\\'s.txt"
+#
+# Note the '--'. Without it, cat(1) will treat the following argument
+# as a command line option if it starts with '-'. It is guaranteed
+# that Shellwords.escape converts a string to a form that a Bourne
+# shell will parse back to the original string, but it is the
+# programmer's responsibility to make sure that passing an arbitrary
+# argument to a command does no harm.
#
# Shellwords also comes with a core extension for Array, Array#shelljoin.
#
-# argv = %w{ls -lta lib}
-# system(argv.shelljoin)
+# dir = "Funny GIFs"
+# argv = %W[ls -lta -- #{dir}]
+# system(argv.shelljoin + " | less")
+# # runs "ls -lta -- Funny\\ GIFs | less"
#
-# You can use this method to create an escaped string out of an array of tokens
-# separated by a space. In this example we used the literal shortcut for
-# Array.new.
+# You can use this method to build a complete command line out of an
+# array of arguments.
#
# === Authors
# * Wakou Aoyama
@@ -81,7 +90,7 @@ module Shellwords
field = String.new
line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
|word, sq, dq, esc, garbage, sep|
- raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
+ raise ArgumentError, "Unmatched quote: #{line.inspect}" if garbage
# 2.2.3 Double-Quotes:
#
# The <backslash> shall retain its special meaning as an
@@ -123,7 +132,7 @@ module Shellwords
#
# # Search files in lib for method definitions
# pattern = "^[ \t]*def "
- # open("| grep -Ern #{pattern.shellescape} lib") { |grep|
+ # open("| grep -Ern -e #{pattern.shellescape} lib") { |grep|
# grep.each_line { |line|
# file, lineno, matched_line = line.split(':', 3)
# # ...
@@ -147,7 +156,7 @@ module Shellwords
# Treat multibyte characters as is. It is the caller's responsibility
# to encode the string in the right encoding for the shell
# environment.
- str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1")
+ str.gsub!(/[^A-Za-z0-9_\-.,:+\/@\n]/, "\\\\\\&")
# A LF cannot be escaped with a backslash because a backslash + LF
# combo is regarded as a line continuation and simply ignored.
diff --git a/lib/singleton.rb b/lib/singleton.rb
index 368febc74d..07420d2ea2 100644
--- a/lib/singleton.rb
+++ b/lib/singleton.rb
@@ -13,7 +13,7 @@
#
# This ensures that only one instance of Klass can be created.
#
-# a,b = Klass.instance, Klass.instance
+# a,b = Klass.instance, Klass.instance
#
# a == b
# # => true
@@ -58,10 +58,9 @@
# == Singleton and Marshal
#
# By default Singleton's #_dump(depth) returns the empty string. Marshalling by
-# default will strip state information, e.g. instance variables and taint
-# state, from the instance. Classes using Singleton can provide custom
-# _load(str) and _dump(depth) methods to retain some of the previous state of
-# the instance.
+# default will strip state information, e.g. instance variables from the instance.
+# Classes using Singleton can provide custom _load(str) and _dump(depth) methods
+# to retain some of the previous state of the instance.
#
# require 'singleton'
#
@@ -82,7 +81,6 @@
# a = Example.instance
# a.keep = "keep this"
# a.strip = "get rid of this"
-# a.taint
#
# stored_state = Marshal.dump(a)
#
@@ -94,6 +92,8 @@
# p a.strip # => nil
#
module Singleton
+ VERSION = "0.1.1"
+
# Raises a TypeError to prevent cloning.
def clone
raise TypeError, "can't clone instance of singleton #{self.class}"
@@ -120,6 +120,15 @@ module Singleton
instance
end
+ def instance # :nodoc:
+ return @singleton__instance__ if @singleton__instance__
+ @singleton__mutex__.synchronize {
+ return @singleton__instance__ if @singleton__instance__
+ @singleton__instance__ = new()
+ }
+ @singleton__instance__
+ end
+
private
def inherited(sub_klass)
@@ -134,14 +143,6 @@ module Singleton
@singleton__instance__ = nil
@singleton__mutex__ = Thread::Mutex.new
}
- def klass.instance # :nodoc:
- return @singleton__instance__ if @singleton__instance__
- @singleton__mutex__.synchronize {
- return @singleton__instance__ if @singleton__instance__
- @singleton__instance__ = new()
- }
- @singleton__instance__
- end
klass
end
@@ -169,4 +170,8 @@ module Singleton
##
# :singleton-method: _load
# By default calls instance(). Override to retain singleton state.
+
+ ##
+ # :singleton-method: instance
+ # Returns the singleton instance.
end
diff --git a/lib/singleton/singleton.gemspec b/lib/singleton/singleton.gemspec
new file mode 100644
index 0000000000..88d3111b65
--- /dev/null
+++ b/lib/singleton/singleton.gemspec
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{The Singleton module implements the Singleton pattern.}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/singleton"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/sync.rb b/lib/sync.rb
deleted file mode 100644
index 40a48ac985..0000000000
--- a/lib/sync.rb
+++ /dev/null
@@ -1,329 +0,0 @@
-# frozen_string_literal: false
-#
-# sync.rb - 2 phase lock with counter
-# $Release Version: 1.0$
-# $Revision$
-# by Keiju ISHITSUKA(keiju@ishitsuka.com)
-#
-# --
-# Sync_m, Synchronizer_m
-# Usage:
-# obj.extend(Sync_m)
-# or
-# class Foo
-# include Sync_m
-# :
-# end
-#
-# Sync_m#sync_mode
-# Sync_m#sync_locked?, locked?
-# Sync_m#sync_shared?, shared?
-# Sync_m#sync_exclusive?, sync_exclusive?
-# Sync_m#sync_try_lock, try_lock
-# Sync_m#sync_lock, lock
-# Sync_m#sync_unlock, unlock
-#
-# Sync, Synchronizer:
-# Usage:
-# sync = Sync.new
-#
-# Sync#mode
-# Sync#locked?
-# Sync#shared?
-# Sync#exclusive?
-# Sync#try_lock(mode) -- mode = :EX, :SH, :UN
-# Sync#lock(mode) -- mode = :EX, :SH, :UN
-# Sync#unlock
-# Sync#synchronize(mode) {...}
-#
-#
-
-unless defined? Thread
- raise "Thread not available for this ruby interpreter"
-end
-
-##
-# A module that provides a two-phase lock with a counter.
-
-module Sync_m
- # lock mode
- UN = :UN
- SH = :SH
- EX = :EX
-
- # exceptions
- class Err < StandardError
- def Err.Fail(*opt)
- fail self, sprintf(self::Message, *opt)
- end
-
- class UnknownLocker < Err
- Message = "Thread(%s) not locked."
- def UnknownLocker.Fail(th)
- super(th.inspect)
- end
- end
-
- class LockModeFailer < Err
- Message = "Unknown lock mode(%s)"
- def LockModeFailer.Fail(mode)
- if mode.id2name
- mode = mode.id2name
- end
- super(mode)
- end
- end
- end
-
- def Sync_m.define_aliases(cl)
- cl.module_eval %q{
- alias locked? sync_locked?
- alias shared? sync_shared?
- alias exclusive? sync_exclusive?
- alias lock sync_lock
- alias unlock sync_unlock
- alias try_lock sync_try_lock
- alias synchronize sync_synchronize
- }
- end
-
- def Sync_m.append_features(cl)
- super
- # do nothing for Modules
- # make aliases for Classes.
- define_aliases(cl) unless cl.instance_of?(Module)
- self
- end
-
- def Sync_m.extend_object(obj)
- super
- obj.sync_extend
- end
-
- def sync_extend
- unless (defined? locked? and
- defined? shared? and
- defined? exclusive? and
- defined? lock and
- defined? unlock and
- defined? try_lock and
- defined? synchronize)
- Sync_m.define_aliases(singleton_class)
- end
- sync_initialize
- end
-
- # accessing
- def sync_locked?
- sync_mode != UN
- end
-
- def sync_shared?
- sync_mode == SH
- end
-
- def sync_exclusive?
- sync_mode == EX
- end
-
- # locking methods.
- def sync_try_lock(mode = EX)
- return unlock if mode == UN
- @sync_mutex.synchronize do
- sync_try_lock_sub(mode)
- end
- end
-
- def sync_lock(m = EX)
- return unlock if m == UN
- Thread.handle_interrupt(StandardError => :on_blocking) do
- while true
- @sync_mutex.synchronize do
- begin
- if sync_try_lock_sub(m)
- return self
- else
- if sync_sh_locker[Thread.current]
- sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
- sync_sh_locker.delete(Thread.current)
- else
- unless sync_waiting.include?(Thread.current) || sync_upgrade_waiting.reverse_each.any?{|w| w.first == Thread.current }
- sync_waiting.push Thread.current
- end
- end
- @sync_mutex.sleep
- end
- ensure
- sync_waiting.delete(Thread.current)
- end
- end
- end
- end
- self
- end
-
- def sync_unlock(m = EX)
- wakeup_threads = []
- @sync_mutex.synchronize do
- if sync_mode == UN
- Err::UnknownLocker.Fail(Thread.current)
- end
-
- m = sync_mode if m == EX and sync_mode == SH
-
- runnable = false
- case m
- when UN
- Err::UnknownLocker.Fail(Thread.current)
-
- when EX
- if sync_ex_locker == Thread.current
- if (self.sync_ex_count = sync_ex_count - 1) == 0
- self.sync_ex_locker = nil
- if sync_sh_locker.include?(Thread.current)
- self.sync_mode = SH
- else
- self.sync_mode = UN
- end
- runnable = true
- end
- else
- Err::UnknownLocker.Fail(Thread.current)
- end
-
- when SH
- if (count = sync_sh_locker[Thread.current]).nil?
- Err::UnknownLocker.Fail(Thread.current)
- else
- if (sync_sh_locker[Thread.current] = count - 1) == 0
- sync_sh_locker.delete(Thread.current)
- if sync_sh_locker.empty? and sync_ex_count == 0
- self.sync_mode = UN
- runnable = true
- end
- end
- end
- end
-
- if runnable
- if sync_upgrade_waiting.size > 0
- th, count = sync_upgrade_waiting.shift
- sync_sh_locker[th] = count
- th.wakeup
- wakeup_threads.push th
- else
- wait = sync_waiting
- self.sync_waiting = []
- for th in wait
- th.wakeup
- wakeup_threads.push th
- end
- end
- end
- end
- for th in wakeup_threads
- th.run
- end
- self
- end
-
- def sync_synchronize(mode = EX)
- Thread.handle_interrupt(StandardError => :on_blocking) do
- sync_lock(mode)
- begin
- yield
- ensure
- sync_unlock
- end
- end
- end
-
- attr_accessor :sync_mode
-
- attr_accessor :sync_waiting
- attr_accessor :sync_upgrade_waiting
- attr_accessor :sync_sh_locker
- attr_accessor :sync_ex_locker
- attr_accessor :sync_ex_count
-
- def sync_inspect
- sync_iv = instance_variables.select{|iv| /^@sync_/ =~ iv.id2name}.collect{|iv| iv.id2name + '=' + instance_eval(iv.id2name).inspect}.join(",")
- print "<#{self.class}.extend Sync_m: #{inspect}, <Sync_m: #{sync_iv}>"
- end
-
- private
-
- def sync_initialize
- @sync_mode = UN
- @sync_waiting = []
- @sync_upgrade_waiting = []
- @sync_sh_locker = Hash.new
- @sync_ex_locker = nil
- @sync_ex_count = 0
-
- @sync_mutex = Thread::Mutex.new
- end
-
- def initialize(*args)
- super
- sync_initialize
- end
-
- def sync_try_lock_sub(m)
- case m
- when SH
- case sync_mode
- when UN
- self.sync_mode = m
- sync_sh_locker[Thread.current] = 1
- ret = true
- when SH
- count = 0 unless count = sync_sh_locker[Thread.current]
- sync_sh_locker[Thread.current] = count + 1
- ret = true
- when EX
- # in EX mode, lock will upgrade to EX lock
- if sync_ex_locker == Thread.current
- self.sync_ex_count = sync_ex_count + 1
- ret = true
- else
- ret = false
- end
- end
- when EX
- if sync_mode == UN or
- sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
- self.sync_mode = m
- self.sync_ex_locker = Thread.current
- self.sync_ex_count = 1
- ret = true
- elsif sync_mode == EX && sync_ex_locker == Thread.current
- self.sync_ex_count = sync_ex_count + 1
- ret = true
- else
- ret = false
- end
- else
- Err::LockModeFailer.Fail m
- end
- return ret
- end
-end
-
-##
-# An alias for Sync_m from sync.rb
-
-Synchronizer_m = Sync_m
-
-##
-# A class that provides two-phase lock with a counter. See Sync_m for
-# details.
-
-class Sync
- include Sync_m
-end
-
-##
-# An alias for Sync from sync.rb. See Sync_m for details.
-
-Synchronizer = Sync
diff --git a/lib/tempfile.gemspec b/lib/tempfile.gemspec
new file mode 100644
index 0000000000..4917b997e7
--- /dev/null
+++ b/lib/tempfile.gemspec
@@ -0,0 +1,24 @@
+Gem::Specification.new do |spec|
+ spec.name = "tempfile"
+ spec.version = "0.1.1"
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{A utility class for managing temporary files.}
+ spec.description = %q{A utility class for managing temporary files.}
+ spec.homepage = "https://github.com/ruby/tempfile"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/tempfile.rb b/lib/tempfile.rb
index 85b7720a48..1577e45bec 100644
--- a/lib/tempfile.rb
+++ b/lib/tempfile.rb
@@ -47,12 +47,20 @@ require 'tmpdir'
#
# file = Tempfile.new('foo')
# begin
-# ...do something with file...
+# # ...do something with file...
# ensure
# file.close
# file.unlink # deletes the temp file
# end
#
+# Tempfile.create { ... } exists for this purpose and is more convenient to use.
+# Note that Tempfile.create returns a File instance instead of a Tempfile, which
+# also avoids the overhead and complications of delegation.
+#
+# Tempfile.open('foo') do |file|
+# # ...do something with file...
+# end
+#
# === Unlink after creation
#
# On POSIX systems, it's possible to unlink a file right after creating it,
@@ -79,12 +87,13 @@ require 'tmpdir'
# same Tempfile object from multiple threads then you should protect it with a
# mutex.
class Tempfile < DelegateClass(File)
- # call-seq:
- # new(basename = "", [tmpdir = Dir.tmpdir], [options])
- #
# Creates a temporary file with permissions 0600 (= only readable and
# writable by the owner) and opens it with mode "w+".
#
+ # It is recommended to use Tempfile.create { ... } instead when possible,
+ # because that method avoids the cost of delegation and does not rely on a
+ # finalizer to close and unlink the file, which is unreliable.
+ #
# The +basename+ parameter is used to determine the name of the
# temporary file. You can either pass a String or an Array with
# 2 String elements. In the former form, the temporary file's base
@@ -101,10 +110,6 @@ class Tempfile < DelegateClass(File)
#
# The temporary file will be placed in the directory as specified
# by the +tmpdir+ parameter. By default, this is +Dir.tmpdir+.
- # When $SAFE > 0 and the given +tmpdir+ is tainted, it uses
- # '/tmp' as the temporary directory. Please note that ENV values
- # are tainted by default, and +Dir.tmpdir+'s return value might
- # come from environment variables (e.g. <tt>$TMPDIR</tt>).
#
# file = Tempfile.new('hello', '/home/aisaka')
# file.path # => something like: "/home/aisaka/hello2843-8392-92849382--0"
@@ -114,23 +119,26 @@ class Tempfile < DelegateClass(File)
# +File.open+. This is mostly useful for specifying encoding
# options, e.g.:
#
- # Tempfile.new('hello', '/home/aisaka', :encoding => 'ascii-8bit')
+ # Tempfile.new('hello', '/home/aisaka', encoding: 'ascii-8bit')
#
# # You can also omit the 'tmpdir' parameter:
- # Tempfile.new('hello', :encoding => 'ascii-8bit')
+ # Tempfile.new('hello', encoding: 'ascii-8bit')
+ #
+ # Note: +mode+ keyword argument, as accepted by Tempfile, can only be
+ # numeric, combination of the modes defined in File::Constants.
#
# === Exceptions
#
# If Tempfile.new cannot find a unique filename within a limited
# number of tries, then it will raise an exception.
def initialize(basename="", tmpdir=nil, mode: 0, **options)
- warn "Tempfile.new doesn't call the given block." if block_given?
+ warn "Tempfile.new doesn't call the given block.", uplevel: 1 if block_given?
@unlinked = false
@mode = mode|File::RDWR|File::CREAT|File::EXCL
- ::Dir::Tmpname.create(basename, tmpdir, options) do |tmpname, n, opts|
+ ::Dir::Tmpname.create(basename, tmpdir, **options) do |tmpname, n, opts|
opts[:perm] = 0600
- @tmpfile = File.open(tmpname, @mode, opts)
+ @tmpfile = File.open(tmpname, @mode, **opts)
@opts = opts.freeze
end
ObjectSpace.define_finalizer(self, Remover.new(@tmpfile))
@@ -142,7 +150,7 @@ class Tempfile < DelegateClass(File)
def open
_close
mode = @mode & ~(File::CREAT|File::EXCL)
- @tmpfile = File.open(@tmpfile.path, mode, @opts)
+ @tmpfile = File.open(@tmpfile.path, mode, **@opts)
__setobj__(@tmpfile)
end
@@ -174,7 +182,7 @@ class Tempfile < DelegateClass(File)
#
# file = Tempfile.new('foo')
# begin
- # ...do something with file...
+ # # ...do something with file...
# ensure
# file.close
# file.unlink # deletes the temp file
@@ -195,7 +203,7 @@ class Tempfile < DelegateClass(File)
# file = Tempfile.new('foo')
# file.unlink # On Windows this silently fails.
# begin
- # ... do something with file ...
+ # # ... do something with file ...
# ensure
# file.close! # Closes the file handle. If the file wasn't unlinked
# # because #unlink failed, then this method will attempt
@@ -234,14 +242,14 @@ class Tempfile < DelegateClass(File)
# :stopdoc:
def inspect
- if closed?
+ if @tmpfile.closed?
"#<#{self.class}:#{path} (closed)>"
else
"#<#{self.class}:#{path}>"
end
end
- class Remover
+ class Remover # :nodoc:
def initialize(tmpfile)
@pid = Process.pid
@tmpfile = tmpfile
@@ -250,7 +258,7 @@ class Tempfile < DelegateClass(File)
def call(*args)
return if @pid != Process.pid
- warn "removing #{@tmpfile.path}..." if $DEBUG
+ $stderr.puts "removing #{@tmpfile.path}..." if $DEBUG
@tmpfile.close
begin
@@ -258,7 +266,7 @@ class Tempfile < DelegateClass(File)
rescue Errno::ENOENT
end
- warn "done" if $DEBUG
+ $stderr.puts "done" if $DEBUG
end
end
@@ -267,28 +275,42 @@ class Tempfile < DelegateClass(File)
# Creates a new Tempfile.
#
+ # This method is not recommended and exists mostly for backward compatibility.
+ # Please use Tempfile.create instead, which avoids the cost of delegation,
+ # does not rely on a finalizer, and also unlinks the file when given a block.
+ #
+ # Tempfile.open is still appropriate if you need the Tempfile to be unlinked
+ # by a finalizer and you cannot explicitly know where in the program the
+ # Tempfile can be unlinked safely.
+ #
# If no block is given, this is a synonym for Tempfile.new.
#
# If a block is given, then a Tempfile object will be constructed,
- # and the block is run with said object as argument. The Tempfile
+ # and the block is run with the Tempfile object as argument. The Tempfile
# object will be automatically closed after the block terminates.
+ # However, the file will *not* be unlinked and needs to be manually unlinked
+ # with Tempfile#close! or Tempfile#unlink. The finalizer will try to unlink
+ # but should not be relied upon as it can keep the file on the disk much
+ # longer than intended. For instance, on CRuby, finalizers can be delayed
+ # due to conservative stack scanning and references left in unused memory.
+ #
# The call returns the value of the block.
#
- # In any case, all arguments (+*args+) will be passed to Tempfile.new.
+ # In any case, all arguments (<code>*args</code>) will be passed to Tempfile.new.
#
# Tempfile.open('foo', '/home/temp') do |f|
- # ... do something with f ...
+ # # ... do something with f ...
# end
#
# # Equivalent:
# f = Tempfile.open('foo', '/home/temp')
# begin
- # ... do something with f ...
+ # # ... do something with f ...
# ensure
# f.close
# end
- def open(*args)
- tempfile = new(*args)
+ def open(*args, **kw)
+ tempfile = new(*args, **kw)
if block_given?
begin
@@ -303,32 +325,33 @@ class Tempfile < DelegateClass(File)
end
end
-# Creates a temporary file as usual File object (not Tempfile).
-# It doesn't use finalizer and delegation.
+# Creates a temporary file as a usual File object (not a Tempfile).
+# It does not use finalizer and delegation, which makes it more efficient and reliable.
#
# If no block is given, this is similar to Tempfile.new except
-# creating File instead of Tempfile.
-# The created file is not removed automatically.
-# You should use File.unlink to remove it.
+# creating File instead of Tempfile. In that case, the created file is
+# not removed automatically. You should use File.unlink to remove it.
#
# If a block is given, then a File object will be constructed,
# and the block is invoked with the object as the argument.
# The File object will be automatically closed and
-# the temporary file is removed after the block terminates.
+# the temporary file is removed after the block terminates,
+# releasing all resources that the block created.
# The call returns the value of the block.
#
-# In any case, all arguments (+*args+) will be treated as Tempfile.new.
+# In any case, all arguments (+basename+, +tmpdir+, +mode+, and
+# <code>**options</code>) will be treated the same as for Tempfile.new.
#
# Tempfile.create('foo', '/home/temp') do |f|
-# ... do something with f ...
+# # ... do something with f ...
# end
#
def Tempfile.create(basename="", tmpdir=nil, mode: 0, **options)
tmpfile = nil
- Dir::Tmpname.create(basename, tmpdir, options) do |tmpname, n, opts|
+ Dir::Tmpname.create(basename, tmpdir, **options) do |tmpname, n, opts|
mode |= File::RDWR|File::CREAT|File::EXCL
opts[:perm] = 0600
- tmpfile = File.open(tmpname, mode, opts)
+ tmpfile = File.open(tmpname, mode, **opts)
end
if block_given?
begin
diff --git a/lib/thwait.rb b/lib/thwait.rb
deleted file mode 100644
index 8f9e0c2a78..0000000000
--- a/lib/thwait.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-# frozen_string_literal: false
-#
-# thwait.rb - thread synchronization class
-# $Release Version: 0.9 $
-# $Revision: 1.3 $
-# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.)
-
-require "e2mmap.rb"
-
-#
-# This class watches for termination of multiple threads. Basic functionality
-# (wait until specified threads have terminated) can be accessed through the
-# class method ThreadsWait::all_waits. Finer control can be gained using
-# instance methods.
-#
-# Example:
-#
-# ThreadsWait.all_waits(thr1, thr2, ...) do |t|
-# STDERR.puts "Thread #{t} has terminated."
-# end
-#
-#
-# th = ThreadsWait.new(thread1,...)
-# th.next_wait # next one to be done
-#
-#
-class ThreadsWait
- extend Exception2MessageMapper
- def_exception("ErrNoWaitingThread", "No threads for waiting.")
- def_exception("ErrNoFinishedThread", "No finished threads.")
-
- #
- # Waits until all specified threads have terminated. If a block is provided,
- # it is executed for each thread as they terminate.
- #
- def ThreadsWait.all_waits(*threads) # :yield: thread
- tw = ThreadsWait.new(*threads)
- if block_given?
- tw.all_waits do |th|
- yield th
- end
- else
- tw.all_waits
- end
- end
-
- #
- # Creates a ThreadsWait object, specifying the threads to wait on.
- # Non-blocking.
- #
- def initialize(*threads)
- @threads = []
- @wait_queue = Thread::Queue.new
- join_nowait(*threads) unless threads.empty?
- end
-
- # Returns the array of threads that have not terminated yet.
- attr_reader :threads
-
- #
- # Returns +true+ if there are no threads in the pool still running.
- #
- def empty?
- @threads.empty?
- end
-
- #
- # Returns +true+ if any thread has terminated and is ready to be collected.
- #
- def finished?
- !@wait_queue.empty?
- end
-
- #
- # Waits for specified threads to terminate, and returns when one of
- # the threads terminated.
- #
- def join(*threads)
- join_nowait(*threads)
- next_wait
- end
-
- #
- # Specifies the threads that this object will wait for, but does not actually
- # wait.
- #
- def join_nowait(*threads)
- threads.flatten!
- @threads.concat threads
- for th in threads
- Thread.start(th) do |t|
- begin
- t.join
- ensure
- @wait_queue.push t
- end
- end
- end
- end
-
- #
- # Waits until any of the specified threads has terminated, and returns the one
- # that does.
- #
- # If there is no thread to wait, raises +ErrNoWaitingThread+. If +nonblock+
- # is true, and there is no terminated thread, raises +ErrNoFinishedThread+.
- #
- def next_wait(nonblock = nil)
- ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
- begin
- @threads.delete(th = @wait_queue.pop(nonblock))
- th
- rescue ThreadError
- ThreadsWait.fail ErrNoFinishedThread
- end
- end
-
- #
- # Waits until all of the specified threads are terminated. If a block is
- # supplied for the method, it is executed for each thread termination.
- #
- # Raises exceptions in the same manner as +next_wait+.
- #
- def all_waits
- until @threads.empty?
- th = next_wait
- yield th if block_given?
- end
- end
-end
-
-##
-# An alias for ThreadsWait from thwait.rb
-
-ThWait = ThreadsWait
-
-# Documentation comments:
-# - Source of documentation is evenly split between Nutshell, existing
-# comments, and my own rephrasing.
-# - I'm not particularly confident that the comments are all exactly correct.
diff --git a/lib/time.gemspec b/lib/time.gemspec
new file mode 100644
index 0000000000..be6de35c99
--- /dev/null
+++ b/lib/time.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "time"
+ spec.version = "0.1.1"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Extends the Time class with methods for parsing and conversion.}
+ spec.description = %q{Extends the Time class with methods for parsing and conversion.}
+ spec.homepage = "https://github.com/ruby/time"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/time.rb b/lib/time.rb
index 5179e9fee4..8af482cb68 100644
--- a/lib/time.rb
+++ b/lib/time.rb
@@ -2,6 +2,8 @@
require 'date'
+# :stopdoc:
+
# = time.rb
#
# When 'time' is required, Time is extended with additional methods for parsing
@@ -18,73 +20,8 @@ require 'date'
# 8601}[http://www.iso.org/iso/date_and_time_format])
# * various formats handled by Date._parse
# * custom formats handled by Date._strptime
-#
-# == Examples
-#
-# All examples assume you have loaded Time with:
-#
-# require 'time'
-#
-# All of these examples were done using the EST timezone which is GMT-5.
-#
-# === Converting to a String
-#
-# t = Time.now
-# t.iso8601 # => "2011-10-05T22:26:12-04:00"
-# t.rfc2822 # => "Wed, 05 Oct 2011 22:26:12 -0400"
-# t.httpdate # => "Thu, 06 Oct 2011 02:26:12 GMT"
-#
-# === Time.parse
-#
-# #parse takes a string representation of a Time and attempts to parse it
-# using a heuristic.
-#
-# Time.parse("2010-10-31") #=> 2010-10-31 00:00:00 -0500
-#
-# Any missing pieces of the date are inferred based on the current date.
-#
-# # assuming the current date is "2011-10-31"
-# Time.parse("12:00") #=> 2011-10-31 12:00:00 -0500
-#
-# We can change the date used to infer our missing elements by passing a second
-# object that responds to #mon, #day and #year, such as Date, Time or DateTime.
-# We can also use our own object.
-#
-# class MyDate
-# attr_reader :mon, :day, :year
-#
-# def initialize(mon, day, year)
-# @mon, @day, @year = mon, day, year
-# end
-# end
-#
-# d = Date.parse("2010-10-28")
-# t = Time.parse("2010-10-29")
-# dt = DateTime.parse("2010-10-30")
-# md = MyDate.new(10,31,2010)
-#
-# Time.parse("12:00", d) #=> 2010-10-28 12:00:00 -0500
-# Time.parse("12:00", t) #=> 2010-10-29 12:00:00 -0500
-# Time.parse("12:00", dt) #=> 2010-10-30 12:00:00 -0500
-# Time.parse("12:00", md) #=> 2010-10-31 12:00:00 -0500
-#
-# #parse also accepts an optional block. You can use this block to specify how
-# to handle the year component of the date. This is specifically designed for
-# handling two digit years. For example, if you wanted to treat all two digit
-# years prior to 70 as the year 2000+ you could write this:
-#
-# Time.parse("01-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
-# #=> 2001-10-31 00:00:00 -0500
-# Time.parse("70-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
-# #=> 1970-10-31 00:00:00 -0500
-#
-# === Time.strptime
-#
-# #strptime works similar to +parse+ except that instead of using a heuristic
-# to detect the format of the input string, you provide a second argument that
-# describes the format of the string. For example:
-#
-# Time.strptime("2000-10-31", "%Y-%m-%d") #=> 2000-10-31 00:00:00 -0500
+
+# :startdoc:
class Time
class << Time
@@ -131,12 +68,19 @@ class Time
#
# If +zone_offset+ is unable to determine the offset, nil will be
# returned.
+ #
+ # require 'time'
+ #
+ # Time.zone_offset("EST") #=> -18000
+ #
+ # You must require 'time' to use this method.
+ #
def zone_offset(zone, year=self.now.year)
off = nil
zone = zone.upcase
- if /\A([+-])(\d\d):?(\d\d)\z/ =~ zone
- off = ($1 == '-' ? -1 : 1) * ($2.to_i * 60 + $3.to_i) * 60
- elsif /\A[+-]\d\d\z/ =~ zone
+ if /\A([+-])(\d\d)(:?)(\d\d)(?:\3(\d\d))?\z/ =~ zone
+ off = ($1 == '-' ? -1 : 1) * (($2.to_i * 60 + $4.to_i) * 60 + $5.to_i)
+ elsif zone.match?(/\A[+-]\d\d\z/)
off = zone.to_i * 3600
elsif ZoneOffset.include?(zone)
off = ZoneOffset[zone] * 3600
@@ -168,11 +112,7 @@ class Time
# They are not appropriate for specific time zone such as
# Europe/London because time zone neutral,
# So -00:00 and -0000 are treated as UTC.
- if /\A(?:-00:00|-0000|-00|UTC|Z|UT)\z/i =~ zone
- true
- else
- false
- end
+ zone.match?(/\A(?:-00:00|-0000|-00|UTC|Z|UT)\z/i)
end
private :zone_utc?
@@ -249,8 +189,8 @@ class Time
end
private :apply_offset
- def make_time(date, year, mon, day, hour, min, sec, sec_fraction, zone, now)
- if !year && !mon && !day && !hour && !min && !sec && !sec_fraction
+ def make_time(date, year, yday, mon, day, hour, min, sec, sec_fraction, zone, now)
+ if !year && !yday && !mon && !day && !hour && !min && !sec && !sec_fraction
raise ArgumentError, "no time information in #{date.inspect}"
end
@@ -260,7 +200,27 @@ class Time
off = zone_offset(zone, off_year) if zone
end
- if now
+ if yday
+ unless (1..366) === yday
+ raise ArgumentError, "yday #{yday} out of range"
+ end
+ mon, day = (yday-1).divmod(31)
+ mon += 1
+ day += 1
+ t = make_time(date, year, nil, mon, day, hour, min, sec, sec_fraction, zone, now)
+ diff = yday - t.yday
+ return t if diff.zero?
+ day += diff
+ if day > 28 and day > (mday = month_days(off_year, mon))
+ if (mon += 1) > 12
+ raise ArgumentError, "yday #{yday} out of range"
+ end
+ day -= mday
+ end
+ return make_time(date, year, nil, mon, day, hour, min, sec, sec_fraction, zone, now)
+ end
+
+ if now and now.respond_to?(:getlocal)
if off
now = now.getlocal(off) if now.utc_offset != off
else
@@ -309,17 +269,67 @@ class Time
private :make_time
#
- # Parses +date+ using Date._parse and converts it to a Time object.
+ # Takes a string representation of a Time and attempts to parse it
+ # using a heuristic.
#
- # If a block is given, the year described in +date+ is converted by the
- # block. For example:
+ # This method **does not** function as a validator. If the input
+ # string does not match valid formats strictly, you may get a
+ # cryptic result. Should consider to use `Time.strptime` instead
+ # of this method as possible.
+ #
+ # require 'time'
+ #
+ # Time.parse("2010-10-31") #=> 2010-10-31 00:00:00 -0500
+ #
+ # Any missing pieces of the date are inferred based on the current date.
+ #
+ # require 'time'
+ #
+ # # assuming the current date is "2011-10-31"
+ # Time.parse("12:00") #=> 2011-10-31 12:00:00 -0500
+ #
+ # We can change the date used to infer our missing elements by passing a second
+ # object that responds to #mon, #day and #year, such as Date, Time or DateTime.
+ # We can also use our own object.
+ #
+ # require 'time'
+ #
+ # class MyDate
+ # attr_reader :mon, :day, :year
+ #
+ # def initialize(mon, day, year)
+ # @mon, @day, @year = mon, day, year
+ # end
+ # end
#
- # Time.parse(...) {|y| 0 <= y && y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}
+ # d = Date.parse("2010-10-28")
+ # t = Time.parse("2010-10-29")
+ # dt = DateTime.parse("2010-10-30")
+ # md = MyDate.new(10,31,2010)
+ #
+ # Time.parse("12:00", d) #=> 2010-10-28 12:00:00 -0500
+ # Time.parse("12:00", t) #=> 2010-10-29 12:00:00 -0500
+ # Time.parse("12:00", dt) #=> 2010-10-30 12:00:00 -0500
+ # Time.parse("12:00", md) #=> 2010-10-31 12:00:00 -0500
+ #
+ # If a block is given, the year described in +date+ is converted
+ # by the block. This is specifically designed for handling two
+ # digit years. For example, if you wanted to treat all two digit
+ # years prior to 70 as the year 2000+ you could write this:
+ #
+ # require 'time'
+ #
+ # Time.parse("01-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
+ # #=> 2001-10-31 00:00:00 -0500
+ # Time.parse("70-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
+ # #=> 1970-10-31 00:00:00 -0500
#
# If the upper components of the given time are broken or missing, they are
# supplied with those of +now+. For the lower components, the minimum
# values (1 or 0) are assumed if broken or missing. For example:
#
+ # require 'time'
+ #
# # Suppose it is "Thu Nov 29 14:33:20 2001" now and
# # your time zone is EST which is GMT-5.
# now = Time.parse("Thu Nov 29 14:33:20 2001")
@@ -367,11 +377,13 @@ class Time
d = Date._parse(date, comp)
year = d[:year]
year = yield(year) if year && !comp
- make_time(date, year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
+ make_time(date, year, d[:yday], d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
end
#
- # Parses +date+ using Date._strptime and converts it to a Time object.
+ # Works similar to +parse+ except that instead of using a
+ # heuristic to detect the format of the input string, you provide
+ # a second argument that describes the format of the string.
#
# If a block is given, the year described in +date+ is converted by the
# block. For example:
@@ -390,6 +402,9 @@ class Time
# %D :: Date (%m/%d/%y)
# %e :: Day of the month, blank-padded ( 1..31)
# %F :: Equivalent to %Y-%m-%d (the ISO 8601 date format)
+ # %g :: The last two digits of the commercial year
+ # %G :: The week-based year according to ISO-8601 (week 1 starts on Monday
+ # and includes January 4)
# %h :: Equivalent to %b
# %H :: Hour of the day, 24-hour clock (00..23)
# %I :: Hour of the day, 12-hour clock (01..12)
@@ -400,10 +415,7 @@ class Time
# %m :: Month of the year (01..12)
# %M :: Minute of the hour (00..59)
# %n :: Newline (\n)
- # %N :: Fractional seconds digits, default is 9 digits (nanosecond)
- # %3N :: millisecond (3 digits)
- # %6N :: microsecond (6 digits)
- # %9N :: nanosecond (9 digits)
+ # %N :: Fractional seconds digits
# %p :: Meridian indicator ("AM" or "PM")
# %P :: Meridian indicator ("am" or "pm")
# %r :: time, 12-hour (same as %I:%M:%S %p)
@@ -427,10 +439,17 @@ class Time
# %z :: Time zone as hour offset from UTC (e.g. +0900)
# %Z :: Time zone name
# %% :: Literal "%" character
-
+ # %+ :: date(1) (%a %b %e %H:%M:%S %Z %Y)
+ #
+ # require 'time'
+ #
+ # Time.strptime("2000-10-31", "%Y-%m-%d") #=> 2000-10-31 00:00:00 -0500
+ #
+ # You must require 'time' to use this method.
+ #
def strptime(date, format, now=self.now)
d = Date._strptime(date, format)
- raise ArgumentError, "invalid strptime format - `#{format}'" unless d
+ raise ArgumentError, "invalid date or strptime format - `#{date}' `#{format}'" unless d
if seconds = d[:seconds]
if sec_fraction = d[:sec_fraction]
usec = sec_fraction * 1000000
@@ -445,7 +464,15 @@ class Time
else
year = d[:year]
year = yield(year) if year && block_given?
- t = make_time(date, year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
+ yday = d[:yday]
+ if (d[:cwyear] && !year) || ((d[:cwday] || d[:cweek]) && !(d[:mon] && d[:mday]))
+ # make_time doesn't deal with cwyear/cwday/cweek
+ return Date.strptime(date, format).to_time
+ end
+ if (d[:wnum0] || d[:wnum1]) && !yday && !(d[:mon] && d[:mday])
+ yday = Date.strptime(date, format).yday
+ end
+ t = make_time(date, year, yday, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
end
t
end
@@ -465,6 +492,11 @@ class Time
#
# See #rfc2822 for more information on this format.
#
+ # require 'time'
+ #
+ # Time.rfc2822("Wed, 05 Oct 2011 22:26:12 -0400")
+ # #=> 2010-10-05 22:26:12 -0400
+ #
# You must require 'time' to use this method.
#
def rfc2822(date)
@@ -474,8 +506,8 @@ class Time
(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+
(\d{2,})\s+
(\d{2})\s*
- :\s*(\d{2})\s*
- (?::\s*(\d{2}))?\s+
+ :\s*(\d{2})
+ (?:\s*:\s*(\d\d))?\s+
([+-]\d{4}|
UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date
# Since RFC 2822 permit comments, the regexp has no right anchor.
@@ -518,17 +550,22 @@ class Time
#
# See #httpdate for more information on this format.
#
+ # require 'time'
+ #
+ # Time.httpdate("Thu, 06 Oct 2011 02:26:12 GMT")
+ # #=> 2011-10-06 02:26:12 UTC
+ #
# You must require 'time' to use this method.
#
def httpdate(date)
- if /\A\s*
+ if date.match?(/\A\s*
(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\x20
(\d{2})\x20
(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20
(\d{4})\x20
(\d{2}):(\d{2}):(\d{2})\x20
GMT
- \s*\z/ix =~ date
+ \s*\z/ix)
self.rfc2822(date).utc
elsif /\A\s*
(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\x20
@@ -558,25 +595,30 @@ class Time
end
#
- # Parses +date+ as a dateTime defined by the XML Schema and converts it to
+ # Parses +time+ as a dateTime defined by the XML Schema and converts it to
# a Time object. The format is a restricted version of the format defined
# by ISO 8601.
#
- # ArgumentError is raised if +date+ is not compliant with the format or if
- # the Time class cannot represent specified date.
+ # ArgumentError is raised if +time+ is not compliant with the format or if
+ # the Time class cannot represent the specified time.
#
# See #xmlschema for more information on this format.
#
+ # require 'time'
+ #
+ # Time.xmlschema("2011-10-05T22:26:12-04:00")
+ # #=> 2011-10-05 22:26:12-04:00
+ #
# You must require 'time' to use this method.
#
- def xmlschema(date)
+ def xmlschema(time)
if /\A\s*
(-?\d+)-(\d\d)-(\d\d)
T
(\d\d):(\d\d):(\d\d)
(\.\d+)?
- (Z|[+-]\d\d:\d\d)?
- \s*\z/ix =~ date
+ (Z|[+-]\d\d(?::?\d\d)?)?
+ \s*\z/ix =~ time
year = $1.to_i
mon = $2.to_i
day = $3.to_i
@@ -599,7 +641,7 @@ class Time
self.local(year, mon, day, hour, min, sec, usec)
end
else
- raise ArgumentError.new("invalid date: #{date.inspect}")
+ raise ArgumentError.new("invalid xmlschema format: #{time.inspect}")
end
end
alias iso8601 xmlschema
@@ -614,6 +656,11 @@ class Time
#
# If +self+ is a UTC time, -0000 is used as zone.
#
+ # require 'time'
+ #
+ # t = Time.now
+ # t.rfc2822 # => "Wed, 05 Oct 2011 22:26:12 -0400"
+ #
# You must require 'time' to use this method.
#
def rfc2822
@@ -649,6 +696,11 @@ class Time
#
# Note that the result is always UTC (GMT).
#
+ # require 'time'
+ #
+ # t = Time.now
+ # t.httpdate # => "Thu, 06 Oct 2011 02:26:12 GMT"
+ #
# You must require 'time' to use this method.
#
def httpdate
@@ -673,6 +725,11 @@ class Time
# +fractional_digits+ specifies a number of digits to use for fractional
# seconds. Its default value is 0.
#
+ # require 'time'
+ #
+ # t = Time.now
+ # t.iso8601 # => "2011-10-05T22:26:12-04:00"
+ #
# You must require 'time' to use this method.
#
def xmlschema(fraction_digits=0)
diff --git a/lib/timeout.rb b/lib/timeout.rb
index 9a0fc91156..0dc84b08b1 100644
--- a/lib/timeout.rb
+++ b/lib/timeout.rb
@@ -15,7 +15,7 @@
#
# Previous versions didn't use a module for namespacing, however
# #timeout is provided for backwards compatibility. You
-# should prefer Timeout#timeout instead.
+# should prefer Timeout.timeout instead.
#
# == Copyright
#
@@ -23,7 +23,9 @@
# Copyright:: (C) 2000 Information-technology Promotion Agency, Japan
module Timeout
- # Raised by Timeout#timeout when the block times out.
+ VERSION = "0.1.1"
+
+ # Raised by Timeout.timeout when the block times out.
class Error < RuntimeError
attr_reader :thread
@@ -67,7 +69,9 @@ module Timeout
# +sec+ seconds, otherwise throws an exception, based on the value of +klass+.
#
# The exception thrown to terminate the given block cannot be rescued inside
- # the block unless +klass+ is given explicitly.
+ # the block unless +klass+ is given explicitly. However, the block can use
+ # ensure to prevent the handling of the exception. For that reason, this
+ # method cannot be relied on to enforce timeouts for untrusted blocks.
#
# Note that this is both a method of module Timeout, so you can <tt>include
# Timeout</tt> into your classes so they have a #timeout method, as well as
@@ -118,7 +122,7 @@ module Timeout
end
def timeout(*args, &block)
- warn "#{caller_locations(1, 1)[0]}: Object##{__method__} is deprecated, use Timeout.timeout instead."
+ warn "Object##{__method__} is deprecated, use Timeout.timeout instead.", uplevel: 1
Timeout.timeout(*args, &block)
end
diff --git a/lib/timeout/timeout.gemspec b/lib/timeout/timeout.gemspec
new file mode 100644
index 0000000000..3dc37f8768
--- /dev/null
+++ b/lib/timeout/timeout.gemspec
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Auto-terminate potentially long-running operations in Ruby.}
+ spec.description = %q{Auto-terminate potentially long-running operations in Ruby.}
+ spec.homepage = "https://github.com/ruby/timeout"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/tmpdir.gemspec b/lib/tmpdir.gemspec
new file mode 100644
index 0000000000..7b76403002
--- /dev/null
+++ b/lib/tmpdir.gemspec
@@ -0,0 +1,26 @@
+Gem::Specification.new do |spec|
+ spec.name = "tmpdir"
+ spec.version = "0.1.2"
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Extends the Dir class to manage the OS temporary file path.}
+ spec.description = %q{Extends the Dir class to manage the OS temporary file path.}
+ spec.homepage = "https://github.com/ruby/tmpdir"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "fileutils"
+end
diff --git a/lib/tmpdir.rb b/lib/tmpdir.rb
index d12afa1ae6..bf7db5282a 100644
--- a/lib/tmpdir.rb
+++ b/lib/tmpdir.rb
@@ -19,22 +19,25 @@ class Dir
# Returns the operating system's temporary file path.
def self.tmpdir
- if $SAFE > 0
- @@systmpdir.dup
- else
- tmp = nil
- [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp', '.'].each do |dir|
- next if !dir
- dir = File.expand_path(dir)
- if stat = File.stat(dir) and stat.directory? and stat.writable? and
- (!stat.world_writable? or stat.sticky?)
- tmp = dir
- break
- end rescue nil
+ tmp = nil
+ ['TMPDIR', 'TMP', 'TEMP', ['system temporary path', @@systmpdir], ['/tmp']*2, ['.']*2].each do |name, dir = ENV[name]|
+ next if !dir
+ dir = File.expand_path(dir)
+ stat = File.stat(dir) rescue next
+ case
+ when !stat.directory?
+ warn "#{name} is not a directory: #{dir}"
+ when !stat.writable?
+ warn "#{name} is not writable: #{dir}"
+ when stat.world_writable? && !stat.sticky?
+ warn "#{name} is world-writable: #{dir}"
+ else
+ tmp = dir
+ break
end
- raise ArgumentError, "could not find a temporary directory" unless tmp
- tmp
end
+ raise ArgumentError, "could not find a temporary directory" unless tmp
+ tmp
end
# Dir.mktmpdir creates a temporary directory.
@@ -82,15 +85,21 @@ class Dir
# FileUtils.remove_entry dir
# end
#
- def self.mktmpdir(prefix_suffix=nil, *rest)
- path = Tmpname.create(prefix_suffix || "d", *rest) {|n| mkdir(n, 0700)}
+ def self.mktmpdir(prefix_suffix=nil, *rest, **options)
+ base = nil
+ path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|path, _, _, d|
+ base = d
+ mkdir(path, 0700)
+ }
if block_given?
begin
- yield path
+ yield path.dup
ensure
- stat = File.stat(File.dirname(path))
- if stat.world_writable? and !stat.sticky?
- raise ArgumentError, "parent directory is world writable but not sticky"
+ unless base
+ stat = File.stat(File.dirname(path))
+ if stat.world_writable? and !stat.sticky?
+ raise ArgumentError, "parent directory is world writable but not sticky"
+ end
end
FileUtils.remove_entry path
end
@@ -106,28 +115,33 @@ class Dir
Dir.tmpdir
end
- def make_tmpname((prefix, suffix), n)
- prefix = (String.try_convert(prefix) or
- raise ArgumentError, "unexpected prefix: #{prefix.inspect}")
- suffix &&= (String.try_convert(suffix) or
- raise ArgumentError, "unexpected suffix: #{suffix.inspect}")
- t = Time.now.strftime("%Y%m%d")
- path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}".dup
- path << "-#{n}" if n
- path << suffix if suffix
- path
+ UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~"
+
+ class << (RANDOM = Random.new)
+ MAX = 36**6 # < 0x100000000
+ def next
+ rand(MAX).to_s(36)
+ end
end
+ private_constant :RANDOM
def create(basename, tmpdir=nil, max_try: nil, **opts)
- if $SAFE > 0 and tmpdir.tainted?
- tmpdir = '/tmp'
- else
- tmpdir ||= tmpdir()
- end
+ origdir = tmpdir
+ tmpdir ||= tmpdir()
n = nil
+ prefix, suffix = basename
+ prefix = (String.try_convert(prefix) or
+ raise ArgumentError, "unexpected prefix: #{prefix.inspect}")
+ prefix = prefix.delete(UNUSABLE_CHARS)
+ suffix &&= (String.try_convert(suffix) or
+ raise ArgumentError, "unexpected suffix: #{suffix.inspect}")
+ suffix &&= suffix.delete(UNUSABLE_CHARS)
begin
- path = File.join(tmpdir, make_tmpname(basename, n))
- yield(path, n, opts)
+ t = Time.now.strftime("%Y%m%d")
+ path = "#{prefix}#{t}-#{$$}-#{RANDOM.next}"\
+ "#{n ? %[-#{n}] : ''}#{suffix||''}"
+ path = File.join(tmpdir, path)
+ yield(path, n, opts, origdir)
rescue Errno::EEXIST
n ||= 0
n += 1
diff --git a/lib/tracer.rb b/lib/tracer.rb
index faafd803f4..9014d80da5 100644
--- a/lib/tracer.rb
+++ b/lib/tracer.rb
@@ -60,6 +60,8 @@
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
class Tracer
+ VERSION = "0.1.1"
+
class << self
# display additional debug information (defaults to false)
attr_accessor :verbose
@@ -141,11 +143,13 @@ class Tracer
stdout.print "Trace off\n" if Tracer.verbose?
end
- def add_filter(p = proc) # :nodoc:
+ def add_filter(p = nil, &b) # :nodoc:
+ p ||= b
@filters.push p
end
- def set_get_line_procs(file, p = proc) # :nodoc:
+ def set_get_line_procs(file, p = nil, &b) # :nodoc:
+ p ||= b
@get_line_procs[file] = p
end
@@ -238,7 +242,7 @@ class Tracer
end
##
- # Register an event handler <code>p</code> which is called everytime a line
+ # Register an event handler <code>p</code> which is called every time a line
# in +file_name+ is executed.
#
# Example:
@@ -247,7 +251,8 @@ class Tracer
# puts "line number executed is #{line}"
# })
- def Tracer.set_get_line_procs(file_name, p = proc)
+ def Tracer.set_get_line_procs(file_name, p = nil, &b)
+ p ||= b
Single.set_get_line_procs(file_name, p)
end
@@ -260,7 +265,8 @@ class Tracer
# "Kernel" == klass.to_s
# end
- def Tracer.add_filter(p = proc)
+ def Tracer.add_filter(p = nil, &b)
+ p ||= b
Single.add_filter(p)
end
end
diff --git a/lib/tracer/tracer.gemspec b/lib/tracer/tracer.gemspec
new file mode 100644
index 0000000000..de9401da2c
--- /dev/null
+++ b/lib/tracer/tracer.gemspec
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Keiju ISHITSUKA"]
+ spec.email = ["keiju@ruby-lang.org"]
+
+ spec.summary = %q{Outputs a source level execution trace of a Ruby program.}
+ spec.description = %q{Outputs a source level execution trace of a Ruby program.}
+ spec.homepage = "https://github.com/ruby/tracer"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.files = ["Gemfile", "LICENSE.txt", "README.md", "Rakefile", "lib/tracer.rb", "tracer.gemspec"]
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/tsort.gemspec b/lib/tsort.gemspec
new file mode 100644
index 0000000000..4656d0b845
--- /dev/null
+++ b/lib/tsort.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "tsort"
+ spec.version = "0.1.0"
+ spec.authors = ["Tanaka Akira"]
+ spec.email = ["akr@fsij.org"]
+
+ spec.summary = %q{Topological sorting using Tarjan's algorithm}
+ spec.description = %q{Topological sorting using Tarjan's algorithm}
+ spec.homepage = "https://github.com/ruby/tsort"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/un.gemspec b/lib/un.gemspec
new file mode 100644
index 0000000000..1b89ffa2fb
--- /dev/null
+++ b/lib/un.gemspec
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+Gem::Specification.new do |spec|
+ spec.name = "un"
+ spec.version = "0.1.0"
+ spec.authors = ["WATANABE Hirofumi"]
+ spec.email = ["eban@ruby-lang.org"]
+
+ spec.summary = "Utilities to replace common UNIX commands"
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/un"
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/un.rb b/lib/un.rb
index c445dba4ec..3f59e3ff8b 100644
--- a/lib/un.rb
+++ b/lib/un.rb
@@ -22,7 +22,7 @@
# ruby -run -e touch -- [OPTION] FILE
# ruby -run -e wait_writable -- [OPTION] FILE
# ruby -run -e mkmf -- [OPTION] EXTNAME [OPTION]
-# ruby -run -e httpd -- [OPTION] DocumentRoot
+# ruby -run -e httpd -- [OPTION] [DocumentRoot]
# ruby -run -e help [COMMAND]
require "fileutils"
@@ -47,7 +47,7 @@ def setup(options = "", *long_options)
end
long_options.each do |s|
opt_name, arg_name = s.split(/(?=[\s=])/, 2)
- opt_name.sub!(/\A--/, '')
+ opt_name.delete_prefix!('--')
s = "--#{opt_name.gsub(/([A-Z]+|[a-z])([A-Z])/, '\1-\2').downcase}#{arg_name}"
puts "#{opt_name}=>#{s}" if $DEBUG
opt_name = opt_name.intern
@@ -88,7 +88,7 @@ def cp
options[:preserve] = true if options.delete :p
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.send cmd, argv, dest, options
+ FileUtils.__send__ cmd, argv, dest, **options
end
end
@@ -109,7 +109,7 @@ def ln
options[:force] = true if options.delete :f
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.send cmd, argv, dest, options
+ FileUtils.__send__ cmd, argv, dest, **options
end
end
@@ -125,7 +125,7 @@ def mv
setup do |argv, options|
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.mv argv, dest, options
+ FileUtils.mv argv, dest, **options
end
end
@@ -144,7 +144,7 @@ def rm
cmd = "rm"
cmd += "_r" if options.delete :r
options[:force] = true if options.delete :f
- FileUtils.send cmd, argv, options
+ FileUtils.__send__ cmd, argv, **options
end
end
@@ -161,7 +161,7 @@ def mkdir
setup("p") do |argv, options|
cmd = "mkdir"
cmd += "_p" if options.delete :p
- FileUtils.send cmd, argv, options
+ FileUtils.__send__ cmd, argv, **options
end
end
@@ -177,7 +177,7 @@ end
def rmdir
setup("p") do |argv, options|
options[:parents] = true if options.delete :p
- FileUtils.rmdir argv, options
+ FileUtils.rmdir argv, **options
end
end
@@ -202,7 +202,7 @@ def install
(group = options.delete :g) and options[:group] = group
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.install argv, dest, options
+ FileUtils.install argv, dest, **options
end
end
@@ -218,7 +218,7 @@ def chmod
setup do |argv, options|
mode = argv.shift
mode = /\A\d/ =~ mode ? mode.oct : mode
- FileUtils.chmod mode, argv, options
+ FileUtils.chmod mode, argv, **options
end
end
@@ -232,7 +232,7 @@ end
def touch
setup do |argv, options|
- FileUtils.touch argv, options
+ FileUtils.touch argv, **options
end
end
@@ -304,7 +304,7 @@ end
##
# Run WEBrick HTTP server.
#
-# ruby -run -e httpd -- [OPTION] DocumentRoot
+# ruby -run -e httpd -- [OPTION] [DocumentRoot]
#
# --bind-address=ADDR address to bind
# --port=NUM listening port number
@@ -313,6 +313,8 @@ end
# --do-not-reverse-lookup disable reverse lookup
# --request-timeout=SECOND request timeout in seconds
# --http-version=VERSION HTTP version
+# --server-name=NAME name of the server host
+# --server-software=NAME name and version of the server
# --ssl-certificate=CERT The SSL certificate file for the server
# --ssl-private-key=KEY The SSL private key file for the server certificate
# -v verbose
@@ -321,9 +323,14 @@ end
def httpd
setup("", "BindAddress=ADDR", "Port=PORT", "MaxClients=NUM", "TempDir=DIR",
"DoNotReverseLookup", "RequestTimeout=SECOND", "HTTPVersion=VERSION",
+ "ServerName=NAME", "ServerSoftware=NAME",
"SSLCertificate=CERT", "SSLPrivateKey=KEY") do
|argv, options|
- require 'webrick'
+ begin
+ require 'webrick'
+ rescue LoadError
+ abort "webrick is not found. You may need to `gem install webrick` to install webrick."
+ end
opt = options[:RequestTimeout] and options[:RequestTimeout] = opt.to_i
[:Port, :MaxClients].each do |name|
opt = options[name] and (options[name] = Integer(opt)) rescue nil
diff --git a/lib/unicode_normalize/normalize.rb b/lib/unicode_normalize/normalize.rb
index a2f7a29c88..b27cdadaaa 100644
--- a/lib/unicode_normalize/normalize.rb
+++ b/lib/unicode_normalize/normalize.rb
@@ -18,7 +18,7 @@
# content are purely an implementation detail, and should not be exposed in
# any test or spec or otherwise.
-require 'unicode_normalize/tables.rb'
+require_relative 'tables'
module UnicodeNormalize # :nodoc:
@@ -70,7 +70,7 @@ module UnicodeNormalize # :nodoc:
if length>1 and 0 <= (lead =string[0].ord-LBASE) and lead < LCOUNT and
0 <= (vowel=string[1].ord-VBASE) and vowel < VCOUNT
lead_vowel = SBASE + (lead * VCOUNT + vowel) * TCOUNT
- if length>2 and 0 <= (trail=string[2].ord-TBASE) and trail < TCOUNT
+ if length>2 and 0 < (trail=string[2].ord-TBASE) and trail < TCOUNT
(lead_vowel + trail).chr(Encoding::UTF_8) + string[3..-1]
else
lead_vowel.chr(Encoding::UTF_8) + string[2..-1]
diff --git a/lib/unicode_normalize/tables.rb b/lib/unicode_normalize/tables.rb
index 4984e3d329..a36daa84e6 100644
--- a/lib/unicode_normalize/tables.rb
+++ b/lib/unicode_normalize/tables.rb
@@ -5,1166 +5,9035 @@
module UnicodeNormalize # :nodoc:
accents = "" \
- "[\u0300-\u034E\u0350-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7" \
- "\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711" \
- "\u0730-\u074A\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D4-\u08E1" \
- "\u08E3-\u08FF\u093C\u094D\u0951-\u0954\u09BC\u09BE\u09CD\u09D7" \
- "\u0A3C\u0A4D\u0ABC\u0ACD\u0B3C\u0B3E\u0B4D\u0B56\u0B57" \
- "\u0BBE\u0BCD\u0BD7\u0C4D\u0C55\u0C56\u0CBC\u0CC2\u0CCD" \
- "\u0CD5\u0CD6\u0D3B\u0D3C\u0D3E\u0D4D\u0D57\u0DCA\u0DCF\u0DDF" \
- "\u0E38-\u0E3A\u0E48-\u0E4B\u0EB8\u0EB9\u0EC8-\u0ECB\u0F18\u0F19\u0F35\u0F37\u0F39" \
- "\u0F71\u0F72\u0F74\u0F7A-\u0F7D\u0F80\u0F82-\u0F84\u0F86\u0F87\u0FC6\u102E" \
- "\u1037\u1039\u103A\u108D\u135D-\u135F\u1714\u1734\u17D2\u17DD" \
- "\u18A9\u1939-\u193B\u1A17\u1A18\u1A60\u1A75-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B34\u1B35" \
- "\u1B44\u1B6B-\u1B73\u1BAA\u1BAB\u1BE6\u1BF2\u1BF3\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0" \
- "\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20DC\u20E1" \
- "\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F\uA674-\uA67D" \
- "\uA69E\uA69F\uA6F0\uA6F1\uA806\uA8C4\uA8E0-\uA8F1\uA92B-\uA92D\uA953\uA9B3" \
- "\uA9C0\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAF6\uABED" \
- "\uFB1E\uFE20-\uFE2F\u{101FD}\u{102E0}\u{10376}-\u{1037A}\u{10A0D}\u{10A0F}\u{10A38}-\u{10A3A}" \
- "\u{10A3F}\u{10AE5}\u{10AE6}\u{11046}\u{1107F}\u{110B9}\u{110BA}\u{11100}-\u{11102}\u{11127}\u{11133}\u{11134}" \
- "\u{11173}\u{111C0}\u{111CA}\u{11235}\u{11236}\u{112E9}\u{112EA}\u{1133C}\u{1133E}\u{1134D}" \
- "\u{11357}\u{11366}-\u{1136C}\u{11370}-\u{11374}\u{11442}\u{11446}\u{114B0}\u{114BA}\u{114BD}" \
- "\u{114C2}\u{114C3}\u{115AF}\u{115BF}\u{115C0}\u{1163F}\u{116B6}\u{116B7}\u{1172B}\u{11A34}\u{11A47}" \
- "\u{11A99}\u{11C3F}\u{11D42}\u{11D44}\u{11D45}\u{16AF0}-\u{16AF4}\u{16B30}-\u{16B36}\u{1BC9E}\u{1D165}-\u{1D169}" \
- "\u{1D16D}-\u{1D172}\u{1D17B}-\u{1D182}\u{1D185}-\u{1D18B}\u{1D1AA}-\u{1D1AD}\u{1D242}-\u{1D244}\u{1E000}-\u{1E006}\u{1E008}-\u{1E018}\u{1E01B}-\u{1E021}" \
- "\u{1E023}\u{1E024}\u{1E026}-\u{1E02A}\u{1E8D0}-\u{1E8D6}\u{1E944}-\u{1E94A}" \
+ "[\u0300-\u034E" \
+ "\u0350-\u036F" \
+ "\u0483-\u0487" \
+ "\u0591-\u05BD" \
+ "\u05BF" \
+ "\u05C1\u05C2" \
+ "\u05C4\u05C5" \
+ "\u05C7" \
+ "\u0610-\u061A" \
+ "\u064B-\u065F" \
+ "\u0670" \
+ "\u06D6-\u06DC" \
+ "\u06DF-\u06E4" \
+ "\u06E7\u06E8" \
+ "\u06EA-\u06ED" \
+ "\u0711" \
+ "\u0730-\u074A" \
+ "\u07EB-\u07F3" \
+ "\u07FD" \
+ "\u0816-\u0819" \
+ "\u081B-\u0823" \
+ "\u0825-\u0827" \
+ "\u0829-\u082D" \
+ "\u0859-\u085B" \
+ "\u08D3-\u08E1" \
+ "\u08E3-\u08FF" \
+ "\u093C" \
+ "\u094D" \
+ "\u0951-\u0954" \
+ "\u09BC" \
+ "\u09BE" \
+ "\u09CD" \
+ "\u09D7" \
+ "\u09FE" \
+ "\u0A3C" \
+ "\u0A4D" \
+ "\u0ABC" \
+ "\u0ACD" \
+ "\u0B3C" \
+ "\u0B3E" \
+ "\u0B4D" \
+ "\u0B56\u0B57" \
+ "\u0BBE" \
+ "\u0BCD" \
+ "\u0BD7" \
+ "\u0C4D" \
+ "\u0C55\u0C56" \
+ "\u0CBC" \
+ "\u0CC2" \
+ "\u0CCD" \
+ "\u0CD5\u0CD6" \
+ "\u0D3B\u0D3C" \
+ "\u0D3E" \
+ "\u0D4D" \
+ "\u0D57" \
+ "\u0DCA" \
+ "\u0DCF" \
+ "\u0DDF" \
+ "\u0E38-\u0E3A" \
+ "\u0E48-\u0E4B" \
+ "\u0EB8-\u0EBA" \
+ "\u0EC8-\u0ECB" \
+ "\u0F18\u0F19" \
+ "\u0F35" \
+ "\u0F37" \
+ "\u0F39" \
+ "\u0F71\u0F72" \
+ "\u0F74" \
+ "\u0F7A-\u0F7D" \
+ "\u0F80" \
+ "\u0F82-\u0F84" \
+ "\u0F86\u0F87" \
+ "\u0FC6" \
+ "\u102E" \
+ "\u1037" \
+ "\u1039\u103A" \
+ "\u108D" \
+ "\u135D-\u135F" \
+ "\u1714" \
+ "\u1734" \
+ "\u17D2" \
+ "\u17DD" \
+ "\u18A9" \
+ "\u1939-\u193B" \
+ "\u1A17\u1A18" \
+ "\u1A60" \
+ "\u1A75-\u1A7C" \
+ "\u1A7F" \
+ "\u1AB0-\u1ABD" \
+ "\u1B34\u1B35" \
+ "\u1B44" \
+ "\u1B6B-\u1B73" \
+ "\u1BAA\u1BAB" \
+ "\u1BE6" \
+ "\u1BF2\u1BF3" \
+ "\u1C37" \
+ "\u1CD0-\u1CD2" \
+ "\u1CD4-\u1CE0" \
+ "\u1CE2-\u1CE8" \
+ "\u1CED" \
+ "\u1CF4" \
+ "\u1CF8\u1CF9" \
+ "\u1DC0-\u1DF9" \
+ "\u1DFB-\u1DFF" \
+ "\u20D0-\u20DC" \
+ "\u20E1" \
+ "\u20E5-\u20F0" \
+ "\u2CEF-\u2CF1" \
+ "\u2D7F" \
+ "\u2DE0-\u2DFF" \
+ "\u302A-\u302F" \
+ "\u3099\u309A" \
+ "\uA66F" \
+ "\uA674-\uA67D" \
+ "\uA69E\uA69F" \
+ "\uA6F0\uA6F1" \
+ "\uA806" \
+ "\uA8C4" \
+ "\uA8E0-\uA8F1" \
+ "\uA92B-\uA92D" \
+ "\uA953" \
+ "\uA9B3" \
+ "\uA9C0" \
+ "\uAAB0" \
+ "\uAAB2-\uAAB4" \
+ "\uAAB7\uAAB8" \
+ "\uAABE\uAABF" \
+ "\uAAC1" \
+ "\uAAF6" \
+ "\uABED" \
+ "\uFB1E" \
+ "\uFE20-\uFE2F" \
+ "\u{101FD}" \
+ "\u{102E0}" \
+ "\u{10376}-\u{1037A}" \
+ "\u{10A0D}" \
+ "\u{10A0F}" \
+ "\u{10A38}-\u{10A3A}" \
+ "\u{10A3F}" \
+ "\u{10AE5}\u{10AE6}" \
+ "\u{10D24}-\u{10D27}" \
+ "\u{10F46}-\u{10F50}" \
+ "\u{11046}" \
+ "\u{1107F}" \
+ "\u{110B9}\u{110BA}" \
+ "\u{11100}-\u{11102}" \
+ "\u{11127}" \
+ "\u{11133}\u{11134}" \
+ "\u{11173}" \
+ "\u{111C0}" \
+ "\u{111CA}" \
+ "\u{11235}\u{11236}" \
+ "\u{112E9}\u{112EA}" \
+ "\u{1133B}\u{1133C}" \
+ "\u{1133E}" \
+ "\u{1134D}" \
+ "\u{11357}" \
+ "\u{11366}-\u{1136C}" \
+ "\u{11370}-\u{11374}" \
+ "\u{11442}" \
+ "\u{11446}" \
+ "\u{1145E}" \
+ "\u{114B0}" \
+ "\u{114BA}" \
+ "\u{114BD}" \
+ "\u{114C2}\u{114C3}" \
+ "\u{115AF}" \
+ "\u{115BF}\u{115C0}" \
+ "\u{1163F}" \
+ "\u{116B6}\u{116B7}" \
+ "\u{1172B}" \
+ "\u{11839}\u{1183A}" \
+ "\u{119E0}" \
+ "\u{11A34}" \
+ "\u{11A47}" \
+ "\u{11A99}" \
+ "\u{11C3F}" \
+ "\u{11D42}" \
+ "\u{11D44}\u{11D45}" \
+ "\u{11D97}" \
+ "\u{16AF0}-\u{16AF4}" \
+ "\u{16B30}-\u{16B36}" \
+ "\u{1BC9E}" \
+ "\u{1D165}-\u{1D169}" \
+ "\u{1D16D}-\u{1D172}" \
+ "\u{1D17B}-\u{1D182}" \
+ "\u{1D185}-\u{1D18B}" \
+ "\u{1D1AA}-\u{1D1AD}" \
+ "\u{1D242}-\u{1D244}" \
+ "\u{1E000}-\u{1E006}" \
+ "\u{1E008}-\u{1E018}" \
+ "\u{1E01B}-\u{1E021}" \
+ "\u{1E023}\u{1E024}" \
+ "\u{1E026}-\u{1E02A}" \
+ "\u{1E130}-\u{1E136}" \
+ "\u{1E2EC}-\u{1E2EF}" \
+ "\u{1E8D0}-\u{1E8D6}" \
+ "\u{1E944}-\u{1E94A}" \
"]"
ACCENTS = accents
REGEXP_D_STRING = "#{'' # composition starters and composition exclusions
}" \
- "[\u00C0-\u00C5\u00C7-\u00CF\u00D1-\u00D6\u00D9-\u00DD\u00E0-\u00E5\u00E7-\u00EF\u00F1-\u00F6\u00F9-\u00FD" \
- "\u00FF-\u010F\u0112-\u0125\u0128-\u0130\u0134-\u0137\u0139-\u013E\u0143-\u0148\u014C-\u0151\u0154-\u0165" \
- "\u0168-\u017E\u01A0\u01A1\u01AF\u01B0\u01CD-\u01DC\u01DE-\u01E3\u01E6-\u01F0\u01F4\u01F5\u01F8-\u021B" \
- "\u021E\u021F\u0226-\u0233\u0340\u0341\u0343\u0344\u0374\u037E\u0385-\u038A\u038C" \
- "\u038E-\u0390\u03AA-\u03B0\u03CA-\u03CE\u03D3\u03D4\u0400\u0401\u0403\u0407\u040C-\u040E" \
- "\u0419\u0439\u0450\u0451\u0453\u0457\u045C-\u045E\u0476\u0477\u04C1\u04C2" \
- "\u04D0-\u04D3\u04D6\u04D7\u04DA-\u04DF\u04E2-\u04E7\u04EA-\u04F5\u04F8\u04F9\u0622-\u0626\u06C0" \
- "\u06C2\u06D3\u0929\u0931\u0934\u0958-\u095F\u09CB\u09CC\u09DC\u09DD" \
- "\u09DF\u0A33\u0A36\u0A59-\u0A5B\u0A5E\u0B48\u0B4B\u0B4C\u0B5C\u0B5D" \
- "\u0B94\u0BCA-\u0BCC\u0C48\u0CC0\u0CC7\u0CC8\u0CCA\u0CCB\u0D4A-\u0D4C\u0DDA" \
- "\u0DDC-\u0DDE\u0F43\u0F4D\u0F52\u0F57\u0F5C\u0F69\u0F73" \
- "\u0F75\u0F76\u0F78\u0F81\u0F93\u0F9D\u0FA2\u0FA7\u0FAC" \
- "\u0FB9\u1026\u1B06\u1B08\u1B0A\u1B0C\u1B0E\u1B12" \
- "\u1B3B\u1B3D\u1B40\u1B41\u1B43\u1E00-\u1E99\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15" \
- "\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D" \
- "\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC1-\u1FC4\u1FC6-\u1FD3\u1FD6-\u1FDB\u1FDD-\u1FEF\u1FF2-\u1FF4" \
- "\u1FF6-\u1FFD\u2000\u2001\u2126\u212A\u212B\u219A\u219B\u21AE\u21CD-\u21CF\u2204" \
- "\u2209\u220C\u2224\u2226\u2241\u2244\u2247\u2249" \
- "\u2260\u2262\u226D-\u2271\u2274\u2275\u2278\u2279\u2280\u2281\u2284\u2285\u2288\u2289" \
- "\u22AC-\u22AF\u22E0-\u22E3\u22EA-\u22ED\u2329\u232A\u2ADC\u304C\u304E\u3050" \
- "\u3052\u3054\u3056\u3058\u305A\u305C\u305E\u3060" \
- "\u3062\u3065\u3067\u3069\u3070\u3071\u3073\u3074\u3076\u3077\u3079\u307A" \
- "\u307C\u307D\u3094\u309E\u30AC\u30AE\u30B0\u30B2\u30B4" \
- "\u30B6\u30B8\u30BA\u30BC\u30BE\u30C0\u30C2\u30C5" \
- "\u30C7\u30C9\u30D0\u30D1\u30D3\u30D4\u30D6\u30D7\u30D9\u30DA\u30DC\u30DD\u30F4" \
- "\u30F7-\u30FA\u30FE\uF900-\uFA0D\uFA10\uFA12\uFA15-\uFA1E\uFA20\uFA22" \
- "\uFA25\uFA26\uFA2A-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E" \
- "\uFB40\uFB41\uFB43\uFB44\uFB46-\uFB4E\u{1109A}\u{1109C}\u{110AB}\u{1112E}\u{1112F}\u{1134B}\u{1134C}" \
- "\u{114BB}\u{114BC}\u{114BE}\u{115BA}\u{115BB}\u{1D15E}-\u{1D164}\u{1D1BB}-\u{1D1C0}\u{2F800}-\u{2FA1D}" \
+ "[\u00C0-\u00C5" \
+ "\u00C7-\u00CF" \
+ "\u00D1-\u00D6" \
+ "\u00D9-\u00DD" \
+ "\u00E0-\u00E5" \
+ "\u00E7-\u00EF" \
+ "\u00F1-\u00F6" \
+ "\u00F9-\u00FD" \
+ "\u00FF-\u010F" \
+ "\u0112-\u0125" \
+ "\u0128-\u0130" \
+ "\u0134-\u0137" \
+ "\u0139-\u013E" \
+ "\u0143-\u0148" \
+ "\u014C-\u0151" \
+ "\u0154-\u0165" \
+ "\u0168-\u017E" \
+ "\u01A0\u01A1" \
+ "\u01AF\u01B0" \
+ "\u01CD-\u01DC" \
+ "\u01DE-\u01E3" \
+ "\u01E6-\u01F0" \
+ "\u01F4\u01F5" \
+ "\u01F8-\u021B" \
+ "\u021E\u021F" \
+ "\u0226-\u0233" \
+ "\u0340\u0341" \
+ "\u0343\u0344" \
+ "\u0374" \
+ "\u037E" \
+ "\u0385-\u038A" \
+ "\u038C" \
+ "\u038E-\u0390" \
+ "\u03AA-\u03B0" \
+ "\u03CA-\u03CE" \
+ "\u03D3\u03D4" \
+ "\u0400\u0401" \
+ "\u0403" \
+ "\u0407" \
+ "\u040C-\u040E" \
+ "\u0419" \
+ "\u0439" \
+ "\u0450\u0451" \
+ "\u0453" \
+ "\u0457" \
+ "\u045C-\u045E" \
+ "\u0476\u0477" \
+ "\u04C1\u04C2" \
+ "\u04D0-\u04D3" \
+ "\u04D6\u04D7" \
+ "\u04DA-\u04DF" \
+ "\u04E2-\u04E7" \
+ "\u04EA-\u04F5" \
+ "\u04F8\u04F9" \
+ "\u0622-\u0626" \
+ "\u06C0" \
+ "\u06C2" \
+ "\u06D3" \
+ "\u0929" \
+ "\u0931" \
+ "\u0934" \
+ "\u0958-\u095F" \
+ "\u09CB\u09CC" \
+ "\u09DC\u09DD" \
+ "\u09DF" \
+ "\u0A33" \
+ "\u0A36" \
+ "\u0A59-\u0A5B" \
+ "\u0A5E" \
+ "\u0B48" \
+ "\u0B4B\u0B4C" \
+ "\u0B5C\u0B5D" \
+ "\u0B94" \
+ "\u0BCA-\u0BCC" \
+ "\u0C48" \
+ "\u0CC0" \
+ "\u0CC7\u0CC8" \
+ "\u0CCA\u0CCB" \
+ "\u0D4A-\u0D4C" \
+ "\u0DDA" \
+ "\u0DDC-\u0DDE" \
+ "\u0F43" \
+ "\u0F4D" \
+ "\u0F52" \
+ "\u0F57" \
+ "\u0F5C" \
+ "\u0F69" \
+ "\u0F73" \
+ "\u0F75\u0F76" \
+ "\u0F78" \
+ "\u0F81" \
+ "\u0F93" \
+ "\u0F9D" \
+ "\u0FA2" \
+ "\u0FA7" \
+ "\u0FAC" \
+ "\u0FB9" \
+ "\u1026" \
+ "\u1B06" \
+ "\u1B08" \
+ "\u1B0A" \
+ "\u1B0C" \
+ "\u1B0E" \
+ "\u1B12" \
+ "\u1B3B" \
+ "\u1B3D" \
+ "\u1B40\u1B41" \
+ "\u1B43" \
+ "\u1E00-\u1E99" \
+ "\u1E9B" \
+ "\u1EA0-\u1EF9" \
+ "\u1F00-\u1F15" \
+ "\u1F18-\u1F1D" \
+ "\u1F20-\u1F45" \
+ "\u1F48-\u1F4D" \
+ "\u1F50-\u1F57" \
+ "\u1F59" \
+ "\u1F5B" \
+ "\u1F5D" \
+ "\u1F5F-\u1F7D" \
+ "\u1F80-\u1FB4" \
+ "\u1FB6-\u1FBC" \
+ "\u1FBE" \
+ "\u1FC1-\u1FC4" \
+ "\u1FC6-\u1FD3" \
+ "\u1FD6-\u1FDB" \
+ "\u1FDD-\u1FEF" \
+ "\u1FF2-\u1FF4" \
+ "\u1FF6-\u1FFD" \
+ "\u2000\u2001" \
+ "\u2126" \
+ "\u212A\u212B" \
+ "\u219A\u219B" \
+ "\u21AE" \
+ "\u21CD-\u21CF" \
+ "\u2204" \
+ "\u2209" \
+ "\u220C" \
+ "\u2224" \
+ "\u2226" \
+ "\u2241" \
+ "\u2244" \
+ "\u2247" \
+ "\u2249" \
+ "\u2260" \
+ "\u2262" \
+ "\u226D-\u2271" \
+ "\u2274\u2275" \
+ "\u2278\u2279" \
+ "\u2280\u2281" \
+ "\u2284\u2285" \
+ "\u2288\u2289" \
+ "\u22AC-\u22AF" \
+ "\u22E0-\u22E3" \
+ "\u22EA-\u22ED" \
+ "\u2329\u232A" \
+ "\u2ADC" \
+ "\u304C" \
+ "\u304E" \
+ "\u3050" \
+ "\u3052" \
+ "\u3054" \
+ "\u3056" \
+ "\u3058" \
+ "\u305A" \
+ "\u305C" \
+ "\u305E" \
+ "\u3060" \
+ "\u3062" \
+ "\u3065" \
+ "\u3067" \
+ "\u3069" \
+ "\u3070\u3071" \
+ "\u3073\u3074" \
+ "\u3076\u3077" \
+ "\u3079\u307A" \
+ "\u307C\u307D" \
+ "\u3094" \
+ "\u309E" \
+ "\u30AC" \
+ "\u30AE" \
+ "\u30B0" \
+ "\u30B2" \
+ "\u30B4" \
+ "\u30B6" \
+ "\u30B8" \
+ "\u30BA" \
+ "\u30BC" \
+ "\u30BE" \
+ "\u30C0" \
+ "\u30C2" \
+ "\u30C5" \
+ "\u30C7" \
+ "\u30C9" \
+ "\u30D0\u30D1" \
+ "\u30D3\u30D4" \
+ "\u30D6\u30D7" \
+ "\u30D9\u30DA" \
+ "\u30DC\u30DD" \
+ "\u30F4" \
+ "\u30F7-\u30FA" \
+ "\u30FE" \
+ "\uF900-\uFA0D" \
+ "\uFA10" \
+ "\uFA12" \
+ "\uFA15-\uFA1E" \
+ "\uFA20" \
+ "\uFA22" \
+ "\uFA25\uFA26" \
+ "\uFA2A-\uFA6D" \
+ "\uFA70-\uFAD9" \
+ "\uFB1D" \
+ "\uFB1F" \
+ "\uFB2A-\uFB36" \
+ "\uFB38-\uFB3C" \
+ "\uFB3E" \
+ "\uFB40\uFB41" \
+ "\uFB43\uFB44" \
+ "\uFB46-\uFB4E" \
+ "\u{1109A}" \
+ "\u{1109C}" \
+ "\u{110AB}" \
+ "\u{1112E}\u{1112F}" \
+ "\u{1134B}\u{1134C}" \
+ "\u{114BB}\u{114BC}" \
+ "\u{114BE}" \
+ "\u{115BA}\u{115BB}" \
+ "\u{1D15E}-\u{1D164}" \
+ "\u{1D1BB}-\u{1D1C0}" \
+ "\u{2F800}-\u{2FA1D}" \
"]#{accents}*" \
"|#{'' # characters that can be the result of a composition, except composition starters
}" \
- "[<->A-PR-Za-pr-z\u00A8\u00C6\u00D8" \
- "\u00E6\u00F8\u017F\u01B7\u0292\u0391\u0395\u0397" \
- "\u0399\u039F\u03A1\u03A5\u03A9\u03B1\u03B5\u03B7" \
- "\u03B9\u03BF\u03C1\u03C5\u03C9\u03D2\u0406\u0410" \
- "\u0413\u0415-\u0418\u041A\u041E\u0423\u0427\u042B\u042D" \
- "\u0430\u0433\u0435-\u0438\u043A\u043E\u0443\u0447\u044B" \
- "\u044D\u0456\u0474\u0475\u04D8\u04D9\u04E8\u04E9\u0627\u0648\u064A" \
- "\u06C1\u06D2\u06D5\u0928\u0930\u0933\u09C7\u0B47" \
- "\u0B92\u0BC6\u0BC7\u0C46\u0CBF\u0CC6\u0D46\u0D47\u0DD9\u1025" \
- "\u1B05\u1B07\u1B09\u1B0B\u1B0D\u1B11\u1B3A\u1B3C" \
- "\u1B3E\u1B3F\u1B42\u1FBF\u1FFE\u2190\u2192\u2194\u21D0" \
- "\u21D2\u21D4\u2203\u2208\u220B\u2223\u2225\u223C" \
- "\u2243\u2245\u2248\u224D\u2261\u2264\u2265\u2272\u2273\u2276\u2277" \
- "\u227A-\u227D\u2282\u2283\u2286\u2287\u2291\u2292\u22A2\u22A8\u22A9\u22AB\u22B2-\u22B5" \
- "\u3046\u304B\u304D\u304F\u3051\u3053\u3055\u3057" \
- "\u3059\u305B\u305D\u305F\u3061\u3064\u3066\u3068" \
- "\u306F\u3072\u3075\u3078\u307B\u309D\u30A6\u30AB" \
- "\u30AD\u30AF\u30B1\u30B3\u30B5\u30B7\u30B9\u30BB" \
- "\u30BD\u30BF\u30C1\u30C4\u30C6\u30C8\u30CF\u30D2" \
- "\u30D5\u30D8\u30DB\u30EF-\u30F2\u30FD\u{11099}\u{1109B}\u{110A5}" \
- "\u{11131}\u{11132}\u{11347}\u{114B9}\u{115B8}\u{115B9}" \
+ "[<->" \
+ "A-P" \
+ "R-Z" \
+ "a-p" \
+ "r-z" \
+ "\u00A8" \
+ "\u00C6" \
+ "\u00D8" \
+ "\u00E6" \
+ "\u00F8" \
+ "\u017F" \
+ "\u01B7" \
+ "\u0292" \
+ "\u0391" \
+ "\u0395" \
+ "\u0397" \
+ "\u0399" \
+ "\u039F" \
+ "\u03A1" \
+ "\u03A5" \
+ "\u03A9" \
+ "\u03B1" \
+ "\u03B5" \
+ "\u03B7" \
+ "\u03B9" \
+ "\u03BF" \
+ "\u03C1" \
+ "\u03C5" \
+ "\u03C9" \
+ "\u03D2" \
+ "\u0406" \
+ "\u0410" \
+ "\u0413" \
+ "\u0415-\u0418" \
+ "\u041A" \
+ "\u041E" \
+ "\u0423" \
+ "\u0427" \
+ "\u042B" \
+ "\u042D" \
+ "\u0430" \
+ "\u0433" \
+ "\u0435-\u0438" \
+ "\u043A" \
+ "\u043E" \
+ "\u0443" \
+ "\u0447" \
+ "\u044B" \
+ "\u044D" \
+ "\u0456" \
+ "\u0474\u0475" \
+ "\u04D8\u04D9" \
+ "\u04E8\u04E9" \
+ "\u0627" \
+ "\u0648" \
+ "\u064A" \
+ "\u06C1" \
+ "\u06D2" \
+ "\u06D5" \
+ "\u0928" \
+ "\u0930" \
+ "\u0933" \
+ "\u09C7" \
+ "\u0B47" \
+ "\u0B92" \
+ "\u0BC6\u0BC7" \
+ "\u0C46" \
+ "\u0CBF" \
+ "\u0CC6" \
+ "\u0D46\u0D47" \
+ "\u0DD9" \
+ "\u1025" \
+ "\u1B05" \
+ "\u1B07" \
+ "\u1B09" \
+ "\u1B0B" \
+ "\u1B0D" \
+ "\u1B11" \
+ "\u1B3A" \
+ "\u1B3C" \
+ "\u1B3E\u1B3F" \
+ "\u1B42" \
+ "\u1FBF" \
+ "\u1FFE" \
+ "\u2190" \
+ "\u2192" \
+ "\u2194" \
+ "\u21D0" \
+ "\u21D2" \
+ "\u21D4" \
+ "\u2203" \
+ "\u2208" \
+ "\u220B" \
+ "\u2223" \
+ "\u2225" \
+ "\u223C" \
+ "\u2243" \
+ "\u2245" \
+ "\u2248" \
+ "\u224D" \
+ "\u2261" \
+ "\u2264\u2265" \
+ "\u2272\u2273" \
+ "\u2276\u2277" \
+ "\u227A-\u227D" \
+ "\u2282\u2283" \
+ "\u2286\u2287" \
+ "\u2291\u2292" \
+ "\u22A2" \
+ "\u22A8\u22A9" \
+ "\u22AB" \
+ "\u22B2-\u22B5" \
+ "\u3046" \
+ "\u304B" \
+ "\u304D" \
+ "\u304F" \
+ "\u3051" \
+ "\u3053" \
+ "\u3055" \
+ "\u3057" \
+ "\u3059" \
+ "\u305B" \
+ "\u305D" \
+ "\u305F" \
+ "\u3061" \
+ "\u3064" \
+ "\u3066" \
+ "\u3068" \
+ "\u306F" \
+ "\u3072" \
+ "\u3075" \
+ "\u3078" \
+ "\u307B" \
+ "\u309D" \
+ "\u30A6" \
+ "\u30AB" \
+ "\u30AD" \
+ "\u30AF" \
+ "\u30B1" \
+ "\u30B3" \
+ "\u30B5" \
+ "\u30B7" \
+ "\u30B9" \
+ "\u30BB" \
+ "\u30BD" \
+ "\u30BF" \
+ "\u30C1" \
+ "\u30C4" \
+ "\u30C6" \
+ "\u30C8" \
+ "\u30CF" \
+ "\u30D2" \
+ "\u30D5" \
+ "\u30D8" \
+ "\u30DB" \
+ "\u30EF-\u30F2" \
+ "\u30FD" \
+ "\u{11099}" \
+ "\u{1109B}" \
+ "\u{110A5}" \
+ "\u{11131}\u{11132}" \
+ "\u{11347}" \
+ "\u{114B9}" \
+ "\u{115B8}\u{115B9}" \
"]?#{accents}+" \
"|#{'' # precomposed Hangul syllables
}" \
"[\u{AC00}-\u{D7A4}]"
REGEXP_C_STRING = "#{'' # composition exclusions
}" \
- "[\u0340\u0341\u0343\u0344\u0374\u037E\u0387\u0958-\u095F\u09DC\u09DD\u09DF" \
- "\u0A33\u0A36\u0A59-\u0A5B\u0A5E\u0B5C\u0B5D\u0F43\u0F4D\u0F52" \
- "\u0F57\u0F5C\u0F69\u0F73\u0F75\u0F76\u0F78\u0F81\u0F93" \
- "\u0F9D\u0FA2\u0FA7\u0FAC\u0FB9\u1F71\u1F73\u1F75" \
- "\u1F77\u1F79\u1F7B\u1F7D\u1FBB\u1FBE\u1FC9\u1FCB" \
- "\u1FD3\u1FDB\u1FE3\u1FEB\u1FEE\u1FEF\u1FF9\u1FFB\u1FFD" \
- "\u2000\u2001\u2126\u212A\u212B\u2329\u232A\u2ADC\uF900-\uFA0D\uFA10\uFA12" \
- "\uFA15-\uFA1E\uFA20\uFA22\uFA25\uFA26\uFA2A-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F" \
- "\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFB4E\u{1D15E}-\u{1D164}\u{1D1BB}-\u{1D1C0}" \
+ "[\u0340\u0341" \
+ "\u0343\u0344" \
+ "\u0374" \
+ "\u037E" \
+ "\u0387" \
+ "\u0958-\u095F" \
+ "\u09DC\u09DD" \
+ "\u09DF" \
+ "\u0A33" \
+ "\u0A36" \
+ "\u0A59-\u0A5B" \
+ "\u0A5E" \
+ "\u0B5C\u0B5D" \
+ "\u0F43" \
+ "\u0F4D" \
+ "\u0F52" \
+ "\u0F57" \
+ "\u0F5C" \
+ "\u0F69" \
+ "\u0F73" \
+ "\u0F75\u0F76" \
+ "\u0F78" \
+ "\u0F81" \
+ "\u0F93" \
+ "\u0F9D" \
+ "\u0FA2" \
+ "\u0FA7" \
+ "\u0FAC" \
+ "\u0FB9" \
+ "\u1F71" \
+ "\u1F73" \
+ "\u1F75" \
+ "\u1F77" \
+ "\u1F79" \
+ "\u1F7B" \
+ "\u1F7D" \
+ "\u1FBB" \
+ "\u1FBE" \
+ "\u1FC9" \
+ "\u1FCB" \
+ "\u1FD3" \
+ "\u1FDB" \
+ "\u1FE3" \
+ "\u1FEB" \
+ "\u1FEE\u1FEF" \
+ "\u1FF9" \
+ "\u1FFB" \
+ "\u1FFD" \
+ "\u2000\u2001" \
+ "\u2126" \
+ "\u212A\u212B" \
+ "\u2329\u232A" \
+ "\u2ADC" \
+ "\uF900-\uFA0D" \
+ "\uFA10" \
+ "\uFA12" \
+ "\uFA15-\uFA1E" \
+ "\uFA20" \
+ "\uFA22" \
+ "\uFA25\uFA26" \
+ "\uFA2A-\uFA6D" \
+ "\uFA70-\uFAD9" \
+ "\uFB1D" \
+ "\uFB1F" \
+ "\uFB2A-\uFB36" \
+ "\uFB38-\uFB3C" \
+ "\uFB3E" \
+ "\uFB40\uFB41" \
+ "\uFB43\uFB44" \
+ "\uFB46-\uFB4E" \
+ "\u{1D15E}-\u{1D164}" \
+ "\u{1D1BB}-\u{1D1C0}" \
"\u{2F800}-\u{2FA1D}" \
"]#{accents}*" \
"|#{'' # composition starters and characters that can be the result of a composition
}" \
- "[<->A-PR-Za-pr-z\u00A8\u00C0-\u00CF\u00D1-\u00D6" \
- "\u00D8-\u00DD\u00E0-\u00EF\u00F1-\u00F6\u00F8-\u00FD\u00FF-\u010F\u0112-\u0125\u0128-\u0130\u0134-\u0137" \
- "\u0139-\u013E\u0143-\u0148\u014C-\u0151\u0154-\u0165\u0168-\u017F\u01A0\u01A1\u01AF\u01B0\u01B7" \
- "\u01CD-\u01DC\u01DE-\u01E3\u01E6-\u01F0\u01F4\u01F5\u01F8-\u021B\u021E\u021F\u0226-\u0233\u0292" \
- "\u0385\u0386\u0388-\u038A\u038C\u038E-\u0391\u0395\u0397\u0399\u039F" \
- "\u03A1\u03A5\u03A9-\u03B1\u03B5\u03B7\u03B9\u03BF\u03C1" \
- "\u03C5\u03C9-\u03CE\u03D2-\u03D4\u0400\u0401\u0403\u0406\u0407\u040C-\u040E\u0410" \
- "\u0413\u0415-\u041A\u041E\u0423\u0427\u042B\u042D\u0430" \
- "\u0433\u0435-\u043A\u043E\u0443\u0447\u044B\u044D\u0450\u0451" \
- "\u0453\u0456\u0457\u045C-\u045E\u0474-\u0477\u04C1\u04C2\u04D0-\u04D3\u04D6-\u04DF\u04E2-\u04F5" \
- "\u04F8\u04F9\u0622-\u0627\u0648\u064A\u06C0-\u06C2\u06D2\u06D3\u06D5\u0928\u0929" \
- "\u0930\u0931\u0933\u0934\u09C7\u09CB\u09CC\u0B47\u0B48\u0B4B\u0B4C\u0B92\u0B94" \
- "\u0BC6\u0BC7\u0BCA-\u0BCC\u0C46\u0C48\u0CBF\u0CC0\u0CC6-\u0CC8\u0CCA\u0CCB\u0D46\u0D47" \
- "\u0D4A-\u0D4C\u0DD9\u0DDA\u0DDC-\u0DDE\u1025\u1026\u1B05-\u1B0E\u1B11\u1B12\u1B3A-\u1B43\u1E00-\u1E99" \
- "\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59" \
- "\u1F5B\u1F5D\u1F5F-\u1F70\u1F72\u1F74\u1F76\u1F78\u1F7A" \
- "\u1F7C\u1F80-\u1FB4\u1FB6-\u1FBA\u1FBC\u1FBF\u1FC1-\u1FC4\u1FC6-\u1FC8\u1FCA" \
- "\u1FCC-\u1FD2\u1FD6-\u1FDA\u1FDD-\u1FE2\u1FE4-\u1FEA\u1FEC\u1FED\u1FF2-\u1FF4\u1FF6-\u1FF8\u1FFA" \
- "\u1FFC\u1FFE\u2190\u2192\u2194\u219A\u219B\u21AE\u21CD-\u21D0" \
- "\u21D2\u21D4\u2203\u2204\u2208\u2209\u220B\u220C\u2223-\u2226\u223C\u2241" \
- "\u2243-\u2245\u2247-\u2249\u224D\u2260-\u2262\u2264\u2265\u226D-\u227D\u2280-\u2289\u2291\u2292" \
- "\u22A2\u22A8\u22A9\u22AB-\u22AF\u22B2-\u22B5\u22E0-\u22E3\u22EA-\u22ED\u3046\u304B-\u3062" \
- "\u3064-\u3069\u306F-\u307D\u3094\u309D\u309E\u30A6\u30AB-\u30C2\u30C4-\u30C9\u30CF-\u30DD" \
- "\u30EF-\u30F2\u30F4\u30F7-\u30FA\u30FD\u30FE\u{11099}-\u{1109C}\u{110A5}\u{110AB}\u{1112E}\u{1112F}" \
- "\u{11131}\u{11132}\u{11347}\u{1134B}\u{1134C}\u{114B9}\u{114BB}\u{114BC}\u{114BE}\u{115B8}-\u{115BB}" \
+ "[<->" \
+ "A-P" \
+ "R-Z" \
+ "a-p" \
+ "r-z" \
+ "\u00A8" \
+ "\u00C0-\u00CF" \
+ "\u00D1-\u00D6" \
+ "\u00D8-\u00DD" \
+ "\u00E0-\u00EF" \
+ "\u00F1-\u00F6" \
+ "\u00F8-\u00FD" \
+ "\u00FF-\u010F" \
+ "\u0112-\u0125" \
+ "\u0128-\u0130" \
+ "\u0134-\u0137" \
+ "\u0139-\u013E" \
+ "\u0143-\u0148" \
+ "\u014C-\u0151" \
+ "\u0154-\u0165" \
+ "\u0168-\u017F" \
+ "\u01A0\u01A1" \
+ "\u01AF\u01B0" \
+ "\u01B7" \
+ "\u01CD-\u01DC" \
+ "\u01DE-\u01E3" \
+ "\u01E6-\u01F0" \
+ "\u01F4\u01F5" \
+ "\u01F8-\u021B" \
+ "\u021E\u021F" \
+ "\u0226-\u0233" \
+ "\u0292" \
+ "\u0385\u0386" \
+ "\u0388-\u038A" \
+ "\u038C" \
+ "\u038E-\u0391" \
+ "\u0395" \
+ "\u0397" \
+ "\u0399" \
+ "\u039F" \
+ "\u03A1" \
+ "\u03A5" \
+ "\u03A9-\u03B1" \
+ "\u03B5" \
+ "\u03B7" \
+ "\u03B9" \
+ "\u03BF" \
+ "\u03C1" \
+ "\u03C5" \
+ "\u03C9-\u03CE" \
+ "\u03D2-\u03D4" \
+ "\u0400\u0401" \
+ "\u0403" \
+ "\u0406\u0407" \
+ "\u040C-\u040E" \
+ "\u0410" \
+ "\u0413" \
+ "\u0415-\u041A" \
+ "\u041E" \
+ "\u0423" \
+ "\u0427" \
+ "\u042B" \
+ "\u042D" \
+ "\u0430" \
+ "\u0433" \
+ "\u0435-\u043A" \
+ "\u043E" \
+ "\u0443" \
+ "\u0447" \
+ "\u044B" \
+ "\u044D" \
+ "\u0450\u0451" \
+ "\u0453" \
+ "\u0456\u0457" \
+ "\u045C-\u045E" \
+ "\u0474-\u0477" \
+ "\u04C1\u04C2" \
+ "\u04D0-\u04D3" \
+ "\u04D6-\u04DF" \
+ "\u04E2-\u04F5" \
+ "\u04F8\u04F9" \
+ "\u0622-\u0627" \
+ "\u0648" \
+ "\u064A" \
+ "\u06C0-\u06C2" \
+ "\u06D2\u06D3" \
+ "\u06D5" \
+ "\u0928\u0929" \
+ "\u0930\u0931" \
+ "\u0933\u0934" \
+ "\u09C7" \
+ "\u09CB\u09CC" \
+ "\u0B47\u0B48" \
+ "\u0B4B\u0B4C" \
+ "\u0B92" \
+ "\u0B94" \
+ "\u0BC6\u0BC7" \
+ "\u0BCA-\u0BCC" \
+ "\u0C46" \
+ "\u0C48" \
+ "\u0CBF\u0CC0" \
+ "\u0CC6-\u0CC8" \
+ "\u0CCA\u0CCB" \
+ "\u0D46\u0D47" \
+ "\u0D4A-\u0D4C" \
+ "\u0DD9\u0DDA" \
+ "\u0DDC-\u0DDE" \
+ "\u1025\u1026" \
+ "\u1B05-\u1B0E" \
+ "\u1B11\u1B12" \
+ "\u1B3A-\u1B43" \
+ "\u1E00-\u1E99" \
+ "\u1E9B" \
+ "\u1EA0-\u1EF9" \
+ "\u1F00-\u1F15" \
+ "\u1F18-\u1F1D" \
+ "\u1F20-\u1F45" \
+ "\u1F48-\u1F4D" \
+ "\u1F50-\u1F57" \
+ "\u1F59" \
+ "\u1F5B" \
+ "\u1F5D" \
+ "\u1F5F-\u1F70" \
+ "\u1F72" \
+ "\u1F74" \
+ "\u1F76" \
+ "\u1F78" \
+ "\u1F7A" \
+ "\u1F7C" \
+ "\u1F80-\u1FB4" \
+ "\u1FB6-\u1FBA" \
+ "\u1FBC" \
+ "\u1FBF" \
+ "\u1FC1-\u1FC4" \
+ "\u1FC6-\u1FC8" \
+ "\u1FCA" \
+ "\u1FCC-\u1FD2" \
+ "\u1FD6-\u1FDA" \
+ "\u1FDD-\u1FE2" \
+ "\u1FE4-\u1FEA" \
+ "\u1FEC\u1FED" \
+ "\u1FF2-\u1FF4" \
+ "\u1FF6-\u1FF8" \
+ "\u1FFA" \
+ "\u1FFC" \
+ "\u1FFE" \
+ "\u2190" \
+ "\u2192" \
+ "\u2194" \
+ "\u219A\u219B" \
+ "\u21AE" \
+ "\u21CD-\u21D0" \
+ "\u21D2" \
+ "\u21D4" \
+ "\u2203\u2204" \
+ "\u2208\u2209" \
+ "\u220B\u220C" \
+ "\u2223-\u2226" \
+ "\u223C" \
+ "\u2241" \
+ "\u2243-\u2245" \
+ "\u2247-\u2249" \
+ "\u224D" \
+ "\u2260-\u2262" \
+ "\u2264\u2265" \
+ "\u226D-\u227D" \
+ "\u2280-\u2289" \
+ "\u2291\u2292" \
+ "\u22A2" \
+ "\u22A8\u22A9" \
+ "\u22AB-\u22AF" \
+ "\u22B2-\u22B5" \
+ "\u22E0-\u22E3" \
+ "\u22EA-\u22ED" \
+ "\u3046" \
+ "\u304B-\u3062" \
+ "\u3064-\u3069" \
+ "\u306F-\u307D" \
+ "\u3094" \
+ "\u309D\u309E" \
+ "\u30A6" \
+ "\u30AB-\u30C2" \
+ "\u30C4-\u30C9" \
+ "\u30CF-\u30DD" \
+ "\u30EF-\u30F2" \
+ "\u30F4" \
+ "\u30F7-\u30FA" \
+ "\u30FD\u30FE" \
+ "\u{11099}-\u{1109C}" \
+ "\u{110A5}" \
+ "\u{110AB}" \
+ "\u{1112E}\u{1112F}" \
+ "\u{11131}\u{11132}" \
+ "\u{11347}" \
+ "\u{1134B}\u{1134C}" \
+ "\u{114B9}" \
+ "\u{114BB}\u{114BC}" \
+ "\u{114BE}" \
+ "\u{115B8}-\u{115BB}" \
"]?#{accents}+" \
"|#{'' # Hangul syllables with separate trailer
}" \
- "[\uAC00\uAC1C\uAC38\uAC54\uAC70\uAC8C\uACA8\uACC4" \
- "\uACE0\uACFC\uAD18\uAD34\uAD50\uAD6C\uAD88\uADA4" \
- "\uADC0\uADDC\uADF8\uAE14\uAE30\uAE4C\uAE68\uAE84" \
- "\uAEA0\uAEBC\uAED8\uAEF4\uAF10\uAF2C\uAF48\uAF64" \
- "\uAF80\uAF9C\uAFB8\uAFD4\uAFF0\uB00C\uB028\uB044" \
- "\uB060\uB07C\uB098\uB0B4\uB0D0\uB0EC\uB108\uB124" \
- "\uB140\uB15C\uB178\uB194\uB1B0\uB1CC\uB1E8\uB204" \
- "\uB220\uB23C\uB258\uB274\uB290\uB2AC\uB2C8\uB2E4" \
- "\uB300\uB31C\uB338\uB354\uB370\uB38C\uB3A8\uB3C4" \
- "\uB3E0\uB3FC\uB418\uB434\uB450\uB46C\uB488\uB4A4" \
- "\uB4C0\uB4DC\uB4F8\uB514\uB530\uB54C\uB568\uB584" \
- "\uB5A0\uB5BC\uB5D8\uB5F4\uB610\uB62C\uB648\uB664" \
- "\uB680\uB69C\uB6B8\uB6D4\uB6F0\uB70C\uB728\uB744" \
- "\uB760\uB77C\uB798\uB7B4\uB7D0\uB7EC\uB808\uB824" \
- "\uB840\uB85C\uB878\uB894\uB8B0\uB8CC\uB8E8\uB904" \
- "\uB920\uB93C\uB958\uB974\uB990\uB9AC\uB9C8\uB9E4" \
- "\uBA00\uBA1C\uBA38\uBA54\uBA70\uBA8C\uBAA8\uBAC4" \
- "\uBAE0\uBAFC\uBB18\uBB34\uBB50\uBB6C\uBB88\uBBA4" \
- "\uBBC0\uBBDC\uBBF8\uBC14\uBC30\uBC4C\uBC68\uBC84" \
- "\uBCA0\uBCBC\uBCD8\uBCF4\uBD10\uBD2C\uBD48\uBD64" \
- "\uBD80\uBD9C\uBDB8\uBDD4\uBDF0\uBE0C\uBE28\uBE44" \
- "\uBE60\uBE7C\uBE98\uBEB4\uBED0\uBEEC\uBF08\uBF24" \
- "\uBF40\uBF5C\uBF78\uBF94\uBFB0\uBFCC\uBFE8\uC004" \
- "\uC020\uC03C\uC058\uC074\uC090\uC0AC\uC0C8\uC0E4" \
- "\uC100\uC11C\uC138\uC154\uC170\uC18C\uC1A8\uC1C4" \
- "\uC1E0\uC1FC\uC218\uC234\uC250\uC26C\uC288\uC2A4" \
- "\uC2C0\uC2DC\uC2F8\uC314\uC330\uC34C\uC368\uC384" \
- "\uC3A0\uC3BC\uC3D8\uC3F4\uC410\uC42C\uC448\uC464" \
- "\uC480\uC49C\uC4B8\uC4D4\uC4F0\uC50C\uC528\uC544" \
- "\uC560\uC57C\uC598\uC5B4\uC5D0\uC5EC\uC608\uC624" \
- "\uC640\uC65C\uC678\uC694\uC6B0\uC6CC\uC6E8\uC704" \
- "\uC720\uC73C\uC758\uC774\uC790\uC7AC\uC7C8\uC7E4" \
- "\uC800\uC81C\uC838\uC854\uC870\uC88C\uC8A8\uC8C4" \
- "\uC8E0\uC8FC\uC918\uC934\uC950\uC96C\uC988\uC9A4" \
- "\uC9C0\uC9DC\uC9F8\uCA14\uCA30\uCA4C\uCA68\uCA84" \
- "\uCAA0\uCABC\uCAD8\uCAF4\uCB10\uCB2C\uCB48\uCB64" \
- "\uCB80\uCB9C\uCBB8\uCBD4\uCBF0\uCC0C\uCC28\uCC44" \
- "\uCC60\uCC7C\uCC98\uCCB4\uCCD0\uCCEC\uCD08\uCD24" \
- "\uCD40\uCD5C\uCD78\uCD94\uCDB0\uCDCC\uCDE8\uCE04" \
- "\uCE20\uCE3C\uCE58\uCE74\uCE90\uCEAC\uCEC8\uCEE4" \
- "\uCF00\uCF1C\uCF38\uCF54\uCF70\uCF8C\uCFA8\uCFC4" \
- "\uCFE0\uCFFC\uD018\uD034\uD050\uD06C\uD088\uD0A4" \
- "\uD0C0\uD0DC\uD0F8\uD114\uD130\uD14C\uD168\uD184" \
- "\uD1A0\uD1BC\uD1D8\uD1F4\uD210\uD22C\uD248\uD264" \
- "\uD280\uD29C\uD2B8\uD2D4\uD2F0\uD30C\uD328\uD344" \
- "\uD360\uD37C\uD398\uD3B4\uD3D0\uD3EC\uD408\uD424" \
- "\uD440\uD45C\uD478\uD494\uD4B0\uD4CC\uD4E8\uD504" \
- "\uD520\uD53C\uD558\uD574\uD590\uD5AC\uD5C8\uD5E4" \
- "\uD600\uD61C\uD638\uD654\uD670\uD68C\uD6A8\uD6C4" \
- "\uD6E0\uD6FC\uD718\uD734\uD750\uD76C\uD788" \
+ "[\uAC00" \
+ "\uAC1C" \
+ "\uAC38" \
+ "\uAC54" \
+ "\uAC70" \
+ "\uAC8C" \
+ "\uACA8" \
+ "\uACC4" \
+ "\uACE0" \
+ "\uACFC" \
+ "\uAD18" \
+ "\uAD34" \
+ "\uAD50" \
+ "\uAD6C" \
+ "\uAD88" \
+ "\uADA4" \
+ "\uADC0" \
+ "\uADDC" \
+ "\uADF8" \
+ "\uAE14" \
+ "\uAE30" \
+ "\uAE4C" \
+ "\uAE68" \
+ "\uAE84" \
+ "\uAEA0" \
+ "\uAEBC" \
+ "\uAED8" \
+ "\uAEF4" \
+ "\uAF10" \
+ "\uAF2C" \
+ "\uAF48" \
+ "\uAF64" \
+ "\uAF80" \
+ "\uAF9C" \
+ "\uAFB8" \
+ "\uAFD4" \
+ "\uAFF0" \
+ "\uB00C" \
+ "\uB028" \
+ "\uB044" \
+ "\uB060" \
+ "\uB07C" \
+ "\uB098" \
+ "\uB0B4" \
+ "\uB0D0" \
+ "\uB0EC" \
+ "\uB108" \
+ "\uB124" \
+ "\uB140" \
+ "\uB15C" \
+ "\uB178" \
+ "\uB194" \
+ "\uB1B0" \
+ "\uB1CC" \
+ "\uB1E8" \
+ "\uB204" \
+ "\uB220" \
+ "\uB23C" \
+ "\uB258" \
+ "\uB274" \
+ "\uB290" \
+ "\uB2AC" \
+ "\uB2C8" \
+ "\uB2E4" \
+ "\uB300" \
+ "\uB31C" \
+ "\uB338" \
+ "\uB354" \
+ "\uB370" \
+ "\uB38C" \
+ "\uB3A8" \
+ "\uB3C4" \
+ "\uB3E0" \
+ "\uB3FC" \
+ "\uB418" \
+ "\uB434" \
+ "\uB450" \
+ "\uB46C" \
+ "\uB488" \
+ "\uB4A4" \
+ "\uB4C0" \
+ "\uB4DC" \
+ "\uB4F8" \
+ "\uB514" \
+ "\uB530" \
+ "\uB54C" \
+ "\uB568" \
+ "\uB584" \
+ "\uB5A0" \
+ "\uB5BC" \
+ "\uB5D8" \
+ "\uB5F4" \
+ "\uB610" \
+ "\uB62C" \
+ "\uB648" \
+ "\uB664" \
+ "\uB680" \
+ "\uB69C" \
+ "\uB6B8" \
+ "\uB6D4" \
+ "\uB6F0" \
+ "\uB70C" \
+ "\uB728" \
+ "\uB744" \
+ "\uB760" \
+ "\uB77C" \
+ "\uB798" \
+ "\uB7B4" \
+ "\uB7D0" \
+ "\uB7EC" \
+ "\uB808" \
+ "\uB824" \
+ "\uB840" \
+ "\uB85C" \
+ "\uB878" \
+ "\uB894" \
+ "\uB8B0" \
+ "\uB8CC" \
+ "\uB8E8" \
+ "\uB904" \
+ "\uB920" \
+ "\uB93C" \
+ "\uB958" \
+ "\uB974" \
+ "\uB990" \
+ "\uB9AC" \
+ "\uB9C8" \
+ "\uB9E4" \
+ "\uBA00" \
+ "\uBA1C" \
+ "\uBA38" \
+ "\uBA54" \
+ "\uBA70" \
+ "\uBA8C" \
+ "\uBAA8" \
+ "\uBAC4" \
+ "\uBAE0" \
+ "\uBAFC" \
+ "\uBB18" \
+ "\uBB34" \
+ "\uBB50" \
+ "\uBB6C" \
+ "\uBB88" \
+ "\uBBA4" \
+ "\uBBC0" \
+ "\uBBDC" \
+ "\uBBF8" \
+ "\uBC14" \
+ "\uBC30" \
+ "\uBC4C" \
+ "\uBC68" \
+ "\uBC84" \
+ "\uBCA0" \
+ "\uBCBC" \
+ "\uBCD8" \
+ "\uBCF4" \
+ "\uBD10" \
+ "\uBD2C" \
+ "\uBD48" \
+ "\uBD64" \
+ "\uBD80" \
+ "\uBD9C" \
+ "\uBDB8" \
+ "\uBDD4" \
+ "\uBDF0" \
+ "\uBE0C" \
+ "\uBE28" \
+ "\uBE44" \
+ "\uBE60" \
+ "\uBE7C" \
+ "\uBE98" \
+ "\uBEB4" \
+ "\uBED0" \
+ "\uBEEC" \
+ "\uBF08" \
+ "\uBF24" \
+ "\uBF40" \
+ "\uBF5C" \
+ "\uBF78" \
+ "\uBF94" \
+ "\uBFB0" \
+ "\uBFCC" \
+ "\uBFE8" \
+ "\uC004" \
+ "\uC020" \
+ "\uC03C" \
+ "\uC058" \
+ "\uC074" \
+ "\uC090" \
+ "\uC0AC" \
+ "\uC0C8" \
+ "\uC0E4" \
+ "\uC100" \
+ "\uC11C" \
+ "\uC138" \
+ "\uC154" \
+ "\uC170" \
+ "\uC18C" \
+ "\uC1A8" \
+ "\uC1C4" \
+ "\uC1E0" \
+ "\uC1FC" \
+ "\uC218" \
+ "\uC234" \
+ "\uC250" \
+ "\uC26C" \
+ "\uC288" \
+ "\uC2A4" \
+ "\uC2C0" \
+ "\uC2DC" \
+ "\uC2F8" \
+ "\uC314" \
+ "\uC330" \
+ "\uC34C" \
+ "\uC368" \
+ "\uC384" \
+ "\uC3A0" \
+ "\uC3BC" \
+ "\uC3D8" \
+ "\uC3F4" \
+ "\uC410" \
+ "\uC42C" \
+ "\uC448" \
+ "\uC464" \
+ "\uC480" \
+ "\uC49C" \
+ "\uC4B8" \
+ "\uC4D4" \
+ "\uC4F0" \
+ "\uC50C" \
+ "\uC528" \
+ "\uC544" \
+ "\uC560" \
+ "\uC57C" \
+ "\uC598" \
+ "\uC5B4" \
+ "\uC5D0" \
+ "\uC5EC" \
+ "\uC608" \
+ "\uC624" \
+ "\uC640" \
+ "\uC65C" \
+ "\uC678" \
+ "\uC694" \
+ "\uC6B0" \
+ "\uC6CC" \
+ "\uC6E8" \
+ "\uC704" \
+ "\uC720" \
+ "\uC73C" \
+ "\uC758" \
+ "\uC774" \
+ "\uC790" \
+ "\uC7AC" \
+ "\uC7C8" \
+ "\uC7E4" \
+ "\uC800" \
+ "\uC81C" \
+ "\uC838" \
+ "\uC854" \
+ "\uC870" \
+ "\uC88C" \
+ "\uC8A8" \
+ "\uC8C4" \
+ "\uC8E0" \
+ "\uC8FC" \
+ "\uC918" \
+ "\uC934" \
+ "\uC950" \
+ "\uC96C" \
+ "\uC988" \
+ "\uC9A4" \
+ "\uC9C0" \
+ "\uC9DC" \
+ "\uC9F8" \
+ "\uCA14" \
+ "\uCA30" \
+ "\uCA4C" \
+ "\uCA68" \
+ "\uCA84" \
+ "\uCAA0" \
+ "\uCABC" \
+ "\uCAD8" \
+ "\uCAF4" \
+ "\uCB10" \
+ "\uCB2C" \
+ "\uCB48" \
+ "\uCB64" \
+ "\uCB80" \
+ "\uCB9C" \
+ "\uCBB8" \
+ "\uCBD4" \
+ "\uCBF0" \
+ "\uCC0C" \
+ "\uCC28" \
+ "\uCC44" \
+ "\uCC60" \
+ "\uCC7C" \
+ "\uCC98" \
+ "\uCCB4" \
+ "\uCCD0" \
+ "\uCCEC" \
+ "\uCD08" \
+ "\uCD24" \
+ "\uCD40" \
+ "\uCD5C" \
+ "\uCD78" \
+ "\uCD94" \
+ "\uCDB0" \
+ "\uCDCC" \
+ "\uCDE8" \
+ "\uCE04" \
+ "\uCE20" \
+ "\uCE3C" \
+ "\uCE58" \
+ "\uCE74" \
+ "\uCE90" \
+ "\uCEAC" \
+ "\uCEC8" \
+ "\uCEE4" \
+ "\uCF00" \
+ "\uCF1C" \
+ "\uCF38" \
+ "\uCF54" \
+ "\uCF70" \
+ "\uCF8C" \
+ "\uCFA8" \
+ "\uCFC4" \
+ "\uCFE0" \
+ "\uCFFC" \
+ "\uD018" \
+ "\uD034" \
+ "\uD050" \
+ "\uD06C" \
+ "\uD088" \
+ "\uD0A4" \
+ "\uD0C0" \
+ "\uD0DC" \
+ "\uD0F8" \
+ "\uD114" \
+ "\uD130" \
+ "\uD14C" \
+ "\uD168" \
+ "\uD184" \
+ "\uD1A0" \
+ "\uD1BC" \
+ "\uD1D8" \
+ "\uD1F4" \
+ "\uD210" \
+ "\uD22C" \
+ "\uD248" \
+ "\uD264" \
+ "\uD280" \
+ "\uD29C" \
+ "\uD2B8" \
+ "\uD2D4" \
+ "\uD2F0" \
+ "\uD30C" \
+ "\uD328" \
+ "\uD344" \
+ "\uD360" \
+ "\uD37C" \
+ "\uD398" \
+ "\uD3B4" \
+ "\uD3D0" \
+ "\uD3EC" \
+ "\uD408" \
+ "\uD424" \
+ "\uD440" \
+ "\uD45C" \
+ "\uD478" \
+ "\uD494" \
+ "\uD4B0" \
+ "\uD4CC" \
+ "\uD4E8" \
+ "\uD504" \
+ "\uD520" \
+ "\uD53C" \
+ "\uD558" \
+ "\uD574" \
+ "\uD590" \
+ "\uD5AC" \
+ "\uD5C8" \
+ "\uD5E4" \
+ "\uD600" \
+ "\uD61C" \
+ "\uD638" \
+ "\uD654" \
+ "\uD670" \
+ "\uD68C" \
+ "\uD6A8" \
+ "\uD6C4" \
+ "\uD6E0" \
+ "\uD6FC" \
+ "\uD718" \
+ "\uD734" \
+ "\uD750" \
+ "\uD76C" \
+ "\uD788" \
"][\u11A8-\u11C2]" \
"|#{'' # decomposed Hangul syllables
}" \
"[\u1100-\u1112][\u1161-\u1175][\u11A8-\u11C2]?"
REGEXP_K_STRING = "" \
- "[\u00A0\u00A8\u00AA\u00AF\u00B2-\u00B5\u00B8-\u00BA\u00BC-\u00BE\u0132\u0133" \
- "\u013F\u0140\u0149\u017F\u01C4-\u01CC\u01F1-\u01F3\u02B0-\u02B8\u02D8-\u02DD\u02E0-\u02E4" \
- "\u037A\u0384\u0385\u03D0-\u03D6\u03F0-\u03F2\u03F4\u03F5\u03F9\u0587\u0675-\u0678" \
- "\u0E33\u0EB3\u0EDC\u0EDD\u0F0C\u0F77\u0F79\u10FC\u1D2C-\u1D2E" \
- "\u1D30-\u1D3A\u1D3C-\u1D4D\u1D4F-\u1D6A\u1D78\u1D9B-\u1DBF\u1E9A\u1E9B\u1FBD\u1FBF-\u1FC1" \
- "\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED\u1FEE\u1FFD\u1FFE\u2000-\u200A\u2011\u2017\u2024-\u2026" \
- "\u202F\u2033\u2034\u2036\u2037\u203C\u203E\u2047-\u2049\u2057\u205F" \
- "\u2070\u2071\u2074-\u208E\u2090-\u209C\u20A8\u2100-\u2103\u2105-\u2107\u2109-\u2113\u2115\u2116" \
- "\u2119-\u211D\u2120-\u2122\u2124\u2128\u212C\u212D\u212F-\u2131\u2133-\u2139\u213B-\u2140" \
- "\u2145-\u2149\u2150-\u217F\u2189\u222C\u222D\u222F\u2230\u2460-\u24EA\u2A0C\u2A74-\u2A76" \
- "\u2C7C\u2C7D\u2D6F\u2E9F\u2EF3\u2F00-\u2FD5\u3000\u3036\u3038-\u303A" \
- "\u309B\u309C\u309F\u30FF\u3131-\u318E\u3192-\u319F\u3200-\u321E\u3220-\u3247\u3250-\u327E" \
- "\u3280-\u32FE\u3300-\u33FF\uA69C\uA69D\uA770\uA7F8\uA7F9\uAB5C-\uAB5F\uFB00-\uFB06\uFB13-\uFB17" \
- "\uFB20-\uFB29\uFB4F-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFC\uFE10-\uFE19\uFE30-\uFE44" \
- "\uFE47-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFE70-\uFE72\uFE74\uFE76-\uFEFC\uFF01-\uFFBE\uFFC2-\uFFC7" \
- "\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\uFFE0-\uFFE6\uFFE8-\uFFEE\u{1D400}-\u{1D454}\u{1D456}-\u{1D49C}\u{1D49E}\u{1D49F}" \
- "\u{1D4A2}\u{1D4A5}\u{1D4A6}\u{1D4A9}-\u{1D4AC}\u{1D4AE}-\u{1D4B9}\u{1D4BB}\u{1D4BD}-\u{1D4C3}\u{1D4C5}-\u{1D505}\u{1D507}-\u{1D50A}" \
- "\u{1D50D}-\u{1D514}\u{1D516}-\u{1D51C}\u{1D51E}-\u{1D539}\u{1D53B}-\u{1D53E}\u{1D540}-\u{1D544}\u{1D546}\u{1D54A}-\u{1D550}\u{1D552}-\u{1D6A5}" \
- "\u{1D6A8}-\u{1D7CB}\u{1D7CE}-\u{1D7FF}\u{1EE00}-\u{1EE03}\u{1EE05}-\u{1EE1F}\u{1EE21}\u{1EE22}\u{1EE24}\u{1EE27}\u{1EE29}-\u{1EE32}" \
- "\u{1EE34}-\u{1EE37}\u{1EE39}\u{1EE3B}\u{1EE42}\u{1EE47}\u{1EE49}\u{1EE4B}\u{1EE4D}-\u{1EE4F}" \
- "\u{1EE51}\u{1EE52}\u{1EE54}\u{1EE57}\u{1EE59}\u{1EE5B}\u{1EE5D}\u{1EE5F}\u{1EE61}\u{1EE62}" \
- "\u{1EE64}\u{1EE67}-\u{1EE6A}\u{1EE6C}-\u{1EE72}\u{1EE74}-\u{1EE77}\u{1EE79}-\u{1EE7C}\u{1EE7E}\u{1EE80}-\u{1EE89}\u{1EE8B}-\u{1EE9B}" \
- "\u{1EEA1}-\u{1EEA3}\u{1EEA5}-\u{1EEA9}\u{1EEAB}-\u{1EEBB}\u{1F100}-\u{1F10A}\u{1F110}-\u{1F12E}\u{1F130}-\u{1F14F}\u{1F16A}\u{1F16B}\u{1F190}" \
- "\u{1F200}-\u{1F202}\u{1F210}-\u{1F23B}\u{1F240}-\u{1F248}\u{1F250}\u{1F251}" \
+ "[\u00A0" \
+ "\u00A8" \
+ "\u00AA" \
+ "\u00AF" \
+ "\u00B2-\u00B5" \
+ "\u00B8-\u00BA" \
+ "\u00BC-\u00BE" \
+ "\u0132\u0133" \
+ "\u013F\u0140" \
+ "\u0149" \
+ "\u017F" \
+ "\u01C4-\u01CC" \
+ "\u01F1-\u01F3" \
+ "\u02B0-\u02B8" \
+ "\u02D8-\u02DD" \
+ "\u02E0-\u02E4" \
+ "\u037A" \
+ "\u0384\u0385" \
+ "\u03D0-\u03D6" \
+ "\u03F0-\u03F2" \
+ "\u03F4\u03F5" \
+ "\u03F9" \
+ "\u0587" \
+ "\u0675-\u0678" \
+ "\u0E33" \
+ "\u0EB3" \
+ "\u0EDC\u0EDD" \
+ "\u0F0C" \
+ "\u0F77" \
+ "\u0F79" \
+ "\u10FC" \
+ "\u1D2C-\u1D2E" \
+ "\u1D30-\u1D3A" \
+ "\u1D3C-\u1D4D" \
+ "\u1D4F-\u1D6A" \
+ "\u1D78" \
+ "\u1D9B-\u1DBF" \
+ "\u1E9A\u1E9B" \
+ "\u1FBD" \
+ "\u1FBF-\u1FC1" \
+ "\u1FCD-\u1FCF" \
+ "\u1FDD-\u1FDF" \
+ "\u1FED\u1FEE" \
+ "\u1FFD\u1FFE" \
+ "\u2000-\u200A" \
+ "\u2011" \
+ "\u2017" \
+ "\u2024-\u2026" \
+ "\u202F" \
+ "\u2033\u2034" \
+ "\u2036\u2037" \
+ "\u203C" \
+ "\u203E" \
+ "\u2047-\u2049" \
+ "\u2057" \
+ "\u205F" \
+ "\u2070\u2071" \
+ "\u2074-\u208E" \
+ "\u2090-\u209C" \
+ "\u20A8" \
+ "\u2100-\u2103" \
+ "\u2105-\u2107" \
+ "\u2109-\u2113" \
+ "\u2115\u2116" \
+ "\u2119-\u211D" \
+ "\u2120-\u2122" \
+ "\u2124" \
+ "\u2128" \
+ "\u212C\u212D" \
+ "\u212F-\u2131" \
+ "\u2133-\u2139" \
+ "\u213B-\u2140" \
+ "\u2145-\u2149" \
+ "\u2150-\u217F" \
+ "\u2189" \
+ "\u222C\u222D" \
+ "\u222F\u2230" \
+ "\u2460-\u24EA" \
+ "\u2A0C" \
+ "\u2A74-\u2A76" \
+ "\u2C7C\u2C7D" \
+ "\u2D6F" \
+ "\u2E9F" \
+ "\u2EF3" \
+ "\u2F00-\u2FD5" \
+ "\u3000" \
+ "\u3036" \
+ "\u3038-\u303A" \
+ "\u309B\u309C" \
+ "\u309F" \
+ "\u30FF" \
+ "\u3131-\u318E" \
+ "\u3192-\u319F" \
+ "\u3200-\u321E" \
+ "\u3220-\u3247" \
+ "\u3250-\u327E" \
+ "\u3280-\u33FF" \
+ "\uA69C\uA69D" \
+ "\uA770" \
+ "\uA7F8\uA7F9" \
+ "\uAB5C-\uAB5F" \
+ "\uFB00-\uFB06" \
+ "\uFB13-\uFB17" \
+ "\uFB20-\uFB29" \
+ "\uFB4F-\uFBB1" \
+ "\uFBD3-\uFD3D" \
+ "\uFD50-\uFD8F" \
+ "\uFD92-\uFDC7" \
+ "\uFDF0-\uFDFC" \
+ "\uFE10-\uFE19" \
+ "\uFE30-\uFE44" \
+ "\uFE47-\uFE52" \
+ "\uFE54-\uFE66" \
+ "\uFE68-\uFE6B" \
+ "\uFE70-\uFE72" \
+ "\uFE74" \
+ "\uFE76-\uFEFC" \
+ "\uFF01-\uFFBE" \
+ "\uFFC2-\uFFC7" \
+ "\uFFCA-\uFFCF" \
+ "\uFFD2-\uFFD7" \
+ "\uFFDA-\uFFDC" \
+ "\uFFE0-\uFFE6" \
+ "\uFFE8-\uFFEE" \
+ "\u{1D400}-\u{1D454}" \
+ "\u{1D456}-\u{1D49C}" \
+ "\u{1D49E}\u{1D49F}" \
+ "\u{1D4A2}" \
+ "\u{1D4A5}\u{1D4A6}" \
+ "\u{1D4A9}-\u{1D4AC}" \
+ "\u{1D4AE}-\u{1D4B9}" \
+ "\u{1D4BB}" \
+ "\u{1D4BD}-\u{1D4C3}" \
+ "\u{1D4C5}-\u{1D505}" \
+ "\u{1D507}-\u{1D50A}" \
+ "\u{1D50D}-\u{1D514}" \
+ "\u{1D516}-\u{1D51C}" \
+ "\u{1D51E}-\u{1D539}" \
+ "\u{1D53B}-\u{1D53E}" \
+ "\u{1D540}-\u{1D544}" \
+ "\u{1D546}" \
+ "\u{1D54A}-\u{1D550}" \
+ "\u{1D552}-\u{1D6A5}" \
+ "\u{1D6A8}-\u{1D7CB}" \
+ "\u{1D7CE}-\u{1D7FF}" \
+ "\u{1EE00}-\u{1EE03}" \
+ "\u{1EE05}-\u{1EE1F}" \
+ "\u{1EE21}\u{1EE22}" \
+ "\u{1EE24}" \
+ "\u{1EE27}" \
+ "\u{1EE29}-\u{1EE32}" \
+ "\u{1EE34}-\u{1EE37}" \
+ "\u{1EE39}" \
+ "\u{1EE3B}" \
+ "\u{1EE42}" \
+ "\u{1EE47}" \
+ "\u{1EE49}" \
+ "\u{1EE4B}" \
+ "\u{1EE4D}-\u{1EE4F}" \
+ "\u{1EE51}\u{1EE52}" \
+ "\u{1EE54}" \
+ "\u{1EE57}" \
+ "\u{1EE59}" \
+ "\u{1EE5B}" \
+ "\u{1EE5D}" \
+ "\u{1EE5F}" \
+ "\u{1EE61}\u{1EE62}" \
+ "\u{1EE64}" \
+ "\u{1EE67}-\u{1EE6A}" \
+ "\u{1EE6C}-\u{1EE72}" \
+ "\u{1EE74}-\u{1EE77}" \
+ "\u{1EE79}-\u{1EE7C}" \
+ "\u{1EE7E}" \
+ "\u{1EE80}-\u{1EE89}" \
+ "\u{1EE8B}-\u{1EE9B}" \
+ "\u{1EEA1}-\u{1EEA3}" \
+ "\u{1EEA5}-\u{1EEA9}" \
+ "\u{1EEAB}-\u{1EEBB}" \
+ "\u{1F100}-\u{1F10A}" \
+ "\u{1F110}-\u{1F12E}" \
+ "\u{1F130}-\u{1F14F}" \
+ "\u{1F16A}-\u{1F16C}" \
+ "\u{1F190}" \
+ "\u{1F200}-\u{1F202}" \
+ "\u{1F210}-\u{1F23B}" \
+ "\u{1F240}-\u{1F248}" \
+ "\u{1F250}\u{1F251}" \
"]"
class_table = {
- "\u0300"=>230, "\u0301"=>230, "\u0302"=>230, "\u0303"=>230, "\u0304"=>230, "\u0305"=>230, "\u0306"=>230, "\u0307"=>230,
- "\u0308"=>230, "\u0309"=>230, "\u030A"=>230, "\u030B"=>230, "\u030C"=>230, "\u030D"=>230, "\u030E"=>230, "\u030F"=>230,
- "\u0310"=>230, "\u0311"=>230, "\u0312"=>230, "\u0313"=>230, "\u0314"=>230, "\u0315"=>232, "\u0316"=>220, "\u0317"=>220,
- "\u0318"=>220, "\u0319"=>220, "\u031A"=>232, "\u031B"=>216, "\u031C"=>220, "\u031D"=>220, "\u031E"=>220, "\u031F"=>220,
- "\u0320"=>220, "\u0321"=>202, "\u0322"=>202, "\u0323"=>220, "\u0324"=>220, "\u0325"=>220, "\u0326"=>220, "\u0327"=>202,
- "\u0328"=>202, "\u0329"=>220, "\u032A"=>220, "\u032B"=>220, "\u032C"=>220, "\u032D"=>220, "\u032E"=>220, "\u032F"=>220,
- "\u0330"=>220, "\u0331"=>220, "\u0332"=>220, "\u0333"=>220, "\u0334"=>1, "\u0335"=>1, "\u0336"=>1, "\u0337"=>1,
- "\u0338"=>1, "\u0339"=>220, "\u033A"=>220, "\u033B"=>220, "\u033C"=>220, "\u033D"=>230, "\u033E"=>230, "\u033F"=>230,
- "\u0340"=>230, "\u0341"=>230, "\u0342"=>230, "\u0343"=>230, "\u0344"=>230, "\u0345"=>240, "\u0346"=>230, "\u0347"=>220,
- "\u0348"=>220, "\u0349"=>220, "\u034A"=>230, "\u034B"=>230, "\u034C"=>230, "\u034D"=>220, "\u034E"=>220, "\u0350"=>230,
- "\u0351"=>230, "\u0352"=>230, "\u0353"=>220, "\u0354"=>220, "\u0355"=>220, "\u0356"=>220, "\u0357"=>230, "\u0358"=>232,
- "\u0359"=>220, "\u035A"=>220, "\u035B"=>230, "\u035C"=>233, "\u035D"=>234, "\u035E"=>234, "\u035F"=>233, "\u0360"=>234,
- "\u0361"=>234, "\u0362"=>233, "\u0363"=>230, "\u0364"=>230, "\u0365"=>230, "\u0366"=>230, "\u0367"=>230, "\u0368"=>230,
- "\u0369"=>230, "\u036A"=>230, "\u036B"=>230, "\u036C"=>230, "\u036D"=>230, "\u036E"=>230, "\u036F"=>230, "\u0483"=>230,
- "\u0484"=>230, "\u0485"=>230, "\u0486"=>230, "\u0487"=>230, "\u0591"=>220, "\u0592"=>230, "\u0593"=>230, "\u0594"=>230,
- "\u0595"=>230, "\u0596"=>220, "\u0597"=>230, "\u0598"=>230, "\u0599"=>230, "\u059A"=>222, "\u059B"=>220, "\u059C"=>230,
- "\u059D"=>230, "\u059E"=>230, "\u059F"=>230, "\u05A0"=>230, "\u05A1"=>230, "\u05A2"=>220, "\u05A3"=>220, "\u05A4"=>220,
- "\u05A5"=>220, "\u05A6"=>220, "\u05A7"=>220, "\u05A8"=>230, "\u05A9"=>230, "\u05AA"=>220, "\u05AB"=>230, "\u05AC"=>230,
- "\u05AD"=>222, "\u05AE"=>228, "\u05AF"=>230, "\u05B0"=>10, "\u05B1"=>11, "\u05B2"=>12, "\u05B3"=>13, "\u05B4"=>14,
- "\u05B5"=>15, "\u05B6"=>16, "\u05B7"=>17, "\u05B8"=>18, "\u05B9"=>19, "\u05BA"=>19, "\u05BB"=>20, "\u05BC"=>21,
- "\u05BD"=>22, "\u05BF"=>23, "\u05C1"=>24, "\u05C2"=>25, "\u05C4"=>230, "\u05C5"=>220, "\u05C7"=>18, "\u0610"=>230,
- "\u0611"=>230, "\u0612"=>230, "\u0613"=>230, "\u0614"=>230, "\u0615"=>230, "\u0616"=>230, "\u0617"=>230, "\u0618"=>30,
- "\u0619"=>31, "\u061A"=>32, "\u064B"=>27, "\u064C"=>28, "\u064D"=>29, "\u064E"=>30, "\u064F"=>31, "\u0650"=>32,
- "\u0651"=>33, "\u0652"=>34, "\u0653"=>230, "\u0654"=>230, "\u0655"=>220, "\u0656"=>220, "\u0657"=>230, "\u0658"=>230,
- "\u0659"=>230, "\u065A"=>230, "\u065B"=>230, "\u065C"=>220, "\u065D"=>230, "\u065E"=>230, "\u065F"=>220, "\u0670"=>35,
- "\u06D6"=>230, "\u06D7"=>230, "\u06D8"=>230, "\u06D9"=>230, "\u06DA"=>230, "\u06DB"=>230, "\u06DC"=>230, "\u06DF"=>230,
- "\u06E0"=>230, "\u06E1"=>230, "\u06E2"=>230, "\u06E3"=>220, "\u06E4"=>230, "\u06E7"=>230, "\u06E8"=>230, "\u06EA"=>220,
- "\u06EB"=>230, "\u06EC"=>230, "\u06ED"=>220, "\u0711"=>36, "\u0730"=>230, "\u0731"=>220, "\u0732"=>230, "\u0733"=>230,
- "\u0734"=>220, "\u0735"=>230, "\u0736"=>230, "\u0737"=>220, "\u0738"=>220, "\u0739"=>220, "\u073A"=>230, "\u073B"=>220,
- "\u073C"=>220, "\u073D"=>230, "\u073E"=>220, "\u073F"=>230, "\u0740"=>230, "\u0741"=>230, "\u0742"=>220, "\u0743"=>230,
- "\u0744"=>220, "\u0745"=>230, "\u0746"=>220, "\u0747"=>230, "\u0748"=>220, "\u0749"=>230, "\u074A"=>230, "\u07EB"=>230,
- "\u07EC"=>230, "\u07ED"=>230, "\u07EE"=>230, "\u07EF"=>230, "\u07F0"=>230, "\u07F1"=>230, "\u07F2"=>220, "\u07F3"=>230,
- "\u0816"=>230, "\u0817"=>230, "\u0818"=>230, "\u0819"=>230, "\u081B"=>230, "\u081C"=>230, "\u081D"=>230, "\u081E"=>230,
- "\u081F"=>230, "\u0820"=>230, "\u0821"=>230, "\u0822"=>230, "\u0823"=>230, "\u0825"=>230, "\u0826"=>230, "\u0827"=>230,
- "\u0829"=>230, "\u082A"=>230, "\u082B"=>230, "\u082C"=>230, "\u082D"=>230, "\u0859"=>220, "\u085A"=>220, "\u085B"=>220,
- "\u08D4"=>230, "\u08D5"=>230, "\u08D6"=>230, "\u08D7"=>230, "\u08D8"=>230, "\u08D9"=>230, "\u08DA"=>230, "\u08DB"=>230,
- "\u08DC"=>230, "\u08DD"=>230, "\u08DE"=>230, "\u08DF"=>230, "\u08E0"=>230, "\u08E1"=>230, "\u08E3"=>220, "\u08E4"=>230,
- "\u08E5"=>230, "\u08E6"=>220, "\u08E7"=>230, "\u08E8"=>230, "\u08E9"=>220, "\u08EA"=>230, "\u08EB"=>230, "\u08EC"=>230,
- "\u08ED"=>220, "\u08EE"=>220, "\u08EF"=>220, "\u08F0"=>27, "\u08F1"=>28, "\u08F2"=>29, "\u08F3"=>230, "\u08F4"=>230,
- "\u08F5"=>230, "\u08F6"=>220, "\u08F7"=>230, "\u08F8"=>230, "\u08F9"=>220, "\u08FA"=>220, "\u08FB"=>230, "\u08FC"=>230,
- "\u08FD"=>230, "\u08FE"=>230, "\u08FF"=>230, "\u093C"=>7, "\u094D"=>9, "\u0951"=>230, "\u0952"=>220, "\u0953"=>230,
- "\u0954"=>230, "\u09BC"=>7, "\u09CD"=>9, "\u0A3C"=>7, "\u0A4D"=>9, "\u0ABC"=>7, "\u0ACD"=>9, "\u0B3C"=>7,
- "\u0B4D"=>9, "\u0BCD"=>9, "\u0C4D"=>9, "\u0C55"=>84, "\u0C56"=>91, "\u0CBC"=>7, "\u0CCD"=>9, "\u0D3B"=>9,
- "\u0D3C"=>9, "\u0D4D"=>9, "\u0DCA"=>9, "\u0E38"=>103, "\u0E39"=>103, "\u0E3A"=>9, "\u0E48"=>107, "\u0E49"=>107,
- "\u0E4A"=>107, "\u0E4B"=>107, "\u0EB8"=>118, "\u0EB9"=>118, "\u0EC8"=>122, "\u0EC9"=>122, "\u0ECA"=>122, "\u0ECB"=>122,
- "\u0F18"=>220, "\u0F19"=>220, "\u0F35"=>220, "\u0F37"=>220, "\u0F39"=>216, "\u0F71"=>129, "\u0F72"=>130, "\u0F74"=>132,
- "\u0F7A"=>130, "\u0F7B"=>130, "\u0F7C"=>130, "\u0F7D"=>130, "\u0F80"=>130, "\u0F82"=>230, "\u0F83"=>230, "\u0F84"=>9,
- "\u0F86"=>230, "\u0F87"=>230, "\u0FC6"=>220, "\u1037"=>7, "\u1039"=>9, "\u103A"=>9, "\u108D"=>220, "\u135D"=>230,
- "\u135E"=>230, "\u135F"=>230, "\u1714"=>9, "\u1734"=>9, "\u17D2"=>9, "\u17DD"=>230, "\u18A9"=>228, "\u1939"=>222,
- "\u193A"=>230, "\u193B"=>220, "\u1A17"=>230, "\u1A18"=>220, "\u1A60"=>9, "\u1A75"=>230, "\u1A76"=>230, "\u1A77"=>230,
- "\u1A78"=>230, "\u1A79"=>230, "\u1A7A"=>230, "\u1A7B"=>230, "\u1A7C"=>230, "\u1A7F"=>220, "\u1AB0"=>230, "\u1AB1"=>230,
- "\u1AB2"=>230, "\u1AB3"=>230, "\u1AB4"=>230, "\u1AB5"=>220, "\u1AB6"=>220, "\u1AB7"=>220, "\u1AB8"=>220, "\u1AB9"=>220,
- "\u1ABA"=>220, "\u1ABB"=>230, "\u1ABC"=>230, "\u1ABD"=>220, "\u1B34"=>7, "\u1B44"=>9, "\u1B6B"=>230, "\u1B6C"=>220,
- "\u1B6D"=>230, "\u1B6E"=>230, "\u1B6F"=>230, "\u1B70"=>230, "\u1B71"=>230, "\u1B72"=>230, "\u1B73"=>230, "\u1BAA"=>9,
- "\u1BAB"=>9, "\u1BE6"=>7, "\u1BF2"=>9, "\u1BF3"=>9, "\u1C37"=>7, "\u1CD0"=>230, "\u1CD1"=>230, "\u1CD2"=>230,
- "\u1CD4"=>1, "\u1CD5"=>220, "\u1CD6"=>220, "\u1CD7"=>220, "\u1CD8"=>220, "\u1CD9"=>220, "\u1CDA"=>230, "\u1CDB"=>230,
- "\u1CDC"=>220, "\u1CDD"=>220, "\u1CDE"=>220, "\u1CDF"=>220, "\u1CE0"=>230, "\u1CE2"=>1, "\u1CE3"=>1, "\u1CE4"=>1,
- "\u1CE5"=>1, "\u1CE6"=>1, "\u1CE7"=>1, "\u1CE8"=>1, "\u1CED"=>220, "\u1CF4"=>230, "\u1CF8"=>230, "\u1CF9"=>230,
- "\u1DC0"=>230, "\u1DC1"=>230, "\u1DC2"=>220, "\u1DC3"=>230, "\u1DC4"=>230, "\u1DC5"=>230, "\u1DC6"=>230, "\u1DC7"=>230,
- "\u1DC8"=>230, "\u1DC9"=>230, "\u1DCA"=>220, "\u1DCB"=>230, "\u1DCC"=>230, "\u1DCD"=>234, "\u1DCE"=>214, "\u1DCF"=>220,
- "\u1DD0"=>202, "\u1DD1"=>230, "\u1DD2"=>230, "\u1DD3"=>230, "\u1DD4"=>230, "\u1DD5"=>230, "\u1DD6"=>230, "\u1DD7"=>230,
- "\u1DD8"=>230, "\u1DD9"=>230, "\u1DDA"=>230, "\u1DDB"=>230, "\u1DDC"=>230, "\u1DDD"=>230, "\u1DDE"=>230, "\u1DDF"=>230,
- "\u1DE0"=>230, "\u1DE1"=>230, "\u1DE2"=>230, "\u1DE3"=>230, "\u1DE4"=>230, "\u1DE5"=>230, "\u1DE6"=>230, "\u1DE7"=>230,
- "\u1DE8"=>230, "\u1DE9"=>230, "\u1DEA"=>230, "\u1DEB"=>230, "\u1DEC"=>230, "\u1DED"=>230, "\u1DEE"=>230, "\u1DEF"=>230,
- "\u1DF0"=>230, "\u1DF1"=>230, "\u1DF2"=>230, "\u1DF3"=>230, "\u1DF4"=>230, "\u1DF5"=>230, "\u1DF6"=>232, "\u1DF7"=>228,
- "\u1DF8"=>228, "\u1DF9"=>220, "\u1DFB"=>230, "\u1DFC"=>233, "\u1DFD"=>220, "\u1DFE"=>230, "\u1DFF"=>220, "\u20D0"=>230,
- "\u20D1"=>230, "\u20D2"=>1, "\u20D3"=>1, "\u20D4"=>230, "\u20D5"=>230, "\u20D6"=>230, "\u20D7"=>230, "\u20D8"=>1,
- "\u20D9"=>1, "\u20DA"=>1, "\u20DB"=>230, "\u20DC"=>230, "\u20E1"=>230, "\u20E5"=>1, "\u20E6"=>1, "\u20E7"=>230,
- "\u20E8"=>220, "\u20E9"=>230, "\u20EA"=>1, "\u20EB"=>1, "\u20EC"=>220, "\u20ED"=>220, "\u20EE"=>220, "\u20EF"=>220,
- "\u20F0"=>230, "\u2CEF"=>230, "\u2CF0"=>230, "\u2CF1"=>230, "\u2D7F"=>9, "\u2DE0"=>230, "\u2DE1"=>230, "\u2DE2"=>230,
- "\u2DE3"=>230, "\u2DE4"=>230, "\u2DE5"=>230, "\u2DE6"=>230, "\u2DE7"=>230, "\u2DE8"=>230, "\u2DE9"=>230, "\u2DEA"=>230,
- "\u2DEB"=>230, "\u2DEC"=>230, "\u2DED"=>230, "\u2DEE"=>230, "\u2DEF"=>230, "\u2DF0"=>230, "\u2DF1"=>230, "\u2DF2"=>230,
- "\u2DF3"=>230, "\u2DF4"=>230, "\u2DF5"=>230, "\u2DF6"=>230, "\u2DF7"=>230, "\u2DF8"=>230, "\u2DF9"=>230, "\u2DFA"=>230,
- "\u2DFB"=>230, "\u2DFC"=>230, "\u2DFD"=>230, "\u2DFE"=>230, "\u2DFF"=>230, "\u302A"=>218, "\u302B"=>228, "\u302C"=>232,
- "\u302D"=>222, "\u302E"=>224, "\u302F"=>224, "\u3099"=>8, "\u309A"=>8, "\uA66F"=>230, "\uA674"=>230, "\uA675"=>230,
- "\uA676"=>230, "\uA677"=>230, "\uA678"=>230, "\uA679"=>230, "\uA67A"=>230, "\uA67B"=>230, "\uA67C"=>230, "\uA67D"=>230,
- "\uA69E"=>230, "\uA69F"=>230, "\uA6F0"=>230, "\uA6F1"=>230, "\uA806"=>9, "\uA8C4"=>9, "\uA8E0"=>230, "\uA8E1"=>230,
- "\uA8E2"=>230, "\uA8E3"=>230, "\uA8E4"=>230, "\uA8E5"=>230, "\uA8E6"=>230, "\uA8E7"=>230, "\uA8E8"=>230, "\uA8E9"=>230,
- "\uA8EA"=>230, "\uA8EB"=>230, "\uA8EC"=>230, "\uA8ED"=>230, "\uA8EE"=>230, "\uA8EF"=>230, "\uA8F0"=>230, "\uA8F1"=>230,
- "\uA92B"=>220, "\uA92C"=>220, "\uA92D"=>220, "\uA953"=>9, "\uA9B3"=>7, "\uA9C0"=>9, "\uAAB0"=>230, "\uAAB2"=>230,
- "\uAAB3"=>230, "\uAAB4"=>220, "\uAAB7"=>230, "\uAAB8"=>230, "\uAABE"=>230, "\uAABF"=>230, "\uAAC1"=>230, "\uAAF6"=>9,
- "\uABED"=>9, "\uFB1E"=>26, "\uFE20"=>230, "\uFE21"=>230, "\uFE22"=>230, "\uFE23"=>230, "\uFE24"=>230, "\uFE25"=>230,
- "\uFE26"=>230, "\uFE27"=>220, "\uFE28"=>220, "\uFE29"=>220, "\uFE2A"=>220, "\uFE2B"=>220, "\uFE2C"=>220, "\uFE2D"=>220,
- "\uFE2E"=>230, "\uFE2F"=>230, "\u{101FD}"=>220, "\u{102E0}"=>220, "\u{10376}"=>230, "\u{10377}"=>230, "\u{10378}"=>230, "\u{10379}"=>230,
- "\u{1037A}"=>230, "\u{10A0D}"=>220, "\u{10A0F}"=>230, "\u{10A38}"=>230, "\u{10A39}"=>1, "\u{10A3A}"=>220, "\u{10A3F}"=>9, "\u{10AE5}"=>230,
- "\u{10AE6}"=>220, "\u{11046}"=>9, "\u{1107F}"=>9, "\u{110B9}"=>9, "\u{110BA}"=>7, "\u{11100}"=>230, "\u{11101}"=>230, "\u{11102}"=>230,
- "\u{11133}"=>9, "\u{11134}"=>9, "\u{11173}"=>7, "\u{111C0}"=>9, "\u{111CA}"=>7, "\u{11235}"=>9, "\u{11236}"=>7, "\u{112E9}"=>7,
- "\u{112EA}"=>9, "\u{1133C}"=>7, "\u{1134D}"=>9, "\u{11366}"=>230, "\u{11367}"=>230, "\u{11368}"=>230, "\u{11369}"=>230, "\u{1136A}"=>230,
- "\u{1136B}"=>230, "\u{1136C}"=>230, "\u{11370}"=>230, "\u{11371}"=>230, "\u{11372}"=>230, "\u{11373}"=>230, "\u{11374}"=>230, "\u{11442}"=>9,
- "\u{11446}"=>7, "\u{114C2}"=>9, "\u{114C3}"=>7, "\u{115BF}"=>9, "\u{115C0}"=>7, "\u{1163F}"=>9, "\u{116B6}"=>9, "\u{116B7}"=>7,
- "\u{1172B}"=>9, "\u{11A34}"=>9, "\u{11A47}"=>9, "\u{11A99}"=>9, "\u{11C3F}"=>9, "\u{11D42}"=>7, "\u{11D44}"=>9, "\u{11D45}"=>9,
- "\u{16AF0}"=>1, "\u{16AF1}"=>1, "\u{16AF2}"=>1, "\u{16AF3}"=>1, "\u{16AF4}"=>1, "\u{16B30}"=>230, "\u{16B31}"=>230, "\u{16B32}"=>230,
- "\u{16B33}"=>230, "\u{16B34}"=>230, "\u{16B35}"=>230, "\u{16B36}"=>230, "\u{1BC9E}"=>1, "\u{1D165}"=>216, "\u{1D166}"=>216, "\u{1D167}"=>1,
- "\u{1D168}"=>1, "\u{1D169}"=>1, "\u{1D16D}"=>226, "\u{1D16E}"=>216, "\u{1D16F}"=>216, "\u{1D170}"=>216, "\u{1D171}"=>216, "\u{1D172}"=>216,
- "\u{1D17B}"=>220, "\u{1D17C}"=>220, "\u{1D17D}"=>220, "\u{1D17E}"=>220, "\u{1D17F}"=>220, "\u{1D180}"=>220, "\u{1D181}"=>220, "\u{1D182}"=>220,
- "\u{1D185}"=>230, "\u{1D186}"=>230, "\u{1D187}"=>230, "\u{1D188}"=>230, "\u{1D189}"=>230, "\u{1D18A}"=>220, "\u{1D18B}"=>220, "\u{1D1AA}"=>230,
- "\u{1D1AB}"=>230, "\u{1D1AC}"=>230, "\u{1D1AD}"=>230, "\u{1D242}"=>230, "\u{1D243}"=>230, "\u{1D244}"=>230, "\u{1E000}"=>230, "\u{1E001}"=>230,
- "\u{1E002}"=>230, "\u{1E003}"=>230, "\u{1E004}"=>230, "\u{1E005}"=>230, "\u{1E006}"=>230, "\u{1E008}"=>230, "\u{1E009}"=>230, "\u{1E00A}"=>230,
- "\u{1E00B}"=>230, "\u{1E00C}"=>230, "\u{1E00D}"=>230, "\u{1E00E}"=>230, "\u{1E00F}"=>230, "\u{1E010}"=>230, "\u{1E011}"=>230, "\u{1E012}"=>230,
- "\u{1E013}"=>230, "\u{1E014}"=>230, "\u{1E015}"=>230, "\u{1E016}"=>230, "\u{1E017}"=>230, "\u{1E018}"=>230, "\u{1E01B}"=>230, "\u{1E01C}"=>230,
- "\u{1E01D}"=>230, "\u{1E01E}"=>230, "\u{1E01F}"=>230, "\u{1E020}"=>230, "\u{1E021}"=>230, "\u{1E023}"=>230, "\u{1E024}"=>230, "\u{1E026}"=>230,
- "\u{1E027}"=>230, "\u{1E028}"=>230, "\u{1E029}"=>230, "\u{1E02A}"=>230, "\u{1E8D0}"=>220, "\u{1E8D1}"=>220, "\u{1E8D2}"=>220, "\u{1E8D3}"=>220,
- "\u{1E8D4}"=>220, "\u{1E8D5}"=>220, "\u{1E8D6}"=>220, "\u{1E944}"=>230, "\u{1E945}"=>230, "\u{1E946}"=>230, "\u{1E947}"=>230, "\u{1E948}"=>230,
- "\u{1E949}"=>230, "\u{1E94A}"=>7,
+ "\u0300"=>230,
+ "\u0301"=>230,
+ "\u0302"=>230,
+ "\u0303"=>230,
+ "\u0304"=>230,
+ "\u0305"=>230,
+ "\u0306"=>230,
+ "\u0307"=>230,
+ "\u0308"=>230,
+ "\u0309"=>230,
+ "\u030A"=>230,
+ "\u030B"=>230,
+ "\u030C"=>230,
+ "\u030D"=>230,
+ "\u030E"=>230,
+ "\u030F"=>230,
+ "\u0310"=>230,
+ "\u0311"=>230,
+ "\u0312"=>230,
+ "\u0313"=>230,
+ "\u0314"=>230,
+ "\u0315"=>232,
+ "\u0316"=>220,
+ "\u0317"=>220,
+ "\u0318"=>220,
+ "\u0319"=>220,
+ "\u031A"=>232,
+ "\u031B"=>216,
+ "\u031C"=>220,
+ "\u031D"=>220,
+ "\u031E"=>220,
+ "\u031F"=>220,
+ "\u0320"=>220,
+ "\u0321"=>202,
+ "\u0322"=>202,
+ "\u0323"=>220,
+ "\u0324"=>220,
+ "\u0325"=>220,
+ "\u0326"=>220,
+ "\u0327"=>202,
+ "\u0328"=>202,
+ "\u0329"=>220,
+ "\u032A"=>220,
+ "\u032B"=>220,
+ "\u032C"=>220,
+ "\u032D"=>220,
+ "\u032E"=>220,
+ "\u032F"=>220,
+ "\u0330"=>220,
+ "\u0331"=>220,
+ "\u0332"=>220,
+ "\u0333"=>220,
+ "\u0334"=>1,
+ "\u0335"=>1,
+ "\u0336"=>1,
+ "\u0337"=>1,
+ "\u0338"=>1,
+ "\u0339"=>220,
+ "\u033A"=>220,
+ "\u033B"=>220,
+ "\u033C"=>220,
+ "\u033D"=>230,
+ "\u033E"=>230,
+ "\u033F"=>230,
+ "\u0340"=>230,
+ "\u0341"=>230,
+ "\u0342"=>230,
+ "\u0343"=>230,
+ "\u0344"=>230,
+ "\u0345"=>240,
+ "\u0346"=>230,
+ "\u0347"=>220,
+ "\u0348"=>220,
+ "\u0349"=>220,
+ "\u034A"=>230,
+ "\u034B"=>230,
+ "\u034C"=>230,
+ "\u034D"=>220,
+ "\u034E"=>220,
+ "\u0350"=>230,
+ "\u0351"=>230,
+ "\u0352"=>230,
+ "\u0353"=>220,
+ "\u0354"=>220,
+ "\u0355"=>220,
+ "\u0356"=>220,
+ "\u0357"=>230,
+ "\u0358"=>232,
+ "\u0359"=>220,
+ "\u035A"=>220,
+ "\u035B"=>230,
+ "\u035C"=>233,
+ "\u035D"=>234,
+ "\u035E"=>234,
+ "\u035F"=>233,
+ "\u0360"=>234,
+ "\u0361"=>234,
+ "\u0362"=>233,
+ "\u0363"=>230,
+ "\u0364"=>230,
+ "\u0365"=>230,
+ "\u0366"=>230,
+ "\u0367"=>230,
+ "\u0368"=>230,
+ "\u0369"=>230,
+ "\u036A"=>230,
+ "\u036B"=>230,
+ "\u036C"=>230,
+ "\u036D"=>230,
+ "\u036E"=>230,
+ "\u036F"=>230,
+ "\u0483"=>230,
+ "\u0484"=>230,
+ "\u0485"=>230,
+ "\u0486"=>230,
+ "\u0487"=>230,
+ "\u0591"=>220,
+ "\u0592"=>230,
+ "\u0593"=>230,
+ "\u0594"=>230,
+ "\u0595"=>230,
+ "\u0596"=>220,
+ "\u0597"=>230,
+ "\u0598"=>230,
+ "\u0599"=>230,
+ "\u059A"=>222,
+ "\u059B"=>220,
+ "\u059C"=>230,
+ "\u059D"=>230,
+ "\u059E"=>230,
+ "\u059F"=>230,
+ "\u05A0"=>230,
+ "\u05A1"=>230,
+ "\u05A2"=>220,
+ "\u05A3"=>220,
+ "\u05A4"=>220,
+ "\u05A5"=>220,
+ "\u05A6"=>220,
+ "\u05A7"=>220,
+ "\u05A8"=>230,
+ "\u05A9"=>230,
+ "\u05AA"=>220,
+ "\u05AB"=>230,
+ "\u05AC"=>230,
+ "\u05AD"=>222,
+ "\u05AE"=>228,
+ "\u05AF"=>230,
+ "\u05B0"=>10,
+ "\u05B1"=>11,
+ "\u05B2"=>12,
+ "\u05B3"=>13,
+ "\u05B4"=>14,
+ "\u05B5"=>15,
+ "\u05B6"=>16,
+ "\u05B7"=>17,
+ "\u05B8"=>18,
+ "\u05B9"=>19,
+ "\u05BA"=>19,
+ "\u05BB"=>20,
+ "\u05BC"=>21,
+ "\u05BD"=>22,
+ "\u05BF"=>23,
+ "\u05C1"=>24,
+ "\u05C2"=>25,
+ "\u05C4"=>230,
+ "\u05C5"=>220,
+ "\u05C7"=>18,
+ "\u0610"=>230,
+ "\u0611"=>230,
+ "\u0612"=>230,
+ "\u0613"=>230,
+ "\u0614"=>230,
+ "\u0615"=>230,
+ "\u0616"=>230,
+ "\u0617"=>230,
+ "\u0618"=>30,
+ "\u0619"=>31,
+ "\u061A"=>32,
+ "\u064B"=>27,
+ "\u064C"=>28,
+ "\u064D"=>29,
+ "\u064E"=>30,
+ "\u064F"=>31,
+ "\u0650"=>32,
+ "\u0651"=>33,
+ "\u0652"=>34,
+ "\u0653"=>230,
+ "\u0654"=>230,
+ "\u0655"=>220,
+ "\u0656"=>220,
+ "\u0657"=>230,
+ "\u0658"=>230,
+ "\u0659"=>230,
+ "\u065A"=>230,
+ "\u065B"=>230,
+ "\u065C"=>220,
+ "\u065D"=>230,
+ "\u065E"=>230,
+ "\u065F"=>220,
+ "\u0670"=>35,
+ "\u06D6"=>230,
+ "\u06D7"=>230,
+ "\u06D8"=>230,
+ "\u06D9"=>230,
+ "\u06DA"=>230,
+ "\u06DB"=>230,
+ "\u06DC"=>230,
+ "\u06DF"=>230,
+ "\u06E0"=>230,
+ "\u06E1"=>230,
+ "\u06E2"=>230,
+ "\u06E3"=>220,
+ "\u06E4"=>230,
+ "\u06E7"=>230,
+ "\u06E8"=>230,
+ "\u06EA"=>220,
+ "\u06EB"=>230,
+ "\u06EC"=>230,
+ "\u06ED"=>220,
+ "\u0711"=>36,
+ "\u0730"=>230,
+ "\u0731"=>220,
+ "\u0732"=>230,
+ "\u0733"=>230,
+ "\u0734"=>220,
+ "\u0735"=>230,
+ "\u0736"=>230,
+ "\u0737"=>220,
+ "\u0738"=>220,
+ "\u0739"=>220,
+ "\u073A"=>230,
+ "\u073B"=>220,
+ "\u073C"=>220,
+ "\u073D"=>230,
+ "\u073E"=>220,
+ "\u073F"=>230,
+ "\u0740"=>230,
+ "\u0741"=>230,
+ "\u0742"=>220,
+ "\u0743"=>230,
+ "\u0744"=>220,
+ "\u0745"=>230,
+ "\u0746"=>220,
+ "\u0747"=>230,
+ "\u0748"=>220,
+ "\u0749"=>230,
+ "\u074A"=>230,
+ "\u07EB"=>230,
+ "\u07EC"=>230,
+ "\u07ED"=>230,
+ "\u07EE"=>230,
+ "\u07EF"=>230,
+ "\u07F0"=>230,
+ "\u07F1"=>230,
+ "\u07F2"=>220,
+ "\u07F3"=>230,
+ "\u07FD"=>220,
+ "\u0816"=>230,
+ "\u0817"=>230,
+ "\u0818"=>230,
+ "\u0819"=>230,
+ "\u081B"=>230,
+ "\u081C"=>230,
+ "\u081D"=>230,
+ "\u081E"=>230,
+ "\u081F"=>230,
+ "\u0820"=>230,
+ "\u0821"=>230,
+ "\u0822"=>230,
+ "\u0823"=>230,
+ "\u0825"=>230,
+ "\u0826"=>230,
+ "\u0827"=>230,
+ "\u0829"=>230,
+ "\u082A"=>230,
+ "\u082B"=>230,
+ "\u082C"=>230,
+ "\u082D"=>230,
+ "\u0859"=>220,
+ "\u085A"=>220,
+ "\u085B"=>220,
+ "\u08D3"=>220,
+ "\u08D4"=>230,
+ "\u08D5"=>230,
+ "\u08D6"=>230,
+ "\u08D7"=>230,
+ "\u08D8"=>230,
+ "\u08D9"=>230,
+ "\u08DA"=>230,
+ "\u08DB"=>230,
+ "\u08DC"=>230,
+ "\u08DD"=>230,
+ "\u08DE"=>230,
+ "\u08DF"=>230,
+ "\u08E0"=>230,
+ "\u08E1"=>230,
+ "\u08E3"=>220,
+ "\u08E4"=>230,
+ "\u08E5"=>230,
+ "\u08E6"=>220,
+ "\u08E7"=>230,
+ "\u08E8"=>230,
+ "\u08E9"=>220,
+ "\u08EA"=>230,
+ "\u08EB"=>230,
+ "\u08EC"=>230,
+ "\u08ED"=>220,
+ "\u08EE"=>220,
+ "\u08EF"=>220,
+ "\u08F0"=>27,
+ "\u08F1"=>28,
+ "\u08F2"=>29,
+ "\u08F3"=>230,
+ "\u08F4"=>230,
+ "\u08F5"=>230,
+ "\u08F6"=>220,
+ "\u08F7"=>230,
+ "\u08F8"=>230,
+ "\u08F9"=>220,
+ "\u08FA"=>220,
+ "\u08FB"=>230,
+ "\u08FC"=>230,
+ "\u08FD"=>230,
+ "\u08FE"=>230,
+ "\u08FF"=>230,
+ "\u093C"=>7,
+ "\u094D"=>9,
+ "\u0951"=>230,
+ "\u0952"=>220,
+ "\u0953"=>230,
+ "\u0954"=>230,
+ "\u09BC"=>7,
+ "\u09CD"=>9,
+ "\u09FE"=>230,
+ "\u0A3C"=>7,
+ "\u0A4D"=>9,
+ "\u0ABC"=>7,
+ "\u0ACD"=>9,
+ "\u0B3C"=>7,
+ "\u0B4D"=>9,
+ "\u0BCD"=>9,
+ "\u0C4D"=>9,
+ "\u0C55"=>84,
+ "\u0C56"=>91,
+ "\u0CBC"=>7,
+ "\u0CCD"=>9,
+ "\u0D3B"=>9,
+ "\u0D3C"=>9,
+ "\u0D4D"=>9,
+ "\u0DCA"=>9,
+ "\u0E38"=>103,
+ "\u0E39"=>103,
+ "\u0E3A"=>9,
+ "\u0E48"=>107,
+ "\u0E49"=>107,
+ "\u0E4A"=>107,
+ "\u0E4B"=>107,
+ "\u0EB8"=>118,
+ "\u0EB9"=>118,
+ "\u0EBA"=>9,
+ "\u0EC8"=>122,
+ "\u0EC9"=>122,
+ "\u0ECA"=>122,
+ "\u0ECB"=>122,
+ "\u0F18"=>220,
+ "\u0F19"=>220,
+ "\u0F35"=>220,
+ "\u0F37"=>220,
+ "\u0F39"=>216,
+ "\u0F71"=>129,
+ "\u0F72"=>130,
+ "\u0F74"=>132,
+ "\u0F7A"=>130,
+ "\u0F7B"=>130,
+ "\u0F7C"=>130,
+ "\u0F7D"=>130,
+ "\u0F80"=>130,
+ "\u0F82"=>230,
+ "\u0F83"=>230,
+ "\u0F84"=>9,
+ "\u0F86"=>230,
+ "\u0F87"=>230,
+ "\u0FC6"=>220,
+ "\u1037"=>7,
+ "\u1039"=>9,
+ "\u103A"=>9,
+ "\u108D"=>220,
+ "\u135D"=>230,
+ "\u135E"=>230,
+ "\u135F"=>230,
+ "\u1714"=>9,
+ "\u1734"=>9,
+ "\u17D2"=>9,
+ "\u17DD"=>230,
+ "\u18A9"=>228,
+ "\u1939"=>222,
+ "\u193A"=>230,
+ "\u193B"=>220,
+ "\u1A17"=>230,
+ "\u1A18"=>220,
+ "\u1A60"=>9,
+ "\u1A75"=>230,
+ "\u1A76"=>230,
+ "\u1A77"=>230,
+ "\u1A78"=>230,
+ "\u1A79"=>230,
+ "\u1A7A"=>230,
+ "\u1A7B"=>230,
+ "\u1A7C"=>230,
+ "\u1A7F"=>220,
+ "\u1AB0"=>230,
+ "\u1AB1"=>230,
+ "\u1AB2"=>230,
+ "\u1AB3"=>230,
+ "\u1AB4"=>230,
+ "\u1AB5"=>220,
+ "\u1AB6"=>220,
+ "\u1AB7"=>220,
+ "\u1AB8"=>220,
+ "\u1AB9"=>220,
+ "\u1ABA"=>220,
+ "\u1ABB"=>230,
+ "\u1ABC"=>230,
+ "\u1ABD"=>220,
+ "\u1B34"=>7,
+ "\u1B44"=>9,
+ "\u1B6B"=>230,
+ "\u1B6C"=>220,
+ "\u1B6D"=>230,
+ "\u1B6E"=>230,
+ "\u1B6F"=>230,
+ "\u1B70"=>230,
+ "\u1B71"=>230,
+ "\u1B72"=>230,
+ "\u1B73"=>230,
+ "\u1BAA"=>9,
+ "\u1BAB"=>9,
+ "\u1BE6"=>7,
+ "\u1BF2"=>9,
+ "\u1BF3"=>9,
+ "\u1C37"=>7,
+ "\u1CD0"=>230,
+ "\u1CD1"=>230,
+ "\u1CD2"=>230,
+ "\u1CD4"=>1,
+ "\u1CD5"=>220,
+ "\u1CD6"=>220,
+ "\u1CD7"=>220,
+ "\u1CD8"=>220,
+ "\u1CD9"=>220,
+ "\u1CDA"=>230,
+ "\u1CDB"=>230,
+ "\u1CDC"=>220,
+ "\u1CDD"=>220,
+ "\u1CDE"=>220,
+ "\u1CDF"=>220,
+ "\u1CE0"=>230,
+ "\u1CE2"=>1,
+ "\u1CE3"=>1,
+ "\u1CE4"=>1,
+ "\u1CE5"=>1,
+ "\u1CE6"=>1,
+ "\u1CE7"=>1,
+ "\u1CE8"=>1,
+ "\u1CED"=>220,
+ "\u1CF4"=>230,
+ "\u1CF8"=>230,
+ "\u1CF9"=>230,
+ "\u1DC0"=>230,
+ "\u1DC1"=>230,
+ "\u1DC2"=>220,
+ "\u1DC3"=>230,
+ "\u1DC4"=>230,
+ "\u1DC5"=>230,
+ "\u1DC6"=>230,
+ "\u1DC7"=>230,
+ "\u1DC8"=>230,
+ "\u1DC9"=>230,
+ "\u1DCA"=>220,
+ "\u1DCB"=>230,
+ "\u1DCC"=>230,
+ "\u1DCD"=>234,
+ "\u1DCE"=>214,
+ "\u1DCF"=>220,
+ "\u1DD0"=>202,
+ "\u1DD1"=>230,
+ "\u1DD2"=>230,
+ "\u1DD3"=>230,
+ "\u1DD4"=>230,
+ "\u1DD5"=>230,
+ "\u1DD6"=>230,
+ "\u1DD7"=>230,
+ "\u1DD8"=>230,
+ "\u1DD9"=>230,
+ "\u1DDA"=>230,
+ "\u1DDB"=>230,
+ "\u1DDC"=>230,
+ "\u1DDD"=>230,
+ "\u1DDE"=>230,
+ "\u1DDF"=>230,
+ "\u1DE0"=>230,
+ "\u1DE1"=>230,
+ "\u1DE2"=>230,
+ "\u1DE3"=>230,
+ "\u1DE4"=>230,
+ "\u1DE5"=>230,
+ "\u1DE6"=>230,
+ "\u1DE7"=>230,
+ "\u1DE8"=>230,
+ "\u1DE9"=>230,
+ "\u1DEA"=>230,
+ "\u1DEB"=>230,
+ "\u1DEC"=>230,
+ "\u1DED"=>230,
+ "\u1DEE"=>230,
+ "\u1DEF"=>230,
+ "\u1DF0"=>230,
+ "\u1DF1"=>230,
+ "\u1DF2"=>230,
+ "\u1DF3"=>230,
+ "\u1DF4"=>230,
+ "\u1DF5"=>230,
+ "\u1DF6"=>232,
+ "\u1DF7"=>228,
+ "\u1DF8"=>228,
+ "\u1DF9"=>220,
+ "\u1DFB"=>230,
+ "\u1DFC"=>233,
+ "\u1DFD"=>220,
+ "\u1DFE"=>230,
+ "\u1DFF"=>220,
+ "\u20D0"=>230,
+ "\u20D1"=>230,
+ "\u20D2"=>1,
+ "\u20D3"=>1,
+ "\u20D4"=>230,
+ "\u20D5"=>230,
+ "\u20D6"=>230,
+ "\u20D7"=>230,
+ "\u20D8"=>1,
+ "\u20D9"=>1,
+ "\u20DA"=>1,
+ "\u20DB"=>230,
+ "\u20DC"=>230,
+ "\u20E1"=>230,
+ "\u20E5"=>1,
+ "\u20E6"=>1,
+ "\u20E7"=>230,
+ "\u20E8"=>220,
+ "\u20E9"=>230,
+ "\u20EA"=>1,
+ "\u20EB"=>1,
+ "\u20EC"=>220,
+ "\u20ED"=>220,
+ "\u20EE"=>220,
+ "\u20EF"=>220,
+ "\u20F0"=>230,
+ "\u2CEF"=>230,
+ "\u2CF0"=>230,
+ "\u2CF1"=>230,
+ "\u2D7F"=>9,
+ "\u2DE0"=>230,
+ "\u2DE1"=>230,
+ "\u2DE2"=>230,
+ "\u2DE3"=>230,
+ "\u2DE4"=>230,
+ "\u2DE5"=>230,
+ "\u2DE6"=>230,
+ "\u2DE7"=>230,
+ "\u2DE8"=>230,
+ "\u2DE9"=>230,
+ "\u2DEA"=>230,
+ "\u2DEB"=>230,
+ "\u2DEC"=>230,
+ "\u2DED"=>230,
+ "\u2DEE"=>230,
+ "\u2DEF"=>230,
+ "\u2DF0"=>230,
+ "\u2DF1"=>230,
+ "\u2DF2"=>230,
+ "\u2DF3"=>230,
+ "\u2DF4"=>230,
+ "\u2DF5"=>230,
+ "\u2DF6"=>230,
+ "\u2DF7"=>230,
+ "\u2DF8"=>230,
+ "\u2DF9"=>230,
+ "\u2DFA"=>230,
+ "\u2DFB"=>230,
+ "\u2DFC"=>230,
+ "\u2DFD"=>230,
+ "\u2DFE"=>230,
+ "\u2DFF"=>230,
+ "\u302A"=>218,
+ "\u302B"=>228,
+ "\u302C"=>232,
+ "\u302D"=>222,
+ "\u302E"=>224,
+ "\u302F"=>224,
+ "\u3099"=>8,
+ "\u309A"=>8,
+ "\uA66F"=>230,
+ "\uA674"=>230,
+ "\uA675"=>230,
+ "\uA676"=>230,
+ "\uA677"=>230,
+ "\uA678"=>230,
+ "\uA679"=>230,
+ "\uA67A"=>230,
+ "\uA67B"=>230,
+ "\uA67C"=>230,
+ "\uA67D"=>230,
+ "\uA69E"=>230,
+ "\uA69F"=>230,
+ "\uA6F0"=>230,
+ "\uA6F1"=>230,
+ "\uA806"=>9,
+ "\uA8C4"=>9,
+ "\uA8E0"=>230,
+ "\uA8E1"=>230,
+ "\uA8E2"=>230,
+ "\uA8E3"=>230,
+ "\uA8E4"=>230,
+ "\uA8E5"=>230,
+ "\uA8E6"=>230,
+ "\uA8E7"=>230,
+ "\uA8E8"=>230,
+ "\uA8E9"=>230,
+ "\uA8EA"=>230,
+ "\uA8EB"=>230,
+ "\uA8EC"=>230,
+ "\uA8ED"=>230,
+ "\uA8EE"=>230,
+ "\uA8EF"=>230,
+ "\uA8F0"=>230,
+ "\uA8F1"=>230,
+ "\uA92B"=>220,
+ "\uA92C"=>220,
+ "\uA92D"=>220,
+ "\uA953"=>9,
+ "\uA9B3"=>7,
+ "\uA9C0"=>9,
+ "\uAAB0"=>230,
+ "\uAAB2"=>230,
+ "\uAAB3"=>230,
+ "\uAAB4"=>220,
+ "\uAAB7"=>230,
+ "\uAAB8"=>230,
+ "\uAABE"=>230,
+ "\uAABF"=>230,
+ "\uAAC1"=>230,
+ "\uAAF6"=>9,
+ "\uABED"=>9,
+ "\uFB1E"=>26,
+ "\uFE20"=>230,
+ "\uFE21"=>230,
+ "\uFE22"=>230,
+ "\uFE23"=>230,
+ "\uFE24"=>230,
+ "\uFE25"=>230,
+ "\uFE26"=>230,
+ "\uFE27"=>220,
+ "\uFE28"=>220,
+ "\uFE29"=>220,
+ "\uFE2A"=>220,
+ "\uFE2B"=>220,
+ "\uFE2C"=>220,
+ "\uFE2D"=>220,
+ "\uFE2E"=>230,
+ "\uFE2F"=>230,
+ "\u{101FD}"=>220,
+ "\u{102E0}"=>220,
+ "\u{10376}"=>230,
+ "\u{10377}"=>230,
+ "\u{10378}"=>230,
+ "\u{10379}"=>230,
+ "\u{1037A}"=>230,
+ "\u{10A0D}"=>220,
+ "\u{10A0F}"=>230,
+ "\u{10A38}"=>230,
+ "\u{10A39}"=>1,
+ "\u{10A3A}"=>220,
+ "\u{10A3F}"=>9,
+ "\u{10AE5}"=>230,
+ "\u{10AE6}"=>220,
+ "\u{10D24}"=>230,
+ "\u{10D25}"=>230,
+ "\u{10D26}"=>230,
+ "\u{10D27}"=>230,
+ "\u{10F46}"=>220,
+ "\u{10F47}"=>220,
+ "\u{10F48}"=>230,
+ "\u{10F49}"=>230,
+ "\u{10F4A}"=>230,
+ "\u{10F4B}"=>220,
+ "\u{10F4C}"=>230,
+ "\u{10F4D}"=>220,
+ "\u{10F4E}"=>220,
+ "\u{10F4F}"=>220,
+ "\u{10F50}"=>220,
+ "\u{11046}"=>9,
+ "\u{1107F}"=>9,
+ "\u{110B9}"=>9,
+ "\u{110BA}"=>7,
+ "\u{11100}"=>230,
+ "\u{11101}"=>230,
+ "\u{11102}"=>230,
+ "\u{11133}"=>9,
+ "\u{11134}"=>9,
+ "\u{11173}"=>7,
+ "\u{111C0}"=>9,
+ "\u{111CA}"=>7,
+ "\u{11235}"=>9,
+ "\u{11236}"=>7,
+ "\u{112E9}"=>7,
+ "\u{112EA}"=>9,
+ "\u{1133B}"=>7,
+ "\u{1133C}"=>7,
+ "\u{1134D}"=>9,
+ "\u{11366}"=>230,
+ "\u{11367}"=>230,
+ "\u{11368}"=>230,
+ "\u{11369}"=>230,
+ "\u{1136A}"=>230,
+ "\u{1136B}"=>230,
+ "\u{1136C}"=>230,
+ "\u{11370}"=>230,
+ "\u{11371}"=>230,
+ "\u{11372}"=>230,
+ "\u{11373}"=>230,
+ "\u{11374}"=>230,
+ "\u{11442}"=>9,
+ "\u{11446}"=>7,
+ "\u{1145E}"=>230,
+ "\u{114C2}"=>9,
+ "\u{114C3}"=>7,
+ "\u{115BF}"=>9,
+ "\u{115C0}"=>7,
+ "\u{1163F}"=>9,
+ "\u{116B6}"=>9,
+ "\u{116B7}"=>7,
+ "\u{1172B}"=>9,
+ "\u{11839}"=>9,
+ "\u{1183A}"=>7,
+ "\u{119E0}"=>9,
+ "\u{11A34}"=>9,
+ "\u{11A47}"=>9,
+ "\u{11A99}"=>9,
+ "\u{11C3F}"=>9,
+ "\u{11D42}"=>7,
+ "\u{11D44}"=>9,
+ "\u{11D45}"=>9,
+ "\u{11D97}"=>9,
+ "\u{16AF0}"=>1,
+ "\u{16AF1}"=>1,
+ "\u{16AF2}"=>1,
+ "\u{16AF3}"=>1,
+ "\u{16AF4}"=>1,
+ "\u{16B30}"=>230,
+ "\u{16B31}"=>230,
+ "\u{16B32}"=>230,
+ "\u{16B33}"=>230,
+ "\u{16B34}"=>230,
+ "\u{16B35}"=>230,
+ "\u{16B36}"=>230,
+ "\u{1BC9E}"=>1,
+ "\u{1D165}"=>216,
+ "\u{1D166}"=>216,
+ "\u{1D167}"=>1,
+ "\u{1D168}"=>1,
+ "\u{1D169}"=>1,
+ "\u{1D16D}"=>226,
+ "\u{1D16E}"=>216,
+ "\u{1D16F}"=>216,
+ "\u{1D170}"=>216,
+ "\u{1D171}"=>216,
+ "\u{1D172}"=>216,
+ "\u{1D17B}"=>220,
+ "\u{1D17C}"=>220,
+ "\u{1D17D}"=>220,
+ "\u{1D17E}"=>220,
+ "\u{1D17F}"=>220,
+ "\u{1D180}"=>220,
+ "\u{1D181}"=>220,
+ "\u{1D182}"=>220,
+ "\u{1D185}"=>230,
+ "\u{1D186}"=>230,
+ "\u{1D187}"=>230,
+ "\u{1D188}"=>230,
+ "\u{1D189}"=>230,
+ "\u{1D18A}"=>220,
+ "\u{1D18B}"=>220,
+ "\u{1D1AA}"=>230,
+ "\u{1D1AB}"=>230,
+ "\u{1D1AC}"=>230,
+ "\u{1D1AD}"=>230,
+ "\u{1D242}"=>230,
+ "\u{1D243}"=>230,
+ "\u{1D244}"=>230,
+ "\u{1E000}"=>230,
+ "\u{1E001}"=>230,
+ "\u{1E002}"=>230,
+ "\u{1E003}"=>230,
+ "\u{1E004}"=>230,
+ "\u{1E005}"=>230,
+ "\u{1E006}"=>230,
+ "\u{1E008}"=>230,
+ "\u{1E009}"=>230,
+ "\u{1E00A}"=>230,
+ "\u{1E00B}"=>230,
+ "\u{1E00C}"=>230,
+ "\u{1E00D}"=>230,
+ "\u{1E00E}"=>230,
+ "\u{1E00F}"=>230,
+ "\u{1E010}"=>230,
+ "\u{1E011}"=>230,
+ "\u{1E012}"=>230,
+ "\u{1E013}"=>230,
+ "\u{1E014}"=>230,
+ "\u{1E015}"=>230,
+ "\u{1E016}"=>230,
+ "\u{1E017}"=>230,
+ "\u{1E018}"=>230,
+ "\u{1E01B}"=>230,
+ "\u{1E01C}"=>230,
+ "\u{1E01D}"=>230,
+ "\u{1E01E}"=>230,
+ "\u{1E01F}"=>230,
+ "\u{1E020}"=>230,
+ "\u{1E021}"=>230,
+ "\u{1E023}"=>230,
+ "\u{1E024}"=>230,
+ "\u{1E026}"=>230,
+ "\u{1E027}"=>230,
+ "\u{1E028}"=>230,
+ "\u{1E029}"=>230,
+ "\u{1E02A}"=>230,
+ "\u{1E130}"=>230,
+ "\u{1E131}"=>230,
+ "\u{1E132}"=>230,
+ "\u{1E133}"=>230,
+ "\u{1E134}"=>230,
+ "\u{1E135}"=>230,
+ "\u{1E136}"=>230,
+ "\u{1E2EC}"=>230,
+ "\u{1E2ED}"=>230,
+ "\u{1E2EE}"=>230,
+ "\u{1E2EF}"=>230,
+ "\u{1E8D0}"=>220,
+ "\u{1E8D1}"=>220,
+ "\u{1E8D2}"=>220,
+ "\u{1E8D3}"=>220,
+ "\u{1E8D4}"=>220,
+ "\u{1E8D5}"=>220,
+ "\u{1E8D6}"=>220,
+ "\u{1E944}"=>230,
+ "\u{1E945}"=>230,
+ "\u{1E946}"=>230,
+ "\u{1E947}"=>230,
+ "\u{1E948}"=>230,
+ "\u{1E949}"=>230,
+ "\u{1E94A}"=>7,
}
class_table.default = 0
CLASS_TABLE = class_table.freeze
DECOMPOSITION_TABLE = {
- "\u00C0"=>"A\u0300", "\u00C1"=>"A\u0301", "\u00C2"=>"A\u0302", "\u00C3"=>"A\u0303", "\u00C4"=>"A\u0308", "\u00C5"=>"A\u030A", "\u00C7"=>"C\u0327", "\u00C8"=>"E\u0300",
- "\u00C9"=>"E\u0301", "\u00CA"=>"E\u0302", "\u00CB"=>"E\u0308", "\u00CC"=>"I\u0300", "\u00CD"=>"I\u0301", "\u00CE"=>"I\u0302", "\u00CF"=>"I\u0308", "\u00D1"=>"N\u0303",
- "\u00D2"=>"O\u0300", "\u00D3"=>"O\u0301", "\u00D4"=>"O\u0302", "\u00D5"=>"O\u0303", "\u00D6"=>"O\u0308", "\u00D9"=>"U\u0300", "\u00DA"=>"U\u0301", "\u00DB"=>"U\u0302",
- "\u00DC"=>"U\u0308", "\u00DD"=>"Y\u0301", "\u00E0"=>"a\u0300", "\u00E1"=>"a\u0301", "\u00E2"=>"a\u0302", "\u00E3"=>"a\u0303", "\u00E4"=>"a\u0308", "\u00E5"=>"a\u030A",
- "\u00E7"=>"c\u0327", "\u00E8"=>"e\u0300", "\u00E9"=>"e\u0301", "\u00EA"=>"e\u0302", "\u00EB"=>"e\u0308", "\u00EC"=>"i\u0300", "\u00ED"=>"i\u0301", "\u00EE"=>"i\u0302",
- "\u00EF"=>"i\u0308", "\u00F1"=>"n\u0303", "\u00F2"=>"o\u0300", "\u00F3"=>"o\u0301", "\u00F4"=>"o\u0302", "\u00F5"=>"o\u0303", "\u00F6"=>"o\u0308", "\u00F9"=>"u\u0300",
- "\u00FA"=>"u\u0301", "\u00FB"=>"u\u0302", "\u00FC"=>"u\u0308", "\u00FD"=>"y\u0301", "\u00FF"=>"y\u0308", "\u0100"=>"A\u0304", "\u0101"=>"a\u0304", "\u0102"=>"A\u0306",
- "\u0103"=>"a\u0306", "\u0104"=>"A\u0328", "\u0105"=>"a\u0328", "\u0106"=>"C\u0301", "\u0107"=>"c\u0301", "\u0108"=>"C\u0302", "\u0109"=>"c\u0302", "\u010A"=>"C\u0307",
- "\u010B"=>"c\u0307", "\u010C"=>"C\u030C", "\u010D"=>"c\u030C", "\u010E"=>"D\u030C", "\u010F"=>"d\u030C", "\u0112"=>"E\u0304", "\u0113"=>"e\u0304", "\u0114"=>"E\u0306",
- "\u0115"=>"e\u0306", "\u0116"=>"E\u0307", "\u0117"=>"e\u0307", "\u0118"=>"E\u0328", "\u0119"=>"e\u0328", "\u011A"=>"E\u030C", "\u011B"=>"e\u030C", "\u011C"=>"G\u0302",
- "\u011D"=>"g\u0302", "\u011E"=>"G\u0306", "\u011F"=>"g\u0306", "\u0120"=>"G\u0307", "\u0121"=>"g\u0307", "\u0122"=>"G\u0327", "\u0123"=>"g\u0327", "\u0124"=>"H\u0302",
- "\u0125"=>"h\u0302", "\u0128"=>"I\u0303", "\u0129"=>"i\u0303", "\u012A"=>"I\u0304", "\u012B"=>"i\u0304", "\u012C"=>"I\u0306", "\u012D"=>"i\u0306", "\u012E"=>"I\u0328",
- "\u012F"=>"i\u0328", "\u0130"=>"I\u0307", "\u0134"=>"J\u0302", "\u0135"=>"j\u0302", "\u0136"=>"K\u0327", "\u0137"=>"k\u0327", "\u0139"=>"L\u0301", "\u013A"=>"l\u0301",
- "\u013B"=>"L\u0327", "\u013C"=>"l\u0327", "\u013D"=>"L\u030C", "\u013E"=>"l\u030C", "\u0143"=>"N\u0301", "\u0144"=>"n\u0301", "\u0145"=>"N\u0327", "\u0146"=>"n\u0327",
- "\u0147"=>"N\u030C", "\u0148"=>"n\u030C", "\u014C"=>"O\u0304", "\u014D"=>"o\u0304", "\u014E"=>"O\u0306", "\u014F"=>"o\u0306", "\u0150"=>"O\u030B", "\u0151"=>"o\u030B",
- "\u0154"=>"R\u0301", "\u0155"=>"r\u0301", "\u0156"=>"R\u0327", "\u0157"=>"r\u0327", "\u0158"=>"R\u030C", "\u0159"=>"r\u030C", "\u015A"=>"S\u0301", "\u015B"=>"s\u0301",
- "\u015C"=>"S\u0302", "\u015D"=>"s\u0302", "\u015E"=>"S\u0327", "\u015F"=>"s\u0327", "\u0160"=>"S\u030C", "\u0161"=>"s\u030C", "\u0162"=>"T\u0327", "\u0163"=>"t\u0327",
- "\u0164"=>"T\u030C", "\u0165"=>"t\u030C", "\u0168"=>"U\u0303", "\u0169"=>"u\u0303", "\u016A"=>"U\u0304", "\u016B"=>"u\u0304", "\u016C"=>"U\u0306", "\u016D"=>"u\u0306",
- "\u016E"=>"U\u030A", "\u016F"=>"u\u030A", "\u0170"=>"U\u030B", "\u0171"=>"u\u030B", "\u0172"=>"U\u0328", "\u0173"=>"u\u0328", "\u0174"=>"W\u0302", "\u0175"=>"w\u0302",
- "\u0176"=>"Y\u0302", "\u0177"=>"y\u0302", "\u0178"=>"Y\u0308", "\u0179"=>"Z\u0301", "\u017A"=>"z\u0301", "\u017B"=>"Z\u0307", "\u017C"=>"z\u0307", "\u017D"=>"Z\u030C",
- "\u017E"=>"z\u030C", "\u01A0"=>"O\u031B", "\u01A1"=>"o\u031B", "\u01AF"=>"U\u031B", "\u01B0"=>"u\u031B", "\u01CD"=>"A\u030C", "\u01CE"=>"a\u030C", "\u01CF"=>"I\u030C",
- "\u01D0"=>"i\u030C", "\u01D1"=>"O\u030C", "\u01D2"=>"o\u030C", "\u01D3"=>"U\u030C", "\u01D4"=>"u\u030C", "\u01D5"=>"U\u0308\u0304", "\u01D6"=>"u\u0308\u0304", "\u01D7"=>"U\u0308\u0301",
- "\u01D8"=>"u\u0308\u0301", "\u01D9"=>"U\u0308\u030C", "\u01DA"=>"u\u0308\u030C", "\u01DB"=>"U\u0308\u0300", "\u01DC"=>"u\u0308\u0300", "\u01DE"=>"A\u0308\u0304", "\u01DF"=>"a\u0308\u0304", "\u01E0"=>"A\u0307\u0304",
- "\u01E1"=>"a\u0307\u0304", "\u01E2"=>"\u00C6\u0304", "\u01E3"=>"\u00E6\u0304", "\u01E6"=>"G\u030C", "\u01E7"=>"g\u030C", "\u01E8"=>"K\u030C", "\u01E9"=>"k\u030C", "\u01EA"=>"O\u0328",
- "\u01EB"=>"o\u0328", "\u01EC"=>"O\u0328\u0304", "\u01ED"=>"o\u0328\u0304", "\u01EE"=>"\u01B7\u030C", "\u01EF"=>"\u0292\u030C", "\u01F0"=>"j\u030C", "\u01F4"=>"G\u0301", "\u01F5"=>"g\u0301",
- "\u01F8"=>"N\u0300", "\u01F9"=>"n\u0300", "\u01FA"=>"A\u030A\u0301", "\u01FB"=>"a\u030A\u0301", "\u01FC"=>"\u00C6\u0301", "\u01FD"=>"\u00E6\u0301", "\u01FE"=>"\u00D8\u0301", "\u01FF"=>"\u00F8\u0301",
- "\u0200"=>"A\u030F", "\u0201"=>"a\u030F", "\u0202"=>"A\u0311", "\u0203"=>"a\u0311", "\u0204"=>"E\u030F", "\u0205"=>"e\u030F", "\u0206"=>"E\u0311", "\u0207"=>"e\u0311",
- "\u0208"=>"I\u030F", "\u0209"=>"i\u030F", "\u020A"=>"I\u0311", "\u020B"=>"i\u0311", "\u020C"=>"O\u030F", "\u020D"=>"o\u030F", "\u020E"=>"O\u0311", "\u020F"=>"o\u0311",
- "\u0210"=>"R\u030F", "\u0211"=>"r\u030F", "\u0212"=>"R\u0311", "\u0213"=>"r\u0311", "\u0214"=>"U\u030F", "\u0215"=>"u\u030F", "\u0216"=>"U\u0311", "\u0217"=>"u\u0311",
- "\u0218"=>"S\u0326", "\u0219"=>"s\u0326", "\u021A"=>"T\u0326", "\u021B"=>"t\u0326", "\u021E"=>"H\u030C", "\u021F"=>"h\u030C", "\u0226"=>"A\u0307", "\u0227"=>"a\u0307",
- "\u0228"=>"E\u0327", "\u0229"=>"e\u0327", "\u022A"=>"O\u0308\u0304", "\u022B"=>"o\u0308\u0304", "\u022C"=>"O\u0303\u0304", "\u022D"=>"o\u0303\u0304", "\u022E"=>"O\u0307", "\u022F"=>"o\u0307",
- "\u0230"=>"O\u0307\u0304", "\u0231"=>"o\u0307\u0304", "\u0232"=>"Y\u0304", "\u0233"=>"y\u0304", "\u0340"=>"\u0300", "\u0341"=>"\u0301", "\u0343"=>"\u0313", "\u0344"=>"\u0308\u0301",
- "\u0374"=>"\u02B9", "\u037E"=>";", "\u0385"=>"\u00A8\u0301", "\u0386"=>"\u0391\u0301", "\u0387"=>"\u00B7", "\u0388"=>"\u0395\u0301", "\u0389"=>"\u0397\u0301", "\u038A"=>"\u0399\u0301",
- "\u038C"=>"\u039F\u0301", "\u038E"=>"\u03A5\u0301", "\u038F"=>"\u03A9\u0301", "\u0390"=>"\u03B9\u0308\u0301", "\u03AA"=>"\u0399\u0308", "\u03AB"=>"\u03A5\u0308", "\u03AC"=>"\u03B1\u0301", "\u03AD"=>"\u03B5\u0301",
- "\u03AE"=>"\u03B7\u0301", "\u03AF"=>"\u03B9\u0301", "\u03B0"=>"\u03C5\u0308\u0301", "\u03CA"=>"\u03B9\u0308", "\u03CB"=>"\u03C5\u0308", "\u03CC"=>"\u03BF\u0301", "\u03CD"=>"\u03C5\u0301", "\u03CE"=>"\u03C9\u0301",
- "\u03D3"=>"\u03D2\u0301", "\u03D4"=>"\u03D2\u0308", "\u0400"=>"\u0415\u0300", "\u0401"=>"\u0415\u0308", "\u0403"=>"\u0413\u0301", "\u0407"=>"\u0406\u0308", "\u040C"=>"\u041A\u0301", "\u040D"=>"\u0418\u0300",
- "\u040E"=>"\u0423\u0306", "\u0419"=>"\u0418\u0306", "\u0439"=>"\u0438\u0306", "\u0450"=>"\u0435\u0300", "\u0451"=>"\u0435\u0308", "\u0453"=>"\u0433\u0301", "\u0457"=>"\u0456\u0308", "\u045C"=>"\u043A\u0301",
- "\u045D"=>"\u0438\u0300", "\u045E"=>"\u0443\u0306", "\u0476"=>"\u0474\u030F", "\u0477"=>"\u0475\u030F", "\u04C1"=>"\u0416\u0306", "\u04C2"=>"\u0436\u0306", "\u04D0"=>"\u0410\u0306", "\u04D1"=>"\u0430\u0306",
- "\u04D2"=>"\u0410\u0308", "\u04D3"=>"\u0430\u0308", "\u04D6"=>"\u0415\u0306", "\u04D7"=>"\u0435\u0306", "\u04DA"=>"\u04D8\u0308", "\u04DB"=>"\u04D9\u0308", "\u04DC"=>"\u0416\u0308", "\u04DD"=>"\u0436\u0308",
- "\u04DE"=>"\u0417\u0308", "\u04DF"=>"\u0437\u0308", "\u04E2"=>"\u0418\u0304", "\u04E3"=>"\u0438\u0304", "\u04E4"=>"\u0418\u0308", "\u04E5"=>"\u0438\u0308", "\u04E6"=>"\u041E\u0308", "\u04E7"=>"\u043E\u0308",
- "\u04EA"=>"\u04E8\u0308", "\u04EB"=>"\u04E9\u0308", "\u04EC"=>"\u042D\u0308", "\u04ED"=>"\u044D\u0308", "\u04EE"=>"\u0423\u0304", "\u04EF"=>"\u0443\u0304", "\u04F0"=>"\u0423\u0308", "\u04F1"=>"\u0443\u0308",
- "\u04F2"=>"\u0423\u030B", "\u04F3"=>"\u0443\u030B", "\u04F4"=>"\u0427\u0308", "\u04F5"=>"\u0447\u0308", "\u04F8"=>"\u042B\u0308", "\u04F9"=>"\u044B\u0308", "\u0622"=>"\u0627\u0653", "\u0623"=>"\u0627\u0654",
- "\u0624"=>"\u0648\u0654", "\u0625"=>"\u0627\u0655", "\u0626"=>"\u064A\u0654", "\u06C0"=>"\u06D5\u0654", "\u06C2"=>"\u06C1\u0654", "\u06D3"=>"\u06D2\u0654", "\u0929"=>"\u0928\u093C", "\u0931"=>"\u0930\u093C",
- "\u0934"=>"\u0933\u093C", "\u0958"=>"\u0915\u093C", "\u0959"=>"\u0916\u093C", "\u095A"=>"\u0917\u093C", "\u095B"=>"\u091C\u093C", "\u095C"=>"\u0921\u093C", "\u095D"=>"\u0922\u093C", "\u095E"=>"\u092B\u093C",
- "\u095F"=>"\u092F\u093C", "\u09CB"=>"\u09C7\u09BE", "\u09CC"=>"\u09C7\u09D7", "\u09DC"=>"\u09A1\u09BC", "\u09DD"=>"\u09A2\u09BC", "\u09DF"=>"\u09AF\u09BC", "\u0A33"=>"\u0A32\u0A3C", "\u0A36"=>"\u0A38\u0A3C",
- "\u0A59"=>"\u0A16\u0A3C", "\u0A5A"=>"\u0A17\u0A3C", "\u0A5B"=>"\u0A1C\u0A3C", "\u0A5E"=>"\u0A2B\u0A3C", "\u0B48"=>"\u0B47\u0B56", "\u0B4B"=>"\u0B47\u0B3E", "\u0B4C"=>"\u0B47\u0B57", "\u0B5C"=>"\u0B21\u0B3C",
- "\u0B5D"=>"\u0B22\u0B3C", "\u0B94"=>"\u0B92\u0BD7", "\u0BCA"=>"\u0BC6\u0BBE", "\u0BCB"=>"\u0BC7\u0BBE", "\u0BCC"=>"\u0BC6\u0BD7", "\u0C48"=>"\u0C46\u0C56", "\u0CC0"=>"\u0CBF\u0CD5", "\u0CC7"=>"\u0CC6\u0CD5",
- "\u0CC8"=>"\u0CC6\u0CD6", "\u0CCA"=>"\u0CC6\u0CC2", "\u0CCB"=>"\u0CC6\u0CC2\u0CD5", "\u0D4A"=>"\u0D46\u0D3E", "\u0D4B"=>"\u0D47\u0D3E", "\u0D4C"=>"\u0D46\u0D57", "\u0DDA"=>"\u0DD9\u0DCA", "\u0DDC"=>"\u0DD9\u0DCF",
- "\u0DDD"=>"\u0DD9\u0DCF\u0DCA", "\u0DDE"=>"\u0DD9\u0DDF", "\u0F43"=>"\u0F42\u0FB7", "\u0F4D"=>"\u0F4C\u0FB7", "\u0F52"=>"\u0F51\u0FB7", "\u0F57"=>"\u0F56\u0FB7", "\u0F5C"=>"\u0F5B\u0FB7", "\u0F69"=>"\u0F40\u0FB5",
- "\u0F73"=>"\u0F71\u0F72", "\u0F75"=>"\u0F71\u0F74", "\u0F76"=>"\u0FB2\u0F80", "\u0F78"=>"\u0FB3\u0F80", "\u0F81"=>"\u0F71\u0F80", "\u0F93"=>"\u0F92\u0FB7", "\u0F9D"=>"\u0F9C\u0FB7", "\u0FA2"=>"\u0FA1\u0FB7",
- "\u0FA7"=>"\u0FA6\u0FB7", "\u0FAC"=>"\u0FAB\u0FB7", "\u0FB9"=>"\u0F90\u0FB5", "\u1026"=>"\u1025\u102E", "\u1B06"=>"\u1B05\u1B35", "\u1B08"=>"\u1B07\u1B35", "\u1B0A"=>"\u1B09\u1B35", "\u1B0C"=>"\u1B0B\u1B35",
- "\u1B0E"=>"\u1B0D\u1B35", "\u1B12"=>"\u1B11\u1B35", "\u1B3B"=>"\u1B3A\u1B35", "\u1B3D"=>"\u1B3C\u1B35", "\u1B40"=>"\u1B3E\u1B35", "\u1B41"=>"\u1B3F\u1B35", "\u1B43"=>"\u1B42\u1B35", "\u1E00"=>"A\u0325",
- "\u1E01"=>"a\u0325", "\u1E02"=>"B\u0307", "\u1E03"=>"b\u0307", "\u1E04"=>"B\u0323", "\u1E05"=>"b\u0323", "\u1E06"=>"B\u0331", "\u1E07"=>"b\u0331", "\u1E08"=>"C\u0327\u0301",
- "\u1E09"=>"c\u0327\u0301", "\u1E0A"=>"D\u0307", "\u1E0B"=>"d\u0307", "\u1E0C"=>"D\u0323", "\u1E0D"=>"d\u0323", "\u1E0E"=>"D\u0331", "\u1E0F"=>"d\u0331", "\u1E10"=>"D\u0327",
- "\u1E11"=>"d\u0327", "\u1E12"=>"D\u032D", "\u1E13"=>"d\u032D", "\u1E14"=>"E\u0304\u0300", "\u1E15"=>"e\u0304\u0300", "\u1E16"=>"E\u0304\u0301", "\u1E17"=>"e\u0304\u0301", "\u1E18"=>"E\u032D",
- "\u1E19"=>"e\u032D", "\u1E1A"=>"E\u0330", "\u1E1B"=>"e\u0330", "\u1E1C"=>"E\u0327\u0306", "\u1E1D"=>"e\u0327\u0306", "\u1E1E"=>"F\u0307", "\u1E1F"=>"f\u0307", "\u1E20"=>"G\u0304",
- "\u1E21"=>"g\u0304", "\u1E22"=>"H\u0307", "\u1E23"=>"h\u0307", "\u1E24"=>"H\u0323", "\u1E25"=>"h\u0323", "\u1E26"=>"H\u0308", "\u1E27"=>"h\u0308", "\u1E28"=>"H\u0327",
- "\u1E29"=>"h\u0327", "\u1E2A"=>"H\u032E", "\u1E2B"=>"h\u032E", "\u1E2C"=>"I\u0330", "\u1E2D"=>"i\u0330", "\u1E2E"=>"I\u0308\u0301", "\u1E2F"=>"i\u0308\u0301", "\u1E30"=>"K\u0301",
- "\u1E31"=>"k\u0301", "\u1E32"=>"K\u0323", "\u1E33"=>"k\u0323", "\u1E34"=>"K\u0331", "\u1E35"=>"k\u0331", "\u1E36"=>"L\u0323", "\u1E37"=>"l\u0323", "\u1E38"=>"L\u0323\u0304",
- "\u1E39"=>"l\u0323\u0304", "\u1E3A"=>"L\u0331", "\u1E3B"=>"l\u0331", "\u1E3C"=>"L\u032D", "\u1E3D"=>"l\u032D", "\u1E3E"=>"M\u0301", "\u1E3F"=>"m\u0301", "\u1E40"=>"M\u0307",
- "\u1E41"=>"m\u0307", "\u1E42"=>"M\u0323", "\u1E43"=>"m\u0323", "\u1E44"=>"N\u0307", "\u1E45"=>"n\u0307", "\u1E46"=>"N\u0323", "\u1E47"=>"n\u0323", "\u1E48"=>"N\u0331",
- "\u1E49"=>"n\u0331", "\u1E4A"=>"N\u032D", "\u1E4B"=>"n\u032D", "\u1E4C"=>"O\u0303\u0301", "\u1E4D"=>"o\u0303\u0301", "\u1E4E"=>"O\u0303\u0308", "\u1E4F"=>"o\u0303\u0308", "\u1E50"=>"O\u0304\u0300",
- "\u1E51"=>"o\u0304\u0300", "\u1E52"=>"O\u0304\u0301", "\u1E53"=>"o\u0304\u0301", "\u1E54"=>"P\u0301", "\u1E55"=>"p\u0301", "\u1E56"=>"P\u0307", "\u1E57"=>"p\u0307", "\u1E58"=>"R\u0307",
- "\u1E59"=>"r\u0307", "\u1E5A"=>"R\u0323", "\u1E5B"=>"r\u0323", "\u1E5C"=>"R\u0323\u0304", "\u1E5D"=>"r\u0323\u0304", "\u1E5E"=>"R\u0331", "\u1E5F"=>"r\u0331", "\u1E60"=>"S\u0307",
- "\u1E61"=>"s\u0307", "\u1E62"=>"S\u0323", "\u1E63"=>"s\u0323", "\u1E64"=>"S\u0301\u0307", "\u1E65"=>"s\u0301\u0307", "\u1E66"=>"S\u030C\u0307", "\u1E67"=>"s\u030C\u0307", "\u1E68"=>"S\u0323\u0307",
- "\u1E69"=>"s\u0323\u0307", "\u1E6A"=>"T\u0307", "\u1E6B"=>"t\u0307", "\u1E6C"=>"T\u0323", "\u1E6D"=>"t\u0323", "\u1E6E"=>"T\u0331", "\u1E6F"=>"t\u0331", "\u1E70"=>"T\u032D",
- "\u1E71"=>"t\u032D", "\u1E72"=>"U\u0324", "\u1E73"=>"u\u0324", "\u1E74"=>"U\u0330", "\u1E75"=>"u\u0330", "\u1E76"=>"U\u032D", "\u1E77"=>"u\u032D", "\u1E78"=>"U\u0303\u0301",
- "\u1E79"=>"u\u0303\u0301", "\u1E7A"=>"U\u0304\u0308", "\u1E7B"=>"u\u0304\u0308", "\u1E7C"=>"V\u0303", "\u1E7D"=>"v\u0303", "\u1E7E"=>"V\u0323", "\u1E7F"=>"v\u0323", "\u1E80"=>"W\u0300",
- "\u1E81"=>"w\u0300", "\u1E82"=>"W\u0301", "\u1E83"=>"w\u0301", "\u1E84"=>"W\u0308", "\u1E85"=>"w\u0308", "\u1E86"=>"W\u0307", "\u1E87"=>"w\u0307", "\u1E88"=>"W\u0323",
- "\u1E89"=>"w\u0323", "\u1E8A"=>"X\u0307", "\u1E8B"=>"x\u0307", "\u1E8C"=>"X\u0308", "\u1E8D"=>"x\u0308", "\u1E8E"=>"Y\u0307", "\u1E8F"=>"y\u0307", "\u1E90"=>"Z\u0302",
- "\u1E91"=>"z\u0302", "\u1E92"=>"Z\u0323", "\u1E93"=>"z\u0323", "\u1E94"=>"Z\u0331", "\u1E95"=>"z\u0331", "\u1E96"=>"h\u0331", "\u1E97"=>"t\u0308", "\u1E98"=>"w\u030A",
- "\u1E99"=>"y\u030A", "\u1E9B"=>"\u017F\u0307", "\u1EA0"=>"A\u0323", "\u1EA1"=>"a\u0323", "\u1EA2"=>"A\u0309", "\u1EA3"=>"a\u0309", "\u1EA4"=>"A\u0302\u0301", "\u1EA5"=>"a\u0302\u0301",
- "\u1EA6"=>"A\u0302\u0300", "\u1EA7"=>"a\u0302\u0300", "\u1EA8"=>"A\u0302\u0309", "\u1EA9"=>"a\u0302\u0309", "\u1EAA"=>"A\u0302\u0303", "\u1EAB"=>"a\u0302\u0303", "\u1EAC"=>"A\u0323\u0302", "\u1EAD"=>"a\u0323\u0302",
- "\u1EAE"=>"A\u0306\u0301", "\u1EAF"=>"a\u0306\u0301", "\u1EB0"=>"A\u0306\u0300", "\u1EB1"=>"a\u0306\u0300", "\u1EB2"=>"A\u0306\u0309", "\u1EB3"=>"a\u0306\u0309", "\u1EB4"=>"A\u0306\u0303", "\u1EB5"=>"a\u0306\u0303",
- "\u1EB6"=>"A\u0323\u0306", "\u1EB7"=>"a\u0323\u0306", "\u1EB8"=>"E\u0323", "\u1EB9"=>"e\u0323", "\u1EBA"=>"E\u0309", "\u1EBB"=>"e\u0309", "\u1EBC"=>"E\u0303", "\u1EBD"=>"e\u0303",
- "\u1EBE"=>"E\u0302\u0301", "\u1EBF"=>"e\u0302\u0301", "\u1EC0"=>"E\u0302\u0300", "\u1EC1"=>"e\u0302\u0300", "\u1EC2"=>"E\u0302\u0309", "\u1EC3"=>"e\u0302\u0309", "\u1EC4"=>"E\u0302\u0303", "\u1EC5"=>"e\u0302\u0303",
- "\u1EC6"=>"E\u0323\u0302", "\u1EC7"=>"e\u0323\u0302", "\u1EC8"=>"I\u0309", "\u1EC9"=>"i\u0309", "\u1ECA"=>"I\u0323", "\u1ECB"=>"i\u0323", "\u1ECC"=>"O\u0323", "\u1ECD"=>"o\u0323",
- "\u1ECE"=>"O\u0309", "\u1ECF"=>"o\u0309", "\u1ED0"=>"O\u0302\u0301", "\u1ED1"=>"o\u0302\u0301", "\u1ED2"=>"O\u0302\u0300", "\u1ED3"=>"o\u0302\u0300", "\u1ED4"=>"O\u0302\u0309", "\u1ED5"=>"o\u0302\u0309",
- "\u1ED6"=>"O\u0302\u0303", "\u1ED7"=>"o\u0302\u0303", "\u1ED8"=>"O\u0323\u0302", "\u1ED9"=>"o\u0323\u0302", "\u1EDA"=>"O\u031B\u0301", "\u1EDB"=>"o\u031B\u0301", "\u1EDC"=>"O\u031B\u0300", "\u1EDD"=>"o\u031B\u0300",
- "\u1EDE"=>"O\u031B\u0309", "\u1EDF"=>"o\u031B\u0309", "\u1EE0"=>"O\u031B\u0303", "\u1EE1"=>"o\u031B\u0303", "\u1EE2"=>"O\u031B\u0323", "\u1EE3"=>"o\u031B\u0323", "\u1EE4"=>"U\u0323", "\u1EE5"=>"u\u0323",
- "\u1EE6"=>"U\u0309", "\u1EE7"=>"u\u0309", "\u1EE8"=>"U\u031B\u0301", "\u1EE9"=>"u\u031B\u0301", "\u1EEA"=>"U\u031B\u0300", "\u1EEB"=>"u\u031B\u0300", "\u1EEC"=>"U\u031B\u0309", "\u1EED"=>"u\u031B\u0309",
- "\u1EEE"=>"U\u031B\u0303", "\u1EEF"=>"u\u031B\u0303", "\u1EF0"=>"U\u031B\u0323", "\u1EF1"=>"u\u031B\u0323", "\u1EF2"=>"Y\u0300", "\u1EF3"=>"y\u0300", "\u1EF4"=>"Y\u0323", "\u1EF5"=>"y\u0323",
- "\u1EF6"=>"Y\u0309", "\u1EF7"=>"y\u0309", "\u1EF8"=>"Y\u0303", "\u1EF9"=>"y\u0303", "\u1F00"=>"\u03B1\u0313", "\u1F01"=>"\u03B1\u0314", "\u1F02"=>"\u03B1\u0313\u0300", "\u1F03"=>"\u03B1\u0314\u0300",
- "\u1F04"=>"\u03B1\u0313\u0301", "\u1F05"=>"\u03B1\u0314\u0301", "\u1F06"=>"\u03B1\u0313\u0342", "\u1F07"=>"\u03B1\u0314\u0342", "\u1F08"=>"\u0391\u0313", "\u1F09"=>"\u0391\u0314", "\u1F0A"=>"\u0391\u0313\u0300", "\u1F0B"=>"\u0391\u0314\u0300",
- "\u1F0C"=>"\u0391\u0313\u0301", "\u1F0D"=>"\u0391\u0314\u0301", "\u1F0E"=>"\u0391\u0313\u0342", "\u1F0F"=>"\u0391\u0314\u0342", "\u1F10"=>"\u03B5\u0313", "\u1F11"=>"\u03B5\u0314", "\u1F12"=>"\u03B5\u0313\u0300", "\u1F13"=>"\u03B5\u0314\u0300",
- "\u1F14"=>"\u03B5\u0313\u0301", "\u1F15"=>"\u03B5\u0314\u0301", "\u1F18"=>"\u0395\u0313", "\u1F19"=>"\u0395\u0314", "\u1F1A"=>"\u0395\u0313\u0300", "\u1F1B"=>"\u0395\u0314\u0300", "\u1F1C"=>"\u0395\u0313\u0301", "\u1F1D"=>"\u0395\u0314\u0301",
- "\u1F20"=>"\u03B7\u0313", "\u1F21"=>"\u03B7\u0314", "\u1F22"=>"\u03B7\u0313\u0300", "\u1F23"=>"\u03B7\u0314\u0300", "\u1F24"=>"\u03B7\u0313\u0301", "\u1F25"=>"\u03B7\u0314\u0301", "\u1F26"=>"\u03B7\u0313\u0342", "\u1F27"=>"\u03B7\u0314\u0342",
- "\u1F28"=>"\u0397\u0313", "\u1F29"=>"\u0397\u0314", "\u1F2A"=>"\u0397\u0313\u0300", "\u1F2B"=>"\u0397\u0314\u0300", "\u1F2C"=>"\u0397\u0313\u0301", "\u1F2D"=>"\u0397\u0314\u0301", "\u1F2E"=>"\u0397\u0313\u0342", "\u1F2F"=>"\u0397\u0314\u0342",
- "\u1F30"=>"\u03B9\u0313", "\u1F31"=>"\u03B9\u0314", "\u1F32"=>"\u03B9\u0313\u0300", "\u1F33"=>"\u03B9\u0314\u0300", "\u1F34"=>"\u03B9\u0313\u0301", "\u1F35"=>"\u03B9\u0314\u0301", "\u1F36"=>"\u03B9\u0313\u0342", "\u1F37"=>"\u03B9\u0314\u0342",
- "\u1F38"=>"\u0399\u0313", "\u1F39"=>"\u0399\u0314", "\u1F3A"=>"\u0399\u0313\u0300", "\u1F3B"=>"\u0399\u0314\u0300", "\u1F3C"=>"\u0399\u0313\u0301", "\u1F3D"=>"\u0399\u0314\u0301", "\u1F3E"=>"\u0399\u0313\u0342", "\u1F3F"=>"\u0399\u0314\u0342",
- "\u1F40"=>"\u03BF\u0313", "\u1F41"=>"\u03BF\u0314", "\u1F42"=>"\u03BF\u0313\u0300", "\u1F43"=>"\u03BF\u0314\u0300", "\u1F44"=>"\u03BF\u0313\u0301", "\u1F45"=>"\u03BF\u0314\u0301", "\u1F48"=>"\u039F\u0313", "\u1F49"=>"\u039F\u0314",
- "\u1F4A"=>"\u039F\u0313\u0300", "\u1F4B"=>"\u039F\u0314\u0300", "\u1F4C"=>"\u039F\u0313\u0301", "\u1F4D"=>"\u039F\u0314\u0301", "\u1F50"=>"\u03C5\u0313", "\u1F51"=>"\u03C5\u0314", "\u1F52"=>"\u03C5\u0313\u0300", "\u1F53"=>"\u03C5\u0314\u0300",
- "\u1F54"=>"\u03C5\u0313\u0301", "\u1F55"=>"\u03C5\u0314\u0301", "\u1F56"=>"\u03C5\u0313\u0342", "\u1F57"=>"\u03C5\u0314\u0342", "\u1F59"=>"\u03A5\u0314", "\u1F5B"=>"\u03A5\u0314\u0300", "\u1F5D"=>"\u03A5\u0314\u0301", "\u1F5F"=>"\u03A5\u0314\u0342",
- "\u1F60"=>"\u03C9\u0313", "\u1F61"=>"\u03C9\u0314", "\u1F62"=>"\u03C9\u0313\u0300", "\u1F63"=>"\u03C9\u0314\u0300", "\u1F64"=>"\u03C9\u0313\u0301", "\u1F65"=>"\u03C9\u0314\u0301", "\u1F66"=>"\u03C9\u0313\u0342", "\u1F67"=>"\u03C9\u0314\u0342",
- "\u1F68"=>"\u03A9\u0313", "\u1F69"=>"\u03A9\u0314", "\u1F6A"=>"\u03A9\u0313\u0300", "\u1F6B"=>"\u03A9\u0314\u0300", "\u1F6C"=>"\u03A9\u0313\u0301", "\u1F6D"=>"\u03A9\u0314\u0301", "\u1F6E"=>"\u03A9\u0313\u0342", "\u1F6F"=>"\u03A9\u0314\u0342",
- "\u1F70"=>"\u03B1\u0300", "\u1F71"=>"\u03B1\u0301", "\u1F72"=>"\u03B5\u0300", "\u1F73"=>"\u03B5\u0301", "\u1F74"=>"\u03B7\u0300", "\u1F75"=>"\u03B7\u0301", "\u1F76"=>"\u03B9\u0300", "\u1F77"=>"\u03B9\u0301",
- "\u1F78"=>"\u03BF\u0300", "\u1F79"=>"\u03BF\u0301", "\u1F7A"=>"\u03C5\u0300", "\u1F7B"=>"\u03C5\u0301", "\u1F7C"=>"\u03C9\u0300", "\u1F7D"=>"\u03C9\u0301", "\u1F80"=>"\u03B1\u0313\u0345", "\u1F81"=>"\u03B1\u0314\u0345",
- "\u1F82"=>"\u03B1\u0313\u0300\u0345", "\u1F83"=>"\u03B1\u0314\u0300\u0345", "\u1F84"=>"\u03B1\u0313\u0301\u0345", "\u1F85"=>"\u03B1\u0314\u0301\u0345", "\u1F86"=>"\u03B1\u0313\u0342\u0345", "\u1F87"=>"\u03B1\u0314\u0342\u0345", "\u1F88"=>"\u0391\u0313\u0345", "\u1F89"=>"\u0391\u0314\u0345",
- "\u1F8A"=>"\u0391\u0313\u0300\u0345", "\u1F8B"=>"\u0391\u0314\u0300\u0345", "\u1F8C"=>"\u0391\u0313\u0301\u0345", "\u1F8D"=>"\u0391\u0314\u0301\u0345", "\u1F8E"=>"\u0391\u0313\u0342\u0345", "\u1F8F"=>"\u0391\u0314\u0342\u0345", "\u1F90"=>"\u03B7\u0313\u0345", "\u1F91"=>"\u03B7\u0314\u0345",
- "\u1F92"=>"\u03B7\u0313\u0300\u0345", "\u1F93"=>"\u03B7\u0314\u0300\u0345", "\u1F94"=>"\u03B7\u0313\u0301\u0345", "\u1F95"=>"\u03B7\u0314\u0301\u0345", "\u1F96"=>"\u03B7\u0313\u0342\u0345", "\u1F97"=>"\u03B7\u0314\u0342\u0345", "\u1F98"=>"\u0397\u0313\u0345", "\u1F99"=>"\u0397\u0314\u0345",
- "\u1F9A"=>"\u0397\u0313\u0300\u0345", "\u1F9B"=>"\u0397\u0314\u0300\u0345", "\u1F9C"=>"\u0397\u0313\u0301\u0345", "\u1F9D"=>"\u0397\u0314\u0301\u0345", "\u1F9E"=>"\u0397\u0313\u0342\u0345", "\u1F9F"=>"\u0397\u0314\u0342\u0345", "\u1FA0"=>"\u03C9\u0313\u0345", "\u1FA1"=>"\u03C9\u0314\u0345",
- "\u1FA2"=>"\u03C9\u0313\u0300\u0345", "\u1FA3"=>"\u03C9\u0314\u0300\u0345", "\u1FA4"=>"\u03C9\u0313\u0301\u0345", "\u1FA5"=>"\u03C9\u0314\u0301\u0345", "\u1FA6"=>"\u03C9\u0313\u0342\u0345", "\u1FA7"=>"\u03C9\u0314\u0342\u0345", "\u1FA8"=>"\u03A9\u0313\u0345", "\u1FA9"=>"\u03A9\u0314\u0345",
- "\u1FAA"=>"\u03A9\u0313\u0300\u0345", "\u1FAB"=>"\u03A9\u0314\u0300\u0345", "\u1FAC"=>"\u03A9\u0313\u0301\u0345", "\u1FAD"=>"\u03A9\u0314\u0301\u0345", "\u1FAE"=>"\u03A9\u0313\u0342\u0345", "\u1FAF"=>"\u03A9\u0314\u0342\u0345", "\u1FB0"=>"\u03B1\u0306", "\u1FB1"=>"\u03B1\u0304",
- "\u1FB2"=>"\u03B1\u0300\u0345", "\u1FB3"=>"\u03B1\u0345", "\u1FB4"=>"\u03B1\u0301\u0345", "\u1FB6"=>"\u03B1\u0342", "\u1FB7"=>"\u03B1\u0342\u0345", "\u1FB8"=>"\u0391\u0306", "\u1FB9"=>"\u0391\u0304", "\u1FBA"=>"\u0391\u0300",
- "\u1FBB"=>"\u0391\u0301", "\u1FBC"=>"\u0391\u0345", "\u1FBE"=>"\u03B9", "\u1FC1"=>"\u00A8\u0342", "\u1FC2"=>"\u03B7\u0300\u0345", "\u1FC3"=>"\u03B7\u0345", "\u1FC4"=>"\u03B7\u0301\u0345", "\u1FC6"=>"\u03B7\u0342",
- "\u1FC7"=>"\u03B7\u0342\u0345", "\u1FC8"=>"\u0395\u0300", "\u1FC9"=>"\u0395\u0301", "\u1FCA"=>"\u0397\u0300", "\u1FCB"=>"\u0397\u0301", "\u1FCC"=>"\u0397\u0345", "\u1FCD"=>"\u1FBF\u0300", "\u1FCE"=>"\u1FBF\u0301",
- "\u1FCF"=>"\u1FBF\u0342", "\u1FD0"=>"\u03B9\u0306", "\u1FD1"=>"\u03B9\u0304", "\u1FD2"=>"\u03B9\u0308\u0300", "\u1FD3"=>"\u03B9\u0308\u0301", "\u1FD6"=>"\u03B9\u0342", "\u1FD7"=>"\u03B9\u0308\u0342", "\u1FD8"=>"\u0399\u0306",
- "\u1FD9"=>"\u0399\u0304", "\u1FDA"=>"\u0399\u0300", "\u1FDB"=>"\u0399\u0301", "\u1FDD"=>"\u1FFE\u0300", "\u1FDE"=>"\u1FFE\u0301", "\u1FDF"=>"\u1FFE\u0342", "\u1FE0"=>"\u03C5\u0306", "\u1FE1"=>"\u03C5\u0304",
- "\u1FE2"=>"\u03C5\u0308\u0300", "\u1FE3"=>"\u03C5\u0308\u0301", "\u1FE4"=>"\u03C1\u0313", "\u1FE5"=>"\u03C1\u0314", "\u1FE6"=>"\u03C5\u0342", "\u1FE7"=>"\u03C5\u0308\u0342", "\u1FE8"=>"\u03A5\u0306", "\u1FE9"=>"\u03A5\u0304",
- "\u1FEA"=>"\u03A5\u0300", "\u1FEB"=>"\u03A5\u0301", "\u1FEC"=>"\u03A1\u0314", "\u1FED"=>"\u00A8\u0300", "\u1FEE"=>"\u00A8\u0301", "\u1FEF"=>"`", "\u1FF2"=>"\u03C9\u0300\u0345", "\u1FF3"=>"\u03C9\u0345",
- "\u1FF4"=>"\u03C9\u0301\u0345", "\u1FF6"=>"\u03C9\u0342", "\u1FF7"=>"\u03C9\u0342\u0345", "\u1FF8"=>"\u039F\u0300", "\u1FF9"=>"\u039F\u0301", "\u1FFA"=>"\u03A9\u0300", "\u1FFB"=>"\u03A9\u0301", "\u1FFC"=>"\u03A9\u0345",
- "\u1FFD"=>"\u00B4", "\u2000"=>"\u2002", "\u2001"=>"\u2003", "\u2126"=>"\u03A9", "\u212A"=>"K", "\u212B"=>"A\u030A", "\u219A"=>"\u2190\u0338", "\u219B"=>"\u2192\u0338",
- "\u21AE"=>"\u2194\u0338", "\u21CD"=>"\u21D0\u0338", "\u21CE"=>"\u21D4\u0338", "\u21CF"=>"\u21D2\u0338", "\u2204"=>"\u2203\u0338", "\u2209"=>"\u2208\u0338", "\u220C"=>"\u220B\u0338", "\u2224"=>"\u2223\u0338",
- "\u2226"=>"\u2225\u0338", "\u2241"=>"\u223C\u0338", "\u2244"=>"\u2243\u0338", "\u2247"=>"\u2245\u0338", "\u2249"=>"\u2248\u0338", "\u2260"=>"=\u0338", "\u2262"=>"\u2261\u0338", "\u226D"=>"\u224D\u0338",
- "\u226E"=>"<\u0338", "\u226F"=>">\u0338", "\u2270"=>"\u2264\u0338", "\u2271"=>"\u2265\u0338", "\u2274"=>"\u2272\u0338", "\u2275"=>"\u2273\u0338", "\u2278"=>"\u2276\u0338", "\u2279"=>"\u2277\u0338",
- "\u2280"=>"\u227A\u0338", "\u2281"=>"\u227B\u0338", "\u2284"=>"\u2282\u0338", "\u2285"=>"\u2283\u0338", "\u2288"=>"\u2286\u0338", "\u2289"=>"\u2287\u0338", "\u22AC"=>"\u22A2\u0338", "\u22AD"=>"\u22A8\u0338",
- "\u22AE"=>"\u22A9\u0338", "\u22AF"=>"\u22AB\u0338", "\u22E0"=>"\u227C\u0338", "\u22E1"=>"\u227D\u0338", "\u22E2"=>"\u2291\u0338", "\u22E3"=>"\u2292\u0338", "\u22EA"=>"\u22B2\u0338", "\u22EB"=>"\u22B3\u0338",
- "\u22EC"=>"\u22B4\u0338", "\u22ED"=>"\u22B5\u0338", "\u2329"=>"\u3008", "\u232A"=>"\u3009", "\u2ADC"=>"\u2ADD\u0338", "\u304C"=>"\u304B\u3099", "\u304E"=>"\u304D\u3099", "\u3050"=>"\u304F\u3099",
- "\u3052"=>"\u3051\u3099", "\u3054"=>"\u3053\u3099", "\u3056"=>"\u3055\u3099", "\u3058"=>"\u3057\u3099", "\u305A"=>"\u3059\u3099", "\u305C"=>"\u305B\u3099", "\u305E"=>"\u305D\u3099", "\u3060"=>"\u305F\u3099",
- "\u3062"=>"\u3061\u3099", "\u3065"=>"\u3064\u3099", "\u3067"=>"\u3066\u3099", "\u3069"=>"\u3068\u3099", "\u3070"=>"\u306F\u3099", "\u3071"=>"\u306F\u309A", "\u3073"=>"\u3072\u3099", "\u3074"=>"\u3072\u309A",
- "\u3076"=>"\u3075\u3099", "\u3077"=>"\u3075\u309A", "\u3079"=>"\u3078\u3099", "\u307A"=>"\u3078\u309A", "\u307C"=>"\u307B\u3099", "\u307D"=>"\u307B\u309A", "\u3094"=>"\u3046\u3099", "\u309E"=>"\u309D\u3099",
- "\u30AC"=>"\u30AB\u3099", "\u30AE"=>"\u30AD\u3099", "\u30B0"=>"\u30AF\u3099", "\u30B2"=>"\u30B1\u3099", "\u30B4"=>"\u30B3\u3099", "\u30B6"=>"\u30B5\u3099", "\u30B8"=>"\u30B7\u3099", "\u30BA"=>"\u30B9\u3099",
- "\u30BC"=>"\u30BB\u3099", "\u30BE"=>"\u30BD\u3099", "\u30C0"=>"\u30BF\u3099", "\u30C2"=>"\u30C1\u3099", "\u30C5"=>"\u30C4\u3099", "\u30C7"=>"\u30C6\u3099", "\u30C9"=>"\u30C8\u3099", "\u30D0"=>"\u30CF\u3099",
- "\u30D1"=>"\u30CF\u309A", "\u30D3"=>"\u30D2\u3099", "\u30D4"=>"\u30D2\u309A", "\u30D6"=>"\u30D5\u3099", "\u30D7"=>"\u30D5\u309A", "\u30D9"=>"\u30D8\u3099", "\u30DA"=>"\u30D8\u309A", "\u30DC"=>"\u30DB\u3099",
- "\u30DD"=>"\u30DB\u309A", "\u30F4"=>"\u30A6\u3099", "\u30F7"=>"\u30EF\u3099", "\u30F8"=>"\u30F0\u3099", "\u30F9"=>"\u30F1\u3099", "\u30FA"=>"\u30F2\u3099", "\u30FE"=>"\u30FD\u3099", "\uF900"=>"\u8C48",
- "\uF901"=>"\u66F4", "\uF902"=>"\u8ECA", "\uF903"=>"\u8CC8", "\uF904"=>"\u6ED1", "\uF905"=>"\u4E32", "\uF906"=>"\u53E5", "\uF907"=>"\u9F9C", "\uF908"=>"\u9F9C",
- "\uF909"=>"\u5951", "\uF90A"=>"\u91D1", "\uF90B"=>"\u5587", "\uF90C"=>"\u5948", "\uF90D"=>"\u61F6", "\uF90E"=>"\u7669", "\uF90F"=>"\u7F85", "\uF910"=>"\u863F",
- "\uF911"=>"\u87BA", "\uF912"=>"\u88F8", "\uF913"=>"\u908F", "\uF914"=>"\u6A02", "\uF915"=>"\u6D1B", "\uF916"=>"\u70D9", "\uF917"=>"\u73DE", "\uF918"=>"\u843D",
- "\uF919"=>"\u916A", "\uF91A"=>"\u99F1", "\uF91B"=>"\u4E82", "\uF91C"=>"\u5375", "\uF91D"=>"\u6B04", "\uF91E"=>"\u721B", "\uF91F"=>"\u862D", "\uF920"=>"\u9E1E",
- "\uF921"=>"\u5D50", "\uF922"=>"\u6FEB", "\uF923"=>"\u85CD", "\uF924"=>"\u8964", "\uF925"=>"\u62C9", "\uF926"=>"\u81D8", "\uF927"=>"\u881F", "\uF928"=>"\u5ECA",
- "\uF929"=>"\u6717", "\uF92A"=>"\u6D6A", "\uF92B"=>"\u72FC", "\uF92C"=>"\u90CE", "\uF92D"=>"\u4F86", "\uF92E"=>"\u51B7", "\uF92F"=>"\u52DE", "\uF930"=>"\u64C4",
- "\uF931"=>"\u6AD3", "\uF932"=>"\u7210", "\uF933"=>"\u76E7", "\uF934"=>"\u8001", "\uF935"=>"\u8606", "\uF936"=>"\u865C", "\uF937"=>"\u8DEF", "\uF938"=>"\u9732",
- "\uF939"=>"\u9B6F", "\uF93A"=>"\u9DFA", "\uF93B"=>"\u788C", "\uF93C"=>"\u797F", "\uF93D"=>"\u7DA0", "\uF93E"=>"\u83C9", "\uF93F"=>"\u9304", "\uF940"=>"\u9E7F",
- "\uF941"=>"\u8AD6", "\uF942"=>"\u58DF", "\uF943"=>"\u5F04", "\uF944"=>"\u7C60", "\uF945"=>"\u807E", "\uF946"=>"\u7262", "\uF947"=>"\u78CA", "\uF948"=>"\u8CC2",
- "\uF949"=>"\u96F7", "\uF94A"=>"\u58D8", "\uF94B"=>"\u5C62", "\uF94C"=>"\u6A13", "\uF94D"=>"\u6DDA", "\uF94E"=>"\u6F0F", "\uF94F"=>"\u7D2F", "\uF950"=>"\u7E37",
- "\uF951"=>"\u964B", "\uF952"=>"\u52D2", "\uF953"=>"\u808B", "\uF954"=>"\u51DC", "\uF955"=>"\u51CC", "\uF956"=>"\u7A1C", "\uF957"=>"\u7DBE", "\uF958"=>"\u83F1",
- "\uF959"=>"\u9675", "\uF95A"=>"\u8B80", "\uF95B"=>"\u62CF", "\uF95C"=>"\u6A02", "\uF95D"=>"\u8AFE", "\uF95E"=>"\u4E39", "\uF95F"=>"\u5BE7", "\uF960"=>"\u6012",
- "\uF961"=>"\u7387", "\uF962"=>"\u7570", "\uF963"=>"\u5317", "\uF964"=>"\u78FB", "\uF965"=>"\u4FBF", "\uF966"=>"\u5FA9", "\uF967"=>"\u4E0D", "\uF968"=>"\u6CCC",
- "\uF969"=>"\u6578", "\uF96A"=>"\u7D22", "\uF96B"=>"\u53C3", "\uF96C"=>"\u585E", "\uF96D"=>"\u7701", "\uF96E"=>"\u8449", "\uF96F"=>"\u8AAA", "\uF970"=>"\u6BBA",
- "\uF971"=>"\u8FB0", "\uF972"=>"\u6C88", "\uF973"=>"\u62FE", "\uF974"=>"\u82E5", "\uF975"=>"\u63A0", "\uF976"=>"\u7565", "\uF977"=>"\u4EAE", "\uF978"=>"\u5169",
- "\uF979"=>"\u51C9", "\uF97A"=>"\u6881", "\uF97B"=>"\u7CE7", "\uF97C"=>"\u826F", "\uF97D"=>"\u8AD2", "\uF97E"=>"\u91CF", "\uF97F"=>"\u52F5", "\uF980"=>"\u5442",
- "\uF981"=>"\u5973", "\uF982"=>"\u5EEC", "\uF983"=>"\u65C5", "\uF984"=>"\u6FFE", "\uF985"=>"\u792A", "\uF986"=>"\u95AD", "\uF987"=>"\u9A6A", "\uF988"=>"\u9E97",
- "\uF989"=>"\u9ECE", "\uF98A"=>"\u529B", "\uF98B"=>"\u66C6", "\uF98C"=>"\u6B77", "\uF98D"=>"\u8F62", "\uF98E"=>"\u5E74", "\uF98F"=>"\u6190", "\uF990"=>"\u6200",
- "\uF991"=>"\u649A", "\uF992"=>"\u6F23", "\uF993"=>"\u7149", "\uF994"=>"\u7489", "\uF995"=>"\u79CA", "\uF996"=>"\u7DF4", "\uF997"=>"\u806F", "\uF998"=>"\u8F26",
- "\uF999"=>"\u84EE", "\uF99A"=>"\u9023", "\uF99B"=>"\u934A", "\uF99C"=>"\u5217", "\uF99D"=>"\u52A3", "\uF99E"=>"\u54BD", "\uF99F"=>"\u70C8", "\uF9A0"=>"\u88C2",
- "\uF9A1"=>"\u8AAA", "\uF9A2"=>"\u5EC9", "\uF9A3"=>"\u5FF5", "\uF9A4"=>"\u637B", "\uF9A5"=>"\u6BAE", "\uF9A6"=>"\u7C3E", "\uF9A7"=>"\u7375", "\uF9A8"=>"\u4EE4",
- "\uF9A9"=>"\u56F9", "\uF9AA"=>"\u5BE7", "\uF9AB"=>"\u5DBA", "\uF9AC"=>"\u601C", "\uF9AD"=>"\u73B2", "\uF9AE"=>"\u7469", "\uF9AF"=>"\u7F9A", "\uF9B0"=>"\u8046",
- "\uF9B1"=>"\u9234", "\uF9B2"=>"\u96F6", "\uF9B3"=>"\u9748", "\uF9B4"=>"\u9818", "\uF9B5"=>"\u4F8B", "\uF9B6"=>"\u79AE", "\uF9B7"=>"\u91B4", "\uF9B8"=>"\u96B8",
- "\uF9B9"=>"\u60E1", "\uF9BA"=>"\u4E86", "\uF9BB"=>"\u50DA", "\uF9BC"=>"\u5BEE", "\uF9BD"=>"\u5C3F", "\uF9BE"=>"\u6599", "\uF9BF"=>"\u6A02", "\uF9C0"=>"\u71CE",
- "\uF9C1"=>"\u7642", "\uF9C2"=>"\u84FC", "\uF9C3"=>"\u907C", "\uF9C4"=>"\u9F8D", "\uF9C5"=>"\u6688", "\uF9C6"=>"\u962E", "\uF9C7"=>"\u5289", "\uF9C8"=>"\u677B",
- "\uF9C9"=>"\u67F3", "\uF9CA"=>"\u6D41", "\uF9CB"=>"\u6E9C", "\uF9CC"=>"\u7409", "\uF9CD"=>"\u7559", "\uF9CE"=>"\u786B", "\uF9CF"=>"\u7D10", "\uF9D0"=>"\u985E",
- "\uF9D1"=>"\u516D", "\uF9D2"=>"\u622E", "\uF9D3"=>"\u9678", "\uF9D4"=>"\u502B", "\uF9D5"=>"\u5D19", "\uF9D6"=>"\u6DEA", "\uF9D7"=>"\u8F2A", "\uF9D8"=>"\u5F8B",
- "\uF9D9"=>"\u6144", "\uF9DA"=>"\u6817", "\uF9DB"=>"\u7387", "\uF9DC"=>"\u9686", "\uF9DD"=>"\u5229", "\uF9DE"=>"\u540F", "\uF9DF"=>"\u5C65", "\uF9E0"=>"\u6613",
- "\uF9E1"=>"\u674E", "\uF9E2"=>"\u68A8", "\uF9E3"=>"\u6CE5", "\uF9E4"=>"\u7406", "\uF9E5"=>"\u75E2", "\uF9E6"=>"\u7F79", "\uF9E7"=>"\u88CF", "\uF9E8"=>"\u88E1",
- "\uF9E9"=>"\u91CC", "\uF9EA"=>"\u96E2", "\uF9EB"=>"\u533F", "\uF9EC"=>"\u6EBA", "\uF9ED"=>"\u541D", "\uF9EE"=>"\u71D0", "\uF9EF"=>"\u7498", "\uF9F0"=>"\u85FA",
- "\uF9F1"=>"\u96A3", "\uF9F2"=>"\u9C57", "\uF9F3"=>"\u9E9F", "\uF9F4"=>"\u6797", "\uF9F5"=>"\u6DCB", "\uF9F6"=>"\u81E8", "\uF9F7"=>"\u7ACB", "\uF9F8"=>"\u7B20",
- "\uF9F9"=>"\u7C92", "\uF9FA"=>"\u72C0", "\uF9FB"=>"\u7099", "\uF9FC"=>"\u8B58", "\uF9FD"=>"\u4EC0", "\uF9FE"=>"\u8336", "\uF9FF"=>"\u523A", "\uFA00"=>"\u5207",
- "\uFA01"=>"\u5EA6", "\uFA02"=>"\u62D3", "\uFA03"=>"\u7CD6", "\uFA04"=>"\u5B85", "\uFA05"=>"\u6D1E", "\uFA06"=>"\u66B4", "\uFA07"=>"\u8F3B", "\uFA08"=>"\u884C",
- "\uFA09"=>"\u964D", "\uFA0A"=>"\u898B", "\uFA0B"=>"\u5ED3", "\uFA0C"=>"\u5140", "\uFA0D"=>"\u55C0", "\uFA10"=>"\u585A", "\uFA12"=>"\u6674", "\uFA15"=>"\u51DE",
- "\uFA16"=>"\u732A", "\uFA17"=>"\u76CA", "\uFA18"=>"\u793C", "\uFA19"=>"\u795E", "\uFA1A"=>"\u7965", "\uFA1B"=>"\u798F", "\uFA1C"=>"\u9756", "\uFA1D"=>"\u7CBE",
- "\uFA1E"=>"\u7FBD", "\uFA20"=>"\u8612", "\uFA22"=>"\u8AF8", "\uFA25"=>"\u9038", "\uFA26"=>"\u90FD", "\uFA2A"=>"\u98EF", "\uFA2B"=>"\u98FC", "\uFA2C"=>"\u9928",
- "\uFA2D"=>"\u9DB4", "\uFA2E"=>"\u90DE", "\uFA2F"=>"\u96B7", "\uFA30"=>"\u4FAE", "\uFA31"=>"\u50E7", "\uFA32"=>"\u514D", "\uFA33"=>"\u52C9", "\uFA34"=>"\u52E4",
- "\uFA35"=>"\u5351", "\uFA36"=>"\u559D", "\uFA37"=>"\u5606", "\uFA38"=>"\u5668", "\uFA39"=>"\u5840", "\uFA3A"=>"\u58A8", "\uFA3B"=>"\u5C64", "\uFA3C"=>"\u5C6E",
- "\uFA3D"=>"\u6094", "\uFA3E"=>"\u6168", "\uFA3F"=>"\u618E", "\uFA40"=>"\u61F2", "\uFA41"=>"\u654F", "\uFA42"=>"\u65E2", "\uFA43"=>"\u6691", "\uFA44"=>"\u6885",
- "\uFA45"=>"\u6D77", "\uFA46"=>"\u6E1A", "\uFA47"=>"\u6F22", "\uFA48"=>"\u716E", "\uFA49"=>"\u722B", "\uFA4A"=>"\u7422", "\uFA4B"=>"\u7891", "\uFA4C"=>"\u793E",
- "\uFA4D"=>"\u7949", "\uFA4E"=>"\u7948", "\uFA4F"=>"\u7950", "\uFA50"=>"\u7956", "\uFA51"=>"\u795D", "\uFA52"=>"\u798D", "\uFA53"=>"\u798E", "\uFA54"=>"\u7A40",
- "\uFA55"=>"\u7A81", "\uFA56"=>"\u7BC0", "\uFA57"=>"\u7DF4", "\uFA58"=>"\u7E09", "\uFA59"=>"\u7E41", "\uFA5A"=>"\u7F72", "\uFA5B"=>"\u8005", "\uFA5C"=>"\u81ED",
- "\uFA5D"=>"\u8279", "\uFA5E"=>"\u8279", "\uFA5F"=>"\u8457", "\uFA60"=>"\u8910", "\uFA61"=>"\u8996", "\uFA62"=>"\u8B01", "\uFA63"=>"\u8B39", "\uFA64"=>"\u8CD3",
- "\uFA65"=>"\u8D08", "\uFA66"=>"\u8FB6", "\uFA67"=>"\u9038", "\uFA68"=>"\u96E3", "\uFA69"=>"\u97FF", "\uFA6A"=>"\u983B", "\uFA6B"=>"\u6075", "\uFA6C"=>"\u{242EE}",
- "\uFA6D"=>"\u8218", "\uFA70"=>"\u4E26", "\uFA71"=>"\u51B5", "\uFA72"=>"\u5168", "\uFA73"=>"\u4F80", "\uFA74"=>"\u5145", "\uFA75"=>"\u5180", "\uFA76"=>"\u52C7",
- "\uFA77"=>"\u52FA", "\uFA78"=>"\u559D", "\uFA79"=>"\u5555", "\uFA7A"=>"\u5599", "\uFA7B"=>"\u55E2", "\uFA7C"=>"\u585A", "\uFA7D"=>"\u58B3", "\uFA7E"=>"\u5944",
- "\uFA7F"=>"\u5954", "\uFA80"=>"\u5A62", "\uFA81"=>"\u5B28", "\uFA82"=>"\u5ED2", "\uFA83"=>"\u5ED9", "\uFA84"=>"\u5F69", "\uFA85"=>"\u5FAD", "\uFA86"=>"\u60D8",
- "\uFA87"=>"\u614E", "\uFA88"=>"\u6108", "\uFA89"=>"\u618E", "\uFA8A"=>"\u6160", "\uFA8B"=>"\u61F2", "\uFA8C"=>"\u6234", "\uFA8D"=>"\u63C4", "\uFA8E"=>"\u641C",
- "\uFA8F"=>"\u6452", "\uFA90"=>"\u6556", "\uFA91"=>"\u6674", "\uFA92"=>"\u6717", "\uFA93"=>"\u671B", "\uFA94"=>"\u6756", "\uFA95"=>"\u6B79", "\uFA96"=>"\u6BBA",
- "\uFA97"=>"\u6D41", "\uFA98"=>"\u6EDB", "\uFA99"=>"\u6ECB", "\uFA9A"=>"\u6F22", "\uFA9B"=>"\u701E", "\uFA9C"=>"\u716E", "\uFA9D"=>"\u77A7", "\uFA9E"=>"\u7235",
- "\uFA9F"=>"\u72AF", "\uFAA0"=>"\u732A", "\uFAA1"=>"\u7471", "\uFAA2"=>"\u7506", "\uFAA3"=>"\u753B", "\uFAA4"=>"\u761D", "\uFAA5"=>"\u761F", "\uFAA6"=>"\u76CA",
- "\uFAA7"=>"\u76DB", "\uFAA8"=>"\u76F4", "\uFAA9"=>"\u774A", "\uFAAA"=>"\u7740", "\uFAAB"=>"\u78CC", "\uFAAC"=>"\u7AB1", "\uFAAD"=>"\u7BC0", "\uFAAE"=>"\u7C7B",
- "\uFAAF"=>"\u7D5B", "\uFAB0"=>"\u7DF4", "\uFAB1"=>"\u7F3E", "\uFAB2"=>"\u8005", "\uFAB3"=>"\u8352", "\uFAB4"=>"\u83EF", "\uFAB5"=>"\u8779", "\uFAB6"=>"\u8941",
- "\uFAB7"=>"\u8986", "\uFAB8"=>"\u8996", "\uFAB9"=>"\u8ABF", "\uFABA"=>"\u8AF8", "\uFABB"=>"\u8ACB", "\uFABC"=>"\u8B01", "\uFABD"=>"\u8AFE", "\uFABE"=>"\u8AED",
- "\uFABF"=>"\u8B39", "\uFAC0"=>"\u8B8A", "\uFAC1"=>"\u8D08", "\uFAC2"=>"\u8F38", "\uFAC3"=>"\u9072", "\uFAC4"=>"\u9199", "\uFAC5"=>"\u9276", "\uFAC6"=>"\u967C",
- "\uFAC7"=>"\u96E3", "\uFAC8"=>"\u9756", "\uFAC9"=>"\u97DB", "\uFACA"=>"\u97FF", "\uFACB"=>"\u980B", "\uFACC"=>"\u983B", "\uFACD"=>"\u9B12", "\uFACE"=>"\u9F9C",
- "\uFACF"=>"\u{2284A}", "\uFAD0"=>"\u{22844}", "\uFAD1"=>"\u{233D5}", "\uFAD2"=>"\u3B9D", "\uFAD3"=>"\u4018", "\uFAD4"=>"\u4039", "\uFAD5"=>"\u{25249}", "\uFAD6"=>"\u{25CD0}",
- "\uFAD7"=>"\u{27ED3}", "\uFAD8"=>"\u9F43", "\uFAD9"=>"\u9F8E", "\uFB1D"=>"\u05D9\u05B4", "\uFB1F"=>"\u05F2\u05B7", "\uFB2A"=>"\u05E9\u05C1", "\uFB2B"=>"\u05E9\u05C2", "\uFB2C"=>"\u05E9\u05BC\u05C1",
- "\uFB2D"=>"\u05E9\u05BC\u05C2", "\uFB2E"=>"\u05D0\u05B7", "\uFB2F"=>"\u05D0\u05B8", "\uFB30"=>"\u05D0\u05BC", "\uFB31"=>"\u05D1\u05BC", "\uFB32"=>"\u05D2\u05BC", "\uFB33"=>"\u05D3\u05BC", "\uFB34"=>"\u05D4\u05BC",
- "\uFB35"=>"\u05D5\u05BC", "\uFB36"=>"\u05D6\u05BC", "\uFB38"=>"\u05D8\u05BC", "\uFB39"=>"\u05D9\u05BC", "\uFB3A"=>"\u05DA\u05BC", "\uFB3B"=>"\u05DB\u05BC", "\uFB3C"=>"\u05DC\u05BC", "\uFB3E"=>"\u05DE\u05BC",
- "\uFB40"=>"\u05E0\u05BC", "\uFB41"=>"\u05E1\u05BC", "\uFB43"=>"\u05E3\u05BC", "\uFB44"=>"\u05E4\u05BC", "\uFB46"=>"\u05E6\u05BC", "\uFB47"=>"\u05E7\u05BC", "\uFB48"=>"\u05E8\u05BC", "\uFB49"=>"\u05E9\u05BC",
- "\uFB4A"=>"\u05EA\u05BC", "\uFB4B"=>"\u05D5\u05B9", "\uFB4C"=>"\u05D1\u05BF", "\uFB4D"=>"\u05DB\u05BF", "\uFB4E"=>"\u05E4\u05BF", "\u{1109A}"=>"\u{11099}\u{110BA}", "\u{1109C}"=>"\u{1109B}\u{110BA}", "\u{110AB}"=>"\u{110A5}\u{110BA}",
- "\u{1112E}"=>"\u{11131}\u{11127}", "\u{1112F}"=>"\u{11132}\u{11127}", "\u{1134B}"=>"\u{11347}\u{1133E}", "\u{1134C}"=>"\u{11347}\u{11357}", "\u{114BB}"=>"\u{114B9}\u{114BA}", "\u{114BC}"=>"\u{114B9}\u{114B0}", "\u{114BE}"=>"\u{114B9}\u{114BD}", "\u{115BA}"=>"\u{115B8}\u{115AF}",
- "\u{115BB}"=>"\u{115B9}\u{115AF}", "\u{1D15E}"=>"\u{1D157}\u{1D165}", "\u{1D15F}"=>"\u{1D158}\u{1D165}", "\u{1D160}"=>"\u{1D158}\u{1D165}\u{1D16E}", "\u{1D161}"=>"\u{1D158}\u{1D165}\u{1D16F}", "\u{1D162}"=>"\u{1D158}\u{1D165}\u{1D170}", "\u{1D163}"=>"\u{1D158}\u{1D165}\u{1D171}", "\u{1D164}"=>"\u{1D158}\u{1D165}\u{1D172}",
- "\u{1D1BB}"=>"\u{1D1B9}\u{1D165}", "\u{1D1BC}"=>"\u{1D1BA}\u{1D165}", "\u{1D1BD}"=>"\u{1D1B9}\u{1D165}\u{1D16E}", "\u{1D1BE}"=>"\u{1D1BA}\u{1D165}\u{1D16E}", "\u{1D1BF}"=>"\u{1D1B9}\u{1D165}\u{1D16F}", "\u{1D1C0}"=>"\u{1D1BA}\u{1D165}\u{1D16F}", "\u{2F800}"=>"\u4E3D", "\u{2F801}"=>"\u4E38",
- "\u{2F802}"=>"\u4E41", "\u{2F803}"=>"\u{20122}", "\u{2F804}"=>"\u4F60", "\u{2F805}"=>"\u4FAE", "\u{2F806}"=>"\u4FBB", "\u{2F807}"=>"\u5002", "\u{2F808}"=>"\u507A", "\u{2F809}"=>"\u5099",
- "\u{2F80A}"=>"\u50E7", "\u{2F80B}"=>"\u50CF", "\u{2F80C}"=>"\u349E", "\u{2F80D}"=>"\u{2063A}", "\u{2F80E}"=>"\u514D", "\u{2F80F}"=>"\u5154", "\u{2F810}"=>"\u5164", "\u{2F811}"=>"\u5177",
- "\u{2F812}"=>"\u{2051C}", "\u{2F813}"=>"\u34B9", "\u{2F814}"=>"\u5167", "\u{2F815}"=>"\u518D", "\u{2F816}"=>"\u{2054B}", "\u{2F817}"=>"\u5197", "\u{2F818}"=>"\u51A4", "\u{2F819}"=>"\u4ECC",
- "\u{2F81A}"=>"\u51AC", "\u{2F81B}"=>"\u51B5", "\u{2F81C}"=>"\u{291DF}", "\u{2F81D}"=>"\u51F5", "\u{2F81E}"=>"\u5203", "\u{2F81F}"=>"\u34DF", "\u{2F820}"=>"\u523B", "\u{2F821}"=>"\u5246",
- "\u{2F822}"=>"\u5272", "\u{2F823}"=>"\u5277", "\u{2F824}"=>"\u3515", "\u{2F825}"=>"\u52C7", "\u{2F826}"=>"\u52C9", "\u{2F827}"=>"\u52E4", "\u{2F828}"=>"\u52FA", "\u{2F829}"=>"\u5305",
- "\u{2F82A}"=>"\u5306", "\u{2F82B}"=>"\u5317", "\u{2F82C}"=>"\u5349", "\u{2F82D}"=>"\u5351", "\u{2F82E}"=>"\u535A", "\u{2F82F}"=>"\u5373", "\u{2F830}"=>"\u537D", "\u{2F831}"=>"\u537F",
- "\u{2F832}"=>"\u537F", "\u{2F833}"=>"\u537F", "\u{2F834}"=>"\u{20A2C}", "\u{2F835}"=>"\u7070", "\u{2F836}"=>"\u53CA", "\u{2F837}"=>"\u53DF", "\u{2F838}"=>"\u{20B63}", "\u{2F839}"=>"\u53EB",
- "\u{2F83A}"=>"\u53F1", "\u{2F83B}"=>"\u5406", "\u{2F83C}"=>"\u549E", "\u{2F83D}"=>"\u5438", "\u{2F83E}"=>"\u5448", "\u{2F83F}"=>"\u5468", "\u{2F840}"=>"\u54A2", "\u{2F841}"=>"\u54F6",
- "\u{2F842}"=>"\u5510", "\u{2F843}"=>"\u5553", "\u{2F844}"=>"\u5563", "\u{2F845}"=>"\u5584", "\u{2F846}"=>"\u5584", "\u{2F847}"=>"\u5599", "\u{2F848}"=>"\u55AB", "\u{2F849}"=>"\u55B3",
- "\u{2F84A}"=>"\u55C2", "\u{2F84B}"=>"\u5716", "\u{2F84C}"=>"\u5606", "\u{2F84D}"=>"\u5717", "\u{2F84E}"=>"\u5651", "\u{2F84F}"=>"\u5674", "\u{2F850}"=>"\u5207", "\u{2F851}"=>"\u58EE",
- "\u{2F852}"=>"\u57CE", "\u{2F853}"=>"\u57F4", "\u{2F854}"=>"\u580D", "\u{2F855}"=>"\u578B", "\u{2F856}"=>"\u5832", "\u{2F857}"=>"\u5831", "\u{2F858}"=>"\u58AC", "\u{2F859}"=>"\u{214E4}",
- "\u{2F85A}"=>"\u58F2", "\u{2F85B}"=>"\u58F7", "\u{2F85C}"=>"\u5906", "\u{2F85D}"=>"\u591A", "\u{2F85E}"=>"\u5922", "\u{2F85F}"=>"\u5962", "\u{2F860}"=>"\u{216A8}", "\u{2F861}"=>"\u{216EA}",
- "\u{2F862}"=>"\u59EC", "\u{2F863}"=>"\u5A1B", "\u{2F864}"=>"\u5A27", "\u{2F865}"=>"\u59D8", "\u{2F866}"=>"\u5A66", "\u{2F867}"=>"\u36EE", "\u{2F868}"=>"\u36FC", "\u{2F869}"=>"\u5B08",
- "\u{2F86A}"=>"\u5B3E", "\u{2F86B}"=>"\u5B3E", "\u{2F86C}"=>"\u{219C8}", "\u{2F86D}"=>"\u5BC3", "\u{2F86E}"=>"\u5BD8", "\u{2F86F}"=>"\u5BE7", "\u{2F870}"=>"\u5BF3", "\u{2F871}"=>"\u{21B18}",
- "\u{2F872}"=>"\u5BFF", "\u{2F873}"=>"\u5C06", "\u{2F874}"=>"\u5F53", "\u{2F875}"=>"\u5C22", "\u{2F876}"=>"\u3781", "\u{2F877}"=>"\u5C60", "\u{2F878}"=>"\u5C6E", "\u{2F879}"=>"\u5CC0",
- "\u{2F87A}"=>"\u5C8D", "\u{2F87B}"=>"\u{21DE4}", "\u{2F87C}"=>"\u5D43", "\u{2F87D}"=>"\u{21DE6}", "\u{2F87E}"=>"\u5D6E", "\u{2F87F}"=>"\u5D6B", "\u{2F880}"=>"\u5D7C", "\u{2F881}"=>"\u5DE1",
- "\u{2F882}"=>"\u5DE2", "\u{2F883}"=>"\u382F", "\u{2F884}"=>"\u5DFD", "\u{2F885}"=>"\u5E28", "\u{2F886}"=>"\u5E3D", "\u{2F887}"=>"\u5E69", "\u{2F888}"=>"\u3862", "\u{2F889}"=>"\u{22183}",
- "\u{2F88A}"=>"\u387C", "\u{2F88B}"=>"\u5EB0", "\u{2F88C}"=>"\u5EB3", "\u{2F88D}"=>"\u5EB6", "\u{2F88E}"=>"\u5ECA", "\u{2F88F}"=>"\u{2A392}", "\u{2F890}"=>"\u5EFE", "\u{2F891}"=>"\u{22331}",
- "\u{2F892}"=>"\u{22331}", "\u{2F893}"=>"\u8201", "\u{2F894}"=>"\u5F22", "\u{2F895}"=>"\u5F22", "\u{2F896}"=>"\u38C7", "\u{2F897}"=>"\u{232B8}", "\u{2F898}"=>"\u{261DA}", "\u{2F899}"=>"\u5F62",
- "\u{2F89A}"=>"\u5F6B", "\u{2F89B}"=>"\u38E3", "\u{2F89C}"=>"\u5F9A", "\u{2F89D}"=>"\u5FCD", "\u{2F89E}"=>"\u5FD7", "\u{2F89F}"=>"\u5FF9", "\u{2F8A0}"=>"\u6081", "\u{2F8A1}"=>"\u393A",
- "\u{2F8A2}"=>"\u391C", "\u{2F8A3}"=>"\u6094", "\u{2F8A4}"=>"\u{226D4}", "\u{2F8A5}"=>"\u60C7", "\u{2F8A6}"=>"\u6148", "\u{2F8A7}"=>"\u614C", "\u{2F8A8}"=>"\u614E", "\u{2F8A9}"=>"\u614C",
- "\u{2F8AA}"=>"\u617A", "\u{2F8AB}"=>"\u618E", "\u{2F8AC}"=>"\u61B2", "\u{2F8AD}"=>"\u61A4", "\u{2F8AE}"=>"\u61AF", "\u{2F8AF}"=>"\u61DE", "\u{2F8B0}"=>"\u61F2", "\u{2F8B1}"=>"\u61F6",
- "\u{2F8B2}"=>"\u6210", "\u{2F8B3}"=>"\u621B", "\u{2F8B4}"=>"\u625D", "\u{2F8B5}"=>"\u62B1", "\u{2F8B6}"=>"\u62D4", "\u{2F8B7}"=>"\u6350", "\u{2F8B8}"=>"\u{22B0C}", "\u{2F8B9}"=>"\u633D",
- "\u{2F8BA}"=>"\u62FC", "\u{2F8BB}"=>"\u6368", "\u{2F8BC}"=>"\u6383", "\u{2F8BD}"=>"\u63E4", "\u{2F8BE}"=>"\u{22BF1}", "\u{2F8BF}"=>"\u6422", "\u{2F8C0}"=>"\u63C5", "\u{2F8C1}"=>"\u63A9",
- "\u{2F8C2}"=>"\u3A2E", "\u{2F8C3}"=>"\u6469", "\u{2F8C4}"=>"\u647E", "\u{2F8C5}"=>"\u649D", "\u{2F8C6}"=>"\u6477", "\u{2F8C7}"=>"\u3A6C", "\u{2F8C8}"=>"\u654F", "\u{2F8C9}"=>"\u656C",
- "\u{2F8CA}"=>"\u{2300A}", "\u{2F8CB}"=>"\u65E3", "\u{2F8CC}"=>"\u66F8", "\u{2F8CD}"=>"\u6649", "\u{2F8CE}"=>"\u3B19", "\u{2F8CF}"=>"\u6691", "\u{2F8D0}"=>"\u3B08", "\u{2F8D1}"=>"\u3AE4",
- "\u{2F8D2}"=>"\u5192", "\u{2F8D3}"=>"\u5195", "\u{2F8D4}"=>"\u6700", "\u{2F8D5}"=>"\u669C", "\u{2F8D6}"=>"\u80AD", "\u{2F8D7}"=>"\u43D9", "\u{2F8D8}"=>"\u6717", "\u{2F8D9}"=>"\u671B",
- "\u{2F8DA}"=>"\u6721", "\u{2F8DB}"=>"\u675E", "\u{2F8DC}"=>"\u6753", "\u{2F8DD}"=>"\u{233C3}", "\u{2F8DE}"=>"\u3B49", "\u{2F8DF}"=>"\u67FA", "\u{2F8E0}"=>"\u6785", "\u{2F8E1}"=>"\u6852",
- "\u{2F8E2}"=>"\u6885", "\u{2F8E3}"=>"\u{2346D}", "\u{2F8E4}"=>"\u688E", "\u{2F8E5}"=>"\u681F", "\u{2F8E6}"=>"\u6914", "\u{2F8E7}"=>"\u3B9D", "\u{2F8E8}"=>"\u6942", "\u{2F8E9}"=>"\u69A3",
- "\u{2F8EA}"=>"\u69EA", "\u{2F8EB}"=>"\u6AA8", "\u{2F8EC}"=>"\u{236A3}", "\u{2F8ED}"=>"\u6ADB", "\u{2F8EE}"=>"\u3C18", "\u{2F8EF}"=>"\u6B21", "\u{2F8F0}"=>"\u{238A7}", "\u{2F8F1}"=>"\u6B54",
- "\u{2F8F2}"=>"\u3C4E", "\u{2F8F3}"=>"\u6B72", "\u{2F8F4}"=>"\u6B9F", "\u{2F8F5}"=>"\u6BBA", "\u{2F8F6}"=>"\u6BBB", "\u{2F8F7}"=>"\u{23A8D}", "\u{2F8F8}"=>"\u{21D0B}", "\u{2F8F9}"=>"\u{23AFA}",
- "\u{2F8FA}"=>"\u6C4E", "\u{2F8FB}"=>"\u{23CBC}", "\u{2F8FC}"=>"\u6CBF", "\u{2F8FD}"=>"\u6CCD", "\u{2F8FE}"=>"\u6C67", "\u{2F8FF}"=>"\u6D16", "\u{2F900}"=>"\u6D3E", "\u{2F901}"=>"\u6D77",
- "\u{2F902}"=>"\u6D41", "\u{2F903}"=>"\u6D69", "\u{2F904}"=>"\u6D78", "\u{2F905}"=>"\u6D85", "\u{2F906}"=>"\u{23D1E}", "\u{2F907}"=>"\u6D34", "\u{2F908}"=>"\u6E2F", "\u{2F909}"=>"\u6E6E",
- "\u{2F90A}"=>"\u3D33", "\u{2F90B}"=>"\u6ECB", "\u{2F90C}"=>"\u6EC7", "\u{2F90D}"=>"\u{23ED1}", "\u{2F90E}"=>"\u6DF9", "\u{2F90F}"=>"\u6F6E", "\u{2F910}"=>"\u{23F5E}", "\u{2F911}"=>"\u{23F8E}",
- "\u{2F912}"=>"\u6FC6", "\u{2F913}"=>"\u7039", "\u{2F914}"=>"\u701E", "\u{2F915}"=>"\u701B", "\u{2F916}"=>"\u3D96", "\u{2F917}"=>"\u704A", "\u{2F918}"=>"\u707D", "\u{2F919}"=>"\u7077",
- "\u{2F91A}"=>"\u70AD", "\u{2F91B}"=>"\u{20525}", "\u{2F91C}"=>"\u7145", "\u{2F91D}"=>"\u{24263}", "\u{2F91E}"=>"\u719C", "\u{2F91F}"=>"\u{243AB}", "\u{2F920}"=>"\u7228", "\u{2F921}"=>"\u7235",
- "\u{2F922}"=>"\u7250", "\u{2F923}"=>"\u{24608}", "\u{2F924}"=>"\u7280", "\u{2F925}"=>"\u7295", "\u{2F926}"=>"\u{24735}", "\u{2F927}"=>"\u{24814}", "\u{2F928}"=>"\u737A", "\u{2F929}"=>"\u738B",
- "\u{2F92A}"=>"\u3EAC", "\u{2F92B}"=>"\u73A5", "\u{2F92C}"=>"\u3EB8", "\u{2F92D}"=>"\u3EB8", "\u{2F92E}"=>"\u7447", "\u{2F92F}"=>"\u745C", "\u{2F930}"=>"\u7471", "\u{2F931}"=>"\u7485",
- "\u{2F932}"=>"\u74CA", "\u{2F933}"=>"\u3F1B", "\u{2F934}"=>"\u7524", "\u{2F935}"=>"\u{24C36}", "\u{2F936}"=>"\u753E", "\u{2F937}"=>"\u{24C92}", "\u{2F938}"=>"\u7570", "\u{2F939}"=>"\u{2219F}",
- "\u{2F93A}"=>"\u7610", "\u{2F93B}"=>"\u{24FA1}", "\u{2F93C}"=>"\u{24FB8}", "\u{2F93D}"=>"\u{25044}", "\u{2F93E}"=>"\u3FFC", "\u{2F93F}"=>"\u4008", "\u{2F940}"=>"\u76F4", "\u{2F941}"=>"\u{250F3}",
- "\u{2F942}"=>"\u{250F2}", "\u{2F943}"=>"\u{25119}", "\u{2F944}"=>"\u{25133}", "\u{2F945}"=>"\u771E", "\u{2F946}"=>"\u771F", "\u{2F947}"=>"\u771F", "\u{2F948}"=>"\u774A", "\u{2F949}"=>"\u4039",
- "\u{2F94A}"=>"\u778B", "\u{2F94B}"=>"\u4046", "\u{2F94C}"=>"\u4096", "\u{2F94D}"=>"\u{2541D}", "\u{2F94E}"=>"\u784E", "\u{2F94F}"=>"\u788C", "\u{2F950}"=>"\u78CC", "\u{2F951}"=>"\u40E3",
- "\u{2F952}"=>"\u{25626}", "\u{2F953}"=>"\u7956", "\u{2F954}"=>"\u{2569A}", "\u{2F955}"=>"\u{256C5}", "\u{2F956}"=>"\u798F", "\u{2F957}"=>"\u79EB", "\u{2F958}"=>"\u412F", "\u{2F959}"=>"\u7A40",
- "\u{2F95A}"=>"\u7A4A", "\u{2F95B}"=>"\u7A4F", "\u{2F95C}"=>"\u{2597C}", "\u{2F95D}"=>"\u{25AA7}", "\u{2F95E}"=>"\u{25AA7}", "\u{2F95F}"=>"\u7AEE", "\u{2F960}"=>"\u4202", "\u{2F961}"=>"\u{25BAB}",
- "\u{2F962}"=>"\u7BC6", "\u{2F963}"=>"\u7BC9", "\u{2F964}"=>"\u4227", "\u{2F965}"=>"\u{25C80}", "\u{2F966}"=>"\u7CD2", "\u{2F967}"=>"\u42A0", "\u{2F968}"=>"\u7CE8", "\u{2F969}"=>"\u7CE3",
- "\u{2F96A}"=>"\u7D00", "\u{2F96B}"=>"\u{25F86}", "\u{2F96C}"=>"\u7D63", "\u{2F96D}"=>"\u4301", "\u{2F96E}"=>"\u7DC7", "\u{2F96F}"=>"\u7E02", "\u{2F970}"=>"\u7E45", "\u{2F971}"=>"\u4334",
- "\u{2F972}"=>"\u{26228}", "\u{2F973}"=>"\u{26247}", "\u{2F974}"=>"\u4359", "\u{2F975}"=>"\u{262D9}", "\u{2F976}"=>"\u7F7A", "\u{2F977}"=>"\u{2633E}", "\u{2F978}"=>"\u7F95", "\u{2F979}"=>"\u7FFA",
- "\u{2F97A}"=>"\u8005", "\u{2F97B}"=>"\u{264DA}", "\u{2F97C}"=>"\u{26523}", "\u{2F97D}"=>"\u8060", "\u{2F97E}"=>"\u{265A8}", "\u{2F97F}"=>"\u8070", "\u{2F980}"=>"\u{2335F}", "\u{2F981}"=>"\u43D5",
- "\u{2F982}"=>"\u80B2", "\u{2F983}"=>"\u8103", "\u{2F984}"=>"\u440B", "\u{2F985}"=>"\u813E", "\u{2F986}"=>"\u5AB5", "\u{2F987}"=>"\u{267A7}", "\u{2F988}"=>"\u{267B5}", "\u{2F989}"=>"\u{23393}",
- "\u{2F98A}"=>"\u{2339C}", "\u{2F98B}"=>"\u8201", "\u{2F98C}"=>"\u8204", "\u{2F98D}"=>"\u8F9E", "\u{2F98E}"=>"\u446B", "\u{2F98F}"=>"\u8291", "\u{2F990}"=>"\u828B", "\u{2F991}"=>"\u829D",
- "\u{2F992}"=>"\u52B3", "\u{2F993}"=>"\u82B1", "\u{2F994}"=>"\u82B3", "\u{2F995}"=>"\u82BD", "\u{2F996}"=>"\u82E6", "\u{2F997}"=>"\u{26B3C}", "\u{2F998}"=>"\u82E5", "\u{2F999}"=>"\u831D",
- "\u{2F99A}"=>"\u8363", "\u{2F99B}"=>"\u83AD", "\u{2F99C}"=>"\u8323", "\u{2F99D}"=>"\u83BD", "\u{2F99E}"=>"\u83E7", "\u{2F99F}"=>"\u8457", "\u{2F9A0}"=>"\u8353", "\u{2F9A1}"=>"\u83CA",
- "\u{2F9A2}"=>"\u83CC", "\u{2F9A3}"=>"\u83DC", "\u{2F9A4}"=>"\u{26C36}", "\u{2F9A5}"=>"\u{26D6B}", "\u{2F9A6}"=>"\u{26CD5}", "\u{2F9A7}"=>"\u452B", "\u{2F9A8}"=>"\u84F1", "\u{2F9A9}"=>"\u84F3",
- "\u{2F9AA}"=>"\u8516", "\u{2F9AB}"=>"\u{273CA}", "\u{2F9AC}"=>"\u8564", "\u{2F9AD}"=>"\u{26F2C}", "\u{2F9AE}"=>"\u455D", "\u{2F9AF}"=>"\u4561", "\u{2F9B0}"=>"\u{26FB1}", "\u{2F9B1}"=>"\u{270D2}",
- "\u{2F9B2}"=>"\u456B", "\u{2F9B3}"=>"\u8650", "\u{2F9B4}"=>"\u865C", "\u{2F9B5}"=>"\u8667", "\u{2F9B6}"=>"\u8669", "\u{2F9B7}"=>"\u86A9", "\u{2F9B8}"=>"\u8688", "\u{2F9B9}"=>"\u870E",
- "\u{2F9BA}"=>"\u86E2", "\u{2F9BB}"=>"\u8779", "\u{2F9BC}"=>"\u8728", "\u{2F9BD}"=>"\u876B", "\u{2F9BE}"=>"\u8786", "\u{2F9BF}"=>"\u45D7", "\u{2F9C0}"=>"\u87E1", "\u{2F9C1}"=>"\u8801",
- "\u{2F9C2}"=>"\u45F9", "\u{2F9C3}"=>"\u8860", "\u{2F9C4}"=>"\u8863", "\u{2F9C5}"=>"\u{27667}", "\u{2F9C6}"=>"\u88D7", "\u{2F9C7}"=>"\u88DE", "\u{2F9C8}"=>"\u4635", "\u{2F9C9}"=>"\u88FA",
- "\u{2F9CA}"=>"\u34BB", "\u{2F9CB}"=>"\u{278AE}", "\u{2F9CC}"=>"\u{27966}", "\u{2F9CD}"=>"\u46BE", "\u{2F9CE}"=>"\u46C7", "\u{2F9CF}"=>"\u8AA0", "\u{2F9D0}"=>"\u8AED", "\u{2F9D1}"=>"\u8B8A",
- "\u{2F9D2}"=>"\u8C55", "\u{2F9D3}"=>"\u{27CA8}", "\u{2F9D4}"=>"\u8CAB", "\u{2F9D5}"=>"\u8CC1", "\u{2F9D6}"=>"\u8D1B", "\u{2F9D7}"=>"\u8D77", "\u{2F9D8}"=>"\u{27F2F}", "\u{2F9D9}"=>"\u{20804}",
- "\u{2F9DA}"=>"\u8DCB", "\u{2F9DB}"=>"\u8DBC", "\u{2F9DC}"=>"\u8DF0", "\u{2F9DD}"=>"\u{208DE}", "\u{2F9DE}"=>"\u8ED4", "\u{2F9DF}"=>"\u8F38", "\u{2F9E0}"=>"\u{285D2}", "\u{2F9E1}"=>"\u{285ED}",
- "\u{2F9E2}"=>"\u9094", "\u{2F9E3}"=>"\u90F1", "\u{2F9E4}"=>"\u9111", "\u{2F9E5}"=>"\u{2872E}", "\u{2F9E6}"=>"\u911B", "\u{2F9E7}"=>"\u9238", "\u{2F9E8}"=>"\u92D7", "\u{2F9E9}"=>"\u92D8",
- "\u{2F9EA}"=>"\u927C", "\u{2F9EB}"=>"\u93F9", "\u{2F9EC}"=>"\u9415", "\u{2F9ED}"=>"\u{28BFA}", "\u{2F9EE}"=>"\u958B", "\u{2F9EF}"=>"\u4995", "\u{2F9F0}"=>"\u95B7", "\u{2F9F1}"=>"\u{28D77}",
- "\u{2F9F2}"=>"\u49E6", "\u{2F9F3}"=>"\u96C3", "\u{2F9F4}"=>"\u5DB2", "\u{2F9F5}"=>"\u9723", "\u{2F9F6}"=>"\u{29145}", "\u{2F9F7}"=>"\u{2921A}", "\u{2F9F8}"=>"\u4A6E", "\u{2F9F9}"=>"\u4A76",
- "\u{2F9FA}"=>"\u97E0", "\u{2F9FB}"=>"\u{2940A}", "\u{2F9FC}"=>"\u4AB2", "\u{2F9FD}"=>"\u{29496}", "\u{2F9FE}"=>"\u980B", "\u{2F9FF}"=>"\u980B", "\u{2FA00}"=>"\u9829", "\u{2FA01}"=>"\u{295B6}",
- "\u{2FA02}"=>"\u98E2", "\u{2FA03}"=>"\u4B33", "\u{2FA04}"=>"\u9929", "\u{2FA05}"=>"\u99A7", "\u{2FA06}"=>"\u99C2", "\u{2FA07}"=>"\u99FE", "\u{2FA08}"=>"\u4BCE", "\u{2FA09}"=>"\u{29B30}",
- "\u{2FA0A}"=>"\u9B12", "\u{2FA0B}"=>"\u9C40", "\u{2FA0C}"=>"\u9CFD", "\u{2FA0D}"=>"\u4CCE", "\u{2FA0E}"=>"\u4CED", "\u{2FA0F}"=>"\u9D67", "\u{2FA10}"=>"\u{2A0CE}", "\u{2FA11}"=>"\u4CF8",
- "\u{2FA12}"=>"\u{2A105}", "\u{2FA13}"=>"\u{2A20E}", "\u{2FA14}"=>"\u{2A291}", "\u{2FA15}"=>"\u9EBB", "\u{2FA16}"=>"\u4D56", "\u{2FA17}"=>"\u9EF9", "\u{2FA18}"=>"\u9EFE", "\u{2FA19}"=>"\u9F05",
- "\u{2FA1A}"=>"\u9F0F", "\u{2FA1B}"=>"\u9F16", "\u{2FA1C}"=>"\u9F3B", "\u{2FA1D}"=>"\u{2A600}",
+ "\u00C0"=>"A\u0300",
+ "\u00C1"=>"A\u0301",
+ "\u00C2"=>"A\u0302",
+ "\u00C3"=>"A\u0303",
+ "\u00C4"=>"A\u0308",
+ "\u00C5"=>"A\u030A",
+ "\u00C7"=>"C\u0327",
+ "\u00C8"=>"E\u0300",
+ "\u00C9"=>"E\u0301",
+ "\u00CA"=>"E\u0302",
+ "\u00CB"=>"E\u0308",
+ "\u00CC"=>"I\u0300",
+ "\u00CD"=>"I\u0301",
+ "\u00CE"=>"I\u0302",
+ "\u00CF"=>"I\u0308",
+ "\u00D1"=>"N\u0303",
+ "\u00D2"=>"O\u0300",
+ "\u00D3"=>"O\u0301",
+ "\u00D4"=>"O\u0302",
+ "\u00D5"=>"O\u0303",
+ "\u00D6"=>"O\u0308",
+ "\u00D9"=>"U\u0300",
+ "\u00DA"=>"U\u0301",
+ "\u00DB"=>"U\u0302",
+ "\u00DC"=>"U\u0308",
+ "\u00DD"=>"Y\u0301",
+ "\u00E0"=>"a\u0300",
+ "\u00E1"=>"a\u0301",
+ "\u00E2"=>"a\u0302",
+ "\u00E3"=>"a\u0303",
+ "\u00E4"=>"a\u0308",
+ "\u00E5"=>"a\u030A",
+ "\u00E7"=>"c\u0327",
+ "\u00E8"=>"e\u0300",
+ "\u00E9"=>"e\u0301",
+ "\u00EA"=>"e\u0302",
+ "\u00EB"=>"e\u0308",
+ "\u00EC"=>"i\u0300",
+ "\u00ED"=>"i\u0301",
+ "\u00EE"=>"i\u0302",
+ "\u00EF"=>"i\u0308",
+ "\u00F1"=>"n\u0303",
+ "\u00F2"=>"o\u0300",
+ "\u00F3"=>"o\u0301",
+ "\u00F4"=>"o\u0302",
+ "\u00F5"=>"o\u0303",
+ "\u00F6"=>"o\u0308",
+ "\u00F9"=>"u\u0300",
+ "\u00FA"=>"u\u0301",
+ "\u00FB"=>"u\u0302",
+ "\u00FC"=>"u\u0308",
+ "\u00FD"=>"y\u0301",
+ "\u00FF"=>"y\u0308",
+ "\u0100"=>"A\u0304",
+ "\u0101"=>"a\u0304",
+ "\u0102"=>"A\u0306",
+ "\u0103"=>"a\u0306",
+ "\u0104"=>"A\u0328",
+ "\u0105"=>"a\u0328",
+ "\u0106"=>"C\u0301",
+ "\u0107"=>"c\u0301",
+ "\u0108"=>"C\u0302",
+ "\u0109"=>"c\u0302",
+ "\u010A"=>"C\u0307",
+ "\u010B"=>"c\u0307",
+ "\u010C"=>"C\u030C",
+ "\u010D"=>"c\u030C",
+ "\u010E"=>"D\u030C",
+ "\u010F"=>"d\u030C",
+ "\u0112"=>"E\u0304",
+ "\u0113"=>"e\u0304",
+ "\u0114"=>"E\u0306",
+ "\u0115"=>"e\u0306",
+ "\u0116"=>"E\u0307",
+ "\u0117"=>"e\u0307",
+ "\u0118"=>"E\u0328",
+ "\u0119"=>"e\u0328",
+ "\u011A"=>"E\u030C",
+ "\u011B"=>"e\u030C",
+ "\u011C"=>"G\u0302",
+ "\u011D"=>"g\u0302",
+ "\u011E"=>"G\u0306",
+ "\u011F"=>"g\u0306",
+ "\u0120"=>"G\u0307",
+ "\u0121"=>"g\u0307",
+ "\u0122"=>"G\u0327",
+ "\u0123"=>"g\u0327",
+ "\u0124"=>"H\u0302",
+ "\u0125"=>"h\u0302",
+ "\u0128"=>"I\u0303",
+ "\u0129"=>"i\u0303",
+ "\u012A"=>"I\u0304",
+ "\u012B"=>"i\u0304",
+ "\u012C"=>"I\u0306",
+ "\u012D"=>"i\u0306",
+ "\u012E"=>"I\u0328",
+ "\u012F"=>"i\u0328",
+ "\u0130"=>"I\u0307",
+ "\u0134"=>"J\u0302",
+ "\u0135"=>"j\u0302",
+ "\u0136"=>"K\u0327",
+ "\u0137"=>"k\u0327",
+ "\u0139"=>"L\u0301",
+ "\u013A"=>"l\u0301",
+ "\u013B"=>"L\u0327",
+ "\u013C"=>"l\u0327",
+ "\u013D"=>"L\u030C",
+ "\u013E"=>"l\u030C",
+ "\u0143"=>"N\u0301",
+ "\u0144"=>"n\u0301",
+ "\u0145"=>"N\u0327",
+ "\u0146"=>"n\u0327",
+ "\u0147"=>"N\u030C",
+ "\u0148"=>"n\u030C",
+ "\u014C"=>"O\u0304",
+ "\u014D"=>"o\u0304",
+ "\u014E"=>"O\u0306",
+ "\u014F"=>"o\u0306",
+ "\u0150"=>"O\u030B",
+ "\u0151"=>"o\u030B",
+ "\u0154"=>"R\u0301",
+ "\u0155"=>"r\u0301",
+ "\u0156"=>"R\u0327",
+ "\u0157"=>"r\u0327",
+ "\u0158"=>"R\u030C",
+ "\u0159"=>"r\u030C",
+ "\u015A"=>"S\u0301",
+ "\u015B"=>"s\u0301",
+ "\u015C"=>"S\u0302",
+ "\u015D"=>"s\u0302",
+ "\u015E"=>"S\u0327",
+ "\u015F"=>"s\u0327",
+ "\u0160"=>"S\u030C",
+ "\u0161"=>"s\u030C",
+ "\u0162"=>"T\u0327",
+ "\u0163"=>"t\u0327",
+ "\u0164"=>"T\u030C",
+ "\u0165"=>"t\u030C",
+ "\u0168"=>"U\u0303",
+ "\u0169"=>"u\u0303",
+ "\u016A"=>"U\u0304",
+ "\u016B"=>"u\u0304",
+ "\u016C"=>"U\u0306",
+ "\u016D"=>"u\u0306",
+ "\u016E"=>"U\u030A",
+ "\u016F"=>"u\u030A",
+ "\u0170"=>"U\u030B",
+ "\u0171"=>"u\u030B",
+ "\u0172"=>"U\u0328",
+ "\u0173"=>"u\u0328",
+ "\u0174"=>"W\u0302",
+ "\u0175"=>"w\u0302",
+ "\u0176"=>"Y\u0302",
+ "\u0177"=>"y\u0302",
+ "\u0178"=>"Y\u0308",
+ "\u0179"=>"Z\u0301",
+ "\u017A"=>"z\u0301",
+ "\u017B"=>"Z\u0307",
+ "\u017C"=>"z\u0307",
+ "\u017D"=>"Z\u030C",
+ "\u017E"=>"z\u030C",
+ "\u01A0"=>"O\u031B",
+ "\u01A1"=>"o\u031B",
+ "\u01AF"=>"U\u031B",
+ "\u01B0"=>"u\u031B",
+ "\u01CD"=>"A\u030C",
+ "\u01CE"=>"a\u030C",
+ "\u01CF"=>"I\u030C",
+ "\u01D0"=>"i\u030C",
+ "\u01D1"=>"O\u030C",
+ "\u01D2"=>"o\u030C",
+ "\u01D3"=>"U\u030C",
+ "\u01D4"=>"u\u030C",
+ "\u01D5"=>"U\u0308\u0304",
+ "\u01D6"=>"u\u0308\u0304",
+ "\u01D7"=>"U\u0308\u0301",
+ "\u01D8"=>"u\u0308\u0301",
+ "\u01D9"=>"U\u0308\u030C",
+ "\u01DA"=>"u\u0308\u030C",
+ "\u01DB"=>"U\u0308\u0300",
+ "\u01DC"=>"u\u0308\u0300",
+ "\u01DE"=>"A\u0308\u0304",
+ "\u01DF"=>"a\u0308\u0304",
+ "\u01E0"=>"A\u0307\u0304",
+ "\u01E1"=>"a\u0307\u0304",
+ "\u01E2"=>"\u00C6\u0304",
+ "\u01E3"=>"\u00E6\u0304",
+ "\u01E6"=>"G\u030C",
+ "\u01E7"=>"g\u030C",
+ "\u01E8"=>"K\u030C",
+ "\u01E9"=>"k\u030C",
+ "\u01EA"=>"O\u0328",
+ "\u01EB"=>"o\u0328",
+ "\u01EC"=>"O\u0328\u0304",
+ "\u01ED"=>"o\u0328\u0304",
+ "\u01EE"=>"\u01B7\u030C",
+ "\u01EF"=>"\u0292\u030C",
+ "\u01F0"=>"j\u030C",
+ "\u01F4"=>"G\u0301",
+ "\u01F5"=>"g\u0301",
+ "\u01F8"=>"N\u0300",
+ "\u01F9"=>"n\u0300",
+ "\u01FA"=>"A\u030A\u0301",
+ "\u01FB"=>"a\u030A\u0301",
+ "\u01FC"=>"\u00C6\u0301",
+ "\u01FD"=>"\u00E6\u0301",
+ "\u01FE"=>"\u00D8\u0301",
+ "\u01FF"=>"\u00F8\u0301",
+ "\u0200"=>"A\u030F",
+ "\u0201"=>"a\u030F",
+ "\u0202"=>"A\u0311",
+ "\u0203"=>"a\u0311",
+ "\u0204"=>"E\u030F",
+ "\u0205"=>"e\u030F",
+ "\u0206"=>"E\u0311",
+ "\u0207"=>"e\u0311",
+ "\u0208"=>"I\u030F",
+ "\u0209"=>"i\u030F",
+ "\u020A"=>"I\u0311",
+ "\u020B"=>"i\u0311",
+ "\u020C"=>"O\u030F",
+ "\u020D"=>"o\u030F",
+ "\u020E"=>"O\u0311",
+ "\u020F"=>"o\u0311",
+ "\u0210"=>"R\u030F",
+ "\u0211"=>"r\u030F",
+ "\u0212"=>"R\u0311",
+ "\u0213"=>"r\u0311",
+ "\u0214"=>"U\u030F",
+ "\u0215"=>"u\u030F",
+ "\u0216"=>"U\u0311",
+ "\u0217"=>"u\u0311",
+ "\u0218"=>"S\u0326",
+ "\u0219"=>"s\u0326",
+ "\u021A"=>"T\u0326",
+ "\u021B"=>"t\u0326",
+ "\u021E"=>"H\u030C",
+ "\u021F"=>"h\u030C",
+ "\u0226"=>"A\u0307",
+ "\u0227"=>"a\u0307",
+ "\u0228"=>"E\u0327",
+ "\u0229"=>"e\u0327",
+ "\u022A"=>"O\u0308\u0304",
+ "\u022B"=>"o\u0308\u0304",
+ "\u022C"=>"O\u0303\u0304",
+ "\u022D"=>"o\u0303\u0304",
+ "\u022E"=>"O\u0307",
+ "\u022F"=>"o\u0307",
+ "\u0230"=>"O\u0307\u0304",
+ "\u0231"=>"o\u0307\u0304",
+ "\u0232"=>"Y\u0304",
+ "\u0233"=>"y\u0304",
+ "\u0340"=>"\u0300",
+ "\u0341"=>"\u0301",
+ "\u0343"=>"\u0313",
+ "\u0344"=>"\u0308\u0301",
+ "\u0374"=>"\u02B9",
+ "\u037E"=>";",
+ "\u0385"=>"\u00A8\u0301",
+ "\u0386"=>"\u0391\u0301",
+ "\u0387"=>"\u00B7",
+ "\u0388"=>"\u0395\u0301",
+ "\u0389"=>"\u0397\u0301",
+ "\u038A"=>"\u0399\u0301",
+ "\u038C"=>"\u039F\u0301",
+ "\u038E"=>"\u03A5\u0301",
+ "\u038F"=>"\u03A9\u0301",
+ "\u0390"=>"\u03B9\u0308\u0301",
+ "\u03AA"=>"\u0399\u0308",
+ "\u03AB"=>"\u03A5\u0308",
+ "\u03AC"=>"\u03B1\u0301",
+ "\u03AD"=>"\u03B5\u0301",
+ "\u03AE"=>"\u03B7\u0301",
+ "\u03AF"=>"\u03B9\u0301",
+ "\u03B0"=>"\u03C5\u0308\u0301",
+ "\u03CA"=>"\u03B9\u0308",
+ "\u03CB"=>"\u03C5\u0308",
+ "\u03CC"=>"\u03BF\u0301",
+ "\u03CD"=>"\u03C5\u0301",
+ "\u03CE"=>"\u03C9\u0301",
+ "\u03D3"=>"\u03D2\u0301",
+ "\u03D4"=>"\u03D2\u0308",
+ "\u0400"=>"\u0415\u0300",
+ "\u0401"=>"\u0415\u0308",
+ "\u0403"=>"\u0413\u0301",
+ "\u0407"=>"\u0406\u0308",
+ "\u040C"=>"\u041A\u0301",
+ "\u040D"=>"\u0418\u0300",
+ "\u040E"=>"\u0423\u0306",
+ "\u0419"=>"\u0418\u0306",
+ "\u0439"=>"\u0438\u0306",
+ "\u0450"=>"\u0435\u0300",
+ "\u0451"=>"\u0435\u0308",
+ "\u0453"=>"\u0433\u0301",
+ "\u0457"=>"\u0456\u0308",
+ "\u045C"=>"\u043A\u0301",
+ "\u045D"=>"\u0438\u0300",
+ "\u045E"=>"\u0443\u0306",
+ "\u0476"=>"\u0474\u030F",
+ "\u0477"=>"\u0475\u030F",
+ "\u04C1"=>"\u0416\u0306",
+ "\u04C2"=>"\u0436\u0306",
+ "\u04D0"=>"\u0410\u0306",
+ "\u04D1"=>"\u0430\u0306",
+ "\u04D2"=>"\u0410\u0308",
+ "\u04D3"=>"\u0430\u0308",
+ "\u04D6"=>"\u0415\u0306",
+ "\u04D7"=>"\u0435\u0306",
+ "\u04DA"=>"\u04D8\u0308",
+ "\u04DB"=>"\u04D9\u0308",
+ "\u04DC"=>"\u0416\u0308",
+ "\u04DD"=>"\u0436\u0308",
+ "\u04DE"=>"\u0417\u0308",
+ "\u04DF"=>"\u0437\u0308",
+ "\u04E2"=>"\u0418\u0304",
+ "\u04E3"=>"\u0438\u0304",
+ "\u04E4"=>"\u0418\u0308",
+ "\u04E5"=>"\u0438\u0308",
+ "\u04E6"=>"\u041E\u0308",
+ "\u04E7"=>"\u043E\u0308",
+ "\u04EA"=>"\u04E8\u0308",
+ "\u04EB"=>"\u04E9\u0308",
+ "\u04EC"=>"\u042D\u0308",
+ "\u04ED"=>"\u044D\u0308",
+ "\u04EE"=>"\u0423\u0304",
+ "\u04EF"=>"\u0443\u0304",
+ "\u04F0"=>"\u0423\u0308",
+ "\u04F1"=>"\u0443\u0308",
+ "\u04F2"=>"\u0423\u030B",
+ "\u04F3"=>"\u0443\u030B",
+ "\u04F4"=>"\u0427\u0308",
+ "\u04F5"=>"\u0447\u0308",
+ "\u04F8"=>"\u042B\u0308",
+ "\u04F9"=>"\u044B\u0308",
+ "\u0622"=>"\u0627\u0653",
+ "\u0623"=>"\u0627\u0654",
+ "\u0624"=>"\u0648\u0654",
+ "\u0625"=>"\u0627\u0655",
+ "\u0626"=>"\u064A\u0654",
+ "\u06C0"=>"\u06D5\u0654",
+ "\u06C2"=>"\u06C1\u0654",
+ "\u06D3"=>"\u06D2\u0654",
+ "\u0929"=>"\u0928\u093C",
+ "\u0931"=>"\u0930\u093C",
+ "\u0934"=>"\u0933\u093C",
+ "\u0958"=>"\u0915\u093C",
+ "\u0959"=>"\u0916\u093C",
+ "\u095A"=>"\u0917\u093C",
+ "\u095B"=>"\u091C\u093C",
+ "\u095C"=>"\u0921\u093C",
+ "\u095D"=>"\u0922\u093C",
+ "\u095E"=>"\u092B\u093C",
+ "\u095F"=>"\u092F\u093C",
+ "\u09CB"=>"\u09C7\u09BE",
+ "\u09CC"=>"\u09C7\u09D7",
+ "\u09DC"=>"\u09A1\u09BC",
+ "\u09DD"=>"\u09A2\u09BC",
+ "\u09DF"=>"\u09AF\u09BC",
+ "\u0A33"=>"\u0A32\u0A3C",
+ "\u0A36"=>"\u0A38\u0A3C",
+ "\u0A59"=>"\u0A16\u0A3C",
+ "\u0A5A"=>"\u0A17\u0A3C",
+ "\u0A5B"=>"\u0A1C\u0A3C",
+ "\u0A5E"=>"\u0A2B\u0A3C",
+ "\u0B48"=>"\u0B47\u0B56",
+ "\u0B4B"=>"\u0B47\u0B3E",
+ "\u0B4C"=>"\u0B47\u0B57",
+ "\u0B5C"=>"\u0B21\u0B3C",
+ "\u0B5D"=>"\u0B22\u0B3C",
+ "\u0B94"=>"\u0B92\u0BD7",
+ "\u0BCA"=>"\u0BC6\u0BBE",
+ "\u0BCB"=>"\u0BC7\u0BBE",
+ "\u0BCC"=>"\u0BC6\u0BD7",
+ "\u0C48"=>"\u0C46\u0C56",
+ "\u0CC0"=>"\u0CBF\u0CD5",
+ "\u0CC7"=>"\u0CC6\u0CD5",
+ "\u0CC8"=>"\u0CC6\u0CD6",
+ "\u0CCA"=>"\u0CC6\u0CC2",
+ "\u0CCB"=>"\u0CC6\u0CC2\u0CD5",
+ "\u0D4A"=>"\u0D46\u0D3E",
+ "\u0D4B"=>"\u0D47\u0D3E",
+ "\u0D4C"=>"\u0D46\u0D57",
+ "\u0DDA"=>"\u0DD9\u0DCA",
+ "\u0DDC"=>"\u0DD9\u0DCF",
+ "\u0DDD"=>"\u0DD9\u0DCF\u0DCA",
+ "\u0DDE"=>"\u0DD9\u0DDF",
+ "\u0F43"=>"\u0F42\u0FB7",
+ "\u0F4D"=>"\u0F4C\u0FB7",
+ "\u0F52"=>"\u0F51\u0FB7",
+ "\u0F57"=>"\u0F56\u0FB7",
+ "\u0F5C"=>"\u0F5B\u0FB7",
+ "\u0F69"=>"\u0F40\u0FB5",
+ "\u0F73"=>"\u0F71\u0F72",
+ "\u0F75"=>"\u0F71\u0F74",
+ "\u0F76"=>"\u0FB2\u0F80",
+ "\u0F78"=>"\u0FB3\u0F80",
+ "\u0F81"=>"\u0F71\u0F80",
+ "\u0F93"=>"\u0F92\u0FB7",
+ "\u0F9D"=>"\u0F9C\u0FB7",
+ "\u0FA2"=>"\u0FA1\u0FB7",
+ "\u0FA7"=>"\u0FA6\u0FB7",
+ "\u0FAC"=>"\u0FAB\u0FB7",
+ "\u0FB9"=>"\u0F90\u0FB5",
+ "\u1026"=>"\u1025\u102E",
+ "\u1B06"=>"\u1B05\u1B35",
+ "\u1B08"=>"\u1B07\u1B35",
+ "\u1B0A"=>"\u1B09\u1B35",
+ "\u1B0C"=>"\u1B0B\u1B35",
+ "\u1B0E"=>"\u1B0D\u1B35",
+ "\u1B12"=>"\u1B11\u1B35",
+ "\u1B3B"=>"\u1B3A\u1B35",
+ "\u1B3D"=>"\u1B3C\u1B35",
+ "\u1B40"=>"\u1B3E\u1B35",
+ "\u1B41"=>"\u1B3F\u1B35",
+ "\u1B43"=>"\u1B42\u1B35",
+ "\u1E00"=>"A\u0325",
+ "\u1E01"=>"a\u0325",
+ "\u1E02"=>"B\u0307",
+ "\u1E03"=>"b\u0307",
+ "\u1E04"=>"B\u0323",
+ "\u1E05"=>"b\u0323",
+ "\u1E06"=>"B\u0331",
+ "\u1E07"=>"b\u0331",
+ "\u1E08"=>"C\u0327\u0301",
+ "\u1E09"=>"c\u0327\u0301",
+ "\u1E0A"=>"D\u0307",
+ "\u1E0B"=>"d\u0307",
+ "\u1E0C"=>"D\u0323",
+ "\u1E0D"=>"d\u0323",
+ "\u1E0E"=>"D\u0331",
+ "\u1E0F"=>"d\u0331",
+ "\u1E10"=>"D\u0327",
+ "\u1E11"=>"d\u0327",
+ "\u1E12"=>"D\u032D",
+ "\u1E13"=>"d\u032D",
+ "\u1E14"=>"E\u0304\u0300",
+ "\u1E15"=>"e\u0304\u0300",
+ "\u1E16"=>"E\u0304\u0301",
+ "\u1E17"=>"e\u0304\u0301",
+ "\u1E18"=>"E\u032D",
+ "\u1E19"=>"e\u032D",
+ "\u1E1A"=>"E\u0330",
+ "\u1E1B"=>"e\u0330",
+ "\u1E1C"=>"E\u0327\u0306",
+ "\u1E1D"=>"e\u0327\u0306",
+ "\u1E1E"=>"F\u0307",
+ "\u1E1F"=>"f\u0307",
+ "\u1E20"=>"G\u0304",
+ "\u1E21"=>"g\u0304",
+ "\u1E22"=>"H\u0307",
+ "\u1E23"=>"h\u0307",
+ "\u1E24"=>"H\u0323",
+ "\u1E25"=>"h\u0323",
+ "\u1E26"=>"H\u0308",
+ "\u1E27"=>"h\u0308",
+ "\u1E28"=>"H\u0327",
+ "\u1E29"=>"h\u0327",
+ "\u1E2A"=>"H\u032E",
+ "\u1E2B"=>"h\u032E",
+ "\u1E2C"=>"I\u0330",
+ "\u1E2D"=>"i\u0330",
+ "\u1E2E"=>"I\u0308\u0301",
+ "\u1E2F"=>"i\u0308\u0301",
+ "\u1E30"=>"K\u0301",
+ "\u1E31"=>"k\u0301",
+ "\u1E32"=>"K\u0323",
+ "\u1E33"=>"k\u0323",
+ "\u1E34"=>"K\u0331",
+ "\u1E35"=>"k\u0331",
+ "\u1E36"=>"L\u0323",
+ "\u1E37"=>"l\u0323",
+ "\u1E38"=>"L\u0323\u0304",
+ "\u1E39"=>"l\u0323\u0304",
+ "\u1E3A"=>"L\u0331",
+ "\u1E3B"=>"l\u0331",
+ "\u1E3C"=>"L\u032D",
+ "\u1E3D"=>"l\u032D",
+ "\u1E3E"=>"M\u0301",
+ "\u1E3F"=>"m\u0301",
+ "\u1E40"=>"M\u0307",
+ "\u1E41"=>"m\u0307",
+ "\u1E42"=>"M\u0323",
+ "\u1E43"=>"m\u0323",
+ "\u1E44"=>"N\u0307",
+ "\u1E45"=>"n\u0307",
+ "\u1E46"=>"N\u0323",
+ "\u1E47"=>"n\u0323",
+ "\u1E48"=>"N\u0331",
+ "\u1E49"=>"n\u0331",
+ "\u1E4A"=>"N\u032D",
+ "\u1E4B"=>"n\u032D",
+ "\u1E4C"=>"O\u0303\u0301",
+ "\u1E4D"=>"o\u0303\u0301",
+ "\u1E4E"=>"O\u0303\u0308",
+ "\u1E4F"=>"o\u0303\u0308",
+ "\u1E50"=>"O\u0304\u0300",
+ "\u1E51"=>"o\u0304\u0300",
+ "\u1E52"=>"O\u0304\u0301",
+ "\u1E53"=>"o\u0304\u0301",
+ "\u1E54"=>"P\u0301",
+ "\u1E55"=>"p\u0301",
+ "\u1E56"=>"P\u0307",
+ "\u1E57"=>"p\u0307",
+ "\u1E58"=>"R\u0307",
+ "\u1E59"=>"r\u0307",
+ "\u1E5A"=>"R\u0323",
+ "\u1E5B"=>"r\u0323",
+ "\u1E5C"=>"R\u0323\u0304",
+ "\u1E5D"=>"r\u0323\u0304",
+ "\u1E5E"=>"R\u0331",
+ "\u1E5F"=>"r\u0331",
+ "\u1E60"=>"S\u0307",
+ "\u1E61"=>"s\u0307",
+ "\u1E62"=>"S\u0323",
+ "\u1E63"=>"s\u0323",
+ "\u1E64"=>"S\u0301\u0307",
+ "\u1E65"=>"s\u0301\u0307",
+ "\u1E66"=>"S\u030C\u0307",
+ "\u1E67"=>"s\u030C\u0307",
+ "\u1E68"=>"S\u0323\u0307",
+ "\u1E69"=>"s\u0323\u0307",
+ "\u1E6A"=>"T\u0307",
+ "\u1E6B"=>"t\u0307",
+ "\u1E6C"=>"T\u0323",
+ "\u1E6D"=>"t\u0323",
+ "\u1E6E"=>"T\u0331",
+ "\u1E6F"=>"t\u0331",
+ "\u1E70"=>"T\u032D",
+ "\u1E71"=>"t\u032D",
+ "\u1E72"=>"U\u0324",
+ "\u1E73"=>"u\u0324",
+ "\u1E74"=>"U\u0330",
+ "\u1E75"=>"u\u0330",
+ "\u1E76"=>"U\u032D",
+ "\u1E77"=>"u\u032D",
+ "\u1E78"=>"U\u0303\u0301",
+ "\u1E79"=>"u\u0303\u0301",
+ "\u1E7A"=>"U\u0304\u0308",
+ "\u1E7B"=>"u\u0304\u0308",
+ "\u1E7C"=>"V\u0303",
+ "\u1E7D"=>"v\u0303",
+ "\u1E7E"=>"V\u0323",
+ "\u1E7F"=>"v\u0323",
+ "\u1E80"=>"W\u0300",
+ "\u1E81"=>"w\u0300",
+ "\u1E82"=>"W\u0301",
+ "\u1E83"=>"w\u0301",
+ "\u1E84"=>"W\u0308",
+ "\u1E85"=>"w\u0308",
+ "\u1E86"=>"W\u0307",
+ "\u1E87"=>"w\u0307",
+ "\u1E88"=>"W\u0323",
+ "\u1E89"=>"w\u0323",
+ "\u1E8A"=>"X\u0307",
+ "\u1E8B"=>"x\u0307",
+ "\u1E8C"=>"X\u0308",
+ "\u1E8D"=>"x\u0308",
+ "\u1E8E"=>"Y\u0307",
+ "\u1E8F"=>"y\u0307",
+ "\u1E90"=>"Z\u0302",
+ "\u1E91"=>"z\u0302",
+ "\u1E92"=>"Z\u0323",
+ "\u1E93"=>"z\u0323",
+ "\u1E94"=>"Z\u0331",
+ "\u1E95"=>"z\u0331",
+ "\u1E96"=>"h\u0331",
+ "\u1E97"=>"t\u0308",
+ "\u1E98"=>"w\u030A",
+ "\u1E99"=>"y\u030A",
+ "\u1E9B"=>"\u017F\u0307",
+ "\u1EA0"=>"A\u0323",
+ "\u1EA1"=>"a\u0323",
+ "\u1EA2"=>"A\u0309",
+ "\u1EA3"=>"a\u0309",
+ "\u1EA4"=>"A\u0302\u0301",
+ "\u1EA5"=>"a\u0302\u0301",
+ "\u1EA6"=>"A\u0302\u0300",
+ "\u1EA7"=>"a\u0302\u0300",
+ "\u1EA8"=>"A\u0302\u0309",
+ "\u1EA9"=>"a\u0302\u0309",
+ "\u1EAA"=>"A\u0302\u0303",
+ "\u1EAB"=>"a\u0302\u0303",
+ "\u1EAC"=>"A\u0323\u0302",
+ "\u1EAD"=>"a\u0323\u0302",
+ "\u1EAE"=>"A\u0306\u0301",
+ "\u1EAF"=>"a\u0306\u0301",
+ "\u1EB0"=>"A\u0306\u0300",
+ "\u1EB1"=>"a\u0306\u0300",
+ "\u1EB2"=>"A\u0306\u0309",
+ "\u1EB3"=>"a\u0306\u0309",
+ "\u1EB4"=>"A\u0306\u0303",
+ "\u1EB5"=>"a\u0306\u0303",
+ "\u1EB6"=>"A\u0323\u0306",
+ "\u1EB7"=>"a\u0323\u0306",
+ "\u1EB8"=>"E\u0323",
+ "\u1EB9"=>"e\u0323",
+ "\u1EBA"=>"E\u0309",
+ "\u1EBB"=>"e\u0309",
+ "\u1EBC"=>"E\u0303",
+ "\u1EBD"=>"e\u0303",
+ "\u1EBE"=>"E\u0302\u0301",
+ "\u1EBF"=>"e\u0302\u0301",
+ "\u1EC0"=>"E\u0302\u0300",
+ "\u1EC1"=>"e\u0302\u0300",
+ "\u1EC2"=>"E\u0302\u0309",
+ "\u1EC3"=>"e\u0302\u0309",
+ "\u1EC4"=>"E\u0302\u0303",
+ "\u1EC5"=>"e\u0302\u0303",
+ "\u1EC6"=>"E\u0323\u0302",
+ "\u1EC7"=>"e\u0323\u0302",
+ "\u1EC8"=>"I\u0309",
+ "\u1EC9"=>"i\u0309",
+ "\u1ECA"=>"I\u0323",
+ "\u1ECB"=>"i\u0323",
+ "\u1ECC"=>"O\u0323",
+ "\u1ECD"=>"o\u0323",
+ "\u1ECE"=>"O\u0309",
+ "\u1ECF"=>"o\u0309",
+ "\u1ED0"=>"O\u0302\u0301",
+ "\u1ED1"=>"o\u0302\u0301",
+ "\u1ED2"=>"O\u0302\u0300",
+ "\u1ED3"=>"o\u0302\u0300",
+ "\u1ED4"=>"O\u0302\u0309",
+ "\u1ED5"=>"o\u0302\u0309",
+ "\u1ED6"=>"O\u0302\u0303",
+ "\u1ED7"=>"o\u0302\u0303",
+ "\u1ED8"=>"O\u0323\u0302",
+ "\u1ED9"=>"o\u0323\u0302",
+ "\u1EDA"=>"O\u031B\u0301",
+ "\u1EDB"=>"o\u031B\u0301",
+ "\u1EDC"=>"O\u031B\u0300",
+ "\u1EDD"=>"o\u031B\u0300",
+ "\u1EDE"=>"O\u031B\u0309",
+ "\u1EDF"=>"o\u031B\u0309",
+ "\u1EE0"=>"O\u031B\u0303",
+ "\u1EE1"=>"o\u031B\u0303",
+ "\u1EE2"=>"O\u031B\u0323",
+ "\u1EE3"=>"o\u031B\u0323",
+ "\u1EE4"=>"U\u0323",
+ "\u1EE5"=>"u\u0323",
+ "\u1EE6"=>"U\u0309",
+ "\u1EE7"=>"u\u0309",
+ "\u1EE8"=>"U\u031B\u0301",
+ "\u1EE9"=>"u\u031B\u0301",
+ "\u1EEA"=>"U\u031B\u0300",
+ "\u1EEB"=>"u\u031B\u0300",
+ "\u1EEC"=>"U\u031B\u0309",
+ "\u1EED"=>"u\u031B\u0309",
+ "\u1EEE"=>"U\u031B\u0303",
+ "\u1EEF"=>"u\u031B\u0303",
+ "\u1EF0"=>"U\u031B\u0323",
+ "\u1EF1"=>"u\u031B\u0323",
+ "\u1EF2"=>"Y\u0300",
+ "\u1EF3"=>"y\u0300",
+ "\u1EF4"=>"Y\u0323",
+ "\u1EF5"=>"y\u0323",
+ "\u1EF6"=>"Y\u0309",
+ "\u1EF7"=>"y\u0309",
+ "\u1EF8"=>"Y\u0303",
+ "\u1EF9"=>"y\u0303",
+ "\u1F00"=>"\u03B1\u0313",
+ "\u1F01"=>"\u03B1\u0314",
+ "\u1F02"=>"\u03B1\u0313\u0300",
+ "\u1F03"=>"\u03B1\u0314\u0300",
+ "\u1F04"=>"\u03B1\u0313\u0301",
+ "\u1F05"=>"\u03B1\u0314\u0301",
+ "\u1F06"=>"\u03B1\u0313\u0342",
+ "\u1F07"=>"\u03B1\u0314\u0342",
+ "\u1F08"=>"\u0391\u0313",
+ "\u1F09"=>"\u0391\u0314",
+ "\u1F0A"=>"\u0391\u0313\u0300",
+ "\u1F0B"=>"\u0391\u0314\u0300",
+ "\u1F0C"=>"\u0391\u0313\u0301",
+ "\u1F0D"=>"\u0391\u0314\u0301",
+ "\u1F0E"=>"\u0391\u0313\u0342",
+ "\u1F0F"=>"\u0391\u0314\u0342",
+ "\u1F10"=>"\u03B5\u0313",
+ "\u1F11"=>"\u03B5\u0314",
+ "\u1F12"=>"\u03B5\u0313\u0300",
+ "\u1F13"=>"\u03B5\u0314\u0300",
+ "\u1F14"=>"\u03B5\u0313\u0301",
+ "\u1F15"=>"\u03B5\u0314\u0301",
+ "\u1F18"=>"\u0395\u0313",
+ "\u1F19"=>"\u0395\u0314",
+ "\u1F1A"=>"\u0395\u0313\u0300",
+ "\u1F1B"=>"\u0395\u0314\u0300",
+ "\u1F1C"=>"\u0395\u0313\u0301",
+ "\u1F1D"=>"\u0395\u0314\u0301",
+ "\u1F20"=>"\u03B7\u0313",
+ "\u1F21"=>"\u03B7\u0314",
+ "\u1F22"=>"\u03B7\u0313\u0300",
+ "\u1F23"=>"\u03B7\u0314\u0300",
+ "\u1F24"=>"\u03B7\u0313\u0301",
+ "\u1F25"=>"\u03B7\u0314\u0301",
+ "\u1F26"=>"\u03B7\u0313\u0342",
+ "\u1F27"=>"\u03B7\u0314\u0342",
+ "\u1F28"=>"\u0397\u0313",
+ "\u1F29"=>"\u0397\u0314",
+ "\u1F2A"=>"\u0397\u0313\u0300",
+ "\u1F2B"=>"\u0397\u0314\u0300",
+ "\u1F2C"=>"\u0397\u0313\u0301",
+ "\u1F2D"=>"\u0397\u0314\u0301",
+ "\u1F2E"=>"\u0397\u0313\u0342",
+ "\u1F2F"=>"\u0397\u0314\u0342",
+ "\u1F30"=>"\u03B9\u0313",
+ "\u1F31"=>"\u03B9\u0314",
+ "\u1F32"=>"\u03B9\u0313\u0300",
+ "\u1F33"=>"\u03B9\u0314\u0300",
+ "\u1F34"=>"\u03B9\u0313\u0301",
+ "\u1F35"=>"\u03B9\u0314\u0301",
+ "\u1F36"=>"\u03B9\u0313\u0342",
+ "\u1F37"=>"\u03B9\u0314\u0342",
+ "\u1F38"=>"\u0399\u0313",
+ "\u1F39"=>"\u0399\u0314",
+ "\u1F3A"=>"\u0399\u0313\u0300",
+ "\u1F3B"=>"\u0399\u0314\u0300",
+ "\u1F3C"=>"\u0399\u0313\u0301",
+ "\u1F3D"=>"\u0399\u0314\u0301",
+ "\u1F3E"=>"\u0399\u0313\u0342",
+ "\u1F3F"=>"\u0399\u0314\u0342",
+ "\u1F40"=>"\u03BF\u0313",
+ "\u1F41"=>"\u03BF\u0314",
+ "\u1F42"=>"\u03BF\u0313\u0300",
+ "\u1F43"=>"\u03BF\u0314\u0300",
+ "\u1F44"=>"\u03BF\u0313\u0301",
+ "\u1F45"=>"\u03BF\u0314\u0301",
+ "\u1F48"=>"\u039F\u0313",
+ "\u1F49"=>"\u039F\u0314",
+ "\u1F4A"=>"\u039F\u0313\u0300",
+ "\u1F4B"=>"\u039F\u0314\u0300",
+ "\u1F4C"=>"\u039F\u0313\u0301",
+ "\u1F4D"=>"\u039F\u0314\u0301",
+ "\u1F50"=>"\u03C5\u0313",
+ "\u1F51"=>"\u03C5\u0314",
+ "\u1F52"=>"\u03C5\u0313\u0300",
+ "\u1F53"=>"\u03C5\u0314\u0300",
+ "\u1F54"=>"\u03C5\u0313\u0301",
+ "\u1F55"=>"\u03C5\u0314\u0301",
+ "\u1F56"=>"\u03C5\u0313\u0342",
+ "\u1F57"=>"\u03C5\u0314\u0342",
+ "\u1F59"=>"\u03A5\u0314",
+ "\u1F5B"=>"\u03A5\u0314\u0300",
+ "\u1F5D"=>"\u03A5\u0314\u0301",
+ "\u1F5F"=>"\u03A5\u0314\u0342",
+ "\u1F60"=>"\u03C9\u0313",
+ "\u1F61"=>"\u03C9\u0314",
+ "\u1F62"=>"\u03C9\u0313\u0300",
+ "\u1F63"=>"\u03C9\u0314\u0300",
+ "\u1F64"=>"\u03C9\u0313\u0301",
+ "\u1F65"=>"\u03C9\u0314\u0301",
+ "\u1F66"=>"\u03C9\u0313\u0342",
+ "\u1F67"=>"\u03C9\u0314\u0342",
+ "\u1F68"=>"\u03A9\u0313",
+ "\u1F69"=>"\u03A9\u0314",
+ "\u1F6A"=>"\u03A9\u0313\u0300",
+ "\u1F6B"=>"\u03A9\u0314\u0300",
+ "\u1F6C"=>"\u03A9\u0313\u0301",
+ "\u1F6D"=>"\u03A9\u0314\u0301",
+ "\u1F6E"=>"\u03A9\u0313\u0342",
+ "\u1F6F"=>"\u03A9\u0314\u0342",
+ "\u1F70"=>"\u03B1\u0300",
+ "\u1F71"=>"\u03B1\u0301",
+ "\u1F72"=>"\u03B5\u0300",
+ "\u1F73"=>"\u03B5\u0301",
+ "\u1F74"=>"\u03B7\u0300",
+ "\u1F75"=>"\u03B7\u0301",
+ "\u1F76"=>"\u03B9\u0300",
+ "\u1F77"=>"\u03B9\u0301",
+ "\u1F78"=>"\u03BF\u0300",
+ "\u1F79"=>"\u03BF\u0301",
+ "\u1F7A"=>"\u03C5\u0300",
+ "\u1F7B"=>"\u03C5\u0301",
+ "\u1F7C"=>"\u03C9\u0300",
+ "\u1F7D"=>"\u03C9\u0301",
+ "\u1F80"=>"\u03B1\u0313\u0345",
+ "\u1F81"=>"\u03B1\u0314\u0345",
+ "\u1F82"=>"\u03B1\u0313\u0300\u0345",
+ "\u1F83"=>"\u03B1\u0314\u0300\u0345",
+ "\u1F84"=>"\u03B1\u0313\u0301\u0345",
+ "\u1F85"=>"\u03B1\u0314\u0301\u0345",
+ "\u1F86"=>"\u03B1\u0313\u0342\u0345",
+ "\u1F87"=>"\u03B1\u0314\u0342\u0345",
+ "\u1F88"=>"\u0391\u0313\u0345",
+ "\u1F89"=>"\u0391\u0314\u0345",
+ "\u1F8A"=>"\u0391\u0313\u0300\u0345",
+ "\u1F8B"=>"\u0391\u0314\u0300\u0345",
+ "\u1F8C"=>"\u0391\u0313\u0301\u0345",
+ "\u1F8D"=>"\u0391\u0314\u0301\u0345",
+ "\u1F8E"=>"\u0391\u0313\u0342\u0345",
+ "\u1F8F"=>"\u0391\u0314\u0342\u0345",
+ "\u1F90"=>"\u03B7\u0313\u0345",
+ "\u1F91"=>"\u03B7\u0314\u0345",
+ "\u1F92"=>"\u03B7\u0313\u0300\u0345",
+ "\u1F93"=>"\u03B7\u0314\u0300\u0345",
+ "\u1F94"=>"\u03B7\u0313\u0301\u0345",
+ "\u1F95"=>"\u03B7\u0314\u0301\u0345",
+ "\u1F96"=>"\u03B7\u0313\u0342\u0345",
+ "\u1F97"=>"\u03B7\u0314\u0342\u0345",
+ "\u1F98"=>"\u0397\u0313\u0345",
+ "\u1F99"=>"\u0397\u0314\u0345",
+ "\u1F9A"=>"\u0397\u0313\u0300\u0345",
+ "\u1F9B"=>"\u0397\u0314\u0300\u0345",
+ "\u1F9C"=>"\u0397\u0313\u0301\u0345",
+ "\u1F9D"=>"\u0397\u0314\u0301\u0345",
+ "\u1F9E"=>"\u0397\u0313\u0342\u0345",
+ "\u1F9F"=>"\u0397\u0314\u0342\u0345",
+ "\u1FA0"=>"\u03C9\u0313\u0345",
+ "\u1FA1"=>"\u03C9\u0314\u0345",
+ "\u1FA2"=>"\u03C9\u0313\u0300\u0345",
+ "\u1FA3"=>"\u03C9\u0314\u0300\u0345",
+ "\u1FA4"=>"\u03C9\u0313\u0301\u0345",
+ "\u1FA5"=>"\u03C9\u0314\u0301\u0345",
+ "\u1FA6"=>"\u03C9\u0313\u0342\u0345",
+ "\u1FA7"=>"\u03C9\u0314\u0342\u0345",
+ "\u1FA8"=>"\u03A9\u0313\u0345",
+ "\u1FA9"=>"\u03A9\u0314\u0345",
+ "\u1FAA"=>"\u03A9\u0313\u0300\u0345",
+ "\u1FAB"=>"\u03A9\u0314\u0300\u0345",
+ "\u1FAC"=>"\u03A9\u0313\u0301\u0345",
+ "\u1FAD"=>"\u03A9\u0314\u0301\u0345",
+ "\u1FAE"=>"\u03A9\u0313\u0342\u0345",
+ "\u1FAF"=>"\u03A9\u0314\u0342\u0345",
+ "\u1FB0"=>"\u03B1\u0306",
+ "\u1FB1"=>"\u03B1\u0304",
+ "\u1FB2"=>"\u03B1\u0300\u0345",
+ "\u1FB3"=>"\u03B1\u0345",
+ "\u1FB4"=>"\u03B1\u0301\u0345",
+ "\u1FB6"=>"\u03B1\u0342",
+ "\u1FB7"=>"\u03B1\u0342\u0345",
+ "\u1FB8"=>"\u0391\u0306",
+ "\u1FB9"=>"\u0391\u0304",
+ "\u1FBA"=>"\u0391\u0300",
+ "\u1FBB"=>"\u0391\u0301",
+ "\u1FBC"=>"\u0391\u0345",
+ "\u1FBE"=>"\u03B9",
+ "\u1FC1"=>"\u00A8\u0342",
+ "\u1FC2"=>"\u03B7\u0300\u0345",
+ "\u1FC3"=>"\u03B7\u0345",
+ "\u1FC4"=>"\u03B7\u0301\u0345",
+ "\u1FC6"=>"\u03B7\u0342",
+ "\u1FC7"=>"\u03B7\u0342\u0345",
+ "\u1FC8"=>"\u0395\u0300",
+ "\u1FC9"=>"\u0395\u0301",
+ "\u1FCA"=>"\u0397\u0300",
+ "\u1FCB"=>"\u0397\u0301",
+ "\u1FCC"=>"\u0397\u0345",
+ "\u1FCD"=>"\u1FBF\u0300",
+ "\u1FCE"=>"\u1FBF\u0301",
+ "\u1FCF"=>"\u1FBF\u0342",
+ "\u1FD0"=>"\u03B9\u0306",
+ "\u1FD1"=>"\u03B9\u0304",
+ "\u1FD2"=>"\u03B9\u0308\u0300",
+ "\u1FD3"=>"\u03B9\u0308\u0301",
+ "\u1FD6"=>"\u03B9\u0342",
+ "\u1FD7"=>"\u03B9\u0308\u0342",
+ "\u1FD8"=>"\u0399\u0306",
+ "\u1FD9"=>"\u0399\u0304",
+ "\u1FDA"=>"\u0399\u0300",
+ "\u1FDB"=>"\u0399\u0301",
+ "\u1FDD"=>"\u1FFE\u0300",
+ "\u1FDE"=>"\u1FFE\u0301",
+ "\u1FDF"=>"\u1FFE\u0342",
+ "\u1FE0"=>"\u03C5\u0306",
+ "\u1FE1"=>"\u03C5\u0304",
+ "\u1FE2"=>"\u03C5\u0308\u0300",
+ "\u1FE3"=>"\u03C5\u0308\u0301",
+ "\u1FE4"=>"\u03C1\u0313",
+ "\u1FE5"=>"\u03C1\u0314",
+ "\u1FE6"=>"\u03C5\u0342",
+ "\u1FE7"=>"\u03C5\u0308\u0342",
+ "\u1FE8"=>"\u03A5\u0306",
+ "\u1FE9"=>"\u03A5\u0304",
+ "\u1FEA"=>"\u03A5\u0300",
+ "\u1FEB"=>"\u03A5\u0301",
+ "\u1FEC"=>"\u03A1\u0314",
+ "\u1FED"=>"\u00A8\u0300",
+ "\u1FEE"=>"\u00A8\u0301",
+ "\u1FEF"=>"`",
+ "\u1FF2"=>"\u03C9\u0300\u0345",
+ "\u1FF3"=>"\u03C9\u0345",
+ "\u1FF4"=>"\u03C9\u0301\u0345",
+ "\u1FF6"=>"\u03C9\u0342",
+ "\u1FF7"=>"\u03C9\u0342\u0345",
+ "\u1FF8"=>"\u039F\u0300",
+ "\u1FF9"=>"\u039F\u0301",
+ "\u1FFA"=>"\u03A9\u0300",
+ "\u1FFB"=>"\u03A9\u0301",
+ "\u1FFC"=>"\u03A9\u0345",
+ "\u1FFD"=>"\u00B4",
+ "\u2000"=>"\u2002",
+ "\u2001"=>"\u2003",
+ "\u2126"=>"\u03A9",
+ "\u212A"=>"K",
+ "\u212B"=>"A\u030A",
+ "\u219A"=>"\u2190\u0338",
+ "\u219B"=>"\u2192\u0338",
+ "\u21AE"=>"\u2194\u0338",
+ "\u21CD"=>"\u21D0\u0338",
+ "\u21CE"=>"\u21D4\u0338",
+ "\u21CF"=>"\u21D2\u0338",
+ "\u2204"=>"\u2203\u0338",
+ "\u2209"=>"\u2208\u0338",
+ "\u220C"=>"\u220B\u0338",
+ "\u2224"=>"\u2223\u0338",
+ "\u2226"=>"\u2225\u0338",
+ "\u2241"=>"\u223C\u0338",
+ "\u2244"=>"\u2243\u0338",
+ "\u2247"=>"\u2245\u0338",
+ "\u2249"=>"\u2248\u0338",
+ "\u2260"=>"=\u0338",
+ "\u2262"=>"\u2261\u0338",
+ "\u226D"=>"\u224D\u0338",
+ "\u226E"=>"<\u0338",
+ "\u226F"=>">\u0338",
+ "\u2270"=>"\u2264\u0338",
+ "\u2271"=>"\u2265\u0338",
+ "\u2274"=>"\u2272\u0338",
+ "\u2275"=>"\u2273\u0338",
+ "\u2278"=>"\u2276\u0338",
+ "\u2279"=>"\u2277\u0338",
+ "\u2280"=>"\u227A\u0338",
+ "\u2281"=>"\u227B\u0338",
+ "\u2284"=>"\u2282\u0338",
+ "\u2285"=>"\u2283\u0338",
+ "\u2288"=>"\u2286\u0338",
+ "\u2289"=>"\u2287\u0338",
+ "\u22AC"=>"\u22A2\u0338",
+ "\u22AD"=>"\u22A8\u0338",
+ "\u22AE"=>"\u22A9\u0338",
+ "\u22AF"=>"\u22AB\u0338",
+ "\u22E0"=>"\u227C\u0338",
+ "\u22E1"=>"\u227D\u0338",
+ "\u22E2"=>"\u2291\u0338",
+ "\u22E3"=>"\u2292\u0338",
+ "\u22EA"=>"\u22B2\u0338",
+ "\u22EB"=>"\u22B3\u0338",
+ "\u22EC"=>"\u22B4\u0338",
+ "\u22ED"=>"\u22B5\u0338",
+ "\u2329"=>"\u3008",
+ "\u232A"=>"\u3009",
+ "\u2ADC"=>"\u2ADD\u0338",
+ "\u304C"=>"\u304B\u3099",
+ "\u304E"=>"\u304D\u3099",
+ "\u3050"=>"\u304F\u3099",
+ "\u3052"=>"\u3051\u3099",
+ "\u3054"=>"\u3053\u3099",
+ "\u3056"=>"\u3055\u3099",
+ "\u3058"=>"\u3057\u3099",
+ "\u305A"=>"\u3059\u3099",
+ "\u305C"=>"\u305B\u3099",
+ "\u305E"=>"\u305D\u3099",
+ "\u3060"=>"\u305F\u3099",
+ "\u3062"=>"\u3061\u3099",
+ "\u3065"=>"\u3064\u3099",
+ "\u3067"=>"\u3066\u3099",
+ "\u3069"=>"\u3068\u3099",
+ "\u3070"=>"\u306F\u3099",
+ "\u3071"=>"\u306F\u309A",
+ "\u3073"=>"\u3072\u3099",
+ "\u3074"=>"\u3072\u309A",
+ "\u3076"=>"\u3075\u3099",
+ "\u3077"=>"\u3075\u309A",
+ "\u3079"=>"\u3078\u3099",
+ "\u307A"=>"\u3078\u309A",
+ "\u307C"=>"\u307B\u3099",
+ "\u307D"=>"\u307B\u309A",
+ "\u3094"=>"\u3046\u3099",
+ "\u309E"=>"\u309D\u3099",
+ "\u30AC"=>"\u30AB\u3099",
+ "\u30AE"=>"\u30AD\u3099",
+ "\u30B0"=>"\u30AF\u3099",
+ "\u30B2"=>"\u30B1\u3099",
+ "\u30B4"=>"\u30B3\u3099",
+ "\u30B6"=>"\u30B5\u3099",
+ "\u30B8"=>"\u30B7\u3099",
+ "\u30BA"=>"\u30B9\u3099",
+ "\u30BC"=>"\u30BB\u3099",
+ "\u30BE"=>"\u30BD\u3099",
+ "\u30C0"=>"\u30BF\u3099",
+ "\u30C2"=>"\u30C1\u3099",
+ "\u30C5"=>"\u30C4\u3099",
+ "\u30C7"=>"\u30C6\u3099",
+ "\u30C9"=>"\u30C8\u3099",
+ "\u30D0"=>"\u30CF\u3099",
+ "\u30D1"=>"\u30CF\u309A",
+ "\u30D3"=>"\u30D2\u3099",
+ "\u30D4"=>"\u30D2\u309A",
+ "\u30D6"=>"\u30D5\u3099",
+ "\u30D7"=>"\u30D5\u309A",
+ "\u30D9"=>"\u30D8\u3099",
+ "\u30DA"=>"\u30D8\u309A",
+ "\u30DC"=>"\u30DB\u3099",
+ "\u30DD"=>"\u30DB\u309A",
+ "\u30F4"=>"\u30A6\u3099",
+ "\u30F7"=>"\u30EF\u3099",
+ "\u30F8"=>"\u30F0\u3099",
+ "\u30F9"=>"\u30F1\u3099",
+ "\u30FA"=>"\u30F2\u3099",
+ "\u30FE"=>"\u30FD\u3099",
+ "\uF900"=>"\u8C48",
+ "\uF901"=>"\u66F4",
+ "\uF902"=>"\u8ECA",
+ "\uF903"=>"\u8CC8",
+ "\uF904"=>"\u6ED1",
+ "\uF905"=>"\u4E32",
+ "\uF906"=>"\u53E5",
+ "\uF907"=>"\u9F9C",
+ "\uF908"=>"\u9F9C",
+ "\uF909"=>"\u5951",
+ "\uF90A"=>"\u91D1",
+ "\uF90B"=>"\u5587",
+ "\uF90C"=>"\u5948",
+ "\uF90D"=>"\u61F6",
+ "\uF90E"=>"\u7669",
+ "\uF90F"=>"\u7F85",
+ "\uF910"=>"\u863F",
+ "\uF911"=>"\u87BA",
+ "\uF912"=>"\u88F8",
+ "\uF913"=>"\u908F",
+ "\uF914"=>"\u6A02",
+ "\uF915"=>"\u6D1B",
+ "\uF916"=>"\u70D9",
+ "\uF917"=>"\u73DE",
+ "\uF918"=>"\u843D",
+ "\uF919"=>"\u916A",
+ "\uF91A"=>"\u99F1",
+ "\uF91B"=>"\u4E82",
+ "\uF91C"=>"\u5375",
+ "\uF91D"=>"\u6B04",
+ "\uF91E"=>"\u721B",
+ "\uF91F"=>"\u862D",
+ "\uF920"=>"\u9E1E",
+ "\uF921"=>"\u5D50",
+ "\uF922"=>"\u6FEB",
+ "\uF923"=>"\u85CD",
+ "\uF924"=>"\u8964",
+ "\uF925"=>"\u62C9",
+ "\uF926"=>"\u81D8",
+ "\uF927"=>"\u881F",
+ "\uF928"=>"\u5ECA",
+ "\uF929"=>"\u6717",
+ "\uF92A"=>"\u6D6A",
+ "\uF92B"=>"\u72FC",
+ "\uF92C"=>"\u90CE",
+ "\uF92D"=>"\u4F86",
+ "\uF92E"=>"\u51B7",
+ "\uF92F"=>"\u52DE",
+ "\uF930"=>"\u64C4",
+ "\uF931"=>"\u6AD3",
+ "\uF932"=>"\u7210",
+ "\uF933"=>"\u76E7",
+ "\uF934"=>"\u8001",
+ "\uF935"=>"\u8606",
+ "\uF936"=>"\u865C",
+ "\uF937"=>"\u8DEF",
+ "\uF938"=>"\u9732",
+ "\uF939"=>"\u9B6F",
+ "\uF93A"=>"\u9DFA",
+ "\uF93B"=>"\u788C",
+ "\uF93C"=>"\u797F",
+ "\uF93D"=>"\u7DA0",
+ "\uF93E"=>"\u83C9",
+ "\uF93F"=>"\u9304",
+ "\uF940"=>"\u9E7F",
+ "\uF941"=>"\u8AD6",
+ "\uF942"=>"\u58DF",
+ "\uF943"=>"\u5F04",
+ "\uF944"=>"\u7C60",
+ "\uF945"=>"\u807E",
+ "\uF946"=>"\u7262",
+ "\uF947"=>"\u78CA",
+ "\uF948"=>"\u8CC2",
+ "\uF949"=>"\u96F7",
+ "\uF94A"=>"\u58D8",
+ "\uF94B"=>"\u5C62",
+ "\uF94C"=>"\u6A13",
+ "\uF94D"=>"\u6DDA",
+ "\uF94E"=>"\u6F0F",
+ "\uF94F"=>"\u7D2F",
+ "\uF950"=>"\u7E37",
+ "\uF951"=>"\u964B",
+ "\uF952"=>"\u52D2",
+ "\uF953"=>"\u808B",
+ "\uF954"=>"\u51DC",
+ "\uF955"=>"\u51CC",
+ "\uF956"=>"\u7A1C",
+ "\uF957"=>"\u7DBE",
+ "\uF958"=>"\u83F1",
+ "\uF959"=>"\u9675",
+ "\uF95A"=>"\u8B80",
+ "\uF95B"=>"\u62CF",
+ "\uF95C"=>"\u6A02",
+ "\uF95D"=>"\u8AFE",
+ "\uF95E"=>"\u4E39",
+ "\uF95F"=>"\u5BE7",
+ "\uF960"=>"\u6012",
+ "\uF961"=>"\u7387",
+ "\uF962"=>"\u7570",
+ "\uF963"=>"\u5317",
+ "\uF964"=>"\u78FB",
+ "\uF965"=>"\u4FBF",
+ "\uF966"=>"\u5FA9",
+ "\uF967"=>"\u4E0D",
+ "\uF968"=>"\u6CCC",
+ "\uF969"=>"\u6578",
+ "\uF96A"=>"\u7D22",
+ "\uF96B"=>"\u53C3",
+ "\uF96C"=>"\u585E",
+ "\uF96D"=>"\u7701",
+ "\uF96E"=>"\u8449",
+ "\uF96F"=>"\u8AAA",
+ "\uF970"=>"\u6BBA",
+ "\uF971"=>"\u8FB0",
+ "\uF972"=>"\u6C88",
+ "\uF973"=>"\u62FE",
+ "\uF974"=>"\u82E5",
+ "\uF975"=>"\u63A0",
+ "\uF976"=>"\u7565",
+ "\uF977"=>"\u4EAE",
+ "\uF978"=>"\u5169",
+ "\uF979"=>"\u51C9",
+ "\uF97A"=>"\u6881",
+ "\uF97B"=>"\u7CE7",
+ "\uF97C"=>"\u826F",
+ "\uF97D"=>"\u8AD2",
+ "\uF97E"=>"\u91CF",
+ "\uF97F"=>"\u52F5",
+ "\uF980"=>"\u5442",
+ "\uF981"=>"\u5973",
+ "\uF982"=>"\u5EEC",
+ "\uF983"=>"\u65C5",
+ "\uF984"=>"\u6FFE",
+ "\uF985"=>"\u792A",
+ "\uF986"=>"\u95AD",
+ "\uF987"=>"\u9A6A",
+ "\uF988"=>"\u9E97",
+ "\uF989"=>"\u9ECE",
+ "\uF98A"=>"\u529B",
+ "\uF98B"=>"\u66C6",
+ "\uF98C"=>"\u6B77",
+ "\uF98D"=>"\u8F62",
+ "\uF98E"=>"\u5E74",
+ "\uF98F"=>"\u6190",
+ "\uF990"=>"\u6200",
+ "\uF991"=>"\u649A",
+ "\uF992"=>"\u6F23",
+ "\uF993"=>"\u7149",
+ "\uF994"=>"\u7489",
+ "\uF995"=>"\u79CA",
+ "\uF996"=>"\u7DF4",
+ "\uF997"=>"\u806F",
+ "\uF998"=>"\u8F26",
+ "\uF999"=>"\u84EE",
+ "\uF99A"=>"\u9023",
+ "\uF99B"=>"\u934A",
+ "\uF99C"=>"\u5217",
+ "\uF99D"=>"\u52A3",
+ "\uF99E"=>"\u54BD",
+ "\uF99F"=>"\u70C8",
+ "\uF9A0"=>"\u88C2",
+ "\uF9A1"=>"\u8AAA",
+ "\uF9A2"=>"\u5EC9",
+ "\uF9A3"=>"\u5FF5",
+ "\uF9A4"=>"\u637B",
+ "\uF9A5"=>"\u6BAE",
+ "\uF9A6"=>"\u7C3E",
+ "\uF9A7"=>"\u7375",
+ "\uF9A8"=>"\u4EE4",
+ "\uF9A9"=>"\u56F9",
+ "\uF9AA"=>"\u5BE7",
+ "\uF9AB"=>"\u5DBA",
+ "\uF9AC"=>"\u601C",
+ "\uF9AD"=>"\u73B2",
+ "\uF9AE"=>"\u7469",
+ "\uF9AF"=>"\u7F9A",
+ "\uF9B0"=>"\u8046",
+ "\uF9B1"=>"\u9234",
+ "\uF9B2"=>"\u96F6",
+ "\uF9B3"=>"\u9748",
+ "\uF9B4"=>"\u9818",
+ "\uF9B5"=>"\u4F8B",
+ "\uF9B6"=>"\u79AE",
+ "\uF9B7"=>"\u91B4",
+ "\uF9B8"=>"\u96B8",
+ "\uF9B9"=>"\u60E1",
+ "\uF9BA"=>"\u4E86",
+ "\uF9BB"=>"\u50DA",
+ "\uF9BC"=>"\u5BEE",
+ "\uF9BD"=>"\u5C3F",
+ "\uF9BE"=>"\u6599",
+ "\uF9BF"=>"\u6A02",
+ "\uF9C0"=>"\u71CE",
+ "\uF9C1"=>"\u7642",
+ "\uF9C2"=>"\u84FC",
+ "\uF9C3"=>"\u907C",
+ "\uF9C4"=>"\u9F8D",
+ "\uF9C5"=>"\u6688",
+ "\uF9C6"=>"\u962E",
+ "\uF9C7"=>"\u5289",
+ "\uF9C8"=>"\u677B",
+ "\uF9C9"=>"\u67F3",
+ "\uF9CA"=>"\u6D41",
+ "\uF9CB"=>"\u6E9C",
+ "\uF9CC"=>"\u7409",
+ "\uF9CD"=>"\u7559",
+ "\uF9CE"=>"\u786B",
+ "\uF9CF"=>"\u7D10",
+ "\uF9D0"=>"\u985E",
+ "\uF9D1"=>"\u516D",
+ "\uF9D2"=>"\u622E",
+ "\uF9D3"=>"\u9678",
+ "\uF9D4"=>"\u502B",
+ "\uF9D5"=>"\u5D19",
+ "\uF9D6"=>"\u6DEA",
+ "\uF9D7"=>"\u8F2A",
+ "\uF9D8"=>"\u5F8B",
+ "\uF9D9"=>"\u6144",
+ "\uF9DA"=>"\u6817",
+ "\uF9DB"=>"\u7387",
+ "\uF9DC"=>"\u9686",
+ "\uF9DD"=>"\u5229",
+ "\uF9DE"=>"\u540F",
+ "\uF9DF"=>"\u5C65",
+ "\uF9E0"=>"\u6613",
+ "\uF9E1"=>"\u674E",
+ "\uF9E2"=>"\u68A8",
+ "\uF9E3"=>"\u6CE5",
+ "\uF9E4"=>"\u7406",
+ "\uF9E5"=>"\u75E2",
+ "\uF9E6"=>"\u7F79",
+ "\uF9E7"=>"\u88CF",
+ "\uF9E8"=>"\u88E1",
+ "\uF9E9"=>"\u91CC",
+ "\uF9EA"=>"\u96E2",
+ "\uF9EB"=>"\u533F",
+ "\uF9EC"=>"\u6EBA",
+ "\uF9ED"=>"\u541D",
+ "\uF9EE"=>"\u71D0",
+ "\uF9EF"=>"\u7498",
+ "\uF9F0"=>"\u85FA",
+ "\uF9F1"=>"\u96A3",
+ "\uF9F2"=>"\u9C57",
+ "\uF9F3"=>"\u9E9F",
+ "\uF9F4"=>"\u6797",
+ "\uF9F5"=>"\u6DCB",
+ "\uF9F6"=>"\u81E8",
+ "\uF9F7"=>"\u7ACB",
+ "\uF9F8"=>"\u7B20",
+ "\uF9F9"=>"\u7C92",
+ "\uF9FA"=>"\u72C0",
+ "\uF9FB"=>"\u7099",
+ "\uF9FC"=>"\u8B58",
+ "\uF9FD"=>"\u4EC0",
+ "\uF9FE"=>"\u8336",
+ "\uF9FF"=>"\u523A",
+ "\uFA00"=>"\u5207",
+ "\uFA01"=>"\u5EA6",
+ "\uFA02"=>"\u62D3",
+ "\uFA03"=>"\u7CD6",
+ "\uFA04"=>"\u5B85",
+ "\uFA05"=>"\u6D1E",
+ "\uFA06"=>"\u66B4",
+ "\uFA07"=>"\u8F3B",
+ "\uFA08"=>"\u884C",
+ "\uFA09"=>"\u964D",
+ "\uFA0A"=>"\u898B",
+ "\uFA0B"=>"\u5ED3",
+ "\uFA0C"=>"\u5140",
+ "\uFA0D"=>"\u55C0",
+ "\uFA10"=>"\u585A",
+ "\uFA12"=>"\u6674",
+ "\uFA15"=>"\u51DE",
+ "\uFA16"=>"\u732A",
+ "\uFA17"=>"\u76CA",
+ "\uFA18"=>"\u793C",
+ "\uFA19"=>"\u795E",
+ "\uFA1A"=>"\u7965",
+ "\uFA1B"=>"\u798F",
+ "\uFA1C"=>"\u9756",
+ "\uFA1D"=>"\u7CBE",
+ "\uFA1E"=>"\u7FBD",
+ "\uFA20"=>"\u8612",
+ "\uFA22"=>"\u8AF8",
+ "\uFA25"=>"\u9038",
+ "\uFA26"=>"\u90FD",
+ "\uFA2A"=>"\u98EF",
+ "\uFA2B"=>"\u98FC",
+ "\uFA2C"=>"\u9928",
+ "\uFA2D"=>"\u9DB4",
+ "\uFA2E"=>"\u90DE",
+ "\uFA2F"=>"\u96B7",
+ "\uFA30"=>"\u4FAE",
+ "\uFA31"=>"\u50E7",
+ "\uFA32"=>"\u514D",
+ "\uFA33"=>"\u52C9",
+ "\uFA34"=>"\u52E4",
+ "\uFA35"=>"\u5351",
+ "\uFA36"=>"\u559D",
+ "\uFA37"=>"\u5606",
+ "\uFA38"=>"\u5668",
+ "\uFA39"=>"\u5840",
+ "\uFA3A"=>"\u58A8",
+ "\uFA3B"=>"\u5C64",
+ "\uFA3C"=>"\u5C6E",
+ "\uFA3D"=>"\u6094",
+ "\uFA3E"=>"\u6168",
+ "\uFA3F"=>"\u618E",
+ "\uFA40"=>"\u61F2",
+ "\uFA41"=>"\u654F",
+ "\uFA42"=>"\u65E2",
+ "\uFA43"=>"\u6691",
+ "\uFA44"=>"\u6885",
+ "\uFA45"=>"\u6D77",
+ "\uFA46"=>"\u6E1A",
+ "\uFA47"=>"\u6F22",
+ "\uFA48"=>"\u716E",
+ "\uFA49"=>"\u722B",
+ "\uFA4A"=>"\u7422",
+ "\uFA4B"=>"\u7891",
+ "\uFA4C"=>"\u793E",
+ "\uFA4D"=>"\u7949",
+ "\uFA4E"=>"\u7948",
+ "\uFA4F"=>"\u7950",
+ "\uFA50"=>"\u7956",
+ "\uFA51"=>"\u795D",
+ "\uFA52"=>"\u798D",
+ "\uFA53"=>"\u798E",
+ "\uFA54"=>"\u7A40",
+ "\uFA55"=>"\u7A81",
+ "\uFA56"=>"\u7BC0",
+ "\uFA57"=>"\u7DF4",
+ "\uFA58"=>"\u7E09",
+ "\uFA59"=>"\u7E41",
+ "\uFA5A"=>"\u7F72",
+ "\uFA5B"=>"\u8005",
+ "\uFA5C"=>"\u81ED",
+ "\uFA5D"=>"\u8279",
+ "\uFA5E"=>"\u8279",
+ "\uFA5F"=>"\u8457",
+ "\uFA60"=>"\u8910",
+ "\uFA61"=>"\u8996",
+ "\uFA62"=>"\u8B01",
+ "\uFA63"=>"\u8B39",
+ "\uFA64"=>"\u8CD3",
+ "\uFA65"=>"\u8D08",
+ "\uFA66"=>"\u8FB6",
+ "\uFA67"=>"\u9038",
+ "\uFA68"=>"\u96E3",
+ "\uFA69"=>"\u97FF",
+ "\uFA6A"=>"\u983B",
+ "\uFA6B"=>"\u6075",
+ "\uFA6C"=>"\u{242EE}",
+ "\uFA6D"=>"\u8218",
+ "\uFA70"=>"\u4E26",
+ "\uFA71"=>"\u51B5",
+ "\uFA72"=>"\u5168",
+ "\uFA73"=>"\u4F80",
+ "\uFA74"=>"\u5145",
+ "\uFA75"=>"\u5180",
+ "\uFA76"=>"\u52C7",
+ "\uFA77"=>"\u52FA",
+ "\uFA78"=>"\u559D",
+ "\uFA79"=>"\u5555",
+ "\uFA7A"=>"\u5599",
+ "\uFA7B"=>"\u55E2",
+ "\uFA7C"=>"\u585A",
+ "\uFA7D"=>"\u58B3",
+ "\uFA7E"=>"\u5944",
+ "\uFA7F"=>"\u5954",
+ "\uFA80"=>"\u5A62",
+ "\uFA81"=>"\u5B28",
+ "\uFA82"=>"\u5ED2",
+ "\uFA83"=>"\u5ED9",
+ "\uFA84"=>"\u5F69",
+ "\uFA85"=>"\u5FAD",
+ "\uFA86"=>"\u60D8",
+ "\uFA87"=>"\u614E",
+ "\uFA88"=>"\u6108",
+ "\uFA89"=>"\u618E",
+ "\uFA8A"=>"\u6160",
+ "\uFA8B"=>"\u61F2",
+ "\uFA8C"=>"\u6234",
+ "\uFA8D"=>"\u63C4",
+ "\uFA8E"=>"\u641C",
+ "\uFA8F"=>"\u6452",
+ "\uFA90"=>"\u6556",
+ "\uFA91"=>"\u6674",
+ "\uFA92"=>"\u6717",
+ "\uFA93"=>"\u671B",
+ "\uFA94"=>"\u6756",
+ "\uFA95"=>"\u6B79",
+ "\uFA96"=>"\u6BBA",
+ "\uFA97"=>"\u6D41",
+ "\uFA98"=>"\u6EDB",
+ "\uFA99"=>"\u6ECB",
+ "\uFA9A"=>"\u6F22",
+ "\uFA9B"=>"\u701E",
+ "\uFA9C"=>"\u716E",
+ "\uFA9D"=>"\u77A7",
+ "\uFA9E"=>"\u7235",
+ "\uFA9F"=>"\u72AF",
+ "\uFAA0"=>"\u732A",
+ "\uFAA1"=>"\u7471",
+ "\uFAA2"=>"\u7506",
+ "\uFAA3"=>"\u753B",
+ "\uFAA4"=>"\u761D",
+ "\uFAA5"=>"\u761F",
+ "\uFAA6"=>"\u76CA",
+ "\uFAA7"=>"\u76DB",
+ "\uFAA8"=>"\u76F4",
+ "\uFAA9"=>"\u774A",
+ "\uFAAA"=>"\u7740",
+ "\uFAAB"=>"\u78CC",
+ "\uFAAC"=>"\u7AB1",
+ "\uFAAD"=>"\u7BC0",
+ "\uFAAE"=>"\u7C7B",
+ "\uFAAF"=>"\u7D5B",
+ "\uFAB0"=>"\u7DF4",
+ "\uFAB1"=>"\u7F3E",
+ "\uFAB2"=>"\u8005",
+ "\uFAB3"=>"\u8352",
+ "\uFAB4"=>"\u83EF",
+ "\uFAB5"=>"\u8779",
+ "\uFAB6"=>"\u8941",
+ "\uFAB7"=>"\u8986",
+ "\uFAB8"=>"\u8996",
+ "\uFAB9"=>"\u8ABF",
+ "\uFABA"=>"\u8AF8",
+ "\uFABB"=>"\u8ACB",
+ "\uFABC"=>"\u8B01",
+ "\uFABD"=>"\u8AFE",
+ "\uFABE"=>"\u8AED",
+ "\uFABF"=>"\u8B39",
+ "\uFAC0"=>"\u8B8A",
+ "\uFAC1"=>"\u8D08",
+ "\uFAC2"=>"\u8F38",
+ "\uFAC3"=>"\u9072",
+ "\uFAC4"=>"\u9199",
+ "\uFAC5"=>"\u9276",
+ "\uFAC6"=>"\u967C",
+ "\uFAC7"=>"\u96E3",
+ "\uFAC8"=>"\u9756",
+ "\uFAC9"=>"\u97DB",
+ "\uFACA"=>"\u97FF",
+ "\uFACB"=>"\u980B",
+ "\uFACC"=>"\u983B",
+ "\uFACD"=>"\u9B12",
+ "\uFACE"=>"\u9F9C",
+ "\uFACF"=>"\u{2284A}",
+ "\uFAD0"=>"\u{22844}",
+ "\uFAD1"=>"\u{233D5}",
+ "\uFAD2"=>"\u3B9D",
+ "\uFAD3"=>"\u4018",
+ "\uFAD4"=>"\u4039",
+ "\uFAD5"=>"\u{25249}",
+ "\uFAD6"=>"\u{25CD0}",
+ "\uFAD7"=>"\u{27ED3}",
+ "\uFAD8"=>"\u9F43",
+ "\uFAD9"=>"\u9F8E",
+ "\uFB1D"=>"\u05D9\u05B4",
+ "\uFB1F"=>"\u05F2\u05B7",
+ "\uFB2A"=>"\u05E9\u05C1",
+ "\uFB2B"=>"\u05E9\u05C2",
+ "\uFB2C"=>"\u05E9\u05BC\u05C1",
+ "\uFB2D"=>"\u05E9\u05BC\u05C2",
+ "\uFB2E"=>"\u05D0\u05B7",
+ "\uFB2F"=>"\u05D0\u05B8",
+ "\uFB30"=>"\u05D0\u05BC",
+ "\uFB31"=>"\u05D1\u05BC",
+ "\uFB32"=>"\u05D2\u05BC",
+ "\uFB33"=>"\u05D3\u05BC",
+ "\uFB34"=>"\u05D4\u05BC",
+ "\uFB35"=>"\u05D5\u05BC",
+ "\uFB36"=>"\u05D6\u05BC",
+ "\uFB38"=>"\u05D8\u05BC",
+ "\uFB39"=>"\u05D9\u05BC",
+ "\uFB3A"=>"\u05DA\u05BC",
+ "\uFB3B"=>"\u05DB\u05BC",
+ "\uFB3C"=>"\u05DC\u05BC",
+ "\uFB3E"=>"\u05DE\u05BC",
+ "\uFB40"=>"\u05E0\u05BC",
+ "\uFB41"=>"\u05E1\u05BC",
+ "\uFB43"=>"\u05E3\u05BC",
+ "\uFB44"=>"\u05E4\u05BC",
+ "\uFB46"=>"\u05E6\u05BC",
+ "\uFB47"=>"\u05E7\u05BC",
+ "\uFB48"=>"\u05E8\u05BC",
+ "\uFB49"=>"\u05E9\u05BC",
+ "\uFB4A"=>"\u05EA\u05BC",
+ "\uFB4B"=>"\u05D5\u05B9",
+ "\uFB4C"=>"\u05D1\u05BF",
+ "\uFB4D"=>"\u05DB\u05BF",
+ "\uFB4E"=>"\u05E4\u05BF",
+ "\u{1109A}"=>"\u{11099}\u{110BA}",
+ "\u{1109C}"=>"\u{1109B}\u{110BA}",
+ "\u{110AB}"=>"\u{110A5}\u{110BA}",
+ "\u{1112E}"=>"\u{11131}\u{11127}",
+ "\u{1112F}"=>"\u{11132}\u{11127}",
+ "\u{1134B}"=>"\u{11347}\u{1133E}",
+ "\u{1134C}"=>"\u{11347}\u{11357}",
+ "\u{114BB}"=>"\u{114B9}\u{114BA}",
+ "\u{114BC}"=>"\u{114B9}\u{114B0}",
+ "\u{114BE}"=>"\u{114B9}\u{114BD}",
+ "\u{115BA}"=>"\u{115B8}\u{115AF}",
+ "\u{115BB}"=>"\u{115B9}\u{115AF}",
+ "\u{1D15E}"=>"\u{1D157}\u{1D165}",
+ "\u{1D15F}"=>"\u{1D158}\u{1D165}",
+ "\u{1D160}"=>"\u{1D158}\u{1D165}\u{1D16E}",
+ "\u{1D161}"=>"\u{1D158}\u{1D165}\u{1D16F}",
+ "\u{1D162}"=>"\u{1D158}\u{1D165}\u{1D170}",
+ "\u{1D163}"=>"\u{1D158}\u{1D165}\u{1D171}",
+ "\u{1D164}"=>"\u{1D158}\u{1D165}\u{1D172}",
+ "\u{1D1BB}"=>"\u{1D1B9}\u{1D165}",
+ "\u{1D1BC}"=>"\u{1D1BA}\u{1D165}",
+ "\u{1D1BD}"=>"\u{1D1B9}\u{1D165}\u{1D16E}",
+ "\u{1D1BE}"=>"\u{1D1BA}\u{1D165}\u{1D16E}",
+ "\u{1D1BF}"=>"\u{1D1B9}\u{1D165}\u{1D16F}",
+ "\u{1D1C0}"=>"\u{1D1BA}\u{1D165}\u{1D16F}",
+ "\u{2F800}"=>"\u4E3D",
+ "\u{2F801}"=>"\u4E38",
+ "\u{2F802}"=>"\u4E41",
+ "\u{2F803}"=>"\u{20122}",
+ "\u{2F804}"=>"\u4F60",
+ "\u{2F805}"=>"\u4FAE",
+ "\u{2F806}"=>"\u4FBB",
+ "\u{2F807}"=>"\u5002",
+ "\u{2F808}"=>"\u507A",
+ "\u{2F809}"=>"\u5099",
+ "\u{2F80A}"=>"\u50E7",
+ "\u{2F80B}"=>"\u50CF",
+ "\u{2F80C}"=>"\u349E",
+ "\u{2F80D}"=>"\u{2063A}",
+ "\u{2F80E}"=>"\u514D",
+ "\u{2F80F}"=>"\u5154",
+ "\u{2F810}"=>"\u5164",
+ "\u{2F811}"=>"\u5177",
+ "\u{2F812}"=>"\u{2051C}",
+ "\u{2F813}"=>"\u34B9",
+ "\u{2F814}"=>"\u5167",
+ "\u{2F815}"=>"\u518D",
+ "\u{2F816}"=>"\u{2054B}",
+ "\u{2F817}"=>"\u5197",
+ "\u{2F818}"=>"\u51A4",
+ "\u{2F819}"=>"\u4ECC",
+ "\u{2F81A}"=>"\u51AC",
+ "\u{2F81B}"=>"\u51B5",
+ "\u{2F81C}"=>"\u{291DF}",
+ "\u{2F81D}"=>"\u51F5",
+ "\u{2F81E}"=>"\u5203",
+ "\u{2F81F}"=>"\u34DF",
+ "\u{2F820}"=>"\u523B",
+ "\u{2F821}"=>"\u5246",
+ "\u{2F822}"=>"\u5272",
+ "\u{2F823}"=>"\u5277",
+ "\u{2F824}"=>"\u3515",
+ "\u{2F825}"=>"\u52C7",
+ "\u{2F826}"=>"\u52C9",
+ "\u{2F827}"=>"\u52E4",
+ "\u{2F828}"=>"\u52FA",
+ "\u{2F829}"=>"\u5305",
+ "\u{2F82A}"=>"\u5306",
+ "\u{2F82B}"=>"\u5317",
+ "\u{2F82C}"=>"\u5349",
+ "\u{2F82D}"=>"\u5351",
+ "\u{2F82E}"=>"\u535A",
+ "\u{2F82F}"=>"\u5373",
+ "\u{2F830}"=>"\u537D",
+ "\u{2F831}"=>"\u537F",
+ "\u{2F832}"=>"\u537F",
+ "\u{2F833}"=>"\u537F",
+ "\u{2F834}"=>"\u{20A2C}",
+ "\u{2F835}"=>"\u7070",
+ "\u{2F836}"=>"\u53CA",
+ "\u{2F837}"=>"\u53DF",
+ "\u{2F838}"=>"\u{20B63}",
+ "\u{2F839}"=>"\u53EB",
+ "\u{2F83A}"=>"\u53F1",
+ "\u{2F83B}"=>"\u5406",
+ "\u{2F83C}"=>"\u549E",
+ "\u{2F83D}"=>"\u5438",
+ "\u{2F83E}"=>"\u5448",
+ "\u{2F83F}"=>"\u5468",
+ "\u{2F840}"=>"\u54A2",
+ "\u{2F841}"=>"\u54F6",
+ "\u{2F842}"=>"\u5510",
+ "\u{2F843}"=>"\u5553",
+ "\u{2F844}"=>"\u5563",
+ "\u{2F845}"=>"\u5584",
+ "\u{2F846}"=>"\u5584",
+ "\u{2F847}"=>"\u5599",
+ "\u{2F848}"=>"\u55AB",
+ "\u{2F849}"=>"\u55B3",
+ "\u{2F84A}"=>"\u55C2",
+ "\u{2F84B}"=>"\u5716",
+ "\u{2F84C}"=>"\u5606",
+ "\u{2F84D}"=>"\u5717",
+ "\u{2F84E}"=>"\u5651",
+ "\u{2F84F}"=>"\u5674",
+ "\u{2F850}"=>"\u5207",
+ "\u{2F851}"=>"\u58EE",
+ "\u{2F852}"=>"\u57CE",
+ "\u{2F853}"=>"\u57F4",
+ "\u{2F854}"=>"\u580D",
+ "\u{2F855}"=>"\u578B",
+ "\u{2F856}"=>"\u5832",
+ "\u{2F857}"=>"\u5831",
+ "\u{2F858}"=>"\u58AC",
+ "\u{2F859}"=>"\u{214E4}",
+ "\u{2F85A}"=>"\u58F2",
+ "\u{2F85B}"=>"\u58F7",
+ "\u{2F85C}"=>"\u5906",
+ "\u{2F85D}"=>"\u591A",
+ "\u{2F85E}"=>"\u5922",
+ "\u{2F85F}"=>"\u5962",
+ "\u{2F860}"=>"\u{216A8}",
+ "\u{2F861}"=>"\u{216EA}",
+ "\u{2F862}"=>"\u59EC",
+ "\u{2F863}"=>"\u5A1B",
+ "\u{2F864}"=>"\u5A27",
+ "\u{2F865}"=>"\u59D8",
+ "\u{2F866}"=>"\u5A66",
+ "\u{2F867}"=>"\u36EE",
+ "\u{2F868}"=>"\u36FC",
+ "\u{2F869}"=>"\u5B08",
+ "\u{2F86A}"=>"\u5B3E",
+ "\u{2F86B}"=>"\u5B3E",
+ "\u{2F86C}"=>"\u{219C8}",
+ "\u{2F86D}"=>"\u5BC3",
+ "\u{2F86E}"=>"\u5BD8",
+ "\u{2F86F}"=>"\u5BE7",
+ "\u{2F870}"=>"\u5BF3",
+ "\u{2F871}"=>"\u{21B18}",
+ "\u{2F872}"=>"\u5BFF",
+ "\u{2F873}"=>"\u5C06",
+ "\u{2F874}"=>"\u5F53",
+ "\u{2F875}"=>"\u5C22",
+ "\u{2F876}"=>"\u3781",
+ "\u{2F877}"=>"\u5C60",
+ "\u{2F878}"=>"\u5C6E",
+ "\u{2F879}"=>"\u5CC0",
+ "\u{2F87A}"=>"\u5C8D",
+ "\u{2F87B}"=>"\u{21DE4}",
+ "\u{2F87C}"=>"\u5D43",
+ "\u{2F87D}"=>"\u{21DE6}",
+ "\u{2F87E}"=>"\u5D6E",
+ "\u{2F87F}"=>"\u5D6B",
+ "\u{2F880}"=>"\u5D7C",
+ "\u{2F881}"=>"\u5DE1",
+ "\u{2F882}"=>"\u5DE2",
+ "\u{2F883}"=>"\u382F",
+ "\u{2F884}"=>"\u5DFD",
+ "\u{2F885}"=>"\u5E28",
+ "\u{2F886}"=>"\u5E3D",
+ "\u{2F887}"=>"\u5E69",
+ "\u{2F888}"=>"\u3862",
+ "\u{2F889}"=>"\u{22183}",
+ "\u{2F88A}"=>"\u387C",
+ "\u{2F88B}"=>"\u5EB0",
+ "\u{2F88C}"=>"\u5EB3",
+ "\u{2F88D}"=>"\u5EB6",
+ "\u{2F88E}"=>"\u5ECA",
+ "\u{2F88F}"=>"\u{2A392}",
+ "\u{2F890}"=>"\u5EFE",
+ "\u{2F891}"=>"\u{22331}",
+ "\u{2F892}"=>"\u{22331}",
+ "\u{2F893}"=>"\u8201",
+ "\u{2F894}"=>"\u5F22",
+ "\u{2F895}"=>"\u5F22",
+ "\u{2F896}"=>"\u38C7",
+ "\u{2F897}"=>"\u{232B8}",
+ "\u{2F898}"=>"\u{261DA}",
+ "\u{2F899}"=>"\u5F62",
+ "\u{2F89A}"=>"\u5F6B",
+ "\u{2F89B}"=>"\u38E3",
+ "\u{2F89C}"=>"\u5F9A",
+ "\u{2F89D}"=>"\u5FCD",
+ "\u{2F89E}"=>"\u5FD7",
+ "\u{2F89F}"=>"\u5FF9",
+ "\u{2F8A0}"=>"\u6081",
+ "\u{2F8A1}"=>"\u393A",
+ "\u{2F8A2}"=>"\u391C",
+ "\u{2F8A3}"=>"\u6094",
+ "\u{2F8A4}"=>"\u{226D4}",
+ "\u{2F8A5}"=>"\u60C7",
+ "\u{2F8A6}"=>"\u6148",
+ "\u{2F8A7}"=>"\u614C",
+ "\u{2F8A8}"=>"\u614E",
+ "\u{2F8A9}"=>"\u614C",
+ "\u{2F8AA}"=>"\u617A",
+ "\u{2F8AB}"=>"\u618E",
+ "\u{2F8AC}"=>"\u61B2",
+ "\u{2F8AD}"=>"\u61A4",
+ "\u{2F8AE}"=>"\u61AF",
+ "\u{2F8AF}"=>"\u61DE",
+ "\u{2F8B0}"=>"\u61F2",
+ "\u{2F8B1}"=>"\u61F6",
+ "\u{2F8B2}"=>"\u6210",
+ "\u{2F8B3}"=>"\u621B",
+ "\u{2F8B4}"=>"\u625D",
+ "\u{2F8B5}"=>"\u62B1",
+ "\u{2F8B6}"=>"\u62D4",
+ "\u{2F8B7}"=>"\u6350",
+ "\u{2F8B8}"=>"\u{22B0C}",
+ "\u{2F8B9}"=>"\u633D",
+ "\u{2F8BA}"=>"\u62FC",
+ "\u{2F8BB}"=>"\u6368",
+ "\u{2F8BC}"=>"\u6383",
+ "\u{2F8BD}"=>"\u63E4",
+ "\u{2F8BE}"=>"\u{22BF1}",
+ "\u{2F8BF}"=>"\u6422",
+ "\u{2F8C0}"=>"\u63C5",
+ "\u{2F8C1}"=>"\u63A9",
+ "\u{2F8C2}"=>"\u3A2E",
+ "\u{2F8C3}"=>"\u6469",
+ "\u{2F8C4}"=>"\u647E",
+ "\u{2F8C5}"=>"\u649D",
+ "\u{2F8C6}"=>"\u6477",
+ "\u{2F8C7}"=>"\u3A6C",
+ "\u{2F8C8}"=>"\u654F",
+ "\u{2F8C9}"=>"\u656C",
+ "\u{2F8CA}"=>"\u{2300A}",
+ "\u{2F8CB}"=>"\u65E3",
+ "\u{2F8CC}"=>"\u66F8",
+ "\u{2F8CD}"=>"\u6649",
+ "\u{2F8CE}"=>"\u3B19",
+ "\u{2F8CF}"=>"\u6691",
+ "\u{2F8D0}"=>"\u3B08",
+ "\u{2F8D1}"=>"\u3AE4",
+ "\u{2F8D2}"=>"\u5192",
+ "\u{2F8D3}"=>"\u5195",
+ "\u{2F8D4}"=>"\u6700",
+ "\u{2F8D5}"=>"\u669C",
+ "\u{2F8D6}"=>"\u80AD",
+ "\u{2F8D7}"=>"\u43D9",
+ "\u{2F8D8}"=>"\u6717",
+ "\u{2F8D9}"=>"\u671B",
+ "\u{2F8DA}"=>"\u6721",
+ "\u{2F8DB}"=>"\u675E",
+ "\u{2F8DC}"=>"\u6753",
+ "\u{2F8DD}"=>"\u{233C3}",
+ "\u{2F8DE}"=>"\u3B49",
+ "\u{2F8DF}"=>"\u67FA",
+ "\u{2F8E0}"=>"\u6785",
+ "\u{2F8E1}"=>"\u6852",
+ "\u{2F8E2}"=>"\u6885",
+ "\u{2F8E3}"=>"\u{2346D}",
+ "\u{2F8E4}"=>"\u688E",
+ "\u{2F8E5}"=>"\u681F",
+ "\u{2F8E6}"=>"\u6914",
+ "\u{2F8E7}"=>"\u3B9D",
+ "\u{2F8E8}"=>"\u6942",
+ "\u{2F8E9}"=>"\u69A3",
+ "\u{2F8EA}"=>"\u69EA",
+ "\u{2F8EB}"=>"\u6AA8",
+ "\u{2F8EC}"=>"\u{236A3}",
+ "\u{2F8ED}"=>"\u6ADB",
+ "\u{2F8EE}"=>"\u3C18",
+ "\u{2F8EF}"=>"\u6B21",
+ "\u{2F8F0}"=>"\u{238A7}",
+ "\u{2F8F1}"=>"\u6B54",
+ "\u{2F8F2}"=>"\u3C4E",
+ "\u{2F8F3}"=>"\u6B72",
+ "\u{2F8F4}"=>"\u6B9F",
+ "\u{2F8F5}"=>"\u6BBA",
+ "\u{2F8F6}"=>"\u6BBB",
+ "\u{2F8F7}"=>"\u{23A8D}",
+ "\u{2F8F8}"=>"\u{21D0B}",
+ "\u{2F8F9}"=>"\u{23AFA}",
+ "\u{2F8FA}"=>"\u6C4E",
+ "\u{2F8FB}"=>"\u{23CBC}",
+ "\u{2F8FC}"=>"\u6CBF",
+ "\u{2F8FD}"=>"\u6CCD",
+ "\u{2F8FE}"=>"\u6C67",
+ "\u{2F8FF}"=>"\u6D16",
+ "\u{2F900}"=>"\u6D3E",
+ "\u{2F901}"=>"\u6D77",
+ "\u{2F902}"=>"\u6D41",
+ "\u{2F903}"=>"\u6D69",
+ "\u{2F904}"=>"\u6D78",
+ "\u{2F905}"=>"\u6D85",
+ "\u{2F906}"=>"\u{23D1E}",
+ "\u{2F907}"=>"\u6D34",
+ "\u{2F908}"=>"\u6E2F",
+ "\u{2F909}"=>"\u6E6E",
+ "\u{2F90A}"=>"\u3D33",
+ "\u{2F90B}"=>"\u6ECB",
+ "\u{2F90C}"=>"\u6EC7",
+ "\u{2F90D}"=>"\u{23ED1}",
+ "\u{2F90E}"=>"\u6DF9",
+ "\u{2F90F}"=>"\u6F6E",
+ "\u{2F910}"=>"\u{23F5E}",
+ "\u{2F911}"=>"\u{23F8E}",
+ "\u{2F912}"=>"\u6FC6",
+ "\u{2F913}"=>"\u7039",
+ "\u{2F914}"=>"\u701E",
+ "\u{2F915}"=>"\u701B",
+ "\u{2F916}"=>"\u3D96",
+ "\u{2F917}"=>"\u704A",
+ "\u{2F918}"=>"\u707D",
+ "\u{2F919}"=>"\u7077",
+ "\u{2F91A}"=>"\u70AD",
+ "\u{2F91B}"=>"\u{20525}",
+ "\u{2F91C}"=>"\u7145",
+ "\u{2F91D}"=>"\u{24263}",
+ "\u{2F91E}"=>"\u719C",
+ "\u{2F91F}"=>"\u{243AB}",
+ "\u{2F920}"=>"\u7228",
+ "\u{2F921}"=>"\u7235",
+ "\u{2F922}"=>"\u7250",
+ "\u{2F923}"=>"\u{24608}",
+ "\u{2F924}"=>"\u7280",
+ "\u{2F925}"=>"\u7295",
+ "\u{2F926}"=>"\u{24735}",
+ "\u{2F927}"=>"\u{24814}",
+ "\u{2F928}"=>"\u737A",
+ "\u{2F929}"=>"\u738B",
+ "\u{2F92A}"=>"\u3EAC",
+ "\u{2F92B}"=>"\u73A5",
+ "\u{2F92C}"=>"\u3EB8",
+ "\u{2F92D}"=>"\u3EB8",
+ "\u{2F92E}"=>"\u7447",
+ "\u{2F92F}"=>"\u745C",
+ "\u{2F930}"=>"\u7471",
+ "\u{2F931}"=>"\u7485",
+ "\u{2F932}"=>"\u74CA",
+ "\u{2F933}"=>"\u3F1B",
+ "\u{2F934}"=>"\u7524",
+ "\u{2F935}"=>"\u{24C36}",
+ "\u{2F936}"=>"\u753E",
+ "\u{2F937}"=>"\u{24C92}",
+ "\u{2F938}"=>"\u7570",
+ "\u{2F939}"=>"\u{2219F}",
+ "\u{2F93A}"=>"\u7610",
+ "\u{2F93B}"=>"\u{24FA1}",
+ "\u{2F93C}"=>"\u{24FB8}",
+ "\u{2F93D}"=>"\u{25044}",
+ "\u{2F93E}"=>"\u3FFC",
+ "\u{2F93F}"=>"\u4008",
+ "\u{2F940}"=>"\u76F4",
+ "\u{2F941}"=>"\u{250F3}",
+ "\u{2F942}"=>"\u{250F2}",
+ "\u{2F943}"=>"\u{25119}",
+ "\u{2F944}"=>"\u{25133}",
+ "\u{2F945}"=>"\u771E",
+ "\u{2F946}"=>"\u771F",
+ "\u{2F947}"=>"\u771F",
+ "\u{2F948}"=>"\u774A",
+ "\u{2F949}"=>"\u4039",
+ "\u{2F94A}"=>"\u778B",
+ "\u{2F94B}"=>"\u4046",
+ "\u{2F94C}"=>"\u4096",
+ "\u{2F94D}"=>"\u{2541D}",
+ "\u{2F94E}"=>"\u784E",
+ "\u{2F94F}"=>"\u788C",
+ "\u{2F950}"=>"\u78CC",
+ "\u{2F951}"=>"\u40E3",
+ "\u{2F952}"=>"\u{25626}",
+ "\u{2F953}"=>"\u7956",
+ "\u{2F954}"=>"\u{2569A}",
+ "\u{2F955}"=>"\u{256C5}",
+ "\u{2F956}"=>"\u798F",
+ "\u{2F957}"=>"\u79EB",
+ "\u{2F958}"=>"\u412F",
+ "\u{2F959}"=>"\u7A40",
+ "\u{2F95A}"=>"\u7A4A",
+ "\u{2F95B}"=>"\u7A4F",
+ "\u{2F95C}"=>"\u{2597C}",
+ "\u{2F95D}"=>"\u{25AA7}",
+ "\u{2F95E}"=>"\u{25AA7}",
+ "\u{2F95F}"=>"\u7AEE",
+ "\u{2F960}"=>"\u4202",
+ "\u{2F961}"=>"\u{25BAB}",
+ "\u{2F962}"=>"\u7BC6",
+ "\u{2F963}"=>"\u7BC9",
+ "\u{2F964}"=>"\u4227",
+ "\u{2F965}"=>"\u{25C80}",
+ "\u{2F966}"=>"\u7CD2",
+ "\u{2F967}"=>"\u42A0",
+ "\u{2F968}"=>"\u7CE8",
+ "\u{2F969}"=>"\u7CE3",
+ "\u{2F96A}"=>"\u7D00",
+ "\u{2F96B}"=>"\u{25F86}",
+ "\u{2F96C}"=>"\u7D63",
+ "\u{2F96D}"=>"\u4301",
+ "\u{2F96E}"=>"\u7DC7",
+ "\u{2F96F}"=>"\u7E02",
+ "\u{2F970}"=>"\u7E45",
+ "\u{2F971}"=>"\u4334",
+ "\u{2F972}"=>"\u{26228}",
+ "\u{2F973}"=>"\u{26247}",
+ "\u{2F974}"=>"\u4359",
+ "\u{2F975}"=>"\u{262D9}",
+ "\u{2F976}"=>"\u7F7A",
+ "\u{2F977}"=>"\u{2633E}",
+ "\u{2F978}"=>"\u7F95",
+ "\u{2F979}"=>"\u7FFA",
+ "\u{2F97A}"=>"\u8005",
+ "\u{2F97B}"=>"\u{264DA}",
+ "\u{2F97C}"=>"\u{26523}",
+ "\u{2F97D}"=>"\u8060",
+ "\u{2F97E}"=>"\u{265A8}",
+ "\u{2F97F}"=>"\u8070",
+ "\u{2F980}"=>"\u{2335F}",
+ "\u{2F981}"=>"\u43D5",
+ "\u{2F982}"=>"\u80B2",
+ "\u{2F983}"=>"\u8103",
+ "\u{2F984}"=>"\u440B",
+ "\u{2F985}"=>"\u813E",
+ "\u{2F986}"=>"\u5AB5",
+ "\u{2F987}"=>"\u{267A7}",
+ "\u{2F988}"=>"\u{267B5}",
+ "\u{2F989}"=>"\u{23393}",
+ "\u{2F98A}"=>"\u{2339C}",
+ "\u{2F98B}"=>"\u8201",
+ "\u{2F98C}"=>"\u8204",
+ "\u{2F98D}"=>"\u8F9E",
+ "\u{2F98E}"=>"\u446B",
+ "\u{2F98F}"=>"\u8291",
+ "\u{2F990}"=>"\u828B",
+ "\u{2F991}"=>"\u829D",
+ "\u{2F992}"=>"\u52B3",
+ "\u{2F993}"=>"\u82B1",
+ "\u{2F994}"=>"\u82B3",
+ "\u{2F995}"=>"\u82BD",
+ "\u{2F996}"=>"\u82E6",
+ "\u{2F997}"=>"\u{26B3C}",
+ "\u{2F998}"=>"\u82E5",
+ "\u{2F999}"=>"\u831D",
+ "\u{2F99A}"=>"\u8363",
+ "\u{2F99B}"=>"\u83AD",
+ "\u{2F99C}"=>"\u8323",
+ "\u{2F99D}"=>"\u83BD",
+ "\u{2F99E}"=>"\u83E7",
+ "\u{2F99F}"=>"\u8457",
+ "\u{2F9A0}"=>"\u8353",
+ "\u{2F9A1}"=>"\u83CA",
+ "\u{2F9A2}"=>"\u83CC",
+ "\u{2F9A3}"=>"\u83DC",
+ "\u{2F9A4}"=>"\u{26C36}",
+ "\u{2F9A5}"=>"\u{26D6B}",
+ "\u{2F9A6}"=>"\u{26CD5}",
+ "\u{2F9A7}"=>"\u452B",
+ "\u{2F9A8}"=>"\u84F1",
+ "\u{2F9A9}"=>"\u84F3",
+ "\u{2F9AA}"=>"\u8516",
+ "\u{2F9AB}"=>"\u{273CA}",
+ "\u{2F9AC}"=>"\u8564",
+ "\u{2F9AD}"=>"\u{26F2C}",
+ "\u{2F9AE}"=>"\u455D",
+ "\u{2F9AF}"=>"\u4561",
+ "\u{2F9B0}"=>"\u{26FB1}",
+ "\u{2F9B1}"=>"\u{270D2}",
+ "\u{2F9B2}"=>"\u456B",
+ "\u{2F9B3}"=>"\u8650",
+ "\u{2F9B4}"=>"\u865C",
+ "\u{2F9B5}"=>"\u8667",
+ "\u{2F9B6}"=>"\u8669",
+ "\u{2F9B7}"=>"\u86A9",
+ "\u{2F9B8}"=>"\u8688",
+ "\u{2F9B9}"=>"\u870E",
+ "\u{2F9BA}"=>"\u86E2",
+ "\u{2F9BB}"=>"\u8779",
+ "\u{2F9BC}"=>"\u8728",
+ "\u{2F9BD}"=>"\u876B",
+ "\u{2F9BE}"=>"\u8786",
+ "\u{2F9BF}"=>"\u45D7",
+ "\u{2F9C0}"=>"\u87E1",
+ "\u{2F9C1}"=>"\u8801",
+ "\u{2F9C2}"=>"\u45F9",
+ "\u{2F9C3}"=>"\u8860",
+ "\u{2F9C4}"=>"\u8863",
+ "\u{2F9C5}"=>"\u{27667}",
+ "\u{2F9C6}"=>"\u88D7",
+ "\u{2F9C7}"=>"\u88DE",
+ "\u{2F9C8}"=>"\u4635",
+ "\u{2F9C9}"=>"\u88FA",
+ "\u{2F9CA}"=>"\u34BB",
+ "\u{2F9CB}"=>"\u{278AE}",
+ "\u{2F9CC}"=>"\u{27966}",
+ "\u{2F9CD}"=>"\u46BE",
+ "\u{2F9CE}"=>"\u46C7",
+ "\u{2F9CF}"=>"\u8AA0",
+ "\u{2F9D0}"=>"\u8AED",
+ "\u{2F9D1}"=>"\u8B8A",
+ "\u{2F9D2}"=>"\u8C55",
+ "\u{2F9D3}"=>"\u{27CA8}",
+ "\u{2F9D4}"=>"\u8CAB",
+ "\u{2F9D5}"=>"\u8CC1",
+ "\u{2F9D6}"=>"\u8D1B",
+ "\u{2F9D7}"=>"\u8D77",
+ "\u{2F9D8}"=>"\u{27F2F}",
+ "\u{2F9D9}"=>"\u{20804}",
+ "\u{2F9DA}"=>"\u8DCB",
+ "\u{2F9DB}"=>"\u8DBC",
+ "\u{2F9DC}"=>"\u8DF0",
+ "\u{2F9DD}"=>"\u{208DE}",
+ "\u{2F9DE}"=>"\u8ED4",
+ "\u{2F9DF}"=>"\u8F38",
+ "\u{2F9E0}"=>"\u{285D2}",
+ "\u{2F9E1}"=>"\u{285ED}",
+ "\u{2F9E2}"=>"\u9094",
+ "\u{2F9E3}"=>"\u90F1",
+ "\u{2F9E4}"=>"\u9111",
+ "\u{2F9E5}"=>"\u{2872E}",
+ "\u{2F9E6}"=>"\u911B",
+ "\u{2F9E7}"=>"\u9238",
+ "\u{2F9E8}"=>"\u92D7",
+ "\u{2F9E9}"=>"\u92D8",
+ "\u{2F9EA}"=>"\u927C",
+ "\u{2F9EB}"=>"\u93F9",
+ "\u{2F9EC}"=>"\u9415",
+ "\u{2F9ED}"=>"\u{28BFA}",
+ "\u{2F9EE}"=>"\u958B",
+ "\u{2F9EF}"=>"\u4995",
+ "\u{2F9F0}"=>"\u95B7",
+ "\u{2F9F1}"=>"\u{28D77}",
+ "\u{2F9F2}"=>"\u49E6",
+ "\u{2F9F3}"=>"\u96C3",
+ "\u{2F9F4}"=>"\u5DB2",
+ "\u{2F9F5}"=>"\u9723",
+ "\u{2F9F6}"=>"\u{29145}",
+ "\u{2F9F7}"=>"\u{2921A}",
+ "\u{2F9F8}"=>"\u4A6E",
+ "\u{2F9F9}"=>"\u4A76",
+ "\u{2F9FA}"=>"\u97E0",
+ "\u{2F9FB}"=>"\u{2940A}",
+ "\u{2F9FC}"=>"\u4AB2",
+ "\u{2F9FD}"=>"\u{29496}",
+ "\u{2F9FE}"=>"\u980B",
+ "\u{2F9FF}"=>"\u980B",
+ "\u{2FA00}"=>"\u9829",
+ "\u{2FA01}"=>"\u{295B6}",
+ "\u{2FA02}"=>"\u98E2",
+ "\u{2FA03}"=>"\u4B33",
+ "\u{2FA04}"=>"\u9929",
+ "\u{2FA05}"=>"\u99A7",
+ "\u{2FA06}"=>"\u99C2",
+ "\u{2FA07}"=>"\u99FE",
+ "\u{2FA08}"=>"\u4BCE",
+ "\u{2FA09}"=>"\u{29B30}",
+ "\u{2FA0A}"=>"\u9B12",
+ "\u{2FA0B}"=>"\u9C40",
+ "\u{2FA0C}"=>"\u9CFD",
+ "\u{2FA0D}"=>"\u4CCE",
+ "\u{2FA0E}"=>"\u4CED",
+ "\u{2FA0F}"=>"\u9D67",
+ "\u{2FA10}"=>"\u{2A0CE}",
+ "\u{2FA11}"=>"\u4CF8",
+ "\u{2FA12}"=>"\u{2A105}",
+ "\u{2FA13}"=>"\u{2A20E}",
+ "\u{2FA14}"=>"\u{2A291}",
+ "\u{2FA15}"=>"\u9EBB",
+ "\u{2FA16}"=>"\u4D56",
+ "\u{2FA17}"=>"\u9EF9",
+ "\u{2FA18}"=>"\u9EFE",
+ "\u{2FA19}"=>"\u9F05",
+ "\u{2FA1A}"=>"\u9F0F",
+ "\u{2FA1B}"=>"\u9F16",
+ "\u{2FA1C}"=>"\u9F3B",
+ "\u{2FA1D}"=>"\u{2A600}",
}.freeze
KOMPATIBLE_TABLE = {
- "\u00A0"=>" ", "\u00A8"=>" \u0308", "\u00AA"=>"a", "\u00AF"=>" \u0304", "\u00B2"=>"2", "\u00B3"=>"3", "\u00B4"=>" \u0301", "\u00B5"=>"\u03BC",
- "\u00B8"=>" \u0327", "\u00B9"=>"1", "\u00BA"=>"o", "\u00BC"=>"1\u20444", "\u00BD"=>"1\u20442", "\u00BE"=>"3\u20444", "\u0132"=>"IJ", "\u0133"=>"ij",
- "\u013F"=>"L\u00B7", "\u0140"=>"l\u00B7", "\u0149"=>"\u02BCn", "\u017F"=>"s", "\u01C4"=>"D\u017D", "\u01C5"=>"D\u017E", "\u01C6"=>"d\u017E", "\u01C7"=>"LJ",
- "\u01C8"=>"Lj", "\u01C9"=>"lj", "\u01CA"=>"NJ", "\u01CB"=>"Nj", "\u01CC"=>"nj", "\u01F1"=>"DZ", "\u01F2"=>"Dz", "\u01F3"=>"dz",
- "\u02B0"=>"h", "\u02B1"=>"\u0266", "\u02B2"=>"j", "\u02B3"=>"r", "\u02B4"=>"\u0279", "\u02B5"=>"\u027B", "\u02B6"=>"\u0281", "\u02B7"=>"w",
- "\u02B8"=>"y", "\u02D8"=>" \u0306", "\u02D9"=>" \u0307", "\u02DA"=>" \u030A", "\u02DB"=>" \u0328", "\u02DC"=>" \u0303", "\u02DD"=>" \u030B", "\u02E0"=>"\u0263",
- "\u02E1"=>"l", "\u02E2"=>"s", "\u02E3"=>"x", "\u02E4"=>"\u0295", "\u037A"=>" \u0345", "\u0384"=>" \u0301", "\u03D0"=>"\u03B2", "\u03D1"=>"\u03B8",
- "\u03D2"=>"\u03A5", "\u03D5"=>"\u03C6", "\u03D6"=>"\u03C0", "\u03F0"=>"\u03BA", "\u03F1"=>"\u03C1", "\u03F2"=>"\u03C2", "\u03F4"=>"\u0398", "\u03F5"=>"\u03B5",
- "\u03F9"=>"\u03A3", "\u0587"=>"\u0565\u0582", "\u0675"=>"\u0627\u0674", "\u0676"=>"\u0648\u0674", "\u0677"=>"\u06C7\u0674", "\u0678"=>"\u064A\u0674", "\u0E33"=>"\u0E4D\u0E32", "\u0EB3"=>"\u0ECD\u0EB2",
- "\u0EDC"=>"\u0EAB\u0E99", "\u0EDD"=>"\u0EAB\u0EA1", "\u0F0C"=>"\u0F0B", "\u0F77"=>"\u0FB2\u0F81", "\u0F79"=>"\u0FB3\u0F81", "\u10FC"=>"\u10DC", "\u1D2C"=>"A", "\u1D2D"=>"\u00C6",
- "\u1D2E"=>"B", "\u1D30"=>"D", "\u1D31"=>"E", "\u1D32"=>"\u018E", "\u1D33"=>"G", "\u1D34"=>"H", "\u1D35"=>"I", "\u1D36"=>"J",
- "\u1D37"=>"K", "\u1D38"=>"L", "\u1D39"=>"M", "\u1D3A"=>"N", "\u1D3C"=>"O", "\u1D3D"=>"\u0222", "\u1D3E"=>"P", "\u1D3F"=>"R",
- "\u1D40"=>"T", "\u1D41"=>"U", "\u1D42"=>"W", "\u1D43"=>"a", "\u1D44"=>"\u0250", "\u1D45"=>"\u0251", "\u1D46"=>"\u1D02", "\u1D47"=>"b",
- "\u1D48"=>"d", "\u1D49"=>"e", "\u1D4A"=>"\u0259", "\u1D4B"=>"\u025B", "\u1D4C"=>"\u025C", "\u1D4D"=>"g", "\u1D4F"=>"k", "\u1D50"=>"m",
- "\u1D51"=>"\u014B", "\u1D52"=>"o", "\u1D53"=>"\u0254", "\u1D54"=>"\u1D16", "\u1D55"=>"\u1D17", "\u1D56"=>"p", "\u1D57"=>"t", "\u1D58"=>"u",
- "\u1D59"=>"\u1D1D", "\u1D5A"=>"\u026F", "\u1D5B"=>"v", "\u1D5C"=>"\u1D25", "\u1D5D"=>"\u03B2", "\u1D5E"=>"\u03B3", "\u1D5F"=>"\u03B4", "\u1D60"=>"\u03C6",
- "\u1D61"=>"\u03C7", "\u1D62"=>"i", "\u1D63"=>"r", "\u1D64"=>"u", "\u1D65"=>"v", "\u1D66"=>"\u03B2", "\u1D67"=>"\u03B3", "\u1D68"=>"\u03C1",
- "\u1D69"=>"\u03C6", "\u1D6A"=>"\u03C7", "\u1D78"=>"\u043D", "\u1D9B"=>"\u0252", "\u1D9C"=>"c", "\u1D9D"=>"\u0255", "\u1D9E"=>"\u00F0", "\u1D9F"=>"\u025C",
- "\u1DA0"=>"f", "\u1DA1"=>"\u025F", "\u1DA2"=>"\u0261", "\u1DA3"=>"\u0265", "\u1DA4"=>"\u0268", "\u1DA5"=>"\u0269", "\u1DA6"=>"\u026A", "\u1DA7"=>"\u1D7B",
- "\u1DA8"=>"\u029D", "\u1DA9"=>"\u026D", "\u1DAA"=>"\u1D85", "\u1DAB"=>"\u029F", "\u1DAC"=>"\u0271", "\u1DAD"=>"\u0270", "\u1DAE"=>"\u0272", "\u1DAF"=>"\u0273",
- "\u1DB0"=>"\u0274", "\u1DB1"=>"\u0275", "\u1DB2"=>"\u0278", "\u1DB3"=>"\u0282", "\u1DB4"=>"\u0283", "\u1DB5"=>"\u01AB", "\u1DB6"=>"\u0289", "\u1DB7"=>"\u028A",
- "\u1DB8"=>"\u1D1C", "\u1DB9"=>"\u028B", "\u1DBA"=>"\u028C", "\u1DBB"=>"z", "\u1DBC"=>"\u0290", "\u1DBD"=>"\u0291", "\u1DBE"=>"\u0292", "\u1DBF"=>"\u03B8",
- "\u1E9A"=>"a\u02BE", "\u1FBD"=>" \u0313", "\u1FBF"=>" \u0313", "\u1FC0"=>" \u0342", "\u1FFE"=>" \u0314", "\u2002"=>" ", "\u2003"=>" ", "\u2004"=>" ",
- "\u2005"=>" ", "\u2006"=>" ", "\u2007"=>" ", "\u2008"=>" ", "\u2009"=>" ", "\u200A"=>" ", "\u2011"=>"\u2010", "\u2017"=>" \u0333",
- "\u2024"=>".", "\u2025"=>"..", "\u2026"=>"...", "\u202F"=>" ", "\u2033"=>"\u2032\u2032", "\u2034"=>"\u2032\u2032\u2032", "\u2036"=>"\u2035\u2035", "\u2037"=>"\u2035\u2035\u2035",
- "\u203C"=>"!!", "\u203E"=>" \u0305", "\u2047"=>"??", "\u2048"=>"?!", "\u2049"=>"!?", "\u2057"=>"\u2032\u2032\u2032\u2032", "\u205F"=>" ", "\u2070"=>"0",
- "\u2071"=>"i", "\u2074"=>"4", "\u2075"=>"5", "\u2076"=>"6", "\u2077"=>"7", "\u2078"=>"8", "\u2079"=>"9", "\u207A"=>"+",
- "\u207B"=>"\u2212", "\u207C"=>"=", "\u207D"=>"(", "\u207E"=>")", "\u207F"=>"n", "\u2080"=>"0", "\u2081"=>"1", "\u2082"=>"2",
- "\u2083"=>"3", "\u2084"=>"4", "\u2085"=>"5", "\u2086"=>"6", "\u2087"=>"7", "\u2088"=>"8", "\u2089"=>"9", "\u208A"=>"+",
- "\u208B"=>"\u2212", "\u208C"=>"=", "\u208D"=>"(", "\u208E"=>")", "\u2090"=>"a", "\u2091"=>"e", "\u2092"=>"o", "\u2093"=>"x",
- "\u2094"=>"\u0259", "\u2095"=>"h", "\u2096"=>"k", "\u2097"=>"l", "\u2098"=>"m", "\u2099"=>"n", "\u209A"=>"p", "\u209B"=>"s",
- "\u209C"=>"t", "\u20A8"=>"Rs", "\u2100"=>"a/c", "\u2101"=>"a/s", "\u2102"=>"C", "\u2103"=>"\u00B0C", "\u2105"=>"c/o", "\u2106"=>"c/u",
- "\u2107"=>"\u0190", "\u2109"=>"\u00B0F", "\u210A"=>"g", "\u210B"=>"H", "\u210C"=>"H", "\u210D"=>"H", "\u210E"=>"h", "\u210F"=>"\u0127",
- "\u2110"=>"I", "\u2111"=>"I", "\u2112"=>"L", "\u2113"=>"l", "\u2115"=>"N", "\u2116"=>"No", "\u2119"=>"P", "\u211A"=>"Q",
- "\u211B"=>"R", "\u211C"=>"R", "\u211D"=>"R", "\u2120"=>"SM", "\u2121"=>"TEL", "\u2122"=>"TM", "\u2124"=>"Z", "\u2128"=>"Z",
- "\u212C"=>"B", "\u212D"=>"C", "\u212F"=>"e", "\u2130"=>"E", "\u2131"=>"F", "\u2133"=>"M", "\u2134"=>"o", "\u2135"=>"\u05D0",
- "\u2136"=>"\u05D1", "\u2137"=>"\u05D2", "\u2138"=>"\u05D3", "\u2139"=>"i", "\u213B"=>"FAX", "\u213C"=>"\u03C0", "\u213D"=>"\u03B3", "\u213E"=>"\u0393",
- "\u213F"=>"\u03A0", "\u2140"=>"\u2211", "\u2145"=>"D", "\u2146"=>"d", "\u2147"=>"e", "\u2148"=>"i", "\u2149"=>"j", "\u2150"=>"1\u20447",
- "\u2151"=>"1\u20449", "\u2152"=>"1\u204410", "\u2153"=>"1\u20443", "\u2154"=>"2\u20443", "\u2155"=>"1\u20445", "\u2156"=>"2\u20445", "\u2157"=>"3\u20445", "\u2158"=>"4\u20445",
- "\u2159"=>"1\u20446", "\u215A"=>"5\u20446", "\u215B"=>"1\u20448", "\u215C"=>"3\u20448", "\u215D"=>"5\u20448", "\u215E"=>"7\u20448", "\u215F"=>"1\u2044", "\u2160"=>"I",
- "\u2161"=>"II", "\u2162"=>"III", "\u2163"=>"IV", "\u2164"=>"V", "\u2165"=>"VI", "\u2166"=>"VII", "\u2167"=>"VIII", "\u2168"=>"IX",
- "\u2169"=>"X", "\u216A"=>"XI", "\u216B"=>"XII", "\u216C"=>"L", "\u216D"=>"C", "\u216E"=>"D", "\u216F"=>"M", "\u2170"=>"i",
- "\u2171"=>"ii", "\u2172"=>"iii", "\u2173"=>"iv", "\u2174"=>"v", "\u2175"=>"vi", "\u2176"=>"vii", "\u2177"=>"viii", "\u2178"=>"ix",
- "\u2179"=>"x", "\u217A"=>"xi", "\u217B"=>"xii", "\u217C"=>"l", "\u217D"=>"c", "\u217E"=>"d", "\u217F"=>"m", "\u2189"=>"0\u20443",
- "\u222C"=>"\u222B\u222B", "\u222D"=>"\u222B\u222B\u222B", "\u222F"=>"\u222E\u222E", "\u2230"=>"\u222E\u222E\u222E", "\u2460"=>"1", "\u2461"=>"2", "\u2462"=>"3", "\u2463"=>"4",
- "\u2464"=>"5", "\u2465"=>"6", "\u2466"=>"7", "\u2467"=>"8", "\u2468"=>"9", "\u2469"=>"10", "\u246A"=>"11", "\u246B"=>"12",
- "\u246C"=>"13", "\u246D"=>"14", "\u246E"=>"15", "\u246F"=>"16", "\u2470"=>"17", "\u2471"=>"18", "\u2472"=>"19", "\u2473"=>"20",
- "\u2474"=>"(1)", "\u2475"=>"(2)", "\u2476"=>"(3)", "\u2477"=>"(4)", "\u2478"=>"(5)", "\u2479"=>"(6)", "\u247A"=>"(7)", "\u247B"=>"(8)",
- "\u247C"=>"(9)", "\u247D"=>"(10)", "\u247E"=>"(11)", "\u247F"=>"(12)", "\u2480"=>"(13)", "\u2481"=>"(14)", "\u2482"=>"(15)", "\u2483"=>"(16)",
- "\u2484"=>"(17)", "\u2485"=>"(18)", "\u2486"=>"(19)", "\u2487"=>"(20)", "\u2488"=>"1.", "\u2489"=>"2.", "\u248A"=>"3.", "\u248B"=>"4.",
- "\u248C"=>"5.", "\u248D"=>"6.", "\u248E"=>"7.", "\u248F"=>"8.", "\u2490"=>"9.", "\u2491"=>"10.", "\u2492"=>"11.", "\u2493"=>"12.",
- "\u2494"=>"13.", "\u2495"=>"14.", "\u2496"=>"15.", "\u2497"=>"16.", "\u2498"=>"17.", "\u2499"=>"18.", "\u249A"=>"19.", "\u249B"=>"20.",
- "\u249C"=>"(a)", "\u249D"=>"(b)", "\u249E"=>"(c)", "\u249F"=>"(d)", "\u24A0"=>"(e)", "\u24A1"=>"(f)", "\u24A2"=>"(g)", "\u24A3"=>"(h)",
- "\u24A4"=>"(i)", "\u24A5"=>"(j)", "\u24A6"=>"(k)", "\u24A7"=>"(l)", "\u24A8"=>"(m)", "\u24A9"=>"(n)", "\u24AA"=>"(o)", "\u24AB"=>"(p)",
- "\u24AC"=>"(q)", "\u24AD"=>"(r)", "\u24AE"=>"(s)", "\u24AF"=>"(t)", "\u24B0"=>"(u)", "\u24B1"=>"(v)", "\u24B2"=>"(w)", "\u24B3"=>"(x)",
- "\u24B4"=>"(y)", "\u24B5"=>"(z)", "\u24B6"=>"A", "\u24B7"=>"B", "\u24B8"=>"C", "\u24B9"=>"D", "\u24BA"=>"E", "\u24BB"=>"F",
- "\u24BC"=>"G", "\u24BD"=>"H", "\u24BE"=>"I", "\u24BF"=>"J", "\u24C0"=>"K", "\u24C1"=>"L", "\u24C2"=>"M", "\u24C3"=>"N",
- "\u24C4"=>"O", "\u24C5"=>"P", "\u24C6"=>"Q", "\u24C7"=>"R", "\u24C8"=>"S", "\u24C9"=>"T", "\u24CA"=>"U", "\u24CB"=>"V",
- "\u24CC"=>"W", "\u24CD"=>"X", "\u24CE"=>"Y", "\u24CF"=>"Z", "\u24D0"=>"a", "\u24D1"=>"b", "\u24D2"=>"c", "\u24D3"=>"d",
- "\u24D4"=>"e", "\u24D5"=>"f", "\u24D6"=>"g", "\u24D7"=>"h", "\u24D8"=>"i", "\u24D9"=>"j", "\u24DA"=>"k", "\u24DB"=>"l",
- "\u24DC"=>"m", "\u24DD"=>"n", "\u24DE"=>"o", "\u24DF"=>"p", "\u24E0"=>"q", "\u24E1"=>"r", "\u24E2"=>"s", "\u24E3"=>"t",
- "\u24E4"=>"u", "\u24E5"=>"v", "\u24E6"=>"w", "\u24E7"=>"x", "\u24E8"=>"y", "\u24E9"=>"z", "\u24EA"=>"0", "\u2A0C"=>"\u222B\u222B\u222B\u222B",
- "\u2A74"=>"::=", "\u2A75"=>"==", "\u2A76"=>"===", "\u2C7C"=>"j", "\u2C7D"=>"V", "\u2D6F"=>"\u2D61", "\u2E9F"=>"\u6BCD", "\u2EF3"=>"\u9F9F",
- "\u2F00"=>"\u4E00", "\u2F01"=>"\u4E28", "\u2F02"=>"\u4E36", "\u2F03"=>"\u4E3F", "\u2F04"=>"\u4E59", "\u2F05"=>"\u4E85", "\u2F06"=>"\u4E8C", "\u2F07"=>"\u4EA0",
- "\u2F08"=>"\u4EBA", "\u2F09"=>"\u513F", "\u2F0A"=>"\u5165", "\u2F0B"=>"\u516B", "\u2F0C"=>"\u5182", "\u2F0D"=>"\u5196", "\u2F0E"=>"\u51AB", "\u2F0F"=>"\u51E0",
- "\u2F10"=>"\u51F5", "\u2F11"=>"\u5200", "\u2F12"=>"\u529B", "\u2F13"=>"\u52F9", "\u2F14"=>"\u5315", "\u2F15"=>"\u531A", "\u2F16"=>"\u5338", "\u2F17"=>"\u5341",
- "\u2F18"=>"\u535C", "\u2F19"=>"\u5369", "\u2F1A"=>"\u5382", "\u2F1B"=>"\u53B6", "\u2F1C"=>"\u53C8", "\u2F1D"=>"\u53E3", "\u2F1E"=>"\u56D7", "\u2F1F"=>"\u571F",
- "\u2F20"=>"\u58EB", "\u2F21"=>"\u5902", "\u2F22"=>"\u590A", "\u2F23"=>"\u5915", "\u2F24"=>"\u5927", "\u2F25"=>"\u5973", "\u2F26"=>"\u5B50", "\u2F27"=>"\u5B80",
- "\u2F28"=>"\u5BF8", "\u2F29"=>"\u5C0F", "\u2F2A"=>"\u5C22", "\u2F2B"=>"\u5C38", "\u2F2C"=>"\u5C6E", "\u2F2D"=>"\u5C71", "\u2F2E"=>"\u5DDB", "\u2F2F"=>"\u5DE5",
- "\u2F30"=>"\u5DF1", "\u2F31"=>"\u5DFE", "\u2F32"=>"\u5E72", "\u2F33"=>"\u5E7A", "\u2F34"=>"\u5E7F", "\u2F35"=>"\u5EF4", "\u2F36"=>"\u5EFE", "\u2F37"=>"\u5F0B",
- "\u2F38"=>"\u5F13", "\u2F39"=>"\u5F50", "\u2F3A"=>"\u5F61", "\u2F3B"=>"\u5F73", "\u2F3C"=>"\u5FC3", "\u2F3D"=>"\u6208", "\u2F3E"=>"\u6236", "\u2F3F"=>"\u624B",
- "\u2F40"=>"\u652F", "\u2F41"=>"\u6534", "\u2F42"=>"\u6587", "\u2F43"=>"\u6597", "\u2F44"=>"\u65A4", "\u2F45"=>"\u65B9", "\u2F46"=>"\u65E0", "\u2F47"=>"\u65E5",
- "\u2F48"=>"\u66F0", "\u2F49"=>"\u6708", "\u2F4A"=>"\u6728", "\u2F4B"=>"\u6B20", "\u2F4C"=>"\u6B62", "\u2F4D"=>"\u6B79", "\u2F4E"=>"\u6BB3", "\u2F4F"=>"\u6BCB",
- "\u2F50"=>"\u6BD4", "\u2F51"=>"\u6BDB", "\u2F52"=>"\u6C0F", "\u2F53"=>"\u6C14", "\u2F54"=>"\u6C34", "\u2F55"=>"\u706B", "\u2F56"=>"\u722A", "\u2F57"=>"\u7236",
- "\u2F58"=>"\u723B", "\u2F59"=>"\u723F", "\u2F5A"=>"\u7247", "\u2F5B"=>"\u7259", "\u2F5C"=>"\u725B", "\u2F5D"=>"\u72AC", "\u2F5E"=>"\u7384", "\u2F5F"=>"\u7389",
- "\u2F60"=>"\u74DC", "\u2F61"=>"\u74E6", "\u2F62"=>"\u7518", "\u2F63"=>"\u751F", "\u2F64"=>"\u7528", "\u2F65"=>"\u7530", "\u2F66"=>"\u758B", "\u2F67"=>"\u7592",
- "\u2F68"=>"\u7676", "\u2F69"=>"\u767D", "\u2F6A"=>"\u76AE", "\u2F6B"=>"\u76BF", "\u2F6C"=>"\u76EE", "\u2F6D"=>"\u77DB", "\u2F6E"=>"\u77E2", "\u2F6F"=>"\u77F3",
- "\u2F70"=>"\u793A", "\u2F71"=>"\u79B8", "\u2F72"=>"\u79BE", "\u2F73"=>"\u7A74", "\u2F74"=>"\u7ACB", "\u2F75"=>"\u7AF9", "\u2F76"=>"\u7C73", "\u2F77"=>"\u7CF8",
- "\u2F78"=>"\u7F36", "\u2F79"=>"\u7F51", "\u2F7A"=>"\u7F8A", "\u2F7B"=>"\u7FBD", "\u2F7C"=>"\u8001", "\u2F7D"=>"\u800C", "\u2F7E"=>"\u8012", "\u2F7F"=>"\u8033",
- "\u2F80"=>"\u807F", "\u2F81"=>"\u8089", "\u2F82"=>"\u81E3", "\u2F83"=>"\u81EA", "\u2F84"=>"\u81F3", "\u2F85"=>"\u81FC", "\u2F86"=>"\u820C", "\u2F87"=>"\u821B",
- "\u2F88"=>"\u821F", "\u2F89"=>"\u826E", "\u2F8A"=>"\u8272", "\u2F8B"=>"\u8278", "\u2F8C"=>"\u864D", "\u2F8D"=>"\u866B", "\u2F8E"=>"\u8840", "\u2F8F"=>"\u884C",
- "\u2F90"=>"\u8863", "\u2F91"=>"\u897E", "\u2F92"=>"\u898B", "\u2F93"=>"\u89D2", "\u2F94"=>"\u8A00", "\u2F95"=>"\u8C37", "\u2F96"=>"\u8C46", "\u2F97"=>"\u8C55",
- "\u2F98"=>"\u8C78", "\u2F99"=>"\u8C9D", "\u2F9A"=>"\u8D64", "\u2F9B"=>"\u8D70", "\u2F9C"=>"\u8DB3", "\u2F9D"=>"\u8EAB", "\u2F9E"=>"\u8ECA", "\u2F9F"=>"\u8F9B",
- "\u2FA0"=>"\u8FB0", "\u2FA1"=>"\u8FB5", "\u2FA2"=>"\u9091", "\u2FA3"=>"\u9149", "\u2FA4"=>"\u91C6", "\u2FA5"=>"\u91CC", "\u2FA6"=>"\u91D1", "\u2FA7"=>"\u9577",
- "\u2FA8"=>"\u9580", "\u2FA9"=>"\u961C", "\u2FAA"=>"\u96B6", "\u2FAB"=>"\u96B9", "\u2FAC"=>"\u96E8", "\u2FAD"=>"\u9751", "\u2FAE"=>"\u975E", "\u2FAF"=>"\u9762",
- "\u2FB0"=>"\u9769", "\u2FB1"=>"\u97CB", "\u2FB2"=>"\u97ED", "\u2FB3"=>"\u97F3", "\u2FB4"=>"\u9801", "\u2FB5"=>"\u98A8", "\u2FB6"=>"\u98DB", "\u2FB7"=>"\u98DF",
- "\u2FB8"=>"\u9996", "\u2FB9"=>"\u9999", "\u2FBA"=>"\u99AC", "\u2FBB"=>"\u9AA8", "\u2FBC"=>"\u9AD8", "\u2FBD"=>"\u9ADF", "\u2FBE"=>"\u9B25", "\u2FBF"=>"\u9B2F",
- "\u2FC0"=>"\u9B32", "\u2FC1"=>"\u9B3C", "\u2FC2"=>"\u9B5A", "\u2FC3"=>"\u9CE5", "\u2FC4"=>"\u9E75", "\u2FC5"=>"\u9E7F", "\u2FC6"=>"\u9EA5", "\u2FC7"=>"\u9EBB",
- "\u2FC8"=>"\u9EC3", "\u2FC9"=>"\u9ECD", "\u2FCA"=>"\u9ED1", "\u2FCB"=>"\u9EF9", "\u2FCC"=>"\u9EFD", "\u2FCD"=>"\u9F0E", "\u2FCE"=>"\u9F13", "\u2FCF"=>"\u9F20",
- "\u2FD0"=>"\u9F3B", "\u2FD1"=>"\u9F4A", "\u2FD2"=>"\u9F52", "\u2FD3"=>"\u9F8D", "\u2FD4"=>"\u9F9C", "\u2FD5"=>"\u9FA0", "\u3000"=>" ", "\u3036"=>"\u3012",
- "\u3038"=>"\u5341", "\u3039"=>"\u5344", "\u303A"=>"\u5345", "\u309B"=>" \u3099", "\u309C"=>" \u309A", "\u309F"=>"\u3088\u308A", "\u30FF"=>"\u30B3\u30C8", "\u3131"=>"\u1100",
- "\u3132"=>"\u1101", "\u3133"=>"\u11AA", "\u3134"=>"\u1102", "\u3135"=>"\u11AC", "\u3136"=>"\u11AD", "\u3137"=>"\u1103", "\u3138"=>"\u1104", "\u3139"=>"\u1105",
- "\u313A"=>"\u11B0", "\u313B"=>"\u11B1", "\u313C"=>"\u11B2", "\u313D"=>"\u11B3", "\u313E"=>"\u11B4", "\u313F"=>"\u11B5", "\u3140"=>"\u111A", "\u3141"=>"\u1106",
- "\u3142"=>"\u1107", "\u3143"=>"\u1108", "\u3144"=>"\u1121", "\u3145"=>"\u1109", "\u3146"=>"\u110A", "\u3147"=>"\u110B", "\u3148"=>"\u110C", "\u3149"=>"\u110D",
- "\u314A"=>"\u110E", "\u314B"=>"\u110F", "\u314C"=>"\u1110", "\u314D"=>"\u1111", "\u314E"=>"\u1112", "\u314F"=>"\u1161", "\u3150"=>"\u1162", "\u3151"=>"\u1163",
- "\u3152"=>"\u1164", "\u3153"=>"\u1165", "\u3154"=>"\u1166", "\u3155"=>"\u1167", "\u3156"=>"\u1168", "\u3157"=>"\u1169", "\u3158"=>"\u116A", "\u3159"=>"\u116B",
- "\u315A"=>"\u116C", "\u315B"=>"\u116D", "\u315C"=>"\u116E", "\u315D"=>"\u116F", "\u315E"=>"\u1170", "\u315F"=>"\u1171", "\u3160"=>"\u1172", "\u3161"=>"\u1173",
- "\u3162"=>"\u1174", "\u3163"=>"\u1175", "\u3164"=>"\u1160", "\u3165"=>"\u1114", "\u3166"=>"\u1115", "\u3167"=>"\u11C7", "\u3168"=>"\u11C8", "\u3169"=>"\u11CC",
- "\u316A"=>"\u11CE", "\u316B"=>"\u11D3", "\u316C"=>"\u11D7", "\u316D"=>"\u11D9", "\u316E"=>"\u111C", "\u316F"=>"\u11DD", "\u3170"=>"\u11DF", "\u3171"=>"\u111D",
- "\u3172"=>"\u111E", "\u3173"=>"\u1120", "\u3174"=>"\u1122", "\u3175"=>"\u1123", "\u3176"=>"\u1127", "\u3177"=>"\u1129", "\u3178"=>"\u112B", "\u3179"=>"\u112C",
- "\u317A"=>"\u112D", "\u317B"=>"\u112E", "\u317C"=>"\u112F", "\u317D"=>"\u1132", "\u317E"=>"\u1136", "\u317F"=>"\u1140", "\u3180"=>"\u1147", "\u3181"=>"\u114C",
- "\u3182"=>"\u11F1", "\u3183"=>"\u11F2", "\u3184"=>"\u1157", "\u3185"=>"\u1158", "\u3186"=>"\u1159", "\u3187"=>"\u1184", "\u3188"=>"\u1185", "\u3189"=>"\u1188",
- "\u318A"=>"\u1191", "\u318B"=>"\u1192", "\u318C"=>"\u1194", "\u318D"=>"\u119E", "\u318E"=>"\u11A1", "\u3192"=>"\u4E00", "\u3193"=>"\u4E8C", "\u3194"=>"\u4E09",
- "\u3195"=>"\u56DB", "\u3196"=>"\u4E0A", "\u3197"=>"\u4E2D", "\u3198"=>"\u4E0B", "\u3199"=>"\u7532", "\u319A"=>"\u4E59", "\u319B"=>"\u4E19", "\u319C"=>"\u4E01",
- "\u319D"=>"\u5929", "\u319E"=>"\u5730", "\u319F"=>"\u4EBA", "\u3200"=>"(\u1100)", "\u3201"=>"(\u1102)", "\u3202"=>"(\u1103)", "\u3203"=>"(\u1105)", "\u3204"=>"(\u1106)",
- "\u3205"=>"(\u1107)", "\u3206"=>"(\u1109)", "\u3207"=>"(\u110B)", "\u3208"=>"(\u110C)", "\u3209"=>"(\u110E)", "\u320A"=>"(\u110F)", "\u320B"=>"(\u1110)", "\u320C"=>"(\u1111)",
- "\u320D"=>"(\u1112)", "\u320E"=>"(\u1100\u1161)", "\u320F"=>"(\u1102\u1161)", "\u3210"=>"(\u1103\u1161)", "\u3211"=>"(\u1105\u1161)", "\u3212"=>"(\u1106\u1161)", "\u3213"=>"(\u1107\u1161)", "\u3214"=>"(\u1109\u1161)",
- "\u3215"=>"(\u110B\u1161)", "\u3216"=>"(\u110C\u1161)", "\u3217"=>"(\u110E\u1161)", "\u3218"=>"(\u110F\u1161)", "\u3219"=>"(\u1110\u1161)", "\u321A"=>"(\u1111\u1161)", "\u321B"=>"(\u1112\u1161)", "\u321C"=>"(\u110C\u116E)",
- "\u321D"=>"(\u110B\u1169\u110C\u1165\u11AB)", "\u321E"=>"(\u110B\u1169\u1112\u116E)", "\u3220"=>"(\u4E00)", "\u3221"=>"(\u4E8C)", "\u3222"=>"(\u4E09)", "\u3223"=>"(\u56DB)", "\u3224"=>"(\u4E94)", "\u3225"=>"(\u516D)",
- "\u3226"=>"(\u4E03)", "\u3227"=>"(\u516B)", "\u3228"=>"(\u4E5D)", "\u3229"=>"(\u5341)", "\u322A"=>"(\u6708)", "\u322B"=>"(\u706B)", "\u322C"=>"(\u6C34)", "\u322D"=>"(\u6728)",
- "\u322E"=>"(\u91D1)", "\u322F"=>"(\u571F)", "\u3230"=>"(\u65E5)", "\u3231"=>"(\u682A)", "\u3232"=>"(\u6709)", "\u3233"=>"(\u793E)", "\u3234"=>"(\u540D)", "\u3235"=>"(\u7279)",
- "\u3236"=>"(\u8CA1)", "\u3237"=>"(\u795D)", "\u3238"=>"(\u52B4)", "\u3239"=>"(\u4EE3)", "\u323A"=>"(\u547C)", "\u323B"=>"(\u5B66)", "\u323C"=>"(\u76E3)", "\u323D"=>"(\u4F01)",
- "\u323E"=>"(\u8CC7)", "\u323F"=>"(\u5354)", "\u3240"=>"(\u796D)", "\u3241"=>"(\u4F11)", "\u3242"=>"(\u81EA)", "\u3243"=>"(\u81F3)", "\u3244"=>"\u554F", "\u3245"=>"\u5E7C",
- "\u3246"=>"\u6587", "\u3247"=>"\u7B8F", "\u3250"=>"PTE", "\u3251"=>"21", "\u3252"=>"22", "\u3253"=>"23", "\u3254"=>"24", "\u3255"=>"25",
- "\u3256"=>"26", "\u3257"=>"27", "\u3258"=>"28", "\u3259"=>"29", "\u325A"=>"30", "\u325B"=>"31", "\u325C"=>"32", "\u325D"=>"33",
- "\u325E"=>"34", "\u325F"=>"35", "\u3260"=>"\u1100", "\u3261"=>"\u1102", "\u3262"=>"\u1103", "\u3263"=>"\u1105", "\u3264"=>"\u1106", "\u3265"=>"\u1107",
- "\u3266"=>"\u1109", "\u3267"=>"\u110B", "\u3268"=>"\u110C", "\u3269"=>"\u110E", "\u326A"=>"\u110F", "\u326B"=>"\u1110", "\u326C"=>"\u1111", "\u326D"=>"\u1112",
- "\u326E"=>"\u1100\u1161", "\u326F"=>"\u1102\u1161", "\u3270"=>"\u1103\u1161", "\u3271"=>"\u1105\u1161", "\u3272"=>"\u1106\u1161", "\u3273"=>"\u1107\u1161", "\u3274"=>"\u1109\u1161", "\u3275"=>"\u110B\u1161",
- "\u3276"=>"\u110C\u1161", "\u3277"=>"\u110E\u1161", "\u3278"=>"\u110F\u1161", "\u3279"=>"\u1110\u1161", "\u327A"=>"\u1111\u1161", "\u327B"=>"\u1112\u1161", "\u327C"=>"\u110E\u1161\u11B7\u1100\u1169", "\u327D"=>"\u110C\u116E\u110B\u1174",
- "\u327E"=>"\u110B\u116E", "\u3280"=>"\u4E00", "\u3281"=>"\u4E8C", "\u3282"=>"\u4E09", "\u3283"=>"\u56DB", "\u3284"=>"\u4E94", "\u3285"=>"\u516D", "\u3286"=>"\u4E03",
- "\u3287"=>"\u516B", "\u3288"=>"\u4E5D", "\u3289"=>"\u5341", "\u328A"=>"\u6708", "\u328B"=>"\u706B", "\u328C"=>"\u6C34", "\u328D"=>"\u6728", "\u328E"=>"\u91D1",
- "\u328F"=>"\u571F", "\u3290"=>"\u65E5", "\u3291"=>"\u682A", "\u3292"=>"\u6709", "\u3293"=>"\u793E", "\u3294"=>"\u540D", "\u3295"=>"\u7279", "\u3296"=>"\u8CA1",
- "\u3297"=>"\u795D", "\u3298"=>"\u52B4", "\u3299"=>"\u79D8", "\u329A"=>"\u7537", "\u329B"=>"\u5973", "\u329C"=>"\u9069", "\u329D"=>"\u512A", "\u329E"=>"\u5370",
- "\u329F"=>"\u6CE8", "\u32A0"=>"\u9805", "\u32A1"=>"\u4F11", "\u32A2"=>"\u5199", "\u32A3"=>"\u6B63", "\u32A4"=>"\u4E0A", "\u32A5"=>"\u4E2D", "\u32A6"=>"\u4E0B",
- "\u32A7"=>"\u5DE6", "\u32A8"=>"\u53F3", "\u32A9"=>"\u533B", "\u32AA"=>"\u5B97", "\u32AB"=>"\u5B66", "\u32AC"=>"\u76E3", "\u32AD"=>"\u4F01", "\u32AE"=>"\u8CC7",
- "\u32AF"=>"\u5354", "\u32B0"=>"\u591C", "\u32B1"=>"36", "\u32B2"=>"37", "\u32B3"=>"38", "\u32B4"=>"39", "\u32B5"=>"40", "\u32B6"=>"41",
- "\u32B7"=>"42", "\u32B8"=>"43", "\u32B9"=>"44", "\u32BA"=>"45", "\u32BB"=>"46", "\u32BC"=>"47", "\u32BD"=>"48", "\u32BE"=>"49",
- "\u32BF"=>"50", "\u32C0"=>"1\u6708", "\u32C1"=>"2\u6708", "\u32C2"=>"3\u6708", "\u32C3"=>"4\u6708", "\u32C4"=>"5\u6708", "\u32C5"=>"6\u6708", "\u32C6"=>"7\u6708",
- "\u32C7"=>"8\u6708", "\u32C8"=>"9\u6708", "\u32C9"=>"10\u6708", "\u32CA"=>"11\u6708", "\u32CB"=>"12\u6708", "\u32CC"=>"Hg", "\u32CD"=>"erg", "\u32CE"=>"eV",
- "\u32CF"=>"LTD", "\u32D0"=>"\u30A2", "\u32D1"=>"\u30A4", "\u32D2"=>"\u30A6", "\u32D3"=>"\u30A8", "\u32D4"=>"\u30AA", "\u32D5"=>"\u30AB", "\u32D6"=>"\u30AD",
- "\u32D7"=>"\u30AF", "\u32D8"=>"\u30B1", "\u32D9"=>"\u30B3", "\u32DA"=>"\u30B5", "\u32DB"=>"\u30B7", "\u32DC"=>"\u30B9", "\u32DD"=>"\u30BB", "\u32DE"=>"\u30BD",
- "\u32DF"=>"\u30BF", "\u32E0"=>"\u30C1", "\u32E1"=>"\u30C4", "\u32E2"=>"\u30C6", "\u32E3"=>"\u30C8", "\u32E4"=>"\u30CA", "\u32E5"=>"\u30CB", "\u32E6"=>"\u30CC",
- "\u32E7"=>"\u30CD", "\u32E8"=>"\u30CE", "\u32E9"=>"\u30CF", "\u32EA"=>"\u30D2", "\u32EB"=>"\u30D5", "\u32EC"=>"\u30D8", "\u32ED"=>"\u30DB", "\u32EE"=>"\u30DE",
- "\u32EF"=>"\u30DF", "\u32F0"=>"\u30E0", "\u32F1"=>"\u30E1", "\u32F2"=>"\u30E2", "\u32F3"=>"\u30E4", "\u32F4"=>"\u30E6", "\u32F5"=>"\u30E8", "\u32F6"=>"\u30E9",
- "\u32F7"=>"\u30EA", "\u32F8"=>"\u30EB", "\u32F9"=>"\u30EC", "\u32FA"=>"\u30ED", "\u32FB"=>"\u30EF", "\u32FC"=>"\u30F0", "\u32FD"=>"\u30F1", "\u32FE"=>"\u30F2",
- "\u3300"=>"\u30A2\u30D1\u30FC\u30C8", "\u3301"=>"\u30A2\u30EB\u30D5\u30A1", "\u3302"=>"\u30A2\u30F3\u30DA\u30A2", "\u3303"=>"\u30A2\u30FC\u30EB", "\u3304"=>"\u30A4\u30CB\u30F3\u30B0", "\u3305"=>"\u30A4\u30F3\u30C1", "\u3306"=>"\u30A6\u30A9\u30F3", "\u3307"=>"\u30A8\u30B9\u30AF\u30FC\u30C9",
- "\u3308"=>"\u30A8\u30FC\u30AB\u30FC", "\u3309"=>"\u30AA\u30F3\u30B9", "\u330A"=>"\u30AA\u30FC\u30E0", "\u330B"=>"\u30AB\u30A4\u30EA", "\u330C"=>"\u30AB\u30E9\u30C3\u30C8", "\u330D"=>"\u30AB\u30ED\u30EA\u30FC", "\u330E"=>"\u30AC\u30ED\u30F3", "\u330F"=>"\u30AC\u30F3\u30DE",
- "\u3310"=>"\u30AE\u30AC", "\u3311"=>"\u30AE\u30CB\u30FC", "\u3312"=>"\u30AD\u30E5\u30EA\u30FC", "\u3313"=>"\u30AE\u30EB\u30C0\u30FC", "\u3314"=>"\u30AD\u30ED", "\u3315"=>"\u30AD\u30ED\u30B0\u30E9\u30E0", "\u3316"=>"\u30AD\u30ED\u30E1\u30FC\u30C8\u30EB", "\u3317"=>"\u30AD\u30ED\u30EF\u30C3\u30C8",
- "\u3318"=>"\u30B0\u30E9\u30E0", "\u3319"=>"\u30B0\u30E9\u30E0\u30C8\u30F3", "\u331A"=>"\u30AF\u30EB\u30BC\u30A4\u30ED", "\u331B"=>"\u30AF\u30ED\u30FC\u30CD", "\u331C"=>"\u30B1\u30FC\u30B9", "\u331D"=>"\u30B3\u30EB\u30CA", "\u331E"=>"\u30B3\u30FC\u30DD", "\u331F"=>"\u30B5\u30A4\u30AF\u30EB",
- "\u3320"=>"\u30B5\u30F3\u30C1\u30FC\u30E0", "\u3321"=>"\u30B7\u30EA\u30F3\u30B0", "\u3322"=>"\u30BB\u30F3\u30C1", "\u3323"=>"\u30BB\u30F3\u30C8", "\u3324"=>"\u30C0\u30FC\u30B9", "\u3325"=>"\u30C7\u30B7", "\u3326"=>"\u30C9\u30EB", "\u3327"=>"\u30C8\u30F3",
- "\u3328"=>"\u30CA\u30CE", "\u3329"=>"\u30CE\u30C3\u30C8", "\u332A"=>"\u30CF\u30A4\u30C4", "\u332B"=>"\u30D1\u30FC\u30BB\u30F3\u30C8", "\u332C"=>"\u30D1\u30FC\u30C4", "\u332D"=>"\u30D0\u30FC\u30EC\u30EB", "\u332E"=>"\u30D4\u30A2\u30B9\u30C8\u30EB", "\u332F"=>"\u30D4\u30AF\u30EB",
- "\u3330"=>"\u30D4\u30B3", "\u3331"=>"\u30D3\u30EB", "\u3332"=>"\u30D5\u30A1\u30E9\u30C3\u30C9", "\u3333"=>"\u30D5\u30A3\u30FC\u30C8", "\u3334"=>"\u30D6\u30C3\u30B7\u30A7\u30EB", "\u3335"=>"\u30D5\u30E9\u30F3", "\u3336"=>"\u30D8\u30AF\u30BF\u30FC\u30EB", "\u3337"=>"\u30DA\u30BD",
- "\u3338"=>"\u30DA\u30CB\u30D2", "\u3339"=>"\u30D8\u30EB\u30C4", "\u333A"=>"\u30DA\u30F3\u30B9", "\u333B"=>"\u30DA\u30FC\u30B8", "\u333C"=>"\u30D9\u30FC\u30BF", "\u333D"=>"\u30DD\u30A4\u30F3\u30C8", "\u333E"=>"\u30DC\u30EB\u30C8", "\u333F"=>"\u30DB\u30F3",
- "\u3340"=>"\u30DD\u30F3\u30C9", "\u3341"=>"\u30DB\u30FC\u30EB", "\u3342"=>"\u30DB\u30FC\u30F3", "\u3343"=>"\u30DE\u30A4\u30AF\u30ED", "\u3344"=>"\u30DE\u30A4\u30EB", "\u3345"=>"\u30DE\u30C3\u30CF", "\u3346"=>"\u30DE\u30EB\u30AF", "\u3347"=>"\u30DE\u30F3\u30B7\u30E7\u30F3",
- "\u3348"=>"\u30DF\u30AF\u30ED\u30F3", "\u3349"=>"\u30DF\u30EA", "\u334A"=>"\u30DF\u30EA\u30D0\u30FC\u30EB", "\u334B"=>"\u30E1\u30AC", "\u334C"=>"\u30E1\u30AC\u30C8\u30F3", "\u334D"=>"\u30E1\u30FC\u30C8\u30EB", "\u334E"=>"\u30E4\u30FC\u30C9", "\u334F"=>"\u30E4\u30FC\u30EB",
- "\u3350"=>"\u30E6\u30A2\u30F3", "\u3351"=>"\u30EA\u30C3\u30C8\u30EB", "\u3352"=>"\u30EA\u30E9", "\u3353"=>"\u30EB\u30D4\u30FC", "\u3354"=>"\u30EB\u30FC\u30D6\u30EB", "\u3355"=>"\u30EC\u30E0", "\u3356"=>"\u30EC\u30F3\u30C8\u30B2\u30F3", "\u3357"=>"\u30EF\u30C3\u30C8",
- "\u3358"=>"0\u70B9", "\u3359"=>"1\u70B9", "\u335A"=>"2\u70B9", "\u335B"=>"3\u70B9", "\u335C"=>"4\u70B9", "\u335D"=>"5\u70B9", "\u335E"=>"6\u70B9", "\u335F"=>"7\u70B9",
- "\u3360"=>"8\u70B9", "\u3361"=>"9\u70B9", "\u3362"=>"10\u70B9", "\u3363"=>"11\u70B9", "\u3364"=>"12\u70B9", "\u3365"=>"13\u70B9", "\u3366"=>"14\u70B9", "\u3367"=>"15\u70B9",
- "\u3368"=>"16\u70B9", "\u3369"=>"17\u70B9", "\u336A"=>"18\u70B9", "\u336B"=>"19\u70B9", "\u336C"=>"20\u70B9", "\u336D"=>"21\u70B9", "\u336E"=>"22\u70B9", "\u336F"=>"23\u70B9",
- "\u3370"=>"24\u70B9", "\u3371"=>"hPa", "\u3372"=>"da", "\u3373"=>"AU", "\u3374"=>"bar", "\u3375"=>"oV", "\u3376"=>"pc", "\u3377"=>"dm",
- "\u3378"=>"dm2", "\u3379"=>"dm3", "\u337A"=>"IU", "\u337B"=>"\u5E73\u6210", "\u337C"=>"\u662D\u548C", "\u337D"=>"\u5927\u6B63", "\u337E"=>"\u660E\u6CBB", "\u337F"=>"\u682A\u5F0F\u4F1A\u793E",
- "\u3380"=>"pA", "\u3381"=>"nA", "\u3382"=>"\u03BCA", "\u3383"=>"mA", "\u3384"=>"kA", "\u3385"=>"KB", "\u3386"=>"MB", "\u3387"=>"GB",
- "\u3388"=>"cal", "\u3389"=>"kcal", "\u338A"=>"pF", "\u338B"=>"nF", "\u338C"=>"\u03BCF", "\u338D"=>"\u03BCg", "\u338E"=>"mg", "\u338F"=>"kg",
- "\u3390"=>"Hz", "\u3391"=>"kHz", "\u3392"=>"MHz", "\u3393"=>"GHz", "\u3394"=>"THz", "\u3395"=>"\u03BCl", "\u3396"=>"ml", "\u3397"=>"dl",
- "\u3398"=>"kl", "\u3399"=>"fm", "\u339A"=>"nm", "\u339B"=>"\u03BCm", "\u339C"=>"mm", "\u339D"=>"cm", "\u339E"=>"km", "\u339F"=>"mm2",
- "\u33A0"=>"cm2", "\u33A1"=>"m2", "\u33A2"=>"km2", "\u33A3"=>"mm3", "\u33A4"=>"cm3", "\u33A5"=>"m3", "\u33A6"=>"km3", "\u33A7"=>"m\u2215s",
- "\u33A8"=>"m\u2215s2", "\u33A9"=>"Pa", "\u33AA"=>"kPa", "\u33AB"=>"MPa", "\u33AC"=>"GPa", "\u33AD"=>"rad", "\u33AE"=>"rad\u2215s", "\u33AF"=>"rad\u2215s2",
- "\u33B0"=>"ps", "\u33B1"=>"ns", "\u33B2"=>"\u03BCs", "\u33B3"=>"ms", "\u33B4"=>"pV", "\u33B5"=>"nV", "\u33B6"=>"\u03BCV", "\u33B7"=>"mV",
- "\u33B8"=>"kV", "\u33B9"=>"MV", "\u33BA"=>"pW", "\u33BB"=>"nW", "\u33BC"=>"\u03BCW", "\u33BD"=>"mW", "\u33BE"=>"kW", "\u33BF"=>"MW",
- "\u33C0"=>"k\u03A9", "\u33C1"=>"M\u03A9", "\u33C2"=>"a.m.", "\u33C3"=>"Bq", "\u33C4"=>"cc", "\u33C5"=>"cd", "\u33C6"=>"C\u2215kg", "\u33C7"=>"Co.",
- "\u33C8"=>"dB", "\u33C9"=>"Gy", "\u33CA"=>"ha", "\u33CB"=>"HP", "\u33CC"=>"in", "\u33CD"=>"KK", "\u33CE"=>"KM", "\u33CF"=>"kt",
- "\u33D0"=>"lm", "\u33D1"=>"ln", "\u33D2"=>"log", "\u33D3"=>"lx", "\u33D4"=>"mb", "\u33D5"=>"mil", "\u33D6"=>"mol", "\u33D7"=>"PH",
- "\u33D8"=>"p.m.", "\u33D9"=>"PPM", "\u33DA"=>"PR", "\u33DB"=>"sr", "\u33DC"=>"Sv", "\u33DD"=>"Wb", "\u33DE"=>"V\u2215m", "\u33DF"=>"A\u2215m",
- "\u33E0"=>"1\u65E5", "\u33E1"=>"2\u65E5", "\u33E2"=>"3\u65E5", "\u33E3"=>"4\u65E5", "\u33E4"=>"5\u65E5", "\u33E5"=>"6\u65E5", "\u33E6"=>"7\u65E5", "\u33E7"=>"8\u65E5",
- "\u33E8"=>"9\u65E5", "\u33E9"=>"10\u65E5", "\u33EA"=>"11\u65E5", "\u33EB"=>"12\u65E5", "\u33EC"=>"13\u65E5", "\u33ED"=>"14\u65E5", "\u33EE"=>"15\u65E5", "\u33EF"=>"16\u65E5",
- "\u33F0"=>"17\u65E5", "\u33F1"=>"18\u65E5", "\u33F2"=>"19\u65E5", "\u33F3"=>"20\u65E5", "\u33F4"=>"21\u65E5", "\u33F5"=>"22\u65E5", "\u33F6"=>"23\u65E5", "\u33F7"=>"24\u65E5",
- "\u33F8"=>"25\u65E5", "\u33F9"=>"26\u65E5", "\u33FA"=>"27\u65E5", "\u33FB"=>"28\u65E5", "\u33FC"=>"29\u65E5", "\u33FD"=>"30\u65E5", "\u33FE"=>"31\u65E5", "\u33FF"=>"gal",
- "\uA69C"=>"\u044A", "\uA69D"=>"\u044C", "\uA770"=>"\uA76F", "\uA7F8"=>"\u0126", "\uA7F9"=>"\u0153", "\uAB5C"=>"\uA727", "\uAB5D"=>"\uAB37", "\uAB5E"=>"\u026B",
- "\uAB5F"=>"\uAB52", "\uFB00"=>"ff", "\uFB01"=>"fi", "\uFB02"=>"fl", "\uFB03"=>"ffi", "\uFB04"=>"ffl", "\uFB05"=>"st", "\uFB06"=>"st",
- "\uFB13"=>"\u0574\u0576", "\uFB14"=>"\u0574\u0565", "\uFB15"=>"\u0574\u056B", "\uFB16"=>"\u057E\u0576", "\uFB17"=>"\u0574\u056D", "\uFB20"=>"\u05E2", "\uFB21"=>"\u05D0", "\uFB22"=>"\u05D3",
- "\uFB23"=>"\u05D4", "\uFB24"=>"\u05DB", "\uFB25"=>"\u05DC", "\uFB26"=>"\u05DD", "\uFB27"=>"\u05E8", "\uFB28"=>"\u05EA", "\uFB29"=>"+", "\uFB4F"=>"\u05D0\u05DC",
- "\uFB50"=>"\u0671", "\uFB51"=>"\u0671", "\uFB52"=>"\u067B", "\uFB53"=>"\u067B", "\uFB54"=>"\u067B", "\uFB55"=>"\u067B", "\uFB56"=>"\u067E", "\uFB57"=>"\u067E",
- "\uFB58"=>"\u067E", "\uFB59"=>"\u067E", "\uFB5A"=>"\u0680", "\uFB5B"=>"\u0680", "\uFB5C"=>"\u0680", "\uFB5D"=>"\u0680", "\uFB5E"=>"\u067A", "\uFB5F"=>"\u067A",
- "\uFB60"=>"\u067A", "\uFB61"=>"\u067A", "\uFB62"=>"\u067F", "\uFB63"=>"\u067F", "\uFB64"=>"\u067F", "\uFB65"=>"\u067F", "\uFB66"=>"\u0679", "\uFB67"=>"\u0679",
- "\uFB68"=>"\u0679", "\uFB69"=>"\u0679", "\uFB6A"=>"\u06A4", "\uFB6B"=>"\u06A4", "\uFB6C"=>"\u06A4", "\uFB6D"=>"\u06A4", "\uFB6E"=>"\u06A6", "\uFB6F"=>"\u06A6",
- "\uFB70"=>"\u06A6", "\uFB71"=>"\u06A6", "\uFB72"=>"\u0684", "\uFB73"=>"\u0684", "\uFB74"=>"\u0684", "\uFB75"=>"\u0684", "\uFB76"=>"\u0683", "\uFB77"=>"\u0683",
- "\uFB78"=>"\u0683", "\uFB79"=>"\u0683", "\uFB7A"=>"\u0686", "\uFB7B"=>"\u0686", "\uFB7C"=>"\u0686", "\uFB7D"=>"\u0686", "\uFB7E"=>"\u0687", "\uFB7F"=>"\u0687",
- "\uFB80"=>"\u0687", "\uFB81"=>"\u0687", "\uFB82"=>"\u068D", "\uFB83"=>"\u068D", "\uFB84"=>"\u068C", "\uFB85"=>"\u068C", "\uFB86"=>"\u068E", "\uFB87"=>"\u068E",
- "\uFB88"=>"\u0688", "\uFB89"=>"\u0688", "\uFB8A"=>"\u0698", "\uFB8B"=>"\u0698", "\uFB8C"=>"\u0691", "\uFB8D"=>"\u0691", "\uFB8E"=>"\u06A9", "\uFB8F"=>"\u06A9",
- "\uFB90"=>"\u06A9", "\uFB91"=>"\u06A9", "\uFB92"=>"\u06AF", "\uFB93"=>"\u06AF", "\uFB94"=>"\u06AF", "\uFB95"=>"\u06AF", "\uFB96"=>"\u06B3", "\uFB97"=>"\u06B3",
- "\uFB98"=>"\u06B3", "\uFB99"=>"\u06B3", "\uFB9A"=>"\u06B1", "\uFB9B"=>"\u06B1", "\uFB9C"=>"\u06B1", "\uFB9D"=>"\u06B1", "\uFB9E"=>"\u06BA", "\uFB9F"=>"\u06BA",
- "\uFBA0"=>"\u06BB", "\uFBA1"=>"\u06BB", "\uFBA2"=>"\u06BB", "\uFBA3"=>"\u06BB", "\uFBA4"=>"\u06C0", "\uFBA5"=>"\u06C0", "\uFBA6"=>"\u06C1", "\uFBA7"=>"\u06C1",
- "\uFBA8"=>"\u06C1", "\uFBA9"=>"\u06C1", "\uFBAA"=>"\u06BE", "\uFBAB"=>"\u06BE", "\uFBAC"=>"\u06BE", "\uFBAD"=>"\u06BE", "\uFBAE"=>"\u06D2", "\uFBAF"=>"\u06D2",
- "\uFBB0"=>"\u06D3", "\uFBB1"=>"\u06D3", "\uFBD3"=>"\u06AD", "\uFBD4"=>"\u06AD", "\uFBD5"=>"\u06AD", "\uFBD6"=>"\u06AD", "\uFBD7"=>"\u06C7", "\uFBD8"=>"\u06C7",
- "\uFBD9"=>"\u06C6", "\uFBDA"=>"\u06C6", "\uFBDB"=>"\u06C8", "\uFBDC"=>"\u06C8", "\uFBDD"=>"\u06C7\u0674", "\uFBDE"=>"\u06CB", "\uFBDF"=>"\u06CB", "\uFBE0"=>"\u06C5",
- "\uFBE1"=>"\u06C5", "\uFBE2"=>"\u06C9", "\uFBE3"=>"\u06C9", "\uFBE4"=>"\u06D0", "\uFBE5"=>"\u06D0", "\uFBE6"=>"\u06D0", "\uFBE7"=>"\u06D0", "\uFBE8"=>"\u0649",
- "\uFBE9"=>"\u0649", "\uFBEA"=>"\u0626\u0627", "\uFBEB"=>"\u0626\u0627", "\uFBEC"=>"\u0626\u06D5", "\uFBED"=>"\u0626\u06D5", "\uFBEE"=>"\u0626\u0648", "\uFBEF"=>"\u0626\u0648", "\uFBF0"=>"\u0626\u06C7",
- "\uFBF1"=>"\u0626\u06C7", "\uFBF2"=>"\u0626\u06C6", "\uFBF3"=>"\u0626\u06C6", "\uFBF4"=>"\u0626\u06C8", "\uFBF5"=>"\u0626\u06C8", "\uFBF6"=>"\u0626\u06D0", "\uFBF7"=>"\u0626\u06D0", "\uFBF8"=>"\u0626\u06D0",
- "\uFBF9"=>"\u0626\u0649", "\uFBFA"=>"\u0626\u0649", "\uFBFB"=>"\u0626\u0649", "\uFBFC"=>"\u06CC", "\uFBFD"=>"\u06CC", "\uFBFE"=>"\u06CC", "\uFBFF"=>"\u06CC", "\uFC00"=>"\u0626\u062C",
- "\uFC01"=>"\u0626\u062D", "\uFC02"=>"\u0626\u0645", "\uFC03"=>"\u0626\u0649", "\uFC04"=>"\u0626\u064A", "\uFC05"=>"\u0628\u062C", "\uFC06"=>"\u0628\u062D", "\uFC07"=>"\u0628\u062E", "\uFC08"=>"\u0628\u0645",
- "\uFC09"=>"\u0628\u0649", "\uFC0A"=>"\u0628\u064A", "\uFC0B"=>"\u062A\u062C", "\uFC0C"=>"\u062A\u062D", "\uFC0D"=>"\u062A\u062E", "\uFC0E"=>"\u062A\u0645", "\uFC0F"=>"\u062A\u0649", "\uFC10"=>"\u062A\u064A",
- "\uFC11"=>"\u062B\u062C", "\uFC12"=>"\u062B\u0645", "\uFC13"=>"\u062B\u0649", "\uFC14"=>"\u062B\u064A", "\uFC15"=>"\u062C\u062D", "\uFC16"=>"\u062C\u0645", "\uFC17"=>"\u062D\u062C", "\uFC18"=>"\u062D\u0645",
- "\uFC19"=>"\u062E\u062C", "\uFC1A"=>"\u062E\u062D", "\uFC1B"=>"\u062E\u0645", "\uFC1C"=>"\u0633\u062C", "\uFC1D"=>"\u0633\u062D", "\uFC1E"=>"\u0633\u062E", "\uFC1F"=>"\u0633\u0645", "\uFC20"=>"\u0635\u062D",
- "\uFC21"=>"\u0635\u0645", "\uFC22"=>"\u0636\u062C", "\uFC23"=>"\u0636\u062D", "\uFC24"=>"\u0636\u062E", "\uFC25"=>"\u0636\u0645", "\uFC26"=>"\u0637\u062D", "\uFC27"=>"\u0637\u0645", "\uFC28"=>"\u0638\u0645",
- "\uFC29"=>"\u0639\u062C", "\uFC2A"=>"\u0639\u0645", "\uFC2B"=>"\u063A\u062C", "\uFC2C"=>"\u063A\u0645", "\uFC2D"=>"\u0641\u062C", "\uFC2E"=>"\u0641\u062D", "\uFC2F"=>"\u0641\u062E", "\uFC30"=>"\u0641\u0645",
- "\uFC31"=>"\u0641\u0649", "\uFC32"=>"\u0641\u064A", "\uFC33"=>"\u0642\u062D", "\uFC34"=>"\u0642\u0645", "\uFC35"=>"\u0642\u0649", "\uFC36"=>"\u0642\u064A", "\uFC37"=>"\u0643\u0627", "\uFC38"=>"\u0643\u062C",
- "\uFC39"=>"\u0643\u062D", "\uFC3A"=>"\u0643\u062E", "\uFC3B"=>"\u0643\u0644", "\uFC3C"=>"\u0643\u0645", "\uFC3D"=>"\u0643\u0649", "\uFC3E"=>"\u0643\u064A", "\uFC3F"=>"\u0644\u062C", "\uFC40"=>"\u0644\u062D",
- "\uFC41"=>"\u0644\u062E", "\uFC42"=>"\u0644\u0645", "\uFC43"=>"\u0644\u0649", "\uFC44"=>"\u0644\u064A", "\uFC45"=>"\u0645\u062C", "\uFC46"=>"\u0645\u062D", "\uFC47"=>"\u0645\u062E", "\uFC48"=>"\u0645\u0645",
- "\uFC49"=>"\u0645\u0649", "\uFC4A"=>"\u0645\u064A", "\uFC4B"=>"\u0646\u062C", "\uFC4C"=>"\u0646\u062D", "\uFC4D"=>"\u0646\u062E", "\uFC4E"=>"\u0646\u0645", "\uFC4F"=>"\u0646\u0649", "\uFC50"=>"\u0646\u064A",
- "\uFC51"=>"\u0647\u062C", "\uFC52"=>"\u0647\u0645", "\uFC53"=>"\u0647\u0649", "\uFC54"=>"\u0647\u064A", "\uFC55"=>"\u064A\u062C", "\uFC56"=>"\u064A\u062D", "\uFC57"=>"\u064A\u062E", "\uFC58"=>"\u064A\u0645",
- "\uFC59"=>"\u064A\u0649", "\uFC5A"=>"\u064A\u064A", "\uFC5B"=>"\u0630\u0670", "\uFC5C"=>"\u0631\u0670", "\uFC5D"=>"\u0649\u0670", "\uFC5E"=>" \u064C\u0651", "\uFC5F"=>" \u064D\u0651", "\uFC60"=>" \u064E\u0651",
- "\uFC61"=>" \u064F\u0651", "\uFC62"=>" \u0650\u0651", "\uFC63"=>" \u0651\u0670", "\uFC64"=>"\u0626\u0631", "\uFC65"=>"\u0626\u0632", "\uFC66"=>"\u0626\u0645", "\uFC67"=>"\u0626\u0646", "\uFC68"=>"\u0626\u0649",
- "\uFC69"=>"\u0626\u064A", "\uFC6A"=>"\u0628\u0631", "\uFC6B"=>"\u0628\u0632", "\uFC6C"=>"\u0628\u0645", "\uFC6D"=>"\u0628\u0646", "\uFC6E"=>"\u0628\u0649", "\uFC6F"=>"\u0628\u064A", "\uFC70"=>"\u062A\u0631",
- "\uFC71"=>"\u062A\u0632", "\uFC72"=>"\u062A\u0645", "\uFC73"=>"\u062A\u0646", "\uFC74"=>"\u062A\u0649", "\uFC75"=>"\u062A\u064A", "\uFC76"=>"\u062B\u0631", "\uFC77"=>"\u062B\u0632", "\uFC78"=>"\u062B\u0645",
- "\uFC79"=>"\u062B\u0646", "\uFC7A"=>"\u062B\u0649", "\uFC7B"=>"\u062B\u064A", "\uFC7C"=>"\u0641\u0649", "\uFC7D"=>"\u0641\u064A", "\uFC7E"=>"\u0642\u0649", "\uFC7F"=>"\u0642\u064A", "\uFC80"=>"\u0643\u0627",
- "\uFC81"=>"\u0643\u0644", "\uFC82"=>"\u0643\u0645", "\uFC83"=>"\u0643\u0649", "\uFC84"=>"\u0643\u064A", "\uFC85"=>"\u0644\u0645", "\uFC86"=>"\u0644\u0649", "\uFC87"=>"\u0644\u064A", "\uFC88"=>"\u0645\u0627",
- "\uFC89"=>"\u0645\u0645", "\uFC8A"=>"\u0646\u0631", "\uFC8B"=>"\u0646\u0632", "\uFC8C"=>"\u0646\u0645", "\uFC8D"=>"\u0646\u0646", "\uFC8E"=>"\u0646\u0649", "\uFC8F"=>"\u0646\u064A", "\uFC90"=>"\u0649\u0670",
- "\uFC91"=>"\u064A\u0631", "\uFC92"=>"\u064A\u0632", "\uFC93"=>"\u064A\u0645", "\uFC94"=>"\u064A\u0646", "\uFC95"=>"\u064A\u0649", "\uFC96"=>"\u064A\u064A", "\uFC97"=>"\u0626\u062C", "\uFC98"=>"\u0626\u062D",
- "\uFC99"=>"\u0626\u062E", "\uFC9A"=>"\u0626\u0645", "\uFC9B"=>"\u0626\u0647", "\uFC9C"=>"\u0628\u062C", "\uFC9D"=>"\u0628\u062D", "\uFC9E"=>"\u0628\u062E", "\uFC9F"=>"\u0628\u0645", "\uFCA0"=>"\u0628\u0647",
- "\uFCA1"=>"\u062A\u062C", "\uFCA2"=>"\u062A\u062D", "\uFCA3"=>"\u062A\u062E", "\uFCA4"=>"\u062A\u0645", "\uFCA5"=>"\u062A\u0647", "\uFCA6"=>"\u062B\u0645", "\uFCA7"=>"\u062C\u062D", "\uFCA8"=>"\u062C\u0645",
- "\uFCA9"=>"\u062D\u062C", "\uFCAA"=>"\u062D\u0645", "\uFCAB"=>"\u062E\u062C", "\uFCAC"=>"\u062E\u0645", "\uFCAD"=>"\u0633\u062C", "\uFCAE"=>"\u0633\u062D", "\uFCAF"=>"\u0633\u062E", "\uFCB0"=>"\u0633\u0645",
- "\uFCB1"=>"\u0635\u062D", "\uFCB2"=>"\u0635\u062E", "\uFCB3"=>"\u0635\u0645", "\uFCB4"=>"\u0636\u062C", "\uFCB5"=>"\u0636\u062D", "\uFCB6"=>"\u0636\u062E", "\uFCB7"=>"\u0636\u0645", "\uFCB8"=>"\u0637\u062D",
- "\uFCB9"=>"\u0638\u0645", "\uFCBA"=>"\u0639\u062C", "\uFCBB"=>"\u0639\u0645", "\uFCBC"=>"\u063A\u062C", "\uFCBD"=>"\u063A\u0645", "\uFCBE"=>"\u0641\u062C", "\uFCBF"=>"\u0641\u062D", "\uFCC0"=>"\u0641\u062E",
- "\uFCC1"=>"\u0641\u0645", "\uFCC2"=>"\u0642\u062D", "\uFCC3"=>"\u0642\u0645", "\uFCC4"=>"\u0643\u062C", "\uFCC5"=>"\u0643\u062D", "\uFCC6"=>"\u0643\u062E", "\uFCC7"=>"\u0643\u0644", "\uFCC8"=>"\u0643\u0645",
- "\uFCC9"=>"\u0644\u062C", "\uFCCA"=>"\u0644\u062D", "\uFCCB"=>"\u0644\u062E", "\uFCCC"=>"\u0644\u0645", "\uFCCD"=>"\u0644\u0647", "\uFCCE"=>"\u0645\u062C", "\uFCCF"=>"\u0645\u062D", "\uFCD0"=>"\u0645\u062E",
- "\uFCD1"=>"\u0645\u0645", "\uFCD2"=>"\u0646\u062C", "\uFCD3"=>"\u0646\u062D", "\uFCD4"=>"\u0646\u062E", "\uFCD5"=>"\u0646\u0645", "\uFCD6"=>"\u0646\u0647", "\uFCD7"=>"\u0647\u062C", "\uFCD8"=>"\u0647\u0645",
- "\uFCD9"=>"\u0647\u0670", "\uFCDA"=>"\u064A\u062C", "\uFCDB"=>"\u064A\u062D", "\uFCDC"=>"\u064A\u062E", "\uFCDD"=>"\u064A\u0645", "\uFCDE"=>"\u064A\u0647", "\uFCDF"=>"\u0626\u0645", "\uFCE0"=>"\u0626\u0647",
- "\uFCE1"=>"\u0628\u0645", "\uFCE2"=>"\u0628\u0647", "\uFCE3"=>"\u062A\u0645", "\uFCE4"=>"\u062A\u0647", "\uFCE5"=>"\u062B\u0645", "\uFCE6"=>"\u062B\u0647", "\uFCE7"=>"\u0633\u0645", "\uFCE8"=>"\u0633\u0647",
- "\uFCE9"=>"\u0634\u0645", "\uFCEA"=>"\u0634\u0647", "\uFCEB"=>"\u0643\u0644", "\uFCEC"=>"\u0643\u0645", "\uFCED"=>"\u0644\u0645", "\uFCEE"=>"\u0646\u0645", "\uFCEF"=>"\u0646\u0647", "\uFCF0"=>"\u064A\u0645",
- "\uFCF1"=>"\u064A\u0647", "\uFCF2"=>"\u0640\u064E\u0651", "\uFCF3"=>"\u0640\u064F\u0651", "\uFCF4"=>"\u0640\u0650\u0651", "\uFCF5"=>"\u0637\u0649", "\uFCF6"=>"\u0637\u064A", "\uFCF7"=>"\u0639\u0649", "\uFCF8"=>"\u0639\u064A",
- "\uFCF9"=>"\u063A\u0649", "\uFCFA"=>"\u063A\u064A", "\uFCFB"=>"\u0633\u0649", "\uFCFC"=>"\u0633\u064A", "\uFCFD"=>"\u0634\u0649", "\uFCFE"=>"\u0634\u064A", "\uFCFF"=>"\u062D\u0649", "\uFD00"=>"\u062D\u064A",
- "\uFD01"=>"\u062C\u0649", "\uFD02"=>"\u062C\u064A", "\uFD03"=>"\u062E\u0649", "\uFD04"=>"\u062E\u064A", "\uFD05"=>"\u0635\u0649", "\uFD06"=>"\u0635\u064A", "\uFD07"=>"\u0636\u0649", "\uFD08"=>"\u0636\u064A",
- "\uFD09"=>"\u0634\u062C", "\uFD0A"=>"\u0634\u062D", "\uFD0B"=>"\u0634\u062E", "\uFD0C"=>"\u0634\u0645", "\uFD0D"=>"\u0634\u0631", "\uFD0E"=>"\u0633\u0631", "\uFD0F"=>"\u0635\u0631", "\uFD10"=>"\u0636\u0631",
- "\uFD11"=>"\u0637\u0649", "\uFD12"=>"\u0637\u064A", "\uFD13"=>"\u0639\u0649", "\uFD14"=>"\u0639\u064A", "\uFD15"=>"\u063A\u0649", "\uFD16"=>"\u063A\u064A", "\uFD17"=>"\u0633\u0649", "\uFD18"=>"\u0633\u064A",
- "\uFD19"=>"\u0634\u0649", "\uFD1A"=>"\u0634\u064A", "\uFD1B"=>"\u062D\u0649", "\uFD1C"=>"\u062D\u064A", "\uFD1D"=>"\u062C\u0649", "\uFD1E"=>"\u062C\u064A", "\uFD1F"=>"\u062E\u0649", "\uFD20"=>"\u062E\u064A",
- "\uFD21"=>"\u0635\u0649", "\uFD22"=>"\u0635\u064A", "\uFD23"=>"\u0636\u0649", "\uFD24"=>"\u0636\u064A", "\uFD25"=>"\u0634\u062C", "\uFD26"=>"\u0634\u062D", "\uFD27"=>"\u0634\u062E", "\uFD28"=>"\u0634\u0645",
- "\uFD29"=>"\u0634\u0631", "\uFD2A"=>"\u0633\u0631", "\uFD2B"=>"\u0635\u0631", "\uFD2C"=>"\u0636\u0631", "\uFD2D"=>"\u0634\u062C", "\uFD2E"=>"\u0634\u062D", "\uFD2F"=>"\u0634\u062E", "\uFD30"=>"\u0634\u0645",
- "\uFD31"=>"\u0633\u0647", "\uFD32"=>"\u0634\u0647", "\uFD33"=>"\u0637\u0645", "\uFD34"=>"\u0633\u062C", "\uFD35"=>"\u0633\u062D", "\uFD36"=>"\u0633\u062E", "\uFD37"=>"\u0634\u062C", "\uFD38"=>"\u0634\u062D",
- "\uFD39"=>"\u0634\u062E", "\uFD3A"=>"\u0637\u0645", "\uFD3B"=>"\u0638\u0645", "\uFD3C"=>"\u0627\u064B", "\uFD3D"=>"\u0627\u064B", "\uFD50"=>"\u062A\u062C\u0645", "\uFD51"=>"\u062A\u062D\u062C", "\uFD52"=>"\u062A\u062D\u062C",
- "\uFD53"=>"\u062A\u062D\u0645", "\uFD54"=>"\u062A\u062E\u0645", "\uFD55"=>"\u062A\u0645\u062C", "\uFD56"=>"\u062A\u0645\u062D", "\uFD57"=>"\u062A\u0645\u062E", "\uFD58"=>"\u062C\u0645\u062D", "\uFD59"=>"\u062C\u0645\u062D", "\uFD5A"=>"\u062D\u0645\u064A",
- "\uFD5B"=>"\u062D\u0645\u0649", "\uFD5C"=>"\u0633\u062D\u062C", "\uFD5D"=>"\u0633\u062C\u062D", "\uFD5E"=>"\u0633\u062C\u0649", "\uFD5F"=>"\u0633\u0645\u062D", "\uFD60"=>"\u0633\u0645\u062D", "\uFD61"=>"\u0633\u0645\u062C", "\uFD62"=>"\u0633\u0645\u0645",
- "\uFD63"=>"\u0633\u0645\u0645", "\uFD64"=>"\u0635\u062D\u062D", "\uFD65"=>"\u0635\u062D\u062D", "\uFD66"=>"\u0635\u0645\u0645", "\uFD67"=>"\u0634\u062D\u0645", "\uFD68"=>"\u0634\u062D\u0645", "\uFD69"=>"\u0634\u062C\u064A", "\uFD6A"=>"\u0634\u0645\u062E",
- "\uFD6B"=>"\u0634\u0645\u062E", "\uFD6C"=>"\u0634\u0645\u0645", "\uFD6D"=>"\u0634\u0645\u0645", "\uFD6E"=>"\u0636\u062D\u0649", "\uFD6F"=>"\u0636\u062E\u0645", "\uFD70"=>"\u0636\u062E\u0645", "\uFD71"=>"\u0637\u0645\u062D", "\uFD72"=>"\u0637\u0645\u062D",
- "\uFD73"=>"\u0637\u0645\u0645", "\uFD74"=>"\u0637\u0645\u064A", "\uFD75"=>"\u0639\u062C\u0645", "\uFD76"=>"\u0639\u0645\u0645", "\uFD77"=>"\u0639\u0645\u0645", "\uFD78"=>"\u0639\u0645\u0649", "\uFD79"=>"\u063A\u0645\u0645", "\uFD7A"=>"\u063A\u0645\u064A",
- "\uFD7B"=>"\u063A\u0645\u0649", "\uFD7C"=>"\u0641\u062E\u0645", "\uFD7D"=>"\u0641\u062E\u0645", "\uFD7E"=>"\u0642\u0645\u062D", "\uFD7F"=>"\u0642\u0645\u0645", "\uFD80"=>"\u0644\u062D\u0645", "\uFD81"=>"\u0644\u062D\u064A", "\uFD82"=>"\u0644\u062D\u0649",
- "\uFD83"=>"\u0644\u062C\u062C", "\uFD84"=>"\u0644\u062C\u062C", "\uFD85"=>"\u0644\u062E\u0645", "\uFD86"=>"\u0644\u062E\u0645", "\uFD87"=>"\u0644\u0645\u062D", "\uFD88"=>"\u0644\u0645\u062D", "\uFD89"=>"\u0645\u062D\u062C", "\uFD8A"=>"\u0645\u062D\u0645",
- "\uFD8B"=>"\u0645\u062D\u064A", "\uFD8C"=>"\u0645\u062C\u062D", "\uFD8D"=>"\u0645\u062C\u0645", "\uFD8E"=>"\u0645\u062E\u062C", "\uFD8F"=>"\u0645\u062E\u0645", "\uFD92"=>"\u0645\u062C\u062E", "\uFD93"=>"\u0647\u0645\u062C", "\uFD94"=>"\u0647\u0645\u0645",
- "\uFD95"=>"\u0646\u062D\u0645", "\uFD96"=>"\u0646\u062D\u0649", "\uFD97"=>"\u0646\u062C\u0645", "\uFD98"=>"\u0646\u062C\u0645", "\uFD99"=>"\u0646\u062C\u0649", "\uFD9A"=>"\u0646\u0645\u064A", "\uFD9B"=>"\u0646\u0645\u0649", "\uFD9C"=>"\u064A\u0645\u0645",
- "\uFD9D"=>"\u064A\u0645\u0645", "\uFD9E"=>"\u0628\u062E\u064A", "\uFD9F"=>"\u062A\u062C\u064A", "\uFDA0"=>"\u062A\u062C\u0649", "\uFDA1"=>"\u062A\u062E\u064A", "\uFDA2"=>"\u062A\u062E\u0649", "\uFDA3"=>"\u062A\u0645\u064A", "\uFDA4"=>"\u062A\u0645\u0649",
- "\uFDA5"=>"\u062C\u0645\u064A", "\uFDA6"=>"\u062C\u062D\u0649", "\uFDA7"=>"\u062C\u0645\u0649", "\uFDA8"=>"\u0633\u062E\u0649", "\uFDA9"=>"\u0635\u062D\u064A", "\uFDAA"=>"\u0634\u062D\u064A", "\uFDAB"=>"\u0636\u062D\u064A", "\uFDAC"=>"\u0644\u062C\u064A",
- "\uFDAD"=>"\u0644\u0645\u064A", "\uFDAE"=>"\u064A\u062D\u064A", "\uFDAF"=>"\u064A\u062C\u064A", "\uFDB0"=>"\u064A\u0645\u064A", "\uFDB1"=>"\u0645\u0645\u064A", "\uFDB2"=>"\u0642\u0645\u064A", "\uFDB3"=>"\u0646\u062D\u064A", "\uFDB4"=>"\u0642\u0645\u062D",
- "\uFDB5"=>"\u0644\u062D\u0645", "\uFDB6"=>"\u0639\u0645\u064A", "\uFDB7"=>"\u0643\u0645\u064A", "\uFDB8"=>"\u0646\u062C\u062D", "\uFDB9"=>"\u0645\u062E\u064A", "\uFDBA"=>"\u0644\u062C\u0645", "\uFDBB"=>"\u0643\u0645\u0645", "\uFDBC"=>"\u0644\u062C\u0645",
- "\uFDBD"=>"\u0646\u062C\u062D", "\uFDBE"=>"\u062C\u062D\u064A", "\uFDBF"=>"\u062D\u062C\u064A", "\uFDC0"=>"\u0645\u062C\u064A", "\uFDC1"=>"\u0641\u0645\u064A", "\uFDC2"=>"\u0628\u062D\u064A", "\uFDC3"=>"\u0643\u0645\u0645", "\uFDC4"=>"\u0639\u062C\u0645",
- "\uFDC5"=>"\u0635\u0645\u0645", "\uFDC6"=>"\u0633\u062E\u064A", "\uFDC7"=>"\u0646\u062C\u064A", "\uFDF0"=>"\u0635\u0644\u06D2", "\uFDF1"=>"\u0642\u0644\u06D2", "\uFDF2"=>"\u0627\u0644\u0644\u0647", "\uFDF3"=>"\u0627\u0643\u0628\u0631", "\uFDF4"=>"\u0645\u062D\u0645\u062F",
- "\uFDF5"=>"\u0635\u0644\u0639\u0645", "\uFDF6"=>"\u0631\u0633\u0648\u0644", "\uFDF7"=>"\u0639\u0644\u064A\u0647", "\uFDF8"=>"\u0648\u0633\u0644\u0645", "\uFDF9"=>"\u0635\u0644\u0649", "\uFDFA"=>"\u0635\u0644\u0649 \u0627\u0644\u0644\u0647 \u0639\u0644\u064A\u0647 \u0648\u0633\u0644\u0645", "\uFDFB"=>"\u062C\u0644 \u062C\u0644\u0627\u0644\u0647", "\uFDFC"=>"\u0631\u06CC\u0627\u0644",
- "\uFE10"=>",", "\uFE11"=>"\u3001", "\uFE12"=>"\u3002", "\uFE13"=>":", "\uFE14"=>";", "\uFE15"=>"!", "\uFE16"=>"?", "\uFE17"=>"\u3016",
- "\uFE18"=>"\u3017", "\uFE19"=>"...", "\uFE30"=>"..", "\uFE31"=>"\u2014", "\uFE32"=>"\u2013", "\uFE33"=>"_", "\uFE34"=>"_", "\uFE35"=>"(",
- "\uFE36"=>")", "\uFE37"=>"{", "\uFE38"=>"}", "\uFE39"=>"\u3014", "\uFE3A"=>"\u3015", "\uFE3B"=>"\u3010", "\uFE3C"=>"\u3011", "\uFE3D"=>"\u300A",
- "\uFE3E"=>"\u300B", "\uFE3F"=>"\u3008", "\uFE40"=>"\u3009", "\uFE41"=>"\u300C", "\uFE42"=>"\u300D", "\uFE43"=>"\u300E", "\uFE44"=>"\u300F", "\uFE47"=>"[",
- "\uFE48"=>"]", "\uFE49"=>" \u0305", "\uFE4A"=>" \u0305", "\uFE4B"=>" \u0305", "\uFE4C"=>" \u0305", "\uFE4D"=>"_", "\uFE4E"=>"_", "\uFE4F"=>"_",
- "\uFE50"=>",", "\uFE51"=>"\u3001", "\uFE52"=>".", "\uFE54"=>";", "\uFE55"=>":", "\uFE56"=>"?", "\uFE57"=>"!", "\uFE58"=>"\u2014",
- "\uFE59"=>"(", "\uFE5A"=>")", "\uFE5B"=>"{", "\uFE5C"=>"}", "\uFE5D"=>"\u3014", "\uFE5E"=>"\u3015", "\uFE5F"=>"#", "\uFE60"=>"&",
- "\uFE61"=>"*", "\uFE62"=>"+", "\uFE63"=>"-", "\uFE64"=>"<", "\uFE65"=>">", "\uFE66"=>"=", "\uFE68"=>"\\", "\uFE69"=>"$",
- "\uFE6A"=>"%", "\uFE6B"=>"@", "\uFE70"=>" \u064B", "\uFE71"=>"\u0640\u064B", "\uFE72"=>" \u064C", "\uFE74"=>" \u064D", "\uFE76"=>" \u064E", "\uFE77"=>"\u0640\u064E",
- "\uFE78"=>" \u064F", "\uFE79"=>"\u0640\u064F", "\uFE7A"=>" \u0650", "\uFE7B"=>"\u0640\u0650", "\uFE7C"=>" \u0651", "\uFE7D"=>"\u0640\u0651", "\uFE7E"=>" \u0652", "\uFE7F"=>"\u0640\u0652",
- "\uFE80"=>"\u0621", "\uFE81"=>"\u0622", "\uFE82"=>"\u0622", "\uFE83"=>"\u0623", "\uFE84"=>"\u0623", "\uFE85"=>"\u0624", "\uFE86"=>"\u0624", "\uFE87"=>"\u0625",
- "\uFE88"=>"\u0625", "\uFE89"=>"\u0626", "\uFE8A"=>"\u0626", "\uFE8B"=>"\u0626", "\uFE8C"=>"\u0626", "\uFE8D"=>"\u0627", "\uFE8E"=>"\u0627", "\uFE8F"=>"\u0628",
- "\uFE90"=>"\u0628", "\uFE91"=>"\u0628", "\uFE92"=>"\u0628", "\uFE93"=>"\u0629", "\uFE94"=>"\u0629", "\uFE95"=>"\u062A", "\uFE96"=>"\u062A", "\uFE97"=>"\u062A",
- "\uFE98"=>"\u062A", "\uFE99"=>"\u062B", "\uFE9A"=>"\u062B", "\uFE9B"=>"\u062B", "\uFE9C"=>"\u062B", "\uFE9D"=>"\u062C", "\uFE9E"=>"\u062C", "\uFE9F"=>"\u062C",
- "\uFEA0"=>"\u062C", "\uFEA1"=>"\u062D", "\uFEA2"=>"\u062D", "\uFEA3"=>"\u062D", "\uFEA4"=>"\u062D", "\uFEA5"=>"\u062E", "\uFEA6"=>"\u062E", "\uFEA7"=>"\u062E",
- "\uFEA8"=>"\u062E", "\uFEA9"=>"\u062F", "\uFEAA"=>"\u062F", "\uFEAB"=>"\u0630", "\uFEAC"=>"\u0630", "\uFEAD"=>"\u0631", "\uFEAE"=>"\u0631", "\uFEAF"=>"\u0632",
- "\uFEB0"=>"\u0632", "\uFEB1"=>"\u0633", "\uFEB2"=>"\u0633", "\uFEB3"=>"\u0633", "\uFEB4"=>"\u0633", "\uFEB5"=>"\u0634", "\uFEB6"=>"\u0634", "\uFEB7"=>"\u0634",
- "\uFEB8"=>"\u0634", "\uFEB9"=>"\u0635", "\uFEBA"=>"\u0635", "\uFEBB"=>"\u0635", "\uFEBC"=>"\u0635", "\uFEBD"=>"\u0636", "\uFEBE"=>"\u0636", "\uFEBF"=>"\u0636",
- "\uFEC0"=>"\u0636", "\uFEC1"=>"\u0637", "\uFEC2"=>"\u0637", "\uFEC3"=>"\u0637", "\uFEC4"=>"\u0637", "\uFEC5"=>"\u0638", "\uFEC6"=>"\u0638", "\uFEC7"=>"\u0638",
- "\uFEC8"=>"\u0638", "\uFEC9"=>"\u0639", "\uFECA"=>"\u0639", "\uFECB"=>"\u0639", "\uFECC"=>"\u0639", "\uFECD"=>"\u063A", "\uFECE"=>"\u063A", "\uFECF"=>"\u063A",
- "\uFED0"=>"\u063A", "\uFED1"=>"\u0641", "\uFED2"=>"\u0641", "\uFED3"=>"\u0641", "\uFED4"=>"\u0641", "\uFED5"=>"\u0642", "\uFED6"=>"\u0642", "\uFED7"=>"\u0642",
- "\uFED8"=>"\u0642", "\uFED9"=>"\u0643", "\uFEDA"=>"\u0643", "\uFEDB"=>"\u0643", "\uFEDC"=>"\u0643", "\uFEDD"=>"\u0644", "\uFEDE"=>"\u0644", "\uFEDF"=>"\u0644",
- "\uFEE0"=>"\u0644", "\uFEE1"=>"\u0645", "\uFEE2"=>"\u0645", "\uFEE3"=>"\u0645", "\uFEE4"=>"\u0645", "\uFEE5"=>"\u0646", "\uFEE6"=>"\u0646", "\uFEE7"=>"\u0646",
- "\uFEE8"=>"\u0646", "\uFEE9"=>"\u0647", "\uFEEA"=>"\u0647", "\uFEEB"=>"\u0647", "\uFEEC"=>"\u0647", "\uFEED"=>"\u0648", "\uFEEE"=>"\u0648", "\uFEEF"=>"\u0649",
- "\uFEF0"=>"\u0649", "\uFEF1"=>"\u064A", "\uFEF2"=>"\u064A", "\uFEF3"=>"\u064A", "\uFEF4"=>"\u064A", "\uFEF5"=>"\u0644\u0622", "\uFEF6"=>"\u0644\u0622", "\uFEF7"=>"\u0644\u0623",
- "\uFEF8"=>"\u0644\u0623", "\uFEF9"=>"\u0644\u0625", "\uFEFA"=>"\u0644\u0625", "\uFEFB"=>"\u0644\u0627", "\uFEFC"=>"\u0644\u0627", "\uFF01"=>"!", "\uFF02"=>"\"", "\uFF03"=>"#",
- "\uFF04"=>"$", "\uFF05"=>"%", "\uFF06"=>"&", "\uFF07"=>"'", "\uFF08"=>"(", "\uFF09"=>")", "\uFF0A"=>"*", "\uFF0B"=>"+",
- "\uFF0C"=>",", "\uFF0D"=>"-", "\uFF0E"=>".", "\uFF0F"=>"/", "\uFF10"=>"0", "\uFF11"=>"1", "\uFF12"=>"2", "\uFF13"=>"3",
- "\uFF14"=>"4", "\uFF15"=>"5", "\uFF16"=>"6", "\uFF17"=>"7", "\uFF18"=>"8", "\uFF19"=>"9", "\uFF1A"=>":", "\uFF1B"=>";",
- "\uFF1C"=>"<", "\uFF1D"=>"=", "\uFF1E"=>">", "\uFF1F"=>"?", "\uFF20"=>"@", "\uFF21"=>"A", "\uFF22"=>"B", "\uFF23"=>"C",
- "\uFF24"=>"D", "\uFF25"=>"E", "\uFF26"=>"F", "\uFF27"=>"G", "\uFF28"=>"H", "\uFF29"=>"I", "\uFF2A"=>"J", "\uFF2B"=>"K",
- "\uFF2C"=>"L", "\uFF2D"=>"M", "\uFF2E"=>"N", "\uFF2F"=>"O", "\uFF30"=>"P", "\uFF31"=>"Q", "\uFF32"=>"R", "\uFF33"=>"S",
- "\uFF34"=>"T", "\uFF35"=>"U", "\uFF36"=>"V", "\uFF37"=>"W", "\uFF38"=>"X", "\uFF39"=>"Y", "\uFF3A"=>"Z", "\uFF3B"=>"[",
- "\uFF3C"=>"\\", "\uFF3D"=>"]", "\uFF3E"=>"^", "\uFF3F"=>"_", "\uFF40"=>"`", "\uFF41"=>"a", "\uFF42"=>"b", "\uFF43"=>"c",
- "\uFF44"=>"d", "\uFF45"=>"e", "\uFF46"=>"f", "\uFF47"=>"g", "\uFF48"=>"h", "\uFF49"=>"i", "\uFF4A"=>"j", "\uFF4B"=>"k",
- "\uFF4C"=>"l", "\uFF4D"=>"m", "\uFF4E"=>"n", "\uFF4F"=>"o", "\uFF50"=>"p", "\uFF51"=>"q", "\uFF52"=>"r", "\uFF53"=>"s",
- "\uFF54"=>"t", "\uFF55"=>"u", "\uFF56"=>"v", "\uFF57"=>"w", "\uFF58"=>"x", "\uFF59"=>"y", "\uFF5A"=>"z", "\uFF5B"=>"{",
- "\uFF5C"=>"|", "\uFF5D"=>"}", "\uFF5E"=>"~", "\uFF5F"=>"\u2985", "\uFF60"=>"\u2986", "\uFF61"=>"\u3002", "\uFF62"=>"\u300C", "\uFF63"=>"\u300D",
- "\uFF64"=>"\u3001", "\uFF65"=>"\u30FB", "\uFF66"=>"\u30F2", "\uFF67"=>"\u30A1", "\uFF68"=>"\u30A3", "\uFF69"=>"\u30A5", "\uFF6A"=>"\u30A7", "\uFF6B"=>"\u30A9",
- "\uFF6C"=>"\u30E3", "\uFF6D"=>"\u30E5", "\uFF6E"=>"\u30E7", "\uFF6F"=>"\u30C3", "\uFF70"=>"\u30FC", "\uFF71"=>"\u30A2", "\uFF72"=>"\u30A4", "\uFF73"=>"\u30A6",
- "\uFF74"=>"\u30A8", "\uFF75"=>"\u30AA", "\uFF76"=>"\u30AB", "\uFF77"=>"\u30AD", "\uFF78"=>"\u30AF", "\uFF79"=>"\u30B1", "\uFF7A"=>"\u30B3", "\uFF7B"=>"\u30B5",
- "\uFF7C"=>"\u30B7", "\uFF7D"=>"\u30B9", "\uFF7E"=>"\u30BB", "\uFF7F"=>"\u30BD", "\uFF80"=>"\u30BF", "\uFF81"=>"\u30C1", "\uFF82"=>"\u30C4", "\uFF83"=>"\u30C6",
- "\uFF84"=>"\u30C8", "\uFF85"=>"\u30CA", "\uFF86"=>"\u30CB", "\uFF87"=>"\u30CC", "\uFF88"=>"\u30CD", "\uFF89"=>"\u30CE", "\uFF8A"=>"\u30CF", "\uFF8B"=>"\u30D2",
- "\uFF8C"=>"\u30D5", "\uFF8D"=>"\u30D8", "\uFF8E"=>"\u30DB", "\uFF8F"=>"\u30DE", "\uFF90"=>"\u30DF", "\uFF91"=>"\u30E0", "\uFF92"=>"\u30E1", "\uFF93"=>"\u30E2",
- "\uFF94"=>"\u30E4", "\uFF95"=>"\u30E6", "\uFF96"=>"\u30E8", "\uFF97"=>"\u30E9", "\uFF98"=>"\u30EA", "\uFF99"=>"\u30EB", "\uFF9A"=>"\u30EC", "\uFF9B"=>"\u30ED",
- "\uFF9C"=>"\u30EF", "\uFF9D"=>"\u30F3", "\uFF9E"=>"\u3099", "\uFF9F"=>"\u309A", "\uFFA0"=>"\u1160", "\uFFA1"=>"\u1100", "\uFFA2"=>"\u1101", "\uFFA3"=>"\u11AA",
- "\uFFA4"=>"\u1102", "\uFFA5"=>"\u11AC", "\uFFA6"=>"\u11AD", "\uFFA7"=>"\u1103", "\uFFA8"=>"\u1104", "\uFFA9"=>"\u1105", "\uFFAA"=>"\u11B0", "\uFFAB"=>"\u11B1",
- "\uFFAC"=>"\u11B2", "\uFFAD"=>"\u11B3", "\uFFAE"=>"\u11B4", "\uFFAF"=>"\u11B5", "\uFFB0"=>"\u111A", "\uFFB1"=>"\u1106", "\uFFB2"=>"\u1107", "\uFFB3"=>"\u1108",
- "\uFFB4"=>"\u1121", "\uFFB5"=>"\u1109", "\uFFB6"=>"\u110A", "\uFFB7"=>"\u110B", "\uFFB8"=>"\u110C", "\uFFB9"=>"\u110D", "\uFFBA"=>"\u110E", "\uFFBB"=>"\u110F",
- "\uFFBC"=>"\u1110", "\uFFBD"=>"\u1111", "\uFFBE"=>"\u1112", "\uFFC2"=>"\u1161", "\uFFC3"=>"\u1162", "\uFFC4"=>"\u1163", "\uFFC5"=>"\u1164", "\uFFC6"=>"\u1165",
- "\uFFC7"=>"\u1166", "\uFFCA"=>"\u1167", "\uFFCB"=>"\u1168", "\uFFCC"=>"\u1169", "\uFFCD"=>"\u116A", "\uFFCE"=>"\u116B", "\uFFCF"=>"\u116C", "\uFFD2"=>"\u116D",
- "\uFFD3"=>"\u116E", "\uFFD4"=>"\u116F", "\uFFD5"=>"\u1170", "\uFFD6"=>"\u1171", "\uFFD7"=>"\u1172", "\uFFDA"=>"\u1173", "\uFFDB"=>"\u1174", "\uFFDC"=>"\u1175",
- "\uFFE0"=>"\u00A2", "\uFFE1"=>"\u00A3", "\uFFE2"=>"\u00AC", "\uFFE3"=>" \u0304", "\uFFE4"=>"\u00A6", "\uFFE5"=>"\u00A5", "\uFFE6"=>"\u20A9", "\uFFE8"=>"\u2502",
- "\uFFE9"=>"\u2190", "\uFFEA"=>"\u2191", "\uFFEB"=>"\u2192", "\uFFEC"=>"\u2193", "\uFFED"=>"\u25A0", "\uFFEE"=>"\u25CB", "\u{1D400}"=>"A", "\u{1D401}"=>"B",
- "\u{1D402}"=>"C", "\u{1D403}"=>"D", "\u{1D404}"=>"E", "\u{1D405}"=>"F", "\u{1D406}"=>"G", "\u{1D407}"=>"H", "\u{1D408}"=>"I", "\u{1D409}"=>"J",
- "\u{1D40A}"=>"K", "\u{1D40B}"=>"L", "\u{1D40C}"=>"M", "\u{1D40D}"=>"N", "\u{1D40E}"=>"O", "\u{1D40F}"=>"P", "\u{1D410}"=>"Q", "\u{1D411}"=>"R",
- "\u{1D412}"=>"S", "\u{1D413}"=>"T", "\u{1D414}"=>"U", "\u{1D415}"=>"V", "\u{1D416}"=>"W", "\u{1D417}"=>"X", "\u{1D418}"=>"Y", "\u{1D419}"=>"Z",
- "\u{1D41A}"=>"a", "\u{1D41B}"=>"b", "\u{1D41C}"=>"c", "\u{1D41D}"=>"d", "\u{1D41E}"=>"e", "\u{1D41F}"=>"f", "\u{1D420}"=>"g", "\u{1D421}"=>"h",
- "\u{1D422}"=>"i", "\u{1D423}"=>"j", "\u{1D424}"=>"k", "\u{1D425}"=>"l", "\u{1D426}"=>"m", "\u{1D427}"=>"n", "\u{1D428}"=>"o", "\u{1D429}"=>"p",
- "\u{1D42A}"=>"q", "\u{1D42B}"=>"r", "\u{1D42C}"=>"s", "\u{1D42D}"=>"t", "\u{1D42E}"=>"u", "\u{1D42F}"=>"v", "\u{1D430}"=>"w", "\u{1D431}"=>"x",
- "\u{1D432}"=>"y", "\u{1D433}"=>"z", "\u{1D434}"=>"A", "\u{1D435}"=>"B", "\u{1D436}"=>"C", "\u{1D437}"=>"D", "\u{1D438}"=>"E", "\u{1D439}"=>"F",
- "\u{1D43A}"=>"G", "\u{1D43B}"=>"H", "\u{1D43C}"=>"I", "\u{1D43D}"=>"J", "\u{1D43E}"=>"K", "\u{1D43F}"=>"L", "\u{1D440}"=>"M", "\u{1D441}"=>"N",
- "\u{1D442}"=>"O", "\u{1D443}"=>"P", "\u{1D444}"=>"Q", "\u{1D445}"=>"R", "\u{1D446}"=>"S", "\u{1D447}"=>"T", "\u{1D448}"=>"U", "\u{1D449}"=>"V",
- "\u{1D44A}"=>"W", "\u{1D44B}"=>"X", "\u{1D44C}"=>"Y", "\u{1D44D}"=>"Z", "\u{1D44E}"=>"a", "\u{1D44F}"=>"b", "\u{1D450}"=>"c", "\u{1D451}"=>"d",
- "\u{1D452}"=>"e", "\u{1D453}"=>"f", "\u{1D454}"=>"g", "\u{1D456}"=>"i", "\u{1D457}"=>"j", "\u{1D458}"=>"k", "\u{1D459}"=>"l", "\u{1D45A}"=>"m",
- "\u{1D45B}"=>"n", "\u{1D45C}"=>"o", "\u{1D45D}"=>"p", "\u{1D45E}"=>"q", "\u{1D45F}"=>"r", "\u{1D460}"=>"s", "\u{1D461}"=>"t", "\u{1D462}"=>"u",
- "\u{1D463}"=>"v", "\u{1D464}"=>"w", "\u{1D465}"=>"x", "\u{1D466}"=>"y", "\u{1D467}"=>"z", "\u{1D468}"=>"A", "\u{1D469}"=>"B", "\u{1D46A}"=>"C",
- "\u{1D46B}"=>"D", "\u{1D46C}"=>"E", "\u{1D46D}"=>"F", "\u{1D46E}"=>"G", "\u{1D46F}"=>"H", "\u{1D470}"=>"I", "\u{1D471}"=>"J", "\u{1D472}"=>"K",
- "\u{1D473}"=>"L", "\u{1D474}"=>"M", "\u{1D475}"=>"N", "\u{1D476}"=>"O", "\u{1D477}"=>"P", "\u{1D478}"=>"Q", "\u{1D479}"=>"R", "\u{1D47A}"=>"S",
- "\u{1D47B}"=>"T", "\u{1D47C}"=>"U", "\u{1D47D}"=>"V", "\u{1D47E}"=>"W", "\u{1D47F}"=>"X", "\u{1D480}"=>"Y", "\u{1D481}"=>"Z", "\u{1D482}"=>"a",
- "\u{1D483}"=>"b", "\u{1D484}"=>"c", "\u{1D485}"=>"d", "\u{1D486}"=>"e", "\u{1D487}"=>"f", "\u{1D488}"=>"g", "\u{1D489}"=>"h", "\u{1D48A}"=>"i",
- "\u{1D48B}"=>"j", "\u{1D48C}"=>"k", "\u{1D48D}"=>"l", "\u{1D48E}"=>"m", "\u{1D48F}"=>"n", "\u{1D490}"=>"o", "\u{1D491}"=>"p", "\u{1D492}"=>"q",
- "\u{1D493}"=>"r", "\u{1D494}"=>"s", "\u{1D495}"=>"t", "\u{1D496}"=>"u", "\u{1D497}"=>"v", "\u{1D498}"=>"w", "\u{1D499}"=>"x", "\u{1D49A}"=>"y",
- "\u{1D49B}"=>"z", "\u{1D49C}"=>"A", "\u{1D49E}"=>"C", "\u{1D49F}"=>"D", "\u{1D4A2}"=>"G", "\u{1D4A5}"=>"J", "\u{1D4A6}"=>"K", "\u{1D4A9}"=>"N",
- "\u{1D4AA}"=>"O", "\u{1D4AB}"=>"P", "\u{1D4AC}"=>"Q", "\u{1D4AE}"=>"S", "\u{1D4AF}"=>"T", "\u{1D4B0}"=>"U", "\u{1D4B1}"=>"V", "\u{1D4B2}"=>"W",
- "\u{1D4B3}"=>"X", "\u{1D4B4}"=>"Y", "\u{1D4B5}"=>"Z", "\u{1D4B6}"=>"a", "\u{1D4B7}"=>"b", "\u{1D4B8}"=>"c", "\u{1D4B9}"=>"d", "\u{1D4BB}"=>"f",
- "\u{1D4BD}"=>"h", "\u{1D4BE}"=>"i", "\u{1D4BF}"=>"j", "\u{1D4C0}"=>"k", "\u{1D4C1}"=>"l", "\u{1D4C2}"=>"m", "\u{1D4C3}"=>"n", "\u{1D4C5}"=>"p",
- "\u{1D4C6}"=>"q", "\u{1D4C7}"=>"r", "\u{1D4C8}"=>"s", "\u{1D4C9}"=>"t", "\u{1D4CA}"=>"u", "\u{1D4CB}"=>"v", "\u{1D4CC}"=>"w", "\u{1D4CD}"=>"x",
- "\u{1D4CE}"=>"y", "\u{1D4CF}"=>"z", "\u{1D4D0}"=>"A", "\u{1D4D1}"=>"B", "\u{1D4D2}"=>"C", "\u{1D4D3}"=>"D", "\u{1D4D4}"=>"E", "\u{1D4D5}"=>"F",
- "\u{1D4D6}"=>"G", "\u{1D4D7}"=>"H", "\u{1D4D8}"=>"I", "\u{1D4D9}"=>"J", "\u{1D4DA}"=>"K", "\u{1D4DB}"=>"L", "\u{1D4DC}"=>"M", "\u{1D4DD}"=>"N",
- "\u{1D4DE}"=>"O", "\u{1D4DF}"=>"P", "\u{1D4E0}"=>"Q", "\u{1D4E1}"=>"R", "\u{1D4E2}"=>"S", "\u{1D4E3}"=>"T", "\u{1D4E4}"=>"U", "\u{1D4E5}"=>"V",
- "\u{1D4E6}"=>"W", "\u{1D4E7}"=>"X", "\u{1D4E8}"=>"Y", "\u{1D4E9}"=>"Z", "\u{1D4EA}"=>"a", "\u{1D4EB}"=>"b", "\u{1D4EC}"=>"c", "\u{1D4ED}"=>"d",
- "\u{1D4EE}"=>"e", "\u{1D4EF}"=>"f", "\u{1D4F0}"=>"g", "\u{1D4F1}"=>"h", "\u{1D4F2}"=>"i", "\u{1D4F3}"=>"j", "\u{1D4F4}"=>"k", "\u{1D4F5}"=>"l",
- "\u{1D4F6}"=>"m", "\u{1D4F7}"=>"n", "\u{1D4F8}"=>"o", "\u{1D4F9}"=>"p", "\u{1D4FA}"=>"q", "\u{1D4FB}"=>"r", "\u{1D4FC}"=>"s", "\u{1D4FD}"=>"t",
- "\u{1D4FE}"=>"u", "\u{1D4FF}"=>"v", "\u{1D500}"=>"w", "\u{1D501}"=>"x", "\u{1D502}"=>"y", "\u{1D503}"=>"z", "\u{1D504}"=>"A", "\u{1D505}"=>"B",
- "\u{1D507}"=>"D", "\u{1D508}"=>"E", "\u{1D509}"=>"F", "\u{1D50A}"=>"G", "\u{1D50D}"=>"J", "\u{1D50E}"=>"K", "\u{1D50F}"=>"L", "\u{1D510}"=>"M",
- "\u{1D511}"=>"N", "\u{1D512}"=>"O", "\u{1D513}"=>"P", "\u{1D514}"=>"Q", "\u{1D516}"=>"S", "\u{1D517}"=>"T", "\u{1D518}"=>"U", "\u{1D519}"=>"V",
- "\u{1D51A}"=>"W", "\u{1D51B}"=>"X", "\u{1D51C}"=>"Y", "\u{1D51E}"=>"a", "\u{1D51F}"=>"b", "\u{1D520}"=>"c", "\u{1D521}"=>"d", "\u{1D522}"=>"e",
- "\u{1D523}"=>"f", "\u{1D524}"=>"g", "\u{1D525}"=>"h", "\u{1D526}"=>"i", "\u{1D527}"=>"j", "\u{1D528}"=>"k", "\u{1D529}"=>"l", "\u{1D52A}"=>"m",
- "\u{1D52B}"=>"n", "\u{1D52C}"=>"o", "\u{1D52D}"=>"p", "\u{1D52E}"=>"q", "\u{1D52F}"=>"r", "\u{1D530}"=>"s", "\u{1D531}"=>"t", "\u{1D532}"=>"u",
- "\u{1D533}"=>"v", "\u{1D534}"=>"w", "\u{1D535}"=>"x", "\u{1D536}"=>"y", "\u{1D537}"=>"z", "\u{1D538}"=>"A", "\u{1D539}"=>"B", "\u{1D53B}"=>"D",
- "\u{1D53C}"=>"E", "\u{1D53D}"=>"F", "\u{1D53E}"=>"G", "\u{1D540}"=>"I", "\u{1D541}"=>"J", "\u{1D542}"=>"K", "\u{1D543}"=>"L", "\u{1D544}"=>"M",
- "\u{1D546}"=>"O", "\u{1D54A}"=>"S", "\u{1D54B}"=>"T", "\u{1D54C}"=>"U", "\u{1D54D}"=>"V", "\u{1D54E}"=>"W", "\u{1D54F}"=>"X", "\u{1D550}"=>"Y",
- "\u{1D552}"=>"a", "\u{1D553}"=>"b", "\u{1D554}"=>"c", "\u{1D555}"=>"d", "\u{1D556}"=>"e", "\u{1D557}"=>"f", "\u{1D558}"=>"g", "\u{1D559}"=>"h",
- "\u{1D55A}"=>"i", "\u{1D55B}"=>"j", "\u{1D55C}"=>"k", "\u{1D55D}"=>"l", "\u{1D55E}"=>"m", "\u{1D55F}"=>"n", "\u{1D560}"=>"o", "\u{1D561}"=>"p",
- "\u{1D562}"=>"q", "\u{1D563}"=>"r", "\u{1D564}"=>"s", "\u{1D565}"=>"t", "\u{1D566}"=>"u", "\u{1D567}"=>"v", "\u{1D568}"=>"w", "\u{1D569}"=>"x",
- "\u{1D56A}"=>"y", "\u{1D56B}"=>"z", "\u{1D56C}"=>"A", "\u{1D56D}"=>"B", "\u{1D56E}"=>"C", "\u{1D56F}"=>"D", "\u{1D570}"=>"E", "\u{1D571}"=>"F",
- "\u{1D572}"=>"G", "\u{1D573}"=>"H", "\u{1D574}"=>"I", "\u{1D575}"=>"J", "\u{1D576}"=>"K", "\u{1D577}"=>"L", "\u{1D578}"=>"M", "\u{1D579}"=>"N",
- "\u{1D57A}"=>"O", "\u{1D57B}"=>"P", "\u{1D57C}"=>"Q", "\u{1D57D}"=>"R", "\u{1D57E}"=>"S", "\u{1D57F}"=>"T", "\u{1D580}"=>"U", "\u{1D581}"=>"V",
- "\u{1D582}"=>"W", "\u{1D583}"=>"X", "\u{1D584}"=>"Y", "\u{1D585}"=>"Z", "\u{1D586}"=>"a", "\u{1D587}"=>"b", "\u{1D588}"=>"c", "\u{1D589}"=>"d",
- "\u{1D58A}"=>"e", "\u{1D58B}"=>"f", "\u{1D58C}"=>"g", "\u{1D58D}"=>"h", "\u{1D58E}"=>"i", "\u{1D58F}"=>"j", "\u{1D590}"=>"k", "\u{1D591}"=>"l",
- "\u{1D592}"=>"m", "\u{1D593}"=>"n", "\u{1D594}"=>"o", "\u{1D595}"=>"p", "\u{1D596}"=>"q", "\u{1D597}"=>"r", "\u{1D598}"=>"s", "\u{1D599}"=>"t",
- "\u{1D59A}"=>"u", "\u{1D59B}"=>"v", "\u{1D59C}"=>"w", "\u{1D59D}"=>"x", "\u{1D59E}"=>"y", "\u{1D59F}"=>"z", "\u{1D5A0}"=>"A", "\u{1D5A1}"=>"B",
- "\u{1D5A2}"=>"C", "\u{1D5A3}"=>"D", "\u{1D5A4}"=>"E", "\u{1D5A5}"=>"F", "\u{1D5A6}"=>"G", "\u{1D5A7}"=>"H", "\u{1D5A8}"=>"I", "\u{1D5A9}"=>"J",
- "\u{1D5AA}"=>"K", "\u{1D5AB}"=>"L", "\u{1D5AC}"=>"M", "\u{1D5AD}"=>"N", "\u{1D5AE}"=>"O", "\u{1D5AF}"=>"P", "\u{1D5B0}"=>"Q", "\u{1D5B1}"=>"R",
- "\u{1D5B2}"=>"S", "\u{1D5B3}"=>"T", "\u{1D5B4}"=>"U", "\u{1D5B5}"=>"V", "\u{1D5B6}"=>"W", "\u{1D5B7}"=>"X", "\u{1D5B8}"=>"Y", "\u{1D5B9}"=>"Z",
- "\u{1D5BA}"=>"a", "\u{1D5BB}"=>"b", "\u{1D5BC}"=>"c", "\u{1D5BD}"=>"d", "\u{1D5BE}"=>"e", "\u{1D5BF}"=>"f", "\u{1D5C0}"=>"g", "\u{1D5C1}"=>"h",
- "\u{1D5C2}"=>"i", "\u{1D5C3}"=>"j", "\u{1D5C4}"=>"k", "\u{1D5C5}"=>"l", "\u{1D5C6}"=>"m", "\u{1D5C7}"=>"n", "\u{1D5C8}"=>"o", "\u{1D5C9}"=>"p",
- "\u{1D5CA}"=>"q", "\u{1D5CB}"=>"r", "\u{1D5CC}"=>"s", "\u{1D5CD}"=>"t", "\u{1D5CE}"=>"u", "\u{1D5CF}"=>"v", "\u{1D5D0}"=>"w", "\u{1D5D1}"=>"x",
- "\u{1D5D2}"=>"y", "\u{1D5D3}"=>"z", "\u{1D5D4}"=>"A", "\u{1D5D5}"=>"B", "\u{1D5D6}"=>"C", "\u{1D5D7}"=>"D", "\u{1D5D8}"=>"E", "\u{1D5D9}"=>"F",
- "\u{1D5DA}"=>"G", "\u{1D5DB}"=>"H", "\u{1D5DC}"=>"I", "\u{1D5DD}"=>"J", "\u{1D5DE}"=>"K", "\u{1D5DF}"=>"L", "\u{1D5E0}"=>"M", "\u{1D5E1}"=>"N",
- "\u{1D5E2}"=>"O", "\u{1D5E3}"=>"P", "\u{1D5E4}"=>"Q", "\u{1D5E5}"=>"R", "\u{1D5E6}"=>"S", "\u{1D5E7}"=>"T", "\u{1D5E8}"=>"U", "\u{1D5E9}"=>"V",
- "\u{1D5EA}"=>"W", "\u{1D5EB}"=>"X", "\u{1D5EC}"=>"Y", "\u{1D5ED}"=>"Z", "\u{1D5EE}"=>"a", "\u{1D5EF}"=>"b", "\u{1D5F0}"=>"c", "\u{1D5F1}"=>"d",
- "\u{1D5F2}"=>"e", "\u{1D5F3}"=>"f", "\u{1D5F4}"=>"g", "\u{1D5F5}"=>"h", "\u{1D5F6}"=>"i", "\u{1D5F7}"=>"j", "\u{1D5F8}"=>"k", "\u{1D5F9}"=>"l",
- "\u{1D5FA}"=>"m", "\u{1D5FB}"=>"n", "\u{1D5FC}"=>"o", "\u{1D5FD}"=>"p", "\u{1D5FE}"=>"q", "\u{1D5FF}"=>"r", "\u{1D600}"=>"s", "\u{1D601}"=>"t",
- "\u{1D602}"=>"u", "\u{1D603}"=>"v", "\u{1D604}"=>"w", "\u{1D605}"=>"x", "\u{1D606}"=>"y", "\u{1D607}"=>"z", "\u{1D608}"=>"A", "\u{1D609}"=>"B",
- "\u{1D60A}"=>"C", "\u{1D60B}"=>"D", "\u{1D60C}"=>"E", "\u{1D60D}"=>"F", "\u{1D60E}"=>"G", "\u{1D60F}"=>"H", "\u{1D610}"=>"I", "\u{1D611}"=>"J",
- "\u{1D612}"=>"K", "\u{1D613}"=>"L", "\u{1D614}"=>"M", "\u{1D615}"=>"N", "\u{1D616}"=>"O", "\u{1D617}"=>"P", "\u{1D618}"=>"Q", "\u{1D619}"=>"R",
- "\u{1D61A}"=>"S", "\u{1D61B}"=>"T", "\u{1D61C}"=>"U", "\u{1D61D}"=>"V", "\u{1D61E}"=>"W", "\u{1D61F}"=>"X", "\u{1D620}"=>"Y", "\u{1D621}"=>"Z",
- "\u{1D622}"=>"a", "\u{1D623}"=>"b", "\u{1D624}"=>"c", "\u{1D625}"=>"d", "\u{1D626}"=>"e", "\u{1D627}"=>"f", "\u{1D628}"=>"g", "\u{1D629}"=>"h",
- "\u{1D62A}"=>"i", "\u{1D62B}"=>"j", "\u{1D62C}"=>"k", "\u{1D62D}"=>"l", "\u{1D62E}"=>"m", "\u{1D62F}"=>"n", "\u{1D630}"=>"o", "\u{1D631}"=>"p",
- "\u{1D632}"=>"q", "\u{1D633}"=>"r", "\u{1D634}"=>"s", "\u{1D635}"=>"t", "\u{1D636}"=>"u", "\u{1D637}"=>"v", "\u{1D638}"=>"w", "\u{1D639}"=>"x",
- "\u{1D63A}"=>"y", "\u{1D63B}"=>"z", "\u{1D63C}"=>"A", "\u{1D63D}"=>"B", "\u{1D63E}"=>"C", "\u{1D63F}"=>"D", "\u{1D640}"=>"E", "\u{1D641}"=>"F",
- "\u{1D642}"=>"G", "\u{1D643}"=>"H", "\u{1D644}"=>"I", "\u{1D645}"=>"J", "\u{1D646}"=>"K", "\u{1D647}"=>"L", "\u{1D648}"=>"M", "\u{1D649}"=>"N",
- "\u{1D64A}"=>"O", "\u{1D64B}"=>"P", "\u{1D64C}"=>"Q", "\u{1D64D}"=>"R", "\u{1D64E}"=>"S", "\u{1D64F}"=>"T", "\u{1D650}"=>"U", "\u{1D651}"=>"V",
- "\u{1D652}"=>"W", "\u{1D653}"=>"X", "\u{1D654}"=>"Y", "\u{1D655}"=>"Z", "\u{1D656}"=>"a", "\u{1D657}"=>"b", "\u{1D658}"=>"c", "\u{1D659}"=>"d",
- "\u{1D65A}"=>"e", "\u{1D65B}"=>"f", "\u{1D65C}"=>"g", "\u{1D65D}"=>"h", "\u{1D65E}"=>"i", "\u{1D65F}"=>"j", "\u{1D660}"=>"k", "\u{1D661}"=>"l",
- "\u{1D662}"=>"m", "\u{1D663}"=>"n", "\u{1D664}"=>"o", "\u{1D665}"=>"p", "\u{1D666}"=>"q", "\u{1D667}"=>"r", "\u{1D668}"=>"s", "\u{1D669}"=>"t",
- "\u{1D66A}"=>"u", "\u{1D66B}"=>"v", "\u{1D66C}"=>"w", "\u{1D66D}"=>"x", "\u{1D66E}"=>"y", "\u{1D66F}"=>"z", "\u{1D670}"=>"A", "\u{1D671}"=>"B",
- "\u{1D672}"=>"C", "\u{1D673}"=>"D", "\u{1D674}"=>"E", "\u{1D675}"=>"F", "\u{1D676}"=>"G", "\u{1D677}"=>"H", "\u{1D678}"=>"I", "\u{1D679}"=>"J",
- "\u{1D67A}"=>"K", "\u{1D67B}"=>"L", "\u{1D67C}"=>"M", "\u{1D67D}"=>"N", "\u{1D67E}"=>"O", "\u{1D67F}"=>"P", "\u{1D680}"=>"Q", "\u{1D681}"=>"R",
- "\u{1D682}"=>"S", "\u{1D683}"=>"T", "\u{1D684}"=>"U", "\u{1D685}"=>"V", "\u{1D686}"=>"W", "\u{1D687}"=>"X", "\u{1D688}"=>"Y", "\u{1D689}"=>"Z",
- "\u{1D68A}"=>"a", "\u{1D68B}"=>"b", "\u{1D68C}"=>"c", "\u{1D68D}"=>"d", "\u{1D68E}"=>"e", "\u{1D68F}"=>"f", "\u{1D690}"=>"g", "\u{1D691}"=>"h",
- "\u{1D692}"=>"i", "\u{1D693}"=>"j", "\u{1D694}"=>"k", "\u{1D695}"=>"l", "\u{1D696}"=>"m", "\u{1D697}"=>"n", "\u{1D698}"=>"o", "\u{1D699}"=>"p",
- "\u{1D69A}"=>"q", "\u{1D69B}"=>"r", "\u{1D69C}"=>"s", "\u{1D69D}"=>"t", "\u{1D69E}"=>"u", "\u{1D69F}"=>"v", "\u{1D6A0}"=>"w", "\u{1D6A1}"=>"x",
- "\u{1D6A2}"=>"y", "\u{1D6A3}"=>"z", "\u{1D6A4}"=>"\u0131", "\u{1D6A5}"=>"\u0237", "\u{1D6A8}"=>"\u0391", "\u{1D6A9}"=>"\u0392", "\u{1D6AA}"=>"\u0393", "\u{1D6AB}"=>"\u0394",
- "\u{1D6AC}"=>"\u0395", "\u{1D6AD}"=>"\u0396", "\u{1D6AE}"=>"\u0397", "\u{1D6AF}"=>"\u0398", "\u{1D6B0}"=>"\u0399", "\u{1D6B1}"=>"\u039A", "\u{1D6B2}"=>"\u039B", "\u{1D6B3}"=>"\u039C",
- "\u{1D6B4}"=>"\u039D", "\u{1D6B5}"=>"\u039E", "\u{1D6B6}"=>"\u039F", "\u{1D6B7}"=>"\u03A0", "\u{1D6B8}"=>"\u03A1", "\u{1D6B9}"=>"\u0398", "\u{1D6BA}"=>"\u03A3", "\u{1D6BB}"=>"\u03A4",
- "\u{1D6BC}"=>"\u03A5", "\u{1D6BD}"=>"\u03A6", "\u{1D6BE}"=>"\u03A7", "\u{1D6BF}"=>"\u03A8", "\u{1D6C0}"=>"\u03A9", "\u{1D6C1}"=>"\u2207", "\u{1D6C2}"=>"\u03B1", "\u{1D6C3}"=>"\u03B2",
- "\u{1D6C4}"=>"\u03B3", "\u{1D6C5}"=>"\u03B4", "\u{1D6C6}"=>"\u03B5", "\u{1D6C7}"=>"\u03B6", "\u{1D6C8}"=>"\u03B7", "\u{1D6C9}"=>"\u03B8", "\u{1D6CA}"=>"\u03B9", "\u{1D6CB}"=>"\u03BA",
- "\u{1D6CC}"=>"\u03BB", "\u{1D6CD}"=>"\u03BC", "\u{1D6CE}"=>"\u03BD", "\u{1D6CF}"=>"\u03BE", "\u{1D6D0}"=>"\u03BF", "\u{1D6D1}"=>"\u03C0", "\u{1D6D2}"=>"\u03C1", "\u{1D6D3}"=>"\u03C2",
- "\u{1D6D4}"=>"\u03C3", "\u{1D6D5}"=>"\u03C4", "\u{1D6D6}"=>"\u03C5", "\u{1D6D7}"=>"\u03C6", "\u{1D6D8}"=>"\u03C7", "\u{1D6D9}"=>"\u03C8", "\u{1D6DA}"=>"\u03C9", "\u{1D6DB}"=>"\u2202",
- "\u{1D6DC}"=>"\u03B5", "\u{1D6DD}"=>"\u03B8", "\u{1D6DE}"=>"\u03BA", "\u{1D6DF}"=>"\u03C6", "\u{1D6E0}"=>"\u03C1", "\u{1D6E1}"=>"\u03C0", "\u{1D6E2}"=>"\u0391", "\u{1D6E3}"=>"\u0392",
- "\u{1D6E4}"=>"\u0393", "\u{1D6E5}"=>"\u0394", "\u{1D6E6}"=>"\u0395", "\u{1D6E7}"=>"\u0396", "\u{1D6E8}"=>"\u0397", "\u{1D6E9}"=>"\u0398", "\u{1D6EA}"=>"\u0399", "\u{1D6EB}"=>"\u039A",
- "\u{1D6EC}"=>"\u039B", "\u{1D6ED}"=>"\u039C", "\u{1D6EE}"=>"\u039D", "\u{1D6EF}"=>"\u039E", "\u{1D6F0}"=>"\u039F", "\u{1D6F1}"=>"\u03A0", "\u{1D6F2}"=>"\u03A1", "\u{1D6F3}"=>"\u0398",
- "\u{1D6F4}"=>"\u03A3", "\u{1D6F5}"=>"\u03A4", "\u{1D6F6}"=>"\u03A5", "\u{1D6F7}"=>"\u03A6", "\u{1D6F8}"=>"\u03A7", "\u{1D6F9}"=>"\u03A8", "\u{1D6FA}"=>"\u03A9", "\u{1D6FB}"=>"\u2207",
- "\u{1D6FC}"=>"\u03B1", "\u{1D6FD}"=>"\u03B2", "\u{1D6FE}"=>"\u03B3", "\u{1D6FF}"=>"\u03B4", "\u{1D700}"=>"\u03B5", "\u{1D701}"=>"\u03B6", "\u{1D702}"=>"\u03B7", "\u{1D703}"=>"\u03B8",
- "\u{1D704}"=>"\u03B9", "\u{1D705}"=>"\u03BA", "\u{1D706}"=>"\u03BB", "\u{1D707}"=>"\u03BC", "\u{1D708}"=>"\u03BD", "\u{1D709}"=>"\u03BE", "\u{1D70A}"=>"\u03BF", "\u{1D70B}"=>"\u03C0",
- "\u{1D70C}"=>"\u03C1", "\u{1D70D}"=>"\u03C2", "\u{1D70E}"=>"\u03C3", "\u{1D70F}"=>"\u03C4", "\u{1D710}"=>"\u03C5", "\u{1D711}"=>"\u03C6", "\u{1D712}"=>"\u03C7", "\u{1D713}"=>"\u03C8",
- "\u{1D714}"=>"\u03C9", "\u{1D715}"=>"\u2202", "\u{1D716}"=>"\u03B5", "\u{1D717}"=>"\u03B8", "\u{1D718}"=>"\u03BA", "\u{1D719}"=>"\u03C6", "\u{1D71A}"=>"\u03C1", "\u{1D71B}"=>"\u03C0",
- "\u{1D71C}"=>"\u0391", "\u{1D71D}"=>"\u0392", "\u{1D71E}"=>"\u0393", "\u{1D71F}"=>"\u0394", "\u{1D720}"=>"\u0395", "\u{1D721}"=>"\u0396", "\u{1D722}"=>"\u0397", "\u{1D723}"=>"\u0398",
- "\u{1D724}"=>"\u0399", "\u{1D725}"=>"\u039A", "\u{1D726}"=>"\u039B", "\u{1D727}"=>"\u039C", "\u{1D728}"=>"\u039D", "\u{1D729}"=>"\u039E", "\u{1D72A}"=>"\u039F", "\u{1D72B}"=>"\u03A0",
- "\u{1D72C}"=>"\u03A1", "\u{1D72D}"=>"\u0398", "\u{1D72E}"=>"\u03A3", "\u{1D72F}"=>"\u03A4", "\u{1D730}"=>"\u03A5", "\u{1D731}"=>"\u03A6", "\u{1D732}"=>"\u03A7", "\u{1D733}"=>"\u03A8",
- "\u{1D734}"=>"\u03A9", "\u{1D735}"=>"\u2207", "\u{1D736}"=>"\u03B1", "\u{1D737}"=>"\u03B2", "\u{1D738}"=>"\u03B3", "\u{1D739}"=>"\u03B4", "\u{1D73A}"=>"\u03B5", "\u{1D73B}"=>"\u03B6",
- "\u{1D73C}"=>"\u03B7", "\u{1D73D}"=>"\u03B8", "\u{1D73E}"=>"\u03B9", "\u{1D73F}"=>"\u03BA", "\u{1D740}"=>"\u03BB", "\u{1D741}"=>"\u03BC", "\u{1D742}"=>"\u03BD", "\u{1D743}"=>"\u03BE",
- "\u{1D744}"=>"\u03BF", "\u{1D745}"=>"\u03C0", "\u{1D746}"=>"\u03C1", "\u{1D747}"=>"\u03C2", "\u{1D748}"=>"\u03C3", "\u{1D749}"=>"\u03C4", "\u{1D74A}"=>"\u03C5", "\u{1D74B}"=>"\u03C6",
- "\u{1D74C}"=>"\u03C7", "\u{1D74D}"=>"\u03C8", "\u{1D74E}"=>"\u03C9", "\u{1D74F}"=>"\u2202", "\u{1D750}"=>"\u03B5", "\u{1D751}"=>"\u03B8", "\u{1D752}"=>"\u03BA", "\u{1D753}"=>"\u03C6",
- "\u{1D754}"=>"\u03C1", "\u{1D755}"=>"\u03C0", "\u{1D756}"=>"\u0391", "\u{1D757}"=>"\u0392", "\u{1D758}"=>"\u0393", "\u{1D759}"=>"\u0394", "\u{1D75A}"=>"\u0395", "\u{1D75B}"=>"\u0396",
- "\u{1D75C}"=>"\u0397", "\u{1D75D}"=>"\u0398", "\u{1D75E}"=>"\u0399", "\u{1D75F}"=>"\u039A", "\u{1D760}"=>"\u039B", "\u{1D761}"=>"\u039C", "\u{1D762}"=>"\u039D", "\u{1D763}"=>"\u039E",
- "\u{1D764}"=>"\u039F", "\u{1D765}"=>"\u03A0", "\u{1D766}"=>"\u03A1", "\u{1D767}"=>"\u0398", "\u{1D768}"=>"\u03A3", "\u{1D769}"=>"\u03A4", "\u{1D76A}"=>"\u03A5", "\u{1D76B}"=>"\u03A6",
- "\u{1D76C}"=>"\u03A7", "\u{1D76D}"=>"\u03A8", "\u{1D76E}"=>"\u03A9", "\u{1D76F}"=>"\u2207", "\u{1D770}"=>"\u03B1", "\u{1D771}"=>"\u03B2", "\u{1D772}"=>"\u03B3", "\u{1D773}"=>"\u03B4",
- "\u{1D774}"=>"\u03B5", "\u{1D775}"=>"\u03B6", "\u{1D776}"=>"\u03B7", "\u{1D777}"=>"\u03B8", "\u{1D778}"=>"\u03B9", "\u{1D779}"=>"\u03BA", "\u{1D77A}"=>"\u03BB", "\u{1D77B}"=>"\u03BC",
- "\u{1D77C}"=>"\u03BD", "\u{1D77D}"=>"\u03BE", "\u{1D77E}"=>"\u03BF", "\u{1D77F}"=>"\u03C0", "\u{1D780}"=>"\u03C1", "\u{1D781}"=>"\u03C2", "\u{1D782}"=>"\u03C3", "\u{1D783}"=>"\u03C4",
- "\u{1D784}"=>"\u03C5", "\u{1D785}"=>"\u03C6", "\u{1D786}"=>"\u03C7", "\u{1D787}"=>"\u03C8", "\u{1D788}"=>"\u03C9", "\u{1D789}"=>"\u2202", "\u{1D78A}"=>"\u03B5", "\u{1D78B}"=>"\u03B8",
- "\u{1D78C}"=>"\u03BA", "\u{1D78D}"=>"\u03C6", "\u{1D78E}"=>"\u03C1", "\u{1D78F}"=>"\u03C0", "\u{1D790}"=>"\u0391", "\u{1D791}"=>"\u0392", "\u{1D792}"=>"\u0393", "\u{1D793}"=>"\u0394",
- "\u{1D794}"=>"\u0395", "\u{1D795}"=>"\u0396", "\u{1D796}"=>"\u0397", "\u{1D797}"=>"\u0398", "\u{1D798}"=>"\u0399", "\u{1D799}"=>"\u039A", "\u{1D79A}"=>"\u039B", "\u{1D79B}"=>"\u039C",
- "\u{1D79C}"=>"\u039D", "\u{1D79D}"=>"\u039E", "\u{1D79E}"=>"\u039F", "\u{1D79F}"=>"\u03A0", "\u{1D7A0}"=>"\u03A1", "\u{1D7A1}"=>"\u0398", "\u{1D7A2}"=>"\u03A3", "\u{1D7A3}"=>"\u03A4",
- "\u{1D7A4}"=>"\u03A5", "\u{1D7A5}"=>"\u03A6", "\u{1D7A6}"=>"\u03A7", "\u{1D7A7}"=>"\u03A8", "\u{1D7A8}"=>"\u03A9", "\u{1D7A9}"=>"\u2207", "\u{1D7AA}"=>"\u03B1", "\u{1D7AB}"=>"\u03B2",
- "\u{1D7AC}"=>"\u03B3", "\u{1D7AD}"=>"\u03B4", "\u{1D7AE}"=>"\u03B5", "\u{1D7AF}"=>"\u03B6", "\u{1D7B0}"=>"\u03B7", "\u{1D7B1}"=>"\u03B8", "\u{1D7B2}"=>"\u03B9", "\u{1D7B3}"=>"\u03BA",
- "\u{1D7B4}"=>"\u03BB", "\u{1D7B5}"=>"\u03BC", "\u{1D7B6}"=>"\u03BD", "\u{1D7B7}"=>"\u03BE", "\u{1D7B8}"=>"\u03BF", "\u{1D7B9}"=>"\u03C0", "\u{1D7BA}"=>"\u03C1", "\u{1D7BB}"=>"\u03C2",
- "\u{1D7BC}"=>"\u03C3", "\u{1D7BD}"=>"\u03C4", "\u{1D7BE}"=>"\u03C5", "\u{1D7BF}"=>"\u03C6", "\u{1D7C0}"=>"\u03C7", "\u{1D7C1}"=>"\u03C8", "\u{1D7C2}"=>"\u03C9", "\u{1D7C3}"=>"\u2202",
- "\u{1D7C4}"=>"\u03B5", "\u{1D7C5}"=>"\u03B8", "\u{1D7C6}"=>"\u03BA", "\u{1D7C7}"=>"\u03C6", "\u{1D7C8}"=>"\u03C1", "\u{1D7C9}"=>"\u03C0", "\u{1D7CA}"=>"\u03DC", "\u{1D7CB}"=>"\u03DD",
- "\u{1D7CE}"=>"0", "\u{1D7CF}"=>"1", "\u{1D7D0}"=>"2", "\u{1D7D1}"=>"3", "\u{1D7D2}"=>"4", "\u{1D7D3}"=>"5", "\u{1D7D4}"=>"6", "\u{1D7D5}"=>"7",
- "\u{1D7D6}"=>"8", "\u{1D7D7}"=>"9", "\u{1D7D8}"=>"0", "\u{1D7D9}"=>"1", "\u{1D7DA}"=>"2", "\u{1D7DB}"=>"3", "\u{1D7DC}"=>"4", "\u{1D7DD}"=>"5",
- "\u{1D7DE}"=>"6", "\u{1D7DF}"=>"7", "\u{1D7E0}"=>"8", "\u{1D7E1}"=>"9", "\u{1D7E2}"=>"0", "\u{1D7E3}"=>"1", "\u{1D7E4}"=>"2", "\u{1D7E5}"=>"3",
- "\u{1D7E6}"=>"4", "\u{1D7E7}"=>"5", "\u{1D7E8}"=>"6", "\u{1D7E9}"=>"7", "\u{1D7EA}"=>"8", "\u{1D7EB}"=>"9", "\u{1D7EC}"=>"0", "\u{1D7ED}"=>"1",
- "\u{1D7EE}"=>"2", "\u{1D7EF}"=>"3", "\u{1D7F0}"=>"4", "\u{1D7F1}"=>"5", "\u{1D7F2}"=>"6", "\u{1D7F3}"=>"7", "\u{1D7F4}"=>"8", "\u{1D7F5}"=>"9",
- "\u{1D7F6}"=>"0", "\u{1D7F7}"=>"1", "\u{1D7F8}"=>"2", "\u{1D7F9}"=>"3", "\u{1D7FA}"=>"4", "\u{1D7FB}"=>"5", "\u{1D7FC}"=>"6", "\u{1D7FD}"=>"7",
- "\u{1D7FE}"=>"8", "\u{1D7FF}"=>"9", "\u{1EE00}"=>"\u0627", "\u{1EE01}"=>"\u0628", "\u{1EE02}"=>"\u062C", "\u{1EE03}"=>"\u062F", "\u{1EE05}"=>"\u0648", "\u{1EE06}"=>"\u0632",
- "\u{1EE07}"=>"\u062D", "\u{1EE08}"=>"\u0637", "\u{1EE09}"=>"\u064A", "\u{1EE0A}"=>"\u0643", "\u{1EE0B}"=>"\u0644", "\u{1EE0C}"=>"\u0645", "\u{1EE0D}"=>"\u0646", "\u{1EE0E}"=>"\u0633",
- "\u{1EE0F}"=>"\u0639", "\u{1EE10}"=>"\u0641", "\u{1EE11}"=>"\u0635", "\u{1EE12}"=>"\u0642", "\u{1EE13}"=>"\u0631", "\u{1EE14}"=>"\u0634", "\u{1EE15}"=>"\u062A", "\u{1EE16}"=>"\u062B",
- "\u{1EE17}"=>"\u062E", "\u{1EE18}"=>"\u0630", "\u{1EE19}"=>"\u0636", "\u{1EE1A}"=>"\u0638", "\u{1EE1B}"=>"\u063A", "\u{1EE1C}"=>"\u066E", "\u{1EE1D}"=>"\u06BA", "\u{1EE1E}"=>"\u06A1",
- "\u{1EE1F}"=>"\u066F", "\u{1EE21}"=>"\u0628", "\u{1EE22}"=>"\u062C", "\u{1EE24}"=>"\u0647", "\u{1EE27}"=>"\u062D", "\u{1EE29}"=>"\u064A", "\u{1EE2A}"=>"\u0643", "\u{1EE2B}"=>"\u0644",
- "\u{1EE2C}"=>"\u0645", "\u{1EE2D}"=>"\u0646", "\u{1EE2E}"=>"\u0633", "\u{1EE2F}"=>"\u0639", "\u{1EE30}"=>"\u0641", "\u{1EE31}"=>"\u0635", "\u{1EE32}"=>"\u0642", "\u{1EE34}"=>"\u0634",
- "\u{1EE35}"=>"\u062A", "\u{1EE36}"=>"\u062B", "\u{1EE37}"=>"\u062E", "\u{1EE39}"=>"\u0636", "\u{1EE3B}"=>"\u063A", "\u{1EE42}"=>"\u062C", "\u{1EE47}"=>"\u062D", "\u{1EE49}"=>"\u064A",
- "\u{1EE4B}"=>"\u0644", "\u{1EE4D}"=>"\u0646", "\u{1EE4E}"=>"\u0633", "\u{1EE4F}"=>"\u0639", "\u{1EE51}"=>"\u0635", "\u{1EE52}"=>"\u0642", "\u{1EE54}"=>"\u0634", "\u{1EE57}"=>"\u062E",
- "\u{1EE59}"=>"\u0636", "\u{1EE5B}"=>"\u063A", "\u{1EE5D}"=>"\u06BA", "\u{1EE5F}"=>"\u066F", "\u{1EE61}"=>"\u0628", "\u{1EE62}"=>"\u062C", "\u{1EE64}"=>"\u0647", "\u{1EE67}"=>"\u062D",
- "\u{1EE68}"=>"\u0637", "\u{1EE69}"=>"\u064A", "\u{1EE6A}"=>"\u0643", "\u{1EE6C}"=>"\u0645", "\u{1EE6D}"=>"\u0646", "\u{1EE6E}"=>"\u0633", "\u{1EE6F}"=>"\u0639", "\u{1EE70}"=>"\u0641",
- "\u{1EE71}"=>"\u0635", "\u{1EE72}"=>"\u0642", "\u{1EE74}"=>"\u0634", "\u{1EE75}"=>"\u062A", "\u{1EE76}"=>"\u062B", "\u{1EE77}"=>"\u062E", "\u{1EE79}"=>"\u0636", "\u{1EE7A}"=>"\u0638",
- "\u{1EE7B}"=>"\u063A", "\u{1EE7C}"=>"\u066E", "\u{1EE7E}"=>"\u06A1", "\u{1EE80}"=>"\u0627", "\u{1EE81}"=>"\u0628", "\u{1EE82}"=>"\u062C", "\u{1EE83}"=>"\u062F", "\u{1EE84}"=>"\u0647",
- "\u{1EE85}"=>"\u0648", "\u{1EE86}"=>"\u0632", "\u{1EE87}"=>"\u062D", "\u{1EE88}"=>"\u0637", "\u{1EE89}"=>"\u064A", "\u{1EE8B}"=>"\u0644", "\u{1EE8C}"=>"\u0645", "\u{1EE8D}"=>"\u0646",
- "\u{1EE8E}"=>"\u0633", "\u{1EE8F}"=>"\u0639", "\u{1EE90}"=>"\u0641", "\u{1EE91}"=>"\u0635", "\u{1EE92}"=>"\u0642", "\u{1EE93}"=>"\u0631", "\u{1EE94}"=>"\u0634", "\u{1EE95}"=>"\u062A",
- "\u{1EE96}"=>"\u062B", "\u{1EE97}"=>"\u062E", "\u{1EE98}"=>"\u0630", "\u{1EE99}"=>"\u0636", "\u{1EE9A}"=>"\u0638", "\u{1EE9B}"=>"\u063A", "\u{1EEA1}"=>"\u0628", "\u{1EEA2}"=>"\u062C",
- "\u{1EEA3}"=>"\u062F", "\u{1EEA5}"=>"\u0648", "\u{1EEA6}"=>"\u0632", "\u{1EEA7}"=>"\u062D", "\u{1EEA8}"=>"\u0637", "\u{1EEA9}"=>"\u064A", "\u{1EEAB}"=>"\u0644", "\u{1EEAC}"=>"\u0645",
- "\u{1EEAD}"=>"\u0646", "\u{1EEAE}"=>"\u0633", "\u{1EEAF}"=>"\u0639", "\u{1EEB0}"=>"\u0641", "\u{1EEB1}"=>"\u0635", "\u{1EEB2}"=>"\u0642", "\u{1EEB3}"=>"\u0631", "\u{1EEB4}"=>"\u0634",
- "\u{1EEB5}"=>"\u062A", "\u{1EEB6}"=>"\u062B", "\u{1EEB7}"=>"\u062E", "\u{1EEB8}"=>"\u0630", "\u{1EEB9}"=>"\u0636", "\u{1EEBA}"=>"\u0638", "\u{1EEBB}"=>"\u063A", "\u{1F100}"=>"0.",
- "\u{1F101}"=>"0,", "\u{1F102}"=>"1,", "\u{1F103}"=>"2,", "\u{1F104}"=>"3,", "\u{1F105}"=>"4,", "\u{1F106}"=>"5,", "\u{1F107}"=>"6,", "\u{1F108}"=>"7,",
- "\u{1F109}"=>"8,", "\u{1F10A}"=>"9,", "\u{1F110}"=>"(A)", "\u{1F111}"=>"(B)", "\u{1F112}"=>"(C)", "\u{1F113}"=>"(D)", "\u{1F114}"=>"(E)", "\u{1F115}"=>"(F)",
- "\u{1F116}"=>"(G)", "\u{1F117}"=>"(H)", "\u{1F118}"=>"(I)", "\u{1F119}"=>"(J)", "\u{1F11A}"=>"(K)", "\u{1F11B}"=>"(L)", "\u{1F11C}"=>"(M)", "\u{1F11D}"=>"(N)",
- "\u{1F11E}"=>"(O)", "\u{1F11F}"=>"(P)", "\u{1F120}"=>"(Q)", "\u{1F121}"=>"(R)", "\u{1F122}"=>"(S)", "\u{1F123}"=>"(T)", "\u{1F124}"=>"(U)", "\u{1F125}"=>"(V)",
- "\u{1F126}"=>"(W)", "\u{1F127}"=>"(X)", "\u{1F128}"=>"(Y)", "\u{1F129}"=>"(Z)", "\u{1F12A}"=>"\u3014S\u3015", "\u{1F12B}"=>"C", "\u{1F12C}"=>"R", "\u{1F12D}"=>"CD",
- "\u{1F12E}"=>"WZ", "\u{1F130}"=>"A", "\u{1F131}"=>"B", "\u{1F132}"=>"C", "\u{1F133}"=>"D", "\u{1F134}"=>"E", "\u{1F135}"=>"F", "\u{1F136}"=>"G",
- "\u{1F137}"=>"H", "\u{1F138}"=>"I", "\u{1F139}"=>"J", "\u{1F13A}"=>"K", "\u{1F13B}"=>"L", "\u{1F13C}"=>"M", "\u{1F13D}"=>"N", "\u{1F13E}"=>"O",
- "\u{1F13F}"=>"P", "\u{1F140}"=>"Q", "\u{1F141}"=>"R", "\u{1F142}"=>"S", "\u{1F143}"=>"T", "\u{1F144}"=>"U", "\u{1F145}"=>"V", "\u{1F146}"=>"W",
- "\u{1F147}"=>"X", "\u{1F148}"=>"Y", "\u{1F149}"=>"Z", "\u{1F14A}"=>"HV", "\u{1F14B}"=>"MV", "\u{1F14C}"=>"SD", "\u{1F14D}"=>"SS", "\u{1F14E}"=>"PPV",
- "\u{1F14F}"=>"WC", "\u{1F16A}"=>"MC", "\u{1F16B}"=>"MD", "\u{1F190}"=>"DJ", "\u{1F200}"=>"\u307B\u304B", "\u{1F201}"=>"\u30B3\u30B3", "\u{1F202}"=>"\u30B5", "\u{1F210}"=>"\u624B",
- "\u{1F211}"=>"\u5B57", "\u{1F212}"=>"\u53CC", "\u{1F213}"=>"\u30C7", "\u{1F214}"=>"\u4E8C", "\u{1F215}"=>"\u591A", "\u{1F216}"=>"\u89E3", "\u{1F217}"=>"\u5929", "\u{1F218}"=>"\u4EA4",
- "\u{1F219}"=>"\u6620", "\u{1F21A}"=>"\u7121", "\u{1F21B}"=>"\u6599", "\u{1F21C}"=>"\u524D", "\u{1F21D}"=>"\u5F8C", "\u{1F21E}"=>"\u518D", "\u{1F21F}"=>"\u65B0", "\u{1F220}"=>"\u521D",
- "\u{1F221}"=>"\u7D42", "\u{1F222}"=>"\u751F", "\u{1F223}"=>"\u8CA9", "\u{1F224}"=>"\u58F0", "\u{1F225}"=>"\u5439", "\u{1F226}"=>"\u6F14", "\u{1F227}"=>"\u6295", "\u{1F228}"=>"\u6355",
- "\u{1F229}"=>"\u4E00", "\u{1F22A}"=>"\u4E09", "\u{1F22B}"=>"\u904A", "\u{1F22C}"=>"\u5DE6", "\u{1F22D}"=>"\u4E2D", "\u{1F22E}"=>"\u53F3", "\u{1F22F}"=>"\u6307", "\u{1F230}"=>"\u8D70",
- "\u{1F231}"=>"\u6253", "\u{1F232}"=>"\u7981", "\u{1F233}"=>"\u7A7A", "\u{1F234}"=>"\u5408", "\u{1F235}"=>"\u6E80", "\u{1F236}"=>"\u6709", "\u{1F237}"=>"\u6708", "\u{1F238}"=>"\u7533",
- "\u{1F239}"=>"\u5272", "\u{1F23A}"=>"\u55B6", "\u{1F23B}"=>"\u914D", "\u{1F240}"=>"\u3014\u672C\u3015", "\u{1F241}"=>"\u3014\u4E09\u3015", "\u{1F242}"=>"\u3014\u4E8C\u3015", "\u{1F243}"=>"\u3014\u5B89\u3015", "\u{1F244}"=>"\u3014\u70B9\u3015",
- "\u{1F245}"=>"\u3014\u6253\u3015", "\u{1F246}"=>"\u3014\u76D7\u3015", "\u{1F247}"=>"\u3014\u52DD\u3015", "\u{1F248}"=>"\u3014\u6557\u3015", "\u{1F250}"=>"\u5F97", "\u{1F251}"=>"\u53EF", "\u0385"=>" \u0308\u0301", "\u03D3"=>"\u03A5\u0301",
- "\u03D4"=>"\u03A5\u0308", "\u1E9B"=>"s\u0307", "\u1FC1"=>" \u0308\u0342", "\u1FCD"=>" \u0313\u0300", "\u1FCE"=>" \u0313\u0301", "\u1FCF"=>" \u0313\u0342", "\u1FDD"=>" \u0314\u0300", "\u1FDE"=>" \u0314\u0301",
- "\u1FDF"=>" \u0314\u0342", "\u1FED"=>" \u0308\u0300", "\u1FEE"=>" \u0308\u0301", "\u1FFD"=>" \u0301", "\u2000"=>" ", "\u2001"=>" ",
+ "\u00A0"=>" ",
+ "\u00A8"=>" \u0308",
+ "\u00AA"=>"a",
+ "\u00AF"=>" \u0304",
+ "\u00B2"=>"2",
+ "\u00B3"=>"3",
+ "\u00B4"=>" \u0301",
+ "\u00B5"=>"\u03BC",
+ "\u00B8"=>" \u0327",
+ "\u00B9"=>"1",
+ "\u00BA"=>"o",
+ "\u00BC"=>"1\u20444",
+ "\u00BD"=>"1\u20442",
+ "\u00BE"=>"3\u20444",
+ "\u0132"=>"IJ",
+ "\u0133"=>"ij",
+ "\u013F"=>"L\u00B7",
+ "\u0140"=>"l\u00B7",
+ "\u0149"=>"\u02BCn",
+ "\u017F"=>"s",
+ "\u01C4"=>"D\u017D",
+ "\u01C5"=>"D\u017E",
+ "\u01C6"=>"d\u017E",
+ "\u01C7"=>"LJ",
+ "\u01C8"=>"Lj",
+ "\u01C9"=>"lj",
+ "\u01CA"=>"NJ",
+ "\u01CB"=>"Nj",
+ "\u01CC"=>"nj",
+ "\u01F1"=>"DZ",
+ "\u01F2"=>"Dz",
+ "\u01F3"=>"dz",
+ "\u02B0"=>"h",
+ "\u02B1"=>"\u0266",
+ "\u02B2"=>"j",
+ "\u02B3"=>"r",
+ "\u02B4"=>"\u0279",
+ "\u02B5"=>"\u027B",
+ "\u02B6"=>"\u0281",
+ "\u02B7"=>"w",
+ "\u02B8"=>"y",
+ "\u02D8"=>" \u0306",
+ "\u02D9"=>" \u0307",
+ "\u02DA"=>" \u030A",
+ "\u02DB"=>" \u0328",
+ "\u02DC"=>" \u0303",
+ "\u02DD"=>" \u030B",
+ "\u02E0"=>"\u0263",
+ "\u02E1"=>"l",
+ "\u02E2"=>"s",
+ "\u02E3"=>"x",
+ "\u02E4"=>"\u0295",
+ "\u037A"=>" \u0345",
+ "\u0384"=>" \u0301",
+ "\u03D0"=>"\u03B2",
+ "\u03D1"=>"\u03B8",
+ "\u03D2"=>"\u03A5",
+ "\u03D5"=>"\u03C6",
+ "\u03D6"=>"\u03C0",
+ "\u03F0"=>"\u03BA",
+ "\u03F1"=>"\u03C1",
+ "\u03F2"=>"\u03C2",
+ "\u03F4"=>"\u0398",
+ "\u03F5"=>"\u03B5",
+ "\u03F9"=>"\u03A3",
+ "\u0587"=>"\u0565\u0582",
+ "\u0675"=>"\u0627\u0674",
+ "\u0676"=>"\u0648\u0674",
+ "\u0677"=>"\u06C7\u0674",
+ "\u0678"=>"\u064A\u0674",
+ "\u0E33"=>"\u0E4D\u0E32",
+ "\u0EB3"=>"\u0ECD\u0EB2",
+ "\u0EDC"=>"\u0EAB\u0E99",
+ "\u0EDD"=>"\u0EAB\u0EA1",
+ "\u0F0C"=>"\u0F0B",
+ "\u0F77"=>"\u0FB2\u0F81",
+ "\u0F79"=>"\u0FB3\u0F81",
+ "\u10FC"=>"\u10DC",
+ "\u1D2C"=>"A",
+ "\u1D2D"=>"\u00C6",
+ "\u1D2E"=>"B",
+ "\u1D30"=>"D",
+ "\u1D31"=>"E",
+ "\u1D32"=>"\u018E",
+ "\u1D33"=>"G",
+ "\u1D34"=>"H",
+ "\u1D35"=>"I",
+ "\u1D36"=>"J",
+ "\u1D37"=>"K",
+ "\u1D38"=>"L",
+ "\u1D39"=>"M",
+ "\u1D3A"=>"N",
+ "\u1D3C"=>"O",
+ "\u1D3D"=>"\u0222",
+ "\u1D3E"=>"P",
+ "\u1D3F"=>"R",
+ "\u1D40"=>"T",
+ "\u1D41"=>"U",
+ "\u1D42"=>"W",
+ "\u1D43"=>"a",
+ "\u1D44"=>"\u0250",
+ "\u1D45"=>"\u0251",
+ "\u1D46"=>"\u1D02",
+ "\u1D47"=>"b",
+ "\u1D48"=>"d",
+ "\u1D49"=>"e",
+ "\u1D4A"=>"\u0259",
+ "\u1D4B"=>"\u025B",
+ "\u1D4C"=>"\u025C",
+ "\u1D4D"=>"g",
+ "\u1D4F"=>"k",
+ "\u1D50"=>"m",
+ "\u1D51"=>"\u014B",
+ "\u1D52"=>"o",
+ "\u1D53"=>"\u0254",
+ "\u1D54"=>"\u1D16",
+ "\u1D55"=>"\u1D17",
+ "\u1D56"=>"p",
+ "\u1D57"=>"t",
+ "\u1D58"=>"u",
+ "\u1D59"=>"\u1D1D",
+ "\u1D5A"=>"\u026F",
+ "\u1D5B"=>"v",
+ "\u1D5C"=>"\u1D25",
+ "\u1D5D"=>"\u03B2",
+ "\u1D5E"=>"\u03B3",
+ "\u1D5F"=>"\u03B4",
+ "\u1D60"=>"\u03C6",
+ "\u1D61"=>"\u03C7",
+ "\u1D62"=>"i",
+ "\u1D63"=>"r",
+ "\u1D64"=>"u",
+ "\u1D65"=>"v",
+ "\u1D66"=>"\u03B2",
+ "\u1D67"=>"\u03B3",
+ "\u1D68"=>"\u03C1",
+ "\u1D69"=>"\u03C6",
+ "\u1D6A"=>"\u03C7",
+ "\u1D78"=>"\u043D",
+ "\u1D9B"=>"\u0252",
+ "\u1D9C"=>"c",
+ "\u1D9D"=>"\u0255",
+ "\u1D9E"=>"\u00F0",
+ "\u1D9F"=>"\u025C",
+ "\u1DA0"=>"f",
+ "\u1DA1"=>"\u025F",
+ "\u1DA2"=>"\u0261",
+ "\u1DA3"=>"\u0265",
+ "\u1DA4"=>"\u0268",
+ "\u1DA5"=>"\u0269",
+ "\u1DA6"=>"\u026A",
+ "\u1DA7"=>"\u1D7B",
+ "\u1DA8"=>"\u029D",
+ "\u1DA9"=>"\u026D",
+ "\u1DAA"=>"\u1D85",
+ "\u1DAB"=>"\u029F",
+ "\u1DAC"=>"\u0271",
+ "\u1DAD"=>"\u0270",
+ "\u1DAE"=>"\u0272",
+ "\u1DAF"=>"\u0273",
+ "\u1DB0"=>"\u0274",
+ "\u1DB1"=>"\u0275",
+ "\u1DB2"=>"\u0278",
+ "\u1DB3"=>"\u0282",
+ "\u1DB4"=>"\u0283",
+ "\u1DB5"=>"\u01AB",
+ "\u1DB6"=>"\u0289",
+ "\u1DB7"=>"\u028A",
+ "\u1DB8"=>"\u1D1C",
+ "\u1DB9"=>"\u028B",
+ "\u1DBA"=>"\u028C",
+ "\u1DBB"=>"z",
+ "\u1DBC"=>"\u0290",
+ "\u1DBD"=>"\u0291",
+ "\u1DBE"=>"\u0292",
+ "\u1DBF"=>"\u03B8",
+ "\u1E9A"=>"a\u02BE",
+ "\u1FBD"=>" \u0313",
+ "\u1FBF"=>" \u0313",
+ "\u1FC0"=>" \u0342",
+ "\u1FFE"=>" \u0314",
+ "\u2002"=>" ",
+ "\u2003"=>" ",
+ "\u2004"=>" ",
+ "\u2005"=>" ",
+ "\u2006"=>" ",
+ "\u2007"=>" ",
+ "\u2008"=>" ",
+ "\u2009"=>" ",
+ "\u200A"=>" ",
+ "\u2011"=>"\u2010",
+ "\u2017"=>" \u0333",
+ "\u2024"=>".",
+ "\u2025"=>"..",
+ "\u2026"=>"...",
+ "\u202F"=>" ",
+ "\u2033"=>"\u2032\u2032",
+ "\u2034"=>"\u2032\u2032\u2032",
+ "\u2036"=>"\u2035\u2035",
+ "\u2037"=>"\u2035\u2035\u2035",
+ "\u203C"=>"!!",
+ "\u203E"=>" \u0305",
+ "\u2047"=>"??",
+ "\u2048"=>"?!",
+ "\u2049"=>"!?",
+ "\u2057"=>"\u2032\u2032\u2032\u2032",
+ "\u205F"=>" ",
+ "\u2070"=>"0",
+ "\u2071"=>"i",
+ "\u2074"=>"4",
+ "\u2075"=>"5",
+ "\u2076"=>"6",
+ "\u2077"=>"7",
+ "\u2078"=>"8",
+ "\u2079"=>"9",
+ "\u207A"=>"+",
+ "\u207B"=>"\u2212",
+ "\u207C"=>"=",
+ "\u207D"=>"(",
+ "\u207E"=>")",
+ "\u207F"=>"n",
+ "\u2080"=>"0",
+ "\u2081"=>"1",
+ "\u2082"=>"2",
+ "\u2083"=>"3",
+ "\u2084"=>"4",
+ "\u2085"=>"5",
+ "\u2086"=>"6",
+ "\u2087"=>"7",
+ "\u2088"=>"8",
+ "\u2089"=>"9",
+ "\u208A"=>"+",
+ "\u208B"=>"\u2212",
+ "\u208C"=>"=",
+ "\u208D"=>"(",
+ "\u208E"=>")",
+ "\u2090"=>"a",
+ "\u2091"=>"e",
+ "\u2092"=>"o",
+ "\u2093"=>"x",
+ "\u2094"=>"\u0259",
+ "\u2095"=>"h",
+ "\u2096"=>"k",
+ "\u2097"=>"l",
+ "\u2098"=>"m",
+ "\u2099"=>"n",
+ "\u209A"=>"p",
+ "\u209B"=>"s",
+ "\u209C"=>"t",
+ "\u20A8"=>"Rs",
+ "\u2100"=>"a/c",
+ "\u2101"=>"a/s",
+ "\u2102"=>"C",
+ "\u2103"=>"\u00B0C",
+ "\u2105"=>"c/o",
+ "\u2106"=>"c/u",
+ "\u2107"=>"\u0190",
+ "\u2109"=>"\u00B0F",
+ "\u210A"=>"g",
+ "\u210B"=>"H",
+ "\u210C"=>"H",
+ "\u210D"=>"H",
+ "\u210E"=>"h",
+ "\u210F"=>"\u0127",
+ "\u2110"=>"I",
+ "\u2111"=>"I",
+ "\u2112"=>"L",
+ "\u2113"=>"l",
+ "\u2115"=>"N",
+ "\u2116"=>"No",
+ "\u2119"=>"P",
+ "\u211A"=>"Q",
+ "\u211B"=>"R",
+ "\u211C"=>"R",
+ "\u211D"=>"R",
+ "\u2120"=>"SM",
+ "\u2121"=>"TEL",
+ "\u2122"=>"TM",
+ "\u2124"=>"Z",
+ "\u2128"=>"Z",
+ "\u212C"=>"B",
+ "\u212D"=>"C",
+ "\u212F"=>"e",
+ "\u2130"=>"E",
+ "\u2131"=>"F",
+ "\u2133"=>"M",
+ "\u2134"=>"o",
+ "\u2135"=>"\u05D0",
+ "\u2136"=>"\u05D1",
+ "\u2137"=>"\u05D2",
+ "\u2138"=>"\u05D3",
+ "\u2139"=>"i",
+ "\u213B"=>"FAX",
+ "\u213C"=>"\u03C0",
+ "\u213D"=>"\u03B3",
+ "\u213E"=>"\u0393",
+ "\u213F"=>"\u03A0",
+ "\u2140"=>"\u2211",
+ "\u2145"=>"D",
+ "\u2146"=>"d",
+ "\u2147"=>"e",
+ "\u2148"=>"i",
+ "\u2149"=>"j",
+ "\u2150"=>"1\u20447",
+ "\u2151"=>"1\u20449",
+ "\u2152"=>"1\u204410",
+ "\u2153"=>"1\u20443",
+ "\u2154"=>"2\u20443",
+ "\u2155"=>"1\u20445",
+ "\u2156"=>"2\u20445",
+ "\u2157"=>"3\u20445",
+ "\u2158"=>"4\u20445",
+ "\u2159"=>"1\u20446",
+ "\u215A"=>"5\u20446",
+ "\u215B"=>"1\u20448",
+ "\u215C"=>"3\u20448",
+ "\u215D"=>"5\u20448",
+ "\u215E"=>"7\u20448",
+ "\u215F"=>"1\u2044",
+ "\u2160"=>"I",
+ "\u2161"=>"II",
+ "\u2162"=>"III",
+ "\u2163"=>"IV",
+ "\u2164"=>"V",
+ "\u2165"=>"VI",
+ "\u2166"=>"VII",
+ "\u2167"=>"VIII",
+ "\u2168"=>"IX",
+ "\u2169"=>"X",
+ "\u216A"=>"XI",
+ "\u216B"=>"XII",
+ "\u216C"=>"L",
+ "\u216D"=>"C",
+ "\u216E"=>"D",
+ "\u216F"=>"M",
+ "\u2170"=>"i",
+ "\u2171"=>"ii",
+ "\u2172"=>"iii",
+ "\u2173"=>"iv",
+ "\u2174"=>"v",
+ "\u2175"=>"vi",
+ "\u2176"=>"vii",
+ "\u2177"=>"viii",
+ "\u2178"=>"ix",
+ "\u2179"=>"x",
+ "\u217A"=>"xi",
+ "\u217B"=>"xii",
+ "\u217C"=>"l",
+ "\u217D"=>"c",
+ "\u217E"=>"d",
+ "\u217F"=>"m",
+ "\u2189"=>"0\u20443",
+ "\u222C"=>"\u222B\u222B",
+ "\u222D"=>"\u222B\u222B\u222B",
+ "\u222F"=>"\u222E\u222E",
+ "\u2230"=>"\u222E\u222E\u222E",
+ "\u2460"=>"1",
+ "\u2461"=>"2",
+ "\u2462"=>"3",
+ "\u2463"=>"4",
+ "\u2464"=>"5",
+ "\u2465"=>"6",
+ "\u2466"=>"7",
+ "\u2467"=>"8",
+ "\u2468"=>"9",
+ "\u2469"=>"10",
+ "\u246A"=>"11",
+ "\u246B"=>"12",
+ "\u246C"=>"13",
+ "\u246D"=>"14",
+ "\u246E"=>"15",
+ "\u246F"=>"16",
+ "\u2470"=>"17",
+ "\u2471"=>"18",
+ "\u2472"=>"19",
+ "\u2473"=>"20",
+ "\u2474"=>"(1)",
+ "\u2475"=>"(2)",
+ "\u2476"=>"(3)",
+ "\u2477"=>"(4)",
+ "\u2478"=>"(5)",
+ "\u2479"=>"(6)",
+ "\u247A"=>"(7)",
+ "\u247B"=>"(8)",
+ "\u247C"=>"(9)",
+ "\u247D"=>"(10)",
+ "\u247E"=>"(11)",
+ "\u247F"=>"(12)",
+ "\u2480"=>"(13)",
+ "\u2481"=>"(14)",
+ "\u2482"=>"(15)",
+ "\u2483"=>"(16)",
+ "\u2484"=>"(17)",
+ "\u2485"=>"(18)",
+ "\u2486"=>"(19)",
+ "\u2487"=>"(20)",
+ "\u2488"=>"1.",
+ "\u2489"=>"2.",
+ "\u248A"=>"3.",
+ "\u248B"=>"4.",
+ "\u248C"=>"5.",
+ "\u248D"=>"6.",
+ "\u248E"=>"7.",
+ "\u248F"=>"8.",
+ "\u2490"=>"9.",
+ "\u2491"=>"10.",
+ "\u2492"=>"11.",
+ "\u2493"=>"12.",
+ "\u2494"=>"13.",
+ "\u2495"=>"14.",
+ "\u2496"=>"15.",
+ "\u2497"=>"16.",
+ "\u2498"=>"17.",
+ "\u2499"=>"18.",
+ "\u249A"=>"19.",
+ "\u249B"=>"20.",
+ "\u249C"=>"(a)",
+ "\u249D"=>"(b)",
+ "\u249E"=>"(c)",
+ "\u249F"=>"(d)",
+ "\u24A0"=>"(e)",
+ "\u24A1"=>"(f)",
+ "\u24A2"=>"(g)",
+ "\u24A3"=>"(h)",
+ "\u24A4"=>"(i)",
+ "\u24A5"=>"(j)",
+ "\u24A6"=>"(k)",
+ "\u24A7"=>"(l)",
+ "\u24A8"=>"(m)",
+ "\u24A9"=>"(n)",
+ "\u24AA"=>"(o)",
+ "\u24AB"=>"(p)",
+ "\u24AC"=>"(q)",
+ "\u24AD"=>"(r)",
+ "\u24AE"=>"(s)",
+ "\u24AF"=>"(t)",
+ "\u24B0"=>"(u)",
+ "\u24B1"=>"(v)",
+ "\u24B2"=>"(w)",
+ "\u24B3"=>"(x)",
+ "\u24B4"=>"(y)",
+ "\u24B5"=>"(z)",
+ "\u24B6"=>"A",
+ "\u24B7"=>"B",
+ "\u24B8"=>"C",
+ "\u24B9"=>"D",
+ "\u24BA"=>"E",
+ "\u24BB"=>"F",
+ "\u24BC"=>"G",
+ "\u24BD"=>"H",
+ "\u24BE"=>"I",
+ "\u24BF"=>"J",
+ "\u24C0"=>"K",
+ "\u24C1"=>"L",
+ "\u24C2"=>"M",
+ "\u24C3"=>"N",
+ "\u24C4"=>"O",
+ "\u24C5"=>"P",
+ "\u24C6"=>"Q",
+ "\u24C7"=>"R",
+ "\u24C8"=>"S",
+ "\u24C9"=>"T",
+ "\u24CA"=>"U",
+ "\u24CB"=>"V",
+ "\u24CC"=>"W",
+ "\u24CD"=>"X",
+ "\u24CE"=>"Y",
+ "\u24CF"=>"Z",
+ "\u24D0"=>"a",
+ "\u24D1"=>"b",
+ "\u24D2"=>"c",
+ "\u24D3"=>"d",
+ "\u24D4"=>"e",
+ "\u24D5"=>"f",
+ "\u24D6"=>"g",
+ "\u24D7"=>"h",
+ "\u24D8"=>"i",
+ "\u24D9"=>"j",
+ "\u24DA"=>"k",
+ "\u24DB"=>"l",
+ "\u24DC"=>"m",
+ "\u24DD"=>"n",
+ "\u24DE"=>"o",
+ "\u24DF"=>"p",
+ "\u24E0"=>"q",
+ "\u24E1"=>"r",
+ "\u24E2"=>"s",
+ "\u24E3"=>"t",
+ "\u24E4"=>"u",
+ "\u24E5"=>"v",
+ "\u24E6"=>"w",
+ "\u24E7"=>"x",
+ "\u24E8"=>"y",
+ "\u24E9"=>"z",
+ "\u24EA"=>"0",
+ "\u2A0C"=>"\u222B\u222B\u222B\u222B",
+ "\u2A74"=>"::=",
+ "\u2A75"=>"==",
+ "\u2A76"=>"===",
+ "\u2C7C"=>"j",
+ "\u2C7D"=>"V",
+ "\u2D6F"=>"\u2D61",
+ "\u2E9F"=>"\u6BCD",
+ "\u2EF3"=>"\u9F9F",
+ "\u2F00"=>"\u4E00",
+ "\u2F01"=>"\u4E28",
+ "\u2F02"=>"\u4E36",
+ "\u2F03"=>"\u4E3F",
+ "\u2F04"=>"\u4E59",
+ "\u2F05"=>"\u4E85",
+ "\u2F06"=>"\u4E8C",
+ "\u2F07"=>"\u4EA0",
+ "\u2F08"=>"\u4EBA",
+ "\u2F09"=>"\u513F",
+ "\u2F0A"=>"\u5165",
+ "\u2F0B"=>"\u516B",
+ "\u2F0C"=>"\u5182",
+ "\u2F0D"=>"\u5196",
+ "\u2F0E"=>"\u51AB",
+ "\u2F0F"=>"\u51E0",
+ "\u2F10"=>"\u51F5",
+ "\u2F11"=>"\u5200",
+ "\u2F12"=>"\u529B",
+ "\u2F13"=>"\u52F9",
+ "\u2F14"=>"\u5315",
+ "\u2F15"=>"\u531A",
+ "\u2F16"=>"\u5338",
+ "\u2F17"=>"\u5341",
+ "\u2F18"=>"\u535C",
+ "\u2F19"=>"\u5369",
+ "\u2F1A"=>"\u5382",
+ "\u2F1B"=>"\u53B6",
+ "\u2F1C"=>"\u53C8",
+ "\u2F1D"=>"\u53E3",
+ "\u2F1E"=>"\u56D7",
+ "\u2F1F"=>"\u571F",
+ "\u2F20"=>"\u58EB",
+ "\u2F21"=>"\u5902",
+ "\u2F22"=>"\u590A",
+ "\u2F23"=>"\u5915",
+ "\u2F24"=>"\u5927",
+ "\u2F25"=>"\u5973",
+ "\u2F26"=>"\u5B50",
+ "\u2F27"=>"\u5B80",
+ "\u2F28"=>"\u5BF8",
+ "\u2F29"=>"\u5C0F",
+ "\u2F2A"=>"\u5C22",
+ "\u2F2B"=>"\u5C38",
+ "\u2F2C"=>"\u5C6E",
+ "\u2F2D"=>"\u5C71",
+ "\u2F2E"=>"\u5DDB",
+ "\u2F2F"=>"\u5DE5",
+ "\u2F30"=>"\u5DF1",
+ "\u2F31"=>"\u5DFE",
+ "\u2F32"=>"\u5E72",
+ "\u2F33"=>"\u5E7A",
+ "\u2F34"=>"\u5E7F",
+ "\u2F35"=>"\u5EF4",
+ "\u2F36"=>"\u5EFE",
+ "\u2F37"=>"\u5F0B",
+ "\u2F38"=>"\u5F13",
+ "\u2F39"=>"\u5F50",
+ "\u2F3A"=>"\u5F61",
+ "\u2F3B"=>"\u5F73",
+ "\u2F3C"=>"\u5FC3",
+ "\u2F3D"=>"\u6208",
+ "\u2F3E"=>"\u6236",
+ "\u2F3F"=>"\u624B",
+ "\u2F40"=>"\u652F",
+ "\u2F41"=>"\u6534",
+ "\u2F42"=>"\u6587",
+ "\u2F43"=>"\u6597",
+ "\u2F44"=>"\u65A4",
+ "\u2F45"=>"\u65B9",
+ "\u2F46"=>"\u65E0",
+ "\u2F47"=>"\u65E5",
+ "\u2F48"=>"\u66F0",
+ "\u2F49"=>"\u6708",
+ "\u2F4A"=>"\u6728",
+ "\u2F4B"=>"\u6B20",
+ "\u2F4C"=>"\u6B62",
+ "\u2F4D"=>"\u6B79",
+ "\u2F4E"=>"\u6BB3",
+ "\u2F4F"=>"\u6BCB",
+ "\u2F50"=>"\u6BD4",
+ "\u2F51"=>"\u6BDB",
+ "\u2F52"=>"\u6C0F",
+ "\u2F53"=>"\u6C14",
+ "\u2F54"=>"\u6C34",
+ "\u2F55"=>"\u706B",
+ "\u2F56"=>"\u722A",
+ "\u2F57"=>"\u7236",
+ "\u2F58"=>"\u723B",
+ "\u2F59"=>"\u723F",
+ "\u2F5A"=>"\u7247",
+ "\u2F5B"=>"\u7259",
+ "\u2F5C"=>"\u725B",
+ "\u2F5D"=>"\u72AC",
+ "\u2F5E"=>"\u7384",
+ "\u2F5F"=>"\u7389",
+ "\u2F60"=>"\u74DC",
+ "\u2F61"=>"\u74E6",
+ "\u2F62"=>"\u7518",
+ "\u2F63"=>"\u751F",
+ "\u2F64"=>"\u7528",
+ "\u2F65"=>"\u7530",
+ "\u2F66"=>"\u758B",
+ "\u2F67"=>"\u7592",
+ "\u2F68"=>"\u7676",
+ "\u2F69"=>"\u767D",
+ "\u2F6A"=>"\u76AE",
+ "\u2F6B"=>"\u76BF",
+ "\u2F6C"=>"\u76EE",
+ "\u2F6D"=>"\u77DB",
+ "\u2F6E"=>"\u77E2",
+ "\u2F6F"=>"\u77F3",
+ "\u2F70"=>"\u793A",
+ "\u2F71"=>"\u79B8",
+ "\u2F72"=>"\u79BE",
+ "\u2F73"=>"\u7A74",
+ "\u2F74"=>"\u7ACB",
+ "\u2F75"=>"\u7AF9",
+ "\u2F76"=>"\u7C73",
+ "\u2F77"=>"\u7CF8",
+ "\u2F78"=>"\u7F36",
+ "\u2F79"=>"\u7F51",
+ "\u2F7A"=>"\u7F8A",
+ "\u2F7B"=>"\u7FBD",
+ "\u2F7C"=>"\u8001",
+ "\u2F7D"=>"\u800C",
+ "\u2F7E"=>"\u8012",
+ "\u2F7F"=>"\u8033",
+ "\u2F80"=>"\u807F",
+ "\u2F81"=>"\u8089",
+ "\u2F82"=>"\u81E3",
+ "\u2F83"=>"\u81EA",
+ "\u2F84"=>"\u81F3",
+ "\u2F85"=>"\u81FC",
+ "\u2F86"=>"\u820C",
+ "\u2F87"=>"\u821B",
+ "\u2F88"=>"\u821F",
+ "\u2F89"=>"\u826E",
+ "\u2F8A"=>"\u8272",
+ "\u2F8B"=>"\u8278",
+ "\u2F8C"=>"\u864D",
+ "\u2F8D"=>"\u866B",
+ "\u2F8E"=>"\u8840",
+ "\u2F8F"=>"\u884C",
+ "\u2F90"=>"\u8863",
+ "\u2F91"=>"\u897E",
+ "\u2F92"=>"\u898B",
+ "\u2F93"=>"\u89D2",
+ "\u2F94"=>"\u8A00",
+ "\u2F95"=>"\u8C37",
+ "\u2F96"=>"\u8C46",
+ "\u2F97"=>"\u8C55",
+ "\u2F98"=>"\u8C78",
+ "\u2F99"=>"\u8C9D",
+ "\u2F9A"=>"\u8D64",
+ "\u2F9B"=>"\u8D70",
+ "\u2F9C"=>"\u8DB3",
+ "\u2F9D"=>"\u8EAB",
+ "\u2F9E"=>"\u8ECA",
+ "\u2F9F"=>"\u8F9B",
+ "\u2FA0"=>"\u8FB0",
+ "\u2FA1"=>"\u8FB5",
+ "\u2FA2"=>"\u9091",
+ "\u2FA3"=>"\u9149",
+ "\u2FA4"=>"\u91C6",
+ "\u2FA5"=>"\u91CC",
+ "\u2FA6"=>"\u91D1",
+ "\u2FA7"=>"\u9577",
+ "\u2FA8"=>"\u9580",
+ "\u2FA9"=>"\u961C",
+ "\u2FAA"=>"\u96B6",
+ "\u2FAB"=>"\u96B9",
+ "\u2FAC"=>"\u96E8",
+ "\u2FAD"=>"\u9751",
+ "\u2FAE"=>"\u975E",
+ "\u2FAF"=>"\u9762",
+ "\u2FB0"=>"\u9769",
+ "\u2FB1"=>"\u97CB",
+ "\u2FB2"=>"\u97ED",
+ "\u2FB3"=>"\u97F3",
+ "\u2FB4"=>"\u9801",
+ "\u2FB5"=>"\u98A8",
+ "\u2FB6"=>"\u98DB",
+ "\u2FB7"=>"\u98DF",
+ "\u2FB8"=>"\u9996",
+ "\u2FB9"=>"\u9999",
+ "\u2FBA"=>"\u99AC",
+ "\u2FBB"=>"\u9AA8",
+ "\u2FBC"=>"\u9AD8",
+ "\u2FBD"=>"\u9ADF",
+ "\u2FBE"=>"\u9B25",
+ "\u2FBF"=>"\u9B2F",
+ "\u2FC0"=>"\u9B32",
+ "\u2FC1"=>"\u9B3C",
+ "\u2FC2"=>"\u9B5A",
+ "\u2FC3"=>"\u9CE5",
+ "\u2FC4"=>"\u9E75",
+ "\u2FC5"=>"\u9E7F",
+ "\u2FC6"=>"\u9EA5",
+ "\u2FC7"=>"\u9EBB",
+ "\u2FC8"=>"\u9EC3",
+ "\u2FC9"=>"\u9ECD",
+ "\u2FCA"=>"\u9ED1",
+ "\u2FCB"=>"\u9EF9",
+ "\u2FCC"=>"\u9EFD",
+ "\u2FCD"=>"\u9F0E",
+ "\u2FCE"=>"\u9F13",
+ "\u2FCF"=>"\u9F20",
+ "\u2FD0"=>"\u9F3B",
+ "\u2FD1"=>"\u9F4A",
+ "\u2FD2"=>"\u9F52",
+ "\u2FD3"=>"\u9F8D",
+ "\u2FD4"=>"\u9F9C",
+ "\u2FD5"=>"\u9FA0",
+ "\u3000"=>" ",
+ "\u3036"=>"\u3012",
+ "\u3038"=>"\u5341",
+ "\u3039"=>"\u5344",
+ "\u303A"=>"\u5345",
+ "\u309B"=>" \u3099",
+ "\u309C"=>" \u309A",
+ "\u309F"=>"\u3088\u308A",
+ "\u30FF"=>"\u30B3\u30C8",
+ "\u3131"=>"\u1100",
+ "\u3132"=>"\u1101",
+ "\u3133"=>"\u11AA",
+ "\u3134"=>"\u1102",
+ "\u3135"=>"\u11AC",
+ "\u3136"=>"\u11AD",
+ "\u3137"=>"\u1103",
+ "\u3138"=>"\u1104",
+ "\u3139"=>"\u1105",
+ "\u313A"=>"\u11B0",
+ "\u313B"=>"\u11B1",
+ "\u313C"=>"\u11B2",
+ "\u313D"=>"\u11B3",
+ "\u313E"=>"\u11B4",
+ "\u313F"=>"\u11B5",
+ "\u3140"=>"\u111A",
+ "\u3141"=>"\u1106",
+ "\u3142"=>"\u1107",
+ "\u3143"=>"\u1108",
+ "\u3144"=>"\u1121",
+ "\u3145"=>"\u1109",
+ "\u3146"=>"\u110A",
+ "\u3147"=>"\u110B",
+ "\u3148"=>"\u110C",
+ "\u3149"=>"\u110D",
+ "\u314A"=>"\u110E",
+ "\u314B"=>"\u110F",
+ "\u314C"=>"\u1110",
+ "\u314D"=>"\u1111",
+ "\u314E"=>"\u1112",
+ "\u314F"=>"\u1161",
+ "\u3150"=>"\u1162",
+ "\u3151"=>"\u1163",
+ "\u3152"=>"\u1164",
+ "\u3153"=>"\u1165",
+ "\u3154"=>"\u1166",
+ "\u3155"=>"\u1167",
+ "\u3156"=>"\u1168",
+ "\u3157"=>"\u1169",
+ "\u3158"=>"\u116A",
+ "\u3159"=>"\u116B",
+ "\u315A"=>"\u116C",
+ "\u315B"=>"\u116D",
+ "\u315C"=>"\u116E",
+ "\u315D"=>"\u116F",
+ "\u315E"=>"\u1170",
+ "\u315F"=>"\u1171",
+ "\u3160"=>"\u1172",
+ "\u3161"=>"\u1173",
+ "\u3162"=>"\u1174",
+ "\u3163"=>"\u1175",
+ "\u3164"=>"\u1160",
+ "\u3165"=>"\u1114",
+ "\u3166"=>"\u1115",
+ "\u3167"=>"\u11C7",
+ "\u3168"=>"\u11C8",
+ "\u3169"=>"\u11CC",
+ "\u316A"=>"\u11CE",
+ "\u316B"=>"\u11D3",
+ "\u316C"=>"\u11D7",
+ "\u316D"=>"\u11D9",
+ "\u316E"=>"\u111C",
+ "\u316F"=>"\u11DD",
+ "\u3170"=>"\u11DF",
+ "\u3171"=>"\u111D",
+ "\u3172"=>"\u111E",
+ "\u3173"=>"\u1120",
+ "\u3174"=>"\u1122",
+ "\u3175"=>"\u1123",
+ "\u3176"=>"\u1127",
+ "\u3177"=>"\u1129",
+ "\u3178"=>"\u112B",
+ "\u3179"=>"\u112C",
+ "\u317A"=>"\u112D",
+ "\u317B"=>"\u112E",
+ "\u317C"=>"\u112F",
+ "\u317D"=>"\u1132",
+ "\u317E"=>"\u1136",
+ "\u317F"=>"\u1140",
+ "\u3180"=>"\u1147",
+ "\u3181"=>"\u114C",
+ "\u3182"=>"\u11F1",
+ "\u3183"=>"\u11F2",
+ "\u3184"=>"\u1157",
+ "\u3185"=>"\u1158",
+ "\u3186"=>"\u1159",
+ "\u3187"=>"\u1184",
+ "\u3188"=>"\u1185",
+ "\u3189"=>"\u1188",
+ "\u318A"=>"\u1191",
+ "\u318B"=>"\u1192",
+ "\u318C"=>"\u1194",
+ "\u318D"=>"\u119E",
+ "\u318E"=>"\u11A1",
+ "\u3192"=>"\u4E00",
+ "\u3193"=>"\u4E8C",
+ "\u3194"=>"\u4E09",
+ "\u3195"=>"\u56DB",
+ "\u3196"=>"\u4E0A",
+ "\u3197"=>"\u4E2D",
+ "\u3198"=>"\u4E0B",
+ "\u3199"=>"\u7532",
+ "\u319A"=>"\u4E59",
+ "\u319B"=>"\u4E19",
+ "\u319C"=>"\u4E01",
+ "\u319D"=>"\u5929",
+ "\u319E"=>"\u5730",
+ "\u319F"=>"\u4EBA",
+ "\u3200"=>"(\u1100)",
+ "\u3201"=>"(\u1102)",
+ "\u3202"=>"(\u1103)",
+ "\u3203"=>"(\u1105)",
+ "\u3204"=>"(\u1106)",
+ "\u3205"=>"(\u1107)",
+ "\u3206"=>"(\u1109)",
+ "\u3207"=>"(\u110B)",
+ "\u3208"=>"(\u110C)",
+ "\u3209"=>"(\u110E)",
+ "\u320A"=>"(\u110F)",
+ "\u320B"=>"(\u1110)",
+ "\u320C"=>"(\u1111)",
+ "\u320D"=>"(\u1112)",
+ "\u320E"=>"(\u1100\u1161)",
+ "\u320F"=>"(\u1102\u1161)",
+ "\u3210"=>"(\u1103\u1161)",
+ "\u3211"=>"(\u1105\u1161)",
+ "\u3212"=>"(\u1106\u1161)",
+ "\u3213"=>"(\u1107\u1161)",
+ "\u3214"=>"(\u1109\u1161)",
+ "\u3215"=>"(\u110B\u1161)",
+ "\u3216"=>"(\u110C\u1161)",
+ "\u3217"=>"(\u110E\u1161)",
+ "\u3218"=>"(\u110F\u1161)",
+ "\u3219"=>"(\u1110\u1161)",
+ "\u321A"=>"(\u1111\u1161)",
+ "\u321B"=>"(\u1112\u1161)",
+ "\u321C"=>"(\u110C\u116E)",
+ "\u321D"=>"(\u110B\u1169\u110C\u1165\u11AB)",
+ "\u321E"=>"(\u110B\u1169\u1112\u116E)",
+ "\u3220"=>"(\u4E00)",
+ "\u3221"=>"(\u4E8C)",
+ "\u3222"=>"(\u4E09)",
+ "\u3223"=>"(\u56DB)",
+ "\u3224"=>"(\u4E94)",
+ "\u3225"=>"(\u516D)",
+ "\u3226"=>"(\u4E03)",
+ "\u3227"=>"(\u516B)",
+ "\u3228"=>"(\u4E5D)",
+ "\u3229"=>"(\u5341)",
+ "\u322A"=>"(\u6708)",
+ "\u322B"=>"(\u706B)",
+ "\u322C"=>"(\u6C34)",
+ "\u322D"=>"(\u6728)",
+ "\u322E"=>"(\u91D1)",
+ "\u322F"=>"(\u571F)",
+ "\u3230"=>"(\u65E5)",
+ "\u3231"=>"(\u682A)",
+ "\u3232"=>"(\u6709)",
+ "\u3233"=>"(\u793E)",
+ "\u3234"=>"(\u540D)",
+ "\u3235"=>"(\u7279)",
+ "\u3236"=>"(\u8CA1)",
+ "\u3237"=>"(\u795D)",
+ "\u3238"=>"(\u52B4)",
+ "\u3239"=>"(\u4EE3)",
+ "\u323A"=>"(\u547C)",
+ "\u323B"=>"(\u5B66)",
+ "\u323C"=>"(\u76E3)",
+ "\u323D"=>"(\u4F01)",
+ "\u323E"=>"(\u8CC7)",
+ "\u323F"=>"(\u5354)",
+ "\u3240"=>"(\u796D)",
+ "\u3241"=>"(\u4F11)",
+ "\u3242"=>"(\u81EA)",
+ "\u3243"=>"(\u81F3)",
+ "\u3244"=>"\u554F",
+ "\u3245"=>"\u5E7C",
+ "\u3246"=>"\u6587",
+ "\u3247"=>"\u7B8F",
+ "\u3250"=>"PTE",
+ "\u3251"=>"21",
+ "\u3252"=>"22",
+ "\u3253"=>"23",
+ "\u3254"=>"24",
+ "\u3255"=>"25",
+ "\u3256"=>"26",
+ "\u3257"=>"27",
+ "\u3258"=>"28",
+ "\u3259"=>"29",
+ "\u325A"=>"30",
+ "\u325B"=>"31",
+ "\u325C"=>"32",
+ "\u325D"=>"33",
+ "\u325E"=>"34",
+ "\u325F"=>"35",
+ "\u3260"=>"\u1100",
+ "\u3261"=>"\u1102",
+ "\u3262"=>"\u1103",
+ "\u3263"=>"\u1105",
+ "\u3264"=>"\u1106",
+ "\u3265"=>"\u1107",
+ "\u3266"=>"\u1109",
+ "\u3267"=>"\u110B",
+ "\u3268"=>"\u110C",
+ "\u3269"=>"\u110E",
+ "\u326A"=>"\u110F",
+ "\u326B"=>"\u1110",
+ "\u326C"=>"\u1111",
+ "\u326D"=>"\u1112",
+ "\u326E"=>"\u1100\u1161",
+ "\u326F"=>"\u1102\u1161",
+ "\u3270"=>"\u1103\u1161",
+ "\u3271"=>"\u1105\u1161",
+ "\u3272"=>"\u1106\u1161",
+ "\u3273"=>"\u1107\u1161",
+ "\u3274"=>"\u1109\u1161",
+ "\u3275"=>"\u110B\u1161",
+ "\u3276"=>"\u110C\u1161",
+ "\u3277"=>"\u110E\u1161",
+ "\u3278"=>"\u110F\u1161",
+ "\u3279"=>"\u1110\u1161",
+ "\u327A"=>"\u1111\u1161",
+ "\u327B"=>"\u1112\u1161",
+ "\u327C"=>"\u110E\u1161\u11B7\u1100\u1169",
+ "\u327D"=>"\u110C\u116E\u110B\u1174",
+ "\u327E"=>"\u110B\u116E",
+ "\u3280"=>"\u4E00",
+ "\u3281"=>"\u4E8C",
+ "\u3282"=>"\u4E09",
+ "\u3283"=>"\u56DB",
+ "\u3284"=>"\u4E94",
+ "\u3285"=>"\u516D",
+ "\u3286"=>"\u4E03",
+ "\u3287"=>"\u516B",
+ "\u3288"=>"\u4E5D",
+ "\u3289"=>"\u5341",
+ "\u328A"=>"\u6708",
+ "\u328B"=>"\u706B",
+ "\u328C"=>"\u6C34",
+ "\u328D"=>"\u6728",
+ "\u328E"=>"\u91D1",
+ "\u328F"=>"\u571F",
+ "\u3290"=>"\u65E5",
+ "\u3291"=>"\u682A",
+ "\u3292"=>"\u6709",
+ "\u3293"=>"\u793E",
+ "\u3294"=>"\u540D",
+ "\u3295"=>"\u7279",
+ "\u3296"=>"\u8CA1",
+ "\u3297"=>"\u795D",
+ "\u3298"=>"\u52B4",
+ "\u3299"=>"\u79D8",
+ "\u329A"=>"\u7537",
+ "\u329B"=>"\u5973",
+ "\u329C"=>"\u9069",
+ "\u329D"=>"\u512A",
+ "\u329E"=>"\u5370",
+ "\u329F"=>"\u6CE8",
+ "\u32A0"=>"\u9805",
+ "\u32A1"=>"\u4F11",
+ "\u32A2"=>"\u5199",
+ "\u32A3"=>"\u6B63",
+ "\u32A4"=>"\u4E0A",
+ "\u32A5"=>"\u4E2D",
+ "\u32A6"=>"\u4E0B",
+ "\u32A7"=>"\u5DE6",
+ "\u32A8"=>"\u53F3",
+ "\u32A9"=>"\u533B",
+ "\u32AA"=>"\u5B97",
+ "\u32AB"=>"\u5B66",
+ "\u32AC"=>"\u76E3",
+ "\u32AD"=>"\u4F01",
+ "\u32AE"=>"\u8CC7",
+ "\u32AF"=>"\u5354",
+ "\u32B0"=>"\u591C",
+ "\u32B1"=>"36",
+ "\u32B2"=>"37",
+ "\u32B3"=>"38",
+ "\u32B4"=>"39",
+ "\u32B5"=>"40",
+ "\u32B6"=>"41",
+ "\u32B7"=>"42",
+ "\u32B8"=>"43",
+ "\u32B9"=>"44",
+ "\u32BA"=>"45",
+ "\u32BB"=>"46",
+ "\u32BC"=>"47",
+ "\u32BD"=>"48",
+ "\u32BE"=>"49",
+ "\u32BF"=>"50",
+ "\u32C0"=>"1\u6708",
+ "\u32C1"=>"2\u6708",
+ "\u32C2"=>"3\u6708",
+ "\u32C3"=>"4\u6708",
+ "\u32C4"=>"5\u6708",
+ "\u32C5"=>"6\u6708",
+ "\u32C6"=>"7\u6708",
+ "\u32C7"=>"8\u6708",
+ "\u32C8"=>"9\u6708",
+ "\u32C9"=>"10\u6708",
+ "\u32CA"=>"11\u6708",
+ "\u32CB"=>"12\u6708",
+ "\u32CC"=>"Hg",
+ "\u32CD"=>"erg",
+ "\u32CE"=>"eV",
+ "\u32CF"=>"LTD",
+ "\u32D0"=>"\u30A2",
+ "\u32D1"=>"\u30A4",
+ "\u32D2"=>"\u30A6",
+ "\u32D3"=>"\u30A8",
+ "\u32D4"=>"\u30AA",
+ "\u32D5"=>"\u30AB",
+ "\u32D6"=>"\u30AD",
+ "\u32D7"=>"\u30AF",
+ "\u32D8"=>"\u30B1",
+ "\u32D9"=>"\u30B3",
+ "\u32DA"=>"\u30B5",
+ "\u32DB"=>"\u30B7",
+ "\u32DC"=>"\u30B9",
+ "\u32DD"=>"\u30BB",
+ "\u32DE"=>"\u30BD",
+ "\u32DF"=>"\u30BF",
+ "\u32E0"=>"\u30C1",
+ "\u32E1"=>"\u30C4",
+ "\u32E2"=>"\u30C6",
+ "\u32E3"=>"\u30C8",
+ "\u32E4"=>"\u30CA",
+ "\u32E5"=>"\u30CB",
+ "\u32E6"=>"\u30CC",
+ "\u32E7"=>"\u30CD",
+ "\u32E8"=>"\u30CE",
+ "\u32E9"=>"\u30CF",
+ "\u32EA"=>"\u30D2",
+ "\u32EB"=>"\u30D5",
+ "\u32EC"=>"\u30D8",
+ "\u32ED"=>"\u30DB",
+ "\u32EE"=>"\u30DE",
+ "\u32EF"=>"\u30DF",
+ "\u32F0"=>"\u30E0",
+ "\u32F1"=>"\u30E1",
+ "\u32F2"=>"\u30E2",
+ "\u32F3"=>"\u30E4",
+ "\u32F4"=>"\u30E6",
+ "\u32F5"=>"\u30E8",
+ "\u32F6"=>"\u30E9",
+ "\u32F7"=>"\u30EA",
+ "\u32F8"=>"\u30EB",
+ "\u32F9"=>"\u30EC",
+ "\u32FA"=>"\u30ED",
+ "\u32FB"=>"\u30EF",
+ "\u32FC"=>"\u30F0",
+ "\u32FD"=>"\u30F1",
+ "\u32FE"=>"\u30F2",
+ "\u32FF"=>"\u4EE4\u548C",
+ "\u3300"=>"\u30A2\u30D1\u30FC\u30C8",
+ "\u3301"=>"\u30A2\u30EB\u30D5\u30A1",
+ "\u3302"=>"\u30A2\u30F3\u30DA\u30A2",
+ "\u3303"=>"\u30A2\u30FC\u30EB",
+ "\u3304"=>"\u30A4\u30CB\u30F3\u30B0",
+ "\u3305"=>"\u30A4\u30F3\u30C1",
+ "\u3306"=>"\u30A6\u30A9\u30F3",
+ "\u3307"=>"\u30A8\u30B9\u30AF\u30FC\u30C9",
+ "\u3308"=>"\u30A8\u30FC\u30AB\u30FC",
+ "\u3309"=>"\u30AA\u30F3\u30B9",
+ "\u330A"=>"\u30AA\u30FC\u30E0",
+ "\u330B"=>"\u30AB\u30A4\u30EA",
+ "\u330C"=>"\u30AB\u30E9\u30C3\u30C8",
+ "\u330D"=>"\u30AB\u30ED\u30EA\u30FC",
+ "\u330E"=>"\u30AC\u30ED\u30F3",
+ "\u330F"=>"\u30AC\u30F3\u30DE",
+ "\u3310"=>"\u30AE\u30AC",
+ "\u3311"=>"\u30AE\u30CB\u30FC",
+ "\u3312"=>"\u30AD\u30E5\u30EA\u30FC",
+ "\u3313"=>"\u30AE\u30EB\u30C0\u30FC",
+ "\u3314"=>"\u30AD\u30ED",
+ "\u3315"=>"\u30AD\u30ED\u30B0\u30E9\u30E0",
+ "\u3316"=>"\u30AD\u30ED\u30E1\u30FC\u30C8\u30EB",
+ "\u3317"=>"\u30AD\u30ED\u30EF\u30C3\u30C8",
+ "\u3318"=>"\u30B0\u30E9\u30E0",
+ "\u3319"=>"\u30B0\u30E9\u30E0\u30C8\u30F3",
+ "\u331A"=>"\u30AF\u30EB\u30BC\u30A4\u30ED",
+ "\u331B"=>"\u30AF\u30ED\u30FC\u30CD",
+ "\u331C"=>"\u30B1\u30FC\u30B9",
+ "\u331D"=>"\u30B3\u30EB\u30CA",
+ "\u331E"=>"\u30B3\u30FC\u30DD",
+ "\u331F"=>"\u30B5\u30A4\u30AF\u30EB",
+ "\u3320"=>"\u30B5\u30F3\u30C1\u30FC\u30E0",
+ "\u3321"=>"\u30B7\u30EA\u30F3\u30B0",
+ "\u3322"=>"\u30BB\u30F3\u30C1",
+ "\u3323"=>"\u30BB\u30F3\u30C8",
+ "\u3324"=>"\u30C0\u30FC\u30B9",
+ "\u3325"=>"\u30C7\u30B7",
+ "\u3326"=>"\u30C9\u30EB",
+ "\u3327"=>"\u30C8\u30F3",
+ "\u3328"=>"\u30CA\u30CE",
+ "\u3329"=>"\u30CE\u30C3\u30C8",
+ "\u332A"=>"\u30CF\u30A4\u30C4",
+ "\u332B"=>"\u30D1\u30FC\u30BB\u30F3\u30C8",
+ "\u332C"=>"\u30D1\u30FC\u30C4",
+ "\u332D"=>"\u30D0\u30FC\u30EC\u30EB",
+ "\u332E"=>"\u30D4\u30A2\u30B9\u30C8\u30EB",
+ "\u332F"=>"\u30D4\u30AF\u30EB",
+ "\u3330"=>"\u30D4\u30B3",
+ "\u3331"=>"\u30D3\u30EB",
+ "\u3332"=>"\u30D5\u30A1\u30E9\u30C3\u30C9",
+ "\u3333"=>"\u30D5\u30A3\u30FC\u30C8",
+ "\u3334"=>"\u30D6\u30C3\u30B7\u30A7\u30EB",
+ "\u3335"=>"\u30D5\u30E9\u30F3",
+ "\u3336"=>"\u30D8\u30AF\u30BF\u30FC\u30EB",
+ "\u3337"=>"\u30DA\u30BD",
+ "\u3338"=>"\u30DA\u30CB\u30D2",
+ "\u3339"=>"\u30D8\u30EB\u30C4",
+ "\u333A"=>"\u30DA\u30F3\u30B9",
+ "\u333B"=>"\u30DA\u30FC\u30B8",
+ "\u333C"=>"\u30D9\u30FC\u30BF",
+ "\u333D"=>"\u30DD\u30A4\u30F3\u30C8",
+ "\u333E"=>"\u30DC\u30EB\u30C8",
+ "\u333F"=>"\u30DB\u30F3",
+ "\u3340"=>"\u30DD\u30F3\u30C9",
+ "\u3341"=>"\u30DB\u30FC\u30EB",
+ "\u3342"=>"\u30DB\u30FC\u30F3",
+ "\u3343"=>"\u30DE\u30A4\u30AF\u30ED",
+ "\u3344"=>"\u30DE\u30A4\u30EB",
+ "\u3345"=>"\u30DE\u30C3\u30CF",
+ "\u3346"=>"\u30DE\u30EB\u30AF",
+ "\u3347"=>"\u30DE\u30F3\u30B7\u30E7\u30F3",
+ "\u3348"=>"\u30DF\u30AF\u30ED\u30F3",
+ "\u3349"=>"\u30DF\u30EA",
+ "\u334A"=>"\u30DF\u30EA\u30D0\u30FC\u30EB",
+ "\u334B"=>"\u30E1\u30AC",
+ "\u334C"=>"\u30E1\u30AC\u30C8\u30F3",
+ "\u334D"=>"\u30E1\u30FC\u30C8\u30EB",
+ "\u334E"=>"\u30E4\u30FC\u30C9",
+ "\u334F"=>"\u30E4\u30FC\u30EB",
+ "\u3350"=>"\u30E6\u30A2\u30F3",
+ "\u3351"=>"\u30EA\u30C3\u30C8\u30EB",
+ "\u3352"=>"\u30EA\u30E9",
+ "\u3353"=>"\u30EB\u30D4\u30FC",
+ "\u3354"=>"\u30EB\u30FC\u30D6\u30EB",
+ "\u3355"=>"\u30EC\u30E0",
+ "\u3356"=>"\u30EC\u30F3\u30C8\u30B2\u30F3",
+ "\u3357"=>"\u30EF\u30C3\u30C8",
+ "\u3358"=>"0\u70B9",
+ "\u3359"=>"1\u70B9",
+ "\u335A"=>"2\u70B9",
+ "\u335B"=>"3\u70B9",
+ "\u335C"=>"4\u70B9",
+ "\u335D"=>"5\u70B9",
+ "\u335E"=>"6\u70B9",
+ "\u335F"=>"7\u70B9",
+ "\u3360"=>"8\u70B9",
+ "\u3361"=>"9\u70B9",
+ "\u3362"=>"10\u70B9",
+ "\u3363"=>"11\u70B9",
+ "\u3364"=>"12\u70B9",
+ "\u3365"=>"13\u70B9",
+ "\u3366"=>"14\u70B9",
+ "\u3367"=>"15\u70B9",
+ "\u3368"=>"16\u70B9",
+ "\u3369"=>"17\u70B9",
+ "\u336A"=>"18\u70B9",
+ "\u336B"=>"19\u70B9",
+ "\u336C"=>"20\u70B9",
+ "\u336D"=>"21\u70B9",
+ "\u336E"=>"22\u70B9",
+ "\u336F"=>"23\u70B9",
+ "\u3370"=>"24\u70B9",
+ "\u3371"=>"hPa",
+ "\u3372"=>"da",
+ "\u3373"=>"AU",
+ "\u3374"=>"bar",
+ "\u3375"=>"oV",
+ "\u3376"=>"pc",
+ "\u3377"=>"dm",
+ "\u3378"=>"dm2",
+ "\u3379"=>"dm3",
+ "\u337A"=>"IU",
+ "\u337B"=>"\u5E73\u6210",
+ "\u337C"=>"\u662D\u548C",
+ "\u337D"=>"\u5927\u6B63",
+ "\u337E"=>"\u660E\u6CBB",
+ "\u337F"=>"\u682A\u5F0F\u4F1A\u793E",
+ "\u3380"=>"pA",
+ "\u3381"=>"nA",
+ "\u3382"=>"\u03BCA",
+ "\u3383"=>"mA",
+ "\u3384"=>"kA",
+ "\u3385"=>"KB",
+ "\u3386"=>"MB",
+ "\u3387"=>"GB",
+ "\u3388"=>"cal",
+ "\u3389"=>"kcal",
+ "\u338A"=>"pF",
+ "\u338B"=>"nF",
+ "\u338C"=>"\u03BCF",
+ "\u338D"=>"\u03BCg",
+ "\u338E"=>"mg",
+ "\u338F"=>"kg",
+ "\u3390"=>"Hz",
+ "\u3391"=>"kHz",
+ "\u3392"=>"MHz",
+ "\u3393"=>"GHz",
+ "\u3394"=>"THz",
+ "\u3395"=>"\u03BCl",
+ "\u3396"=>"ml",
+ "\u3397"=>"dl",
+ "\u3398"=>"kl",
+ "\u3399"=>"fm",
+ "\u339A"=>"nm",
+ "\u339B"=>"\u03BCm",
+ "\u339C"=>"mm",
+ "\u339D"=>"cm",
+ "\u339E"=>"km",
+ "\u339F"=>"mm2",
+ "\u33A0"=>"cm2",
+ "\u33A1"=>"m2",
+ "\u33A2"=>"km2",
+ "\u33A3"=>"mm3",
+ "\u33A4"=>"cm3",
+ "\u33A5"=>"m3",
+ "\u33A6"=>"km3",
+ "\u33A7"=>"m\u2215s",
+ "\u33A8"=>"m\u2215s2",
+ "\u33A9"=>"Pa",
+ "\u33AA"=>"kPa",
+ "\u33AB"=>"MPa",
+ "\u33AC"=>"GPa",
+ "\u33AD"=>"rad",
+ "\u33AE"=>"rad\u2215s",
+ "\u33AF"=>"rad\u2215s2",
+ "\u33B0"=>"ps",
+ "\u33B1"=>"ns",
+ "\u33B2"=>"\u03BCs",
+ "\u33B3"=>"ms",
+ "\u33B4"=>"pV",
+ "\u33B5"=>"nV",
+ "\u33B6"=>"\u03BCV",
+ "\u33B7"=>"mV",
+ "\u33B8"=>"kV",
+ "\u33B9"=>"MV",
+ "\u33BA"=>"pW",
+ "\u33BB"=>"nW",
+ "\u33BC"=>"\u03BCW",
+ "\u33BD"=>"mW",
+ "\u33BE"=>"kW",
+ "\u33BF"=>"MW",
+ "\u33C0"=>"k\u03A9",
+ "\u33C1"=>"M\u03A9",
+ "\u33C2"=>"a.m.",
+ "\u33C3"=>"Bq",
+ "\u33C4"=>"cc",
+ "\u33C5"=>"cd",
+ "\u33C6"=>"C\u2215kg",
+ "\u33C7"=>"Co.",
+ "\u33C8"=>"dB",
+ "\u33C9"=>"Gy",
+ "\u33CA"=>"ha",
+ "\u33CB"=>"HP",
+ "\u33CC"=>"in",
+ "\u33CD"=>"KK",
+ "\u33CE"=>"KM",
+ "\u33CF"=>"kt",
+ "\u33D0"=>"lm",
+ "\u33D1"=>"ln",
+ "\u33D2"=>"log",
+ "\u33D3"=>"lx",
+ "\u33D4"=>"mb",
+ "\u33D5"=>"mil",
+ "\u33D6"=>"mol",
+ "\u33D7"=>"PH",
+ "\u33D8"=>"p.m.",
+ "\u33D9"=>"PPM",
+ "\u33DA"=>"PR",
+ "\u33DB"=>"sr",
+ "\u33DC"=>"Sv",
+ "\u33DD"=>"Wb",
+ "\u33DE"=>"V\u2215m",
+ "\u33DF"=>"A\u2215m",
+ "\u33E0"=>"1\u65E5",
+ "\u33E1"=>"2\u65E5",
+ "\u33E2"=>"3\u65E5",
+ "\u33E3"=>"4\u65E5",
+ "\u33E4"=>"5\u65E5",
+ "\u33E5"=>"6\u65E5",
+ "\u33E6"=>"7\u65E5",
+ "\u33E7"=>"8\u65E5",
+ "\u33E8"=>"9\u65E5",
+ "\u33E9"=>"10\u65E5",
+ "\u33EA"=>"11\u65E5",
+ "\u33EB"=>"12\u65E5",
+ "\u33EC"=>"13\u65E5",
+ "\u33ED"=>"14\u65E5",
+ "\u33EE"=>"15\u65E5",
+ "\u33EF"=>"16\u65E5",
+ "\u33F0"=>"17\u65E5",
+ "\u33F1"=>"18\u65E5",
+ "\u33F2"=>"19\u65E5",
+ "\u33F3"=>"20\u65E5",
+ "\u33F4"=>"21\u65E5",
+ "\u33F5"=>"22\u65E5",
+ "\u33F6"=>"23\u65E5",
+ "\u33F7"=>"24\u65E5",
+ "\u33F8"=>"25\u65E5",
+ "\u33F9"=>"26\u65E5",
+ "\u33FA"=>"27\u65E5",
+ "\u33FB"=>"28\u65E5",
+ "\u33FC"=>"29\u65E5",
+ "\u33FD"=>"30\u65E5",
+ "\u33FE"=>"31\u65E5",
+ "\u33FF"=>"gal",
+ "\uA69C"=>"\u044A",
+ "\uA69D"=>"\u044C",
+ "\uA770"=>"\uA76F",
+ "\uA7F8"=>"\u0126",
+ "\uA7F9"=>"\u0153",
+ "\uAB5C"=>"\uA727",
+ "\uAB5D"=>"\uAB37",
+ "\uAB5E"=>"\u026B",
+ "\uAB5F"=>"\uAB52",
+ "\uFB00"=>"ff",
+ "\uFB01"=>"fi",
+ "\uFB02"=>"fl",
+ "\uFB03"=>"ffi",
+ "\uFB04"=>"ffl",
+ "\uFB05"=>"st",
+ "\uFB06"=>"st",
+ "\uFB13"=>"\u0574\u0576",
+ "\uFB14"=>"\u0574\u0565",
+ "\uFB15"=>"\u0574\u056B",
+ "\uFB16"=>"\u057E\u0576",
+ "\uFB17"=>"\u0574\u056D",
+ "\uFB20"=>"\u05E2",
+ "\uFB21"=>"\u05D0",
+ "\uFB22"=>"\u05D3",
+ "\uFB23"=>"\u05D4",
+ "\uFB24"=>"\u05DB",
+ "\uFB25"=>"\u05DC",
+ "\uFB26"=>"\u05DD",
+ "\uFB27"=>"\u05E8",
+ "\uFB28"=>"\u05EA",
+ "\uFB29"=>"+",
+ "\uFB4F"=>"\u05D0\u05DC",
+ "\uFB50"=>"\u0671",
+ "\uFB51"=>"\u0671",
+ "\uFB52"=>"\u067B",
+ "\uFB53"=>"\u067B",
+ "\uFB54"=>"\u067B",
+ "\uFB55"=>"\u067B",
+ "\uFB56"=>"\u067E",
+ "\uFB57"=>"\u067E",
+ "\uFB58"=>"\u067E",
+ "\uFB59"=>"\u067E",
+ "\uFB5A"=>"\u0680",
+ "\uFB5B"=>"\u0680",
+ "\uFB5C"=>"\u0680",
+ "\uFB5D"=>"\u0680",
+ "\uFB5E"=>"\u067A",
+ "\uFB5F"=>"\u067A",
+ "\uFB60"=>"\u067A",
+ "\uFB61"=>"\u067A",
+ "\uFB62"=>"\u067F",
+ "\uFB63"=>"\u067F",
+ "\uFB64"=>"\u067F",
+ "\uFB65"=>"\u067F",
+ "\uFB66"=>"\u0679",
+ "\uFB67"=>"\u0679",
+ "\uFB68"=>"\u0679",
+ "\uFB69"=>"\u0679",
+ "\uFB6A"=>"\u06A4",
+ "\uFB6B"=>"\u06A4",
+ "\uFB6C"=>"\u06A4",
+ "\uFB6D"=>"\u06A4",
+ "\uFB6E"=>"\u06A6",
+ "\uFB6F"=>"\u06A6",
+ "\uFB70"=>"\u06A6",
+ "\uFB71"=>"\u06A6",
+ "\uFB72"=>"\u0684",
+ "\uFB73"=>"\u0684",
+ "\uFB74"=>"\u0684",
+ "\uFB75"=>"\u0684",
+ "\uFB76"=>"\u0683",
+ "\uFB77"=>"\u0683",
+ "\uFB78"=>"\u0683",
+ "\uFB79"=>"\u0683",
+ "\uFB7A"=>"\u0686",
+ "\uFB7B"=>"\u0686",
+ "\uFB7C"=>"\u0686",
+ "\uFB7D"=>"\u0686",
+ "\uFB7E"=>"\u0687",
+ "\uFB7F"=>"\u0687",
+ "\uFB80"=>"\u0687",
+ "\uFB81"=>"\u0687",
+ "\uFB82"=>"\u068D",
+ "\uFB83"=>"\u068D",
+ "\uFB84"=>"\u068C",
+ "\uFB85"=>"\u068C",
+ "\uFB86"=>"\u068E",
+ "\uFB87"=>"\u068E",
+ "\uFB88"=>"\u0688",
+ "\uFB89"=>"\u0688",
+ "\uFB8A"=>"\u0698",
+ "\uFB8B"=>"\u0698",
+ "\uFB8C"=>"\u0691",
+ "\uFB8D"=>"\u0691",
+ "\uFB8E"=>"\u06A9",
+ "\uFB8F"=>"\u06A9",
+ "\uFB90"=>"\u06A9",
+ "\uFB91"=>"\u06A9",
+ "\uFB92"=>"\u06AF",
+ "\uFB93"=>"\u06AF",
+ "\uFB94"=>"\u06AF",
+ "\uFB95"=>"\u06AF",
+ "\uFB96"=>"\u06B3",
+ "\uFB97"=>"\u06B3",
+ "\uFB98"=>"\u06B3",
+ "\uFB99"=>"\u06B3",
+ "\uFB9A"=>"\u06B1",
+ "\uFB9B"=>"\u06B1",
+ "\uFB9C"=>"\u06B1",
+ "\uFB9D"=>"\u06B1",
+ "\uFB9E"=>"\u06BA",
+ "\uFB9F"=>"\u06BA",
+ "\uFBA0"=>"\u06BB",
+ "\uFBA1"=>"\u06BB",
+ "\uFBA2"=>"\u06BB",
+ "\uFBA3"=>"\u06BB",
+ "\uFBA4"=>"\u06C0",
+ "\uFBA5"=>"\u06C0",
+ "\uFBA6"=>"\u06C1",
+ "\uFBA7"=>"\u06C1",
+ "\uFBA8"=>"\u06C1",
+ "\uFBA9"=>"\u06C1",
+ "\uFBAA"=>"\u06BE",
+ "\uFBAB"=>"\u06BE",
+ "\uFBAC"=>"\u06BE",
+ "\uFBAD"=>"\u06BE",
+ "\uFBAE"=>"\u06D2",
+ "\uFBAF"=>"\u06D2",
+ "\uFBB0"=>"\u06D3",
+ "\uFBB1"=>"\u06D3",
+ "\uFBD3"=>"\u06AD",
+ "\uFBD4"=>"\u06AD",
+ "\uFBD5"=>"\u06AD",
+ "\uFBD6"=>"\u06AD",
+ "\uFBD7"=>"\u06C7",
+ "\uFBD8"=>"\u06C7",
+ "\uFBD9"=>"\u06C6",
+ "\uFBDA"=>"\u06C6",
+ "\uFBDB"=>"\u06C8",
+ "\uFBDC"=>"\u06C8",
+ "\uFBDD"=>"\u06C7\u0674",
+ "\uFBDE"=>"\u06CB",
+ "\uFBDF"=>"\u06CB",
+ "\uFBE0"=>"\u06C5",
+ "\uFBE1"=>"\u06C5",
+ "\uFBE2"=>"\u06C9",
+ "\uFBE3"=>"\u06C9",
+ "\uFBE4"=>"\u06D0",
+ "\uFBE5"=>"\u06D0",
+ "\uFBE6"=>"\u06D0",
+ "\uFBE7"=>"\u06D0",
+ "\uFBE8"=>"\u0649",
+ "\uFBE9"=>"\u0649",
+ "\uFBEA"=>"\u0626\u0627",
+ "\uFBEB"=>"\u0626\u0627",
+ "\uFBEC"=>"\u0626\u06D5",
+ "\uFBED"=>"\u0626\u06D5",
+ "\uFBEE"=>"\u0626\u0648",
+ "\uFBEF"=>"\u0626\u0648",
+ "\uFBF0"=>"\u0626\u06C7",
+ "\uFBF1"=>"\u0626\u06C7",
+ "\uFBF2"=>"\u0626\u06C6",
+ "\uFBF3"=>"\u0626\u06C6",
+ "\uFBF4"=>"\u0626\u06C8",
+ "\uFBF5"=>"\u0626\u06C8",
+ "\uFBF6"=>"\u0626\u06D0",
+ "\uFBF7"=>"\u0626\u06D0",
+ "\uFBF8"=>"\u0626\u06D0",
+ "\uFBF9"=>"\u0626\u0649",
+ "\uFBFA"=>"\u0626\u0649",
+ "\uFBFB"=>"\u0626\u0649",
+ "\uFBFC"=>"\u06CC",
+ "\uFBFD"=>"\u06CC",
+ "\uFBFE"=>"\u06CC",
+ "\uFBFF"=>"\u06CC",
+ "\uFC00"=>"\u0626\u062C",
+ "\uFC01"=>"\u0626\u062D",
+ "\uFC02"=>"\u0626\u0645",
+ "\uFC03"=>"\u0626\u0649",
+ "\uFC04"=>"\u0626\u064A",
+ "\uFC05"=>"\u0628\u062C",
+ "\uFC06"=>"\u0628\u062D",
+ "\uFC07"=>"\u0628\u062E",
+ "\uFC08"=>"\u0628\u0645",
+ "\uFC09"=>"\u0628\u0649",
+ "\uFC0A"=>"\u0628\u064A",
+ "\uFC0B"=>"\u062A\u062C",
+ "\uFC0C"=>"\u062A\u062D",
+ "\uFC0D"=>"\u062A\u062E",
+ "\uFC0E"=>"\u062A\u0645",
+ "\uFC0F"=>"\u062A\u0649",
+ "\uFC10"=>"\u062A\u064A",
+ "\uFC11"=>"\u062B\u062C",
+ "\uFC12"=>"\u062B\u0645",
+ "\uFC13"=>"\u062B\u0649",
+ "\uFC14"=>"\u062B\u064A",
+ "\uFC15"=>"\u062C\u062D",
+ "\uFC16"=>"\u062C\u0645",
+ "\uFC17"=>"\u062D\u062C",
+ "\uFC18"=>"\u062D\u0645",
+ "\uFC19"=>"\u062E\u062C",
+ "\uFC1A"=>"\u062E\u062D",
+ "\uFC1B"=>"\u062E\u0645",
+ "\uFC1C"=>"\u0633\u062C",
+ "\uFC1D"=>"\u0633\u062D",
+ "\uFC1E"=>"\u0633\u062E",
+ "\uFC1F"=>"\u0633\u0645",
+ "\uFC20"=>"\u0635\u062D",
+ "\uFC21"=>"\u0635\u0645",
+ "\uFC22"=>"\u0636\u062C",
+ "\uFC23"=>"\u0636\u062D",
+ "\uFC24"=>"\u0636\u062E",
+ "\uFC25"=>"\u0636\u0645",
+ "\uFC26"=>"\u0637\u062D",
+ "\uFC27"=>"\u0637\u0645",
+ "\uFC28"=>"\u0638\u0645",
+ "\uFC29"=>"\u0639\u062C",
+ "\uFC2A"=>"\u0639\u0645",
+ "\uFC2B"=>"\u063A\u062C",
+ "\uFC2C"=>"\u063A\u0645",
+ "\uFC2D"=>"\u0641\u062C",
+ "\uFC2E"=>"\u0641\u062D",
+ "\uFC2F"=>"\u0641\u062E",
+ "\uFC30"=>"\u0641\u0645",
+ "\uFC31"=>"\u0641\u0649",
+ "\uFC32"=>"\u0641\u064A",
+ "\uFC33"=>"\u0642\u062D",
+ "\uFC34"=>"\u0642\u0645",
+ "\uFC35"=>"\u0642\u0649",
+ "\uFC36"=>"\u0642\u064A",
+ "\uFC37"=>"\u0643\u0627",
+ "\uFC38"=>"\u0643\u062C",
+ "\uFC39"=>"\u0643\u062D",
+ "\uFC3A"=>"\u0643\u062E",
+ "\uFC3B"=>"\u0643\u0644",
+ "\uFC3C"=>"\u0643\u0645",
+ "\uFC3D"=>"\u0643\u0649",
+ "\uFC3E"=>"\u0643\u064A",
+ "\uFC3F"=>"\u0644\u062C",
+ "\uFC40"=>"\u0644\u062D",
+ "\uFC41"=>"\u0644\u062E",
+ "\uFC42"=>"\u0644\u0645",
+ "\uFC43"=>"\u0644\u0649",
+ "\uFC44"=>"\u0644\u064A",
+ "\uFC45"=>"\u0645\u062C",
+ "\uFC46"=>"\u0645\u062D",
+ "\uFC47"=>"\u0645\u062E",
+ "\uFC48"=>"\u0645\u0645",
+ "\uFC49"=>"\u0645\u0649",
+ "\uFC4A"=>"\u0645\u064A",
+ "\uFC4B"=>"\u0646\u062C",
+ "\uFC4C"=>"\u0646\u062D",
+ "\uFC4D"=>"\u0646\u062E",
+ "\uFC4E"=>"\u0646\u0645",
+ "\uFC4F"=>"\u0646\u0649",
+ "\uFC50"=>"\u0646\u064A",
+ "\uFC51"=>"\u0647\u062C",
+ "\uFC52"=>"\u0647\u0645",
+ "\uFC53"=>"\u0647\u0649",
+ "\uFC54"=>"\u0647\u064A",
+ "\uFC55"=>"\u064A\u062C",
+ "\uFC56"=>"\u064A\u062D",
+ "\uFC57"=>"\u064A\u062E",
+ "\uFC58"=>"\u064A\u0645",
+ "\uFC59"=>"\u064A\u0649",
+ "\uFC5A"=>"\u064A\u064A",
+ "\uFC5B"=>"\u0630\u0670",
+ "\uFC5C"=>"\u0631\u0670",
+ "\uFC5D"=>"\u0649\u0670",
+ "\uFC5E"=>" \u064C\u0651",
+ "\uFC5F"=>" \u064D\u0651",
+ "\uFC60"=>" \u064E\u0651",
+ "\uFC61"=>" \u064F\u0651",
+ "\uFC62"=>" \u0650\u0651",
+ "\uFC63"=>" \u0651\u0670",
+ "\uFC64"=>"\u0626\u0631",
+ "\uFC65"=>"\u0626\u0632",
+ "\uFC66"=>"\u0626\u0645",
+ "\uFC67"=>"\u0626\u0646",
+ "\uFC68"=>"\u0626\u0649",
+ "\uFC69"=>"\u0626\u064A",
+ "\uFC6A"=>"\u0628\u0631",
+ "\uFC6B"=>"\u0628\u0632",
+ "\uFC6C"=>"\u0628\u0645",
+ "\uFC6D"=>"\u0628\u0646",
+ "\uFC6E"=>"\u0628\u0649",
+ "\uFC6F"=>"\u0628\u064A",
+ "\uFC70"=>"\u062A\u0631",
+ "\uFC71"=>"\u062A\u0632",
+ "\uFC72"=>"\u062A\u0645",
+ "\uFC73"=>"\u062A\u0646",
+ "\uFC74"=>"\u062A\u0649",
+ "\uFC75"=>"\u062A\u064A",
+ "\uFC76"=>"\u062B\u0631",
+ "\uFC77"=>"\u062B\u0632",
+ "\uFC78"=>"\u062B\u0645",
+ "\uFC79"=>"\u062B\u0646",
+ "\uFC7A"=>"\u062B\u0649",
+ "\uFC7B"=>"\u062B\u064A",
+ "\uFC7C"=>"\u0641\u0649",
+ "\uFC7D"=>"\u0641\u064A",
+ "\uFC7E"=>"\u0642\u0649",
+ "\uFC7F"=>"\u0642\u064A",
+ "\uFC80"=>"\u0643\u0627",
+ "\uFC81"=>"\u0643\u0644",
+ "\uFC82"=>"\u0643\u0645",
+ "\uFC83"=>"\u0643\u0649",
+ "\uFC84"=>"\u0643\u064A",
+ "\uFC85"=>"\u0644\u0645",
+ "\uFC86"=>"\u0644\u0649",
+ "\uFC87"=>"\u0644\u064A",
+ "\uFC88"=>"\u0645\u0627",
+ "\uFC89"=>"\u0645\u0645",
+ "\uFC8A"=>"\u0646\u0631",
+ "\uFC8B"=>"\u0646\u0632",
+ "\uFC8C"=>"\u0646\u0645",
+ "\uFC8D"=>"\u0646\u0646",
+ "\uFC8E"=>"\u0646\u0649",
+ "\uFC8F"=>"\u0646\u064A",
+ "\uFC90"=>"\u0649\u0670",
+ "\uFC91"=>"\u064A\u0631",
+ "\uFC92"=>"\u064A\u0632",
+ "\uFC93"=>"\u064A\u0645",
+ "\uFC94"=>"\u064A\u0646",
+ "\uFC95"=>"\u064A\u0649",
+ "\uFC96"=>"\u064A\u064A",
+ "\uFC97"=>"\u0626\u062C",
+ "\uFC98"=>"\u0626\u062D",
+ "\uFC99"=>"\u0626\u062E",
+ "\uFC9A"=>"\u0626\u0645",
+ "\uFC9B"=>"\u0626\u0647",
+ "\uFC9C"=>"\u0628\u062C",
+ "\uFC9D"=>"\u0628\u062D",
+ "\uFC9E"=>"\u0628\u062E",
+ "\uFC9F"=>"\u0628\u0645",
+ "\uFCA0"=>"\u0628\u0647",
+ "\uFCA1"=>"\u062A\u062C",
+ "\uFCA2"=>"\u062A\u062D",
+ "\uFCA3"=>"\u062A\u062E",
+ "\uFCA4"=>"\u062A\u0645",
+ "\uFCA5"=>"\u062A\u0647",
+ "\uFCA6"=>"\u062B\u0645",
+ "\uFCA7"=>"\u062C\u062D",
+ "\uFCA8"=>"\u062C\u0645",
+ "\uFCA9"=>"\u062D\u062C",
+ "\uFCAA"=>"\u062D\u0645",
+ "\uFCAB"=>"\u062E\u062C",
+ "\uFCAC"=>"\u062E\u0645",
+ "\uFCAD"=>"\u0633\u062C",
+ "\uFCAE"=>"\u0633\u062D",
+ "\uFCAF"=>"\u0633\u062E",
+ "\uFCB0"=>"\u0633\u0645",
+ "\uFCB1"=>"\u0635\u062D",
+ "\uFCB2"=>"\u0635\u062E",
+ "\uFCB3"=>"\u0635\u0645",
+ "\uFCB4"=>"\u0636\u062C",
+ "\uFCB5"=>"\u0636\u062D",
+ "\uFCB6"=>"\u0636\u062E",
+ "\uFCB7"=>"\u0636\u0645",
+ "\uFCB8"=>"\u0637\u062D",
+ "\uFCB9"=>"\u0638\u0645",
+ "\uFCBA"=>"\u0639\u062C",
+ "\uFCBB"=>"\u0639\u0645",
+ "\uFCBC"=>"\u063A\u062C",
+ "\uFCBD"=>"\u063A\u0645",
+ "\uFCBE"=>"\u0641\u062C",
+ "\uFCBF"=>"\u0641\u062D",
+ "\uFCC0"=>"\u0641\u062E",
+ "\uFCC1"=>"\u0641\u0645",
+ "\uFCC2"=>"\u0642\u062D",
+ "\uFCC3"=>"\u0642\u0645",
+ "\uFCC4"=>"\u0643\u062C",
+ "\uFCC5"=>"\u0643\u062D",
+ "\uFCC6"=>"\u0643\u062E",
+ "\uFCC7"=>"\u0643\u0644",
+ "\uFCC8"=>"\u0643\u0645",
+ "\uFCC9"=>"\u0644\u062C",
+ "\uFCCA"=>"\u0644\u062D",
+ "\uFCCB"=>"\u0644\u062E",
+ "\uFCCC"=>"\u0644\u0645",
+ "\uFCCD"=>"\u0644\u0647",
+ "\uFCCE"=>"\u0645\u062C",
+ "\uFCCF"=>"\u0645\u062D",
+ "\uFCD0"=>"\u0645\u062E",
+ "\uFCD1"=>"\u0645\u0645",
+ "\uFCD2"=>"\u0646\u062C",
+ "\uFCD3"=>"\u0646\u062D",
+ "\uFCD4"=>"\u0646\u062E",
+ "\uFCD5"=>"\u0646\u0645",
+ "\uFCD6"=>"\u0646\u0647",
+ "\uFCD7"=>"\u0647\u062C",
+ "\uFCD8"=>"\u0647\u0645",
+ "\uFCD9"=>"\u0647\u0670",
+ "\uFCDA"=>"\u064A\u062C",
+ "\uFCDB"=>"\u064A\u062D",
+ "\uFCDC"=>"\u064A\u062E",
+ "\uFCDD"=>"\u064A\u0645",
+ "\uFCDE"=>"\u064A\u0647",
+ "\uFCDF"=>"\u0626\u0645",
+ "\uFCE0"=>"\u0626\u0647",
+ "\uFCE1"=>"\u0628\u0645",
+ "\uFCE2"=>"\u0628\u0647",
+ "\uFCE3"=>"\u062A\u0645",
+ "\uFCE4"=>"\u062A\u0647",
+ "\uFCE5"=>"\u062B\u0645",
+ "\uFCE6"=>"\u062B\u0647",
+ "\uFCE7"=>"\u0633\u0645",
+ "\uFCE8"=>"\u0633\u0647",
+ "\uFCE9"=>"\u0634\u0645",
+ "\uFCEA"=>"\u0634\u0647",
+ "\uFCEB"=>"\u0643\u0644",
+ "\uFCEC"=>"\u0643\u0645",
+ "\uFCED"=>"\u0644\u0645",
+ "\uFCEE"=>"\u0646\u0645",
+ "\uFCEF"=>"\u0646\u0647",
+ "\uFCF0"=>"\u064A\u0645",
+ "\uFCF1"=>"\u064A\u0647",
+ "\uFCF2"=>"\u0640\u064E\u0651",
+ "\uFCF3"=>"\u0640\u064F\u0651",
+ "\uFCF4"=>"\u0640\u0650\u0651",
+ "\uFCF5"=>"\u0637\u0649",
+ "\uFCF6"=>"\u0637\u064A",
+ "\uFCF7"=>"\u0639\u0649",
+ "\uFCF8"=>"\u0639\u064A",
+ "\uFCF9"=>"\u063A\u0649",
+ "\uFCFA"=>"\u063A\u064A",
+ "\uFCFB"=>"\u0633\u0649",
+ "\uFCFC"=>"\u0633\u064A",
+ "\uFCFD"=>"\u0634\u0649",
+ "\uFCFE"=>"\u0634\u064A",
+ "\uFCFF"=>"\u062D\u0649",
+ "\uFD00"=>"\u062D\u064A",
+ "\uFD01"=>"\u062C\u0649",
+ "\uFD02"=>"\u062C\u064A",
+ "\uFD03"=>"\u062E\u0649",
+ "\uFD04"=>"\u062E\u064A",
+ "\uFD05"=>"\u0635\u0649",
+ "\uFD06"=>"\u0635\u064A",
+ "\uFD07"=>"\u0636\u0649",
+ "\uFD08"=>"\u0636\u064A",
+ "\uFD09"=>"\u0634\u062C",
+ "\uFD0A"=>"\u0634\u062D",
+ "\uFD0B"=>"\u0634\u062E",
+ "\uFD0C"=>"\u0634\u0645",
+ "\uFD0D"=>"\u0634\u0631",
+ "\uFD0E"=>"\u0633\u0631",
+ "\uFD0F"=>"\u0635\u0631",
+ "\uFD10"=>"\u0636\u0631",
+ "\uFD11"=>"\u0637\u0649",
+ "\uFD12"=>"\u0637\u064A",
+ "\uFD13"=>"\u0639\u0649",
+ "\uFD14"=>"\u0639\u064A",
+ "\uFD15"=>"\u063A\u0649",
+ "\uFD16"=>"\u063A\u064A",
+ "\uFD17"=>"\u0633\u0649",
+ "\uFD18"=>"\u0633\u064A",
+ "\uFD19"=>"\u0634\u0649",
+ "\uFD1A"=>"\u0634\u064A",
+ "\uFD1B"=>"\u062D\u0649",
+ "\uFD1C"=>"\u062D\u064A",
+ "\uFD1D"=>"\u062C\u0649",
+ "\uFD1E"=>"\u062C\u064A",
+ "\uFD1F"=>"\u062E\u0649",
+ "\uFD20"=>"\u062E\u064A",
+ "\uFD21"=>"\u0635\u0649",
+ "\uFD22"=>"\u0635\u064A",
+ "\uFD23"=>"\u0636\u0649",
+ "\uFD24"=>"\u0636\u064A",
+ "\uFD25"=>"\u0634\u062C",
+ "\uFD26"=>"\u0634\u062D",
+ "\uFD27"=>"\u0634\u062E",
+ "\uFD28"=>"\u0634\u0645",
+ "\uFD29"=>"\u0634\u0631",
+ "\uFD2A"=>"\u0633\u0631",
+ "\uFD2B"=>"\u0635\u0631",
+ "\uFD2C"=>"\u0636\u0631",
+ "\uFD2D"=>"\u0634\u062C",
+ "\uFD2E"=>"\u0634\u062D",
+ "\uFD2F"=>"\u0634\u062E",
+ "\uFD30"=>"\u0634\u0645",
+ "\uFD31"=>"\u0633\u0647",
+ "\uFD32"=>"\u0634\u0647",
+ "\uFD33"=>"\u0637\u0645",
+ "\uFD34"=>"\u0633\u062C",
+ "\uFD35"=>"\u0633\u062D",
+ "\uFD36"=>"\u0633\u062E",
+ "\uFD37"=>"\u0634\u062C",
+ "\uFD38"=>"\u0634\u062D",
+ "\uFD39"=>"\u0634\u062E",
+ "\uFD3A"=>"\u0637\u0645",
+ "\uFD3B"=>"\u0638\u0645",
+ "\uFD3C"=>"\u0627\u064B",
+ "\uFD3D"=>"\u0627\u064B",
+ "\uFD50"=>"\u062A\u062C\u0645",
+ "\uFD51"=>"\u062A\u062D\u062C",
+ "\uFD52"=>"\u062A\u062D\u062C",
+ "\uFD53"=>"\u062A\u062D\u0645",
+ "\uFD54"=>"\u062A\u062E\u0645",
+ "\uFD55"=>"\u062A\u0645\u062C",
+ "\uFD56"=>"\u062A\u0645\u062D",
+ "\uFD57"=>"\u062A\u0645\u062E",
+ "\uFD58"=>"\u062C\u0645\u062D",
+ "\uFD59"=>"\u062C\u0645\u062D",
+ "\uFD5A"=>"\u062D\u0645\u064A",
+ "\uFD5B"=>"\u062D\u0645\u0649",
+ "\uFD5C"=>"\u0633\u062D\u062C",
+ "\uFD5D"=>"\u0633\u062C\u062D",
+ "\uFD5E"=>"\u0633\u062C\u0649",
+ "\uFD5F"=>"\u0633\u0645\u062D",
+ "\uFD60"=>"\u0633\u0645\u062D",
+ "\uFD61"=>"\u0633\u0645\u062C",
+ "\uFD62"=>"\u0633\u0645\u0645",
+ "\uFD63"=>"\u0633\u0645\u0645",
+ "\uFD64"=>"\u0635\u062D\u062D",
+ "\uFD65"=>"\u0635\u062D\u062D",
+ "\uFD66"=>"\u0635\u0645\u0645",
+ "\uFD67"=>"\u0634\u062D\u0645",
+ "\uFD68"=>"\u0634\u062D\u0645",
+ "\uFD69"=>"\u0634\u062C\u064A",
+ "\uFD6A"=>"\u0634\u0645\u062E",
+ "\uFD6B"=>"\u0634\u0645\u062E",
+ "\uFD6C"=>"\u0634\u0645\u0645",
+ "\uFD6D"=>"\u0634\u0645\u0645",
+ "\uFD6E"=>"\u0636\u062D\u0649",
+ "\uFD6F"=>"\u0636\u062E\u0645",
+ "\uFD70"=>"\u0636\u062E\u0645",
+ "\uFD71"=>"\u0637\u0645\u062D",
+ "\uFD72"=>"\u0637\u0645\u062D",
+ "\uFD73"=>"\u0637\u0645\u0645",
+ "\uFD74"=>"\u0637\u0645\u064A",
+ "\uFD75"=>"\u0639\u062C\u0645",
+ "\uFD76"=>"\u0639\u0645\u0645",
+ "\uFD77"=>"\u0639\u0645\u0645",
+ "\uFD78"=>"\u0639\u0645\u0649",
+ "\uFD79"=>"\u063A\u0645\u0645",
+ "\uFD7A"=>"\u063A\u0645\u064A",
+ "\uFD7B"=>"\u063A\u0645\u0649",
+ "\uFD7C"=>"\u0641\u062E\u0645",
+ "\uFD7D"=>"\u0641\u062E\u0645",
+ "\uFD7E"=>"\u0642\u0645\u062D",
+ "\uFD7F"=>"\u0642\u0645\u0645",
+ "\uFD80"=>"\u0644\u062D\u0645",
+ "\uFD81"=>"\u0644\u062D\u064A",
+ "\uFD82"=>"\u0644\u062D\u0649",
+ "\uFD83"=>"\u0644\u062C\u062C",
+ "\uFD84"=>"\u0644\u062C\u062C",
+ "\uFD85"=>"\u0644\u062E\u0645",
+ "\uFD86"=>"\u0644\u062E\u0645",
+ "\uFD87"=>"\u0644\u0645\u062D",
+ "\uFD88"=>"\u0644\u0645\u062D",
+ "\uFD89"=>"\u0645\u062D\u062C",
+ "\uFD8A"=>"\u0645\u062D\u0645",
+ "\uFD8B"=>"\u0645\u062D\u064A",
+ "\uFD8C"=>"\u0645\u062C\u062D",
+ "\uFD8D"=>"\u0645\u062C\u0645",
+ "\uFD8E"=>"\u0645\u062E\u062C",
+ "\uFD8F"=>"\u0645\u062E\u0645",
+ "\uFD92"=>"\u0645\u062C\u062E",
+ "\uFD93"=>"\u0647\u0645\u062C",
+ "\uFD94"=>"\u0647\u0645\u0645",
+ "\uFD95"=>"\u0646\u062D\u0645",
+ "\uFD96"=>"\u0646\u062D\u0649",
+ "\uFD97"=>"\u0646\u062C\u0645",
+ "\uFD98"=>"\u0646\u062C\u0645",
+ "\uFD99"=>"\u0646\u062C\u0649",
+ "\uFD9A"=>"\u0646\u0645\u064A",
+ "\uFD9B"=>"\u0646\u0645\u0649",
+ "\uFD9C"=>"\u064A\u0645\u0645",
+ "\uFD9D"=>"\u064A\u0645\u0645",
+ "\uFD9E"=>"\u0628\u062E\u064A",
+ "\uFD9F"=>"\u062A\u062C\u064A",
+ "\uFDA0"=>"\u062A\u062C\u0649",
+ "\uFDA1"=>"\u062A\u062E\u064A",
+ "\uFDA2"=>"\u062A\u062E\u0649",
+ "\uFDA3"=>"\u062A\u0645\u064A",
+ "\uFDA4"=>"\u062A\u0645\u0649",
+ "\uFDA5"=>"\u062C\u0645\u064A",
+ "\uFDA6"=>"\u062C\u062D\u0649",
+ "\uFDA7"=>"\u062C\u0645\u0649",
+ "\uFDA8"=>"\u0633\u062E\u0649",
+ "\uFDA9"=>"\u0635\u062D\u064A",
+ "\uFDAA"=>"\u0634\u062D\u064A",
+ "\uFDAB"=>"\u0636\u062D\u064A",
+ "\uFDAC"=>"\u0644\u062C\u064A",
+ "\uFDAD"=>"\u0644\u0645\u064A",
+ "\uFDAE"=>"\u064A\u062D\u064A",
+ "\uFDAF"=>"\u064A\u062C\u064A",
+ "\uFDB0"=>"\u064A\u0645\u064A",
+ "\uFDB1"=>"\u0645\u0645\u064A",
+ "\uFDB2"=>"\u0642\u0645\u064A",
+ "\uFDB3"=>"\u0646\u062D\u064A",
+ "\uFDB4"=>"\u0642\u0645\u062D",
+ "\uFDB5"=>"\u0644\u062D\u0645",
+ "\uFDB6"=>"\u0639\u0645\u064A",
+ "\uFDB7"=>"\u0643\u0645\u064A",
+ "\uFDB8"=>"\u0646\u062C\u062D",
+ "\uFDB9"=>"\u0645\u062E\u064A",
+ "\uFDBA"=>"\u0644\u062C\u0645",
+ "\uFDBB"=>"\u0643\u0645\u0645",
+ "\uFDBC"=>"\u0644\u062C\u0645",
+ "\uFDBD"=>"\u0646\u062C\u062D",
+ "\uFDBE"=>"\u062C\u062D\u064A",
+ "\uFDBF"=>"\u062D\u062C\u064A",
+ "\uFDC0"=>"\u0645\u062C\u064A",
+ "\uFDC1"=>"\u0641\u0645\u064A",
+ "\uFDC2"=>"\u0628\u062D\u064A",
+ "\uFDC3"=>"\u0643\u0645\u0645",
+ "\uFDC4"=>"\u0639\u062C\u0645",
+ "\uFDC5"=>"\u0635\u0645\u0645",
+ "\uFDC6"=>"\u0633\u062E\u064A",
+ "\uFDC7"=>"\u0646\u062C\u064A",
+ "\uFDF0"=>"\u0635\u0644\u06D2",
+ "\uFDF1"=>"\u0642\u0644\u06D2",
+ "\uFDF2"=>"\u0627\u0644\u0644\u0647",
+ "\uFDF3"=>"\u0627\u0643\u0628\u0631",
+ "\uFDF4"=>"\u0645\u062D\u0645\u062F",
+ "\uFDF5"=>"\u0635\u0644\u0639\u0645",
+ "\uFDF6"=>"\u0631\u0633\u0648\u0644",
+ "\uFDF7"=>"\u0639\u0644\u064A\u0647",
+ "\uFDF8"=>"\u0648\u0633\u0644\u0645",
+ "\uFDF9"=>"\u0635\u0644\u0649",
+ "\uFDFA"=>"\u0635\u0644\u0649 \u0627\u0644\u0644\u0647 \u0639\u0644\u064A\u0647 \u0648\u0633\u0644\u0645",
+ "\uFDFB"=>"\u062C\u0644 \u062C\u0644\u0627\u0644\u0647",
+ "\uFDFC"=>"\u0631\u06CC\u0627\u0644",
+ "\uFE10"=>",",
+ "\uFE11"=>"\u3001",
+ "\uFE12"=>"\u3002",
+ "\uFE13"=>":",
+ "\uFE14"=>";",
+ "\uFE15"=>"!",
+ "\uFE16"=>"?",
+ "\uFE17"=>"\u3016",
+ "\uFE18"=>"\u3017",
+ "\uFE19"=>"...",
+ "\uFE30"=>"..",
+ "\uFE31"=>"\u2014",
+ "\uFE32"=>"\u2013",
+ "\uFE33"=>"_",
+ "\uFE34"=>"_",
+ "\uFE35"=>"(",
+ "\uFE36"=>")",
+ "\uFE37"=>"{",
+ "\uFE38"=>"}",
+ "\uFE39"=>"\u3014",
+ "\uFE3A"=>"\u3015",
+ "\uFE3B"=>"\u3010",
+ "\uFE3C"=>"\u3011",
+ "\uFE3D"=>"\u300A",
+ "\uFE3E"=>"\u300B",
+ "\uFE3F"=>"\u3008",
+ "\uFE40"=>"\u3009",
+ "\uFE41"=>"\u300C",
+ "\uFE42"=>"\u300D",
+ "\uFE43"=>"\u300E",
+ "\uFE44"=>"\u300F",
+ "\uFE47"=>"[",
+ "\uFE48"=>"]",
+ "\uFE49"=>" \u0305",
+ "\uFE4A"=>" \u0305",
+ "\uFE4B"=>" \u0305",
+ "\uFE4C"=>" \u0305",
+ "\uFE4D"=>"_",
+ "\uFE4E"=>"_",
+ "\uFE4F"=>"_",
+ "\uFE50"=>",",
+ "\uFE51"=>"\u3001",
+ "\uFE52"=>".",
+ "\uFE54"=>";",
+ "\uFE55"=>":",
+ "\uFE56"=>"?",
+ "\uFE57"=>"!",
+ "\uFE58"=>"\u2014",
+ "\uFE59"=>"(",
+ "\uFE5A"=>")",
+ "\uFE5B"=>"{",
+ "\uFE5C"=>"}",
+ "\uFE5D"=>"\u3014",
+ "\uFE5E"=>"\u3015",
+ "\uFE5F"=>"#",
+ "\uFE60"=>"&",
+ "\uFE61"=>"*",
+ "\uFE62"=>"+",
+ "\uFE63"=>"-",
+ "\uFE64"=>"<",
+ "\uFE65"=>">",
+ "\uFE66"=>"=",
+ "\uFE68"=>"\\",
+ "\uFE69"=>"$",
+ "\uFE6A"=>"%",
+ "\uFE6B"=>"@",
+ "\uFE70"=>" \u064B",
+ "\uFE71"=>"\u0640\u064B",
+ "\uFE72"=>" \u064C",
+ "\uFE74"=>" \u064D",
+ "\uFE76"=>" \u064E",
+ "\uFE77"=>"\u0640\u064E",
+ "\uFE78"=>" \u064F",
+ "\uFE79"=>"\u0640\u064F",
+ "\uFE7A"=>" \u0650",
+ "\uFE7B"=>"\u0640\u0650",
+ "\uFE7C"=>" \u0651",
+ "\uFE7D"=>"\u0640\u0651",
+ "\uFE7E"=>" \u0652",
+ "\uFE7F"=>"\u0640\u0652",
+ "\uFE80"=>"\u0621",
+ "\uFE81"=>"\u0622",
+ "\uFE82"=>"\u0622",
+ "\uFE83"=>"\u0623",
+ "\uFE84"=>"\u0623",
+ "\uFE85"=>"\u0624",
+ "\uFE86"=>"\u0624",
+ "\uFE87"=>"\u0625",
+ "\uFE88"=>"\u0625",
+ "\uFE89"=>"\u0626",
+ "\uFE8A"=>"\u0626",
+ "\uFE8B"=>"\u0626",
+ "\uFE8C"=>"\u0626",
+ "\uFE8D"=>"\u0627",
+ "\uFE8E"=>"\u0627",
+ "\uFE8F"=>"\u0628",
+ "\uFE90"=>"\u0628",
+ "\uFE91"=>"\u0628",
+ "\uFE92"=>"\u0628",
+ "\uFE93"=>"\u0629",
+ "\uFE94"=>"\u0629",
+ "\uFE95"=>"\u062A",
+ "\uFE96"=>"\u062A",
+ "\uFE97"=>"\u062A",
+ "\uFE98"=>"\u062A",
+ "\uFE99"=>"\u062B",
+ "\uFE9A"=>"\u062B",
+ "\uFE9B"=>"\u062B",
+ "\uFE9C"=>"\u062B",
+ "\uFE9D"=>"\u062C",
+ "\uFE9E"=>"\u062C",
+ "\uFE9F"=>"\u062C",
+ "\uFEA0"=>"\u062C",
+ "\uFEA1"=>"\u062D",
+ "\uFEA2"=>"\u062D",
+ "\uFEA3"=>"\u062D",
+ "\uFEA4"=>"\u062D",
+ "\uFEA5"=>"\u062E",
+ "\uFEA6"=>"\u062E",
+ "\uFEA7"=>"\u062E",
+ "\uFEA8"=>"\u062E",
+ "\uFEA9"=>"\u062F",
+ "\uFEAA"=>"\u062F",
+ "\uFEAB"=>"\u0630",
+ "\uFEAC"=>"\u0630",
+ "\uFEAD"=>"\u0631",
+ "\uFEAE"=>"\u0631",
+ "\uFEAF"=>"\u0632",
+ "\uFEB0"=>"\u0632",
+ "\uFEB1"=>"\u0633",
+ "\uFEB2"=>"\u0633",
+ "\uFEB3"=>"\u0633",
+ "\uFEB4"=>"\u0633",
+ "\uFEB5"=>"\u0634",
+ "\uFEB6"=>"\u0634",
+ "\uFEB7"=>"\u0634",
+ "\uFEB8"=>"\u0634",
+ "\uFEB9"=>"\u0635",
+ "\uFEBA"=>"\u0635",
+ "\uFEBB"=>"\u0635",
+ "\uFEBC"=>"\u0635",
+ "\uFEBD"=>"\u0636",
+ "\uFEBE"=>"\u0636",
+ "\uFEBF"=>"\u0636",
+ "\uFEC0"=>"\u0636",
+ "\uFEC1"=>"\u0637",
+ "\uFEC2"=>"\u0637",
+ "\uFEC3"=>"\u0637",
+ "\uFEC4"=>"\u0637",
+ "\uFEC5"=>"\u0638",
+ "\uFEC6"=>"\u0638",
+ "\uFEC7"=>"\u0638",
+ "\uFEC8"=>"\u0638",
+ "\uFEC9"=>"\u0639",
+ "\uFECA"=>"\u0639",
+ "\uFECB"=>"\u0639",
+ "\uFECC"=>"\u0639",
+ "\uFECD"=>"\u063A",
+ "\uFECE"=>"\u063A",
+ "\uFECF"=>"\u063A",
+ "\uFED0"=>"\u063A",
+ "\uFED1"=>"\u0641",
+ "\uFED2"=>"\u0641",
+ "\uFED3"=>"\u0641",
+ "\uFED4"=>"\u0641",
+ "\uFED5"=>"\u0642",
+ "\uFED6"=>"\u0642",
+ "\uFED7"=>"\u0642",
+ "\uFED8"=>"\u0642",
+ "\uFED9"=>"\u0643",
+ "\uFEDA"=>"\u0643",
+ "\uFEDB"=>"\u0643",
+ "\uFEDC"=>"\u0643",
+ "\uFEDD"=>"\u0644",
+ "\uFEDE"=>"\u0644",
+ "\uFEDF"=>"\u0644",
+ "\uFEE0"=>"\u0644",
+ "\uFEE1"=>"\u0645",
+ "\uFEE2"=>"\u0645",
+ "\uFEE3"=>"\u0645",
+ "\uFEE4"=>"\u0645",
+ "\uFEE5"=>"\u0646",
+ "\uFEE6"=>"\u0646",
+ "\uFEE7"=>"\u0646",
+ "\uFEE8"=>"\u0646",
+ "\uFEE9"=>"\u0647",
+ "\uFEEA"=>"\u0647",
+ "\uFEEB"=>"\u0647",
+ "\uFEEC"=>"\u0647",
+ "\uFEED"=>"\u0648",
+ "\uFEEE"=>"\u0648",
+ "\uFEEF"=>"\u0649",
+ "\uFEF0"=>"\u0649",
+ "\uFEF1"=>"\u064A",
+ "\uFEF2"=>"\u064A",
+ "\uFEF3"=>"\u064A",
+ "\uFEF4"=>"\u064A",
+ "\uFEF5"=>"\u0644\u0622",
+ "\uFEF6"=>"\u0644\u0622",
+ "\uFEF7"=>"\u0644\u0623",
+ "\uFEF8"=>"\u0644\u0623",
+ "\uFEF9"=>"\u0644\u0625",
+ "\uFEFA"=>"\u0644\u0625",
+ "\uFEFB"=>"\u0644\u0627",
+ "\uFEFC"=>"\u0644\u0627",
+ "\uFF01"=>"!",
+ "\uFF02"=>"\"",
+ "\uFF03"=>"#",
+ "\uFF04"=>"$",
+ "\uFF05"=>"%",
+ "\uFF06"=>"&",
+ "\uFF07"=>"'",
+ "\uFF08"=>"(",
+ "\uFF09"=>")",
+ "\uFF0A"=>"*",
+ "\uFF0B"=>"+",
+ "\uFF0C"=>",",
+ "\uFF0D"=>"-",
+ "\uFF0E"=>".",
+ "\uFF0F"=>"/",
+ "\uFF10"=>"0",
+ "\uFF11"=>"1",
+ "\uFF12"=>"2",
+ "\uFF13"=>"3",
+ "\uFF14"=>"4",
+ "\uFF15"=>"5",
+ "\uFF16"=>"6",
+ "\uFF17"=>"7",
+ "\uFF18"=>"8",
+ "\uFF19"=>"9",
+ "\uFF1A"=>":",
+ "\uFF1B"=>";",
+ "\uFF1C"=>"<",
+ "\uFF1D"=>"=",
+ "\uFF1E"=>">",
+ "\uFF1F"=>"?",
+ "\uFF20"=>"@",
+ "\uFF21"=>"A",
+ "\uFF22"=>"B",
+ "\uFF23"=>"C",
+ "\uFF24"=>"D",
+ "\uFF25"=>"E",
+ "\uFF26"=>"F",
+ "\uFF27"=>"G",
+ "\uFF28"=>"H",
+ "\uFF29"=>"I",
+ "\uFF2A"=>"J",
+ "\uFF2B"=>"K",
+ "\uFF2C"=>"L",
+ "\uFF2D"=>"M",
+ "\uFF2E"=>"N",
+ "\uFF2F"=>"O",
+ "\uFF30"=>"P",
+ "\uFF31"=>"Q",
+ "\uFF32"=>"R",
+ "\uFF33"=>"S",
+ "\uFF34"=>"T",
+ "\uFF35"=>"U",
+ "\uFF36"=>"V",
+ "\uFF37"=>"W",
+ "\uFF38"=>"X",
+ "\uFF39"=>"Y",
+ "\uFF3A"=>"Z",
+ "\uFF3B"=>"[",
+ "\uFF3C"=>"\\",
+ "\uFF3D"=>"]",
+ "\uFF3E"=>"^",
+ "\uFF3F"=>"_",
+ "\uFF40"=>"`",
+ "\uFF41"=>"a",
+ "\uFF42"=>"b",
+ "\uFF43"=>"c",
+ "\uFF44"=>"d",
+ "\uFF45"=>"e",
+ "\uFF46"=>"f",
+ "\uFF47"=>"g",
+ "\uFF48"=>"h",
+ "\uFF49"=>"i",
+ "\uFF4A"=>"j",
+ "\uFF4B"=>"k",
+ "\uFF4C"=>"l",
+ "\uFF4D"=>"m",
+ "\uFF4E"=>"n",
+ "\uFF4F"=>"o",
+ "\uFF50"=>"p",
+ "\uFF51"=>"q",
+ "\uFF52"=>"r",
+ "\uFF53"=>"s",
+ "\uFF54"=>"t",
+ "\uFF55"=>"u",
+ "\uFF56"=>"v",
+ "\uFF57"=>"w",
+ "\uFF58"=>"x",
+ "\uFF59"=>"y",
+ "\uFF5A"=>"z",
+ "\uFF5B"=>"{",
+ "\uFF5C"=>"|",
+ "\uFF5D"=>"}",
+ "\uFF5E"=>"~",
+ "\uFF5F"=>"\u2985",
+ "\uFF60"=>"\u2986",
+ "\uFF61"=>"\u3002",
+ "\uFF62"=>"\u300C",
+ "\uFF63"=>"\u300D",
+ "\uFF64"=>"\u3001",
+ "\uFF65"=>"\u30FB",
+ "\uFF66"=>"\u30F2",
+ "\uFF67"=>"\u30A1",
+ "\uFF68"=>"\u30A3",
+ "\uFF69"=>"\u30A5",
+ "\uFF6A"=>"\u30A7",
+ "\uFF6B"=>"\u30A9",
+ "\uFF6C"=>"\u30E3",
+ "\uFF6D"=>"\u30E5",
+ "\uFF6E"=>"\u30E7",
+ "\uFF6F"=>"\u30C3",
+ "\uFF70"=>"\u30FC",
+ "\uFF71"=>"\u30A2",
+ "\uFF72"=>"\u30A4",
+ "\uFF73"=>"\u30A6",
+ "\uFF74"=>"\u30A8",
+ "\uFF75"=>"\u30AA",
+ "\uFF76"=>"\u30AB",
+ "\uFF77"=>"\u30AD",
+ "\uFF78"=>"\u30AF",
+ "\uFF79"=>"\u30B1",
+ "\uFF7A"=>"\u30B3",
+ "\uFF7B"=>"\u30B5",
+ "\uFF7C"=>"\u30B7",
+ "\uFF7D"=>"\u30B9",
+ "\uFF7E"=>"\u30BB",
+ "\uFF7F"=>"\u30BD",
+ "\uFF80"=>"\u30BF",
+ "\uFF81"=>"\u30C1",
+ "\uFF82"=>"\u30C4",
+ "\uFF83"=>"\u30C6",
+ "\uFF84"=>"\u30C8",
+ "\uFF85"=>"\u30CA",
+ "\uFF86"=>"\u30CB",
+ "\uFF87"=>"\u30CC",
+ "\uFF88"=>"\u30CD",
+ "\uFF89"=>"\u30CE",
+ "\uFF8A"=>"\u30CF",
+ "\uFF8B"=>"\u30D2",
+ "\uFF8C"=>"\u30D5",
+ "\uFF8D"=>"\u30D8",
+ "\uFF8E"=>"\u30DB",
+ "\uFF8F"=>"\u30DE",
+ "\uFF90"=>"\u30DF",
+ "\uFF91"=>"\u30E0",
+ "\uFF92"=>"\u30E1",
+ "\uFF93"=>"\u30E2",
+ "\uFF94"=>"\u30E4",
+ "\uFF95"=>"\u30E6",
+ "\uFF96"=>"\u30E8",
+ "\uFF97"=>"\u30E9",
+ "\uFF98"=>"\u30EA",
+ "\uFF99"=>"\u30EB",
+ "\uFF9A"=>"\u30EC",
+ "\uFF9B"=>"\u30ED",
+ "\uFF9C"=>"\u30EF",
+ "\uFF9D"=>"\u30F3",
+ "\uFF9E"=>"\u3099",
+ "\uFF9F"=>"\u309A",
+ "\uFFA0"=>"\u1160",
+ "\uFFA1"=>"\u1100",
+ "\uFFA2"=>"\u1101",
+ "\uFFA3"=>"\u11AA",
+ "\uFFA4"=>"\u1102",
+ "\uFFA5"=>"\u11AC",
+ "\uFFA6"=>"\u11AD",
+ "\uFFA7"=>"\u1103",
+ "\uFFA8"=>"\u1104",
+ "\uFFA9"=>"\u1105",
+ "\uFFAA"=>"\u11B0",
+ "\uFFAB"=>"\u11B1",
+ "\uFFAC"=>"\u11B2",
+ "\uFFAD"=>"\u11B3",
+ "\uFFAE"=>"\u11B4",
+ "\uFFAF"=>"\u11B5",
+ "\uFFB0"=>"\u111A",
+ "\uFFB1"=>"\u1106",
+ "\uFFB2"=>"\u1107",
+ "\uFFB3"=>"\u1108",
+ "\uFFB4"=>"\u1121",
+ "\uFFB5"=>"\u1109",
+ "\uFFB6"=>"\u110A",
+ "\uFFB7"=>"\u110B",
+ "\uFFB8"=>"\u110C",
+ "\uFFB9"=>"\u110D",
+ "\uFFBA"=>"\u110E",
+ "\uFFBB"=>"\u110F",
+ "\uFFBC"=>"\u1110",
+ "\uFFBD"=>"\u1111",
+ "\uFFBE"=>"\u1112",
+ "\uFFC2"=>"\u1161",
+ "\uFFC3"=>"\u1162",
+ "\uFFC4"=>"\u1163",
+ "\uFFC5"=>"\u1164",
+ "\uFFC6"=>"\u1165",
+ "\uFFC7"=>"\u1166",
+ "\uFFCA"=>"\u1167",
+ "\uFFCB"=>"\u1168",
+ "\uFFCC"=>"\u1169",
+ "\uFFCD"=>"\u116A",
+ "\uFFCE"=>"\u116B",
+ "\uFFCF"=>"\u116C",
+ "\uFFD2"=>"\u116D",
+ "\uFFD3"=>"\u116E",
+ "\uFFD4"=>"\u116F",
+ "\uFFD5"=>"\u1170",
+ "\uFFD6"=>"\u1171",
+ "\uFFD7"=>"\u1172",
+ "\uFFDA"=>"\u1173",
+ "\uFFDB"=>"\u1174",
+ "\uFFDC"=>"\u1175",
+ "\uFFE0"=>"\u00A2",
+ "\uFFE1"=>"\u00A3",
+ "\uFFE2"=>"\u00AC",
+ "\uFFE3"=>" \u0304",
+ "\uFFE4"=>"\u00A6",
+ "\uFFE5"=>"\u00A5",
+ "\uFFE6"=>"\u20A9",
+ "\uFFE8"=>"\u2502",
+ "\uFFE9"=>"\u2190",
+ "\uFFEA"=>"\u2191",
+ "\uFFEB"=>"\u2192",
+ "\uFFEC"=>"\u2193",
+ "\uFFED"=>"\u25A0",
+ "\uFFEE"=>"\u25CB",
+ "\u{1D400}"=>"A",
+ "\u{1D401}"=>"B",
+ "\u{1D402}"=>"C",
+ "\u{1D403}"=>"D",
+ "\u{1D404}"=>"E",
+ "\u{1D405}"=>"F",
+ "\u{1D406}"=>"G",
+ "\u{1D407}"=>"H",
+ "\u{1D408}"=>"I",
+ "\u{1D409}"=>"J",
+ "\u{1D40A}"=>"K",
+ "\u{1D40B}"=>"L",
+ "\u{1D40C}"=>"M",
+ "\u{1D40D}"=>"N",
+ "\u{1D40E}"=>"O",
+ "\u{1D40F}"=>"P",
+ "\u{1D410}"=>"Q",
+ "\u{1D411}"=>"R",
+ "\u{1D412}"=>"S",
+ "\u{1D413}"=>"T",
+ "\u{1D414}"=>"U",
+ "\u{1D415}"=>"V",
+ "\u{1D416}"=>"W",
+ "\u{1D417}"=>"X",
+ "\u{1D418}"=>"Y",
+ "\u{1D419}"=>"Z",
+ "\u{1D41A}"=>"a",
+ "\u{1D41B}"=>"b",
+ "\u{1D41C}"=>"c",
+ "\u{1D41D}"=>"d",
+ "\u{1D41E}"=>"e",
+ "\u{1D41F}"=>"f",
+ "\u{1D420}"=>"g",
+ "\u{1D421}"=>"h",
+ "\u{1D422}"=>"i",
+ "\u{1D423}"=>"j",
+ "\u{1D424}"=>"k",
+ "\u{1D425}"=>"l",
+ "\u{1D426}"=>"m",
+ "\u{1D427}"=>"n",
+ "\u{1D428}"=>"o",
+ "\u{1D429}"=>"p",
+ "\u{1D42A}"=>"q",
+ "\u{1D42B}"=>"r",
+ "\u{1D42C}"=>"s",
+ "\u{1D42D}"=>"t",
+ "\u{1D42E}"=>"u",
+ "\u{1D42F}"=>"v",
+ "\u{1D430}"=>"w",
+ "\u{1D431}"=>"x",
+ "\u{1D432}"=>"y",
+ "\u{1D433}"=>"z",
+ "\u{1D434}"=>"A",
+ "\u{1D435}"=>"B",
+ "\u{1D436}"=>"C",
+ "\u{1D437}"=>"D",
+ "\u{1D438}"=>"E",
+ "\u{1D439}"=>"F",
+ "\u{1D43A}"=>"G",
+ "\u{1D43B}"=>"H",
+ "\u{1D43C}"=>"I",
+ "\u{1D43D}"=>"J",
+ "\u{1D43E}"=>"K",
+ "\u{1D43F}"=>"L",
+ "\u{1D440}"=>"M",
+ "\u{1D441}"=>"N",
+ "\u{1D442}"=>"O",
+ "\u{1D443}"=>"P",
+ "\u{1D444}"=>"Q",
+ "\u{1D445}"=>"R",
+ "\u{1D446}"=>"S",
+ "\u{1D447}"=>"T",
+ "\u{1D448}"=>"U",
+ "\u{1D449}"=>"V",
+ "\u{1D44A}"=>"W",
+ "\u{1D44B}"=>"X",
+ "\u{1D44C}"=>"Y",
+ "\u{1D44D}"=>"Z",
+ "\u{1D44E}"=>"a",
+ "\u{1D44F}"=>"b",
+ "\u{1D450}"=>"c",
+ "\u{1D451}"=>"d",
+ "\u{1D452}"=>"e",
+ "\u{1D453}"=>"f",
+ "\u{1D454}"=>"g",
+ "\u{1D456}"=>"i",
+ "\u{1D457}"=>"j",
+ "\u{1D458}"=>"k",
+ "\u{1D459}"=>"l",
+ "\u{1D45A}"=>"m",
+ "\u{1D45B}"=>"n",
+ "\u{1D45C}"=>"o",
+ "\u{1D45D}"=>"p",
+ "\u{1D45E}"=>"q",
+ "\u{1D45F}"=>"r",
+ "\u{1D460}"=>"s",
+ "\u{1D461}"=>"t",
+ "\u{1D462}"=>"u",
+ "\u{1D463}"=>"v",
+ "\u{1D464}"=>"w",
+ "\u{1D465}"=>"x",
+ "\u{1D466}"=>"y",
+ "\u{1D467}"=>"z",
+ "\u{1D468}"=>"A",
+ "\u{1D469}"=>"B",
+ "\u{1D46A}"=>"C",
+ "\u{1D46B}"=>"D",
+ "\u{1D46C}"=>"E",
+ "\u{1D46D}"=>"F",
+ "\u{1D46E}"=>"G",
+ "\u{1D46F}"=>"H",
+ "\u{1D470}"=>"I",
+ "\u{1D471}"=>"J",
+ "\u{1D472}"=>"K",
+ "\u{1D473}"=>"L",
+ "\u{1D474}"=>"M",
+ "\u{1D475}"=>"N",
+ "\u{1D476}"=>"O",
+ "\u{1D477}"=>"P",
+ "\u{1D478}"=>"Q",
+ "\u{1D479}"=>"R",
+ "\u{1D47A}"=>"S",
+ "\u{1D47B}"=>"T",
+ "\u{1D47C}"=>"U",
+ "\u{1D47D}"=>"V",
+ "\u{1D47E}"=>"W",
+ "\u{1D47F}"=>"X",
+ "\u{1D480}"=>"Y",
+ "\u{1D481}"=>"Z",
+ "\u{1D482}"=>"a",
+ "\u{1D483}"=>"b",
+ "\u{1D484}"=>"c",
+ "\u{1D485}"=>"d",
+ "\u{1D486}"=>"e",
+ "\u{1D487}"=>"f",
+ "\u{1D488}"=>"g",
+ "\u{1D489}"=>"h",
+ "\u{1D48A}"=>"i",
+ "\u{1D48B}"=>"j",
+ "\u{1D48C}"=>"k",
+ "\u{1D48D}"=>"l",
+ "\u{1D48E}"=>"m",
+ "\u{1D48F}"=>"n",
+ "\u{1D490}"=>"o",
+ "\u{1D491}"=>"p",
+ "\u{1D492}"=>"q",
+ "\u{1D493}"=>"r",
+ "\u{1D494}"=>"s",
+ "\u{1D495}"=>"t",
+ "\u{1D496}"=>"u",
+ "\u{1D497}"=>"v",
+ "\u{1D498}"=>"w",
+ "\u{1D499}"=>"x",
+ "\u{1D49A}"=>"y",
+ "\u{1D49B}"=>"z",
+ "\u{1D49C}"=>"A",
+ "\u{1D49E}"=>"C",
+ "\u{1D49F}"=>"D",
+ "\u{1D4A2}"=>"G",
+ "\u{1D4A5}"=>"J",
+ "\u{1D4A6}"=>"K",
+ "\u{1D4A9}"=>"N",
+ "\u{1D4AA}"=>"O",
+ "\u{1D4AB}"=>"P",
+ "\u{1D4AC}"=>"Q",
+ "\u{1D4AE}"=>"S",
+ "\u{1D4AF}"=>"T",
+ "\u{1D4B0}"=>"U",
+ "\u{1D4B1}"=>"V",
+ "\u{1D4B2}"=>"W",
+ "\u{1D4B3}"=>"X",
+ "\u{1D4B4}"=>"Y",
+ "\u{1D4B5}"=>"Z",
+ "\u{1D4B6}"=>"a",
+ "\u{1D4B7}"=>"b",
+ "\u{1D4B8}"=>"c",
+ "\u{1D4B9}"=>"d",
+ "\u{1D4BB}"=>"f",
+ "\u{1D4BD}"=>"h",
+ "\u{1D4BE}"=>"i",
+ "\u{1D4BF}"=>"j",
+ "\u{1D4C0}"=>"k",
+ "\u{1D4C1}"=>"l",
+ "\u{1D4C2}"=>"m",
+ "\u{1D4C3}"=>"n",
+ "\u{1D4C5}"=>"p",
+ "\u{1D4C6}"=>"q",
+ "\u{1D4C7}"=>"r",
+ "\u{1D4C8}"=>"s",
+ "\u{1D4C9}"=>"t",
+ "\u{1D4CA}"=>"u",
+ "\u{1D4CB}"=>"v",
+ "\u{1D4CC}"=>"w",
+ "\u{1D4CD}"=>"x",
+ "\u{1D4CE}"=>"y",
+ "\u{1D4CF}"=>"z",
+ "\u{1D4D0}"=>"A",
+ "\u{1D4D1}"=>"B",
+ "\u{1D4D2}"=>"C",
+ "\u{1D4D3}"=>"D",
+ "\u{1D4D4}"=>"E",
+ "\u{1D4D5}"=>"F",
+ "\u{1D4D6}"=>"G",
+ "\u{1D4D7}"=>"H",
+ "\u{1D4D8}"=>"I",
+ "\u{1D4D9}"=>"J",
+ "\u{1D4DA}"=>"K",
+ "\u{1D4DB}"=>"L",
+ "\u{1D4DC}"=>"M",
+ "\u{1D4DD}"=>"N",
+ "\u{1D4DE}"=>"O",
+ "\u{1D4DF}"=>"P",
+ "\u{1D4E0}"=>"Q",
+ "\u{1D4E1}"=>"R",
+ "\u{1D4E2}"=>"S",
+ "\u{1D4E3}"=>"T",
+ "\u{1D4E4}"=>"U",
+ "\u{1D4E5}"=>"V",
+ "\u{1D4E6}"=>"W",
+ "\u{1D4E7}"=>"X",
+ "\u{1D4E8}"=>"Y",
+ "\u{1D4E9}"=>"Z",
+ "\u{1D4EA}"=>"a",
+ "\u{1D4EB}"=>"b",
+ "\u{1D4EC}"=>"c",
+ "\u{1D4ED}"=>"d",
+ "\u{1D4EE}"=>"e",
+ "\u{1D4EF}"=>"f",
+ "\u{1D4F0}"=>"g",
+ "\u{1D4F1}"=>"h",
+ "\u{1D4F2}"=>"i",
+ "\u{1D4F3}"=>"j",
+ "\u{1D4F4}"=>"k",
+ "\u{1D4F5}"=>"l",
+ "\u{1D4F6}"=>"m",
+ "\u{1D4F7}"=>"n",
+ "\u{1D4F8}"=>"o",
+ "\u{1D4F9}"=>"p",
+ "\u{1D4FA}"=>"q",
+ "\u{1D4FB}"=>"r",
+ "\u{1D4FC}"=>"s",
+ "\u{1D4FD}"=>"t",
+ "\u{1D4FE}"=>"u",
+ "\u{1D4FF}"=>"v",
+ "\u{1D500}"=>"w",
+ "\u{1D501}"=>"x",
+ "\u{1D502}"=>"y",
+ "\u{1D503}"=>"z",
+ "\u{1D504}"=>"A",
+ "\u{1D505}"=>"B",
+ "\u{1D507}"=>"D",
+ "\u{1D508}"=>"E",
+ "\u{1D509}"=>"F",
+ "\u{1D50A}"=>"G",
+ "\u{1D50D}"=>"J",
+ "\u{1D50E}"=>"K",
+ "\u{1D50F}"=>"L",
+ "\u{1D510}"=>"M",
+ "\u{1D511}"=>"N",
+ "\u{1D512}"=>"O",
+ "\u{1D513}"=>"P",
+ "\u{1D514}"=>"Q",
+ "\u{1D516}"=>"S",
+ "\u{1D517}"=>"T",
+ "\u{1D518}"=>"U",
+ "\u{1D519}"=>"V",
+ "\u{1D51A}"=>"W",
+ "\u{1D51B}"=>"X",
+ "\u{1D51C}"=>"Y",
+ "\u{1D51E}"=>"a",
+ "\u{1D51F}"=>"b",
+ "\u{1D520}"=>"c",
+ "\u{1D521}"=>"d",
+ "\u{1D522}"=>"e",
+ "\u{1D523}"=>"f",
+ "\u{1D524}"=>"g",
+ "\u{1D525}"=>"h",
+ "\u{1D526}"=>"i",
+ "\u{1D527}"=>"j",
+ "\u{1D528}"=>"k",
+ "\u{1D529}"=>"l",
+ "\u{1D52A}"=>"m",
+ "\u{1D52B}"=>"n",
+ "\u{1D52C}"=>"o",
+ "\u{1D52D}"=>"p",
+ "\u{1D52E}"=>"q",
+ "\u{1D52F}"=>"r",
+ "\u{1D530}"=>"s",
+ "\u{1D531}"=>"t",
+ "\u{1D532}"=>"u",
+ "\u{1D533}"=>"v",
+ "\u{1D534}"=>"w",
+ "\u{1D535}"=>"x",
+ "\u{1D536}"=>"y",
+ "\u{1D537}"=>"z",
+ "\u{1D538}"=>"A",
+ "\u{1D539}"=>"B",
+ "\u{1D53B}"=>"D",
+ "\u{1D53C}"=>"E",
+ "\u{1D53D}"=>"F",
+ "\u{1D53E}"=>"G",
+ "\u{1D540}"=>"I",
+ "\u{1D541}"=>"J",
+ "\u{1D542}"=>"K",
+ "\u{1D543}"=>"L",
+ "\u{1D544}"=>"M",
+ "\u{1D546}"=>"O",
+ "\u{1D54A}"=>"S",
+ "\u{1D54B}"=>"T",
+ "\u{1D54C}"=>"U",
+ "\u{1D54D}"=>"V",
+ "\u{1D54E}"=>"W",
+ "\u{1D54F}"=>"X",
+ "\u{1D550}"=>"Y",
+ "\u{1D552}"=>"a",
+ "\u{1D553}"=>"b",
+ "\u{1D554}"=>"c",
+ "\u{1D555}"=>"d",
+ "\u{1D556}"=>"e",
+ "\u{1D557}"=>"f",
+ "\u{1D558}"=>"g",
+ "\u{1D559}"=>"h",
+ "\u{1D55A}"=>"i",
+ "\u{1D55B}"=>"j",
+ "\u{1D55C}"=>"k",
+ "\u{1D55D}"=>"l",
+ "\u{1D55E}"=>"m",
+ "\u{1D55F}"=>"n",
+ "\u{1D560}"=>"o",
+ "\u{1D561}"=>"p",
+ "\u{1D562}"=>"q",
+ "\u{1D563}"=>"r",
+ "\u{1D564}"=>"s",
+ "\u{1D565}"=>"t",
+ "\u{1D566}"=>"u",
+ "\u{1D567}"=>"v",
+ "\u{1D568}"=>"w",
+ "\u{1D569}"=>"x",
+ "\u{1D56A}"=>"y",
+ "\u{1D56B}"=>"z",
+ "\u{1D56C}"=>"A",
+ "\u{1D56D}"=>"B",
+ "\u{1D56E}"=>"C",
+ "\u{1D56F}"=>"D",
+ "\u{1D570}"=>"E",
+ "\u{1D571}"=>"F",
+ "\u{1D572}"=>"G",
+ "\u{1D573}"=>"H",
+ "\u{1D574}"=>"I",
+ "\u{1D575}"=>"J",
+ "\u{1D576}"=>"K",
+ "\u{1D577}"=>"L",
+ "\u{1D578}"=>"M",
+ "\u{1D579}"=>"N",
+ "\u{1D57A}"=>"O",
+ "\u{1D57B}"=>"P",
+ "\u{1D57C}"=>"Q",
+ "\u{1D57D}"=>"R",
+ "\u{1D57E}"=>"S",
+ "\u{1D57F}"=>"T",
+ "\u{1D580}"=>"U",
+ "\u{1D581}"=>"V",
+ "\u{1D582}"=>"W",
+ "\u{1D583}"=>"X",
+ "\u{1D584}"=>"Y",
+ "\u{1D585}"=>"Z",
+ "\u{1D586}"=>"a",
+ "\u{1D587}"=>"b",
+ "\u{1D588}"=>"c",
+ "\u{1D589}"=>"d",
+ "\u{1D58A}"=>"e",
+ "\u{1D58B}"=>"f",
+ "\u{1D58C}"=>"g",
+ "\u{1D58D}"=>"h",
+ "\u{1D58E}"=>"i",
+ "\u{1D58F}"=>"j",
+ "\u{1D590}"=>"k",
+ "\u{1D591}"=>"l",
+ "\u{1D592}"=>"m",
+ "\u{1D593}"=>"n",
+ "\u{1D594}"=>"o",
+ "\u{1D595}"=>"p",
+ "\u{1D596}"=>"q",
+ "\u{1D597}"=>"r",
+ "\u{1D598}"=>"s",
+ "\u{1D599}"=>"t",
+ "\u{1D59A}"=>"u",
+ "\u{1D59B}"=>"v",
+ "\u{1D59C}"=>"w",
+ "\u{1D59D}"=>"x",
+ "\u{1D59E}"=>"y",
+ "\u{1D59F}"=>"z",
+ "\u{1D5A0}"=>"A",
+ "\u{1D5A1}"=>"B",
+ "\u{1D5A2}"=>"C",
+ "\u{1D5A3}"=>"D",
+ "\u{1D5A4}"=>"E",
+ "\u{1D5A5}"=>"F",
+ "\u{1D5A6}"=>"G",
+ "\u{1D5A7}"=>"H",
+ "\u{1D5A8}"=>"I",
+ "\u{1D5A9}"=>"J",
+ "\u{1D5AA}"=>"K",
+ "\u{1D5AB}"=>"L",
+ "\u{1D5AC}"=>"M",
+ "\u{1D5AD}"=>"N",
+ "\u{1D5AE}"=>"O",
+ "\u{1D5AF}"=>"P",
+ "\u{1D5B0}"=>"Q",
+ "\u{1D5B1}"=>"R",
+ "\u{1D5B2}"=>"S",
+ "\u{1D5B3}"=>"T",
+ "\u{1D5B4}"=>"U",
+ "\u{1D5B5}"=>"V",
+ "\u{1D5B6}"=>"W",
+ "\u{1D5B7}"=>"X",
+ "\u{1D5B8}"=>"Y",
+ "\u{1D5B9}"=>"Z",
+ "\u{1D5BA}"=>"a",
+ "\u{1D5BB}"=>"b",
+ "\u{1D5BC}"=>"c",
+ "\u{1D5BD}"=>"d",
+ "\u{1D5BE}"=>"e",
+ "\u{1D5BF}"=>"f",
+ "\u{1D5C0}"=>"g",
+ "\u{1D5C1}"=>"h",
+ "\u{1D5C2}"=>"i",
+ "\u{1D5C3}"=>"j",
+ "\u{1D5C4}"=>"k",
+ "\u{1D5C5}"=>"l",
+ "\u{1D5C6}"=>"m",
+ "\u{1D5C7}"=>"n",
+ "\u{1D5C8}"=>"o",
+ "\u{1D5C9}"=>"p",
+ "\u{1D5CA}"=>"q",
+ "\u{1D5CB}"=>"r",
+ "\u{1D5CC}"=>"s",
+ "\u{1D5CD}"=>"t",
+ "\u{1D5CE}"=>"u",
+ "\u{1D5CF}"=>"v",
+ "\u{1D5D0}"=>"w",
+ "\u{1D5D1}"=>"x",
+ "\u{1D5D2}"=>"y",
+ "\u{1D5D3}"=>"z",
+ "\u{1D5D4}"=>"A",
+ "\u{1D5D5}"=>"B",
+ "\u{1D5D6}"=>"C",
+ "\u{1D5D7}"=>"D",
+ "\u{1D5D8}"=>"E",
+ "\u{1D5D9}"=>"F",
+ "\u{1D5DA}"=>"G",
+ "\u{1D5DB}"=>"H",
+ "\u{1D5DC}"=>"I",
+ "\u{1D5DD}"=>"J",
+ "\u{1D5DE}"=>"K",
+ "\u{1D5DF}"=>"L",
+ "\u{1D5E0}"=>"M",
+ "\u{1D5E1}"=>"N",
+ "\u{1D5E2}"=>"O",
+ "\u{1D5E3}"=>"P",
+ "\u{1D5E4}"=>"Q",
+ "\u{1D5E5}"=>"R",
+ "\u{1D5E6}"=>"S",
+ "\u{1D5E7}"=>"T",
+ "\u{1D5E8}"=>"U",
+ "\u{1D5E9}"=>"V",
+ "\u{1D5EA}"=>"W",
+ "\u{1D5EB}"=>"X",
+ "\u{1D5EC}"=>"Y",
+ "\u{1D5ED}"=>"Z",
+ "\u{1D5EE}"=>"a",
+ "\u{1D5EF}"=>"b",
+ "\u{1D5F0}"=>"c",
+ "\u{1D5F1}"=>"d",
+ "\u{1D5F2}"=>"e",
+ "\u{1D5F3}"=>"f",
+ "\u{1D5F4}"=>"g",
+ "\u{1D5F5}"=>"h",
+ "\u{1D5F6}"=>"i",
+ "\u{1D5F7}"=>"j",
+ "\u{1D5F8}"=>"k",
+ "\u{1D5F9}"=>"l",
+ "\u{1D5FA}"=>"m",
+ "\u{1D5FB}"=>"n",
+ "\u{1D5FC}"=>"o",
+ "\u{1D5FD}"=>"p",
+ "\u{1D5FE}"=>"q",
+ "\u{1D5FF}"=>"r",
+ "\u{1D600}"=>"s",
+ "\u{1D601}"=>"t",
+ "\u{1D602}"=>"u",
+ "\u{1D603}"=>"v",
+ "\u{1D604}"=>"w",
+ "\u{1D605}"=>"x",
+ "\u{1D606}"=>"y",
+ "\u{1D607}"=>"z",
+ "\u{1D608}"=>"A",
+ "\u{1D609}"=>"B",
+ "\u{1D60A}"=>"C",
+ "\u{1D60B}"=>"D",
+ "\u{1D60C}"=>"E",
+ "\u{1D60D}"=>"F",
+ "\u{1D60E}"=>"G",
+ "\u{1D60F}"=>"H",
+ "\u{1D610}"=>"I",
+ "\u{1D611}"=>"J",
+ "\u{1D612}"=>"K",
+ "\u{1D613}"=>"L",
+ "\u{1D614}"=>"M",
+ "\u{1D615}"=>"N",
+ "\u{1D616}"=>"O",
+ "\u{1D617}"=>"P",
+ "\u{1D618}"=>"Q",
+ "\u{1D619}"=>"R",
+ "\u{1D61A}"=>"S",
+ "\u{1D61B}"=>"T",
+ "\u{1D61C}"=>"U",
+ "\u{1D61D}"=>"V",
+ "\u{1D61E}"=>"W",
+ "\u{1D61F}"=>"X",
+ "\u{1D620}"=>"Y",
+ "\u{1D621}"=>"Z",
+ "\u{1D622}"=>"a",
+ "\u{1D623}"=>"b",
+ "\u{1D624}"=>"c",
+ "\u{1D625}"=>"d",
+ "\u{1D626}"=>"e",
+ "\u{1D627}"=>"f",
+ "\u{1D628}"=>"g",
+ "\u{1D629}"=>"h",
+ "\u{1D62A}"=>"i",
+ "\u{1D62B}"=>"j",
+ "\u{1D62C}"=>"k",
+ "\u{1D62D}"=>"l",
+ "\u{1D62E}"=>"m",
+ "\u{1D62F}"=>"n",
+ "\u{1D630}"=>"o",
+ "\u{1D631}"=>"p",
+ "\u{1D632}"=>"q",
+ "\u{1D633}"=>"r",
+ "\u{1D634}"=>"s",
+ "\u{1D635}"=>"t",
+ "\u{1D636}"=>"u",
+ "\u{1D637}"=>"v",
+ "\u{1D638}"=>"w",
+ "\u{1D639}"=>"x",
+ "\u{1D63A}"=>"y",
+ "\u{1D63B}"=>"z",
+ "\u{1D63C}"=>"A",
+ "\u{1D63D}"=>"B",
+ "\u{1D63E}"=>"C",
+ "\u{1D63F}"=>"D",
+ "\u{1D640}"=>"E",
+ "\u{1D641}"=>"F",
+ "\u{1D642}"=>"G",
+ "\u{1D643}"=>"H",
+ "\u{1D644}"=>"I",
+ "\u{1D645}"=>"J",
+ "\u{1D646}"=>"K",
+ "\u{1D647}"=>"L",
+ "\u{1D648}"=>"M",
+ "\u{1D649}"=>"N",
+ "\u{1D64A}"=>"O",
+ "\u{1D64B}"=>"P",
+ "\u{1D64C}"=>"Q",
+ "\u{1D64D}"=>"R",
+ "\u{1D64E}"=>"S",
+ "\u{1D64F}"=>"T",
+ "\u{1D650}"=>"U",
+ "\u{1D651}"=>"V",
+ "\u{1D652}"=>"W",
+ "\u{1D653}"=>"X",
+ "\u{1D654}"=>"Y",
+ "\u{1D655}"=>"Z",
+ "\u{1D656}"=>"a",
+ "\u{1D657}"=>"b",
+ "\u{1D658}"=>"c",
+ "\u{1D659}"=>"d",
+ "\u{1D65A}"=>"e",
+ "\u{1D65B}"=>"f",
+ "\u{1D65C}"=>"g",
+ "\u{1D65D}"=>"h",
+ "\u{1D65E}"=>"i",
+ "\u{1D65F}"=>"j",
+ "\u{1D660}"=>"k",
+ "\u{1D661}"=>"l",
+ "\u{1D662}"=>"m",
+ "\u{1D663}"=>"n",
+ "\u{1D664}"=>"o",
+ "\u{1D665}"=>"p",
+ "\u{1D666}"=>"q",
+ "\u{1D667}"=>"r",
+ "\u{1D668}"=>"s",
+ "\u{1D669}"=>"t",
+ "\u{1D66A}"=>"u",
+ "\u{1D66B}"=>"v",
+ "\u{1D66C}"=>"w",
+ "\u{1D66D}"=>"x",
+ "\u{1D66E}"=>"y",
+ "\u{1D66F}"=>"z",
+ "\u{1D670}"=>"A",
+ "\u{1D671}"=>"B",
+ "\u{1D672}"=>"C",
+ "\u{1D673}"=>"D",
+ "\u{1D674}"=>"E",
+ "\u{1D675}"=>"F",
+ "\u{1D676}"=>"G",
+ "\u{1D677}"=>"H",
+ "\u{1D678}"=>"I",
+ "\u{1D679}"=>"J",
+ "\u{1D67A}"=>"K",
+ "\u{1D67B}"=>"L",
+ "\u{1D67C}"=>"M",
+ "\u{1D67D}"=>"N",
+ "\u{1D67E}"=>"O",
+ "\u{1D67F}"=>"P",
+ "\u{1D680}"=>"Q",
+ "\u{1D681}"=>"R",
+ "\u{1D682}"=>"S",
+ "\u{1D683}"=>"T",
+ "\u{1D684}"=>"U",
+ "\u{1D685}"=>"V",
+ "\u{1D686}"=>"W",
+ "\u{1D687}"=>"X",
+ "\u{1D688}"=>"Y",
+ "\u{1D689}"=>"Z",
+ "\u{1D68A}"=>"a",
+ "\u{1D68B}"=>"b",
+ "\u{1D68C}"=>"c",
+ "\u{1D68D}"=>"d",
+ "\u{1D68E}"=>"e",
+ "\u{1D68F}"=>"f",
+ "\u{1D690}"=>"g",
+ "\u{1D691}"=>"h",
+ "\u{1D692}"=>"i",
+ "\u{1D693}"=>"j",
+ "\u{1D694}"=>"k",
+ "\u{1D695}"=>"l",
+ "\u{1D696}"=>"m",
+ "\u{1D697}"=>"n",
+ "\u{1D698}"=>"o",
+ "\u{1D699}"=>"p",
+ "\u{1D69A}"=>"q",
+ "\u{1D69B}"=>"r",
+ "\u{1D69C}"=>"s",
+ "\u{1D69D}"=>"t",
+ "\u{1D69E}"=>"u",
+ "\u{1D69F}"=>"v",
+ "\u{1D6A0}"=>"w",
+ "\u{1D6A1}"=>"x",
+ "\u{1D6A2}"=>"y",
+ "\u{1D6A3}"=>"z",
+ "\u{1D6A4}"=>"\u0131",
+ "\u{1D6A5}"=>"\u0237",
+ "\u{1D6A8}"=>"\u0391",
+ "\u{1D6A9}"=>"\u0392",
+ "\u{1D6AA}"=>"\u0393",
+ "\u{1D6AB}"=>"\u0394",
+ "\u{1D6AC}"=>"\u0395",
+ "\u{1D6AD}"=>"\u0396",
+ "\u{1D6AE}"=>"\u0397",
+ "\u{1D6AF}"=>"\u0398",
+ "\u{1D6B0}"=>"\u0399",
+ "\u{1D6B1}"=>"\u039A",
+ "\u{1D6B2}"=>"\u039B",
+ "\u{1D6B3}"=>"\u039C",
+ "\u{1D6B4}"=>"\u039D",
+ "\u{1D6B5}"=>"\u039E",
+ "\u{1D6B6}"=>"\u039F",
+ "\u{1D6B7}"=>"\u03A0",
+ "\u{1D6B8}"=>"\u03A1",
+ "\u{1D6B9}"=>"\u0398",
+ "\u{1D6BA}"=>"\u03A3",
+ "\u{1D6BB}"=>"\u03A4",
+ "\u{1D6BC}"=>"\u03A5",
+ "\u{1D6BD}"=>"\u03A6",
+ "\u{1D6BE}"=>"\u03A7",
+ "\u{1D6BF}"=>"\u03A8",
+ "\u{1D6C0}"=>"\u03A9",
+ "\u{1D6C1}"=>"\u2207",
+ "\u{1D6C2}"=>"\u03B1",
+ "\u{1D6C3}"=>"\u03B2",
+ "\u{1D6C4}"=>"\u03B3",
+ "\u{1D6C5}"=>"\u03B4",
+ "\u{1D6C6}"=>"\u03B5",
+ "\u{1D6C7}"=>"\u03B6",
+ "\u{1D6C8}"=>"\u03B7",
+ "\u{1D6C9}"=>"\u03B8",
+ "\u{1D6CA}"=>"\u03B9",
+ "\u{1D6CB}"=>"\u03BA",
+ "\u{1D6CC}"=>"\u03BB",
+ "\u{1D6CD}"=>"\u03BC",
+ "\u{1D6CE}"=>"\u03BD",
+ "\u{1D6CF}"=>"\u03BE",
+ "\u{1D6D0}"=>"\u03BF",
+ "\u{1D6D1}"=>"\u03C0",
+ "\u{1D6D2}"=>"\u03C1",
+ "\u{1D6D3}"=>"\u03C2",
+ "\u{1D6D4}"=>"\u03C3",
+ "\u{1D6D5}"=>"\u03C4",
+ "\u{1D6D6}"=>"\u03C5",
+ "\u{1D6D7}"=>"\u03C6",
+ "\u{1D6D8}"=>"\u03C7",
+ "\u{1D6D9}"=>"\u03C8",
+ "\u{1D6DA}"=>"\u03C9",
+ "\u{1D6DB}"=>"\u2202",
+ "\u{1D6DC}"=>"\u03B5",
+ "\u{1D6DD}"=>"\u03B8",
+ "\u{1D6DE}"=>"\u03BA",
+ "\u{1D6DF}"=>"\u03C6",
+ "\u{1D6E0}"=>"\u03C1",
+ "\u{1D6E1}"=>"\u03C0",
+ "\u{1D6E2}"=>"\u0391",
+ "\u{1D6E3}"=>"\u0392",
+ "\u{1D6E4}"=>"\u0393",
+ "\u{1D6E5}"=>"\u0394",
+ "\u{1D6E6}"=>"\u0395",
+ "\u{1D6E7}"=>"\u0396",
+ "\u{1D6E8}"=>"\u0397",
+ "\u{1D6E9}"=>"\u0398",
+ "\u{1D6EA}"=>"\u0399",
+ "\u{1D6EB}"=>"\u039A",
+ "\u{1D6EC}"=>"\u039B",
+ "\u{1D6ED}"=>"\u039C",
+ "\u{1D6EE}"=>"\u039D",
+ "\u{1D6EF}"=>"\u039E",
+ "\u{1D6F0}"=>"\u039F",
+ "\u{1D6F1}"=>"\u03A0",
+ "\u{1D6F2}"=>"\u03A1",
+ "\u{1D6F3}"=>"\u0398",
+ "\u{1D6F4}"=>"\u03A3",
+ "\u{1D6F5}"=>"\u03A4",
+ "\u{1D6F6}"=>"\u03A5",
+ "\u{1D6F7}"=>"\u03A6",
+ "\u{1D6F8}"=>"\u03A7",
+ "\u{1D6F9}"=>"\u03A8",
+ "\u{1D6FA}"=>"\u03A9",
+ "\u{1D6FB}"=>"\u2207",
+ "\u{1D6FC}"=>"\u03B1",
+ "\u{1D6FD}"=>"\u03B2",
+ "\u{1D6FE}"=>"\u03B3",
+ "\u{1D6FF}"=>"\u03B4",
+ "\u{1D700}"=>"\u03B5",
+ "\u{1D701}"=>"\u03B6",
+ "\u{1D702}"=>"\u03B7",
+ "\u{1D703}"=>"\u03B8",
+ "\u{1D704}"=>"\u03B9",
+ "\u{1D705}"=>"\u03BA",
+ "\u{1D706}"=>"\u03BB",
+ "\u{1D707}"=>"\u03BC",
+ "\u{1D708}"=>"\u03BD",
+ "\u{1D709}"=>"\u03BE",
+ "\u{1D70A}"=>"\u03BF",
+ "\u{1D70B}"=>"\u03C0",
+ "\u{1D70C}"=>"\u03C1",
+ "\u{1D70D}"=>"\u03C2",
+ "\u{1D70E}"=>"\u03C3",
+ "\u{1D70F}"=>"\u03C4",
+ "\u{1D710}"=>"\u03C5",
+ "\u{1D711}"=>"\u03C6",
+ "\u{1D712}"=>"\u03C7",
+ "\u{1D713}"=>"\u03C8",
+ "\u{1D714}"=>"\u03C9",
+ "\u{1D715}"=>"\u2202",
+ "\u{1D716}"=>"\u03B5",
+ "\u{1D717}"=>"\u03B8",
+ "\u{1D718}"=>"\u03BA",
+ "\u{1D719}"=>"\u03C6",
+ "\u{1D71A}"=>"\u03C1",
+ "\u{1D71B}"=>"\u03C0",
+ "\u{1D71C}"=>"\u0391",
+ "\u{1D71D}"=>"\u0392",
+ "\u{1D71E}"=>"\u0393",
+ "\u{1D71F}"=>"\u0394",
+ "\u{1D720}"=>"\u0395",
+ "\u{1D721}"=>"\u0396",
+ "\u{1D722}"=>"\u0397",
+ "\u{1D723}"=>"\u0398",
+ "\u{1D724}"=>"\u0399",
+ "\u{1D725}"=>"\u039A",
+ "\u{1D726}"=>"\u039B",
+ "\u{1D727}"=>"\u039C",
+ "\u{1D728}"=>"\u039D",
+ "\u{1D729}"=>"\u039E",
+ "\u{1D72A}"=>"\u039F",
+ "\u{1D72B}"=>"\u03A0",
+ "\u{1D72C}"=>"\u03A1",
+ "\u{1D72D}"=>"\u0398",
+ "\u{1D72E}"=>"\u03A3",
+ "\u{1D72F}"=>"\u03A4",
+ "\u{1D730}"=>"\u03A5",
+ "\u{1D731}"=>"\u03A6",
+ "\u{1D732}"=>"\u03A7",
+ "\u{1D733}"=>"\u03A8",
+ "\u{1D734}"=>"\u03A9",
+ "\u{1D735}"=>"\u2207",
+ "\u{1D736}"=>"\u03B1",
+ "\u{1D737}"=>"\u03B2",
+ "\u{1D738}"=>"\u03B3",
+ "\u{1D739}"=>"\u03B4",
+ "\u{1D73A}"=>"\u03B5",
+ "\u{1D73B}"=>"\u03B6",
+ "\u{1D73C}"=>"\u03B7",
+ "\u{1D73D}"=>"\u03B8",
+ "\u{1D73E}"=>"\u03B9",
+ "\u{1D73F}"=>"\u03BA",
+ "\u{1D740}"=>"\u03BB",
+ "\u{1D741}"=>"\u03BC",
+ "\u{1D742}"=>"\u03BD",
+ "\u{1D743}"=>"\u03BE",
+ "\u{1D744}"=>"\u03BF",
+ "\u{1D745}"=>"\u03C0",
+ "\u{1D746}"=>"\u03C1",
+ "\u{1D747}"=>"\u03C2",
+ "\u{1D748}"=>"\u03C3",
+ "\u{1D749}"=>"\u03C4",
+ "\u{1D74A}"=>"\u03C5",
+ "\u{1D74B}"=>"\u03C6",
+ "\u{1D74C}"=>"\u03C7",
+ "\u{1D74D}"=>"\u03C8",
+ "\u{1D74E}"=>"\u03C9",
+ "\u{1D74F}"=>"\u2202",
+ "\u{1D750}"=>"\u03B5",
+ "\u{1D751}"=>"\u03B8",
+ "\u{1D752}"=>"\u03BA",
+ "\u{1D753}"=>"\u03C6",
+ "\u{1D754}"=>"\u03C1",
+ "\u{1D755}"=>"\u03C0",
+ "\u{1D756}"=>"\u0391",
+ "\u{1D757}"=>"\u0392",
+ "\u{1D758}"=>"\u0393",
+ "\u{1D759}"=>"\u0394",
+ "\u{1D75A}"=>"\u0395",
+ "\u{1D75B}"=>"\u0396",
+ "\u{1D75C}"=>"\u0397",
+ "\u{1D75D}"=>"\u0398",
+ "\u{1D75E}"=>"\u0399",
+ "\u{1D75F}"=>"\u039A",
+ "\u{1D760}"=>"\u039B",
+ "\u{1D761}"=>"\u039C",
+ "\u{1D762}"=>"\u039D",
+ "\u{1D763}"=>"\u039E",
+ "\u{1D764}"=>"\u039F",
+ "\u{1D765}"=>"\u03A0",
+ "\u{1D766}"=>"\u03A1",
+ "\u{1D767}"=>"\u0398",
+ "\u{1D768}"=>"\u03A3",
+ "\u{1D769}"=>"\u03A4",
+ "\u{1D76A}"=>"\u03A5",
+ "\u{1D76B}"=>"\u03A6",
+ "\u{1D76C}"=>"\u03A7",
+ "\u{1D76D}"=>"\u03A8",
+ "\u{1D76E}"=>"\u03A9",
+ "\u{1D76F}"=>"\u2207",
+ "\u{1D770}"=>"\u03B1",
+ "\u{1D771}"=>"\u03B2",
+ "\u{1D772}"=>"\u03B3",
+ "\u{1D773}"=>"\u03B4",
+ "\u{1D774}"=>"\u03B5",
+ "\u{1D775}"=>"\u03B6",
+ "\u{1D776}"=>"\u03B7",
+ "\u{1D777}"=>"\u03B8",
+ "\u{1D778}"=>"\u03B9",
+ "\u{1D779}"=>"\u03BA",
+ "\u{1D77A}"=>"\u03BB",
+ "\u{1D77B}"=>"\u03BC",
+ "\u{1D77C}"=>"\u03BD",
+ "\u{1D77D}"=>"\u03BE",
+ "\u{1D77E}"=>"\u03BF",
+ "\u{1D77F}"=>"\u03C0",
+ "\u{1D780}"=>"\u03C1",
+ "\u{1D781}"=>"\u03C2",
+ "\u{1D782}"=>"\u03C3",
+ "\u{1D783}"=>"\u03C4",
+ "\u{1D784}"=>"\u03C5",
+ "\u{1D785}"=>"\u03C6",
+ "\u{1D786}"=>"\u03C7",
+ "\u{1D787}"=>"\u03C8",
+ "\u{1D788}"=>"\u03C9",
+ "\u{1D789}"=>"\u2202",
+ "\u{1D78A}"=>"\u03B5",
+ "\u{1D78B}"=>"\u03B8",
+ "\u{1D78C}"=>"\u03BA",
+ "\u{1D78D}"=>"\u03C6",
+ "\u{1D78E}"=>"\u03C1",
+ "\u{1D78F}"=>"\u03C0",
+ "\u{1D790}"=>"\u0391",
+ "\u{1D791}"=>"\u0392",
+ "\u{1D792}"=>"\u0393",
+ "\u{1D793}"=>"\u0394",
+ "\u{1D794}"=>"\u0395",
+ "\u{1D795}"=>"\u0396",
+ "\u{1D796}"=>"\u0397",
+ "\u{1D797}"=>"\u0398",
+ "\u{1D798}"=>"\u0399",
+ "\u{1D799}"=>"\u039A",
+ "\u{1D79A}"=>"\u039B",
+ "\u{1D79B}"=>"\u039C",
+ "\u{1D79C}"=>"\u039D",
+ "\u{1D79D}"=>"\u039E",
+ "\u{1D79E}"=>"\u039F",
+ "\u{1D79F}"=>"\u03A0",
+ "\u{1D7A0}"=>"\u03A1",
+ "\u{1D7A1}"=>"\u0398",
+ "\u{1D7A2}"=>"\u03A3",
+ "\u{1D7A3}"=>"\u03A4",
+ "\u{1D7A4}"=>"\u03A5",
+ "\u{1D7A5}"=>"\u03A6",
+ "\u{1D7A6}"=>"\u03A7",
+ "\u{1D7A7}"=>"\u03A8",
+ "\u{1D7A8}"=>"\u03A9",
+ "\u{1D7A9}"=>"\u2207",
+ "\u{1D7AA}"=>"\u03B1",
+ "\u{1D7AB}"=>"\u03B2",
+ "\u{1D7AC}"=>"\u03B3",
+ "\u{1D7AD}"=>"\u03B4",
+ "\u{1D7AE}"=>"\u03B5",
+ "\u{1D7AF}"=>"\u03B6",
+ "\u{1D7B0}"=>"\u03B7",
+ "\u{1D7B1}"=>"\u03B8",
+ "\u{1D7B2}"=>"\u03B9",
+ "\u{1D7B3}"=>"\u03BA",
+ "\u{1D7B4}"=>"\u03BB",
+ "\u{1D7B5}"=>"\u03BC",
+ "\u{1D7B6}"=>"\u03BD",
+ "\u{1D7B7}"=>"\u03BE",
+ "\u{1D7B8}"=>"\u03BF",
+ "\u{1D7B9}"=>"\u03C0",
+ "\u{1D7BA}"=>"\u03C1",
+ "\u{1D7BB}"=>"\u03C2",
+ "\u{1D7BC}"=>"\u03C3",
+ "\u{1D7BD}"=>"\u03C4",
+ "\u{1D7BE}"=>"\u03C5",
+ "\u{1D7BF}"=>"\u03C6",
+ "\u{1D7C0}"=>"\u03C7",
+ "\u{1D7C1}"=>"\u03C8",
+ "\u{1D7C2}"=>"\u03C9",
+ "\u{1D7C3}"=>"\u2202",
+ "\u{1D7C4}"=>"\u03B5",
+ "\u{1D7C5}"=>"\u03B8",
+ "\u{1D7C6}"=>"\u03BA",
+ "\u{1D7C7}"=>"\u03C6",
+ "\u{1D7C8}"=>"\u03C1",
+ "\u{1D7C9}"=>"\u03C0",
+ "\u{1D7CA}"=>"\u03DC",
+ "\u{1D7CB}"=>"\u03DD",
+ "\u{1D7CE}"=>"0",
+ "\u{1D7CF}"=>"1",
+ "\u{1D7D0}"=>"2",
+ "\u{1D7D1}"=>"3",
+ "\u{1D7D2}"=>"4",
+ "\u{1D7D3}"=>"5",
+ "\u{1D7D4}"=>"6",
+ "\u{1D7D5}"=>"7",
+ "\u{1D7D6}"=>"8",
+ "\u{1D7D7}"=>"9",
+ "\u{1D7D8}"=>"0",
+ "\u{1D7D9}"=>"1",
+ "\u{1D7DA}"=>"2",
+ "\u{1D7DB}"=>"3",
+ "\u{1D7DC}"=>"4",
+ "\u{1D7DD}"=>"5",
+ "\u{1D7DE}"=>"6",
+ "\u{1D7DF}"=>"7",
+ "\u{1D7E0}"=>"8",
+ "\u{1D7E1}"=>"9",
+ "\u{1D7E2}"=>"0",
+ "\u{1D7E3}"=>"1",
+ "\u{1D7E4}"=>"2",
+ "\u{1D7E5}"=>"3",
+ "\u{1D7E6}"=>"4",
+ "\u{1D7E7}"=>"5",
+ "\u{1D7E8}"=>"6",
+ "\u{1D7E9}"=>"7",
+ "\u{1D7EA}"=>"8",
+ "\u{1D7EB}"=>"9",
+ "\u{1D7EC}"=>"0",
+ "\u{1D7ED}"=>"1",
+ "\u{1D7EE}"=>"2",
+ "\u{1D7EF}"=>"3",
+ "\u{1D7F0}"=>"4",
+ "\u{1D7F1}"=>"5",
+ "\u{1D7F2}"=>"6",
+ "\u{1D7F3}"=>"7",
+ "\u{1D7F4}"=>"8",
+ "\u{1D7F5}"=>"9",
+ "\u{1D7F6}"=>"0",
+ "\u{1D7F7}"=>"1",
+ "\u{1D7F8}"=>"2",
+ "\u{1D7F9}"=>"3",
+ "\u{1D7FA}"=>"4",
+ "\u{1D7FB}"=>"5",
+ "\u{1D7FC}"=>"6",
+ "\u{1D7FD}"=>"7",
+ "\u{1D7FE}"=>"8",
+ "\u{1D7FF}"=>"9",
+ "\u{1EE00}"=>"\u0627",
+ "\u{1EE01}"=>"\u0628",
+ "\u{1EE02}"=>"\u062C",
+ "\u{1EE03}"=>"\u062F",
+ "\u{1EE05}"=>"\u0648",
+ "\u{1EE06}"=>"\u0632",
+ "\u{1EE07}"=>"\u062D",
+ "\u{1EE08}"=>"\u0637",
+ "\u{1EE09}"=>"\u064A",
+ "\u{1EE0A}"=>"\u0643",
+ "\u{1EE0B}"=>"\u0644",
+ "\u{1EE0C}"=>"\u0645",
+ "\u{1EE0D}"=>"\u0646",
+ "\u{1EE0E}"=>"\u0633",
+ "\u{1EE0F}"=>"\u0639",
+ "\u{1EE10}"=>"\u0641",
+ "\u{1EE11}"=>"\u0635",
+ "\u{1EE12}"=>"\u0642",
+ "\u{1EE13}"=>"\u0631",
+ "\u{1EE14}"=>"\u0634",
+ "\u{1EE15}"=>"\u062A",
+ "\u{1EE16}"=>"\u062B",
+ "\u{1EE17}"=>"\u062E",
+ "\u{1EE18}"=>"\u0630",
+ "\u{1EE19}"=>"\u0636",
+ "\u{1EE1A}"=>"\u0638",
+ "\u{1EE1B}"=>"\u063A",
+ "\u{1EE1C}"=>"\u066E",
+ "\u{1EE1D}"=>"\u06BA",
+ "\u{1EE1E}"=>"\u06A1",
+ "\u{1EE1F}"=>"\u066F",
+ "\u{1EE21}"=>"\u0628",
+ "\u{1EE22}"=>"\u062C",
+ "\u{1EE24}"=>"\u0647",
+ "\u{1EE27}"=>"\u062D",
+ "\u{1EE29}"=>"\u064A",
+ "\u{1EE2A}"=>"\u0643",
+ "\u{1EE2B}"=>"\u0644",
+ "\u{1EE2C}"=>"\u0645",
+ "\u{1EE2D}"=>"\u0646",
+ "\u{1EE2E}"=>"\u0633",
+ "\u{1EE2F}"=>"\u0639",
+ "\u{1EE30}"=>"\u0641",
+ "\u{1EE31}"=>"\u0635",
+ "\u{1EE32}"=>"\u0642",
+ "\u{1EE34}"=>"\u0634",
+ "\u{1EE35}"=>"\u062A",
+ "\u{1EE36}"=>"\u062B",
+ "\u{1EE37}"=>"\u062E",
+ "\u{1EE39}"=>"\u0636",
+ "\u{1EE3B}"=>"\u063A",
+ "\u{1EE42}"=>"\u062C",
+ "\u{1EE47}"=>"\u062D",
+ "\u{1EE49}"=>"\u064A",
+ "\u{1EE4B}"=>"\u0644",
+ "\u{1EE4D}"=>"\u0646",
+ "\u{1EE4E}"=>"\u0633",
+ "\u{1EE4F}"=>"\u0639",
+ "\u{1EE51}"=>"\u0635",
+ "\u{1EE52}"=>"\u0642",
+ "\u{1EE54}"=>"\u0634",
+ "\u{1EE57}"=>"\u062E",
+ "\u{1EE59}"=>"\u0636",
+ "\u{1EE5B}"=>"\u063A",
+ "\u{1EE5D}"=>"\u06BA",
+ "\u{1EE5F}"=>"\u066F",
+ "\u{1EE61}"=>"\u0628",
+ "\u{1EE62}"=>"\u062C",
+ "\u{1EE64}"=>"\u0647",
+ "\u{1EE67}"=>"\u062D",
+ "\u{1EE68}"=>"\u0637",
+ "\u{1EE69}"=>"\u064A",
+ "\u{1EE6A}"=>"\u0643",
+ "\u{1EE6C}"=>"\u0645",
+ "\u{1EE6D}"=>"\u0646",
+ "\u{1EE6E}"=>"\u0633",
+ "\u{1EE6F}"=>"\u0639",
+ "\u{1EE70}"=>"\u0641",
+ "\u{1EE71}"=>"\u0635",
+ "\u{1EE72}"=>"\u0642",
+ "\u{1EE74}"=>"\u0634",
+ "\u{1EE75}"=>"\u062A",
+ "\u{1EE76}"=>"\u062B",
+ "\u{1EE77}"=>"\u062E",
+ "\u{1EE79}"=>"\u0636",
+ "\u{1EE7A}"=>"\u0638",
+ "\u{1EE7B}"=>"\u063A",
+ "\u{1EE7C}"=>"\u066E",
+ "\u{1EE7E}"=>"\u06A1",
+ "\u{1EE80}"=>"\u0627",
+ "\u{1EE81}"=>"\u0628",
+ "\u{1EE82}"=>"\u062C",
+ "\u{1EE83}"=>"\u062F",
+ "\u{1EE84}"=>"\u0647",
+ "\u{1EE85}"=>"\u0648",
+ "\u{1EE86}"=>"\u0632",
+ "\u{1EE87}"=>"\u062D",
+ "\u{1EE88}"=>"\u0637",
+ "\u{1EE89}"=>"\u064A",
+ "\u{1EE8B}"=>"\u0644",
+ "\u{1EE8C}"=>"\u0645",
+ "\u{1EE8D}"=>"\u0646",
+ "\u{1EE8E}"=>"\u0633",
+ "\u{1EE8F}"=>"\u0639",
+ "\u{1EE90}"=>"\u0641",
+ "\u{1EE91}"=>"\u0635",
+ "\u{1EE92}"=>"\u0642",
+ "\u{1EE93}"=>"\u0631",
+ "\u{1EE94}"=>"\u0634",
+ "\u{1EE95}"=>"\u062A",
+ "\u{1EE96}"=>"\u062B",
+ "\u{1EE97}"=>"\u062E",
+ "\u{1EE98}"=>"\u0630",
+ "\u{1EE99}"=>"\u0636",
+ "\u{1EE9A}"=>"\u0638",
+ "\u{1EE9B}"=>"\u063A",
+ "\u{1EEA1}"=>"\u0628",
+ "\u{1EEA2}"=>"\u062C",
+ "\u{1EEA3}"=>"\u062F",
+ "\u{1EEA5}"=>"\u0648",
+ "\u{1EEA6}"=>"\u0632",
+ "\u{1EEA7}"=>"\u062D",
+ "\u{1EEA8}"=>"\u0637",
+ "\u{1EEA9}"=>"\u064A",
+ "\u{1EEAB}"=>"\u0644",
+ "\u{1EEAC}"=>"\u0645",
+ "\u{1EEAD}"=>"\u0646",
+ "\u{1EEAE}"=>"\u0633",
+ "\u{1EEAF}"=>"\u0639",
+ "\u{1EEB0}"=>"\u0641",
+ "\u{1EEB1}"=>"\u0635",
+ "\u{1EEB2}"=>"\u0642",
+ "\u{1EEB3}"=>"\u0631",
+ "\u{1EEB4}"=>"\u0634",
+ "\u{1EEB5}"=>"\u062A",
+ "\u{1EEB6}"=>"\u062B",
+ "\u{1EEB7}"=>"\u062E",
+ "\u{1EEB8}"=>"\u0630",
+ "\u{1EEB9}"=>"\u0636",
+ "\u{1EEBA}"=>"\u0638",
+ "\u{1EEBB}"=>"\u063A",
+ "\u{1F100}"=>"0.",
+ "\u{1F101}"=>"0,",
+ "\u{1F102}"=>"1,",
+ "\u{1F103}"=>"2,",
+ "\u{1F104}"=>"3,",
+ "\u{1F105}"=>"4,",
+ "\u{1F106}"=>"5,",
+ "\u{1F107}"=>"6,",
+ "\u{1F108}"=>"7,",
+ "\u{1F109}"=>"8,",
+ "\u{1F10A}"=>"9,",
+ "\u{1F110}"=>"(A)",
+ "\u{1F111}"=>"(B)",
+ "\u{1F112}"=>"(C)",
+ "\u{1F113}"=>"(D)",
+ "\u{1F114}"=>"(E)",
+ "\u{1F115}"=>"(F)",
+ "\u{1F116}"=>"(G)",
+ "\u{1F117}"=>"(H)",
+ "\u{1F118}"=>"(I)",
+ "\u{1F119}"=>"(J)",
+ "\u{1F11A}"=>"(K)",
+ "\u{1F11B}"=>"(L)",
+ "\u{1F11C}"=>"(M)",
+ "\u{1F11D}"=>"(N)",
+ "\u{1F11E}"=>"(O)",
+ "\u{1F11F}"=>"(P)",
+ "\u{1F120}"=>"(Q)",
+ "\u{1F121}"=>"(R)",
+ "\u{1F122}"=>"(S)",
+ "\u{1F123}"=>"(T)",
+ "\u{1F124}"=>"(U)",
+ "\u{1F125}"=>"(V)",
+ "\u{1F126}"=>"(W)",
+ "\u{1F127}"=>"(X)",
+ "\u{1F128}"=>"(Y)",
+ "\u{1F129}"=>"(Z)",
+ "\u{1F12A}"=>"\u3014S\u3015",
+ "\u{1F12B}"=>"C",
+ "\u{1F12C}"=>"R",
+ "\u{1F12D}"=>"CD",
+ "\u{1F12E}"=>"WZ",
+ "\u{1F130}"=>"A",
+ "\u{1F131}"=>"B",
+ "\u{1F132}"=>"C",
+ "\u{1F133}"=>"D",
+ "\u{1F134}"=>"E",
+ "\u{1F135}"=>"F",
+ "\u{1F136}"=>"G",
+ "\u{1F137}"=>"H",
+ "\u{1F138}"=>"I",
+ "\u{1F139}"=>"J",
+ "\u{1F13A}"=>"K",
+ "\u{1F13B}"=>"L",
+ "\u{1F13C}"=>"M",
+ "\u{1F13D}"=>"N",
+ "\u{1F13E}"=>"O",
+ "\u{1F13F}"=>"P",
+ "\u{1F140}"=>"Q",
+ "\u{1F141}"=>"R",
+ "\u{1F142}"=>"S",
+ "\u{1F143}"=>"T",
+ "\u{1F144}"=>"U",
+ "\u{1F145}"=>"V",
+ "\u{1F146}"=>"W",
+ "\u{1F147}"=>"X",
+ "\u{1F148}"=>"Y",
+ "\u{1F149}"=>"Z",
+ "\u{1F14A}"=>"HV",
+ "\u{1F14B}"=>"MV",
+ "\u{1F14C}"=>"SD",
+ "\u{1F14D}"=>"SS",
+ "\u{1F14E}"=>"PPV",
+ "\u{1F14F}"=>"WC",
+ "\u{1F16A}"=>"MC",
+ "\u{1F16B}"=>"MD",
+ "\u{1F16C}"=>"MR",
+ "\u{1F190}"=>"DJ",
+ "\u{1F200}"=>"\u307B\u304B",
+ "\u{1F201}"=>"\u30B3\u30B3",
+ "\u{1F202}"=>"\u30B5",
+ "\u{1F210}"=>"\u624B",
+ "\u{1F211}"=>"\u5B57",
+ "\u{1F212}"=>"\u53CC",
+ "\u{1F213}"=>"\u30C7",
+ "\u{1F214}"=>"\u4E8C",
+ "\u{1F215}"=>"\u591A",
+ "\u{1F216}"=>"\u89E3",
+ "\u{1F217}"=>"\u5929",
+ "\u{1F218}"=>"\u4EA4",
+ "\u{1F219}"=>"\u6620",
+ "\u{1F21A}"=>"\u7121",
+ "\u{1F21B}"=>"\u6599",
+ "\u{1F21C}"=>"\u524D",
+ "\u{1F21D}"=>"\u5F8C",
+ "\u{1F21E}"=>"\u518D",
+ "\u{1F21F}"=>"\u65B0",
+ "\u{1F220}"=>"\u521D",
+ "\u{1F221}"=>"\u7D42",
+ "\u{1F222}"=>"\u751F",
+ "\u{1F223}"=>"\u8CA9",
+ "\u{1F224}"=>"\u58F0",
+ "\u{1F225}"=>"\u5439",
+ "\u{1F226}"=>"\u6F14",
+ "\u{1F227}"=>"\u6295",
+ "\u{1F228}"=>"\u6355",
+ "\u{1F229}"=>"\u4E00",
+ "\u{1F22A}"=>"\u4E09",
+ "\u{1F22B}"=>"\u904A",
+ "\u{1F22C}"=>"\u5DE6",
+ "\u{1F22D}"=>"\u4E2D",
+ "\u{1F22E}"=>"\u53F3",
+ "\u{1F22F}"=>"\u6307",
+ "\u{1F230}"=>"\u8D70",
+ "\u{1F231}"=>"\u6253",
+ "\u{1F232}"=>"\u7981",
+ "\u{1F233}"=>"\u7A7A",
+ "\u{1F234}"=>"\u5408",
+ "\u{1F235}"=>"\u6E80",
+ "\u{1F236}"=>"\u6709",
+ "\u{1F237}"=>"\u6708",
+ "\u{1F238}"=>"\u7533",
+ "\u{1F239}"=>"\u5272",
+ "\u{1F23A}"=>"\u55B6",
+ "\u{1F23B}"=>"\u914D",
+ "\u{1F240}"=>"\u3014\u672C\u3015",
+ "\u{1F241}"=>"\u3014\u4E09\u3015",
+ "\u{1F242}"=>"\u3014\u4E8C\u3015",
+ "\u{1F243}"=>"\u3014\u5B89\u3015",
+ "\u{1F244}"=>"\u3014\u70B9\u3015",
+ "\u{1F245}"=>"\u3014\u6253\u3015",
+ "\u{1F246}"=>"\u3014\u76D7\u3015",
+ "\u{1F247}"=>"\u3014\u52DD\u3015",
+ "\u{1F248}"=>"\u3014\u6557\u3015",
+ "\u{1F250}"=>"\u5F97",
+ "\u{1F251}"=>"\u53EF",
+ "\u0385"=>" \u0308\u0301",
+ "\u03D3"=>"\u03A5\u0301",
+ "\u03D4"=>"\u03A5\u0308",
+ "\u1E9B"=>"s\u0307",
+ "\u1FC1"=>" \u0308\u0342",
+ "\u1FCD"=>" \u0313\u0300",
+ "\u1FCE"=>" \u0313\u0301",
+ "\u1FCF"=>" \u0313\u0342",
+ "\u1FDD"=>" \u0314\u0300",
+ "\u1FDE"=>" \u0314\u0301",
+ "\u1FDF"=>" \u0314\u0342",
+ "\u1FED"=>" \u0308\u0300",
+ "\u1FEE"=>" \u0308\u0301",
+ "\u1FFD"=>" \u0301",
+ "\u2000"=>" ",
+ "\u2001"=>" ",
}.freeze
COMPOSITION_TABLE = {
- "A\u0300"=>"\u00C0", "A\u0301"=>"\u00C1", "A\u0302"=>"\u00C2", "A\u0303"=>"\u00C3", "A\u0308"=>"\u00C4", "A\u030A"=>"\u00C5", "C\u0327"=>"\u00C7", "E\u0300"=>"\u00C8",
- "E\u0301"=>"\u00C9", "E\u0302"=>"\u00CA", "E\u0308"=>"\u00CB", "I\u0300"=>"\u00CC", "I\u0301"=>"\u00CD", "I\u0302"=>"\u00CE", "I\u0308"=>"\u00CF", "N\u0303"=>"\u00D1",
- "O\u0300"=>"\u00D2", "O\u0301"=>"\u00D3", "O\u0302"=>"\u00D4", "O\u0303"=>"\u00D5", "O\u0308"=>"\u00D6", "U\u0300"=>"\u00D9", "U\u0301"=>"\u00DA", "U\u0302"=>"\u00DB",
- "U\u0308"=>"\u00DC", "Y\u0301"=>"\u00DD", "a\u0300"=>"\u00E0", "a\u0301"=>"\u00E1", "a\u0302"=>"\u00E2", "a\u0303"=>"\u00E3", "a\u0308"=>"\u00E4", "a\u030A"=>"\u00E5",
- "c\u0327"=>"\u00E7", "e\u0300"=>"\u00E8", "e\u0301"=>"\u00E9", "e\u0302"=>"\u00EA", "e\u0308"=>"\u00EB", "i\u0300"=>"\u00EC", "i\u0301"=>"\u00ED", "i\u0302"=>"\u00EE",
- "i\u0308"=>"\u00EF", "n\u0303"=>"\u00F1", "o\u0300"=>"\u00F2", "o\u0301"=>"\u00F3", "o\u0302"=>"\u00F4", "o\u0303"=>"\u00F5", "o\u0308"=>"\u00F6", "u\u0300"=>"\u00F9",
- "u\u0301"=>"\u00FA", "u\u0302"=>"\u00FB", "u\u0308"=>"\u00FC", "y\u0301"=>"\u00FD", "y\u0308"=>"\u00FF", "A\u0304"=>"\u0100", "a\u0304"=>"\u0101", "A\u0306"=>"\u0102",
- "a\u0306"=>"\u0103", "A\u0328"=>"\u0104", "a\u0328"=>"\u0105", "C\u0301"=>"\u0106", "c\u0301"=>"\u0107", "C\u0302"=>"\u0108", "c\u0302"=>"\u0109", "C\u0307"=>"\u010A",
- "c\u0307"=>"\u010B", "C\u030C"=>"\u010C", "c\u030C"=>"\u010D", "D\u030C"=>"\u010E", "d\u030C"=>"\u010F", "E\u0304"=>"\u0112", "e\u0304"=>"\u0113", "E\u0306"=>"\u0114",
- "e\u0306"=>"\u0115", "E\u0307"=>"\u0116", "e\u0307"=>"\u0117", "E\u0328"=>"\u0118", "e\u0328"=>"\u0119", "E\u030C"=>"\u011A", "e\u030C"=>"\u011B", "G\u0302"=>"\u011C",
- "g\u0302"=>"\u011D", "G\u0306"=>"\u011E", "g\u0306"=>"\u011F", "G\u0307"=>"\u0120", "g\u0307"=>"\u0121", "G\u0327"=>"\u0122", "g\u0327"=>"\u0123", "H\u0302"=>"\u0124",
- "h\u0302"=>"\u0125", "I\u0303"=>"\u0128", "i\u0303"=>"\u0129", "I\u0304"=>"\u012A", "i\u0304"=>"\u012B", "I\u0306"=>"\u012C", "i\u0306"=>"\u012D", "I\u0328"=>"\u012E",
- "i\u0328"=>"\u012F", "I\u0307"=>"\u0130", "J\u0302"=>"\u0134", "j\u0302"=>"\u0135", "K\u0327"=>"\u0136", "k\u0327"=>"\u0137", "L\u0301"=>"\u0139", "l\u0301"=>"\u013A",
- "L\u0327"=>"\u013B", "l\u0327"=>"\u013C", "L\u030C"=>"\u013D", "l\u030C"=>"\u013E", "N\u0301"=>"\u0143", "n\u0301"=>"\u0144", "N\u0327"=>"\u0145", "n\u0327"=>"\u0146",
- "N\u030C"=>"\u0147", "n\u030C"=>"\u0148", "O\u0304"=>"\u014C", "o\u0304"=>"\u014D", "O\u0306"=>"\u014E", "o\u0306"=>"\u014F", "O\u030B"=>"\u0150", "o\u030B"=>"\u0151",
- "R\u0301"=>"\u0154", "r\u0301"=>"\u0155", "R\u0327"=>"\u0156", "r\u0327"=>"\u0157", "R\u030C"=>"\u0158", "r\u030C"=>"\u0159", "S\u0301"=>"\u015A", "s\u0301"=>"\u015B",
- "S\u0302"=>"\u015C", "s\u0302"=>"\u015D", "S\u0327"=>"\u015E", "s\u0327"=>"\u015F", "S\u030C"=>"\u0160", "s\u030C"=>"\u0161", "T\u0327"=>"\u0162", "t\u0327"=>"\u0163",
- "T\u030C"=>"\u0164", "t\u030C"=>"\u0165", "U\u0303"=>"\u0168", "u\u0303"=>"\u0169", "U\u0304"=>"\u016A", "u\u0304"=>"\u016B", "U\u0306"=>"\u016C", "u\u0306"=>"\u016D",
- "U\u030A"=>"\u016E", "u\u030A"=>"\u016F", "U\u030B"=>"\u0170", "u\u030B"=>"\u0171", "U\u0328"=>"\u0172", "u\u0328"=>"\u0173", "W\u0302"=>"\u0174", "w\u0302"=>"\u0175",
- "Y\u0302"=>"\u0176", "y\u0302"=>"\u0177", "Y\u0308"=>"\u0178", "Z\u0301"=>"\u0179", "z\u0301"=>"\u017A", "Z\u0307"=>"\u017B", "z\u0307"=>"\u017C", "Z\u030C"=>"\u017D",
- "z\u030C"=>"\u017E", "O\u031B"=>"\u01A0", "o\u031B"=>"\u01A1", "U\u031B"=>"\u01AF", "u\u031B"=>"\u01B0", "A\u030C"=>"\u01CD", "a\u030C"=>"\u01CE", "I\u030C"=>"\u01CF",
- "i\u030C"=>"\u01D0", "O\u030C"=>"\u01D1", "o\u030C"=>"\u01D2", "U\u030C"=>"\u01D3", "u\u030C"=>"\u01D4", "\u00DC\u0304"=>"\u01D5", "\u00FC\u0304"=>"\u01D6", "\u00DC\u0301"=>"\u01D7",
- "\u00FC\u0301"=>"\u01D8", "\u00DC\u030C"=>"\u01D9", "\u00FC\u030C"=>"\u01DA", "\u00DC\u0300"=>"\u01DB", "\u00FC\u0300"=>"\u01DC", "\u00C4\u0304"=>"\u01DE", "\u00E4\u0304"=>"\u01DF", "\u0226\u0304"=>"\u01E0",
- "\u0227\u0304"=>"\u01E1", "\u00C6\u0304"=>"\u01E2", "\u00E6\u0304"=>"\u01E3", "G\u030C"=>"\u01E6", "g\u030C"=>"\u01E7", "K\u030C"=>"\u01E8", "k\u030C"=>"\u01E9", "O\u0328"=>"\u01EA",
- "o\u0328"=>"\u01EB", "\u01EA\u0304"=>"\u01EC", "\u01EB\u0304"=>"\u01ED", "\u01B7\u030C"=>"\u01EE", "\u0292\u030C"=>"\u01EF", "j\u030C"=>"\u01F0", "G\u0301"=>"\u01F4", "g\u0301"=>"\u01F5",
- "N\u0300"=>"\u01F8", "n\u0300"=>"\u01F9", "\u00C5\u0301"=>"\u01FA", "\u00E5\u0301"=>"\u01FB", "\u00C6\u0301"=>"\u01FC", "\u00E6\u0301"=>"\u01FD", "\u00D8\u0301"=>"\u01FE", "\u00F8\u0301"=>"\u01FF",
- "A\u030F"=>"\u0200", "a\u030F"=>"\u0201", "A\u0311"=>"\u0202", "a\u0311"=>"\u0203", "E\u030F"=>"\u0204", "e\u030F"=>"\u0205", "E\u0311"=>"\u0206", "e\u0311"=>"\u0207",
- "I\u030F"=>"\u0208", "i\u030F"=>"\u0209", "I\u0311"=>"\u020A", "i\u0311"=>"\u020B", "O\u030F"=>"\u020C", "o\u030F"=>"\u020D", "O\u0311"=>"\u020E", "o\u0311"=>"\u020F",
- "R\u030F"=>"\u0210", "r\u030F"=>"\u0211", "R\u0311"=>"\u0212", "r\u0311"=>"\u0213", "U\u030F"=>"\u0214", "u\u030F"=>"\u0215", "U\u0311"=>"\u0216", "u\u0311"=>"\u0217",
- "S\u0326"=>"\u0218", "s\u0326"=>"\u0219", "T\u0326"=>"\u021A", "t\u0326"=>"\u021B", "H\u030C"=>"\u021E", "h\u030C"=>"\u021F", "A\u0307"=>"\u0226", "a\u0307"=>"\u0227",
- "E\u0327"=>"\u0228", "e\u0327"=>"\u0229", "\u00D6\u0304"=>"\u022A", "\u00F6\u0304"=>"\u022B", "\u00D5\u0304"=>"\u022C", "\u00F5\u0304"=>"\u022D", "O\u0307"=>"\u022E", "o\u0307"=>"\u022F",
- "\u022E\u0304"=>"\u0230", "\u022F\u0304"=>"\u0231", "Y\u0304"=>"\u0232", "y\u0304"=>"\u0233", "\u00A8\u0301"=>"\u0385", "\u0391\u0301"=>"\u0386", "\u0395\u0301"=>"\u0388", "\u0397\u0301"=>"\u0389",
- "\u0399\u0301"=>"\u038A", "\u039F\u0301"=>"\u038C", "\u03A5\u0301"=>"\u038E", "\u03A9\u0301"=>"\u038F", "\u03CA\u0301"=>"\u0390", "\u0399\u0308"=>"\u03AA", "\u03A5\u0308"=>"\u03AB", "\u03B1\u0301"=>"\u03AC",
- "\u03B5\u0301"=>"\u03AD", "\u03B7\u0301"=>"\u03AE", "\u03B9\u0301"=>"\u03AF", "\u03CB\u0301"=>"\u03B0", "\u03B9\u0308"=>"\u03CA", "\u03C5\u0308"=>"\u03CB", "\u03BF\u0301"=>"\u03CC", "\u03C5\u0301"=>"\u03CD",
- "\u03C9\u0301"=>"\u03CE", "\u03D2\u0301"=>"\u03D3", "\u03D2\u0308"=>"\u03D4", "\u0415\u0300"=>"\u0400", "\u0415\u0308"=>"\u0401", "\u0413\u0301"=>"\u0403", "\u0406\u0308"=>"\u0407", "\u041A\u0301"=>"\u040C",
- "\u0418\u0300"=>"\u040D", "\u0423\u0306"=>"\u040E", "\u0418\u0306"=>"\u0419", "\u0438\u0306"=>"\u0439", "\u0435\u0300"=>"\u0450", "\u0435\u0308"=>"\u0451", "\u0433\u0301"=>"\u0453", "\u0456\u0308"=>"\u0457",
- "\u043A\u0301"=>"\u045C", "\u0438\u0300"=>"\u045D", "\u0443\u0306"=>"\u045E", "\u0474\u030F"=>"\u0476", "\u0475\u030F"=>"\u0477", "\u0416\u0306"=>"\u04C1", "\u0436\u0306"=>"\u04C2", "\u0410\u0306"=>"\u04D0",
- "\u0430\u0306"=>"\u04D1", "\u0410\u0308"=>"\u04D2", "\u0430\u0308"=>"\u04D3", "\u0415\u0306"=>"\u04D6", "\u0435\u0306"=>"\u04D7", "\u04D8\u0308"=>"\u04DA", "\u04D9\u0308"=>"\u04DB", "\u0416\u0308"=>"\u04DC",
- "\u0436\u0308"=>"\u04DD", "\u0417\u0308"=>"\u04DE", "\u0437\u0308"=>"\u04DF", "\u0418\u0304"=>"\u04E2", "\u0438\u0304"=>"\u04E3", "\u0418\u0308"=>"\u04E4", "\u0438\u0308"=>"\u04E5", "\u041E\u0308"=>"\u04E6",
- "\u043E\u0308"=>"\u04E7", "\u04E8\u0308"=>"\u04EA", "\u04E9\u0308"=>"\u04EB", "\u042D\u0308"=>"\u04EC", "\u044D\u0308"=>"\u04ED", "\u0423\u0304"=>"\u04EE", "\u0443\u0304"=>"\u04EF", "\u0423\u0308"=>"\u04F0",
- "\u0443\u0308"=>"\u04F1", "\u0423\u030B"=>"\u04F2", "\u0443\u030B"=>"\u04F3", "\u0427\u0308"=>"\u04F4", "\u0447\u0308"=>"\u04F5", "\u042B\u0308"=>"\u04F8", "\u044B\u0308"=>"\u04F9", "\u0627\u0653"=>"\u0622",
- "\u0627\u0654"=>"\u0623", "\u0648\u0654"=>"\u0624", "\u0627\u0655"=>"\u0625", "\u064A\u0654"=>"\u0626", "\u06D5\u0654"=>"\u06C0", "\u06C1\u0654"=>"\u06C2", "\u06D2\u0654"=>"\u06D3", "\u0928\u093C"=>"\u0929",
- "\u0930\u093C"=>"\u0931", "\u0933\u093C"=>"\u0934", "\u09C7\u09BE"=>"\u09CB", "\u09C7\u09D7"=>"\u09CC", "\u0B47\u0B56"=>"\u0B48", "\u0B47\u0B3E"=>"\u0B4B", "\u0B47\u0B57"=>"\u0B4C", "\u0B92\u0BD7"=>"\u0B94",
- "\u0BC6\u0BBE"=>"\u0BCA", "\u0BC7\u0BBE"=>"\u0BCB", "\u0BC6\u0BD7"=>"\u0BCC", "\u0C46\u0C56"=>"\u0C48", "\u0CBF\u0CD5"=>"\u0CC0", "\u0CC6\u0CD5"=>"\u0CC7", "\u0CC6\u0CD6"=>"\u0CC8", "\u0CC6\u0CC2"=>"\u0CCA",
- "\u0CCA\u0CD5"=>"\u0CCB", "\u0D46\u0D3E"=>"\u0D4A", "\u0D47\u0D3E"=>"\u0D4B", "\u0D46\u0D57"=>"\u0D4C", "\u0DD9\u0DCA"=>"\u0DDA", "\u0DD9\u0DCF"=>"\u0DDC", "\u0DDC\u0DCA"=>"\u0DDD", "\u0DD9\u0DDF"=>"\u0DDE",
- "\u1025\u102E"=>"\u1026", "\u1B05\u1B35"=>"\u1B06", "\u1B07\u1B35"=>"\u1B08", "\u1B09\u1B35"=>"\u1B0A", "\u1B0B\u1B35"=>"\u1B0C", "\u1B0D\u1B35"=>"\u1B0E", "\u1B11\u1B35"=>"\u1B12", "\u1B3A\u1B35"=>"\u1B3B",
- "\u1B3C\u1B35"=>"\u1B3D", "\u1B3E\u1B35"=>"\u1B40", "\u1B3F\u1B35"=>"\u1B41", "\u1B42\u1B35"=>"\u1B43", "A\u0325"=>"\u1E00", "a\u0325"=>"\u1E01", "B\u0307"=>"\u1E02", "b\u0307"=>"\u1E03",
- "B\u0323"=>"\u1E04", "b\u0323"=>"\u1E05", "B\u0331"=>"\u1E06", "b\u0331"=>"\u1E07", "\u00C7\u0301"=>"\u1E08", "\u00E7\u0301"=>"\u1E09", "D\u0307"=>"\u1E0A", "d\u0307"=>"\u1E0B",
- "D\u0323"=>"\u1E0C", "d\u0323"=>"\u1E0D", "D\u0331"=>"\u1E0E", "d\u0331"=>"\u1E0F", "D\u0327"=>"\u1E10", "d\u0327"=>"\u1E11", "D\u032D"=>"\u1E12", "d\u032D"=>"\u1E13",
- "\u0112\u0300"=>"\u1E14", "\u0113\u0300"=>"\u1E15", "\u0112\u0301"=>"\u1E16", "\u0113\u0301"=>"\u1E17", "E\u032D"=>"\u1E18", "e\u032D"=>"\u1E19", "E\u0330"=>"\u1E1A", "e\u0330"=>"\u1E1B",
- "\u0228\u0306"=>"\u1E1C", "\u0229\u0306"=>"\u1E1D", "F\u0307"=>"\u1E1E", "f\u0307"=>"\u1E1F", "G\u0304"=>"\u1E20", "g\u0304"=>"\u1E21", "H\u0307"=>"\u1E22", "h\u0307"=>"\u1E23",
- "H\u0323"=>"\u1E24", "h\u0323"=>"\u1E25", "H\u0308"=>"\u1E26", "h\u0308"=>"\u1E27", "H\u0327"=>"\u1E28", "h\u0327"=>"\u1E29", "H\u032E"=>"\u1E2A", "h\u032E"=>"\u1E2B",
- "I\u0330"=>"\u1E2C", "i\u0330"=>"\u1E2D", "\u00CF\u0301"=>"\u1E2E", "\u00EF\u0301"=>"\u1E2F", "K\u0301"=>"\u1E30", "k\u0301"=>"\u1E31", "K\u0323"=>"\u1E32", "k\u0323"=>"\u1E33",
- "K\u0331"=>"\u1E34", "k\u0331"=>"\u1E35", "L\u0323"=>"\u1E36", "l\u0323"=>"\u1E37", "\u1E36\u0304"=>"\u1E38", "\u1E37\u0304"=>"\u1E39", "L\u0331"=>"\u1E3A", "l\u0331"=>"\u1E3B",
- "L\u032D"=>"\u1E3C", "l\u032D"=>"\u1E3D", "M\u0301"=>"\u1E3E", "m\u0301"=>"\u1E3F", "M\u0307"=>"\u1E40", "m\u0307"=>"\u1E41", "M\u0323"=>"\u1E42", "m\u0323"=>"\u1E43",
- "N\u0307"=>"\u1E44", "n\u0307"=>"\u1E45", "N\u0323"=>"\u1E46", "n\u0323"=>"\u1E47", "N\u0331"=>"\u1E48", "n\u0331"=>"\u1E49", "N\u032D"=>"\u1E4A", "n\u032D"=>"\u1E4B",
- "\u00D5\u0301"=>"\u1E4C", "\u00F5\u0301"=>"\u1E4D", "\u00D5\u0308"=>"\u1E4E", "\u00F5\u0308"=>"\u1E4F", "\u014C\u0300"=>"\u1E50", "\u014D\u0300"=>"\u1E51", "\u014C\u0301"=>"\u1E52", "\u014D\u0301"=>"\u1E53",
- "P\u0301"=>"\u1E54", "p\u0301"=>"\u1E55", "P\u0307"=>"\u1E56", "p\u0307"=>"\u1E57", "R\u0307"=>"\u1E58", "r\u0307"=>"\u1E59", "R\u0323"=>"\u1E5A", "r\u0323"=>"\u1E5B",
- "\u1E5A\u0304"=>"\u1E5C", "\u1E5B\u0304"=>"\u1E5D", "R\u0331"=>"\u1E5E", "r\u0331"=>"\u1E5F", "S\u0307"=>"\u1E60", "s\u0307"=>"\u1E61", "S\u0323"=>"\u1E62", "s\u0323"=>"\u1E63",
- "\u015A\u0307"=>"\u1E64", "\u015B\u0307"=>"\u1E65", "\u0160\u0307"=>"\u1E66", "\u0161\u0307"=>"\u1E67", "\u1E62\u0307"=>"\u1E68", "\u1E63\u0307"=>"\u1E69", "T\u0307"=>"\u1E6A", "t\u0307"=>"\u1E6B",
- "T\u0323"=>"\u1E6C", "t\u0323"=>"\u1E6D", "T\u0331"=>"\u1E6E", "t\u0331"=>"\u1E6F", "T\u032D"=>"\u1E70", "t\u032D"=>"\u1E71", "U\u0324"=>"\u1E72", "u\u0324"=>"\u1E73",
- "U\u0330"=>"\u1E74", "u\u0330"=>"\u1E75", "U\u032D"=>"\u1E76", "u\u032D"=>"\u1E77", "\u0168\u0301"=>"\u1E78", "\u0169\u0301"=>"\u1E79", "\u016A\u0308"=>"\u1E7A", "\u016B\u0308"=>"\u1E7B",
- "V\u0303"=>"\u1E7C", "v\u0303"=>"\u1E7D", "V\u0323"=>"\u1E7E", "v\u0323"=>"\u1E7F", "W\u0300"=>"\u1E80", "w\u0300"=>"\u1E81", "W\u0301"=>"\u1E82", "w\u0301"=>"\u1E83",
- "W\u0308"=>"\u1E84", "w\u0308"=>"\u1E85", "W\u0307"=>"\u1E86", "w\u0307"=>"\u1E87", "W\u0323"=>"\u1E88", "w\u0323"=>"\u1E89", "X\u0307"=>"\u1E8A", "x\u0307"=>"\u1E8B",
- "X\u0308"=>"\u1E8C", "x\u0308"=>"\u1E8D", "Y\u0307"=>"\u1E8E", "y\u0307"=>"\u1E8F", "Z\u0302"=>"\u1E90", "z\u0302"=>"\u1E91", "Z\u0323"=>"\u1E92", "z\u0323"=>"\u1E93",
- "Z\u0331"=>"\u1E94", "z\u0331"=>"\u1E95", "h\u0331"=>"\u1E96", "t\u0308"=>"\u1E97", "w\u030A"=>"\u1E98", "y\u030A"=>"\u1E99", "\u017F\u0307"=>"\u1E9B", "A\u0323"=>"\u1EA0",
- "a\u0323"=>"\u1EA1", "A\u0309"=>"\u1EA2", "a\u0309"=>"\u1EA3", "\u00C2\u0301"=>"\u1EA4", "\u00E2\u0301"=>"\u1EA5", "\u00C2\u0300"=>"\u1EA6", "\u00E2\u0300"=>"\u1EA7", "\u00C2\u0309"=>"\u1EA8",
- "\u00E2\u0309"=>"\u1EA9", "\u00C2\u0303"=>"\u1EAA", "\u00E2\u0303"=>"\u1EAB", "\u1EA0\u0302"=>"\u1EAC", "\u1EA1\u0302"=>"\u1EAD", "\u0102\u0301"=>"\u1EAE", "\u0103\u0301"=>"\u1EAF", "\u0102\u0300"=>"\u1EB0",
- "\u0103\u0300"=>"\u1EB1", "\u0102\u0309"=>"\u1EB2", "\u0103\u0309"=>"\u1EB3", "\u0102\u0303"=>"\u1EB4", "\u0103\u0303"=>"\u1EB5", "\u1EA0\u0306"=>"\u1EB6", "\u1EA1\u0306"=>"\u1EB7", "E\u0323"=>"\u1EB8",
- "e\u0323"=>"\u1EB9", "E\u0309"=>"\u1EBA", "e\u0309"=>"\u1EBB", "E\u0303"=>"\u1EBC", "e\u0303"=>"\u1EBD", "\u00CA\u0301"=>"\u1EBE", "\u00EA\u0301"=>"\u1EBF", "\u00CA\u0300"=>"\u1EC0",
- "\u00EA\u0300"=>"\u1EC1", "\u00CA\u0309"=>"\u1EC2", "\u00EA\u0309"=>"\u1EC3", "\u00CA\u0303"=>"\u1EC4", "\u00EA\u0303"=>"\u1EC5", "\u1EB8\u0302"=>"\u1EC6", "\u1EB9\u0302"=>"\u1EC7", "I\u0309"=>"\u1EC8",
- "i\u0309"=>"\u1EC9", "I\u0323"=>"\u1ECA", "i\u0323"=>"\u1ECB", "O\u0323"=>"\u1ECC", "o\u0323"=>"\u1ECD", "O\u0309"=>"\u1ECE", "o\u0309"=>"\u1ECF", "\u00D4\u0301"=>"\u1ED0",
- "\u00F4\u0301"=>"\u1ED1", "\u00D4\u0300"=>"\u1ED2", "\u00F4\u0300"=>"\u1ED3", "\u00D4\u0309"=>"\u1ED4", "\u00F4\u0309"=>"\u1ED5", "\u00D4\u0303"=>"\u1ED6", "\u00F4\u0303"=>"\u1ED7", "\u1ECC\u0302"=>"\u1ED8",
- "\u1ECD\u0302"=>"\u1ED9", "\u01A0\u0301"=>"\u1EDA", "\u01A1\u0301"=>"\u1EDB", "\u01A0\u0300"=>"\u1EDC", "\u01A1\u0300"=>"\u1EDD", "\u01A0\u0309"=>"\u1EDE", "\u01A1\u0309"=>"\u1EDF", "\u01A0\u0303"=>"\u1EE0",
- "\u01A1\u0303"=>"\u1EE1", "\u01A0\u0323"=>"\u1EE2", "\u01A1\u0323"=>"\u1EE3", "U\u0323"=>"\u1EE4", "u\u0323"=>"\u1EE5", "U\u0309"=>"\u1EE6", "u\u0309"=>"\u1EE7", "\u01AF\u0301"=>"\u1EE8",
- "\u01B0\u0301"=>"\u1EE9", "\u01AF\u0300"=>"\u1EEA", "\u01B0\u0300"=>"\u1EEB", "\u01AF\u0309"=>"\u1EEC", "\u01B0\u0309"=>"\u1EED", "\u01AF\u0303"=>"\u1EEE", "\u01B0\u0303"=>"\u1EEF", "\u01AF\u0323"=>"\u1EF0",
- "\u01B0\u0323"=>"\u1EF1", "Y\u0300"=>"\u1EF2", "y\u0300"=>"\u1EF3", "Y\u0323"=>"\u1EF4", "y\u0323"=>"\u1EF5", "Y\u0309"=>"\u1EF6", "y\u0309"=>"\u1EF7", "Y\u0303"=>"\u1EF8",
- "y\u0303"=>"\u1EF9", "\u03B1\u0313"=>"\u1F00", "\u03B1\u0314"=>"\u1F01", "\u1F00\u0300"=>"\u1F02", "\u1F01\u0300"=>"\u1F03", "\u1F00\u0301"=>"\u1F04", "\u1F01\u0301"=>"\u1F05", "\u1F00\u0342"=>"\u1F06",
- "\u1F01\u0342"=>"\u1F07", "\u0391\u0313"=>"\u1F08", "\u0391\u0314"=>"\u1F09", "\u1F08\u0300"=>"\u1F0A", "\u1F09\u0300"=>"\u1F0B", "\u1F08\u0301"=>"\u1F0C", "\u1F09\u0301"=>"\u1F0D", "\u1F08\u0342"=>"\u1F0E",
- "\u1F09\u0342"=>"\u1F0F", "\u03B5\u0313"=>"\u1F10", "\u03B5\u0314"=>"\u1F11", "\u1F10\u0300"=>"\u1F12", "\u1F11\u0300"=>"\u1F13", "\u1F10\u0301"=>"\u1F14", "\u1F11\u0301"=>"\u1F15", "\u0395\u0313"=>"\u1F18",
- "\u0395\u0314"=>"\u1F19", "\u1F18\u0300"=>"\u1F1A", "\u1F19\u0300"=>"\u1F1B", "\u1F18\u0301"=>"\u1F1C", "\u1F19\u0301"=>"\u1F1D", "\u03B7\u0313"=>"\u1F20", "\u03B7\u0314"=>"\u1F21", "\u1F20\u0300"=>"\u1F22",
- "\u1F21\u0300"=>"\u1F23", "\u1F20\u0301"=>"\u1F24", "\u1F21\u0301"=>"\u1F25", "\u1F20\u0342"=>"\u1F26", "\u1F21\u0342"=>"\u1F27", "\u0397\u0313"=>"\u1F28", "\u0397\u0314"=>"\u1F29", "\u1F28\u0300"=>"\u1F2A",
- "\u1F29\u0300"=>"\u1F2B", "\u1F28\u0301"=>"\u1F2C", "\u1F29\u0301"=>"\u1F2D", "\u1F28\u0342"=>"\u1F2E", "\u1F29\u0342"=>"\u1F2F", "\u03B9\u0313"=>"\u1F30", "\u03B9\u0314"=>"\u1F31", "\u1F30\u0300"=>"\u1F32",
- "\u1F31\u0300"=>"\u1F33", "\u1F30\u0301"=>"\u1F34", "\u1F31\u0301"=>"\u1F35", "\u1F30\u0342"=>"\u1F36", "\u1F31\u0342"=>"\u1F37", "\u0399\u0313"=>"\u1F38", "\u0399\u0314"=>"\u1F39", "\u1F38\u0300"=>"\u1F3A",
- "\u1F39\u0300"=>"\u1F3B", "\u1F38\u0301"=>"\u1F3C", "\u1F39\u0301"=>"\u1F3D", "\u1F38\u0342"=>"\u1F3E", "\u1F39\u0342"=>"\u1F3F", "\u03BF\u0313"=>"\u1F40", "\u03BF\u0314"=>"\u1F41", "\u1F40\u0300"=>"\u1F42",
- "\u1F41\u0300"=>"\u1F43", "\u1F40\u0301"=>"\u1F44", "\u1F41\u0301"=>"\u1F45", "\u039F\u0313"=>"\u1F48", "\u039F\u0314"=>"\u1F49", "\u1F48\u0300"=>"\u1F4A", "\u1F49\u0300"=>"\u1F4B", "\u1F48\u0301"=>"\u1F4C",
- "\u1F49\u0301"=>"\u1F4D", "\u03C5\u0313"=>"\u1F50", "\u03C5\u0314"=>"\u1F51", "\u1F50\u0300"=>"\u1F52", "\u1F51\u0300"=>"\u1F53", "\u1F50\u0301"=>"\u1F54", "\u1F51\u0301"=>"\u1F55", "\u1F50\u0342"=>"\u1F56",
- "\u1F51\u0342"=>"\u1F57", "\u03A5\u0314"=>"\u1F59", "\u1F59\u0300"=>"\u1F5B", "\u1F59\u0301"=>"\u1F5D", "\u1F59\u0342"=>"\u1F5F", "\u03C9\u0313"=>"\u1F60", "\u03C9\u0314"=>"\u1F61", "\u1F60\u0300"=>"\u1F62",
- "\u1F61\u0300"=>"\u1F63", "\u1F60\u0301"=>"\u1F64", "\u1F61\u0301"=>"\u1F65", "\u1F60\u0342"=>"\u1F66", "\u1F61\u0342"=>"\u1F67", "\u03A9\u0313"=>"\u1F68", "\u03A9\u0314"=>"\u1F69", "\u1F68\u0300"=>"\u1F6A",
- "\u1F69\u0300"=>"\u1F6B", "\u1F68\u0301"=>"\u1F6C", "\u1F69\u0301"=>"\u1F6D", "\u1F68\u0342"=>"\u1F6E", "\u1F69\u0342"=>"\u1F6F", "\u03B1\u0300"=>"\u1F70", "\u03B5\u0300"=>"\u1F72", "\u03B7\u0300"=>"\u1F74",
- "\u03B9\u0300"=>"\u1F76", "\u03BF\u0300"=>"\u1F78", "\u03C5\u0300"=>"\u1F7A", "\u03C9\u0300"=>"\u1F7C", "\u1F00\u0345"=>"\u1F80", "\u1F01\u0345"=>"\u1F81", "\u1F02\u0345"=>"\u1F82", "\u1F03\u0345"=>"\u1F83",
- "\u1F04\u0345"=>"\u1F84", "\u1F05\u0345"=>"\u1F85", "\u1F06\u0345"=>"\u1F86", "\u1F07\u0345"=>"\u1F87", "\u1F08\u0345"=>"\u1F88", "\u1F09\u0345"=>"\u1F89", "\u1F0A\u0345"=>"\u1F8A", "\u1F0B\u0345"=>"\u1F8B",
- "\u1F0C\u0345"=>"\u1F8C", "\u1F0D\u0345"=>"\u1F8D", "\u1F0E\u0345"=>"\u1F8E", "\u1F0F\u0345"=>"\u1F8F", "\u1F20\u0345"=>"\u1F90", "\u1F21\u0345"=>"\u1F91", "\u1F22\u0345"=>"\u1F92", "\u1F23\u0345"=>"\u1F93",
- "\u1F24\u0345"=>"\u1F94", "\u1F25\u0345"=>"\u1F95", "\u1F26\u0345"=>"\u1F96", "\u1F27\u0345"=>"\u1F97", "\u1F28\u0345"=>"\u1F98", "\u1F29\u0345"=>"\u1F99", "\u1F2A\u0345"=>"\u1F9A", "\u1F2B\u0345"=>"\u1F9B",
- "\u1F2C\u0345"=>"\u1F9C", "\u1F2D\u0345"=>"\u1F9D", "\u1F2E\u0345"=>"\u1F9E", "\u1F2F\u0345"=>"\u1F9F", "\u1F60\u0345"=>"\u1FA0", "\u1F61\u0345"=>"\u1FA1", "\u1F62\u0345"=>"\u1FA2", "\u1F63\u0345"=>"\u1FA3",
- "\u1F64\u0345"=>"\u1FA4", "\u1F65\u0345"=>"\u1FA5", "\u1F66\u0345"=>"\u1FA6", "\u1F67\u0345"=>"\u1FA7", "\u1F68\u0345"=>"\u1FA8", "\u1F69\u0345"=>"\u1FA9", "\u1F6A\u0345"=>"\u1FAA", "\u1F6B\u0345"=>"\u1FAB",
- "\u1F6C\u0345"=>"\u1FAC", "\u1F6D\u0345"=>"\u1FAD", "\u1F6E\u0345"=>"\u1FAE", "\u1F6F\u0345"=>"\u1FAF", "\u03B1\u0306"=>"\u1FB0", "\u03B1\u0304"=>"\u1FB1", "\u1F70\u0345"=>"\u1FB2", "\u03B1\u0345"=>"\u1FB3",
- "\u03AC\u0345"=>"\u1FB4", "\u03B1\u0342"=>"\u1FB6", "\u1FB6\u0345"=>"\u1FB7", "\u0391\u0306"=>"\u1FB8", "\u0391\u0304"=>"\u1FB9", "\u0391\u0300"=>"\u1FBA", "\u0391\u0345"=>"\u1FBC", "\u00A8\u0342"=>"\u1FC1",
- "\u1F74\u0345"=>"\u1FC2", "\u03B7\u0345"=>"\u1FC3", "\u03AE\u0345"=>"\u1FC4", "\u03B7\u0342"=>"\u1FC6", "\u1FC6\u0345"=>"\u1FC7", "\u0395\u0300"=>"\u1FC8", "\u0397\u0300"=>"\u1FCA", "\u0397\u0345"=>"\u1FCC",
- "\u1FBF\u0300"=>"\u1FCD", "\u1FBF\u0301"=>"\u1FCE", "\u1FBF\u0342"=>"\u1FCF", "\u03B9\u0306"=>"\u1FD0", "\u03B9\u0304"=>"\u1FD1", "\u03CA\u0300"=>"\u1FD2", "\u03B9\u0342"=>"\u1FD6", "\u03CA\u0342"=>"\u1FD7",
- "\u0399\u0306"=>"\u1FD8", "\u0399\u0304"=>"\u1FD9", "\u0399\u0300"=>"\u1FDA", "\u1FFE\u0300"=>"\u1FDD", "\u1FFE\u0301"=>"\u1FDE", "\u1FFE\u0342"=>"\u1FDF", "\u03C5\u0306"=>"\u1FE0", "\u03C5\u0304"=>"\u1FE1",
- "\u03CB\u0300"=>"\u1FE2", "\u03C1\u0313"=>"\u1FE4", "\u03C1\u0314"=>"\u1FE5", "\u03C5\u0342"=>"\u1FE6", "\u03CB\u0342"=>"\u1FE7", "\u03A5\u0306"=>"\u1FE8", "\u03A5\u0304"=>"\u1FE9", "\u03A5\u0300"=>"\u1FEA",
- "\u03A1\u0314"=>"\u1FEC", "\u00A8\u0300"=>"\u1FED", "\u1F7C\u0345"=>"\u1FF2", "\u03C9\u0345"=>"\u1FF3", "\u03CE\u0345"=>"\u1FF4", "\u03C9\u0342"=>"\u1FF6", "\u1FF6\u0345"=>"\u1FF7", "\u039F\u0300"=>"\u1FF8",
- "\u03A9\u0300"=>"\u1FFA", "\u03A9\u0345"=>"\u1FFC", "\u2190\u0338"=>"\u219A", "\u2192\u0338"=>"\u219B", "\u2194\u0338"=>"\u21AE", "\u21D0\u0338"=>"\u21CD", "\u21D4\u0338"=>"\u21CE", "\u21D2\u0338"=>"\u21CF",
- "\u2203\u0338"=>"\u2204", "\u2208\u0338"=>"\u2209", "\u220B\u0338"=>"\u220C", "\u2223\u0338"=>"\u2224", "\u2225\u0338"=>"\u2226", "\u223C\u0338"=>"\u2241", "\u2243\u0338"=>"\u2244", "\u2245\u0338"=>"\u2247",
- "\u2248\u0338"=>"\u2249", "=\u0338"=>"\u2260", "\u2261\u0338"=>"\u2262", "\u224D\u0338"=>"\u226D", "<\u0338"=>"\u226E", ">\u0338"=>"\u226F", "\u2264\u0338"=>"\u2270", "\u2265\u0338"=>"\u2271",
- "\u2272\u0338"=>"\u2274", "\u2273\u0338"=>"\u2275", "\u2276\u0338"=>"\u2278", "\u2277\u0338"=>"\u2279", "\u227A\u0338"=>"\u2280", "\u227B\u0338"=>"\u2281", "\u2282\u0338"=>"\u2284", "\u2283\u0338"=>"\u2285",
- "\u2286\u0338"=>"\u2288", "\u2287\u0338"=>"\u2289", "\u22A2\u0338"=>"\u22AC", "\u22A8\u0338"=>"\u22AD", "\u22A9\u0338"=>"\u22AE", "\u22AB\u0338"=>"\u22AF", "\u227C\u0338"=>"\u22E0", "\u227D\u0338"=>"\u22E1",
- "\u2291\u0338"=>"\u22E2", "\u2292\u0338"=>"\u22E3", "\u22B2\u0338"=>"\u22EA", "\u22B3\u0338"=>"\u22EB", "\u22B4\u0338"=>"\u22EC", "\u22B5\u0338"=>"\u22ED", "\u304B\u3099"=>"\u304C", "\u304D\u3099"=>"\u304E",
- "\u304F\u3099"=>"\u3050", "\u3051\u3099"=>"\u3052", "\u3053\u3099"=>"\u3054", "\u3055\u3099"=>"\u3056", "\u3057\u3099"=>"\u3058", "\u3059\u3099"=>"\u305A", "\u305B\u3099"=>"\u305C", "\u305D\u3099"=>"\u305E",
- "\u305F\u3099"=>"\u3060", "\u3061\u3099"=>"\u3062", "\u3064\u3099"=>"\u3065", "\u3066\u3099"=>"\u3067", "\u3068\u3099"=>"\u3069", "\u306F\u3099"=>"\u3070", "\u306F\u309A"=>"\u3071", "\u3072\u3099"=>"\u3073",
- "\u3072\u309A"=>"\u3074", "\u3075\u3099"=>"\u3076", "\u3075\u309A"=>"\u3077", "\u3078\u3099"=>"\u3079", "\u3078\u309A"=>"\u307A", "\u307B\u3099"=>"\u307C", "\u307B\u309A"=>"\u307D", "\u3046\u3099"=>"\u3094",
- "\u309D\u3099"=>"\u309E", "\u30AB\u3099"=>"\u30AC", "\u30AD\u3099"=>"\u30AE", "\u30AF\u3099"=>"\u30B0", "\u30B1\u3099"=>"\u30B2", "\u30B3\u3099"=>"\u30B4", "\u30B5\u3099"=>"\u30B6", "\u30B7\u3099"=>"\u30B8",
- "\u30B9\u3099"=>"\u30BA", "\u30BB\u3099"=>"\u30BC", "\u30BD\u3099"=>"\u30BE", "\u30BF\u3099"=>"\u30C0", "\u30C1\u3099"=>"\u30C2", "\u30C4\u3099"=>"\u30C5", "\u30C6\u3099"=>"\u30C7", "\u30C8\u3099"=>"\u30C9",
- "\u30CF\u3099"=>"\u30D0", "\u30CF\u309A"=>"\u30D1", "\u30D2\u3099"=>"\u30D3", "\u30D2\u309A"=>"\u30D4", "\u30D5\u3099"=>"\u30D6", "\u30D5\u309A"=>"\u30D7", "\u30D8\u3099"=>"\u30D9", "\u30D8\u309A"=>"\u30DA",
- "\u30DB\u3099"=>"\u30DC", "\u30DB\u309A"=>"\u30DD", "\u30A6\u3099"=>"\u30F4", "\u30EF\u3099"=>"\u30F7", "\u30F0\u3099"=>"\u30F8", "\u30F1\u3099"=>"\u30F9", "\u30F2\u3099"=>"\u30FA", "\u30FD\u3099"=>"\u30FE",
- "\u{11099}\u{110BA}"=>"\u{1109A}", "\u{1109B}\u{110BA}"=>"\u{1109C}", "\u{110A5}\u{110BA}"=>"\u{110AB}", "\u{11131}\u{11127}"=>"\u{1112E}", "\u{11132}\u{11127}"=>"\u{1112F}", "\u{11347}\u{1133E}"=>"\u{1134B}", "\u{11347}\u{11357}"=>"\u{1134C}", "\u{114B9}\u{114BA}"=>"\u{114BB}",
- "\u{114B9}\u{114B0}"=>"\u{114BC}", "\u{114B9}\u{114BD}"=>"\u{114BE}", "\u{115B8}\u{115AF}"=>"\u{115BA}", "\u{115B9}\u{115AF}"=>"\u{115BB}",
+ "A\u0300"=>"\u00C0",
+ "A\u0301"=>"\u00C1",
+ "A\u0302"=>"\u00C2",
+ "A\u0303"=>"\u00C3",
+ "A\u0308"=>"\u00C4",
+ "A\u030A"=>"\u00C5",
+ "C\u0327"=>"\u00C7",
+ "E\u0300"=>"\u00C8",
+ "E\u0301"=>"\u00C9",
+ "E\u0302"=>"\u00CA",
+ "E\u0308"=>"\u00CB",
+ "I\u0300"=>"\u00CC",
+ "I\u0301"=>"\u00CD",
+ "I\u0302"=>"\u00CE",
+ "I\u0308"=>"\u00CF",
+ "N\u0303"=>"\u00D1",
+ "O\u0300"=>"\u00D2",
+ "O\u0301"=>"\u00D3",
+ "O\u0302"=>"\u00D4",
+ "O\u0303"=>"\u00D5",
+ "O\u0308"=>"\u00D6",
+ "U\u0300"=>"\u00D9",
+ "U\u0301"=>"\u00DA",
+ "U\u0302"=>"\u00DB",
+ "U\u0308"=>"\u00DC",
+ "Y\u0301"=>"\u00DD",
+ "a\u0300"=>"\u00E0",
+ "a\u0301"=>"\u00E1",
+ "a\u0302"=>"\u00E2",
+ "a\u0303"=>"\u00E3",
+ "a\u0308"=>"\u00E4",
+ "a\u030A"=>"\u00E5",
+ "c\u0327"=>"\u00E7",
+ "e\u0300"=>"\u00E8",
+ "e\u0301"=>"\u00E9",
+ "e\u0302"=>"\u00EA",
+ "e\u0308"=>"\u00EB",
+ "i\u0300"=>"\u00EC",
+ "i\u0301"=>"\u00ED",
+ "i\u0302"=>"\u00EE",
+ "i\u0308"=>"\u00EF",
+ "n\u0303"=>"\u00F1",
+ "o\u0300"=>"\u00F2",
+ "o\u0301"=>"\u00F3",
+ "o\u0302"=>"\u00F4",
+ "o\u0303"=>"\u00F5",
+ "o\u0308"=>"\u00F6",
+ "u\u0300"=>"\u00F9",
+ "u\u0301"=>"\u00FA",
+ "u\u0302"=>"\u00FB",
+ "u\u0308"=>"\u00FC",
+ "y\u0301"=>"\u00FD",
+ "y\u0308"=>"\u00FF",
+ "A\u0304"=>"\u0100",
+ "a\u0304"=>"\u0101",
+ "A\u0306"=>"\u0102",
+ "a\u0306"=>"\u0103",
+ "A\u0328"=>"\u0104",
+ "a\u0328"=>"\u0105",
+ "C\u0301"=>"\u0106",
+ "c\u0301"=>"\u0107",
+ "C\u0302"=>"\u0108",
+ "c\u0302"=>"\u0109",
+ "C\u0307"=>"\u010A",
+ "c\u0307"=>"\u010B",
+ "C\u030C"=>"\u010C",
+ "c\u030C"=>"\u010D",
+ "D\u030C"=>"\u010E",
+ "d\u030C"=>"\u010F",
+ "E\u0304"=>"\u0112",
+ "e\u0304"=>"\u0113",
+ "E\u0306"=>"\u0114",
+ "e\u0306"=>"\u0115",
+ "E\u0307"=>"\u0116",
+ "e\u0307"=>"\u0117",
+ "E\u0328"=>"\u0118",
+ "e\u0328"=>"\u0119",
+ "E\u030C"=>"\u011A",
+ "e\u030C"=>"\u011B",
+ "G\u0302"=>"\u011C",
+ "g\u0302"=>"\u011D",
+ "G\u0306"=>"\u011E",
+ "g\u0306"=>"\u011F",
+ "G\u0307"=>"\u0120",
+ "g\u0307"=>"\u0121",
+ "G\u0327"=>"\u0122",
+ "g\u0327"=>"\u0123",
+ "H\u0302"=>"\u0124",
+ "h\u0302"=>"\u0125",
+ "I\u0303"=>"\u0128",
+ "i\u0303"=>"\u0129",
+ "I\u0304"=>"\u012A",
+ "i\u0304"=>"\u012B",
+ "I\u0306"=>"\u012C",
+ "i\u0306"=>"\u012D",
+ "I\u0328"=>"\u012E",
+ "i\u0328"=>"\u012F",
+ "I\u0307"=>"\u0130",
+ "J\u0302"=>"\u0134",
+ "j\u0302"=>"\u0135",
+ "K\u0327"=>"\u0136",
+ "k\u0327"=>"\u0137",
+ "L\u0301"=>"\u0139",
+ "l\u0301"=>"\u013A",
+ "L\u0327"=>"\u013B",
+ "l\u0327"=>"\u013C",
+ "L\u030C"=>"\u013D",
+ "l\u030C"=>"\u013E",
+ "N\u0301"=>"\u0143",
+ "n\u0301"=>"\u0144",
+ "N\u0327"=>"\u0145",
+ "n\u0327"=>"\u0146",
+ "N\u030C"=>"\u0147",
+ "n\u030C"=>"\u0148",
+ "O\u0304"=>"\u014C",
+ "o\u0304"=>"\u014D",
+ "O\u0306"=>"\u014E",
+ "o\u0306"=>"\u014F",
+ "O\u030B"=>"\u0150",
+ "o\u030B"=>"\u0151",
+ "R\u0301"=>"\u0154",
+ "r\u0301"=>"\u0155",
+ "R\u0327"=>"\u0156",
+ "r\u0327"=>"\u0157",
+ "R\u030C"=>"\u0158",
+ "r\u030C"=>"\u0159",
+ "S\u0301"=>"\u015A",
+ "s\u0301"=>"\u015B",
+ "S\u0302"=>"\u015C",
+ "s\u0302"=>"\u015D",
+ "S\u0327"=>"\u015E",
+ "s\u0327"=>"\u015F",
+ "S\u030C"=>"\u0160",
+ "s\u030C"=>"\u0161",
+ "T\u0327"=>"\u0162",
+ "t\u0327"=>"\u0163",
+ "T\u030C"=>"\u0164",
+ "t\u030C"=>"\u0165",
+ "U\u0303"=>"\u0168",
+ "u\u0303"=>"\u0169",
+ "U\u0304"=>"\u016A",
+ "u\u0304"=>"\u016B",
+ "U\u0306"=>"\u016C",
+ "u\u0306"=>"\u016D",
+ "U\u030A"=>"\u016E",
+ "u\u030A"=>"\u016F",
+ "U\u030B"=>"\u0170",
+ "u\u030B"=>"\u0171",
+ "U\u0328"=>"\u0172",
+ "u\u0328"=>"\u0173",
+ "W\u0302"=>"\u0174",
+ "w\u0302"=>"\u0175",
+ "Y\u0302"=>"\u0176",
+ "y\u0302"=>"\u0177",
+ "Y\u0308"=>"\u0178",
+ "Z\u0301"=>"\u0179",
+ "z\u0301"=>"\u017A",
+ "Z\u0307"=>"\u017B",
+ "z\u0307"=>"\u017C",
+ "Z\u030C"=>"\u017D",
+ "z\u030C"=>"\u017E",
+ "O\u031B"=>"\u01A0",
+ "o\u031B"=>"\u01A1",
+ "U\u031B"=>"\u01AF",
+ "u\u031B"=>"\u01B0",
+ "A\u030C"=>"\u01CD",
+ "a\u030C"=>"\u01CE",
+ "I\u030C"=>"\u01CF",
+ "i\u030C"=>"\u01D0",
+ "O\u030C"=>"\u01D1",
+ "o\u030C"=>"\u01D2",
+ "U\u030C"=>"\u01D3",
+ "u\u030C"=>"\u01D4",
+ "\u00DC\u0304"=>"\u01D5",
+ "\u00FC\u0304"=>"\u01D6",
+ "\u00DC\u0301"=>"\u01D7",
+ "\u00FC\u0301"=>"\u01D8",
+ "\u00DC\u030C"=>"\u01D9",
+ "\u00FC\u030C"=>"\u01DA",
+ "\u00DC\u0300"=>"\u01DB",
+ "\u00FC\u0300"=>"\u01DC",
+ "\u00C4\u0304"=>"\u01DE",
+ "\u00E4\u0304"=>"\u01DF",
+ "\u0226\u0304"=>"\u01E0",
+ "\u0227\u0304"=>"\u01E1",
+ "\u00C6\u0304"=>"\u01E2",
+ "\u00E6\u0304"=>"\u01E3",
+ "G\u030C"=>"\u01E6",
+ "g\u030C"=>"\u01E7",
+ "K\u030C"=>"\u01E8",
+ "k\u030C"=>"\u01E9",
+ "O\u0328"=>"\u01EA",
+ "o\u0328"=>"\u01EB",
+ "\u01EA\u0304"=>"\u01EC",
+ "\u01EB\u0304"=>"\u01ED",
+ "\u01B7\u030C"=>"\u01EE",
+ "\u0292\u030C"=>"\u01EF",
+ "j\u030C"=>"\u01F0",
+ "G\u0301"=>"\u01F4",
+ "g\u0301"=>"\u01F5",
+ "N\u0300"=>"\u01F8",
+ "n\u0300"=>"\u01F9",
+ "\u00C5\u0301"=>"\u01FA",
+ "\u00E5\u0301"=>"\u01FB",
+ "\u00C6\u0301"=>"\u01FC",
+ "\u00E6\u0301"=>"\u01FD",
+ "\u00D8\u0301"=>"\u01FE",
+ "\u00F8\u0301"=>"\u01FF",
+ "A\u030F"=>"\u0200",
+ "a\u030F"=>"\u0201",
+ "A\u0311"=>"\u0202",
+ "a\u0311"=>"\u0203",
+ "E\u030F"=>"\u0204",
+ "e\u030F"=>"\u0205",
+ "E\u0311"=>"\u0206",
+ "e\u0311"=>"\u0207",
+ "I\u030F"=>"\u0208",
+ "i\u030F"=>"\u0209",
+ "I\u0311"=>"\u020A",
+ "i\u0311"=>"\u020B",
+ "O\u030F"=>"\u020C",
+ "o\u030F"=>"\u020D",
+ "O\u0311"=>"\u020E",
+ "o\u0311"=>"\u020F",
+ "R\u030F"=>"\u0210",
+ "r\u030F"=>"\u0211",
+ "R\u0311"=>"\u0212",
+ "r\u0311"=>"\u0213",
+ "U\u030F"=>"\u0214",
+ "u\u030F"=>"\u0215",
+ "U\u0311"=>"\u0216",
+ "u\u0311"=>"\u0217",
+ "S\u0326"=>"\u0218",
+ "s\u0326"=>"\u0219",
+ "T\u0326"=>"\u021A",
+ "t\u0326"=>"\u021B",
+ "H\u030C"=>"\u021E",
+ "h\u030C"=>"\u021F",
+ "A\u0307"=>"\u0226",
+ "a\u0307"=>"\u0227",
+ "E\u0327"=>"\u0228",
+ "e\u0327"=>"\u0229",
+ "\u00D6\u0304"=>"\u022A",
+ "\u00F6\u0304"=>"\u022B",
+ "\u00D5\u0304"=>"\u022C",
+ "\u00F5\u0304"=>"\u022D",
+ "O\u0307"=>"\u022E",
+ "o\u0307"=>"\u022F",
+ "\u022E\u0304"=>"\u0230",
+ "\u022F\u0304"=>"\u0231",
+ "Y\u0304"=>"\u0232",
+ "y\u0304"=>"\u0233",
+ "\u00A8\u0301"=>"\u0385",
+ "\u0391\u0301"=>"\u0386",
+ "\u0395\u0301"=>"\u0388",
+ "\u0397\u0301"=>"\u0389",
+ "\u0399\u0301"=>"\u038A",
+ "\u039F\u0301"=>"\u038C",
+ "\u03A5\u0301"=>"\u038E",
+ "\u03A9\u0301"=>"\u038F",
+ "\u03CA\u0301"=>"\u0390",
+ "\u0399\u0308"=>"\u03AA",
+ "\u03A5\u0308"=>"\u03AB",
+ "\u03B1\u0301"=>"\u03AC",
+ "\u03B5\u0301"=>"\u03AD",
+ "\u03B7\u0301"=>"\u03AE",
+ "\u03B9\u0301"=>"\u03AF",
+ "\u03CB\u0301"=>"\u03B0",
+ "\u03B9\u0308"=>"\u03CA",
+ "\u03C5\u0308"=>"\u03CB",
+ "\u03BF\u0301"=>"\u03CC",
+ "\u03C5\u0301"=>"\u03CD",
+ "\u03C9\u0301"=>"\u03CE",
+ "\u03D2\u0301"=>"\u03D3",
+ "\u03D2\u0308"=>"\u03D4",
+ "\u0415\u0300"=>"\u0400",
+ "\u0415\u0308"=>"\u0401",
+ "\u0413\u0301"=>"\u0403",
+ "\u0406\u0308"=>"\u0407",
+ "\u041A\u0301"=>"\u040C",
+ "\u0418\u0300"=>"\u040D",
+ "\u0423\u0306"=>"\u040E",
+ "\u0418\u0306"=>"\u0419",
+ "\u0438\u0306"=>"\u0439",
+ "\u0435\u0300"=>"\u0450",
+ "\u0435\u0308"=>"\u0451",
+ "\u0433\u0301"=>"\u0453",
+ "\u0456\u0308"=>"\u0457",
+ "\u043A\u0301"=>"\u045C",
+ "\u0438\u0300"=>"\u045D",
+ "\u0443\u0306"=>"\u045E",
+ "\u0474\u030F"=>"\u0476",
+ "\u0475\u030F"=>"\u0477",
+ "\u0416\u0306"=>"\u04C1",
+ "\u0436\u0306"=>"\u04C2",
+ "\u0410\u0306"=>"\u04D0",
+ "\u0430\u0306"=>"\u04D1",
+ "\u0410\u0308"=>"\u04D2",
+ "\u0430\u0308"=>"\u04D3",
+ "\u0415\u0306"=>"\u04D6",
+ "\u0435\u0306"=>"\u04D7",
+ "\u04D8\u0308"=>"\u04DA",
+ "\u04D9\u0308"=>"\u04DB",
+ "\u0416\u0308"=>"\u04DC",
+ "\u0436\u0308"=>"\u04DD",
+ "\u0417\u0308"=>"\u04DE",
+ "\u0437\u0308"=>"\u04DF",
+ "\u0418\u0304"=>"\u04E2",
+ "\u0438\u0304"=>"\u04E3",
+ "\u0418\u0308"=>"\u04E4",
+ "\u0438\u0308"=>"\u04E5",
+ "\u041E\u0308"=>"\u04E6",
+ "\u043E\u0308"=>"\u04E7",
+ "\u04E8\u0308"=>"\u04EA",
+ "\u04E9\u0308"=>"\u04EB",
+ "\u042D\u0308"=>"\u04EC",
+ "\u044D\u0308"=>"\u04ED",
+ "\u0423\u0304"=>"\u04EE",
+ "\u0443\u0304"=>"\u04EF",
+ "\u0423\u0308"=>"\u04F0",
+ "\u0443\u0308"=>"\u04F1",
+ "\u0423\u030B"=>"\u04F2",
+ "\u0443\u030B"=>"\u04F3",
+ "\u0427\u0308"=>"\u04F4",
+ "\u0447\u0308"=>"\u04F5",
+ "\u042B\u0308"=>"\u04F8",
+ "\u044B\u0308"=>"\u04F9",
+ "\u0627\u0653"=>"\u0622",
+ "\u0627\u0654"=>"\u0623",
+ "\u0648\u0654"=>"\u0624",
+ "\u0627\u0655"=>"\u0625",
+ "\u064A\u0654"=>"\u0626",
+ "\u06D5\u0654"=>"\u06C0",
+ "\u06C1\u0654"=>"\u06C2",
+ "\u06D2\u0654"=>"\u06D3",
+ "\u0928\u093C"=>"\u0929",
+ "\u0930\u093C"=>"\u0931",
+ "\u0933\u093C"=>"\u0934",
+ "\u09C7\u09BE"=>"\u09CB",
+ "\u09C7\u09D7"=>"\u09CC",
+ "\u0B47\u0B56"=>"\u0B48",
+ "\u0B47\u0B3E"=>"\u0B4B",
+ "\u0B47\u0B57"=>"\u0B4C",
+ "\u0B92\u0BD7"=>"\u0B94",
+ "\u0BC6\u0BBE"=>"\u0BCA",
+ "\u0BC7\u0BBE"=>"\u0BCB",
+ "\u0BC6\u0BD7"=>"\u0BCC",
+ "\u0C46\u0C56"=>"\u0C48",
+ "\u0CBF\u0CD5"=>"\u0CC0",
+ "\u0CC6\u0CD5"=>"\u0CC7",
+ "\u0CC6\u0CD6"=>"\u0CC8",
+ "\u0CC6\u0CC2"=>"\u0CCA",
+ "\u0CCA\u0CD5"=>"\u0CCB",
+ "\u0D46\u0D3E"=>"\u0D4A",
+ "\u0D47\u0D3E"=>"\u0D4B",
+ "\u0D46\u0D57"=>"\u0D4C",
+ "\u0DD9\u0DCA"=>"\u0DDA",
+ "\u0DD9\u0DCF"=>"\u0DDC",
+ "\u0DDC\u0DCA"=>"\u0DDD",
+ "\u0DD9\u0DDF"=>"\u0DDE",
+ "\u1025\u102E"=>"\u1026",
+ "\u1B05\u1B35"=>"\u1B06",
+ "\u1B07\u1B35"=>"\u1B08",
+ "\u1B09\u1B35"=>"\u1B0A",
+ "\u1B0B\u1B35"=>"\u1B0C",
+ "\u1B0D\u1B35"=>"\u1B0E",
+ "\u1B11\u1B35"=>"\u1B12",
+ "\u1B3A\u1B35"=>"\u1B3B",
+ "\u1B3C\u1B35"=>"\u1B3D",
+ "\u1B3E\u1B35"=>"\u1B40",
+ "\u1B3F\u1B35"=>"\u1B41",
+ "\u1B42\u1B35"=>"\u1B43",
+ "A\u0325"=>"\u1E00",
+ "a\u0325"=>"\u1E01",
+ "B\u0307"=>"\u1E02",
+ "b\u0307"=>"\u1E03",
+ "B\u0323"=>"\u1E04",
+ "b\u0323"=>"\u1E05",
+ "B\u0331"=>"\u1E06",
+ "b\u0331"=>"\u1E07",
+ "\u00C7\u0301"=>"\u1E08",
+ "\u00E7\u0301"=>"\u1E09",
+ "D\u0307"=>"\u1E0A",
+ "d\u0307"=>"\u1E0B",
+ "D\u0323"=>"\u1E0C",
+ "d\u0323"=>"\u1E0D",
+ "D\u0331"=>"\u1E0E",
+ "d\u0331"=>"\u1E0F",
+ "D\u0327"=>"\u1E10",
+ "d\u0327"=>"\u1E11",
+ "D\u032D"=>"\u1E12",
+ "d\u032D"=>"\u1E13",
+ "\u0112\u0300"=>"\u1E14",
+ "\u0113\u0300"=>"\u1E15",
+ "\u0112\u0301"=>"\u1E16",
+ "\u0113\u0301"=>"\u1E17",
+ "E\u032D"=>"\u1E18",
+ "e\u032D"=>"\u1E19",
+ "E\u0330"=>"\u1E1A",
+ "e\u0330"=>"\u1E1B",
+ "\u0228\u0306"=>"\u1E1C",
+ "\u0229\u0306"=>"\u1E1D",
+ "F\u0307"=>"\u1E1E",
+ "f\u0307"=>"\u1E1F",
+ "G\u0304"=>"\u1E20",
+ "g\u0304"=>"\u1E21",
+ "H\u0307"=>"\u1E22",
+ "h\u0307"=>"\u1E23",
+ "H\u0323"=>"\u1E24",
+ "h\u0323"=>"\u1E25",
+ "H\u0308"=>"\u1E26",
+ "h\u0308"=>"\u1E27",
+ "H\u0327"=>"\u1E28",
+ "h\u0327"=>"\u1E29",
+ "H\u032E"=>"\u1E2A",
+ "h\u032E"=>"\u1E2B",
+ "I\u0330"=>"\u1E2C",
+ "i\u0330"=>"\u1E2D",
+ "\u00CF\u0301"=>"\u1E2E",
+ "\u00EF\u0301"=>"\u1E2F",
+ "K\u0301"=>"\u1E30",
+ "k\u0301"=>"\u1E31",
+ "K\u0323"=>"\u1E32",
+ "k\u0323"=>"\u1E33",
+ "K\u0331"=>"\u1E34",
+ "k\u0331"=>"\u1E35",
+ "L\u0323"=>"\u1E36",
+ "l\u0323"=>"\u1E37",
+ "\u1E36\u0304"=>"\u1E38",
+ "\u1E37\u0304"=>"\u1E39",
+ "L\u0331"=>"\u1E3A",
+ "l\u0331"=>"\u1E3B",
+ "L\u032D"=>"\u1E3C",
+ "l\u032D"=>"\u1E3D",
+ "M\u0301"=>"\u1E3E",
+ "m\u0301"=>"\u1E3F",
+ "M\u0307"=>"\u1E40",
+ "m\u0307"=>"\u1E41",
+ "M\u0323"=>"\u1E42",
+ "m\u0323"=>"\u1E43",
+ "N\u0307"=>"\u1E44",
+ "n\u0307"=>"\u1E45",
+ "N\u0323"=>"\u1E46",
+ "n\u0323"=>"\u1E47",
+ "N\u0331"=>"\u1E48",
+ "n\u0331"=>"\u1E49",
+ "N\u032D"=>"\u1E4A",
+ "n\u032D"=>"\u1E4B",
+ "\u00D5\u0301"=>"\u1E4C",
+ "\u00F5\u0301"=>"\u1E4D",
+ "\u00D5\u0308"=>"\u1E4E",
+ "\u00F5\u0308"=>"\u1E4F",
+ "\u014C\u0300"=>"\u1E50",
+ "\u014D\u0300"=>"\u1E51",
+ "\u014C\u0301"=>"\u1E52",
+ "\u014D\u0301"=>"\u1E53",
+ "P\u0301"=>"\u1E54",
+ "p\u0301"=>"\u1E55",
+ "P\u0307"=>"\u1E56",
+ "p\u0307"=>"\u1E57",
+ "R\u0307"=>"\u1E58",
+ "r\u0307"=>"\u1E59",
+ "R\u0323"=>"\u1E5A",
+ "r\u0323"=>"\u1E5B",
+ "\u1E5A\u0304"=>"\u1E5C",
+ "\u1E5B\u0304"=>"\u1E5D",
+ "R\u0331"=>"\u1E5E",
+ "r\u0331"=>"\u1E5F",
+ "S\u0307"=>"\u1E60",
+ "s\u0307"=>"\u1E61",
+ "S\u0323"=>"\u1E62",
+ "s\u0323"=>"\u1E63",
+ "\u015A\u0307"=>"\u1E64",
+ "\u015B\u0307"=>"\u1E65",
+ "\u0160\u0307"=>"\u1E66",
+ "\u0161\u0307"=>"\u1E67",
+ "\u1E62\u0307"=>"\u1E68",
+ "\u1E63\u0307"=>"\u1E69",
+ "T\u0307"=>"\u1E6A",
+ "t\u0307"=>"\u1E6B",
+ "T\u0323"=>"\u1E6C",
+ "t\u0323"=>"\u1E6D",
+ "T\u0331"=>"\u1E6E",
+ "t\u0331"=>"\u1E6F",
+ "T\u032D"=>"\u1E70",
+ "t\u032D"=>"\u1E71",
+ "U\u0324"=>"\u1E72",
+ "u\u0324"=>"\u1E73",
+ "U\u0330"=>"\u1E74",
+ "u\u0330"=>"\u1E75",
+ "U\u032D"=>"\u1E76",
+ "u\u032D"=>"\u1E77",
+ "\u0168\u0301"=>"\u1E78",
+ "\u0169\u0301"=>"\u1E79",
+ "\u016A\u0308"=>"\u1E7A",
+ "\u016B\u0308"=>"\u1E7B",
+ "V\u0303"=>"\u1E7C",
+ "v\u0303"=>"\u1E7D",
+ "V\u0323"=>"\u1E7E",
+ "v\u0323"=>"\u1E7F",
+ "W\u0300"=>"\u1E80",
+ "w\u0300"=>"\u1E81",
+ "W\u0301"=>"\u1E82",
+ "w\u0301"=>"\u1E83",
+ "W\u0308"=>"\u1E84",
+ "w\u0308"=>"\u1E85",
+ "W\u0307"=>"\u1E86",
+ "w\u0307"=>"\u1E87",
+ "W\u0323"=>"\u1E88",
+ "w\u0323"=>"\u1E89",
+ "X\u0307"=>"\u1E8A",
+ "x\u0307"=>"\u1E8B",
+ "X\u0308"=>"\u1E8C",
+ "x\u0308"=>"\u1E8D",
+ "Y\u0307"=>"\u1E8E",
+ "y\u0307"=>"\u1E8F",
+ "Z\u0302"=>"\u1E90",
+ "z\u0302"=>"\u1E91",
+ "Z\u0323"=>"\u1E92",
+ "z\u0323"=>"\u1E93",
+ "Z\u0331"=>"\u1E94",
+ "z\u0331"=>"\u1E95",
+ "h\u0331"=>"\u1E96",
+ "t\u0308"=>"\u1E97",
+ "w\u030A"=>"\u1E98",
+ "y\u030A"=>"\u1E99",
+ "\u017F\u0307"=>"\u1E9B",
+ "A\u0323"=>"\u1EA0",
+ "a\u0323"=>"\u1EA1",
+ "A\u0309"=>"\u1EA2",
+ "a\u0309"=>"\u1EA3",
+ "\u00C2\u0301"=>"\u1EA4",
+ "\u00E2\u0301"=>"\u1EA5",
+ "\u00C2\u0300"=>"\u1EA6",
+ "\u00E2\u0300"=>"\u1EA7",
+ "\u00C2\u0309"=>"\u1EA8",
+ "\u00E2\u0309"=>"\u1EA9",
+ "\u00C2\u0303"=>"\u1EAA",
+ "\u00E2\u0303"=>"\u1EAB",
+ "\u1EA0\u0302"=>"\u1EAC",
+ "\u1EA1\u0302"=>"\u1EAD",
+ "\u0102\u0301"=>"\u1EAE",
+ "\u0103\u0301"=>"\u1EAF",
+ "\u0102\u0300"=>"\u1EB0",
+ "\u0103\u0300"=>"\u1EB1",
+ "\u0102\u0309"=>"\u1EB2",
+ "\u0103\u0309"=>"\u1EB3",
+ "\u0102\u0303"=>"\u1EB4",
+ "\u0103\u0303"=>"\u1EB5",
+ "\u1EA0\u0306"=>"\u1EB6",
+ "\u1EA1\u0306"=>"\u1EB7",
+ "E\u0323"=>"\u1EB8",
+ "e\u0323"=>"\u1EB9",
+ "E\u0309"=>"\u1EBA",
+ "e\u0309"=>"\u1EBB",
+ "E\u0303"=>"\u1EBC",
+ "e\u0303"=>"\u1EBD",
+ "\u00CA\u0301"=>"\u1EBE",
+ "\u00EA\u0301"=>"\u1EBF",
+ "\u00CA\u0300"=>"\u1EC0",
+ "\u00EA\u0300"=>"\u1EC1",
+ "\u00CA\u0309"=>"\u1EC2",
+ "\u00EA\u0309"=>"\u1EC3",
+ "\u00CA\u0303"=>"\u1EC4",
+ "\u00EA\u0303"=>"\u1EC5",
+ "\u1EB8\u0302"=>"\u1EC6",
+ "\u1EB9\u0302"=>"\u1EC7",
+ "I\u0309"=>"\u1EC8",
+ "i\u0309"=>"\u1EC9",
+ "I\u0323"=>"\u1ECA",
+ "i\u0323"=>"\u1ECB",
+ "O\u0323"=>"\u1ECC",
+ "o\u0323"=>"\u1ECD",
+ "O\u0309"=>"\u1ECE",
+ "o\u0309"=>"\u1ECF",
+ "\u00D4\u0301"=>"\u1ED0",
+ "\u00F4\u0301"=>"\u1ED1",
+ "\u00D4\u0300"=>"\u1ED2",
+ "\u00F4\u0300"=>"\u1ED3",
+ "\u00D4\u0309"=>"\u1ED4",
+ "\u00F4\u0309"=>"\u1ED5",
+ "\u00D4\u0303"=>"\u1ED6",
+ "\u00F4\u0303"=>"\u1ED7",
+ "\u1ECC\u0302"=>"\u1ED8",
+ "\u1ECD\u0302"=>"\u1ED9",
+ "\u01A0\u0301"=>"\u1EDA",
+ "\u01A1\u0301"=>"\u1EDB",
+ "\u01A0\u0300"=>"\u1EDC",
+ "\u01A1\u0300"=>"\u1EDD",
+ "\u01A0\u0309"=>"\u1EDE",
+ "\u01A1\u0309"=>"\u1EDF",
+ "\u01A0\u0303"=>"\u1EE0",
+ "\u01A1\u0303"=>"\u1EE1",
+ "\u01A0\u0323"=>"\u1EE2",
+ "\u01A1\u0323"=>"\u1EE3",
+ "U\u0323"=>"\u1EE4",
+ "u\u0323"=>"\u1EE5",
+ "U\u0309"=>"\u1EE6",
+ "u\u0309"=>"\u1EE7",
+ "\u01AF\u0301"=>"\u1EE8",
+ "\u01B0\u0301"=>"\u1EE9",
+ "\u01AF\u0300"=>"\u1EEA",
+ "\u01B0\u0300"=>"\u1EEB",
+ "\u01AF\u0309"=>"\u1EEC",
+ "\u01B0\u0309"=>"\u1EED",
+ "\u01AF\u0303"=>"\u1EEE",
+ "\u01B0\u0303"=>"\u1EEF",
+ "\u01AF\u0323"=>"\u1EF0",
+ "\u01B0\u0323"=>"\u1EF1",
+ "Y\u0300"=>"\u1EF2",
+ "y\u0300"=>"\u1EF3",
+ "Y\u0323"=>"\u1EF4",
+ "y\u0323"=>"\u1EF5",
+ "Y\u0309"=>"\u1EF6",
+ "y\u0309"=>"\u1EF7",
+ "Y\u0303"=>"\u1EF8",
+ "y\u0303"=>"\u1EF9",
+ "\u03B1\u0313"=>"\u1F00",
+ "\u03B1\u0314"=>"\u1F01",
+ "\u1F00\u0300"=>"\u1F02",
+ "\u1F01\u0300"=>"\u1F03",
+ "\u1F00\u0301"=>"\u1F04",
+ "\u1F01\u0301"=>"\u1F05",
+ "\u1F00\u0342"=>"\u1F06",
+ "\u1F01\u0342"=>"\u1F07",
+ "\u0391\u0313"=>"\u1F08",
+ "\u0391\u0314"=>"\u1F09",
+ "\u1F08\u0300"=>"\u1F0A",
+ "\u1F09\u0300"=>"\u1F0B",
+ "\u1F08\u0301"=>"\u1F0C",
+ "\u1F09\u0301"=>"\u1F0D",
+ "\u1F08\u0342"=>"\u1F0E",
+ "\u1F09\u0342"=>"\u1F0F",
+ "\u03B5\u0313"=>"\u1F10",
+ "\u03B5\u0314"=>"\u1F11",
+ "\u1F10\u0300"=>"\u1F12",
+ "\u1F11\u0300"=>"\u1F13",
+ "\u1F10\u0301"=>"\u1F14",
+ "\u1F11\u0301"=>"\u1F15",
+ "\u0395\u0313"=>"\u1F18",
+ "\u0395\u0314"=>"\u1F19",
+ "\u1F18\u0300"=>"\u1F1A",
+ "\u1F19\u0300"=>"\u1F1B",
+ "\u1F18\u0301"=>"\u1F1C",
+ "\u1F19\u0301"=>"\u1F1D",
+ "\u03B7\u0313"=>"\u1F20",
+ "\u03B7\u0314"=>"\u1F21",
+ "\u1F20\u0300"=>"\u1F22",
+ "\u1F21\u0300"=>"\u1F23",
+ "\u1F20\u0301"=>"\u1F24",
+ "\u1F21\u0301"=>"\u1F25",
+ "\u1F20\u0342"=>"\u1F26",
+ "\u1F21\u0342"=>"\u1F27",
+ "\u0397\u0313"=>"\u1F28",
+ "\u0397\u0314"=>"\u1F29",
+ "\u1F28\u0300"=>"\u1F2A",
+ "\u1F29\u0300"=>"\u1F2B",
+ "\u1F28\u0301"=>"\u1F2C",
+ "\u1F29\u0301"=>"\u1F2D",
+ "\u1F28\u0342"=>"\u1F2E",
+ "\u1F29\u0342"=>"\u1F2F",
+ "\u03B9\u0313"=>"\u1F30",
+ "\u03B9\u0314"=>"\u1F31",
+ "\u1F30\u0300"=>"\u1F32",
+ "\u1F31\u0300"=>"\u1F33",
+ "\u1F30\u0301"=>"\u1F34",
+ "\u1F31\u0301"=>"\u1F35",
+ "\u1F30\u0342"=>"\u1F36",
+ "\u1F31\u0342"=>"\u1F37",
+ "\u0399\u0313"=>"\u1F38",
+ "\u0399\u0314"=>"\u1F39",
+ "\u1F38\u0300"=>"\u1F3A",
+ "\u1F39\u0300"=>"\u1F3B",
+ "\u1F38\u0301"=>"\u1F3C",
+ "\u1F39\u0301"=>"\u1F3D",
+ "\u1F38\u0342"=>"\u1F3E",
+ "\u1F39\u0342"=>"\u1F3F",
+ "\u03BF\u0313"=>"\u1F40",
+ "\u03BF\u0314"=>"\u1F41",
+ "\u1F40\u0300"=>"\u1F42",
+ "\u1F41\u0300"=>"\u1F43",
+ "\u1F40\u0301"=>"\u1F44",
+ "\u1F41\u0301"=>"\u1F45",
+ "\u039F\u0313"=>"\u1F48",
+ "\u039F\u0314"=>"\u1F49",
+ "\u1F48\u0300"=>"\u1F4A",
+ "\u1F49\u0300"=>"\u1F4B",
+ "\u1F48\u0301"=>"\u1F4C",
+ "\u1F49\u0301"=>"\u1F4D",
+ "\u03C5\u0313"=>"\u1F50",
+ "\u03C5\u0314"=>"\u1F51",
+ "\u1F50\u0300"=>"\u1F52",
+ "\u1F51\u0300"=>"\u1F53",
+ "\u1F50\u0301"=>"\u1F54",
+ "\u1F51\u0301"=>"\u1F55",
+ "\u1F50\u0342"=>"\u1F56",
+ "\u1F51\u0342"=>"\u1F57",
+ "\u03A5\u0314"=>"\u1F59",
+ "\u1F59\u0300"=>"\u1F5B",
+ "\u1F59\u0301"=>"\u1F5D",
+ "\u1F59\u0342"=>"\u1F5F",
+ "\u03C9\u0313"=>"\u1F60",
+ "\u03C9\u0314"=>"\u1F61",
+ "\u1F60\u0300"=>"\u1F62",
+ "\u1F61\u0300"=>"\u1F63",
+ "\u1F60\u0301"=>"\u1F64",
+ "\u1F61\u0301"=>"\u1F65",
+ "\u1F60\u0342"=>"\u1F66",
+ "\u1F61\u0342"=>"\u1F67",
+ "\u03A9\u0313"=>"\u1F68",
+ "\u03A9\u0314"=>"\u1F69",
+ "\u1F68\u0300"=>"\u1F6A",
+ "\u1F69\u0300"=>"\u1F6B",
+ "\u1F68\u0301"=>"\u1F6C",
+ "\u1F69\u0301"=>"\u1F6D",
+ "\u1F68\u0342"=>"\u1F6E",
+ "\u1F69\u0342"=>"\u1F6F",
+ "\u03B1\u0300"=>"\u1F70",
+ "\u03B5\u0300"=>"\u1F72",
+ "\u03B7\u0300"=>"\u1F74",
+ "\u03B9\u0300"=>"\u1F76",
+ "\u03BF\u0300"=>"\u1F78",
+ "\u03C5\u0300"=>"\u1F7A",
+ "\u03C9\u0300"=>"\u1F7C",
+ "\u1F00\u0345"=>"\u1F80",
+ "\u1F01\u0345"=>"\u1F81",
+ "\u1F02\u0345"=>"\u1F82",
+ "\u1F03\u0345"=>"\u1F83",
+ "\u1F04\u0345"=>"\u1F84",
+ "\u1F05\u0345"=>"\u1F85",
+ "\u1F06\u0345"=>"\u1F86",
+ "\u1F07\u0345"=>"\u1F87",
+ "\u1F08\u0345"=>"\u1F88",
+ "\u1F09\u0345"=>"\u1F89",
+ "\u1F0A\u0345"=>"\u1F8A",
+ "\u1F0B\u0345"=>"\u1F8B",
+ "\u1F0C\u0345"=>"\u1F8C",
+ "\u1F0D\u0345"=>"\u1F8D",
+ "\u1F0E\u0345"=>"\u1F8E",
+ "\u1F0F\u0345"=>"\u1F8F",
+ "\u1F20\u0345"=>"\u1F90",
+ "\u1F21\u0345"=>"\u1F91",
+ "\u1F22\u0345"=>"\u1F92",
+ "\u1F23\u0345"=>"\u1F93",
+ "\u1F24\u0345"=>"\u1F94",
+ "\u1F25\u0345"=>"\u1F95",
+ "\u1F26\u0345"=>"\u1F96",
+ "\u1F27\u0345"=>"\u1F97",
+ "\u1F28\u0345"=>"\u1F98",
+ "\u1F29\u0345"=>"\u1F99",
+ "\u1F2A\u0345"=>"\u1F9A",
+ "\u1F2B\u0345"=>"\u1F9B",
+ "\u1F2C\u0345"=>"\u1F9C",
+ "\u1F2D\u0345"=>"\u1F9D",
+ "\u1F2E\u0345"=>"\u1F9E",
+ "\u1F2F\u0345"=>"\u1F9F",
+ "\u1F60\u0345"=>"\u1FA0",
+ "\u1F61\u0345"=>"\u1FA1",
+ "\u1F62\u0345"=>"\u1FA2",
+ "\u1F63\u0345"=>"\u1FA3",
+ "\u1F64\u0345"=>"\u1FA4",
+ "\u1F65\u0345"=>"\u1FA5",
+ "\u1F66\u0345"=>"\u1FA6",
+ "\u1F67\u0345"=>"\u1FA7",
+ "\u1F68\u0345"=>"\u1FA8",
+ "\u1F69\u0345"=>"\u1FA9",
+ "\u1F6A\u0345"=>"\u1FAA",
+ "\u1F6B\u0345"=>"\u1FAB",
+ "\u1F6C\u0345"=>"\u1FAC",
+ "\u1F6D\u0345"=>"\u1FAD",
+ "\u1F6E\u0345"=>"\u1FAE",
+ "\u1F6F\u0345"=>"\u1FAF",
+ "\u03B1\u0306"=>"\u1FB0",
+ "\u03B1\u0304"=>"\u1FB1",
+ "\u1F70\u0345"=>"\u1FB2",
+ "\u03B1\u0345"=>"\u1FB3",
+ "\u03AC\u0345"=>"\u1FB4",
+ "\u03B1\u0342"=>"\u1FB6",
+ "\u1FB6\u0345"=>"\u1FB7",
+ "\u0391\u0306"=>"\u1FB8",
+ "\u0391\u0304"=>"\u1FB9",
+ "\u0391\u0300"=>"\u1FBA",
+ "\u0391\u0345"=>"\u1FBC",
+ "\u00A8\u0342"=>"\u1FC1",
+ "\u1F74\u0345"=>"\u1FC2",
+ "\u03B7\u0345"=>"\u1FC3",
+ "\u03AE\u0345"=>"\u1FC4",
+ "\u03B7\u0342"=>"\u1FC6",
+ "\u1FC6\u0345"=>"\u1FC7",
+ "\u0395\u0300"=>"\u1FC8",
+ "\u0397\u0300"=>"\u1FCA",
+ "\u0397\u0345"=>"\u1FCC",
+ "\u1FBF\u0300"=>"\u1FCD",
+ "\u1FBF\u0301"=>"\u1FCE",
+ "\u1FBF\u0342"=>"\u1FCF",
+ "\u03B9\u0306"=>"\u1FD0",
+ "\u03B9\u0304"=>"\u1FD1",
+ "\u03CA\u0300"=>"\u1FD2",
+ "\u03B9\u0342"=>"\u1FD6",
+ "\u03CA\u0342"=>"\u1FD7",
+ "\u0399\u0306"=>"\u1FD8",
+ "\u0399\u0304"=>"\u1FD9",
+ "\u0399\u0300"=>"\u1FDA",
+ "\u1FFE\u0300"=>"\u1FDD",
+ "\u1FFE\u0301"=>"\u1FDE",
+ "\u1FFE\u0342"=>"\u1FDF",
+ "\u03C5\u0306"=>"\u1FE0",
+ "\u03C5\u0304"=>"\u1FE1",
+ "\u03CB\u0300"=>"\u1FE2",
+ "\u03C1\u0313"=>"\u1FE4",
+ "\u03C1\u0314"=>"\u1FE5",
+ "\u03C5\u0342"=>"\u1FE6",
+ "\u03CB\u0342"=>"\u1FE7",
+ "\u03A5\u0306"=>"\u1FE8",
+ "\u03A5\u0304"=>"\u1FE9",
+ "\u03A5\u0300"=>"\u1FEA",
+ "\u03A1\u0314"=>"\u1FEC",
+ "\u00A8\u0300"=>"\u1FED",
+ "\u1F7C\u0345"=>"\u1FF2",
+ "\u03C9\u0345"=>"\u1FF3",
+ "\u03CE\u0345"=>"\u1FF4",
+ "\u03C9\u0342"=>"\u1FF6",
+ "\u1FF6\u0345"=>"\u1FF7",
+ "\u039F\u0300"=>"\u1FF8",
+ "\u03A9\u0300"=>"\u1FFA",
+ "\u03A9\u0345"=>"\u1FFC",
+ "\u2190\u0338"=>"\u219A",
+ "\u2192\u0338"=>"\u219B",
+ "\u2194\u0338"=>"\u21AE",
+ "\u21D0\u0338"=>"\u21CD",
+ "\u21D4\u0338"=>"\u21CE",
+ "\u21D2\u0338"=>"\u21CF",
+ "\u2203\u0338"=>"\u2204",
+ "\u2208\u0338"=>"\u2209",
+ "\u220B\u0338"=>"\u220C",
+ "\u2223\u0338"=>"\u2224",
+ "\u2225\u0338"=>"\u2226",
+ "\u223C\u0338"=>"\u2241",
+ "\u2243\u0338"=>"\u2244",
+ "\u2245\u0338"=>"\u2247",
+ "\u2248\u0338"=>"\u2249",
+ "=\u0338"=>"\u2260",
+ "\u2261\u0338"=>"\u2262",
+ "\u224D\u0338"=>"\u226D",
+ "<\u0338"=>"\u226E",
+ ">\u0338"=>"\u226F",
+ "\u2264\u0338"=>"\u2270",
+ "\u2265\u0338"=>"\u2271",
+ "\u2272\u0338"=>"\u2274",
+ "\u2273\u0338"=>"\u2275",
+ "\u2276\u0338"=>"\u2278",
+ "\u2277\u0338"=>"\u2279",
+ "\u227A\u0338"=>"\u2280",
+ "\u227B\u0338"=>"\u2281",
+ "\u2282\u0338"=>"\u2284",
+ "\u2283\u0338"=>"\u2285",
+ "\u2286\u0338"=>"\u2288",
+ "\u2287\u0338"=>"\u2289",
+ "\u22A2\u0338"=>"\u22AC",
+ "\u22A8\u0338"=>"\u22AD",
+ "\u22A9\u0338"=>"\u22AE",
+ "\u22AB\u0338"=>"\u22AF",
+ "\u227C\u0338"=>"\u22E0",
+ "\u227D\u0338"=>"\u22E1",
+ "\u2291\u0338"=>"\u22E2",
+ "\u2292\u0338"=>"\u22E3",
+ "\u22B2\u0338"=>"\u22EA",
+ "\u22B3\u0338"=>"\u22EB",
+ "\u22B4\u0338"=>"\u22EC",
+ "\u22B5\u0338"=>"\u22ED",
+ "\u304B\u3099"=>"\u304C",
+ "\u304D\u3099"=>"\u304E",
+ "\u304F\u3099"=>"\u3050",
+ "\u3051\u3099"=>"\u3052",
+ "\u3053\u3099"=>"\u3054",
+ "\u3055\u3099"=>"\u3056",
+ "\u3057\u3099"=>"\u3058",
+ "\u3059\u3099"=>"\u305A",
+ "\u305B\u3099"=>"\u305C",
+ "\u305D\u3099"=>"\u305E",
+ "\u305F\u3099"=>"\u3060",
+ "\u3061\u3099"=>"\u3062",
+ "\u3064\u3099"=>"\u3065",
+ "\u3066\u3099"=>"\u3067",
+ "\u3068\u3099"=>"\u3069",
+ "\u306F\u3099"=>"\u3070",
+ "\u306F\u309A"=>"\u3071",
+ "\u3072\u3099"=>"\u3073",
+ "\u3072\u309A"=>"\u3074",
+ "\u3075\u3099"=>"\u3076",
+ "\u3075\u309A"=>"\u3077",
+ "\u3078\u3099"=>"\u3079",
+ "\u3078\u309A"=>"\u307A",
+ "\u307B\u3099"=>"\u307C",
+ "\u307B\u309A"=>"\u307D",
+ "\u3046\u3099"=>"\u3094",
+ "\u309D\u3099"=>"\u309E",
+ "\u30AB\u3099"=>"\u30AC",
+ "\u30AD\u3099"=>"\u30AE",
+ "\u30AF\u3099"=>"\u30B0",
+ "\u30B1\u3099"=>"\u30B2",
+ "\u30B3\u3099"=>"\u30B4",
+ "\u30B5\u3099"=>"\u30B6",
+ "\u30B7\u3099"=>"\u30B8",
+ "\u30B9\u3099"=>"\u30BA",
+ "\u30BB\u3099"=>"\u30BC",
+ "\u30BD\u3099"=>"\u30BE",
+ "\u30BF\u3099"=>"\u30C0",
+ "\u30C1\u3099"=>"\u30C2",
+ "\u30C4\u3099"=>"\u30C5",
+ "\u30C6\u3099"=>"\u30C7",
+ "\u30C8\u3099"=>"\u30C9",
+ "\u30CF\u3099"=>"\u30D0",
+ "\u30CF\u309A"=>"\u30D1",
+ "\u30D2\u3099"=>"\u30D3",
+ "\u30D2\u309A"=>"\u30D4",
+ "\u30D5\u3099"=>"\u30D6",
+ "\u30D5\u309A"=>"\u30D7",
+ "\u30D8\u3099"=>"\u30D9",
+ "\u30D8\u309A"=>"\u30DA",
+ "\u30DB\u3099"=>"\u30DC",
+ "\u30DB\u309A"=>"\u30DD",
+ "\u30A6\u3099"=>"\u30F4",
+ "\u30EF\u3099"=>"\u30F7",
+ "\u30F0\u3099"=>"\u30F8",
+ "\u30F1\u3099"=>"\u30F9",
+ "\u30F2\u3099"=>"\u30FA",
+ "\u30FD\u3099"=>"\u30FE",
+ "\u{11099}\u{110BA}"=>"\u{1109A}",
+ "\u{1109B}\u{110BA}"=>"\u{1109C}",
+ "\u{110A5}\u{110BA}"=>"\u{110AB}",
+ "\u{11131}\u{11127}"=>"\u{1112E}",
+ "\u{11132}\u{11127}"=>"\u{1112F}",
+ "\u{11347}\u{1133E}"=>"\u{1134B}",
+ "\u{11347}\u{11357}"=>"\u{1134C}",
+ "\u{114B9}\u{114BA}"=>"\u{114BB}",
+ "\u{114B9}\u{114B0}"=>"\u{114BC}",
+ "\u{114B9}\u{114BD}"=>"\u{114BE}",
+ "\u{115B8}\u{115AF}"=>"\u{115BA}",
+ "\u{115B9}\u{115AF}"=>"\u{115BB}",
}.freeze
end
diff --git a/lib/uri.rb b/lib/uri.rb
index 971a97038f..b544a5ee65 100644
--- a/lib/uri.rb
+++ b/lib/uri.rb
@@ -1,34 +1,28 @@
# frozen_string_literal: false
# URI is a module providing classes to handle Uniform Resource Identifiers
-# (RFC2396[http://tools.ietf.org/html/rfc2396])
+# (RFC2396[http://tools.ietf.org/html/rfc2396]).
#
# == Features
#
-# * Uniform handling of handling URIs
-# * Flexibility to introduce custom URI schemes
+# * Uniform way of handling URIs.
+# * Flexibility to introduce custom URI schemes.
# * Flexibility to have an alternate URI::Parser (or just different patterns
-# and regexp's)
+# and regexp's).
#
# == Basic example
#
# require 'uri'
#
# uri = URI("http://foo.com/posts?id=30&limit=5#time=1305298413")
-# #=> #<URI::HTTP:0x00000000b14880
-# URL:http://foo.com/posts?id=30&limit=5#time=1305298413>
-# uri.scheme
-# #=> "http"
-# uri.host
-# #=> "foo.com"
-# uri.path
-# #=> "/posts"
-# uri.query
-# #=> "id=30&limit=5"
-# uri.fragment
-# #=> "time=1305298413"
-#
-# uri.to_s
-# #=> "http://foo.com/posts?id=30&limit=5#time=1305298413"
+# #=> #<URI::HTTP http://foo.com/posts?id=30&limit=5#time=1305298413>
+#
+# uri.scheme #=> "http"
+# uri.host #=> "foo.com"
+# uri.path #=> "/posts"
+# uri.query #=> "id=30&limit=5"
+# uri.fragment #=> "time=1305298413"
+#
+# uri.to_s #=> "http://foo.com/posts?id=30&limit=5#time=1305298413"
#
# == Adding custom URIs
#
@@ -41,18 +35,18 @@
# #=> URI::RSYNC
#
# URI.scheme_list
-# #=> {"FTP"=>URI::FTP, "HTTP"=>URI::HTTP, "HTTPS"=>URI::HTTPS,
-# "LDAP"=>URI::LDAP, "LDAPS"=>URI::LDAPS, "MAILTO"=>URI::MailTo,
-# "RSYNC"=>URI::RSYNC}
+# #=> {"FILE"=>URI::File, "FTP"=>URI::FTP, "HTTP"=>URI::HTTP,
+# # "HTTPS"=>URI::HTTPS, "LDAP"=>URI::LDAP, "LDAPS"=>URI::LDAPS,
+# # "MAILTO"=>URI::MailTo, "RSYNC"=>URI::RSYNC}
#
# uri = URI("rsync://rsync.foo.com")
-# #=> #<URI::RSYNC:0x00000000f648c8 URL:rsync://rsync.foo.com>
+# #=> #<URI::RSYNC rsync://rsync.foo.com>
#
# == RFC References
#
-# A good place to view an RFC spec is http://www.ietf.org/rfc.html
+# A good place to view an RFC spec is http://www.ietf.org/rfc.html.
#
-# Here is a list of all related RFC's.
+# Here is a list of all related RFC's:
# - RFC822[http://tools.ietf.org/html/rfc822]
# - RFC1738[http://tools.ietf.org/html/rfc1738]
# - RFC2255[http://tools.ietf.org/html/rfc2255]
@@ -65,6 +59,7 @@
# == Class tree
#
# - URI::Generic (in uri/generic.rb)
+# - URI::File - (in uri/file.rb)
# - URI::FTP - (in uri/ftp.rb)
# - URI::HTTP - (in uri/http.rb)
# - URI::HTTPS - (in uri/https.rb)
@@ -91,22 +86,18 @@
# License::
# Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
# You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
#
module URI
- # :stopdoc:
- VERSION_CODE = '001000'.freeze
- VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
- # :startdoc:
-
end
-require 'uri/common'
-require 'uri/generic'
-require 'uri/ftp'
-require 'uri/http'
-require 'uri/https'
-require 'uri/ldap'
-require 'uri/ldaps'
-require 'uri/mailto'
+require_relative 'uri/version'
+require_relative 'uri/common'
+require_relative 'uri/generic'
+require_relative 'uri/file'
+require_relative 'uri/ftp'
+require_relative 'uri/http'
+require_relative 'uri/https'
+require_relative 'uri/ldap'
+require_relative 'uri/ldaps'
+require_relative 'uri/mailto'
diff --git a/lib/uri/common.rb b/lib/uri/common.rb
index 74bbdea0a4..d818592b74 100644
--- a/lib/uri/common.rb
+++ b/lib/uri/common.rb
@@ -1,17 +1,16 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
#--
# = uri/common.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
-# Revision:: $Id$
# License::
# You can redistribute it and/or modify it under the same term as Ruby.
#
# See URI for general documentation
#
-require "uri/rfc2396_parser"
-require "uri/rfc3986_parser"
+require_relative "rfc2396_parser"
+require_relative "rfc3986_parser"
module URI
REGEXP = RFC2396_REGEXP
@@ -61,93 +60,29 @@ module URI
module_function :make_components_hash
end
- # module for escaping unsafe characters with codes.
- module Escape
- #
- # == Synopsis
- #
- # URI.escape(str [, unsafe])
- #
- # == Args
- #
- # +str+::
- # String to replaces in.
- # +unsafe+::
- # Regexp that matches all symbols that must be replaced with codes.
- # By default uses <tt>UNSAFE</tt>.
- # When this argument is a String, it represents a character set.
- #
- # == Description
- #
- # Escapes the string, replacing all unsafe characters with codes.
- #
- # This method is obsolete and should not be used. Instead, use
- # CGI.escape, URI.encode_www_form or URI.encode_www_form_component
- # depending on your specific use case.
- #
- # == Usage
- #
- # require 'uri'
- #
- # enc_uri = URI.escape("http://example.com/?a=\11\15")
- # p enc_uri
- # # => "http://example.com/?a=%09%0D"
- #
- # p URI.unescape(enc_uri)
- # # => "http://example.com/?a=\t\r"
- #
- # p URI.escape("@?@!", "!?")
- # # => "@%3F@%21"
- #
- def escape(*arg)
- warn "#{caller(1)[0]}: warning: URI.escape is obsolete" if $VERBOSE
- DEFAULT_PARSER.escape(*arg)
- end
- alias encode escape
- #
- # == Synopsis
- #
- # URI.unescape(str)
- #
- # == Args
- #
- # +str+::
- # Unescapes the string.
- #
- # == Description
- #
- # This method is obsolete and should not be used. Instead, use
- # CGI.unescape, URI.decode_www_form or URI.decode_www_form_component
- # depending on your specific use case.
- #
- # == Usage
- #
- # require 'uri'
- #
- # enc_uri = URI.escape("http://example.com/?a=\11\15")
- # p enc_uri
- # # => "http://example.com/?a=%09%0D"
- #
- # p URI.unescape(enc_uri)
- # # => "http://example.com/?a=\t\r"
- #
- def unescape(*arg)
- warn "#{caller(1)[0]}: warning: URI.unescape is obsolete" if $VERBOSE
- DEFAULT_PARSER.unescape(*arg)
- end
- alias decode unescape
- end # module Escape
-
- extend Escape
include REGEXP
@@schemes = {}
- # Returns a Hash of the defined schemes
+ # Returns a Hash of the defined schemes.
def self.scheme_list
@@schemes
end
#
+ # Construct a URI instance, using the scheme to detect the appropriate class
+ # from +URI.scheme_list+.
+ #
+ def self.for(scheme, *arguments, default: Generic)
+ if scheme
+ uri_class = @@schemes[scheme.upcase] || default
+ else
+ uri_class = default
+ end
+
+ return uri_class.new(scheme, *arguments)
+ end
+
+ #
# Base class for all URI exceptions.
#
class Error < StandardError; end
@@ -178,21 +113,21 @@ module URI
#
# Splits the string on following parts and returns array with result:
#
- # * Scheme
- # * Userinfo
- # * Host
- # * Port
- # * Registry
- # * Path
- # * Opaque
- # * Query
- # * Fragment
+ # * Scheme
+ # * Userinfo
+ # * Host
+ # * Port
+ # * Registry
+ # * Path
+ # * Opaque
+ # * Query
+ # * Fragment
#
# == Usage
#
# require 'uri'
#
- # p URI.split("http://www.ruby-lang.org/")
+ # URI.split("http://www.ruby-lang.org/")
# # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
#
def self.split(uri)
@@ -215,7 +150,7 @@ module URI
#
# == Raises
#
- # URI::InvalidURIError
+ # URI::InvalidURIError::
# Raised if URI given is not a correct one.
#
# == Usage
@@ -223,11 +158,10 @@ module URI
# require 'uri'
#
# uri = URI.parse("http://www.ruby-lang.org/")
- # p uri
- # # => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>
- # p uri.scheme
+ # # => #<URI::HTTP http://www.ruby-lang.org/>
+ # uri.scheme
# # => "http"
- # p uri.host
+ # uri.host
# # => "www.ruby-lang.org"
#
# It's recommended to first ::escape the provided +uri_str+ if there are any
@@ -255,21 +189,20 @@ module URI
#
# require 'uri'
#
- # p URI.join("http://example.com/","main.rbx")
- # # => #<URI::HTTP:0x2022ac02 URL:http://example.com/main.rbx>
+ # URI.join("http://example.com/","main.rbx")
+ # # => #<URI::HTTP http://example.com/main.rbx>
#
- # p URI.join('http://example.com', 'foo')
- # # => #<URI::HTTP:0x01ab80a0 URL:http://example.com/foo>
+ # URI.join('http://example.com', 'foo')
+ # # => #<URI::HTTP http://example.com/foo>
#
- # p URI.join('http://example.com', '/foo', '/bar')
- # # => #<URI::HTTP:0x01aaf0b0 URL:http://example.com/bar>
+ # URI.join('http://example.com', '/foo', '/bar')
+ # # => #<URI::HTTP http://example.com/bar>
#
- # p URI.join('http://example.com', '/foo', 'bar')
- # # => #<URI::HTTP:0x801a92af0 URL:http://example.com/bar>
- #
- # p URI.join('http://example.com', '/foo/', 'bar')
- # # => #<URI::HTTP:0x80135a3a0 URL:http://example.com/foo/bar>
+ # URI.join('http://example.com', '/foo', 'bar')
+ # # => #<URI::HTTP http://example.com/bar>
#
+ # URI.join('http://example.com', '/foo/', 'bar')
+ # # => #<URI::HTTP http://example.com/foo/bar>
#
def self.join(*str)
RFC3986_PARSER.join(*str)
@@ -285,7 +218,7 @@ module URI
# +str+::
# String to extract URIs from.
# +schemes+::
- # Limit URI matching to a specific schemes.
+ # Limit URI matching to specific schemes.
#
# == Description
#
@@ -300,7 +233,7 @@ module URI
# # => ["http://foo.example.com/bla", "mailto:test@example.com"]
#
def self.extract(str, schemes = nil, &block)
- warn "#{caller(1)[0]}: warning: URI.extract is obsolete" if $VERBOSE
+ warn "URI.extract is obsolete", uplevel: 1 if $VERBOSE
DEFAULT_PARSER.extract(str, schemes, &block)
end
@@ -316,9 +249,10 @@ module URI
# whose scheme is one of the match_schemes.
#
# == Description
+ #
# Returns a Regexp object which matches to URI-like strings.
# The Regexp object returned by this method includes arbitrary
- # number of capture group (parentheses). Never rely on it's number.
+ # number of capture group (parentheses). Never rely on its number.
#
# == Usage
#
@@ -328,7 +262,7 @@ module URI
# html_string.slice(URI.regexp)
#
# # remove ftp URIs
- # html_string.sub(URI.regexp(['ftp'])
+ # html_string.sub(URI.regexp(['ftp']), '')
#
# # You should not rely on the number of parentheses
# html_string.scan(URI.regexp) do |*matches|
@@ -336,31 +270,28 @@ module URI
# end
#
def self.regexp(schemes = nil)
- warn "#{caller(1)[0]}: warning: URI.regexp is obsolete" if $VERBOSE
+ warn "URI.regexp is obsolete", uplevel: 1 if $VERBOSE
DEFAULT_PARSER.make_regexp(schemes)
end
TBLENCWWWCOMP_ = {} # :nodoc:
256.times do |i|
- TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
+ TBLENCWWWCOMP_[-i.chr] = -('%%%02X' % i)
end
TBLENCWWWCOMP_[' '] = '+'
TBLENCWWWCOMP_.freeze
TBLDECWWWCOMP_ = {} # :nodoc:
256.times do |i|
h, l = i>>4, i&15
- TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
- TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
- TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
- TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
+ TBLDECWWWCOMP_[-('%%%X%X' % [h, l])] = -i.chr
+ TBLDECWWWCOMP_[-('%%%x%X' % [h, l])] = -i.chr
+ TBLDECWWWCOMP_[-('%%%X%x' % [h, l])] = -i.chr
+ TBLDECWWWCOMP_[-('%%%x%x' % [h, l])] = -i.chr
end
TBLDECWWWCOMP_['+'] = ' '
TBLDECWWWCOMP_.freeze
- HTML5ASCIIINCOMPAT = defined? Encoding::UTF_7 ? [Encoding::UTF_7, Encoding::UTF_16BE, Encoding::UTF_16LE,
- Encoding::UTF_32BE, Encoding::UTF_32LE] : [] # :nodoc:
-
- # Encode given +str+ to URL-encoded form data.
+ # Encodes given +str+ to URL-encoded form data.
#
# This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
# (ASCII space) to + and converts others to %XX.
@@ -368,15 +299,15 @@ module URI
# If +enc+ is given, convert +str+ to the encoding before percent encoding.
#
# This is an implementation of
- # http://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data
+ # https://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data.
#
- # See URI.decode_www_form_component, URI.encode_www_form
+ # See URI.decode_www_form_component, URI.encode_www_form.
def self.encode_www_form_component(str, enc=nil)
str = str.to_s.dup
if str.encoding != Encoding::ASCII_8BIT
if enc && enc != Encoding::ASCII_8BIT
str.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace)
- str.encode!(enc, fallback: ->(x){"&#{x.ord};"})
+ str.encode!(enc, fallback: ->(x){"&##{x.ord};"})
end
str.force_encoding(Encoding::ASCII_8BIT)
end
@@ -384,17 +315,17 @@ module URI
str.force_encoding(Encoding::US_ASCII)
end
- # Decode given +str+ of URL-encoded form data.
+ # Decodes given +str+ of URL-encoded form data.
#
# This decodes + to SP.
#
- # See URI.encode_www_form_component, URI.decode_www_form
+ # See URI.encode_www_form_component, URI.decode_www_form.
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
raise ArgumentError, "invalid %-encoding (#{str})" if /%(?!\h\h)/ =~ str
str.b.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc)
end
- # Generate URL-encoded form data from given +enum+.
+ # Generates URL-encoded form data from given +enum+.
#
# This generates application/x-www-form-urlencoded data defined in HTML5
# from given an Enumerable object.
@@ -402,14 +333,14 @@ module URI
# This internally uses URI.encode_www_form_component(str).
#
# This method doesn't convert the encoding of given items, so convert them
- # before call this method if you want to send data as other than original
+ # before calling this method if you want to send data as other than original
# encoding or mixed encoding data. (Strings which are encoded in an HTML5
# ASCII incompatible encoding are converted to UTF-8.)
#
# This method doesn't handle files. When you send a file, use
# multipart/form-data.
#
- # This refers http://url.spec.whatwg.org/#concept-urlencoded-serializer
+ # This refers https://url.spec.whatwg.org/#concept-urlencoded-serializer
#
# URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
# #=> "q=ruby&lang=en"
@@ -420,7 +351,7 @@ module URI
# URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
# #=> "q=ruby&q=perl&lang=en"
#
- # See URI.encode_www_form_component, URI.decode_www_form
+ # See URI.encode_www_form_component, URI.decode_www_form.
def self.encode_www_form(enum, enc=nil)
enum.map do |k,v|
if v.nil?
@@ -441,22 +372,22 @@ module URI
end.join('&')
end
- # Decode URL-encoded form data from given +str+.
+ # Decodes URL-encoded form data from given +str+.
#
# This decodes application/x-www-form-urlencoded data
- # and returns array of key-value array.
+ # and returns an array of key-value arrays.
#
- # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser ,
- # so this supports only &-separator, don't support ;-separator.
+ # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser,
+ # so this supports only &-separator, and doesn't support ;-separator.
#
# ary = URI.decode_www_form("a=1&a=2&b=3")
- # p ary #=> [['a', '1'], ['a', '2'], ['b', '3']]
- # p ary.assoc('a').last #=> '1'
- # p ary.assoc('b').last #=> '3'
- # p ary.rassoc('a').last #=> '2'
- # p Hash[ary] # => {"a"=>"2", "b"=>"3"}
+ # ary #=> [['a', '1'], ['a', '2'], ['b', '3']]
+ # ary.assoc('a').last #=> '1'
+ # ary.assoc('b').last #=> '3'
+ # ary.rassoc('a').last #=> '2'
+ # Hash[ary] #=> {"a"=>"2", "b"=>"3"}
#
- # See URI.decode_www_form_component, URI.encode_www_form
+ # See URI.decode_www_form_component, URI.encode_www_form.
def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false)
raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only?
ary = []
@@ -468,7 +399,7 @@ module URI
if isindex
if sep.empty?
val = key
- key = ''
+ key = +''
end
isindex = false
end
@@ -482,7 +413,7 @@ module URI
if val
val.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_)
else
- val = ''
+ val = +''
end
ary << [key, val]
@@ -734,7 +665,7 @@ end # module URI
module Kernel
#
- # Returns +uri+ converted to a URI object.
+ # Returns +uri+ converted to an URI object.
#
def URI(uri)
if uri.is_a?(URI::Generic)
diff --git a/lib/uri/file.rb b/lib/uri/file.rb
new file mode 100644
index 0000000000..561ec703c4
--- /dev/null
+++ b/lib/uri/file.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require_relative 'generic'
+
+module URI
+
+ #
+ # The "file" URI is defined by RFC8089.
+ #
+ class File < Generic
+ # A Default port of nil for URI::File.
+ DEFAULT_PORT = nil
+
+ #
+ # An Array of the available components for URI::File.
+ #
+ COMPONENT = [
+ :scheme,
+ :host,
+ :path
+ ].freeze
+
+ #
+ # == Description
+ #
+ # Creates a new URI::File object from components, with syntax checking.
+ #
+ # The components accepted are +host+ and +path+.
+ #
+ # The components should be provided either as an Array, or as a Hash
+ # with keys formed by preceding the component names with a colon.
+ #
+ # If an Array is used, the components must be passed in the
+ # order <code>[host, path]</code>.
+ #
+ # Examples:
+ #
+ # require 'uri'
+ #
+ # uri1 = URI::File.build(['host.example.com', '/path/file.zip'])
+ # uri1.to_s # => "file://host.example.com/path/file.zip"
+ #
+ # uri2 = URI::File.build({:host => 'host.example.com',
+ # :path => '/ruby/src'})
+ # uri2.to_s # => "file://host.example.com/ruby/src"
+ #
+ def self.build(args)
+ tmp = Util::make_components_hash(self, args)
+ super(tmp)
+ end
+
+ # Protected setter for the host component +v+.
+ #
+ # See also URI::Generic.host=.
+ #
+ def set_host(v)
+ v = "" if v.nil? || v == "localhost"
+ @host = v
+ end
+
+ # do nothing
+ def set_port(v)
+ end
+
+ # raise InvalidURIError
+ def check_userinfo(user)
+ raise URI::InvalidURIError, "can not set userinfo for file URI"
+ end
+
+ # raise InvalidURIError
+ def check_user(user)
+ raise URI::InvalidURIError, "can not set user for file URI"
+ end
+
+ # raise InvalidURIError
+ def check_password(user)
+ raise URI::InvalidURIError, "can not set password for file URI"
+ end
+
+ # do nothing
+ def set_userinfo(v)
+ end
+
+ # do nothing
+ def set_user(v)
+ end
+
+ # do nothing
+ def set_password(v)
+ end
+ end
+
+ @@schemes['FILE'] = File
+end
diff --git a/lib/uri/ftp.rb b/lib/uri/ftp.rb
index 90c1403ce6..fb38481193 100644
--- a/lib/uri/ftp.rb
+++ b/lib/uri/ftp.rb
@@ -3,12 +3,11 @@
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
#
# See URI for general documentation
#
-require 'uri/generic'
+require_relative 'generic'
module URI
@@ -21,11 +20,11 @@ module URI
# http://tools.ietf.org/html/draft-hoffman-ftp-uri-04
#
class FTP < Generic
- # A Default port of 21 for URI::FTP
+ # A Default port of 21 for URI::FTP.
DEFAULT_PORT = 21
#
- # An Array of the available components for URI::FTP
+ # An Array of the available components for URI::FTP.
#
COMPONENT = [
:scheme,
@@ -34,7 +33,7 @@ module URI
].freeze
#
- # Typecode is "a", "i" or "d".
+ # Typecode is "a", "i", or "d".
#
# * "a" indicates a text file (the FTP command was ASCII)
# * "i" indicates a binary file (FTP command IMAGE)
@@ -42,8 +41,7 @@ module URI
#
TYPECODE = ['a', 'i', 'd'].freeze
- # Typecode prefix
- # ';type='
+ # Typecode prefix ";type=".
TYPECODE_PREFIX = ';type='.freeze
def self.new2(user, password, host, port, path,
@@ -71,27 +69,29 @@ module URI
#
# Creates a new URI::FTP object from components, with syntax checking.
#
- # The components accepted are +userinfo+, +host+, +port+, +path+ and
+ # The components accepted are +userinfo+, +host+, +port+, +path+, and
# +typecode+.
#
# The components should be provided either as an Array, or as a Hash
# with keys formed by preceding the component names with a colon.
#
- # If an Array is used, the components must be passed in the order
- # [userinfo, host, port, path, typecode]
+ # If an Array is used, the components must be passed in the
+ # order <code>[userinfo, host, port, path, typecode]</code>.
#
# If the path supplied is absolute, it will be escaped in order to
- # make it absolute in the URI. Examples:
+ # make it absolute in the URI.
+ #
+ # Examples:
#
# require 'uri'
#
- # uri = URI::FTP.build(['user:password', 'ftp.example.com', nil,
+ # uri1 = URI::FTP.build(['user:password', 'ftp.example.com', nil,
# '/path/file.zip', 'i'])
- # puts uri.to_s -> ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=i
+ # uri1.to_s # => "ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=i"
#
# uri2 = URI::FTP.build({:host => 'ftp.example.com',
# :path => 'ruby/src'})
- # puts uri2.to_s -> ftp://ftp.example.com/ruby/src
+ # uri2.to_s # => "ftp://ftp.example.com/ruby/src"
#
def self.build(args)
@@ -128,7 +128,7 @@ module URI
# required by RFC1738; instead it is treated as per RFC2396.
#
# Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
- # +opaque+, +query+ and +fragment+, in that order.
+ # +opaque+, +query+, and +fragment+, in that order.
#
def initialize(scheme,
userinfo, host, port, registry,
@@ -155,13 +155,13 @@ module URI
end
end
- # typecode accessor
+ # typecode accessor.
#
- # see URI::FTP::COMPONENT
+ # See URI::FTP::COMPONENT.
attr_reader :typecode
- # validates typecode +v+,
- # returns a +true+ or +false+ boolean
+ # Validates typecode +v+,
+ # returns +true+ or +false+.
#
def check_typecode(v)
if TYPECODE.include?(v)
@@ -173,9 +173,9 @@ module URI
end
private :check_typecode
- # Private setter for the typecode +v+
+ # Private setter for the typecode +v+.
#
- # see also URI::FTP.typecode=
+ # See also URI::FTP.typecode=.
#
def set_typecode(v)
@typecode = v
@@ -190,21 +190,20 @@ module URI
#
# == Description
#
- # public setter for the typecode +v+.
- # (with validation)
+ # Public setter for the typecode +v+
+ # (with validation).
#
- # see also URI::FTP.check_typecode
+ # See also URI::FTP.check_typecode.
#
# == Usage
#
# require 'uri'
#
# uri = URI.parse("ftp://john@ftp.example.com/my_file.img")
- # #=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img>
+ # #=> #<URI::FTP ftp://john@ftp.example.com/my_file.img>
# uri.typecode = "i"
- # # => "i"
# uri
- # #=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img;type=i>
+ # #=> #<URI::FTP ftp://john@ftp.example.com/my_file.img;type=i>
#
def typecode=(typecode)
check_typecode(typecode)
@@ -226,29 +225,29 @@ module URI
# RFC 1738 specifically states that the path for an FTP URI does not
# include the / which separates the URI path from the URI host. Example:
#
- # +ftp://ftp.example.com/pub/ruby+
+ # <code>ftp://ftp.example.com/pub/ruby</code>
#
# The above URI indicates that the client should connect to
- # ftp.example.com then cd pub/ruby from the initial login directory.
+ # ftp.example.com then cd to pub/ruby from the initial login directory.
#
# If you want to cd to an absolute directory, you must include an
# escaped / (%2F) in the path. Example:
#
- # +ftp://ftp.example.com/%2Fpub/ruby+
+ # <code>ftp://ftp.example.com/%2Fpub/ruby</code>
#
- # This method will then return "/pub/ruby"
+ # This method will then return "/pub/ruby".
#
def path
return @path.sub(/^\//,'').sub(/^%2F/,'/')
end
- # Private setter for the path of the URI::FTP
+ # Private setter for the path of the URI::FTP.
def set_path(v)
super("/" + v.sub(/^\//, "%2F"))
end
protected :set_path
- # Returns a String representation of the URI::FTP
+ # Returns a String representation of the URI::FTP.
def to_s
save_path = nil
if @typecode
diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index 2a066a4cb6..a4192c6557 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -4,12 +4,11 @@
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
#
# See URI for general documentation
#
-require 'uri/common'
+require_relative 'common'
autoload :IPSocket, 'socket'
autoload :IPAddr, 'ipaddr'
@@ -23,26 +22,26 @@ module URI
include URI
#
- # A Default port of nil for URI::Generic
+ # A Default port of nil for URI::Generic.
#
DEFAULT_PORT = nil
#
- # Returns default port
+ # Returns default port.
#
def self.default_port
self::DEFAULT_PORT
end
#
- # Returns default port
+ # Returns default port.
#
def default_port
self.class.default_port
end
#
- # An Array of the available components for URI::Generic
+ # An Array of the available components for URI::Generic.
#
COMPONENT = [
:scheme,
@@ -68,14 +67,13 @@ module URI
#
# == Synopsis
#
- # See #new
+ # See ::new.
#
# == Description
#
# At first, tries to create a new URI::Generic instance using
# URI::Generic::build. But, if exception URI::InvalidComponentError is raised,
- # then it URI::Escape.escape all URI components and tries again.
- #
+ # then it does URI::Escape.escape all URI components and tries again.
#
def self.build2(args)
begin
@@ -106,14 +104,14 @@ module URI
#
# == Synopsis
#
- # See #new
+ # See ::new.
#
# == Description
#
# Creates a new URI::Generic instance from components of URI::Generic
# with check. Components are: scheme, userinfo, host, port, registry, path,
- # opaque, query and fragment. You can provide arguments either by an Array or a Hash.
- # See #new for hash keys to use or for order of array items.
+ # opaque, query, and fragment. You can provide arguments either by an Array or a Hash.
+ # See ::new for hash keys to use or for order of array items.
#
def self.build(args)
if args.kind_of?(Array) &&
@@ -137,31 +135,32 @@ module URI
tmp << true
return self.new(*tmp)
end
+
#
# == Args
#
# +scheme+::
# Protocol scheme, i.e. 'http','ftp','mailto' and so on.
# +userinfo+::
- # User name and password, i.e. 'sdmitry:bla'
+ # User name and password, i.e. 'sdmitry:bla'.
# +host+::
- # Server host name
+ # Server host name.
# +port+::
- # Server port
+ # Server port.
# +registry+::
# Registry of naming authorities.
# +path+::
- # Path on server
+ # Path on server.
# +opaque+::
- # Opaque part
+ # Opaque part.
# +query+::
- # Query data
+ # Query data.
# +fragment+::
- # A part of URI after '#' sign
+ # Part of the URI after '#' character.
# +parser+::
- # Parser for internal use [URI::DEFAULT_PARSER by default]
+ # Parser for internal use [URI::DEFAULT_PARSER by default].
# +arg_check+::
- # Check arguments [false by default]
+ # Check arguments [false by default].
#
# == Description
#
@@ -215,39 +214,38 @@ module URI
end
#
- # returns the scheme component of the URI.
+ # Returns the scheme component of the URI.
#
# URI("http://foo/bar/baz").scheme #=> "http"
#
attr_reader :scheme
- # returns the host component of the URI.
+ # Returns the host component of the URI.
#
# URI("http://foo/bar/baz").host #=> "foo"
#
- # It returns nil if no host component.
+ # It returns nil if no host component exists.
#
# URI("mailto:foo@example.org").host #=> nil
#
- # The component doesn't contains the port number.
+ # The component does not contain the port number.
#
# URI("http://foo:8080/bar/baz").host #=> "foo"
#
- # Since IPv6 addresses are wrapped by brackets in URIs,
- # this method returns IPv6 addresses wrapped by brackets.
- # This form is not appropriate to pass socket methods such as TCPSocket.open.
- # If unwrapped host names are required, use "hostname" method.
+ # Since IPv6 addresses are wrapped with brackets in URIs,
+ # this method returns IPv6 addresses wrapped with brackets.
+ # This form is not appropriate to pass to socket methods such as TCPSocket.open.
+ # If unwrapped host names are required, use the #hostname method.
#
- # URI("http://[::1]/bar/baz").host #=> "[::1]"
+ # URI("http://[::1]/bar/baz").host #=> "[::1]"
# URI("http://[::1]/bar/baz").hostname #=> "::1"
#
attr_reader :host
- # returns the port component of the URI.
+ # Returns the port component of the URI.
#
- # URI("http://foo/bar/baz").port #=> "80"
- #
- # URI("http://foo:8080/bar/baz").port #=> "8080"
+ # URI("http://foo/bar/baz").port #=> 80
+ # URI("http://foo:8080/bar/baz").port #=> 8080
#
attr_reader :port
@@ -255,37 +253,38 @@ module URI
nil
end
- # returns the path component of the URI.
+ # Returns the path component of the URI.
#
# URI("http://foo/bar/baz").path #=> "/bar/baz"
#
attr_reader :path
- # returns the query component of the URI.
+ # Returns the query component of the URI.
#
# URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar"
#
attr_reader :query
- # returns the opaque part of the URI.
+ # Returns the opaque part of the URI.
#
# URI("mailto:foo@example.org").opaque #=> "foo@example.org"
+ # URI("http://foo/bar/baz").opaque #=> nil
#
- # Portion of the path that does make use of the slash '/'.
- # The path typically refers to the absolute path and the opaque part.
+ # The portion of the path that does not make use of the slash '/'.
+ # The path typically refers to an absolute path or an opaque part.
# (See RFC2396 Section 3 and 5.2.)
#
attr_reader :opaque
- # returns the fragment component of the URI.
+ # Returns the fragment component of the URI.
#
# URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies"
#
attr_reader :fragment
- # returns the parser to be used.
+ # Returns the parser to be used.
#
- # Unless a URI::Parser is defined, then DEFAULT_PARSER is used.
+ # Unless a URI::Parser is defined, DEFAULT_PARSER is used.
#
def parser
if !defined?(@parser) || !@parser
@@ -295,7 +294,8 @@ module URI
end
end
- # replace self by other URI object
+ # Replaces self by other URI object.
+ #
def replace!(oth)
if self.class != oth.class
raise ArgumentError, "expected #{self.class} object"
@@ -315,7 +315,7 @@ module URI
end
#
- # check the scheme +v+ component against the URI::Parser Regexp for :SCHEME
+ # Checks the scheme +v+ component against the URI::Parser Regexp for :SCHEME.
#
def check_scheme(v)
if v && parser.regexp[:SCHEME] !~ v
@@ -327,9 +327,9 @@ module URI
end
private :check_scheme
- # protected setter for the scheme component +v+
+ # Protected setter for the scheme component +v+.
#
- # see also URI::Generic.scheme=
+ # See also URI::Generic.scheme=.
#
def set_scheme(v)
@scheme = v&.downcase
@@ -344,10 +344,10 @@ module URI
#
# == Description
#
- # public setter for the scheme component +v+.
- # (with validation)
+ # Public setter for the scheme component +v+
+ # (with validation).
#
- # see also URI::Generic.check_scheme
+ # See also URI::Generic.check_scheme.
#
# == Usage
#
@@ -355,9 +355,7 @@ module URI
#
# uri = URI.parse("http://my.example.com")
# uri.scheme = "https"
- # # => "https"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:https://my.example.com>
+ # uri.to_s #=> "https://my.example.com"
#
def scheme=(v)
check_scheme(v)
@@ -366,13 +364,13 @@ module URI
end
#
- # check the +user+ and +password+.
+ # Checks the +user+ and +password+.
#
# If +password+ is not provided, then +user+ is
# split, using URI::Generic.split_userinfo, to
# pull +user+ and +password.
#
- # see also URI::Generic.check_user, URI::Generic.check_password
+ # See also URI::Generic.check_user, URI::Generic.check_password.
#
def check_userinfo(user, password = nil)
if !password
@@ -386,8 +384,8 @@ module URI
private :check_userinfo
#
- # check the user +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :USERINFO
+ # Checks the user +v+ component for RFC2396 compliance
+ # and against the URI::Parser Regexp for :USERINFO.
#
# Can not have a registry or opaque component defined,
# with a user component defined.
@@ -410,8 +408,8 @@ module URI
private :check_user
#
- # check the password +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :USERINFO
+ # Checks the password +v+ component for RFC2396 compliance
+ # and against the URI::Parser Regexp for :USERINFO.
#
# Can not have a registry or opaque component defined,
# with a user component defined.
@@ -438,7 +436,7 @@ module URI
private :check_password
#
- # Sets userinfo, argument is string like 'name:pass'
+ # Sets userinfo, argument is string like 'name:pass'.
#
def userinfo=(userinfo)
if userinfo.nil?
@@ -457,10 +455,10 @@ module URI
#
# == Description
#
- # public setter for the +user+ component.
- # (with validation)
+ # Public setter for the +user+ component
+ # (with validation).
#
- # see also URI::Generic.check_user
+ # See also URI::Generic.check_user.
#
# == Usage
#
@@ -468,9 +466,7 @@ module URI
#
# uri = URI.parse("http://john:S3nsit1ve@my.example.com")
# uri.user = "sam"
- # # => "sam"
- # uri
- # #=> #<URI::HTTP:0x00000000881d90 URL:http://sam:V3ry_S3nsit1ve@my.example.com>
+ # uri.to_s #=> "http://sam:V3ry_S3nsit1ve@my.example.com"
#
def user=(user)
check_user(user)
@@ -486,10 +482,10 @@ module URI
#
# == Description
#
- # public setter for the +password+ component.
- # (with validation)
+ # Public setter for the +password+ component
+ # (with validation).
#
- # see also URI::Generic.check_password
+ # See also URI::Generic.check_password.
#
# == Usage
#
@@ -497,9 +493,7 @@ module URI
#
# uri = URI.parse("http://john:S3nsit1ve@my.example.com")
# uri.password = "V3ry_S3nsit1ve"
- # # => "V3ry_S3nsit1ve"
- # uri
- # #=> #<URI::HTTP:0x00000000881d90 URL:http://john:V3ry_S3nsit1ve@my.example.com>
+ # uri.to_s #=> "http://john:V3ry_S3nsit1ve@my.example.com"
#
def password=(password)
check_password(password)
@@ -507,10 +501,10 @@ module URI
# returns password
end
- # protect setter for the +user+ component, and +password+ if available.
- # (with validation)
+ # Protected setter for the +user+ component, and +password+ if available
+ # (with validation).
#
- # see also URI::Generic.userinfo=
+ # See also URI::Generic.userinfo=.
#
def set_userinfo(user, password = nil)
unless password
@@ -523,9 +517,9 @@ module URI
end
protected :set_userinfo
- # protected setter for the user component +v+
+ # Protected setter for the user component +v+.
#
- # see also URI::Generic.user=
+ # See also URI::Generic.user=.
#
def set_user(v)
set_userinfo(v, @password)
@@ -533,9 +527,9 @@ module URI
end
protected :set_user
- # protected setter for the password component +v+
+ # Protected setter for the password component +v+.
#
- # see also URI::Generic.password=
+ # See also URI::Generic.password=.
#
def set_password(v)
@password = v
@@ -543,8 +537,8 @@ module URI
end
protected :set_password
- # returns the userinfo +ui+ as user, password
- # if properly formatted as 'user:password'
+ # Returns the userinfo +ui+ as <code>[user, password]</code>
+ # if properly formatted as 'user:password'.
def split_userinfo(ui)
return nil, nil unless ui
user, password = ui.split(':', 2)
@@ -553,13 +547,13 @@ module URI
end
private :split_userinfo
- # escapes 'user:password' +v+ based on RFC 1738 section 3.1
+ # Escapes 'user:password' +v+ based on RFC 1738 section 3.1.
def escape_userpass(v)
parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
end
private :escape_userpass
- # returns the userinfo, either as 'user' or 'user:password'
+ # Returns the userinfo, either as 'user' or 'user:password'.
def userinfo
if @user.nil?
nil
@@ -570,19 +564,19 @@ module URI
end
end
- # returns the user component
+ # Returns the user component.
def user
@user
end
- # returns the password component
+ # Returns the password component.
def password
@password
end
#
- # check the host +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :HOST
+ # Checks the host +v+ component for RFC2396 compliance
+ # and against the URI::Parser Regexp for :HOST.
#
# Can not have a registry or opaque component defined,
# with a host component defined.
@@ -602,9 +596,9 @@ module URI
end
private :check_host
- # protected setter for the host component +v+
+ # Protected setter for the host component +v+.
#
- # see also URI::Generic.host=
+ # See also URI::Generic.host=.
#
def set_host(v)
@host = v
@@ -619,10 +613,10 @@ module URI
#
# == Description
#
- # public setter for the host component +v+.
- # (with validation)
+ # Public setter for the host component +v+
+ # (with validation).
#
- # see also URI::Generic.check_host
+ # See also URI::Generic.check_host.
#
# == Usage
#
@@ -630,9 +624,7 @@ module URI
#
# uri = URI.parse("http://my.example.com")
# uri.host = "foo.com"
- # # => "foo.com"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://foo.com>
+ # uri.to_s #=> "http://foo.com"
#
def host=(v)
check_host(v)
@@ -640,32 +632,31 @@ module URI
v
end
- # extract the host part of the URI and unwrap brackets for IPv6 addresses.
+ # Extract the host part of the URI and unwrap brackets for IPv6 addresses.
#
- # This method is same as URI::Generic#host except
+ # This method is the same as URI::Generic#host except
# brackets for IPv6 (and future IP) addresses are removed.
#
- # u = URI("http://[::1]/bar")
- # p u.hostname #=> "::1"
- # p u.host #=> "[::1]"
+ # uri = URI("http://[::1]/bar")
+ # uri.hostname #=> "::1"
+ # uri.host #=> "[::1]"
#
def hostname
v = self.host
/\A\[(.*)\]\z/ =~ v ? $1 : v
end
- # set the host part of the URI as the argument with brackets for IPv6 addresses.
+ # Sets the host part of the URI as the argument with brackets for IPv6 addresses.
#
- # This method is same as URI::Generic#host= except
- # the argument can be bare IPv6 address.
+ # This method is the same as URI::Generic#host= except
+ # the argument can be a bare IPv6 address.
#
- # u = URI("http://foo/bar")
- # p u.to_s #=> "http://foo/bar"
- # u.hostname = "::1"
- # p u.to_s #=> "http://[::1]/bar"
+ # uri = URI("http://foo/bar")
+ # uri.hostname = "::1"
+ # uri.to_s #=> "http://[::1]/bar"
#
- # If the argument seems IPv6 address,
- # it is wrapped by brackets.
+ # If the argument seems to be an IPv6 address,
+ # it is wrapped with brackets.
#
def hostname=(v)
v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
@@ -673,8 +664,8 @@ module URI
end
#
- # check the port +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :PORT
+ # Checks the port +v+ component for RFC2396 compliance
+ # and against the URI::Parser Regexp for :PORT.
#
# Can not have a registry or opaque component defined,
# with a port component defined.
@@ -694,9 +685,9 @@ module URI
end
private :check_port
- # protected setter for the port component +v+
+ # Protected setter for the port component +v+.
#
- # see also URI::Generic.port=
+ # See also URI::Generic.port=.
#
def set_port(v)
v = v.empty? ? nil : v.to_i unless !v || v.kind_of?(Integer)
@@ -712,10 +703,10 @@ module URI
#
# == Description
#
- # public setter for the port component +v+.
- # (with validation)
+ # Public setter for the port component +v+
+ # (with validation).
#
- # see also URI::Generic.check_port
+ # See also URI::Generic.check_port.
#
# == Usage
#
@@ -723,9 +714,7 @@ module URI
#
# uri = URI.parse("http://my.example.com")
# uri.port = 8080
- # # => 8080
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com:8080>
+ # uri.to_s #=> "http://my.example.com:8080"
#
def port=(v)
check_port(v)
@@ -748,9 +737,9 @@ module URI
end
#
- # check the path +v+ component for RFC2396 compliance
+ # Checks the path +v+ component for RFC2396 compliance
# and against the URI::Parser Regexp
- # for :ABS_PATH and :REL_PATH
+ # for :ABS_PATH and :REL_PATH.
#
# Can not have a opaque component defined,
# with a path component defined.
@@ -783,9 +772,9 @@ module URI
end
private :check_path
- # protected setter for the path component +v+
+ # Protected setter for the path component +v+.
#
- # see also URI::Generic.path=
+ # See also URI::Generic.path=.
#
def set_path(v)
@path = v
@@ -800,10 +789,10 @@ module URI
#
# == Description
#
- # public setter for the path component +v+.
- # (with validation)
+ # Public setter for the path component +v+
+ # (with validation).
#
- # see also URI::Generic.check_path
+ # See also URI::Generic.check_path.
#
# == Usage
#
@@ -811,9 +800,7 @@ module URI
#
# uri = URI.parse("http://my.example.com/pub/files")
# uri.path = "/faq/"
- # # => "/faq/"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/faq/>
+ # uri.to_s #=> "http://my.example.com/faq/"
#
def path=(v)
check_path(v)
@@ -829,7 +816,7 @@ module URI
#
# == Description
#
- # public setter for the query component +v+.
+ # Public setter for the query component +v+.
#
# == Usage
#
@@ -837,9 +824,7 @@ module URI
#
# uri = URI.parse("http://my.example.com/?id=25")
# uri.query = "id=1"
- # # => "id=1"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/?id=1>
+ # uri.to_s #=> "http://my.example.com/?id=1"
#
def query=(v)
return @query = nil unless v
@@ -850,16 +835,17 @@ module URI
v.encode!(Encoding::UTF_8) rescue nil
v.delete!("\t\r\n")
v.force_encoding(Encoding::ASCII_8BIT)
+ raise InvalidURIError, "invalid percent escape: #{$1}" if /(%\H\H)/n.match(v)
v.gsub!(/(?!%\h\h|[!$-&(-;=?-_a-~])./n.freeze){'%%%02X' % $&.ord}
v.force_encoding(Encoding::US_ASCII)
@query = v
end
#
- # check the opaque +v+ component for RFC2396 compliance and
- # against the URI::Parser Regexp for :OPAQUE
+ # Checks the opaque +v+ component for RFC2396 compliance and
+ # against the URI::Parser Regexp for :OPAQUE.
#
- # Can not have a host, port, user or path component defined,
+ # Can not have a host, port, user, or path component defined,
# with an opaque component defined.
#
def check_opaque(v)
@@ -880,9 +866,9 @@ module URI
end
private :check_opaque
- # protected setter for the opaque component +v+
+ # Protected setter for the opaque component +v+.
#
- # see also URI::Generic.opaque=
+ # See also URI::Generic.opaque=.
#
def set_opaque(v)
@opaque = v
@@ -897,10 +883,10 @@ module URI
#
# == Description
#
- # public setter for the opaque component +v+.
- # (with validation)
+ # Public setter for the opaque component +v+
+ # (with validation).
#
- # see also URI::Generic.check_opaque
+ # See also URI::Generic.check_opaque.
#
def opaque=(v)
check_opaque(v)
@@ -909,7 +895,7 @@ module URI
end
#
- # check the fragment +v+ component against the URI::Parser Regexp for :FRAGMENT
+ # Checks the fragment +v+ component against the URI::Parser Regexp for :FRAGMENT.
#
#
# == Args
@@ -919,8 +905,8 @@ module URI
#
# == Description
#
- # public setter for the fragment component +v+.
- # (with validation)
+ # Public setter for the fragment component +v+
+ # (with validation).
#
# == Usage
#
@@ -928,9 +914,7 @@ module URI
#
# uri = URI.parse("http://my.example.com/?id=25#time=1305212049")
# uri.fragment = "time=1305212086"
- # # => "time=1305212086"
- # uri
- # #=> #<URI::HTTP:0x000000007a81f8 URL:http://my.example.com/?id=25#time=1305212086>
+ # uri.to_s #=> "http://my.example.com/?id=25#time=1305212086"
#
def fragment=(v)
return @fragment = nil unless v
@@ -946,7 +930,23 @@ module URI
end
#
- # Checks if URI has a path
+ # Returns true if URI is hierarchical.
+ #
+ # == Description
+ #
+ # URI has components listed in order of decreasing significance from left to right,
+ # see RFC3986 https://tools.ietf.org/html/rfc3986 1.2.3.
+ #
+ # == Usage
+ #
+ # require 'uri'
+ #
+ # uri = URI.parse("http://my.example.com/")
+ # uri.hierarchical?
+ # #=> true
+ # uri = URI.parse("mailto:joe@example.com")
+ # uri.hierarchical?
+ # #=> false
#
def hierarchical?
if @path
@@ -957,7 +957,7 @@ module URI
end
#
- # Checks if URI is an absolute one
+ # Returns true if URI has a scheme (e.g. http:// or https://) specified.
#
def absolute?
if @scheme
@@ -969,17 +969,17 @@ module URI
alias absolute absolute?
#
- # Checks if URI is relative
+ # Returns true if URI does not have a scheme (e.g. http:// or https://) specified.
#
def relative?
!absolute?
end
#
- # returns an Array of the path split on '/'
+ # Returns an Array of the path split on '/'.
#
def split_path(path)
- path.split(%r{/+}, -1)
+ path.split("/", -1)
end
private :split_path
@@ -1058,7 +1058,7 @@ module URI
#
# == Description
#
- # Destructive form of #merge
+ # Destructive form of #merge.
#
# == Usage
#
@@ -1066,8 +1066,7 @@ module URI
#
# uri = URI.parse("http://my.example.com")
# uri.merge!("/main.rbx?page=1")
- # p uri
- # # => #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
+ # uri.to_s # => "http://my.example.com/main.rbx?page=1"
#
def merge!(oth)
t = merge(oth)
@@ -1087,18 +1086,18 @@ module URI
#
# == Description
#
- # Merges two URI's.
+ # Merges two URIs.
#
# == Usage
#
# require 'uri'
#
# uri = URI.parse("http://my.example.com")
- # p uri.merge("/main.rbx?page=1")
- # # => #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
+ # uri.merge("/main.rbx?page=1")
+ # # => "http://my.example.com/main.rbx?page=1"
#
def merge(oth)
- rel = parser.send(:convert_to_uri, oth)
+ rel = parser.__send__(:convert_to_uri, oth)
if rel.absolute?
#raise BadURIError, "both URI are absolute" if absolute?
@@ -1154,8 +1153,8 @@ module URI
return dst.dup
end
- src_path = src.scan(%r{(?:\A|[^/]+)/})
- dst_path = dst.scan(%r{(?:\A|[^/]+)/?})
+ src_path = src.scan(%r{[^/]*/})
+ dst_path = dst.scan(%r{[^/]*/?})
# discard same parts
while !dst_path.empty? && dst_path.first == src_path.first
@@ -1183,7 +1182,7 @@ module URI
# :stopdoc:
def route_from0(oth)
- oth = parser.send(:convert_to_uri, oth)
+ oth = parser.__send__(:convert_to_uri, oth)
if self.relative?
raise BadURIError,
"relative URI: #{self}"
@@ -1240,15 +1239,15 @@ module URI
#
# == Description
#
- # Calculates relative path from oth to self
+ # Calculates relative path from oth to self.
#
# == Usage
#
# require 'uri'
#
# uri = URI.parse('http://my.example.com/main.rbx?page=1')
- # p uri.route_from('http://my.example.com')
- # #=> #<URI::Generic:0x20218858 URL:/main.rbx?page=1>
+ # uri.route_from('http://my.example.com')
+ # #=> #<URI::Generic /main.rbx?page=1>
#
def route_from(oth)
# you can modify `rel', but can not `oth'.
@@ -1280,18 +1279,18 @@ module URI
#
# == Description
#
- # Calculates relative path to oth from self
+ # Calculates relative path to oth from self.
#
# == Usage
#
# require 'uri'
#
# uri = URI.parse('http://my.example.com')
- # p uri.route_to('http://my.example.com/main.rbx?page=1')
- # #=> #<URI::Generic:0x2020c2f6 URL:/main.rbx?page=1>
+ # uri.route_to('http://my.example.com/main.rbx?page=1')
+ # #=> #<URI::Generic /main.rbx?page=1>
#
def route_to(oth)
- parser.send(:convert_to_uri, oth).route_from(self)
+ parser.__send__(:convert_to_uri, oth).route_from(self)
end
#
@@ -1314,7 +1313,7 @@ module URI
end
#
- # Destructive version of #normalize
+ # Destructive version of #normalize.
#
def normalize!
if path&.empty?
@@ -1329,7 +1328,7 @@ module URI
end
#
- # Constructs String from URI
+ # Constructs String from URI.
#
def to_s
str = ''.dup
@@ -1341,7 +1340,7 @@ module URI
if @opaque
str << @opaque
else
- if @host
+ if @host || %w[file postgres].include?(@scheme)
str << '//'
end
if self.userinfo
@@ -1369,7 +1368,7 @@ module URI
end
#
- # Compares two URIs
+ # Compares two URIs.
#
def ==(oth)
if self.class == oth.class
@@ -1402,10 +1401,10 @@ module URI
=end
- # returns an Array of the components defined from the COMPONENT Array
+ # Returns an Array of the components defined from the COMPONENT Array.
def component_ary
component.collect do |x|
- self.send(x)
+ self.__send__(x)
end
end
protected :component_ary
@@ -1413,24 +1412,24 @@ module URI
# == Args
#
# +components+::
- # Multiple Symbol arguments defined in URI::HTTP
+ # Multiple Symbol arguments defined in URI::HTTP.
#
# == Description
#
- # Selects specified components from URI
+ # Selects specified components from URI.
#
# == Usage
#
# require 'uri'
#
# uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx')
- # p uri.select(:userinfo, :host, :path)
+ # uri.select(:userinfo, :host, :path)
# # => ["myuser:mypass", "my.example.com", "/test.rbx"]
#
def select(*components)
components.collect do |c|
if component.include?(c)
- self.send(c)
+ self.__send__(c)
else
raise ArgumentError,
"expected of components of #{self.class} (#{self.class.component.join(', ')})"
@@ -1450,8 +1449,8 @@ module URI
#
# == Description
#
- # attempts to parse other URI +oth+,
- # returns [parsed_oth, self]
+ # Attempts to parse other URI +oth+,
+ # returns [parsed_oth, self].
#
# == Usage
#
@@ -1459,7 +1458,7 @@ module URI
#
# uri = URI.parse("http://my.example.com")
# uri.coerce("http://foo.com")
- # #=> [#<URI::HTTP:0x00000000bcb028 URL:http://foo.com/>, #<URI::HTTP:0x00000000d92178 URL:http://my.example.com>]
+ # #=> [#<URI::HTTP http://foo.com>, #<URI::HTTP http://my.example.com>]
#
def coerce(oth)
case oth
@@ -1472,15 +1471,15 @@ module URI
return oth, self
end
- # returns a proxy URI.
+ # Returns a proxy URI.
# The proxy URI is obtained from environment variables such as http_proxy,
# ftp_proxy, no_proxy, etc.
# If there is no proper proxy, nil is returned.
#
- # If the optional parameter, +env+, is specified, it is used instead of ENV.
+ # If the optional parameter +env+ is specified, it is used instead of ENV.
#
# Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
- # are examined too.
+ # are examined, too.
#
# But http_proxy and HTTP_PROXY is treated specially under CGI environment.
# It's because HTTP_PROXY may be set by Proxy: header.
@@ -1517,7 +1516,7 @@ module URI
elsif name == 'http_proxy'
unless proxy_uri = env[name]
if proxy_uri = env[name.upcase]
- warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
+ warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.', uplevel: 1
end
end
else
@@ -1544,11 +1543,16 @@ module URI
end
def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc:
- no_proxy.scan(/(?!\.)([^:,\s]+)(?::(\d+))?/) {|p_host, p_port|
+ hostname = hostname.downcase
+ dothostname = ".#{hostname}"
+ no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) {|p_host, p_port|
if !p_port || port == p_port.to_i
- if /(\A|\.)#{Regexp.quote p_host}\z/i =~ hostname
- return false
- elsif addr
+ if p_host.start_with?('.')
+ return false if hostname.end_with?(p_host.downcase)
+ else
+ return false if dothostname.end_with?(".#{p_host.downcase}")
+ end
+ if addr
begin
return false if IPAddr.new(p_host).include?(addr)
rescue IPAddr::InvalidAddressError
diff --git a/lib/uri/http.rb b/lib/uri/http.rb
index 0af1858efe..70cfb2a1bf 100644
--- a/lib/uri/http.rb
+++ b/lib/uri/http.rb
@@ -3,12 +3,11 @@
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
#
# See URI for general documentation
#
-require 'uri/generic'
+require_relative 'generic'
module URI
@@ -21,10 +20,10 @@ module URI
# update. See <URL:http://support.microsoft.com/kb/834489>.
#
class HTTP < Generic
- # A Default port of 80 for URI::HTTP
+ # A Default port of 80 for URI::HTTP.
DEFAULT_PORT = 80
- # An Array of the available components for URI::HTTP
+ # An Array of the available components for URI::HTTP.
COMPONENT = %i[
scheme
userinfo host port
@@ -36,22 +35,22 @@ module URI
#
# == Description
#
- # Create a new URI::HTTP object from components, with syntax checking.
+ # Creates a new URI::HTTP object from components, with syntax checking.
#
- # The components accepted are userinfo, host, port, path, query and
+ # The components accepted are userinfo, host, port, path, query, and
# fragment.
#
# The components should be provided either as an Array, or as a Hash
# with keys formed by preceding the component names with a colon.
#
- # If an Array is used, the components must be passed in the order
- # [userinfo, host, port, path, query, fragment].
+ # If an Array is used, the components must be passed in the
+ # order <code>[userinfo, host, port, path, query, fragment]</code>.
#
# Example:
#
- # newuri = URI::HTTP.build(host: 'www.example.com', path: '/foo/bar')
+ # uri = URI::HTTP.build(host: 'www.example.com', path: '/foo/bar')
#
- # newuri = URI::HTTP.build([nil, "www.example.com", nil, "/path",
+ # uri = URI::HTTP.build([nil, "www.example.com", nil, "/path",
# "query", 'fragment'])
#
# Currently, if passed userinfo components this method generates
@@ -72,8 +71,8 @@ module URI
#
# Example:
#
- # newuri = URI::HTTP.build(path: '/foo/bar', query: 'test=true')
- # newuri.request_uri # => "/foo/bar?test=true"
+ # uri = URI::HTTP.build(path: '/foo/bar', query: 'test=true')
+ # uri.request_uri # => "/foo/bar?test=true"
#
def request_uri
return unless @path
diff --git a/lib/uri/https.rb b/lib/uri/https.rb
index 3c8c905cc3..c481b1fe6d 100644
--- a/lib/uri/https.rb
+++ b/lib/uri/https.rb
@@ -3,12 +3,11 @@
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
#
# See URI for general documentation
#
-require 'uri/http'
+require_relative 'http'
module URI
diff --git a/lib/uri/ldap.rb b/lib/uri/ldap.rb
index 4345875e28..14e6163292 100644
--- a/lib/uri/ldap.rb
+++ b/lib/uri/ldap.rb
@@ -7,25 +7,25 @@
# License::
# URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada.
# You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
#
# See URI for general documentation
#
-require 'uri/generic'
+require_relative 'generic'
module URI
#
- # LDAP URI SCHEMA (described in RFC2255)
+ # LDAP URI SCHEMA (described in RFC2255).
+ #--
# ldap://<host>/<dn>[?<attrs>[?<scope>[?<filter>[?<extensions>]]]]
- #
+ #++
class LDAP < Generic
- # A Default port of 389 for URI::LDAP
+ # A Default port of 389 for URI::LDAP.
DEFAULT_PORT = 389
- # An Array of the available components for URI::LDAP
+ # An Array of the available components for URI::LDAP.
COMPONENT = [
:scheme,
:host, :port,
@@ -40,8 +40,8 @@ module URI
#
# * SCOPE_BASE - the Base DN
# * SCOPE_ONE - one level under the Base DN, not including the base DN and
- # not including any entries under this.
- # * SCOPE_SUB - subtress, all entries at all levels
+ # not including any entries under this
+ # * SCOPE_SUB - subtrees, all entries at all levels
#
SCOPE = [
SCOPE_ONE = 'one',
@@ -52,7 +52,7 @@ module URI
#
# == Description
#
- # Create a new URI::LDAP object from components, with syntax checking.
+ # Creates a new URI::LDAP object from components, with syntax checking.
#
# The components accepted are host, port, dn, attributes,
# scope, filter, and extensions.
@@ -60,15 +60,15 @@ module URI
# The components should be provided either as an Array, or as a Hash
# with keys formed by preceding the component names with a colon.
#
- # If an Array is used, the components must be passed in the order
- # [host, port, dn, attributes, scope, filter, extensions].
+ # If an Array is used, the components must be passed in the
+ # order <code>[host, port, dn, attributes, scope, filter, extensions]</code>.
#
# Example:
#
- # newuri = URI::LDAP.build({:host => 'ldap.example.com',
- # :dn> => '/dc=example'})
+ # uri = URI::LDAP.build({:host => 'ldap.example.com',
+ # :dn => '/dc=example'})
#
- # newuri = URI::LDAP.build(["ldap.example.com", nil,
+ # uri = URI::LDAP.build(["ldap.example.com", nil,
# "/dc=example;dc=com", "query", nil, nil, nil])
#
def self.build(args)
@@ -92,19 +92,18 @@ module URI
#
# == Description
#
- # Create a new URI::LDAP object from generic URI components as per
+ # Creates a new URI::LDAP object from generic URI components as per
# RFC 2396. No LDAP-specific syntax checking is performed.
#
# Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
- # +opaque+, +query+ and +fragment+, in that order.
+ # +opaque+, +query+, and +fragment+, in that order.
#
# Example:
#
- # uri = URI::LDAP.new("ldap", nil, "ldap.example.com", nil,
- # "/dc=example;dc=com", "query", nil, nil, nil, nil)
- #
+ # uri = URI::LDAP.new("ldap", nil, "ldap.example.com", nil, nil,
+ # "/dc=example;dc=com", nil, "query", nil)
#
- # See also URI::Generic.new
+ # See also URI::Generic.new.
#
def initialize(*arg)
super(*arg)
@@ -117,14 +116,15 @@ module URI
parse_query
end
- # private method to cleanup +dn+ from using the +path+ component attribute
+ # Private method to cleanup +dn+ from using the +path+ component attribute.
def parse_dn
+ raise InvalidURIError, 'bad LDAP URL' unless @path
@dn = @path[1..-1]
end
private :parse_dn
- # private method to cleanup +attributes+, +scope+, +filter+ and +extensions+,
- # from using the +query+ component attribute
+ # Private method to cleanup +attributes+, +scope+, +filter+, and +extensions+
+ # from using the +query+ component attribute.
def parse_query
@attributes = nil
@scope = nil
@@ -142,7 +142,7 @@ module URI
end
private :parse_query
- # private method to assemble +query+ from +attributes+, +scope+, +filter+ and +extensions+.
+ # Private method to assemble +query+ from +attributes+, +scope+, +filter+, and +extensions+.
def build_path_query
@path = '/' + @dn
@@ -155,12 +155,12 @@ module URI
end
private :build_path_query
- # returns dn.
+ # Returns dn.
def dn
@dn
end
- # private setter for dn +val+
+ # Private setter for dn +val+.
def set_dn(val)
@dn = val
build_path_query
@@ -168,18 +168,18 @@ module URI
end
protected :set_dn
- # setter for dn +val+
+ # Setter for dn +val+.
def dn=(val)
set_dn(val)
val
end
- # returns attributes.
+ # Returns attributes.
def attributes
@attributes
end
- # private setter for attributes +val+
+ # Private setter for attributes +val+.
def set_attributes(val)
@attributes = val
build_path_query
@@ -187,18 +187,18 @@ module URI
end
protected :set_attributes
- # setter for attributes +val+
+ # Setter for attributes +val+.
def attributes=(val)
set_attributes(val)
val
end
- # returns scope.
+ # Returns scope.
def scope
@scope
end
- # private setter for scope +val+
+ # Private setter for scope +val+.
def set_scope(val)
@scope = val
build_path_query
@@ -206,18 +206,18 @@ module URI
end
protected :set_scope
- # setter for scope +val+
+ # Setter for scope +val+.
def scope=(val)
set_scope(val)
val
end
- # returns filter.
+ # Returns filter.
def filter
@filter
end
- # private setter for filter +val+
+ # Private setter for filter +val+.
def set_filter(val)
@filter = val
build_path_query
@@ -225,18 +225,18 @@ module URI
end
protected :set_filter
- # setter for filter +val+
+ # Setter for filter +val+.
def filter=(val)
set_filter(val)
val
end
- # returns extensions.
+ # Returns extensions.
def extensions
@extensions
end
- # private setter for extensions +val+
+ # Private setter for extensions +val+.
def set_extensions(val)
@extensions = val
build_path_query
@@ -244,14 +244,14 @@ module URI
end
protected :set_extensions
- # setter for extensions +val+
+ # Setter for extensions +val+.
def extensions=(val)
set_extensions(val)
val
end
- # Checks if URI has a path
- # For URI::LDAP this will return +false+
+ # Checks if URI has a path.
+ # For URI::LDAP this will return +false+.
def hierarchical?
false
end
diff --git a/lib/uri/ldaps.rb b/lib/uri/ldaps.rb
index d03f8efa2d..227e7fab35 100644
--- a/lib/uri/ldaps.rb
+++ b/lib/uri/ldaps.rb
@@ -6,7 +6,7 @@
# See URI for general documentation
#
-require 'uri/ldap'
+require_relative 'ldap'
module URI
diff --git a/lib/uri/mailto.rb b/lib/uri/mailto.rb
index 1494c3952b..d08c2ae9da 100644
--- a/lib/uri/mailto.rb
+++ b/lib/uri/mailto.rb
@@ -3,25 +3,24 @@
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
#
# See URI for general documentation
#
-require 'uri/generic'
+require_relative 'generic'
module URI
#
- # RFC6068, The mailto URL scheme
+ # RFC6068, the mailto URL scheme.
#
class MailTo < Generic
include REGEXP
- # A Default port of nil for URI::MailTo
+ # A Default port of nil for URI::MailTo.
DEFAULT_PORT = nil
- # An Array of the available components for URI::MailTo
+ # An Array of the available components for URI::MailTo.
COMPONENT = [ :scheme, :to, :headers ].freeze
# :stopdoc:
@@ -52,7 +51,7 @@ module URI
# pct-encoded = "%" HEXDIG HEXDIG
HEADER_REGEXP = /\A(?<hfield>(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g<hfield>)*\z/
# practical regexp for email address
- # http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
+ # https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
EMAIL_REGEXP = /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
# :startdoc:
@@ -62,26 +61,26 @@ module URI
# Creates a new URI::MailTo object from components, with syntax checking.
#
# Components can be provided as an Array or Hash. If an Array is used,
- # the components must be supplied as [to, headers].
+ # the components must be supplied as <code>[to, headers]</code>.
#
# If a Hash is used, the keys are the component names preceded by colons.
#
# The headers can be supplied as a pre-encoded string, such as
- # "subject=subscribe&cc=address", or as an Array of Arrays like
- # [['subject', 'subscribe'], ['cc', 'address']]
+ # <code>"subject=subscribe&cc=address"</code>, or as an Array of Arrays
+ # like <code>[['subject', 'subscribe'], ['cc', 'address']]</code>.
#
# Examples:
#
# require 'uri'
#
# m1 = URI::MailTo.build(['joe@example.com', 'subject=Ruby'])
- # puts m1.to_s -> mailto:joe@example.com?subject=Ruby
+ # m1.to_s # => "mailto:joe@example.com?subject=Ruby"
#
# m2 = URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]])
- # puts m2.to_s -> mailto:john@example.com?Subject=Ruby&Cc=jack@example.com
+ # m2.to_s # => "mailto:john@example.com?Subject=Ruby&Cc=jack@example.com"
#
# m3 = URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]})
- # puts m3.to_s -> mailto:listman@example.com?subject=subscribe
+ # m3.to_s # => "mailto:listman@example.com?subject=subscribe"
#
def self.build(args)
tmp = Util.make_components_hash(self, args)
@@ -160,13 +159,13 @@ module URI
end
end
- # The primary e-mail address of the URL, as a String
+ # The primary e-mail address of the URL, as a String.
attr_reader :to
- # E-mail headers set by the URL, as an Array of Arrays
+ # E-mail headers set by the URL, as an Array of Arrays.
attr_reader :headers
- # check the to +v+ component
+ # Checks the to +v+ component.
def check_to(v)
return true unless v
return true if v.size == 0
@@ -191,20 +190,20 @@ module URI
end
private :check_to
- # private setter for to +v+
+ # Private setter for to +v+.
def set_to(v)
@to = v
end
protected :set_to
- # setter for to +v+
+ # Setter for to +v+.
def to=(v)
check_to(v)
set_to(v)
v
end
- # check the headers +v+ component against either
+ # Checks the headers +v+ component against either
# * HEADER_REGEXP
def check_headers(v)
return true unless v
@@ -218,7 +217,7 @@ module URI
end
private :check_headers
- # private setter for headers +v+
+ # Private setter for headers +v+.
def set_headers(v)
@headers = []
if v
@@ -229,14 +228,14 @@ module URI
end
protected :set_headers
- # setter for headers +v+
+ # Setter for headers +v+.
def headers=(v)
check_headers(v)
set_headers(v)
v
end
- # Constructs String from URI
+ # Constructs String from URI.
def to_s
@scheme + ':' +
if @to
diff --git a/lib/uri/rfc2396_parser.rb b/lib/uri/rfc2396_parser.rb
index b9e7b2b26e..253c54b786 100644
--- a/lib/uri/rfc2396_parser.rb
+++ b/lib/uri/rfc2396_parser.rb
@@ -3,7 +3,6 @@
# = uri/common.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
-# Revision:: $Id$
# License::
# You can redistribute it and/or modify it under the same term as Ruby.
#
@@ -58,7 +57,7 @@ module URI
# :startdoc:
end # REGEXP
- # class that Parses String's into URI's
+ # Class that parses String's into URI's.
#
# It contains a Hash set of patterns and Regexp's that match and validate.
#
@@ -88,12 +87,12 @@ module URI
# == Examples
#
# p = URI::Parser.new(:ESCAPED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})")
- # u = p.parse("http://example.jp/%uABCD") #=> #<URI::HTTP:0xb78cf4f8 URL:http://example.jp/%uABCD>
+ # u = p.parse("http://example.jp/%uABCD") #=> #<URI::HTTP http://example.jp/%uABCD>
# URI.parse(u.to_s) #=> raises URI::InvalidURIError
#
# s = "http://example.com/ABCD"
- # u1 = p.parse(s) #=> #<URI::HTTP:0xb78c3220 URL:http://example.com/ABCD>
- # u2 = URI.parse(s) #=> #<URI::HTTP:0xb78b6d54 URL:http://example.com/ABCD>
+ # u1 = p.parse(s) #=> #<URI::HTTP http://example.com/ABCD>
+ # u2 = URI.parse(s) #=> #<URI::HTTP http://example.com/ABCD>
# u1 == u2 #=> true
# u1.eql?(u2) #=> false
#
@@ -109,15 +108,15 @@ module URI
# The Hash of patterns.
#
- # see also URI::Parser.initialize_pattern
+ # See also URI::Parser.initialize_pattern.
attr_reader :pattern
- # The Hash of Regexp
+ # The Hash of Regexp.
#
- # see also URI::Parser.initialize_regexp
+ # See also URI::Parser.initialize_regexp.
attr_reader :regexp
- # Returns a split URI against regexp[:ABS_URI]
+ # Returns a split URI against regexp[:ABS_URI].
def split(uri)
case uri
when ''
@@ -198,31 +197,19 @@ module URI
#
# == Description
#
- # parses +uri+ and constructs either matching URI scheme object
- # (FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or URI::Generic
+ # Parses +uri+ and constructs either matching URI scheme object
+ # (File, FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or URI::Generic.
#
# == Usage
#
# p = URI::Parser.new
# p.parse("ldap://ldap.example.com/dc=example?user=john")
- # #=> #<URI::LDAP:0x00000000b9e7e8 URL:ldap://ldap.example.com/dc=example?user=john>
+ # #=> #<URI::LDAP ldap://ldap.example.com/dc=example?user=john>
#
def parse(uri)
- scheme, userinfo, host, port,
- registry, path, opaque, query, fragment = self.split(uri)
-
- if scheme && URI.scheme_list.include?(scheme.upcase)
- URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
- registry, path, opaque, query,
- fragment, self)
- else
- Generic.new(scheme, userinfo, host, port,
- registry, path, opaque, query,
- fragment, self)
- end
+ URI.for(*self.split(uri), self)
end
-
#
# == Args
#
@@ -231,7 +218,7 @@ module URI
#
# == Description
#
- # Attempts to parse and merge a set of URIs
+ # Attempts to parse and merge a set of URIs.
#
def join(*uris)
uris[0] = convert_to_uri(uris[0])
@@ -253,11 +240,11 @@ module URI
#
# == Description
#
- # Attempts to parse and merge a set of URIs
- # If no +block+ given , then returns the result,
+ # Attempts to parse and merge a set of URIs.
+ # If no +block+ given, then returns the result,
# else it calls +block+ for each element in result.
#
- # see also URI::Parser.make_regexp
+ # See also URI::Parser.make_regexp.
#
def extract(str, schemes = nil)
if block_given?
@@ -270,8 +257,8 @@ module URI
end
end
- # returns Regexp that is default self.regexp[:ABS_URI_REF],
- # unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI]
+ # Returns Regexp that is default self.regexp[:ABS_URI_REF],
+ # unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI].
def make_regexp(schemes = nil)
unless schemes
@regexp[:ABS_URI_REF]
@@ -294,7 +281,7 @@ module URI
#
# == Description
#
- # constructs a safe String from +str+, removing unsafe characters,
+ # Constructs a safe String from +str+, removing unsafe characters,
# replacing them with codes.
#
def escape(str, unsafe = @regexp[:UNSAFE])
@@ -315,31 +302,33 @@ module URI
#
# :call-seq:
# unescape( str )
- # unescape( str, unsafe )
+ # unescape( str, escaped )
#
# == Args
#
# +str+::
# String to remove escapes from
- # +unsafe+::
+ # +escaped+::
# Regexp to apply. Defaults to self.regexp[:ESCAPED]
#
# == Description
#
- # Removes escapes from +str+
+ # Removes escapes from +str+.
#
def unescape(str, escaped = @regexp[:ESCAPED])
- str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(str.encoding)
+ enc = str.encoding
+ enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
+ str.gsub(escaped) { [$&[1, 2]].pack('H2').force_encoding(enc) }
end
@@to_s = Kernel.instance_method(:to_s)
def inspect
- @@to_s.bind(self).call
+ @@to_s.bind_call(self)
end
private
- # Constructs the default Hash of patterns
+ # Constructs the default Hash of patterns.
def initialize_pattern(opts = {})
ret = {}
ret[:ESCAPED] = escaped = (opts.delete(:ESCAPED) || PATTERN::ESCAPED)
@@ -497,13 +486,13 @@ module URI
ret
end
- # Constructs the default Hash of Regexp's
+ # Constructs the default Hash of Regexp's.
def initialize_regexp(pattern)
ret = {}
# for URI::split
- ret[:ABS_URI] = Regexp.new('\A\s*' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED)
- ret[:REL_URI] = Regexp.new('\A\s*' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED)
+ ret[:ABS_URI] = Regexp.new('\A\s*+' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED)
+ ret[:REL_URI] = Regexp.new('\A\s*+' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED)
# for URI::extract
ret[:URI_REF] = Regexp.new(pattern[:URI_REF])
diff --git a/lib/uri/rfc3986_parser.rb b/lib/uri/rfc3986_parser.rb
index 871280044a..5a9e44e08c 100644
--- a/lib/uri/rfc3986_parser.rb
+++ b/lib/uri/rfc3986_parser.rb
@@ -3,8 +3,8 @@ module URI
class RFC3986_Parser # :nodoc:
# URI defined in RFC3986
# this regexp is modified not to host is not empty string
- RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/
- RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+)\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])+)(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/
+ RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*+):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
+ RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])++)(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
attr_reader :regexp
def initialize
@@ -15,7 +15,7 @@ module URI
begin
uri = uri.to_str
rescue NoMethodError
- raise InvalidURIError, "bad URI(is not URI?): #{uri}"
+ raise InvalidURIError, "bad URI(is not URI?): #{uri.inspect}"
end
uri.ascii_only? or
raise InvalidURIError, "URI must be ascii only #{uri.dump}"
@@ -64,23 +64,12 @@ module URI
m["fragment".freeze]
]
else
- raise InvalidURIError, "bad URI(is not URI?): #{uri}"
+ raise InvalidURIError, "bad URI(is not URI?): #{uri.inspect}"
end
end
def parse(uri) # :nodoc:
- scheme, userinfo, host, port,
- registry, path, opaque, query, fragment = self.split(uri)
- scheme_list = URI.scheme_list
- if scheme && scheme_list.include?(uc = scheme.upcase)
- scheme_list[uc].new(scheme, userinfo, host, port,
- registry, path, opaque, query,
- fragment, self)
- else
- Generic.new(scheme, userinfo, host, port,
- registry, path, opaque, query,
- fragment, self)
- end
+ URI.for(*self.split(uri), self)
end
@@ -91,7 +80,7 @@ module URI
@@to_s = Kernel.instance_method(:to_s)
def inspect
- @@to_s.bind(self).call
+ @@to_s.bind_call(self)
end
private
@@ -106,7 +95,7 @@ module URI
QUERY: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
FRAGMENT: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
OPAQUE: /\A(?:[^\/].*)?\z/,
- PORT: /\A[\x09\x0a\x0c\x0d ]*\d*[\x09\x0a\x0c\x0d ]*\z/,
+ PORT: /\A[\x09\x0a\x0c\x0d ]*+\d*[\x09\x0a\x0c\x0d ]*\z/,
}
end
diff --git a/lib/uri/uri.gemspec b/lib/uri/uri.gemspec
new file mode 100644
index 0000000000..c4a16f47eb
--- /dev/null
+++ b/lib/uri/uri.gemspec
@@ -0,0 +1,29 @@
+begin
+ require_relative "lib/uri/version"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "uri"
+ spec.version = URI::VERSION
+ spec.authors = ["Akira Yamada"]
+ spec.email = ["akira@ruby-lang.org"]
+
+ spec.summary = %q{URI is a module providing classes to handle Uniform Resource Identifiers}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/uri"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/uri/version.rb b/lib/uri/version.rb
new file mode 100644
index 0000000000..fb195ee686
--- /dev/null
+++ b/lib/uri/version.rb
@@ -0,0 +1,6 @@
+module URI
+ # :stopdoc:
+ VERSION_CODE = '001003'.freeze
+ VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
+ # :startdoc:
+end
diff --git a/lib/uri/ws.rb b/lib/uri/ws.rb
new file mode 100644
index 0000000000..2bfee59003
--- /dev/null
+++ b/lib/uri/ws.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: false
+# = uri/ws.rb
+#
+# Author:: Matt Muller <mamuller@amazon.com>
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+#
+# See URI for general documentation
+#
+
+require_relative 'generic'
+
+module URI
+
+ #
+ # The syntax of WS URIs is defined in RFC6455 section 3.
+ #
+ # Note that the Ruby URI library allows WS URLs containing usernames and
+ # passwords. This is not legal as per the RFC, but used to be
+ # supported in Internet Explorer 5 and 6, before the MS04-004 security
+ # update. See <URL:http://support.microsoft.com/kb/834489>.
+ #
+ class WS < Generic
+ # A Default port of 80 for URI::WS.
+ DEFAULT_PORT = 80
+
+ # An Array of the available components for URI::WS.
+ COMPONENT = %i[
+ scheme
+ userinfo host port
+ path
+ query
+ ].freeze
+
+ #
+ # == Description
+ #
+ # Creates a new URI::WS object from components, with syntax checking.
+ #
+ # The components accepted are userinfo, host, port, path, and query.
+ #
+ # The components should be provided either as an Array, or as a Hash
+ # with keys formed by preceding the component names with a colon.
+ #
+ # If an Array is used, the components must be passed in the
+ # order <code>[userinfo, host, port, path, query]</code>.
+ #
+ # Example:
+ #
+ # uri = URI::WS.build(host: 'www.example.com', path: '/foo/bar')
+ #
+ # uri = URI::WS.build([nil, "www.example.com", nil, "/path", "query"])
+ #
+ # Currently, if passed userinfo components this method generates
+ # invalid WS URIs as per RFC 1738.
+ #
+ def self.build(args)
+ tmp = Util.make_components_hash(self, args)
+ super(tmp)
+ end
+
+ #
+ # == Description
+ #
+ # Returns the full path for a WS URI, as required by Net::HTTP::Get.
+ #
+ # If the URI contains a query, the full path is URI#path + '?' + URI#query.
+ # Otherwise, the path is simply URI#path.
+ #
+ # Example:
+ #
+ # uri = URI::WS.build(path: '/foo/bar', query: 'test=true')
+ # uri.request_uri # => "/foo/bar?test=true"
+ #
+ def request_uri
+ return unless @path
+
+ url = @query ? "#@path?#@query" : @path.dup
+ url.start_with?(?/.freeze) ? url : ?/ + url
+ end
+ end
+
+ @@schemes['WS'] = WS
+
+end
diff --git a/lib/uri/wss.rb b/lib/uri/wss.rb
new file mode 100644
index 0000000000..1cfa133389
--- /dev/null
+++ b/lib/uri/wss.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: false
+# = uri/wss.rb
+#
+# Author:: Matt Muller <mamuller@amazon.com>
+# License:: You can redistribute it and/or modify it under the same term as Ruby.
+#
+# See URI for general documentation
+#
+
+require_relative 'ws'
+
+module URI
+
+ # The default port for WSS URIs is 443, and the scheme is 'wss:' rather
+ # than 'ws:'. Other than that, WSS URIs are identical to WS URIs;
+ # see URI::WS.
+ class WSS < WS
+ # A Default port of 443 for URI::WSS
+ DEFAULT_PORT = 443
+ end
+ @@schemes['WSS'] = WSS
+end
diff --git a/lib/weakref.rb b/lib/weakref.rb
index c88babba46..fbd5d8fa82 100644
--- a/lib/weakref.rb
+++ b/lib/weakref.rb
@@ -15,55 +15,9 @@ require "delegate"
# GC.start # start the garbage collector
# p foo.to_s # should raise exception (recycled)
#
-# == Example
-#
-# With help from WeakRef, we can implement our own rudimentary WeakHash class.
-#
-# We will call it WeakHash, since it's really just a Hash except all of it's
-# keys and values can be garbage collected.
-#
-# require 'weakref'
-#
-# class WeakHash < Hash
-# def []= key, obj
-# super WeakRef.new(key), WeakRef.new(obj)
-# end
-# end
-#
-# This is just a simple implementation, we've opened the Hash class and changed
-# Hash#store to create a new WeakRef object with +key+ and +obj+ parameters
-# before passing them as our key-value pair to the hash.
-#
-# With this you will have to limit your self to String keys, otherwise you
-# will get an ArgumentError because WeakRef cannot create a finalizer for a
-# Symbol. Symbols are immutable and cannot be garbage collected.
-#
-# Let's see it in action:
-#
-# omg = "lol"
-# c = WeakHash.new
-# c['foo'] = "bar"
-# c['baz'] = Object.new
-# c['qux'] = omg
-# puts c.inspect
-# #=> {"foo"=>"bar", "baz"=>#<Object:0x007f4ddfc6cb48>, "qux"=>"lol"}
-#
-# # Now run the garbage collector
-# GC.start
-# c['foo'] #=> nil
-# c['baz'] #=> nil
-# c['qux'] #=> nil
-# omg #=> "lol"
-#
-# puts c.inspect
-# #=> WeakRef::RefError: Invalid Reference - probably recycled
-#
-# You can see the local variable +omg+ stayed, although its reference in our
-# hash object was garbage collected, along with the rest of the keys and
-# values. Also, when we tried to inspect our hash, we got a WeakRef::RefError.
-# This is because these objects were also garbage collected.
class WeakRef < Delegator
+ VERSION = "0.1.1"
##
# RefError is raised when a referenced object has been recycled by the
diff --git a/lib/weakref/weakref.gemspec b/lib/weakref/weakref.gemspec
new file mode 100644
index 0000000000..96a9765079
--- /dev/null
+++ b/lib/weakref/weakref.gemspec
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Allows a referenced object to be garbage-collected.}
+ spec.description = %q{Allows a referenced object to be garbage-collected.}
+ spec.homepage = "https://github.com/ruby/weakref"
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = "https://github.com/ruby/weakref"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "delegate"
+end
diff --git a/lib/webrick.rb b/lib/webrick.rb
deleted file mode 100644
index cbaf18a792..0000000000
--- a/lib/webrick.rb
+++ /dev/null
@@ -1,227 +0,0 @@
-# frozen_string_literal: false
-##
-# = WEB server toolkit.
-#
-# WEBrick is an HTTP server toolkit that can be configured as an HTTPS server,
-# a proxy server, and a virtual-host server. WEBrick features complete
-# logging of both server operations and HTTP access. WEBrick supports both
-# basic and digest authentication in addition to algorithms not in RFC 2617.
-#
-# A WEBrick server can be composed of multiple WEBrick servers or servlets to
-# provide differing behavior on a per-host or per-path basis. WEBrick
-# includes servlets for handling CGI scripts, ERB pages, Ruby blocks and
-# directory listings.
-#
-# WEBrick also includes tools for daemonizing a process and starting a process
-# at a higher privilege level and dropping permissions.
-#
-# == Starting an HTTP server
-#
-# To create a new WEBrick::HTTPServer that will listen to connections on port
-# 8000 and serve documents from the current user's public_html folder:
-#
-# require 'webrick'
-#
-# root = File.expand_path '~/public_html'
-# server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root
-#
-# To run the server you will need to provide a suitable shutdown hook as
-# starting the server blocks the current thread:
-#
-# trap 'INT' do server.shutdown end
-#
-# server.start
-#
-# == Custom Behavior
-#
-# The easiest way to have a server perform custom operations is through
-# WEBrick::HTTPServer#mount_proc. The block given will be called with a
-# WEBrick::HTTPRequest with request info and a WEBrick::HTTPResponse which
-# must be filled in appropriately:
-#
-# server.mount_proc '/' do |req, res|
-# res.body = 'Hello, world!'
-# end
-#
-# Remember that +server.mount_proc+ must precede +server.start+.
-#
-# == Servlets
-#
-# Advanced custom behavior can be obtained through mounting a subclass of
-# WEBrick::HTTPServlet::AbstractServlet. Servlets provide more modularity
-# when writing an HTTP server than mount_proc allows. Here is a simple
-# servlet:
-#
-# class Simple < WEBrick::HTTPServlet::AbstractServlet
-# def do_GET request, response
-# status, content_type, body = do_stuff_with request
-#
-# response.status = 200
-# response['Content-Type'] = 'text/plain'
-# response.body = 'Hello, World!'
-# end
-# end
-#
-# To initialize the servlet you mount it on the server:
-#
-# server.mount '/simple', Simple
-#
-# See WEBrick::HTTPServlet::AbstractServlet for more details.
-#
-# == Virtual Hosts
-#
-# A server can act as a virtual host for multiple host names. After creating
-# the listening host, additional hosts that do not listen can be created and
-# attached as virtual hosts:
-#
-# server = WEBrick::HTTPServer.new # ...
-#
-# vhost = WEBrick::HTTPServer.new :ServerName => 'vhost.example',
-# :DoNotListen => true, # ...
-# vhost.mount '/', ...
-#
-# server.virtual_host vhost
-#
-# If no +:DocumentRoot+ is provided and no servlets or procs are mounted on the
-# main server it will return 404 for all URLs.
-#
-# == HTTPS
-#
-# To create an HTTPS server you only need to enable SSL and provide an SSL
-# certificate name:
-#
-# require 'webrick'
-# require 'webrick/https'
-#
-# cert_name = [
-# %w[CN localhost],
-# ]
-#
-# server = WEBrick::HTTPServer.new(:Port => 8000,
-# :SSLEnable => true,
-# :SSLCertName => cert_name)
-#
-# This will start the server with a self-generated self-signed certificate.
-# The certificate will be changed every time the server is restarted.
-#
-# To create a server with a pre-determined key and certificate you can provide
-# them:
-#
-# require 'webrick'
-# require 'webrick/https'
-# require 'openssl'
-#
-# cert = OpenSSL::X509::Certificate.new File.read '/path/to/cert.pem'
-# pkey = OpenSSL::PKey::RSA.new File.read '/path/to/pkey.pem'
-#
-# server = WEBrick::HTTPServer.new(:Port => 8000,
-# :SSLEnable => true,
-# :SSLCertificate => cert,
-# :SSLPrivateKey => pkey)
-#
-# == Proxy Server
-#
-# WEBrick can act as a proxy server:
-#
-# require 'webrick'
-# require 'webrick/httpproxy'
-#
-# proxy = WEBrick::HTTPProxyServer.new :Port => 8000
-#
-# trap 'INT' do proxy.shutdown end
-#
-# See WEBrick::HTTPProxy for further details including modifying proxied
-# responses.
-#
-# == Basic and Digest authentication
-#
-# WEBrick provides both Basic and Digest authentication for regular and proxy
-# servers. See WEBrick::HTTPAuth, WEBrick::HTTPAuth::BasicAuth and
-# WEBrick::HTTPAuth::DigestAuth.
-#
-# == WEBrick as a Production Web Server
-#
-# WEBrick can be run as a production server for small loads.
-#
-# === Daemonizing
-#
-# To start a WEBrick server as a daemon simple run WEBrick::Daemon.start
-# before starting the server.
-#
-# === Dropping Permissions
-#
-# WEBrick can be started as one user to gain permission to bind to port 80 or
-# 443 for serving HTTP or HTTPS traffic then can drop these permissions for
-# regular operation. To listen on all interfaces for HTTP traffic:
-#
-# sockets = WEBrick::Utils.create_listeners nil, 80
-#
-# Then drop privileges:
-#
-# WEBrick::Utils.su 'www'
-#
-# Then create a server that does not listen by default:
-#
-# server = WEBrick::HTTPServer.new :DoNotListen => true, # ...
-#
-# Then overwrite the listening sockets with the port 80 sockets:
-#
-# server.listeners.replace sockets
-#
-# === Logging
-#
-# WEBrick can separately log server operations and end-user access. For
-# server operations:
-#
-# log_file = File.open '/var/log/webrick.log', 'a+'
-# log = WEBrick::Log.new log_file
-#
-# For user access logging:
-#
-# access_log = [
-# [log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT],
-# ]
-#
-# server = WEBrick::HTTPServer.new :Logger => log, :AccessLog => access_log
-#
-# See WEBrick::AccessLog for further log formats.
-#
-# === Log Rotation
-#
-# To rotate logs in WEBrick on a HUP signal (like syslogd can send), open the
-# log file in 'a+' mode (as above) and trap 'HUP' to reopen the log file:
-#
-# trap 'HUP' do log_file.reopen '/path/to/webrick.log', 'a+'
-#
-# == Copyright
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-#
-# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#--
-# $IPR: webrick.rb,v 1.12 2002/10/01 17:16:31 gotoyuzo Exp $
-
-module WEBrick
-end
-
-require 'webrick/compat.rb'
-
-require 'webrick/version.rb'
-require 'webrick/config.rb'
-require 'webrick/log.rb'
-require 'webrick/server.rb'
-require 'webrick/utils.rb'
-require 'webrick/accesslog'
-
-require 'webrick/htmlutils.rb'
-require 'webrick/httputils.rb'
-require 'webrick/cookie.rb'
-require 'webrick/httpversion.rb'
-require 'webrick/httpstatus.rb'
-require 'webrick/httprequest.rb'
-require 'webrick/httpresponse.rb'
-require 'webrick/httpserver.rb'
-require 'webrick/httpservlet.rb'
-require 'webrick/httpauth.rb'
diff --git a/lib/webrick/accesslog.rb b/lib/webrick/accesslog.rb
deleted file mode 100644
index 17e5b38ac9..0000000000
--- a/lib/webrick/accesslog.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-# frozen_string_literal: false
-#--
-# accesslog.rb -- Access log handling utilities
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2002 keita yamaguchi
-# Copyright (c) 2002 Internet Programming with Ruby writers
-#
-# $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $
-
-module WEBrick
-
- ##
- # AccessLog provides logging to various files in various formats.
- #
- # Multiple logs may be written to at the same time:
- #
- # access_log = [
- # [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
- # [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
- # ]
- #
- # server = WEBrick::HTTPServer.new :AccessLog => access_log
- #
- # Custom log formats may be defined. WEBrick::AccessLog provides a subset
- # of the formatting from Apache's mod_log_config
- # http://httpd.apache.org/docs/mod/mod_log_config.html#formats. See
- # AccessLog::setup_params for a list of supported options
-
- module AccessLog
-
- ##
- # Raised if a parameter such as %e, %i, %o or %n is used without fetching
- # a specific field.
-
- class AccessLogError < StandardError; end
-
- ##
- # The Common Log Format's time format
-
- CLF_TIME_FORMAT = "[%d/%b/%Y:%H:%M:%S %Z]"
-
- ##
- # Common Log Format
-
- COMMON_LOG_FORMAT = "%h %l %u %t \"%r\" %s %b"
-
- ##
- # Short alias for Common Log Format
-
- CLF = COMMON_LOG_FORMAT
-
- ##
- # Referer Log Format
-
- REFERER_LOG_FORMAT = "%{Referer}i -> %U"
-
- ##
- # User-Agent Log Format
-
- AGENT_LOG_FORMAT = "%{User-Agent}i"
-
- ##
- # Combined Log Format
-
- COMBINED_LOG_FORMAT = "#{CLF} \"%{Referer}i\" \"%{User-agent}i\""
-
- module_function
-
- # This format specification is a subset of mod_log_config of Apache:
- #
- # %a:: Remote IP address
- # %b:: Total response size
- # %e{variable}:: Given variable in ENV
- # %f:: Response filename
- # %h:: Remote host name
- # %{header}i:: Given request header
- # %l:: Remote logname, always "-"
- # %m:: Request method
- # %{attr}n:: Given request attribute from <tt>req.attributes</tt>
- # %{header}o:: Given response header
- # %p:: Server's request port
- # %{format}p:: The canonical port of the server serving the request or the
- # actual port or the client's actual port. Valid formats are
- # canonical, local or remote.
- # %q:: Request query string
- # %r:: First line of the request
- # %s:: Request status
- # %t:: Time the request was received
- # %T:: Time taken to process the request
- # %u:: Remote user from auth
- # %U:: Unparsed URI
- # %%:: Literal %
-
- def setup_params(config, req, res)
- params = Hash.new("")
- params["a"] = req.peeraddr[3]
- params["b"] = res.sent_size
- params["e"] = ENV
- params["f"] = res.filename || ""
- params["h"] = req.peeraddr[2]
- params["i"] = req
- params["l"] = "-"
- params["m"] = req.request_method
- params["n"] = req.attributes
- params["o"] = res
- params["p"] = req.port
- params["q"] = req.query_string
- params["r"] = req.request_line.sub(/\x0d?\x0a\z/o, '')
- params["s"] = res.status # won't support "%>s"
- params["t"] = req.request_time
- params["T"] = Time.now - req.request_time
- params["u"] = req.user || "-"
- params["U"] = req.unparsed_uri
- params["v"] = config[:ServerName]
- params
- end
-
- ##
- # Formats +params+ according to +format_string+ which is described in
- # setup_params.
-
- def format(format_string, params)
- format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){
- param, spec = $1, $2
- case spec[0]
- when ?e, ?i, ?n, ?o
- raise AccessLogError,
- "parameter is required for \"#{spec}\"" unless param
- (param = params[spec][param]) ? escape(param) : "-"
- when ?t
- params[spec].strftime(param || CLF_TIME_FORMAT)
- when ?p
- case param
- when 'remote'
- escape(params["i"].peeraddr[1].to_s)
- else
- escape(params["p"].to_s)
- end
- when ?%
- "%"
- else
- escape(params[spec].to_s)
- end
- }
- end
-
- ##
- # Escapes control characters in +data+
-
- def escape(data)
- if data.tainted?
- data.gsub(/[[:cntrl:]\\]+/) {$&.dump[1...-1]}.untaint
- else
- data
- end
- end
- end
-end
diff --git a/lib/webrick/cgi.rb b/lib/webrick/cgi.rb
deleted file mode 100644
index 94f385f1dd..0000000000
--- a/lib/webrick/cgi.rb
+++ /dev/null
@@ -1,309 +0,0 @@
-# frozen_string_literal: false
-#
-# cgi.rb -- Yet another CGI library
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $Id$
-
-require "webrick/httprequest"
-require "webrick/httpresponse"
-require "webrick/config"
-require "stringio"
-
-module WEBrick
-
- # A CGI library using WEBrick requests and responses.
- #
- # Example:
- #
- # class MyCGI < WEBrick::CGI
- # def do_GET req, res
- # res.body = 'it worked!'
- # res.status = 200
- # end
- # end
- #
- # MyCGI.new.start
-
- class CGI
-
- # The CGI error exception class
-
- CGIError = Class.new(StandardError)
-
- ##
- # The CGI configuration. This is based on WEBrick::Config::HTTP
-
- attr_reader :config
-
- ##
- # The CGI logger
-
- attr_reader :logger
-
- ##
- # Creates a new CGI interface.
- #
- # The first argument in +args+ is a configuration hash which would update
- # WEBrick::Config::HTTP.
- #
- # Any remaining arguments are stored in the <code>@options</code> instance
- # variable for use by a subclass.
-
- def initialize(*args)
- if defined?(MOD_RUBY)
- unless ENV.has_key?("GATEWAY_INTERFACE")
- Apache.request.setup_cgi_env
- end
- end
- if %r{HTTP/(\d+\.\d+)} =~ ENV["SERVER_PROTOCOL"]
- httpv = $1
- end
- @config = WEBrick::Config::HTTP.dup.update(
- :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null",
- :HTTPVersion => HTTPVersion.new(httpv || "1.0"),
- :RunOnCGI => true, # to detect if it runs on CGI.
- :NPH => false # set true to run as NPH script.
- )
- if config = args.shift
- @config.update(config)
- end
- @config[:Logger] ||= WEBrick::BasicLog.new($stderr)
- @logger = @config[:Logger]
- @options = args
- end
-
- ##
- # Reads +key+ from the configuration
-
- def [](key)
- @config[key]
- end
-
- ##
- # Starts the CGI process with the given environment +env+ and standard
- # input and output +stdin+ and +stdout+.
-
- def start(env=ENV, stdin=$stdin, stdout=$stdout)
- sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout)
- req = HTTPRequest.new(@config)
- res = HTTPResponse.new(@config)
- unless @config[:NPH] or defined?(MOD_RUBY)
- def res.setup_header
- unless @header["status"]
- phrase = HTTPStatus::reason_phrase(@status)
- @header["status"] = "#{@status} #{phrase}"
- end
- super
- end
- def res.status_line
- ""
- end
- end
-
- begin
- req.parse(sock)
- req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup
- req.path_info = (env["PATH_INFO"] || "").dup
- req.query_string = env["QUERY_STRING"]
- req.user = env["REMOTE_USER"]
- res.request_method = req.request_method
- res.request_uri = req.request_uri
- res.request_http_version = req.http_version
- res.keep_alive = req.keep_alive?
- self.service(req, res)
- rescue HTTPStatus::Error => ex
- res.set_error(ex)
- rescue HTTPStatus::Status => ex
- res.status = ex.code
- rescue Exception => ex
- @logger.error(ex)
- res.set_error(ex, true)
- ensure
- req.fixup
- if defined?(MOD_RUBY)
- res.setup_header
- Apache.request.status_line = "#{res.status} #{res.reason_phrase}"
- Apache.request.status = res.status
- table = Apache.request.headers_out
- res.header.each{|key, val|
- case key
- when /^content-encoding$/i
- Apache::request.content_encoding = val
- when /^content-type$/i
- Apache::request.content_type = val
- else
- table[key] = val.to_s
- end
- }
- res.cookies.each{|cookie|
- table.add("Set-Cookie", cookie.to_s)
- }
- Apache.request.send_http_header
- res.send_body(sock)
- else
- res.send_response(sock)
- end
- end
- end
-
- ##
- # Services the request +req+ which will fill in the response +res+. See
- # WEBrick::HTTPServlet::AbstractServlet#service for details.
-
- def service(req, res)
- method_name = "do_" + req.request_method.gsub(/-/, "_")
- if respond_to?(method_name)
- __send__(method_name, req, res)
- else
- raise HTTPStatus::MethodNotAllowed,
- "unsupported method `#{req.request_method}'."
- end
- end
-
- ##
- # Provides HTTP socket emulation from the CGI environment
-
- class Socket # :nodoc:
- include Enumerable
-
- private
-
- def initialize(config, env, stdin, stdout)
- @config = config
- @env = env
- @header_part = StringIO.new
- @body_part = stdin
- @out_port = stdout
- @out_port.binmode
-
- @server_addr = @env["SERVER_ADDR"] || "0.0.0.0"
- @server_name = @env["SERVER_NAME"]
- @server_port = @env["SERVER_PORT"]
- @remote_addr = @env["REMOTE_ADDR"]
- @remote_host = @env["REMOTE_HOST"] || @remote_addr
- @remote_port = @env["REMOTE_PORT"] || 0
-
- begin
- @header_part << request_line << CRLF
- setup_header
- @header_part << CRLF
- @header_part.rewind
- rescue Exception
- raise CGIError, "invalid CGI environment"
- end
- end
-
- def request_line
- meth = @env["REQUEST_METHOD"] || "GET"
- unless url = @env["REQUEST_URI"]
- url = (@env["SCRIPT_NAME"] || File.expand_path($0)).dup
- url << @env["PATH_INFO"].to_s
- url = WEBrick::HTTPUtils.escape_path(url)
- if query_string = @env["QUERY_STRING"]
- unless query_string.empty?
- url << "?" << query_string
- end
- end
- end
- # we cannot get real HTTP version of client ;)
- httpv = @config[:HTTPVersion]
- return "#{meth} #{url} HTTP/#{httpv}"
- end
-
- def setup_header
- @env.each{|key, value|
- case key
- when "CONTENT_TYPE", "CONTENT_LENGTH"
- add_header(key.gsub(/_/, "-"), value)
- when /^HTTP_(.*)/
- add_header($1.gsub(/_/, "-"), value)
- end
- }
- end
-
- def add_header(hdrname, value)
- unless value.empty?
- @header_part << hdrname << ": " << value << CRLF
- end
- end
-
- def input
- @header_part.eof? ? @body_part : @header_part
- end
-
- public
-
- def peeraddr
- [nil, @remote_port, @remote_host, @remote_addr]
- end
-
- def addr
- [nil, @server_port, @server_name, @server_addr]
- end
-
- def gets(eol=LF, size=nil)
- input.gets(eol, size)
- end
-
- def read(size=nil)
- input.read(size)
- end
-
- def each
- input.each{|line| yield(line) }
- end
-
- def eof?
- input.eof?
- end
-
- def <<(data)
- @out_port << data
- end
-
- def cert
- return nil unless defined?(OpenSSL)
- if pem = @env["SSL_SERVER_CERT"]
- OpenSSL::X509::Certificate.new(pem) unless pem.empty?
- end
- end
-
- def peer_cert
- return nil unless defined?(OpenSSL)
- if pem = @env["SSL_CLIENT_CERT"]
- OpenSSL::X509::Certificate.new(pem) unless pem.empty?
- end
- end
-
- def peer_cert_chain
- return nil unless defined?(OpenSSL)
- if @env["SSL_CLIENT_CERT_CHAIN_0"]
- keys = @env.keys
- certs = keys.sort.collect{|k|
- if /^SSL_CLIENT_CERT_CHAIN_\d+$/ =~ k
- if pem = @env[k]
- OpenSSL::X509::Certificate.new(pem) unless pem.empty?
- end
- end
- }
- certs.compact
- end
- end
-
- def cipher
- return nil unless defined?(OpenSSL)
- if cipher = @env["SSL_CIPHER"]
- ret = [ cipher ]
- ret << @env["SSL_PROTOCOL"]
- ret << @env["SSL_CIPHER_USEKEYSIZE"]
- ret << @env["SSL_CIPHER_ALGKEYSIZE"]
- ret
- end
- end
- end
- end
-end
diff --git a/lib/webrick/config.rb b/lib/webrick/config.rb
deleted file mode 100644
index af4b561534..0000000000
--- a/lib/webrick/config.rb
+++ /dev/null
@@ -1,158 +0,0 @@
-# frozen_string_literal: false
-#
-# config.rb -- Default configurations.
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $
-
-require 'webrick/version'
-require 'webrick/httpversion'
-require 'webrick/httputils'
-require 'webrick/utils'
-require 'webrick/log'
-
-module WEBrick
- module Config
- LIBDIR = File::dirname(__FILE__) # :nodoc:
-
- # for GenericServer
- General = Hash.new { |hash, key|
- case key
- when :ServerName
- hash[key] = Utils.getservername
- else
- nil
- end
- }.update(
- :BindAddress => nil, # "0.0.0.0" or "::" or nil
- :Port => nil, # users MUST specify this!!
- :MaxClients => 100, # maximum number of the concurrent connections
- :ServerType => nil, # default: WEBrick::SimpleServer
- :Logger => nil, # default: WEBrick::Log.new
- :ServerSoftware => "WEBrick/#{WEBrick::VERSION} " +
- "(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})",
- :TempDir => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp',
- :DoNotListen => false,
- :StartCallback => nil,
- :StopCallback => nil,
- :AcceptCallback => nil,
- :DoNotReverseLookup => true,
- :ShutdownSocketWithoutClose => false,
- )
-
- # for HTTPServer, HTTPRequest, HTTPResponse ...
- HTTP = General.dup.update(
- :Port => 80,
- :RequestTimeout => 30,
- :HTTPVersion => HTTPVersion.new("1.1"),
- :AccessLog => nil,
- :MimeTypes => HTTPUtils::DefaultMimeTypes,
- :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"],
- :DocumentRoot => nil,
- :DocumentRootOptions => { :FancyIndexing => true },
- :RequestCallback => nil,
- :ServerAlias => nil,
- :InputBufferSize => 65536, # input buffer size in reading request body
- :OutputBufferSize => 65536, # output buffer size in sending File or IO
-
- # for HTTPProxyServer
- :ProxyAuthProc => nil,
- :ProxyContentHandler => nil,
- :ProxyVia => true,
- :ProxyTimeout => true,
- :ProxyURI => nil,
-
- :CGIInterpreter => nil,
- :CGIPathEnv => nil,
-
- # workaround: if Request-URIs contain 8bit chars,
- # they should be escaped before calling of URI::parse().
- :Escape8bitURI => false
- )
-
- ##
- # Default configuration for WEBrick::HTTPServlet::FileHandler
- #
- # :AcceptableLanguages::
- # Array of languages allowed for accept-language. There is no default
- # :DirectoryCallback::
- # Allows preprocessing of directory requests. There is no default
- # callback.
- # :FancyIndexing::
- # If true, show an index for directories. The default is true.
- # :FileCallback::
- # Allows preprocessing of file requests. There is no default callback.
- # :HandlerCallback::
- # Allows preprocessing of requests. There is no default callback.
- # :HandlerTable::
- # Maps file suffixes to file handlers. DefaultFileHandler is used by
- # default but any servlet can be used.
- # :NondisclosureName::
- # Do not show files matching this array of globs. .ht* and *~ are
- # excluded by default.
- # :UserDir::
- # Directory inside ~user to serve content from for /~user requests.
- # Only works if mounted on /. Disabled by default.
-
- FileHandler = {
- :NondisclosureName => [".ht*", "*~"],
- :FancyIndexing => false,
- :HandlerTable => {},
- :HandlerCallback => nil,
- :DirectoryCallback => nil,
- :FileCallback => nil,
- :UserDir => nil, # e.g. "public_html"
- :AcceptableLanguages => [] # ["en", "ja", ... ]
- }
-
- ##
- # Default configuration for WEBrick::HTTPAuth::BasicAuth
- #
- # :AutoReloadUserDB:: Reload the user database provided by :UserDB
- # automatically?
-
- BasicAuth = {
- :AutoReloadUserDB => true,
- }
-
- ##
- # Default configuration for WEBrick::HTTPAuth::DigestAuth.
- #
- # :Algorithm:: MD5, MD5-sess (default), SHA1, SHA1-sess
- # :Domain:: An Array of URIs that define the protected space
- # :Qop:: 'auth' for authentication, 'auth-int' for integrity protection or
- # both
- # :UseOpaque:: Should the server send opaque values to the client? This
- # helps prevent replay attacks.
- # :CheckNc:: Should the server check the nonce count? This helps the
- # server detect replay attacks.
- # :UseAuthenticationInfoHeader:: Should the server send an
- # AuthenticationInfo header?
- # :AutoReloadUserDB:: Reload the user database provided by :UserDB
- # automatically?
- # :NonceExpirePeriod:: How long should we store used nonces? Default is
- # 30 minutes.
- # :NonceExpireDelta:: How long is a nonce valid? Default is 1 minute
- # :InternetExplorerHack:: Hack which allows Internet Explorer to work.
- # :OperaHack:: Hack which allows Opera to work.
-
- DigestAuth = {
- :Algorithm => 'MD5-sess', # or 'MD5'
- :Domain => nil, # an array includes domain names.
- :Qop => [ 'auth' ], # 'auth' or 'auth-int' or both.
- :UseOpaque => true,
- :UseNextNonce => false,
- :CheckNc => false,
- :UseAuthenticationInfoHeader => true,
- :AutoReloadUserDB => true,
- :NonceExpirePeriod => 30*60,
- :NonceExpireDelta => 60,
- :InternetExplorerHack => true,
- :OperaHack => true,
- }
- end
-end
diff --git a/lib/webrick/cookie.rb b/lib/webrick/cookie.rb
deleted file mode 100644
index 24bf92ec00..0000000000
--- a/lib/webrick/cookie.rb
+++ /dev/null
@@ -1,172 +0,0 @@
-# frozen_string_literal: false
-#
-# cookie.rb -- Cookie class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $
-
-require 'time'
-require 'webrick/httputils'
-
-module WEBrick
-
- ##
- # Processes HTTP cookies
-
- class Cookie
-
- ##
- # The cookie name
-
- attr_reader :name
-
- ##
- # The cookie value
-
- attr_accessor :value
-
- ##
- # The cookie version
-
- attr_accessor :version
-
- ##
- # The cookie domain
- attr_accessor :domain
-
- ##
- # The cookie path
-
- attr_accessor :path
-
- ##
- # Is this a secure cookie?
-
- attr_accessor :secure
-
- ##
- # The cookie comment
-
- attr_accessor :comment
-
- ##
- # The maximum age of the cookie
-
- attr_accessor :max_age
-
- #attr_accessor :comment_url, :discard, :port
-
- ##
- # Creates a new cookie with the given +name+ and +value+
-
- def initialize(name, value)
- @name = name
- @value = value
- @version = 0 # Netscape Cookie
-
- @domain = @path = @secure = @comment = @max_age =
- @expires = @comment_url = @discard = @port = nil
- end
-
- ##
- # Sets the cookie expiration to the time +t+. The expiration time may be
- # a false value to disable expiration or a Time or HTTP format time string
- # to set the expiration date.
-
- def expires=(t)
- @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
- end
-
- ##
- # Retrieves the expiration time as a Time
-
- def expires
- @expires && Time.parse(@expires)
- end
-
- ##
- # The cookie string suitable for use in an HTTP header
-
- def to_s
- ret = ""
- ret << @name << "=" << @value
- ret << "; " << "Version=" << @version.to_s if @version > 0
- ret << "; " << "Domain=" << @domain if @domain
- ret << "; " << "Expires=" << @expires if @expires
- ret << "; " << "Max-Age=" << @max_age.to_s if @max_age
- ret << "; " << "Comment=" << @comment if @comment
- ret << "; " << "Path=" << @path if @path
- ret << "; " << "Secure" if @secure
- ret
- end
-
- ##
- # Parses a Cookie field sent from the user-agent. Returns an array of
- # cookies.
-
- def self.parse(str)
- if str
- ret = []
- cookie = nil
- ver = 0
- str.split(/;\s+/).each{|x|
- key, val = x.split(/=/,2)
- val = val ? HTTPUtils::dequote(val) : ""
- case key
- when "$Version"; ver = val.to_i
- when "$Path"; cookie.path = val
- when "$Domain"; cookie.domain = val
- when "$Port"; cookie.port = val
- else
- ret << cookie if cookie
- cookie = self.new(key, val)
- cookie.version = ver
- end
- }
- ret << cookie if cookie
- ret
- end
- end
-
- ##
- # Parses the cookie in +str+
-
- def self.parse_set_cookie(str)
- cookie_elem = str.split(/;/)
- first_elem = cookie_elem.shift
- first_elem.strip!
- key, value = first_elem.split(/=/, 2)
- cookie = new(key, HTTPUtils.dequote(value))
- cookie_elem.each{|pair|
- pair.strip!
- key, value = pair.split(/=/, 2)
- if value
- value = HTTPUtils.dequote(value.strip)
- end
- case key.downcase
- when "domain" then cookie.domain = value
- when "path" then cookie.path = value
- when "expires" then cookie.expires = value
- when "max-age" then cookie.max_age = Integer(value)
- when "comment" then cookie.comment = value
- when "version" then cookie.version = Integer(value)
- when "secure" then cookie.secure = true
- end
- }
- return cookie
- end
-
- ##
- # Parses the cookies in +str+
-
- def self.parse_set_cookies(str)
- return str.split(/,(?=[^;,]*=)|,$/).collect{|c|
- parse_set_cookie(c)
- }
- end
- end
-end
diff --git a/lib/webrick/httpauth.rb b/lib/webrick/httpauth.rb
deleted file mode 100644
index bbb6776528..0000000000
--- a/lib/webrick/httpauth.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-# frozen_string_literal: false
-#
-# httpauth.rb -- HTTP access authentication
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpauth.rb,v 1.14 2003/07/22 19:20:42 gotoyuzo Exp $
-
-require 'webrick/httpauth/basicauth'
-require 'webrick/httpauth/digestauth'
-require 'webrick/httpauth/htpasswd'
-require 'webrick/httpauth/htdigest'
-require 'webrick/httpauth/htgroup'
-
-module WEBrick
-
- ##
- # HTTPAuth provides both basic and digest authentication.
- #
- # To enable authentication for requests in WEBrick you will need a user
- # database and an authenticator. To start, here's an Htpasswd database for
- # use with a DigestAuth authenticator:
- #
- # config = { :Realm => 'DigestAuth example realm' }
- #
- # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
- # htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth
- # htpasswd.set_passwd config[:Realm], 'username', 'password'
- # htpasswd.flush
- #
- # The +:Realm+ is used to provide different access to different groups
- # across several resources on a server. Typically you'll need only one
- # realm for a server.
- #
- # This database can be used to create an authenticator:
- #
- # config[:UserDB] = htpasswd
- #
- # digest_auth = WEBrick::HTTPAuth::DigestAuth.new config
- #
- # To authenticate a request call #authenticate with a request and response
- # object in a servlet:
- #
- # def do_GET req, res
- # @authenticator.authenticate req, res
- # end
- #
- # For digest authentication the authenticator must not be created every
- # request, it must be passed in as an option via WEBrick::HTTPServer#mount.
-
- module HTTPAuth
- module_function
-
- def _basic_auth(req, res, realm, req_field, res_field, err_type,
- block) # :nodoc:
- user = pass = nil
- if /^Basic\s+(.*)/o =~ req[req_field]
- userpass = $1
- user, pass = userpass.unpack("m*")[0].split(":", 2)
- end
- if block.call(user, pass)
- req.user = user
- return
- end
- res[res_field] = "Basic realm=\"#{realm}\""
- raise err_type
- end
-
- ##
- # Simple wrapper for providing basic authentication for a request. When
- # called with a request +req+, response +res+, authentication +realm+ and
- # +block+ the block will be called with a +username+ and +password+. If
- # the block returns true the request is allowed to continue, otherwise an
- # HTTPStatus::Unauthorized error is raised.
-
- def basic_auth(req, res, realm, &block) # :yield: username, password
- _basic_auth(req, res, realm, "Authorization", "WWW-Authenticate",
- HTTPStatus::Unauthorized, block)
- end
-
- ##
- # Simple wrapper for providing basic authentication for a proxied request.
- # When called with a request +req+, response +res+, authentication +realm+
- # and +block+ the block will be called with a +username+ and +password+.
- # If the block returns true the request is allowed to continue, otherwise
- # an HTTPStatus::ProxyAuthenticationRequired error is raised.
-
- def proxy_basic_auth(req, res, realm, &block) # :yield: username, password
- _basic_auth(req, res, realm, "Proxy-Authorization", "Proxy-Authenticate",
- HTTPStatus::ProxyAuthenticationRequired, block)
- end
- end
-end
diff --git a/lib/webrick/httpauth/authenticator.rb b/lib/webrick/httpauth/authenticator.rb
deleted file mode 100644
index 8655118a04..0000000000
--- a/lib/webrick/httpauth/authenticator.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-# frozen_string_literal: false
-#--
-# httpauth/authenticator.rb -- Authenticator mix-in module.
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: authenticator.rb,v 1.3 2003/02/20 07:15:47 gotoyuzo Exp $
-
-module WEBrick
- module HTTPAuth
-
- ##
- # Module providing generic support for both Digest and Basic
- # authentication schemes.
-
- module Authenticator
-
- RequestField = "Authorization" # :nodoc:
- ResponseField = "WWW-Authenticate" # :nodoc:
- ResponseInfoField = "Authentication-Info" # :nodoc:
- AuthException = HTTPStatus::Unauthorized # :nodoc:
-
- ##
- # Method of authentication, must be overridden by the including class
-
- AuthScheme = nil
-
- ##
- # The realm this authenticator covers
-
- attr_reader :realm
-
- ##
- # The user database for this authenticator
-
- attr_reader :userdb
-
- ##
- # The logger for this authenticator
-
- attr_reader :logger
-
- private
-
- # :stopdoc:
-
- ##
- # Initializes the authenticator from +config+
-
- def check_init(config)
- [:UserDB, :Realm].each{|sym|
- unless config[sym]
- raise ArgumentError, "Argument #{sym.inspect} missing."
- end
- }
- @realm = config[:Realm]
- @userdb = config[:UserDB]
- @logger = config[:Logger] || Log::new($stderr)
- @reload_db = config[:AutoReloadUserDB]
- @request_field = self::class::RequestField
- @response_field = self::class::ResponseField
- @resp_info_field = self::class::ResponseInfoField
- @auth_exception = self::class::AuthException
- @auth_scheme = self::class::AuthScheme
- end
-
- ##
- # Ensures +req+ has credentials that can be authenticated.
-
- def check_scheme(req)
- unless credentials = req[@request_field]
- error("no credentials in the request.")
- return nil
- end
- unless match = /^#{@auth_scheme}\s+/i.match(credentials)
- error("invalid scheme in %s.", credentials)
- info("%s: %s", @request_field, credentials) if $DEBUG
- return nil
- end
- return match.post_match
- end
-
- def log(meth, fmt, *args)
- msg = format("%s %s: ", @auth_scheme, @realm)
- msg << fmt % args
- @logger.send(meth, msg)
- end
-
- def error(fmt, *args)
- if @logger.error?
- log(:error, fmt, *args)
- end
- end
-
- def info(fmt, *args)
- if @logger.info?
- log(:info, fmt, *args)
- end
- end
-
- # :startdoc:
- end
-
- ##
- # Module providing generic support for both Digest and Basic
- # authentication schemes for proxies.
-
- module ProxyAuthenticator
- RequestField = "Proxy-Authorization" # :nodoc:
- ResponseField = "Proxy-Authenticate" # :nodoc:
- InfoField = "Proxy-Authentication-Info" # :nodoc:
- AuthException = HTTPStatus::ProxyAuthenticationRequired # :nodoc:
- end
- end
-end
diff --git a/lib/webrick/httpauth/basicauth.rb b/lib/webrick/httpauth/basicauth.rb
deleted file mode 100644
index e23420fdfa..0000000000
--- a/lib/webrick/httpauth/basicauth.rb
+++ /dev/null
@@ -1,108 +0,0 @@
-# frozen_string_literal: false
-#
-# httpauth/basicauth.rb -- HTTP basic access authentication
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: basicauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $
-
-require 'webrick/config'
-require 'webrick/httpstatus'
-require 'webrick/httpauth/authenticator'
-
-module WEBrick
- module HTTPAuth
-
- ##
- # Basic Authentication for WEBrick
- #
- # Use this class to add basic authentication to a WEBrick servlet.
- #
- # Here is an example of how to set up a BasicAuth:
- #
- # config = { :Realm => 'BasicAuth example realm' }
- #
- # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
- # htpasswd.set_passwd config[:Realm], 'username', 'password'
- # htpasswd.flush
- #
- # config[:UserDB] = htpasswd
- #
- # basic_auth = WEBrick::HTTPAuth::BasicAuth.new config
-
- class BasicAuth
- include Authenticator
-
- AuthScheme = "Basic" # :nodoc:
-
- ##
- # Used by UserDB to create a basic password entry
-
- def self.make_passwd(realm, user, pass)
- pass ||= ""
- pass.crypt(Utils::random_string(2))
- end
-
- attr_reader :realm, :userdb, :logger
-
- ##
- # Creates a new BasicAuth instance.
- #
- # See WEBrick::Config::BasicAuth for default configuration entries
- #
- # You must supply the following configuration entries:
- #
- # :Realm:: The name of the realm being protected.
- # :UserDB:: A database of usernames and passwords.
- # A WEBrick::HTTPAuth::Htpasswd instance should be used.
-
- def initialize(config, default=Config::BasicAuth)
- check_init(config)
- @config = default.dup.update(config)
- end
-
- ##
- # Authenticates a +req+ and returns a 401 Unauthorized using +res+ if
- # the authentication was not correct.
-
- def authenticate(req, res)
- unless basic_credentials = check_scheme(req)
- challenge(req, res)
- end
- userid, password = basic_credentials.unpack("m*")[0].split(":", 2)
- password ||= ""
- if userid.empty?
- error("user id was not given.")
- challenge(req, res)
- end
- unless encpass = @userdb.get_passwd(@realm, userid, @reload_db)
- error("%s: the user is not allowed.", userid)
- challenge(req, res)
- end
- if password.crypt(encpass) != encpass
- error("%s: password unmatch.", userid)
- challenge(req, res)
- end
- info("%s: authentication succeeded.", userid)
- req.user = userid
- end
-
- ##
- # Returns a challenge response which asks for authentication information
-
- def challenge(req, res)
- res[@response_field] = "#{@auth_scheme} realm=\"#{@realm}\""
- raise @auth_exception
- end
- end
-
- ##
- # Basic authentication for proxy servers. See BasicAuth for details.
-
- class ProxyBasicAuth < BasicAuth
- include ProxyAuthenticator
- end
- end
-end
diff --git a/lib/webrick/httpauth/digestauth.rb b/lib/webrick/httpauth/digestauth.rb
deleted file mode 100644
index 375ec20154..0000000000
--- a/lib/webrick/httpauth/digestauth.rb
+++ /dev/null
@@ -1,408 +0,0 @@
-# frozen_string_literal: false
-#
-# httpauth/digestauth.rb -- HTTP digest access authentication
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers.
-# Copyright (c) 2003 H.M.
-#
-# The original implementation is provided by H.M.
-# URL: http://rwiki.jin.gr.jp/cgi-bin/rw-cgi.rb?cmd=view;name=
-# %C7%A7%BE%DA%B5%A1%C7%BD%A4%F2%B2%FE%C2%A4%A4%B7%A4%C6%A4%DF%A4%EB
-#
-# $IPR: digestauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $
-
-require 'webrick/config'
-require 'webrick/httpstatus'
-require 'webrick/httpauth/authenticator'
-require 'digest/md5'
-require 'digest/sha1'
-
-module WEBrick
- module HTTPAuth
-
- ##
- # RFC 2617 Digest Access Authentication for WEBrick
- #
- # Use this class to add digest authentication to a WEBrick servlet.
- #
- # Here is an example of how to set up DigestAuth:
- #
- # config = { :Realm => 'DigestAuth example realm' }
- #
- # htdigest = WEBrick::HTTPAuth::Htdigest.new 'my_password_file'
- # htdigest.set_passwd config[:Realm], 'username', 'password'
- # htdigest.flush
- #
- # config[:UserDB] = htdigest
- #
- # digest_auth = WEBrick::HTTPAuth::DigestAuth.new config
- #
- # When using this as with a servlet be sure not to create a new DigestAuth
- # object in the servlet's #initialize. By default WEBrick creates a new
- # servlet instance for every request and the DigestAuth object must be
- # used across requests.
-
- class DigestAuth
- include Authenticator
-
- AuthScheme = "Digest" # :nodoc:
-
- ##
- # Struct containing the opaque portion of the digest authentication
-
- OpaqueInfo = Struct.new(:time, :nonce, :nc) # :nodoc:
-
- ##
- # Digest authentication algorithm
-
- attr_reader :algorithm
-
- ##
- # Quality of protection. RFC 2617 defines "auth" and "auth-int"
-
- attr_reader :qop
-
- ##
- # Used by UserDB to create a digest password entry
-
- def self.make_passwd(realm, user, pass)
- pass ||= ""
- Digest::MD5::hexdigest([user, realm, pass].join(":"))
- end
-
- ##
- # Creates a new DigestAuth instance. Be sure to use the same DigestAuth
- # instance for multiple requests as it saves state between requests in
- # order to perform authentication.
- #
- # See WEBrick::Config::DigestAuth for default configuration entries
- #
- # You must supply the following configuration entries:
- #
- # :Realm:: The name of the realm being protected.
- # :UserDB:: A database of usernames and passwords.
- # A WEBrick::HTTPAuth::Htdigest instance should be used.
-
- def initialize(config, default=Config::DigestAuth)
- check_init(config)
- @config = default.dup.update(config)
- @algorithm = @config[:Algorithm]
- @domain = @config[:Domain]
- @qop = @config[:Qop]
- @use_opaque = @config[:UseOpaque]
- @use_next_nonce = @config[:UseNextNonce]
- @check_nc = @config[:CheckNc]
- @use_auth_info_header = @config[:UseAuthenticationInfoHeader]
- @nonce_expire_period = @config[:NonceExpirePeriod]
- @nonce_expire_delta = @config[:NonceExpireDelta]
- @internet_explorer_hack = @config[:InternetExplorerHack]
-
- case @algorithm
- when 'MD5','MD5-sess'
- @h = Digest::MD5
- when 'SHA1','SHA1-sess' # it is a bonus feature :-)
- @h = Digest::SHA1
- else
- msg = format('Algorithm "%s" is not supported.', @algorithm)
- raise ArgumentError.new(msg)
- end
-
- @instance_key = hexdigest(self.__id__, Time.now.to_i, Process.pid)
- @opaques = {}
- @last_nonce_expire = Time.now
- @mutex = Thread::Mutex.new
- end
-
- ##
- # Authenticates a +req+ and returns a 401 Unauthorized using +res+ if
- # the authentication was not correct.
-
- def authenticate(req, res)
- unless result = @mutex.synchronize{ _authenticate(req, res) }
- challenge(req, res)
- end
- if result == :nonce_is_stale
- challenge(req, res, true)
- end
- return true
- end
-
- ##
- # Returns a challenge response which asks for authentication information
-
- def challenge(req, res, stale=false)
- nonce = generate_next_nonce(req)
- if @use_opaque
- opaque = generate_opaque(req)
- @opaques[opaque].nonce = nonce
- end
-
- param = Hash.new
- param["realm"] = HTTPUtils::quote(@realm)
- param["domain"] = HTTPUtils::quote(@domain.to_a.join(" ")) if @domain
- param["nonce"] = HTTPUtils::quote(nonce)
- param["opaque"] = HTTPUtils::quote(opaque) if opaque
- param["stale"] = stale.to_s
- param["algorithm"] = @algorithm
- param["qop"] = HTTPUtils::quote(@qop.to_a.join(",")) if @qop
-
- res[@response_field] =
- "#{@auth_scheme} " + param.map{|k,v| "#{k}=#{v}" }.join(", ")
- info("%s: %s", @response_field, res[@response_field]) if $DEBUG
- raise @auth_exception
- end
-
- private
-
- # :stopdoc:
-
- MustParams = ['username','realm','nonce','uri','response']
- MustParamsAuth = ['cnonce','nc']
-
- def _authenticate(req, res)
- unless digest_credentials = check_scheme(req)
- return false
- end
-
- auth_req = split_param_value(digest_credentials)
- if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
- req_params = MustParams + MustParamsAuth
- else
- req_params = MustParams
- end
- req_params.each{|key|
- unless auth_req.has_key?(key)
- error('%s: parameter missing. "%s"', auth_req['username'], key)
- raise HTTPStatus::BadRequest
- end
- }
-
- if !check_uri(req, auth_req)
- raise HTTPStatus::BadRequest
- end
-
- if auth_req['realm'] != @realm
- error('%s: realm unmatch. "%s" for "%s"',
- auth_req['username'], auth_req['realm'], @realm)
- return false
- end
-
- auth_req['algorithm'] ||= 'MD5'
- if auth_req['algorithm'].upcase != @algorithm.upcase
- error('%s: algorithm unmatch. "%s" for "%s"',
- auth_req['username'], auth_req['algorithm'], @algorithm)
- return false
- end
-
- if (@qop.nil? && auth_req.has_key?('qop')) ||
- (@qop && (! @qop.member?(auth_req['qop'])))
- error('%s: the qop is not allowed. "%s"',
- auth_req['username'], auth_req['qop'])
- return false
- end
-
- password = @userdb.get_passwd(@realm, auth_req['username'], @reload_db)
- unless password
- error('%s: the user is not allowed.', auth_req['username'])
- return false
- end
-
- nonce_is_invalid = false
- if @use_opaque
- info("@opaque = %s", @opaque.inspect) if $DEBUG
- if !(opaque = auth_req['opaque'])
- error('%s: opaque is not given.', auth_req['username'])
- nonce_is_invalid = true
- elsif !(opaque_struct = @opaques[opaque])
- error('%s: invalid opaque is given.', auth_req['username'])
- nonce_is_invalid = true
- elsif !check_opaque(opaque_struct, req, auth_req)
- @opaques.delete(auth_req['opaque'])
- nonce_is_invalid = true
- end
- elsif !check_nonce(req, auth_req)
- nonce_is_invalid = true
- end
-
- if /-sess$/i =~ auth_req['algorithm']
- ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce'])
- else
- ha1 = password
- end
-
- if auth_req['qop'] == "auth" || auth_req['qop'] == nil
- ha2 = hexdigest(req.request_method, auth_req['uri'])
- ha2_res = hexdigest("", auth_req['uri'])
- elsif auth_req['qop'] == "auth-int"
- ha2 = hexdigest(req.request_method, auth_req['uri'],
- hexdigest(req.body))
- ha2_res = hexdigest("", auth_req['uri'], hexdigest(res.body))
- end
-
- if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
- param2 = ['nonce', 'nc', 'cnonce', 'qop'].map{|key|
- auth_req[key]
- }.join(':')
- digest = hexdigest(ha1, param2, ha2)
- digest_res = hexdigest(ha1, param2, ha2_res)
- else
- digest = hexdigest(ha1, auth_req['nonce'], ha2)
- digest_res = hexdigest(ha1, auth_req['nonce'], ha2_res)
- end
-
- if digest != auth_req['response']
- error("%s: digest unmatch.", auth_req['username'])
- return false
- elsif nonce_is_invalid
- error('%s: digest is valid, but nonce is not valid.',
- auth_req['username'])
- return :nonce_is_stale
- elsif @use_auth_info_header
- auth_info = {
- 'nextnonce' => generate_next_nonce(req),
- 'rspauth' => digest_res
- }
- if @use_opaque
- opaque_struct.time = req.request_time
- opaque_struct.nonce = auth_info['nextnonce']
- opaque_struct.nc = "%08x" % (auth_req['nc'].hex + 1)
- end
- if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
- ['qop','cnonce','nc'].each{|key|
- auth_info[key] = auth_req[key]
- }
- end
- res[@resp_info_field] = auth_info.keys.map{|key|
- if key == 'nc'
- key + '=' + auth_info[key]
- else
- key + "=" + HTTPUtils::quote(auth_info[key])
- end
- }.join(', ')
- end
- info('%s: authentication succeeded.', auth_req['username'])
- req.user = auth_req['username']
- return true
- end
-
- def split_param_value(string)
- ret = {}
- while string.bytesize != 0
- case string
- when /^\s*([\w\-\.\*\%\!]+)=\s*\"((\\.|[^\"])*)\"\s*,?/
- key = $1
- matched = $2
- string = $'
- ret[key] = matched.gsub(/\\(.)/, "\\1")
- when /^\s*([\w\-\.\*\%\!]+)=\s*([^,\"]*),?/
- key = $1
- matched = $2
- string = $'
- ret[key] = matched.clone
- when /^s*^,/
- string = $'
- else
- break
- end
- end
- ret
- end
-
- def generate_next_nonce(req)
- now = "%012d" % req.request_time.to_i
- pk = hexdigest(now, @instance_key)[0,32]
- nonce = [now + ":" + pk].pack("m0") # it has 60 length of chars.
- nonce
- end
-
- def check_nonce(req, auth_req)
- username = auth_req['username']
- nonce = auth_req['nonce']
-
- pub_time, pk = nonce.unpack("m*")[0].split(":", 2)
- if (!pub_time || !pk)
- error("%s: empty nonce is given", username)
- return false
- elsif (hexdigest(pub_time, @instance_key)[0,32] != pk)
- error("%s: invalid private-key: %s for %s",
- username, hexdigest(pub_time, @instance_key)[0,32], pk)
- return false
- end
-
- diff_time = req.request_time.to_i - pub_time.to_i
- if (diff_time < 0)
- error("%s: difference of time-stamp is negative.", username)
- return false
- elsif diff_time > @nonce_expire_period
- error("%s: nonce is expired.", username)
- return false
- end
-
- return true
- end
-
- def generate_opaque(req)
- @mutex.synchronize{
- now = req.request_time
- if now - @last_nonce_expire > @nonce_expire_delta
- @opaques.delete_if{|key,val|
- (now - val.time) > @nonce_expire_period
- }
- @last_nonce_expire = now
- end
- begin
- opaque = Utils::random_string(16)
- end while @opaques[opaque]
- @opaques[opaque] = OpaqueInfo.new(now, nil, '00000001')
- opaque
- }
- end
-
- def check_opaque(opaque_struct, req, auth_req)
- if (@use_next_nonce && auth_req['nonce'] != opaque_struct.nonce)
- error('%s: nonce unmatched. "%s" for "%s"',
- auth_req['username'], auth_req['nonce'], opaque_struct.nonce)
- return false
- elsif !check_nonce(req, auth_req)
- return false
- end
- if (@check_nc && auth_req['nc'] != opaque_struct.nc)
- error('%s: nc unmatched."%s" for "%s"',
- auth_req['username'], auth_req['nc'], opaque_struct.nc)
- return false
- end
- true
- end
-
- def check_uri(req, auth_req)
- uri = auth_req['uri']
- if uri != req.request_uri.to_s && uri != req.unparsed_uri &&
- (@internet_explorer_hack && uri != req.path)
- error('%s: uri unmatch. "%s" for "%s"', auth_req['username'],
- auth_req['uri'], req.request_uri.to_s)
- return false
- end
- true
- end
-
- def hexdigest(*args)
- @h.hexdigest(args.join(":"))
- end
-
- # :startdoc:
- end
-
- ##
- # Digest authentication for proxy servers. See DigestAuth for details.
-
- class ProxyDigestAuth < DigestAuth
- include ProxyAuthenticator
-
- private
- def check_uri(req, auth_req) # :nodoc:
- return true
- end
- end
- end
-end
diff --git a/lib/webrick/httpauth/htdigest.rb b/lib/webrick/httpauth/htdigest.rb
deleted file mode 100644
index 1b42c02dfa..0000000000
--- a/lib/webrick/httpauth/htdigest.rb
+++ /dev/null
@@ -1,132 +0,0 @@
-# frozen_string_literal: false
-#
-# httpauth/htdigest.rb -- Apache compatible htdigest file
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
-
-require 'webrick/httpauth/userdb'
-require 'webrick/httpauth/digestauth'
-require 'tempfile'
-
-module WEBrick
- module HTTPAuth
-
- ##
- # Htdigest accesses apache-compatible digest password files. Passwords are
- # matched to a realm where they are valid. For security, the path for a
- # digest password database should be stored outside of the paths available
- # to the HTTP server.
- #
- # Htdigest is intended for use with WEBrick::HTTPAuth::DigestAuth and
- # stores passwords using cryptographic hashes.
- #
- # htpasswd = WEBrick::HTTPAuth::Htdigest.new 'my_password_file'
- # htpasswd.set_passwd 'my realm', 'username', 'password'
- # htpasswd.flush
-
- class Htdigest
- include UserDB
-
- ##
- # Open a digest password database at +path+
-
- def initialize(path)
- @path = path
- @mtime = Time.at(0)
- @digest = Hash.new
- @mutex = Thread::Mutex::new
- @auth_type = DigestAuth
- open(@path,"a").close unless File::exist?(@path)
- reload
- end
-
- ##
- # Reloads passwords from the database
-
- def reload
- mtime = File::mtime(@path)
- if mtime > @mtime
- @digest.clear
- open(@path){|io|
- while line = io.gets
- line.chomp!
- user, realm, pass = line.split(/:/, 3)
- unless @digest[realm]
- @digest[realm] = Hash.new
- end
- @digest[realm][user] = pass
- end
- }
- @mtime = mtime
- end
- end
-
- ##
- # Flush the password database. If +output+ is given the database will
- # be written there instead of to the original path.
-
- def flush(output=nil)
- output ||= @path
- tmp = Tempfile.create("htpasswd", File::dirname(output))
- renamed = false
- begin
- each{|item| tmp.puts(item.join(":")) }
- tmp.close
- File::rename(tmp.path, output)
- renamed = true
- ensure
- tmp.close
- File.unlink(tmp.path) if !renamed
- end
- end
-
- ##
- # Retrieves a password from the database for +user+ in +realm+. If
- # +reload_db+ is true the database will be reloaded first.
-
- def get_passwd(realm, user, reload_db)
- reload() if reload_db
- if hash = @digest[realm]
- hash[user]
- end
- end
-
- ##
- # Sets a password in the database for +user+ in +realm+ to +pass+.
-
- def set_passwd(realm, user, pass)
- @mutex.synchronize{
- unless @digest[realm]
- @digest[realm] = Hash.new
- end
- @digest[realm][user] = make_passwd(realm, user, pass)
- }
- end
-
- ##
- # Removes a password from the database for +user+ in +realm+.
-
- def delete_passwd(realm, user)
- if hash = @digest[realm]
- hash.delete(user)
- end
- end
-
- ##
- # Iterate passwords in the database.
-
- def each # :yields: [user, realm, password_hash]
- @digest.keys.sort.each{|realm|
- hash = @digest[realm]
- hash.keys.sort.each{|user|
- yield([user, realm, hash[user]])
- }
- }
- end
- end
- end
-end
diff --git a/lib/webrick/httpauth/htgroup.rb b/lib/webrick/httpauth/htgroup.rb
deleted file mode 100644
index 832ae8bd04..0000000000
--- a/lib/webrick/httpauth/htgroup.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: false
-#
-# httpauth/htgroup.rb -- Apache compatible htgroup file
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: htgroup.rb,v 1.1 2003/02/16 22:22:56 gotoyuzo Exp $
-
-require 'tempfile'
-
-module WEBrick
- module HTTPAuth
-
- ##
- # Htgroup accesses apache-compatible group files. Htgroup can be used to
- # provide group-based authentication for users. Currently Htgroup is not
- # directly integrated with any authenticators in WEBrick. For security,
- # the path for a digest password database should be stored outside of the
- # paths available to the HTTP server.
- #
- # Example:
- #
- # htgroup = WEBrick::HTTPAuth::Htgroup.new 'my_group_file'
- # htgroup.add 'superheroes', %w[spiderman batman]
- #
- # htgroup.members('superheroes').include? 'magneto' # => false
-
- class Htgroup
-
- ##
- # Open a group database at +path+
-
- def initialize(path)
- @path = path
- @mtime = Time.at(0)
- @group = Hash.new
- open(@path,"a").close unless File::exist?(@path)
- reload
- end
-
- ##
- # Reload groups from the database
-
- def reload
- if (mtime = File::mtime(@path)) > @mtime
- @group.clear
- open(@path){|io|
- while line = io.gets
- line.chomp!
- group, members = line.split(/:\s*/)
- @group[group] = members.split(/\s+/)
- end
- }
- @mtime = mtime
- end
- end
-
- ##
- # Flush the group database. If +output+ is given the database will be
- # written there instead of to the original path.
-
- def flush(output=nil)
- output ||= @path
- tmp = Tempfile.new("htgroup", File::dirname(output))
- begin
- @group.keys.sort.each{|group|
- tmp.puts(format("%s: %s", group, self.members(group).join(" ")))
- }
- tmp.close
- File::rename(tmp.path, output)
- rescue
- tmp.close(true)
- end
- end
-
- ##
- # Retrieve the list of members from +group+
-
- def members(group)
- reload
- @group[group] || []
- end
-
- ##
- # Add an Array of +members+ to +group+
-
- def add(group, members)
- @group[group] = members(group) | members
- end
- end
- end
-end
diff --git a/lib/webrick/httpauth/htpasswd.rb b/lib/webrick/httpauth/htpasswd.rb
deleted file mode 100644
index 8c7b09463b..0000000000
--- a/lib/webrick/httpauth/htpasswd.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-# frozen_string_literal: false
-#
-# httpauth/htpasswd -- Apache compatible htpasswd file
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
-
-require 'webrick/httpauth/userdb'
-require 'webrick/httpauth/basicauth'
-require 'tempfile'
-
-module WEBrick
- module HTTPAuth
-
- ##
- # Htpasswd accesses apache-compatible password files. Passwords are
- # matched to a realm where they are valid. For security, the path for a
- # password database should be stored outside of the paths available to the
- # HTTP server.
- #
- # Htpasswd is intended for use with WEBrick::HTTPAuth::BasicAuth.
- #
- # To create an Htpasswd database with a single user:
- #
- # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
- # htpasswd.set_passwd 'my realm', 'username', 'password'
- # htpasswd.flush
-
- class Htpasswd
- include UserDB
-
- ##
- # Open a password database at +path+
-
- def initialize(path)
- @path = path
- @mtime = Time.at(0)
- @passwd = Hash.new
- @auth_type = BasicAuth
- open(@path,"a").close unless File::exist?(@path)
- reload
- end
-
- ##
- # Reload passwords from the database
-
- def reload
- mtime = File::mtime(@path)
- if mtime > @mtime
- @passwd.clear
- open(@path){|io|
- while line = io.gets
- line.chomp!
- case line
- when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z!
- user, pass = line.split(":")
- when /:\$/, /:{SHA}/
- raise NotImplementedError,
- 'MD5, SHA1 .htpasswd file not supported'
- else
- raise StandardError, 'bad .htpasswd file'
- end
- @passwd[user] = pass
- end
- }
- @mtime = mtime
- end
- end
-
- ##
- # Flush the password database. If +output+ is given the database will
- # be written there instead of to the original path.
-
- def flush(output=nil)
- output ||= @path
- tmp = Tempfile.create("htpasswd", File::dirname(output))
- renamed = false
- begin
- each{|item| tmp.puts(item.join(":")) }
- tmp.close
- File::rename(tmp.path, output)
- renamed = true
- ensure
- tmp.close
- File.unlink(tmp.path) if !renamed
- end
- end
-
- ##
- # Retrieves a password from the database for +user+ in +realm+. If
- # +reload_db+ is true the database will be reloaded first.
-
- def get_passwd(realm, user, reload_db)
- reload() if reload_db
- @passwd[user]
- end
-
- ##
- # Sets a password in the database for +user+ in +realm+ to +pass+.
-
- def set_passwd(realm, user, pass)
- @passwd[user] = make_passwd(realm, user, pass)
- end
-
- ##
- # Removes a password from the database for +user+ in +realm+.
-
- def delete_passwd(realm, user)
- @passwd.delete(user)
- end
-
- ##
- # Iterate passwords in the database.
-
- def each # :yields: [user, password]
- @passwd.keys.sort.each{|user|
- yield([user, @passwd[user]])
- }
- end
- end
- end
-end
diff --git a/lib/webrick/httpproxy.rb b/lib/webrick/httpproxy.rb
deleted file mode 100644
index be5531fec0..0000000000
--- a/lib/webrick/httpproxy.rb
+++ /dev/null
@@ -1,338 +0,0 @@
-# frozen_string_literal: false
-#
-# httpproxy.rb -- HTTPProxy Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2002 GOTO Kentaro
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpproxy.rb,v 1.18 2003/03/08 18:58:10 gotoyuzo Exp $
-# $kNotwork: straw.rb,v 1.3 2002/02/12 15:13:07 gotoken Exp $
-
-require "webrick/httpserver"
-require "net/http"
-
-module WEBrick
-
- NullReader = Object.new # :nodoc:
- class << NullReader # :nodoc:
- def read(*args)
- nil
- end
- alias gets read
- end
-
- FakeProxyURI = Object.new # :nodoc:
- class << FakeProxyURI # :nodoc:
- def method_missing(meth, *args)
- if %w(scheme host port path query userinfo).member?(meth.to_s)
- return nil
- end
- super
- end
- end
-
- # :startdoc:
-
- ##
- # An HTTP Proxy server which proxies GET, HEAD and POST requests.
- #
- # To create a simple proxy server:
- #
- # require 'webrick'
- # require 'webrick/httpproxy'
- #
- # proxy = WEBrick::HTTPProxyServer.new Port: 8000
- #
- # trap 'INT' do proxy.shutdown end
- # trap 'TERM' do proxy.shutdown end
- #
- # proxy.start
- #
- # See ::new for proxy-specific configuration items.
- #
- # == Modifying proxied responses
- #
- # To modify content the proxy server returns use the +:ProxyContentHandler+
- # option:
- #
- # handler = proc do |req, res|
- # if res['content-type'] == 'text/plain' then
- # res.body << "\nThis content was proxied!\n"
- # end
- # end
- #
- # proxy =
- # WEBrick::HTTPProxyServer.new Port: 8000, ProxyContentHandler: handler
-
- class HTTPProxyServer < HTTPServer
-
- ##
- # Proxy server configurations. The proxy server handles the following
- # configuration items in addition to those supported by HTTPServer:
- #
- # :ProxyAuthProc:: Called with a request and response to authorize a
- # request
- # :ProxyVia:: Appended to the via header
- # :ProxyURI:: The proxy server's URI
- # :ProxyContentHandler:: Called with a request and response and allows
- # modification of the response
- # :ProxyTimeout:: Sets the proxy timeouts to 30 seconds for open and 60
- # seconds for read operations
-
- def initialize(config={}, default=Config::HTTP)
- super(config, default)
- c = @config
- @via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}"
- end
-
- # :stopdoc:
- def service(req, res)
- if req.request_method == "CONNECT"
- do_CONNECT(req, res)
- elsif req.unparsed_uri =~ %r!^http://!
- proxy_service(req, res)
- else
- super(req, res)
- end
- end
-
- def proxy_auth(req, res)
- if proc = @config[:ProxyAuthProc]
- proc.call(req, res)
- end
- req.header.delete("proxy-authorization")
- end
-
- def proxy_uri(req, res)
- # should return upstream proxy server's URI
- return @config[:ProxyURI]
- end
-
- def proxy_service(req, res)
- # Proxy Authentication
- proxy_auth(req, res)
-
- begin
- self.send("do_#{req.request_method}", req, res)
- rescue NoMethodError
- raise HTTPStatus::MethodNotAllowed,
- "unsupported method `#{req.request_method}'."
- rescue => err
- logger.debug("#{err.class}: #{err.message}")
- raise HTTPStatus::ServiceUnavailable, err.message
- end
-
- # Process contents
- if handler = @config[:ProxyContentHandler]
- handler.call(req, res)
- end
- end
-
- def do_CONNECT(req, res)
- # Proxy Authentication
- proxy_auth(req, res)
-
- ua = Thread.current[:WEBrickSocket] # User-Agent
- raise HTTPStatus::InternalServerError,
- "[BUG] cannot get socket" unless ua
-
- host, port = req.unparsed_uri.split(":", 2)
- # Proxy authentication for upstream proxy server
- if proxy = proxy_uri(req, res)
- proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0"
- if proxy.userinfo
- credentials = "Basic " + [proxy.userinfo].pack("m0")
- end
- host, port = proxy.host, proxy.port
- end
-
- begin
- @logger.debug("CONNECT: upstream proxy is `#{host}:#{port}'.")
- os = TCPSocket.new(host, port) # origin server
-
- if proxy
- @logger.debug("CONNECT: sending a Request-Line")
- os << proxy_request_line << CRLF
- @logger.debug("CONNECT: > #{proxy_request_line}")
- if credentials
- @logger.debug("CONNECT: sending credentials")
- os << "Proxy-Authorization: " << credentials << CRLF
- end
- os << CRLF
- proxy_status_line = os.gets(LF)
- @logger.debug("CONNECT: read Status-Line from the upstream server")
- @logger.debug("CONNECT: < #{proxy_status_line}")
- if %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line
- while line = os.gets(LF)
- break if /\A(#{CRLF}|#{LF})\z/om =~ line
- end
- else
- raise HTTPStatus::BadGateway
- end
- end
- @logger.debug("CONNECT #{host}:#{port}: succeeded")
- res.status = HTTPStatus::RC_OK
- rescue => ex
- @logger.debug("CONNECT #{host}:#{port}: failed `#{ex.message}'")
- res.set_error(ex)
- raise HTTPStatus::EOFError
- ensure
- if handler = @config[:ProxyContentHandler]
- handler.call(req, res)
- end
- res.send_response(ua)
- access_log(@config, req, res)
-
- # Should clear request-line not to send the response twice.
- # see: HTTPServer#run
- req.parse(NullReader) rescue nil
- end
-
- begin
- while fds = IO::select([ua, os])
- if fds[0].member?(ua)
- buf = ua.readpartial(1024);
- @logger.debug("CONNECT: #{buf.bytesize} byte from User-Agent")
- os.write(buf)
- elsif fds[0].member?(os)
- buf = os.readpartial(1024);
- @logger.debug("CONNECT: #{buf.bytesize} byte from #{host}:#{port}")
- ua.write(buf)
- end
- end
- rescue
- os.close
- @logger.debug("CONNECT #{host}:#{port}: closed")
- end
-
- raise HTTPStatus::EOFError
- end
-
- def do_GET(req, res)
- perform_proxy_request(req, res) do |http, path, header|
- http.get(path, header)
- end
- end
-
- def do_HEAD(req, res)
- perform_proxy_request(req, res) do |http, path, header|
- http.head(path, header)
- end
- end
-
- def do_POST(req, res)
- perform_proxy_request(req, res) do |http, path, header|
- http.post(path, req.body || "", header)
- end
- end
-
- def do_OPTIONS(req, res)
- res['allow'] = "GET,HEAD,POST,OPTIONS,CONNECT"
- end
-
- private
-
- # Some header fields should not be transferred.
- HopByHop = %w( connection keep-alive proxy-authenticate upgrade
- proxy-authorization te trailers transfer-encoding )
- ShouldNotTransfer = %w( set-cookie proxy-connection )
- def split_field(f) f ? f.split(/,\s+/).collect{|i| i.downcase } : [] end
-
- def choose_header(src, dst)
- connections = split_field(src['connection'])
- src.each{|key, value|
- key = key.downcase
- if HopByHop.member?(key) || # RFC2616: 13.5.1
- connections.member?(key) || # RFC2616: 14.10
- ShouldNotTransfer.member?(key) # pragmatics
- @logger.debug("choose_header: `#{key}: #{value}'")
- next
- end
- dst[key] = value
- }
- end
-
- # Net::HTTP is stupid about the multiple header fields.
- # Here is workaround:
- def set_cookie(src, dst)
- if str = src['set-cookie']
- cookies = []
- str.split(/,\s*/).each{|token|
- if /^[^=]+;/o =~ token
- cookies[-1] << ", " << token
- elsif /=/o =~ token
- cookies << token
- else
- cookies[-1] << ", " << token
- end
- }
- dst.cookies.replace(cookies)
- end
- end
-
- def set_via(h)
- if @config[:ProxyVia]
- if h['via']
- h['via'] << ", " << @via
- else
- h['via'] = @via
- end
- end
- end
-
- def setup_proxy_header(req, res)
- # Choose header fields to transfer
- header = Hash.new
- choose_header(req, header)
- set_via(header)
- return header
- end
-
- def setup_upstream_proxy_authentication(req, res, header)
- if upstream = proxy_uri(req, res)
- if upstream.userinfo
- header['proxy-authorization'] =
- "Basic " + [upstream.userinfo].pack("m0")
- end
- return upstream
- end
- return FakeProxyURI
- end
-
- def perform_proxy_request(req, res)
- uri = req.request_uri
- path = uri.path.dup
- path << "?" << uri.query if uri.query
- header = setup_proxy_header(req, res)
- upstream = setup_upstream_proxy_authentication(req, res, header)
- response = nil
-
- http = Net::HTTP.new(uri.host, uri.port, upstream.host, upstream.port)
- http.start do
- if @config[:ProxyTimeout]
- ################################## these issues are
- http.open_timeout = 30 # secs # necessary (maybe because
- http.read_timeout = 60 # secs # Ruby's bug, but why?)
- ##################################
- end
- response = yield(http, path, header)
- end
-
- # Persistent connection requirements are mysterious for me.
- # So I will close the connection in every response.
- res['proxy-connection'] = "close"
- res['connection'] = "close"
-
- # Convert Net::HTTP::HTTPResponse to WEBrick::HTTPResponse
- res.status = response.code.to_i
- choose_header(response, res)
- set_cookie(response, res)
- set_via(res)
- res.body = response.body
- end
-
- # :stopdoc:
- end
-end
diff --git a/lib/webrick/httprequest.rb b/lib/webrick/httprequest.rb
deleted file mode 100644
index 10cf72d288..0000000000
--- a/lib/webrick/httprequest.rb
+++ /dev/null
@@ -1,587 +0,0 @@
-# frozen_string_literal: false
-#
-# httprequest.rb -- HTTPRequest Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $
-
-require 'uri'
-require 'webrick/httpversion'
-require 'webrick/httpstatus'
-require 'webrick/httputils'
-require 'webrick/cookie'
-
-module WEBrick
-
- ##
- # An HTTP request. This is consumed by service and do_* methods in
- # WEBrick servlets
-
- class HTTPRequest
-
- BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ] # :nodoc:
-
- # :section: Request line
-
- ##
- # The complete request line such as:
- #
- # GET / HTTP/1.1
-
- attr_reader :request_line
-
- ##
- # The request method, GET, POST, PUT, etc.
-
- attr_reader :request_method
-
- ##
- # The unparsed URI of the request
-
- attr_reader :unparsed_uri
-
- ##
- # The HTTP version of the request
-
- attr_reader :http_version
-
- # :section: Request-URI
-
- ##
- # The parsed URI of the request
-
- attr_reader :request_uri
-
- ##
- # The request path
-
- attr_reader :path
-
- ##
- # The script name (CGI variable)
-
- attr_accessor :script_name
-
- ##
- # The path info (CGI variable)
-
- attr_accessor :path_info
-
- ##
- # The query from the URI of the request
-
- attr_accessor :query_string
-
- # :section: Header and entity body
-
- ##
- # The raw header of the request
-
- attr_reader :raw_header
-
- ##
- # The parsed header of the request
-
- attr_reader :header
-
- ##
- # The parsed request cookies
-
- attr_reader :cookies
-
- ##
- # The Accept header value
-
- attr_reader :accept
-
- ##
- # The Accept-Charset header value
-
- attr_reader :accept_charset
-
- ##
- # The Accept-Encoding header value
-
- attr_reader :accept_encoding
-
- ##
- # The Accept-Language header value
-
- attr_reader :accept_language
-
- # :section:
-
- ##
- # The remote user (CGI variable)
-
- attr_accessor :user
-
- ##
- # The socket address of the server
-
- attr_reader :addr
-
- ##
- # The socket address of the client
-
- attr_reader :peeraddr
-
- ##
- # Hash of request attributes
-
- attr_reader :attributes
-
- ##
- # Is this a keep-alive connection?
-
- attr_reader :keep_alive
-
- ##
- # The local time this request was received
-
- attr_reader :request_time
-
- ##
- # Creates a new HTTP request. WEBrick::Config::HTTP is the default
- # configuration.
-
- def initialize(config)
- @config = config
- @buffer_size = @config[:InputBufferSize]
- @logger = config[:Logger]
-
- @request_line = @request_method =
- @unparsed_uri = @http_version = nil
-
- @request_uri = @host = @port = @path = nil
- @script_name = @path_info = nil
- @query_string = nil
- @query = nil
- @form_data = nil
-
- @raw_header = Array.new
- @header = nil
- @cookies = []
- @accept = []
- @accept_charset = []
- @accept_encoding = []
- @accept_language = []
- @body = ""
-
- @addr = @peeraddr = nil
- @attributes = {}
- @user = nil
- @keep_alive = false
- @request_time = nil
-
- @remaining_size = nil
- @socket = nil
-
- @forwarded_proto = @forwarded_host = @forwarded_port =
- @forwarded_server = @forwarded_for = nil
- end
-
- ##
- # Parses a request from +socket+. This is called internally by
- # WEBrick::HTTPServer.
-
- def parse(socket=nil)
- @socket = socket
- begin
- @peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : []
- @addr = socket.respond_to?(:addr) ? socket.addr : []
- rescue Errno::ENOTCONN
- raise HTTPStatus::EOFError
- end
-
- read_request_line(socket)
- if @http_version.major > 0
- read_header(socket)
- @header['cookie'].each{|cookie|
- @cookies += Cookie::parse(cookie)
- }
- @accept = HTTPUtils.parse_qvalues(self['accept'])
- @accept_charset = HTTPUtils.parse_qvalues(self['accept-charset'])
- @accept_encoding = HTTPUtils.parse_qvalues(self['accept-encoding'])
- @accept_language = HTTPUtils.parse_qvalues(self['accept-language'])
- end
- return if @request_method == "CONNECT"
- return if @unparsed_uri == "*"
-
- begin
- setup_forwarded_info
- @request_uri = parse_uri(@unparsed_uri)
- @path = HTTPUtils::unescape(@request_uri.path)
- @path = HTTPUtils::normalize_path(@path)
- @host = @request_uri.host
- @port = @request_uri.port
- @query_string = @request_uri.query
- @script_name = ""
- @path_info = @path.dup
- rescue
- raise HTTPStatus::BadRequest, "bad URI `#{@unparsed_uri}'."
- end
-
- if /close/io =~ self["connection"]
- @keep_alive = false
- elsif /keep-alive/io =~ self["connection"]
- @keep_alive = true
- elsif @http_version < "1.1"
- @keep_alive = false
- else
- @keep_alive = true
- end
- end
-
- ##
- # Generate HTTP/1.1 100 continue response if the client expects it,
- # otherwise does nothing.
-
- def continue # :nodoc:
- if self['expect'] == '100-continue' && @config[:HTTPVersion] >= "1.1"
- @socket << "HTTP/#{@config[:HTTPVersion]} 100 continue#{CRLF}#{CRLF}"
- @header.delete('expect')
- end
- end
-
- ##
- # Returns the request body.
-
- def body(&block) # :yields: body_chunk
- block ||= Proc.new{|chunk| @body << chunk }
- read_body(@socket, block)
- @body.empty? ? nil : @body
- end
-
- ##
- # Request query as a Hash
-
- def query
- unless @query
- parse_query()
- end
- @query
- end
-
- ##
- # The content-length header
-
- def content_length
- return Integer(self['content-length'])
- end
-
- ##
- # The content-type header
-
- def content_type
- return self['content-type']
- end
-
- ##
- # Retrieves +header_name+
-
- def [](header_name)
- if @header
- value = @header[header_name.downcase]
- value.empty? ? nil : value.join(", ")
- end
- end
-
- ##
- # Iterates over the request headers
-
- def each
- if @header
- @header.each{|k, v|
- value = @header[k]
- yield(k, value.empty? ? nil : value.join(", "))
- }
- end
- end
-
- ##
- # The host this request is for
-
- def host
- return @forwarded_host || @host
- end
-
- ##
- # The port this request is for
-
- def port
- return @forwarded_port || @port
- end
-
- ##
- # The server name this request is for
-
- def server_name
- return @forwarded_server || @config[:ServerName]
- end
-
- ##
- # The client's IP address
-
- def remote_ip
- return self["client-ip"] || @forwarded_for || @peeraddr[3]
- end
-
- ##
- # Is this an SSL request?
-
- def ssl?
- return @request_uri.scheme == "https"
- end
-
- ##
- # Should the connection this request was made on be kept alive?
-
- def keep_alive?
- @keep_alive
- end
-
- def to_s # :nodoc:
- ret = @request_line.dup
- @raw_header.each{|line| ret << line }
- ret << CRLF
- ret << body if body
- ret
- end
-
- ##
- # Consumes any remaining body and updates keep-alive status
-
- def fixup() # :nodoc:
- begin
- body{|chunk| } # read remaining body
- rescue HTTPStatus::Error => ex
- @logger.error("HTTPRequest#fixup: #{ex.class} occurred.")
- @keep_alive = false
- rescue => ex
- @logger.error(ex)
- @keep_alive = false
- end
- end
-
- # This method provides the metavariables defined by the revision 3
- # of "The WWW Common Gateway Interface Version 1.1"
- # To browse the current document of CGI Version 1.1, see below:
- # http://tools.ietf.org/html/rfc3875
-
- def meta_vars
- meta = Hash.new
-
- cl = self["Content-Length"]
- ct = self["Content-Type"]
- meta["CONTENT_LENGTH"] = cl if cl.to_i > 0
- meta["CONTENT_TYPE"] = ct.dup if ct
- meta["GATEWAY_INTERFACE"] = "CGI/1.1"
- meta["PATH_INFO"] = @path_info ? @path_info.dup : ""
- #meta["PATH_TRANSLATED"] = nil # no plan to be provided
- meta["QUERY_STRING"] = @query_string ? @query_string.dup : ""
- meta["REMOTE_ADDR"] = @peeraddr[3]
- meta["REMOTE_HOST"] = @peeraddr[2]
- #meta["REMOTE_IDENT"] = nil # no plan to be provided
- meta["REMOTE_USER"] = @user
- meta["REQUEST_METHOD"] = @request_method.dup
- meta["REQUEST_URI"] = @request_uri.to_s
- meta["SCRIPT_NAME"] = @script_name.dup
- meta["SERVER_NAME"] = @host
- meta["SERVER_PORT"] = @port.to_s
- meta["SERVER_PROTOCOL"] = "HTTP/" + @config[:HTTPVersion].to_s
- meta["SERVER_SOFTWARE"] = @config[:ServerSoftware].dup
-
- self.each{|key, val|
- next if /^content-type$/i =~ key
- next if /^content-length$/i =~ key
- name = "HTTP_" + key
- name.gsub!(/-/o, "_")
- name.upcase!
- meta[name] = val
- }
-
- meta
- end
-
- private
-
- # :stopdoc:
-
- MAX_URI_LENGTH = 2083 # :nodoc:
-
- def read_request_line(socket)
- @request_line = read_line(socket, MAX_URI_LENGTH) if socket
- if @request_line.bytesize >= MAX_URI_LENGTH and @request_line[-1, 1] != LF
- raise HTTPStatus::RequestURITooLarge
- end
- @request_time = Time.now
- raise HTTPStatus::EOFError unless @request_line
- if /^(\S+)\s+(\S++)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line
- @request_method = $1
- @unparsed_uri = $2
- @http_version = HTTPVersion.new($3 ? $3 : "0.9")
- else
- rl = @request_line.sub(/\x0d?\x0a\z/o, '')
- raise HTTPStatus::BadRequest, "bad Request-Line `#{rl}'."
- end
- end
-
- def read_header(socket)
- if socket
- while line = read_line(socket)
- break if /\A(#{CRLF}|#{LF})\z/om =~ line
- @raw_header << line
- end
- end
- @header = HTTPUtils::parse_header(@raw_header.join)
- end
-
- def parse_uri(str, scheme="http")
- if @config[:Escape8bitURI]
- str = HTTPUtils::escape8bit(str)
- end
- str.sub!(%r{\A/+}o, '/')
- uri = URI::parse(str)
- return uri if uri.absolute?
- if @forwarded_host
- host, port = @forwarded_host, @forwarded_port
- elsif self["host"]
- pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/n
- host, port = *self['host'].scan(pattern)[0]
- elsif @addr.size > 0
- host, port = @addr[2], @addr[1]
- else
- host, port = @config[:ServerName], @config[:Port]
- end
- uri.scheme = @forwarded_proto || scheme
- uri.host = host
- uri.port = port ? port.to_i : nil
- return URI::parse(uri.to_s)
- end
-
- def read_body(socket, block)
- return unless socket
- if tc = self['transfer-encoding']
- case tc
- when /chunked/io then read_chunked(socket, block)
- else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
- end
- elsif self['content-length'] || @remaining_size
- @remaining_size ||= self['content-length'].to_i
- while @remaining_size > 0
- sz = [@buffer_size, @remaining_size].min
- break unless buf = read_data(socket, sz)
- @remaining_size -= buf.bytesize
- block.call(buf)
- end
- if @remaining_size > 0 && @socket.eof?
- raise HTTPStatus::BadRequest, "invalid body size."
- end
- elsif BODY_CONTAINABLE_METHODS.member?(@request_method)
- raise HTTPStatus::LengthRequired
- end
- return @body
- end
-
- def read_chunk_size(socket)
- line = read_line(socket)
- if /^([0-9a-fA-F]+)(?:;(\S+))?/ =~ line
- chunk_size = $1.hex
- chunk_ext = $2
- [ chunk_size, chunk_ext ]
- else
- raise HTTPStatus::BadRequest, "bad chunk `#{line}'."
- end
- end
-
- def read_chunked(socket, block)
- chunk_size, = read_chunk_size(socket)
- while chunk_size > 0
- data = read_data(socket, chunk_size) # read chunk-data
- if data.nil? || data.bytesize != chunk_size
- raise BadRequest, "bad chunk data size."
- end
- read_line(socket) # skip CRLF
- block.call(data)
- chunk_size, = read_chunk_size(socket)
- end
- read_header(socket) # trailer + CRLF
- @header.delete("transfer-encoding")
- @remaining_size = 0
- end
-
- def _read_data(io, method, *arg)
- begin
- WEBrick::Utils.timeout(@config[:RequestTimeout]){
- return io.__send__(method, *arg)
- }
- rescue Errno::ECONNRESET
- return nil
- rescue Timeout::Error
- raise HTTPStatus::RequestTimeout
- end
- end
-
- def read_line(io, size=4096)
- _read_data(io, :gets, LF, size)
- end
-
- def read_data(io, size)
- _read_data(io, :read, size)
- end
-
- def parse_query()
- begin
- if @request_method == "GET" || @request_method == "HEAD"
- @query = HTTPUtils::parse_query(@query_string)
- elsif self['content-type'] =~ /^application\/x-www-form-urlencoded/
- @query = HTTPUtils::parse_query(body)
- elsif self['content-type'] =~ /^multipart\/form-data; boundary=(.+)/
- boundary = HTTPUtils::dequote($1)
- @query = HTTPUtils::parse_form_data(body, boundary)
- else
- @query = Hash.new
- end
- rescue => ex
- raise HTTPStatus::BadRequest, ex.message
- end
- end
-
- PrivateNetworkRegexp = /
- ^unknown$|
- ^((::ffff:)?127.0.0.1|::1)$|
- ^(::ffff:)?(10|172\.(1[6-9]|2[0-9]|3[01])|192\.168)\.
- /ixo
-
- # It's said that all X-Forwarded-* headers will contain more than one
- # (comma-separated) value if the original request already contained one of
- # these headers. Since we could use these values as Host header, we choose
- # the initial(first) value. (apr_table_mergen() adds new value after the
- # existing value with ", " prefix)
- def setup_forwarded_info
- if @forwarded_server = self["x-forwarded-server"]
- @forwarded_server = @forwarded_server.split(",", 2).first
- end
- if @forwarded_proto = self["x-forwarded-proto"]
- @forwarded_proto = @forwarded_proto.split(",", 2).first
- end
- if host_port = self["x-forwarded-host"]
- host_port = host_port.split(",", 2).first
- @forwarded_host, tmp = host_port.split(":", 2)
- @forwarded_port = (tmp || (@forwarded_proto == "https" ? 443 : 80)).to_i
- end
- if addrs = self["x-forwarded-for"]
- addrs = addrs.split(",").collect(&:strip)
- addrs.reject!{|ip| PrivateNetworkRegexp =~ ip }
- @forwarded_for = addrs.first
- end
- end
-
- # :startdoc:
- end
-end
diff --git a/lib/webrick/httpresponse.rb b/lib/webrick/httpresponse.rb
deleted file mode 100644
index eae14d6597..0000000000
--- a/lib/webrick/httpresponse.rb
+++ /dev/null
@@ -1,471 +0,0 @@
-# frozen_string_literal: false
-#
-# httpresponse.rb -- HTTPResponse Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpresponse.rb,v 1.45 2003/07/11 11:02:25 gotoyuzo Exp $
-
-require 'time'
-require 'webrick/httpversion'
-require 'webrick/htmlutils'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-
-module WEBrick
- ##
- # An HTTP response. This is filled in by the service or do_* methods of a
- # WEBrick HTTP Servlet.
-
- class HTTPResponse
-
- ##
- # HTTP Response version
-
- attr_reader :http_version
-
- ##
- # Response status code (200)
-
- attr_reader :status
-
- ##
- # Response header
-
- attr_reader :header
-
- ##
- # Response cookies
-
- attr_reader :cookies
-
- ##
- # Response reason phrase ("OK")
-
- attr_accessor :reason_phrase
-
- ##
- # Body may be a String or IO-like object that responds to #read and
- # #readpartial.
-
- attr_accessor :body
-
- ##
- # Request method for this response
-
- attr_accessor :request_method
-
- ##
- # Request URI for this response
-
- attr_accessor :request_uri
-
- ##
- # Request HTTP version for this response
-
- attr_accessor :request_http_version
-
- ##
- # Filename of the static file in this response. Only used by the
- # FileHandler servlet.
-
- attr_accessor :filename
-
- ##
- # Is this a keep-alive response?
-
- attr_accessor :keep_alive
-
- ##
- # Configuration for this response
-
- attr_reader :config
-
- ##
- # Bytes sent in this response
-
- attr_reader :sent_size
-
- ##
- # Creates a new HTTP response object. WEBrick::Config::HTTP is the
- # default configuration.
-
- def initialize(config)
- @config = config
- @buffer_size = config[:OutputBufferSize]
- @logger = config[:Logger]
- @header = Hash.new
- @status = HTTPStatus::RC_OK
- @reason_phrase = nil
- @http_version = HTTPVersion::convert(@config[:HTTPVersion])
- @body = ''
- @keep_alive = true
- @cookies = []
- @request_method = nil
- @request_uri = nil
- @request_http_version = @http_version # temporary
- @chunked = false
- @filename = nil
- @sent_size = 0
- end
-
- ##
- # The response's HTTP status line
-
- def status_line
- "HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
- end
-
- ##
- # Sets the response's status to the +status+ code
-
- def status=(status)
- @status = status
- @reason_phrase = HTTPStatus::reason_phrase(status)
- end
-
- ##
- # Retrieves the response header +field+
-
- def [](field)
- @header[field.downcase]
- end
-
- ##
- # Sets the response header +field+ to +value+
-
- def []=(field, value)
- @header[field.downcase] = value.to_s
- end
-
- ##
- # The content-length header
-
- def content_length
- if len = self['content-length']
- return Integer(len)
- end
- end
-
- ##
- # Sets the content-length header to +len+
-
- def content_length=(len)
- self['content-length'] = len.to_s
- end
-
- ##
- # The content-type header
-
- def content_type
- self['content-type']
- end
-
- ##
- # Sets the content-type header to +type+
-
- def content_type=(type)
- self['content-type'] = type
- end
-
- ##
- # Iterates over each header in the response
-
- def each
- @header.each{|field, value| yield(field, value) }
- end
-
- ##
- # Will this response body be returned using chunked transfer-encoding?
-
- def chunked?
- @chunked
- end
-
- ##
- # Enables chunked transfer encoding.
-
- def chunked=(val)
- @chunked = val ? true : false
- end
-
- ##
- # Will this response's connection be kept alive?
-
- def keep_alive?
- @keep_alive
- end
-
- ##
- # Sends the response on +socket+
-
- def send_response(socket) # :nodoc:
- begin
- setup_header()
- send_header(socket)
- send_body(socket)
- rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex
- @logger.debug(ex)
- @keep_alive = false
- rescue Exception => ex
- @logger.error(ex)
- @keep_alive = false
- end
- end
-
- ##
- # Sets up the headers for sending
-
- def setup_header() # :nodoc:
- @reason_phrase ||= HTTPStatus::reason_phrase(@status)
- @header['server'] ||= @config[:ServerSoftware]
- @header['date'] ||= Time.now.httpdate
-
- # HTTP/0.9 features
- if @request_http_version < "1.0"
- @http_version = HTTPVersion.new("0.9")
- @keep_alive = false
- end
-
- # HTTP/1.0 features
- if @request_http_version < "1.1"
- if chunked?
- @chunked = false
- ver = @request_http_version.to_s
- msg = "chunked is set for an HTTP/#{ver} request. (ignored)"
- @logger.warn(msg)
- end
- end
-
- # Determine the message length (RFC2616 -- 4.4 Message Length)
- if @status == 304 || @status == 204 || HTTPStatus::info?(@status)
- @header.delete('content-length')
- @body = ""
- elsif chunked?
- @header["transfer-encoding"] = "chunked"
- @header.delete('content-length')
- elsif %r{^multipart/byteranges} =~ @header['content-type']
- @header.delete('content-length')
- elsif @header['content-length'].nil?
- unless @body.is_a?(IO)
- @header['content-length'] = @body ? @body.bytesize : 0
- end
- end
-
- # Keep-Alive connection.
- if @header['connection'] == "close"
- @keep_alive = false
- elsif keep_alive?
- if chunked? || @header['content-length'] || @status == 304 || @status == 204 || HTTPStatus.info?(@status)
- @header['connection'] = "Keep-Alive"
- else
- msg = "Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true"
- @logger.warn(msg)
- @header['connection'] = "close"
- @keep_alive = false
- end
- else
- @header['connection'] = "close"
- end
-
- # Location is a single absoluteURI.
- if location = @header['location']
- if @request_uri
- @header['location'] = @request_uri.merge(location)
- end
- end
- end
-
- ##
- # Sends the headers on +socket+
-
- def send_header(socket) # :nodoc:
- if @http_version.major > 0
- data = status_line()
- @header.each{|key, value|
- tmp = key.gsub(/\bwww|^te$|\b\w/){ $&.upcase }
- data << "#{tmp}: #{value}" << CRLF
- }
- @cookies.each{|cookie|
- data << "Set-Cookie: " << cookie.to_s << CRLF
- }
- data << CRLF
- _write_data(socket, data)
- end
- end
-
- ##
- # Sends the body on +socket+
-
- def send_body(socket) # :nodoc:
- if @body.respond_to? :readpartial then
- send_body_io(socket)
- else
- send_body_string(socket)
- end
- end
-
- def to_s # :nodoc:
- ret = ""
- send_response(ret)
- ret
- end
-
- ##
- # Redirects to +url+ with a WEBrick::HTTPStatus::Redirect +status+.
- #
- # Example:
- #
- # res.set_redirect WEBrick::HTTPStatus::TemporaryRedirect
-
- def set_redirect(status, url)
- @body = "<HTML><A HREF=\"#{url}\">#{url}</A>.</HTML>\n"
- @header['location'] = url.to_s
- raise status
- end
-
- ##
- # Creates an error page for exception +ex+ with an optional +backtrace+
-
- def set_error(ex, backtrace=false)
- case ex
- when HTTPStatus::Status
- @keep_alive = false if HTTPStatus::error?(ex.code)
- self.status = ex.code
- else
- @keep_alive = false
- self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
- end
- @header['content-type'] = "text/html; charset=ISO-8859-1"
-
- if respond_to?(:create_error_page)
- create_error_page()
- return
- end
-
- if @request_uri
- host, port = @request_uri.host, @request_uri.port
- else
- host, port = @config[:ServerName], @config[:Port]
- end
-
- error_body(backtrace, ex, host, port)
- end
-
- private
-
- # :stopdoc:
-
- def error_body(backtrace, ex, host, port)
- @body = ''
- @body << <<-_end_of_html_
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<HTML>
- <HEAD><TITLE>#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>
- <BODY>
- <H1>#{HTMLUtils::escape(@reason_phrase)}</H1>
- #{HTMLUtils::escape(ex.message)}
- <HR>
- _end_of_html_
-
- if backtrace && $DEBUG
- @body << "backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' "
- @body << "#{HTMLUtils::escape(ex.message)}"
- @body << "<PRE>"
- ex.backtrace.each{|line| @body << "\t#{line}\n"}
- @body << "</PRE><HR>"
- end
-
- @body << <<-_end_of_html_
- <ADDRESS>
- #{HTMLUtils::escape(@config[:ServerSoftware])} at
- #{host}:#{port}
- </ADDRESS>
- </BODY>
-</HTML>
- _end_of_html_
- end
-
- def send_body_io(socket)
- begin
- if @request_method == "HEAD"
- # do nothing
- elsif chunked?
- begin
- buf = ''
- data = ''
- while true
- @body.readpartial( @buffer_size, buf ) # there is no need to clear buf?
- data << format("%x", buf.bytesize) << CRLF
- data << buf << CRLF
- _write_data(socket, data)
- data.clear
- @sent_size += buf.bytesize
- end
- rescue EOFError # do nothing
- end
- _write_data(socket, "0#{CRLF}#{CRLF}")
- else
- size = @header['content-length'].to_i
- _send_file(socket, @body, 0, size)
- @sent_size = size
- end
- ensure
- @body.close
- end
- end
-
- def send_body_string(socket)
- if @request_method == "HEAD"
- # do nothing
- elsif chunked?
- body ? @body.bytesize : 0
- while buf = @body[@sent_size, @buffer_size]
- break if buf.empty?
- data = ""
- data << format("%x", buf.bytesize) << CRLF
- data << buf << CRLF
- _write_data(socket, data)
- @sent_size += buf.bytesize
- end
- _write_data(socket, "0#{CRLF}#{CRLF}")
- else
- if @body && @body.bytesize > 0
- _write_data(socket, @body)
- @sent_size = @body.bytesize
- end
- end
- end
-
- def _send_file(output, input, offset, size)
- while offset > 0
- sz = @buffer_size < size ? @buffer_size : size
- buf = input.read(sz)
- offset -= buf.bytesize
- end
-
- if size == 0
- while buf = input.read(@buffer_size)
- _write_data(output, buf)
- end
- else
- while size > 0
- sz = @buffer_size < size ? @buffer_size : size
- buf = input.read(sz)
- _write_data(output, buf)
- size -= buf.bytesize
- end
- end
- end
-
- def _write_data(socket, data)
- socket << data
- end
-
- # :startdoc:
- end
-
-end
diff --git a/lib/webrick/https.rb b/lib/webrick/https.rb
deleted file mode 100644
index 4826654d3a..0000000000
--- a/lib/webrick/https.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-# frozen_string_literal: false
-#
-# https.rb -- SSL/TLS enhancement for HTTPServer
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $
-
-require 'webrick/ssl'
-require 'webrick/httpserver'
-
-module WEBrick
- module Config
- HTTP.update(SSL)
- end
-
- ##
- #--
- # Adds SSL functionality to WEBrick::HTTPRequest
-
- class HTTPRequest
-
- ##
- # HTTP request SSL cipher
-
- attr_reader :cipher
-
- ##
- # HTTP request server certificate
-
- attr_reader :server_cert
-
- ##
- # HTTP request client certificate
-
- attr_reader :client_cert
-
- # :stopdoc:
-
- alias orig_parse parse
-
- def parse(socket=nil)
- if socket.respond_to?(:cert)
- @server_cert = socket.cert || @config[:SSLCertificate]
- @client_cert = socket.peer_cert
- @client_cert_chain = socket.peer_cert_chain
- @cipher = socket.cipher
- end
- orig_parse(socket)
- end
-
- alias orig_parse_uri parse_uri
-
- def parse_uri(str, scheme="https")
- if server_cert
- return orig_parse_uri(str, scheme)
- end
- return orig_parse_uri(str)
- end
- private :parse_uri
-
- alias orig_meta_vars meta_vars
-
- def meta_vars
- meta = orig_meta_vars
- if server_cert
- meta["HTTPS"] = "on"
- meta["SSL_SERVER_CERT"] = @server_cert.to_pem
- meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : ""
- if @client_cert_chain
- @client_cert_chain.each_with_index{|cert, i|
- meta["SSL_CLIENT_CERT_CHAIN_#{i}"] = cert.to_pem
- }
- end
- meta["SSL_CIPHER"] = @cipher[0]
- meta["SSL_PROTOCOL"] = @cipher[1]
- meta["SSL_CIPHER_USEKEYSIZE"] = @cipher[2].to_s
- meta["SSL_CIPHER_ALGKEYSIZE"] = @cipher[3].to_s
- end
- meta
- end
-
- # :startdoc:
- end
-
- ##
- #--
- # Fake WEBrick::HTTPRequest for lookup_server
-
- class SNIRequest
-
- ##
- # The SNI hostname
-
- attr_reader :host
-
- ##
- # The socket address of the server
-
- attr_reader :addr
-
- ##
- # The port this request is for
-
- attr_reader :port
-
- ##
- # Creates a new SNIRequest.
-
- def initialize(sslsocket, hostname)
- @host = hostname
- @addr = sslsocket.addr
- @port = @addr[1]
- end
- end
-
-
- ##
- #--
- # Adds SSL functionality to WEBrick::HTTPServer
-
- class HTTPServer < ::WEBrick::GenericServer
- ##
- # ServerNameIndication callback
-
- def ssl_servername_callback(sslsocket, hostname = nil)
- req = SNIRequest.new(sslsocket, hostname)
- server = lookup_server(req)
- server ? server.ssl_context : nil
- end
-
- # :stopdoc:
-
- ##
- # Check whether +server+ is also SSL server.
- # Also +server+'s SSL context will be created.
-
- alias orig_virtual_host virtual_host
-
- def virtual_host(server)
- if @config[:SSLEnable] && !server.ssl_context
- raise ArgumentError, "virtual host must set SSLEnable to true"
- end
- orig_virtual_host(server)
- end
-
- # :startdoc:
- end
-end
diff --git a/lib/webrick/httpserver.rb b/lib/webrick/httpserver.rb
deleted file mode 100644
index b27f2311bd..0000000000
--- a/lib/webrick/httpserver.rb
+++ /dev/null
@@ -1,280 +0,0 @@
-# frozen_string_literal: false
-#
-# httpserver.rb -- HTTPServer Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $
-
-require 'io/wait'
-require 'webrick/server'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-require 'webrick/httprequest'
-require 'webrick/httpresponse'
-require 'webrick/httpservlet'
-require 'webrick/accesslog'
-
-module WEBrick
- class HTTPServerError < ServerError; end
-
- ##
- # An HTTP Server
-
- class HTTPServer < ::WEBrick::GenericServer
- ##
- # Creates a new HTTP server according to +config+
- #
- # An HTTP server uses the following attributes:
- #
- # :AccessLog:: An array of access logs. See WEBrick::AccessLog
- # :BindAddress:: Local address for the server to bind to
- # :DocumentRoot:: Root path to serve files from
- # :DocumentRootOptions:: Options for the default HTTPServlet::FileHandler
- # :HTTPVersion:: The HTTP version of this server
- # :Port:: Port to listen on
- # :RequestCallback:: Called with a request and response before each
- # request is serviced.
- # :RequestTimeout:: Maximum time to wait between requests
- # :ServerAlias:: Array of alternate names for this server for virtual
- # hosting
- # :ServerName:: Name for this server for virtual hosting
-
- def initialize(config={}, default=Config::HTTP)
- super(config, default)
- @http_version = HTTPVersion::convert(@config[:HTTPVersion])
-
- @mount_tab = MountTable.new
- if @config[:DocumentRoot]
- mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
- @config[:DocumentRootOptions])
- end
-
- unless @config[:AccessLog]
- @config[:AccessLog] = [
- [ $stderr, AccessLog::COMMON_LOG_FORMAT ],
- [ $stderr, AccessLog::REFERER_LOG_FORMAT ]
- ]
- end
-
- @virtual_hosts = Array.new
- end
-
- ##
- # Processes requests on +sock+
-
- def run(sock)
- while true
- res = HTTPResponse.new(@config)
- req = HTTPRequest.new(@config)
- server = self
- begin
- timeout = @config[:RequestTimeout]
- while timeout > 0
- break if sock.to_io.wait_readable(0.5)
- break if @status != :Running
- timeout -= 0.5
- end
- raise HTTPStatus::EOFError if timeout <= 0 || @status != :Running
- raise HTTPStatus::EOFError if sock.eof?
- req.parse(sock)
- res.request_method = req.request_method
- res.request_uri = req.request_uri
- res.request_http_version = req.http_version
- res.keep_alive = req.keep_alive?
- server = lookup_server(req) || self
- if callback = server[:RequestCallback]
- callback.call(req, res)
- elsif callback = server[:RequestHandler]
- msg = ":RequestHandler is deprecated, please use :RequestCallback"
- @logger.warn(msg)
- callback.call(req, res)
- end
- server.service(req, res)
- rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
- res.set_error(ex)
- rescue HTTPStatus::Error => ex
- @logger.error(ex.message)
- res.set_error(ex)
- rescue HTTPStatus::Status => ex
- res.status = ex.code
- rescue StandardError => ex
- @logger.error(ex)
- res.set_error(ex, true)
- ensure
- if req.request_line
- if req.keep_alive? && res.keep_alive?
- req.fixup()
- end
- res.send_response(sock)
- server.access_log(@config, req, res)
- end
- end
- break if @http_version < "1.1"
- break unless req.keep_alive?
- break unless res.keep_alive?
- end
- end
-
- ##
- # Services +req+ and fills in +res+
-
- def service(req, res)
- if req.unparsed_uri == "*"
- if req.request_method == "OPTIONS"
- do_OPTIONS(req, res)
- raise HTTPStatus::OK
- end
- raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
- end
-
- servlet, options, script_name, path_info = search_servlet(req.path)
- raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
- req.script_name = script_name
- req.path_info = path_info
- si = servlet.get_instance(self, *options)
- @logger.debug(format("%s is invoked.", si.class.name))
- si.service(req, res)
- end
-
- ##
- # The default OPTIONS request handler says GET, HEAD, POST and OPTIONS
- # requests are allowed.
-
- def do_OPTIONS(req, res)
- res["allow"] = "GET,HEAD,POST,OPTIONS"
- end
-
- ##
- # Mounts +servlet+ on +dir+ passing +options+ to the servlet at creation
- # time
-
- def mount(dir, servlet, *options)
- @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
- @mount_tab[dir] = [ servlet, options ]
- end
-
- ##
- # Mounts +proc+ or +block+ on +dir+ and calls it with a
- # WEBrick::HTTPRequest and WEBrick::HTTPResponse
-
- def mount_proc(dir, proc=nil, &block)
- proc ||= block
- raise HTTPServerError, "must pass a proc or block" unless proc
- mount(dir, HTTPServlet::ProcHandler.new(proc))
- end
-
- ##
- # Unmounts +dir+
-
- def unmount(dir)
- @logger.debug(sprintf("unmount %s.", dir))
- @mount_tab.delete(dir)
- end
- alias umount unmount
-
- ##
- # Finds a servlet for +path+
-
- def search_servlet(path)
- script_name, path_info = @mount_tab.scan(path)
- servlet, options = @mount_tab[script_name]
- if servlet
- [ servlet, options, script_name, path_info ]
- end
- end
-
- ##
- # Adds +server+ as a virtual host.
-
- def virtual_host(server)
- @virtual_hosts << server
- @virtual_hosts = @virtual_hosts.sort_by{|s|
- num = 0
- num -= 4 if s[:BindAddress]
- num -= 2 if s[:Port]
- num -= 1 if s[:ServerName]
- num
- }
- end
-
- ##
- # Finds the appropriate virtual host to handle +req+
-
- def lookup_server(req)
- @virtual_hosts.find{|s|
- (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
- (s[:Port].nil? || req.port == s[:Port]) &&
- ((s[:ServerName].nil? || req.host == s[:ServerName]) ||
- (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
- }
- end
-
- ##
- # Logs +req+ and +res+ in the access logs. +config+ is used for the
- # server name.
-
- def access_log(config, req, res)
- param = AccessLog::setup_params(config, req, res)
- @config[:AccessLog].each{|logger, fmt|
- logger << AccessLog::format(fmt+"\n", param)
- }
- end
-
- ##
- # Mount table for the path a servlet is mounted on in the directory space
- # of the server. Users of WEBrick can only access this indirectly via
- # WEBrick::HTTPServer#mount, WEBrick::HTTPServer#unmount and
- # WEBrick::HTTPServer#search_servlet
-
- class MountTable # :nodoc:
- def initialize
- @tab = Hash.new
- compile
- end
-
- def [](dir)
- dir = normalize(dir)
- @tab[dir]
- end
-
- def []=(dir, val)
- dir = normalize(dir)
- @tab[dir] = val
- compile
- val
- end
-
- def delete(dir)
- dir = normalize(dir)
- res = @tab.delete(dir)
- compile
- res
- end
-
- def scan(path)
- @scanner =~ path
- [ $&, $' ]
- end
-
- private
-
- def compile
- k = @tab.keys
- k.sort!
- k.reverse!
- k.collect!{|path| Regexp.escape(path) }
- @scanner = Regexp.new("^(" + k.join("|") +")(?=/|$)")
- end
-
- def normalize(dir)
- ret = dir ? dir.dup : ""
- ret.sub!(%r|/+$|, "")
- ret
- end
- end
- end
-end
diff --git a/lib/webrick/httpservlet.rb b/lib/webrick/httpservlet.rb
deleted file mode 100644
index 1ee04ec86f..0000000000
--- a/lib/webrick/httpservlet.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: false
-#
-# httpservlet.rb -- HTTPServlet Utility File
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $
-
-require 'webrick/httpservlet/abstract'
-require 'webrick/httpservlet/filehandler'
-require 'webrick/httpservlet/cgihandler'
-require 'webrick/httpservlet/erbhandler'
-require 'webrick/httpservlet/prochandler'
-
-module WEBrick
- module HTTPServlet
- FileHandler.add_handler("cgi", CGIHandler)
- FileHandler.add_handler("rhtml", ERBHandler)
- end
-end
diff --git a/lib/webrick/httpservlet/abstract.rb b/lib/webrick/httpservlet/abstract.rb
deleted file mode 100644
index fc4cd2275a..0000000000
--- a/lib/webrick/httpservlet/abstract.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-# frozen_string_literal: false
-#
-# httpservlet.rb -- HTTPServlet Module
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $
-
-require 'webrick/htmlutils'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-
-module WEBrick
- module HTTPServlet
- class HTTPServletError < StandardError; end
-
- ##
- # AbstractServlet allows HTTP server modules to be reused across multiple
- # servers and allows encapsulation of functionality.
- #
- # By default a servlet will respond to GET, HEAD (through an alias to GET)
- # and OPTIONS requests.
- #
- # By default a new servlet is initialized for every request. A servlet
- # instance can be reused by overriding ::get_instance in the
- # AbstractServlet subclass.
- #
- # == A Simple Servlet
- #
- # class Simple < WEBrick::HTTPServlet::AbstractServlet
- # def do_GET request, response
- # status, content_type, body = do_stuff_with request
- #
- # response.status = status
- # response['Content-Type'] = content_type
- # response.body = body
- # end
- #
- # def do_stuff_with request
- # return 200, 'text/plain', 'you got a page'
- # end
- # end
- #
- # This servlet can be mounted on a server at a given path:
- #
- # server.mount '/simple', Simple
- #
- # == Servlet Configuration
- #
- # Servlets can be configured via initialize. The first argument is the
- # HTTP server the servlet is being initialized for.
- #
- # class Configurable < Simple
- # def initialize server, color, size
- # super server
- # @color = color
- # @size = size
- # end
- #
- # def do_stuff_with request
- # content = "<p " \
- # %q{style="color: #{@color}; font-size: #{@size}"} \
- # ">Hello, World!"
- #
- # return 200, "text/html", content
- # end
- # end
- #
- # This servlet must be provided two arguments at mount time:
- #
- # server.mount '/configurable', Configurable, 'red', '2em'
-
- class AbstractServlet
-
- ##
- # Factory for servlet instances that will handle a request from +server+
- # using +options+ from the mount point. By default a new servlet
- # instance is created for every call.
-
- def self.get_instance(server, *options)
- self.new(server, *options)
- end
-
- ##
- # Initializes a new servlet for +server+ using +options+ which are
- # stored as-is in +@options+. +@logger+ is also provided.
-
- def initialize(server, *options)
- @server = @config = server
- @logger = @server[:Logger]
- @options = options
- end
-
- ##
- # Dispatches to a +do_+ method based on +req+ if such a method is
- # available. (+do_GET+ for a GET request). Raises a MethodNotAllowed
- # exception if the method is not implemented.
-
- def service(req, res)
- method_name = "do_" + req.request_method.gsub(/-/, "_")
- if respond_to?(method_name)
- __send__(method_name, req, res)
- else
- raise HTTPStatus::MethodNotAllowed,
- "unsupported method `#{req.request_method}'."
- end
- end
-
- ##
- # Raises a NotFound exception
-
- def do_GET(req, res)
- raise HTTPStatus::NotFound, "not found."
- end
-
- ##
- # Dispatches to do_GET
-
- def do_HEAD(req, res)
- do_GET(req, res)
- end
-
- ##
- # Returns the allowed HTTP request methods
-
- def do_OPTIONS(req, res)
- m = self.methods.grep(/\Ado_([A-Z]+)\z/) {$1}
- m.sort!
- res["allow"] = m.join(",")
- end
-
- private
-
- ##
- # Redirects to a path ending in /
-
- def redirect_to_directory_uri(req, res)
- if req.path[-1] != ?/
- location = WEBrick::HTTPUtils.escape_path(req.path + "/")
- if req.query_string && req.query_string.bytesize > 0
- location << "?" << req.query_string
- end
- res.set_redirect(HTTPStatus::MovedPermanently, location)
- end
- end
- end
-
- end
-end
diff --git a/lib/webrick/httpservlet/cgi_runner.rb b/lib/webrick/httpservlet/cgi_runner.rb
deleted file mode 100644
index 597f48936b..0000000000
--- a/lib/webrick/httpservlet/cgi_runner.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: false
-#
-# cgi_runner.rb -- CGI launcher.
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $
-
-def sysread(io, size)
- buf = ""
- while size > 0
- tmp = io.sysread(size)
- buf << tmp
- size -= tmp.bytesize
- end
- return buf
-end
-
-STDIN.binmode
-
-len = sysread(STDIN, 8).to_i
-out = sysread(STDIN, len)
-STDOUT.reopen(open(out, "w"))
-
-len = sysread(STDIN, 8).to_i
-err = sysread(STDIN, len)
-STDERR.reopen(open(err, "w"))
-
-len = sysread(STDIN, 8).to_i
-dump = sysread(STDIN, len)
-hash = Marshal.restore(dump)
-ENV.keys.each{|name| ENV.delete(name) }
-hash.each{|k, v| ENV[k] = v if v }
-
-dir = File::dirname(ENV["SCRIPT_FILENAME"])
-Dir::chdir dir
-
-if ARGV[0]
- argv = ARGV.dup
- argv << ENV["SCRIPT_FILENAME"]
- exec(*argv)
- # NOTREACHED
-end
-exec ENV["SCRIPT_FILENAME"]
diff --git a/lib/webrick/httpservlet/cgihandler.rb b/lib/webrick/httpservlet/cgihandler.rb
deleted file mode 100644
index ba6b0b6032..0000000000
--- a/lib/webrick/httpservlet/cgihandler.rb
+++ /dev/null
@@ -1,122 +0,0 @@
-# frozen_string_literal: false
-#
-# cgihandler.rb -- CGIHandler Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $
-
-require 'rbconfig'
-require 'tempfile'
-require 'webrick/config'
-require 'webrick/httpservlet/abstract'
-
-module WEBrick
- module HTTPServlet
-
- ##
- # Servlet for handling CGI scripts
- #
- # Example:
- #
- # server.mount('/cgi/my_script', WEBrick::HTTPServlet::CGIHandler,
- # '/path/to/my_script')
-
- class CGIHandler < AbstractServlet
- Ruby = RbConfig.ruby # :nodoc:
- CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\"" # :nodoc:
-
- ##
- # Creates a new CGI script servlet for the script at +name+
-
- def initialize(server, name)
- super(server, name)
- @script_filename = name
- @tempdir = server[:TempDir]
- @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
- end
-
- # :stopdoc:
-
- def do_GET(req, res)
- cgi_in = IO::popen(@cgicmd, "wb")
- cgi_out = Tempfile.new("webrick.cgiout.", @tempdir, mode: IO::BINARY)
- cgi_out.set_encoding("ASCII-8BIT")
- cgi_err = Tempfile.new("webrick.cgierr.", @tempdir, mode: IO::BINARY)
- cgi_err.set_encoding("ASCII-8BIT")
- begin
- cgi_in.sync = true
- meta = req.meta_vars
- meta["SCRIPT_FILENAME"] = @script_filename
- meta["PATH"] = @config[:CGIPathEnv]
- meta.delete("HTTP_PROXY")
- if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
- meta["SystemRoot"] = ENV["SystemRoot"]
- end
- dump = Marshal.dump(meta)
-
- cgi_in.write("%8d" % cgi_out.path.bytesize)
- cgi_in.write(cgi_out.path)
- cgi_in.write("%8d" % cgi_err.path.bytesize)
- cgi_in.write(cgi_err.path)
- cgi_in.write("%8d" % dump.bytesize)
- cgi_in.write(dump)
-
- if req.body and req.body.bytesize > 0
- cgi_in.write(req.body)
- end
- ensure
- cgi_in.close
- status = $?.exitstatus
- sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
- data = cgi_out.read
- cgi_out.close(true)
- if errmsg = cgi_err.read
- if errmsg.bytesize > 0
- @logger.error("CGIHandler: #{@script_filename}:\n" + errmsg)
- end
- end
- cgi_err.close(true)
- end
-
- if status != 0
- @logger.error("CGIHandler: #{@script_filename} exit with #{status}")
- end
-
- data = "" unless data
- raw_header, body = data.split(/^[\xd\xa]+/, 2)
- raise HTTPStatus::InternalServerError,
- "Premature end of script headers: #{@script_filename}" if body.nil?
-
- begin
- header = HTTPUtils::parse_header(raw_header)
- if /^(\d+)/ =~ header['status'][0]
- res.status = $1.to_i
- header.delete('status')
- end
- if header.has_key?('location')
- # RFC 3875 6.2.3, 6.2.4
- res.status = 302 unless (300...400) === res.status
- end
- if header.has_key?('set-cookie')
- header['set-cookie'].each{|k|
- res.cookies << Cookie.parse_set_cookie(k)
- }
- header.delete('set-cookie')
- end
- header.each{|key, val| res[key] = val.join(", ") }
- rescue => ex
- raise HTTPStatus::InternalServerError, ex.message
- end
- res.body = body
- end
- alias do_POST do_GET
-
- # :startdoc:
- end
-
- end
-end
diff --git a/lib/webrick/httpservlet/erbhandler.rb b/lib/webrick/httpservlet/erbhandler.rb
deleted file mode 100644
index 9bcec69883..0000000000
--- a/lib/webrick/httpservlet/erbhandler.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# frozen_string_literal: false
-#
-# erbhandler.rb -- ERBHandler Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $
-
-require 'webrick/httpservlet/abstract.rb'
-
-require 'erb'
-
-module WEBrick
- module HTTPServlet
-
- ##
- # ERBHandler evaluates an ERB file and returns the result. This handler
- # is automatically used if there are .rhtml files in a directory served by
- # the FileHandler.
- #
- # ERBHandler supports GET and POST methods.
- #
- # The ERB file is evaluated with the local variables +servlet_request+ and
- # +servlet_response+ which are a WEBrick::HTTPRequest and
- # WEBrick::HTTPResponse respectively.
- #
- # Example .rhtml file:
- #
- # Request to <%= servlet_request.request_uri %>
- #
- # Query params <%= servlet_request.query.inspect %>
-
- class ERBHandler < AbstractServlet
-
- ##
- # Creates a new ERBHandler on +server+ that will evaluate and serve the
- # ERB file +name+
-
- def initialize(server, name)
- super(server, name)
- @script_filename = name
- end
-
- ##
- # Handles GET requests
-
- def do_GET(req, res)
- unless defined?(ERB)
- @logger.warn "#{self.class}: ERB not defined."
- raise HTTPStatus::Forbidden, "ERBHandler cannot work."
- end
- begin
- data = open(@script_filename){|io| io.read }
- res.body = evaluate(ERB.new(data), req, res)
- res['content-type'] ||=
- HTTPUtils::mime_type(@script_filename, @config[:MimeTypes])
- rescue StandardError
- raise
- rescue Exception => ex
- @logger.error(ex)
- raise HTTPStatus::InternalServerError, ex.message
- end
- end
-
- ##
- # Handles POST requests
-
- alias do_POST do_GET
-
- private
-
- ##
- # Evaluates +erb+ providing +servlet_request+ and +servlet_response+ as
- # local variables.
-
- def evaluate(erb, servlet_request, servlet_response)
- Module.new.module_eval{
- servlet_request.meta_vars
- servlet_request.query
- erb.result(binding)
- }
- end
- end
- end
-end
diff --git a/lib/webrick/httpservlet/filehandler.rb b/lib/webrick/httpservlet/filehandler.rb
deleted file mode 100644
index 3ea1eec7d0..0000000000
--- a/lib/webrick/httpservlet/filehandler.rb
+++ /dev/null
@@ -1,522 +0,0 @@
-# frozen_string_literal: false
-#
-# filehandler.rb -- FileHandler Module
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $
-
-require 'time'
-
-require 'webrick/htmlutils'
-require 'webrick/httputils'
-require 'webrick/httpstatus'
-
-module WEBrick
- module HTTPServlet
-
- ##
- # Servlet for serving a single file. You probably want to use the
- # FileHandler servlet instead as it handles directories and fancy indexes.
- #
- # Example:
- #
- # server.mount('/my_page.txt', WEBrick::HTTPServlet::DefaultFileHandler,
- # '/path/to/my_page.txt')
- #
- # This servlet handles If-Modified-Since and Range requests.
-
- class DefaultFileHandler < AbstractServlet
-
- ##
- # Creates a DefaultFileHandler instance for the file at +local_path+.
-
- def initialize(server, local_path)
- super(server, local_path)
- @local_path = local_path
- end
-
- # :stopdoc:
-
- def do_GET(req, res)
- st = File::stat(@local_path)
- mtime = st.mtime
- res['etag'] = sprintf("%x-%x-%x", st.ino, st.size, st.mtime.to_i)
-
- if not_modified?(req, res, mtime, res['etag'])
- res.body = ''
- raise HTTPStatus::NotModified
- elsif req['range']
- make_partial_content(req, res, @local_path, st.size)
- raise HTTPStatus::PartialContent
- else
- mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
- res['content-type'] = mtype
- res['content-length'] = st.size
- res['last-modified'] = mtime.httpdate
- res.body = open(@local_path, "rb")
- end
- end
-
- def not_modified?(req, res, mtime, etag)
- if ir = req['if-range']
- begin
- if Time.httpdate(ir) >= mtime
- return true
- end
- rescue
- if HTTPUtils::split_header_value(ir).member?(res['etag'])
- return true
- end
- end
- end
-
- if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime
- return true
- end
-
- if (inm = req['if-none-match']) &&
- HTTPUtils::split_header_value(inm).member?(res['etag'])
- return true
- end
-
- return false
- end
-
- def make_partial_content(req, res, filename, filesize)
- mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
- unless ranges = HTTPUtils::parse_range_header(req['range'])
- raise HTTPStatus::BadRequest,
- "Unrecognized range-spec: \"#{req['range']}\""
- end
- open(filename, "rb"){|io|
- if ranges.size > 1
- time = Time.now
- boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
- body = ''
- ranges.each{|range|
- first, last = prepare_range(range, filesize)
- next if first < 0
- io.pos = first
- content = io.read(last-first+1)
- body << "--" << boundary << CRLF
- body << "Content-Type: #{mtype}" << CRLF
- body << "Content-Range: bytes #{first}-#{last}/#{filesize}" << CRLF
- body << CRLF
- body << content
- body << CRLF
- }
- raise HTTPStatus::RequestRangeNotSatisfiable if body.empty?
- body << "--" << boundary << "--" << CRLF
- res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
- res.body = body
- elsif range = ranges[0]
- first, last = prepare_range(range, filesize)
- raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
- if last == filesize - 1
- content = io.dup
- content.pos = first
- else
- io.pos = first
- content = io.read(last-first+1)
- end
- res['content-type'] = mtype
- res['content-range'] = "bytes #{first}-#{last}/#{filesize}"
- res['content-length'] = last - first + 1
- res.body = content
- else
- raise HTTPStatus::BadRequest
- end
- }
- end
-
- def prepare_range(range, filesize)
- first = range.first < 0 ? filesize + range.first : range.first
- return -1, -1 if first < 0 || first >= filesize
- last = range.last < 0 ? filesize + range.last : range.last
- last = filesize - 1 if last >= filesize
- return first, last
- end
-
- # :startdoc:
- end
-
- ##
- # Serves a directory including fancy indexing and a variety of other
- # options.
- #
- # Example:
- #
- # server.mount('/assets', WEBrick::HTTPServlet::FileHandler,
- # '/path/to/assets')
-
- class FileHandler < AbstractServlet
- HandlerTable = Hash.new # :nodoc:
-
- ##
- # Allow custom handling of requests for files with +suffix+ by class
- # +handler+
-
- def self.add_handler(suffix, handler)
- HandlerTable[suffix] = handler
- end
-
- ##
- # Remove custom handling of requests for files with +suffix+
-
- def self.remove_handler(suffix)
- HandlerTable.delete(suffix)
- end
-
- ##
- # Creates a FileHandler servlet on +server+ that serves files starting
- # at directory +root+
- #
- # +options+ may be a Hash containing keys from
- # WEBrick::Config::FileHandler or +true+ or +false+.
- #
- # If +options+ is true or false then +:FancyIndexing+ is enabled or
- # disabled respectively.
-
- def initialize(server, root, options={}, default=Config::FileHandler)
- @config = server.config
- @logger = @config[:Logger]
- @root = File.expand_path(root)
- if options == true || options == false
- options = { :FancyIndexing => options }
- end
- @options = default.dup.update(options)
- end
-
- # :stopdoc:
-
- def service(req, res)
- # if this class is mounted on "/" and /~username is requested.
- # we're going to override path informations before invoking service.
- if defined?(Etc) && @options[:UserDir] && req.script_name.empty?
- if %r|^(/~([^/]+))| =~ req.path_info
- script_name, user = $1, $2
- path_info = $'
- begin
- passwd = Etc::getpwnam(user)
- @root = File::join(passwd.dir, @options[:UserDir])
- req.script_name = script_name
- req.path_info = path_info
- rescue
- @logger.debug "#{self.class}#do_GET: getpwnam(#{user}) failed"
- end
- end
- end
- prevent_directory_traversal(req, res)
- super(req, res)
- end
-
- def do_GET(req, res)
- unless exec_handler(req, res)
- set_dir_list(req, res)
- end
- end
-
- def do_POST(req, res)
- unless exec_handler(req, res)
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
-
- def do_OPTIONS(req, res)
- unless exec_handler(req, res)
- super(req, res)
- end
- end
-
- # ToDo
- # RFC2518: HTTP Extensions for Distributed Authoring -- WEBDAV
- #
- # PROPFIND PROPPATCH MKCOL DELETE PUT COPY MOVE
- # LOCK UNLOCK
-
- # RFC3253: Versioning Extensions to WebDAV
- # (Web Distributed Authoring and Versioning)
- #
- # VERSION-CONTROL REPORT CHECKOUT CHECK_IN UNCHECKOUT
- # MKWORKSPACE UPDATE LABEL MERGE ACTIVITY
-
- private
-
- def trailing_pathsep?(path)
- # check for trailing path separator:
- # File.dirname("/aaaa/bbbb/") #=> "/aaaa")
- # File.dirname("/aaaa/bbbb/x") #=> "/aaaa/bbbb")
- # File.dirname("/aaaa/bbbb") #=> "/aaaa")
- # File.dirname("/aaaa/bbbbx") #=> "/aaaa")
- return File.dirname(path) != File.dirname(path+"x")
- end
-
- def prevent_directory_traversal(req, res)
- # Preventing directory traversal on Windows platforms;
- # Backslashes (0x5c) in path_info are not interpreted as special
- # character in URI notation. So the value of path_info should be
- # normalize before accessing to the filesystem.
-
- # dirty hack for filesystem encoding; in nature, File.expand_path
- # should not be used for path normalization. [Bug #3345]
- path = req.path_info.dup.force_encoding(Encoding.find("filesystem"))
- if trailing_pathsep?(req.path_info)
- # File.expand_path removes the trailing path separator.
- # Adding a character is a workaround to save it.
- # File.expand_path("/aaa/") #=> "/aaa"
- # File.expand_path("/aaa/" + "x") #=> "/aaa/x"
- expanded = File.expand_path(path + "x")
- expanded.chop! # remove trailing "x"
- else
- expanded = File.expand_path(path)
- end
- expanded.force_encoding(req.path_info.encoding)
- req.path_info = expanded
- end
-
- def exec_handler(req, res)
- raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
- if set_filename(req, res)
- handler = get_handler(req, res)
- call_callback(:HandlerCallback, req, res)
- h = handler.get_instance(@config, res.filename)
- h.service(req, res)
- return true
- end
- call_callback(:HandlerCallback, req, res)
- return false
- end
-
- def get_handler(req, res)
- suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase
- if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename
- if @options[:AcceptableLanguages].include?($2.downcase)
- suffix2 = $1.downcase
- end
- end
- handler_table = @options[:HandlerTable]
- return handler_table[suffix1] || handler_table[suffix2] ||
- HandlerTable[suffix1] || HandlerTable[suffix2] ||
- DefaultFileHandler
- end
-
- def set_filename(req, res)
- res.filename = @root.dup
- path_info = req.path_info.scan(%r|/[^/]*|)
-
- path_info.unshift("") # dummy for checking @root dir
- while base = path_info.first
- break if base == "/"
- break unless File.directory?(File.expand_path(res.filename + base))
- shift_path_info(req, res, path_info)
- call_callback(:DirectoryCallback, req, res)
- end
-
- if base = path_info.first
- if base == "/"
- if file = search_index_file(req, res)
- shift_path_info(req, res, path_info, file)
- call_callback(:FileCallback, req, res)
- return true
- end
- shift_path_info(req, res, path_info)
- elsif file = search_file(req, res, base)
- shift_path_info(req, res, path_info, file)
- call_callback(:FileCallback, req, res)
- return true
- else
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
-
- return false
- end
-
- def check_filename(req, res, name)
- if nondisclosure_name?(name) || windows_ambiguous_name?(name)
- @logger.warn("the request refers nondisclosure name `#{name}'.")
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
-
- def shift_path_info(req, res, path_info, base=nil)
- tmp = path_info.shift
- base = base || tmp
- req.path_info = path_info.join
- req.script_name << base
- res.filename = File.expand_path(res.filename + base)
- check_filename(req, res, File.basename(res.filename))
- end
-
- def search_index_file(req, res)
- @config[:DirectoryIndex].each{|index|
- if file = search_file(req, res, "/"+index)
- return file
- end
- }
- return nil
- end
-
- def search_file(req, res, basename)
- langs = @options[:AcceptableLanguages]
- path = res.filename + basename
- if File.file?(path)
- return basename
- elsif langs.size > 0
- req.accept_language.each{|lang|
- path_with_lang = path + ".#{lang}"
- if langs.member?(lang) && File.file?(path_with_lang)
- return basename + ".#{lang}"
- end
- }
- (langs - req.accept_language).each{|lang|
- path_with_lang = path + ".#{lang}"
- if File.file?(path_with_lang)
- return basename + ".#{lang}"
- end
- }
- end
- return nil
- end
-
- def call_callback(callback_name, req, res)
- if cb = @options[callback_name]
- cb.call(req, res)
- end
- end
-
- def windows_ambiguous_name?(name)
- return true if /[. ]+\z/ =~ name
- return true if /::\$DATA\z/ =~ name
- return false
- end
-
- def nondisclosure_name?(name)
- @options[:NondisclosureName].each{|pattern|
- if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
- return true
- end
- }
- return false
- end
-
- def set_dir_list(req, res)
- redirect_to_directory_uri(req, res)
- unless @options[:FancyIndexing]
- raise HTTPStatus::Forbidden, "no access permission to `#{req.path}'"
- end
- local_path = res.filename
- list = Dir::entries(local_path).collect{|name|
- next if name == "." || name == ".."
- next if nondisclosure_name?(name)
- next if windows_ambiguous_name?(name)
- st = (File::stat(File.join(local_path, name)) rescue nil)
- if st.nil?
- [ name, nil, -1 ]
- elsif st.directory?
- [ name + "/", st.mtime, -1 ]
- else
- [ name, st.mtime, st.size ]
- end
- }
- list.compact!
-
- query = req.query
-
- d0 = nil
- idx = nil
- %w[N M S].each_with_index do |q, i|
- if d = query.delete(q)
- idx ||= i
- d0 ||= d
- end
- end
- d0 ||= "A"
- idx ||= 0
- d1 = (d0 == "A") ? "D" : "A"
-
- if d0 == "A"
- list.sort!{|a,b| a[idx] <=> b[idx] }
- else
- list.sort!{|a,b| b[idx] <=> a[idx] }
- end
-
- namewidth = query["NameWidth"]
- if namewidth == "*"
- namewidth = nil
- elsif !namewidth or (namewidth = namewidth.to_i) < 2
- namewidth = 25
- end
- query = query.inject('') {|s, (k, v)| s << '&' << HTMLUtils::escape("#{k}=#{v}")}
-
- type = "text/html"
- case enc = Encoding.find('filesystem')
- when Encoding::US_ASCII, Encoding::ASCII_8BIT
- else
- type << "; charset=\"#{enc.name}\""
- end
- res['content-type'] = type
-
- title = "Index of #{HTMLUtils::escape(req.path)}"
- res.body = <<-_end_of_html_
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<HTML>
- <HEAD>
- <TITLE>#{title}</TITLE>
- <style type="text/css">
- <!--
- .name, .mtime { text-align: left; }
- .size { text-align: right; }
- td { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
- table { border-collapse: collapse; }
- tr th { border-bottom: 2px groove; }
- //-->
- </style>
- </HEAD>
- <BODY>
- <H1>#{title}</H1>
- _end_of_html_
-
- res.body << "<TABLE width=\"100%\"><THEAD><TR>\n"
- res.body << "<TH class=\"name\"><A HREF=\"?N=#{d1}#{query}\">Name</A></TH>"
- res.body << "<TH class=\"mtime\"><A HREF=\"?M=#{d1}#{query}\">Last modified</A></TH>"
- res.body << "<TH class=\"size\"><A HREF=\"?S=#{d1}#{query}\">Size</A></TH>\n"
- res.body << "</TR></THEAD>\n"
- res.body << "<TBODY>\n"
-
- query.sub!(/\A&/, '?')
- list.unshift [ "..", File::mtime(local_path+"/.."), -1 ]
- list.each{ |name, time, size|
- if name == ".."
- dname = "Parent Directory"
- elsif namewidth and name.size > namewidth
- dname = name[0...(namewidth - 2)] << '..'
- else
- dname = name
- end
- s = "<TR><TD class=\"name\"><A HREF=\"#{HTTPUtils::escape(name)}#{query if name.end_with?('/')}\">#{HTMLUtils::escape(dname)}</A></TD>"
- s << "<TD class=\"mtime\">" << (time ? time.strftime("%Y/%m/%d %H:%M") : "") << "</TD>"
- s << "<TD class=\"size\">" << (size >= 0 ? size.to_s : "-") << "</TD></TR>\n"
- res.body << s
- }
- res.body << "</TBODY></TABLE>"
- res.body << "<HR>"
-
- res.body << <<-_end_of_html_
- <ADDRESS>
- #{HTMLUtils::escape(@config[:ServerSoftware])}<BR>
- at #{req.host}:#{req.port}
- </ADDRESS>
- </BODY>
-</HTML>
- _end_of_html_
- end
-
- # :startdoc:
- end
- end
-end
diff --git a/lib/webrick/httpservlet/prochandler.rb b/lib/webrick/httpservlet/prochandler.rb
deleted file mode 100644
index c1f454e2f6..0000000000
--- a/lib/webrick/httpservlet/prochandler.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: false
-#
-# prochandler.rb -- ProcHandler Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: prochandler.rb,v 1.7 2002/09/21 12:23:42 gotoyuzo Exp $
-
-require 'webrick/httpservlet/abstract.rb'
-
-module WEBrick
- module HTTPServlet
-
- ##
- # Mounts a proc at a path that accepts a request and response.
- #
- # Instead of mounting this servlet with WEBrick::HTTPServer#mount use
- # WEBrick::HTTPServer#mount_proc:
- #
- # server.mount_proc '/' do |req, res|
- # res.body = 'it worked!'
- # res.status = 200
- # end
-
- class ProcHandler < AbstractServlet
- # :stopdoc:
- def get_instance(server, *options)
- self
- end
-
- def initialize(proc)
- @proc = proc
- end
-
- def do_GET(request, response)
- @proc.call(request, response)
- end
-
- alias do_POST do_GET
- # :startdoc:
- end
-
- end
-end
diff --git a/lib/webrick/httpstatus.rb b/lib/webrick/httpstatus.rb
deleted file mode 100644
index 0630219ada..0000000000
--- a/lib/webrick/httpstatus.rb
+++ /dev/null
@@ -1,194 +0,0 @@
-# frozen_string_literal: false
-#--
-# httpstatus.rb -- HTTPStatus Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $
-
-require 'webrick/accesslog'
-
-module WEBrick
-
- ##
- # This module is used to manager HTTP status codes.
- #
- # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for more
- # information.
- module HTTPStatus
-
- ##
- # Root of the HTTP status class hierarchy
- class Status < StandardError
- class << self
- attr_reader :code, :reason_phrase # :nodoc:
- end
-
- # Returns the HTTP status code
- def code() self::class::code end
-
- # Returns the HTTP status description
- def reason_phrase() self::class::reason_phrase end
-
- alias to_i code # :nodoc:
- end
-
- # Root of the HTTP info statuses
- class Info < Status; end
- # Root of the HTTP success statuses
- class Success < Status; end
- # Root of the HTTP redirect statuses
- class Redirect < Status; end
- # Root of the HTTP error statuses
- class Error < Status; end
- # Root of the HTTP client error statuses
- class ClientError < Error; end
- # Root of the HTTP server error statuses
- class ServerError < Error; end
-
- class EOFError < StandardError; end
-
- # HTTP status codes and descriptions
- StatusMessage = { # :nodoc:
- 100 => 'Continue',
- 101 => 'Switching Protocols',
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
- 207 => 'Multi-Status',
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Found',
- 303 => 'See Other',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 307 => 'Temporary Redirect',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Large',
- 415 => 'Unsupported Media Type',
- 416 => 'Request Range Not Satisfiable',
- 417 => 'Expectation Failed',
- 422 => 'Unprocessable Entity',
- 423 => 'Locked',
- 424 => 'Failed Dependency',
- 426 => 'Upgrade Required',
- 428 => 'Precondition Required',
- 429 => 'Too Many Requests',
- 431 => 'Request Header Fields Too Large',
- 451 => 'Unavailable For Legal Reasons',
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- 505 => 'HTTP Version Not Supported',
- 507 => 'Insufficient Storage',
- 511 => 'Network Authentication Required',
- }
-
- # Maps a status code to the corresponding Status class
- CodeToError = {} # :nodoc:
-
- # Creates a status or error class for each status code and
- # populates the CodeToError map.
- StatusMessage.each{|code, message|
- message.freeze
- var_name = message.gsub(/[ \-]/,'_').upcase
- err_name = message.gsub(/[ \-]/,'')
-
- case code
- when 100...200; parent = Info
- when 200...300; parent = Success
- when 300...400; parent = Redirect
- when 400...500; parent = ClientError
- when 500...600; parent = ServerError
- end
-
- const_set("RC_#{var_name}", code)
- err_class = Class.new(parent)
- err_class.instance_variable_set(:@code, code)
- err_class.instance_variable_set(:@reason_phrase, message)
- const_set(err_name, err_class)
- CodeToError[code] = err_class
- }
-
- ##
- # Returns the description corresponding to the HTTP status +code+
- #
- # WEBrick::HTTPStatus.reason_phrase 404
- # => "Not Found"
- def reason_phrase(code)
- StatusMessage[code.to_i]
- end
-
- ##
- # Is +code+ an informational status?
- def info?(code)
- code.to_i >= 100 and code.to_i < 200
- end
-
- ##
- # Is +code+ a successful status?
- def success?(code)
- code.to_i >= 200 and code.to_i < 300
- end
-
- ##
- # Is +code+ a redirection status?
- def redirect?(code)
- code.to_i >= 300 and code.to_i < 400
- end
-
- ##
- # Is +code+ an error status?
- def error?(code)
- code.to_i >= 400 and code.to_i < 600
- end
-
- ##
- # Is +code+ a client error status?
- def client_error?(code)
- code.to_i >= 400 and code.to_i < 500
- end
-
- ##
- # Is +code+ a server error status?
- def server_error?(code)
- code.to_i >= 500 and code.to_i < 600
- end
-
- ##
- # Returns the status class corresponding to +code+
- #
- # WEBrick::HTTPStatus[302]
- # => WEBrick::HTTPStatus::NotFound
- #
- def self.[](code)
- CodeToError[code]
- end
-
- module_function :reason_phrase
- module_function :info?, :success?, :redirect?, :error?
- module_function :client_error?, :server_error?
- end
-end
diff --git a/lib/webrick/httputils.rb b/lib/webrick/httputils.rb
deleted file mode 100644
index 586971dd06..0000000000
--- a/lib/webrick/httputils.rb
+++ /dev/null
@@ -1,511 +0,0 @@
-# frozen_string_literal: false
-#
-# httputils.rb -- HTTPUtils Module
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: httputils.rb,v 1.34 2003/06/05 21:34:08 gotoyuzo Exp $
-
-require 'socket'
-require 'tempfile'
-
-module WEBrick
- CR = "\x0d" # :nodoc:
- LF = "\x0a" # :nodoc:
- CRLF = "\x0d\x0a" # :nodoc:
-
- ##
- # HTTPUtils provides utility methods for working with the HTTP protocol.
- #
- # This module is generally used internally by WEBrick
-
- module HTTPUtils
-
- ##
- # Normalizes a request path. Raises an exception if the path cannot be
- # normalized.
-
- def normalize_path(path)
- raise "abnormal path `#{path}'" if path[0] != ?/
- ret = path.dup
-
- ret.gsub!(%r{/+}o, '/') # // => /
- while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => /
- while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo
-
- raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
- ret
- end
- module_function :normalize_path
-
- ##
- # Default mime types
-
- DefaultMimeTypes = {
- "ai" => "application/postscript",
- "asc" => "text/plain",
- "avi" => "video/x-msvideo",
- "bin" => "application/octet-stream",
- "bmp" => "image/bmp",
- "class" => "application/octet-stream",
- "cer" => "application/pkix-cert",
- "crl" => "application/pkix-crl",
- "crt" => "application/x-x509-ca-cert",
- #"crl" => "application/x-pkcs7-crl",
- "css" => "text/css",
- "dms" => "application/octet-stream",
- "doc" => "application/msword",
- "dvi" => "application/x-dvi",
- "eps" => "application/postscript",
- "etx" => "text/x-setext",
- "exe" => "application/octet-stream",
- "gif" => "image/gif",
- "htm" => "text/html",
- "html" => "text/html",
- "jpe" => "image/jpeg",
- "jpeg" => "image/jpeg",
- "jpg" => "image/jpeg",
- "js" => "application/javascript",
- "json" => "application/json",
- "lha" => "application/octet-stream",
- "lzh" => "application/octet-stream",
- "mov" => "video/quicktime",
- "mpe" => "video/mpeg",
- "mpeg" => "video/mpeg",
- "mpg" => "video/mpeg",
- "pbm" => "image/x-portable-bitmap",
- "pdf" => "application/pdf",
- "pgm" => "image/x-portable-graymap",
- "png" => "image/png",
- "pnm" => "image/x-portable-anymap",
- "ppm" => "image/x-portable-pixmap",
- "ppt" => "application/vnd.ms-powerpoint",
- "ps" => "application/postscript",
- "qt" => "video/quicktime",
- "ras" => "image/x-cmu-raster",
- "rb" => "text/plain",
- "rd" => "text/plain",
- "rtf" => "application/rtf",
- "sgm" => "text/sgml",
- "sgml" => "text/sgml",
- "svg" => "image/svg+xml",
- "tif" => "image/tiff",
- "tiff" => "image/tiff",
- "txt" => "text/plain",
- "xbm" => "image/x-xbitmap",
- "xhtml" => "text/html",
- "xls" => "application/vnd.ms-excel",
- "xml" => "text/xml",
- "xpm" => "image/x-xpixmap",
- "xwd" => "image/x-xwindowdump",
- "zip" => "application/zip",
- }
-
- ##
- # Loads Apache-compatible mime.types in +file+.
-
- def load_mime_types(file)
- open(file){ |io|
- hash = Hash.new
- io.each{ |line|
- next if /^#/ =~ line
- line.chomp!
- mimetype, ext0 = line.split(/\s+/, 2)
- next unless ext0
- next if ext0.empty?
- ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype }
- }
- hash
- }
- end
- module_function :load_mime_types
-
- ##
- # Returns the mime type of +filename+ from the list in +mime_tab+. If no
- # mime type was found application/octet-stream is returned.
-
- def mime_type(filename, mime_tab)
- suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
- suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
- mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream"
- end
- module_function :mime_type
-
- ##
- # Parses an HTTP header +raw+ into a hash of header fields with an Array
- # of values.
-
- def parse_header(raw)
- header = Hash.new([].freeze)
- field = nil
- raw.each_line{|line|
- case line
- when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om
- field, value = $1, $2
- field.downcase!
- header[field] = [] unless header.has_key?(field)
- header[field] << value
- when /^\s+(.*?)\s*\z/om
- value = $1
- unless field
- raise HTTPStatus::BadRequest, "bad header '#{line}'."
- end
- header[field][-1] << " " << value
- else
- raise HTTPStatus::BadRequest, "bad header '#{line}'."
- end
- }
- header.each{|key, values|
- values.each{|value|
- value.strip!
- value.gsub!(/\s+/, " ")
- }
- }
- header
- end
- module_function :parse_header
-
- ##
- # Splits a header value +str+ according to HTTP specification.
-
- def split_header_value(str)
- str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
- (?:,\s*|\Z)'xn).flatten
- end
- module_function :split_header_value
-
- ##
- # Parses a Range header value +ranges_specifier+
-
- def parse_range_header(ranges_specifier)
- if /^bytes=(.*)/ =~ ranges_specifier
- byte_range_set = split_header_value($1)
- byte_range_set.collect{|range_spec|
- case range_spec
- when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i
- when /^(\d+)-/ then $1.to_i .. -1
- when /^-(\d+)/ then -($1.to_i) .. -1
- else return nil
- end
- }
- end
- end
- module_function :parse_range_header
-
- ##
- # Parses q values in +value+ as used in Accept headers.
-
- def parse_qvalues(value)
- tmp = []
- if value
- parts = value.split(/,\s*/)
- parts.each {|part|
- if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
- val = m[1]
- q = (m[2] or 1).to_f
- tmp.push([val, q])
- end
- }
- tmp = tmp.sort_by{|val, q| -q}
- tmp.collect!{|val, q| val}
- end
- return tmp
- end
- module_function :parse_qvalues
-
- ##
- # Removes quotes and escapes from +str+
-
- def dequote(str)
- ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
- ret.gsub!(/\\(.)/, "\\1")
- ret
- end
- module_function :dequote
-
- ##
- # Quotes and escapes quotes in +str+
-
- def quote(str)
- '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
- end
- module_function :quote
-
- ##
- # Stores multipart form data. FormData objects are created when
- # WEBrick::HTTPUtils.parse_form_data is called.
-
- class FormData < String
- EmptyRawHeader = [].freeze # :nodoc:
- EmptyHeader = {}.freeze # :nodoc:
-
- ##
- # The name of the form data part
-
- attr_accessor :name
-
- ##
- # The filename of the form data part
-
- attr_accessor :filename
-
- attr_accessor :next_data # :nodoc:
- protected :next_data
-
- ##
- # Creates a new FormData object.
- #
- # +args+ is an Array of form data entries. One FormData will be created
- # for each entry.
- #
- # This is called by WEBrick::HTTPUtils.parse_form_data for you
-
- def initialize(*args)
- @name = @filename = @next_data = nil
- if args.empty?
- @raw_header = []
- @header = nil
- super("")
- else
- @raw_header = EmptyRawHeader
- @header = EmptyHeader
- super(args.shift)
- unless args.empty?
- @next_data = self.class.new(*args)
- end
- end
- end
-
- ##
- # Retrieves the header at the first entry in +key+
-
- def [](*key)
- begin
- @header[key[0].downcase].join(", ")
- rescue StandardError, NameError
- super
- end
- end
-
- ##
- # Adds +str+ to this FormData which may be the body, a header or a
- # header entry.
- #
- # This is called by WEBrick::HTTPUtils.parse_form_data for you
-
- def <<(str)
- if @header
- super
- elsif str == CRLF
- @header = HTTPUtils::parse_header(@raw_header.join)
- if cd = self['content-disposition']
- if /\s+name="(.*?)"/ =~ cd then @name = $1 end
- if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end
- end
- else
- @raw_header << str
- end
- self
- end
-
- ##
- # Adds +data+ at the end of the chain of entries
- #
- # This is called by WEBrick::HTTPUtils.parse_form_data for you.
-
- def append_data(data)
- tmp = self
- while tmp
- unless tmp.next_data
- tmp.next_data = data
- break
- end
- tmp = tmp.next_data
- end
- self
- end
-
- ##
- # Yields each entry in this FormData
-
- def each_data
- tmp = self
- while tmp
- next_data = tmp.next_data
- yield(tmp)
- tmp = next_data
- end
- end
-
- ##
- # Returns all the FormData as an Array
-
- def list
- ret = []
- each_data{|data|
- ret << data.to_s
- }
- ret
- end
-
- ##
- # A FormData will behave like an Array
-
- alias :to_ary :list
-
- ##
- # This FormData's body
-
- def to_s
- String.new(self)
- end
- end
-
- ##
- # Parses the query component of a URI in +str+
-
- def parse_query(str)
- query = Hash.new
- if str
- str.split(/[&;]/).each{|x|
- next if x.empty?
- key, val = x.split(/=/,2)
- key = unescape_form(key)
- val = unescape_form(val.to_s)
- val = FormData.new(val)
- val.name = key
- if query.has_key?(key)
- query[key].append_data(val)
- next
- end
- query[key] = val
- }
- end
- query
- end
- module_function :parse_query
-
- ##
- # Parses form data in +io+ with the given +boundary+
-
- def parse_form_data(io, boundary)
- boundary_regexp = /\A--#{Regexp.quote(boundary)}(--)?#{CRLF}\z/
- form_data = Hash.new
- return form_data unless io
- data = nil
- io.each_line{|line|
- if boundary_regexp =~ line
- if data
- data.chop!
- key = data.name
- if form_data.has_key?(key)
- form_data[key].append_data(data)
- else
- form_data[key] = data
- end
- end
- data = FormData.new
- next
- else
- if data
- data << line
- end
- end
- }
- return form_data
- end
- module_function :parse_form_data
-
- #####
-
- reserved = ';/?:@&=+$,'
- num = '0123456789'
- lowalpha = 'abcdefghijklmnopqrstuvwxyz'
- upalpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- mark = '-_.!~*\'()'
- unreserved = num + lowalpha + upalpha + mark
- control = (0x0..0x1f).collect{|c| c.chr }.join + "\x7f"
- space = " "
- delims = '<>#%"'
- unwise = '{}|\\^[]`'
- nonascii = (0x80..0xff).collect{|c| c.chr }.join
-
- module_function
-
- # :stopdoc:
-
- def _make_regex(str) /([#{Regexp.escape(str)}])/n end
- def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
- def _escape(str, regex)
- str = str.b
- str.gsub!(regex) {"%%%02X" % $1.ord}
- # %-escaped string should contain US-ASCII only
- str.force_encoding(Encoding::US_ASCII)
- end
- def _unescape(str, regex)
- str = str.b
- str.gsub!(regex) {$1.hex.chr}
- # encoding of %-unescaped string is unknown
- str
- end
-
- UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
- UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
- NONASCII = _make_regex(nonascii)
- ESCAPED = /%([0-9a-fA-F]{2})/
- UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
-
- # :startdoc:
-
- ##
- # Escapes HTTP reserved and unwise characters in +str+
-
- def escape(str)
- _escape(str, UNESCAPED)
- end
-
- ##
- # Unescapes HTTP reserved and unwise characters in +str+
-
- def unescape(str)
- _unescape(str, ESCAPED)
- end
-
- ##
- # Escapes form reserved characters in +str+
-
- def escape_form(str)
- ret = _escape(str, UNESCAPED_FORM)
- ret.gsub!(/ /, "+")
- ret
- end
-
- ##
- # Unescapes form reserved characters in +str+
-
- def unescape_form(str)
- _unescape(str.gsub(/\+/, " "), ESCAPED)
- end
-
- ##
- # Escapes path +str+
-
- def escape_path(str)
- result = ""
- str.scan(%r{/([^/]*)}).each{|i|
- result << "/" << _escape(i[0], UNESCAPED_PCHAR)
- }
- return result
- end
-
- ##
- # Escapes 8 bit characters in +str+
-
- def escape8bit(str)
- _escape(str, NONASCII)
- end
- end
-end
diff --git a/lib/webrick/log.rb b/lib/webrick/log.rb
deleted file mode 100644
index 41e907cd3b..0000000000
--- a/lib/webrick/log.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-# frozen_string_literal: false
-#--
-# log.rb -- Log Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: log.rb,v 1.26 2002/10/06 17:06:10 gotoyuzo Exp $
-
-module WEBrick
-
- ##
- # A generic logging class
-
- class BasicLog
-
- # Fatal log level which indicates a server crash
-
- FATAL = 1
-
- # Error log level which indicates a recoverable error
-
- ERROR = 2
-
- # Warning log level which indicates a possible problem
-
- WARN = 3
-
- # Information log level which indicates possibly useful information
-
- INFO = 4
-
- # Debugging error level for messages used in server development or
- # debugging
-
- DEBUG = 5
-
- # log-level, messages above this level will be logged
- attr_accessor :level
-
- ##
- # Initializes a new logger for +log_file+ that outputs messages at +level+
- # or higher. +log_file+ can be a filename, an IO-like object that
- # responds to #<< or nil which outputs to $stderr.
- #
- # If no level is given INFO is chosen by default
-
- def initialize(log_file=nil, level=nil)
- @level = level || INFO
- case log_file
- when String
- @log = open(log_file, "a+")
- @log.sync = true
- @opened = true
- when NilClass
- @log = $stderr
- else
- @log = log_file # requires "<<". (see BasicLog#log)
- end
- end
-
- ##
- # Closes the logger (also closes the log device associated to the logger)
- def close
- @log.close if @opened
- @log = nil
- end
-
- ##
- # Logs +data+ at +level+ if the given level is above the current log
- # level.
-
- def log(level, data)
- if @log && level <= @level
- data += "\n" if /\n\Z/ !~ data
- @log << data
- end
- end
-
- ##
- # Synonym for log(INFO, obj.to_s)
- def <<(obj)
- log(INFO, obj.to_s)
- end
-
- # Shortcut for logging a FATAL message
- def fatal(msg) log(FATAL, "FATAL " << format(msg)); end
- # Shortcut for logging an ERROR message
- def error(msg) log(ERROR, "ERROR " << format(msg)); end
- # Shortcut for logging a WARN message
- def warn(msg) log(WARN, "WARN " << format(msg)); end
- # Shortcut for logging an INFO message
- def info(msg) log(INFO, "INFO " << format(msg)); end
- # Shortcut for logging a DEBUG message
- def debug(msg) log(DEBUG, "DEBUG " << format(msg)); end
-
- # Will the logger output FATAL messages?
- def fatal?; @level >= FATAL; end
- # Will the logger output ERROR messages?
- def error?; @level >= ERROR; end
- # Will the logger output WARN messages?
- def warn?; @level >= WARN; end
- # Will the logger output INFO messages?
- def info?; @level >= INFO; end
- # Will the logger output DEBUG messages?
- def debug?; @level >= DEBUG; end
-
- private
-
- ##
- # Formats +arg+ for the logger
- #
- # * If +arg+ is an Exception, it will format the error message and
- # the back trace.
- # * If +arg+ responds to #to_str, it will return it.
- # * Otherwise it will return +arg+.inspect.
- def format(arg)
- if arg.is_a?(Exception)
- "#{arg.class}: #{AccessLog.escape(arg.message)}\n\t" <<
- arg.backtrace.join("\n\t") << "\n"
- elsif arg.respond_to?(:to_str)
- AccessLog.escape(arg.to_str)
- else
- arg.inspect
- end
- end
- end
-
- ##
- # A logging class that prepends a timestamp to each message.
-
- class Log < BasicLog
- # Format of the timestamp which is applied to each logged line. The
- # default is <tt>"[%Y-%m-%d %H:%M:%S]"</tt>
- attr_accessor :time_format
-
- ##
- # Same as BasicLog#initialize
- #
- # You can set the timestamp format through #time_format
- def initialize(log_file=nil, level=nil)
- super(log_file, level)
- @time_format = "[%Y-%m-%d %H:%M:%S]"
- end
-
- ##
- # Same as BasicLog#log
- def log(level, data)
- tmp = Time.now.strftime(@time_format)
- tmp << " " << data
- super(level, tmp)
- end
- end
-end
diff --git a/lib/webrick/server.rb b/lib/webrick/server.rb
deleted file mode 100644
index 5e83b692db..0000000000
--- a/lib/webrick/server.rb
+++ /dev/null
@@ -1,359 +0,0 @@
-# frozen_string_literal: false
-#
-# server.rb -- GenericServer Class
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $
-
-require 'socket'
-require 'webrick/config'
-require 'webrick/log'
-
-module WEBrick
-
- ##
- # Server error exception
-
- class ServerError < StandardError; end
-
- ##
- # Base server class
-
- class SimpleServer
-
- ##
- # A SimpleServer only yields when you start it
-
- def SimpleServer.start
- yield
- end
- end
-
- ##
- # A generic module for daemonizing a process
-
- class Daemon
-
- ##
- # Performs the standard operations for daemonizing a process. Runs a
- # block, if given.
-
- def Daemon.start
- Process.daemon
- File.umask(0)
- yield if block_given?
- end
- end
-
- ##
- # Base TCP server class. You must subclass GenericServer and provide a #run
- # method.
-
- class GenericServer
-
- ##
- # The server status. One of :Stop, :Running or :Shutdown
-
- attr_reader :status
-
- ##
- # The server configuration
-
- attr_reader :config
-
- ##
- # The server logger. This is independent from the HTTP access log.
-
- attr_reader :logger
-
- ##
- # Tokens control the number of outstanding clients. The
- # <code>:MaxClients</code> configuration sets this.
-
- attr_reader :tokens
-
- ##
- # Sockets listening for connections.
-
- attr_reader :listeners
-
- ##
- # Creates a new generic server from +config+. The default configuration
- # comes from +default+.
-
- def initialize(config={}, default=Config::General)
- @config = default.dup.update(config)
- @status = :Stop
- @config[:Logger] ||= Log::new
- @logger = @config[:Logger]
-
- @tokens = Thread::SizedQueue.new(@config[:MaxClients])
- @config[:MaxClients].times{ @tokens.push(nil) }
-
- webrickv = WEBrick::VERSION
- rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
- @logger.info("WEBrick #{webrickv}")
- @logger.info("ruby #{rubyv}")
-
- @listeners = []
- @shutdown_pipe = nil
- unless @config[:DoNotListen]
- if @config[:Listen]
- warn(":Listen option is deprecated; use GenericServer#listen")
- end
- listen(@config[:BindAddress], @config[:Port])
- if @config[:Port] == 0
- @config[:Port] = @listeners[0].addr[1]
- end
- end
- end
-
- ##
- # Retrieves +key+ from the configuration
-
- def [](key)
- @config[key]
- end
-
- ##
- # Adds listeners from +address+ and +port+ to the server. See
- # WEBrick::Utils::create_listeners for details.
-
- def listen(address, port)
- @listeners += Utils::create_listeners(address, port)
- end
-
- ##
- # Starts the server and runs the +block+ for each connection. This method
- # does not return until the server is stopped from a signal handler or
- # another thread using #stop or #shutdown.
- #
- # If the block raises a subclass of StandardError the exception is logged
- # and ignored. If an IOError or Errno::EBADF exception is raised the
- # exception is ignored. If an Exception subclass is raised the exception
- # is logged and re-raised which stops the server.
- #
- # To completely shut down a server call #shutdown from ensure:
- #
- # server = WEBrick::GenericServer.new
- # # or WEBrick::HTTPServer.new
- #
- # begin
- # server.start
- # ensure
- # server.shutdown
- # end
-
- def start(&block)
- raise ServerError, "already started." if @status != :Stop
- server_type = @config[:ServerType] || SimpleServer
-
- setup_shutdown_pipe
-
- server_type.start{
- @logger.info \
- "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
- call_callback(:StartCallback)
-
- shutdown_pipe = @shutdown_pipe
-
- thgroup = ThreadGroup.new
- @status = :Running
- begin
- while @status == :Running
- begin
- sp = shutdown_pipe[0]
- if svrs = IO.select([sp, *@listeners])
- if svrs[0].include? sp
- # swallow shutdown pipe
- buf = String.new
- nil while String ===
- sp.read_nonblock([sp.nread, 8].max, buf, exception: false)
- break
- end
- svrs[0].each{|svr|
- @tokens.pop # blocks while no token is there.
- if sock = accept_client(svr)
- unless config[:DoNotReverseLookup].nil?
- sock.do_not_reverse_lookup = !!config[:DoNotReverseLookup]
- end
- th = start_thread(sock, &block)
- th[:WEBrickThread] = true
- thgroup.add(th)
- else
- @tokens.push(nil)
- end
- }
- end
- rescue Errno::EBADF, Errno::ENOTSOCK, IOError => ex
- # if the listening socket was closed in GenericServer#shutdown,
- # IO::select raise it.
- rescue StandardError => ex
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
- @logger.error msg
- rescue Exception => ex
- @logger.fatal ex
- raise
- end
- end
- ensure
- cleanup_shutdown_pipe(shutdown_pipe)
- cleanup_listener
- @status = :Shutdown
- @logger.info "going to shutdown ..."
- thgroup.list.each{|th| th.join if th[:WEBrickThread] }
- call_callback(:StopCallback)
- @logger.info "#{self.class}#start done."
- @status = :Stop
- end
- }
- end
-
- ##
- # Stops the server from accepting new connections.
-
- def stop
- if @status == :Running
- @status = :Shutdown
- end
-
- alarm_shutdown_pipe {|f| f.write_nonblock("\0")}
- end
-
- ##
- # Shuts down the server and all listening sockets. New listeners must be
- # provided to restart the server.
-
- def shutdown
- stop
-
- alarm_shutdown_pipe(&:close)
- end
-
- ##
- # You must subclass GenericServer and implement \#run which accepts a TCP
- # client socket
-
- def run(sock)
- @logger.fatal "run() must be provided by user."
- end
-
- private
-
- # :stopdoc:
-
- ##
- # Accepts a TCP client socket from the TCP server socket +svr+ and returns
- # the client socket.
-
- def accept_client(svr)
- sock = nil
- begin
- sock = svr.accept
- Utils::set_non_blocking(sock)
- rescue Errno::ECONNRESET, Errno::ECONNABORTED,
- Errno::EPROTO, Errno::EINVAL
- rescue StandardError => ex
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
- @logger.error msg
- end
- return sock
- end
-
- ##
- # Starts a server thread for the client socket +sock+ that runs the given
- # +block+.
- #
- # Sets the socket to the <code>:WEBrickSocket</code> thread local variable
- # in the thread.
- #
- # If any errors occur in the block they are logged and handled.
-
- def start_thread(sock, &block)
- Thread.start{
- begin
- Thread.current[:WEBrickSocket] = sock
- begin
- addr = sock.peeraddr
- @logger.debug "accept: #{addr[3]}:#{addr[1]}"
- rescue SocketError
- @logger.debug "accept: <address unknown>"
- raise
- end
- call_callback(:AcceptCallback, sock)
- block ? block.call(sock) : run(sock)
- rescue Errno::ENOTCONN
- @logger.debug "Errno::ENOTCONN raised"
- rescue ServerError => ex
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
- @logger.error msg
- rescue Exception => ex
- @logger.error ex
- ensure
- @tokens.push(nil)
- Thread.current[:WEBrickSocket] = nil
- if addr
- @logger.debug "close: #{addr[3]}:#{addr[1]}"
- else
- @logger.debug "close: <address unknown>"
- end
- sock.close
- end
- }
- end
-
- ##
- # Calls the callback +callback_name+ from the configuration with +args+
-
- def call_callback(callback_name, *args)
- @config[callback_name]&.call(*args)
- end
-
- def setup_shutdown_pipe
- return @shutdown_pipe ||= IO.pipe
- end
-
- def cleanup_shutdown_pipe(shutdown_pipe)
- @shutdown_pipe = nil
- shutdown_pipe&.each(&:close)
- end
-
- def alarm_shutdown_pipe
- _, pipe = @shutdown_pipe # another thread may modify @shutdown_pipe.
- if pipe
- if !pipe.closed?
- begin
- yield pipe
- rescue IOError # closed by another thread.
- end
- end
- end
- end
-
- def cleanup_listener
- @listeners.each{|s|
- if @logger.debug?
- addr = s.addr
- @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
- end
- begin
- s.shutdown
- rescue Errno::ENOTCONN
- # when `Errno::ENOTCONN: Socket is not connected' on some platforms,
- # call #close instead of #shutdown.
- # (ignore @config[:ShutdownSocketWithoutClose])
- s.close
- else
- unless @config[:ShutdownSocketWithoutClose]
- s.close
- end
- end
- }
- @listeners.clear
- end
- end # end of GenericServer
-end
diff --git a/lib/webrick/ssl.rb b/lib/webrick/ssl.rb
deleted file mode 100644
index 8a334eaff1..0000000000
--- a/lib/webrick/ssl.rb
+++ /dev/null
@@ -1,215 +0,0 @@
-# frozen_string_literal: false
-#
-# ssl.rb -- SSL/TLS enhancement for GenericServer
-#
-# Copyright (c) 2003 GOTOU Yuuzou All rights reserved.
-#
-# $Id$
-
-require 'webrick'
-require 'openssl'
-
-module WEBrick
- module Config
- svrsoft = General[:ServerSoftware]
- osslv = ::OpenSSL::OPENSSL_VERSION.split[1]
-
- ##
- # Default SSL server configuration.
- #
- # WEBrick can automatically create a self-signed certificate if
- # <code>:SSLCertName</code> is set. For more information on the various
- # SSL options see OpenSSL::SSL::SSLContext.
- #
- # :ServerSoftware ::
- # The server software name used in the Server: header.
- # :SSLEnable :: false,
- # Enable SSL for this server. Defaults to false.
- # :SSLCertificate ::
- # The SSL certificate for the server.
- # :SSLPrivateKey ::
- # The SSL private key for the server certificate.
- # :SSLClientCA :: nil,
- # Array of certificates that will be sent to the client.
- # :SSLExtraChainCert :: nil,
- # Array of certificates that will be added to the certificate chain
- # :SSLCACertificateFile :: nil,
- # Path to a CA certificate file
- # :SSLCACertificatePath :: nil,
- # Path to a directory containing CA certificates
- # :SSLCertificateStore :: nil,
- # OpenSSL::X509::Store used for certificate validation of the client
- # :SSLTmpDhCallback :: nil,
- # Callback invoked when DH parameters are required.
- # :SSLVerifyClient ::
- # Sets whether the client is verified. This defaults to VERIFY_NONE
- # which is typical for an HTTPS server.
- # :SSLVerifyDepth ::
- # Number of CA certificates to walk when verifying a certificate chain
- # :SSLVerifyCallback ::
- # Custom certificate verification callback
- # :SSLServerNameCallback::
- # Custom servername indication callback
- # :SSLTimeout ::
- # Maximum session lifetime
- # :SSLOptions ::
- # Various SSL options
- # :SSLCiphers ::
- # Ciphers to be used
- # :SSLStartImmediately ::
- # Immediately start SSL upon connection? Defaults to true
- # :SSLCertName ::
- # SSL certificate name. Must be set to enable automatic certificate
- # creation.
- # :SSLCertComment ::
- # Comment used during automatic certificate creation.
-
- SSL = {
- :ServerSoftware => "#{svrsoft} OpenSSL/#{osslv}",
- :SSLEnable => false,
- :SSLCertificate => nil,
- :SSLPrivateKey => nil,
- :SSLClientCA => nil,
- :SSLExtraChainCert => nil,
- :SSLCACertificateFile => nil,
- :SSLCACertificatePath => nil,
- :SSLCertificateStore => nil,
- :SSLTmpDhCallback => nil,
- :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
- :SSLVerifyDepth => nil,
- :SSLVerifyCallback => nil, # custom verification
- :SSLTimeout => nil,
- :SSLOptions => nil,
- :SSLCiphers => nil,
- :SSLStartImmediately => true,
- # Must specify if you use auto generated certificate.
- :SSLCertName => nil,
- :SSLCertComment => "Generated by Ruby/OpenSSL"
- }
- General.update(SSL)
- end
-
- module Utils
- ##
- # Creates a self-signed certificate with the given number of +bits+,
- # the issuer +cn+ and a +comment+ to be stored in the certificate.
-
- def create_self_signed_cert(bits, cn, comment)
- rsa = OpenSSL::PKey::RSA.new(bits){|p, n|
- case p
- when 0; $stderr.putc "." # BN_generate_prime
- when 1; $stderr.putc "+" # BN_generate_prime
- when 2; $stderr.putc "*" # searching good prime,
- # n = #of try,
- # but also data from BN_generate_prime
- when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
- # but also data from BN_generate_prime
- else; $stderr.putc "*" # BN_generate_prime
- end
- }
- cert = OpenSSL::X509::Certificate.new
- cert.version = 2
- cert.serial = 1
- name = (cn.kind_of? String) ? OpenSSL::X509::Name.parse(cn)
- : OpenSSL::X509::Name.new(cn)
- cert.subject = name
- cert.issuer = name
- cert.not_before = Time.now
- cert.not_after = Time.now + (365*24*60*60)
- cert.public_key = rsa.public_key
-
- ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
- ef.issuer_certificate = cert
- cert.extensions = [
- ef.create_extension("basicConstraints","CA:FALSE"),
- ef.create_extension("keyUsage", "keyEncipherment"),
- ef.create_extension("subjectKeyIdentifier", "hash"),
- ef.create_extension("extendedKeyUsage", "serverAuth"),
- ef.create_extension("nsComment", comment),
- ]
- aki = ef.create_extension("authorityKeyIdentifier",
- "keyid:always,issuer:always")
- cert.add_extension(aki)
- cert.sign(rsa, OpenSSL::Digest::SHA1.new)
-
- return [ cert, rsa ]
- end
- module_function :create_self_signed_cert
- end
-
- ##
- #--
- # Updates WEBrick::GenericServer with SSL functionality
-
- class GenericServer
-
- ##
- # SSL context for the server when run in SSL mode
-
- def ssl_context # :nodoc:
- @ssl_context ||= begin
- if @config[:SSLEnable]
- ssl_context = setup_ssl_context(@config)
- @logger.info("\n" + @config[:SSLCertificate].to_text)
- ssl_context
- end
- end
- end
-
- undef listen
-
- ##
- # Updates +listen+ to enable SSL when the SSL configuration is active.
-
- def listen(address, port) # :nodoc:
- listeners = Utils::create_listeners(address, port)
- if @config[:SSLEnable]
- listeners.collect!{|svr|
- ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)
- ssvr.start_immediately = @config[:SSLStartImmediately]
- ssvr
- }
- end
- @listeners += listeners
- setup_shutdown_pipe
- end
-
- ##
- # Sets up an SSL context for +config+
-
- def setup_ssl_context(config) # :nodoc:
- unless config[:SSLCertificate]
- cn = config[:SSLCertName]
- comment = config[:SSLCertComment]
- cert, key = Utils::create_self_signed_cert(1024, cn, comment)
- config[:SSLCertificate] = cert
- config[:SSLPrivateKey] = key
- end
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.key = config[:SSLPrivateKey]
- ctx.cert = config[:SSLCertificate]
- ctx.client_ca = config[:SSLClientCA]
- ctx.extra_chain_cert = config[:SSLExtraChainCert]
- ctx.ca_file = config[:SSLCACertificateFile]
- ctx.ca_path = config[:SSLCACertificatePath]
- ctx.cert_store = config[:SSLCertificateStore]
- ctx.tmp_dh_callback = config[:SSLTmpDhCallback]
- ctx.verify_mode = config[:SSLVerifyClient]
- ctx.verify_depth = config[:SSLVerifyDepth]
- ctx.verify_callback = config[:SSLVerifyCallback]
- ctx.servername_cb = config[:SSLServerNameCallback] || proc { |args| ssl_servername_callback(*args) }
- ctx.timeout = config[:SSLTimeout]
- ctx.options = config[:SSLOptions]
- ctx.ciphers = config[:SSLCiphers]
- ctx
- end
-
- ##
- # ServerNameIndication callback
-
- def ssl_servername_callback(sslsocket, hostname = nil)
- # default
- end
-
- end
-end
diff --git a/lib/webrick/utils.rb b/lib/webrick/utils.rb
deleted file mode 100644
index 68833af96e..0000000000
--- a/lib/webrick/utils.rb
+++ /dev/null
@@ -1,270 +0,0 @@
-# frozen_string_literal: false
-#
-# utils.rb -- Miscellaneous utilities
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
-# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: utils.rb,v 1.10 2003/02/16 22:22:54 gotoyuzo Exp $
-
-require 'socket'
-require 'io/nonblock'
-require 'etc'
-
-module WEBrick
- module Utils
- ##
- # Sets IO operations on +io+ to be non-blocking
- def set_non_blocking(io)
- io.nonblock = true if io.respond_to?(:nonblock=)
- end
- module_function :set_non_blocking
-
- ##
- # Sets the close on exec flag for +io+
- def set_close_on_exec(io)
- io.close_on_exec = true if io.respond_to?(:close_on_exec=)
- end
- module_function :set_close_on_exec
-
- ##
- # Changes the process's uid and gid to the ones of +user+
- def su(user)
- if pw = Etc.getpwnam(user)
- Process::initgroups(user, pw.gid)
- Process::Sys::setgid(pw.gid)
- Process::Sys::setuid(pw.uid)
- else
- warn("WEBrick::Utils::su doesn't work on this platform")
- end
- end
- module_function :su
-
- ##
- # The server hostname
- def getservername
- host = Socket::gethostname
- begin
- Socket::gethostbyname(host)[0]
- rescue
- host
- end
- end
- module_function :getservername
-
- ##
- # Creates TCP server sockets bound to +address+:+port+ and returns them.
- #
- # It will create IPV4 and IPV6 sockets on all interfaces.
- def create_listeners(address, port)
- unless port
- raise ArgumentError, "must specify port"
- end
- sockets = Socket.tcp_server_sockets(address, port)
- sockets = sockets.map {|s|
- s.autoclose = false
- ts = TCPServer.for_fd(s.fileno)
- s.close
- ts
- }
- return sockets
- end
- module_function :create_listeners
-
- ##
- # Characters used to generate random strings
- RAND_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
- "0123456789" +
- "abcdefghijklmnopqrstuvwxyz"
-
- ##
- # Generates a random string of length +len+
- def random_string(len)
- rand_max = RAND_CHARS.bytesize
- ret = ""
- len.times{ ret << RAND_CHARS[rand(rand_max)] }
- ret
- end
- module_function :random_string
-
- ###########
-
- require "timeout"
- require "singleton"
-
- ##
- # Class used to manage timeout handlers across multiple threads.
- #
- # Timeout handlers should be managed by using the class methods which are
- # synchronized.
- #
- # id = TimeoutHandler.register(10, Timeout::Error)
- # begin
- # sleep 20
- # puts 'foo'
- # ensure
- # TimeoutHandler.cancel(id)
- # end
- #
- # will raise Timeout::Error
- #
- # id = TimeoutHandler.register(10, Timeout::Error)
- # begin
- # sleep 5
- # puts 'foo'
- # ensure
- # TimeoutHandler.cancel(id)
- # end
- #
- # will print 'foo'
- #
- class TimeoutHandler
- include Singleton
-
- ##
- # Mutex used to synchronize access across threads
- TimeoutMutex = Thread::Mutex.new # :nodoc:
-
- ##
- # Registers a new timeout handler
- #
- # +time+:: Timeout in seconds
- # +exception+:: Exception to raise when timeout elapsed
- def TimeoutHandler.register(seconds, exception)
- at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + seconds
- instance.register(Thread.current, at, exception)
- end
-
- ##
- # Cancels the timeout handler +id+
- def TimeoutHandler.cancel(id)
- instance.cancel(Thread.current, id)
- end
-
- def self.terminate
- instance.terminate
- end
-
- ##
- # Creates a new TimeoutHandler. You should use ::register and ::cancel
- # instead of creating the timeout handler directly.
- def initialize
- TimeoutMutex.synchronize{
- @timeout_info = Hash.new
- }
- @queue = Thread::Queue.new
- @watcher = nil
- end
-
- # :nodoc:
- private \
- def watch
- to_interrupt = []
- while true
- now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- wakeup = nil
- to_interrupt.clear
- TimeoutMutex.synchronize{
- @timeout_info.each {|thread, ary|
- next unless ary
- ary.each{|info|
- time, exception = *info
- if time < now
- to_interrupt.push [thread, info.object_id, exception]
- elsif !wakeup || time < wakeup
- wakeup = time
- end
- }
- }
- }
- to_interrupt.each {|arg| interrupt(*arg)}
- if !wakeup
- @queue.pop
- elsif (wakeup -= now) > 0
- begin
- (th = Thread.start {@queue.pop}).join(wakeup)
- ensure
- th&.kill&.join
- end
- end
- @queue.clear
- end
- end
-
- # :nodoc:
- private \
- def watcher
- (w = @watcher)&.alive? and return w # usual case
- TimeoutMutex.synchronize{
- (w = @watcher)&.alive? and next w # pathological check
- @watcher = Thread.start(&method(:watch))
- }
- end
-
- ##
- # Interrupts the timeout handler +id+ and raises +exception+
- def interrupt(thread, id, exception)
- if cancel(thread, id) && thread.alive?
- thread.raise(exception, "execution timeout")
- end
- end
-
- ##
- # Registers a new timeout handler
- #
- # +time+:: Timeout in seconds
- # +exception+:: Exception to raise when timeout elapsed
- def register(thread, time, exception)
- info = nil
- TimeoutMutex.synchronize{
- (@timeout_info[thread] ||= []) << (info = [time, exception])
- }
- @queue.push nil
- watcher
- return info.object_id
- end
-
- ##
- # Cancels the timeout handler +id+
- def cancel(thread, id)
- TimeoutMutex.synchronize{
- if ary = @timeout_info[thread]
- ary.delete_if{|info| info.object_id == id }
- if ary.empty?
- @timeout_info.delete(thread)
- end
- return true
- end
- return false
- }
- end
-
- ##
- def terminate
- TimeoutMutex.synchronize{
- @timeout_info.clear
- @watcher&.kill&.join
- }
- end
- end
-
- ##
- # Executes the passed block and raises +exception+ if execution takes more
- # than +seconds+.
- #
- # If +seconds+ is zero or nil, simply executes the block
- def timeout(seconds, exception=Timeout::Error)
- return yield if seconds.nil? or seconds.zero?
- # raise ThreadError, "timeout within critical session" if Thread.critical
- id = TimeoutHandler.register(seconds, exception)
- begin
- yield(seconds)
- ensure
- TimeoutHandler.cancel(id)
- end
- end
- module_function :timeout
- end
-end
diff --git a/lib/webrick/version.rb b/lib/webrick/version.rb
deleted file mode 100644
index d9b9f877a2..0000000000
--- a/lib/webrick/version.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: false
-#--
-# version.rb -- version and release date
-#
-# Author: IPR -- Internet Programming with Ruby -- writers
-# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
-# Copyright (c) 2003 Internet Programming with Ruby writers. All rights
-# reserved.
-#
-# $IPR: version.rb,v 1.74 2003/07/22 19:20:43 gotoyuzo Exp $
-
-module WEBrick
-
- ##
- # The WEBrick version
-
- VERSION = "1.4.0.beta1"
-end
diff --git a/lib/webrick/webrick.gemspec b/lib/webrick/webrick.gemspec
deleted file mode 100644
index 34821b8ac5..0000000000
--- a/lib/webrick/webrick.gemspec
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
-require 'webrick/version'
-
-Gem::Specification.new do |s|
- s.name = "webrick"
- s.version = WEBrick::VERSION
- s.date = '2017-05-01'
- s.summary = "HTTP server toolkit"
- s.description = "WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server."
-
- s.require_path = %w{lib}
- s.files = ["lib/webrick.rb", "lib/webrick/accesslog.rb", "lib/webrick/cgi.rb", "lib/webrick/compat.rb", "lib/webrick/config.rb", "lib/webrick/cookie.rb", "lib/webrick/htmlutils.rb", "lib/webrick/httpauth.rb", "lib/webrick/httpauth/authenticator.rb", "lib/webrick/httpauth/basicauth.rb", "lib/webrick/httpauth/digestauth.rb", "lib/webrick/httpauth/htdigest.rb", "lib/webrick/httpauth/htgroup.rb", "lib/webrick/httpauth/htpasswd.rb", "lib/webrick/httpauth/userdb.rb", "lib/webrick/httpauth.rb", "lib/webrick/httpproxy.rb", "lib/webrick/httprequest.rb", "lib/webrick/httpresponse.rb", "lib/webrick/https.rb", "lib/webrick/httpserver.rb", "lib/webrick/httpservlet.rb", "lib/webrick/httpservlet/abstract.rb", "lib/webrick/httpservlet/cgi_runner.rb", "lib/webrick/httpservlet/cgihandler.rb", "lib/webrick/httpservlet/erbhandler.rb", "lib/webrick/httpservlet/filehandler.rb", "lib/webrick/httpservlet/prochandler.rb", "lib/webrick/httpservlet.rb", "lib/webrick/httpstatus.rb", "lib/webrick/httputils.rb", "lib/webrick/httpversion.rb", "lib/webrick/log.rb", "lib/webrick/server.rb", "lib/webrick/ssl.rb", "lib/webrick/utils.rb", "lib/webrick/version.rb"]
- s.required_ruby_version = ">= 2.5.0dev"
-
- s.authors = ["TAKAHASHI Masayoshi", "GOTOU YUUZOU"]
- s.email = [nil, nil]
- s.homepage = "https://www.ruby-lang.org"
- s.license = "BSD-2-Clause"
-
- if s.respond_to?(:metadata=)
- s.metadata = {
- "bug_tracker_uri" => "https://bugs.ruby-lang.org/projects/ruby-trunk/issues",
- "homepage_uri" => "https://www.ruby-lang.org",
- "source_code_uri" => "https://svn.ruby-lang.org/repos/ruby"
- }
- end
-
- s.add_development_dependency "rake"
-end
diff --git a/lib/yaml.rb b/lib/yaml.rb
index 0c33305e1d..17b27e802f 100644
--- a/lib/yaml.rb
+++ b/lib/yaml.rb
@@ -1,13 +1,11 @@
# frozen_string_literal: false
-##
-# The YAML module is an alias of Psych, the YAML engine for Ruby.
begin
require 'psych'
rescue LoadError
- warn "#{caller[0]}:"
- warn "It seems your ruby installation is missing psych (for YAML output)."
- warn "To eliminate this warning, please install libyaml and reinstall your ruby."
+ warn "It seems your ruby installation is missing psych (for YAML output).\n" \
+ "To eliminate this warning, please install libyaml and reinstall your ruby.\n",
+ uplevel: 1
raise
end
@@ -17,7 +15,7 @@ YAML = Psych # :nodoc:
#
# This module provides a Ruby interface for data serialization in YAML format.
#
-# The underlying implementation is the libyaml wrapper Psych.
+# The YAML module is an alias of Psych, the YAML engine for Ruby.
#
# == Usage
#
@@ -31,6 +29,9 @@ YAML = Psych # :nodoc:
# YAML.dump("foo") # => "--- foo\n...\n"
# { :a => 'b'}.to_yaml # => "---\n:a: b\n"
#
+# As the implementation is provided by the Psych library, detailed documentation
+# can be found in that library's docs (also part of standard library).
+#
# == Security
#
# Do not use YAML to load untrusted data. Doing so is unsafe and could allow
@@ -39,7 +40,7 @@ YAML = Psych # :nodoc:
#
# == History
#
-# Syck was the original for YAML implementation in Ruby's standard library
+# Syck was the original YAML implementation in Ruby's standard library
# developed by why the lucky stiff.
#
# You can still use Syck, if you prefer, for parsing and emitting YAML, but you
@@ -53,8 +54,8 @@ YAML = Psych # :nodoc:
# For more advanced details on the implementation see Psych, and also check out
# http://yaml.org for spec details and other helpful information.
#
-# Psych is maintained by Aaron Patterson on github: https://github.com/tenderlove/psych
+# Psych is maintained by Aaron Patterson on github: https://github.com/ruby/psych
#
-# Syck can also be found on github: https://github.com/tenderlove/syck
+# Syck can also be found on github: https://github.com/ruby/syck
module YAML
end
diff --git a/lib/yaml/yaml.gemspec b/lib/yaml/yaml.gemspec
new file mode 100644
index 0000000000..cf19b0e0da
--- /dev/null
+++ b/lib/yaml/yaml.gemspec
@@ -0,0 +1,23 @@
+Gem::Specification.new do |spec|
+ spec.name = "yaml"
+ spec.version = "0.1.1"
+ spec.authors = ["Aaron Patterson", "SHIBATA Hiroshi"]
+ spec.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org"]
+
+ spec.summary = "YAML Ain't Markup Language"
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/yaml"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/libexec/bundle b/libexec/bundle
new file mode 100755
index 0000000000..1168e5a361
--- /dev/null
+++ b/libexec/bundle
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+# Exit cleanly from an early interrupt
+Signal.trap("INT") do
+ Bundler.ui.debug("\n#{caller.join("\n")}") if defined?(Bundler)
+ exit 1
+end
+
+base_path = File.expand_path("../lib", __dir__)
+
+if File.exist?(base_path)
+ require_relative "../lib/bundler"
+else
+ require "bundler"
+end
+
+# Workaround for non-activated bundler spec due to missing https://github.com/rubygems/rubygems/commit/4e306d7bcdee924b8d80ca9db6125aa59ee4e5a3
+gem "bundler", Bundler::VERSION if Gem.rubygems_version < Gem::Version.new("2.6.2")
+
+# Check if an older version of bundler is installed
+$LOAD_PATH.each do |path|
+ next unless path =~ %r{/bundler-0\.(\d+)} && $1.to_i < 9
+ err = String.new
+ err << "Looks like you have a version of bundler that's older than 0.9.\n"
+ err << "Please remove your old versions.\n"
+ err << "An easy way to do this is by running `gem cleanup bundler`."
+ abort(err)
+end
+
+if File.exist?(base_path)
+ require_relative "../lib/bundler/friendly_errors"
+else
+ require "bundler/friendly_errors"
+end
+
+Bundler.with_friendly_errors do
+ if File.exist?(base_path)
+ require_relative "../lib/bundler/cli"
+ else
+ require "bundler/cli"
+ end
+
+ # Allow any command to use --help flag to show help for that command
+ help_flags = %w[--help -h]
+ help_flag_used = ARGV.any? {|a| help_flags.include? a }
+ args = help_flag_used ? Bundler::CLI.reformatted_help_args(ARGV) : ARGV
+
+ Bundler::CLI.start(args, :debug => true)
+end
diff --git a/libexec/bundler b/libexec/bundler
new file mode 100755
index 0000000000..d9131fe834
--- /dev/null
+++ b/libexec/bundler
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+load File.expand_path("../bundle", __FILE__)
diff --git a/libexec/erb b/libexec/erb
new file mode 100755
index 0000000000..ded76991dc
--- /dev/null
+++ b/libexec/erb
@@ -0,0 +1,174 @@
+#!/usr/bin/env ruby
+# Tiny eRuby --- ERB2
+# Copyright (c) 1999-2000,2002 Masatoshi SEKI
+# You can redistribute it and/or modify it under the same terms as Ruby.
+
+require 'erb'
+
+class ERB
+ module Main
+ def ARGV.switch
+ return nil if self.empty?
+ arg = self.shift
+ return nil if arg == '--'
+ case arg
+ when /\A-(.)(.*)/
+ if $1 == '-'
+ arg, @maybe_arg = arg.split(/=/, 2)
+ return arg
+ end
+ raise 'unknown switch "-"' if $2[0] == ?- and $1 != 'T'
+ if $2.size > 0
+ self.unshift "-#{$2}"
+ @maybe_arg = $2
+ else
+ @maybe_arg = nil
+ end
+ "-#{$1}"
+ when /\A(\w+)=/
+ arg
+ else
+ self.unshift arg
+ nil
+ end
+ end
+
+ def ARGV.req_arg
+ (@maybe_arg || self.shift || raise('missing argument')).tap {
+ @maybe_arg = nil
+ }
+ end
+
+ def trim_mode_opt(trim_mode, disable_percent)
+ return trim_mode if disable_percent
+ case trim_mode
+ when 0
+ return '%'
+ when 1
+ return '%>'
+ when 2
+ return '%<>'
+ when '-'
+ return '%-'
+ end
+ end
+ module_function :trim_mode_opt
+
+ def run(factory=ERB)
+ trim_mode = 0
+ disable_percent = false
+ variables = {}
+ begin
+ while switch = ARGV.switch
+ case switch
+ when '-x' # ruby source
+ output = true
+ when '-n' # line number
+ number = true
+ when '-v' # verbose
+ $VERBOSE = true
+ when '--version' # version
+ STDERR.puts factory.version
+ exit
+ when '-d', '--debug' # debug
+ $DEBUG = true
+ when '-r' # require
+ require ARGV.req_arg
+ when '-S' # security level
+ warn 'warning: -S option of erb command is deprecated. Please do not use this.'
+ arg = ARGV.req_arg
+ raise "invalid safe_level #{arg.dump}" unless arg =~ /\A[0-1]\z/
+ safe_level = arg.to_i
+ when '-T' # trim mode
+ arg = ARGV.req_arg
+ if arg == '-'
+ trim_mode = arg
+ next
+ end
+ raise "invalid trim mode #{arg.dump}" unless arg =~ /\A[0-2]\z/
+ trim_mode = arg.to_i
+ when '-E', '--encoding'
+ arg = ARGV.req_arg
+ set_encoding(*arg.split(/:/, 2))
+ when '-U'
+ set_encoding(Encoding::UTF_8, Encoding::UTF_8)
+ when '-P'
+ disable_percent = true
+ when '--help'
+ raise "print this help"
+ when /\A-/
+ raise "unknown switch #{switch.dump}"
+ else
+ var, val = *switch.split('=', 2)
+ (variables ||= {})[var] = val
+ end
+ end
+ rescue # usage
+ STDERR.puts $!.to_s
+ STDERR.puts File.basename($0) +
+ " [switches] [var=value...] [inputfile]"
+ STDERR.puts <<EOU
+ -x print ruby script
+ -n print ruby script with line number
+ -v enable verbose mode
+ -d set $DEBUG to true
+ -r library load a library
+ -E ex[:in] set default external/internal encodings
+ -U set default encoding to UTF-8
+ -T trim_mode specify trim_mode (0..2, -)
+ -P disable ruby code evaluation for lines beginning with %
+ var=value set variable
+EOU
+ exit 1
+ end
+
+ $<.set_encoding(Encoding::UTF_8, nil)
+ src = $<.read
+ filename = $FILENAME
+ exit 2 unless src
+ trim = trim_mode_opt(trim_mode, disable_percent)
+ if safe_level.nil?
+ erb = factory.new(src, trim_mode: trim)
+ else
+ # [deprecated] This will be removed at Ruby 2.7.
+ erb = factory.new(src, safe_level, trim_mode: trim)
+ end
+ erb.filename = filename
+ if output
+ if number
+ erb.src.each_line.with_index do |line, l|
+ puts "%3d %s"%[l+1, line]
+ end
+ else
+ puts erb.src
+ end
+ else
+ bind = TOPLEVEL_BINDING
+ if variables
+ enc = erb.encoding
+ for var, val in variables do
+ val = val.encode(enc) if val
+ bind.local_variable_set(var, val)
+ end
+ end
+ erb.run(bind)
+ end
+ end
+ module_function :run
+
+ def set_encoding(extern, intern = nil)
+ verbose, $VERBOSE = $VERBOSE, nil
+ Encoding.default_external = extern unless extern.nil? || extern == ""
+ Encoding.default_internal = intern unless intern.nil? || intern == ""
+ [$stdin, $stdout, $stderr].each do |io|
+ io.set_encoding(extern, intern)
+ end
+ ensure
+ $VERBOSE = verbose
+ end
+ module_function :set_encoding
+ class << self; private :set_encoding; end
+ end
+end
+
+ERB::Main.run
diff --git a/libexec/irb b/libexec/irb
new file mode 100755
index 0000000000..c64ee85fbd
--- /dev/null
+++ b/libexec/irb
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+#
+# irb.rb - interactive ruby
+# $Release Version: 0.9.6 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+
+require "irb"
+
+IRB.start(__FILE__)
diff --git a/libexec/racc b/libexec/racc
new file mode 100755
index 0000000000..4507d04962
--- /dev/null
+++ b/libexec/racc
@@ -0,0 +1,320 @@
+#!/usr/bin/env ruby
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+
+require 'racc/static'
+require 'optparse'
+
+def main
+ output = nil
+ debug_parser = false
+ make_logfile = false
+ logfilename = nil
+ make_executable = false
+ rubypath = nil
+ embed_runtime = false
+ debug_flags = Racc::DebugFlags.new
+ line_convert = true
+ line_convert_all = false
+ omit_action_call = true
+ superclass = nil
+ check_only = false
+ verbose = false
+ profiler = RaccProfiler.new(false)
+
+ parser = OptionParser.new
+ parser.banner = "Usage: #{File.basename($0)} [options] <input>"
+ parser.on('-o', '--output-file=PATH',
+ 'output file name [<input>.tab.rb]') {|name|
+ output = name
+ }
+ parser.on('-t', '--debug', 'Outputs debugging parser.') {|fl|
+ debug_parser = fl
+ }
+ parser.on('-g', 'Equivalent to -t (obsolete).') {|fl|
+ $stderr.puts "racc -g is obsolete. Use racc -t instead." if $VERBOSE
+ debug_parser = fl
+ }
+ parser.on('-v', '--verbose',
+ 'Creates <filename>.output log file.') {|fl|
+ make_logfile = fl
+ }
+ parser.on('-O', '--log-file=PATH',
+ 'Log file name [<input>.output]') {|path|
+ make_logfile = true
+ logfilename = path
+ }
+ parser.on('-e', '--executable [RUBYPATH]', 'Makes executable parser.') {|path|
+ make_executable = true
+ rubypath = (path == 'ruby' ? nil : path)
+ }
+ parser.on('-E', '--embedded', "Embeds Racc runtime in output.") {
+ embed_runtime = true
+ }
+ parser.on('--line-convert-all', 'Converts line numbers of user codes.') {
+ line_convert_all = true
+ }
+ parser.on('-l', '--no-line-convert', 'Never convert line numbers.') {
+ line_convert = false
+ line_convert_all = false
+ }
+ parser.on('-a', '--no-omit-actions', 'Never omit actions.') {
+ omit_action_call = false
+ }
+ parser.on('--superclass=CLASSNAME',
+ 'Uses CLASSNAME instead of Racc::Parser.') {|name|
+ superclass = name
+ }
+ parser.on('-C', '--check-only', 'Checks syntax and quit immediately.') {|fl|
+ check_only = fl
+ }
+ parser.on('-S', '--output-status', 'Outputs internal status time to time.') {
+ verbose = true
+ }
+ parser.on('-P', 'Enables generator profile') {
+ profiler = RaccProfiler.new(true)
+ }
+ parser.on('-D flags', "Flags for Racc debugging (do not use).") {|flags|
+ debug_flags = Racc::DebugFlags.parse_option_string(flags)
+ }
+ #parser.on('--no-extensions', 'Run Racc without any Ruby extension.') {
+ # Racc.const_set :Racc_No_Extensions, true
+ #}
+ parser.on('--version', 'Prints version and quit.') {
+ puts "racc version #{Racc::Version}"
+ exit 0
+ }
+ parser.on('--runtime-version', 'Prints runtime version and quit.') {
+ printf "racc runtime version %s; %s\n",
+ Racc::Parser::Racc_Runtime_Version,
+ if Racc::Parser.racc_runtime_type == 'ruby'
+ sprintf('ruby core version %s',
+ Racc::Parser::Racc_Runtime_Core_Version_R)
+ else
+ sprintf('c core version %s',
+ Racc::Parser::Racc_Runtime_Core_Version_C)
+ end
+ exit 0
+ }
+ parser.on('--copyright', 'Prints copyright and quit.') {
+ puts Racc::Copyright
+ exit 0
+ }
+ parser.on('--help', 'Prints this message and quit.') {
+ puts parser.help
+ exit 1
+ }
+ begin
+ parser.parse!
+ rescue OptionParser::ParseError => err
+ $stderr.puts err.message
+ $stderr.puts parser.help
+ exit 1
+ end
+ if ARGV.empty?
+ $stderr.puts 'no input'
+ exit 1
+ end
+ if ARGV.size > 1
+ $stderr.puts 'too many input'
+ exit 1
+ end
+ input = ARGV[0]
+
+ begin
+ $stderr.puts 'Parsing grammar file...' if verbose
+ result = profiler.section('parse') {
+ parser = Racc::GrammarFileParser.new(debug_flags)
+ parser.parse(File.read(input), File.basename(input))
+ }
+ if check_only
+ $stderr.puts 'syntax ok'
+ exit 0
+ end
+
+ $stderr.puts 'Generating LALR states...' if verbose
+ states = profiler.section('nfa') {
+ Racc::States.new(result.grammar).nfa
+ }
+
+ $stderr.puts "Resolving #{states.size} states..." if verbose
+ profiler.section('dfa') {
+ states.dfa
+ }
+
+ $stderr.puts 'Creating parser file...' if verbose
+ params = result.params.dup
+ # Overwrites parameters given by a grammar file with command line options.
+ params.superclass = superclass if superclass
+ params.omit_action_call = true if omit_action_call
+ # From command line option
+ if make_executable
+ params.make_executable = true
+ params.interpreter = rubypath
+ end
+ params.debug_parser = debug_parser
+ params.convert_line = line_convert
+ params.convert_line_all = line_convert_all
+ params.embed_runtime = embed_runtime
+ profiler.section('generation') {
+ generator = Racc::ParserFileGenerator.new(states, params)
+ generator.generate_parser_file(output || make_filename(input, '.tab.rb'))
+ }
+
+ if make_logfile
+ profiler.section('logging') {
+ $stderr.puts 'Creating log file...' if verbose
+ logfilename ||= make_filename(output || File.basename(input), '.output')
+ File.open(logfilename, 'w') {|f|
+ Racc::LogFileGenerator.new(states, debug_flags).output f
+ }
+ }
+ end
+ if debug_flags.status_logging
+ log_useless states.grammar
+ log_conflict states
+ else
+ has_useless = report_useless states.grammar
+ has_conflicts = report_conflict states
+ if has_useless || has_conflicts
+ preamble = make_logfile ? 'C' : 'Turn on logging with "-v" and c'
+ $stderr.puts %Q{#{preamble}heck ".output" file for details}
+ end
+ end
+
+ profiler.report
+ rescue Racc::Error, Errno::ENOENT, Errno::EPERM => err
+ raise if $DEBUG or debug_flags.any?
+ lineno = err.message.slice(/\A\d+:/).to_s
+ $stderr.puts "#{File.basename $0}: #{input}:#{lineno} #{err.message.strip}"
+ exit 1
+ end
+end
+
+def make_filename(path, suffix)
+ path.sub(/(?:\..*?)?\z/, suffix)
+end
+
+LIST_LIMIT = 10
+def report_list(enum, label)
+ c = enum.count
+ if c > 0
+ $stderr.puts "#{c} #{label}:"
+ enum.first(LIST_LIMIT).each do |item|
+ $stderr.puts " #{yield item}"
+ end
+ $stderr.puts " ..." if c > LIST_LIMIT
+ end
+end
+
+# @return [Boolean] if anything was reported
+def report_conflict(states)
+ if states.should_report_srconflict?
+ reported = true
+ $stderr.puts "#{states.n_srconflicts} shift/reduce conflicts"
+ end
+ if states.rrconflict_exist?
+ reported = true
+ $stderr.puts "#{states.n_rrconflicts} reduce/reduce conflicts"
+ end
+ reported
+end
+
+def log_conflict(states)
+ logging('w') {|f|
+ f.puts "ex#{states.grammar.n_expected_srconflicts}"
+ if states.should_report_srconflict?
+ f.puts "sr#{states.n_srconflicts}"
+ end
+ if states.rrconflict_exist?
+ f.puts "rr#{states.n_rrconflicts}"
+ end
+ }
+end
+
+# @return [Boolean] if anything was reported
+def report_useless(grammar)
+ reported = report_list(grammar.each_useless_nonterminal, 'useless nonterminals', &:to_s)
+
+ reported ||= report_list(grammar.each_useless_rule, 'useless rules') { |r| "##{r.ident} (#{r.target})" }
+
+ if grammar.start.useless?
+ $stderr.puts 'fatal: start symbol does not derive any sentence'
+ reported = true
+ end
+ reported
+end
+
+def log_useless(grammar)
+ logging('a') {|f|
+ if grammar.useless_nonterminal_exist?
+ f.puts "un#{grammar.n_useless_nonterminals}"
+ end
+ if grammar.useless_rule_exist?
+ f.puts "ur#{grammar.n_useless_rules}"
+ end
+ }
+end
+
+def logging(mode, &block)
+ File.open("log/#{File.basename(ARGV[0])}", mode, &block)
+end
+
+class RaccProfiler
+ def initialize(really)
+ @really = really
+ @log = []
+ unless ::Process.respond_to?(:times)
+ # Ruby 1.6
+ @class = ::Time
+ else
+ @class = ::Process
+ end
+ end
+
+ def section(name)
+ if @really
+ t1 = @class.times.utime
+ result = yield
+ t2 = @class.times.utime
+ @log.push [name, t2 - t1]
+ result
+ else
+ yield
+ end
+ end
+
+ def report
+ return unless @really
+ f = $stderr
+ total = cumulative_time()
+ f.puts '--task-----------+--sec------+---%-'
+ @log.each do |name, time|
+ f.printf "%-19s %s %3d%%\n", name, pjust(time,4,4), (time/total*100).to_i
+ end
+ f.puts '-----------------+-----------+-----'
+ f.printf "%-20s%s\n", 'total', pjust(total,4,4)
+ end
+
+ private
+
+ def cumulative_time
+ t = @log.inject(0) {|sum, (name, time)| sum + time }
+ t == 0 ? 0.01 : t
+ end
+
+ def pjust(num, i, j)
+ m = /(\d+)(\.\d+)?/.match(num.to_s)
+ str = m[1].rjust(i)
+ str.concat m[2].ljust(j+1)[0,j+1] if m[2]
+ str
+ end
+end
+
+main
diff --git a/libexec/rdoc b/libexec/rdoc
new file mode 100755
index 0000000000..aaa23292df
--- /dev/null
+++ b/libexec/rdoc
@@ -0,0 +1,44 @@
+#!/usr/bin/env ruby
+#
+# RDoc: Documentation tool for source code
+# (see lib/rdoc/rdoc.rb for more information)
+#
+# Copyright (c) 2003 Dave Thomas
+# Released under the same terms as Ruby
+
+begin
+ gem 'rdoc'
+rescue NameError => e # --disable-gems
+ raise unless e.name == :gem
+rescue Gem::LoadError
+end
+
+require 'rdoc/rdoc'
+
+begin
+ r = RDoc::RDoc.new
+ r.document ARGV
+rescue Errno::ENOSPC
+ $stderr.puts 'Ran out of space creating documentation'
+ $stderr.puts
+ $stderr.puts 'Please free up some space and try again'
+rescue SystemExit
+ raise
+rescue Exception => e
+ if $DEBUG_RDOC then
+ $stderr.puts e.message
+ $stderr.puts "#{e.backtrace.join "\n\t"}"
+ $stderr.puts
+ elsif Interrupt === e then
+ $stderr.puts
+ $stderr.puts 'Interrupted'
+ else
+ $stderr.puts "uh-oh! RDoc had a problem:"
+ $stderr.puts e.message
+ $stderr.puts
+ $stderr.puts "run with --debug for full backtrace"
+ end
+
+ exit 1
+end
+
diff --git a/libexec/ri b/libexec/ri
new file mode 100755
index 0000000000..7fbed0c099
--- /dev/null
+++ b/libexec/ri
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+
+begin
+ gem 'rdoc'
+rescue NameError => e # --disable-gems
+ raise unless e.name == :gem
+rescue Gem::LoadError
+end
+
+require 'rdoc/ri/driver'
+
+RDoc::RI::Driver.run ARGV
diff --git a/load.c b/load.c
index d2ed55fed2..3dcc40bbe9 100644
--- a/load.c
+++ b/load.c
@@ -2,11 +2,20 @@
* load methods from eval.c
*/
-#include "internal.h"
-#include "ruby/util.h"
#include "dln.h"
#include "eval_intern.h"
+#include "internal.h"
+#include "internal/dir.h"
+#include "internal/error.h"
+#include "internal/file.h"
+#include "internal/load.h"
+#include "internal/parse.h"
+#include "internal/thread.h"
+#include "internal/variable.h"
+#include "iseq.h"
#include "probes.h"
+#include "ruby/encoding.h"
+#include "ruby/util.h"
static VALUE ruby_dln_librefs;
@@ -26,12 +35,10 @@ static const char *const loadable_ext[] = {
0
};
-VALUE
-rb_get_load_path(void)
-{
- VALUE load_path = GET_VM()->load_path;
- return load_path;
-}
+static const char *const ruby_ext[] = {
+ ".rb",
+ 0
+};
enum expand_type {
EXPAND_ALL,
@@ -53,7 +60,6 @@ rb_construct_expanded_load_path(enum expand_type type, int *has_relative, int *h
VALUE expanded_load_path = vm->expanded_load_path;
VALUE ary;
long i;
- int level = rb_safe_level();
ary = rb_ary_tmp_new(RARRAY_LEN(load_path));
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
@@ -63,7 +69,7 @@ rb_construct_expanded_load_path(enum expand_type type, int *has_relative, int *h
as_str = path = RARRAY_AREF(load_path, i);
is_string = RB_TYPE_P(path, T_STRING) ? 1 : 0;
non_cache = !is_string ? 1 : 0;
- as_str = rb_get_path_check_to_string(path, level);
+ as_str = rb_get_path_check_to_string(path);
as_cstr = RSTRING_PTR(as_str);
if (!non_cache) {
@@ -84,8 +90,8 @@ rb_construct_expanded_load_path(enum expand_type type, int *has_relative, int *h
/* Freeze only string object. We expand other objects every time. */
if (is_string)
rb_str_freeze(path);
- as_str = rb_get_path_check_convert(path, as_str, level);
- expanded_path = rb_check_realpath(Qnil, as_str);
+ as_str = rb_get_path_check_convert(as_str);
+ expanded_path = rb_check_realpath(Qnil, as_str, NULL);
if (NIL_P(expanded_path)) expanded_path = as_str;
rb_ary_push(ary, rb_fstring(expanded_path));
}
@@ -94,15 +100,6 @@ rb_construct_expanded_load_path(enum expand_type type, int *has_relative, int *h
rb_ary_replace(vm->load_path_snapshot, vm->load_path);
}
-static VALUE
-load_path_getcwd(void)
-{
- char *cwd = my_getcwd();
- VALUE cwd_str = rb_filesystem_str_new_cstr(cwd);
- xfree(cwd);
- return cwd_str;
-}
-
VALUE
rb_get_expanded_load_path(void)
{
@@ -114,7 +111,7 @@ rb_get_expanded_load_path(void)
int has_relative = 0, has_non_cache = 0;
rb_construct_expanded_load_path(EXPAND_ALL, &has_relative, &has_non_cache);
if (has_relative) {
- vm->load_path_check_cache = load_path_getcwd();
+ vm->load_path_check_cache = rb_dir_getwd_ospath();
}
else if (has_non_cache) {
/* Non string object. */
@@ -132,7 +129,7 @@ rb_get_expanded_load_path(void)
}
else if (vm->load_path_check_cache) {
int has_relative = 1, has_non_cache = 1;
- VALUE cwd = load_path_getcwd();
+ VALUE cwd = rb_dir_getwd_ospath();
if (!rb_str_equal(vm->load_path_check_cache, cwd)) {
/* Current working directory or filesystem encoding was changed.
Expand relative load path and non-cacheable objects again. */
@@ -150,8 +147,9 @@ rb_get_expanded_load_path(void)
}
static VALUE
-load_path_getter(ID id, rb_vm_t *vm)
+load_path_getter(ID id, VALUE * p)
{
+ rb_vm_t *vm = (void *)p;
return vm->load_path;
}
@@ -161,6 +159,12 @@ get_loaded_features(void)
return GET_VM()->loaded_features;
}
+static VALUE
+get_LOADED_FEATURES(ID _x, VALUE *_y)
+{
+ return get_loaded_features();
+}
+
static void
reset_loaded_features_snapshot(void)
{
@@ -180,35 +184,75 @@ get_loading_table(void)
return GET_VM()->loading_table;
}
+static st_data_t
+feature_key(const char *str, size_t len)
+{
+ return st_hash(str, len, 0xfea7009e);
+}
+
+static bool
+is_rbext_path(VALUE feature_path)
+{
+ long len = RSTRING_LEN(feature_path);
+ long rbext_len = rb_strlen_lit(".rb");
+ if (len <= rbext_len) return false;
+ return IS_RBEXT(RSTRING_PTR(feature_path) + len - rbext_len);
+}
+
static void
-features_index_add_single(VALUE short_feature, VALUE offset)
+features_index_add_single(const char* str, size_t len, VALUE offset, bool rb)
{
struct st_table *features_index;
VALUE this_feature_index = Qnil;
- char *short_feature_cstr;
+ st_data_t short_feature_key;
Check_Type(offset, T_FIXNUM);
- Check_Type(short_feature, T_STRING);
- short_feature_cstr = StringValueCStr(short_feature);
+ short_feature_key = feature_key(str, len);
features_index = get_loaded_features_index_raw();
- st_lookup(features_index, (st_data_t)short_feature_cstr, (st_data_t *)&this_feature_index);
+ st_lookup(features_index, short_feature_key, (st_data_t *)&this_feature_index);
if (NIL_P(this_feature_index)) {
- st_insert(features_index, (st_data_t)ruby_strdup(short_feature_cstr), (st_data_t)offset);
+ st_insert(features_index, short_feature_key, (st_data_t)offset);
}
else if (RB_TYPE_P(this_feature_index, T_FIXNUM)) {
+ VALUE loaded_features = get_loaded_features();
+ VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(this_feature_index));
VALUE feature_indexes[2];
- feature_indexes[0] = this_feature_index;
- feature_indexes[1] = offset;
+ int top = (rb && !is_rbext_path(this_feature_path)) ? 1 : 0;
+ feature_indexes[top^0] = this_feature_index;
+ feature_indexes[top^1] = offset;
this_feature_index = (VALUE)xcalloc(1, sizeof(struct RArray));
RBASIC(this_feature_index)->flags = T_ARRAY; /* fake VALUE, do not mark/sweep */
rb_ary_cat(this_feature_index, feature_indexes, numberof(feature_indexes));
- st_insert(features_index, (st_data_t)short_feature_cstr, (st_data_t)this_feature_index);
+ st_insert(features_index, short_feature_key, (st_data_t)this_feature_index);
}
else {
+ long pos = -1;
+
Check_Type(this_feature_index, T_ARRAY);
+ if (rb) {
+ VALUE loaded_features = get_loaded_features();
+ for (long i = 0; i < RARRAY_LEN(this_feature_index); ++i) {
+ VALUE idx = RARRAY_AREF(this_feature_index, i);
+ VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(idx));
+ Check_Type(this_feature_path, T_STRING);
+ if (!is_rbext_path(this_feature_path)) {
+ /* as this_feature_index is a fake VALUE, `push` (which
+ * doesn't wb_unprotect like as rb_ary_splice) first,
+ * then rotate partially. */
+ pos = i;
+ break;
+ }
+ }
+ }
rb_ary_push(this_feature_index, offset);
+ if (pos >= 0) {
+ VALUE *ptr = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(this_feature_index);
+ long len = RARRAY_LEN(this_feature_index);
+ MEMMOVE(ptr + pos, ptr + pos + 1, VALUE, len - pos - 1);
+ ptr[pos] = offset;
+ }
}
}
@@ -223,8 +267,8 @@ features_index_add_single(VALUE short_feature, VALUE offset)
static void
features_index_add(VALUE feature, VALUE offset)
{
- VALUE short_feature;
const char *feature_str, *feature_end, *ext, *p;
+ bool rb = false;
feature_str = StringValuePtr(feature);
feature_end = feature_str + RSTRING_LEN(feature);
@@ -234,31 +278,27 @@ features_index_add(VALUE feature, VALUE offset)
break;
if (*ext != '.')
ext = NULL;
+ else
+ rb = IS_RBEXT(ext);
/* Now `ext` points to the only string matching %r{^\.[^./]*$} that is
at the end of `feature`, or is NULL if there is no such string. */
p = ext ? ext : feature_end;
while (1) {
- long beg;
-
p--;
while (p >= feature_str && *p != '/')
p--;
if (p < feature_str)
break;
/* Now *p == '/'. We reach this point for every '/' in `feature`. */
- beg = p + 1 - feature_str;
- short_feature = rb_str_subseq(feature, beg, feature_end - p - 1);
- features_index_add_single(short_feature, offset);
+ features_index_add_single(p + 1, feature_end - p - 1, offset, false);
if (ext) {
- short_feature = rb_str_subseq(feature, beg, ext - p - 1);
- features_index_add_single(short_feature, offset);
+ features_index_add_single(p + 1, ext - p - 1, offset, rb);
}
}
- features_index_add_single(feature, offset);
+ features_index_add_single(feature_str, feature_end - feature_str, offset, false);
if (ext) {
- short_feature = rb_str_subseq(feature, 0, ext - feature_str);
- features_index_add_single(short_feature, offset);
+ features_index_add_single(feature_str, ext - feature_str, offset, rb);
}
}
@@ -268,9 +308,8 @@ loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
VALUE obj = (VALUE)val;
if (!SPECIAL_CONST_P(obj)) {
rb_ary_free(obj);
- xfree((void *)obj);
+ ruby_sized_xfree((void *)obj, sizeof(struct RArray));
}
- xfree((char *)key);
return ST_DELETE;
}
@@ -383,6 +422,7 @@ rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const c
long i, len, elen, n;
st_table *loading_tbl, *features_index;
st_data_t data;
+ st_data_t key;
int type;
if (fn) *fn = 0;
@@ -399,7 +439,8 @@ rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const c
features = get_loaded_features();
features_index = get_loaded_features_index();
- st_lookup(features_index, (st_data_t)feature, (st_data_t *)&this_feature_index);
+ key = feature_key(feature, strlen(feature));
+ st_lookup(features_index, key, (st_data_t *)&this_feature_index);
/* We search `features` for an entry such that either
"#{features[i]}" == "#{load_path[j]}/#{feature}#{e}"
for some j, or
@@ -482,9 +523,7 @@ rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const c
}
if (st_get_key(loading_tbl, (st_data_t)feature, &data)) {
if (fn) *fn = (const char*)data;
- loading:
- if (!ext) return 'u';
- return !IS_RBEXT(ext) ? 's' : 'r';
+ goto loading;
}
else {
VALUE bufstr;
@@ -516,6 +555,10 @@ rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const c
rb_str_resize(bufstr, 0);
}
return 0;
+
+ loading:
+ if (!ext) return 'u';
+ return !IS_RBEXT(ext) ? 's' : 'r';
}
int
@@ -563,6 +606,7 @@ rb_provide_feature(VALUE feature)
}
rb_str_freeze(feature);
+ get_loaded_features_index();
rb_ary_push(features, rb_fstring(feature));
features_index_add(feature, INT2FIX(RARRAY_LEN(features)-1));
reset_loaded_features_snapshot();
@@ -575,49 +619,49 @@ rb_provide(const char *feature)
}
NORETURN(static void load_failed(VALUE));
-const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
-static int
-rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
+static inline void
+load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
+{
+ const rb_iseq_t *iseq = rb_iseq_load_iseq(fname);
+
+ if (!iseq) {
+ rb_ast_t *ast;
+ VALUE parser = rb_parser_new();
+ rb_parser_set_context(parser, NULL, FALSE);
+ ast = (rb_ast_t *)rb_parser_load_file(parser, fname);
+ iseq = rb_iseq_new_top(&ast->body, rb_fstring_lit("<top (required)>"),
+ fname, rb_realpath_internal(Qnil, fname, 1), NULL);
+ rb_ast_dispose(ast);
+ }
+ rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
+ rb_iseq_eval(iseq);
+}
+
+static inline enum ruby_tag_type
+load_wrapping(rb_execution_context_t *ec, VALUE fname)
{
enum ruby_tag_type state;
+ rb_thread_t *th = rb_ec_thread_ptr(ec);
volatile VALUE wrapper = th->top_wrapper;
volatile VALUE self = th->top_self;
#if !defined __GNUC__
rb_thread_t *volatile th0 = th;
#endif
- th->ec.errinfo = Qnil; /* ensure */
+ ec->errinfo = Qnil; /* ensure */
- if (!wrap) {
- th->top_wrapper = 0;
- }
- else {
- /* load in anonymous module as toplevel */
- th->top_self = rb_obj_clone(rb_vm_top_self());
- th->top_wrapper = rb_module_new();
- rb_extend_object(th->top_self, th->top_wrapper);
- }
+ /* load in anonymous module as toplevel */
+ th->top_self = rb_obj_clone(rb_vm_top_self());
+ th->top_wrapper = rb_module_new();
+ rb_extend_object(th->top_self, th->top_wrapper);
- TH_PUSH_TAG(th);
- state = EXEC_TAG();
+ EC_PUSH_TAG(ec);
+ state = EC_EXEC_TAG();
if (state == TAG_NONE) {
- NODE *node;
- const rb_iseq_t *iseq;
-
- if ((iseq = rb_iseq_load_iseq(fname)) != NULL) {
- /* OK */
- }
- else {
- VALUE parser = rb_parser_new();
- rb_parser_set_context(parser, NULL, FALSE);
- node = (NODE *)rb_parser_load_file(parser, fname);
- iseq = rb_iseq_new_top(node, rb_fstring_cstr("<top (required)>"),
- fname, rb_realpath_internal(Qnil, fname, 1), NULL);
- }
- rb_iseq_eval(iseq);
+ load_iseq_eval(ec, fname);
}
- TH_POP_TAG();
+ EC_POP_TAG();
#if !defined __GNUC__
th = th0;
@@ -625,61 +669,54 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
#endif
th->top_self = self;
th->top_wrapper = wrapper;
+ return state;
+}
+static inline void
+raise_load_if_failed(rb_execution_context_t *ec, enum ruby_tag_type state)
+{
if (state) {
- /* usually state == TAG_RAISE only, except for
- * rb_iseq_load_iseq case */
- VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
- if (NIL_P(exc)) return state;
- th->ec.errinfo = exc;
- return TAG_RAISE;
+ rb_vm_jump_tag_but_local_jump(state);
}
- if (!NIL_P(th->ec.errinfo)) {
- /* exception during load */
- return TAG_RAISE;
+ if (!NIL_P(ec->errinfo)) {
+ rb_exc_raise(ec->errinfo);
}
- return state;
}
static void
rb_load_internal(VALUE fname, int wrap)
{
- rb_thread_t *curr_th = GET_THREAD();
- int state = rb_load_internal0(curr_th, fname, wrap);
- if (state) {
- if (state == TAG_RAISE) rb_exc_raise(curr_th->ec.errinfo);
- TH_JUMP_TAG(curr_th, state);
+ rb_execution_context_t *ec = GET_EC();
+ enum ruby_tag_type state = TAG_NONE;
+ if (wrap) {
+ state = load_wrapping(ec, fname);
}
-}
-
-static VALUE
-file_to_load(VALUE fname)
-{
- VALUE tmp = rb_find_file(FilePathValue(fname));
- if (!tmp) load_failed(fname);
- return tmp;
+ else {
+ load_iseq_eval(ec, fname);
+ }
+ raise_load_if_failed(ec, state);
}
void
rb_load(VALUE fname, int wrap)
{
- rb_load_internal(file_to_load(fname), wrap);
+ VALUE tmp = rb_find_file(FilePathValue(fname));
+ if (!tmp) load_failed(fname);
+ rb_load_internal(tmp, wrap);
}
void
rb_load_protect(VALUE fname, int wrap, int *pstate)
{
enum ruby_tag_type state;
- volatile VALUE path = 0;
- PUSH_TAG();
- if ((state = EXEC_TAG()) == TAG_NONE) {
- path = file_to_load(fname);
+ EC_PUSH_TAG(GET_EC());
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
+ rb_load(fname, wrap);
}
- POP_TAG();
+ EC_POP_TAG();
- if (state == TAG_NONE) state = rb_load_internal0(GET_THREAD(), path, wrap);
if (state != TAG_NONE) *pstate = state;
}
@@ -687,24 +724,40 @@ rb_load_protect(VALUE fname, int wrap, int *pstate)
* call-seq:
* load(filename, wrap=false) -> true
*
- * Loads and executes the Ruby
- * program in the file _filename_. If the filename does not
- * resolve to an absolute path, the file is searched for in the library
- * directories listed in <code>$:</code>. If the optional _wrap_
- * parameter is +true+, the loaded script will be executed
- * under an anonymous module, protecting the calling program's global
- * namespace. In no circumstance will any local variables in the loaded
- * file be propagated to the loading environment.
+ * Loads and executes the Ruby program in the file _filename_.
+ *
+ * If the filename is an absolute path (e.g. starts with '/'), the file
+ * will be loaded directly using the absolute path.
+ *
+ * If the filename is an explicit relative path (e.g. starts with './' or
+ * '../'), the file will be loaded using the relative path from the current
+ * directory.
+ *
+ * Otherwise, the file will be searched for in the library
+ * directories listed in <code>$LOAD_PATH</code> (<code>$:</code>).
+ * If the file is found in a directory, it will attempt to load the file
+ * relative to that directory. If the file is not found in any of the
+ * directories in <code>$LOAD_PATH</code>, the file will be loaded using
+ * the relative path from the current directory.
+ *
+ * If the file doesn't exist when there is an attempt to load it, a
+ * LoadError will be raised.
+ *
+ * If the optional _wrap_ parameter is +true+, the loaded script will
+ * be executed under an anonymous module, protecting the calling
+ * program's global namespace. In no circumstance will any local
+ * variables in the loaded file be propagated to the loading
+ * environment.
*/
static VALUE
-rb_f_load(int argc, VALUE *argv)
+rb_f_load(int argc, VALUE *argv, VALUE _)
{
VALUE fname, wrap, path, orig_fname;
rb_scan_args(argc, argv, "11", &fname, &wrap);
- orig_fname = rb_get_path_check_to_string(fname, rb_safe_level());
+ orig_fname = rb_get_path_check_to_string(fname);
fname = rb_str_encode_ospath(orig_fname);
RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname));
@@ -721,8 +774,6 @@ rb_f_load(int argc, VALUE *argv)
return Qtrue;
}
-extern VALUE rb_mWarning;
-
static char *
load_lock(const char *ftptr)
{
@@ -738,7 +789,7 @@ load_lock(const char *ftptr)
}
else if (imemo_type_p(data, imemo_memo)) {
struct MEMO *memo = MEMO_CAST(data);
- void (*init)(void) = (void (*)(void))memo->u3.func;
+ void (*init)(void) = memo->u3.func;
data = (st_data_t)rb_thread_shield_new();
st_insert(loading_tbl, (st_data_t)ftptr, data);
(*init)();
@@ -747,7 +798,7 @@ load_lock(const char *ftptr)
if (RTEST(ruby_verbose)) {
VALUE warning = rb_warning_string("loading in progress, circular require considered harmful - %s", ftptr);
rb_backtrace_each(rb_str_append, warning);
- rb_warning_warn(rb_mWarning, warning);
+ rb_warning("%"PRIsVALUE, warning);
}
switch (rb_thread_shield_wait((VALUE)data)) {
case Qfalse:
@@ -794,8 +845,10 @@ load_unlock(const char *ftptr, int done)
* Loads the given +name+, returning +true+ if successful and +false+ if the
* feature is already loaded.
*
- * If the filename does not resolve to an absolute path, it will be searched
- * for in the directories listed in <code>$LOAD_PATH</code> (<code>$:</code>).
+ * If the filename neither resolves to an absolute path nor starts with
+ * './' or '../', the file will be searched for in the library
+ * directories listed in <code>$LOAD_PATH</code> (<code>$:</code>).
+ * If the filename starts with './' or '../', resolution is based on Dir.pwd.
*
* If the filename has the extension ".rb", it is loaded as a source file; if
* the extension is ".so", ".o", or ".dll", or the default shared library
@@ -826,7 +879,7 @@ load_unlock(const char *ftptr, int done)
VALUE
rb_f_require(VALUE obj, VALUE fname)
{
- return rb_require_safe(fname, rb_safe_level());
+ return rb_require_string(fname);
}
/*
@@ -845,11 +898,13 @@ rb_f_require_relative(VALUE obj, VALUE fname)
rb_loaderror("cannot infer basepath");
}
base = rb_file_dirname(base);
- return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
+ return rb_require_string(rb_file_absolute_path(fname, base));
}
+typedef int (*feature_func)(const char *feature, const char *ext, int rb, int expanded, const char **fn);
+
static int
-search_required(VALUE fname, volatile VALUE *path, int safe_level)
+search_required(VALUE fname, volatile VALUE *path, feature_func rb_feature_p)
{
VALUE tmp;
char *ext, *ftptr;
@@ -864,7 +919,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
if (loading) *path = rb_filesystem_str_new_cstr(loading);
return 'r';
}
- if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
+ if ((tmp = rb_find_file(fname)) != 0) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
*path = tmp;
@@ -880,7 +935,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
tmp = rb_str_subseq(fname, 0, ext - RSTRING_PTR(fname));
#ifdef DLEXT2
OBJ_FREEZE(tmp);
- if (rb_find_file_ext_safe(&tmp, loadable_ext + 1, safe_level)) {
+ if (rb_find_file_ext(&tmp, loadable_ext + 1)) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
*path = tmp;
@@ -889,7 +944,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
#else
rb_str_cat2(tmp, DLEXT);
OBJ_FREEZE(tmp);
- if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) {
+ if ((tmp = rb_find_file(tmp)) != 0) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
*path = tmp;
@@ -902,7 +957,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
if (loading) *path = rb_filesystem_str_new_cstr(loading);
return 's';
}
- if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
+ if ((tmp = rb_find_file(fname)) != 0) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
*path = tmp;
@@ -915,7 +970,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
return 'r';
}
tmp = fname;
- type = rb_find_file_ext_safe(&tmp, loadable_ext, safe_level);
+ type = rb_find_file_ext(&tmp, ft == 's' ? ruby_ext : loadable_ext);
switch (type) {
case 0:
if (ft)
@@ -925,10 +980,9 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
default:
if (ft) {
- statically_linked:
- if (loading) *path = rb_filesystem_str_new_cstr(loading);
- return ft;
+ goto statically_linked;
}
+ /* fall through */
case 1:
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading)
@@ -936,6 +990,10 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
*path = tmp;
}
return type ? 's' : 'r';
+
+ statically_linked:
+ if (loading) *path = rb_filesystem_str_new_cstr(loading);
+ return ft;
}
static void
@@ -951,6 +1009,57 @@ load_ext(VALUE path)
return (VALUE)dln_load(RSTRING_PTR(path));
}
+static int
+no_feature_p(const char *feature, const char *ext, int rb, int expanded, const char **fn)
+{
+ return 0;
+}
+
+// Documented in doc/globals.rdoc
+VALUE
+rb_resolve_feature_path(VALUE klass, VALUE fname)
+{
+ VALUE path;
+ int found;
+ VALUE sym;
+
+ fname = rb_get_path(fname);
+ path = rb_str_encode_ospath(fname);
+ found = search_required(path, &path, no_feature_p);
+
+ switch (found) {
+ case 'r':
+ sym = ID2SYM(rb_intern("rb"));
+ break;
+ case 's':
+ sym = ID2SYM(rb_intern("so"));
+ break;
+ default:
+ load_failed(fname);
+ }
+
+ return rb_ary_new_from_args(2, sym, path);
+}
+
+static void
+ext_config_push(rb_thread_t *th, struct rb_ext_config *prev)
+{
+ *prev = th->ext_config;
+ th->ext_config = (struct rb_ext_config){0};
+}
+
+static void
+ext_config_pop(rb_thread_t *th, struct rb_ext_config *prev)
+{
+ th->ext_config = *prev;
+}
+
+void
+rb_ext_ractor_safe(bool flag)
+{
+ GET_THREAD()->ext_config.ractor_safe = flag;
+}
+
/*
* returns
* 0: if already loaded (false)
@@ -958,73 +1067,94 @@ load_ext(VALUE path)
* <0: not found (LoadError)
* >1: exception
*/
-int
-rb_require_internal(VALUE fname, int safe)
+static int
+require_internal(rb_execution_context_t *ec, VALUE fname, int exception)
{
volatile int result = -1;
- rb_thread_t *th = GET_THREAD();
- volatile VALUE errinfo = th->ec.errinfo;
+ rb_thread_t *th = rb_ec_thread_ptr(ec);
+ volatile VALUE wrapper = th->top_wrapper;
+ volatile VALUE self = th->top_self;
+ volatile VALUE errinfo = ec->errinfo;
enum ruby_tag_type state;
- struct {
- int safe;
- } volatile saved;
char *volatile ftptr = 0;
VALUE path;
+ volatile bool reset_ext_config = false;
+ struct rb_ext_config prev_ext_config;
- fname = rb_get_path_check(fname, safe);
+ fname = rb_get_path(fname);
path = rb_str_encode_ospath(fname);
RUBY_DTRACE_HOOK(REQUIRE_ENTRY, RSTRING_PTR(fname));
- TH_PUSH_TAG(th);
- saved.safe = rb_safe_level();
- if ((state = EXEC_TAG()) == TAG_NONE) {
+ EC_PUSH_TAG(ec);
+ ec->errinfo = Qnil; /* ensure */
+ th->top_wrapper = 0;
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
long handle;
int found;
- rb_set_safe_level_force(0);
-
RUBY_DTRACE_HOOK(FIND_REQUIRE_ENTRY, RSTRING_PTR(fname));
- found = search_required(path, &path, safe);
+ found = search_required(path, &path, rb_feature_p);
RUBY_DTRACE_HOOK(FIND_REQUIRE_RETURN, RSTRING_PTR(fname));
if (found) {
- if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
+ if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
result = 0;
}
else if (!*ftptr) {
- rb_provide_feature(path);
result = TAG_RETURN;
}
else {
switch (found) {
case 'r':
- state = rb_load_internal0(th, path, 0);
+ load_iseq_eval(ec, path);
break;
case 's':
+ reset_ext_config = true;
+ ext_config_push(th, &prev_ext_config);
handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
path, VM_BLOCK_HANDLER_NONE, path);
rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
break;
}
- if (!state) {
- rb_provide_feature(path);
- result = TAG_RETURN;
- }
+ result = TAG_RETURN;
}
}
}
- TH_POP_TAG();
- load_unlock(ftptr, !state);
+ EC_POP_TAG();
+
+ rb_thread_t *th2 = rb_ec_thread_ptr(ec);
+ th2->top_self = self;
+ th2->top_wrapper = wrapper;
+ if (reset_ext_config) ext_config_pop(th2, &prev_ext_config);
+
+ if (ftptr) load_unlock(RSTRING_PTR(path), !state);
- rb_set_safe_level_force(saved.safe);
if (state) {
+ if (state == TAG_FATAL || state == TAG_THROW) {
+ EC_JUMP_TAG(ec, state);
+ }
+ else if (exception) {
+ /* usually state == TAG_RAISE only, except for
+ * rb_iseq_load_iseq in load_iseq_eval case */
+ VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
+ if (!NIL_P(exc)) ec->errinfo = exc;
+ return TAG_RAISE;
+ }
+ else if (state == TAG_RETURN) {
+ return TAG_RAISE;
+ }
RB_GC_GUARD(fname);
/* never TAG_RETURN */
return state;
}
+ if (!NIL_P(ec->errinfo)) {
+ if (!exception) return TAG_RAISE;
+ rb_exc_raise(ec->errinfo);
+ }
- th->ec.errinfo = errinfo;
+ if (result == TAG_RETURN) rb_provide_feature(path);
+ ec->errinfo = errinfo;
RUBY_DTRACE_HOOK(REQUIRE_RETURN, RSTRING_PTR(fname));
@@ -1032,23 +1162,31 @@ rb_require_internal(VALUE fname, int safe)
}
int
+rb_require_internal(VALUE fname)
+{
+ rb_execution_context_t *ec = GET_EC();
+ return require_internal(ec, fname, 1);
+}
+
+int
ruby_require_internal(const char *fname, unsigned int len)
{
struct RString fake;
VALUE str = rb_setup_fake_str(&fake, fname, len, 0);
- int result = rb_require_internal(str, 0);
+ rb_execution_context_t *ec = GET_EC();
+ int result = require_internal(ec, str, 0);
rb_set_errinfo(Qnil);
return result == TAG_RETURN ? 1 : result ? -1 : 0;
}
VALUE
-rb_require_safe(VALUE fname, int safe)
+rb_require_string(VALUE fname)
{
- int result = rb_require_internal(fname, safe);
+ rb_execution_context_t *ec = GET_EC();
+ int result = require_internal(ec, fname, 1);
if (result > TAG_RETURN) {
- if (result == TAG_RAISE) rb_exc_raise(rb_errinfo());
- JUMP_TAG(result);
+ EC_JUMP_TAG(ec, result);
}
if (result < 0) {
load_failed(fname);
@@ -1060,8 +1198,7 @@ rb_require_safe(VALUE fname, int safe)
VALUE
rb_require(const char *fname)
{
- VALUE fn = rb_str_new_cstr(fname);
- return rb_require_safe(fn, rb_safe_level());
+ return rb_require_string(rb_str_new_cstr(fname));
}
static int
@@ -1093,8 +1230,8 @@ ruby_init_ext(const char *name, void (*init)(void))
* call-seq:
* mod.autoload(module, filename) -> nil
*
- * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
- * the first time that _module_ (which may be a <code>String</code> or
+ * Registers _filename_ to be loaded (using Kernel::require)
+ * the first time that _module_ (which may be a String or
* a symbol) is accessed in the namespace of _mod_.
*
* module A
@@ -1115,33 +1252,49 @@ rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
/*
* call-seq:
- * mod.autoload?(name) -> String or nil
+ * mod.autoload?(name, inherit=true) -> String or nil
*
* Returns _filename_ to be loaded if _name_ is registered as
- * +autoload+ in the namespace of _mod_.
+ * +autoload+ in the namespace of _mod_ or one of its ancestors.
*
* module A
* end
* A.autoload(:B, "b")
* A.autoload?(:B) #=> "b"
+ *
+ * If +inherit+ is false, the lookup only checks the autoloads in the receiver:
+ *
+ * class A
+ * autoload :CONST, "const.rb"
+ * end
+ *
+ * class B < A
+ * end
+ *
+ * B.autoload?(:CONST) #=> "const.rb", found in A (ancestor)
+ * B.autoload?(:CONST, false) #=> nil, not found in B itself
+ *
*/
static VALUE
-rb_mod_autoload_p(VALUE mod, VALUE sym)
+rb_mod_autoload_p(int argc, VALUE *argv, VALUE mod)
{
+ int recur = (rb_check_arity(argc, 1, 2) == 1) ? TRUE : RTEST(argv[1]);
+ VALUE sym = argv[0];
+
ID id = rb_check_id(&sym);
if (!id) {
return Qnil;
}
- return rb_autoload_p(mod, id);
+ return rb_autoload_at_p(mod, id, recur);
}
/*
* call-seq:
* autoload(module, filename) -> nil
*
- * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
- * the first time that _module_ (which may be a <code>String</code> or
+ * Registers _filename_ to be loaded (using Kernel::require)
+ * the first time that _module_ (which may be a String or
* a symbol) is accessed.
*
* autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
@@ -1151,7 +1304,7 @@ static VALUE
rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
{
VALUE klass = rb_class_real(rb_vm_cbase());
- if (NIL_P(klass)) {
+ if (!klass) {
rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
}
return rb_mod_autoload(klass, sym, file);
@@ -1159,7 +1312,7 @@ rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
/*
* call-seq:
- * autoload?(name) -> String or nil
+ * autoload?(name, inherit=true) -> String or nil
*
* Returns _filename_ to be loaded if _name_ is registered as
* +autoload+.
@@ -1169,46 +1322,45 @@ rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
*/
static VALUE
-rb_f_autoload_p(VALUE obj, VALUE sym)
+rb_f_autoload_p(int argc, VALUE *argv, VALUE obj)
{
/* use rb_vm_cbase() as same as rb_f_autoload. */
VALUE klass = rb_vm_cbase();
if (NIL_P(klass)) {
return Qnil;
}
- return rb_mod_autoload_p(klass, sym);
+ return rb_mod_autoload_p(argc, argv, klass);
}
void
Init_load(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern2((str), strlen(str))
rb_vm_t *vm = GET_VM();
static const char var_load_path[] = "$:";
ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter);
- rb_alias_variable(rb_intern("$-I"), id_load_path);
- rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path);
+ rb_alias_variable(rb_intern_const("$-I"), id_load_path);
+ rb_alias_variable(rb_intern_const("$LOAD_PATH"), id_load_path);
vm->load_path = rb_ary_new();
vm->expanded_load_path = rb_ary_tmp_new(0);
vm->load_path_snapshot = rb_ary_tmp_new(0);
vm->load_path_check_cache = 0;
+ rb_define_singleton_method(vm->load_path, "resolve_feature_path", rb_resolve_feature_path, 1);
- rb_define_virtual_variable("$\"", get_loaded_features, 0);
- rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
+ rb_define_virtual_variable("$\"", get_LOADED_FEATURES, 0);
+ rb_define_virtual_variable("$LOADED_FEATURES", get_LOADED_FEATURES, 0);
vm->loaded_features = rb_ary_new();
vm->loaded_features_snapshot = rb_ary_tmp_new(0);
- vm->loaded_features_index = st_init_strtable();
+ vm->loaded_features_index = st_init_numtable();
rb_define_global_function("load", rb_f_load, -1);
rb_define_global_function("require", rb_f_require, 1);
rb_define_global_function("require_relative", rb_f_require_relative, 1);
rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
- rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
+ rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, -1);
rb_define_global_function("autoload", rb_f_autoload, 2);
- rb_define_global_function("autoload?", rb_f_autoload_p, 1);
+ rb_define_global_function("autoload?", rb_f_autoload_p, -1);
ruby_dln_librefs = rb_ary_tmp_new(0);
rb_gc_register_mark_object(ruby_dln_librefs);
diff --git a/loadpath.c b/loadpath.c
index 9160031971..b8969e6998 100644
--- a/loadpath.c
+++ b/loadpath.c
@@ -89,4 +89,3 @@ const char ruby_initial_load_paths[] =
RUBY_ARCH_LIB_FOR(RUBY_ARCH) "\0"
#endif
"";
-
diff --git a/localeinit.c b/localeinit.c
index dc48d42561..bbcbac832e 100644
--- a/localeinit.c
+++ b/localeinit.c
@@ -9,6 +9,7 @@
**********************************************************************/
+#include "ruby/encoding.h"
#include "internal.h"
#include "encindex.h"
#ifdef __CYGWIN__
@@ -122,8 +123,9 @@ Init_enc_set_filesystem_encoding(void)
idx = ENCINDEX_US_ASCII;
#elif defined _WIN32
char cp[SIZEOF_CP_NAME];
- const UINT codepage = ruby_w32_codepage[1] ? ruby_w32_codepage[1] :
- AreFileApisANSI() ? GetACP() : GetOEMCP();
+ const UINT codepage = ruby_w32_codepage[1];
+ if (!codepage) return ENCINDEX_UTF_8;
+ /* for debugging */
CP_FORMAT(cp, codepage);
idx = rb_enc_find_index(cp);
if (idx < 0) idx = ENCINDEX_ASCII;
diff --git a/main.c b/main.c
index 6e8ab7b9fe..313aaedd42 100644
--- a/main.c
+++ b/main.c
@@ -9,6 +9,14 @@
**********************************************************************/
+/*!
+ * \mainpage Developers' documentation for Ruby
+ *
+ * This documentation is produced by applying Doxygen to
+ * <a href="https://github.com/ruby/ruby">Ruby's source code</a>.
+ * It is still under construction (and even not well-maintained).
+ * If you are familiar with Ruby's source code, please improve the doc.
+ */
#undef RUBY_EXPORT
#include "ruby.h"
#include "vm_debug.h"
diff --git a/man/erb.1 b/man/erb.1
index 46ee2fa2d4..d8739a7639 100644
--- a/man/erb.1
+++ b/man/erb.1
@@ -1,5 +1,5 @@
.\"Ruby is copyrighted by Yukihiro Matsumoto <matz@netlab.jp>.
-.Dd November 15, 2012
+.Dd December 16, 2018
.Dt ERB \&1 "Ruby Programmer's Reference Guide"
.Os UNIX
.Sh NAME
@@ -45,9 +45,8 @@ You can omit the one for internal encodings, then the value
.Pf ( Li "Encoding.default_internal" ) will be nil.
.Pp
.It Fl P
-Evaluates lines starting with
-.Li "%"
-as Ruby code and removes the tailing EOLs.
+Disables ruby code evaluation for lines beginning with
+.Li "%" .
.Pp
.It Fl S Ar level
Specifies the safe level in which eRuby script will run.
@@ -77,6 +76,8 @@ And leading whitespaces are removed if the erb directive starts with
.Li "<%-" .
.Pp
.El
+.It Fl r
+Load a library
.Pp
.It Fl U
can be one of
diff --git a/man/goruby.1 b/man/goruby.1
index 47a015f34d..a305a5afce 100644
--- a/man/goruby.1
+++ b/man/goruby.1
@@ -1,5 +1,5 @@
.\"Ruby is copyrighted by Yukihiro Matsumoto <matz@netlab.jp>.
-.Dd November 15, 2012
+.Dd April 20, 2017
.Dt GORUBY \&1 "Ruby Programmer's Reference Guide"
.Os UNIX
.Sh NAME
diff --git a/man/index.txt b/man/index.txt
new file mode 100644
index 0000000000..400eb02267
--- /dev/null
+++ b/man/index.txt
@@ -0,0 +1,25 @@
+Gemfile(5) gemfile.5
+bundle(1) bundle.1
+bundle-add(1) bundle-add.1
+bundle-binstubs(1) bundle-binstubs.1
+bundle-check(1) bundle-check.1
+bundle-clean(1) bundle-clean.1
+bundle-config(1) bundle-config.1
+bundle-doctor(1) bundle-doctor.1
+bundle-exec(1) bundle-exec.1
+bundle-gem(1) bundle-gem.1
+bundle-info(1) bundle-info.1
+bundle-init(1) bundle-init.1
+bundle-inject(1) bundle-inject.1
+bundle-install(1) bundle-install.1
+bundle-list(1) bundle-list.1
+bundle-lock(1) bundle-lock.1
+bundle-open(1) bundle-open.1
+bundle-outdated(1) bundle-outdated.1
+bundle-package(1) bundle-package.1
+bundle-platform(1) bundle-platform.1
+bundle-pristine(1) bundle-pristine.1
+bundle-remove(1) bundle-remove.1
+bundle-show(1) bundle-show.1
+bundle-update(1) bundle-update.1
+bundle-viz(1) bundle-viz.1
diff --git a/man/irb.1 b/man/irb.1
index e980a2ebfd..f0a720fbd3 100644
--- a/man/irb.1
+++ b/man/irb.1
@@ -1,5 +1,5 @@
.\"Ruby is copyrighted by Yukihiro Matsumoto <matz@netlab.jp>.
-.Dd November 15, 2012
+.Dd August 11, 2019
.Dt IRB \&1 "Ruby Programmer's Reference Guide"
.Os UNIX
.Sh NAME
@@ -8,11 +8,17 @@
.Sh SYNOPSIS
.Nm
.Op Fl -version
-.Op Fl dfm
+.Op Fl dfUw
.Op Fl I Ar directory
.Op Fl r Ar library
+.Op Fl E Ar external Ns Op : Ns Ar internal
+.Op Fl W Ns Op Ar level
.Op Fl - Ns Oo no Oc Ns inspect
-.Op Fl - Ns Oo no Oc Ns readline
+.Op Fl - Ns Oo no Oc Ns multiline
+.Op Fl - Ns Oo no Oc Ns singleline
+.Op Fl - Ns Oo no Oc Ns echo
+.Op Fl - Ns Oo no Oc Ns colorize
+.Op Fl - Ns Oo no Oc Ns verbose
.Op Fl -prompt Ar mode
.Op Fl -prompt-mode Ar mode
.Op Fl -inf-ruby-mode
@@ -20,7 +26,6 @@
.Op Fl -noprompt
.Op Fl -tracer
.Op Fl -back-trace-limit Ar n
-.Op Fl -irb_debug Ar n
.Op Fl -
.Op program_file
.Op argument ...
@@ -65,6 +70,13 @@ to true.
Suppresses read of
.Pa ~/.irbrc .
.Pp
+.It Fl w
+Same as `ruby -w' .
+.Pp
+.Pp
+.It Fl W
+Same as `ruby -W' .
+.Pp
.It Fl h
.It Fl -help
Prints a summary of the options.
@@ -79,11 +91,38 @@ Uses `inspect' for output (default except for bc mode)
.It Fl -noinspect
Doesn't use inspect for output
.Pp
-.It Fl -readline
-Uses Readline extension module.
+.It Fl -multiline
+Uses multiline editor module.
+.Pp
+.It Fl -nomultiline
+Doesn't use multiline editor module.
+.Pp
+.It Fl -singleline
+Uses singleline editor module.
+.Pp
+.It Fl -nosingleline
+Doesn't use singleline editor module.
+.Pp
+.Pp
+.It Fl -echo
+Show result(default).
.Pp
-.It Fl -noreadline
-Doesn't use Readline extension module.
+.It Fl -noecho
+Don't show result.
+.Pp
+.Pp
+.It Fl -colorize
+Use colorization.
+.Pp
+.It Fl -nocolorize
+Don't use colorization.
+.Pp
+.Pp
+.It Fl -verbose
+Show details.
+.Pp
+.It Fl -noverbose
+Don't show details.
.Pp
.It Fl -prompt Ar mode
.It Fl -prompt-mode Ar mode
@@ -92,7 +131,7 @@ Switch prompt mode. Pre-defined prompt modes are
.Pp
.It Fl -inf-ruby-mode
Uses prompt appropriate for inf-ruby-mode on emacs.
-Suppresses --readline.
+Suppresses --multiline and --singleline.
.Pp
.It Fl -simple-prompt
Makes prompts simple.
@@ -109,10 +148,6 @@ Displays backtrace top
and tail
.Ar n Ns .
The default value is 16.
-.Pp
-.It Fl -irb_debug Ar n
-Sets internal debug level to n (not for popular use)
-.Pp
.El
.Pp
.Sh ENVIRONMENT
@@ -138,7 +173,7 @@ Personal irb initialization.
.Dl irb(main):001:0> Ic 1 + 1
.Dl 2
.Dl irb(main):002:0> Ic def t(x)
-.Dl irb(main):003:1> Ic x+1
+.Dl irb(main):003:1> Ic x + 1
.Dl irb(main):004:1> Ic end
.Dl => :t
.Dl irb(main):005:0> Ic t(3)
diff --git a/man/ruby.1 b/man/ruby.1
index 88cef8d480..9f0ae05ee9 100644
--- a/man/ruby.1
+++ b/man/ruby.1
@@ -1,5 +1,5 @@
.\"Ruby is copyrighted by Yukihiro Matsumoto <matz@netlab.jp>.
-.Dd October 31, 2015
+.Dd April 14, 2018
.Dt RUBY \&1 "Ruby Programmer's Reference Guide"
.Os UNIX
.Sh NAME
@@ -137,16 +137,18 @@ to see how they are being developed and used.
.El
.Pp
.Sh OPTIONS
-Ruby interpreter accepts following command-line options (switches).
+The Ruby interpreter accepts the following command-line options (switches).
They are quite similar to those of
.Xr perl 1 .
.Bl -tag -width "1234567890123" -compact
.Pp
.It Fl -copyright
-Prints the copyright notice.
+Prints the copyright notice, and quits immediately without running any
+script.
.Pp
.It Fl -version
-Prints the version of Ruby interpreter.
+Prints the version of the Ruby interpreter, and quits immediately without
+running any script.
.Pp
.It Fl 0 Ns Op Ar octal
(The digit
@@ -311,7 +313,7 @@ Enables automatic line-ending processing, which means to firstly set
to the value of
.Li "$/" ,
and secondly chops every line read using
-.Li chop! .
+.Li chomp! .
.Pp
.It Fl n
Causes Ruby to assume the following loop around your script, which
@@ -417,7 +419,7 @@ Disables (or enables) all features.
.El
.Pp
.It Fl -dump Ns = Ns Ar target
-Dump some informations.
+Dump some information.
.Pp
Prints the specified target.
.Ar target
@@ -457,8 +459,9 @@ Enables verbose mode without printing version message at the
beginning. It sets the
.Li "$VERBOSE"
variable to true.
-If this switch is given, and no other switches are present, Ruby quits
-after printing its version.
+If this switch is given, and no script arguments (script file or
+.Fl e
+options) are present, Ruby quits immediately.
.El
.Pp
.Sh ENVIRONMENT
diff --git a/marshal.c b/marshal.c
index 61eb01e721..ed096f52fe 100644
--- a/marshal.c
+++ b/marshal.c
@@ -9,16 +9,7 @@
**********************************************************************/
-#if defined __GNUC__ && __GNUC__ < 3
-# error too old GCC
-#endif
-
-#include "internal.h"
-#include "ruby/io.h"
-#include "ruby/st.h"
-#include "ruby/util.h"
-#include "encindex.h"
-#include "id_table.h"
+#include "ruby/internal/config.h"
#include <math.h>
#ifdef HAVE_FLOAT_H
@@ -28,6 +19,24 @@
#include <ieeefp.h>
#endif
+#include "encindex.h"
+#include "id_table.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/bignum.h"
+#include "internal/class.h"
+#include "internal/encoding.h"
+#include "internal/error.h"
+#include "internal/hash.h"
+#include "internal/object.h"
+#include "internal/struct.h"
+#include "internal/util.h"
+#include "internal/vm.h"
+#include "ruby/io.h"
+#include "ruby/ruby.h"
+#include "ruby/st.h"
+#include "ruby/util.h"
+
#define BITSPERSHORT (2*CHAR_BIT)
#define SHORTMASK ((1<<BITSPERSHORT)-1)
#define SHORTDN(x) RSHIFT((x),BITSPERSHORT)
@@ -86,6 +95,7 @@ shortlen(size_t len, BDIGIT *ds)
static ID s_dump, s_load, s_mdump, s_mload;
static ID s_dump_data, s_load_data, s_alloc, s_call;
static ID s_getbyte, s_read, s_write, s_binmode;
+static ID s_encoding_short, s_ruby2_keywords_flag;
#define name_s_dump "_dump"
#define name_s_load "_load"
@@ -99,6 +109,8 @@ static ID s_getbyte, s_read, s_write, s_binmode;
#define name_s_read "read"
#define name_s_write "write"
#define name_s_binmode "binmode"
+#define name_s_encoding_short "E"
+#define name_s_ruby2_keywords_flag "K"
typedef struct {
VALUE newclass;
@@ -113,7 +125,7 @@ static VALUE rb_marshal_dump_limited(VALUE obj, VALUE port, int limit);
static VALUE rb_marshal_load_with_proc(VALUE port, VALUE proc);
static int
-mark_marshal_compat_i(st_data_t key, st_data_t value)
+mark_marshal_compat_i(st_data_t key, st_data_t value, st_data_t _)
{
marshal_compat_t *p = (marshal_compat_t *)value;
rb_gc_mark(p->newclass);
@@ -151,16 +163,12 @@ rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE),
st_insert(compat_allocator_table(), (st_data_t)allocator, (st_data_t)compat);
}
-#define MARSHAL_INFECTION FL_TAINT
-STATIC_ASSERT(marshal_infection_is_int, MARSHAL_INFECTION == (int)MARSHAL_INFECTION);
-
struct dump_arg {
VALUE str, dest;
st_table *symbols;
st_table *data;
st_table *compat_tbl;
st_table *encodings;
- int infection;
};
struct dump_call_arg {
@@ -259,8 +267,9 @@ class2path(VALUE klass)
return path;
}
+int ruby_marshal_write_long(long x, char *buf);
static void w_long(long, struct dump_arg*);
-static void w_encoding(VALUE encname, struct dump_call_arg *arg);
+static int w_encoding(VALUE encname, struct dump_call_arg *arg);
static VALUE encoding_name(VALUE obj, struct dump_arg *arg);
static void
@@ -268,7 +277,6 @@ w_nbyte(const char *s, long n, struct dump_arg *arg)
{
VALUE buf = arg->str;
rb_str_buf_cat(buf, s, n);
- RBASIC(buf)->flags |= arg->infection;
if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
rb_io_write(arg->dest, buf);
rb_str_resize(buf, 0);
@@ -301,26 +309,36 @@ static void
w_long(long x, struct dump_arg *arg)
{
char buf[sizeof(long)+1];
+ int i = ruby_marshal_write_long(x, buf);
+ if (i < 0) {
+ rb_raise(rb_eTypeError, "long too big to dump");
+ }
+ w_nbyte(buf, i, arg);
+}
+
+int
+ruby_marshal_write_long(long x, char *buf)
+{
int i;
#if SIZEOF_LONG > 4
if (!(RSHIFT(x, 31) == 0 || RSHIFT(x, 31) == -1)) {
/* big long does not fit in 4 bytes */
- rb_raise(rb_eTypeError, "long too big to dump");
+ return -1;
}
#endif
if (x == 0) {
- w_byte(0, arg);
- return;
+ buf[0] = 0;
+ return 1;
}
if (0 < x && x < 123) {
- w_byte((char)(x + 5), arg);
- return;
+ buf[0] = (char)(x + 5);
+ return 1;
}
if (-124 < x && x < 0) {
- w_byte((char)((x - 5)&0xff), arg);
- return;
+ buf[0] = (char)((x - 5)&0xff);
+ return 1;
}
for (i=1;i<(int)sizeof(long)+1;i++) {
buf[i] = (char)(x & 0xff);
@@ -334,7 +352,7 @@ w_long(long x, struct dump_arg *arg)
break;
}
}
- w_nbyte(buf, i+1, arg);
+ return i+1;
}
#ifdef DBL_MANT_DIG
@@ -362,12 +380,12 @@ load_mantissa(double d, const char *buf, long len)
do {
m = 0;
switch (len) {
- default: m = *buf++ & 0xff;
+ default: m = *buf++ & 0xff; /* fall through */
#if MANT_BITS > 24
- case 3: m = (m << 8) | (*buf++ & 0xff);
+ case 3: m = (m << 8) | (*buf++ & 0xff); /* fall through */
#endif
#if MANT_BITS > 16
- case 2: m = (m << 8) | (*buf++ & 0xff);
+ case 2: m = (m << 8) | (*buf++ & 0xff); /* fall through */
#endif
#if MANT_BITS > 8
case 1: m = (m << 8) | (*buf++ & 0xff);
@@ -404,8 +422,8 @@ w_float(double d, struct dump_arg *arg)
w_cstr("nan", arg);
}
else if (d == 0.0) {
- if (1.0/d < 0) w_cstr("-0", arg);
- else w_cstr("0", arg);
+ if (signbit(d)) w_cstr("-0", arg);
+ else w_cstr("0", arg);
}
else {
int decpt, sign, digs, len = 0;
@@ -490,8 +508,9 @@ w_unique(VALUE s, struct dump_arg *arg)
static void w_object(VALUE,struct dump_arg*,int);
static int
-hash_each(VALUE key, VALUE value, struct dump_call_arg *arg)
+hash_each(VALUE key, VALUE value, VALUE v)
{
+ struct dump_call_arg *arg = (void *)v;
w_object(key, arg->arg, arg->limit);
w_object(value, arg->arg, arg->limit);
return ST_CONTINUE;
@@ -513,10 +532,13 @@ w_extended(VALUE klass, struct dump_arg *arg, int check)
klass = RCLASS_SUPER(klass);
}
while (BUILTIN_TYPE(klass) == T_ICLASS) {
- VALUE path = rb_class_name(RBASIC(klass)->klass);
- w_byte(TYPE_EXTENDED, arg);
- w_unique(path, arg);
- klass = RCLASS_SUPER(klass);
+ if (!FL_TEST(klass, RICLASS_IS_ORIGIN) ||
+ BUILTIN_TYPE(RBASIC(klass)->klass) != T_MODULE) {
+ VALUE path = rb_class_name(RBASIC(klass)->klass);
+ w_byte(TYPE_EXTENDED, arg);
+ w_unique(path, arg);
+ }
+ klass = RCLASS_SUPER(klass);
}
}
@@ -551,16 +573,37 @@ w_uclass(VALUE obj, VALUE super, struct dump_arg *arg)
}
}
-#define to_be_skipped_id(id) (id == rb_id_encoding() || id == rb_intern("E") || !rb_id2str(id))
+#define to_be_skipped_id(id) (id == rb_id_encoding() || id == s_encoding_short || id == s_ruby2_keywords_flag || !rb_id2str(id))
+
+struct w_ivar_arg {
+ struct dump_call_arg *dump;
+ st_data_t num_ivar;
+};
static int
w_obj_each(st_data_t key, st_data_t val, st_data_t a)
{
ID id = (ID)key;
VALUE value = (VALUE)val;
- struct dump_call_arg *arg = (struct dump_call_arg *)a;
+ struct w_ivar_arg *ivarg = (struct w_ivar_arg *)a;
+ struct dump_call_arg *arg = ivarg->dump;
- if (to_be_skipped_id(id)) return ST_CONTINUE;
+ if (to_be_skipped_id(id)) {
+ if (id == s_encoding_short) {
+ rb_warn("instance variable `"name_s_encoding_short"' on class %"PRIsVALUE" is not dumped",
+ CLASS_OF(arg->obj));
+ }
+ if (id == s_ruby2_keywords_flag) {
+ rb_warn("instance variable `"name_s_ruby2_keywords_flag"' on class %"PRIsVALUE" is not dumped",
+ CLASS_OF(arg->obj));
+ }
+ return ST_CONTINUE;
+ }
+ if (!ivarg->num_ivar) {
+ rb_raise(rb_eRuntimeError, "instance variable added to %"PRIsVALUE" instance",
+ CLASS_OF(arg->obj));
+ }
+ --ivarg->num_ivar;
w_symbol(ID2SYM(id), arg->arg);
w_object(value, arg->arg, arg->limit);
return ST_CONTINUE;
@@ -577,32 +620,37 @@ obj_count_ivars(st_data_t key, st_data_t val, st_data_t a)
static VALUE
encoding_name(VALUE obj, struct dump_arg *arg)
{
- int encidx = rb_enc_get_index(obj);
- rb_encoding *enc = 0;
- st_data_t name;
+ if (rb_enc_capable(obj)) {
+ int encidx = rb_enc_get_index(obj);
+ rb_encoding *enc = 0;
+ st_data_t name;
- if (encidx <= 0 || !(enc = rb_enc_from_index(encidx))) {
- return Qnil;
- }
+ if (encidx <= 0 || !(enc = rb_enc_from_index(encidx))) {
+ return Qnil;
+ }
- /* special treatment for US-ASCII and UTF-8 */
- if (encidx == rb_usascii_encindex()) {
- return Qfalse;
- }
- else if (encidx == rb_utf8_encindex()) {
- return Qtrue;
- }
+ /* special treatment for US-ASCII and UTF-8 */
+ if (encidx == rb_usascii_encindex()) {
+ return Qfalse;
+ }
+ else if (encidx == rb_utf8_encindex()) {
+ return Qtrue;
+ }
- if (arg->encodings ?
- !st_lookup(arg->encodings, (st_data_t)rb_enc_name(enc), &name) :
- (arg->encodings = st_init_strcasetable(), 1)) {
- name = (st_data_t)rb_str_new_cstr(rb_enc_name(enc));
- st_insert(arg->encodings, (st_data_t)rb_enc_name(enc), name);
+ if (arg->encodings ?
+ !st_lookup(arg->encodings, (st_data_t)rb_enc_name(enc), &name) :
+ (arg->encodings = st_init_strcasetable(), 1)) {
+ name = (st_data_t)rb_str_new_cstr(rb_enc_name(enc));
+ st_insert(arg->encodings, (st_data_t)rb_enc_name(enc), name);
+ }
+ return (VALUE)name;
+ }
+ else {
+ return Qnil;
}
- return (VALUE)name;
}
-static void
+static int
w_encoding(VALUE encname, struct dump_call_arg *arg)
{
int limit = arg->limit;
@@ -610,13 +658,15 @@ w_encoding(VALUE encname, struct dump_call_arg *arg)
switch (encname) {
case Qfalse:
case Qtrue:
- w_symbol(ID2SYM(rb_intern("E")), arg->arg);
+ w_symbol(ID2SYM(s_encoding_short), arg->arg);
w_object(encname, arg->arg, limit);
+ return 1;
case Qnil:
- return;
+ return 0;
}
w_symbol(ID2SYM(rb_id_encoding()), arg->arg);
w_object(encname, arg->arg, limit);
+ return 1;
}
static st_index_t
@@ -624,6 +674,7 @@ has_ivars(VALUE obj, VALUE encname, VALUE *ivobj)
{
st_index_t enc = !NIL_P(encname);
st_index_t num = 0;
+ st_index_t ruby2_keywords_flag = 0;
if (SPECIAL_CONST_P(obj)) goto generic;
switch (BUILTIN_TYPE(obj)) {
@@ -631,22 +682,44 @@ has_ivars(VALUE obj, VALUE encname, VALUE *ivobj)
case T_CLASS:
case T_MODULE:
break; /* counted elsewhere */
+ case T_HASH:
+ ruby2_keywords_flag = RHASH(obj)->basic.flags & RHASH_PASS_AS_KEYWORDS ? 1 : 0;
+ /* fall through */
default:
generic:
rb_ivar_foreach(obj, obj_count_ivars, (st_data_t)&num);
- if (num) *ivobj = obj;
+ if (ruby2_keywords_flag || num) *ivobj = obj;
}
- return num + enc;
+ return num + enc + ruby2_keywords_flag;
+}
+
+static void
+w_ivar_each(VALUE obj, st_index_t num, struct dump_call_arg *arg)
+{
+ struct w_ivar_arg ivarg = {arg, num};
+ if (!num) return;
+ rb_ivar_foreach(obj, w_obj_each, (st_data_t)&ivarg);
+ if (ivarg.num_ivar) {
+ rb_raise(rb_eRuntimeError, "instance variable removed from %"PRIsVALUE" instance",
+ CLASS_OF(arg->obj));
+ }
}
static void
w_ivar(st_index_t num, VALUE ivobj, VALUE encname, struct dump_call_arg *arg)
{
w_long(num, arg->arg);
- w_encoding(encname, arg);
- if (ivobj != Qundef) {
- rb_ivar_foreach(ivobj, w_obj_each, (st_data_t)arg);
+ num -= w_encoding(encname, arg);
+ if (RB_TYPE_P(ivobj, T_HASH) && (RHASH(ivobj)->basic.flags & RHASH_PASS_AS_KEYWORDS)) {
+ int limit = arg->limit;
+ if (limit >= 0) ++limit;
+ w_symbol(ID2SYM(s_ruby2_keywords_flag), arg->arg);
+ w_object(Qtrue, arg->arg, limit);
+ num--;
+ }
+ if (ivobj != Qundef && num) {
+ w_ivar_each(ivobj, num, arg);
}
}
@@ -657,9 +730,7 @@ w_objivar(VALUE obj, struct dump_call_arg *arg)
rb_ivar_foreach(obj, obj_count_ivars, (st_data_t)&num);
w_long(num, arg->arg);
- if (num != 0) {
- rb_ivar_foreach(obj, w_obj_each, (st_data_t)arg);
- }
+ w_ivar_each(obj, num, arg);
}
static void
@@ -678,6 +749,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
if (limit > 0) limit--;
c_arg.limit = limit;
c_arg.arg = arg;
+ c_arg.obj = obj;
if (st_lookup(arg->data, obj, &num)) {
w_byte(TYPE_LINK, arg);
@@ -724,8 +796,6 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
rb_builtin_type_name(BUILTIN_TYPE(obj)));
}
- arg->infection |= (int)FL_TEST(obj, MARSHAL_INFECTION);
-
if (rb_obj_respond_to(obj, s_mdump, TRUE)) {
st_add_direct(arg->data, obj, arg->data->num_entries);
@@ -815,6 +885,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
char sign = BIGNUM_SIGN(obj) ? '+' : '-';
size_t len = BIGNUM_LEN(obj);
size_t slen;
+ size_t j;
BDIGIT *d = BIGNUM_DIGITS(obj);
slen = SHORTLEN(len);
@@ -824,7 +895,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
w_byte(sign, arg);
w_long((long)slen, arg);
- while (len--) {
+ for (j = 0; j < len; j++) {
#if SIZEOF_BDIGIT > SIZEOF_SHORT
BDIGIT num = *d;
int i;
@@ -832,7 +903,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
for (i=0; i<SIZEOF_BDIGIT; i+=SIZEOF_SHORT) {
w_short(num & SHORTMASK, arg);
num = SHORTDN(num);
- if (len == 0 && num == 0) break;
+ if (j == len - 1 && num == 0) break;
}
#else
w_short(*d, arg);
@@ -879,13 +950,13 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
if (NIL_P(RHASH_IFNONE(obj))) {
w_byte(TYPE_HASH, arg);
}
- else if (FL_TEST(obj, HASH_PROC_DEFAULT)) {
+ else if (FL_TEST(obj, RHASH_PROC_DEFAULT)) {
rb_raise(rb_eTypeError, "can't dump hash with default proc");
}
else {
w_byte(TYPE_HASH_DEF, arg);
}
- w_long(RHASH_SIZE(obj), arg);
+ w_long(rb_hash_size_num(obj), arg);
rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg);
if (!NIL_P(RHASH_IFNONE(obj))) {
w_object(RHASH_IFNONE(obj), arg, limit);
@@ -1000,7 +1071,7 @@ io_needed(void)
* * objects which define singleton methods
*/
static VALUE
-marshal_dump(int argc, VALUE *argv)
+marshal_dump(int argc, VALUE *argv, VALUE _)
{
VALUE obj, port, a1, a2;
int limit = -1;
@@ -1030,7 +1101,6 @@ rb_marshal_dump_limited(VALUE obj, VALUE port, int limit)
arg->dest = 0;
arg->symbols = st_init_numtable();
arg->data = rb_init_identtable();
- arg->infection = 0;
arg->compat_tbl = 0;
arg->encodings = 0;
arg->str = rb_str_buf_new(0);
@@ -1067,9 +1137,9 @@ struct load_arg {
long offset;
st_table *symbols;
st_table *data;
+ st_table *partial_objects;
VALUE proc;
st_table *compat_tbl;
- int infection;
};
static VALUE
@@ -1094,6 +1164,7 @@ mark_load_arg(void *ptr)
return;
rb_mark_tbl(p->symbols);
rb_mark_tbl(p->data);
+ rb_mark_tbl(p->partial_objects);
rb_mark_hash(p->compat_tbl);
}
@@ -1148,7 +1219,6 @@ r_byte1_buffered(struct load_arg *arg)
str = load_funcall(arg, arg->src, s_read, 1, &n);
if (NIL_P(str)) too_short();
StringValue(str);
- arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
memcpy(arg->buf, RSTRING_PTR(str), RSTRING_LEN(str));
arg->offset = 0;
arg->buflen = RSTRING_LEN(str);
@@ -1183,6 +1253,8 @@ r_byte(struct load_arg *arg)
return c;
}
+NORETURN(static void long_toobig(int size));
+
static void
long_toobig(int size)
{
@@ -1223,6 +1295,19 @@ r_long(struct load_arg *arg)
return x;
}
+long
+ruby_marshal_read_long(const char **buf, long len)
+{
+ long x;
+ struct RString src;
+ struct load_arg arg;
+ memset(&arg, 0, sizeof(arg));
+ arg.src = rb_setup_fake_str(&src, *buf, len, 0);
+ x = r_long(&arg);
+ *buf += arg.offset;
+ return x;
+}
+
static VALUE
r_bytes1(long len, struct load_arg *arg)
{
@@ -1232,7 +1317,6 @@ r_bytes1(long len, struct load_arg *arg)
if (NIL_P(str)) too_short();
StringValue(str);
if (RSTRING_LEN(str) != len) too_short();
- arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
return str;
}
@@ -1263,7 +1347,6 @@ r_bytes1_buffered(long len, struct load_arg *arg)
tmp_len = RSTRING_LEN(tmp);
if (tmp_len < need_len) too_short();
- arg->infection |= (int)FL_TEST(tmp, MARSHAL_INFECTION);
str = rb_str_new(arg->buf+arg->offset, buflen);
rb_str_cat(str, RSTRING_PTR(tmp), need_len);
@@ -1310,6 +1393,13 @@ r_bytes0(long len, struct load_arg *arg)
return str;
}
+static inline int
+name_equal(const char *name, size_t nlen, const char *p, long l)
+{
+ if ((size_t)l != nlen || *p != *name) return 0;
+ return nlen == 1 || memcmp(p+1, name+1, nlen-1) == 0;
+}
+
static int
sym2encidx(VALUE sym, VALUE val)
{
@@ -1319,12 +1409,11 @@ sym2encidx(VALUE sym, VALUE val)
if (rb_enc_get_index(sym) != ENCINDEX_US_ASCII) return -1;
RSTRING_GETMEM(sym, p, l);
if (l <= 0) return -1;
- if (l == sizeof(name_encoding) &&
- memcmp(p, name_encoding, sizeof(name_encoding)) == 0) {
+ if (name_equal(name_encoding, sizeof(name_encoding), p, l)) {
int idx = rb_enc_find_index(StringValueCStr(val));
return idx;
}
- else if (l == 1 && *p == 'E') {
+ if (name_equal(name_s_encoding_short, rb_strlen_lit(name_s_encoding_short), p, l)) {
if (val == Qfalse) return rb_usascii_encindex();
else if (val == Qtrue) return rb_utf8_encindex();
/* bogus ignore */
@@ -1332,6 +1421,20 @@ sym2encidx(VALUE sym, VALUE val)
return -1;
}
+static int
+ruby2_keywords_flag_check(VALUE sym)
+{
+ const char *p;
+ long l;
+ if (rb_enc_get_index(sym) != ENCINDEX_US_ASCII) return 0;
+ RSTRING_GETMEM(sym, p, l);
+ if (l <= 0) return 0;
+ if (name_equal(name_s_ruby2_keywords_flag, rb_strlen_lit(name_s_ruby2_keywords_flag), p, l)) {
+ return 1;
+ }
+ return 0;
+}
+
static VALUE
r_symlink(struct load_arg *arg)
{
@@ -1361,7 +1464,13 @@ r_symreal(struct load_arg *arg, int ivar)
idx = sym2encidx(sym, r_object(arg));
}
}
- if (idx > 0) rb_enc_associate_index(s, idx);
+ if (idx > 0) {
+ rb_enc_associate_index(s, idx);
+ if (rb_enc_str_coderange(s) == ENC_CODERANGE_BROKEN) {
+ rb_raise(rb_eArgError, "invalid byte sequence in %s: %+"PRIsVALUE,
+ rb_enc_name(rb_enc_from_index(idx)), s);
+ }
+ }
return s;
}
@@ -1403,19 +1512,13 @@ r_string(struct load_arg *arg)
static VALUE
r_entry0(VALUE v, st_index_t num, struct load_arg *arg)
{
- st_data_t real_obj = (VALUE)Qundef;
- if (arg->compat_tbl && st_lookup(arg->compat_tbl, v, &real_obj)) {
- st_insert(arg->data, num, (st_data_t)real_obj);
- }
- else {
- st_insert(arg->data, num, (st_data_t)v);
- }
- if (arg->infection &&
- !RB_TYPE_P(v, T_CLASS) && !RB_TYPE_P(v, T_MODULE)) {
- OBJ_TAINT(v);
- if ((VALUE)real_obj != Qundef)
- OBJ_TAINT((VALUE)real_obj);
+ st_data_t real_obj = (st_data_t)v;
+ if (arg->compat_tbl) {
+ /* real_obj is kept if not found */
+ st_lookup(arg->compat_tbl, v, &real_obj);
}
+ st_insert(arg->data, num, real_obj);
+ st_insert(arg->partial_objects, (st_data_t)real_obj, Qtrue);
return v;
}
@@ -1446,10 +1549,15 @@ r_post_proc(VALUE v, struct load_arg *arg)
}
static VALUE
-r_leave(VALUE v, struct load_arg *arg)
+r_leave(VALUE v, struct load_arg *arg, bool partial)
{
v = r_fixup_compat(v, arg);
- v = r_post_proc(v, arg);
+ if (!partial) {
+ st_data_t data;
+ st_data_t key = (st_data_t)v;
+ st_delete(arg->partial_objects, &key, &data);
+ v = r_post_proc(v, arg);
+ }
return v;
}
@@ -1483,11 +1591,24 @@ r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg)
VALUE val = r_object(arg);
int idx = sym2encidx(sym, val);
if (idx >= 0) {
- rb_enc_associate_index(obj, idx);
+ if (rb_enc_capable(obj)) {
+ rb_enc_associate_index(obj, idx);
+ }
+ else {
+ rb_raise(rb_eArgError, "%"PRIsVALUE" is not enc_capable", obj);
+ }
if (has_encoding) *has_encoding = TRUE;
}
- else {
- rb_ivar_set(obj, rb_intern_str(sym), val);
+ else if (ruby2_keywords_flag_check(sym)) {
+ if (RB_TYPE_P(obj, T_HASH)) {
+ RHASH(obj)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
+ }
+ else {
+ rb_raise(rb_eArgError, "ruby2_keywords flag is given but %"PRIsVALUE" is not a Hash", obj);
+ }
+ }
+ else {
+ rb_ivar_set(obj, rb_intern_str(sym), val);
}
} while (--len > 0);
}
@@ -1563,7 +1684,7 @@ append_extmod(VALUE obj, VALUE extmod)
} while (0)
static VALUE
-r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
+r_object0(struct load_arg *arg, bool partial, int *ivp, VALUE extmod)
{
VALUE v = Qnil;
int type = r_byte(arg);
@@ -1577,15 +1698,18 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
rb_raise(rb_eArgError, "dump format error (unlinked)");
}
v = (VALUE)link;
- v = r_post_proc(v, arg);
+ if (!st_lookup(arg->partial_objects, (st_data_t)v, &link)) {
+ v = r_post_proc(v, arg);
+ }
break;
case TYPE_IVAR:
{
int ivar = TRUE;
- v = r_object0(arg, &ivar, extmod);
+ v = r_object0(arg, true, &ivar, extmod);
if (ivar) r_ivar(v, NULL, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1598,7 +1722,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
if (RB_TYPE_P(m, T_CLASS)) { /* prepended */
VALUE c;
- v = r_object0(arg, 0, Qnil);
+ v = r_object0(arg, true, 0, Qnil);
c = CLASS_OF(v);
if (c != m || FL_TEST(c, FL_SINGLETON)) {
rb_raise(rb_eArgError,
@@ -1615,7 +1739,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
must_be_module(m, path);
rb_ary_push(extmod, m);
- v = r_object0(arg, 0, extmod);
+ v = r_object0(arg, true, 0, extmod);
while (RARRAY_LEN(extmod) > 0) {
m = rb_ary_pop(extmod);
rb_extend_object(v, m);
@@ -1631,10 +1755,9 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
if (FL_TEST(c, FL_SINGLETON)) {
rb_raise(rb_eTypeError, "singleton can't be loaded");
}
- v = r_object0(arg, 0, extmod);
+ v = r_object0(arg, partial, 0, extmod);
if (rb_special_const_p(v) || RB_TYPE_P(v, T_OBJECT) || RB_TYPE_P(v, T_CLASS)) {
- format_error:
- rb_raise(rb_eArgError, "dump format error (user class)");
+ goto format_error;
}
if (RB_TYPE_P(v, T_MODULE) || !RTEST(rb_class_inherited_p(c, RBASIC(v)->klass))) {
VALUE tmp = rb_obj_alloc(c);
@@ -1645,19 +1768,22 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
}
break;
+ format_error:
+ rb_raise(rb_eArgError, "dump format error (user class)");
+
case TYPE_NIL:
v = Qnil;
- v = r_leave(v, arg);
+ v = r_leave(v, arg, false);
break;
case TYPE_TRUE:
v = Qtrue;
- v = r_leave(v, arg);
+ v = r_leave(v, arg, false);
break;
case TYPE_FALSE:
v = Qfalse;
- v = r_leave(v, arg);
+ v = r_leave(v, arg, false);
break;
case TYPE_FIXNUM:
@@ -1665,7 +1791,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
long i = r_long(arg);
v = LONG2FIX(i);
}
- v = r_leave(v, arg);
+ v = r_leave(v, arg, false);
break;
case TYPE_FLOAT:
@@ -1675,13 +1801,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
const char *ptr = RSTRING_PTR(str);
if (strcmp(ptr, "nan") == 0) {
- d = NAN;
+ d = nan("");
}
else if (strcmp(ptr, "inf") == 0) {
- d = INFINITY;
+ d = HUGE_VAL;
}
else if (strcmp(ptr, "-inf") == 0) {
- d = -INFINITY;
+ d = -HUGE_VAL;
}
else {
char *e;
@@ -1690,7 +1816,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
}
v = DBL2NUM(d);
v = r_entry(v, arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, false);
}
break;
@@ -1707,13 +1833,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
INTEGER_PACK_LITTLE_ENDIAN | (sign == '-' ? INTEGER_PACK_NEGATIVE : 0));
rb_str_resize(data, 0L);
v = r_entry(v, arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, false);
}
break;
case TYPE_STRING:
v = r_entry(r_string(arg), arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
break;
case TYPE_REGEXP:
@@ -1741,13 +1867,14 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
case 'L': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'X': case 'Y':
if (bs & 1) --dst;
+ /* fall through */
default: bs = 0; break;
}
}
rb_str_set_len(str, dst - ptr);
}
v = r_entry0(rb_reg_new_str(str, options), idx, arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1762,7 +1889,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
rb_ary_push(v, r_object(arg));
arg->readable--;
}
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
arg->readable++;
}
break;
@@ -1785,7 +1912,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
if (type == TYPE_HASH_DEF) {
RHASH_SET_IFNONE(v, r_object(arg));
}
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1811,20 +1938,33 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
arg->readable += (len - 1) * 2;
v = r_entry0(v, idx, arg);
values = rb_ary_new2(len);
- for (i=0; i<len; i++) {
- VALUE n = rb_sym2str(RARRAY_AREF(mem, i));
- slot = r_symbol(arg);
-
- if (!rb_str_equal(n, slot)) {
- rb_raise(rb_eTypeError, "struct %"PRIsVALUE" not compatible (:%"PRIsVALUE" for :%"PRIsVALUE")",
- rb_class_name(klass),
- slot, n);
+ {
+ VALUE keywords = Qfalse;
+ if (RTEST(rb_struct_s_keyword_init(klass))) {
+ keywords = rb_hash_new();
+ rb_ary_push(values, keywords);
+ }
+
+ for (i=0; i<len; i++) {
+ VALUE n = rb_sym2str(RARRAY_AREF(mem, i));
+ slot = r_symbol(arg);
+
+ if (!rb_str_equal(n, slot)) {
+ rb_raise(rb_eTypeError, "struct %"PRIsVALUE" not compatible (:%"PRIsVALUE" for :%"PRIsVALUE")",
+ rb_class_name(klass),
+ slot, n);
+ }
+ if (keywords) {
+ rb_hash_aset(keywords, RARRAY_AREF(mem, i), r_object(arg));
+ }
+ else {
+ rb_ary_push(values, r_object(arg));
+ }
+ arg->readable -= 2;
}
- rb_ary_push(values, r_object(arg));
- arg->readable -= 2;
}
rb_struct_initialize(v, values);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
arg->readable += 2;
}
break;
@@ -1851,7 +1991,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
marshal_compat_t *compat = (marshal_compat_t*)d;
v = compat->loader(klass, v);
}
- v = r_post_proc(v, arg);
+ if (!partial) v = r_post_proc(v, arg);
}
break;
@@ -1893,7 +2033,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
}
v = r_entry0(v, idx, arg);
r_ivar(v, NULL, arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1914,9 +2054,9 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
"class %"PRIsVALUE" needs to have instance method `_load_data'",
name);
}
- r = r_object0(arg, 0, extmod);
+ r = r_object0(arg, partial, 0, extmod);
load_funcall(arg, v, s_load_data, 1, &r);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1927,7 +2067,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
v = rb_path_to_class(str);
prohibit_ivar("class/module", str);
v = r_entry(v, arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1938,7 +2078,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
v = path2class(str);
prohibit_ivar("class", str);
v = r_entry(v, arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1949,7 +2089,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
v = path2module(str);
prohibit_ivar("module", str);
v = r_entry(v, arg);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
}
break;
@@ -1962,7 +2102,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
v = r_symreal(arg, 0);
}
v = rb_str_intern(v);
- v = r_leave(v, arg);
+ v = r_leave(v, arg, partial);
break;
case TYPE_SYMLINK:
@@ -1984,7 +2124,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
static VALUE
r_object(struct load_arg *arg)
{
- return r_object0(arg, 0, Qnil);
+ return r_object0(arg, false, 0, Qnil);
}
static void
@@ -2002,6 +2142,8 @@ clear_load_arg(struct load_arg *arg)
arg->symbols = 0;
st_free_table(arg->data);
arg->data = 0;
+ st_free_table(arg->partial_objects);
+ arg->partial_objects = 0;
if (arg->compat_tbl) {
st_free_table(arg->compat_tbl);
arg->compat_tbl = 0;
@@ -2023,7 +2165,7 @@ clear_load_arg(struct load_arg *arg)
* Please see the overview for further details.
*/
static VALUE
-marshal_load(int argc, VALUE *argv)
+marshal_load(int argc, VALUE *argv, VALUE _)
{
VALUE port, proc;
@@ -2036,29 +2178,27 @@ marshal_load(int argc, VALUE *argv)
VALUE
rb_marshal_load_with_proc(VALUE port, VALUE proc)
{
- int major, minor, infection = 0;
+ int major, minor;
VALUE v;
VALUE wrapper; /* used to avoid memory leak in case of exception */
struct load_arg *arg;
v = rb_check_string_type(port);
if (!NIL_P(v)) {
- infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
port = v;
}
else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
rb_check_funcall(port, s_binmode, 0, 0);
- infection = (int)FL_TAINT;
}
else {
io_needed();
}
wrapper = TypedData_Make_Struct(0, struct load_arg, &load_arg_data, arg);
- arg->infection = infection;
arg->src = port;
arg->offset = 0;
arg->symbols = st_init_numtable();
arg->data = rb_init_identtable();
+ arg->partial_objects = rb_init_identtable();
arg->compat_tbl = 0;
arg->proc = 0;
arg->readable = 0;
@@ -2204,9 +2344,6 @@ rb_marshal_load_with_proc(VALUE port, VALUE proc)
void
Init_marshal(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
VALUE rb_mMarshal = rb_define_module("Marshal");
#define set_id(sym) sym = rb_intern_const(name_##sym)
set_id(s_dump);
@@ -2221,6 +2358,8 @@ Init_marshal(void)
set_id(s_read);
set_id(s_write);
set_id(s_binmode);
+ set_id(s_encoding_short);
+ set_id(s_ruby2_keywords_flag);
rb_define_module_function(rb_mMarshal, "dump", marshal_dump, -1);
rb_define_module_function(rb_mMarshal, "load", marshal_load, -1);
@@ -2240,7 +2379,7 @@ compat_allocator_table(void)
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
compat_allocator_tbl_wrapper =
- Data_Wrap_Struct(rb_cData, mark_marshal_compat_t, 0, compat_allocator_tbl);
+ Data_Wrap_Struct(0, mark_marshal_compat_t, 0, compat_allocator_tbl);
rb_gc_register_mark_object(compat_allocator_tbl_wrapper);
return compat_allocator_tbl;
}
diff --git a/math.c b/math.c
index ce49879305..f64ad93c06 100644
--- a/math.c
+++ b/math.c
@@ -9,13 +9,22 @@
**********************************************************************/
+#include "ruby/internal/config.h"
+
#ifdef _MSC_VER
# define _USE_MATH_DEFINES 1
#endif
-#include "internal.h"
+
+#include <errno.h>
#include <float.h>
#include <math.h>
-#include <errno.h>
+
+#include "internal.h"
+#include "internal/bignum.h"
+#include "internal/complex.h"
+#include "internal/math.h"
+#include "internal/object.h"
+#include "internal/vm.h"
#if defined(HAVE_SIGNBIT) && defined(__GNUC__) && defined(__sun) && \
!defined(signbit)
@@ -382,8 +391,8 @@ math_atanh(VALUE unused_obj, VALUE x)
/* check for domain error */
if (d < -1.0 || +1.0 < d) domain_error("atanh");
/* check for pole error */
- if (d == -1.0) return DBL2NUM(-INFINITY);
- if (d == +1.0) return DBL2NUM(+INFINITY);
+ if (d == -1.0) return DBL2NUM(-HUGE_VAL);
+ if (d == +1.0) return DBL2NUM(+HUGE_VAL);
return DBL2NUM(atanh(d));
}
@@ -426,6 +435,7 @@ math_exp(VALUE unused_obj, VALUE x)
#endif
static double math_log1(VALUE x);
+FUNC_MINIMIZED(static VALUE math_log(int, const VALUE *, VALUE));
/*
* call-seq:
@@ -451,6 +461,12 @@ static double math_log1(VALUE x);
static VALUE
math_log(int argc, const VALUE *argv, VALUE unused_obj)
{
+ return rb_math_log(argc, argv);
+}
+
+VALUE
+rb_math_log(int argc, const VALUE *argv)
+{
VALUE x, base;
double d;
@@ -488,7 +504,7 @@ math_log1(VALUE x)
/* check for domain error */
if (d < 0.0) domain_error("log");
/* check for pole error */
- if (d == 0.0) return -INFINITY;
+ if (d == 0.0) return -HUGE_VAL;
return log(d) + numbits * M_LN2; /* log(d * 2 ** numbits) */
}
@@ -531,7 +547,7 @@ math_log2(VALUE unused_obj, VALUE x)
/* check for domain error */
if (d < 0.0) domain_error("log2");
/* check for pole error */
- if (d == 0.0) return DBL2NUM(-INFINITY);
+ if (d == 0.0) return DBL2NUM(-HUGE_VAL);
return DBL2NUM(log2(d) + numbits); /* log2(d * 2 ** numbits) */
}
@@ -561,11 +577,13 @@ math_log10(VALUE unused_obj, VALUE x)
/* check for domain error */
if (d < 0.0) domain_error("log10");
/* check for pole error */
- if (d == 0.0) return DBL2NUM(-INFINITY);
+ if (d == 0.0) return DBL2NUM(-HUGE_VAL);
return DBL2NUM(log10(d) + numbits * log10(2)); /* log10(d * 2 ** numbits) */
}
+static VALUE rb_math_sqrt(VALUE x);
+
/*
* call-seq:
* Math.sqrt(x) -> Float
@@ -623,7 +641,7 @@ f_signbit(VALUE x)
return f_negative_p(x);
}
-VALUE
+static VALUE
rb_math_sqrt(VALUE x)
{
double d;
@@ -682,7 +700,14 @@ rb_math_sqrt(VALUE x)
static VALUE
math_cbrt(VALUE unused_obj, VALUE x)
{
- return DBL2NUM(cbrt(Get_Double(x)));
+ double f = Get_Double(x);
+ double r = cbrt(f);
+#if defined __GLIBC__
+ if (isfinite(r)) {
+ r = (2.0 * r + (f / r / r)) / 3.0;
+ }
+#endif
+ return DBL2NUM(r);
}
/*
@@ -855,10 +880,10 @@ math_gamma(VALUE unused_obj, VALUE x)
/* check for domain error */
if (isinf(d)) {
if (signbit(d)) domain_error("gamma");
- return DBL2NUM(INFINITY);
+ return DBL2NUM(HUGE_VAL);
}
if (d == 0.0) {
- return signbit(d) ? DBL2NUM(-INFINITY) : DBL2NUM(INFINITY);
+ return signbit(d) ? DBL2NUM(-HUGE_VAL) : DBL2NUM(HUGE_VAL);
}
if (d == floor(d)) {
if (d < 0.0) domain_error("gamma");
@@ -893,11 +918,11 @@ math_lgamma(VALUE unused_obj, VALUE x)
/* check for domain error */
if (isinf(d)) {
if (signbit(d)) domain_error("lgamma");
- return rb_assoc_new(DBL2NUM(INFINITY), INT2FIX(1));
+ return rb_assoc_new(DBL2NUM(HUGE_VAL), INT2FIX(1));
}
if (d == 0.0) {
VALUE vsign = signbit(d) ? INT2FIX(-1) : INT2FIX(+1);
- return rb_assoc_new(DBL2NUM(INFINITY), vsign);
+ return rb_assoc_new(DBL2NUM(HUGE_VAL), vsign);
}
v = DBL2NUM(lgamma_r(d, &sign));
return rb_assoc_new(v, INT2FIX(sign));
@@ -923,13 +948,6 @@ exp1(cos)
exp1(cosh)
exp1(exp)
exp2(hypot)
-
-VALUE
-rb_math_log(int argc, const VALUE *argv)
-{
- return math_log(argc, argv, 0);
-}
-
exp1(sin)
exp1(sinh)
#if 0
@@ -975,7 +993,7 @@ InitVM_Math(void)
rb_define_const(rb_mMath, "PI", DBL2NUM(M_PI));
#ifdef M_E
- /* Definition of the mathematical constant E (e) as a Float number. */
+ /* Definition of the mathematical constant E for Euler's number (e) as a Float number. */
rb_define_const(rb_mMath, "E", DBL2NUM(M_E));
#else
rb_define_const(rb_mMath, "E", DBL2NUM(exp(1.0)));
diff --git a/memory_view.c b/memory_view.c
new file mode 100644
index 0000000000..a1ab240656
--- /dev/null
+++ b/memory_view.c
@@ -0,0 +1,869 @@
+/**********************************************************************
+
+ memory_view.c - Memory View
+
+ Copyright (C) 2020 Kenta Murata <mrkn@mrkn.jp>
+
+**********************************************************************/
+
+#include "internal.h"
+#include "internal/hash.h"
+#include "internal/variable.h"
+#include "internal/util.h"
+#include "ruby/memory_view.h"
+#include "vm_sync.h"
+
+#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
+# define INTPTR2NUM LL2NUM
+# define UINTPTR2NUM ULL2NUM
+#elif SIZEOF_INTPTR_T == SIZEOF_LONG
+# define INTPTR2NUM LONG2NUM
+# define UINTPTR2NUM ULONG2NUM
+#else
+# define INTPTR2NUM INT2NUM
+# define UINTPTR2NUM UINT2NUM
+#endif
+
+
+#define STRUCT_ALIGNOF(T, result) do { \
+ (result) = RUBY_ALIGNOF(T); \
+} while(0)
+
+// Exported Object Registry
+
+static st_table *exported_object_table = NULL;
+VALUE rb_memory_view_exported_object_registry = Qundef;
+
+static int
+exported_object_registry_mark_key_i(st_data_t key, st_data_t value, st_data_t data)
+{
+ rb_gc_mark(key);
+ return ST_CONTINUE;
+}
+
+static void
+exported_object_registry_mark(void *ptr)
+{
+ // Don't use RB_VM_LOCK_ENTER here. It is unnecessary during GC.
+ st_foreach(exported_object_table, exported_object_registry_mark_key_i, 0);
+}
+
+static void
+exported_object_registry_free(void *ptr)
+{
+ RB_VM_LOCK_ENTER();
+ st_clear(exported_object_table);
+ st_free_table(exported_object_table);
+ exported_object_table = NULL;
+ RB_VM_LOCK_LEAVE();
+}
+
+const rb_data_type_t rb_memory_view_exported_object_registry_data_type = {
+ "memory_view/exported_object_registry",
+ {
+ exported_object_registry_mark,
+ exported_object_registry_free,
+ 0,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static int
+exported_object_add_ref(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
+{
+ ASSERT_vm_locking();
+
+ if (existing) {
+ *val += 1;
+ }
+ else {
+ *val = 1;
+ }
+ return ST_CONTINUE;
+}
+
+static int
+exported_object_dec_ref(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
+{
+ ASSERT_vm_locking();
+
+ if (existing) {
+ *val -= 1;
+ if (*val == 0) {
+ return ST_DELETE;
+ }
+ }
+ return ST_CONTINUE;
+}
+
+static void
+register_exported_object(VALUE obj)
+{
+ RB_VM_LOCK_ENTER();
+ st_update(exported_object_table, (st_data_t)obj, exported_object_add_ref, 0);
+ RB_VM_LOCK_LEAVE();
+}
+
+static void
+unregister_exported_object(VALUE obj)
+{
+ RB_VM_LOCK_ENTER();
+ st_update(exported_object_table, (st_data_t)obj, exported_object_dec_ref, 0);
+ RB_VM_LOCK_LEAVE();
+}
+
+// MemoryView
+
+static ID id_memory_view;
+
+static const rb_data_type_t memory_view_entry_data_type = {
+ "memory_view/entry",
+ {
+ 0,
+ 0,
+ 0,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+/* Register memory view functions for the given class */
+bool
+rb_memory_view_register(VALUE klass, const rb_memory_view_entry_t *entry) {
+ Check_Type(klass, T_CLASS);
+ VALUE entry_obj = rb_ivar_lookup(klass, id_memory_view, Qnil);
+ if (! NIL_P(entry_obj)) {
+ rb_warning("Duplicated registration of memory view to %"PRIsVALUE, klass);
+ return false;
+ }
+ else {
+ entry_obj = TypedData_Wrap_Struct(0, &memory_view_entry_data_type, (void *)entry);
+ rb_ivar_set(klass, id_memory_view, entry_obj);
+ return true;
+ }
+}
+
+/* Examine whether the given memory view has row-major order strides. */
+bool
+rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view)
+{
+ const ssize_t ndim = view->ndim;
+ const ssize_t *shape = view->shape;
+ const ssize_t *strides = view->strides;
+ ssize_t n = view->item_size;
+ ssize_t i;
+ for (i = ndim - 1; i >= 0; --i) {
+ if (strides[i] != n) return false;
+ n *= shape[i];
+ }
+ return true;
+}
+
+/* Examine whether the given memory view has column-major order strides. */
+bool
+rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view)
+{
+ const ssize_t ndim = view->ndim;
+ const ssize_t *shape = view->shape;
+ const ssize_t *strides = view->strides;
+ ssize_t n = view->item_size;
+ ssize_t i;
+ for (i = 0; i < ndim; ++i) {
+ if (strides[i] != n) return false;
+ n *= shape[i];
+ }
+ return true;
+}
+
+/* Initialize strides array to represent the specified contiguous array. */
+void
+rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides)
+{
+ ssize_t i, n = item_size;
+ if (row_major_p) {
+ for (i = ndim - 1; i >= 0; --i) {
+ strides[i] = n;
+ n *= shape[i];
+ }
+ }
+ else { // column-major
+ for (i = 0; i < ndim; ++i) {
+ strides[i] = n;
+ n *= shape[i];
+ }
+ }
+}
+
+/* Initialize view to expose a simple byte array */
+bool
+rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly)
+{
+ view->obj = obj;
+ view->data = data;
+ view->byte_size = len;
+ view->readonly = readonly;
+ view->format = NULL;
+ view->item_size = 1;
+ view->item_desc.components = NULL;
+ view->item_desc.length = 0;
+ view->ndim = 1;
+ view->shape = NULL;
+ view->strides = NULL;
+ view->sub_offsets = NULL;
+ *((void **)&view->private) = NULL;
+
+ return true;
+}
+
+#ifdef HAVE_TRUE_LONG_LONG
+static const char native_types[] = "sSiIlLqQjJ";
+#else
+static const char native_types[] = "sSiIlLjJ";
+#endif
+static const char endianness_types[] = "sSiIlLqQjJ";
+
+typedef enum {
+ ENDIANNESS_NATIVE,
+ ENDIANNESS_LITTLE,
+ ENDIANNESS_BIG
+} endianness_t;
+
+static ssize_t
+get_format_size(const char *format, bool *native_p, ssize_t *alignment, endianness_t *endianness, ssize_t *count, const char **next_format, VALUE *error)
+{
+ RUBY_ASSERT(format != NULL);
+ RUBY_ASSERT(native_p != NULL);
+ RUBY_ASSERT(endianness != NULL);
+ RUBY_ASSERT(count != NULL);
+ RUBY_ASSERT(next_format != NULL);
+
+ *native_p = false;
+ *endianness = ENDIANNESS_NATIVE;
+ *count = 1;
+
+ const int type_char = *format;
+
+ int i = 1;
+ while (format[i]) {
+ switch (format[i]) {
+ case '!':
+ case '_':
+ if (strchr(native_types, type_char)) {
+ *native_p = true;
+ ++i;
+ }
+ else {
+ if (error) {
+ *error = rb_exc_new_str(rb_eArgError,
+ rb_sprintf("Unable to specify native size for '%c'", type_char));
+ }
+ return -1;
+ }
+ continue;
+
+ case '<':
+ case '>':
+ if (!strchr(endianness_types, type_char)) {
+ if (error) {
+ *error = rb_exc_new_str(rb_eArgError,
+ rb_sprintf("Unable to specify endianness for '%c'", type_char));
+ }
+ return -1;
+ }
+ if (*endianness != ENDIANNESS_NATIVE) {
+ *error = rb_exc_new_cstr(rb_eArgError, "Unable to use both '<' and '>' multiple times");
+ return -1;
+ }
+ *endianness = (format[i] == '<') ? ENDIANNESS_LITTLE : ENDIANNESS_BIG;
+ ++i;
+ continue;
+
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ // parse count
+ int ch = format[i];
+ if ('0' <= ch && ch <= '9') {
+ ssize_t n = 0;
+ while ('0' <= (ch = format[i]) && ch <= '9') {
+ n = 10*n + ruby_digit36_to_number_table[ch];
+ ++i;
+ }
+ *count = n;
+ }
+
+ *next_format = &format[i];
+
+ switch (type_char) {
+ case 'x': // padding
+ return 1;
+
+ case 'c': // signed char
+ case 'C': // unsigned char
+ return sizeof(char);
+
+ case 's': // s for int16_t, s! for signed short
+ case 'S': // S for uint16_t, S! for unsigned short
+ if (*native_p) {
+ STRUCT_ALIGNOF(short, *alignment);
+ return sizeof(short);
+ }
+ // fall through
+
+ case 'n': // n for big-endian 16bit unsigned integer
+ case 'v': // v for little-endian 16bit unsigned integer
+ STRUCT_ALIGNOF(int16_t, *alignment);
+ return 2;
+
+ case 'i': // i and i! for signed int
+ case 'I': // I and I! for unsigned int
+ STRUCT_ALIGNOF(int, *alignment);
+ return sizeof(int);
+
+ case 'l': // l for int32_t, l! for signed long
+ case 'L': // L for uint32_t, L! for unsigned long
+ if (*native_p) {
+ STRUCT_ALIGNOF(long, *alignment);
+ return sizeof(long);
+ }
+ // fall through
+
+ case 'N': // N for big-endian 32bit unsigned integer
+ case 'V': // V for little-endian 32bit unsigned integer
+ STRUCT_ALIGNOF(int32_t, *alignment);
+ return 4;
+
+ case 'f': // f for native float
+ case 'e': // e for little-endian float
+ case 'g': // g for big-endian float
+ STRUCT_ALIGNOF(float, *alignment);
+ return sizeof(float);
+
+ case 'q': // q for int64_t, q! for signed long long
+ case 'Q': // Q for uint64_t, Q! for unsigned long long
+ if (*native_p) {
+ STRUCT_ALIGNOF(LONG_LONG, *alignment);
+ return sizeof(LONG_LONG);
+ }
+ STRUCT_ALIGNOF(int64_t, *alignment);
+ return 8;
+
+ case 'd': // d for native double
+ case 'E': // E for little-endian double
+ case 'G': // G for big-endian double
+ STRUCT_ALIGNOF(double, *alignment);
+ return sizeof(double);
+
+ case 'j': // j for intptr_t
+ case 'J': // J for uintptr_t
+ STRUCT_ALIGNOF(intptr_t, *alignment);
+ return sizeof(intptr_t);
+
+ default:
+ *alignment = -1;
+ if (error) {
+ *error = rb_exc_new_str(rb_eArgError, rb_sprintf("Invalid type character '%c'", type_char));
+ }
+ return -1;
+ }
+}
+
+static inline ssize_t
+calculate_padding(ssize_t total, ssize_t alignment_size) {
+ if (alignment_size > 1) {
+ ssize_t res = total % alignment_size;
+ if (res > 0) {
+ return alignment_size - res;
+ }
+ }
+ return 0;
+}
+
+ssize_t
+rb_memory_view_parse_item_format(const char *format,
+ rb_memory_view_item_component_t **members,
+ size_t *n_members, const char **err)
+{
+ if (format == NULL) return 1;
+
+ VALUE error = Qnil;
+ ssize_t total = 0;
+ size_t len = 0;
+ bool alignment = false;
+ ssize_t max_alignment_size = 0;
+
+ const char *p = format;
+ if (*p == '|') { // alginment specifier
+ alignment = true;
+ ++format;
+ ++p;
+ }
+ while (*p) {
+ const char *q = p;
+
+ // ignore spaces
+ if (ISSPACE(*p)) {
+ while (ISSPACE(*p)) ++p;
+ continue;
+ }
+
+ bool native_size_p = false;
+ ssize_t alignment_size = 0;
+ endianness_t endianness = ENDIANNESS_NATIVE;
+ ssize_t count = 0;
+ const ssize_t size = get_format_size(p, &native_size_p, &alignment_size, &endianness, &count, &p, &error);
+ if (size < 0) {
+ if (err) *err = q;
+ return -1;
+ }
+ if (max_alignment_size < alignment_size) {
+ max_alignment_size = alignment_size;
+ }
+
+ const ssize_t padding = alignment ? calculate_padding(total, alignment_size) : 0;
+ total += padding + size * count;
+
+ if (*q != 'x') {
+ ++len;
+ }
+ }
+
+ // adjust total size with the alignment size of the largest element
+ if (alignment && max_alignment_size > 0) {
+ const ssize_t padding = calculate_padding(total, max_alignment_size);
+ total += padding;
+ }
+
+ if (members && n_members) {
+ rb_memory_view_item_component_t *buf = ALLOC_N(rb_memory_view_item_component_t, len);
+
+ ssize_t i = 0, offset = 0;
+ const char *p = format;
+ while (*p) {
+ const int type_char = *p;
+
+ bool native_size_p;
+ ssize_t alignment_size = 0;
+ endianness_t endianness = ENDIANNESS_NATIVE;
+ ssize_t count = 0;
+ const ssize_t size = get_format_size(p, &native_size_p, &alignment_size, &endianness, &count, &p, NULL);
+
+ const ssize_t padding = alignment ? calculate_padding(offset, alignment_size) : 0;
+ offset += padding;
+
+ if (type_char != 'x') {
+#ifdef WORDS_BIGENDIAN
+ bool little_endian_p = (endianness == ENDIANNESS_LITTLE);
+#else
+ bool little_endian_p = (endianness != ENDIANNESS_BIG);
+#endif
+
+ switch (type_char) {
+ case 'e':
+ case 'E':
+ case 'v':
+ case 'V':
+ little_endian_p = true;
+ break;
+ case 'g':
+ case 'G':
+ case 'n':
+ case 'N':
+ little_endian_p = false;
+ break;
+ default:
+ break;
+ }
+
+ buf[i++] = (rb_memory_view_item_component_t){
+ .format = type_char,
+ .native_size_p = native_size_p,
+ .little_endian_p = little_endian_p,
+ .offset = offset,
+ .size = size,
+ .repeat = count
+ };
+ }
+
+ offset += size * count;
+ }
+
+ *members = buf;
+ *n_members = len;
+ }
+
+ return total;
+}
+
+/* Return the item size. */
+ssize_t
+rb_memory_view_item_size_from_format(const char *format, const char **err)
+{
+ return rb_memory_view_parse_item_format(format, NULL, NULL, err);
+}
+
+/* Return the pointer to the item located by the given indices. */
+void *
+rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices)
+{
+ uint8_t *ptr = view->data;
+
+ if (view->ndim == 1) {
+ ssize_t stride = view->strides != NULL ? view->strides[0] : view->item_size;
+ return ptr + indices[0] * stride;
+ }
+
+ assert(view->shape != NULL);
+
+ ssize_t i;
+ if (view->strides == NULL) {
+ // row-major contiguous array
+ ssize_t stride = view->item_size;
+ for (i = 0; i < view->ndim; ++i) {
+ stride *= view->shape[i];
+ }
+ for (i = 0; i < view->ndim; ++i) {
+ stride /= view->shape[i];
+ ptr += indices[i] * stride;
+ }
+ }
+ else if (view->sub_offsets == NULL) {
+ // flat strided array
+ for (i = 0; i < view->ndim; ++i) {
+ ptr += indices[i] * view->strides[i];
+ }
+ }
+ else {
+ // indirect strided array
+ for (i = 0; i < view->ndim; ++i) {
+ ptr += indices[i] * view->strides[i];
+ if (view->sub_offsets[i] >= 0) {
+ ptr = *(uint8_t **)ptr + view->sub_offsets[i];
+ }
+ }
+ }
+
+ return ptr;
+}
+
+static void
+switch_endianness(uint8_t *buf, ssize_t len)
+{
+ RUBY_ASSERT(buf != NULL);
+ RUBY_ASSERT(len >= 0);
+
+ uint8_t *p = buf;
+ uint8_t *q = buf + len - 1;
+
+ while (q - p > 0) {
+ uint8_t t = *p;
+ *p = *q;
+ *q = t;
+ ++p;
+ --q;
+ }
+}
+
+static inline VALUE
+extract_item_member(const uint8_t *ptr, const rb_memory_view_item_component_t *member, const size_t i)
+{
+ RUBY_ASSERT(ptr != NULL);
+ RUBY_ASSERT(member != NULL);
+ RUBY_ASSERT(i < member->repeat);
+
+#ifdef WORDS_BIGENDIAN
+ const bool native_endian_p = !member->little_endian_p;
+#else
+ const bool native_endian_p = member->little_endian_p;
+#endif
+
+ const uint8_t *p = ptr + member->offset + i * member->size;
+
+ if (member->format == 'c') {
+ return INT2FIX(*(char *)p);
+ }
+ else if (member->format == 'C') {
+ return INT2FIX(*(unsigned char *)p);
+ }
+
+ union {
+ short s;
+ unsigned short us;
+ int i;
+ unsigned int ui;
+ long l;
+ unsigned long ul;
+ LONG_LONG ll;
+ unsigned LONG_LONG ull;
+ int16_t i16;
+ uint16_t u16;
+ int32_t i32;
+ uint32_t u32;
+ int64_t i64;
+ uint64_t u64;
+ intptr_t iptr;
+ uintptr_t uptr;
+ float f;
+ double d;
+ } val;
+
+ if (!native_endian_p) {
+ MEMCPY(&val, p, uint8_t, member->size);
+ switch_endianness((uint8_t *)&val, member->size);
+ }
+ else {
+ MEMCPY(&val, p, uint8_t, member->size);
+ }
+
+ switch (member->format) {
+ case 's':
+ if (member->native_size_p) {
+ return INT2FIX(val.s);
+ }
+ else {
+ return INT2FIX(val.i16);
+ }
+
+ case 'S':
+ case 'n':
+ case 'v':
+ if (member->native_size_p) {
+ return UINT2NUM(val.us);
+ }
+ else {
+ return INT2FIX(val.u16);
+ }
+
+ case 'i':
+ return INT2NUM(val.i);
+
+ case 'I':
+ return UINT2NUM(val.ui);
+
+ case 'l':
+ if (member->native_size_p) {
+ return LONG2NUM(val.l);
+ }
+ else {
+ return LONG2NUM(val.i32);
+ }
+
+ case 'L':
+ case 'N':
+ case 'V':
+ if (member->native_size_p) {
+ return ULONG2NUM(val.ul);
+ }
+ else {
+ return ULONG2NUM(val.u32);
+ }
+
+ case 'f':
+ case 'e':
+ case 'g':
+ return DBL2NUM(val.f);
+
+ case 'q':
+ if (member->native_size_p) {
+ return LL2NUM(val.ll);
+ }
+ else {
+#if SIZEOF_INT64_t == SIZEOF_LONG
+ return LONG2NUM(val.i64);
+#else
+ return LL2NUM(val.i64);
+#endif
+ }
+
+ case 'Q':
+ if (member->native_size_p) {
+ return ULL2NUM(val.ull);
+ }
+ else {
+#if SIZEOF_UINT64_t == SIZEOF_LONG
+ return ULONG2NUM(val.u64);
+#else
+ return ULL2NUM(val.u64);
+#endif
+ }
+
+ case 'd':
+ case 'E':
+ case 'G':
+ return DBL2NUM(val.d);
+
+ case 'j':
+ return INTPTR2NUM(val.iptr);
+
+ case 'J':
+ return UINTPTR2NUM(val.uptr);
+
+ default:
+ UNREACHABLE_RETURN(Qnil);
+ }
+}
+
+/* Return a value of the extracted member. */
+VALUE
+rb_memory_view_extract_item_member(const void *ptr, const rb_memory_view_item_component_t *member, const size_t i)
+{
+ if (ptr == NULL) return Qnil;
+ if (member == NULL) return Qnil;
+ if (i >= member->repeat) return Qnil;
+
+ return extract_item_member(ptr, member, i);
+}
+
+/* Return a value that consists of item members.
+ * When an item is a single member, the return value is a single value.
+ * When an item consists of multiple members, an array will be returned. */
+VALUE
+rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members)
+{
+ if (ptr == NULL) return Qnil;
+ if (members == NULL) return Qnil;
+ if (n_members == 0) return Qnil;
+
+ if (n_members == 1 && members[0].repeat == 1) {
+ return rb_memory_view_extract_item_member(ptr, members, 0);
+ }
+
+ size_t i, j;
+ VALUE item = rb_ary_new();
+ for (i = 0; i < n_members; ++i) {
+ for (j = 0; j < members[i].repeat; ++j) {
+ VALUE v = extract_item_member(ptr, &members[i], j);
+ rb_ary_push(item, v);
+ }
+ }
+
+ return item;
+}
+
+void
+rb_memory_view_prepare_item_desc(rb_memory_view_t *view)
+{
+ if (view->item_desc.components == NULL) {
+ const char *err;
+ rb_memory_view_item_component_t **p_components =
+ (rb_memory_view_item_component_t **)&view->item_desc.components;
+ ssize_t n = rb_memory_view_parse_item_format(view->format, p_components, &view->item_desc.length, &err);
+ if (n < 0) {
+ rb_raise(rb_eRuntimeError,
+ "Unable to parse item format at %"PRIdSIZE" in \"%s\"",
+ (err - view->format), view->format);
+ }
+ }
+}
+
+/* Return a value that consists of item members in the given memory view. */
+VALUE
+rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices)
+{
+ void *ptr = rb_memory_view_get_item_pointer(view, indices);
+
+ if (view->format == NULL) {
+ return INT2FIX(*(uint8_t *)ptr);
+ }
+
+ if (view->item_desc.components == NULL) {
+ rb_memory_view_prepare_item_desc(view);
+ }
+
+ return rb_memory_view_extract_item_members(ptr, view->item_desc.components, view->item_desc.length);
+}
+
+static const rb_memory_view_entry_t *
+lookup_memory_view_entry(VALUE klass)
+{
+ VALUE entry_obj = rb_ivar_lookup(klass, id_memory_view, Qnil);
+ while (NIL_P(entry_obj)) {
+ klass = rb_class_get_superclass(klass);
+
+ if (klass == rb_cBasicObject || klass == rb_cObject)
+ return NULL;
+
+ entry_obj = rb_ivar_lookup(klass, id_memory_view, Qnil);
+ }
+
+ if (! rb_typeddata_is_kind_of(entry_obj, &memory_view_entry_data_type))
+ return NULL;
+
+ return (const rb_memory_view_entry_t *)RTYPEDDATA_DATA(entry_obj);
+}
+
+/* Examine whether the given object supports memory view. */
+bool
+rb_memory_view_available_p(VALUE obj)
+{
+ VALUE klass = CLASS_OF(obj);
+ const rb_memory_view_entry_t *entry = lookup_memory_view_entry(klass);
+ if (entry)
+ return (* entry->available_p_func)(obj);
+ else
+ return false;
+}
+
+/* Obtain a memory view from obj, and substitute the information to view. */
+bool
+rb_memory_view_get(VALUE obj, rb_memory_view_t* view, int flags)
+{
+ VALUE klass = CLASS_OF(obj);
+ const rb_memory_view_entry_t *entry = lookup_memory_view_entry(klass);
+ if (entry) {
+ if (!(*entry->available_p_func)(obj)) {
+ return false;
+ }
+
+ bool rv = (*entry->get_func)(obj, view, flags);
+ if (rv) {
+ register_exported_object(view->obj);
+ }
+ return rv;
+ }
+ else
+ return false;
+}
+
+/* Release the memory view obtained from obj. */
+bool
+rb_memory_view_release(rb_memory_view_t* view)
+{
+ VALUE klass = CLASS_OF(view->obj);
+ const rb_memory_view_entry_t *entry = lookup_memory_view_entry(klass);
+ if (entry) {
+ bool rv = true;
+ if (entry->release_func) {
+ rv = (*entry->release_func)(view->obj, view);
+ }
+ if (rv) {
+ unregister_exported_object(view->obj);
+ view->obj = Qnil;
+ if (view->item_desc.components) {
+ xfree((void *)view->item_desc.components);
+ }
+ }
+ return rv;
+ }
+ else
+ return false;
+}
+
+void
+Init_MemoryView(void)
+{
+ exported_object_table = rb_init_identtable();
+
+ // exported_object_table is referred through rb_memory_view_exported_object_registry
+ // in -test-/memory_view extension.
+ VALUE obj = TypedData_Wrap_Struct(
+ 0, &rb_memory_view_exported_object_registry_data_type,
+ exported_object_table);
+ rb_gc_register_mark_object(obj);
+ rb_memory_view_exported_object_registry = obj;
+
+ id_memory_view = rb_intern_const("__memory_view__");
+}
diff --git a/method.h b/method.h
index acdf67f762..16a48ccf88 100644
--- a/method.h
+++ b/method.h
@@ -1,3 +1,5 @@
+#ifndef RUBY_METHOD_H
+#define RUBY_METHOD_H 1
/**********************************************************************
method.h -
@@ -8,10 +10,11 @@
Copyright (C) 2009 Koichi Sasada
**********************************************************************/
-#ifndef RUBY_METHOD_H
-#define RUBY_METHOD_H 1
#include "internal.h"
+#include "internal/imemo.h"
+#include "internal/compilers.h"
+#include "internal/static_assert.h"
#ifndef END_OF_ENUMERATION
# if defined(__GNUC__) &&! defined(__STRICT_ANSI__)
@@ -33,15 +36,16 @@ typedef enum {
} rb_method_visibility_t;
typedef struct rb_scope_visi_struct {
- rb_method_visibility_t method_visi : 3;
+ BITFIELD(rb_method_visibility_t, method_visi, 3);
unsigned int module_func : 1;
} rb_scope_visibility_t;
+/*! CREF (Class REFerence) */
typedef struct rb_cref_struct {
VALUE flags;
- const VALUE refinements;
- const VALUE klass;
- struct rb_cref_struct * const next;
+ VALUE refinements;
+ VALUE klass;
+ struct rb_cref_struct * next;
const rb_scope_visibility_t scope_visi;
} rb_cref_t;
@@ -49,10 +53,10 @@ typedef struct rb_cref_struct {
typedef struct rb_method_entry_struct {
VALUE flags;
- const VALUE defined_class;
+ VALUE defined_class;
struct rb_method_definition_struct * const def;
ID called_id;
- const VALUE owner;
+ VALUE owner;
} rb_method_entry_t;
typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_entry_t */
@@ -65,8 +69,13 @@ typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_e
#define METHOD_ENTRY_VISI(me) (rb_method_visibility_t)(((me)->flags & (IMEMO_FL_USER0 | IMEMO_FL_USER1)) >> (IMEMO_FL_USHIFT+0))
#define METHOD_ENTRY_BASIC(me) (int) (((me)->flags & (IMEMO_FL_USER2 )) >> (IMEMO_FL_USHIFT+2))
-#define METHOD_ENTRY_COMPLEMENTED(me) ((me)->flags & IMEMO_FL_USER3)
-#define METHOD_ENTRY_COMPLEMENTED_SET(me) ((me)->flags = (me)->flags | IMEMO_FL_USER3)
+#define METHOD_ENTRY_COMPLEMENTED(me) ((me)->flags & IMEMO_FL_USER3)
+#define METHOD_ENTRY_COMPLEMENTED_SET(me) ((me)->flags |= IMEMO_FL_USER3)
+#define METHOD_ENTRY_CACHED(me) ((me)->flags & IMEMO_FL_USER4)
+#define METHOD_ENTRY_CACHED_SET(me) ((me)->flags |= IMEMO_FL_USER4)
+#define METHOD_ENTRY_INVALIDATED(me) ((me)->flags & IMEMO_FL_USER5)
+#define METHOD_ENTRY_INVALIDATED_SET(me) ((me)->flags |= IMEMO_FL_USER5)
+#define METHOD_ENTRY_CACHEABLE(me) !(METHOD_ENTRY_VISI(me) == METHOD_VISI_PROTECTED)
static inline void
METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi)
@@ -87,32 +96,35 @@ METHOD_ENTRY_FLAGS_SET(rb_method_entry_t *me, rb_method_visibility_t visi, unsig
VM_ASSERT(basic <= 1);
me->flags =
(me->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2)) |
- ((visi << (IMEMO_FL_USHIFT+0)) | (basic << (IMEMO_FL_USHIFT+2)));
+ ((visi << (IMEMO_FL_USHIFT+0)) | (basic << (IMEMO_FL_USHIFT+2)));
}
static inline void
METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src)
{
dst->flags =
(dst->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2)) |
- (src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2));
+ (src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2));
}
typedef enum {
- VM_METHOD_TYPE_ISEQ,
- VM_METHOD_TYPE_CFUNC,
- VM_METHOD_TYPE_ATTRSET,
- VM_METHOD_TYPE_IVAR,
+ VM_METHOD_TYPE_ISEQ, /*!< Ruby method */
+ VM_METHOD_TYPE_CFUNC, /*!< C method */
+ VM_METHOD_TYPE_ATTRSET, /*!< attr_writer or attr_accessor */
+ VM_METHOD_TYPE_IVAR, /*!< attr_reader or attr_accessor */
VM_METHOD_TYPE_BMETHOD,
VM_METHOD_TYPE_ZSUPER,
VM_METHOD_TYPE_ALIAS,
VM_METHOD_TYPE_UNDEF,
VM_METHOD_TYPE_NOTIMPLEMENTED,
- VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */
- VM_METHOD_TYPE_MISSING, /* wrapper for method_missing(id) */
- VM_METHOD_TYPE_REFINED,
+ VM_METHOD_TYPE_OPTIMIZED, /*!< Kernel#send, Proc#call, etc */
+ VM_METHOD_TYPE_MISSING, /*!< wrapper for method_missing(id) */
+ VM_METHOD_TYPE_REFINED, /*!< refinement */
END_OF_ENUMERATION(VM_METHOD_TYPE)
} rb_method_type_t;
+#define VM_METHOD_TYPE_MINIMUM_BITS 4
+STATIC_ASSERT(VM_METHOD_TYPE_MINIMUM_BITS,
+ VM_METHOD_TYPE_REFINED <= (1<<VM_METHOD_TYPE_MINIMUM_BITS));
#ifndef rb_iseq_t
typedef struct rb_iseq_struct rb_iseq_t;
@@ -120,56 +132,68 @@ typedef struct rb_iseq_struct rb_iseq_t;
#endif
typedef struct rb_method_iseq_struct {
- const rb_iseq_t * const iseqptr; /* should be separated from iseqval */
- rb_cref_t * const cref; /* should be marked */
+ rb_iseq_t * iseqptr; /*!< iseq pointer, should be separated from iseqval */
+ rb_cref_t * cref; /*!< class reference, should be marked */
} rb_method_iseq_t; /* check rb_add_method_iseq() when modify the fields */
typedef struct rb_method_cfunc_struct {
VALUE (*func)(ANYARGS);
- VALUE (*invoker)(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv);
+ VALUE (*invoker)(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS));
int argc;
} rb_method_cfunc_t;
typedef struct rb_method_attr_struct {
ID id;
- const VALUE location; /* should be marked */
+ VALUE location; /* should be marked */
} rb_method_attr_t;
typedef struct rb_method_alias_struct {
- const struct rb_method_entry_struct * const original_me; /* original_me->klass is original owner */
+ struct rb_method_entry_struct * original_me; /* original_me->klass is original owner */
} rb_method_alias_t;
typedef struct rb_method_refined_struct {
- const struct rb_method_entry_struct * const orig_me;
- const VALUE owner;
+ struct rb_method_entry_struct * orig_me;
+ VALUE owner;
} rb_method_refined_t;
+typedef struct rb_method_bmethod_struct {
+ VALUE proc; /* should be marked */
+ struct rb_hook_list_struct *hooks;
+ VALUE defined_ractor;
+} rb_method_bmethod_t;
+
enum method_optimized_type {
OPTIMIZED_METHOD_TYPE_SEND,
OPTIMIZED_METHOD_TYPE_CALL,
+ OPTIMIZED_METHOD_TYPE_BLOCK_CALL,
OPTIMIZED_METHOD_TYPE__MAX
};
-PACKED_STRUCT_UNALIGNED(struct rb_method_definition_struct {
- unsigned int type : 4; /* method type */
+struct rb_method_definition_struct {
+ BITFIELD(rb_method_type_t, type, VM_METHOD_TYPE_MINIMUM_BITS);
int alias_count : 28;
int complemented_count : 28;
+ unsigned int no_redef_warning: 1;
union {
- rb_method_iseq_t iseq;
- rb_method_cfunc_t cfunc;
- rb_method_attr_t attr;
- rb_method_alias_t alias;
- rb_method_refined_t refined;
-
- const VALUE proc; /* should be marked */
- enum method_optimized_type optimize_type;
+ rb_method_iseq_t iseq;
+ rb_method_cfunc_t cfunc;
+ rb_method_attr_t attr;
+ rb_method_alias_t alias;
+ rb_method_refined_t refined;
+ rb_method_bmethod_t bmethod;
+
+ enum method_optimized_type optimize_type;
} body;
ID original_id;
-});
+ uintptr_t method_serial;
+};
+
+struct rb_id_table;
typedef struct rb_method_definition_struct rb_method_definition_t;
+STATIC_ASSERT(sizeof_method_def, offsetof(rb_method_definition_t, body)==8);
#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
#define UNDEFINED_REFINED_METHOD_P(def) \
@@ -179,8 +203,8 @@ typedef struct rb_method_definition_struct rb_method_definition_t;
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi);
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi);
void rb_add_refined_method_entry(VALUE refined_class, ID mid);
+void rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
-rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex);
rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def);
@@ -190,27 +214,33 @@ const rb_method_entry_t *rb_method_entry(VALUE klass, ID id);
const rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class);
const rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class);
const rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
+RUBY_SYMBOL_EXPORT_BEGIN
+const rb_method_entry_t *rb_resolve_me_location(const rb_method_entry_t *, VALUE[5]);
+RUBY_SYMBOL_EXPORT_END
const rb_callable_method_entry_t *rb_callable_method_entry(VALUE klass, ID id);
const rb_callable_method_entry_t *rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class);
const rb_callable_method_entry_t *rb_callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class);
-const rb_callable_method_entry_t *rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
int rb_method_entry_arity(const rb_method_entry_t *me);
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2);
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me);
VALUE rb_method_entry_location(const rb_method_entry_t *me);
-VALUE rb_mod_method_location(VALUE mod, ID id);
-VALUE rb_obj_method_location(VALUE obj, ID id);
void rb_free_method_entry(const rb_method_entry_t *me);
-void rb_sweep_method_entry(void *vm);
const rb_method_entry_t *rb_method_entry_clone(const rb_method_entry_t *me);
const rb_callable_method_entry_t *rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class);
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src);
+void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me);
+
void rb_scope_visibility_set(rb_method_visibility_t);
+VALUE rb_unnamed_parameters(int arity);
+
+void rb_clear_method_cache(VALUE klass_or_module, ID mid);
+void rb_clear_method_cache_all(void);
+
#endif /* RUBY_METHOD_H */
diff --git a/mini_builtin.c b/mini_builtin.c
new file mode 100644
index 0000000000..86803e1656
--- /dev/null
+++ b/mini_builtin.c
@@ -0,0 +1,84 @@
+#include "internal.h"
+#include "internal/array.h"
+#include "iseq.h"
+#include "vm_core.h"
+#include "builtin.h"
+
+#include "miniprelude.c"
+
+// included from miniinit.c
+
+#ifndef INCLUDED_BY_BUILTIN_C
+static struct st_table *loaded_builtin_table;
+#endif
+
+rb_ast_t *rb_builtin_ast(const char *feature_name, VALUE *name_str);
+
+static const rb_iseq_t *
+builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *table)
+{
+ VALUE name_str = 0;
+ rb_ast_t *ast = rb_builtin_ast(feature_name, &name_str);
+ rb_vm_t *vm = GET_VM();
+
+ vm->builtin_function_table = table;
+ vm->builtin_inline_index = 0;
+ const rb_iseq_t *iseq = rb_iseq_new(&ast->body, name_str, name_str, Qnil, NULL, ISEQ_TYPE_TOP);
+ GET_VM()->builtin_function_table = NULL;
+
+ rb_ast_dispose(ast);
+
+ // for debug
+ if (0 && strcmp("prelude", feature_name) == 0) {
+ rb_io_write(rb_stdout, rb_iseq_disasm((const rb_iseq_t *)iseq));
+ }
+
+#ifndef INCLUDED_BY_BUILTIN_C
+ st_insert(loaded_builtin_table, (st_data_t)feature_name, (st_data_t)iseq);
+ rb_gc_register_mark_object((VALUE)iseq);
+#endif
+
+ return iseq;
+}
+
+void
+rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
+{
+ const rb_iseq_t *iseq = builtin_iseq_load(feature_name, table);
+ rb_iseq_eval(iseq);
+}
+
+#ifndef INCLUDED_BY_BUILTIN_C
+
+static int
+each_builtin_i(st_data_t key, st_data_t val, st_data_t dmy)
+{
+ const char *feature = (const char *)key;
+ const rb_iseq_t *iseq = (const rb_iseq_t *)val;
+
+ rb_yield_values(2, rb_str_new2(feature), rb_iseqw_new(iseq));
+
+ return ST_CONTINUE;
+}
+
+static VALUE
+each_builtin(VALUE self)
+{
+ st_foreach(loaded_builtin_table, each_builtin_i, 0);
+ return Qnil;
+}
+
+void
+Init_builtin(void)
+{
+ rb_define_singleton_method(rb_cRubyVM, "each_builtin", each_builtin, 0);
+ loaded_builtin_table = st_init_strtable();
+}
+
+void
+Init_builtin_features(void)
+{
+ // register for ruby
+ builtin_iseq_load("gem_prelude", NULL);
+}
+#endif
diff --git a/miniinit.c b/miniinit.c
index 7284e2e62d..2a14a0d1c5 100644
--- a/miniinit.c
+++ b/miniinit.c
@@ -47,3 +47,5 @@ Init_enc(void)
rb_encdb_alias("BINARY", "ASCII-8BIT");
rb_encdb_alias("ASCII", "US-ASCII");
}
+
+#include "mini_builtin.c"
diff --git a/misc/README b/misc/README
index 08a9010f58..1728b42700 100644
--- a/misc/README
+++ b/misc/README
@@ -1,12 +1,6 @@
-README this file
-inf-ruby.el program to run ruby under emacs
-rb_optparse.bash bash completion script
-rb_optparse.zsh zsh completion script
-rdoc-mode.el RDoc mode for emacs
-ruby-mode.el ruby mode for emacs
-ruby-style.el Ruby's C/C++ mode style for emacs
-rubydb2x.el ruby debugger support for emacs 19.2x or before
-rubydb3x.el ruby debugger support for emacs 19.3x or later
-ruby-electric.el emacs minor mode providing electric commands
-
-Check out https://github.com/ruby-debug/ also.
+README this file
+rb_optparse.bash bash completion script
+rb_optparse.zsh zsh completion script
+ruby-style.el Ruby's C/C++ mode style for emacs
+lldb_cruby.py LLDB port of debug utility
+test_lldb_cruby.rb test file for LLDB port
diff --git a/misc/expand_tabs.rb b/misc/expand_tabs.rb
new file mode 100755
index 0000000000..b748ab4a61
--- /dev/null
+++ b/misc/expand_tabs.rb
@@ -0,0 +1,167 @@
+#!/usr/bin/env ruby --disable-gems
+# Add the following line to your `.git/hooks/pre-commit`:
+#
+# $ ruby --disable-gems misc/expand_tabs.rb
+#
+
+require 'shellwords'
+require 'tmpdir'
+ENV['LC_ALL'] = 'C'
+
+class Git
+ def initialize(oldrev, newrev)
+ @oldrev = oldrev
+ @newrev = newrev
+ end
+
+ # ["foo/bar.c", "baz.h", ...]
+ def updated_paths
+ with_clean_env do
+ IO.popen(['git', 'diff', '--cached', '--name-only', @newrev], &:readlines).each(&:chomp!)
+ end
+ end
+
+ # [0, 1, 4, ...]
+ def updated_lines(file)
+ lines = []
+ revs_pattern = ("0"*40) + " "
+ with_clean_env { IO.popen(['git', 'blame', '-l', '--', file], &:readlines) }.each_with_index do |line, index|
+ if line.b.start_with?(revs_pattern)
+ lines << index
+ end
+ end
+ lines
+ end
+
+ def add(file)
+ git('add', file)
+ end
+
+ def toplevel
+ IO.popen(['git', 'rev-parse', '--show-toplevel'], &:read).chomp
+ end
+
+ private
+
+ def git(*args)
+ cmd = ['git', *args].shelljoin
+ unless with_clean_env { system(cmd) }
+ abort "Failed to run: #{cmd}"
+ end
+ end
+
+ def with_clean_env
+ git_dir = ENV.delete('GIT_DIR') # this overcomes '-C' or pwd
+ yield
+ ensure
+ ENV['GIT_DIR'] = git_dir if git_dir
+ end
+end
+
+DEFAULT_GEM_LIBS = %w[
+ bundler
+ cmath
+ csv
+ e2mmap
+ fileutils
+ forwardable
+ ipaddr
+ irb
+ logger
+ matrix
+ mutex_m
+ ostruct
+ prime
+ racc
+ rdoc
+ rexml
+ rss
+ scanf
+ shell
+ sync
+ thwait
+ tracer
+]
+
+DEFAULT_GEM_EXTS = %w[
+ bigdecimal
+ date
+ dbm
+ etc
+ fcntl
+ fiddle
+ gdbm
+ io/console
+ json
+ openssl
+ psych
+ stringio
+ strscan
+ zlib
+]
+
+EXPANDTAB_IGNORED_FILES = [
+ # default gems whose master is GitHub
+ %r{\Abin/(?!erb)\w+\z},
+ *DEFAULT_GEM_LIBS.flat_map { |lib|
+ [
+ %r{\Alib/#{lib}/},
+ %r{\Alib/#{lib}\.gemspec\z},
+ %r{\Alib/#{lib}\.rb\z},
+ %r{\Atest/#{lib}/},
+ ]
+ },
+ *DEFAULT_GEM_EXTS.flat_map { |ext|
+ [
+ %r{\Aext/#{ext}/},
+ %r{\Atest/#{ext}/},
+ ]
+ },
+
+ # vendoring (ccan)
+ %r{\Accan/},
+
+ # vendoring (onigmo)
+ %r{\Aenc/},
+ %r{\Ainclude/ruby/onigmo\.h\z},
+ %r{\Areg.+\.(c|h)\z},
+
+ # explicit or implicit `c-file-style: "linux"`
+ %r{\Aaddr2line\.c\z},
+ %r{\Amissing/},
+ %r{\Astrftime\.c\z},
+ %r{\Avsnprintf\.c\z},
+]
+
+git = Git.new('HEAD^', 'HEAD')
+
+Dir.chdir(git.toplevel) do
+ paths = git.updated_paths
+ paths.select! {|f|
+ (f.end_with?('.c') || f.end_with?('.h') || f == 'insns.def') && EXPANDTAB_IGNORED_FILES.all? { |re| !f.match(re) }
+ }
+ files = paths.select {|n| File.file?(n)}
+ exit if files.empty?
+
+ files.each do |f|
+ src = File.binread(f) rescue next
+
+ expanded = false
+ updated_lines = git.updated_lines(f)
+ unless updated_lines.empty?
+ src.gsub!(/^.*$/).with_index do |line, lineno|
+ if updated_lines.include?(lineno) && line.start_with?("\t") # last-committed line with hard tabs
+ expanded = true
+ line.sub(/\A\t+/) { |tabs| ' ' * (8 * tabs.length) }
+ else
+ line
+ end
+ end
+ end
+
+ if expanded
+ File.binwrite(f, src)
+ git.add(f)
+ end
+ end
+end
diff --git a/misc/inf-ruby.el b/misc/inf-ruby.el
deleted file mode 100644
index b3f4f10267..0000000000
--- a/misc/inf-ruby.el
+++ /dev/null
@@ -1,418 +0,0 @@
-;;; -*-Emacs-Lisp-*-
-;;;
-;;; $Id$
-;;; $Author$
-;;;
-;;; Inferior Ruby Mode - ruby process in a buffer.
-;;; adapted from cmuscheme.el
-;;;
-;;; Usage:
-;;;
-;;; (0) check ruby-program-name variable that can run your environment.
-;;;
-;;; (1) modify .emacs to use ruby-mode
-;;; for example :
-;;;
-;;; (autoload 'ruby-mode "ruby-mode"
-;;; "Mode for editing ruby source files" t)
-;;; (setq auto-mode-alist
-;;; (append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
-;;; (setq interpreter-mode-alist (append '(("ruby" . ruby-mode))
-;;; interpreter-mode-alist))
-;;;
-;;; (2) set to load inf-ruby and set inf-ruby key definition in ruby-mode.
-;;;
-;;; (autoload 'run-ruby "inf-ruby"
-;;; "Run an inferior Ruby process")
-;;; (autoload 'inf-ruby-keys "inf-ruby"
-;;; "Set local key defs for inf-ruby in ruby-mode")
-;;; (add-hook 'ruby-mode-hook
-;;; '(lambda ()
-;;; (inf-ruby-keys)
-;;; ))
-;;;
-;;; HISTORY
-;;; senda - 8 Apr 1998: Created.
-;;; $Log$
-;;; Revision 1.7 2004/07/27 08:11:36 matz
-;;; * eval.c (rb_eval): copy on write for argument local variable
-;;; assignment.
-;;;
-;;; * eval.c (assign): ditto.
-;;;
-;;; * eval.c (rb_call0): update ruby_frame->argv with the default
-;;; value used for the optional arguments.
-;;;
-;;; * object.c (Init_Object): "===" calls rb_obj_equal() directly.
-;;; [ruby-list:39937]
-;;;
-;;; Revision 1.6 2002/09/07 14:35:46 nobu
-;;; * misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp
-;;; alist for error message from ruby.
-;;;
-;;; * misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs.
-;;;
-;;; * misc/inf-ruby.el (ruby-send-region): compilation-parse-errors
-;;; doesn't parse first line, so insert separators before each
-;;; evaluations.
-;;;
-;;; Revision 1.5 2002/08/19 10:05:47 nobu
-;;; * misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition
-;;; conflicted with ruby-insert-end.
-;;;
-;;; * misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode.
-;;;
-;;; * misc/inf-ruby.el (ruby-send-region): send as here document to
-;;; adjust source file/line. [ruby-talk:47113], [ruby-dev:17965]
-;;;
-;;; * misc/inf-ruby.el (ruby-send-terminator): added to make unique
-;;; terminator.
-;;;
-;;; Revision 1.4 2002/01/29 07:16:09 matz
-;;; * file.c (rb_stat_rdev_major): added. [new]
-;;;
-;;; * file.c (rb_stat_rdev_minor): added. [new]
-;;;
-;;; * file.c (rb_stat_inspect): print mode in octal.
-;;;
-;;; Revision 1.3 1999/12/01 09:24:18 matz
-;;; 19991201
-;;;
-;;; Revision 1.2 1999/08/13 05:45:18 matz
-;;; 1.4.0
-;;;
-;;; Revision 1.1.1.1.2.1 1999/07/15 07:59:59 matz
-;;; 990715
-;;;
-;;; Revision 1.1.1.1 1999/01/20 04:59:36 matz
-;;; ruby 1.3 cycle
-;;;
-;;; Revision 1.1.2.1 1998/12/16 07:30:36 matz
-;;; first public release of 1.1d (pre1.2) series
-;;;
-;;; Revision 1.4 1998/05/20 02:45:58 senda
-;;; default program to irb
-;;;
-;;; Revision 1.3 1998/04/10 04:11:30 senda
-;;; modification by Matsumoto san (1.1b9_09)
-;;; remove-in-string defined
-;;; global variable :
-;;; inferior-ruby-first-prompt-pattern
-;;; inferior-ruby-prompt-pattern
-;;; defined
-;;;
-;;; Revision 1.2 1998/04/09 07:53:42 senda
-;;; remove M-C-x in inferior-ruby-mode
-;;;
-;;; Revision 1.1 1998/04/09 07:28:36 senda
-;;; Initial revision
-;;;
-;;;
-
-(require 'comint)
-(require 'compile)
-(require 'ruby-mode)
-
-;;
-;; you may change these variables
-;;
-;(defvar ruby-program-name "rbc --noreadline"
-; "*Program invoked by the run-ruby command")
-;
-;(defvar inferior-ruby-first-prompt-pattern "^rbc0> *"
-; "first prompt regex pattern of ruby interpreter.")
-;
-;(defvar inferior-ruby-prompt-pattern "^\\(rbc.[>*\"'] *\\)+"
-; "prompt regex pattern of ruby interpreter.")
-
-;;;; for irb
-(defvar ruby-program-name "irb --inf-ruby-mode"
- "*Program invoked by the run-ruby command")
-
-(defvar inferior-ruby-first-prompt-pattern "^irb(.*)[0-9:]+0> *"
- "first prompt regex pattern of ruby interpreter.")
-
-(defvar inferior-ruby-prompt-pattern "^\\(irb(.*)[0-9:]+[>*\"'] *\\)+"
- "prompt regex pattern of ruby interpreter.")
-
-;;
-;; mode variables
-;;
-(defvar inferior-ruby-mode-hook nil
- "*Hook for customising inferior-ruby mode.")
-(defvar inferior-ruby-mode-map nil
- "*Mode map for inferior-ruby-mode")
-
-(defconst inferior-ruby-error-regexp-alist
- '(("SyntaxError: compile error\n^\\([^\(].*\\):\\([1-9][0-9]*\\):" 1 2)
- ("^\tfrom \\([^\(].*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?$" 1 2)))
-
-(cond ((not inferior-ruby-mode-map)
- (setq inferior-ruby-mode-map
- (copy-keymap comint-mode-map))
-; (define-key inferior-ruby-mode-map "\M-\C-x" ;gnu convention
-; 'ruby-send-definition)
-; (define-key inferior-ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
- (define-key inferior-ruby-mode-map "\C-c\C-l" 'ruby-load-file)
-))
-
-;;;###autoload
-(defun inf-ruby-keys ()
- "Set local key defs for inf-ruby in ruby-mode"
- (define-key ruby-mode-map "\M-\C-x" 'ruby-send-definition)
-; (define-key ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
- (define-key ruby-mode-map "\C-c\C-b" 'ruby-send-block)
- (define-key ruby-mode-map "\C-c\M-b" 'ruby-send-block-and-go)
- (define-key ruby-mode-map "\C-c\C-x" 'ruby-send-definition)
- (define-key ruby-mode-map "\C-c\M-x" 'ruby-send-definition-and-go)
- (define-key ruby-mode-map "\C-c\C-r" 'ruby-send-region)
- (define-key ruby-mode-map "\C-c\M-r" 'ruby-send-region-and-go)
- (define-key ruby-mode-map "\C-c\C-z" 'switch-to-ruby)
- (define-key ruby-mode-map "\C-c\C-l" 'ruby-load-file)
- (define-key ruby-mode-map "\C-c\C-s" 'run-ruby)
-)
-
-(defvar ruby-buffer nil "current ruby (actually irb) process buffer.")
-
-(defun inferior-ruby-mode ()
- "Major mode for interacting with an inferior ruby (irb) process.
-
-The following commands are available:
-\\{inferior-ruby-mode-map}
-
-A ruby process can be fired up with M-x run-ruby.
-
-Customisation: Entry to this mode runs the hooks on comint-mode-hook and
-inferior-ruby-mode-hook (in that order).
-
-You can send text to the inferior ruby process from other buffers containing
-Ruby source.
- switch-to-ruby switches the current buffer to the ruby process buffer.
- ruby-send-definition sends the current definition to the ruby process.
- ruby-send-region sends the current region to the ruby process.
-
- ruby-send-definition-and-go, ruby-send-region-and-go,
- switch to the ruby process buffer after sending their text.
-For information on running multiple processes in multiple buffers, see
-documentation for variable ruby-buffer.
-
-Commands:
-Return after the end of the process' output sends the text from the
- end of process to point.
-Return before the end of the process' output copies the sexp ending at point
- to the end of the process' output, and sends it.
-Delete converts tabs to spaces as it moves back.
-Tab indents for ruby; with argument, shifts rest
- of expression rigidly with the current line.
-C-M-q does Tab on each line starting within following expression.
-Paragraphs are separated only by blank lines. # start comments.
-If you accidentally suspend your process, use \\[comint-continue-subjob]
-to continue it."
- (interactive)
- (comint-mode)
- ;; Customise in inferior-ruby-mode-hook
- ;(setq comint-prompt-regexp "^[^>\n]*>+ *")
- (setq comint-prompt-regexp inferior-ruby-prompt-pattern)
- ;;(scheme-mode-variables)
- (ruby-mode-variables)
- (setq major-mode 'inferior-ruby-mode)
- (setq mode-name "Inferior Ruby")
- (setq mode-line-process '(":%s"))
- (use-local-map inferior-ruby-mode-map)
- (setq comint-input-filter (function ruby-input-filter))
- (setq comint-get-old-input (function ruby-get-old-input))
- (make-local-variable 'compilation-error-regexp-alist)
- (setq compilation-error-regexp-alist inferior-ruby-error-regexp-alist)
- (compilation-shell-minor-mode t)
- (run-hooks 'inferior-ruby-mode-hook))
-
-(defvar inferior-ruby-filter-regexp "\\`\\s *\\S ?\\S ?\\s *\\'"
- "*Input matching this regexp are not saved on the history list.
-Defaults to a regexp ignoring all inputs of 0, 1, or 2 letters.")
-
-(defun ruby-input-filter (str)
- "Don't save anything matching inferior-ruby-filter-regexp"
- (not (string-match inferior-ruby-filter-regexp str)))
-
-;; adapted from replace-in-string in XEmacs (subr.el)
-(defun remove-in-string (str regexp)
- "Remove all matches in STR for REGEXP and returns the new string."
- (let ((rtn-str "") (start 0) match prev-start)
- (while (setq match (string-match regexp str start))
- (setq prev-start start
- start (match-end 0)
- rtn-str (concat rtn-str (substring str prev-start match))))
- (concat rtn-str (substring str start))))
-
-(defun ruby-get-old-input ()
- "Snarf the sexp ending at point"
- (save-excursion
- (let ((end (point)))
- (re-search-backward inferior-ruby-first-prompt-pattern)
- (remove-in-string (buffer-substring (point) end)
- inferior-ruby-prompt-pattern)
- )))
-
-(defun ruby-args-to-list (string)
- (let ((where (string-match "[ \t]" string)))
- (cond ((null where) (list string))
- ((not (= where 0))
- (cons (substring string 0 where)
- (ruby-args-to-list (substring string (+ 1 where)
- (length string)))))
- (t (let ((pos (string-match "[^ \t]" string)))
- (if (null pos)
- nil
- (ruby-args-to-list (substring string pos
- (length string)))))))))
-
-;;;###autoload
-(defun run-ruby (cmd)
- "Run an inferior Ruby process, input and output via buffer *ruby*.
-If there is a process already running in `*ruby*', switch to that buffer.
-With argument, allows you to edit the command line (default is value
-of `ruby-program-name'). Runs the hooks `inferior-ruby-mode-hook'
-\(after the `comint-mode-hook' is run).
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
-
- (interactive (list (if current-prefix-arg
- (read-string "Run Ruby: " ruby-program-name)
- ruby-program-name)))
- (if (not (comint-check-proc "*ruby*"))
- (let ((cmdlist (ruby-args-to-list cmd)))
- (set-buffer (apply 'make-comint "ruby" (car cmdlist)
- nil (cdr cmdlist)))
- (inferior-ruby-mode)))
- (setq ruby-program-name cmd)
- (setq ruby-buffer "*ruby*")
- (pop-to-buffer "*ruby*"))
-
-(defconst ruby-send-terminator "--inf-ruby-%x-%d-%d-%d--"
- "Template for irb here document terminator.
-Must not contain ruby meta characters.")
-
-(defconst ruby-eval-separator "")
-
-(defun ruby-send-region (start end)
- "Send the current region to the inferior Ruby process."
- (interactive "r")
- (let (term (file (buffer-file-name)) line)
- (save-excursion
- (save-restriction
- (widen)
- (goto-char start)
- (setq line (+ start (forward-line (- start)) 1))
- (goto-char start)
- (while (progn
- (setq term (apply 'format ruby-send-terminator (random) (current-time)))
- (re-search-forward (concat "^" (regexp-quote term) "$") end t)))))
- ;; compilation-parse-errors parses from second line.
- (save-excursion
- (let ((m (process-mark (ruby-proc))))
- (set-buffer (marker-buffer m))
- (goto-char m)
- (insert ruby-eval-separator "\n")
- (set-marker m (point))))
- (comint-send-string (ruby-proc) (format "eval <<'%s', nil, %S, %d\n" term file line))
- (comint-send-region (ruby-proc) start end)
- (comint-send-string (ruby-proc) (concat "\n" term "\n"))))
-
-(defun ruby-send-definition ()
- "Send the current definition to the inferior Ruby process."
- (interactive)
- (save-excursion
- (ruby-end-of-defun)
- (let ((end (point)))
- (ruby-beginning-of-defun)
- (ruby-send-region (point) end))))
-
-;(defun ruby-send-last-sexp ()
-; "Send the previous sexp to the inferior Ruby process."
-; (interactive)
-; (ruby-send-region (save-excursion (backward-sexp) (point)) (point)))
-
-(defun ruby-send-block ()
- "Send the current block to the inferior Ruby process."
- (interactive)
- (save-excursion
- (ruby-end-of-block)
- (end-of-line)
- (let ((end (point)))
- (ruby-beginning-of-block)
- (ruby-send-region (point) end))))
-
-(defun switch-to-ruby (eob-p)
- "Switch to the ruby process buffer.
-With argument, positions cursor at end of buffer."
- (interactive "P")
- (if (get-buffer ruby-buffer)
- (pop-to-buffer ruby-buffer)
- (error "No current process buffer. See variable ruby-buffer."))
- (cond (eob-p
- (push-mark)
- (goto-char (point-max)))))
-
-(defun ruby-send-region-and-go (start end)
- "Send the current region to the inferior Ruby process.
-Then switch to the process buffer."
- (interactive "r")
- (ruby-send-region start end)
- (switch-to-ruby t))
-
-(defun ruby-send-definition-and-go ()
- "Send the current definition to the inferior Ruby.
-Then switch to the process buffer."
- (interactive)
- (ruby-send-definition)
- (switch-to-ruby t))
-
-(defun ruby-send-block-and-go ()
- "Send the current block to the inferior Ruby.
-Then switch to the process buffer."
- (interactive)
- (ruby-send-block)
- (switch-to-ruby t))
-
-(defvar ruby-source-modes '(ruby-mode)
- "*Used to determine if a buffer contains Ruby source code.
-If it's loaded into a buffer that is in one of these major modes, it's
-considered a ruby source file by ruby-load-file.
-Used by these commands to determine defaults.")
-
-(defvar ruby-prev-l/c-dir/file nil
- "Caches the last (directory . file) pair.
-Caches the last pair used in the last ruby-load-file command.
-Used for determining the default in the
-next one.")
-
-(defun ruby-load-file (file-name)
- "Load a Ruby file into the inferior Ruby process."
- (interactive (comint-get-source "Load Ruby file: " ruby-prev-l/c-dir/file
- ruby-source-modes t)) ; T because LOAD
- ; needs an exact name
- (comint-check-source file-name) ; Check to see if buffer needs saved.
- (setq ruby-prev-l/c-dir/file (cons (file-name-directory file-name)
- (file-name-nondirectory file-name)))
- (comint-send-string (ruby-proc) (concat "(load \""
- file-name
- "\"\)\n")))
-
-(defun ruby-proc ()
- "Returns the current ruby process. See variable ruby-buffer."
- (let ((proc (get-buffer-process (if (eq major-mode 'inferior-ruby-mode)
- (current-buffer)
- ruby-buffer))))
- (or proc
- (error "No current process. See variable ruby-buffer"))))
-
-;;; Do the user's customisation...
-
-(defvar inf-ruby-load-hook nil
- "This hook is run when inf-ruby is loaded in.
-This is a good place to put keybindings.")
-
-(run-hooks 'inf-ruby-load-hook)
-
-(provide 'inf-ruby)
-
-;;; inf-ruby.el ends here
diff --git a/misc/lldb_cruby.py b/misc/lldb_cruby.py
index e954d1be00..075612735c 100755
--- a/misc/lldb_cruby.py
+++ b/misc/lldb_cruby.py
@@ -6,11 +6,157 @@
# Test: misc/test_lldb_cruby.rb
#
+from __future__ import print_function
import lldb
-import commands
import os
import shlex
+HEAP_PAGE_ALIGN_LOG = 14
+HEAP_PAGE_ALIGN_MASK = (~(~0 << HEAP_PAGE_ALIGN_LOG))
+
+class BackTrace:
+ VM_FRAME_MAGIC_METHOD = 0x11110001
+ VM_FRAME_MAGIC_BLOCK = 0x22220001
+ VM_FRAME_MAGIC_CLASS = 0x33330001
+ VM_FRAME_MAGIC_TOP = 0x44440001
+ VM_FRAME_MAGIC_CFUNC = 0x55550001
+ VM_FRAME_MAGIC_IFUNC = 0x66660001
+ VM_FRAME_MAGIC_EVAL = 0x77770001
+ VM_FRAME_MAGIC_RESCUE = 0x78880001
+ VM_FRAME_MAGIC_DUMMY = 0x79990001
+
+ VM_FRAME_MAGIC_MASK = 0x7fff0001
+
+ VM_FRAME_MAGIC_NAME = {
+ VM_FRAME_MAGIC_TOP: "TOP",
+ VM_FRAME_MAGIC_METHOD: "METHOD",
+ VM_FRAME_MAGIC_CLASS: "CLASS",
+ VM_FRAME_MAGIC_BLOCK: "BLOCK",
+ VM_FRAME_MAGIC_CFUNC: "CFUNC",
+ VM_FRAME_MAGIC_IFUNC: "IFUNC",
+ VM_FRAME_MAGIC_EVAL: "EVAL",
+ VM_FRAME_MAGIC_RESCUE: "RESCUE",
+ 0: "-----"
+ }
+
+ def __init__(self, debugger, command, result, internal_dict):
+ self.debugger = debugger
+ self.command = command
+ self.result = result
+
+ self.target = debugger.GetSelectedTarget()
+ self.process = self.target.GetProcess()
+ self.thread = self.process.GetSelectedThread()
+ self.frame = self.thread.GetSelectedFrame()
+ self.tRString = self.target.FindFirstType("struct RString").GetPointerType()
+ self.tRArray = self.target.FindFirstType("struct RArray").GetPointerType()
+
+ rb_cft_len = len("rb_control_frame_t")
+ method_type_length = sorted(map(len, self.VM_FRAME_MAGIC_NAME.values()), reverse=True)[0]
+ # cfp address, method type, function name
+ self.fmt = "%%-%ds %%-%ds %%s" % (rb_cft_len, method_type_length)
+
+ def vm_frame_magic(self, cfp):
+ ep = cfp.GetValueForExpressionPath("->ep")
+ frame_type = ep.GetChildAtIndex(0).GetValueAsUnsigned() & self.VM_FRAME_MAGIC_MASK
+ return self.VM_FRAME_MAGIC_NAME.get(frame_type, "(none)")
+
+ def rb_iseq_path_str(self, iseq):
+ tRBasic = self.target.FindFirstType("struct RBasic").GetPointerType()
+
+ pathobj = iseq.GetValueForExpressionPath("->body->location.pathobj")
+ pathobj = pathobj.Cast(tRBasic)
+ flags = pathobj.GetValueForExpressionPath("->flags").GetValueAsUnsigned()
+ flType = flags & RUBY_T_MASK
+
+ if flType == RUBY_T_ARRAY:
+ pathobj = pathobj.Cast(self.tRArray)
+
+ if flags & RUBY_FL_USER1:
+ len = ((flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
+ ptr = pathobj.GetValueForExpressionPath("->as.ary")
+ else:
+ len = pathobj.GetValueForExpressionPath("->as.heap.len").GetValueAsSigned()
+ ptr = pathobj.GetValueForExpressionPath("->as.heap.ptr")
+
+ pathobj = ptr.GetChildAtIndex(0)
+
+ pathobj = pathobj.Cast(self.tRString)
+ ptr, len = string2cstr(pathobj)
+ err = lldb.SBError()
+ path = self.target.process.ReadMemory(ptr, len, err)
+ if err.Success():
+ return path.decode("utf-8")
+ else:
+ return "unknown"
+
+ def dump_iseq_frame(self, cfp, iseq):
+ m = self.vm_frame_magic(cfp)
+
+ if iseq.GetValueAsUnsigned():
+ iseq_label = iseq.GetValueForExpressionPath("->body->location.label")
+ path = self.rb_iseq_path_str(iseq)
+ ptr, len = string2cstr(iseq_label.Cast(self.tRString))
+
+ err = lldb.SBError()
+ iseq_name = self.target.process.ReadMemory(ptr, len, err)
+ if err.Success():
+ iseq_name = iseq_name.decode("utf-8")
+ else:
+ iseq_name = "error!!"
+
+ else:
+ print("No iseq", file=self.result)
+
+ print(self.fmt % (("%0#12x" % cfp.GetAddress().GetLoadAddress(self.target)), m, "%s %s" % (path, iseq_name)), file=self.result)
+
+ def dump_cfunc_frame(self, cfp):
+ print(self.fmt % ("%0#12x" % (cfp.GetAddress().GetLoadAddress(self.target)), "CFUNC", ""), file=self.result)
+
+ def print_bt(self, ec):
+ tRbExecutionContext_t = self.target.FindFirstType("rb_execution_context_t")
+ ec = ec.Cast(tRbExecutionContext_t.GetPointerType())
+ vm_stack = ec.GetValueForExpressionPath("->vm_stack")
+ vm_stack_size = ec.GetValueForExpressionPath("->vm_stack_size")
+
+ last_cfp_frame = ec.GetValueForExpressionPath("->cfp")
+ cfp_type_p = last_cfp_frame.GetType()
+
+ stack_top = vm_stack.GetValueAsUnsigned() + (
+ vm_stack_size.GetValueAsUnsigned() * vm_stack.GetType().GetByteSize())
+
+ cfp_frame_size = cfp_type_p.GetPointeeType().GetByteSize()
+
+ start_cfp = stack_top
+ # Skip dummy frames
+ start_cfp -= cfp_frame_size
+ start_cfp -= cfp_frame_size
+
+ last_cfp = last_cfp_frame.GetValueAsUnsigned()
+
+ size = ((start_cfp - last_cfp) / cfp_frame_size) + 1
+
+ print(self.fmt % ("rb_control_frame_t", "TYPE", ""), file=self.result)
+
+ curr_addr = start_cfp
+
+ while curr_addr >= last_cfp:
+ cfp = self.target.CreateValueFromAddress("cfp", lldb.SBAddress(curr_addr, self.target), cfp_type_p.GetPointeeType())
+ ep = cfp.GetValueForExpressionPath("->ep")
+ iseq = cfp.GetValueForExpressionPath("->iseq")
+
+ frame_type = ep.GetChildAtIndex(0).GetValueAsUnsigned() & self.VM_FRAME_MAGIC_MASK
+
+ if iseq.GetValueAsUnsigned():
+ pc = cfp.GetValueForExpressionPath("->pc")
+ if pc.GetValueAsUnsigned():
+ self.dump_iseq_frame(cfp, iseq)
+ else:
+ if frame_type == self.VM_FRAME_MAGIC_CFUNC:
+ self.dump_cfunc_frame(cfp)
+
+ curr_addr -= cfp_frame_size
+
def lldb_init(debugger):
target = debugger.GetSelectedTarget()
global SIZEOF_VALUE
@@ -21,7 +167,7 @@ def lldb_init(debugger):
for enum in target.FindFirstGlobalVariable('ruby_dummy_gdb_enums'):
enum = enum.GetType()
members = enum.GetEnumMembers()
- for i in xrange(0, members.GetSize()):
+ for i in range(0, members.GetSize()):
member = members.GetTypeEnumMemberAtIndex(i)
name = member.GetName()
value = member.GetValueAsUnsigned()
@@ -33,6 +179,8 @@ def lldb_init(debugger):
def string2cstr(rstring):
"""Returns the pointer to the C-string in the given String object"""
+ if rstring.TypeIsPointerType():
+ rstring = rstring.Dereference()
flags = rstring.GetValueForExpressionPath(".basic->flags").unsigned
if flags & RUBY_T_MASK != RUBY_T_STRING:
raise TypeError("not a string")
@@ -40,14 +188,14 @@ def string2cstr(rstring):
cptr = int(rstring.GetValueForExpressionPath(".as.heap.ptr").value, 0)
clen = int(rstring.GetValueForExpressionPath(".as.heap.len").value, 0)
else:
- cptr = int(rstring.GetValueForExpressionPath(".as.ary").value, 0)
+ cptr = int(rstring.GetValueForExpressionPath(".as.ary").location, 0)
clen = (flags & RSTRING_EMBED_LEN_MASK) >> RSTRING_EMBED_LEN_SHIFT
return cptr, clen
-def output_string(ctx, rstring):
+def output_string(debugger, result, rstring):
cptr, clen = string2cstr(rstring)
- expr = 'printf("%%.*s", (size_t)%d, (const char*)%d)' % (clen, cptr)
- ctx.frame.EvaluateExpression(expr)
+ expr = "print *(const char (*)[%d])%0#x" % (clen, cptr)
+ append_command_output(debugger, expr, result)
def fixnum_p(x):
return x & RUBY_FIXNUM_FLAG != 0
@@ -55,7 +203,21 @@ def fixnum_p(x):
def flonum_p(x):
return (x&RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG
+def static_sym_p(x):
+ return (x&~(~0<<RUBY_SPECIAL_SHIFT)) == RUBY_SYMBOL_FLAG
+
+def append_command_output(debugger, command, result):
+ output1 = result.GetOutput()
+ debugger.GetCommandInterpreter().HandleCommand(command, result)
+ output2 = result.GetOutput()
+ result.Clear()
+ result.write(output1)
+ result.write(output2)
+
def lldb_rp(debugger, command, result, internal_dict):
+ if not ('RUBY_Qfalse' in globals()):
+ lldb_init(debugger)
+
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
@@ -66,70 +228,200 @@ def lldb_rp(debugger, command, result, internal_dict):
val = target.EvaluateExpression(command)
error = val.GetError()
if error.Fail():
- print >> result, error
+ print(error, file=result)
return
+ lldb_inspect(debugger, target, result, val)
+
+def lldb_inspect(debugger, target, result, val):
num = val.GetValueAsSigned()
if num == RUBY_Qfalse:
- print >> result, 'false'
+ print('false', file=result)
elif num == RUBY_Qtrue:
- print >> result, 'true'
+ print('true', file=result)
elif num == RUBY_Qnil:
- print >> result, 'nil'
+ print('nil', file=result)
elif num == RUBY_Qundef:
- print >> result, 'undef'
+ print('undef', file=result)
elif fixnum_p(num):
- print >> result, num >> 1
+ print(num >> 1, file=result)
elif flonum_p(num):
- debugger.HandleCommand("print rb_float_value(%0#x)" % val.GetValueAsUnsigned())
+ append_command_output(debugger, "print rb_float_value(%0#x)" % val.GetValueAsUnsigned(), result)
+ elif static_sym_p(num):
+ if num < 128:
+ print("T_SYMBOL: %c" % num, file=result)
+ else:
+ print("T_SYMBOL: (%x)" % num, file=result)
+ append_command_output(debugger, "p rb_id2name(%0#x)" % (num >> 8), result)
elif num & RUBY_IMMEDIATE_MASK:
- print >> result, 'immediate(%x)' % num
+ print('immediate(%x)' % num, file=result)
else:
tRBasic = target.FindFirstType("struct RBasic").GetPointerType()
+ tRValue = target.FindFirstType("struct RVALUE")
+ tUintPtr = target.FindFirstType("uintptr_t") # bits_t
+
val = val.Cast(tRBasic)
flags = val.GetValueForExpressionPath("->flags").GetValueAsUnsigned()
+ flaginfo = ""
+
+ num_in_page = (val.GetValueAsUnsigned() & HEAP_PAGE_ALIGN_MASK) // tRValue.GetByteSize();
+ bits_bitlength = tUintPtr.GetByteSize() * 8
+ bitmap_index = num_in_page // bits_bitlength
+ bitmap_offset = num_in_page & (bits_bitlength - 1)
+ bitmap_bit = 1 << bitmap_offset
+
+ page = get_page(lldb, target, val)
+ page_type = target.FindFirstType("struct heap_page").GetPointerType()
+ page.Cast(page_type)
+
+ print("bits [%s%s%s%s%s]" % (
+ check_bits(page, "uncollectible_bits", bitmap_index, bitmap_bit, "L"),
+ check_bits(page, "mark_bits", bitmap_index, bitmap_bit, "M"),
+ check_bits(page, "pinned_bits", bitmap_index, bitmap_bit, "P"),
+ check_bits(page, "marking_bits", bitmap_index, bitmap_bit, "R"),
+ check_bits(page, "wb_unprotected_bits", bitmap_index, bitmap_bit, "U"),
+ ), file=result)
+
if (flags & RUBY_FL_PROMOTED) == RUBY_FL_PROMOTED:
- print >> result, "[PROMOTED] "
+ flaginfo += "[PROMOTED] "
+ if (flags & RUBY_FL_FREEZE) == RUBY_FL_FREEZE:
+ flaginfo += "[FROZEN] "
flType = flags & RUBY_T_MASK
if flType == RUBY_T_NONE:
- print >> result, 'T_NONE: %s' % val.Dereference()
+ print('T_NONE: %s%s' % (flaginfo, val.Dereference()), file=result)
elif flType == RUBY_T_NIL:
- print >> result, 'T_NIL: %s' % val.Dereference()
+ print('T_NIL: %s%s' % (flaginfo, val.Dereference()), file=result)
elif flType == RUBY_T_OBJECT:
- tRObject = target.FindFirstType("struct RObject").GetPointerType()
- val = val.Cast(tRObject)
- print >> result, 'T_OBJECT: %s' % val.Dereference()
+ result.write('T_OBJECT: %s' % flaginfo)
+ append_command_output(debugger, "print *(struct RObject*)%0#x" % val.GetValueAsUnsigned(), result)
+ elif flType == RUBY_T_CLASS or flType == RUBY_T_MODULE or flType == RUBY_T_ICLASS:
+ result.write('T_%s: %s' % ('CLASS' if flType == RUBY_T_CLASS else 'MODULE' if flType == RUBY_T_MODULE else 'ICLASS', flaginfo))
+ append_command_output(debugger, "print *(struct RClass*)%0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_STRING:
+ result.write('T_STRING: %s' % flaginfo)
tRString = target.FindFirstType("struct RString").GetPointerType()
- val = val.Cast(tRString)
- if flags & RSTRING_NOEMBED:
- print >> result, val.GetValueForExpressionPath("->as.heap")
+ ptr, len = string2cstr(val.Cast(tRString))
+ if len == 0:
+ result.write("(empty)\n")
else:
- print >> result, val.GetValueForExpressionPath("->as.ary")
+ append_command_output(debugger, "print *(const char (*)[%d])%0#x" % (len, ptr), result)
+ elif flType == RUBY_T_SYMBOL:
+ result.write('T_SYMBOL: %s' % flaginfo)
+ tRSymbol = target.FindFirstType("struct RSymbol").GetPointerType()
+ val = val.Cast(tRSymbol)
+ append_command_output(debugger, 'print (ID)%0#x ' % val.GetValueForExpressionPath("->id").GetValueAsUnsigned(), result)
+ tRString = target.FindFirstType("struct RString").GetPointerType()
+ output_string(debugger, result, val.GetValueForExpressionPath("->fstr").Cast(tRString))
elif flType == RUBY_T_ARRAY:
tRArray = target.FindFirstType("struct RArray").GetPointerType()
val = val.Cast(tRArray)
if flags & RUBY_FL_USER1:
len = ((flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
- print >> result, "T_ARRAY: len=%d (embed)" % len
- if len == 0:
- print >> result, "{(empty)}"
- else:
- print >> result, val.GetValueForExpressionPath("->as.ary")
+ ptr = val.GetValueForExpressionPath("->as.ary")
else:
len = val.GetValueForExpressionPath("->as.heap.len").GetValueAsSigned()
- print >> result, "T_ARRAY: len=%d " % len
- #print >> result, val.GetValueForExpressionPath("->as.heap")
- if flags & RUBY_FL_USER2:
- shared = val.GetValueForExpressionPath("->as.heap.aux.shared").GetValueAsUnsigned()
- print >> result, "(shared) shared=%016x " % shared
- else:
- capa = val.GetValueForExpressionPath("->as.heap.aux.capa").GetValueAsSigned()
- print >> result, "(ownership) capa=%d " % capa
- if len == 0:
- print >> result, "{(empty)}"
+ ptr = val.GetValueForExpressionPath("->as.heap.ptr")
+ #print(val.GetValueForExpressionPath("->as.heap"), file=result)
+ result.write("T_ARRAY: %slen=%d" % (flaginfo, len))
+ if flags & RUBY_FL_USER1:
+ result.write(" (embed)")
+ elif flags & RUBY_FL_USER2:
+ shared = val.GetValueForExpressionPath("->as.heap.aux.shared").GetValueAsUnsigned()
+ result.write(" (shared) shared=%016x" % shared)
+ else:
+ capa = val.GetValueForExpressionPath("->as.heap.aux.capa").GetValueAsSigned()
+ result.write(" (ownership) capa=%d" % capa)
+ if len == 0:
+ result.write(" {(empty)}\n")
+ else:
+ result.write("\n")
+ if ptr.GetValueAsSigned() == 0:
+ append_command_output(debugger, "expression -fx -- ((struct RArray*)%0#x)->as.ary" % val.GetValueAsUnsigned(), result)
else:
- debugger.HandleCommand("expression -Z %d -fx -- (const VALUE*)((struct RArray*)%d)->as.heap.ptr" % (len, val.GetValueAsUnsigned()))
- debugger.HandleCommand("p (struct RArray *) %0#x" % val.GetValueAsUnsigned())
+ append_command_output(debugger, "expression -Z %d -fx -- (const VALUE*)%0#x" % (len, ptr.GetValueAsUnsigned()), result)
+ elif flType == RUBY_T_HASH:
+ result.write("T_HASH: %s" % flaginfo)
+ append_command_output(debugger, "p *(struct RHash *) %0#x" % val.GetValueAsUnsigned(), result)
+ elif flType == RUBY_T_BIGNUM:
+ tRBignum = target.FindFirstType("struct RBignum").GetPointerType()
+ val = val.Cast(tRBignum)
+ sign = '+' if (flags & RUBY_FL_USER1) != 0 else '-'
+ if flags & RUBY_FL_USER2:
+ len = ((flags & (RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5)) >> (RUBY_FL_USHIFT+3))
+ print("T_BIGNUM: sign=%s len=%d (embed)" % (sign, len), file=result)
+ append_command_output(debugger, "print ((struct RBignum *) %0#x)->as.ary" % val.GetValueAsUnsigned(), result)
+ else:
+ len = val.GetValueForExpressionPath("->as.heap.len").GetValueAsSigned()
+ print("T_BIGNUM: sign=%s len=%d" % (sign, len), file=result)
+ print(val.Dereference(), file=result)
+ append_command_output(debugger, "expression -Z %x -fx -- (const BDIGIT*)((struct RBignum*)%d)->as.heap.digits" % (len, val.GetValueAsUnsigned()), result)
+ # append_command_output(debugger, "x ((struct RBignum *) %0#x)->as.heap.digits / %d" % (val.GetValueAsUnsigned(), len), result)
+ elif flType == RUBY_T_FLOAT:
+ tRFloat = target.FindFirstType("struct RFloat").GetPointerType()
+ val = val.Cast(tRFloat)
+ append_command_output(debugger, "p *(double *)%0#x" % val.GetValueForExpressionPath("->float_value").GetAddress(), result)
+ elif flType == RUBY_T_RATIONAL:
+ tRRational = target.FindFirstType("struct RRational").GetPointerType()
+ val = val.Cast(tRRational)
+ lldb_inspect(debugger, target, result, val.GetValueForExpressionPath("->num"))
+ output = result.GetOutput()
+ result.Clear()
+ result.write("(Rational) " + output.rstrip() + " / ")
+ lldb_inspect(debugger, target, result, val.GetValueForExpressionPath("->den"))
+ elif flType == RUBY_T_COMPLEX:
+ tRComplex = target.FindFirstType("struct RComplex").GetPointerType()
+ val = val.Cast(tRComplex)
+ lldb_inspect(debugger, target, result, val.GetValueForExpressionPath("->real"))
+ real = result.GetOutput().rstrip()
+ result.Clear()
+ lldb_inspect(debugger, target, result, val.GetValueForExpressionPath("->imag"))
+ imag = result.GetOutput().rstrip()
+ result.Clear()
+ if not imag.startswith("-"):
+ imag = "+" + imag
+ print("(Complex) " + real + imag + "i", file=result)
+ elif flType == RUBY_T_REGEXP:
+ tRRegex = target.FindFirstType("struct RRegexp").GetPointerType()
+ val = val.Cast(tRRegex)
+ print("(Regex) ->src {", file=result)
+ lldb_inspect(debugger, target, result, val.GetValueForExpressionPath("->src"))
+ print("}", file=result)
+ elif flType == RUBY_T_DATA:
+ tRTypedData = target.FindFirstType("struct RTypedData").GetPointerType()
+ val = val.Cast(tRTypedData)
+ flag = val.GetValueForExpressionPath("->typed_flag")
+ if flag.GetValueAsUnsigned() == 1:
+ print("T_DATA: %s" % val.GetValueForExpressionPath("->type->wrap_struct_name"), file=result)
+ append_command_output(debugger, "p *(struct RTypedData *) %0#x" % val.GetValueAsUnsigned(), result)
+ else:
+ print("T_DATA:", file=result)
+ append_command_output(debugger, "p *(struct RData *) %0#x" % val.GetValueAsUnsigned(), result)
+ elif flType == RUBY_T_NODE:
+ tRTypedData = target.FindFirstType("struct RNode").GetPointerType()
+ nd_type = (flags & RUBY_NODE_TYPEMASK) >> RUBY_NODE_TYPESHIFT
+ append_command_output(debugger, "p (node_type) %d" % nd_type, result)
+ val = val.Cast(tRTypedData)
+ append_command_output(debugger, "p *(struct RNode *) %0#x" % val.GetValueAsUnsigned(), result)
+ elif flType == RUBY_T_MOVED:
+ tRTypedData = target.FindFirstType("struct RMoved").GetPointerType()
+ val = val.Cast(tRTypedData)
+ append_command_output(debugger, "p *(struct RMoved *) %0#x" % val.GetValueAsUnsigned(), result)
+ elif flType == RUBY_T_MATCH:
+ tRTypedData = target.FindFirstType("struct RMatch").GetPointerType()
+ val = val.Cast(tRTypedData)
+ append_command_output(debugger, "p *(struct RMatch *) %0#x" % val.GetValueAsUnsigned(), result)
+ elif flType == RUBY_T_IMEMO:
+ # I'm not sure how to get IMEMO_MASK out of lldb. It's not in globals()
+ imemo_type = (flags >> RUBY_FL_USHIFT) & 0x0F # IMEMO_MASK
+ print("T_IMEMO: ", file=result)
+ append_command_output(debugger, "p (enum imemo_type) %d" % imemo_type, result)
+ append_command_output(debugger, "p *(struct MEMO *) %0#x" % val.GetValueAsUnsigned(), result)
+ elif flType == RUBY_T_ZOMBIE:
+ tRZombie = target.FindFirstType("struct RZombie").GetPointerType()
+ val = val.Cast(tRZombie)
+ append_command_output(debugger, "p *(struct RZombie *) %0#x" % val.GetValueAsUnsigned(), result)
+ else:
+ print("Not-handled type %0#x" % flType, file=result)
+ print(val, file=result)
def count_objects(debugger, command, ctx, result, internal_dict):
objspace = ctx.frame.EvaluateExpression("ruby_current_vm->objspace")
@@ -141,7 +433,7 @@ def count_objects(debugger, command, ctx, result, internal_dict):
counts[t] = 0
for i in range(0, num_pages):
- print "\rcounting... %d/%d" % (i, num_pages),
+ print("\rcounting... %d/%d" % (i, num_pages), end="")
page = objspace.GetValueForExpressionPath('.heap_pages.sorted[%d]' % i)
p = page.GetChildMemberWithName('start')
num_slots = page.GetChildMemberWithName('total_slots').unsigned
@@ -152,13 +444,56 @@ def count_objects(debugger, command, ctx, result, internal_dict):
counts[obj_type] += 1
total += num_slots
- print "\rTOTAL: %d, FREE: %d" % (total, counts[0x00])
+ print("\rTOTAL: %d, FREE: %d" % (total, counts[0x00]))
for sym in value_types:
- print "%s: %d" % (sym, counts[globals()[sym]])
+ print("%s: %d" % (sym, counts[globals()[sym]]))
def stack_dump_raw(debugger, command, ctx, result, internal_dict):
ctx.frame.EvaluateExpression("rb_vmdebug_stack_dump_raw_current()")
+def check_bits(page, bitmap_name, bitmap_index, bitmap_bit, v):
+ bits = page.GetChildMemberWithName(bitmap_name)
+ plane = bits.GetChildAtIndex(bitmap_index).GetValueAsUnsigned()
+ if (plane & bitmap_bit) != 0:
+ return v
+ else:
+ return ' '
+
+def heap_page(debugger, command, ctx, result, internal_dict):
+ target = debugger.GetSelectedTarget()
+ process = target.GetProcess()
+ thread = process.GetSelectedThread()
+ frame = thread.GetSelectedFrame()
+
+ val = frame.EvaluateExpression(command)
+ page = get_page(lldb, target, val)
+ page_type = target.FindFirstType("struct heap_page").GetPointerType()
+ page.Cast(page_type)
+ append_command_output(debugger, "p (struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result)
+
+def heap_page_body(debugger, command, ctx, result, internal_dict):
+ target = debugger.GetSelectedTarget()
+ process = target.GetProcess()
+ thread = process.GetSelectedThread()
+ frame = thread.GetSelectedFrame()
+
+ val = frame.EvaluateExpression(command)
+ page = get_page_body(lldb, target, val)
+ print("Page body address: ", page.GetAddress(), file=result)
+ print(page, file=result)
+
+def get_page_body(lldb, target, val):
+ tHeapPageBody = target.FindFirstType("struct heap_page_body")
+ addr = val.GetValueAsUnsigned()
+ page_addr = addr & ~(HEAP_PAGE_ALIGN_MASK)
+ address = lldb.SBAddress(page_addr, target)
+ return target.CreateValueFromAddress("page", address, tHeapPageBody)
+
+def get_page(lldb, target, val):
+ body = get_page_body(lldb, target, val)
+ return body.GetValueForExpressionPath("->header.page")
+
def dump_node(debugger, command, ctx, result, internal_dict):
args = shlex.split(command)
if not args:
@@ -166,12 +501,34 @@ def dump_node(debugger, command, ctx, result, internal_dict):
node = args[0]
dump = ctx.frame.EvaluateExpression("(struct RString*)rb_parser_dump_tree((NODE*)(%s), 0)" % node)
- output_string(ctx, dump)
+ output_string(ctx, result, dump)
+
+def rb_backtrace(debugger, command, result, internal_dict):
+ bt = BackTrace(debugger, command, result, internal_dict)
+ frame = bt.frame
+
+ if command:
+ if frame.IsValid():
+ val = frame.EvaluateExpression(command)
+ else:
+ val = target.EvaluateExpression(command)
+
+ error = val.GetError()
+ if error.Fail():
+ print >> result, error
+ return
+ else:
+ print("Need an EC for now")
+
+ bt.print_bt(val)
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("command script add -f lldb_cruby.lldb_rp rp")
debugger.HandleCommand("command script add -f lldb_cruby.count_objects rb_count_objects")
debugger.HandleCommand("command script add -f lldb_cruby.stack_dump_raw SDR")
debugger.HandleCommand("command script add -f lldb_cruby.dump_node dump_node")
+ debugger.HandleCommand("command script add -f lldb_cruby.heap_page heap_page")
+ debugger.HandleCommand("command script add -f lldb_cruby.heap_page_body heap_page_body")
+ debugger.HandleCommand("command script add -f lldb_cruby.rb_backtrace rbbt")
lldb_init(debugger)
- print "lldb scripts for ruby has been installed."
+ print("lldb scripts for ruby has been installed.")
diff --git a/misc/lldb_disasm.py b/misc/lldb_disasm.py
new file mode 100644
index 0000000000..b46d097910
--- /dev/null
+++ b/misc/lldb_disasm.py
@@ -0,0 +1,239 @@
+#!/usr/bin/env python
+#coding: utf-8
+#
+# Usage: run `command script import -r misc/lldb_disasm.py` on LLDB
+#
+#
+# (lldb) p iseq
+# (rb_iseq_t *) $147 = 0x0000000101068400
+# (lldb) rbdisasm iseq
+# 0000 putspecialobject( 3 )
+# 0002 putnil
+# 0003 defineclass( ID: 0x560b, (rb_iseq_t *)0x1010681d0, 2 )
+# 0007 pop
+# 0008 putspecialobject( 3 )
+# 0010 putnil
+# 0011 defineclass( ID: 0x56eb, (rb_iseq_t *)0x101063b58, 2 )
+# 0015 leave
+
+
+import lldb
+import os
+import shlex
+
+class IseqDissassembler:
+ TS_VARIABLE = b'.'[0]
+ TS_CALLDATA = b'C'[0]
+ TS_CDHASH = b'H'[0]
+ TS_IC = b'K'[0]
+ TS_IVC = b'A'[0]
+ TS_ID = b'I'[0]
+ TS_ISE = b'T'[0]
+ TS_ISEQ = b'S'[0]
+ TS_OFFSET = b'O'[0]
+ TS_VALUE = b'V'[0]
+ TS_LINDEX = b'L'[0]
+ TS_FUNCPTR = b'F'[0]
+ TS_NUM = b'N'[0]
+ TS_BUILTIN = b'R'[0]
+
+ ISEQ_OPT_DISPATCH = {
+ TS_BUILTIN: "(rb_builtin_function *)%0#x",
+ TS_NUM: "%d",
+ TS_FUNCPTR: "(rb_insn_func_t) %0#x",
+ TS_LINDEX: "%d",
+ TS_VALUE: "(VALUE)%0#x",
+ TS_OFFSET: "%d",
+ TS_ISEQ: "(rb_iseq_t *)%0#x",
+ TS_ISE: "(iseq_inline_storage_entry *)%0#x",
+ TS_ID: "ID: %0#x",
+ TS_IVC: "(struct iseq_inline_iv_cache_entry *)%0#x",
+ TS_IC: "(struct iseq_inline_cache_entry *)%0#x",
+ TS_CDHASH: "CDHASH (VALUE)%0#x",
+ TS_CALLDATA: "(struct rb_call_data *)%0#x",
+ TS_VARIABLE: "VARIABLE %0#x",
+ }
+
+ def __init__(self, debugger, command, result, internal_dict):
+ self.debugger = debugger
+ self.command = command
+ self.result = result
+ self.internal_dict = internal_dict
+
+ self.target = debugger.GetSelectedTarget()
+ self.process = self.target.GetProcess()
+ self.thread = self.process.GetSelectedThread()
+ self.frame = self.thread.GetSelectedFrame()
+ self.addr2insn = self.build_addr2insn(self.target)
+ self.tChar = self.target.FindFirstType("char")
+
+ def disasm(self, val):
+ tRbISeq = self.target.FindFirstType("struct rb_iseq_struct").GetPointerType()
+ val = val.Cast(tRbISeq)
+ iseq_size = val.GetValueForExpressionPath("->body->iseq_size").GetValueAsUnsigned()
+ iseqs = val.GetValueForExpressionPath("->body->iseq_encoded")
+ idx = 0
+ print("PC IDX insn_name(operands) ", file=self.result)
+ while idx < iseq_size:
+ m = self.iseq_extract_values(self.debugger, self.target, self.process, self.result, iseqs, idx)
+ if m < 1:
+ print("Error decoding", file=self.result)
+ return
+ else:
+ idx += m
+
+ def build_addr2insn(self, target):
+ tIntPtr = target.FindFirstType("intptr_t")
+ size = target.EvaluateExpression('ruby_vminsn_type::VM_INSTRUCTION_SIZE').unsigned
+ sizeOfIntPtr = tIntPtr.GetByteSize()
+ addr_of_table = target.FindSymbols("vm_exec_core.insns_address_table")[0].GetSymbol().GetStartAddress().GetLoadAddress(target)
+
+ my_dict = {}
+
+ for insn in range(size):
+ addr_in_table = addr_of_table + (insn * sizeOfIntPtr)
+ addr = lldb.SBAddress(addr_in_table, target)
+ machine_insn = target.CreateValueFromAddress("insn", addr, tIntPtr).GetValueAsUnsigned()
+ my_dict[machine_insn] = insn
+
+ return my_dict
+
+ def rb_vm_insn_addr2insn2(self, target, result, wanted_addr):
+ return self.addr2insn.get(wanted_addr)
+
+ def iseq_extract_values(self, debugger, target, process, result, iseqs, n):
+ tValueP = target.FindFirstType("VALUE")
+ sizeofValueP = tValueP.GetByteSize()
+ pc = iseqs.unsigned + (n * sizeofValueP)
+ insn = target.CreateValueFromAddress("i", lldb.SBAddress(pc, target), tValueP)
+ addr = insn.GetValueAsUnsigned()
+ orig_insn = self.rb_vm_insn_addr2insn2(target, result, addr)
+
+ name = self.insn_name(target, process, result, orig_insn)
+ length = self.insn_len(target, orig_insn)
+ op_str = self.insn_op_types(target, process, result, orig_insn)
+ op_types = bytes(op_str, 'utf-8')
+
+ if length != (len(op_types) + 1):
+ print("error decoding iseqs", file=result)
+ return -1
+
+ print("%0#14x %04d %s" % (pc, n, name), file=result, end="")
+
+ if length == 1:
+ print("", file=result)
+ return length
+
+ print("(", end="", file=result)
+ for idx, op_type in enumerate(op_types):
+ if idx == 0:
+ print(" ", end="", file=result)
+ else:
+ print(", ", end="", file=result)
+
+ opAddr = lldb.SBAddress(iseqs.unsigned + ((n + idx + 1) * sizeofValueP), target)
+ opValue = target.CreateValueFromAddress("op", opAddr, tValueP)
+ op = opValue.GetValueAsUnsigned()
+ print(self.ISEQ_OPT_DISPATCH.get(op_type) % op, end="", file=result)
+
+ print(" )", file=result)
+ return length
+
+ def insn_len(self, target, offset):
+ size_of_char = self.tChar.GetByteSize()
+
+ symbol = target.FindSymbols("insn_len.t")[0].GetSymbol()
+ section = symbol.GetStartAddress().GetSection()
+ addr_of_table = symbol.GetStartAddress().GetOffset()
+
+ error = lldb.SBError()
+ length = section.GetSectionData().GetUnsignedInt8(error, addr_of_table + (offset * size_of_char))
+
+ if error.Success():
+ return length
+ else:
+ print("error getting length: ", error)
+
+ def insn_op_types(self, target, process, result, insn):
+ tUShort = target.FindFirstType("unsigned short")
+
+ size_of_short = tUShort.GetByteSize()
+ size_of_char = self.tChar.GetByteSize()
+
+ symbol = target.FindSymbols("insn_op_types.y")[0].GetSymbol()
+ section = symbol.GetStartAddress().GetSection()
+ addr_of_table = symbol.GetStartAddress().GetOffset()
+
+ addr_in_table = addr_of_table + (insn * size_of_short)
+
+ error = lldb.SBError()
+ offset = section.GetSectionData().GetUnsignedInt16(error, addr_in_table)
+
+ if not error.Success():
+ print("error getting op type offset: ", error)
+
+ symbol = target.FindSymbols("insn_op_types.x")[0].GetSymbol()
+ section = symbol.GetStartAddress().GetSection()
+ addr_of_table = symbol.GetStartAddress().GetOffset()
+ addr_in_name_table = addr_of_table + (offset * size_of_char)
+
+ error = lldb.SBError()
+ types = section.GetSectionData().GetString(error, addr_in_name_table)
+ if error.Success():
+ return types
+ else:
+ print("error getting op types: ", error)
+
+ def insn_name_table_offset(self, target, offset):
+ tUShort = target.FindFirstType("unsigned short")
+ size_of_short = tUShort.GetByteSize()
+
+ symbol = target.FindSymbols("insn_name.y")[0].GetSymbol()
+ section = symbol.GetStartAddress().GetSection()
+ table_offset = symbol.GetStartAddress().GetOffset()
+
+ table_offset = table_offset + (offset * size_of_short)
+
+ error = lldb.SBError()
+ offset = section.GetSectionData().GetUnsignedInt16(error, table_offset)
+
+ if error.Success():
+ return offset
+ else:
+ print("error getting insn name table offset: ", error)
+
+ def insn_name(self, target, process, result, offset):
+ symbol = target.FindSymbols("insn_name.x")[0].GetSymbol()
+ section = symbol.GetStartAddress().GetSection()
+ addr_of_table = symbol.GetStartAddress().GetOffset()
+
+ name_table_offset = self.insn_name_table_offset(target, offset)
+ addr_in_name_table = addr_of_table + name_table_offset
+
+ error = lldb.SBError()
+ name = section.GetSectionData().GetString(error, addr_in_name_table)
+
+ if error.Success():
+ return name
+ else:
+ print('error getting insn name', error)
+
+def disasm(debugger, command, result, internal_dict):
+ disassembler = IseqDissassembler(debugger, command, result, internal_dict)
+ frame = disassembler.frame
+
+ if frame.IsValid():
+ val = frame.EvaluateExpression(command)
+ else:
+ val = target.EvaluateExpression(command)
+ error = val.GetError()
+ if error.Fail():
+ print >> result, error
+ return
+
+ disassembler.disasm(val);
+
+
+def __lldb_init_module(debugger, internal_dict):
+ debugger.HandleCommand("command script add -f lldb_disasm.disasm rbdisasm")
+ print("lldb Ruby disasm installed.")
diff --git a/misc/rb_optparse.zsh b/misc/rb_optparse.zsh
index d53170c5f7..7407e87c03 100755
--- a/misc/rb_optparse.zsh
+++ b/misc/rb_optparse.zsh
@@ -13,7 +13,7 @@
#
# (3) restart zsh.
#
-# (4) geneate completion files once.
+# (4) generate completion files once.
# generate-complete-function/ruby/optparse COMMAND1
# generate-complete-function/ruby/optparse COMMAND2
#
diff --git a/misc/rdoc-mode.el b/misc/rdoc-mode.el
deleted file mode 100644
index c26c2ee564..0000000000
--- a/misc/rdoc-mode.el
+++ /dev/null
@@ -1,166 +0,0 @@
-;;
-;; rdoc-mode.el
-;; Major mode for RDoc editing
-;;
-
-;; Created: Fri Sep 18 09:04:49 JST 2009
-
-;; License: Ruby's
-
-(require 'derived)
-
-;;;###autoload
-(define-derived-mode rdoc-mode text-mode "RDoc"
- "Major mode for RD editing.
-\\{rdoc-mode-map}"
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate "^\\(=+\\|\\*+\\)[ \t\v\f]*\\|^\\s *$")
- (make-local-variable 'paragraph-start)
- (setq paragraph-start paragraph-separate)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '((rdoc-font-lock-keywords) t nil))
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-keywords rdoc-font-lock-keywords)
- (make-local-variable 'outline-regexp)
- (setq outline-regexp "^\\(=+\\)[ \t\v\f]*")
- (outline-minor-mode t)
- (setq show-trailing-whitespace t)
- (rdoc-setup-keys)
- (setq indent-tabs-mode nil)
- (run-hooks 'rdoc-mode-hook)
- )
-
-(defun rdoc-fill-paragraph (&optional justify region)
- "Fills paragraph, except for cited region"
- (interactive (progn
- (barf-if-buffer-read-only)
- (list (if current-prefix-arg 'full))))
- (save-excursion
- (beginning-of-line)
- (save-restriction
- (let ((pos (point)) beg end indent hanging)
- (cond
- ((looking-at "^ +\\(\\*\\s *\\)")
- (setq indent (- (match-end 0) (match-beginning 0))
- hanging (- (match-end 1) (match-beginning 1))))
- ((looking-at "^ +")
- (setq indent (- (match-end 0) (match-beginning 0)))
- (when (and (re-search-backward "^[^ ]\\|^\\( *\\(\\* *\\)\\)" nil t)
- (match-beginning 1)
- (= indent (- (match-end 1) (match-beginning 1))))
- (setq hanging (- (match-end 2) (match-beginning 2)))
- (setq beg (match-beginning 1))))
- ((setq beg t)))
- (when beg
- (when indent
- (goto-char pos)
- (while (progn (beginning-of-line 2)
- (and (looking-at "^\\( +\\)\\S ")
- (= indent (- (match-end 1) (match-beginning 1))))))
- (setq end (point))
- (when (and beg (not region))
- (setq region (list beg end))
- (narrow-to-region beg end)
- ))
- (goto-char pos)
- (fill-paragraph justify region)
- (when (and indent
- (or (goto-char beg) t)
- (or (beginning-of-line 2) t)
- (looking-at "^\\( +\\)")
- (= (- indent hanging) (- (match-end 0) (match-beginning 0))))
- (insert-char ?\s hanging)
- (beginning-of-line)
- (narrow-to-region (point) end)
- (fill-paragraph justify (list (point) end))))))))
-
-(defun rdoc-setup-keys ()
- (interactive)
- (define-key rdoc-mode-map "\M-q" 'rdoc-fill-paragraph)
- )
-
-(defvar rdoc-heading1-face 'font-lock-keywordoc-face)
-(defvar rdoc-heading2-face 'font-lock-type-face)
-(defvar rdoc-heading3-face 'font-lock-variable-name-face)
-(defvar rdoc-heading4-face 'font-lock-comment-face)
-(defvar rdoc-bold-face 'font-lock-function-name-face)
-(defvar rdoc-emphasis-face 'font-lock-function-name-face)
-(defvar rdoc-code-face 'font-lock-keyword-face)
-(defvar rdoc-description-face 'font-lock-constant-face)
-
-(defvar rdoc-font-lock-keywords
- (list
- (list "^=([^=\r\n].*)?$"
- 0 rdoc-heading1-face)
- (list "^==([^=\r\n].*)?$"
- 0 rdoc-heading2-face)
- (list "^===([^=\r\n].*)?$"
- 0 rdoc-heading3-face)
- (list "^====+.*$"
- 0 rdoc-heading4-face)
- (list "\\(^\\|[ \t\v\f]\\)\\(\\*\\(\\sw\\|[-_:]\\)+\\*\\)\\($\\|[ \t\v\f]\\)"
- 2 rdoc-bold-face) ; *bold*
- (list "\\(^\\|[ \t\v\f]\\)\\(_\\(\\sw\\|[-_:]\\)+_\\)\\($\\|[ \t\v\f]\\)"
- 2 rdoc-emphasis-face) ; _emphasis_
- (list "\\(^\\|[ \t\v\f]\\)\\(\\+\\(\\sw\\|[-_:]\\)+\\+\\)\\($\\|[ \t\v\f]\\)"
- 2 rdoc-code-face) ; +code+
- (list "<em>[^<>]*</em>" 0 rdoc-emphasis-face)
- (list "<i>[^<>]*</i>" 0 rdoc-emphasis-face)
- (list "<b>[^<>]*</b>" 0 rdoc-bold-face)
- (list "<tt>[^<>]*</tt>" 0 rdoc-code-face)
- (list "<code>[^<>]*</code>" 0 rdoc-code-face)
- (list "^\\([-*]\\|[0-9]+\\.\\|[A-Za-z]\\.\\)\\s "
- 1 rdoc-description-face) ; bullet | numbered | alphabetically numbered
- (list "^\\[[^\]]*\\]\\|\\S .*::\\)\\([ \t\v\f]\\|$\\)"
- 1 rdoc-description-face) ; labeled | node
- ;(list "^[ \t\v\f]+\\(.*\\)" 1 rdoc-verbatim-face)
- ))
-
-(defun rdoc-imenu-create-index ()
- (let ((root '(nil . nil))
- cur-alist
- (cur-level 0)
- (pattern (concat outline-regexp "\\(.*?\\)[ \t\v\f]*$"))
- (empty-heading "-")
- (self-heading ".")
- pos level heading alist)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward pattern (point-max) t)
- (setq heading (match-string-no-properties 2)
- level (min 6 (length (match-string-no-properties 1)))
- pos (match-beginning 1))
- (if (= (length heading) 0)
- (setq heading empty-heading))
- (setq alist (list (cons heading pos)))
- (cond
- ((= cur-level level) ; new sibling
- (setcdr cur-alist alist)
- (setq cur-alist alist))
- ((< cur-level level) ; first child
- (dotimes (i (- level cur-level 1))
- (setq alist (list (cons empty-heading alist))))
- (if cur-alist
- (let* ((parent (car cur-alist))
- (self-pos (cdr parent)))
- (setcdr parent (cons (cons self-heading self-pos) alist)))
- (setcdr root alist)) ; primogenitor
- (setq cur-alist alist
- cur-level level))
- (t ; new sibling of an ancestor
- (let ((sibling-alist (last (cdr root))))
- (dotimes (i (1- level))
- (setq sibling-alist (last (cdar sibling-alist))))
- (setcdr sibling-alist alist)
- (setq cur-alist alist
- cur-level level))))))
- (cdr root)))
-
-(defun rdoc-set-imenu-create-index-function ()
- (setq imenu-create-index-function 'rdoc-imenu-create-index))
-
-(add-hook 'rdoc-mode-hook 'rdoc-set-imenu-create-index-function)
-
-(provide 'rdoc-mode)
diff --git a/misc/ruby-additional.el b/misc/ruby-additional.el
deleted file mode 100644
index 432adfedb6..0000000000
--- a/misc/ruby-additional.el
+++ /dev/null
@@ -1,181 +0,0 @@
-;;; ruby-additional.el --- ruby-mode extensions yet to be merged into Emacs
-
-;; Authors: Yukihiro Matsumoto, Nobuyoshi Nakada, Akinori MUSHA
-;; URL: https://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/misc/
-;; Created: 3 Sep 2012
-;; Package-Requires: ((emacs "24.3") (ruby-mode "1.2"))
-;; Keywords: ruby, languages
-
-;;; Commentary:
-;;
-;; This package contains ruby-mode extensions yet to be merged into
-;; the latest released version of Emacs distribution. For older
-;; versions of Emacs, use ruby-mode.el bundled with CRuby.
-
-;;; Code:
-
-(eval-when-compile
- (require 'ruby-mode))
-
-(eval-after-load 'ruby-mode
- '(progn
- (define-key ruby-mode-map "\C-c\C-e" 'ruby-insert-end)
-
- (defun ruby-insert-end ()
- (interactive)
- (if (eq (char-syntax (preceding-char)) ?w)
- (insert " "))
- (insert "end")
- (save-excursion
- (if (eq (char-syntax (following-char)) ?w)
- (insert " "))
- (ruby-indent-line t)
- (end-of-line)))
-
- (defconst ruby-default-encoding-map
- '((us-ascii . nil) ;; Do not put coding: us-ascii
- (utf-8 . nil) ;; Do not put coding: utf-8
- (shift-jis . cp932) ;; Emacs charset name of Shift_JIS
- (shift_jis . cp932) ;; MIME charset name of Shift_JIS
- (japanese-cp932 . cp932)) ;; Emacs charset name of CP932
- )
-
- (custom-set-default 'ruby-encoding-map ruby-default-encoding-map)
-
- (defcustom ruby-encoding-map ruby-default-encoding-map
- "Alist to map encoding name from Emacs to Ruby.
-Associating an encoding name with nil means it needs not be
-explicitly declared in magic comment."
- :type '(repeat (cons (symbol :tag "From") (symbol :tag "To")))
- :group 'ruby)
-
- (defun ruby-mode-set-encoding ()
- "Insert or update a magic comment header with the proper encoding.
-`ruby-encoding-map' is looked up to convert an encoding name from
-Emacs to Ruby."
- (let* ((nonascii
- (save-excursion
- (widen)
- (goto-char (point-min))
- (re-search-forward "[^\0-\177]" nil t)))
- (coding-system
- (or coding-system-for-write
- buffer-file-coding-system))
- (coding-system
- (and coding-system
- (coding-system-change-eol-conversion coding-system nil)))
- (coding-system
- (and coding-system
- (or
- (coding-system-get coding-system :mime-charset)
- (let ((coding-type (coding-system-get coding-system :coding-type)))
- (cond ((eq coding-type 'undecided)
- (if nonascii
- (or (and (coding-system-get coding-system :prefer-utf-8)
- 'utf-8)
- (coding-system-get default-buffer-file-coding-system :coding-type)
- 'ascii-8bit)))
- ((memq coding-type '(utf-8 shift-jis))
- coding-type)
- (t coding-system))))))
- (coding-system
- (or coding-system
- 'us-ascii))
- (coding-system
- (let ((cons (assq coding-system ruby-encoding-map)))
- (if cons (cdr cons) coding-system)))
- (coding-system
- (and coding-system
- (symbol-name coding-system))))
- (if coding-system
- (save-excursion
- (widen)
- (goto-char (point-min))
- (if (looking-at "^#!") (beginning-of-line 2))
- (cond ((looking-at "\\s *#.*-\*-\\s *\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)\\s *\\(;\\|-\*-\\)")
- (unless (string= (match-string 2) coding-system)
- (goto-char (match-beginning 2))
- (delete-region (point) (match-end 2))
- (and (looking-at "-\*-")
- (let ((n (skip-chars-backward " ")))
- (cond ((= n 0) (insert " ") (backward-char))
- ((= n -1) (insert " "))
- ((forward-char)))))
- (insert coding-system)))
- ((looking-at "\\s *#.*coding\\s *[:=]"))
- (t (when ruby-insert-encoding-magic-comment
- (insert "# -*- coding: " coding-system " -*-\n"))))))))
-
- (define-key ruby-mode-map "\C-cU" 'ruby-encode-decode-unicode)
-
- (defun ruby-encode-unicode (beg end)
- "Convert non-ascii string in the given region to \\u{} form."
- (interactive "r")
- (setq end (set-marker (make-marker) end))
- (goto-char beg)
- (while (and (< (point) end)
- (re-search-forward "\\([\C-@-\C-I\C-K\C-_\C-?]+\\)\\|[^\C-@-\C-?]+" end t))
- (let ((str (match-string-no-properties 0)) sep b e f)
- (if (match-beginning 1)
- (setq b "" e "" sep ""
- f (lambda (c)
- (cond ((= c ?\t) "\\t")
- ((= c ?\r) "\\r")
- ((= c ?\e) "\\e")
- ((= c ?\f) "\\f")
- ((= c ?\b) "\\b")
- ((= c ?\v) "\\v")
- ((= c ?\C-?) "\\c?")
- ((concat "\\c" (char-to-string (logior c #x40)))))))
- (setq b "\\u{" e "}" sep " " f (lambda (c) (format "%x" c))))
- (setq str (mapconcat f str sep))
- (delete-region (match-beginning 0) (match-end 0))
- (insert b str e))))
-
- (defun ruby-decode-unicode (beg end)
- "Convert escaped Unicode in the given region to raw string."
- (interactive "r")
- (setq end (set-marker (make-marker) end))
- (goto-char beg)
- (while (and (< (point) end)
- (re-search-forward "\\\\u\\([0-9a-fA-F]\\{4\\}\\)\\|\\\\u{\\([0-9a-fA-F \t]+\\)}" end t))
- (let ((b (match-beginning 0)) (e (match-end 0))
- (s (match-string-no-properties 1)))
- (if s
- (setq s (cons s nil))
- (goto-char (match-beginning 2))
- (while (looking-at "[ \t]*\\([0-9a-fA-F]+\\)")
- (setq s (cons (match-string-no-properties 1) s))
- (goto-char (match-end 0))))
- (setq s (mapconcat (lambda (c) (format "%c" (string-to-int c 16)))
- (nreverse s) ""))
- (delete-region b e)
- (insert s))
- ))
-
- (defun ruby-encode-decode-unicode (dec beg end)
- "Convert Unicode <-> \\u{} in the given region."
- (interactive "P\nr")
- (if dec (ruby-decode-unicode beg end) (ruby-encode-unicode beg end)))
-
- (defun ruby-insert-heredoc-code-block (arg)
- "Insert indented here document code block"
- (interactive "P")
- (let ((c (if arg "~" "-")))
- (insert "\"#{<<" c "\"{#\"}\\n#{<<" c "'};'}\""))
- (end-of-line)
- (if (eobp) (insert "\n") (forward-char))
- (indent-region (point)
- (progn (insert "{#\n" "};\n") (point)))
- (beginning-of-line 0))
- (define-key ruby-mode-map "\C-cH" 'ruby-insert-heredoc-code-block)
- ))
-
-;; monkey-patching ruby-mode.el in Emacs 24, as r49872.
-(when (and (boundp 'ruby-syntax-before-regexp-re)
- (not (string-match ruby-syntax-before-regexp-re "foo {|" 1)))
- (replace-regexp-in-string "\\[\\[" "\\&{|" ruby-syntax-before-regexp-re))
-
-(provide 'ruby-additional)
-
-;;; ruby-additional.el ends here
diff --git a/misc/ruby-electric.el b/misc/ruby-electric.el
deleted file mode 100644
index 61e84d2adb..0000000000
--- a/misc/ruby-electric.el
+++ /dev/null
@@ -1,583 +0,0 @@
-;;; ruby-electric.el --- Minor mode for electrically editing ruby code
-;;
-;; Authors: Dee Zsombor <dee dot zsombor at gmail dot com>
-;; Yukihiro Matsumoto
-;; Nobuyoshi Nakada
-;; Akinori MUSHA <knu@iDaemons.org>
-;; Jakub Kuźma <qoobaa@gmail.com>
-;; Maintainer: Akinori MUSHA <knu@iDaemons.org>
-;; Created: 6 Mar 2005
-;; URL: https://github.com/knu/ruby-electric.el
-;; Keywords: languages ruby
-;; License: The same license terms as Ruby
-;; Version: 2.3.1
-
-;;; Commentary:
-;;
-;; `ruby-electric-mode' accelerates code writing in ruby by making
-;; some keys "electric" and automatically supplying with closing
-;; parentheses and "end" as appropriate.
-;;
-;; This work was originally inspired by a code snippet posted by
-;; [Frederick Ros](https://github.com/sleeper).
-;;
-;; Add the following line to enable ruby-electric-mode under
-;; ruby-mode.
-;;
-;; (eval-after-load "ruby-mode"
-;; '(add-hook 'ruby-mode-hook 'ruby-electric-mode))
-;;
-;; Type M-x customize-group ruby-electric for configuration.
-
-;;; Code:
-
-(require 'ruby-mode)
-
-(eval-when-compile
- (require 'cl))
-
-(defgroup ruby-electric nil
- "Minor mode providing electric editing commands for ruby files"
- :group 'ruby)
-
-(defconst ruby-electric-expandable-bar-re
- "\\s-\\(do\\|{\\)\\s-*|")
-
-(defconst ruby-electric-delimiters-alist
- '((?\{ :name "Curly brace" :handler ruby-electric-curlies :closing ?\})
- (?\[ :name "Square brace" :handler ruby-electric-matching-char :closing ?\])
- (?\( :name "Round brace" :handler ruby-electric-matching-char :closing ?\))
- (?\' :name "Quote" :handler ruby-electric-matching-char)
- (?\" :name "Double quote" :handler ruby-electric-matching-char)
- (?\` :name "Back quote" :handler ruby-electric-matching-char)
- (?\| :name "Vertical bar" :handler ruby-electric-bar)
- (?\# :name "Hash" :handler ruby-electric-hash)))
-
-(defvar ruby-electric-matching-delimeter-alist
- (apply 'nconc
- (mapcar #'(lambda (x)
- (let ((delim (car x))
- (plist (cdr x)))
- (if (eq (plist-get plist :handler) 'ruby-electric-matching-char)
- (list (cons delim (or (plist-get plist :closing)
- delim))))))
- ruby-electric-delimiters-alist)))
-
-(defvar ruby-electric-expandable-keyword-re)
-
-(defmacro ruby-electric--try-insert-and-do (string &rest body)
- (declare (indent 1))
- `(let ((before (point))
- (after (progn
- (insert ,string)
- (point))))
- (unwind-protect
- (progn ,@body)
- (delete-region before after)
- (goto-char before))))
-
-(defconst ruby-modifier-beg-symbol-re
- (regexp-opt ruby-modifier-beg-keywords 'symbols))
-
-(defun ruby-electric--modifier-keyword-at-point-p ()
- "Test if there is a modifier keyword at point."
- (and (looking-at ruby-modifier-beg-symbol-re)
- (let ((end (match-end 1)))
- (not (looking-back "\\."))
- (save-excursion
- (let ((indent1 (ruby-electric--try-insert-and-do "\n"
- (ruby-calculate-indent)))
- (indent2 (save-excursion
- (goto-char end)
- (ruby-electric--try-insert-and-do " x\n"
- (ruby-calculate-indent)))))
- (= indent1 indent2))))))
-
-(defconst ruby-block-mid-symbol-re
- (regexp-opt ruby-block-mid-keywords 'symbols))
-
-(defun ruby-electric--block-mid-keyword-at-point-p ()
- "Test if there is a block mid keyword at point."
- (and (looking-at ruby-block-mid-symbol-re)
- (looking-back "^\\s-*")))
-
-(defconst ruby-block-beg-symbol-re
- (regexp-opt ruby-block-beg-keywords 'symbols))
-
-(defun ruby-electric--block-beg-keyword-at-point-p ()
- "Test if there is a block beginning keyword at point."
- (and (looking-at ruby-block-beg-symbol-re)
- (if (string= (match-string 1) "do")
- (looking-back "\\s-")
- (not (looking-back "\\.")))
- ;; (not (ruby-electric--modifier-keyword-at-point-p)) ;; implicit assumption
- ))
-
-(defcustom ruby-electric-keywords-alist
- '(("begin" . end)
- ("case" . end)
- ("class" . end)
- ("def" . end)
- ("do" . end)
- ("else" . reindent)
- ("elsif" . reindent)
- ("end" . reindent)
- ("ensure" . reindent)
- ("for" . end)
- ("if" . end)
- ("module" . end)
- ("rescue" . reindent)
- ("unless" . end)
- ("until" . end)
- ("when" . reindent)
- ("while" . end))
- "Alist of keywords and actions to define how to react to space
-or return right after each keyword. In each (KEYWORD . ACTION)
-cons, ACTION can be set to one of the following values:
-
- `reindent' Reindent the line.
-
- `end' Reindent the line and auto-close the keyword with
- end if applicable.
-
- `nil' Do nothing.
-"
- :type '(repeat (cons (string :tag "Keyword")
- (choice :tag "Action"
- :menu-tag "Action"
- (const :tag "Auto-close with end"
- :value end)
- (const :tag "Auto-reindent"
- :value reindent)
- (const :tag "None"
- :value nil))))
- :set (lambda (sym val)
- (set sym val)
- (let (keywords)
- (dolist (x val)
- (let ((keyword (car x))
- (action (cdr x)))
- (if action
- (setq keywords (cons keyword keywords)))))
- (setq ruby-electric-expandable-keyword-re
- (concat (regexp-opt keywords 'symbols)
- "$"))))
- :group 'ruby-electric)
-
-(defvar ruby-electric-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map " " 'ruby-electric-space/return)
- (define-key map [remap delete-backward-char] 'ruby-electric-delete-backward-char)
- (define-key map [remap newline] 'ruby-electric-space/return)
- (define-key map [remap newline-and-indent] 'ruby-electric-space/return)
- (define-key map [remap electric-newline-and-maybe-indent] 'ruby-electric-space/return)
- (define-key map [remap reindent-then-newline-and-indent] 'ruby-electric-space/return)
- (dolist (x ruby-electric-delimiters-alist)
- (let* ((delim (car x))
- (plist (cdr x))
- (name (plist-get plist :name))
- (func (plist-get plist :handler))
- (closing (plist-get plist :closing)))
- (define-key map (char-to-string delim) func)
- (if closing
- (define-key map (char-to-string closing) 'ruby-electric-closing-char))))
- map)
- "Keymap used in ruby-electric-mode")
-
-(defcustom ruby-electric-expand-delimiters-list '(all)
- "*List of contexts where matching delimiter should be inserted.
-The word 'all' will do all insertions."
- :type `(set :extra-offset 8
- (const :tag "Everything" all)
- ,@(apply 'list
- (mapcar #'(lambda (x)
- `(const :tag ,(plist-get (cdr x) :name)
- ,(car x)))
- ruby-electric-delimiters-alist)))
- :group 'ruby-electric)
-
-(defcustom ruby-electric-newline-before-closing-bracket nil
- "*Non-nil means a newline should be inserted before an
-automatically inserted closing bracket."
- :type 'boolean :group 'ruby-electric)
-
-(defcustom ruby-electric-autoindent-on-closing-char nil
- "*Non-nil means the current line should be automatically
-indented when a closing character is manually typed in."
- :type 'boolean :group 'ruby-electric)
-
-(defvar ruby-electric-mode-hook nil
- "Called after `ruby-electric-mode' is turned on.")
-
-;;;###autoload
-(define-minor-mode ruby-electric-mode
- "Toggle Ruby Electric minor mode.
-With no argument, this command toggles the mode. Non-null prefix
-argument turns on the mode. Null prefix argument turns off the
-mode.
-
-When Ruby Electric mode is enabled, an indented 'end' is
-heuristicaly inserted whenever typing a word like 'module',
-'class', 'def', 'if', 'unless', 'case', 'until', 'for', 'begin',
-'do' followed by a space. Single, double and back quotes as well
-as braces are paired auto-magically. Expansion does not occur
-inside comments and strings. Note that you must have Font Lock
-enabled."
- ;; initial value.
- nil
- ;;indicator for the mode line.
- " REl"
- ;;keymap
- ruby-electric-mode-map
- (if ruby-electric-mode
- (run-hooks 'ruby-electric-mode-hook)))
-
-(defun ruby-electric-space/return-fallback ()
- (if (or (eq this-original-command 'ruby-electric-space/return)
- (null (ignore-errors
- ;; ac-complete may fail if there is nothing left to complete
- (call-interactively this-original-command)
- (setq this-command this-original-command))))
- ;; fall back to a globally bound command
- (let ((command (global-key-binding (char-to-string last-command-event) t)))
- (and command
- (call-interactively (setq this-command command))))))
-
-(defun ruby-electric-space/return (arg)
- (interactive "*P")
- (and (boundp 'sp-last-operation)
- (setq sp-delayed-pair nil))
- (cond ((or arg
- (region-active-p))
- (or (= last-command-event ?\s)
- (setq last-command-event ?\n))
- (ruby-electric-replace-region-or-insert))
- ((ruby-electric-space/return-can-be-expanded-p)
- (let (action)
- (save-excursion
- (goto-char (match-beginning 0))
- (let* ((keyword (match-string 1))
- (allowed-actions
- (cond ((ruby-electric--modifier-keyword-at-point-p)
- '(reindent)) ;; no end necessary
- ((ruby-electric--block-mid-keyword-at-point-p)
- '(reindent)) ;; ditto
- ((ruby-electric--block-beg-keyword-at-point-p)
- '(end reindent)))))
- (if allowed-actions
- (setq action
- (let ((action (cdr (assoc keyword ruby-electric-keywords-alist))))
- (and (memq action allowed-actions)
- action))))))
- (cond ((eq action 'end)
- (ruby-indent-line)
- (save-excursion
- (newline)
- (ruby-electric-end)))
- ((eq action 'reindent)
- (ruby-indent-line)))
- (ruby-electric-space/return-fallback)))
- ((and (eq this-original-command 'newline-and-indent)
- (ruby-electric-comment-at-point-p))
- (call-interactively (setq this-command 'comment-indent-new-line)))
- (t
- (ruby-electric-space/return-fallback))))
-
-(defun ruby-electric--get-faces-at-point ()
- (let* ((point (point))
- (value (or
- (get-text-property point 'read-face-name)
- (get-text-property point 'face))))
- (if (listp value) value (list value))))
-
-(defun ruby-electric--faces-include-p (pfaces &rest faces)
- (and ruby-electric-mode
- (loop for face in faces
- thereis (memq face pfaces))))
-
-(defun ruby-electric--faces-at-point-include-p (&rest faces)
- (apply 'ruby-electric--faces-include-p
- (ruby-electric--get-faces-at-point)
- faces))
-
-(defun ruby-electric-code-face-p (faces)
- (not (ruby-electric--faces-include-p
- faces
- 'font-lock-string-face
- 'font-lock-comment-face
- 'enh-ruby-string-delimiter-face
- 'enh-ruby-heredoc-delimiter-face
- 'enh-ruby-regexp-delimiter-face
- 'enh-ruby-regexp-face)))
-
-(defun ruby-electric-code-at-point-p ()
- (ruby-electric-code-face-p
- (ruby-electric--get-faces-at-point)))
-
-(defun ruby-electric-string-face-p (faces)
- (ruby-electric--faces-include-p
- faces
- 'font-lock-string-face
- 'enh-ruby-string-delimiter-face
- 'enh-ruby-heredoc-delimiter-face
- 'enh-ruby-regexp-delimiter-face
- 'enh-ruby-regexp-face))
-
-(defun ruby-electric-string-at-point-p ()
- (ruby-electric-string-face-p
- (ruby-electric--get-faces-at-point)))
-
-(defun ruby-electric-comment-at-point-p ()
- (ruby-electric--faces-at-point-include-p
- 'font-lock-comment-face))
-
-(defun ruby-electric-escaped-p()
- (let ((f nil))
- (save-excursion
- (while (char-equal ?\\ (preceding-char))
- (backward-char 1)
- (setq f (not f))))
- f))
-
-(defun ruby-electric-command-char-expandable-punct-p(char)
- (or (memq 'all ruby-electric-expand-delimiters-list)
- (memq char ruby-electric-expand-delimiters-list)))
-
-(defun ruby-electric-space/return-can-be-expanded-p()
- (and (ruby-electric-code-at-point-p)
- (looking-back ruby-electric-expandable-keyword-re)))
-
-(defun ruby-electric-replace-region-or-insert ()
- (and (region-active-p)
- (bound-and-true-p delete-selection-mode)
- (fboundp 'delete-selection-helper)
- (delete-selection-helper (get 'self-insert-command 'delete-selection)))
- (insert (make-string (prefix-numeric-value current-prefix-arg)
- last-command-event))
- (setq this-command 'self-insert-command))
-
-(defmacro ruby-electric-insert (arg &rest body)
- `(cond ((and
- (null ,arg)
- (ruby-electric-command-char-expandable-punct-p last-command-event))
- (let ((region-beginning
- (cond ((region-active-p)
- (prog1
- (save-excursion
- (goto-char (region-beginning))
- (insert last-command-event)
- (point))
- (goto-char (region-end))))
- (t
- (insert last-command-event)
- nil)))
- (faces-at-point
- (ruby-electric--get-faces-at-point)))
- ,@body
- (and region-beginning
- ;; If no extra character is inserted, go back to the
- ;; region beginning.
- (eq this-command 'self-insert-command)
- (goto-char region-beginning))))
- ((ruby-electric-replace-region-or-insert))))
-
-(defun ruby-electric-curlies (arg)
- (interactive "*P")
- (ruby-electric-insert
- arg
- (cond
- ((or (ruby-electric-code-at-point-p)
- (ruby-electric--faces-include-p
- faces-at-point
- 'enh-ruby-string-delimiter-face
- 'enh-ruby-regexp-delimiter-face))
- (save-excursion
- (insert "}")
- (font-lock-fontify-region (line-beginning-position) (point)))
- (cond
- ((or (ruby-electric-string-at-point-p) ;; %w{}, %r{}, etc.
- (looking-back "%[QqWwRrxIis]{"))
- (if region-beginning
- (forward-char 1)))
- (ruby-electric-newline-before-closing-bracket
- (cond (region-beginning
- (save-excursion
- (goto-char region-beginning)
- (newline))
- (newline)
- (forward-char 1)
- (indent-region region-beginning (line-end-position)))
- (t
- (insert " ")
- (save-excursion
- (newline)
- (ruby-indent-line t)))))
- (t
- (if region-beginning
- (save-excursion
- (goto-char region-beginning)
- (insert " "))
- (insert " "))
- (insert " ")
- (backward-char 1)
- (and region-beginning
- (forward-char 1)))))
- ((ruby-electric-string-at-point-p)
- (let ((start-position (1- (or region-beginning (point)))))
- (cond
- ((char-equal ?\# (char-before start-position))
- (unless (save-excursion
- (goto-char (1- start-position))
- (ruby-electric-escaped-p))
- (insert "}")
- (or region-beginning
- (backward-char 1))))
- ((or
- (ruby-electric-command-char-expandable-punct-p ?\#)
- (save-excursion
- (goto-char start-position)
- (ruby-electric-escaped-p)))
- (if region-beginning
- (goto-char region-beginning))
- (setq this-command 'self-insert-command))
- (t
- (save-excursion
- (goto-char start-position)
- (insert "#"))
- (insert "}")
- (or region-beginning
- (backward-char 1))))))
- (t
- (delete-char -1)
- (ruby-electric-replace-region-or-insert)))))
-
-(defun ruby-electric-hash (arg)
- (interactive "*P")
- (ruby-electric-insert
- arg
- (if (ruby-electric-string-at-point-p)
- (let ((start-position (1- (or region-beginning (point)))))
- (cond
- ((char-equal (following-char) ?')) ;; likely to be in ''
- ((save-excursion
- (goto-char start-position)
- (ruby-electric-escaped-p)))
- (region-beginning
- (save-excursion
- (goto-char (1+ start-position))
- (insert "{"))
- (insert "}"))
- (t
- (insert "{")
- (save-excursion
- (insert "}")))))
- (delete-char -1)
- (ruby-electric-replace-region-or-insert))))
-
-(defun ruby-electric-matching-char (arg)
- (interactive "*P")
- (ruby-electric-insert
- arg
- (let ((closing (cdr (assoc last-command-event
- ruby-electric-matching-delimeter-alist))))
- (cond
- ;; quotes
- ((char-equal closing last-command-event)
- (cond ((not (ruby-electric-string-face-p faces-at-point))
- (if region-beginning
- ;; escape quotes of the same kind, backslash and hash
- (let ((re (format "[%c\\%s]"
- last-command-event
- (if (char-equal last-command-event ?\")
- "#" "")))
- (bound (point)))
- (save-excursion
- (goto-char region-beginning)
- (while (re-search-forward re bound t)
- (let ((end (point)))
- (replace-match "\\\\\\&")
- (setq bound (+ bound (- (point) end))))))))
- (insert closing)
- (or region-beginning
- (backward-char 1)))
- (t
- (and (eq last-command 'ruby-electric-matching-char)
- (char-equal (following-char) closing) ;; repeated quotes
- (delete-char 1))
- (setq this-command 'self-insert-command))))
- ((ruby-electric-code-at-point-p)
- (insert closing)
- (or region-beginning
- (backward-char 1)))))))
-
-(defun ruby-electric-closing-char(arg)
- (interactive "*P")
- (cond
- (arg
- (ruby-electric-replace-region-or-insert))
- ((and
- (eq last-command 'ruby-electric-curlies)
- (= last-command-event ?})
- (not (char-equal (preceding-char) last-command-event))) ;; {}
- (if (char-equal (following-char) ?\n) (delete-char 1))
- (delete-horizontal-space)
- (forward-char))
- ((and
- (= last-command-event (following-char))
- (not (char-equal (preceding-char) last-command-event))
- (memq last-command '(ruby-electric-matching-char
- ruby-electric-closing-char))) ;; ()/[] and (())/[[]]
- (forward-char))
- (t
- (ruby-electric-replace-region-or-insert)
- (if ruby-electric-autoindent-on-closing-char
- (ruby-indent-line)))))
-
-(defun ruby-electric-bar(arg)
- (interactive "*P")
- (ruby-electric-insert
- arg
- (cond ((and (ruby-electric-code-at-point-p)
- (looking-back ruby-electric-expandable-bar-re))
- (save-excursion (insert "|")))
- (t
- (delete-char -1)
- (ruby-electric-replace-region-or-insert)))))
-
-(defun ruby-electric-delete-backward-char(arg)
- (interactive "*p")
- (cond ((memq last-command '(ruby-electric-matching-char
- ruby-electric-bar))
- (delete-char 1))
- ((eq last-command 'ruby-electric-curlies)
- (cond ((eolp)
- (cond ((char-equal (preceding-char) ?\s)
- (setq this-command last-command))
- ((char-equal (preceding-char) ?{)
- (and (looking-at "[ \t\n]*}")
- (delete-char (- (match-end 0) (match-beginning 0)))))))
- ((char-equal (following-char) ?\s)
- (setq this-command last-command)
- (delete-char 1))
- ((char-equal (following-char) ?})
- (delete-char 1))))
- ((eq last-command 'ruby-electric-hash)
- (and (char-equal (preceding-char) ?{)
- (delete-char 1))))
- (delete-char (- arg)))
-
-(put 'ruby-electric-delete-backward-char 'delete-selection 'supersede)
-
-(defun ruby-electric-end ()
- (interactive)
- (if (eq (char-syntax (preceding-char)) ?w)
- (insert " "))
- (insert "end")
- (save-excursion
- (if (eq (char-syntax (following-char)) ?w)
- (insert " "))
- (ruby-indent-line t)))
-
-(provide 'ruby-electric)
-
-;;; ruby-electric.el ends here
diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el
deleted file mode 100644
index b1abd18a9e..0000000000
--- a/misc/ruby-mode.el
+++ /dev/null
@@ -1,1584 +0,0 @@
-;;; ruby-mode.el --- Major mode for editing Ruby files
-
-;; Copyright (C) 1994, 1995, 1996 1997, 1998, 1999, 2000, 2001,
-;; 2002,2003, 2004, 2005, 2006, 2007, 2008
-;; Free Software Foundation, Inc.
-
-;; Authors: Yukihiro Matsumoto, Nobuyoshi Nakada
-;; URL: http://www.emacswiki.org/cgi-bin/wiki/RubyMode
-;; Created: Fri Feb 4 14:49:13 JST 1994
-;; Keywords: languages ruby
-;; Version: 0.9
-
-;; This file is not part of GNU Emacs. However, a newer version of
-;; ruby-mode is included in recent releases of GNU Emacs (version 23
-;; and up), but the new version is not guaranteed to be compatible
-;; with older versions of Emacs or XEmacs. This file is the last
-;; version that aims to keep this compatibility.
-
-;; You can also get the latest version from the Emacs Lisp Package
-;; Archive: http://tromey.com/elpa
-
-;; This file is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; It 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 it. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Provides font-locking, indentation support, and navigation for Ruby code.
-;;
-;; If you're installing manually, you should add this to your .emacs
-;; file after putting it on your load path:
-;;
-;; (autoload 'ruby-mode "ruby-mode" "Major mode for ruby files" t)
-;; (add-to-list 'auto-mode-alist '("\\.rb$" . ruby-mode))
-;; (add-to-list 'interpreter-mode-alist '("ruby" . ruby-mode))
-;;
-
-;;; Code:
-
-(defconst ruby-mode-revision "$Revision$"
- "Ruby mode revision string.")
-
-(defconst ruby-mode-version
- (and (string-match "[0-9.]+" ruby-mode-revision)
- (substring ruby-mode-revision (match-beginning 0) (match-end 0)))
- "Ruby mode version number.")
-
-(defconst ruby-keyword-end-re
- (if (string-match "\\_>" "ruby")
- "\\_>"
- "\\>"))
-
-(defconst ruby-block-beg-keywords
- '("class" "module" "def" "if" "unless" "case" "while" "until" "for" "begin" "do")
- "Keywords at the beginning of blocks.")
-
-(defconst ruby-block-beg-re
- (regexp-opt ruby-block-beg-keywords)
- "Regexp to match the beginning of blocks.")
-
-(defconst ruby-non-block-do-re
- (concat (regexp-opt '("while" "until" "for" "rescue") t) ruby-keyword-end-re)
- "Regexp to match")
-
-(defconst ruby-indent-beg-re
- (concat "\\(\\s *" (regexp-opt '("class" "module" "def") t) "\\)\\|"
- (regexp-opt '("if" "unless" "case" "while" "until" "for" "begin")))
- "Regexp to match where the indentation gets deeper.")
-
-(defconst ruby-modifier-beg-keywords
- '("if" "unless" "while" "until")
- "Modifiers that are the same as the beginning of blocks.")
-
-(defconst ruby-modifier-beg-re
- (regexp-opt ruby-modifier-beg-keywords)
- "Regexp to match modifiers same as the beginning of blocks.")
-
-(defconst ruby-modifier-re
- (regexp-opt (cons "rescue" ruby-modifier-beg-keywords))
- "Regexp to match modifiers.")
-
-(defconst ruby-block-mid-keywords
- '("then" "else" "elsif" "when" "rescue" "ensure")
- "Keywords where the indentation gets shallower in middle of block statements.")
-
-(defconst ruby-block-mid-re
- (regexp-opt ruby-block-mid-keywords)
- "Regexp to match where the indentation gets shallower in middle of block statements.")
-
-(defconst ruby-block-op-keywords
- '("and" "or" "not")
- "Block operators.")
-
-(defconst ruby-block-hanging-re
- (regexp-opt (append ruby-modifier-beg-keywords ruby-block-op-keywords))
- "Regexp to match hanging block modifiers.")
-
-(defconst ruby-block-end-re "\\_<end\\_>")
-
-(defconst ruby-here-doc-beg-re
- "\\(<\\)<\\([-~]\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)")
-
-(defconst ruby-here-doc-end-re
- "^\\([ \t]+\\)?\\(.*\\)\\(.\\)$")
-
-(defun ruby-here-doc-end-match ()
- (concat "^"
- (if (match-string 2) "[ \t]*" nil)
- (regexp-quote
- (or (match-string 4)
- (match-string 5)
- (match-string 6)))))
-
-(defun ruby-here-doc-beg-match ()
- (let ((contents (concat
- (regexp-quote (concat (match-string 2) (match-string 3)))
- (if (string= (match-string 3) "_") "\\B" "\\b"))))
- (concat "<<"
- (let ((match (match-string 1)))
- (if (and match (> (length match) 0))
- (concat "\\(?:[-~]\\([\"']?\\)\\|\\([\"']\\)" (match-string 1) "\\)"
- contents "\\(\\1\\|\\2\\)")
- (concat "[-~]?\\([\"']\\|\\)" contents "\\1"))))))
-
-(defconst ruby-delimiter
- (concat "[?$/%(){}#\"'`.:]\\|<<\\|\\[\\|\\]\\|\\_<\\("
- ruby-block-beg-re
- "\\)\\_>\\|" ruby-block-end-re
- "\\|^=begin\\|" ruby-here-doc-beg-re)
- )
-
-(defconst ruby-negative
- (concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\>\\|"
- ruby-block-end-re "\\|}\\|\\]\\)")
- "Regexp to match where the indentation gets shallower.")
-
-(defconst ruby-operator-chars "-,.+*/%&|^~=<>:")
-(defconst ruby-operator-re (concat "[" ruby-operator-chars "]"))
-
-(defconst ruby-symbol-chars "a-zA-Z0-9_")
-(defconst ruby-symbol-re (concat "[" ruby-symbol-chars "]"))
-
-(defvar ruby-mode-abbrev-table nil
- "Abbrev table in use in ruby-mode buffers.")
-
-(define-abbrev-table 'ruby-mode-abbrev-table ())
-
-(defvar ruby-mode-map nil "Keymap used in ruby mode.")
-
-(if ruby-mode-map
- nil
- (setq ruby-mode-map (make-sparse-keymap))
- (define-key ruby-mode-map "{" 'ruby-electric-brace)
- (define-key ruby-mode-map "}" 'ruby-electric-brace)
- (define-key ruby-mode-map "\e\C-a" 'ruby-beginning-of-defun)
- (define-key ruby-mode-map "\e\C-e" 'ruby-end-of-defun)
- (define-key ruby-mode-map "\e\C-b" 'ruby-backward-sexp)
- (define-key ruby-mode-map "\e\C-f" 'ruby-forward-sexp)
- (define-key ruby-mode-map "\e\C-p" 'ruby-beginning-of-block)
- (define-key ruby-mode-map "\e\C-n" 'ruby-end-of-block)
- (define-key ruby-mode-map "\e\C-h" 'ruby-mark-defun)
- (define-key ruby-mode-map "\e\C-q" 'ruby-indent-exp)
- (define-key ruby-mode-map "\t" 'ruby-indent-command)
- (define-key ruby-mode-map "\C-c\C-e" 'ruby-insert-end)
- (define-key ruby-mode-map "\C-j" 'ruby-reindent-then-newline-and-indent)
- (define-key ruby-mode-map "\C-c{" 'ruby-toggle-block)
- (define-key ruby-mode-map "\C-c\C-u" 'uncomment-region))
-
-(defvar ruby-mode-syntax-table nil
- "Syntax table in use in ruby-mode buffers.")
-
-(if ruby-mode-syntax-table
- ()
- (setq ruby-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\' "\"" ruby-mode-syntax-table)
- (modify-syntax-entry ?\" "\"" ruby-mode-syntax-table)
- (modify-syntax-entry ?\` "\"" ruby-mode-syntax-table)
- (modify-syntax-entry ?# "<" ruby-mode-syntax-table)
- (modify-syntax-entry ?\n ">" ruby-mode-syntax-table)
- (modify-syntax-entry ?\\ "\\" ruby-mode-syntax-table)
- (modify-syntax-entry ?$ "." ruby-mode-syntax-table)
- (modify-syntax-entry ?? "_" ruby-mode-syntax-table)
- (modify-syntax-entry ?_ "_" ruby-mode-syntax-table)
- (modify-syntax-entry ?: "_" ruby-mode-syntax-table)
- (modify-syntax-entry ?< "." ruby-mode-syntax-table)
- (modify-syntax-entry ?> "." ruby-mode-syntax-table)
- (modify-syntax-entry ?& "." ruby-mode-syntax-table)
- (modify-syntax-entry ?| "." ruby-mode-syntax-table)
- (modify-syntax-entry ?% "." ruby-mode-syntax-table)
- (modify-syntax-entry ?= "." ruby-mode-syntax-table)
- (modify-syntax-entry ?/ "." ruby-mode-syntax-table)
- (modify-syntax-entry ?+ "." ruby-mode-syntax-table)
- (modify-syntax-entry ?* "." ruby-mode-syntax-table)
- (modify-syntax-entry ?- "." ruby-mode-syntax-table)
- (modify-syntax-entry ?\; "." ruby-mode-syntax-table)
- (modify-syntax-entry ?\( "()" ruby-mode-syntax-table)
- (modify-syntax-entry ?\) ")(" ruby-mode-syntax-table)
- (modify-syntax-entry ?\{ "(}" ruby-mode-syntax-table)
- (modify-syntax-entry ?\} "){" ruby-mode-syntax-table)
- (modify-syntax-entry ?\[ "(]" ruby-mode-syntax-table)
- (modify-syntax-entry ?\] ")[" ruby-mode-syntax-table)
- )
-
-(defcustom ruby-indent-tabs-mode nil
- "*Indentation can insert tabs in ruby mode if this is non-nil."
- :type 'boolean :group 'ruby)
-(put 'ruby-indent-tabs-mode 'safe-local-variable 'booleanp)
-
-(defcustom ruby-indent-level 2
- "*Indentation of ruby statements."
- :type 'integer :group 'ruby)
-(put 'ruby-indent-level 'safe-local-variable 'integerp)
-
-(defcustom ruby-comment-column 32
- "*Indentation column of comments."
- :type 'integer :group 'ruby)
-(put 'ruby-comment-column 'safe-local-variable 'integerp)
-
-(defcustom ruby-deep-arglist t
- "*Deep indent lists in parenthesis when non-nil.
-Also ignores spaces after parenthesis when 'space."
- :group 'ruby)
-(put 'ruby-deep-arglist 'safe-local-variable 'booleanp)
-
-(defcustom ruby-deep-indent-paren '(?\( ?\[ ?\] t)
- "*Deep indent lists in parenthesis when non-nil. t means continuous line.
-Also ignores spaces after parenthesis when 'space."
- :group 'ruby)
-
-(defcustom ruby-deep-indent-paren-style 'space
- "Default deep indent style."
- :options '(t nil space) :group 'ruby)
-
-(defcustom ruby-encoding-map
- '((us-ascii . nil) ;; Do not put coding: us-ascii
- (utf-8 . nil) ;; Do not put coding: utf-8
- (shift-jis . cp932) ;; Emacs charset name of Shift_JIS
- (shift_jis . cp932) ;; MIME charset name of Shift_JIS
- (japanese-cp932 . cp932)) ;; Emacs charset name of CP932
- "Alist to map encoding name from Emacs to Ruby.
-Associating an encoding name with nil means it needs not be
-explicitly declared in magic comment."
- :type '(repeat (cons (symbol :tag "From") (symbol :tag "To")))
- :group 'ruby)
-
-(defcustom ruby-use-encoding-map t
- "*Use `ruby-encoding-map' to set encoding magic comment if this is non-nil."
- :type 'boolean :group 'ruby)
-
-(defvar ruby-indent-point nil "internal variable")
-
-(eval-when-compile (require 'cl))
-(defun ruby-imenu-create-index-in-block (prefix beg end)
- (let ((index-alist '()) (case-fold-search nil)
- name next pos decl sing)
- (goto-char beg)
- (while (re-search-forward "^\\s *\\(\\(class\\s +\\|\\(class\\s *<<\\s *\\)\\|module\\s +\\)\\([^\(<\n ]+\\)\\|\\(def\\|alias\\)\\s +\\([^\(\n ]+\\)\\)" end t)
- (setq sing (match-beginning 3))
- (setq decl (match-string 5))
- (setq next (match-end 0))
- (setq name (or (match-string 4) (match-string 6)))
- (setq pos (match-beginning 0))
- (cond
- ((string= "alias" decl)
- (if prefix (setq name (concat prefix name)))
- (push (cons name pos) index-alist))
- ((string= "def" decl)
- (if prefix
- (setq name
- (cond
- ((string-match "^self\." name)
- (concat (substring prefix 0 -1) (substring name 4)))
- (t (concat prefix name)))))
- (push (cons name pos) index-alist)
- (ruby-accurate-end-of-block end))
- (t
- (if (string= "self" name)
- (if prefix (setq name (substring prefix 0 -1)))
- (if prefix (setq name (concat (substring prefix 0 -1) "::" name)))
- (push (cons name pos) index-alist))
- (ruby-accurate-end-of-block end)
- (setq beg (point))
- (setq index-alist
- (nconc (ruby-imenu-create-index-in-block
- (concat name (if sing "." "#"))
- next beg) index-alist))
- (goto-char beg))))
- index-alist))
-
-(defun ruby-imenu-create-index ()
- (nreverse (ruby-imenu-create-index-in-block nil (point-min) nil)))
-
-(defun ruby-accurate-end-of-block (&optional end)
- (let (state)
- (or end (setq end (point-max)))
- (while (and (setq state (apply 'ruby-parse-partial end state))
- (>= (nth 2 state) 0) (< (point) end)))))
-
-(defun ruby-mode-variables ()
- (set-syntax-table ruby-mode-syntax-table)
- (setq show-trailing-whitespace t)
- (setq local-abbrev-table ruby-mode-abbrev-table)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'ruby-indent-line)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- (make-local-variable 'comment-start)
- (setq comment-start "# ")
- (make-local-variable 'comment-end)
- (setq comment-end "")
- (make-local-variable 'comment-column)
- (setq comment-column ruby-comment-column)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "#+ *")
- (setq indent-tabs-mode ruby-indent-tabs-mode)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (make-local-variable 'parse-sexp-lookup-properties)
- (setq parse-sexp-lookup-properties t)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t))
-
-(defun ruby-mode-set-encoding ()
- "Insert or update a magic comment header with the proper encoding.
-`ruby-encoding-map' is looked up to convert an encoding name from
-Emacs to Ruby."
- (let* ((nonascii
- (save-excursion
- (widen)
- (goto-char (point-min))
- (re-search-forward "[^\0-\177]" nil t)))
- (coding-system
- (or coding-system-for-write
- buffer-file-coding-system))
- (coding-system
- (and coding-system
- (coding-system-change-eol-conversion coding-system nil)))
- (coding-system
- (and coding-system
- (or
- (coding-system-get coding-system :mime-charset)
- (let ((coding-type (coding-system-get coding-system :coding-type)))
- (cond ((eq coding-type 'undecided)
- (if nonascii
- (or (and (coding-system-get coding-system :prefer-utf-8)
- 'utf-8)
- (coding-system-get default-buffer-file-coding-system :coding-type)
- 'ascii-8bit)))
- ((memq coding-type '(utf-8 shift-jis))
- coding-type)
- (t coding-system))))))
- (coding-system
- (or coding-system
- 'us-ascii))
- (coding-system
- (let ((cons (assq coding-system ruby-encoding-map)))
- (if cons (cdr cons) coding-system)))
- (coding-system
- (and coding-system
- (symbol-name coding-system))))
- (if coding-system
- (save-excursion
- (widen)
- (goto-char (point-min))
- (if (looking-at "^#!") (beginning-of-line 2))
- (cond ((looking-at "\\s *#.*-\*-\\s *\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)\\s *\\(;\\|-\*-\\)")
- (unless (string= (match-string 2) coding-system)
- (goto-char (match-beginning 2))
- (delete-region (point) (match-end 2))
- (and (looking-at "-\*-")
- (let ((n (skip-chars-backward " ")))
- (cond ((= n 0) (insert " ") (backward-char))
- ((= n -1) (insert " "))
- ((forward-char)))))
- (insert coding-system)))
- ((looking-at "\\s *#.*coding\\s *[:=]"))
- (t (when ruby-insert-encoding-magic-comment
- (insert "# -*- coding: " coding-system " -*-\n"))))))))
-
-(defun ruby-current-indentation ()
- (save-excursion
- (beginning-of-line)
- (back-to-indentation)
- (current-column)))
-
-(defun ruby-indent-line (&optional flag)
- "Correct indentation of the current ruby line."
- (ruby-indent-to (ruby-calculate-indent)))
-
-(defun ruby-indent-command ()
- (interactive)
- (ruby-indent-line t))
-
-(defun ruby-indent-to (x)
- (if x
- (let (shift top beg)
- (and (< x 0) (error "invalid nest"))
- (setq shift (current-column))
- (beginning-of-line)
- (setq beg (point))
- (back-to-indentation)
- (setq top (current-column))
- (skip-chars-backward " \t")
- (if (>= shift top) (setq shift (- shift top))
- (setq shift 0))
- (if (and (bolp)
- (= x top))
- (move-to-column (+ x shift))
- (move-to-column top)
- (delete-region beg (point))
- (beginning-of-line)
- (indent-to x)
- (move-to-column (+ x shift))))))
-
-(defun ruby-special-char-p (&optional pnt)
- (setq pnt (or pnt (point)))
- (let ((c (char-before pnt)) (b (and (< (point-min) pnt) (char-before (1- pnt)))))
- (cond ((or (eq c ??) (eq c ?$)))
- ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? ))))
- ((eq c ?\\) (eq b ??)))))
-
-(defun ruby-singleton-class-p ()
- (save-excursion
- (forward-word -1)
- (and (or (bolp) (not (eq (char-before (point)) ?_)))
- (looking-at "class\\s *<<"))))
-
-(defun ruby-expr-beg (&optional option)
- (save-excursion
- (store-match-data nil)
- (let ((space (skip-chars-backward " \t"))
- (start (point)))
- (cond
- ((bolp) t)
- ((progn
- (forward-char -1)
- (and (looking-at "\\?")
- (or (eq (char-syntax (preceding-char)) ?w)
- (ruby-special-char-p))))
- nil)
- ((and (eq option 'heredoc) (< space 0))
- (not (progn (goto-char start) (ruby-singleton-class-p))))
- ((or (looking-at ruby-operator-re)
- (looking-at "[\\[({,;]")
- (and (looking-at "[!?]")
- (or (not (eq option 'modifier))
- (bolp)
- (save-excursion (forward-char -1) (looking-at "\\Sw$"))))
- (and (looking-at ruby-symbol-re)
- (skip-chars-backward ruby-symbol-chars)
- (cond
- ((looking-at (regexp-opt
- (append ruby-block-beg-keywords
- ruby-block-op-keywords
- ruby-block-mid-keywords)
- 'words))
- (goto-char (match-end 0))
- (not (looking-at "\\s_\\|[!?:]")))
- ((eq option 'expr-qstr)
- (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]"))
- ((eq option 'expr-re)
- (looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]"))
- (t nil)))))))))
-
-(defun ruby-forward-string (term &optional end no-error expand)
- (let ((n 1) (c (string-to-char term))
- (re (if expand
- (concat "[^\\]\\(\\\\\\\\\\)*\\([" term "]\\|\\(#{\\)\\)")
- (concat "[^\\]\\(\\\\\\\\\\)*[" term "]"))))
- (while (and (re-search-forward re end no-error)
- (if (match-beginning 3)
- (ruby-forward-string "}{" end no-error nil)
- (> (setq n (if (eq (char-before (point)) c)
- (1- n) (1+ n))) 0)))
- (forward-char -1))
- (cond ((zerop n))
- (no-error nil)
- ((error "unterminated string")))))
-
-(defun ruby-deep-indent-paren-p (c &optional pos)
- (cond ((save-excursion
- (if pos (goto-char pos))
- (ruby-expr-beg))
- nil)
- ((listp ruby-deep-indent-paren)
- (let ((deep (assoc c ruby-deep-indent-paren)))
- (cond (deep
- (or (cdr deep) ruby-deep-indent-paren-style))
- ((memq c ruby-deep-indent-paren)
- ruby-deep-indent-paren-style))))
- ((eq c ruby-deep-indent-paren) ruby-deep-indent-paren-style)
- ((eq c ?\( ) ruby-deep-arglist)))
-
-(defun ruby-parse-partial (&optional end in-string nest depth pcol indent)
- (or depth (setq depth 0))
- (or indent (setq indent 0))
- (when (re-search-forward ruby-delimiter end 'move)
- (let ((pnt (point)) w re expand)
- (goto-char (match-beginning 0))
- (cond
- ((and (memq (char-before) '(?@ ?$)) (looking-at "\\sw"))
- (goto-char pnt))
- ((looking-at "[\"`]") ;skip string
- (cond
- ((and (not (eobp))
- (ruby-forward-string (buffer-substring (point) (1+ (point))) end t t))
- nil)
- (t
- (setq in-string (point))
- (goto-char end))))
- ((looking-at "'")
- (cond
- ((and (not (eobp))
- (re-search-forward "[^\\]\\(\\\\\\\\\\)*'" end t))
- nil)
- (t
- (setq in-string (point))
- (goto-char end))))
- ((looking-at "/=")
- (goto-char pnt))
- ((looking-at "/")
- (cond
- ((and (not (eobp)) (ruby-expr-beg 'expr-re))
- (if (ruby-forward-string "/" end t t)
- nil
- (setq in-string (point))
- (goto-char end)))
- (t
- (goto-char pnt))))
- ((looking-at "%")
- (cond
- ((and (not (eobp))
- (ruby-expr-beg 'expr-qstr)
- (not (looking-at "%="))
- (looking-at "%[QqrxWw]?\\([^a-zA-Z0-9 \t\n]\\)"))
- (goto-char (match-beginning 1))
- (setq expand (not (memq (char-before) '(?q ?w))))
- (setq w (match-string 1))
- (cond
- ((string= w "[") (setq re "]["))
- ((string= w "{") (setq re "}{"))
- ((string= w "(") (setq re ")("))
- ((string= w "<") (setq re "><"))
- ((and expand (string= w "\\"))
- (setq w (concat "\\" w))))
- (unless (cond (re (ruby-forward-string re end t expand))
- (expand (ruby-forward-string w end t t))
- (t (re-search-forward
- (if (string= w "\\")
- "\\\\[^\\]*\\\\"
- (concat "[^\\]\\(\\\\\\\\\\)*" w))
- end t)))
- (setq in-string (point))
- (goto-char end)))
- (t
- (goto-char pnt))))
- ((looking-at "\\?") ;skip ?char
- (cond
- ((and (ruby-expr-beg)
- (looking-at "?\\(\\\\C-\\|\\\\M-\\)*\\\\?."))
- (goto-char (match-end 0)))
- (t
- (goto-char pnt))))
- ((looking-at "\\$") ;skip $char
- (goto-char pnt)
- (forward-char 1))
- ((looking-at "#") ;skip comment
- (forward-line 1)
- (goto-char (point))
- )
- ((looking-at "[\\[{(]")
- (let ((deep (ruby-deep-indent-paren-p (char-after))))
- (if (and deep (or (not (eq (char-after) ?\{)) (ruby-expr-beg)))
- (progn
- (and (eq deep 'space) (looking-at ".\\s +[^# \t\n]")
- (setq pnt (1- (match-end 0))))
- (setq nest (cons (cons (char-after (point)) (point)) nest))
- (setq pcol (cons (cons pnt depth) pcol))
- (setq depth 0))
- (setq nest (cons (cons (char-after (point)) pnt) nest))
- (setq depth (1+ depth))))
- (goto-char pnt)
- )
- ((looking-at "[])}]")
- (if (ruby-deep-indent-paren-p (matching-paren (char-after))
- (if nest
- (cdr (nth 0 nest))
- (save-excursion
- (forward-char)
- (ruby-backward-sexp)
- (point))))
- (setq depth (cdr (car pcol)) pcol (cdr pcol))
- (setq depth (1- depth)))
- (setq nest (cdr nest))
- (goto-char pnt))
- ((looking-at ruby-block-end-re)
- (if (or (and (not (bolp))
- (progn
- (forward-char -1)
- (setq w (char-after (point)))
- (or (eq ?_ w)
- (eq ?. w))))
- (progn
- (goto-char pnt)
- (setq w (char-after (point)))
- (or (eq ?_ w)
- (eq ?! w)
- (eq ?? w))))
- nil
- (setq nest (cdr nest))
- (setq depth (1- depth)))
- (goto-char pnt))
- ((looking-at "def\\s +[^(\n;]*")
- (if (or (bolp)
- (progn
- (forward-char -1)
- (not (eq ?_ (char-after (point))))))
- (progn
- (setq nest (cons (cons nil pnt) nest))
- (setq depth (1+ depth))))
- (goto-char (match-end 0)))
- ((looking-at (concat "\\_<\\(" ruby-block-beg-re "\\)\\_>"))
- (and
- (save-match-data
- (or (not (looking-at (concat "do" ruby-keyword-end-re)))
- (save-excursion
- (back-to-indentation)
- (not (looking-at ruby-non-block-do-re)))))
- (or (bolp)
- (progn
- (forward-char -1)
- (setq w (char-after (point)))
- (not (or (eq ?_ w)
- (eq ?. w)))))
- (goto-char pnt)
- (setq w (char-after (point)))
- (not (eq ?_ w))
- (not (eq ?! w))
- (not (eq ?? w))
- (not (eq ?: w))
- (skip-chars-forward " \t")
- (goto-char (match-beginning 0))
- (or (not (looking-at ruby-modifier-re))
- (ruby-expr-beg 'modifier))
- (goto-char pnt)
- (setq nest (cons (cons nil pnt) nest))
- (setq depth (1+ depth)))
- (goto-char pnt))
- ((looking-at ":\\(['\"]\\)")
- (goto-char (match-beginning 1))
- (ruby-forward-string (buffer-substring (match-beginning 1) (match-end 1)) end))
- ((looking-at ":\\([-,.+*/%&|^~<>]=?\\|===?\\|<=>\\|![~=]?\\)")
- (goto-char (match-end 0)))
- ((looking-at ":\\([a-zA-Z_][a-zA-Z_0-9]*[!?=]?\\)?")
- (goto-char (match-end 0)))
- ((or (looking-at "\\.\\.\\.?")
- (looking-at "\\.[0-9]+")
- (looking-at "\\.[a-zA-Z_0-9]+")
- (looking-at "\\."))
- (goto-char (match-end 0)))
- ((looking-at "^=begin")
- (if (re-search-forward "^=end" end t)
- (forward-line 1)
- (setq in-string (match-end 0))
- (goto-char end)))
- ((looking-at "<<")
- (cond
- ((and (ruby-expr-beg 'heredoc)
- (looking-at "<<\\([-~]\\)?\\(\\([\"'`]\\)\\([^\n]+?\\)\\3\\|\\(?:\\sw\\|\\s_\\)+\\)"))
- (setq re (regexp-quote (or (match-string 4) (match-string 2))))
- (if (match-beginning 1) (setq re (concat "\\s *" re)))
- (let* ((id-end (goto-char (match-end 0)))
- (line-end-position (save-excursion (end-of-line) (point)))
- (state (list in-string nest depth pcol indent)))
- ;; parse the rest of the line
- (while (and (> line-end-position (point))
- (setq state (apply 'ruby-parse-partial
- line-end-position state))))
- (setq in-string (car state)
- nest (nth 1 state)
- depth (nth 2 state)
- pcol (nth 3 state)
- indent (nth 4 state))
- ;; skip heredoc section
- (if (re-search-forward (concat "^" re "$") end 'move)
- (forward-line 1)
- (setq in-string id-end)
- (goto-char end))))
- (t
- (goto-char pnt))))
- ((looking-at "^__END__$")
- (goto-char pnt))
- ((looking-at ruby-here-doc-beg-re)
- (if (re-search-forward (ruby-here-doc-end-match)
- ruby-indent-point t)
- (forward-line 1)
- (setq in-string (match-end 0))
- (goto-char ruby-indent-point)))
- (t
- (error (format "bad string %s"
- (buffer-substring (point) pnt)
- ))))))
- (list in-string nest depth pcol))
-
-(defun ruby-parse-region (start end)
- (let (state)
- (save-excursion
- (if start
- (goto-char start)
- (ruby-beginning-of-indent))
- (save-restriction
- (narrow-to-region (point) end)
- (while (and (> end (point))
- (setq state (apply 'ruby-parse-partial end state))))))
- (list (nth 0 state) ; in-string
- (car (nth 1 state)) ; nest
- (nth 2 state) ; depth
- (car (car (nth 3 state))) ; pcol
- ;(car (nth 5 state)) ; indent
- )))
-
-(defun ruby-indent-size (pos nest)
- (+ pos (* (or nest 1) ruby-indent-level)))
-
-(defun ruby-calculate-indent (&optional parse-start)
- (save-excursion
- (beginning-of-line)
- (let ((ruby-indent-point (point))
- (case-fold-search nil)
- state bol eol begin op-end
- (paren (progn (skip-syntax-forward " ")
- (and (char-after) (matching-paren (char-after)))))
- (indent 0))
- (if parse-start
- (goto-char parse-start)
- (ruby-beginning-of-indent)
- (setq parse-start (point)))
- (back-to-indentation)
- (setq indent (current-column))
- (setq state (ruby-parse-region parse-start ruby-indent-point))
- (cond
- ((nth 0 state) ; within string
- (setq indent nil)) ; do nothing
- ((car (nth 1 state)) ; in paren
- (goto-char (setq begin (cdr (nth 1 state))))
- (let ((deep (ruby-deep-indent-paren-p (car (nth 1 state))
- (1- (cdr (nth 1 state))))))
- (if deep
- (cond ((and (eq deep t) (eq (car (nth 1 state)) paren))
- (skip-syntax-backward " ")
- (setq indent (1- (current-column))))
- ((eq deep 'space)
- (goto-char (cdr (nth 1 state)))
- (setq indent (1+ (current-column))))
- ((let ((s (ruby-parse-region (point) ruby-indent-point)))
- (and (nth 2 s) (> (nth 2 s) 0)
- (or (goto-char (cdr (nth 1 s))) t)))
- (forward-word -1)
- (setq indent (ruby-indent-size (current-column) (nth 2 state))))
- (t
- (setq indent (current-column))
- (cond ((eq deep 'space))
- (paren (setq indent (1- indent)))
- (t (setq indent (ruby-indent-size (1- indent) 1))))))
- (if (nth 3 state) (goto-char (nth 3 state))
- (goto-char parse-start) (back-to-indentation))
- (setq indent (ruby-indent-size (current-column) (nth 2 state))))
- (and (eq (car (nth 1 state)) paren)
- (ruby-deep-indent-paren-p (matching-paren paren)
- (1- (cdr (nth 1 state))))
- (search-backward (char-to-string paren))
- (setq indent (current-column)))))
- ((and (nth 2 state) (> (nth 2 state) 0)) ; in nest
- (if (null (cdr (nth 1 state)))
- (error "invalid nest"))
- (goto-char (cdr (nth 1 state)))
- (forward-word -1) ; skip back a keyword
- (setq begin (point))
- (cond
- ((looking-at "do\\>[^_]") ; iter block is a special case
- (if (nth 3 state) (goto-char (nth 3 state))
- (goto-char parse-start) (back-to-indentation))
- (setq indent (ruby-indent-size (current-column) (nth 2 state))))
- (t
- (setq indent (+ (current-column) ruby-indent-level)))))
-
- ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest
- (setq indent (ruby-indent-size (current-column) (nth 2 state)))))
- (when indent
- (goto-char ruby-indent-point)
- (end-of-line)
- (setq eol (point))
- (beginning-of-line)
- (cond
- ((and (not (ruby-deep-indent-paren-p paren
- (and (cdr (nth 1 state))
- (1- (cdr (nth 1 state))))))
- (re-search-forward ruby-negative eol t))
- (and (not (eq ?_ (char-after (match-end 0))))
- (setq indent (- indent ruby-indent-level))))
- ((and
- (save-excursion
- (beginning-of-line)
- (not (bobp)))
- (or (ruby-deep-indent-paren-p t)
- (null (car (nth 1 state)))))
- ;; goto beginning of non-empty no-comment line
- (let (end done)
- (while (not done)
- (skip-chars-backward " \t\n")
- (setq end (point))
- (beginning-of-line)
- (if (re-search-forward "^\\s *#" end t)
- (beginning-of-line)
- (setq done t))))
- (setq bol (point))
- (end-of-line)
- ;; skip the comment at the end
- (skip-chars-backward " \t")
- (let (end (pos (point)))
- (beginning-of-line)
- (while (and (re-search-forward "#" pos t)
- (setq end (1- (point)))
- (or (ruby-special-char-p end)
- (and (setq state (ruby-parse-region parse-start end))
- (nth 0 state))))
- (setq end nil))
- (goto-char (or end pos))
- (skip-chars-backward " \t")
- (setq begin (if (and end (nth 0 state)) pos (cdr (nth 1 state))))
- (setq state (ruby-parse-region parse-start (point))))
- (or (bobp) (forward-char -1))
- (and
- (or (and (looking-at ruby-symbol-re)
- (skip-chars-backward ruby-symbol-chars)
- (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>"))
- (not (eq (point) (nth 3 state)))
- (save-excursion
- (goto-char (match-end 0))
- (not (looking-at "[a-z_]"))))
- (and (looking-at ruby-operator-re)
- (not (ruby-special-char-p))
- ;; operator at the end of line
- (let ((c (char-after (point))))
- (and
-;; (or (null begin)
-;; (save-excursion
-;; (goto-char begin)
-;; (skip-chars-forward " \t")
-;; (not (or (eolp) (looking-at "#")
-;; (and (eq (car (nth 1 state)) ?{)
-;; (looking-at "|"))))))
- (or (not (eq ?/ c))
- (null (nth 0 (ruby-parse-region (or begin parse-start) (point)))))
- (or (not (eq ?| (char-after (point))))
- (save-excursion
- (or (eolp) (forward-char -1))
- (cond
- ((search-backward "|" nil t)
- (skip-chars-backward " \t\n")
- (and (not (eolp))
- (progn
- (forward-char -1)
- (not (looking-at "{")))
- (progn
- (forward-word -1)
- (not (looking-at "do\\>[^_]")))))
- (t t))))
- (not (eq ?, c))
- (setq op-end t)))))
- (setq indent
- (cond
- ((and
- (null op-end)
- (not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>")))
- (eq (ruby-deep-indent-paren-p t) 'space)
- (not (bobp)))
- (widen)
- (goto-char (or begin parse-start))
- (skip-syntax-forward " ")
- (current-column))
- ((car (nth 1 state)) indent)
- (t
- (+ indent ruby-indent-level))))))))
- (goto-char ruby-indent-point)
- (beginning-of-line)
- (skip-syntax-forward " ")
- (if (looking-at "\\.[^.]\\|&\\.")
- (+ indent ruby-indent-level)
- indent))))
-
-(defun ruby-electric-brace (arg)
- (interactive "P")
- (insert-char last-command-event 1)
- (ruby-indent-line t)
- (delete-char -1)
- (self-insert-command (prefix-numeric-value arg)))
-
-(eval-when-compile
- (defmacro defun-region-command (func args &rest body)
- (let ((intr (car body)))
- (when (featurep 'xemacs)
- (if (stringp intr) (setq intr (cadr body)))
- (and (eq (car intr) 'interactive)
- (setq intr (cdr intr))
- (setcar intr (concat "_" (car intr)))))
- (cons 'defun (cons func (cons args body))))))
-
-(defun-region-command ruby-beginning-of-defun (&optional arg)
- "Move backward to next beginning-of-defun.
-With argument, do this that many times.
-Returns t unless search stops due to end of buffer."
- (interactive "p")
- (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)\\_>")
- nil 'move (or arg 1))
- (progn (beginning-of-line) t)))
-
-(defun ruby-beginning-of-indent ()
- (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\_>")
- nil 'move)
- (progn
- (beginning-of-line)
- t)))
-
-(defun-region-command ruby-end-of-defun (&optional arg)
- "Move forward to next end of defun.
-An end of a defun is found by moving forward from the beginning of one."
- (interactive "p")
- (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\($\\|\\b[^_]\\)")
- nil 'move (or arg 1))
- (progn (beginning-of-line) t))
- (forward-line 1))
-
-(defun ruby-move-to-block (n)
- (let (start pos done down (orig (point)))
- (setq start (ruby-calculate-indent))
- (setq down (looking-at (if (< n 0) ruby-block-end-re
- (concat "\\<\\(" ruby-block-beg-re "\\)\\>"))))
- (while (and (not done) (not (if (< n 0) (bobp) (eobp))))
- (forward-line n)
- (cond
- ((looking-at "^\\s *$"))
- ((looking-at "^\\s *#"))
- ((and (> n 0) (looking-at "^=begin\\>"))
- (re-search-forward "^=end\\>"))
- ((and (< n 0) (looking-at "^=end\\>"))
- (re-search-backward "^=begin\\>"))
- (t
- (setq pos (current-indentation))
- (cond
- ((< start pos)
- (setq down t))
- ((and down (= pos start))
- (setq done t))
- ((> start pos)
- (setq done t)))))
- (if done
- (save-excursion
- (back-to-indentation)
- (if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>"))
- (setq done nil)))))
- (back-to-indentation)
- (when (< n 0)
- (let ((eol (point-at-eol)) state next)
- (if (< orig eol) (setq eol orig))
- (setq orig (point))
- (while (and (setq next (apply 'ruby-parse-partial eol state))
- (< (point) eol))
- (setq state next))
- (when (cdaadr state)
- (goto-char (cdaadr state)))
- (backward-word)))))
-
-(defun-region-command ruby-beginning-of-block (&optional arg)
- "Move backward to next beginning-of-block"
- (interactive "p")
- (ruby-move-to-block (- (or arg 1))))
-
-(defun-region-command ruby-end-of-block (&optional arg)
- "Move forward to next beginning-of-block"
- (interactive "p")
- (ruby-move-to-block (or arg 1)))
-
-(defun-region-command ruby-forward-sexp (&optional cnt)
- (interactive "p")
- (if (and (numberp cnt) (< cnt 0))
- (ruby-backward-sexp (- cnt))
- (let ((i (or cnt 1)))
- (condition-case nil
- (while (> i 0)
- (skip-syntax-forward " ")
- (if (looking-at ",\\s *") (goto-char (match-end 0)))
- (cond ((looking-at "\\?\\(\\\\[CM]-\\)*\\\\?\\S ")
- (goto-char (match-end 0)))
- ((progn
- (skip-chars-forward ",.:;|&^~=!?\\+\\-\\*")
- (looking-at "\\s("))
- (goto-char (scan-sexps (point) 1)))
- ((and (looking-at (concat "\\<\\(" ruby-block-beg-re "\\)\\>"))
- (not (eq (char-before (point)) ?.))
- (not (eq (char-before (point)) ?:)))
- (ruby-end-of-block)
- (forward-word 1))
- ((looking-at "\\(\\$\\|@@?\\)?\\sw")
- (while (progn
- (while (progn (forward-word 1) (looking-at "_")))
- (cond ((looking-at "::") (forward-char 2) t)
- ((> (skip-chars-forward ".") 0))
- ((looking-at "\\?\\|!\\(=[~=>]\\|[^~=]\\)")
- (forward-char 1) nil)))))
- ((let (state expr)
- (while
- (progn
- (setq expr (or expr (ruby-expr-beg)
- (looking-at "%\\sw?\\Sw\\|[\"'`/]")))
- (nth 1 (setq state (apply 'ruby-parse-partial nil state))))
- (setq expr t)
- (skip-chars-forward "<"))
- (not expr))))
- (setq i (1- i)))
- ((error) (forward-word 1)))
- i)))
-
-(defun-region-command ruby-backward-sexp (&optional cnt)
- (interactive "p")
- (if (and (numberp cnt) (< cnt 0))
- (ruby-forward-sexp (- cnt))
- (let ((i (or cnt 1)))
- (condition-case nil
- (while (> i 0)
- (skip-chars-backward " \t\n,.:;|&^~=!?\\+\\-\\*")
- (forward-char -1)
- (cond ((looking-at "\\s)")
- (goto-char (scan-sexps (1+ (point)) -1))
- (case (char-before)
- (?% (forward-char -1))
- ('(?q ?Q ?w ?W ?r ?x)
- (if (eq (char-before (1- (point))) ?%) (forward-char -2))))
- nil)
- ((looking-at "\\s\"\\|\\\\\\S_")
- (let ((c (char-to-string (char-before (match-end 0)))))
- (while (and (search-backward c)
- (oddp (skip-chars-backward "\\")))))
- nil)
- ((looking-at "\\s.\\|\\s\\")
- (if (ruby-special-char-p) (forward-char -1)))
- ((looking-at "\\s(") nil)
- (t
- (forward-char 1)
- (while (progn (forward-word -1)
- (case (char-before)
- (?_ t)
- (?. (forward-char -1) t)
- ((?$ ?@)
- (forward-char -1)
- (and (eq (char-before) (char-after)) (forward-char -1)))
- (?:
- (forward-char -1)
- (eq (char-before) :)))))
- (if (looking-at ruby-block-end-re)
- (ruby-beginning-of-block))
- nil))
- (setq i (1- i)))
- ((error)))
- i)))
-
-(defun ruby-reindent-then-newline-and-indent ()
- (interactive "*")
- (newline)
- (save-excursion
- (end-of-line 0)
- (indent-according-to-mode)
- (delete-region (point) (progn (skip-chars-backward " \t") (point))))
- (indent-according-to-mode))
-
-(fset 'ruby-encomment-region (symbol-function 'comment-region))
-
-(defun ruby-decomment-region (beg end)
- (interactive "r")
- (save-excursion
- (goto-char beg)
- (while (re-search-forward "^\\([ \t]*\\)#" end t)
- (replace-match "\\1" nil nil)
- (save-excursion
- (ruby-indent-line)))))
-
-(defun ruby-insert-end ()
- (interactive)
- (insert "end")
- (ruby-indent-line t)
- (end-of-line))
-
-(defun ruby-mark-defun ()
- "Put mark at end of this Ruby function, point at beginning."
- (interactive)
- (push-mark (point))
- (ruby-end-of-defun)
- (push-mark (point) nil t)
- (ruby-beginning-of-defun)
- (re-search-backward "^\n" (- (point) 1) t))
-
-(defun ruby-indent-exp (&optional shutup-p)
- "Indent each line in the balanced expression following point syntactically.
-If optional SHUTUP-P is non-nil, no errors are signalled if no
-balanced expression is found."
- (interactive "*P")
- (let ((here (point-marker)) start top column (nest t))
- (set-marker-insertion-type here t)
- (unwind-protect
- (progn
- (beginning-of-line)
- (setq start (point) top (current-indentation))
- (while (and (not (eobp))
- (progn
- (setq column (ruby-calculate-indent start))
- (cond ((> column top)
- (setq nest t))
- ((and (= column top) nest)
- (setq nest nil) t))))
- (ruby-indent-to column)
- (beginning-of-line 2)))
- (goto-char here)
- (set-marker here nil))))
-
-(defun ruby-add-log-current-method ()
- "Return current method string."
- (condition-case nil
- (save-excursion
- (let (mname mlist (indent 0))
- ;; get current method (or class/module)
- (if (re-search-backward
- (concat "^[ \t]*\\(def\\|class\\|module\\)[ \t]+"
- "\\("
- ;; \\. and :: for class method
- "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
- "+\\)")
- nil t)
- (progn
- (setq mname (match-string 2))
- (unless (string-equal "def" (match-string 1))
- (setq mlist (list mname) mname nil))
- (goto-char (match-beginning 1))
- (setq indent (current-column))
- (beginning-of-line)))
- ;; nest class/module
- (while (and (> indent 0)
- (re-search-backward
- (concat
- "^[ \t]*\\(class\\|module\\)[ \t]+"
- "\\([A-Z]" ruby-symbol-re "*\\)")
- nil t))
- (goto-char (match-beginning 1))
- (if (< (current-column) indent)
- (progn
- (setq mlist (cons (match-string 2) mlist))
- (setq indent (current-column))
- (beginning-of-line))))
- (when mname
- (let ((mn (split-string mname "\\.\\|::")))
- (if (cdr mn)
- (progn
- (cond
- ((string-equal "" (car mn))
- (setq mn (cdr mn) mlist nil))
- ((string-equal "self" (car mn))
- (setq mn (cdr mn)))
- ((let ((ml (nreverse mlist)))
- (while ml
- (if (string-equal (car ml) (car mn))
- (setq mlist (nreverse (cdr ml)) ml nil))
- (or (setq ml (cdr ml)) (nreverse mlist))))))
- (if mlist
- (setcdr (last mlist) mn)
- (setq mlist mn))
- (setq mn (last mn 2))
- (setq mname (concat "." (cadr mn)))
- (setcdr mn nil))
- (setq mname (concat "#" mname)))))
- ;; generate string
- (if (consp mlist)
- (setq mlist (mapconcat (function identity) mlist "::")))
- (if mname
- (if mlist (concat mlist mname) mname)
- mlist)))))
-
-(defun ruby-brace-to-do-end ()
- (when (looking-at "{")
- (let ((orig (point)) (end (progn (ruby-forward-sexp) (point)))
- oneline (end (make-marker)))
- (setq oneline (and (eolp) (<= (point-at-bol) orig)))
- (when (eq (char-before) ?\})
- (delete-char -1)
- (cond
- (oneline
- (insert "\n")
- (set-marker end (point)))
- ((eq (char-syntax (preceding-char)) ?w)
- (insert " ")))
- (insert "end")
- (if (eq (char-syntax (following-char)) ?w)
- (insert " "))
- (goto-char orig)
- (delete-char 1)
- (if (eq (char-syntax (preceding-char)) ?w)
- (insert " "))
- (insert "do")
- (when (looking-at "\\sw\\||")
- (insert " ")
- (backward-char))
- (when oneline
- (setq orig (point))
- (when (cond
- ((looking-at "\\s *|")
- (goto-char (match-end 0))
- (and (search-forward "|" (point-at-eol) 'move)
- (not (eolp))))
- (t))
- (while (progn
- (insert "\n")
- (ruby-forward-sexp)
- (looking-at "\\s *;\\s *"))
- (delete-char (- (match-end 0) (match-beginning 0))))
- (goto-char orig)
- (beginning-of-line 2)
- (indent-region (point) end))
- (goto-char orig))
- t))))
-
-(defun ruby-do-end-to-brace ()
- (when (and (or (bolp)
- (not (memq (char-syntax (preceding-char)) '(?w ?_))))
- (looking-at "\\<do\\(\\s \\|$\\)"))
- (let ((orig (point)) (end (progn (ruby-forward-sexp) (point)))
- first last)
- (backward-char 3)
- (when (looking-at ruby-block-end-re)
- (delete-char 3)
- (insert "}")
- (setq last (and (eolp)
- (progn (backward-char 1)
- (skip-syntax-backward " ")
- (bolp))
- (1- (point-at-eol -1))))
- (goto-char orig)
- (delete-char 2)
- (insert "{")
- (setq orig (point))
- (when (and last (<= last (point))
- (not (search-forward "#" (setq first (point-at-eol)) t)))
- (goto-char (- end 4))
- (end-of-line 0)
- (if (looking-at "\n\\s *")
- (delete-char (- (match-end 0) (match-beginning 0))) t)
- (goto-char first)
- (if (looking-at "\n\\s *")
- (delete-char (- (match-end 0) (match-beginning 0))) t))
- (goto-char orig)
- (if (looking-at "\\s +|")
- (delete-char (- (match-end 0) (match-beginning 0) 1)))
- t))))
-
-(defun ruby-toggle-block ()
- (interactive)
- (or (ruby-brace-to-do-end)
- (ruby-do-end-to-brace)))
-
-(eval-when-compile
- (if (featurep 'font-lock)
- (defmacro eval-when-font-lock-available (&rest args) (cons 'progn args))
- (defmacro eval-when-font-lock-available (&rest args))))
-
-(eval-when-compile
- (if (featurep 'hilit19)
- (defmacro eval-when-hilit19-available (&rest args) (cons 'progn args))
- (defmacro eval-when-hilit19-available (&rest args))))
-
-(eval-when-font-lock-available
- (or (boundp 'font-lock-variable-name-face)
- (setq font-lock-variable-name-face font-lock-type-face))
-
- (defconst ruby-font-lock-syntactic-keywords
- `(
- ;; #{ }, #$hoge, #@foo are not comments
- ("\\(#\\)[{$@]" 1 (1 . nil))
- ;; the last $', $", $` in the respective string is not variable
- ;; the last ?', ?", ?` in the respective string is not ascii code
- ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)"
- (2 (7 . nil))
- (4 (7 . nil)))
- ;; $' $" $` .... are variables
- ;; ?' ?" ?` are ascii codes
- ("\\(^\\|[^\\\\]\\)\\(\\\\\\\\\\)*[?$]\\([#\"'`]\\)" 3 (1 . nil))
- ;; regexps
- ("\\(^\\|[[{|=(,~?:;<>]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
- (4 (7 . ?/))
- (6 (7 . ?/)))
- ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
- ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))
- (,(concat ruby-here-doc-beg-re ".*\\(\n\\)")
- ,(+ 1 (regexp-opt-depth ruby-here-doc-beg-re))
- (ruby-here-doc-beg-syntax))
- (,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax))))
-
- (unless (functionp 'syntax-ppss)
- (defun syntax-ppss (&optional pos)
- (parse-partial-sexp (point-min) (or pos (point)))))
-
- (defun ruby-in-ppss-context-p (context &optional ppss)
- (let ((ppss (or ppss (syntax-ppss (point)))))
- (if (cond
- ((eq context 'anything)
- (or (nth 3 ppss)
- (nth 4 ppss)))
- ((eq context 'string)
- (nth 3 ppss))
- ((eq context 'heredoc)
- (and (nth 3 ppss)
- ;; If it's generic string, it's a heredoc and we don't care
- ;; See `parse-partial-sexp'
- (not (numberp (nth 3 ppss)))))
- ((eq context 'non-heredoc)
- (and (ruby-in-ppss-context-p 'anything)
- (not (ruby-in-ppss-context-p 'heredoc))))
- ((eq context 'comment)
- (nth 4 ppss))
- (t
- (error (concat
- "Internal error on `ruby-in-ppss-context-p': "
- "context name `" (symbol-name context) "' is unknown"))))
- t)))
-
- (defun ruby-in-here-doc-p ()
- (save-excursion
- (let ((old-point (point)) (case-fold-search nil))
- (beginning-of-line)
- (catch 'found-beg
- (while (and (re-search-backward ruby-here-doc-beg-re nil t)
- (not (ruby-singleton-class-p)))
- (if (not (or (ruby-in-ppss-context-p 'anything)
- (ruby-here-doc-find-end old-point)))
- (throw 'found-beg t)))))))
-
- (defun ruby-here-doc-find-end (&optional limit)
- "Expects the point to be on a line with one or more heredoc
-openers. Returns the buffer position at which all heredocs on the
-line are terminated, or nil if they aren't terminated before the
-buffer position `limit' or the end of the buffer."
- (save-excursion
- (beginning-of-line)
- (catch 'done
- (let ((eol (save-excursion (end-of-line) (point)))
- (case-fold-search nil)
- ;; Fake match data such that (match-end 0) is at eol
- (end-match-data (progn (looking-at ".*$") (match-data)))
- beg-match-data end-re)
- (while (re-search-forward ruby-here-doc-beg-re eol t)
- (setq beg-match-data (match-data))
- (setq end-re (ruby-here-doc-end-match))
-
- (set-match-data end-match-data)
- (goto-char (match-end 0))
- (unless (re-search-forward end-re limit t) (throw 'done nil))
- (setq end-match-data (match-data))
-
- (set-match-data beg-match-data)
- (goto-char (match-end 0)))
- (set-match-data end-match-data)
- (goto-char (match-end 0))
- (point)))))
-
- (defun ruby-here-doc-beg-syntax ()
- (save-excursion
- (goto-char (match-beginning 0))
- (unless (or (ruby-in-ppss-context-p 'non-heredoc)
- (ruby-in-here-doc-p))
- (string-to-syntax "|"))))
-
- (defun ruby-here-doc-end-syntax ()
- (let ((pss (syntax-ppss)) (case-fold-search nil))
- (when (ruby-in-ppss-context-p 'heredoc pss)
- (save-excursion
- (goto-char (nth 8 pss)) ; Go to the beginning of heredoc.
- (let ((eol (point)))
- (beginning-of-line)
- (if (and (re-search-forward (ruby-here-doc-beg-match) eol t) ; If there is a heredoc that matches this line...
- (not (ruby-in-ppss-context-p 'anything)) ; And that's not inside a heredoc/string/comment...
- (progn (goto-char (match-end 0)) ; And it's the last heredoc on its line...
- (not (re-search-forward ruby-here-doc-beg-re eol t))))
- (string-to-syntax "|")))))))
-
- (eval-when-compile
- (put 'ruby-mode 'font-lock-defaults
- '((ruby-font-lock-keywords)
- nil nil nil
- beginning-of-line
- (font-lock-syntactic-keywords
- . ruby-font-lock-syntactic-keywords))))
-
- (defun ruby-font-lock-docs (limit)
- (if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t)
- (let (beg)
- (beginning-of-line)
- (setq beg (point))
- (forward-line 1)
- (if (re-search-forward "^=end\\(\\s \\|$\\)" limit t)
- (progn
- (set-match-data (list beg (point)))
- t)))))
-
- (defun ruby-font-lock-maybe-docs (limit)
- (let (beg)
- (save-excursion
- (if (and (re-search-backward "^=\\(begin\\|end\\)\\(\\s \\|$\\)" nil t)
- (string= (match-string 1) "begin"))
- (progn
- (beginning-of-line)
- (setq beg (point)))))
- (if (and beg (and (re-search-forward "^=\\(begin\\|end\\)\\(\\s \\|$\\)" nil t)
- (string= (match-string 1) "end")))
- (progn
- (set-match-data (list beg (point)))
- t)
- nil)))
-
- (defvar ruby-font-lock-syntax-table
- (let* ((tbl (copy-syntax-table ruby-mode-syntax-table)))
- (modify-syntax-entry ?_ "w" tbl)
- tbl))
-
- (defconst ruby-font-lock-keywords
- (list
- ;; functions
- '("^\\s *def\\s +\\([^( \t\n]+\\)"
- 1 font-lock-function-name-face)
- ;; keywords
- (cons (concat
- "\\(^\\|[^_:.@$]\\|\\.\\.\\)\\_<\\(defined\\?\\|"
- (regexp-opt
- '("alias"
- "and"
- "begin"
- "break"
- "case"
- "catch"
- "class"
- "def"
- "do"
- "elsif"
- "else"
- "fail"
- "ensure"
- "for"
- "end"
- "if"
- "in"
- "module"
- "next"
- "not"
- "or"
- "raise"
- "redo"
- "rescue"
- "retry"
- "return"
- "then"
- "throw"
- "super"
- "unless"
- "undef"
- "until"
- "when"
- "while"
- "yield"
- )
- t)
- "\\)"
- ruby-keyword-end-re)
- 2)
- ;; here-doc beginnings
- (list ruby-here-doc-beg-re 0 'font-lock-string-face)
- ;; variables
- '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\_<\\(nil\\|self\\|true\\|false\\)\\>"
- 2 font-lock-variable-name-face)
- ;; variables
- '("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W"
- 1 font-lock-variable-name-face)
- '("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+"
- 0 font-lock-variable-name-face)
- ;; embedded document
- '(ruby-font-lock-docs
- 0 font-lock-comment-face t)
- '(ruby-font-lock-maybe-docs
- 0 font-lock-comment-face t)
- ;; general delimited string
- '("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)"
- (2 font-lock-string-face))
- ;; constants
- '("\\(^\\|[^_]\\)\\_<\\([A-Z]+\\(\\w\\|_\\)*\\)"
- 2 font-lock-type-face)
- ;; symbols
- '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
- 2 font-lock-reference-face)
- '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-reference-face)
- ;; expression expansion
- '("#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)"
- 0 font-lock-variable-name-face t)
- ;; warn lower camel case
- ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)"
- ; 0 font-lock-warning-face)
- )
- "*Additional expressions to highlight in ruby mode."))
-
-(eval-when-hilit19-available
- (hilit-set-mode-patterns
- 'ruby-mode
- '(("[^$\\?]\\(\"[^\\\"]*\\(\\\\\\(.\\|\n\\)[^\\\"]*\\)*\"\\)" 1 string)
- ("[^$\\?]\\('[^\\']*\\(\\\\\\(.\\|\n\\)[^\\']*\\)*'\\)" 1 string)
- ("[^$\\?]\\(`[^\\`]*\\(\\\\\\(.\\|\n\\)[^\\`]*\\)*`\\)" 1 string)
- ("^\\s *#.*$" nil comment)
- ("[^$@?\\]\\(#[^$@{\n].*$\\)" 1 comment)
- ("[^a-zA-Z_]\\(\\?\\(\\\\[CM]-\\)*.\\)" 1 string)
- ("^\\s *\\(require\\|load\\).*$" nil include)
- ("^\\s *\\(include\\|alias\\|undef\\).*$" nil decl)
- ("^\\s *\\<\\(class\\|def\\|module\\)\\>" "[)\n;]" defun)
- ("[^_]\\<\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|unless\\|rescue\\|then\\|when\\|while\\|until\\|do\\|yield\\)\\>\\([^_]\\|$\\)" 1 defun)
- ("[^_]\\<\\(and\\|break\\|next\\|raise\\|fail\\|in\\|not\\|or\\|redo\\|retry\\|return\\|super\\|yield\\|catch\\|throw\\|self\\|nil\\)\\>\\([^_]\\|$\\)" 1 keyword)
- ("\\$\\(.\\|\\sw+\\)" nil type)
- ("[$@].[a-zA-Z_0-9]*" nil struct)
- ("^__END__" nil label))))
-
-
-;;;###autoload
-(defun ruby-mode ()
- "Major mode for editing ruby scripts.
-\\[ruby-indent-command] properly indents subexpressions of multi-line
-class, module, def, if, while, for, do, and case statements, taking
-nesting into account.
-
-The variable ruby-indent-level controls the amount of indentation.
-\\{ruby-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (use-local-map ruby-mode-map)
- (setq mode-name "Ruby")
- (setq major-mode 'ruby-mode)
- (ruby-mode-variables)
-
- (make-local-variable 'imenu-create-index-function)
- (setq imenu-create-index-function 'ruby-imenu-create-index)
-
- (make-local-variable 'add-log-current-defun-function)
- (setq add-log-current-defun-function 'ruby-add-log-current-method)
-
- (add-hook
- (cond ((boundp 'before-save-hook)
- (make-local-variable 'before-save-hook)
- 'before-save-hook)
- ((boundp 'write-contents-functions) 'write-contents-functions)
- ((boundp 'write-contents-hooks) 'write-contents-hooks))
- 'ruby-mode-set-encoding)
-
- (set (make-local-variable 'font-lock-defaults) '((ruby-font-lock-keywords) nil nil))
- (set (make-local-variable 'font-lock-keywords) ruby-font-lock-keywords)
- (set (make-local-variable 'font-lock-syntax-table) ruby-font-lock-syntax-table)
- (set (make-local-variable 'font-lock-syntactic-keywords) ruby-font-lock-syntactic-keywords)
-
- (if (fboundp 'run-mode-hooks)
- (run-mode-hooks 'ruby-mode-hook)
- (run-hooks 'ruby-mode-hook)))
-
-(provide 'ruby-mode)
diff --git a/misc/ruby-style.el b/misc/ruby-style.el
index b8593b202a..13aad77b3d 100644
--- a/misc/ruby-style.el
+++ b/misc/ruby-style.el
@@ -55,7 +55,7 @@
'("bsd"
(c-basic-offset . 4)
(tab-width . 8)
- (indent-tabs-mode . t)
+ (indent-tabs-mode . nil)
(setq show-trailing-whitespace t)
(c-offsets-alist
(case-label . *)
@@ -75,7 +75,20 @@
(let ((head (progn (forward-line 100) (point)))
(case-fold-search nil))
(goto-char (point-min))
- (re-search-forward "Copyright (C) .* Yukihiro Matsumoto" head t))))
+ (re-search-forward "Copyright (C) .* Yukihiro Matsumoto" head t)))
+ (condition-case ()
+ (with-temp-buffer
+ (when (= 0 (call-process "git" nil t nil "remote" "get-url" "origin"))
+ (goto-char (point-min))
+ (looking-at ".*/ruby\\(\\.git\\)?$")))
+ (error))
+ (condition-case ()
+ (with-temp-buffer
+ (when (= 0 (call-process "svn" nil t nil "info" "--xml"))
+ (goto-char (point-min))
+ (search-forward-regexp "<root>.*/ruby</root>" nil)))
+ (error))
+ nil)
(c-set-style "ruby")))
(provide 'ruby-style)
diff --git a/misc/rubydb2x.el b/misc/rubydb2x.el
deleted file mode 100644
index a74265fb0e..0000000000
--- a/misc/rubydb2x.el
+++ /dev/null
@@ -1,104 +0,0 @@
-(require 'gud)
-(provide 'rubydb)
-
-;; ======================================================================
-;; rubydb functions
-
-;;; History of argument lists passed to rubydb.
-(defvar gud-rubydb-history nil)
-
-(defun gud-rubydb-massage-args (file args)
- (cons "-I" (cons "." (cons "-r" (cons "debug" (cons file args))))))
-
-;; There's no guarantee that Emacs will hand the filter the entire
-;; marker at once; it could be broken up across several strings. We
-;; might even receive a big chunk with several markers in it. If we
-;; receive a chunk of text which looks like it might contain the
-;; beginning of a marker, we save it here between calls to the
-;; filter.
-(defvar gud-rubydb-marker-acc "")
-
-(defun gud-rubydb-marker-filter (string)
- (save-match-data
- (setq gud-marker-acc (concat gud-marker-acc string))
- (let ((output ""))
-
- ;; Process all the complete markers in this chunk.
- (while (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n"
- gud-marker-acc)
- (setq
-
- ;; Extract the frame position from the marker.
- gud-last-frame
- (cons (substring gud-marker-acc (match-beginning 1) (match-end 1))
- (string-to-int (substring gud-marker-acc
- (match-beginning 2)
- (match-end 2))))
-
- ;; Append any text before the marker to the output we're going
- ;; to return - we don't include the marker in this text.
- output (concat output
- (substring gud-marker-acc 0 (match-beginning 0)))
-
- ;; Set the accumulator to the remaining text.
- gud-marker-acc (substring gud-marker-acc (match-end 0))))
-
- ;; Does the remaining text look like it might end with the
- ;; beginning of another marker? If it does, then keep it in
- ;; gud-marker-acc until we receive the rest of it. Since we
- ;; know the full marker regexp above failed, it's pretty simple to
- ;; test for marker starts.
- (if (string-match "\032.*\\'" gud-marker-acc)
- (progn
- ;; Everything before the potential marker start can be output.
- (setq output (concat output (substring gud-marker-acc
- 0 (match-beginning 0))))
-
- ;; Everything after, we save, to combine with later input.
- (setq gud-marker-acc
- (substring gud-marker-acc (match-beginning 0))))
-
- (setq output (concat output gud-marker-acc)
- gud-marker-acc ""))
-
- output)))
-
-(defun gud-rubydb-find-file (f)
- (find-file-noselect f))
-
-(defvar rubydb-command-name "ruby"
- "File name for executing ruby.")
-
-;;;###autoload
-(defun rubydb (command-line)
- "Run rubydb on program FILE in buffer *gud-FILE*.
-The directory containing FILE becomes the initial working directory
-and source-file directory for your debugger."
- (interactive
- (list (read-from-minibuffer "Run rubydb (like this): "
- (if (consp gud-rubydb-history)
- (car gud-rubydb-history)
- (concat rubydb-command-name " "))
- nil nil
- '(gud-rubydb-history . 1))))
-
- (gud-overload-functions '((gud-massage-args . gud-rubydb-massage-args)
- (gud-marker-filter . gud-rubydb-marker-filter)
- (gud-find-file . gud-rubydb-find-file)
- ))
- (gud-common-init command-line)
-
- (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.")
-; (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line")
- (gud-def gud-step "s" "\C-s" "Step one source line with display.")
- (gud-def gud-next "n" "\C-n" "Step one line (skip functions).")
- (gud-def gud-cont "c" "\C-r" "Continue with display.")
- (gud-def gud-finish "finish" "\C-f" "Finish executing current function.")
- (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).")
- (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
- (gud-def gud-print "p %e" "\C-p" "Evaluate ruby expression at point.")
-
- (setq comint-prompt-regexp "^(rdb:-) ")
- (setq paragraph-start comint-prompt-regexp)
- (run-hooks 'rubydb-mode-hook)
- )
diff --git a/misc/rubydb3x.el b/misc/rubydb3x.el
deleted file mode 100644
index 9d6bc57d5a..0000000000
--- a/misc/rubydb3x.el
+++ /dev/null
@@ -1,115 +0,0 @@
-(require 'gud)
-(provide 'rubydb)
-
-;; ======================================================================
-;; rubydb functions
-
-;;; History of argument lists passed to rubydb.
-(defvar gud-rubydb-history nil)
-
-(if (fboundp 'gud-overload-functions)
- (defun gud-rubydb-massage-args (file args)
- (cons "-r" (cons "debug" (cons file args))))
- (defun gud-rubydb-massage-args (file args)
- (cons "-r" (cons "debug" args))))
-
-;; There's no guarantee that Emacs will hand the filter the entire
-;; marker at once; it could be broken up across several strings. We
-;; might even receive a big chunk with several markers in it. If we
-;; receive a chunk of text which looks like it might contain the
-;; beginning of a marker, we save it here between calls to the
-;; filter.
-(defvar gud-rubydb-marker-acc "")
-(make-variable-buffer-local 'gud-rubydb-marker-acc)
-
-(defun gud-rubydb-marker-filter (string)
- (setq gud-rubydb-marker-acc (concat gud-rubydb-marker-acc string))
- (let ((output ""))
-
- ;; Process all the complete markers in this chunk.
- (while (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n"
- gud-rubydb-marker-acc)
- (setq
-
- ;; Extract the frame position from the marker.
- gud-last-frame
- (cons (substring gud-rubydb-marker-acc (match-beginning 1) (match-end 1))
- (string-to-int (substring gud-rubydb-marker-acc
- (match-beginning 2)
- (match-end 2))))
-
- ;; Append any text before the marker to the output we're going
- ;; to return - we don't include the marker in this text.
- output (concat output
- (substring gud-rubydb-marker-acc 0 (match-beginning 0)))
-
- ;; Set the accumulator to the remaining text.
- gud-rubydb-marker-acc (substring gud-rubydb-marker-acc (match-end 0))))
-
- ;; Does the remaining text look like it might end with the
- ;; beginning of another marker? If it does, then keep it in
- ;; gud-rubydb-marker-acc until we receive the rest of it. Since we
- ;; know the full marker regexp above failed, it's pretty simple to
- ;; test for marker starts.
- (if (string-match "\032.*\\'" gud-rubydb-marker-acc)
- (progn
- ;; Everything before the potential marker start can be output.
- (setq output (concat output (substring gud-rubydb-marker-acc
- 0 (match-beginning 0))))
-
- ;; Everything after, we save, to combine with later input.
- (setq gud-rubydb-marker-acc
- (substring gud-rubydb-marker-acc (match-beginning 0))))
-
- (setq output (concat output gud-rubydb-marker-acc)
- gud-rubydb-marker-acc ""))
-
- output))
-
-(defun gud-rubydb-find-file (f)
- (save-excursion
- (let ((buf (find-file-noselect f)))
- (set-buffer buf)
-;; (gud-make-debug-menu)
- buf)))
-
-(defvar rubydb-command-name "ruby"
- "File name for executing ruby.")
-
-;;;###autoload
-(defun rubydb (command-line)
- "Run rubydb on program FILE in buffer *gud-FILE*.
-The directory containing FILE becomes the initial working directory
-and source-file directory for your debugger."
- (interactive
- (list (read-from-minibuffer "Run rubydb (like this): "
- (if (consp gud-rubydb-history)
- (car gud-rubydb-history)
- (concat rubydb-command-name " "))
- nil nil
- '(gud-rubydb-history . 1))))
-
- (if (not (fboundp 'gud-overload-functions))
- (gud-common-init command-line 'gud-rubydb-massage-args
- 'gud-rubydb-marker-filter 'gud-rubydb-find-file)
- (gud-overload-functions '((gud-massage-args . gud-rubydb-massage-args)
- (gud-marker-filter . gud-rubydb-marker-filter)
- (gud-find-file . gud-rubydb-find-file)))
- (gud-common-init command-line rubydb-command-name))
-
- (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.")
-; (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line")
- (gud-def gud-step "s" "\C-s" "Step one source line with display.")
- (gud-def gud-next "n" "\C-n" "Step one line (skip functions).")
- (gud-def gud-cont "c" "\C-r" "Continue with display.")
- (gud-def gud-finish "finish" "\C-f" "Finish executing current function.")
- (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).")
- (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
- (gud-def gud-print "p %e" "\C-p" "Evaluate ruby expression at point.")
-
- (setq comint-prompt-regexp "^(rdb:-) ")
- (if (boundp 'comint-last-output-start)
- (set-marker comint-last-output-start (point)))
- (set (make-local-variable 'paragraph-start) comint-prompt-regexp)
- (run-hooks 'rubydb-mode-hook)
- )
diff --git a/misc/test_lldb_cruby.rb b/misc/test_lldb_cruby.rb
index 4d1cc499f5..bd58619ac2 100644
--- a/misc/test_lldb_cruby.rb
+++ b/misc/test_lldb_cruby.rb
@@ -9,7 +9,7 @@ class TestLLDBInit < Test::Unit::TestCase
tf.puts <<eom
target create ./miniruby
command script import -r misc/lldb_cruby.py
-b rb_p
+b rb_inspect
run -e'p #{expr}'
rp obj
eom
@@ -24,8 +24,12 @@ eom
assert_rp 'Object.new', 'T_OBJECT'
end
+ def test_rp_regex
+ assert_rp '/foo/', '[(]Regex'
+ end
+
def test_rp_symbol
- assert_rp ':abcde', /immediate\(\h+\)/
+ assert_rp ':abcde', /T_SYMBOL: \(\h+\)/
end
def test_rp_string
diff --git a/missing/alloca.c b/missing/alloca.c
index 96121f7647..d039dfc2cc 100644
--- a/missing/alloca.c
+++ b/missing/alloca.c
@@ -29,7 +29,7 @@
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
#endif
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#define X3J11 1 /* config.h should contain void if needed */
#ifdef C_ALLOCA
diff --git a/missing/crypt.h b/missing/crypt.h
index 7a78767931..ff135eee93 100644
--- a/missing/crypt.h
+++ b/missing/crypt.h
@@ -1,3 +1,5 @@
+#ifndef CRYPT_H
+#define CRYPT_H 1
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -30,9 +32,6 @@
* SUCH DAMAGE.
*/
-#ifndef CRYPT_H
-#define CRYPT_H 1
-
/* ===== Configuration ==================== */
#ifdef CHAR_BITS
@@ -237,8 +236,6 @@ struct crypt_data {
char cryptresult[1+4+4+11+1]; /* encrypted result */
};
-#define SIZEOF_CRYPT_DATA (KS_SIZE*8+(1+4+4+11+1))
-
char *crypt(const char *key, const char *setting);
void setkey(const char *key);
void encrypt(char *block, int flag);
diff --git a/missing/dtoa.c b/missing/dtoa.c
new file mode 100644
index 0000000000..b7a8302875
--- /dev/null
+++ b/missing/dtoa.c
@@ -0,0 +1,3470 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa. If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ * _control87(PC_53, MCW_PC);
+ * does this with many compilers. Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ * and strtod and dtoa should round accordingly.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ * and Honor_FLT_ROUNDS is not #defined.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "long long"
+ * integer type (of >= 64 bits). On such machines, you can
+ * #define Just_16 to store 16 bits per 32-bit Long when doing
+ * high-precision integer arithmetic. Whether this speeds things
+ * up or slows things down depends on the machine and the number
+ * being converted. If long long is available and the name is
+ * something other than "long long", #define Llong to be the name,
+ * and if "unsigned Llong" does not work as an unsigned version of
+ * Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed.
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ * memory allocations from a private pool of memory when possible.
+ * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
+ * unless #defined to be a different length. This default length
+ * suffices to get rid of MALLOC calls except for unusual cases,
+ * such as decimal-to-binary conversion of a very long string of
+ * digits. The longest string dtoa can return is about 751 bytes
+ * long. For conversions by strtod of strings of 800 digits and
+ * all dtoa conversions in single-threaded executions with 8-byte
+ * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
+ * pointers, PRIVATE_MEM >= 7112 appears adequate.
+ * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
+ * Infinity and NaN (case insensitively). On some systems (e.g.,
+ * some HP systems), it may be necessary to #define NAN_WORD0
+ * appropriately -- to the most significant word of a quiet NaN.
+ * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
+ * strtod also accepts (case insensitively) strings of the form
+ * NaN(x), where x is a string of hexadecimal digits and spaces;
+ * if there is only one string of hexadecimal digits, it is taken
+ * for the 52 fraction bits of the resulting NaN; if there are two
+ * or more strings of hex digits, the first is for the high 20 bits,
+ * the second and subsequent for the low 32 bits, with intervening
+ * white space ignored; but if this results in none of the 52
+ * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0
+ * and NAN_WORD1 are used instead.
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ * multiple threads. In this case, you must provide (or suitably
+ * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
+ * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed
+ * in pow5mult, ensures lazy evaluation of only one copy of high
+ * powers of 5; omitting this lock would introduce a small
+ * probability of wasting memory, but would otherwise be harmless.)
+ * You must also invoke freedtoa(s) to free the value s returned by
+ * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
+ * avoids underflows on inputs whose result does not underflow.
+ * If you #define NO_IEEE_Scale on a machine that uses IEEE-format
+ * floating-point numbers and flushes underflows to zero rather
+ * than implementing gradual underflow, then you must also #define
+ * Sudden_Underflow.
+ * #define YES_ALIAS to permit aliasing certain double values with
+ * arrays of ULongs. This leads to slightly better code with
+ * some compilers and was always used prior to 19990916, but it
+ * is not strictly legal and can cause trouble with aggressively
+ * optimizing compilers (e.g., gcc 2.95.1 under -O2).
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ * #define SET_INEXACT if IEEE arithmetic is being used and extra
+ * computation should be done to set the inexact flag when the
+ * result is inexact and avoid setting inexact when the result
+ * is exact. In this case, dtoa.c must be compiled in
+ * an environment, perhaps provided by #include "dtoa.c" in a
+ * suitable wrapper, that defines two functions,
+ * int get_inexact(void);
+ * void clear_inexact(void);
+ * such that get_inexact() returns a nonzero value if the
+ * inexact bit is already set, and clear_inexact() sets the
+ * inexact bit to 0. When SET_INEXACT is #defined, strtod
+ * also does extra computations to set the underflow and overflow
+ * flags when appropriate (i.e., when the result is tiny and
+ * inexact or when it is a numeric value rounded to +-infinity).
+ * #define NO_ERRNO if strtod should not assign errno = ERANGE when
+ * the result overflows to +-Infinity or underflows to 0.
+ */
+
+#ifdef WORDS_BIGENDIAN
+#define IEEE_BIG_ENDIAN
+#else
+#define IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __vax__
+#define VAX
+#undef IEEE_BIG_ENDIAN
+#undef IEEE_LITTLE_ENDIAN
+#endif
+
+#if defined(__arm__) && !defined(__VFP_FP__)
+#define IEEE_BIG_ENDIAN
+#undef IEEE_LITTLE_ENDIAN
+#endif
+
+#undef Long
+#undef ULong
+
+#include <limits.h>
+
+#if (INT_MAX >> 30) && !(INT_MAX >> 31)
+#define Long int
+#define ULong unsigned int
+#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31)
+#define Long long int
+#define ULong unsigned long int
+#else
+#error No 32bit integer
+#endif
+
+#if HAVE_LONG_LONG
+#define Llong LONG_LONG
+#else
+#define NO_LONG_LONG
+#endif
+
+#ifdef DEBUG
+#include <stdio.h>
+#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);}
+#endif
+
+#ifndef ISDIGIT
+#include <ctype.h>
+#define ISDIGIT(c) isdigit(c)
+#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef USE_LOCALE
+#include <locale.h>
+#endif
+
+#ifdef MALLOC
+extern void *MALLOC(size_t);
+#else
+#define MALLOC xmalloc
+#endif
+#ifdef FREE
+extern void FREE(void*);
+#else
+#define FREE xfree
+#endif
+#ifndef NO_SANITIZE
+#define NO_SANITIZE(x, y) y
+#endif
+
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+#undef IEEE_Arith
+#undef Avoid_Underflow
+#ifdef IEEE_BIG_ENDIAN
+#define IEEE_Arith
+#endif
+#ifdef IEEE_LITTLE_ENDIAN
+#define IEEE_Arith
+#endif
+
+#ifdef Bad_float_h
+
+#ifdef IEEE_Arith
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#endif /*IEEE_Arith*/
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define DBL_MAX 1.7014118346046923e+38
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include <float.h>
+#endif /* Bad_float_h */
+
+#include <math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* satisfy cc-mode */
+#endif
+#endif
+
+#ifndef hexdigit
+static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
+#endif
+
+#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
+#endif
+
+typedef union { double d; ULong L[2]; } U;
+
+#ifdef YES_ALIAS
+typedef double double_u;
+# define dval(x) (x)
+# ifdef IEEE_LITTLE_ENDIAN
+# define word0(x) (((ULong *)&(x))[1])
+# define word1(x) (((ULong *)&(x))[0])
+# else
+# define word0(x) (((ULong *)&(x))[0])
+# define word1(x) (((ULong *)&(x))[1])
+# endif
+#else
+typedef U double_u;
+# ifdef IEEE_LITTLE_ENDIAN
+# define word0(x) ((x).L[1])
+# define word1(x) ((x).L[0])
+# else
+# define word0(x) ((x).L[0])
+# define word1(x) ((x).L[1])
+# endif
+# define dval(x) ((x).d)
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
+#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \
+((unsigned short *)(a))[0] = (unsigned short)(c), (a)++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \
+((unsigned short *)(a))[1] = (unsigned short)(c), (a)++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#ifdef Flush_Denorm /* debugging option */
+#undef Sudden_Underflow
+#endif
+#endif
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#ifdef Honor_FLT_ROUNDS
+#define Rounding rounding
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+#else /* ifndef IEEE_Arith */
+#undef Check_FLT_ROUNDS
+#undef Honor_FLT_ROUNDS
+#undef SET_INEXACT
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#undef Flt_Rounds
+#define Flt_Rounds 0
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#undef Flt_Rounds
+#define Flt_Rounds 1
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) ((a) = rnd_prod((a), (b)))
+#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b)))
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#else
+#define rounded_product(a,b) ((a) *= (b))
+#define rounded_quotient(a,b) ((a) /= (b))
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Pack_32
+#define Pack_32
+#endif
+
+#define FFFFFFFF 0xffffffffUL
+
+#ifdef NO_LONG_LONG
+#undef ULLong
+#ifdef Just_16
+#undef Pack_32
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per Long.
+ */
+#endif
+#else /* long long available */
+#ifndef Llong
+#define Llong long long
+#endif
+#ifndef ULLong
+#define ULLong unsigned Llong
+#endif
+#endif /* NO_LONG_LONG */
+
+#define MULTIPLE_THREADS 1
+
+#ifndef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
+#define FREE_DTOA_LOCK(n) /*nothing*/
+#else
+#define ACQUIRE_DTOA_LOCK(n) /*unused right now*/
+#define FREE_DTOA_LOCK(n) /*unused right now*/
+#endif
+
+#ifndef ATOMIC_PTR_CAS
+#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old))
+#endif
+#ifndef LIKELY
+#define LIKELY(x) (x)
+#endif
+#ifndef UNLIKELY
+#define UNLIKELY(x) (x)
+#endif
+#ifndef ASSUME
+#define ASSUME(x) (void)(x)
+#endif
+
+#define Kmax 15
+
+struct Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+};
+
+typedef struct Bigint Bigint;
+
+static Bigint *freelist[Kmax+1];
+
+#define BLOCKING_BIGINT ((Bigint *)(-1))
+
+static Bigint *
+Balloc(int k)
+{
+ int x;
+ Bigint *rv;
+#ifndef Omit_Private_Memory
+ size_t len;
+#endif
+
+ rv = 0;
+ ACQUIRE_DTOA_LOCK(0);
+ if (k <= Kmax) {
+ rv = freelist[k];
+ while (rv) {
+ Bigint *rvn = rv;
+ rv = ATOMIC_PTR_CAS(freelist[k], rv, BLOCKING_BIGINT);
+ if (LIKELY(rv != BLOCKING_BIGINT && rvn == rv)) {
+ rvn = ATOMIC_PTR_CAS(freelist[k], BLOCKING_BIGINT, rv->next);
+ assert(rvn == BLOCKING_BIGINT);
+ ASSUME(rv);
+ break;
+ }
+ }
+ }
+ if (!rv) {
+ x = 1 << k;
+#ifdef Omit_Private_Memory
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+ /sizeof(double);
+ if (k <= Kmax) {
+ double *pnext = pmem_next;
+ while (pnext - private_mem + len <= PRIVATE_mem) {
+ double *p = pnext;
+ pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len);
+ if (LIKELY(p == pnext)) {
+ rv = (Bigint*)pnext;
+ ASSUME(rv);
+ break;
+ }
+ }
+ }
+ if (!rv)
+ rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ FREE_DTOA_LOCK(0);
+ rv->sign = rv->wds = 0;
+ return rv;
+}
+
+static void
+Bfree(Bigint *v)
+{
+ Bigint *vn;
+ if (v) {
+ if (v->k > Kmax) {
+ FREE(v);
+ return;
+ }
+ ACQUIRE_DTOA_LOCK(0);
+ do {
+ do {
+ vn = ATOMIC_PTR_CAS(freelist[v->k], 0, 0);
+ } while (UNLIKELY(vn == BLOCKING_BIGINT));
+ v->next = vn;
+ } while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn));
+ FREE_DTOA_LOCK(0);
+ }
+}
+
+#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
+(y)->wds*sizeof(Long) + 2*sizeof(int))
+
+static Bigint *
+multadd(Bigint *b, int m, int a) /* multiply by m and add a */
+{
+ int i, wds;
+ ULong *x;
+#ifdef ULLong
+ ULLong carry, y;
+#else
+ ULong carry, y;
+#ifdef Pack_32
+ ULong xi, z;
+#endif
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ carry = a;
+ do {
+#ifdef ULLong
+ y = *x * (ULLong)m + carry;
+ carry = y >> 32;
+ *x++ = (ULong)(y & FFFFFFFF);
+#else
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + carry;
+ z = (xi >> 16) * m + (y >> 16);
+ carry = z >> 16;
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + carry;
+ carry = y >> 16;
+ *x++ = y & 0xffff;
+#endif
+#endif
+ } while (++i < wds);
+ if (carry) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = (ULong)carry;
+ b->wds = wds;
+ }
+ return b;
+}
+
+static Bigint *
+s2b(const char *s, int nd0, int nd, ULong y9)
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for (k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do {
+ b = multadd(b, 10, *s++ - '0');
+ } while (++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for (; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0');
+ return b;
+}
+
+static int
+hi0bits(register ULong x)
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+}
+
+static int
+lo0bits(ULong *y)
+{
+ register int k;
+ register ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x)
+ return 32;
+ }
+ *y = x;
+ return k;
+}
+
+static Bigint *
+i2b(int i)
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+}
+
+static Bigint *
+mult(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ ULong y;
+#ifdef ULLong
+ ULLong carry, z;
+#else
+ ULong carry, z;
+#ifdef Pack_32
+ ULong z2;
+#endif
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ for (x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef ULLong
+ for (; xb < xbe; xc0++) {
+ if ((y = *xb++) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * (ULLong)y + *xc + carry;
+ carry = z >> 32;
+ *xc++ = (ULong)(z & FFFFFFFF);
+ } while (x < xae);
+ *xc = (ULong)carry;
+ }
+ }
+#else
+#ifdef Pack_32
+ for (; xb < xbe; xb++, xc0++) {
+ if ((y = *xb & 0xffff) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ } while (x < xae);
+ *xc = (ULong)carry;
+ }
+ if ((y = *xb >> 16) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ } while (x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for (; xb < xbe; xc0++) {
+ if (y = *xb++) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ } while (x < xae);
+ *xc = (ULong)carry;
+ }
+ }
+#endif
+#endif
+ for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+}
+
+static Bigint *p5s;
+
+static Bigint *
+pow5mult(Bigint *b, int k)
+{
+ Bigint *b1, *p5, *p51;
+ Bigint *p5tmp;
+ int i;
+ static const int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3) != 0)
+ b = multadd(b, p05[i-1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = p5s)) {
+ /* first time */
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p5 = p5s)) {
+ p5 = i2b(625);
+ p5->next = 0;
+ p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5);
+ if (UNLIKELY(p5tmp)) {
+ Bfree(p5);
+ p5 = p5tmp;
+ }
+ }
+ FREE_DTOA_LOCK(1);
+ }
+ for (;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->next)) {
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p51 = p5->next)) {
+ p51 = mult(p5,p5);
+ p51->next = 0;
+ p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51);
+ if (UNLIKELY(p5tmp)) {
+ Bfree(p51);
+ p51 = p5tmp;
+ }
+ }
+ FREE_DTOA_LOCK(1);
+ }
+ p5 = p51;
+ }
+ return b;
+}
+
+static Bigint *
+lshift(Bigint *b, int k)
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for (i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ x1 = b1->x;
+ for (i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ } while (x < xe);
+ if ((*x1 = z) != 0)
+ ++n1;
+ }
+#else
+ if (k &= 0xf) {
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ } while (x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else
+ do {
+ *x1++ = *x++;
+ } while (x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+}
+
+static int
+cmp(Bigint *a, Bigint *b)
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for (;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+}
+
+NO_SANITIZE("unsigned-integer-overflow", static Bigint * diff(Bigint *a, Bigint *b));
+static Bigint *
+diff(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int i, wa, wb;
+ ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+ ULLong borrow, y;
+#else
+ ULong borrow, y;
+#ifdef Pack_32
+ ULong z;
+#endif
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef ULLong
+ do {
+ y = (ULLong)*xa++ - *xb++ - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *xc++ = (ULong)(y & FFFFFFFF);
+ } while (xb < xbe);
+ while (xa < xae) {
+ y = *xa++ - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *xc++ = (ULong)(y & FFFFFFFF);
+ }
+#else
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ } while (xb < xbe);
+ while (xa < xae) {
+ y = (*xa & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ } while (xb < xbe);
+ while (xa < xae) {
+ y = *xa++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+#endif
+#endif
+ while (!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+}
+
+static double
+ulp(double x_)
+{
+ register Long L;
+ double_u x, a;
+ dval(x) = x_;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0(a) = L;
+ word1(a) = 0;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(a) = 0x80000 >> L;
+ word1(a) = 0;
+ }
+ else {
+ word0(a) = 0;
+ L -= Exp_shift;
+ word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+ }
+ }
+#endif
+#endif
+ return dval(a);
+}
+
+static double
+b2d(Bigint *a, int *e)
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ double_u d;
+#ifdef VAX
+ ULong d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ d0 = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+ d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = Exp_1 | y << k | z >> (32 - k);
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k | y >> (32 - k);
+ }
+ else {
+ d0 = Exp_1 | y;
+ d1 = z;
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ret_d:
+#ifdef VAX
+ word0(d) = d0 >> 16 | d0 << 16;
+ word1(d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return dval(d);
+}
+
+static Bigint *
+d2b(double d_, int *e, int *bits)
+{
+ double_u d;
+ Bigint *b;
+ int de, k;
+ ULong *x, y, z;
+#ifndef Sudden_Underflow
+ int i;
+#endif
+#ifdef VAX
+ ULong d0, d1;
+#endif
+ dval(d) = d_;
+#ifdef VAX
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ x = b->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ((de = (int)(d0 >> Exp_shift)) != 0)
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ((y = d1) != 0) {
+ if ((k = lo0bits(&y)) != 0) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = 1;
+ k += 32;
+ }
+#else
+ if (y = d1) {
+ if (k = lo0bits(&y))
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while (!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+}
+#undef d0
+#undef d1
+
+static double
+ratio(Bigint *a, Bigint *b)
+{
+ double_u da, db;
+ int k, ka, kb;
+
+ dval(da) = b2d(a, &ka);
+ dval(db) = b2d(b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32*(a->wds - b->wds);
+#else
+ k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+ if (k > 0) {
+ word0(da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(da) *= 1 << k;
+ }
+ else {
+ k = -k;
+ word0(db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(db) *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(db) += k*Exp_msk1;
+ }
+#endif
+ return dval(da) / dval(db);
+}
+
+static const double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+};
+
+static const double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+#ifdef Avoid_Underflow
+ 9007199254740992.*9007199254740992.e-256
+ /* = 2^106 * 1e-53 */
+#else
+ 1e-256
+#endif
+};
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static const double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#undef INFNAN_CHECK
+#endif
+
+#ifdef INFNAN_CHECK
+
+#ifndef NAN_WORD0
+#define NAN_WORD0 0x7ff80000
+#endif
+
+#ifndef NAN_WORD1
+#define NAN_WORD1 0
+#endif
+
+static int
+match(const char **sp, char *t)
+{
+ int c, d;
+ const char *s = *sp;
+
+ while (d = *t++) {
+ if ((c = *++s) >= 'A' && c <= 'Z')
+ c += 'a' - 'A';
+ if (c != d)
+ return 0;
+ }
+ *sp = s + 1;
+ return 1;
+}
+
+#ifndef No_Hex_NaN
+static void
+hexnan(double *rvp, const char **sp)
+{
+ ULong c, x[2];
+ const char *s;
+ int havedig, udx0, xshift;
+
+ x[0] = x[1] = 0;
+ havedig = xshift = 0;
+ udx0 = 1;
+ s = *sp;
+ while (c = *(const unsigned char*)++s) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'f')
+ c += 10 - 'a';
+ else if (c >= 'A' && c <= 'F')
+ c += 10 - 'A';
+ else if (c <= ' ') {
+ if (udx0 && havedig) {
+ udx0 = 0;
+ xshift = 1;
+ }
+ continue;
+ }
+ else if (/*(*/ c == ')' && havedig) {
+ *sp = s + 1;
+ break;
+ }
+ else
+ return; /* invalid form: don't change *sp */
+ havedig = 1;
+ if (xshift) {
+ xshift = 0;
+ x[0] = x[1];
+ x[1] = 0;
+ }
+ if (udx0)
+ x[0] = (x[0] << 4) | (x[1] >> 28);
+ x[1] = (x[1] << 4) | c;
+ }
+ if ((x[0] &= 0xfffff) || x[1]) {
+ word0(*rvp) = Exp_mask | x[0];
+ word1(*rvp) = x[1];
+ }
+}
+#endif /*No_Hex_NaN*/
+#endif /* INFNAN_CHECK */
+
+NO_SANITIZE("unsigned-integer-overflow", double strtod(const char *s00, char **se));
+double
+strtod(const char *s00, char **se)
+{
+#ifdef Avoid_Underflow
+ int scale;
+#endif
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ const char *s, *s0, *s1;
+ double aadj, adj;
+ double_u aadj1, rv, rv0;
+ Long L;
+ ULong y, z;
+ Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+#ifdef SET_INEXACT
+ int inexact, oldinexact;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ int rounding;
+#endif
+#ifdef USE_LOCALE
+ const char *s2;
+#endif
+
+ errno = 0;
+ sign = nz0 = nz = 0;
+ dval(rv) = 0.;
+ for (s = s00;;s++)
+ switch (*s) {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ goto ret0;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+break2:
+ if (*s == '0') {
+ if (s[1] == 'x' || s[1] == 'X') {
+ s0 = ++s;
+ adj = 0;
+ aadj = 1.0;
+ nd0 = -4;
+
+ if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
+ if (*s == '0') {
+ while (*++s == '0');
+ if (!*s) goto ret;
+ s1 = strchr(hexdigit, *s);
+ }
+ if (s1 != NULL) {
+ do {
+ adj += aadj * ((s1 - hexdigit) & 15);
+ nd0 += 4;
+ aadj /= 16;
+ } while (*++s && (s1 = strchr(hexdigit, *s)));
+ }
+
+ if (*s == '.') {
+ dsign = 1;
+ if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
+ if (nd0 < 0) {
+ while (*s == '0') {
+ s++;
+ nd0 -= 4;
+ }
+ }
+ for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
+ adj += aadj * ((s1 - hexdigit) & 15);
+ if ((aadj /= 16) == 0.0) {
+ while (*++s && strchr(hexdigit, *s));
+ break;
+ }
+ }
+ }
+ else {
+ dsign = 0;
+ }
+
+ if (*s == 'P' || *s == 'p') {
+ dsign = 0x2C - *++s; /* +: 2B, -: 2D */
+ if (abs(dsign) == 1) s++;
+ else dsign = 1;
+
+ nd = 0;
+ c = *s;
+ if (c < '0' || '9' < c) goto ret0;
+ do {
+ nd *= 10;
+ nd += c;
+ nd -= '0';
+ c = *++s;
+ /* Float("0x0."+("0"*267)+"1fp2095") */
+ if (nd + dsign * nd0 > 2095) {
+ while ('0' <= c && c <= '9') c = *++s;
+ break;
+ }
+ } while ('0' <= c && c <= '9');
+ nd0 += nd * dsign;
+ }
+ else {
+ if (dsign) goto ret0;
+ }
+ dval(rv) = ldexp(adj, nd0);
+ goto ret;
+ }
+ nz0 = 1;
+ while (*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < DBL_DIG + 2)
+ z = 10*z + c - '0';
+ nd0 = nd;
+#ifdef USE_LOCALE
+ s1 = localeconv()->decimal_point;
+ if (c == *s1) {
+ c = '.';
+ if (*++s1) {
+ s2 = s;
+ for (;;) {
+ if (*++s2 != *s1) {
+ c = 0;
+ break;
+ }
+ if (!*++s1) {
+ s = s2;
+ break;
+ }
+ }
+ }
+ }
+#endif
+ if (c == '.') {
+ if (!ISDIGIT(s[1]))
+ goto dig_done;
+ c = *++s;
+ if (!nd) {
+ for (; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for (; c >= '0' && c <= '9'; c = *++s) {
+have_dig:
+ nz++;
+ if (nd > DBL_DIG * 4) {
+ continue;
+ }
+ if (c -= '0') {
+ nf += nz;
+ for (i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 2)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 2)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ goto ret0;
+ }
+ s00 = s;
+ esign = 0;
+ switch (c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while (c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while ((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+ /* Check for Nan and Infinity */
+ switch (c) {
+ case 'i':
+ case 'I':
+ if (match(&s,"nf")) {
+ --s;
+ if (!match(&s,"inity"))
+ ++s;
+ word0(rv) = 0x7ff00000;
+ word1(rv) = 0;
+ goto ret;
+ }
+ break;
+ case 'n':
+ case 'N':
+ if (match(&s, "an")) {
+ word0(rv) = NAN_WORD0;
+ word1(rv) = NAN_WORD1;
+#ifndef No_Hex_NaN
+ if (*s == '(') /*)*/
+ hexnan(&rv, &s);
+#endif
+ goto ret;
+ }
+ }
+#endif /* INFNAN_CHECK */
+ret0:
+ s = s00;
+ sign = 0;
+ }
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2;
+ dval(rv) = y;
+ if (k > 9) {
+#ifdef SET_INEXACT
+ if (k > DBL_DIG)
+ oldinexact = get_inexact();
+#endif
+ dval(rv) = tens[k - 9] * dval(rv) + z;
+ }
+ bd0 = bb = bd = bs = delta = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+#ifndef Honor_FLT_ROUNDS
+ && Flt_Rounds == 1
+#endif
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ dval(rv) = -dval(rv);
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ dval(rv) = -dval(rv);
+ sign = 0;
+ }
+#endif
+ e -= i;
+ dval(rv) *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+vax_ovfl_check:
+ word0(rv) -= P*Exp_msk1;
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ word0(rv) += P*Exp_msk1;
+#else
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ dval(rv) = -dval(rv);
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_quotient(dval(rv), tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+#ifdef IEEE_Arith
+#ifdef SET_INEXACT
+ inexact = 1;
+ if (k <= DBL_DIG)
+ oldinexact = get_inexact();
+#endif
+#ifdef Avoid_Underflow
+ scale = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if ((rounding = Flt_Rounds) >= 2) {
+ if (sign)
+ rounding = rounding == 2 ? 0 : 2;
+ else
+ if (rounding != 2)
+ rounding = 0;
+ }
+#endif
+#endif /*IEEE_Arith*/
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15) != 0)
+ dval(rv) *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ovfl:
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+#ifdef Honor_FLT_ROUNDS
+ switch (rounding) {
+ case 0: /* toward 0 */
+ case 3: /* toward -infinity */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ break;
+ default:
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+ }
+#else /*Honor_FLT_ROUNDS*/
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+#endif /*Honor_FLT_ROUNDS*/
+#ifdef SET_INEXACT
+ /* set overflow bit */
+ dval(rv0) = 1e300;
+ dval(rv0) *= dval(rv0);
+#endif
+#else /*IEEE_Arith*/
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+#endif /*IEEE_Arith*/
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ e1 >>= 4;
+ for (j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(rv) -= P*Exp_msk1;
+ dval(rv) *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ((i = e1 & 15) != 0)
+ dval(rv) /= tens[i];
+ if (e1 >>= 4) {
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+#ifdef Avoid_Underflow
+ if (e1 & Scale_Bit)
+ scale = 2*P;
+ for (j = 0; e1 > 0; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
+ >> Exp_shift)) > 0) {
+ /* scaled rv is denormal; zap j low bits */
+ if (j >= 32) {
+ word1(rv) = 0;
+ if (j >= 53)
+ word0(rv) = (P+2)*Exp_msk1;
+ else
+ word0(rv) &= 0xffffffff << (j-32);
+ }
+ else
+ word1(rv) &= 0xffffffff << j;
+ }
+#else
+ for (j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ /* The last multiplication could underflow. */
+ dval(rv0) = dval(rv);
+ dval(rv) *= tinytens[j];
+ if (!dval(rv)) {
+ dval(rv) = 2.*dval(rv0);
+ dval(rv) *= tinytens[j];
+#endif
+ if (!dval(rv)) {
+undfl:
+ dval(rv) = 0.;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+#ifndef Avoid_Underflow
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+#endif
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for (;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Honor_FLT_ROUNDS
+ if (rounding != 1)
+ bs2++;
+#endif
+#ifdef Avoid_Underflow
+ j = bbe - scale;
+ i = j + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j += P - Emin;
+ else
+ j = P + 1 - bbbits;
+#else /*Avoid_Underflow*/
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else /*Sudden_Underflow*/
+ j = bbe;
+ i = j + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j += P - Emin;
+ else
+ j = P + 1 - bbbits;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ bb2 += j;
+ bd2 += j;
+#ifdef Avoid_Underflow
+ bd2 += scale;
+#endif
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+#ifdef Honor_FLT_ROUNDS
+ if (rounding != 1) {
+ if (i < 0) {
+ /* Error is less than an ulp */
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact */
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ if (rounding) {
+ if (dsign) {
+ adj = 1.;
+ goto apply_adj;
+ }
+ }
+ else if (!dsign) {
+ adj = -1.;
+ if (!word1(rv)
+ && !(word0(rv) & Frac_mask)) {
+ y = word0(rv) & Exp_mask;
+#ifdef Avoid_Underflow
+ if (!scale || y > 2*P*Exp_msk1)
+#else
+ if (y)
+#endif
+ {
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) <= 0)
+ adj = -0.5;
+ }
+ }
+apply_adj:
+#ifdef Avoid_Underflow
+ if (scale && (y = word0(rv) & Exp_mask)
+ <= 2*P*Exp_msk1)
+ word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <=
+ P*Exp_msk1) {
+ word0(rv) += P*Exp_msk1;
+ dval(rv) += adj*ulp(dval(rv));
+ word0(rv) -= P*Exp_msk1;
+ }
+ else
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ dval(rv) += adj*ulp(dval(rv));
+ }
+ break;
+ }
+ adj = ratio(delta, bs);
+ if (adj < 1.)
+ adj = 1.;
+ if (adj <= 0x7ffffffe) {
+ /* adj = rounding ? ceil(adj) : floor(adj); */
+ y = adj;
+ if (y != adj) {
+ if (!((rounding>>1) ^ dsign))
+ y++;
+ adj = y;
+ }
+ }
+#ifdef Avoid_Underflow
+ if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+ word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ word0(rv) += P*Exp_msk1;
+ adj *= ulp(dval(rv));
+ if (dsign)
+ dval(rv) += adj;
+ else
+ dval(rv) -= adj;
+ word0(rv) -= P*Exp_msk1;
+ goto cont;
+ }
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ adj *= ulp(dval(rv));
+ if (dsign)
+ dval(rv) += adj;
+ else
+ dval(rv) -= adj;
+ goto cont;
+ }
+#endif /*Honor_FLT_ROUNDS*/
+
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask
+#ifdef IEEE_Arith
+#ifdef Avoid_Underflow
+ || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+#else
+ || (word0(rv) & Exp_mask) <= Exp_msk1
+#endif
+#endif
+ ) {
+#ifdef SET_INEXACT
+ if (!delta->x[0] && delta->wds <= 1)
+ inexact = 0;
+#endif
+ break;
+ }
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact result */
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == (
+#ifdef Avoid_Underflow
+ (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+ ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+#endif
+ 0xffffffff)) {
+ /*boundary case -- increment exponent*/
+ word0(rv) = (word0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(rv) = 0;
+#ifdef Avoid_Underflow
+ dsign = 0;
+#endif
+ break;
+ }
+ }
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow /*{{*/
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+#ifdef Avoid_Underflow
+ if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
+#else
+ if (L <= Exp_msk1)
+#endif /*Avoid_Underflow*/
+#endif /*IBM*/
+ goto undfl;
+ L -= Exp_msk1;
+#else /*Sudden_Underflow}{*/
+#ifdef Avoid_Underflow
+ if (scale) {
+ L = word0(rv) & Exp_mask;
+ if (L <= (2*P+1)*Exp_msk1) {
+ if (L > (P+2)*Exp_msk1)
+ /* round even ==> */
+ /* accept rv */
+ break;
+ /* rv = smallest denormal */
+ goto undfl;
+ }
+ }
+#endif /*Avoid_Underflow*/
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif /*Sudden_Underflow}}*/
+ word0(rv) = L | Bndry_mask1;
+ word1(rv) = 0xffffffff;
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ dval(rv) += ulp(dval(rv));
+#ifndef ROUND_BIASED
+ else {
+ dval(rv) -= ulp(dval(rv));
+#ifndef Sudden_Underflow
+ if (!dval(rv))
+ goto undfl;
+#endif
+ }
+#ifdef Avoid_Underflow
+ dsign = 1 - dsign;
+#endif
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = dval(aadj1) = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ dval(aadj1) = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ dval(aadj1) = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ dval(aadj1) = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch (Rounding) {
+ case 2: /* towards +infinity */
+ dval(aadj1) -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ dval(aadj1) += 0.5;
+ }
+#else
+ if (Flt_Rounds == 0)
+ dval(aadj1) += 0.5;
+#endif /*Check_FLT_ROUNDS*/
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ dval(rv0) = dval(rv);
+ word0(rv) -= P*Exp_msk1;
+ adj = dval(aadj1) * ulp(dval(rv));
+ dval(rv) += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ goto cont;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ else {
+#ifdef Avoid_Underflow
+ if (scale && y <= 2*P*Exp_msk1) {
+ if (aadj <= 0x7fffffff) {
+ if ((z = (int)aadj) <= 0)
+ z = 1;
+ aadj = z;
+ dval(aadj1) = dsign ? aadj : -aadj;
+ }
+ word0(aadj1) += (2*P+1)*Exp_msk1 - y;
+ }
+ adj = dval(aadj1) * ulp(dval(rv));
+ dval(rv) += adj;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ dval(rv0) = dval(rv);
+ word0(rv) += P*Exp_msk1;
+ adj = dval(aadj1) * ulp(dval(rv));
+ dval(rv) += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1)
+ goto undfl;
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ goto cont;
+ }
+ else
+ word0(rv) -= P*Exp_msk1;
+ }
+ else {
+ adj = dval(aadj1) * ulp(dval(rv));
+ dval(rv) += adj;
+ }
+#else /*Sudden_Underflow*/
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
+ dval(aadj1) = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ dval(aadj1) = -dval(aadj1);
+ }
+ adj = dval(aadj1) * ulp(dval(rv));
+ dval(rv) += adj;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ }
+ z = word0(rv) & Exp_mask;
+#ifndef SET_INEXACT
+#ifdef Avoid_Underflow
+ if (!scale)
+#endif
+ if (y == z) {
+ /* Can we stop now? */
+ L = (Long)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+#endif
+cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+#ifdef SET_INEXACT
+ if (inexact) {
+ if (!oldinexact) {
+ word0(rv0) = Exp_1 + (70 << Exp_shift);
+ word1(rv0) = 0;
+ dval(rv0) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+#ifdef Avoid_Underflow
+ if (scale) {
+ word0(rv0) = Exp_1 - 2*P*Exp_msk1;
+ word1(rv0) = 0;
+ dval(rv) *= dval(rv0);
+#ifndef NO_ERRNO
+ /* try to avoid the bug of testing an 8087 register value */
+ if (word0(rv) == 0 && word1(rv) == 0)
+ errno = ERANGE;
+#endif
+ }
+#endif /* Avoid_Underflow */
+#ifdef SET_INEXACT
+ if (inexact && !(word0(rv) & Exp_mask)) {
+ /* set underflow bit */
+ dval(rv0) = 1e-300;
+ dval(rv0) *= dval(rv0);
+ }
+#endif
+retfree:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -dval(rv) : dval(rv);
+}
+
+NO_SANITIZE("unsigned-integer-overflow", static int quorem(Bigint *b, Bigint *S));
+static int
+quorem(Bigint *b, Bigint *S)
+{
+ int n;
+ ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+ ULLong borrow, carry, y, ys;
+#else
+ ULong borrow, carry, y, ys;
+#ifdef Pack_32
+ ULong si, z, zs;
+#endif
+#endif
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef ULLong
+ ys = *sx++ * (ULLong)q + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *bx++ = (ULong)(y & FFFFFFFF);
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ } while (sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef ULLong
+ ys = *sx++ + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (ULong)1;
+ *bx++ = (ULong)(y & FFFFFFFF);
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ } while (sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+}
+
+#ifndef MULTIPLE_THREADS
+static char *dtoa_result;
+#endif
+
+#ifndef MULTIPLE_THREADS
+static char *
+rv_alloc(int i)
+{
+ return dtoa_result = MALLOC(i);
+}
+#else
+#define rv_alloc(i) MALLOC(i)
+#endif
+
+static char *
+nrv_alloc(const char *s, char **rve, size_t n)
+{
+ char *rv, *t;
+
+ t = rv = rv_alloc(n);
+ while ((*t = *s++) != 0) t++;
+ if (rve)
+ *rve = t;
+ return rv;
+}
+
+#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1)
+
+#ifndef MULTIPLE_THREADS
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined. It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+static void
+freedtoa(char *s)
+{
+ FREE(s);
+}
+#endif
+
+static const char INFSTR[] = "Infinity";
+static const char NANSTR[] = "NaN";
+static const char ZEROSTR[] = "0";
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+char *
+dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4,5 ==> similar to 2 and 3, respectively, but (in
+ round-nearest mode) with the tests of mode 0 to
+ possibly return a shorter string that rounds to d.
+ With IEEE arithmetic and compilation with
+ -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+ as modes 2 and 3 when FLT_ROUNDS != 1.
+ 6-9 ==> Debugging modes similar to mode - 4: don't try
+ fast floating-point estimate (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ spec_case, try_quick, half = 0;
+ Long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ ULong x;
+#endif
+ Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S;
+ double ds;
+ double_u d, d2, eps;
+ char *s, *s0;
+#ifdef Honor_FLT_ROUNDS
+ int rounding;
+#endif
+#ifdef SET_INEXACT
+ int inexact, oldinexact;
+#endif
+
+ dval(d) = d_;
+
+#ifndef MULTIPLE_THREADS
+ if (dtoa_result) {
+ freedtoa(dtoa_result);
+ dtoa_result = 0;
+ }
+#endif
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+#ifdef IEEE_Arith
+ if (!word1(d) && !(word0(d) & 0xfffff))
+ return rv_strdup(INFSTR, rve);
+#endif
+ return rv_strdup(NANSTR, rve);
+ }
+#endif
+#ifdef IBM
+ dval(d) += 0; /* normalize */
+#endif
+ if (!dval(d)) {
+ *decpt = 1;
+ return rv_strdup(ZEROSTR, rve);
+ }
+
+#ifdef SET_INEXACT
+ try_quick = oldinexact = get_inexact();
+ inexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if ((rounding = Flt_Rounds) >= 2) {
+ if (*sign)
+ rounding = rounding == 2 ? 0 : 2;
+ else
+ if (rounding != 2)
+ rounding = 0;
+ }
+#endif
+
+ b = d2b(dval(d), &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
+#endif
+ dval(d2) = dval(d);
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= Exp_11;
+#ifdef IBM
+ if (j = 11 - hi0bits(word0(d2) & Frac_mask))
+ dval(d2) /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
+ : word1(d) << (32 - i);
+ dval(d2) = x;
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (dval(d) < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+
+#ifndef SET_INEXACT
+#ifdef Check_FLT_ROUNDS
+ try_quick = Rounding == 1;
+#else
+ try_quick = 1;
+#endif
+#endif /*SET_INEXACT*/
+
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ ilim = ilim1 = -1;
+ switch (mode) {
+ case 0:
+ case 1:
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ s = s0 = rv_alloc(i+1);
+
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1 && rounding != 1)
+ leftright = 0;
+#endif
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ dval(d2) = dval(d);
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(d) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for (; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ dval(d) /= ds;
+ }
+ else if ((j1 = -k) != 0) {
+ dval(d) *= tens[j1 & 0xf];
+ for (j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ dval(d) *= bigtens[i];
+ }
+ }
+ if (k_check && dval(d) < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ dval(d) *= 10.;
+ ieps++;
+ }
+ dval(eps) = ieps*dval(d) + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ dval(d) -= 5.;
+ if (dval(d) > dval(eps))
+ goto one_digit;
+ if (dval(d) < -dval(eps))
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(eps) = 0.5/tens[ilim-1] - dval(eps);
+ for (i = 0;;) {
+ L = (int)dval(d);
+ dval(d) -= L;
+ *s++ = '0' + (int)L;
+ if (dval(d) < dval(eps))
+ goto ret1;
+ if (1. - dval(d) < dval(eps))
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ dval(eps) *= 10.;
+ dval(d) *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ dval(eps) *= tens[ilim-1];
+ for (i = 1;; i++, dval(d) *= 10.) {
+ L = (Long)(dval(d));
+ if (!(dval(d) -= L))
+ ilim = i;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (dval(d) > 0.5 + dval(eps))
+ goto bump_up;
+ else if (dval(d) < 0.5 - dval(eps)) {
+ while (*--s == '0') ;
+ s++;
+ goto ret1;
+ }
+ half = 1;
+ if ((*(s-1) - '0') & 1) {
+ goto bump_up;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+fast_failed:
+ s = s0;
+ dval(d) = dval(d2);
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || dval(d) <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for (i = 1;; i++, dval(d) *= 10.) {
+ L = (Long)(dval(d) / ds);
+ dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (dval(d) < 0) {
+ L--;
+ dval(d) += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (!dval(d)) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch (rounding) {
+ case 0: goto ret1;
+ case 2: goto bump_up;
+ }
+#endif
+ dval(d) += dval(d);
+ if (dval(d) > ds || (dval(d) == ds && (L & 1))) {
+bump_up:
+ while (*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ if (leftright) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if ((j = b5 - m5) != 0)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if ((mode < 2 || leftright)
+#ifdef Honor_FLT_ROUNDS
+ && rounding == 1
+#endif
+ ) {
+ if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & (Exp_mask & ~Exp_msk1)
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
+ i = 32 - i;
+#else
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && (mode == 3 || mode == 5)) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ }
+
+ for (i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && mode != 1 && !(word1(d) & 1)
+#ifdef Honor_FLT_ROUNDS
+ && rounding >= 1
+#endif
+ ) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+#ifdef SET_INEXACT
+ else if (!b->x[0] && b->wds <= 1)
+ inexact = 0;
+#endif
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && mode != 1
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1)
+#endif
+ )) {
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto accept_dig;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch (rounding) {
+ case 0: goto accept_dig;
+ case 2: goto keep_dig;
+ }
+#endif /*Honor_FLT_ROUNDS*/
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9')
+ goto round_9_up;
+ }
+accept_dig:
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+#ifdef Honor_FLT_ROUNDS
+ if (!rounding)
+ goto accept_dig;
+#endif
+ if (dig == '9') { /* possible if i == 1 */
+round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+#ifdef Honor_FLT_ROUNDS
+keep_dig:
+#endif
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for (i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto ret;
+ }
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+#ifdef Honor_FLT_ROUNDS
+ switch (rounding) {
+ case 0: goto trimzeros;
+ case 2: goto roundoff;
+ }
+#endif
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && (dig & 1))) {
+ roundoff:
+ while (*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ if (!half || (*s - '0') & 1)
+ ++*s;
+ }
+ else {
+ while (*--s == '0') ;
+ }
+ s++;
+ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ret1:
+#ifdef SET_INEXACT
+ if (inexact) {
+ if (!oldinexact) {
+ word0(d) = Exp_1 + (70 << Exp_shift);
+ word1(d) = 0;
+ dval(d) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+}
+
+/*-
+ * Copyright (c) 2004-2008 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define DBL_MANH_SIZE 20
+#define DBL_MANL_SIZE 32
+#define DBL_ADJ (DBL_MAX_EXP - 2)
+#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1)
+#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1)
+#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift)))
+#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask))
+#define dmanl_get(u) ((uint32_t)word1(u))
+
+
+/*
+ * This procedure converts a double-precision number in IEEE format
+ * into a string of hexadecimal digits and an exponent of 2. Its
+ * behavior is bug-for-bug compatible with dtoa() in mode 2, with the
+ * following exceptions:
+ *
+ * - An ndigits < 0 causes it to use as many digits as necessary to
+ * represent the number exactly.
+ * - The additional xdigs argument should point to either the string
+ * "0123456789ABCDEF" or the string "0123456789abcdef", depending on
+ * which case is desired.
+ * - This routine does not repeat dtoa's mistake of setting decpt
+ * to 9999 in the case of an infinity or NaN. INT_MAX is used
+ * for this purpose instead.
+ *
+ * Note that the C99 standard does not specify what the leading digit
+ * should be for non-zero numbers. For instance, 0x1.3p3 is the same
+ * as 0x2.6p2 is the same as 0x4.cp3. This implementation always makes
+ * the leading digit a 1. This ensures that the exponent printed is the
+ * actual base-2 exponent, i.e., ilogb(d).
+ *
+ * Inputs: d, xdigs, ndigits
+ * Outputs: decpt, sign, rve
+ */
+char *
+hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve)
+{
+ U u;
+ char *s, *s0;
+ int bufsize;
+ uint32_t manh, manl;
+
+ u.d = d;
+ if (word0(u) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(u) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+ if (isinf(d)) { /* FP_INFINITE */
+ *decpt = INT_MAX;
+ return rv_strdup(INFSTR, rve);
+ }
+ else if (isnan(d)) { /* FP_NAN */
+ *decpt = INT_MAX;
+ return rv_strdup(NANSTR, rve);
+ }
+ else if (d == 0.0) { /* FP_ZERO */
+ *decpt = 1;
+ return rv_strdup(ZEROSTR, rve);
+ }
+ else if (dexp_get(u)) { /* FP_NORMAL */
+ *decpt = dexp_get(u) - DBL_ADJ;
+ }
+ else { /* FP_SUBNORMAL */
+ u.d *= 5.363123171977039e+154 /* 0x1p514 */;
+ *decpt = dexp_get(u) - (514 + DBL_ADJ);
+ }
+
+ if (ndigits == 0) /* dtoa() compatibility */
+ ndigits = 1;
+
+ /*
+ * If ndigits < 0, we are expected to auto-size, so we allocate
+ * enough space for all the digits.
+ */
+ bufsize = (ndigits > 0) ? ndigits : SIGFIGS;
+ s0 = rv_alloc(bufsize+1);
+
+ /* Round to the desired number of digits. */
+ if (SIGFIGS > ndigits && ndigits > 0) {
+ float redux = 1.0f;
+ int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG;
+ dexp_set(u, offset);
+ u.d += redux;
+ u.d -= redux;
+ *decpt += dexp_get(u) - offset;
+ }
+
+ manh = dmanh_get(u);
+ manl = dmanl_get(u);
+ *s0 = '1';
+ for (s = s0 + 1; s < s0 + bufsize; s++) {
+ *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf];
+ manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4));
+ manl <<= 4;
+ }
+
+ /* If ndigits < 0, we are expected to auto-size the precision. */
+ if (ndigits < 0) {
+ for (ndigits = SIGFIGS; s0[ndigits - 1] == '0'; ndigits--)
+ ;
+ }
+
+ s = s0 + ndigits;
+ *s = '\0';
+ if (rve != NULL)
+ *rve = s;
+ return (s0);
+}
+
+#ifdef __cplusplus
+#if 0
+{ /* satisfy cc-mode */
+#endif
+}
+#endif
diff --git a/missing/dup2.c b/missing/dup2.c
index 7554084c5d..7f2b78c10f 100644
--- a/missing/dup2.c
+++ b/missing/dup2.c
@@ -11,7 +11,7 @@
* Return fd2 if all went well; return BADEXIT otherwise.
*/
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#if defined(HAVE_FCNTL)
# include <fcntl.h>
diff --git a/missing/explicit_bzero.c b/missing/explicit_bzero.c
index a7ff9cb517..1220e5f9ad 100644
--- a/missing/explicit_bzero.c
+++ b/missing/explicit_bzero.c
@@ -17,9 +17,9 @@
/* OS support note:
* BSDs have explicit_bzero().
- * OS-X has memset_s().
+ * macOS has memset_s().
* Windows has SecureZeroMemory() since XP.
- * Linux has none. *Sigh*
+ * Linux has explicit_bzero() since glibc 2.25, musl libc 1.1.20.
*/
/*
@@ -33,7 +33,13 @@
#undef explicit_bzero
#ifndef HAVE_EXPLICIT_BZERO
- #ifdef HAVE_MEMSET_S
+ #ifdef HAVE_EXPLICIT_MEMSET
+void
+explicit_bzero(void *b, size_t len)
+{
+ (void)explicit_memset(b, 0, len);
+}
+ #elif defined HAVE_MEMSET_S
void
explicit_bzero(void *b, size_t len)
{
diff --git a/missing/file.h b/missing/file.h
index 241d716563..5e25c4761c 100644
--- a/missing/file.h
+++ b/missing/file.h
@@ -1,7 +1,6 @@
-/* This is file FILE.H */
-
#ifndef _FILE_H_
#define _FILE_H_
+/* This is file FILE.H */
#include <fcntl.h>
diff --git a/missing/fileblocks.c b/missing/fileblocks.c
deleted file mode 100644
index ccb8d667b4..0000000000
--- a/missing/fileblocks.c
+++ /dev/null
@@ -1 +0,0 @@
-/* dummy for autoconf */
diff --git a/missing/flock.c b/missing/flock.c
index 829f431ddc..c0b3f80601 100644
--- a/missing/flock.c
+++ b/missing/flock.c
@@ -1,8 +1,8 @@
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#include "ruby/ruby.h"
#if defined _WIN32
-#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H && !defined(__native_client__)
+#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H
/* These are the flock() constants. Since this systems doesn't have
flock(), the values of the constants are probably not available.
diff --git a/missing/isinf.c b/missing/isinf.c
index 55187adc63..ba24b7768b 100644
--- a/missing/isinf.c
+++ b/missing/isinf.c
@@ -18,7 +18,7 @@ isinf(double n)
#else
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#if defined(HAVE_FINITE) && defined(HAVE_ISNAN)
diff --git a/missing/memcmp.c b/missing/memcmp.c
index a81eec4244..9657e6c372 100644
--- a/missing/memcmp.c
+++ b/missing/memcmp.c
@@ -11,7 +11,8 @@ memcmp(const void *s1, const void *s2, size_t len)
register int tmp;
for (; len; --len) {
- if (tmp = *a++ - *b++)
+ tmp = *a++ - *b++;
+ if (tmp)
return tmp;
}
return 0;
diff --git a/missing/mt19937.c b/missing/mt19937.c
new file mode 100644
index 0000000000..cf1da349fb
--- /dev/null
+++ b/missing/mt19937.c
@@ -0,0 +1,158 @@
+/*
+This is based on trimmed version of MT19937. To get the original version,
+contact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.
+
+The original copyright notice follows.
+
+ A C-program for MT19937, with initialization improved 2002/2/10.
+ Coded by Takuji Nishimura and Makoto Matsumoto.
+ This is a faster version by taking Shawn Cokus's optimization,
+ Matthe Bellew's simplification, Isaku Wada's real version.
+
+ Before using, initialize the state by using init_genrand(mt, seed)
+ or init_by_array(mt, init_key, key_length).
+
+ Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ Any feedback is very welcome.
+ http://www.math.keio.ac.jp/matumoto/emt.html
+ email: matumoto@math.keio.ac.jp
+*/
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfU /* constant vector a */
+#define UMASK 0x80000000U /* most significant w-r bits */
+#define LMASK 0x7fffffffU /* least significant r bits */
+#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
+#define TWIST(u,v) ((MIXBITS((u),(v)) >> 1) ^ ((v)&1U ? MATRIX_A : 0U))
+
+enum {MT_MAX_STATE = N};
+
+struct MT {
+ /* assume int is enough to store 32bits */
+ uint32_t state[N]; /* the array for the state vector */
+ uint32_t *next;
+ int left;
+};
+
+#define genrand_initialized(mt) ((mt)->next != 0)
+#define uninit_genrand(mt) ((mt)->next = 0)
+
+NO_SANITIZE("unsigned-integer-overflow", static void init_genrand(struct MT *mt, unsigned int s));
+NO_SANITIZE("unsigned-integer-overflow", static void init_by_array(struct MT *mt, const uint32_t init_key[], int key_length));
+
+/* initializes state[N] with a seed */
+static void
+init_genrand(struct MT *mt, unsigned int s)
+{
+ int j;
+ mt->state[0] = s & 0xffffffffU;
+ for (j=1; j<N; j++) {
+ mt->state[j] = (1812433253U * (mt->state[j-1] ^ (mt->state[j-1] >> 30)) + j);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array state[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ mt->state[j] &= 0xffffffff; /* for >32 bit machines */
+ }
+ mt->left = 1;
+ mt->next = mt->state + N;
+}
+
+/* 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 */
+static void
+init_by_array(struct MT *mt, const uint32_t init_key[], int key_length)
+{
+ int i, j, k;
+ init_genrand(mt, 19650218U);
+ i=1; j=0;
+ k = (N>key_length ? N : key_length);
+ for (; k; k--) {
+ mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1664525U))
+ + init_key[j] + j; /* non linear */
+ mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
+ i++; j++;
+ if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
+ if (j>=key_length) j=0;
+ }
+ for (k=N-1; k; k--) {
+ mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1566083941U))
+ - i; /* non linear */
+ mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
+ i++;
+ if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
+ }
+
+ mt->state[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
+}
+
+static void
+next_state(struct MT *mt)
+{
+ uint32_t *p = mt->state;
+ int j;
+
+ mt->left = N;
+ mt->next = mt->state;
+
+ for (j=N-M+1; --j; p++)
+ *p = p[M] ^ TWIST(p[0], p[1]);
+
+ for (j=M; --j; p++)
+ *p = p[M-N] ^ TWIST(p[0], p[1]);
+
+ *p = p[M-N] ^ TWIST(p[0], mt->state[0]);
+}
+
+/* generates a random number on [0,0xffffffff]-interval */
+static unsigned int
+genrand_int32(struct MT *mt)
+{
+ /* mt must be initialized */
+ unsigned int y;
+
+ if (--mt->left <= 0) next_state(mt);
+ y = *mt->next++;
+
+ /* Tempering */
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680;
+ y ^= (y << 15) & 0xefc60000;
+ y ^= (y >> 18);
+
+ return y;
+}
diff --git a/missing/nan.c b/missing/nan.c
new file mode 100644
index 0000000000..686c48a336
--- /dev/null
+++ b/missing/nan.c
@@ -0,0 +1,28 @@
+#include "ruby/missing.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+double
+nan(const char *spec)
+{
+#if 0
+ /* FIXME: we have not yet seen any situation this is
+ * necessary. Please write a proper implementation that
+ * covers this branch. */
+ if (spec && spec[0]) {
+ double generated_nan;
+ int len = snprintf(NULL, 0, "NAN(%s)", spec);
+ char *buf = malloc(len + 1); /* +1 for NUL */
+ sprintf(buf, "NAN(%s)", spec);
+ generated_nan = strtod(buf, NULL);
+ free(buf);
+ return generated_nan;
+ }
+ else
+#endif
+ {
+ assert(!spec || !spec[0]);
+ return (double)NAN;
+ }
+}
diff --git a/missing/procstat_vm.c b/missing/procstat_vm.c
new file mode 100644
index 0000000000..76fd8f61ba
--- /dev/null
+++ b/missing/procstat_vm.c
@@ -0,0 +1,85 @@
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <sys/param.h>
+#include <libprocstat.h>
+# ifndef KVME_TYPE_MGTDEVICE
+# define KVME_TYPE_MGTDEVICE 8
+# endif
+void
+procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
+{
+ struct kinfo_vmentry *freep, *kve;
+ int ptrwidth;
+ unsigned int i, cnt;
+ const char *str;
+#ifdef __x86_64__
+ ptrwidth = 14;
+#else
+ ptrwidth = 2*sizeof(void *) + 2;
+#endif
+ fprintf(stderr, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n",
+ ptrwidth, "START", ptrwidth, "END", "PRT", "RES",
+ "P""RES", "REF", "SHD", "FL", "TP", "PATH");
+
+#ifdef HAVE_PROCSTAT_GETVMMAP
+ freep = procstat_getvmmap(procstat, kipp, &cnt);
+#else
+ freep = kinfo_getvmmap(kipp->ki_pid, &cnt);
+#endif
+ if (freep == NULL)
+ return;
+ for (i = 0; i < cnt; i++) {
+ kve = &freep[i];
+ fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_start);
+ fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_end);
+ fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-");
+ fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-");
+ fprintf(stderr, "%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-");
+ fprintf(stderr, "%4d ", kve->kve_resident);
+ fprintf(stderr, "%4d ", kve->kve_private_resident);
+ fprintf(stderr, "%3d ", kve->kve_ref_count);
+ fprintf(stderr, "%3d ", kve->kve_shadow_count);
+ fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-");
+ fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" :
+ "-");
+ fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-");
+ fprintf(stderr, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" :
+ kve->kve_flags & KVME_FLAG_GROWS_DOWN ? "D" : "-");
+ switch (kve->kve_type) {
+ case KVME_TYPE_NONE:
+ str = "--";
+ break;
+ case KVME_TYPE_DEFAULT:
+ str = "df";
+ break;
+ case KVME_TYPE_VNODE:
+ str = "vn";
+ break;
+ case KVME_TYPE_SWAP:
+ str = "sw";
+ break;
+ case KVME_TYPE_DEVICE:
+ str = "dv";
+ break;
+ case KVME_TYPE_PHYS:
+ str = "ph";
+ break;
+ case KVME_TYPE_DEAD:
+ str = "dd";
+ break;
+ case KVME_TYPE_SG:
+ str = "sg";
+ break;
+ case KVME_TYPE_MGTDEVICE:
+ str = "md";
+ break;
+ case KVME_TYPE_UNKNOWN:
+ default:
+ str = "??";
+ break;
+ }
+ fprintf(stderr, "%-2s ", str);
+ fprintf(stderr, "%-s\n", kve->kve_path);
+ }
+ free(freep);
+}
diff --git a/missing/setproctitle.c b/missing/setproctitle.c
index 9fceeee52b..811829c060 100644
--- a/missing/setproctitle.c
+++ b/missing/setproctitle.c
@@ -152,10 +152,9 @@ setproctitle(const char *fmt, ...)
return;
#endif
+ /* fmt must be non-NULL */
va_start(ap, fmt);
- if (fmt != NULL) {
- vsnprintf(ptitle, sizeof(ptitle) , fmt, ap);
- }
+ vsnprintf(ptitle, sizeof(ptitle), fmt, ap);
va_end(ap);
#if SPT_TYPE == SPT_PSTAT
diff --git a/missing/tgamma.c b/missing/tgamma.c
index 6260e4f519..c8638eab2b 100644
--- a/missing/tgamma.c
+++ b/missing/tgamma.c
@@ -9,7 +9,7 @@ reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
/***********************************************************
gamma.c -- Gamma function
***********************************************************/
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#include "ruby/missing.h"
#include <math.h>
#include <errno.h>
diff --git a/missing/x86_64-chkstk.s b/missing/x86_64-chkstk.S
index 6d1227b6d2..6d1227b6d2 100644
--- a/missing/x86_64-chkstk.s
+++ b/missing/x86_64-chkstk.S
diff --git a/mjit.c b/mjit.c
new file mode 100644
index 0000000000..db0efb76a3
--- /dev/null
+++ b/mjit.c
@@ -0,0 +1,1023 @@
+/**********************************************************************
+
+ mjit.c - MRI method JIT compiler functions for Ruby's main thread
+
+ Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
+
+**********************************************************************/
+
+// Functions in this file are never executed on MJIT worker thread.
+// So you can safely use Ruby methods and GC in this file.
+
+// To share variables privately, include mjit_worker.c instead of linking.
+
+#include "ruby/internal/config.h" // defines USE_MJIT
+
+#if USE_MJIT
+
+#include "constant.h"
+#include "id_table.h"
+#include "internal.h"
+#include "internal/class.h"
+#include "internal/cont.h"
+#include "internal/file.h"
+#include "internal/hash.h"
+#include "internal/warnings.h"
+
+#include "mjit_worker.c"
+
+extern int rb_thread_create_mjit_thread(void (*worker_func)(void));
+
+// Return an unique file name in /tmp with PREFIX and SUFFIX and
+// number ID. Use getpid if ID == 0. The return file name exists
+// until the next function call.
+static char *
+get_uniq_filename(unsigned long id, const char *prefix, const char *suffix)
+{
+ char buff[70], *str = buff;
+ int size = sprint_uniq_filename(buff, sizeof(buff), id, prefix, suffix);
+ str = 0;
+ ++size;
+ str = xmalloc(size);
+ if (size <= (int)sizeof(buff)) {
+ memcpy(str, buff, size);
+ }
+ else {
+ sprint_uniq_filename(str, size, id, prefix, suffix);
+ }
+ return str;
+}
+
+// Wait until workers don't compile any iseq. It is called at the
+// start of GC.
+void
+mjit_gc_start_hook(void)
+{
+ if (!mjit_enabled)
+ return;
+ CRITICAL_SECTION_START(4, "mjit_gc_start_hook");
+ while (in_jit) {
+ verbose(4, "Waiting wakeup from a worker for GC");
+ rb_native_cond_wait(&mjit_client_wakeup, &mjit_engine_mutex);
+ verbose(4, "Getting wakeup from a worker for GC");
+ }
+ in_gc++;
+ CRITICAL_SECTION_FINISH(4, "mjit_gc_start_hook");
+}
+
+// Send a signal to workers to continue iseq compilations. It is
+// called at the end of GC.
+void
+mjit_gc_exit_hook(void)
+{
+ if (!mjit_enabled)
+ return;
+ CRITICAL_SECTION_START(4, "mjit_gc_exit_hook");
+ in_gc--;
+ RUBY_ASSERT_ALWAYS(in_gc >= 0);
+ if (!in_gc) {
+ verbose(4, "Sending wakeup signal to workers after GC");
+ rb_native_cond_broadcast(&mjit_gc_wakeup);
+ }
+ CRITICAL_SECTION_FINISH(4, "mjit_gc_exit_hook");
+}
+
+// Deal with ISeq movement from compactor
+void
+mjit_update_references(const rb_iseq_t *iseq)
+{
+ if (!mjit_enabled)
+ return;
+
+ CRITICAL_SECTION_START(4, "mjit_update_references");
+ if (iseq->body->jit_unit) {
+ iseq->body->jit_unit->iseq = (rb_iseq_t *)rb_gc_location((VALUE)iseq->body->jit_unit->iseq);
+ // We need to invalidate JIT-ed code for the ISeq because it embeds pointer addresses.
+ // To efficiently do that, we use the same thing as TracePoint and thus everything is cancelled for now.
+ // See mjit.h and tool/ruby_vm/views/_mjit_compile_insn.erb for how `mjit_call_p` is used.
+ mjit_call_p = false; // TODO: instead of cancelling all, invalidate only this one and recompile it with some threshold.
+ }
+
+ // Units in stale_units (list of over-speculated and invalidated code) are not referenced from
+ // `iseq->body->jit_unit` anymore (because new one replaces that). So we need to check them too.
+ // TODO: we should be able to reduce the number of units checked here.
+ struct rb_mjit_unit *unit = NULL;
+ list_for_each(&stale_units.head, unit, unode) {
+ if (unit->iseq == iseq) {
+ unit->iseq = (rb_iseq_t *)rb_gc_location((VALUE)unit->iseq);
+ }
+ }
+ CRITICAL_SECTION_FINISH(4, "mjit_update_references");
+}
+
+// Iseqs can be garbage collected. This function should call when it
+// happens. It removes iseq from the unit.
+void
+mjit_free_iseq(const rb_iseq_t *iseq)
+{
+ if (!mjit_enabled)
+ return;
+
+ CRITICAL_SECTION_START(4, "mjit_free_iseq");
+ RUBY_ASSERT_ALWAYS(in_gc);
+ RUBY_ASSERT_ALWAYS(!in_jit);
+ if (iseq->body->jit_unit) {
+ // jit_unit is not freed here because it may be referred by multiple
+ // lists of units. `get_from_list` and `mjit_finish` do the job.
+ iseq->body->jit_unit->iseq = NULL;
+ }
+ // Units in stale_units (list of over-speculated and invalidated code) are not referenced from
+ // `iseq->body->jit_unit` anymore (because new one replaces that). So we need to check them too.
+ // TODO: we should be able to reduce the number of units checked here.
+ struct rb_mjit_unit *unit = NULL;
+ list_for_each(&stale_units.head, unit, unode) {
+ if (unit->iseq == iseq) {
+ unit->iseq = NULL;
+ }
+ }
+ CRITICAL_SECTION_FINISH(4, "mjit_free_iseq");
+}
+
+// Free unit list. This should be called only when worker is finished
+// because node of unit_queue and one of active_units may have the same unit
+// during proceeding unit.
+static void
+free_list(struct rb_mjit_unit_list *list, bool close_handle_p)
+{
+ struct rb_mjit_unit *unit = 0, *next;
+
+ list_for_each_safe(&list->head, unit, next, unode) {
+ list_del(&unit->unode);
+ if (!close_handle_p) unit->handle = NULL; /* Skip dlclose in free_unit() */
+
+ if (list == &stale_units) { // `free_unit(unit)` crashes after GC.compact on `stale_units`
+ /*
+ * TODO: REVERT THIS BRANCH
+ * Debug the crash on stale_units w/ GC.compact and just use `free_unit(unit)`!!
+ */
+ if (unit->handle && dlclose(unit->handle)) {
+ mjit_warning("failed to close handle for u%d: %s", unit->id, dlerror());
+ }
+ clean_temp_files(unit);
+ free(unit);
+ }
+ else {
+ free_unit(unit);
+ }
+ }
+ list->length = 0;
+}
+
+// Register a new continuation with execution context `ec`. Return MJIT info about
+// the continuation.
+struct mjit_cont *
+mjit_cont_new(rb_execution_context_t *ec)
+{
+ struct mjit_cont *cont;
+
+ // We need to use calloc instead of something like ZALLOC to avoid triggering GC here.
+ // When this function is called from rb_thread_alloc through rb_threadptr_root_fiber_setup,
+ // the thread is still being prepared and marking it causes SEGV.
+ cont = calloc(1, sizeof(struct mjit_cont));
+ if (cont == NULL)
+ rb_memerror();
+ cont->ec = ec;
+
+ CRITICAL_SECTION_START(3, "in mjit_cont_new");
+ if (first_cont == NULL) {
+ cont->next = cont->prev = NULL;
+ }
+ else {
+ cont->prev = NULL;
+ cont->next = first_cont;
+ first_cont->prev = cont;
+ }
+ first_cont = cont;
+ CRITICAL_SECTION_FINISH(3, "in mjit_cont_new");
+
+ return cont;
+}
+
+// Unregister continuation `cont`.
+void
+mjit_cont_free(struct mjit_cont *cont)
+{
+ CRITICAL_SECTION_START(3, "in mjit_cont_new");
+ if (cont == first_cont) {
+ first_cont = cont->next;
+ if (first_cont != NULL)
+ first_cont->prev = NULL;
+ }
+ else {
+ cont->prev->next = cont->next;
+ if (cont->next != NULL)
+ cont->next->prev = cont->prev;
+ }
+ CRITICAL_SECTION_FINISH(3, "in mjit_cont_new");
+
+ free(cont);
+}
+
+// Finish work with continuation info.
+static void
+finish_conts(void)
+{
+ struct mjit_cont *cont, *next;
+
+ for (cont = first_cont; cont != NULL; cont = next) {
+ next = cont->next;
+ xfree(cont);
+ }
+}
+
+// Create unit for `iseq`. This function may be called from an MJIT worker.
+static void
+create_unit(const rb_iseq_t *iseq)
+{
+ struct rb_mjit_unit *unit;
+
+ unit = calloc(1, sizeof(struct rb_mjit_unit));
+ if (unit == NULL)
+ return;
+
+ unit->id = current_unit_num++;
+ unit->iseq = (rb_iseq_t *)iseq;
+ iseq->body->jit_unit = unit;
+}
+
+// This is called from an MJIT worker when worker_p is true.
+static void
+mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info, bool worker_p)
+{
+ if (!mjit_enabled || pch_status == PCH_FAILED)
+ return;
+
+ RB_DEBUG_COUNTER_INC(mjit_add_iseq_to_process);
+ iseq->body->jit_func = (mjit_func_t)NOT_READY_JIT_ISEQ_FUNC;
+ create_unit(iseq);
+ if (iseq->body->jit_unit == NULL)
+ // Failure in creating the unit.
+ return;
+ if (compile_info != NULL)
+ iseq->body->jit_unit->compile_info = *compile_info;
+
+ if (!worker_p) {
+ CRITICAL_SECTION_START(3, "in add_iseq_to_process");
+ }
+ add_to_list(iseq->body->jit_unit, &unit_queue);
+ if (active_units.length >= mjit_opts.max_cache_size) {
+ unload_requests++;
+ }
+ if (!worker_p) {
+ verbose(3, "Sending wakeup signal to workers in mjit_add_iseq_to_process");
+ rb_native_cond_broadcast(&mjit_worker_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in add_iseq_to_process");
+ }
+}
+
+// Add ISEQ to be JITed in parallel with the current thread.
+// Unload some JIT codes if there are too many of them.
+void
+rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq)
+{
+ mjit_add_iseq_to_process(iseq, NULL, false);
+}
+
+// For this timeout seconds, --jit-wait will wait for JIT compilation finish.
+#define MJIT_WAIT_TIMEOUT_SECONDS 60
+
+static void
+mjit_wait(struct rb_iseq_constant_body *body)
+{
+ struct timeval tv;
+ int tries = 0;
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ while (body->jit_func == (mjit_func_t)NOT_READY_JIT_ISEQ_FUNC) {
+ tries++;
+ if (tries / 1000 > MJIT_WAIT_TIMEOUT_SECONDS || pch_status == PCH_FAILED) {
+ CRITICAL_SECTION_START(3, "in rb_mjit_wait_call to set jit_func");
+ body->jit_func = (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC; // JIT worker seems dead. Give up.
+ CRITICAL_SECTION_FINISH(3, "in rb_mjit_wait_call to set jit_func");
+ mjit_warning("timed out to wait for JIT finish");
+ break;
+ }
+
+ CRITICAL_SECTION_START(3, "in rb_mjit_wait_call for a client wakeup");
+ rb_native_cond_broadcast(&mjit_worker_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in rb_mjit_wait_call for a client wakeup");
+ rb_thread_wait_for(tv);
+ }
+}
+
+// Wait for JIT compilation finish for --jit-wait, and call the function pointer
+// if the compiled result is not NOT_COMPILED_JIT_ISEQ_FUNC.
+VALUE
+rb_mjit_wait_call(rb_execution_context_t *ec, struct rb_iseq_constant_body *body)
+{
+ mjit_wait(body);
+ if ((uintptr_t)body->jit_func <= (uintptr_t)LAST_JIT_ISEQ_FUNC) {
+ return Qundef;
+ }
+ return body->jit_func(ec, ec->cfp);
+}
+
+struct rb_mjit_compile_info*
+rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body)
+{
+ assert(body->jit_unit != NULL);
+ return &body->jit_unit->compile_info;
+}
+
+static void
+mjit_recompile(const rb_iseq_t *iseq)
+{
+ if ((uintptr_t)iseq->body->jit_func <= (uintptr_t)LAST_JIT_ISEQ_FUNC)
+ return;
+
+ verbose(1, "JIT recompile: %s@%s:%d", RSTRING_PTR(iseq->body->location.label),
+ RSTRING_PTR(rb_iseq_path(iseq)), FIX2INT(iseq->body->location.first_lineno));
+ assert(iseq->body->jit_unit != NULL);
+
+ if (UNLIKELY(mjit_opts.wait)) {
+ remove_from_list(iseq->body->jit_unit, &active_units);
+ add_to_list(iseq->body->jit_unit, &stale_units);
+ mjit_add_iseq_to_process(iseq, &iseq->body->jit_unit->compile_info, false);
+ mjit_wait(iseq->body);
+ }
+ else {
+ // Lazily move active_units to stale_units to avoid race conditions around active_units with compaction.
+ // Also, it's lazily moved to unit_queue as well because otherwise it won't be added to stale_units properly.
+ // It's good to avoid a race condition between mjit_add_iseq_to_process and mjit_compile around jit_unit as well.
+ CRITICAL_SECTION_START(3, "in rb_mjit_recompile_iseq");
+ iseq->body->jit_unit->stale_p = true;
+ iseq->body->jit_func = (mjit_func_t)NOT_ADDED_JIT_ISEQ_FUNC;
+ pending_stale_p = true;
+ CRITICAL_SECTION_FINISH(3, "in rb_mjit_recompile_iseq");
+ }
+}
+
+// Recompile iseq, disabling send optimization
+void
+rb_mjit_recompile_send(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(iseq->body)->disable_send_cache = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling ivar optimization
+void
+rb_mjit_recompile_ivar(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(iseq->body)->disable_ivar_cache = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling exivar optimization
+void
+rb_mjit_recompile_exivar(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(iseq->body)->disable_exivar_cache = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling method inlining
+void
+rb_mjit_recompile_inlining(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(iseq->body)->disable_inlining = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling getconstant inlining
+void
+rb_mjit_recompile_const(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(iseq->body)->disable_const_cache = true;
+ mjit_recompile(iseq);
+}
+
+extern VALUE ruby_archlibdir_path, ruby_prefix_path;
+
+// Initialize header_file, pch_file, libruby_pathflag. Return true on success.
+static bool
+init_header_filename(void)
+{
+ int fd;
+#ifdef LOAD_RELATIVE
+ // Root path of the running ruby process. Equal to RbConfig::TOPDIR.
+ VALUE basedir_val;
+#endif
+ const char *basedir = "";
+ size_t baselen = 0;
+ char *p;
+#ifdef _WIN32
+ static const char libpathflag[] =
+# ifdef _MSC_VER
+ "-LIBPATH:"
+# else
+ "-L"
+# endif
+ ;
+ const size_t libpathflag_len = sizeof(libpathflag) - 1;
+#endif
+
+#ifdef LOAD_RELATIVE
+ basedir_val = ruby_prefix_path;
+ basedir = StringValuePtr(basedir_val);
+ baselen = RSTRING_LEN(basedir_val);
+#else
+ if (getenv("MJIT_SEARCH_BUILD_DIR")) {
+ // This path is not intended to be used on production, but using build directory's
+ // header file here because people want to run `make test-all` without running
+ // `make install`. Don't use $MJIT_SEARCH_BUILD_DIR except for test-all.
+
+ struct stat st;
+ const char *hdr = dlsym(RTLD_DEFAULT, "MJIT_HEADER");
+ if (!hdr) {
+ verbose(1, "No MJIT_HEADER");
+ }
+ else if (hdr[0] != '/') {
+ verbose(1, "Non-absolute header file path: %s", hdr);
+ }
+ else if (stat(hdr, &st) || !S_ISREG(st.st_mode)) {
+ verbose(1, "Non-file header file path: %s", hdr);
+ }
+ else if ((st.st_uid != getuid()) || (st.st_mode & 022) ||
+ !rb_path_check(hdr)) {
+ verbose(1, "Unsafe header file: uid=%ld mode=%#o %s",
+ (long)st.st_uid, (unsigned)st.st_mode, hdr);
+ return FALSE;
+ }
+ else {
+ // Do not pass PRELOADENV to child processes, on
+ // multi-arch environment
+ verbose(3, "PRELOADENV("PRELOADENV")=%s", getenv(PRELOADENV));
+ // assume no other PRELOADENV in test-all
+ unsetenv(PRELOADENV);
+ verbose(3, "MJIT_HEADER: %s", hdr);
+ header_file = ruby_strdup(hdr);
+ if (!header_file) return false;
+ }
+ }
+ else
+#endif
+#ifndef _MSC_VER
+ {
+ // A name of the header file included in any C file generated by MJIT for iseqs.
+ static const char header_name[] = MJIT_HEADER_INSTALL_DIR "/" MJIT_MIN_HEADER_NAME;
+ const size_t header_name_len = sizeof(header_name) - 1;
+
+ header_file = xmalloc(baselen + header_name_len + 1);
+ p = append_str2(header_file, basedir, baselen);
+ p = append_str2(p, header_name, header_name_len + 1);
+
+ if ((fd = rb_cloexec_open(header_file, O_RDONLY, 0)) < 0) {
+ verbose(1, "Cannot access header file: %s", header_file);
+ xfree(header_file);
+ header_file = NULL;
+ return false;
+ }
+ (void)close(fd);
+ }
+
+ pch_file = get_uniq_filename(0, MJIT_TMP_PREFIX "h", ".h.gch");
+#else
+ {
+ static const char pch_name[] = MJIT_HEADER_INSTALL_DIR "/" MJIT_PRECOMPILED_HEADER_NAME;
+ const size_t pch_name_len = sizeof(pch_name) - 1;
+
+ pch_file = xmalloc(baselen + pch_name_len + 1);
+ p = append_str2(pch_file, basedir, baselen);
+ p = append_str2(p, pch_name, pch_name_len + 1);
+ if ((fd = rb_cloexec_open(pch_file, O_RDONLY, 0)) < 0) {
+ verbose(1, "Cannot access precompiled header file: %s", pch_file);
+ xfree(pch_file);
+ pch_file = NULL;
+ return false;
+ }
+ (void)close(fd);
+ }
+#endif
+
+#ifdef _WIN32
+ basedir_val = ruby_archlibdir_path;
+ basedir = StringValuePtr(basedir_val);
+ baselen = RSTRING_LEN(basedir_val);
+ libruby_pathflag = p = xmalloc(libpathflag_len + baselen + 1);
+ p = append_str(p, libpathflag);
+ p = append_str2(p, basedir, baselen);
+ *p = '\0';
+#endif
+
+ return true;
+}
+
+static enum rb_id_table_iterator_result
+valid_class_serials_add_i(ID key, VALUE v, void *unused)
+{
+ rb_const_entry_t *ce = (rb_const_entry_t *)v;
+ VALUE value = ce->value;
+
+ if (!rb_is_const_id(key)) return ID_TABLE_CONTINUE;
+ if (RB_TYPE_P(value, T_MODULE) || RB_TYPE_P(value, T_CLASS)) {
+ mjit_add_class_serial(RCLASS_SERIAL(value));
+ }
+ return ID_TABLE_CONTINUE;
+}
+
+#ifdef _WIN32
+UINT rb_w32_system_tmpdir(WCHAR *path, UINT len);
+#endif
+
+static char *
+system_default_tmpdir(void)
+{
+ // c.f. ext/etc/etc.c:etc_systmpdir()
+#ifdef _WIN32
+ WCHAR tmppath[_MAX_PATH];
+ UINT len = rb_w32_system_tmpdir(tmppath, numberof(tmppath));
+ if (len) {
+ int blen = WideCharToMultiByte(CP_UTF8, 0, tmppath, len, NULL, 0, NULL, NULL);
+ char *tmpdir = xmalloc(blen + 1);
+ WideCharToMultiByte(CP_UTF8, 0, tmppath, len, tmpdir, blen, NULL, NULL);
+ tmpdir[blen] = '\0';
+ return tmpdir;
+ }
+#elif defined _CS_DARWIN_USER_TEMP_DIR
+ char path[MAXPATHLEN];
+ size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
+ if (len > 0) {
+ char *tmpdir = xmalloc(len);
+ if (len > sizeof(path)) {
+ confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir, len);
+ }
+ else {
+ memcpy(tmpdir, path, len);
+ }
+ return tmpdir;
+ }
+#endif
+ return 0;
+}
+
+static int
+check_tmpdir(const char *dir)
+{
+ struct stat st;
+
+ if (!dir) return FALSE;
+ if (stat(dir, &st)) return FALSE;
+#ifndef S_ISDIR
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+ if (!S_ISDIR(st.st_mode)) return FALSE;
+#ifndef _WIN32
+# ifndef S_IWOTH
+# define S_IWOTH 002
+# endif
+ if (st.st_mode & S_IWOTH) {
+# ifdef S_ISVTX
+ if (!(st.st_mode & S_ISVTX)) return FALSE;
+# else
+ return FALSE;
+# endif
+ }
+ if (access(dir, W_OK)) return FALSE;
+#endif
+ return TRUE;
+}
+
+static char *
+system_tmpdir(void)
+{
+ char *tmpdir;
+# define RETURN_ENV(name) \
+ if (check_tmpdir(tmpdir = getenv(name))) return ruby_strdup(tmpdir)
+ RETURN_ENV("TMPDIR");
+ RETURN_ENV("TMP");
+ tmpdir = system_default_tmpdir();
+ if (check_tmpdir(tmpdir)) return tmpdir;
+ return ruby_strdup("/tmp");
+# undef RETURN_ENV
+}
+
+// Minimum value for JIT cache size.
+#define MIN_CACHE_SIZE 10
+// Default permitted number of units with a JIT code kept in memory.
+#define DEFAULT_MAX_CACHE_SIZE 100
+// A default threshold used to add iseq to JIT.
+#define DEFAULT_MIN_CALLS_TO_ADD 10000
+
+// Start MJIT worker. Return TRUE if worker is successfully started.
+static bool
+start_worker(void)
+{
+ stop_worker_p = false;
+ worker_stopped = false;
+
+ if (!rb_thread_create_mjit_thread(mjit_worker)) {
+ mjit_enabled = false;
+ rb_native_mutex_destroy(&mjit_engine_mutex);
+ rb_native_cond_destroy(&mjit_pch_wakeup);
+ rb_native_cond_destroy(&mjit_client_wakeup);
+ rb_native_cond_destroy(&mjit_worker_wakeup);
+ rb_native_cond_destroy(&mjit_gc_wakeup);
+ verbose(1, "Failure in MJIT thread initialization\n");
+ return false;
+ }
+ return true;
+}
+
+// There's no strndup on Windows
+static char*
+ruby_strndup(const char *str, size_t n)
+{
+ char *ret = xmalloc(n + 1);
+ memcpy(ret, str, n);
+ ret[n] = '\0';
+ return ret;
+}
+
+// Convert "foo bar" to {"foo", "bar", NULL} array. Caller is responsible for
+// freeing a returned buffer and its elements.
+static char **
+split_flags(const char *flags)
+{
+ char *buf[MAXPATHLEN];
+ int i = 0;
+ char *next;
+ for (; flags != NULL; flags = next) {
+ next = strchr(flags, ' ');
+ if (next == NULL) {
+ if (strlen(flags) > 0)
+ buf[i++] = strdup(flags);
+ }
+ else {
+ if (next > flags)
+ buf[i++] = ruby_strndup(flags, next - flags);
+ next++; // skip space
+ }
+ }
+
+ char **ret = xmalloc(sizeof(char *) * (i + 1));
+ memcpy(ret, buf, sizeof(char *) * i);
+ ret[i] = NULL;
+ return ret;
+}
+
+// Initialize MJIT. Start a thread creating the precompiled header and
+// processing ISeqs. The function should be called first for using MJIT.
+// If everything is successful, MJIT_INIT_P will be TRUE.
+void
+mjit_init(const struct mjit_options *opts)
+{
+ mjit_opts = *opts;
+ mjit_enabled = true;
+ mjit_call_p = true;
+
+ // Normalize options
+ if (mjit_opts.min_calls == 0)
+ mjit_opts.min_calls = DEFAULT_MIN_CALLS_TO_ADD;
+ if (mjit_opts.max_cache_size <= 0)
+ mjit_opts.max_cache_size = DEFAULT_MAX_CACHE_SIZE;
+ if (mjit_opts.max_cache_size < MIN_CACHE_SIZE)
+ mjit_opts.max_cache_size = MIN_CACHE_SIZE;
+
+ // Initialize variables for compilation
+#ifdef _MSC_VER
+ pch_status = PCH_SUCCESS; // has prebuilt precompiled header
+#else
+ pch_status = PCH_NOT_READY;
+#endif
+ cc_path = CC_COMMON_ARGS[0];
+ verbose(2, "MJIT: CC defaults to %s", cc_path);
+ cc_common_args = xmalloc(sizeof(CC_COMMON_ARGS));
+ memcpy((void *)cc_common_args, CC_COMMON_ARGS, sizeof(CC_COMMON_ARGS));
+ cc_added_args = split_flags(opts->debug_flags);
+ xfree(opts->debug_flags);
+#if MJIT_CFLAGS_PIPE
+ // eliminate a flag incompatible with `-pipe`
+ for (size_t i = 0, j = 0; i < sizeof(CC_COMMON_ARGS) / sizeof(char *); i++) {
+ if (CC_COMMON_ARGS[i] && strncmp("-save-temps", CC_COMMON_ARGS[i], strlen("-save-temps")) == 0)
+ continue; // skip -save-temps flag
+ cc_common_args[j] = CC_COMMON_ARGS[i];
+ j++;
+ }
+#endif
+
+ tmp_dir = system_tmpdir();
+ verbose(2, "MJIT: tmp_dir is %s", tmp_dir);
+
+ if (!init_header_filename()) {
+ mjit_enabled = false;
+ verbose(1, "Failure in MJIT header file name initialization\n");
+ return;
+ }
+ pch_owner_pid = getpid();
+
+ // Initialize mutex
+ rb_native_mutex_initialize(&mjit_engine_mutex);
+ rb_native_cond_initialize(&mjit_pch_wakeup);
+ rb_native_cond_initialize(&mjit_client_wakeup);
+ rb_native_cond_initialize(&mjit_worker_wakeup);
+ rb_native_cond_initialize(&mjit_gc_wakeup);
+
+ // Make sure the saved_ec of the initial thread's root_fiber is scanned by mark_ec_units.
+ //
+ // rb_threadptr_root_fiber_setup for the initial thread is called before mjit_init,
+ // meaning mjit_cont_new is skipped for the root_fiber. Therefore we need to call
+ // rb_fiber_init_mjit_cont again with mjit_enabled=true to set the root_fiber's mjit_cont.
+ rb_fiber_init_mjit_cont(GET_EC()->fiber_ptr);
+
+ // Initialize class_serials cache for compilation
+ valid_class_serials = rb_hash_new();
+ rb_obj_hide(valid_class_serials);
+ rb_gc_register_mark_object(valid_class_serials);
+ mjit_add_class_serial(RCLASS_SERIAL(rb_cObject));
+ mjit_add_class_serial(RCLASS_SERIAL(CLASS_OF(rb_vm_top_self())));
+ if (RCLASS_CONST_TBL(rb_cObject)) {
+ rb_id_table_foreach(RCLASS_CONST_TBL(rb_cObject), valid_class_serials_add_i, NULL);
+ }
+
+ // Initialize worker thread
+ start_worker();
+}
+
+static void
+stop_worker(void)
+{
+ rb_execution_context_t *ec = GET_EC();
+
+ while (!worker_stopped) {
+ verbose(3, "Sending cancel signal to worker");
+ CRITICAL_SECTION_START(3, "in stop_worker");
+ stop_worker_p = true; // Setting this inside loop because RUBY_VM_CHECK_INTS may make this false.
+ rb_native_cond_broadcast(&mjit_worker_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in stop_worker");
+ RUBY_VM_CHECK_INTS(ec);
+ }
+}
+
+// Stop JIT-compiling methods but compiled code is kept available.
+VALUE
+mjit_pause(bool wait_p)
+{
+ if (!mjit_enabled) {
+ rb_raise(rb_eRuntimeError, "MJIT is not enabled");
+ }
+ if (worker_stopped) {
+ return Qfalse;
+ }
+
+ // Flush all queued units with no option or `wait: true`
+ if (wait_p) {
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+
+ while (unit_queue.length > 0 && active_units.length < mjit_opts.max_cache_size) { // inverse of condition that waits for mjit_worker_wakeup
+ CRITICAL_SECTION_START(3, "in mjit_pause for a worker wakeup");
+ rb_native_cond_broadcast(&mjit_worker_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in mjit_pause for a worker wakeup");
+ rb_thread_wait_for(tv);
+ }
+ }
+
+ stop_worker();
+ return Qtrue;
+}
+
+// Restart JIT-compiling methods after mjit_pause.
+VALUE
+mjit_resume(void)
+{
+ if (!mjit_enabled) {
+ rb_raise(rb_eRuntimeError, "MJIT is not enabled");
+ }
+ if (!worker_stopped) {
+ return Qfalse;
+ }
+
+ if (!start_worker()) {
+ rb_raise(rb_eRuntimeError, "Failed to resume MJIT worker");
+ }
+ return Qtrue;
+}
+
+// Skip calling `clean_temp_files` for units which currently exist in the list.
+static void
+skip_cleaning_object_files(struct rb_mjit_unit_list *list)
+{
+ struct rb_mjit_unit *unit = NULL, *next;
+
+ // No mutex for list, assuming MJIT worker does not exist yet since it's immediately after fork.
+ list_for_each_safe(&list->head, unit, next, unode) {
+#if defined(_WIN32) // mswin doesn't reach here either. This is for MinGW.
+ if (unit->so_file) unit->so_file = NULL;
+#endif
+ }
+}
+
+// This is called after fork initiated by Ruby's method to launch MJIT worker thread
+// for child Ruby process.
+//
+// In multi-process Ruby applications, child Ruby processes do most of the jobs.
+// Thus we want child Ruby processes to enqueue ISeqs to MJIT worker's queue and
+// call the JIT-ed code.
+//
+// But unfortunately current MJIT-generated code is process-specific. After the fork,
+// JIT-ed code created by parent Ruby process cannot be used in child Ruby process
+// because the code could rely on inline cache values (ivar's IC, send's CC) which
+// may vary between processes after fork or embed some process-specific addresses.
+//
+// So child Ruby process can't request parent process to JIT an ISeq and use the code.
+// Instead of that, MJIT worker thread is created for all child Ruby processes, even
+// while child processes would end up with compiling the same ISeqs.
+void
+mjit_child_after_fork(void)
+{
+ if (!mjit_enabled)
+ return;
+
+ /* Let parent process delete the already-compiled object files.
+ This must be done before starting MJIT worker on child process. */
+ skip_cleaning_object_files(&active_units);
+
+ /* MJIT worker thread is not inherited on fork. Start it for this child process. */
+ start_worker();
+}
+
+// Edit 0 to 1 to enable this feature for investigating hot methods
+#define MJIT_COUNTER 0
+#if MJIT_COUNTER
+static void
+mjit_dump_total_calls(void)
+{
+ struct rb_mjit_unit *unit;
+ fprintf(stderr, "[MJIT_COUNTER] total_calls of active_units:\n");
+ list_for_each(&active_units.head, unit, unode) {
+ const rb_iseq_t *iseq = unit->iseq;
+ fprintf(stderr, "%8ld: %s@%s:%d\n", iseq->body->total_calls, RSTRING_PTR(iseq->body->location.label),
+ RSTRING_PTR(rb_iseq_path(iseq)), FIX2INT(iseq->body->location.first_lineno));
+ }
+}
+#endif
+
+// Finish the threads processing units and creating PCH, finalize
+// and free MJIT data. It should be called last during MJIT
+// life.
+//
+// If close_handle_p is true, it calls dlclose() for JIT-ed code. So it should be false
+// if the code can still be on stack. ...But it means to leak JIT-ed handle forever (FIXME).
+void
+mjit_finish(bool close_handle_p)
+{
+ if (!mjit_enabled)
+ return;
+
+ // Wait for pch finish
+ verbose(2, "Stopping worker thread");
+ CRITICAL_SECTION_START(3, "in mjit_finish to wakeup from pch");
+ // As our threads are detached, we could just cancel them. But it
+ // is a bad idea because OS processes (C compiler) started by
+ // threads can produce temp files. And even if the temp files are
+ // removed, the used C compiler still complaint about their
+ // absence. So wait for a clean finish of the threads.
+ while (pch_status == PCH_NOT_READY) {
+ verbose(3, "Waiting wakeup from make_pch");
+ rb_native_cond_wait(&mjit_pch_wakeup, &mjit_engine_mutex);
+ }
+ CRITICAL_SECTION_FINISH(3, "in mjit_finish to wakeup from pch");
+
+ // Stop worker
+ stop_worker();
+
+ rb_native_mutex_destroy(&mjit_engine_mutex);
+ rb_native_cond_destroy(&mjit_pch_wakeup);
+ rb_native_cond_destroy(&mjit_client_wakeup);
+ rb_native_cond_destroy(&mjit_worker_wakeup);
+ rb_native_cond_destroy(&mjit_gc_wakeup);
+
+#if MJIT_COUNTER
+ mjit_dump_total_calls();
+#endif
+
+#ifndef _MSC_VER // mswin has prebuilt precompiled header
+ if (!mjit_opts.save_temps && getpid() == pch_owner_pid)
+ remove_file(pch_file);
+
+ xfree(header_file); header_file = NULL;
+#endif
+ xfree((void *)cc_common_args); cc_common_args = NULL;
+ for (char **flag = cc_added_args; *flag != NULL; flag++)
+ xfree(*flag);
+ xfree((void *)cc_added_args); cc_added_args = NULL;
+ xfree(tmp_dir); tmp_dir = NULL;
+ xfree(pch_file); pch_file = NULL;
+
+ mjit_call_p = false;
+ free_list(&unit_queue, close_handle_p);
+ free_list(&active_units, close_handle_p);
+ free_list(&compact_units, close_handle_p);
+ free_list(&stale_units, close_handle_p);
+ finish_conts();
+
+ mjit_enabled = false;
+ verbose(1, "Successful MJIT finish");
+}
+
+// Called by rb_vm_mark().
+//
+// Mark an ISeq being compiled to prevent its CCs from being GC-ed, which
+// an MJIT worker may concurrently see.
+//
+// Also mark active_units so that we do not GC ISeq which may still be
+// referred to by mjit_recompile() or compact_all_jit_code().
+void
+mjit_mark(void)
+{
+ if (!mjit_enabled)
+ return;
+ RUBY_MARK_ENTER("mjit");
+
+ // We need to release a lock when calling rb_gc_mark to avoid doubly acquiring
+ // a lock by by mjit_gc_start_hook inside rb_gc_mark.
+ //
+ // Because an MJIT worker may modify active_units anytime, we need to convert
+ // the linked list to an array to safely loop its ISeqs without keeping a lock.
+ CRITICAL_SECTION_START(4, "mjit_mark");
+ int length = 0;
+ if (compiling_iseqs != NULL) {
+ while (compiling_iseqs[length]) length++;
+ }
+ length += active_units.length;
+ const rb_iseq_t **iseqs = ALLOCA_N(const rb_iseq_t *, length);
+
+ struct rb_mjit_unit *unit = NULL;
+ int i = 0;
+ if (compiling_iseqs != NULL) {
+ while (compiling_iseqs[i]) {
+ iseqs[i] = compiling_iseqs[i];
+ i++;
+ }
+ }
+ list_for_each(&active_units.head, unit, unode) {
+ iseqs[i] = unit->iseq;
+ i++;
+ }
+ assert(i == length);
+ CRITICAL_SECTION_FINISH(4, "mjit_mark");
+
+ for (i = 0; i < length; i++) {
+ if (iseqs[i] == NULL) // ISeq is GC-ed
+ continue;
+ rb_gc_mark((VALUE)iseqs[i]);
+ }
+
+ RUBY_MARK_LEAVE("mjit");
+}
+
+// Called by rb_iseq_mark() to mark cc_entries captured for MJIT
+void
+mjit_mark_cc_entries(const struct rb_iseq_constant_body *const body)
+{
+ const struct rb_callcache **cc_entries;
+ if (body->jit_unit && (cc_entries = body->jit_unit->cc_entries) != NULL) {
+ // It must be `body->jit_unit->cc_entries_size` instead of `body->ci_size` to mark children's cc_entries
+ for (unsigned int i = 0; i < body->jit_unit->cc_entries_size; i++) {
+ const struct rb_callcache *cc = cc_entries[i];
+ if (cc != NULL && vm_cc_markable(cc)) {
+ // Pin `cc` and `cc->cme` against GC.compact as their addresses may be written in JIT-ed code.
+ rb_gc_mark((VALUE)cc);
+ rb_gc_mark((VALUE)vm_cc_cme(cc));
+ }
+ }
+ }
+}
+
+// A hook to update valid_class_serials.
+void
+mjit_add_class_serial(rb_serial_t class_serial)
+{
+ if (!mjit_enabled)
+ return;
+
+ // Do not wrap CRITICAL_SECTION here. This function is only called in main thread
+ // and guarded by GVL, and `rb_hash_aset` may cause GC and deadlock in it.
+ rb_hash_aset(valid_class_serials, LONG2FIX(class_serial), Qtrue);
+}
+
+// A hook to update valid_class_serials.
+void
+mjit_remove_class_serial(rb_serial_t class_serial)
+{
+ if (!mjit_enabled)
+ return;
+
+ CRITICAL_SECTION_START(3, "in mjit_remove_class_serial");
+ rb_hash_delete_entry(valid_class_serials, LONG2FIX(class_serial));
+ CRITICAL_SECTION_FINISH(3, "in mjit_remove_class_serial");
+}
+
+#endif
diff --git a/mjit.h b/mjit.h
new file mode 100644
index 0000000000..34c47d79a5
--- /dev/null
+++ b/mjit.h
@@ -0,0 +1,216 @@
+#ifndef RUBY_MJIT_H
+#define RUBY_MJIT_H 1
+/**********************************************************************
+
+ mjit.h - Interface to MRI method JIT compiler for Ruby's main thread
+
+ Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
+
+**********************************************************************/
+
+#include "ruby/internal/config.h" // defines USE_MJIT
+#include "ruby/internal/stdbool.h"
+#include "vm_core.h"
+
+# if USE_MJIT
+
+#include "debug_counter.h"
+#include "ruby.h"
+
+// Special address values of a function generated from the
+// corresponding iseq by MJIT:
+enum rb_mjit_iseq_func {
+ // ISEQ was not queued yet for the machine code generation
+ NOT_ADDED_JIT_ISEQ_FUNC = 0,
+ // ISEQ is already queued for the machine code generation but the
+ // code is not ready yet for the execution
+ NOT_READY_JIT_ISEQ_FUNC = 1,
+ // ISEQ included not compilable insn, some internal assertion failed
+ // or the unit is unloaded
+ NOT_COMPILED_JIT_ISEQ_FUNC = 2,
+ // End mark
+ LAST_JIT_ISEQ_FUNC = 3
+};
+
+// MJIT options which can be defined on the MRI command line.
+struct mjit_options {
+ // Converted from "jit" feature flag to tell the enablement
+ // information to ruby_show_version().
+ char on;
+ // Save temporary files after MRI finish. The temporary files
+ // include the pre-compiled header, C code file generated for ISEQ,
+ // and the corresponding object file.
+ char save_temps;
+ // Print MJIT warnings to stderr.
+ char warnings;
+ // Disable compiler optimization and add debug symbols. It can be
+ // very slow.
+ char debug;
+ // Add arbitrary cflags.
+ char* debug_flags;
+ // If not 0, all ISeqs are synchronously compiled. For testing.
+ unsigned int wait;
+ // Number of calls to trigger JIT compilation. For testing.
+ unsigned int min_calls;
+ // Force printing info about MJIT work of level VERBOSE or
+ // less. 0=silence, 1=medium, 2=verbose.
+ int verbose;
+ // Maximal permitted number of iseq JIT codes in a MJIT memory
+ // cache.
+ int max_cache_size;
+};
+
+// State of optimization switches
+struct rb_mjit_compile_info {
+ // Disable getinstancevariable/setinstancevariable optimizations based on inline cache (T_OBJECT)
+ bool disable_ivar_cache;
+ // Disable getinstancevariable/setinstancevariable optimizations based on inline cache (FL_EXIVAR)
+ bool disable_exivar_cache;
+ // Disable send/opt_send_without_block optimizations based on inline cache
+ bool disable_send_cache;
+ // Disable method inlining
+ bool disable_inlining;
+ // Disable opt_getinlinecache inlining
+ bool disable_const_cache;
+};
+
+typedef VALUE (*mjit_func_t)(rb_execution_context_t *, rb_control_frame_t *);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+RUBY_EXTERN struct mjit_options mjit_opts;
+RUBY_EXTERN bool mjit_call_p;
+
+extern void rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq);
+extern VALUE rb_mjit_wait_call(rb_execution_context_t *ec, struct rb_iseq_constant_body *body);
+extern struct rb_mjit_compile_info* rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body);
+extern void rb_mjit_recompile_send(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_ivar(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_exivar(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_inlining(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_const(const rb_iseq_t *iseq);
+RUBY_SYMBOL_EXPORT_END
+
+extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
+extern void mjit_init(const struct mjit_options *opts);
+extern void mjit_gc_start_hook(void);
+extern void mjit_gc_exit_hook(void);
+extern void mjit_free_iseq(const rb_iseq_t *iseq);
+extern void mjit_update_references(const rb_iseq_t *iseq);
+extern void mjit_mark(void);
+extern struct mjit_cont *mjit_cont_new(rb_execution_context_t *ec);
+extern void mjit_cont_free(struct mjit_cont *cont);
+extern void mjit_add_class_serial(rb_serial_t class_serial);
+extern void mjit_remove_class_serial(rb_serial_t class_serial);
+extern void mjit_mark_cc_entries(const struct rb_iseq_constant_body *const body);
+
+// A threshold used to reject long iseqs from JITting as such iseqs
+// takes too much time to be compiled.
+#define JIT_ISEQ_SIZE_THRESHOLD 1000
+
+// Return TRUE if given ISeq body should be compiled by MJIT
+static inline int
+mjit_target_iseq_p(struct rb_iseq_constant_body *body)
+{
+ return (body->type == ISEQ_TYPE_METHOD || body->type == ISEQ_TYPE_BLOCK)
+ && !body->builtin_inline_p
+ && body->iseq_size < JIT_ISEQ_SIZE_THRESHOLD;
+}
+
+# ifdef MJIT_HEADER
+NOINLINE(static COLDFUNC VALUE mjit_exec_slowpath(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body));
+# else
+static inline VALUE mjit_exec_slowpath(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body);
+# endif
+static VALUE
+mjit_exec_slowpath(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body)
+{
+ uintptr_t func_i = (uintptr_t)(body->jit_func);
+ ASSUME(func_i <= LAST_JIT_ISEQ_FUNC);
+ switch ((enum rb_mjit_iseq_func)func_i) {
+ case NOT_ADDED_JIT_ISEQ_FUNC:
+ RB_DEBUG_COUNTER_INC(mjit_exec_not_added);
+ if (body->total_calls == mjit_opts.min_calls && mjit_target_iseq_p(body)) {
+ rb_mjit_add_iseq_to_process(iseq);
+ if (UNLIKELY(mjit_opts.wait)) {
+ return rb_mjit_wait_call(ec, body);
+ }
+ }
+ break;
+ case NOT_READY_JIT_ISEQ_FUNC:
+ RB_DEBUG_COUNTER_INC(mjit_exec_not_ready);
+ break;
+ case NOT_COMPILED_JIT_ISEQ_FUNC:
+ RB_DEBUG_COUNTER_INC(mjit_exec_not_compiled);
+ break;
+ default: // to avoid warning with LAST_JIT_ISEQ_FUNC
+ break;
+ }
+ return Qundef;
+}
+
+// Try to execute the current iseq in ec. Use JIT code if it is ready.
+// If it is not, add ISEQ to the compilation queue and return Qundef.
+static inline VALUE
+mjit_exec(rb_execution_context_t *ec)
+{
+ const rb_iseq_t *iseq;
+ struct rb_iseq_constant_body *body;
+
+ if (!mjit_call_p)
+ return Qundef;
+ RB_DEBUG_COUNTER_INC(mjit_exec);
+
+ iseq = ec->cfp->iseq;
+ body = iseq->body;
+ body->total_calls++;
+
+ mjit_func_t func = body->jit_func;
+ if (UNLIKELY((uintptr_t)func <= LAST_JIT_ISEQ_FUNC)) {
+# ifdef MJIT_HEADER
+ RB_DEBUG_COUNTER_INC(mjit_frame_JT2VM);
+# else
+ RB_DEBUG_COUNTER_INC(mjit_frame_VM2VM);
+# endif
+ return mjit_exec_slowpath(ec, iseq, body);
+ }
+
+# ifdef MJIT_HEADER
+ RB_DEBUG_COUNTER_INC(mjit_frame_JT2JT);
+# else
+ RB_DEBUG_COUNTER_INC(mjit_frame_VM2JT);
+# endif
+ RB_DEBUG_COUNTER_INC(mjit_exec_call_func);
+ return func(ec, ec->cfp);
+}
+
+void mjit_child_after_fork(void);
+
+# ifdef MJIT_HEADER
+#define mjit_enabled true
+# else // MJIT_HEADER
+extern bool mjit_enabled;
+# endif // MJIT_HEADER
+VALUE mjit_pause(bool wait_p);
+VALUE mjit_resume(void);
+void mjit_finish(bool close_handle_p);
+
+# else // USE_MJIT
+
+static inline struct mjit_cont *mjit_cont_new(rb_execution_context_t *ec){return NULL;}
+static inline void mjit_cont_free(struct mjit_cont *cont){}
+static inline void mjit_gc_start_hook(void){}
+static inline void mjit_gc_exit_hook(void){}
+static inline void mjit_free_iseq(const rb_iseq_t *iseq){}
+static inline void mjit_mark(void){}
+static inline void mjit_add_class_serial(rb_serial_t class_serial){}
+static inline void mjit_remove_class_serial(rb_serial_t class_serial){}
+static inline VALUE mjit_exec(rb_execution_context_t *ec) { return Qundef; /* unreachable */ }
+static inline void mjit_child_after_fork(void){}
+
+#define mjit_enabled false
+static inline VALUE mjit_pause(bool wait_p){ return Qnil; } // unreachable
+static inline VALUE mjit_resume(void){ return Qnil; } // unreachable
+static inline void mjit_finish(bool close_handle_p){}
+
+# endif // USE_MJIT
+#endif // RUBY_MJIT_H
diff --git a/mjit_compile.c b/mjit_compile.c
new file mode 100644
index 0000000000..c857153e35
--- /dev/null
+++ b/mjit_compile.c
@@ -0,0 +1,606 @@
+/**********************************************************************
+
+ mjit_compile.c - MRI method JIT compiler
+
+ Copyright (C) 2017 Takashi Kokubun <takashikkbn@gmail.com>.
+
+**********************************************************************/
+
+// NOTE: All functions in this file are executed on MJIT worker. So don't
+// call Ruby methods (C functions that may call rb_funcall) or trigger
+// GC (using ZALLOC, xmalloc, xfree, etc.) in this file.
+
+#include "ruby/internal/config.h" // defines USE_MJIT
+
+#if USE_MJIT
+
+#include "internal.h"
+#include "internal/compile.h"
+#include "internal/hash.h"
+#include "internal/object.h"
+#include "internal/variable.h"
+#include "mjit.h"
+#include "vm_core.h"
+#include "vm_callinfo.h"
+#include "vm_exec.h"
+#include "vm_insnhelper.h"
+
+#include "builtin.h"
+#include "insns.inc"
+#include "insns_info.inc"
+
+// Macros to check if a position is already compiled using compile_status.stack_size_for_pos
+#define NOT_COMPILED_STACK_SIZE -1
+#define ALREADY_COMPILED_P(status, pos) (status->stack_size_for_pos[pos] != NOT_COMPILED_STACK_SIZE)
+
+// For propagating information needed for lazily pushing a frame.
+struct inlined_call_context {
+ int orig_argc; // ci->orig_argc
+ VALUE me; // vm_cc_cme(cc)
+ int param_size; // def_iseq_ptr(vm_cc_cme(cc)->def)->body->param.size
+ int local_size; // def_iseq_ptr(vm_cc_cme(cc)->def)->body->local_table_size
+};
+
+// Storage to keep compiler's status. This should have information
+// which is global during one `mjit_compile` call. Ones conditional
+// in each branch should be stored in `compile_branch`.
+struct compile_status {
+ bool success; // has true if compilation has had no issue
+ int *stack_size_for_pos; // stack_size_for_pos[pos] has stack size for the position (otherwise -1)
+ // If true, JIT-ed code will use local variables to store pushed values instead of
+ // using VM's stack and moving stack pointer.
+ bool local_stack_p;
+ // Safely-accessible ivar cache entries copied from main thread.
+ union iseq_inline_storage_entry *is_entries;
+ // Index of call cache entries captured to compiled_iseq to be marked on GC
+ int cc_entries_index;
+ // A pointer to root (i.e. not inlined) iseq being compiled.
+ const struct rb_iseq_constant_body *compiled_iseq;
+ int compiled_id; // Just a copy of compiled_iseq->jit_unit->id
+ // Mutated optimization levels
+ struct rb_mjit_compile_info *compile_info;
+ bool merge_ivar_guards_p; // If true, merge guards of ivar accesses
+ rb_serial_t ivar_serial; // ic_serial of IVC in is_entries (used only when merge_ivar_guards_p)
+ size_t max_ivar_index; // Max IVC index in is_entries (used only when merge_ivar_guards_p)
+ // If `inlined_iseqs[pos]` is not NULL, `mjit_compile_body` tries to inline ISeq there.
+ const struct rb_iseq_constant_body **inlined_iseqs;
+ struct inlined_call_context inline_context;
+};
+
+// Storage to keep data which is consistent in each conditional branch.
+// This is created and used for one `compile_insns` call and its values
+// should be copied for extra `compile_insns` call.
+struct compile_branch {
+ unsigned int stack_size; // this simulates sp (stack pointer) of YARV
+ bool finish_p; // if true, compilation in this branch should stop and let another branch to be compiled
+};
+
+struct case_dispatch_var {
+ FILE *f;
+ unsigned int base_pos;
+ VALUE last_value;
+};
+
+static size_t
+call_data_index(CALL_DATA cd, const struct rb_iseq_constant_body *body)
+{
+ return cd - body->call_data;
+}
+
+const struct rb_callcache ** mjit_iseq_cc_entries(const struct rb_iseq_constant_body *const body);
+
+// Using this function to refer to cc_entries allocated by `mjit_capture_cc_entries`
+// instead of storing cc_entries in status directly so that we always refer to a new address
+// returned by `realloc` inside it.
+static const struct rb_callcache **
+captured_cc_entries(const struct compile_status *status)
+{
+ VM_ASSERT(status->cc_entries_index != -1);
+ return mjit_iseq_cc_entries(status->compiled_iseq) + status->cc_entries_index;
+}
+
+// Returns true if call cache is still not obsoleted and vm_cc_cme(cc)->def->type is available.
+static bool
+has_valid_method_type(CALL_CACHE cc)
+{
+ return vm_cc_cme(cc) != NULL;
+}
+
+// Returns true if MJIT thinks this cc's opt_* insn may fallback to opt_send_without_block.
+static bool
+has_cache_for_send(CALL_CACHE cc, int insn)
+{
+ extern bool rb_vm_opt_cfunc_p(CALL_CACHE cc, int insn);
+ return has_valid_method_type(cc) &&
+ !(vm_cc_cme(cc)->def->type == VM_METHOD_TYPE_CFUNC && rb_vm_opt_cfunc_p(cc, insn));
+}
+
+// Returns true if iseq can use fastpath for setup, otherwise NULL. This becomes true in the same condition
+// as CC_SET_FASTPATH (in vm_callee_setup_arg) is called from vm_call_iseq_setup.
+static bool
+fastpath_applied_iseq_p(const CALL_INFO ci, const CALL_CACHE cc, const rb_iseq_t *iseq)
+{
+ extern bool rb_simple_iseq_p(const rb_iseq_t *iseq);
+ return iseq != NULL
+ && !(vm_ci_flag(ci) & VM_CALL_KW_SPLAT) && rb_simple_iseq_p(iseq) // Top of vm_callee_setup_arg. In this case, opt_pc is 0.
+ && vm_ci_argc(ci) == (unsigned int)iseq->body->param.lead_num // exclude argument_arity_error (assumption: `calling->argc == ci->orig_argc` in send insns)
+ && vm_call_iseq_optimizable_p(ci, cc); // CC_SET_FASTPATH condition
+}
+
+// Return true if an object of the klass may be a special const. See: rb_class_of
+static bool
+maybe_special_const_class_p(const VALUE klass)
+{
+ return klass == rb_cFalseClass
+ || klass == rb_cNilClass
+ || klass == rb_cTrueClass
+ || klass == rb_cInteger
+ || klass == rb_cSymbol
+ || klass == rb_cFloat;
+}
+
+static int
+compile_case_dispatch_each(VALUE key, VALUE value, VALUE arg)
+{
+ struct case_dispatch_var *var = (struct case_dispatch_var *)arg;
+ unsigned int offset;
+
+ if (var->last_value != value) {
+ offset = FIX2INT(value);
+ var->last_value = value;
+ fprintf(var->f, " case %d:\n", offset);
+ fprintf(var->f, " goto label_%d;\n", var->base_pos + offset);
+ fprintf(var->f, " break;\n");
+ }
+ return ST_CONTINUE;
+}
+
+// Calling rb_id2str in MJIT worker causes random SEGV. So this is disabled by default.
+static void
+comment_id(FILE *f, ID id)
+{
+#ifdef MJIT_COMMENT_ID
+ VALUE name = rb_id2str(id);
+ const char *p, *e;
+ char c, prev = '\0';
+
+ if (!name) return;
+ p = RSTRING_PTR(name);
+ e = RSTRING_END(name);
+ fputs("/* :\"", f);
+ for (; p < e; ++p) {
+ switch (c = *p) {
+ case '*': case '/': if (prev != (c ^ ('/' ^ '*'))) break;
+ case '\\': case '"': fputc('\\', f);
+ }
+ fputc(c, f);
+ prev = c;
+ }
+ fputs("\" */", f);
+#endif
+}
+
+static void compile_insns(FILE *f, const struct rb_iseq_constant_body *body, unsigned int stack_size,
+ unsigned int pos, struct compile_status *status);
+
+// Main function of JIT compilation, vm_exec_core counterpart for JIT. Compile one insn to `f`, may modify
+// b->stack_size and return next position.
+//
+// When you add a new instruction to insns.def, it would be nice to have JIT compilation support here but
+// it's optional. This JIT compiler just ignores ISeq which includes unknown instruction, and ISeq which
+// does not have it can be compiled as usual.
+static unsigned int
+compile_insn(FILE *f, const struct rb_iseq_constant_body *body, const int insn, const VALUE *operands,
+ const unsigned int pos, struct compile_status *status, struct compile_branch *b)
+{
+ unsigned int next_pos = pos + insn_len(insn);
+
+/*****************/
+ #include "mjit_compile.inc"
+/*****************/
+
+ // If next_pos is already compiled and this branch is not finished yet,
+ // next instruction won't be compiled in C code next and will need `goto`.
+ if (!b->finish_p && next_pos < body->iseq_size && ALREADY_COMPILED_P(status, next_pos)) {
+ fprintf(f, "goto label_%d;\n", next_pos);
+
+ // Verify stack size assumption is the same among multiple branches
+ if ((unsigned int)status->stack_size_for_pos[next_pos] != b->stack_size) {
+ if (mjit_opts.warnings || mjit_opts.verbose)
+ fprintf(stderr, "MJIT warning: JIT stack assumption is not the same between branches (%d != %u)\n",
+ status->stack_size_for_pos[next_pos], b->stack_size);
+ status->success = false;
+ }
+ }
+
+ return next_pos;
+}
+
+// Compile one conditional branch. If it has branchXXX insn, this should be
+// called multiple times for each branch.
+static void
+compile_insns(FILE *f, const struct rb_iseq_constant_body *body, unsigned int stack_size,
+ unsigned int pos, struct compile_status *status)
+{
+ int insn;
+ struct compile_branch branch;
+
+ branch.stack_size = stack_size;
+ branch.finish_p = false;
+
+ while (pos < body->iseq_size && !ALREADY_COMPILED_P(status, pos) && !branch.finish_p) {
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ insn = rb_vm_insn_addr2insn((void *)body->iseq_encoded[pos]);
+#else
+ insn = (int)body->iseq_encoded[pos];
+#endif
+ status->stack_size_for_pos[pos] = (int)branch.stack_size;
+
+ fprintf(f, "\nlabel_%d: /* %s */\n", pos, insn_name(insn));
+ pos = compile_insn(f, body, insn, body->iseq_encoded + (pos+1), pos, status, &branch);
+ if (status->success && branch.stack_size > body->stack_max) {
+ if (mjit_opts.warnings || mjit_opts.verbose)
+ fprintf(stderr, "MJIT warning: JIT stack size (%d) exceeded its max size (%d)\n", branch.stack_size, body->stack_max);
+ status->success = false;
+ }
+ if (!status->success)
+ break;
+ }
+}
+
+// Print the block to cancel inlined method call. It's supporting only `opt_send_without_block` for now.
+static void
+compile_inlined_cancel_handler(FILE *f, const struct rb_iseq_constant_body *body, struct inlined_call_context *inline_context)
+{
+ fprintf(f, "\ncancel:\n");
+ fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel);\n");
+ fprintf(f, " rb_mjit_recompile_inlining(original_iseq);\n");
+
+ // Swap pc/sp set on cancel with original pc/sp.
+ fprintf(f, " const VALUE *current_pc = reg_cfp->pc;\n");
+ fprintf(f, " VALUE *current_sp = reg_cfp->sp;\n");
+ fprintf(f, " reg_cfp->pc = orig_pc;\n");
+ fprintf(f, " reg_cfp->sp = orig_sp;\n\n");
+
+ // Lazily push the current call frame.
+ fprintf(f, " struct rb_calling_info calling;\n");
+ fprintf(f, " calling.block_handler = VM_BLOCK_HANDLER_NONE;\n"); // assumes `opt_send_without_block`
+ fprintf(f, " calling.argc = %d;\n", inline_context->orig_argc);
+ fprintf(f, " calling.recv = reg_cfp->self;\n");
+ fprintf(f, " reg_cfp->self = orig_self;\n");
+ fprintf(f, " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, (const rb_callable_method_entry_t *)0x%"PRIxVALUE", 0, %d, %d);\n\n",
+ inline_context->me, inline_context->param_size, inline_context->local_size); // fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
+
+ // Start usual cancel from here.
+ fprintf(f, " reg_cfp = ec->cfp;\n"); // work on the new frame
+ fprintf(f, " reg_cfp->pc = current_pc;\n");
+ fprintf(f, " reg_cfp->sp = current_sp;\n");
+ for (unsigned int i = 0; i < body->stack_max; i++) { // should be always `status->local_stack_p`
+ fprintf(f, " *(vm_base_ptr(reg_cfp) + %d) = stack[%d];\n", i, i);
+ }
+ // We're not just returning Qundef here so that caller's normal cancel handler can
+ // push back `stack` to `cfp->sp`.
+ fprintf(f, " return vm_exec(ec, false);\n");
+}
+
+// Print the block to cancel JIT execution.
+static void
+compile_cancel_handler(FILE *f, const struct rb_iseq_constant_body *body, struct compile_status *status)
+{
+ if (status->inlined_iseqs == NULL) { // the current ISeq is being inlined
+ compile_inlined_cancel_handler(f, body, &status->inline_context);
+ return;
+ }
+
+ fprintf(f, "\nsend_cancel:\n");
+ fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_send_inline);\n");
+ fprintf(f, " rb_mjit_recompile_send(original_iseq);\n");
+ fprintf(f, " goto cancel;\n");
+
+ fprintf(f, "\nivar_cancel:\n");
+ fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_ivar_inline);\n");
+ fprintf(f, " rb_mjit_recompile_ivar(original_iseq);\n");
+ fprintf(f, " goto cancel;\n");
+
+ fprintf(f, "\nexivar_cancel:\n");
+ fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_exivar_inline);\n");
+ fprintf(f, " rb_mjit_recompile_exivar(original_iseq);\n");
+ fprintf(f, " goto cancel;\n");
+
+ fprintf(f, "\nconst_cancel:\n");
+ fprintf(f, " rb_mjit_recompile_const(original_iseq);\n");
+ fprintf(f, " goto cancel;\n");
+
+ fprintf(f, "\ncancel:\n");
+ fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel);\n");
+ if (status->local_stack_p) {
+ for (unsigned int i = 0; i < body->stack_max; i++) {
+ fprintf(f, " *(vm_base_ptr(reg_cfp) + %d) = stack[%d];\n", i, i);
+ }
+ }
+ fprintf(f, " return Qundef;\n");
+}
+
+extern int
+mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq);
+
+// Copy current is_entries and use it throughout the current compilation consistently.
+// While ic->entry has been immutable since https://github.com/ruby/ruby/pull/3662,
+// we still need this to avoid a race condition between entries and ivar_serial/max_ivar_index.
+static void
+mjit_capture_is_entries(const struct rb_iseq_constant_body *body, union iseq_inline_storage_entry *is_entries)
+{
+ if (is_entries == NULL)
+ return;
+ memcpy(is_entries, body->is_entries, sizeof(union iseq_inline_storage_entry) * body->is_size);
+}
+
+static bool
+mjit_compile_body(FILE *f, const rb_iseq_t *iseq, struct compile_status *status)
+{
+ const struct rb_iseq_constant_body *body = iseq->body;
+ status->success = true;
+ status->local_stack_p = !body->catch_except_p;
+
+ if (status->local_stack_p) {
+ fprintf(f, " VALUE stack[%d];\n", body->stack_max);
+ }
+ else {
+ fprintf(f, " VALUE *stack = reg_cfp->sp;\n");
+ }
+ if (status->inlined_iseqs != NULL) // i.e. compile root
+ fprintf(f, " static const rb_iseq_t *original_iseq = (const rb_iseq_t *)0x%"PRIxVALUE";\n", (VALUE)iseq);
+ fprintf(f, " static const VALUE *const original_body_iseq = (VALUE *)0x%"PRIxVALUE";\n",
+ (VALUE)body->iseq_encoded);
+ fprintf(f, " VALUE cfp_self = reg_cfp->self;\n"); // cache self across the method
+ fprintf(f, "#define GET_SELF() cfp_self\n");
+
+ // Generate merged ivar guards first if needed
+ if (!status->compile_info->disable_ivar_cache && status->merge_ivar_guards_p) {
+ fprintf(f, " if (UNLIKELY(!(RB_TYPE_P(GET_SELF(), T_OBJECT) && (rb_serial_t)%"PRI_SERIALT_PREFIX"u == RCLASS_SERIAL(RBASIC(GET_SELF())->klass) &&", status->ivar_serial);
+ if (status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX) {
+ fprintf(f, "%"PRIuSIZE" < ROBJECT_NUMIV(GET_SELF())", status->max_ivar_index); // index < ROBJECT_NUMIV(obj) && !RB_FL_ANY_RAW(obj, ROBJECT_EMBED)
+ }
+ else {
+ fprintf(f, "ROBJECT_EMBED_LEN_MAX == ROBJECT_NUMIV(GET_SELF())"); // index < ROBJECT_NUMIV(obj) && RB_FL_ANY_RAW(obj, ROBJECT_EMBED)
+ }
+ fprintf(f, "))) {\n");
+ fprintf(f, " goto ivar_cancel;\n");
+ fprintf(f, " }\n");
+ }
+
+ // Simulate `opt_pc` in setup_parameters_complex. Other PCs which may be passed by catch tables
+ // are not considered since vm_exec doesn't call mjit_exec for catch tables.
+ if (body->param.flags.has_opt) {
+ int i;
+ fprintf(f, "\n");
+ fprintf(f, " switch (reg_cfp->pc - reg_cfp->iseq->body->iseq_encoded) {\n");
+ for (i = 0; i <= body->param.opt_num; i++) {
+ VALUE pc_offset = body->param.opt_table[i];
+ fprintf(f, " case %"PRIdVALUE":\n", pc_offset);
+ fprintf(f, " goto label_%"PRIdVALUE";\n", pc_offset);
+ }
+ fprintf(f, " }\n");
+ }
+
+ compile_insns(f, body, 0, 0, status);
+ compile_cancel_handler(f, body, status);
+ fprintf(f, "#undef GET_SELF");
+ return status->success;
+}
+
+// Return true if the ISeq can be inlined without pushing a new control frame.
+static bool
+inlinable_iseq_p(const struct rb_iseq_constant_body *body)
+{
+ // 1) If catch_except_p, caller frame should be preserved when callee catches an exception.
+ // Then we need to wrap `vm_exec()` but then we can't inline the call inside it.
+ //
+ // 2) If `body->catch_except_p` is false and `handles_sp?` of an insn is false,
+ // sp is not moved as we assume `status->local_stack_p = !body->catch_except_p`.
+ //
+ // 3) If `body->catch_except_p` is false and `always_leaf?` of an insn is true,
+ // pc is not moved.
+ if (body->catch_except_p)
+ return false;
+
+ unsigned int pos = 0;
+ while (pos < body->iseq_size) {
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ int insn = rb_vm_insn_addr2insn((void *)body->iseq_encoded[pos]);
+#else
+ int insn = (int)body->iseq_encoded[pos];
+#endif
+ // All insns in the ISeq except `leave` (to be overridden in the inlined code)
+ // should meet following strong assumptions:
+ // * Do not require `cfp->sp` motion
+ // * Do not move `cfp->pc`
+ // * Do not read any `cfp->pc`
+ if (insn == BIN(invokebuiltin) || insn == BIN(opt_invokebuiltin_delegate) || insn == BIN(opt_invokebuiltin_delegate_leave)) {
+ // builtin insn's inlinability is handled by `Primitive.attr! 'inline'` per iseq
+ if (!body->builtin_inline_p)
+ return false;
+ }
+ else if (insn != BIN(leave) && insn_may_depend_on_sp_or_pc(insn, body->iseq_encoded + (pos + 1)))
+ return false;
+ // At this moment, `cfp->ep` in an inlined method is not working.
+ switch (insn) {
+ case BIN(getlocal):
+ case BIN(getlocal_WC_0):
+ case BIN(getlocal_WC_1):
+ case BIN(setlocal):
+ case BIN(setlocal_WC_0):
+ case BIN(setlocal_WC_1):
+ case BIN(getblockparam):
+ case BIN(getblockparamproxy):
+ case BIN(setblockparam):
+ return false;
+ }
+ pos += insn_len(insn);
+ }
+ return true;
+}
+
+// Return an iseq pointer if cc has inlinable iseq.
+const rb_iseq_t *
+rb_mjit_inlinable_iseq(const struct rb_callinfo *ci, const struct rb_callcache *cc)
+{
+ const rb_iseq_t *iseq;
+ if (has_valid_method_type(cc) &&
+ !(vm_ci_flag(ci) & VM_CALL_TAILCALL) && // inlining only non-tailcall path
+ vm_cc_cme(cc)->def->type == VM_METHOD_TYPE_ISEQ &&
+ fastpath_applied_iseq_p(ci, cc, iseq = def_iseq_ptr(vm_cc_cme(cc)->def)) &&
+ // CC_SET_FASTPATH in vm_callee_setup_arg
+ inlinable_iseq_p(iseq->body)) {
+ return iseq;
+ }
+ return NULL;
+}
+
+static void
+init_ivar_compile_status(const struct rb_iseq_constant_body *body, struct compile_status *status)
+{
+ mjit_capture_is_entries(body, status->is_entries);
+
+ int num_ivars = 0;
+ unsigned int pos = 0;
+ status->max_ivar_index = 0;
+ status->ivar_serial = 0;
+
+ while (pos < body->iseq_size) {
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ int insn = rb_vm_insn_addr2insn((void *)body->iseq_encoded[pos]);
+#else
+ int insn = (int)body->iseq_encoded[pos];
+#endif
+ if (insn == BIN(getinstancevariable) || insn == BIN(setinstancevariable)) {
+ IVC ic = (IVC)body->iseq_encoded[pos+2];
+ IVC ic_copy = &(status->is_entries + ((union iseq_inline_storage_entry *)ic - body->is_entries))->iv_cache;
+ if (ic_copy->entry) { // Only initialized (ic_serial > 0) IVCs are optimized
+ num_ivars++;
+
+ if (status->max_ivar_index < ic_copy->entry->index) {
+ status->max_ivar_index = ic_copy->entry->index;
+ }
+
+ if (status->ivar_serial == 0) {
+ status->ivar_serial = ic_copy->entry->class_serial;
+ }
+ else if (status->ivar_serial != ic_copy->entry->class_serial) {
+ // Multiple classes have used this ISeq. Give up assuming one serial.
+ status->merge_ivar_guards_p = false;
+ return;
+ }
+ }
+ }
+ pos += insn_len(insn);
+ }
+ status->merge_ivar_guards_p = status->ivar_serial > 0 && num_ivars >= 2;
+}
+
+// This needs to be macro instead of a function because it's using `alloca`.
+#define INIT_COMPILE_STATUS(status, body, compile_root_p) do { \
+ status = (struct compile_status){ \
+ .stack_size_for_pos = (int *)alloca(sizeof(int) * body->iseq_size), \
+ .inlined_iseqs = compile_root_p ? \
+ alloca(sizeof(const struct rb_iseq_constant_body *) * body->iseq_size) : NULL, \
+ .is_entries = (body->is_size > 0) ? \
+ alloca(sizeof(union iseq_inline_storage_entry) * body->is_size) : NULL, \
+ .cc_entries_index = (body->ci_size > 0) ? \
+ mjit_capture_cc_entries(status.compiled_iseq, body) : -1, \
+ .compiled_id = status.compiled_id, \
+ .compiled_iseq = status.compiled_iseq, \
+ .compile_info = compile_root_p ? \
+ rb_mjit_iseq_compile_info(body) : alloca(sizeof(struct rb_mjit_compile_info)) \
+ }; \
+ memset(status.stack_size_for_pos, NOT_COMPILED_STACK_SIZE, sizeof(int) * body->iseq_size); \
+ if (compile_root_p) \
+ memset((void *)status.inlined_iseqs, 0, sizeof(const struct rb_iseq_constant_body *) * body->iseq_size); \
+ else \
+ memset(status.compile_info, 0, sizeof(struct rb_mjit_compile_info)); \
+} while (0)
+
+// Compile inlinable ISeqs to C code in `f`. It returns true if it succeeds to compile them.
+static bool
+precompile_inlinable_iseqs(FILE *f, const rb_iseq_t *iseq, struct compile_status *status)
+{
+ const struct rb_iseq_constant_body *body = iseq->body;
+ unsigned int pos = 0;
+ while (pos < body->iseq_size) {
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ int insn = rb_vm_insn_addr2insn((void *)body->iseq_encoded[pos]);
+#else
+ int insn = (int)body->iseq_encoded[pos];
+#endif
+ if (insn == BIN(opt_send_without_block)) { // `compile_inlined_cancel_handler` supports only `opt_send_without_block`
+ CALL_DATA cd = (CALL_DATA)body->iseq_encoded[pos + 1];
+ const struct rb_callinfo *ci = cd->ci;
+ const struct rb_callcache *cc = captured_cc_entries(status)[call_data_index(cd, body)]; // use copy to avoid race condition
+
+ extern bool rb_mjit_compiling_iseq_p(const rb_iseq_t *iseq);
+ const rb_iseq_t *child_iseq;
+ if ((child_iseq = rb_mjit_inlinable_iseq(ci, cc)) != NULL && rb_mjit_compiling_iseq_p(child_iseq)) {
+ status->inlined_iseqs[pos] = child_iseq->body;
+
+ if (mjit_opts.verbose >= 1) // print beforehand because ISeq may be GCed during copy job.
+ fprintf(stderr, "JIT inline: %s@%s:%d => %s@%s:%d\n",
+ RSTRING_PTR(child_iseq->body->location.label),
+ RSTRING_PTR(rb_iseq_path(child_iseq)), FIX2INT(child_iseq->body->location.first_lineno),
+ RSTRING_PTR(iseq->body->location.label),
+ RSTRING_PTR(rb_iseq_path(iseq)), FIX2INT(iseq->body->location.first_lineno));
+
+ struct compile_status child_status = { .compiled_iseq = status->compiled_iseq, .compiled_id = status->compiled_id };
+ INIT_COMPILE_STATUS(child_status, child_iseq->body, false);
+ child_status.inline_context = (struct inlined_call_context){
+ .orig_argc = vm_ci_argc(ci),
+ .me = (VALUE)vm_cc_cme(cc),
+ .param_size = child_iseq->body->param.size,
+ .local_size = child_iseq->body->local_table_size
+ };
+ if (child_iseq->body->ci_size > 0 && child_status.cc_entries_index == -1) {
+ return false;
+ }
+ init_ivar_compile_status(child_iseq->body, &child_status);
+
+ fprintf(f, "ALWAYS_INLINE(static VALUE _mjit%d_inlined_%d(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq));\n", status->compiled_id, pos);
+ fprintf(f, "static inline VALUE\n_mjit%d_inlined_%d(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq)\n{\n", status->compiled_id, pos);
+ fprintf(f, " const VALUE *orig_pc = reg_cfp->pc;\n");
+ fprintf(f, " VALUE *orig_sp = reg_cfp->sp;\n");
+ bool success = mjit_compile_body(f, child_iseq, &child_status);
+ fprintf(f, "\n} /* end of _mjit%d_inlined_%d */\n\n", status->compiled_id, pos);
+
+ if (!success)
+ return false;
+ }
+ }
+ pos += insn_len(insn);
+ }
+ return true;
+}
+
+// Compile ISeq to C code in `f`. It returns true if it succeeds to compile.
+bool
+mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
+{
+ struct compile_status status = { .compiled_iseq = iseq->body, .compiled_id = id };
+ INIT_COMPILE_STATUS(status, iseq->body, true);
+ if (iseq->body->ci_size > 0 && status.cc_entries_index == -1) {
+ return false;
+ }
+ init_ivar_compile_status(iseq->body, &status);
+
+ if (!status.compile_info->disable_send_cache && !status.compile_info->disable_inlining) {
+ if (!precompile_inlinable_iseqs(f, iseq, &status))
+ return false;
+ }
+
+#ifdef _WIN32
+ fprintf(f, "__declspec(dllexport)\n");
+#endif
+ fprintf(f, "VALUE\n%s(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)\n{\n", funcname);
+ bool success = mjit_compile_body(f, iseq, &status);
+ fprintf(f, "\n} // end of %s\n", funcname);
+ return success;
+}
+
+#endif // USE_MJIT
diff --git a/mjit_worker.c b/mjit_worker.c
new file mode 100644
index 0000000000..f7f0b6bced
--- /dev/null
+++ b/mjit_worker.c
@@ -0,0 +1,1528 @@
+/**********************************************************************
+
+ mjit_worker.c - Worker for MRI method JIT compiler
+
+ Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
+
+**********************************************************************/
+
+// NOTE: All functions in this file are executed on MJIT worker. So don't
+// call Ruby methods (C functions that may call rb_funcall) or trigger
+// GC (using ZALLOC, xmalloc, xfree, etc.) in this file.
+
+/* However, note that calling `free` for resources `xmalloc`-ed in mjit.c,
+ which is currently done in some places, is sometimes problematic in the
+ following situations:
+
+ * malloc library could be different between interpreter and extensions
+ on Windows (perhaps not applicable to MJIT because CC is the same)
+ * xmalloc -> free leaks extra space used for USE_GC_MALLOC_OBJ_INFO_DETAILS
+ (not enabled by default)
+
+ ...in short, it's usually not a problem in MJIT. But maybe it's worth
+ fixing for consistency or for USE_GC_MALLOC_OBJ_INFO_DETAILS support.
+*/
+
+/* We utilize widely used C compilers (GCC and LLVM Clang) to
+ implement MJIT. We feed them a C code generated from ISEQ. The
+ industrial C compilers are slower than regular JIT engines.
+ Generated code performance of the used C compilers has a higher
+ priority over the compilation speed.
+
+ So our major goal is to minimize the ISEQ compilation time when we
+ use widely optimization level (-O2). It is achieved by
+
+ o Using a precompiled version of the header
+ o Keeping all files in `/tmp`. On modern Linux `/tmp` is a file
+ system in memory. So it is pretty fast
+ o Implementing MJIT as a multi-threaded code because we want to
+ compile ISEQs in parallel with iseq execution to speed up Ruby
+ code execution. MJIT has one thread (*worker*) to do
+ parallel compilations:
+ o It prepares a precompiled code of the minimized header.
+ It starts at the MRI execution start
+ o It generates PIC object files of ISEQs
+ o It takes one JIT unit from a priority queue unless it is empty.
+ o It translates the JIT unit ISEQ into C-code using the precompiled
+ header, calls CC and load PIC code when it is ready
+ o Currently MJIT put ISEQ in the queue when ISEQ is called
+ o MJIT can reorder ISEQs in the queue if some ISEQ has been called
+ many times and its compilation did not start yet
+ o MRI reuses the machine code if it already exists for ISEQ
+ o The machine code we generate can stop and switch to the ISEQ
+ interpretation if some condition is not satisfied as the machine
+ code can be speculative or some exception raises
+ o Speculative machine code can be canceled.
+
+ Here is a diagram showing the MJIT organization:
+
+ _______
+ |header |
+ |_______|
+ | MRI building
+ --------------|----------------------------------------
+ | MRI execution
+ |
+ _____________|_____
+ | | |
+ | ___V__ | CC ____________________
+ | | |----------->| precompiled header |
+ | | | | |____________________|
+ | | | | |
+ | | MJIT | | |
+ | | | | |
+ | | | | ____V___ CC __________
+ | |______|----------->| C code |--->| .so file |
+ | | |________| |__________|
+ | | |
+ | | |
+ | MRI machine code |<-----------------------------
+ |___________________| loading
+
+*/
+
+#ifdef __sun
+#define __EXTENSIONS__ 1
+#endif
+
+#include "vm_core.h"
+#include "vm_callinfo.h"
+#include "mjit.h"
+#include "gc.h"
+#include "ruby_assert.h"
+#include "ruby/debug.h"
+#include "ruby/thread.h"
+#include "ruby/version.h"
+#include "builtin.h"
+#include "insns.inc"
+#include "insns_info.inc"
+#include "internal/compile.h"
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <windows.h>
+#else
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <dlfcn.h>
+#endif
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#include "dln.h"
+
+#include "ruby/util.h"
+#undef strdup // ruby_strdup may trigger GC
+
+#ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+#endif
+
+#ifdef _WIN32
+#define dlopen(name,flag) ((void*)LoadLibrary(name))
+#define dlerror() strerror(rb_w32_map_errno(GetLastError()))
+#define dlsym(handle,name) ((void*)GetProcAddress((handle),(name)))
+#define dlclose(handle) (!FreeLibrary(handle))
+#define RTLD_NOW -1
+
+#define waitpid(pid,stat_loc,options) (WaitForSingleObject((HANDLE)(pid), INFINITE), GetExitCodeProcess((HANDLE)(pid), (LPDWORD)(stat_loc)), CloseHandle((HANDLE)pid), (pid))
+#define WIFEXITED(S) ((S) != STILL_ACTIVE)
+#define WEXITSTATUS(S) (S)
+#define WIFSIGNALED(S) (0)
+typedef intptr_t pid_t;
+#endif
+
+// Atomically set function pointer if possible.
+#define MJIT_ATOMIC_SET(var, val) (void)ATOMIC_PTR_EXCHANGE(var, val)
+
+#define MJIT_TMP_PREFIX "_ruby_mjit_"
+
+// JIT compaction requires the header transformation because linking multiple .o files
+// doesn't work without having `static` in the same function definitions. We currently
+// don't support transforming the MJIT header on Windows.
+#ifdef _WIN32
+# define USE_JIT_COMPACTION 0
+#else
+# define USE_JIT_COMPACTION 1
+#endif
+
+// The unit structure that holds metadata of ISeq for MJIT.
+struct rb_mjit_unit {
+ struct list_node unode;
+ // Unique order number of unit.
+ int id;
+ // Dlopen handle of the loaded object file.
+ void *handle;
+ rb_iseq_t *iseq;
+#if defined(_WIN32)
+ // DLL cannot be removed while loaded on Windows. If this is set, it'll be lazily deleted.
+ char *so_file;
+#endif
+ // Only used by unload_units. Flag to check this unit is currently on stack or not.
+ bool used_code_p;
+ // True if this is still in active_units but it's to be lazily removed
+ bool stale_p;
+ // mjit_compile's optimization switches
+ struct rb_mjit_compile_info compile_info;
+ // captured CC values, they should be marked with iseq.
+ const struct rb_callcache **cc_entries;
+ unsigned int cc_entries_size; // iseq->body->ci_size + ones of inlined iseqs
+};
+
+// Linked list of struct rb_mjit_unit.
+struct rb_mjit_unit_list {
+ struct list_head head;
+ int length; // the list length
+};
+
+extern void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
+extern void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);
+extern void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);
+extern void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);
+
+extern void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
+extern void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
+extern void rb_native_cond_signal(rb_nativethread_cond_t *cond);
+extern void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
+extern void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
+
+// process.c
+extern rb_pid_t ruby_waitpid_locked(rb_vm_t *, rb_pid_t, int *status, int options, rb_nativethread_cond_t *cond);
+
+// A copy of MJIT portion of MRI options since MJIT initialization. We
+// need them as MJIT threads still can work when the most MRI data were
+// freed.
+struct mjit_options mjit_opts;
+
+// true if MJIT is enabled.
+bool mjit_enabled = false;
+// true if JIT-ed code should be called. When `ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS`
+// and `mjit_call_p == false`, any JIT-ed code execution is cancelled as soon as possible.
+bool mjit_call_p = false;
+
+// Priority queue of iseqs waiting for JIT compilation.
+// This variable is a pointer to head unit of the queue.
+static struct rb_mjit_unit_list unit_queue = { LIST_HEAD_INIT(unit_queue.head) };
+// List of units which are successfully compiled.
+static struct rb_mjit_unit_list active_units = { LIST_HEAD_INIT(active_units.head) };
+// List of compacted so files which will be cleaned up by `free_list()` in `mjit_finish()`.
+static struct rb_mjit_unit_list compact_units = { LIST_HEAD_INIT(compact_units.head) };
+// List of units before recompilation and just waiting for dlclose().
+static struct rb_mjit_unit_list stale_units = { LIST_HEAD_INIT(stale_units.head) };
+// The number of so far processed ISEQs, used to generate unique id.
+static int current_unit_num;
+// A mutex for conitionals and critical sections.
+static rb_nativethread_lock_t mjit_engine_mutex;
+// A thread conditional to wake up `mjit_finish` at the end of PCH thread.
+static rb_nativethread_cond_t mjit_pch_wakeup;
+// A thread conditional to wake up the client if there is a change in
+// executed unit status.
+static rb_nativethread_cond_t mjit_client_wakeup;
+// A thread conditional to wake up a worker if there we have something
+// to add or we need to stop MJIT engine.
+static rb_nativethread_cond_t mjit_worker_wakeup;
+// A thread conditional to wake up workers if at the end of GC.
+static rb_nativethread_cond_t mjit_gc_wakeup;
+// Greater than 0 when GC is working.
+static int in_gc = 0;
+// True when JIT is working.
+static bool in_jit = false;
+// True when active_units has at least one stale_p=true unit.
+static bool pending_stale_p = false;
+// The times when unload_units is requested. unload_units is called after some requests.
+static int unload_requests = 0;
+// The total number of unloaded units.
+static int total_unloads = 0;
+// Set to true to stop worker.
+static bool stop_worker_p;
+// Set to true if worker is stopped.
+static bool worker_stopped;
+
+// Path of "/tmp", which can be changed to $TMP in MinGW.
+static char *tmp_dir;
+// Hash like { 1 => true, 2 => true, ... } whose keys are valid `class_serial`s.
+// This is used to invalidate obsoleted CALL_CACHE.
+static VALUE valid_class_serials;
+
+// Used C compiler path.
+static const char *cc_path;
+// Used C compiler flags.
+static const char **cc_common_args;
+// Used C compiler flags added by --jit-debug=...
+static char **cc_added_args;
+// Name of the precompiled header file.
+static char *pch_file;
+// The process id which should delete the pch_file on mjit_finish.
+static rb_pid_t pch_owner_pid;
+// Status of the precompiled header creation. The status is
+// shared by the workers and the pch thread.
+static enum {PCH_NOT_READY, PCH_FAILED, PCH_SUCCESS} pch_status;
+
+#ifndef _MSC_VER
+// Name of the header file.
+static char *header_file;
+#endif
+
+#ifdef _WIN32
+// Linker option to enable libruby.
+static char *libruby_pathflag;
+#endif
+
+#include "mjit_config.h"
+
+#if defined(__GNUC__) && \
+ (!defined(__clang__) || \
+ (defined(__clang__) && (defined(__FreeBSD__) || defined(__GLIBC__))))
+# define GCC_PIC_FLAGS "-Wfatal-errors", "-fPIC", "-shared", "-w", "-pipe",
+# define MJIT_CFLAGS_PIPE 1
+#else
+# define GCC_PIC_FLAGS /* empty */
+# define MJIT_CFLAGS_PIPE 0
+#endif
+
+// Use `-nodefaultlibs -nostdlib` for GCC where possible, which does not work on mingw, cygwin, AIX, and OpenBSD.
+// This seems to improve MJIT performance on GCC.
+#if defined __GNUC__ && !defined __clang__ && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(_AIX) && !defined(__OpenBSD__)
+# define GCC_NOSTDLIB_FLAGS "-nodefaultlibs", "-nostdlib",
+#else
+# define GCC_NOSTDLIB_FLAGS // empty
+#endif
+
+static const char *const CC_COMMON_ARGS[] = {
+ MJIT_CC_COMMON MJIT_CFLAGS GCC_PIC_FLAGS
+ NULL
+};
+
+static const char *const CC_DEBUG_ARGS[] = {MJIT_DEBUGFLAGS NULL};
+static const char *const CC_OPTIMIZE_ARGS[] = {MJIT_OPTFLAGS NULL};
+
+static const char *const CC_LDSHARED_ARGS[] = {MJIT_LDSHARED GCC_PIC_FLAGS NULL};
+static const char *const CC_DLDFLAGS_ARGS[] = {MJIT_DLDFLAGS NULL};
+// `CC_LINKER_ARGS` are linker flags which must be passed to `-c` as well.
+static const char *const CC_LINKER_ARGS[] = {
+#if defined __GNUC__ && !defined __clang__ && !defined(__OpenBSD__)
+ "-nostartfiles",
+#endif
+ GCC_NOSTDLIB_FLAGS NULL
+};
+
+static const char *const CC_LIBS[] = {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ MJIT_LIBS // mswin, mingw, cygwin
+#endif
+#if defined __GNUC__ && !defined __clang__
+# if defined(_WIN32)
+ "-lmsvcrt", // mingw
+# endif
+ "-lgcc", // mingw, cygwin, and GCC platforms using `-nodefaultlibs -nostdlib`
+#endif
+#if defined __ANDROID__
+ "-lm", // to avoid 'cannot locate symbol "modf" referenced by .../_ruby_mjit_XXX.so"'
+#endif
+ NULL
+};
+
+#define CC_CODEFLAG_ARGS (mjit_opts.debug ? CC_DEBUG_ARGS : CC_OPTIMIZE_ARGS)
+
+// Print the arguments according to FORMAT to stderr only if MJIT
+// verbose option value is more or equal to LEVEL.
+PRINTF_ARGS(static void, 2, 3)
+verbose(int level, const char *format, ...)
+{
+ if (mjit_opts.verbose >= level) {
+ va_list args;
+ size_t len = strlen(format);
+ char *full_format = alloca(sizeof(char) * (len + 2));
+
+ // Creating `format + '\n'` to atomically print format and '\n'.
+ memcpy(full_format, format, len);
+ full_format[len] = '\n';
+ full_format[len+1] = '\0';
+
+ va_start(args, format);
+ vfprintf(stderr, full_format, args);
+ va_end(args);
+ }
+}
+
+PRINTF_ARGS(static void, 1, 2)
+mjit_warning(const char *format, ...)
+{
+ if (mjit_opts.warnings || mjit_opts.verbose) {
+ va_list args;
+
+ fprintf(stderr, "MJIT warning: ");
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ }
+}
+
+// Add unit node to the tail of doubly linked `list`. It should be not in
+// the list before.
+static void
+add_to_list(struct rb_mjit_unit *unit, struct rb_mjit_unit_list *list)
+{
+ (void)RB_DEBUG_COUNTER_INC_IF(mjit_length_unit_queue, list == &unit_queue);
+ (void)RB_DEBUG_COUNTER_INC_IF(mjit_length_active_units, list == &active_units);
+ (void)RB_DEBUG_COUNTER_INC_IF(mjit_length_compact_units, list == &compact_units);
+ (void)RB_DEBUG_COUNTER_INC_IF(mjit_length_stale_units, list == &stale_units);
+
+ list_add_tail(&list->head, &unit->unode);
+ list->length++;
+}
+
+static void
+remove_from_list(struct rb_mjit_unit *unit, struct rb_mjit_unit_list *list)
+{
+#if USE_DEBUG_COUNTER
+ rb_debug_counter_add(RB_DEBUG_COUNTER_mjit_length_unit_queue, -1, list == &unit_queue);
+ rb_debug_counter_add(RB_DEBUG_COUNTER_mjit_length_active_units, -1, list == &active_units);
+ rb_debug_counter_add(RB_DEBUG_COUNTER_mjit_length_compact_units, -1, list == &compact_units);
+ rb_debug_counter_add(RB_DEBUG_COUNTER_mjit_length_stale_units, -1, list == &stale_units);
+#endif
+
+ list_del(&unit->unode);
+ list->length--;
+}
+
+static void
+remove_file(const char *filename)
+{
+ if (remove(filename)) {
+ mjit_warning("failed to remove \"%s\": %s", filename, strerror(errno));
+ }
+}
+
+// Lazily delete .so files.
+static void
+clean_temp_files(struct rb_mjit_unit *unit)
+{
+#if defined(_WIN32)
+ if (unit->so_file) {
+ char *so_file = unit->so_file;
+
+ unit->so_file = NULL;
+ // unit->so_file is set only when mjit_opts.save_temps is false.
+ remove_file(so_file);
+ free(so_file);
+ }
+#endif
+}
+
+// This is called in the following situations:
+// 1) On dequeue or `unload_units()`, associated ISeq is already GCed.
+// 2) The unit is not called often and unloaded by `unload_units()`.
+// 3) Freeing lists on `mjit_finish()`.
+//
+// `jit_func` value does not matter for 1 and 3 since the unit won't be used anymore.
+// For the situation 2, this sets the ISeq's JIT state to NOT_COMPILED_JIT_ISEQ_FUNC
+// to prevent the situation that the same methods are continuously compiled.
+static void
+free_unit(struct rb_mjit_unit *unit)
+{
+ if (unit->iseq) { // ISeq is not GCed
+ unit->iseq->body->jit_func = (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
+ unit->iseq->body->jit_unit = NULL;
+ }
+ if (unit->cc_entries) {
+ void *entries = (void *)unit->cc_entries;
+ free(entries);
+ }
+ if (unit->handle && dlclose(unit->handle)) { // handle is NULL if it's in queue
+ mjit_warning("failed to close handle for u%d: %s", unit->id, dlerror());
+ }
+ clean_temp_files(unit);
+ free(unit);
+}
+
+// Start a critical section. Use message `msg` to print debug info at `level`.
+static inline void
+CRITICAL_SECTION_START(int level, const char *msg)
+{
+ verbose(level, "Locking %s", msg);
+ rb_native_mutex_lock(&mjit_engine_mutex);
+ verbose(level, "Locked %s", msg);
+}
+
+// Finish the current critical section. Use message `msg` to print
+// debug info at `level`.
+static inline void
+CRITICAL_SECTION_FINISH(int level, const char *msg)
+{
+ verbose(level, "Unlocked %s", msg);
+ rb_native_mutex_unlock(&mjit_engine_mutex);
+}
+
+static int
+sprint_uniq_filename(char *str, size_t size, unsigned long id, const char *prefix, const char *suffix)
+{
+ return snprintf(str, size, "%s/%sp%"PRI_PIDT_PREFIX"uu%lu%s", tmp_dir, prefix, getpid(), id, suffix);
+}
+
+// Return time in milliseconds as a double.
+#ifdef __APPLE__
+double ruby_real_ms_time(void);
+# define real_ms_time() ruby_real_ms_time()
+#else
+static double
+real_ms_time(void)
+{
+# ifdef HAVE_CLOCK_GETTIME
+ struct timespec tv;
+# ifdef CLOCK_MONOTONIC
+ const clockid_t c = CLOCK_MONOTONIC;
+# else
+ const clockid_t c = CLOCK_REALTIME;
+# endif
+
+ clock_gettime(c, &tv);
+ return tv.tv_nsec / 1000000.0 + tv.tv_sec * 1000.0;
+# else
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return tv.tv_usec / 1000.0 + tv.tv_sec * 1000.0;
+# endif
+}
+#endif
+
+// Return true if class_serial is not obsoleted. This is used by mjit_compile.c.
+bool
+mjit_valid_class_serial_p(rb_serial_t class_serial)
+{
+ CRITICAL_SECTION_START(3, "in valid_class_serial_p");
+ bool found_p = rb_hash_stlike_lookup(valid_class_serials, LONG2FIX(class_serial), NULL);
+ CRITICAL_SECTION_FINISH(3, "in valid_class_serial_p");
+ return found_p;
+}
+
+// Return the best unit from list. The best is the first
+// high priority unit or the unit whose iseq has the biggest number
+// of calls so far.
+static struct rb_mjit_unit *
+get_from_list(struct rb_mjit_unit_list *list)
+{
+ while (in_gc) {
+ verbose(3, "Waiting wakeup from GC");
+ rb_native_cond_wait(&mjit_gc_wakeup, &mjit_engine_mutex);
+ }
+ in_jit = true; // Lock GC
+
+ // Find iseq with max total_calls
+ struct rb_mjit_unit *unit = NULL, *next, *best = NULL;
+ list_for_each_safe(&list->head, unit, next, unode) {
+ if (unit->iseq == NULL) { // ISeq is GCed.
+ remove_from_list(unit, list);
+ free_unit(unit);
+ continue;
+ }
+
+ if (best == NULL || best->iseq->body->total_calls < unit->iseq->body->total_calls) {
+ best = unit;
+ }
+ }
+
+ in_jit = false; // Unlock GC
+ verbose(3, "Sending wakeup signal to client in a mjit-worker for GC");
+ rb_native_cond_signal(&mjit_client_wakeup);
+
+ if (best) {
+ remove_from_list(best, list);
+ }
+ return best;
+}
+
+// Return length of NULL-terminated array `args` excluding the NULL marker.
+static size_t
+args_len(char *const *args)
+{
+ size_t i;
+
+ for (i = 0; (args[i]) != NULL;i++)
+ ;
+ return i;
+}
+
+// Concatenate `num` passed NULL-terminated arrays of strings, put the
+// result (with NULL end marker) into the heap, and return the result.
+static char **
+form_args(int num, ...)
+{
+ va_list argp;
+ size_t len, n;
+ int i;
+ char **args, **res, **tmp;
+
+ va_start(argp, num);
+ res = NULL;
+ for (i = len = 0; i < num; i++) {
+ args = va_arg(argp, char **);
+ n = args_len(args);
+ if ((tmp = (char **)realloc(res, sizeof(char *) * (len + n + 1))) == NULL) {
+ free(res);
+ res = NULL;
+ break;
+ }
+ res = tmp;
+ MEMCPY(res + len, args, char *, n + 1);
+ len += n;
+ }
+ va_end(argp);
+ return res;
+}
+
+COMPILER_WARNING_PUSH
+#if __has_warning("-Wdeprecated-declarations") || RBIMPL_COMPILER_IS(GCC)
+COMPILER_WARNING_IGNORED(-Wdeprecated-declarations)
+#endif
+// Start an OS process of absolute executable path with arguments `argv`.
+// Return PID of the process.
+static pid_t
+start_process(const char *abspath, char *const *argv)
+{
+ // Not calling non-async-signal-safe functions between vfork
+ // and execv for safety
+ int dev_null = rb_cloexec_open(ruby_null_device, O_WRONLY, 0);
+ if (dev_null < 0) {
+ verbose(1, "MJIT: Failed to open a null device: %s", strerror(errno));
+ return -1;
+ }
+ if (mjit_opts.verbose >= 2) {
+ const char *arg;
+ fprintf(stderr, "Starting process: %s", abspath);
+ for (int i = 0; (arg = argv[i]) != NULL; i++)
+ fprintf(stderr, " %s", arg);
+ fprintf(stderr, "\n");
+ }
+
+ pid_t pid;
+#ifdef _WIN32
+ extern HANDLE rb_w32_start_process(const char *abspath, char *const *argv, int out_fd);
+ int out_fd = 0;
+ if (mjit_opts.verbose <= 1) {
+ // Discard cl.exe's outputs like:
+ // _ruby_mjit_p12u3.c
+ // Creating library C:.../_ruby_mjit_p12u3.lib and object C:.../_ruby_mjit_p12u3.exp
+ out_fd = dev_null;
+ }
+
+ pid = (pid_t)rb_w32_start_process(abspath, argv, out_fd);
+ if (pid == 0) {
+ verbose(1, "MJIT: Failed to create process: %s", dlerror());
+ return -1;
+ }
+#else
+ if ((pid = vfork()) == 0) { /* TODO: reuse some function in process.c */
+ umask(0077);
+ if (mjit_opts.verbose == 0) {
+ // CC can be started in a thread using a file which has been
+ // already removed while MJIT is finishing. Discard the
+ // messages about missing files.
+ dup2(dev_null, STDERR_FILENO);
+ dup2(dev_null, STDOUT_FILENO);
+ }
+ (void)close(dev_null);
+ pid = execv(abspath, argv); // Pid will be negative on an error
+ // Even if we successfully found CC to compile PCH we still can
+ // fail with loading the CC in very rare cases for some reasons.
+ // Stop the forked process in this case.
+ verbose(1, "MJIT: Error in execv: %s", abspath);
+ _exit(1);
+ }
+#endif
+ (void)close(dev_null);
+ return pid;
+}
+COMPILER_WARNING_POP
+
+// Execute an OS process of executable PATH with arguments ARGV.
+// Return -1 or -2 if failed to execute, otherwise exit code of the process.
+// TODO: Use a similar function in process.c
+static int
+exec_process(const char *path, char *const argv[])
+{
+ int stat, exit_code = -2;
+ rb_vm_t *vm = WAITPID_USE_SIGCHLD ? GET_VM() : 0;
+ rb_nativethread_cond_t cond;
+
+ if (vm) {
+ rb_native_cond_initialize(&cond);
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ }
+
+ pid_t pid = start_process(path, argv);
+ for (;pid > 0;) {
+ pid_t r = vm ? ruby_waitpid_locked(vm, pid, &stat, 0, &cond)
+ : waitpid(pid, &stat, 0);
+ if (r == -1) {
+ if (errno == EINTR) continue;
+ fprintf(stderr, "[%"PRI_PIDT_PREFIX"d] waitpid(%lu): %s (SIGCHLD=%d,%u)\n",
+ getpid(), (unsigned long)pid, strerror(errno),
+ RUBY_SIGCHLD, SIGCHLD_LOSSY);
+ break;
+ }
+ else if (r == pid) {
+ if (WIFEXITED(stat)) {
+ exit_code = WEXITSTATUS(stat);
+ break;
+ }
+ else if (WIFSIGNALED(stat)) {
+ exit_code = -1;
+ break;
+ }
+ }
+ }
+
+ if (vm) {
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+ rb_native_cond_destroy(&cond);
+ }
+ return exit_code;
+}
+
+static void
+remove_so_file(const char *so_file, struct rb_mjit_unit *unit)
+{
+#if defined(_WIN32)
+ // Windows can't remove files while it's used.
+ unit->so_file = strdup(so_file); // lazily delete on `clean_temp_files()`
+ if (unit->so_file == NULL)
+ mjit_warning("failed to allocate memory to lazily remove '%s': %s", so_file, strerror(errno));
+#else
+ remove_file(so_file);
+#endif
+}
+
+// Print _mjitX, but make a human-readable funcname when --jit-debug is used
+static void
+sprint_funcname(char *funcname, const struct rb_mjit_unit *unit)
+{
+ const rb_iseq_t *iseq = unit->iseq;
+ if (iseq == NULL || (!mjit_opts.debug && !mjit_opts.debug_flags)) {
+ sprintf(funcname, "_mjit%d", unit->id);
+ return;
+ }
+
+ // Generate a short path
+ const char *path = RSTRING_PTR(rb_iseq_path(iseq));
+ const char *lib = "/lib/";
+ const char *version = "/" STRINGIZE(RUBY_API_VERSION_MAJOR) "." STRINGIZE(RUBY_API_VERSION_MINOR) "." STRINGIZE(RUBY_API_VERSION_TEENY) "/";
+ while (strstr(path, lib)) // skip "/lib/"
+ path = strstr(path, lib) + strlen(lib);
+ while (strstr(path, version)) // skip "/x.y.z/"
+ path = strstr(path, version) + strlen(version);
+
+ // Annotate all-normalized method names
+ const char *method = RSTRING_PTR(iseq->body->location.label);
+ if (!strcmp(method, "[]")) method = "AREF";
+ if (!strcmp(method, "[]=")) method = "ASET";
+
+ // Print and normalize
+ sprintf(funcname, "_mjit%d_%s_%s", unit->id, path, method);
+ for (size_t i = 0; i < strlen(funcname); i++) {
+ char c = funcname[i];
+ if (!(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_')) {
+ funcname[i] = '_';
+ }
+ }
+}
+
+static const rb_iseq_t **compiling_iseqs = NULL;
+
+static bool
+set_compiling_iseqs(const rb_iseq_t *iseq)
+{
+ compiling_iseqs = calloc(iseq->body->iseq_size + 2, sizeof(rb_iseq_t *)); // 2: 1 (unit->iseq) + 1 (NULL end)
+ if (compiling_iseqs == NULL)
+ return false;
+
+ compiling_iseqs[0] = iseq;
+ int i = 1;
+
+ unsigned int pos = 0;
+ while (pos < iseq->body->iseq_size) {
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ int insn = rb_vm_insn_addr2insn((void *)iseq->body->iseq_encoded[pos]);
+#else
+ int insn = (int)iseq->body->iseq_encoded[pos];
+#endif
+ if (insn == BIN(opt_send_without_block)) {
+ CALL_DATA cd = (CALL_DATA)iseq->body->iseq_encoded[pos + 1];
+ extern const rb_iseq_t *rb_mjit_inlinable_iseq(const struct rb_callinfo *ci, const struct rb_callcache *cc);
+ const rb_iseq_t *iseq = rb_mjit_inlinable_iseq(cd->ci, cd->cc);
+ if (iseq != NULL) {
+ compiling_iseqs[i] = iseq;
+ i++;
+ }
+ }
+ pos += insn_len(insn);
+ }
+ return true;
+}
+
+bool
+rb_mjit_compiling_iseq_p(const rb_iseq_t *iseq)
+{
+ assert(compiling_iseqs != NULL);
+ int i = 0;
+ while (compiling_iseqs[i]) {
+ if (compiling_iseqs[i] == iseq) return true;
+ i++;
+ }
+ return false;
+}
+
+static const int c_file_access_mode =
+#ifdef O_BINARY
+ O_BINARY|
+#endif
+ O_WRONLY|O_EXCL|O_CREAT;
+
+#define append_str2(p, str, len) ((char *)memcpy((p), str, (len))+(len))
+#define append_str(p, str) append_str2(p, str, sizeof(str)-1)
+#define append_lit(p, str) append_str2(p, str, rb_strlen_lit(str))
+
+#ifdef _MSC_VER
+// Compile C file to so. It returns true if it succeeds. (mswin)
+static bool
+compile_c_to_so(const char *c_file, const char *so_file)
+{
+ const char *files[] = { NULL, NULL, NULL, NULL, NULL, NULL, "-link", libruby_pathflag, NULL };
+ char *p;
+
+ // files[0] = "-Fe*.dll"
+ files[0] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fe") + strlen(so_file) + 1));
+ p = append_lit(p, "-Fe");
+ p = append_str2(p, so_file, strlen(so_file));
+ *p = '\0';
+
+ // files[1] = "-Fo*.obj"
+ // We don't need .obj file, but it's somehow created to cwd without -Fo and we want to control the output directory.
+ files[1] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fo") + strlen(so_file) - rb_strlen_lit(DLEXT) + rb_strlen_lit(".obj") + 1));
+ char *obj_file = p = append_lit(p, "-Fo");
+ p = append_str2(p, so_file, strlen(so_file) - rb_strlen_lit(DLEXT));
+ p = append_lit(p, ".obj");
+ *p = '\0';
+
+ // files[2] = "-Yu*.pch"
+ files[2] = p = alloca(sizeof(char) * (rb_strlen_lit("-Yu") + strlen(pch_file) + 1));
+ p = append_lit(p, "-Yu");
+ p = append_str2(p, pch_file, strlen(pch_file));
+ *p = '\0';
+
+ // files[3] = "C:/.../rb_mjit_header-*.obj"
+ files[3] = p = alloca(sizeof(char) * (strlen(pch_file) + 1));
+ p = append_str2(p, pch_file, strlen(pch_file) - strlen(".pch"));
+ p = append_lit(p, ".obj");
+ *p = '\0';
+
+ // files[4] = "-Tc*.c"
+ files[4] = p = alloca(sizeof(char) * (rb_strlen_lit("-Tc") + strlen(c_file) + 1));
+ p = append_lit(p, "-Tc");
+ p = append_str2(p, c_file, strlen(c_file));
+ *p = '\0';
+
+ // files[5] = "-Fd*.pdb"
+ files[5] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fd") + strlen(pch_file) + 1));
+ p = append_lit(p, "-Fd");
+ p = append_str2(p, pch_file, strlen(pch_file) - rb_strlen_lit(".pch"));
+ p = append_lit(p, ".pdb");
+ *p = '\0';
+
+ char **args = form_args(5, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS,
+ files, CC_LIBS, CC_DLDFLAGS_ARGS);
+ if (args == NULL)
+ return false;
+
+ int exit_code = exec_process(cc_path, args);
+ free(args);
+
+ if (exit_code == 0) {
+ // remove never-used files (.obj, .lib, .exp, .pdb). XXX: Is there any way not to generate this?
+ if (!mjit_opts.save_temps) {
+ char *before_dot;
+ remove_file(obj_file);
+
+ before_dot = obj_file + strlen(obj_file) - rb_strlen_lit(".obj");
+ append_lit(before_dot, ".lib"); remove_file(obj_file);
+ append_lit(before_dot, ".exp"); remove_file(obj_file);
+ append_lit(before_dot, ".pdb"); remove_file(obj_file);
+ }
+ }
+ else {
+ verbose(2, "compile_c_to_so: compile error: %d", exit_code);
+ }
+ return exit_code == 0;
+}
+#else // _MSC_VER
+
+// The function producing the pre-compiled header.
+static void
+make_pch(void)
+{
+ const char *rest_args[] = {
+# ifdef __clang__
+ "-emit-pch",
+ "-c",
+# endif
+ // -nodefaultlibs is a linker flag, but it may affect cc1 behavior on Gentoo, which should NOT be changed on pch:
+ // https://gitweb.gentoo.org/proj/gcc-patches.git/tree/7.3.0/gentoo/13_all_default-ssp-fix.patch
+ GCC_NOSTDLIB_FLAGS
+ "-o", pch_file, header_file,
+ NULL,
+ };
+
+ verbose(2, "Creating precompiled header");
+ char **args = form_args(4, cc_common_args, CC_CODEFLAG_ARGS, cc_added_args, rest_args);
+ if (args == NULL) {
+ mjit_warning("making precompiled header failed on forming args");
+ CRITICAL_SECTION_START(3, "in make_pch");
+ pch_status = PCH_FAILED;
+ CRITICAL_SECTION_FINISH(3, "in make_pch");
+ return;
+ }
+
+ int exit_code = exec_process(cc_path, args);
+ free(args);
+
+ CRITICAL_SECTION_START(3, "in make_pch");
+ if (exit_code == 0) {
+ pch_status = PCH_SUCCESS;
+ }
+ else {
+ mjit_warning("Making precompiled header failed on compilation. Stopping MJIT worker...");
+ pch_status = PCH_FAILED;
+ }
+ /* wakeup `mjit_finish` */
+ rb_native_cond_broadcast(&mjit_pch_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in make_pch");
+}
+
+// Compile .c file to .so file. It returns true if it succeeds. (non-mswin)
+// Not compiling .c to .so directly because it fails on MinGW, and this helps
+// to generate no .dSYM on macOS.
+static bool
+compile_c_to_so(const char *c_file, const char *so_file)
+{
+ char* o_file = alloca(strlen(c_file) + 1);
+ strcpy(o_file, c_file);
+ o_file[strlen(c_file) - 1] = 'o';
+
+ const char *o_args[] = {
+ "-o", o_file, c_file,
+# ifdef __clang__
+ "-include-pch", pch_file,
+# endif
+ "-c", NULL
+ };
+ char **args = form_args(5, cc_common_args, CC_CODEFLAG_ARGS, cc_added_args, o_args, CC_LINKER_ARGS);
+ if (args == NULL) return false;
+ int exit_code = exec_process(cc_path, args);
+ free(args);
+ if (exit_code != 0) {
+ verbose(2, "compile_c_to_so: failed to compile .c to .o: %d", exit_code);
+ return false;
+ }
+
+ const char *so_args[] = {
+ "-o", so_file,
+# ifdef _WIN32
+ libruby_pathflag,
+# endif
+ o_file, NULL
+ };
+# if defined(__MACH__)
+ extern VALUE rb_libruby_selfpath;
+ const char *loader_args[] = {"-bundle_loader", StringValuePtr(rb_libruby_selfpath), NULL};
+# else
+ const char *loader_args[] = {NULL};
+# endif
+ args = form_args(7, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS, so_args, loader_args, CC_LIBS, CC_DLDFLAGS_ARGS, CC_LINKER_ARGS);
+ if (args == NULL) return false;
+ exit_code = exec_process(cc_path, args);
+ free(args);
+ if (!mjit_opts.save_temps) remove_file(o_file);
+ if (exit_code != 0) {
+ verbose(2, "compile_c_to_so: failed to link .o to .so: %d", exit_code);
+ }
+ return exit_code == 0;
+}
+#endif // _MSC_VER
+
+#if USE_JIT_COMPACTION
+static void compile_prelude(FILE *f);
+
+static bool
+compile_compact_jit_code(char* c_file)
+{
+ FILE *f;
+ int fd = rb_cloexec_open(c_file, c_file_access_mode, 0600);
+ if (fd < 0 || (f = fdopen(fd, "w")) == NULL) {
+ int e = errno;
+ if (fd >= 0) (void)close(fd);
+ verbose(1, "Failed to fopen '%s', giving up JIT for it (%s)", c_file, strerror(e));
+ return false;
+ }
+
+ compile_prelude(f);
+
+ // wait until mjit_gc_exit_hook is called
+ CRITICAL_SECTION_START(3, "before mjit_compile to wait GC finish");
+ while (in_gc) {
+ verbose(3, "Waiting wakeup from GC");
+ rb_native_cond_wait(&mjit_gc_wakeup, &mjit_engine_mutex);
+ }
+ // We need to check again here because we could've waited on GC above
+ bool iseq_gced = false;
+ struct rb_mjit_unit *child_unit = 0, *next;
+ list_for_each_safe(&active_units.head, child_unit, next, unode) {
+ if (child_unit->iseq == NULL) { // ISeq is GC-ed
+ iseq_gced = true;
+ verbose(1, "JIT compaction: A method for JIT code u%d is obsoleted. Compaction will be skipped.", child_unit->id);
+ remove_from_list(child_unit, &active_units);
+ free_unit(child_unit); // unload it without waiting for throttled unload_units to retry compaction quickly
+ }
+ }
+ in_jit = !iseq_gced;
+ CRITICAL_SECTION_FINISH(3, "before mjit_compile to wait GC finish");
+ if (!in_jit) {
+ fclose(f);
+ if (!mjit_opts.save_temps)
+ remove_file(c_file);
+ return false;
+ }
+
+ // This entire loop lock GC so that we do not need to consider a case that
+ // ISeq is GC-ed in a middle of re-compilation. It takes 3~4ms with 100 methods
+ // on my machine. It's not too bad compared to compilation time of C (7200~8000ms),
+ // but it might be larger if we use a larger --jit-max-cache.
+ //
+ // TODO: Consider using a more granular lock after we implement inlining across
+ // compacted functions (not done yet).
+ bool success = true;
+ list_for_each(&active_units.head, child_unit, unode) {
+ CRITICAL_SECTION_START(3, "before set_compiling_iseqs");
+ success &= set_compiling_iseqs(child_unit->iseq);
+ CRITICAL_SECTION_FINISH(3, "after set_compiling_iseqs");
+ if (!success) continue;
+
+ char funcname[MAXPATHLEN];
+ sprint_funcname(funcname, child_unit);
+
+ long iseq_lineno = 0;
+ if (FIXNUM_P(child_unit->iseq->body->location.first_lineno))
+ // FIX2INT may fallback to rb_num2long(), which is a method call and dangerous in MJIT worker. So using only FIX2LONG.
+ iseq_lineno = FIX2LONG(child_unit->iseq->body->location.first_lineno);
+ const char *sep = "@";
+ const char *iseq_label = RSTRING_PTR(child_unit->iseq->body->location.label);
+ const char *iseq_path = RSTRING_PTR(rb_iseq_path(child_unit->iseq));
+ if (!iseq_label) iseq_label = sep = "";
+ fprintf(f, "\n/* %s%s%s:%ld */\n", iseq_label, sep, iseq_path, iseq_lineno);
+ success &= mjit_compile(f, child_unit->iseq, funcname, child_unit->id);
+
+ CRITICAL_SECTION_START(3, "before compiling_iseqs free");
+ free(compiling_iseqs);
+ compiling_iseqs = NULL;
+ CRITICAL_SECTION_FINISH(3, "after compiling_iseqs free");
+ }
+
+ // release blocking mjit_gc_start_hook
+ CRITICAL_SECTION_START(3, "after mjit_compile to wakeup client for GC");
+ in_jit = false;
+ verbose(3, "Sending wakeup signal to client in a mjit-worker for GC");
+ rb_native_cond_signal(&mjit_client_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in worker to wakeup client for GC");
+
+ fclose(f);
+ return success;
+}
+
+// Compile all cached .c files and build a single .so file. Reload all JIT func from it.
+// This improves the code locality for better performance in terms of iTLB and iCache.
+static void
+compact_all_jit_code(void)
+{
+ struct rb_mjit_unit *unit, *cur = 0;
+ static const char c_ext[] = ".c";
+ static const char so_ext[] = DLEXT;
+ char c_file[MAXPATHLEN], so_file[MAXPATHLEN];
+
+ // Abnormal use case of rb_mjit_unit that doesn't have ISeq
+ unit = calloc(1, sizeof(struct rb_mjit_unit)); // To prevent GC, don't use ZALLOC
+ if (unit == NULL) return;
+ unit->id = current_unit_num++;
+ sprint_uniq_filename(c_file, (int)sizeof(c_file), unit->id, MJIT_TMP_PREFIX, c_ext);
+ sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext);
+
+ bool success = compile_compact_jit_code(c_file);
+ double start_time = real_ms_time();
+ if (success) {
+ success = compile_c_to_so(c_file, so_file);
+ if (!mjit_opts.save_temps)
+ remove_file(c_file);
+ }
+ double end_time = real_ms_time();
+
+ if (success) {
+ void *handle = dlopen(so_file, RTLD_NOW);
+ if (handle == NULL) {
+ mjit_warning("failure in loading code from compacted '%s': %s", so_file, dlerror());
+ free(unit);
+ return;
+ }
+ unit->handle = handle;
+
+ // lazily dlclose handle (and .so file for win32) on `mjit_finish()`.
+ add_to_list(unit, &compact_units);
+
+ if (!mjit_opts.save_temps)
+ remove_so_file(so_file, unit);
+
+ CRITICAL_SECTION_START(3, "in compact_all_jit_code to read list");
+ list_for_each(&active_units.head, cur, unode) {
+ void *func;
+ char funcname[MAXPATHLEN];
+ sprint_funcname(funcname, cur);
+
+ if ((func = dlsym(handle, funcname)) == NULL) {
+ mjit_warning("skipping to reload '%s' from '%s': %s", funcname, so_file, dlerror());
+ continue;
+ }
+
+ if (cur->iseq) { // Check whether GCed or not
+ // Usage of jit_code might be not in a critical section.
+ MJIT_ATOMIC_SET(cur->iseq->body->jit_func, (mjit_func_t)func);
+ }
+ }
+ CRITICAL_SECTION_FINISH(3, "in compact_all_jit_code to read list");
+ verbose(1, "JIT compaction (%.1fms): Compacted %d methods %s -> %s", end_time - start_time, active_units.length, c_file, so_file);
+ }
+ else {
+ free(unit);
+ verbose(1, "JIT compaction failure (%.1fms): Failed to compact methods", end_time - start_time);
+ }
+}
+#endif // USE_JIT_COMPACTION
+
+static void *
+load_func_from_so(const char *so_file, const char *funcname, struct rb_mjit_unit *unit)
+{
+ void *handle, *func;
+
+ handle = dlopen(so_file, RTLD_NOW);
+ if (handle == NULL) {
+ mjit_warning("failure in loading code from '%s': %s", so_file, dlerror());
+ return (void *)NOT_ADDED_JIT_ISEQ_FUNC;
+ }
+
+ func = dlsym(handle, funcname);
+ unit->handle = handle;
+ return func;
+}
+
+#ifndef __clang__
+static const char *
+header_name_end(const char *s)
+{
+ const char *e = s + strlen(s);
+# ifdef __GNUC__ // don't chomp .pch for mswin
+ static const char suffix[] = ".gch";
+
+ // chomp .gch suffix
+ if (e > s+sizeof(suffix)-1 && strcmp(e-sizeof(suffix)+1, suffix) == 0) {
+ e -= sizeof(suffix)-1;
+ }
+# endif
+ return e;
+}
+#endif
+
+// Print platform-specific prerequisites in generated code.
+static void
+compile_prelude(FILE *f)
+{
+#ifndef __clang__ // -include-pch is used for Clang
+ const char *s = pch_file;
+ const char *e = header_name_end(s);
+
+ fprintf(f, "#include \"");
+ // print pch_file except .gch for gcc, but keep .pch for mswin
+ for (; s < e; s++) {
+ switch(*s) {
+ case '\\': case '"':
+ fputc('\\', f);
+ }
+ fputc(*s, f);
+ }
+ fprintf(f, "\"\n");
+#endif
+
+#ifdef _WIN32
+ fprintf(f, "void _pei386_runtime_relocator(void){}\n");
+ fprintf(f, "int __stdcall DllMainCRTStartup(void* hinstDLL, unsigned int fdwReason, void* lpvReserved) { return 1; }\n");
+#endif
+}
+
+// Compile ISeq in UNIT and return function pointer of JIT-ed code.
+// It may return NOT_COMPILED_JIT_ISEQ_FUNC if something went wrong.
+static mjit_func_t
+convert_unit_to_func(struct rb_mjit_unit *unit)
+{
+ static const char c_ext[] = ".c";
+ static const char so_ext[] = DLEXT;
+ char c_file[MAXPATHLEN], so_file[MAXPATHLEN], funcname[MAXPATHLEN];
+
+ sprint_uniq_filename(c_file, (int)sizeof(c_file), unit->id, MJIT_TMP_PREFIX, c_ext);
+ sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext);
+ sprint_funcname(funcname, unit);
+
+ FILE *f;
+ int fd = rb_cloexec_open(c_file, c_file_access_mode, 0600);
+ if (fd < 0 || (f = fdopen(fd, "w")) == NULL) {
+ int e = errno;
+ if (fd >= 0) (void)close(fd);
+ verbose(1, "Failed to fopen '%s', giving up JIT for it (%s)", c_file, strerror(e));
+ return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
+ }
+
+ // print #include of MJIT header, etc.
+ compile_prelude(f);
+
+ // wait until mjit_gc_exit_hook is called
+ CRITICAL_SECTION_START(3, "before mjit_compile to wait GC finish");
+ while (in_gc) {
+ verbose(3, "Waiting wakeup from GC");
+ rb_native_cond_wait(&mjit_gc_wakeup, &mjit_engine_mutex);
+ }
+ // We need to check again here because we could've waited on GC above
+ in_jit = (unit->iseq != NULL);
+ if (in_jit)
+ in_jit &= set_compiling_iseqs(unit->iseq);
+ CRITICAL_SECTION_FINISH(3, "before mjit_compile to wait GC finish");
+ if (!in_jit) {
+ fclose(f);
+ if (!mjit_opts.save_temps)
+ remove_file(c_file);
+ return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
+ }
+
+ // To make MJIT worker thread-safe against GC.compact, copy ISeq values while `in_jit` is true.
+ long iseq_lineno = 0;
+ if (FIXNUM_P(unit->iseq->body->location.first_lineno))
+ // FIX2INT may fallback to rb_num2long(), which is a method call and dangerous in MJIT worker. So using only FIX2LONG.
+ iseq_lineno = FIX2LONG(unit->iseq->body->location.first_lineno);
+ char *iseq_label = alloca(RSTRING_LEN(unit->iseq->body->location.label) + 1);
+ char *iseq_path = alloca(RSTRING_LEN(rb_iseq_path(unit->iseq)) + 1);
+ strcpy(iseq_label, RSTRING_PTR(unit->iseq->body->location.label));
+ strcpy(iseq_path, RSTRING_PTR(rb_iseq_path(unit->iseq)));
+
+ verbose(2, "start compilation: %s@%s:%ld -> %s", iseq_label, iseq_path, iseq_lineno, c_file);
+ fprintf(f, "/* %s@%s:%ld */\n\n", iseq_label, iseq_path, iseq_lineno);
+ bool success = mjit_compile(f, unit->iseq, funcname, unit->id);
+
+ // release blocking mjit_gc_start_hook
+ CRITICAL_SECTION_START(3, "after mjit_compile to wakeup client for GC");
+ free(compiling_iseqs);
+ compiling_iseqs = NULL;
+ in_jit = false;
+ verbose(3, "Sending wakeup signal to client in a mjit-worker for GC");
+ rb_native_cond_signal(&mjit_client_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in worker to wakeup client for GC");
+
+ fclose(f);
+ if (!success) {
+ if (!mjit_opts.save_temps)
+ remove_file(c_file);
+ verbose(1, "JIT failure: %s@%s:%ld -> %s", iseq_label, iseq_path, iseq_lineno, c_file);
+ return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
+ }
+
+ double start_time = real_ms_time();
+ success = compile_c_to_so(c_file, so_file);
+ if (!mjit_opts.save_temps)
+ remove_file(c_file);
+ double end_time = real_ms_time();
+
+ if (!success) {
+ verbose(2, "Failed to generate so: %s", so_file);
+ return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
+ }
+
+ void *func = load_func_from_so(so_file, funcname, unit);
+ if (!mjit_opts.save_temps)
+ remove_so_file(so_file, unit);
+
+ if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) {
+ verbose(1, "JIT success (%.1fms): %s@%s:%ld -> %s",
+ end_time - start_time, iseq_label, iseq_path, iseq_lineno, c_file);
+ }
+ return (mjit_func_t)func;
+}
+
+// To see cc_entries using index returned by `mjit_capture_cc_entries` in mjit_compile.c
+const struct rb_callcache **
+mjit_iseq_cc_entries(const struct rb_iseq_constant_body *const body)
+{
+ return body->jit_unit->cc_entries;
+}
+
+// Capture cc entries of `captured_iseq` and append them to `compiled_iseq->jit_unit->cc_entries`.
+// This is needed when `captured_iseq` is inlined by `compiled_iseq` and GC needs to mark inlined cc.
+//
+// Index to refer to `compiled_iseq->jit_unit->cc_entries` is returned instead of the address
+// because old addresses may be invalidated by `realloc` later. -1 is returned on failure.
+//
+// This assumes that it's safe to reference cc without acquiring GVL.
+int
+mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq)
+{
+ struct rb_mjit_unit *unit = compiled_iseq->jit_unit;
+ unsigned int new_entries_size = unit->cc_entries_size + captured_iseq->ci_size;
+ VM_ASSERT(captured_iseq->ci_size > 0);
+
+ // Allocate new cc_entries and append them to unit->cc_entries
+ const struct rb_callcache **cc_entries;
+ int cc_entries_index = unit->cc_entries_size;
+ if (unit->cc_entries_size == 0) {
+ VM_ASSERT(unit->cc_entries == NULL);
+ unit->cc_entries = cc_entries = malloc(sizeof(struct rb_callcache *) * new_entries_size);
+ if (cc_entries == NULL) return -1;
+ }
+ else {
+ void *cc_ptr = (void *)unit->cc_entries; // get rid of bogus warning by VC
+ cc_entries = realloc(cc_ptr, sizeof(struct rb_callcache *) * new_entries_size);
+ if (cc_entries == NULL) return -1;
+ unit->cc_entries = cc_entries;
+ cc_entries += cc_entries_index;
+ }
+ unit->cc_entries_size = new_entries_size;
+
+ // Capture cc to cc_enties
+ for (unsigned int i = 0; i < captured_iseq->ci_size; i++) {
+ cc_entries[i] = captured_iseq->call_data[i].cc;
+ }
+
+ return cc_entries_index;
+}
+
+// Set up field `used_code_p` for unit iseqs whose iseq on the stack of ec.
+static void
+mark_ec_units(rb_execution_context_t *ec)
+{
+ const rb_control_frame_t *cfp;
+
+ if (ec->vm_stack == NULL)
+ return;
+ for (cfp = RUBY_VM_END_CONTROL_FRAME(ec) - 1; ; cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp)) {
+ const rb_iseq_t *iseq;
+ if (cfp->pc && (iseq = cfp->iseq) != NULL
+ && imemo_type((VALUE) iseq) == imemo_iseq
+ && (iseq->body->jit_unit) != NULL) {
+ iseq->body->jit_unit->used_code_p = true;
+ }
+
+ if (cfp == ec->cfp)
+ break; // reached the most recent cfp
+ }
+}
+
+// MJIT info related to an existing continutaion.
+struct mjit_cont {
+ rb_execution_context_t *ec; // continuation ec
+ struct mjit_cont *prev, *next; // used to form lists
+};
+
+// Double linked list of registered continuations. This is used to detect
+// units which are in use in unload_units.
+static struct mjit_cont *first_cont;
+
+// Unload JIT code of some units to satisfy the maximum permitted
+// number of units with a loaded code.
+static void
+unload_units(void)
+{
+ struct rb_mjit_unit *unit = 0, *next;
+ struct mjit_cont *cont;
+ int units_num = active_units.length;
+
+ // For now, we don't unload units when ISeq is GCed. We should
+ // unload such ISeqs first here.
+ list_for_each_safe(&active_units.head, unit, next, unode) {
+ if (unit->iseq == NULL) { // ISeq is GCed.
+ remove_from_list(unit, &active_units);
+ free_unit(unit);
+ }
+ }
+
+ // Detect units which are in use and can't be unloaded.
+ list_for_each(&active_units.head, unit, unode) {
+ assert(unit->iseq != NULL && unit->handle != NULL);
+ unit->used_code_p = false;
+ }
+ // All threads have a root_fiber which has a mjit_cont. Other normal fibers also
+ // have a mjit_cont. Thus we can check ISeqs in use by scanning ec of mjit_conts.
+ for (cont = first_cont; cont != NULL; cont = cont->next) {
+ mark_ec_units(cont->ec);
+ }
+ // TODO: check stale_units and unload unused ones! (note that the unit is not associated to ISeq anymore)
+
+ // Unload units whose total_calls is smaller than any total_calls in unit_queue.
+ // TODO: make the algorithm more efficient
+ long unsigned prev_queue_calls = -1;
+ while (true) {
+ // Calculate the next max total_calls in unit_queue
+ long unsigned max_queue_calls = 0;
+ list_for_each(&unit_queue.head, unit, unode) {
+ if (unit->iseq != NULL && max_queue_calls < unit->iseq->body->total_calls
+ && unit->iseq->body->total_calls < prev_queue_calls) {
+ max_queue_calls = unit->iseq->body->total_calls;
+ }
+ }
+ prev_queue_calls = max_queue_calls;
+
+ bool unloaded_p = false;
+ list_for_each_safe(&active_units.head, unit, next, unode) {
+ if (unit->used_code_p) // We can't unload code on stack.
+ continue;
+
+ if (max_queue_calls > unit->iseq->body->total_calls) {
+ verbose(2, "Unloading unit %d (calls=%lu, threshold=%lu)",
+ unit->id, unit->iseq->body->total_calls, max_queue_calls);
+ assert(unit->handle != NULL);
+ remove_from_list(unit, &active_units);
+ free_unit(unit);
+ unloaded_p = true;
+ }
+ }
+ if (!unloaded_p) break;
+ }
+
+ if (units_num > active_units.length) {
+ verbose(1, "Too many JIT code -- %d units unloaded", units_num - active_units.length);
+ total_unloads += units_num - active_units.length;
+ }
+}
+
+static void mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info, bool worker_p);
+
+// The function implementing a worker. It is executed in a separate
+// thread by rb_thread_create_mjit_thread. It compiles precompiled header
+// and then compiles requested ISeqs.
+void
+mjit_worker(void)
+{
+ // Allow only `max_cache_size / 10` times (default: 10) of compaction.
+ // Note: GC of compacted code has not been implemented yet.
+ int max_compact_size = mjit_opts.max_cache_size / 10;
+ if (max_compact_size < 10) max_compact_size = 10;
+
+ // Run unload_units after it's requested `max_cache_size / 10` (default: 10) times.
+ // This throttles the call to mitigate locking in unload_units. It also throttles JIT compaction.
+ int throttle_threshold = mjit_opts.max_cache_size / 10;
+
+#ifndef _MSC_VER
+ if (pch_status == PCH_NOT_READY) {
+ make_pch();
+ }
+#endif
+ if (pch_status == PCH_FAILED) {
+ mjit_enabled = false;
+ CRITICAL_SECTION_START(3, "in worker to update worker_stopped");
+ worker_stopped = true;
+ verbose(3, "Sending wakeup signal to client in a mjit-worker");
+ rb_native_cond_signal(&mjit_client_wakeup);
+ CRITICAL_SECTION_FINISH(3, "in worker to update worker_stopped");
+ return; // TODO: do the same thing in the latter half of mjit_finish
+ }
+
+ // main worker loop
+ while (!stop_worker_p) {
+ struct rb_mjit_unit *unit;
+
+ // Wait until a unit becomes available
+ CRITICAL_SECTION_START(3, "in worker dequeue");
+ while ((list_empty(&unit_queue.head) || active_units.length >= mjit_opts.max_cache_size) && !stop_worker_p) {
+ rb_native_cond_wait(&mjit_worker_wakeup, &mjit_engine_mutex);
+ verbose(3, "Getting wakeup from client");
+
+ // Lazily move active_units to stale_units to avoid race conditions around active_units with compaction
+ if (pending_stale_p) {
+ pending_stale_p = false;
+ struct rb_mjit_unit *next;
+ list_for_each_safe(&active_units.head, unit, next, unode) {
+ if (unit->stale_p) {
+ unit->stale_p = false;
+ remove_from_list(unit, &active_units);
+ add_to_list(unit, &stale_units);
+ // Lazily put it to unit_queue as well to avoid race conditions on jit_unit with mjit_compile.
+ mjit_add_iseq_to_process(unit->iseq, &unit->iseq->body->jit_unit->compile_info, true);
+ }
+ }
+ }
+
+ // Unload some units as needed
+ if (unload_requests >= throttle_threshold) {
+ while (in_gc) {
+ verbose(3, "Waiting wakeup from GC");
+ rb_native_cond_wait(&mjit_gc_wakeup, &mjit_engine_mutex);
+ }
+ in_jit = true; // Lock GC
+
+ RB_DEBUG_COUNTER_INC(mjit_unload_units);
+ unload_units();
+ unload_requests = 0;
+
+ in_jit = false; // Unlock GC
+ verbose(3, "Sending wakeup signal to client in a mjit-worker for GC");
+ rb_native_cond_signal(&mjit_client_wakeup);
+ }
+ if (active_units.length == mjit_opts.max_cache_size && mjit_opts.wait) { // Sometimes all methods may be in use
+ mjit_opts.max_cache_size++; // avoid infinite loop on `rb_mjit_wait_call`. Note that --jit-wait is just for testing.
+ verbose(1, "No units can be unloaded -- incremented max-cache-size to %d for --jit-wait", mjit_opts.max_cache_size);
+ }
+ }
+ unit = get_from_list(&unit_queue);
+ CRITICAL_SECTION_FINISH(3, "in worker dequeue");
+
+ if (unit) {
+ // JIT compile
+ mjit_func_t func = convert_unit_to_func(unit);
+ (void)RB_DEBUG_COUNTER_INC_IF(mjit_compile_failures, func == (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC);
+
+ CRITICAL_SECTION_START(3, "in jit func replace");
+ while (in_gc) { // Make sure we're not GC-ing when touching ISeq
+ verbose(3, "Waiting wakeup from GC");
+ rb_native_cond_wait(&mjit_gc_wakeup, &mjit_engine_mutex);
+ }
+ if (unit->iseq) { // Check whether GCed or not
+ if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) {
+ add_to_list(unit, &active_units);
+ }
+ // Usage of jit_code might be not in a critical section.
+ MJIT_ATOMIC_SET(unit->iseq->body->jit_func, func);
+ }
+ else {
+ free_unit(unit);
+ }
+ CRITICAL_SECTION_FINISH(3, "in jit func replace");
+
+#if USE_JIT_COMPACTION
+ // Combine .o files to one .so and reload all jit_func to improve memory locality.
+ if (compact_units.length < max_compact_size
+ && ((!mjit_opts.wait && unit_queue.length == 0 && active_units.length > 1)
+ || (active_units.length == mjit_opts.max_cache_size && compact_units.length * throttle_threshold <= total_unloads))) { // throttle compaction by total_unloads
+ compact_all_jit_code();
+ }
+#endif
+ }
+ }
+
+ // To keep mutex unlocked when it is destroyed by mjit_finish, don't wrap CRITICAL_SECTION here.
+ worker_stopped = true;
+}
diff --git a/nacl/GNUmakefile.in b/nacl/GNUmakefile.in
deleted file mode 100644
index 1fffcee898..0000000000
--- a/nacl/GNUmakefile.in
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2012 Google Inc. All Rights Reserved.
-# Author: yugui@google.com (Yugui Sonoda)
-
-include Makefile
--include uncommon.mk
-
-NACL_SDK_ROOT=@NACL_SDK_ROOT@
-NACL_TOOLCHAIN=@NACL_TOOLCHAIN@
-NACL_TOOLCHAIN_DIR=$(NACL_SDK_ROOT)/toolchain/$(NACL_TOOLCHAIN)
-CXX=@CXX@
-
-# Don't override CC/LD/etc if they are already set to absolute
-# paths (this is the case when building in the naclports tree).
-ifeq ($(dir $(CC)),./)
-CC:=$(NACL_TOOLCHAIN_DIR)/bin/$(CC)
-endif
-ifeq ($(dir $(CXX)),./)
-CXX:=$(NACL_TOOLCHAIN_DIR)/bin/$(CXX)
-endif
-ifeq ($(dir $(LD)),./)
-LD:=$(NACL_TOOLCHAIN_DIR)/bin/$(LD)
-endif
-ifeq ($(dir $(NM)),./)
-NM:=$(NACL_TOOLCHAIN_DIR)/bin/$(NM)
-endif
-ifeq ($(dir $(AR)),./)
-AR:=$(NACL_TOOLCHAIN_DIR)/bin/$(AR)
-endif
-ifeq ($(dir $(AS)),./)
-AS:=$(NACL_TOOLCHAIN_DIR)/bin/$(AS)
-endif
-ifeq ($(dir $(RANLIB)),./)
-RANLIB:=$(NACL_TOOLCHAIN_DIR)/bin/$(RANLIB)
-endif
-ifeq ($(dir $(OBJDUMP)),./)
-OBJDUMP:=$(NACL_TOOLCHAIN_DIR)/bin/$(OBJDUMP)
-endif
-ifeq ($(dir $(OBJCOPY)),./)
-OBJCOPY:=$(NACL_TOOLCHAIN_DIR)/bin/$(OBJCOPY)
-endif
-PYTHON=@PYTHON@
-
-PPROGRAM=pepper-$(PROGRAM)
-PEPPER_LIBS=-lppapi -lnacl_io
-PROGRAM_NMF=$(PROGRAM:$(EXEEXT)=.nmf)
-PPROGRAM_NMF=$(PPROGRAM:$(EXEEXT)=.nmf)
-
-GNUmakefile: $(srcdir)/nacl/GNUmakefile.in
-$(PPROGRAM): $(PROGRAM) pepper_main.$(OBJEXT)
- $(Q)$(MAKE) $(MFLAGS) PROGRAM=$(PPROGRAM) MAINOBJ="pepper_main.$(OBJEXT)" LIBS="$(LIBS) $(PEPPER_LIBS)" CC="$(CXX)" program
-$(PROGRAM_NMF) $(PPROGRAM_NMF): $(@:.nmf=$(EXEEXT)) nacl/create_nmf.rb
-
-.PHONY: pprogram package show_naclflags
-.SUFFIXES: $(EXEEXT) .nmf
-$(EXEEXT).nmf:
- $(ECHO) generating manifest $@
- $(Q)$(MINIRUBY) $(srcdir)/nacl/create_nmf.rb --verbose=$(V) $(@:.nmf=$(EXEEXT)) $@
-
-pepper_main.$(OBJEXT): $(srcdir)/nacl/pepper_main.c
- @$(ECHO) compiling nacl/pepper_main.c
- $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(srcdir)/nacl/pepper_main.c
-
-.rbconfig.time:
- @$(MAKE) .rbconfig.raw.time RBCONFIG=.rbconfig.raw.time
- @sed \
- -e 's!CONFIG\["CC"\] = .*!CONFIG\["CC"\] = "$(CC)"!' \
- -e 's!CONFIG\["LD"\] = .*!CONFIG\["LD"\] = "$(LD)"!' \
- -e 's!CONFIG\["NM"\] = .*!CONFIG\["NM"\] = "$(NM)"!' \
- -e 's!CONFIG\["AR"\] = .*!CONFIG\["AR"\] = "$(AR)"!' \
- -e 's!CONFIG\["AS"\] = .*!CONFIG\["AS"\] = "$(AS)"!' \
- -e 's!CONFIG\["RANLIB"\] = .*!CONFIG\["RANLIB"\] = "$(RANLIB)"!' \
- -e 's!CONFIG\["OBJDUMP"\] = .*!CONFIG\["OBJDUMP"\] = "$(OBJDUMP)"!' \
- -e 's!CONFIG\["OBJCOPY"\] = .*!CONFIG\["OBJCOPY"\] = "$(OBJCOPY)"!' \
- -i.bak rbconfig.rb
- @touch .rbconfig.time
-
-all: pprogram
-main: $(PROGRAM_NMF)
-pprogram: showflags $(PPROGRAM) $(PPROGRAM_NMF)
-program: $(PROGRAM_NMF)
-prog: pprogram
-
-package: pprogram install-lib install-ext-comm install-ext-arch
- $(INSTALL_DATA) $(srcdir)/nacl/example.html $(prefix)
- $(ECHO) generating manifest $@
- $(Q)$(MINIRUBY) $(srcdir)/nacl/package.rb $(prefix)
-
-showflags: show_naclflags
-
-show_naclflags:
- @echo " NACL_SDK_ROOT = $(NACL_SDK_ROOT)"
- @echo " NM = $(NM)"
- @echo " AR = $(AR)"
- @echo " AS = $(AS)"
- @echo " RANLIB = $(RANLIB)"
- @echo " OBJDUMP = $(OBJDUMP)"
- @echo " OBJCOPY = $(OBJCOPY)"
-
-clean-local::
- -$(RM) $(PPROGRAM) pepper_main.$(OBJEXT) $(PROGRAM_NMF) $(PPRGORAM_NMF)
diff --git a/nacl/README.nacl b/nacl/README.nacl
deleted file mode 100644
index 77140e0f75..0000000000
--- a/nacl/README.nacl
+++ /dev/null
@@ -1,51 +0,0 @@
-=begin
-= Native Client port of Ruby
-
-= How to build
-== Prerequisites
-You need to install the following things before building NaCl port of Ruby.
-* Ruby 1.9.3 or later
-* Python 2.6 or later
-* NativeClient SDK pepper 37 or later
-* GNU make
-
-== Steps
-(1) Extract all files from the tarball:
- $ tar xzf ruby-X.Y.Z.tar.gz
-(2) Set NACL_SDK_ROOT environment variable to the path to the Native Client SDK you installed:
- $ export NACL_SDK_ROOT=/home/yugui/src/nacl_sdk/pepper_37
-(3) Configure
- $ ./configure --prefix=/tmp/nacl-ruby --host=x86_64-nacl --with-baseruby=/path/to/ruby-1.9.3-or-later
-(4) Make
- $ make
- $ make package
-
-Now you have ruby.nexe. You can run it by sel_ldr in NaCl SDK.
-
-"make package" installs "pepper-ruby.nexe", an example Pepper application that
-embeds Ruby", and libraries to $prefix. You can run it by the following steps:
-(5) Publish the $prefix directory on a web server
-(6) Visit the example.html on the web server by a browser that implements Pepper 18 or later.
- -- e.g., Chrome 18 implements Pepper 18, Chrome 19 implements Pepper 19, ...
-
-=== Example Configurations
-* x86_32 Native Client
- $ ./configure --prefix=/tmp/nacl-ruby \
- --host=i686-nacl \
- --with-baseruby=/path/to/ruby-1.9.3-or-later
-* arm Native Client
- $ ./configure --prefix=/tmp/nacl-ruby \
- --host=arm-nacl \
- --with-newlib \
- --with-baseruby=/path/to/ruby-1.9.3-or-later
-* Portable Native Client
- $ ./configure --prefix=/tmp/nacl-ruby \
- --host=le32-nacl \
- --with-newlib \
- --with-static-linked-ext \
- --with-baseruby=/path/to/ruby-1.9.3-or-later
-
-= Copyright
-* Copyright 2012 Google Inc. All Rights Reserved.
-* Author: yugui@google.com (Yugui Sonoda)
-=end
diff --git a/nacl/create_nmf.rb b/nacl/create_nmf.rb
deleted file mode 100644
index cdfe7ad239..0000000000
--- a/nacl/create_nmf.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/ruby
-# Copyright:: Copyright 2012 Google Inc.
-# License:: All Rights Reserved.
-# Original Author:: Yugui Sonoda (mailto:yugui@google.com)
-#
-# Wrapper for create_nmf.py / generate_nmf.py
-
-require File.join(File.dirname(__FILE__), 'nacl-config')
-
-include NaClConfig
-$verbosity = 0
-
-def usage_and_exit
- $stderr.puts "Usage: #{$PROGRAM_NAME} [--verbose=N] path/to/input.nexe path/to/output.nmf"
- exit false
-end
-
-def create_dynamically_linked(nmf, exe)
- cmd = [
- PYTHON, CREATE_NMF,
- '-o', nmf,
- '-D', OBJDUMP,
- '-L', HOST_LIB,
- exe
- ]
- puts cmd.join(' ') if $verbosity > 0
- exec(*cmd)
-end
-
-def create_statically_linked(nmf, exe)
- File.open(nmf, "w") {|f|
- f.write <<-EOS.gsub(/^ {6}/, '')
- {
- "program": {
- "#{ARCH}": {
- "url": "#{exe}"
- }
- }
- }
- EOS
- }
-end
-
-def main
- while m = ARGV.first.match(/--([a-z-]+)(?:=(\S+))?/)
- case m[1]
- when 'verbose'
- usage_and_exit unless m[2][/\A[0-9]+\z/]
- $verbosity = m[2].to_i
- when 'help'
- usage_end_exit
- end
- ARGV.shift
- end
-
- usage_and_exit if ARGV.size < 2
-
- exe, nmf = ARGV[0], ARGV[1]
- if newlib?
- create_statically_linked(nmf, exe)
- else
- create_dynamically_linked(nmf, exe)
- end
-end
-
-if __FILE__ == $0
- main()
-end
-
-
diff --git a/nacl/dirent.h b/nacl/dirent.h
deleted file mode 100644
index 31bdad31b7..0000000000
--- a/nacl/dirent.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright 2011 Google Inc. All Rights Reserved.
- * Author: yugui@google.com (Yugui Sonoda)
- */
-#ifndef RUBY_NACL_DIRENT_H
-#define RUBY_NACL_DIRENT_H
-
-/* NaCl SDK 0.3 has implementations of dir functions but no declaration in
- * dirent.h */
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
-void rewinddir(DIR *dirp);
-long telldir(DIR *dirp);
-void seekdir(DIR *dirp, long offset);
-
-#endif
diff --git a/nacl/example.html b/nacl/example.html
deleted file mode 100644
index 3cc33298dd..0000000000
--- a/nacl/example.html
+++ /dev/null
@@ -1,150 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Ruby Example</title>
-
- <script type="text/javascript">
- RubyModule = null; // Global application object.
- statusText = 'NO-STATUS';
- rubyReady = false;
-
- // Indicate load success.
- function moduleDidLoad() {
- RubyModule = document.getElementById('ruby');
- form = document.getElementById('source-form');
- form.style.display = "block";
- updateStatus('SUCCESS');
- }
-
- function evalSource() {
- if (rubyReady) {
- RubyModule.postMessage('eval:' + document.getElementById("source").value);
- } else {
- throw "Not yet ready";
- }
- return false;
- }
-
- function RubyError(message) {
- this.message = message;
- this.toString = function() {
- return message;
- }
- }
-
- function FatalError(message) {
- this.message = message;
- }
-
- // The 'message' event handler. This handler is fired when the NaCl module
- // posts a message to the browser by calling PPB_Messaging.PostMessage()
- // (in C) or pp::Instance.PostMessage() (in C++). This implementation
- // simply displays the content of the message in an alert panel.
- function handleMessage(message_event) {
- var raw = message_event.data;
- var components;
- if (raw.indexOf("error") == 0) {
- components = raw.split(":", 2);
- throw new RubyError(components[1]);
- } else if (raw.indexOf("return") == 0) {
- components = raw.split(":", 2);
- document.getElementById("result").value = components[1];
- } else if (raw == "rubyReady") {
- rubyReady = true;
- } else {
- throw new FatalError(raw);
- }
- }
-
- // If the page loads before the Native Client module loads, then set the
- // status message indicating that the module is still loading. Otherwise,
- // do not change the status message.
- function pageDidLoad() {
- if (RubyModule == null) {
- updateStatus('LOADING...');
- } else {
- // It's possible that the Native Client module onload event fired
- // before the page's onload event. In this case, the status message
- // will reflect 'SUCCESS', but won't be displayed. This call will
- // display the current message.
- updateStatus();
- }
- }
-
- // Set the global status message. If the element with id 'statusField'
- // exists, then set its HTML to the status message as well.
- // opt_message The message test. If this is null or undefined, then
- // attempt to set the element with id 'statusField' to the value of
- // |statusText|.
- function updateStatus(opt_message) {
- if (opt_message)
- statusText = opt_message;
- var statusField = document.getElementById('status_field');
- if (statusField) {
- statusField.innerHTML = statusText;
- }
- }
- </script>
-</head>
-<body onload="pageDidLoad()">
-
-<h1>Native Client Module Ruby</h1>
-<p>
- <!-- Load the published .nexe. This includes the 'nacl' attribute which
- shows how to load multi-architecture modules. Each entry in the "nexes"
- object in the .nmf manifest file is a key-value pair: the key is the
- instruction set architecture ('x86-32', 'x86-64', etc.); the value is a URL
- for the desired NaCl module.
- To load the debug versions of your .nexes, set the 'nacl' attribute to the
- _dbg.nmf version of the manifest file.
-
- Note: Since this NaCl module does not use any real-estate in the browser,
- it's width and height are set to 0.
-
- Note: The <EMBED> element is wrapped inside a <DIV>, which has both a 'load'
- and a 'message' event listener attached. This wrapping method is used
- instead of attaching the event listeners directly to the <EMBED> element to
- ensure that the listeners are active before the NaCl module 'load' event
- fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or
- pp::Instance.PostMessage() (in C++) from within the initialization code in
- your NaCl module.
- -->
- <div id="listener">
- <script type="text/javascript">
- var listener = document.getElementById('listener');
- listener.addEventListener('load', moduleDidLoad, true);
- listener.addEventListener('message', handleMessage, true);
- </script>
-
- <embed name="nacl_module"
- id="ruby"
- width="0" height="0"
- src="ruby.nmf"
- type="application/x-nacl" />
- <form id="source-form" action="#" method="post" style="display:none"
- onsubmit="evalSource(); return false">
- <table>
- <tbody>
- <tr>
- <th>Source</th>
- <td>
- <textarea rows="10" cols="80" id="source"></textarea>
- <input type="submit" />
- </td>
- </tr>
- <tr>
- <th>Result</th>
- <td>
- <textarea rows="10" cols="80" id="result"></textarea>
- </td>
- </tr>
- </tbody>
- </table>
- </form>
- </div>
-</p>
-
-<h2>Status</h2>
-<div id="status_field">NO-STATUS</div>
-</body>
-</html>
diff --git a/nacl/nacl-config.rb b/nacl/nacl-config.rb
deleted file mode 100755
index 66481301f5..0000000000
--- a/nacl/nacl-config.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/ruby
-#
-# Copyright:: Copyright 2012 Google Inc.
-# License:: All Rights Reserved.
-# Original Author:: Yugui Sonoda (mailto:yugui@google.com)
-#
-# Convenient functions/constants for native client specific configurations.
-require 'rbconfig'
-
-module NaClConfig
- config = RbConfig::CONFIG
-
- cpu_nick = config['host_alias'].sub(/-gnu$|-newlib$/, '').sub(/-nacl$/, '').sub(/i.86/, 'x86_32')
- ARCH = cpu_nick.sub('x86_64', 'x86-64').sub('x86_32', 'x86-32')
- HOST = ARCH.sub(/x86-../, 'x86_64') + '-nacl'
-
- lib_suffix = config['host_cpu'][/i.86/] ? '32' : ''
- PYTHON = config['PYTHON']
- OBJDUMP = config['OBJDUMP']
- SDK_ROOT = config['NACL_SDK_ROOT']
- CREATE_NMF = [
- File.join(SDK_ROOT, 'build_tools', 'nacl_sdk_scons', 'site_tools', 'create_nmf.py'),
- File.join(SDK_ROOT, 'tools', 'create_nmf.py')
- ].find{|path| File.exist?(path) } or raise "No create_nmf found"
- HOST_LIB = File.join(SDK_ROOT, 'toolchain', config['NACL_TOOLCHAIN'], HOST, "lib#{lib_suffix}")
-
- NACL_LIB = File.join(SDK_ROOT, 'lib', config['NACL_LIB_PATH'], 'Release')
-
- INSTALL_PROGRAM = config['INSTALL_PROGRAM']
- INSTALL_LIBRARY = config['INSTALL_DATA']
-
- if cpu_nick == 'x86_64' or cpu_nick == 'x86_32'
- SEL_LDR = File.join(SDK_ROOT, 'tools', "sel_ldr_#{cpu_nick}")
- IRT_CORE = File.join(SDK_ROOT, 'tools', "irt_core_#{cpu_nick}.nexe")
- raise "No sel_ldr found" if not File.executable?(SEL_LDR)
- raise "No irt_core found" if not File.exists?(IRT_CORE)
- end
- RUNNABLE_LD = File.join(HOST_LIB, 'runnable-ld.so')
-
- module_function
-
- def newlib?
- RbConfig::CONFIG['NACL_SDK_VARIANT'] == 'newlib'
- end
-
- def self.config(name)
- if NaClConfig::const_defined?(name.upcase)
- NaClConfig::const_get(name.upcase)
- elsif NaClConfig::respond_to?(name) and NaClConfig::method(name).arity == 0
- NaClConfig::send(name)
- else
- raise ArgumentError, "No such config: #{name}"
- end
- end
-end
-
-if $0 == __FILE__
- ARGV.each do |arg|
- puts NaClConfig::config(arg)
- end
-end
diff --git a/nacl/package.rb b/nacl/package.rb
deleted file mode 100644
index 9ba95888c4..0000000000
--- a/nacl/package.rb
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/ruby
-# Copyright:: Copyright 2012 Google Inc.
-# License:: All Rights Reserved.
-# Original Author:: Yugui Sonoda (mailto:yugui@google.com)
-#
-# Generates a runnable package of the pepper API example.
-
-require File.join(File.dirname(__FILE__), 'nacl-config')
-require 'json'
-require 'find'
-require 'fileutils'
-
-include NaClConfig
-
-class Installation
- include NaClConfig
-
- SRC_DIRS = [
- Dir.pwd,
- HOST_LIB,
- NACL_LIB,
- ]
-
- def initialize(destdir)
- @destdir = destdir
- @manifest = {
- "files" => {}
- }
- ruby_libs.each do |path|
- raise "Collision of #{path}" if @manifest['files'].key? path
- @manifest['files'][path] = {
- ARCH => {
- "url" => path
- }
- }
- if path[/\.so$/]
- alternate_path = path.gsub('/', "_")
- raise "Collision of #{alternate_path}" if @manifest['files'].key? alternate_path
- @manifest['files'][alternate_path] = {
- ARCH => {
- "url" => path
- }
- }
- end
- end
- end
-
- def manifest
- @manifest.dup
- end
-
- def install_program(basename)
- do_install_binary(basename, File.join(@destdir, "bin", ARCH))
- @manifest["program"] = {
- ARCH => {
- "url" => File.join("bin", ARCH, basename)
- }
- }
- end
-
- def install_library(name, basename)
- do_install_binary(basename, File.join(@destdir, "lib", ARCH))
- @manifest["files"][name] = {
- ARCH => {
- "url" => File.join("lib", ARCH, basename)
- }
- }
- end
-
- private
- def do_install_binary(basename, dest_dir)
- full_path = nil
- catch(:found) {
- SRC_DIRS.each do |path|
- full_path = File.join(path, basename)
- if File.exist? full_path
- throw :found
- end
- end
- raise Errno::ENOENT, "No such file to install: %s" % basename
- }
- FileUtils.mkdir_p dest_dir
- system("#{INSTALL_PROGRAM} #{full_path} #{dest_dir}")
- end
-
- def ruby_libs
- Find.find(RbConfig::CONFIG['rubylibdir']).select{|path| File.file?(path) }.map{|path| path.sub("#{@destdir}/", "") }
- end
-end
-
-def install(destdir)
- inst = Installation.new(destdir)
- manifest = JSON.parse(File.read("pepper-ruby.nmf"))
-
- program = File.basename(manifest['program'][ARCH]['url'])
- inst.install_program(program)
-
- manifest['files'].each do |name, attr|
- inst.install_library(name, File.basename(attr[ARCH]["url"]))
- end
-
- File.open(File.join(destdir, "ruby.nmf"), "w") {|f|
- f.puts JSON.pretty_generate(inst.manifest)
- }
-end
-
-def main
- install(ARGV[0])
-end
-
-if __FILE__ == $0
- main()
-end
diff --git a/nacl/pepper_main.c b/nacl/pepper_main.c
deleted file mode 100644
index 168e8f9fd4..0000000000
--- a/nacl/pepper_main.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/******************************************************************************
- Copyright 2012 Google Inc. All Rights Reserved.
- Author: yugui@google.com (Yugui Sonoda)
- ******************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <sys/mount.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/c/pp_module.h"
-#include "ppapi/c/pp_var.h"
-#include "ppapi/c/ppb.h"
-#include "ppapi/c/ppb_core.h"
-#include "ppapi/c/ppb_file_ref.h"
-#include "ppapi/c/ppb_instance.h"
-#include "ppapi/c/ppb_messaging.h"
-#include "ppapi/c/ppb_url_loader.h"
-#include "ppapi/c/ppb_url_request_info.h"
-#include "ppapi/c/ppb_url_response_info.h"
-#include "ppapi/c/ppb_var.h"
-#include "ppapi/c/ppp.h"
-#include "ppapi/c/ppp_instance.h"
-#include "ppapi/c/ppp_messaging.h"
-#include "nacl_io/nacl_io.h"
-
-#include "verconf.h"
-#include "ruby/ruby.h"
-#include "version.h"
-#include "gc.h"
-
-#ifdef HAVE_STRUCT_PPB_CORE
-typedef struct PPB_Core PPB_Core;
-#endif
-#ifdef HAVE_STRUCT_PPB_MESSAGING
-typedef struct PPB_Messaging PPB_Messaging;
-#endif
-#ifdef HAVE_STRUCT_PPB_VAR
-typedef struct PPB_Var PPB_Var;
-#endif
-#ifdef HAVE_STRUCT_PPB_URLLOADER
-typedef struct PPB_URLLoader PPB_URLLoader;
-#endif
-#ifdef HAVE_STRUCT_PPB_URLREQUESTINFO
-typedef struct PPB_URLRequestInfo PPB_URLRequestInfo;
-#endif
-#ifdef HAVE_STRUCT_PPB_URLRESPONSEINFO
-typedef struct PPB_URLResponseInfo PPB_URLResponseInfo;
-#endif
-#ifdef HAVE_STRUCT_PPP_INSTANCE
-typedef struct PPP_Instance PPP_Instance;
-#endif
-
-static PP_Module module_id = 0;
-static PPB_GetInterface get_browser_interface = NULL;
-static PPB_Core* core_interface = NULL;
-static PPB_Messaging* messaging_interface = NULL;
-static PPB_Var* var_interface = NULL;
-static PPB_URLLoader* loader_interface = NULL;
-static PPB_URLRequestInfo* request_interface = NULL;
-static PPB_URLResponseInfo* response_interface = NULL;
-static PPB_FileRef* fileref_interface = NULL;
-static struct st_table* instance_data = NULL;
-
-static VALUE instance_table = Qundef;
-
-static PP_Instance current_instance = 0;
-
-/******************************************************************************
- * State of instance
- ******************************************************************************/
-
-static void inst_mark(void *const ptr);
-static void inst_free(void *const ptr);
-static size_t inst_memsize(void *const ptr);
-static const rb_data_type_t pepper_instance_data_type = {
- "PepperInstance",
- { inst_mark, inst_free, inst_memsize }
-};
-
-struct PepperInstance {
- PP_Instance instance;
- PP_Resource url_loader;
- VALUE self;
- void* async_call_args;
- union {
- int32_t as_int;
- const char* as_str;
- VALUE as_value;
- } async_call_result;
- char buf[1000];
-
- pthread_t th;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-};
-
-struct PepperInstance*
-pruby_get_instance(PP_Instance instance)
-{
- VALUE self = rb_hash_aref(instance_table, INT2FIX(instance));
- if (RTEST(self)) {
- struct PepperInstance *inst;
- TypedData_Get_Struct(self, struct PepperInstance, &pepper_instance_data_type, inst);
- return inst;
- }
- else {
- return NULL;
- }
-}
-
-#define GET_PEPPER_INSTANCE() (pruby_get_instance(current_instance))
-
-struct PepperInstance*
-pruby_register_instance(PP_Instance instance)
-{
- VALUE obj;
- struct PepperInstance *data;
- obj = TypedData_Make_Struct(rb_cData, struct PepperInstance, &pepper_instance_data_type, data);
- data->self = obj;
- data->instance = instance;
- data->url_loader = 0;
-
- pthread_mutex_init(&data->mutex, NULL);
- pthread_cond_init(&data->cond, NULL);
-
- rb_hash_aset(instance_table, INT2FIX(instance), obj);
- return data;
-}
-
-int
-pruby_unregister_instance(PP_Instance instance)
-{
- VALUE inst = rb_hash_delete(instance_table, INT2FIX(instance));
- return RTEST(inst);
-}
-
-static void
-inst_mark(void *const ptr)
-{
- RUBY_MARK_ENTER("PepperInstance"0);
- if (ptr) {
- const struct PepperInstance* inst = (struct PepperInstance*)ptr;
- RUBY_MARK_UNLESS_NULL(inst->async_call_result.as_value);
- }
- RUBY_MARK_LEAVE("PepperInstance"0);
-}
-
-static void
-inst_free(void *const ptr)
-{
- ruby_xfree(ptr);
-}
-
-static size_t
-inst_memsize(void *const ptr)
-{
- if (ptr) {
- const struct PepperInstance* inst = (struct PepperInstance*)ptr;
- return sizeof(*inst);
- } else {
- return 0;
- }
-}
-
-void
-pruby_async_return_int(void* data, int32_t result)
-{
- /* PPAPI main thread */
- struct PepperInstance* const instance = (struct PepperInstance*)data;
- instance->async_call_result.as_int = result;
- if (pthread_cond_signal(&instance->cond)) {
- perror("pepper-ruby:pthread_cond_signal");
- }
-}
-
-void
-pruby_async_return_str(void* data, const char *result)
-{
- /* PPAPI main thread */
- struct PepperInstance* const instance = (struct PepperInstance*)data;
- instance->async_call_result.as_str = result;
- if (pthread_cond_signal(&instance->cond)) {
- perror("pepper-ruby:pthread_cond_signal");
- }
-}
-
-void
-pruby_async_return_value(void* data, VALUE value)
-{
- /* PPAPI main thread */
- struct PepperInstance* const instance = (struct PepperInstance*)data;
- instance->async_call_result.as_value = value;
- if (pthread_cond_signal(&instance->cond)) {
- perror("pepper-ruby:pthread_cond_signal");
- }
-}
-/******************************************************************************
- * Conversion between Ruby's VALUE, Pepper's Var and C string
- ******************************************************************************/
-
-/**
- * Creates a new string PP_Var from C string. The resulting object will be a
- * refcounted string object. It will be AddRef()ed for the caller. When the
- * caller is done with it, it should be Release()d.
- * @param[in] str C string to be converted to PP_Var
- * @return PP_Var containing string.
- */
-static struct PP_Var
-pruby_cstr_to_var(const char* str)
-{
-#ifndef PPB_VAR_INTERFACE_1_1
- if (var_interface != NULL)
- return var_interface->VarFromUtf8(module_id, str, strlen(str));
- return PP_MakeUndefined();
-#else
- return var_interface->VarFromUtf8(str, strlen(str));
-#endif
-}
-
-/**
- * Returns a mutable C string contained in the @a var or NULL if @a var is not
- * string. This makes a copy of the string in the @a var and adds a NULL
- * terminator. Note that VarToUtf8() does not guarantee the NULL terminator on
- * the returned string. See the comments for VarToUtf8() in ppapi/c/ppb_var.h
- * for more info. The caller is responsible for freeing the returned memory.
- * @param[in] var PP_Var containing string.
- * @return a mutable C string representation of @a var.
- * @note The caller is responsible for freeing the returned string.
- */
-static char*
-pruby_var_to_cstr(struct PP_Var var)
-{
- uint32_t len = 0;
- if (var_interface != NULL) {
- const char* var_c_str = var_interface->VarToUtf8(var, &len);
- if (len > 0) {
- char* c_str = (char*)malloc(len + 1);
- memcpy(c_str, var_c_str, len);
- c_str[len] = '\0';
- return c_str;
- }
- }
- return NULL;
-}
-
-static struct PP_Var
-pruby_str_to_var(volatile VALUE str)
-{
- if (!RB_TYPE_P(str, T_STRING)) {
- fprintf(stderr, "[BUG] Unexpected object type: %x\n", TYPE(str));
- exit(EXIT_FAILURE);
- }
-#ifndef PPB_VAR_INTERFACE_1_1
- if (var_interface != NULL) {
- return var_interface->VarFromUtf8(module_id, RSTRING_PTR(str), RSTRING_LEN(str));
- }
-#else
- return var_interface->VarFromUtf8(RSTRING_PTR(str), RSTRING_LEN(str));
-#endif
- return PP_MakeUndefined();
-}
-
-static struct PP_Var
-pruby_obj_to_var(volatile VALUE obj)
-{
- static const char* const error =
- "throw 'Failed to convert the result to a JavaScript object';";
- int state;
- obj = rb_protect(&rb_obj_as_string, obj, &state);
- if (!state) {
- return pruby_str_to_var(obj);
- }
- else {
- return pruby_cstr_to_var(error);
- }
-}
-
-int
-pruby_var_equal_to_cstr_p(struct PP_Var lhs, const char* rhs)
-{
- uint32_t len = 0;
- if (var_interface == NULL) {
- return 0;
- }
- else {
- const char* const cstr = var_interface->VarToUtf8(lhs, &len);
- return strncmp(cstr, rhs, len) == 0;
- }
-}
-
-int
-pruby_var_prefixed_p(struct PP_Var var, const char* prefix)
-{
- uint32_t len = 0;
- if (var_interface == NULL) {
- return 0;
- }
- else {
- const char* const cstr = var_interface->VarToUtf8(var, &len);
- const size_t prefix_len = strlen(prefix);
- return len >= prefix_len && memcmp(cstr, prefix, len) == 0;
- }
-}
-
-
-/******************************************************************************
- * Messaging
- ******************************************************************************/
-
-/* Posts the given C string as a message.
- * @param data pointer to a NULL-terminated string */
-void
-pruby_post_cstr(void* data)
-{
- /* PPAPI main thread */
- struct PepperInstance* const instance = (struct PepperInstance*)data;
- const char* const msg = (const char*)instance->async_call_args;
- messaging_interface->PostMessage(instance->instance,
- pruby_cstr_to_var(msg));
-}
-
-/* Posts the given Ruby VALUE as a message.
- * @param data a VALUE casted to void* */
-void
-pruby_post_value(void* data)
-{
- /* PPAPI main thread */
- struct PepperInstance* const instance = (struct PepperInstance*)data;
- volatile VALUE value = (VALUE)instance->async_call_args;
- messaging_interface->PostMessage(instance->instance, pruby_obj_to_var(value));
-}
-
-
-
-/******************************************************************************
- * Ruby initialization
- ******************************************************************************/
-
-static void
-init_loadpath(void)
-{
- ruby_incpush("lib/ruby/"RUBY_LIB_VERSION);
- ruby_incpush("lib/ruby/"RUBY_LIB_VERSION"/"RUBY_PLATFORM);
- ruby_incpush(".");
-}
-
-static VALUE
-init_libraries_internal(VALUE unused)
-{
- extern void Init_enc();
- extern void Init_ext();
-
- init_loadpath();
- Init_enc();
- Init_ext();
- return Qnil;
-}
-
-static void*
-init_libraries(void* data)
-{
- int state;
- struct PepperInstance* const instance = (struct PepperInstance*)data;
- current_instance = instance->instance;
-
- if (pthread_mutex_lock(&instance->mutex)) {
- perror("pepper-ruby:pthread_mutex_lock");
- return 0;
- }
- rb_protect(&init_libraries_internal, Qnil, &state);
- pthread_mutex_unlock(&instance->mutex);
-
- if (state) {
- volatile VALUE err = rb_errinfo();
- err = rb_obj_as_string(err);
- } else {
- instance->async_call_args = (void*)"rubyReady";
- core_interface->CallOnMainThread(
- 0, PP_MakeCompletionCallback(pruby_post_cstr, instance), 0);
- }
- return NULL;
-}
-
-static int
-init_libraries_if_necessary(void)
-{
- static int initialized = 0;
- if (!initialized) {
- struct PepperInstance* const instance = GET_PEPPER_INSTANCE();
- int err;
- initialized = 1;
- err = pthread_create(&instance->th, NULL, &init_libraries, instance);
- if (err) {
- fprintf(stderr, "pepper_ruby:pthread_create: %s\n", strerror(err));
- exit(EXIT_FAILURE);
- }
- pthread_detach(instance->th);
- }
- return 0;
-}
-
-static int
-reopen_fd(int fd, const char* path, int flags) {
- int fd2 = open(path, flags);
- if (fd2 < 0) {
- perror("open fd");
- return -1;
- }
- if (dup2(fd2, fd) < 0) {
- perror("dup2 fd");
- return -1;
- }
- if (close(fd2)) {
- perror("close old fd");
- return -1;
- }
- return fd;
-}
-
-static int
-pruby_init(void)
-{
- RUBY_INIT_STACK;
- ruby_init();
-
- instance_table = rb_hash_new();
- rb_gc_register_mark_object(instance_table);
-
- return 0;
-}
-
-
-/******************************************************************************
- * Ruby evaluation
- ******************************************************************************/
-
-static void*
-pruby_eval(void* data)
-{
- extern VALUE ruby_eval_string_from_file_protect(const char* src, const char* path, int* state);
- struct PepperInstance* const instance = (struct PepperInstance*)data;
- volatile VALUE src = (VALUE)instance->async_call_args;
- volatile VALUE result = Qnil;
- volatile int state;
-
- RUBY_INIT_STACK;
-
- if (pthread_mutex_lock(&instance->mutex)) {
- perror("pepper-ruby:pthread_mutex_lock");
- return 0;
- }
- result = ruby_eval_string_from_file_protect(
- RSTRING_PTR(src), "(pepper-ruby)", &state);
- pthread_mutex_unlock(&instance->mutex);
-
- if (!state) {
- instance->async_call_args =
- rb_str_concat(rb_usascii_str_new_cstr("return:"),
- rb_obj_as_string(result));
- core_interface->CallOnMainThread(
- 0, PP_MakeCompletionCallback(pruby_post_value, instance), 0);
- return NULL;
- }
- else {
- rb_set_errinfo(Qnil);
- instance->async_call_args =
- rb_str_concat(rb_usascii_str_new_cstr("error:"),
- rb_obj_as_string(result));
- core_interface->CallOnMainThread(
- 0, PP_MakeCompletionCallback(pruby_post_value, instance), 0);
- return NULL;
- }
-}
-
-
-/******************************************************************************
- * Pepper Module callbacks
- ******************************************************************************/
-
-/**
- * Called when the NaCl module is instantiated on the web page. The identifier
- * of the new instance will be passed in as the first argument (this value is
- * generated by the browser and is an opaque handle). This is called for each
- * instantiation of the NaCl module, which is each time the <embed> tag for
- * this module is encountered.
- *
- * If this function reports a failure (by returning @a PP_FALSE), the NaCl
- * module will be deleted and DidDestroy will be called.
- * @param[in] instance The identifier of the new instance representing this
- * NaCl module.
- * @param[in] argc The number of arguments contained in @a argn and @a argv.
- * @param[in] argn An array of argument names. These argument names are
- * supplied in the <embed> tag, for example:
- * <embed id="nacl_module" dimensions="2">
- * will produce two arguments, one named "id" and one named "dimensions".
- * @param[in] argv An array of argument values. These are the values of the
- * arguments listed in the <embed> tag. In the above example, there will
- * be two elements in this array, "nacl_module" and "2". The indices of
- * these values match the indices of the corresponding names in @a argn.
- * @return @a PP_TRUE on success.
- */
-static PP_Bool
-Instance_DidCreate(PP_Instance instance,
- uint32_t argc, const char* argn[], const char* argv[])
-{
- struct PepperInstance* data = pruby_register_instance(instance);
- current_instance = instance;
-
- nacl_io_init_ppapi(instance, get_browser_interface);
-
- if (mount("", "/dev2", "dev", 0, "")) {
- perror("mount dev");
- return PP_FALSE;
- }
- if (reopen_fd(0, "/dev2/stdin", O_RDONLY) < 0) {
- perror("reopen stdin");
- return PP_FALSE;
- }
- if (reopen_fd(1, "/dev2/stdout", O_WRONLY) < 0) {
- perror("reopen stdout");
- return PP_FALSE;
- }
- if (reopen_fd(2, "/dev2/console1", O_WRONLY) < 0) {
- perror("reopen stderr");
- return PP_FALSE;
- }
-
- /* TODO(yugui) Unmount original /dev */
-
- if (mount("/lib", "/lib", "httpfs",
- 0, "allow_cross_origin_requests=false")) {
- perror("mount httpfs");
- return PP_FALSE;
- }
-
- return init_libraries_if_necessary() ? PP_FALSE : PP_TRUE;
-}
-
-/**
- * Called when the NaCl module is destroyed. This will always be called,
- * even if DidCreate returned failure. This routine should deallocate any data
- * associated with the instance.
- * @param[in] instance The identifier of the instance representing this NaCl
- * module.
- */
-static void Instance_DidDestroy(PP_Instance instance) {
- struct PepperInstance* data = pruby_get_instance(instance);
- core_interface->ReleaseResource(data->url_loader);
- pruby_unregister_instance(instance);
-}
-
-/**
- * Called when the position, the size, or the clip rect of the element in the
- * browser that corresponds to this NaCl module has changed.
- * @param[in] instance The identifier of the instance representing this NaCl
- * module.
- * @param[in] position The location on the page of this NaCl module. This is
- * relative to the top left corner of the viewport, which changes as the
- * page is scrolled.
- * @param[in] clip The visible region of the NaCl module. This is relative to
- * the top left of the plugin's coordinate system (not the page). If the
- * plugin is invisible, @a clip will be (0, 0, 0, 0).
- */
-#ifndef PPP_INSTANCE_INTERFACE_1_1
-static void
-Instance_DidChangeView(PP_Instance instance,
- const struct PP_Rect* position,
- const struct PP_Rect* clip)
-{
-}
-#else
-static void
-Instance_DidChangeView(PP_Instance instance, PP_Resource view_resource)
-{
-}
-#endif
-
-/**
- * Notification that the given NaCl module has gained or lost focus.
- * Having focus means that keyboard events will be sent to the NaCl module
- * represented by @a instance. A NaCl module's default condition is that it
- * will not have focus.
- *
- * Note: clicks on NaCl modules will give focus only if you handle the
- * click event. You signal if you handled it by returning @a true from
- * HandleInputEvent. Otherwise the browser will bubble the event and give
- * focus to the element on the page that actually did end up consuming it.
- * If you're not getting focus, check to make sure you're returning true from
- * the mouse click in HandleInputEvent.
- * @param[in] instance The identifier of the instance representing this NaCl
- * module.
- * @param[in] has_focus Indicates whether this NaCl module gained or lost
- * event focus.
- */
-static void
-Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus)
-{
-}
-
-/**
- * Handler that gets called after a full-frame module is instantiated based on
- * registered MIME types. This function is not called on NaCl modules. This
- * function is essentially a place-holder for the required function pointer in
- * the PPP_Instance structure.
- * @param[in] instance The identifier of the instance representing this NaCl
- * module.
- * @param[in] url_loader A PP_Resource an open PPB_URLLoader instance.
- * @return PP_FALSE.
- */
-static PP_Bool
-Instance_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader)
-{
- /* NaCl modules do not need to handle the document load function. */
- return PP_FALSE;
-}
-
-
-/**
- * Handler for messages coming in from the browser via postMessage. The
- * @a var_message can contain anything: a JSON string; a string that encodes
- * method names and arguments; etc. For example, you could use JSON.stringify
- * in the browser to create a message that contains a method name and some
- * parameters, something like this:
- * var json_message = JSON.stringify({ "myMethod" : "3.14159" });
- * nacl_module.postMessage(json_message);
- * On receipt of this message in @a var_message, you could parse the JSON to
- * retrieve the method name, match it to a function call, and then call it with
- * the parameter.
- * @param[in] instance The instance ID.
- * @param[in] message The contents, copied by value, of the message sent from
- * browser via postMessage.
- */
-void
-Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message)
-{
- char* const message = pruby_var_to_cstr(var_message);
- size_t message_len = strlen(message);
- current_instance = instance;
-
- if (strstr(message, "eval:") != NULL) {
- volatile VALUE src;
- struct PepperInstance* const instance_data = GET_PEPPER_INSTANCE();
- int err;
-#define EVAL_PREFIX_LEN 5
- src = rb_str_new(message + EVAL_PREFIX_LEN, message_len - EVAL_PREFIX_LEN);
- instance_data->async_call_args = (void*)src;
- err = pthread_create(&instance_data->th, NULL, &pruby_eval, instance_data);
- if (err) {
- fprintf(stderr, "pepper_ruby:pthread_create: %s\n", strerror(err));
- exit(EXIT_FAILURE);
- }
- pthread_detach(instance_data->th);
- }
- free(message);
-}
-
-/**
- * Entry points for the module.
- * Initialize instance interface and scriptable object class.
- * @param[in] a_module_id Module ID
- * @param[in] get_browser_interface Pointer to PPB_GetInterface
- * @return PP_OK on success, any other value on failure.
- */
-PP_EXPORT int32_t
-PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface a_get_browser_interface)
-{
- module_id = a_module_id;
- get_browser_interface = a_get_browser_interface;
- core_interface = (PPB_Core*)(get_browser_interface(PPB_CORE_INTERFACE));
- if (core_interface == NULL) return PP_ERROR_NOINTERFACE;
-
- var_interface = (PPB_Var*)(get_browser_interface(PPB_VAR_INTERFACE));
- if (var_interface == NULL) return PP_ERROR_NOINTERFACE;
-
- messaging_interface = (PPB_Messaging*)(get_browser_interface(PPB_MESSAGING_INTERFACE));
- if (messaging_interface == NULL) return PP_ERROR_NOINTERFACE;
-
- loader_interface = (PPB_URLLoader*)(get_browser_interface(PPB_URLLOADER_INTERFACE));
- if (loader_interface == NULL) return PP_ERROR_NOINTERFACE;
-
- request_interface = (PPB_URLRequestInfo*)(get_browser_interface(PPB_URLREQUESTINFO_INTERFACE));
- if (request_interface == NULL) return PP_ERROR_NOINTERFACE;
-
- response_interface = (PPB_URLResponseInfo*)(get_browser_interface(PPB_URLRESPONSEINFO_INTERFACE));
- if (response_interface == NULL) return PP_ERROR_NOINTERFACE;
-
- fileref_interface = (PPB_FileRef*)(get_browser_interface(PPB_FILEREF_INTERFACE));
- if (fileref_interface == NULL) return PP_ERROR_NOINTERFACE;
-
- return pruby_init() ? PP_ERROR_FAILED : PP_OK;
-}
-
-/**
- * Returns an interface pointer for the interface of the given name, or NULL
- * if the interface is not supported.
- * @param[in] interface_name name of the interface
- * @return pointer to the interface
- */
-PP_EXPORT const void*
-PPP_GetInterface(const char* interface_name)
-{
- if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
- static PPP_Instance instance_interface = {
- &Instance_DidCreate,
- &Instance_DidDestroy,
- &Instance_DidChangeView,
- &Instance_DidChangeFocus,
- &Instance_HandleDocumentLoad
- };
- return &instance_interface;
- } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
- static PPP_Messaging messaging_interface = {
- &Messaging_HandleMessage
- };
- return &messaging_interface;
- }
- return NULL;
-}
-
-/**
- * Called before the plugin module is unloaded.
- */
-PP_EXPORT void
-PPP_ShutdownModule(void)
-{
- ruby_cleanup(0);
-}
diff --git a/nacl/resource.h b/nacl/resource.h
deleted file mode 100644
index 57ca53b093..0000000000
--- a/nacl/resource.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * Copyright 2011 Google Inc. All Rights Reserved.
- * Author: yugui@google.com (Yugui Sonoda)
- * */
-#ifndef RUBY_NACL_RESOURCE_H
-#define RUBY_NACL_RESOURCE_H
-int getrusage(int who, struct rusage *usage);
-#endif
diff --git a/nacl/select.h b/nacl/select.h
deleted file mode 100644
index 921721a2fd..0000000000
--- a/nacl/select.h
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-// Author: yugui@google.com (Yugui Sonoda)
-#ifndef RUBY_NACL_SELECT_H
-#define RUBY_NACL_SELECT_H
-int select(int num_fds, fd_set *in_fds, fd_set *out_fds,
- fd_set *ex_fds, struct timeval *timeout);
-#endif
diff --git a/nacl/signal.h b/nacl/signal.h
deleted file mode 100644
index 54832de1fe..0000000000
--- a/nacl/signal.h
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-// Author: yugui@google.com (Yugui Sonoda)
-#ifndef RUBY_NACL_SIGNAL_H
-#define RUBY_NACL_SIGNAL_H
-int kill(pid_t pid, int signal);
-#endif
diff --git a/nacl/stat.h b/nacl/stat.h
deleted file mode 100644
index 7be40ada7c..0000000000
--- a/nacl/stat.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2011 Google Inc. All Rights Reserved.
- * Author: yugui@google.com (Yugui Sonoda)
- * */
-#ifndef RUBY_NACL_STAT_H
-#define RUBY_NACL_STAT_H
-mode_t umask(mode_t mask);
-struct stat;
-int lstat(const char* path, struct stat* result);
-#endif
diff --git a/nacl/unistd.h b/nacl/unistd.h
deleted file mode 100644
index 1c97390c63..0000000000
--- a/nacl/unistd.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-// Author: yugui@google.com (Yugui Sonoda)
-#ifndef RUBY_NACL_UNISTD_H
-#define RUBY_NACL_UNISTD_H
-int seteuid(pid_t pid);
-int setegid(pid_t pid);
-int truncate(const char* path, off_t new_size);
-int ftruncate(int fd, off_t new_size);
-#endif
diff --git a/nacl/utime.h b/nacl/utime.h
deleted file mode 100644
index 96910051e4..0000000000
--- a/nacl/utime.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2011 Google Inc. All Rights Reserved.
- * Author: yugui@google.com (Yugui Sonoda)
- */
-
-#ifndef RUBY_NACL_UTIME_H
-#define RUBY_NACL_UTIME_H
-#include <utime.h>
-int utime(const char *filename, const struct utimbuf *times);
-int utimes(const char *filename, const struct timeval times[2]);
-#endif
diff --git a/node.c b/node.c
index a0544d7a7a..bef9d7bcbd 100644
--- a/node.c
+++ b/node.c
@@ -9,9 +9,14 @@
**********************************************************************/
+#include "internal.h"
+#include "internal/hash.h"
+#include "internal/variable.h"
#include "ruby/ruby.h"
#include "vm_core.h"
+#define NODE_BUF_DEFAULT_LEN 16
+
#define A(str) rb_str_cat2(buf, (str))
#define AR(str) rb_str_concat(buf, (str))
@@ -21,9 +26,13 @@
#define A_ID(id) add_id(buf, (id))
#define A_INT(val) rb_str_catf(buf, "%d", (val))
#define A_LONG(val) rb_str_catf(buf, "%ld", (val))
-#define A_LIT(lit) AR(rb_inspect(lit))
+#define A_LIT(lit) AR(rb_dump_literal(lit))
#define A_NODE_HEADER(node, term) \
- rb_str_catf(buf, "@ %s (line: %d)"term, ruby_node_name(nd_type(node)), nd_line(node))
+ rb_str_catf(buf, "@ %s (line: %d, location: (%d,%d)-(%d,%d))%s"term, \
+ ruby_node_name(nd_type(node)), nd_line(node), \
+ nd_first_lineno(node), nd_first_column(node), \
+ nd_last_lineno(node), nd_last_column(node), \
+ (node->flags & NODE_FL_NEWLINE ? "*" : ""))
#define A_FIELD_HEADER(len, name, term) \
rb_str_catf(buf, "+- %.*s:"term, (len), (name))
#define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
@@ -31,18 +40,12 @@
#define D_NULL_NODE (A_INDENT, A("(null node)\n"))
#define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
-#define COMPOUND_FIELD(len, name, block) \
- do { \
- D_FIELD_HEADER((len), (name), "\n"); \
- D_INDENT; \
- block; \
- D_DEDENT; \
- } while (0)
+#define COMPOUND_FIELD(len, name) \
+ FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
-#define COMPOUND_FIELD1(name, ann, block) \
+#define COMPOUND_FIELD1(name, ann) \
COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
- FIELD_NAME_DESC(name, ann), \
- block)
+ FIELD_NAME_DESC(name, ann))
#define FIELD_NAME_DESC(name, ann) name " (" ann ")"
#define FIELD_NAME_LEN(name, ann) (int)( \
@@ -50,23 +53,24 @@
rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
rb_strlen_lit(name))
#define SIMPLE_FIELD(len, name) \
- for (D_FIELD_HEADER((len), (name), " "), field_flag = 1; \
+ FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
+
+#define FIELD_BLOCK(init, reset) \
+ for (init, field_flag = 1; \
field_flag; /* should be optimized away */ \
- A("\n"), field_flag = 0)
+ reset, field_flag = 0)
#define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
#define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
#define F_ID(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
-#define F_GENTRY(name, ann) SIMPLE_FIELD1(#name, ann) A_ID((node->name)->id)
+#define F_GENTRY(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
#define F_INT(name, ann) SIMPLE_FIELD1(#name, ann) A_INT(node->name)
#define F_LONG(name, ann) SIMPLE_FIELD1(#name, ann) A_LONG(node->name)
#define F_LIT(name, ann) SIMPLE_FIELD1(#name, ann) A_LIT(node->name)
#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
#define F_NODE(name, ann) \
- COMPOUND_FIELD1(#name, ann, dump_node(buf, indent, comment, node->name))
-#define F_OPTION(name, ann) \
- COMPOUND_FIELD1(#name, ann, dump_option(buf, indent, node->name))
+ COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, node->name);}
#define ANN(ann) \
if (comment) { \
@@ -75,6 +79,25 @@
#define LAST_NODE (next_indent = " ")
+VALUE
+rb_dump_literal(VALUE lit)
+{
+ if (!RB_SPECIAL_CONST_P(lit)) {
+ VALUE str;
+ switch (RB_BUILTIN_TYPE(lit)) {
+ case T_CLASS: case T_MODULE: case T_ICLASS:
+ str = rb_class_path(lit);
+ if (FL_TEST(lit, FL_SINGLETON)) {
+ str = rb_sprintf("<%"PRIsVALUE">", str);
+ }
+ return str;
+ default:
+ break;
+ }
+ }
+ return rb_inspect(lit);
+}
+
static void
add_indent(VALUE buf, VALUE indent)
{
@@ -93,7 +116,7 @@ add_id(VALUE buf, ID id)
A(":"); AR(str);
}
else {
- A("(internal variable)");
+ rb_str_catf(buf, "(internal variable: 0x%"PRIsVALUE")", id);
}
}
}
@@ -103,48 +126,17 @@ struct add_option_arg {
st_index_t count;
};
-static int
-add_option_i(VALUE key, VALUE val, VALUE args)
-{
- struct add_option_arg *argp = (void *)args;
- VALUE buf = argp->buf;
- VALUE indent = argp->indent;
-
- A_INDENT;
- A("+- ");
- AR(rb_sym2str(key));
- A(": ");
- A_LIT(val);
- A("\n");
- return ST_CONTINUE;
-}
-
-static void
-dump_option(VALUE buf, VALUE indent, VALUE opt)
-{
- struct add_option_arg arg;
-
- if (!RB_TYPE_P(opt, T_HASH)) {
- A_LIT(opt);
- return;
- }
- arg.buf = buf;
- arg.indent = indent;
- arg.count = 0;
- rb_hash_foreach(opt, add_option_i, (VALUE)&arg);
-}
-
-static void dump_node(VALUE, VALUE, int, NODE *);
+static void dump_node(VALUE, VALUE, int, const NODE *);
static const char default_indent[] = "| ";
static void
-dump_array(VALUE buf, VALUE indent, int comment, NODE *node)
+dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
{
int field_flag;
const char *next_indent = default_indent;
F_LONG(nd_alen, "length");
F_NODE(nd_head, "element");
- while (node->nd_next && nd_type(node->nd_next) == NODE_ARRAY) {
+ while (node->nd_next && nd_type(node->nd_next) == NODE_LIST) {
node = node->nd_next;
F_NODE(nd_head, "element");
}
@@ -153,7 +145,7 @@ dump_array(VALUE buf, VALUE indent, int comment, NODE *node)
}
static void
-dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
+dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
{
int field_flag;
int i;
@@ -185,10 +177,11 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
} while (node->nd_next &&
nd_type(node->nd_next) == NODE_BLOCK &&
(node = node->nd_next, 1));
- if (!node->nd_next) break;
- LAST_NODE;
- F_NODE(nd_next, "next block");
- break;
+ if (node->nd_next) {
+ LAST_NODE;
+ F_NODE(nd_next, "next block");
+ }
+ return;
case NODE_IF:
ANN("if statement");
@@ -198,7 +191,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_body, "then clause");
LAST_NODE;
F_NODE(nd_else, "else clause");
- break;
+ return;
case NODE_UNLESS:
ANN("unless statement");
@@ -208,7 +201,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_body, "then clause");
LAST_NODE;
F_NODE(nd_else, "else clause");
- break;
+ return;
case NODE_CASE:
ANN("case statement");
@@ -217,23 +210,44 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_head, "case expr");
LAST_NODE;
F_NODE(nd_body, "when clauses");
- break;
+ return;
+ case NODE_CASE2:
+ ANN("case statement with no head");
+ ANN("format: case; [nd_body]; end");
+ ANN("example: case; when 1; foo; when 2; bar; else baz; end");
+ F_NODE(nd_head, "case expr");
+ LAST_NODE;
+ F_NODE(nd_body, "when clauses");
+ return;
+ case NODE_CASE3:
+ ANN("case statement (pattern matching)");
+ ANN("format: case [nd_head]; [nd_body]; end");
+ ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
+ F_NODE(nd_head, "case expr");
+ LAST_NODE;
+ F_NODE(nd_body, "in clauses");
+ return;
case NODE_WHEN:
- ANN("if statement");
+ ANN("when clause");
ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
F_NODE(nd_head, "when value");
- F_NODE(nd_body, "when clause");
+ F_NODE(nd_body, "when body");
LAST_NODE;
F_NODE(nd_next, "next when clause");
- break;
+ return;
+
+ case NODE_IN:
+ ANN("in clause");
+ ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
+ ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
+ F_NODE(nd_head, "in pattern");
+ F_NODE(nd_body, "in body");
+ LAST_NODE;
+ F_NODE(nd_next, "next in clause");
+ return;
- case NODE_OPT_N:
- ANN("wrapper for -n option");
- ANN("format: ruby -ne '[nd_body]' (nd_cond is `gets')");
- ANN("example: ruby -ne 'p $_'");
- goto loop;
case NODE_WHILE:
ANN("while statement");
ANN("format: while [nd_cond]; [nd_body]; end");
@@ -251,7 +265,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_cond, "condition");
LAST_NODE;
F_NODE(nd_body, "body");
- break;
+ return;
case NODE_ITER:
ANN("method call with block");
@@ -266,10 +280,18 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_iter, "iteration receiver");
LAST_NODE;
F_NODE(nd_body, "body");
- break;
+ return;
+
+ case NODE_FOR_MASGN:
+ ANN("vars of for statement with masgn");
+ ANN("format: for [nd_var] in ... do ... end");
+ ANN("example: for x, y in 1..3 do foo end");
+ LAST_NODE;
+ F_NODE(nd_var, "var");
+ return;
case NODE_BREAK:
- ANN("for statement");
+ ANN("break statement");
ANN("format: break [nd_stts]");
ANN("example: break 1");
goto jump;
@@ -285,19 +307,19 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
jump:
LAST_NODE;
F_NODE(nd_stts, "value");
- break;
+ return;
case NODE_REDO:
ANN("redo statement");
ANN("format: redo");
ANN("example: redo");
- break;
+ return;
case NODE_RETRY:
ANN("retry statement");
ANN("format: retry");
ANN("example: retry");
- break;
+ return;
case NODE_BEGIN:
ANN("begin statement");
@@ -305,7 +327,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: begin; 1; end");
LAST_NODE;
F_NODE(nd_body, "body");
- break;
+ return;
case NODE_RESCUE:
ANN("rescue clause");
@@ -315,7 +337,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_resq, "rescue clause list");
LAST_NODE;
F_NODE(nd_else, "rescue else clause");
- break;
+ return;
case NODE_RESBODY:
ANN("rescue clause (cont'd)");
@@ -325,7 +347,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_body, "rescue clause");
LAST_NODE;
F_NODE(nd_head, "next rescue clause");
- break;
+ return;
case NODE_ENSURE:
ANN("ensure clause");
@@ -334,7 +356,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_head, "body");
LAST_NODE;
F_NODE(nd_ensr, "ensure clause");
- break;
+ return;
case NODE_AND:
ANN("&& operator");
@@ -354,7 +376,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
}
LAST_NODE;
F_NODE(nd_2nd, "right expr");
- break;
+ return;
case NODE_MASGN:
ANN("multiple assignment");
@@ -362,50 +384,65 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: a, b = foo");
F_NODE(nd_value, "rhsn");
F_NODE(nd_head, "lhsn");
- if ((VALUE)node->nd_args != (VALUE)-1) {
+ if (NODE_NAMED_REST_P(node->nd_args)) {
LAST_NODE;
F_NODE(nd_args, "splatn");
}
else {
- F_MSG(nd_args, "splatn", "-1 (rest argument without name)");
+ F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
}
- break;
+ return;
case NODE_LASGN:
ANN("local variable assignment");
ANN("format: [nd_vid](lvar) = [nd_value]");
ANN("example: x = foo");
- goto asgn;
+ F_ID(nd_vid, "local variable");
+ if (NODE_REQUIRED_KEYWORD_P(node)) {
+ F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
+ }
+ else {
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ }
+ return;
case NODE_DASGN:
ANN("dynamic variable assignment (out of current scope)");
ANN("format: [nd_vid](dvar) = [nd_value]");
ANN("example: x = nil; 1.times { x = foo }");
- goto asgn;
+ F_ID(nd_vid, "local variable");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
case NODE_DASGN_CURR:
ANN("dynamic variable assignment (in current scope)");
ANN("format: [nd_vid](current dvar) = [nd_value]");
ANN("example: 1.times { x = foo }");
- goto asgn;
+ F_ID(nd_vid, "local variable");
+ if (NODE_REQUIRED_KEYWORD_P(node)) {
+ F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
+ }
+ else {
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ }
+ return;
case NODE_IASGN:
ANN("instance variable assignment");
ANN("format: [nd_vid](ivar) = [nd_value]");
ANN("example: @x = foo");
- goto asgn;
+ F_ID(nd_vid, "instance variable");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
case NODE_CVASGN:
ANN("class variable assignment");
ANN("format: [nd_vid](cvar) = [nd_value]");
ANN("example: @@x = foo");
- asgn:
- F_ID(nd_vid, "variable");
+ F_ID(nd_vid, "class variable");
LAST_NODE;
- if (node->nd_value == (NODE *)-1) {
- F_MSG(nd_value, "rvalue", "(required keyword argument)");
- }
- else {
- F_NODE(nd_value, "rvalue");
- }
- break;
-
+ F_NODE(nd_value, "rvalue");
+ return;
case NODE_GASGN:
ANN("global variable assignment");
ANN("format: [nd_entry](gvar) = [nd_value]");
@@ -413,44 +450,38 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_GENTRY(nd_entry, "global variable");
LAST_NODE;
F_NODE(nd_value, "rvalue");
- break;
+ return;
case NODE_CDECL:
ANN("constant declaration");
ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
ANN("example: X = foo");
if (node->nd_vid) {
- F_ID(nd_vid, "variable");
- F_MSG(nd_else, "extension", "not used");
+ F_ID(nd_vid, "constant");
+ F_MSG(nd_else, "extension", "not used");
}
else {
- F_MSG(nd_vid, "variable", "0 (see extension field)");
- F_NODE(nd_else, "extension");
+ F_MSG(nd_vid, "constant", "0 (see extension field)");
+ F_NODE(nd_else, "extension");
}
LAST_NODE;
F_NODE(nd_value, "rvalue");
- break;
+ return;
case NODE_OP_ASGN1:
ANN("array assignment with operator");
- ANN("format: [nd_value] [ [nd_args->nd_body] ] [nd_vid]= [nd_args->nd_head]");
+ ANN("format: [nd_recv] [ [nd_args->nd_head] ] [nd_mid]= [nd_args->nd_body]");
ANN("example: ary[1] += foo");
F_NODE(nd_recv, "receiver");
- F_CUSTOM1(nd_mid, "operator") {
- switch (node->nd_mid) {
- case 0: A("0 (||)"); break;
- case 1: A("1 (&&)"); break;
- default: A_ID(node->nd_mid);
- }
- };
+ F_ID(nd_mid, "operator");
F_NODE(nd_args->nd_head, "index");
LAST_NODE;
F_NODE(nd_args->nd_body, "rvalue");
- break;
+ return;
case NODE_OP_ASGN2:
ANN("attr assignment with operator");
- ANN("format: [nd_value].[attr] [nd_next->nd_mid]= [nd_value]");
+ ANN("format: [nd_recv].[attr] [nd_next->nd_mid]= [nd_value]");
ANN(" where [attr]: [nd_next->nd_vid]");
ANN("example: struct.field += foo");
F_NODE(nd_recv, "receiver");
@@ -458,16 +489,10 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
if (node->nd_next->nd_aid) A("? ");
A_ID(node->nd_next->nd_vid);
}
- F_CUSTOM1(nd_next->nd_mid, "operator") {
- switch (node->nd_next->nd_mid) {
- case 0: A("0 (||)"); break;
- case 1: A("1 (&&)"); break;
- default: A_ID(node->nd_next->nd_mid);
- }
- }
+ F_ID(nd_next->nd_mid, "operator");
LAST_NODE;
F_NODE(nd_value, "rvalue");
- break;
+ return;
case NODE_OP_ASGN_AND:
ANN("assignment with && operator");
@@ -482,10 +507,19 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_head, "variable");
LAST_NODE;
F_NODE(nd_value, "rvalue");
- break;
+ return;
+
+ case NODE_OP_CDECL:
+ ANN("constant declaration with operator");
+ ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
+ ANN("example: A::B ||= 1");
+ F_NODE(nd_head, "constant");
+ F_ID(nd_aid, "operator");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
case NODE_CALL:
- case NODE_OPCALL:
ANN("method invocation");
ANN("format: [nd_recv].[nd_mid]([nd_args])");
ANN("example: obj.foo(1)");
@@ -493,7 +527,17 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_recv, "receiver");
LAST_NODE;
F_NODE(nd_args, "arguments");
- break;
+ return;
+
+ case NODE_OPCALL:
+ ANN("method invocation");
+ ANN("format: [nd_recv] [nd_mid] [nd_args]");
+ ANN("example: foo + bar");
+ F_ID(nd_mid, "method id");
+ F_NODE(nd_recv, "receiver");
+ LAST_NODE;
+ F_NODE(nd_args, "arguments");
+ return;
case NODE_FCALL:
ANN("function call");
@@ -502,14 +546,14 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_ID(nd_mid, "method id");
LAST_NODE;
F_NODE(nd_args, "arguments");
- break;
+ return;
case NODE_VCALL:
ANN("function call with no argument");
ANN("format: [nd_mid]");
ANN("example: foo");
F_ID(nd_mid, "method id");
- break;
+ return;
case NODE_QCALL:
ANN("safe method invocation");
@@ -519,7 +563,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_recv, "receiver");
LAST_NODE;
F_NODE(nd_args, "arguments");
- break;
+ return;
case NODE_SUPER:
ANN("super invocation");
@@ -527,16 +571,16 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: super 1");
LAST_NODE;
F_NODE(nd_args, "arguments");
- break;
+ return;
case NODE_ZSUPER:
ANN("super invocation with no argument");
ANN("format: super");
ANN("example: super");
- break;
+ return;
- case NODE_ARRAY:
- ANN("array constructor");
+ case NODE_LIST:
+ ANN("list constructor");
ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
ANN("example: [1, 2, 3]");
goto ary;
@@ -546,16 +590,16 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: return 1, 2, 3");
ary:
dump_array(buf, indent, comment, node);
- break;
+ return;
- case NODE_ZARRAY:
- ANN("empty array constructor");
+ case NODE_ZLIST:
+ ANN("empty list constructor");
ANN("format: []");
ANN("example: []");
- break;
+ return;
case NODE_HASH:
- if (!node->nd_alen) {
+ if (!node->nd_brace) {
ANN("keyword arguments");
ANN("format: nd_head");
ANN("example: a: 1, b: 2");
@@ -565,9 +609,15 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("format: { [nd_head] }");
ANN("example: { 1 => 2, 3 => 4 }");
}
+ F_CUSTOM1(nd_brace, "keyword arguments or hash literal") {
+ switch (node->nd_brace) {
+ case 0: A("0 (keyword argument)"); break;
+ case 1: A("1 (hash literal)"); break;
+ }
+ }
LAST_NODE;
F_NODE(nd_head, "contents");
- break;
+ return;
case NODE_YIELD:
ANN("yield invocation");
@@ -575,49 +625,52 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: yield 1");
LAST_NODE;
F_NODE(nd_head, "arguments");
- break;
+ return;
case NODE_LVAR:
ANN("local variable reference");
ANN("format: [nd_vid](lvar)");
ANN("example: x");
- goto var;
+ F_ID(nd_vid, "local variable");
+ return;
case NODE_DVAR:
ANN("dynamic variable reference");
ANN("format: [nd_vid](dvar)");
ANN("example: 1.times { x = 1; x }");
- goto var;
+ F_ID(nd_vid, "local variable");
+ return;
case NODE_IVAR:
ANN("instance variable reference");
ANN("format: [nd_vid](ivar)");
ANN("example: @x");
- goto var;
+ F_ID(nd_vid, "instance variable");
+ return;
case NODE_CONST:
ANN("constant reference");
ANN("format: [nd_vid](constant)");
ANN("example: X");
- goto var;
+ F_ID(nd_vid, "constant");
+ return;
case NODE_CVAR:
ANN("class variable reference");
ANN("format: [nd_vid](cvar)");
ANN("example: @@x");
- var:
- F_ID(nd_vid, "local variable");
- break;
+ F_ID(nd_vid, "class variable");
+ return;
case NODE_GVAR:
ANN("global variable reference");
ANN("format: [nd_entry](gvar)");
ANN("example: $x");
F_GENTRY(nd_entry, "global variable");
- break;
+ return;
case NODE_NTH_REF:
ANN("nth special variable reference");
ANN("format: $[nd_nth]");
ANN("example: $1, $2, ..");
F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(node->nd_nth); }
- break;
+ return;
case NODE_BACK_REF:
ANN("back special variable reference");
@@ -630,14 +683,14 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
name[2] = '\0';
A(name);
}
- break;
+ return;
case NODE_MATCH:
ANN("match expression (against $_ implicitly)");
ANN("format: [nd_lit] (in condition)");
ANN("example: if /foo/; foo; end");
F_LIT(nd_lit, "regexp");
- break;
+ return;
case NODE_MATCH2:
ANN("match expression (regexp first)");
@@ -650,7 +703,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
LAST_NODE;
F_NODE(nd_args, "named captures");
}
- break;
+ return;
case NODE_MATCH3:
ANN("match expression (regexp second)");
@@ -659,7 +712,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_recv, "string (receiver)");
LAST_NODE;
F_NODE(nd_value, "regexp (argument)");
- break;
+ return;
case NODE_LIT:
ANN("literal");
@@ -677,8 +730,15 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: `foo`");
lit:
F_LIT(nd_lit, "literal");
- break;
+ return;
+ case NODE_ONCE:
+ ANN("once evaluation");
+ ANN("format: [nd_body]");
+ ANN("example: /foo#{ bar }baz/o");
+ LAST_NODE;
+ F_NODE(nd_body, "body");
+ return;
case NODE_DSTR:
ANN("string literal with interpolation");
ANN("format: [nd_lit]");
@@ -694,21 +754,17 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("format: [nd_lit]");
ANN("example: /foo#{ bar }baz/");
goto dlit;
- case NODE_DREGX_ONCE:
- ANN("regexp literal with interpolation and once flag");
- ANN("format: [nd_lit]");
- ANN("example: /foo#{ bar }baz/o");
- goto dlit;
case NODE_DSYM:
ANN("symbol literal with interpolation");
ANN("format: [nd_lit]");
ANN("example: :\"foo#{ bar }baz\"");
dlit:
F_LIT(nd_lit, "preceding string");
+ if (!node->nd_next) return;
F_NODE(nd_next->nd_head, "interpolation");
LAST_NODE;
F_NODE(nd_next->nd_next, "tailing strings");
- break;
+ return;
case NODE_EVSTR:
ANN("interpolation expression");
@@ -716,7 +772,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: \"foo#{ bar }baz\"");
LAST_NODE;
F_NODE(nd_body, "body");
- break;
+ return;
case NODE_ARGSCAT:
ANN("splat argument following arguments");
@@ -725,7 +781,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_head, "preceding array");
LAST_NODE;
F_NODE(nd_body, "following array");
- break;
+ return;
case NODE_ARGSPUSH:
ANN("splat argument following one argument");
@@ -734,7 +790,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_head, "preceding array");
LAST_NODE;
F_NODE(nd_body, "following element");
- break;
+ return;
case NODE_SPLAT:
ANN("splat argument");
@@ -742,7 +798,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: foo(*ary)");
LAST_NODE;
F_NODE(nd_head, "splat'ed array");
- break;
+ return;
case NODE_BLOCK_PASS:
ANN("arguments with block argument");
@@ -751,51 +807,51 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_head, "other arguments");
LAST_NODE;
F_NODE(nd_body, "block argument");
- break;
+ return;
case NODE_DEFN:
ANN("method definition");
ANN("format: def [nd_mid] [nd_defn]; end");
- ANN("example; def foo; bar; end");
+ ANN("example: def foo; bar; end");
F_ID(nd_mid, "method name");
LAST_NODE;
F_NODE(nd_defn, "method definition");
- break;
+ return;
case NODE_DEFS:
ANN("singleton method definition");
ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
- ANN("example; def obj.foo; bar; end");
+ ANN("example: def obj.foo; bar; end");
F_NODE(nd_recv, "receiver");
F_ID(nd_mid, "method name");
LAST_NODE;
F_NODE(nd_defn, "method definition");
- break;
+ return;
case NODE_ALIAS:
ANN("method alias statement");
- ANN("format: alias [u1.node] [u2.node]");
+ ANN("format: alias [nd_1st] [nd_2nd]");
ANN("example: alias bar foo");
- F_NODE(u1.node, "new name");
+ F_NODE(nd_1st, "new name");
LAST_NODE;
- F_NODE(u2.node, "old name");
- break;
+ F_NODE(nd_2nd, "old name");
+ return;
case NODE_VALIAS:
ANN("global variable alias statement");
- ANN("format: alias [u1.id](gvar) [u2.id](gvar)");
+ ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
ANN("example: alias $y $x");
- F_ID(u1.id, "new name");
- F_ID(u2.id, "old name");
- break;
+ F_ID(nd_alias, "new name");
+ F_ID(nd_orig, "old name");
+ return;
case NODE_UNDEF:
- ANN("method alias statement");
- ANN("format: undef [u2.node]");
+ ANN("method undef statement");
+ ANN("format: undef [nd_undef]");
ANN("example: undef foo");
LAST_NODE;
- F_NODE(u2.node, "old name");
- break;
+ F_NODE(nd_undef, "old name");
+ return;
case NODE_CLASS:
ANN("class definition");
@@ -805,7 +861,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_super, "superclass");
LAST_NODE;
F_NODE(nd_body, "class definition");
- break;
+ return;
case NODE_MODULE:
ANN("module definition");
@@ -814,7 +870,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_cpath, "module path");
LAST_NODE;
F_NODE(nd_body, "module definition");
- break;
+ return;
case NODE_SCLASS:
ANN("singleton class definition");
@@ -823,7 +879,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_recv, "receiver");
LAST_NODE;
F_NODE(nd_body, "singleton class definition");
- break;
+ return;
case NODE_COLON2:
ANN("scoped constant reference");
@@ -832,14 +888,14 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_ID(nd_mid, "constant name");
LAST_NODE;
F_NODE(nd_head, "receiver");
- break;
+ return;
case NODE_COLON3:
ANN("top-level constant reference");
ANN("format: ::[nd_mid]");
ANN("example: ::Object");
F_ID(nd_mid, "constant name");
- break;
+ return;
case NODE_DOT2:
ANN("range constructor (incl.)");
@@ -864,44 +920,44 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_beg, "begin");
LAST_NODE;
F_NODE(nd_end, "end");
- break;
+ return;
case NODE_SELF:
ANN("self");
ANN("format: self");
ANN("example: self");
- break;
+ return;
case NODE_NIL:
ANN("nil");
ANN("format: nil");
ANN("example: nil");
- break;
+ return;
case NODE_TRUE:
ANN("true");
ANN("format: true");
ANN("example: true");
- break;
+ return;
case NODE_FALSE:
ANN("false");
ANN("format: false");
ANN("example: false");
- break;
+ return;
case NODE_ERRINFO:
ANN("virtual reference to $!");
ANN("format: rescue => id");
ANN("example: rescue => id");
- break;
+ return;
case NODE_DEFINED:
ANN("defined? expression");
ANN("format: defined?([nd_head])");
ANN("example: defined?(foo)");
F_NODE(nd_head, "expr");
- break;
+ return;
case NODE_POSTEXE:
ANN("post-execution");
@@ -909,36 +965,17 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: END { foo }");
LAST_NODE;
F_NODE(nd_body, "END clause");
- break;
+ return;
case NODE_ATTRASGN:
ANN("attr assignment");
ANN("format: [nd_recv].[nd_mid] = [nd_args]");
ANN("example: struct.field = foo");
- if (node->nd_recv == (NODE *) 1) {
- F_MSG(nd_recv, "receiver", "1 (self)");
- }
- else {
- F_NODE(nd_recv, "receiver");
- }
+ F_NODE(nd_recv, "receiver");
F_ID(nd_mid, "method name");
LAST_NODE;
F_NODE(nd_args, "arguments");
- break;
-
- case NODE_PRELUDE:
- ANN("pre-execution");
- ANN("format: BEGIN { [nd_head] }; [nd_body]");
- ANN("example: bar; BEGIN { foo }");
-#define nd_compile_option u3.value
- F_NODE(nd_head, "prelude");
- if (!node->nd_compile_option) LAST_NODE;
- F_NODE(nd_body, "body");
- if (node->nd_compile_option) {
- LAST_NODE;
- F_OPTION(nd_compile_option, "compile_option");
- }
- break;
+ return;
case NODE_LAMBDA:
ANN("lambda expression");
@@ -946,7 +983,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
ANN("example: -> { foo }");
LAST_NODE;
F_NODE(nd_body, "lambda clause");
- break;
+ return;
case NODE_OPT_ARG:
ANN("optional arguments");
@@ -955,7 +992,7 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_body, "body");
LAST_NODE;
F_NODE(nd_next, "next");
- break;
+ return;
case NODE_KW_ARG:
ANN("keyword arguments");
@@ -964,21 +1001,21 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_body, "body");
LAST_NODE;
F_NODE(nd_next, "next");
- break;
+ return;
case NODE_POSTARG:
ANN("post arguments");
ANN("format: *[nd_1st], [nd_2nd..] = ..");
ANN("example: a, *rest, z = foo");
- if ((VALUE)node->nd_1st != (VALUE)-1) {
+ if (NODE_NAMED_REST_P(node->nd_1st)) {
F_NODE(nd_1st, "rest argument");
}
else {
- F_MSG(nd_1st, "rest argument", "-1 (rest argument without name)");
+ F_MSG(nd_1st, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
}
LAST_NODE;
F_NODE(nd_2nd, "post arguments");
- break;
+ return;
case NODE_ARGS:
ANN("method parameters");
@@ -989,13 +1026,20 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_INT(nd_ainfo->post_args_num, "count of mandatory post-arguments");
F_NODE(nd_ainfo->post_init, "initialization of post-arguments");
F_ID(nd_ainfo->first_post_arg, "first post argument");
- F_ID(nd_ainfo->rest_arg, "rest argument");
+ F_CUSTOM1(nd_ainfo->rest_arg, "rest argument") {
+ if (node->nd_ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) {
+ A("1 (excessed comma)");
+ }
+ else {
+ A_ID(node->nd_ainfo->rest_arg);
+ }
+ }
F_ID(nd_ainfo->block_arg, "block argument");
F_NODE(nd_ainfo->opt_args, "optional arguments");
F_NODE(nd_ainfo->kw_args, "keyword arguments");
LAST_NODE;
F_NODE(nd_ainfo->kw_rest_arg, "keyword rest argument");
- break;
+ return;
case NODE_SCOPE:
ANN("new scope");
@@ -1012,15 +1056,68 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
F_NODE(nd_args, "arguments");
LAST_NODE;
F_NODE(nd_body, "body");
- break;
+ return;
- default:
- rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
+ case NODE_ARYPTN:
+ ANN("array pattern");
+ ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
+ F_NODE(nd_pconst, "constant");
+ F_NODE(nd_apinfo->pre_args, "pre arguments");
+ if (NODE_NAMED_REST_P(node->nd_apinfo->rest_arg)) {
+ F_NODE(nd_apinfo->rest_arg, "rest argument");
+ }
+ else {
+ F_MSG(nd_apinfo->rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ LAST_NODE;
+ F_NODE(nd_apinfo->post_args, "post arguments");
+ return;
+
+ case NODE_FNDPTN:
+ ANN("find pattern");
+ ANN("format: [nd_pconst](*[pre_rest_arg], args, ..., *[post_rest_arg])");
+ F_NODE(nd_pconst, "constant");
+ if (NODE_NAMED_REST_P(node->nd_fpinfo->pre_rest_arg)) {
+ F_NODE(nd_fpinfo->pre_rest_arg, "pre rest argument");
+ }
+ else {
+ F_MSG(nd_fpinfo->pre_rest_arg, "pre rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ F_NODE(nd_fpinfo->args, "arguments");
+
+ LAST_NODE;
+ if (NODE_NAMED_REST_P(node->nd_fpinfo->post_rest_arg)) {
+ F_NODE(nd_fpinfo->post_rest_arg, "post rest argument");
+ }
+ else {
+ F_MSG(nd_fpinfo->post_rest_arg, "post rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ return;
+
+ case NODE_HSHPTN:
+ ANN("hash pattern");
+ ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
+ F_NODE(nd_pconst, "constant");
+ F_NODE(nd_pkwargs, "keyword arguments");
+ LAST_NODE;
+ if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
+ F_MSG(nd_pkwrestarg, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
+ }
+ else {
+ F_NODE(nd_pkwrestarg, "keyword rest argument");
+ }
+ return;
+
+ case NODE_ARGS_AUX:
+ case NODE_LAST:
+ break;
}
+
+ rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
}
VALUE
-rb_parser_dump_tree(NODE *node, int comment)
+rb_parser_dump_tree(const NODE *node, int comment)
{
VALUE buf = rb_str_new_cstr(
"###########################################################\n"
@@ -1032,178 +1129,332 @@ rb_parser_dump_tree(NODE *node, int comment)
return buf;
}
+/* Setup NODE structure.
+ * NODE is not an object managed by GC, but it imitates an object
+ * so that it can work with `RB_TYPE_P(obj, T_NODE)`.
+ * This dirty hack is needed because Ripper jumbles NODEs and other type
+ * objects.
+ */
void
-rb_gc_free_node(VALUE obj)
+rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
{
- switch (nd_type(obj)) {
- case NODE_SCOPE:
- if (RNODE(obj)->nd_tbl) {
- xfree(RNODE(obj)->nd_tbl);
- }
- break;
- case NODE_ARGS:
- if (RNODE(obj)->nd_ainfo) {
- xfree(RNODE(obj)->nd_ainfo);
- }
- break;
- case NODE_ALLOCA:
- xfree(RNODE(obj)->u1.node);
- break;
+ n->flags = T_NODE;
+ nd_init_type(n, type);
+ n->u1.value = a0;
+ n->u2.value = a1;
+ n->u3.value = a2;
+ n->nd_loc.beg_pos.lineno = 0;
+ n->nd_loc.beg_pos.column = 0;
+ n->nd_loc.end_pos.lineno = 0;
+ n->nd_loc.end_pos.column = 0;
+}
+
+typedef struct node_buffer_elem_struct {
+ struct node_buffer_elem_struct *next;
+ long len;
+ NODE buf[FLEX_ARY_LEN];
+} node_buffer_elem_t;
+
+typedef struct {
+ long idx, len;
+ node_buffer_elem_t *head;
+ node_buffer_elem_t *last;
+} node_buffer_list_t;
+
+struct node_buffer_struct {
+ node_buffer_list_t unmarkable;
+ node_buffer_list_t markable;
+ ID *local_tables;
+ VALUE mark_hash;
+};
+
+static void
+init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
+{
+ nb->idx = 0;
+ nb->len = NODE_BUF_DEFAULT_LEN;
+ nb->head = nb->last = head;
+ nb->head->len = nb->len;
+ nb->head->next = NULL;
+}
+
+static node_buffer_t *
+rb_node_buffer_new(void)
+{
+ const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
+ const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
+ STATIC_ASSERT(
+ integer_overflow,
+ offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE)
+ > sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
+ node_buffer_t *nb = ruby_xmalloc(alloc_size);
+ init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
+ init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
+ nb->local_tables = 0;
+ nb->mark_hash = Qnil;
+ return nb;
+}
+
+static void
+node_buffer_list_free(node_buffer_list_t * nb)
+{
+ node_buffer_elem_t *nbe = nb->head;
+
+ while (nbe != nb->last) {
+ void *buf = nbe;
+ nbe = nbe->next;
+ xfree(buf);
}
}
-size_t
-rb_node_memsize(VALUE obj)
+static void
+rb_node_buffer_free(node_buffer_t *nb)
{
- size_t size = 0;
- switch (nd_type(obj)) {
- case NODE_SCOPE:
- if (RNODE(obj)->nd_tbl) {
- size += (RNODE(obj)->nd_tbl[0]+1) * sizeof(*RNODE(obj)->nd_tbl);
- }
- break;
- case NODE_ARGS:
- if (RNODE(obj)->nd_ainfo) {
- size += sizeof(*RNODE(obj)->nd_ainfo);
- }
- break;
- case NODE_ALLOCA:
- size += RNODE(obj)->nd_cnt * sizeof(VALUE);
- break;
+ node_buffer_list_free(&nb->unmarkable);
+ node_buffer_list_free(&nb->markable);
+ ID * local_table = nb->local_tables;
+ while (local_table) {
+ unsigned int size = (unsigned int)*local_table;
+ ID * next_table = (ID *)local_table[size + 1];
+ xfree(local_table);
+ local_table = next_table;
}
- return size;
+ xfree(nb);
}
-VALUE
-rb_gc_mark_node(NODE *obj)
+static NODE *
+ast_newnode_in_bucket(node_buffer_list_t *nb)
{
- switch (nd_type(obj)) {
- case NODE_IF: /* 1,2,3 */
- case NODE_FOR:
- case NODE_ITER:
- case NODE_WHEN:
- case NODE_MASGN:
- case NODE_RESCUE:
- case NODE_RESBODY:
- case NODE_CLASS:
- case NODE_MATCH2:
- rb_gc_mark(RNODE(obj)->u2.value);
- /* fall through */
- case NODE_BLOCK: /* 1,3 */
- case NODE_ARRAY:
+ if (nb->idx >= nb->len) {
+ long n = nb->len * 2;
+ node_buffer_elem_t *nbe;
+ nbe = rb_xmalloc_mul_add(n, sizeof(NODE), offsetof(node_buffer_elem_t, buf));
+ nbe->len = n;
+ nb->idx = 0;
+ nb->len = n;
+ nbe->next = nb->head;
+ nb->head = nbe;
+ }
+ return &nb->head->buf[nb->idx++];
+}
+
+RBIMPL_ATTR_PURE()
+static bool
+nodetype_markable_p(enum node_type type)
+{
+ switch (type) {
+ case NODE_MATCH:
+ case NODE_LIT:
+ case NODE_STR:
+ case NODE_XSTR:
case NODE_DSTR:
case NODE_DXSTR:
case NODE_DREGX:
- case NODE_DREGX_ONCE:
- case NODE_ENSURE:
- case NODE_CALL:
- case NODE_DEFS:
- case NODE_OP_ASGN1:
- rb_gc_mark(RNODE(obj)->u1.value);
- /* fall through */
- case NODE_SUPER: /* 3 */
- case NODE_FCALL:
- case NODE_DEFN:
- case NODE_ARGS_AUX:
- return RNODE(obj)->u3.value;
+ case NODE_DSYM:
+ case NODE_ARGS:
+ case NODE_ARYPTN:
+ case NODE_FNDPTN:
+ return true;
+ default:
+ return false;
+ }
+}
- case NODE_WHILE: /* 1,2 */
- case NODE_UNTIL:
- case NODE_AND:
- case NODE_OR:
- case NODE_CASE:
- case NODE_SCLASS:
- case NODE_DOT2:
- case NODE_DOT3:
- case NODE_FLIP2:
- case NODE_FLIP3:
- case NODE_MATCH3:
- case NODE_OP_ASGN_OR:
- case NODE_OP_ASGN_AND:
- case NODE_MODULE:
- case NODE_ALIAS:
- case NODE_VALIAS:
- case NODE_ARGSCAT:
- case NODE_BLOCK_PASS:
- rb_gc_mark(RNODE(obj)->u1.value);
- /* fall through */
- case NODE_GASGN: /* 2 */
- case NODE_LASGN:
- case NODE_DASGN:
- case NODE_DASGN_CURR:
- case NODE_IASGN:
- case NODE_IASGN2:
- case NODE_CVASGN:
- case NODE_COLON3:
- case NODE_OPT_N:
- case NODE_EVSTR:
- case NODE_UNDEF:
- case NODE_POSTEXE:
- return RNODE(obj)->u2.value;
+NODE *
+rb_ast_newnode(rb_ast_t *ast, enum node_type type)
+{
+ node_buffer_t *nb = ast->node_buffer;
+ node_buffer_list_t *bucket =
+ (nodetype_markable_p(type) ? &nb->markable : &nb->unmarkable);
+ return ast_newnode_in_bucket(bucket);
+}
+
+void
+rb_ast_node_type_change(NODE *n, enum node_type type)
+{
+ enum node_type old_type = nd_type(n);
+ if (nodetype_markable_p(old_type) != nodetype_markable_p(type)) {
+ rb_bug("node type changed: %s -> %s",
+ ruby_node_name(old_type), ruby_node_name(type));
+ }
+}
+
+void
+rb_ast_add_local_table(rb_ast_t *ast, ID *buf)
+{
+ unsigned int size = (unsigned int)*buf;
+ buf[size + 1] = (ID)ast->node_buffer->local_tables;
+ ast->node_buffer->local_tables = buf;
+}
+
+void
+rb_ast_delete_node(rb_ast_t *ast, NODE *n)
+{
+ (void)ast;
+ (void)n;
+ /* should we implement freelist? */
+}
+
+rb_ast_t *
+rb_ast_new(void)
+{
+ node_buffer_t *nb = rb_node_buffer_new();
+ rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, (VALUE)nb);
+ return ast;
+}
+
+typedef void node_itr_t(void *ctx, NODE * node);
+
+static void
+iterate_buffer_elements(node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
+{
+ long cursor;
+ for (cursor = 0; cursor < len; cursor++) {
+ func(ctx, &nbe->buf[cursor]);
+ }
+}
+
+static void
+iterate_node_values(node_buffer_list_t *nb, node_itr_t * func, void *ctx)
+{
+ node_buffer_elem_t *nbe = nb->head;
+
+ /* iterate over the head first because it's not full */
+ iterate_buffer_elements(nbe, nb->idx, func, ctx);
+
+ nbe = nbe->next;
+ while (nbe) {
+ iterate_buffer_elements(nbe, nbe->len, func, ctx);
+ nbe = nbe->next;
+ }
+}
- case NODE_HASH: /* 1 */
+static void
+mark_ast_value(void *ctx, NODE * node)
+{
+ switch (nd_type(node)) {
+ case NODE_ARGS:
+ {
+ struct rb_args_info *args = node->nd_ainfo;
+ rb_gc_mark_movable(args->imemo);
+ break;
+ }
+ case NODE_MATCH:
case NODE_LIT:
case NODE_STR:
case NODE_XSTR:
- case NODE_DEFINED:
+ case NODE_DSTR:
+ case NODE_DXSTR:
+ case NODE_DREGX:
+ case NODE_DSYM:
+ rb_gc_mark_movable(node->nd_lit);
+ break;
+ case NODE_ARYPTN:
+ case NODE_FNDPTN:
+ rb_gc_mark_movable(node->nd_rval);
+ break;
+ default:
+ rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
+ }
+}
+
+static void
+update_ast_value(void *ctx, NODE * node)
+{
+ switch (nd_type(node)) {
+ case NODE_ARGS:
+ {
+ struct rb_args_info *args = node->nd_ainfo;
+ args->imemo = rb_gc_location(args->imemo);
+ break;
+ }
case NODE_MATCH:
- case NODE_RETURN:
- case NODE_BREAK:
- case NODE_NEXT:
- case NODE_YIELD:
- case NODE_COLON2:
- case NODE_SPLAT:
- case NODE_TO_ARY:
- return RNODE(obj)->u1.value;
+ case NODE_LIT:
+ case NODE_STR:
+ case NODE_XSTR:
+ case NODE_DSTR:
+ case NODE_DXSTR:
+ case NODE_DREGX:
+ case NODE_DSYM:
+ node->nd_lit = rb_gc_location(node->nd_lit);
+ break;
+ case NODE_ARYPTN:
+ case NODE_FNDPTN:
+ node->nd_rval = rb_gc_location(node->nd_rval);
+ break;
+ default:
+ rb_bug("unreachable");
+ }
+}
- case NODE_SCOPE: /* 2,3 */
- case NODE_CDECL:
- case NODE_OPT_ARG:
- rb_gc_mark(RNODE(obj)->u3.value);
- return RNODE(obj)->u2.value;
-
- case NODE_ARGS: /* custom */
- {
- struct rb_args_info *args = obj->u3.args;
- if (args) {
- if (args->pre_init) rb_gc_mark((VALUE)args->pre_init);
- if (args->post_init) rb_gc_mark((VALUE)args->post_init);
- if (args->opt_args) rb_gc_mark((VALUE)args->opt_args);
- if (args->kw_args) rb_gc_mark((VALUE)args->kw_args);
- if (args->kw_rest_arg) rb_gc_mark((VALUE)args->kw_rest_arg);
- }
- }
- return RNODE(obj)->u2.value;
+void
+rb_ast_update_references(rb_ast_t *ast)
+{
+ if (ast->node_buffer) {
+ node_buffer_t *nb = ast->node_buffer;
- case NODE_ZARRAY: /* - */
- case NODE_ZSUPER:
- case NODE_VCALL:
- case NODE_GVAR:
- case NODE_LVAR:
- case NODE_DVAR:
- case NODE_IVAR:
- case NODE_CVAR:
- case NODE_NTH_REF:
- case NODE_BACK_REF:
- case NODE_REDO:
- case NODE_RETRY:
- case NODE_SELF:
- case NODE_NIL:
- case NODE_TRUE:
- case NODE_FALSE:
- case NODE_ERRINFO:
- case NODE_BLOCK_ARG:
- break;
- case NODE_ALLOCA:
- rb_gc_mark_locations((VALUE*)RNODE(obj)->u1.value,
- (VALUE*)RNODE(obj)->u1.value + RNODE(obj)->u3.cnt);
- rb_gc_mark(RNODE(obj)->u2.value);
- break;
+ iterate_node_values(&nb->markable, update_ast_value, NULL);
+ }
+}
+
+void
+rb_ast_mark(rb_ast_t *ast)
+{
+ if (ast->node_buffer) rb_gc_mark(ast->node_buffer->mark_hash);
+ if (ast->body.compile_option) rb_gc_mark(ast->body.compile_option);
+ if (ast->node_buffer) {
+ node_buffer_t *nb = ast->node_buffer;
- default: /* unlisted NODE */
- rb_gc_mark_maybe(RNODE(obj)->u1.value);
- rb_gc_mark_maybe(RNODE(obj)->u2.value);
- rb_gc_mark_maybe(RNODE(obj)->u3.value);
+ iterate_node_values(&nb->markable, mark_ast_value, NULL);
+ }
+}
+
+void
+rb_ast_free(rb_ast_t *ast)
+{
+ if (ast->node_buffer) {
+ rb_node_buffer_free(ast->node_buffer);
+ ast->node_buffer = 0;
+ }
+}
+
+static size_t
+buffer_list_size(node_buffer_list_t *nb)
+{
+ size_t size = 0;
+ node_buffer_elem_t *nbe = nb->head;
+ while (nbe != nb->last) {
+ nbe = nbe->next;
+ size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
+ }
+ return size;
+}
+
+size_t
+rb_ast_memsize(const rb_ast_t *ast)
+{
+ size_t size = 0;
+ node_buffer_t *nb = ast->node_buffer;
+
+ if (nb) {
+ size += sizeof(node_buffer_t) + offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
+ size += buffer_list_size(&nb->unmarkable);
+ size += buffer_list_size(&nb->markable);
+ }
+ return size;
+}
+
+void
+rb_ast_dispose(rb_ast_t *ast)
+{
+ rb_ast_free(ast);
+}
+
+void
+rb_ast_add_mark_object(rb_ast_t *ast, VALUE obj)
+{
+ if (NIL_P(ast->node_buffer->mark_hash)) {
+ RB_OBJ_WRITE(ast, &ast->node_buffer->mark_hash, rb_ident_hash_new());
}
- return 0;
+ rb_hash_aset(ast->node_buffer->mark_hash, obj, Qtrue);
}
diff --git a/node.h b/node.h
index f1c8029257..192e121fd7 100644
--- a/node.h
+++ b/node.h
@@ -1,3 +1,5 @@
+#ifndef RUBY_NODE_H
+#define RUBY_NODE_H 1
/**********************************************************************
node.h -
@@ -9,9 +11,6 @@
**********************************************************************/
-#ifndef RUBY_NODE_H
-#define RUBY_NODE_H 1
-
#if defined(__cplusplus)
extern "C" {
#if 0
@@ -21,229 +20,138 @@ extern "C" {
enum node_type {
NODE_SCOPE,
-#define NODE_SCOPE NODE_SCOPE
NODE_BLOCK,
-#define NODE_BLOCK NODE_BLOCK
NODE_IF,
-#define NODE_IF NODE_IF
NODE_UNLESS,
-#define NODE_UNLESS NODE_UNLESS
NODE_CASE,
-#define NODE_CASE NODE_CASE
+ NODE_CASE2,
+ NODE_CASE3,
NODE_WHEN,
-#define NODE_WHEN NODE_WHEN
- NODE_OPT_N,
-#define NODE_OPT_N NODE_OPT_N
+ NODE_IN,
NODE_WHILE,
-#define NODE_WHILE NODE_WHILE
NODE_UNTIL,
-#define NODE_UNTIL NODE_UNTIL
NODE_ITER,
-#define NODE_ITER NODE_ITER
NODE_FOR,
-#define NODE_FOR NODE_FOR
+ NODE_FOR_MASGN,
NODE_BREAK,
-#define NODE_BREAK NODE_BREAK
NODE_NEXT,
-#define NODE_NEXT NODE_NEXT
NODE_REDO,
-#define NODE_REDO NODE_REDO
NODE_RETRY,
-#define NODE_RETRY NODE_RETRY
NODE_BEGIN,
-#define NODE_BEGIN NODE_BEGIN
NODE_RESCUE,
-#define NODE_RESCUE NODE_RESCUE
NODE_RESBODY,
-#define NODE_RESBODY NODE_RESBODY
NODE_ENSURE,
-#define NODE_ENSURE NODE_ENSURE
NODE_AND,
-#define NODE_AND NODE_AND
NODE_OR,
-#define NODE_OR NODE_OR
NODE_MASGN,
-#define NODE_MASGN NODE_MASGN
NODE_LASGN,
-#define NODE_LASGN NODE_LASGN
NODE_DASGN,
-#define NODE_DASGN NODE_DASGN
NODE_DASGN_CURR,
-#define NODE_DASGN_CURR NODE_DASGN_CURR
NODE_GASGN,
-#define NODE_GASGN NODE_GASGN
NODE_IASGN,
-#define NODE_IASGN NODE_IASGN
- NODE_IASGN2,
-#define NODE_IASGN2 NODE_IASGN2
NODE_CDECL,
-#define NODE_CDECL NODE_CDECL
NODE_CVASGN,
-#define NODE_CVASGN NODE_CVASGN
- NODE_CVDECL,
-#define NODE_CVDECL NODE_CVDECL
NODE_OP_ASGN1,
-#define NODE_OP_ASGN1 NODE_OP_ASGN1
NODE_OP_ASGN2,
-#define NODE_OP_ASGN2 NODE_OP_ASGN2
NODE_OP_ASGN_AND,
-#define NODE_OP_ASGN_AND NODE_OP_ASGN_AND
NODE_OP_ASGN_OR,
-#define NODE_OP_ASGN_OR NODE_OP_ASGN_OR
NODE_OP_CDECL,
-#define NODE_OP_CDECL NODE_OP_CDECL
NODE_CALL,
-#define NODE_CALL NODE_CALL
NODE_OPCALL,
-#define NODE_OPCALL NODE_OPCALL
NODE_FCALL,
-#define NODE_FCALL NODE_FCALL
NODE_VCALL,
-#define NODE_VCALL NODE_VCALL
NODE_QCALL,
-#define NODE_QCALL NODE_QCALL
NODE_SUPER,
-#define NODE_SUPER NODE_SUPER
NODE_ZSUPER,
-#define NODE_ZSUPER NODE_ZSUPER
- NODE_ARRAY,
-#define NODE_ARRAY NODE_ARRAY
- NODE_ZARRAY,
-#define NODE_ZARRAY NODE_ZARRAY
+ NODE_LIST,
+ NODE_ZLIST,
NODE_VALUES,
-#define NODE_VALUES NODE_VALUES
NODE_HASH,
-#define NODE_HASH NODE_HASH
NODE_RETURN,
-#define NODE_RETURN NODE_RETURN
NODE_YIELD,
-#define NODE_YIELD NODE_YIELD
NODE_LVAR,
-#define NODE_LVAR NODE_LVAR
NODE_DVAR,
-#define NODE_DVAR NODE_DVAR
NODE_GVAR,
-#define NODE_GVAR NODE_GVAR
NODE_IVAR,
-#define NODE_IVAR NODE_IVAR
NODE_CONST,
-#define NODE_CONST NODE_CONST
NODE_CVAR,
-#define NODE_CVAR NODE_CVAR
NODE_NTH_REF,
-#define NODE_NTH_REF NODE_NTH_REF
NODE_BACK_REF,
-#define NODE_BACK_REF NODE_BACK_REF
NODE_MATCH,
-#define NODE_MATCH NODE_MATCH
NODE_MATCH2,
-#define NODE_MATCH2 NODE_MATCH2
NODE_MATCH3,
-#define NODE_MATCH3 NODE_MATCH3
NODE_LIT,
-#define NODE_LIT NODE_LIT
NODE_STR,
-#define NODE_STR NODE_STR
NODE_DSTR,
-#define NODE_DSTR NODE_DSTR
NODE_XSTR,
-#define NODE_XSTR NODE_XSTR
NODE_DXSTR,
-#define NODE_DXSTR NODE_DXSTR
NODE_EVSTR,
-#define NODE_EVSTR NODE_EVSTR
NODE_DREGX,
-#define NODE_DREGX NODE_DREGX
- NODE_DREGX_ONCE,
-#define NODE_DREGX_ONCE NODE_DREGX_ONCE
+ NODE_ONCE,
NODE_ARGS,
-#define NODE_ARGS NODE_ARGS
NODE_ARGS_AUX,
-#define NODE_ARGS_AUX NODE_ARGS_AUX
NODE_OPT_ARG,
-#define NODE_OPT_ARG NODE_OPT_ARG
NODE_KW_ARG,
-#define NODE_KW_ARG NODE_KW_ARG
NODE_POSTARG,
-#define NODE_POSTARG NODE_POSTARG
NODE_ARGSCAT,
-#define NODE_ARGSCAT NODE_ARGSCAT
NODE_ARGSPUSH,
-#define NODE_ARGSPUSH NODE_ARGSPUSH
NODE_SPLAT,
-#define NODE_SPLAT NODE_SPLAT
- NODE_TO_ARY,
-#define NODE_TO_ARY NODE_TO_ARY
- NODE_BLOCK_ARG,
-#define NODE_BLOCK_ARG NODE_BLOCK_ARG
NODE_BLOCK_PASS,
-#define NODE_BLOCK_PASS NODE_BLOCK_PASS
NODE_DEFN,
-#define NODE_DEFN NODE_DEFN
NODE_DEFS,
-#define NODE_DEFS NODE_DEFS
NODE_ALIAS,
-#define NODE_ALIAS NODE_ALIAS
NODE_VALIAS,
-#define NODE_VALIAS NODE_VALIAS
NODE_UNDEF,
-#define NODE_UNDEF NODE_UNDEF
NODE_CLASS,
-#define NODE_CLASS NODE_CLASS
NODE_MODULE,
-#define NODE_MODULE NODE_MODULE
NODE_SCLASS,
-#define NODE_SCLASS NODE_SCLASS
NODE_COLON2,
-#define NODE_COLON2 NODE_COLON2
NODE_COLON3,
-#define NODE_COLON3 NODE_COLON3
NODE_DOT2,
-#define NODE_DOT2 NODE_DOT2
NODE_DOT3,
-#define NODE_DOT3 NODE_DOT3
NODE_FLIP2,
-#define NODE_FLIP2 NODE_FLIP2
NODE_FLIP3,
-#define NODE_FLIP3 NODE_FLIP3
NODE_SELF,
-#define NODE_SELF NODE_SELF
NODE_NIL,
-#define NODE_NIL NODE_NIL
NODE_TRUE,
-#define NODE_TRUE NODE_TRUE
NODE_FALSE,
-#define NODE_FALSE NODE_FALSE
NODE_ERRINFO,
-#define NODE_ERRINFO NODE_ERRINFO
NODE_DEFINED,
-#define NODE_DEFINED NODE_DEFINED
NODE_POSTEXE,
-#define NODE_POSTEXE NODE_POSTEXE
- NODE_ALLOCA,
-#define NODE_ALLOCA NODE_ALLOCA
- NODE_BMETHOD,
-#define NODE_BMETHOD NODE_BMETHOD
NODE_DSYM,
-#define NODE_DSYM NODE_DSYM
NODE_ATTRASGN,
-#define NODE_ATTRASGN NODE_ATTRASGN
- NODE_PRELUDE,
-#define NODE_PRELUDE NODE_PRELUDE
NODE_LAMBDA,
-#define NODE_LAMBDA NODE_LAMBDA
+ NODE_ARYPTN,
+ NODE_HSHPTN,
+ NODE_FNDPTN,
NODE_LAST
-#define NODE_LAST NODE_LAST
};
+typedef struct rb_code_position_struct {
+ int lineno;
+ int column;
+} rb_code_position_t;
+
+typedef struct rb_code_location_struct {
+ rb_code_position_t beg_pos;
+ rb_code_position_t end_pos;
+} rb_code_location_t;
+
+static inline rb_code_location_t
+code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2)
+{
+ rb_code_location_t loc;
+ loc.beg_pos = loc1->beg_pos;
+ loc.end_pos = loc2->end_pos;
+ return loc;
+}
+
typedef struct RNode {
VALUE flags;
- VALUE nd_reserved; /* ex nd_file */
union {
struct RNode *node;
ID id;
VALUE value;
- VALUE (*cfunc)(ANYARGS);
ID *tbl;
} u1;
union {
@@ -256,17 +164,19 @@ typedef struct RNode {
struct RNode *node;
ID id;
long state;
- struct rb_global_entry *entry;
struct rb_args_info *args;
- long cnt;
+ struct rb_ary_pattern_info *apinfo;
+ struct rb_fnd_pattern_info *fpinfo;
VALUE value;
} u3;
+ rb_code_location_t nd_loc;
+ int node_id;
} NODE;
-#define RNODE(obj) (R_CAST(RNode)(obj))
+#define RNODE(obj) ((struct RNode *)(obj))
-/* FL : 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: FINALIZE, 8: TAINT, 9: UNTRUSTED, 10: EXIVAR, 11: FREEZE */
-/* NODE_FL: 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: NODE_FL_NEWLINE|NODE_FL_CREF_PUSHED_BY_EVAL,
+/* FL : 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: FINALIZE, 8: UNUSED, 9: UNUSED, 10: EXIVAR, 11: FREEZE */
+/* NODE_FL: 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: NODE_FL_NEWLINE,
* 8..14: nd_type,
* 15..: nd_line
*/
@@ -275,15 +185,33 @@ typedef struct RNode {
#define NODE_TYPESHIFT 8
#define NODE_TYPEMASK (((VALUE)0x7f)<<NODE_TYPESHIFT)
-#define nd_type(n) ((int) (((RNODE(n))->flags & NODE_TYPEMASK)>>NODE_TYPESHIFT))
+#define nd_type(n) ((int) (((n)->flags & NODE_TYPEMASK)>>NODE_TYPESHIFT))
#define nd_set_type(n,t) \
- RNODE(n)->flags=((RNODE(n)->flags&~NODE_TYPEMASK)|((((unsigned long)(t))<<NODE_TYPESHIFT)&NODE_TYPEMASK))
+ rb_node_set_type(n, t)
+#define nd_init_type(n,t) \
+ (n)->flags=(((n)->flags&~NODE_TYPEMASK)|((((unsigned long)(t))<<NODE_TYPESHIFT)&NODE_TYPEMASK))
#define NODE_LSHIFT (NODE_TYPESHIFT+7)
#define NODE_LMASK (((SIGNED_VALUE)1<<(sizeof(VALUE)*CHAR_BIT-NODE_LSHIFT))-1)
-#define nd_line(n) (int)(((SIGNED_VALUE)RNODE(n)->flags)>>NODE_LSHIFT)
+#define nd_line(n) (int)(((SIGNED_VALUE)(n)->flags)>>NODE_LSHIFT)
#define nd_set_line(n,l) \
- RNODE(n)->flags=((RNODE(n)->flags&~((VALUE)(-1)<<NODE_LSHIFT))|((VALUE)((l)&NODE_LMASK)<<NODE_LSHIFT))
+ (n)->flags=(((n)->flags&~((VALUE)(-1)<<NODE_LSHIFT))|((VALUE)((l)&NODE_LMASK)<<NODE_LSHIFT))
+
+#define nd_first_column(n) ((int)((n)->nd_loc.beg_pos.column))
+#define nd_set_first_column(n, v) ((n)->nd_loc.beg_pos.column = (v))
+#define nd_first_lineno(n) ((int)((n)->nd_loc.beg_pos.lineno))
+#define nd_set_first_lineno(n, v) ((n)->nd_loc.beg_pos.lineno = (v))
+#define nd_first_loc(n) ((n)->nd_loc.beg_pos)
+#define nd_set_first_loc(n, v) (nd_first_loc(n) = (v))
+
+#define nd_last_column(n) ((int)((n)->nd_loc.end_pos.column))
+#define nd_set_last_column(n, v) ((n)->nd_loc.end_pos.column = (v))
+#define nd_last_lineno(n) ((int)((n)->nd_loc.end_pos.lineno))
+#define nd_set_last_lineno(n, v) ((n)->nd_loc.end_pos.lineno = (v))
+#define nd_last_loc(n) ((n)->nd_loc.end_pos)
+#define nd_set_last_loc(n, v) (nd_last_loc(n) = (v))
+#define nd_node_id(n) ((n)->node_id)
+#define nd_set_node_id(n,id) ((n)->node_id = (id))
#define nd_head u1.node
#define nd_alen u2.argc
@@ -293,8 +221,6 @@ typedef struct RNode {
#define nd_body u2.node
#define nd_else u3.node
-#define nd_orig u3.value
-
#define nd_resq u2.node
#define nd_ensr u3.node
@@ -303,13 +229,12 @@ typedef struct RNode {
#define nd_stts u1.node
-#define nd_entry u3.entry
+#define nd_entry u3.id
#define nd_vid u1.id
#define nd_cflag u2.id
#define nd_cval u3.value
#define nd_oid u1.id
-#define nd_cnt u3.cnt
#define nd_tbl u1.tbl
#define nd_var u1.node
@@ -320,7 +245,6 @@ typedef struct RNode {
#define nd_lit u1.value
-#define nd_frml u2.argc
#define nd_rest u1.id
#define nd_opt u1.node
#define nd_pid u1.id
@@ -331,18 +255,11 @@ typedef struct RNode {
#define nd_args u3.node
#define nd_ainfo u3.args
-#define nd_noex u3.id
#define nd_defn u3.node
-#define nd_cfnc u1.cfunc
-#define nd_argc u2.argc
-
#define nd_cpath u1.node
#define nd_super u3.node
-#define nd_modl u1.id
-#define nd_clss_ u1.value
-
#define nd_beg u1.node
#define nd_end u2.node
#define nd_state u3.state
@@ -351,138 +268,168 @@ typedef struct RNode {
#define nd_nth u2.argc
#define nd_tag u1.id
-#define nd_tval u2.value
-
-#define nd_visi_ u2.argc
-
-#define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
-
-#define NEW_DEFN(i,a,d,p) NEW_NODE(NODE_DEFN,0,i,NEW_SCOPE(a,d))
-#define NEW_DEFS(r,i,a,d) NEW_NODE(NODE_DEFS,r,i,NEW_SCOPE(a,d))
-#define NEW_SCOPE(a,b) NEW_NODE(NODE_SCOPE,local_tbl(),b,a)
-#define NEW_BLOCK(a) NEW_NODE(NODE_BLOCK,a,0,0)
-#define NEW_IF(c,t,e) NEW_NODE(NODE_IF,c,t,e)
-#define NEW_UNLESS(c,t,e) NEW_NODE(NODE_UNLESS,c,t,e)
-#define NEW_CASE(h,b) NEW_NODE(NODE_CASE,h,b,0)
-#define NEW_WHEN(c,t,e) NEW_NODE(NODE_WHEN,c,t,e)
-#define NEW_OPT_N(b) NEW_NODE(NODE_OPT_N,0,b,0)
-#define NEW_WHILE(c,b,n) NEW_NODE(NODE_WHILE,c,b,n)
-#define NEW_UNTIL(c,b,n) NEW_NODE(NODE_UNTIL,c,b,n)
-#define NEW_FOR(v,i,b) NEW_NODE(NODE_FOR,v,b,i)
-#define NEW_ITER(a,b) NEW_NODE(NODE_ITER,0,NEW_SCOPE(a,b),0)
-#define NEW_LAMBDA(a,b) NEW_NODE(NODE_LAMBDA,0,NEW_SCOPE(a,b),0)
-#define NEW_BREAK(s) NEW_NODE(NODE_BREAK,s,0,0)
-#define NEW_NEXT(s) NEW_NODE(NODE_NEXT,s,0,0)
-#define NEW_REDO() NEW_NODE(NODE_REDO,0,0,0)
-#define NEW_RETRY() NEW_NODE(NODE_RETRY,0,0,0)
-#define NEW_BEGIN(b) NEW_NODE(NODE_BEGIN,0,b,0)
-#define NEW_RESCUE(b,res,e) NEW_NODE(NODE_RESCUE,b,res,e)
-#define NEW_RESBODY(a,ex,n) NEW_NODE(NODE_RESBODY,n,ex,a)
-#define NEW_ENSURE(b,en) NEW_NODE(NODE_ENSURE,b,0,en)
-#define NEW_RETURN(s) NEW_NODE(NODE_RETURN,s,0,0)
-#define NEW_YIELD(a) NEW_NODE(NODE_YIELD,a,0,0)
-#define NEW_LIST(a) NEW_ARRAY(a)
-#define NEW_ARRAY(a) NEW_NODE(NODE_ARRAY,a,1,0)
-#define NEW_ZARRAY() NEW_NODE(NODE_ZARRAY,0,0,0)
-#define NEW_HASH(a) NEW_NODE(NODE_HASH,a,0,0)
-#define NEW_MASGN(l,r) NEW_NODE(NODE_MASGN,l,0,r)
-#define NEW_GASGN(v,val) NEW_NODE(NODE_GASGN,v,val,rb_global_entry(v))
-#define NEW_LASGN(v,val) NEW_NODE(NODE_LASGN,v,val,0)
-#define NEW_DASGN(v,val) NEW_NODE(NODE_DASGN,v,val,0)
-#define NEW_DASGN_CURR(v,val) NEW_NODE(NODE_DASGN_CURR,v,val,0)
-#define NEW_IASGN(v,val) NEW_NODE(NODE_IASGN,v,val,0)
-#define NEW_IASGN2(v,val) NEW_NODE(NODE_IASGN2,v,val,0)
-#define NEW_CDECL(v,val,path) NEW_NODE(NODE_CDECL,v,val,path)
-#define NEW_CVASGN(v,val) NEW_NODE(NODE_CVASGN,v,val,0)
-#define NEW_CVDECL(v,val) NEW_NODE(NODE_CVDECL,v,val,0)
-#define NEW_OP_ASGN1(p,id,a) NEW_NODE(NODE_OP_ASGN1,p,id,a)
-#define NEW_OP_ASGN2(r,t,i,o,val) NEW_NODE(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o,t))
-#define NEW_OP_ASGN22(i,o,t) NEW_NODE(NODE_OP_ASGN2,i,o,t)
-#define NEW_OP_ASGN_OR(i,val) NEW_NODE(NODE_OP_ASGN_OR,i,val,0)
-#define NEW_OP_ASGN_AND(i,val) NEW_NODE(NODE_OP_ASGN_AND,i,val,0)
-#define NEW_OP_CDECL(v,op,val) NEW_NODE(NODE_OP_CDECL,v,val,op)
-#define NEW_GVAR(v) NEW_NODE(NODE_GVAR,v,0,rb_global_entry(v))
-#define NEW_LVAR(v) NEW_NODE(NODE_LVAR,v,0,0)
-#define NEW_DVAR(v) NEW_NODE(NODE_DVAR,v,0,0)
-#define NEW_IVAR(v) NEW_NODE(NODE_IVAR,v,0,0)
-#define NEW_CONST(v) NEW_NODE(NODE_CONST,v,0,0)
-#define NEW_CVAR(v) NEW_NODE(NODE_CVAR,v,0,0)
-#define NEW_NTH_REF(n) NEW_NODE(NODE_NTH_REF,0,n,0)
-#define NEW_BACK_REF(n) NEW_NODE(NODE_BACK_REF,0,n,0)
-#define NEW_MATCH(c) NEW_NODE(NODE_MATCH,c,0,0)
-#define NEW_MATCH2(n1,n2) NEW_NODE(NODE_MATCH2,n1,n2,0)
-#define NEW_MATCH3(r,n2) NEW_NODE(NODE_MATCH3,r,n2,0)
-#define NEW_LIT(l) NEW_NODE(NODE_LIT,l,0,0)
-#define NEW_STR(s) NEW_NODE(NODE_STR,s,0,0)
-#define NEW_DSTR(s) NEW_NODE(NODE_DSTR,s,1,0)
-#define NEW_XSTR(s) NEW_NODE(NODE_XSTR,s,0,0)
-#define NEW_DXSTR(s) NEW_NODE(NODE_DXSTR,s,0,0)
-#define NEW_DSYM(s) NEW_NODE(NODE_DSYM,s,0,0)
-#define NEW_EVSTR(n) NEW_NODE(NODE_EVSTR,0,(n),0)
-#define NEW_CALL(r,m,a) NEW_NODE(NODE_CALL,r,m,a)
-#define NEW_OPCALL(r,m,a) NEW_NODE(NODE_OPCALL,r,m,a)
-#define NEW_FCALL(m,a) NEW_NODE(NODE_FCALL,0,m,a)
-#define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)
-#define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)
-#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)
-#define NEW_ARGS_AUX(r,b) NEW_NODE(NODE_ARGS_AUX,r,b,0)
-#define NEW_OPT_ARG(i,v) NEW_NODE(NODE_OPT_ARG,i,v,0)
-#define NEW_KW_ARG(i,v) NEW_NODE(NODE_KW_ARG,i,v,0)
-#define NEW_POSTARG(i,v) NEW_NODE(NODE_POSTARG,i,v,0)
-#define NEW_ARGSCAT(a,b) NEW_NODE(NODE_ARGSCAT,a,b,0)
-#define NEW_ARGSPUSH(a,b) NEW_NODE(NODE_ARGSPUSH,a,b,0)
-#define NEW_SPLAT(a) NEW_NODE(NODE_SPLAT,a,0,0)
-#define NEW_TO_ARY(a) NEW_NODE(NODE_TO_ARY,a,0,0)
-#define NEW_BLOCK_ARG(v) NEW_NODE(NODE_BLOCK_ARG,v,0,local_cnt(v))
-#define NEW_BLOCK_PASS(b) NEW_NODE(NODE_BLOCK_PASS,0,b,0)
-#define NEW_ALIAS(n,o) NEW_NODE(NODE_ALIAS,n,o,0)
-#define NEW_VALIAS(n,o) NEW_NODE(NODE_VALIAS,n,o,0)
-#define NEW_UNDEF(i) NEW_NODE(NODE_UNDEF,0,i,0)
-#define NEW_CLASS(n,b,s) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(0,b),(s))
-#define NEW_SCLASS(r,b) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(0,b),0)
-#define NEW_MODULE(n,b) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b),0)
-#define NEW_COLON2(c,i) NEW_NODE(NODE_COLON2,c,i,0)
-#define NEW_COLON3(i) NEW_NODE(NODE_COLON3,0,i,0)
-#define NEW_DOT2(b,e) NEW_NODE(NODE_DOT2,b,e,0)
-#define NEW_DOT3(b,e) NEW_NODE(NODE_DOT3,b,e,0)
-#define NEW_SELF() NEW_NODE(NODE_SELF,0,0,0)
-#define NEW_NIL() NEW_NODE(NODE_NIL,0,0,0)
-#define NEW_TRUE() NEW_NODE(NODE_TRUE,0,0,0)
-#define NEW_FALSE() NEW_NODE(NODE_FALSE,0,0,0)
-#define NEW_ERRINFO() NEW_NODE(NODE_ERRINFO,0,0,0)
-#define NEW_DEFINED(e) NEW_NODE(NODE_DEFINED,e,0,0)
-#define NEW_PREEXE(b) NEW_SCOPE(b)
-#define NEW_POSTEXE(b) NEW_NODE(NODE_POSTEXE,0,b,0)
-#define NEW_BMETHOD(b) NEW_NODE(NODE_BMETHOD,0,0,b)
-#define NEW_ATTRASGN(r,m,a) NEW_NODE(NODE_ATTRASGN,r,m,a)
-#define NEW_PRELUDE(p,b,o) NEW_NODE(NODE_PRELUDE,p,b,o)
+
+#define nd_alias u1.id
+#define nd_orig u2.id
+#define nd_undef u2.node
+
+#define nd_brace u2.argc
+
+#define nd_pconst u1.node
+#define nd_pkwargs u2.node
+#define nd_pkwrestarg u3.node
+
+#define nd_apinfo u3.apinfo
+
+#define nd_fpinfo u3.fpinfo
+
+#define NEW_NODE(t,a0,a1,a2,loc) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2),loc)
+#define NEW_NODE_WITH_LOCALS(t,a1,a2,loc) node_newnode_with_locals(p, (t),(VALUE)(a1),(VALUE)(a2),loc)
+
+#define NEW_DEFN(i,a,d,loc) NEW_NODE(NODE_DEFN,0,i,NEW_SCOPE(a,d,loc),loc)
+#define NEW_DEFS(r,i,a,d,loc) NEW_NODE(NODE_DEFS,r,i,NEW_SCOPE(a,d,loc),loc)
+#define NEW_SCOPE(a,b,loc) NEW_NODE_WITH_LOCALS(NODE_SCOPE,b,a,loc)
+#define NEW_BLOCK(a,loc) NEW_NODE(NODE_BLOCK,a,0,0,loc)
+#define NEW_IF(c,t,e,loc) NEW_NODE(NODE_IF,c,t,e,loc)
+#define NEW_UNLESS(c,t,e,loc) NEW_NODE(NODE_UNLESS,c,t,e,loc)
+#define NEW_CASE(h,b,loc) NEW_NODE(NODE_CASE,h,b,0,loc)
+#define NEW_CASE2(b,loc) NEW_NODE(NODE_CASE2,0,b,0,loc)
+#define NEW_CASE3(h,b,loc) NEW_NODE(NODE_CASE3,h,b,0,loc)
+#define NEW_WHEN(c,t,e,loc) NEW_NODE(NODE_WHEN,c,t,e,loc)
+#define NEW_IN(c,t,e,loc) NEW_NODE(NODE_IN,c,t,e,loc)
+#define NEW_WHILE(c,b,n,loc) NEW_NODE(NODE_WHILE,c,b,n,loc)
+#define NEW_UNTIL(c,b,n,loc) NEW_NODE(NODE_UNTIL,c,b,n,loc)
+#define NEW_FOR(i,b,loc) NEW_NODE(NODE_FOR,0,b,i,loc)
+#define NEW_FOR_MASGN(v,loc) NEW_NODE(NODE_FOR_MASGN,v,0,0,loc)
+#define NEW_ITER(a,b,loc) NEW_NODE(NODE_ITER,0,NEW_SCOPE(a,b,loc),0,loc)
+#define NEW_LAMBDA(a,b,loc) NEW_NODE(NODE_LAMBDA,0,NEW_SCOPE(a,b,loc),0,loc)
+#define NEW_BREAK(s,loc) NEW_NODE(NODE_BREAK,s,0,0,loc)
+#define NEW_NEXT(s,loc) NEW_NODE(NODE_NEXT,s,0,0,loc)
+#define NEW_REDO(loc) NEW_NODE(NODE_REDO,0,0,0,loc)
+#define NEW_RETRY(loc) NEW_NODE(NODE_RETRY,0,0,0,loc)
+#define NEW_BEGIN(b,loc) NEW_NODE(NODE_BEGIN,0,b,0,loc)
+#define NEW_RESCUE(b,res,e,loc) NEW_NODE(NODE_RESCUE,b,res,e,loc)
+#define NEW_RESBODY(a,ex,n,loc) NEW_NODE(NODE_RESBODY,n,ex,a,loc)
+#define NEW_ENSURE(b,en,loc) NEW_NODE(NODE_ENSURE,b,0,en,loc)
+#define NEW_RETURN(s,loc) NEW_NODE(NODE_RETURN,s,0,0,loc)
+#define NEW_YIELD(a,loc) NEW_NODE(NODE_YIELD,a,0,0,loc)
+#define NEW_LIST(a,loc) NEW_NODE(NODE_LIST,a,1,0,loc)
+#define NEW_ZLIST(loc) NEW_NODE(NODE_ZLIST,0,0,0,loc)
+#define NEW_HASH(a,loc) NEW_NODE(NODE_HASH,a,0,0,loc)
+#define NEW_MASGN(l,r,loc) NEW_NODE(NODE_MASGN,l,0,r,loc)
+#define NEW_GASGN(v,val,loc) NEW_NODE(NODE_GASGN,v,val,v,loc)
+#define NEW_LASGN(v,val,loc) NEW_NODE(NODE_LASGN,v,val,0,loc)
+#define NEW_DASGN(v,val,loc) NEW_NODE(NODE_DASGN,v,val,0,loc)
+#define NEW_DASGN_CURR(v,val,loc) NEW_NODE(NODE_DASGN_CURR,v,val,0,loc)
+#define NEW_IASGN(v,val,loc) NEW_NODE(NODE_IASGN,v,val,0,loc)
+#define NEW_CDECL(v,val,path,loc) NEW_NODE(NODE_CDECL,v,val,path,loc)
+#define NEW_CVASGN(v,val,loc) NEW_NODE(NODE_CVASGN,v,val,0,loc)
+#define NEW_OP_ASGN1(p,id,a,loc) NEW_NODE(NODE_OP_ASGN1,p,id,a,loc)
+#define NEW_OP_ASGN2(r,t,i,o,val,loc) NEW_NODE(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o,t,loc),loc)
+#define NEW_OP_ASGN22(i,o,t,loc) NEW_NODE(NODE_OP_ASGN2,i,o,t,loc)
+#define NEW_OP_ASGN_OR(i,val,loc) NEW_NODE(NODE_OP_ASGN_OR,i,val,0,loc)
+#define NEW_OP_ASGN_AND(i,val,loc) NEW_NODE(NODE_OP_ASGN_AND,i,val,0,loc)
+#define NEW_OP_CDECL(v,op,val,loc) NEW_NODE(NODE_OP_CDECL,v,val,op,loc)
+#define NEW_GVAR(v,loc) NEW_NODE(NODE_GVAR,v,0,v,loc)
+#define NEW_LVAR(v,loc) NEW_NODE(NODE_LVAR,v,0,0,loc)
+#define NEW_DVAR(v,loc) NEW_NODE(NODE_DVAR,v,0,0,loc)
+#define NEW_IVAR(v,loc) NEW_NODE(NODE_IVAR,v,0,0,loc)
+#define NEW_CONST(v,loc) NEW_NODE(NODE_CONST,v,0,0,loc)
+#define NEW_CVAR(v,loc) NEW_NODE(NODE_CVAR,v,0,0,loc)
+#define NEW_NTH_REF(n,loc) NEW_NODE(NODE_NTH_REF,0,n,0,loc)
+#define NEW_BACK_REF(n,loc) NEW_NODE(NODE_BACK_REF,0,n,0,loc)
+#define NEW_MATCH(c,loc) NEW_NODE(NODE_MATCH,c,0,0,loc)
+#define NEW_MATCH2(n1,n2,loc) NEW_NODE(NODE_MATCH2,n1,n2,0,loc)
+#define NEW_MATCH3(r,n2,loc) NEW_NODE(NODE_MATCH3,r,n2,0,loc)
+#define NEW_LIT(l,loc) NEW_NODE(NODE_LIT,l,0,0,loc)
+#define NEW_STR(s,loc) NEW_NODE(NODE_STR,s,0,0,loc)
+#define NEW_DSTR(s,loc) NEW_NODE(NODE_DSTR,s,1,0,loc)
+#define NEW_XSTR(s,loc) NEW_NODE(NODE_XSTR,s,0,0,loc)
+#define NEW_DXSTR(s,loc) NEW_NODE(NODE_DXSTR,s,0,0,loc)
+#define NEW_DSYM(s,loc) NEW_NODE(NODE_DSYM,s,0,0,loc)
+#define NEW_EVSTR(n,loc) NEW_NODE(NODE_EVSTR,0,(n),0,loc)
+#define NEW_CALL(r,m,a,loc) NEW_NODE(NODE_CALL,r,m,a,loc)
+#define NEW_OPCALL(r,m,a,loc) NEW_NODE(NODE_OPCALL,r,m,a,loc)
+#define NEW_FCALL(m,a,loc) NEW_NODE(NODE_FCALL,0,m,a,loc)
+#define NEW_VCALL(m,loc) NEW_NODE(NODE_VCALL,0,m,0,loc)
+#define NEW_SUPER(a,loc) NEW_NODE(NODE_SUPER,0,0,a,loc)
+#define NEW_ZSUPER(loc) NEW_NODE(NODE_ZSUPER,0,0,0,loc)
+#define NEW_ARGS_AUX(r,b,loc) NEW_NODE(NODE_ARGS_AUX,r,b,0,loc)
+#define NEW_OPT_ARG(i,v,loc) NEW_NODE(NODE_OPT_ARG,i,v,0,loc)
+#define NEW_KW_ARG(i,v,loc) NEW_NODE(NODE_KW_ARG,i,v,0,loc)
+#define NEW_POSTARG(i,v,loc) NEW_NODE(NODE_POSTARG,i,v,0,loc)
+#define NEW_ARGSCAT(a,b,loc) NEW_NODE(NODE_ARGSCAT,a,b,0,loc)
+#define NEW_ARGSPUSH(a,b,loc) NEW_NODE(NODE_ARGSPUSH,a,b,0,loc)
+#define NEW_SPLAT(a,loc) NEW_NODE(NODE_SPLAT,a,0,0,loc)
+#define NEW_BLOCK_PASS(b,loc) NEW_NODE(NODE_BLOCK_PASS,0,b,0,loc)
+#define NEW_ALIAS(n,o,loc) NEW_NODE(NODE_ALIAS,n,o,0,loc)
+#define NEW_VALIAS(n,o,loc) NEW_NODE(NODE_VALIAS,n,o,0,loc)
+#define NEW_UNDEF(i,loc) NEW_NODE(NODE_UNDEF,0,i,0,loc)
+#define NEW_CLASS(n,b,s,loc) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(0,b,loc),(s),loc)
+#define NEW_SCLASS(r,b,loc) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(0,b,loc),0,loc)
+#define NEW_MODULE(n,b,loc) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b,loc),0,loc)
+#define NEW_COLON2(c,i,loc) NEW_NODE(NODE_COLON2,c,i,0,loc)
+#define NEW_COLON3(i,loc) NEW_NODE(NODE_COLON3,0,i,0,loc)
+#define NEW_DOT2(b,e,loc) NEW_NODE(NODE_DOT2,b,e,0,loc)
+#define NEW_DOT3(b,e,loc) NEW_NODE(NODE_DOT3,b,e,0,loc)
+#define NEW_SELF(loc) NEW_NODE(NODE_SELF,0,0,1,loc)
+#define NEW_NIL(loc) NEW_NODE(NODE_NIL,0,0,0,loc)
+#define NEW_TRUE(loc) NEW_NODE(NODE_TRUE,0,0,0,loc)
+#define NEW_FALSE(loc) NEW_NODE(NODE_FALSE,0,0,0,loc)
+#define NEW_ERRINFO(loc) NEW_NODE(NODE_ERRINFO,0,0,0,loc)
+#define NEW_DEFINED(e,loc) NEW_NODE(NODE_DEFINED,e,0,0,loc)
+#define NEW_PREEXE(b,loc) NEW_SCOPE(b,loc)
+#define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,loc)
+#define NEW_ATTRASGN(r,m,a,loc) NEW_NODE(NODE_ATTRASGN,r,m,a,loc)
+
+#define NODE_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
+#define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
+#define NODE_SPECIAL_NO_NAME_REST ((NODE *)-1)
+#define NODE_NAMED_REST_P(node) ((node) != NODE_SPECIAL_NO_NAME_REST)
+#define NODE_SPECIAL_EXCESSIVE_COMMA ((ID)1)
+#define NODE_SPECIAL_NO_REST_KEYWORD ((NODE *)-1)
+
+VALUE rb_node_case_when_optimizable_literal(const NODE *const node);
RUBY_SYMBOL_EXPORT_BEGIN
+typedef struct node_buffer_struct node_buffer_t;
+/* T_IMEMO/ast */
+typedef struct rb_ast_body_struct {
+ const NODE *root;
+ VALUE compile_option;
+ int line_count;
+} rb_ast_body_t;
+typedef struct rb_ast_struct {
+ VALUE flags;
+ node_buffer_t *node_buffer;
+ rb_ast_body_t body;
+} rb_ast_t;
+rb_ast_t *rb_ast_new(void);
+void rb_ast_mark(rb_ast_t*);
+void rb_ast_update_references(rb_ast_t*);
+void rb_ast_add_local_table(rb_ast_t*, ID *buf);
+void rb_ast_dispose(rb_ast_t*);
+void rb_ast_free(rb_ast_t*);
+size_t rb_ast_memsize(const rb_ast_t*);
+void rb_ast_add_mark_object(rb_ast_t*, VALUE);
+NODE *rb_ast_newnode(rb_ast_t*, enum node_type type);
+void rb_ast_delete_node(rb_ast_t*, NODE *n);
+
VALUE rb_parser_new(void);
VALUE rb_parser_end_seen_p(VALUE);
VALUE rb_parser_encoding(VALUE);
-VALUE rb_parser_get_yydebug(VALUE);
VALUE rb_parser_set_yydebug(VALUE, VALUE);
-VALUE rb_parser_dump_tree(NODE *node, int comment);
-NODE *rb_parser_append_print(VALUE, NODE *);
-NODE *rb_parser_while_loop(VALUE, NODE *, int, int);
-
-NODE *rb_parser_compile_cstr(VALUE, const char*, const char*, int, int);
-NODE *rb_parser_compile_string(VALUE, const char*, VALUE, int);
-NODE *rb_parser_compile_file(VALUE, const char*, VALUE, int);
-NODE *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
-NODE *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
-
-NODE *rb_compile_cstr(const char*, const char*, int, int);
-NODE *rb_compile_string(const char*, VALUE, int);
-NODE *rb_compile_file(const char*, VALUE, int);
-
-NODE *rb_node_newnode(enum node_type,VALUE,VALUE,VALUE);
-NODE *rb_node_newnode_longlife(enum node_type,VALUE,VALUE,VALUE);
-void rb_gc_free_node(VALUE obj);
-size_t rb_node_memsize(VALUE obj);
-VALUE rb_gc_mark_node(NODE *obj);
+VALUE rb_parser_dump_tree(const NODE *node, int comment);
+void rb_parser_set_options(VALUE, int, int, int, int);
+
+rb_ast_t *rb_parser_compile_string(VALUE, const char*, VALUE, int);
+rb_ast_t *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
+rb_ast_t *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
+rb_ast_t *rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int line);
+
+void rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2);
+const char *ruby_node_name(int node);
const struct kwtable *rb_reserved_word(const char *, unsigned int);
@@ -502,6 +449,22 @@ struct rb_args_info {
NODE *kw_rest_arg;
NODE *opt_args;
+ unsigned int no_kwarg: 1;
+ unsigned int ruby2_keywords: 1;
+
+ VALUE imemo;
+};
+
+struct rb_ary_pattern_info {
+ NODE *pre_args;
+ NODE *rest_arg;
+ NODE *post_args;
+};
+
+struct rb_fnd_pattern_info {
+ NODE *pre_rest_arg;
+ NODE *args;
+ NODE *post_rest_arg;
};
struct parser_params;
@@ -509,10 +472,20 @@ void *rb_parser_malloc(struct parser_params *, size_t);
void *rb_parser_realloc(struct parser_params *, void *, size_t);
void *rb_parser_calloc(struct parser_params *, size_t, size_t);
void rb_parser_free(struct parser_params *, void *);
-void rb_parser_printf(struct parser_params *parser, const char *fmt, ...);
+PRINTF_ARGS(void rb_parser_printf(struct parser_params *parser, const char *fmt, ...), 2, 3);
+void rb_ast_node_type_change(NODE *n, enum node_type type);
RUBY_SYMBOL_EXPORT_END
+static inline VALUE
+rb_node_set_type(NODE *n, enum node_type t)
+{
+#if RUBY_DEBUG
+ rb_ast_node_type_change(n, t);
+#endif
+ return nd_init_type(n, t);
+}
+
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
diff --git a/numeric.c b/numeric.c
index 1858113c09..691ab77042 100644
--- a/numeric.c
+++ b/numeric.c
@@ -9,9 +9,8 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/util.h"
-#include "id.h"
+#include "ruby/internal/config.h"
+
#include <assert.h>
#include <ctype.h>
#include <math.h>
@@ -25,13 +24,27 @@
#include <ieeefp.h>
#endif
+#include "id.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/compilers.h"
+#include "internal/complex.h"
+#include "internal/enumerator.h"
+#include "internal/gc.h"
+#include "internal/hash.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/rational.h"
+#include "internal/util.h"
+#include "internal/variable.h"
+#include "ruby/encoding.h"
+#include "ruby/util.h"
+#include "builtin.h"
+
/* use IEEE 64bit values if not defined */
#ifndef FLT_RADIX
#define FLT_RADIX 2
#endif
-#ifndef FLT_ROUNDS
-#define FLT_ROUNDS 1
-#endif
#ifndef DBL_MIN
#define DBL_MIN 2.2250738585072014e-308
#endif
@@ -60,14 +73,14 @@
#define DBL_EPSILON 2.2204460492503131e-16
#endif
-#ifdef HAVE_INFINITY
+#ifndef USE_RB_INFINITY
#elif !defined(WORDS_BIGENDIAN) /* BYTE_ORDER == LITTLE_ENDIAN */
const union bytesequence4_or_float rb_infinity = {{0x00, 0x00, 0x80, 0x7f}};
#else
const union bytesequence4_or_float rb_infinity = {{0x7f, 0x80, 0x00, 0x00}};
#endif
-#ifdef HAVE_NAN
+#ifndef USE_RB_NAN
#elif !defined(WORDS_BIGENDIAN) /* BYTE_ORDER == LITTLE_ENDIAN */
const union bytesequence4_or_float rb_nan = {{0x00, 0x00, 0xc0, 0x7f}};
#else
@@ -157,21 +170,18 @@ round_half_even(double x, double s)
return x;
}
-static VALUE fix_uminus(VALUE num);
-static VALUE fix_mul(VALUE x, VALUE y);
static VALUE fix_lshift(long, unsigned long);
static VALUE fix_rshift(long, unsigned long);
static VALUE int_pow(long x, unsigned long y);
-static VALUE int_odd_p(VALUE x);
-static VALUE int_even_p(VALUE x);
-static int int_round_zero_p(VALUE num, int ndigits);
-VALUE rb_int_floor(VALUE num, int ndigits);
-VALUE rb_int_ceil(VALUE num, int ndigits);
+static VALUE rb_int_floor(VALUE num, int ndigits);
+static VALUE rb_int_ceil(VALUE num, int ndigits);
static VALUE flo_to_i(VALUE num);
static int float_round_overflow(int ndigits, int binexp);
static int float_round_underflow(int ndigits, int binexp);
-static ID id_coerce, id_div, id_divmod;
+static ID id_coerce;
+#define id_div idDiv
+#define id_divmod idDivmod
#define id_to_i idTo_i
#define id_eq idEq
#define id_cmp idCmp
@@ -179,9 +189,6 @@ static ID id_coerce, id_div, id_divmod;
VALUE rb_cNumeric;
VALUE rb_cFloat;
VALUE rb_cInteger;
-#ifndef RUBY_INTEGER_UNIFICATION
-VALUE rb_cFixnum;
-#endif
VALUE rb_eZeroDivError;
VALUE rb_eFloatDomainError;
@@ -217,6 +224,7 @@ rb_num_get_rounding_option(VALUE opts)
str = rb_check_string_type(rounding);
if (NIL_P(str)) goto invalid;
}
+ rb_must_asciicompat(str);
s = RSTRING_PTR(str);
switch (RSTRING_LEN(str)) {
case 2:
@@ -271,17 +279,6 @@ rb_num_to_uint(VALUE val, unsigned int *ret)
#define method_basic_p(klass) rb_method_basic_definition_p(klass, mid)
-static VALUE
-compare_with_zero(VALUE num, ID mid)
-{
- VALUE zero = INT2FIX(0);
- VALUE r = rb_check_funcall(num, mid, 1, &zero);
- if (r == Qundef) {
- rb_cmperr(num, zero);
- }
- return r;
-}
-
static inline int
int_pos_p(VALUE num)
{
@@ -306,42 +303,22 @@ int_neg_p(VALUE num)
rb_raise(rb_eTypeError, "not an Integer");
}
-static inline int
-positive_int_p(VALUE num)
+int
+rb_int_positive_p(VALUE num)
{
- const ID mid = '>';
-
- if (FIXNUM_P(num)) {
- if (method_basic_p(rb_cInteger))
- return FIXNUM_POSITIVE_P(num);
- }
- else if (RB_TYPE_P(num, T_BIGNUM)) {
- if (method_basic_p(rb_cInteger))
- return BIGNUM_POSITIVE_P(num);
- }
- return RTEST(compare_with_zero(num, mid));
+ return int_pos_p(num);
}
-static inline int
-negative_int_p(VALUE num)
+int
+rb_int_negative_p(VALUE num)
{
- const ID mid = '<';
-
- if (FIXNUM_P(num)) {
- if (method_basic_p(rb_cInteger))
- return FIXNUM_NEGATIVE_P(num);
- }
- else if (RB_TYPE_P(num, T_BIGNUM)) {
- if (method_basic_p(rb_cInteger))
- return BIGNUM_NEGATIVE_P(num);
- }
- return RTEST(compare_with_zero(num, mid));
+ return int_neg_p(num);
}
int
rb_num_negative_p(VALUE num)
{
- return negative_int_p(num);
+ return rb_num_negative_int_p(num);
}
static VALUE
@@ -372,6 +349,8 @@ num_funcall0(VALUE x, ID func)
return rb_exec_recursive(num_funcall_op_0, x, (VALUE)func);
}
+NORETURN(static void num_funcall_op_1_recursion(VALUE x, ID func, VALUE y));
+
static void
num_funcall_op_1_recursion(VALUE x, ID func, VALUE y)
{
@@ -437,7 +416,7 @@ NORETURN(static void coerce_failed(VALUE x, VALUE y));
static void
coerce_failed(VALUE x, VALUE y)
{
- if (SPECIAL_CONST_P(y) || BUILTIN_TYPE(y) == T_FLOAT) {
+ if (SPECIAL_CONST_P(y) || SYMBOL_P(y) || RB_FLOAT_TYPE_P(y)) {
y = rb_inspect(y);
}
else {
@@ -484,19 +463,27 @@ rb_num_coerce_cmp(VALUE x, VALUE y, ID func)
return Qnil;
}
+static VALUE
+ensure_cmp(VALUE c, VALUE x, VALUE y)
+{
+ if (NIL_P(c)) rb_cmperr(x, y);
+ return c;
+}
+
VALUE
rb_num_coerce_relop(VALUE x, VALUE y, ID func)
{
- VALUE c, x0 = x, y0 = y;
+ VALUE x0 = x, y0 = y;
- if (!do_coerce(&x, &y, FALSE) ||
- NIL_P(c = rb_funcall(x, func, 1, y))) {
+ if (!do_coerce(&x, &y, FALSE)) {
rb_cmperr(x0, y0);
- return Qnil; /* not reached */
+ UNREACHABLE_RETURN(Qnil);
}
- return c;
+ return ensure_cmp(rb_funcall(x, func, 1, y), x0, y0);
}
+NORETURN(static VALUE num_sadded(VALUE x, VALUE name));
+
/*
* :nodoc:
*
@@ -516,7 +503,7 @@ num_sadded(VALUE x, VALUE name)
rb_id2str(mid),
rb_obj_class(x));
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
#if 0
@@ -665,10 +652,10 @@ num_remainder(VALUE x, VALUE y)
VALUE z = num_funcall1(x, '%', y);
if ((!rb_equal(z, INT2FIX(0))) &&
- ((negative_int_p(x) &&
- positive_int_p(y)) ||
- (positive_int_p(x) &&
- negative_int_p(y)))) {
+ ((rb_num_negative_int_p(x) &&
+ rb_num_positive_int_p(y)) ||
+ (rb_num_positive_int_p(x) &&
+ rb_num_negative_int_p(y)))) {
return rb_funcall(z, '-', 1, y);
}
return z;
@@ -769,7 +756,7 @@ num_int_p(VALUE num)
static VALUE
num_abs(VALUE num)
{
- if (negative_int_p(num)) {
+ if (rb_num_negative_int_p(num)) {
return num_funcall0(num, idUMinus);
}
return num;
@@ -785,23 +772,36 @@ num_abs(VALUE num)
static VALUE
num_zero_p(VALUE num)
{
+ if (rb_equal(num, INT2FIX(0))) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+static VALUE
+int_zero_p(VALUE num)
+{
if (FIXNUM_P(num)) {
if (FIXNUM_ZERO_P(num)) {
return Qtrue;
}
}
- else if (RB_TYPE_P(num, T_BIGNUM)) {
+ else {
+ assert(RB_TYPE_P(num, T_BIGNUM));
if (rb_bigzero_p(num)) {
/* this should not happen usually */
return Qtrue;
}
}
- else if (rb_equal(num, INT2FIX(0))) {
- return Qtrue;
- }
return Qfalse;
}
+VALUE
+rb_int_zero_p(VALUE num)
+{
+ return int_zero_p(num);
+}
+
/*
* call-seq:
* num.nonzero? -> self or nil
@@ -886,7 +886,7 @@ num_positive_p(VALUE num)
if (method_basic_p(rb_cInteger))
return BIGNUM_POSITIVE_P(num) && !rb_bigzero_p(num) ? Qtrue : Qfalse;
}
- return compare_with_zero(num, mid);
+ return rb_num_compare_with_zero(num, mid);
}
/*
@@ -899,7 +899,7 @@ num_positive_p(VALUE num)
static VALUE
num_negative_p(VALUE num)
{
- return negative_int_p(num) ? Qtrue : Qfalse;
+ return rb_num_negative_int_p(num) ? Qtrue : Qfalse;
}
@@ -913,9 +913,9 @@ num_negative_p(VALUE num)
* Floating point has a different arithmetic and is an inexact number.
* So you should know its esoteric system. See following:
*
- * - http://docs.sun.com/source/806-3568/ncg_goldberg.html
- * - http://wiki.github.com/rdp/ruby_tutorials_core/ruby-talk-faq#wiki-floats_imprecise
- * - http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
+ * - https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
+ * - https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#floats_imprecise
+ * - https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
*/
VALUE
@@ -924,7 +924,7 @@ rb_float_new_in_heap(double d)
NEWOBJ_OF(flt, struct RFloat, rb_cFloat, T_FLOAT | (RGENGC_WB_PROTECTED_FLOAT ? FL_WB_PROTECTED : 0));
flt->float_value = d;
- OBJ_FREEZE(flt);
+ OBJ_FREEZE((VALUE)flt);
return (VALUE)flt;
}
@@ -993,18 +993,21 @@ flo_to_s(VALUE flt)
memcpy(ptr -= decpt, buf, digs);
}
else {
- exp:
- if (digs > 1) {
- memmove(buf + 2, buf + 1, digs - 1);
- }
- else {
- buf[2] = '0';
- digs++;
- }
- buf[1] = '.';
- rb_str_cat(s, buf, digs + 1);
- rb_str_catf(s, "e%+03d", decpt - 1);
+ goto exp;
+ }
+ return s;
+
+ exp:
+ if (digs > 1) {
+ memmove(buf + 2, buf + 1, digs - 1);
+ }
+ else {
+ buf[2] = '0';
+ digs++;
}
+ buf[1] = '.';
+ rb_str_cat(s, buf, digs + 1);
+ rb_str_catf(s, "e%+03d", decpt - 1);
return s;
}
@@ -1047,8 +1050,8 @@ rb_float_uminus(VALUE flt)
* Returns a new Float which is the sum of +float+ and +other+.
*/
-static VALUE
-flo_plus(VALUE x, VALUE y)
+VALUE
+rb_float_plus(VALUE x, VALUE y)
{
if (RB_TYPE_P(y, T_FIXNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
@@ -1071,8 +1074,8 @@ flo_plus(VALUE x, VALUE y)
* Returns a new Float which is the difference of +float+ and +other+.
*/
-static VALUE
-flo_minus(VALUE x, VALUE y)
+VALUE
+rb_float_minus(VALUE x, VALUE y)
{
if (RB_TYPE_P(y, T_FIXNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
@@ -1095,8 +1098,8 @@ flo_minus(VALUE x, VALUE y)
* Returns a new Float which is the product of +float+ and +other+.
*/
-static VALUE
-flo_mul(VALUE x, VALUE y)
+VALUE
+rb_float_mul(VALUE x, VALUE y)
{
if (RB_TYPE_P(y, T_FIXNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
@@ -1112,6 +1115,36 @@ flo_mul(VALUE x, VALUE y)
}
}
+static bool
+flo_iszero(VALUE f)
+{
+ return FLOAT_ZERO_P(f);
+}
+
+static double
+double_div_double(double x, double y)
+{
+ if (LIKELY(y != 0.0)) {
+ return x / y;
+ }
+ else if (x == 0.0) {
+ return nan("");
+ }
+ else {
+ double z = signbit(y) ? -1.0 : 1.0;
+ return x * z * HUGE_VAL;
+ }
+}
+
+MJIT_FUNC_EXPORTED VALUE
+rb_flo_div_flo(VALUE x, VALUE y)
+{
+ double num = RFLOAT_VALUE(x);
+ double den = RFLOAT_VALUE(y);
+ double ret = double_div_double(num, den);
+ return DBL2NUM(ret);
+}
+
/*
* call-seq:
* float / other -> float
@@ -1119,26 +1152,28 @@ flo_mul(VALUE x, VALUE y)
* Returns a new Float which is the result of dividing +float+ by +other+.
*/
-static VALUE
-flo_div(VALUE x, VALUE y)
+VALUE
+rb_float_div(VALUE x, VALUE y)
{
- long f_y;
- double d;
+ double num = RFLOAT_VALUE(x);
+ double den;
+ double ret;
if (RB_TYPE_P(y, T_FIXNUM)) {
- f_y = FIX2LONG(y);
- return DBL2NUM(RFLOAT_VALUE(x) / (double)f_y);
+ den = FIX2LONG(y);
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
- d = rb_big2dbl(y);
- return DBL2NUM(RFLOAT_VALUE(x) / d);
+ den = rb_big2dbl(y);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
- return DBL2NUM(RFLOAT_VALUE(x) / RFLOAT_VALUE(y));
+ den = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_bin(x, y, '/');
}
+
+ ret = double_div_double(num, den);
+ return DBL2NUM(ret);
}
/*
@@ -1198,7 +1233,7 @@ flodivmod(double x, double y, double *divp, double *modp)
* An error will be raised if y == 0.
*/
-double
+MJIT_FUNC_EXPORTED double
ruby_float_mod(double x, double y)
{
double mod;
@@ -1293,7 +1328,11 @@ VALUE
rb_float_pow(VALUE x, VALUE y)
{
double dx, dy;
- if (RB_TYPE_P(y, T_FIXNUM)) {
+ if (y == INT2FIX(2)) {
+ dx = RFLOAT_VALUE(x);
+ return DBL2NUM(dx * dx);
+ }
+ else if (RB_TYPE_P(y, T_FIXNUM)) {
dx = RFLOAT_VALUE(x);
dy = (double)FIX2LONG(y);
}
@@ -1305,7 +1344,7 @@ rb_float_pow(VALUE x, VALUE y)
dx = RFLOAT_VALUE(x);
dy = RFLOAT_VALUE(y);
if (dx < 0 && dy != round(dy))
- return num_funcall1(rb_complex_raw1(x), idPow, y);
+ return rb_dbl_complex_new_polar_pi(pow(-dx, dy), dy);
}
else {
return rb_num_coerce_bin(x, y, idPow);
@@ -1374,7 +1413,7 @@ num_equal(VALUE x, VALUE y)
* so an implementation-dependent value is returned.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_float_equal(VALUE x, VALUE y)
{
volatile double a, b;
@@ -1384,7 +1423,7 @@ rb_float_equal(VALUE x, VALUE y)
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(b)) return Qfalse;
#endif
}
@@ -1392,13 +1431,14 @@ rb_float_equal(VALUE x, VALUE y)
return num_equal(x, y);
}
a = RFLOAT_VALUE(x);
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(a)) return Qfalse;
#endif
return (a == b)?Qtrue:Qfalse;
}
#define flo_eq rb_float_equal
+static VALUE rb_dbl_hash(double d);
/*
* call-seq:
@@ -1415,10 +1455,10 @@ flo_hash(VALUE num)
return rb_dbl_hash(RFLOAT_VALUE(num));
}
-VALUE
+static VALUE
rb_dbl_hash(double d)
{
- return LONG2FIX(rb_dbl_long_hash(d));
+ return ST2FIX(rb_dbl_long_hash(d));
}
VALUE
@@ -1456,7 +1496,7 @@ flo_cmp(VALUE x, VALUE y)
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
- return INT2FIX(-FIX2INT(rel));
+ return LONG2FIX(-FIX2LONG(rel));
return rel;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
@@ -1477,10 +1517,10 @@ flo_cmp(VALUE x, VALUE y)
return rb_dbl_cmp(a, b);
}
-int
+MJIT_FUNC_EXPORTED int
rb_float_cmp(VALUE x, VALUE y)
{
- return NUM2INT(flo_cmp(x, y));
+ return NUM2INT(ensure_cmp(flo_cmp(x, y), x, y));
}
/*
@@ -1502,19 +1542,19 @@ rb_float_gt(VALUE x, VALUE y)
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
- return -FIX2INT(rel) > 0 ? Qtrue : Qfalse;
+ return -FIX2LONG(rel) > 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(b)) return Qfalse;
#endif
}
else {
return rb_num_coerce_relop(x, y, '>');
}
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(a)) return Qfalse;
#endif
return (a > b)?Qtrue:Qfalse;
@@ -1539,19 +1579,19 @@ flo_ge(VALUE x, VALUE y)
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
- return -FIX2INT(rel) >= 0 ? Qtrue : Qfalse;
+ return -FIX2LONG(rel) >= 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(b)) return Qfalse;
#endif
}
else {
return rb_num_coerce_relop(x, y, idGE);
}
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(a)) return Qfalse;
#endif
return (a >= b)?Qtrue:Qfalse;
@@ -1576,19 +1616,19 @@ flo_lt(VALUE x, VALUE y)
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
- return -FIX2INT(rel) < 0 ? Qtrue : Qfalse;
+ return -FIX2LONG(rel) < 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(b)) return Qfalse;
#endif
}
else {
return rb_num_coerce_relop(x, y, '<');
}
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(a)) return Qfalse;
#endif
return (a < b)?Qtrue:Qfalse;
@@ -1613,19 +1653,19 @@ flo_le(VALUE x, VALUE y)
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
- return -FIX2INT(rel) <= 0 ? Qtrue : Qfalse;
+ return -FIX2LONG(rel) <= 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(b)) return Qfalse;
#endif
}
else {
return rb_num_coerce_relop(x, y, idLE);
}
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(a)) return Qfalse;
#endif
return (a <= b)?Qtrue:Qfalse;
@@ -1644,13 +1684,13 @@ flo_le(VALUE x, VALUE y)
* so an implementation-dependent value is returned.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_float_eql(VALUE x, VALUE y)
{
if (RB_TYPE_P(y, T_FLOAT)) {
double a = RFLOAT_VALUE(x);
double b = RFLOAT_VALUE(y);
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if MSC_VERSION_BEFORE(1300)
if (isnan(a) || isnan(b)) return Qfalse;
#endif
if (a == b)
@@ -1705,10 +1745,7 @@ rb_float_abs(VALUE flt)
static VALUE
flo_zero_p(VALUE num)
{
- if (RFLOAT_VALUE(num) == 0.0) {
- return Qtrue;
- }
- return Qfalse;
+ return flo_iszero(num) ? Qtrue : Qfalse;
}
/*
@@ -1779,6 +1816,15 @@ rb_flo_is_finite_p(VALUE num)
return Qtrue;
}
+static VALUE
+flo_nextafter(VALUE flo, double value)
+{
+ double x, y;
+ x = NUM2DBL(flo);
+ y = nextafter(x, value);
+ return DBL2NUM(y);
+}
+
/*
* call-seq:
* float.next_float -> float
@@ -1834,10 +1880,7 @@ rb_flo_is_finite_p(VALUE num)
static VALUE
flo_next_float(VALUE vx)
{
- double x, y;
- x = NUM2DBL(vx);
- y = nextafter(x, INFINITY);
- return DBL2NUM(y);
+ return flo_nextafter(vx, HUGE_VAL);
}
/*
@@ -1885,10 +1928,32 @@ flo_next_float(VALUE vx)
static VALUE
flo_prev_float(VALUE vx)
{
- double x, y;
- x = NUM2DBL(vx);
- y = nextafter(x, -INFINITY);
- return DBL2NUM(y);
+ return flo_nextafter(vx, -HUGE_VAL);
+}
+
+VALUE
+rb_float_floor(VALUE num, int ndigits)
+{
+ double number, f;
+ number = RFLOAT_VALUE(num);
+ if (number == 0.0) {
+ return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
+ }
+ if (ndigits > 0) {
+ int binexp;
+ frexp(number, &binexp);
+ if (float_round_overflow(ndigits, binexp)) return num;
+ if (number > 0.0 && float_round_underflow(ndigits, binexp))
+ return DBL2NUM(0.0);
+ f = pow(10, ndigits);
+ f = floor(number * f) / f;
+ return DBL2NUM(f);
+ }
+ else {
+ num = dbl2ival(floor(number));
+ if (ndigits < 0) num = rb_int_floor(num, ndigits);
+ return num;
+ }
}
/*
@@ -1933,31 +1998,11 @@ flo_prev_float(VALUE vx)
static VALUE
flo_floor(int argc, VALUE *argv, VALUE num)
{
- double number, f;
int ndigits = 0;
-
if (rb_check_arity(argc, 0, 1)) {
ndigits = NUM2INT(argv[0]);
}
- number = RFLOAT_VALUE(num);
- if (number == 0.0) {
- return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
- }
- if (ndigits > 0) {
- int binexp;
- frexp(number, &binexp);
- if (float_round_overflow(ndigits, binexp)) return num;
- if (number > 0.0 && float_round_underflow(ndigits, binexp))
- return DBL2NUM(0.0);
- f = pow(10, ndigits);
- f = floor(number * f) / f;
- return DBL2NUM(f);
- }
- else {
- num = dbl2ival(floor(number));
- if (ndigits < 0) num = rb_int_floor(num, ndigits);
- return num;
- }
+ return rb_float_floor(num, ndigits);
}
/*
@@ -2002,12 +2047,19 @@ flo_floor(int argc, VALUE *argv, VALUE num)
static VALUE
flo_ceil(int argc, VALUE *argv, VALUE num)
{
- double number, f;
int ndigits = 0;
if (rb_check_arity(argc, 0, 1)) {
ndigits = NUM2INT(argv[0]);
}
+ return rb_float_ceil(num, ndigits);
+}
+
+VALUE
+rb_float_ceil(VALUE num, int ndigits)
+{
+ double number, f;
+
number = RFLOAT_VALUE(num);
if (number == 0.0) {
return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
@@ -2072,7 +2124,7 @@ int_round_half_down(SIGNED_VALUE x, SIGNED_VALUE y)
static int
int_half_p_half_even(VALUE num, VALUE n, VALUE f)
{
- return (int)int_odd_p(rb_int_idiv(n, f));
+ return (int)rb_int_odd_p(rb_int_idiv(n, f));
}
static int
@@ -2090,7 +2142,7 @@ int_half_p_half_down(VALUE num, VALUE n, VALUE f)
/*
* Assumes num is an Integer, ndigits <= 0
*/
-VALUE
+static VALUE
rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode)
{
VALUE n, f, h, r;
@@ -2123,7 +2175,7 @@ rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode)
return n;
}
-VALUE
+static VALUE
rb_int_floor(VALUE num, int ndigits)
{
VALUE f;
@@ -2146,7 +2198,7 @@ rb_int_floor(VALUE num, int ndigits)
return rb_int_minus(num, rb_int_modulo(num, f));
}
-VALUE
+static VALUE
rb_int_ceil(VALUE num, int ndigits)
{
VALUE f;
@@ -2481,19 +2533,20 @@ num_truncate(int argc, VALUE *argv, VALUE num)
return flo_truncate(argc, argv, rb_Float(num));
}
-static double
+double
ruby_float_step_size(double beg, double end, double unit, int excl)
{
const double epsilon = DBL_EPSILON;
- double n = (end - beg)/unit;
- double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
+ double n, err;
+ if (unit == 0) {
+ return HUGE_VAL;
+ }
+ n= (end - beg)/unit;
+ err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
if (isinf(unit)) {
return unit > 0 ? beg <= end : beg >= end;
}
- if (unit == 0) {
- return INFINITY;
- }
if (err>0.5) err=0.5;
if (excl) {
if (n<=0) return 0;
@@ -2510,12 +2563,12 @@ ruby_float_step_size(double beg, double end, double unit, int excl)
}
int
-ruby_float_step(VALUE from, VALUE to, VALUE step, int excl)
+ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless)
{
if (RB_TYPE_P(from, T_FLOAT) || RB_TYPE_P(to, T_FLOAT) || RB_TYPE_P(step, T_FLOAT)) {
+ double unit = NUM2DBL(step);
double beg = NUM2DBL(from);
- double end = NUM2DBL(to);
- double unit = NUM2DBL(step);
+ double end = (allow_endless && NIL_P(to)) ? (unit < 0 ? -1 : 1)*HUGE_VAL : NUM2DBL(to);
double n = ruby_float_step_size(beg, end, unit, excl);
long i;
@@ -2548,7 +2601,7 @@ ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
diff = FIX2LONG(step);
if (diff == 0) {
- return DBL2NUM(INFINITY);
+ return DBL2NUM(HUGE_VAL);
}
delta = FIX2LONG(to) - FIX2LONG(from);
if (diff < 0) {
@@ -2567,14 +2620,14 @@ ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
double n = ruby_float_step_size(NUM2DBL(from), NUM2DBL(to), NUM2DBL(step), excl);
if (isinf(n)) return DBL2NUM(n);
- if (POSFIXABLE(n)) return LONG2FIX(n);
+ if (POSFIXABLE(n)) return LONG2FIX((long)n);
return rb_dbl2big(n);
}
else {
VALUE result;
ID cmp = '>';
switch (rb_cmpint(rb_num_coerce_cmp(step, INT2FIX(0), id_cmp), step, INT2FIX(0))) {
- case 0: return DBL2NUM(INFINITY);
+ case 0: return DBL2NUM(HUGE_VAL);
case -1: cmp = '<'; break;
}
if (RTEST(rb_funcall(from, cmp, 1, to))) return INT2FIX(0);
@@ -2610,10 +2663,9 @@ num_step_negative_p(VALUE num)
}
static int
-num_step_scan_args(int argc, const VALUE *argv, VALUE *to, VALUE *step)
+num_step_extract_args(int argc, const VALUE *argv, VALUE *to, VALUE *step, VALUE *by)
{
VALUE hash;
- int desc;
argc = rb_scan_args(argc, argv, "02:", to, step, &hash);
if (!NIL_P(hash)) {
@@ -2628,28 +2680,47 @@ num_step_scan_args(int argc, const VALUE *argv, VALUE *to, VALUE *step)
}
if (values[1] != Qundef) {
if (argc > 1) rb_raise(rb_eArgError, "step is given twice");
- *step = values[1];
+ *by = values[1];
}
}
+
+ return argc;
+}
+
+static int
+num_step_check_fix_args(int argc, VALUE *to, VALUE *step, VALUE by, int fix_nil, int allow_zero_step)
+{
+ int desc;
+ if (by != Qundef) {
+ *step = by;
+ }
else {
- /* compatibility */
- if (argc > 1 && NIL_P(*step)) {
- rb_raise(rb_eTypeError, "step must be numeric");
- }
- if (rb_equal(*step, INT2FIX(0))) {
- rb_raise(rb_eArgError, "step can't be 0");
- }
+ /* compatibility */
+ if (argc > 1 && NIL_P(*step)) {
+ rb_raise(rb_eTypeError, "step must be numeric");
+ }
+ }
+ if (!allow_zero_step && rb_equal(*step, INT2FIX(0))) {
+ rb_raise(rb_eArgError, "step can't be 0");
}
if (NIL_P(*step)) {
*step = INT2FIX(1);
}
desc = num_step_negative_p(*step);
- if (NIL_P(*to)) {
- *to = desc ? DBL2NUM(-INFINITY) : DBL2NUM(INFINITY);
+ if (fix_nil && NIL_P(*to)) {
+ *to = desc ? DBL2NUM(-HUGE_VAL) : DBL2NUM(HUGE_VAL);
}
return desc;
}
+static int
+num_step_scan_args(int argc, const VALUE *argv, VALUE *to, VALUE *step, int fix_nil, int allow_zero_step)
+{
+ VALUE by = Qundef;
+ argc = num_step_extract_args(argc, argv, to, step, &by);
+ return num_step_check_fix_args(argc, to, step, by, fix_nil, allow_zero_step);
+}
+
static VALUE
num_step_size(VALUE from, VALUE args, VALUE eobj)
{
@@ -2657,7 +2728,7 @@ num_step_size(VALUE from, VALUE args, VALUE eobj)
int argc = args ? RARRAY_LENINT(args) : 0;
const VALUE *argv = args ? RARRAY_CONST_PTR(args) : 0;
- num_step_scan_args(argc, argv, &to, &step);
+ num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
return ruby_num_interval_step_size(from, to, step, FALSE);
}
@@ -2665,9 +2736,11 @@ num_step_size(VALUE from, VALUE args, VALUE eobj)
/*
* call-seq:
* num.step(by: step, to: limit) {|i| block } -> self
- * num.step(by: step, to: limit) -> an_enumerator
+ * num.step(by: step, to: limit) -> an_enumerator
+ * num.step(by: step, to: limit) -> an_arithmetic_sequence
* num.step(limit=nil, step=1) {|i| block } -> self
* num.step(limit=nil, step=1) -> an_enumerator
+ * num.step(limit=nil, step=1) -> an_arithmetic_sequence
*
* Invokes the given block with the sequence of numbers starting at +num+,
* incremented by +step+ (defaulted to +1+) on each call.
@@ -2696,6 +2769,8 @@ num_step_size(VALUE from, VALUE args, VALUE eobj)
* and increments itself using the <code>+</code> operator.
*
* If no block is given, an Enumerator is returned instead.
+ * Especially, the enumerator is an Enumerator::ArithmeticSequence
+ * if both +limit+ and +step+ are kind of Numeric or <code>nil</code>.
*
* For example:
*
@@ -2720,9 +2795,29 @@ num_step(int argc, VALUE *argv, VALUE from)
VALUE to, step;
int desc, inf;
- RETURN_SIZED_ENUMERATOR(from, argc, argv, num_step_size);
+ if (!rb_block_given_p()) {
+ VALUE by = Qundef;
+
+ num_step_extract_args(argc, argv, &to, &step, &by);
+ if (by != Qundef) {
+ step = by;
+ }
+ if (NIL_P(step)) {
+ step = INT2FIX(1);
+ }
+ else if (rb_equal(step, INT2FIX(0))) {
+ rb_raise(rb_eArgError, "step can't be 0");
+ }
+ if ((NIL_P(to) || rb_obj_is_kind_of(to, rb_cNumeric)) &&
+ rb_obj_is_kind_of(step, rb_cNumeric)) {
+ return rb_arith_seq_new(from, ID2SYM(rb_frame_this_func()), argc, argv,
+ num_step_size, from, to, step, FALSE);
+ }
+
+ return SIZED_ENUMERATOR(from, 2, ((VALUE [2]){to, step}), num_step_size);
+ }
- desc = num_step_scan_args(argc, argv, &to, &step);
+ desc = num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
if (rb_equal(step, INT2FIX(0))) {
inf = 1;
}
@@ -2753,7 +2848,7 @@ num_step(int argc, VALUE *argv, VALUE from)
}
}
}
- else if (!ruby_float_step(from, to, step, FALSE)) {
+ else if (!ruby_float_step(from, to, step, FALSE, FALSE)) {
VALUE i = from;
if (inf) {
@@ -2870,7 +2965,6 @@ rb_num2ulong(VALUE val)
return rb_num2ulong_internal(val, NULL);
}
-#if SIZEOF_INT < SIZEOF_LONG
void
rb_out_of_int(SIGNED_VALUE num)
{
@@ -2878,6 +2972,7 @@ rb_out_of_int(SIGNED_VALUE num)
num, num < 0 ? "small" : "big");
}
+#if SIZEOF_INT < SIZEOF_LONG
static void
check_int(long num)
{
@@ -2939,7 +3034,7 @@ rb_fix2uint(VALUE val)
}
num = FIX2ULONG(val);
- check_uint(num, negative_int_p(val));
+ check_uint(num, rb_num_negative_int_p(val));
return num;
}
#else
@@ -2954,6 +3049,18 @@ rb_fix2int(VALUE val)
{
return FIX2INT(val);
}
+
+unsigned long
+rb_num2uint(VALUE val)
+{
+ return rb_num2ulong(val);
+}
+
+unsigned long
+rb_fix2uint(VALUE val)
+{
+ return RB_FIX2ULONG(val);
+}
#endif
NORETURN(static void rb_out_of_short(SIGNED_VALUE num));
@@ -3025,7 +3132,7 @@ rb_fix2ushort(VALUE val)
}
num = FIX2ULONG(val);
- check_ushort(num, negative_int_p(val));
+ check_ushort(num, rb_num_negative_int_p(val));
return num;
}
@@ -3132,81 +3239,82 @@ rb_num2ull(VALUE val)
*
*/
-/*
- * call-seq:
- * int.to_i -> integer
- * int.to_int -> integer
- *
- * Since +int+ is already an Integer, returns +self+.
- *
- * #to_int is an alias for #to_i.
- */
+VALUE
+rb_int_odd_p(VALUE num)
+{
+ if (FIXNUM_P(num)) {
+ if (num & 2) {
+ return Qtrue;
+ }
+ return Qfalse;
+ }
+ else {
+ assert(RB_TYPE_P(num, T_BIGNUM));
+ return rb_big_odd_p(num);
+ }
+}
static VALUE
-int_to_i(VALUE num)
+int_even_p(VALUE num)
{
- return num;
+ if (FIXNUM_P(num)) {
+ if ((num & 2) == 0) {
+ return Qtrue;
+ }
+ return Qfalse;
+ }
+ else {
+ assert(RB_TYPE_P(num, T_BIGNUM));
+ return rb_big_even_p(num);
+ }
+}
+
+VALUE
+rb_int_even_p(VALUE num)
+{
+ return int_even_p(num);
}
/*
* call-seq:
- * int.integer? -> true
+ * int.allbits?(mask) -> true or false
*
- * Since +int+ is already an Integer, this always returns +true+.
+ * Returns +true+ if all bits of <code>+int+ & +mask+</code> are 1.
*/
static VALUE
-int_int_p(VALUE num)
+int_allbits_p(VALUE num, VALUE mask)
{
- return Qtrue;
+ mask = rb_to_int(mask);
+ return rb_int_equal(rb_int_and(num, mask), mask);
}
/*
* call-seq:
- * int.odd? -> true or false
+ * int.anybits?(mask) -> true or false
*
- * Returns +true+ if +int+ is an odd number.
+ * Returns +true+ if any bits of <code>+int+ & +mask+</code> are 1.
*/
static VALUE
-int_odd_p(VALUE num)
+int_anybits_p(VALUE num, VALUE mask)
{
- if (FIXNUM_P(num)) {
- if (num & 2) {
- return Qtrue;
- }
- }
- else if (RB_TYPE_P(num, T_BIGNUM)) {
- return rb_big_odd_p(num);
- }
- else if (rb_funcall(num, '%', 1, INT2FIX(2)) != INT2FIX(0)) {
- return Qtrue;
- }
- return Qfalse;
+ mask = rb_to_int(mask);
+ return int_zero_p(rb_int_and(num, mask)) ? Qfalse : Qtrue;
}
/*
* call-seq:
- * int.even? -> true or false
+ * int.nobits?(mask) -> true or false
*
- * Returns +true+ if +int+ is an even number.
+ * Returns +true+ if no bits of <code>+int+ & +mask+</code> are 1.
*/
static VALUE
-int_even_p(VALUE num)
+int_nobits_p(VALUE num, VALUE mask)
{
- if (FIXNUM_P(num)) {
- if ((num & 2) == 0) {
- return Qtrue;
- }
- }
- else if (RB_TYPE_P(num, T_BIGNUM)) {
- return rb_big_even_p(num);
- }
- else if (rb_funcall(num, '%', 1, INT2FIX(2)) == INT2FIX(0)) {
- return Qtrue;
- }
- return Qfalse;
+ mask = rb_to_int(mask);
+ return int_zero_p(rb_int_and(num, mask));
}
/*
@@ -3251,7 +3359,7 @@ rb_int_succ(VALUE num)
* (-1).pred #=> -2
*/
-VALUE
+static VALUE
rb_int_pred(VALUE num)
{
if (FIXNUM_P(num)) {
@@ -3322,7 +3430,7 @@ int_chr(int argc, VALUE *argv, VALUE num)
if (0xff < i) {
enc = rb_default_internal_encoding();
if (!enc) {
- rb_raise(rb_eRangeError, "%d out of char range", i);
+ rb_raise(rb_eRangeError, "%u out of char range", i);
}
goto decode;
}
@@ -3336,8 +3444,7 @@ int_chr(int argc, VALUE *argv, VALUE num)
case 1:
break;
default:
- rb_check_arity(argc, 0, 1);
- break;
+ rb_error_arity(argc, 0, 1);
}
enc = rb_to_encoding(argv[0]);
if (!enc) enc = rb_ascii8bit_encoding();
@@ -3346,38 +3453,9 @@ int_chr(int argc, VALUE *argv, VALUE num)
}
/*
- * call-seq:
- * int.ord -> self
- *
- * Returns the +int+ itself.
- *
- * 97.ord #=> 97
- *
- * This method is intended for compatibility to character literals
- * in Ruby 1.9.
- *
- * For example, <code>?a.ord</code> returns 97 both in 1.8 and 1.9.
- */
-
-static VALUE
-int_ord(VALUE num)
-{
- return num;
-}
-
-/*
* Fixnum
*/
-
-/*
- * Document-method: Integer#-@
- * call-seq:
- * -int -> integer
- *
- * Returns +int+, negated.
- */
-
static VALUE
fix_uminus(VALUE num)
{
@@ -3390,10 +3468,10 @@ rb_int_uminus(VALUE num)
if (FIXNUM_P(num)) {
return fix_uminus(num);
}
- else if (RB_TYPE_P(num, T_BIGNUM)) {
+ else {
+ assert(RB_TYPE_P(num, T_BIGNUM));
return rb_big_uminus(num);
}
- return num_funcall0(num, idUMinus);
}
/*
@@ -3567,7 +3645,7 @@ rb_int_minus(VALUE x, VALUE y)
}
-#define SQRT_LONG_MAX ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
+#define SQRT_LONG_MAX HALF_LONG_MSB
/*tests if N*N would overflow*/
#define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
@@ -3620,16 +3698,16 @@ static double
fix_fdiv_double(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
- return (double)FIX2LONG(x) / (double)FIX2LONG(y);
+ return double_div_double(FIX2LONG(x), FIX2LONG(y));
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), y);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
- return (double)FIX2LONG(x) / RFLOAT_VALUE(y);
+ return double_div_double(FIX2LONG(x), RFLOAT_VALUE(y));
}
else {
- return NUM2DBL(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
+ return NUM2DBL(rb_num_coerce_bin(x, y, idFdiv));
}
}
@@ -3649,7 +3727,9 @@ rb_int_fdiv_double(VALUE x, VALUE y)
else if (RB_TYPE_P(x, T_BIGNUM)) {
return rb_big_fdiv_double(x, y);
}
- return NAN;
+ else {
+ return nan("");
+ }
}
/*
@@ -3694,19 +3774,16 @@ fix_divide(VALUE x, VALUE y, ID op)
return rb_big_div(x, y);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
- {
- double div;
-
if (op == '/') {
- div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
- return DBL2NUM(div);
+ double d = FIX2LONG(x);
+ return rb_flo_div_flo(DBL2NUM(d), y);
}
else {
+ VALUE v;
if (RFLOAT_VALUE(y) == 0) rb_num_zerodiv();
- div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
- return rb_dbl2big(floor(div));
+ v = fix_divide(x, y, '/');
+ return flo_floor(0, 0, v);
}
- }
}
else {
if (RB_TYPE_P(y, T_RATIONAL) &&
@@ -3821,7 +3898,7 @@ rb_int_modulo(VALUE x, VALUE y)
* See Numeric#divmod.
*/
-VALUE
+static VALUE
int_remainder(VALUE x, VALUE y)
{
if (FIXNUM_P(x)) {
@@ -3907,6 +3984,7 @@ int_pow(long x, unsigned long y)
long z = 1;
if (y == 0) return INT2FIX(1);
+ if (y == 1) return LONG2NUM(x);
if (neg) x = -x;
if (y & 1)
z = x;
@@ -3916,13 +3994,7 @@ int_pow(long x, unsigned long y)
do {
while (y % 2 == 0) {
if (!FIT_SQRT_LONG(x)) {
- VALUE v;
- bignum:
- v = rb_big_pow(rb_int2big(x), LONG2NUM(y));
- if (RB_FLOAT_TYPE_P(v)) /* infinity due to overflow */
- return v;
- if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
- return v;
+ goto bignum;
}
x = x * x;
y >>= 1;
@@ -3936,6 +4008,14 @@ int_pow(long x, unsigned long y)
} while (--y);
if (neg) z = -z;
return LONG2NUM(z);
+
+ VALUE v;
+ bignum:
+ v = rb_big_pow(rb_int2big(x), LONG2NUM(y));
+ if (RB_FLOAT_TYPE_P(v)) /* infinity due to overflow */
+ return v;
+ if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
+ return v;
}
VALUE
@@ -3945,6 +4025,26 @@ rb_int_positive_pow(long x, unsigned long y)
}
static VALUE
+fix_pow_inverted(VALUE x, VALUE minusb)
+{
+ if (x == INT2FIX(0)) {
+ rb_num_zerodiv();
+ UNREACHABLE_RETURN(Qundef);
+ }
+ else {
+ VALUE y = rb_int_pow(x, minusb);
+
+ if (RB_FLOAT_TYPE_P(y)) {
+ double d = pow((double)FIX2LONG(x), RFLOAT_VALUE(y));
+ return DBL2NUM(1.0 / d);
+ }
+ else {
+ return rb_rational_raw(INT2FIX(1), y);
+ }
+ }
+}
+
+static VALUE
fix_pow(VALUE x, VALUE y)
{
long a = FIX2LONG(x);
@@ -3953,31 +4053,17 @@ fix_pow(VALUE x, VALUE y)
long b = FIX2LONG(y);
if (a == 1) return INT2FIX(1);
- if (a == -1) {
- if (b % 2 == 0)
- return INT2FIX(1);
- else
- return INT2FIX(-1);
- }
- if (b < 0)
- return num_funcall1(rb_rational_raw1(x), idPow, y);
-
+ if (a == -1) return INT2FIX(b % 2 ? -1 : 1);
+ if (b < 0) return fix_pow_inverted(x, fix_uminus(y));
if (b == 0) return INT2FIX(1);
if (b == 1) return x;
- if (a == 0) {
- if (b > 0) return INT2FIX(0);
- return DBL2NUM(INFINITY);
- }
+ if (a == 0) return INT2FIX(0);
return int_pow(a, b);
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
if (a == 1) return INT2FIX(1);
- if (a == -1) {
- if (int_even_p(y)) return INT2FIX(1);
- else return INT2FIX(-1);
- }
- if (negative_int_p(y))
- return num_funcall1(rb_rational_raw1(x), idPow, y);
+ if (a == -1) return INT2FIX(int_even_p(y) ? 1 : -1);
+ if (BIGNUM_NEGATIVE_P(y)) return fix_pow_inverted(x, rb_big_uminus(y));
if (a == 0) return INT2FIX(0);
x = rb_int2big(FIX2LONG(x));
return rb_big_pow(x, y);
@@ -3986,14 +4072,12 @@ fix_pow(VALUE x, VALUE y)
double dy = RFLOAT_VALUE(y);
if (dy == 0.0) return DBL2NUM(1.0);
if (a == 0) {
- return DBL2NUM(dy < 0 ? INFINITY : 0.0);
+ return DBL2NUM(dy < 0 ? HUGE_VAL : 0.0);
}
if (a == 1) return DBL2NUM(1.0);
- {
- if (a < 0 && dy != round(dy))
- return num_funcall1(rb_complex_raw1(x), idPow, y);
- return DBL2NUM(pow((double)a, dy));
- }
+ if (a < 0 && dy != round(dy))
+ return rb_dbl_complex_new_polar_pi(pow(-(double)a, dy), dy);
+ return DBL2NUM(pow((double)a, dy));
}
else {
return rb_num_coerce_bin(x, y, idPow);
@@ -4012,6 +4096,24 @@ rb_int_pow(VALUE x, VALUE y)
return Qnil;
}
+VALUE
+rb_num_pow(VALUE x, VALUE y)
+{
+ VALUE z = rb_int_pow(x, y);
+ if (!NIL_P(z)) return z;
+ if (RB_FLOAT_TYPE_P(x)) return rb_float_pow(x, y);
+ if (SPECIAL_CONST_P(x)) return Qnil;
+ switch (BUILTIN_TYPE(x)) {
+ case T_COMPLEX:
+ return rb_complex_pow(x, y);
+ case T_RATIONAL:
+ return rb_rational_pow(x, y);
+ default:
+ break;
+ }
+ return Qnil;
+}
+
/*
* Document-method: Integer#==
* Document-method: Integer#===
@@ -4088,7 +4190,6 @@ fix_cmp(VALUE x, VALUE y)
else {
return rb_num_coerce_cmp(x, y, id_cmp);
}
- return rb_num_coerce_cmp(x, y, id_cmp);
}
VALUE
@@ -4261,29 +4362,14 @@ int_le(VALUE x, VALUE y)
return Qnil;
}
-/*
- * Document-method: Integer#~
- * call-seq:
- * ~int -> integer
- *
- * One's complement: returns a number where each bit is flipped.
- *
- * Inverts the bits in an Integer. As integers are conceptually of
- * infinite length, the result acts as if it had an infinite number of
- * one bits to the left. In hex representations, this is displayed
- * as two periods to the left of the digits.
- *
- * sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
- */
-
static VALUE
fix_comp(VALUE num)
{
return ~num | FIXNUM_FLAG;
}
-static VALUE
-int_comp(VALUE num)
+VALUE
+rb_int_comp(VALUE num)
{
if (FIXNUM_P(num)) {
return fix_comp(num);
@@ -4443,6 +4529,7 @@ rb_fix_lshift(VALUE x, VALUE y)
long val, width;
val = NUM2LONG(x);
+ if (!val) return (rb_to_int(y), INT2FIX(0));
if (!FIXNUM_P(y))
return rb_big_lshift(rb_int2big(val), y);
width = FIX2LONG(y);
@@ -4489,6 +4576,7 @@ rb_fix_rshift(VALUE x, VALUE y)
long i, val;
val = FIX2LONG(x);
+ if (!val) return (rb_to_int(y), INT2FIX(0));
if (!FIXNUM_P(y))
return rb_big_rshift(rb_int2big(val), y);
i = FIX2LONG(y);
@@ -4521,26 +4609,8 @@ rb_int_rshift(VALUE x, VALUE y)
return Qnil;
}
-/*
- * Document-method: Integer#[]
- * call-seq:
- * int[n] -> 0, 1
- *
- * Bit Reference---Returns the <code>n</code>th bit in the
- * binary representation of +int+, where <code>int[0]</code>
- * is the least significant bit.
- *
- * a = 0b11001100101010
- * 30.downto(0) {|n| print a[n] }
- * #=> 0000000000000000011001100101010
- *
- * a = 9**15
- * 50.downto(0) {|n| print a[n] }
- * #=> 000101110110100000111000011110010100111100010111001
- */
-
-static VALUE
-fix_aref(VALUE fix, VALUE idx)
+MJIT_FUNC_EXPORTED VALUE
+rb_fix_aref(VALUE fix, VALUE idx)
{
long val = FIX2LONG(fix);
long i;
@@ -4566,15 +4636,136 @@ fix_aref(VALUE fix, VALUE idx)
return INT2FIX(0);
}
+
+/* copied from "r_less" in range.c */
+/* compares _a_ and _b_ and returns:
+ * < 0: a < b
+ * = 0: a = b
+ * > 0: a > b or non-comparable
+ */
+static int
+compare_indexes(VALUE a, VALUE b)
+{
+ VALUE r = rb_funcall(a, id_cmp, 1, b);
+
+ if (NIL_P(r))
+ return INT_MAX;
+ return rb_cmpint(r, a, b);
+}
+
static VALUE
-int_aref(VALUE num, VALUE idx)
+generate_mask(VALUE len)
{
+ return rb_int_minus(rb_int_lshift(INT2FIX(1), len), INT2FIX(1));
+}
+
+static VALUE
+int_aref1(VALUE num, VALUE arg)
+{
+ VALUE orig_num = num, beg, end;
+ int excl;
+
+ if (rb_range_values(arg, &beg, &end, &excl)) {
+ if (NIL_P(beg)) {
+ /* beginless range */
+ if (!RTEST(num_negative_p(end))) {
+ if (!excl) end = rb_int_plus(end, INT2FIX(1));
+ VALUE mask = generate_mask(end);
+ if (RTEST(int_zero_p(rb_int_and(num, mask)))) {
+ return INT2FIX(0);
+ }
+ else {
+ rb_raise(rb_eArgError, "The beginless range for Integer#[] results in infinity");
+ }
+ }
+ else {
+ return INT2FIX(0);
+ }
+ }
+ num = rb_int_rshift(num, beg);
+
+ int cmp = compare_indexes(beg, end);
+ if (!NIL_P(end) && cmp < 0) {
+ VALUE len = rb_int_minus(end, beg);
+ if (!excl) len = rb_int_plus(len, INT2FIX(1));
+ VALUE mask = generate_mask(len);
+ num = rb_int_and(num, mask);
+ }
+ else if (cmp == 0) {
+ if (excl) return INT2FIX(0);
+ num = orig_num;
+ arg = beg;
+ goto one_bit;
+ }
+ return num;
+ }
+
+one_bit:
if (FIXNUM_P(num)) {
- return fix_aref(num, idx);
+ return rb_fix_aref(num, arg);
}
else if (RB_TYPE_P(num, T_BIGNUM)) {
- return rb_big_aref(num, idx);
+ return rb_big_aref(num, arg);
+ }
+ return Qnil;
+}
+
+static VALUE
+int_aref2(VALUE num, VALUE beg, VALUE len)
+{
+ num = rb_int_rshift(num, beg);
+ VALUE mask = generate_mask(len);
+ num = rb_int_and(num, mask);
+ return num;
+}
+
+/*
+ * Document-method: Integer#[]
+ * call-seq:
+ * int[n] -> 0, 1
+ * int[n, m] -> num
+ * int[range] -> num
+ *
+ * Bit Reference---Returns the <code>n</code>th bit in the
+ * binary representation of +int+, where <code>int[0]</code>
+ * is the least significant bit.
+ *
+ * a = 0b11001100101010
+ * 30.downto(0) {|n| print a[n] }
+ * #=> 0000000000000000011001100101010
+ *
+ * a = 9**15
+ * 50.downto(0) {|n| print a[n] }
+ * #=> 000101110110100000111000011110010100111100010111001
+ *
+ * In principle, <code>n[i]</code> is equivalent to <code>(n >> i) & 1</code>.
+ * Thus, any negative index always returns zero:
+ *
+ * p 255[-1] #=> 0
+ *
+ * Range operations <code>n[i, len]</code> and <code>n[i..j]</code>
+ * are naturally extended.
+ *
+ * * <code>n[i, len]</code> equals to <code>(n >> i) & ((1 << len) - 1)</code>.
+ * * <code>n[i..j]</code> equals to <code>(n >> i) & ((1 << (j - i + 1)) - 1)</code>.
+ * * <code>n[i...j]</code> equals to <code>(n >> i) & ((1 << (j - i)) - 1)</code>.
+ * * <code>n[i..]</code> equals to <code>(n >> i)</code>.
+ * * <code>n[..j]</code> is zero if <code>n & ((1 << (j + 1)) - 1)</code> is zero. Otherwise, raises an ArgumentError.
+ * * <code>n[...j]</code> is zero if <code>n & ((1 << j) - 1)</code> is zero. Otherwise, raises an ArgumentError.
+ *
+ * Note that range operation may exhaust memory.
+ * For example, <code>-1[0, 1000000000000]</code> will raise NoMemoryError.
+ */
+
+static VALUE
+int_aref(int const argc, VALUE * const argv, VALUE const num)
+{
+ rb_check_arity(argc, 1, 2);
+ if (argc == 2) {
+ return int_aref2(num, argv[0], argv[1]);
}
+ return int_aref1(num, argv[0]);
+
return Qnil;
}
@@ -4677,51 +4868,6 @@ int_size(VALUE num)
return Qnil;
}
-/*
- * Document-method: Integer#bit_length
- * call-seq:
- * int.bit_length -> integer
- *
- * Returns the number of bits of the value of +int+.
- *
- * "Number of bits" means the bit position of the highest bit
- * which is different from the sign bit
- * (where the least significant bit has bit position 1).
- * If there is no such bit (zero or minus one), zero is returned.
- *
- * I.e. this method returns <i>ceil(log2(int < 0 ? -int : int+1))</i>.
- *
- * (-2**1000-1).bit_length #=> 1001
- * (-2**1000).bit_length #=> 1000
- * (-2**1000+1).bit_length #=> 1000
- * (-2**12-1).bit_length #=> 13
- * (-2**12).bit_length #=> 12
- * (-2**12+1).bit_length #=> 12
- * -0x101.bit_length #=> 9
- * -0x100.bit_length #=> 8
- * -0xff.bit_length #=> 8
- * -2.bit_length #=> 1
- * -1.bit_length #=> 0
- * 0.bit_length #=> 0
- * 1.bit_length #=> 1
- * 0xff.bit_length #=> 8
- * 0x100.bit_length #=> 9
- * (2**12-1).bit_length #=> 12
- * (2**12).bit_length #=> 13
- * (2**12+1).bit_length #=> 13
- * (2**1000-1).bit_length #=> 1000
- * (2**1000).bit_length #=> 1001
- * (2**1000+1).bit_length #=> 1001
- *
- * This method can be used to detect overflow in Array#pack as follows:
- *
- * if n.bit_length < 32
- * [n].pack("l") # no overflow
- * else
- * raise "overflow"
- * end
- */
-
static VALUE
rb_fix_bit_length(VALUE fix)
{
@@ -4731,7 +4877,7 @@ rb_fix_bit_length(VALUE fix)
return LONG2FIX(bit_length(v));
}
-static VALUE
+VALUE
rb_int_bit_length(VALUE num)
{
if (FIXNUM_P(num)) {
@@ -4891,7 +5037,7 @@ int_upto(VALUE from, VALUE to)
rb_yield(i);
i = rb_funcall(i, '+', 1, INT2FIX(1));
}
- if (NIL_P(c)) rb_cmperr(i, to);
+ ensure_cmp(c, i, to);
}
return from;
}
@@ -5274,10 +5420,11 @@ rb_int_s_isqrt(VALUE self, VALUE num)
* 1.object_id == a.object_id #=> true
*
* There can only ever be one instance of the integer +1+, for example. Ruby ensures this
- * by preventing instantiation and duplication.
+ * by preventing instantiation. If duplication is attempted, the same instance is returned.
*
- * Integer.new(1) #=> NoMethodError: undefined method `new' for Integer:Class
- * 1.dup #=> TypeError: can't dup Integer
+ * Integer.new(1) #=> NoMethodError: undefined method `new' for Integer:Class
+ * 1.dup #=> 1
+ * 1.object_id == 1.dup.object_id #=> true
*
* For this reason, Numeric should be used when defining other numeric classes.
*
@@ -5335,16 +5482,13 @@ rb_int_s_isqrt(VALUE self, VALUE num)
void
Init_Numeric(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
#ifdef _UNICOSMP
/* Turn off floating point exceptions for divide by zero, etc. */
_set_Creg(0, 0);
#endif
- id_coerce = rb_intern("coerce");
- id_div = rb_intern("div");
- id_divmod = rb_intern("divmod");
+ id_coerce = rb_intern_const("coerce");
+ id_to = rb_intern_const("to");
+ id_by = rb_intern_const("by");
rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError);
@@ -5393,9 +5537,9 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "to_s", int_to_s, -1);
rb_define_alias(rb_cInteger, "inspect", "to_s");
- rb_define_method(rb_cInteger, "integer?", int_int_p, 0);
- rb_define_method(rb_cInteger, "odd?", int_odd_p, 0);
- rb_define_method(rb_cInteger, "even?", int_even_p, 0);
+ rb_define_method(rb_cInteger, "allbits?", int_allbits_p, 1);
+ rb_define_method(rb_cInteger, "anybits?", int_anybits_p, 1);
+ rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1);
rb_define_method(rb_cInteger, "upto", int_upto, 1);
rb_define_method(rb_cInteger, "downto", int_downto, 1);
rb_define_method(rb_cInteger, "times", int_dotimes, 0);
@@ -5403,9 +5547,6 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "next", int_succ, 0);
rb_define_method(rb_cInteger, "pred", int_pred, 0);
rb_define_method(rb_cInteger, "chr", int_chr, -1);
- rb_define_method(rb_cInteger, "ord", int_ord, 0);
- rb_define_method(rb_cInteger, "to_i", int_to_i, 0);
- rb_define_method(rb_cInteger, "to_int", int_to_i, 0);
rb_define_method(rb_cInteger, "to_f", int_to_f, 0);
rb_define_method(rb_cInteger, "floor", int_floor, -1);
rb_define_method(rb_cInteger, "ceil", int_ceil, -1);
@@ -5413,7 +5554,6 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "round", int_round, -1);
rb_define_method(rb_cInteger, "<=>", rb_int_cmp, 1);
- rb_define_method(rb_cInteger, "-@", rb_int_uminus, 0);
rb_define_method(rb_cInteger, "+", rb_int_plus, 1);
rb_define_method(rb_cInteger, "-", rb_int_minus, 1);
rb_define_method(rb_cInteger, "*", rb_int_mul, 1);
@@ -5426,8 +5566,7 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "fdiv", rb_int_fdiv, 1);
rb_define_method(rb_cInteger, "**", rb_int_pow, 1);
- rb_define_method(rb_cInteger, "abs", rb_int_abs, 0);
- rb_define_method(rb_cInteger, "magnitude", rb_int_abs, 0);
+ rb_define_method(rb_cInteger, "pow", rb_int_powm, -1); /* in bignum.c */
rb_define_method(rb_cInteger, "===", rb_int_equal, 1);
rb_define_method(rb_cInteger, "==", rb_int_equal, 1);
@@ -5436,22 +5575,18 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "<", int_lt, 1);
rb_define_method(rb_cInteger, "<=", int_le, 1);
- rb_define_method(rb_cInteger, "~", int_comp, 0);
rb_define_method(rb_cInteger, "&", rb_int_and, 1);
rb_define_method(rb_cInteger, "|", int_or, 1);
rb_define_method(rb_cInteger, "^", int_xor, 1);
- rb_define_method(rb_cInteger, "[]", int_aref, 1);
+ rb_define_method(rb_cInteger, "[]", int_aref, -1);
rb_define_method(rb_cInteger, "<<", rb_int_lshift, 1);
rb_define_method(rb_cInteger, ">>", rb_int_rshift, 1);
rb_define_method(rb_cInteger, "size", int_size, 0);
- rb_define_method(rb_cInteger, "bit_length", rb_int_bit_length, 0);
rb_define_method(rb_cInteger, "digits", rb_int_digits, -1);
-#ifndef RUBY_INTEGER_UNIFICATION
- rb_cFixnum = rb_cInteger;
-#endif
+ /* An obsolete class, use Integer */
rb_define_const(rb_cObject, "Fixnum", rb_cInteger);
rb_deprecate_constant(rb_cObject, "Fixnum");
@@ -5461,20 +5596,6 @@ Init_Numeric(void)
rb_undef_method(CLASS_OF(rb_cFloat), "new");
/*
- * Represents the rounding mode for floating point addition.
- *
- * Usually defaults to 1, rounding to the nearest number.
- *
- * Other modes include:
- *
- * -1:: Indeterminable
- * 0:: Rounding towards zero
- * 1:: Rounding to the nearest number
- * 2:: Rounding towards positive infinity
- * 3:: Rounding towards negative infinity
- */
- rb_define_const(rb_cFloat, "ROUNDS", INT2FIX(FLT_ROUNDS));
- /*
* The base of the floating point, or number of unique digits used to
* represent the number.
*
@@ -5549,20 +5670,20 @@ Init_Numeric(void)
/*
* An expression representing positive infinity.
*/
- rb_define_const(rb_cFloat, "INFINITY", DBL2NUM(INFINITY));
+ rb_define_const(rb_cFloat, "INFINITY", DBL2NUM(HUGE_VAL));
/*
* An expression representing a value which is "not a number".
*/
- rb_define_const(rb_cFloat, "NAN", DBL2NUM(NAN));
+ rb_define_const(rb_cFloat, "NAN", DBL2NUM(nan("")));
rb_define_method(rb_cFloat, "to_s", flo_to_s, 0);
rb_define_alias(rb_cFloat, "inspect", "to_s");
rb_define_method(rb_cFloat, "coerce", flo_coerce, 1);
rb_define_method(rb_cFloat, "-@", rb_float_uminus, 0);
- rb_define_method(rb_cFloat, "+", flo_plus, 1);
- rb_define_method(rb_cFloat, "-", flo_minus, 1);
- rb_define_method(rb_cFloat, "*", flo_mul, 1);
- rb_define_method(rb_cFloat, "/", flo_div, 1);
+ rb_define_method(rb_cFloat, "+", rb_float_plus, 1);
+ rb_define_method(rb_cFloat, "-", rb_float_minus, 1);
+ rb_define_method(rb_cFloat, "*", rb_float_mul, 1);
+ rb_define_method(rb_cFloat, "/", rb_float_div, 1);
rb_define_method(rb_cFloat, "quo", flo_quo, 1);
rb_define_method(rb_cFloat, "fdiv", flo_quo, 1);
rb_define_method(rb_cFloat, "%", flo_mod, 1);
@@ -5597,9 +5718,6 @@ Init_Numeric(void)
rb_define_method(rb_cFloat, "prev_float", flo_prev_float, 0);
rb_define_method(rb_cFloat, "positive?", flo_positive_p, 0);
rb_define_method(rb_cFloat, "negative?", flo_negative_p, 0);
-
- id_to = rb_intern("to");
- id_by = rb_intern("by");
}
#undef rb_float_value
@@ -5615,3 +5733,5 @@ rb_float_new(double d)
{
return rb_float_new_inline(d);
}
+
+#include "integer.rbinc"
diff --git a/object.c b/object.c
index 7f5e89f6bc..64cf88ae9f 100644
--- a/object.c
+++ b/object.c
@@ -11,17 +11,33 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/st.h"
-#include "ruby/util.h"
-#include <stdio.h>
-#include <errno.h>
+#include "ruby/internal/config.h"
+
#include <ctype.h>
-#include <math.h>
+#include <errno.h>
#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
#include "constant.h"
#include "id.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/class.h"
+#include "internal/error.h"
+#include "internal/eval.h"
+#include "internal/inits.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/struct.h"
+#include "internal/symbol.h"
+#include "internal/variable.h"
#include "probes.h"
+#include "ruby/encoding.h"
+#include "ruby/st.h"
+#include "ruby/util.h"
+#include "ruby/assert.h"
+#include "builtin.h"
/*!
* \defgroup object Core objects and their operations
@@ -33,12 +49,15 @@ VALUE rb_mKernel; /*!< Kernel module */
VALUE rb_cObject; /*!< Object class */
VALUE rb_cModule; /*!< Module class */
VALUE rb_cClass; /*!< Class class */
-VALUE rb_cData; /*!< Data class */
VALUE rb_cNilClass; /*!< NilClass class */
VALUE rb_cTrueClass; /*!< TrueClass class */
VALUE rb_cFalseClass; /*!< FalseClass class */
+static VALUE rb_cNilClass_to_s;
+static VALUE rb_cTrueClass_to_s;
+static VALUE rb_cFalseClass_to_s;
+
/*! \cond INTERNAL_MACRO */
#define id_eq idEq
@@ -49,6 +68,7 @@ VALUE rb_cFalseClass; /*!< FalseClass class */
#define id_init_clone idInitialize_clone
#define id_init_dup idInitialize_dup
#define id_const_missing idConst_missing
+#define id_to_f idTo_f
#define CLASS_OR_MODULE_P(obj) \
(!SPECIAL_CONST_P(obj) && \
@@ -117,11 +137,22 @@ rb_obj_setup(VALUE obj, VALUE klass, VALUE type)
* Case Equality -- For class Object, effectively the same as calling
* <code>#==</code>, but typically overridden by descendants to provide
* meaningful semantics in +case+ statements.
- *--
- * Same as \c Object#===, case equality.
- *++
*/
+#define case_equal rb_equal
+ /* The default implementation of #=== is
+ * to call #== with the rb_equal() optimization. */
+/*!
+ * This function is an optimized version of calling #==.
+ * It checks equality between two objects by first doing a fast
+ * identity check using using C's == (same as BasicObject#equal?).
+ * If that check fails, it calls #== dynamically.
+ * This optimization actually affects semantics,
+ * because when #== returns false for the same object obj,
+ * rb_equal(obj, obj) would still return true.
+ * This happens for Float::NAN, where Float::NAN == Float::NAN
+ * is false, but rb_equal(Float::NAN, Float::NAN) is true.
+ */
VALUE
rb_equal(VALUE obj1, VALUE obj2)
{
@@ -165,15 +196,15 @@ rb_eql(VALUE obj1, VALUE obj2)
* obj.equal?(other) -> true or false
* obj.eql?(other) -> true or false
*
- * Equality --- At the <code>Object</code> level, <code>==</code> returns
- * <code>true</code> only if +obj+ and +other+ are the same object.
- * Typically, this method is overridden in descendant classes to provide
+ * Equality --- At the Object level, #== returns <code>true</code>
+ * only if +obj+ and +other+ are the same object. Typically, this
+ * method is overridden in descendant classes to provide
* class-specific meaning.
*
- * Unlike <code>==</code>, the <code>equal?</code> method should never be
- * overridden by subclasses as it is used to determine object identity
- * (that is, <code>a.equal?(b)</code> if and only if <code>a</code> is the
- * same object as <code>b</code>):
+ * Unlike #==, the #equal? method should never be overridden by
+ * subclasses as it is used to determine object identity (that is,
+ * <code>a.equal?(b)</code> if and only if <code>a</code> is the same
+ * object as <code>b</code>):
*
* obj = "a"
* other = obj.dup
@@ -182,14 +213,17 @@ rb_eql(VALUE obj1, VALUE obj2)
* obj.equal? other #=> false
* obj.equal? obj #=> true
*
- * The <code>eql?</code> method returns <code>true</code> if +obj+ and
- * +other+ refer to the same hash key. This is used by Hash to test members
- * for equality. For objects of class <code>Object</code>, <code>eql?</code>
- * is synonymous with <code>==</code>. Subclasses normally continue this
- * tradition by aliasing <code>eql?</code> to their overridden <code>==</code>
- * method, but there are exceptions. <code>Numeric</code> types, for
- * example, perform type conversion across <code>==</code>, but not across
- * <code>eql?</code>, so:
+ * The #eql? method returns <code>true</code> if +obj+ and +other+
+ * refer to the same hash key. This is used by Hash to test members
+ * for equality. For any pair of objects where #eql? returns +true+,
+ * the #hash value of both objects must be equal. So any subclass
+ * that overrides #eql? should also override #hash appropriately.
+ *
+ * For objects of class Object, #eql? is synonymous
+ * with #==. Subclasses normally continue this tradition by aliasing
+ * #eql? to their overridden #== method, but there are exceptions.
+ * Numeric types, for example, perform type conversion across #==,
+ * but not across #eql?, so:
*
* 1 == 1.0 #=> true
* 1.eql? 1.0 #=> false
@@ -197,7 +231,7 @@ rb_eql(VALUE obj1, VALUE obj2)
* \private
*++
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
if (obj1 == obj2) return Qtrue;
@@ -216,7 +250,7 @@ VALUE rb_obj_hash(VALUE obj);
*++
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_obj_not(VALUE obj)
{
return RTEST(obj) ? Qfalse : Qtrue;
@@ -232,7 +266,7 @@ rb_obj_not(VALUE obj)
*++
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_obj_not_equal(VALUE obj1, VALUE obj2)
{
VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
@@ -245,7 +279,7 @@ rb_obj_not_equal(VALUE obj1, VALUE obj2)
* It returns the \a cl itself if it is neither a singleton class or a module.
*
* \param[in] cl a Class object.
- * \return the ancestor class found, or a falsey value if nothing found.
+ * \return the ancestor class found, or Qfalse if nothing found.
*/
VALUE
rb_class_real(VALUE cl)
@@ -257,22 +291,6 @@ rb_class_real(VALUE cl)
return cl;
}
-/**
- * call-seq:
- * obj.class -> class
- *
- * Returns the class of <i>obj</i>. This method must always be
- * called with an explicit receiver, as <code>class</code> is also a
- * reserved word in Ruby.
- *
- * 1.class #=> Integer
- * self.class #=> Object
- *--
- * Equivalent to \c Object\#class in Ruby.
- *
- * Returns the class of \c obj, skipping singleton classes or module inclusions.
- *++
- */
VALUE
rb_obj_class(VALUE obj)
{
@@ -303,15 +321,11 @@ rb_obj_singleton_class(VALUE obj)
}
/*! \private */
-void
+MJIT_FUNC_EXPORTED void
rb_obj_copy_ivar(VALUE dest, VALUE obj)
{
- if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
- xfree(ROBJECT_IVPTR(dest));
- ROBJECT(dest)->as.heap.ivptr = 0;
- ROBJECT(dest)->as.heap.numiv = 0;
- ROBJECT(dest)->as.heap.iv_index_tbl = 0;
- }
+ RUBY_ASSERT(RBASIC(dest)->flags & ROBJECT_EMBED);
+
if (RBASIC(obj)->flags & ROBJECT_EMBED) {
MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
RBASIC(dest)->flags |= ROBJECT_EMBED;
@@ -337,7 +351,7 @@ init_copy(VALUE dest, VALUE obj)
rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
}
RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
- RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT);
+ RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR);
rb_copy_wb_protected_attribute(dest, obj);
rb_copy_generic_ivar(dest, obj);
rb_gc_copy_finalizer(dest, obj);
@@ -346,9 +360,9 @@ init_copy(VALUE dest, VALUE obj)
}
}
-static int freeze_opt(int argc, VALUE *argv);
-static VALUE immutable_obj_clone(VALUE obj, int kwfreeze);
-static VALUE mutable_obj_clone(VALUE obj, int kwfreeze);
+static VALUE freeze_opt(int argc, VALUE *argv);
+static VALUE immutable_obj_clone(VALUE obj, VALUE kwfreeze);
+static VALUE mutable_obj_clone(VALUE obj, VALUE kwfreeze);
PUREFUNC(static inline int special_object_p(VALUE obj)); /*!< \private */
static inline int
special_object_p(VALUE obj)
@@ -367,35 +381,25 @@ special_object_p(VALUE obj)
}
}
-/*
- * call-seq:
- * obj.clone(freeze: true) -> an_object
- *
- * Produces a shallow copy of <i>obj</i>---the instance variables of
- * <i>obj</i> are copied, but not the objects they reference.
- * <code>clone</code> copies the frozen (unless :freeze keyword argument
- * is given with a false value) and tainted state of <i>obj</i>.
- * See also the discussion under <code>Object#dup</code>.
- *
- * class Klass
- * attr_accessor :str
- * end
- * s1 = Klass.new #=> #<Klass:0x401b3a38>
- * s1.str = "Hello" #=> "Hello"
- * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello">
- * s2.str[1,4] = "i" #=> "i"
- * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
- * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">"
- *
- * This method may have class-specific behavior. If so, that
- * behavior will be documented under the #+initialize_copy+ method of
- * the class.
- */
+static VALUE
+obj_freeze_opt(VALUE freeze)
+{
+ switch(freeze) {
+ case Qfalse:
+ case Qtrue:
+ case Qnil:
+ break;
+ default:
+ rb_raise(rb_eArgError, "unexpected value for freeze: %"PRIsVALUE, rb_obj_class(freeze));
+ }
+
+ return freeze;
+}
static VALUE
-rb_obj_clone2(int argc, VALUE *argv, VALUE obj)
+rb_obj_clone2(rb_execution_context_t *ec, VALUE obj, VALUE freeze)
{
- int kwfreeze = freeze_opt(argc, argv);
+ VALUE kwfreeze = obj_freeze_opt(freeze);
if (!special_object_p(obj))
return mutable_obj_clone(obj, kwfreeze);
return immutable_obj_clone(obj, kwfreeze);
@@ -405,16 +409,16 @@ rb_obj_clone2(int argc, VALUE *argv, VALUE obj)
VALUE
rb_immutable_obj_clone(int argc, VALUE *argv, VALUE obj)
{
- int kwfreeze = freeze_opt(argc, argv);
+ VALUE kwfreeze = freeze_opt(argc, argv);
return immutable_obj_clone(obj, kwfreeze);
}
-static int
+static VALUE
freeze_opt(int argc, VALUE *argv)
{
static ID keyword_ids[1];
VALUE opt;
- VALUE kwfreeze;
+ VALUE kwfreeze = Qnil;
if (!keyword_ids[0]) {
CONST_ID(keyword_ids[0], "freeze");
@@ -422,32 +426,28 @@ freeze_opt(int argc, VALUE *argv)
rb_scan_args(argc, argv, "0:", &opt);
if (!NIL_P(opt)) {
rb_get_kwargs(opt, keyword_ids, 0, 1, &kwfreeze);
- if (kwfreeze == Qfalse) return FALSE;
- if (kwfreeze != Qundef && kwfreeze != Qtrue) {
- rb_raise(rb_eArgError, "unexpected value for freeze: %"PRIsVALUE,
- rb_obj_class(kwfreeze));
- }
+ if (kwfreeze != Qundef)
+ kwfreeze = obj_freeze_opt(kwfreeze);
}
- return TRUE;
+ return kwfreeze;
}
static VALUE
-immutable_obj_clone(VALUE obj, int kwfreeze)
+immutable_obj_clone(VALUE obj, VALUE kwfreeze)
{
- if (!kwfreeze)
+ if (kwfreeze == Qfalse)
rb_raise(rb_eArgError, "can't unfreeze %"PRIsVALUE,
rb_obj_class(obj));
return obj;
}
static VALUE
-mutable_obj_clone(VALUE obj, int kwfreeze)
+mutable_obj_clone(VALUE obj, VALUE kwfreeze)
{
VALUE clone, singleton;
+ VALUE argv[2];
clone = rb_obj_alloc(rb_obj_class(obj));
- RBASIC(clone)->flags &= (FL_TAINT|FL_PROMOTED0|FL_PROMOTED1);
- RBASIC(clone)->flags |= RBASIC(obj)->flags & ~(FL_PROMOTED0|FL_PROMOTED1|FL_FREEZE|FL_FINALIZE);
singleton = rb_singleton_class_clone_and_attach(obj, clone);
RBASIC_SET_CLASS(clone, singleton);
@@ -456,10 +456,45 @@ mutable_obj_clone(VALUE obj, int kwfreeze)
}
init_copy(clone, obj);
- rb_funcall(clone, id_init_clone, 1, obj);
- if (kwfreeze) {
+ switch (kwfreeze) {
+ case Qnil:
+ rb_funcall(clone, id_init_clone, 1, obj);
RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
+ break;
+ case Qtrue:
+ {
+ static VALUE freeze_true_hash;
+ if (!freeze_true_hash) {
+ freeze_true_hash = rb_hash_new();
+ rb_gc_register_mark_object(freeze_true_hash);
+ rb_hash_aset(freeze_true_hash, ID2SYM(rb_intern("freeze")), Qtrue);
+ rb_obj_freeze(freeze_true_hash);
+ }
+
+ argv[0] = obj;
+ argv[1] = freeze_true_hash;
+ rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS);
+ RBASIC(clone)->flags |= FL_FREEZE;
+ break;
+ }
+ case Qfalse:
+ {
+ static VALUE freeze_false_hash;
+ if (!freeze_false_hash) {
+ freeze_false_hash = rb_hash_new();
+ rb_gc_register_mark_object(freeze_false_hash);
+ rb_hash_aset(freeze_false_hash, ID2SYM(rb_intern("freeze")), Qfalse);
+ rb_obj_freeze(freeze_false_hash);
+ }
+
+ argv[0] = obj;
+ argv[1] = freeze_false_hash;
+ rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS);
+ break;
+ }
+ default:
+ rb_bug("invalid kwfreeze passed to mutable_obj_clone");
}
return clone;
@@ -475,7 +510,7 @@ VALUE
rb_obj_clone(VALUE obj)
{
if (special_object_p(obj)) return obj;
- return mutable_obj_clone(obj, Qtrue);
+ return mutable_obj_clone(obj, Qnil);
}
/**
@@ -484,7 +519,6 @@ rb_obj_clone(VALUE obj)
*
* Produces a shallow copy of <i>obj</i>---the instance variables of
* <i>obj</i> are copied, but not the objects they reference.
- * <code>dup</code> copies the tainted state of <i>obj</i>.
*
* This method may have class-specific behavior. If so, that
* behavior will be documented under the #+initialize_copy+ method of
@@ -492,11 +526,10 @@ rb_obj_clone(VALUE obj)
*
* === on dup vs clone
*
- * In general, <code>clone</code> and <code>dup</code> may have different
- * semantics in descendant classes. While <code>clone</code> is used to
- * duplicate an object, including its internal state, <code>dup</code>
- * typically uses the class of the descendant object to create the new
- * instance.
+ * In general, #clone and #dup may have different semantics in
+ * descendant classes. While #clone is used to duplicate an object,
+ * including its internal state, #dup typically uses the class of the
+ * descendant object to create the new instance.
*
* When using #dup, any modules that the object has been extended with will not
* be copied.
@@ -513,11 +546,11 @@ rb_obj_clone(VALUE obj)
* s1.extend(Foo) #=> #<Klass:0x401b3a38>
* s1.foo #=> "foo"
*
- * s2 = s1.clone #=> #<Klass:0x401b3a38>
+ * s2 = s1.clone #=> #<Klass:0x401be280>
* s2.foo #=> "foo"
*
- * s3 = s1.dup #=> #<Klass:0x401b3a38>
- * s3.foo #=> NoMethodError: undefined method `foo' for #<Klass:0x401b3a38>
+ * s3 = s1.dup #=> #<Klass:0x401c1084>
+ * s3.foo #=> NoMethodError: undefined method `foo' for #<Klass:0x401c1084>
*--
* Equivalent to \c Object\#dup in Ruby
*++
@@ -554,28 +587,16 @@ rb_obj_itself(VALUE obj)
return obj;
}
-static VALUE
+VALUE
rb_obj_size(VALUE self, VALUE args, VALUE obj)
{
return LONG2FIX(1);
}
-/*
- * call-seq:
- * obj.yield_self {|x| block } -> an_object
- *
- * Yields self to the block and returns the result of the block.
- *
- * "my string".yield_self {|s| s.upcase } #=> "MY STRING"
- * 3.next.yield_self {|x| x**x }.to_s #=> "256"
- *
- */
-
static VALUE
-rb_obj_yield_self(VALUE obj)
+block_given_p(rb_execution_context_t *ec, VALUE self)
{
- RETURN_SIZED_ENUMERATOR(obj, 0, 0, rb_obj_size);
- return rb_yield_values2(1, &obj);
+ return rb_block_given_p() ? Qtrue : Qfalse;
}
/**
@@ -591,7 +612,6 @@ rb_obj_init_copy(VALUE obj, VALUE orig)
{
if (obj == orig) return obj;
rb_check_frozen(obj);
- rb_check_trusted(obj);
if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {
rb_raise(rb_eTypeError, "initialize_copy should take same class object");
}
@@ -601,10 +621,10 @@ rb_obj_init_copy(VALUE obj, VALUE orig)
/*!
* :nodoc:
*--
- * Default implementation of \c #initialize_dup and \c #initialize_clone
+ * Default implementation of \c #initialize_dup
*
* \param[in,out] obj the receiver being initialized
- * \param[in] orig the object to be dup or cloned from.
+ * \param[in] orig the object to be dup from.
*++
**/
VALUE
@@ -614,14 +634,35 @@ rb_obj_init_dup_clone(VALUE obj, VALUE orig)
return obj;
}
+/*!
+ * :nodoc:
+ *--
+ * Default implementation of \c #initialize_clone
+ *
+ * \param[in] The number of arguments
+ * \param[in] The array of arguments
+ * \param[in] obj the receiver being initialized
+ *++
+ **/
+static VALUE
+rb_obj_init_clone(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE orig, opts;
+ rb_scan_args(argc, argv, "1:", &orig, &opts);
+ /* Ignore a freeze keyword */
+ if (argc == 2) (void)freeze_opt(1, &opts);
+ rb_funcall(obj, id_init_copy, 1, orig);
+ return obj;
+}
+
/**
* call-seq:
* obj.to_s -> string
*
- * Returns a string representing <i>obj</i>. The default
- * <code>to_s</code> prints the object's class and an encoding of the
- * object id. As a special case, the top-level object that is the
- * initial execution context of Ruby programs returns ``main''.
+ * Returns a string representing <i>obj</i>. The default #to_s prints
+ * the object's class and an encoding of the object id. As a special
+ * case, the top-level object that is the initial execution context
+ * of Ruby programs returns ``main''.
*
*--
* Default implementation of \c #to_s.
@@ -634,7 +675,6 @@ rb_any_to_s(VALUE obj)
VALUE cname = rb_class_name(CLASS_OF(obj));
str = rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)obj);
- OBJ_INFECT(str, obj);
return str;
}
@@ -703,7 +743,6 @@ inspect_obj(VALUE obj, VALUE str, int recur)
}
rb_str_cat2(str, ">");
RSTRING_PTR(str)[0] = '#';
- OBJ_INFECT(str, obj);
return str;
}
@@ -713,13 +752,12 @@ inspect_obj(VALUE obj, VALUE str, int recur)
* obj.inspect -> string
*
* Returns a string containing a human-readable representation of <i>obj</i>.
- * The default <code>inspect</code> shows the object's class name,
- * an encoding of the object id, and a list of the instance variables and
- * their values (by calling #inspect on each of them).
- * User defined classes should override this method to provide a better
- * representation of <i>obj</i>. When overriding this method, it should
- * return a string whose encoding is compatible with the default external
- * encoding.
+ * The default #inspect shows the object's class name, an encoding of
+ * its memory address, and a list of the instance variables and their
+ * values (by calling #inspect on each of them). User defined classes
+ * should override this method to provide a better representation of
+ * <i>obj</i>. When overriding this method, it should return a string
+ * whose encoding is compatible with the default external encoding.
*
* [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]"
* Time.new.inspect #=> "2008-03-08 19:43:39 +0900"
@@ -754,15 +792,13 @@ rb_obj_inspect(VALUE obj)
static VALUE
class_or_module_required(VALUE c)
{
- if (SPECIAL_CONST_P(c)) goto not_class;
- switch (BUILTIN_TYPE(c)) {
+ switch (OBJ_BUILTIN_TYPE(c)) {
case T_MODULE:
case T_CLASS:
case T_ICLASS:
break;
default:
- not_class:
rb_raise(rb_eTypeError, "class or module required");
}
return c;
@@ -775,7 +811,7 @@ static VALUE class_search_ancestor(VALUE cl, VALUE c);
* obj.instance_of?(class) -> true or false
*
* Returns <code>true</code> if <i>obj</i> is an instance of the given
- * class. See also <code>Object#kind_of?</code>.
+ * class. See also Object#kind_of?.
*
* class A; end
* class B < A; end
@@ -867,31 +903,6 @@ rb_class_search_ancestor(VALUE cl, VALUE c)
return class_search_ancestor(cl, RCLASS_ORIGIN(c));
}
-/**
- * call-seq:
- * obj.tap {|x| block } -> obj
- *
- * Yields self to the block, and then returns self.
- * The primary purpose of this method is to "tap into" a method chain,
- * in order to perform operations on intermediate results within the chain.
- *
- * (1..10) .tap {|x| puts "original: #{x}" }
- * .to_a .tap {|x| puts "array: #{x}" }
- * .select {|x| x.even? } .tap {|x| puts "evens: #{x}" }
- * .map {|x| x*x } .tap {|x| puts "squares: #{x}" }
- *
- *--
- * \private
- *++
- */
-
-VALUE
-rb_obj_tap(VALUE obj)
-{
- rb_yield(obj);
- return obj;
-}
-
/*
* Document-method: inherited
@@ -1126,28 +1137,29 @@ rb_obj_dummy(void)
return Qnil;
}
+static VALUE
+rb_obj_dummy0(VALUE _)
+{
+ return rb_obj_dummy();
+}
+
+static VALUE
+rb_obj_dummy1(VALUE _x, VALUE _y)
+{
+ return rb_obj_dummy();
+}
+
/**
* call-seq:
- * obj.tainted? -> true or false
- *
- * Returns true if the object is tainted.
+ * obj.tainted? -> false
*
- * See #taint for more information.
- *--
- * Determines if \a obj is tainted. Equivalent to \c Object\#tainted? in Ruby.
- * \param[in] obj the object to be determined
- * \retval Qtrue if the object is tainted
- * \retval Qfalse if the object is not tainted
- * \sa rb_obj_taint
- * \sa rb_obj_untaint
- *++
+ * Returns false. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_tainted(VALUE obj)
{
- if (OBJ_TAINTED(obj))
- return Qtrue;
+ rb_warn_deprecated_to_remove("Object#tainted?", "3.2");
return Qfalse;
}
@@ -1155,33 +1167,13 @@ rb_obj_tainted(VALUE obj)
* call-seq:
* obj.taint -> obj
*
- * Mark the object as tainted.
- *
- * Objects that are marked as tainted will be restricted from various built-in
- * methods. This is to prevent insecure data, such as command-line arguments
- * or strings read from Kernel#gets, from inadvertently compromising the user's
- * system.
- *
- * To check whether an object is tainted, use #tainted?.
- *
- * You should only untaint a tainted object if your code has inspected it and
- * determined that it is safe. To do so use #untaint.
- *--
- * Marks the object as tainted. Equivalent to \c Object\#taint in Ruby
- * \param[in] obj the object to be tainted
- * \return the object itself
- * \sa rb_obj_untaint
- * \sa rb_obj_tainted
- *++
+ * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_taint(VALUE obj)
{
- if (!OBJ_TAINTED(obj) && OBJ_TAINTABLE(obj)) {
- rb_check_frozen(obj);
- OBJ_TAINT(obj);
- }
+ rb_warn_deprecated_to_remove("Object#taint", "3.2");
return obj;
}
@@ -1190,74 +1182,42 @@ rb_obj_taint(VALUE obj)
* call-seq:
* obj.untaint -> obj
*
- * Removes the tainted mark from the object.
- *
- * See #taint for more information.
- *--
- * Removes the tainted mark from the object.
- * Equivalent to \c Object\#untaint in Ruby.
- *
- * \param[in] obj the object to be tainted
- * \return the object itself
- * \sa rb_obj_taint
- * \sa rb_obj_tainted
- *++
+ * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_untaint(VALUE obj)
{
- if (OBJ_TAINTED(obj)) {
- rb_check_frozen(obj);
- FL_UNSET(obj, FL_TAINT);
- }
+ rb_warn_deprecated_to_remove("Object#untaint", "3.2");
return obj;
}
/**
* call-seq:
- * obj.untrusted? -> true or false
+ * obj.untrusted? -> false
*
- * Deprecated method that is equivalent to #tainted?.
- *--
- * \deprecated Use rb_obj_tainted.
- *
- * Trustiness used to have independent semantics from taintedness.
- * But now trustiness of objects is obsolete and this function behaves
- * the same as rb_obj_tainted.
- *
- * \sa rb_obj_tainted
- *++
+ * Returns false. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_untrusted(VALUE obj)
{
- rb_warning("untrusted? is deprecated and its behavior is same as tainted?");
- return rb_obj_tainted(obj);
+ rb_warn_deprecated_to_remove("Object#untrusted?", "3.2");
+ return Qfalse;
}
/**
* call-seq:
* obj.untrust -> obj
*
- * Deprecated method that is equivalent to #taint.
- *--
- * \deprecated Use rb_obj_taint(obj)
- *
- * Trustiness used to have independent semantics from taintedness.
- * But now trustiness of objects is obsolete and this function behaves
- * the same as rb_obj_taint.
- *
- * \sa rb_obj_taint
- *++
+ * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_untrust(VALUE obj)
{
- rb_warning("untrust is deprecated and its behavior is same as taint");
- return rb_obj_taint(obj);
+ rb_warn_deprecated_to_remove("Object#untrust", "3.2");
+ return obj;
}
@@ -1265,37 +1225,24 @@ rb_obj_untrust(VALUE obj)
* call-seq:
* obj.trust -> obj
*
- * Deprecated method that is equivalent to #untaint.
- *--
- * \deprecated Use rb_obj_untaint(obj)
- *
- * Trustiness used to have independent semantics from taintedness.
- * But now trustiness of objects is obsolete and this function behaves
- * the same as rb_obj_untaint.
- *
- * \sa rb_obj_untaint
- *++
+ * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_trust(VALUE obj)
{
- rb_warning("trust is deprecated and its behavior is same as untaint");
- return rb_obj_untaint(obj);
+ rb_warn_deprecated_to_remove("Object#trust", "3.2");
+ return obj;
}
/**
- * Convenient function to infect \a victim with the taintedness of \a carrier.
- *
- * It just keeps the taintedness of \a victim if \a carrier is not tainted.
- * \param[in,out] victim the object being infected with the taintness of \a carrier
- * \param[in] carrier a possibly tainted object
+ * Does nothing. This method is deprecated and will be removed in Ruby 3.2.
*/
void
rb_obj_infect(VALUE victim, VALUE carrier)
{
- OBJ_INFECT(victim, carrier);
+ rb_warn_deprecated_to_remove("rb_obj_infect", "3.2");
}
/**
@@ -1303,9 +1250,9 @@ rb_obj_infect(VALUE victim, VALUE carrier)
* obj.freeze -> obj
*
* Prevents further modifications to <i>obj</i>. A
- * <code>RuntimeError</code> will be raised if modification is attempted.
+ * RuntimeError will be raised if modification is attempted.
* There is no way to unfreeze a frozen object. See also
- * <code>Object#frozen?</code>.
+ * Object#frozen?.
*
* This method returns self.
*
@@ -1315,7 +1262,7 @@ rb_obj_infect(VALUE victim, VALUE carrier)
*
* <em>produces:</em>
*
- * prog.rb:3:in `<<': can't modify frozen Array (RuntimeError)
+ * prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
* from prog.rb:3
*
* Objects of the following classes are always frozen: Integer,
@@ -1339,23 +1286,6 @@ rb_obj_freeze(VALUE obj)
return obj;
}
-/**
- * call-seq:
- * obj.frozen? -> true or false
- *
- * Returns the freeze status of <i>obj</i>.
- *
- * a = [ "a", "b", "c" ]
- * a.freeze #=> ["a", "b", "c"]
- * a.frozen? #=> true
- *--
- * Determines if the object is frozen. Equivalent to \c Object\#frozen? in Ruby.
- * \param[in] obj the object to be determines
- * \retval Qtrue if frozen
- * \retval Qfalse if not frozen
- *++
- */
-
VALUE
rb_obj_frozen_p(VALUE obj)
{
@@ -1410,7 +1340,7 @@ nil_to_f(VALUE obj)
static VALUE
nil_to_s(VALUE obj)
{
- return rb_usascii_str_new(0, 0);
+ return rb_cNilClass_to_s;
}
/*
@@ -1460,11 +1390,24 @@ nil_inspect(VALUE obj)
return rb_usascii_str_new2("nil");
}
+/*
+ * call-seq:
+ * nil =~ other -> nil
+ *
+ * Dummy pattern matching -- always returns nil.
+ */
+
+static VALUE
+nil_match(VALUE obj1, VALUE obj2)
+{
+ return Qnil;
+}
+
/***********************************************************************
* Document-class: TrueClass
*
* The global value <code>true</code> is the only instance of class
- * <code>TrueClass</code> and represents a logically true value in
+ * TrueClass and represents a logically true value in
* boolean expressions. The class provides operators allowing
* <code>true</code> to be used in logical expressions.
*/
@@ -1480,7 +1423,7 @@ nil_inspect(VALUE obj)
static VALUE
true_to_s(VALUE obj)
{
- return rb_usascii_str_new2("true");
+ return rb_cTrueClass_to_s;
}
@@ -1541,7 +1484,7 @@ true_xor(VALUE obj, VALUE obj2)
* Document-class: FalseClass
*
* The global value <code>false</code> is the only instance of class
- * <code>FalseClass</code> and represents a logically false value in
+ * FalseClass and represents a logically false value in
* boolean expressions. The class provides operators allowing
* <code>false</code> to participate correctly in logical expressions.
*
@@ -1557,7 +1500,7 @@ true_xor(VALUE obj, VALUE obj2)
static VALUE
false_to_s(VALUE obj)
{
- return rb_usascii_str_new2("false");
+ return rb_cFalseClass_to_s;
}
/*
@@ -1586,13 +1529,7 @@ false_and(VALUE obj, VALUE obj2)
* <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
*/
-static VALUE
-false_or(VALUE obj, VALUE obj2)
-{
- return RTEST(obj2)?Qtrue:Qfalse;
-}
-
-
+#define false_or true_and
/*
* call-seq:
@@ -1605,11 +1542,7 @@ false_or(VALUE obj, VALUE obj2)
*
*/
-static VALUE
-false_xor(VALUE obj, VALUE obj2)
-{
- return RTEST(obj2)?Qtrue:Qfalse;
-}
+#define false_xor true_and
/*
* call-seq:
@@ -1635,7 +1568,7 @@ rb_true(VALUE obj)
*/
-static VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_false(VALUE obj)
{
return Qfalse;
@@ -1646,14 +1579,19 @@ rb_false(VALUE obj)
* call-seq:
* obj =~ other -> nil
*
- * Pattern Match---Overridden by descendants (notably
- * <code>Regexp</code> and <code>String</code>) to provide meaningful
- * pattern-match semantics.
+ * This method is deprecated.
+ *
+ * This is not only useless but also troublesome because it may hide a
+ * type error.
*/
static VALUE
rb_obj_match(VALUE obj1, VALUE obj2)
{
+ if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_DEPRECATED)) {
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "deprecated Object#=~ is called on %"PRIsVALUE
+ "; it always returns nil", rb_obj_class(obj1));
+ }
return Qnil;
}
@@ -1680,21 +1618,21 @@ rb_obj_not_match(VALUE obj1, VALUE obj2)
* Returns 0 if +obj+ and +other+ are the same object
* or <code>obj == other</code>, otherwise nil.
*
- * The <code><=></code> is used by various methods to compare objects, for example
+ * The #<=> is used by various methods to compare objects, for example
* Enumerable#sort, Enumerable#max etc.
*
- * Your implementation of <code><=></code> should return one of the following values: -1, 0,
+ * Your implementation of #<=> should return one of the following values: -1, 0,
* 1 or nil. -1 means self is smaller than other. 0 means self is equal to other.
* 1 means self is bigger than other. Nil means the two values could not be
* compared.
*
- * When you define <code><=></code>, you can include Comparable to gain the methods
- * <code><=</code>, <code><</code>, <code>==</code>, <code>>=</code>, <code>></code> and <code>between?</code>.
+ * When you define #<=>, you can include Comparable to gain the
+ * methods #<=, #<, #==, #>=, #> and #between?.
*/
static VALUE
rb_obj_cmp(VALUE obj1, VALUE obj2)
{
- if (obj1 == obj2 || rb_equal(obj1, obj2))
+ if (rb_equal(obj1, obj2))
return INT2FIX(0);
return Qnil;
}
@@ -1703,16 +1641,16 @@ rb_obj_cmp(VALUE obj1, VALUE obj2)
*
* Document-class: Module
*
- * A <code>Module</code> is a collection of methods and constants. The
+ * A Module is a collection of methods and constants. The
* methods in a module may be instance methods or module methods.
* Instance methods appear as methods in a class when the module is
* included, module methods do not. Conversely, module methods may be
* called without creating an encapsulating object, while instance
- * methods may not. (See <code>Module#module_function</code>.)
+ * methods may not. (See Module#module_function.)
*
* In the descriptions that follow, the parameter <i>sym</i> refers
* to a symbol, which is either a quoted string or a
- * <code>Symbol</code> (such as <code>:name</code>).
+ * Symbol (such as <code>:name</code>).
*
* module Mod
* include Math
@@ -1768,7 +1706,7 @@ rb_mod_to_s(VALUE klass)
rb_str_cat2(s, ">");
return s;
}
- return rb_str_dup(rb_class_name(klass));
+ return rb_class_name(klass);
}
/*
@@ -1951,7 +1889,7 @@ rb_class_s_alloc(VALUE klass)
*
* Creates a new anonymous module. If a block is given, it is passed
* the module object, and the block is evaluated in the context of this
- * module like <code>module_eval</code>.
+ * module like #module_eval.
*
* fred = Module.new do
* def meth1
@@ -1981,10 +1919,11 @@ rb_mod_initialize(VALUE module)
/* :nodoc: */
static VALUE
-rb_mod_initialize_clone(VALUE clone, VALUE orig)
+rb_mod_initialize_clone(int argc, VALUE* argv, VALUE clone)
{
- VALUE ret;
- ret = rb_obj_init_dup_clone(clone, orig);
+ VALUE ret, orig, opts;
+ rb_scan_args(argc, argv, "1:", &orig, &opts);
+ ret = rb_obj_init_clone(argc, argv, clone);
if (OBJ_FROZEN(orig))
rb_class_name(clone);
return ret;
@@ -1996,12 +1935,12 @@ rb_mod_initialize_clone(VALUE clone, VALUE orig)
* Class.new(super_class=Object) { |mod| ... } -> a_class
*
* Creates a new anonymous (unnamed) class with the given superclass
- * (or <code>Object</code> if no parameter is given). You can give a
+ * (or Object if no parameter is given). You can give a
* class a name by assigning the class object to a constant.
*
* If a block is given, it is passed the class object, and the block
* is evaluated in the context of this class like
- * <code>class_eval</code>.
+ * #class_eval.
*
* fred = Class.new do
* def meth1
@@ -2028,11 +1967,11 @@ rb_class_initialize(int argc, VALUE *argv, VALUE klass)
if (RCLASS_SUPER(klass) != 0 || klass == rb_cBasicObject) {
rb_raise(rb_eTypeError, "already initialized class");
}
- if (argc == 0) {
+ if (rb_check_arity(argc, 0, 1) == 0) {
super = rb_cObject;
}
else {
- rb_scan_args(argc, argv, "01", &super);
+ super = argv[0];
rb_check_inheritable(super);
if (super != rb_cBasicObject && !RCLASS_SUPER(super)) {
rb_raise(rb_eTypeError, "can't inherit uninitialized class");
@@ -2054,6 +1993,9 @@ rb_undefined_alloc(VALUE klass)
klass);
}
+static rb_alloc_func_t class_get_alloc_func(VALUE klass);
+static VALUE class_call_alloc_func(rb_alloc_func_t allocator, VALUE klass);
+
/*
* call-seq:
* class.allocate() -> obj
@@ -2077,9 +2019,26 @@ rb_undefined_alloc(VALUE klass)
*/
static VALUE
+rb_class_alloc_m(VALUE klass)
+{
+ rb_alloc_func_t allocator = class_get_alloc_func(klass);
+ if (!rb_obj_respond_to(klass, rb_intern("allocate"), 1)) {
+ rb_raise(rb_eTypeError, "calling %"PRIsVALUE".allocate is prohibited",
+ klass);
+ }
+ return class_call_alloc_func(allocator, klass);
+}
+
+static VALUE
rb_class_alloc(VALUE klass)
{
- VALUE obj;
+ rb_alloc_func_t allocator = class_get_alloc_func(klass);
+ return class_call_alloc_func(allocator, klass);
+}
+
+static rb_alloc_func_t
+class_get_alloc_func(VALUE klass)
+{
rb_alloc_func_t allocator;
if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject) {
@@ -2092,6 +2051,13 @@ rb_class_alloc(VALUE klass)
if (!allocator) {
rb_undefined_alloc(klass);
}
+ return allocator;
+}
+
+static VALUE
+class_call_alloc_func(rb_alloc_func_t allocator, VALUE klass)
+{
+ VALUE obj;
RUBY_DTRACE_CREATE_HOOK(OBJECT, rb_class2name(klass));
@@ -2124,32 +2090,36 @@ rb_obj_alloc(VALUE klass)
return rb_class_alloc(klass);
}
-static VALUE
-rb_class_allocate_instance(VALUE klass)
-{
- NEWOBJ_OF(obj, struct RObject, klass, T_OBJECT | (RGENGC_WB_PROTECTED_OBJECT ? FL_WB_PROTECTED : 0));
- return (VALUE)obj;
-}
-
/*
* call-seq:
* class.new(args, ...) -> obj
*
- * Calls <code>allocate</code> to create a new object of
- * <i>class</i>'s class, then invokes that object's
- * <code>initialize</code> method, passing it <i>args</i>.
- * This is the method that ends up getting called whenever
- * an object is constructed using .new.
+ * Calls #allocate to create a new object of <i>class</i>'s class,
+ * then invokes that object's #initialize method, passing it
+ * <i>args</i>. This is the method that ends up getting called
+ * whenever an object is constructed using <code>.new</code>.
*
*/
-static VALUE
-rb_class_s_new(int argc, const VALUE *argv, VALUE klass)
+VALUE
+rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass)
{
VALUE obj;
obj = rb_class_alloc(klass);
- rb_obj_call_init(obj, argc, argv);
+ rb_obj_call_init_kw(obj, argc, argv, RB_PASS_CALLED_KEYWORDS);
+
+ return obj;
+}
+
+VALUE
+rb_class_new_instance_kw(int argc, const VALUE *argv, VALUE klass, int kw_splat)
+{
+ VALUE obj;
+ Check_Type(klass, T_CLASS);
+
+ obj = rb_class_alloc(klass);
+ rb_obj_call_init_kw(obj, argc, argv, kw_splat);
return obj;
}
@@ -2169,8 +2139,13 @@ rb_class_s_new(int argc, const VALUE *argv, VALUE klass)
VALUE
rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
{
+ VALUE obj;
Check_Type(klass, T_CLASS);
- return rb_class_s_new(argc, argv, klass);
+
+ obj = rb_class_alloc(klass);
+ rb_obj_call_init_kw(obj, argc, argv, RB_NO_KEYWORDS);
+
+ return obj;
}
/**
@@ -2231,9 +2206,14 @@ rb_class_get_superclass(VALUE klass)
return RCLASS(klass)->super;
}
+static const char bad_instance_name[] = "`%1$s' is not allowed as an instance variable name";
+static const char bad_class_name[] = "`%1$s' is not allowed as a class variable name";
+static const char bad_const_name[] = "wrong constant name %1$s";
+static const char bad_attr_name[] = "invalid attribute name `%1$s'";
+#define wrong_constant_name bad_const_name
+
/*! \private */
-#define id_for_var(obj, name, part, type) \
- id_for_setter(obj, name, type, "`%1$s' is not allowed as "#part" "#type" variable name")
+#define id_for_var(obj, name, type) id_for_setter(obj, name, type, bad_##type##_name)
/*! \private */
#define id_for_setter(obj, name, type, message) \
check_setter_id(obj, &(name), rb_is_##type##_id, rb_is_##type##_name, message, strlen(message))
@@ -2264,50 +2244,52 @@ rb_is_attr_id(ID id)
return rb_is_local_id(id) || rb_is_const_id(id);
}
-static const char wrong_constant_name[] = "wrong constant name %1$s";
-static const char invalid_attribute_name[] = "invalid attribute name `%1$s'";
-
static ID
id_for_attr(VALUE obj, VALUE name)
{
- ID id = id_for_setter(obj, name, attr, invalid_attribute_name);
+ ID id = id_for_var(obj, name, attr);
if (!id) id = rb_intern_str(name);
return id;
}
/*
* call-seq:
- * attr_reader(symbol, ...) -> nil
- * attr(symbol, ...) -> nil
- * attr_reader(string, ...) -> nil
- * attr(string, ...) -> nil
+ * attr_reader(symbol, ...) -> array
+ * attr(symbol, ...) -> array
+ * attr_reader(string, ...) -> array
+ * attr(string, ...) -> array
*
* Creates instance variables and corresponding methods that return the
* value of each instance variable. Equivalent to calling
* ``<code>attr</code><i>:name</i>'' on each name in turn.
* String arguments are converted to symbols.
+ * Returns an array of defined method names as symbols.
*/
static VALUE
rb_mod_attr_reader(int argc, VALUE *argv, VALUE klass)
{
int i;
+ VALUE names = rb_ary_new2(argc);
for (i=0; i<argc; i++) {
- rb_attr(klass, id_for_attr(klass, argv[i]), TRUE, FALSE, TRUE);
+ ID id = id_for_attr(klass, argv[i]);
+ rb_attr(klass, id, TRUE, FALSE, TRUE);
+ rb_ary_push(names, ID2SYM(id));
}
- return Qnil;
+ return names;
}
/**
* call-seq:
- * attr(name, ...) -> nil
- * attr(name, true) -> nil
- * attr(name, false) -> nil
+ * attr(name, ...) -> array
+ * attr(name, true) -> array
+ * attr(name, false) -> array
*
- * The first form is equivalent to <code>attr_reader</code>.
+ * The first form is equivalent to #attr_reader.
* The second form is equivalent to <code>attr_accessor(name)</code> but deprecated.
* The last form is equivalent to <code>attr_reader(name)</code> but deprecated.
+ * Returns an array of defined method names as symbols.
*--
* \private
* \todo can be static?
@@ -2317,47 +2299,57 @@ VALUE
rb_mod_attr(int argc, VALUE *argv, VALUE klass)
{
if (argc == 2 && (argv[1] == Qtrue || argv[1] == Qfalse)) {
- rb_warning("optional boolean argument is obsoleted");
- rb_attr(klass, id_for_attr(klass, argv[0]), 1, RTEST(argv[1]), TRUE);
- return Qnil;
+ ID id = id_for_attr(klass, argv[0]);
+ VALUE names = rb_ary_new();
+
+ rb_category_warning(RB_WARN_CATEGORY_DEPRECATED, "optional boolean argument is obsoleted");
+ rb_attr(klass, id, 1, RTEST(argv[1]), TRUE);
+ rb_ary_push(names, ID2SYM(id));
+ if (argv[1] == Qtrue) rb_ary_push(names, ID2SYM(rb_id_attrset(id)));
+ return names;
}
return rb_mod_attr_reader(argc, argv, klass);
}
/*
* call-seq:
- * attr_writer(symbol, ...) -> nil
- * attr_writer(string, ...) -> nil
+ * attr_writer(symbol, ...) -> array
+ * attr_writer(string, ...) -> array
*
* Creates an accessor method to allow assignment to the attribute
* <i>symbol</i><code>.id2name</code>.
* String arguments are converted to symbols.
+ * Returns an array of defined method names as symbols.
*/
static VALUE
rb_mod_attr_writer(int argc, VALUE *argv, VALUE klass)
{
int i;
+ VALUE names = rb_ary_new2(argc);
for (i=0; i<argc; i++) {
- rb_attr(klass, id_for_attr(klass, argv[i]), FALSE, TRUE, TRUE);
+ ID id = id_for_attr(klass, argv[i]);
+ rb_attr(klass, id, FALSE, TRUE, TRUE);
+ rb_ary_push(names, ID2SYM(rb_id_attrset(id)));
}
- return Qnil;
+ return names;
}
/*
* call-seq:
- * attr_accessor(symbol, ...) -> nil
- * attr_accessor(string, ...) -> nil
+ * attr_accessor(symbol, ...) -> array
+ * attr_accessor(string, ...) -> array
*
* Defines a named attribute for this module, where the name is
* <i>symbol.</i><code>id2name</code>, creating an instance variable
* (<code>@name</code>) and a corresponding access method to read it.
* Also creates a method called <code>name=</code> to set the attribute.
* String arguments are converted to symbols.
+ * Returns an array of defined method names as symbols.
*
* module Mod
- * attr_accessor(:one, :two)
+ * attr_accessor(:one, :two) #=> [:one, :one=, :two, :two=]
* end
* Mod.instance_methods.sort #=> [:one, :one=, :two, :two=]
*/
@@ -2366,11 +2358,16 @@ static VALUE
rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
{
int i;
+ VALUE names = rb_ary_new2(argc * 2);
for (i=0; i<argc; i++) {
- rb_attr(klass, id_for_attr(klass, argv[i]), TRUE, TRUE, TRUE);
+ ID id = id_for_attr(klass, argv[i]);
+
+ rb_attr(klass, id, TRUE, TRUE, TRUE);
+ rb_ary_push(names, ID2SYM(id));
+ rb_ary_push(names, ID2SYM(rb_id_attrset(id)));
}
- return Qnil;
+ return names;
}
/*
@@ -2443,8 +2440,7 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
pend = path + RSTRING_LEN(name);
if (p >= pend || !*p) {
- wrong_name:
- rb_name_err_raise(wrong_constant_name, mod, name);
+ goto wrong_name;
}
if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
@@ -2478,7 +2474,7 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
if (!id) {
part = rb_str_subseq(name, beglen, len);
OBJ_FREEZE(part);
- if (!ISUPPER(*pbeg) || !rb_is_const_name(part)) {
+ if (!rb_is_const_name(part)) {
name = part;
goto wrong_name;
}
@@ -2495,10 +2491,26 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
name = ID2SYM(id);
goto wrong_name;
}
- mod = RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);
+#if 0
+ mod = rb_const_get_0(mod, id, beglen > 0 || !RTEST(recur), RTEST(recur), FALSE);
+#else
+ if (!RTEST(recur)) {
+ mod = rb_const_get_at(mod, id);
+ }
+ else if (beglen == 0) {
+ mod = rb_const_get(mod, id);
+ }
+ else {
+ mod = rb_const_get_from(mod, id);
+ }
+#endif
}
return mod;
+
+ wrong_name:
+ rb_name_err_raise(wrong_constant_name, mod, name);
+ UNREACHABLE_RETURN(Qundef);
}
/*
@@ -2523,7 +2535,7 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
static VALUE
rb_mod_const_set(VALUE mod, VALUE name, VALUE value)
{
- ID id = id_for_setter(mod, name, const, wrong_constant_name);
+ ID id = id_for_var(mod, name, const);
if (!id) id = rb_intern_str(name);
rb_const_set(mod, id, value);
@@ -2601,8 +2613,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
pend = path + RSTRING_LEN(name);
if (p >= pend || !*p) {
- wrong_name:
- rb_name_err_raise(wrong_constant_name, mod, name);
+ goto wrong_name;
}
if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
@@ -2631,7 +2642,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
if (!id) {
part = rb_str_subseq(name, beglen, len);
OBJ_FREEZE(part);
- if (!ISUPPER(*pbeg) || !rb_is_const_name(part)) {
+ if (!rb_is_const_name(part)) {
name = part;
goto wrong_name;
}
@@ -2643,17 +2654,30 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
name = ID2SYM(id);
goto wrong_name;
}
- if (RTEST(recur)) {
- if (!rb_const_defined(mod, id))
- return Qfalse;
- mod = rb_const_get(mod, id);
- }
- else {
+
+#if 0
+ mod = rb_const_search(mod, id, beglen > 0 || !RTEST(recur), RTEST(recur), FALSE);
+ if (mod == Qundef) return Qfalse;
+#else
+ if (!RTEST(recur)) {
if (!rb_const_defined_at(mod, id))
return Qfalse;
+ if (p == pend) return Qtrue;
mod = rb_const_get_at(mod, id);
}
- recur = Qfalse;
+ else if (beglen == 0) {
+ if (!rb_const_defined(mod, id))
+ return Qfalse;
+ if (p == pend) return Qtrue;
+ mod = rb_const_get(mod, id);
+ }
+ else {
+ if (!rb_const_defined_from(mod, id))
+ return Qfalse;
+ if (p == pend) return Qtrue;
+ mod = rb_const_get_from(mod, id);
+ }
+#endif
if (p < pend && !RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {
rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",
@@ -2662,6 +2686,163 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
}
return Qtrue;
+
+ wrong_name:
+ rb_name_err_raise(wrong_constant_name, mod, name);
+ UNREACHABLE_RETURN(Qundef);
+}
+
+/*
+ * call-seq:
+ * mod.const_source_location(sym, inherit=true) -> [String, Integer]
+ * mod.const_source_location(str, inherit=true) -> [String, Integer]
+ *
+ * Returns the Ruby source filename and line number containing the definition
+ * of the constant specified. If the named constant is not found, +nil+ is returned.
+ * If the constant is found, but its source location can not be extracted
+ * (constant is defined in C code), empty array is returned.
+ *
+ * _inherit_ specifies whether to lookup in <code>mod.ancestors</code> (+true+
+ * by default).
+ *
+ * # test.rb:
+ * class A # line 1
+ * C1 = 1
+ * C2 = 2
+ * end
+ *
+ * module M # line 6
+ * C3 = 3
+ * end
+ *
+ * class B < A # line 10
+ * include M
+ * C4 = 4
+ * end
+ *
+ * class A # continuation of A definition
+ * C2 = 8 # constant redefinition; warned yet allowed
+ * end
+ *
+ * p B.const_source_location('C4') # => ["test.rb", 12]
+ * p B.const_source_location('C3') # => ["test.rb", 7]
+ * p B.const_source_location('C1') # => ["test.rb", 2]
+ *
+ * p B.const_source_location('C3', false) # => nil -- don't lookup in ancestors
+ *
+ * p A.const_source_location('C2') # => ["test.rb", 16] -- actual (last) definition place
+ *
+ * p Object.const_source_location('B') # => ["test.rb", 10] -- top-level constant could be looked through Object
+ * p Object.const_source_location('A') # => ["test.rb", 1] -- class reopening is NOT considered new definition
+ *
+ * p B.const_source_location('A') # => ["test.rb", 1] -- because Object is in ancestors
+ * p M.const_source_location('A') # => ["test.rb", 1] -- Object is not ancestor, but additionally checked for modules
+ *
+ * p Object.const_source_location('A::C1') # => ["test.rb", 2] -- nesting is supported
+ * p Object.const_source_location('String') # => [] -- constant is defined in C code
+ *
+ *
+ */
+static VALUE
+rb_mod_const_source_location(int argc, VALUE *argv, VALUE mod)
+{
+ VALUE name, recur, loc = Qnil;
+ rb_encoding *enc;
+ const char *pbeg, *p, *path, *pend;
+ ID id;
+
+ rb_check_arity(argc, 1, 2);
+ name = argv[0];
+ recur = (argc == 1) ? Qtrue : argv[1];
+
+ if (SYMBOL_P(name)) {
+ if (!rb_is_const_sym(name)) goto wrong_name;
+ id = rb_check_id(&name);
+ if (!id) return Qnil;
+ return RTEST(recur) ? rb_const_source_location(mod, id) : rb_const_source_location_at(mod, id);
+ }
+
+ path = StringValuePtr(name);
+ enc = rb_enc_get(name);
+
+ if (!rb_enc_asciicompat(enc)) {
+ rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");
+ }
+
+ pbeg = p = path;
+ pend = path + RSTRING_LEN(name);
+
+ if (p >= pend || !*p) {
+ goto wrong_name;
+ }
+
+ if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
+ mod = rb_cObject;
+ p += 2;
+ pbeg = p;
+ }
+
+ while (p < pend) {
+ VALUE part;
+ long len, beglen;
+
+ while (p < pend && *p != ':') p++;
+
+ if (pbeg == p) goto wrong_name;
+
+ id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);
+ beglen = pbeg-path;
+
+ if (p < pend && p[0] == ':') {
+ if (p + 2 >= pend || p[1] != ':') goto wrong_name;
+ p += 2;
+ pbeg = p;
+ }
+
+ if (!id) {
+ part = rb_str_subseq(name, beglen, len);
+ OBJ_FREEZE(part);
+ if (!rb_is_const_name(part)) {
+ name = part;
+ goto wrong_name;
+ }
+ else {
+ return Qnil;
+ }
+ }
+ if (!rb_is_const_id(id)) {
+ name = ID2SYM(id);
+ goto wrong_name;
+ }
+ if (p < pend) {
+ if (RTEST(recur)) {
+ mod = rb_const_get(mod, id);
+ }
+ else {
+ mod = rb_const_get_at(mod, id);
+ }
+ if (!RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {
+ rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",
+ QUOTE(name));
+ }
+ }
+ else {
+ if (RTEST(recur)) {
+ loc = rb_const_source_location(mod, id);
+ }
+ else {
+ loc = rb_const_source_location_at(mod, id);
+ }
+ break;
+ }
+ recur = Qfalse;
+ }
+
+ return loc;
+
+ wrong_name:
+ rb_name_err_raise(wrong_constant_name, mod, name);
+ UNREACHABLE_RETURN(Qundef);
}
/*
@@ -2672,7 +2853,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
* Returns the value of the given instance variable, or nil if the
* instance variable is not set. The <code>@</code> part of the
* variable name should be included for regular instance
- * variables. Throws a <code>NameError</code> exception if the
+ * variables. Throws a NameError exception if the
* supplied symbol is not valid as an instance variable name.
* String arguments are converted to symbols.
*
@@ -2689,7 +2870,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
static VALUE
rb_obj_ivar_get(VALUE obj, VALUE iv)
{
- ID id = id_for_var(obj, iv, an, instance);
+ ID id = id_for_var(obj, iv, instance);
if (!id) {
return Qnil;
@@ -2703,9 +2884,9 @@ rb_obj_ivar_get(VALUE obj, VALUE iv)
* obj.instance_variable_set(string, obj) -> obj
*
* Sets the instance variable named by <i>symbol</i> to the given
- * object, thereby frustrating the efforts of the class's
- * author to attempt to provide proper encapsulation. The variable
- * does not have to exist prior to this call.
+ * object. This may circumvent the encapsulation intended by
+ * the author of the class, so it should be used with care.
+ * The variable does not have to exist prior to this call.
* If the instance variable name is passed as a string, that string
* is converted to a symbol.
*
@@ -2723,7 +2904,7 @@ rb_obj_ivar_get(VALUE obj, VALUE iv)
static VALUE
rb_obj_ivar_set(VALUE obj, VALUE iv, VALUE val)
{
- ID id = id_for_var(obj, iv, an, instance);
+ ID id = id_for_var(obj, iv, instance);
if (!id) id = rb_intern_str(iv);
return rb_ivar_set(obj, id, val);
}
@@ -2751,7 +2932,7 @@ rb_obj_ivar_set(VALUE obj, VALUE iv, VALUE val)
static VALUE
rb_obj_ivar_defined(VALUE obj, VALUE iv)
{
- ID id = id_for_var(obj, iv, an, instance);
+ ID id = id_for_var(obj, iv, instance);
if (!id) {
return Qfalse;
@@ -2765,7 +2946,7 @@ rb_obj_ivar_defined(VALUE obj, VALUE iv)
* mod.class_variable_get(string) -> obj
*
* Returns the value of the given class variable (or throws a
- * <code>NameError</code> exception). The <code>@@</code> part of the
+ * NameError exception). The <code>@@</code> part of the
* variable name should be included for regular class variables.
* String arguments are converted to symbols.
*
@@ -2778,7 +2959,7 @@ rb_obj_ivar_defined(VALUE obj, VALUE iv)
static VALUE
rb_mod_cvar_get(VALUE obj, VALUE iv)
{
- ID id = id_for_var(obj, iv, a, class);
+ ID id = id_for_var(obj, iv, class);
if (!id) {
rb_name_err_raise("uninitialized class variable %1$s in %2$s",
@@ -2810,7 +2991,7 @@ rb_mod_cvar_get(VALUE obj, VALUE iv)
static VALUE
rb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val)
{
- ID id = id_for_var(obj, iv, a, class);
+ ID id = id_for_var(obj, iv, class);
if (!id) id = rb_intern_str(iv);
rb_cvar_set(obj, id, val);
return val;
@@ -2835,7 +3016,7 @@ rb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val)
static VALUE
rb_mod_cvar_defined(VALUE obj, VALUE iv)
{
- ID id = id_for_var(obj, iv, a, class);
+ ID id = id_for_var(obj, iv, class);
if (!id) {
return Qfalse;
@@ -3018,7 +3199,7 @@ rb_check_convert_type(VALUE val, int type, const char *tname, const char *method
}
/*! \private */
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_check_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
{
VALUE v;
@@ -3033,17 +3214,19 @@ rb_check_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
return v;
}
+#define try_to_int(val, mid, raise) \
+ convert_type_with_id(val, "Integer", mid, raise, -1)
-static VALUE
-rb_to_integer(VALUE val, const char *method)
+ALWAYS_INLINE(static VALUE rb_to_integer(VALUE val, const char *method, ID mid));
+static inline VALUE
+rb_to_integer(VALUE val, const char *method, ID mid)
{
VALUE v;
- if (FIXNUM_P(val)) return val;
- if (RB_TYPE_P(val, T_BIGNUM)) return val;
- v = convert_type(val, "Integer", method, TRUE);
- if (!rb_obj_is_kind_of(v, rb_cInteger)) {
- conversion_mismatch(val, "Integer", method, v);
+ if (RB_INTEGER_TYPE_P(val)) return val;
+ v = try_to_int(val, mid, TRUE);
+ if (!RB_INTEGER_TYPE_P(v)) {
+ conversion_mismatch(val, "Integer", method, v);
}
return v;
}
@@ -3066,8 +3249,8 @@ rb_check_to_integer(VALUE val, const char *method)
if (FIXNUM_P(val)) return val;
if (RB_TYPE_P(val, T_BIGNUM)) return val;
v = convert_type(val, "Integer", method, FALSE);
- if (!rb_obj_is_kind_of(v, rb_cInteger)) {
- return Qnil;
+ if (!RB_INTEGER_TYPE_P(v)) {
+ return Qnil;
}
return v;
}
@@ -3083,7 +3266,7 @@ rb_check_to_integer(VALUE val, const char *method)
VALUE
rb_to_int(VALUE val)
{
- return rb_to_integer(val, "to_int");
+ return rb_to_integer(val, "to_int", idTo_int);
}
/**
@@ -3098,44 +3281,67 @@ rb_to_int(VALUE val)
VALUE
rb_check_to_int(VALUE val)
{
- return rb_check_to_integer(val, "to_int");
+ if (RB_INTEGER_TYPE_P(val)) return val;
+ val = try_to_int(val, idTo_int, FALSE);
+ if (RB_INTEGER_TYPE_P(val)) return val;
+ return Qnil;
}
static VALUE
-rb_convert_to_integer(VALUE val, int base)
+rb_check_to_i(VALUE val)
+{
+ if (RB_INTEGER_TYPE_P(val)) return val;
+ val = try_to_int(val, idTo_i, FALSE);
+ if (RB_INTEGER_TYPE_P(val)) return val;
+ return Qnil;
+}
+
+static VALUE
+rb_convert_to_integer(VALUE val, int base, int raise_exception)
{
VALUE tmp;
+ if (base) {
+ tmp = rb_check_string_type(val);
+
+ if (! NIL_P(tmp)) {
+ val = tmp;
+ }
+ else if (! raise_exception) {
+ return Qnil;
+ }
+ else {
+ rb_raise(rb_eArgError, "base specified for non string value");
+ }
+ }
if (RB_FLOAT_TYPE_P(val)) {
- double f;
- if (base != 0) goto arg_error;
- f = RFLOAT_VALUE(val);
- if (FIXABLE(f)) return LONG2FIX((long)f);
- return rb_dbl2big(f);
+ double f = RFLOAT_VALUE(val);
+ if (!raise_exception && !isfinite(f)) return Qnil;
+ if (FIXABLE(f)) return LONG2FIX((long)f);
+ return rb_dbl2big(f);
}
else if (RB_INTEGER_TYPE_P(val)) {
- if (base != 0) goto arg_error;
- return val;
+ return val;
}
else if (RB_TYPE_P(val, T_STRING)) {
- return rb_str_to_inum(val, base, TRUE);
+ return rb_str_convert_to_inum(val, base, TRUE, raise_exception);
}
else if (NIL_P(val)) {
- if (base != 0) goto arg_error;
- rb_raise(rb_eTypeError, "can't convert nil into Integer");
- }
- if (base != 0) {
- tmp = rb_check_string_type(val);
- if (!NIL_P(tmp)) return rb_str_to_inum(tmp, base, TRUE);
- arg_error:
- rb_raise(rb_eArgError, "base specified for non string value");
+ if (!raise_exception) return Qnil;
+ rb_raise(rb_eTypeError, "can't convert nil into Integer");
}
- tmp = convert_type(val, "Integer", "to_int", FALSE);
- if (NIL_P(tmp)) {
- return rb_to_integer(val, "to_i");
+
+ tmp = rb_protect(rb_check_to_int, val, NULL);
+ if (RB_INTEGER_TYPE_P(tmp)) return tmp;
+ rb_set_errinfo(Qnil);
+
+ if (!raise_exception) {
+ VALUE result = rb_protect(rb_check_to_i, val, NULL);
+ rb_set_errinfo(Qnil);
+ return result;
}
- return tmp;
+ return rb_to_integer(val, "to_i", idTo_i);
}
/**
@@ -3147,65 +3353,97 @@ rb_convert_to_integer(VALUE val, int base)
VALUE
rb_Integer(VALUE val)
{
- return rb_convert_to_integer(val, 0);
+ return rb_convert_to_integer(val, 0, TRUE);
}
+int
+rb_bool_expected(VALUE obj, const char *flagname)
+{
+ switch (obj) {
+ case Qtrue: case Qfalse:
+ break;
+ default:
+ rb_raise(rb_eArgError, "true or false is expected as %s: %+"PRIsVALUE,
+ flagname, obj);
+ }
+ return obj != Qfalse;
+}
+
+int
+rb_opts_exception_p(VALUE opts, int default_value)
+{
+ static ID kwds[1] = {idException};
+ VALUE exception;
+ if (rb_get_kwargs(opts, kwds, 0, 1, &exception))
+ return rb_bool_expected(exception, "exception");
+ return default_value;
+}
+
+#define opts_exception_p(opts) rb_opts_exception_p((opts), TRUE)
+
/*
* call-seq:
- * Integer(arg, base=0) -> integer
+ * Integer(arg, base=0, exception: true) -> integer or nil
*
- * Converts <i>arg</i> to an <code>Integer</code>.
+ * Converts <i>arg</i> to an Integer.
* Numeric types are converted directly (with floating point numbers
* being truncated). <i>base</i> (0, or between 2 and 36) is a base for
- * integer string representation. If <i>arg</i> is a <code>String</code>,
+ * integer string representation. If <i>arg</i> is a String,
* when <i>base</i> is omitted or equals zero, radix indicators
* (<code>0</code>, <code>0b</code>, and <code>0x</code>) are honored.
- * In any case, strings should be strictly conformed to numeric
- * representation. This behavior is different from that of
- * <code>String#to_i</code>. Non string values will be converted by first
- * trying <code>to_int</code>, then <code>to_i</code>. Passing <code>nil</code>
- * raises a TypeError.
+ * In any case, strings should consist only of one or more digits, except
+ * for that a sign, one underscore between two digits, and leading/trailing
+ * spaces are optional. This behavior is different from that of
+ * String#to_i. Non string values will be converted by first
+ * trying <code>to_int</code>, then <code>to_i</code>.
+ *
+ * Passing <code>nil</code> raises a TypeError, while passing a String that
+ * does not conform with numeric representation raises an ArgumentError.
+ * This behavior can be altered by passing <code>exception: false</code>,
+ * in this case a not convertible value will return <code>nil</code>.
*
* Integer(123.999) #=> 123
* Integer("0x1a") #=> 26
* Integer(Time.new) #=> 1204973019
* Integer("0930", 10) #=> 930
* Integer("111", 2) #=> 7
- * Integer(nil) #=> TypeError
+ * Integer(" +1_0 ") #=> 10
+ * Integer(nil) #=> TypeError: can't convert nil into Integer
+ * Integer("x") #=> ArgumentError: invalid value for Integer(): "x"
+ *
+ * Integer("x", exception: false) #=> nil
+ *
*/
static VALUE
rb_f_integer(int argc, VALUE *argv, VALUE obj)
{
- VALUE arg = Qnil;
+ VALUE arg = Qnil, opts = Qnil;
int base = 0;
- switch (argc) {
- case 2:
- base = NUM2INT(argv[1]);
- case 1:
- arg = argv[0];
- break;
- default:
- /* should cause ArgumentError */
- rb_scan_args(argc, argv, "11", NULL, NULL);
+ if (argc > 1) {
+ int narg = 1;
+ VALUE vbase = rb_check_to_int(argv[1]);
+ if (!NIL_P(vbase)) {
+ base = NUM2INT(vbase);
+ narg = 2;
+ }
+ if (argc > narg) {
+ VALUE hash = rb_check_hash_type(argv[argc-1]);
+ if (!NIL_P(hash)) {
+ opts = rb_extract_keywords(&hash);
+ if (!hash) --argc;
+ }
+ }
}
- return rb_convert_to_integer(arg, base);
+ rb_check_arity(argc, 1, 2);
+ arg = argv[0];
+
+ return rb_convert_to_integer(arg, base, opts_exception_p(opts));
}
-/*!
- * Parses a string representation of a floating point number.
- *
- * \param[in] p a string representation of a floating number
- * \param[in] badcheck raises an exception on parse error if \a badcheck is non-zero.
- * \return the floating point number in the string on success,
- * 0.0 on parse error and \a badcheck is zero.
- * \note it always fails to parse a hexadecimal representation like "0xAB.CDp+1" when
- * \a badcheck is zero, even though it would success if \a badcheck was non-zero.
- * This inconsistency is coming from a historical compatibility reason. [ruby-dev:40822]
- */
-double
-rb_cstr_to_dbl(const char *p, int badcheck)
+static double
+rb_cstr_to_dbl_raise(const char *p, int badcheck, int raise, int *error)
{
const char *q;
char *end;
@@ -3214,79 +3452,116 @@ rb_cstr_to_dbl(const char *p, int badcheck)
int w;
enum {max_width = 20};
#define OutOfRange() ((end - p > max_width) ? \
- (w = max_width, ellipsis = "...") : \
- (w = (int)(end - p), ellipsis = ""))
+ (w = max_width, ellipsis = "...") : \
+ (w = (int)(end - p), ellipsis = ""))
if (!p) return 0.0;
q = p;
while (ISSPACE(*p)) p++;
if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
- return 0.0;
+ return 0.0;
}
d = strtod(p, &end);
if (errno == ERANGE) {
- OutOfRange();
- rb_warning("Float %.*s%s out of range", w, p, ellipsis);
- errno = 0;
+ OutOfRange();
+ rb_warning("Float %.*s%s out of range", w, p, ellipsis);
+ errno = 0;
}
if (p == end) {
- if (badcheck) {
- bad:
- rb_invalid_str(q, "Float()");
- }
- return d;
+ if (badcheck) {
+ goto bad;
+ }
+ return d;
}
if (*end) {
- char buf[DBL_DIG * 4 + 10];
- 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 an underscore between digits */
- if (n == buf || !ISDIGIT(prev) || (++p, !ISDIGIT(*p))) {
- if (badcheck) goto bad;
- break;
- }
- }
- 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 = strtod(p, &end);
- if (errno == ERANGE) {
- OutOfRange();
- rb_warning("Float %.*s%s out of range", w, p, ellipsis);
- errno = 0;
- }
- if (badcheck) {
- if (!end || p == end) goto bad;
- while (*end && ISSPACE(*end)) end++;
- if (*end) goto bad;
- }
+ char buf[DBL_DIG * 4 + 10];
+ char *n = buf;
+ char *const init_e = buf + DBL_DIG * 4;
+ char *e = init_e;
+ char prev = 0;
+ int dot_seen = FALSE;
+
+ switch (*p) {case '+': case '-': prev = *n++ = *p++;}
+ if (*p == '0') {
+ prev = *n++ = '0';
+ while (*++p == '0');
+ }
+ while (p < end && n < e) prev = *n++ = *p++;
+ while (*p) {
+ if (*p == '_') {
+ /* remove an underscore between digits */
+ if (n == buf || !ISDIGIT(prev) || (++p, !ISDIGIT(*p))) {
+ if (badcheck) goto bad;
+ break;
+ }
+ }
+ prev = *p++;
+ if (e == init_e && (prev == 'e' || prev == 'E' || prev == 'p' || prev == 'P')) {
+ e = buf + sizeof(buf) - 1;
+ *n++ = prev;
+ switch (*p) {case '+': case '-': prev = *n++ = *p++;}
+ if (*p == '0') {
+ prev = *n++ = '0';
+ while (*++p == '0');
+ }
+ continue;
+ }
+ else if (ISSPACE(prev)) {
+ while (ISSPACE(*p)) ++p;
+ if (*p) {
+ if (badcheck) goto bad;
+ break;
+ }
+ }
+ else if (prev == '.' ? dot_seen++ : !ISDIGIT(prev)) {
+ if (badcheck) goto bad;
+ break;
+ }
+ if (n < e) *n++ = prev;
+ }
+ *n = '\0';
+ p = buf;
+
+ if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+ return 0.0;
+ }
+
+ d = strtod(p, &end);
+ if (errno == ERANGE) {
+ OutOfRange();
+ rb_warning("Float %.*s%s out of range", w, p, ellipsis);
+ errno = 0;
+ }
+ if (badcheck) {
+ if (!end || p == end) goto bad;
+ while (*end && ISSPACE(*end)) end++;
+ if (*end) goto bad;
+ }
}
if (errno == ERANGE) {
- errno = 0;
- OutOfRange();
- rb_raise(rb_eArgError, "Float %.*s%s out of range", w, q, ellipsis);
+ errno = 0;
+ OutOfRange();
+ rb_raise(rb_eArgError, "Float %.*s%s out of range", w, q, ellipsis);
}
return d;
+
+ bad:
+ if (raise) {
+ rb_invalid_str(q, "Float()");
+ UNREACHABLE_RETURN(nan(""));
+ }
+ else {
+ if (error) *error = 1;
+ return 0.0;
+ }
}
/*!
* Parses a string representation of a floating point number.
*
- * \param[in] str a \c String object representation of a floating number
+ * \param[in] p a string representation of a floating number
* \param[in] badcheck raises an exception on parse error if \a badcheck is non-zero.
* \return the floating point number in the string on success,
* 0.0 on parse error and \a badcheck is zero.
@@ -3295,7 +3570,13 @@ rb_cstr_to_dbl(const char *p, int badcheck)
* This inconsistency is coming from a historical compatibility reason. [ruby-dev:40822]
*/
double
-rb_str_to_dbl(VALUE str, int badcheck)
+rb_cstr_to_dbl(const char *p, int badcheck)
+{
+ return rb_cstr_to_dbl_raise(p, badcheck, TRUE, NULL);
+}
+
+static double
+rb_str_to_dbl_raise(VALUE str, int badcheck, int raise, int *error)
{
char *s;
long len;
@@ -3307,7 +3588,12 @@ rb_str_to_dbl(VALUE str, int badcheck)
len = RSTRING_LEN(str);
if (s) {
if (badcheck && memchr(s, '\0', len)) {
- rb_raise(rb_eArgError, "string for Float contains null byte");
+ if (raise)
+ rb_raise(rb_eArgError, "string for Float contains null byte");
+ else {
+ if (error) *error = 1;
+ return 0.0;
+ }
}
if (s[len]) { /* no sentinel somehow */
char *p = ALLOCV(v, (size_t)len + 1);
@@ -3316,20 +3602,47 @@ rb_str_to_dbl(VALUE str, int badcheck)
s = p;
}
}
- ret = rb_cstr_to_dbl(s, badcheck);
+ ret = rb_cstr_to_dbl_raise(s, badcheck, raise, error);
if (v)
ALLOCV_END(v);
return ret;
}
+FUNC_MINIMIZED(double rb_str_to_dbl(VALUE str, int badcheck));
+
+/*!
+ * Parses a string representation of a floating point number.
+ *
+ * \param[in] str a \c String object representation of a floating number
+ * \param[in] badcheck raises an exception on parse error if \a badcheck is non-zero.
+ * \return the floating point number in the string on success,
+ * 0.0 on parse error and \a badcheck is zero.
+ * \note it always fails to parse a hexadecimal representation like "0xAB.CDp+1" when
+ * \a badcheck is zero, even though it would success if \a badcheck was non-zero.
+ * This inconsistency is coming from a historical compatibility reason. [ruby-dev:40822]
+ */
+double
+rb_str_to_dbl(VALUE str, int badcheck)
+{
+ return rb_str_to_dbl_raise(str, badcheck, TRUE, NULL);
+}
+
/*! \cond INTERNAL_MACRO */
#define fix2dbl_without_to_f(x) (double)FIX2LONG(x)
#define big2dbl_without_to_f(x) rb_big2dbl(x)
#define int2dbl_without_to_f(x) \
(FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x))
-#define rat2dbl_without_to_f(x) \
- (int2dbl_without_to_f(rb_rational_num(x)) / \
- int2dbl_without_to_f(rb_rational_den(x)))
+#define num2dbl_without_to_f(x) \
+ (FIXNUM_P(x) ? fix2dbl_without_to_f(x) : \
+ RB_TYPE_P(x, T_BIGNUM) ? big2dbl_without_to_f(x) : \
+ (Check_Type(x, T_FLOAT), RFLOAT_VALUE(x)))
+static inline double
+rat2dbl_without_to_f(VALUE x)
+{
+ VALUE num = rb_rational_num(x);
+ VALUE den = rb_rational_den(x);
+ return num2dbl_without_to_f(num) / num2dbl_without_to_f(den);
+}
#define special_const_to_float(val, pre, post) \
switch (val) { \
@@ -3355,7 +3668,7 @@ implicit_conversion_to_float(VALUE val)
}
static int
-to_float(VALUE *valp)
+to_float(VALUE *valp, int raise_exception)
{
VALUE val = *valp;
if (SPECIAL_CONST_P(val)) {
@@ -3366,7 +3679,7 @@ to_float(VALUE *valp)
else if (FLONUM_P(val)) {
return T_FLOAT;
}
- else {
+ else if (raise_exception) {
conversion_to_float(val);
}
}
@@ -3388,45 +3701,59 @@ to_float(VALUE *valp)
return T_NONE;
}
-/*!
- * Equivalent to \c Kernel\#Float in Ruby.
- *
- * Converts \a val into \c Float in a slightly more strict manner
- * than \c #to_f.
- */
-VALUE
-rb_Float(VALUE val)
+static VALUE
+convert_type_to_float_protected(VALUE val)
{
- switch (to_float(&val)) {
+ return rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
+}
+
+static VALUE
+rb_convert_to_float(VALUE val, int raise_exception)
+{
+ switch (to_float(&val, raise_exception)) {
case T_FLOAT:
return val;
case T_STRING:
- return DBL2NUM(rb_str_to_dbl(val, TRUE));
+ if (!raise_exception) {
+ int e = 0;
+ double x = rb_str_to_dbl_raise(val, TRUE, raise_exception, &e);
+ return e ? Qnil : DBL2NUM(x);
+ }
+ return DBL2NUM(rb_str_to_dbl(val, TRUE));
+ case T_NONE:
+ if (SPECIAL_CONST_P(val) && !raise_exception)
+ return Qnil;
}
- return rb_convert_type(val, T_FLOAT, "Float", "to_f");
+
+ if (!raise_exception) {
+ int state;
+ VALUE result = rb_protect(convert_type_to_float_protected, val, &state);
+ if (state) rb_set_errinfo(Qnil);
+ return result;
+ }
+
+ return rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
}
-FUNC_MINIMIZED(static VALUE rb_f_float(VALUE obj, VALUE arg)); /*!< \private */
+FUNC_MINIMIZED(VALUE rb_Float(VALUE val));
-/*
- * call-seq:
- * Float(arg) -> float
- *
- * Returns <i>arg</i> converted to a float. Numeric types are converted
- * directly, and with exception to string and nil the rest are converted using <i>arg</i>.to_f.
- * Converting a <code>string</code> with invalid characters will result in a <code>ArgumentError</code>.
- * Converting <code>nil</code> generates a <code>TypeError</code>.
+/*!
+ * Equivalent to \c Kernel\#Float in Ruby.
*
- * Float(1) #=> 1.0
- * Float("123.456") #=> 123.456
- * Float("123.0_badstring") #=> ArgumentError: invalid value for Float(): "123.0_badstring"
- * Float(nil) #=> TypeError: can't convert nil into Float
+ * Converts \a val into \c Float in a slightly more strict manner
+ * than \c #to_f.
*/
+VALUE
+rb_Float(VALUE val)
+{
+ return rb_convert_to_float(val, TRUE);
+}
static VALUE
-rb_f_float(VALUE obj, VALUE arg)
+rb_f_float(rb_execution_context_t *ec, VALUE obj, VALUE arg, VALUE opts)
{
- return rb_Float(arg);
+ int exception = rb_bool_expected(opts, "exception");
+ return rb_convert_to_float(arg, exception);
}
static VALUE
@@ -3436,7 +3763,7 @@ numeric_to_float(VALUE val)
rb_raise(rb_eTypeError, "can't convert %"PRIsVALUE" into Float",
rb_obj_class(val));
}
- return rb_convert_type(val, T_FLOAT, "Float", "to_f");
+ return rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
}
/*!
@@ -3447,7 +3774,7 @@ numeric_to_float(VALUE val)
VALUE
rb_to_float(VALUE val)
{
- switch (to_float(&val)) {
+ switch (to_float(&val, TRUE)) {
case T_FLOAT:
return val;
}
@@ -3468,11 +3795,9 @@ rb_check_to_float(VALUE val)
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
return Qnil;
}
- return rb_check_convert_type(val, T_FLOAT, "Float", "to_f");
+ return rb_check_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
}
-static ID id_to_f;
-
static inline int
basic_to_f_p(VALUE klass)
{
@@ -3507,6 +3832,8 @@ rb_num_to_dbl(VALUE val)
if (basic_to_f_p(rb_cRational))
return rat2dbl_without_to_f(val);
break;
+ default:
+ break;
}
}
val = numeric_to_float(val);
@@ -3544,9 +3871,11 @@ rb_num2dbl(VALUE val)
return rat2dbl_without_to_f(val);
case T_STRING:
rb_raise(rb_eTypeError, "no implicit conversion to float from string");
+ default:
+ break;
}
}
- val = rb_convert_type(val, T_FLOAT, "Float", "to_f");
+ val = rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
return RFLOAT_VALUE(val);
}
@@ -3570,7 +3899,7 @@ rb_String(VALUE val)
* call-seq:
* String(arg) -> string
*
- * Returns <i>arg</i> as a <code>String</code>.
+ * Returns <i>arg</i> as a String.
*
* First tries to call its <code>to_str</code> method, then its <code>to_s</code> method.
*
@@ -3594,7 +3923,7 @@ rb_Array(VALUE val)
VALUE tmp = rb_check_array_type(val);
if (NIL_P(tmp)) {
- tmp = rb_check_convert_type_with_id(val, T_ARRAY, "Array", idTo_a);
+ tmp = rb_check_to_array(val);
if (NIL_P(tmp)) {
return rb_ary_new3(1, val);
}
@@ -3609,8 +3938,17 @@ rb_Array(VALUE val)
* Returns +arg+ as an Array.
*
* First tries to call <code>to_ary</code> on +arg+, then <code>to_a</code>.
+ * If +arg+ does not respond to <code>to_ary</code> or <code>to_a</code>,
+ * returns an Array of length 1 containing +arg+.
+ *
+ * If <code>to_ary</code> or <code>to_a</code> returns something other than
+ * an Array, raises a TypeError.
*
- * Array(1..5) #=> [1, 2, 3, 4, 5]
+ * Array(["a", "b"]) #=> ["a", "b"]
+ * Array(1..5) #=> [1, 2, 3, 4, 5]
+ * Array(key: :value) #=> [[:key, :value]]
+ * Array(nil) #=> []
+ * Array(1) #=> [1]
*/
static VALUE
@@ -3641,8 +3979,8 @@ rb_Hash(VALUE val)
* call-seq:
* Hash(arg) -> hash
*
- * Converts <i>arg</i> to a <code>Hash</code> by calling
- * <i>arg</i><code>.to_hash</code>. Returns an empty <code>Hash</code> when
+ * Converts <i>arg</i> to a Hash by calling
+ * <i>arg</i><code>.to_hash</code>. Returns an empty Hash when
* <i>arg</i> is <tt>nil</tt> or <tt>[]</tt>.
*
* Hash([]) #=> {}
@@ -3713,19 +4051,289 @@ rb_obj_dig(int argc, VALUE *argv, VALUE obj, VALUE notfound)
continue;
}
break;
+ default:
+ break;
}
}
- return rb_check_funcall_with_hook(obj, id_dig, argc, argv,
- no_dig_method, obj);
+ return rb_check_funcall_with_hook_kw(obj, id_dig, argc, argv,
+ no_dig_method, obj,
+ RB_NO_KEYWORDS);
}
return obj;
}
/*
+ * call-seq:
+ * format(format_string [, arguments...] ) -> string
+ * sprintf(format_string [, arguments...] ) -> string
+ *
+ * Returns the string resulting from applying <i>format_string</i> to
+ * any additional arguments. Within the format string, any characters
+ * other than format sequences are copied to the result.
+ *
+ * The syntax of a format sequence is as follows.
+ *
+ * %[flags][width][.precision]type
+ *
+ * A format
+ * sequence consists of a percent sign, followed by optional flags,
+ * width, and precision indicators, then terminated with a field type
+ * character. The field type controls how the corresponding
+ * <code>sprintf</code> argument is to be interpreted, while the flags
+ * modify that interpretation.
+ *
+ * The field type characters are:
+ *
+ * Field | Integer Format
+ * ------+--------------------------------------------------------------
+ * b | Convert argument as a binary number.
+ * | Negative numbers will be displayed as a two's complement
+ * | prefixed with `..1'.
+ * B | Equivalent to `b', but uses an uppercase 0B for prefix
+ * | in the alternative format by #.
+ * d | Convert argument as a decimal number.
+ * i | Identical to `d'.
+ * o | Convert argument as an octal number.
+ * | Negative numbers will be displayed as a two's complement
+ * | prefixed with `..7'.
+ * u | Identical to `d'.
+ * x | Convert argument as a hexadecimal number.
+ * | Negative numbers will be displayed as a two's complement
+ * | prefixed with `..f' (representing an infinite string of
+ * | leading 'ff's).
+ * X | Equivalent to `x', but uses uppercase letters.
+ *
+ * Field | Float Format
+ * ------+--------------------------------------------------------------
+ * e | Convert floating point argument into exponential notation
+ * | with one digit before the decimal point as [-]d.dddddde[+-]dd.
+ * | The precision specifies the number of digits after the decimal
+ * | point (defaulting to six).
+ * E | Equivalent to `e', but uses an uppercase E to indicate
+ * | the exponent.
+ * f | Convert floating point argument as [-]ddd.dddddd,
+ * | where the precision specifies the number of digits after
+ * | the decimal point.
+ * g | Convert a floating point number using exponential form
+ * | if the exponent is less than -4 or greater than or
+ * | equal to the precision, or in dd.dddd form otherwise.
+ * | The precision specifies the number of significant digits.
+ * G | Equivalent to `g', but use an uppercase `E' in exponent form.
+ * a | Convert floating point argument as [-]0xh.hhhhp[+-]dd,
+ * | which is consisted from optional sign, "0x", fraction part
+ * | as hexadecimal, "p", and exponential part as decimal.
+ * A | Equivalent to `a', but use uppercase `X' and `P'.
+ *
+ * Field | Other Format
+ * ------+--------------------------------------------------------------
+ * c | Argument is the numeric code for a single character or
+ * | a single character string itself.
+ * p | The valuing of argument.inspect.
+ * s | Argument is a string to be substituted. If the format
+ * | sequence contains a precision, at most that many characters
+ * | will be copied.
+ * % | A percent sign itself will be displayed. No argument taken.
+ *
+ * The flags modifies the behavior of the formats.
+ * The flag characters are:
+ *
+ * Flag | Applies to | Meaning
+ * ---------+---------------+-----------------------------------------
+ * space | bBdiouxX | Leave a space at the start of
+ * | aAeEfgG | non-negative numbers.
+ * | (numeric fmt) | For `o', `x', `X', `b' and `B', use
+ * | | a minus sign with absolute value for
+ * | | negative values.
+ * ---------+---------------+-----------------------------------------
+ * (digit)$ | all | Specifies the absolute argument number
+ * | | for this field. Absolute and relative
+ * | | argument numbers cannot be mixed in a
+ * | | sprintf string.
+ * ---------+---------------+-----------------------------------------
+ * # | bBoxX | Use an alternative format.
+ * | aAeEfgG | For the conversions `o', increase the precision
+ * | | until the first digit will be `0' if
+ * | | it is not formatted as complements.
+ * | | For the conversions `x', `X', `b' and `B'
+ * | | on non-zero, prefix the result with ``0x'',
+ * | | ``0X'', ``0b'' and ``0B'', respectively.
+ * | | For `a', `A', `e', `E', `f', `g', and 'G',
+ * | | force a decimal point to be added,
+ * | | even if no digits follow.
+ * | | For `g' and 'G', do not remove trailing zeros.
+ * ---------+---------------+-----------------------------------------
+ * + | bBdiouxX | Add a leading plus sign to non-negative
+ * | aAeEfgG | numbers.
+ * | (numeric fmt) | For `o', `x', `X', `b' and `B', use
+ * | | a minus sign with absolute value for
+ * | | negative values.
+ * ---------+---------------+-----------------------------------------
+ * - | all | Left-justify the result of this conversion.
+ * ---------+---------------+-----------------------------------------
+ * 0 (zero) | bBdiouxX | Pad with zeros, not spaces.
+ * | aAeEfgG | For `o', `x', `X', `b' and `B', radix-1
+ * | (numeric fmt) | is used for negative numbers formatted as
+ * | | complements.
+ * ---------+---------------+-----------------------------------------
+ * * | all | Use the next argument as the field width.
+ * | | If negative, left-justify the result. If the
+ * | | asterisk is followed by a number and a dollar
+ * | | sign, use the indicated argument as the width.
+ *
+ * Examples of flags:
+ *
+ * # `+' and space flag specifies the sign of non-negative numbers.
+ * sprintf("%d", 123) #=> "123"
+ * sprintf("%+d", 123) #=> "+123"
+ * sprintf("% d", 123) #=> " 123"
+ *
+ * # `#' flag for `o' increases number of digits to show `0'.
+ * # `+' and space flag changes format of negative numbers.
+ * sprintf("%o", 123) #=> "173"
+ * sprintf("%#o", 123) #=> "0173"
+ * sprintf("%+o", -123) #=> "-173"
+ * sprintf("%o", -123) #=> "..7605"
+ * sprintf("%#o", -123) #=> "..7605"
+ *
+ * # `#' flag for `x' add a prefix `0x' for non-zero numbers.
+ * # `+' and space flag disables complements for negative numbers.
+ * sprintf("%x", 123) #=> "7b"
+ * sprintf("%#x", 123) #=> "0x7b"
+ * sprintf("%+x", -123) #=> "-7b"
+ * sprintf("%x", -123) #=> "..f85"
+ * sprintf("%#x", -123) #=> "0x..f85"
+ * sprintf("%#x", 0) #=> "0"
+ *
+ * # `#' for `X' uses the prefix `0X'.
+ * sprintf("%X", 123) #=> "7B"
+ * sprintf("%#X", 123) #=> "0X7B"
+ *
+ * # `#' flag for `b' add a prefix `0b' for non-zero numbers.
+ * # `+' and space flag disables complements for negative numbers.
+ * sprintf("%b", 123) #=> "1111011"
+ * sprintf("%#b", 123) #=> "0b1111011"
+ * sprintf("%+b", -123) #=> "-1111011"
+ * sprintf("%b", -123) #=> "..10000101"
+ * sprintf("%#b", -123) #=> "0b..10000101"
+ * sprintf("%#b", 0) #=> "0"
+ *
+ * # `#' for `B' uses the prefix `0B'.
+ * sprintf("%B", 123) #=> "1111011"
+ * sprintf("%#B", 123) #=> "0B1111011"
+ *
+ * # `#' for `e' forces to show the decimal point.
+ * sprintf("%.0e", 1) #=> "1e+00"
+ * sprintf("%#.0e", 1) #=> "1.e+00"
+ *
+ * # `#' for `f' forces to show the decimal point.
+ * sprintf("%.0f", 1234) #=> "1234"
+ * sprintf("%#.0f", 1234) #=> "1234."
+ *
+ * # `#' for `g' forces to show the decimal point.
+ * # It also disables stripping lowest zeros.
+ * sprintf("%g", 123.4) #=> "123.4"
+ * sprintf("%#g", 123.4) #=> "123.400"
+ * sprintf("%g", 123456) #=> "123456"
+ * sprintf("%#g", 123456) #=> "123456."
+ *
+ * The field width is an optional integer, followed optionally by a
+ * period and a precision. The width specifies the minimum number of
+ * characters that will be written to the result for this field.
+ *
+ * Examples of width:
+ *
+ * # padding is done by spaces, width=20
+ * # 0 or radix-1. <------------------>
+ * sprintf("%20d", 123) #=> " 123"
+ * sprintf("%+20d", 123) #=> " +123"
+ * sprintf("%020d", 123) #=> "00000000000000000123"
+ * sprintf("%+020d", 123) #=> "+0000000000000000123"
+ * sprintf("% 020d", 123) #=> " 0000000000000000123"
+ * sprintf("%-20d", 123) #=> "123 "
+ * sprintf("%-+20d", 123) #=> "+123 "
+ * sprintf("%- 20d", 123) #=> " 123 "
+ * sprintf("%020x", -123) #=> "..ffffffffffffffff85"
+ *
+ * For
+ * numeric fields, the precision controls the number of decimal places
+ * displayed. For string fields, the precision determines the maximum
+ * number of characters to be copied from the string. (Thus, the format
+ * sequence <code>%10.10s</code> will always contribute exactly ten
+ * characters to the result.)
+ *
+ * Examples of precisions:
+ *
+ * # precision for `d', 'o', 'x' and 'b' is
+ * # minimum number of digits <------>
+ * sprintf("%20.8d", 123) #=> " 00000123"
+ * sprintf("%20.8o", 123) #=> " 00000173"
+ * sprintf("%20.8x", 123) #=> " 0000007b"
+ * sprintf("%20.8b", 123) #=> " 01111011"
+ * sprintf("%20.8d", -123) #=> " -00000123"
+ * sprintf("%20.8o", -123) #=> " ..777605"
+ * sprintf("%20.8x", -123) #=> " ..ffff85"
+ * sprintf("%20.8b", -11) #=> " ..110101"
+ *
+ * # "0x" and "0b" for `#x' and `#b' is not counted for
+ * # precision but "0" for `#o' is counted. <------>
+ * sprintf("%#20.8d", 123) #=> " 00000123"
+ * sprintf("%#20.8o", 123) #=> " 00000173"
+ * sprintf("%#20.8x", 123) #=> " 0x0000007b"
+ * sprintf("%#20.8b", 123) #=> " 0b01111011"
+ * sprintf("%#20.8d", -123) #=> " -00000123"
+ * sprintf("%#20.8o", -123) #=> " ..777605"
+ * sprintf("%#20.8x", -123) #=> " 0x..ffff85"
+ * sprintf("%#20.8b", -11) #=> " 0b..110101"
+ *
+ * # precision for `e' is number of
+ * # digits after the decimal point <------>
+ * sprintf("%20.8e", 1234.56789) #=> " 1.23456789e+03"
+ *
+ * # precision for `f' is number of
+ * # digits after the decimal point <------>
+ * sprintf("%20.8f", 1234.56789) #=> " 1234.56789000"
+ *
+ * # precision for `g' is number of
+ * # significant digits <------->
+ * sprintf("%20.8g", 1234.56789) #=> " 1234.5679"
+ *
+ * # <------->
+ * sprintf("%20.8g", 123456789) #=> " 1.2345679e+08"
+ *
+ * # precision for `s' is
+ * # maximum number of characters <------>
+ * sprintf("%20.8s", "string test") #=> " string t"
+ *
+ * Examples:
+ *
+ * sprintf("%d %04x", 123, 123) #=> "123 007b"
+ * sprintf("%08b '%4s'", 123, 123) #=> "01111011 ' 123'"
+ * sprintf("%1$*2$s %2$d %1$s", "hello", 8) #=> " hello 8 hello"
+ * sprintf("%1$*2$s %2$d", "hello", -8) #=> "hello -8"
+ * sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23) #=> "+1.23: 1.23:1.23"
+ * sprintf("%u", -123) #=> "-123"
+ *
+ * For more complex formatting, Ruby supports a reference by name.
+ * %<name>s style uses format style, but %{name} style doesn't.
+ *
+ * Examples:
+ * sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 })
+ * #=> 1 : 2.000000
+ * sprintf("%{foo}f", { :foo => 1 })
+ * # => "1f"
+ */
+
+static VALUE
+f_sprintf(int c, const VALUE *v, VALUE _)
+{
+ return rb_f_sprintf(c, v);
+}
+
+/*
* Document-class: Class
*
* Classes in Ruby are first-class objects---each is an instance of
- * class <code>Class</code>.
+ * class Class.
*
* Typically, you create a new class by using:
*
@@ -3734,12 +4342,11 @@ rb_obj_dig(int argc, VALUE *argv, VALUE obj, VALUE notfound)
* end
*
* When a new class is created, an object of type Class is initialized and
- * assigned to a global constant (<code>Name</code> in this case).
+ * assigned to a global constant (Name in this case).
*
* When <code>Name.new</code> is called to create a new object, the
- * <code>new</code> method in <code>Class</code> is run by default.
- * This can be demonstrated by overriding <code>new</code> in
- * <code>Class</code>:
+ * #new method in Class is run by default.
+ * This can be demonstrated by overriding #new in Class:
*
* class Class
* alias old_new new
@@ -3815,7 +4422,7 @@ rb_obj_dig(int argc, VALUE *argv, VALUE obj, VALUE notfound)
* DELEGATE = [:puts, :p]
*
* def method_missing(name, *args, &block)
- * super unless DELEGATE.include? name
+ * return super unless DELEGATE.include? name
* ::Kernel.send(name, *args, &block)
* end
*
@@ -3890,19 +4497,16 @@ InitVM_Object(void)
rb_cClass = rb_define_class("Class", rb_cModule);
#endif
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
- rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy, 0);
+ rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy0, 0);
rb_define_alloc_func(rb_cBasicObject, rb_class_allocate_instance);
rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1);
rb_define_method(rb_cBasicObject, "equal?", rb_obj_equal, 1);
rb_define_method(rb_cBasicObject, "!", rb_obj_not, 0);
rb_define_method(rb_cBasicObject, "!=", rb_obj_not_equal, 1);
- rb_define_private_method(rb_cBasicObject, "singleton_method_added", rb_obj_dummy, 1);
- rb_define_private_method(rb_cBasicObject, "singleton_method_removed", rb_obj_dummy, 1);
- rb_define_private_method(rb_cBasicObject, "singleton_method_undefined", rb_obj_dummy, 1);
+ rb_define_private_method(rb_cBasicObject, "singleton_method_added", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cBasicObject, "singleton_method_removed", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cBasicObject, "singleton_method_undefined", rb_obj_dummy1, 1);
/* Document-module: Kernel
*
@@ -3918,31 +4522,28 @@ InitVM_Object(void)
*/
rb_mKernel = rb_define_module("Kernel");
rb_include_module(rb_cObject, rb_mKernel);
- rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1);
- rb_define_private_method(rb_cModule, "included", rb_obj_dummy, 1);
- rb_define_private_method(rb_cModule, "extended", rb_obj_dummy, 1);
- rb_define_private_method(rb_cModule, "prepended", rb_obj_dummy, 1);
- rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy, 1);
- rb_define_private_method(rb_cModule, "method_removed", rb_obj_dummy, 1);
- rb_define_private_method(rb_cModule, "method_undefined", rb_obj_dummy, 1);
+ rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cModule, "included", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cModule, "extended", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cModule, "prepended", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cModule, "method_removed", rb_obj_dummy1, 1);
+ rb_define_private_method(rb_cModule, "method_undefined", rb_obj_dummy1, 1);
rb_define_method(rb_mKernel, "nil?", rb_false, 0);
- rb_define_method(rb_mKernel, "===", rb_equal, 1);
+ rb_define_method(rb_mKernel, "===", case_equal, 1);
rb_define_method(rb_mKernel, "=~", rb_obj_match, 1);
rb_define_method(rb_mKernel, "!~", rb_obj_not_match, 1);
rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);
- rb_define_method(rb_mKernel, "hash", rb_obj_hash, 0);
+ rb_define_method(rb_mKernel, "hash", rb_obj_hash, 0); /* in hash.c */
rb_define_method(rb_mKernel, "<=>", rb_obj_cmp, 1);
- rb_define_method(rb_mKernel, "class", rb_obj_class, 0);
rb_define_method(rb_mKernel, "singleton_class", rb_obj_singleton_class, 0);
- rb_define_method(rb_mKernel, "clone", rb_obj_clone2, -1);
rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0);
rb_define_method(rb_mKernel, "itself", rb_obj_itself, 0);
- rb_define_method(rb_mKernel, "yield_self", rb_obj_yield_self, 0);
rb_define_method(rb_mKernel, "initialize_copy", rb_obj_init_copy, 1);
rb_define_method(rb_mKernel, "initialize_dup", rb_obj_init_dup_clone, 1);
- rb_define_method(rb_mKernel, "initialize_clone", rb_obj_init_dup_clone, 1);
+ rb_define_method(rb_mKernel, "initialize_clone", rb_obj_init_clone, -1);
rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0);
rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0);
@@ -3951,7 +4552,6 @@ InitVM_Object(void)
rb_define_method(rb_mKernel, "untrusted?", rb_obj_untrusted, 0);
rb_define_method(rb_mKernel, "trust", rb_obj_trust, 0);
rb_define_method(rb_mKernel, "freeze", rb_obj_freeze, 0);
- rb_define_method(rb_mKernel, "frozen?", rb_obj_frozen_p, 0);
rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0);
rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0);
@@ -3970,38 +4570,34 @@ InitVM_Object(void)
rb_define_method(rb_mKernel, "instance_of?", rb_obj_is_instance_of, 1);
rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1);
rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1);
- rb_define_method(rb_mKernel, "tap", rb_obj_tap, 0);
- rb_define_global_function("sprintf", rb_f_sprintf, -1); /* in sprintf.c */
- rb_define_global_function("format", rb_f_sprintf, -1); /* in sprintf.c */
+ rb_define_global_function("sprintf", f_sprintf, -1);
+ rb_define_global_function("format", f_sprintf, -1);
rb_define_global_function("Integer", rb_f_integer, -1);
- rb_define_global_function("Float", rb_f_float, 1);
rb_define_global_function("String", rb_f_string, 1);
rb_define_global_function("Array", rb_f_array, 1);
rb_define_global_function("Hash", rb_f_hash, 1);
rb_cNilClass = rb_define_class("NilClass", rb_cObject);
+ rb_cNilClass_to_s = rb_fstring_enc_lit("", rb_usascii_encoding());
+ rb_gc_register_mark_object(rb_cNilClass_to_s);
rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0);
rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0);
rb_define_method(rb_cNilClass, "to_h", nil_to_h, 0);
rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0);
+ rb_define_method(rb_cNilClass, "=~", nil_match, 1);
rb_define_method(rb_cNilClass, "&", false_and, 1);
rb_define_method(rb_cNilClass, "|", false_or, 1);
rb_define_method(rb_cNilClass, "^", false_xor, 1);
- rb_define_method(rb_cNilClass, "===", rb_equal, 1);
+ rb_define_method(rb_cNilClass, "===", case_equal, 1);
rb_define_method(rb_cNilClass, "nil?", rb_true, 0);
rb_undef_alloc_func(rb_cNilClass);
rb_undef_method(CLASS_OF(rb_cNilClass), "new");
- /*
- * An obsolete alias of +nil+
- */
- rb_define_global_const("NIL", Qnil);
- rb_deprecate_constant(rb_cObject, "NIL");
rb_define_method(rb_cModule, "freeze", rb_mod_freeze, 0);
rb_define_method(rb_cModule, "===", rb_mod_eqq, 1);
@@ -4019,14 +4615,14 @@ InitVM_Object(void)
rb_define_method(rb_cModule, "name", rb_mod_name, 0); /* in variable.c */
rb_define_method(rb_cModule, "ancestors", rb_mod_ancestors, 0); /* in class.c */
- rb_define_private_method(rb_cModule, "attr", rb_mod_attr, -1);
- rb_define_private_method(rb_cModule, "attr_reader", rb_mod_attr_reader, -1);
- rb_define_private_method(rb_cModule, "attr_writer", rb_mod_attr_writer, -1);
- rb_define_private_method(rb_cModule, "attr_accessor", rb_mod_attr_accessor, -1);
+ rb_define_method(rb_cModule, "attr", rb_mod_attr, -1);
+ rb_define_method(rb_cModule, "attr_reader", rb_mod_attr_reader, -1);
+ rb_define_method(rb_cModule, "attr_writer", rb_mod_attr_writer, -1);
+ rb_define_method(rb_cModule, "attr_accessor", rb_mod_attr_accessor, -1);
rb_define_alloc_func(rb_cModule, rb_module_s_alloc);
rb_define_method(rb_cModule, "initialize", rb_mod_initialize, 0);
- rb_define_method(rb_cModule, "initialize_clone", rb_mod_initialize_clone, 1);
+ rb_define_method(rb_cModule, "initialize_clone", rb_mod_initialize_clone, -1);
rb_define_method(rb_cModule, "instance_methods", rb_class_instance_methods, -1); /* in class.c */
rb_define_method(rb_cModule, "public_instance_methods",
rb_class_public_instance_methods, -1); /* in class.c */
@@ -4039,6 +4635,7 @@ InitVM_Object(void)
rb_define_method(rb_cModule, "const_get", rb_mod_const_get, -1);
rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2);
rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, -1);
+ rb_define_method(rb_cModule, "const_source_location", rb_mod_const_source_location, -1);
rb_define_private_method(rb_cModule, "remove_const",
rb_mod_remove_const, 1); /* in variable.c */
rb_define_method(rb_cModule, "const_missing",
@@ -4055,8 +4652,8 @@ InitVM_Object(void)
rb_define_method(rb_cModule, "deprecate_constant", rb_mod_deprecate_constant, -1); /* in variable.c */
rb_define_method(rb_cModule, "singleton_class?", rb_mod_singleton_p, 0);
- rb_define_method(rb_cClass, "allocate", rb_class_alloc, 0);
- rb_define_method(rb_cClass, "new", rb_class_s_new, -1);
+ rb_define_method(rb_cClass, "allocate", rb_class_alloc_m, 0);
+ rb_define_method(rb_cClass, "new", rb_class_new_instance_pass_kw, -1);
rb_define_method(rb_cClass, "initialize", rb_class_initialize, -1);
rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0);
rb_define_alloc_func(rb_cClass, rb_class_s_alloc);
@@ -4064,50 +4661,36 @@ InitVM_Object(void)
rb_undef_method(rb_cClass, "append_features");
rb_undef_method(rb_cClass, "prepend_features");
- /*
- * Document-class: Data
- *
- * This is a recommended base class for C extensions using Data_Make_Struct
- * or Data_Wrap_Struct, see doc/extension.rdoc for details.
- */
- rb_cData = rb_define_class("Data", rb_cObject);
- rb_undef_alloc_func(rb_cData);
-
rb_cTrueClass = rb_define_class("TrueClass", rb_cObject);
+ rb_cTrueClass_to_s = rb_fstring_enc_lit("true", rb_usascii_encoding());
+ rb_gc_register_mark_object(rb_cTrueClass_to_s);
rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0);
rb_define_alias(rb_cTrueClass, "inspect", "to_s");
rb_define_method(rb_cTrueClass, "&", true_and, 1);
rb_define_method(rb_cTrueClass, "|", true_or, 1);
rb_define_method(rb_cTrueClass, "^", true_xor, 1);
- rb_define_method(rb_cTrueClass, "===", rb_equal, 1);
+ rb_define_method(rb_cTrueClass, "===", case_equal, 1);
rb_undef_alloc_func(rb_cTrueClass);
rb_undef_method(CLASS_OF(rb_cTrueClass), "new");
- /*
- * An obsolete alias of +true+
- */
- rb_define_global_const("TRUE", Qtrue);
- rb_deprecate_constant(rb_cObject, "TRUE");
rb_cFalseClass = rb_define_class("FalseClass", rb_cObject);
+ rb_cFalseClass_to_s = rb_fstring_enc_lit("false", rb_usascii_encoding());
+ rb_gc_register_mark_object(rb_cFalseClass_to_s);
rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0);
rb_define_alias(rb_cFalseClass, "inspect", "to_s");
rb_define_method(rb_cFalseClass, "&", false_and, 1);
rb_define_method(rb_cFalseClass, "|", false_or, 1);
rb_define_method(rb_cFalseClass, "^", false_xor, 1);
- rb_define_method(rb_cFalseClass, "===", rb_equal, 1);
+ rb_define_method(rb_cFalseClass, "===", case_equal, 1);
rb_undef_alloc_func(rb_cFalseClass);
rb_undef_method(CLASS_OF(rb_cFalseClass), "new");
- /*
- * An obsolete alias of +false+
- */
- rb_define_global_const("FALSE", Qfalse);
- rb_deprecate_constant(rb_cObject, "FALSE");
}
+#include "kernel.rbinc"
+
void
Init_Object(void)
{
- id_to_f = rb_intern_const("to_f");
id_dig = rb_intern_const("dig");
InitVM(Object);
}
diff --git a/pack.c b/pack.c
index 327c478af8..9fecc31a34 100644
--- a/pack.c
+++ b/pack.c
@@ -9,10 +9,22 @@
**********************************************************************/
-#include "internal.h"
-#include <sys/types.h>
+#include "ruby/internal/config.h"
+
#include <ctype.h>
#include <errno.h>
+#include <float.h>
+#include <sys/types.h>
+
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/bits.h"
+#include "internal/string.h"
+#include "internal/symbol.h"
+#include "internal/util.h"
+#include "internal/variable.h"
+
+#include "builtin.h"
/*
* It is intentional that the condition for natstr is HAVE_TRUE_LONG_LONG
@@ -41,20 +53,20 @@ static const char endstr[] = "sSiIlLqQjJ";
#endif
#ifdef DYNAMIC_ENDIAN
- /* for universal binary of NEXTSTEP and MacOS X */
- /* useless since autoconf 2.63? */
- static int
- is_bigendian(void)
- {
- static int init = 0;
- static int endian_value;
- char *p;
-
- if (init) return endian_value;
- init = 1;
- p = (char*)&init;
- return endian_value = p[0]?0:1;
- }
+/* for universal binary of NEXTSTEP and MacOS X */
+/* useless since autoconf 2.63? */
+static int
+is_bigendian(void)
+{
+ static int init = 0;
+ static int endian_value;
+ char *p;
+
+ if (init) return endian_value;
+ init = 1;
+ p = (char*)&init;
+ return endian_value = p[0]?0:1;
+}
# define BIGENDIAN_P() (is_bigendian())
#elif defined(WORDS_BIGENDIAN)
# define BIGENDIAN_P() 1
@@ -126,142 +138,54 @@ str_associated(VALUE str)
return rb_ivar_lookup(str, id_associated, Qfalse);
}
-/*
- * call-seq:
- * arr.pack( aTemplateString ) -> aBinaryString
- * arr.pack( aTemplateString, buffer: aBufferString ) -> aBufferString
- *
- * Packs the contents of <i>arr</i> into a binary sequence according to
- * the directives in <i>aTemplateString</i> (see the table below)
- * Directives ``A,'' ``a,'' and ``Z'' may be followed by a count,
- * which gives the width of the resulting field. The remaining
- * directives also may take a count, indicating the number of array
- * elements to convert. If the count is an asterisk
- * (``<code>*</code>''), all remaining array elements will be
- * converted. Any of the directives ``<code>sSiIlL</code>'' may be
- * followed by an underscore (``<code>_</code>'') or
- * exclamation mark (``<code>!</code>'') to use the underlying
- * platform's native size for the specified type; otherwise, they use a
- * platform-independent size. Spaces are ignored in the template
- * string. See also <code>String#unpack</code>.
- *
- * a = [ "a", "b", "c" ]
- * n = [ 65, 66, 67 ]
- * a.pack("A3A3A3") #=> "a b c "
- * a.pack("a3a3a3") #=> "a\000\000b\000\000c\000\000"
- * n.pack("ccc") #=> "ABC"
- *
- * If <i>aBufferString</i> is specified and its capacity is enough,
- * +pack+ uses it as the buffer and returns it.
- * When the offset is specified by the beginning of <i>aTemplateString</i>,
- * the result is filled after the offset.
- * If original contents of <i>aBufferString</i> exists and it's longer than
- * the offset, the rest of <i>offsetOfBuffer</i> are overwritten by the result.
- * If it's shorter, the gap is filled with ``<code>\0</code>''.
- *
- * Note that ``buffer:'' option does not guarantee not to allocate memory
- * in +pack+. If the capacity of <i>aBufferString</i> is not enough,
- * +pack+ allocates memory.
- *
- * Directives for +pack+.
- *
- * Integer | Array |
- * Directive | Element | Meaning
- * ----------------------------------------------------------------------------
- * C | Integer | 8-bit unsigned (unsigned char)
- * S | Integer | 16-bit unsigned, native endian (uint16_t)
- * L | Integer | 32-bit unsigned, native endian (uint32_t)
- * Q | Integer | 64-bit unsigned, native endian (uint64_t)
- * J | Integer | pointer width unsigned, native endian (uintptr_t)
- * | | (J is available since Ruby 2.3.)
- * | |
- * c | Integer | 8-bit signed (signed char)
- * s | Integer | 16-bit signed, native endian (int16_t)
- * l | Integer | 32-bit signed, native endian (int32_t)
- * q | Integer | 64-bit signed, native endian (int64_t)
- * j | Integer | pointer width signed, native endian (intptr_t)
- * | | (j is available since Ruby 2.3.)
- * | |
- * S_ S! | Integer | unsigned short, native endian
- * I I_ I! | Integer | unsigned int, native endian
- * L_ L! | Integer | unsigned long, native endian
- * Q_ Q! | Integer | unsigned long long, native endian (ArgumentError
- * | | if the platform has no long long type.)
- * | | (Q_ and Q! is available since Ruby 2.1.)
- * J! | Integer | uintptr_t, native endian (same with J)
- * | | (J! is available since Ruby 2.3.)
- * | |
- * s_ s! | Integer | signed short, native endian
- * i i_ i! | Integer | signed int, native endian
- * l_ l! | Integer | signed long, native endian
- * q_ q! | Integer | signed long long, native endian (ArgumentError
- * | | if the platform has no long long type.)
- * | | (q_ and q! is available since Ruby 2.1.)
- * j! | Integer | intptr_t, native endian (same with j)
- * | | (j! is available since Ruby 2.3.)
- * | |
- * S> s> S!> s!> | Integer | same as the directives without ">" except
- * L> l> L!> l!> | | big endian
- * I!> i!> | | (available since Ruby 1.9.3)
- * Q> q> Q!> q!> | | "S>" is same as "n"
- * J> j> J!> j!> | | "L>" is same as "N"
- * | |
- * S< s< S!< s!< | Integer | same as the directives without "<" except
- * L< l< L!< l!< | | little endian
- * I!< i!< | | (available since Ruby 1.9.3)
- * Q< q< Q!< q!< | | "S<" is same as "v"
- * J< j< J!< j!< | | "L<" is same as "V"
- * | |
- * n | Integer | 16-bit unsigned, network (big-endian) byte order
- * N | Integer | 32-bit unsigned, network (big-endian) byte order
- * v | Integer | 16-bit unsigned, VAX (little-endian) byte order
- * V | Integer | 32-bit unsigned, VAX (little-endian) byte order
- * | |
- * U | Integer | UTF-8 character
- * w | Integer | BER-compressed integer
- *
- * Float | Array |
- * Directive | Element | Meaning
- * ---------------------------------------------------------------------------
- * D d | Float | double-precision, native format
- * F f | Float | single-precision, native format
- * E | Float | double-precision, little-endian byte order
- * e | Float | single-precision, little-endian byte order
- * G | Float | double-precision, network (big-endian) byte order
- * g | Float | single-precision, network (big-endian) byte order
- *
- * String | Array |
- * Directive | Element | Meaning
- * ---------------------------------------------------------------------------
- * A | String | arbitrary binary string (space padded, count is width)
- * a | String | arbitrary binary string (null padded, count is width)
- * Z | String | same as ``a'', except that null is added with *
- * B | String | bit string (MSB first)
- * b | String | bit string (LSB first)
- * H | String | hex string (high nibble first)
- * h | String | hex string (low nibble first)
- * u | String | UU-encoded string
- * M | String | quoted printable, MIME encoding (see RFC2045)
- * m | String | base64 encoded string (see RFC 2045, count is width)
- * | | (if count is 0, no line feed are added, see RFC 4648)
- * P | String | pointer to a structure (fixed-length string)
- * p | String | pointer to a null-terminated string
- *
- * Misc. | Array |
- * Directive | Element | Meaning
- * ---------------------------------------------------------------------------
- * @ | --- | moves to absolute position
- * X | --- | back up a byte
- * x | --- | null byte
- */
+static void
+unknown_directive(const char *mode, char type, VALUE fmt)
+{
+ VALUE f;
+ char unknown[5];
+
+ if (ISPRINT(type)) {
+ unknown[0] = type;
+ unknown[1] = '\0';
+ }
+ else {
+ snprintf(unknown, sizeof(unknown), "\\x%.2x", type & 0xff);
+ }
+ f = rb_str_quote_unprintable(fmt);
+ if (f != fmt) {
+ fmt = rb_str_subseq(f, 1, RSTRING_LEN(f) - 2);
+ }
+ rb_warning("unknown %s directive '%s' in '%"PRIsVALUE"'",
+ mode, unknown, fmt);
+}
+
+static float
+VALUE_to_float(VALUE obj)
+{
+ VALUE v = rb_to_float(obj);
+ double d = RFLOAT_VALUE(v);
+
+ if (isnan(d)) {
+ return NAN;
+ }
+ else if (d < -FLT_MAX) {
+ return -INFINITY;
+ }
+ else if (d <= FLT_MAX) {
+ return d;
+ }
+ else {
+ return INFINITY;
+ }
+}
static VALUE
-pack_pack(int argc, VALUE *argv, VALUE ary)
+pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
{
static const char nul10[] = "\0\0\0\0\0\0\0\0\0\0";
static const char spc10[] = " ";
const char *p, *pend;
- VALUE fmt, opt = Qnil, res, from, associates = 0, buffer = 0;
+ VALUE res, from, associates = 0;
char type;
long len, idx, plen;
const char *ptr;
@@ -271,25 +195,18 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
#endif
int integer_size, bigendian_p;
- rb_scan_args(argc, argv, "10:", &fmt, &opt);
-
StringValue(fmt);
p = RSTRING_PTR(fmt);
pend = p + RSTRING_LEN(fmt);
- if (!NIL_P(opt)) {
- static ID keyword_ids[1];
- if (!keyword_ids[0])
- CONST_ID(keyword_ids[0], "buffer");
-
- rb_get_kwargs(opt, keyword_ids, 0, 1, &buffer);
- if (buffer != Qundef && !RB_TYPE_P(buffer, T_STRING))
- rb_raise(rb_eTypeError, "buffer must be String, not %s", rb_obj_classname(buffer));
+ if (NIL_P(buffer)) {
+ res = rb_str_buf_new(0);
}
- if (buffer)
+ else {
+ if (!RB_TYPE_P(buffer, T_STRING))
+ rb_raise(rb_eTypeError, "buffer must be String, not %s", rb_obj_classname(buffer));
res = buffer;
- else
- res = rb_str_buf_new(0);
+ }
idx = 0;
@@ -388,7 +305,6 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
StringValue(from);
ptr = RSTRING_PTR(from);
plen = RSTRING_LEN(from);
- OBJ_INFECT(res, from);
}
if (p[-1] == '*')
@@ -640,7 +556,7 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
float f;
from = NEXTFROM;
- f = (float)RFLOAT_VALUE(rb_to_float(from));
+ f = VALUE_to_float(from);
rb_str_buf_cat(res, (char*)&f, sizeof(float));
}
break;
@@ -650,7 +566,7 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
FLOAT_CONVWITH(tmp);
from = NEXTFROM;
- tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
+ tmp.f = VALUE_to_float(from);
HTOVF(tmp);
rb_str_buf_cat(res, tmp.buf, sizeof(float));
}
@@ -681,7 +597,7 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
while (len-- > 0) {
FLOAT_CONVWITH(tmp);
from = NEXTFROM;
- tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
+ tmp.f = VALUE_to_float(from);
HTONF(tmp);
rb_str_buf_cat(res, tmp.buf, sizeof(float));
}
@@ -801,7 +717,6 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
}
else {
t = StringValuePtr(from);
- rb_obj_taint(from);
}
if (!associates) {
associates = rb_ary_new();
@@ -834,9 +749,9 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
cp = RSTRING_PTR(buf);
while (1 < numbytes) {
- *cp |= 0x80;
- cp++;
- numbytes--;
+ *cp |= 0x80;
+ cp++;
+ numbytes--;
}
rb_str_buf_cat(res, RSTRING_PTR(buf), RSTRING_LEN(buf));
@@ -844,16 +759,7 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
break;
default: {
- char unknown[5];
- if (ISPRINT(type)) {
- unknown[0] = type;
- unknown[1] = '\0';
- }
- else {
- snprintf(unknown, sizeof(unknown), "\\x%.2x", type & 0xff);
- }
- rb_warning("unknown pack directive '%s' in '% "PRIsVALUE"'",
- unknown, fmt);
+ unknown_directive("pack", type, fmt);
break;
}
}
@@ -862,7 +768,6 @@ pack_pack(int argc, VALUE *argv, VALUE ary)
if (associates) {
str_associate(res, associates);
}
- OBJ_INFECT(res, fmt);
switch (enc_info) {
case 1:
ENCODING_CODERANGE_SET(res, rb_usascii_encindex(), ENC_CODERANGE_7BIT);
@@ -1000,7 +905,7 @@ hex2num(char c)
tmp_len = 0; \
if (len > (long)((send-s)/(sz))) { \
if (!star) { \
- tmp_len = len-(send-s)/(sz); \
+ tmp_len = len-(send-s)/(sz); \
} \
len = (send-s)/(sz); \
} \
@@ -1011,24 +916,16 @@ hex2num(char c)
rb_ary_store(ary, RARRAY_LEN(ary)+tmp_len-1, Qnil); \
} while (0)
-/* Workaround for Oracle Solaris Studio 12.4/12.5 C compiler optimization bug
+/* Workaround for Oracle Developer Studio (Oracle Solaris Studio)
+ * 12.4/12.5/12.6 C compiler optimization bug
* with "-xO4" optimization option.
*/
-#if defined(__SUNPRO_C) && 0x5130 <= __SUNPRO_C && __SUNPRO_C <= 0x5140
+#if defined(__SUNPRO_C) && 0x5130 <= __SUNPRO_C && __SUNPRO_C <= 0x5150
# define AVOID_CC_BUG volatile
#else
# define AVOID_CC_BUG
#endif
-static VALUE
-infected_str_new(const char *ptr, long len, VALUE str)
-{
- VALUE s = rb_str_new(ptr, len);
-
- OBJ_INFECT(s, str);
- return s;
-}
-
/* unpack mode */
#define UNPACK_ARRAY 0
#define UNPACK_BLOCK 1
@@ -1126,7 +1023,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
else if (ISDIGIT(*p)) {
errno = 0;
len = STRTOUL(p, (char**)&p, 10);
- if (errno) {
+ if (len < 0 || errno) {
rb_raise(rb_eRangeError, "pack length too big");
}
}
@@ -1149,7 +1046,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
if (*t != ' ' && *t != '\0') break;
t--; len--;
}
- UNPACK_PUSH(infected_str_new(s, len, str));
+ UNPACK_PUSH(rb_str_new(s, len));
s += end;
}
break;
@@ -1160,7 +1057,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
if (len > send-s) len = send-s;
while (t < s+len && *t) t++;
- UNPACK_PUSH(infected_str_new(s, t-s, str));
+ UNPACK_PUSH(rb_str_new(s, t-s));
if (t < send) t++;
s = star ? t : s+len;
}
@@ -1168,7 +1065,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'a':
if (len > send - s) len = send - s;
- UNPACK_PUSH(infected_str_new(s, len, str));
+ UNPACK_PUSH(rb_str_new(s, len));
s += len;
break;
@@ -1459,7 +1356,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'u':
{
- VALUE buf = infected_str_new(0, (send - s)*3/4, str);
+ VALUE buf = rb_str_new(0, (send - s)*3/4);
char *ptr = RSTRING_PTR(buf);
long total = 0;
@@ -1514,7 +1411,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'm':
{
- VALUE buf = infected_str_new(0, (send - s + 3)*3/4, str); /* +3 is for skipping paddings */
+ VALUE buf = rb_str_new(0, (send - s + 3)*3/4); /* +3 is for skipping paddings */
char *ptr = RSTRING_PTR(buf);
int a = -1,b = -1,c = 0,d = 0;
static signed char b64_xtable[256];
@@ -1595,7 +1492,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'M':
{
- VALUE buf = infected_str_new(0, send - s, str);
+ VALUE buf = rb_str_new(0, send - s);
char *ptr = RSTRING_PTR(buf), *ss = s;
int csum = 0;
int c1, c2;
@@ -1664,7 +1561,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
while (p < pend) {
if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
if (len < RSTRING_LEN(*p)) {
- tmp = rb_tainted_str_new(t, len);
+ tmp = rb_str_new(t, len);
str_associate(tmp, a);
}
else {
@@ -1738,8 +1635,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
break;
default:
- rb_warning("unknown unpack directive '%c' in '%s'",
- type, RSTRING_PTR(fmt));
+ unknown_directive("unpack", type, fmt);
break;
}
}
@@ -1747,144 +1643,15 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
return ary;
}
-/*
- * call-seq:
- * str.unpack(format) -> anArray
- *
- * Decodes <i>str</i> (which may contain binary data) according to the
- * format string, returning an array of each value extracted. The
- * format string consists of a sequence of single-character directives,
- * summarized in the table at the end of this entry.
- * Each directive may be followed
- * by a number, indicating the number of times to repeat with this
- * directive. An asterisk (``<code>*</code>'') will use up all
- * remaining elements. The directives <code>sSiIlL</code> may each be
- * followed by an underscore (``<code>_</code>'') or
- * exclamation mark (``<code>!</code>'') to use the underlying
- * platform's native size for the specified type; otherwise, it uses a
- * platform-independent consistent size. Spaces are ignored in the
- * format string. See also <code>String#unpack1</code>, <code>Array#pack</code>.
- *
- * "abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "]
- * "abc \0\0".unpack('a3a3') #=> ["abc", " \000\000"]
- * "abc \0abc \0".unpack('Z*Z*') #=> ["abc ", "abc "]
- * "aa".unpack('b8B8') #=> ["10000110", "01100001"]
- * "aaa".unpack('h2H2c') #=> ["16", "61", 97]
- * "\xfe\xff\xfe\xff".unpack('sS') #=> [-2, 65534]
- * "now=20is".unpack('M*') #=> ["now is"]
- * "whole".unpack('xax2aX2aX1aX2a') #=> ["h", "e", "l", "l", "o"]
- *
- * This table summarizes the various formats and the Ruby classes
- * returned by each.
- *
- * Integer | |
- * Directive | Returns | Meaning
- * ------------------------------------------------------------------
- * C | Integer | 8-bit unsigned (unsigned char)
- * S | Integer | 16-bit unsigned, native endian (uint16_t)
- * L | Integer | 32-bit unsigned, native endian (uint32_t)
- * Q | Integer | 64-bit unsigned, native endian (uint64_t)
- * J | Integer | pointer width unsigned, native endian (uintptr_t)
- * | |
- * c | Integer | 8-bit signed (signed char)
- * s | Integer | 16-bit signed, native endian (int16_t)
- * l | Integer | 32-bit signed, native endian (int32_t)
- * q | Integer | 64-bit signed, native endian (int64_t)
- * j | Integer | pointer width signed, native endian (intptr_t)
- * | |
- * S_ S! | Integer | unsigned short, native endian
- * I I_ I! | Integer | unsigned int, native endian
- * L_ L! | Integer | unsigned long, native endian
- * Q_ Q! | Integer | unsigned long long, native endian (ArgumentError
- * | | if the platform has no long long type.)
- * J! | Integer | uintptr_t, native endian (same with J)
- * | |
- * s_ s! | Integer | signed short, native endian
- * i i_ i! | Integer | signed int, native endian
- * l_ l! | Integer | signed long, native endian
- * q_ q! | Integer | signed long long, native endian (ArgumentError
- * | | if the platform has no long long type.)
- * j! | Integer | intptr_t, native endian (same with j)
- * | |
- * S> s> S!> s!> | Integer | same as the directives without ">" except
- * L> l> L!> l!> | | big endian
- * I!> i!> | |
- * Q> q> Q!> q!> | | "S>" is same as "n"
- * J> j> J!> j!> | | "L>" is same as "N"
- * | |
- * S< s< S!< s!< | Integer | same as the directives without "<" except
- * L< l< L!< l!< | | little endian
- * I!< i!< | |
- * Q< q< Q!< q!< | | "S<" is same as "v"
- * J< j< J!< j!< | | "L<" is same as "V"
- * | |
- * n | Integer | 16-bit unsigned, network (big-endian) byte order
- * N | Integer | 32-bit unsigned, network (big-endian) byte order
- * v | Integer | 16-bit unsigned, VAX (little-endian) byte order
- * V | Integer | 32-bit unsigned, VAX (little-endian) byte order
- * | |
- * U | Integer | UTF-8 character
- * w | Integer | BER-compressed integer (see Array.pack)
- *
- * Float | |
- * Directive | Returns | Meaning
- * -----------------------------------------------------------------
- * D d | Float | double-precision, native format
- * F f | Float | single-precision, native format
- * E | Float | double-precision, little-endian byte order
- * e | Float | single-precision, little-endian byte order
- * G | Float | double-precision, network (big-endian) byte order
- * g | Float | single-precision, network (big-endian) byte order
- *
- * String | |
- * Directive | Returns | Meaning
- * -----------------------------------------------------------------
- * A | String | arbitrary binary string (remove trailing nulls and ASCII spaces)
- * a | String | arbitrary binary string
- * Z | String | null-terminated string
- * B | String | bit string (MSB first)
- * b | String | bit string (LSB first)
- * H | String | hex string (high nibble first)
- * h | String | hex string (low nibble first)
- * u | String | UU-encoded string
- * M | String | quoted-printable, MIME encoding (see RFC2045)
- * m | String | base64 encoded string (RFC 2045) (default)
- * | | base64 encoded string (RFC 4648) if followed by 0
- * P | String | pointer to a structure (fixed-length string)
- * p | String | pointer to a null-terminated string
- *
- * Misc. | |
- * Directive | Returns | Meaning
- * -----------------------------------------------------------------
- * @ | --- | skip to the offset given by the length argument
- * X | --- | skip backward one byte
- * x | --- | skip forward one byte
- *
- * HISTORY
- *
- * * J, J! j, and j! are available since Ruby 2.3.
- * * Q_, Q!, q_, and q! are available since Ruby 2.1.
- * * I!<, i!<, I!>, and i!> are available since Ruby 1.9.3.
- */
-
static VALUE
-pack_unpack(VALUE str, VALUE fmt)
+pack_unpack(rb_execution_context_t *ec, VALUE str, VALUE fmt)
{
int mode = rb_block_given_p() ? UNPACK_BLOCK : UNPACK_ARRAY;
return pack_unpack_internal(str, fmt, mode);
}
-/*
- * call-seq:
- * str.unpack1(format) -> obj
- *
- * Decodes <i>str</i> (which may contain binary data) according to the
- * format string, returning the first value extracted.
- * See also <code>String#unpack</code>, <code>Array#pack</code>.
- */
-
static VALUE
-pack_unpack1(VALUE str, VALUE fmt)
+pack_unpack1(rb_execution_context_t *ec, VALUE str, VALUE fmt)
{
return pack_unpack_internal(str, fmt, UNPACK_1);
}
@@ -1933,7 +1700,7 @@ rb_uv_to_utf8(char buf[6], unsigned long uv)
}
rb_raise(rb_eRangeError, "pack(U): value out of range");
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
static const unsigned long utf8_limits[] = {
@@ -1996,12 +1763,10 @@ utf8_to_uv(const char *p, long *lenp)
return uv;
}
+#include "pack.rbinc"
+
void
Init_pack(void)
{
- rb_define_method(rb_cArray, "pack", pack_pack, -1);
- rb_define_method(rb_cString, "unpack", pack_unpack, 1);
- rb_define_method(rb_cString, "unpack1", pack_unpack1, 1);
-
id_associated = rb_make_internal_id();
}
diff --git a/pack.rb b/pack.rb
new file mode 100644
index 0000000000..a4723861d5
--- /dev/null
+++ b/pack.rb
@@ -0,0 +1,283 @@
+# for pack.c
+
+class Array
+ # call-seq:
+ # arr.pack( aTemplateString ) -> aBinaryString
+ # arr.pack( aTemplateString, buffer: aBufferString ) -> aBufferString
+ #
+ # Packs the contents of <i>arr</i> into a binary sequence according to
+ # the directives in <i>aTemplateString</i> (see the table below)
+ # Directives ``A,'' ``a,'' and ``Z'' may be followed by a count,
+ # which gives the width of the resulting field. The remaining
+ # directives also may take a count, indicating the number of array
+ # elements to convert. If the count is an asterisk
+ # (``<code>*</code>''), all remaining array elements will be
+ # converted. Any of the directives ``<code>sSiIlL</code>'' may be
+ # followed by an underscore (``<code>_</code>'') or
+ # exclamation mark (``<code>!</code>'') to use the underlying
+ # platform's native size for the specified type; otherwise, they use a
+ # platform-independent size. Spaces are ignored in the template
+ # string. See also String#unpack.
+ #
+ # a = [ "a", "b", "c" ]
+ # n = [ 65, 66, 67 ]
+ # a.pack("A3A3A3") #=> "a b c "
+ # a.pack("a3a3a3") #=> "a\000\000b\000\000c\000\000"
+ # n.pack("ccc") #=> "ABC"
+ #
+ # If <i>aBufferString</i> is specified and its capacity is enough,
+ # +pack+ uses it as the buffer and returns it.
+ # When the offset is specified by the beginning of <i>aTemplateString</i>,
+ # the result is filled after the offset.
+ # If original contents of <i>aBufferString</i> exists and it's longer than
+ # the offset, the rest of <i>offsetOfBuffer</i> are overwritten by the result.
+ # If it's shorter, the gap is filled with ``<code>\0</code>''.
+ #
+ # Note that ``buffer:'' option does not guarantee not to allocate memory
+ # in +pack+. If the capacity of <i>aBufferString</i> is not enough,
+ # +pack+ allocates memory.
+ #
+ # Directives for +pack+.
+ #
+ # Integer | Array |
+ # Directive | Element | Meaning
+ # ----------------------------------------------------------------------------
+ # C | Integer | 8-bit unsigned (unsigned char)
+ # S | Integer | 16-bit unsigned, native endian (uint16_t)
+ # L | Integer | 32-bit unsigned, native endian (uint32_t)
+ # Q | Integer | 64-bit unsigned, native endian (uint64_t)
+ # J | Integer | pointer width unsigned, native endian (uintptr_t)
+ # | | (J is available since Ruby 2.3.)
+ # | |
+ # c | Integer | 8-bit signed (signed char)
+ # s | Integer | 16-bit signed, native endian (int16_t)
+ # l | Integer | 32-bit signed, native endian (int32_t)
+ # q | Integer | 64-bit signed, native endian (int64_t)
+ # j | Integer | pointer width signed, native endian (intptr_t)
+ # | | (j is available since Ruby 2.3.)
+ # | |
+ # S_ S! | Integer | unsigned short, native endian
+ # I I_ I! | Integer | unsigned int, native endian
+ # L_ L! | Integer | unsigned long, native endian
+ # Q_ Q! | Integer | unsigned long long, native endian (ArgumentError
+ # | | if the platform has no long long type.)
+ # | | (Q_ and Q! is available since Ruby 2.1.)
+ # J! | Integer | uintptr_t, native endian (same with J)
+ # | | (J! is available since Ruby 2.3.)
+ # | |
+ # s_ s! | Integer | signed short, native endian
+ # i i_ i! | Integer | signed int, native endian
+ # l_ l! | Integer | signed long, native endian
+ # q_ q! | Integer | signed long long, native endian (ArgumentError
+ # | | if the platform has no long long type.)
+ # | | (q_ and q! is available since Ruby 2.1.)
+ # j! | Integer | intptr_t, native endian (same with j)
+ # | | (j! is available since Ruby 2.3.)
+ # | |
+ # S> s> S!> s!> | Integer | same as the directives without ">" except
+ # L> l> L!> l!> | | big endian
+ # I!> i!> | | (available since Ruby 1.9.3)
+ # Q> q> Q!> q!> | | "S>" is same as "n"
+ # J> j> J!> j!> | | "L>" is same as "N"
+ # | |
+ # S< s< S!< s!< | Integer | same as the directives without "<" except
+ # L< l< L!< l!< | | little endian
+ # I!< i!< | | (available since Ruby 1.9.3)
+ # Q< q< Q!< q!< | | "S<" is same as "v"
+ # J< j< J!< j!< | | "L<" is same as "V"
+ # | |
+ # n | Integer | 16-bit unsigned, network (big-endian) byte order
+ # N | Integer | 32-bit unsigned, network (big-endian) byte order
+ # v | Integer | 16-bit unsigned, VAX (little-endian) byte order
+ # V | Integer | 32-bit unsigned, VAX (little-endian) byte order
+ # | |
+ # U | Integer | UTF-8 character
+ # w | Integer | BER-compressed integer
+ #
+ # Float | Array |
+ # Directive | Element | Meaning
+ # ---------------------------------------------------------------------------
+ # D d | Float | double-precision, native format
+ # F f | Float | single-precision, native format
+ # E | Float | double-precision, little-endian byte order
+ # e | Float | single-precision, little-endian byte order
+ # G | Float | double-precision, network (big-endian) byte order
+ # g | Float | single-precision, network (big-endian) byte order
+ #
+ # String | Array |
+ # Directive | Element | Meaning
+ # ---------------------------------------------------------------------------
+ # A | String | arbitrary binary string (space padded, count is width)
+ # a | String | arbitrary binary string (null padded, count is width)
+ # Z | String | same as ``a'', except that null is added with *
+ # B | String | bit string (MSB first)
+ # b | String | bit string (LSB first)
+ # H | String | hex string (high nibble first)
+ # h | String | hex string (low nibble first)
+ # u | String | UU-encoded string
+ # M | String | quoted printable, MIME encoding (see also RFC2045)
+ # | | (text mode but input must use LF and output LF)
+ # m | String | base64 encoded string (see RFC 2045)
+ # | | (if count is 0, no line feed are added, see RFC 4648)
+ # | | (count specifies input bytes between each LF,
+ # | | rounded down to nearest multiple of 3)
+ # P | String | pointer to a structure (fixed-length string)
+ # p | String | pointer to a null-terminated string
+ #
+ # Misc. | Array |
+ # Directive | Element | Meaning
+ # ---------------------------------------------------------------------------
+ # @ | --- | moves to absolute position
+ # X | --- | back up a byte
+ # x | --- | null byte
+ def pack(fmt, buffer: nil)
+ Primitive.pack_pack(fmt, buffer)
+ end
+end
+
+class String
+ # call-seq:
+ # str.unpack(format) -> anArray
+ #
+ # Decodes <i>str</i> (which may contain binary data) according to the
+ # format string, returning an array of each value extracted. The
+ # format string consists of a sequence of single-character directives,
+ # summarized in the table at the end of this entry.
+ # Each directive may be followed
+ # by a number, indicating the number of times to repeat with this
+ # directive. An asterisk (``<code>*</code>'') will use up all
+ # remaining elements. The directives <code>sSiIlL</code> may each be
+ # followed by an underscore (``<code>_</code>'') or
+ # exclamation mark (``<code>!</code>'') to use the underlying
+ # platform's native size for the specified type; otherwise, it uses a
+ # platform-independent consistent size. Spaces are ignored in the
+ # format string. See also String#unpack1, Array#pack.
+ #
+ # "abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "]
+ # "abc \0\0".unpack('a3a3') #=> ["abc", " \000\000"]
+ # "abc \0abc \0".unpack('Z*Z*') #=> ["abc ", "abc "]
+ # "aa".unpack('b8B8') #=> ["10000110", "01100001"]
+ # "aaa".unpack('h2H2c') #=> ["16", "61", 97]
+ # "\xfe\xff\xfe\xff".unpack('sS') #=> [-2, 65534]
+ # "now=20is".unpack('M*') #=> ["now is"]
+ # "whole".unpack('xax2aX2aX1aX2a') #=> ["h", "e", "l", "l", "o"]
+ #
+ # This table summarizes the various formats and the Ruby classes
+ # returned by each.
+ #
+ # Integer | |
+ # Directive | Returns | Meaning
+ # ------------------------------------------------------------------
+ # C | Integer | 8-bit unsigned (unsigned char)
+ # S | Integer | 16-bit unsigned, native endian (uint16_t)
+ # L | Integer | 32-bit unsigned, native endian (uint32_t)
+ # Q | Integer | 64-bit unsigned, native endian (uint64_t)
+ # J | Integer | pointer width unsigned, native endian (uintptr_t)
+ # | |
+ # c | Integer | 8-bit signed (signed char)
+ # s | Integer | 16-bit signed, native endian (int16_t)
+ # l | Integer | 32-bit signed, native endian (int32_t)
+ # q | Integer | 64-bit signed, native endian (int64_t)
+ # j | Integer | pointer width signed, native endian (intptr_t)
+ # | |
+ # S_ S! | Integer | unsigned short, native endian
+ # I I_ I! | Integer | unsigned int, native endian
+ # L_ L! | Integer | unsigned long, native endian
+ # Q_ Q! | Integer | unsigned long long, native endian (ArgumentError
+ # | | if the platform has no long long type.)
+ # J! | Integer | uintptr_t, native endian (same with J)
+ # | |
+ # s_ s! | Integer | signed short, native endian
+ # i i_ i! | Integer | signed int, native endian
+ # l_ l! | Integer | signed long, native endian
+ # q_ q! | Integer | signed long long, native endian (ArgumentError
+ # | | if the platform has no long long type.)
+ # j! | Integer | intptr_t, native endian (same with j)
+ # | |
+ # S> s> S!> s!> | Integer | same as the directives without ">" except
+ # L> l> L!> l!> | | big endian
+ # I!> i!> | |
+ # Q> q> Q!> q!> | | "S>" is same as "n"
+ # J> j> J!> j!> | | "L>" is same as "N"
+ # | |
+ # S< s< S!< s!< | Integer | same as the directives without "<" except
+ # L< l< L!< l!< | | little endian
+ # I!< i!< | |
+ # Q< q< Q!< q!< | | "S<" is same as "v"
+ # J< j< J!< j!< | | "L<" is same as "V"
+ # | |
+ # n | Integer | 16-bit unsigned, network (big-endian) byte order
+ # N | Integer | 32-bit unsigned, network (big-endian) byte order
+ # v | Integer | 16-bit unsigned, VAX (little-endian) byte order
+ # V | Integer | 32-bit unsigned, VAX (little-endian) byte order
+ # | |
+ # U | Integer | UTF-8 character
+ # w | Integer | BER-compressed integer (see Array#pack)
+ #
+ # Float | |
+ # Directive | Returns | Meaning
+ # -----------------------------------------------------------------
+ # D d | Float | double-precision, native format
+ # F f | Float | single-precision, native format
+ # E | Float | double-precision, little-endian byte order
+ # e | Float | single-precision, little-endian byte order
+ # G | Float | double-precision, network (big-endian) byte order
+ # g | Float | single-precision, network (big-endian) byte order
+ #
+ # String | |
+ # Directive | Returns | Meaning
+ # -----------------------------------------------------------------
+ # A | String | arbitrary binary string (remove trailing nulls and ASCII spaces)
+ # a | String | arbitrary binary string
+ # Z | String | null-terminated string
+ # B | String | bit string (MSB first)
+ # b | String | bit string (LSB first)
+ # H | String | hex string (high nibble first)
+ # h | String | hex string (low nibble first)
+ # u | String | UU-encoded string
+ # M | String | quoted-printable, MIME encoding (see RFC2045)
+ # m | String | base64 encoded string (RFC 2045) (default)
+ # | | base64 encoded string (RFC 4648) if followed by 0
+ # P | String | pointer to a structure (fixed-length string)
+ # p | String | pointer to a null-terminated string
+ #
+ # Misc. | |
+ # Directive | Returns | Meaning
+ # -----------------------------------------------------------------
+ # @ | --- | skip to the offset given by the length argument
+ # X | --- | skip backward one byte
+ # x | --- | skip forward one byte
+ #
+ # HISTORY
+ #
+ # * J, J! j, and j! are available since Ruby 2.3.
+ # * Q_, Q!, q_, and q! are available since Ruby 2.1.
+ # * I!<, i!<, I!>, and i!> are available since Ruby 1.9.3.
+ def unpack(fmt)
+ Primitive.pack_unpack(fmt)
+ end
+
+ # call-seq:
+ # str.unpack1(format) -> obj
+ #
+ # Decodes <i>str</i> (which may contain binary data) according to the
+ # format string, returning the first value extracted.
+ # See also String#unpack, Array#pack.
+ #
+ # Contrast with String#unpack:
+ #
+ # "abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "]
+ # "abc \0\0abc \0\0".unpack1('A6Z6') #=> "abc"
+ #
+ # In that case data would be lost but often it's the case that the array
+ # only holds one value, especially when unpacking binary data. For instance:
+ #
+ # "\xff\x00\x00\x00".unpack("l") #=> [255]
+ # "\xff\x00\x00\x00".unpack1("l") #=> 255
+ #
+ # Thus unpack1 is convenient, makes clear the intention and signals
+ # the expected return value to those reading the code.
+ def unpack1(fmt)
+ Primitive.pack_unpack1(fmt)
+ end
+end
diff --git a/parse.y b/parse.y
index 678e7575c3..3bc3748dd5 100644
--- a/parse.y
+++ b/parse.y
@@ -14,25 +14,67 @@
#if !YYPURE
# error needs pure parser
#endif
-#ifndef PARSER_DEBUG
-#define PARSER_DEBUG 0
-#endif
#define YYDEBUG 1
#define YYERROR_VERBOSE 1
#define YYSTACK_USE_ALLOCA 0
+#define YYLTYPE rb_code_location_t
+#define YYLTYPE_IS_DECLARED 1
+
+#include "ruby/internal/config.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+
+struct lex_context;
-#include "ruby/ruby.h"
-#include "ruby/st.h"
-#include "ruby/encoding.h"
#include "internal.h"
+#include "internal/compile.h"
+#include "internal/compilers.h"
+#include "internal/complex.h"
+#include "internal/error.h"
+#include "internal/hash.h"
+#include "internal/imemo.h"
+#include "internal/io.h"
+#include "internal/numeric.h"
+#include "internal/parse.h"
+#include "internal/rational.h"
+#include "internal/re.h"
+#include "internal/symbol.h"
+#include "internal/thread.h"
+#include "internal/util.h"
+#include "internal/variable.h"
#include "node.h"
-#include "parse.h"
-#include "symbol.h"
-#include "regenc.h"
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
#include "probes.h"
+#include "regenc.h"
+#include "ruby/encoding.h"
+#include "ruby/regex.h"
+#include "ruby/ruby.h"
+#include "ruby/st.h"
+#include "ruby/util.h"
+#include "ruby/ractor.h"
+#include "symbol.h"
+
+enum shareability {
+ shareable_none,
+ shareable_literal,
+ shareable_copy,
+ shareable_everything,
+};
+
+struct lex_context {
+ unsigned int in_defined: 1;
+ unsigned int in_kwarg: 1;
+ unsigned int in_def: 1;
+ unsigned int in_class: 1;
+ BITFIELD(enum shareability, shareable_constant_value, 2);
+};
+
+#include "parse.h"
+
+#define NO_LEX_CTXT (struct lex_context){0}
+
+#define AREF(ary, i) RARRAY_AREF(ary, i)
#ifndef WARN_PAST_SCOPE
# define WARN_PAST_SCOPE 0
@@ -40,25 +82,42 @@
#define TAB_WIDTH 8
-#define YYMALLOC(size) rb_parser_malloc(parser, (size))
-#define YYREALLOC(ptr, size) rb_parser_realloc(parser, (ptr), (size))
-#define YYCALLOC(nelem, size) rb_parser_calloc(parser, (nelem), (size))
-#define YYFREE(ptr) rb_parser_free(parser, (ptr))
+#define yydebug (p->debug) /* disable the global variable definition */
+
+#define YYMALLOC(size) rb_parser_malloc(p, (size))
+#define YYREALLOC(ptr, size) rb_parser_realloc(p, (ptr), (size))
+#define YYCALLOC(nelem, size) rb_parser_calloc(p, (nelem), (size))
+#define YYFREE(ptr) rb_parser_free(p, (ptr))
#define YYFPRINTF rb_parser_printf
-#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- rb_parser_printf(parser, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-#endif
-#undef malloc
-#undef realloc
-#undef calloc
-#undef free
-#define malloc YYMALLOC
-#define realloc YYREALLOC
-#define calloc YYCALLOC
-#define free YYFREE
+#define YY_LOCATION_PRINT(File, loc) \
+ rb_parser_printf(p, "%d.%d-%d.%d", \
+ (loc).beg_pos.lineno, (loc).beg_pos.column,\
+ (loc).end_pos.lineno, (loc).end_pos.column)
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).beg_pos = YYRHSLOC(Rhs, 1).beg_pos; \
+ (Current).end_pos = YYRHSLOC(Rhs, N).end_pos; \
+ } \
+ else \
+ { \
+ (Current).beg_pos = YYRHSLOC(Rhs, 0).end_pos; \
+ (Current).end_pos = YYRHSLOC(Rhs, 0).end_pos; \
+ } \
+ while (0)
+
+#define RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(Current) \
+ rb_parser_set_location_from_strterm_heredoc(p, &p->lex.strterm->u.heredoc, &(Current))
+#define RUBY_SET_YYLLOC_OF_NONE(Current) \
+ rb_parser_set_location_of_none(p, &(Current))
+#define RUBY_SET_YYLLOC(Current) \
+ rb_parser_set_location(p, &(Current))
+#define RUBY_INIT_YYLLOC() \
+ { \
+ {p->ruby_sourceline, (int)(p->lex.ptok - p->lex.pbeg)}, \
+ {p->ruby_sourceline, (int)(p->lex.pcur - p->lex.pbeg)}, \
+ }
enum lex_state_bits {
EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
@@ -95,37 +154,41 @@ enum lex_state_e {
EXPR_VALUE = EXPR_BEG,
EXPR_BEG_ANY = (EXPR_BEG | EXPR_MID | EXPR_CLASS),
EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
- EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
+ EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN),
+ EXPR_NONE = 0
};
#define IS_lex_state_for(x, ls) ((x) & (ls))
#define IS_lex_state_all_for(x, ls) (((x) & (ls)) == (ls))
-#define IS_lex_state(ls) IS_lex_state_for(lex_state, (ls))
-#define IS_lex_state_all(ls) IS_lex_state_all_for(lex_state, (ls))
+#define IS_lex_state(ls) IS_lex_state_for(p->lex.state, (ls))
+#define IS_lex_state_all(ls) IS_lex_state_all_for(p->lex.state, (ls))
# define SET_LEX_STATE(ls) \
- (lex_state = \
- (yydebug ? \
- rb_parser_trace_lex_state(parser, lex_state, (ls), __LINE__) : \
+ (p->lex.state = \
+ (p->debug ? \
+ rb_parser_trace_lex_state(p, p->lex.state, (ls), __LINE__) : \
(enum lex_state_e)(ls)))
typedef VALUE stack_type;
-# define SHOW_BITSTACK(stack, name) (yydebug ? rb_parser_show_bitstack(parser, stack, name, __LINE__) : (void)0)
-# define BITSTACK_PUSH(stack, n) (((stack) = ((stack)<<1)|((n)&1)), SHOW_BITSTACK(stack, #stack"(push)"))
-# define BITSTACK_POP(stack) (((stack) = (stack) >> 1), SHOW_BITSTACK(stack, #stack"(pop)"))
-# define BITSTACK_LEXPOP(stack) (((stack) = ((stack) >> 1) | ((stack) & 1)), SHOW_BITSTACK(stack, #stack"(lexpop)"))
-# define BITSTACK_SET_P(stack) (SHOW_BITSTACK(stack, #stack), (stack)&1)
-# define BITSTACK_SET(stack, n) ((stack)=(n), SHOW_BITSTACK(stack, #stack"(set)"))
+static const rb_code_location_t NULL_LOC = { {0, -1}, {0, -1} };
+
+# define SHOW_BITSTACK(stack, name) (p->debug ? rb_parser_show_bitstack(p, stack, name, __LINE__) : (void)0)
+# define BITSTACK_PUSH(stack, n) (((p->stack) = ((p->stack)<<1)|((n)&1)), SHOW_BITSTACK(p->stack, #stack"(push)"))
+# define BITSTACK_POP(stack) (((p->stack) = (p->stack) >> 1), SHOW_BITSTACK(p->stack, #stack"(pop)"))
+# define BITSTACK_SET_P(stack) (SHOW_BITSTACK(p->stack, #stack), (p->stack)&1)
+# define BITSTACK_SET(stack, n) ((p->stack)=(n), SHOW_BITSTACK(p->stack, #stack"(set)"))
+/* A flag to identify keyword_do_cond, "do" keyword after condition expression.
+ Examples: `while ... do`, `until ... do`, and `for ... in ... do` */
#define COND_PUSH(n) BITSTACK_PUSH(cond_stack, (n))
#define COND_POP() BITSTACK_POP(cond_stack)
-#define COND_LEXPOP() BITSTACK_LEXPOP(cond_stack)
#define COND_P() BITSTACK_SET_P(cond_stack)
#define COND_SET(n) BITSTACK_SET(cond_stack, (n))
+/* A flag to identify keyword_do_block; "do" keyword after command_call.
+ Example: `foo 1, 2 do`. */
#define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, (n))
#define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
-#define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
#define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
#define CMDARG_SET(n) BITSTACK_SET(cmdarg_stack, (n))
@@ -144,50 +207,80 @@ struct local_vars {
struct vtable *past;
# endif
struct local_vars *prev;
- stack_type cmdargs;
+# ifndef RIPPER
+ struct {
+ NODE *outer, *inner, *current;
+ } numparam;
+# endif
};
+enum {
+ ORDINAL_PARAM = -1,
+ NO_PARAM = 0,
+ NUMPARAM_MAX = 9,
+};
+
+#define NUMPARAM_ID_P(id) numparam_id_p(id)
+#define NUMPARAM_ID_TO_IDX(id) (unsigned int)(((id) >> ID_SCOPE_SHIFT) - tNUMPARAM_1 + 1)
+#define NUMPARAM_IDX_TO_ID(idx) TOKEN2LOCALID((tNUMPARAM_1 + (idx) - 1))
+static int
+numparam_id_p(ID id)
+{
+ if (!is_local_id(id)) return 0;
+ unsigned int idx = NUMPARAM_ID_TO_IDX(id);
+ return idx > 0 && idx <= NUMPARAM_MAX;
+}
+static void numparam_name(struct parser_params *p, ID id);
+
#define DVARS_INHERIT ((void*)1)
#define DVARS_TOPSCOPE NULL
-#define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
-#define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
+#define DVARS_TERMINAL_P(tbl) ((tbl) == DVARS_INHERIT || (tbl) == DVARS_TOPSCOPE)
typedef struct token_info {
const char *token;
- int linenum;
- int column;
+ rb_code_position_t beg;
+ int indent;
int nonspc;
struct token_info *next;
} token_info;
+typedef struct rb_strterm_struct rb_strterm_t;
+
/*
Structure of Lexer Buffer:
- lex_pbeg tokp lex_p lex_pend
- | | | |
- |-----------+--------------+------------|
- |<------------>|
+ lex.pbeg lex.ptok lex.pcur lex.pend
+ | | | |
+ |------------+------------+------------|
+ |<---------->|
token
*/
struct parser_params {
- NODE *heap;
+ rb_imemo_tmpbuf_t *heap;
YYSTYPE *lval;
struct {
- NODE *strterm;
+ rb_strterm_t *strterm;
VALUE (*gets)(struct parser_params*,VALUE);
VALUE input;
+ VALUE prevline;
VALUE lastline;
VALUE nextline;
const char *pbeg;
const char *pcur;
const char *pend;
const char *ptok;
- long gets_ptr;
+ union {
+ long ptr;
+ VALUE (*call)(VALUE, int);
+ } gets_;
enum lex_state_e state;
+ /* track the nest level of any parens "()[]{}" */
int paren_nest;
+ /* keep p->lex.paren_nest at the beginning of lambda "->" to detect tLAMBEG and keyword_do_LAMBDA */
int lpar_beg;
+ /* track the nest level of only braces "{}" */
int brace_nest;
} lex;
stack_type cond_stack;
@@ -200,12 +293,15 @@ struct parser_params {
int heredoc_line_indent;
char *tokenbuf;
struct local_vars *lvtbl;
+ st_table *pvtbl;
+ st_table *pktbl;
int line_count;
int ruby_sourceline; /* current line no. */
- char *ruby_sourcefile; /* current source file */
+ const char *ruby_sourcefile; /* current source file */
VALUE ruby_sourcefile_string;
rb_encoding *enc;
token_info *token_info;
+ VALUE case_labels;
VALUE compile_option;
VALUE debug_buffer;
@@ -213,16 +309,18 @@ struct parser_params {
ID cur_arg;
+ rb_ast_t *ast;
+ int node_id;
+
+ int max_numparam;
+
+ struct lex_context ctxt;
+
unsigned int command_start:1;
unsigned int eofp: 1;
unsigned int ruby__end__seen: 1;
- unsigned int yydebug: 1;
+ unsigned int debug: 1;
unsigned int has_shebang: 1;
- unsigned int in_defined: 1;
- unsigned int in_main: 1;
- unsigned int in_kwarg: 1;
- unsigned int in_single: 1;
- unsigned int in_def: 1;
unsigned int token_seen: 1;
unsigned int token_info_enabled: 1;
# if WARN_PAST_SCOPE
@@ -234,18 +332,24 @@ struct parser_params {
#ifndef RIPPER
/* Ruby core only */
+ unsigned int do_print: 1;
+ unsigned int do_loop: 1;
+ unsigned int do_chomp: 1;
+ unsigned int do_split: 1;
+
NODE *eval_tree_begin;
NODE *eval_tree;
VALUE error_buffer;
VALUE debug_lines;
- VALUE coverage;
- const struct rb_block *base_block;
+ const struct rb_iseq_struct *parent_iseq;
#else
/* Ripper only */
- VALUE delayed;
- int delayed_line;
- int delayed_col;
+ struct {
+ VALUE token;
+ int line;
+ int col;
+ } delayed;
VALUE value;
VALUE result;
@@ -253,80 +357,106 @@ struct parser_params {
#endif
};
-#ifdef RIPPER
-#define intern_cstr(n,l,en) rb_intern3(n,l,en)
-#else
#define intern_cstr(n,l,en) rb_intern3(n,l,en)
-#endif
-#define STR_NEW(p,n) rb_enc_str_new((p),(n),current_enc)
-#define STR_NEW0() rb_enc_str_new(0,0,current_enc)
-#define STR_NEW2(p) rb_enc_str_new((p),strlen(p),current_enc)
-#define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),current_enc)
-#define TOK_INTERN() intern_cstr(tok(), toklen(), current_enc)
-
-static int parser_yyerror(struct parser_params*, const char*);
-#define yyerror(msg) parser_yyerror(parser, (msg))
-#define token_flush(p) ((p)->lex.ptok = (p)->lex.pcur)
-
-#define lex_strterm (parser->lex.strterm)
-#define lex_state (parser->lex.state)
-#define cond_stack (parser->cond_stack)
-#define cmdarg_stack (parser->cmdarg_stack)
-#define paren_nest (parser->lex.paren_nest)
-#define lpar_beg (parser->lex.lpar_beg)
-#define brace_nest (parser->lex.brace_nest)
-#define in_single (parser->in_single)
-#define in_def (parser->in_def)
-#define in_main (parser->in_main)
-#define in_defined (parser->in_defined)
-#define tokenbuf (parser->tokenbuf)
-#define tokidx (parser->tokidx)
-#define toksiz (parser->toksiz)
-#define tokline (parser->tokline)
-#define lex_input (parser->lex.input)
-#define lex_lastline (parser->lex.lastline)
-#define lex_nextline (parser->lex.nextline)
-#define lex_pbeg (parser->lex.pbeg)
-#define lex_p (parser->lex.pcur)
-#define lex_pend (parser->lex.pend)
-#define heredoc_end (parser->heredoc_end)
-#define heredoc_indent (parser->heredoc_indent)
-#define heredoc_line_indent (parser->heredoc_line_indent)
-#define command_start (parser->command_start)
-#define lex_gets_ptr (parser->lex.gets_ptr)
-#define lex_gets (parser->lex.gets)
-#define lvtbl (parser->lvtbl)
-#define ruby__end__seen (parser->ruby__end__seen)
-#define ruby_sourceline (parser->ruby_sourceline)
-#define ruby_sourcefile (parser->ruby_sourcefile)
-#define ruby_sourcefile_string (parser->ruby_sourcefile_string)
-#define current_enc (parser->enc)
-#define current_arg (parser->cur_arg)
-#define yydebug (parser->yydebug)
+#define STR_NEW(ptr,len) rb_enc_str_new((ptr),(len),p->enc)
+#define STR_NEW0() rb_enc_str_new(0,0,p->enc)
+#define STR_NEW2(ptr) rb_enc_str_new((ptr),strlen(ptr),p->enc)
+#define STR_NEW3(ptr,len,e,func) parser_str_new((ptr),(len),(e),(func),p->enc)
+#define TOK_INTERN() intern_cstr(tok(p), toklen(p), p->enc)
+
+static st_table *
+push_pvtbl(struct parser_params *p)
+{
+ st_table *tbl = p->pvtbl;
+ p->pvtbl = st_init_numtable();
+ return tbl;
+}
+
+static void
+pop_pvtbl(struct parser_params *p, st_table *tbl)
+{
+ st_free_table(p->pvtbl);
+ p->pvtbl = tbl;
+}
+
+static st_table *
+push_pktbl(struct parser_params *p)
+{
+ st_table *tbl = p->pktbl;
+ p->pktbl = 0;
+ return tbl;
+}
+
+static void
+pop_pktbl(struct parser_params *p, st_table *tbl)
+{
+ if (p->pktbl) st_free_table(p->pktbl);
+ p->pktbl = tbl;
+}
+
+static int parser_yyerror(struct parser_params*, const YYLTYPE *yylloc, const char*);
+#define yyerror0(msg) parser_yyerror(p, NULL, (msg))
+#define yyerror1(loc, msg) parser_yyerror(p, (loc), (msg))
+#define yyerror(yylloc, p, msg) parser_yyerror(p, yylloc, msg)
+#define token_flush(ptr) ((ptr)->lex.ptok = (ptr)->lex.pcur)
+
+static void token_info_setup(token_info *ptinfo, const char *ptr, const rb_code_location_t *loc);
+static void token_info_push(struct parser_params*, const char *token, const rb_code_location_t *loc);
+static void token_info_pop(struct parser_params*, const char *token, const rb_code_location_t *loc);
+static void token_info_warn(struct parser_params *p, const char *token, token_info *ptinfo_beg, int same, const rb_code_location_t *loc);
+static void token_info_drop(struct parser_params *p, const char *token, rb_code_position_t beg_pos);
+
#ifdef RIPPER
#define compile_for_eval (0)
#else
-#define compile_for_eval (parser->base_block != 0 && !in_main)
-#define ruby_eval_tree (parser->eval_tree)
-#define ruby_eval_tree_begin (parser->eval_tree_begin)
-#define ruby_debug_lines (parser->debug_lines)
-#define ruby_coverage (parser->coverage)
+#define compile_for_eval (p->parent_iseq != 0)
#endif
-#define tokp lex.ptok
+
+#define token_column ((int)(p->lex.ptok - p->lex.pbeg))
#define CALL_Q_P(q) ((q) == TOKEN2VAL(tANDDOT))
#define NODE_CALL_Q(q) (CALL_Q_P(q) ? NODE_QCALL : NODE_CALL)
-#define NEW_QCALL(q,r,m,a) NEW_NODE(NODE_CALL_Q(q),r,m,a)
+#define NEW_QCALL(q,r,m,a,loc) NEW_NODE(NODE_CALL_Q(q),r,m,a,loc)
-#define lambda_beginning_p() (lpar_beg && lpar_beg == paren_nest)
+#define lambda_beginning_p() (p->lex.lpar_beg == p->lex.paren_nest)
-static enum yytokentype yylex(YYSTYPE*, struct parser_params*);
+static enum yytokentype yylex(YYSTYPE*, YYLTYPE*, struct parser_params*);
+#ifndef RIPPER
static inline void
-parser_set_line(NODE *n, int l)
+rb_discard_node(struct parser_params *p, NODE *n)
+{
+ rb_ast_delete_node(p->ast, n);
+}
+#endif
+
+#ifdef RIPPER
+static inline VALUE
+add_mark_object(struct parser_params *p, VALUE obj)
+{
+ if (!SPECIAL_CONST_P(obj)
+ && !RB_TYPE_P(obj, T_NODE) /* Ripper jumbles NODE objects and other objects... */
+ ) {
+ rb_ast_add_mark_object(p->ast, obj);
+ }
+ return obj;
+}
+#else
+static NODE* node_newnode_with_locals(struct parser_params *, enum node_type, VALUE, VALUE, const rb_code_location_t*);
+#endif
+
+static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE, const rb_code_location_t*);
+#define rb_node_newnode(type, a1, a2, a3, loc) node_newnode(p, (type), (a1), (a2), (a3), (loc))
+
+static NODE *nd_set_loc(NODE *nd, const YYLTYPE *loc);
+
+static int
+parser_get_node_id(struct parser_params *p)
{
- nd_set_line(n, l);
+ int node_id = p->node_id;
+ p->node_id++;
+ return node_id;
}
#ifndef RIPPER
@@ -343,157 +473,128 @@ set_line_body(NODE *body, int line)
#define yyparse ruby_yyparse
-static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
-#define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, (type), (a1), (a2), (a3))
-
-static NODE *cond_gen(struct parser_params*,NODE*,int);
-#define cond(node) cond_gen(parser, (node), FALSE)
-#define method_cond(node) cond_gen(parser, (node), TRUE)
-#define new_nil() NEW_NIL()
-static NODE *new_if_gen(struct parser_params*,NODE*,NODE*,NODE*);
-#define new_if(cc,left,right) new_if_gen(parser, (cc), (left), (right))
-static NODE *new_unless_gen(struct parser_params*,NODE*,NODE*,NODE*);
-#define new_unless(cc,left,right) new_unless_gen(parser, (cc), (left), (right))
-static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
-#define logop(id,node1,node2) \
- logop_gen(parser, ((id)==idAND||(id)==idANDOP)?NODE_AND:NODE_OR, \
- (node1), (node2))
+static NODE* cond(struct parser_params *p, NODE *node, const YYLTYPE *loc);
+static NODE* method_cond(struct parser_params *p, NODE *node, const YYLTYPE *loc);
+#define new_nil(loc) NEW_NIL(loc)
+static NODE *new_nil_at(struct parser_params *p, const rb_code_position_t *pos);
+static NODE *new_if(struct parser_params*,NODE*,NODE*,NODE*,const YYLTYPE*);
+static NODE *new_unless(struct parser_params*,NODE*,NODE*,NODE*,const YYLTYPE*);
+static NODE *logop(struct parser_params*,ID,NODE*,NODE*,const YYLTYPE*,const YYLTYPE*);
static NODE *newline_node(NODE*);
static void fixpos(NODE*,NODE*);
static int value_expr_gen(struct parser_params*,NODE*);
-static void void_expr_gen(struct parser_params*,NODE*);
+static void void_expr(struct parser_params*,NODE*);
static NODE *remove_begin(NODE*);
static NODE *remove_begin_all(NODE*);
-#define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
-#define void_expr0(node) void_expr_gen(parser, (node))
-#define void_expr(node) void_expr0((node) = remove_begin(node))
-static void void_stmts_gen(struct parser_params*,NODE*);
-#define void_stmts(node) void_stmts_gen(parser, (node))
-static void reduce_nodes_gen(struct parser_params*,NODE**);
-#define reduce_nodes(n) reduce_nodes_gen(parser,(n))
-static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
-#define block_dup_check(n1,n2) block_dup_check_gen(parser,(n1),(n2))
-
-static NODE *block_append_gen(struct parser_params*,NODE*,NODE*);
-#define block_append(h,t) block_append_gen(parser,(h),(t))
-static NODE *list_append_gen(struct parser_params*,NODE*,NODE*);
-#define list_append(l,i) list_append_gen(parser,(l),(i))
+#define value_expr(node) value_expr_gen(p, (node))
+static NODE *void_stmts(struct parser_params*,NODE*);
+static void reduce_nodes(struct parser_params*,NODE**);
+static void block_dup_check(struct parser_params*,NODE*,NODE*);
+
+static NODE *block_append(struct parser_params*,NODE*,NODE*);
+static NODE *list_append(struct parser_params*,NODE*,NODE*);
static NODE *list_concat(NODE*,NODE*);
-static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
-#define arg_append(h,t) arg_append_gen(parser,(h),(t))
-static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
-#define arg_concat(h,t) arg_concat_gen(parser,(h),(t))
-static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
-#define literal_concat(h,t) literal_concat_gen(parser,(h),(t))
-static int literal_concat0(struct parser_params *, VALUE, VALUE);
-static NODE *new_evstr_gen(struct parser_params*,NODE*);
-#define new_evstr(n) new_evstr_gen(parser,(n))
-static NODE *evstr2dstr_gen(struct parser_params*,NODE*);
-#define evstr2dstr(n) evstr2dstr_gen(parser,(n))
+static NODE *arg_append(struct parser_params*,NODE*,NODE*,const YYLTYPE*);
+static NODE *last_arg_append(struct parser_params *p, NODE *args, NODE *last_arg, const YYLTYPE *loc);
+static NODE *rest_arg_append(struct parser_params *p, NODE *args, NODE *rest_arg, const YYLTYPE *loc);
+static NODE *literal_concat(struct parser_params*,NODE*,NODE*,const YYLTYPE*);
+static NODE *new_evstr(struct parser_params*,NODE*,const YYLTYPE*);
+static NODE *new_dstr(struct parser_params*,NODE*,const YYLTYPE*);
+static NODE *evstr2dstr(struct parser_params*,NODE*);
static NODE *splat_array(NODE*);
-
-static NODE *call_bin_op_gen(struct parser_params*,NODE*,ID,NODE*);
-#define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1))
-static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
-#define call_uni_op(recv,id) call_uni_op_gen(parser, (recv),(id))
-#define new_qcall(q,r,m,a) NEW_QCALL(q,r,m,a)
-#define new_command_qcall(q,r,m,a) NEW_QCALL(q,r,m,a)
-static NODE *new_command_gen(struct parser_params*parser, NODE *m, NODE *a) {m->nd_args = a; return m;}
-#define new_command(m,a) new_command_gen(parser, m, a)
-static NODE *method_add_block_gen(struct parser_params*parser, NODE *m, NODE *b) {b->nd_iter = m; return b;}
-#define method_add_block(m,b) method_add_block_gen(parser, m, b)
-
-static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*);
-#define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
-static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID);
-#define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
-#define new_kw_arg(k) ((k) ? NEW_KW_ARG(0, (k)) : 0)
-
-static VALUE negate_lit_gen(struct parser_params*, VALUE);
-#define negate_lit(lit) negate_lit_gen(parser, lit)
-static NODE *ret_args_gen(struct parser_params*,NODE*);
-#define ret_args(node) ret_args_gen(parser, (node))
+static void mark_lvar_used(struct parser_params *p, NODE *rhs);
+
+static NODE *call_bin_op(struct parser_params*,NODE*,ID,NODE*,const YYLTYPE*,const YYLTYPE*);
+static NODE *call_uni_op(struct parser_params*,NODE*,ID,const YYLTYPE*,const YYLTYPE*);
+static NODE *new_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *args, const YYLTYPE *op_loc, const YYLTYPE *loc);
+static NODE *new_command_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *args, NODE *block, const YYLTYPE *op_loc, const YYLTYPE *loc);
+static NODE *method_add_block(struct parser_params*p, NODE *m, NODE *b, const YYLTYPE *loc) {b->nd_iter = m; b->nd_loc = *loc; return b;}
+
+static bool args_info_empty_p(struct rb_args_info *args);
+static NODE *new_args(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*,const YYLTYPE*);
+static NODE *new_args_tail(struct parser_params*,NODE*,ID,ID,const YYLTYPE*);
+static NODE *new_array_pattern(struct parser_params *p, NODE *constant, NODE *pre_arg, NODE *aryptn, const YYLTYPE *loc);
+static NODE *new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID rest_arg, NODE *post_args, const YYLTYPE *loc);
+static NODE *new_find_pattern(struct parser_params *p, NODE *constant, NODE *fndptn, const YYLTYPE *loc);
+static NODE *new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID post_rest_arg, const YYLTYPE *loc);
+static NODE *new_hash_pattern(struct parser_params *p, NODE *constant, NODE *hshptn, const YYLTYPE *loc);
+static NODE *new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, const YYLTYPE *loc);
+static void warn_one_line_pattern_matching(struct parser_params *p, NODE *node, NODE *pattern, bool right_assign);
+
+static NODE *new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc);
+static NODE *args_with_numbered(struct parser_params*,NODE*,int);
+
+static VALUE negate_lit(struct parser_params*, VALUE);
+static NODE *ret_args(struct parser_params*,NODE*);
static NODE *arg_blk_pass(NODE*,NODE*);
-static NODE *new_yield_gen(struct parser_params*,NODE*);
-#define new_yield(node) new_yield_gen(parser, (node))
-static NODE *dsym_node_gen(struct parser_params*,NODE*);
-#define dsym_node(node) dsym_node_gen(parser, (node))
-
-static NODE *gettable_gen(struct parser_params*,ID);
-#define gettable(id) gettable_gen(parser,(id))
-static NODE *assignable_gen(struct parser_params*,ID,NODE*);
-#define assignable(id,node) assignable_gen(parser, (id), (node))
-
-static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
-#define aryset(node1,node2) aryset_gen(parser, (node1), (node2))
-static NODE *attrset_gen(struct parser_params*,NODE*,ID,ID);
-#define attrset(node,q,id) attrset_gen(parser, (node), (q), (id))
-
-static void rb_backref_error_gen(struct parser_params*,NODE*);
-#define rb_backref_error(n) rb_backref_error_gen(parser,(n))
-static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
-#define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2))
-
-static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
-static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID atype, ID attr, ID op, NODE *rhs);
-#define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
-static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
-#define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
-
-#define const_path_field(w, n) NEW_COLON2(w, n)
-#define top_const_field(n) NEW_COLON3(n)
-static NODE *const_decl_gen(struct parser_params *parser, NODE* path);
-#define const_decl(path) const_decl_gen(parser, path)
-
-#define var_field(n) (n)
-#define backref_assign_error(n, a) (rb_backref_error(n), NEW_BEGIN(0))
+static NODE *new_yield(struct parser_params*,NODE*,const YYLTYPE*);
+static NODE *dsym_node(struct parser_params*,NODE*,const YYLTYPE*);
+static NODE *gettable(struct parser_params*,ID,const YYLTYPE*);
+static NODE *assignable(struct parser_params*,ID,NODE*,const YYLTYPE*);
+
+static NODE *aryset(struct parser_params*,NODE*,NODE*,const YYLTYPE*);
+static NODE *attrset(struct parser_params*,NODE*,ID,ID,const YYLTYPE*);
+
+static void rb_backref_error(struct parser_params*,NODE*);
+static NODE *node_assign(struct parser_params*,NODE*,NODE*,struct lex_context,const YYLTYPE*);
+
+static NODE *new_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_context, const YYLTYPE *loc);
+static NODE *new_ary_op_assign(struct parser_params *p, NODE *ary, NODE *args, ID op, NODE *rhs, const YYLTYPE *args_loc, const YYLTYPE *loc);
+static NODE *new_attr_op_assign(struct parser_params *p, NODE *lhs, ID atype, ID attr, ID op, NODE *rhs, const YYLTYPE *loc);
+static NODE *new_const_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_context, const YYLTYPE *loc);
+static NODE *new_bodystmt(struct parser_params *p, NODE *head, NODE *rescue, NODE *rescue_else, NODE *ensure, const YYLTYPE *loc);
+
+static NODE *const_decl(struct parser_params *p, NODE* path, const YYLTYPE *loc);
+
+static NODE *opt_arg_append(NODE*, NODE*);
static NODE *kwd_append(NODE*, NODE*);
-static NODE *new_hash_gen(struct parser_params *parser, NODE *hash);
-#define new_hash(hash) new_hash_gen(parser, (hash))
+static NODE *new_hash(struct parser_params *p, NODE *hash, const YYLTYPE *loc);
+static NODE *new_unique_key_hash(struct parser_params *p, NODE *hash, const YYLTYPE *loc);
+
+static NODE *new_defined(struct parser_params *p, NODE *expr, const YYLTYPE *loc);
-#define new_defined(expr) NEW_DEFINED(remove_begin_all(expr))
+static NODE *new_regexp(struct parser_params *, NODE *, int, const YYLTYPE *);
-static NODE *new_regexp_gen(struct parser_params *, NODE *, int);
-#define new_regexp(node, opt) new_regexp_gen(parser, node, opt)
+#define make_list(list, loc) ((list) ? (nd_set_loc(list, loc), list) : NEW_ZLIST(loc))
-static NODE *new_xstring_gen(struct parser_params *, NODE *);
-#define new_xstring(node) new_xstring_gen(parser, node)
-#define new_string1(str) (str)
+static NODE *new_xstring(struct parser_params *, NODE *, const YYLTYPE *loc);
-#define new_brace_body(param, stmt) NEW_ITER(param, stmt)
-#define new_do_body(param, stmt) NEW_ITER(param, stmt)
+static NODE *symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol);
-static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
-#define match_op(node1,node2) match_op_gen(parser, (node1), (node2))
+static NODE *match_op(struct parser_params*,NODE*,NODE*,const YYLTYPE*,const YYLTYPE*);
-static ID *local_tbl_gen(struct parser_params*);
-#define local_tbl() local_tbl_gen(parser)
+static ID *local_tbl(struct parser_params*);
-static VALUE reg_compile_gen(struct parser_params*, VALUE, int);
-#define reg_compile(str,options) reg_compile_gen(parser, (str), (options))
-static void reg_fragment_setenc_gen(struct parser_params*, VALUE, int);
-#define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options))
-static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
-#define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options))
-static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp);
-#define reg_named_capture_assign(regexp) reg_named_capture_assign_gen(parser,(regexp))
+static VALUE reg_compile(struct parser_params*, VALUE, int);
+static void reg_fragment_setenc(struct parser_params*, VALUE, int);
+static int reg_fragment_check(struct parser_params*, VALUE, int);
+static NODE *reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc);
-static NODE *parser_heredoc_dedent(struct parser_params*,NODE*);
-# define heredoc_dedent(str) parser_heredoc_dedent(parser, (str))
+static int literal_concat0(struct parser_params *p, VALUE head, VALUE tail);
+static NODE *heredoc_dedent(struct parser_params*,NODE*);
+
+static void check_literal_when(struct parser_params *p, NODE *args, const YYLTYPE *loc);
#define get_id(id) (id)
#define get_value(val) (val)
+#define get_num(num) (num)
#else /* RIPPER */
#define NODE_RIPPER NODE_CDECL
+#define NEW_RIPPER(a,b,c,loc) (VALUE)NEW_CDECL(a,b,c,loc)
+
+static inline int ripper_is_node_yylval(VALUE n);
static inline VALUE
-ripper_new_yylval(ID a, VALUE b, VALUE c)
+ripper_new_yylval(struct parser_params *p, ID a, VALUE b, VALUE c)
{
- return (VALUE)NEW_CDECL(a, b, c);
+ if (ripper_is_node_yylval(c)) c = RNODE(c)->nd_cval;
+ add_mark_object(p, b);
+ add_mark_object(p, c);
+ return NEW_RIPPER(a, b, c, &NULL_LOC);
}
static inline int
@@ -504,112 +605,88 @@ ripper_is_node_yylval(VALUE n)
#define value_expr(node) ((void)(node))
#define remove_begin(node) (node)
+#define void_stmts(p,x) (x)
#define rb_dvar_defined(id, base) 0
#define rb_local_defined(id, base) 0
static ID ripper_get_id(VALUE);
#define get_id(id) ripper_get_id(id)
static VALUE ripper_get_value(VALUE);
#define get_value(val) ripper_get_value(val)
-static VALUE assignable_gen(struct parser_params*,VALUE);
-#define assignable(lhs,node) assignable_gen(parser, (lhs))
-static int id_is_var_gen(struct parser_params *parser, ID id);
-#define id_is_var(id) id_is_var_gen(parser, (id))
-
-#define method_cond(node) (node)
-#define call_bin_op(recv,id,arg1) dispatch3(binary, (recv), STATIC_ID2SYM(id), (arg1))
-#define match_op(node1,node2) call_bin_op((node1), idEqTilde, (node2))
-#define call_uni_op(recv,id) dispatch2(unary, STATIC_ID2SYM(id), (recv))
-#define logop(id,node1,node2) call_bin_op((node1), (id), (node2))
-#define node_assign(node1, node2) dispatch2(assign, (node1), (node2))
-static VALUE new_qcall_gen(struct parser_params *parser, VALUE q, VALUE r, VALUE m, VALUE a);
-#define new_qcall(q,r,m,a) new_qcall_gen(parser, (r), (q), (m), (a))
-#define new_command_qcall(q,r,m,a) dispatch4(command_call, (r), (q), (m), (a))
-#define new_command_call(q,r,m,a) dispatch4(command_call, (r), (q), (m), (a))
-#define new_command(m,a) dispatch2(command, (m), (a));
-
-#define new_nil() Qnil
-static VALUE new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs);
-static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs);
-#define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
-#define new_const_op_assign(lhs, op, rhs) new_op_assign(lhs, op, rhs)
-
-static VALUE new_regexp_gen(struct parser_params *, VALUE, VALUE);
-#define new_regexp(node, opt) new_regexp_gen(parser, node, opt)
-
-static VALUE new_xstring_gen(struct parser_params *, VALUE);
-#define new_xstring(str) new_xstring_gen(parser, str)
-#define new_string1(str) dispatch1(string_literal, str)
-
-#define new_brace_body(param, stmt) dispatch2(brace_block, escape_Qundef(param), stmt)
-#define new_do_body(param, stmt) dispatch2(do_block, escape_Qundef(param), stmt)
-
-#define const_path_field(w, n) dispatch2(const_path_field, (w), (n))
-#define top_const_field(n) dispatch1(top_const_field, (n))
-static VALUE const_decl_gen(struct parser_params *parser, VALUE path);
-#define const_decl(path) const_decl_gen(parser, path)
-
-static VALUE var_field_gen(struct parser_params *parser, VALUE a);
-#define var_field(a) var_field_gen(parser, (a))
-static VALUE assign_error_gen(struct parser_params *parser, VALUE a);
-#define assign_error(a) assign_error_gen(parser, (a))
-#define backref_assign_error(n, a) assign_error(a)
-
-#define block_dup_check(n1,n2) ((void)(n1), (void)(n2))
-#define fixpos(n1,n2) ((void)(n1), (void)(n2))
-#undef nd_set_line
-#define nd_set_line(n,l) ((void)(n))
+#define get_num(num) (int)get_id(num)
+static VALUE assignable(struct parser_params*,VALUE);
+static int id_is_var(struct parser_params *p, ID id);
+
+#define method_cond(p,node,loc) (node)
+#define call_bin_op(p, recv,id,arg1,op_loc,loc) dispatch3(binary, (recv), STATIC_ID2SYM(id), (arg1))
+#define match_op(p,node1,node2,op_loc,loc) call_bin_op(0, (node1), idEqTilde, (node2), op_loc, loc)
+#define call_uni_op(p, recv,id,op_loc,loc) dispatch2(unary, STATIC_ID2SYM(id), (recv))
+#define logop(p,id,node1,node2,op_loc,loc) call_bin_op(0, (node1), (id), (node2), op_loc, loc)
+
+#define new_nil(loc) Qnil
+
+static VALUE new_regexp(struct parser_params *, VALUE, VALUE, const YYLTYPE *);
+
+static VALUE const_decl(struct parser_params *p, VALUE path);
+
+static VALUE var_field(struct parser_params *p, VALUE a);
+static VALUE assign_error(struct parser_params *p, const char *mesg, VALUE a);
static VALUE parser_reg_compile(struct parser_params*, VALUE, int, VALUE *);
+static VALUE backref_error(struct parser_params*, NODE *, VALUE);
#endif /* !RIPPER */
-#define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
+/* forward declaration */
+typedef struct rb_strterm_heredoc_struct rb_strterm_heredoc_t;
RUBY_SYMBOL_EXPORT_BEGIN
-VALUE rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options);
+VALUE rb_parser_reg_compile(struct parser_params* p, VALUE str, int options);
int rb_reg_fragment_setenc(struct parser_params*, VALUE, int);
enum lex_state_e rb_parser_trace_lex_state(struct parser_params *, enum lex_state_e, enum lex_state_e, int);
VALUE rb_parser_lex_state_name(enum lex_state_e state);
void rb_parser_show_bitstack(struct parser_params *, stack_type, const char *, int);
-PRINTF_ARGS(void rb_parser_fatal(struct parser_params *parser, const char *fmt, ...), 2, 3);
+PRINTF_ARGS(void rb_parser_fatal(struct parser_params *p, const char *fmt, ...), 2, 3);
+YYLTYPE *rb_parser_set_location_from_strterm_heredoc(struct parser_params *p, rb_strterm_heredoc_t *here, YYLTYPE *yylloc);
+YYLTYPE *rb_parser_set_location_of_none(struct parser_params *p, YYLTYPE *yylloc);
+YYLTYPE *rb_parser_set_location(struct parser_params *p, YYLTYPE *yylloc);
RUBY_SYMBOL_EXPORT_END
-static ID formal_argument_gen(struct parser_params*, ID);
-#define formal_argument(id) formal_argument_gen(parser, (id))
-static ID shadowing_lvar_gen(struct parser_params*,ID);
-#define shadowing_lvar(name) shadowing_lvar_gen(parser, (name))
-static void new_bv_gen(struct parser_params*,ID);
-#define new_bv(id) new_bv_gen(parser, (id))
-
-static void local_push_gen(struct parser_params*,int);
-#define local_push(top) local_push_gen(parser,(top))
-static void local_pop_gen(struct parser_params*);
-#define local_pop() local_pop_gen(parser)
-static void local_var_gen(struct parser_params*, ID);
-#define local_var(id) local_var_gen(parser, (id))
-static void arg_var_gen(struct parser_params*, ID);
-#define arg_var(id) arg_var_gen(parser, (id))
-static int local_id_gen(struct parser_params*, ID, ID **);
-#define local_id_ref(id, vidp) local_id_gen(parser, (id), &(vidp))
-#define local_id(id) local_id_gen(parser, (id), NULL)
-static ID internal_id_gen(struct parser_params*);
-#define internal_id() internal_id_gen(parser)
-
-static const struct vtable *dyna_push_gen(struct parser_params *);
-#define dyna_push() dyna_push_gen(parser)
-static void dyna_pop_gen(struct parser_params*, const struct vtable *);
-#define dyna_pop(node) dyna_pop_gen(parser, (node))
-static int dyna_in_block_gen(struct parser_params*);
-#define dyna_in_block() dyna_in_block_gen(parser)
-#define dyna_var(id) local_var(id)
-static int dvar_defined_gen(struct parser_params*, ID, ID**);
-#define dvar_defined_ref(id, vidp) dvar_defined_gen(parser, (id), &(vidp))
-#define dvar_defined(id) dvar_defined_gen(parser, (id), NULL)
-static int dvar_curr_gen(struct parser_params*,ID);
-#define dvar_curr(id) dvar_curr_gen(parser, (id))
-
-static int lvar_defined_gen(struct parser_params*, ID);
-#define lvar_defined(id) lvar_defined_gen(parser, (id))
+static void error_duplicate_pattern_variable(struct parser_params *p, ID id, const YYLTYPE *loc);
+static void error_duplicate_pattern_key(struct parser_params *p, ID id, const YYLTYPE *loc);
+#ifndef RIPPER
+static ID formal_argument(struct parser_params*, ID);
+#else
+static ID formal_argument(struct parser_params*, VALUE);
+#endif
+static ID shadowing_lvar(struct parser_params*,ID);
+static void new_bv(struct parser_params*,ID);
+
+static void local_push(struct parser_params*,int);
+static void local_pop(struct parser_params*);
+static void local_var(struct parser_params*, ID);
+static void arg_var(struct parser_params*, ID);
+static int local_id(struct parser_params *p, ID id);
+static int local_id_ref(struct parser_params*, ID, ID **);
+#ifndef RIPPER
+static ID internal_id(struct parser_params*);
+static NODE *new_args_forward_call(struct parser_params*, NODE*, const YYLTYPE*, const YYLTYPE*);
+static NODE *new_args_forward_def(struct parser_params*, NODE*, const YYLTYPE*);
+#endif
+static int check_forwarding_args(struct parser_params*);
+static void add_forwarding_args(struct parser_params *p);
+
+static const struct vtable *dyna_push(struct parser_params *);
+static void dyna_pop(struct parser_params*, const struct vtable *);
+static int dyna_in_block(struct parser_params*);
+#define dyna_var(p, id) local_var(p, id)
+static int dvar_defined(struct parser_params*, ID);
+static int dvar_defined_ref(struct parser_params*, ID, ID**);
+static int dvar_curr(struct parser_params*,ID);
+
+static int lvar_defined(struct parser_params*, ID);
+
+static NODE *numparam_push(struct parser_params *p);
+static void numparam_pop(struct parser_params *p, NODE *prev_inner);
#ifdef RIPPER
# define METHOD_NOT idNOT
@@ -617,6 +694,14 @@ static int lvar_defined_gen(struct parser_params*, ID);
# define METHOD_NOT '!'
#endif
+#define idFWD_REST '*'
+#ifdef RUBY3_KEYWORDS
+#define idFWD_KWREST idPow /* Use simple "**", as tDSTAR is "**arg" */
+#else
+#define idFWD_KWREST 0
+#endif
+#define idFWD_BLOCK '&'
+
#define RE_OPTION_ONCE (1<<16)
#define RE_OPTION_ENCODING_SHIFT 8
#define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
@@ -625,17 +710,74 @@ static int lvar_defined_gen(struct parser_params*, ID);
#define RE_OPTION_MASK 0xff
#define RE_OPTION_ARG_ENCODING_NONE 32
-#define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
-#define NODE_HEREDOC NODE_ARRAY /* 1, 3 to gc */
-#define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
-#define nd_func u1.id
-#if SIZEOF_SHORT == 2
-#define nd_term(node) ((signed short)(node)->u2.id)
+/* structs for managing terminator of string literal and heredocment */
+typedef struct rb_strterm_literal_struct {
+ union {
+ VALUE dummy;
+ long nest;
+ } u0;
+ union {
+ VALUE dummy;
+ long func; /* STR_FUNC_* (e.g., STR_FUNC_ESCAPE and STR_FUNC_EXPAND) */
+ } u1;
+ union {
+ VALUE dummy;
+ long paren; /* '(' of `%q(...)` */
+ } u2;
+ union {
+ VALUE dummy;
+ long term; /* ')' of `%q(...)` */
+ } u3;
+} rb_strterm_literal_t;
+
+#define HERETERM_LENGTH_BITS ((SIZEOF_VALUE - 1) * CHAR_BIT - 1)
+
+struct rb_strterm_heredoc_struct {
+ VALUE lastline; /* the string of line that contains `<<"END"` */
+ long offset; /* the column of END in `<<"END"` */
+ int sourceline; /* lineno of the line that contains `<<"END"` */
+ unsigned length /* the length of END in `<<"END"` */
+#if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
+ : HERETERM_LENGTH_BITS
+# define HERETERM_LENGTH_MAX ((1U << HERETERM_LENGTH_BITS) - 1)
+#else
+# define HERETERM_LENGTH_MAX UINT_MAX
+#endif
+ ;
+#if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
+ unsigned quote: 1;
+ unsigned func: 8;
#else
-#define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
+ uint8_t quote;
+ uint8_t func;
#endif
-#define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
-#define nd_nest u3.cnt
+};
+STATIC_ASSERT(rb_strterm_heredoc_t, sizeof(rb_strterm_heredoc_t) <= 4 * SIZEOF_VALUE);
+
+#define STRTERM_HEREDOC IMEMO_FL_USER0
+
+struct rb_strterm_struct {
+ VALUE flags;
+ union {
+ rb_strterm_literal_t literal;
+ rb_strterm_heredoc_t heredoc;
+ } u;
+};
+
+#ifndef RIPPER
+void
+rb_strterm_mark(VALUE obj)
+{
+ rb_strterm_t *strterm = (rb_strterm_t*)obj;
+ if (RBASIC(obj)->flags & STRTERM_HEREDOC) {
+ rb_strterm_heredoc_t *heredoc = &strterm->u.heredoc;
+ rb_gc_mark(heredoc->lastline);
+ }
+}
+#endif
+
+#define yytnamerr(yyres, yystr) (YYSIZE_T)rb_yytnamerr(p, yyres, yystr)
+size_t rb_yytnamerr(struct parser_params *p, char *yyres, const char *yystr);
#define TOKEN2ID(tok) ( \
tTOKEN_LOCAL_BEGIN<(tok)&&(tok)<tTOKEN_LOCAL_END ? TOKEN2LOCALID(tok) : \
@@ -663,81 +805,199 @@ static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
-static void ripper_error_gen(struct parser_params *parser);
-#define ripper_error() ripper_error_gen(parser)
+static void ripper_error(struct parser_params *p);
-#define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
-#define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
-#define dispatch2(n,a,b) ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), (a), (b))
-#define dispatch3(n,a,b,c) ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
-#define dispatch4(n,a,b,c,d) ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
-#define dispatch5(n,a,b,c,d,e) ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
-#define dispatch7(n,a,b,c,d,e,f,g) ripper_dispatch7(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e), (f), (g))
+#define dispatch0(n) ripper_dispatch0(p, TOKEN_PASTE(ripper_id_, n))
+#define dispatch1(n,a) ripper_dispatch1(p, TOKEN_PASTE(ripper_id_, n), (a))
+#define dispatch2(n,a,b) ripper_dispatch2(p, TOKEN_PASTE(ripper_id_, n), (a), (b))
+#define dispatch3(n,a,b,c) ripper_dispatch3(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
+#define dispatch4(n,a,b,c,d) ripper_dispatch4(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
+#define dispatch5(n,a,b,c,d,e) ripper_dispatch5(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
+#define dispatch7(n,a,b,c,d,e,f,g) ripper_dispatch7(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e), (f), (g))
#define yyparse ripper_yyparse
#define ID2VAL(id) STATIC_ID2SYM(id)
#define TOKEN2VAL(t) ID2VAL(TOKEN2ID(t))
-#define KWD2EID(t, v) ripper_new_yylval(keyword_##t, get_value(v), 0)
-
-#define arg_new() dispatch0(args_new)
-#define arg_add(l,a) dispatch2(args_add, (l), (a))
-#define arg_add_star(l,a) dispatch2(args_add_star, (l), (a))
-#define arg_add_block(l,b) dispatch2(args_add_block, (l), (b))
-#define arg_add_optblock(l,b) ((b)==Qundef? (l) : dispatch2(args_add_block, (l), (b)))
-#define bare_assoc(v) dispatch1(bare_assoc_hash, (v))
-#define arg_add_assocs(l,b) arg_add((l), bare_assoc(b))
-
-#define args2mrhs(a) dispatch1(mrhs_new_from_args, (a))
-#define mrhs_new() dispatch0(mrhs_new)
-#define mrhs_add(l,a) dispatch2(mrhs_add, (l), (a))
-#define mrhs_add_star(l,a) dispatch2(mrhs_add_star, (l), (a))
-
-#define mlhs_new() dispatch0(mlhs_new)
-#define mlhs_add(l,a) dispatch2(mlhs_add, (l), (a))
-#define mlhs_add_star(l,a) dispatch2(mlhs_add_star, (l), (a))
-#define mlhs_add_post(l,a) dispatch2(mlhs_add_post, (l), (a))
+#define KWD2EID(t, v) ripper_new_yylval(p, keyword_##t, get_value(v), 0)
#define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
-#define blockvar_new(p,v) dispatch2(block_var, (p), (v))
-
-#define method_optarg(m,a) ((a)==Qundef ? (m) : dispatch2(method_add_arg,(m),(a)))
-#define method_arg(m,a) dispatch2(method_add_arg,(m),(a))
-#define method_add_block(m,b) dispatch2(method_add_block, (m), (b))
-
#define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
static inline VALUE
-new_args_gen(struct parser_params *parser, VALUE f, VALUE o, VALUE r, VALUE p, VALUE tail)
+new_args(struct parser_params *p, VALUE pre_args, VALUE opt_args, VALUE rest_arg, VALUE post_args, VALUE tail, YYLTYPE *loc)
{
NODE *t = (NODE *)tail;
- VALUE k = t->u1.value, kr = t->u2.value, b = t->u3.value;
- return params_new(f, o, r, p, k, kr, escape_Qundef(b));
+ VALUE kw_args = t->u1.value, kw_rest_arg = t->u2.value, block = t->u3.value;
+ return params_new(pre_args, opt_args, rest_arg, post_args, kw_args, kw_rest_arg, escape_Qundef(block));
}
-#define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
static inline VALUE
-new_args_tail_gen(struct parser_params *parser, VALUE k, VALUE kr, VALUE b)
+new_args_tail(struct parser_params *p, VALUE kw_args, VALUE kw_rest_arg, VALUE block, YYLTYPE *loc)
{
- return (VALUE)MEMO_NEW(k, kr, b);
+ NODE *t = rb_node_newnode(NODE_ARGS_AUX, kw_args, kw_rest_arg, block, &NULL_LOC);
+ add_mark_object(p, kw_args);
+ add_mark_object(p, kw_rest_arg);
+ add_mark_object(p, block);
+ return (VALUE)t;
}
-#define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
-#define new_defined(expr) dispatch1(defined, (expr))
+static inline VALUE
+args_with_numbered(struct parser_params *p, VALUE args, int max_numparam)
+{
+ return args;
+}
+
+static VALUE
+new_array_pattern(struct parser_params *p, VALUE constant, VALUE pre_arg, VALUE aryptn, const YYLTYPE *loc)
+{
+ NODE *t = (NODE *)aryptn;
+ VALUE pre_args = t->u1.value, rest_arg = t->u2.value, post_args = t->u3.value;
+
+ if (!NIL_P(pre_arg)) {
+ if (!NIL_P(pre_args)) {
+ rb_ary_unshift(pre_args, pre_arg);
+ }
+ else {
+ pre_args = rb_ary_new_from_args(1, pre_arg);
+ }
+ }
+ return dispatch4(aryptn, constant, pre_args, rest_arg, post_args);
+}
+
+static VALUE
+new_array_pattern_tail(struct parser_params *p, VALUE pre_args, VALUE has_rest, VALUE rest_arg, VALUE post_args, const YYLTYPE *loc)
+{
+ NODE *t;
+
+ if (has_rest) {
+ rest_arg = dispatch1(var_field, rest_arg ? rest_arg : Qnil);
+ }
+ else {
+ rest_arg = Qnil;
+ }
+
+ t = rb_node_newnode(NODE_ARYPTN, pre_args, rest_arg, post_args, &NULL_LOC);
+ add_mark_object(p, pre_args);
+ add_mark_object(p, rest_arg);
+ add_mark_object(p, post_args);
+ return (VALUE)t;
+}
+
+static VALUE
+new_find_pattern(struct parser_params *p, VALUE constant, VALUE fndptn, const YYLTYPE *loc)
+{
+ NODE *t = (NODE *)fndptn;
+ VALUE pre_rest_arg = t->u1.value, args = t->u2.value, post_rest_arg = t->u3.value;
+
+ return dispatch4(fndptn, constant, pre_rest_arg, args, post_rest_arg);
+}
+
+static VALUE
+new_find_pattern_tail(struct parser_params *p, VALUE pre_rest_arg, VALUE args, VALUE post_rest_arg, const YYLTYPE *loc)
+{
+ NODE *t;
+
+ pre_rest_arg = dispatch1(var_field, pre_rest_arg ? pre_rest_arg : Qnil);
+ post_rest_arg = dispatch1(var_field, post_rest_arg ? post_rest_arg : Qnil);
+
+ t = rb_node_newnode(NODE_FNDPTN, pre_rest_arg, args, post_rest_arg, &NULL_LOC);
+ add_mark_object(p, pre_rest_arg);
+ add_mark_object(p, args);
+ add_mark_object(p, post_rest_arg);
+ return (VALUE)t;
+}
+
+#define new_hash(p,h,l) rb_ary_new_from_args(0)
+
+static VALUE
+new_unique_key_hash(struct parser_params *p, VALUE ary, const YYLTYPE *loc)
+{
+ return ary;
+}
+
+static VALUE
+new_hash_pattern(struct parser_params *p, VALUE constant, VALUE hshptn, const YYLTYPE *loc)
+{
+ NODE *t = (NODE *)hshptn;
+ VALUE kw_args = t->u1.value, kw_rest_arg = t->u2.value;
+ return dispatch3(hshptn, constant, kw_args, kw_rest_arg);
+}
+
+static VALUE
+new_hash_pattern_tail(struct parser_params *p, VALUE kw_args, VALUE kw_rest_arg, const YYLTYPE *loc)
+{
+ NODE *t;
+ if (kw_rest_arg) {
+ kw_rest_arg = dispatch1(var_field, kw_rest_arg);
+ }
+ else {
+ kw_rest_arg = Qnil;
+ }
+ t = rb_node_newnode(NODE_HSHPTN, kw_args, kw_rest_arg, 0, &NULL_LOC);
+
+ add_mark_object(p, kw_args);
+ add_mark_object(p, kw_rest_arg);
+ return (VALUE)t;
+}
-static VALUE parser_heredoc_dedent(struct parser_params*,VALUE);
-# define heredoc_dedent(str) parser_heredoc_dedent(parser, (str))
+#define new_defined(p,expr,loc) dispatch1(defined, (expr))
-#define FIXME 0
+static VALUE heredoc_dedent(struct parser_params*,VALUE);
#else
-#define ID2VAL(id) ((VALUE)(id))
+#define ID2VAL(id) (id)
#define TOKEN2VAL(t) ID2VAL(t)
#define KWD2EID(t, v) keyword_##t
+
+static NODE *
+set_defun_body(struct parser_params *p, NODE *n, NODE *args, NODE *body, const YYLTYPE *loc)
+{
+ body = remove_begin(body);
+ reduce_nodes(p, &body);
+ n->nd_defn = NEW_SCOPE(args, body, loc);
+ n->nd_loc = *loc;
+ nd_set_line(n->nd_defn, loc->end_pos.lineno);
+ set_line_body(body, loc->beg_pos.lineno);
+ return n;
+}
+
+static NODE *
+rescued_expr(struct parser_params *p, NODE *arg, NODE *rescue,
+ const YYLTYPE *arg_loc, const YYLTYPE *mod_loc, const YYLTYPE *res_loc)
+{
+ YYLTYPE loc = code_loc_gen(mod_loc, res_loc);
+ rescue = NEW_RESBODY(0, remove_begin(rescue), 0, &loc);
+ loc.beg_pos = arg_loc->beg_pos;
+ return NEW_RESCUE(arg, rescue, 0, &loc);
+}
+
#endif /* RIPPER */
+static void
+restore_defun(struct parser_params *p, NODE *name)
+{
+ YYSTYPE c = {.val = name->nd_cval};
+ p->cur_arg = name->nd_vid;
+ p->ctxt.in_def = c.ctxt.in_def;
+ p->ctxt.shareable_constant_value = c.ctxt.shareable_constant_value;
+}
+
+static void
+endless_method_name(struct parser_params *p, NODE *defn, const YYLTYPE *loc)
+{
+#ifdef RIPPER
+ defn = defn->nd_defn;
+#endif
+ ID mid = defn->nd_mid;
+ if (is_attrset_id(mid)) {
+ yyerror1(loc, "setter method cannot be defined in an endless method definition");
+ }
+ token_info_drop(p, "def", loc->beg_pos);
+}
+
#ifndef RIPPER
# define Qnone 0
# define Qnull 0
@@ -769,19 +1029,23 @@ static VALUE parser_heredoc_dedent(struct parser_params*,VALUE);
# define rb_warning3L(l,fmt,a,b,c) WARNING_CALL(WARNING_ARGS_L(l, fmt, 4), (a), (b), (c))
# define rb_warning4L(l,fmt,a,b,c,d) WARNING_CALL(WARNING_ARGS_L(l, fmt, 5), (a), (b), (c), (d))
#ifdef RIPPER
-static ID id_warn, id_warning, id_gets;
+static ID id_warn, id_warning, id_gets, id_assoc;
+# define ERR_MESG() STR_NEW2(mesg) /* to bypass Ripper DSL */
# define WARN_S_L(s,l) STR_NEW(s,l)
# define WARN_S(s) STR_NEW2(s)
# define WARN_I(i) INT2NUM(i)
+# define WARN_ID(i) rb_id2str(i)
+# define WARN_IVAL(i) i
# define PRIsWARN "s"
-# define WARN_ARGS(fmt,n) parser->value, id_warn, n, rb_usascii_str_new_lit(fmt)
+# define rb_warn0L_experimental(l,fmt) WARN_CALL(WARN_ARGS_L(l, fmt, 1))
+# define WARN_ARGS(fmt,n) p->value, id_warn, n, rb_usascii_str_new_lit(fmt)
# define WARN_ARGS_L(l,fmt,n) WARN_ARGS(fmt,n)
# ifdef HAVE_VA_ARGS_MACRO
# define WARN_CALL(...) rb_funcall(__VA_ARGS__)
# else
# define WARN_CALL rb_funcall
# endif
-# define WARNING_ARGS(fmt,n) parser->value, id_warning, n, rb_usascii_str_new_lit(fmt)
+# define WARNING_ARGS(fmt,n) p->value, id_warning, n, rb_usascii_str_new_lit(fmt)
# define WARNING_ARGS_L(l, fmt,n) WARNING_ARGS(fmt,n)
# ifdef HAVE_VA_ARGS_MACRO
# define WARNING_CALL(...) rb_funcall(__VA_ARGS__)
@@ -790,121 +1054,165 @@ static ID id_warn, id_warning, id_gets;
# endif
PRINTF_ARGS(static void ripper_compile_error(struct parser_params*, const char *fmt, ...), 2, 3);
# define compile_error ripper_compile_error
-# define PARSER_ARG parser,
#else
# define WARN_S_L(s,l) s
# define WARN_S(s) s
# define WARN_I(i) i
+# define WARN_ID(i) rb_id2name(i)
+# define WARN_IVAL(i) NUM2INT(i)
# define PRIsWARN PRIsVALUE
-# define WARN_ARGS(fmt,n) WARN_ARGS_L(ruby_sourceline,fmt,n)
-# define WARN_ARGS_L(l,fmt,n) ruby_sourcefile, (l), (fmt)
+# define WARN_ARGS(fmt,n) WARN_ARGS_L(p->ruby_sourceline,fmt,n)
+# define WARN_ARGS_L(l,fmt,n) p->ruby_sourcefile, (l), (fmt)
# define WARN_CALL rb_compile_warn
+# define rb_warn0L_experimental(l,fmt) rb_category_compile_warn(RB_WARN_CATEGORY_EXPERIMENTAL, WARN_ARGS_L(l, fmt, 1))
# define WARNING_ARGS(fmt,n) WARN_ARGS(fmt,n)
# define WARNING_ARGS_L(l,fmt,n) WARN_ARGS_L(l,fmt,n)
# define WARNING_CALL rb_compile_warning
PRINTF_ARGS(static void parser_compile_error(struct parser_params*, const char *fmt, ...), 2, 3);
# define compile_error parser_compile_error
-# define PARSER_ARG parser,
#endif
-/* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
- for instance). This is too low for Ruby to parse some files, such as
- date/format.rb, therefore bump the value up to at least Bison's default. */
-#ifdef OLD_YACC
-#ifndef YYMAXDEPTH
-#define YYMAXDEPTH 10000
+#define WARN_EOL(tok) \
+ (looking_at_eol_p(p) ? \
+ (void)rb_warning0("`" tok "' at the end of line without an expression") : \
+ (void)0)
+static int looking_at_eol_p(struct parser_params *p);
+%}
+
+%expect 0
+%define api.pure
+%define parse.error verbose
+%printer {
+#ifndef RIPPER
+ rb_parser_printf(p, "%"PRIsVALUE, rb_id2str($$));
+#else
+ rb_parser_printf(p, "%"PRIsVALUE, RNODE($$)->nd_rval);
+#endif
+} tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL tOP_ASGN
+%printer {
+#ifndef RIPPER
+ rb_parser_printf(p, "%+"PRIsVALUE, $$->nd_lit);
+#else
+ rb_parser_printf(p, "%+"PRIsVALUE, get_value($$));
#endif
+} tINTEGER tFLOAT tRATIONAL tIMAGINARY tSTRING_CONTENT tCHAR
+%printer {
+#ifndef RIPPER
+ rb_parser_printf(p, "$%ld", $$->nd_nth);
+#else
+ rb_parser_printf(p, "%"PRIsVALUE, $$);
#endif
+} tNTH_REF
+%printer {
+#ifndef RIPPER
+ rb_parser_printf(p, "$%c", (int)$$->nd_nth);
+#else
+ rb_parser_printf(p, "%"PRIsVALUE, $$);
+#endif
+} tBACK_REF
-static void token_info_push_gen(struct parser_params*, const char *token, size_t len);
-static void token_info_pop_gen(struct parser_params*, const char *token, size_t len);
-#define token_info_push(token) token_info_push_gen(parser, (token), rb_strlen_lit(token))
-#define token_info_pop(token) token_info_pop_gen(parser, (token), rb_strlen_lit(token))
-%}
-
-%pure-parser
-%lex-param {struct parser_params *parser}
-%parse-param {struct parser_params *parser}
+%lex-param {struct parser_params *p}
+%parse-param {struct parser_params *p}
+%initial-action
+{
+ RUBY_SET_YYLLOC_OF_NONE(@$);
+};
%union {
VALUE val;
NODE *node;
ID id;
int num;
+ st_table *tbl;
const struct vtable *vars;
+ struct rb_strterm_struct *strterm;
+ struct lex_context ctxt;
}
%token <id>
- keyword_class
- keyword_module
- keyword_def
- keyword_undef
- keyword_begin
- keyword_rescue
- keyword_ensure
- keyword_end
- keyword_if
- keyword_unless
- keyword_then
- keyword_elsif
- keyword_else
- keyword_case
- keyword_when
- keyword_while
- keyword_until
- keyword_for
- 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_defined
- keyword_BEGIN
- keyword_END
- keyword__LINE__
- keyword__FILE__
- keyword__ENCODING__
-
-%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
-%token <node> tINTEGER tFLOAT tRATIONAL tIMAGINARY tSTRING_CONTENT tCHAR
-%token <node> tNTH_REF tBACK_REF
+ keyword_class "`class'"
+ keyword_module "`module'"
+ keyword_def "`def'"
+ keyword_undef "`undef'"
+ keyword_begin "`begin'"
+ keyword_rescue "`rescue'"
+ keyword_ensure "`ensure'"
+ keyword_end "`end'"
+ keyword_if "`if'"
+ keyword_unless "`unless'"
+ keyword_then "`then'"
+ keyword_elsif "`elsif'"
+ keyword_else "`else'"
+ keyword_case "`case'"
+ keyword_when "`when'"
+ keyword_while "`while'"
+ keyword_until "`until'"
+ keyword_for "`for'"
+ keyword_break "`break'"
+ keyword_next "`next'"
+ keyword_redo "`redo'"
+ keyword_retry "`retry'"
+ keyword_in "`in'"
+ keyword_do "`do'"
+ keyword_do_cond "`do' for condition"
+ keyword_do_block "`do' for block"
+ keyword_do_LAMBDA "`do' for lambda"
+ keyword_return "`return'"
+ keyword_yield "`yield'"
+ keyword_super "`super'"
+ keyword_self "`self'"
+ keyword_nil "`nil'"
+ keyword_true "`true'"
+ keyword_false "`false'"
+ keyword_and "`and'"
+ keyword_or "`or'"
+ keyword_not "`not'"
+ modifier_if "`if' modifier"
+ modifier_unless "`unless' modifier"
+ modifier_while "`while' modifier"
+ modifier_until "`until' modifier"
+ modifier_rescue "`rescue' modifier"
+ keyword_alias "`alias'"
+ keyword_defined "`defined?'"
+ keyword_BEGIN "`BEGIN'"
+ keyword_END "`END'"
+ keyword__LINE__ "`__LINE__'"
+ keyword__FILE__ "`__FILE__'"
+ keyword__ENCODING__ "`__ENCODING__'"
+
+%token <id> tIDENTIFIER "local variable or method"
+%token <id> tFID "method"
+%token <id> tGVAR "global variable"
+%token <id> tIVAR "instance variable"
+%token <id> tCONSTANT "constant"
+%token <id> tCVAR "class variable"
+%token <id> tLABEL "label"
+%token <node> tINTEGER "integer literal"
+%token <node> tFLOAT "float literal"
+%token <node> tRATIONAL "rational literal"
+%token <node> tIMAGINARY "imaginary literal"
+%token <node> tCHAR "char literal"
+%token <node> tNTH_REF "numbered reference"
+%token <node> tBACK_REF "back reference"
+%token <node> tSTRING_CONTENT "literal content"
%token <num> tREGEXP_END
%type <node> singleton strings string string1 xstring regexp
%type <node> string_contents xstring_contents regexp_contents string_content
%type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
-%type <node> literal numeric simple_numeric dsym cpath
-%type <node> top_compstmt top_stmts top_stmt
+%type <node> literal numeric simple_numeric ssym dsym symbol cpath def_name defn_head defs_head
+%type <node> top_compstmt top_stmts top_stmt begin_block
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
-%type <node> expr_value arg_value primary_value fcall
-%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
+%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr
+%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
%type <node> args call_args opt_call_args
%type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <node> command_rhs arg_rhs
%type <node> command_asgn mrhs mrhs_arg superclass block_call block_command
%type <node> f_block_optarg f_block_opt
-%type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
+%type <node> f_arglist f_opt_paren_args f_paren_args f_args f_arg f_arg_item
+%type <node> f_optarg f_marg f_marg_list f_margs f_rest_marg
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
%type <node> block_param opt_block_param block_param_def f_opt
%type <node> f_kwarg f_kw f_block_kwarg f_block_kw
@@ -912,14 +1220,26 @@ static void token_info_pop_gen(struct parser_params*, const char *token, size_t
%type <node> lambda f_larglist lambda_body brace_body do_body
%type <node> brace_block cmd_brace_block do_block lhs none fitem
%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
-%type <id> fsym keyword_variable user_variable sym symbol operation operation2 operation3
+%type <node> p_case_body p_cases p_top_expr p_top_expr_body
+%type <node> p_expr p_as p_alt p_expr_basic p_find
+%type <node> p_args p_args_head p_args_tail p_args_post p_arg
+%type <node> p_value p_primitive p_variable p_var_ref p_const
+%type <node> p_kwargs p_kwarg p_kw
+%type <id> keyword_variable user_variable sym operation operation2 operation3
%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
-%type <id> f_kwrest f_label f_arg_asgn call_op call_op2 reswords
-/*%%%*/
-/*%
-%type <val> program then do
-%*/
+%type <id> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon
+%type <id> p_rest p_kwrest p_kwnorest p_any_kwrest p_kw_label
+%type <id> f_no_kwarg f_any_kwrest args_forward excessed_comma
+ %type <ctxt> lex_ctxt /* keep <ctxt> in ripper */
%token END_OF_INPUT 0 "end-of-input"
+%token <id> '.'
+/* escaped chars, should be ignored otherwise */
+%token <id> '\\' "backslash"
+%token tSP "escaped space"
+%token <id> '\t' "escaped horizontal tab"
+%token <id> '\f' "escaped form feed"
+%token <id> '\r' "escaped carriage return"
+%token <id> '\13' "escaped vertical tab"
%token tUPLUS RUBY_TOKEN(UPLUS) "unary+"
%token tUMINUS RUBY_TOKEN(UMINUS) "unary-"
%token tPOW RUBY_TOKEN(POW) "**"
@@ -935,14 +1255,16 @@ static void token_info_pop_gen(struct parser_params*, const char *token, size_t
%token tNMATCH RUBY_TOKEN(NMATCH) "!~"
%token tDOT2 RUBY_TOKEN(DOT2) ".."
%token tDOT3 RUBY_TOKEN(DOT3) "..."
+%token tBDOT2 RUBY_TOKEN(BDOT2) "(.."
+%token tBDOT3 RUBY_TOKEN(BDOT3) "(..."
%token tAREF RUBY_TOKEN(AREF) "[]"
%token tASET RUBY_TOKEN(ASET) "[]="
%token tLSHFT RUBY_TOKEN(LSHFT) "<<"
%token tRSHFT RUBY_TOKEN(RSHFT) ">>"
-%token tANDDOT RUBY_TOKEN(ANDDOT) "&."
-%token tCOLON2 RUBY_TOKEN(COLON2) "::"
+%token <id> tANDDOT RUBY_TOKEN(ANDDOT) "&."
+%token <id> tCOLON2 RUBY_TOKEN(COLON2) "::"
%token tCOLON3 ":: at EXPR_BEG"
-%token <id> tOP_ASGN /* +=, -= etc. */
+%token <id> tOP_ASGN "operator-assignment" /* +=, -= etc. */
%token tASSOC "=>"
%token tLPAREN "("
%token tLPAREN_ARG "( arg"
@@ -954,8 +1276,17 @@ static void token_info_pop_gen(struct parser_params*, const char *token, size_t
%token tDSTAR "**arg"
%token tAMPER "&"
%token tLAMBDA "->"
-%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
-%token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG tLABEL_END
+%token tSYMBEG "symbol literal"
+%token tSTRING_BEG "string literal"
+%token tXSTRING_BEG "backtick literal"
+%token tREGEXP_BEG "regexp literal"
+%token tWORDS_BEG "word list"
+%token tQWORDS_BEG "verbatim word list"
+%token tSYMBOLS_BEG "symbol list"
+%token tQSYMBOLS_BEG "verbatim symbol list"
+%token tSTRING_END "terminator"
+%token tSTRING_DEND "'}'"
+%token tSTRING_DBEG tSTRING_DVAR tLAMBEG tLABEL_END
/*
* precedence table
@@ -964,14 +1295,14 @@ static void token_info_pop_gen(struct parser_params*, const char *token, size_t
%nonassoc tLOWEST
%nonassoc tLBRACE_ARG
-%nonassoc modifier_if modifier_unless modifier_while modifier_until
+%nonassoc modifier_if modifier_unless modifier_while modifier_until keyword_in
%left keyword_or keyword_and
%right keyword_not
%nonassoc keyword_defined
%right '=' tOP_ASGN
%left modifier_rescue
%right '?' ':'
-%nonassoc tDOT2 tDOT3
+%nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
%left tOROP
%left tANDOP
%nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -990,69 +1321,56 @@ static void token_info_pop_gen(struct parser_params*, const char *token, size_t
%%
program : {
SET_LEX_STATE(EXPR_BEG);
- /*%%%*/
- local_push(compile_for_eval || in_main);
- /*%
- local_push(0);
- %*/
+ local_push(p, ifndef_ripper(1)+0);
}
top_compstmt
{
/*%%%*/
if ($2 && !compile_for_eval) {
+ NODE *node = $2;
/* last expression should not be void */
- if (nd_type($2) != NODE_BLOCK) void_expr($2);
- else {
- NODE *node = $2;
+ if (nd_type(node) == NODE_BLOCK) {
while (node->nd_next) {
node = node->nd_next;
}
- void_expr(node->nd_head);
+ node = node->nd_head;
}
+ node = remove_begin(node);
+ void_expr(p, node);
}
- ruby_eval_tree = NEW_SCOPE(0, block_append(ruby_eval_tree, $2));
- /*%
- $$ = $2;
- parser->result = dispatch1(program, $$);
- %*/
- local_pop();
+ p->eval_tree = NEW_SCOPE(0, block_append(p, p->eval_tree, $2), &@$);
+ /*% %*/
+ /*% ripper[final]: program!($2) %*/
+ local_pop(p);
}
;
top_compstmt : top_stmts opt_terms
{
- /*%%%*/
- void_stmts($1);
- /*%
- %*/
- $$ = $1;
+ $$ = void_stmts(p, $1);
}
;
top_stmts : none
{
/*%%%*/
- $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch2(stmts_add, dispatch0(stmts_new),
- dispatch0(void_stmt));
- %*/
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
}
| top_stmt
{
/*%%%*/
$$ = newline_node($1);
- /*%
- $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
- %*/
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, $1) %*/
}
| top_stmts terms top_stmt
{
/*%%%*/
- $$ = block_append($1, newline_node($3));
- /*%
- $$ = dispatch2(stmts_add, $1, $3);
- %*/
+ $$ = block_append(p, $1, newline_node($3));
+ /*% %*/
+ /*% ripper: stmts_add!($1, $3) %*/
}
| error top_stmt
{
@@ -1061,94 +1379,71 @@ top_stmts : none
;
top_stmt : stmt
- | keyword_BEGIN
+ | keyword_BEGIN begin_block
{
- /*%%%*/
- /* local_push(0); */
- /*%
- %*/
+ $$ = $2;
}
- '{' top_compstmt '}'
+ ;
+
+begin_block : '{' top_compstmt '}'
{
/*%%%*/
- ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
- $4);
- /* NEW_PREEXE($4)); */
- /* local_pop(); */
- $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch1(BEGIN, $4);
- %*/
+ p->eval_tree_begin = block_append(p, p->eval_tree_begin,
+ NEW_BEGIN($2, &@$));
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: BEGIN!($2) %*/
}
;
bodystmt : compstmt
opt_rescue
- opt_else
+ k_else {if (!$2) {yyerror1(&@3, "else without rescue is useless");}}
+ compstmt
opt_ensure
{
/*%%%*/
- $$ = $1;
- if ($2) {
- $$ = NEW_RESCUE($1, $2, $3);
- }
- else if ($3) {
- rb_warn0("else without rescue is useless");
- $$ = block_append($$, $3);
- }
- if ($4) {
- if ($$) {
- $$ = NEW_ENSURE($$, $4);
- }
- else {
- $$ = block_append($4, NEW_NIL());
- }
- }
- fixpos($$, $1);
- /*%
- $$ = dispatch4(bodystmt,
- escape_Qundef($1),
- escape_Qundef($2),
- escape_Qundef($3),
- escape_Qundef($4));
- %*/
+ $$ = new_bodystmt(p, $1, $2, $5, $6, &@$);
+ /*% %*/
+ /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), escape_Qundef($5), escape_Qundef($6)) %*/
+ }
+ | compstmt
+ opt_rescue
+ opt_ensure
+ {
+ /*%%%*/
+ $$ = new_bodystmt(p, $1, $2, 0, $3, &@$);
+ /*% %*/
+ /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), Qnil, escape_Qundef($3)) %*/
}
;
compstmt : stmts opt_terms
{
- /*%%%*/
- void_stmts($1);
- /*%
- %*/
- $$ = $1;
+ $$ = void_stmts(p, $1);
}
;
stmts : none
{
/*%%%*/
- $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch2(stmts_add, dispatch0(stmts_new),
- dispatch0(void_stmt));
- %*/
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
}
| stmt_or_begin
{
/*%%%*/
$$ = newline_node($1);
- /*%
- $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
- %*/
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, $1) %*/
}
| stmts terms stmt_or_begin
{
/*%%%*/
- $$ = block_append($1, newline_node($3));
- /*%
- $$ = dispatch2(stmts_add, $1, $3);
- %*/
+ $$ = block_append(p, $1, newline_node($3));
+ /*% %*/
+ /*% ripper: stmts_add!($1, $3) %*/
}
| error stmt
{
@@ -1162,41 +1457,27 @@ stmt_or_begin : stmt
}
| keyword_BEGIN
{
- yyerror("BEGIN is permitted only at toplevel");
- /*%%%*/
- /* local_push(0); */
- /*%
- %*/
+ yyerror1(&@1, "BEGIN is permitted only at toplevel");
}
- '{' top_compstmt '}'
+ begin_block
{
- /*%%%*/
- ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
- $4);
- /* NEW_PREEXE($4)); */
- /* local_pop(); */
- $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch1(BEGIN, $4);
- %*/
+ $$ = $3;
}
;
stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
{
/*%%%*/
- $$ = NEW_ALIAS($2, $4);
- /*%
- $$ = dispatch2(alias, $2, $4);
- %*/
+ $$ = NEW_ALIAS($2, $4, &@$);
+ /*% %*/
+ /*% ripper: alias!($2, $4) %*/
}
| keyword_alias tGVAR tGVAR
{
/*%%%*/
- $$ = NEW_VALIAS($2, $3);
- /*%
- $$ = dispatch2(var_alias, $2, $3);
- %*/
+ $$ = NEW_VALIAS($2, $3, &@$);
+ /*% %*/
+ /*% ripper: var_alias!($2, $3) %*/
}
| keyword_alias tGVAR tBACK_REF
{
@@ -1204,197 +1485,200 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
char buf[2];
buf[0] = '$';
buf[1] = (char)$3->nd_nth;
- $$ = NEW_VALIAS($2, rb_intern2(buf, 2));
- /*%
- $$ = dispatch2(var_alias, $2, $3);
- %*/
+ $$ = NEW_VALIAS($2, rb_intern2(buf, 2), &@$);
+ /*% %*/
+ /*% ripper: var_alias!($2, $3) %*/
}
| keyword_alias tGVAR tNTH_REF
{
+ static const char mesg[] = "can't make alias for the number variables";
/*%%%*/
- yyerror("can't make alias for the number variables");
- $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch2(var_alias, $2, $3);
- $$ = dispatch1(alias_error, $$);
- ripper_error();
- %*/
+ yyerror1(&@3, mesg);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: alias_error!(ERR_MESG(), $3) %*/
}
| keyword_undef undef_list
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(undef, $2);
- %*/
+ /*% %*/
+ /*% ripper: undef!($2) %*/
}
| stmt modifier_if expr_value
{
/*%%%*/
- $$ = new_if($3, remove_begin($1), 0);
+ $$ = new_if(p, $3, remove_begin($1), 0, &@$);
fixpos($$, $3);
- /*%
- $$ = dispatch2(if_mod, $3, $1);
- %*/
+ /*% %*/
+ /*% ripper: if_mod!($3, $1) %*/
}
| stmt modifier_unless expr_value
{
/*%%%*/
- $$ = new_unless($3, remove_begin($1), 0);
+ $$ = new_unless(p, $3, remove_begin($1), 0, &@$);
fixpos($$, $3);
- /*%
- $$ = dispatch2(unless_mod, $3, $1);
- %*/
+ /*% %*/
+ /*% ripper: unless_mod!($3, $1) %*/
}
| stmt modifier_while expr_value
{
/*%%%*/
if ($1 && nd_type($1) == NODE_BEGIN) {
- $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
+ $$ = NEW_WHILE(cond(p, $3, &@3), $1->nd_body, 0, &@$);
}
else {
- $$ = NEW_WHILE(cond($3), $1, 1);
+ $$ = NEW_WHILE(cond(p, $3, &@3), $1, 1, &@$);
}
- /*%
- $$ = dispatch2(while_mod, $3, $1);
- %*/
+ /*% %*/
+ /*% ripper: while_mod!($3, $1) %*/
}
| stmt modifier_until expr_value
{
/*%%%*/
if ($1 && nd_type($1) == NODE_BEGIN) {
- $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
+ $$ = NEW_UNTIL(cond(p, $3, &@3), $1->nd_body, 0, &@$);
}
else {
- $$ = NEW_UNTIL(cond($3), $1, 1);
+ $$ = NEW_UNTIL(cond(p, $3, &@3), $1, 1, &@$);
}
- /*%
- $$ = dispatch2(until_mod, $3, $1);
- %*/
+ /*% %*/
+ /*% ripper: until_mod!($3, $1) %*/
}
| stmt modifier_rescue stmt
{
/*%%%*/
- NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
- $$ = NEW_RESCUE(remove_begin($1), resq, 0);
- /*%
- $$ = dispatch2(rescue_mod, $1, $3);
- %*/
+ NODE *resq;
+ YYLTYPE loc = code_loc_gen(&@2, &@3);
+ resq = NEW_RESBODY(0, remove_begin($3), 0, &loc);
+ $$ = NEW_RESCUE(remove_begin($1), resq, 0, &@$);
+ /*% %*/
+ /*% ripper: rescue_mod!($1, $3) %*/
}
| keyword_END '{' compstmt '}'
{
- if (in_def || in_single) {
+ if (p->ctxt.in_def) {
rb_warn0("END in method; use at_exit");
}
/*%%%*/
- $$ = NEW_POSTEXE(NEW_NODE(
- NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */));
- /*%
- $$ = dispatch1(END, $3);
- %*/
+ {
+ NODE *scope = NEW_NODE(
+ NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */, &@$);
+ $$ = NEW_POSTEXE(scope, &@$);
+ }
+ /*% %*/
+ /*% ripper: END!($3) %*/
}
| command_asgn
- | mlhs '=' command_call
+ | mlhs '=' lex_ctxt command_call
{
/*%%%*/
- value_expr($3);
- $1->nd_value = $3;
- $$ = $1;
- /*%
- $$ = dispatch2(massign, $1, $3);
- %*/
+ value_expr($4);
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: massign!($1, $4) %*/
}
- | lhs '=' mrhs
+ | lhs '=' lex_ctxt mrhs
{
- value_expr($3);
- $$ = node_assign($1, $3);
+ /*%%%*/
+ value_expr($4);
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: assign!($1, $4) %*/
}
- | mlhs '=' mrhs_arg
+ | mlhs '=' lex_ctxt mrhs_arg modifier_rescue stmt
+ {
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@5, &@6);
+ value_expr($4);
+ $$ = node_assign(p, $1, NEW_RESCUE($4, NEW_RESBODY(0, remove_begin($6), 0, &loc), 0, &@$), $3, &@$);
+ /*% %*/
+ /*% ripper: massign!($1, rescue_mod!($4, $6)) %*/
+ }
+ | mlhs '=' lex_ctxt mrhs_arg
{
/*%%%*/
- $1->nd_value = $3;
- $$ = $1;
- /*%
- $$ = dispatch2(massign, $1, $3);
- %*/
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: massign!($1, $4) %*/
}
| expr
;
-command_asgn : lhs '=' command_rhs
+command_asgn : lhs '=' lex_ctxt command_rhs
{
- value_expr($3);
- $$ = node_assign($1, $3);
+ /*%%%*/
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: assign!($1, $4) %*/
}
- | var_lhs tOP_ASGN command_rhs
+ | var_lhs tOP_ASGN lex_ctxt command_rhs
{
- value_expr($3);
- $$ = new_op_assign($1, $2, $3);
+ /*%%%*/
+ $$ = new_op_assign(p, $1, $2, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: opassign!($1, $2, $4) %*/
}
- | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs
+ | primary_value '[' opt_call_args rbracket tOP_ASGN lex_ctxt command_rhs
{
/*%%%*/
- NODE *args;
+ $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$);
+ /*% %*/
+ /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
- value_expr($6);
- if (!$3) $3 = NEW_ZARRAY();
- args = arg_concat($3, $6);
- if ($5 == tOROP) {
- $5 = 0;
- }
- else if ($5 == tANDOP) {
- $5 = 1;
- }
- $$ = NEW_OP_ASGN1($1, $5, args);
- fixpos($$, $1);
- /*%
- $$ = dispatch2(aref_field, $1, escape_Qundef($3));
- $$ = dispatch3(opassign, $$, $5, $6);
- %*/
}
- | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
+ | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
{
- value_expr($5);
- $$ = new_attr_op_assign($1, $2, $3, $4, $5);
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
}
- | primary_value call_op tCONSTANT tOP_ASGN command_rhs
+ | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt command_rhs
{
- value_expr($5);
- $$ = new_attr_op_assign($1, $2, $3, $4, $5);
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
}
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt command_rhs
{
- $$ = const_path_field($1, $3);
- $$ = new_const_op_assign($$, $4, $5);
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ $$ = new_const_op_assign(p, NEW_COLON2($1, $3, &loc), $4, $6, $5, &@$);
+ /*% %*/
+ /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
}
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
{
- value_expr($5);
- $$ = new_attr_op_assign($1, ID2VAL(idCOLON2), $3, $4, $5);
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, ID2VAL(idCOLON2), $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, ID2VAL(idCOLON2), $3), $4, $6) %*/
}
- | backref tOP_ASGN command_rhs
+ | backref tOP_ASGN lex_ctxt command_rhs
{
- $1 = var_field($1);
- $$ = backref_assign_error($1, node_assign($1, $3));
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), assign!(var_field(p, $1), $4)) %*/
}
;
command_rhs : command_call %prec tOP_ASGN
{
- /*%%%*/
value_expr($1);
$$ = $1;
- /*%
- %*/
}
| command_call modifier_rescue stmt
{
/*%%%*/
+ YYLTYPE loc = code_loc_gen(&@2, &@3);
value_expr($1);
- $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($3), 0), 0);
- /*%
- $$ = dispatch2(rescue_mod, $1, $3);
- %*/
+ $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($3), 0, &loc), 0, &@$);
+ /*% %*/
+ /*% ripper: rescue_mod!($1, $3) %*/
}
| command_asgn
;
@@ -1402,35 +1686,114 @@ command_rhs : command_call %prec tOP_ASGN
expr : command_call
| expr keyword_and expr
{
- $$ = logop(idAND, $1, $3);
+ $$ = logop(p, idAND, $1, $3, &@2, &@$);
}
| expr keyword_or expr
{
- $$ = logop(idOR, $1, $3);
+ $$ = logop(p, idOR, $1, $3, &@2, &@$);
}
| keyword_not opt_nl expr
{
- $$ = call_uni_op(method_cond($3), METHOD_NOT);
+ $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
}
| '!' command_call
{
- $$ = call_uni_op(method_cond($2), '!');
+ $$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
}
- | arg
+ | arg tASSOC
+ {
+ value_expr($1);
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<ctxt>$ = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ }
+ {$<tbl>$ = push_pvtbl(p);}
+ p_expr
+ {pop_pvtbl(p, $<tbl>4);}
+ {
+ p->ctxt.in_kwarg = $<ctxt>3.in_kwarg;
+ /*%%%*/
+ $$ = NEW_CASE3($1, NEW_IN($5, 0, 0, &@5), &@$);
+ warn_one_line_pattern_matching(p, $$, $5, true);
+ /*% %*/
+ /*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/
+ }
+ | arg keyword_in
+ {
+ value_expr($1);
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<ctxt>$ = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ }
+ {$<tbl>$ = push_pvtbl(p);}
+ p_expr
+ {pop_pvtbl(p, $<tbl>4);}
+ {
+ p->ctxt.in_kwarg = $<ctxt>3.in_kwarg;
+ /*%%%*/
+ $$ = NEW_CASE3($1, NEW_IN($5, NEW_TRUE(&@5), NEW_FALSE(&@5), &@5), &@$);
+ warn_one_line_pattern_matching(p, $$, $5, false);
+ /*% %*/
+ /*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/
+ }
+ | arg %prec tLBRACE_ARG
;
-expr_value : expr
+def_name : fname
{
+ ID fname = get_id($1);
+ ID cur_arg = p->cur_arg;
+ YYSTYPE c = {.ctxt = p->ctxt};
+ numparam_name(p, fname);
+ local_push(p, 0);
+ p->cur_arg = 0;
+ p->ctxt.in_def = 1;
+ $<node>$ = NEW_NODE(NODE_SELF, /*vid*/cur_arg, /*mid*/fname, /*cval*/c.val, &@$);
/*%%%*/
- value_expr($1);
- $$ = $1;
- if (!$$) $$ = NEW_NIL();
/*%
- $$ = $1;
+ $$ = NEW_RIPPER(fname, get_value($1), $$, &NULL_LOC);
+ %*/
+ }
+ ;
+
+defn_head : k_def def_name
+ {
+ $$ = $2;
+ /*%%%*/
+ $$ = NEW_NODE(NODE_DEFN, 0, $$->nd_mid, $$, &@$);
+ /*% %*/
+ }
+ ;
+
+defs_head : k_def singleton dot_or_colon {SET_LEX_STATE(EXPR_FNAME);} def_name
+ {
+ SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); /* force for args */
+ $$ = $5;
+ /*%%%*/
+ $$ = NEW_NODE(NODE_DEFS, $2, $$->nd_mid, $$, &@$);
+ /*%
+ VALUE ary = rb_ary_new_from_args(3, $2, $3, get_value($$));
+ add_mark_object(p, ary);
+ $<node>$->nd_rval = ary;
%*/
}
;
+expr_value : expr
+ {
+ value_expr($1);
+ $$ = $1;
+ }
+ ;
+
+expr_value_do : {COND_PUSH(1);} expr_value do {COND_POP();}
+ {
+ $$ = $2;
+ }
+
+
command_call : command
| block_command
;
@@ -1438,22 +1801,19 @@ command_call : command
block_command : block_call
| block_call call_op2 operation2 command_args
{
- $$ = new_qcall($2, $1, $3, $4);
+ /*%%%*/
+ $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, $2, $3), $4) %*/
}
;
-cmd_brace_block : tLBRACE_ARG
- {
- /*%%%*/
- $<num>$ = ruby_sourceline;
- /*%
- %*/
- }
- brace_body '}'
+cmd_brace_block : tLBRACE_ARG brace_body '}'
{
- $$ = $3;
+ $$ = $2;
/*%%%*/
- nd_set_line($$, $<num>2);
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
/*% %*/
}
;
@@ -1461,94 +1821,97 @@ cmd_brace_block : tLBRACE_ARG
fcall : operation
{
/*%%%*/
- $$ = NEW_FCALL($1, 0);
- nd_set_line($$, tokline);
- /*%
- %*/
+ $$ = NEW_FCALL($1, 0, &@$);
+ nd_set_line($$, p->tokline);
+ /*% %*/
+ /*% ripper: $1 %*/
}
;
command : fcall command_args %prec tLOWEST
{
/*%%%*/
+ $1->nd_args = $2;
+ nd_set_last_loc($1, @2.end_pos);
$$ = $1;
- $$->nd_args = $2;
- /*%
- $$ = dispatch2(command, $1, $2);
- %*/
+ /*% %*/
+ /*% ripper: command!($1, $2) %*/
}
| fcall command_args cmd_brace_block
{
- block_dup_check($2,$3);
- $$ = new_command($1, $2);
- $$ = method_add_block($$, $3);
+ /*%%%*/
+ block_dup_check(p, $2, $3);
+ $1->nd_args = $2;
+ $$ = method_add_block(p, $1, $3, &@$);
fixpos($$, $1);
+ nd_set_last_loc($1, @2.end_pos);
+ /*% %*/
+ /*% ripper: method_add_block!(command!($1, $2), $3) %*/
}
| primary_value call_op operation2 command_args %prec tLOWEST
{
- $$ = new_command_qcall($2, $1, $3, $4);
- fixpos($$, $1);
+ /*%%%*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, Qnull, &@3, &@$);
+ /*% %*/
+ /*% ripper: command_call!($1, $2, $3, $4) %*/
}
| primary_value call_op operation2 command_args cmd_brace_block
{
- block_dup_check($4,$5);
- $$ = new_command_qcall($2, $1, $3, $4);
- $$ = method_add_block($$, $5);
- fixpos($$, $1);
- }
+ /*%%%*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
+ }
| primary_value tCOLON2 operation2 command_args %prec tLOWEST
{
- $$ = new_command_qcall(ID2VAL(idCOLON2), $1, $3, $4);
- fixpos($$, $1);
+ /*%%%*/
+ $$ = new_command_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, Qnull, &@3, &@$);
+ /*% %*/
+ /*% ripper: command_call!($1, ID2VAL(idCOLON2), $3, $4) %*/
}
| primary_value tCOLON2 operation2 command_args cmd_brace_block
{
- block_dup_check($4,$5);
- $$ = new_command_qcall(ID2VAL(idCOLON2), $1, $3, $4);
- $$ = method_add_block($$, $5);
- fixpos($$, $1);
+ /*%%%*/
+ $$ = new_command_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(command_call!($1, ID2VAL(idCOLON2), $3, $4), $5) %*/
}
| keyword_super command_args
{
/*%%%*/
- $$ = NEW_SUPER($2);
+ $$ = NEW_SUPER($2, &@$);
fixpos($$, $2);
- /*%
- $$ = dispatch1(super, $2);
- %*/
+ /*% %*/
+ /*% ripper: super!($2) %*/
}
| keyword_yield command_args
{
/*%%%*/
- $$ = new_yield($2);
+ $$ = new_yield(p, $2, &@$);
fixpos($$, $2);
- /*%
- $$ = dispatch1(yield, $2);
- %*/
+ /*% %*/
+ /*% ripper: yield!($2) %*/
}
- | keyword_return call_args
+ | k_return call_args
{
/*%%%*/
- $$ = NEW_RETURN(ret_args($2));
- /*%
- $$ = dispatch1(return, $2);
- %*/
+ $$ = NEW_RETURN(ret_args(p, $2), &@$);
+ /*% %*/
+ /*% ripper: return!($2) %*/
}
| keyword_break call_args
{
/*%%%*/
- $$ = NEW_BREAK(ret_args($2));
- /*%
- $$ = dispatch1(break, $2);
- %*/
+ $$ = NEW_BREAK(ret_args(p, $2), &@$);
+ /*% %*/
+ /*% ripper: break!($2) %*/
}
| keyword_next call_args
{
/*%%%*/
- $$ = NEW_NEXT(ret_args($2));
- /*%
- $$ = dispatch1(next, $2);
- %*/
+ $$ = NEW_NEXT(ret_args(p, $2), &@$);
+ /*% %*/
+ /*% ripper: next!($2) %*/
}
;
@@ -1557,9 +1920,8 @@ mlhs : mlhs_basic
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(mlhs_paren, $2);
- %*/
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
}
;
@@ -1567,96 +1929,81 @@ mlhs_inner : mlhs_basic
| tLPAREN mlhs_inner rparen
{
/*%%%*/
- $$ = NEW_MASGN(NEW_LIST($2), 0);
- /*%
- $$ = dispatch1(mlhs_paren, $2);
- %*/
+ $$ = NEW_MASGN(NEW_LIST($2, &@$), 0, &@$);
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
}
;
mlhs_basic : mlhs_head
{
/*%%%*/
- $$ = NEW_MASGN($1, 0);
- /*%
- $$ = $1;
- %*/
+ $$ = NEW_MASGN($1, 0, &@$);
+ /*% %*/
+ /*% ripper: $1 %*/
}
| mlhs_head mlhs_item
{
/*%%%*/
- $$ = NEW_MASGN(list_append($1,$2), 0);
- /*%
- $$ = mlhs_add($1, $2);
- %*/
+ $$ = NEW_MASGN(list_append(p, $1,$2), 0, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $2) %*/
}
| mlhs_head tSTAR mlhs_node
{
/*%%%*/
- $$ = NEW_MASGN($1, $3);
- /*%
- $$ = mlhs_add_star($1, $3);
- %*/
+ $$ = NEW_MASGN($1, $3, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!($1, $3) %*/
}
| mlhs_head tSTAR mlhs_node ',' mlhs_post
{
/*%%%*/
- $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
- /*%
- $1 = mlhs_add_star($1, $3);
- $$ = mlhs_add_post($1, $5);
- %*/
+ $$ = NEW_MASGN($1, NEW_POSTARG($3,$5,&@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
}
| mlhs_head tSTAR
{
/*%%%*/
- $$ = NEW_MASGN($1, -1);
- /*%
- $$ = mlhs_add_star($1, Qnil);
- %*/
+ $$ = NEW_MASGN($1, NODE_SPECIAL_NO_NAME_REST, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!($1, Qnil) %*/
}
| mlhs_head tSTAR ',' mlhs_post
{
/*%%%*/
- $$ = NEW_MASGN($1, NEW_POSTARG(-1, $4));
- /*%
- $1 = mlhs_add_star($1, Qnil);
- $$ = mlhs_add_post($1, $4);
- %*/
+ $$ = NEW_MASGN($1, NEW_POSTARG(NODE_SPECIAL_NO_NAME_REST, $4, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!($1, Qnil), $4) %*/
}
| tSTAR mlhs_node
{
/*%%%*/
- $$ = NEW_MASGN(0, $2);
- /*%
- $$ = mlhs_add_star(mlhs_new(), $2);
- %*/
+ $$ = NEW_MASGN(0, $2, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!(mlhs_new!, $2) %*/
}
| tSTAR mlhs_node ',' mlhs_post
{
/*%%%*/
- $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
- /*%
- $2 = mlhs_add_star(mlhs_new(), $2);
- $$ = mlhs_add_post($2, $4);
- %*/
+ $$ = NEW_MASGN(0, NEW_POSTARG($2,$4,&@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $2), $4) %*/
}
| tSTAR
{
/*%%%*/
- $$ = NEW_MASGN(0, -1);
- /*%
- $$ = mlhs_add_star(mlhs_new(), Qnil);
- %*/
+ $$ = NEW_MASGN(0, NODE_SPECIAL_NO_NAME_REST, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!(mlhs_new!, Qnil) %*/
}
| tSTAR ',' mlhs_post
{
/*%%%*/
- $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
- /*%
- $$ = mlhs_add_star(mlhs_new(), Qnil);
- $$ = mlhs_add_post($$, $3);
- %*/
+ $$ = NEW_MASGN(0, NEW_POSTARG(NODE_SPECIAL_NO_NAME_REST, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, Qnil), $3) %*/
}
;
@@ -1665,174 +2012,188 @@ mlhs_item : mlhs_node
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(mlhs_paren, $2);
- %*/
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
}
;
mlhs_head : mlhs_item ','
{
/*%%%*/
- $$ = NEW_LIST($1);
- /*%
- $$ = mlhs_add(mlhs_new(), $1);
- %*/
+ $$ = NEW_LIST($1, &@1);
+ /*% %*/
+ /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
}
| mlhs_head mlhs_item ','
{
/*%%%*/
- $$ = list_append($1, $2);
- /*%
- $$ = mlhs_add($1, $2);
- %*/
+ $$ = list_append(p, $1, $2);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $2) %*/
}
;
mlhs_post : mlhs_item
{
/*%%%*/
- $$ = NEW_LIST($1);
- /*%
- $$ = mlhs_add(mlhs_new(), $1);
- %*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
}
| mlhs_post ',' mlhs_item
{
/*%%%*/
- $$ = list_append($1, $3);
- /*%
- $$ = mlhs_add($1, $3);
- %*/
+ $$ = list_append(p, $1, $3);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $3) %*/
}
;
mlhs_node : user_variable
{
- $$ = assignable(var_field($1), 0);
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
}
| keyword_variable
{
- $$ = assignable(var_field($1), 0);
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
}
| primary_value '[' opt_call_args rbracket
{
/*%%%*/
- $$ = aryset($1, $3);
- /*%
- $$ = dispatch2(aref_field, $1, escape_Qundef($3));
- %*/
+ $$ = aryset(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
}
| primary_value call_op tIDENTIFIER
{
+ if ($2 == tANDDOT) {
+ yyerror1(&@2, "&. inside multiple assignment destination");
+ }
/*%%%*/
- $$ = attrset($1, $2, $3);
- /*%
- $$ = dispatch3(field, $1, $2, $3);
- %*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
}
| primary_value tCOLON2 tIDENTIFIER
{
/*%%%*/
- $$ = attrset($1, idCOLON2, $3);
- /*%
- $$ = dispatch2(const_path_field, $1, $3);
- %*/
+ $$ = attrset(p, $1, idCOLON2, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_field!($1, $3) %*/
}
| primary_value call_op tCONSTANT
{
+ if ($2 == tANDDOT) {
+ yyerror1(&@2, "&. inside multiple assignment destination");
+ }
/*%%%*/
- $$ = attrset($1, $2, $3);
- /*%
- $$ = dispatch3(field, $1, $2, $3);
- %*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
}
| primary_value tCOLON2 tCONSTANT
{
- $$ = const_decl(const_path_field($1, $3));
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
}
| tCOLON3 tCONSTANT
{
- $$ = const_decl(top_const_field($2));
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, top_const_field!($2)) %*/
}
| backref
{
- $1 = var_field($1);
- $$ = backref_assign_error($1, $1);
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
}
;
lhs : user_variable
{
- $$ = assignable(var_field($1), 0);
/*%%%*/
- if (!$$) $$ = NEW_BEGIN(0);
- /*%
- %*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
}
| keyword_variable
{
- $$ = assignable(var_field($1), 0);
/*%%%*/
- if (!$$) $$ = NEW_BEGIN(0);
- /*%
- %*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
}
| primary_value '[' opt_call_args rbracket
{
/*%%%*/
- $$ = aryset($1, $3);
- /*%
- $$ = dispatch2(aref_field, $1, escape_Qundef($3));
- %*/
+ $$ = aryset(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
}
| primary_value call_op tIDENTIFIER
{
/*%%%*/
- $$ = attrset($1, $2, $3);
- /*%
- $$ = dispatch3(field, $1, $2, $3);
- %*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
}
| primary_value tCOLON2 tIDENTIFIER
{
/*%%%*/
- $$ = attrset($1, idCOLON2, $3);
- /*%
- $$ = dispatch3(field, $1, ID2VAL(idCOLON2), $3);
- %*/
+ $$ = attrset(p, $1, idCOLON2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, ID2VAL(idCOLON2), $3) %*/
}
| primary_value call_op tCONSTANT
{
/*%%%*/
- $$ = attrset($1, $2, $3);
- /*%
- $$ = dispatch3(field, $1, $2, $3);
- %*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
}
| primary_value tCOLON2 tCONSTANT
{
- $$ = const_decl(const_path_field($1, $3));
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
}
| tCOLON3 tCONSTANT
{
- $$ = const_decl(top_const_field($2));
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, top_const_field!($2)) %*/
}
| backref
{
- $1 = var_field($1);
- $$ = backref_assign_error($1, $1);
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
}
;
cname : tIDENTIFIER
{
+ static const char mesg[] = "class/module name must be CONSTANT";
/*%%%*/
- yyerror("class/module name must be CONSTANT");
- /*%
- $$ = dispatch1(class_name_error, $1);
- ripper_error();
- %*/
+ yyerror1(&@1, mesg);
+ /*% %*/
+ /*% ripper[error]: class_name_error!(ERR_MESG(), $1) %*/
}
| tCONSTANT
;
@@ -1840,26 +2201,23 @@ cname : tIDENTIFIER
cpath : tCOLON3 cname
{
/*%%%*/
- $$ = NEW_COLON3($2);
- /*%
- $$ = dispatch1(top_const_ref, $2);
- %*/
+ $$ = NEW_COLON3($2, &@$);
+ /*% %*/
+ /*% ripper: top_const_ref!($2) %*/
}
| cname
{
/*%%%*/
- $$ = NEW_COLON2(0, $$);
- /*%
- $$ = dispatch1(const_ref, $1);
- %*/
+ $$ = NEW_COLON2(0, $$, &@$);
+ /*% %*/
+ /*% ripper: const_ref!($1) %*/
}
| primary_value tCOLON2 cname
{
/*%%%*/
- $$ = NEW_COLON2($1, $3);
- /*%
- $$ = dispatch2(const_path_ref, $1, $3);
- %*/
+ $$ = NEW_COLON2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_ref!($1, $3) %*/
}
;
@@ -1872,42 +2230,32 @@ fname : tIDENTIFIER
$$ = $1;
}
| reswords
- {
- SET_LEX_STATE(EXPR_ENDFN);
- $$ = $1;
- }
- ;
-
-fsym : fname
- | symbol
;
-fitem : fsym
+fitem : fname
{
/*%%%*/
- $$ = NEW_LIT(ID2SYM($1));
- /*%
- $$ = dispatch1(symbol_literal, $1);
- %*/
+ $$ = NEW_LIT(ID2SYM($1), &@$);
+ /*% %*/
+ /*% ripper: symbol_literal!($1) %*/
}
- | dsym
+ | symbol
;
undef_list : fitem
{
/*%%%*/
- $$ = NEW_UNDEF($1);
- /*%
- $$ = rb_ary_new3(1, get_value($1));
- %*/
+ $$ = NEW_UNDEF($1, &@$);
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
}
| undef_list ',' {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
{
/*%%%*/
- $$ = block_append($1, NEW_UNDEF($4));
- /*%
- rb_ary_push($1, get_value($4));
- %*/
+ NODE *undef = NEW_UNDEF($4, &@4);
+ $$ = block_append(p, $1, undef);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($4)) %*/
}
;
@@ -1957,220 +2305,277 @@ reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
| keyword_while | keyword_until
;
-arg : lhs '=' arg_rhs
+arg : lhs '=' lex_ctxt arg_rhs
{
- $$ = node_assign($1, $3);
+ /*%%%*/
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: assign!($1, $4) %*/
}
- | var_lhs tOP_ASGN arg_rhs
+ | var_lhs tOP_ASGN lex_ctxt arg_rhs
{
- $$ = new_op_assign($1, $2, $3);
+ /*%%%*/
+ $$ = new_op_assign(p, $1, $2, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: opassign!($1, $2, $4) %*/
}
- | primary_value '[' opt_call_args rbracket tOP_ASGN arg_rhs
+ | primary_value '[' opt_call_args rbracket tOP_ASGN lex_ctxt arg_rhs
{
/*%%%*/
- NODE *args;
-
- value_expr($6);
- if (!$3) $3 = NEW_ZARRAY();
- if (nd_type($3) == NODE_BLOCK_PASS) {
- args = NEW_ARGSCAT($3, $6);
- }
- else {
- args = arg_concat($3, $6);
- }
- if ($5 == tOROP) {
- $5 = 0;
- }
- else if ($5 == tANDOP) {
- $5 = 1;
- }
- $$ = NEW_OP_ASGN1($1, $5, args);
- fixpos($$, $1);
- /*%
- $1 = dispatch2(aref_field, $1, escape_Qundef($3));
- $$ = dispatch3(opassign, $1, $5, $6);
- %*/
+ $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$);
+ /*% %*/
+ /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
}
- | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
+ | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
{
- value_expr($5);
- $$ = new_attr_op_assign($1, $2, $3, $4, $5);
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
}
- | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
+ | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt arg_rhs
{
- value_expr($5);
- $$ = new_attr_op_assign($1, $2, $3, $4, $5);
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
}
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
{
- value_expr($5);
- $$ = new_attr_op_assign($1, ID2VAL(idCOLON2), $3, $4, $5);
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, ID2VAL(idCOLON2), $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, ID2VAL(idCOLON2), $3), $4, $6) %*/
}
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
{
- $$ = const_path_field($1, $3);
- $$ = new_const_op_assign($$, $4, $5);
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ $$ = new_const_op_assign(p, NEW_COLON2($1, $3, &loc), $4, $6, $5, &@$);
+ /*% %*/
+ /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
}
- | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
+ | tCOLON3 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
{
- $$ = top_const_field($2);
- $$ = new_const_op_assign($$, $3, $4);
+ /*%%%*/
+ $$ = new_const_op_assign(p, NEW_COLON3($2, &@$), $3, $5, $4, &@$);
+ /*% %*/
+ /*% ripper: opassign!(top_const_field!($2), $3, $5) %*/
}
- | backref tOP_ASGN arg_rhs
+ | backref tOP_ASGN lex_ctxt arg_rhs
{
- $1 = var_field($1);
- $$ = backref_assign_error($1, new_op_assign($1, $2, $3));
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), opassign!(var_field(p, $1), $2, $4)) %*/
}
| arg tDOT2 arg
{
/*%%%*/
value_expr($1);
value_expr($3);
- $$ = NEW_DOT2($1, $3);
- /*%
- $$ = dispatch2(dot2, $1, $3);
- %*/
+ $$ = NEW_DOT2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, $3) %*/
}
| arg tDOT3 arg
{
/*%%%*/
value_expr($1);
value_expr($3);
- $$ = NEW_DOT3($1, $3);
- /*%
- $$ = dispatch2(dot3, $1, $3);
- %*/
+ $$ = NEW_DOT3($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, $3) %*/
+ }
+ | arg tDOT2
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT2($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, Qnil) %*/
+ }
+ | arg tDOT3
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT3($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, Qnil) %*/
+ }
+ | tBDOT2 arg
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT2(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot2!(Qnil, $2) %*/
+ }
+ | tBDOT3 arg
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT3(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot3!(Qnil, $2) %*/
}
| arg '+' arg
{
- $$ = call_bin_op($1, '+', $3);
+ $$ = call_bin_op(p, $1, '+', $3, &@2, &@$);
}
| arg '-' arg
{
- $$ = call_bin_op($1, '-', $3);
+ $$ = call_bin_op(p, $1, '-', $3, &@2, &@$);
}
| arg '*' arg
{
- $$ = call_bin_op($1, '*', $3);
+ $$ = call_bin_op(p, $1, '*', $3, &@2, &@$);
}
| arg '/' arg
{
- $$ = call_bin_op($1, '/', $3);
+ $$ = call_bin_op(p, $1, '/', $3, &@2, &@$);
}
| arg '%' arg
{
- $$ = call_bin_op($1, '%', $3);
+ $$ = call_bin_op(p, $1, '%', $3, &@2, &@$);
}
| arg tPOW arg
{
- $$ = call_bin_op($1, idPow, $3);
+ $$ = call_bin_op(p, $1, idPow, $3, &@2, &@$);
}
| tUMINUS_NUM simple_numeric tPOW arg
{
- $$ = call_uni_op(call_bin_op($2, idPow, $4), idUMinus);
+ $$ = call_uni_op(p, call_bin_op(p, $2, idPow, $4, &@2, &@$), idUMinus, &@1, &@$);
}
| tUPLUS arg
{
- $$ = call_uni_op($2, idUPlus);
+ $$ = call_uni_op(p, $2, idUPlus, &@1, &@$);
}
| tUMINUS arg
{
- $$ = call_uni_op($2, idUMinus);
+ $$ = call_uni_op(p, $2, idUMinus, &@1, &@$);
}
| arg '|' arg
{
- $$ = call_bin_op($1, '|', $3);
+ $$ = call_bin_op(p, $1, '|', $3, &@2, &@$);
}
| arg '^' arg
{
- $$ = call_bin_op($1, '^', $3);
+ $$ = call_bin_op(p, $1, '^', $3, &@2, &@$);
}
| arg '&' arg
{
- $$ = call_bin_op($1, '&', $3);
+ $$ = call_bin_op(p, $1, '&', $3, &@2, &@$);
}
| arg tCMP arg
{
- $$ = call_bin_op($1, idCmp, $3);
- }
- | arg '>' arg
- {
- $$ = call_bin_op($1, '>', $3);
- }
- | arg tGEQ arg
- {
- $$ = call_bin_op($1, idGE, $3);
- }
- | arg '<' arg
- {
- $$ = call_bin_op($1, '<', $3);
- }
- | arg tLEQ arg
- {
- $$ = call_bin_op($1, idLE, $3);
+ $$ = call_bin_op(p, $1, idCmp, $3, &@2, &@$);
}
+ | rel_expr %prec tCMP
| arg tEQ arg
{
- $$ = call_bin_op($1, idEq, $3);
+ $$ = call_bin_op(p, $1, idEq, $3, &@2, &@$);
}
| arg tEQQ arg
{
- $$ = call_bin_op($1, idEqq, $3);
+ $$ = call_bin_op(p, $1, idEqq, $3, &@2, &@$);
}
| arg tNEQ arg
{
- $$ = call_bin_op($1, idNeq, $3);
+ $$ = call_bin_op(p, $1, idNeq, $3, &@2, &@$);
}
| arg tMATCH arg
{
- $$ = match_op($1, $3);
+ $$ = match_op(p, $1, $3, &@2, &@$);
}
| arg tNMATCH arg
{
- $$ = call_bin_op($1, idNeqTilde, $3);
+ $$ = call_bin_op(p, $1, idNeqTilde, $3, &@2, &@$);
}
| '!' arg
{
- $$ = call_uni_op(method_cond($2), '!');
+ $$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
}
| '~' arg
{
- $$ = call_uni_op($2, '~');
+ $$ = call_uni_op(p, $2, '~', &@1, &@$);
}
| arg tLSHFT arg
{
- $$ = call_bin_op($1, idLTLT, $3);
+ $$ = call_bin_op(p, $1, idLTLT, $3, &@2, &@$);
}
| arg tRSHFT arg
{
- $$ = call_bin_op($1, idGTGT, $3);
+ $$ = call_bin_op(p, $1, idGTGT, $3, &@2, &@$);
}
| arg tANDOP arg
{
- $$ = logop(idANDOP, $1, $3);
+ $$ = logop(p, idANDOP, $1, $3, &@2, &@$);
}
| arg tOROP arg
{
- $$ = logop(idOROP, $1, $3);
+ $$ = logop(p, idOROP, $1, $3, &@2, &@$);
}
- | keyword_defined opt_nl {in_defined = 1;} arg
+ | keyword_defined opt_nl {p->ctxt.in_defined = 1;} arg
{
- in_defined = 0;
- /*%%%*/
- $$ = new_defined($4);
- /*%
- $$ = dispatch1(defined, $4);
- %*/
+ p->ctxt.in_defined = 0;
+ $$ = new_defined(p, $4, &@$);
}
| arg '?' arg opt_nl ':' arg
{
/*%%%*/
value_expr($1);
- $$ = new_if($1, $3, $6);
+ $$ = new_if(p, $1, $3, $6, &@$);
fixpos($$, $1);
+ /*% %*/
+ /*% ripper: ifop!($1, $3, $6) %*/
+ }
+ | defn_head f_opt_paren_args '=' arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*% %*/
+ /*% ripper: def!(get_value($1), $2, $4) %*/
+ local_pop(p);
+ }
+ | defn_head f_opt_paren_args '=' arg modifier_rescue arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6);
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*% %*/
+ /*% ripper: def!(get_value($1), $2, rescue_mod!($4, $6)) %*/
+ local_pop(p);
+ }
+ | defs_head f_opt_paren_args '=' arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
/*%
- $$ = dispatch3(ifop, $1, $3, $6);
+ $1 = get_value($1);
%*/
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
+ local_pop(p);
+ }
+ | defs_head f_opt_paren_args '=' arg modifier_rescue arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6);
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*%
+ $1 = get_value($1);
+ %*/
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, rescue_mod!($4, $6)) %*/
+ local_pop(p);
}
| primary
{
@@ -2178,15 +2583,37 @@ arg : lhs '=' arg_rhs
}
;
+relop : '>' {$$ = '>';}
+ | '<' {$$ = '<';}
+ | tGEQ {$$ = idGE;}
+ | tLEQ {$$ = idLE;}
+ ;
+
+rel_expr : arg relop arg %prec '>'
+ {
+ $$ = call_bin_op(p, $1, $2, $3, &@2, &@$);
+ }
+ | rel_expr relop arg %prec '>'
+ {
+ rb_warning1("comparison '%s' after comparison", WARN_ID($2));
+ $$ = call_bin_op(p, $1, $2, $3, &@2, &@$);
+ }
+ ;
+
+lex_ctxt : tSP
+ {
+ $$ = p->ctxt;
+ }
+ | none
+ {
+ $$ = p->ctxt;
+ }
+ ;
+
arg_value : arg
{
- /*%%%*/
value_expr($1);
$$ = $1;
- if (!$$) $$ = NEW_NIL();
- /*%
- $$ = $1;
- %*/
}
;
@@ -2198,37 +2625,31 @@ aref_args : none
| args ',' assocs trailer
{
/*%%%*/
- $$ = $3 ? arg_append($1, new_hash($3)) : $1;
- /*%
- $$ = arg_add_assocs($1, $3);
- %*/
+ $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
+ /*% %*/
+ /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
}
| assocs trailer
{
/*%%%*/
- $$ = $1 ? NEW_LIST(new_hash($1)) : 0;
- /*%
- $$ = arg_add_assocs(arg_new(), $1);
- %*/
+ $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@$) : 0;
+ /*% %*/
+ /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
}
;
arg_rhs : arg %prec tOP_ASGN
{
- /*%%%*/
value_expr($1);
$$ = $1;
- /*%
- %*/
}
| arg modifier_rescue arg
{
/*%%%*/
value_expr($1);
- $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($3), 0), 0);
- /*%
- $$ = dispatch2(rescue_mod, $1, $3);
- %*/
+ $$ = rescued_expr(p, $1, $3, &@1, &@2, &@3);
+ /*% %*/
+ /*% ripper: rescue_mod!($1, $3) %*/
}
;
@@ -2236,9 +2657,32 @@ paren_args : '(' opt_call_args rparen
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(arg_paren, escape_Qundef($2));
- %*/
+ /*% %*/
+ /*% ripper: arg_paren!(escape_Qundef($2)) %*/
+ }
+ | '(' args ',' args_forward rparen
+ {
+ if (!check_forwarding_args(p)) {
+ $$ = Qnone;
+ }
+ else {
+ /*%%%*/
+ $$ = new_args_forward_call(p, $2, &@4, &@$);
+ /*% %*/
+ /*% ripper: arg_paren!(args_add!($2, $4)) %*/
+ }
+ }
+ | '(' args_forward rparen
+ {
+ if (!check_forwarding_args(p)) {
+ $$ = Qnone;
+ }
+ else {
+ /*%%%*/
+ $$ = new_args_forward_call(p, 0, &@2, &@$);
+ /*% %*/
+ /*% ripper: arg_paren!($2) %*/
+ }
}
;
@@ -2255,18 +2699,16 @@ opt_call_args : none
| args ',' assocs ','
{
/*%%%*/
- $$ = $3 ? arg_append($1, new_hash($3)) : $1;
- /*%
- $$ = arg_add_assocs($1, $3);
- %*/
+ $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
+ /*% %*/
+ /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
}
| assocs ','
{
/*%%%*/
- $$ = $1 ? NEW_LIST(new_hash($1)) : 0;
- /*%
- $$ = arg_add_assocs(arg_new(), $1);
- %*/
+ $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@1) : 0;
+ /*% %*/
+ /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
}
;
@@ -2274,55 +2716,70 @@ call_args : command
{
/*%%%*/
value_expr($1);
- $$ = NEW_LIST($1);
- /*%
- $$ = arg_add(arg_new(), $1);
- %*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: args_add!(args_new!, $1) %*/
}
| args opt_block_arg
{
/*%%%*/
$$ = arg_blk_pass($1, $2);
- /*%
- $$ = arg_add_optblock($1, $2);
- %*/
+ /*% %*/
+ /*% ripper: args_add_block!($1, $2) %*/
}
| assocs opt_block_arg
{
/*%%%*/
- $$ = $1 ? NEW_LIST(new_hash($1)) : 0;
+ $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@1) : 0;
$$ = arg_blk_pass($$, $2);
- /*%
- $$ = arg_add_assocs(arg_new(), $1);
- $$ = arg_add_optblock($$, $2);
- %*/
+ /*% %*/
+ /*% ripper: args_add_block!(args_add!(args_new!, bare_assoc_hash!($1)), $2) %*/
}
| args ',' assocs opt_block_arg
{
/*%%%*/
- $$ = $3 ? arg_append($1, new_hash($3)) : $1;
+ $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
$$ = arg_blk_pass($$, $4);
- /*%
- $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
- %*/
+ /*% %*/
+ /*% ripper: args_add_block!(args_add!($1, bare_assoc_hash!($3)), $4) %*/
}
| block_arg
- /*%c%*/
- /*%c
- {
- $$ = arg_add_block(arg_new(), $1);
- }
- %*/
+ /*% ripper[brace]: args_add_block!(args_new!, $1) %*/
;
command_args : {
- $<val>$ = cmdarg_stack;
+ /* If call_args starts with a open paren '(' or '[',
+ * look-ahead reading of the letters calls CMDARG_PUSH(0),
+ * but the push must be done after CMDARG_PUSH(1).
+ * So this code makes them consistent by first cancelling
+ * the premature CMDARG_PUSH(0), doing CMDARG_PUSH(1),
+ * and finally redoing CMDARG_PUSH(0).
+ */
+ int lookahead = 0;
+ switch (yychar) {
+ case '(': case tLPAREN: case tLPAREN_ARG: case '[': case tLBRACK:
+ lookahead = 1;
+ }
+ if (lookahead) CMDARG_POP();
CMDARG_PUSH(1);
+ if (lookahead) CMDARG_PUSH(0);
}
call_args
{
- /* CMDARG_POP() */
- CMDARG_SET($<val>1);
+ /* call_args can be followed by tLBRACE_ARG (that does CMDARG_PUSH(0) in the lexer)
+ * but the push must be done after CMDARG_POP() in the parser.
+ * So this code does CMDARG_POP() to pop 0 pushed by tLBRACE_ARG,
+ * CMDARG_POP() to pop 1 pushed by command_args,
+ * and CMDARG_PUSH(0) to restore back the flag set by tLBRACE_ARG.
+ */
+ int lookahead = 0;
+ switch (yychar) {
+ case tLBRACE_ARG:
+ lookahead = 1;
+ }
+ if (lookahead) CMDARG_POP();
+ CMDARG_POP();
+ if (lookahead) CMDARG_PUSH(0);
$$ = $2;
}
;
@@ -2330,10 +2787,9 @@ command_args : {
block_arg : tAMPER arg_value
{
/*%%%*/
- $$ = NEW_BLOCK_PASS($2);
- /*%
- $$ = $2;
- %*/
+ $$ = NEW_BLOCK_PASS($2, &@$);
+ /*% %*/
+ /*% ripper: $2 %*/
}
;
@@ -2350,46 +2806,30 @@ opt_block_arg : ',' block_arg
args : arg_value
{
/*%%%*/
- $$ = NEW_LIST($1);
- /*%
- $$ = arg_add(arg_new(), $1);
- %*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: args_add!(args_new!, $1) %*/
}
| tSTAR arg_value
{
/*%%%*/
- $$ = NEW_SPLAT($2);
- /*%
- $$ = arg_add_star(arg_new(), $2);
- %*/
+ $$ = NEW_SPLAT($2, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!(args_new!, $2) %*/
}
| args ',' arg_value
{
/*%%%*/
- NODE *n1;
- if ((n1 = splat_array($1)) != 0) {
- $$ = list_append(n1, $3);
- }
- else {
- $$ = arg_append($1, $3);
- }
- /*%
- $$ = arg_add($1, $3);
- %*/
+ $$ = last_arg_append(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: args_add!($1, $3) %*/
}
| args ',' tSTAR arg_value
{
/*%%%*/
- NODE *n1;
- if ((nd_type($4) == NODE_ARRAY) && (n1 = splat_array($1)) != 0) {
- $$ = list_concat(n1, $4);
- }
- else {
- $$ = arg_concat($1, $4);
- }
- /*%
- $$ = arg_add_star($1, $4);
- %*/
+ $$ = rest_arg_append(p, $1, $4, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!($1, $4) %*/
}
;
@@ -2400,39 +2840,23 @@ mrhs_arg : mrhs
mrhs : args ',' arg_value
{
/*%%%*/
- NODE *n1;
- if ((n1 = splat_array($1)) != 0) {
- $$ = list_append(n1, $3);
- }
- else {
- $$ = arg_append($1, $3);
- }
- /*%
- $$ = mrhs_add(args2mrhs($1), $3);
- %*/
+ $$ = last_arg_append(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: mrhs_add!(mrhs_new_from_args!($1), $3) %*/
}
| args ',' tSTAR arg_value
{
/*%%%*/
- NODE *n1;
- if (nd_type($4) == NODE_ARRAY &&
- (n1 = splat_array($1)) != 0) {
- $$ = list_concat(n1, $4);
- }
- else {
- $$ = arg_concat($1, $4);
- }
- /*%
- $$ = mrhs_add_star(args2mrhs($1), $4);
- %*/
+ $$ = rest_arg_append(p, $1, $4, &@$);
+ /*% %*/
+ /*% ripper: mrhs_add_star!(mrhs_new_from_args!($1), $4) %*/
}
| tSTAR arg_value
{
/*%%%*/
- $$ = NEW_SPLAT($2);
- /*%
- $$ = mrhs_add_star(mrhs_new(), $2);
- %*/
+ $$ = NEW_SPLAT($2, &@$);
+ /*% %*/
+ /*% ripper: mrhs_add_star!(mrhs_new!, $2) %*/
}
;
@@ -2449,190 +2873,145 @@ primary : literal
| tFID
{
/*%%%*/
- $$ = NEW_FCALL($1, 0);
- /*%
- $$ = method_arg(dispatch1(fcall, $1), arg_new());
- %*/
+ $$ = NEW_FCALL($1, 0, &@$);
+ /*% %*/
+ /*% ripper: method_add_arg!(fcall!($1), args_new!) %*/
}
| k_begin
{
- $<val>1 = cmdarg_stack;
- CMDARG_SET(0);
- /*%%%*/
- $<num>$ = ruby_sourceline;
- /*%
- %*/
+ CMDARG_PUSH(0);
}
bodystmt
k_end
{
- CMDARG_SET($<val>1);
+ CMDARG_POP();
/*%%%*/
- if ($3 == NULL) {
- $$ = NEW_NIL();
- }
- else {
- set_line_body($3, $<num>2);
- $$ = NEW_BEGIN($3);
- }
- nd_set_line($$, $<num>2);
- /*%
- $$ = dispatch1(begin, $3);
- %*/
+ set_line_body($3, @1.end_pos.lineno);
+ $$ = NEW_BEGIN($3, &@$);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
+ /*% ripper: begin!($3) %*/
}
| tLPAREN_ARG {SET_LEX_STATE(EXPR_ENDARG);} rparen
{
/*%%%*/
- $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch1(paren, 0);
- %*/
- }
- | tLPAREN_ARG
- {
- $<val>1 = cmdarg_stack;
- CMDARG_SET(0);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: paren!(0) %*/
}
- stmt {SET_LEX_STATE(EXPR_ENDARG);} rparen
+ | tLPAREN_ARG stmt {SET_LEX_STATE(EXPR_ENDARG);} rparen
{
- CMDARG_SET($<val>1);
/*%%%*/
- $$ = $3;
- /*%
- $$ = dispatch1(paren, $3);
- %*/
+ if (nd_type($2) == NODE_SELF) $2->nd_state = 0;
+ $$ = $2;
+ /*% %*/
+ /*% ripper: paren!($2) %*/
}
| tLPAREN compstmt ')'
{
/*%%%*/
+ if (nd_type($2) == NODE_SELF) $2->nd_state = 0;
$$ = $2;
- /*%
- $$ = dispatch1(paren, $2);
- %*/
+ /*% %*/
+ /*% ripper: paren!($2) %*/
}
| primary_value tCOLON2 tCONSTANT
{
/*%%%*/
- $$ = NEW_COLON2($1, $3);
- /*%
- $$ = dispatch2(const_path_ref, $1, $3);
- %*/
+ $$ = NEW_COLON2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_ref!($1, $3) %*/
}
| tCOLON3 tCONSTANT
{
/*%%%*/
- $$ = NEW_COLON3($2);
- /*%
- $$ = dispatch1(top_const_ref, $2);
- %*/
+ $$ = NEW_COLON3($2, &@$);
+ /*% %*/
+ /*% ripper: top_const_ref!($2) %*/
}
| tLBRACK aref_args ']'
{
/*%%%*/
- if ($2 == 0) {
- $$ = NEW_ZARRAY(); /* zero length array*/
- }
- else {
- $$ = $2;
- }
- /*%
- $$ = dispatch1(array, escape_Qundef($2));
- %*/
+ $$ = make_list($2, &@$);
+ /*% %*/
+ /*% ripper: array!(escape_Qundef($2)) %*/
}
| tLBRACE assoc_list '}'
{
/*%%%*/
- $$ = new_hash($2);
- $$->nd_alen = TRUE;
- /*%
- $$ = dispatch1(hash, escape_Qundef($2));
- %*/
+ $$ = new_hash(p, $2, &@$);
+ $$->nd_brace = TRUE;
+ /*% %*/
+ /*% ripper: hash!(escape_Qundef($2)) %*/
}
- | keyword_return
+ | k_return
{
/*%%%*/
- $$ = NEW_RETURN(0);
- /*%
- $$ = dispatch0(return0);
- %*/
+ $$ = NEW_RETURN(0, &@$);
+ /*% %*/
+ /*% ripper: return0! %*/
}
| keyword_yield '(' call_args rparen
{
/*%%%*/
- $$ = new_yield($3);
- /*%
- $$ = dispatch1(yield, dispatch1(paren, $3));
- %*/
+ $$ = new_yield(p, $3, &@$);
+ /*% %*/
+ /*% ripper: yield!(paren!($3)) %*/
}
| keyword_yield '(' rparen
{
/*%%%*/
- $$ = NEW_YIELD(0);
- /*%
- $$ = dispatch1(yield, dispatch1(paren, arg_new()));
- %*/
+ $$ = NEW_YIELD(0, &@$);
+ /*% %*/
+ /*% ripper: yield!(paren!(args_new!)) %*/
}
| keyword_yield
{
/*%%%*/
- $$ = NEW_YIELD(0);
- /*%
- $$ = dispatch0(yield0);
- %*/
+ $$ = NEW_YIELD(0, &@$);
+ /*% %*/
+ /*% ripper: yield0! %*/
}
- | keyword_defined opt_nl '(' {in_defined = 1;} expr rparen
+ | keyword_defined opt_nl '(' {p->ctxt.in_defined = 1;} expr rparen
{
- in_defined = 0;
- /*%%%*/
- $$ = new_defined($5);
- /*%
- $$ = dispatch1(defined, $5);
- %*/
+ p->ctxt.in_defined = 0;
+ $$ = new_defined(p, $5, &@$);
}
| keyword_not '(' expr rparen
{
- $$ = call_uni_op(method_cond($3), METHOD_NOT);
+ $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
}
| keyword_not '(' rparen
{
- $$ = call_uni_op(method_cond(new_nil()), METHOD_NOT);
+ $$ = call_uni_op(p, method_cond(p, new_nil(&@2), &@2), METHOD_NOT, &@1, &@$);
}
| fcall brace_block
{
/*%%%*/
- $2->nd_iter = $1;
- $$ = $2;
- /*%
- $$ = method_arg(dispatch1(fcall, $1), arg_new());
- $$ = method_add_block($$, $2);
- %*/
+ $$ = method_add_block(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(method_add_arg!(fcall!($1), args_new!), $2) %*/
}
| method_call
| method_call brace_block
{
/*%%%*/
- block_dup_check($1->nd_args, $2);
- $2->nd_iter = $1;
- $$ = $2;
- /*%
- $$ = method_add_block($1, $2);
- %*/
- }
- | tLAMBDA lambda
- {
- $$ = $2;
+ block_dup_check(p, $1->nd_args, $2);
+ $$ = method_add_block(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!($1, $2) %*/
}
+ | lambda
| k_if expr_value then
compstmt
if_tail
k_end
{
/*%%%*/
- $$ = new_if($2, $4, $5);
+ $$ = new_if(p, $2, $4, $5, &@$);
fixpos($$, $2);
- /*%
- $$ = dispatch3(if, $2, $4, escape_Qundef($5));
- %*/
+ /*% %*/
+ /*% ripper: if!($2, $4, escape_Qundef($5)) %*/
}
| k_unless expr_value then
compstmt
@@ -2640,58 +3019,72 @@ primary : literal
k_end
{
/*%%%*/
- $$ = new_unless($2, $4, $5);
+ $$ = new_unless(p, $2, $4, $5, &@$);
fixpos($$, $2);
- /*%
- $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
- %*/
+ /*% %*/
+ /*% ripper: unless!($2, $4, escape_Qundef($5)) %*/
}
- | k_while {COND_PUSH(1);} expr_value do {COND_POP();}
+ | k_while expr_value_do
compstmt
k_end
{
/*%%%*/
- $$ = NEW_WHILE(cond($3), $6, 1);
- fixpos($$, $3);
- /*%
- $$ = dispatch2(while, $3, $6);
- %*/
+ $$ = NEW_WHILE(cond(p, $2, &@2), $3, 1, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: while!($2, $3) %*/
}
- | k_until {COND_PUSH(1);} expr_value do {COND_POP();}
+ | k_until expr_value_do
compstmt
k_end
{
/*%%%*/
- $$ = NEW_UNTIL(cond($3), $6, 1);
- fixpos($$, $3);
- /*%
- $$ = dispatch2(until, $3, $6);
- %*/
+ $$ = NEW_UNTIL(cond(p, $2, &@2), $3, 1, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: until!($2, $3) %*/
}
| k_case expr_value opt_terms
+ {
+ $<val>$ = p->case_labels;
+ p->case_labels = Qnil;
+ }
case_body
k_end
{
+ if (RTEST(p->case_labels)) rb_hash_clear(p->case_labels);
+ p->case_labels = $<val>4;
/*%%%*/
- $$ = NEW_CASE($2, $4);
+ $$ = NEW_CASE($2, $5, &@$);
fixpos($$, $2);
- /*%
- $$ = dispatch2(case, $2, $4);
- %*/
+ /*% %*/
+ /*% ripper: case!($2, $5) %*/
}
- | k_case opt_terms case_body k_end
+ | k_case opt_terms
{
+ $<val>$ = p->case_labels;
+ p->case_labels = 0;
+ }
+ case_body
+ k_end
+ {
+ if (RTEST(p->case_labels)) rb_hash_clear(p->case_labels);
+ p->case_labels = $<val>3;
/*%%%*/
- $$ = NEW_CASE(0, $3);
- nd_set_line($3, $<num>1);
- /*%
- $$ = dispatch2(case, Qnil, $3);
- %*/
+ $$ = NEW_CASE2($4, &@$);
+ /*% %*/
+ /*% ripper: case!(Qnil, $4) %*/
+ }
+ | k_case expr_value opt_terms
+ p_case_body
+ k_end
+ {
+ /*%%%*/
+ $$ = NEW_CASE3($2, $4, &@$);
+ /*% %*/
+ /*% ripper: case!($2, $4) %*/
}
- | k_for for_var keyword_in
- {COND_PUSH(1);}
- expr_value do
- {COND_POP();}
+ | k_for for_var keyword_in expr_value_do
compstmt
k_end
{
@@ -2705,319 +3098,334 @@ primary : literal
* #=>
* e.each{|x| a, = x}
*/
- ID id = internal_id();
- ID *tbl = ALLOC_N(ID, 2);
- NODE *m = NEW_ARGS_AUX(0, 0);
- NODE *args, *scope;
+ ID id = internal_id(p);
+ NODE *m = NEW_ARGS_AUX(0, 0, &NULL_LOC);
+ NODE *args, *scope, *internal_var = NEW_DVAR(id, &@2);
+ ID *tbl = ALLOC_N(ID, 3);
+ tbl[0] = 1 /* length of local var table */; tbl[1] = id /* internal id */;
+ rb_ast_add_local_table(p->ast, tbl);
switch (nd_type($2)) {
- case NODE_MASGN:
- m->nd_next = node_assign($2, NEW_FOR(NEW_DVAR(id), 0, 0));
- args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
- break;
case NODE_LASGN:
case NODE_DASGN:
- case NODE_DASGN_CURR:
- $2->nd_value = NEW_DVAR(id);
+ case NODE_DASGN_CURR: /* e.each {|internal_var| a = internal_var; ... } */
+ $2->nd_value = internal_var;
+ id = 0;
m->nd_plen = 1;
m->nd_next = $2;
- args = new_args(m, 0, 0, 0, new_args_tail(0, 0, 0));
break;
- default:
- m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
- args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
+ case NODE_MASGN: /* e.each {|*internal_var| a, b, c = (internal_var.length == 1 && Array === (tmp = internal_var[0]) ? tmp : internal_var); ... } */
+ m->nd_next = node_assign(p, $2, NEW_FOR_MASGN(internal_var, &@2), NO_LEX_CTXT, &@2);
break;
+ default: /* e.each {|*internal_var| @a, B, c[1], d.attr = internal_val; ... } */
+ m->nd_next = node_assign(p, NEW_MASGN(NEW_LIST($2, &@2), 0, &@2), internal_var, NO_LEX_CTXT, &@2);
}
- scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
- tbl[0] = 1; tbl[1] = id;
- $$ = NEW_FOR(0, $5, scope);
+ /* {|*internal_id| <m> = internal_id; ... } */
+ args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
+ scope = NEW_NODE(NODE_SCOPE, tbl, $5, args, &@$);
+ $$ = NEW_FOR($4, scope, &@$);
fixpos($$, $2);
- /*%
- $$ = dispatch3(for, $2, $5, $8);
- %*/
+ /*% %*/
+ /*% ripper: for!($2, $4, $5) %*/
}
| k_class cpath superclass
{
- if (in_def || in_single)
- yyerror("class definition in method body");
- local_push(0);
- /*%%%*/
- $<num>$ = ruby_sourceline;
- /*%
- %*/
+ if (p->ctxt.in_def) {
+ YYLTYPE loc = code_loc_gen(&@1, &@2);
+ yyerror1(&loc, "class definition in method body");
+ }
+ p->ctxt.in_class = 1;
+ local_push(p, 0);
}
bodystmt
k_end
{
/*%%%*/
- $$ = NEW_CLASS($2, $5, $3);
- set_line_body($5, $<num>4);
- nd_set_line($$, $<num>4);
- /*%
- $$ = dispatch3(class, $2, $3, $5);
- %*/
- local_pop();
+ $$ = NEW_CLASS($2, $5, $3, &@$);
+ nd_set_line($$->nd_body, @6.end_pos.lineno);
+ set_line_body($5, @3.end_pos.lineno);
+ nd_set_line($$, @3.end_pos.lineno);
+ /*% %*/
+ /*% ripper: class!($2, $3, $5) %*/
+ local_pop(p);
+ p->ctxt.in_class = $<ctxt>1.in_class;
+ p->ctxt.shareable_constant_value = $<ctxt>1.shareable_constant_value;
}
| k_class tLSHFT expr
{
- $<num>$ = (in_def << 1) | in_single;
- in_def = 0;
- in_single = 0;
- local_push(0);
+ p->ctxt.in_def = 0;
+ p->ctxt.in_class = 0;
+ local_push(p, 0);
}
term
bodystmt
k_end
{
/*%%%*/
- $$ = NEW_SCLASS($3, $6);
+ $$ = NEW_SCLASS($3, $6, &@$);
+ nd_set_line($$->nd_body, @7.end_pos.lineno);
set_line_body($6, nd_line($3));
fixpos($$, $3);
- /*%
- $$ = dispatch2(sclass, $3, $6);
- %*/
- local_pop();
- in_def = ($<num>4 >> 1) & 1;
- in_single = $<num>4 & 1;
+ /*% %*/
+ /*% ripper: sclass!($3, $6) %*/
+ local_pop(p);
+ p->ctxt.in_def = $<ctxt>1.in_def;
+ p->ctxt.in_class = $<ctxt>1.in_class;
+ p->ctxt.shareable_constant_value = $<ctxt>1.shareable_constant_value;
}
| k_module cpath
{
- if (in_def || in_single)
- yyerror("module definition in method body");
- local_push(0);
- /*%%%*/
- $<num>$ = ruby_sourceline;
- /*%
- %*/
+ if (p->ctxt.in_def) {
+ YYLTYPE loc = code_loc_gen(&@1, &@2);
+ yyerror1(&loc, "module definition in method body");
+ }
+ p->ctxt.in_class = 1;
+ local_push(p, 0);
}
bodystmt
k_end
{
/*%%%*/
- $$ = NEW_MODULE($2, $4);
- set_line_body($4, $<num>3);
- nd_set_line($$, $<num>3);
- /*%
- $$ = dispatch2(module, $2, $4);
- %*/
- local_pop();
- }
- | k_def fname
- {
- local_push(0);
- $<id>$ = current_arg;
- current_arg = 0;
- }
- {
- $<num>$ = in_def;
- in_def = 1;
+ $$ = NEW_MODULE($2, $4, &@$);
+ nd_set_line($$->nd_body, @5.end_pos.lineno);
+ set_line_body($4, @2.end_pos.lineno);
+ nd_set_line($$, @2.end_pos.lineno);
+ /*% %*/
+ /*% ripper: module!($2, $4) %*/
+ local_pop(p);
+ p->ctxt.in_class = $<ctxt>1.in_class;
+ p->ctxt.shareable_constant_value = $<ctxt>1.shareable_constant_value;
}
+ | defn_head
f_arglist
bodystmt
k_end
{
+ restore_defun(p, $<node>1->nd_defn);
/*%%%*/
- NODE *body = remove_begin($6);
- reduce_nodes(&body);
- $$ = NEW_DEFN($2, $5, body, METHOD_VISI_PRIVATE);
- set_line_body(body, $<num>1);
- nd_set_line($$, $<num>1);
- /*%
- $$ = dispatch3(def, $2, $5, $6);
- %*/
- local_pop();
- in_def = $<num>4 & 1;
- current_arg = $<id>3;
- }
- | k_def singleton dot_or_colon {SET_LEX_STATE(EXPR_FNAME);} fname
- {
- $<num>4 = in_single;
- in_single = 1;
- SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); /* force for args */
- local_push(0);
- $<id>$ = current_arg;
- current_arg = 0;
+ $$ = set_defun_body(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: def!(get_value($1), $2, $3) %*/
+ local_pop(p);
}
+ | defs_head
f_arglist
bodystmt
k_end
{
+ restore_defun(p, $<node>1->nd_defn);
/*%%%*/
- NODE *body = remove_begin($8);
- reduce_nodes(&body);
- $$ = NEW_DEFS($2, $5, $7, body);
- set_line_body(body, $<num>1);
- nd_set_line($$, $<num>1);
+ $$ = set_defun_body(p, $1, $2, $3, &@$);
/*%
- $$ = dispatch5(defs, $2, $<val>3, $5, $7, $8);
+ $1 = get_value($1);
%*/
- local_pop();
- in_single = $<num>4 & 1;
- current_arg = $<id>6;
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $3) %*/
+ local_pop(p);
}
| keyword_break
{
/*%%%*/
- $$ = NEW_BREAK(0);
- /*%
- $$ = dispatch1(break, arg_new());
- %*/
+ $$ = NEW_BREAK(0, &@$);
+ /*% %*/
+ /*% ripper: break!(args_new!) %*/
}
| keyword_next
{
/*%%%*/
- $$ = NEW_NEXT(0);
- /*%
- $$ = dispatch1(next, arg_new());
- %*/
+ $$ = NEW_NEXT(0, &@$);
+ /*% %*/
+ /*% ripper: next!(args_new!) %*/
}
| keyword_redo
{
/*%%%*/
- $$ = NEW_REDO();
- /*%
- $$ = dispatch0(redo);
- %*/
+ $$ = NEW_REDO(&@$);
+ /*% %*/
+ /*% ripper: redo! %*/
}
| keyword_retry
{
/*%%%*/
- $$ = NEW_RETRY();
- /*%
- $$ = dispatch0(retry);
- %*/
+ $$ = NEW_RETRY(&@$);
+ /*% %*/
+ /*% ripper: retry! %*/
}
;
primary_value : primary
{
- /*%%%*/
value_expr($1);
$$ = $1;
- if (!$$) $$ = NEW_NIL();
- /*%
- $$ = $1;
- %*/
}
;
k_begin : keyword_begin
{
- token_info_push("begin");
+ token_info_push(p, "begin", &@$);
}
;
k_if : keyword_if
{
- token_info_push("if");
+ WARN_EOL("if");
+ token_info_push(p, "if", &@$);
+ if (p->token_info && p->token_info->nonspc &&
+ p->token_info->next && !strcmp(p->token_info->next->token, "else")) {
+ const char *tok = p->lex.ptok;
+ const char *beg = p->lex.pbeg + p->token_info->next->beg.column;
+ beg += rb_strlen_lit("else");
+ while (beg < tok && ISSPACE(*beg)) beg++;
+ if (beg == tok) {
+ p->token_info->nonspc = 0;
+ }
+ }
}
;
k_unless : keyword_unless
{
- token_info_push("unless");
+ token_info_push(p, "unless", &@$);
}
;
k_while : keyword_while
{
- token_info_push("while");
+ token_info_push(p, "while", &@$);
}
;
k_until : keyword_until
{
- token_info_push("until");
+ token_info_push(p, "until", &@$);
}
;
k_case : keyword_case
{
- token_info_push("case");
- /*%%%*/
- $<num>$ = ruby_sourceline;
- /*%
- %*/
+ token_info_push(p, "case", &@$);
}
;
k_for : keyword_for
{
- token_info_push("for");
+ token_info_push(p, "for", &@$);
}
;
k_class : keyword_class
{
- token_info_push("class");
+ token_info_push(p, "class", &@$);
+ $<ctxt>$ = p->ctxt;
}
;
k_module : keyword_module
{
- token_info_push("module");
+ token_info_push(p, "module", &@$);
+ $<ctxt>$ = p->ctxt;
}
;
k_def : keyword_def
{
- token_info_push("def");
- /*%%%*/
- $<num>$ = ruby_sourceline;
- /*%
- %*/
+ token_info_push(p, "def", &@$);
+ }
+ ;
+
+k_do : keyword_do
+ {
+ token_info_push(p, "do", &@$);
+ }
+ ;
+
+k_do_block : keyword_do_block
+ {
+ token_info_push(p, "do", &@$);
+ }
+ ;
+
+k_rescue : keyword_rescue
+ {
+ token_info_warn(p, "rescue", p->token_info, 1, &@$);
+ }
+ ;
+
+k_ensure : keyword_ensure
+ {
+ token_info_warn(p, "ensure", p->token_info, 1, &@$);
+ }
+ ;
+
+k_when : keyword_when
+ {
+ token_info_warn(p, "when", p->token_info, 0, &@$);
+ }
+ ;
+
+k_else : keyword_else
+ {
+ token_info *ptinfo_beg = p->token_info;
+ int same = ptinfo_beg && strcmp(ptinfo_beg->token, "case") != 0;
+ token_info_warn(p, "else", p->token_info, same, &@$);
+ if (same) {
+ token_info e;
+ e.next = ptinfo_beg->next;
+ e.token = "else";
+ token_info_setup(&e, p->lex.pbeg, &@$);
+ if (!e.nonspc) *ptinfo_beg = e;
+ }
+ }
+ ;
+
+k_elsif : keyword_elsif
+ {
+ WARN_EOL("elsif");
+ token_info_warn(p, "elsif", p->token_info, 1, &@$);
}
;
k_end : keyword_end
{
- token_info_pop("end");
+ token_info_pop(p, "end", &@$);
+ }
+ ;
+
+k_return : keyword_return
+ {
+ if (p->ctxt.in_class && !p->ctxt.in_def && !dyna_in_block(p))
+ yyerror1(&@1, "Invalid return in class/module body");
}
;
then : term
- /*%c%*/
- /*%c
- { $$ = Qnil; }
- %*/
| keyword_then
| term keyword_then
- /*%c%*/
- /*%c
- { $$ = $2; }
- %*/
;
do : term
- /*%c%*/
- /*%c
- { $$ = Qnil; }
- %*/
| keyword_do_cond
;
if_tail : opt_else
- | keyword_elsif expr_value then
+ | k_elsif expr_value then
compstmt
if_tail
{
/*%%%*/
- $$ = new_if($2, $4, $5);
+ $$ = new_if(p, $2, $4, $5, &@$);
fixpos($$, $2);
- /*%
- $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
- %*/
+ /*% %*/
+ /*% ripper: elsif!($2, $4, escape_Qundef($5)) %*/
}
;
opt_else : none
- | keyword_else compstmt
+ | k_else compstmt
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(else, $2);
- %*/
+ /*% %*/
+ /*% ripper: else!($2) %*/
}
;
@@ -3027,137 +3435,110 @@ for_var : lhs
f_marg : f_norm_arg
{
- $$ = assignable($1, 0);
/*%%%*/
- /*%
- %*/
+ $$ = assignable(p, $1, 0, &@$);
+ mark_lvar_used(p, $$);
+ /*% %*/
+ /*% ripper: assignable(p, $1) %*/
}
| tLPAREN f_margs rparen
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(mlhs_paren, $2);
- %*/
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
}
;
f_marg_list : f_marg
{
/*%%%*/
- $$ = NEW_LIST($1);
- /*%
- $$ = mlhs_add(mlhs_new(), $1);
- %*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
}
| f_marg_list ',' f_marg
{
/*%%%*/
- $$ = list_append($1, $3);
- /*%
- $$ = mlhs_add($1, $3);
- %*/
+ $$ = list_append(p, $1, $3);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $3) %*/
}
;
f_margs : f_marg_list
{
/*%%%*/
- $$ = NEW_MASGN($1, 0);
- /*%
- $$ = $1;
- %*/
- }
- | f_marg_list ',' tSTAR f_norm_arg
- {
- $$ = assignable($4, 0);
- /*%%%*/
- $$ = NEW_MASGN($1, $$);
- /*%
- $$ = mlhs_add_star($1, $$);
- %*/
+ $$ = NEW_MASGN($1, 0, &@$);
+ /*% %*/
+ /*% ripper: $1 %*/
}
- | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
+ | f_marg_list ',' f_rest_marg
{
- $$ = assignable($4, 0);
/*%%%*/
- $$ = NEW_MASGN($1, NEW_POSTARG($$, $6));
- /*%
- $$ = mlhs_add_star($1, $$);
- $$ = mlhs_add_post($$, $6);
- %*/
+ $$ = NEW_MASGN($1, $3, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!($1, $3) %*/
}
- | f_marg_list ',' tSTAR
+ | f_marg_list ',' f_rest_marg ',' f_marg_list
{
/*%%%*/
- $$ = NEW_MASGN($1, -1);
- /*%
- $$ = mlhs_add_star($1, Qnil);
- %*/
+ $$ = NEW_MASGN($1, NEW_POSTARG($3, $5, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
}
- | f_marg_list ',' tSTAR ',' f_marg_list
+ | f_rest_marg
{
/*%%%*/
- $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5));
- /*%
- $$ = mlhs_add_star($1, Qnil);
- $$ = mlhs_add_post($$, $5);
- %*/
+ $$ = NEW_MASGN(0, $1, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!(mlhs_new!, $1) %*/
}
- | tSTAR f_norm_arg
+ | f_rest_marg ',' f_marg_list
{
- $$ = assignable($2, 0);
/*%%%*/
- $$ = NEW_MASGN(0, $$);
- /*%
- $$ = mlhs_add_star(mlhs_new(), $$);
- %*/
+ $$ = NEW_MASGN(0, NEW_POSTARG($1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $1), $3) %*/
}
- | tSTAR f_norm_arg ',' f_marg_list
+ ;
+
+f_rest_marg : tSTAR f_norm_arg
{
- $$ = assignable($2, 0);
/*%%%*/
- $$ = NEW_MASGN(0, NEW_POSTARG($$, $4));
- /*%
- $$ = mlhs_add_star(mlhs_new(), $$);
- $$ = mlhs_add_post($$, $4);
- %*/
+ $$ = assignable(p, $2, 0, &@$);
+ mark_lvar_used(p, $$);
+ /*% %*/
+ /*% ripper: assignable(p, $2) %*/
}
| tSTAR
{
/*%%%*/
- $$ = NEW_MASGN(0, -1);
- /*%
- $$ = mlhs_add_star(mlhs_new(), Qnil);
- %*/
- }
- | tSTAR ',' f_marg_list
- {
- /*%%%*/
- $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
- /*%
- $$ = mlhs_add_star(mlhs_new(), Qnil);
- $$ = mlhs_add_post($$, $3);
- %*/
+ $$ = NODE_SPECIAL_NO_NAME_REST;
+ /*% %*/
+ /*% ripper: Qnil %*/
}
;
+f_any_kwrest : f_kwrest
+ | f_no_kwarg {$$ = ID2VAL(idNil);}
+ ;
block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
{
- $$ = new_args_tail($1, $3, $4);
+ $$ = new_args_tail(p, $1, $3, $4, &@3);
}
| f_block_kwarg opt_f_block_arg
{
- $$ = new_args_tail($1, Qnone, $2);
+ $$ = new_args_tail(p, $1, Qnone, $2, &@1);
}
- | f_kwrest opt_f_block_arg
+ | f_any_kwrest opt_f_block_arg
{
- $$ = new_args_tail(Qnone, $1, $2);
+ $$ = new_args_tail(p, Qnone, $1, $2, &@1);
}
| f_block_arg
{
- $$ = new_args_tail(Qnone, Qnone, $1);
+ $$ = new_args_tail(p, Qnone, Qnone, $1, &@1);
}
;
@@ -3167,110 +3548,107 @@ opt_block_args_tail : ',' block_args_tail
}
| /* none */
{
- $$ = new_args_tail(Qnone, Qnone, Qnone);
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
+ }
+ ;
+
+excessed_comma : ','
+ {
+ /* magic number for rest_id in iseq_set_arguments() */
+ /*%%%*/
+ $$ = NODE_SPECIAL_EXCESSIVE_COMMA;
+ /*% %*/
+ /*% ripper: excessed_comma! %*/
}
;
block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
{
- $$ = new_args($1, $3, $5, Qnone, $6);
+ $$ = new_args(p, $1, $3, $5, Qnone, $6, &@$);
}
| f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
{
- $$ = new_args($1, $3, $5, $7, $8);
+ $$ = new_args(p, $1, $3, $5, $7, $8, &@$);
}
| f_arg ',' f_block_optarg opt_block_args_tail
{
- $$ = new_args($1, $3, Qnone, Qnone, $4);
+ $$ = new_args(p, $1, $3, Qnone, Qnone, $4, &@$);
}
| f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
{
- $$ = new_args($1, $3, Qnone, $5, $6);
+ $$ = new_args(p, $1, $3, Qnone, $5, $6, &@$);
}
| f_arg ',' f_rest_arg opt_block_args_tail
{
- $$ = new_args($1, Qnone, $3, Qnone, $4);
+ $$ = new_args(p, $1, Qnone, $3, Qnone, $4, &@$);
}
- | f_arg ','
+ | f_arg excessed_comma
{
- $$ = new_args($1, Qnone, 1, Qnone, new_args_tail(Qnone, Qnone, Qnone));
- /*%%%*/
- /*%
- dispatch1(excessed_comma, $$);
- %*/
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@2);
+ $$ = new_args(p, $1, Qnone, $2, Qnone, $$, &@$);
}
| f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
{
- $$ = new_args($1, Qnone, $3, $5, $6);
+ $$ = new_args(p, $1, Qnone, $3, $5, $6, &@$);
}
| f_arg opt_block_args_tail
{
- $$ = new_args($1, Qnone, Qnone, Qnone, $2);
+ $$ = new_args(p, $1, Qnone, Qnone, Qnone, $2, &@$);
}
| f_block_optarg ',' f_rest_arg opt_block_args_tail
{
- $$ = new_args(Qnone, $1, $3, Qnone, $4);
+ $$ = new_args(p, Qnone, $1, $3, Qnone, $4, &@$);
}
| f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
{
- $$ = new_args(Qnone, $1, $3, $5, $6);
+ $$ = new_args(p, Qnone, $1, $3, $5, $6, &@$);
}
| f_block_optarg opt_block_args_tail
{
- $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
+ $$ = new_args(p, Qnone, $1, Qnone, Qnone, $2, &@$);
}
| f_block_optarg ',' f_arg opt_block_args_tail
{
- $$ = new_args(Qnone, $1, Qnone, $3, $4);
+ $$ = new_args(p, Qnone, $1, Qnone, $3, $4, &@$);
}
| f_rest_arg opt_block_args_tail
{
- $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
+ $$ = new_args(p, Qnone, Qnone, $1, Qnone, $2, &@$);
}
| f_rest_arg ',' f_arg opt_block_args_tail
{
- $$ = new_args(Qnone, Qnone, $1, $3, $4);
+ $$ = new_args(p, Qnone, Qnone, $1, $3, $4, &@$);
}
| block_args_tail
{
- $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
+ $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $1, &@$);
}
;
opt_block_param : none
| block_param_def
{
- command_start = TRUE;
+ p->command_start = TRUE;
}
;
block_param_def : '|' opt_bv_decl '|'
{
- current_arg = 0;
- /*%%%*/
- $$ = 0;
- /*%
- $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
- escape_Qundef($2));
- %*/
- }
- | tOROP
- {
+ p->cur_arg = 0;
+ p->max_numparam = ORDINAL_PARAM;
/*%%%*/
$$ = 0;
- /*%
- $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
- Qnil);
- %*/
+ /*% %*/
+ /*% ripper: block_var!(params!(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil), escape_Qundef($2)) %*/
}
| '|' block_param opt_bv_decl '|'
{
- current_arg = 0;
+ p->cur_arg = 0;
+ p->max_numparam = ORDINAL_PARAM;
/*%%%*/
$$ = $2;
- /*%
- $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
- %*/
+ /*% %*/
+ /*% ripper: block_var!(escape_Qundef($2), escape_Qundef($3)) %*/
}
;
@@ -3283,35 +3661,21 @@ opt_bv_decl : opt_nl
{
/*%%%*/
$$ = 0;
- /*%
- $$ = $3;
- %*/
+ /*% %*/
+ /*% ripper: $3 %*/
}
;
bv_decls : bvar
- /*%c%*/
- /*%c
- {
- $$ = rb_ary_new3(1, get_value($1));
- }
- %*/
+ /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
| bv_decls ',' bvar
- /*%c%*/
- /*%c
- {
- rb_ary_push($1, get_value($3));
- }
- %*/
+ /*% ripper[brace]: rb_ary_push($1, get_value($3)) %*/
;
bvar : tIDENTIFIER
{
- new_bv(get_id($1));
- /*%%%*/
- /*%
- $$ = get_value($1);
- %*/
+ new_bv(p, get_id($1));
+ /*% ripper: get_value($1) %*/
}
| f_bad_arg
{
@@ -3319,33 +3683,43 @@ bvar : tIDENTIFIER
}
;
-lambda : {
- $<vars>$ = dyna_push();
+lambda : tLAMBDA
+ {
+ token_info_push(p, "->", &@1);
+ $<vars>1 = dyna_push(p);
+ $<num>$ = p->lex.lpar_beg;
+ p->lex.lpar_beg = p->lex.paren_nest;
}
{
- $<num>$ = lpar_beg;
- lpar_beg = ++paren_nest;
+ $<num>$ = p->max_numparam;
+ p->max_numparam = 0;
}
- f_larglist
{
- $<num>$ = ruby_sourceline;
+ $<node>$ = numparam_push(p);
}
+ f_larglist
{
- $<val>$ = cmdarg_stack;
- CMDARG_SET(0);
+ CMDARG_PUSH(0);
}
lambda_body
{
- lpar_beg = $<num>2;
- CMDARG_SET($<val>5);
- CMDARG_LEXPOP();
- /*%%%*/
- $$ = NEW_LAMBDA($3, $6);
- nd_set_line($$, $<num>4);
- /*%
- $$ = dispatch2(lambda, $3, $6);
- %*/
- dyna_pop($<vars>1);
+ int max_numparam = p->max_numparam;
+ p->lex.lpar_beg = $<num>2;
+ p->max_numparam = $<num>3;
+ CMDARG_POP();
+ $5 = args_with_numbered(p, $5, max_numparam);
+ /*%%%*/
+ {
+ YYLTYPE loc = code_loc_gen(&@5, &@7);
+ $$ = NEW_LAMBDA($5, $7, &loc);
+ nd_set_line($$->nd_body, @7.end_pos.lineno);
+ nd_set_line($$, @5.end_pos.lineno);
+ nd_set_first_loc($$, @1.beg_pos);
+ }
+ /*% %*/
+ /*% ripper: lambda!($5, $7) %*/
+ numparam_pop(p, $<node>4);
+ dyna_pop(p, $<vars>1);
}
;
@@ -3353,38 +3727,37 @@ f_larglist : '(' f_args opt_bv_decl ')'
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(paren, $2);
- %*/
+ p->max_numparam = ORDINAL_PARAM;
+ /*% %*/
+ /*% ripper: paren!($2) %*/
}
| f_args
{
+ /*%%%*/
+ if (!args_info_empty_p($1->nd_ainfo))
+ p->max_numparam = ORDINAL_PARAM;
+ /*% %*/
$$ = $1;
}
;
lambda_body : tLAMBEG compstmt '}'
{
- token_info_pop("}");
+ token_info_pop(p, "}", &@3);
$$ = $2;
}
- | keyword_do_LAMBDA compstmt k_end
+ | keyword_do_LAMBDA bodystmt k_end
{
$$ = $2;
}
;
-do_block : keyword_do_block
+do_block : k_do_block do_body k_end
{
+ $$ = $2;
/*%%%*/
- $<num>$ = ruby_sourceline;
- /*% %*/
- }
- do_body keyword_end
- {
- $$ = $3;
- /*%%%*/
- nd_set_line($$, $<num>2);
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
/*% %*/
}
;
@@ -3393,45 +3766,36 @@ block_call : command do_block
{
/*%%%*/
if (nd_type($1) == NODE_YIELD) {
- compile_error(PARSER_ARG "block given to yield");
+ compile_error(p, "block given to yield");
}
else {
- block_dup_check($1->nd_args, $2);
+ block_dup_check(p, $1->nd_args, $2);
}
- $2->nd_iter = $1;
- $$ = $2;
+ $$ = method_add_block(p, $1, $2, &@$);
fixpos($$, $1);
- /*%
- $$ = method_add_block($1, $2);
- %*/
+ /*% %*/
+ /*% ripper: method_add_block!($1, $2) %*/
}
| block_call call_op2 operation2 opt_paren_args
{
- $$ = new_qcall($2, $1, $3, $4);
+ /*%%%*/
+ $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
+ /*% %*/
+ /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
}
| block_call call_op2 operation2 opt_paren_args brace_block
{
/*%%%*/
- block_dup_check($4, $5);
- $5->nd_iter = new_command_qcall($2, $1, $3, $4);
- $$ = $5;
- fixpos($$, $1);
- /*%
- $$ = dispatch4(command_call, $1, $2, $3, $4);
- $$ = method_add_block($$, $5);
- %*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: opt_event(:method_add_block!, command_call!($1, $2, $3, $4), $5) %*/
}
| block_call call_op2 operation2 command_args do_block
{
/*%%%*/
- block_dup_check($4, $5);
- $5->nd_iter = new_command_qcall($2, $1, $3, $4);
- $$ = $5;
- fixpos($$, $1);
- /*%
- $$ = dispatch4(command_call, $1, $2, $3, $4);
- $$ = method_add_block($$, $5);
- %*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
}
;
@@ -3440,170 +3804,725 @@ method_call : fcall paren_args
/*%%%*/
$$ = $1;
$$->nd_args = $2;
- /*%
- $$ = method_arg(dispatch1(fcall, $1), $2);
- %*/
+ nd_set_last_loc($1, @2.end_pos);
+ /*% %*/
+ /*% ripper: method_add_arg!(fcall!($1), $2) %*/
}
- | primary_value call_op operation2
+ | primary_value call_op operation2 opt_paren_args
{
/*%%%*/
- $<num>$ = ruby_sourceline;
+ $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
+ nd_set_line($$, @3.end_pos.lineno);
/*% %*/
+ /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
}
- opt_paren_args
+ | primary_value tCOLON2 operation2 paren_args
{
- $$ = new_qcall($2, $1, $3, $5);
- nd_set_line($$, $<num>4);
+ /*%%%*/
+ $$ = new_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, &@3, &@$);
+ nd_set_line($$, @3.end_pos.lineno);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, ID2VAL(idCOLON2), $3), $4) %*/
}
- | primary_value tCOLON2 operation2
+ | primary_value tCOLON2 operation3
{
/*%%%*/
- $<num>$ = ruby_sourceline;
+ $$ = new_qcall(p, ID2VAL(idCOLON2), $1, $3, Qnull, &@3, &@$);
/*% %*/
+ /*% ripper: call!($1, ID2VAL(idCOLON2), $3) %*/
}
- paren_args
+ | primary_value call_op paren_args
{
- $$ = new_qcall(ID2VAL(idCOLON2), $1, $3, $5);
- nd_set_line($$, $<num>4);
+ /*%%%*/
+ $$ = new_qcall(p, $2, $1, ID2VAL(idCall), $3, &@2, &@$);
+ nd_set_line($$, @2.end_pos.lineno);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, $2, ID2VAL(idCall)), $3) %*/
}
- | primary_value tCOLON2 operation3
+ | primary_value tCOLON2 paren_args
{
- $$ = new_qcall(ID2VAL(idCOLON2), $1, $3, Qnull);
+ /*%%%*/
+ $$ = new_qcall(p, ID2VAL(idCOLON2), $1, ID2VAL(idCall), $3, &@2, &@$);
+ nd_set_line($$, @2.end_pos.lineno);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, ID2VAL(idCOLON2), ID2VAL(idCall)), $3) %*/
}
- | primary_value call_op
+ | keyword_super paren_args
{
/*%%%*/
- $<num>$ = ruby_sourceline;
+ $$ = NEW_SUPER($2, &@$);
/*% %*/
+ /*% ripper: super!($2) %*/
}
- paren_args
+ | keyword_super
{
- $$ = new_qcall($2, $1, ID2VAL(idCall), $4);
- nd_set_line($$, $<num>3);
+ /*%%%*/
+ $$ = NEW_ZSUPER(&@$);
+ /*% %*/
+ /*% ripper: zsuper! %*/
}
- | primary_value tCOLON2
+ | primary_value '[' opt_call_args rbracket
{
/*%%%*/
- $<num>$ = ruby_sourceline;
+ if ($1 && nd_type($1) == NODE_SELF)
+ $$ = NEW_FCALL(tAREF, $3, &@$);
+ else
+ $$ = NEW_CALL($1, tAREF, $3, &@$);
+ fixpos($$, $1);
/*% %*/
+ /*% ripper: aref!($1, escape_Qundef($3)) %*/
}
- paren_args
+ ;
+
+brace_block : '{' brace_body '}'
{
- $$ = new_qcall(ID2VAL(idCOLON2), $1, ID2VAL(idCall), $4);
- nd_set_line($$, $<num>3);
+ $$ = $2;
+ /*%%%*/
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
}
- | keyword_super paren_args
+ | k_do do_body k_end
+ {
+ $$ = $2;
+ /*%%%*/
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
+ }
+ ;
+
+brace_body : {$<vars>$ = dyna_push(p);}
+ {
+ $<num>$ = p->max_numparam;
+ p->max_numparam = 0;
+ }
+ {
+ $<node>$ = numparam_push(p);
+ }
+ opt_block_param compstmt
+ {
+ int max_numparam = p->max_numparam;
+ p->max_numparam = $<num>2;
+ $4 = args_with_numbered(p, $4, max_numparam);
+ /*%%%*/
+ $$ = NEW_ITER($4, $5, &@$);
+ /*% %*/
+ /*% ripper: brace_block!(escape_Qundef($4), $5) %*/
+ numparam_pop(p, $<node>3);
+ dyna_pop(p, $<vars>1);
+ }
+ ;
+
+do_body : {$<vars>$ = dyna_push(p);}
+ {
+ $<num>$ = p->max_numparam;
+ p->max_numparam = 0;
+ }
+ {
+ $<node>$ = numparam_push(p);
+ CMDARG_PUSH(0);
+ }
+ opt_block_param bodystmt
+ {
+ int max_numparam = p->max_numparam;
+ p->max_numparam = $<num>2;
+ $4 = args_with_numbered(p, $4, max_numparam);
+ /*%%%*/
+ $$ = NEW_ITER($4, $5, &@$);
+ /*% %*/
+ /*% ripper: do_block!(escape_Qundef($4), $5) %*/
+ CMDARG_POP();
+ numparam_pop(p, $<node>3);
+ dyna_pop(p, $<vars>1);
+ }
+ ;
+
+case_args : arg_value
+ {
+ /*%%%*/
+ check_literal_when(p, $1, &@1);
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: args_add!(args_new!, $1) %*/
+ }
+ | tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = NEW_SPLAT($2, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!(args_new!, $2) %*/
+ }
+ | case_args ',' arg_value
+ {
+ /*%%%*/
+ check_literal_when(p, $3, &@3);
+ $$ = last_arg_append(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: args_add!($1, $3) %*/
+ }
+ | case_args ',' tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = rest_arg_append(p, $1, $4, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!($1, $4) %*/
+ }
+ ;
+
+case_body : k_when case_args then
+ compstmt
+ cases
+ {
+ /*%%%*/
+ $$ = NEW_WHEN($2, $4, $5, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: when!($2, $4, escape_Qundef($5)) %*/
+ }
+ ;
+
+cases : opt_else
+ | case_body
+ ;
+
+p_case_body : keyword_in
+ {
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<ctxt>1 = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ $<tbl>$ = push_pvtbl(p);
+ }
+ {
+ $<tbl>$ = push_pktbl(p);
+ }
+ p_top_expr then
+ {
+ pop_pktbl(p, $<tbl>3);
+ pop_pvtbl(p, $<tbl>2);
+ p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
+ }
+ compstmt
+ p_cases
+ {
+ /*%%%*/
+ $$ = NEW_IN($4, $7, $8, &@$);
+ /*% %*/
+ /*% ripper: in!($4, $7, escape_Qundef($8)) %*/
+ }
+ ;
+
+p_cases : opt_else
+ | p_case_body
+ ;
+
+p_top_expr : p_top_expr_body
+ | p_top_expr_body modifier_if expr_value
+ {
+ /*%%%*/
+ $$ = new_if(p, $3, remove_begin($1), 0, &@$);
+ fixpos($$, $3);
+ /*% %*/
+ /*% ripper: if_mod!($3, $1) %*/
+ }
+ | p_top_expr_body modifier_unless expr_value
{
/*%%%*/
- $$ = NEW_SUPER($2);
+ $$ = new_unless(p, $3, remove_begin($1), 0, &@$);
+ fixpos($$, $3);
+ /*% %*/
+ /*% ripper: unless_mod!($3, $1) %*/
+ }
+ ;
+
+p_top_expr_body : p_expr
+ | p_expr ','
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 1, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, Qnone, get_value($1), $$, &@$);
+ }
+ | p_expr ',' p_args
+ {
+ $$ = new_array_pattern(p, Qnone, get_value($1), $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
/*%
- $$ = dispatch1(super, $2);
%*/
}
- | keyword_super
+ | p_find
+ {
+ $$ = new_find_pattern(p, Qnone, $1, &@$);
+ }
+ | p_args_tail
+ {
+ $$ = new_array_pattern(p, Qnone, Qnone, $1, &@$);
+ }
+ | p_kwargs
+ {
+ $$ = new_hash_pattern(p, Qnone, $1, &@$);
+ }
+ ;
+
+p_expr : p_as
+ ;
+
+p_as : p_expr tASSOC p_variable
+ {
+ /*%%%*/
+ NODE *n = NEW_LIST($1, &@$);
+ n = list_append(p, n, $3);
+ $$ = new_hash(p, n, &@$);
+ /*% %*/
+ /*% ripper: binary!($1, STATIC_ID2SYM((id_assoc)), $3) %*/
+ }
+ | p_alt
+ ;
+
+p_alt : p_alt '|' p_expr_basic
{
/*%%%*/
- $$ = NEW_ZSUPER();
+ $$ = NEW_NODE(NODE_OR, $1, $3, 0, &@$);
+ /*% %*/
+ /*% ripper: binary!($1, STATIC_ID2SYM(idOr), $3) %*/
+ }
+ | p_expr_basic
+ ;
+
+p_lparen : '(' {$<tbl>$ = push_pktbl(p);};
+p_lbracket : '[' {$<tbl>$ = push_pktbl(p);};
+
+p_expr_basic : p_value
+ | p_const p_lparen p_args rparen
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_array_pattern(p, $1, Qnone, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
/*%
- $$ = dispatch0(zsuper);
%*/
}
- | primary_value '[' opt_call_args rbracket
+ | p_const p_lparen p_find rparen
{
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_find_pattern(p, $1, $3, &@$);
/*%%%*/
- if ($1 && nd_type($1) == NODE_SELF)
- $$ = NEW_FCALL(tAREF, $3);
- else
- $$ = NEW_CALL($1, tAREF, $3);
- fixpos($$, $1);
+ nd_set_first_loc($$, @1.beg_pos);
/*%
- $$ = dispatch2(aref, $1, escape_Qundef($3));
%*/
}
+ | p_const p_lparen p_kwargs rparen
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_hash_pattern(p, $1, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const '(' rparen
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, $1, Qnone, $$, &@$);
+ }
+ | p_const p_lbracket p_args rbracket
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_array_pattern(p, $1, Qnone, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const p_lbracket p_find rbracket
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_find_pattern(p, $1, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const p_lbracket p_kwargs rbracket
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_hash_pattern(p, $1, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const '[' rbracket
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, $1, Qnone, $$, &@$);
+ }
+ | tLBRACK p_args rbracket
+ {
+ $$ = new_array_pattern(p, Qnone, Qnone, $2, &@$);
+ }
+ | tLBRACK p_find rbracket
+ {
+ $$ = new_find_pattern(p, Qnone, $2, &@$);
+ }
+ | tLBRACK rbracket
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, Qnone, Qnone, $$, &@$);
+ }
+ | tLBRACE
+ {
+ $<tbl>$ = push_pktbl(p);
+ $<ctxt>1 = p->ctxt;
+ p->ctxt.in_kwarg = 0;
+ }
+ p_kwargs rbrace
+ {
+ pop_pktbl(p, $<tbl>2);
+ p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
+ $$ = new_hash_pattern(p, Qnone, $3, &@$);
+ }
+ | tLBRACE rbrace
+ {
+ $$ = new_hash_pattern_tail(p, Qnone, 0, &@$);
+ $$ = new_hash_pattern(p, Qnone, $$, &@$);
+ }
+ | tLPAREN {$<tbl>$ = push_pktbl(p);} p_expr rparen
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = $3;
+ }
;
-brace_block : '{'
+p_args : p_expr
{
/*%%%*/
- $<num>$ = ruby_sourceline;
- /*% %*/
+ NODE *pre_args = NEW_LIST($1, &@$);
+ $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
+ /*%
+ $$ = new_array_pattern_tail(p, rb_ary_new_from_args(1, get_value($1)), 0, 0, Qnone, &@$);
+ %*/
}
- brace_body '}'
+ | p_args_head
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, 0, Qnone, &@$);
+ }
+ | p_args_head p_arg
{
- $$ = $3;
/*%%%*/
- nd_set_line($$, $<num>2);
+ $$ = new_array_pattern_tail(p, list_concat($1, $2), 0, 0, Qnone, &@$);
+ /*%
+ VALUE pre_args = rb_ary_concat($1, get_value($2));
+ $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
+ %*/
+ }
+ | p_args_head tSTAR tIDENTIFIER
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, $3, Qnone, &@$);
+ }
+ | p_args_head tSTAR tIDENTIFIER ',' p_args_post
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, $3, $5, &@$);
+ }
+ | p_args_head tSTAR
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, 0, Qnone, &@$);
+ }
+ | p_args_head tSTAR ',' p_args_post
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, 0, $4, &@$);
+ }
+ | p_args_tail
+ ;
+
+p_args_head : p_arg ','
+ {
+ $$ = $1;
+ }
+ | p_args_head p_arg ','
+ {
+ /*%%%*/
+ $$ = list_concat($1, $2);
/*% %*/
+ /*% ripper: rb_ary_concat($1, get_value($2)) %*/
+ }
+ ;
+
+p_args_tail : p_rest
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 1, $1, Qnone, &@$);
+ }
+ | p_rest ',' p_args_post
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 1, $1, $3, &@$);
}
- | keyword_do
+ ;
+
+p_find : p_rest ',' p_args_post ',' p_rest
+ {
+ $$ = new_find_pattern_tail(p, $1, $3, $5, &@$);
+
+ if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL))
+ rb_warn0L_experimental(nd_line($$), "Find pattern is experimental, and the behavior may change in future versions of Ruby!");
+ }
+ ;
+
+
+p_rest : tSTAR tIDENTIFIER
+ {
+ $$ = $2;
+ }
+ | tSTAR
+ {
+ $$ = 0;
+ }
+ ;
+
+p_args_post : p_arg
+ | p_args_post ',' p_arg
{
/*%%%*/
- $<num>$ = ruby_sourceline;
+ $$ = list_concat($1, $3);
/*% %*/
+ /*% ripper: rb_ary_concat($1, get_value($3)) %*/
}
- do_body keyword_end
+ ;
+
+p_arg : p_expr
{
- $$ = $3;
/*%%%*/
- nd_set_line($$, $<num>2);
+ $$ = NEW_LIST($1, &@$);
/*% %*/
+ /*% ripper: rb_ary_new_from_args(1, get_value($1)) %*/
}
;
-brace_body : {$<vars>$ = dyna_push();}
- {$<val>$ = cmdarg_stack >> 1; CMDARG_SET(0);}
- opt_block_param compstmt
+p_kwargs : p_kwarg ',' p_any_kwrest
+ {
+ $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), $3, &@$);
+ }
+ | p_kwarg
{
- $$ = new_brace_body($3, $4);
- dyna_pop($<vars>1);
- CMDARG_SET($<val>2);
+ $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), 0, &@$);
+ }
+ | p_kwarg ','
+ {
+ $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), 0, &@$);
+ }
+ | p_any_kwrest
+ {
+ $$ = new_hash_pattern_tail(p, new_hash(p, Qnone, &@$), $1, &@$);
}
;
-do_body : {$<vars>$ = dyna_push();}
- {$<val>$ = cmdarg_stack; CMDARG_SET(0);}
- opt_block_param bodystmt
+p_kwarg : p_kw
+ /*% ripper[brace]: rb_ary_new_from_args(1, $1) %*/
+ | p_kwarg ',' p_kw
{
- $$ = new_do_body($3, $4);
- dyna_pop($<vars>1);
- CMDARG_SET($<val>2);
+ /*%%%*/
+ $$ = list_concat($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, $3) %*/
}
;
-case_body : keyword_when args then
- compstmt
- cases
+p_kw : p_kw_label p_expr
{
+ error_duplicate_pattern_key(p, get_id($1), &@1);
/*%%%*/
- $$ = NEW_WHEN($2, $4, $5);
+ $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$), $2);
+ /*% %*/
+ /*% ripper: rb_ary_new_from_args(2, get_value($1), get_value($2)) %*/
+ }
+ | p_kw_label
+ {
+ error_duplicate_pattern_key(p, get_id($1), &@1);
+ if ($1 && !is_local_id(get_id($1))) {
+ yyerror1(&@1, "key must be valid as local variables");
+ }
+ error_duplicate_pattern_variable(p, get_id($1), &@1);
+ /*%%%*/
+ $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$), assignable(p, $1, 0, &@$));
+ /*% %*/
+ /*% ripper: rb_ary_new_from_args(2, get_value($1), Qnil) %*/
+ }
+ ;
+
+p_kw_label : tLABEL
+ | tSTRING_BEG string_contents tLABEL_END
+ {
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ /*%%%*/
+ if (!$2 || nd_type($2) == NODE_STR) {
+ NODE *node = dsym_node(p, $2, &loc);
+ $$ = SYM2ID(node->nd_lit);
+ }
/*%
- $$ = dispatch3(when, $2, $4, escape_Qundef($5));
+ if (ripper_is_node_yylval($2) && RNODE($2)->nd_cval) {
+ VALUE label = RNODE($2)->nd_cval;
+ VALUE rval = RNODE($2)->nd_rval;
+ $$ = ripper_new_yylval(p, rb_intern_str(label), rval, label);
+ RNODE($$)->nd_loc = loc;
+ }
%*/
+ else {
+ yyerror1(&loc, "symbol literal with interpolation is not allowed");
+ $$ = 0;
+ }
}
;
-cases : opt_else
- | case_body
+p_kwrest : kwrest_mark tIDENTIFIER
+ {
+ $$ = $2;
+ }
+ | kwrest_mark
+ {
+ $$ = 0;
+ }
+ ;
+
+p_kwnorest : kwrest_mark keyword_nil
+ {
+ $$ = 0;
+ }
+ ;
+
+p_any_kwrest : p_kwrest
+ | p_kwnorest {$$ = ID2VAL(idNil);}
;
-opt_rescue : keyword_rescue exc_list exc_var then
+p_value : p_primitive
+ | p_primitive tDOT2 p_primitive
+ {
+ /*%%%*/
+ value_expr($1);
+ value_expr($3);
+ $$ = NEW_DOT2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, $3) %*/
+ }
+ | p_primitive tDOT3 p_primitive
+ {
+ /*%%%*/
+ value_expr($1);
+ value_expr($3);
+ $$ = NEW_DOT3($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, $3) %*/
+ }
+ | p_primitive tDOT2
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT2($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, Qnil) %*/
+ }
+ | p_primitive tDOT3
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT3($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, Qnil) %*/
+ }
+ | p_variable
+ | p_var_ref
+ | p_const
+ | tBDOT2 p_primitive
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT2(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot2!(Qnil, $2) %*/
+ }
+ | tBDOT3 p_primitive
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT3(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot3!(Qnil, $2) %*/
+ }
+ ;
+
+p_primitive : literal
+ | strings
+ | xstring
+ | regexp
+ | words
+ | qwords
+ | symbols
+ | qsymbols
+ | keyword_variable
+ {
+ /*%%%*/
+ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ | lambda
+ ;
+
+p_variable : tIDENTIFIER
+ {
+ /*%%%*/
+ error_duplicate_pattern_variable(p, $1, &@1);
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ ;
+
+p_var_ref : '^' tIDENTIFIER
+ {
+ /*%%%*/
+ NODE *n = gettable(p, $2, &@$);
+ if (!(nd_type(n) == NODE_LVAR || nd_type(n) == NODE_DVAR)) {
+ compile_error(p, "%"PRIsVALUE": no such local variable", rb_id2str($2));
+ }
+ $$ = n;
+ /*% %*/
+ /*% ripper: var_ref!($2) %*/
+ }
+ ;
+
+p_const : tCOLON3 cname
+ {
+ /*%%%*/
+ $$ = NEW_COLON3($2, &@$);
+ /*% %*/
+ /*% ripper: top_const_ref!($2) %*/
+ }
+ | p_const tCOLON2 cname
+ {
+ /*%%%*/
+ $$ = NEW_COLON2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_ref!($1, $3) %*/
+ }
+ | tCONSTANT
+ {
+ /*%%%*/
+ $$ = gettable(p, $1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ ;
+
+opt_rescue : k_rescue exc_list exc_var then
compstmt
opt_rescue
{
/*%%%*/
- if ($3) {
- $3 = node_assign($3, NEW_ERRINFO());
- $5 = block_append($3, $5);
- }
- $$ = NEW_RESBODY($2, $5, $6);
+ $$ = NEW_RESBODY($2,
+ $3 ? block_append(p, node_assign(p, $3, NEW_ERRINFO(&@3), NO_LEX_CTXT, &@3), $5) : $5,
+ $6, &@$);
fixpos($$, $2?$2:$5);
- /*%
- $$ = dispatch4(rescue,
- escape_Qundef($2),
- escape_Qundef($3),
- escape_Qundef($5),
- escape_Qundef($6));
- %*/
+ /*% %*/
+ /*% ripper: rescue!(escape_Qundef($2), escape_Qundef($3), escape_Qundef($5), escape_Qundef($6)) %*/
}
| none
;
@@ -3611,18 +4530,16 @@ opt_rescue : keyword_rescue exc_list exc_var then
exc_list : arg_value
{
/*%%%*/
- $$ = NEW_LIST($1);
- /*%
- $$ = rb_ary_new3(1, get_value($1));
- %*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
}
| mrhs
{
/*%%%*/
if (!($$ = splat_array($1))) $$ = $1;
- /*%
- $$ = $1;
- %*/
+ /*% %*/
+ /*% ripper: $1 %*/
}
| none
;
@@ -3634,27 +4551,18 @@ exc_var : tASSOC lhs
| none
;
-opt_ensure : keyword_ensure compstmt
+opt_ensure : k_ensure compstmt
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(ensure, $2);
- %*/
+ /*% %*/
+ /*% ripper: ensure!($2) %*/
}
| none
;
literal : numeric
| symbol
- {
- /*%%%*/
- $$ = NEW_LIT(ID2SYM($1));
- /*%
- $$ = dispatch1(symbol_literal, $1);
- %*/
- }
- | dsym
;
strings : string
@@ -3662,15 +4570,15 @@ strings : string
/*%%%*/
NODE *node = $1;
if (!node) {
- node = NEW_STR(STR_NEW0());
+ node = NEW_STR(STR_NEW0(), &@$);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit);
}
else {
- node = evstr2dstr(node);
+ node = evstr2dstr(p, node);
}
$$ = node;
- /*%
- $$ = $1;
- %*/
+ /*% %*/
+ /*% ripper: $1 %*/
}
;
@@ -3679,47 +4587,43 @@ string : tCHAR
| string string1
{
/*%%%*/
- $$ = literal_concat($1, $2);
- /*%
- $$ = dispatch2(string_concat, $1, $2);
- %*/
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: string_concat!($1, $2) %*/
}
;
string1 : tSTRING_BEG string_contents tSTRING_END
{
- $$ = new_string1(heredoc_dedent($2));
+ /*%%%*/
+ $$ = heredoc_dedent(p, $2);
+ if ($$) nd_set_loc($$, &@$);
+ /*% %*/
+ /*% ripper: string_literal!(heredoc_dedent(p, $2)) %*/
}
;
xstring : tXSTRING_BEG xstring_contents tSTRING_END
{
- $$ = new_xstring(heredoc_dedent($2));
+ /*%%%*/
+ $$ = new_xstring(p, heredoc_dedent(p, $2), &@$);
+ /*% %*/
+ /*% ripper: xstring_literal!(heredoc_dedent(p, $2)) %*/
}
;
regexp : tREGEXP_BEG regexp_contents tREGEXP_END
{
- $$ = new_regexp($2, $3);
+ $$ = new_regexp(p, $2, $3, &@$);
}
;
-words : tWORDS_BEG ' ' tSTRING_END
- {
- /*%%%*/
- $$ = NEW_ZARRAY();
- /*%
- $$ = dispatch0(words_new);
- $$ = dispatch1(array, $$);
- %*/
- }
- | tWORDS_BEG word_list tSTRING_END
+words : tWORDS_BEG ' ' word_list tSTRING_END
{
/*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(array, $2);
- %*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
}
;
@@ -3727,54 +4631,35 @@ word_list : /* none */
{
/*%%%*/
$$ = 0;
- /*%
- $$ = dispatch0(words_new);
- %*/
+ /*% %*/
+ /*% ripper: words_new! %*/
}
| word_list word ' '
{
/*%%%*/
- $$ = list_append($1, evstr2dstr($2));
- /*%
- $$ = dispatch2(words_add, $1, $2);
- %*/
+ $$ = list_append(p, $1, evstr2dstr(p, $2));
+ /*% %*/
+ /*% ripper: words_add!($1, $2) %*/
}
;
word : string_content
- /*%c%*/
- /*%c
- {
- $$ = dispatch0(word_new);
- $$ = dispatch2(word_add, $$, $1);
- }
- %*/
+ /*% ripper[brace]: word_add!(word_new!, $1) %*/
| word string_content
{
/*%%%*/
- $$ = literal_concat($1, $2);
- /*%
- $$ = dispatch2(word_add, $1, $2);
- %*/
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: word_add!($1, $2) %*/
}
;
-symbols : tSYMBOLS_BEG ' ' tSTRING_END
- {
- /*%%%*/
- $$ = NEW_ZARRAY();
- /*%
- $$ = dispatch0(symbols_new);
- $$ = dispatch1(array, $$);
- %*/
- }
- | tSYMBOLS_BEG symbol_list tSTRING_END
+symbols : tSYMBOLS_BEG ' ' symbol_list tSTRING_END
{
/*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(array, $2);
- %*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
}
;
@@ -3782,63 +4667,33 @@ symbol_list : /* none */
{
/*%%%*/
$$ = 0;
- /*%
- $$ = dispatch0(symbols_new);
- %*/
+ /*% %*/
+ /*% ripper: symbols_new! %*/
}
| symbol_list word ' '
{
/*%%%*/
- $2 = evstr2dstr($2);
- if (nd_type($2) == NODE_DSTR) {
- nd_set_type($2, NODE_DSYM);
- }
- else {
- nd_set_type($2, NODE_LIT);
- $2->nd_lit = rb_str_intern($2->nd_lit);
- }
- $$ = list_append($1, $2);
- /*%
- $$ = dispatch2(symbols_add, $1, $2);
- %*/
+ $$ = symbol_append(p, $1, evstr2dstr(p, $2));
+ /*% %*/
+ /*% ripper: symbols_add!($1, $2) %*/
}
;
-qwords : tQWORDS_BEG ' ' tSTRING_END
+qwords : tQWORDS_BEG ' ' qword_list tSTRING_END
{
/*%%%*/
- $$ = NEW_ZARRAY();
- /*%
- $$ = dispatch0(qwords_new);
- $$ = dispatch1(array, $$);
- %*/
- }
- | tQWORDS_BEG qword_list tSTRING_END
- {
- /*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(array, $2);
- %*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
}
;
-qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END
+qsymbols : tQSYMBOLS_BEG ' ' qsym_list tSTRING_END
{
/*%%%*/
- $$ = NEW_ZARRAY();
- /*%
- $$ = dispatch0(qsymbols_new);
- $$ = dispatch1(array, $$);
- %*/
- }
- | tQSYMBOLS_BEG qsym_list tSTRING_END
- {
- /*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(array, $2);
- %*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
}
;
@@ -3846,17 +4701,15 @@ qword_list : /* none */
{
/*%%%*/
$$ = 0;
- /*%
- $$ = dispatch0(qwords_new);
- %*/
+ /*% %*/
+ /*% ripper: qwords_new! %*/
}
| qword_list tSTRING_CONTENT ' '
{
/*%%%*/
- $$ = list_append($1, $2);
- /*%
- $$ = dispatch2(qwords_add, $1, $2);
- %*/
+ $$ = list_append(p, $1, $2);
+ /*% %*/
+ /*% ripper: qwords_add!($1, $2) %*/
}
;
@@ -3864,21 +4717,15 @@ qsym_list : /* none */
{
/*%%%*/
$$ = 0;
- /*%
- $$ = dispatch0(qsymbols_new);
- %*/
+ /*% %*/
+ /*% ripper: qsymbols_new! %*/
}
| qsym_list tSTRING_CONTENT ' '
{
/*%%%*/
- VALUE lit;
- lit = $2->nd_lit;
- $2->nd_lit = ID2SYM(rb_intern_str(lit));
- nd_set_type($2, NODE_LIT);
- $$ = list_append($1, $2);
- /*%
- $$ = dispatch2(qsymbols_add, $1, $2);
- %*/
+ $$ = symbol_append(p, $1, $2);
+ /*% %*/
+ /*% ripper: qsymbols_add!($1, $2) %*/
}
;
@@ -3886,16 +4733,27 @@ string_contents : /* none */
{
/*%%%*/
$$ = 0;
+ /*% %*/
+ /*% ripper: string_content! %*/
+ /*%%%*/
/*%
- $$ = dispatch0(string_content);
+ $$ = ripper_new_yylval(p, 0, $$, 0);
%*/
}
| string_contents string_content
{
/*%%%*/
- $$ = literal_concat($1, $2);
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: string_add!($1, $2) %*/
+ /*%%%*/
/*%
- $$ = dispatch2(string_add, $1, $2);
+ if (ripper_is_node_yylval($1) && ripper_is_node_yylval($2) &&
+ !RNODE($1)->nd_cval) {
+ RNODE($1)->nd_cval = RNODE($2)->nd_cval;
+ RNODE($1)->nd_rval = add_mark_object(p, $$);
+ $$ = $1;
+ }
%*/
}
;
@@ -3904,17 +4762,15 @@ xstring_contents: /* none */
{
/*%%%*/
$$ = 0;
- /*%
- $$ = dispatch0(xstring_new);
- %*/
+ /*% %*/
+ /*% ripper: xstring_new! %*/
}
| xstring_contents string_content
{
/*%%%*/
- $$ = literal_concat($1, $2);
- /*%
- $$ = dispatch2(xstring_add, $1, $2);
- %*/
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: xstring_add!($1, $2) %*/
}
;
@@ -3922,8 +4778,11 @@ regexp_contents: /* none */
{
/*%%%*/
$$ = 0;
+ /*% %*/
+ /*% ripper: regexp_new! %*/
+ /*%%%*/
/*%
- $$ = ripper_new_yylval(0, dispatch0(regexp_new), 0);
+ $$ = ripper_new_yylval(p, 0, $$, 0);
%*/
}
| regexp_contents string_content
@@ -3944,10 +4803,10 @@ regexp_contents: /* none */
case NODE_DSTR:
break;
default:
- head = list_append(NEW_DSTR(Qnil), head);
+ head = list_append(p, NEW_DSTR(Qnil, &@$), head);
break;
}
- $$ = list_append(head, tail);
+ $$ = list_append(p, head, tail);
}
/*%
VALUE s1 = 1, s2 = 0, n1 = $1, n2 = $2;
@@ -3961,104 +4820,104 @@ regexp_contents: /* none */
}
$$ = dispatch2(regexp_add, n1, n2);
if (!s1 && s2) {
- $$ = ripper_new_yylval(0, $$, s2);
+ $$ = ripper_new_yylval(p, 0, $$, s2);
}
%*/
}
;
string_content : tSTRING_CONTENT
+ /*% ripper[brace]: ripper_new_yylval(p, 0, get_value($1), $1) %*/
| tSTRING_DVAR
{
- $<node>$ = lex_strterm;
- lex_strterm = 0;
+ /* need to backup p->lex.strterm so that a string literal `%&foo,#$&,bar&` can be parsed */
+ $<strterm>$ = p->lex.strterm;
+ p->lex.strterm = 0;
SET_LEX_STATE(EXPR_BEG);
}
string_dvar
{
- lex_strterm = $<node>2;
+ p->lex.strterm = $<strterm>2;
/*%%%*/
- $$ = NEW_EVSTR($3);
- /*%
- $$ = dispatch1(string_dvar, $3);
- %*/
+ $$ = NEW_EVSTR($3, &@$);
+ nd_set_line($$, @3.end_pos.lineno);
+ /*% %*/
+ /*% ripper: string_dvar!($3) %*/
}
| tSTRING_DBEG
{
- $<val>1 = cond_stack;
- $<val>$ = cmdarg_stack;
- COND_SET(0);
- CMDARG_SET(0);
+ CMDARG_PUSH(0);
+ COND_PUSH(0);
}
{
- $<node>$ = lex_strterm;
- lex_strterm = 0;
+ /* need to backup p->lex.strterm so that a string literal `%!foo,#{ !0 },bar!` can be parsed */
+ $<strterm>$ = p->lex.strterm;
+ p->lex.strterm = 0;
}
{
- $<num>$ = lex_state;
+ $<num>$ = p->lex.state;
SET_LEX_STATE(EXPR_BEG);
}
{
- $<num>$ = brace_nest;
- brace_nest = 0;
+ $<num>$ = p->lex.brace_nest;
+ p->lex.brace_nest = 0;
}
{
- $<num>$ = heredoc_indent;
- heredoc_indent = 0;
+ $<num>$ = p->heredoc_indent;
+ p->heredoc_indent = 0;
}
compstmt tSTRING_DEND
{
- COND_SET($<val>1);
- CMDARG_SET($<val>2);
- lex_strterm = $<node>3;
+ COND_POP();
+ CMDARG_POP();
+ p->lex.strterm = $<strterm>3;
SET_LEX_STATE($<num>4);
- brace_nest = $<num>5;
- heredoc_indent = $<num>6;
- heredoc_line_indent = -1;
+ p->lex.brace_nest = $<num>5;
+ p->heredoc_indent = $<num>6;
+ p->heredoc_line_indent = -1;
/*%%%*/
if ($7) $7->flags &= ~NODE_FL_NEWLINE;
- $$ = new_evstr($7);
- /*%
- $$ = dispatch1(string_embexpr, $7);
- %*/
+ $$ = new_evstr(p, $7, &@$);
+ /*% %*/
+ /*% ripper: string_embexpr!($7) %*/
}
;
string_dvar : tGVAR
{
/*%%%*/
- $$ = NEW_GVAR($1);
- /*%
- $$ = dispatch1(var_ref, $1);
- %*/
+ $$ = NEW_GVAR($1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
}
| tIVAR
{
/*%%%*/
- $$ = NEW_IVAR($1);
- /*%
- $$ = dispatch1(var_ref, $1);
- %*/
+ $$ = NEW_IVAR($1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
}
| tCVAR
{
/*%%%*/
- $$ = NEW_CVAR($1);
- /*%
- $$ = dispatch1(var_ref, $1);
- %*/
+ $$ = NEW_CVAR($1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
}
| backref
;
-symbol : tSYMBEG sym
+symbol : ssym
+ | dsym
+ ;
+
+ssym : tSYMBEG sym
{
- SET_LEX_STATE(EXPR_END|EXPR_ENDARG);
+ SET_LEX_STATE(EXPR_END);
/*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(symbol, $2);
- %*/
+ $$ = NEW_LIT(ID2SYM($2), &@$);
+ /*% %*/
+ /*% ripper: symbol_literal!(symbol!($2)) %*/
}
;
@@ -4068,14 +4927,13 @@ sym : fname
| tCVAR
;
-dsym : tSYMBEG xstring_contents tSTRING_END
+dsym : tSYMBEG string_contents tSTRING_END
{
- SET_LEX_STATE(EXPR_END|EXPR_ENDARG);
+ SET_LEX_STATE(EXPR_END);
/*%%%*/
- $$ = dsym_node($2);
- /*%
- $$ = dispatch1(dyna_symbol, $2);
- %*/
+ $$ = dsym_node(p, $2, &@$);
+ /*% %*/
+ /*% ripper: dyna_symbol!($2) %*/
}
;
@@ -4084,10 +4942,9 @@ numeric : simple_numeric
{
/*%%%*/
$$ = $2;
- $$->nd_lit = negate_lit($$->nd_lit);
- /*%
- $$ = dispatch2(unary, ID2VAL(idUMinus), $2);
- %*/
+ RB_OBJ_WRITE(p->ast, &$$->nd_lit, negate_lit(p, $$->nd_lit));
+ /*% %*/
+ /*% ripper: unary!(ID2VAL(idUMinus), $2) %*/
}
;
@@ -4116,9 +4973,9 @@ keyword_variable: keyword_nil {$$ = KWD2EID(nil, $1);}
var_ref : user_variable
{
/*%%%*/
- if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
+ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
/*%
- if (id_is_var(get_id($1))) {
+ if (id_is_var(p, get_id($1))) {
$$ = dispatch1(var_ref, $1);
}
else {
@@ -4129,20 +4986,25 @@ var_ref : user_variable
| keyword_variable
{
/*%%%*/
- if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch1(var_ref, $1);
- %*/
+ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
}
;
var_lhs : user_variable
{
- $$ = assignable(var_field($1), 0);
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
}
| keyword_variable
{
- $$ = assignable(var_field($1), 0);
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
}
;
@@ -4153,7 +5015,7 @@ backref : tNTH_REF
superclass : '<'
{
SET_LEX_STATE(EXPR_BEG);
- command_start = TRUE;
+ p->command_start = TRUE;
}
expr_value term
{
@@ -4163,51 +5025,74 @@ superclass : '<'
{
/*%%%*/
$$ = 0;
- /*%
- $$ = Qnil;
- %*/
+ /*% %*/
+ /*% ripper: Qnil %*/
}
;
-f_arglist : '(' f_args rparen
+f_opt_paren_args: f_paren_args | none;
+
+f_paren_args : '(' f_args rparen
{
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(paren, $2);
- %*/
+ /*% %*/
+ /*% ripper: paren!($2) %*/
SET_LEX_STATE(EXPR_BEG);
- command_start = TRUE;
+ p->command_start = TRUE;
}
+ | '(' f_arg ',' args_forward rparen
+ {
+ add_forwarding_args(p);
+ /*%%%*/
+ $$ = new_args_forward_def(p, $2, &@$);
+ /*% %*/
+ /*% ripper: paren!(params!($2, Qnone, $4, Qnone, Qnone, Qnone, Qnone)) %*/
+ SET_LEX_STATE(EXPR_BEG);
+ p->command_start = TRUE;
+ }
+ | '(' args_forward rparen
+ {
+ add_forwarding_args(p);
+ /*%%%*/
+ $$ = new_args_forward_def(p, 0, &@$);
+ /*% %*/
+ /*% ripper: paren!(params!(Qnone, Qnone, $2, Qnone, Qnone, Qnone, Qnone)) %*/
+ SET_LEX_STATE(EXPR_BEG);
+ p->command_start = TRUE;
+ }
+ ;
+
+f_arglist : f_paren_args
| {
- $<num>$ = parser->in_kwarg;
- parser->in_kwarg = 1;
- SET_LEX_STATE(lex_state|EXPR_LABEL); /* force for args */
+ $<ctxt>$ = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ SET_LEX_STATE(p->lex.state|EXPR_LABEL); /* force for args */
}
- f_args term
+ f_args term
{
- parser->in_kwarg = !!$<num>1;
+ p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
$$ = $2;
SET_LEX_STATE(EXPR_BEG);
- command_start = TRUE;
+ p->command_start = TRUE;
}
;
args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
{
- $$ = new_args_tail($1, $3, $4);
+ $$ = new_args_tail(p, $1, $3, $4, &@3);
}
| f_kwarg opt_f_block_arg
{
- $$ = new_args_tail($1, Qnone, $2);
+ $$ = new_args_tail(p, $1, Qnone, $2, &@1);
}
- | f_kwrest opt_f_block_arg
+ | f_any_kwrest opt_f_block_arg
{
- $$ = new_args_tail(Qnone, $1, $2);
+ $$ = new_args_tail(p, Qnone, $1, $2, &@1);
}
| f_block_arg
{
- $$ = new_args_tail(Qnone, Qnone, $1);
+ $$ = new_args_tail(p, Qnone, Qnone, $1, &@1);
}
;
@@ -4217,119 +5102,125 @@ opt_args_tail : ',' args_tail
}
| /* none */
{
- $$ = new_args_tail(Qnone, Qnone, Qnone);
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
}
;
f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
{
- $$ = new_args($1, $3, $5, Qnone, $6);
+ $$ = new_args(p, $1, $3, $5, Qnone, $6, &@$);
}
| f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
{
- $$ = new_args($1, $3, $5, $7, $8);
+ $$ = new_args(p, $1, $3, $5, $7, $8, &@$);
}
| f_arg ',' f_optarg opt_args_tail
{
- $$ = new_args($1, $3, Qnone, Qnone, $4);
+ $$ = new_args(p, $1, $3, Qnone, Qnone, $4, &@$);
}
| f_arg ',' f_optarg ',' f_arg opt_args_tail
{
- $$ = new_args($1, $3, Qnone, $5, $6);
+ $$ = new_args(p, $1, $3, Qnone, $5, $6, &@$);
}
| f_arg ',' f_rest_arg opt_args_tail
{
- $$ = new_args($1, Qnone, $3, Qnone, $4);
+ $$ = new_args(p, $1, Qnone, $3, Qnone, $4, &@$);
}
| f_arg ',' f_rest_arg ',' f_arg opt_args_tail
{
- $$ = new_args($1, Qnone, $3, $5, $6);
+ $$ = new_args(p, $1, Qnone, $3, $5, $6, &@$);
}
| f_arg opt_args_tail
{
- $$ = new_args($1, Qnone, Qnone, Qnone, $2);
+ $$ = new_args(p, $1, Qnone, Qnone, Qnone, $2, &@$);
}
| f_optarg ',' f_rest_arg opt_args_tail
{
- $$ = new_args(Qnone, $1, $3, Qnone, $4);
+ $$ = new_args(p, Qnone, $1, $3, Qnone, $4, &@$);
}
| f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
{
- $$ = new_args(Qnone, $1, $3, $5, $6);
+ $$ = new_args(p, Qnone, $1, $3, $5, $6, &@$);
}
| f_optarg opt_args_tail
{
- $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
+ $$ = new_args(p, Qnone, $1, Qnone, Qnone, $2, &@$);
}
| f_optarg ',' f_arg opt_args_tail
{
- $$ = new_args(Qnone, $1, Qnone, $3, $4);
+ $$ = new_args(p, Qnone, $1, Qnone, $3, $4, &@$);
}
| f_rest_arg opt_args_tail
{
- $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
+ $$ = new_args(p, Qnone, Qnone, $1, Qnone, $2, &@$);
}
| f_rest_arg ',' f_arg opt_args_tail
{
- $$ = new_args(Qnone, Qnone, $1, $3, $4);
+ $$ = new_args(p, Qnone, Qnone, $1, $3, $4, &@$);
}
| args_tail
{
- $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
+ $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $1, &@$);
}
| /* none */
{
- $$ = new_args_tail(Qnone, Qnone, Qnone);
- $$ = new_args(Qnone, Qnone, Qnone, Qnone, $$);
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
+ $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $$, &@0);
+ }
+ ;
+
+args_forward : tBDOT3
+ {
+ /*%%%*/
+ $$ = idDot3;
+ /*% %*/
+ /*% ripper: args_forward! %*/
}
;
f_bad_arg : tCONSTANT
{
+ static const char mesg[] = "formal argument cannot be a constant";
/*%%%*/
- yyerror("formal argument cannot be a constant");
+ yyerror1(&@1, mesg);
$$ = 0;
- /*%
- $$ = dispatch1(param_error, $1);
- ripper_error();
- %*/
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
}
| tIVAR
{
+ static const char mesg[] = "formal argument cannot be an instance variable";
/*%%%*/
- yyerror("formal argument cannot be an instance variable");
+ yyerror1(&@1, mesg);
$$ = 0;
- /*%
- $$ = dispatch1(param_error, $1);
- ripper_error();
- %*/
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
}
| tGVAR
{
+ static const char mesg[] = "formal argument cannot be a global variable";
/*%%%*/
- yyerror("formal argument cannot be a global variable");
+ yyerror1(&@1, mesg);
$$ = 0;
- /*%
- $$ = dispatch1(param_error, $1);
- ripper_error();
- %*/
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
}
| tCVAR
{
+ static const char mesg[] = "formal argument cannot be a class variable";
/*%%%*/
- yyerror("formal argument cannot be a class variable");
+ yyerror1(&@1, mesg);
$$ = 0;
- /*%
- $$ = dispatch1(param_error, $1);
- ripper_error();
- %*/
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
}
;
f_norm_arg : f_bad_arg
| tIDENTIFIER
{
- formal_argument(get_id($1));
+ formal_argument(p, $1);
+ p->max_numparam = ORDINAL_PARAM;
$$ = $1;
}
;
@@ -4337,109 +5228,96 @@ f_norm_arg : f_bad_arg
f_arg_asgn : f_norm_arg
{
ID id = get_id($1);
- arg_var(id);
- current_arg = id;
+ arg_var(p, id);
+ p->cur_arg = id;
$$ = $1;
}
;
f_arg_item : f_arg_asgn
{
- current_arg = 0;
+ p->cur_arg = 0;
/*%%%*/
- $$ = NEW_ARGS_AUX($1, 1);
- /*%
- $$ = get_value($1);
- %*/
+ $$ = NEW_ARGS_AUX($1, 1, &NULL_LOC);
+ /*% %*/
+ /*% ripper: get_value($1) %*/
}
| tLPAREN f_margs rparen
{
- ID tid = internal_id();
- arg_var(tid);
/*%%%*/
- if (dyna_in_block()) {
- $2->nd_value = NEW_DVAR(tid);
+ ID tid = internal_id(p);
+ YYLTYPE loc;
+ loc.beg_pos = @2.beg_pos;
+ loc.end_pos = @2.beg_pos;
+ arg_var(p, tid);
+ if (dyna_in_block(p)) {
+ $2->nd_value = NEW_DVAR(tid, &loc);
}
else {
- $2->nd_value = NEW_LVAR(tid);
+ $2->nd_value = NEW_LVAR(tid, &loc);
}
- $$ = NEW_ARGS_AUX(tid, 1);
+ $$ = NEW_ARGS_AUX(tid, 1, &NULL_LOC);
$$->nd_next = $2;
- /*%
- $$ = dispatch1(mlhs_paren, $2);
- %*/
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
}
;
f_arg : f_arg_item
- /*%c%*/
- /*%c
- {
- $$ = rb_ary_new3(1, get_value($1));
- }
- c%*/
+ /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
| f_arg ',' f_arg_item
{
/*%%%*/
$$ = $1;
$$->nd_plen++;
- $$->nd_next = block_append($$->nd_next, $3->nd_next);
- rb_gc_force_recycle((VALUE)$3);
- /*%
- $$ = rb_ary_push($1, get_value($3));
- %*/
+ $$->nd_next = block_append(p, $$->nd_next, $3->nd_next);
+ rb_discard_node(p, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
}
;
f_label : tLABEL
{
- ID id = get_id($1);
- arg_var(formal_argument(id));
- current_arg = id;
+ arg_var(p, formal_argument(p, $1));
+ p->cur_arg = get_id($1);
+ p->max_numparam = ORDINAL_PARAM;
$$ = $1;
}
;
f_kw : f_label arg_value
{
- current_arg = 0;
- $$ = assignable($1, $2);
+ p->cur_arg = 0;
/*%%%*/
- $$ = new_kw_arg($$);
- /*%
- $$ = rb_assoc_new(get_value($$), get_value($2));
- %*/
+ $$ = new_kw_arg(p, assignable(p, $1, $2, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
}
| f_label
{
- current_arg = 0;
- $$ = assignable($1, (NODE *)-1);
+ p->cur_arg = 0;
/*%%%*/
- $$ = new_kw_arg($$);
- /*%
- $$ = rb_assoc_new(get_value($$), 0);
- %*/
+ $$ = new_kw_arg(p, assignable(p, $1, NODE_SPECIAL_REQUIRED_KEYWORD, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
}
;
f_block_kw : f_label primary_value
{
- $$ = assignable($1, $2);
/*%%%*/
- $$ = new_kw_arg($$);
- /*%
- $$ = rb_assoc_new(get_value($$), get_value($2));
- %*/
+ $$ = new_kw_arg(p, assignable(p, $1, $2, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
}
| f_label
{
- $$ = assignable($1, (NODE *)-1);
/*%%%*/
- $$ = new_kw_arg($$);
- /*%
- $$ = rb_assoc_new(get_value($$), 0);
- %*/
+ $$ = new_kw_arg(p, assignable(p, $1, NODE_SPECIAL_REQUIRED_KEYWORD, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
}
;
@@ -4447,17 +5325,15 @@ f_block_kwarg : f_block_kw
{
/*%%%*/
$$ = $1;
- /*%
- $$ = rb_ary_new3(1, get_value($1));
- %*/
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
}
| f_block_kwarg ',' f_block_kw
{
/*%%%*/
$$ = kwd_append($1, $3);
- /*%
- $$ = rb_ary_push($1, get_value($3));
- %*/
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
}
;
@@ -4466,17 +5342,15 @@ f_kwarg : f_kw
{
/*%%%*/
$$ = $1;
- /*%
- $$ = rb_ary_new3(1, get_value($1));
- %*/
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
}
| f_kwarg ',' f_kw
{
/*%%%*/
$$ = kwd_append($1, $3);
- /*%
- $$ = rb_ary_push($1, get_value($3));
- %*/
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
}
;
@@ -4484,47 +5358,49 @@ kwrest_mark : tPOW
| tDSTAR
;
+f_no_kwarg : kwrest_mark keyword_nil
+ {
+ /*%%%*/
+ /*% %*/
+ /*% ripper: nokw_param!(Qnil) %*/
+ }
+ ;
+
f_kwrest : kwrest_mark tIDENTIFIER
{
- shadowing_lvar(get_id($2));
+ arg_var(p, shadowing_lvar(p, get_id($2)));
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(kwrest_param, $2);
- %*/
+ /*% %*/
+ /*% ripper: kwrest_param!($2) %*/
}
| kwrest_mark
{
/*%%%*/
- $$ = internal_id();
- arg_var($$);
- /*%
- $$ = dispatch1(kwrest_param, Qnil);
- %*/
+ $$ = internal_id(p);
+ arg_var(p, $$);
+ /*% %*/
+ /*% ripper: kwrest_param!(Qnil) %*/
}
;
f_opt : f_arg_asgn '=' arg_value
{
- current_arg = 0;
- $$ = assignable($1, $3);
+ p->cur_arg = 0;
/*%%%*/
- $$ = NEW_OPT_ARG(0, $$);
- /*%
- $$ = rb_assoc_new(get_value($$), get_value($3));
- %*/
+ $$ = NEW_OPT_ARG(0, assignable(p, $1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
}
;
f_block_opt : f_arg_asgn '=' primary_value
{
- current_arg = 0;
- $$ = assignable($1, $3);
+ p->cur_arg = 0;
/*%%%*/
- $$ = NEW_OPT_ARG(0, $$);
- /*%
- $$ = rb_assoc_new(get_value($$), get_value($3));
- %*/
+ $$ = NEW_OPT_ARG(0, assignable(p, $1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
}
;
@@ -4532,23 +5408,15 @@ f_block_optarg : f_block_opt
{
/*%%%*/
$$ = $1;
- /*%
- $$ = rb_ary_new3(1, get_value($1));
- %*/
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
}
| f_block_optarg ',' f_block_opt
{
/*%%%*/
- NODE *opts = $1;
-
- while (opts->nd_next) {
- opts = opts->nd_next;
- }
- opts->nd_next = $3;
- $$ = $1;
- /*%
- $$ = rb_ary_push($1, get_value($3));
- %*/
+ $$ = opt_arg_append($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
}
;
@@ -4556,23 +5424,15 @@ f_optarg : f_opt
{
/*%%%*/
$$ = $1;
- /*%
- $$ = rb_ary_new3(1, get_value($1));
- %*/
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
}
| f_optarg ',' f_opt
{
/*%%%*/
- NODE *opts = $1;
-
- while (opts->nd_next) {
- opts = opts->nd_next;
- }
- opts->nd_next = $3;
- $$ = $1;
- /*%
- $$ = rb_ary_push($1, get_value($3));
- %*/
+ $$ = opt_arg_append($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
}
;
@@ -4582,25 +5442,19 @@ restarg_mark : '*'
f_rest_arg : restarg_mark tIDENTIFIER
{
- /*%%%*/
- if (!is_local_id($2))
- yyerror("rest argument must be local variable");
- /*% %*/
- arg_var(shadowing_lvar(get_id($2)));
+ arg_var(p, shadowing_lvar(p, get_id($2)));
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(rest_param, $2);
- %*/
+ /*% %*/
+ /*% ripper: rest_param!($2) %*/
}
| restarg_mark
{
/*%%%*/
- $$ = internal_id();
- arg_var($$);
- /*%
- $$ = dispatch1(rest_param, Qnil);
- %*/
+ $$ = internal_id(p);
+ arg_var(p, $$);
+ /*% %*/
+ /*% ripper: rest_param!(Qnil) %*/
}
;
@@ -4610,18 +5464,11 @@ blkarg_mark : '&'
f_block_arg : blkarg_mark tIDENTIFIER
{
- /*%%%*/
- if (!is_local_id($2))
- yyerror("block argument must be local variable");
- else if (!dyna_in_block() && local_id($2))
- yyerror("duplicated block argument name");
- /*% %*/
- arg_var(shadowing_lvar(get_id($2)));
+ arg_var(p, shadowing_lvar(p, get_id($2)));
/*%%%*/
$$ = $2;
- /*%
- $$ = dispatch1(blockarg, $2);
- %*/
+ /*% %*/
+ /*% ripper: blockarg!($2) %*/
}
;
@@ -4631,51 +5478,36 @@ opt_f_block_arg : ',' f_block_arg
}
| none
{
- /*%%%*/
- $$ = 0;
- /*%
- $$ = Qundef;
- %*/
+ $$ = Qnull;
}
;
singleton : var_ref
{
- /*%%%*/
value_expr($1);
$$ = $1;
- if (!$$) $$ = NEW_NIL();
- /*%
- $$ = $1;
- %*/
}
| '(' {SET_LEX_STATE(EXPR_BEG);} expr rparen
{
/*%%%*/
- if ($3 == 0) {
- yyerror("can't define singleton method for ().");
- }
- else {
- switch (nd_type($3)) {
- case NODE_STR:
- case NODE_DSTR:
- case NODE_XSTR:
- case NODE_DXSTR:
- case NODE_DREGX:
- case NODE_LIT:
- case NODE_ARRAY:
- case NODE_ZARRAY:
- yyerror("can't define singleton method for literals");
- break;
- default:
- value_expr($3);
- break;
- }
+ switch (nd_type($3)) {
+ case NODE_STR:
+ case NODE_DSTR:
+ case NODE_XSTR:
+ case NODE_DXSTR:
+ case NODE_DREGX:
+ case NODE_LIT:
+ case NODE_LIST:
+ case NODE_ZLIST:
+ yyerror1(&@3, "can't define singleton method for literals");
+ break;
+ default:
+ value_expr($3);
+ break;
}
$$ = $3;
- /*%
- $$ = dispatch1(paren, $3);
- %*/
+ /*% %*/
+ /*% ripper: paren!($3) %*/
}
;
@@ -4684,19 +5516,13 @@ assoc_list : none
{
/*%%%*/
$$ = $1;
- /*%
- $$ = dispatch1(assoclist_from_args, $1);
- %*/
+ /*% %*/
+ /*% ripper: assoclist_from_args!($1) %*/
}
;
assocs : assoc
- /*%c%*/
- /*%c
- {
- $$ = rb_ary_new3(1, get_value($1));
- }
- %*/
+ /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
| assocs ',' assoc
{
/*%%%*/
@@ -4706,18 +5532,17 @@ assocs : assoc
assocs = tail;
}
else if (tail) {
- if (assocs->nd_head &&
- !tail->nd_head && nd_type(tail->nd_next) == NODE_ARRAY &&
- nd_type(tail->nd_next->nd_head) == NODE_HASH) {
- /* DSTAR */
- tail = tail->nd_next->nd_head->nd_head;
- }
+ if (assocs->nd_head &&
+ !tail->nd_head && nd_type(tail->nd_next) == NODE_LIST &&
+ nd_type(tail->nd_next->nd_head) == NODE_HASH) {
+ /* DSTAR */
+ tail = tail->nd_next->nd_head->nd_head;
+ }
assocs = list_concat(assocs, tail);
}
$$ = assocs;
- /*%
- $$ = rb_ary_push($1, get_value($3));
- %*/
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
}
;
@@ -4726,40 +5551,43 @@ assoc : arg_value tASSOC arg_value
/*%%%*/
if (nd_type($1) == NODE_STR) {
nd_set_type($1, NODE_LIT);
- $1->nd_lit = rb_fstring($1->nd_lit);
+ RB_OBJ_WRITE(p->ast, &$1->nd_lit, rb_fstring($1->nd_lit));
}
- $$ = list_append(NEW_LIST($1), $3);
- /*%
- $$ = dispatch2(assoc_new, $1, $3);
- %*/
+ $$ = list_append(p, NEW_LIST($1, &@$), $3);
+ /*% %*/
+ /*% ripper: assoc_new!($1, $3) %*/
}
| tLABEL arg_value
{
/*%%%*/
- $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
- /*%
- $$ = dispatch2(assoc_new, $1, $2);
- %*/
+ $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), $2);
+ /*% %*/
+ /*% ripper: assoc_new!($1, $2) %*/
}
| tSTRING_BEG string_contents tLABEL_END arg_value
{
/*%%%*/
- $$ = list_append(NEW_LIST(dsym_node($2)), $4);
- /*%
- $$ = dispatch2(assoc_new, dispatch1(dyna_symbol, $2), $4);
- %*/
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ $$ = list_append(p, NEW_LIST(dsym_node(p, $2, &loc), &loc), $4);
+ /*% %*/
+ /*% ripper: assoc_new!(dyna_symbol!($2), $4) %*/
}
| tDSTAR arg_value
{
/*%%%*/
- if (nd_type($2) == NODE_HASH &&
- !($2->nd_head && $2->nd_head->nd_alen))
- $$ = 0;
- else
- $$ = list_append(NEW_LIST(0), $2);
- /*%
- $$ = dispatch1(assoc_splat, $2);
- %*/
+ if (nd_type($2) == NODE_HASH &&
+ !($2->nd_head && $2->nd_head->nd_alen)) {
+ static VALUE empty_hash;
+ if (!empty_hash) {
+ empty_hash = rb_obj_freeze(rb_hash_new());
+ rb_gc_register_mark_object(empty_hash);
+ }
+ $$ = list_append(p, NEW_LIST(0, &@$), NEW_LIT(empty_hash, &@$));
+ }
+ else
+ $$ = list_append(p, NEW_LIST(0, &@$), $2);
+ /*% %*/
+ /*% ripper: assoc_splat!($2) %*/
}
;
@@ -4784,20 +5612,11 @@ dot_or_colon : '.'
;
call_op : '.'
- {
- $$ = TOKEN2VAL('.');
- }
| tANDDOT
- {
- $$ = ID2VAL(idANDDOT);
- }
;
call_op2 : call_op
| tCOLON2
- {
- $$ = ID2VAL(idCOLON2);
- }
;
opt_terms : /* none */
@@ -4814,13 +5633,16 @@ rparen : opt_nl ')'
rbracket : opt_nl ']'
;
+rbrace : opt_nl '}'
+ ;
+
trailer : /* none */
| '\n'
| ','
;
-term : ';' {yyerrok;token_flush(parser);}
- | '\n' {token_flush(parser);}
+term : ';' {yyerrok;token_flush(p);}
+ | '\n' {token_flush(p);}
;
terms : term
@@ -4833,68 +5655,62 @@ none : /* none */
}
;
%%
-# undef parser
+# undef p
# undef yylex
# undef yylval
-# define yylval (*parser->lval)
-
-static int parser_regx_options(struct parser_params*);
-static int parser_tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**);
-static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc);
-static enum yytokentype parser_parse_string(struct parser_params*,NODE*);
-static enum yytokentype parser_here_document(struct parser_params*,NODE*);
-
-
-# define nextc() parser_nextc(parser)
-# define pushback(c) parser_pushback(parser, (c))
-# define newtok() parser_newtok(parser)
-# define tokspace(n) parser_tokspace(parser, (n))
-# define tokadd(c) parser_tokadd(parser, (c))
-# define tok_hex(numlen) parser_tok_hex(parser, (numlen))
-# define read_escape(flags,e) parser_read_escape(parser, (flags), (e))
-# define tokadd_escape(e) parser_tokadd_escape(parser, (e))
-# define regx_options() parser_regx_options(parser)
-# define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser,(f),(t),(p),(n),(e))
-# define parse_string(n) parser_parse_string(parser,(n))
-# define tokaddmbc(c, enc) parser_tokaddmbc(parser, (c), (enc))
-# define here_document(n) parser_here_document(parser,(n))
-# define heredoc_identifier() parser_heredoc_identifier(parser)
-# define heredoc_restore(n) parser_heredoc_restore(parser,(n))
-# define whole_match_p(e,l,i) parser_whole_match_p(parser,(e),(l),(i))
-# define number_literal_suffix(f) parser_number_literal_suffix(parser, (f))
-# define set_number_literal(v, t, f) parser_set_number_literal(parser, (v), (t), (f))
-# define set_integer_literal(v, f) parser_set_integer_literal(parser, (v), (f))
+# define yylval (*p->lval)
+
+static int regx_options(struct parser_params*);
+static int tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**,rb_encoding**);
+static void tokaddmbc(struct parser_params *p, int c, rb_encoding *enc);
+static enum yytokentype parse_string(struct parser_params*,rb_strterm_literal_t*);
+static enum yytokentype here_document(struct parser_params*,rb_strterm_heredoc_t*);
#ifndef RIPPER
-# define set_yylval_str(x) (yylval.node = NEW_STR(x))
+# define set_yylval_node(x) { \
+ YYLTYPE _cur_loc; \
+ rb_parser_set_location(p, &_cur_loc); \
+ yylval.node = (x); \
+}
+# define set_yylval_str(x) \
+do { \
+ set_yylval_node(NEW_STR(x, &_cur_loc)); \
+ RB_OBJ_WRITTEN(p->ast, Qnil, x); \
+} while(0)
+# define set_yylval_literal(x) \
+do { \
+ set_yylval_node(NEW_LIT(x, &_cur_loc)); \
+ RB_OBJ_WRITTEN(p->ast, Qnil, x); \
+} while(0)
# define set_yylval_num(x) (yylval.num = (x))
# define set_yylval_id(x) (yylval.id = (x))
# define set_yylval_name(x) (yylval.id = (x))
-# define set_yylval_literal(x) (yylval.node = NEW_LIT(x))
-# define set_yylval_node(x) (yylval.node = (x))
# define yylval_id() (yylval.id)
#else
static inline VALUE
-ripper_yylval_id(ID x)
+ripper_yylval_id(struct parser_params *p, ID x)
{
- return ripper_new_yylval(x, ID2SYM(x), 0);
+ return ripper_new_yylval(p, x, ID2SYM(x), 0);
}
-# define set_yylval_str(x) (yylval.val = (x))
-# define set_yylval_num(x) (yylval.val = ripper_new_yylval((x), 0, 0))
+# define set_yylval_str(x) (yylval.val = add_mark_object(p, (x)))
+# define set_yylval_num(x) (yylval.val = ripper_new_yylval(p, (x), 0, 0))
# define set_yylval_id(x) (void)(x)
-# define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
-# define set_yylval_literal(x) (void)(x)
-# define set_yylval_node(x) (void)(x)
+# define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(p, x))
+# define set_yylval_literal(x) add_mark_object(p, (x))
+# define set_yylval_node(x) (yylval.val = ripper_new_yylval(p, 0, 0, STR_NEW(p->lex.ptok, p->lex.pcur-p->lex.ptok)))
# define yylval_id() yylval.id
+# define _cur_loc NULL_LOC /* dummy */
#endif
+#define set_yylval_noname() set_yylval_id(keyword_nil)
+
#ifndef RIPPER
-#define literal_flush(p) (parser->tokp = (p))
-#define dispatch_scan_event(t) ((void)0)
-#define dispatch_delayed_token(t) ((void)0)
-#define has_delayed_token() (0)
+#define literal_flush(p, ptr) ((p)->lex.ptok = (ptr))
+#define dispatch_scan_event(p, t) ((void)0)
+#define dispatch_delayed_token(p, t) ((void)0)
+#define has_delayed_token(p) (0)
#else
-#define literal_flush(p) ((void)0)
+#define literal_flush(p, ptr) ((void)(ptr))
#define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
@@ -4906,218 +5722,344 @@ intern_sym(const char *name)
}
static int
-ripper_has_scan_event(struct parser_params *parser)
+ripper_has_scan_event(struct parser_params *p)
{
-
- if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
- return lex_p > parser->tokp;
+ if (p->lex.pcur < p->lex.ptok) rb_raise(rb_eRuntimeError, "lex.pcur < lex.ptok");
+ return p->lex.pcur > p->lex.ptok;
}
static VALUE
-ripper_scan_event_val(struct parser_params *parser, int t)
+ripper_scan_event_val(struct parser_params *p, enum yytokentype t)
{
- VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
- VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
- token_flush(parser);
+ VALUE str = STR_NEW(p->lex.ptok, p->lex.pcur - p->lex.ptok);
+ VALUE rval = ripper_dispatch1(p, ripper_token2eventid(t), str);
+ token_flush(p);
return rval;
}
static void
-ripper_dispatch_scan_event(struct parser_params *parser, int t)
+ripper_dispatch_scan_event(struct parser_params *p, enum yytokentype t)
{
- if (!ripper_has_scan_event(parser)) return;
- yylval_rval = ripper_scan_event_val(parser, t);
+ if (!ripper_has_scan_event(p)) return;
+ add_mark_object(p, yylval_rval = ripper_scan_event_val(p, t));
}
-#define dispatch_scan_event(t) ripper_dispatch_scan_event(parser, t)
+#define dispatch_scan_event(p, t) ripper_dispatch_scan_event(p, t)
static void
-ripper_dispatch_delayed_token(struct parser_params *parser, int t)
+ripper_dispatch_delayed_token(struct parser_params *p, enum yytokentype t)
{
- int saved_line = ruby_sourceline;
- const char *saved_tokp = parser->tokp;
+ int saved_line = p->ruby_sourceline;
+ const char *saved_tokp = p->lex.ptok;
- ruby_sourceline = parser->delayed_line;
- parser->tokp = lex_pbeg + parser->delayed_col;
- yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), parser->delayed);
- parser->delayed = Qnil;
- ruby_sourceline = saved_line;
- parser->tokp = saved_tokp;
+ if (NIL_P(p->delayed.token)) return;
+ p->ruby_sourceline = p->delayed.line;
+ p->lex.ptok = p->lex.pbeg + p->delayed.col;
+ add_mark_object(p, yylval_rval = ripper_dispatch1(p, ripper_token2eventid(t), p->delayed.token));
+ p->delayed.token = Qnil;
+ p->ruby_sourceline = saved_line;
+ p->lex.ptok = saved_tokp;
}
-#define dispatch_delayed_token(t) ripper_dispatch_delayed_token(parser, t)
-#define has_delayed_token() (!NIL_P(parser->delayed))
+#define dispatch_delayed_token(p, t) ripper_dispatch_delayed_token(p, t)
+#define has_delayed_token(p) (!NIL_P(p->delayed.token))
#endif /* RIPPER */
-#include "ruby/regex.h"
-#include "ruby/util.h"
+static inline int
+is_identchar(const char *ptr, const char *MAYBE_UNUSED(ptr_end), rb_encoding *enc)
+{
+ return rb_enc_isalnum((unsigned char)*ptr, enc) || *ptr == '_' || !ISASCII(*ptr);
+}
-#define parser_encoding_name() (current_enc->name)
-#define parser_mbclen() mbclen((lex_p-1),lex_pend,current_enc)
-#define is_identchar(p,e,enc) (rb_enc_isalnum((unsigned char)(*(p)),(enc)) || (*(p)) == '_' || !ISASCII(*(p)))
-#define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,current_enc))
+static inline int
+parser_is_identchar(struct parser_params *p)
+{
+ return !(p)->eofp && is_identchar(p->lex.pcur-1, p->lex.pend, p->enc);
+}
-#define parser_isascii() ISASCII(*(lex_p-1))
+static inline int
+parser_isascii(struct parser_params *p)
+{
+ return ISASCII(*(p->lex.pcur-1));
+}
-static int
-token_info_get_column(struct parser_params *parser, const char *pend)
+static void
+token_info_setup(token_info *ptinfo, const char *ptr, const rb_code_location_t *loc)
{
- int column = 1;
- const char *p;
- for (p = lex_pbeg; p < pend; p++) {
- if (*p == '\t') {
+ int column = 1, nonspc = 0, i;
+ for (i = 0; i < loc->beg_pos.column; i++, ptr++) {
+ if (*ptr == '\t') {
column = (((column - 1) / TAB_WIDTH) + 1) * TAB_WIDTH;
}
column++;
- }
- return column;
-}
-
-static int
-token_info_has_nonspaces(struct parser_params *parser, const char *pend)
-{
- const char *p;
- for (p = lex_pbeg; p < pend; p++) {
- if (*p != ' ' && *p != '\t') {
- return 1;
+ if (*ptr != ' ' && *ptr != '\t') {
+ nonspc = 1;
}
}
- return 0;
+
+ ptinfo->beg = loc->beg_pos;
+ ptinfo->indent = column;
+ ptinfo->nonspc = nonspc;
}
static void
-token_info_push_gen(struct parser_params *parser, const char *token, size_t len)
+token_info_push(struct parser_params *p, const char *token, const rb_code_location_t *loc)
{
token_info *ptinfo;
- const char *t = lex_p - len;
- if (!parser->token_info_enabled) return;
+ if (!p->token_info_enabled) return;
ptinfo = ALLOC(token_info);
ptinfo->token = token;
- ptinfo->linenum = ruby_sourceline;
- ptinfo->column = token_info_get_column(parser, t);
- ptinfo->nonspc = token_info_has_nonspaces(parser, t);
- ptinfo->next = parser->token_info;
+ ptinfo->next = p->token_info;
+ token_info_setup(ptinfo, p->lex.pbeg, loc);
+
+ p->token_info = ptinfo;
+}
+
+static void
+token_info_pop(struct parser_params *p, const char *token, const rb_code_location_t *loc)
+{
+ token_info *ptinfo_beg = p->token_info;
+
+ if (!ptinfo_beg) return;
+ p->token_info = ptinfo_beg->next;
- parser->token_info = ptinfo;
+ /* indentation check of matched keywords (begin..end, if..end, etc.) */
+ token_info_warn(p, token, ptinfo_beg, 1, loc);
+ ruby_sized_xfree(ptinfo_beg, sizeof(*ptinfo_beg));
}
static void
-token_info_pop_gen(struct parser_params *parser, const char *token, size_t len)
+token_info_drop(struct parser_params *p, const char *token, rb_code_position_t beg_pos)
{
- int linenum;
- token_info *ptinfo = parser->token_info;
- const char *t = lex_p - len;
+ token_info *ptinfo_beg = p->token_info;
+
+ if (!ptinfo_beg) return;
+ p->token_info = ptinfo_beg->next;
- if (!ptinfo) return;
- parser->token_info = ptinfo->next;
- linenum = ruby_sourceline;
- if (parser->token_info_enabled &&
- linenum != ptinfo->linenum && !ptinfo->nonspc &&
- !token_info_has_nonspaces(parser, t) &&
- token_info_get_column(parser, t) != ptinfo->column) {
- rb_warn3L(linenum,
- "mismatched indentations at '%s' with '%s' at %d",
- WARN_S(token), WARN_S(ptinfo->token), WARN_I(ptinfo->linenum));
+ if (ptinfo_beg->beg.lineno != beg_pos.lineno ||
+ ptinfo_beg->beg.column != beg_pos.column ||
+ strcmp(ptinfo_beg->token, token)) {
+ compile_error(p, "token position mismatch: %d:%d:%s expected but %d:%d:%s",
+ beg_pos.lineno, beg_pos.column, token,
+ ptinfo_beg->beg.lineno, ptinfo_beg->beg.column,
+ ptinfo_beg->token);
}
- xfree(ptinfo);
+ ruby_sized_xfree(ptinfo_beg, sizeof(*ptinfo_beg));
+}
+
+static void
+token_info_warn(struct parser_params *p, const char *token, token_info *ptinfo_beg, int same, const rb_code_location_t *loc)
+{
+ token_info ptinfo_end_body, *ptinfo_end = &ptinfo_end_body;
+ if (!p->token_info_enabled) return;
+ if (!ptinfo_beg) return;
+ token_info_setup(ptinfo_end, p->lex.pbeg, loc);
+ if (ptinfo_beg->beg.lineno == ptinfo_end->beg.lineno) return; /* ignore one-line block */
+ if (ptinfo_beg->nonspc || ptinfo_end->nonspc) return; /* ignore keyword in the middle of a line */
+ if (ptinfo_beg->indent == ptinfo_end->indent) return; /* the indents are matched */
+ if (!same && ptinfo_beg->indent < ptinfo_end->indent) return;
+ rb_warn3L(ptinfo_end->beg.lineno,
+ "mismatched indentations at '%s' with '%s' at %d",
+ WARN_S(token), WARN_S(ptinfo_beg->token), WARN_I(ptinfo_beg->beg.lineno));
}
static int
-parser_precise_mbclen(struct parser_params *parser, const char *p)
+parser_precise_mbclen(struct parser_params *p, const char *ptr)
{
- int len = rb_enc_precise_mbclen(p, lex_pend, current_enc);
+ int len = rb_enc_precise_mbclen(ptr, p->lex.pend, p->enc);
if (!MBCLEN_CHARFOUND_P(len)) {
- compile_error(PARSER_ARG "invalid multibyte char (%s)", parser_encoding_name());
+ compile_error(p, "invalid multibyte char (%s)", rb_enc_name(p->enc));
return -1;
}
return len;
}
+#ifndef RIPPER
+static void ruby_show_error_line(VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str);
+
+static inline void
+parser_show_error_line(struct parser_params *p, const YYLTYPE *yylloc)
+{
+ VALUE str;
+ int lineno = p->ruby_sourceline;
+ if (!yylloc) {
+ return;
+ }
+ else if (yylloc->beg_pos.lineno == lineno) {
+ str = p->lex.lastline;
+ }
+ else {
+ return;
+ }
+ ruby_show_error_line(p->error_buffer, yylloc, lineno, str);
+}
+
static int
-parser_yyerror(struct parser_params *parser, const char *msg)
+parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg)
{
-#ifndef RIPPER
+ YYLTYPE current;
+
+ if (!yylloc) {
+ yylloc = RUBY_SET_YYLLOC(current);
+ }
+ else if ((p->ruby_sourceline != yylloc->beg_pos.lineno &&
+ p->ruby_sourceline != yylloc->end_pos.lineno) ||
+ (yylloc->beg_pos.lineno == yylloc->end_pos.lineno &&
+ yylloc->beg_pos.column == yylloc->end_pos.column)) {
+ yylloc = 0;
+ }
+ compile_error(p, "%s", msg);
+ parser_show_error_line(p, yylloc);
+ return 0;
+}
+
+static void
+ruby_show_error_line(VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str)
+{
+ VALUE mesg;
const int max_line_margin = 30;
- const char *p, *pe;
+ const char *ptr, *ptr_end, *pt, *pb;
const char *pre = "", *post = "", *pend;
- const char *code = "", *caret = "", *newline = "";
+ const char *code = "", *caret = "";
const char *lim;
+ const char *const pbeg = RSTRING_PTR(str);
char *buf;
long len;
int i;
- pend = lex_pend;
- if (pend > lex_pbeg && pend[-1] == '\n') {
- if (--pend > lex_pbeg && pend[-1] == '\r') --pend;
+ if (!yylloc) return;
+ pend = RSTRING_END(str);
+ if (pend > pbeg && pend[-1] == '\n') {
+ if (--pend > pbeg && pend[-1] == '\r') --pend;
}
- p = pe = lex_p < pend ? lex_p : pend;
- lim = p - lex_pbeg > max_line_margin ? p - max_line_margin : lex_pbeg;
- while ((lim < p) && (*(p-1) != '\n')) p--;
+ pt = pend;
+ if (lineno == yylloc->end_pos.lineno &&
+ (pend - pbeg) > yylloc->end_pos.column) {
+ pt = pbeg + yylloc->end_pos.column;
+ }
- lim = pend - pe > max_line_margin ? pe + max_line_margin : pend;
- while ((pe < lim) && (*pe != '\n')) pe++;
+ ptr = ptr_end = pt;
+ lim = ptr - pbeg > max_line_margin ? ptr - max_line_margin : pbeg;
+ while ((lim < ptr) && (*(ptr-1) != '\n')) ptr--;
- len = pe - p;
- if (len > 4) {
- char *p2;
+ lim = pend - ptr_end > max_line_margin ? ptr_end + max_line_margin : pend;
+ while ((ptr_end < lim) && (*ptr_end != '\n') && (*ptr_end != '\r')) ptr_end++;
- if (p > lex_pbeg) {
- p = rb_enc_prev_char(lex_pbeg, p, lex_p, rb_enc_get(lex_lastline));
- if (p > lex_pbeg) pre = "...";
+ len = ptr_end - ptr;
+ if (len > 4) {
+ if (ptr > pbeg) {
+ ptr = rb_enc_prev_char(pbeg, ptr, pt, rb_enc_get(str));
+ if (ptr > pbeg) pre = "...";
}
- if (pe < pend) {
- pe = rb_enc_prev_char(lex_p, pe, pend, rb_enc_get(lex_lastline));
- if (pe < pend) post = "...";
+ if (ptr_end < pend) {
+ ptr_end = rb_enc_prev_char(pt, ptr_end, pend, rb_enc_get(str));
+ if (ptr_end < pend) post = "...";
}
- len = pe - p;
- lim = lex_p < pend ? lex_p : pend;
- i = (int)(lim - p);
+ }
+ pb = pbeg;
+ if (lineno == yylloc->beg_pos.lineno) {
+ pb += yylloc->beg_pos.column;
+ if (pb > pt) pb = pt;
+ }
+ if (pb < ptr) pb = ptr;
+ if (len <= 4 && yylloc->beg_pos.lineno == yylloc->end_pos.lineno) {
+ return;
+ }
+ if (RTEST(errbuf)) {
+ mesg = rb_attr_get(errbuf, idMesg);
+ if (RSTRING_LEN(mesg) > 0 && *(RSTRING_END(mesg)-1) != '\n')
+ rb_str_cat_cstr(mesg, "\n");
+ }
+ else {
+ mesg = rb_enc_str_new(0, 0, rb_enc_get(str));
+ }
+ if (!errbuf && rb_stderr_tty_p()) {
+#define CSI_BEGIN "\033["
+#define CSI_SGR "m"
+ rb_str_catf(mesg,
+ CSI_BEGIN""CSI_SGR"%s" /* pre */
+ CSI_BEGIN"1"CSI_SGR"%.*s"
+ CSI_BEGIN"1;4"CSI_SGR"%.*s"
+ CSI_BEGIN";1"CSI_SGR"%.*s"
+ CSI_BEGIN""CSI_SGR"%s" /* post */
+ "\n",
+ pre,
+ (int)(pb - ptr), ptr,
+ (int)(pt - pb), pb,
+ (int)(ptr_end - pt), pt,
+ post);
+ }
+ else {
+ char *p2;
+
+ len = ptr_end - ptr;
+ lim = pt < pend ? pt : pend;
+ i = (int)(lim - ptr);
buf = ALLOCA_N(char, i+2);
- code = p;
+ code = ptr;
caret = p2 = buf;
- pe = (parser->tokp < lim ? parser->tokp : lim);
- if (p <= pe) {
- while (p < pe) {
- *p2++ = *p++ == '\t' ? '\t' : ' ';
+ if (ptr <= pb) {
+ while (ptr < pb) {
+ *p2++ = *ptr++ == '\t' ? '\t' : ' ';
}
*p2++ = '^';
- p++;
+ ptr++;
}
- if (lim > p) {
- memset(p2, '~', (lim - p));
- p2 += (lim - p);
+ if (lim > ptr) {
+ memset(p2, '~', (lim - ptr));
+ p2 += (lim - ptr);
}
*p2 = '\0';
- newline = "\n";
- }
- else {
- len = 0;
+ rb_str_catf(mesg, "%s%.*s%s\n""%s%s\n",
+ pre, (int)len, code, post,
+ pre, caret);
}
- compile_error(PARSER_ARG "%s%s""%s%.*s%s%s""%s%s",
- msg, newline,
- pre, (int)len, code, post, newline,
- pre, caret);
+ if (!errbuf) rb_write_error_str(mesg);
+}
#else
+static int
+parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg)
+{
+ const char *pcur = 0, *ptok = 0;
+ if (yylloc &&
+ p->ruby_sourceline == yylloc->beg_pos.lineno &&
+ p->ruby_sourceline == yylloc->end_pos.lineno) {
+ pcur = p->lex.pcur;
+ ptok = p->lex.ptok;
+ p->lex.ptok = p->lex.pbeg + yylloc->beg_pos.column;
+ p->lex.pcur = p->lex.pbeg + yylloc->end_pos.column;
+ }
dispatch1(parse_error, STR_NEW2(msg));
- ripper_error();
-#endif /* !RIPPER */
+ ripper_error(p);
+ if (pcur) {
+ p->lex.ptok = ptok;
+ p->lex.pcur = pcur;
+ }
return 0;
}
+static inline void
+parser_show_error_line(struct parser_params *p, const YYLTYPE *yylloc)
+{
+}
+#endif /* !RIPPER */
+
+#ifndef RIPPER
static int
vtable_size(const struct vtable *tbl)
{
- if (POINTER_P(tbl)) {
+ if (!DVARS_TERMINAL_P(tbl)) {
return tbl->pos;
}
else {
return 0;
}
}
+#endif
static struct vtable *
-vtable_alloc_gen(struct parser_params *parser, int line, struct vtable *prev)
+vtable_alloc_gen(struct parser_params *p, int line, struct vtable *prev)
{
struct vtable *tbl = ALLOC(struct vtable);
tbl->pos = 0;
@@ -5125,70 +6067,70 @@ vtable_alloc_gen(struct parser_params *parser, int line, struct vtable *prev)
tbl->tbl = ALLOC_N(ID, tbl->capa);
tbl->prev = prev;
#ifndef RIPPER
- if (yydebug) {
- rb_parser_printf(parser, "vtable_alloc:%d: %p\n", line, tbl);
+ if (p->debug) {
+ rb_parser_printf(p, "vtable_alloc:%d: %p\n", line, (void *)tbl);
}
#endif
return tbl;
}
-#define vtable_alloc(prev) vtable_alloc_gen(parser, __LINE__, prev)
+#define vtable_alloc(prev) vtable_alloc_gen(p, __LINE__, prev)
static void
-vtable_free_gen(struct parser_params *parser, int line, const char *name,
+vtable_free_gen(struct parser_params *p, int line, const char *name,
struct vtable *tbl)
{
#ifndef RIPPER
- if (yydebug) {
- rb_parser_printf(parser, "vtable_free:%d: %s(%p)\n", line, name, tbl);
+ if (p->debug) {
+ rb_parser_printf(p, "vtable_free:%d: %s(%p)\n", line, name, (void *)tbl);
}
#endif
- if (POINTER_P(tbl)) {
+ if (!DVARS_TERMINAL_P(tbl)) {
if (tbl->tbl) {
- xfree(tbl->tbl);
+ ruby_sized_xfree(tbl->tbl, tbl->capa * sizeof(ID));
}
- xfree(tbl);
+ ruby_sized_xfree(tbl, sizeof(*tbl));
}
}
-#define vtable_free(tbl) vtable_free_gen(parser, __LINE__, #tbl, tbl)
+#define vtable_free(tbl) vtable_free_gen(p, __LINE__, #tbl, tbl)
static void
-vtable_add_gen(struct parser_params *parser, int line, const char *name,
+vtable_add_gen(struct parser_params *p, int line, const char *name,
struct vtable *tbl, ID id)
{
#ifndef RIPPER
- if (yydebug) {
- rb_parser_printf(parser, "vtable_add:%d: %s(%p), %s\n",
- line, name, tbl, rb_id2name(id));
+ if (p->debug) {
+ rb_parser_printf(p, "vtable_add:%d: %s(%p), %s\n",
+ line, name, (void *)tbl, rb_id2name(id));
}
#endif
- if (!POINTER_P(tbl)) {
- rb_parser_fatal(parser, "vtable_add: vtable is not allocated (%p)", (void *)tbl);
+ if (DVARS_TERMINAL_P(tbl)) {
+ rb_parser_fatal(p, "vtable_add: vtable is not allocated (%p)", (void *)tbl);
return;
}
if (tbl->pos == tbl->capa) {
tbl->capa = tbl->capa * 2;
- REALLOC_N(tbl->tbl, ID, tbl->capa);
+ SIZED_REALLOC_N(tbl->tbl, ID, tbl->capa, tbl->pos);
}
tbl->tbl[tbl->pos++] = id;
}
-#define vtable_add(tbl, id) vtable_add_gen(parser, __LINE__, #tbl, tbl, id)
+#define vtable_add(tbl, id) vtable_add_gen(p, __LINE__, #tbl, tbl, id)
#ifndef RIPPER
static void
-vtable_pop_gen(struct parser_params *parser, int line, const char *name,
+vtable_pop_gen(struct parser_params *p, int line, const char *name,
struct vtable *tbl, int n)
{
- if (yydebug) {
- rb_parser_printf(parser, "vtable_pop:%d: %s(%p), %d\n",
- line, name, tbl, n);
+ if (p->debug) {
+ rb_parser_printf(p, "vtable_pop:%d: %s(%p), %d\n",
+ line, name, (void *)tbl, n);
}
if (tbl->pos < n) {
- rb_parser_fatal(parser, "vtable_pop: unreachable (%d < %d)", tbl->pos, n);
+ rb_parser_fatal(p, "vtable_pop: unreachable (%d < %d)", tbl->pos, n);
return;
}
tbl->pos -= n;
}
-#define vtable_pop(tbl, n) vtable_pop_gen(parser, __LINE__, #tbl, tbl, n)
+#define vtable_pop(tbl, n) vtable_pop_gen(p, __LINE__, #tbl, tbl, n)
#endif
static int
@@ -5196,7 +6138,7 @@ vtable_included(const struct vtable * tbl, ID id)
{
int i;
- if (POINTER_P(tbl)) {
+ if (!DVARS_TERMINAL_P(tbl)) {
for (i = 0; i < tbl->pos; i++) {
if (tbl->tbl[i] == id) {
return i+1;
@@ -5206,9 +6148,11 @@ vtable_included(const struct vtable * tbl, ID id)
return 0;
}
-static void parser_prepare(struct parser_params *parser);
+static void parser_prepare(struct parser_params *p);
#ifndef RIPPER
+static NODE *parser_append_options(struct parser_params *p, NODE *node);
+
static VALUE
debug_lines(VALUE fname)
{
@@ -5225,25 +6169,10 @@ debug_lines(VALUE fname)
return 0;
}
-static VALUE
-coverage(VALUE fname, int n)
-{
- VALUE coverages = rb_get_coverages();
- if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
- VALUE coverage = rb_default_coverage(n);
- VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
-
- rb_hash_aset(coverages, fname, coverage);
-
- return lines == Qnil ? Qfalse : lines;
- }
- return 0;
-}
-
static int
-e_option_supplied(struct parser_params *parser)
+e_option_supplied(struct parser_params *p)
{
- return strcmp(ruby_sourcefile, "-e") == 0;
+ return strcmp(p->ruby_sourcefile, "-e") == 0;
}
static VALUE
@@ -5251,71 +6180,84 @@ yycompile0(VALUE arg)
{
int n;
NODE *tree;
- struct parser_params *parser = (struct parser_params *)arg;
+ struct parser_params *p = (struct parser_params *)arg;
VALUE cov = Qfalse;
- if (!compile_for_eval && rb_safe_level() == 0) {
- ruby_debug_lines = debug_lines(ruby_sourcefile_string);
- if (ruby_debug_lines && ruby_sourceline > 0) {
- VALUE str = STR_NEW0();
- n = ruby_sourceline;
+ if (!compile_for_eval && !NIL_P(p->ruby_sourcefile_string)) {
+ p->debug_lines = debug_lines(p->ruby_sourcefile_string);
+ if (p->debug_lines && p->ruby_sourceline > 0) {
+ VALUE str = rb_default_rs;
+ n = p->ruby_sourceline;
do {
- rb_ary_push(ruby_debug_lines, str);
+ rb_ary_push(p->debug_lines, str);
} while (--n);
}
- if (!e_option_supplied(parser)) {
- ruby_coverage = coverage(ruby_sourcefile_string, ruby_sourceline);
+ if (!e_option_supplied(p)) {
cov = Qtrue;
}
}
- parser_prepare(parser);
-#ifndef RIPPER
+ parser_prepare(p);
#define RUBY_DTRACE_PARSE_HOOK(name) \
if (RUBY_DTRACE_PARSE_##name##_ENABLED()) { \
- RUBY_DTRACE_PARSE_##name(ruby_sourcefile, ruby_sourceline); \
+ RUBY_DTRACE_PARSE_##name(p->ruby_sourcefile, p->ruby_sourceline); \
}
RUBY_DTRACE_PARSE_HOOK(BEGIN);
-#endif
- n = yyparse((void*)parser);
-#ifndef RIPPER
+ n = yyparse(p);
RUBY_DTRACE_PARSE_HOOK(END);
-#endif
- ruby_debug_lines = 0;
- ruby_coverage = 0;
-
- lex_strterm = 0;
- lex_p = lex_pbeg = lex_pend = 0;
- lex_lastline = lex_nextline = 0;
- if (parser->error_p) {
- VALUE mesg = parser->error_buffer;
+ p->debug_lines = 0;
+
+ p->lex.strterm = 0;
+ p->lex.pcur = p->lex.pbeg = p->lex.pend = 0;
+ p->lex.prevline = p->lex.lastline = p->lex.nextline = 0;
+ if (n || p->error_p) {
+ VALUE mesg = p->error_buffer;
if (!mesg) {
mesg = rb_class_new_instance(0, 0, rb_eSyntaxError);
}
rb_set_errinfo(mesg);
- return 0;
+ return FALSE;
}
- tree = ruby_eval_tree;
+ tree = p->eval_tree;
if (!tree) {
- tree = NEW_NIL();
+ tree = NEW_NIL(&NULL_LOC);
}
else {
- VALUE opt = parser->compile_option;
+ VALUE opt = p->compile_option;
+ NODE *prelude;
+ NODE *body = parser_append_options(p, tree->nd_body);
if (!opt) opt = rb_obj_hide(rb_ident_hash_new());
rb_hash_aset(opt, rb_sym_intern_ascii_cstr("coverage_enabled"), cov);
- tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body, opt);
+ prelude = block_append(p, p->eval_tree_begin, body);
+ tree->nd_body = prelude;
+ RB_OBJ_WRITE(p->ast, &p->ast->body.compile_option, opt);
}
- return (VALUE)tree;
+ p->ast->body.root = tree;
+ p->ast->body.line_count = p->line_count;
+ return TRUE;
}
-static NODE*
-yycompile(struct parser_params *parser, VALUE fname, int line)
+static rb_ast_t *
+yycompile(VALUE vparser, struct parser_params *p, VALUE fname, int line)
{
- ruby_sourcefile_string = rb_str_new_frozen(fname);
- ruby_sourcefile = RSTRING_PTR(fname);
- ruby_sourceline = line - 1;
- return (NODE *)rb_suppress_tracing(yycompile0, (VALUE)parser);
+ rb_ast_t *ast;
+ if (NIL_P(fname)) {
+ p->ruby_sourcefile_string = Qnil;
+ p->ruby_sourcefile = "(none)";
+ }
+ else {
+ p->ruby_sourcefile_string = rb_fstring(fname);
+ p->ruby_sourcefile = StringValueCStr(fname);
+ }
+ p->ruby_sourceline = line - 1;
+
+ p->ast = ast = rb_ast_new();
+ rb_suppress_tracing(yycompile0, (VALUE)p);
+ p->ast = 0;
+ RB_GC_GUARD(vparser); /* prohibit tail call optimization */
+
+ return ast;
}
#endif /* !RIPPER */
@@ -5330,7 +6272,7 @@ must_be_ascii_compatible(VALUE s)
}
static VALUE
-lex_get_str(struct parser_params *parser, VALUE s)
+lex_get_str(struct parser_params *p, VALUE s)
{
char *beg, *end, *start;
long len;
@@ -5338,127 +6280,105 @@ lex_get_str(struct parser_params *parser, VALUE s)
beg = RSTRING_PTR(s);
len = RSTRING_LEN(s);
start = beg;
- if (lex_gets_ptr) {
- if (len == lex_gets_ptr) return Qnil;
- beg += lex_gets_ptr;
- len -= lex_gets_ptr;
+ if (p->lex.gets_.ptr) {
+ if (len == p->lex.gets_.ptr) return Qnil;
+ beg += p->lex.gets_.ptr;
+ len -= p->lex.gets_.ptr;
}
end = memchr(beg, '\n', len);
if (end) len = ++end - beg;
- lex_gets_ptr += len;
+ p->lex.gets_.ptr += len;
return rb_str_subseq(s, beg - start, len);
}
static VALUE
-lex_getline(struct parser_params *parser)
+lex_getline(struct parser_params *p)
{
- VALUE line = (*lex_gets)(parser, lex_input);
+ VALUE line = (*p->lex.gets)(p, p->lex.input);
if (NIL_P(line)) return line;
must_be_ascii_compatible(line);
#ifndef RIPPER
- if (ruby_debug_lines) {
- rb_enc_associate(line, current_enc);
- rb_ary_push(ruby_debug_lines, line);
- }
- if (ruby_coverage) {
- rb_ary_push(ruby_coverage, Qnil);
+ if (p->debug_lines) {
+ rb_enc_associate(line, p->enc);
+ rb_ary_push(p->debug_lines, line);
}
#endif
+ p->line_count++;
return line;
}
static const rb_data_type_t parser_data_type;
#ifndef RIPPER
-static NODE*
+static rb_ast_t*
parser_compile_string(VALUE vparser, VALUE fname, VALUE s, int line)
{
- struct parser_params *parser;
- NODE *node;
+ struct parser_params *p;
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
- lex_gets = lex_get_str;
- lex_gets_ptr = 0;
- lex_input = rb_str_new_frozen(s);
- lex_pbeg = lex_p = lex_pend = 0;
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- node = yycompile(parser, fname, line);
- RB_GC_GUARD(vparser); /* prohibit tail call optimization */
+ p->lex.gets = lex_get_str;
+ p->lex.gets_.ptr = 0;
+ p->lex.input = rb_str_new_frozen(s);
+ p->lex.pbeg = p->lex.pcur = p->lex.pend = 0;
- return node;
+ return yycompile(vparser, p, fname, line);
}
-NODE*
-rb_compile_string(const char *f, VALUE s, int line)
-{
- must_be_ascii_compatible(s);
- return parser_compile_string(rb_parser_new(), rb_filesystem_str_new_cstr(f), s, line);
-}
-
-NODE*
+rb_ast_t*
rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
{
return rb_parser_compile_string_path(vparser, rb_filesystem_str_new_cstr(f), s, line);
}
-NODE*
+rb_ast_t*
rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
{
must_be_ascii_compatible(s);
return parser_compile_string(vparser, f, s, line);
}
-NODE*
-rb_compile_cstr(const char *f, const char *s, int len, int line)
-{
- VALUE str = rb_str_new(s, len);
- return parser_compile_string(rb_parser_new(), rb_filesystem_str_new_cstr(f), str, line);
-}
-
-NODE*
-rb_parser_compile_cstr(VALUE vparser, const char *f, const char *s, int len, int line)
-{
- VALUE str = rb_str_new(s, len);
- return parser_compile_string(vparser, rb_filesystem_str_new_cstr(f), str, line);
-}
-
VALUE rb_io_gets_internal(VALUE io);
static VALUE
-lex_io_gets(struct parser_params *parser, VALUE io)
+lex_io_gets(struct parser_params *p, VALUE io)
{
return rb_io_gets_internal(io);
}
-NODE*
-rb_compile_file(const char *f, VALUE file, int start)
+rb_ast_t*
+rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
{
- VALUE vparser = rb_parser_new();
+ struct parser_params *p;
+
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+
+ p->lex.gets = lex_io_gets;
+ p->lex.input = file;
+ p->lex.pbeg = p->lex.pcur = p->lex.pend = 0;
- return rb_parser_compile_file(vparser, f, file, start);
+ return yycompile(vparser, p, fname, start);
}
-NODE*
-rb_parser_compile_file(VALUE vparser, const char *f, VALUE file, int start)
+static VALUE
+lex_generic_gets(struct parser_params *p, VALUE input)
{
- return rb_parser_compile_file_path(vparser, rb_filesystem_str_new_cstr(f), file, start);
+ return (*p->lex.gets_.call)(input, p->line_count);
}
-NODE*
-rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
+rb_ast_t*
+rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start)
{
- struct parser_params *parser;
- NODE *node;
+ struct parser_params *p;
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
- lex_gets = lex_io_gets;
- lex_input = file;
- lex_pbeg = lex_p = lex_pend = 0;
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- node = yycompile(parser, fname, start);
- RB_GC_GUARD(vparser); /* prohibit tail call optimization */
+ p->lex.gets = lex_generic_gets;
+ p->lex.gets_.call = lex_gets;
+ p->lex.input = input;
+ p->lex.pbeg = p->lex.pcur = p->lex.pend = 0;
- return node;
+ return yycompile(vparser, p, fname, start);
}
#endif /* !RIPPER */
@@ -5469,6 +6389,7 @@ rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
#define STR_FUNC_SYMBOL 0x10
#define STR_FUNC_INDENT 0x20
#define STR_FUNC_LABEL 0x40
+#define STR_FUNC_LIST 0x4000
#define STR_FUNC_TERM 0x8000
enum string_type {
@@ -5477,18 +6398,18 @@ enum string_type {
str_dquote = (STR_FUNC_EXPAND),
str_xquote = (STR_FUNC_EXPAND),
str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
- str_sword = (STR_FUNC_QWORDS),
- str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
+ str_sword = (STR_FUNC_QWORDS|STR_FUNC_LIST),
+ str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND|STR_FUNC_LIST),
str_ssym = (STR_FUNC_SYMBOL),
str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
};
static VALUE
-parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
+parser_str_new(const char *ptr, long len, rb_encoding *enc, int func, rb_encoding *enc0)
{
VALUE str;
- str = rb_enc_str_new(p, n, enc);
+ str = rb_enc_str_new(ptr, len, enc);
if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
if (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
}
@@ -5500,264 +6421,327 @@ parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *e
return str;
}
-#define lex_goto_eol(parser) ((parser)->lex.pcur = (parser)->lex.pend)
-#define lex_eol_p() (lex_p >= lex_pend)
-#define peek(c) peek_n((c), 0)
-#define peek_n(c,n) (lex_p+(n) < lex_pend && (c) == (unsigned char)lex_p[n])
-#define peekc() peekc_n(0)
-#define peekc_n(n) (lex_p+(n) < lex_pend ? (unsigned char)lex_p[n] : -1)
+#define lex_goto_eol(p) ((p)->lex.pcur = (p)->lex.pend)
+#define lex_eol_p(p) ((p)->lex.pcur >= (p)->lex.pend)
+#define lex_eol_n_p(p,n) ((p)->lex.pcur+(n) >= (p)->lex.pend)
+#define peek(p,c) peek_n(p, (c), 0)
+#define peek_n(p,c,n) (!lex_eol_n_p(p, n) && (c) == (unsigned char)(p)->lex.pcur[n])
+#define peekc(p) peekc_n(p, 0)
+#define peekc_n(p,n) (lex_eol_n_p(p, n) ? -1 : (unsigned char)(p)->lex.pcur[n])
+
+#ifdef RIPPER
+static void
+add_delayed_token(struct parser_params *p, const char *tok, const char *end)
+{
+ if (tok < end) {
+ if (!has_delayed_token(p)) {
+ p->delayed.token = rb_str_buf_new(end - tok);
+ rb_enc_associate(p->delayed.token, p->enc);
+ p->delayed.line = p->ruby_sourceline;
+ p->delayed.col = rb_long2int(tok - p->lex.pbeg);
+ }
+ rb_str_buf_cat(p->delayed.token, tok, end - tok);
+ p->lex.ptok = end;
+ }
+}
+#else
+#define add_delayed_token(p, tok, end) ((void)(tok), (void)(end))
+#endif
static int
-parser_nextline(struct parser_params *parser)
+nextline(struct parser_params *p)
{
- VALUE v = lex_nextline;
- lex_nextline = 0;
+ VALUE v = p->lex.nextline;
+ p->lex.nextline = 0;
if (!v) {
- if (parser->eofp)
+ if (p->eofp)
return -1;
- if (!lex_input || NIL_P(v = lex_getline(parser))) {
- parser->eofp = 1;
- lex_goto_eol(parser);
+ if (p->lex.pend > p->lex.pbeg && *(p->lex.pend-1) != '\n') {
+ goto end_of_input;
+ }
+
+ if (!p->lex.input || NIL_P(v = lex_getline(p))) {
+ end_of_input:
+ p->eofp = 1;
+ lex_goto_eol(p);
return -1;
}
- parser->cr_seen = FALSE;
+ p->cr_seen = FALSE;
}
-#ifdef RIPPER
- if (parser->tokp < lex_pend) {
- if (!has_delayed_token()) {
- parser->delayed = rb_str_buf_new(1024);
- rb_enc_associate(parser->delayed, current_enc);
- rb_str_buf_cat(parser->delayed,
- parser->tokp, lex_pend - parser->tokp);
- parser->delayed_line = ruby_sourceline;
- parser->delayed_col = (int)(parser->tokp - lex_pbeg);
- }
- else {
- rb_str_buf_cat(parser->delayed,
- parser->tokp, lex_pend - parser->tokp);
- }
+ else if (NIL_P(v)) {
+ /* after here-document without terminator */
+ goto end_of_input;
}
-#endif
- if (heredoc_end > 0) {
- ruby_sourceline = heredoc_end;
- heredoc_end = 0;
- }
- ruby_sourceline++;
- parser->line_count++;
- lex_pbeg = lex_p = RSTRING_PTR(v);
- lex_pend = lex_p + RSTRING_LEN(v);
- token_flush(parser);
- lex_lastline = v;
+ add_delayed_token(p, p->lex.ptok, p->lex.pend);
+ if (p->heredoc_end > 0) {
+ p->ruby_sourceline = p->heredoc_end;
+ p->heredoc_end = 0;
+ }
+ p->ruby_sourceline++;
+ p->lex.pbeg = p->lex.pcur = RSTRING_PTR(v);
+ p->lex.pend = p->lex.pcur + RSTRING_LEN(v);
+ token_flush(p);
+ p->lex.prevline = p->lex.lastline;
+ p->lex.lastline = v;
return 0;
}
static int
-parser_cr(struct parser_params *parser, int c)
+parser_cr(struct parser_params *p, int c)
{
- if (peek('\n')) {
- lex_p++;
+ if (peek(p, '\n')) {
+ p->lex.pcur++;
c = '\n';
}
- else if (!parser->cr_seen) {
- parser->cr_seen = TRUE;
- /* carried over with lex_nextline for nextc() */
- rb_warn0("encountered \\r in middle of line, treated as a mere space");
- }
return c;
}
static inline int
-parser_nextc(struct parser_params *parser)
+nextc(struct parser_params *p)
{
int c;
- if (UNLIKELY(lex_p == lex_pend)) {
- if (parser_nextline(parser)) return -1;
+ if (UNLIKELY((p->lex.pcur == p->lex.pend) || p->eofp || RTEST(p->lex.nextline))) {
+ if (nextline(p)) return -1;
}
- c = (unsigned char)*lex_p++;
+ c = (unsigned char)*p->lex.pcur++;
if (UNLIKELY(c == '\r')) {
- c = parser_cr(parser, c);
+ c = parser_cr(p, c);
}
return c;
}
static void
-parser_pushback(struct parser_params *parser, int c)
+pushback(struct parser_params *p, int c)
{
if (c == -1) return;
- lex_p--;
- if (lex_p > lex_pbeg && lex_p[0] == '\n' && lex_p[-1] == '\r') {
- lex_p--;
+ p->lex.pcur--;
+ if (p->lex.pcur > p->lex.pbeg && p->lex.pcur[0] == '\n' && p->lex.pcur[-1] == '\r') {
+ p->lex.pcur--;
}
}
-#define was_bol() (lex_p == lex_pbeg + 1)
+#define was_bol(p) ((p)->lex.pcur == (p)->lex.pbeg + 1)
+
+#define tokfix(p) ((p)->tokenbuf[(p)->tokidx]='\0')
+#define tok(p) (p)->tokenbuf
+#define toklen(p) (p)->tokidx
-#define tokfix() (tokenbuf[tokidx]='\0')
-#define tok() tokenbuf
-#define toklen() tokidx
-#define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
+static int
+looking_at_eol_p(struct parser_params *p)
+{
+ const char *ptr = p->lex.pcur;
+ while (ptr < p->lex.pend) {
+ int c = (unsigned char)*ptr++;
+ int eol = (c == '\n' || c == '#');
+ if (eol || !ISSPACE(c)) {
+ return eol;
+ }
+ }
+ return TRUE;
+}
static char*
-parser_newtok(struct parser_params *parser)
+newtok(struct parser_params *p)
{
- tokidx = 0;
- tokline = ruby_sourceline;
- if (!tokenbuf) {
- toksiz = 60;
- tokenbuf = ALLOC_N(char, 60);
+ p->tokidx = 0;
+ p->tokline = p->ruby_sourceline;
+ if (!p->tokenbuf) {
+ p->toksiz = 60;
+ p->tokenbuf = ALLOC_N(char, 60);
}
- if (toksiz > 4096) {
- toksiz = 60;
- REALLOC_N(tokenbuf, char, 60);
+ if (p->toksiz > 4096) {
+ p->toksiz = 60;
+ REALLOC_N(p->tokenbuf, char, 60);
}
- return tokenbuf;
+ return p->tokenbuf;
}
static char *
-parser_tokspace(struct parser_params *parser, int n)
+tokspace(struct parser_params *p, int n)
{
- tokidx += n;
+ p->tokidx += n;
- if (tokidx >= toksiz) {
- do {toksiz *= 2;} while (toksiz < tokidx);
- REALLOC_N(tokenbuf, char, toksiz);
+ if (p->tokidx >= p->toksiz) {
+ do {p->toksiz *= 2;} while (p->toksiz < p->tokidx);
+ REALLOC_N(p->tokenbuf, char, p->toksiz);
}
- return &tokenbuf[tokidx-n];
+ return &p->tokenbuf[p->tokidx-n];
}
static void
-parser_tokadd(struct parser_params *parser, int c)
+tokadd(struct parser_params *p, int c)
{
- tokenbuf[tokidx++] = (char)c;
- if (tokidx >= toksiz) {
- toksiz *= 2;
- REALLOC_N(tokenbuf, char, toksiz);
+ p->tokenbuf[p->tokidx++] = (char)c;
+ if (p->tokidx >= p->toksiz) {
+ p->toksiz *= 2;
+ REALLOC_N(p->tokenbuf, char, p->toksiz);
}
}
static int
-parser_tok_hex(struct parser_params *parser, size_t *numlen)
+tok_hex(struct parser_params *p, size_t *numlen)
{
int c;
- c = scan_hex(lex_p, 2, numlen);
+ c = scan_hex(p->lex.pcur, 2, numlen);
if (!*numlen) {
- parser->tokp = lex_p;
- yyerror("invalid hex escape");
+ yyerror0("invalid hex escape");
+ token_flush(p);
return 0;
}
- lex_p += *numlen;
+ p->lex.pcur += *numlen;
return c;
}
-#define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
+#define tokcopy(p, n) memcpy(tokspace(p, n), (p)->lex.pcur - (n), (n))
+
+static int
+escaped_control_code(int c)
+{
+ int c2 = 0;
+ 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;
+ }
+ return c2;
+}
+
+#define WARN_SPACE_CHAR(c, prefix) \
+ rb_warn1("invalid character syntax; use "prefix"\\%c", WARN_I(c2))
static int
-parser_tokadd_codepoint(struct parser_params *parser, rb_encoding **encp,
- int regexp_literal, int wide)
+tokadd_codepoint(struct parser_params *p, rb_encoding **encp,
+ int regexp_literal, int wide)
{
size_t numlen;
- int codepoint = scan_hex(lex_p, wide ? lex_pend - lex_p : 4, &numlen);
- literal_flush(lex_p);
- lex_p += numlen;
+ int codepoint = scan_hex(p->lex.pcur, wide ? p->lex.pend - p->lex.pcur : 4, &numlen);
+ literal_flush(p, p->lex.pcur);
+ p->lex.pcur += numlen;
if (wide ? (numlen == 0 || numlen > 6) : (numlen < 4)) {
- yyerror("invalid Unicode escape");
+ yyerror0("invalid Unicode escape");
return wide && numlen > 0;
}
if (codepoint > 0x10ffff) {
- yyerror("invalid Unicode codepoint (too large)");
+ yyerror0("invalid Unicode codepoint (too large)");
return wide;
}
if ((codepoint & 0xfffff800) == 0xd800) {
- yyerror("invalid Unicode codepoint");
+ yyerror0("invalid Unicode codepoint");
return wide;
}
if (regexp_literal) {
- tokcopy((int)numlen);
+ tokcopy(p, (int)numlen);
}
else if (codepoint >= 0x80) {
rb_encoding *utf8 = rb_utf8_encoding();
if (*encp && utf8 != *encp) {
- static const char mixed_utf8[] = "UTF-8 mixed within %s source";
- size_t len = sizeof(mixed_utf8) - 2 + strlen(rb_enc_name(*encp));
- char *mesg = alloca(len);
- snprintf(mesg, len, mixed_utf8, rb_enc_name(*encp));
- yyerror(mesg);
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ compile_error(p, "UTF-8 mixed within %s source", rb_enc_name(*encp));
+ parser_show_error_line(p, &loc);
return wide;
}
*encp = utf8;
- tokaddmbc(codepoint, *encp);
+ tokaddmbc(p, codepoint, *encp);
}
else {
- tokadd(codepoint);
+ tokadd(p, codepoint);
}
return TRUE;
}
/* return value is for ?\u3042 */
-static int
-parser_tokadd_utf8(struct parser_params *parser, rb_encoding **encp,
- int string_literal, int symbol_literal, int regexp_literal)
+static void
+tokadd_utf8(struct parser_params *p, rb_encoding **encp,
+ int term, int symbol_literal, int regexp_literal)
{
/*
- * If string_literal is true, then we allow multiple codepoints
- * in \u{}, and add the codepoints to the current token.
- * Otherwise we're parsing a character literal and return a single
- * codepoint without adding it
+ * If `term` is not -1, then we allow multiple codepoints in \u{}
+ * upto `term` byte, otherwise we're parsing a character literal.
+ * And then add the codepoints to the current token.
*/
+ static const char multiple_codepoints[] = "Multiple codepoints at single character literal";
const int open_brace = '{', close_brace = '}';
- if (regexp_literal) { tokadd('\\'); tokadd('u'); }
-
- if (peek(open_brace)) { /* handle \u{...} form */
- int c, last = nextc();
- if (lex_p >= lex_pend) goto unterminated;
- while (ISSPACE(c = *lex_p) && ++lex_p < lex_pend);
- do {
- if (regexp_literal) tokadd(last);
- if (!parser_tokadd_codepoint(parser, encp, regexp_literal, TRUE)) {
+ if (regexp_literal) { tokadd(p, '\\'); tokadd(p, 'u'); }
+
+ if (peek(p, open_brace)) { /* handle \u{...} form */
+ const char *second = NULL;
+ int c, last = nextc(p);
+ if (p->lex.pcur >= p->lex.pend) goto unterminated;
+ while (ISSPACE(c = *p->lex.pcur) && ++p->lex.pcur < p->lex.pend);
+ while (c != close_brace) {
+ if (c == term) goto unterminated;
+ if (second == multiple_codepoints)
+ second = p->lex.pcur;
+ if (regexp_literal) tokadd(p, last);
+ if (!tokadd_codepoint(p, encp, regexp_literal, TRUE)) {
break;
}
- while (ISSPACE(c = *lex_p)) {
- if (++lex_p >= lex_pend) goto unterminated;
+ while (ISSPACE(c = *p->lex.pcur)) {
+ if (++p->lex.pcur >= p->lex.pend) goto unterminated;
last = c;
}
- } while (c != close_brace);
+ if (term == -1 && !second)
+ second = multiple_codepoints;
+ }
if (c != close_brace) {
unterminated:
- literal_flush(lex_p);
- yyerror("unterminated Unicode escape");
- return 0;
+ token_flush(p);
+ yyerror0("unterminated Unicode escape");
+ return;
+ }
+ if (second && second != multiple_codepoints) {
+ const char *pcur = p->lex.pcur;
+ p->lex.pcur = second;
+ dispatch_scan_event(p, tSTRING_CONTENT);
+ token_flush(p);
+ p->lex.pcur = pcur;
+ yyerror0(multiple_codepoints);
+ token_flush(p);
}
- if (regexp_literal) tokadd(close_brace);
- nextc();
+ if (regexp_literal) tokadd(p, close_brace);
+ nextc(p);
}
else { /* handle \uxxxx form */
- if (!parser_tokadd_codepoint(parser, encp, regexp_literal, FALSE)) {
- return 0;
+ if (!tokadd_codepoint(p, encp, regexp_literal, FALSE)) {
+ token_flush(p);
+ return;
}
}
-
- return TRUE;
}
#define ESCAPE_CONTROL 1
#define ESCAPE_META 2
static int
-parser_read_escape(struct parser_params *parser, int flags,
- rb_encoding **encp)
+read_escape(struct parser_params *p, int flags, rb_encoding **encp)
{
int c;
size_t numlen;
- switch (c = nextc()) {
+ switch (c = nextc(p)) {
case '\\': /* Backslash */
return c;
@@ -5784,13 +6768,13 @@ parser_read_escape(struct parser_params *parser, int flags,
case '0': case '1': case '2': case '3': /* octal constant */
case '4': case '5': case '6': case '7':
- pushback(c);
- c = scan_oct(lex_p, 3, &numlen);
- lex_p += numlen;
+ pushback(p, c);
+ c = scan_oct(p->lex.pcur, 3, &numlen);
+ p->lex.pcur += numlen;
return c;
case 'x': /* hex constant */
- c = tok_hex(&numlen);
+ c = tok_hex(p, &numlen);
if (numlen == 0) return 0;
return c;
@@ -5802,37 +6786,77 @@ parser_read_escape(struct parser_params *parser, int flags,
case 'M':
if (flags & ESCAPE_META) goto eof;
- if ((c = nextc()) != '-') {
+ if ((c = nextc(p)) != '-') {
goto eof;
}
- if ((c = nextc()) == '\\') {
- if (peek('u')) goto eof;
- return read_escape(flags|ESCAPE_META, encp) | 0x80;
+ if ((c = nextc(p)) == '\\') {
+ switch (peekc(p)) {
+ case 'u': case 'U':
+ nextc(p);
+ goto eof;
+ }
+ return read_escape(p, flags|ESCAPE_META, encp) | 0x80;
}
else if (c == -1 || !ISASCII(c)) goto eof;
else {
+ int c2 = escaped_control_code(c);
+ if (c2) {
+ if (ISCNTRL(c) || !(flags & ESCAPE_CONTROL)) {
+ WARN_SPACE_CHAR(c2, "\\M-");
+ }
+ else {
+ WARN_SPACE_CHAR(c2, "\\C-\\M-");
+ }
+ }
+ else if (ISCNTRL(c)) goto eof;
return ((c & 0xff) | 0x80);
}
case 'C':
- if ((c = nextc()) != '-') {
+ if ((c = nextc(p)) != '-') {
goto eof;
}
case 'c':
if (flags & ESCAPE_CONTROL) goto eof;
- if ((c = nextc())== '\\') {
- if (peek('u')) goto eof;
- c = read_escape(flags|ESCAPE_CONTROL, encp);
+ if ((c = nextc(p))== '\\') {
+ switch (peekc(p)) {
+ case 'u': case 'U':
+ nextc(p);
+ goto eof;
+ }
+ c = read_escape(p, flags|ESCAPE_CONTROL, encp);
}
else if (c == '?')
return 0177;
else if (c == -1 || !ISASCII(c)) goto eof;
+ else {
+ int c2 = escaped_control_code(c);
+ if (c2) {
+ if (ISCNTRL(c)) {
+ if (flags & ESCAPE_META) {
+ WARN_SPACE_CHAR(c2, "\\M-");
+ }
+ else {
+ WARN_SPACE_CHAR(c2, "");
+ }
+ }
+ else {
+ if (flags & ESCAPE_META) {
+ WARN_SPACE_CHAR(c2, "\\M-\\C-");
+ }
+ else {
+ WARN_SPACE_CHAR(c2, "\\C-");
+ }
+ }
+ }
+ else if (ISCNTRL(c)) goto eof;
+ }
return c & 0x9f;
eof:
case -1:
- yyerror("Invalid escape character syntax");
- pushback(c);
+ yyerror0("Invalid escape character syntax");
+ token_flush(p);
return '\0';
default:
@@ -5841,95 +6865,96 @@ parser_read_escape(struct parser_params *parser, int flags,
}
static void
-parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
+tokaddmbc(struct parser_params *p, int c, rb_encoding *enc)
{
int len = rb_enc_codelen(c, enc);
- rb_enc_mbcput(c, tokspace(len), enc);
+ rb_enc_mbcput(c, tokspace(p, len), enc);
}
static int
-parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
+tokadd_escape(struct parser_params *p, rb_encoding **encp)
{
int c;
int flags = 0;
size_t numlen;
first:
- switch (c = nextc()) {
+ switch (c = nextc(p)) {
case '\n':
return 0; /* just ignore */
case '0': case '1': case '2': case '3': /* octal constant */
case '4': case '5': case '6': case '7':
{
- ruby_scan_oct(--lex_p, 3, &numlen);
+ ruby_scan_oct(--p->lex.pcur, 3, &numlen);
if (numlen == 0) goto eof;
- lex_p += numlen;
- tokcopy((int)numlen + 1);
+ p->lex.pcur += numlen;
+ tokcopy(p, (int)numlen + 1);
}
return 0;
case 'x': /* hex constant */
{
- tok_hex(&numlen);
+ tok_hex(p, &numlen);
if (numlen == 0) return -1;
- tokcopy((int)numlen + 2);
+ tokcopy(p, (int)numlen + 2);
}
return 0;
case 'M':
if (flags & ESCAPE_META) goto eof;
- if ((c = nextc()) != '-') {
- pushback(c);
+ if ((c = nextc(p)) != '-') {
+ pushback(p, c);
goto eof;
}
- tokcopy(3);
+ tokcopy(p, 3);
flags |= ESCAPE_META;
goto escaped;
case 'C':
if (flags & ESCAPE_CONTROL) goto eof;
- if ((c = nextc()) != '-') {
- pushback(c);
+ if ((c = nextc(p)) != '-') {
+ pushback(p, c);
goto eof;
}
- tokcopy(3);
+ tokcopy(p, 3);
goto escaped;
case 'c':
if (flags & ESCAPE_CONTROL) goto eof;
- tokcopy(2);
+ tokcopy(p, 2);
flags |= ESCAPE_CONTROL;
escaped:
- if ((c = nextc()) == '\\') {
+ if ((c = nextc(p)) == '\\') {
goto first;
}
else if (c == -1) goto eof;
- tokadd(c);
+ tokadd(p, c);
return 0;
eof:
case -1:
- yyerror("Invalid escape character syntax");
+ yyerror0("Invalid escape character syntax");
+ token_flush(p);
return -1;
default:
- tokadd('\\');
- tokadd(c);
+ tokadd(p, '\\');
+ tokadd(p, c);
}
return 0;
}
static int
-parser_regx_options(struct parser_params *parser)
+regx_options(struct parser_params *p)
{
int kcode = 0;
int kopt = 0;
int options = 0;
int c, opt, kc;
- newtok();
- while (c = nextc(), ISALPHA(c)) {
+ newtok(p);
+ while (c = nextc(p), ISALPHA(c)) {
if (c == 'o') {
options |= RE_OPTION_ONCE;
}
@@ -5943,39 +6968,32 @@ parser_regx_options(struct parser_params *parser)
}
}
else {
- tokadd(c);
+ tokadd(p, c);
}
}
options |= kopt;
- pushback(c);
- if (toklen()) {
- tokfix();
- compile_error(PARSER_ARG "unknown regexp option%s - %s",
- toklen() > 1 ? "s" : "", tok());
+ pushback(p, c);
+ if (toklen(p)) {
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ tokfix(p);
+ compile_error(p, "unknown regexp option%s - %*s",
+ toklen(p) > 1 ? "s" : "", toklen(p), tok(p));
+ parser_show_error_line(p, &loc);
}
return options | RE_OPTION_ENCODING(kcode);
}
-static void
-dispose_string(VALUE str)
-{
- rb_str_free(str);
- rb_gc_force_recycle(str);
-}
-
static int
-parser_tokadd_mbchar(struct parser_params *parser, int c)
+tokadd_mbchar(struct parser_params *p, int c)
{
- int len = parser_precise_mbclen(parser, lex_p-1);
+ int len = parser_precise_mbclen(p, p->lex.pcur-1);
if (len < 0) return -1;
- tokadd(c);
- lex_p += --len;
- if (len > 0) tokcopy(len);
+ tokadd(p, c);
+ p->lex.pcur += --len;
+ if (len > 0) tokcopy(p, len);
return c;
}
-#define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
-
static inline int
simple_re_meta(int c)
{
@@ -5990,61 +7008,65 @@ simple_re_meta(int c)
}
static int
-parser_update_heredoc_indent(struct parser_params *parser, int c)
+parser_update_heredoc_indent(struct parser_params *p, int c)
{
- if (heredoc_line_indent == -1) {
- if (c == '\n') heredoc_line_indent = 0;
+ if (p->heredoc_line_indent == -1) {
+ if (c == '\n') p->heredoc_line_indent = 0;
}
else {
if (c == ' ') {
- heredoc_line_indent++;
+ p->heredoc_line_indent++;
return TRUE;
}
else if (c == '\t') {
- int w = (heredoc_line_indent / TAB_WIDTH) + 1;
- heredoc_line_indent = w * TAB_WIDTH;
+ int w = (p->heredoc_line_indent / TAB_WIDTH) + 1;
+ p->heredoc_line_indent = w * TAB_WIDTH;
return TRUE;
}
else if (c != '\n') {
- if (heredoc_indent > heredoc_line_indent) {
- heredoc_indent = heredoc_line_indent;
+ if (p->heredoc_indent > p->heredoc_line_indent) {
+ p->heredoc_indent = p->heredoc_line_indent;
}
- heredoc_line_indent = -1;
+ p->heredoc_line_indent = -1;
}
}
return FALSE;
}
+static void
+parser_mixed_error(struct parser_params *p, rb_encoding *enc1, rb_encoding *enc2)
+{
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ const char *n1 = rb_enc_name(enc1), *n2 = rb_enc_name(enc2);
+ compile_error(p, "%s mixed within %s source", n1, n2);
+ parser_show_error_line(p, &loc);
+}
+
+static void
+parser_mixed_escape(struct parser_params *p, const char *beg, rb_encoding *enc1, rb_encoding *enc2)
+{
+ const char *pos = p->lex.pcur;
+ p->lex.pcur = beg;
+ parser_mixed_error(p, enc1, enc2);
+ p->lex.pcur = pos;
+}
+
static int
-parser_tokadd_string(struct parser_params *parser,
- int func, int term, int paren, long *nest,
- rb_encoding **encp)
+tokadd_string(struct parser_params *p,
+ int func, int term, int paren, long *nest,
+ rb_encoding **encp, rb_encoding **enc)
{
int c;
- rb_encoding *enc = 0;
- char *errbuf = 0;
- static const char mixed_msg[] = "%s mixed within %s source";
-
-#define mixed_error(enc1, enc2) if (!errbuf) { \
- size_t len = sizeof(mixed_msg) - 4; \
- len += strlen(rb_enc_name(enc1)); \
- len += strlen(rb_enc_name(enc2)); \
- errbuf = ALLOCA_N(char, len); \
- snprintf(errbuf, len, mixed_msg, \
- rb_enc_name(enc1), \
- rb_enc_name(enc2)); \
- yyerror(errbuf); \
- }
-#define mixed_escape(beg, enc1, enc2) do { \
- const char *pos = lex_p; \
- lex_p = (beg); \
- mixed_error((enc1), (enc2)); \
- lex_p = pos; \
- } while (0)
-
- while ((c = nextc()) != -1) {
- if (heredoc_indent > 0) {
- parser_update_heredoc_indent(parser, c);
+ bool erred = false;
+
+#define mixed_error(enc1, enc2) \
+ (void)(erred || (parser_mixed_error(p, enc1, enc2), erred = true))
+#define mixed_escape(beg, enc1, enc2) \
+ (void)(erred || (parser_mixed_escape(p, beg, enc1, enc2), erred = true))
+
+ while ((c = nextc(p)) != -1) {
+ if (p->heredoc_indent > 0) {
+ parser_update_heredoc_indent(p, c);
}
if (paren && c == paren) {
@@ -6052,137 +7074,148 @@ parser_tokadd_string(struct parser_params *parser,
}
else if (c == term) {
if (!nest || !*nest) {
- pushback(c);
+ pushback(p, c);
break;
}
--*nest;
}
- else if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {
- int c2 = *lex_p;
+ else if ((func & STR_FUNC_EXPAND) && c == '#' && p->lex.pcur < p->lex.pend) {
+ int c2 = *p->lex.pcur;
if (c2 == '$' || c2 == '@' || c2 == '{') {
- pushback(c);
+ pushback(p, c);
break;
}
}
else if (c == '\\') {
- literal_flush(lex_p - 1);
- c = nextc();
+ literal_flush(p, p->lex.pcur - 1);
+ c = nextc(p);
switch (c) {
case '\n':
if (func & STR_FUNC_QWORDS) break;
- if (func & STR_FUNC_EXPAND) continue;
- tokadd('\\');
+ if (func & STR_FUNC_EXPAND) {
+ if (!(func & STR_FUNC_INDENT) || (p->heredoc_indent < 0))
+ continue;
+ if (c == term) {
+ c = '\\';
+ goto terminate;
+ }
+ }
+ tokadd(p, '\\');
break;
case '\\':
- if (func & STR_FUNC_ESCAPE) tokadd(c);
+ if (func & STR_FUNC_ESCAPE) tokadd(p, c);
break;
case 'u':
if ((func & STR_FUNC_EXPAND) == 0) {
- tokadd('\\');
+ tokadd(p, '\\');
break;
}
- if (!parser_tokadd_utf8(parser, &enc, term,
- func & STR_FUNC_SYMBOL,
- func & STR_FUNC_REGEXP)) {
- return -1;
- }
+ tokadd_utf8(p, enc, term,
+ func & STR_FUNC_SYMBOL,
+ func & STR_FUNC_REGEXP);
continue;
default:
if (c == -1) return -1;
if (!ISASCII(c)) {
- if ((func & STR_FUNC_EXPAND) == 0) tokadd('\\');
+ if ((func & STR_FUNC_EXPAND) == 0) tokadd(p, '\\');
goto non_ascii;
}
if (func & STR_FUNC_REGEXP) {
if (c == term && !simple_re_meta(c)) {
- tokadd(c);
+ tokadd(p, c);
continue;
}
- pushback(c);
- if ((c = tokadd_escape(&enc)) < 0)
+ pushback(p, c);
+ if ((c = tokadd_escape(p, enc)) < 0)
return -1;
- if (enc && enc != *encp) {
- mixed_escape(parser->tokp+2, enc, *encp);
+ if (*enc && *enc != *encp) {
+ mixed_escape(p->lex.ptok+2, *enc, *encp);
}
continue;
}
else if (func & STR_FUNC_EXPAND) {
- pushback(c);
- if (func & STR_FUNC_ESCAPE) tokadd('\\');
- c = read_escape(0, &enc);
+ pushback(p, c);
+ if (func & STR_FUNC_ESCAPE) tokadd(p, '\\');
+ c = read_escape(p, 0, enc);
}
else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
/* ignore backslashed spaces in %w */
}
else if (c != term && !(paren && c == paren)) {
- tokadd('\\');
- pushback(c);
+ tokadd(p, '\\');
+ pushback(p, c);
continue;
}
}
}
- else if (!parser_isascii()) {
+ else if (!parser_isascii(p)) {
non_ascii:
- if (!enc) {
- enc = *encp;
+ if (!*enc) {
+ *enc = *encp;
}
- else if (enc != *encp) {
- mixed_error(enc, *encp);
+ else if (*enc != *encp) {
+ mixed_error(*enc, *encp);
continue;
}
- if (tokadd_mbchar(c) == -1) return -1;
+ if (tokadd_mbchar(p, c) == -1) return -1;
continue;
}
else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
- pushback(c);
+ pushback(p, c);
break;
}
if (c & 0x80) {
- if (!enc) {
- enc = *encp;
+ if (!*enc) {
+ *enc = *encp;
}
- else if (enc != *encp) {
- mixed_error(enc, *encp);
+ else if (*enc != *encp) {
+ mixed_error(*enc, *encp);
continue;
}
}
- tokadd(c);
+ tokadd(p, c);
}
- if (enc) *encp = enc;
+ terminate:
+ if (*enc) *encp = *enc;
return c;
}
+static inline rb_strterm_t *
+new_strterm(VALUE v1, VALUE v2, VALUE v3, VALUE v0)
+{
+ return (rb_strterm_t*)rb_imemo_new(imemo_parser_strterm, v1, v2, v3, v0);
+}
+
+/* imemo_parser_strterm for literal */
#define NEW_STRTERM(func, term, paren) \
- rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
+ new_strterm((VALUE)(func), (VALUE)(paren), (VALUE)(term), 0)
#ifdef RIPPER
static void
-token_flush_string_content(struct parser_params *parser, rb_encoding *enc)
+flush_string_content(struct parser_params *p, rb_encoding *enc)
{
VALUE content = yylval.val;
if (!ripper_is_node_yylval(content))
- content = ripper_new_yylval(0, 0, content);
- if (has_delayed_token()) {
- ptrdiff_t len = lex_p - parser->tokp;
+ content = ripper_new_yylval(p, 0, 0, content);
+ if (has_delayed_token(p)) {
+ ptrdiff_t len = p->lex.pcur - p->lex.ptok;
if (len > 0) {
- rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
+ rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
}
- dispatch_delayed_token(tSTRING_CONTENT);
- parser->tokp = lex_p;
+ dispatch_delayed_token(p, tSTRING_CONTENT);
+ p->lex.ptok = p->lex.pcur;
RNODE(content)->nd_rval = yylval.val;
}
- dispatch_scan_event(tSTRING_CONTENT);
+ dispatch_scan_event(p, tSTRING_CONTENT);
if (yylval.val != content)
RNODE(content)->nd_rval = yylval.val;
yylval.val = content;
}
-
-#define flush_string_content(enc) token_flush_string_content(parser, (enc))
#else
-#define flush_string_content(enc) ((void)(enc))
+#define flush_string_content(p, enc) ((void)(enc))
#endif
RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
@@ -6207,32 +7240,32 @@ const unsigned int ruby_global_name_punct_bits[] = {
#endif
static enum yytokentype
-parser_peek_variable_name(struct parser_params *parser)
+parser_peek_variable_name(struct parser_params *p)
{
int c;
- const char *p = lex_p;
+ const char *ptr = p->lex.pcur;
- if (p + 1 >= lex_pend) return 0;
- c = *p++;
+ if (ptr + 1 >= p->lex.pend) return 0;
+ c = *ptr++;
switch (c) {
case '$':
- if ((c = *p) == '-') {
- if (++p >= lex_pend) return 0;
- c = *p;
+ if ((c = *ptr) == '-') {
+ if (++ptr >= p->lex.pend) return 0;
+ c = *ptr;
}
else if (is_global_name_punct(c) || ISDIGIT(c)) {
return tSTRING_DVAR;
}
break;
case '@':
- if ((c = *p) == '@') {
- if (++p >= lex_pend) return 0;
- c = *p;
+ if ((c = *ptr) == '@') {
+ if (++ptr >= p->lex.pend) return 0;
+ c = *ptr;
}
break;
case '{':
- lex_p = p;
- command_start = TRUE;
+ p->lex.pcur = ptr;
+ p->command_start = TRUE;
return tSTRING_DBEG;
default:
return 0;
@@ -6249,109 +7282,130 @@ parser_peek_variable_name(struct parser_params *parser)
#define IS_LABEL_POSSIBLE() (\
(IS_lex_state(EXPR_LABEL|EXPR_ENDFN) && !cmd_state) || \
IS_ARG())
-#define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
+#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
#define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
static inline enum yytokentype
-parser_string_term(struct parser_params *parser, int func)
+parser_string_term(struct parser_params *p, int func)
{
- rb_gc_force_recycle((VALUE)lex_strterm);
- lex_strterm = 0;
+ p->lex.strterm = 0;
if (func & STR_FUNC_REGEXP) {
- set_yylval_num(regx_options());
- dispatch_scan_event(tREGEXP_END);
- SET_LEX_STATE(EXPR_END|EXPR_ENDARG);
+ set_yylval_num(regx_options(p));
+ dispatch_scan_event(p, tREGEXP_END);
+ SET_LEX_STATE(EXPR_END);
return tREGEXP_END;
}
if ((func & STR_FUNC_LABEL) && IS_LABEL_SUFFIX(0)) {
- nextc();
+ nextc(p);
SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
return tLABEL_END;
}
- SET_LEX_STATE(EXPR_END|EXPR_ENDARG);
+ SET_LEX_STATE(EXPR_END);
return tSTRING_END;
}
static enum yytokentype
-parser_parse_string(struct parser_params *parser, NODE *quote)
+parse_string(struct parser_params *p, rb_strterm_literal_t *quote)
{
- int func = (int)quote->nd_func;
- int term = nd_term(quote);
- int paren = nd_paren(quote);
+ int func = (int)quote->u1.func;
+ int term = (int)quote->u3.term;
+ int paren = (int)quote->u2.paren;
int c, space = 0;
- rb_encoding *enc = current_enc;
+ rb_encoding *enc = p->enc;
+ rb_encoding *base_enc = 0;
+ VALUE lit;
if (func & STR_FUNC_TERM) {
- SET_LEX_STATE(EXPR_END|EXPR_ENDARG);
- lex_strterm = 0;
+ if (func & STR_FUNC_QWORDS) nextc(p); /* delayed term */
+ SET_LEX_STATE(EXPR_END);
+ p->lex.strterm = 0;
return func & STR_FUNC_REGEXP ? tREGEXP_END : tSTRING_END;
}
- c = nextc();
+ c = nextc(p);
if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
- do {c = nextc();} while (ISSPACE(c));
+ do {c = nextc(p);} while (ISSPACE(c));
space = 1;
}
- if (c == term && !quote->nd_nest) {
+ if (func & STR_FUNC_LIST) {
+ quote->u1.func &= ~STR_FUNC_LIST;
+ space = 1;
+ }
+ if (c == term && !quote->u0.nest) {
if (func & STR_FUNC_QWORDS) {
- quote->nd_func |= STR_FUNC_TERM;
+ quote->u1.func |= STR_FUNC_TERM;
+ pushback(p, c); /* dispatch the term at tSTRING_END */
+ add_delayed_token(p, p->lex.ptok, p->lex.pcur);
return ' ';
}
- return parser_string_term(parser, func);
+ return parser_string_term(p, func);
}
if (space) {
- pushback(c);
+ pushback(p, c);
+ add_delayed_token(p, p->lex.ptok, p->lex.pcur);
return ' ';
}
- newtok();
+ newtok(p);
if ((func & STR_FUNC_EXPAND) && c == '#') {
- int t = parser_peek_variable_name(parser);
+ int t = parser_peek_variable_name(p);
if (t) return t;
- tokadd('#');
- c = nextc();
+ tokadd(p, '#');
+ c = nextc(p);
}
- pushback(c);
- if (tokadd_string(func, term, paren, &quote->nd_nest,
- &enc) == -1) {
- if (parser->eofp) {
+ pushback(p, c);
+ if (tokadd_string(p, func, term, paren, &quote->u0.nest,
+ &enc, &base_enc) == -1) {
+ if (p->eofp) {
#ifndef RIPPER
-# define unterminated_literal(mesg) yyerror(mesg)
+# define unterminated_literal(mesg) yyerror0(mesg)
#else
-# define unterminated_literal(mesg) compile_error(PARSER_ARG mesg)
+# define unterminated_literal(mesg) compile_error(p, mesg)
#endif
- literal_flush(lex_p);
+ literal_flush(p, p->lex.pcur);
+ if (func & STR_FUNC_QWORDS) {
+ /* no content to add, bailing out here */
+ unterminated_literal("unterminated list meets end of file");
+ p->lex.strterm = 0;
+ return tSTRING_END;
+ }
if (func & STR_FUNC_REGEXP) {
unterminated_literal("unterminated regexp meets end of file");
}
else {
unterminated_literal("unterminated string meets end of file");
}
- quote->nd_func |= STR_FUNC_TERM;
+ quote->u1.func |= STR_FUNC_TERM;
}
}
- tokfix();
- set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
- flush_string_content(enc);
+ tokfix(p);
+ lit = STR_NEW3(tok(p), toklen(p), enc, func);
+ set_yylval_str(lit);
+ flush_string_content(p, enc);
return tSTRING_CONTENT;
}
static enum yytokentype
-parser_heredoc_identifier(struct parser_params *parser)
+heredoc_identifier(struct parser_params *p)
{
- int c = nextc(), term, func = 0;
+ /*
+ * term_len is length of `<<"END"` except `END`,
+ * in this case term_len is 4 (<, <, " and ").
+ */
+ long len, offset = p->lex.pcur - p->lex.pbeg;
+ int c = nextc(p), term, func = 0, quote = 0;
enum yytokentype token = tSTRING_BEG;
- long len;
- int newline = 0;
int indent = 0;
if (c == '-') {
- c = nextc();
+ c = nextc(p);
func = STR_FUNC_INDENT;
+ offset++;
}
else if (c == '~') {
- c = nextc();
+ c = nextc(p);
func = STR_FUNC_INDENT;
+ offset++;
indent = INT_MAX;
}
switch (c) {
@@ -6364,77 +7418,73 @@ parser_heredoc_identifier(struct parser_params *parser)
func |= str_xquote; goto quoted;
quoted:
- newtok();
- tokadd(func);
+ quote++;
+ offset++;
term = c;
- while ((c = nextc()) != -1 && c != term) {
- if (tokadd_mbchar(c) == -1) return 0;
- if (!newline && c == '\n') newline = 1;
- else if (newline) newline = 2;
- }
- if (c == -1) {
- compile_error(PARSER_ARG "unterminated here document identifier");
- return 0;
- }
- switch (newline) {
- case 1:
- rb_warn0("here document identifier ends with a newline");
- if (--tokidx > 0 && tokenbuf[tokidx] == '\r') --tokidx;
- break;
- case 2:
- compile_error(PARSER_ARG "here document identifier across newlines, never match");
- return -1;
+ len = 0;
+ while ((c = nextc(p)) != term) {
+ if (c == -1 || c == '\r' || c == '\n') {
+ yyerror(NULL, p, "unterminated here document identifier");
+ return -1;
+ }
}
break;
default:
- if (!parser_is_identchar()) {
- pushback(c);
+ if (!parser_is_identchar(p)) {
+ pushback(p, c);
if (func & STR_FUNC_INDENT) {
- pushback(indent > 0 ? '~' : '-');
+ pushback(p, indent > 0 ? '~' : '-');
}
return 0;
}
- newtok();
- tokadd(func |= str_dquote);
+ func |= str_dquote;
do {
- if (tokadd_mbchar(c) == -1) return 0;
- } while ((c = nextc()) != -1 && parser_is_identchar());
- pushback(c);
+ int n = parser_precise_mbclen(p, p->lex.pcur-1);
+ if (n < 0) return 0;
+ p->lex.pcur += --n;
+ } while ((c = nextc(p)) != -1 && parser_is_identchar(p));
+ pushback(p, c);
break;
}
- tokfix();
- dispatch_scan_event(tHEREDOC_BEG);
- len = lex_p - lex_pbeg;
- lex_goto_eol(parser);
- lex_strterm = rb_node_newnode(NODE_HEREDOC,
- STR_NEW(tok(), toklen()), /* nd_lit */
- len, /* nd_nth */
- lex_lastline); /* nd_orig */
- parser_set_line(lex_strterm, ruby_sourceline);
- token_flush(parser);
- heredoc_indent = indent;
- heredoc_line_indent = 0;
+ len = p->lex.pcur - (p->lex.pbeg + offset) - quote;
+ if ((unsigned long)len >= HERETERM_LENGTH_MAX)
+ yyerror(NULL, p, "too long here document identifier");
+ dispatch_scan_event(p, tHEREDOC_BEG);
+ lex_goto_eol(p);
+
+ p->lex.strterm = new_strterm(0, 0, 0, p->lex.lastline);
+ p->lex.strterm->flags |= STRTERM_HEREDOC;
+ rb_strterm_heredoc_t *here = &p->lex.strterm->u.heredoc;
+ here->offset = offset;
+ here->sourceline = p->ruby_sourceline;
+ here->length = (int)len;
+ here->quote = quote;
+ here->func = func;
+
+ token_flush(p);
+ p->heredoc_indent = indent;
+ p->heredoc_line_indent = 0;
return token;
}
static void
-parser_heredoc_restore(struct parser_params *parser, NODE *here)
+heredoc_restore(struct parser_params *p, rb_strterm_heredoc_t *here)
{
VALUE line;
- lex_strterm = 0;
- line = here->nd_orig;
- lex_lastline = line;
- lex_pbeg = RSTRING_PTR(line);
- lex_pend = lex_pbeg + RSTRING_LEN(line);
- lex_p = lex_pbeg + here->nd_nth;
- heredoc_end = ruby_sourceline;
- ruby_sourceline = nd_line(here);
- dispose_string(here->nd_lit);
- rb_gc_force_recycle((VALUE)here);
- token_flush(parser);
+ p->lex.strterm = 0;
+ line = here->lastline;
+ p->lex.lastline = line;
+ p->lex.pbeg = RSTRING_PTR(line);
+ p->lex.pend = p->lex.pbeg + RSTRING_LEN(line);
+ p->lex.pcur = p->lex.pbeg + here->offset + here->length + here->quote;
+ p->lex.ptok = p->lex.pbeg + here->offset - here->quote;
+ p->heredoc_end = p->ruby_sourceline;
+ p->ruby_sourceline = (int)here->sourceline;
+ if (p->eofp) p->lex.nextline = Qnil;
+ p->eofp = 0;
}
static int
@@ -6470,30 +7520,50 @@ dedent_string(VALUE string, int width)
#ifndef RIPPER
static NODE *
-parser_heredoc_dedent(struct parser_params *parser, NODE *root)
+heredoc_dedent(struct parser_params *p, NODE *root)
{
- NODE *node, *str_node;
- int bol = TRUE;
- int indent = heredoc_indent;
+ NODE *node, *str_node, *prev_node;
+ int indent = p->heredoc_indent;
+ VALUE prev_lit = 0;
if (indent <= 0) return root;
- heredoc_indent = 0;
+ p->heredoc_indent = 0;
if (!root) return root;
- node = str_node = root;
- if (nd_type(root) == NODE_ARRAY) str_node = root->nd_head;
+ prev_node = node = str_node = root;
+ if (nd_type(root) == NODE_LIST) str_node = root->nd_head;
while (str_node) {
VALUE lit = str_node->nd_lit;
- if (bol) dedent_string(lit, indent);
- bol = TRUE;
+ if (str_node->flags & NODE_FL_NEWLINE) {
+ dedent_string(lit, indent);
+ }
+ if (!prev_lit) {
+ prev_lit = lit;
+ }
+ else if (!literal_concat0(p, prev_lit, lit)) {
+ return 0;
+ }
+ else {
+ NODE *end = node->nd_end;
+ node = prev_node->nd_next = node->nd_next;
+ if (!node) {
+ if (nd_type(prev_node) == NODE_DSTR)
+ nd_set_type(prev_node, NODE_STR);
+ break;
+ }
+ node->nd_end = end;
+ goto next_str;
+ }
str_node = 0;
- while ((node = node->nd_next) != 0 && nd_type(node) == NODE_ARRAY) {
+ while ((node = (prev_node = node)->nd_next) != 0) {
+ next_str:
+ if (nd_type(node) != NODE_LIST) break;
if ((str_node = node->nd_head) != 0) {
enum node_type type = nd_type(str_node);
if (type == NODE_STR || type == NODE_DSTR) break;
- bol = FALSE;
+ prev_lit = 0;
str_node = 0;
}
}
@@ -6502,16 +7572,25 @@ parser_heredoc_dedent(struct parser_params *parser, NODE *root)
}
#else /* RIPPER */
static VALUE
-parser_heredoc_dedent(struct parser_params *parser, VALUE array)
+heredoc_dedent(struct parser_params *p, VALUE array)
{
- int indent = heredoc_indent;
+ int indent = p->heredoc_indent;
if (indent <= 0) return array;
- heredoc_indent = 0;
+ p->heredoc_indent = 0;
dispatch2(heredoc_dedent, array, INT2NUM(indent));
return array;
}
+/*
+ * call-seq:
+ * Ripper.dedent_string(input, width) -> Integer
+ *
+ * USE OF RIPPER LIBRARY ONLY.
+ *
+ * Strips up to +width+ leading whitespaces from +input+,
+ * and returns the stripped column width.
+ */
static VALUE
parser_dedent_string(VALUE self, VALUE input, VALUE width)
{
@@ -6525,22 +7604,34 @@ parser_dedent_string(VALUE self, VALUE input, VALUE width)
#endif
static int
-parser_whole_match_p(struct parser_params *parser,
- const char *eos, long len, int indent)
+whole_match_p(struct parser_params *p, const char *eos, long len, int indent)
{
- const char *p = lex_pbeg;
+ const char *ptr = p->lex.pbeg;
long n;
if (indent) {
- while (*p && ISSPACE(*p)) p++;
+ while (*ptr && ISSPACE(*ptr)) ptr++;
}
- n = lex_pend - (p + len);
+ n = p->lex.pend - (ptr + len);
if (n < 0) return FALSE;
- if (n > 0 && p[len] != '\n') {
- if (p[len] != '\r') return FALSE;
- if (n <= 1 || p[len+1] != '\n') return FALSE;
+ if (n > 0 && ptr[len] != '\n') {
+ if (ptr[len] != '\r') return FALSE;
+ if (n <= 1 || ptr[len+1] != '\n') return FALSE;
}
- return strncmp(eos, p, len) == 0;
+ return strncmp(eos, ptr, len) == 0;
+}
+
+static int
+word_match_p(struct parser_params *p, const char *word, long len)
+{
+ if (strncmp(p->lex.pcur, word, len)) return 0;
+ if (p->lex.pcur + len == p->lex.pend) return 1;
+ int c = (unsigned char)p->lex.pcur[len];
+ if (ISSPACE(c)) return 1;
+ switch (c) {
+ case '\0': case '\004': case '\032': return 1;
+ }
+ return 0;
}
#define NUM_SUFFIX_R (1<<0)
@@ -6548,12 +7639,12 @@ parser_whole_match_p(struct parser_params *parser,
#define NUM_SUFFIX_ALL 3
static int
-parser_number_literal_suffix(struct parser_params *parser, int mask)
+number_literal_suffix(struct parser_params *p, int mask)
{
int c, result = 0;
- const char *lastp = lex_p;
+ const char *lastp = p->lex.pcur;
- while ((c = nextc()) != -1) {
+ while ((c = nextc(p)) != -1) {
if ((mask & NUM_SUFFIX_I) && c == 'i') {
result |= (mask & NUM_SUFFIX_I);
mask &= ~NUM_SUFFIX_I;
@@ -6567,259 +7658,286 @@ parser_number_literal_suffix(struct parser_params *parser, int mask)
continue;
}
if (!ISASCII(c) || ISALPHA(c) || c == '_') {
- lex_p = lastp;
- literal_flush(lex_p);
+ p->lex.pcur = lastp;
+ literal_flush(p, p->lex.pcur);
return 0;
}
- pushback(c);
- if (c == '.') {
- c = peekc_n(1);
- if (ISDIGIT(c)) {
- yyerror("unexpected fraction part after numeric literal");
- lex_p += 2;
- while (parser_is_identchar()) nextc();
- }
- }
+ pushback(p, c);
break;
}
return result;
}
static enum yytokentype
-parser_set_number_literal(struct parser_params *parser, VALUE v,
- enum yytokentype type, int suffix)
+set_number_literal(struct parser_params *p, VALUE v,
+ enum yytokentype type, int suffix)
{
if (suffix & NUM_SUFFIX_I) {
v = rb_complex_raw(INT2FIX(0), v);
type = tIMAGINARY;
}
set_yylval_literal(v);
- SET_LEX_STATE(EXPR_END|EXPR_ENDARG);
+ SET_LEX_STATE(EXPR_END);
return type;
}
-static int
-parser_set_integer_literal(struct parser_params *parser, VALUE v, int suffix)
+static enum yytokentype
+set_integer_literal(struct parser_params *p, VALUE v, int suffix)
{
enum yytokentype type = tINTEGER;
if (suffix & NUM_SUFFIX_R) {
v = rb_rational_raw1(v);
type = tRATIONAL;
}
- return set_number_literal(v, type, suffix);
+ return set_number_literal(p, v, type, suffix);
}
#ifdef RIPPER
static void
-ripper_dispatch_heredoc_end(struct parser_params *parser)
+dispatch_heredoc_end(struct parser_params *p)
{
VALUE str;
- if (has_delayed_token())
- dispatch_delayed_token(tSTRING_CONTENT);
- str = STR_NEW(parser->tokp, lex_pend - parser->tokp);
- ripper_dispatch1(parser, ripper_token2eventid(tHEREDOC_END), str);
- lex_goto_eol(parser);
- token_flush(parser);
+ if (has_delayed_token(p))
+ dispatch_delayed_token(p, tSTRING_CONTENT);
+ str = STR_NEW(p->lex.ptok, p->lex.pend - p->lex.ptok);
+ ripper_dispatch1(p, ripper_token2eventid(tHEREDOC_END), str);
+ lex_goto_eol(p);
+ token_flush(p);
}
-#define dispatch_heredoc_end() ripper_dispatch_heredoc_end(parser)
#else
-#define dispatch_heredoc_end() ((void)0)
+#define dispatch_heredoc_end(p) ((void)0)
#endif
static enum yytokentype
-parser_here_document(struct parser_params *parser, NODE *here)
+here_document(struct parser_params *p, rb_strterm_heredoc_t *here)
{
int c, func, indent = 0;
- const char *eos, *p, *pend;
+ const char *eos, *ptr, *ptr_end;
long len;
VALUE str = 0;
- rb_encoding *enc = current_enc;
+ rb_encoding *enc = p->enc;
+ rb_encoding *base_enc = 0;
+ int bol;
- eos = RSTRING_PTR(here->nd_lit);
- len = RSTRING_LEN(here->nd_lit) - 1;
- indent = (func = *eos++) & STR_FUNC_INDENT;
+ eos = RSTRING_PTR(here->lastline) + here->offset;
+ len = here->length;
+ indent = (func = here->func) & STR_FUNC_INDENT;
- if ((c = nextc()) == -1) {
+ if ((c = nextc(p)) == -1) {
error:
- compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
#ifdef RIPPER
- if (!has_delayed_token()) {
- dispatch_scan_event(tSTRING_CONTENT);
+ if (!has_delayed_token(p)) {
+ dispatch_scan_event(p, tSTRING_CONTENT);
}
else {
- if (str) {
- rb_str_append(parser->delayed, str);
- }
- else if ((len = lex_p - parser->tokp) > 0) {
+ if ((len = p->lex.pcur - p->lex.ptok) > 0) {
if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
int cr = ENC_CODERANGE_UNKNOWN;
- rb_str_coderange_scan_restartable(parser->tokp, lex_p, enc, &cr);
+ rb_str_coderange_scan_restartable(p->lex.ptok, p->lex.pcur, enc, &cr);
if (cr != ENC_CODERANGE_7BIT &&
- current_enc == rb_usascii_encoding() &&
+ p->enc == rb_usascii_encoding() &&
enc != rb_utf8_encoding()) {
enc = rb_ascii8bit_encoding();
}
}
- rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
+ rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
}
- dispatch_delayed_token(tSTRING_CONTENT);
+ dispatch_delayed_token(p, tSTRING_CONTENT);
}
- lex_goto_eol(parser);
+ lex_goto_eol(p);
#endif
- restore:
- heredoc_restore(lex_strterm);
- lex_strterm = 0;
- return 0;
+ heredoc_restore(p, &p->lex.strterm->u.heredoc);
+ compile_error(p, "can't find string \"%.*s\" anywhere before EOF",
+ (int)len, eos);
+ token_flush(p);
+ p->lex.strterm = 0;
+ SET_LEX_STATE(EXPR_END);
+ return tSTRING_END;
+ }
+ bol = was_bol(p);
+ if (!bol) {
+ /* not beginning of line, cannot be the terminator */
+ }
+ else if (p->heredoc_line_indent == -1) {
+ /* `heredoc_line_indent == -1` means
+ * - "after an interpolation in the same line", or
+ * - "in a continuing line"
+ */
+ p->heredoc_line_indent = 0;
}
- if (was_bol() && whole_match_p(eos, len, indent)) {
- dispatch_heredoc_end();
- heredoc_restore(lex_strterm);
- lex_strterm = 0;
+ else if (whole_match_p(p, eos, len, indent)) {
+ dispatch_heredoc_end(p);
+ restore:
+ heredoc_restore(p, &p->lex.strterm->u.heredoc);
+ token_flush(p);
+ p->lex.strterm = 0;
SET_LEX_STATE(EXPR_END);
return tSTRING_END;
}
if (!(func & STR_FUNC_EXPAND)) {
do {
- p = RSTRING_PTR(lex_lastline);
- pend = lex_pend;
- if (pend > p) {
- switch (pend[-1]) {
+ ptr = RSTRING_PTR(p->lex.lastline);
+ ptr_end = p->lex.pend;
+ if (ptr_end > ptr) {
+ switch (ptr_end[-1]) {
case '\n':
- if (--pend == p || pend[-1] != '\r') {
- pend++;
+ if (--ptr_end == ptr || ptr_end[-1] != '\r') {
+ ptr_end++;
break;
}
case '\r':
- --pend;
+ --ptr_end;
}
}
- if (heredoc_indent > 0) {
+ if (p->heredoc_indent > 0) {
long i = 0;
- while (p + i < pend && parser_update_heredoc_indent(parser, p[i]))
+ while (ptr + i < ptr_end && parser_update_heredoc_indent(p, ptr[i]))
i++;
- heredoc_line_indent = 0;
+ p->heredoc_line_indent = 0;
}
if (str)
- rb_str_cat(str, p, pend - p);
+ rb_str_cat(str, ptr, ptr_end - ptr);
else
- str = STR_NEW(p, pend - p);
- if (pend < lex_pend) rb_str_cat(str, "\n", 1);
- lex_goto_eol(parser);
- if (heredoc_indent > 0) {
- set_yylval_str(str);
- flush_string_content(enc);
- return tSTRING_CONTENT;
+ str = STR_NEW(ptr, ptr_end - ptr);
+ if (ptr_end < p->lex.pend) rb_str_cat(str, "\n", 1);
+ lex_goto_eol(p);
+ if (p->heredoc_indent > 0) {
+ goto flush_str;
}
- if (nextc() == -1) {
+ if (nextc(p) == -1) {
if (str) {
- dispose_string(str);
str = 0;
}
goto error;
}
- } while (!whole_match_p(eos, len, indent));
+ } while (!whole_match_p(p, eos, len, indent));
}
else {
/* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
- newtok();
+ newtok(p);
if (c == '#') {
- int t = parser_peek_variable_name(parser);
+ int t = parser_peek_variable_name(p);
+ if (p->heredoc_line_indent != -1) {
+ if (p->heredoc_indent > p->heredoc_line_indent) {
+ p->heredoc_indent = p->heredoc_line_indent;
+ }
+ p->heredoc_line_indent = -1;
+ }
if (t) return t;
- tokadd('#');
- c = nextc();
+ tokadd(p, '#');
+ c = nextc(p);
}
do {
- pushback(c);
- if ((c = tokadd_string(func, '\n', 0, NULL, &enc)) == -1) {
- if (parser->eofp) goto error;
+ pushback(p, c);
+ enc = p->enc;
+ if ((c = tokadd_string(p, func, '\n', 0, NULL, &enc, &base_enc)) == -1) {
+ if (p->eofp) goto error;
goto restore;
}
if (c != '\n') {
+ if (c == '\\') p->heredoc_line_indent = -1;
flush:
- set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
- flush_string_content(enc);
+ str = STR_NEW3(tok(p), toklen(p), enc, func);
+ flush_str:
+ set_yylval_str(str);
+#ifndef RIPPER
+ if (bol) yylval.node->flags |= NODE_FL_NEWLINE;
+#endif
+ flush_string_content(p, enc);
return tSTRING_CONTENT;
}
- tokadd(nextc());
- if (heredoc_indent > 0) {
- lex_goto_eol(parser);
+ tokadd(p, nextc(p));
+ if (p->heredoc_indent > 0) {
+ lex_goto_eol(p);
goto flush;
}
/* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
- if ((c = nextc()) == -1) goto error;
- } while (!whole_match_p(eos, len, indent));
- str = STR_NEW3(tok(), toklen(), enc, func);
+ if ((c = nextc(p)) == -1) goto error;
+ } while (!whole_match_p(p, eos, len, indent));
+ str = STR_NEW3(tok(p), toklen(p), enc, func);
}
- dispatch_heredoc_end();
+ dispatch_heredoc_end(p);
#ifdef RIPPER
- str = ripper_new_yylval(ripper_token2eventid(tSTRING_CONTENT),
+ str = ripper_new_yylval(p, ripper_token2eventid(tSTRING_CONTENT),
yylval.val, str);
#endif
- heredoc_restore(lex_strterm);
- lex_strterm = NEW_STRTERM(func | STR_FUNC_TERM, 0, 0);
+ heredoc_restore(p, &p->lex.strterm->u.heredoc);
+ token_flush(p);
+ p->lex.strterm = NEW_STRTERM(func | STR_FUNC_TERM, 0, 0);
set_yylval_str(str);
+#ifndef RIPPER
+ if (bol) yylval.node->flags |= NODE_FL_NEWLINE;
+#endif
return tSTRING_CONTENT;
}
#include "lex.c"
-static void
-arg_ambiguous_gen(struct parser_params *parser, char c)
+static int
+arg_ambiguous(struct parser_params *p, char c)
{
#ifndef RIPPER
- rb_warning1("ambiguous first argument; put parentheses or a space even after `%c' operator", WARN_I(c));
+ if (c == '/') {
+ rb_warning1("ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after `%c' operator", WARN_I(c));
+ }
+ else {
+ rb_warning1("ambiguous first argument; put parentheses or a space even after `%c' operator", WARN_I(c));
+ }
#else
dispatch1(arg_ambiguous, rb_usascii_str_new(&c, 1));
#endif
+ return TRUE;
}
-#define arg_ambiguous(c) (arg_ambiguous_gen(parser, (c)), 1)
static ID
-formal_argument_gen(struct parser_params *parser, ID lhs)
+#ifndef RIPPER
+formal_argument(struct parser_params *p, ID lhs)
+#else
+formal_argument(struct parser_params *p, VALUE lhs)
+#endif
{
- switch (id_type(lhs)) {
+ switch (id_type(get_id(lhs))) {
case ID_LOCAL:
break;
#ifndef RIPPER
+# define ERR(mesg) yyerror0(mesg)
+#else
+# define ERR(mesg) (dispatch2(param_error, WARN_S(mesg), lhs), ripper_error(p))
+#endif
case ID_CONST:
- yyerror("formal argument cannot be a constant");
+ ERR("formal argument cannot be a constant");
return 0;
case ID_INSTANCE:
- yyerror("formal argument cannot be an instance variable");
+ ERR("formal argument cannot be an instance variable");
return 0;
case ID_GLOBAL:
- yyerror("formal argument cannot be a global variable");
+ ERR("formal argument cannot be a global variable");
return 0;
case ID_CLASS:
- yyerror("formal argument cannot be a class variable");
+ ERR("formal argument cannot be a class variable");
return 0;
default:
- yyerror("formal argument must be local variable");
+ ERR("formal argument must be local variable");
return 0;
-#else
- default:
- lhs = dispatch1(param_error, lhs);
- ripper_error();
- return 0;
-#endif
+#undef ERR
}
- shadowing_lvar(lhs);
+ shadowing_lvar(p, lhs);
return lhs;
}
static int
-lvar_defined_gen(struct parser_params *parser, ID id)
+lvar_defined(struct parser_params *p, ID id)
{
- return (dyna_in_block() && dvar_defined(id)) || local_id(id);
+ return (dyna_in_block(p) && dvar_defined(p, id)) || local_id(p, id);
}
/* emacsen -*- hack */
static long
-parser_encode_length(struct parser_params *parser, const char *name, long len)
+parser_encode_length(struct parser_params *p, const char *name, long len)
{
long nlen;
@@ -6839,7 +7957,7 @@ parser_encode_length(struct parser_params *parser, const char *name, long len)
}
static void
-parser_set_encode(struct parser_params *parser, const char *name)
+parser_set_encode(struct parser_params *p, const char *name)
{
int idx = rb_enc_find_index(name);
rb_encoding *enc;
@@ -6850,7 +7968,7 @@ parser_set_encode(struct parser_params *parser, const char *name)
error:
excargs[0] = rb_eArgError;
excargs[2] = rb_make_backtrace();
- rb_ary_unshift(excargs[2], rb_sprintf("%"PRIsVALUE":%d", ruby_sourcefile_string, ruby_sourceline));
+ rb_ary_unshift(excargs[2], rb_sprintf("%"PRIsVALUE":%d", p->ruby_sourcefile_string, p->ruby_sourceline));
rb_exc_raise(rb_make_exception(3, excargs));
}
enc = rb_enc_from_index(idx);
@@ -6858,10 +7976,10 @@ parser_set_encode(struct parser_params *parser, const char *name)
excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
goto error;
}
- parser->enc = enc;
+ p->enc = enc;
#ifndef RIPPER
- if (ruby_debug_lines) {
- VALUE lines = ruby_debug_lines;
+ if (p->debug_lines) {
+ VALUE lines = p->debug_lines;
long i, n = RARRAY_LEN(lines);
for (i = 0; i < n; ++i) {
rb_enc_associate_index(RARRAY_AREF(lines, i), idx);
@@ -6871,80 +7989,125 @@ parser_set_encode(struct parser_params *parser, const char *name)
}
static int
-comment_at_top(struct parser_params *parser)
+comment_at_top(struct parser_params *p)
{
- const char *p = lex_pbeg, *pend = lex_p - 1;
- if (parser->line_count != (parser->has_shebang ? 2 : 1)) return 0;
- while (p < pend) {
- if (!ISSPACE(*p)) return 0;
- p++;
+ const char *ptr = p->lex.pbeg, *ptr_end = p->lex.pcur - 1;
+ if (p->line_count != (p->has_shebang ? 2 : 1)) return 0;
+ while (ptr < ptr_end) {
+ if (!ISSPACE(*ptr)) return 0;
+ ptr++;
}
return 1;
}
-typedef long (*rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len);
-typedef void (*rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val);
+typedef long (*rb_magic_comment_length_t)(struct parser_params *p, const char *name, long len);
+typedef void (*rb_magic_comment_setter_t)(struct parser_params *p, const char *name, const char *val);
+
+static int parser_invalid_pragma_value(struct parser_params *p, const char *name, const char *val);
static void
-magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
+magic_comment_encoding(struct parser_params *p, const char *name, const char *val)
{
- if (!comment_at_top(parser)) {
+ if (!comment_at_top(p)) {
return;
}
- parser_set_encode(parser, val);
+ parser_set_encode(p, val);
}
static int
-parser_get_bool(struct parser_params *parser, const char *name, const char *val)
+parser_get_bool(struct parser_params *p, const char *name, const char *val)
{
switch (*val) {
case 't': case 'T':
- if (strcasecmp(val, "true") == 0) {
+ if (STRCASECMP(val, "true") == 0) {
return TRUE;
}
break;
case 'f': case 'F':
- if (strcasecmp(val, "false") == 0) {
+ if (STRCASECMP(val, "false") == 0) {
return FALSE;
}
break;
}
- rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
+ return parser_invalid_pragma_value(p, name, val);
+}
+
+static int
+parser_invalid_pragma_value(struct parser_params *p, const char *name, const char *val)
+{
+ rb_warning2("invalid value for %s: %s", WARN_S(name), WARN_S(val));
return -1;
}
static void
-parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
+parser_set_token_info(struct parser_params *p, const char *name, const char *val)
{
- int b = parser_get_bool(parser, name, val);
- if (b >= 0) parser->token_info_enabled = b;
+ int b = parser_get_bool(p, name, val);
+ if (b >= 0) p->token_info_enabled = b;
}
static void
-parser_set_compile_option_flag(struct parser_params *parser, const char *name, const char *val)
+parser_set_compile_option_flag(struct parser_params *p, const char *name, const char *val)
{
int b;
- if (parser->token_seen) {
+ if (p->token_seen) {
rb_warning1("`%s' is ignored after any tokens", WARN_S(name));
return;
}
- b = parser_get_bool(parser, name, val);
+ b = parser_get_bool(p, name, val);
if (b < 0) return;
- if (!parser->compile_option)
- parser->compile_option = rb_obj_hide(rb_ident_hash_new());
- rb_hash_aset(parser->compile_option, ID2SYM(rb_intern(name)),
+ if (!p->compile_option)
+ p->compile_option = rb_obj_hide(rb_ident_hash_new());
+ rb_hash_aset(p->compile_option, ID2SYM(rb_intern(name)),
(b ? Qtrue : Qfalse));
}
+static void
+parser_set_shareable_constant_value(struct parser_params *p, const char *name, const char *val)
+{
+ for (const char *s = p->lex.pbeg, *e = p->lex.pcur; s < e; ++s) {
+ if (*s == ' ' || *s == '\t') continue;
+ if (*s == '#') break;
+ rb_warning1("`%s' is ignored unless in comment-only line", WARN_S(name));
+ return;
+ }
+
+ switch (*val) {
+ case 'n': case 'N':
+ if (STRCASECMP(val, "none") == 0) {
+ p->ctxt.shareable_constant_value = shareable_none;
+ return;
+ }
+ break;
+ case 'l': case 'L':
+ if (STRCASECMP(val, "literal") == 0) {
+ p->ctxt.shareable_constant_value = shareable_literal;
+ return;
+ }
+ break;
+ case 'e': case 'E':
+ if (STRCASECMP(val, "experimental_copy") == 0) {
+ p->ctxt.shareable_constant_value = shareable_copy;
+ return;
+ }
+ if (STRCASECMP(val, "experimental_everything") == 0) {
+ p->ctxt.shareable_constant_value = shareable_everything;
+ return;
+ }
+ break;
+ }
+ parser_invalid_pragma_value(p, name, val);
+}
+
# if WARN_PAST_SCOPE
static void
-parser_set_past_scope(struct parser_params *parser, const char *name, const char *val)
+parser_set_past_scope(struct parser_params *p, const char *name, const char *val)
{
- int b = parser_get_bool(parser, name, val);
- if (b >= 0) parser->past_scope_enabled = b;
+ int b = parser_get_bool(p, name, val);
+ if (b >= 0) p->past_scope_enabled = b;
}
# endif
@@ -6958,6 +8121,7 @@ static const struct magic_comment magic_comments[] = {
{"coding", magic_comment_encoding, parser_encode_length},
{"encoding", magic_comment_encoding, parser_encode_length},
{"frozen_string_literal", parser_set_compile_option_flag},
+ {"shareable_constant_value", parser_set_shareable_constant_value},
{"warn_indent", parser_set_token_info},
# if WARN_PAST_SCOPE
{"warn_past_scope", parser_set_past_scope},
@@ -6998,7 +8162,7 @@ magic_comment_marker(const char *str, long len)
}
static int
-parser_magic_comment(struct parser_params *parser, const char *str, long len)
+parser_magic_comment(struct parser_params *p, const char *str, long len)
{
int indicator = 0;
VALUE name = 0, val = 0;
@@ -7019,7 +8183,7 @@ parser_magic_comment(struct parser_params *parser, const char *str, long len)
/* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
while (len > 0) {
- const struct magic_comment *p = magic_comments;
+ const struct magic_comment *mc = magic_comments;
char *s;
int i;
long n = 0;
@@ -7082,16 +8246,16 @@ parser_magic_comment(struct parser_params *parser, const char *str, long len)
if (s[i] == '-') s[i] = '_';
}
do {
- if (STRNCASECMP(p->name, s, n) == 0 && !p->name[n]) {
+ if (STRNCASECMP(mc->name, s, n) == 0 && !mc->name[n]) {
n = vend - vbeg;
- if (p->length) {
- n = (*p->length)(parser, vbeg, n);
+ if (mc->length) {
+ n = (*mc->length)(p, vbeg, n);
}
str_copy(val, vbeg, n);
- (*p->func)(parser, p->name, RSTRING_PTR(val));
+ (*mc->func)(p, mc->name, RSTRING_PTR(val));
break;
}
- } while (++p < magic_comments + numberof(magic_comments));
+ } while (++mc < magic_comments + numberof(magic_comments));
#ifdef RIPPER
str_copy(val, vbeg, vend - vbeg);
dispatch2(magic_comment, name, val);
@@ -7102,7 +8266,7 @@ parser_magic_comment(struct parser_params *parser, const char *str, long len)
}
static void
-set_file_encoding(struct parser_params *parser, const char *str, const char *send)
+set_file_encoding(struct parser_params *p, const char *str, const char *send)
{
int sep = 0;
const char *beg = str;
@@ -7139,35 +8303,35 @@ set_file_encoding(struct parser_params *parser, const char *str, const char *sen
}
beg = str;
while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
- s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
- parser_set_encode(parser, RSTRING_PTR(s));
+ s = rb_str_new(beg, parser_encode_length(p, beg, str - beg));
+ parser_set_encode(p, RSTRING_PTR(s));
rb_str_resize(s, 0);
}
static void
-parser_prepare(struct parser_params *parser)
+parser_prepare(struct parser_params *p)
{
- int c = nextc();
+ int c = nextc(p);
+ p->token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
switch (c) {
case '#':
- if (peek('!')) parser->has_shebang = 1;
+ if (peek(p, '!')) p->has_shebang = 1;
break;
case 0xef: /* UTF-8 BOM marker */
- if (lex_pend - lex_p >= 2 &&
- (unsigned char)lex_p[0] == 0xbb &&
- (unsigned char)lex_p[1] == 0xbf) {
- parser->enc = rb_utf8_encoding();
- lex_p += 2;
- lex_pbeg = lex_p;
+ if (p->lex.pend - p->lex.pcur >= 2 &&
+ (unsigned char)p->lex.pcur[0] == 0xbb &&
+ (unsigned char)p->lex.pcur[1] == 0xbf) {
+ p->enc = rb_utf8_encoding();
+ p->lex.pcur += 2;
+ p->lex.pbeg = p->lex.pcur;
return;
}
break;
case EOF:
return;
}
- pushback(c);
- parser->enc = rb_enc_get(lex_lastline);
- parser->token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
+ pushback(p, c);
+ p->enc = rb_enc_get(p->lex.lastline);
}
#ifndef RIPPER
@@ -7185,7 +8349,7 @@ parser_prepare(struct parser_params *parser)
(enum yytokentype)(tok))
static VALUE
-parse_rational(struct parser_params *parser, char *str, int len, int seen_point)
+parse_rational(struct parser_params *p, char *str, int len, int seen_point)
{
VALUE v;
char *point = &str[seen_point];
@@ -7195,26 +8359,34 @@ parse_rational(struct parser_params *parser, char *str, int len, int seen_point)
return rb_rational_new(v, rb_int_positive_pow(10, fraclen));
}
-static int
-parse_numeric(struct parser_params *parser, int c)
+static enum yytokentype
+no_digits(struct parser_params *p)
+{
+ yyerror0("numeric literal without digits");
+ if (peek(p, '_')) nextc(p);
+ /* dummy 0, for tUMINUS_NUM at numeric */
+ return set_integer_literal(p, INT2FIX(0), 0);
+}
+
+static enum yytokentype
+parse_numeric(struct parser_params *p, int c)
{
int is_float, seen_point, seen_e, nondigit;
int suffix;
is_float = seen_point = seen_e = nondigit = 0;
SET_LEX_STATE(EXPR_END);
- newtok();
+ newtok(p);
if (c == '-' || c == '+') {
- tokadd(c);
- c = nextc();
+ tokadd(p, c);
+ c = nextc(p);
}
if (c == '0') {
-#define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
- int start = toklen();
- c = nextc();
+ int start = toklen(p);
+ c = nextc(p);
if (c == 'x' || c == 'X') {
/* hexadecimal */
- c = nextc();
+ c = nextc(p);
if (c != -1 && ISXDIGIT(c)) {
do {
if (c == '_') {
@@ -7224,21 +8396,21 @@ parse_numeric(struct parser_params *parser, int c)
}
if (!ISXDIGIT(c)) break;
nondigit = 0;
- tokadd(c);
- } while ((c = nextc()) != -1);
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
}
- pushback(c);
- tokfix();
- if (toklen() == start) {
- no_digits();
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ return no_digits(p);
}
else if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(NUM_SUFFIX_ALL);
- return set_integer_literal(rb_cstr_to_inum(tok(), 16, FALSE), suffix);
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 16, FALSE), suffix);
}
if (c == 'b' || c == 'B') {
/* binary */
- c = nextc();
+ c = nextc(p);
if (c == '0' || c == '1') {
do {
if (c == '_') {
@@ -7248,21 +8420,21 @@ parse_numeric(struct parser_params *parser, int c)
}
if (c != '0' && c != '1') break;
nondigit = 0;
- tokadd(c);
- } while ((c = nextc()) != -1);
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
}
- pushback(c);
- tokfix();
- if (toklen() == start) {
- no_digits();
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ return no_digits(p);
}
else if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(NUM_SUFFIX_ALL);
- return set_integer_literal(rb_cstr_to_inum(tok(), 2, FALSE), suffix);
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 2, FALSE), suffix);
}
if (c == 'd' || c == 'D') {
/* decimal */
- c = nextc();
+ c = nextc(p);
if (c != -1 && ISDIGIT(c)) {
do {
if (c == '_') {
@@ -7272,17 +8444,17 @@ parse_numeric(struct parser_params *parser, int c)
}
if (!ISDIGIT(c)) break;
nondigit = 0;
- tokadd(c);
- } while ((c = nextc()) != -1);
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
}
- pushback(c);
- tokfix();
- if (toklen() == start) {
- no_digits();
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ return no_digits(p);
}
else if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(NUM_SUFFIX_ALL);
- return set_integer_literal(rb_cstr_to_inum(tok(), 10, FALSE), suffix);
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 10, FALSE), suffix);
}
if (c == '_') {
/* 0_0 */
@@ -7290,9 +8462,9 @@ parse_numeric(struct parser_params *parser, int c)
}
if (c == 'o' || c == 'O') {
/* prefixed octal */
- c = nextc();
+ c = nextc(p);
if (c == -1 || c == '_' || !ISDIGIT(c)) {
- no_digits();
+ return no_digits(p);
}
}
if (c >= '0' && c <= '7') {
@@ -7307,31 +8479,31 @@ parse_numeric(struct parser_params *parser, int c)
if (c < '0' || c > '9') break;
if (c > '7') goto invalid_octal;
nondigit = 0;
- tokadd(c);
- } while ((c = nextc()) != -1);
- if (toklen() > start) {
- pushback(c);
- tokfix();
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ if (toklen(p) > start) {
+ pushback(p, c);
+ tokfix(p);
if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(NUM_SUFFIX_ALL);
- return set_integer_literal(rb_cstr_to_inum(tok(), 8, FALSE), suffix);
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 8, FALSE), suffix);
}
if (nondigit) {
- pushback(c);
+ pushback(p, c);
goto trailing_uc;
}
}
if (c > '7' && c <= '9') {
invalid_octal:
- yyerror("Invalid octal digit");
+ yyerror0("Invalid octal digit");
}
else if (c == '.' || c == 'e' || c == 'E') {
- tokadd('0');
+ tokadd(p, '0');
}
else {
- pushback(c);
- suffix = number_literal_suffix(NUM_SUFFIX_ALL);
- return set_integer_literal(INT2FIX(0), suffix);
+ pushback(p, c);
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, INT2FIX(0), suffix);
}
}
@@ -7340,7 +8512,7 @@ parse_numeric(struct parser_params *parser, int c)
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
nondigit = 0;
- tokadd(c);
+ tokadd(p, c);
break;
case '.':
@@ -7349,16 +8521,16 @@ parse_numeric(struct parser_params *parser, int c)
goto decode_num;
}
else {
- int c0 = nextc();
+ int c0 = nextc(p);
if (c0 == -1 || !ISDIGIT(c0)) {
- pushback(c0);
+ pushback(p, c0);
goto decode_num;
}
c = c0;
}
- seen_point = toklen();
- tokadd('.');
- tokadd(c);
+ seen_point = toklen(p);
+ tokadd(p, '.');
+ tokadd(p, c);
is_float++;
nondigit = 0;
break;
@@ -7366,7 +8538,7 @@ parse_numeric(struct parser_params *parser, int c)
case 'e':
case 'E':
if (nondigit) {
- pushback(c);
+ pushback(p, c);
c = nondigit;
goto decode_num;
}
@@ -7374,16 +8546,16 @@ parse_numeric(struct parser_params *parser, int c)
goto decode_num;
}
nondigit = c;
- c = nextc();
+ c = nextc(p);
if (c != '-' && c != '+' && !ISDIGIT(c)) {
- pushback(c);
+ pushback(p, c);
nondigit = 0;
goto decode_num;
}
- tokadd(nondigit);
+ tokadd(p, nondigit);
seen_e++;
is_float++;
- tokadd(c);
+ tokadd(p, c);
nondigit = (c == '-' || c == '+') ? c : 0;
break;
@@ -7395,159 +8567,146 @@ parse_numeric(struct parser_params *parser, int c)
default:
goto decode_num;
}
- c = nextc();
+ c = nextc(p);
}
decode_num:
- pushback(c);
+ pushback(p, c);
if (nondigit) {
- char tmp[30];
trailing_uc:
- literal_flush(lex_p - 1);
- snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
- yyerror(tmp);
+ literal_flush(p, p->lex.pcur - 1);
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ compile_error(p, "trailing `%c' in number", nondigit);
+ parser_show_error_line(p, &loc);
}
- tokfix();
+ tokfix(p);
if (is_float) {
- int type = tFLOAT;
+ enum yytokentype type = tFLOAT;
VALUE v;
- suffix = number_literal_suffix(seen_e ? NUM_SUFFIX_I : NUM_SUFFIX_ALL);
+ suffix = number_literal_suffix(p, seen_e ? NUM_SUFFIX_I : NUM_SUFFIX_ALL);
if (suffix & NUM_SUFFIX_R) {
type = tRATIONAL;
- v = parse_rational(parser, tok(), toklen(), seen_point);
+ v = parse_rational(p, tok(p), toklen(p), seen_point);
}
else {
- double d = strtod(tok(), 0);
+ double d = strtod(tok(p), 0);
if (errno == ERANGE) {
- rb_warning1("Float %s out of range", WARN_S(tok()));
+ rb_warning1("Float %s out of range", WARN_S(tok(p)));
errno = 0;
}
v = DBL2NUM(d);
}
- literal_flush(lex_p);
- return set_number_literal(v, type, suffix);
+ return set_number_literal(p, v, type, suffix);
}
- suffix = number_literal_suffix(NUM_SUFFIX_ALL);
- return set_integer_literal(rb_cstr_to_inum(tok(), 10, FALSE), suffix);
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 10, FALSE), suffix);
}
static enum yytokentype
-parse_qmark(struct parser_params *parser, int space_seen)
+parse_qmark(struct parser_params *p, int space_seen)
{
rb_encoding *enc;
register int c;
+ VALUE lit;
if (IS_END()) {
SET_LEX_STATE(EXPR_VALUE);
return '?';
}
- c = nextc();
+ c = nextc(p);
if (c == -1) {
- compile_error(PARSER_ARG "incomplete character syntax");
+ compile_error(p, "incomplete character syntax");
return 0;
}
- if (rb_enc_isspace(c, current_enc)) {
+ if (rb_enc_isspace(c, p->enc)) {
if (!IS_ARG()) {
- int c2 = 0;
- 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;
- }
+ int c2 = escaped_control_code(c);
if (c2) {
- rb_warn1("invalid character syntax; use ?\\%c", WARN_I(c2));
+ WARN_SPACE_CHAR(c2, "?");
}
}
ternary:
- pushback(c);
+ pushback(p, c);
SET_LEX_STATE(EXPR_VALUE);
return '?';
}
- newtok();
- enc = current_enc;
- if (!parser_isascii()) {
- if (tokadd_mbchar(c) == -1) return 0;
+ newtok(p);
+ enc = p->enc;
+ if (!parser_isascii(p)) {
+ if (tokadd_mbchar(p, c) == -1) return 0;
}
- else if ((rb_enc_isalnum(c, current_enc) || c == '_') &&
- lex_p < lex_pend && is_identchar(lex_p, lex_pend, current_enc)) {
+ else if ((rb_enc_isalnum(c, p->enc) || c == '_') &&
+ p->lex.pcur < p->lex.pend && is_identchar(p->lex.pcur, p->lex.pend, p->enc)) {
if (space_seen) {
- const char *start = lex_p - 1, *p = start;
+ const char *start = p->lex.pcur - 1, *ptr = start;
do {
- int n = parser_precise_mbclen(parser, p);
+ int n = parser_precise_mbclen(p, ptr);
if (n < 0) return -1;
- p += n;
- } while (p < lex_pend && is_identchar(p, lex_pend, current_enc));
+ ptr += n;
+ } while (ptr < p->lex.pend && is_identchar(ptr, p->lex.pend, p->enc));
rb_warn2("`?' just followed by `%.*s' is interpreted as" \
" a conditional operator, put a space after `?'",
- WARN_I((int)(p - start)), WARN_S_L(start, (p - start)));
+ WARN_I((int)(ptr - start)), WARN_S_L(start, (ptr - start)));
}
goto ternary;
}
else if (c == '\\') {
- if (peek('u')) {
- nextc();
+ if (peek(p, 'u')) {
+ nextc(p);
enc = rb_utf8_encoding();
- if (!parser_tokadd_utf8(parser, &enc, -1, 0, 0))
- return 0;
+ tokadd_utf8(p, &enc, -1, 0, 0);
}
- else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
- nextc();
- if (tokadd_mbchar(c) == -1) return 0;
+ else if (!lex_eol_p(p) && !(c = *p->lex.pcur, ISASCII(c))) {
+ nextc(p);
+ if (tokadd_mbchar(p, c) == -1) return 0;
}
else {
- c = read_escape(0, &enc);
- tokadd(c);
+ c = read_escape(p, 0, &enc);
+ tokadd(p, c);
}
}
else {
- tokadd(c);
+ tokadd(p, c);
}
- tokfix();
- set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
+ tokfix(p);
+ lit = STR_NEW3(tok(p), toklen(p), enc, 0);
+ set_yylval_str(lit);
SET_LEX_STATE(EXPR_END);
return tCHAR;
}
static enum yytokentype
-parse_percent(struct parser_params *parser, const int space_seen, const enum lex_state_e last_state)
+parse_percent(struct parser_params *p, const int space_seen, const enum lex_state_e last_state)
{
register int c;
+ const char *ptok = p->lex.pcur;
if (IS_BEG()) {
int term;
int paren;
- c = nextc();
+ c = nextc(p);
quotation:
if (c == -1 || !ISALNUM(c)) {
term = c;
+ if (!ISASCII(c)) goto unknown;
c = 'Q';
}
else {
- term = nextc();
- if (rb_enc_isalnum(term, current_enc) || !parser_isascii()) {
- yyerror("unknown type of %string");
+ term = nextc(p);
+ if (rb_enc_isalnum(term, p->enc) || !parser_isascii(p)) {
+ unknown:
+ pushback(p, term);
+ c = parser_precise_mbclen(p, p->lex.pcur);
+ if (c < 0) return 0;
+ p->lex.pcur += c;
+ yyerror0("unknown type of %string");
return 0;
}
}
- if (c == -1 || term == -1) {
- compile_error(PARSER_ARG "unterminated quoted string meets end of file");
+ if (term == -1) {
+ compile_error(p, "unterminated quoted string meets end of file");
return 0;
}
paren = term;
@@ -7557,58 +8716,51 @@ parse_percent(struct parser_params *parser, const int space_seen, const enum lex
else if (term == '<') term = '>';
else paren = 0;
+ p->lex.ptok = ptok-1;
switch (c) {
case 'Q':
- lex_strterm = NEW_STRTERM(str_dquote, term, paren);
+ p->lex.strterm = NEW_STRTERM(str_dquote, term, paren);
return tSTRING_BEG;
case 'q':
- lex_strterm = NEW_STRTERM(str_squote, term, paren);
+ p->lex.strterm = NEW_STRTERM(str_squote, term, paren);
return tSTRING_BEG;
case 'W':
- lex_strterm = NEW_STRTERM(str_dword, term, paren);
- do {c = nextc();} while (ISSPACE(c));
- pushback(c);
+ p->lex.strterm = NEW_STRTERM(str_dword, term, paren);
return tWORDS_BEG;
case 'w':
- lex_strterm = NEW_STRTERM(str_sword, term, paren);
- do {c = nextc();} while (ISSPACE(c));
- pushback(c);
+ p->lex.strterm = NEW_STRTERM(str_sword, term, paren);
return tQWORDS_BEG;
case 'I':
- lex_strterm = NEW_STRTERM(str_dword, term, paren);
- do {c = nextc();} while (ISSPACE(c));
- pushback(c);
+ p->lex.strterm = NEW_STRTERM(str_dword, term, paren);
return tSYMBOLS_BEG;
case 'i':
- lex_strterm = NEW_STRTERM(str_sword, term, paren);
- do {c = nextc();} while (ISSPACE(c));
- pushback(c);
+ p->lex.strterm = NEW_STRTERM(str_sword, term, paren);
return tQSYMBOLS_BEG;
case 'x':
- lex_strterm = NEW_STRTERM(str_xquote, term, paren);
+ p->lex.strterm = NEW_STRTERM(str_xquote, term, paren);
return tXSTRING_BEG;
case 'r':
- lex_strterm = NEW_STRTERM(str_regexp, term, paren);
+ p->lex.strterm = NEW_STRTERM(str_regexp, term, paren);
return tREGEXP_BEG;
case 's':
- lex_strterm = NEW_STRTERM(str_ssym, term, paren);
+ p->lex.strterm = NEW_STRTERM(str_ssym, term, paren);
SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);
return tSYMBEG;
default:
- yyerror("unknown type of %string");
+ yyerror0("unknown type of %string");
return 0;
}
}
- if ((c = nextc()) == '=') {
+ if ((c = nextc(p)) == '=') {
set_yylval_id('%');
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
@@ -7617,23 +8769,23 @@ parse_percent(struct parser_params *parser, const int space_seen, const enum lex
goto quotation;
}
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- pushback(c);
+ pushback(p, c);
return warn_balanced('%', "%%", "string literal");
}
static int
-tokadd_ident(struct parser_params *parser, int c)
+tokadd_ident(struct parser_params *p, int c)
{
do {
- if (tokadd_mbchar(c) == -1) return -1;
- c = nextc();
- } while (parser_is_identchar());
- pushback(c);
+ if (tokadd_mbchar(p, c) == -1) return -1;
+ c = nextc(p);
+ } while (parser_is_identchar(p));
+ pushback(p, c);
return 0;
}
static ID
-tokenize_ident(struct parser_params *parser, const enum lex_state_e last_state)
+tokenize_ident(struct parser_params *p, const enum lex_state_e last_state)
{
ID ident = TOK_INTERN();
@@ -7643,11 +8795,11 @@ tokenize_ident(struct parser_params *parser, const enum lex_state_e last_state)
}
static int
-parse_numvar(struct parser_params *parser)
+parse_numvar(struct parser_params *p)
{
size_t len;
int overflow;
- unsigned long n = ruby_scan_digits(tok()+1, toklen()-1, 10, &len, &overflow);
+ unsigned long n = ruby_scan_digits(tok(p)+1, toklen(p)-1, 10, &len, &overflow);
const unsigned long nth_ref_max =
((FIXNUM_MAX < INT_MAX) ? FIXNUM_MAX : INT_MAX) >> 1;
/* NTH_REF is left-shifted to be ORed with back-ref flag and
@@ -7655,7 +8807,7 @@ parse_numvar(struct parser_params *parser)
if (overflow || n > nth_ref_max) {
/* compile_error()? */
- rb_warn1("`%s' is too big for a number variable, always nil", WARN_S(tok()));
+ rb_warn1("`%s' is too big for a number variable, always nil", WARN_S(tok(p)));
return 0; /* $0 is $PROGRAM_NAME, not NTH_REF */
}
else {
@@ -7664,22 +8816,24 @@ parse_numvar(struct parser_params *parser)
}
static enum yytokentype
-parse_gvar(struct parser_params *parser, const enum lex_state_e last_state)
+parse_gvar(struct parser_params *p, const enum lex_state_e last_state)
{
+ const char *ptr = p->lex.pcur;
register int c;
SET_LEX_STATE(EXPR_END);
- newtok();
- c = nextc();
+ p->lex.ptok = ptr - 1; /* from '$' */
+ newtok(p);
+ c = nextc(p);
switch (c) {
case '_': /* $_: last read line string */
- c = nextc();
- if (parser_is_identchar()) {
- tokadd('$');
- tokadd('_');
+ c = nextc(p);
+ if (parser_is_identchar(p)) {
+ tokadd(p, '$');
+ tokadd(p, '_');
break;
}
- pushback(c);
+ pushback(p, c);
c = '_';
/* fall through */
case '~': /* $~: match-data */
@@ -7698,20 +8852,20 @@ parse_gvar(struct parser_params *parser, const enum lex_state_e last_state)
case '<': /* $<: reading filename */
case '>': /* $>: default output handle */
case '\"': /* $": already loaded files */
- tokadd('$');
- tokadd(c);
+ tokadd(p, '$');
+ tokadd(p, c);
goto gvar;
case '-':
- tokadd('$');
- tokadd(c);
- c = nextc();
- if (parser_is_identchar()) {
- if (tokadd_mbchar(c) == -1) return 0;
+ tokadd(p, '$');
+ tokadd(p, c);
+ c = nextc(p);
+ if (parser_is_identchar(p)) {
+ if (tokadd_mbchar(p, c) == -1) return 0;
}
else {
- pushback(c);
- pushback('-');
+ pushback(p, c);
+ pushback(p, '-');
return '$';
}
gvar:
@@ -7723,119 +8877,160 @@ parse_gvar(struct parser_params *parser, const enum lex_state_e last_state)
case '\'': /* $': string after last match */
case '+': /* $+: string matches last paren. */
if (IS_lex_state_for(last_state, EXPR_FNAME)) {
- tokadd('$');
- tokadd(c);
+ tokadd(p, '$');
+ tokadd(p, c);
goto gvar;
}
- set_yylval_node(NEW_BACK_REF(c));
+ set_yylval_node(NEW_BACK_REF(c, &_cur_loc));
return tBACK_REF;
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
- tokadd('$');
+ tokadd(p, '$');
do {
- tokadd(c);
- c = nextc();
+ tokadd(p, c);
+ c = nextc(p);
} while (c != -1 && ISDIGIT(c));
- pushback(c);
+ pushback(p, c);
if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
- tokfix();
- set_yylval_node(NEW_NTH_REF(parse_numvar(parser)));
+ tokfix(p);
+ c = parse_numvar(p);
+ set_yylval_node(NEW_NTH_REF(c, &_cur_loc));
return tNTH_REF;
default:
- if (!parser_is_identchar()) {
+ if (!parser_is_identchar(p)) {
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
if (c == -1 || ISSPACE(c)) {
- compile_error(PARSER_ARG "`$' without identifiers is not allowed as a global variable name");
+ compile_error(p, "`$' without identifiers is not allowed as a global variable name");
}
else {
- pushback(c);
- compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
+ pushback(p, c);
+ compile_error(p, "`$%c' is not allowed as a global variable name", c);
}
- return 0;
+ parser_show_error_line(p, &loc);
+ set_yylval_noname();
+ return tGVAR;
}
+ /* fall through */
case '0':
- tokadd('$');
+ tokadd(p, '$');
}
- if (tokadd_ident(parser, c)) return 0;
+ if (tokadd_ident(p, c)) return 0;
SET_LEX_STATE(EXPR_END);
- tokenize_ident(parser, last_state);
+ tokenize_ident(p, last_state);
return tGVAR;
}
+#ifndef RIPPER
+static bool
+parser_numbered_param(struct parser_params *p, int n)
+{
+ if (n < 0) return false;
+
+ if (DVARS_TERMINAL_P(p->lvtbl->args) || DVARS_TERMINAL_P(p->lvtbl->args->prev)) {
+ return false;
+ }
+ if (p->max_numparam == ORDINAL_PARAM) {
+ compile_error(p, "ordinary parameter is defined");
+ return false;
+ }
+ struct vtable *args = p->lvtbl->args;
+ if (p->max_numparam < n) {
+ p->max_numparam = n;
+ }
+ while (n > args->pos) {
+ vtable_add(args, NUMPARAM_IDX_TO_ID(args->pos+1));
+ }
+ return true;
+}
+#endif
+
static enum yytokentype
-parse_atmark(struct parser_params *parser, const enum lex_state_e last_state)
+parse_atmark(struct parser_params *p, const enum lex_state_e last_state)
{
+ const char *ptr = p->lex.pcur;
enum yytokentype result = tIVAR;
- register int c = nextc();
+ register int c = nextc(p);
+ YYLTYPE loc;
- newtok();
- tokadd('@');
+ p->lex.ptok = ptr - 1; /* from '@' */
+ newtok(p);
+ tokadd(p, '@');
if (c == '@') {
result = tCVAR;
- tokadd('@');
- c = nextc();
+ tokadd(p, '@');
+ c = nextc(p);
}
- if (c == -1 || ISSPACE(c)) {
+ SET_LEX_STATE(IS_lex_state_for(last_state, EXPR_FNAME) ? EXPR_ENDFN : EXPR_END);
+ if (c == -1 || !parser_is_identchar(p)) {
+ pushback(p, c);
+ RUBY_SET_YYLLOC(loc);
if (result == tIVAR) {
- compile_error(PARSER_ARG "`@' without identifiers is not allowed as an instance variable name");
+ compile_error(p, "`@' without identifiers is not allowed as an instance variable name");
}
else {
- compile_error(PARSER_ARG "`@@' without identifiers is not allowed as a class variable name");
+ compile_error(p, "`@@' without identifiers is not allowed as a class variable name");
}
- return 0;
+ parser_show_error_line(p, &loc);
+ set_yylval_noname();
+ SET_LEX_STATE(EXPR_END);
+ return result;
}
- else if (ISDIGIT(c) || !parser_is_identchar()) {
- pushback(c);
+ else if (ISDIGIT(c)) {
+ pushback(p, c);
+ RUBY_SET_YYLLOC(loc);
if (result == tIVAR) {
- compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
+ compile_error(p, "`@%c' is not allowed as an instance variable name", c);
}
else {
- compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
+ compile_error(p, "`@@%c' is not allowed as a class variable name", c);
}
- return 0;
+ parser_show_error_line(p, &loc);
+ set_yylval_noname();
+ SET_LEX_STATE(EXPR_END);
+ return result;
}
- if (tokadd_ident(parser, c)) return 0;
- SET_LEX_STATE(EXPR_END);
- tokenize_ident(parser, last_state);
+ if (tokadd_ident(p, c)) return 0;
+ tokenize_ident(p, last_state);
return result;
}
static enum yytokentype
-parse_ident(struct parser_params *parser, int c, int cmd_state)
+parse_ident(struct parser_params *p, int c, int cmd_state)
{
enum yytokentype result;
int mb = ENC_CODERANGE_7BIT;
- const enum lex_state_e last_state = lex_state;
+ const enum lex_state_e last_state = p->lex.state;
ID ident;
do {
if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
- if (tokadd_mbchar(c) == -1) return 0;
- c = nextc();
- } while (parser_is_identchar());
- if ((c == '!' || c == '?') && !peek('=')) {
+ if (tokadd_mbchar(p, c) == -1) return 0;
+ c = nextc(p);
+ } while (parser_is_identchar(p));
+ if ((c == '!' || c == '?') && !peek(p, '=')) {
result = tFID;
- tokadd(c);
+ tokadd(p, c);
}
else if (c == '=' && IS_lex_state(EXPR_FNAME) &&
- (!peek('~') && !peek('>') && (!peek('=') || (peek_n('>', 1))))) {
+ (!peek(p, '~') && !peek(p, '>') && (!peek(p, '=') || (peek_n(p, '>', 1))))) {
result = tIDENTIFIER;
- tokadd(c);
+ tokadd(p, c);
}
else {
result = tCONSTANT; /* assume provisionally */
- pushback(c);
+ pushback(p, c);
}
- tokfix();
+ tokfix(p);
if (IS_LABEL_POSSIBLE()) {
if (IS_LABEL_SUFFIX(0)) {
SET_LEX_STATE(EXPR_ARG|EXPR_LABELED);
- nextc();
+ nextc(p);
set_yylval_name(TOK_INTERN());
return tLABEL;
}
@@ -7844,28 +9039,26 @@ parse_ident(struct parser_params *parser, int c, int cmd_state)
const struct kwtable *kw;
/* See if it is a reserved word. */
- kw = rb_reserved_word(tok(), toklen());
+ kw = rb_reserved_word(tok(p), toklen(p));
if (kw) {
- enum lex_state_e state = lex_state;
- SET_LEX_STATE(kw->state);
+ enum lex_state_e state = p->lex.state;
if (IS_lex_state_for(state, EXPR_FNAME)) {
- set_yylval_name(rb_intern2(tok(), toklen()));
+ SET_LEX_STATE(EXPR_ENDFN);
+ set_yylval_name(rb_intern2(tok(p), toklen(p)));
return kw->id[0];
}
+ SET_LEX_STATE(kw->state);
if (IS_lex_state(EXPR_BEG)) {
- command_start = TRUE;
+ p->command_start = TRUE;
}
if (kw->id[0] == keyword_do) {
if (lambda_beginning_p()) {
- lpar_beg = 0;
- --paren_nest;
+ p->lex.lpar_beg = -1; /* make lambda_beginning_p() == FALSE in the body of "-> do ... end" */
return keyword_do_LAMBDA;
}
if (COND_P()) return keyword_do_cond;
if (CMDARG_P() && !IS_lex_state_for(state, EXPR_CMDARG))
return keyword_do_block;
- if (IS_lex_state_for(state, (EXPR_BEG | EXPR_ENDARG)))
- return keyword_do_block;
return keyword_do;
}
if (IS_lex_state_for(state, (EXPR_BEG | EXPR_LABELED)))
@@ -7886,25 +9079,25 @@ parse_ident(struct parser_params *parser, int c, int cmd_state)
SET_LEX_STATE(EXPR_ARG);
}
}
- else if (lex_state == EXPR_FNAME) {
+ else if (p->lex.state == EXPR_FNAME) {
SET_LEX_STATE(EXPR_ENDFN);
}
else {
SET_LEX_STATE(EXPR_END);
}
- ident = tokenize_ident(parser, last_state);
+ ident = tokenize_ident(p, last_state);
if (result == tCONSTANT && is_local_id(ident)) result = tIDENTIFIER;
if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
(result == tIDENTIFIER) && /* not EXPR_FNAME, not attrasgn */
- lvar_defined(ident)) {
+ lvar_defined(p, ident)) {
SET_LEX_STATE(EXPR_END|EXPR_LABEL);
}
return result;
}
static enum yytokentype
-parser_yylex(struct parser_params *parser)
+parser_yylex(struct parser_params *p)
{
register int c;
int space_seen = 0;
@@ -7912,25 +9105,26 @@ parser_yylex(struct parser_params *parser)
int label;
enum lex_state_e last_state;
int fallthru = FALSE;
- int token_seen = parser->token_seen;
+ int token_seen = p->token_seen;
- if (lex_strterm) {
- if (nd_type(lex_strterm) == NODE_HEREDOC) {
- return here_document(lex_strterm);
+ if (p->lex.strterm) {
+ if (p->lex.strterm->flags & STRTERM_HEREDOC) {
+ return here_document(p, &p->lex.strterm->u.heredoc);
}
else {
- return parse_string(lex_strterm);
+ token_flush(p);
+ return parse_string(p, &p->lex.strterm->u.literal);
}
}
- cmd_state = command_start;
- command_start = FALSE;
- parser->token_seen = TRUE;
+ cmd_state = p->command_start;
+ p->command_start = FALSE;
+ p->token_seen = TRUE;
retry:
- last_state = lex_state;
+ last_state = p->lex.state;
#ifndef RIPPER
- token_flush(parser);
+ token_flush(p);
#endif
- switch (c = nextc()) {
+ switch (c = nextc(p)) {
case '\0': /* NUL */
case '\004': /* ^D */
case '\032': /* ^Z */
@@ -7938,11 +9132,18 @@ parser_yylex(struct parser_params *parser)
return 0;
/* white spaces */
- case ' ': case '\t': case '\f': case '\r':
+ case '\r':
+ if (!p->cr_seen) {
+ p->cr_seen = TRUE;
+ /* carried over with p->lex.nextline for nextc() */
+ rb_warn0("encountered \\r in middle of line, treated as a mere space");
+ }
+ /* fall through */
+ case ' ': case '\t': case '\f':
case '\13': /* '\v' */
space_seen = 1;
#ifdef RIPPER
- while ((c = nextc())) {
+ while ((c = nextc(p))) {
switch (c) {
case ' ': case '\t': case '\f': case '\r':
case '\13': /* '\v' */
@@ -7952,78 +9153,88 @@ parser_yylex(struct parser_params *parser)
}
}
outofloop:
- pushback(c);
- dispatch_scan_event(tSP);
+ pushback(p, c);
+ dispatch_scan_event(p, tSP);
#endif
goto retry;
case '#': /* it's a comment */
- parser->token_seen = token_seen;
+ p->token_seen = token_seen;
/* no magic_comment in shebang line */
- if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
- if (comment_at_top(parser)) {
- set_file_encoding(parser, lex_p, lex_pend);
+ if (!parser_magic_comment(p, p->lex.pcur, p->lex.pend - p->lex.pcur)) {
+ if (comment_at_top(p)) {
+ set_file_encoding(p, p->lex.pcur, p->lex.pend);
}
}
- lex_p = lex_pend;
- dispatch_scan_event(tCOMMENT);
+ lex_goto_eol(p);
+ dispatch_scan_event(p, tCOMMENT);
fallthru = TRUE;
/* fall through */
case '\n':
- parser->token_seen = token_seen;
+ p->token_seen = token_seen;
c = (IS_lex_state(EXPR_BEG|EXPR_CLASS|EXPR_FNAME|EXPR_DOT) &&
!IS_lex_state(EXPR_LABELED));
if (c || IS_lex_state_all(EXPR_ARG|EXPR_LABELED)) {
if (!fallthru) {
- dispatch_scan_event(tIGNORED_NL);
+ dispatch_scan_event(p, tIGNORED_NL);
}
fallthru = FALSE;
- if (!c && parser->in_kwarg) {
+ if (!c && p->ctxt.in_kwarg) {
goto normal_newline;
}
goto retry;
}
- while ((c = nextc())) {
- switch (c) {
+ while (1) {
+ switch (c = nextc(p)) {
case ' ': case '\t': case '\f': case '\r':
case '\13': /* '\v' */
space_seen = 1;
break;
+ case '#':
+ pushback(p, c);
+ if (space_seen) dispatch_scan_event(p, tSP);
+ goto retry;
case '&':
case '.': {
- dispatch_delayed_token(tIGNORED_NL);
- if (peek('.') == (c == '&')) {
- pushback(c);
- dispatch_scan_event(tSP);
+ dispatch_delayed_token(p, tIGNORED_NL);
+ if (peek(p, '.') == (c == '&')) {
+ pushback(p, c);
+ dispatch_scan_event(p, tSP);
goto retry;
}
}
default:
- --ruby_sourceline;
- lex_nextline = lex_lastline;
+ p->ruby_sourceline--;
+ p->lex.nextline = p->lex.lastline;
case -1: /* EOF no decrement*/
- lex_goto_eol(parser);
-#ifdef RIPPER
+#ifndef RIPPER
+ if (p->lex.prevline && !p->eofp) p->lex.lastline = p->lex.prevline;
+ p->lex.pbeg = RSTRING_PTR(p->lex.lastline);
+ p->lex.pend = p->lex.pcur = p->lex.pbeg + RSTRING_LEN(p->lex.lastline);
+ pushback(p, 1); /* always pushback */
+ p->lex.ptok = p->lex.pcur;
+#else
+ lex_goto_eol(p);
if (c != -1) {
- parser->tokp = lex_p;
+ p->lex.ptok = p->lex.pcur;
}
#endif
goto normal_newline;
}
}
normal_newline:
- command_start = TRUE;
+ p->command_start = TRUE;
SET_LEX_STATE(EXPR_BEG);
return '\n';
case '*':
- if ((c = nextc()) == '*') {
- if ((c = nextc()) == '=') {
- set_yylval_id(tPOW);
+ if ((c = nextc(p)) == '*') {
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idPow);
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- pushback(c);
+ pushback(p, c);
if (IS_SPCARG(c)) {
rb_warning0("`**' interpreted as argument prefix");
c = tDSTAR;
@@ -8041,7 +9252,7 @@ parser_yylex(struct parser_params *parser)
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- pushback(c);
+ pushback(p, c);
if (IS_SPCARG(c)) {
rb_warning0("`*' interpreted as argument prefix");
c = tSTAR;
@@ -8057,7 +9268,7 @@ parser_yylex(struct parser_params *parser)
return c;
case '!':
- c = nextc();
+ c = nextc(p);
if (IS_AFTER_OPERATOR()) {
SET_LEX_STATE(EXPR_ARG);
if (c == '@') {
@@ -8073,46 +9284,45 @@ parser_yylex(struct parser_params *parser)
if (c == '~') {
return tNMATCH;
}
- pushback(c);
+ pushback(p, c);
return '!';
case '=':
- if (was_bol()) {
+ if (was_bol(p)) {
/* skip embedded rd document */
- if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
+ if (word_match_p(p, "begin", 5)) {
int first_p = TRUE;
- lex_goto_eol(parser);
- dispatch_scan_event(tEMBDOC_BEG);
+ lex_goto_eol(p);
+ dispatch_scan_event(p, tEMBDOC_BEG);
for (;;) {
- lex_goto_eol(parser);
+ lex_goto_eol(p);
if (!first_p) {
- dispatch_scan_event(tEMBDOC);
+ dispatch_scan_event(p, tEMBDOC);
}
first_p = FALSE;
- c = nextc();
+ c = nextc(p);
if (c == -1) {
- compile_error(PARSER_ARG "embedded document meets end of file");
+ compile_error(p, "embedded document meets end of file");
return 0;
}
- if (c != '=') continue;
- if (c == '=' && strncmp(lex_p, "end", 3) == 0 &&
- (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
+ if (c == '=' && word_match_p(p, "end", 3)) {
break;
}
+ pushback(p, c);
}
- lex_goto_eol(parser);
- dispatch_scan_event(tEMBDOC_END);
+ lex_goto_eol(p);
+ dispatch_scan_event(p, tEMBDOC_END);
goto retry;
}
}
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- if ((c = nextc()) == '=') {
- if ((c = nextc()) == '=') {
+ if ((c = nextc(p)) == '=') {
+ if ((c = nextc(p)) == '=') {
return tEQQ;
}
- pushback(c);
+ pushback(p, c);
return tEQ;
}
if (c == '~') {
@@ -8121,66 +9331,66 @@ parser_yylex(struct parser_params *parser)
else if (c == '>') {
return tASSOC;
}
- pushback(c);
+ pushback(p, c);
return '=';
case '<':
- last_state = lex_state;
- c = nextc();
+ c = nextc(p);
if (c == '<' &&
!IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
!IS_END() &&
(!IS_ARG() || IS_lex_state(EXPR_LABELED) || space_seen)) {
- int token = heredoc_identifier();
- if (token) return token;
+ int token = heredoc_identifier(p);
+ if (token) return token < 0 ? 0 : token;
}
if (IS_AFTER_OPERATOR()) {
SET_LEX_STATE(EXPR_ARG);
}
else {
if (IS_lex_state(EXPR_CLASS))
- command_start = TRUE;
+ p->command_start = TRUE;
SET_LEX_STATE(EXPR_BEG);
}
if (c == '=') {
- if ((c = nextc()) == '>') {
+ if ((c = nextc(p)) == '>') {
return tCMP;
}
- pushback(c);
+ pushback(p, c);
return tLEQ;
}
if (c == '<') {
- if ((c = nextc()) == '=') {
- set_yylval_id(tLSHFT);
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idLTLT);
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- pushback(c);
+ pushback(p, c);
return warn_balanced((enum ruby_method_ids)tLSHFT, "<<", "here document");
}
- pushback(c);
+ pushback(p, c);
return '<';
case '>':
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- if ((c = nextc()) == '=') {
+ if ((c = nextc(p)) == '=') {
return tGEQ;
}
if (c == '>') {
- if ((c = nextc()) == '=') {
- set_yylval_id(tRSHFT);
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idGTGT);
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- pushback(c);
+ pushback(p, c);
return tRSHFT;
}
- pushback(c);
+ pushback(p, c);
return '>';
case '"':
label = (IS_LABEL_POSSIBLE() ? str_label : 0);
- lex_strterm = NEW_STRTERM(str_dquote | label, '"', 0);
+ p->lex.strterm = NEW_STRTERM(str_dquote | label, '"', 0);
+ p->lex.ptok = p->lex.pcur-1;
return tSTRING_BEG;
case '`':
@@ -8195,26 +9405,27 @@ parser_yylex(struct parser_params *parser)
SET_LEX_STATE(EXPR_ARG);
return c;
}
- lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
+ p->lex.strterm = NEW_STRTERM(str_xquote, '`', 0);
return tXSTRING_BEG;
case '\'':
label = (IS_LABEL_POSSIBLE() ? str_label : 0);
- lex_strterm = NEW_STRTERM(str_squote | label, '\'', 0);
+ p->lex.strterm = NEW_STRTERM(str_squote | label, '\'', 0);
+ p->lex.ptok = p->lex.pcur-1;
return tSTRING_BEG;
case '?':
- return parse_qmark(parser, space_seen);
+ return parse_qmark(p, space_seen);
case '&':
- if ((c = nextc()) == '&') {
+ if ((c = nextc(p)) == '&') {
SET_LEX_STATE(EXPR_BEG);
- if ((c = nextc()) == '=') {
- set_yylval_id(tANDOP);
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idANDOP);
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- pushback(c);
+ pushback(p, c);
return tANDOP;
}
else if (c == '=') {
@@ -8223,15 +9434,16 @@ parser_yylex(struct parser_params *parser)
return tOP_ASGN;
}
else if (c == '.') {
+ set_yylval_id(idANDDOT);
SET_LEX_STATE(EXPR_DOT);
return tANDDOT;
}
- pushback(c);
+ pushback(p, c);
if (IS_SPCARG(c)) {
if ((c != ':') ||
- (c = peekc_n(1)) == -1 ||
+ (c = peekc_n(p, 1)) == -1 ||
!(c == '\'' || c == '"' ||
- is_identchar((lex_p+1), lex_pend, current_enc))) {
+ is_identchar((p->lex.pcur+1), p->lex.pend, p->enc))) {
rb_warning0("`&' interpreted as argument prefix");
}
c = tAMPER;
@@ -8246,14 +9458,19 @@ parser_yylex(struct parser_params *parser)
return c;
case '|':
- if ((c = nextc()) == '|') {
+ if ((c = nextc(p)) == '|') {
SET_LEX_STATE(EXPR_BEG);
- if ((c = nextc()) == '=') {
- set_yylval_id(tOROP);
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idOROP);
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- pushback(c);
+ pushback(p, c);
+ if (IS_lex_state_for(last_state, EXPR_BEG)) {
+ c = '|';
+ pushback(p, '|');
+ return c;
+ }
return tOROP;
}
if (c == '=') {
@@ -8262,17 +9479,17 @@ parser_yylex(struct parser_params *parser)
return tOP_ASGN;
}
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG|EXPR_LABEL);
- pushback(c);
+ pushback(p, c);
return '|';
case '+':
- c = nextc();
+ c = nextc(p);
if (IS_AFTER_OPERATOR()) {
SET_LEX_STATE(EXPR_ARG);
if (c == '@') {
return tUPLUS;
}
- pushback(c);
+ pushback(p, c);
return '+';
}
if (c == '=') {
@@ -8280,26 +9497,26 @@ parser_yylex(struct parser_params *parser)
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous('+'))) {
+ if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p, '+'))) {
SET_LEX_STATE(EXPR_BEG);
- pushback(c);
+ pushback(p, c);
if (c != -1 && ISDIGIT(c)) {
- return parse_numeric(parser, '+');
+ return parse_numeric(p, '+');
}
return tUPLUS;
}
SET_LEX_STATE(EXPR_BEG);
- pushback(c);
+ pushback(p, c);
return warn_balanced('+', "+", "unary operator");
case '-':
- c = nextc();
+ c = nextc(p);
if (IS_AFTER_OPERATOR()) {
SET_LEX_STATE(EXPR_ARG);
if (c == '@') {
return tUMINUS;
}
- pushback(c);
+ pushback(p, c);
return '-';
}
if (c == '=') {
@@ -8309,81 +9526,109 @@ parser_yylex(struct parser_params *parser)
}
if (c == '>') {
SET_LEX_STATE(EXPR_ENDFN);
- token_info_push("->");
return tLAMBDA;
}
- if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous('-'))) {
+ if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p, '-'))) {
SET_LEX_STATE(EXPR_BEG);
- pushback(c);
+ pushback(p, c);
if (c != -1 && ISDIGIT(c)) {
return tUMINUS_NUM;
}
return tUMINUS;
}
SET_LEX_STATE(EXPR_BEG);
- pushback(c);
+ pushback(p, c);
return warn_balanced('-', "-", "unary operator");
- case '.':
+ case '.': {
+ int is_beg = IS_BEG();
SET_LEX_STATE(EXPR_BEG);
- if ((c = nextc()) == '.') {
- if ((c = nextc()) == '.') {
- return tDOT3;
+ if ((c = nextc(p)) == '.') {
+ if ((c = nextc(p)) == '.') {
+ if (p->lex.paren_nest == 0 && looking_at_eol_p(p)) {
+ rb_warn0("... at EOL, should be parenthesized?");
+ }
+ else if (p->lex.lpar_beg >= 0 && p->lex.lpar_beg+1 == p->lex.paren_nest) {
+ if (IS_lex_state_for(last_state, EXPR_LABEL))
+ return tDOT3;
+ }
+ return is_beg ? tBDOT3 : tDOT3;
}
- pushback(c);
- return tDOT2;
+ pushback(p, c);
+ return is_beg ? tBDOT2 : tDOT2;
}
- pushback(c);
+ pushback(p, c);
if (c != -1 && ISDIGIT(c)) {
- yyerror("no .<digit> floating literal anymore; put 0 before dot");
+ char prev = p->lex.pcur-1 > p->lex.pbeg ? *(p->lex.pcur-2) : 0;
+ parse_numeric(p, '.');
+ if (ISDIGIT(prev)) {
+ yyerror0("unexpected fraction part after numeric literal");
+ }
+ else {
+ yyerror0("no .<digit> floating literal anymore; put 0 before dot");
+ }
+ SET_LEX_STATE(EXPR_END);
+ p->lex.ptok = p->lex.pcur;
+ goto retry;
}
+ set_yylval_id('.');
SET_LEX_STATE(EXPR_DOT);
return '.';
+ }
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- return parse_numeric(parser, c);
+ return parse_numeric(p, c);
case ')':
+ COND_POP();
+ CMDARG_POP();
+ SET_LEX_STATE(EXPR_ENDFN);
+ p->lex.paren_nest--;
+ return c;
+
case ']':
- paren_nest--;
+ COND_POP();
+ CMDARG_POP();
+ SET_LEX_STATE(EXPR_END);
+ p->lex.paren_nest--;
+ return c;
+
case '}':
- COND_LEXPOP();
- CMDARG_LEXPOP();
- if (c == ')')
- SET_LEX_STATE(EXPR_ENDFN);
- else
- SET_LEX_STATE(EXPR_END);
- if (c == '}') {
- if (!brace_nest--) c = tSTRING_DEND;
- }
+ /* tSTRING_DEND does COND_POP and CMDARG_POP in the yacc's rule */
+ if (!p->lex.brace_nest--) return tSTRING_DEND;
+ COND_POP();
+ CMDARG_POP();
+ SET_LEX_STATE(EXPR_END);
+ p->lex.paren_nest--;
return c;
case ':':
- c = nextc();
+ c = nextc(p);
if (c == ':') {
if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
SET_LEX_STATE(EXPR_BEG);
return tCOLON3;
}
+ set_yylval_id(idCOLON2);
SET_LEX_STATE(EXPR_DOT);
return tCOLON2;
}
if (IS_END() || ISSPACE(c) || c == '#') {
- pushback(c);
+ pushback(p, c);
c = warn_balanced(':', ":", "symbol literal");
SET_LEX_STATE(EXPR_BEG);
return c;
}
switch (c) {
case '\'':
- lex_strterm = NEW_STRTERM(str_ssym, c, 0);
+ p->lex.strterm = NEW_STRTERM(str_ssym, c, 0);
break;
case '"':
- lex_strterm = NEW_STRTERM(str_dsym, c, 0);
+ p->lex.strterm = NEW_STRTERM(str_dsym, c, 0);
break;
default:
- pushback(c);
+ pushback(p, c);
break;
}
SET_LEX_STATE(EXPR_FNAME);
@@ -8391,36 +9636,36 @@ parser_yylex(struct parser_params *parser)
case '/':
if (IS_BEG()) {
- lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
+ p->lex.strterm = NEW_STRTERM(str_regexp, '/', 0);
return tREGEXP_BEG;
}
- if ((c = nextc()) == '=') {
+ if ((c = nextc(p)) == '=') {
set_yylval_id('/');
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
- pushback(c);
+ pushback(p, c);
if (IS_SPCARG(c)) {
- (void)arg_ambiguous('/');
- lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
+ arg_ambiguous(p, '/');
+ p->lex.strterm = NEW_STRTERM(str_regexp, '/', 0);
return tREGEXP_BEG;
}
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
return warn_balanced('/', "/", "regexp literal");
case '^':
- if ((c = nextc()) == '=') {
+ if ((c = nextc(p)) == '=') {
set_yylval_id('^');
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- pushback(c);
+ pushback(p, c);
return '^';
case ';':
SET_LEX_STATE(EXPR_BEG);
- command_start = TRUE;
+ p->command_start = TRUE;
return ';';
case ',':
@@ -8429,8 +9674,8 @@ parser_yylex(struct parser_params *parser)
case '~':
if (IS_AFTER_OPERATOR()) {
- if ((c = nextc()) != '@') {
- pushback(c);
+ if ((c = nextc(p)) != '@') {
+ pushback(p, c);
}
SET_LEX_STATE(EXPR_ARG);
}
@@ -8453,24 +9698,25 @@ parser_yylex(struct parser_params *parser)
rb_warning0("parentheses after method name is interpreted as "
"an argument list, not a decomposed argument");
}
- paren_nest++;
+ p->lex.paren_nest++;
COND_PUSH(0);
CMDARG_PUSH(0);
SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
return c;
case '[':
- paren_nest++;
+ p->lex.paren_nest++;
if (IS_AFTER_OPERATOR()) {
- if ((c = nextc()) == ']') {
+ if ((c = nextc(p)) == ']') {
+ p->lex.paren_nest--;
SET_LEX_STATE(EXPR_ARG);
- if ((c = nextc()) == '=') {
+ if ((c = nextc(p)) == '=') {
return tASET;
}
- pushback(c);
+ pushback(p, c);
return tAREF;
}
- pushback(c);
+ pushback(p, c);
SET_LEX_STATE(EXPR_ARG|EXPR_LABEL);
return '[';
}
@@ -8486,16 +9732,10 @@ parser_yylex(struct parser_params *parser)
return c;
case '{':
- ++brace_nest;
- if (lambda_beginning_p()) {
- SET_LEX_STATE(EXPR_BEG);
- lpar_beg = 0;
- --paren_nest;
- COND_PUSH(0);
- CMDARG_PUSH(0);
- return tLAMBEG;
- }
- if (IS_lex_state(EXPR_LABELED))
+ ++p->lex.brace_nest;
+ if (lambda_beginning_p())
+ c = tLAMBEG;
+ else if (IS_lex_state(EXPR_LABELED))
c = tLBRACE; /* hash */
else if (IS_lex_state(EXPR_ARG_ANY | EXPR_END | EXPR_ENDFN))
c = '{'; /* block (primary) */
@@ -8503,86 +9743,113 @@ parser_yylex(struct parser_params *parser)
c = tLBRACE_ARG; /* block (expr) */
else
c = tLBRACE; /* hash */
+ if (c != tLBRACE) {
+ p->command_start = TRUE;
+ SET_LEX_STATE(EXPR_BEG);
+ }
+ else {
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ }
+ ++p->lex.paren_nest; /* after lambda_beginning_p() */
COND_PUSH(0);
CMDARG_PUSH(0);
- SET_LEX_STATE(c == tLBRACE_ARG ? EXPR_BEG : EXPR_BEG|EXPR_LABEL);
- if (c != tLBRACE) command_start = TRUE;
return c;
case '\\':
- c = nextc();
+ c = nextc(p);
if (c == '\n') {
space_seen = 1;
- dispatch_scan_event(tSP);
+ dispatch_scan_event(p, tSP);
goto retry; /* skip \\n */
}
- pushback(c);
+ if (c == ' ') return tSP;
+ if (ISSPACE(c)) return c;
+ pushback(p, c);
return '\\';
case '%':
- return parse_percent(parser, space_seen, last_state);
+ return parse_percent(p, space_seen, last_state);
case '$':
- return parse_gvar(parser, last_state);
+ return parse_gvar(p, last_state);
case '@':
- return parse_atmark(parser, last_state);
+ return parse_atmark(p, last_state);
case '_':
- if (was_bol() && whole_match_p("__END__", 7, 0)) {
- ruby__end__seen = 1;
- parser->eofp = 1;
+ if (was_bol(p) && whole_match_p(p, "__END__", 7, 0)) {
+ p->ruby__end__seen = 1;
+ p->eofp = 1;
#ifndef RIPPER
return -1;
#else
- lex_goto_eol(parser);
- dispatch_scan_event(k__END__);
+ lex_goto_eol(p);
+ dispatch_scan_event(p, k__END__);
return 0;
#endif
}
- newtok();
+ newtok(p);
break;
default:
- if (!parser_is_identchar()) {
- compile_error(PARSER_ARG "Invalid char `\\x%02X' in expression", c);
+ if (!parser_is_identchar(p)) {
+ compile_error(p, "Invalid char `\\x%02X' in expression", c);
+ token_flush(p);
goto retry;
}
- newtok();
+ newtok(p);
break;
}
- return parse_ident(parser, c, cmd_state);
+ return parse_ident(p, c, cmd_state);
}
static enum yytokentype
-yylex(YYSTYPE *lval, struct parser_params *parser)
+yylex(YYSTYPE *lval, YYLTYPE *yylloc, struct parser_params *p)
{
enum yytokentype t;
- parser->lval = lval;
+ p->lval = lval;
lval->val = Qundef;
- t = parser_yylex(parser);
- if (has_delayed_token())
- dispatch_delayed_token(t);
+ t = parser_yylex(p);
+
+ if (p->lex.strterm && (p->lex.strterm->flags & STRTERM_HEREDOC))
+ RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(*yylloc);
+ else
+ RUBY_SET_YYLLOC(*yylloc);
+
+ if (has_delayed_token(p))
+ dispatch_delayed_token(p, t);
else if (t != 0)
- dispatch_scan_event(t);
+ dispatch_scan_event(p, t);
return t;
}
#define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
-#ifndef RIPPER
static NODE*
-node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
+node_newnode(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2, const rb_code_location_t *loc)
{
- NODE *n = (rb_node_newnode)(type, a0, a1, a2);
- nd_set_line(n, ruby_sourceline);
+ NODE *n = rb_ast_newnode(p->ast, type);
+
+ rb_node_init(n, type, a0, a1, a2);
+
+ nd_set_loc(n, loc);
+ nd_set_node_id(n, parser_get_node_id(p));
return n;
}
+static NODE *
+nd_set_loc(NODE *nd, const YYLTYPE *loc)
+{
+ nd->nd_loc = *loc;
+ nd_set_line(nd, loc->beg_pos.lineno);
+ return nd;
+}
+
+#ifndef RIPPER
static enum node_type
nodetype(NODE *node) /* for debug */
{
@@ -8610,26 +9877,23 @@ fixpos(NODE *node, NODE *orig)
{
if (!node) return;
if (!orig) return;
- if (orig == (NODE*)1) return;
nd_set_line(node, nd_line(orig));
}
static void
-parser_warning(struct parser_params *parser, NODE *node, const char *mesg)
+parser_warning(struct parser_params *p, NODE *node, const char *mesg)
{
- rb_compile_warning(ruby_sourcefile, nd_line(node), "%s", mesg);
+ rb_compile_warning(p->ruby_sourcefile, nd_line(node), "%s", mesg);
}
-#define parser_warning(node, mesg) parser_warning(parser, (node), (mesg))
static void
-parser_warn(struct parser_params *parser, NODE *node, const char *mesg)
+parser_warn(struct parser_params *p, NODE *node, const char *mesg)
{
- rb_compile_warn(ruby_sourcefile, nd_line(node), "%s", mesg);
+ rb_compile_warn(p->ruby_sourcefile, nd_line(node), "%s", mesg);
}
-#define parser_warn(node, mesg) parser_warn(parser, (node), (mesg))
static NODE*
-block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
+block_append(struct parser_params *p, NODE *head, NODE *tail)
{
NODE *end, *h = head, *nd;
@@ -8643,12 +9907,11 @@ block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
case NODE_TRUE:
case NODE_FALSE:
case NODE_NIL:
- parser_warning(h, "unused literal ignored");
+ parser_warning(p, h, "unused literal ignored");
return tail;
default:
- h = end = NEW_BLOCK(head);
+ h = end = NEW_BLOCK(head, &head->nd_loc);
end->nd_end = end;
- fixpos(end, head);
head = end;
break;
case NODE_BLOCK:
@@ -8664,7 +9927,7 @@ block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
case NODE_REDO:
case NODE_RETRY:
if (RTEST(ruby_verbose)) {
- parser_warning(tail, "statement not reached");
+ parser_warning(p, tail, "statement not reached");
}
break;
@@ -8673,21 +9936,22 @@ block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
}
if (nd_type(tail) != NODE_BLOCK) {
- tail = NEW_BLOCK(tail);
+ tail = NEW_BLOCK(tail, &tail->nd_loc);
tail->nd_end = tail;
}
end->nd_next = tail;
h->nd_end = tail->nd_end;
+ nd_set_last_loc(head, nd_last_loc(tail));
return head;
}
/* append item to the list */
static NODE*
-list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
+list_append(struct parser_params *p, NODE *list, NODE *item)
{
NODE *last;
- if (list == 0) return NEW_LIST(item);
+ if (list == 0) return NEW_LIST(item, &item->nd_loc);
if (list->nd_next) {
last = list->nd_next->nd_end;
}
@@ -8696,8 +9960,11 @@ list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
}
list->nd_alen += 1;
- last->nd_next = NEW_LIST(item);
+ last->nd_next = NEW_LIST(item, &item->nd_loc);
list->nd_next->nd_end = last->nd_next;
+
+ nd_set_last_loc(list, nd_last_loc(item));
+
return list;
}
@@ -8723,15 +9990,17 @@ list_concat(NODE *head, NODE *tail)
head->nd_next->nd_end = tail;
}
+ nd_set_last_loc(head, nd_last_loc(tail));
+
return head;
}
static int
-literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
+literal_concat0(struct parser_params *p, VALUE head, VALUE tail)
{
if (NIL_P(tail)) return 1;
if (!rb_enc_compatible(head, tail)) {
- compile_error(PARSER_ARG "string literal encodings differ (%s / %s)",
+ compile_error(p, "string literal encodings differ (%s / %s)",
rb_enc_name(rb_enc_get(head)),
rb_enc_name(rb_enc_get(tail)));
rb_str_resize(head, 0);
@@ -8742,12 +10011,24 @@ literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
return 1;
}
+static VALUE
+string_literal_head(enum node_type htype, NODE *head)
+{
+ if (htype != NODE_DSTR) return Qfalse;
+ if (head->nd_next) {
+ head = head->nd_next->nd_end->nd_head;
+ if (!head || nd_type(head) != NODE_STR) return Qfalse;
+ }
+ const VALUE lit = head->nd_lit;
+ ASSUME(lit != Qfalse);
+ return lit;
+}
+
/* concat two string literals */
static NODE *
-literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
+literal_concat(struct parser_params *p, NODE *head, NODE *tail, const YYLTYPE *loc)
{
enum node_type htype;
- NODE *headlast;
VALUE lit;
if (!head) return tail;
@@ -8755,71 +10036,69 @@ literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
htype = nd_type(head);
if (htype == NODE_EVSTR) {
- NODE *node = NEW_DSTR(STR_NEW0());
- head = list_append(node, head);
+ head = new_dstr(p, head, loc);
htype = NODE_DSTR;
}
- if (heredoc_indent > 0) {
+ if (p->heredoc_indent > 0) {
switch (htype) {
case NODE_STR:
nd_set_type(head, NODE_DSTR);
case NODE_DSTR:
- return list_append(head, tail);
+ return list_append(p, head, tail);
default:
break;
}
}
switch (nd_type(tail)) {
case NODE_STR:
- if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
- nd_type(headlast) == NODE_STR) {
+ if ((lit = string_literal_head(htype, head)) != Qfalse) {
htype = NODE_STR;
- lit = headlast->nd_lit;
}
else {
lit = head->nd_lit;
}
if (htype == NODE_STR) {
- if (!literal_concat0(parser, lit, tail->nd_lit)) {
+ if (!literal_concat0(p, lit, tail->nd_lit)) {
error:
- rb_gc_force_recycle((VALUE)head);
- rb_gc_force_recycle((VALUE)tail);
+ rb_discard_node(p, head);
+ rb_discard_node(p, tail);
return 0;
}
- rb_gc_force_recycle((VALUE)tail);
+ rb_discard_node(p, tail);
}
else {
- list_append(head, tail);
+ list_append(p, head, tail);
}
break;
case NODE_DSTR:
if (htype == NODE_STR) {
- if (!literal_concat0(parser, head->nd_lit, tail->nd_lit))
+ if (!literal_concat0(p, head->nd_lit, tail->nd_lit))
goto error;
tail->nd_lit = head->nd_lit;
- rb_gc_force_recycle((VALUE)head);
+ rb_discard_node(p, head);
head = tail;
}
else if (NIL_P(tail->nd_lit)) {
append:
head->nd_alen += tail->nd_alen - 1;
- head->nd_next->nd_end->nd_next = tail->nd_next;
- head->nd_next->nd_end = tail->nd_next->nd_end;
- rb_gc_force_recycle((VALUE)tail);
- }
- else if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
- nd_type(headlast) == NODE_STR) {
- lit = headlast->nd_lit;
- if (!literal_concat0(parser, lit, tail->nd_lit))
+ if (!head->nd_next) {
+ head->nd_next = tail->nd_next;
+ }
+ else if (tail->nd_next) {
+ head->nd_next->nd_end->nd_next = tail->nd_next;
+ head->nd_next->nd_end = tail->nd_next->nd_end;
+ }
+ rb_discard_node(p, tail);
+ }
+ else if ((lit = string_literal_head(htype, head)) != Qfalse) {
+ if (!literal_concat0(p, lit, tail->nd_lit))
goto error;
tail->nd_lit = Qnil;
goto append;
}
else {
- nd_set_type(tail, NODE_ARRAY);
- tail->nd_head = NEW_STR(tail->nd_lit);
- list_concat(head, tail);
+ list_concat(head, NEW_NODE(NODE_LIST, NEW_STR(tail->nd_lit, loc), tail->nd_alen, tail->nd_next, loc));
}
break;
@@ -8828,95 +10107,139 @@ literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
nd_set_type(head, NODE_DSTR);
head->nd_alen = 1;
}
- list_append(head, tail);
+ list_append(p, head, tail);
break;
}
return head;
}
static NODE *
-evstr2dstr_gen(struct parser_params *parser, NODE *node)
+evstr2dstr(struct parser_params *p, NODE *node)
{
if (nd_type(node) == NODE_EVSTR) {
- node = list_append(NEW_DSTR(STR_NEW0()), node);
+ node = new_dstr(p, node, &node->nd_loc);
}
return node;
}
static NODE *
-new_evstr_gen(struct parser_params *parser, NODE *node)
+new_evstr(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
NODE *head = node;
if (node) {
switch (nd_type(node)) {
- case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
+ case NODE_STR:
+ nd_set_type(node, NODE_DSTR);
+ case NODE_DSTR: case NODE_EVSTR:
return node;
}
}
- return NEW_EVSTR(head);
+ return NEW_EVSTR(head, loc);
+}
+
+static NODE *
+new_dstr(struct parser_params *p, NODE *node, const YYLTYPE *loc)
+{
+ VALUE lit = STR_NEW0();
+ NODE *dstr = NEW_DSTR(lit, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, lit);
+ return list_append(p, dstr, node);
}
static NODE *
-call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1)
+call_bin_op(struct parser_params *p, NODE *recv, ID id, NODE *arg1,
+ const YYLTYPE *op_loc, const YYLTYPE *loc)
{
NODE *expr;
value_expr(recv);
value_expr(arg1);
- expr = NEW_OPCALL(recv, id, NEW_LIST(arg1));
- fixpos(expr, recv);
+ expr = NEW_OPCALL(recv, id, NEW_LIST(arg1, &arg1->nd_loc), loc);
+ nd_set_line(expr, op_loc->beg_pos.lineno);
return expr;
}
static NODE *
-call_uni_op_gen(struct parser_params *parser, NODE *recv, ID id)
+call_uni_op(struct parser_params *p, NODE *recv, ID id, const YYLTYPE *op_loc, const YYLTYPE *loc)
{
+ NODE *opcall;
value_expr(recv);
- return NEW_OPCALL(recv, id, 0);
+ opcall = NEW_OPCALL(recv, id, 0, loc);
+ nd_set_line(opcall, op_loc->beg_pos.lineno);
+ return opcall;
+}
+
+static NODE *
+new_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *args, const YYLTYPE *op_loc, const YYLTYPE *loc)
+{
+ NODE *qcall = NEW_QCALL(atype, recv, mid, args, loc);
+ nd_set_line(qcall, op_loc->beg_pos.lineno);
+ return qcall;
}
static NODE*
-match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
+new_command_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *args, NODE *block, const YYLTYPE *op_loc, const YYLTYPE *loc)
{
+ NODE *ret;
+ if (block) block_dup_check(p, args, block);
+ ret = new_qcall(p, atype, recv, mid, args, op_loc, loc);
+ if (block) ret = method_add_block(p, ret, block, loc);
+ fixpos(ret, recv);
+ return ret;
+}
+
+#define nd_once_body(node) (nd_type(node) == NODE_ONCE ? (node)->nd_body : node)
+static NODE*
+match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_loc, const YYLTYPE *loc)
+{
+ NODE *n;
+ int line = op_loc->beg_pos.lineno;
+
value_expr(node1);
value_expr(node2);
- if (node1) {
- switch (nd_type(node1)) {
+ if (node1 && (n = nd_once_body(node1)) != 0) {
+ switch (nd_type(n)) {
case NODE_DREGX:
- case NODE_DREGX_ONCE:
- return NEW_MATCH2(node1, node2);
+ {
+ NODE *match = NEW_MATCH2(node1, node2, loc);
+ nd_set_line(match, line);
+ return match;
+ }
case NODE_LIT:
- if (RB_TYPE_P(node1->nd_lit, T_REGEXP)) {
- const VALUE lit = node1->nd_lit;
- NODE *match = NEW_MATCH2(node1, node2);
- match->nd_args = reg_named_capture_assign(lit);
+ if (RB_TYPE_P(n->nd_lit, T_REGEXP)) {
+ const VALUE lit = n->nd_lit;
+ NODE *match = NEW_MATCH2(node1, node2, loc);
+ match->nd_args = reg_named_capture_assign(p, lit, loc);
+ nd_set_line(match, line);
return match;
}
}
}
- if (node2) {
- switch (nd_type(node2)) {
- case NODE_DREGX:
- case NODE_DREGX_ONCE:
- return NEW_MATCH3(node2, node1);
+ if (node2 && (n = nd_once_body(node2)) != 0) {
+ NODE *match3;
+ switch (nd_type(n)) {
case NODE_LIT:
- if (RB_TYPE_P(node2->nd_lit, T_REGEXP)) {
- return NEW_MATCH3(node2, node1);
- }
+ if (!RB_TYPE_P(n->nd_lit, T_REGEXP)) break;
+ /* fallthru */
+ case NODE_DREGX:
+ match3 = NEW_MATCH3(node2, node1, loc);
+ return match3;
}
}
- return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
+ n = NEW_CALL(node1, tMATCH, NEW_LIST(node2, &node2->nd_loc), loc);
+ nd_set_line(n, line);
+ return n;
}
# if WARN_PAST_SCOPE
static int
-past_dvar_p(struct parser_params *parser, ID id)
+past_dvar_p(struct parser_params *p, ID id)
{
- struct vtable *past = lvtbl->past;
+ struct vtable *past = p->lvtbl->past;
while (past) {
if (vtable_included(past, id)) return 1;
past = past->prev;
@@ -8925,69 +10248,130 @@ past_dvar_p(struct parser_params *parser, ID id)
}
# endif
+static int
+numparam_nested_p(struct parser_params *p)
+{
+ struct local_vars *local = p->lvtbl;
+ NODE *outer = local->numparam.outer;
+ NODE *inner = local->numparam.inner;
+ if (outer || inner) {
+ NODE *used = outer ? outer : inner;
+ compile_error(p, "numbered parameter is already used in\n"
+ "%s:%d: %s block here",
+ p->ruby_sourcefile, nd_line(used),
+ outer ? "outer" : "inner");
+ parser_show_error_line(p, &used->nd_loc);
+ return 1;
+ }
+ return 0;
+}
+
static NODE*
-gettable_gen(struct parser_params *parser, ID id)
+gettable(struct parser_params *p, ID id, const YYLTYPE *loc)
{
ID *vidp = NULL;
+ NODE *node;
switch (id) {
case keyword_self:
- return NEW_SELF();
+ return NEW_SELF(loc);
case keyword_nil:
- return NEW_NIL();
+ return NEW_NIL(loc);
case keyword_true:
- return NEW_TRUE();
+ return NEW_TRUE(loc);
case keyword_false:
- return NEW_FALSE();
+ return NEW_FALSE(loc);
case keyword__FILE__:
- return NEW_STR(rb_str_dup(ruby_sourcefile_string));
+ {
+ VALUE file = p->ruby_sourcefile_string;
+ if (NIL_P(file))
+ file = rb_str_new(0, 0);
+ else
+ file = rb_str_dup(file);
+ node = NEW_STR(file, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, file);
+ }
+ return node;
case keyword__LINE__:
- return NEW_LIT(INT2FIX(tokline));
+ return NEW_LIT(INT2FIX(p->tokline), loc);
case keyword__ENCODING__:
- return NEW_LIT(rb_enc_from_encoding(current_enc));
+ node = NEW_LIT(rb_enc_from_encoding(p->enc), loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit);
+ return node;
+
}
switch (id_type(id)) {
case ID_LOCAL:
- if (dyna_in_block() && dvar_defined_ref(id, vidp)) {
- if (id == current_arg) {
- rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
+ if (dyna_in_block(p) && dvar_defined_ref(p, id, &vidp)) {
+ if (NUMPARAM_ID_P(id) && numparam_nested_p(p)) return 0;
+ if (id == p->cur_arg) {
+ compile_error(p, "circular argument reference - %"PRIsWARN, rb_id2str(id));
+ return 0;
}
if (vidp) *vidp |= LVAR_USED;
- return NEW_DVAR(id);
+ node = NEW_DVAR(id, loc);
+ return node;
}
- if (local_id_ref(id, vidp)) {
- if (id == current_arg) {
- rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
+ if (local_id_ref(p, id, &vidp)) {
+ if (id == p->cur_arg) {
+ compile_error(p, "circular argument reference - %"PRIsWARN, rb_id2str(id));
+ return 0;
}
if (vidp) *vidp |= LVAR_USED;
- return NEW_LVAR(id);
+ node = NEW_LVAR(id, loc);
+ return node;
+ }
+ if (dyna_in_block(p) && NUMPARAM_ID_P(id) &&
+ parser_numbered_param(p, NUMPARAM_ID_TO_IDX(id))) {
+ if (numparam_nested_p(p)) return 0;
+ node = NEW_DVAR(id, loc);
+ struct local_vars *local = p->lvtbl;
+ if (!local->numparam.current) local->numparam.current = node;
+ return node;
}
# if WARN_PAST_SCOPE
- if (!in_defined && RTEST(ruby_verbose) && past_dvar_p(parser, id)) {
+ if (!p->ctxt.in_defined && RTEST(ruby_verbose) && past_dvar_p(p, id)) {
rb_warning1("possible reference to past scope - %"PRIsWARN, rb_id2str(id));
}
# endif
/* method call without arguments */
- return NEW_VCALL(id);
+ return NEW_VCALL(id, loc);
case ID_GLOBAL:
- return NEW_GVAR(id);
+ return NEW_GVAR(id, loc);
case ID_INSTANCE:
- return NEW_IVAR(id);
+ return NEW_IVAR(id, loc);
case ID_CONST:
- return NEW_CONST(id);
+ return NEW_CONST(id, loc);
case ID_CLASS:
- return NEW_CVAR(id);
+ return NEW_CVAR(id, loc);
}
- compile_error(PARSER_ARG "identifier %"PRIsVALUE" is not valid to get", rb_id2str(id));
+ compile_error(p, "identifier %"PRIsVALUE" is not valid to get", rb_id2str(id));
return 0;
}
static NODE *
+opt_arg_append(NODE *opt_list, NODE *opt)
+{
+ NODE *opts = opt_list;
+ opts->nd_loc.end_pos = opt->nd_loc.end_pos;
+
+ while (opts->nd_next) {
+ opts = opts->nd_next;
+ opts->nd_loc.end_pos = opt->nd_loc.end_pos;
+ }
+ opts->nd_next = opt;
+
+ return opt_list;
+}
+
+static NODE *
kwd_append(NODE *kwlist, NODE *kw)
{
if (kwlist) {
NODE *kws = kwlist;
+ kws->nd_loc.end_pos = kw->nd_loc.end_pos;
while (kws->nd_next) {
kws = kws->nd_next;
+ kws->nd_loc.end_pos = kw->nd_loc.end_pos;
}
kws->nd_next = kw;
}
@@ -8995,45 +10379,73 @@ kwd_append(NODE *kwlist, NODE *kw)
}
static NODE *
-new_regexp_gen(struct parser_params *parser, NODE *node, int options)
+new_defined(struct parser_params *p, NODE *expr, const YYLTYPE *loc)
+{
+ return NEW_DEFINED(remove_begin_all(expr), loc);
+}
+
+static NODE*
+symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol)
+{
+ enum node_type type = nd_type(symbol);
+ switch (type) {
+ case NODE_DSTR:
+ nd_set_type(symbol, NODE_DSYM);
+ break;
+ case NODE_STR:
+ nd_set_type(symbol, NODE_LIT);
+ RB_OBJ_WRITTEN(p->ast, Qnil, symbol->nd_lit = rb_str_intern(symbol->nd_lit));
+ break;
+ default:
+ compile_error(p, "unexpected node as symbol: %s", ruby_node_name(type));
+ }
+ return list_append(p, symbols, symbol);
+}
+
+static NODE *
+new_regexp(struct parser_params *p, NODE *node, int options, const YYLTYPE *loc)
{
NODE *list, *prev;
+ VALUE lit;
if (!node) {
- return NEW_LIT(reg_compile(STR_NEW0(), options));
+ node = NEW_LIT(reg_compile(p, STR_NEW0(), options), loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit);
+ return node;
}
switch (nd_type(node)) {
case NODE_STR:
{
VALUE src = node->nd_lit;
nd_set_type(node, NODE_LIT);
- node->nd_lit = reg_compile(src, options);
+ nd_set_loc(node, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = reg_compile(p, src, options));
}
break;
default:
- node = NEW_NODE(NODE_DSTR, STR_NEW0(), 1, NEW_LIST(node));
+ lit = STR_NEW0();
+ node = NEW_NODE(NODE_DSTR, lit, 1, NEW_LIST(node, loc), loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, lit);
+ /* fall through */
case NODE_DSTR:
- if (options & RE_OPTION_ONCE) {
- nd_set_type(node, NODE_DREGX_ONCE);
- }
- else {
- nd_set_type(node, NODE_DREGX);
- }
+ nd_set_type(node, NODE_DREGX);
+ nd_set_loc(node, loc);
node->nd_cflag = options & RE_OPTION_MASK;
- if (!NIL_P(node->nd_lit)) reg_fragment_check(node->nd_lit, options);
+ if (!NIL_P(node->nd_lit)) reg_fragment_check(p, node->nd_lit, options);
for (list = (prev = node)->nd_next; list; list = list->nd_next) {
- if (nd_type(list->nd_head) == NODE_STR) {
- VALUE tail = list->nd_head->nd_lit;
- if (reg_fragment_check(tail, options) && prev && !NIL_P(prev->nd_lit)) {
+ NODE *frag = list->nd_head;
+ enum node_type type = nd_type(frag);
+ if (type == NODE_STR || (type == NODE_DSTR && !frag->nd_next)) {
+ VALUE tail = frag->nd_lit;
+ if (reg_fragment_check(p, tail, options) && prev && !NIL_P(prev->nd_lit)) {
VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
- if (!literal_concat0(parser, lit, tail)) {
- node = 0;
- break;
+ if (!literal_concat0(p, lit, tail)) {
+ return NEW_NIL(loc); /* dummy node on error */
}
rb_str_resize(tail, 0);
prev->nd_next = list->nd_next;
- rb_gc_force_recycle((VALUE)list->nd_head);
- rb_gc_force_recycle((VALUE)list);
+ rb_discard_node(p, list->nd_head);
+ rb_discard_node(p, list);
list = prev;
}
else {
@@ -9047,7 +10459,10 @@ new_regexp_gen(struct parser_params *parser, NODE *node, int options)
if (!node->nd_next) {
VALUE src = node->nd_lit;
nd_set_type(node, NODE_LIT);
- node->nd_lit = reg_compile(src, options);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = reg_compile(p, src, options));
+ }
+ if (options & RE_OPTION_ONCE) {
+ node = NEW_NODE(NODE_ONCE, 0, node, 0, loc);
}
break;
}
@@ -9055,45 +10470,87 @@ new_regexp_gen(struct parser_params *parser, NODE *node, int options)
}
static NODE *
-new_xstring_gen(struct parser_params *parser, NODE *node)
+new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc)
+{
+ if (!k) return 0;
+ return NEW_KW_ARG(0, (k), loc);
+}
+
+static NODE *
+new_xstring(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
if (!node) {
- return NEW_XSTR(STR_NEW0());
+ VALUE lit = STR_NEW0();
+ NODE *xstr = NEW_XSTR(lit, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, lit);
+ return xstr;
}
switch (nd_type(node)) {
case NODE_STR:
nd_set_type(node, NODE_XSTR);
+ nd_set_loc(node, loc);
break;
case NODE_DSTR:
nd_set_type(node, NODE_DXSTR);
+ nd_set_loc(node, loc);
break;
default:
- node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node));
+ node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node, loc), loc);
break;
}
return node;
}
+
+static void
+check_literal_when(struct parser_params *p, NODE *arg, const YYLTYPE *loc)
+{
+ VALUE lit;
+
+ if (!arg || !p->case_labels) return;
+
+ lit = rb_node_case_when_optimizable_literal(arg);
+ if (lit == Qundef) return;
+ if (nd_type(arg) == NODE_STR) {
+ RB_OBJ_WRITTEN(p->ast, Qnil, arg->nd_lit = lit);
+ }
+
+ if (NIL_P(p->case_labels)) {
+ p->case_labels = rb_obj_hide(rb_hash_new());
+ }
+ else {
+ VALUE line = rb_hash_lookup(p->case_labels, lit);
+ if (!NIL_P(line)) {
+ rb_warning1("duplicated `when' clause with line %d is ignored",
+ WARN_IVAL(line));
+ return;
+ }
+ }
+ rb_hash_aset(p->case_labels, lit, INT2NUM(p->ruby_sourceline));
+}
+
#else /* !RIPPER */
static int
-id_is_var_gen(struct parser_params *parser, ID id)
+id_is_var(struct parser_params *p, ID id)
{
if (is_notop_id(id)) {
switch (id & ID_SCOPE_MASK) {
case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
return 1;
case ID_LOCAL:
- if (dyna_in_block() && dvar_defined(id)) return 1;
- if (local_id(id)) return 1;
+ if (dyna_in_block(p)) {
+ if (NUMPARAM_ID_P(id) || dvar_defined(p, id)) return 1;
+ }
+ if (local_id(p, id)) return 1;
/* method call without arguments */
return 0;
}
}
- compile_error(PARSER_ARG "identifier %"PRIsVALUE" is not valid to get", rb_id2str(id));
+ compile_error(p, "identifier %"PRIsVALUE" is not valid to get", rb_id2str(id));
return 0;
}
static VALUE
-new_regexp_gen(struct parser_params *parser, VALUE re, VALUE opt)
+new_regexp(struct parser_params *p, VALUE re, VALUE opt, const YYLTYPE *loc)
{
VALUE src = 0, err;
int options = 0;
@@ -9105,24 +10562,19 @@ new_regexp_gen(struct parser_params *parser, VALUE re, VALUE opt)
options = (int)RNODE(opt)->nd_tag;
opt = RNODE(opt)->nd_rval;
}
- if (src && NIL_P(parser_reg_compile(parser, src, options, &err))) {
- compile_error(PARSER_ARG "%"PRIsVALUE, err);
+ if (src && NIL_P(parser_reg_compile(p, src, options, &err))) {
+ compile_error(p, "%"PRIsVALUE, err);
}
return dispatch2(regexp_literal, re, opt);
}
-
-static VALUE
-new_xstring_gen(struct parser_params *parser, VALUE str)
-{
- return dispatch1(xstring_literal, str);
-}
#endif /* !RIPPER */
+
#ifndef RIPPER
-const char rb_parser_lex_state_names[][13] = {
- "EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
- "EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
- "EXPR_LABEL", "EXPR_LABELED","EXPR_FITEM",
+static const char rb_parser_lex_state_names[][8] = {
+ "BEG", "END", "ENDARG", "ENDFN", "ARG",
+ "CMDARG", "MID", "FNAME", "DOT", "CLASS",
+ "LABEL", "LABELED","FITEM",
};
static VALUE
@@ -9130,7 +10582,7 @@ append_lex_state_name(enum lex_state_e state, VALUE buf)
{
int i, sep = 0;
unsigned int mask = 1;
- static const char none[] = "EXPR_NONE";
+ static const char none[] = "NONE";
for (i = 0; i < EXPR_MAX_STATE; ++i, mask <<= 1) {
if ((unsigned)state & mask) {
@@ -9148,21 +10600,21 @@ append_lex_state_name(enum lex_state_e state, VALUE buf)
}
static void
-flush_debug_buffer(struct parser_params *parser, VALUE out, VALUE str)
+flush_debug_buffer(struct parser_params *p, VALUE out, VALUE str)
{
- VALUE mesg = parser->debug_buffer;
+ VALUE mesg = p->debug_buffer;
if (!NIL_P(mesg) && RSTRING_LEN(mesg)) {
- parser->debug_buffer = Qnil;
+ p->debug_buffer = Qnil;
rb_io_puts(1, &mesg, out);
}
if (!NIL_P(str) && RSTRING_LEN(str)) {
- rb_io_write(parser->debug_output, str);
+ rb_io_write(p->debug_output, str);
}
}
enum lex_state_e
-rb_parser_trace_lex_state(struct parser_params *parser, enum lex_state_e from,
+rb_parser_trace_lex_state(struct parser_params *p, enum lex_state_e from,
enum lex_state_e to, int line)
{
VALUE mesg;
@@ -9171,14 +10623,14 @@ rb_parser_trace_lex_state(struct parser_params *parser, enum lex_state_e from,
rb_str_cat_cstr(mesg, " -> ");
append_lex_state_name(to, mesg);
rb_str_catf(mesg, " at line %d\n", line);
- flush_debug_buffer(parser, parser->debug_output, mesg);
+ flush_debug_buffer(p, p->debug_output, mesg);
return to;
}
VALUE
rb_parser_lex_state_name(enum lex_state_e state)
{
- return append_lex_state_name(state, rb_str_new(0, 0));
+ return rb_fstring(append_lex_state_name(state, rb_str_new(0, 0)));
}
static void
@@ -9195,17 +10647,17 @@ append_bitstack_value(stack_type stack, VALUE mesg)
}
void
-rb_parser_show_bitstack(struct parser_params *parser, stack_type stack,
+rb_parser_show_bitstack(struct parser_params *p, stack_type stack,
const char *name, int line)
{
VALUE mesg = rb_sprintf("%s: ", name);
append_bitstack_value(stack, mesg);
rb_str_catf(mesg, " at line %d\n", line);
- flush_debug_buffer(parser, parser->debug_output, mesg);
+ flush_debug_buffer(p, p->debug_output, mesg);
}
void
-rb_parser_fatal(struct parser_params *parser, const char *fmt, ...)
+rb_parser_fatal(struct parser_params *p, const char *fmt, ...)
{
va_list ap;
VALUE mesg = rb_str_new_cstr("internal parser error: ");
@@ -9213,112 +10665,190 @@ rb_parser_fatal(struct parser_params *parser, const char *fmt, ...)
va_start(ap, fmt);
rb_str_vcatf(mesg, fmt, ap);
va_end(ap);
-#ifndef RIPPER
- parser_yyerror(parser, RSTRING_PTR(mesg));
+ parser_yyerror(p, NULL, RSTRING_PTR(mesg));
RB_GC_GUARD(mesg);
-#else
- dispatch1(parse_error, mesg);
- ripper_error();
-#endif /* !RIPPER */
mesg = rb_str_new(0, 0);
- append_lex_state_name(lex_state, mesg);
- compile_error(PARSER_ARG "lex_state: %"PRIsVALUE, mesg);
+ append_lex_state_name(p->lex.state, mesg);
+ compile_error(p, "lex.state: %"PRIsVALUE, mesg);
rb_str_resize(mesg, 0);
- append_bitstack_value(cond_stack, mesg);
- compile_error(PARSER_ARG "cond_stack: %"PRIsVALUE, mesg);
+ append_bitstack_value(p->cond_stack, mesg);
+ compile_error(p, "cond_stack: %"PRIsVALUE, mesg);
rb_str_resize(mesg, 0);
- append_bitstack_value(cmdarg_stack, mesg);
- compile_error(PARSER_ARG "cmdarg_stack: %"PRIsVALUE, mesg);
- if (parser->debug_output == rb_stdout)
- parser->debug_output = rb_stderr;
- yydebug = TRUE;
+ append_bitstack_value(p->cmdarg_stack, mesg);
+ compile_error(p, "cmdarg_stack: %"PRIsVALUE, mesg);
+ if (p->debug_output == rb_ractor_stdout())
+ p->debug_output = rb_ractor_stderr();
+ p->debug = TRUE;
+}
+
+YYLTYPE *
+rb_parser_set_location_from_strterm_heredoc(struct parser_params *p, rb_strterm_heredoc_t *here, YYLTYPE *yylloc)
+{
+ int sourceline = here->sourceline;
+ int beg_pos = (int)here->offset - here->quote
+ - (rb_strlen_lit("<<-") - !(here->func & STR_FUNC_INDENT));
+ int end_pos = (int)here->offset + here->length + here->quote;
+
+ yylloc->beg_pos.lineno = sourceline;
+ yylloc->beg_pos.column = beg_pos;
+ yylloc->end_pos.lineno = sourceline;
+ yylloc->end_pos.column = end_pos;
+ return yylloc;
+}
+
+YYLTYPE *
+rb_parser_set_location_of_none(struct parser_params *p, YYLTYPE *yylloc)
+{
+ yylloc->beg_pos.lineno = p->ruby_sourceline;
+ yylloc->beg_pos.column = (int)(p->lex.ptok - p->lex.pbeg);
+ yylloc->end_pos.lineno = p->ruby_sourceline;
+ yylloc->end_pos.column = (int)(p->lex.ptok - p->lex.pbeg);
+ return yylloc;
+}
+
+YYLTYPE *
+rb_parser_set_location(struct parser_params *p, YYLTYPE *yylloc)
+{
+ yylloc->beg_pos.lineno = p->ruby_sourceline;
+ yylloc->beg_pos.column = (int)(p->lex.ptok - p->lex.pbeg);
+ yylloc->end_pos.lineno = p->ruby_sourceline;
+ yylloc->end_pos.column = (int)(p->lex.pcur - p->lex.pbeg);
+ return yylloc;
}
#endif /* !RIPPER */
-#ifdef RIPPER
-static VALUE
-assignable_gen(struct parser_params *parser, VALUE lhs)
+static void
+parser_token_value_print(struct parser_params *p, enum yytokentype type, const YYSTYPE *valp)
+{
+ VALUE v;
+
+ switch (type) {
+ case tIDENTIFIER: case tFID: case tGVAR: case tIVAR:
+ case tCONSTANT: case tCVAR: case tLABEL: case tOP_ASGN:
+#ifndef RIPPER
+ v = rb_id2str(valp->id);
#else
-static NODE*
-assignable_gen(struct parser_params *parser, ID id, NODE *val)
+ v = valp->node->nd_rval;
#endif
-{
-#ifdef RIPPER
- ID id = get_id(lhs);
-# define assignable_result(x) (lhs)
-# define parser_yyerror(parser, x) (lhs = assign_error_gen(parser, lhs))
+ rb_parser_printf(p, "%"PRIsVALUE, v);
+ break;
+ case tINTEGER: case tFLOAT: case tRATIONAL: case tIMAGINARY:
+ case tSTRING_CONTENT: case tCHAR:
+#ifndef RIPPER
+ v = valp->node->nd_lit;
+#else
+ v = valp->val;
+#endif
+ rb_parser_printf(p, "%+"PRIsVALUE, v);
+ break;
+ case tNTH_REF:
+#ifndef RIPPER
+ rb_parser_printf(p, "$%ld", valp->node->nd_nth);
#else
-# define assignable_result(x) (x)
+ rb_parser_printf(p, "%"PRIsVALUE, valp->val);
#endif
- if (!id) return assignable_result(0);
+ break;
+ case tBACK_REF:
+#ifndef RIPPER
+ rb_parser_printf(p, "$%c", (int)valp->node->nd_nth);
+#else
+ rb_parser_printf(p, "%"PRIsVALUE, valp->val);
+#endif
+ break;
+ default:
+ break;
+ }
+}
+
+static int
+assignable0(struct parser_params *p, ID id, const char **err)
+{
+ if (!id) return -1;
switch (id) {
case keyword_self:
- yyerror("Can't change the value of self");
- goto error;
+ *err = "Can't change the value of self";
+ return -1;
case keyword_nil:
- yyerror("Can't assign to nil");
- goto error;
+ *err = "Can't assign to nil";
+ return -1;
case keyword_true:
- yyerror("Can't assign to true");
- goto error;
+ *err = "Can't assign to true";
+ return -1;
case keyword_false:
- yyerror("Can't assign to false");
- goto error;
+ *err = "Can't assign to false";
+ return -1;
case keyword__FILE__:
- yyerror("Can't assign to __FILE__");
- goto error;
+ *err = "Can't assign to __FILE__";
+ return -1;
case keyword__LINE__:
- yyerror("Can't assign to __LINE__");
- goto error;
+ *err = "Can't assign to __LINE__";
+ return -1;
case keyword__ENCODING__:
- yyerror("Can't assign to __ENCODING__");
- goto error;
+ *err = "Can't assign to __ENCODING__";
+ return -1;
}
switch (id_type(id)) {
case ID_LOCAL:
- if (dyna_in_block()) {
- if (dvar_curr(id)) {
- return assignable_result(NEW_DASGN_CURR(id, val));
- }
- else if (dvar_defined(id)) {
- return assignable_result(NEW_DASGN(id, val));
- }
- else if (local_id(id)) {
- return assignable_result(NEW_LASGN(id, val));
- }
- else {
- dyna_var(id);
- return assignable_result(NEW_DASGN_CURR(id, val));
+ if (dyna_in_block(p)) {
+ if (p->max_numparam > NO_PARAM && NUMPARAM_ID_P(id)) {
+ compile_error(p, "Can't assign to numbered parameter _%d",
+ NUMPARAM_ID_TO_IDX(id));
+ return -1;
}
+ if (dvar_curr(p, id)) return NODE_DASGN_CURR;
+ if (dvar_defined(p, id)) return NODE_DASGN;
+ if (local_id(p, id)) return NODE_LASGN;
+ dyna_var(p, id);
+ return NODE_DASGN_CURR;
}
else {
- if (!local_id(id)) {
- local_var(id);
- }
- return assignable_result(NEW_LASGN(id, val));
+ if (!local_id(p, id)) local_var(p, id);
+ return NODE_LASGN;
}
break;
- case ID_GLOBAL:
- return assignable_result(NEW_GASGN(id, val));
- case ID_INSTANCE:
- return assignable_result(NEW_IASGN(id, val));
+ case ID_GLOBAL: return NODE_GASGN;
+ case ID_INSTANCE: return NODE_IASGN;
case ID_CONST:
- if (!in_def && !in_single)
- return assignable_result(NEW_CDECL(id, val, 0));
- yyerror("dynamic constant assignment");
- break;
- case ID_CLASS:
- return assignable_result(NEW_CVASGN(id, val));
+ if (!p->ctxt.in_def) return NODE_CDECL;
+ *err = "dynamic constant assignment";
+ return -1;
+ case ID_CLASS: return NODE_CVASGN;
default:
- compile_error(PARSER_ARG "identifier %"PRIsVALUE" is not valid to set", rb_id2str(id));
+ compile_error(p, "identifier %"PRIsVALUE" is not valid to set", rb_id2str(id));
}
- error:
- return assignable_result(0);
-#undef assignable_result
-#undef parser_yyerror
+ return -1;
}
+#ifndef RIPPER
+static NODE*
+assignable(struct parser_params *p, ID id, NODE *val, const YYLTYPE *loc)
+{
+ const char *err = 0;
+ int node_type = assignable0(p, id, &err);
+ switch (node_type) {
+ case NODE_DASGN_CURR: return NEW_DASGN_CURR(id, val, loc);
+ case NODE_DASGN: return NEW_DASGN(id, val, loc);
+ case NODE_LASGN: return NEW_LASGN(id, val, loc);
+ case NODE_GASGN: return NEW_GASGN(id, val, loc);
+ case NODE_IASGN: return NEW_IASGN(id, val, loc);
+ case NODE_CDECL: return NEW_CDECL(id, val, 0, loc);
+ case NODE_CVASGN: return NEW_CVASGN(id, val, loc);
+ }
+ if (err) yyerror1(loc, err);
+ return NEW_BEGIN(0, loc);
+}
+#else
+static VALUE
+assignable(struct parser_params *p, VALUE lhs)
+{
+ const char *err = 0;
+ assignable0(p, get_id(lhs), &err);
+ if (err) lhs = assign_error(p, err, lhs);
+ return lhs;
+}
+#endif
+
static int
is_private_local_id(ID name)
{
@@ -9331,157 +10861,465 @@ is_private_local_id(ID name)
}
static int
-shadowing_lvar_0(struct parser_params *parser, ID name)
+shadowing_lvar_0(struct parser_params *p, ID name)
{
if (is_private_local_id(name)) return 1;
- if (dyna_in_block()) {
- if (dvar_curr(name)) {
- yyerror("duplicated argument name");
- }
- else if (dvar_defined(name) || local_id(name)) {
- rb_warning1("shadowing outer local variable - %"PRIsWARN, rb_id2str(name));
- vtable_add(lvtbl->vars, name);
- if (lvtbl->used) {
- vtable_add(lvtbl->used, (ID)ruby_sourceline | LVAR_USED);
+ if (dyna_in_block(p)) {
+ if (dvar_curr(p, name)) {
+ yyerror0("duplicated argument name");
+ }
+ else if (dvar_defined(p, name) || local_id(p, name)) {
+ vtable_add(p->lvtbl->vars, name);
+ if (p->lvtbl->used) {
+ vtable_add(p->lvtbl->used, (ID)p->ruby_sourceline | LVAR_USED);
}
return 0;
}
}
else {
- if (local_id(name)) {
- yyerror("duplicated argument name");
+ if (local_id(p, name)) {
+ yyerror0("duplicated argument name");
}
}
return 1;
}
static ID
-shadowing_lvar_gen(struct parser_params *parser, ID name)
+shadowing_lvar(struct parser_params *p, ID name)
{
- shadowing_lvar_0(parser, name);
+ shadowing_lvar_0(p, name);
return name;
}
static void
-new_bv_gen(struct parser_params *parser, ID name)
+new_bv(struct parser_params *p, ID name)
{
if (!name) return;
if (!is_local_id(name)) {
- compile_error(PARSER_ARG "invalid local variable - %"PRIsVALUE,
+ compile_error(p, "invalid local variable - %"PRIsVALUE,
rb_id2str(name));
return;
}
- if (!shadowing_lvar_0(parser, name)) return;
- dyna_var(name);
+ if (!shadowing_lvar_0(p, name)) return;
+ dyna_var(p, name);
}
#ifndef RIPPER
static NODE *
-aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
+aryset(struct parser_params *p, NODE *recv, NODE *idx, const YYLTYPE *loc)
{
- return NEW_ATTRASGN(recv, tASET, idx);
+ return NEW_ATTRASGN(recv, tASET, idx, loc);
}
static void
-block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
+block_dup_check(struct parser_params *p, NODE *node1, NODE *node2)
{
if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
- compile_error(PARSER_ARG "both block arg and actual block given");
+ compile_error(p, "both block arg and actual block given");
}
}
static NODE *
-attrset_gen(struct parser_params *parser, NODE *recv, ID atype, ID id)
+attrset(struct parser_params *p, NODE *recv, ID atype, ID id, const YYLTYPE *loc)
{
if (!CALL_Q_P(atype)) id = rb_id_attrset(id);
- return NEW_ATTRASGN(recv, id, 0);
+ return NEW_ATTRASGN(recv, id, 0, loc);
}
static void
-rb_backref_error_gen(struct parser_params *parser, NODE *node)
+rb_backref_error(struct parser_params *p, NODE *node)
{
switch (nd_type(node)) {
case NODE_NTH_REF:
- compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
+ compile_error(p, "Can't set variable $%ld", node->nd_nth);
break;
case NODE_BACK_REF:
- compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
+ compile_error(p, "Can't set variable $%c", (int)node->nd_nth);
break;
}
}
+#else
+static VALUE
+backref_error(struct parser_params *p, NODE *ref, VALUE expr)
+{
+ VALUE mesg = rb_str_new_cstr("Can't set variable ");
+ rb_str_append(mesg, ref->nd_cval);
+ return dispatch2(assign_error, mesg, expr);
+}
+#endif
+
+#ifndef RIPPER
+static NODE *
+arg_append(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *loc)
+{
+ if (!node1) return NEW_LIST(node2, &node2->nd_loc);
+ switch (nd_type(node1)) {
+ case NODE_LIST:
+ return list_append(p, node1, node2);
+ case NODE_BLOCK_PASS:
+ node1->nd_head = arg_append(p, node1->nd_head, node2, loc);
+ node1->nd_loc.end_pos = node1->nd_head->nd_loc.end_pos;
+ return node1;
+ case NODE_ARGSPUSH:
+ node1->nd_body = list_append(p, NEW_LIST(node1->nd_body, &node1->nd_body->nd_loc), node2);
+ node1->nd_loc.end_pos = node1->nd_body->nd_loc.end_pos;
+ nd_set_type(node1, NODE_ARGSCAT);
+ return node1;
+ case NODE_ARGSCAT:
+ if (nd_type(node1->nd_body) != NODE_LIST) break;
+ node1->nd_body = list_append(p, node1->nd_body, node2);
+ node1->nd_loc.end_pos = node1->nd_body->nd_loc.end_pos;
+ return node1;
+ }
+ return NEW_ARGSPUSH(node1, node2, loc);
+}
static NODE *
-arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
+arg_concat(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *loc)
{
if (!node2) return node1;
switch (nd_type(node1)) {
case NODE_BLOCK_PASS:
if (node1->nd_head)
- node1->nd_head = arg_concat(node1->nd_head, node2);
+ node1->nd_head = arg_concat(p, node1->nd_head, node2, loc);
else
- node1->nd_head = NEW_LIST(node2);
+ node1->nd_head = NEW_LIST(node2, loc);
return node1;
case NODE_ARGSPUSH:
- if (nd_type(node2) != NODE_ARRAY) break;
- node1->nd_body = list_concat(NEW_LIST(node1->nd_body), node2);
+ if (nd_type(node2) != NODE_LIST) break;
+ node1->nd_body = list_concat(NEW_LIST(node1->nd_body, loc), node2);
nd_set_type(node1, NODE_ARGSCAT);
return node1;
case NODE_ARGSCAT:
- if (nd_type(node2) != NODE_ARRAY ||
- nd_type(node1->nd_body) != NODE_ARRAY) break;
+ if (nd_type(node2) != NODE_LIST ||
+ nd_type(node1->nd_body) != NODE_LIST) break;
node1->nd_body = list_concat(node1->nd_body, node2);
return node1;
}
- return NEW_ARGSCAT(node1, node2);
+ return NEW_ARGSCAT(node1, node2, loc);
}
static NODE *
-arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
+last_arg_append(struct parser_params *p, NODE *args, NODE *last_arg, const YYLTYPE *loc)
{
- if (!node1) return NEW_LIST(node2);
- switch (nd_type(node1)) {
- case NODE_ARRAY:
- return list_append(node1, node2);
- case NODE_BLOCK_PASS:
- node1->nd_head = arg_append(node1->nd_head, node2);
- return node1;
- case NODE_ARGSPUSH:
- node1->nd_body = list_append(NEW_LIST(node1->nd_body), node2);
- nd_set_type(node1, NODE_ARGSCAT);
- return node1;
+ NODE *n1;
+ if ((n1 = splat_array(args)) != 0) {
+ return list_append(p, n1, last_arg);
}
- return NEW_ARGSPUSH(node1, node2);
+ return arg_append(p, args, last_arg, loc);
+}
+
+static NODE *
+rest_arg_append(struct parser_params *p, NODE *args, NODE *rest_arg, const YYLTYPE *loc)
+{
+ NODE *n1;
+ if ((nd_type(rest_arg) == NODE_LIST) && (n1 = splat_array(args)) != 0) {
+ return list_concat(n1, rest_arg);
+ }
+ return arg_concat(p, args, rest_arg, loc);
}
static NODE *
splat_array(NODE* node)
{
if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
- if (nd_type(node) == NODE_ARRAY) return node;
+ if (nd_type(node) == NODE_LIST) return node;
return 0;
}
+static void
+mark_lvar_used(struct parser_params *p, NODE *rhs)
+{
+ ID *vidp = NULL;
+ if (!rhs) return;
+ switch (nd_type(rhs)) {
+ case NODE_LASGN:
+ if (local_id_ref(p, rhs->nd_vid, &vidp)) {
+ if (vidp) *vidp |= LVAR_USED;
+ }
+ break;
+ case NODE_DASGN:
+ case NODE_DASGN_CURR:
+ if (dvar_defined_ref(p, rhs->nd_vid, &vidp)) {
+ if (vidp) *vidp |= LVAR_USED;
+ }
+ break;
+#if 0
+ case NODE_MASGN:
+ for (rhs = rhs->nd_head; rhs; rhs = rhs->nd_next) {
+ mark_lvar_used(p, rhs->nd_head);
+ }
+ break;
+#endif
+ }
+}
+
+static NODE *
+const_decl_path(struct parser_params *p, NODE **dest)
+{
+ NODE *n = *dest;
+ if (nd_type(n) != NODE_CALL) {
+ const YYLTYPE *loc = &n->nd_loc;
+ VALUE path;
+ if (n->nd_vid) {
+ path = rb_id2str(n->nd_vid);
+ }
+ else {
+ n = n->nd_else;
+ path = rb_ary_new();
+ for (; n && nd_type(n) == NODE_COLON2; n = n->nd_head) {
+ rb_ary_push(path, rb_id2str(n->nd_mid));
+ }
+ if (n && nd_type(n) == NODE_CONST) {
+ // Const::Name
+ rb_ary_push(path, rb_id2str(n->nd_vid));
+ }
+ else if (n && nd_type(n) == NODE_COLON3) {
+ // ::Const::Name
+ rb_ary_push(path, rb_str_new(0, 0));
+ }
+ else {
+ // expression::Name
+ rb_ary_push(path, rb_str_new_cstr("..."));
+ }
+ path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::"));
+ path = rb_fstring(path);
+ }
+ *dest = n = NEW_LIT(path, loc);
+ }
+ return n;
+}
+
+extern VALUE rb_mRubyVMFrozenCore;
+
+static NODE *
+make_shareable_node(struct parser_params *p, NODE *value, bool copy, const YYLTYPE *loc)
+{
+ NODE *fcore = NEW_LIT(rb_mRubyVMFrozenCore, loc);
+
+ if (copy) {
+ return NEW_CALL(fcore, rb_intern("make_shareable_copy"),
+ NEW_LIST(value, loc), loc);
+ }
+ else {
+ return NEW_CALL(fcore, rb_intern("make_shareable"),
+ NEW_LIST(value, loc), loc);
+ }
+}
+
+static NODE *
+ensure_shareable_node(struct parser_params *p, NODE **dest, NODE *value, const YYLTYPE *loc)
+{
+ NODE *fcore = NEW_LIT(rb_mRubyVMFrozenCore, loc);
+ NODE *args = NEW_LIST(value, loc);
+ args = list_append(p, args, const_decl_path(p, dest));
+ return NEW_CALL(fcore, rb_intern("ensure_shareable"), args, loc);
+}
+
+static int is_static_content(NODE *node);
+
+static VALUE
+shareable_literal_value(NODE *node)
+{
+ if (!node) return Qnil;
+ enum node_type type = nd_type(node);
+ switch (type) {
+ case NODE_TRUE:
+ return Qtrue;
+ case NODE_FALSE:
+ return Qfalse;
+ case NODE_NIL:
+ return Qnil;
+ case NODE_LIT:
+ return node->nd_lit;
+ default:
+ return Qundef;
+ }
+}
+
+#ifndef SHAREABLE_BARE_EXPRESSION
+#define SHAREABLE_BARE_EXPRESSION 1
+#endif
+
+static NODE *
+shareable_literal_constant(struct parser_params *p, enum shareability shareable,
+ NODE **dest, NODE *value, const YYLTYPE *loc, size_t level)
+{
+# define shareable_literal_constant_next(n) \
+ shareable_literal_constant(p, shareable, dest, (n), &(n)->nd_loc, level+1)
+ VALUE lit = Qnil;
+
+ if (!value) return 0;
+ enum node_type type = nd_type(value);
+ switch (type) {
+ case NODE_TRUE:
+ case NODE_FALSE:
+ case NODE_NIL:
+ case NODE_LIT:
+ return value;
+
+ case NODE_DSTR:
+ if (shareable == shareable_literal) {
+ value = NEW_CALL(value, idUMinus, 0, loc);
+ }
+ return value;
+
+ case NODE_STR:
+ lit = rb_fstring(value->nd_lit);
+ nd_set_type(value, NODE_LIT);
+ RB_OBJ_WRITE(p->ast, &value->nd_lit, lit);
+ return value;
+
+ case NODE_ZLIST:
+ lit = rb_ary_new();
+ OBJ_FREEZE_RAW(lit);
+ return NEW_LIT(lit, loc);
+
+ case NODE_LIST:
+ lit = rb_ary_new();
+ for (NODE *n = value; n; n = n->nd_next) {
+ NODE *elt = n->nd_head;
+ if (elt) {
+ elt = shareable_literal_constant_next(elt);
+ if (elt) {
+ n->nd_head = elt;
+ }
+ else if (RTEST(lit)) {
+ rb_ary_clear(lit);
+ lit = Qfalse;
+ }
+ }
+ if (RTEST(lit)) {
+ VALUE e = shareable_literal_value(elt);
+ if (e != Qundef) {
+ rb_ary_push(lit, e);
+ }
+ else {
+ rb_ary_clear(lit);
+ lit = Qnil; /* make shareable at runtime */
+ }
+ }
+ }
+ break;
+
+ case NODE_HASH:
+ if (!value->nd_brace) return 0;
+ lit = rb_hash_new();
+ for (NODE *n = value->nd_head; n; n = n->nd_next->nd_next) {
+ NODE *key = n->nd_head;
+ NODE *val = n->nd_next->nd_head;
+ if (key) {
+ key = shareable_literal_constant_next(key);
+ if (key) {
+ n->nd_head = key;
+ }
+ else if (RTEST(lit)) {
+ rb_hash_clear(lit);
+ lit = Qfalse;
+ }
+ }
+ if (val) {
+ val = shareable_literal_constant_next(val);
+ if (val) {
+ n->nd_next->nd_head = val;
+ }
+ else if (RTEST(lit)) {
+ rb_hash_clear(lit);
+ lit = Qfalse;
+ }
+ }
+ if (RTEST(lit)) {
+ VALUE k = shareable_literal_value(key);
+ VALUE v = shareable_literal_value(val);
+ if (k != Qundef && v != Qundef) {
+ rb_hash_aset(lit, k, v);
+ }
+ else {
+ rb_hash_clear(lit);
+ lit = Qnil; /* make shareable at runtime */
+ }
+ }
+ }
+ break;
+
+ default:
+ if (shareable == shareable_literal &&
+ (SHAREABLE_BARE_EXPRESSION || level > 0)) {
+ return ensure_shareable_node(p, dest, value, loc);
+ }
+ return 0;
+ }
+
+ /* Array or Hash */
+ if (!lit) return 0;
+ if (NIL_P(lit)) {
+ // if shareable_literal, all elements should have been ensured
+ // as shareable
+ value = make_shareable_node(p, value, false, loc);
+ }
+ else {
+ value = NEW_LIT(rb_ractor_make_shareable(lit), loc);
+ }
+
+ return value;
+# undef shareable_literal_constant_next
+}
+
static NODE *
-node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
+shareable_constant_value(struct parser_params *p, enum shareability shareable,
+ NODE *lhs, NODE *value, const YYLTYPE *loc)
+{
+ if (!value) return 0;
+ switch (shareable) {
+ case shareable_none:
+ return value;
+
+ case shareable_literal:
+ {
+ NODE *lit = shareable_literal_constant(p, shareable, &lhs, value, loc, 0);
+ if (lit) return lit;
+ return value;
+ }
+ break;
+
+ case shareable_copy:
+ case shareable_everything:
+ {
+ NODE *lit = shareable_literal_constant(p, shareable, &lhs, value, loc, 0);
+ if (lit) return lit;
+ return make_shareable_node(p, value, shareable == shareable_copy, loc);
+ }
+ break;
+
+ default:
+ UNREACHABLE_RETURN(0);
+ }
+}
+
+static NODE *
+node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, struct lex_context ctxt, const YYLTYPE *loc)
{
if (!lhs) return 0;
switch (nd_type(lhs)) {
+ case NODE_CDECL:
+ rhs = shareable_constant_value(p, ctxt.shareable_constant_value, lhs, rhs, loc);
+ /* fallthru */
+
case NODE_GASGN:
case NODE_IASGN:
- case NODE_IASGN2:
case NODE_LASGN:
case NODE_DASGN:
case NODE_DASGN_CURR:
case NODE_MASGN:
- case NODE_CDECL:
case NODE_CVASGN:
lhs->nd_value = rhs;
+ nd_set_loc(lhs, loc);
break;
case NODE_ATTRASGN:
- case NODE_CALL:
- lhs->nd_args = arg_append(lhs->nd_args, rhs);
+ lhs->nd_args = arg_append(p, lhs->nd_args, rhs, loc);
+ nd_set_loc(lhs, loc);
break;
default:
@@ -9492,10 +11330,10 @@ node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
return lhs;
}
-static int
-value_expr_gen(struct parser_params *parser, NODE *node)
+static NODE *
+value_expr_check(struct parser_params *p, NODE *node)
{
- int cond = 0;
+ NODE *void_node = 0, *vn;
if (!node) {
rb_warning0("empty expression");
@@ -9507,9 +11345,18 @@ value_expr_gen(struct parser_params *parser, NODE *node)
case NODE_NEXT:
case NODE_REDO:
case NODE_RETRY:
- if (!cond) yyerror("void value expression");
- /* or "control never reach"? */
- return FALSE;
+ return void_node ? void_node : node;
+
+ case NODE_CASE3:
+ if (!node->nd_body || nd_type(node->nd_body) != NODE_IN) {
+ compile_error(p, "unexpected node");
+ return NULL;
+ }
+ if (node->nd_body->nd_body) {
+ return NULL;
+ }
+ /* single line pattern matching */
+ return void_node ? void_node : node;
case NODE_BLOCK:
while (node->nd_next) {
@@ -9525,39 +11372,56 @@ value_expr_gen(struct parser_params *parser, NODE *node)
case NODE_IF:
case NODE_UNLESS:
if (!node->nd_body) {
- node = node->nd_else;
- break;
+ return NULL;
}
else if (!node->nd_else) {
- node = node->nd_body;
- break;
+ return NULL;
}
- if (!value_expr(node->nd_body)) return FALSE;
+ vn = value_expr_check(p, node->nd_body);
+ if (!vn) return NULL;
+ if (!void_node) void_node = vn;
node = node->nd_else;
break;
case NODE_AND:
case NODE_OR:
- cond = 1;
- node = node->nd_2nd;
+ node = node->nd_1st;
break;
+ case NODE_LASGN:
+ case NODE_DASGN:
+ case NODE_DASGN_CURR:
+ case NODE_MASGN:
+ mark_lvar_used(p, node);
+ return NULL;
+
default:
- return TRUE;
+ return NULL;
}
}
- return TRUE;
+ return NULL;
}
+static int
+value_expr_gen(struct parser_params *p, NODE *node)
+{
+ NODE *void_node = value_expr_check(p, node);
+ if (void_node) {
+ yyerror1(&void_node->nd_loc, "void value expression");
+ /* or "control never reach"? */
+ return FALSE;
+ }
+ return TRUE;
+}
static void
-void_expr_gen(struct parser_params *parser, NODE *node)
+void_expr(struct parser_params *p, NODE *node)
{
const char *useless = 0;
if (!RTEST(ruby_verbose)) return;
- if (!node) return;
+ if (!node || !(node = nd_once_body(node))) return;
switch (nd_type(node)) {
case NODE_OPCALL:
switch (node->nd_mid) {
@@ -9600,7 +11464,6 @@ void_expr_gen(struct parser_params *parser, NODE *node)
case NODE_STR:
case NODE_DSTR:
case NODE_DREGX:
- case NODE_DREGX_ONCE:
useless = "a literal";
break;
case NODE_COLON2:
@@ -9635,18 +11498,19 @@ void_expr_gen(struct parser_params *parser, NODE *node)
}
}
-static void
-void_stmts_gen(struct parser_params *parser, NODE *node)
+static NODE *
+void_stmts(struct parser_params *p, NODE *node)
{
- if (!RTEST(ruby_verbose)) return;
- if (!node) return;
- if (nd_type(node) != NODE_BLOCK) return;
+ NODE *const n = node;
+ if (!RTEST(ruby_verbose)) return n;
+ if (!node) return n;
+ if (nd_type(node) != NODE_BLOCK) return n;
- for (;;) {
- if (!node->nd_next) return;
- void_expr0(node->nd_head);
+ while (node->nd_next) {
+ void_expr(p, node->nd_head);
node = node->nd_next;
}
+ return n;
}
static NODE *
@@ -9670,18 +11534,18 @@ remove_begin_all(NODE *node)
}
static void
-reduce_nodes_gen(struct parser_params *parser, NODE **body)
+reduce_nodes(struct parser_params *p, NODE **body)
{
NODE *node = *body;
if (!node) {
- *body = NEW_NIL();
+ *body = NEW_NIL(&NULL_LOC);
return;
}
#define subnodes(n1, n2) \
((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
(!node->n2) ? (body = &node->n1, 1) : \
- (reduce_nodes(&node->n1), body = &node->n2, 1))
+ (reduce_nodes(p, &node->n1), body = &node->n2, 1))
while (node) {
int newline = (int)(node->flags & NODE_FL_NEWLINE);
@@ -9738,7 +11602,7 @@ is_static_content(NODE *node)
switch (nd_type(node)) {
case NODE_HASH:
if (!(node = node->nd_head)) break;
- case NODE_ARRAY:
+ case NODE_LIST:
do {
if (!is_static_content(node->nd_head)) return 0;
} while ((node = node->nd_next) != 0);
@@ -9747,7 +11611,7 @@ is_static_content(NODE *node)
case NODE_NIL:
case NODE_TRUE:
case NODE_FALSE:
- case NODE_ZARRAY:
+ case NODE_ZLIST:
break;
default:
return 0;
@@ -9756,7 +11620,7 @@ is_static_content(NODE *node)
}
static int
-assign_in_cond(struct parser_params *parser, NODE *node)
+assign_in_cond(struct parser_params *p, NODE *node)
{
switch (nd_type(node)) {
case NODE_MASGN:
@@ -9774,27 +11638,28 @@ assign_in_cond(struct parser_params *parser, NODE *node)
if (!node->nd_value) return 1;
if (is_static_content(node->nd_value)) {
/* reports always */
- parser_warn(node->nd_value, "found = in conditional, should be ==");
+ parser_warn(p, node->nd_value, "found `= literal' in conditional, should be ==");
}
return 1;
}
-static void
-warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
-{
- if (!e_option_supplied(parser)) parser_warn(node, str);
-}
+enum cond_type {
+ COND_IN_OP,
+ COND_IN_COND,
+ COND_IN_FF
+};
-static void
-warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
-{
- if (!e_option_supplied(parser)) parser_warning(node, str);
-}
+#define SWITCH_BY_COND_TYPE(t, w, arg) \
+ switch (t) { \
+ case COND_IN_OP: break; \
+ case COND_IN_COND: rb_##w##0(arg "literal in condition"); break; \
+ case COND_IN_FF: rb_##w##0(arg "literal in flip-flop"); break; \
+ }
-static NODE *cond0(struct parser_params*,NODE*,int);
+static NODE *cond0(struct parser_params*,NODE*,enum cond_type,const YYLTYPE*);
static NODE*
-range_op(struct parser_params *parser, NODE *node)
+range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
enum node_type type;
@@ -9803,86 +11668,61 @@ range_op(struct parser_params *parser, NODE *node)
type = nd_type(node);
value_expr(node);
if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
- warn_unless_e_option(parser, node, "integer literal in conditional range");
- return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."))));
+ if (!e_option_supplied(p)) parser_warn(p, node, "integer literal in flip-flop");
+ ID lineno = rb_intern("$.");
+ return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(lineno, loc), loc), loc);
}
- return cond0(parser, node, FALSE);
-}
-
-static int
-literal_node(NODE *node)
-{
- if (!node) return 1; /* same as NODE_NIL */
- switch (nd_type(node)) {
- case NODE_LIT:
- case NODE_STR:
- case NODE_DSTR:
- case NODE_EVSTR:
- case NODE_DREGX:
- case NODE_DREGX_ONCE:
- case NODE_DSYM:
- return 2;
- case NODE_TRUE:
- case NODE_FALSE:
- case NODE_NIL:
- return 1;
- }
- return 0;
+ return cond0(p, node, COND_IN_FF, loc);
}
static NODE*
-cond0(struct parser_params *parser, NODE *node, int method_op)
+cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *loc)
{
if (node == 0) return 0;
- assign_in_cond(parser, node);
+ if (!(node = nd_once_body(node))) return 0;
+ assign_in_cond(p, node);
switch (nd_type(node)) {
case NODE_DSTR:
case NODE_EVSTR:
case NODE_STR:
- if (!method_op) rb_warn0("string literal in condition");
+ SWITCH_BY_COND_TYPE(type, warn, "string ")
break;
case NODE_DREGX:
- case NODE_DREGX_ONCE:
- if (!method_op)
- warning_unless_e_option(parser, node, "regex literal in condition");
- return NEW_MATCH2(node, NEW_GVAR(idLASTLINE));
+ if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warning, "regex ")
+
+ return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc);
case NODE_AND:
case NODE_OR:
- node->nd_1st = cond0(parser, node->nd_1st, FALSE);
- node->nd_2nd = cond0(parser, node->nd_2nd, FALSE);
+ node->nd_1st = cond0(p, node->nd_1st, COND_IN_COND, loc);
+ node->nd_2nd = cond0(p, node->nd_2nd, COND_IN_COND, loc);
break;
case NODE_DOT2:
case NODE_DOT3:
- node->nd_beg = range_op(parser, node->nd_beg);
- node->nd_end = range_op(parser, node->nd_end);
+ node->nd_beg = range_op(p, node->nd_beg, loc);
+ node->nd_end = range_op(p, node->nd_end, loc);
if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
- if (!method_op && !e_option_supplied(parser)) {
- int b = literal_node(node->nd_beg);
- int e = literal_node(node->nd_end);
- if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
- parser_warn(node, "range literal in condition");
- }
- }
break;
case NODE_DSYM:
- if (!method_op) parser_warning(node, "literal in condition");
+ SWITCH_BY_COND_TYPE(type, warning, "string ")
break;
case NODE_LIT:
if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
- if (!method_op)
- warn_unless_e_option(parser, node, "regex literal in condition");
+ if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warn, "regex ")
nd_set_type(node, NODE_MATCH);
}
+ else if (node->nd_lit == Qtrue ||
+ node->nd_lit == Qfalse) {
+ /* booleans are OK, e.g., while true */
+ }
else {
- if (!method_op)
- parser_warning(node, "literal in condition");
+ SWITCH_BY_COND_TYPE(type, warning, "")
}
default:
break;
@@ -9891,57 +11731,78 @@ cond0(struct parser_params *parser, NODE *node, int method_op)
}
static NODE*
-cond_gen(struct parser_params *parser, NODE *node, int method_op)
+cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
if (node == 0) return 0;
- return cond0(parser, node, method_op);
+ return cond0(p, node, COND_IN_COND, loc);
+}
+
+static NODE*
+method_cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
+{
+ if (node == 0) return 0;
+ return cond0(p, node, COND_IN_OP, loc);
+}
+
+static NODE*
+new_nil_at(struct parser_params *p, const rb_code_position_t *pos)
+{
+ YYLTYPE loc = {*pos, *pos};
+ return NEW_NIL(&loc);
}
static NODE*
-new_if_gen(struct parser_params *parser, NODE *cc, NODE *left, NODE *right)
+new_if(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
{
if (!cc) return right;
- cc = cond0(parser, cc, FALSE);
- return newline_node(NEW_IF(cc, left, right));
+ cc = cond0(p, cc, COND_IN_COND, loc);
+ return newline_node(NEW_IF(cc, left, right, loc));
}
static NODE*
-new_unless_gen(struct parser_params *parser, NODE *cc, NODE *left, NODE *right)
+new_unless(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
{
if (!cc) return right;
- cc = cond0(parser, cc, FALSE);
- return newline_node(NEW_UNLESS(cc, left, right));
+ cc = cond0(p, cc, COND_IN_COND, loc);
+ return newline_node(NEW_UNLESS(cc, left, right, loc));
}
static NODE*
-logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right)
+logop(struct parser_params *p, ID id, NODE *left, NODE *right,
+ const YYLTYPE *op_loc, const YYLTYPE *loc)
{
+ enum node_type type = id == idAND || id == idANDOP ? NODE_AND : NODE_OR;
+ NODE *op;
value_expr(left);
if (left && (enum node_type)nd_type(left) == type) {
NODE *node = left, *second;
while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) {
node = second;
}
- node->nd_2nd = NEW_NODE(type, second, right, 0);
+ node->nd_2nd = NEW_NODE(type, second, right, 0, loc);
+ nd_set_line(node->nd_2nd, op_loc->beg_pos.lineno);
+ left->nd_loc.end_pos = loc->end_pos;
return left;
}
- return NEW_NODE(type, left, right, 0);
+ op = NEW_NODE(type, left, right, 0, loc);
+ nd_set_line(op, op_loc->beg_pos.lineno);
+ return op;
}
static void
-no_blockarg(struct parser_params *parser, NODE *node)
+no_blockarg(struct parser_params *p, NODE *node)
{
if (node && nd_type(node) == NODE_BLOCK_PASS) {
- compile_error(PARSER_ARG "block argument should not be given");
+ compile_error(p, "block argument should not be given");
}
}
static NODE *
-ret_args_gen(struct parser_params *parser, NODE *node)
+ret_args(struct parser_params *p, NODE *node)
{
if (node) {
- no_blockarg(parser, node);
- if (nd_type(node) == NODE_ARRAY) {
+ no_blockarg(p, node);
+ if (nd_type(node) == NODE_LIST) {
if (node->nd_next == 0) {
node = node->nd_head;
}
@@ -9954,43 +11815,46 @@ ret_args_gen(struct parser_params *parser, NODE *node)
}
static NODE *
-new_yield_gen(struct parser_params *parser, NODE *node)
+new_yield(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
- if (node) no_blockarg(parser, node);
+ if (node) no_blockarg(p, node);
- return NEW_YIELD(node);
+ return NEW_YIELD(node, loc);
}
static VALUE
-negate_lit_gen(struct parser_params *parser, VALUE lit)
+negate_lit(struct parser_params *p, VALUE lit)
{
- int type = TYPE(lit);
- switch (type) {
- case T_FIXNUM:
- lit = LONG2FIX(-FIX2LONG(lit));
- break;
+ if (FIXNUM_P(lit)) {
+ return LONG2FIX(-FIX2LONG(lit));
+ }
+ if (SPECIAL_CONST_P(lit)) {
+#if USE_FLONUM
+ if (FLONUM_P(lit)) {
+ return DBL2NUM(-RFLOAT_VALUE(lit));
+ }
+#endif
+ goto unknown;
+ }
+ switch (BUILTIN_TYPE(lit)) {
case T_BIGNUM:
BIGNUM_NEGATE(lit);
lit = rb_big_norm(lit);
break;
case T_RATIONAL:
- RRATIONAL_SET_NUM(lit, negate_lit(RRATIONAL(lit)->num));
+ RATIONAL_SET_NUM(lit, negate_lit(p, RRATIONAL(lit)->num));
break;
case T_COMPLEX:
- RCOMPLEX_SET_REAL(lit, negate_lit(RCOMPLEX(lit)->real));
- RCOMPLEX_SET_IMAG(lit, negate_lit(RCOMPLEX(lit)->imag));
+ RCOMPLEX_SET_REAL(lit, negate_lit(p, RCOMPLEX(lit)->real));
+ RCOMPLEX_SET_IMAG(lit, negate_lit(p, RCOMPLEX(lit)->imag));
break;
case T_FLOAT:
-#if USE_FLONUM
- if (FLONUM_P(lit)) {
- lit = DBL2NUM(-RFLOAT_VALUE(lit));
- break;
- }
-#endif
RFLOAT(lit)->float_value = -RFLOAT_VALUE(lit);
break;
+ unknown:
default:
- rb_parser_fatal(parser, "unknown literal type (%d) passed to negate_lit", type);
+ rb_parser_fatal(p, "unknown literal type (%s) passed to negate_lit",
+ rb_builtin_class_name(lit));
break;
}
return lit;
@@ -10000,123 +11864,270 @@ static NODE *
arg_blk_pass(NODE *node1, NODE *node2)
{
if (node2) {
+ if (!node1) return node2;
node2->nd_head = node1;
+ nd_set_first_lineno(node2, nd_first_lineno(node1));
+ nd_set_first_column(node2, nd_first_column(node1));
return node2;
}
return node1;
}
+static bool
+args_info_empty_p(struct rb_args_info *args)
+{
+ if (args->pre_args_num) return false;
+ if (args->post_args_num) return false;
+ if (args->rest_arg) return false;
+ if (args->opt_args) return false;
+ if (args->block_arg) return false;
+ if (args->kw_args) return false;
+ if (args->kw_rest_arg) return false;
+ return true;
+}
static NODE*
-new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, NODE *tail)
+new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, NODE *post_args, NODE *tail, const YYLTYPE *loc)
{
- int saved_line = ruby_sourceline;
+ int saved_line = p->ruby_sourceline;
struct rb_args_info *args = tail->nd_ainfo;
- args->pre_args_num = m ? rb_long2int(m->nd_plen) : 0;
- args->pre_init = m ? m->nd_next : 0;
+ args->pre_args_num = pre_args ? rb_long2int(pre_args->nd_plen) : 0;
+ args->pre_init = pre_args ? pre_args->nd_next : 0;
- args->post_args_num = p ? rb_long2int(p->nd_plen) : 0;
- args->post_init = p ? p->nd_next : 0;
- args->first_post_arg = p ? p->nd_pid : 0;
+ args->post_args_num = post_args ? rb_long2int(post_args->nd_plen) : 0;
+ args->post_init = post_args ? post_args->nd_next : 0;
+ args->first_post_arg = post_args ? post_args->nd_pid : 0;
- args->rest_arg = r;
+ args->rest_arg = rest_arg;
- args->opt_args = o;
+ args->opt_args = opt_args;
- ruby_sourceline = saved_line;
+ args->ruby2_keywords = rest_arg == idFWD_REST;
+
+ p->ruby_sourceline = saved_line;
+ nd_set_loc(tail, loc);
return tail;
}
static NODE*
-new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
+new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block, const YYLTYPE *kw_rest_loc)
{
- int saved_line = ruby_sourceline;
- struct rb_args_info *args;
+ int saved_line = p->ruby_sourceline;
NODE *node;
-
- args = ZALLOC(struct rb_args_info);
- node = NEW_NODE(NODE_ARGS, 0, 0, args);
- if (parser->error_p) return node;
-
- args->block_arg = b;
- args->kw_args = k;
-
- if (k) {
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ struct rb_args_info *args = ZALLOC(struct rb_args_info);
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, args);
+ args->imemo = tmpbuf;
+ node = NEW_NODE(NODE_ARGS, 0, 0, args, &NULL_LOC);
+ RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
+ if (p->error_p) return node;
+
+ args->block_arg = block;
+ args->kw_args = kw_args;
+
+ if (kw_args) {
/*
* def foo(k1: 1, kr1:, k2: 2, **krest, &b)
* variable order: k1, kr1, k2, &b, internal_id, krest
* #=> <reorder>
* variable order: kr1, k1, k2, internal_id, krest, &b
*/
- ID kw_bits;
- NODE *kwn = k;
- struct vtable *required_kw_vars = vtable_alloc(NULL);
- struct vtable *kw_vars = vtable_alloc(NULL);
- int i;
+ ID kw_bits = internal_id(p), *required_kw_vars, *kw_vars;
+ struct vtable *vtargs = p->lvtbl->args;
+ NODE *kwn = kw_args;
+ vtable_pop(vtargs, !!block + !!kw_rest_arg);
+ required_kw_vars = kw_vars = &vtargs->tbl[vtargs->pos];
while (kwn) {
- NODE *val_node = kwn->nd_body->nd_value;
- ID vid = kwn->nd_body->nd_vid;
+ if (!NODE_REQUIRED_KEYWORD_P(kwn->nd_body))
+ --kw_vars;
+ --required_kw_vars;
+ kwn = kwn->nd_next;
+ }
- if (val_node == (NODE *)-1) {
- vtable_add(required_kw_vars, vid);
+ for (kwn = kw_args; kwn; kwn = kwn->nd_next) {
+ ID vid = kwn->nd_body->nd_vid;
+ if (NODE_REQUIRED_KEYWORD_P(kwn->nd_body)) {
+ *required_kw_vars++ = vid;
}
else {
- vtable_add(kw_vars, vid);
+ *kw_vars++ = vid;
}
+ }
- kwn = kwn->nd_next;
+ arg_var(p, kw_bits);
+ if (kw_rest_arg) arg_var(p, kw_rest_arg);
+ if (block) arg_var(p, block);
+
+ args->kw_rest_arg = NEW_DVAR(kw_rest_arg, kw_rest_loc);
+ args->kw_rest_arg->nd_cflag = kw_bits;
+ }
+ else if (kw_rest_arg == idNil) {
+ args->no_kwarg = 1;
+ }
+ else if (kw_rest_arg) {
+ args->kw_rest_arg = NEW_DVAR(kw_rest_arg, kw_rest_loc);
+ }
+
+ p->ruby_sourceline = saved_line;
+ return node;
+}
+
+static NODE *
+args_with_numbered(struct parser_params *p, NODE *args, int max_numparam)
+{
+ if (max_numparam > NO_PARAM) {
+ if (!args) {
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ args = new_args_tail(p, 0, 0, 0, 0);
+ nd_set_loc(args, &loc);
}
+ args->nd_ainfo->pre_args_num = max_numparam;
+ }
+ return args;
+}
- kw_bits = internal_id();
- if (kr && is_junk_id(kr)) vtable_pop(lvtbl->args, 1);
- vtable_pop(lvtbl->args, vtable_size(required_kw_vars) + vtable_size(kw_vars) + (b != 0));
+static NODE*
+new_array_pattern(struct parser_params *p, NODE *constant, NODE *pre_arg, NODE *aryptn, const YYLTYPE *loc)
+{
+ struct rb_ary_pattern_info *apinfo = aryptn->nd_apinfo;
- for (i=0; i<vtable_size(required_kw_vars); i++) arg_var(required_kw_vars->tbl[i]);
- for (i=0; i<vtable_size(kw_vars); i++) arg_var(kw_vars->tbl[i]);
- vtable_free(required_kw_vars);
- vtable_free(kw_vars);
+ aryptn->nd_pconst = constant;
- arg_var(kw_bits);
- if (kr) arg_var(kr);
- if (b) arg_var(b);
+ if (pre_arg) {
+ NODE *pre_args = NEW_LIST(pre_arg, loc);
+ if (apinfo->pre_args) {
+ apinfo->pre_args = list_concat(pre_args, apinfo->pre_args);
+ }
+ else {
+ apinfo->pre_args = pre_args;
+ }
+ }
+ return aryptn;
+}
- args->kw_rest_arg = NEW_DVAR(kr);
- args->kw_rest_arg->nd_cflag = kw_bits;
+static NODE*
+new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID rest_arg, NODE *post_args, const YYLTYPE *loc)
+{
+ int saved_line = p->ruby_sourceline;
+ NODE *node;
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ struct rb_ary_pattern_info *apinfo = ZALLOC(struct rb_ary_pattern_info);
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, apinfo);
+ node = NEW_NODE(NODE_ARYPTN, 0, tmpbuf, apinfo, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
+
+ apinfo->pre_args = pre_args;
+
+ if (has_rest) {
+ if (rest_arg) {
+ apinfo->rest_arg = assignable(p, rest_arg, 0, loc);
+ }
+ else {
+ apinfo->rest_arg = NODE_SPECIAL_NO_NAME_REST;
+ }
+ }
+ else {
+ apinfo->rest_arg = NULL;
+ }
+
+ apinfo->post_args = post_args;
+
+ p->ruby_sourceline = saved_line;
+ return node;
+}
+
+static NODE*
+new_find_pattern(struct parser_params *p, NODE *constant, NODE *fndptn, const YYLTYPE *loc)
+{
+ fndptn->nd_pconst = constant;
+
+ return fndptn;
+}
+
+static NODE*
+new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID post_rest_arg, const YYLTYPE *loc)
+{
+ int saved_line = p->ruby_sourceline;
+ NODE *node;
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ struct rb_fnd_pattern_info *fpinfo = ZALLOC(struct rb_fnd_pattern_info);
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, fpinfo);
+ node = NEW_NODE(NODE_FNDPTN, 0, tmpbuf, fpinfo, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
+
+ fpinfo->pre_rest_arg = pre_rest_arg ? assignable(p, pre_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
+ fpinfo->args = args;
+ fpinfo->post_rest_arg = post_rest_arg ? assignable(p, post_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
+
+ p->ruby_sourceline = saved_line;
+ return node;
+}
+
+static NODE*
+new_hash_pattern(struct parser_params *p, NODE *constant, NODE *hshptn, const YYLTYPE *loc)
+{
+ hshptn->nd_pconst = constant;
+ return hshptn;
+}
+
+static NODE*
+new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, const YYLTYPE *loc)
+{
+ int saved_line = p->ruby_sourceline;
+ NODE *node, *kw_rest_arg_node;
+
+ if (kw_rest_arg == idNil) {
+ kw_rest_arg_node = NODE_SPECIAL_NO_REST_KEYWORD;
}
- else if (kr) {
- if (b) vtable_pop(lvtbl->args, 1); /* reorder */
- arg_var(kr);
- if (b) arg_var(b);
- args->kw_rest_arg = NEW_DVAR(kr);
+ else if (kw_rest_arg) {
+ kw_rest_arg_node = assignable(p, kw_rest_arg, 0, loc);
}
+ else {
+ kw_rest_arg_node = NULL;
+ }
+
+ node = NEW_NODE(NODE_HSHPTN, 0, kw_args, kw_rest_arg_node, loc);
- ruby_sourceline = saved_line;
+ p->ruby_sourceline = saved_line;
return node;
}
+static void
+warn_one_line_pattern_matching(struct parser_params *p, NODE *node, NODE *pattern, bool right_assign)
+{
+ enum node_type type;
+ type = nd_type(pattern);
+
+ if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL) &&
+ !(right_assign && (type == NODE_LASGN || type == NODE_DASGN || type == NODE_DASGN_CURR)))
+ rb_warn0L_experimental(nd_line(node), "One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!");
+}
+
static NODE*
-dsym_node_gen(struct parser_params *parser, NODE *node)
+dsym_node(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
VALUE lit;
if (!node) {
- return NEW_LIT(ID2SYM(idNULL));
+ return NEW_LIT(ID2SYM(idNULL), loc);
}
switch (nd_type(node)) {
case NODE_DSTR:
nd_set_type(node, NODE_DSYM);
+ nd_set_loc(node, loc);
break;
case NODE_STR:
lit = node->nd_lit;
- node->nd_lit = ID2SYM(rb_intern_str(lit));
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = ID2SYM(rb_intern_str(lit)));
nd_set_type(node, NODE_LIT);
+ nd_set_loc(node, loc);
break;
default:
- node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node));
+ node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node, loc), loc);
break;
}
return node;
@@ -10138,10 +12149,11 @@ append_literal_keys(st_data_t k, st_data_t v, st_data_t h)
}
static NODE *
-remove_duplicate_keys(struct parser_params *parser, NODE *hash)
+remove_duplicate_keys(struct parser_params *p, NODE *hash)
{
st_table *literal_keys = st_init_numtable_with_size(hash->nd_alen / 2);
NODE *result = 0;
+ rb_code_location_t loc = hash->nd_loc;
while (hash && hash->nd_head && hash->nd_next) {
NODE *head = hash->nd_head;
NODE *value = hash->nd_next;
@@ -10150,11 +12162,11 @@ remove_duplicate_keys(struct parser_params *parser, NODE *hash)
st_data_t data;
if (nd_type(head) == NODE_LIT &&
st_lookup(literal_keys, (key = head->nd_lit), &data)) {
- rb_compile_warn(ruby_sourcefile, nd_line((NODE *)data),
+ rb_compile_warn(p->ruby_sourcefile, nd_line((NODE *)data),
"key %+"PRIsVALUE" is duplicated and overwritten on line %d",
head->nd_lit, nd_line(head));
head = ((NODE *)data)->nd_next;
- head->nd_head = block_append(head->nd_head, value->nd_head);
+ head->nd_head = block_append(p, head->nd_head, value->nd_head);
}
else {
st_insert(literal_keys, (st_data_t)key, (st_data_t)hash);
@@ -10167,28 +12179,79 @@ remove_duplicate_keys(struct parser_params *parser, NODE *hash)
if (!result) result = hash;
else list_concat(result, hash);
}
+ result->nd_loc = loc;
return result;
}
static NODE *
-new_hash_gen(struct parser_params *parser, NODE *hash)
+new_hash(struct parser_params *p, NODE *hash, const YYLTYPE *loc)
+{
+ if (hash) hash = remove_duplicate_keys(p, hash);
+ return NEW_HASH(hash, loc);
+}
+#endif
+
+static void
+error_duplicate_pattern_variable(struct parser_params *p, ID id, const YYLTYPE *loc)
+{
+ if (is_private_local_id(id)) {
+ return;
+ }
+ if (st_is_member(p->pvtbl, id)) {
+ yyerror1(loc, "duplicated variable name");
+ }
+ else {
+ st_insert(p->pvtbl, (st_data_t)id, 0);
+ }
+}
+
+static void
+error_duplicate_pattern_key(struct parser_params *p, VALUE key, const YYLTYPE *loc)
+{
+ if (!p->pktbl) {
+ p->pktbl = st_init_numtable();
+ }
+ else if (st_is_member(p->pktbl, key)) {
+ yyerror1(loc, "duplicated key name");
+ return;
+ }
+ st_insert(p->pktbl, (st_data_t)key, 0);
+}
+
+#ifndef RIPPER
+static NODE *
+new_unique_key_hash(struct parser_params *p, NODE *hash, const YYLTYPE *loc)
{
- if (hash) hash = remove_duplicate_keys(parser, hash);
- return NEW_HASH(hash);
+ return NEW_HASH(hash, loc);
}
#endif /* !RIPPER */
#ifndef RIPPER
static NODE *
-new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
+new_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_context ctxt, const YYLTYPE *loc)
{
NODE *asgn;
if (lhs) {
ID vid = lhs->nd_vid;
+ YYLTYPE lhs_loc = lhs->nd_loc;
+ int shareable = ctxt.shareable_constant_value;
+ if (shareable) {
+ switch (nd_type(lhs)) {
+ case NODE_CDECL:
+ case NODE_COLON2:
+ case NODE_COLON3:
+ break;
+ default:
+ shareable = 0;
+ break;
+ }
+ }
if (op == tOROP) {
+ rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
lhs->nd_value = rhs;
- asgn = NEW_OP_ASGN_OR(gettable(vid), lhs);
+ nd_set_loc(lhs, loc);
+ asgn = NEW_OP_ASGN_OR(gettable(p, vid, &lhs_loc), lhs, loc);
if (is_notop_id(vid)) {
switch (id_type(vid)) {
case ID_GLOBAL:
@@ -10199,232 +12262,286 @@ new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
}
}
else if (op == tANDOP) {
+ if (shareable) {
+ rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
+ }
lhs->nd_value = rhs;
- asgn = NEW_OP_ASGN_AND(gettable(vid), lhs);
+ nd_set_loc(lhs, loc);
+ asgn = NEW_OP_ASGN_AND(gettable(p, vid, &lhs_loc), lhs, loc);
}
else {
asgn = lhs;
- asgn->nd_value = NEW_CALL(gettable(vid), op, NEW_LIST(rhs));
+ rhs = NEW_CALL(gettable(p, vid, &lhs_loc), op, NEW_LIST(rhs, &rhs->nd_loc), loc);
+ if (shareable) {
+ rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
+ }
+ asgn->nd_value = rhs;
+ nd_set_loc(asgn, loc);
}
}
else {
- asgn = NEW_BEGIN(0);
+ asgn = NEW_BEGIN(0, loc);
}
return asgn;
}
static NODE *
-new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs,
- ID atype, ID attr, ID op, NODE *rhs)
+new_ary_op_assign(struct parser_params *p, NODE *ary,
+ NODE *args, ID op, NODE *rhs, const YYLTYPE *args_loc, const YYLTYPE *loc)
{
NODE *asgn;
- if (op == tOROP) {
- op = 0;
+ args = make_list(args, args_loc);
+ if (nd_type(args) == NODE_BLOCK_PASS) {
+ args = NEW_ARGSCAT(args, rhs, loc);
}
- else if (op == tANDOP) {
- op = 1;
+ else {
+ args = arg_concat(p, args, rhs, loc);
}
- asgn = NEW_OP_ASGN2(lhs, CALL_Q_P(atype), attr, op, rhs);
+ asgn = NEW_OP_ASGN1(ary, op, args, loc);
+ fixpos(asgn, ary);
+ return asgn;
+}
+
+static NODE *
+new_attr_op_assign(struct parser_params *p, NODE *lhs,
+ ID atype, ID attr, ID op, NODE *rhs, const YYLTYPE *loc)
+{
+ NODE *asgn;
+
+ asgn = NEW_OP_ASGN2(lhs, CALL_Q_P(atype), attr, op, rhs, loc);
fixpos(asgn, lhs);
return asgn;
}
static NODE *
-new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
+new_const_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_context ctxt, const YYLTYPE *loc)
{
NODE *asgn;
- if (op == tOROP) {
- op = 0;
- }
- else if (op == tANDOP) {
- op = 1;
- }
if (lhs) {
- asgn = NEW_OP_CDECL(lhs, op, rhs);
+ rhs = shareable_constant_value(p, ctxt.shareable_constant_value, lhs, rhs, loc);
+ asgn = NEW_OP_CDECL(lhs, op, rhs, loc);
}
else {
- asgn = NEW_BEGIN(0);
+ asgn = NEW_BEGIN(0, loc);
}
fixpos(asgn, lhs);
return asgn;
}
static NODE *
-const_decl_gen(struct parser_params *parser, NODE *path)
+const_decl(struct parser_params *p, NODE *path, const YYLTYPE *loc)
{
- if (in_def || in_single) {
- yyerror("dynamic constant assignment");
+ if (p->ctxt.in_def) {
+ yyerror1(loc, "dynamic constant assignment");
}
- return NEW_CDECL(0, 0, (path));
+ return NEW_CDECL(0, 0, (path), loc);
}
#else
static VALUE
-new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs)
+const_decl(struct parser_params *p, VALUE path)
{
- return dispatch3(opassign, lhs, op, rhs);
-}
-
-static VALUE
-new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs)
-{
- VALUE recv = dispatch3(field, lhs, type, attr);
- return dispatch3(opassign, recv, op, rhs);
+ if (p->ctxt.in_def) {
+ path = assign_error(p, "dynamic constant assignment", path);
+ }
+ return path;
}
static VALUE
-new_qcall_gen(struct parser_params *parser, VALUE r, VALUE q, VALUE m, VALUE a)
+assign_error(struct parser_params *p, const char *mesg, VALUE a)
{
- VALUE ret = dispatch3(call, (r), (q), (m));
- return method_optarg(ret, (a));
+ a = dispatch2(assign_error, ERR_MESG(), a);
+ ripper_error(p);
+ return a;
}
static VALUE
-const_decl_gen(struct parser_params *parser, VALUE path)
+var_field(struct parser_params *p, VALUE a)
{
- if (in_def || in_single) {
- path = dispatch1(assign_error, path);
- ripper_error();
- }
- return path;
+ return ripper_new_yylval(p, get_id(a), dispatch1(var_field, a), 0);
}
+#endif
-static VALUE
-assign_error_gen(struct parser_params *parser, VALUE a)
+#ifndef RIPPER
+static NODE *
+new_bodystmt(struct parser_params *p, NODE *head, NODE *rescue, NODE *rescue_else, NODE *ensure, const YYLTYPE *loc)
{
- a = dispatch1(assign_error, a);
- ripper_error();
- return a;
-}
+ NODE *result = head;
+ if (rescue) {
+ NODE *tmp = rescue_else ? rescue_else : rescue;
+ YYLTYPE rescue_loc = code_loc_gen(&head->nd_loc, &tmp->nd_loc);
-static VALUE
-var_field_gen(struct parser_params *parser, VALUE a)
-{
- return ripper_new_yylval(get_id(a), dispatch1(var_field, a), 0);
+ result = NEW_RESCUE(head, rescue, rescue_else, &rescue_loc);
+ nd_set_line(result, rescue->nd_loc.beg_pos.lineno);
+ }
+ else if (rescue_else) {
+ result = block_append(p, result, rescue_else);
+ }
+ if (ensure) {
+ result = NEW_ENSURE(result, ensure, loc);
+ }
+ fixpos(result, head);
+ return result;
}
#endif
static void
-warn_unused_var(struct parser_params *parser, struct local_vars *local)
+warn_unused_var(struct parser_params *p, struct local_vars *local)
{
- int i, cnt;
- ID *v, *u;
+ int cnt;
if (!local->used) return;
- v = local->vars->tbl;
- u = local->used->tbl;
cnt = local->used->pos;
if (cnt != local->vars->pos) {
- rb_parser_fatal(parser, "local->used->pos != local->vars->pos");
+ rb_parser_fatal(p, "local->used->pos != local->vars->pos");
}
- for (i = 0; i < cnt; ++i) {
+#ifndef RIPPER
+ ID *v = local->vars->tbl;
+ ID *u = local->used->tbl;
+ for (int i = 0; i < cnt; ++i) {
if (!v[i] || (u[i] & LVAR_USED)) continue;
if (is_private_local_id(v[i])) continue;
rb_warn1L((int)u[i], "assigned but unused variable - %"PRIsWARN, rb_id2str(v[i]));
}
+#endif
}
static void
-local_push_gen(struct parser_params *parser, int inherit_dvars)
+local_push(struct parser_params *p, int toplevel_scope)
{
struct local_vars *local;
+ int inherits_dvars = toplevel_scope && compile_for_eval;
+ int warn_unused_vars = RTEST(ruby_verbose);
local = ALLOC(struct local_vars);
- local->prev = lvtbl;
+ local->prev = p->lvtbl;
local->args = vtable_alloc(0);
- local->vars = vtable_alloc(inherit_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
- local->used = !(inherit_dvars &&
- (ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
- RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
+ local->vars = vtable_alloc(inherits_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
+#ifndef RIPPER
+ if (toplevel_scope && compile_for_eval) warn_unused_vars = 0;
+ if (toplevel_scope && e_option_supplied(p)) warn_unused_vars = 0;
+ local->numparam.outer = 0;
+ local->numparam.inner = 0;
+ local->numparam.current = 0;
+#endif
+ local->used = warn_unused_vars ? vtable_alloc(0) : 0;
+
# if WARN_PAST_SCOPE
local->past = 0;
# endif
- local->cmdargs = cmdarg_stack;
- CMDARG_SET(0);
- lvtbl = local;
+ CMDARG_PUSH(0);
+ COND_PUSH(0);
+ p->lvtbl = local;
}
static void
-local_pop_gen(struct parser_params *parser)
+local_pop(struct parser_params *p)
{
- struct local_vars *local = lvtbl->prev;
- if (lvtbl->used) {
- warn_unused_var(parser, lvtbl);
- vtable_free(lvtbl->used);
+ struct local_vars *local = p->lvtbl->prev;
+ if (p->lvtbl->used) {
+ warn_unused_var(p, p->lvtbl);
+ vtable_free(p->lvtbl->used);
}
# if WARN_PAST_SCOPE
- while (lvtbl->past) {
- struct vtable *past = lvtbl->past;
- lvtbl->past = past->prev;
+ while (p->lvtbl->past) {
+ struct vtable *past = p->lvtbl->past;
+ p->lvtbl->past = past->prev;
vtable_free(past);
}
# endif
- vtable_free(lvtbl->args);
- vtable_free(lvtbl->vars);
- CMDARG_SET(lvtbl->cmdargs);
- xfree(lvtbl);
- lvtbl = local;
+ vtable_free(p->lvtbl->args);
+ vtable_free(p->lvtbl->vars);
+ CMDARG_POP();
+ COND_POP();
+ ruby_sized_xfree(p->lvtbl, sizeof(*p->lvtbl));
+ p->lvtbl = local;
}
#ifndef RIPPER
static ID*
-local_tbl_gen(struct parser_params *parser)
+local_tbl(struct parser_params *p)
{
- int cnt_args = vtable_size(lvtbl->args);
- int cnt_vars = vtable_size(lvtbl->vars);
+ int cnt_args = vtable_size(p->lvtbl->args);
+ int cnt_vars = vtable_size(p->lvtbl->vars);
int cnt = cnt_args + cnt_vars;
int i, j;
ID *buf;
if (cnt <= 0) return 0;
- buf = ALLOC_N(ID, cnt + 1);
- MEMCPY(buf+1, lvtbl->args->tbl, ID, cnt_args);
+ buf = ALLOC_N(ID, cnt + 2);
+ MEMCPY(buf+1, p->lvtbl->args->tbl, ID, cnt_args);
/* remove IDs duplicated to warn shadowing */
for (i = 0, j = cnt_args+1; i < cnt_vars; ++i) {
- ID id = lvtbl->vars->tbl[i];
- if (!vtable_included(lvtbl->args, id)) {
+ ID id = p->lvtbl->vars->tbl[i];
+ if (!vtable_included(p->lvtbl->args, id)) {
buf[j++] = id;
}
}
- if (--j < cnt) REALLOC_N(buf, ID, (cnt = j) + 1);
+ if (--j < cnt) {
+ REALLOC_N(buf, ID, (cnt = j) + 2);
+ }
buf[0] = cnt;
+ rb_ast_add_local_table(p->ast, buf);
+
return buf;
}
+
+static NODE*
+node_newnode_with_locals(struct parser_params *p, enum node_type type, VALUE a1, VALUE a2, const rb_code_location_t *loc)
+{
+ ID *a0;
+ NODE *n;
+
+ a0 = local_tbl(p);
+ n = NEW_NODE(type, a0, a1, a2, loc);
+ return n;
+}
+
#endif
static void
-arg_var_gen(struct parser_params *parser, ID id)
+numparam_name(struct parser_params *p, ID id)
+{
+ if (!NUMPARAM_ID_P(id)) return;
+ compile_error(p, "_%d is reserved for numbered parameter",
+ NUMPARAM_ID_TO_IDX(id));
+}
+
+static void
+arg_var(struct parser_params *p, ID id)
{
- vtable_add(lvtbl->args, id);
+ numparam_name(p, id);
+ vtable_add(p->lvtbl->args, id);
}
static void
-local_var_gen(struct parser_params *parser, ID id)
+local_var(struct parser_params *p, ID id)
{
- vtable_add(lvtbl->vars, id);
- if (lvtbl->used) {
- vtable_add(lvtbl->used, (ID)ruby_sourceline);
+ numparam_name(p, id);
+ vtable_add(p->lvtbl->vars, id);
+ if (p->lvtbl->used) {
+ vtable_add(p->lvtbl->used, (ID)p->ruby_sourceline);
}
}
static int
-local_id_gen(struct parser_params *parser, ID id, ID **vidrefp)
+local_id_ref(struct parser_params *p, ID id, ID **vidrefp)
{
struct vtable *vars, *args, *used;
- vars = lvtbl->vars;
- args = lvtbl->args;
- used = lvtbl->used;
+ vars = p->lvtbl->vars;
+ args = p->lvtbl->args;
+ used = p->lvtbl->used;
- while (vars && POINTER_P(vars->prev)) {
+ while (vars && !DVARS_TERMINAL_P(vars->prev)) {
vars = vars->prev;
args = args->prev;
if (used) used = used->prev;
}
if (vars && vars->prev == DVARS_INHERIT) {
- return rb_local_defined(id, parser->base_block);
+ return rb_local_defined(id, p->parent_iseq);
}
else if (vtable_included(args, id)) {
return 1;
@@ -10436,26 +12553,120 @@ local_id_gen(struct parser_params *parser, ID id, ID **vidrefp)
}
}
+static int
+local_id(struct parser_params *p, ID id)
+{
+ return local_id_ref(p, id, NULL);
+}
+
+static int
+check_forwarding_args(struct parser_params *p)
+{
+ if (local_id(p, idFWD_REST) &&
+#if idFWD_KWREST
+ local_id(p, idFWD_KWREST) &&
+#endif
+ local_id(p, idFWD_BLOCK)) return TRUE;
+ compile_error(p, "unexpected ...");
+ return FALSE;
+}
+
+static void
+add_forwarding_args(struct parser_params *p)
+{
+ arg_var(p, idFWD_REST);
+#if idFWD_KWREST
+ arg_var(p, idFWD_KWREST);
+#endif
+ arg_var(p, idFWD_BLOCK);
+}
+
+#ifndef RIPPER
+static NODE *
+new_args_forward_call(struct parser_params *p, NODE *leading, const YYLTYPE *loc, const YYLTYPE *argsloc)
+{
+ NODE *splat = NEW_SPLAT(NEW_LVAR(idFWD_REST, loc), loc);
+#if idFWD_KWREST
+ NODE *kwrest = list_append(p, NEW_LIST(0, loc), NEW_LVAR(idFWD_KWREST, loc));
+#endif
+ NODE *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, loc), loc);
+ NODE *args = leading ? rest_arg_append(p, leading, splat, argsloc) : splat;
+#if idFWD_KWREST
+ args = arg_append(p, splat, new_hash(p, kwrest, loc), loc);
+#endif
+ return arg_blk_pass(args, block);
+}
+
+static NODE *
+new_args_forward_def(struct parser_params *p, NODE *leading, const YYLTYPE *loc)
+{
+ NODE *n = new_args_tail(p, Qnone, idFWD_KWREST, idFWD_BLOCK, loc);
+ return new_args(p, leading, Qnone, idFWD_REST, Qnone, n, loc);
+}
+#endif
+
+static NODE *
+numparam_push(struct parser_params *p)
+{
+#ifndef RIPPER
+ struct local_vars *local = p->lvtbl;
+ NODE *inner = local->numparam.inner;
+ if (!local->numparam.outer) {
+ local->numparam.outer = local->numparam.current;
+ }
+ local->numparam.inner = 0;
+ local->numparam.current = 0;
+ return inner;
+#else
+ return 0;
+#endif
+}
+
+static void
+numparam_pop(struct parser_params *p, NODE *prev_inner)
+{
+#ifndef RIPPER
+ struct local_vars *local = p->lvtbl;
+ if (prev_inner) {
+ /* prefer first one */
+ local->numparam.inner = prev_inner;
+ }
+ else if (local->numparam.current) {
+ /* current and inner are exclusive */
+ local->numparam.inner = local->numparam.current;
+ }
+ if (p->max_numparam > NO_PARAM) {
+ /* current and outer are exclusive */
+ local->numparam.current = local->numparam.outer;
+ local->numparam.outer = 0;
+ }
+ else {
+ /* no numbered parameter */
+ local->numparam.current = 0;
+ }
+#endif
+}
+
static const struct vtable *
-dyna_push_gen(struct parser_params *parser)
+dyna_push(struct parser_params *p)
{
- lvtbl->args = vtable_alloc(lvtbl->args);
- lvtbl->vars = vtable_alloc(lvtbl->vars);
- if (lvtbl->used) {
- lvtbl->used = vtable_alloc(lvtbl->used);
+ p->lvtbl->args = vtable_alloc(p->lvtbl->args);
+ p->lvtbl->vars = vtable_alloc(p->lvtbl->vars);
+ if (p->lvtbl->used) {
+ p->lvtbl->used = vtable_alloc(p->lvtbl->used);
}
- return lvtbl->args;
+ return p->lvtbl->args;
}
static void
-dyna_pop_vtable(struct parser_params *parser, struct vtable **vtblp)
+dyna_pop_vtable(struct parser_params *p, struct vtable **vtblp)
{
struct vtable *tmp = *vtblp;
*vtblp = tmp->prev;
# if WARN_PAST_SCOPE
- if (parser->past_scope_enabled) {
- tmp->prev = lvtbl->past;
- lvtbl->past = tmp;
+ if (p->past_scope_enabled) {
+ tmp->prev = p->lvtbl->past;
+ p->lvtbl->past = tmp;
return;
}
# endif
@@ -10463,50 +12674,50 @@ dyna_pop_vtable(struct parser_params *parser, struct vtable **vtblp)
}
static void
-dyna_pop_1(struct parser_params *parser)
+dyna_pop_1(struct parser_params *p)
{
struct vtable *tmp;
- if ((tmp = lvtbl->used) != 0) {
- warn_unused_var(parser, lvtbl);
- lvtbl->used = lvtbl->used->prev;
+ if ((tmp = p->lvtbl->used) != 0) {
+ warn_unused_var(p, p->lvtbl);
+ p->lvtbl->used = p->lvtbl->used->prev;
vtable_free(tmp);
}
- dyna_pop_vtable(parser, &lvtbl->args);
- dyna_pop_vtable(parser, &lvtbl->vars);
+ dyna_pop_vtable(p, &p->lvtbl->args);
+ dyna_pop_vtable(p, &p->lvtbl->vars);
}
static void
-dyna_pop_gen(struct parser_params *parser, const struct vtable *lvargs)
+dyna_pop(struct parser_params *p, const struct vtable *lvargs)
{
- while (lvtbl->args != lvargs) {
- dyna_pop_1(parser);
- if (!lvtbl->args) {
- struct local_vars *local = lvtbl->prev;
- xfree(lvtbl);
- lvtbl = local;
+ while (p->lvtbl->args != lvargs) {
+ dyna_pop_1(p);
+ if (!p->lvtbl->args) {
+ struct local_vars *local = p->lvtbl->prev;
+ ruby_sized_xfree(p->lvtbl, sizeof(*p->lvtbl));
+ p->lvtbl = local;
}
}
- dyna_pop_1(parser);
+ dyna_pop_1(p);
}
static int
-dyna_in_block_gen(struct parser_params *parser)
+dyna_in_block(struct parser_params *p)
{
- return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
+ return !DVARS_TERMINAL_P(p->lvtbl->vars) && p->lvtbl->vars->prev != DVARS_TOPSCOPE;
}
static int
-dvar_defined_gen(struct parser_params *parser, ID id, ID **vidrefp)
+dvar_defined_ref(struct parser_params *p, ID id, ID **vidrefp)
{
struct vtable *vars, *args, *used;
int i;
- args = lvtbl->args;
- vars = lvtbl->vars;
- used = lvtbl->used;
+ args = p->lvtbl->args;
+ vars = p->lvtbl->vars;
+ used = p->lvtbl->used;
- while (POINTER_P(vars)) {
+ while (!DVARS_TERMINAL_P(vars)) {
if (vtable_included(args, id)) {
return 1;
}
@@ -10520,31 +12731,37 @@ dvar_defined_gen(struct parser_params *parser, ID id, ID **vidrefp)
if (used) used = used->prev;
}
- if (vars == DVARS_INHERIT) {
- return rb_dvar_defined(id, parser->base_block);
+ if (vars == DVARS_INHERIT && !NUMPARAM_ID_P(id)) {
+ return rb_dvar_defined(id, p->parent_iseq);
}
return 0;
}
static int
-dvar_curr_gen(struct parser_params *parser, ID id)
+dvar_defined(struct parser_params *p, ID id)
{
- return (vtable_included(lvtbl->args, id) ||
- vtable_included(lvtbl->vars, id));
+ return dvar_defined_ref(p, id, NULL);
+}
+
+static int
+dvar_curr(struct parser_params *p, ID id)
+{
+ return (vtable_included(p->lvtbl->args, id) ||
+ vtable_included(p->lvtbl->vars, id));
}
static void
-reg_fragment_enc_error(struct parser_params* parser, VALUE str, int c)
+reg_fragment_enc_error(struct parser_params* p, VALUE str, int c)
{
- compile_error(PARSER_ARG
+ compile_error(p,
"regexp encoding option '%c' differs from source encoding '%s'",
c, rb_enc_name(rb_enc_get(str)));
}
#ifndef RIPPER
int
-rb_reg_fragment_setenc(struct parser_params* parser, VALUE str, int options)
+rb_reg_fragment_setenc(struct parser_params* p, VALUE str, int options)
{
int c = RE_OPTION_ENCODING_IDX(options);
@@ -10565,7 +12782,7 @@ rb_reg_fragment_setenc(struct parser_params* parser, VALUE str, int options)
}
rb_enc_associate(str, rb_ascii8bit_encoding());
}
- else if (current_enc == rb_usascii_encoding()) {
+ else if (p->enc == rb_usascii_encoding()) {
if (rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
/* raise in re.c */
rb_enc_associate(str, rb_usascii_encoding());
@@ -10581,21 +12798,21 @@ rb_reg_fragment_setenc(struct parser_params* parser, VALUE str, int options)
}
static void
-reg_fragment_setenc_gen(struct parser_params* parser, VALUE str, int options)
+reg_fragment_setenc(struct parser_params* p, VALUE str, int options)
{
- int c = rb_reg_fragment_setenc(parser, str, options);
- if (c) reg_fragment_enc_error(parser, str, c);
+ int c = rb_reg_fragment_setenc(p, str, options);
+ if (c) reg_fragment_enc_error(p, str, c);
}
static int
-reg_fragment_check_gen(struct parser_params* parser, VALUE str, int options)
+reg_fragment_check(struct parser_params* p, VALUE str, int options)
{
VALUE err;
- reg_fragment_setenc(str, options);
+ reg_fragment_setenc(p, str, options);
err = rb_reg_check_preprocess(str);
if (err != Qnil) {
err = rb_obj_as_string(err);
- compile_error(PARSER_ARG "%"PRIsVALUE, err);
+ compile_error(p, "%"PRIsVALUE, err);
return 0;
}
return 1;
@@ -10605,6 +12822,7 @@ typedef struct {
struct parser_params* parser;
rb_encoding *enc;
NODE *succ_block;
+ const YYLTYPE *loc;
} reg_named_capture_assign_t;
static int
@@ -10612,35 +12830,38 @@ reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
int back_num, int *back_refs, OnigRegex regex, void *arg0)
{
reg_named_capture_assign_t *arg = (reg_named_capture_assign_t*)arg0;
- struct parser_params* parser = arg->parser;
+ struct parser_params* p = arg->parser;
rb_encoding *enc = arg->enc;
long len = name_end - name;
const char *s = (const char *)name;
ID var;
NODE *node, *succ;
- if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
- (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
- !rb_enc_symname2_p(s, len, enc)) {
+ if (!len) return ST_CONTINUE;
+ if (rb_enc_symname_type(s, len, enc, (1U<<ID_LOCAL)) != ID_LOCAL)
return ST_CONTINUE;
- }
+
var = intern_cstr(s, len, enc);
- node = node_assign(assignable(var, 0), NEW_LIT(ID2SYM(var)));
+ if (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) {
+ if (!lvar_defined(p, var)) return ST_CONTINUE;
+ }
+ node = node_assign(p, assignable(p, var, 0, arg->loc), NEW_LIT(ID2SYM(var), arg->loc), NO_LEX_CTXT, arg->loc);
succ = arg->succ_block;
- if (!succ) succ = NEW_BEGIN(0);
- succ = block_append(succ, node);
+ if (!succ) succ = NEW_BEGIN(0, arg->loc);
+ succ = block_append(p, succ, node);
arg->succ_block = succ;
return ST_CONTINUE;
}
static NODE *
-reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp)
+reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc)
{
reg_named_capture_assign_t arg;
- arg.parser = parser;
+ arg.parser = p;
arg.enc = rb_enc_get(regexp);
arg.succ_block = 0;
+ arg.loc = loc;
onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
if (!arg.succ_block) return 0;
@@ -10648,43 +12869,44 @@ reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp)
}
static VALUE
-parser_reg_compile(struct parser_params* parser, VALUE str, int options)
+parser_reg_compile(struct parser_params* p, VALUE str, int options)
{
- reg_fragment_setenc(str, options);
- return rb_parser_reg_compile(parser, str, options);
+ reg_fragment_setenc(p, str, options);
+ return rb_parser_reg_compile(p, str, options);
}
VALUE
-rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options)
+rb_parser_reg_compile(struct parser_params* p, VALUE str, int options)
{
- return rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
+ return rb_reg_compile(str, options & RE_OPTION_MASK, p->ruby_sourcefile, p->ruby_sourceline);
}
static VALUE
-reg_compile_gen(struct parser_params* parser, VALUE str, int options)
+reg_compile(struct parser_params* p, VALUE str, int options)
{
VALUE re;
VALUE err;
err = rb_errinfo();
- re = parser_reg_compile(parser, str, options);
+ re = parser_reg_compile(p, str, options);
if (NIL_P(re)) {
VALUE m = rb_attr_get(rb_errinfo(), idMesg);
rb_set_errinfo(err);
- compile_error(PARSER_ARG "%"PRIsVALUE, m);
+ compile_error(p, "%"PRIsVALUE, m);
return Qnil;
}
return re;
}
#else
static VALUE
-parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALUE *errmsg)
+parser_reg_compile(struct parser_params* p, VALUE str, int options, VALUE *errmsg)
{
VALUE err = rb_errinfo();
VALUE re;
- int c = rb_reg_fragment_setenc(parser, str, options);
- if (c) reg_fragment_enc_error(parser, str, c);
- re = rb_parser_reg_compile(parser, str, options);
+ str = ripper_is_node_yylval(str) ? RNODE(str)->nd_cval : str;
+ int c = rb_reg_fragment_setenc(p, str, options);
+ if (c) reg_fragment_enc_error(p, str, c);
+ re = rb_parser_reg_compile(p, str, options);
if (NIL_P(re)) {
*errmsg = rb_attr_get(rb_errinfo(), idMesg);
rb_set_errinfo(err);
@@ -10694,77 +12916,51 @@ parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALUE *
#endif
#ifndef RIPPER
-NODE*
-rb_parser_append_print(VALUE vparser, NODE *node)
+void
+rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
{
- NODE *prelude = 0;
- NODE *scope = node;
- struct parser_params *parser;
-
- if (!node) return node;
-
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
-
- node = node->nd_body;
-
- if (nd_type(node) == NODE_PRELUDE) {
- prelude = node;
- node = node->nd_body;
- }
-
- node = block_append(node,
- NEW_FCALL(rb_intern("print"),
- NEW_ARRAY(NEW_GVAR(idLASTLINE))));
- if (prelude) {
- prelude->nd_body = node;
- scope->nd_body = prelude;
- }
- else {
- scope->nd_body = node;
- }
-
- return scope;
+ struct parser_params *p;
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+ p->do_print = print;
+ p->do_loop = loop;
+ p->do_chomp = chomp;
+ p->do_split = split;
}
-NODE *
-rb_parser_while_loop(VALUE vparser, NODE *node, int chomp, int split)
+static NODE *
+parser_append_options(struct parser_params *p, NODE *node)
{
- NODE *prelude = 0;
- NODE *scope = node;
- struct parser_params *parser;
-
- if (!node) return node;
-
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
+ static const YYLTYPE default_location = {{1, 0}, {1, 0}};
+ const YYLTYPE *const LOC = &default_location;
- node = node->nd_body;
-
- if (nd_type(node) == NODE_PRELUDE) {
- prelude = node;
- node = node->nd_body;
- }
- if (split) {
- node = block_append(NEW_GASGN(rb_intern("$F"),
- NEW_CALL(NEW_GVAR(idLASTLINE),
- rb_intern("split"), 0)),
- node);
- }
- if (chomp) {
- node = block_append(NEW_CALL(NEW_GVAR(idLASTLINE),
- rb_intern("chomp!"), 0), node);
+ if (p->do_print) {
+ NODE *print = NEW_FCALL(rb_intern("print"),
+ NEW_LIST(NEW_GVAR(idLASTLINE, LOC), LOC),
+ LOC);
+ node = block_append(p, node, print);
}
- node = NEW_OPT_N(node);
+ if (p->do_loop) {
+ if (p->do_split) {
+ ID ifs = rb_intern("$;");
+ ID fields = rb_intern("$F");
+ NODE *args = NEW_LIST(NEW_GVAR(ifs, LOC), LOC);
+ NODE *split = NEW_GASGN(fields,
+ NEW_CALL(NEW_GVAR(idLASTLINE, LOC),
+ rb_intern("split"), args, LOC),
+ LOC);
+ node = block_append(p, split, node);
+ }
+ if (p->do_chomp) {
+ NODE *chomp = NEW_CALL(NEW_GVAR(idLASTLINE, LOC),
+ rb_intern("chomp!"), 0, LOC);
+ node = block_append(p, chomp, node);
+ }
- if (prelude) {
- prelude->nd_body = node;
- scope->nd_body = prelude;
- }
- else {
- scope->nd_body = node;
+ node = NEW_WHILE(NEW_VCALL(idGets, LOC), node, 1, LOC);
}
- return scope;
+ return node;
}
void
@@ -10774,32 +12970,35 @@ rb_init_parse(void)
(void)nodetype;
(void)nodeline;
}
-#endif /* !RIPPER */
static ID
-internal_id_gen(struct parser_params *parser)
+internal_id(struct parser_params *p)
{
- ID id = (ID)vtable_size(lvtbl->args) + (ID)vtable_size(lvtbl->vars);
- id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
+ const ID max_id = RB_ID_SERIAL_MAX & ~0xffff;
+ ID id = (ID)vtable_size(p->lvtbl->args) + (ID)vtable_size(p->lvtbl->vars);
+ id = max_id - id;
return ID_STATIC_SYM | ID_INTERNAL | (id << ID_SCOPE_SHIFT);
}
+#endif /* !RIPPER */
static void
-parser_initialize(struct parser_params *parser)
+parser_initialize(struct parser_params *p)
{
/* note: we rely on TypedData_Make_Struct to set most fields to 0 */
- command_start = TRUE;
- ruby_sourcefile_string = Qnil;
+ p->command_start = TRUE;
+ p->ruby_sourcefile_string = Qnil;
+ p->lex.lpar_beg = -1; /* make lambda_beginning_p() == FALSE at first */
+ p->node_id = 0;
#ifdef RIPPER
- parser->delayed = Qnil;
- parser->result = Qnil;
- parser->parsing_thread = Qnil;
+ p->delayed.token = Qnil;
+ p->result = Qnil;
+ p->parsing_thread = Qnil;
#else
- parser->error_buffer = Qfalse;
+ p->error_buffer = Qfalse;
#endif
- parser->debug_buffer = Qnil;
- parser->debug_output = rb_stdout;
- parser->enc = rb_utf8_encoding();
+ p->debug_buffer = Qnil;
+ p->debug_output = rb_ractor_stdout();
+ p->enc = rb_utf8_encoding();
}
#ifdef RIPPER
@@ -10810,50 +13009,51 @@ parser_initialize(struct parser_params *parser)
static void
parser_mark(void *ptr)
{
- struct parser_params *parser = (struct parser_params*)ptr;
+ struct parser_params *p = (struct parser_params*)ptr;
- rb_gc_mark((VALUE)lex_strterm);
- rb_gc_mark(lex_input);
- rb_gc_mark(lex_lastline);
- rb_gc_mark(lex_nextline);
- rb_gc_mark(ruby_sourcefile_string);
+ rb_gc_mark(p->lex.input);
+ rb_gc_mark(p->lex.prevline);
+ rb_gc_mark(p->lex.lastline);
+ rb_gc_mark(p->lex.nextline);
+ rb_gc_mark(p->ruby_sourcefile_string);
+ rb_gc_mark((VALUE)p->lex.strterm);
+ rb_gc_mark((VALUE)p->ast);
+ rb_gc_mark(p->case_labels);
#ifndef RIPPER
- rb_gc_mark((VALUE)ruby_eval_tree_begin);
- rb_gc_mark((VALUE)ruby_eval_tree);
- rb_gc_mark(ruby_debug_lines);
- rb_gc_mark(parser->compile_option);
- rb_gc_mark(parser->error_buffer);
+ rb_gc_mark(p->debug_lines);
+ rb_gc_mark(p->compile_option);
+ rb_gc_mark(p->error_buffer);
#else
- rb_gc_mark(parser->delayed);
- rb_gc_mark(parser->value);
- rb_gc_mark(parser->result);
- rb_gc_mark(parser->parsing_thread);
+ rb_gc_mark(p->delayed.token);
+ rb_gc_mark(p->value);
+ rb_gc_mark(p->result);
+ rb_gc_mark(p->parsing_thread);
#endif
- rb_gc_mark(parser->debug_buffer);
- rb_gc_mark(parser->debug_output);
+ rb_gc_mark(p->debug_buffer);
+ rb_gc_mark(p->debug_output);
#ifdef YYMALLOC
- rb_gc_mark((VALUE)parser->heap);
+ rb_gc_mark((VALUE)p->heap);
#endif
}
static void
parser_free(void *ptr)
{
- struct parser_params *parser = (struct parser_params*)ptr;
+ struct parser_params *p = (struct parser_params*)ptr;
struct local_vars *local, *prev;
- if (tokenbuf) {
- xfree(tokenbuf);
+ if (p->tokenbuf) {
+ ruby_sized_xfree(p->tokenbuf, p->toksiz);
}
- for (local = lvtbl; local; local = prev) {
+ for (local = p->lvtbl; local; local = prev) {
if (local->vars) xfree(local->vars);
prev = local->prev;
xfree(local);
}
{
token_info *ptinfo;
- while ((ptinfo = parser->token_info) != 0) {
- parser->token_info = ptinfo->next;
+ while ((ptinfo = p->token_info) != 0) {
+ p->token_info = ptinfo->next;
xfree(ptinfo);
}
}
@@ -10863,12 +13063,12 @@ parser_free(void *ptr)
static size_t
parser_memsize(const void *ptr)
{
- struct parser_params *parser = (struct parser_params*)ptr;
+ struct parser_params *p = (struct parser_params*)ptr;
struct local_vars *local;
- size_t size = sizeof(*parser);
+ size_t size = sizeof(*p);
- size += toksiz;
- for (local = lvtbl; local; local = local->prev) {
+ size += p->toksiz;
+ for (local = p->lvtbl; local; local = local->prev) {
size += sizeof(*local);
if (local->vars) size += local->vars->capa * sizeof(ID);
}
@@ -10909,14 +13109,13 @@ rb_parser_new(void)
}
VALUE
-rb_parser_set_context(VALUE vparser, const struct rb_block *base, int main)
+rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
- parser->error_buffer = main ? Qfalse : Qnil;
- parser->base_block = base;
- in_main = main;
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+ p->error_buffer = main ? Qfalse : Qnil;
+ p->parent_iseq = base;
return vparser;
}
#endif
@@ -10926,10 +13125,14 @@ rb_parser_set_context(VALUE vparser, const struct rb_block *base, int main)
#define rb_parser_encoding ripper_parser_encoding
#define rb_parser_get_yydebug ripper_parser_get_yydebug
#define rb_parser_set_yydebug ripper_parser_set_yydebug
+#define rb_parser_get_debug_output ripper_parser_get_debug_output
+#define rb_parser_set_debug_output ripper_parser_set_debug_output
static VALUE ripper_parser_end_seen_p(VALUE vparser);
static VALUE ripper_parser_encoding(VALUE vparser);
static VALUE ripper_parser_get_yydebug(VALUE self);
static VALUE ripper_parser_set_yydebug(VALUE self, VALUE flag);
+static VALUE ripper_parser_get_debug_output(VALUE self);
+static VALUE ripper_parser_set_debug_output(VALUE self, VALUE output);
/*
* call-seq:
@@ -10940,10 +13143,10 @@ static VALUE ripper_parser_set_yydebug(VALUE self, VALUE flag);
static VALUE
ripper_error_p(VALUE vparser)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
- return parser->error_p ? Qtrue : Qfalse;
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+ return p->error_p ? Qtrue : Qfalse;
}
#endif
@@ -10956,10 +13159,10 @@ ripper_error_p(VALUE vparser)
VALUE
rb_parser_end_seen_p(VALUE vparser)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
- return ruby__end__seen ? Qtrue : Qfalse;
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+ return p->ruby__end__seen ? Qtrue : Qfalse;
}
/*
@@ -10971,12 +13174,13 @@ rb_parser_end_seen_p(VALUE vparser)
VALUE
rb_parser_encoding(VALUE vparser)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
- return rb_enc_from_encoding(current_enc);
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+ return rb_enc_from_encoding(p->enc);
}
+#ifdef RIPPER
/*
* call-seq:
* ripper.yydebug -> true or false
@@ -10986,11 +13190,12 @@ rb_parser_encoding(VALUE vparser)
VALUE
rb_parser_get_yydebug(VALUE self)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
- return yydebug ? Qtrue : Qfalse;
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ return p->debug ? Qtrue : Qfalse;
}
+#endif
/*
* call-seq:
@@ -11001,54 +13206,86 @@ rb_parser_get_yydebug(VALUE self)
VALUE
rb_parser_set_yydebug(VALUE self, VALUE flag)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
- yydebug = RTEST(flag);
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ p->debug = RTEST(flag);
return flag;
}
+/*
+ * call-seq:
+ * ripper.debug_output -> obj
+ *
+ * Get debug output.
+ */
+VALUE
+rb_parser_get_debug_output(VALUE self)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ return p->debug_output;
+}
+
+/*
+ * call-seq:
+ * ripper.debug_output = obj
+ *
+ * Set debug output.
+ */
+VALUE
+rb_parser_set_debug_output(VALUE self, VALUE output)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ return p->debug_output = output;
+}
+
#ifndef RIPPER
#ifdef YYMALLOC
#define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
-#define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
-#define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
- (n)->u3.cnt = (c), (p))
+/* Keep the order; NEWHEAP then xmalloc and ADD2HEAP to get rid of
+ * potential memory leak */
+#define NEWHEAP() rb_imemo_tmpbuf_parser_heap(0, p->heap, 0)
+#define ADD2HEAP(new, cnt, ptr) ((p->heap = (new))->ptr = (ptr), \
+ (new)->cnt = (cnt), (ptr))
void *
-rb_parser_malloc(struct parser_params *parser, size_t size)
+rb_parser_malloc(struct parser_params *p, size_t size)
{
size_t cnt = HEAPCNT(1, size);
- NODE *n = NEWHEAP();
+ rb_imemo_tmpbuf_t *n = NEWHEAP();
void *ptr = xmalloc(size);
return ADD2HEAP(n, cnt, ptr);
}
void *
-rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
+rb_parser_calloc(struct parser_params *p, size_t nelem, size_t size)
{
size_t cnt = HEAPCNT(nelem, size);
- NODE *n = NEWHEAP();
+ rb_imemo_tmpbuf_t *n = NEWHEAP();
void *ptr = xcalloc(nelem, size);
return ADD2HEAP(n, cnt, ptr);
}
void *
-rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
+rb_parser_realloc(struct parser_params *p, void *ptr, size_t size)
{
- NODE *n;
+ rb_imemo_tmpbuf_t *n;
size_t cnt = HEAPCNT(1, size);
- if (ptr && (n = parser->heap) != NULL) {
+ if (ptr && (n = p->heap) != NULL) {
do {
- if (n->u1.node == ptr) {
- n->u1.node = ptr = xrealloc(ptr, size);
- if (n->u3.cnt) n->u3.cnt = cnt;
+ if (n->ptr == ptr) {
+ n->ptr = ptr = xrealloc(ptr, size);
+ if (n->cnt) n->cnt = cnt;
return ptr;
}
- } while ((n = n->u2.node) != NULL);
+ } while ((n = n->next) != NULL);
}
n = NEWHEAP();
ptr = xrealloc(ptr, size);
@@ -11056,60 +13293,136 @@ rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
}
void
-rb_parser_free(struct parser_params *parser, void *ptr)
+rb_parser_free(struct parser_params *p, void *ptr)
{
- NODE **prev = &parser->heap, *n;
+ rb_imemo_tmpbuf_t **prev = &p->heap, *n;
while ((n = *prev) != NULL) {
- if (n->u1.node == ptr) {
- *prev = n->u2.node;
+ if (n->ptr == ptr) {
+ *prev = n->next;
rb_gc_force_recycle((VALUE)n);
break;
}
- prev = &n->u2.node;
+ prev = &n->next;
}
xfree(ptr);
}
#endif
void
-rb_parser_printf(struct parser_params *parser, const char *fmt, ...)
+rb_parser_printf(struct parser_params *p, const char *fmt, ...)
{
va_list ap;
- VALUE mesg = parser->debug_buffer;
+ VALUE mesg = p->debug_buffer;
- if (NIL_P(mesg)) parser->debug_buffer = mesg = rb_str_new(0, 0);
+ if (NIL_P(mesg)) p->debug_buffer = mesg = rb_str_new(0, 0);
va_start(ap, fmt);
rb_str_vcatf(mesg, fmt, ap);
va_end(ap);
if (RSTRING_END(mesg)[-1] == '\n') {
- rb_io_write(parser->debug_output, mesg);
- parser->debug_buffer = Qnil;
+ rb_io_write(p->debug_output, mesg);
+ p->debug_buffer = Qnil;
}
}
static void
-parser_compile_error(struct parser_params *parser, const char *fmt, ...)
+parser_compile_error(struct parser_params *p, const char *fmt, ...)
{
va_list ap;
- rb_io_flush(parser->debug_output);
- parser->error_p = 1;
+ rb_io_flush(p->debug_output);
+ p->error_p = 1;
va_start(ap, fmt);
- parser->error_buffer =
- rb_syntax_error_append(parser->error_buffer,
- ruby_sourcefile_string,
- ruby_sourceline,
- rb_long2int(lex_p - lex_pbeg),
- current_enc, fmt, ap);
+ p->error_buffer =
+ rb_syntax_error_append(p->error_buffer,
+ p->ruby_sourcefile_string,
+ p->ruby_sourceline,
+ rb_long2int(p->lex.pcur - p->lex.pbeg),
+ p->enc, fmt, ap);
va_end(ap);
}
+
+static size_t
+count_char(const char *str, int c)
+{
+ int n = 0;
+ while (str[n] == c) ++n;
+ return n;
+}
+
+/*
+ * strip enclosing double-quotes, same as the default yytnamerr except
+ * for that single-quotes matching back-quotes do not stop stripping.
+ *
+ * "\"`class' keyword\"" => "`class' keyword"
+ */
+RUBY_FUNC_EXPORTED size_t
+rb_yytnamerr(struct parser_params *p, char *yyres, const char *yystr)
+{
+ if (*yystr == '"') {
+ size_t yyn = 0, bquote = 0;
+ const char *yyp = yystr;
+
+ while (*++yyp) {
+ switch (*yyp) {
+ case '`':
+ if (!bquote) {
+ bquote = count_char(yyp+1, '`') + 1;
+ if (yyres) memcpy(&yyres[yyn], yyp, bquote);
+ yyn += bquote;
+ yyp += bquote - 1;
+ break;
+ }
+ goto default_char;
+
+ case '\'':
+ if (bquote && count_char(yyp+1, '\'') + 1 == bquote) {
+ if (yyres) memcpy(yyres + yyn, yyp, bquote);
+ yyn += bquote;
+ yyp += bquote - 1;
+ bquote = 0;
+ break;
+ }
+ if (yyp[1] && yyp[1] != '\'' && yyp[2] == '\'') {
+ if (yyres) memcpy(yyres + yyn, yyp, 3);
+ yyn += 3;
+ yyp += 2;
+ break;
+ }
+ goto do_not_strip_quotes;
+
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default_char:
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ case '\0':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (!yyres) return strlen(yystr);
+
+ return (YYSIZE_T)(yystpcpy(yyres, yystr) - yyres);
+}
#endif
#ifdef RIPPER
#ifdef RIPPER_DEBUG
-extern int rb_is_pointer_to_heap(VALUE);
-
/* :nodoc: */
static VALUE
ripper_validate_object(VALUE self, VALUE x)
@@ -11118,11 +13431,9 @@ ripper_validate_object(VALUE self, VALUE x)
if (x == Qtrue) return x;
if (x == Qnil) return x;
if (x == Qundef)
- rb_raise(rb_eArgError, "Qundef given");
+ rb_raise(rb_eArgError, "Qundef given");
if (FIXNUM_P(x)) return x;
if (SYMBOL_P(x)) return x;
- if (!rb_is_pointer_to_heap(x))
- rb_raise(rb_eArgError, "invalid pointer: %p", x);
switch (BUILTIN_TYPE(x)) {
case T_STRING:
case T_OBJECT:
@@ -11131,15 +13442,20 @@ ripper_validate_object(VALUE self, VALUE x)
case T_FLOAT:
case T_COMPLEX:
case T_RATIONAL:
- return x;
+ break;
case T_NODE:
- if (nd_type(x) != NODE_RIPPER) {
- rb_raise(rb_eArgError, "NODE given: %p", x);
+ if (nd_type((NODE *)x) != NODE_RIPPER) {
+ rb_raise(rb_eArgError, "NODE given: %p", (void *)x);
}
- return ((NODE *)x)->nd_rval;
+ x = ((NODE *)x)->nd_rval;
+ break;
default:
- rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
- x, rb_obj_classname(x));
+ rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
+ (void *)x, rb_obj_classname(x));
+ }
+ if (!RBASIC_CLASS(x)) {
+ rb_raise(rb_eArgError, "hidden ruby object: %p (%s)",
+ (void *)x, rb_builtin_type_name(TYPE(x)));
}
return x;
}
@@ -11148,58 +13464,58 @@ ripper_validate_object(VALUE self, VALUE x)
#define validate(x) ((x) = get_value(x))
static VALUE
-ripper_dispatch0(struct parser_params *parser, ID mid)
+ripper_dispatch0(struct parser_params *p, ID mid)
{
- return rb_funcall(parser->value, mid, 0);
+ return rb_funcall(p->value, mid, 0);
}
static VALUE
-ripper_dispatch1(struct parser_params *parser, ID mid, VALUE a)
+ripper_dispatch1(struct parser_params *p, ID mid, VALUE a)
{
validate(a);
- return rb_funcall(parser->value, mid, 1, a);
+ return rb_funcall(p->value, mid, 1, a);
}
static VALUE
-ripper_dispatch2(struct parser_params *parser, ID mid, VALUE a, VALUE b)
+ripper_dispatch2(struct parser_params *p, ID mid, VALUE a, VALUE b)
{
validate(a);
validate(b);
- return rb_funcall(parser->value, mid, 2, a, b);
+ return rb_funcall(p->value, mid, 2, a, b);
}
static VALUE
-ripper_dispatch3(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c)
+ripper_dispatch3(struct parser_params *p, ID mid, VALUE a, VALUE b, VALUE c)
{
validate(a);
validate(b);
validate(c);
- return rb_funcall(parser->value, mid, 3, a, b, c);
+ return rb_funcall(p->value, mid, 3, a, b, c);
}
static VALUE
-ripper_dispatch4(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
+ripper_dispatch4(struct parser_params *p, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
{
validate(a);
validate(b);
validate(c);
validate(d);
- return rb_funcall(parser->value, mid, 4, a, b, c, d);
+ return rb_funcall(p->value, mid, 4, a, b, c, d);
}
static VALUE
-ripper_dispatch5(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
+ripper_dispatch5(struct parser_params *p, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
{
validate(a);
validate(b);
validate(c);
validate(d);
validate(e);
- return rb_funcall(parser->value, mid, 5, a, b, c, d, e);
+ return rb_funcall(p->value, mid, 5, a, b, c, d, e);
}
static VALUE
-ripper_dispatch7(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g)
+ripper_dispatch7(struct parser_params *p, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g)
{
validate(a);
validate(b);
@@ -11208,7 +13524,7 @@ ripper_dispatch7(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c
validate(e);
validate(f);
validate(g);
- return rb_funcall(parser->value, mid, 7, a, b, c, d, e, f, g);
+ return rb_funcall(p->value, mid, 7, a, b, c, d, e, f, g);
}
static ID
@@ -11233,13 +13549,13 @@ ripper_get_value(VALUE v)
}
static void
-ripper_error_gen(struct parser_params *parser)
+ripper_error(struct parser_params *p)
{
- parser->error_p = TRUE;
+ p->error_p = TRUE;
}
static void
-ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
+ripper_compile_error(struct parser_params *p, const char *fmt, ...)
{
VALUE str;
va_list args;
@@ -11247,12 +13563,12 @@ ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
va_start(args, fmt);
str = rb_vsprintf(fmt, args);
va_end(args);
- rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
- ripper_error_gen(parser);
+ rb_funcall(p->value, rb_intern("compile_error"), 1, str);
+ ripper_error(p);
}
static VALUE
-ripper_lex_get_generic(struct parser_params *parser, VALUE src)
+ripper_lex_get_generic(struct parser_params *p, VALUE src)
{
VALUE line = rb_funcallv_public(src, id_gets, 0, 0);
if (!NIL_P(line) && !RB_TYPE_P(line, T_STRING)) {
@@ -11264,7 +13580,7 @@ ripper_lex_get_generic(struct parser_params *parser, VALUE src)
}
static VALUE
-ripper_lex_io_get(struct parser_params *parser, VALUE src)
+ripper_lex_io_get(struct parser_params *p, VALUE src)
{
return rb_io_gets(src);
}
@@ -11294,23 +13610,23 @@ ripper_s_allocate(VALUE klass)
static VALUE
ripper_initialize(int argc, VALUE *argv, VALUE self)
{
- struct parser_params *parser;
+ struct parser_params *p;
VALUE src, fname, lineno;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
if (RB_TYPE_P(src, T_FILE)) {
- lex_gets = ripper_lex_io_get;
+ p->lex.gets = ripper_lex_io_get;
}
else if (rb_respond_to(src, id_gets)) {
- lex_gets = ripper_lex_get_generic;
+ p->lex.gets = ripper_lex_get_generic;
}
else {
StringValue(src);
- lex_gets = lex_get_str;
+ p->lex.gets = lex_get_str;
}
- lex_input = src;
- parser->eofp = 0;
+ p->lex.input = src;
+ p->eofp = 0;
if (NIL_P(fname)) {
fname = STR_NEW2("(ripper)");
OBJ_FREEZE(fname);
@@ -11319,39 +13635,36 @@ ripper_initialize(int argc, VALUE *argv, VALUE self)
StringValueCStr(fname);
fname = rb_str_new_frozen(fname);
}
- parser_initialize(parser);
+ parser_initialize(p);
- ruby_sourcefile_string = fname;
- ruby_sourcefile = RSTRING_PTR(fname);
- ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
+ p->ruby_sourcefile_string = fname;
+ p->ruby_sourcefile = RSTRING_PTR(fname);
+ p->ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
return Qnil;
}
-struct ripper_args {
- struct parser_params *parser;
- int argc;
- VALUE *argv;
-};
-
static VALUE
ripper_parse0(VALUE parser_v)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
- parser_prepare(parser);
- ripper_yyparse((void*)parser);
- return parser->result;
+ TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, p);
+ parser_prepare(p);
+ p->ast = rb_ast_new();
+ ripper_yyparse((void*)p);
+ rb_ast_dispose(p->ast);
+ p->ast = 0;
+ return p->result;
}
static VALUE
ripper_ensure(VALUE parser_v)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
- parser->parsing_thread = Qnil;
+ TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, p);
+ p->parsing_thread = Qnil;
return Qnil;
}
@@ -11364,22 +13677,22 @@ ripper_ensure(VALUE parser_v)
static VALUE
ripper_parse(VALUE self)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
- if (!ripper_initialized_p(parser)) {
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
rb_raise(rb_eArgError, "method called for uninitialized object");
}
- if (!NIL_P(parser->parsing_thread)) {
- if (parser->parsing_thread == rb_thread_current())
+ if (!NIL_P(p->parsing_thread)) {
+ if (p->parsing_thread == rb_thread_current())
rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
else
rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
}
- parser->parsing_thread = rb_thread_current();
+ p->parsing_thread = rb_thread_current();
rb_ensure(ripper_parse0, self, ripper_ensure, self);
- return parser->result;
+ return p->result;
}
/*
@@ -11392,15 +13705,15 @@ ripper_parse(VALUE self)
static VALUE
ripper_column(VALUE self)
{
- struct parser_params *parser;
+ struct parser_params *p;
long col;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
- if (!ripper_initialized_p(parser)) {
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
rb_raise(rb_eArgError, "method called for uninitialized object");
}
- if (NIL_P(parser->parsing_thread)) return Qnil;
- col = parser->tokp - lex_pbeg;
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ col = p->lex.ptok - p->lex.pbeg;
return LONG2NUM(col);
}
@@ -11413,13 +13726,13 @@ ripper_column(VALUE self)
static VALUE
ripper_filename(VALUE self)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
- if (!ripper_initialized_p(parser)) {
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
rb_raise(rb_eArgError, "method called for uninitialized object");
}
- return ruby_sourcefile_string;
+ return p->ruby_sourcefile_string;
}
/*
@@ -11432,14 +13745,14 @@ ripper_filename(VALUE self)
static VALUE
ripper_lineno(VALUE self)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
- if (!ripper_initialized_p(parser)) {
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
rb_raise(rb_eArgError, "method called for uninitialized object");
}
- if (NIL_P(parser->parsing_thread)) return Qnil;
- return INT2NUM(ruby_sourceline);
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ return INT2NUM(p->ruby_sourceline);
}
/*
@@ -11451,14 +13764,36 @@ ripper_lineno(VALUE self)
static VALUE
ripper_state(VALUE self)
{
- struct parser_params *parser;
+ struct parser_params *p;
- TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
- if (!ripper_initialized_p(parser)) {
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
rb_raise(rb_eArgError, "method called for uninitialized object");
}
- if (NIL_P(parser->parsing_thread)) return Qnil;
- return INT2NUM(lex_state);
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ return INT2NUM(p->lex.state);
+}
+
+/*
+ * call-seq:
+ * ripper.token -> String
+ *
+ * Return the current token string.
+ */
+static VALUE
+ripper_token(VALUE self)
+{
+ struct parser_params *p;
+ long pos, len;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
+ rb_raise(rb_eArgError, "method called for uninitialized object");
+ }
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ pos = p->lex.ptok - p->lex.pbeg;
+ len = p->lex.pcur - p->lex.ptok;
+ return rb_str_subseq(p->lex.lastline, pos, len);
}
#ifdef RIPPER_DEBUG
@@ -11481,6 +13816,12 @@ ripper_value(VALUE self, VALUE obj)
}
#endif
+/*
+ * call-seq:
+ * Ripper.lex_state_name(integer) -> string
+ *
+ * Returns a string representation of lex_state.
+ */
static VALUE
ripper_lex_state_name(VALUE self, VALUE state)
{
@@ -11495,6 +13836,9 @@ Init_ripper(void)
id_warn = rb_intern_const("warn");
id_warning = rb_intern_const("warning");
id_gets = rb_intern_const("gets");
+ id_assoc = rb_intern_const("=>");
+
+ (void)yystpcpy; /* may not used in newer bison */
InitVM(ripper);
}
@@ -11514,15 +13858,18 @@ InitVM_ripper(void)
rb_define_method(Ripper, "filename", ripper_filename, 0);
rb_define_method(Ripper, "lineno", ripper_lineno, 0);
rb_define_method(Ripper, "state", ripper_state, 0);
+ rb_define_method(Ripper, "token", ripper_token, 0);
rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
+ rb_define_method(Ripper, "debug_output", rb_parser_get_debug_output, 0);
+ rb_define_method(Ripper, "debug_output=", rb_parser_set_debug_output, 1);
rb_define_method(Ripper, "error?", ripper_error_p, 0);
#ifdef RIPPER_DEBUG
- rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
- rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
- rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
+ rb_define_method(Ripper, "assert_Qundef", ripper_assert_Qundef, 2);
+ rb_define_method(Ripper, "rawVALUE", ripper_value, 1);
+ rb_define_method(Ripper, "validate_object", ripper_validate_object, 1);
#endif
rb_define_singleton_method(Ripper, "dedent_string", parser_dedent_string, 2);
@@ -11550,3 +13897,10 @@ InitVM_ripper(void)
}
#endif /* RIPPER */
+
+/*
+ * Local variables:
+ * mode: c
+ * c-file-style: "ruby"
+ * End:
+ */
diff --git a/prelude.rb b/prelude.rb
index 7b98e28285..b1e477a3ea 100644
--- a/prelude.rb
+++ b/prelude.rb
@@ -1,143 +1,22 @@
-class Thread
- MUTEX_FOR_THREAD_EXCLUSIVE = Thread::Mutex.new # :nodoc:
- private_constant :MUTEX_FOR_THREAD_EXCLUSIVE
-
- # call-seq:
- # Thread.exclusive { block } => obj
- #
- # Wraps the block in a single, VM-global Mutex.synchronize, returning the
- # value of the block. A thread executing inside the exclusive section will
- # only block other threads which also use the Thread.exclusive mechanism.
- def self.exclusive
- warn "Thread.exclusive is deprecated, use Thread::Mutex", caller
- MUTEX_FOR_THREAD_EXCLUSIVE.synchronize{
- yield
- }
+class Binding
+ # :nodoc:
+ def irb
+ require 'irb'
+ irb
end
-end
-class IO
+ # suppress redefinition warning
+ alias irb irb # :nodoc:
+end
- # call-seq:
- # ios.read_nonblock(maxlen [, options]) -> string
- # ios.read_nonblock(maxlen, outbuf [, options]) -> outbuf
- #
- # Reads at most <i>maxlen</i> bytes from <em>ios</em> using
- # the read(2) system call after O_NONBLOCK is set for
- # the underlying file descriptor.
- #
- # If the optional <i>outbuf</i> argument is present,
- # it must reference a String, which will receive the data.
- # The <i>outbuf</i> will contain only the received data after the method call
- # even if it is not empty at the beginning.
- #
- # read_nonblock just calls the read(2) system call.
- # It causes all errors the read(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc.
- # The caller should care such errors.
- #
- # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
- # it is extended by IO::WaitReadable.
- # So IO::WaitReadable can be used to rescue the exceptions for retrying
- # read_nonblock.
- #
- # read_nonblock causes EOFError on EOF.
- #
- # If the read byte buffer is not empty,
- # read_nonblock reads from the buffer like readpartial.
- # In this case, the read(2) system call is not called.
- #
- # When read_nonblock raises an exception kind of IO::WaitReadable,
- # read_nonblock should not be called
- # until io is readable for avoiding busy loop.
- # This can be done as follows.
- #
- # # emulates blocking read (readpartial).
- # begin
- # result = io.read_nonblock(maxlen)
- # rescue IO::WaitReadable
- # IO.select([io])
- # retry
- # end
- #
- # Although IO#read_nonblock doesn't raise IO::WaitWritable.
- # OpenSSL::Buffering#read_nonblock can raise IO::WaitWritable.
- # If IO and SSL should be used polymorphically,
- # IO::WaitWritable should be rescued too.
- # See the document of OpenSSL::Buffering#read_nonblock for sample code.
- #
- # Note that this method is identical to readpartial
- # except the non-blocking flag is set.
- #
- # By specifying a keyword argument _exception_ to +false+, you can indicate
- # that read_nonblock should not raise an IO::WaitReadable exception, but
- # return the symbol +:wait_readable+ instead. At EOF, it will return nil
- # instead of raising EOFError.
- def read_nonblock(len, buf = nil, exception: true)
- __read_nonblock(len, buf, exception)
+module Kernel
+ def pp(*objs)
+ require 'pp'
+ pp(*objs)
end
- # call-seq:
- # ios.write_nonblock(string) -> integer
- # ios.write_nonblock(string [, options]) -> integer
- #
- # Writes the given string to <em>ios</em> using
- # the write(2) system call after O_NONBLOCK is set for
- # the underlying file descriptor.
- #
- # It returns the number of bytes written.
- #
- # write_nonblock just calls the write(2) system call.
- # It causes all errors the write(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc.
- # The result may also be smaller than string.length (partial write).
- # The caller should care such errors and partial write.
- #
- # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
- # it is extended by IO::WaitWritable.
- # So IO::WaitWritable can be used to rescue the exceptions for retrying write_nonblock.
- #
- # # Creates a pipe.
- # r, w = IO.pipe
- #
- # # write_nonblock writes only 65536 bytes and return 65536.
- # # (The pipe size is 65536 bytes on this environment.)
- # s = "a" * 100000
- # p w.write_nonblock(s) #=> 65536
- #
- # # write_nonblock cannot write a byte and raise EWOULDBLOCK (EAGAIN).
- # p w.write_nonblock("b") # Resource temporarily unavailable (Errno::EAGAIN)
- #
- # If the write buffer is not empty, it is flushed at first.
- #
- # When write_nonblock raises an exception kind of IO::WaitWritable,
- # write_nonblock should not be called
- # until io is writable for avoiding busy loop.
- # This can be done as follows.
- #
- # begin
- # result = io.write_nonblock(string)
- # rescue IO::WaitWritable, Errno::EINTR
- # IO.select(nil, [io])
- # retry
- # end
- #
- # Note that this doesn't guarantee to write all data in string.
- # The length written is reported as result and it should be checked later.
- #
- # On some platforms such as Windows, write_nonblock is not supported
- # according to the kind of the IO object.
- # In such cases, write_nonblock raises <code>Errno::EBADF</code>.
- #
- # By specifying a keyword argument _exception_ to +false+, you can indicate
- # that write_nonblock should not raise an IO::WaitWritable exception, but
- # return the symbol +:wait_writable+ instead.
- def write_nonblock(buf, exception: true)
- __write_nonblock(buf, exception)
- end
-end
+ # suppress redefinition warning
+ alias pp pp # :nodoc:
-class Binding
- def irb
- require 'irb'
- irb
- end
+ private :pp
end
diff --git a/probes.d b/probes.d
index 57a3d762bd..0762a2d25f 100644
--- a/probes.d
+++ b/probes.d
@@ -214,17 +214,6 @@ provider ruby {
Fired at the end of a sweep phase.
*/
probe gc__sweep__end();
-
- /*
- ruby:::method-cache-clear(class, filename, lineno);
-
- This probe is fired when the method cache is cleared.
-
- * `class` the name of the class or "global" (a string)
- * `filename` the file name where the cache is _being cleared_ (a string)
- * `lineno` the line number where the cache is _being cleared_ (an int)
- */
- probe method__cache__clear(const char *class, const char *filename, int lineno);
};
#pragma D attributes Stable/Evolving/Common provider ruby provider
diff --git a/probes_helper.h b/probes_helper.h
index 1becae5a8d..d2d0ebb6e2 100644
--- a/probes_helper.h
+++ b/probes_helper.h
@@ -2,7 +2,6 @@
#define RUBY_PROBES_HELPER_H
#include "ruby/ruby.h"
-#include "probes.h"
struct ruby_dtrace_method_hook_args {
const char *classname;
@@ -13,13 +12,15 @@ struct ruby_dtrace_method_hook_args {
volatile VALUE name;
};
-NOINLINE(int ruby_th_dtrace_setup(rb_thread_t *, VALUE, ID, struct ruby_dtrace_method_hook_args *));
+MJIT_SYMBOL_EXPORT_BEGIN
+NOINLINE(int rb_dtrace_setup(rb_execution_context_t *, VALUE, ID, struct ruby_dtrace_method_hook_args *));
+MJIT_SYMBOL_EXPORT_END
-#define RUBY_DTRACE_METHOD_HOOK(name, th, klazz, id) \
+#define RUBY_DTRACE_METHOD_HOOK(name, ec, klazz, id) \
do { \
if (UNLIKELY(RUBY_DTRACE_##name##_ENABLED())) { \
struct ruby_dtrace_method_hook_args args; \
- if (ruby_th_dtrace_setup(th, klazz, id, &args)) { \
+ if (rb_dtrace_setup(ec, klazz, id, &args)) { \
RUBY_DTRACE_##name(args.classname, \
args.methodname, \
args.filename, \
@@ -28,16 +29,16 @@ do { \
} \
} while (0)
-#define RUBY_DTRACE_METHOD_ENTRY_HOOK(th, klass, id) \
- RUBY_DTRACE_METHOD_HOOK(METHOD_ENTRY, th, klass, id)
+#define RUBY_DTRACE_METHOD_ENTRY_HOOK(ec, klass, id) \
+ RUBY_DTRACE_METHOD_HOOK(METHOD_ENTRY, ec, klass, id)
-#define RUBY_DTRACE_METHOD_RETURN_HOOK(th, klass, id) \
- RUBY_DTRACE_METHOD_HOOK(METHOD_RETURN, th, klass, id)
+#define RUBY_DTRACE_METHOD_RETURN_HOOK(ec, klass, id) \
+ RUBY_DTRACE_METHOD_HOOK(METHOD_RETURN, ec, klass, id)
-#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, klass, id) \
- RUBY_DTRACE_METHOD_HOOK(CMETHOD_ENTRY, th, klass, id)
+#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec, klass, id) \
+ RUBY_DTRACE_METHOD_HOOK(CMETHOD_ENTRY, ec, klass, id)
-#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, klass, id) \
- RUBY_DTRACE_METHOD_HOOK(CMETHOD_RETURN, th, klass, id)
+#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, klass, id) \
+ RUBY_DTRACE_METHOD_HOOK(CMETHOD_RETURN, ec, klass, id)
#endif /* RUBY_PROBES_HELPER_H */
diff --git a/proc.c b/proc.c
index 021442ad93..a933fde3a8 100644
--- a/proc.c
+++ b/proc.c
@@ -10,13 +10,16 @@
**********************************************************************/
#include "eval_intern.h"
-#include "internal.h"
#include "gc.h"
+#include "internal.h"
+#include "internal/class.h"
+#include "internal/error.h"
+#include "internal/eval.h"
+#include "internal/object.h"
+#include "internal/proc.h"
+#include "internal/symbol.h"
#include "iseq.h"
-
-/* Proc.new with no block will raise an exception in the future
- * versions */
-#define PROC_NEW_REQUIRES_BLOCK 0
+#include "vm_core.h"
#if !defined(__GNUC__) || __GNUC__ < 5 || defined(__MINGW32__)
# define NO_CLOBBERED(v) (*(volatile VALUE *)&(v))
@@ -24,6 +27,9 @@
# define NO_CLOBBERED(v) (v)
#endif
+#define UPDATE_TYPED_REFERENCE(_type, _ref) *(_type*)&_ref = (_type)rb_gc_location((VALUE)_ref)
+#define UPDATE_REFERENCE(_ref) UPDATE_TYPED_REFERENCE(VALUE, _ref)
+
const rb_cref_t *rb_vm_cref_in_context(VALUE self, VALUE cbase);
struct METHOD {
@@ -39,9 +45,10 @@ VALUE rb_cMethod;
VALUE rb_cBinding;
VALUE rb_cProc;
-static VALUE bmcall(VALUE, VALUE, int, VALUE *, VALUE);
+static rb_block_call_func bmcall;
static int method_arity(VALUE);
static int method_min_max_arity(VALUE, int *max);
+static VALUE proc_binding(VALUE self);
#define attached id__attached__
@@ -57,23 +64,51 @@ block_mark(const struct rb_block *block)
case block_type_ifunc:
{
const struct rb_captured_block *captured = &block->as.captured;
- RUBY_MARK_UNLESS_NULL(captured->self);
- RUBY_MARK_UNLESS_NULL((VALUE)captured->code.val);
+ RUBY_MARK_MOVABLE_UNLESS_NULL(captured->self);
+ RUBY_MARK_MOVABLE_UNLESS_NULL((VALUE)captured->code.val);
if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
- RUBY_MARK_UNLESS_NULL(VM_ENV_ENVVAL(captured->ep));
+ rb_gc_mark(VM_ENV_ENVVAL(captured->ep));
}
}
break;
case block_type_symbol:
- RUBY_MARK_UNLESS_NULL(block->as.symbol);
+ RUBY_MARK_MOVABLE_UNLESS_NULL(block->as.symbol);
+ break;
+ case block_type_proc:
+ RUBY_MARK_MOVABLE_UNLESS_NULL(block->as.proc);
+ break;
+ }
+}
+
+static void
+block_compact(struct rb_block *block)
+{
+ switch (block->type) {
+ case block_type_iseq:
+ case block_type_ifunc:
+ {
+ struct rb_captured_block *captured = &block->as.captured;
+ captured->self = rb_gc_location(captured->self);
+ captured->code.val = rb_gc_location(captured->code.val);
+ }
+ break;
+ case block_type_symbol:
+ block->as.symbol = rb_gc_location(block->as.symbol);
break;
case block_type_proc:
- RUBY_MARK_UNLESS_NULL(block->as.proc);
+ block->as.proc = rb_gc_location(block->as.proc);
break;
}
}
static void
+proc_compact(void *ptr)
+{
+ rb_proc_t *proc = ptr;
+ block_compact((struct rb_block *)&proc->block);
+}
+
+static void
proc_mark(void *ptr)
{
rb_proc_t *proc = ptr;
@@ -101,6 +136,7 @@ static const rb_data_type_t proc_data_type = {
proc_mark,
RUBY_TYPED_DEFAULT_FREE,
proc_memsize,
+ proc_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
};
@@ -123,28 +159,11 @@ rb_obj_is_proc(VALUE proc)
}
}
-VALUE rb_proc_create(VALUE klass, const struct rb_block *block,
- int8_t safe_level, int8_t is_from_method, int8_t is_lambda);
-
-/* :nodoc: */
-static VALUE
-proc_dup(VALUE self)
-{
- VALUE procval;
- rb_proc_t *src;
-
- GetProcPtr(self, src);
- procval = rb_proc_create(rb_cProc, &src->block,
- src->safe_level, src->is_from_method, src->is_lambda);
- RB_GC_GUARD(self); /* for: body = proc_dup(body) */
- return procval;
-}
-
/* :nodoc: */
static VALUE
proc_clone(VALUE self)
{
- VALUE procval = proc_dup(self);
+ VALUE procval = rb_proc_dup(self);
CLONESETUP(procval, self);
return procval;
}
@@ -153,8 +172,10 @@ proc_clone(VALUE self)
* call-seq:
* prc.lambda? -> true or false
*
- * Returns +true+ for a Proc object for which argument handling is rigid.
- * Such procs are typically generated by +lambda+.
+ * Returns +true+ if a Proc object is lambda.
+ * +false+ if non-lambda.
+ *
+ * The lambda-ness affects argument handling and the behavior of +return+ and +break+.
*
* A Proc object generated by +proc+ ignores extra arguments.
*
@@ -276,10 +297,19 @@ binding_mark(void *ptr)
RUBY_MARK_ENTER("binding");
block_mark(&bind->block);
- rb_gc_mark(bind->pathobj);
+ rb_gc_mark_movable(bind->pathobj);
RUBY_MARK_LEAVE("binding");
}
+static void
+binding_compact(void *ptr)
+{
+ rb_binding_t *bind = ptr;
+
+ block_compact((struct rb_block *)&bind->block);
+ UPDATE_REFERENCE(bind->pathobj);
+}
+
static size_t
binding_memsize(const void *ptr)
{
@@ -292,6 +322,7 @@ const rb_data_type_t ruby_binding_data_type = {
binding_mark,
binding_free,
binding_memsize,
+ binding_compact,
},
0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -332,8 +363,8 @@ binding_clone(VALUE self)
VALUE
rb_binding_new(void)
{
- rb_thread_t *th = GET_THREAD();
- return rb_vm_make_binding(th, th->ec.cfp);
+ rb_execution_context_t *ec = GET_EC();
+ return rb_vm_make_binding(ec, ec->cfp);
}
/*
@@ -390,13 +421,27 @@ get_local_variable_ptr(const rb_env_t **envp, ID lid)
const rb_env_t *env = *envp;
do {
if (!VM_ENV_FLAGS(env->ep, VM_FRAME_FLAG_CFRAME)) {
- const rb_iseq_t *iseq = env->iseq;
+ if (VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ISOLATED)) {
+ return NULL;
+ }
+
+ const rb_iseq_t *iseq = env->iseq;
unsigned int i;
VM_ASSERT(rb_obj_is_iseq((VALUE)iseq));
for (i=0; i<iseq->body->local_table_size; i++) {
if (iseq->body->local_table[i] == lid) {
+ if (iseq->body->local_iseq == iseq &&
+ iseq->body->param.flags.has_block &&
+ (unsigned int)iseq->body->param.block_start == i) {
+ const VALUE *ep = env->ep;
+ if (!VM_ENV_FLAGS(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)) {
+ RB_OBJ_WRITE(env, &env->env[i], rb_vm_bh_to_procval(GET_EC(), VM_ENV_BLOCK_HANDLER(ep)));
+ VM_ENV_FLAGS_SET(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM);
+ }
+ }
+
*envp = env;
return &env->env[i];
}
@@ -498,14 +543,15 @@ bind_local_variable_get(VALUE bindval, VALUE sym)
GetBindingPtr(bindval, bind);
env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
- if ((ptr = get_local_variable_ptr(&env, lid)) == NULL) {
- sym = ID2SYM(lid);
- undefined:
- rb_name_err_raise("local variable `%1$s' is not defined for %2$s",
- bindval, sym);
+ if ((ptr = get_local_variable_ptr(&env, lid)) != NULL) {
+ return *ptr;
}
- return *ptr;
+ sym = ID2SYM(lid);
+ undefined:
+ rb_name_err_raise("local variable `%1$s' is not defined for %2$s",
+ bindval, sym);
+ UNREACHABLE_RETURN(Qundef);
}
/*
@@ -601,8 +647,26 @@ bind_receiver(VALUE bindval)
return vm_block_self(&bind->block);
}
+/*
+ * call-seq:
+ * binding.source_location -> [String, Integer]
+ *
+ * Returns the Ruby source filename and line number of the binding object.
+ */
+static VALUE
+bind_location(VALUE bindval)
+{
+ VALUE loc[2];
+ const rb_binding_t *bind;
+ GetBindingPtr(bindval, bind);
+ loc[0] = pathobj_path(bind->pathobj);
+ loc[1] = INT2FIX(bind->first_lineno);
+
+ return rb_ary_new4(2, loc);
+}
+
static VALUE
-cfunc_proc_new(VALUE klass, VALUE ifunc, int8_t is_lambda)
+cfunc_proc_new(VALUE klass, VALUE ifunc)
{
rb_proc_t *proc;
cfunc_proc_t *sproc;
@@ -620,7 +684,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc, int8_t is_lambda)
/* self? */
RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
- proc->is_lambda = is_lambda;
+ proc->is_lambda = TRUE;
return procval;
}
@@ -632,12 +696,13 @@ sym_proc_new(VALUE klass, VALUE sym)
GetProcPtr(procval, proc);
vm_block_type_set(&proc->block, block_type_symbol);
+ proc->is_lambda = TRUE;
RB_OBJ_WRITE(procval, &proc->block.as.symbol, sym);
return procval;
}
struct vm_ifunc *
-rb_vm_ifunc_new(VALUE (*func)(ANYARGS), const void *data, int min_argc, int max_argc)
+rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc)
{
union {
struct vm_ifunc_argc argc;
@@ -662,55 +727,36 @@ rb_vm_ifunc_new(VALUE (*func)(ANYARGS), const void *data, int min_argc, int max_
}
arity.argc.min = min_argc;
arity.argc.max = max_argc;
- return IFUNC_NEW(func, data, arity.packed);
+ VALUE ret = rb_imemo_new(imemo_ifunc, (VALUE)func, (VALUE)data, arity.packed, 0);
+ return (struct vm_ifunc *)ret;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_func_proc_new(rb_block_call_func_t func, VALUE val)
{
struct vm_ifunc *ifunc = rb_vm_ifunc_proc_new(func, (void *)val);
- return cfunc_proc_new(rb_cProc, (VALUE)ifunc, 0);
+ return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc)
{
struct vm_ifunc *ifunc = rb_vm_ifunc_new(func, (void *)val, min_argc, max_argc);
- return cfunc_proc_new(rb_cProc, (VALUE)ifunc, 1);
+ return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
}
static const char proc_without_block[] = "tried to create Proc object without a block";
static VALUE
-proc_new(VALUE klass, int8_t is_lambda)
+proc_new(VALUE klass, int8_t is_lambda, int8_t kernel)
{
VALUE procval;
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->ec.cfp;
+ const rb_execution_context_t *ec = GET_EC();
+ rb_control_frame_t *cfp = ec->cfp;
VALUE block_handler;
if ((block_handler = rb_vm_frame_block_handler(cfp)) == VM_BLOCK_HANDLER_NONE) {
-#if !PROC_NEW_REQUIRES_BLOCK
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
-
- if ((block_handler = rb_vm_frame_block_handler(cfp)) != VM_BLOCK_HANDLER_NONE) {
- const VALUE *lep = rb_vm_ep_local_ep(cfp->ep);
-
- if (VM_ENV_ESCAPED_P(lep)) {
- procval = VM_ENV_PROCVAL(lep);
- goto return_existing_proc;
- }
-
- if (is_lambda) {
- rb_warn(proc_without_block);
- }
- }
-#else
- if (0)
-#endif
- else {
- rb_raise(rb_eArgError, proc_without_block);
- }
+ rb_raise(rb_eArgError, proc_without_block);
}
/* block is in cf */
@@ -718,13 +764,12 @@ proc_new(VALUE klass, int8_t is_lambda)
case block_handler_type_proc:
procval = VM_BH_TO_PROC(block_handler);
- return_existing_proc:
if (RBASIC_CLASS(procval) == klass) {
return procval;
}
else {
- VALUE newprocval = proc_dup(procval);
- RBASIC_SET_CLASS(newprocval, klass);
+ VALUE newprocval = rb_proc_dup(procval);
+ RBASIC_SET_CLASS(newprocval, klass);
return newprocval;
}
break;
@@ -736,8 +781,16 @@ proc_new(VALUE klass, int8_t is_lambda)
break;
case block_handler_type_ifunc:
+ return rb_vm_make_proc_lambda(ec, VM_BH_TO_CAPT_BLOCK(block_handler), klass, is_lambda);
case block_handler_type_iseq:
- return rb_vm_make_proc_lambda(th, VM_BH_TO_CAPT_BLOCK(block_handler), klass, is_lambda);
+ {
+ const struct rb_captured_block *captured = VM_BH_TO_CAPT_BLOCK(block_handler);
+ rb_control_frame_t *last_ruby_cfp = rb_vm_get_ruby_level_next_cfp(ec, cfp);
+ if (is_lambda && last_ruby_cfp && vm_cfp_forwarded_bh_p(last_ruby_cfp, block_handler)) {
+ is_lambda = false;
+ }
+ return rb_vm_make_proc_lambda(ec, captured, klass, is_lambda);
+ }
}
VM_UNREACHABLE(proc_new);
return Qnil;
@@ -748,10 +801,10 @@ proc_new(VALUE klass, int8_t is_lambda)
* Proc.new {|...| block } -> a_proc
* Proc.new -> a_proc
*
- * Creates a new <code>Proc</code> object, bound to the current
- * context. <code>Proc::new</code> may be called without a block only
- * within a method with an attached block, in which case that block is
- * converted to the <code>Proc</code> object.
+ * Creates a new Proc object, bound to the current context. Proc::new
+ * may be called without a block only within a method with an
+ * attached block, in which case that block is converted to the Proc
+ * object.
*
* def proc_from
* Proc.new
@@ -763,55 +816,96 @@ proc_new(VALUE klass, int8_t is_lambda)
static VALUE
rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
{
- VALUE block = proc_new(klass, FALSE);
+ VALUE block = proc_new(klass, FALSE, FALSE);
- rb_obj_call_init(block, argc, argv);
+ rb_obj_call_init_kw(block, argc, argv, RB_PASS_CALLED_KEYWORDS);
return block;
}
+VALUE
+rb_block_proc(void)
+{
+ return proc_new(rb_cProc, FALSE, FALSE);
+}
+
/*
* call-seq:
* proc { |...| block } -> a_proc
*
- * Equivalent to <code>Proc.new</code>.
+ * Equivalent to Proc.new.
*/
+static VALUE
+f_proc(VALUE _)
+{
+ return proc_new(rb_cProc, FALSE, TRUE);
+}
+
VALUE
-rb_block_proc(void)
+rb_block_lambda(void)
{
- return proc_new(rb_cProc, FALSE);
+ return proc_new(rb_cProc, TRUE, FALSE);
+}
+
+static void
+f_lambda_warn(void)
+{
+ rb_control_frame_t *cfp = GET_EC()->cfp;
+ VALUE block_handler = rb_vm_frame_block_handler(cfp);
+
+ if (block_handler != VM_BLOCK_HANDLER_NONE) {
+ switch (vm_block_handler_type(block_handler)) {
+ case block_handler_type_iseq:
+ if (RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)->ep == VM_BH_TO_ISEQ_BLOCK(block_handler)->ep) {
+ return;
+ }
+ break;
+ case block_handler_type_symbol:
+ return;
+ case block_handler_type_proc:
+ if (rb_proc_lambda_p(VM_BH_TO_PROC(block_handler))) {
+ return;
+ }
+ break;
+ case block_handler_type_ifunc:
+ break;
+ }
+ }
+
+ rb_warn_deprecated("lambda without a literal block", "the proc without lambda");
}
/*
* call-seq:
* lambda { |...| block } -> a_proc
*
- * Equivalent to <code>Proc.new</code>, except the resulting Proc objects
- * check the number of parameters passed when called.
+ * Equivalent to Proc.new, except the resulting Proc objects check the
+ * number of parameters passed when called.
*/
-VALUE
-rb_block_lambda(void)
+static VALUE
+f_lambda(VALUE _)
{
- return proc_new(rb_cProc, TRUE);
+ f_lambda_warn();
+ return rb_block_lambda();
}
-/* Document-method: ===
+/* Document-method: Proc#===
*
* call-seq:
* proc === obj -> result_of_proc
*
- * Invokes the block with +obj+ as the proc's parameter like Proc#call. It
- * is to allow a proc object to be a target of +when+ clause in a case
- * statement.
+ * Invokes the block with +obj+ as the proc's parameter like Proc#call.
+ * This allows a proc object to be the target of a +when+ clause
+ * in a case statement.
*/
/* CHECKME: are the argument checking semantics correct? */
/*
- * Document-method: []
- * Document-method: call
- * Document-method: yield
+ * Document-method: Proc#[]
+ * Document-method: Proc#call
+ * Document-method: Proc#yield
*
* call-seq:
* prc.call(params,...) -> obj
@@ -832,11 +926,11 @@ rb_block_lambda(void)
* Note that <code>prc.()</code> invokes <code>prc.call()</code> with
* the parameters given. It's syntactic sugar to hide "call".
*
- * For procs created using <code>lambda</code> or <code>->()</code> an error
- * is generated if the wrong number of parameters are passed to the proc.
- * For procs created using <code>Proc.new</code> or <code>Kernel.proc</code>,
- * extra parameters are silently discarded and missing parameters are
- * set to +nil+.
+ * For procs created using #lambda or <code>->()</code> an error is
+ * generated if the wrong number of parameters are passed to the
+ * proc. For procs created using Proc.new or Kernel.proc, extra
+ * parameters are silently discarded and missing parameters are set
+ * to +nil+.
*
* a_proc = proc {|a,b| [a,b] }
* a_proc.call(1) #=> [1, nil]
@@ -869,14 +963,29 @@ check_argc(long argc)
#endif
VALUE
+rb_proc_call_kw(VALUE self, VALUE args, int kw_splat)
+{
+ VALUE vret;
+ rb_proc_t *proc;
+ int argc = check_argc(RARRAY_LEN(args));
+ const VALUE *argv = RARRAY_CONST_PTR(args);
+ GetProcPtr(self, proc);
+ vret = rb_vm_invoke_proc(GET_EC(), proc, argc, argv,
+ kw_splat, VM_BLOCK_HANDLER_NONE);
+ RB_GC_GUARD(self);
+ RB_GC_GUARD(args);
+ return vret;
+}
+
+VALUE
rb_proc_call(VALUE self, VALUE args)
{
VALUE vret;
rb_proc_t *proc;
GetProcPtr(self, proc);
- vret = rb_vm_invoke_proc(GET_THREAD(), proc,
+ vret = rb_vm_invoke_proc(GET_EC(), proc,
check_argc(RARRAY_LEN(args)), RARRAY_CONST_PTR(args),
- VM_BLOCK_HANDLER_NONE);
+ RB_NO_KEYWORDS, VM_BLOCK_HANDLER_NONE);
RB_GC_GUARD(self);
RB_GC_GUARD(args);
return vret;
@@ -889,13 +998,25 @@ proc_to_block_handler(VALUE procval)
}
VALUE
+rb_proc_call_with_block_kw(VALUE self, int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
+{
+ rb_execution_context_t *ec = GET_EC();
+ VALUE vret;
+ rb_proc_t *proc;
+ GetProcPtr(self, proc);
+ vret = rb_vm_invoke_proc(ec, proc, argc, argv, kw_splat, proc_to_block_handler(passed_procval));
+ RB_GC_GUARD(self);
+ return vret;
+}
+
+VALUE
rb_proc_call_with_block(VALUE self, int argc, const VALUE *argv, VALUE passed_procval)
{
- rb_thread_t *th = GET_THREAD();
+ rb_execution_context_t *ec = GET_EC();
VALUE vret;
rb_proc_t *proc;
GetProcPtr(self, proc);
- vret = rb_vm_invoke_proc(th, proc, argc, argv, proc_to_block_handler(passed_procval));
+ vret = rb_vm_invoke_proc(ec, proc, argc, argv, RB_NO_KEYWORDS, proc_to_block_handler(passed_procval));
RB_GC_GUARD(self);
return vret;
}
@@ -912,10 +1033,10 @@ rb_proc_call_with_block(VALUE self, int argc, const VALUE *argv, VALUE passed_pr
* number of mandatory arguments, with the exception for blocks that
* are not lambdas and have only a finite number of optional arguments;
* in this latter case, returns n.
- * Keywords arguments will considered as a single additional argument,
+ * Keyword arguments will be considered as a single additional argument,
* that argument being mandatory if any keyword argument is mandatory.
- * A <code>proc</code> with no argument declarations
- * is the same as a block declaring <code>||</code> as its arguments.
+ * A #proc with no argument declarations is the same as a block
+ * declaring <code>||</code> as its arguments.
*
* proc {}.arity #=> 0
* proc { || }.arity #=> 0
@@ -928,16 +1049,16 @@ rb_proc_call_with_block(VALUE self, int argc, const VALUE *argv, VALUE passed_pr
* proc { |x:, y:, z:0| }.arity #=> 1
* proc { |*a, x:, y:0| }.arity #=> -2
*
- * proc { |x=0| }.arity #=> 0
- * lambda { |x=0| }.arity #=> -1
- * proc { |x=0, y| }.arity #=> 1
- * lambda { |x=0, y| }.arity #=> -2
- * proc { |x=0, y=0| }.arity #=> 0
- * lambda { |x=0, y=0| }.arity #=> -1
- * proc { |x, y=0| }.arity #=> 1
- * lambda { |x, y=0| }.arity #=> -2
- * proc { |(x, y), z=0| }.arity #=> 1
- * lambda { |(x, y), z=0| }.arity #=> -2
+ * proc { |a=0| }.arity #=> 0
+ * lambda { |a=0| }.arity #=> -1
+ * proc { |a=0, b| }.arity #=> 1
+ * lambda { |a=0, b| }.arity #=> -2
+ * proc { |a=0, b=0| }.arity #=> 0
+ * lambda { |a=0, b=0| }.arity #=> -1
+ * proc { |a, b=0| }.arity #=> 1
+ * lambda { |a, b=0| }.arity #=> -2
+ * proc { |(a, b), c=0| }.arity #=> 1
+ * lambda { |(a, b), c=0| }.arity #=> -2
* proc { |a, x:0, y:0| }.arity #=> 1
* lambda { |a, x:0, y:0| }.arity #=> -2
*/
@@ -980,7 +1101,8 @@ rb_vm_block_min_max_arity(const struct rb_block *block, int *max)
return ifunc->argc.min;
}
case block_type_symbol:
- break;
+ *max = UNLIMITED_ARGUMENTS;
+ return 1;
}
*max = UNLIMITED_ARGUMENTS;
return 0;
@@ -1033,11 +1155,46 @@ block_setup(struct rb_block *block, VALUE block_handler)
}
int
+rb_block_pair_yield_optimizable(void)
+{
+ int min, max;
+ const rb_execution_context_t *ec = GET_EC();
+ rb_control_frame_t *cfp = ec->cfp;
+ VALUE block_handler = rb_vm_frame_block_handler(cfp);
+ struct rb_block block;
+
+ if (block_handler == VM_BLOCK_HANDLER_NONE) {
+ rb_raise(rb_eArgError, "no block given");
+ }
+
+ block_setup(&block, block_handler);
+ min = rb_vm_block_min_max_arity(&block, &max);
+
+ switch (vm_block_type(&block)) {
+ case block_handler_type_symbol:
+ return 0;
+
+ case block_handler_type_proc:
+ {
+ VALUE procval = block_handler;
+ rb_proc_t *proc;
+ GetProcPtr(procval, proc);
+ if (proc->is_lambda) return 0;
+ if (min != max) return 0;
+ return min > 1;
+ }
+
+ default:
+ return min > 1;
+ }
+}
+
+int
rb_block_arity(void)
{
int min, max;
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->ec.cfp;
+ const rb_execution_context_t *ec = GET_EC();
+ rb_control_frame_t *cfp = ec->cfp;
VALUE block_handler = rb_vm_frame_block_handler(cfp);
struct rb_block block;
@@ -1058,7 +1215,6 @@ rb_block_arity(void)
rb_proc_t *proc;
GetProcPtr(procval, proc);
return (proc->is_lambda ? min == max : max != UNLIMITED_ARGUMENTS) ? min : -min-1;
- /* fall through */
}
default:
@@ -1069,8 +1225,8 @@ rb_block_arity(void)
int
rb_block_min_max_arity(int *max)
{
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->ec.cfp;
+ const rb_execution_context_t *ec = GET_EC();
+ rb_control_frame_t *cfp = ec->cfp;
VALUE block_handler = rb_vm_frame_block_handler(cfp);
struct rb_block block;
@@ -1117,6 +1273,89 @@ rb_proc_get_iseq(VALUE self, int *is_proc)
return NULL;
}
+/* call-seq:
+ * prc == other -> true or false
+ * prc.eql?(other) -> true or false
+ *
+ * Two proc are the same if, and only if, they were created from the same code block.
+ *
+ * def return_block(&block)
+ * block
+ * end
+ *
+ * def pass_block_twice(&block)
+ * [return_block(&block), return_block(&block)]
+ * end
+ *
+ * block1, block2 = pass_block_twice { puts 'test' }
+ * # Blocks might be instantiated into Proc's lazily, so they may, or may not,
+ * # be the same object.
+ * # But they are produced from the same code block, so they are equal
+ * block1 == block2
+ * #=> true
+ *
+ * # Another Proc will never be equal, even if the code is the "same"
+ * block1 == proc { puts 'test' }
+ * #=> false
+ *
+ */
+static VALUE
+proc_eq(VALUE self, VALUE other)
+{
+ const rb_proc_t *self_proc, *other_proc;
+ const struct rb_block *self_block, *other_block;
+
+ if (rb_obj_class(self) != rb_obj_class(other)) {
+ return Qfalse;
+ }
+
+ GetProcPtr(self, self_proc);
+ GetProcPtr(other, other_proc);
+
+ if (self_proc->is_from_method != other_proc->is_from_method ||
+ self_proc->is_lambda != other_proc->is_lambda) {
+ return Qfalse;
+ }
+
+ self_block = &self_proc->block;
+ other_block = &other_proc->block;
+
+ if (vm_block_type(self_block) != vm_block_type(other_block)) {
+ return Qfalse;
+ }
+
+ switch (vm_block_type(self_block)) {
+ case block_type_iseq:
+ if (self_block->as.captured.ep != \
+ other_block->as.captured.ep ||
+ self_block->as.captured.code.iseq != \
+ other_block->as.captured.code.iseq) {
+ return Qfalse;
+ }
+ break;
+ case block_type_ifunc:
+ if (self_block->as.captured.ep != \
+ other_block->as.captured.ep ||
+ self_block->as.captured.code.ifunc != \
+ other_block->as.captured.code.ifunc) {
+ return Qfalse;
+ }
+ break;
+ case block_type_proc:
+ if (self_block->as.proc != other_block->as.proc) {
+ return Qfalse;
+ }
+ break;
+ case block_type_symbol:
+ if (self_block->as.symbol != other_block->as.symbol) {
+ return Qfalse;
+ }
+ break;
+ }
+
+ return Qtrue;
+}
+
static VALUE
iseq_location(const rb_iseq_t *iseq)
{
@@ -1130,6 +1369,12 @@ iseq_location(const rb_iseq_t *iseq)
return rb_ary_new4(2, loc);
}
+MJIT_FUNC_EXPORTED VALUE
+rb_iseq_location(const rb_iseq_t *iseq)
+{
+ return iseq_location(iseq);
+}
+
/*
* call-seq:
* prc.source_location -> [String, Integer]
@@ -1144,8 +1389,8 @@ rb_proc_location(VALUE self)
return iseq_location(rb_proc_get_iseq(self, 0));
}
-static VALUE
-unnamed_parameters(int arity)
+VALUE
+rb_unnamed_parameters(int arity)
{
VALUE a, param = rb_ary_new2((arity < 0) ? -arity : arity);
int n = (arity < 0) ? ~arity : arity;
@@ -1179,7 +1424,7 @@ rb_proc_parameters(VALUE self)
int is_proc;
const rb_iseq_t *iseq = rb_proc_get_iseq(self, &is_proc);
if (!iseq) {
- return unnamed_parameters(rb_proc_arity(self));
+ return rb_unnamed_parameters(rb_proc_arity(self));
}
return rb_iseq_parameters(iseq, is_proc);
}
@@ -1194,7 +1439,7 @@ rb_hash_proc(st_index_t hash, VALUE prc)
return rb_hash_uint(hash, (st_index_t)proc->block.as.captured.ep >> 16);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_sym_to_proc(VALUE sym)
{
static VALUE sym_proc_cache = Qfalse;
@@ -1202,7 +1447,6 @@ rb_sym_to_proc(VALUE sym)
VALUE proc;
long index;
ID id;
- VALUE *aryp;
if (!sym_proc_cache) {
sym_proc_cache = rb_ary_tmp_new(SYM_PROC_CACHE_SIZE * 2);
@@ -1213,14 +1457,13 @@ rb_sym_to_proc(VALUE sym)
id = SYM2ID(sym);
index = (id % SYM_PROC_CACHE_SIZE) << 1;
- aryp = RARRAY_PTR(sym_proc_cache);
- if (aryp[index] == sym) {
- return aryp[index + 1];
+ if (RARRAY_AREF(sym_proc_cache, index) == sym) {
+ return RARRAY_AREF(sym_proc_cache, index + 1);
}
else {
- proc = sym_proc_new(rb_cProc, ID2SYM(id));
- aryp[index] = sym;
- aryp[index + 1] = proc;
+ proc = sym_proc_new(rb_cProc, ID2SYM(id));
+ RARRAY_ASET(sym_proc_cache, index, sym);
+ RARRAY_ASET(sym_proc_cache, index + 1, proc);
return proc;
}
}
@@ -1258,7 +1501,7 @@ rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_i
case block_type_iseq:
{
const rb_iseq_t *iseq = rb_iseq_check(block->as.captured.code.iseq);
- rb_str_catf(str, "%p@%"PRIsVALUE":%d", (void *)self,
+ rb_str_catf(str, "%p %"PRIsVALUE":%d", (void *)self,
rb_iseq_path(iseq),
FIX2INT(iseq->body->location.first_lineno));
}
@@ -1267,13 +1510,12 @@ rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_i
rb_str_catf(str, "%p(&%+"PRIsVALUE")", (void *)self, block->as.symbol);
break;
case block_type_ifunc:
- rb_str_catf(str, "%p", block->as.captured.code.ifunc);
+ rb_str_catf(str, "%p", (void *)block->as.captured.code.ifunc);
break;
}
if (additional_info) rb_str_cat_cstr(str, additional_info);
rb_str_cat_cstr(str, ">");
- OBJ_INFECT_RAW(str, self);
return str;
}
@@ -1297,9 +1539,8 @@ proc_to_s(VALUE self)
* call-seq:
* prc.to_proc -> proc
*
- * Part of the protocol for converting objects to <code>Proc</code>
- * objects. Instances of class <code>Proc</code> simply return
- * themselves.
+ * Part of the protocol for converting objects to Proc objects.
+ * Instances of class Proc simply return themselves.
*/
static VALUE
@@ -1312,10 +1553,20 @@ static void
bm_mark(void *ptr)
{
struct METHOD *data = ptr;
- rb_gc_mark(data->recv);
- rb_gc_mark(data->klass);
- rb_gc_mark(data->iclass);
- rb_gc_mark((VALUE)data->me);
+ rb_gc_mark_movable(data->recv);
+ rb_gc_mark_movable(data->klass);
+ rb_gc_mark_movable(data->iclass);
+ rb_gc_mark_movable((VALUE)data->me);
+}
+
+static void
+bm_compact(void *ptr)
+{
+ struct METHOD *data = ptr;
+ UPDATE_REFERENCE(data->recv);
+ UPDATE_REFERENCE(data->klass);
+ UPDATE_REFERENCE(data->iclass);
+ UPDATE_TYPED_REFERENCE(rb_method_entry_t *, data->me);
}
static size_t
@@ -1330,6 +1581,7 @@ static const rb_data_type_t method_data_type = {
bm_mark,
RUBY_TYPED_DEFAULT_FREE,
bm_memsize,
+ bm_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -1376,12 +1628,19 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass)
RB_OBJ_WRITE(method, &data->me, me);
- OBJ_INFECT(method, klass);
-
return method;
}
static VALUE
+mnew_missing_by_name(VALUE klass, VALUE obj, VALUE *name, int scope, VALUE mclass)
+{
+ VALUE vid = rb_str_intern(*name);
+ *name = vid;
+ if (!respond_to_missing_p(klass, obj, vid, scope)) return Qfalse;
+ return mnew_missing(klass, obj, SYM2ID(vid), mclass);
+}
+
+static VALUE
mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
VALUE obj, ID id, VALUE mclass, int scope, int error)
{
@@ -1406,12 +1665,12 @@ mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
}
if (me->def->type == VM_METHOD_TYPE_ZSUPER) {
if (me->defined_class) {
- VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->defined_class));
+ VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->defined_class));
id = me->def->original_id;
- me = (rb_method_entry_t *)rb_callable_method_entry_without_refinements(klass, id, &iclass);
+ me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass, id, &iclass);
}
else {
- VALUE klass = RCLASS_SUPER(me->owner);
+ VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->owner));
id = me->def->original_id;
me = rb_method_entry_without_refinements(klass, id, &iclass);
}
@@ -1425,7 +1684,6 @@ mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
RB_OBJ_WRITE(method, &data->iclass, iclass);
RB_OBJ_WRITE(method, &data->me, me);
- OBJ_INFECT(method, klass);
return method;
}
@@ -1443,10 +1701,10 @@ mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)
VALUE iclass = Qnil;
if (obj == Qundef) { /* UnboundMethod */
- me = rb_method_entry_without_refinements(klass, id, &iclass);
+ me = rb_method_entry_with_refinements(klass, id, &iclass);
}
else {
- me = (rb_method_entry_t *)rb_callable_method_entry_without_refinements(klass, id, &iclass);
+ me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass, id, &iclass);
}
return mnew_from_me(me, klass, iclass, obj, id, mclass, scope);
}
@@ -1460,14 +1718,13 @@ method_entry_defined_class(const rb_method_entry_t *me)
/**********************************************************************
*
- * Document-class : Method
+ * Document-class: Method
*
- * Method objects are created by <code>Object#method</code>, and are
- * associated with a particular object (not just with a class). They
- * may be used to invoke the method within the object, and as a block
- * associated with an iterator. They may also be unbound from one
- * object (creating an <code>UnboundMethod</code>) and bound to
- * another.
+ * Method objects are created by Object#method, and are associated
+ * with a particular object (not just with a class). They may be
+ * used to invoke the method within the object, and as a block
+ * associated with an iterator. They may also be unbound from one
+ * object (creating an UnboundMethod) and bound to another.
*
* class Thing
* def square(n)
@@ -1480,6 +1737,11 @@ method_entry_defined_class(const rb_method_entry_t *me)
* meth.call(9) #=> 81
* [ 1, 2, 3 ].collect(&meth) #=> [1, 4, 9]
*
+ * [ 1, 2, 3 ].each(&method(:puts)) #=> prints 1, 2, 3
+ *
+ * require 'date'
+ * %w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
+ * #=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
*/
/*
@@ -1488,8 +1750,8 @@ method_entry_defined_class(const rb_method_entry_t *me)
* meth == other_meth -> true or false
*
* Two method objects are equal if they are bound to the same
- * object and refer to the same method definition and their owners are the
- * same class or module.
+ * object and refer to the same method definition and the classes
+ * defining the methods are the same class or module.
*/
static VALUE
@@ -1540,7 +1802,7 @@ method_hash(VALUE method)
hash = rb_hash_method_entry(hash, m->me);
hash = rb_hash_end(hash);
- return INT2FIX(hash);
+ return ST2FIX(hash);
}
/*
@@ -1548,8 +1810,8 @@ method_hash(VALUE method)
* meth.unbind -> unbound_method
*
* Dissociates <i>meth</i> from its current receiver. The resulting
- * <code>UnboundMethod</code> can subsequently be bound to a new object
- * of the same class (see <code>UnboundMethod</code>).
+ * UnboundMethod can subsequently be bound to a new object of the
+ * same class (see UnboundMethod).
*/
static VALUE
@@ -1563,8 +1825,8 @@ method_unbind(VALUE obj)
&method_data_type, data);
RB_OBJ_WRITE(method, &data->recv, Qundef);
RB_OBJ_WRITE(method, &data->klass, orig->klass);
+ RB_OBJ_WRITE(method, &data->iclass, orig->iclass);
RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
- OBJ_INFECT(method, obj);
return method;
}
@@ -1574,6 +1836,8 @@ method_unbind(VALUE obj)
* meth.receiver -> object
*
* Returns the bound receiver of the method object.
+ *
+ * (1..3).method(:map).receiver # => 1..3
*/
static VALUE
@@ -1628,6 +1892,9 @@ method_original_name(VALUE obj)
* meth.owner -> class_or_module
*
* Returns the class or module that defines the method.
+ * See also Method#receiver.
+ *
+ * (1..3).method(:map).owner #=> Enumerable
*/
static VALUE
@@ -1641,9 +1908,9 @@ method_owner(VALUE obj)
void
rb_method_name_error(VALUE klass, VALUE str)
{
-#define MSG(s) rb_fstring_cstr("undefined method `%1$s' for"s" `%2$s'")
+#define MSG(s) rb_fstring_lit("undefined method `%1$s' for"s" `%2$s'")
VALUE c = klass;
- VALUE s;
+ VALUE s = Qundef;
if (FL_TEST(c, FL_SINGLETON)) {
VALUE obj = rb_ivar_get(klass, attached);
@@ -1652,15 +1919,15 @@ rb_method_name_error(VALUE klass, VALUE str)
case T_MODULE:
case T_CLASS:
c = obj;
- s = MSG("");
+ break;
+ default:
+ break;
}
- goto normal_class;
}
else if (RB_TYPE_P(c, T_MODULE)) {
s = MSG(" module");
}
- else {
- normal_class:
+ if (s == Qundef) {
s = MSG(" class");
}
rb_name_err_raise_str(s, c, str);
@@ -1675,10 +1942,8 @@ obj_method(VALUE obj, VALUE vid, int scope)
const VALUE mclass = rb_cMethod;
if (!id) {
- if (respond_to_missing_p(klass, obj, vid, scope)) {
- id = rb_intern_str(vid);
- return mnew_missing(klass, obj, id, mclass);
- }
+ VALUE m = mnew_missing_by_name(klass, obj, &vid, scope, mclass);
+ if (m) return m;
rb_method_name_error(klass, vid);
}
return mnew(klass, obj, id, mclass, scope);
@@ -1689,10 +1954,9 @@ obj_method(VALUE obj, VALUE vid, int scope)
* obj.method(sym) -> method
*
* Looks up the named method as a receiver in <i>obj</i>, returning a
- * <code>Method</code> object (or raising <code>NameError</code>). The
- * <code>Method</code> object acts as a closure in <i>obj</i>'s object
- * instance, so instance variables and the value of <code>self</code>
- * remain available.
+ * Method object (or raising NameError). The Method object acts as a
+ * closure in <i>obj</i>'s object instance, so instance variables and
+ * the value of <code>self</code> remain available.
*
* class Demo
* def initialize(n)
@@ -1710,6 +1974,18 @@ obj_method(VALUE obj, VALUE vid, int scope)
* l = Demo.new('Fred')
* m = l.method("hello")
* m.call #=> "Hello, @iv = Fred"
+ *
+ * Note that Method implements <code>to_proc</code> method, which
+ * means it can be used with iterators.
+ *
+ * [ 1, 2, 3 ].each(&method(:puts)) # => prints 3 lines to stdout
+ *
+ * out = File.open('test.txt', 'w')
+ * [ 1, 2, 3 ].each(&out.method(:puts)) # => prints 3 lines to file
+ *
+ * require 'date'
+ * %w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
+ * #=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
*/
VALUE
@@ -1758,27 +2034,39 @@ rb_obj_public_method(VALUE obj, VALUE vid)
VALUE
rb_obj_singleton_method(VALUE obj, VALUE vid)
{
- const rb_method_entry_t *me;
- VALUE klass;
+ VALUE klass = rb_singleton_class_get(obj);
ID id = rb_check_id(&vid);
- if (!id) {
- if (!NIL_P(klass = rb_singleton_class_get(obj)) &&
- respond_to_missing_p(klass, obj, vid, FALSE)) {
- id = rb_intern_str(vid);
- return mnew_missing(klass, obj, id, rb_cMethod);
- }
- undef:
- rb_name_err_raise("undefined singleton method `%1$s' for `%2$s'",
- obj, vid);
+ if (NIL_P(klass)) {
+ /* goto undef; */
+ }
+ else if (NIL_P(klass = RCLASS_ORIGIN(klass))) {
+ /* goto undef; */
}
- if (NIL_P(klass = rb_singleton_class_get(obj)) ||
- UNDEFINED_METHOD_ENTRY_P(me = rb_method_entry_at(klass, id)) ||
- UNDEFINED_REFINED_METHOD_P(me->def)) {
- vid = ID2SYM(id);
- goto undef;
+ else if (! id) {
+ VALUE m = mnew_missing_by_name(klass, obj, &vid, FALSE, rb_cMethod);
+ if (m) return m;
+ /* else goto undef; */
}
- return mnew_from_me(me, klass, klass, obj, id, rb_cMethod, FALSE);
+ else {
+ const rb_method_entry_t *me = rb_method_entry_at(klass, id);
+ vid = ID2SYM(id);
+
+ if (UNDEFINED_METHOD_ENTRY_P(me)) {
+ /* goto undef; */
+ }
+ else if (UNDEFINED_REFINED_METHOD_P(me->def)) {
+ /* goto undef; */
+ }
+ else {
+ return mnew_from_me(me, klass, klass, obj, id, rb_cMethod, FALSE);
+ }
+ }
+
+ /* undef: */
+ rb_name_err_raise("undefined singleton method `%1$s' for `%2$s'",
+ obj, vid);
+ UNREACHABLE_RETURN(Qundef);
}
/*
@@ -1846,19 +2134,20 @@ rb_mod_public_instance_method(VALUE mod, VALUE vid)
*
* Defines an instance method in the receiver. The _method_
* parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
- * If a block is specified, it is used as the method body. This block
- * is evaluated using <code>instance_eval</code>, a point that is
- * tricky to demonstrate because <code>define_method</code> is private.
- * (This is why we resort to the +send+ hack in this example.)
+ * If a block is specified, it is used as the method body.
+ * If a block or the _method_ parameter has parameters,
+ * they're used as method parameters.
+ * This block is evaluated using #instance_eval.
*
* class A
* def fred
* puts "In Fred"
* end
* def create_method(name, &block)
- * self.class.send(:define_method, name, &block)
+ * self.class.define_method(name, &block)
* end
* define_method(:wilma) { puts "Charge it!" }
+ * define_method(:flint) {|name| puts "I'm #{name}!"}
* end
* class B < A
* define_method(:barney, instance_method(:fred))
@@ -1866,6 +2155,7 @@ rb_mod_public_instance_method(VALUE mod, VALUE vid)
* a = B.new
* a.barney
* a.wilma
+ * a.flint('Dino')
* a.create_method(:betty) { p self }
* a.betty
*
@@ -1873,6 +2163,7 @@ rb_mod_public_instance_method(VALUE mod, VALUE vid)
*
* In Fred
* Charge it!
+ * I'm Dino!
* #<B:0x401b39e8>
*/
@@ -1895,25 +2186,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
name = argv[0];
id = rb_check_id(&name);
if (argc == 1) {
-#if PROC_NEW_REQUIRES_BLOCK
body = rb_block_lambda();
-#else
- rb_thread_t *th = GET_THREAD();
- VALUE block_handler = rb_vm_frame_block_handler(th->ec.cfp);
- if (block_handler == VM_BLOCK_HANDLER_NONE) rb_raise(rb_eArgError, proc_without_block);
-
- switch (vm_block_handler_type(block_handler)) {
- case block_handler_type_proc:
- body = VM_BH_TO_PROC(block_handler);
- break;
- case block_handler_type_symbol:
- body = rb_sym_to_proc(VM_BH_TO_SYMBOL(block_handler));
- break;
- case block_handler_type_iseq:
- case block_handler_type_ifunc:
- body = rb_vm_make_proc_lambda(th, VM_BH_TO_CAPT_BLOCK(block_handler), rb_cProc, TRUE);
- }
-#endif
}
else {
body = argv[1];
@@ -1926,7 +2199,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
}
else {
rb_raise(rb_eTypeError,
- "wrong argument type %s (expected Proc/Method)",
+ "wrong argument type %s (expected Proc/Method/UnboundMethod)",
rb_obj_classname(body));
}
}
@@ -1953,7 +2226,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
RB_GC_GUARD(body);
}
else {
- VALUE procval = proc_dup(body);
+ VALUE procval = rb_proc_dup(body);
if (vm_proc_iseq(procval) != NULL) {
rb_proc_t *proc;
GetProcPtr(procval, proc);
@@ -1977,6 +2250,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
* Defines a singleton method in the receiver. The _method_
* parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object.
* If a block is specified, it is used as the method body.
+ * If a block or a method has parameters, they're used as method parameters.
*
* class A
* class << self
@@ -1993,6 +2267,10 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
* guy = "Bob"
* guy.define_singleton_method(:hello) { "#{self}: Hello there!" }
* guy.hello #=> "Bob: Hello there!"
+ *
+ * chris = "Chris"
+ * chris.define_singleton_method(:greet) {|greeting| "#{greeting}, I'm Chris!" }
+ * chris.greet("Hi") #=> "Hi, I'm Chris!"
*/
static VALUE
@@ -2054,14 +2332,45 @@ method_clone(VALUE self)
CLONESETUP(clone, self);
RB_OBJ_WRITE(clone, &data->recv, orig->recv);
RB_OBJ_WRITE(clone, &data->klass, orig->klass);
+ RB_OBJ_WRITE(clone, &data->iclass, orig->iclass);
RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
return clone;
}
+/* Document-method: Method#===
+ *
+ * call-seq:
+ * method === obj -> result_of_method
+ *
+ * Invokes the method with +obj+ as the parameter like #call.
+ * This allows a method object to be the target of a +when+ clause
+ * in a case statement.
+ *
+ * require 'prime'
+ *
+ * case 1373
+ * when Prime.method(:prime?)
+ * # ...
+ * end
+ */
+
+
+/* Document-method: Method#[]
+ *
+ * call-seq:
+ * meth[args, ...] -> obj
+ *
+ * Invokes the <i>meth</i> with the specified arguments, returning the
+ * method's return value, like #call.
+ *
+ * m = 12.method("+")
+ * m[3] #=> 15
+ * m[20] #=> 32
+ */
+
/*
* call-seq:
* meth.call(args, ...) -> obj
- * meth[args, ...] -> obj
*
* Invokes the <i>meth</i> with the specified arguments, returning the
* method's return value.
@@ -2071,6 +2380,20 @@ method_clone(VALUE self)
* m.call(20) #=> 32
*/
+static VALUE
+rb_method_call_pass_called_kw(int argc, const VALUE *argv, VALUE method)
+{
+ VALUE procval = rb_block_given_p() ? rb_block_proc() : Qnil;
+ return rb_method_call_with_block_kw(argc, argv, method, procval, RB_PASS_CALLED_KEYWORDS);
+}
+
+VALUE
+rb_method_call_kw(int argc, const VALUE *argv, VALUE method, int kw_splat)
+{
+ VALUE procval = rb_block_given_p() ? rb_block_proc() : Qnil;
+ return rb_method_call_with_block_kw(argc, argv, method, procval, kw_splat);
+}
+
VALUE
rb_method_call(int argc, const VALUE *argv, VALUE method)
{
@@ -2086,71 +2409,47 @@ method_callable_method_entry(const struct METHOD *data)
}
static inline VALUE
-call_method_data(rb_thread_t *th, const struct METHOD *data,
- int argc, const VALUE *argv, VALUE passed_procval)
+call_method_data(rb_execution_context_t *ec, const struct METHOD *data,
+ int argc, const VALUE *argv, VALUE passed_procval, int kw_splat)
{
- vm_passed_block_handler_set(th, proc_to_block_handler(passed_procval));
- return rb_vm_call(th, data->recv, data->me->called_id, argc, argv,
- method_callable_method_entry(data));
-}
-
-static VALUE
-call_method_data_safe(rb_thread_t *th, const struct METHOD *data,
- int argc, const VALUE *argv, VALUE passed_procval,
- int safe)
-{
- VALUE result = Qnil; /* OK */
- enum ruby_tag_type state;
-
- TH_PUSH_TAG(th);
- if ((state = TH_EXEC_TAG()) == TAG_NONE) {
- /* result is used only if state == 0, no exceptions is caught. */
- /* otherwise it doesn't matter even if clobbered. */
- NO_CLOBBERED(result) = call_method_data(th, data, argc, argv, passed_procval);
- }
- TH_POP_TAG();
- rb_set_safe_level_force(safe);
- if (state)
- TH_JUMP_TAG(th, state);
- return result;
+ vm_passed_block_handler_set(ec, proc_to_block_handler(passed_procval));
+ return rb_vm_call_kw(ec, data->recv, data->me->called_id, argc, argv,
+ method_callable_method_entry(data), kw_splat);
}
VALUE
-rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE passed_procval)
+rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE method, VALUE passed_procval, int kw_splat)
{
const struct METHOD *data;
- rb_thread_t *const th = GET_THREAD();
+ rb_execution_context_t *ec = GET_EC();
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
if (data->recv == Qundef) {
rb_raise(rb_eTypeError, "can't call unbound method; bind first");
}
- if (OBJ_TAINTED(method)) {
- const int safe_level_to_run = RUBY_SAFE_LEVEL_MAX;
- int safe = rb_safe_level();
- if (safe < safe_level_to_run) {
- rb_set_safe_level_force(safe_level_to_run);
- return call_method_data_safe(th, data, argc, argv, passed_procval, safe);
- }
- }
- return call_method_data(th, data, argc, argv, passed_procval);
+ return call_method_data(ec, data, argc, argv, passed_procval, kw_splat);
+}
+
+VALUE
+rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE passed_procval)
+{
+ return rb_method_call_with_block_kw(argc, argv, method, passed_procval, RB_NO_KEYWORDS);
}
/**********************************************************************
*
* Document-class: UnboundMethod
*
- * Ruby supports two forms of objectified methods. Class
- * <code>Method</code> is used to represent methods that are associated
- * with a particular object: these method objects are bound to that
- * object. Bound method objects for an object can be created using
- * <code>Object#method</code>.
+ * Ruby supports two forms of objectified methods. Class Method is
+ * used to represent methods that are associated with a particular
+ * object: these method objects are bound to that object. Bound
+ * method objects for an object can be created using Object#method.
*
* Ruby also supports unbound methods; methods objects that are not
- * associated with a particular object. These can be created either by
- * calling <code>Module#instance_method</code> or by calling
- * <code>unbind</code> on a bound method object. The result of both of
- * these is an <code>UnboundMethod</code> object.
+ * associated with a particular object. These can be created either
+ * by calling Module#instance_method or by calling #unbind on a bound
+ * method object. The result of both of these is an UnboundMethod
+ * object.
*
* Unbound methods can only be called after they are bound to an
* object. That object must be a kind_of? the method's original
@@ -2192,13 +2491,60 @@ rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE passe
*
*/
+static void
+convert_umethod_to_method_components(VALUE method, VALUE recv, VALUE *methclass_out, VALUE *klass_out, VALUE *iclass_out, const rb_method_entry_t **me_out)
+{
+ struct METHOD *data;
+
+ TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
+
+ VALUE methclass = data->me->owner;
+ VALUE iclass = data->me->defined_class;
+ VALUE klass = CLASS_OF(recv);
+
+ if (RB_TYPE_P(methclass, T_MODULE)) {
+ VALUE refined_class = rb_refinement_module_get_refined_class(methclass);
+ if (!NIL_P(refined_class)) methclass = refined_class;
+ }
+ if (!RB_TYPE_P(methclass, T_MODULE) &&
+ methclass != CLASS_OF(recv) && !rb_obj_is_kind_of(recv, methclass)) {
+ if (FL_TEST(methclass, FL_SINGLETON)) {
+ rb_raise(rb_eTypeError,
+ "singleton method called for a different object");
+ }
+ else {
+ rb_raise(rb_eTypeError, "bind argument must be an instance of % "PRIsVALUE,
+ methclass);
+ }
+ }
+
+ const rb_method_entry_t *me = rb_method_entry_clone(data->me);
+
+ if (RB_TYPE_P(me->owner, T_MODULE)) {
+ VALUE ic = rb_class_search_ancestor(klass, me->owner);
+ if (ic) {
+ klass = ic;
+ iclass = ic;
+ }
+ else {
+ klass = rb_include_class_new(methclass, klass);
+ }
+ me = (const rb_method_entry_t *) rb_method_entry_complement_defined_class(me, me->called_id, klass);
+ }
+
+ *methclass_out = methclass;
+ *klass_out = klass;
+ *iclass_out = iclass;
+ *me_out = me;
+}
+
/*
* call-seq:
* umeth.bind(obj) -> method
*
- * Bind <i>umeth</i> to <i>obj</i>. If <code>Klass</code> was the class
- * from which <i>umeth</i> was obtained,
- * <code>obj.kind_of?(Klass)</code> must be true.
+ * Bind <i>umeth</i> to <i>obj</i>. If Klass was the class from which
+ * <i>umeth</i> was obtained, <code>obj.kind_of?(Klass)</code> must
+ * be true.
*
* class A
* def test
@@ -2230,44 +2576,45 @@ rb_method_call_with_block(int argc, const VALUE *argv, VALUE method, VALUE passe
static VALUE
umethod_bind(VALUE method, VALUE recv)
{
- struct METHOD *data, *bound;
- VALUE methclass, klass;
-
- TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
+ VALUE methclass, klass, iclass;
+ const rb_method_entry_t *me;
+ convert_umethod_to_method_components(method, recv, &methclass, &klass, &iclass, &me);
- methclass = data->me->owner;
+ struct METHOD *bound;
+ method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
+ RB_OBJ_WRITE(method, &bound->recv, recv);
+ RB_OBJ_WRITE(method, &bound->klass, klass);
+ RB_OBJ_WRITE(method, &bound->iclass, iclass);
+ RB_OBJ_WRITE(method, &bound->me, me);
- if (!RB_TYPE_P(methclass, T_MODULE) &&
- methclass != CLASS_OF(recv) && !rb_obj_is_kind_of(recv, methclass)) {
- if (FL_TEST(methclass, FL_SINGLETON)) {
- rb_raise(rb_eTypeError,
- "singleton method called for a different object");
- }
- else {
- rb_raise(rb_eTypeError, "bind argument must be an instance of % "PRIsVALUE,
- methclass);
- }
- }
+ return method;
+}
- klass = CLASS_OF(recv);
+/*
+ * call-seq:
+ * umeth.bind_call(recv, args, ...) -> obj
+ *
+ * Bind <i>umeth</i> to <i>recv</i> and then invokes the method with the
+ * specified arguments.
+ * This is semantically equivalent to <code>umeth.bind(recv).call(args, ...)</code>.
+ */
+static VALUE
+umethod_bind_call(int argc, VALUE *argv, VALUE method)
+{
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
+ VALUE recv = argv[0];
+ argc--;
+ argv++;
- method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
- RB_OBJ_WRITE(method, &bound->recv, recv);
- RB_OBJ_WRITE(method, &bound->klass, data->klass);
- RB_OBJ_WRITE(method, &bound->me, rb_method_entry_clone(data->me));
+ VALUE methclass, klass, iclass;
+ const rb_method_entry_t *me;
+ convert_umethod_to_method_components(method, recv, &methclass, &klass, &iclass, &me);
+ struct METHOD bound = { recv, klass, 0, me };
- if (RB_TYPE_P(bound->me->owner, T_MODULE)) {
- VALUE ic = rb_class_search_ancestor(klass, bound->me->owner);
- if (ic) {
- klass = ic;
- }
- else {
- klass = rb_include_class_new(methclass, klass);
- }
- RB_OBJ_WRITE(method, &bound->me, rb_method_entry_complement_defined_class(bound->me, bound->me->called_id, klass));
- }
+ VALUE passed_procval = rb_block_given_p() ? rb_block_proc() : Qnil;
- return method;
+ rb_execution_context_t *ec = GET_EC();
+ return call_method_data(ec, &bound, argc, argv, passed_procval, RB_PASS_CALLED_KEYWORDS);
}
/*
@@ -2300,7 +2647,7 @@ rb_method_entry_min_max_arity(const rb_method_entry_t *me, int *max)
def = def->body.alias.original_me->def;
goto again;
case VM_METHOD_TYPE_BMETHOD:
- return rb_proc_min_max_arity(def->body.proc, max);
+ return rb_proc_min_max_arity(def->body.bmethod.proc, max);
case VM_METHOD_TYPE_ISEQ:
return rb_iseq_min_max_arity(rb_iseq_check(def->body.iseq.iseqptr), max);
case VM_METHOD_TYPE_UNDEF:
@@ -2317,6 +2664,9 @@ rb_method_entry_min_max_arity(const rb_method_entry_t *me, int *max)
case OPTIMIZED_METHOD_TYPE_CALL:
*max = UNLIMITED_ARGUMENTS;
return 0;
+ case OPTIMIZED_METHOD_TYPE_BLOCK_CALL:
+ *max = UNLIMITED_ARGUMENTS;
+ return 0;
default:
break;
}
@@ -2327,7 +2677,7 @@ rb_method_entry_min_max_arity(const rb_method_entry_t *me, int *max)
return 0;
}
rb_bug("rb_method_entry_min_max_arity: invalid method entry type (%d)", def->type);
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
int
@@ -2344,8 +2694,10 @@ rb_method_entry_arity(const rb_method_entry_t *me)
* Returns an indication of the number of arguments accepted by a
* method. Returns a nonnegative integer for methods that take a fixed
* number of arguments. For Ruby methods that take a variable number of
- * arguments, returns -n-1, where n is the number of required
- * arguments. For methods written in C, returns -1 if the call takes a
+ * arguments, returns -n-1, where n is the number of required arguments.
+ * Keyword arguments will be considered as a single additional argument,
+ * that argument being mandatory if any keyword argument is mandatory.
+ * For methods written in C, returns -1 if the call takes a
* variable number of arguments.
*
* class C
@@ -2355,6 +2707,10 @@ rb_method_entry_arity(const rb_method_entry_t *me)
* def four(a, b); end
* def five(a, b, *c); end
* def six(a, b, *c, &d); end
+ * def seven(a, b, x:0); end
+ * def eight(x:, y:); end
+ * def nine(x:, y:, **z); end
+ * def ten(*a, x:, y:); end
* end
* c = C.new
* c.method(:one).arity #=> 0
@@ -2363,6 +2719,10 @@ rb_method_entry_arity(const rb_method_entry_t *me)
* c.method(:four).arity #=> 2
* c.method(:five).arity #=> -3
* c.method(:six).arity #=> -3
+ * c.method(:seven).arity #=> -3
+ * c.method(:eight).arity #=> 1
+ * c.method(:nine).arity #=> 1
+ * c.method(:ten).arity #=> -2
*
* "cat".method(:size).arity #=> 0
* "cat".method(:replace).arity #=> 1
@@ -2423,8 +2783,23 @@ rb_obj_method_arity(VALUE obj, ID id)
return rb_mod_method_arity(CLASS_OF(obj), id);
}
-static inline const rb_method_definition_t *
-method_def(VALUE method)
+VALUE
+rb_callable_receiver(VALUE callable)
+{
+ if (rb_obj_is_proc(callable)) {
+ VALUE binding = proc_binding(callable);
+ return rb_funcall(binding, rb_intern("receiver"), 0);
+ }
+ else if (rb_obj_is_method(callable)) {
+ return method_receiver(callable);
+ }
+ else {
+ return Qundef;
+ }
+}
+
+const rb_method_definition_t *
+rb_method_def(VALUE method)
{
const struct METHOD *data;
@@ -2439,7 +2814,7 @@ method_def_iseq(const rb_method_definition_t *def)
case VM_METHOD_TYPE_ISEQ:
return rb_iseq_check(def->body.iseq.iseqptr);
case VM_METHOD_TYPE_BMETHOD:
- return rb_proc_get_iseq(def->body.proc, 0);
+ return rb_proc_get_iseq(def->body.bmethod.proc, 0);
case VM_METHOD_TYPE_ALIAS:
return method_def_iseq(def->body.alias.original_me->def);
case VM_METHOD_TYPE_CFUNC:
@@ -2459,13 +2834,13 @@ method_def_iseq(const rb_method_definition_t *def)
const rb_iseq_t *
rb_method_iseq(VALUE method)
{
- return method_def_iseq(method_def(method));
+ return method_def_iseq(rb_method_def(method));
}
static const rb_cref_t *
method_cref(VALUE method)
{
- const rb_method_definition_t *def = method_def(method);
+ const rb_method_definition_t *def = rb_method_def(method);
again:
switch (def->type) {
@@ -2497,19 +2872,6 @@ rb_method_entry_location(const rb_method_entry_t *me)
return method_def_location(me->def);
}
-VALUE
-rb_mod_method_location(VALUE mod, ID id)
-{
- const rb_method_entry_t *me = original_method_entry(mod, id);
- return rb_method_entry_location(me);
-}
-
-VALUE
-rb_obj_method_location(VALUE obj, ID id)
-{
- return rb_mod_method_location(CLASS_OF(obj), id);
-}
-
/*
* call-seq:
* meth.source_location -> [String, Integer]
@@ -2521,7 +2883,7 @@ rb_obj_method_location(VALUE obj, ID id)
VALUE
rb_method_location(VALUE method)
{
- return method_def_location(method_def(method));
+ return method_def_location(rb_method_def(method));
}
/*
@@ -2548,7 +2910,7 @@ rb_method_parameters(VALUE method)
{
const rb_iseq_t *iseq = rb_method_iseq(method);
if (!iseq) {
- return unnamed_parameters(method_arity(method));
+ return rb_unnamed_parameters(method_arity(method));
}
return rb_iseq_parameters(iseq, 0);
}
@@ -2558,9 +2920,32 @@ rb_method_parameters(VALUE method)
* meth.to_s -> string
* meth.inspect -> string
*
- * Returns the name of the underlying method.
+ * Returns a human-readable description of the underlying method.
+ *
+ * "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
+ * (1..3).method(:map).inspect #=> "#<Method: Range(Enumerable)#map()>"
+ *
+ * In the latter case, the method description includes the "owner" of the
+ * original method (+Enumerable+ module, which is included into +Range+).
*
- * "cat".method(:count).inspect #=> "#<Method: String#count>"
+ * +inspect+ also provides, when possible, method argument names (call
+ * sequence) and source location.
+ *
+ * require 'net/http'
+ * Net::HTTP.method(:get).inspect
+ * #=> "#<Method: Net::HTTP.get(uri_or_host, path=..., port=...) <skip>/lib/ruby/2.7.0/net/http.rb:457>"
+ *
+ * <code>...</code> in argument definition means argument is optional (has
+ * some default value).
+ *
+ * For methods defined in C (language core and extensions), location and
+ * argument names can't be extracted, and only generic information is provided
+ * in form of <code>*</code> (any number of arguments) or <code>_</code> (some
+ * positional argument).
+ *
+ * "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
+ * "cat".method(:+).inspect #=> "#<Method: String#+(_)>""
+
*/
static VALUE
@@ -2574,9 +2959,17 @@ method_inspect(VALUE method)
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method));
- OBJ_INFECT_RAW(str, method);
- mklass = data->klass;
+ mklass = data->iclass;
+ if (!mklass) mklass = data->klass;
+
+ if (RB_TYPE_P(mklass, T_ICLASS)) {
+ /* TODO: I'm not sure why mklass is T_ICLASS.
+ * UnboundMethod#bind() can set it as T_ICLASS at convert_umethod_to_method_components()
+ * but not sure it is needed.
+ */
+ mklass = RBASIC_CLASS(mklass);
+ }
if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
defined_class = data->me->def->body.alias.original_me->owner;
@@ -2608,6 +3001,15 @@ method_inspect(VALUE method)
}
}
else {
+ mklass = data->klass;
+ if (FL_TEST(mklass, FL_SINGLETON)) {
+ VALUE v = rb_ivar_get(mklass, attached);
+ if (!(RB_TYPE_P(v, T_CLASS) || RB_TYPE_P(v, T_MODULE))) {
+ do {
+ mklass = RCLASS_SUPER(mklass);
+ } while (RB_TYPE_P(mklass, T_ICLASS));
+ }
+ }
rb_str_buf_append(str, rb_inspect(mklass));
if (defined_class != mklass) {
rb_str_catf(str, "(% "PRIsVALUE")", defined_class);
@@ -2622,6 +3024,100 @@ method_inspect(VALUE method)
if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
rb_str_buf_cat2(str, " (not-implemented)");
}
+
+ // parameter information
+ {
+ VALUE params = rb_method_parameters(method);
+ VALUE pair, name, kind;
+ const VALUE req = ID2SYM(rb_intern("req"));
+ const VALUE opt = ID2SYM(rb_intern("opt"));
+ const VALUE keyreq = ID2SYM(rb_intern("keyreq"));
+ const VALUE key = ID2SYM(rb_intern("key"));
+ const VALUE rest = ID2SYM(rb_intern("rest"));
+ const VALUE keyrest = ID2SYM(rb_intern("keyrest"));
+ const VALUE block = ID2SYM(rb_intern("block"));
+ const VALUE nokey = ID2SYM(rb_intern("nokey"));
+ int forwarding = 0;
+
+ rb_str_buf_cat2(str, "(");
+
+ for (int i = 0; i < RARRAY_LEN(params); i++) {
+ pair = RARRAY_AREF(params, i);
+ kind = RARRAY_AREF(pair, 0);
+ name = RARRAY_AREF(pair, 1);
+ // FIXME: in tests it turns out that kind, name = [:req] produces name to be false. Why?..
+ if (NIL_P(name) || name == Qfalse) {
+ // FIXME: can it be reduced to switch/case?
+ if (kind == req || kind == opt) {
+ name = rb_str_new2("_");
+ }
+ else if (kind == rest || kind == keyrest) {
+ name = rb_str_new2("");
+ }
+ else if (kind == block) {
+ name = rb_str_new2("block");
+ }
+ else if (kind == nokey) {
+ name = rb_str_new2("nil");
+ }
+ }
+
+ if (kind == req) {
+ rb_str_catf(str, "%"PRIsVALUE, name);
+ }
+ else if (kind == opt) {
+ rb_str_catf(str, "%"PRIsVALUE"=...", name);
+ }
+ else if (kind == keyreq) {
+ rb_str_catf(str, "%"PRIsVALUE":", name);
+ }
+ else if (kind == key) {
+ rb_str_catf(str, "%"PRIsVALUE": ...", name);
+ }
+ else if (kind == rest) {
+ if (name == ID2SYM('*')) {
+ forwarding = 1;
+ rb_str_cat_cstr(str, "...");
+ }
+ else {
+ rb_str_catf(str, "*%"PRIsVALUE, name);
+ }
+ }
+ else if (kind == keyrest) {
+ rb_str_catf(str, "**%"PRIsVALUE, name);
+ }
+ else if (kind == block) {
+ if (name == ID2SYM('&')) {
+ if (forwarding) {
+ rb_str_set_len(str, RSTRING_LEN(str) - 2);
+ }
+ else {
+ rb_str_cat_cstr(str, "...");
+ }
+ }
+ else {
+ rb_str_catf(str, "&%"PRIsVALUE, name);
+ }
+ }
+ else if (kind == nokey) {
+ rb_str_buf_cat2(str, "**nil");
+ }
+
+ if (i < RARRAY_LEN(params) - 1) {
+ rb_str_buf_cat2(str, ", ");
+ }
+ }
+ rb_str_buf_cat2(str, ")");
+ }
+
+ { // source location
+ VALUE loc = rb_method_location(method);
+ if (!NIL_P(loc)) {
+ rb_str_catf(str, " %"PRIsVALUE":%"PRIsVALUE,
+ RARRAY_AREF(loc, 0), RARRAY_AREF(loc, 1));
+ }
+ }
+
rb_str_buf_cat2(str, ">");
return str;
@@ -2640,14 +3136,14 @@ mlambda(VALUE method)
}
static VALUE
-bmcall(VALUE args, VALUE method, int argc, VALUE *argv, VALUE passed_proc)
+bmcall(RB_BLOCK_CALL_FUNC_ARGLIST(args, method))
{
- return rb_method_call_with_block(argc, argv, method, passed_proc);
+ return rb_method_call_with_block_kw(argc, argv, method, blockarg, RB_PASS_CALLED_KEYWORDS);
}
VALUE
rb_proc_new(
- VALUE (*func)(ANYARGS), /* VALUE yieldarg[, VALUE procarg] */
+ rb_block_call_func_t func,
VALUE val)
{
VALUE procval = rb_iterate(mproc, 0, func, val);
@@ -2658,7 +3154,7 @@ rb_proc_new(
* call-seq:
* meth.to_proc -> proc
*
- * Returns a <code>Proc</code> object corresponding to this method.
+ * Returns a Proc object corresponding to this method.
*/
static VALUE
@@ -2682,6 +3178,8 @@ method_to_proc(VALUE method)
return procval;
}
+extern VALUE rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner);
+
/*
* call-seq:
* meth.super_method -> method
@@ -2700,10 +3198,18 @@ method_super_method(VALUE method)
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
iclass = data->iclass;
- super_class = RCLASS_SUPER(RCLASS_ORIGIN(iclass));
- mid = data->me->called_id;
+ if (!iclass) return Qnil;
+ if (data->me->def->type == VM_METHOD_TYPE_ALIAS && data->me->defined_class) {
+ super_class = RCLASS_SUPER(rb_find_defined_class_by_owner(data->me->defined_class,
+ data->me->def->body.alias.original_me->owner));
+ mid = data->me->def->body.alias.original_me->def->original_id;
+ }
+ else {
+ super_class = RCLASS_SUPER(RCLASS_ORIGIN(iclass));
+ mid = data->me->def->original_id;
+ }
if (!super_class) return Qnil;
- me = (rb_method_entry_t *)rb_callable_method_entry_without_refinements(super_class, mid, &iclass);
+ me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(super_class, mid, &iclass);
if (!me) return Qnil;
return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE);
}
@@ -2763,9 +3269,7 @@ env_clone(const rb_env_t *env, const rb_cref_t *cref)
* call-seq:
* prc.binding -> binding
*
- * Returns the binding associated with <i>prc</i>. Note that
- * <code>Kernel#eval</code> accepts either a <code>Proc</code> or a
- * <code>Binding</code> object as its second parameter.
+ * Returns the binding associated with <i>prc</i>.
*
* def fred(param)
* proc {}
@@ -2787,6 +3291,8 @@ proc_binding(VALUE self)
GetProcPtr(self, proc);
block = &proc->block;
+ if (proc->is_isolated) rb_raise(rb_eArgError, "Can't create Binding from isolated Proc");
+
again:
switch (vm_block_type(block)) {
case block_type_iseq:
@@ -2798,27 +3304,27 @@ proc_binding(VALUE self)
GetProcPtr(block->as.proc, proc);
block = &proc->block;
goto again;
- case block_type_symbol:
- goto error;
case block_type_ifunc:
{
const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
if (IS_METHOD_PROC_IFUNC(ifunc)) {
VALUE method = (VALUE)ifunc->data;
+ VALUE name = rb_fstring_lit("<empty_iseq>");
+ rb_iseq_t *empty;
binding_self = method_receiver(method);
iseq = rb_method_iseq(method);
env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
env = env_clone(env, method_cref(method));
/* set empty iseq */
- RB_OBJ_WRITE(env, &env->iseq, rb_iseq_new(NULL, rb_str_new2("<empty iseq>"), rb_str_new2("<empty_iseq>"), Qnil, 0, ISEQ_TYPE_TOP));
+ empty = rb_iseq_new(NULL, name, name, Qnil, 0, ISEQ_TYPE_TOP);
+ RB_OBJ_WRITE(env, &env->iseq, empty);
break;
}
- else {
- error:
- rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
- return Qnil;
- }
}
+ /* FALLTHROUGH */
+ case block_type_symbol:
+ rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
+ UNREACHABLE_RETURN(Qnil);
}
bindval = rb_binding_alloc(rb_cBinding);
@@ -2835,14 +3341,14 @@ proc_binding(VALUE self)
}
else {
RB_OBJ_WRITE(bindval, &bind->pathobj,
- rb_iseq_pathobj_new(rb_fstring_cstr("(binding)"), Qnil));
+ rb_iseq_pathobj_new(rb_fstring_lit("(binding)"), Qnil));
bind->first_lineno = 1;
}
return bindval;
}
-static VALUE curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc);
+static rb_block_call_func curry;
static VALUE
make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
@@ -2862,7 +3368,7 @@ make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
}
static VALUE
-curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc)
+curry(RB_BLOCK_CALL_FUNC_ARGLIST(_, args))
{
VALUE proc, passed, arity;
proc = RARRAY_AREF(args, 0);
@@ -2873,14 +3379,14 @@ curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc)
rb_ary_freeze(passed);
if (RARRAY_LEN(passed) < FIX2INT(arity)) {
- if (!NIL_P(passed_proc)) {
+ if (!NIL_P(blockarg)) {
rb_warn("given block not used");
}
arity = make_curry_proc(proc, passed, arity);
return arity;
}
else {
- return rb_proc_call_with_block(proc, check_argc(RARRAY_LEN(passed)), RARRAY_CONST_PTR(passed), passed_proc);
+ return rb_proc_call_with_block(proc, check_argc(RARRAY_LEN(passed)), RARRAY_CONST_PTR(passed), blockarg);
}
}
@@ -2932,8 +3438,7 @@ proc_curry(int argc, const VALUE *argv, VALUE self)
int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
VALUE arity;
- rb_scan_args(argc, argv, "01", &arity);
- if (NIL_P(arity)) {
+ if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(arity = argv[0])) {
arity = INT2FIX(min_arity);
}
else {
@@ -2985,6 +3490,251 @@ rb_method_curry(int argc, const VALUE *argv, VALUE self)
return proc_curry(argc, argv, proc);
}
+static VALUE
+compose(RB_BLOCK_CALL_FUNC_ARGLIST(_, args))
+{
+ VALUE f, g, fargs;
+ f = RARRAY_AREF(args, 0);
+ g = RARRAY_AREF(args, 1);
+
+ if (rb_obj_is_proc(g))
+ fargs = rb_proc_call_with_block_kw(g, argc, argv, blockarg, RB_PASS_CALLED_KEYWORDS);
+ else
+ fargs = rb_funcall_with_block_kw(g, idCall, argc, argv, blockarg, RB_PASS_CALLED_KEYWORDS);
+
+ if (rb_obj_is_proc(f))
+ return rb_proc_call(f, rb_ary_new3(1, fargs));
+ else
+ return rb_funcallv(f, idCall, 1, &fargs);
+}
+
+static VALUE
+to_callable(VALUE f)
+{
+ VALUE mesg;
+
+ if (rb_obj_is_proc(f)) return f;
+ if (rb_obj_is_method(f)) return f;
+ if (rb_obj_respond_to(f, idCall, TRUE)) return f;
+ mesg = rb_fstring_lit("callable object is expected");
+ rb_exc_raise(rb_exc_new_str(rb_eTypeError, mesg));
+}
+
+static VALUE rb_proc_compose_to_left(VALUE self, VALUE g);
+static VALUE rb_proc_compose_to_right(VALUE self, VALUE g);
+
+/*
+ * call-seq:
+ * prc << g -> a_proc
+ *
+ * Returns a proc that is the composition of this proc and the given <i>g</i>.
+ * The returned proc takes a variable number of arguments, calls <i>g</i> with them
+ * then calls this proc with the result.
+ *
+ * f = proc {|x| x * x }
+ * g = proc {|x| x + x }
+ * p (f << g).call(2) #=> 16
+ *
+ * See Proc#>> for detailed explanations.
+ */
+static VALUE
+proc_compose_to_left(VALUE self, VALUE g)
+{
+ return rb_proc_compose_to_left(self, to_callable(g));
+}
+
+static VALUE
+rb_proc_compose_to_left(VALUE self, VALUE g)
+{
+ VALUE proc, args, procs[2];
+ rb_proc_t *procp;
+ int is_lambda;
+
+ procs[0] = self;
+ procs[1] = g;
+ args = rb_ary_tmp_new_from_values(0, 2, procs);
+
+ if (rb_obj_is_proc(g)) {
+ GetProcPtr(g, procp);
+ is_lambda = procp->is_lambda;
+ }
+ else {
+ VM_ASSERT(rb_obj_is_method(g) || rb_obj_respond_to(g, idCall, TRUE));
+ is_lambda = 1;
+ }
+
+ proc = rb_proc_new(compose, args);
+ GetProcPtr(proc, procp);
+ procp->is_lambda = is_lambda;
+
+ return proc;
+}
+
+/*
+ * call-seq:
+ * prc >> g -> a_proc
+ *
+ * Returns a proc that is the composition of this proc and the given <i>g</i>.
+ * The returned proc takes a variable number of arguments, calls this proc with them
+ * then calls <i>g</i> with the result.
+ *
+ * f = proc {|x| x * x }
+ * g = proc {|x| x + x }
+ * p (f >> g).call(2) #=> 8
+ *
+ * <i>g</i> could be other Proc, or Method, or any other object responding to
+ * +call+ method:
+ *
+ * class Parser
+ * def self.call(text)
+ * # ...some complicated parsing logic...
+ * end
+ * end
+ *
+ * pipeline = File.method(:read) >> Parser >> proc { |data| puts "data size: #{data.count}" }
+ * pipeline.call('data.json')
+ *
+ * See also Method#>> and Method#<<.
+ */
+static VALUE
+proc_compose_to_right(VALUE self, VALUE g)
+{
+ return rb_proc_compose_to_right(self, to_callable(g));
+}
+
+static VALUE
+rb_proc_compose_to_right(VALUE self, VALUE g)
+{
+ VALUE proc, args, procs[2];
+ rb_proc_t *procp;
+ int is_lambda;
+
+ procs[0] = g;
+ procs[1] = self;
+ args = rb_ary_tmp_new_from_values(0, 2, procs);
+
+ GetProcPtr(self, procp);
+ is_lambda = procp->is_lambda;
+
+ proc = rb_proc_new(compose, args);
+ GetProcPtr(proc, procp);
+ procp->is_lambda = is_lambda;
+
+ return proc;
+}
+
+/*
+ * call-seq:
+ * meth << g -> a_proc
+ *
+ * Returns a proc that is the composition of this method and the given <i>g</i>.
+ * The returned proc takes a variable number of arguments, calls <i>g</i> with them
+ * then calls this method with the result.
+ *
+ * def f(x)
+ * x * x
+ * end
+ *
+ * f = self.method(:f)
+ * g = proc {|x| x + x }
+ * p (f << g).call(2) #=> 16
+ */
+static VALUE
+rb_method_compose_to_left(VALUE self, VALUE g)
+{
+ g = to_callable(g);
+ self = method_to_proc(self);
+ return proc_compose_to_left(self, g);
+}
+
+/*
+ * call-seq:
+ * meth >> g -> a_proc
+ *
+ * Returns a proc that is the composition of this method and the given <i>g</i>.
+ * The returned proc takes a variable number of arguments, calls this method
+ * with them then calls <i>g</i> with the result.
+ *
+ * def f(x)
+ * x * x
+ * end
+ *
+ * f = self.method(:f)
+ * g = proc {|x| x + x }
+ * p (f >> g).call(2) #=> 8
+ */
+static VALUE
+rb_method_compose_to_right(VALUE self, VALUE g)
+{
+ g = to_callable(g);
+ self = method_to_proc(self);
+ return proc_compose_to_right(self, g);
+}
+
+/*
+ * call-seq:
+ * proc.ruby2_keywords -> proc
+ *
+ * Marks the proc as passing keywords through a normal argument splat.
+ * This should only be called on procs that accept an argument splat
+ * (<tt>*args</tt>) but not explicit keywords or a keyword splat. It
+ * marks the proc such that if the proc is called with keyword arguments,
+ * the final hash argument is marked with a special flag such that if it
+ * is the final element of a normal argument splat to another method call,
+ * and that method call does not include explicit keywords or a keyword
+ * splat, the final element is interpreted as keywords. In other words,
+ * keywords will be passed through the proc to other methods.
+ *
+ * This should only be used for procs that delegate keywords to another
+ * method, and only for backwards compatibility with Ruby versions before
+ * 2.7.
+ *
+ * This method will probably be removed at some point, as it exists only
+ * for backwards compatibility. As it does not exist in Ruby versions
+ * before 2.7, check that the proc responds to this method before calling
+ * it. Also, be aware that if this method is removed, the behavior of the
+ * proc will change so that it does not pass through keywords.
+ *
+ * module Mod
+ * foo = ->(meth, *args, &block) do
+ * send(:"do_#{meth}", *args, &block)
+ * end
+ * foo.ruby2_keywords if foo.respond_to?(:ruby2_keywords)
+ * end
+ */
+
+static VALUE
+proc_ruby2_keywords(VALUE procval)
+{
+ rb_proc_t *proc;
+ GetProcPtr(procval, proc);
+
+ rb_check_frozen(procval);
+
+ if (proc->is_from_method) {
+ rb_warn("Skipping set of ruby2_keywords flag for proc (proc created from method)");
+ return procval;
+ }
+
+ switch (proc->block.type) {
+ case block_type_iseq:
+ if (proc->block.as.captured.code.iseq->body->param.flags.has_rest &&
+ !proc->block.as.captured.code.iseq->body->param.flags.has_kw &&
+ !proc->block.as.captured.code.iseq->body->param.flags.has_kwrest) {
+ proc->block.as.captured.code.iseq->body->param.flags.ruby2_keywords = 1;
+ }
+ else {
+ rb_warn("Skipping set of ruby2_keywords flag for proc (proc accepts keywords or proc does not accept argument splat)");
+ }
+ break;
+ default:
+ rb_warn("Skipping set of ruby2_keywords flag for proc (proc not defined in Ruby)");
+ break;
+ }
+
+ return procval;
+}
+
/*
* Document-class: LocalJumpError
*
@@ -3029,12 +3779,25 @@ rb_method_curry(int argc, const VALUE *argv, VALUE self)
*/
/*
- * <code>Proc</code> objects are blocks of code that have been bound to
- * a set of local variables. Once bound, the code may be called in
- * different contexts and still access those variables.
+ * Document-class: Proc
+ *
+ * A +Proc+ object is an encapsulation of a block of code, which can be stored
+ * in a local variable, passed to a method or another Proc, and can be called.
+ * Proc is an essential concept in Ruby and a core of its functional
+ * programming features.
+ *
+ * square = Proc.new {|x| x**2 }
+ *
+ * square.call(3) #=> 9
+ * # shorthands:
+ * square.(3) #=> 9
+ * square[3] #=> 9
+ *
+ * Proc objects are _closures_, meaning they remember and can use the entire
+ * context in which they were created.
*
* def gen_times(factor)
- * return Proc.new {|n| n*factor }
+ * Proc.new {|n| n*factor } # remembers the value of factor at the moment of creation
* end
*
* times3 = gen_times(3)
@@ -3044,17 +3807,280 @@ rb_method_curry(int argc, const VALUE *argv, VALUE self)
* times5.call(5) #=> 25
* times3.call(times5.call(4)) #=> 60
*
+ * == Creation
+ *
+ * There are several methods to create a Proc
+ *
+ * * Use the Proc class constructor:
+ *
+ * proc1 = Proc.new {|x| x**2 }
+ *
+ * * Use the Kernel#proc method as a shorthand of Proc.new:
+ *
+ * proc2 = proc {|x| x**2 }
+ *
+ * * Receiving a block of code into proc argument (note the <code>&</code>):
+ *
+ * def make_proc(&block)
+ * block
+ * end
+ *
+ * proc3 = make_proc {|x| x**2 }
+ *
+ * * Construct a proc with lambda semantics using the Kernel#lambda method
+ * (see below for explanations about lambdas):
+ *
+ * lambda1 = lambda {|x| x**2 }
+ *
+ * * Use the Lambda literal syntax (also constructs a proc with lambda semantics):
+ *
+ * lambda2 = ->(x) { x**2 }
+ *
+ * == Lambda and non-lambda semantics
+ *
+ * Procs are coming in two flavors: lambda and non-lambda (regular procs).
+ * Differences are:
+ *
+ * * In lambdas, +return+ and +break+ means exit from this lambda;
+ * * In non-lambda procs, +return+ means exit from embracing method
+ * (and will throw +LocalJumpError+ if invoked outside the method);
+ * * In non-lambda procs, +break+ means exit from the method which the block given for.
+ * (and will throw +LocalJumpError+ if invoked after the method returns);
+ * * In lambdas, arguments are treated in the same way as in methods: strict,
+ * with +ArgumentError+ for mismatching argument number,
+ * and no additional argument processing;
+ * * Regular procs accept arguments more generously: missing arguments
+ * are filled with +nil+, single Array arguments are deconstructed if the
+ * proc has multiple arguments, and there is no error raised on extra
+ * arguments.
+ *
+ * Examples:
+ *
+ * # +return+ in non-lambda proc, +b+, exits +m2+.
+ * # (The block +{ return }+ is given for +m1+ and embraced by +m2+.)
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { return }; $a << :m2 end; m2; p $a
+ * #=> []
+ *
+ * # +break+ in non-lambda proc, +b+, exits +m1+.
+ * # (The block +{ break }+ is given for +m1+ and embraced by +m2+.)
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { break }; $a << :m2 end; m2; p $a
+ * #=> [:m2]
+ *
+ * # +next+ in non-lambda proc, +b+, exits the block.
+ * # (The block +{ next }+ is given for +m1+ and embraced by +m2+.)
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { next }; $a << :m2 end; m2; p $a
+ * #=> [:m1, :m2]
+ *
+ * # Using +proc+ method changes the behavior as follows because
+ * # The block is given for +proc+ method and embraced by +m2+.
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { return }); $a << :m2 end; m2; p $a
+ * #=> []
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { break }); $a << :m2 end; m2; p $a
+ * # break from proc-closure (LocalJumpError)
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { next }); $a << :m2 end; m2; p $a
+ * #=> [:m1, :m2]
+ *
+ * # +return+, +break+ and +next+ in the stubby lambda exits the block.
+ * # (+lambda+ method behaves same.)
+ * # (The block is given for stubby lambda syntax and embraced by +m2+.)
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { return }); $a << :m2 end; m2; p $a
+ * #=> [:m1, :m2]
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { break }); $a << :m2 end; m2; p $a
+ * #=> [:m1, :m2]
+ * $a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { next }); $a << :m2 end; m2; p $a
+ * #=> [:m1, :m2]
+ *
+ * p = proc {|x, y| "x=#{x}, y=#{y}" }
+ * p.call(1, 2) #=> "x=1, y=2"
+ * p.call([1, 2]) #=> "x=1, y=2", array deconstructed
+ * p.call(1, 2, 8) #=> "x=1, y=2", extra argument discarded
+ * p.call(1) #=> "x=1, y=", nil substituted instead of error
+ *
+ * l = lambda {|x, y| "x=#{x}, y=#{y}" }
+ * l.call(1, 2) #=> "x=1, y=2"
+ * l.call([1, 2]) # ArgumentError: wrong number of arguments (given 1, expected 2)
+ * l.call(1, 2, 8) # ArgumentError: wrong number of arguments (given 3, expected 2)
+ * l.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
+ *
+ * def test_return
+ * -> { return 3 }.call # just returns from lambda into method body
+ * proc { return 4 }.call # returns from method
+ * return 5
+ * end
+ *
+ * test_return # => 4, return from proc
+ *
+ * Lambdas are useful as self-sufficient functions, in particular useful as
+ * arguments to higher-order functions, behaving exactly like Ruby methods.
+ *
+ * Procs are useful for implementing iterators:
+ *
+ * def test
+ * [[1, 2], [3, 4], [5, 6]].map {|a, b| return a if a + b > 10 }
+ * # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * end
+ *
+ * Inside +map+, the block of code is treated as a regular (non-lambda) proc,
+ * which means that the internal arrays will be deconstructed to pairs of
+ * arguments, and +return+ will exit from the method +test+. That would
+ * not be possible with a stricter lambda.
+ *
+ * You can tell a lambda from a regular proc by using the #lambda? instance method.
+ *
+ * Lambda semantics is typically preserved during the proc lifetime, including
+ * <code>&</code>-deconstruction to a block of code:
+ *
+ * p = proc {|x, y| x }
+ * l = lambda {|x, y| x }
+ * [[1, 2], [3, 4]].map(&p) #=> [1, 3]
+ * [[1, 2], [3, 4]].map(&l) # ArgumentError: wrong number of arguments (given 1, expected 2)
+ *
+ * The only exception is dynamic method definition: even if defined by
+ * passing a non-lambda proc, methods still have normal semantics of argument
+ * checking.
+ *
+ * class C
+ * define_method(:e, &proc {})
+ * end
+ * C.new.e(1,2) #=> ArgumentError
+ * C.new.method(:e).to_proc.lambda? #=> true
+ *
+ * This exception ensures that methods never have unusual argument passing
+ * conventions, and makes it easy to have wrappers defining methods that
+ * behave as usual.
+ *
+ * class C
+ * def self.def2(name, &body)
+ * define_method(name, &body)
+ * end
+ *
+ * def2(:f) {}
+ * end
+ * C.new.f(1,2) #=> ArgumentError
+ *
+ * The wrapper <code>def2</code> receives _body_ as a non-lambda proc,
+ * yet defines a method which has normal semantics.
+ *
+ * == Conversion of other objects to procs
+ *
+ * Any object that implements the +to_proc+ method can be converted into
+ * a proc by the <code>&</code> operator, and therefore can be
+ * consumed by iterators.
+ *
+
+ * class Greeter
+ * def initialize(greeting)
+ * @greeting = greeting
+ * end
+ *
+ * def to_proc
+ * proc {|name| "#{@greeting}, #{name}!" }
+ * end
+ * end
+ *
+ * hi = Greeter.new("Hi")
+ * hey = Greeter.new("Hey")
+ * ["Bob", "Jane"].map(&hi) #=> ["Hi, Bob!", "Hi, Jane!"]
+ * ["Bob", "Jane"].map(&hey) #=> ["Hey, Bob!", "Hey, Jane!"]
+ *
+ * Of the Ruby core classes, this method is implemented by Symbol,
+ * Method, and Hash.
+ *
+ * :to_s.to_proc.call(1) #=> "1"
+ * [1, 2].map(&:to_s) #=> ["1", "2"]
+ *
+ * method(:puts).to_proc.call(1) # prints 1
+ * [1, 2].each(&method(:puts)) # prints 1, 2
+ *
+ * {test: 1}.to_proc.call(:test) #=> 1
+ * %i[test many keys].map(&{test: 1}) #=> [1, nil, nil]
+ *
+ * == Orphaned Proc
+ *
+ * +return+ and +break+ in a block exit a method.
+ * If a Proc object is generated from the block and the Proc object
+ * survives until the method is returned, +return+ and +break+ cannot work.
+ * In such case, +return+ and +break+ raises LocalJumpError.
+ * A Proc object in such situation is called as orphaned Proc object.
+ *
+ * Note that the method to exit is different for +return+ and +break+.
+ * There is a situation that orphaned for +break+ but not orphaned for +return+.
+ *
+ * def m1(&b) b.call end; def m2(); m1 { return } end; m2 # ok
+ * def m1(&b) b.call end; def m2(); m1 { break } end; m2 # ok
+ *
+ * def m1(&b) b end; def m2(); m1 { return }.call end; m2 # ok
+ * def m1(&b) b end; def m2(); m1 { break }.call end; m2 # LocalJumpError
+ *
+ * def m1(&b) b end; def m2(); m1 { return } end; m2.call # LocalJumpError
+ * def m1(&b) b end; def m2(); m1 { break } end; m2.call # LocalJumpError
+ *
+ * Since +return+ and +break+ exits the block itself in lambdas,
+ * lambdas cannot be orphaned.
+ *
+ * == Numbered parameters
+ *
+ * Numbered parameters are implicitly defined block parameters intended to
+ * simplify writing short blocks:
+ *
+ * # Explicit parameter:
+ * %w[test me please].each { |str| puts str.upcase } # prints TEST, ME, PLEASE
+ * (1..5).map { |i| i**2 } # => [1, 4, 9, 16, 25]
+ *
+ * # Implicit parameter:
+ * %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
+ * (1..5).map { _1**2 } # => [1, 4, 9, 16, 25]
+ *
+ * Parameter names from +_1+ to +_9+ are supported:
+ *
+ * [10, 20, 30].zip([40, 50, 60], [70, 80, 90]).map { _1 + _2 + _3 }
+ * # => [120, 150, 180]
+ *
+ * Though, it is advised to resort to them wisely, probably limiting
+ * yourself to +_1+ and +_2+, and to one-line blocks.
+ *
+ * Numbered parameters can't be used together with explicitly named
+ * ones:
+ *
+ * [10, 20, 30].map { |x| _1**2 }
+ * # SyntaxError (ordinary parameter is defined)
+ *
+ * To avoid conflicts, naming local variables or method
+ * arguments +_1+, +_2+ and so on, causes a warning.
+ *
+ * _1 = 'test'
+ * # warning: `_1' is reserved as numbered parameter
+ *
+ * Using implicit numbered parameters affects block's arity:
+ *
+ * p = proc { _1 + _2 }
+ * l = lambda { _1 + _2 }
+ * p.parameters # => [[:opt, :_1], [:opt, :_2]]
+ * p.arity # => 2
+ * l.parameters # => [[:req, :_1], [:req, :_2]]
+ * l.arity # => 2
+ *
+ * Blocks with numbered parameters can't be nested:
+ *
+ * %w[test me].each { _1.each_char { p _1 } }
+ * # SyntaxError (numbered parameter is already used in outer block here)
+ * # %w[test me].each { _1.each_char { p _1 } }
+ * # ^~
+ *
+ * Numbered parameters were introduced in Ruby 2.7.
*/
+
void
Init_Proc(void)
{
+#undef rb_intern
/* Proc */
rb_cProc = rb_define_class("Proc", rb_cObject);
rb_undef_alloc_func(rb_cProc);
rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1);
- rb_add_method(rb_cProc, rb_intern("call"), VM_METHOD_TYPE_OPTIMIZED,
+ rb_add_method(rb_cProc, idCall, VM_METHOD_TYPE_OPTIMIZED,
(void *)OPTIMIZED_METHOD_TYPE_CALL, METHOD_VISI_PUBLIC);
rb_add_method(rb_cProc, rb_intern("[]"), VM_METHOD_TYPE_OPTIMIZED,
(void *)OPTIMIZED_METHOD_TYPE_CALL, METHOD_VISI_PUBLIC);
@@ -3073,15 +4099,21 @@ Init_Proc(void)
rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
rb_define_method(rb_cProc, "arity", proc_arity, 0);
rb_define_method(rb_cProc, "clone", proc_clone, 0);
- rb_define_method(rb_cProc, "dup", proc_dup, 0);
+ rb_define_method(rb_cProc, "dup", rb_proc_dup, 0);
rb_define_method(rb_cProc, "hash", proc_hash, 0);
rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
rb_define_alias(rb_cProc, "inspect", "to_s");
rb_define_method(rb_cProc, "lambda?", rb_proc_lambda_p, 0);
rb_define_method(rb_cProc, "binding", proc_binding, 0);
rb_define_method(rb_cProc, "curry", proc_curry, -1);
+ rb_define_method(rb_cProc, "<<", proc_compose_to_left, 1);
+ rb_define_method(rb_cProc, ">>", proc_compose_to_right, 1);
+ rb_define_method(rb_cProc, "==", proc_eq, 1);
+ rb_define_method(rb_cProc, "eql?", proc_eq, 1);
rb_define_method(rb_cProc, "source_location", rb_proc_location, 0);
rb_define_method(rb_cProc, "parameters", rb_proc_parameters, 0);
+ rb_define_method(rb_cProc, "ruby2_keywords", proc_ruby2_keywords, 0);
+ // rb_define_method(rb_cProc, "isolate", rb_proc_isolate, 0); is not accepted.
/* Exceptions */
rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
@@ -3092,8 +4124,8 @@ Init_Proc(void)
rb_vm_register_special_exception(ruby_error_sysstack, rb_eSysStackError, "stack level too deep");
/* utility functions */
- rb_define_global_function("proc", rb_block_proc, 0);
- rb_define_global_function("lambda", rb_block_lambda, 0);
+ rb_define_global_function("proc", f_proc, 0);
+ rb_define_global_function("lambda", f_lambda, 0);
/* Method */
rb_cMethod = rb_define_class("Method", rb_cObject);
@@ -3103,9 +4135,12 @@ Init_Proc(void)
rb_define_method(rb_cMethod, "eql?", method_eq, 1);
rb_define_method(rb_cMethod, "hash", method_hash, 0);
rb_define_method(rb_cMethod, "clone", method_clone, 0);
- rb_define_method(rb_cMethod, "call", rb_method_call, -1);
+ rb_define_method(rb_cMethod, "call", rb_method_call_pass_called_kw, -1);
+ rb_define_method(rb_cMethod, "===", rb_method_call_pass_called_kw, -1);
rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
- rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
+ rb_define_method(rb_cMethod, "<<", rb_method_compose_to_left, 1);
+ rb_define_method(rb_cMethod, ">>", rb_method_compose_to_right, 1);
+ rb_define_method(rb_cMethod, "[]", rb_method_call_pass_called_kw, -1);
rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
@@ -3137,6 +4172,7 @@ Init_Proc(void)
rb_define_method(rb_cUnboundMethod, "original_name", method_original_name, 0);
rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0);
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
+ rb_define_method(rb_cUnboundMethod, "bind_call", umethod_bind_call, -1);
rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0);
rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0);
rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0);
@@ -3144,7 +4180,7 @@ Init_Proc(void)
/* Module#*_method */
rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);
rb_define_method(rb_cModule, "public_instance_method", rb_mod_public_instance_method, 1);
- rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1);
+ rb_define_method(rb_cModule, "define_method", rb_mod_define_method, -1);
/* Kernel */
rb_define_method(rb_mKernel, "define_singleton_method", rb_obj_define_method, -1);
@@ -3154,16 +4190,16 @@ Init_Proc(void)
}
/*
- * Objects of class <code>Binding</code> encapsulate the execution
- * context at some particular place in the code and retain this context
- * for future use. The variables, methods, value of <code>self</code>,
- * and possibly an iterator block that can be accessed in this context
+ * Objects of class Binding encapsulate the execution context at some
+ * particular place in the code and retain this context for future
+ * use. The variables, methods, value of <code>self</code>, and
+ * possibly an iterator block that can be accessed in this context
* are all retained. Binding objects can be created using
- * <code>Kernel#binding</code>, and are made available to the callback
- * of <code>Kernel#set_trace_func</code>.
+ * Kernel#binding, and are made available to the callback of
+ * Kernel#set_trace_func and instances of TracePoint.
*
* These binding objects can be passed as the second argument of the
- * <code>Kernel#eval</code> method, establishing an environment for the
+ * Kernel#eval method, establishing an environment for the
* evaluation.
*
* class Demo
@@ -3202,5 +4238,6 @@ Init_Binding(void)
rb_define_method(rb_cBinding, "local_variable_set", bind_local_variable_set, 2);
rb_define_method(rb_cBinding, "local_variable_defined?", bind_local_variable_defined_p, 1);
rb_define_method(rb_cBinding, "receiver", bind_receiver, 0);
+ rb_define_method(rb_cBinding, "source_location", bind_location, 0);
rb_define_global_function("binding", rb_f_binding, 0);
}
diff --git a/process.c b/process.c
index 2d842176bd..674f05dd6c 100644
--- a/process.c
+++ b/process.c
@@ -11,88 +11,112 @@
**********************************************************************/
-#include "internal.h"
-#include "ruby/io.h"
-#include "ruby/thread.h"
-#include "ruby/util.h"
-#include "vm_core.h"
+#include "ruby/internal/config.h"
-#include <stdio.h>
+#include "internal/scheduler.h"
+#include "coroutine/Stack.h"
+
+#include <ctype.h>
#include <errno.h>
#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <time.h>
+
#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
+# include <stdlib.h>
#endif
+
#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+# include <unistd.h>
#endif
+
#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
+# include <fcntl.h>
#endif
+
#ifdef HAVE_PROCESS_H
-#include <process.h>
+# include <process.h>
#endif
-#include <time.h>
-#include <ctype.h>
-
#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS 0
+# define EXIT_SUCCESS 0
#endif
+
#ifndef EXIT_FAILURE
-#define EXIT_FAILURE 1
+# define EXIT_FAILURE 1
#endif
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
+
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
+
#ifdef HAVE_VFORK_H
# include <vfork.h>
#endif
+
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
+
#ifndef MAXPATHLEN
# define MAXPATHLEN 1024
#endif
-#include "ruby/st.h"
#include <sys/stat.h>
-#if defined(__native_client__) && defined(NACL_NEWLIB)
-# include <sys/unistd.h>
-# include "nacl/stat.h"
-# include "nacl/unistd.h"
-# include "nacl/resource.h"
-# undef HAVE_ISSETUGID
-#endif
#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+# include <sys/time.h>
#endif
+
#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
+# include <sys/times.h>
#endif
#ifdef HAVE_PWD_H
-#include <pwd.h>
+# include <pwd.h>
#endif
+
#ifdef HAVE_GRP_H
-#include <grp.h>
+# include <grp.h>
# ifdef __CYGWIN__
int initgroups(const char *, rb_gid_t);
# endif
#endif
+
#ifdef HAVE_SYS_ID_H
-#include <sys/id.h>
+# include <sys/id.h>
#endif
#ifdef __APPLE__
# include <mach/mach_time.h>
#endif
+#include "dln.h"
+#include "hrtime.h"
+#include "internal.h"
+#include "internal/bits.h"
+#include "internal/dir.h"
+#include "internal/error.h"
+#include "internal/eval.h"
+#include "internal/hash.h"
+#include "internal/object.h"
+#include "internal/process.h"
+#include "internal/thread.h"
+#include "internal/variable.h"
+#include "internal/warnings.h"
+#include "mjit.h"
+#include "ruby/io.h"
+#include "ruby/st.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+#include "vm_core.h"
+#include "ruby/ractor.h"
+
/* define system APIs */
#ifdef _WIN32
#undef open
@@ -150,23 +174,49 @@ int setregid(rb_gid_t rgid, rb_gid_t egid);
#endif
#endif
-#define preserving_errno(stmts) \
- do {int saved_errno = errno; stmts; errno = saved_errno;} while (0)
-
static void check_uid_switch(void);
static void check_gid_switch(void);
+static int exec_async_signal_safe(const struct rb_execarg *, char *, size_t);
#if 1
#define p_uid_from_name p_uid_from_name
#define p_gid_from_name p_gid_from_name
#endif
+#if defined(HAVE_UNISTD_H)
+# if defined(HAVE_GETLOGIN_R)
+# define USE_GETLOGIN_R 1
+# define GETLOGIN_R_SIZE_DEFAULT 0x100
+# define GETLOGIN_R_SIZE_LIMIT 0x1000
+# if defined(_SC_LOGIN_NAME_MAX)
+# define GETLOGIN_R_SIZE_INIT sysconf(_SC_LOGIN_NAME_MAX)
+# else
+# define GETLOGIN_R_SIZE_INIT GETLOGIN_R_SIZE_DEFAULT
+# endif
+# elif defined(HAVE_GETLOGIN)
+# define USE_GETLOGIN 1
+# endif
+#endif
+
#if defined(HAVE_PWD_H)
-# if defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
+# if defined(HAVE_GETPWUID_R)
+# define USE_GETPWUID_R 1
+# elif defined(HAVE_GETPWUID)
+# define USE_GETPWUID 1
+# endif
+# if defined(HAVE_GETPWNAM_R)
# define USE_GETPWNAM_R 1
-# define GETPW_R_SIZE_INIT sysconf(_SC_GETPW_R_SIZE_MAX)
+# elif defined(HAVE_GETPWNAM)
+# define USE_GETPWNAM 1
+# endif
+# if defined(HAVE_GETPWNAM_R) || defined(HAVE_GETPWUID_R)
# define GETPW_R_SIZE_DEFAULT 0x1000
# define GETPW_R_SIZE_LIMIT 0x10000
+# if defined(_SC_GETPW_R_SIZE_MAX)
+# define GETPW_R_SIZE_INIT sysconf(_SC_GETPW_R_SIZE_MAX)
+# else
+# define GETPW_R_SIZE_INIT GETPW_R_SIZE_DEFAULT
+# endif
# endif
# ifdef USE_GETPWNAM_R
# define PREPARE_GETPWNAM \
@@ -257,6 +307,7 @@ typedef unsigned LONG_LONG unsigned_clock_t;
typedef void (*sig_t) (int);
#endif
+#define id_exception idException
static ID id_in, id_out, id_err, id_pid, id_uid, id_gid;
static ID id_close, id_child;
#ifdef HAVE_SETPGID
@@ -281,8 +332,6 @@ static ID id_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID;
static ID id_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC;
#endif
static ID id_hertz;
-extern ID ruby_static_id_status;
-#define id_status ruby_static_id_status
/* execv and execl are async-signal-safe since SUSv4 (POSIX.1-2008, XPG7) */
#if defined(__sun) && !defined(_XPG7) /* Solaris 10, 9, ... */
@@ -293,12 +342,30 @@ extern ID ruby_static_id_status;
#define ALWAYS_NEED_ENVP 0
#endif
+static void
+assert_close_on_exec(int fd)
+{
+#if VM_CHECK_MODE > 0
+#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(FD_CLOEXEC)
+ int flags = fcntl(fd, F_GETFD);
+ if (flags == -1) {
+ static const char m[] = "reserved FD closed unexpectedly?\n";
+ (void)!write(2, m, sizeof(m) - 1);
+ return;
+ }
+ if (flags & FD_CLOEXEC) return;
+ rb_bug("reserved FD did not have close-on-exec set");
+#else
+ rb_bug("reserved FD without close-on-exec support");
+#endif /* FD_CLOEXEC */
+#endif /* VM_CHECK_MODE */
+}
+
static inline int
close_unless_reserved(int fd)
{
- /* We should not have reserved FDs at this point */
if (rb_reserved_fd_p(fd)) { /* async-signal-safe */
- rb_async_bug_errno("BUG timer thread still running", 0 /* EDOOFUS */);
+ assert_close_on_exec(fd);
return 0;
}
return close(fd); /* async-signal-safe */
@@ -307,8 +374,6 @@ close_unless_reserved(int fd)
/*#define DEBUG_REDIRECT*/
#if defined(DEBUG_REDIRECT)
-#include <stdarg.h>
-
static void
ttyprintf(const char *fmt, ...)
{
@@ -404,6 +469,30 @@ parent_redirect_close(int fd)
#endif
/*
+ * Document-module: Process
+ *
+ * The module contains several groups of functionality for handling OS processes:
+ *
+ * * Low-level property introspection and management of the current process, like
+ * Process.argv0, Process.pid;
+ * * Low-level introspection of other processes, like Process.getpgid, Process.getpriority;
+ * * Management of the current process: Process.abort, Process.exit, Process.daemon, etc.
+ * (for convenience, most of those are also available as global functions
+ * and module functions of Kernel);
+ * * Creation and management of child processes: Process.fork, Process.spawn, and
+ * related methods;
+ * * Management of low-level system clock: Process.times and Process.clock_gettime,
+ * which could be important for proper benchmarking and other elapsed
+ * time measurement tasks.
+ */
+
+static VALUE
+get_pid(void)
+{
+ return PIDT2NUM(getpid());
+}
+
+/*
* call-seq:
* Process.pid -> integer
*
@@ -414,11 +503,16 @@ parent_redirect_close(int fd)
*/
static VALUE
-get_pid(void)
+proc_get_pid(VALUE _)
{
- return PIDT2NUM(getpid());
+ return get_pid();
}
+static VALUE
+get_ppid(void)
+{
+ return PIDT2NUM(getppid());
+}
/*
* call-seq:
@@ -437,9 +531,9 @@ get_pid(void)
*/
static VALUE
-get_ppid(void)
+proc_get_ppid(VALUE _)
{
- return PIDT2NUM(getppid());
+ return get_ppid();
}
@@ -447,10 +541,10 @@ get_ppid(void)
*
* Document-class: Process::Status
*
- * <code>Process::Status</code> encapsulates the information on the
+ * Process::Status encapsulates the information on the
* status of a running or terminated system process. The built-in
* variable <code>$?</code> is either +nil+ or a
- * <code>Process::Status</code> object.
+ * Process::Status object.
*
* fork { exit 99 } #=> 26557
* Process.wait #=> 26557
@@ -467,7 +561,7 @@ get_ppid(void)
* information (for example the program's return code in the case of
* exited processes). Pre Ruby 1.8, these bits were exposed directly
* to the Ruby program. Ruby now encapsulates these in a
- * <code>Process::Status</code> object. To maximize compatibility,
+ * Process::Status object. To maximize compatibility,
* however, these objects retain a bit-oriented interface. In the
* descriptions that follow, when we talk about the integer value of
* _stat_, we're referring to this 16 bit value.
@@ -475,19 +569,97 @@ get_ppid(void)
static VALUE rb_cProcessStatus;
+struct rb_process_status {
+ rb_pid_t pid;
+ int status;
+ int error;
+};
+
+static const rb_data_type_t rb_process_status_type = {
+ .wrap_struct_name = "Process::Status",
+ .function = {
+ .dfree = RUBY_DEFAULT_FREE,
+ },
+ .data = NULL,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
+};
+
+static VALUE
+rb_process_status_allocate(VALUE klass)
+{
+ struct rb_process_status *data = NULL;
+
+ return TypedData_Make_Struct(klass, struct rb_process_status, &rb_process_status_type, data);
+}
+
VALUE
rb_last_status_get(void)
{
return GET_THREAD()->last_status;
}
+/*
+ * call-seq:
+ * Process.last_status -> Process::Status or nil
+ *
+ * Returns the status of the last executed child process in the
+ * current thread.
+ *
+ * Process.wait Process.spawn("ruby", "-e", "exit 13")
+ * Process.last_status #=> #<Process::Status: pid 4825 exit 13>
+ *
+ * If no child process has ever been executed in the current
+ * thread, this returns +nil+.
+ *
+ * Process.last_status #=> nil
+ */
+static VALUE
+proc_s_last_status(VALUE mod)
+{
+ return rb_last_status_get();
+}
+
+VALUE
+rb_process_status_new(rb_pid_t pid, int status, int error)
+{
+ VALUE last_status = rb_process_status_allocate(rb_cProcessStatus);
+
+ struct rb_process_status *data = RTYPEDDATA_DATA(last_status);
+ data->pid = pid;
+ data->status = status;
+ data->error = error;
+
+ rb_obj_freeze(last_status);
+ return last_status;
+}
+
+static VALUE
+process_status_dump(VALUE status)
+{
+ VALUE dump = rb_class_new_instance(0, 0, rb_cObject);
+ struct rb_process_status *data = RTYPEDDATA_DATA(status);
+ if (data->pid) {
+ rb_ivar_set(dump, id_status, INT2NUM(data->status));
+ rb_ivar_set(dump, id_pid, PIDT2NUM(data->pid));
+ }
+ return dump;
+}
+
+static VALUE
+process_status_load(VALUE real_obj, VALUE load_obj)
+{
+ struct rb_process_status *data = rb_check_typeddata(real_obj, &rb_process_status_type);
+ VALUE status = rb_attr_get(load_obj, id_status);
+ VALUE pid = rb_attr_get(load_obj, id_pid);
+ data->pid = NIL_P(pid) ? 0 : NUM2PIDT(pid);
+ data->status = NIL_P(status) ? 0 : NUM2INT(status);
+ return real_obj;
+}
+
void
rb_last_status_set(int status, rb_pid_t pid)
{
- rb_thread_t *th = GET_THREAD();
- th->last_status = rb_obj_alloc(rb_cProcessStatus);
- rb_ivar_set(th->last_status, id_status, INT2FIX(status));
- rb_ivar_set(th->last_status, id_pid, PIDT2NUM(pid));
+ GET_THREAD()->last_status = rb_process_status_new(pid, status, 0);
}
void
@@ -496,12 +668,25 @@ rb_last_status_clear(void)
GET_THREAD()->last_status = Qnil;
}
+static rb_pid_t
+pst_pid(VALUE pst)
+{
+ struct rb_process_status *data = RTYPEDDATA_DATA(pst);
+ return data->pid;
+}
+
+static int
+pst_status(VALUE pst)
+{
+ struct rb_process_status *data = RTYPEDDATA_DATA(pst);
+ return data->status;
+}
+
/*
* call-seq:
* stat.to_i -> integer
- * stat.to_int -> integer
*
- * Returns the bits in _stat_ as a <code>Integer</code>. Poking
+ * Returns the bits in _stat_ as an Integer. Poking
* around in these bits is platform dependent.
*
* fork { exit 0xab } #=> 26566
@@ -510,12 +695,13 @@ rb_last_status_clear(void)
*/
static VALUE
-pst_to_i(VALUE st)
+pst_to_i(VALUE self)
{
- return rb_ivar_get(st, id_status);
+ int status = pst_status(self);
+ return RB_INT2NUM(status);
}
-#define PST2INT(st) NUM2INT(pst_to_i(st))
+#define PST2INT(st) pst_status(st)
/*
* call-seq:
@@ -529,15 +715,24 @@ pst_to_i(VALUE st)
*/
static VALUE
-pst_pid(VALUE st)
+pst_pid_m(VALUE self)
{
- return rb_attr_get(st, id_pid);
+ rb_pid_t pid = pst_pid(self);
+ return PIDT2NUM(pid);
}
+static VALUE pst_message_status(VALUE str, int status);
+
static void
pst_message(VALUE str, rb_pid_t pid, int status)
{
rb_str_catf(str, "pid %ld", (long)pid);
+ pst_message_status(str, status);
+}
+
+static VALUE
+pst_message_status(VALUE str, int status)
+{
if (WIFSTOPPED(status)) {
int stopsig = WSTOPSIG(status);
const char *signame = ruby_signal_name(stopsig);
@@ -566,6 +761,7 @@ pst_message(VALUE str, rb_pid_t pid, int status)
rb_str_cat2(str, " (core dumped)");
}
#endif
+ return str;
}
@@ -587,7 +783,7 @@ pst_to_s(VALUE st)
int status;
VALUE str;
- pid = NUM2PIDT(pst_pid(st));
+ pid = pst_pid(st);
status = PST2INT(st);
str = rb_str_buf_new(0);
@@ -612,13 +808,12 @@ pst_inspect(VALUE st)
{
rb_pid_t pid;
int status;
- VALUE vpid, str;
+ VALUE str;
- vpid = pst_pid(st);
- if (NIL_P(vpid)) {
+ pid = pst_pid(st);
+ if (!pid) {
return rb_sprintf("#<%s: uninitialized>", rb_class2name(CLASS_OF(st)));
}
- pid = NUM2PIDT(vpid);
status = PST2INT(st);
str = rb_sprintf("#<%s: ", rb_class2name(CLASS_OF(st)));
@@ -690,9 +885,9 @@ pst_rshift(VALUE st1, VALUE st2)
* call-seq:
* stat.stopped? -> true or false
*
- * Returns +true+ if this process is stopped. This is only
- * returned if the corresponding <code>wait</code> call had the
- * <code>WUNTRACED</code> flag set.
+ * Returns +true+ if this process is stopped. This is only returned
+ * if the corresponding #wait call had the Process::WUNTRACED flag
+ * set.
*/
static VALUE
@@ -792,8 +987,7 @@ pst_wifexited(VALUE st)
* stat.exitstatus -> integer or nil
*
* Returns the least significant eight bits of the return code of
- * _stat_. Only available if <code>exited?</code> is
- * +true+.
+ * _stat_. Only available if #exited? is +true+.
*
* fork { } #=> 26572
* Process.wait #=> 26572
@@ -822,7 +1016,7 @@ pst_wexitstatus(VALUE st)
* stat.success? -> true, false or nil
*
* Returns +true+ if _stat_ is successful, +false+ if not.
- * Returns +nil+ if <code>exited?</code> is not +true+.
+ * Returns +nil+ if #exited? is not +true+.
*/
static VALUE
@@ -859,12 +1053,6 @@ pst_wcoredump(VALUE st)
#endif
}
-struct waitpid_arg {
- rb_pid_t pid;
- int flags;
- int *st;
-};
-
static rb_pid_t
do_waitpid(rb_pid_t pid, int *st, int flags)
{
@@ -877,48 +1065,429 @@ do_waitpid(rb_pid_t pid, int *st, int flags)
#endif
}
+#define WAITPID_LOCK_ONLY ((struct waitpid_state *)-1)
+
+struct waitpid_state {
+ struct list_node wnode;
+ rb_execution_context_t *ec;
+ rb_nativethread_cond_t *cond;
+ rb_pid_t ret;
+ rb_pid_t pid;
+ int status;
+ int options;
+ int errnum;
+};
+
+void rb_native_mutex_lock(rb_nativethread_lock_t *);
+void rb_native_mutex_unlock(rb_nativethread_lock_t *);
+void rb_native_cond_signal(rb_nativethread_cond_t *);
+void rb_native_cond_wait(rb_nativethread_cond_t *, rb_nativethread_lock_t *);
+int rb_sigwait_fd_get(const rb_thread_t *);
+void rb_sigwait_sleep(const rb_thread_t *, int fd, const rb_hrtime_t *);
+void rb_sigwait_fd_put(const rb_thread_t *, int fd);
+void rb_thread_sleep_interruptible(void);
+
+static int
+waitpid_signal(struct waitpid_state *w)
+{
+ if (w->ec) { /* rb_waitpid */
+ rb_threadptr_interrupt(rb_ec_thread_ptr(w->ec));
+ return TRUE;
+ }
+ else { /* ruby_waitpid_locked */
+ if (w->cond) {
+ rb_native_cond_signal(w->cond);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * When a thread is done using sigwait_fd and there are other threads
+ * sleeping on waitpid, we must kick one of the threads out of
+ * rb_native_cond_wait so it can switch to rb_sigwait_sleep
+ */
+static void
+sigwait_fd_migrate_sleeper(rb_vm_t *vm)
+{
+ struct waitpid_state *w = 0;
+
+ list_for_each(&vm->waiting_pids, w, wnode) {
+ if (waitpid_signal(w)) return;
+ }
+ list_for_each(&vm->waiting_grps, w, wnode) {
+ if (waitpid_signal(w)) return;
+ }
+}
+
+void
+rb_sigwait_fd_migrate(rb_vm_t *vm)
+{
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ sigwait_fd_migrate_sleeper(vm);
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+}
+
+#if RUBY_SIGCHLD
+extern volatile unsigned int ruby_nocldwait; /* signal.c */
+/* called by timer thread or thread which acquired sigwait_fd */
+static void
+waitpid_each(struct list_head *head)
+{
+ struct waitpid_state *w = 0, *next;
+
+ list_for_each_safe(head, w, next, wnode) {
+ rb_pid_t ret = do_waitpid(w->pid, &w->status, w->options | WNOHANG);
+
+ if (!ret) continue;
+ if (ret == -1) w->errnum = errno;
+
+ w->ret = ret;
+ list_del_init(&w->wnode);
+ waitpid_signal(w);
+ }
+}
+#else
+# define ruby_nocldwait 0
+#endif
+
+void
+ruby_waitpid_all(rb_vm_t *vm)
+{
+#if RUBY_SIGCHLD
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ waitpid_each(&vm->waiting_pids);
+ if (list_empty(&vm->waiting_pids)) {
+ waitpid_each(&vm->waiting_grps);
+ }
+ /* emulate SA_NOCLDWAIT */
+ if (list_empty(&vm->waiting_pids) && list_empty(&vm->waiting_grps)) {
+ while (ruby_nocldwait && do_waitpid(-1, 0, WNOHANG) > 0)
+ ; /* keep looping */
+ }
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+#endif
+}
+
+static void
+waitpid_state_init(struct waitpid_state *w, rb_pid_t pid, int options)
+{
+ w->ret = 0;
+ w->pid = pid;
+ w->options = options;
+ w->errnum = 0;
+ w->status = 0;
+}
+
+static const rb_hrtime_t *
+sigwait_sleep_time(void)
+{
+ if (SIGCHLD_LOSSY) {
+ static const rb_hrtime_t busy_wait = 100 * RB_HRTIME_PER_MSEC;
+
+ return &busy_wait;
+ }
+ return 0;
+}
+
+/*
+ * must be called with vm->waitpid_lock held, this is not interruptible
+ */
+rb_pid_t
+ruby_waitpid_locked(rb_vm_t *vm, rb_pid_t pid, int *status, int options,
+ rb_nativethread_cond_t *cond)
+{
+ struct waitpid_state w;
+
+ assert(!ruby_thread_has_gvl_p() && "must not have GVL");
+
+ waitpid_state_init(&w, pid, options);
+ if (w.pid > 0 || list_empty(&vm->waiting_pids))
+ w.ret = do_waitpid(w.pid, &w.status, w.options | WNOHANG);
+ if (w.ret) {
+ if (w.ret == -1) w.errnum = errno;
+ }
+ else {
+ int sigwait_fd = -1;
+
+ w.ec = 0;
+ list_add(w.pid > 0 ? &vm->waiting_pids : &vm->waiting_grps, &w.wnode);
+ do {
+ if (sigwait_fd < 0)
+ sigwait_fd = rb_sigwait_fd_get(0);
+
+ if (sigwait_fd >= 0) {
+ w.cond = 0;
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+ rb_sigwait_sleep(0, sigwait_fd, sigwait_sleep_time());
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ }
+ else {
+ w.cond = cond;
+ rb_native_cond_wait(w.cond, &vm->waitpid_lock);
+ }
+ } while (!w.ret);
+ list_del(&w.wnode);
+
+ /* we're done, maybe other waitpid callers are not: */
+ if (sigwait_fd >= 0) {
+ rb_sigwait_fd_put(0, sigwait_fd);
+ sigwait_fd_migrate_sleeper(vm);
+ }
+ }
+ if (status) {
+ *status = w.status;
+ }
+ if (w.ret == -1) errno = w.errnum;
+ return w.ret;
+}
+
+static VALUE
+waitpid_sleep(VALUE x)
+{
+ struct waitpid_state *w = (struct waitpid_state *)x;
+
+ while (!w->ret) {
+ rb_thread_sleep_interruptible();
+ }
+
+ return Qfalse;
+}
+
+static VALUE
+waitpid_cleanup(VALUE x)
+{
+ struct waitpid_state *w = (struct waitpid_state *)x;
+
+ /*
+ * XXX w->ret is sometimes set but list_del is still needed, here,
+ * Not sure why, so we unconditionally do list_del here:
+ */
+ if (TRUE || w->ret == 0) {
+ rb_vm_t *vm = rb_ec_vm_ptr(w->ec);
+
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ list_del(&w->wnode);
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+ }
+
+ return Qfalse;
+}
+
+static void
+waitpid_wait(struct waitpid_state *w)
+{
+ rb_vm_t *vm = rb_ec_vm_ptr(w->ec);
+ int need_sleep = FALSE;
+
+ /*
+ * Lock here to prevent do_waitpid from stealing work from the
+ * ruby_waitpid_locked done by mjit workers since mjit works
+ * outside of GVL
+ */
+ rb_native_mutex_lock(&vm->waitpid_lock);
+
+ if (w->pid > 0 || list_empty(&vm->waiting_pids)) {
+ w->ret = do_waitpid(w->pid, &w->status, w->options | WNOHANG);
+ }
+
+ if (w->ret) {
+ if (w->ret == -1) w->errnum = errno;
+ }
+ else if (w->options & WNOHANG) {
+ }
+ else {
+ need_sleep = TRUE;
+ }
+
+ if (need_sleep) {
+ w->cond = 0;
+ /* order matters, favor specified PIDs rather than -1 or 0 */
+ list_add(w->pid > 0 ? &vm->waiting_pids : &vm->waiting_grps, &w->wnode);
+ }
+
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+
+ if (need_sleep) {
+ rb_ensure(waitpid_sleep, (VALUE)w, waitpid_cleanup, (VALUE)w);
+ }
+}
+
static void *
-rb_waitpid_blocking(void *data)
+waitpid_blocking_no_SIGCHLD(void *x)
{
- struct waitpid_arg *arg = data;
- rb_pid_t result = do_waitpid(arg->pid, arg->st, arg->flags);
- return (void *)(VALUE)result;
+ struct waitpid_state *w = x;
+
+ w->ret = do_waitpid(w->pid, &w->status, w->options);
+
+ return 0;
}
-static rb_pid_t
-do_waitpid_nonblocking(rb_pid_t pid, int *st, int flags)
+static void
+waitpid_no_SIGCHLD(struct waitpid_state *w)
+{
+ if (w->options & WNOHANG) {
+ w->ret = do_waitpid(w->pid, &w->status, w->options);
+ }
+ else {
+ do {
+ rb_thread_call_without_gvl(waitpid_blocking_no_SIGCHLD, w,
+ RUBY_UBF_PROCESS, 0);
+ } while (w->ret < 0 && errno == EINTR && (RUBY_VM_CHECK_INTS(w->ec),1));
+ }
+ if (w->ret == -1)
+ w->errnum = errno;
+}
+
+VALUE
+rb_process_status_wait(rb_pid_t pid, int flags)
{
- void *result;
- struct waitpid_arg arg;
- arg.pid = pid;
- arg.st = st;
- arg.flags = flags;
- result = rb_thread_call_without_gvl(rb_waitpid_blocking, &arg,
- RUBY_UBF_PROCESS, 0);
- return (rb_pid_t)(VALUE)result;
+ // We only enter the scheduler if we are "blocking":
+ if (!(flags & WNOHANG)) {
+ VALUE scheduler = rb_scheduler_current();
+ if (rb_scheduler_supports_process_wait(scheduler)) {
+ return rb_scheduler_process_wait(scheduler, pid, flags);
+ }
+ }
+
+ COROUTINE_STACK_LOCAL(struct waitpid_state, w);
+
+ waitpid_state_init(w, pid, flags);
+ w->ec = GET_EC();
+
+ if (WAITPID_USE_SIGCHLD) {
+ waitpid_wait(w);
+ }
+ else {
+ waitpid_no_SIGCHLD(w);
+ }
+
+ rb_pid_t ret = w->ret;
+ int s = w->status, e = w->errnum;
+ COROUTINE_STACK_FREE(w);
+
+ if (ret == 0) return Qnil;
+ if (ret > 0 && ruby_nocldwait) {
+ ret = -1;
+ e = ECHILD;
+ }
+
+ return rb_process_status_new(ret, s, e);
+}
+
+/*
+ * call-seq:
+ * Process::Status.wait(pid=-1, flags=0) -> Process::Status
+ *
+ * Waits for a child process to exit and returns a Process::Status object
+ * containing information on that process. Which child it waits on
+ * depends on the value of _pid_:
+ *
+ * > 0:: Waits for the child whose process ID equals _pid_.
+ *
+ * 0:: Waits for any child whose process group ID equals that of the
+ * calling process.
+ *
+ * -1:: Waits for any child process (the default if no _pid_ is
+ * given).
+ *
+ * < -1:: Waits for any child whose process group ID equals the absolute
+ * value of _pid_.
+ *
+ * The _flags_ argument may be a logical or of the flag values
+ * Process::WNOHANG (do not block if no child available)
+ * or Process::WUNTRACED (return stopped children that
+ * haven't been reported). Not all flags are available on all
+ * platforms, but a flag value of zero will work on all platforms.
+ *
+ * Returns +nil+ if there are no child processes.
+ * Not available on all platforms.
+ *
+ * May invoke the scheduler hook _process_wait_.
+ *
+ * fork { exit 99 } #=> 27429
+ * Process::Status.wait #=> pid 27429 exit 99
+ * $? #=> nil
+ *
+ * pid = fork { sleep 3 } #=> 27440
+ * Time.now #=> 2008-03-08 19:56:16 +0900
+ * Process::Status.wait(pid, Process::WNOHANG) #=> nil
+ * Time.now #=> 2008-03-08 19:56:16 +0900
+ * Process::Status.wait(pid, 0) #=> pid 27440 exit 99
+ * Time.now #=> 2008-03-08 19:56:19 +0900
+ *
+ * This is an EXPERIMENTAL FEATURE.
+ */
+
+VALUE
+rb_process_status_waitv(int argc, VALUE *argv, VALUE _)
+{
+ rb_check_arity(argc, 0, 2);
+
+ rb_pid_t pid = -1;
+ int flags = 0;
+
+ if (argc >= 1) {
+ pid = NUM2PIDT(argv[0]);
+ }
+
+ if (argc >= 2) {
+ flags = RB_NUM2INT(argv[1]);
+ }
+
+ return rb_process_status_wait(pid, flags);
}
rb_pid_t
rb_waitpid(rb_pid_t pid, int *st, int flags)
{
- rb_pid_t result;
+ VALUE status = rb_process_status_wait(pid, flags);
+ if (NIL_P(status)) return 0;
+
+ struct rb_process_status *data = RTYPEDDATA_DATA(status);
+ pid = data->pid;
- if (flags & WNOHANG) {
- result = do_waitpid(pid, st, flags);
+ if (st) *st = data->status;
+
+ if (pid == -1) {
+ errno = data->error;
}
else {
- while ((result = do_waitpid_nonblocking(pid, st, flags)) < 0 &&
- (errno == EINTR)) {
- rb_thread_t *th = GET_THREAD();
- RUBY_VM_CHECK_INTS(th);
- }
+ GET_THREAD()->last_status = status;
}
- if (result > 0) {
- rb_last_status_set(*st, result);
- }
- return result;
+
+ return pid;
}
+static VALUE
+proc_wait(int argc, VALUE *argv)
+{
+ rb_pid_t pid;
+ int flags, status;
+
+ flags = 0;
+ if (rb_check_arity(argc, 0, 2) == 0) {
+ pid = -1;
+ }
+ else {
+ VALUE vflags;
+ pid = NUM2PIDT(argv[0]);
+ if (argc == 2 && !NIL_P(vflags = argv[1])) {
+ flags = NUM2UINT(vflags);
+ }
+ }
+
+ if ((pid = rb_waitpid(pid, &status, flags)) < 0)
+ rb_sys_fail(0);
+
+ if (pid == 0) {
+ rb_last_status_clear();
+ return Qnil;
+ }
+
+ return PIDT2NUM(pid);
+}
/* [MG]:FIXME: I wasn't sure how this should be done, since ::wait()
has historically been documented as if it didn't take any arguments
@@ -941,7 +1510,7 @@ rb_waitpid(rb_pid_t pid, int *st, int flags)
* Process.waitpid(pid=-1, flags=0) -> integer
*
* Waits for a child process to exit, returns its process id, and
- * sets <code>$?</code> to a <code>Process::Status</code> object
+ * sets <code>$?</code> to a Process::Status object
* containing information on that process. Which child it waits on
* depends on the value of _pid_:
*
@@ -957,8 +1526,8 @@ rb_waitpid(rb_pid_t pid, int *st, int flags)
* value of _pid_.
*
* The _flags_ argument may be a logical or of the flag values
- * <code>Process::WNOHANG</code> (do not block if no child available)
- * or <code>Process::WUNTRACED</code> (return stopped children that
+ * Process::WNOHANG (do not block if no child available)
+ * or Process::WUNTRACED (return stopped children that
* haven't been reported). Not all flags are available on all
* platforms, but a flag value of zero will work on all platforms.
*
@@ -979,29 +1548,9 @@ rb_waitpid(rb_pid_t pid, int *st, int flags)
*/
static VALUE
-proc_wait(int argc, VALUE *argv)
+proc_m_wait(int c, VALUE *v, VALUE _)
{
- rb_pid_t pid;
- int flags, status;
-
- flags = 0;
- if (rb_check_arity(argc, 0, 2) == 0) {
- pid = -1;
- }
- else {
- VALUE vflags;
- pid = NUM2PIDT(argv[0]);
- if (argc == 2 && !NIL_P(vflags = argv[1])) {
- flags = NUM2UINT(vflags);
- }
- }
- if ((pid = rb_waitpid(pid, &status, flags)) < 0)
- rb_sys_fail(0);
- if (pid == 0) {
- rb_last_status_clear();
- return Qnil;
- }
- return PIDT2NUM(pid);
+ return proc_wait(c, v);
}
@@ -1012,7 +1561,7 @@ proc_wait(int argc, VALUE *argv)
*
* Waits for a child process to exit (see Process::waitpid for exact
* semantics) and returns an array containing the process id and the
- * exit status (a <code>Process::Status</code> object) of that
+ * exit status (a Process::Status object) of that
* child. Raises a SystemCallError if there are no child processes.
*
* Process.fork { exit 99 } #=> 27437
@@ -1022,7 +1571,7 @@ proc_wait(int argc, VALUE *argv)
*/
static VALUE
-proc_wait2(int argc, VALUE *argv)
+proc_wait2(int argc, VALUE *argv, VALUE _)
{
VALUE pid = proc_wait(argc, argv);
if (NIL_P(pid)) return Qnil;
@@ -1036,7 +1585,7 @@ proc_wait2(int argc, VALUE *argv)
*
* Waits for all children, returning an array of
* _pid_/_status_ pairs (where _status_ is a
- * <code>Process::Status</code> object).
+ * Process::Status object).
*
* fork { sleep 0.2; exit 2 } #=> 27432
* fork { sleep 0.1; exit 1 } #=> 27433
@@ -1051,7 +1600,7 @@ proc_wait2(int argc, VALUE *argv)
*/
static VALUE
-proc_waitall(void)
+proc_waitall(VALUE _)
{
VALUE result;
rb_pid_t pid;
@@ -1111,18 +1660,17 @@ rb_detach_process(rb_pid_t pid)
* processes until the parent collects that status (normally using
* some variant of <code>wait()</code>). If the parent never collects
* this status, the child stays around as a <em>zombie</em> process.
- * <code>Process::detach</code> prevents this by setting up a
- * separate Ruby thread whose sole job is to reap the status of the
- * process _pid_ when it terminates. Use <code>detach</code>
- * only when you do not intend to explicitly wait for the child to
- * terminate.
+ * Process::detach prevents this by setting up a separate Ruby thread
+ * whose sole job is to reap the status of the process _pid_ when it
+ * terminates. Use #detach only when you do not intend to explicitly
+ * wait for the child to terminate.
*
* The waiting thread returns the exit status of the detached process
- * when it terminates, so you can use <code>Thread#join</code> to
+ * when it terminates, so you can use Thread#join to
* know the result. If specified _pid_ is not a valid child process
* ID, the thread returns +nil+ immediately.
*
- * The waiting thread has <code>pid</code> method which returns the pid.
+ * The waiting thread has #pid method which returns the pid.
*
* In this first example, we don't reap the first child process, so
* it appears as a zombie in the process status display.
@@ -1137,7 +1685,7 @@ rb_detach_process(rb_pid_t pid)
*
* 27389 Z
*
- * In the next example, <code>Process::detach</code> is used to reap
+ * In the next example, Process::detach is used to reap
* the child automatically.
*
* p1 = fork { sleep 0.1 }
@@ -1177,6 +1725,39 @@ before_exec_non_async_signal_safe(void)
rb_thread_stop_timer_thread();
}
+#define WRITE_CONST(fd, str) (void)(write((fd),(str),sizeof(str)-1)<0)
+#ifdef _WIN32
+int rb_w32_set_nonblock2(int fd, int nonblock);
+#endif
+
+static int
+set_blocking(int fd)
+{
+#ifdef _WIN32
+ return rb_w32_set_nonblock2(fd, 0);
+#elif defined(F_GETFL) && defined(F_SETFL)
+ int fl = fcntl(fd, F_GETFL); /* async-signal-safe */
+
+ /* EBADF ought to be possible */
+ if (fl == -1) return fl;
+ if (fl & O_NONBLOCK) {
+ fl &= ~O_NONBLOCK;
+ return fcntl(fd, F_SETFL, fl);
+ }
+ return 0;
+#endif
+}
+
+static void
+stdfd_clear_nonblock(void)
+{
+ /* many programs cannot deal with non-blocking stdin/stdout/stderr */
+ int fd;
+ for (fd = 0; fd < 3; fd++) {
+ (void)set_blocking(fd); /* can't do much about errors anyhow */
+ }
+}
+
static void
before_exec(void)
{
@@ -1204,25 +1785,25 @@ after_exec(void)
after_exec_non_async_signal_safe();
}
-#define before_fork_ruby() before_exec()
-#define after_fork_ruby() (rb_threadptr_pending_interrupt_clear(GET_THREAD()), after_exec())
-
-#include "dln.h"
+#if defined HAVE_WORKING_FORK || defined HAVE_DAEMON
+static void
+before_fork_ruby(void)
+{
+ before_exec();
+}
static void
-security(const char *str)
+after_fork_ruby(void)
{
- if (rb_env_path_tainted()) {
- if (rb_safe_level() > 0) {
- rb_raise(rb_eSecurityError, "Insecure PATH - %s", str);
- }
- }
+ rb_threadptr_pending_interrupt_clear(GET_THREAD());
+ after_exec();
}
+#endif
-#if defined(HAVE_WORKING_FORK) && !defined(__native_client__)
+#if defined(HAVE_WORKING_FORK)
/* try_with_sh and exec_with_sh should be async-signal-safe. Actually it is.*/
-#define try_with_sh(prog, argv, envp) ((saved_errno == ENOEXEC) ? exec_with_sh((prog), (argv), (envp)) : (void)0)
+#define try_with_sh(err, prog, argv, envp) ((err == ENOEXEC) ? exec_with_sh((prog), (argv), (envp)) : (void)0)
static void
exec_with_sh(const char *prog, char **argv, char **envp)
{
@@ -1235,40 +1816,37 @@ exec_with_sh(const char *prog, char **argv, char **envp)
}
#else
-#define try_with_sh(prog, argv, envp) (void)0
+#define try_with_sh(err, prog, argv, envp) (void)0
#endif
/* This function should be async-signal-safe. Actually it is. */
static int
proc_exec_cmd(const char *prog, VALUE argv_str, VALUE envp_str)
{
-#ifdef __native_client__
- rb_notimplement();
- UNREACHABLE;
-#else
char **argv;
#ifndef _WIN32
char **envp;
+ int err;
#endif
argv = ARGVSTR2ARGV(argv_str);
if (!prog) {
- errno = ENOENT;
- return -1;
+ return ENOENT;
}
#ifdef _WIN32
rb_w32_uaspawn(P_OVERLAY, prog, argv);
+ return errno;
#else
- envp = envp_str ? (char **)RSTRING_PTR(envp_str) : NULL;
+ envp = envp_str ? RB_IMEMO_TMPBUF_PTR(envp_str) : NULL;
if (envp_str)
execve(prog, argv, envp); /* async-signal-safe */
else
execv(prog, argv); /* async-signal-safe (since SUSv4) */
- preserving_errno(try_with_sh(prog, argv, envp)); /* try_with_sh() is async-signal-safe. */
-#endif
- return -1;
+ err = errno;
+ try_with_sh(err, prog, argv, envp); /* try_with_sh() is async-signal-safe. */
+ return err;
#endif
}
@@ -1276,10 +1854,6 @@ proc_exec_cmd(const char *prog, VALUE argv_str, VALUE envp_str)
static int
proc_exec_sh(const char *str, VALUE envp_str)
{
-#ifdef __native_client__
- rb_notimplement();
- UNREACHABLE;
-#else
const char *s;
s = str;
@@ -1287,15 +1861,12 @@ proc_exec_sh(const char *str, VALUE envp_str)
s++;
if (!*s) {
- errno = ENOENT;
- return -1;
+ return ENOENT;
}
#ifdef _WIN32
rb_w32_uspawn(P_OVERLAY, (char *)str, 0);
- return -1;
-#else
-#if defined(__CYGWIN32__)
+#elif defined(__CYGWIN32__)
{
char fbuf[MAXPATHLEN];
char *shell = dln_find_exe_r("sh", 0, fbuf, sizeof(fbuf));
@@ -1309,13 +1880,11 @@ proc_exec_sh(const char *str, VALUE envp_str)
}
#else
if (envp_str)
- execle("/bin/sh", "sh", "-c", str, (char *)NULL, (char **)RSTRING_PTR(envp_str)); /* async-signal-safe */
+ execle("/bin/sh", "sh", "-c", str, (char *)NULL, RB_IMEMO_TMPBUF_PTR(envp_str)); /* async-signal-safe */
else
execl("/bin/sh", "sh", "-c", str, (char *)NULL); /* async-signal-safe (since SUSv4) */
-#endif
- return -1;
#endif /* _WIN32 */
-#endif
+ return errno;
}
int
@@ -1324,8 +1893,9 @@ rb_proc_exec(const char *str)
int ret;
before_exec();
ret = proc_exec_sh(str, Qfalse);
- preserving_errno(after_exec());
- return ret;
+ after_exec();
+ errno = ret;
+ return -1;
}
static void
@@ -1405,7 +1975,6 @@ proc_spawn_cmd_internal(char **argv, char *prog)
if (!prog)
prog = argv[0];
- security(prog);
prog = dln_find_exe_r(prog, 0, fbuf, sizeof(fbuf));
if (!prog)
return -1;
@@ -1486,7 +2055,7 @@ check_exec_redirect_fd(VALUE v, int iskey)
else
goto wrong;
}
- else if (!NIL_P(tmp = rb_check_convert_type_with_id(v, T_FILE, "IO", idTo_io))) {
+ else if (!NIL_P(tmp = rb_io_check_io(v))) {
rb_io_t *fptr;
GetOpenFile(tmp, fptr);
if (fptr->tied_io_for_writing)
@@ -1494,8 +2063,7 @@ check_exec_redirect_fd(VALUE v, int iskey)
fd = fptr->fd;
}
else {
- wrong:
- rb_raise(rb_eArgError, "wrong exec redirect");
+ goto wrong;
}
if (fd < 0) {
rb_raise(rb_eArgError, "negative file descriptor");
@@ -1506,6 +2074,10 @@ check_exec_redirect_fd(VALUE v, int iskey)
}
#endif
return INT2FIX(fd);
+
+ wrong:
+ rb_raise(rb_eArgError, "wrong exec redirect");
+ UNREACHABLE_RETURN(Qundef);
}
static VALUE
@@ -1519,12 +2091,11 @@ check_exec_redirect1(VALUE ary, VALUE key, VALUE param)
rb_ary_push(ary, hide_obj(rb_assoc_new(fd, param)));
}
else {
- int i, n=0;
+ int i;
for (i = 0 ; i < RARRAY_LEN(key); i++) {
VALUE v = RARRAY_AREF(key, i);
VALUE fd = check_exec_redirect_fd(v, !NIL_P(param));
rb_ary_push(ary, hide_obj(rb_assoc_new(fd, param)));
- n++;
}
}
return ary;
@@ -1540,7 +2111,7 @@ check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp)
switch (TYPE(val)) {
case T_SYMBOL:
- if (!(id = rb_check_id(&val))) goto wrong_symbol;
+ id = rb_check_id(&val);
if (id == id_close) {
param = Qnil;
eargp->fd_close = check_exec_redirect1(eargp->fd_close, key, param);
@@ -1558,7 +2129,6 @@ check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp)
eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
}
else {
- wrong_symbol:
rb_raise(rb_eArgError, "wrong exec redirect symbol: %"PRIsVALUE,
val);
}
@@ -1607,7 +2177,7 @@ check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp)
else if (RB_TYPE_P(key, T_ARRAY)) {
int i;
for (i = 0; i < RARRAY_LEN(key); i++) {
- VALUE v = RARRAY_PTR(key)[i];
+ VALUE v = RARRAY_AREF(key, i);
VALUE fd = check_exec_redirect_fd(v, 1);
if (FIX2INT(fd) != 1 && FIX2INT(fd) != 2) break;
}
@@ -1665,6 +2235,7 @@ rb_execarg_addopt_rlimit(struct rb_execarg *eargp, int rtype, VALUE val)
}
#endif
+#define TO_BOOL(val, name) NIL_P(val) ? 0 : rb_bool_expected((val), name)
int
rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
{
@@ -1712,7 +2283,7 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
rb_raise(rb_eArgError, "new_pgroup option specified twice");
}
eargp->new_pgroup_given = 1;
- eargp->new_pgroup_flag = RTEST(val) ? 1 : 0;
+ eargp->new_pgroup_flag = TO_BOOL(val, "new_pgroup");
}
else
#endif
@@ -1721,7 +2292,7 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
rb_raise(rb_eArgError, "unsetenv_others option specified twice");
}
eargp->unsetenv_others_given = 1;
- eargp->unsetenv_others_do = RTEST(val) ? 1 : 0;
+ eargp->unsetenv_others_do = TO_BOOL(val, "unsetenv_others");
}
else if (id == id_chdir) {
if (eargp->chdir_given) {
@@ -1745,7 +2316,7 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
rb_raise(rb_eArgError, "close_others option specified twice");
}
eargp->close_others_given = 1;
- eargp->close_others_do = RTEST(val) ? 1 : 0;
+ eargp->close_others_do = TO_BOOL(val, "close_others");
}
else if (id == id_in) {
key = INT2FIX(0);
@@ -1789,6 +2360,13 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
"gid option is unimplemented on this machine");
#endif
}
+ else if (id == id_exception) {
+ if (eargp->exception_given) {
+ rb_raise(rb_eArgError, "exception option specified twice");
+ }
+ eargp->exception_given = 1;
+ eargp->exception = TO_BOOL(val, "exception");
+ }
else {
return ST_STOP;
}
@@ -1921,7 +2499,7 @@ rb_check_exec_options(VALUE opthash, VALUE execarg_obj)
{
if (RHASH_EMPTY_P(opthash))
return;
- st_foreach(rb_hash_tbl_raw(opthash), check_exec_options_i, (st_data_t)execarg_obj);
+ rb_hash_stlike_foreach(opthash, check_exec_options_i, (st_data_t)execarg_obj);
}
VALUE
@@ -1932,7 +2510,7 @@ rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash)
return Qnil;
args[0] = execarg_obj;
args[1] = Qnil;
- st_foreach(rb_hash_tbl_raw(opthash), check_exec_options_i_extract, (st_data_t)args);
+ rb_hash_stlike_foreach(opthash, check_exec_options_i_extract, (st_data_t)args);
return args[1];
}
@@ -1953,7 +2531,7 @@ check_exec_env_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
k = StringValueCStr(key);
if (strchr(k, '='))
- rb_raise(rb_eArgError, "environment name contains a equal : %s", k);
+ rb_raise(rb_eArgError, "environment name contains a equal : %"PRIsVALUE, key);
if (!NIL_P(val))
StringValueCStr(val);
@@ -1976,7 +2554,7 @@ rb_check_exec_env(VALUE hash, VALUE *path)
env[0] = hide_obj(rb_ary_new());
env[1] = Qfalse;
- st_foreach(rb_hash_tbl_raw(hash), check_exec_env_i, (st_data_t)env);
+ rb_hash_stlike_foreach(hash, check_exec_env_i, (st_data_t)env);
*path = env[1];
return env[0];
@@ -1987,7 +2565,6 @@ rb_check_argv(int argc, VALUE *argv)
{
VALUE tmp, prog;
int i;
- const char *name = 0;
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
@@ -2002,14 +2579,12 @@ rb_check_argv(int argc, VALUE *argv)
SafeStringValue(prog);
StringValueCStr(prog);
prog = rb_str_new_frozen(prog);
- name = RSTRING_PTR(prog);
}
for (i = 0; i < argc; i++) {
SafeStringValue(argv[i]);
argv[i] = rb_str_new_frozen(argv[i]);
StringValueCStr(argv[i]);
}
- security(name ? name : RSTRING_PTR(argv[0]));
return prog;
}
@@ -2021,6 +2596,8 @@ check_hash(VALUE obj)
case T_STRING:
case T_ARRAY:
return Qnil;
+ default:
+ break;
}
return rb_check_hash_type(obj);
}
@@ -2202,7 +2779,9 @@ rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, VAL
}
}
eargp->invoke.cmd.argv_buf = argv_buf;
- eargp->invoke.cmd.command_name = hide_obj(rb_str_new_cstr(RSTRING_PTR(argv_buf)));
+ eargp->invoke.cmd.command_name =
+ hide_obj(rb_str_subseq(argv_buf, 0, strlen(RSTRING_PTR(argv_buf))));
+ rb_enc_copy(eargp->invoke.cmd.command_name, prog);
}
}
#endif
@@ -2248,22 +2827,12 @@ rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, VAL
p += strlen(p) + 1;
}
rb_str_buf_cat(argv_str, (char *)&null, sizeof(null)); /* terminator for execve. */
- eargp->invoke.cmd.argv_str = argv_str;
+ eargp->invoke.cmd.argv_str =
+ rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(argv_str);
}
RB_GC_GUARD(execarg_obj);
}
-VALUE
-rb_execarg_new(int argc, const VALUE *argv, int accept_shell)
-{
- VALUE execarg_obj;
- struct rb_execarg *eargp;
- execarg_obj = TypedData_Make_Struct(rb_cData, struct rb_execarg, &exec_arg_data_type, eargp);
- hide_obj(execarg_obj);
- rb_execarg_init(argc, argv, accept_shell, execarg_obj);
- return execarg_obj;
-}
-
struct rb_execarg *
rb_execarg_get(VALUE execarg_obj)
{
@@ -2272,7 +2841,7 @@ rb_execarg_get(VALUE execarg_obj)
return eargp;
}
-VALUE
+static VALUE
rb_execarg_init(int argc, const VALUE *orig_argv, int accept_shell, VALUE execarg_obj)
{
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
@@ -2289,6 +2858,19 @@ rb_execarg_init(int argc, const VALUE *orig_argv, int accept_shell, VALUE execar
return ret;
}
+VALUE
+rb_execarg_new(int argc, const VALUE *argv, int accept_shell, int allow_exc_opt)
+{
+ VALUE execarg_obj;
+ struct rb_execarg *eargp;
+ execarg_obj = TypedData_Make_Struct(0, struct rb_execarg, &exec_arg_data_type, eargp);
+ rb_execarg_init(argc, argv, accept_shell, execarg_obj);
+ if (!allow_exc_opt && eargp->exception_given) {
+ rb_raise(rb_eArgError, "exception option is not allowed");
+ }
+ return execarg_obj;
+}
+
void
rb_execarg_setenv(VALUE execarg_obj, VALUE env)
{
@@ -2333,6 +2915,14 @@ open_func(void *ptr)
return NULL;
}
+static void
+rb_execarg_allocate_dup2_tmpbuf(struct rb_execarg *eargp, long len)
+{
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, ruby_xmalloc(run_exec_dup2_tmpbuf_size(len)));
+ eargp->dup2_tmpbuf = tmpbuf;
+}
+
static VALUE
rb_execarg_parent_start1(VALUE execarg_obj)
{
@@ -2350,13 +2940,11 @@ rb_execarg_parent_start1(VALUE execarg_obj)
VALUE param = RARRAY_AREF(elt, 1);
VALUE vpath = RARRAY_AREF(param, 0);
int flags = NUM2INT(RARRAY_AREF(param, 1));
- int perm = NUM2INT(RARRAY_AREF(param, 2));
+ mode_t perm = NUM2MODET(RARRAY_AREF(param, 2));
VALUE fd2v = RARRAY_AREF(param, 3);
int fd2;
if (NIL_P(fd2v)) {
struct open_struct open_data;
- FilePathValue(vpath);
- vpath = rb_str_encode_ospath(vpath);
again:
open_data.fname = vpath;
open_data.oflags = flags;
@@ -2387,10 +2975,7 @@ rb_execarg_parent_start1(VALUE execarg_obj)
ary = eargp->fd_dup2;
if (ary != Qfalse) {
- size_t len = run_exec_dup2_tmpbuf_size(RARRAY_LEN(ary));
- VALUE tmpbuf = hide_obj(rb_str_new(0, len));
- rb_str_set_len(tmpbuf, len);
- eargp->dup2_tmpbuf = tmpbuf;
+ rb_execarg_allocate_dup2_tmpbuf(eargp, RARRAY_LEN(ary));
}
unsetenv_others = eargp->unsetenv_others_given && eargp->unsetenv_others_do;
@@ -2403,7 +2988,7 @@ rb_execarg_parent_start1(VALUE execarg_obj)
}
else {
envtbl = rb_const_get(rb_cObject, id_ENV);
- envtbl = rb_convert_type_with_id(envtbl, T_HASH, "Hash", idTo_hash);
+ envtbl = rb_to_hash_type(envtbl);
}
hide_obj(envtbl);
if (envopts != Qfalse) {
@@ -2426,7 +3011,7 @@ rb_execarg_parent_start1(VALUE execarg_obj)
}
envp_buf = rb_str_buf_new(0);
hide_obj(envp_buf);
- st_foreach(RHASH_TBL_RAW(envtbl), fill_envp_buf_i, (st_data_t)envp_buf);
+ rb_hash_stlike_foreach(envtbl, fill_envp_buf_i, (st_data_t)envp_buf);
envp_str = rb_str_buf_new(sizeof(char*) * (RHASH_SIZE(envtbl) + 1));
hide_obj(envp_str);
p = RSTRING_PTR(envp_buf);
@@ -2437,7 +3022,8 @@ rb_execarg_parent_start1(VALUE execarg_obj)
}
p = NULL;
rb_str_buf_cat(envp_str, (char *)&p, sizeof(p));
- eargp->envp_str = envp_str;
+ eargp->envp_str =
+ rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(envp_str);
eargp->envp_buf = envp_buf;
/*
@@ -2519,6 +3105,40 @@ rb_execarg_fail(VALUE execarg_obj, int err, const char *errmsg)
}
#endif
+VALUE
+rb_f_exec(int argc, const VALUE *argv)
+{
+ VALUE execarg_obj, fail_str;
+ struct rb_execarg *eargp;
+#define CHILD_ERRMSG_BUFLEN 80
+ char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' };
+ int err, state;
+
+ execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
+ eargp = rb_execarg_get(execarg_obj);
+ if (mjit_enabled) mjit_finish(false); // avoid leaking resources, and do not leave files. XXX: JIT-ed handle can leak after exec error is rescued.
+ before_exec(); /* stop timer thread before redirects */
+
+ rb_protect(rb_execarg_parent_start1, execarg_obj, &state);
+ if (state) {
+ execarg_parent_end(execarg_obj);
+ after_exec(); /* restart timer thread */
+ rb_jump_tag(state);
+ }
+
+ fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
+
+ err = exec_async_signal_safe(eargp, errmsg, sizeof(errmsg));
+ after_exec(); /* restart timer thread */
+
+ rb_exec_fail(eargp, err, errmsg);
+ RB_GC_GUARD(execarg_obj);
+ rb_syserr_fail_str(err, fail_str);
+ UNREACHABLE_RETURN(Qnil);
+}
+
+NORETURN(static VALUE f_exec(int c, const VALUE *a, VALUE _));
+
/*
* call-seq:
* exec([env,] command... [,options])
@@ -2570,7 +3190,7 @@ rb_execarg_fail(VALUE execarg_obj, int err, const char *errmsg)
* This behavior is modified by the given +env+ and +options+ parameters. See
* ::spawn for details.
*
- * If the command fails to execute (typically <code>Errno::ENOENT</code> when
+ * If the command fails to execute (typically Errno::ENOENT when
* it was not found) a SystemCallError exception is raised.
*
* This method modifies process attributes according to given +options+ before
@@ -2592,30 +3212,11 @@ rb_execarg_fail(VALUE execarg_obj, int err, const char *errmsg)
* # never get here
*/
-VALUE
-rb_f_exec(int argc, const VALUE *argv)
+static VALUE
+f_exec(int c, const VALUE *a, VALUE _)
{
- VALUE execarg_obj, fail_str;
- struct rb_execarg *eargp;
-#define CHILD_ERRMSG_BUFLEN 80
- char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' };
- int err;
-
- execarg_obj = rb_execarg_new(argc, argv, TRUE);
- eargp = rb_execarg_get(execarg_obj);
- before_exec(); /* stop timer thread before redirects */
- rb_execarg_parent_start(execarg_obj);
- fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
-
- rb_exec_async_signal_safe(eargp, errmsg, sizeof(errmsg));
-
- err = errno;
- after_exec(); /* restart timer thread */
-
- rb_exec_fail(eargp, err, errmsg);
- RB_GC_GUARD(execarg_obj);
- rb_syserr_fail_str(err, fail_str);
- UNREACHABLE;
+ rb_f_exec(c, a);
+ UNREACHABLE_RETURN(Qnil);
}
#define ERRMSG(str) do { if (errmsg && 0 < errmsg_buflen) strlcpy(errmsg, (str), errmsg_buflen); } while (0)
@@ -2755,10 +3356,10 @@ run_exec_dup2(VALUE ary, VALUE tmpbuf, struct rb_execarg *sargp, char *errmsg, s
long n, i;
int ret;
int extra_fd = -1;
- struct run_exec_dup2_fd_pair *pairs = 0;
+ struct rb_imemo_tmpbuf_struct *buf = (void *)tmpbuf;
+ struct run_exec_dup2_fd_pair *pairs = (void *)buf->ptr;
n = RARRAY_LEN(ary);
- pairs = (struct run_exec_dup2_fd_pair *)RSTRING_PTR(tmpbuf);
/* initialize oldfd and newfd: O(n) */
for (i = 0; i < n; i++) {
@@ -3091,7 +3692,7 @@ rb_execarg_run_options(const struct rb_execarg *eargp, struct rb_execarg *sargp,
}
#ifdef HAVE_WORKING_FORK
- if (!eargp->close_others_given || eargp->close_others_do) {
+ if (eargp->close_others_do) {
rb_close_before_exec(3, eargp->close_others_maxhint, eargp->redirect_fds); /* async-signal-safe */
}
#endif
@@ -3104,10 +3705,8 @@ rb_execarg_run_options(const struct rb_execarg *eargp, struct rb_execarg *sargp,
if (eargp->chdir_given) {
if (sargp) {
- char *cwd = my_getcwd();
sargp->chdir_given = 1;
- sargp->chdir_dir = hide_obj(rb_str_new2(cwd));
- xfree(cwd);
+ sargp->chdir_dir = hide_obj(rb_dir_getwd_ospath());
}
if (chdir(RSTRING_PTR(eargp->chdir_dir)) == -1) { /* async-signal-safe */
ERRMSG("chdir");
@@ -3135,12 +3734,14 @@ rb_execarg_run_options(const struct rb_execarg *eargp, struct rb_execarg *sargp,
if (sargp) {
VALUE ary = sargp->fd_dup2;
if (ary != Qfalse) {
- size_t len = run_exec_dup2_tmpbuf_size(RARRAY_LEN(ary));
- VALUE tmpbuf = hide_obj(rb_str_new(0, len));
- rb_str_set_len(tmpbuf, len);
- sargp->dup2_tmpbuf = tmpbuf;
+ rb_execarg_allocate_dup2_tmpbuf(sargp, RARRAY_LEN(ary));
}
}
+ {
+ int preserve = errno;
+ stdfd_clear_nonblock();
+ errno = preserve;
+ }
return 0;
}
@@ -3149,31 +3750,38 @@ rb_execarg_run_options(const struct rb_execarg *eargp, struct rb_execarg *sargp,
int
rb_exec_async_signal_safe(const struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
{
+ errno = exec_async_signal_safe(eargp, errmsg, errmsg_buflen);
+ return -1;
+}
+
+static int
+exec_async_signal_safe(const struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
+{
#if !defined(HAVE_WORKING_FORK)
struct rb_execarg sarg, *const sargp = &sarg;
#else
struct rb_execarg *const sargp = NULL;
#endif
+ int err;
if (rb_execarg_run_options(eargp, sargp, errmsg, errmsg_buflen) < 0) { /* hopefully async-signal-safe */
- goto failure;
+ return errno;
}
if (eargp->use_shell) {
- proc_exec_sh(RSTRING_PTR(eargp->invoke.sh.shell_script), eargp->envp_str); /* async-signal-safe */
+ err = proc_exec_sh(RSTRING_PTR(eargp->invoke.sh.shell_script), eargp->envp_str); /* async-signal-safe */
}
else {
char *abspath = NULL;
if (!NIL_P(eargp->invoke.cmd.command_abspath))
abspath = RSTRING_PTR(eargp->invoke.cmd.command_abspath);
- proc_exec_cmd(abspath, eargp->invoke.cmd.argv_str, eargp->envp_str); /* async-signal-safe */
+ err = proc_exec_cmd(abspath, eargp->invoke.cmd.argv_str, eargp->envp_str); /* async-signal-safe */
}
#if !defined(HAVE_WORKING_FORK)
- preserving_errno(rb_execarg_run_options(sargp, NULL, errmsg, errmsg_buflen));
+ rb_execarg_run_options(sargp, NULL, errmsg, errmsg_buflen);
#endif
-failure:
- return -1;
+ return err;
}
#ifdef HAVE_WORKING_FORK
@@ -3183,9 +3791,7 @@ rb_exec_atfork(void* arg, char *errmsg, size_t errmsg_buflen)
{
return rb_exec_async_signal_safe(arg, errmsg, errmsg_buflen); /* hopefully async-signal-safe */
}
-#endif
-#ifdef HAVE_WORKING_FORK
#if SIZEOF_INT == SIZEOF_LONG
#define proc_syswait (VALUE (*)(VALUE))rb_syswait
#else
@@ -3243,12 +3849,19 @@ pipe_nocrash(int filedes[2], VALUE fds)
#define O_BINARY 0
#endif
+static VALUE
+rb_thread_sleep_that_takes_VALUE_as_sole_argument(VALUE n)
+{
+ rb_thread_sleep(NUM2INT(n));
+ return Qundef;
+}
+
static int
-handle_fork_error(int *status, int *ep, volatile int *try_gc_p)
+handle_fork_error(int err, int *status, int *ep, volatile int *try_gc_p)
{
int state = 0;
- switch (errno) {
+ switch (err) {
case ENOMEM:
if ((*try_gc_p)-- > 0 && !rb_during_gc()) {
rb_gc();
@@ -3264,14 +3877,16 @@ handle_fork_error(int *status, int *ep, volatile int *try_gc_p)
return 0;
}
else {
- rb_protect((VALUE (*)())rb_thread_sleep, 1, &state);
+ rb_protect(rb_thread_sleep_that_takes_VALUE_as_sole_argument, INT2FIX(1), &state);
if (status) *status = state;
if (!state) return 0;
}
break;
}
if (ep) {
- preserving_errno((close(ep[0]), close(ep[1])));
+ close(ep[0]);
+ close(ep[1]);
+ errno = err;
}
if (state && !status) rb_jump_tag(state);
return -1;
@@ -3325,6 +3940,12 @@ read_retry(int fd, void *buf, size_t len)
{
ssize_t r;
+ if (set_blocking(fd) != 0) {
+#ifndef _WIN32
+ rb_async_bug_errno("set_blocking failed reading child error", errno);
+#endif
+ }
+
do {
r = read(fd, buf, len);
} while (r < 0 && errno == EINTR);
@@ -3470,7 +4091,6 @@ has_privilege(void)
struct child_handler_disabler_state
{
sigset_t sigmask;
- int cancelstate;
};
static void
@@ -3491,13 +4111,6 @@ disable_child_handler_before_fork(struct child_handler_disabler_state *old)
#else
# pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous"
#endif
-
-#ifdef PTHREAD_CANCEL_DISABLE
- ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old->cancelstate);
- if (ret != 0) {
- rb_syserr_fail(ret, "pthread_setcancelstate");
- }
-#endif
}
static void
@@ -3505,13 +4118,6 @@ disable_child_handler_fork_parent(struct child_handler_disabler_state *old)
{
int ret;
-#ifdef PTHREAD_CANCEL_DISABLE
- ret = pthread_setcancelstate(old->cancelstate, NULL);
- if (ret != 0) {
- rb_syserr_fail(ret, "pthread_setcancelstate");
- }
-#endif
-
#ifdef HAVE_PTHREAD_SIGMASK
ret = pthread_sigmask(SIG_SETMASK, &old->sigmask, NULL); /* not async-signal-safe */
if (ret != 0) {
@@ -3550,6 +4156,8 @@ disable_child_handler_fork_child(struct child_handler_disabler_state *old, char
}
}
+ /* non-Ruby child process, ensure cmake can see SIGCHLD */
+ sigemptyset(&old->sigmask);
ret = sigprocmask(SIG_SETMASK, &old->sigmask, NULL); /* async-signal-safe */
if (ret != 0) {
ERRMSG("sigprocmask");
@@ -3561,22 +4169,30 @@ disable_child_handler_fork_child(struct child_handler_disabler_state *old, char
static rb_pid_t
retry_fork_async_signal_safe(int *status, int *ep,
int (*chfunc)(void*, char *, size_t), void *charg,
- char *errmsg, size_t errmsg_buflen)
+ char *errmsg, size_t errmsg_buflen,
+ struct waitpid_state *w)
{
rb_pid_t pid;
volatile int try_gc = 1;
struct child_handler_disabler_state old;
+ int err;
+ rb_nativethread_lock_t *const volatile waitpid_lock_init =
+ (w && WAITPID_USE_SIGCHLD) ? &GET_VM()->waitpid_lock : 0;
while (1) {
+ rb_nativethread_lock_t *waitpid_lock = waitpid_lock_init;
prefork();
disable_child_handler_before_fork(&old);
+ if (waitpid_lock) {
+ rb_native_mutex_lock(waitpid_lock);
+ }
#ifdef HAVE_WORKING_VFORK
if (!has_privilege())
pid = vfork();
else
- pid = fork();
+ pid = rb_fork();
#else
- pid = fork();
+ pid = rb_fork();
#endif
if (pid == 0) {/* fork succeed, child process */
int ret;
@@ -3593,37 +4209,53 @@ retry_fork_async_signal_safe(int *status, int *ep,
_exit(127);
#endif
}
- preserving_errno(disable_child_handler_fork_parent(&old));
+ err = errno;
+ waitpid_lock = waitpid_lock_init;
+ if (waitpid_lock) {
+ if (pid > 0 && w != WAITPID_LOCK_ONLY) {
+ w->pid = pid;
+ list_add(&GET_VM()->waiting_pids, &w->wnode);
+ }
+ rb_native_mutex_unlock(waitpid_lock);
+ }
+ disable_child_handler_fork_parent(&old);
if (0 < pid) /* fork succeed, parent process */
return pid;
/* fork failed */
- if (handle_fork_error(status, ep, &try_gc))
+ if (handle_fork_error(err, status, ep, &try_gc))
return -1;
}
}
-rb_pid_t
-rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds,
- char *errmsg, size_t errmsg_buflen)
+static rb_pid_t
+fork_check_err(int *status, int (*chfunc)(void*, char *, size_t), void *charg,
+ VALUE fds, char *errmsg, size_t errmsg_buflen,
+ struct rb_execarg *eargp)
{
rb_pid_t pid;
int err;
int ep[2];
int error_occurred;
+ struct waitpid_state *w;
+
+ w = eargp && eargp->waitpid_state ? eargp->waitpid_state : 0;
if (status) *status = 0;
if (pipe_nocrash(ep, fds)) return -1;
- pid = retry_fork_async_signal_safe(status, ep, chfunc, charg, errmsg, errmsg_buflen);
+ pid = retry_fork_async_signal_safe(status, ep, chfunc, charg,
+ errmsg, errmsg_buflen, w);
if (pid < 0)
return pid;
close(ep[1]);
error_occurred = recv_child_error(ep[0], &err, errmsg, errmsg_buflen);
if (error_occurred) {
if (status) {
+ VM_ASSERT((w == 0 || w == WAITPID_LOCK_ONLY) &&
+ "only used by extensions");
rb_protect(proc_syswait, (VALUE)pid, status);
}
- else {
+ else if (!w || w == WAITPID_LOCK_ONLY) {
rb_syswait(pid);
}
errno = err;
@@ -3632,45 +4264,46 @@ rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), voi
return pid;
}
-static rb_pid_t
-retry_fork_ruby(int *status, struct child_handler_disabler_state *old)
+/*
+ * The "async_signal_safe" name is a lie, but it is used by pty.c and
+ * maybe other exts. fork() is not async-signal-safe due to pthread_atfork
+ * and future POSIX revisions will remove it from a list of signal-safe
+ * functions. rb_waitpid is not async-signal-safe since MJIT, either.
+ * For our purposes, we do not need async-signal-safety, here
+ */
+rb_pid_t
+rb_fork_async_signal_safe(int *status,
+ int (*chfunc)(void*, char *, size_t), void *charg,
+ VALUE fds, char *errmsg, size_t errmsg_buflen)
{
- rb_pid_t pid;
- int try_gc = 1;
-
- while (1) {
- prefork();
- before_fork_ruby();
- disable_child_handler_before_fork(old);
- pid = fork();
- if (pid == 0) /* fork succeed, child process */
- return pid;
- preserving_errno(after_fork_ruby());
- preserving_errno(disable_child_handler_fork_parent(old));
- if (0 < pid) /* fork succeed, parent process */
- return pid;
- /* fork failed */
- if (handle_fork_error(status, NULL, &try_gc))
- return -1;
- }
+ return fork_check_err(status, chfunc, charg, fds, errmsg, errmsg_buflen, 0);
}
rb_pid_t
rb_fork_ruby(int *status)
{
rb_pid_t pid;
+ int try_gc = 1, err;
struct child_handler_disabler_state old;
if (status) *status = 0;
- pid = retry_fork_ruby(status, &old);
- if (pid < 0)
- return pid;
- if (!pid) {
+ while (1) {
+ prefork();
+ if (mjit_enabled) mjit_pause(false); // Don't leave locked mutex to child. Note: child_handler must be enabled to pause MJIT.
+ disable_child_handler_before_fork(&old);
+ before_fork_ruby();
+ pid = rb_fork();
+ err = errno;
after_fork_ruby();
- disable_child_handler_fork_parent(&old); /* yes, bad name */
+ disable_child_handler_fork_parent(&old); /* yes, bad name */
+ if (mjit_enabled && pid > 0) mjit_resume(); /* child (pid == 0) is cared by rb_thread_atfork */
+ if (pid >= 0) /* fork succeed */
+ return pid;
+ /* fork failed */
+ if (handle_fork_error(err, status, NULL, &try_gc))
+ return -1;
}
- return pid;
}
#endif
@@ -3683,15 +4316,14 @@ rb_fork_ruby(int *status)
*
* Creates a subprocess. If a block is specified, that block is run
* in the subprocess, and the subprocess terminates with a status of
- * zero. Otherwise, the +fork+ call returns twice, once in
- * the parent, returning the process ID of the child, and once in
- * the child, returning _nil_. The child process can exit using
- * <code>Kernel.exit!</code> to avoid running any
- * <code>at_exit</code> functions. The parent process should
- * use <code>Process.wait</code> to collect the termination statuses
- * of its children or use <code>Process.detach</code> to register
- * disinterest in their status; otherwise, the operating system
- * may accumulate zombie processes.
+ * zero. Otherwise, the +fork+ call returns twice, once in the
+ * parent, returning the process ID of the child, and once in the
+ * child, returning _nil_. The child process can exit using
+ * Kernel.exit! to avoid running any <code>at_exit</code>
+ * functions. The parent process should use Process.wait to collect
+ * the termination statuses of its children or use Process.detach to
+ * register disinterest in their status; otherwise, the operating
+ * system may accumulate zombie processes.
*
* The thread calling fork is the only thread in the created child process.
* fork doesn't copy other threads.
@@ -3752,6 +4384,7 @@ exit_status_code(VALUE status)
return istatus;
}
+NORETURN(static VALUE rb_f_exit_bang(int argc, VALUE *argv, VALUE obj));
/*
* call-seq:
* Process.exit!(status=false)
@@ -3776,13 +4409,13 @@ rb_f_exit_bang(int argc, VALUE *argv, VALUE obj)
}
_exit(istatus);
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
void
rb_exit(int status)
{
- if (GET_THREAD()->ec.tag) {
+ if (GET_EC()->tag) {
VALUE args[2];
args[0] = INT2NUM(status);
@@ -3792,7 +4425,23 @@ rb_exit(int status)
ruby_stop(status);
}
+VALUE
+rb_f_exit(int argc, const VALUE *argv)
+{
+ int istatus;
+
+ if (rb_check_arity(argc, 0, 1) == 1) {
+ istatus = exit_status_code(argv[0]);
+ }
+ else {
+ istatus = EXIT_SUCCESS;
+ }
+ rb_exit(istatus);
+
+ UNREACHABLE_RETURN(Qnil);
+}
+NORETURN(static VALUE f_exit(int c, const VALUE *a, VALUE _));
/*
* call-seq:
* exit(status=true)
@@ -3800,7 +4449,7 @@ rb_exit(int status)
* Process::exit(status=true)
*
* Initiates the termination of the Ruby script by raising the
- * <code>SystemExit</code> exception. This exception may be caught. The
+ * SystemExit exception. This exception may be caught. The
* optional parameter is used to return a status code to the invoking
* environment.
* +true+ and +FALSE+ of _status_ means success and failure
@@ -3820,9 +4469,9 @@ rb_exit(int status)
* rescued a SystemExit exception
* after begin block
*
- * Just prior to termination, Ruby executes any <code>at_exit</code> functions
- * (see Kernel::at_exit) and runs any object finalizers (see
- * ObjectSpace::define_finalizer).
+ * Just prior to termination, Ruby executes any <code>at_exit</code>
+ * functions (see Kernel::at_exit) and runs any object finalizers
+ * (see ObjectSpace::define_finalizer).
*
* at_exit { puts "at_exit function" }
* ObjectSpace.define_finalizer("string", proc { puts "in finalizer" })
@@ -3834,43 +4483,22 @@ rb_exit(int status)
* in finalizer
*/
-VALUE
-rb_f_exit(int argc, const VALUE *argv)
+static VALUE
+f_exit(int c, const VALUE *a, VALUE _)
{
- int istatus;
-
- if (rb_check_arity(argc, 0, 1) == 1) {
- istatus = exit_status_code(argv[0]);
- }
- else {
- istatus = EXIT_SUCCESS;
- }
- rb_exit(istatus);
-
- UNREACHABLE;
+ rb_f_exit(c, a);
+ UNREACHABLE_RETURN(Qnil);
}
-
-/*
- * call-seq:
- * abort
- * Kernel::abort([msg])
- * Process.abort([msg])
- *
- * Terminate execution immediately, effectively by calling
- * <code>Kernel.exit(false)</code>. If _msg_ is given, it is written
- * to STDERR prior to terminating.
- */
-
VALUE
rb_f_abort(int argc, const VALUE *argv)
{
rb_check_arity(argc, 0, 1);
if (argc == 0) {
- rb_thread_t *th = GET_THREAD();
- VALUE errinfo = th->ec.errinfo;
+ rb_execution_context_t *ec = GET_EC();
+ VALUE errinfo = rb_ec_get_errinfo(ec);
if (!NIL_P(errinfo)) {
- rb_threadptr_error_print(th, errinfo);
+ rb_ec_error_print(ec, errinfo);
}
rb_exit(EXIT_FAILURE);
}
@@ -3879,12 +4507,32 @@ rb_f_abort(int argc, const VALUE *argv)
args[1] = args[0] = argv[0];
StringValue(args[0]);
- rb_io_puts(1, args, rb_stderr);
+ rb_io_puts(1, args, rb_ractor_stderr());
args[0] = INT2NUM(EXIT_FAILURE);
rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit));
}
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
+}
+
+NORETURN(static VALUE f_abort(int c, const VALUE *a, VALUE _));
+
+/*
+ * call-seq:
+ * abort
+ * Kernel::abort([msg])
+ * Process.abort([msg])
+ *
+ * Terminate execution immediately, effectively by calling
+ * <code>Kernel.exit(false)</code>. If _msg_ is given, it is written
+ * to STDERR prior to terminating.
+ */
+
+static VALUE
+f_abort(int c, const VALUE *a, VALUE _)
+{
+ rb_f_abort(c, a);
+ UNREACHABLE_RETURN(Qnil);
}
void
@@ -3931,7 +4579,7 @@ rb_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
#endif
#if defined HAVE_WORKING_FORK && !USE_SPAWNV
- pid = rb_fork_async_signal_safe(NULL, rb_exec_atfork, eargp, eargp->redirect_fds, errmsg, errmsg_buflen);
+ pid = fork_check_err(0, rb_exec_atfork, eargp, eargp->redirect_fds, errmsg, errmsg_buflen, eargp);
#else
prog = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
@@ -3945,30 +4593,37 @@ rb_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
}
# if defined HAVE_SPAWNV
if (eargp->use_shell) {
- pid = proc_spawn_sh(RSTRING_PTR(prog));
+ pid = proc_spawn_sh(RSTRING_PTR(prog));
}
else {
char **argv = ARGVSTR2ARGV(eargp->invoke.cmd.argv_str);
- pid = proc_spawn_cmd(argv, prog, eargp);
+ pid = proc_spawn_cmd(argv, prog, eargp);
+ }
+
+ if (pid == -1) {
+ rb_last_status_set(0x7f << 8, pid);
}
- if (pid == -1)
- rb_last_status_set(0x7f << 8, 0);
# else
status = system(rb_execarg_commandline(eargp, &prog));
- rb_last_status_set((status & 0xff) << 8, 0);
pid = 1; /* dummy */
+ rb_last_status_set((status & 0xff) << 8, pid);
# endif
+ if (eargp->waitpid_state && eargp->waitpid_state != WAITPID_LOCK_ONLY) {
+ eargp->waitpid_state->pid = pid;
+ }
+
rb_execarg_run_options(&sarg, NULL, errmsg, errmsg_buflen);
#endif
+
return pid;
}
struct spawn_args {
VALUE execarg;
struct {
- char *ptr;
- size_t buflen;
+ char *ptr;
+ size_t buflen;
} errmsg;
};
@@ -3985,6 +4640,15 @@ static rb_pid_t
rb_execarg_spawn(VALUE execarg_obj, char *errmsg, size_t errmsg_buflen)
{
struct spawn_args args;
+ struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
+
+ /*
+ * Prevent a race with MJIT where the compiler process where
+ * can hold an FD of ours in between vfork + execve
+ */
+ if (!eargp->waitpid_state && mjit_enabled) {
+ eargp->waitpid_state = WAITPID_LOCK_ONLY;
+ }
args.execarg = execarg_obj;
args.errmsg.ptr = errmsg;
@@ -3998,7 +4662,7 @@ rb_spawn_internal(int argc, const VALUE *argv, char *errmsg, size_t errmsg_bufle
{
VALUE execarg_obj;
- execarg_obj = rb_execarg_new(argc, argv, TRUE);
+ execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
return rb_execarg_spawn(execarg_obj, errmsg, errmsg_buflen);
}
@@ -4016,25 +4680,31 @@ rb_spawn(int argc, const VALUE *argv)
/*
* call-seq:
- * system([env,] command... [,options]) -> true, false or nil
+ * system([env,] command... [,options], exception: false) -> true, false or nil
*
* Executes _command..._ in a subshell.
* _command..._ is one of following forms.
*
- * commandline : command line string which is passed to the standard shell
- * cmdname, arg1, ... : command name and one or more arguments (no shell)
- * [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
+ * [<code>commandline</code>]
+ * command line string which is passed to the standard shell
+ * [<code>cmdname, arg1, ...</code>]
+ * command name and one or more arguments (no shell)
+ * [<code>[cmdname, argv0], arg1, ...</code>]
+ * command name, <code>argv[0]</code> and zero or more arguments (no shell)
*
* system returns +true+ if the command gives zero exit status,
* +false+ for non zero exit status.
* Returns +nil+ if command execution fails.
* An error status is available in <code>$?</code>.
+ *
+ * If the <code>exception: true</code> argument is passed, the method
+ * raises an exception instead of returning +false+ or +nil+.
+ *
* The arguments are processed in the same way as
- * for <code>Kernel.spawn</code>.
+ * for Kernel#spawn.
*
- * The hash arguments, env and options, are same as
- * <code>exec</code> and <code>spawn</code>.
- * See <code>Kernel.spawn</code> for details.
+ * The hash arguments, env and options, are same as #exec and #spawn.
+ * See Kernel#spawn for details.
*
* system("echo *")
* system("echo", "*")
@@ -4044,43 +4714,77 @@ rb_spawn(int argc, const VALUE *argv)
* config.h main.rb
* *
*
- * See <code>Kernel.exec</code> for the standard shell.
+ * Error handling:
+ *
+ * system("cat nonexistent.txt")
+ * # => false
+ * system("catt nonexistent.txt")
+ * # => nil
+ *
+ * system("cat nonexistent.txt", exception: true)
+ * # RuntimeError (Command failed with exit 1: cat)
+ * system("catt nonexistent.txt", exception: true)
+ * # Errno::ENOENT (No such file or directory - catt)
+ *
+ * See Kernel#exec for the standard shell.
*/
static VALUE
-rb_f_system(int argc, VALUE *argv)
+rb_f_system(int argc, VALUE *argv, VALUE _)
{
- rb_pid_t pid;
- int status;
-
-#if defined(SIGCLD) && !defined(SIGCHLD)
-# define SIGCHLD SIGCLD
-#endif
+ /*
+ * n.b. using alloca for now to simplify future Thread::Light code
+ * when we need to use malloc for non-native Fiber
+ */
+ struct waitpid_state *w = alloca(sizeof(struct waitpid_state));
+ rb_pid_t pid; /* may be different from waitpid_state.pid on exec failure */
+ VALUE execarg_obj;
+ struct rb_execarg *eargp;
+ int exec_errnum;
-#ifdef SIGCHLD
- RETSIGTYPE (*chfunc)(int);
+ execarg_obj = rb_execarg_new(argc, argv, TRUE, TRUE);
+ eargp = rb_execarg_get(execarg_obj);
+ w->ec = GET_EC();
+ waitpid_state_init(w, 0, 0);
+ eargp->waitpid_state = w;
+ pid = rb_execarg_spawn(execarg_obj, 0, 0);
+ exec_errnum = pid < 0 ? errno : 0;
- rb_last_status_clear();
- chfunc = signal(SIGCHLD, SIG_DFL);
-#endif
- pid = rb_spawn_internal(argc, argv, NULL, 0);
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
- if (pid > 0) {
- int ret, status;
- ret = rb_waitpid(pid, &status, 0);
- if (ret == (rb_pid_t)-1)
- rb_sys_fail("Another thread waited the process started by system().");
+ if (w->pid > 0) {
+ /* `pid' (not w->pid) may be < 0 here if execve failed in child */
+ if (WAITPID_USE_SIGCHLD) {
+ rb_ensure(waitpid_sleep, (VALUE)w, waitpid_cleanup, (VALUE)w);
+ }
+ else {
+ waitpid_no_SIGCHLD(w);
+ }
+ rb_last_status_set(w->status, w->ret);
}
#endif
-#ifdef SIGCHLD
- signal(SIGCHLD, chfunc);
-#endif
- if (pid < 0) {
- return Qnil;
+ if (w->pid < 0 /* fork failure */ || pid < 0 /* exec failure */) {
+ if (eargp->exception) {
+ int err = exec_errnum ? exec_errnum : w->errnum;
+ VALUE command = eargp->invoke.sh.shell_script;
+ RB_GC_GUARD(execarg_obj);
+ rb_syserr_fail_str(err, command);
+ }
+ else {
+ return Qnil;
+ }
+ }
+ if (w->status == EXIT_SUCCESS) return Qtrue;
+ if (eargp->exception) {
+ VALUE command = eargp->invoke.sh.shell_script;
+ VALUE str = rb_str_new_cstr("Command failed with");
+ rb_str_cat_cstr(pst_message_status(str, w->status), ": ");
+ rb_str_append(str, command);
+ RB_GC_GUARD(execarg_obj);
+ rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, str));
+ }
+ else {
+ return Qfalse;
}
- status = PST2INT(rb_last_status_get());
- if (status == EXIT_SUCCESS) return Qtrue;
- return Qfalse;
}
/*
@@ -4100,9 +4804,9 @@ rb_f_system(int argc, VALUE *argv)
* to finish.
*
* The parent process should
- * use <code>Process.wait</code> to collect
+ * use Process.wait to collect
* the termination status of its child or
- * use <code>Process.detach</code> to register
+ * use Process.detach to register
* disinterest in their status;
* otherwise, the operating system may accumulate zombie processes.
*
@@ -4152,17 +4856,18 @@ rb_f_system(int argc, VALUE *argv)
* integer : the file descriptor of specified the integer
* io : the file descriptor specified as io.fileno
* file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
- * :close_others => true : don't inherit
+ * :close_others => false : inherit
* current directory:
* :chdir => str
*
- * The 'cmdname, arg1, ...' form does not use the shell. However,
- * on different OSes, different things are provided as built-in
- * commands. An example of this is 'echo', which is a built-in
- * on Windows, but is a normal program on Linux and Mac OS X.
- * This means that `Process.spawn 'echo', '%Path%'` will display
- * the contents of the `%Path%` environment variable on Windows,
- * but `Process.spawn 'echo', '$PATH'` prints the literal '$PATH'.
+ * The <code>cmdname, arg1, ...</code> form does not use the shell.
+ * However, on different OSes, different things are provided as
+ * built-in commands. An example of this is +'echo'+, which is a
+ * built-in on Windows, but is a normal program on Linux and Mac OS X.
+ * This means that <code>Process.spawn 'echo', '%Path%'</code> will
+ * display the contents of the <tt>%Path%</tt> environment variable
+ * on Windows, but <code>Process.spawn 'echo', '$PATH'</code> prints
+ * the literal <tt>$PATH</tt>.
*
* If a hash is given as +env+, the environment is
* updated by +env+ before <code>exec(2)</code> in the child process.
@@ -4232,12 +4937,12 @@ rb_f_system(int argc, VALUE *argv)
* pid = spawn(command, STDERR=>:out)
* pid = spawn(command, STDERR=>STDOUT)
*
- * The hash keys specifies a file descriptor
- * in the child process started by <code>spawn</code>.
+ * The hash keys specifies a file descriptor in the child process
+ * started by #spawn.
* :err, 2 and STDERR specifies the standard error stream (stderr).
*
- * The hash values specifies a file descriptor
- * in the parent process which invokes <code>spawn</code>.
+ * The hash values specifies a file descriptor in the parent process
+ * which invokes #spawn.
* :out, 1 and STDOUT specifies the standard output stream (stdout).
*
* In the above example,
@@ -4311,7 +5016,7 @@ rb_f_system(int argc, VALUE *argv)
* pid = spawn(command, :close_others=>true) # close 3,4,5,... (default)
* pid = spawn(command, :close_others=>false) # don't close 3,4,5,...
*
- * :close_others is true by default for spawn and IO.popen.
+ * :close_others is false by default for spawn and IO.popen.
*
* Note that fds which close-on-exec flag is already set are closed
* regardless of :close_others option.
@@ -4348,18 +5053,18 @@ rb_f_system(int argc, VALUE *argv)
* Internally, +spawn+ uses an extra file descriptor to resolve such cyclic
* file descriptor mapping.
*
- * See <code>Kernel.exec</code> for the standard shell.
+ * See Kernel.exec for the standard shell.
*/
static VALUE
-rb_f_spawn(int argc, VALUE *argv)
+rb_f_spawn(int argc, VALUE *argv, VALUE _)
{
rb_pid_t pid;
char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' };
VALUE execarg_obj, fail_str;
struct rb_execarg *eargp;
- execarg_obj = rb_execarg_new(argc, argv, TRUE);
+ execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj);
fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
@@ -4385,7 +5090,7 @@ rb_f_spawn(int argc, VALUE *argv)
* Suspends the current thread for _duration_ seconds (which may be any number,
* including a +Float+ with fractional seconds). Returns the actual number of
* seconds slept (rounded), which may be less than that asked for if another
- * thread calls <code>Thread#run</code>. Called without an argument, sleep()
+ * thread calls Thread#run. Called without an argument, sleep()
* will sleep forever.
*
* Time.new #=> 2008-03-08 19:56:19 +0900
@@ -4396,22 +5101,27 @@ rb_f_spawn(int argc, VALUE *argv)
*/
static VALUE
-rb_f_sleep(int argc, VALUE *argv)
+rb_f_sleep(int argc, VALUE *argv, VALUE _)
{
- time_t beg, end;
+ time_t beg = time(0);
+ VALUE scheduler = rb_scheduler_current();
- beg = time(0);
- if (argc == 0) {
- rb_thread_sleep_forever();
+ if (scheduler != Qnil) {
+ rb_scheduler_kernel_sleepv(scheduler, argc, argv);
}
else {
- rb_check_arity(argc, 0, 1);
- rb_thread_wait_for(rb_time_interval(argv[0]));
+ if (argc == 0) {
+ rb_thread_sleep_forever();
+ }
+ else {
+ rb_check_arity(argc, 0, 1);
+ rb_thread_wait_for(rb_time_interval(argv[0]));
+ }
}
- end = time(0) - beg;
+ time_t end = time(0) - beg;
- return INT2FIX(end);
+ return TIMET2NUM(end);
}
@@ -4428,7 +5138,7 @@ rb_f_sleep(int argc, VALUE *argv)
*/
static VALUE
-proc_getpgrp(void)
+proc_getpgrp(VALUE _)
{
rb_pid_t pgrp;
@@ -4457,7 +5167,7 @@ proc_getpgrp(void)
*/
static VALUE
-proc_setpgrp(void)
+proc_setpgrp(VALUE _)
{
/* check for posix setpgid() first; this matches the posix */
/* getpgrp() above. It appears that configure will set SETPGRP_VOID */
@@ -4539,7 +5249,7 @@ proc_setpgid(VALUE obj, VALUE pid, VALUE pgrp)
* Process.getsid(Process.pid()) #=> 27422
*/
static VALUE
-proc_getsid(int argc, VALUE *argv)
+proc_getsid(int argc, VALUE *argv, VALUE _)
{
rb_pid_t sid;
rb_pid_t pid = 0;
@@ -4573,7 +5283,7 @@ static rb_pid_t ruby_setsid(void);
*/
static VALUE
-proc_setsid(void)
+proc_setsid(VALUE _)
{
rb_pid_t pid;
@@ -4621,9 +5331,9 @@ ruby_setsid(void)
*
* Gets the scheduling priority for specified process, process group,
* or user. <em>kind</em> indicates the kind of entity to find: one
- * of <code>Process::PRIO_PGRP</code>,
- * <code>Process::PRIO_USER</code>, or
- * <code>Process::PRIO_PROCESS</code>. _integer_ is an id
+ * of Process::PRIO_PGRP,
+ * Process::PRIO_USER, or
+ * Process::PRIO_PROCESS. _integer_ is an id
* indicating the particular process, process group, or user (an id
* of 0 means _current_). Lower priorities are more favorable
* for scheduling. Not available on all platforms.
@@ -4655,7 +5365,7 @@ proc_getpriority(VALUE obj, VALUE which, VALUE who)
* call-seq:
* Process.setpriority(kind, integer, priority) -> 0
*
- * See <code>Process#getpriority</code>.
+ * See Process.getpriority.
*
* Process.setpriority(Process::PRIO_USER, 0, 19) #=> 0
* Process.setpriority(Process::PRIO_PROCESS, 0, 19) #=> 0
@@ -4857,7 +5567,7 @@ rlimit_resource_type(VALUE rtype)
rb_raise(rb_eArgError, "invalid resource name: % "PRIsVALUE, rtype);
- UNREACHABLE;
+ UNREACHABLE_RETURN(-1);
}
static rlim_t
@@ -4898,7 +5608,7 @@ rlimit_resource_value(VALUE rval)
#endif
rb_raise(rb_eArgError, "invalid resource value: %"PRIsVALUE, rval);
- UNREACHABLE;
+ UNREACHABLE_RETURN((rlim_t)-1);
}
#endif
@@ -4914,12 +5624,12 @@ rlimit_resource_value(VALUE rval)
* _resource_ indicates the kind of resource to limit.
* It is specified as a symbol such as <code>:CORE</code>,
* a string such as <code>"CORE"</code> or
- * a constant such as <code>Process::RLIMIT_CORE</code>.
+ * a constant such as Process::RLIMIT_CORE.
* See Process.setrlimit for details.
*
- * _cur_limit_ and _max_limit_ may be <code>Process::RLIM_INFINITY</code>,
- * <code>Process::RLIM_SAVED_MAX</code> or
- * <code>Process::RLIM_SAVED_CUR</code>.
+ * _cur_limit_ and _max_limit_ may be Process::RLIM_INFINITY,
+ * Process::RLIM_SAVED_MAX or
+ * Process::RLIM_SAVED_CUR.
* See Process.setrlimit and the system getrlimit(2) manual for details.
*/
@@ -4952,7 +5662,7 @@ proc_getrlimit(VALUE obj, VALUE resource)
* _resource_ indicates the kind of resource to limit.
* It should be a symbol such as <code>:CORE</code>,
* a string such as <code>"CORE"</code> or
- * a constant such as <code>Process::RLIMIT_CORE</code>.
+ * a constant such as Process::RLIMIT_CORE.
* The available resources are OS dependent.
* Ruby may support following resources.
*
@@ -4975,10 +5685,10 @@ proc_getrlimit(VALUE obj, VALUE resource)
*
* _cur_limit_ and _max_limit_ may be
* <code>:INFINITY</code>, <code>"INFINITY"</code> or
- * <code>Process::RLIM_INFINITY</code>,
+ * Process::RLIM_INFINITY,
* which means that the resource is not limited.
- * They may be <code>Process::RLIM_SAVED_MAX</code>,
- * <code>Process::RLIM_SAVED_CUR</code> and
+ * They may be Process::RLIM_SAVED_MAX,
+ * Process::RLIM_SAVED_CUR and
* corresponding symbols and strings too.
* See system setrlimit(2) manual for details.
*
@@ -5032,14 +5742,254 @@ check_gid_switch(void)
}
+#if defined(HAVE_PWD_H)
+/**
+ * Best-effort attempt to obtain the name of the login user, if any,
+ * associated with the process. Processes not descended from login(1) (or
+ * similar) may not have a logged-in user; returns Qnil in that case.
+ */
+VALUE
+rb_getlogin(void)
+{
+#if ( !defined(USE_GETLOGIN_R) && !defined(USE_GETLOGIN) )
+ return Qnil;
+#else
+ char MAYBE_UNUSED(*login) = NULL;
+
+# ifdef USE_GETLOGIN_R
+
+#if defined(__FreeBSD__)
+ typedef int getlogin_r_size_t;
+#else
+ typedef size_t getlogin_r_size_t;
+#endif
+
+ long loginsize = GETLOGIN_R_SIZE_INIT; /* maybe -1 */
+
+ if (loginsize < 0)
+ loginsize = GETLOGIN_R_SIZE_DEFAULT;
+
+ VALUE maybe_result = rb_str_buf_new(loginsize);
+
+ login = RSTRING_PTR(maybe_result);
+ loginsize = rb_str_capacity(maybe_result);
+ rb_str_set_len(maybe_result, loginsize);
+
+ int gle;
+ errno = 0;
+ while ((gle = getlogin_r(login, (getlogin_r_size_t)loginsize)) != 0) {
+
+ if (gle == ENOTTY || gle == ENXIO || gle == ENOENT) {
+ rb_str_resize(maybe_result, 0);
+ return Qnil;
+ }
+
+ if (gle != ERANGE || loginsize >= GETLOGIN_R_SIZE_LIMIT) {
+ rb_str_resize(maybe_result, 0);
+ rb_syserr_fail(gle, "getlogin_r");
+ }
+
+ rb_str_modify_expand(maybe_result, loginsize);
+ login = RSTRING_PTR(maybe_result);
+ loginsize = rb_str_capacity(maybe_result);
+ }
+
+ if (login == NULL) {
+ rb_str_resize(maybe_result, 0);
+ return Qnil;
+ }
+
+ return maybe_result;
+
+# elif USE_GETLOGIN
+
+ errno = 0;
+ login = getlogin();
+ if (errno) {
+ if (errno == ENOTTY || errno == ENXIO || errno == ENOENT) {
+ return Qnil;
+ }
+ rb_syserr_fail(errno, "getlogin");
+ }
+
+ return login ? rb_str_new_cstr(login) : Qnil;
+# endif
+
+#endif
+}
+
+VALUE
+rb_getpwdirnam_for_login(VALUE login_name)
+{
+#if ( !defined(USE_GETPWNAM_R) && !defined(USE_GETPWNAM) )
+ return Qnil;
+#else
+
+ if (NIL_P(login_name)) {
+ /* nothing to do; no name with which to query the password database */
+ return Qnil;
+ }
+
+ char *login = RSTRING_PTR(login_name);
+
+ struct passwd *pwptr;
+
+# ifdef USE_GETPWNAM_R
+
+ struct passwd pwdnm;
+ char *bufnm;
+ long bufsizenm = GETPW_R_SIZE_INIT; /* maybe -1 */
+
+ if (bufsizenm < 0)
+ bufsizenm = GETPW_R_SIZE_DEFAULT;
+
+ VALUE getpwnm_tmp = rb_str_tmp_new(bufsizenm);
+
+ bufnm = RSTRING_PTR(getpwnm_tmp);
+ bufsizenm = rb_str_capacity(getpwnm_tmp);
+ rb_str_set_len(getpwnm_tmp, bufsizenm);
+
+ int enm;
+ errno = 0;
+ while ((enm = getpwnam_r(login, &pwdnm, bufnm, bufsizenm, &pwptr)) != 0) {
+
+ if (enm == ENOENT || enm== ESRCH || enm == EBADF || enm == EPERM) {
+ /* not found; non-errors */
+ rb_str_resize(getpwnm_tmp, 0);
+ return Qnil;
+ }
+
+ if (enm != ERANGE || bufsizenm >= GETPW_R_SIZE_LIMIT) {
+ rb_str_resize(getpwnm_tmp, 0);
+ rb_syserr_fail(enm, "getpwnam_r");
+ }
+
+ rb_str_modify_expand(getpwnm_tmp, bufsizenm);
+ bufnm = RSTRING_PTR(getpwnm_tmp);
+ bufsizenm = rb_str_capacity(getpwnm_tmp);
+ }
+
+ if (pwptr == NULL) {
+ /* no record in the password database for the login name */
+ rb_str_resize(getpwnm_tmp, 0);
+ return Qnil;
+ }
+
+ /* found it */
+ VALUE result = rb_str_new_cstr(pwptr->pw_dir);
+ rb_str_resize(getpwnm_tmp, 0);
+ return result;
+
+# elif USE_GETPWNAM
+
+ errno = 0;
+ pwptr = getpwnam(login);
+ if (pwptr) {
+ /* found it */
+ return rb_str_new_cstr(pwptr->pw_dir);
+ }
+ if (errno
+ /* avoid treating as errors errno values that indicate "not found" */
+ && ( errno != ENOENT && errno != ESRCH && errno != EBADF && errno != EPERM)) {
+ rb_syserr_fail(errno, "getpwnam");
+ }
+
+ return Qnil; /* not found */
+# endif
+
+#endif
+}
+
+/**
+ * Look up the user's dflt home dir in the password db, by uid.
+ */
+VALUE
+rb_getpwdiruid(void)
+{
+# if !defined(USE_GETPWUID_R) && !defined(USE_GETPWUID)
+ /* Should never happen... </famous-last-words> */
+ return Qnil;
+# else
+ uid_t ruid = getuid();
+
+ struct passwd *pwptr;
+
+# ifdef USE_GETPWUID_R
+
+ struct passwd pwdid;
+ char *bufid;
+ long bufsizeid = GETPW_R_SIZE_INIT; /* maybe -1 */
+
+ if (bufsizeid < 0)
+ bufsizeid = GETPW_R_SIZE_DEFAULT;
+
+ VALUE getpwid_tmp = rb_str_tmp_new(bufsizeid);
+
+ bufid = RSTRING_PTR(getpwid_tmp);
+ bufsizeid = rb_str_capacity(getpwid_tmp);
+ rb_str_set_len(getpwid_tmp, bufsizeid);
+
+ int eid;
+ errno = 0;
+ while ((eid = getpwuid_r(ruid, &pwdid, bufid, bufsizeid, &pwptr)) != 0) {
+
+ if (eid == ENOENT || eid== ESRCH || eid == EBADF || eid == EPERM) {
+ /* not found; non-errors */
+ rb_str_resize(getpwid_tmp, 0);
+ return Qnil;
+ }
+
+ if (eid != ERANGE || bufsizeid >= GETPW_R_SIZE_LIMIT) {
+ rb_str_resize(getpwid_tmp, 0);
+ rb_syserr_fail(eid, "getpwuid_r");
+ }
+
+ rb_str_modify_expand(getpwid_tmp, bufsizeid);
+ bufid = RSTRING_PTR(getpwid_tmp);
+ bufsizeid = rb_str_capacity(getpwid_tmp);
+ }
+
+ if (pwptr == NULL) {
+ /* no record in the password database for the uid */
+ rb_str_resize(getpwid_tmp, 0);
+ return Qnil;
+ }
+
+ /* found it */
+ VALUE result = rb_str_new_cstr(pwptr->pw_dir);
+ rb_str_resize(getpwid_tmp, 0);
+ return result;
+
+# elif defined(USE_GETPWUID)
+
+ errno = 0;
+ pwptr = getpwuid(ruid);
+ if (pwptr) {
+ /* found it */
+ return rb_str_new_cstr(pwptr->pw_dir);
+ }
+ if (errno
+ /* avoid treating as errors errno values that indicate "not found" */
+ && ( errno == ENOENT || errno == ESRCH || errno == EBADF || errno == EPERM)) {
+ rb_syserr_fail(errno, "getpwuid");
+ }
+
+ return Qnil; /* not found */
+# endif
+
+#endif /* !defined(USE_GETPWUID_R) && !defined(USE_GETPWUID) */
+}
+#endif /* HAVE_PWD_H */
+
+
/*********************************************************************
* Document-class: Process::Sys
*
- * The <code>Process::Sys</code> module contains UID and GID
+ * The Process::Sys module contains UID and GID
* functions which provide direct bindings to the system calls of the
* same names instead of the more-portable versions of the same
- * functionality found in the <code>Process</code>,
- * <code>Process::UID</code>, and <code>Process::GID</code> modules.
+ * functionality found in the Process,
+ * Process::UID, and Process::GID modules.
*/
#if defined(HAVE_PWD_H)
@@ -5089,7 +6039,7 @@ obj2uid(VALUE id
#ifndef USE_GETPWNAM_R
endpwent();
#endif
- rb_raise(rb_eArgError, "can't find user for %s", usrname);
+ rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, id);
}
uid = pwptr->pw_uid;
#ifndef USE_GETPWNAM_R
@@ -5168,7 +6118,7 @@ obj2gid(VALUE id
#if !defined(USE_GETGRNAM_R) && defined(HAVE_ENDGRENT)
endgrent();
#endif
- rb_raise(rb_eArgError, "can't find group for %s", grpname);
+ rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, id);
}
gid = grptr->gr_gid;
#if !defined(USE_GETGRNAM_R) && defined(HAVE_ENDGRENT)
@@ -5386,7 +6336,7 @@ proc_setuid(VALUE obj, VALUE id)
*
* Document-class: Process::UID
*
- * The <code>Process::UID</code> module contains a collection of
+ * The Process::UID module contains a collection of
* module functions which can be used to portably get, set, and
* switch the current process's real, effective, and saved user IDs.
*
@@ -5660,11 +6610,9 @@ static VALUE
p_sys_setregid(VALUE obj, VALUE rid, VALUE eid)
{
rb_gid_t rgid, egid;
- PREPARE_GETGRNAM;
check_gid_switch();
rgid = OBJ2GID(rid);
egid = OBJ2GID(eid);
- FINISH_GETGRNAM;
if (setregid(rgid, egid) != 0) rb_sys_fail(0);
return Qnil;
}
@@ -5688,12 +6636,10 @@ static VALUE
p_sys_setresgid(VALUE obj, VALUE rid, VALUE eid, VALUE sid)
{
rb_gid_t rgid, egid, sgid;
- PREPARE_GETGRNAM;
check_gid_switch();
rgid = OBJ2GID(rid);
egid = OBJ2GID(eid);
sgid = OBJ2GID(sid);
- FINISH_GETGRNAM;
if (setresgid(rgid, egid, sgid) != 0) rb_sys_fail(0);
return Qnil;
}
@@ -5841,11 +6787,24 @@ maxgroups(void)
* call-seq:
* Process.groups -> array
*
- * Get an <code>Array</code> of the gids of groups in the
+ * Get an Array of the group IDs in the
* supplemental group access list for this process.
*
* Process.groups #=> [27, 6, 10, 11]
*
+ * Note that this method is just a wrapper of getgroups(2).
+ * This means that the following characteristics of
+ * the result completely depend on your system:
+ *
+ * - the result is sorted
+ * - the result includes effective GIDs
+ * - the result does not include duplicated GIDs
+ *
+ * You can make sure to get a sorted unique GID list of
+ * the current process by this expression:
+ *
+ * Process.groups.uniq.sort
+ *
*/
static VALUE
@@ -5884,7 +6843,7 @@ proc_getgroups(VALUE obj)
* Process.groups= array -> array
*
* Set the supplemental group access list to the given
- * <code>Array</code> of group IDs.
+ * Array of group IDs.
*
* Process.groups #=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]
* Process.groups = [27, 6, 10, 11] #=> [27, 6, 10, 11]
@@ -5935,7 +6894,7 @@ proc_setgroups(VALUE obj, VALUE ary)
* Initializes the supplemental group access list by reading the
* system group database and using all groups of which the given user
* is a member. The group with the specified <em>gid</em> is also
- * added to the list. Returns the resulting <code>Array</code> of the
+ * added to the list. Returns the resulting Array of the
* gids of all the groups in the supplementary group access list. Not
* available on all platforms.
*
@@ -5948,7 +6907,7 @@ proc_setgroups(VALUE obj, VALUE ary)
static VALUE
proc_initgroups(VALUE obj, VALUE uname, VALUE base_grp)
{
- if (initgroups(StringValuePtr(uname), OBJ2GID(base_grp)) != 0) {
+ if (initgroups(StringValueCStr(uname), OBJ2GID(base_grp)) != 0) {
rb_sys_fail(0);
}
return proc_getgroups(obj);
@@ -5993,7 +6952,7 @@ proc_setmaxgroups(VALUE obj, VALUE val)
int ngroups_max = get_sc_ngroups_max();
if (ngroups <= 0)
- rb_raise(rb_eArgError, "maxgroups %d shold be positive", ngroups);
+ rb_raise(rb_eArgError, "maxgroups %d should be positive", ngroups);
if (ngroups > RB_MAX_GROUPS)
ngroups = RB_MAX_GROUPS;
@@ -6027,13 +6986,13 @@ static int rb_daemon(int nochdir, int noclose);
*/
static VALUE
-proc_daemon(int argc, VALUE *argv)
+proc_daemon(int argc, VALUE *argv, VALUE _)
{
int n, nochdir = FALSE, noclose = FALSE;
switch (rb_check_arity(argc, 0, 2)) {
- case 2: noclose = RTEST(argv[1]);
- case 1: nochdir = RTEST(argv[0]);
+ case 2: noclose = TO_BOOL(argv[1], "noclose");
+ case 1: nochdir = TO_BOOL(argv[0], "nochdir");
}
prefork();
@@ -6047,10 +7006,11 @@ rb_daemon(int nochdir, int noclose)
{
int err = 0;
#ifdef HAVE_DAEMON
+ if (mjit_enabled) mjit_pause(false); // Don't leave locked mutex to child.
before_fork_ruby();
err = daemon(nochdir, noclose);
after_fork_ruby();
- rb_thread_atfork();
+ rb_thread_atfork(); /* calls mjit_resume() */
#else
int n;
@@ -6090,7 +7050,7 @@ rb_daemon(int nochdir, int noclose)
*
* Document-class: Process::GID
*
- * The <code>Process::GID</code> module contains a collection of
+ * The Process::GID module contains a collection of
* module functions which can be used to portably get, set, and
* switch the current process's real, effective, and saved group IDs.
*
@@ -6545,7 +7505,7 @@ p_gid_grant_privilege(VALUE obj, VALUE id)
*/
static VALUE
-p_uid_exchangeable(void)
+p_uid_exchangeable(VALUE _)
{
#if defined(HAVE_SETRESUID)
return Qtrue;
@@ -6607,7 +7567,7 @@ p_uid_exchange(VALUE obj)
*/
static VALUE
-p_gid_exchangeable(void)
+p_gid_exchangeable(VALUE _)
{
#if defined(HAVE_SETRESGID)
return Qtrue;
@@ -6670,7 +7630,7 @@ p_gid_exchange(VALUE obj)
*/
static VALUE
-p_uid_have_saved_id(void)
+p_uid_have_saved_id(VALUE _)
{
#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)
return Qtrue;
@@ -6682,8 +7642,9 @@ p_uid_have_saved_id(void)
#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)
static VALUE
-p_uid_sw_ensure(rb_uid_t id)
+p_uid_sw_ensure(VALUE i)
{
+ rb_uid_t id = (rb_uid_t/* narrowing */)i;
under_uid_switch = 0;
id = rb_seteuid_core(id);
return UIDT2NUM(id);
@@ -6737,7 +7698,7 @@ p_uid_switch(VALUE obj)
rb_syserr_fail(EPERM, 0);
}
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
#else
static VALUE
@@ -6784,7 +7745,7 @@ p_uid_switch(VALUE obj)
*/
static VALUE
-p_gid_have_saved_id(void)
+p_gid_have_saved_id(VALUE _)
{
#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)
return Qtrue;
@@ -6795,8 +7756,9 @@ p_gid_have_saved_id(void)
#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)
static VALUE
-p_gid_sw_ensure(rb_gid_t id)
+p_gid_sw_ensure(VALUE i)
{
+ rb_gid_t id = (rb_gid_t/* narrowing */)i;
under_gid_switch = 0;
id = rb_setegid_core(id);
return GIDT2NUM(id);
@@ -6850,7 +7812,7 @@ p_gid_switch(VALUE obj)
rb_syserr_fail(EPERM, 0);
}
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
}
#else
static VALUE
@@ -6889,27 +7851,22 @@ p_gid_switch(VALUE obj)
static long
get_clk_tck(void)
{
- long hertz =
#ifdef HAVE__SC_CLK_TCK
- (double)sysconf(_SC_CLK_TCK);
+ return sysconf(_SC_CLK_TCK);
+#elif defined CLK_TCK
+ return CLK_TCK;
+#elif defined HZ
+ return HZ;
#else
-#ifndef HZ
-# ifdef CLK_TCK
-# define HZ CLK_TCK
-# else
-# define HZ 60
-# endif
-#endif /* HZ */
- HZ;
+ return 60;
#endif
- return hertz;
}
/*
* call-seq:
* Process.times -> aProcessTms
*
- * Returns a <code>Tms</code> structure (see <code>Process::Tms</code>)
+ * Returns a <code>Tms</code> structure (see Process::Tms)
* that contains user and system CPU times for this process,
* and also for children processes.
*
@@ -6931,7 +7888,7 @@ rb_proc_times(VALUE obj)
cutime = DBL2NUM((double)usage_c.ru_utime.tv_sec + (double)usage_c.ru_utime.tv_usec/1e6);
cstime = DBL2NUM((double)usage_c.ru_stime.tv_sec + (double)usage_c.ru_stime.tv_usec/1e6);
#else
- const double hertz = get_clk_tck();
+ const double hertz = (double)get_clk_tck();
struct tms buf;
times(&buf);
@@ -7141,7 +8098,7 @@ make_clock_result(struct timetick *ttp,
}
#ifdef __APPLE__
-static mach_timebase_info_data_t *
+static const mach_timebase_info_data_t *
get_mach_timebase_info(void)
{
static mach_timebase_info_data_t sTimebaseInfo;
@@ -7152,6 +8109,14 @@ get_mach_timebase_info(void)
return &sTimebaseInfo;
}
+
+double
+ruby_real_ms_time(void)
+{
+ const mach_timebase_info_data_t *info = get_mach_timebase_info();
+ uint64_t t = mach_absolute_time();
+ return (double)t * info->numer / info->denom / 1e6;
+}
#endif
/*
@@ -7172,7 +8137,7 @@ get_mach_timebase_info(void)
*
* [CLOCK_REALTIME] SUSv2 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS 10.12
* [CLOCK_MONOTONIC] SUSv3 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS 10.12
- * [CLOCK_PROCESS_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, OpenBSD 5.4, macOS 10.12
+ * [CLOCK_PROCESS_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, FreeBSD 9.3, OpenBSD 5.4, macOS 10.12
* [CLOCK_THREAD_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12
* [CLOCK_VIRTUAL] FreeBSD 3.0, OpenBSD 2.1
* [CLOCK_PROF] FreeBSD 3.0, OpenBSD 2.1
@@ -7193,6 +8158,7 @@ get_mach_timebase_info(void)
* [CLOCK_UPTIME_RAW_APPROX] macOS 10.12
* [CLOCK_UPTIME_PRECISE] FreeBSD 8.1
* [CLOCK_SECOND] FreeBSD 8.1
+ * [CLOCK_TAI] Linux 3.10
*
* Note that SUS stands for Single Unix Specification.
* SUS contains POSIX and clock_gettime is defined in the POSIX part.
@@ -7280,8 +8246,8 @@ get_mach_timebase_info(void)
* So the result can be interpreted differently across systems.
* Time.now is recommended over CLOCK_REALTIME.
*/
-VALUE
-rb_clock_gettime(int argc, VALUE *argv)
+static VALUE
+rb_clock_gettime(int argc, VALUE *argv, VALUE _)
{
int ret;
@@ -7297,8 +8263,9 @@ rb_clock_gettime(int argc, VALUE *argv)
if (SYMBOL_P(clk_id)) {
/*
* Non-clock_gettime clocks are provided by symbol clk_id.
- *
- * gettimeofday is always available on platforms supported by Ruby.
+ */
+#ifdef HAVE_GETTIMEOFDAY
+ /*
* GETTIMEOFDAY_BASED_CLOCK_REALTIME is used for
* CLOCK_REALTIME if clock_gettime is not available.
*/
@@ -7313,6 +8280,7 @@ rb_clock_gettime(int argc, VALUE *argv)
denominators[num_denominators++] = 1000000000;
goto success;
}
+#endif
#define RUBY_TIME_BASED_CLOCK_REALTIME ID2SYM(id_TIME_BASED_CLOCK_REALTIME)
if (clk_id == RUBY_TIME_BASED_CLOCK_REALTIME) {
@@ -7405,7 +8373,7 @@ rb_clock_gettime(int argc, VALUE *argv)
#ifdef __APPLE__
#define RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC ID2SYM(id_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC)
if (clk_id == RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC) {
- mach_timebase_info_data_t *info = get_mach_timebase_info();
+ const mach_timebase_info_data_t *info = get_mach_timebase_info();
uint64_t t = mach_absolute_time();
tt.count = (int32_t)(t % 1000000000);
tt.giga_count = t / 1000000000;
@@ -7441,42 +8409,46 @@ rb_clock_gettime(int argc, VALUE *argv)
* call-seq:
* Process.clock_getres(clock_id [, unit]) -> number
*
- * Returns the time resolution returned by POSIX clock_getres() function.
+ * Returns an estimate of the resolution of a +clock_id+ using the POSIX
+ * <code>clock_getres()</code> function.
+ *
+ * Note the reported resolution is often inaccurate on most platforms due to
+ * underlying bugs for this function and therefore the reported resolution
+ * often differs from the actual resolution of the clock in practice.
+ * Inaccurate reported resolutions have been observed for various clocks including
+ * CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW when using Linux, macOS, BSD or AIX
+ * platforms, when using ARM processors, or when using virtualization.
*
* +clock_id+ specifies a kind of clock.
* See the document of +Process.clock_gettime+ for details.
- *
- * +clock_id+ can be a symbol as +Process.clock_gettime+.
- * However the result may not be accurate.
- * For example, +Process.clock_getres(:GETTIMEOFDAY_BASED_CLOCK_REALTIME)+
- * returns 1.0e-06 which means 1 microsecond, but actual resolution can be more coarse.
+ * +clock_id+ can be a symbol as for +Process.clock_gettime+.
*
* If the given +clock_id+ is not supported, Errno::EINVAL is raised.
*
- * +unit+ specifies a type of the return value.
+ * +unit+ specifies the type of the return value.
* +Process.clock_getres+ accepts +unit+ as +Process.clock_gettime+.
- * The default value, +:float_second+, is also same as
+ * The default value, +:float_second+, is also the same as
* +Process.clock_gettime+.
*
* +Process.clock_getres+ also accepts +:hertz+ as +unit+.
- * +:hertz+ means a the reciprocal of +:float_second+.
+ * +:hertz+ means the reciprocal of +:float_second+.
*
* +:hertz+ can be used to obtain the exact value of
- * the clock ticks per second for times() function and
- * CLOCKS_PER_SEC for clock() function.
+ * the clock ticks per second for the times() function and
+ * CLOCKS_PER_SEC for the clock() function.
*
- * +Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
+ * <code>Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)</code>
* returns the clock ticks per second.
*
- * +Process.clock_getres(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
+ * <code>Process.clock_getres(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)</code>
* returns CLOCKS_PER_SEC.
*
* p Process.clock_getres(Process::CLOCK_MONOTONIC)
* #=> 1.0e-09
*
*/
-VALUE
-rb_clock_getres(int argc, VALUE *argv)
+static VALUE
+rb_clock_getres(int argc, VALUE *argv, VALUE _)
{
struct timetick tt;
timetick_int_t numerators[2];
@@ -7544,7 +8516,7 @@ rb_clock_getres(int argc, VALUE *argv)
#ifdef RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC
if (clk_id == RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC) {
- mach_timebase_info_data_t *info = get_mach_timebase_info();
+ const mach_timebase_info_data_t *info = get_mach_timebase_info();
tt.count = 1;
tt.giga_count = 0;
numerators[num_numerators++] = info->numer;
@@ -7579,32 +8551,88 @@ rb_clock_getres(int argc, VALUE *argv)
}
}
+static VALUE
+get_CHILD_STATUS(ID _x, VALUE *_y)
+{
+ return rb_last_status_get();
+}
+
+static VALUE
+get_PROCESS_ID(ID _x, VALUE *_y)
+{
+ return get_pid();
+}
+
+/*
+ * call-seq:
+ * Process.kill(signal, pid, ...) -> integer
+ *
+ * Sends the given signal to the specified process id(s) if _pid_ is positive.
+ * If _pid_ is zero, _signal_ is sent to all processes whose group ID is equal
+ * to the group ID of the process. If _pid_ is negative, results are dependent
+ * on the operating system. _signal_ may be an integer signal number or
+ * a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is
+ * negative (or starts with a minus sign), kills process groups instead of
+ * processes. Not all signals are available on all platforms.
+ * The keys and values of Signal.list are known signal names and numbers,
+ * respectively.
+ *
+ * pid = fork do
+ * Signal.trap("HUP") { puts "Ouch!"; exit }
+ * # ... do some work ...
+ * end
+ * # ...
+ * Process.kill("HUP", pid)
+ * Process.wait
+ *
+ * <em>produces:</em>
+ *
+ * Ouch!
+ *
+ * If _signal_ is an integer but wrong for signal, Errno::EINVAL or
+ * RangeError will be raised. Otherwise unless _signal_ is a String
+ * or a Symbol, and a known signal name, ArgumentError will be
+ * raised.
+ *
+ * Also, Errno::ESRCH or RangeError for invalid _pid_, Errno::EPERM
+ * when failed because of no privilege, will be raised. In these
+ * cases, signals may have been sent to preceding processes.
+ */
+
+static VALUE
+proc_rb_f_kill(int c, const VALUE *v, VALUE _)
+{
+ return rb_f_kill(c, v);
+}
+
VALUE rb_mProcess;
-VALUE rb_mProcUID;
-VALUE rb_mProcGID;
-VALUE rb_mProcID_Syscall;
+static VALUE rb_mProcUID;
+static VALUE rb_mProcGID;
+static VALUE rb_mProcID_Syscall;
/*
- * The <code>Process</code> module is a collection of methods used to
+ * The Process module is a collection of methods used to
* manipulate processes.
*/
void
InitVM_process(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
- rb_define_virtual_variable("$?", rb_last_status_get, 0);
- rb_define_virtual_variable("$$", get_pid, 0);
- rb_define_global_function("exec", rb_f_exec, -1);
+ rb_define_virtual_variable("$?", get_CHILD_STATUS, 0);
+ rb_define_virtual_variable("$$", get_PROCESS_ID, 0);
+
+ rb_gvar_ractor_local("$$");
+ rb_gvar_ractor_local("$?");
+
+ rb_define_global_function("exec", f_exec, -1);
rb_define_global_function("fork", rb_f_fork, 0);
rb_define_global_function("exit!", rb_f_exit_bang, -1);
rb_define_global_function("system", rb_f_system, -1);
rb_define_global_function("spawn", rb_f_spawn, -1);
rb_define_global_function("sleep", rb_f_sleep, -1);
- rb_define_global_function("exit", rb_f_exit, -1);
- rb_define_global_function("abort", rb_f_abort, -1);
+ rb_define_global_function("exit", f_exit, -1);
+ rb_define_global_function("abort", f_abort, -1);
rb_mProcess = rb_define_module("Process");
@@ -7623,28 +8651,35 @@ InitVM_process(void)
rb_define_const(rb_mProcess, "WUNTRACED", INT2FIX(0));
#endif
- rb_define_singleton_method(rb_mProcess, "exec", rb_f_exec, -1);
+ rb_define_singleton_method(rb_mProcess, "exec", f_exec, -1);
rb_define_singleton_method(rb_mProcess, "fork", rb_f_fork, 0);
rb_define_singleton_method(rb_mProcess, "spawn", rb_f_spawn, -1);
rb_define_singleton_method(rb_mProcess, "exit!", rb_f_exit_bang, -1);
- rb_define_singleton_method(rb_mProcess, "exit", rb_f_exit, -1);
- rb_define_singleton_method(rb_mProcess, "abort", rb_f_abort, -1);
+ rb_define_singleton_method(rb_mProcess, "exit", f_exit, -1);
+ rb_define_singleton_method(rb_mProcess, "abort", f_abort, -1);
+ rb_define_singleton_method(rb_mProcess, "last_status", proc_s_last_status, 0);
- rb_define_module_function(rb_mProcess, "kill", rb_f_kill, -1); /* in signal.c */
- rb_define_module_function(rb_mProcess, "wait", proc_wait, -1);
+ rb_define_module_function(rb_mProcess, "kill", proc_rb_f_kill, -1);
+ rb_define_module_function(rb_mProcess, "wait", proc_m_wait, -1);
rb_define_module_function(rb_mProcess, "wait2", proc_wait2, -1);
- rb_define_module_function(rb_mProcess, "waitpid", proc_wait, -1);
+ rb_define_module_function(rb_mProcess, "waitpid", proc_m_wait, -1);
rb_define_module_function(rb_mProcess, "waitpid2", proc_wait2, -1);
rb_define_module_function(rb_mProcess, "waitall", proc_waitall, 0);
rb_define_module_function(rb_mProcess, "detach", proc_detach, 1);
+ /* :nodoc: */
rb_cWaiter = rb_define_class_under(rb_mProcess, "Waiter", rb_cThread);
rb_undef_alloc_func(rb_cWaiter);
rb_undef_method(CLASS_OF(rb_cWaiter), "new");
rb_define_method(rb_cWaiter, "pid", detach_process_pid, 0);
rb_cProcessStatus = rb_define_class_under(rb_mProcess, "Status", rb_cObject);
+ rb_define_alloc_func(rb_cProcessStatus, rb_process_status_allocate);
rb_undef_method(CLASS_OF(rb_cProcessStatus), "new");
+ rb_marshal_define_compat(rb_cProcessStatus, rb_cObject,
+ process_status_dump, process_status_load);
+
+ rb_define_singleton_method(rb_cProcessStatus, "wait", rb_process_status_waitv, -1);
rb_define_method(rb_cProcessStatus, "==", pst_equal, 1);
rb_define_method(rb_cProcessStatus, "&", pst_bitand, 1);
@@ -7653,7 +8688,7 @@ InitVM_process(void)
rb_define_method(rb_cProcessStatus, "to_s", pst_to_s, 0);
rb_define_method(rb_cProcessStatus, "inspect", pst_inspect, 0);
- rb_define_method(rb_cProcessStatus, "pid", pst_pid, 0);
+ rb_define_method(rb_cProcessStatus, "pid", pst_pid_m, 0);
rb_define_method(rb_cProcessStatus, "stopped?", pst_wifstopped, 0);
rb_define_method(rb_cProcessStatus, "stopsig", pst_wstopsig, 0);
@@ -7664,8 +8699,8 @@ InitVM_process(void)
rb_define_method(rb_cProcessStatus, "success?", pst_success_p, 0);
rb_define_method(rb_cProcessStatus, "coredump?", pst_wcoredump, 0);
- rb_define_module_function(rb_mProcess, "pid", get_pid, 0);
- rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0);
+ rb_define_module_function(rb_mProcess, "pid", proc_get_pid, 0);
+ rb_define_module_function(rb_mProcess, "ppid", proc_get_ppid, 0);
rb_define_module_function(rb_mProcess, "getpgrp", proc_getpgrp, 0);
rb_define_module_function(rb_mProcess, "setpgrp", proc_setpgrp, 0);
@@ -7945,12 +8980,16 @@ InitVM_process(void)
/* see Process.clock_gettime */
rb_define_const(rb_mProcess, "CLOCK_SECOND", CLOCKID2NUM(CLOCK_SECOND));
#endif
+#ifdef CLOCK_TAI
+ /* see Process.clock_gettime */
+ rb_define_const(rb_mProcess, "CLOCK_TAI", CLOCKID2NUM(CLOCK_TAI));
+#endif
rb_define_module_function(rb_mProcess, "clock_gettime", rb_clock_gettime, -1);
rb_define_module_function(rb_mProcess, "clock_getres", rb_clock_getres, -1);
#if defined(HAVE_TIMES) || defined(_WIN32)
+ /* Placeholder for rusage */
rb_cProcessTms = rb_struct_define_under(rb_mProcess, "Tms", "utime", "stime", "cutime", "cstime", NULL);
- rb_define_const(rb_cStruct, "Tms", rb_cProcessTms); /* for the backward compatibility */
#endif
SAVED_USER_ID = geteuid();
@@ -8011,46 +9050,46 @@ InitVM_process(void)
void
Init_process(void)
{
- id_in = rb_intern("in");
- id_out = rb_intern("out");
- id_err = rb_intern("err");
- id_pid = rb_intern("pid");
- id_uid = rb_intern("uid");
- id_gid = rb_intern("gid");
- id_close = rb_intern("close");
- id_child = rb_intern("child");
+ id_in = rb_intern_const("in");
+ id_out = rb_intern_const("out");
+ id_err = rb_intern_const("err");
+ id_pid = rb_intern_const("pid");
+ id_uid = rb_intern_const("uid");
+ id_gid = rb_intern_const("gid");
+ id_close = rb_intern_const("close");
+ id_child = rb_intern_const("child");
#ifdef HAVE_SETPGID
- id_pgroup = rb_intern("pgroup");
+ id_pgroup = rb_intern_const("pgroup");
#endif
#ifdef _WIN32
- id_new_pgroup = rb_intern("new_pgroup");
-#endif
- id_unsetenv_others = rb_intern("unsetenv_others");
- id_chdir = rb_intern("chdir");
- id_umask = rb_intern("umask");
- id_close_others = rb_intern("close_others");
- id_ENV = rb_intern("ENV");
- id_nanosecond = rb_intern("nanosecond");
- id_microsecond = rb_intern("microsecond");
- id_millisecond = rb_intern("millisecond");
- id_second = rb_intern("second");
- id_float_microsecond = rb_intern("float_microsecond");
- id_float_millisecond = rb_intern("float_millisecond");
- id_float_second = rb_intern("float_second");
- id_GETTIMEOFDAY_BASED_CLOCK_REALTIME = rb_intern("GETTIMEOFDAY_BASED_CLOCK_REALTIME");
- id_TIME_BASED_CLOCK_REALTIME = rb_intern("TIME_BASED_CLOCK_REALTIME");
+ id_new_pgroup = rb_intern_const("new_pgroup");
+#endif
+ id_unsetenv_others = rb_intern_const("unsetenv_others");
+ id_chdir = rb_intern_const("chdir");
+ id_umask = rb_intern_const("umask");
+ id_close_others = rb_intern_const("close_others");
+ id_ENV = rb_intern_const("ENV");
+ id_nanosecond = rb_intern_const("nanosecond");
+ id_microsecond = rb_intern_const("microsecond");
+ id_millisecond = rb_intern_const("millisecond");
+ id_second = rb_intern_const("second");
+ id_float_microsecond = rb_intern_const("float_microsecond");
+ id_float_millisecond = rb_intern_const("float_millisecond");
+ id_float_second = rb_intern_const("float_second");
+ id_GETTIMEOFDAY_BASED_CLOCK_REALTIME = rb_intern_const("GETTIMEOFDAY_BASED_CLOCK_REALTIME");
+ id_TIME_BASED_CLOCK_REALTIME = rb_intern_const("TIME_BASED_CLOCK_REALTIME");
#ifdef HAVE_TIMES
- id_TIMES_BASED_CLOCK_MONOTONIC = rb_intern("TIMES_BASED_CLOCK_MONOTONIC");
- id_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern("TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID");
+ id_TIMES_BASED_CLOCK_MONOTONIC = rb_intern_const("TIMES_BASED_CLOCK_MONOTONIC");
+ id_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern_const("TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID");
#endif
#ifdef RUSAGE_SELF
- id_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern("GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID");
+ id_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern_const("GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID");
#endif
- id_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern("CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID");
+ id_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern_const("CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID");
#ifdef __APPLE__
- id_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC = rb_intern("MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC");
+ id_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC = rb_intern_const("MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC");
#endif
- id_hertz = rb_intern("hertz");
+ id_hertz = rb_intern_const("hertz");
InitVM(process);
}
diff --git a/ractor.c b/ractor.c
new file mode 100644
index 0000000000..bf31b545cf
--- /dev/null
+++ b/ractor.c
@@ -0,0 +1,3257 @@
+// Ractor implementation
+
+#include "ruby/ruby.h"
+#include "ruby/thread.h"
+#include "ruby/ractor.h"
+#include "ruby/thread_native.h"
+#include "vm_core.h"
+#include "vm_sync.h"
+#include "ractor_core.h"
+#include "internal/complex.h"
+#include "internal/error.h"
+#include "internal/hash.h"
+#include "internal/rational.h"
+#include "internal/struct.h"
+#include "internal/thread.h"
+#include "variable.h"
+#include "gc.h"
+#include "transient_heap.h"
+
+VALUE rb_cRactor;
+
+VALUE rb_eRactorUnsafeError;
+VALUE rb_eRactorIsolationError;
+static VALUE rb_eRactorError;
+static VALUE rb_eRactorRemoteError;
+static VALUE rb_eRactorMovedError;
+static VALUE rb_eRactorClosedError;
+static VALUE rb_cRactorMovedObject;
+
+static void vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *r, const char *file, int line);
+
+static void
+ASSERT_ractor_unlocking(rb_ractor_t *r)
+{
+#if RACTOR_CHECK_MODE > 0
+ // GET_EC is NULL in an MJIT worker
+ if (rb_current_execution_context(false) != NULL && r->sync.locked_by == rb_ractor_self(GET_RACTOR())) {
+ rb_bug("recursive ractor locking");
+ }
+#endif
+}
+
+static void
+ASSERT_ractor_locking(rb_ractor_t *r)
+{
+#if RACTOR_CHECK_MODE > 0
+ // GET_EC is NULL in an MJIT worker
+ if (rb_current_execution_context(false) != NULL && r->sync.locked_by != rb_ractor_self(GET_RACTOR())) {
+ rp(r->sync.locked_by);
+ rb_bug("ractor lock is not acquired.");
+ }
+#endif
+}
+
+static void
+ractor_lock(rb_ractor_t *r, const char *file, int line)
+{
+ RUBY_DEBUG_LOG2(file, line, "locking r:%u%s", r->pub.id, GET_RACTOR() == r ? " (self)" : "");
+
+ ASSERT_ractor_unlocking(r);
+ rb_native_mutex_lock(&r->sync.lock);
+
+#if RACTOR_CHECK_MODE > 0
+ if (rb_current_execution_context(false) != NULL) { // GET_EC is NULL in an MJIT worker
+ r->sync.locked_by = rb_ractor_self(GET_RACTOR());
+ }
+#endif
+
+ RUBY_DEBUG_LOG2(file, line, "locked r:%u%s", r->pub.id, GET_RACTOR() == r ? " (self)" : "");
+}
+
+static void
+ractor_lock_self(rb_ractor_t *cr, const char *file, int line)
+{
+ VM_ASSERT(cr == GET_RACTOR());
+ VM_ASSERT(cr->sync.locked_by != cr->pub.self);
+ ractor_lock(cr, file, line);
+}
+
+static void
+ractor_unlock(rb_ractor_t *r, const char *file, int line)
+{
+ ASSERT_ractor_locking(r);
+#if RACTOR_CHECK_MODE > 0
+ r->sync.locked_by = Qnil;
+#endif
+ rb_native_mutex_unlock(&r->sync.lock);
+
+ RUBY_DEBUG_LOG2(file, line, "r:%u%s", r->pub.id, GET_RACTOR() == r ? " (self)" : "");
+}
+
+static void
+ractor_unlock_self(rb_ractor_t *cr, const char *file, int line)
+{
+ VM_ASSERT(cr == GET_RACTOR());
+ VM_ASSERT(cr->sync.locked_by == cr->pub.self);
+ ractor_unlock(cr, file, line);
+}
+
+#define RACTOR_LOCK(r) ractor_lock(r, __FILE__, __LINE__)
+#define RACTOR_UNLOCK(r) ractor_unlock(r, __FILE__, __LINE__)
+#define RACTOR_LOCK_SELF(r) ractor_lock_self(r, __FILE__, __LINE__)
+#define RACTOR_UNLOCK_SELF(r) ractor_unlock_self(r, __FILE__, __LINE__)
+
+static void
+ractor_cond_wait(rb_ractor_t *r)
+{
+#if RACTOR_CHECK_MODE > 0
+ VALUE locked_by = r->sync.locked_by;
+ r->sync.locked_by = Qnil;
+#endif
+ rb_native_cond_wait(&r->sync.cond, &r->sync.lock);
+
+#if RACTOR_CHECK_MODE > 0
+ r->sync.locked_by = locked_by;
+#endif
+}
+
+static const char *
+ractor_status_str(enum ractor_status status)
+{
+ switch (status) {
+ case ractor_created: return "created";
+ case ractor_running: return "running";
+ case ractor_blocking: return "blocking";
+ case ractor_terminated: return "terminated";
+ }
+ rb_bug("unreachable");
+}
+
+static void
+ractor_status_set(rb_ractor_t *r, enum ractor_status status)
+{
+ RUBY_DEBUG_LOG("r:%u [%s]->[%s]", r->pub.id, ractor_status_str(r->status_), ractor_status_str(status));
+
+ // check 1
+ if (r->status_ != ractor_created) {
+ VM_ASSERT(r == GET_RACTOR()); // only self-modification is allowed.
+ ASSERT_vm_locking();
+ }
+
+ // check2: transition check. assume it will be vanished on non-debug build.
+ switch (r->status_) {
+ case ractor_created:
+ VM_ASSERT(status == ractor_blocking);
+ break;
+ case ractor_running:
+ VM_ASSERT(status == ractor_blocking||
+ status == ractor_terminated);
+ break;
+ case ractor_blocking:
+ VM_ASSERT(status == ractor_running);
+ break;
+ case ractor_terminated:
+ VM_ASSERT(0); // unreachable
+ break;
+ }
+
+ r->status_ = status;
+}
+
+static bool
+ractor_status_p(rb_ractor_t *r, enum ractor_status status)
+{
+ return rb_ractor_status_p(r, status);
+}
+
+static struct rb_ractor_basket *ractor_queue_at(struct rb_ractor_queue *rq, int i);
+
+static void
+ractor_queue_mark(struct rb_ractor_queue *rq)
+{
+ for (int i=0; i<rq->cnt; i++) {
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ rb_gc_mark(b->v);
+ rb_gc_mark(b->sender);
+ }
+}
+
+static void ractor_local_storage_mark(rb_ractor_t *r);
+static void ractor_local_storage_free(rb_ractor_t *r);
+
+static void
+ractor_mark(void *ptr)
+{
+ rb_ractor_t *r = (rb_ractor_t *)ptr;
+
+ ractor_queue_mark(&r->sync.incoming_queue);
+ rb_gc_mark(r->sync.wait.taken_basket.v);
+ rb_gc_mark(r->sync.wait.taken_basket.sender);
+ rb_gc_mark(r->sync.wait.yielded_basket.v);
+ rb_gc_mark(r->sync.wait.yielded_basket.sender);
+ rb_gc_mark(r->receiving_mutex);
+
+ rb_gc_mark(r->loc);
+ rb_gc_mark(r->name);
+ rb_gc_mark(r->r_stdin);
+ rb_gc_mark(r->r_stdout);
+ rb_gc_mark(r->r_stderr);
+ rb_hook_list_mark(&r->pub.hooks);
+
+ if (r->threads.cnt > 0) {
+ rb_thread_t *th = 0;
+ list_for_each(&r->threads.set, th, lt_node) {
+ VM_ASSERT(th != NULL);
+ rb_gc_mark(th->self);
+ }
+ }
+
+ ractor_local_storage_mark(r);
+}
+
+static void
+ractor_queue_free(struct rb_ractor_queue *rq)
+{
+ free(rq->baskets);
+}
+
+static void
+ractor_waiting_list_free(struct rb_ractor_waiting_list *wl)
+{
+ free(wl->ractors);
+}
+
+static void
+ractor_free(void *ptr)
+{
+ rb_ractor_t *r = (rb_ractor_t *)ptr;
+ rb_native_mutex_destroy(&r->sync.lock);
+ rb_native_cond_destroy(&r->sync.cond);
+ ractor_queue_free(&r->sync.incoming_queue);
+ ractor_waiting_list_free(&r->sync.taking_ractors);
+ ractor_local_storage_free(r);
+ rb_hook_list_free(&r->pub.hooks);
+ ruby_xfree(r);
+}
+
+static size_t
+ractor_queue_memsize(const struct rb_ractor_queue *rq)
+{
+ return sizeof(struct rb_ractor_basket) * rq->size;
+}
+
+static size_t
+ractor_waiting_list_memsize(const struct rb_ractor_waiting_list *wl)
+{
+ return sizeof(rb_ractor_t *) * wl->size;
+}
+
+static size_t
+ractor_memsize(const void *ptr)
+{
+ rb_ractor_t *r = (rb_ractor_t *)ptr;
+
+ // TODO
+ return sizeof(rb_ractor_t) +
+ ractor_queue_memsize(&r->sync.incoming_queue) +
+ ractor_waiting_list_memsize(&r->sync.taking_ractors);
+}
+
+static const rb_data_type_t ractor_data_type = {
+ "ractor",
+ {
+ ractor_mark,
+ ractor_free,
+ ractor_memsize,
+ NULL, // update
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY /* | RUBY_TYPED_WB_PROTECTED */
+};
+
+bool
+rb_ractor_p(VALUE gv)
+{
+ if (rb_typeddata_is_kind_of(gv, &ractor_data_type)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static inline rb_ractor_t *
+RACTOR_PTR(VALUE self)
+{
+ VM_ASSERT(rb_ractor_p(self));
+
+ rb_ractor_t *r = DATA_PTR(self);
+ // TODO: check
+ return r;
+}
+
+static uint32_t ractor_last_id;
+
+#if RACTOR_CHECK_MODE > 0
+MJIT_FUNC_EXPORTED uint32_t
+rb_ractor_current_id(void)
+{
+ if (GET_THREAD()->ractor == NULL) {
+ return 1; // main ractor
+ }
+ else {
+ return rb_ractor_id(GET_RACTOR());
+ }
+}
+#endif
+
+static void
+ractor_queue_setup(struct rb_ractor_queue *rq)
+{
+ rq->size = 2;
+ rq->cnt = 0;
+ rq->start = 0;
+ rq->baskets = malloc(sizeof(struct rb_ractor_basket) * rq->size);
+}
+
+static struct rb_ractor_basket *
+ractor_queue_at(struct rb_ractor_queue *rq, int i)
+{
+ return &rq->baskets[(rq->start + i) % rq->size];
+}
+
+static void
+ractor_queue_advance(struct rb_ractor_queue *rq)
+{
+ ASSERT_ractor_locking(GET_RACTOR());
+
+ if (rq->reserved_cnt == 0) {
+ rq->cnt--;
+ rq->start = (rq->start + 1) % rq->size;
+ rq->serial++;
+ }
+ else {
+ ractor_queue_at(rq, 0)->type = basket_type_deleted;
+ }
+}
+
+static bool
+ractor_queue_skip_p(struct rb_ractor_queue *rq, int i)
+{
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ return b->type == basket_type_deleted ||
+ b->type == basket_type_reserved;
+}
+
+static void
+ractor_queue_compact(rb_ractor_t *r, struct rb_ractor_queue *rq)
+{
+ ASSERT_ractor_locking(r);
+
+ while (rq->cnt > 0 && ractor_queue_at(rq, 0)->type == basket_type_deleted) {
+ ractor_queue_advance(rq);
+ }
+}
+
+static bool
+ractor_queue_empty_p(rb_ractor_t *r, struct rb_ractor_queue *rq)
+{
+ ASSERT_ractor_locking(r);
+
+ if (rq->cnt == 0) {
+ return true;
+ }
+
+ ractor_queue_compact(r, rq);
+
+ for (int i=0; i<rq->cnt; i++) {
+ if (!ractor_queue_skip_p(rq, i)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool
+ractor_queue_deq(rb_ractor_t *r, struct rb_ractor_queue *rq, struct rb_ractor_basket *basket)
+{
+ bool found = false;
+
+ RACTOR_LOCK(r);
+ {
+ if (!ractor_queue_empty_p(r, rq)) {
+ for (int i=0; i<rq->cnt; i++) {
+ if (!ractor_queue_skip_p(rq, i)) {
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ *basket = *b;
+
+ // remove from queue
+ b->type = basket_type_deleted;
+ ractor_queue_compact(r, rq);
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ RACTOR_UNLOCK(r);
+
+ return found;
+}
+
+static void
+ractor_queue_enq(rb_ractor_t *r, struct rb_ractor_queue *rq, struct rb_ractor_basket *basket)
+{
+ ASSERT_ractor_locking(r);
+
+ if (rq->size <= rq->cnt) {
+ rq->baskets = realloc(rq->baskets, sizeof(struct rb_ractor_basket) * rq->size * 2);
+ for (int i=rq->size - rq->start; i<rq->cnt; i++) {
+ rq->baskets[i + rq->start] = rq->baskets[i + rq->start - rq->size];
+ }
+ rq->size *= 2;
+ }
+ rq->baskets[(rq->start + rq->cnt++) % rq->size] = *basket;
+ // fprintf(stderr, "%s %p->cnt:%d\n", __func__, rq, rq->cnt);
+}
+
+static void
+ractor_basket_clear(struct rb_ractor_basket *b)
+{
+ b->type = basket_type_none;
+ b->v = Qfalse;
+ b->sender = Qfalse;
+}
+
+static VALUE ractor_reset_belonging(VALUE obj); // in this file
+
+static VALUE
+ractor_basket_value(struct rb_ractor_basket *b)
+{
+ switch (b->type) {
+ case basket_type_ref:
+ break;
+ case basket_type_copy:
+ case basket_type_move:
+ case basket_type_will:
+ b->type = basket_type_ref;
+ b->v = ractor_reset_belonging(b->v);
+ break;
+ default:
+ rb_bug("unreachable");
+ }
+
+ return b->v;
+}
+
+static VALUE
+ractor_basket_accept(struct rb_ractor_basket *b)
+{
+ VALUE v = ractor_basket_value(b);
+
+ if (b->exception) {
+ VALUE cause = v;
+ VALUE err = rb_exc_new_cstr(rb_eRactorRemoteError, "thrown by remote Ractor.");
+ rb_ivar_set(err, rb_intern("@ractor"), b->sender);
+ ractor_basket_clear(b);
+ rb_ec_setup_exception(NULL, err, cause);
+ rb_exc_raise(err);
+ }
+
+ ractor_basket_clear(b);
+ return v;
+}
+
+static void
+ractor_recursive_receive_if(rb_ractor_t *r)
+{
+ if (r->receiving_mutex && rb_mutex_owned_p(r->receiving_mutex)) {
+ rb_raise(rb_eRactorError, "can not call receive/receive_if recursively");
+ }
+}
+
+static VALUE
+ractor_try_receive(rb_execution_context_t *ec, rb_ractor_t *r)
+{
+ struct rb_ractor_queue *rq = &r->sync.incoming_queue;
+ struct rb_ractor_basket basket;
+
+ ractor_recursive_receive_if(r);
+
+ if (ractor_queue_deq(r, rq, &basket) == false) {
+ if (r->sync.incoming_port_closed) {
+ rb_raise(rb_eRactorClosedError, "The incoming port is already closed");
+ }
+ else {
+ return Qundef;
+ }
+ }
+
+ return ractor_basket_accept(&basket);
+}
+
+static void *
+ractor_sleep_wo_gvl(void *ptr)
+{
+ rb_ractor_t *cr = ptr;
+ RACTOR_LOCK_SELF(cr);
+ {
+ VM_ASSERT(cr->sync.wait.status != wait_none);
+ if (cr->sync.wait.wakeup_status == wakeup_none) {
+ ractor_cond_wait(cr);
+ }
+ cr->sync.wait.status = wait_none;
+ }
+ RACTOR_UNLOCK_SELF(cr);
+ return NULL;
+}
+
+static void
+ractor_sleep_interrupt(void *ptr)
+{
+ rb_ractor_t *r = ptr;
+
+ RACTOR_LOCK(r);
+ if (r->sync.wait.wakeup_status == wakeup_none) {
+ r->sync.wait.wakeup_status = wakeup_by_interrupt;
+ rb_native_cond_signal(&r->sync.cond);
+ }
+ RACTOR_UNLOCK(r);
+}
+
+#if USE_RUBY_DEBUG_LOG
+static const char *
+wait_status_str(enum ractor_wait_status wait_status)
+{
+ switch ((int)wait_status) {
+ case wait_none: return "none";
+ case wait_receiving: return "receiving";
+ case wait_taking: return "taking";
+ case wait_yielding: return "yielding";
+ case wait_receiving|wait_taking: return "receiving|taking";
+ case wait_receiving|wait_yielding: return "receiving|yielding";
+ case wait_taking|wait_yielding: return "taking|yielding";
+ case wait_receiving|wait_taking|wait_yielding: return "receiving|taking|yielding";
+ }
+ rb_bug("unrechable");
+}
+
+static const char *
+wakeup_status_str(enum ractor_wakeup_status wakeup_status)
+{
+ switch (wakeup_status) {
+ case wakeup_none: return "none";
+ case wakeup_by_send: return "by_send";
+ case wakeup_by_yield: return "by_yield";
+ case wakeup_by_take: return "by_take";
+ case wakeup_by_close: return "by_close";
+ case wakeup_by_interrupt: return "by_interrupt";
+ case wakeup_by_retry: return "by_retry";
+ }
+ rb_bug("unrechable");
+}
+#endif // USE_RUBY_DEBUG_LOG
+
+static void
+ractor_sleep(rb_execution_context_t *ec, rb_ractor_t *cr)
+{
+ VM_ASSERT(GET_RACTOR() == cr);
+ VM_ASSERT(cr->sync.wait.status != wait_none);
+ // fprintf(stderr, "%s r:%p status:%s, wakeup_status:%s\n", __func__, cr,
+ // wait_status_str(cr->sync.wait.status), wakeup_status_str(cr->sync.wait.wakeup_status));
+
+ RACTOR_UNLOCK(cr);
+ {
+ rb_nogvl(ractor_sleep_wo_gvl, cr,
+ ractor_sleep_interrupt, cr,
+ RB_NOGVL_UBF_ASYNC_SAFE | RB_NOGVL_INTR_FAIL);
+ }
+ RACTOR_LOCK(cr);
+
+ // rb_nogvl() can be canceled by interrupts
+ if (cr->sync.wait.status != wait_none) {
+ cr->sync.wait.status = wait_none;
+ cr->sync.wait.wakeup_status = wakeup_by_interrupt;
+
+ RACTOR_UNLOCK(cr);
+ rb_thread_check_ints();
+ RACTOR_LOCK(cr); // reachable?
+ }
+}
+
+static bool
+ractor_sleeping_by(const rb_ractor_t *r, enum ractor_wait_status wait_status)
+{
+ return (r->sync.wait.status & wait_status) && r->sync.wait.wakeup_status == wakeup_none;
+}
+
+static bool
+ractor_wakeup(rb_ractor_t *r, enum ractor_wait_status wait_status, enum ractor_wakeup_status wakeup_status)
+{
+ ASSERT_ractor_locking(r);
+
+ // fprintf(stderr, "%s r:%p status:%s/%s wakeup_status:%s/%s\n", __func__, r,
+ // wait_status_str(r->sync.wait.status), wait_status_str(wait_status),
+ // wakeup_status_str(r->sync.wait.wakeup_status), wakeup_status_str(wakeup_status));
+
+ if (ractor_sleeping_by(r, wait_status)) {
+ r->sync.wait.wakeup_status = wakeup_status;
+ rb_native_cond_signal(&r->sync.cond);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static void
+ractor_register_taking(rb_ractor_t *r, rb_ractor_t *cr)
+{
+ VM_ASSERT(cr == GET_RACTOR());
+ bool retry_try = false;
+
+ RACTOR_LOCK(r);
+ {
+ if (ractor_sleeping_by(r, wait_yielding)) {
+ // already waiting for yielding. retry try_take.
+ retry_try = true;
+ }
+ else {
+ // insert cr into taking list
+ struct rb_ractor_waiting_list *wl = &r->sync.taking_ractors;
+
+ for (int i=0; i<wl->cnt; i++) {
+ if (wl->ractors[i] == cr) {
+ // TODO: make it clean code.
+ rb_native_mutex_unlock(&r->sync.lock);
+ rb_raise(rb_eRuntimeError, "Already another thread of same ractor is waiting.");
+ }
+ }
+
+ if (wl->size == 0) {
+ wl->size = 1;
+ wl->ractors = malloc(sizeof(rb_ractor_t *) * wl->size);
+ if (wl->ractors == NULL) rb_bug("can't allocate buffer");
+ }
+ else if (wl->size <= wl->cnt + 1) {
+ wl->size *= 2;
+ wl->ractors = realloc(wl->ractors, sizeof(rb_ractor_t *) * wl->size);
+ if (wl->ractors == NULL) rb_bug("can't re-allocate buffer");
+ }
+ wl->ractors[wl->cnt++] = cr;
+ }
+ }
+ RACTOR_UNLOCK(r);
+
+ if (retry_try) {
+ RACTOR_LOCK(cr);
+ {
+ if (cr->sync.wait.wakeup_status == wakeup_none) {
+ VM_ASSERT(cr->sync.wait.status != wait_none);
+
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ cr->sync.wait.status = wait_none;
+ }
+ }
+ RACTOR_UNLOCK(cr);
+ }
+}
+
+static void
+ractor_waiting_list_del(rb_ractor_t *r, struct rb_ractor_waiting_list *wl, rb_ractor_t *wr)
+{
+ RACTOR_LOCK(r);
+ {
+ int pos = -1;
+ for (int i=0; i<wl->cnt; i++) {
+ if (wl->ractors[i] == wr) {
+ pos = i;
+ break;
+ }
+ }
+ if (pos >= 0) { // found
+ wl->cnt--;
+ for (int i=pos; i<wl->cnt; i++) {
+ wl->ractors[i] = wl->ractors[i+1];
+ }
+ }
+ }
+ RACTOR_UNLOCK(r);
+}
+
+static rb_ractor_t *
+ractor_waiting_list_shift(rb_ractor_t *r, struct rb_ractor_waiting_list *wl)
+{
+ ASSERT_ractor_locking(r);
+ VM_ASSERT(&r->sync.taking_ractors == wl);
+
+ if (wl->cnt > 0) {
+ rb_ractor_t *tr = wl->ractors[0];
+ for (int i=1; i<wl->cnt; i++) {
+ wl->ractors[i-1] = wl->ractors[i];
+ }
+ wl->cnt--;
+ return tr;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static void
+ractor_receive_wait(rb_execution_context_t *ec, rb_ractor_t *cr)
+{
+ VM_ASSERT(cr == rb_ec_ractor_ptr(ec));
+ ractor_recursive_receive_if(cr);
+
+ RACTOR_LOCK(cr);
+ {
+ if (ractor_queue_empty_p(cr, &cr->sync.incoming_queue)) {
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ cr->sync.wait.status = wait_receiving;
+ cr->sync.wait.wakeup_status = wakeup_none;
+ ractor_sleep(ec, cr);
+ cr->sync.wait.wakeup_status = wakeup_none;
+ }
+ }
+ RACTOR_UNLOCK(cr);
+}
+
+static VALUE
+ractor_receive(rb_execution_context_t *ec, rb_ractor_t *cr)
+{
+ VM_ASSERT(cr == rb_ec_ractor_ptr(ec));
+ VALUE v;
+
+ while ((v = ractor_try_receive(ec, cr)) == Qundef) {
+ ractor_receive_wait(ec, cr);
+ }
+
+ return v;
+}
+
+#if 0
+// for debug
+static const char *
+basket_type_name(enum rb_ractor_basket_type type)
+{
+ switch (type) {
+#define T(t) case basket_type_##t: return #t
+ T(none);
+ T(ref);
+ T(copy);
+ T(move);
+ T(will);
+ T(deleted);
+ T(reserved);
+ default: rb_bug("unreachable");
+ }
+}
+
+static void
+rq_dump(struct rb_ractor_queue *rq)
+{
+ bool bug = false;
+ for (int i=0; i<rq->cnt; i++) {
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ fprintf(stderr, "%d (start:%d) type:%s %p %s\n", i, rq->start, basket_type_name(b->type), b, RSTRING_PTR(RARRAY_AREF(b->v, 1)));
+ if (b->type == basket_type_reserved) bug = true;
+ }
+ if (bug) rb_bug("!!");
+}
+#endif
+
+struct receive_block_data {
+ rb_ractor_t *cr;
+ struct rb_ractor_queue *rq;
+ VALUE v;
+ int index;
+ bool success;
+};
+
+static void
+ractor_receive_if_lock(rb_ractor_t *cr)
+{
+ VALUE m = cr->receiving_mutex;
+ if (m == Qfalse) {
+ m = cr->receiving_mutex = rb_mutex_new();
+ }
+ rb_mutex_lock(m);
+}
+
+static VALUE
+receive_if_body(VALUE ptr)
+{
+ struct receive_block_data *data = (struct receive_block_data *)ptr;
+
+ ractor_receive_if_lock(data->cr);
+ VALUE block_result = rb_yield(data->v);
+
+ RACTOR_LOCK_SELF(data->cr);
+ {
+ struct rb_ractor_basket *b = ractor_queue_at(data->rq, data->index);
+ VM_ASSERT(b->type == basket_type_reserved);
+ data->rq->reserved_cnt--;
+
+ if (RTEST(block_result)) {
+ b->type = basket_type_deleted;
+ ractor_queue_compact(data->cr, data->rq);
+ }
+ else {
+ b->type = basket_type_ref;
+ }
+ }
+ RACTOR_UNLOCK_SELF(data->cr);
+
+ data->success = true;
+
+ if (RTEST(block_result)) {
+ return data->v;
+ }
+ else {
+ return Qundef;
+ }
+}
+
+static VALUE
+receive_if_ensure(VALUE v)
+{
+ struct receive_block_data *data = (struct receive_block_data *)v;
+
+ if (!data->success) {
+ RACTOR_LOCK_SELF(data->cr);
+ {
+ struct rb_ractor_basket *b = ractor_queue_at(data->rq, data->index);
+ VM_ASSERT(b->type == basket_type_reserved);
+ b->type = basket_type_deleted;
+ data->rq->reserved_cnt--;
+ }
+ RACTOR_UNLOCK_SELF(data->cr);
+ }
+
+ rb_mutex_unlock(data->cr->receiving_mutex);
+ return Qnil;
+}
+
+static VALUE
+ractor_receive_if(rb_execution_context_t *ec, VALUE crv, VALUE b)
+{
+ if (!RTEST(b)) rb_raise(rb_eArgError, "no block given");
+
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ unsigned int serial = (unsigned int)-1;
+ int index = 0;
+ struct rb_ractor_queue *rq = &cr->sync.incoming_queue;
+
+ while (1) {
+ VALUE v = Qundef;
+
+ ractor_receive_wait(ec, cr);
+
+ RACTOR_LOCK_SELF(cr);
+ {
+ if (serial != rq->serial) {
+ serial = rq->serial;
+ index = 0;
+ }
+
+ // check newer version
+ for (int i=index; i<rq->cnt; i++) {
+ if (!ractor_queue_skip_p(rq, i)) {
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ v = ractor_basket_value(b);
+ b->type = basket_type_reserved;
+ rq->reserved_cnt++;
+ index = i;
+ break;
+ }
+ }
+ }
+ RACTOR_UNLOCK_SELF(cr);
+
+ if (v != Qundef) {
+ struct receive_block_data data = {
+ .cr = cr,
+ .rq = rq,
+ .v = v,
+ .index = index,
+ .success = false,
+ };
+
+ VALUE result = rb_ensure(receive_if_body, (VALUE)&data,
+ receive_if_ensure, (VALUE)&data);
+
+ if (result != Qundef) return result;
+ index++;
+ }
+ }
+}
+
+static void
+ractor_send_basket(rb_execution_context_t *ec, rb_ractor_t *r, struct rb_ractor_basket *b)
+{
+ bool closed = false;
+ struct rb_ractor_queue *rq = &r->sync.incoming_queue;
+
+ RACTOR_LOCK(r);
+ {
+ if (r->sync.incoming_port_closed) {
+ closed = true;
+ }
+ else {
+ ractor_queue_enq(r, rq, b);
+ if (ractor_wakeup(r, wait_receiving, wakeup_by_send)) {
+ RUBY_DEBUG_LOG("wakeup", 0);
+ }
+ }
+ }
+ RACTOR_UNLOCK(r);
+
+ if (closed) {
+ rb_raise(rb_eRactorClosedError, "The incoming-port is already closed");
+ }
+}
+
+static VALUE ractor_move(VALUE obj); // in this file
+static VALUE ractor_copy(VALUE obj); // in this file
+
+static void
+ractor_basket_setup(rb_execution_context_t *ec, struct rb_ractor_basket *basket, VALUE obj, VALUE move, bool exc, bool is_will, bool is_yield)
+{
+ basket->sender = rb_ec_ractor_ptr(ec)->pub.self;
+ basket->exception = exc;
+
+ if (is_will) {
+ basket->type = basket_type_will;
+ basket->v = obj;
+ }
+ else if (rb_ractor_shareable_p(obj)) {
+ basket->type = basket_type_ref;
+ basket->v = obj;
+ }
+ else if (!RTEST(move)) {
+ basket->v = ractor_copy(obj);
+ basket->type = basket_type_copy;
+ }
+ else {
+ basket->type = basket_type_move;
+
+ if (is_yield) {
+ basket->v = obj; // call ractor_move() when yielding timing.
+ }
+ else {
+ basket->v = ractor_move(obj);
+ }
+ }
+}
+
+static VALUE
+ractor_send(rb_execution_context_t *ec, rb_ractor_t *r, VALUE obj, VALUE move)
+{
+ struct rb_ractor_basket basket;
+ ractor_basket_setup(ec, &basket, obj, move, false, false, false);
+ ractor_send_basket(ec, r, &basket);
+ return r->pub.self;
+}
+
+static VALUE
+ractor_try_take(rb_execution_context_t *ec, rb_ractor_t *r)
+{
+ struct rb_ractor_basket basket = {
+ .type = basket_type_none,
+ };
+ bool closed = false;
+
+ RACTOR_LOCK(r);
+ {
+ if (ractor_sleeping_by(r, wait_yielding)) {
+ MAYBE_UNUSED(bool) wakeup_result;
+ VM_ASSERT(r->sync.wait.yielded_basket.type != basket_type_none);
+
+ if (r->sync.wait.yielded_basket.type == basket_type_move) {
+ wakeup_result = ractor_wakeup(r, wait_yielding, wakeup_by_retry);
+ }
+ else {
+ wakeup_result = ractor_wakeup(r, wait_yielding, wakeup_by_take);
+ basket = r->sync.wait.yielded_basket;
+ ractor_basket_clear(&r->sync.wait.yielded_basket);
+ }
+ VM_ASSERT(wakeup_result);
+ }
+ else if (r->sync.outgoing_port_closed) {
+ closed = true;
+ }
+ }
+ RACTOR_UNLOCK(r);
+
+ if (basket.type == basket_type_none) {
+ if (closed) {
+ rb_raise(rb_eRactorClosedError, "The outgoing-port is already closed");
+ }
+ else {
+ return Qundef;
+ }
+ }
+ else {
+ return ractor_basket_accept(&basket);
+ }
+}
+
+static VALUE
+ractor_yield_move_body(VALUE v)
+{
+ return ractor_move(v);
+}
+
+static bool
+ractor_try_yield(rb_execution_context_t *ec, rb_ractor_t *cr, struct rb_ractor_basket *basket)
+{
+ ASSERT_ractor_unlocking(cr);
+ VM_ASSERT(basket->type != basket_type_none);
+
+ if (cr->sync.outgoing_port_closed) {
+ rb_raise(rb_eRactorClosedError, "The outgoing-port is already closed");
+ }
+
+ rb_ractor_t *r;
+
+ retry_shift:
+ RACTOR_LOCK(cr);
+ {
+ r = ractor_waiting_list_shift(cr, &cr->sync.taking_ractors);
+ }
+ RACTOR_UNLOCK(cr);
+
+ if (r) {
+ bool retry_shift = false;
+
+ RACTOR_LOCK(r);
+ {
+ if (ractor_sleeping_by(r, wait_taking)) {
+ VM_ASSERT(r->sync.wait.taken_basket.type == basket_type_none);
+
+ if (basket->type == basket_type_move) {
+ enum ractor_wait_status prev_wait_status = r->sync.wait.status;
+ r->sync.wait.status = wait_moving;
+
+ RACTOR_UNLOCK(r);
+ {
+ int state;
+ VALUE moved_value = rb_protect(ractor_yield_move_body, basket->v, &state);
+ if (state) {
+ r->sync.wait.status = prev_wait_status;
+ rb_jump_tag(state);
+ }
+ else {
+ basket->v = moved_value;
+ }
+ }
+ RACTOR_LOCK(r);
+
+ if (!ractor_wakeup(r, wait_moving, wakeup_by_yield)) {
+ // terminating?
+ }
+ }
+ else {
+ ractor_wakeup(r, wait_taking, wakeup_by_yield);
+ }
+ r->sync.wait.taken_basket = *basket;
+ }
+ else {
+ retry_shift = true;
+ }
+ }
+ RACTOR_UNLOCK(r);
+
+ if (retry_shift) {
+ // get candidate take-waiting ractor, but already woke up by another reason.
+ // retry to check another ractor.
+ goto retry_shift;
+ }
+ else {
+ return true;
+ }
+ }
+ else {
+ return false;
+ }
+}
+
+// select(r1, r2, r3, receive: true, yield: obj)
+static VALUE
+ractor_select(rb_execution_context_t *ec, const VALUE *rs, const int rs_len, VALUE yielded_value, bool move, VALUE *ret_r)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ VALUE crv = cr->pub.self;
+ VALUE ret = Qundef;
+ int i;
+ bool interrupted = false;
+ enum ractor_wait_status wait_status = 0;
+ bool yield_p = (yielded_value != Qundef) ? true : false;
+ const int alen = rs_len + (yield_p ? 1 : 0);
+
+ struct ractor_select_action {
+ enum ractor_select_action_type {
+ ractor_select_action_take,
+ ractor_select_action_receive,
+ ractor_select_action_yield,
+ } type;
+ VALUE v;
+ } *actions = ALLOCA_N(struct ractor_select_action, alen);
+
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ VM_ASSERT(cr->sync.wait.wakeup_status == wakeup_none);
+ VM_ASSERT(cr->sync.wait.taken_basket.type == basket_type_none);
+ VM_ASSERT(cr->sync.wait.yielded_basket.type == basket_type_none);
+
+ // setup actions
+ for (i=0; i<rs_len; i++) {
+ VALUE v = rs[i];
+
+ if (v == crv) {
+ actions[i].type = ractor_select_action_receive;
+ actions[i].v = Qnil;
+ wait_status |= wait_receiving;
+ }
+ else if (rb_ractor_p(v)) {
+ actions[i].type = ractor_select_action_take;
+ actions[i].v = v;
+ wait_status |= wait_taking;
+ }
+ else {
+ rb_raise(rb_eArgError, "should be a ractor object, but %"PRIsVALUE, v);
+ }
+ }
+ rs = NULL;
+
+ restart:
+
+ if (yield_p) {
+ actions[rs_len].type = ractor_select_action_yield;
+ actions[rs_len].v = Qundef;
+ wait_status |= wait_yielding;
+ ractor_basket_setup(ec, &cr->sync.wait.yielded_basket, yielded_value, move, false, false, true);
+ }
+
+ // TODO: shuffle actions
+
+ while (1) {
+ RUBY_DEBUG_LOG("try actions (%s)", wait_status_str(wait_status));
+
+ for (i=0; i<alen; i++) {
+ VALUE v, rv;
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ rv = actions[i].v;
+ v = ractor_try_take(ec, RACTOR_PTR(rv));
+ if (v != Qundef) {
+ *ret_r = rv;
+ ret = v;
+ goto cleanup;
+ }
+ break;
+ case ractor_select_action_receive:
+ v = ractor_try_receive(ec, cr);
+ if (v != Qundef) {
+ *ret_r = ID2SYM(rb_intern("receive"));
+ ret = v;
+ goto cleanup;
+ }
+ break;
+ case ractor_select_action_yield:
+ {
+ if (ractor_try_yield(ec, cr, &cr->sync.wait.yielded_basket)) {
+ *ret_r = ID2SYM(rb_intern("yield"));
+ ret = Qnil;
+ goto cleanup;
+ }
+ }
+ break;
+ }
+ }
+
+ RUBY_DEBUG_LOG("wait actions (%s)", wait_status_str(wait_status));
+
+ RACTOR_LOCK(cr);
+ {
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ cr->sync.wait.status = wait_status;
+ cr->sync.wait.wakeup_status = wakeup_none;
+ }
+ RACTOR_UNLOCK(cr);
+
+ // prepare waiting
+ for (i=0; i<alen; i++) {
+ rb_ractor_t *r;
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ r = RACTOR_PTR(actions[i].v);
+ ractor_register_taking(r, cr);
+ break;
+ case ractor_select_action_yield:
+ case ractor_select_action_receive:
+ break;
+ }
+ }
+
+ // wait
+ RACTOR_LOCK(cr);
+ {
+ if (cr->sync.wait.wakeup_status == wakeup_none) {
+ for (i=0; i<alen; i++) {
+ rb_ractor_t *r;
+
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ r = RACTOR_PTR(actions[i].v);
+ if (ractor_sleeping_by(r, wait_yielding)) {
+ RUBY_DEBUG_LOG("wakeup_none, but r:%u is waiting for yielding", r->pub.id);
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ goto skip_sleep;
+ }
+ break;
+ case ractor_select_action_receive:
+ if (cr->sync.incoming_queue.cnt > 0) {
+ RUBY_DEBUG_LOG("wakeup_none, but incoming_queue has %u messages", cr->sync.incoming_queue.cnt);
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ goto skip_sleep;
+ }
+ break;
+ case ractor_select_action_yield:
+ if (cr->sync.taking_ractors.cnt > 0) {
+ RUBY_DEBUG_LOG("wakeup_none, but %u taking_ractors are waiting", cr->sync.taking_ractors.cnt);
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ goto skip_sleep;
+ }
+ else if (cr->sync.outgoing_port_closed) {
+ cr->sync.wait.wakeup_status = wakeup_by_close;
+ goto skip_sleep;
+ }
+ break;
+ }
+ }
+
+ RUBY_DEBUG_LOG("sleep %s", wait_status_str(cr->sync.wait.status));
+ ractor_sleep(ec, cr);
+ RUBY_DEBUG_LOG("awaken %s", wakeup_status_str(cr->sync.wait.wakeup_status));
+ }
+ else {
+ skip_sleep:
+ RUBY_DEBUG_LOG("no need to sleep %s->%s",
+ wait_status_str(cr->sync.wait.status),
+ wakeup_status_str(cr->sync.wait.wakeup_status));
+ cr->sync.wait.status = wait_none;
+ }
+ }
+ RACTOR_UNLOCK(cr);
+
+ // cleanup waiting
+ for (i=0; i<alen; i++) {
+ rb_ractor_t *r;
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ r = RACTOR_PTR(actions[i].v);
+ ractor_waiting_list_del(r, &r->sync.taking_ractors, cr);
+ break;
+ case ractor_select_action_receive:
+ case ractor_select_action_yield:
+ break;
+ }
+ }
+
+ // check results
+ enum ractor_wakeup_status wakeup_status = cr->sync.wait.wakeup_status;
+ cr->sync.wait.wakeup_status = wakeup_none;
+
+ switch (wakeup_status) {
+ case wakeup_none:
+ // OK. something happens.
+ // retry loop.
+ break;
+ case wakeup_by_retry:
+ // Retry request.
+ break;
+ case wakeup_by_send:
+ // OK.
+ // retry loop and try_receive will succss.
+ break;
+ case wakeup_by_yield:
+ // take was succeeded!
+ // cr.wait.taken_basket contains passed block
+ VM_ASSERT(cr->sync.wait.taken_basket.type != basket_type_none);
+ *ret_r = cr->sync.wait.taken_basket.sender;
+ VM_ASSERT(rb_ractor_p(*ret_r));
+ ret = ractor_basket_accept(&cr->sync.wait.taken_basket);
+ goto cleanup;
+ case wakeup_by_take:
+ *ret_r = ID2SYM(rb_intern("yield"));
+ ret = Qnil;
+ goto cleanup;
+ case wakeup_by_close:
+ // OK.
+ // retry loop and will get CloseError.
+ break;
+ case wakeup_by_interrupt:
+ ret = Qundef;
+ interrupted = true;
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+ RUBY_DEBUG_LOG("cleanup actions (%s)", wait_status_str(wait_status));
+
+ if (cr->sync.wait.yielded_basket.type != basket_type_none) {
+ ractor_basket_clear(&cr->sync.wait.yielded_basket);
+ }
+
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ VM_ASSERT(cr->sync.wait.wakeup_status == wakeup_none);
+ VM_ASSERT(cr->sync.wait.taken_basket.type == basket_type_none);
+ VM_ASSERT(cr->sync.wait.yielded_basket.type == basket_type_none);
+
+ if (interrupted) {
+ rb_vm_check_ints_blocking(ec);
+ interrupted = false;
+ goto restart;
+ }
+
+ VM_ASSERT(ret != Qundef);
+ return ret;
+}
+
+static VALUE
+ractor_yield(rb_execution_context_t *ec, rb_ractor_t *r, VALUE obj, VALUE move)
+{
+ VALUE ret_r;
+ ractor_select(ec, NULL, 0, obj, RTEST(move) ? true : false, &ret_r);
+ return Qnil;
+}
+
+static VALUE
+ractor_take(rb_execution_context_t *ec, rb_ractor_t *r)
+{
+ VALUE ret_r;
+ VALUE v = ractor_select(ec, &r->pub.self, 1, Qundef, false, &ret_r);
+ return v;
+}
+
+static VALUE
+ractor_close_incoming(rb_execution_context_t *ec, rb_ractor_t *r)
+{
+ VALUE prev;
+
+ RACTOR_LOCK(r);
+ {
+ if (!r->sync.incoming_port_closed) {
+ prev = Qfalse;
+ r->sync.incoming_port_closed = true;
+ if (ractor_wakeup(r, wait_receiving, wakeup_by_close)) {
+ VM_ASSERT(r->sync.incoming_queue.cnt == 0);
+ RUBY_DEBUG_LOG("cancel receiving", 0);
+ }
+ }
+ else {
+ prev = Qtrue;
+ }
+ }
+ RACTOR_UNLOCK(r);
+ return prev;
+}
+
+static VALUE
+ractor_close_outgoing(rb_execution_context_t *ec, rb_ractor_t *r)
+{
+ VALUE prev;
+
+ RACTOR_LOCK(r);
+ {
+ if (!r->sync.outgoing_port_closed) {
+ prev = Qfalse;
+ r->sync.outgoing_port_closed = true;
+ }
+ else {
+ prev = Qtrue;
+ }
+
+ // wakeup all taking ractors
+ rb_ractor_t *taking_ractor;
+ while ((taking_ractor = ractor_waiting_list_shift(r, &r->sync.taking_ractors)) != NULL) {
+ RACTOR_LOCK(taking_ractor);
+ ractor_wakeup(taking_ractor, wait_taking, wakeup_by_close);
+ RACTOR_UNLOCK(taking_ractor);
+ }
+
+ // raising yielding Ractor
+ if (!r->yield_atexit &&
+ ractor_wakeup(r, wait_yielding, wakeup_by_close)) {
+ RUBY_DEBUG_LOG("cancel yielding", 0);
+ }
+ }
+ RACTOR_UNLOCK(r);
+ return prev;
+}
+
+// creation/termination
+
+static uint32_t
+ractor_next_id(void)
+{
+ uint32_t id;
+
+ RB_VM_LOCK();
+ {
+ id = ++ractor_last_id;
+ }
+ RB_VM_UNLOCK();
+
+ return id;
+}
+
+static void
+vm_insert_ractor0(rb_vm_t *vm, rb_ractor_t *r, bool single_ractor_mode)
+{
+ RUBY_DEBUG_LOG("r:%u ractor.cnt:%u++", r->pub.id, vm->ractor.cnt);
+ VM_ASSERT(single_ractor_mode || RB_VM_LOCKED_P());
+
+ list_add_tail(&vm->ractor.set, &r->vmlr_node);
+ vm->ractor.cnt++;
+}
+
+static void
+cancel_single_ractor_mode(void)
+{
+ // enable multi-ractor mode
+ RUBY_DEBUG_LOG("enable multi-ractor mode", 0);
+
+ rb_gc_start();
+ rb_transient_heap_evacuate();
+
+ ruby_single_main_ractor = NULL;
+
+ if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL)) {
+ rb_category_warn(RB_WARN_CATEGORY_EXPERIMENTAL,
+ "Ractor is experimental, and the behavior may change in future versions of Ruby! "
+ "Also there are many implementation issues.");
+ }
+}
+
+static void
+vm_insert_ractor(rb_vm_t *vm, rb_ractor_t *r)
+{
+ VM_ASSERT(ractor_status_p(r, ractor_created));
+
+ if (rb_multi_ractor_p()) {
+ RB_VM_LOCK();
+ {
+ vm_insert_ractor0(vm, r, false);
+ vm_ractor_blocking_cnt_inc(vm, r, __FILE__, __LINE__);
+ }
+ RB_VM_UNLOCK();
+ }
+ else {
+ if (vm->ractor.cnt == 0) {
+ // main ractor
+ vm_insert_ractor0(vm, r, true);
+ ractor_status_set(r, ractor_blocking);
+ ractor_status_set(r, ractor_running);
+ }
+ else {
+ cancel_single_ractor_mode();
+ vm_insert_ractor0(vm, r, true);
+ vm_ractor_blocking_cnt_inc(vm, r, __FILE__, __LINE__);
+ }
+ }
+}
+
+static void
+vm_remove_ractor(rb_vm_t *vm, rb_ractor_t *cr)
+{
+ VM_ASSERT(ractor_status_p(cr, ractor_running));
+ VM_ASSERT(vm->ractor.cnt > 1);
+ VM_ASSERT(cr->threads.cnt == 1);
+
+ RB_VM_LOCK();
+ {
+ RUBY_DEBUG_LOG("ractor.cnt:%u-- terminate_waiting:%d",
+ vm->ractor.cnt, vm->ractor.sync.terminate_waiting);
+
+ VM_ASSERT(vm->ractor.cnt > 0);
+ list_del(&cr->vmlr_node);
+
+ if (vm->ractor.cnt <= 2 && vm->ractor.sync.terminate_waiting) {
+ rb_native_cond_signal(&vm->ractor.sync.terminate_cond);
+ }
+ vm->ractor.cnt--;
+
+ /* Clear the cached freelist to prevent a memory leak. */
+ rb_gc_ractor_newobj_cache_clear(&cr->newobj_cache);
+
+ ractor_status_set(cr, ractor_terminated);
+ }
+ RB_VM_UNLOCK();
+}
+
+static VALUE
+ractor_alloc(VALUE klass)
+{
+ rb_ractor_t *r;
+ VALUE rv = TypedData_Make_Struct(klass, rb_ractor_t, &ractor_data_type, r);
+ FL_SET_RAW(rv, RUBY_FL_SHAREABLE);
+ r->pub.self = rv;
+ VM_ASSERT(ractor_status_p(r, ractor_created));
+ return rv;
+}
+
+rb_ractor_t *
+rb_ractor_main_alloc(void)
+{
+ rb_ractor_t *r = ruby_mimmalloc(sizeof(rb_ractor_t));
+ if (r == NULL) {
+ fprintf(stderr, "[FATAL] failed to allocate memory for main ractor\n");
+ exit(EXIT_FAILURE);
+ }
+ MEMZERO(r, rb_ractor_t, 1);
+ r->pub.id = ++ractor_last_id;
+ r->loc = Qnil;
+ r->name = Qnil;
+ r->pub.self = Qnil;
+ ruby_single_main_ractor = r;
+
+ return r;
+}
+
+#if defined(HAVE_WORKING_FORK)
+void
+rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th)
+{
+ // initialize as a main ractor
+ vm->ractor.cnt = 0;
+ vm->ractor.blocking_cnt = 0;
+ ruby_single_main_ractor = th->ractor;
+ th->ractor->status_ = ractor_created;
+
+ rb_ractor_living_threads_init(th->ractor);
+ rb_ractor_living_threads_insert(th->ractor, th);
+
+ VM_ASSERT(vm->ractor.blocking_cnt == 0);
+ VM_ASSERT(vm->ractor.cnt == 1);
+}
+#endif
+
+void rb_gvl_init(rb_global_vm_lock_t *gvl);
+
+void
+rb_ractor_living_threads_init(rb_ractor_t *r)
+{
+ list_head_init(&r->threads.set);
+ r->threads.cnt = 0;
+ r->threads.blocking_cnt = 0;
+}
+
+static void
+ractor_init(rb_ractor_t *r, VALUE name, VALUE loc)
+{
+ ractor_queue_setup(&r->sync.incoming_queue);
+ rb_native_mutex_initialize(&r->sync.lock);
+ rb_native_cond_initialize(&r->sync.cond);
+ rb_native_cond_initialize(&r->barrier_wait_cond);
+
+ // thread management
+ rb_gvl_init(&r->threads.gvl);
+ rb_ractor_living_threads_init(r);
+
+ // naming
+ if (!NIL_P(name)) {
+ rb_encoding *enc;
+ StringValueCStr(name);
+ enc = rb_enc_get(name);
+ if (!rb_enc_asciicompat(enc)) {
+ rb_raise(rb_eArgError, "ASCII incompatible encoding (%s)",
+ rb_enc_name(enc));
+ }
+ name = rb_str_new_frozen(name);
+ }
+ r->name = name;
+ r->loc = loc;
+}
+
+void
+rb_ractor_main_setup(rb_vm_t *vm, rb_ractor_t *r, rb_thread_t *th)
+{
+ r->pub.self = TypedData_Wrap_Struct(rb_cRactor, &ractor_data_type, r);
+ FL_SET_RAW(r->pub.self, RUBY_FL_SHAREABLE);
+ ractor_init(r, Qnil, Qnil);
+ r->threads.main = th;
+ rb_ractor_living_threads_insert(r, th);
+}
+
+static VALUE
+ractor_create(rb_execution_context_t *ec, VALUE self, VALUE loc, VALUE name, VALUE args, VALUE block)
+{
+ VALUE rv = ractor_alloc(self);
+ rb_ractor_t *r = RACTOR_PTR(rv);
+ ractor_init(r, name, loc);
+
+ // can block here
+ r->pub.id = ractor_next_id();
+ RUBY_DEBUG_LOG("r:%u", r->pub.id);
+
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ r->verbose = cr->verbose;
+ r->debug = cr->debug;
+
+ rb_thread_create_ractor(r, args, block);
+
+ RB_GC_GUARD(rv);
+ return rv;
+}
+
+static void
+ractor_yield_atexit(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE v, bool exc)
+{
+ if (cr->sync.outgoing_port_closed) {
+ return;
+ }
+
+ ASSERT_ractor_unlocking(cr);
+
+ struct rb_ractor_basket basket;
+ ractor_basket_setup(ec, &basket, v, Qfalse, exc, true, true /* this flag is ignored because move is Qfalse */);
+
+ retry:
+ if (ractor_try_yield(ec, cr, &basket)) {
+ // OK.
+ }
+ else {
+ bool retry = false;
+ RACTOR_LOCK(cr);
+ {
+ if (cr->sync.taking_ractors.cnt == 0) {
+ cr->sync.wait.yielded_basket = basket;
+
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ cr->sync.wait.status = wait_yielding;
+ cr->sync.wait.wakeup_status = wakeup_none;
+
+ VM_ASSERT(cr->yield_atexit == false);
+ cr->yield_atexit = true;
+ }
+ else {
+ retry = true; // another ractor is waiting for the yield.
+ }
+ }
+ RACTOR_UNLOCK(cr);
+
+ if (retry) goto retry;
+ }
+}
+
+void
+rb_ractor_teardown(rb_execution_context_t *ec)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ ractor_close_incoming(ec, cr);
+ ractor_close_outgoing(ec, cr);
+
+ // sync with rb_ractor_terminate_interrupt_main_thread()
+ RB_VM_LOCK_ENTER();
+ {
+ VM_ASSERT(cr->threads.main != NULL);
+ cr->threads.main = NULL;
+ }
+ RB_VM_LOCK_LEAVE();
+}
+
+void
+rb_ractor_atexit(rb_execution_context_t *ec, VALUE result)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ ractor_yield_atexit(ec, cr, result, false);
+}
+
+void
+rb_ractor_atexit_exception(rb_execution_context_t *ec)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ ractor_yield_atexit(ec, cr, ec->errinfo, true);
+}
+
+void
+rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *r, int len, VALUE *ptr)
+{
+ for (int i=0; i<len; i++) {
+ ptr[i] = ractor_receive(ec, r);
+ }
+}
+
+void
+rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *r, VALUE args)
+{
+ int len = RARRAY_LENINT(args);
+ for (int i=0; i<len; i++) {
+ ractor_send(ec, r, RARRAY_AREF(args, i), false);
+ }
+}
+
+MJIT_FUNC_EXPORTED bool
+rb_ractor_main_p_(void)
+{
+ VM_ASSERT(rb_multi_ractor_p());
+ rb_execution_context_t *ec = GET_EC();
+ return rb_ec_ractor_ptr(ec) == rb_ec_vm_ptr(ec)->ractor.main_ractor;
+}
+
+bool
+rb_obj_is_main_ractor(VALUE gv)
+{
+ if (!rb_ractor_p(gv)) return false;
+ rb_ractor_t *r = DATA_PTR(gv);
+ return r == GET_VM()->ractor.main_ractor;
+}
+
+rb_global_vm_lock_t *
+rb_ractor_gvl(rb_ractor_t *r)
+{
+ return &r->threads.gvl;
+}
+
+int
+rb_ractor_living_thread_num(const rb_ractor_t *r)
+{
+ return r->threads.cnt;
+}
+
+VALUE
+rb_ractor_thread_list(rb_ractor_t *r)
+{
+ rb_thread_t *th = 0;
+ VALUE *ts;
+ int ts_cnt;
+
+ RACTOR_LOCK(r);
+ {
+ ts = ALLOCA_N(VALUE, r->threads.cnt);
+ ts_cnt = 0;
+
+ list_for_each(&r->threads.set, th, lt_node) {
+ switch (th->status) {
+ case THREAD_RUNNABLE:
+ case THREAD_STOPPED:
+ case THREAD_STOPPED_FOREVER:
+ ts[ts_cnt++] = th->self;
+ default:
+ break;
+ }
+ }
+ }
+ RACTOR_UNLOCK(r);
+
+ VALUE ary = rb_ary_new();
+ for (int i=0; i<ts_cnt; i++) {
+ rb_ary_push(ary, ts[i]);
+ }
+
+ return ary;
+}
+
+void
+rb_ractor_living_threads_insert(rb_ractor_t *r, rb_thread_t *th)
+{
+ VM_ASSERT(th != NULL);
+
+ RACTOR_LOCK(r);
+ {
+ RUBY_DEBUG_LOG("r(%d)->threads.cnt:%d++", r->pub.id, r->threads.cnt);
+ list_add_tail(&r->threads.set, &th->lt_node);
+ r->threads.cnt++;
+ }
+ RACTOR_UNLOCK(r);
+
+ // first thread for a ractor
+ if (r->threads.cnt == 1) {
+ VM_ASSERT(ractor_status_p(r, ractor_created));
+ vm_insert_ractor(th->vm, r);
+ }
+}
+
+static void
+vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *r, const char *file, int line)
+{
+ ractor_status_set(r, ractor_blocking);
+
+ RUBY_DEBUG_LOG2(file, line, "vm->ractor.blocking_cnt:%d++", vm->ractor.blocking_cnt);
+ vm->ractor.blocking_cnt++;
+ VM_ASSERT(vm->ractor.blocking_cnt <= vm->ractor.cnt);
+}
+
+void
+rb_vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line)
+{
+ ASSERT_vm_locking();
+ VM_ASSERT(GET_RACTOR() == cr);
+ vm_ractor_blocking_cnt_inc(vm, cr, file, line);
+}
+
+void
+rb_vm_ractor_blocking_cnt_dec(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line)
+{
+ ASSERT_vm_locking();
+ VM_ASSERT(GET_RACTOR() == cr);
+
+ RUBY_DEBUG_LOG2(file, line, "vm->ractor.blocking_cnt:%d--", vm->ractor.blocking_cnt);
+ VM_ASSERT(vm->ractor.blocking_cnt > 0);
+ vm->ractor.blocking_cnt--;
+
+ ractor_status_set(cr, ractor_running);
+}
+
+static void
+ractor_check_blocking(rb_ractor_t *cr, unsigned int remained_thread_cnt, const char *file, int line)
+{
+ VM_ASSERT(cr == GET_RACTOR());
+
+ RUBY_DEBUG_LOG2(file, line,
+ "cr->threads.cnt:%u cr->threads.blocking_cnt:%u vm->ractor.cnt:%u vm->ractor.blocking_cnt:%u",
+ cr->threads.cnt, cr->threads.blocking_cnt,
+ GET_VM()->ractor.cnt, GET_VM()->ractor.blocking_cnt);
+
+ VM_ASSERT(cr->threads.cnt >= cr->threads.blocking_cnt + 1);
+
+ if (remained_thread_cnt > 0 &&
+ // will be block
+ cr->threads.cnt == cr->threads.blocking_cnt + 1) {
+ // change ractor status: running -> blocking
+ rb_vm_t *vm = GET_VM();
+ ASSERT_vm_unlocking();
+
+ RB_VM_LOCK();
+ {
+ rb_vm_ractor_blocking_cnt_inc(vm, cr, file, line);
+ }
+ RB_VM_UNLOCK();
+ }
+}
+
+void
+rb_ractor_living_threads_remove(rb_ractor_t *cr, rb_thread_t *th)
+{
+ VM_ASSERT(cr == GET_RACTOR());
+ RUBY_DEBUG_LOG("r->threads.cnt:%d--", cr->threads.cnt);
+ ractor_check_blocking(cr, cr->threads.cnt - 1, __FILE__, __LINE__);
+
+ if (cr->threads.cnt == 1) {
+ vm_remove_ractor(th->vm, cr);
+ }
+ else {
+ RACTOR_LOCK(cr);
+ {
+ list_del(&th->lt_node);
+ cr->threads.cnt--;
+ }
+ RACTOR_UNLOCK(cr);
+ }
+}
+
+void
+rb_ractor_blocking_threads_inc(rb_ractor_t *cr, const char *file, int line)
+{
+ RUBY_DEBUG_LOG2(file, line, "cr->threads.blocking_cnt:%d++", cr->threads.blocking_cnt);
+
+ VM_ASSERT(cr->threads.cnt > 0);
+ VM_ASSERT(cr == GET_RACTOR());
+
+ ractor_check_blocking(cr, cr->threads.cnt, __FILE__, __LINE__);
+ cr->threads.blocking_cnt++;
+}
+
+void
+rb_ractor_blocking_threads_dec(rb_ractor_t *cr, const char *file, int line)
+{
+ RUBY_DEBUG_LOG2(file, line,
+ "r->threads.blocking_cnt:%d--, r->threads.cnt:%u",
+ cr->threads.blocking_cnt, cr->threads.cnt);
+
+ VM_ASSERT(cr == GET_RACTOR());
+
+ if (cr->threads.cnt == cr->threads.blocking_cnt) {
+ rb_vm_t *vm = GET_VM();
+
+ RB_VM_LOCK_ENTER();
+ {
+ rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);
+ }
+ RB_VM_LOCK_LEAVE();
+ }
+
+ cr->threads.blocking_cnt--;
+}
+
+void
+rb_ractor_vm_barrier_interrupt_running_thread(rb_ractor_t *r)
+{
+ VM_ASSERT(r != GET_RACTOR());
+ ASSERT_ractor_unlocking(r);
+ ASSERT_vm_locking();
+
+ RACTOR_LOCK(r);
+ {
+ if (ractor_status_p(r, ractor_running)) {
+ rb_execution_context_t *ec = r->threads.running_ec;
+ if (ec) {
+ RUBY_VM_SET_VM_BARRIER_INTERRUPT(ec);
+ }
+ }
+ }
+ RACTOR_UNLOCK(r);
+}
+
+void
+rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r)
+{
+ VM_ASSERT(r != GET_RACTOR());
+ ASSERT_ractor_unlocking(r);
+ ASSERT_vm_locking();
+
+ rb_thread_t *main_th = r->threads.main;
+ if (main_th) {
+ if (main_th->status != THREAD_KILLED) {
+ RUBY_VM_SET_TERMINATE_INTERRUPT(main_th->ec);
+ rb_threadptr_interrupt(main_th);
+ }
+ else {
+ RUBY_DEBUG_LOG("killed (%p)", main_th);
+ }
+ }
+}
+
+void rb_thread_terminate_all(rb_thread_t *th); // thread.c
+
+static void
+ractor_terminal_interrupt_all(rb_vm_t *vm)
+{
+ if (vm->ractor.cnt > 1) {
+ // send terminate notification to all ractors
+ rb_ractor_t *r = 0;
+ list_for_each(&vm->ractor.set, r, vmlr_node) {
+ if (r != vm->ractor.main_ractor) {
+ rb_ractor_terminate_interrupt_main_thread(r);
+ }
+ }
+ }
+}
+
+void
+rb_ractor_terminate_all(void)
+{
+ rb_vm_t *vm = GET_VM();
+ rb_ractor_t *cr = vm->ractor.main_ractor;
+
+ VM_ASSERT(cr == GET_RACTOR()); // only main-ractor's main-thread should kick it.
+
+ if (vm->ractor.cnt > 1) {
+ RB_VM_LOCK();
+ ractor_terminal_interrupt_all(vm); // kill all ractors
+ RB_VM_UNLOCK();
+ }
+ rb_thread_terminate_all(GET_THREAD()); // kill other threads in main-ractor and wait
+
+ RB_VM_LOCK();
+ {
+ while (vm->ractor.cnt > 1) {
+ RUBY_DEBUG_LOG("terminate_waiting:%d", vm->ractor.sync.terminate_waiting);
+ vm->ractor.sync.terminate_waiting = true;
+
+ // wait for 1sec
+ rb_vm_ractor_blocking_cnt_inc(vm, cr, __FILE__, __LINE__);
+ rb_vm_cond_timedwait(vm, &vm->ractor.sync.terminate_cond, 1000 /* ms */);
+ rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);
+
+ ractor_terminal_interrupt_all(vm);
+ }
+ }
+ RB_VM_UNLOCK();
+}
+
+rb_execution_context_t *
+rb_vm_main_ractor_ec(rb_vm_t *vm)
+{
+ return vm->ractor.main_ractor->threads.running_ec;
+}
+
+static VALUE
+ractor_moved_missing(int argc, VALUE *argv, VALUE self)
+{
+ rb_raise(rb_eRactorMovedError, "can not send any methods to a moved object");
+}
+
+/*
+ * Document-class: Ractor::ClosedError
+ *
+ * Raised when an attempt is made to send a message to a closed port,
+ * or to retrieve a message from a closed and empty port.
+ * Ports may be closed explicitly with Ractor#close_outgoing/close_incoming
+ * and are closed implicitly when a Ractor terminates.
+ *
+ * r = Ractor.new { sleep(500) }
+ * r.close_outgoing
+ * r.take # Ractor::ClosedError
+ *
+ * ClosedError is a descendant of StopIteration, so the closing of the ractor will break
+ * the loops without propagating the error:
+ *
+ * r = Ractor.new do
+ * loop do
+ * msg = receive # raises ClosedError and loop traps it
+ * puts "Received: #{msg}"
+ * end
+ * puts "loop exited"
+ * end
+ *
+ * 3.times{|i| r << i}
+ * r.close_incoming
+ * r.take
+ * puts "Continue successfully"
+ *
+ * This will print:
+ *
+ * Received: 0
+ * Received: 1
+ * Received: 2
+ * loop exited
+ * Continue successfully
+ */
+
+/*
+ * Document-class: Ractor::RemoteError
+ *
+ * Raised on attempt to Ractor#take if there was an uncaught exception in the Ractor.
+ * Its +cause+ will contain the original exception, and +ractor+ is the original ractor
+ * it was raised in.
+ *
+ * r = Ractor.new { raise "Something weird happened" }
+ *
+ * begin
+ * r.take
+ * rescue => e
+ * p e # => #<Ractor::RemoteError: thrown by remote Ractor.>
+ * p e.ractor == r # => true
+ * p e.cause # => #<RuntimeError: Something weird happened>
+ * end
+ *
+ */
+
+/*
+ * Document-class: Ractor::MovedError
+ *
+ * Raised on an attempt to access an object which was moved in Ractor#send or Ractor.yield.
+ *
+ * r = Ractor.new { sleep }
+ *
+ * ary = [1, 2, 3]
+ * r.send(ary, move: true)
+ * ary.inspect
+ * # Ractor::MovedError (can not send any methods to a moved object)
+ *
+ */
+
+/*
+ * Document-class: Ractor::MovedObject
+ *
+ * A special object which replaces any value that was moved to another ractor in Ractor#send
+ * or Ractor.yield. Any attempt to access the object results in Ractor::MovedError.
+ *
+ * r = Ractor.new { receive }
+ *
+ * ary = [1, 2, 3]
+ * r.send(ary, move: true)
+ * p Ractor::MovedObject === ary
+ * # => true
+ * ary.inspect
+ * # Ractor::MovedError (can not send any methods to a moved object)
+ */
+
+// Main docs are in ractor.rb, but without this clause there are weird artifacts
+// in their rendering.
+/*
+ * Document-class: Ractor
+ *
+ */
+
+void
+Init_Ractor(void)
+{
+ rb_cRactor = rb_define_class("Ractor", rb_cObject);
+ rb_undef_alloc_func(rb_cRactor);
+
+ rb_eRactorError = rb_define_class_under(rb_cRactor, "Error", rb_eRuntimeError);
+ rb_eRactorIsolationError = rb_define_class_under(rb_cRactor, "IsolationError", rb_eRactorError);
+ rb_eRactorRemoteError = rb_define_class_under(rb_cRactor, "RemoteError", rb_eRactorError);
+ rb_eRactorMovedError = rb_define_class_under(rb_cRactor, "MovedError", rb_eRactorError);
+ rb_eRactorClosedError = rb_define_class_under(rb_cRactor, "ClosedError", rb_eStopIteration);
+ rb_eRactorUnsafeError = rb_define_class_under(rb_cRactor, "UnsafeError", rb_eRactorError);
+
+ rb_cRactorMovedObject = rb_define_class_under(rb_cRactor, "MovedObject", rb_cBasicObject);
+ rb_undef_alloc_func(rb_cRactorMovedObject);
+ rb_define_method(rb_cRactorMovedObject, "method_missing", ractor_moved_missing, -1);
+
+ // override methods defined in BasicObject
+ rb_define_method(rb_cRactorMovedObject, "__send__", ractor_moved_missing, -1);
+ rb_define_method(rb_cRactorMovedObject, "!", ractor_moved_missing, -1);
+ rb_define_method(rb_cRactorMovedObject, "==", ractor_moved_missing, -1);
+ rb_define_method(rb_cRactorMovedObject, "!=", ractor_moved_missing, -1);
+ rb_define_method(rb_cRactorMovedObject, "__id__", ractor_moved_missing, -1);
+ rb_define_method(rb_cRactorMovedObject, "equal?", ractor_moved_missing, -1);
+ rb_define_method(rb_cRactorMovedObject, "instance_eval", ractor_moved_missing, -1);
+ rb_define_method(rb_cRactorMovedObject, "instance_exec", ractor_moved_missing, -1);
+}
+
+void
+rb_ractor_dump(void)
+{
+ rb_vm_t *vm = GET_VM();
+ rb_ractor_t *r = 0;
+
+ list_for_each(&vm->ractor.set, r, vmlr_node) {
+ if (r != vm->ractor.main_ractor) {
+ fprintf(stderr, "r:%u (%s)\n", r->pub.id, ractor_status_str(r->status_));
+ }
+ }
+}
+
+VALUE
+rb_ractor_stdin(void)
+{
+ if (rb_ractor_main_p()) {
+ return rb_stdin;
+ }
+ else {
+ rb_ractor_t *cr = GET_RACTOR();
+ return cr->r_stdin;
+ }
+}
+
+VALUE
+rb_ractor_stdout(void)
+{
+ if (rb_ractor_main_p()) {
+ return rb_stdout;
+ }
+ else {
+ rb_ractor_t *cr = GET_RACTOR();
+ return cr->r_stdout;
+ }
+}
+
+VALUE
+rb_ractor_stderr(void)
+{
+ if (rb_ractor_main_p()) {
+ return rb_stderr;
+ }
+ else {
+ rb_ractor_t *cr = GET_RACTOR();
+ return cr->r_stderr;
+ }
+}
+
+void
+rb_ractor_stdin_set(VALUE in)
+{
+ if (rb_ractor_main_p()) {
+ rb_stdin = in;
+ }
+ else {
+ rb_ractor_t *cr = GET_RACTOR();
+ RB_OBJ_WRITE(cr->pub.self, &cr->r_stdin, in);
+ }
+}
+
+void
+rb_ractor_stdout_set(VALUE out)
+{
+ if (rb_ractor_main_p()) {
+ rb_stdout = out;
+ }
+ else {
+ rb_ractor_t *cr = GET_RACTOR();
+ RB_OBJ_WRITE(cr->pub.self, &cr->r_stdout, out);
+ }
+}
+
+void
+rb_ractor_stderr_set(VALUE err)
+{
+ if (rb_ractor_main_p()) {
+ rb_stderr = err;
+ }
+ else {
+ rb_ractor_t *cr = GET_RACTOR();
+ RB_OBJ_WRITE(cr->pub.self, &cr->r_stderr, err);
+ }
+}
+
+rb_hook_list_t *
+rb_ractor_hooks(rb_ractor_t *cr)
+{
+ return &cr->pub.hooks;
+}
+
+/// traverse function
+
+// 2: stop search
+// 1: skip child
+// 0: continue
+
+enum obj_traverse_iterator_result {
+ traverse_cont,
+ traverse_skip,
+ traverse_stop,
+};
+
+typedef enum obj_traverse_iterator_result (*rb_obj_traverse_enter_func)(VALUE obj);
+typedef enum obj_traverse_iterator_result (*rb_obj_traverse_leave_func)(VALUE obj);
+typedef enum obj_traverse_iterator_result (*rb_obj_traverse_final_func)(VALUE obj);
+
+static enum obj_traverse_iterator_result null_leave(VALUE obj);
+
+struct obj_traverse_data {
+ rb_obj_traverse_enter_func enter_func;
+ rb_obj_traverse_leave_func leave_func;
+
+ st_table *rec;
+ VALUE rec_hash;
+};
+
+
+struct obj_traverse_callback_data {
+ bool stop;
+ struct obj_traverse_data *data;
+};
+
+static int obj_traverse_i(VALUE obj, struct obj_traverse_data *data);
+
+static int
+obj_hash_traverse_i(VALUE key, VALUE val, VALUE ptr)
+{
+ struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr;
+
+ if (obj_traverse_i(key, d->data)) {
+ d->stop = true;
+ return ST_STOP;
+ }
+
+ if (obj_traverse_i(val, d->data)) {
+ d->stop = true;
+ return ST_STOP;
+ }
+
+ return ST_CONTINUE;
+}
+
+static void
+obj_traverse_reachable_i(VALUE obj, void *ptr)
+{
+ struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr;
+
+ if (obj_traverse_i(obj, d->data)) {
+ d->stop = true;
+ }
+}
+
+static struct st_table *
+obj_traverse_rec(struct obj_traverse_data *data)
+{
+ if (UNLIKELY(!data->rec)) {
+ data->rec_hash = rb_ident_hash_new();
+ data->rec = rb_hash_st_table(data->rec_hash);
+ }
+ return data->rec;
+}
+
+static int
+obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
+{
+ if (RB_SPECIAL_CONST_P(obj)) return 0;
+
+ switch (data->enter_func(obj)) {
+ case traverse_cont: break;
+ case traverse_skip: return 0; // skip children
+ case traverse_stop: return 1; // stop search
+ }
+
+ if (UNLIKELY(st_insert(obj_traverse_rec(data), obj, 1))) {
+ // already traversed
+ return 0;
+ }
+
+ if (UNLIKELY(FL_TEST_RAW(obj, FL_EXIVAR))) {
+ struct gen_ivtbl *ivtbl;
+ rb_ivar_generic_ivtbl_lookup(obj, &ivtbl);
+ for (uint32_t i = 0; i < ivtbl->numiv; i++) {
+ VALUE val = ivtbl->ivptr[i];
+ if (val != Qundef && obj_traverse_i(val, data)) return 1;
+ }
+ }
+
+ switch (BUILTIN_TYPE(obj)) {
+ // no child node
+ case T_STRING:
+ case T_FLOAT:
+ case T_BIGNUM:
+ case T_REGEXP:
+ case T_FILE:
+ case T_SYMBOL:
+ case T_MATCH:
+ break;
+
+ case T_OBJECT:
+ {
+ uint32_t len = ROBJECT_NUMIV(obj);
+ VALUE *ptr = ROBJECT_IVPTR(obj);
+
+ for (uint32_t i=0; i<len; i++) {
+ VALUE val = ptr[i];
+ if (val != Qundef && obj_traverse_i(val, data)) return 1;
+ }
+ }
+ break;
+
+ case T_ARRAY:
+ {
+ for (int i = 0; i < RARRAY_LENINT(obj); i++) {
+ VALUE e = rb_ary_entry(obj, i);
+ if (obj_traverse_i(e, data)) return 1;
+ }
+ }
+ break;
+
+ case T_HASH:
+ {
+ if (obj_traverse_i(RHASH_IFNONE(obj), data)) return 1;
+
+ struct obj_traverse_callback_data d = {
+ .stop = false,
+ .data = data,
+ };
+ rb_hash_foreach(obj, obj_hash_traverse_i, (VALUE)&d);
+ if (d.stop) return 1;
+ }
+ break;
+
+ case T_STRUCT:
+ {
+ long len = RSTRUCT_LEN(obj);
+ const VALUE *ptr = RSTRUCT_CONST_PTR(obj);
+
+ for (long i=0; i<len; i++) {
+ if (obj_traverse_i(ptr[i], data)) return 1;
+ }
+ }
+ break;
+
+ case T_RATIONAL:
+ if (obj_traverse_i(RRATIONAL(obj)->num, data)) return 1;
+ if (obj_traverse_i(RRATIONAL(obj)->den, data)) return 1;
+ break;
+ case T_COMPLEX:
+ if (obj_traverse_i(RCOMPLEX(obj)->real, data)) return 1;
+ if (obj_traverse_i(RCOMPLEX(obj)->imag, data)) return 1;
+ break;
+
+ case T_DATA:
+ case T_IMEMO:
+ {
+ struct obj_traverse_callback_data d = {
+ .stop = false,
+ .data = data,
+ };
+ RB_VM_LOCK_ENTER_NO_BARRIER();
+ {
+ rb_objspace_reachable_objects_from(obj, obj_traverse_reachable_i, &d);
+ }
+ RB_VM_LOCK_LEAVE_NO_BARRIER();
+ if (d.stop) return 1;
+ }
+ break;
+
+ // unreachable
+ case T_CLASS:
+ case T_MODULE:
+ case T_ICLASS:
+ default:
+ rp(obj);
+ rb_bug("unreachable");
+ }
+
+ if (data->leave_func(obj) == traverse_stop) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+struct rb_obj_traverse_final_data {
+ rb_obj_traverse_final_func final_func;
+ int stopped;
+};
+
+static int
+obj_traverse_final_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ struct rb_obj_traverse_final_data *data = (void *)arg;
+ if (data->final_func(key)) {
+ data->stopped = 1;
+ return ST_STOP;
+ }
+ return ST_CONTINUE;
+}
+
+// 0: traverse all
+// 1: stopped
+static int
+rb_obj_traverse(VALUE obj,
+ rb_obj_traverse_enter_func enter_func,
+ rb_obj_traverse_leave_func leave_func,
+ rb_obj_traverse_final_func final_func)
+{
+ struct obj_traverse_data data = {
+ .enter_func = enter_func,
+ .leave_func = leave_func,
+ .rec = NULL,
+ };
+
+ if (obj_traverse_i(obj, &data)) return 1;
+ if (final_func && data.rec) {
+ struct rb_obj_traverse_final_data f = {final_func, 0};
+ st_foreach(data.rec, obj_traverse_final_i, (st_data_t)&f);
+ return f.stopped;
+ }
+ return 0;
+}
+
+static int
+frozen_shareable_p(VALUE obj, bool *made_shareable)
+{
+ if (!RB_TYPE_P(obj, T_DATA)) {
+ return true;
+ }
+ else if (RTYPEDDATA_P(obj)) {
+ const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
+ if (type->flags & RUBY_TYPED_FROZEN_SHAREABLE) {
+ return true;
+ }
+ else if (made_shareable && rb_obj_is_proc(obj)) {
+ // special path to make shareable Proc.
+ rb_proc_ractor_make_shareable(obj);
+ *made_shareable = true;
+ VM_ASSERT(RB_OBJ_SHAREABLE_P(obj));
+ return false;
+ }
+ }
+
+ return false;
+}
+
+static enum obj_traverse_iterator_result
+make_shareable_check_shareable(VALUE obj)
+{
+ VM_ASSERT(!SPECIAL_CONST_P(obj));
+ bool made_shareable = false;
+
+ if (rb_ractor_shareable_p(obj)) {
+ return traverse_skip;
+ }
+ else if (!frozen_shareable_p(obj, &made_shareable)) {
+ if (made_shareable) {
+ return traverse_skip;
+ }
+ else {
+ rb_raise(rb_eRactorError, "can not make shareable object for %"PRIsVALUE, obj);
+ }
+ }
+
+ if (!RB_OBJ_FROZEN_RAW(obj)) {
+ rb_funcall(obj, idFreeze, 0);
+
+ if (UNLIKELY(!RB_OBJ_FROZEN_RAW(obj))) {
+ rb_raise(rb_eRactorError, "#freeze does not freeze object correctly");
+ }
+
+ if (RB_OBJ_SHAREABLE_P(obj)) {
+ return traverse_skip;
+ }
+ }
+
+ return traverse_cont;
+}
+
+static enum obj_traverse_iterator_result
+mark_shareable(VALUE obj)
+{
+ FL_SET_RAW(obj, RUBY_FL_SHAREABLE);
+ return traverse_cont;
+}
+
+VALUE
+rb_ractor_make_shareable(VALUE obj)
+{
+ rb_obj_traverse(obj,
+ make_shareable_check_shareable,
+ null_leave, mark_shareable);
+ return obj;
+}
+
+VALUE
+rb_ractor_make_shareable_copy(VALUE obj)
+{
+ VALUE copy = ractor_copy(obj);
+ rb_obj_traverse(copy,
+ make_shareable_check_shareable,
+ null_leave, mark_shareable);
+ return copy;
+}
+
+VALUE
+rb_ractor_ensure_shareable(VALUE obj, VALUE name)
+{
+ if (!rb_ractor_shareable_p(obj)) {
+ VALUE message = rb_sprintf("cannot assign unshareable object to %"PRIsVALUE,
+ name);
+ rb_exc_raise(rb_exc_new_str(rb_eRactorIsolationError, message));
+ }
+ return obj;
+}
+
+static enum obj_traverse_iterator_result
+shareable_p_enter(VALUE obj)
+{
+ if (RB_OBJ_SHAREABLE_P(obj)) {
+ return traverse_skip;
+ }
+ else if (RB_TYPE_P(obj, T_CLASS) ||
+ RB_TYPE_P(obj, T_MODULE) ||
+ RB_TYPE_P(obj, T_ICLASS)) {
+ // TODO: remove it
+ mark_shareable(obj);
+ return traverse_skip;
+ }
+ else if (RB_OBJ_FROZEN_RAW(obj) &&
+ frozen_shareable_p(obj, NULL)) {
+ return traverse_cont;
+ }
+
+ return traverse_stop; // fail
+}
+
+MJIT_FUNC_EXPORTED bool
+rb_ractor_shareable_p_continue(VALUE obj)
+{
+ if (rb_obj_traverse(obj,
+ shareable_p_enter, null_leave,
+ mark_shareable)) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+#if RACTOR_CHECK_MODE > 0
+static enum obj_traverse_iterator_result
+reset_belonging_enter(VALUE obj)
+{
+ if (rb_ractor_shareable_p(obj)) {
+ return traverse_skip;
+ }
+ else {
+ rb_ractor_setup_belonging(obj);
+ return traverse_cont;
+ }
+}
+#endif
+
+static enum obj_traverse_iterator_result
+null_leave(VALUE obj)
+{
+ return traverse_cont;
+}
+
+static VALUE
+ractor_reset_belonging(VALUE obj)
+{
+#if RACTOR_CHECK_MODE > 0
+ rb_obj_traverse(obj, reset_belonging_enter, null_leave, NULL);
+#endif
+ return obj;
+}
+
+
+/// traverse and replace function
+
+// 2: stop search
+// 1: skip child
+// 0: continue
+
+struct obj_traverse_replace_data;
+static int obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data);
+typedef enum obj_traverse_iterator_result (*rb_obj_traverse_replace_enter_func)(VALUE obj, struct obj_traverse_replace_data *data);
+typedef enum obj_traverse_iterator_result (*rb_obj_traverse_replace_leave_func)(VALUE obj, struct obj_traverse_replace_data *data);
+
+struct obj_traverse_replace_data {
+ rb_obj_traverse_replace_enter_func enter_func;
+ rb_obj_traverse_replace_leave_func leave_func;
+
+ st_table *rec;
+ VALUE rec_hash;
+
+ VALUE replacement;
+ bool move;
+};
+
+struct obj_traverse_replace_callback_data {
+ bool stop;
+ VALUE src;
+ struct obj_traverse_replace_data *data;
+};
+
+static int
+obj_hash_traverse_replace_foreach_i(st_data_t key, st_data_t value, st_data_t argp, int error)
+{
+ return ST_REPLACE;
+}
+
+static int
+obj_hash_traverse_replace_i(st_data_t *key, st_data_t *val, st_data_t ptr, int exists)
+{
+ struct obj_traverse_replace_callback_data *d = (struct obj_traverse_replace_callback_data *)ptr;
+ struct obj_traverse_replace_data *data = d->data;
+
+ if (obj_traverse_replace_i(*key, data)) {
+ d->stop = true;
+ return ST_STOP;
+ }
+ else if (*key != data->replacement) {
+ VALUE v = *key = data->replacement;
+ RB_OBJ_WRITTEN(d->src, Qundef, v);
+ }
+
+ if (obj_traverse_replace_i(*val, data)) {
+ d->stop = true;
+ return ST_STOP;
+ }
+ else if (*val != data->replacement) {
+ VALUE v = *val = data->replacement;
+ RB_OBJ_WRITTEN(d->src, Qundef, v);
+ }
+
+ return ST_CONTINUE;
+}
+
+static struct st_table *
+obj_traverse_replace_rec(struct obj_traverse_replace_data *data)
+{
+ if (UNLIKELY(!data->rec)) {
+ data->rec_hash = rb_ident_hash_new();
+ data->rec = rb_hash_st_table(data->rec_hash);
+ }
+ return data->rec;
+}
+
+#if USE_TRANSIENT_HEAP
+void rb_ary_transient_heap_evacuate(VALUE ary, int promote);
+void rb_obj_transient_heap_evacuate(VALUE obj, int promote);
+void rb_hash_transient_heap_evacuate(VALUE hash, int promote);
+void rb_struct_transient_heap_evacuate(VALUE st, int promote);
+#endif
+
+static void
+obj_refer_only_shareables_p_i(VALUE obj, void *ptr)
+{
+ int *pcnt = (int *)ptr;
+
+ if (!rb_ractor_shareable_p(obj)) {
+ pcnt++;
+ }
+}
+
+static int
+obj_refer_only_shareables_p(VALUE obj)
+{
+ int cnt = 0;
+ RB_VM_LOCK_ENTER_NO_BARRIER();
+ {
+ rb_objspace_reachable_objects_from(obj, obj_refer_only_shareables_p_i, &cnt);
+ }
+ RB_VM_LOCK_LEAVE_NO_BARRIER();
+ return cnt == 0;
+}
+
+static int
+obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
+{
+ VALUE replacement;
+
+ if (RB_SPECIAL_CONST_P(obj)) {
+ data->replacement = obj;
+ return 0;
+ }
+
+ switch (data->enter_func(obj, data)) {
+ case traverse_cont: break;
+ case traverse_skip: return 0; // skip children
+ case traverse_stop: return 1; // stop search
+ }
+
+ replacement = data->replacement;
+
+ if (UNLIKELY(st_lookup(obj_traverse_replace_rec(data), (st_data_t)obj, (st_data_t *)&replacement))) {
+ data->replacement = replacement;
+ return 0;
+ }
+ else {
+ st_insert(obj_traverse_replace_rec(data), (st_data_t)obj, (st_data_t)replacement);
+ }
+
+ if (!data->move) {
+ obj = replacement;
+ }
+
+#define CHECK_AND_REPLACE(v) do { \
+ VALUE _val = (v); \
+ if (obj_traverse_replace_i(_val, data)) { return 1; } \
+ else if (data->replacement != _val) { RB_OBJ_WRITE(obj, &v, data->replacement); } \
+} while (0)
+
+ if (UNLIKELY(FL_TEST_RAW(obj, FL_EXIVAR))) {
+ struct gen_ivtbl *ivtbl;
+ rb_ivar_generic_ivtbl_lookup(obj, &ivtbl);
+ for (uint32_t i = 0; i < ivtbl->numiv; i++) {
+ if (ivtbl->ivptr[i] != Qundef) {
+ CHECK_AND_REPLACE(ivtbl->ivptr[i]);
+ }
+ }
+ }
+
+ switch (BUILTIN_TYPE(obj)) {
+ // no child node
+ case T_FLOAT:
+ case T_BIGNUM:
+ case T_REGEXP:
+ case T_FILE:
+ case T_SYMBOL:
+ case T_MATCH:
+ break;
+ case T_STRING:
+ rb_str_make_independent(obj);
+ break;
+
+ case T_OBJECT:
+ {
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_obj_transient_heap_evacuate(obj, TRUE);
+#endif
+
+ uint32_t len = ROBJECT_NUMIV(obj);
+ VALUE *ptr = ROBJECT_IVPTR(obj);
+
+ for (uint32_t i=0; i<len; i++) {
+ if (ptr[i] != Qundef) {
+ CHECK_AND_REPLACE(ptr[i]);
+ }
+ }
+ }
+ break;
+
+ case T_ARRAY:
+ {
+ rb_ary_cancel_sharing(obj);
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_ary_transient_heap_evacuate(obj, TRUE);
+#endif
+
+ for (int i = 0; i < RARRAY_LENINT(obj); i++) {
+ VALUE e = rb_ary_entry(obj, i);
+
+ if (obj_traverse_replace_i(e, data)) {
+ return 1;
+ }
+ else if (e != data->replacement) {
+ RARRAY_ASET(obj, i, data->replacement);
+ }
+ }
+ RB_GC_GUARD(obj);
+ }
+ break;
+
+ case T_HASH:
+ {
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_hash_transient_heap_evacuate(obj, TRUE);
+#endif
+ struct obj_traverse_replace_callback_data d = {
+ .stop = false,
+ .data = data,
+ .src = obj,
+ };
+ rb_hash_stlike_foreach_with_replace(obj,
+ obj_hash_traverse_replace_foreach_i,
+ obj_hash_traverse_replace_i,
+ (VALUE)&d);
+ if (d.stop) return 1;
+ // TODO: rehash here?
+
+ VALUE ifnone = RHASH_IFNONE(obj);
+ if (obj_traverse_replace_i(ifnone, data)) {
+ return 1;
+ }
+ else if (ifnone != data->replacement) {
+ RHASH_SET_IFNONE(obj, data->replacement);
+ }
+ }
+ break;
+
+ case T_STRUCT:
+ {
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_struct_transient_heap_evacuate(obj, TRUE);
+#endif
+ long len = RSTRUCT_LEN(obj);
+ const VALUE *ptr = RSTRUCT_CONST_PTR(obj);
+
+ for (long i=0; i<len; i++) {
+ CHECK_AND_REPLACE(ptr[i]);
+ }
+ }
+ break;
+
+ case T_RATIONAL:
+ CHECK_AND_REPLACE(RRATIONAL(obj)->num);
+ CHECK_AND_REPLACE(RRATIONAL(obj)->den);
+ break;
+ case T_COMPLEX:
+ CHECK_AND_REPLACE(RCOMPLEX(obj)->real);
+ CHECK_AND_REPLACE(RCOMPLEX(obj)->imag);
+ break;
+
+ case T_DATA:
+ if (!data->move && obj_refer_only_shareables_p(obj)) {
+ break;
+ }
+ else {
+ rb_raise(rb_eRactorError, "can not %s %"PRIsVALUE" object.",
+ data->move ? "move" : "copy", rb_class_of(obj));
+ }
+
+ case T_IMEMO:
+ // not supported yet
+ return 1;
+
+ // unreachable
+ case T_CLASS:
+ case T_MODULE:
+ case T_ICLASS:
+ default:
+ rp(obj);
+ rb_bug("unreachable");
+ }
+
+ data->replacement = replacement;
+
+ if (data->leave_func(obj, data) == traverse_stop) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+// 0: traverse all
+// 1: stopped
+static VALUE
+rb_obj_traverse_replace(VALUE obj,
+ rb_obj_traverse_replace_enter_func enter_func,
+ rb_obj_traverse_replace_leave_func leave_func,
+ bool move)
+{
+ struct obj_traverse_replace_data data = {
+ .enter_func = enter_func,
+ .leave_func = leave_func,
+ .rec = NULL,
+ .replacement = Qundef,
+ .move = move,
+ };
+
+ if (obj_traverse_replace_i(obj, &data)) {
+ return Qundef;
+ }
+ else {
+ return data.replacement;
+ }
+}
+
+struct RVALUE {
+ VALUE flags;
+ VALUE klass;
+ VALUE v1;
+ VALUE v2;
+ VALUE v3;
+};
+
+static const VALUE fl_users = FL_USER1 | FL_USER2 | FL_USER3 |
+ FL_USER4 | FL_USER5 | FL_USER6 | FL_USER7 |
+ FL_USER8 | FL_USER9 | FL_USER10 | FL_USER11 |
+ FL_USER12 | FL_USER13 | FL_USER14 | FL_USER15 |
+ FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19;
+
+static void
+ractor_moved_bang(VALUE obj)
+{
+ // invalidate src object
+ struct RVALUE *rv = (void *)obj;
+
+ rv->klass = rb_cRactorMovedObject;
+ rv->v1 = 0;
+ rv->v2 = 0;
+ rv->v3 = 0;
+ rv->flags = rv->flags & ~fl_users;
+
+ // TODO: record moved location
+}
+
+static enum obj_traverse_iterator_result
+move_enter(VALUE obj, struct obj_traverse_replace_data *data)
+{
+ if (rb_ractor_shareable_p(obj)) {
+ data->replacement = obj;
+ return traverse_skip;
+ }
+ else {
+ data->replacement = rb_obj_alloc(RBASIC_CLASS(obj));
+ return traverse_cont;
+ }
+}
+
+void rb_replace_generic_ivar(VALUE clone, VALUE obj); // variable.c
+
+static enum obj_traverse_iterator_result
+move_leave(VALUE obj, struct obj_traverse_replace_data *data)
+{
+ VALUE v = data->replacement;
+ struct RVALUE *dst = (struct RVALUE *)v;
+ struct RVALUE *src = (struct RVALUE *)obj;
+
+ dst->flags = (dst->flags & ~fl_users) | (src->flags & fl_users);
+
+ dst->v1 = src->v1;
+ dst->v2 = src->v2;
+ dst->v3 = src->v3;
+
+ if (UNLIKELY(FL_TEST_RAW(obj, FL_EXIVAR))) {
+ rb_replace_generic_ivar(v, obj);
+ }
+
+ // TODO: generic_ivar
+
+ ractor_moved_bang(obj);
+ return traverse_cont;
+}
+
+static VALUE
+ractor_move(VALUE obj)
+{
+ VALUE val = rb_obj_traverse_replace(obj, move_enter, move_leave, true);
+ if (val != Qundef) {
+ return val;
+ }
+ else {
+ rb_raise(rb_eRactorError, "can not move the object");
+ }
+}
+
+static enum obj_traverse_iterator_result
+copy_enter(VALUE obj, struct obj_traverse_replace_data *data)
+{
+ if (rb_ractor_shareable_p(obj)) {
+ data->replacement = obj;
+ return traverse_skip;
+ }
+ else {
+ data->replacement = rb_obj_clone(obj);
+ return traverse_cont;
+ }
+}
+
+static enum obj_traverse_iterator_result
+copy_leave(VALUE obj, struct obj_traverse_replace_data *data)
+{
+ return traverse_cont;
+}
+
+static VALUE
+ractor_copy(VALUE obj)
+{
+ VALUE val = rb_obj_traverse_replace(obj, copy_enter, copy_leave, false);
+ if (val != Qundef) {
+ return val;
+ }
+ else {
+ rb_raise(rb_eRactorError, "can not copy the object");
+ }
+}
+
+// Ractor local storage
+
+struct rb_ractor_local_key_struct {
+ const struct rb_ractor_local_storage_type *type;
+ void *main_cache;
+};
+
+static struct freed_ractor_local_keys_struct {
+ int cnt;
+ int capa;
+ rb_ractor_local_key_t *keys;
+} freed_ractor_local_keys;
+
+static int
+ractor_local_storage_mark_i(st_data_t key, st_data_t val, st_data_t dmy)
+{
+ struct rb_ractor_local_key_struct *k = (struct rb_ractor_local_key_struct *)key;
+ if (k->type->mark) (*k->type->mark)((void *)val);
+ return ST_CONTINUE;
+}
+
+static enum rb_id_table_iterator_result
+idkey_local_storage_mark_i(ID id, VALUE val, void *dmy)
+{
+ rb_gc_mark(val);
+ return ID_TABLE_CONTINUE;
+}
+
+static void
+ractor_local_storage_mark(rb_ractor_t *r)
+{
+ if (r->local_storage) {
+ st_foreach(r->local_storage, ractor_local_storage_mark_i, 0);
+
+ for (int i=0; i<freed_ractor_local_keys.cnt; i++) {
+ rb_ractor_local_key_t key = freed_ractor_local_keys.keys[i];
+ st_data_t val;
+ if (st_delete(r->local_storage, (st_data_t *)&key, &val) &&
+ key->type->free) {
+ (*key->type->free)((void *)val);
+ }
+ }
+ }
+
+ if (r->idkey_local_storage) {
+ rb_id_table_foreach(r->idkey_local_storage, idkey_local_storage_mark_i, NULL);
+ }
+}
+
+static int
+ractor_local_storage_free_i(st_data_t key, st_data_t val, st_data_t dmy)
+{
+ struct rb_ractor_local_key_struct *k = (struct rb_ractor_local_key_struct *)key;
+ if (k->type->free) (*k->type->free)((void *)val);
+ return ST_CONTINUE;
+}
+
+static void
+ractor_local_storage_free(rb_ractor_t *r)
+{
+ if (r->local_storage) {
+ st_foreach(r->local_storage, ractor_local_storage_free_i, 0);
+ st_free_table(r->local_storage);
+ }
+
+ if (r->idkey_local_storage) {
+ rb_id_table_free(r->idkey_local_storage);
+ }
+}
+
+static void
+rb_ractor_local_storage_value_mark(void *ptr)
+{
+ rb_gc_mark((VALUE)ptr);
+}
+
+static const struct rb_ractor_local_storage_type ractor_local_storage_type_null = {
+ NULL,
+ NULL,
+};
+
+const struct rb_ractor_local_storage_type rb_ractor_local_storage_type_free = {
+ NULL,
+ ruby_xfree,
+};
+
+static const struct rb_ractor_local_storage_type ractor_local_storage_type_value = {
+ rb_ractor_local_storage_value_mark,
+ NULL,
+};
+
+rb_ractor_local_key_t
+rb_ractor_local_storage_ptr_newkey(const struct rb_ractor_local_storage_type *type)
+{
+ rb_ractor_local_key_t key = ALLOC(struct rb_ractor_local_key_struct);
+ key->type = type ? type : &ractor_local_storage_type_null;
+ key->main_cache = (void *)Qundef;
+ return key;
+}
+
+rb_ractor_local_key_t
+rb_ractor_local_storage_value_newkey(void)
+{
+ return rb_ractor_local_storage_ptr_newkey(&ractor_local_storage_type_value);
+}
+
+void
+rb_ractor_local_storage_delkey(rb_ractor_local_key_t key)
+{
+ RB_VM_LOCK_ENTER();
+ {
+ if (freed_ractor_local_keys.cnt == freed_ractor_local_keys.capa) {
+ freed_ractor_local_keys.capa = freed_ractor_local_keys.capa ? freed_ractor_local_keys.capa * 2 : 4;
+ REALLOC_N(freed_ractor_local_keys.keys, rb_ractor_local_key_t, freed_ractor_local_keys.capa);
+ }
+ freed_ractor_local_keys.keys[freed_ractor_local_keys.cnt++] = key;
+ }
+ RB_VM_LOCK_LEAVE();
+}
+
+static bool
+ractor_local_ref(rb_ractor_local_key_t key, void **pret)
+{
+ if (rb_ractor_main_p()) {
+ if ((VALUE)key->main_cache != Qundef) {
+ *pret = key->main_cache;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ rb_ractor_t *cr = GET_RACTOR();
+
+ if (cr->local_storage && st_lookup(cr->local_storage, (st_data_t)key, (st_data_t *)pret)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
+
+static void
+ractor_local_set(rb_ractor_local_key_t key, void *ptr)
+{
+ rb_ractor_t *cr = GET_RACTOR();
+
+ if (cr->local_storage == NULL) {
+ cr->local_storage = st_init_numtable();
+ }
+
+ st_insert(cr->local_storage, (st_data_t)key, (st_data_t)ptr);
+
+ if (rb_ractor_main_p()) {
+ key->main_cache = ptr;
+ }
+}
+
+VALUE
+rb_ractor_local_storage_value(rb_ractor_local_key_t key)
+{
+ VALUE val;
+ if (ractor_local_ref(key, (void **)&val)) {
+ return val;
+ }
+ else {
+ return Qnil;
+ }
+}
+
+bool
+rb_ractor_local_storage_value_lookup(rb_ractor_local_key_t key, VALUE *val)
+{
+ if (ractor_local_ref(key, (void **)val)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+void
+rb_ractor_local_storage_value_set(rb_ractor_local_key_t key, VALUE val)
+{
+ ractor_local_set(key, (void *)val);
+}
+
+void *
+rb_ractor_local_storage_ptr(rb_ractor_local_key_t key)
+{
+ void *ret;
+ if (ractor_local_ref(key, &ret)) {
+ return ret;
+ }
+ else {
+ return NULL;
+ }
+}
+
+void
+rb_ractor_local_storage_ptr_set(rb_ractor_local_key_t key, void *ptr)
+{
+ ractor_local_set(key, ptr);
+}
+
+#define DEFAULT_KEYS_CAPA 0x10
+
+void
+rb_ractor_finish_marking(void)
+{
+ for (int i=0; i<freed_ractor_local_keys.cnt; i++) {
+ ruby_xfree(freed_ractor_local_keys.keys[i]);
+ }
+ freed_ractor_local_keys.cnt = 0;
+ if (freed_ractor_local_keys.capa > DEFAULT_KEYS_CAPA) {
+ freed_ractor_local_keys.capa = DEFAULT_KEYS_CAPA;
+ REALLOC_N(freed_ractor_local_keys.keys, rb_ractor_local_key_t, DEFAULT_KEYS_CAPA);
+ }
+}
+
+static VALUE
+ractor_local_value(rb_execution_context_t *ec, VALUE self, VALUE sym)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ ID id = rb_check_id(&sym);
+ struct rb_id_table *tbl = cr->idkey_local_storage;
+ VALUE val;
+
+ if (id && tbl && rb_id_table_lookup(tbl, id, &val)) {
+ return val;
+ }
+ else {
+ return Qnil;
+ }
+}
+
+static VALUE
+ractor_local_value_set(rb_execution_context_t *ec, VALUE self, VALUE sym, VALUE val)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ ID id = SYM2ID(rb_to_symbol(sym));
+ struct rb_id_table *tbl = cr->idkey_local_storage;
+
+ if (tbl == NULL) {
+ tbl = cr->idkey_local_storage = rb_id_table_create(2);
+ }
+ rb_id_table_insert(tbl, id, val);
+ return val;
+}
+
+#include "ractor.rbinc"
diff --git a/ractor.rb b/ractor.rb
new file mode 100644
index 0000000000..e6d5847237
--- /dev/null
+++ b/ractor.rb
@@ -0,0 +1,838 @@
+# Ractor is a Actor-model abstraction for Ruby that provides thread-safe parallel execution.
+#
+# Ractor.new can make new Ractor and it will run in parallel.
+#
+# # The simplest ractor
+# r = Ractor.new {puts "I am in Ractor!"}
+# r.take # wait it to finish
+# # here "I am in Ractor!" would be printed
+#
+# Ractors do not share usual objects, so the some kind of thread-safety concerns such as data-race,
+# race-conditions are not available on multi-ractor programming.
+#
+# To achieve this, ractors severely limit object sharing between different ractors.
+# For example, unlike threads, ractors can't access each other's objects, nor any objects through
+# variables of the outer scope.
+#
+# a = 1
+# r = Ractor.new {puts "I am in Ractor! a=#{a}"}
+# # fails immediately with
+# # ArgumentError (can not isolate a Proc because it accesses outer variables (a).)
+#
+# On CRuby (the default implementation), Global Virtual Machine Lock (GVL) is held per ractor, so
+# ractors are performed in parallel without locking each other.
+#
+# Instead of accessing the shared state, the objects should be passed to and from ractors via
+# sending and receiving objects as messages.
+#
+# a = 1
+# r = Ractor.new do
+# a_in_ractor = receive # receive blocks till somebody will pass message
+# puts "I am in Ractor! a=#{a_in_ractor}"
+# end
+# r.send(a) # pass it
+# r.take
+# # here "I am in Ractor! a=1" would be printed
+#
+# There are two pairs of methods for sending/receiving messages:
+#
+# * Ractor#send and Ractor.receive for when the _sender_ knows the receiver (push);
+# * Ractor.yield and Ractor#take for when the _receiver_ knows the sender (pull);
+#
+# In addition to that, an argument to Ractor.new would be passed to block and available there
+# as if received by Ractor.receive, and the last block value would be sent outside of the
+# ractor as if sent by Ractor.yield.
+#
+# A little demonstration on a classic ping-pong:
+#
+# server = Ractor.new do
+# puts "Server starts: #{self.inspect}"
+# puts "Server sends: ping"
+# Ractor.yield 'ping' # The server doesn't know the receiver and sends to whoever interested
+# received = Ractor.receive # The server doesn't know the sender and receives from whoever sent
+# puts "Server received: #{received}"
+# end
+#
+# client = Ractor.new(server) do |srv| # The server is sent inside client, and available as srv
+# puts "Client starts: #{self.inspect}"
+# received = srv.take # The Client takes a message specifically from the server
+# puts "Client received from " \
+# "#{srv.inspect}: #{received}"
+# puts "Client sends to " \
+# "#{srv.inspect}: pong"
+# srv.send 'pong' # The client sends a message specifically to the server
+# end
+#
+# [client, server].each(&:take) # Wait till they both finish
+#
+# This will output:
+#
+# Server starts: #<Ractor:#2 test.rb:1 running>
+# Server sends: ping
+# Client starts: #<Ractor:#3 test.rb:8 running>
+# Client received from #<Ractor:#2 rac.rb:1 blocking>: ping
+# Client sends to #<Ractor:#2 rac.rb:1 blocking>: pong
+# Server received: pong
+#
+# It is said that Ractor receives messages via the <em>incoming port</em>, and sends them
+# to the <em>outgoing port</em>. Either one can be disabled with Ractor#close_incoming and
+# Ractor#close_outgoing respectively. If a ractor terminated, its ports will be closed
+# automatically.
+#
+# == Shareable and unshareable objects
+#
+# When the object is sent to and from the ractor, it is important to understand whether the
+# object is shareable or unshareable. Most of objects are unshareable objects.
+#
+# Shareable objects are basically those which can be used by several threads without compromising
+# thread-safety; e.g. immutable ones. Ractor.shareable? allows to check this, and Ractor.make_shareable
+# tries to make object shareable if it is not.
+#
+# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are
+# Ractor.shareable?('foo') #=> false, unless the string is frozen due to # freeze_string_literals: true
+# Ractor.shareable?('foo'.freeze) #=> true
+#
+# ary = ['hello', 'world']
+# ary.frozen? #=> false
+# ary[0].frozen? #=> false
+# Ractor.make_shareable(ary)
+# ary.frozen? #=> true
+# ary[0].frozen? #=> true
+# ary[1].frozen? #=> true
+#
+# When a shareable object is sent (via #send or Ractor.yield), no additional processing happens,
+# and it just becomes usable by both ractors. When an unshareable object is sent, it can be
+# either _copied_ or _moved_. The first is the default, and it makes the object's full copy by
+# deep cloning of non-shareable parts of its structure.
+#
+# data = ['foo', 'bar'.freeze]
+# r = Ractor.new do
+# data2 = Ractor.receive
+# puts "In ractor: #{data2.object_id}, #{data2[0].object_id}, #{data2[1].object_id}"
+# end
+# r.send(data)
+# r.take
+# puts "Outside : #{data.object_id}, #{data[0].object_id}, #{data[1].object_id}"
+#
+# This will output:
+#
+# In ractor: 340, 360, 320
+# Outside : 380, 400, 320
+#
+# (Note that object id of both array and non-frozen string inside array have changed inside
+# the ractor, showing it is different objects. But the second array's element, which is a
+# shareable frozen string, has the same object_id.)
+#
+# Deep cloning of the objects may be slow, and sometimes impossible. Alternatively,
+# <tt>move: true</tt> may be used on sending. This will <em>move</em> the object to the
+# receiving ractor, making it inaccessible for a sending ractor.
+#
+# data = ['foo', 'bar']
+# r = Ractor.new do
+# data_in_ractor = Ractor.receive
+# puts "In ractor: #{data_in_ractor.object_id}, #{data_in_ractor[0].object_id}"
+# end
+# r.send(data, move: true)
+# r.take
+# puts "Outside: moved? #{Ractor::MovedObject === data}"
+# puts "Outside: #{data.inspect}"
+#
+# This will output:
+#
+# In ractor: 100, 120
+# Outside: moved? true
+# test.rb:9:in `method_missing': can not send any methods to a moved object (Ractor::MovedError)
+#
+# Notice that even +inspect+ (and more basic methods like <tt>__id__</tt>) is inaccessible
+# on a moved object.
+#
+# Besides frozen objects, there are shareable objects. Class and Module objects are shareable so
+# the Class/Module definitons are shared between ractors. Ractor objects are also shareable objects.
+# All operations for the shareable mutable objects are thread-safe, so the thread-safety property
+# will be kept. We can not define mutable shareable objects in Ruby, but C extensions can introduce them.
+#
+# It is prohibited to access instance variables of mutable shareable objects (especially Modules and classes)
+# from ractors other than main:
+#
+# class C
+# class << self
+# attr_accessor :tricky
+# end
+# end
+#
+# C.tricky = 'test'
+#
+# r = Ractor.new(C) do |cls|
+# puts "I see #{cls}"
+# puts "I can't see #{cls.tricky}"
+# end
+# r.take
+# # I see C
+# # can not access instance variables of classes/modules from non-main Ractors (RuntimeError)
+#
+# Ractors can access constants if they are shareable. The main Ractor is the only one that can
+# access non-shareable constants.
+#
+# GOOD = 'good'.freeze
+# BAD = 'bad'
+#
+# r = Ractor.new do
+# puts "GOOD=#{GOOD}"
+# puts "BAD=#{BAD}"
+# end
+# r.take
+# # GOOD=good
+# # can not access non-shareable objects in constant Object::BAD by non-main Ractor. (NameError)
+#
+# # Consider the same C class from above
+#
+# r = Ractor.new do
+# puts "I see #{C}"
+# puts "I can't see #{C.tricky}"
+# end
+# r.take
+# # I see C
+# # can not access instance variables of classes/modules from non-main Ractors (RuntimeError)
+#
+# See also the description of <tt># shareable_constant_value</tt> pragma in
+# {Comments syntax}[rdoc-ref:doc/syntax/comments.rdoc] explanation.
+#
+# == Ractors vs threads
+#
+# Each ractor creates its own thread. New threads can be created from inside ractor
+# (and, on CRuby, sharing GVL with other threads of this ractor).
+#
+# r = Ractor.new do
+# a = 1
+# Thread.new {puts "Thread in ractor: a=#{a}"}.join
+# end
+# r.take
+# # Here "Thread in ractor: a=1" will be printed
+#
+# == Note on code examples
+#
+# In examples below, sometimes we use the following method to wait till ractors that
+# are not currently blocked will finish (or process till next blocking) method.
+#
+# def wait
+# sleep(0.1)
+# end
+#
+# It is **only for demonstration purposes** and shouldn't be used in a real code.
+# Most of the times, just #take is used to wait till ractor will finish.
+#
+# == Reference
+#
+# See {Ractor desgin doc}[rdoc-ref:doc/ractor.md] for more details.
+#
+class Ractor
+ #
+ # call-seq:
+ # Ractor.new(*args, name: nil) {|*args| block } -> ractor
+ #
+ # Create a new Ractor with args and a block.
+ #
+ # A block (Proc) will be isolated (can't access to outer variables). +self+
+ # inside the block will refer to the current Ractor.
+ #
+ # r = Ractor.new { puts "Hi, I am #{self.inspect}" }
+ # r.take
+ # # Prints "Hi, I am #<Ractor:#2 test.rb:1 running>"
+ #
+ # +args+ passed to the method would be propagated to block args by the same rules as
+ # objects passed through #send/Ractor.receive: if +args+ are not shareable, they
+ # will be copied (via deep cloning, which might be inefficient).
+ #
+ # arg = [1, 2, 3]
+ # puts "Passing: #{arg} (##{arg.object_id})"
+ # r = Ractor.new(arg) {|received_arg|
+ # puts "Received: #{received_arg} (##{received_arg.object_id})"
+ # }
+ # r.take
+ # # Prints:
+ # # Passing: [1, 2, 3] (#280)
+ # # Received: [1, 2, 3] (#300)
+ #
+ # Ractor's +name+ can be set for debugging purposes:
+ #
+ # r = Ractor.new(name: 'my ractor') {}
+ # p r
+ # #=> #<Ractor:#3 my ractor test.rb:1 terminated>
+ #
+ def self.new(*args, name: nil, &block)
+ b = block # TODO: builtin bug
+ raise ArgumentError, "must be called with a block" unless block
+ loc = caller_locations(1, 1).first
+ loc = "#{loc.path}:#{loc.lineno}"
+ __builtin_ractor_create(loc, name, args, b)
+ end
+
+ # Returns the currently executing Ractor.
+ #
+ # Ractor.current #=> #<Ractor:#1 running>
+ def self.current
+ __builtin_cexpr! %q{
+ rb_ractor_self(rb_ec_ractor_ptr(ec));
+ }
+ end
+
+ # Returns total count of Ractors currently running.
+ #
+ # Ractor.count #=> 1
+ # r = Ractor.new(name: 'example') { Ractor.yield(1) }
+ # Ractor.count #=> 2 (main + example ractor)
+ # r.take # wait for Ractor.yield(1)
+ # r.take # wait till r will finish
+ # Ractor.count #=> 1
+ def self.count
+ __builtin_cexpr! %q{
+ ULONG2NUM(GET_VM()->ractor.cnt);
+ }
+ end
+
+ #
+ # call-seq:
+ # Ractor.select(*ractors, [yield_value:, move: false]) -> [ractor or symbol, obj]
+ #
+ # Waits for the first ractor to have something in its outgoing port, reads from this ractor, and
+ # returns that ractor and the object received.
+ #
+ # r1 = Ractor.new {Ractor.yield 'from 1'}
+ # r2 = Ractor.new {Ractor.yield 'from 2'}
+ #
+ # r, obj = Ractor.select(r1, r2)
+ #
+ # puts "received #{obj.inspect} from #{r.inspect}"
+ # # Prints: received "from 1" from #<Ractor:#2 test.rb:1 running>
+ #
+ # If one of the given ractors is the current ractor, and it would be selected, +r+ will contain
+ # +:receive+ symbol instead of the ractor object.
+ #
+ # r1 = Ractor.new(Ractor.current) do |main|
+ # main.send 'to main'
+ # Ractor.yield 'from 1'
+ # end
+ # r2 = Ractor.new do
+ # Ractor.yield 'from 2'
+ # end
+ #
+ # r, obj = Ractor.select(r1, r2, Ractor.current)
+ # puts "received #{obj.inspect} from #{r.inspect}"
+ # # Prints: received "to main" from :receive
+ #
+ # If +yield_value+ is provided, that value may be yielded if another Ractor is calling #take.
+ # In this case, the pair <tt>[:yield, nil]</tt> would be returned:
+ #
+ # r1 = Ractor.new(Ractor.current) do |main|
+ # puts "Received from main: #{main.take}"
+ # end
+ #
+ # puts "Trying to select"
+ # r, obj = Ractor.select(r1, Ractor.current, yield_value: 123)
+ # wait
+ # puts "Received #{obj.inspect} from #{r.inspect}"
+ #
+ # This will print:
+ #
+ # Trying to select
+ # Received from main: 123
+ # Received nil from :yield
+ #
+ # +move+ boolean flag defines whether yielded value should be copied (default) or moved.
+ def self.select(*ractors, yield_value: yield_unspecified = true, move: false)
+ raise ArgumentError, 'specify at least one ractor or `yield_value`' if yield_unspecified && ractors.empty?
+
+ __builtin_cstmt! %q{
+ const VALUE *rs = RARRAY_CONST_PTR_TRANSIENT(ractors);
+ VALUE rv;
+ VALUE v = ractor_select(ec, rs, RARRAY_LENINT(ractors),
+ yield_unspecified == Qtrue ? Qundef : yield_value,
+ (bool)RTEST(move) ? true : false, &rv);
+ return rb_ary_new_from_args(2, rv, v);
+ }
+ end
+
+ #
+ # call-seq:
+ # Ractor.receive -> msg
+ #
+ # Receive an incoming message from the current Ractor's incoming port's queue, which was
+ # sent there by #send.
+ #
+ # r = Ractor.new do
+ # v1 = Ractor.receive
+ # puts "Received: #{v1}"
+ # end
+ # r.send('message1')
+ # r.take
+ # # Here will be printed: "Received: message1"
+ #
+ # Alternatively, private instance method +receive+ may be used:
+ #
+ # r = Ractor.new do
+ # v1 = receive
+ # puts "Received: #{v1}"
+ # end
+ # r.send('message1')
+ # r.take
+ # # Here will be printed: "Received: message1"
+ #
+ # The method blocks if the queue is empty.
+ #
+ # r = Ractor.new do
+ # puts "Before first receive"
+ # v1 = Ractor.receive
+ # puts "Received: #{v1}"
+ # v2 = Ractor.receive
+ # puts "Received: #{v2}"
+ # end
+ # wait
+ # puts "Still not received"
+ # r.send('message1')
+ # wait
+ # puts "Still received only one"
+ # r.send('message2')
+ # r.take
+ #
+ # Output:
+ #
+ # Before first receive
+ # Still not received
+ # Received: message1
+ # Still received only one
+ # Received: message2
+ #
+ # If close_incoming was called on the ractor, the method raises Ractor::ClosedError
+ # if there are no more messages in incoming queue:
+ #
+ # Ractor.new do
+ # close_incoming
+ # receive
+ # end
+ # wait
+ # # in `receive': The incoming port is already closed => #<Ractor:#2 test.rb:1 running> (Ractor::ClosedError)
+ #
+ def self.receive
+ __builtin_cexpr! %q{
+ ractor_receive(ec, rb_ec_ractor_ptr(ec))
+ }
+ end
+
+ class << self
+ alias recv receive
+ end
+
+ # same as Ractor.receive
+ private def receive
+ __builtin_cexpr! %q{
+ ractor_receive(ec, rb_ec_ractor_ptr(ec))
+ }
+ end
+ alias recv receive
+
+ #
+ # call-seq:
+ # Ractor.receive_if {|msg| block } -> msg
+ #
+ # Receive only a specific message.
+ #
+ # Instead of Ractor.receive, Ractor.receive_if can provide a pattern
+ # by a block and you can choose the receiving message.
+ #
+ # r = Ractor.new do
+ # p Ractor.receive_if{|msg| msg.match?(/foo/)} #=> "foo3"
+ # p Ractor.receive_if{|msg| msg.match?(/bar/)} #=> "bar1"
+ # p Ractor.receive_if{|msg| msg.match?(/baz/)} #=> "baz2"
+ # end
+ # r << "bar1"
+ # r << "baz2"
+ # r << "foo3"
+ # r.take
+ #
+ # This will output:
+ #
+ # foo3
+ # bar1
+ # baz2
+ #
+ # If the block returns a truthy value, the message will be removed from the incoming queue
+ # and returned.
+ # Otherwise, the messsage remains in the incoming queue and the following received
+ # messages are checked by the given block.
+ #
+ # If there are no messages left in the incoming queue, the method will
+ # block until new messages arrive.
+ #
+ # If the block is escaped by break/return/exception/throw, the message is removed from
+ # the incoming queue as if a truthy value had been returned.
+ #
+ # r = Ractor.new do
+ # val = Ractor.receive_if{|msg| msg.is_a?(Array)}
+ # puts "Received successfully: #{val}"
+ # end
+ #
+ # r.send(1)
+ # r.send('test')
+ # wait
+ # puts "2 non-matching sent, nothing received"
+ # r.send([1, 2, 3])
+ # wait
+ #
+ # Prints:
+ #
+ # 2 non-matching sent, nothing received
+ # Received successfully: [1, 2, 3]
+ #
+ # Note that you can not call receive/receive_if in the given block recursively.
+ # It means that you should not do any tasks in the block.
+ #
+ # Ractor.current << true
+ # Ractor.receive_if{|msg| Ractor.receive}
+ # #=> `receive': can not call receive/receive_if recursively (Ractor::Error)
+ #
+ def self.receive_if &b
+ Primitive.ractor_receive_if b
+ end
+
+ private def receive_if &b
+ Primitive.ractor_receive_if b
+ end
+
+ #
+ # call-seq:
+ # ractor.send(msg, move: false) -> self
+ #
+ # Send a message to a Ractor's incoming queue to be consumed by Ractor.receive.
+ #
+ # r = Ractor.new do
+ # value = Ractor.receive
+ # puts "Received #{value}"
+ # end
+ # r.send 'message'
+ # # Prints: "Received: message"
+ #
+ # The method is non-blocking (will return immediately even if the ractor is not ready
+ # to receive anything):
+ #
+ # r = Ractor.new {sleep(5)}
+ # r.send('test')
+ # puts "Sent successfully"
+ # # Prints: "Sent successfully" immediately
+ #
+ # Attempt to send to ractor which already finished its execution will raise Ractor::ClosedError.
+ #
+ # r = Ractor.new {}
+ # r.take
+ # p r
+ # # "#<Ractor:#6 (irb):23 terminated>"
+ # r.send('test')
+ # # Ractor::ClosedError (The incoming-port is already closed)
+ #
+ # If close_incoming was called on the ractor, the method also raises Ractor::ClosedError.
+ #
+ # r = Ractor.new do
+ # sleep(500)
+ # receive
+ # end
+ # r.close_incoming
+ # r.send('test')
+ # # Ractor::ClosedError (The incoming-port is already closed)
+ # # The error would be raised immediately, not when ractor will try to receive
+ #
+ # If the +obj+ is unshareable, by default it would be copied into ractor by deep cloning.
+ # If the <tt>move: true</tt> is passed, object is _moved_ into ractor and becomes
+ # inaccessible to sender.
+ #
+ # r = Ractor.new {puts "Received: #{receive}"}
+ # msg = 'message'
+ # r.send(msg, move: true)
+ # r.take
+ # p msg
+ #
+ # This prints:
+ #
+ # Received: message
+ # in `p': undefined method `inspect' for #<Ractor::MovedObject:0x000055c99b9b69b8>
+ #
+ # All references to the object and its parts will become invalid in sender.
+ #
+ # r = Ractor.new {puts "Received: #{receive}"}
+ # s = 'message'
+ # ary = [s]
+ # copy = ary.dup
+ # r.send(ary, move: true)
+ #
+ # s.inspect
+ # # Ractor::MovedError (can not send any methods to a moved object)
+ # ary.class
+ # # Ractor::MovedError (can not send any methods to a moved object)
+ # copy.class
+ # # => Array, it is different object
+ # copy[0].inspect
+ # # Ractor::MovedError (can not send any methods to a moved object)
+ # # ...but its item was still a reference to `s`, which was moved
+ #
+ # If the object was shareable, <tt>move: true</tt> has no effect on it:
+ #
+ # r = Ractor.new {puts "Received: #{receive}"}
+ # s = 'message'.freeze
+ # r.send(s, move: true)
+ # s.inspect #=> "message", still available
+ #
+ def send(obj, move: false)
+ __builtin_cexpr! %q{
+ ractor_send(ec, RACTOR_PTR(self), obj, move)
+ }
+ end
+ alias << send
+
+ #
+ # call-seq:
+ # Ractor.yield(msg, move: false) -> nil
+ #
+ # Send a message to the current ractor's outgoing port to be consumed by #take.
+ #
+ # r = Ractor.new {Ractor.yield 'Hello from ractor'}
+ # puts r.take
+ # # Prints: "Hello from ractor"
+ #
+ # The method is blocking, and will return only when somebody consumes the
+ # sent message.
+ #
+ # r = Ractor.new do
+ # Ractor.yield 'Hello from ractor'
+ # puts "Ractor: after yield"
+ # end
+ # wait
+ # puts "Still not taken"
+ # puts r.take
+ #
+ # This will print:
+ #
+ # Still not taken
+ # Hello from ractor
+ # Ractor: after yield
+ #
+ # If the outgoing port was closed with #close_outgoing, the method will raise:
+ #
+ # r = Ractor.new do
+ # close_outgoing
+ # Ractor.yield 'Hello from ractor'
+ # end
+ # wait
+ # # `yield': The outgoing-port is already closed (Ractor::ClosedError)
+ #
+ # The meaning of +move+ argument is the same as for #send.
+ def self.yield(obj, move: false)
+ __builtin_cexpr! %q{
+ ractor_yield(ec, rb_ec_ractor_ptr(ec), obj, move)
+ }
+ end
+
+ #
+ # call-seq:
+ # ractor.take -> msg
+ #
+ # Take a message from ractor's outgoing port, which was put there by Ractor.yield or at ractor's
+ # finalization.
+ #
+ # r = Ractor.new do
+ # Ractor.yield 'explicit yield'
+ # 'last value'
+ # end
+ # puts r.take #=> 'explicit yield'
+ # puts r.take #=> 'last value'
+ # puts r.take # Ractor::ClosedError (The outgoing-port is already closed)
+ #
+ # The fact that the last value is also put to outgoing port means that +take+ can be used
+ # as some analog of Thread#join ("just wait till ractor finishes"), but don't forget it
+ # will raise if somebody had already consumed everything ractor have produced.
+ #
+ # If the outgoing port was closed with #close_outgoing, the method will raise Ractor::ClosedError.
+ #
+ # r = Ractor.new do
+ # sleep(500)
+ # Ractor.yield 'Hello from ractor'
+ # end
+ # r.close_outgoing
+ # r.take
+ # # Ractor::ClosedError (The outgoing-port is already closed)
+ # # The error would be raised immediately, not when ractor will try to receive
+ #
+ # If an uncaught exception is raised in the Ractor, it is propagated on take as a
+ # Ractor::RemoteError.
+ #
+ # r = Ractor.new {raise "Something weird happened"}
+ #
+ # begin
+ # r.take
+ # rescue => e
+ # p e # => #<Ractor::RemoteError: thrown by remote Ractor.>
+ # p e.ractor == r # => true
+ # p e.cause # => #<RuntimeError: Something weird happened>
+ # end
+ #
+ # Ractor::ClosedError is a descendant of StopIteration, so the closing of the ractor will break
+ # the loops without propagating the error:
+ #
+ # r = Ractor.new do
+ # 3.times {|i| Ractor.yield "message #{i}"}
+ # "finishing"
+ # end
+ #
+ # loop {puts "Received: " + r.take}
+ # puts "Continue successfully"
+ #
+ # This will print:
+ #
+ # Received: message 0
+ # Received: message 1
+ # Received: message 2
+ # Received: finishing
+ # Continue successfully
+ def take
+ __builtin_cexpr! %q{
+ ractor_take(ec, RACTOR_PTR(self))
+ }
+ end
+
+ def inspect
+ loc = __builtin_cexpr! %q{ RACTOR_PTR(self)->loc }
+ name = __builtin_cexpr! %q{ RACTOR_PTR(self)->name }
+ id = __builtin_cexpr! %q{ INT2FIX(rb_ractor_id(RACTOR_PTR(self))) }
+ status = __builtin_cexpr! %q{
+ rb_str_new2(ractor_status_str(RACTOR_PTR(self)->status_))
+ }
+ "#<Ractor:##{id}#{name ? ' '+name : ''}#{loc ? " " + loc : ''} #{status}>"
+ end
+
+ alias to_s inspect
+
+ # The name set in Ractor.new, or +nil+.
+ def name
+ __builtin_cexpr! %q{RACTOR_PTR(self)->name}
+ end
+
+ class RemoteError
+ attr_reader :ractor
+ end
+
+ #
+ # call-seq:
+ # ractor.close_incoming -> true | false
+ #
+ # Closes the incoming port and returns its previous state.
+ # All further attempts to Ractor.receive in the ractor, and #send to the ractor
+ # will fail with Ractor::ClosedError.
+ #
+ # r = Ractor.new {sleep(500)}
+ # r.close_incoming #=> false
+ # r.close_incoming #=> true
+ # r.send('test')
+ # # Ractor::ClosedError (The incoming-port is already closed)
+ def close_incoming
+ __builtin_cexpr! %q{
+ ractor_close_incoming(ec, RACTOR_PTR(self));
+ }
+ end
+
+ #
+ # call-seq:
+ # ractor.close_outgoing -> true | false
+ #
+ # Closes the outgoing port and returns its previous state.
+ # All further attempts to Ractor.yield in the ractor, and #take from the ractor
+ # will fail with Ractor::ClosedError.
+ #
+ # r = Ractor.new {sleep(500)}
+ # r.close_outgoing #=> false
+ # r.close_outgoing #=> true
+ # r.take
+ # # Ractor::ClosedError (The outgoing-port is already closed)
+ def close_outgoing
+ __builtin_cexpr! %q{
+ ractor_close_outgoing(ec, RACTOR_PTR(self));
+ }
+ end
+
+ #
+ # call-seq:
+ # Ractor.shareable?(obj) -> true | false
+ #
+ # Checks if the object is shareable by ractors.
+ #
+ # Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are frozen
+ # Ractor.shareable?('foo') #=> false, unless the string is frozen due to # freeze_string_literals: true
+ # Ractor.shareable?('foo'.freeze) #=> true
+ #
+ # See also the "Shareable and unshareable objects" section in the Ractor class docs.
+ def self.shareable? obj
+ __builtin_cexpr! %q{
+ rb_ractor_shareable_p(obj) ? Qtrue : Qfalse;
+ }
+ end
+
+ #
+ # call-seq:
+ # Ractor.make_shareable(obj, copy: false) -> shareable_obj
+ #
+ # Make +obj+ shareable between ractors.
+ #
+ # +obj+ and all the objects it refers to will be frozen, unless they are
+ # already shareable.
+ #
+ # If +copy+ keyword is +true+, the method will copy objects before freezing them
+ # This is safer option but it can take be slower.
+ #
+ # Note that the specification and implementation of this method are not
+ # mature and may be changed in the future.
+ #
+ # obj = ['test']
+ # Ractor.shareable?(obj) #=> false
+ # Ractor.make_shareable(obj) #=> ["test"]
+ # Ractor.shareable?(obj) #=> true
+ # obj.frozen? #=> true
+ # obj[0].frozen? #=> true
+ #
+ # # Copy vs non-copy versions:
+ # obj1 = ['test']
+ # obj1s = Ractor.make_shareable(obj1)
+ # obj1.frozen? #=> true
+ # obj1s.object_id == obj1.object_id #=> true
+ # obj2 = ['test']
+ # obj2s = Ractor.make_shareable(obj2, copy: true)
+ # obj2.frozen? #=> false
+ # obj2s.frozen? #=> true
+ # obj2s.object_id == obj2.object_id #=> false
+ # obj2s[0].object_id == obj2[0].object_id #=> false
+ #
+ # See also the "Shareable and unshareable objects" section in the Ractor class docs.
+ def self.make_shareable obj, copy: false
+ if copy
+ __builtin_cexpr! %q{
+ rb_ractor_make_shareable_copy(obj);
+ }
+ else
+ __builtin_cexpr! %q{
+ rb_ractor_make_shareable(obj);
+ }
+ end
+ end
+
+ # get a value from ractor-local storage
+ def [](sym)
+ Primitive.ractor_local_value(sym)
+ end
+
+ # set a value in ractor-local storage
+ def []=(sym, val)
+ Primitive.ractor_local_value_set(sym, val)
+ end
+
+ # returns main ractor
+ def self.main
+ __builtin_cexpr! %q{
+ rb_ractor_self(GET_VM()->ractor.main_ractor);
+ }
+ end
+end
diff --git a/ractor_core.h b/ractor_core.h
new file mode 100644
index 0000000000..800e7ce409
--- /dev/null
+++ b/ractor_core.h
@@ -0,0 +1,341 @@
+#include "ruby/ruby.h"
+#include "ruby/ractor.h"
+#include "vm_core.h"
+#include "id_table.h"
+#include "vm_debug.h"
+
+#ifndef RACTOR_CHECK_MODE
+#define RACTOR_CHECK_MODE (0 || VM_CHECK_MODE || RUBY_DEBUG)
+#endif
+
+enum rb_ractor_basket_type {
+ basket_type_none,
+ basket_type_ref,
+ basket_type_copy,
+ basket_type_move,
+ basket_type_will,
+ basket_type_deleted,
+ basket_type_reserved,
+};
+
+struct rb_ractor_basket {
+ bool exception;
+ enum rb_ractor_basket_type type;
+ VALUE v;
+ VALUE sender;
+};
+
+struct rb_ractor_queue {
+ struct rb_ractor_basket *baskets;
+ int start;
+ int cnt;
+ int size;
+ unsigned int serial;
+ unsigned int reserved_cnt;
+};
+
+struct rb_ractor_waiting_list {
+ int cnt;
+ int size;
+ rb_ractor_t **ractors;
+};
+
+struct rb_ractor_sync {
+ // ractor lock
+ rb_nativethread_lock_t lock;
+#if RACTOR_CHECK_MODE > 0
+ VALUE locked_by;
+#endif
+ rb_nativethread_cond_t cond;
+
+ // communication
+ struct rb_ractor_queue incoming_queue;
+ struct rb_ractor_waiting_list taking_ractors;
+
+ bool incoming_port_closed;
+ bool outgoing_port_closed;
+
+ struct ractor_wait {
+ enum ractor_wait_status {
+ wait_none = 0x00,
+ wait_receiving = 0x01,
+ wait_taking = 0x02,
+ wait_yielding = 0x04,
+ wait_moving = 0x08,
+ } status;
+
+ enum ractor_wakeup_status {
+ wakeup_none,
+ wakeup_by_send,
+ wakeup_by_yield,
+ wakeup_by_take,
+ wakeup_by_close,
+ wakeup_by_interrupt,
+ wakeup_by_retry,
+ } wakeup_status;
+
+ struct rb_ractor_basket yielded_basket;
+ struct rb_ractor_basket taken_basket;
+ } wait;
+};
+
+struct rb_ractor_struct {
+ struct rb_ractor_pub pub;
+
+ struct rb_ractor_sync sync;
+ VALUE receiving_mutex;
+ bool yield_atexit;
+
+ // vm wide barrier synchronization
+ rb_nativethread_cond_t barrier_wait_cond;
+
+ // thread management
+ struct {
+ struct list_head set;
+ unsigned int cnt;
+ unsigned int blocking_cnt;
+ unsigned int sleeper;
+ rb_global_vm_lock_t gvl;
+ rb_execution_context_t *running_ec;
+ rb_thread_t *main;
+ } threads;
+ VALUE thgroup_default;
+
+ VALUE name;
+ VALUE loc;
+
+ // created
+ // | ready to run
+ // ====================== inserted to vm->ractor
+ // v
+ // blocking <---+ all threads are blocking
+ // | |
+ // v |
+ // running -----+
+ // | all threads are terminated.
+ // ====================== removed from vm->ractor
+ // v
+ // terminated
+ //
+ // status is protected by VM lock (global state)
+
+ enum ractor_status {
+ ractor_created,
+ ractor_running,
+ ractor_blocking,
+ ractor_terminated,
+ } status_;
+
+ struct list_node vmlr_node;
+
+ // ractor local data
+
+ st_table *local_storage;
+ struct rb_id_table *idkey_local_storage;
+
+ VALUE r_stdin;
+ VALUE r_stdout;
+ VALUE r_stderr;
+ VALUE verbose;
+ VALUE debug;
+
+ rb_ractor_newobj_cache_t newobj_cache;
+
+ // gc.c rb_objspace_reachable_objects_from
+ struct gc_mark_func_data_struct {
+ void *data;
+ void (*mark_func)(VALUE v, void *data);
+ } *mfd;
+}; // rb_ractor_t is defined in vm_core.h
+
+
+static inline VALUE
+rb_ractor_self(const rb_ractor_t *r)
+{
+ return r->pub.self;
+}
+
+rb_ractor_t *rb_ractor_main_alloc(void);
+void rb_ractor_main_setup(rb_vm_t *vm, rb_ractor_t *main_ractor, rb_thread_t *main_thread);
+void rb_ractor_atexit(rb_execution_context_t *ec, VALUE result);
+void rb_ractor_atexit_exception(rb_execution_context_t *ec);
+void rb_ractor_teardown(rb_execution_context_t *ec);
+void rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *g, int len, VALUE *ptr);
+void rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *g, VALUE args);
+
+VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc); // defined in thread.c
+
+rb_global_vm_lock_t *rb_ractor_gvl(rb_ractor_t *);
+int rb_ractor_living_thread_num(const rb_ractor_t *);
+VALUE rb_ractor_thread_list(rb_ractor_t *r);
+
+void rb_ractor_living_threads_init(rb_ractor_t *r);
+void rb_ractor_living_threads_insert(rb_ractor_t *r, rb_thread_t *th);
+void rb_ractor_living_threads_remove(rb_ractor_t *r, rb_thread_t *th);
+void rb_ractor_blocking_threads_inc(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG
+void rb_ractor_blocking_threads_dec(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG
+
+void rb_ractor_vm_barrier_interrupt_running_thread(rb_ractor_t *r);
+void rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r);
+void rb_ractor_terminate_all(void);
+bool rb_ractor_main_p_(void);
+void rb_ractor_finish_marking(void);
+void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th);
+
+VALUE rb_ractor_ensure_shareable(VALUE obj, VALUE name);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+bool rb_ractor_shareable_p_continue(VALUE obj);
+
+// THIS FUNCTION SHOULD NOT CALL WHILE INCREMENTAL MARKING!!
+// This function is for T_DATA::free_func
+void rb_ractor_local_storage_delkey(rb_ractor_local_key_t key);
+
+RUBY_SYMBOL_EXPORT_END
+
+static inline bool
+rb_ractor_main_p(void)
+{
+ if (ruby_single_main_ractor) {
+ return true;
+ }
+ else {
+ return rb_ractor_main_p_();
+ }
+}
+
+static inline bool
+rb_ractor_status_p(rb_ractor_t *r, enum ractor_status status)
+{
+ return r->status_ == status;
+}
+
+static inline void
+rb_ractor_sleeper_threads_inc(rb_ractor_t *r)
+{
+ r->threads.sleeper++;
+}
+
+static inline void
+rb_ractor_sleeper_threads_dec(rb_ractor_t *r)
+{
+ r->threads.sleeper--;
+}
+
+static inline void
+rb_ractor_sleeper_threads_clear(rb_ractor_t *r)
+{
+ r->threads.sleeper = 0;
+}
+
+static inline int
+rb_ractor_sleeper_thread_num(rb_ractor_t *r)
+{
+ return r->threads.sleeper;
+}
+
+static inline void
+rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th)
+{
+ if (cr->threads.running_ec != th->ec) {
+ if (0) fprintf(stderr, "rb_ractor_thread_switch ec:%p->%p\n",
+ (void *)cr->threads.running_ec, (void *)th->ec);
+ }
+ else {
+ return;
+ }
+
+ if (cr->threads.running_ec != th->ec) {
+ th->running_time_us = 0;
+ }
+
+ cr->threads.running_ec = th->ec;
+
+ VM_ASSERT(cr == GET_RACTOR());
+}
+
+static inline void
+rb_ractor_set_current_ec(rb_ractor_t *cr, rb_execution_context_t *ec)
+{
+#ifdef RB_THREAD_LOCAL_SPECIFIER
+ #if __APPLE__
+ rb_current_ec_set(ec);
+ #else
+ ruby_current_ec = ec;
+ #endif
+#else
+ native_tls_set(ruby_current_ec_key, ec);
+#endif
+
+ if (cr->threads.running_ec != ec) {
+ if (0) fprintf(stderr, "rb_ractor_set_current_ec ec:%p->%p\n",
+ (void *)cr->threads.running_ec, (void *)ec);
+ }
+ else {
+ VM_ASSERT(0); // should be different
+ }
+
+ cr->threads.running_ec = ec;
+}
+
+void rb_vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
+void rb_vm_ractor_blocking_cnt_dec(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
+
+static inline uint32_t
+rb_ractor_id(const rb_ractor_t *r)
+{
+ return r->pub.id;
+}
+
+#if RACTOR_CHECK_MODE > 0
+uint32_t rb_ractor_current_id(void);
+
+static inline void
+rb_ractor_setup_belonging_to(VALUE obj, uint32_t rid)
+{
+ VALUE flags = RBASIC(obj)->flags & 0xffffffff; // 4B
+ RBASIC(obj)->flags = flags | ((VALUE)rid << 32);
+}
+
+static inline void
+rb_ractor_setup_belonging(VALUE obj)
+{
+ rb_ractor_setup_belonging_to(obj, rb_ractor_current_id());
+}
+
+static inline uint32_t
+rb_ractor_belonging(VALUE obj)
+{
+ if (SPECIAL_CONST_P(obj) || RB_OBJ_SHAREABLE_P(obj)) {
+ return 0;
+ }
+ else {
+ return RBASIC(obj)->flags >> 32;
+ }
+}
+
+static inline VALUE
+rb_ractor_confirm_belonging(VALUE obj)
+{
+ uint32_t id = rb_ractor_belonging(obj);
+
+ if (id == 0) {
+ if (UNLIKELY(!rb_ractor_shareable_p(obj))) {
+ rp(obj);
+ rb_bug("id == 0 but not shareable");
+ }
+ }
+ else if (UNLIKELY(id != rb_ractor_current_id())) {
+ if (rb_ractor_shareable_p(obj)) {
+ // ok
+ }
+ else {
+ rp(obj);
+ rb_bug("rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u", id, rb_ractor_current_id());
+ }
+ }
+ return obj;
+}
+#else
+#define rb_ractor_confirm_belonging(obj) obj
+#endif
diff --git a/random.c b/random.c
index 95163d172b..4d70c17116 100644
--- a/random.c
+++ b/random.c
@@ -9,193 +9,70 @@
**********************************************************************/
-/*
-This is based on trimmed version of MT19937. To get the original version,
-contact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.
-
-The original copyright notice follows.
-
- A C-program for MT19937, with initialization improved 2002/2/10.
- Coded by Takuji Nishimura and Makoto Matsumoto.
- This is a faster version by taking Shawn Cokus's optimization,
- Matthe Bellew's simplification, Isaku Wada's real version.
-
- Before using, initialize the state by using init_genrand(mt, seed)
- or init_by_array(mt, init_key, key_length).
-
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. The names of its contributors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
- Any feedback is very welcome.
- http://www.math.keio.ac.jp/matumoto/emt.html
- email: matumoto@math.keio.ac.jp
-*/
-
-#include "internal.h"
+#include "ruby/internal/config.h"
+#include <errno.h>
#include <limits.h>
+#include <math.h>
+#include <float.h>
+#include <time.h>
+
#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+# include <unistd.h>
#endif
-#include <time.h>
+
#include <sys/types.h>
#include <sys/stat.h>
+
#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
+# include <fcntl.h>
#endif
-#include <math.h>
-#include <errno.h>
+
#if defined(HAVE_SYS_TIME_H)
-#include <sys/time.h>
+# include <sys/time.h>
#endif
#ifdef HAVE_SYSCALL_H
-#include <syscall.h>
+# include <syscall.h>
#elif defined HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
+# include <sys/syscall.h>
#endif
#ifdef _WIN32
-#include <windows.h>
-#include <wincrypt.h>
+# include <winsock2.h>
+# include <windows.h>
+# include <wincrypt.h>
#endif
-#include "ruby_atomic.h"
-
-typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
-
-/* Period parameters */
-#define N 624
-#define M 397
-#define MATRIX_A 0x9908b0dfU /* constant vector a */
-#define UMASK 0x80000000U /* most significant w-r bits */
-#define LMASK 0x7fffffffU /* least significant r bits */
-#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
-#define TWIST(u,v) ((MIXBITS((u),(v)) >> 1) ^ ((v)&1U ? MATRIX_A : 0U))
-
-enum {MT_MAX_STATE = N};
-
-struct MT {
- /* assume int is enough to store 32bits */
- uint32_t state[N]; /* the array for the state vector */
- uint32_t *next;
- int left;
-};
-
-#define genrand_initialized(mt) ((mt)->next != 0)
-#define uninit_genrand(mt) ((mt)->next = 0)
-
-/* initializes state[N] with a seed */
-static void
-init_genrand(struct MT *mt, unsigned int s)
-{
- int j;
- mt->state[0] = s & 0xffffffffU;
- for (j=1; j<N; j++) {
- mt->state[j] = (1812433253U * (mt->state[j-1] ^ (mt->state[j-1] >> 30)) + j);
- /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- /* In the previous versions, MSBs of the seed affect */
- /* only MSBs of the array state[]. */
- /* 2002/01/09 modified by Makoto Matsumoto */
- mt->state[j] &= 0xffffffff; /* for >32 bit machines */
- }
- mt->left = 1;
- mt->next = mt->state + N;
-}
-
-/* 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 */
-static void
-init_by_array(struct MT *mt, const uint32_t init_key[], int key_length)
-{
- int i, j, k;
- init_genrand(mt, 19650218U);
- i=1; j=0;
- k = (N>key_length ? N : key_length);
- for (; k; k--) {
- mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1664525U))
- + init_key[j] + j; /* non linear */
- mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
- i++; j++;
- if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
- if (j>=key_length) j=0;
- }
- for (k=N-1; k; k--) {
- mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1566083941U))
- - i; /* non linear */
- mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
- i++;
- if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
- }
-
- mt->state[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
-}
-
-static void
-next_state(struct MT *mt)
-{
- uint32_t *p = mt->state;
- int j;
- mt->left = N;
- mt->next = mt->state;
-
- for (j=N-M+1; --j; p++)
- *p = p[M] ^ TWIST(p[0], p[1]);
-
- for (j=M; --j; p++)
- *p = p[M-N] ^ TWIST(p[0], p[1]);
+#ifdef __OpenBSD__
+/* to define OpenBSD for version check */
+# include <sys/param.h>
+#endif
- *p = p[M-N] ^ TWIST(p[0], mt->state[0]);
-}
+#if defined HAVE_GETRANDOM
+# include <sys/random.h>
+#elif defined __linux__ && defined __NR_getrandom
+# include <linux/random.h>
+#endif
-/* generates a random number on [0,0xffffffff]-interval */
-static unsigned int
-genrand_int32(struct MT *mt)
-{
- /* mt must be initialized */
- unsigned int y;
+#if defined __APPLE__
+# include <AvailabilityMacros.h>
+#endif
- if (--mt->left <= 0) next_state(mt);
- y = *mt->next++;
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/compilers.h"
+#include "internal/numeric.h"
+#include "internal/random.h"
+#include "internal/sanitizers.h"
+#include "internal/variable.h"
+#include "ruby_atomic.h"
+#include "ruby/random.h"
+#include "ruby/ractor.h"
- /* Tempering */
- y ^= (y >> 11);
- y ^= (y << 7) & 0x9d2c5680;
- y ^= (y << 15) & 0xefc60000;
- y ^= (y >> 18);
+typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
- return y;
-}
+#include "missing/mt19937.c"
/* generates a random number on [0,1) with 53-bit resolution*/
static double int_pair_to_real_exclusive(uint32_t a, uint32_t b);
@@ -207,12 +84,22 @@ genrand_real(struct MT *mt)
return int_pair_to_real_exclusive(a, b);
}
+static const double dbl_reduce_scale = /* 2**(-DBL_MANT_DIG) */
+ (1.0
+ / (double)(DBL_MANT_DIG > 2*31 ? (1ul<<31) : 1.0)
+ / (double)(DBL_MANT_DIG > 1*31 ? (1ul<<31) : 1.0)
+ / (double)(1ul<<(DBL_MANT_DIG%31)));
+
static double
int_pair_to_real_exclusive(uint32_t a, uint32_t b)
{
- a >>= 5;
- b >>= 6;
- return(a*67108864.0+b)*(1.0/9007199254740992.0);
+ static const int a_shift = DBL_MANT_DIG < 64 ?
+ (64-DBL_MANT_DIG)/2 : 0;
+ static const int b_shift = DBL_MANT_DIG < 64 ?
+ (65-DBL_MANT_DIG)/2 : 0;
+ a >>= a_shift;
+ b >>= b_shift;
+ return (a*(double)(1ul<<(32-b_shift))+b)*dbl_reduce_scale;
}
/* generates a random number on [0,1] with 53-bit resolution*/
@@ -233,44 +120,82 @@ genrand_real2(struct MT *mt)
#undef M
typedef struct {
- VALUE seed;
+ rb_random_t base;
struct MT mt;
-} rb_random_t;
+} rb_random_mt_t;
#define DEFAULT_SEED_CNT 4
-static rb_random_t default_rand;
+static VALUE rand_init(const rb_random_interface_t *, rb_random_t *, VALUE);
+static VALUE random_seed(VALUE);
+static void fill_random_seed(uint32_t *seed, size_t cnt);
+static VALUE make_seed_value(uint32_t *ptr, size_t len);
-static VALUE rand_init(struct MT *mt, VALUE vseed);
-static VALUE random_seed(void);
+RB_RANDOM_INTERFACE_DECLARE(rand_mt);
+static const rb_random_interface_t random_mt_if = {
+ DEFAULT_SEED_CNT * 32,
+ RB_RANDOM_INTERFACE_DEFINE(rand_mt)
+};
-static rb_random_t *
-rand_start(rb_random_t *r)
+static rb_random_mt_t *
+rand_mt_start(rb_random_mt_t *r)
{
- struct MT *mt = &r->mt;
- if (!genrand_initialized(mt)) {
- r->seed = rand_init(mt, random_seed());
+ if (!genrand_initialized(&r->mt)) {
+ r->base.seed = rand_init(&random_mt_if, &r->base, random_seed(Qundef));
}
return r;
}
-static struct MT *
+static rb_random_t *
+rand_start(rb_random_mt_t *r)
+{
+ return &rand_mt_start(r)->base;
+}
+
+static rb_ractor_local_key_t default_rand_key;
+
+static void
+default_rand_mark(void *ptr)
+{
+ rb_random_mt_t *rnd = (rb_random_mt_t *)ptr;
+ rb_gc_mark(rnd->base.seed);
+}
+
+static const struct rb_ractor_local_storage_type default_rand_key_storage_type = {
+ default_rand_mark,
+ ruby_xfree,
+};
+
+static rb_random_mt_t *
+default_rand(void)
+{
+ rb_random_mt_t *rnd;
+
+ if ((rnd = rb_ractor_local_storage_ptr(default_rand_key)) == NULL) {
+ rnd = ZALLOC(rb_random_mt_t);
+ rb_ractor_local_storage_ptr_set(default_rand_key, rnd);
+ }
+
+ return rnd;
+}
+
+static rb_random_mt_t *
default_mt(void)
{
- return &rand_start(&default_rand)->mt;
+ return rand_mt_start(default_rand());
}
unsigned int
rb_genrand_int32(void)
{
- struct MT *mt = default_mt();
+ struct MT *mt = &default_mt()->mt;
return genrand_int32(mt);
}
double
rb_genrand_real(void)
{
- struct MT *mt = default_mt();
+ struct MT *mt = &default_mt()->mt;
return genrand_real(mt);
}
@@ -280,13 +205,13 @@ static double
int_pair_to_real_inclusive(uint32_t a, uint32_t b)
{
double r;
- enum {dig = 53};
+ enum {dig = DBL_MANT_DIG};
enum {dig_u = dig-32, dig_r64 = 64-dig, bmask = ~(~0u<<(dig_r64))};
#if defined HAVE_UINT128_T
const uint128_t m = ((uint128_t)1 << dig) | 1;
uint128_t x = ((uint128_t)a << 32) | b;
r = (double)(uint64_t)((x * m) >> 64);
-#elif defined HAVE_UINT64_T && !(defined _MSC_VER && _MSC_VER <= 1200)
+#elif defined HAVE_UINT64_T && !MSC_VERSION_BEFORE(1300)
uint64_t x = ((uint64_t)a << dig_u) +
(((uint64_t)b + (a >> dig_u)) >> dig_r64);
r = (double)x;
@@ -295,27 +220,25 @@ int_pair_to_real_inclusive(uint32_t a, uint32_t b)
b = (b >> dig_r64) + (((a >> dig_u) + (b & bmask)) >> dig_r64);
r = (double)a * (1 << dig_u) + b;
#endif
- return ldexp(r, -dig);
+ return r * dbl_reduce_scale;
}
VALUE rb_cRandom;
#define id_minus '-'
#define id_plus '+'
static ID id_rand, id_bytes;
+NORETURN(static void domain_error(void));
/* :nodoc: */
-static void
+#define random_mark rb_random_mark
+
+void
random_mark(void *ptr)
{
rb_gc_mark(((rb_random_t *)ptr)->seed);
}
-static void
-random_free(void *ptr)
-{
- if (ptr != &default_rand)
- xfree(ptr);
-}
+#define random_free RUBY_TYPED_DEFAULT_FREE
static size_t
random_memsize(const void *ptr)
@@ -323,7 +246,7 @@ random_memsize(const void *ptr)
return sizeof(rb_random_t);
}
-static const rb_data_type_t random_data_type = {
+const rb_data_type_t rb_random_data_type = {
"random",
{
random_mark,
@@ -333,62 +256,132 @@ static const rb_data_type_t random_data_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
+#define random_mt_mark rb_random_mark
+
+static void
+random_mt_free(void *ptr)
+{
+ rb_random_mt_t *rnd = rb_ractor_local_storage_ptr(default_rand_key);
+ if (ptr != rnd)
+ xfree(ptr);
+}
+
+static size_t
+random_mt_memsize(const void *ptr)
+{
+ return sizeof(rb_random_mt_t);
+}
+
+static const rb_data_type_t random_mt_type = {
+ "random/MT",
+ {
+ random_mt_mark,
+ random_mt_free,
+ random_mt_memsize,
+ },
+ &rb_random_data_type,
+ (void *)&random_mt_if,
+ RUBY_TYPED_FREE_IMMEDIATELY
+};
+
static rb_random_t *
get_rnd(VALUE obj)
{
rb_random_t *ptr;
- TypedData_Get_Struct(obj, rb_random_t, &random_data_type, ptr);
- return rand_start(ptr);
+ TypedData_Get_Struct(obj, rb_random_t, &rb_random_data_type, ptr);
+ if (RTYPEDDATA_TYPE(obj) == &random_mt_type)
+ return rand_start((rb_random_mt_t *)ptr);
+ return ptr;
+}
+
+static rb_random_mt_t *
+get_rnd_mt(VALUE obj)
+{
+ rb_random_mt_t *ptr;
+ TypedData_Get_Struct(obj, rb_random_mt_t, &random_mt_type, ptr);
+ return ptr;
}
static rb_random_t *
try_get_rnd(VALUE obj)
{
if (obj == rb_cRandom) {
- return rand_start(&default_rand);
+ return rand_start(default_rand());
+ }
+ if (!rb_typeddata_is_kind_of(obj, &rb_random_data_type)) return NULL;
+ if (RTYPEDDATA_TYPE(obj) == &random_mt_type)
+ return rand_start(DATA_PTR(obj));
+ rb_random_t *rnd = DATA_PTR(obj);
+ if (!rnd) {
+ rb_raise(rb_eArgError, "uninitialized random: %s",
+ RTYPEDDATA_TYPE(obj)->wrap_struct_name);
+ }
+ return rnd;
+}
+
+static const rb_random_interface_t *
+try_rand_if(VALUE obj, rb_random_t *rnd)
+{
+ if (rnd == &default_rand()->base) {
+ return &random_mt_if;
}
- if (!rb_typeddata_is_kind_of(obj, &random_data_type)) return NULL;
- return rand_start(DATA_PTR(obj));
+ return rb_rand_if(obj);
+}
+
+/* :nodoc: */
+void
+rb_random_base_init(rb_random_t *rnd)
+{
+ rnd->seed = INT2FIX(0);
}
/* :nodoc: */
static VALUE
random_alloc(VALUE klass)
{
- rb_random_t *rnd;
- VALUE obj = TypedData_Make_Struct(klass, rb_random_t, &random_data_type, rnd);
- rnd->seed = INT2FIX(0);
+ rb_random_mt_t *rnd;
+ VALUE obj = TypedData_Make_Struct(klass, rb_random_mt_t, &random_mt_type, rnd);
+ rb_random_base_init(&rnd->base);
return obj;
}
static VALUE
-rand_init(struct MT *mt, VALUE seed)
+rand_init_default(const rb_random_interface_t *rng, rb_random_t *rnd)
{
- uint32_t buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;
+ VALUE seed, buf0 = 0;
+ size_t len = roomof(rng->default_seed_bits, 32);
+ uint32_t *buf = ALLOCV_N(uint32_t, buf0, len+1);
+
+ fill_random_seed(buf, len);
+ rng->init(rnd, buf, len);
+ seed = make_seed_value(buf, len);
+ explicit_bzero(buf, len * sizeof(*buf));
+ ALLOCV_END(buf0);
+ return seed;
+}
+
+static VALUE
+rand_init(const rb_random_interface_t *rng, rb_random_t *rnd, VALUE seed)
+{
+ uint32_t *buf;
+ VALUE buf0 = 0;
size_t len;
int sign;
len = rb_absint_numwords(seed, 32, NULL);
- if (len > numberof(buf0))
- buf = ALLOC_N(uint32_t, len);
+ if (len == 0) len = 1;
+ buf = ALLOCV_N(uint32_t, buf0, len);
sign = rb_integer_pack(seed, buf, len, sizeof(uint32_t), 0,
INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
if (sign < 0)
sign = -sign;
- if (len == 0) {
- buf[0] = 0;
- len = 1;
- }
- if (len <= 1) {
- init_genrand(mt, buf[0]);
- }
- else {
+ if (len > 1) {
if (sign != 2 && buf[len-1] == 1) /* remove leading-zero-guard */
len--;
- init_by_array(mt, buf, (int)len);
}
+ rng->init(rnd, buf, len);
explicit_bzero(buf, len * sizeof(*buf));
- if (buf != buf0) xfree(buf);
+ ALLOCV_END(buf0);
return seed;
}
@@ -404,19 +397,21 @@ rand_init(struct MT *mt, VALUE seed)
static VALUE
random_init(int argc, VALUE *argv, VALUE obj)
{
- VALUE vseed;
- rb_random_t *rnd = get_rnd(obj);
+ rb_random_t *rnd = try_get_rnd(obj);
+ const rb_random_interface_t *rng = rb_rand_if(obj);
- if (rb_check_arity(argc, 0, 1) == 0) {
- rb_check_frozen(obj);
- vseed = random_seed();
+ if (!rng) {
+ rb_raise(rb_eTypeError, "undefined random interface: %s",
+ RTYPEDDATA_TYPE(obj)->wrap_struct_name);
+ }
+ argc = rb_check_arity(argc, 0, 1);
+ rb_check_frozen(obj);
+ if (argc == 0) {
+ rnd->seed = rand_init_default(rng, rnd);
}
else {
- vseed = argv[0];
- rb_check_copyable(obj, vseed);
- vseed = rb_to_int(vseed);
+ rnd->seed = rand_init(rng, rnd, rb_to_int(argv[0]));
}
- rnd->seed = rand_init(&rnd->mt, vseed);
return obj;
}
@@ -447,27 +442,69 @@ fill_random_bytes_urandom(void *seed, size_t size)
O_RDONLY, 0);
struct stat statbuf;
ssize_t ret = 0;
+ size_t offset = 0;
if (fd < 0) return -1;
rb_update_max_fd(fd);
if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
- ret = read(fd, seed, size);
+ do {
+ ret = read(fd, ((char*)seed) + offset, size - offset);
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+ offset += (size_t)ret;
+ } while (offset < size);
}
close(fd);
- if (ret < 0 || (size_t)ret < size) return -1;
return 0;
}
#else
# define fill_random_bytes_urandom(seed, size) -1
#endif
+#if ! defined HAVE_GETRANDOM && defined __linux__ && defined __NR_getrandom
+# ifndef GRND_NONBLOCK
+# define GRND_NONBLOCK 0x0001 /* not defined in musl libc */
+# endif
+# define getrandom(ptr, size, flags) \
+ (ssize_t)syscall(__NR_getrandom, (ptr), (size), (flags))
+# define HAVE_GETRANDOM 1
+#endif
+
#if 0
+#elif defined MAC_OS_X_VERSION_10_7 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
+#include <Security/Security.h>
+
+static int
+fill_random_bytes_syscall(void *seed, size_t size, int unused)
+{
+ int status = SecRandomCopyBytes(kSecRandomDefault, size, seed);
+
+ if (status != errSecSuccess) {
+# if 0
+ CFStringRef s = SecCopyErrorMessageString(status, NULL);
+ const char *m = s ? CFStringGetCStringPtr(s, kCFStringEncodingUTF8) : NULL;
+ fprintf(stderr, "SecRandomCopyBytes failed: %d: %s\n", status,
+ m ? m : "unknown");
+ if (s) CFRelease(s);
+# endif
+ return -1;
+ }
+ return 0;
+}
#elif defined(HAVE_ARC4RANDOM_BUF)
static int
fill_random_bytes_syscall(void *buf, size_t size, int unused)
{
+#if (defined(__OpenBSD__) && OpenBSD >= 201411) || \
+ (defined(__NetBSD__) && __NetBSD_Version__ >= 700000000) || \
+ (defined(__FreeBSD__) && __FreeBSD_version >= 1200079)
arc4random_buf(buf, size);
return 0;
+#else
+ return -1;
+#endif
}
#elif defined(_WIN32)
static void
@@ -489,12 +526,14 @@ fill_random_bytes_syscall(void *seed, size_t size, int unused)
prov = (HCRYPTPROV)INVALID_HANDLE_VALUE;
}
old_prov = (HCRYPTPROV)ATOMIC_PTR_CAS(perm_prov, 0, prov);
- if (LIKELY(!old_prov)) { /* no other threads acquried */
+ if (LIKELY(!old_prov)) { /* no other threads acquired */
if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
+#undef RUBY_UNTYPED_DATA_WARNING
+#define RUBY_UNTYPED_DATA_WARNING 0
rb_gc_register_mark_object(Data_Wrap_Struct(0, 0, release_crypt, &perm_prov));
}
}
- else { /* another thread acquried */
+ else { /* another thread acquired */
if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
CryptReleaseContext(prov, 0);
}
@@ -505,29 +544,26 @@ fill_random_bytes_syscall(void *seed, size_t size, int unused)
CryptGenRandom(prov, size, seed);
return 0;
}
-#elif defined __linux__ && defined __NR_getrandom
-#include <linux/random.h>
-
-# ifndef GRND_NONBLOCK
-# define GRND_NONBLOCK 0x0001 /* not defined in musl libc */
-# endif
-
+#elif defined HAVE_GETRANDOM
static int
fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
{
static rb_atomic_t try_syscall = 1;
if (try_syscall) {
- long ret;
+ size_t offset = 0;
int flags = 0;
if (!need_secure)
flags = GRND_NONBLOCK;
- errno = 0;
- ret = syscall(__NR_getrandom, seed, size, flags);
- if (errno == ENOSYS) {
- ATOMIC_SET(try_syscall, 0);
- return -1;
- }
- if ((size_t)ret == size) return 0;
+ do {
+ errno = 0;
+ ssize_t ret = getrandom(((char*)seed) + offset, size - offset, flags);
+ if (ret == -1) {
+ ATOMIC_SET(try_syscall, 0);
+ return -1;
+ }
+ offset += (size_t)ret;
+ } while (offset < size);
+ return 0;
}
return -1;
}
@@ -535,27 +571,39 @@ fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
# define fill_random_bytes_syscall(seed, size, need_secure) -1
#endif
-static int
-fill_random_bytes(void *seed, size_t size, int need_secure)
+int
+ruby_fill_random_bytes(void *seed, size_t size, int need_secure)
{
int ret = fill_random_bytes_syscall(seed, size, need_secure);
if (ret == 0) return ret;
return fill_random_bytes_urandom(seed, size);
}
+#define fill_random_bytes ruby_fill_random_bytes
+
+/* cnt must be 4 or more */
static void
fill_random_seed(uint32_t *seed, size_t cnt)
{
static int n = 0;
+#if defined HAVE_CLOCK_GETTIME
+ struct timespec tv;
+#elif defined HAVE_GETTIMEOFDAY
struct timeval tv;
+#endif
size_t len = cnt * sizeof(*seed);
memset(seed, 0, len);
- fill_random_bytes(seed, len, TRUE);
+ fill_random_bytes(seed, len, FALSE);
+#if defined HAVE_CLOCK_GETTIME
+ clock_gettime(CLOCK_REALTIME, &tv);
+ seed[0] ^= tv.tv_nsec;
+#elif defined HAVE_GETTIMEOFDAY
gettimeofday(&tv, 0);
seed[0] ^= tv.tv_usec;
+#endif
seed[1] ^= (uint32_t)tv.tv_sec;
#if SIZEOF_TIME_T > SIZEOF_INT
seed[0] ^= (uint32_t)((time_t)tv.tv_sec >> SIZEOF_INT * CHAR_BIT);
@@ -583,6 +631,10 @@ make_seed_value(uint32_t *ptr, size_t len)
return seed;
}
+#define with_random_seed(size, add) \
+ for (uint32_t seedbuf[(size)+(add)], loop = (fill_random_seed(seedbuf, (size)), 1); \
+ loop; explicit_bzero(seedbuf, (size)*sizeof(seedbuf[0])), loop = 0)
+
/*
* call-seq: Random.new_seed -> integer
*
@@ -592,13 +644,12 @@ make_seed_value(uint32_t *ptr, size_t len)
* Random.new_seed #=> 115032730400174366788466674494640623225
*/
static VALUE
-random_seed(void)
+random_seed(VALUE _)
{
VALUE v;
- uint32_t buf[DEFAULT_SEED_CNT+1];
- fill_random_seed(buf, DEFAULT_SEED_CNT);
- v = make_seed_value(buf, DEFAULT_SEED_CNT);
- explicit_bzero(buf, DEFAULT_SEED_LEN);
+ with_random_seed(DEFAULT_SEED_CNT, 1) {
+ v = make_seed_value(seedbuf, DEFAULT_SEED_CNT);
+ }
return v;
}
@@ -624,7 +675,7 @@ random_raw_seed(VALUE self, VALUE size)
long n = NUM2ULONG(size);
VALUE buf = rb_str_new(0, n);
if (n == 0) return buf;
- if (fill_random_bytes(RSTRING_PTR(buf), n, FALSE))
+ if (fill_random_bytes(RSTRING_PTR(buf), n, TRUE))
rb_raise(rb_eRuntimeError, "failed to get urandom");
return buf;
}
@@ -651,15 +702,15 @@ random_get_seed(VALUE obj)
/* :nodoc: */
static VALUE
-random_copy(VALUE obj, VALUE orig)
+rand_mt_copy(VALUE obj, VALUE orig)
{
- rb_random_t *rnd1, *rnd2;
+ rb_random_mt_t *rnd1, *rnd2;
struct MT *mt;
if (!OBJ_INIT_COPY(obj, orig)) return obj;
- rnd1 = get_rnd(obj);
- rnd2 = get_rnd(orig);
+ rnd1 = get_rnd_mt(obj);
+ rnd2 = get_rnd_mt(orig);
mt = &rnd1->mt;
*rnd1 = *rnd2;
@@ -677,9 +728,9 @@ mt_state(const struct MT *mt)
/* :nodoc: */
static VALUE
-random_state(VALUE obj)
+rand_mt_state(VALUE obj)
{
- rb_random_t *rnd = get_rnd(obj);
+ rb_random_mt_t *rnd = get_rnd_mt(obj);
return mt_state(&rnd->mt);
}
@@ -687,14 +738,14 @@ random_state(VALUE obj)
static VALUE
random_s_state(VALUE klass)
{
- return mt_state(&default_rand.mt);
+ return mt_state(&default_rand()->mt);
}
/* :nodoc: */
static VALUE
-random_left(VALUE obj)
+rand_mt_left(VALUE obj)
{
- rb_random_t *rnd = get_rnd(obj);
+ rb_random_mt_t *rnd = get_rnd_mt(obj);
return INT2FIX(rnd->mt.left);
}
@@ -702,43 +753,41 @@ random_left(VALUE obj)
static VALUE
random_s_left(VALUE klass)
{
- return INT2FIX(default_rand.mt.left);
+ return INT2FIX(default_rand()->mt.left);
}
/* :nodoc: */
static VALUE
-random_dump(VALUE obj)
+rand_mt_dump(VALUE obj)
{
- rb_random_t *rnd = get_rnd(obj);
+ rb_random_mt_t *rnd = rb_check_typeddata(obj, &random_mt_type);
VALUE dump = rb_ary_new2(3);
rb_ary_push(dump, mt_state(&rnd->mt));
rb_ary_push(dump, INT2FIX(rnd->mt.left));
- rb_ary_push(dump, rnd->seed);
+ rb_ary_push(dump, rnd->base.seed);
return dump;
}
/* :nodoc: */
static VALUE
-random_load(VALUE obj, VALUE dump)
+rand_mt_load(VALUE obj, VALUE dump)
{
- rb_random_t *rnd = get_rnd(obj);
+ rb_random_mt_t *rnd = rb_check_typeddata(obj, &random_mt_type);
struct MT *mt = &rnd->mt;
VALUE state, left = INT2FIX(1), seed = INT2FIX(0);
- const VALUE *ary;
unsigned long x;
rb_check_copyable(obj, dump);
Check_Type(dump, T_ARRAY);
- ary = RARRAY_CONST_PTR(dump);
switch (RARRAY_LEN(dump)) {
case 3:
- seed = ary[2];
+ seed = RARRAY_AREF(dump, 2);
case 2:
- left = ary[1];
+ left = RARRAY_AREF(dump, 1);
case 1:
- state = ary[0];
+ state = RARRAY_AREF(dump, 0);
break;
default:
rb_raise(rb_eArgError, "wrong dump data");
@@ -752,17 +801,42 @@ random_load(VALUE obj, VALUE dump)
}
mt->left = (unsigned int)x;
mt->next = mt->state + numberof(mt->state) - x + 1;
- rnd->seed = rb_to_int(seed);
+ rnd->base.seed = rb_to_int(seed);
return obj;
}
+static void
+rand_mt_init(rb_random_t *rnd, const uint32_t *buf, size_t len)
+{
+ struct MT *mt = &((rb_random_mt_t *)rnd)->mt;
+ if (len <= 1) {
+ init_genrand(mt, len ? buf[0] : 0);
+ }
+ else {
+ init_by_array(mt, buf, (int)len);
+ }
+}
+
+static unsigned int
+rand_mt_get_int32(rb_random_t *rnd)
+{
+ struct MT *mt = &((rb_random_mt_t *)rnd)->mt;
+ return genrand_int32(mt);
+}
+
+static void
+rand_mt_get_bytes(rb_random_t *rnd, void *ptr, size_t n)
+{
+ rb_rand_bytes_int32(rand_mt_get_int32, rnd, ptr, n);
+}
+
/*
* call-seq:
* srand(number = Random.new_seed) -> old_seed
*
- * Seeds the system pseudo-random number generator, Random::DEFAULT, with
- * +number+. The previous seed value is returned.
+ * Seeds the system pseudo-random number generator, with +number+.
+ * The previous seed value is returned.
*
* If +number+ is omitted, seeds the generator using a source of entropy
* provided by the operating system, if available (/dev/urandom on Unix systems
@@ -784,16 +858,17 @@ static VALUE
rb_f_srand(int argc, VALUE *argv, VALUE obj)
{
VALUE seed, old;
- rb_random_t *r = &default_rand;
+ rb_random_mt_t *r = rand_mt_start(default_rand());
if (rb_check_arity(argc, 0, 1) == 0) {
- seed = random_seed();
+ seed = random_seed(obj);
}
else {
seed = rb_to_int(argv[0]);
}
- old = r->seed;
- r->seed = rand_init(&r->mt, seed);
+ old = r->base.seed;
+ rand_init(&random_mt_if, &r->base, seed);
+ r->base.seed = seed;
return old;
}
@@ -813,7 +888,7 @@ make_mask(unsigned long x)
}
static unsigned long
-limited_rand(struct MT *mt, unsigned long limit)
+limited_rand(const rb_random_interface_t *rng, rb_random_t *rnd, unsigned long limit)
{
/* mt must be initialized */
unsigned long val, mask;
@@ -828,7 +903,7 @@ limited_rand(struct MT *mt, unsigned long limit)
val = 0;
for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
if ((mask >> (i * 32)) & 0xffffffff) {
- val |= (unsigned long)genrand_int32(mt) << (i * 32);
+ val |= (unsigned long)rng->get_int32(rnd) << (i * 32);
val &= mask;
if (limit < val)
goto retry;
@@ -839,13 +914,13 @@ limited_rand(struct MT *mt, unsigned long limit)
#endif
do {
- val = genrand_int32(mt) & mask;
+ val = rng->get_int32(rnd) & mask;
} while (limit < val);
return val;
}
static VALUE
-limited_big_rand(struct MT *mt, VALUE limit)
+limited_big_rand(const rb_random_interface_t *rng, rb_random_t *rnd, VALUE limit)
{
/* mt must be initialized */
@@ -869,22 +944,19 @@ limited_big_rand(struct MT *mt, VALUE limit)
mask = 0;
boundary = 1;
for (i = len-1; 0 <= i; i--) {
- uint32_t rnd;
+ uint32_t r = 0;
uint32_t lim = lim_array[i];
mask = mask ? 0xffffffff : (uint32_t)make_mask(lim);
if (mask) {
- rnd = genrand_int32(mt) & mask;
+ r = rng->get_int32(rnd) & mask;
if (boundary) {
- if (lim < rnd)
+ if (lim < r)
goto retry;
- if (rnd < lim)
+ if (r < lim)
boundary = 0;
}
}
- else {
- rnd = 0;
- }
- rnd_array[i] = rnd;
+ rnd_array[i] = r;
}
val = rb_integer_unpack(rnd_array, len, sizeof(uint32_t), 0,
INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
@@ -902,7 +974,8 @@ limited_big_rand(struct MT *mt, VALUE limit)
unsigned long
rb_genrand_ulong_limited(unsigned long limit)
{
- return limited_rand(default_mt(), limit);
+ rb_random_mt_t *mt = default_mt();
+ return limited_rand(&random_mt_if, &mt->base, limit);
}
static VALUE
@@ -922,9 +995,9 @@ obj_random_bytes(VALUE obj, void *p, long n)
}
static unsigned int
-random_int32(rb_random_t *rnd)
+random_int32(const rb_random_interface_t *rng, rb_random_t *rnd)
{
- return genrand_int32(&rnd->mt);
+ return rng->get_int32(rnd);
}
unsigned int
@@ -936,7 +1009,7 @@ rb_random_int32(VALUE obj)
obj_random_bytes(obj, &x, sizeof(x));
return (unsigned int)x;
}
- return random_int32(rnd);
+ return random_int32(try_rand_if(obj, rnd), rnd);
}
static double
@@ -951,9 +1024,17 @@ random_real(VALUE obj, rb_random_t *rnd, int excl)
b = x[1];
}
else {
- a = random_int32(rnd);
- b = random_int32(rnd);
+ const rb_random_interface_t *rng = try_rand_if(obj, rnd);
+ if (rng->get_real) return rng->get_real(rnd, excl);
+ a = random_int32(rng, rnd);
+ b = random_int32(rng, rnd);
}
+ return rb_int_pair_to_real(a, b, excl);
+}
+
+double
+rb_int_pair_to_real(uint32_t a, uint32_t b, int excl)
+{
if (excl) {
return int_pair_to_real_exclusive(a, b);
}
@@ -977,7 +1058,7 @@ rb_random_real(VALUE obj)
}
return d;
}
- return genrand_real(&rnd->mt);
+ return random_real(obj, rnd, TRUE);
}
static inline VALUE
@@ -1019,7 +1100,7 @@ random_ulong_limited(VALUE obj, rb_random_t *rnd, unsigned long limit)
} while (limit < val);
return val;
}
- return limited_rand(&rnd->mt, limit);
+ return limited_rand(try_rand_if(obj, rnd), rnd, limit);
}
unsigned long
@@ -1038,7 +1119,7 @@ rb_random_ulong_limited(VALUE obj, unsigned long limit)
}
return r;
}
- return limited_rand(&rnd->mt, limit);
+ return limited_rand(try_rand_if(obj, rnd), rnd, limit);
}
static VALUE
@@ -1067,13 +1148,23 @@ random_ulong_limited_big(VALUE obj, rb_random_t *rnd, VALUE vmax)
ALLOCV_END(vtmp);
return v;
}
- return limited_big_rand(&rnd->mt, vmax);
+ return limited_big_rand(try_rand_if(obj, rnd), rnd, vmax);
}
-static VALUE genrand_bytes(rb_random_t *rnd, long n);
+static VALUE
+rand_bytes(const rb_random_interface_t *rng, rb_random_t *rnd, long n)
+{
+ VALUE bytes;
+ char *ptr;
+
+ bytes = rb_str_new(0, n);
+ ptr = RSTRING_PTR(bytes);
+ rb_rand_bytes_int32(rng->get_int32, rnd, ptr, n);
+ return bytes;
+}
/*
- * call-seq: prng.bytes(size) -> a_string
+ * call-seq: prng.bytes(size) -> string
*
* Returns a random binary string containing +size+ bytes.
*
@@ -1083,20 +1174,18 @@ static VALUE genrand_bytes(rb_random_t *rnd, long n);
static VALUE
random_bytes(VALUE obj, VALUE len)
{
- return genrand_bytes(get_rnd(obj), NUM2LONG(rb_to_int(len)));
+ rb_random_t *rnd = try_get_rnd(obj);
+ return rand_bytes(rb_rand_if(obj), rnd, NUM2LONG(rb_to_int(len)));
}
-static VALUE
-genrand_bytes(rb_random_t *rnd, long n)
+void
+rb_rand_bytes_int32(rb_random_get_int32_func *get_int32,
+ rb_random_t *rnd, void *p, size_t n)
{
- VALUE bytes;
- char *ptr;
+ char *ptr = p;
unsigned int r, i;
-
- bytes = rb_str_new(0, n);
- ptr = RSTRING_PTR(bytes);
for (; n >= SIZEOF_INT32; n -= SIZEOF_INT32) {
- r = genrand_int32(&rnd->mt);
+ r = get_int32(rnd);
i = SIZEOF_INT32;
do {
*ptr++ = (char)r;
@@ -1104,13 +1193,12 @@ genrand_bytes(rb_random_t *rnd, long n)
} while (--i);
}
if (n > 0) {
- r = genrand_int32(&rnd->mt);
+ r = get_int32(rnd);
do {
*ptr++ = (char)r;
r >>= CHAR_BIT;
} while (--n);
}
- return bytes;
}
VALUE
@@ -1120,20 +1208,40 @@ rb_random_bytes(VALUE obj, long n)
if (!rnd) {
return obj_random_bytes(obj, NULL, n);
}
- return genrand_bytes(rnd, n);
+ return rand_bytes(try_rand_if(obj, rnd), rnd, n);
+}
+
+/*
+ * call-seq: Random.bytes(size) -> string
+ *
+ * Returns a random binary string.
+ * The argument +size+ specifies the length of the returned string.
+ */
+static VALUE
+random_s_bytes(VALUE obj, VALUE len)
+{
+ rb_random_t *rnd = rand_start(default_rand());
+ return rand_bytes(&random_mt_if, rnd, NUM2LONG(rb_to_int(len)));
+}
+
+static VALUE
+random_s_seed(VALUE obj)
+{
+ rb_random_mt_t *rnd = rand_mt_start(default_rand());
+ return rnd->base.seed;
}
static VALUE
range_values(VALUE vmax, VALUE *begp, VALUE *endp, int *exclp)
{
- VALUE end, r;
+ VALUE beg, end;
- if (!rb_range_values(vmax, begp, &end, exclp)) return Qfalse;
+ if (!rb_range_values(vmax, &beg, &end, exclp)) return Qfalse;
+ if (begp) *begp = beg;
+ if (NIL_P(beg)) return Qnil;
if (endp) *endp = end;
- if (!rb_respond_to(end, id_minus)) return Qfalse;
- r = rb_funcallv(end, id_minus, 1, begp);
- if (NIL_P(r)) return Qfalse;
- return r;
+ if (NIL_P(end)) return Qnil;
+ return rb_check_funcall_default(end, id_minus, 1, begp, Qfalse);
}
static VALUE
@@ -1172,7 +1280,6 @@ rand_int(VALUE obj, rb_random_t *rnd, VALUE vmax, int restrictive)
}
}
-NORETURN(static void domain_error(void));
static void
domain_error(void)
{
@@ -1218,12 +1325,13 @@ rand_range(VALUE obj, rb_random_t* rnd, VALUE range)
if ((v = vmax = range_values(range, &beg, &end, &excl)) == Qfalse)
return Qfalse;
+ if (NIL_P(v)) domain_error();
if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_int(vmax), !NIL_P(v))) {
long max;
vmax = v;
v = Qnil;
+ fixnum:
if (FIXNUM_P(vmax)) {
- fixnum:
if ((max = FIX2LONG(vmax) - excl) >= 0) {
unsigned long r = random_ulong_limited(obj, rnd, (unsigned long)max);
v = ULONG2NUM(r);
@@ -1320,7 +1428,7 @@ static VALUE rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd);
static VALUE
random_rand(int argc, VALUE *argv, VALUE obj)
{
- VALUE v = rand_random(argc, argv, obj, get_rnd(obj));
+ VALUE v = rand_random(argc, argv, obj, try_get_rnd(obj));
check_random_number(v, argv);
return v;
}
@@ -1354,6 +1462,16 @@ rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd)
return rand_range(obj, rnd, vmax);
}
+/*
+ * call-seq:
+ * prng.random_number -> float
+ * prng.random_number(max) -> number
+ * prng.rand -> float
+ * prng.rand(max) -> number
+ *
+ * Generates formatted random number from raw random bytes.
+ * See Random#rand.
+ */
static VALUE
rand_random_number(int argc, VALUE *argv, VALUE obj)
{
@@ -1389,16 +1507,16 @@ rand_random_number(int argc, VALUE *argv, VALUE obj)
* prng1 == prng2 # => true
*/
static VALUE
-random_equal(VALUE self, VALUE other)
+rand_mt_equal(VALUE self, VALUE other)
{
- rb_random_t *r1, *r2;
+ rb_random_mt_t *r1, *r2;
if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
- r1 = get_rnd(self);
- r2 = get_rnd(other);
+ r1 = get_rnd_mt(self);
+ r2 = get_rnd_mt(other);
if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
if (r1->mt.left != r2->mt.left) return Qfalse;
- return rb_equal(r1->seed, r2->seed);
+ return rb_equal(r1->base.seed, r2->base.seed);
}
/*
@@ -1436,32 +1554,30 @@ static VALUE
rb_f_rand(int argc, VALUE *argv, VALUE obj)
{
VALUE vmax;
- rb_random_t *rnd = rand_start(&default_rand);
+ rb_random_t *rnd = rand_start(default_rand());
if (rb_check_arity(argc, 0, 1) && !NIL_P(vmax = argv[0])) {
- VALUE v = rand_range(Qnil, rnd, vmax);
+ VALUE v = rand_range(obj, rnd, vmax);
if (v != Qfalse) return v;
vmax = rb_to_int(vmax);
if (vmax != INT2FIX(0)) {
- v = rand_int(Qnil, rnd, vmax, 0);
+ v = rand_int(obj, rnd, vmax, 0);
if (!NIL_P(v)) return v;
}
}
- return DBL2NUM(genrand_real(&rnd->mt));
+ return DBL2NUM(random_real(obj, rnd, TRUE));
}
/*
* call-seq:
* Random.rand -> float
* Random.rand(max) -> number
- *
- * Alias of Random::DEFAULT.rand.
*/
static VALUE
random_s_rand(int argc, VALUE *argv, VALUE obj)
{
- VALUE v = rand_random(argc, argv, Qnil, rand_start(&default_rand));
+ VALUE v = rand_random(argc, argv, Qnil, rand_start(default_rand()));
check_random_number(v, argv);
return v;
}
@@ -1486,32 +1602,33 @@ random_s_rand(int argc, VALUE *argv, VALUE obj)
typedef struct {
st_index_t hash;
uint8_t sip[16];
-} seed_keys_t;
+} hash_salt_t;
static union {
- seed_keys_t key;
- uint32_t u32[type_roomof(seed_keys_t, uint32_t)];
-} seed;
+ hash_salt_t key;
+ uint32_t u32[type_roomof(hash_salt_t, uint32_t)];
+} hash_salt;
static void
-init_seed(struct MT *mt)
+init_hash_salt(struct MT *mt)
{
int i;
- for (i = 0; i < numberof(seed.u32); ++i)
- seed.u32[i] = genrand_int32(mt);
+ for (i = 0; i < numberof(hash_salt.u32); ++i)
+ hash_salt.u32[i] = genrand_int32(mt);
}
+NO_SANITIZE("unsigned-integer-overflow", extern st_index_t rb_hash_start(st_index_t h));
st_index_t
rb_hash_start(st_index_t h)
{
- return st_hash_start(seed.key.hash + h);
+ return st_hash_start(hash_salt.key.hash + h);
}
st_index_t
rb_memhash(const void *ptr, long len)
{
- sip_uint64_t h = sip_hash13(seed.key.sip, ptr, len);
+ sip_uint64_t h = sip_hash13(hash_salt.key.sip, ptr, len);
#ifdef HAVE_UINT64_T
return (st_index_t)h;
#else
@@ -1524,54 +1641,31 @@ rb_memhash(const void *ptr, long len)
void
Init_RandomSeedCore(void)
{
+ if (!fill_random_bytes(&hash_salt, sizeof(hash_salt), FALSE)) return;
+
/*
- Don't reuse this MT for Random::DEFAULT. Random::DEFAULT::seed shouldn't
+ If failed to fill siphash's salt with random data, expand less random
+ data with MT.
+
+ Don't reuse this MT for default_rand(). default_rand()::seed shouldn't
provide a hint that an attacker guess siphash's seed.
*/
struct MT mt;
- uint32_t initial_seed[DEFAULT_SEED_CNT];
-
- fill_random_seed(initial_seed, DEFAULT_SEED_CNT);
- init_by_array(&mt, initial_seed, DEFAULT_SEED_CNT);
-
- init_seed(&mt);
-
- explicit_bzero(initial_seed, DEFAULT_SEED_LEN);
-}
-
-static VALUE
-init_randomseed(struct MT *mt)
-{
- uint32_t initial[DEFAULT_SEED_CNT+1];
- VALUE seed;
-
- fill_random_seed(initial, DEFAULT_SEED_CNT);
- init_by_array(mt, initial, DEFAULT_SEED_CNT);
- seed = make_seed_value(initial, DEFAULT_SEED_CNT);
- explicit_bzero(initial, DEFAULT_SEED_LEN);
- return seed;
-}
-
-/* construct Random::DEFAULT bits */
-static VALUE
-Init_Random_default(void)
-{
- rb_random_t *r = &default_rand;
- struct MT *mt = &r->mt;
- VALUE v = TypedData_Wrap_Struct(rb_cRandom, &random_data_type, r);
- rb_gc_register_mark_object(v);
- r->seed = init_randomseed(mt);
+ with_random_seed(DEFAULT_SEED_CNT, 0) {
+ init_by_array(&mt, seedbuf, DEFAULT_SEED_CNT);
+ }
- return v;
+ init_hash_salt(&mt);
+ explicit_bzero(&mt, sizeof(mt));
}
void
rb_reset_random_seed(void)
{
- rb_random_t *r = &default_rand;
+ rb_random_mt_t *r = default_rand();
uninit_genrand(&r->mt);
- r->seed = INT2FIX(0);
+ r->base.seed = INT2FIX(0);
}
/*
@@ -1587,55 +1681,72 @@ rb_reset_random_seed(void)
*
* The class method Random.rand provides the base functionality of Kernel.rand
* along with better handling of floating point values. These are both
- * interfaces to Random::DEFAULT, the Ruby system PRNG.
+ * interfaces to the Ruby system PRNG.
*
- * Random.new will create a new PRNG with a state independent of
- * Random::DEFAULT, allowing multiple generators with different seed values or
+ * Random.new will create a new PRNG with a state independent of the Ruby
+ * system PRNG, allowing multiple generators with different seed values or
* sequence positions to exist simultaneously. Random objects can be
* marshaled, allowing sequences to be saved and resumed.
*
* PRNGs are currently implemented as a modified Mersenne Twister with a period
- * of 2**19937-1.
+ * of 2**19937-1. As this algorithm is _not_ for cryptographical use, you must
+ * use SecureRandom for security purpose, instead of this PRNG.
*/
void
InitVM_Random(void)
{
+ VALUE base;
+ ID id_base = rb_intern_const("Base");
+
rb_define_global_function("srand", rb_f_srand, -1);
rb_define_global_function("rand", rb_f_rand, -1);
- rb_cRandom = rb_define_class("Random", rb_cObject);
+ base = rb_define_class_id(id_base, rb_cObject);
+ rb_undef_alloc_func(base);
+ rb_cRandom = rb_define_class("Random", base);
+ rb_const_set(rb_cRandom, id_base, base);
rb_define_alloc_func(rb_cRandom, random_alloc);
+ rb_define_method(base, "initialize", random_init, -1);
+ rb_define_method(base, "rand", random_rand, -1);
+ rb_define_method(base, "bytes", random_bytes, 1);
+ rb_define_method(base, "seed", random_get_seed, 0);
+ rb_define_method(rb_cRandom, "initialize_copy", rand_mt_copy, 1);
+ rb_define_private_method(rb_cRandom, "marshal_dump", rand_mt_dump, 0);
+ rb_define_private_method(rb_cRandom, "marshal_load", rand_mt_load, 1);
+ rb_define_private_method(rb_cRandom, "state", rand_mt_state, 0);
+ rb_define_private_method(rb_cRandom, "left", rand_mt_left, 0);
+ rb_define_method(rb_cRandom, "==", rand_mt_equal, 1);
+
+#if 0 /* for RDoc: it can't handle unnamed base class */
rb_define_method(rb_cRandom, "initialize", random_init, -1);
rb_define_method(rb_cRandom, "rand", random_rand, -1);
rb_define_method(rb_cRandom, "bytes", random_bytes, 1);
rb_define_method(rb_cRandom, "seed", random_get_seed, 0);
- rb_define_method(rb_cRandom, "initialize_copy", random_copy, 1);
- rb_define_private_method(rb_cRandom, "marshal_dump", random_dump, 0);
- rb_define_private_method(rb_cRandom, "marshal_load", random_load, 1);
- rb_define_private_method(rb_cRandom, "state", random_state, 0);
- rb_define_private_method(rb_cRandom, "left", random_left, 0);
- rb_define_method(rb_cRandom, "==", random_equal, 1);
+#endif
- {
- /* Direct access to Ruby's Pseudorandom number generator (PRNG). */
- VALUE rand_default = Init_Random_default();
- rb_define_const(rb_cRandom, "DEFAULT", rand_default);
- }
+ rb_define_const(rb_cRandom, "DEFAULT", rb_cRandom);
+ rb_deprecate_constant(rb_cRandom, "DEFAULT");
rb_define_singleton_method(rb_cRandom, "srand", rb_f_srand, -1);
rb_define_singleton_method(rb_cRandom, "rand", random_s_rand, -1);
+ rb_define_singleton_method(rb_cRandom, "bytes", random_s_bytes, 1);
+ rb_define_singleton_method(rb_cRandom, "seed", random_s_seed, 0);
rb_define_singleton_method(rb_cRandom, "new_seed", random_seed, 0);
rb_define_singleton_method(rb_cRandom, "urandom", random_raw_seed, 1);
rb_define_private_method(CLASS_OF(rb_cRandom), "state", random_s_state, 0);
rb_define_private_method(CLASS_OF(rb_cRandom), "left", random_s_left, 0);
{
+ /* Format raw random number as Random does */
VALUE m = rb_define_module_under(rb_cRandom, "Formatter");
- rb_include_module(rb_cRandom, m);
+ rb_include_module(base, m);
+ rb_extend_object(base, m);
rb_define_method(m, "random_number", rand_random_number, -1);
rb_define_method(m, "rand", rand_random_number, -1);
}
+
+ default_rand_key = rb_ractor_local_storage_ptr_newkey(&default_rand_key_storage_type);
}
#undef rb_intern
diff --git a/range.c b/range.c
index ba96e3de3f..2939ef3798 100644
--- a/range.c
+++ b/range.c
@@ -9,24 +9,34 @@
**********************************************************************/
-#include "internal.h"
-#include "id.h"
+#include "ruby/internal/config.h"
+
+#include <assert.h>
+#include <math.h>
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
-#include <math.h>
+
+#include "id.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/compar.h"
+#include "internal/enum.h"
+#include "internal/enumerator.h"
+#include "internal/error.h"
+#include "internal/numeric.h"
+#include "internal/range.h"
VALUE rb_cRange;
-static ID id_beg, id_end, id_excl, id_integer_p, id_div;
+static ID id_beg, id_end, id_excl;
#define id_cmp idCmp
#define id_succ idSucc
+#define id_min idMin
+#define id_max idMax
static VALUE r_cover_p(VALUE, VALUE, VALUE, VALUE);
-#define RANGE_BEG(r) (RSTRUCT(r)->as.ary[0])
-#define RANGE_END(r) (RSTRUCT(r)->as.ary[1])
-#define RANGE_EXCL(r) (RSTRUCT(r)->as.ary[2])
#define RANGE_SET_BEG(r, v) (RSTRUCT_SET(r, 0, v))
#define RANGE_SET_END(r, v) (RSTRUCT_SET(r, 1, v))
#define RANGE_SET_EXCL(r, v) (RSTRUCT_SET(r, 2, v))
@@ -37,7 +47,7 @@ static VALUE r_cover_p(VALUE, VALUE, VALUE, VALUE);
static void
range_init(VALUE range, VALUE beg, VALUE end, VALUE exclude_end)
{
- if (!FIXNUM_P(beg) || !FIXNUM_P(end)) {
+ if ((!FIXNUM_P(beg) || !FIXNUM_P(end)) && !NIL_P(beg) && !NIL_P(end)) {
VALUE v;
v = rb_funcall(beg, id_cmp, 1, end);
@@ -48,6 +58,10 @@ range_init(VALUE range, VALUE beg, VALUE end, VALUE exclude_end)
RANGE_SET_EXCL(range, exclude_end);
RANGE_SET_BEG(range, beg);
RANGE_SET_END(range, end);
+
+ if (CLASS_OF(range) == rb_cRange) {
+ rb_obj_freeze(range);
+ }
}
VALUE
@@ -74,7 +88,7 @@ range_modify(VALUE range)
* Range.new(begin, end, exclude_end=false) -> rng
*
* Constructs a range using the given +begin+ and +end+. If the +exclude_end+
- * parameter is omitted or is <code>false</code>, the +rng+ will include
+ * parameter is omitted or is <code>false</code>, the range will include
* the end object; otherwise, it will be excluded.
*/
@@ -232,11 +246,11 @@ range_hash(VALUE range)
hash = rb_hash_uint(hash, EXCL(range) << 24);
hash = rb_hash_end(hash);
- return LONG2FIX(hash);
+ return ST2FIX(hash);
}
static void
-range_each_func(VALUE range, rb_block_call_func *func, VALUE arg)
+range_each_func(VALUE range, int (*func)(VALUE, VALUE), VALUE arg)
{
int c;
VALUE b = RANGE_BEG(range);
@@ -245,21 +259,21 @@ range_each_func(VALUE range, rb_block_call_func *func, VALUE arg)
if (EXCL(range)) {
while (r_less(v, e) < 0) {
- (*func) (v, arg, 0, 0, 0);
+ if ((*func)(v, arg)) break;
v = rb_funcallv(v, id_succ, 0, 0);
}
}
else {
while ((c = r_less(v, e)) <= 0) {
- (*func) (v, arg, 0, 0, 0);
+ if ((*func)(v, arg)) break;
if (!c) break;
v = rb_funcallv(v, id_succ, 0, 0);
}
}
}
-static VALUE
-sym_step_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
+static int
+sym_step_i(VALUE i, VALUE arg)
{
VALUE *iter = (VALUE *)arg;
@@ -273,11 +287,11 @@ sym_step_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
rb_yield(rb_str_intern(i));
iter[0] = iter[1];
}
- return Qnil;
+ return 0;
}
-static VALUE
-step_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
+static int
+step_i(VALUE i, VALUE arg)
{
VALUE *iter = (VALUE *)arg;
@@ -291,7 +305,7 @@ step_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
rb_yield(i);
iter[0] = iter[1];
}
- return Qnil;
+ return 0;
}
static int
@@ -310,6 +324,8 @@ linear_object_p(VALUE obj)
case T_FLOAT:
case T_BIGNUM:
return TRUE;
+ default:
+ break;
}
if (rb_obj_is_kind_of(obj, rb_cNumeric)) return TRUE;
if (rb_obj_is_kind_of(obj, rb_cTime)) return TRUE;
@@ -350,16 +366,22 @@ range_step_size(VALUE range, VALUE args, VALUE eobj)
}
/*
+ * Document-method: Range#step
+ * Document-method: Range#%
* call-seq:
* rng.step(n=1) {| obj | block } -> rng
* rng.step(n=1) -> an_enumerator
+ * rng.step(n=1) -> an_arithmetic_sequence
+ * rng % n -> an_enumerator
+ * rng % n -> an_arithmetic_sequence
*
* Iterates over the range, passing each <code>n</code>th element to the block.
* If begin and end are numeric, +n+ is added for each iteration.
- * Otherwise <code>step</code> invokes <code>succ</code> to iterate through
- * range elements.
+ * Otherwise #step invokes #succ to iterate through range elements.
*
* If no block is given, an enumerator is returned instead.
+ * Especially, the enumerator is an Enumerator::ArithmeticSequence
+ * if begin and end of the range are numeric.
*
* range = Xs.new(1)..Xs.new(10)
* range.step(2) {|x| puts x}
@@ -388,19 +410,42 @@ range_step(int argc, VALUE *argv, VALUE range)
{
VALUE b, e, step, tmp;
- RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);
-
b = RANGE_BEG(range);
e = RANGE_END(range);
- if (argc == 0) {
- step = INT2FIX(1);
- }
- else {
- rb_scan_args(argc, argv, "01", &step);
- step = check_step_domain(step);
+ step = (!rb_check_arity(argc, 0, 1) ? INT2FIX(1) : argv[0]);
+
+ if (!rb_block_given_p()) {
+ if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
+ step = rb_to_int(step);
+ }
+ if (rb_equal(step, INT2FIX(0))) {
+ rb_raise(rb_eArgError, "step can't be 0");
+ }
+
+ const VALUE b_num_p = rb_obj_is_kind_of(b, rb_cNumeric);
+ const VALUE e_num_p = rb_obj_is_kind_of(e, rb_cNumeric);
+ if ((b_num_p && (NIL_P(e) || e_num_p)) || (NIL_P(b) && e_num_p)) {
+ return rb_arith_seq_new(range, ID2SYM(rb_frame_this_func()), argc, argv,
+ range_step_size, b, e, step, EXCL(range));
+ }
+
+ RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);
}
- if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
+ step = check_step_domain(step);
+
+ if (FIXNUM_P(b) && NIL_P(e) && FIXNUM_P(step)) {
+ long i = FIX2LONG(b), unit = FIX2LONG(step);
+ do {
+ rb_yield(LONG2FIX(i));
+ i += unit; /* FIXABLE+FIXABLE never overflow */
+ } while (FIXABLE(i));
+ b = LONG2NUM(i);
+
+ for (;; b = rb_big_plus(b, step))
+ rb_yield(b);
+ }
+ else if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
long end = FIX2LONG(e);
long i, unit = FIX2LONG(step);
@@ -414,16 +459,20 @@ range_step(int argc, VALUE *argv, VALUE range)
}
}
- else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
- VALUE args[2], iter[2];
-
- args[0] = rb_sym2str(e);
- args[1] = EXCL(range) ? Qtrue : Qfalse;
+ else if (SYMBOL_P(b) && (NIL_P(e) || SYMBOL_P(e))) { /* symbols are special */
+ VALUE iter[2];
iter[0] = INT2FIX(1);
iter[1] = step;
- rb_block_call(rb_sym2str(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
+
+ b = rb_sym2str(b);
+ if (NIL_P(e)) {
+ rb_str_upto_endless_each(b, sym_step_i, (VALUE)iter);
+ }
+ else {
+ rb_str_upto_each(b, rb_sym2str(e), EXCL(range), sym_step_i, (VALUE)iter);
+ }
}
- else if (ruby_float_step(b, e, step, EXCL(range))) {
+ else if (ruby_float_step(b, e, step, EXCL(range), TRUE)) {
/* done */
}
else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
@@ -433,7 +482,7 @@ range_step(int argc, VALUE *argv, VALUE range)
VALUE v = b;
int i = 0;
- while (RTEST(rb_funcall(v, op, 1, e))) {
+ while (NIL_P(e) || RTEST(rb_funcall(v, op, 1, e))) {
rb_yield(v);
i++;
v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
@@ -443,14 +492,18 @@ range_step(int argc, VALUE *argv, VALUE range)
tmp = rb_check_string_type(b);
if (!NIL_P(tmp)) {
- VALUE args[2], iter[2];
+ VALUE iter[2];
b = tmp;
- args[0] = e;
- args[1] = EXCL(range) ? Qtrue : Qfalse;
iter[0] = INT2FIX(1);
iter[1] = step;
- rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
+
+ if (NIL_P(e)) {
+ rb_str_upto_endless_each(b, step_i, (VALUE)iter);
+ }
+ else {
+ rb_str_upto_each(b, e, EXCL(range), step_i, (VALUE)iter);
+ }
}
else {
VALUE args[2];
@@ -467,6 +520,12 @@ range_step(int argc, VALUE *argv, VALUE range)
return range;
}
+static VALUE
+range_percent_step(VALUE range, VALUE step)
+{
+ return range_step(1, &step, range);
+}
+
#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
union int64_double {
int64_t i;
@@ -499,10 +558,72 @@ double_as_int64(double d)
static int
is_integer_p(VALUE v)
{
- VALUE is_int = rb_check_funcall(v, id_integer_p, 0, 0);
+ ID id_integer_p;
+ VALUE is_int;
+ CONST_ID(id_integer_p, "integer?");
+ is_int = rb_check_funcall(v, id_integer_p, 0, 0);
return RTEST(is_int) && is_int != Qundef;
}
+static VALUE
+bsearch_integer_range(VALUE beg, VALUE end, int excl)
+{
+ VALUE satisfied = Qnil;
+ int smaller;
+
+#define BSEARCH_CHECK(expr) \
+ do { \
+ VALUE val = (expr); \
+ VALUE v = rb_yield(val); \
+ if (FIXNUM_P(v)) { \
+ if (v == INT2FIX(0)) return val; \
+ smaller = (SIGNED_VALUE)v < 0; \
+ } \
+ else if (v == Qtrue) { \
+ satisfied = val; \
+ smaller = 1; \
+ } \
+ else if (v == Qfalse || v == Qnil) { \
+ smaller = 0; \
+ } \
+ else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
+ int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)); \
+ if (!cmp) return val; \
+ smaller = cmp < 0; \
+ } \
+ else { \
+ rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE \
+ " (must be numeric, true, false or nil)", \
+ rb_obj_class(v)); \
+ } \
+ } while (0)
+
+ VALUE low = rb_to_int(beg);
+ VALUE high = rb_to_int(end);
+ VALUE mid, org_high;
+ ID id_div;
+ CONST_ID(id_div, "div");
+
+ if (excl) high = rb_funcall(high, '-', 1, INT2FIX(1));
+ org_high = high;
+
+ while (rb_cmpint(rb_funcall(low, id_cmp, 1, high), low, high) < 0) {
+ mid = rb_funcall(rb_funcall(high, '+', 1, low), id_div, 1, INT2FIX(2));
+ BSEARCH_CHECK(mid);
+ if (smaller) {
+ high = mid;
+ }
+ else {
+ low = rb_funcall(mid, '+', 1, INT2FIX(1));
+ }
+ }
+ if (rb_equal(low, org_high)) {
+ BSEARCH_CHECK(low);
+ if (!smaller) return Qnil;
+ }
+ return satisfied;
+}
+
/*
* call-seq:
* rng.bsearch {|obj| block } -> value
@@ -575,33 +696,6 @@ range_bsearch(VALUE range)
* (-1...0.0).bsearch to yield -0.0.
*/
-#define BSEARCH_CHECK(expr) \
- do { \
- VALUE val = (expr); \
- VALUE v = rb_yield(val); \
- if (FIXNUM_P(v)) { \
- if (v == INT2FIX(0)) return val; \
- smaller = (SIGNED_VALUE)v < 0; \
- } \
- else if (v == Qtrue) { \
- satisfied = val; \
- smaller = 1; \
- } \
- else if (v == Qfalse || v == Qnil) { \
- smaller = 0; \
- } \
- else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
- int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)); \
- if (!cmp) return val; \
- smaller = cmp < 0; \
- } \
- else { \
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE \
- " (must be numeric, true, false or nil)", \
- rb_obj_class(v)); \
- } \
- } while (0)
-
#define BSEARCH(conv) \
do { \
RETURN_ENUMERATOR(range, 0, 0); \
@@ -637,35 +731,39 @@ range_bsearch(VALUE range)
}
#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
else if (RB_TYPE_P(beg, T_FLOAT) || RB_TYPE_P(end, T_FLOAT)) {
- int64_t low = double_as_int64(RFLOAT_VALUE(rb_Float(beg)));
- int64_t high = double_as_int64(RFLOAT_VALUE(rb_Float(end)));
+ int64_t low = double_as_int64(NIL_P(beg) ? -HUGE_VAL : RFLOAT_VALUE(rb_Float(beg)));
+ int64_t high = double_as_int64(NIL_P(end) ? HUGE_VAL : RFLOAT_VALUE(rb_Float(end)));
int64_t mid, org_high;
BSEARCH(int64_as_double_to_num);
}
#endif
else if (is_integer_p(beg) && is_integer_p(end)) {
- VALUE low = rb_to_int(beg);
- VALUE high = rb_to_int(end);
- VALUE mid, org_high;
RETURN_ENUMERATOR(range, 0, 0);
- if (EXCL(range)) high = rb_funcall(high, '-', 1, INT2FIX(1));
- org_high = high;
-
- while (rb_cmpint(rb_funcall(low, id_cmp, 1, high), low, high) < 0) {
- mid = rb_funcall(rb_funcall(high, '+', 1, low), id_div, 1, INT2FIX(2));
+ return bsearch_integer_range(beg, end, EXCL(range));
+ }
+ else if (is_integer_p(beg) && NIL_P(end)) {
+ VALUE diff = LONG2FIX(1);
+ RETURN_ENUMERATOR(range, 0, 0);
+ while (1) {
+ VALUE mid = rb_funcall(beg, '+', 1, diff);
BSEARCH_CHECK(mid);
if (smaller) {
- high = mid;
- }
- else {
- low = rb_funcall(mid, '+', 1, INT2FIX(1));
+ return bsearch_integer_range(beg, mid, 0);
}
+ diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
}
- if (rb_equal(low, org_high)) {
- BSEARCH_CHECK(low);
- if (!smaller) return Qnil;
+ }
+ else if (NIL_P(beg) && is_integer_p(end)) {
+ VALUE diff = LONG2FIX(-1);
+ RETURN_ENUMERATOR(range, 0, 0);
+ while (1) {
+ VALUE mid = rb_funcall(end, '+', 1, diff);
+ BSEARCH_CHECK(mid);
+ if (!smaller) {
+ return bsearch_integer_range(mid, end, 0);
+ }
+ diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
}
- return satisfied;
}
else {
rb_raise(rb_eTypeError, "can't do binary search for %s", rb_obj_classname(beg));
@@ -673,18 +771,18 @@ range_bsearch(VALUE range)
return range;
}
-static VALUE
-each_i(RB_BLOCK_CALL_FUNC_ARGLIST(v, arg))
+static int
+each_i(VALUE v, VALUE arg)
{
rb_yield(v);
- return Qnil;
+ return 0;
}
-static VALUE
-sym_each_i(RB_BLOCK_CALL_FUNC_ARGLIST(v, arg))
+static int
+sym_each_i(VALUE v, VALUE arg)
{
rb_yield(rb_str_intern(v));
- return Qnil;
+ return 0;
}
/*
@@ -703,18 +801,79 @@ static VALUE
range_size(VALUE range)
{
VALUE b = RANGE_BEG(range), e = RANGE_END(range);
- if (rb_obj_is_kind_of(b, rb_cNumeric) && rb_obj_is_kind_of(e, rb_cNumeric)) {
- return ruby_num_interval_step_size(b, e, INT2FIX(1), EXCL(range));
+ if (rb_obj_is_kind_of(b, rb_cNumeric)) {
+ if (rb_obj_is_kind_of(e, rb_cNumeric)) {
+ return ruby_num_interval_step_size(b, e, INT2FIX(1), EXCL(range));
+ }
+ if (NIL_P(e)) {
+ return DBL2NUM(HUGE_VAL);
+ }
+ }
+ else if (NIL_P(b)) {
+ return DBL2NUM(HUGE_VAL);
}
+
return Qnil;
}
+/*
+ * call-seq:
+ * rng.to_a -> array
+ * rng.entries -> array
+ *
+ * Returns an array containing the items in the range.
+ *
+ * (1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7]
+ * (1..).to_a #=> RangeError: cannot convert endless range to an array
+ */
+
+static VALUE
+range_to_a(VALUE range)
+{
+ if (NIL_P(RANGE_END(range))) {
+ rb_raise(rb_eRangeError, "cannot convert endless range to an array");
+ }
+ return rb_call_super(0, 0);
+}
+
static VALUE
range_enum_size(VALUE range, VALUE args, VALUE eobj)
{
return range_size(range);
}
+RBIMPL_ATTR_NORETURN()
+static void
+range_each_bignum_endless(VALUE beg)
+{
+ for (;; beg = rb_big_plus(beg, INT2FIX(1))) {
+ rb_yield(beg);
+ }
+ UNREACHABLE;
+}
+
+RBIMPL_ATTR_NORETURN()
+static void
+range_each_fixnum_endless(VALUE beg)
+{
+ for (long i = FIX2LONG(beg); FIXABLE(i); i++) {
+ rb_yield(LONG2FIX(i));
+ }
+
+ range_each_bignum_endless(LONG2NUM(RUBY_FIXNUM_MAX + 1));
+ UNREACHABLE;
+}
+
+static VALUE
+range_each_fixnum_loop(VALUE beg, VALUE end, VALUE range)
+{
+ long lim = FIX2LONG(end) + !EXCL(range);
+ for (long i = FIX2LONG(beg); i < lim; i++) {
+ rb_yield(LONG2FIX(i));
+ }
+ return range;
+}
+
/*
* call-seq:
* rng.each {| i | block } -> rng
@@ -740,45 +899,91 @@ static VALUE
range_each(VALUE range)
{
VALUE beg, end;
+ long i;
RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);
beg = RANGE_BEG(range);
end = RANGE_END(range);
- if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
- long lim = FIX2LONG(end);
- long i;
-
- if (!EXCL(range))
- lim += 1;
- for (i = FIX2LONG(beg); i < lim; i++) {
- rb_yield(LONG2FIX(i));
+ if (FIXNUM_P(beg) && NIL_P(end)) {
+ range_each_fixnum_endless(beg);
+ }
+ else if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
+ return range_each_fixnum_loop(beg, end, range);
+ }
+ else if (RB_INTEGER_TYPE_P(beg) && (NIL_P(end) || RB_INTEGER_TYPE_P(end))) {
+ if (SPECIAL_CONST_P(end) || RBIGNUM_POSITIVE_P(end)) { /* end >= FIXNUM_MIN */
+ if (!FIXNUM_P(beg)) {
+ if (RBIGNUM_NEGATIVE_P(beg)) {
+ do {
+ rb_yield(beg);
+ } while (!FIXNUM_P(beg = rb_big_plus(beg, INT2FIX(1))));
+ if (NIL_P(end)) range_each_fixnum_endless(beg);
+ if (FIXNUM_P(end)) return range_each_fixnum_loop(beg, end, range);
+ }
+ else {
+ if (NIL_P(end)) range_each_bignum_endless(beg);
+ if (FIXNUM_P(end)) return range;
+ }
+ }
+ if (FIXNUM_P(beg)) {
+ i = FIX2LONG(beg);
+ do {
+ rb_yield(LONG2FIX(i));
+ } while (POSFIXABLE(++i));
+ beg = LONG2NUM(i);
+ }
+ ASSUME(!FIXNUM_P(beg));
+ ASSUME(!SPECIAL_CONST_P(end));
+ }
+ if (!FIXNUM_P(beg) && RBIGNUM_SIGN(beg) == RBIGNUM_SIGN(end)) {
+ if (EXCL(range)) {
+ while (rb_big_cmp(beg, end) == INT2FIX(-1)) {
+ rb_yield(beg);
+ beg = rb_big_plus(beg, INT2FIX(1));
+ }
+ }
+ else {
+ VALUE c;
+ while ((c = rb_big_cmp(beg, end)) != INT2FIX(1)) {
+ rb_yield(beg);
+ if (c == INT2FIX(0)) break;
+ beg = rb_big_plus(beg, INT2FIX(1));
+ }
+ }
}
}
- else if (SYMBOL_P(beg) && SYMBOL_P(end)) { /* symbols are special */
- VALUE args[2];
-
- args[0] = rb_sym2str(end);
- args[1] = EXCL(range) ? Qtrue : Qfalse;
- rb_block_call(rb_sym2str(beg), rb_intern("upto"), 2, args, sym_each_i, 0);
+ else if (SYMBOL_P(beg) && (NIL_P(end) || SYMBOL_P(end))) { /* symbols are special */
+ beg = rb_sym2str(beg);
+ if (NIL_P(end)) {
+ rb_str_upto_endless_each(beg, sym_each_i, 0);
+ }
+ else {
+ rb_str_upto_each(beg, rb_sym2str(end), EXCL(range), sym_each_i, 0);
+ }
}
else {
VALUE tmp = rb_check_string_type(beg);
if (!NIL_P(tmp)) {
- VALUE args[2];
-
- args[0] = end;
- args[1] = EXCL(range) ? Qtrue : Qfalse;
- rb_block_call(tmp, rb_intern("upto"), 2, args, each_i, 0);
+ if (!NIL_P(end)) {
+ rb_str_upto_each(tmp, end, EXCL(range), each_i, 0);
+ }
+ else {
+ rb_str_upto_endless_each(tmp, each_i, 0);
+ }
}
else {
if (!discrete_object_p(beg)) {
rb_raise(rb_eTypeError, "can't iterate from %s",
rb_obj_classname(beg));
}
- range_each_func(range, each_i, 0);
+ if (!NIL_P(end))
+ range_each_func(range, each_i, 0);
+ else
+ for (;; beg = rb_funcallv(beg, id_succ, 0, 0))
+ rb_yield(beg);
}
}
return range;
@@ -829,7 +1034,7 @@ first_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, cbarg))
}
rb_ary_push(ary[1], i);
n--;
- ary[0] = INT2NUM(n);
+ ary[0] = LONG2NUM(n);
return Qnil;
}
@@ -850,6 +1055,9 @@ range_first(int argc, VALUE *argv, VALUE range)
{
VALUE n, ary[2];
+ if (NIL_P(RANGE_BEG(range))) {
+ rb_raise(rb_eRangeError, "cannot get the first element of beginless range");
+ }
if (argc == 0) return RANGE_BEG(range);
rb_scan_args(argc, argv, "1", &n);
@@ -860,6 +1068,58 @@ range_first(int argc, VALUE *argv, VALUE range)
return ary[1];
}
+static VALUE
+rb_int_range_last(int argc, VALUE *argv, VALUE range)
+{
+ static const VALUE ONE = INT2FIX(1);
+
+ VALUE b, e, len_1, len, nv, ary;
+ int x;
+ long n;
+
+ assert(argc > 0);
+
+ b = RANGE_BEG(range);
+ e = RANGE_END(range);
+ assert(RB_INTEGER_TYPE_P(b) && RB_INTEGER_TYPE_P(e));
+
+ x = EXCL(range);
+
+ len_1 = rb_int_minus(e, b);
+ if (FIXNUM_ZERO_P(len_1) || rb_num_negative_p(len_1)) {
+ return rb_ary_new_capa(0);
+ }
+
+ if (x) {
+ e = rb_int_minus(e, ONE);
+ len = len_1;
+ }
+ else {
+ len = rb_int_plus(len_1, ONE);
+ }
+
+ rb_scan_args(argc, argv, "1", &nv);
+ n = NUM2LONG(nv);
+ if (n < 0) {
+ rb_raise(rb_eArgError, "negative array size");
+ }
+
+ nv = LONG2NUM(n);
+ if (RTEST(rb_int_gt(nv, len))) {
+ nv = len;
+ n = NUM2LONG(nv);
+ }
+
+ ary = rb_ary_new_capa(n);
+ b = rb_int_minus(e, nv);
+ while (n) {
+ b = rb_int_plus(b, ONE);
+ rb_ary_push(ary, b);
+ --n;
+ }
+
+ return ary;
+}
/*
* call-seq:
@@ -881,7 +1141,19 @@ range_first(int argc, VALUE *argv, VALUE range)
static VALUE
range_last(int argc, VALUE *argv, VALUE range)
{
+ VALUE b, e;
+
+ if (NIL_P(RANGE_END(range))) {
+ rb_raise(rb_eRangeError, "cannot get the last element of endless range");
+ }
if (argc == 0) return RANGE_END(range);
+
+ b = RANGE_BEG(range);
+ e = RANGE_END(range);
+ if (RB_INTEGER_TYPE_P(b) && RB_INTEGER_TYPE_P(e) &&
+ RB_LIKELY(rb_method_basic_definition_p(rb_cRange, idEach))) {
+ return rb_int_range_last(argc, argv, range);
+ }
return rb_ary_last(argc, argv, rb_Array(range));
}
@@ -907,7 +1179,14 @@ range_last(int argc, VALUE *argv, VALUE range)
static VALUE
range_min(int argc, VALUE *argv, VALUE range)
{
+ if (NIL_P(RANGE_BEG(range))) {
+ rb_raise(rb_eRangeError, "cannot get the minimum of beginless range");
+ }
+
if (rb_block_given_p()) {
+ if (NIL_P(RANGE_END(range))) {
+ rb_raise(rb_eRangeError, "cannot get the minimum of endless range with custom comparison method");
+ }
return rb_call_super(argc, argv);
}
else if (argc != 0) {
@@ -917,7 +1196,7 @@ range_min(int argc, VALUE *argv, VALUE range)
struct cmp_opt_data cmp_opt = { 0, 0 };
VALUE b = RANGE_BEG(range);
VALUE e = RANGE_END(range);
- int c = OPTIMIZED_CMP(b, e, cmp_opt);
+ int c = NIL_P(e) ? -1 : OPTIMIZED_CMP(b, e, cmp_opt);
if (c > 0 || (c == 0 && EXCL(range)))
return Qnil;
@@ -932,14 +1211,34 @@ range_min(int argc, VALUE *argv, VALUE range)
* rng.max(n) -> obj
* rng.max(n) {| a,b | block } -> obj
*
- * Returns the maximum value in the range. Returns +nil+ if the begin
- * value of the range larger than the end value. Returns +nil+ if
- * the begin value of an exclusive range is equal to the end value.
- *
- * Can be given an optional block to override the default comparison
- * method <code>a <=> b</code>.
- *
- * (10..20).max #=> 20
+ * Returns the maximum value in the range, or an array of maximum
+ * values in the range if given an \Integer argument.
+ *
+ * For inclusive ranges with an end, the maximum value of the range
+ * is the same as the end of the range.
+ *
+ * If an argument or block is given, or +self+ is an exclusive,
+ * non-numeric range, calls Enumerable#max (via +super+) with the
+ * argument and/or block to get the maximum values, unless +self+ is
+ * a beginless range, in which case it raises a RangeError.
+ *
+ * If +self+ is an exclusive, integer range (both start and end of the
+ * range are integers), and no arguments or block are provided, returns
+ * last value in the range (1 before the end). Otherwise, if +self+ is
+ * an exclusive, numeric range, raises a TypeError.
+ *
+ * Returns +nil+ if the begin value of the range larger than the
+ * end value. Returns +nil+ if the begin value of an exclusive
+ * range is equal to the end value. Raises a RangeError if called on
+ * an endless range.
+ *
+ * Examples:
+ * (10..20).max #=> 20
+ * (10..20).max(2) #=> [20, 19]
+ * (10...20).max #=> 19
+ * (10...20).max(2) #=> [19, 18]
+ * (10...20).max{|x, y| -x <=> -y } #=> 10
+ * (10...20).max(2){|x, y| -x <=> -y } #=> [10, 11]
*/
static VALUE
@@ -948,31 +1247,63 @@ range_max(int argc, VALUE *argv, VALUE range)
VALUE e = RANGE_END(range);
int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);
+ if (NIL_P(RANGE_END(range))) {
+ rb_raise(rb_eRangeError, "cannot get the maximum of endless range");
+ }
+
+ VALUE b = RANGE_BEG(range);
+
if (rb_block_given_p() || (EXCL(range) && !nm) || argc) {
- return rb_call_super(argc, argv);
+ if (NIL_P(b)) {
+ rb_raise(rb_eRangeError, "cannot get the maximum of beginless range with custom comparison method");
+ }
+ return rb_call_super(argc, argv);
}
else {
- struct cmp_opt_data cmp_opt = { 0, 0 };
- VALUE b = RANGE_BEG(range);
- int c = OPTIMIZED_CMP(b, e, cmp_opt);
+ struct cmp_opt_data cmp_opt = { 0, 0 };
+ int c = NIL_P(b) ? -1 : OPTIMIZED_CMP(b, e, cmp_opt);
+
+ if (c > 0)
+ return Qnil;
+ if (EXCL(range)) {
+ if (!RB_INTEGER_TYPE_P(e)) {
+ rb_raise(rb_eTypeError, "cannot exclude non Integer end value");
+ }
+ if (c == 0) return Qnil;
+ if (!RB_INTEGER_TYPE_P(b)) {
+ rb_raise(rb_eTypeError, "cannot exclude end value with non Integer begin value");
+ }
+ if (FIXNUM_P(e)) {
+ return LONG2NUM(FIX2LONG(e) - 1);
+ }
+ return rb_funcall(e, '-', 1, INT2FIX(1));
+ }
+ return e;
+ }
+}
- if (c > 0)
- return Qnil;
- if (EXCL(range)) {
- if (!FIXNUM_P(e) && !rb_obj_is_kind_of(e, rb_cInteger)) {
- rb_raise(rb_eTypeError, "cannot exclude non Integer end value");
- }
- if (c == 0) return Qnil;
- if (!FIXNUM_P(b) && !rb_obj_is_kind_of(b,rb_cInteger)) {
- rb_raise(rb_eTypeError, "cannot exclude end value with non Integer begin value");
- }
- if (FIXNUM_P(e)) {
- return LONG2NUM(FIX2LONG(e) - 1);
- }
- return rb_funcall(e, '-', 1, INT2FIX(1));
- }
- return e;
+/*
+ * call-seq:
+ * rng.minmax -> [obj, obj]
+ * rng.minmax {| a,b | block } -> [obj, obj]
+ *
+ * Returns a two element array which contains the minimum and the
+ * maximum value in the range.
+ *
+ * Can be given an optional block to override the default comparison
+ * method <code>a <=> b</code>.
+ */
+
+static VALUE
+range_minmax(VALUE range)
+{
+ if (rb_block_given_p()) {
+ return rb_call_super(0, NULL);
}
+ return rb_assoc_new(
+ rb_funcall(range, id_min, 0),
+ rb_funcall(range, id_max, 0)
+ );
}
int
@@ -986,12 +1317,18 @@ rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
e = RANGE_END(range);
excl = EXCL(range);
}
+ else if (RTEST(rb_obj_is_kind_of(range, rb_cArithSeq))) {
+ return (int)Qfalse;
+ }
else {
- if (!rb_respond_to(range, id_beg)) return (int)Qfalse;
- if (!rb_respond_to(range, id_end)) return (int)Qfalse;
- b = rb_funcall(range, id_beg, 0);
- e = rb_funcall(range, id_end, 0);
- excl = RTEST(rb_funcall(range, rb_intern("exclude_end?"), 0));
+ VALUE x;
+ b = rb_check_funcall(range, id_beg, 0, 0);
+ if (b == Qundef) return (int)Qfalse;
+ e = rb_check_funcall(range, id_end, 0, 0);
+ if (e == Qundef) return (int)Qfalse;
+ x = rb_check_funcall(range, rb_intern("exclude_end?"), 0, 0);
+ if (x == Qundef) return (int)Qfalse;
+ excl = RTEST(x);
}
*begp = b;
*endp = e;
@@ -999,50 +1336,81 @@ rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
return (int)Qtrue;
}
+/* Extract the components of a Range.
+ *
+ * You can use +err+ to control the behavior of out-of-range and exception.
+ *
+ * When +err+ is 0 or 2, if the begin offset is greater than +len+,
+ * it is out-of-range. The +RangeError+ is raised only if +err+ is 2,
+ * in this case. If +err+ is 0, +Qnil+ will be returned.
+ *
+ * When +err+ is 1, the begin and end offsets won't be adjusted even if they
+ * are greater than +len+. It allows +rb_ary_aset+ extends arrays.
+ *
+ * If the begin component of the given range is negative and is too-large
+ * abstract value, the +RangeError+ is raised only +err+ is 1 or 2.
+ *
+ * The case of <code>err = 0</code> is used in item accessing methods such as
+ * +rb_ary_aref+, +rb_ary_slice_bang+, and +rb_str_aref+.
+ *
+ * The case of <code>err = 1</code> is used in Array's methods such as
+ * +rb_ary_aset+ and +rb_ary_fill+.
+ *
+ * The case of <code>err = 2</code> is used in +rb_str_aset+.
+ */
VALUE
-rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
+rb_range_component_beg_len(VALUE b, VALUE e, int excl,
+ long *begp, long *lenp, long len, int err)
{
- long beg, end, origbeg, origend;
- VALUE b, e;
- int excl;
+ long beg, end;
- if (!rb_range_values(range, &b, &e, &excl))
- return Qfalse;
- beg = NUM2LONG(b);
- end = NUM2LONG(e);
- origbeg = beg;
- origend = end;
+ beg = NIL_P(b) ? 0 : NUM2LONG(b);
+ end = NIL_P(e) ? -1 : NUM2LONG(e);
+ if (NIL_P(e)) excl = 0;
if (beg < 0) {
- beg += len;
- if (beg < 0)
- goto out_of_range;
+ beg += len;
+ if (beg < 0)
+ goto out_of_range;
}
if (end < 0)
- end += len;
+ end += len;
if (!excl)
- end++; /* include end point */
+ end++; /* include end point */
if (err == 0 || err == 2) {
- if (beg > len)
- goto out_of_range;
- if (end > len)
- end = len;
+ if (beg > len)
+ goto out_of_range;
+ if (end > len)
+ end = len;
}
len = end - beg;
if (len < 0)
- len = 0;
+ len = 0;
*begp = beg;
*lenp = len;
return Qtrue;
out_of_range:
- if (err) {
- rb_raise(rb_eRangeError, "%ld..%s%ld out of range",
- origbeg, excl ? "." : "", origend);
- }
return Qnil;
}
+VALUE
+rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
+{
+ VALUE b, e;
+ int excl;
+
+ if (!rb_range_values(range, &b, &e, &excl))
+ return Qfalse;
+
+ VALUE res = rb_range_component_beg_len(b, e, excl, begp, lenp, len, err);
+ if (NIL_P(res) && err) {
+ rb_raise(rb_eRangeError, "%+"PRIsVALUE" out of range", range);
+ }
+
+ return res;
+}
+
/*
* call-seq:
* rng.to_s -> string
@@ -1061,7 +1429,6 @@ range_to_s(VALUE range)
str = rb_str_dup(str);
rb_str_cat(str, "...", EXCL(range) ? 3 : 2);
rb_str_append(str, str2);
- OBJ_INFECT(str, range);
return str;
}
@@ -1069,17 +1436,22 @@ range_to_s(VALUE range)
static VALUE
inspect_range(VALUE range, VALUE dummy, int recur)
{
- VALUE str, str2;
+ VALUE str, str2 = Qundef;
if (recur) {
return rb_str_new2(EXCL(range) ? "(... ... ...)" : "(... .. ...)");
}
- str = rb_inspect(RANGE_BEG(range));
- str2 = rb_inspect(RANGE_END(range));
- str = rb_str_dup(str);
+ if (!NIL_P(RANGE_BEG(range)) || NIL_P(RANGE_END(range))) {
+ str = rb_str_dup(rb_inspect(RANGE_BEG(range)));
+ }
+ else {
+ str = rb_str_new(0, 0);
+ }
rb_str_cat(str, "...", EXCL(range) ? 3 : 2);
- rb_str_append(str, str2);
- OBJ_INFECT(str, range);
+ if (NIL_P(RANGE_BEG(range)) || !NIL_P(RANGE_END(range))) {
+ str2 = rb_inspect(RANGE_END(range));
+ }
+ if (str2 != Qundef) rb_str_append(str, str2);
return str;
}
@@ -1088,9 +1460,8 @@ inspect_range(VALUE range, VALUE dummy, int recur)
* call-seq:
* rng.inspect -> string
*
- * Convert this range object to a printable form (using
- * <code>inspect</code> to convert the begin and end
- * objects).
+ * Convert this range object to a printable form (using #inspect to
+ * convert the begin and end objects).
*/
@@ -1100,29 +1471,40 @@ range_inspect(VALUE range)
return rb_exec_recursive(inspect_range, range, 0);
}
+static VALUE range_include_internal(VALUE range, VALUE val, int string_use_cover);
+
/*
* call-seq:
* rng === obj -> true or false
*
- * Returns <code>true</code> if +obj+ is an element of the range,
- * <code>false</code> otherwise. Conveniently, <code>===</code> is the
- * comparison operator used by <code>case</code> statements.
+ * Returns <code>true</code> if +obj+ is between begin and end of range,
+ * <code>false</code> otherwise (same as #cover?). Conveniently,
+ * <code>===</code> is the comparison operator used by <code>case</code>
+ * statements.
*
* case 79
- * when 1..50 then print "low\n"
- * when 51..75 then print "medium\n"
- * when 76..100 then print "high\n"
+ * when 1..50 then puts "low"
+ * when 51..75 then puts "medium"
+ * when 76..100 then puts "high"
* end
+ * # Prints "high"
*
- * <em>produces:</em>
+ * case "2.6.5"
+ * when ..."2.4" then puts "EOL"
+ * when "2.4"..."2.5" then puts "maintenance"
+ * when "2.5"..."2.7" then puts "stable"
+ * when "2.7".. then puts "upcoming"
+ * end
+ * # Prints "stable"
*
- * high
*/
static VALUE
range_eqq(VALUE range, VALUE val)
{
- return rb_funcall(range, rb_intern("include?"), 1, val);
+ VALUE ret = range_include_internal(range, val, 1);
+ if (ret != Qundef) return ret;
+ return r_cover_p(range, RANGE_BEG(range), RANGE_END(range), val);
}
@@ -1132,17 +1514,32 @@ range_eqq(VALUE range, VALUE val)
* rng.include?(obj) -> true or false
*
* Returns <code>true</code> if +obj+ is an element of
- * the range, <code>false</code> otherwise. If begin and end are
- * numeric, comparison is done according to the magnitude of the values.
+ * the range, <code>false</code> otherwise.
*
* ("a".."z").include?("g") #=> true
* ("a".."z").include?("A") #=> false
* ("a".."z").include?("cc") #=> false
+ *
+ * If you need to ensure +obj+ is between +begin+ and +end+, use #cover?
+ *
+ * ("a".."z").cover?("cc") #=> true
+ *
+ * If begin and end are numeric, #include? behaves like #cover?
+ *
+ * (1..3).include?(1.5) # => true
*/
static VALUE
range_include(VALUE range, VALUE val)
{
+ VALUE ret = range_include_internal(range, val, 0);
+ if (ret != Qundef) return ret;
+ return rb_call_super(1, &val);
+}
+
+static VALUE
+range_include_internal(VALUE range, VALUE val, int string_use_cover)
+{
VALUE beg = RANGE_BEG(range);
VALUE end = RANGE_END(range);
int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
@@ -1153,18 +1550,38 @@ range_include(VALUE range, VALUE val)
!NIL_P(rb_check_to_integer(end, "to_int"))) {
return r_cover_p(range, beg, end, val);
}
- else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
- VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
- return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
+ else if (RB_TYPE_P(beg, T_STRING) || RB_TYPE_P(end, T_STRING)) {
+ if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
+ if (string_use_cover) {
+ return r_cover_p(range, beg, end, val);
+ }
+ else {
+ VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
+ return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
+ }
+ }
+ else if (NIL_P(beg)) {
+ VALUE r = rb_funcall(val, id_cmp, 1, end);
+ if (NIL_P(r)) return Qfalse;
+ if (rb_cmpint(r, val, end) <= 0) return Qtrue;
+ return Qfalse;
+ }
+ else if (NIL_P(end)) {
+ VALUE r = rb_funcall(beg, id_cmp, 1, val);
+ if (NIL_P(r)) return Qfalse;
+ if (rb_cmpint(r, beg, val) <= 0) return Qtrue;
+ return Qfalse;
+ }
}
- /* TODO: ruby_frame->this_func = rb_intern("include?"); */
- return rb_call_super(1, &val);
+ return Qundef;
}
+static int r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val);
/*
* call-seq:
- * rng.cover?(obj) -> true or false
+ * rng.cover?(obj) -> true or false
+ * rng.cover?(range) -> true or false
*
* Returns <code>true</code> if +obj+ is between the begin and end of
* the range.
@@ -1172,9 +1589,25 @@ range_include(VALUE range, VALUE val)
* This tests <code>begin <= obj <= end</code> when #exclude_end? is +false+
* and <code>begin <= obj < end</code> when #exclude_end? is +true+.
*
- * ("a".."z").cover?("c") #=> true
- * ("a".."z").cover?("5") #=> false
- * ("a".."z").cover?("cc") #=> true
+ * If called with a Range argument, returns <code>true</code> when the
+ * given range is covered by the receiver,
+ * by comparing the begin and end values. If the argument can be treated as
+ * a sequence, this method treats it that way. In the specific case of
+ * <code>(a..b).cover?(c...d)</code> with <code>a <= c && b < d</code>,
+ * the end of the sequence must be calculated, which may exhibit poor
+ * performance if <code>c</code> is non-numeric.
+ * Returns <code>false</code> if the begin value of the
+ * range is larger than the end value. Also returns +false+ if one of the
+ * internal calls to <code><=></code> returns +nil+ (indicating the objects
+ * are not comparable).
+ *
+ * ("a".."z").cover?("c") #=> true
+ * ("a".."z").cover?("5") #=> false
+ * ("a".."z").cover?("cc") #=> true
+ * ("a".."z").cover?(1) #=> false
+ * (1..5).cover?(2..3) #=> true
+ * (1..5).cover?(0..6) #=> false
+ * (1..5).cover?(1...6) #=> true
*/
static VALUE
@@ -1184,15 +1617,57 @@ range_cover(VALUE range, VALUE val)
beg = RANGE_BEG(range);
end = RANGE_END(range);
+
+ if (rb_obj_is_kind_of(val, rb_cRange)) {
+ return RBOOL(r_cover_range_p(range, beg, end, val));
+ }
return r_cover_p(range, beg, end, val);
}
static VALUE
+r_call_max(VALUE r)
+{
+ return rb_funcallv(r, rb_intern("max"), 0, 0);
+}
+
+static int
+r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val)
+{
+ VALUE val_beg, val_end, val_max;
+ int cmp_end;
+
+ val_beg = RANGE_BEG(val);
+ val_end = RANGE_END(val);
+
+ if (!NIL_P(end) && NIL_P(val_end)) return FALSE;
+ if (!NIL_P(beg) && NIL_P(val_beg)) return FALSE;
+ if (!NIL_P(val_beg) && !NIL_P(val_end) && r_less(val_beg, val_end) > (EXCL(val) ? -1 : 0)) return FALSE;
+ if (!NIL_P(val_beg) && !r_cover_p(range, beg, end, val_beg)) return FALSE;
+
+ cmp_end = r_less(end, val_end);
+
+ if (EXCL(range) == EXCL(val)) {
+ return cmp_end >= 0;
+ }
+ else if (EXCL(range)) {
+ return cmp_end > 0;
+ }
+ else if (cmp_end >= 0) {
+ return TRUE;
+ }
+
+ val_max = rb_rescue2(r_call_max, val, 0, Qnil, rb_eTypeError, (VALUE)0);
+ if (val_max == Qnil) return FALSE;
+
+ return r_less(end, val_max) >= 0;
+}
+
+static VALUE
r_cover_p(VALUE range, VALUE beg, VALUE end, VALUE val)
{
- if (r_less(beg, val) <= 0) {
+ if (NIL_P(beg) || r_less(beg, val) <= 0) {
int excl = EXCL(range);
- if (r_less(val, end) <= -excl)
+ if (NIL_P(end) || r_less(val, end) <= -excl)
return Qtrue;
}
return Qfalse;
@@ -1201,10 +1676,7 @@ r_cover_p(VALUE range, VALUE beg, VALUE end, VALUE val)
static VALUE
range_dumper(VALUE range)
{
- VALUE v;
- NEWOBJ_OF(m, struct RObject, rb_cObject, T_OBJECT | (RGENGC_WB_PROTECTED_OBJECT ? FL_WB_PROTECTED : 1));
-
- v = (VALUE)m;
+ VALUE v = rb_obj_alloc(rb_cObject);
rb_ivar_set(v, id_excl, RANGE_EXCL(range));
rb_ivar_set(v, id_beg, RANGE_BEG(range));
@@ -1239,7 +1711,43 @@ range_alloc(VALUE klass)
return rb_struct_alloc_noinit(klass);
}
-/* A <code>Range</code> represents an interval---a set of values with a
+/*
+ * call-seq:
+ * range.count -> int
+ * range.count(item) -> int
+ * range.count { |obj| block } -> int
+ *
+ * Identical to Enumerable#count, except it returns Infinity for endless
+ * ranges.
+ *
+ */
+static VALUE
+range_count(int argc, VALUE *argv, VALUE range)
+{
+ if (argc != 0) {
+ /* It is odd for instance (1...).count(0) to return Infinity. Just let
+ * it loop. */
+ return rb_call_super(argc, argv);
+ }
+ else if (rb_block_given_p()) {
+ /* Likewise it is odd for instance (1...).count {|x| x == 0 } to return
+ * Infinity. Just let it loop. */
+ return rb_call_super(argc, argv);
+ }
+ else if (NIL_P(RANGE_END(range))) {
+ /* We are confident that the answer is Infinity. */
+ return DBL2NUM(HUGE_VAL);
+ }
+ else if (NIL_P(RANGE_BEG(range))) {
+ /* We are confident that the answer is Infinity. */
+ return DBL2NUM(HUGE_VAL);
+ }
+ else {
+ return rb_call_super(argc, argv);
+ }
+}
+
+/* A Range represents an interval---a set of values with a
* beginning and an end. Ranges may be constructed using the
* <em>s</em><code>..</code><em>e</em> and
* <em>s</em><code>...</code><em>e</em> literals, or with
@@ -1253,6 +1761,42 @@ range_alloc(VALUE klass)
* ('a'..'e').to_a #=> ["a", "b", "c", "d", "e"]
* ('a'...'e').to_a #=> ["a", "b", "c", "d"]
*
+ * == Beginless/Endless Ranges
+ *
+ * A "beginless range" and "endless range" represents a semi-infinite
+ * range. Literal notation for a beginless range is:
+ *
+ * (..1)
+ * # or
+ * (...1)
+ *
+ * Literal notation for an endless range is:
+ *
+ * (1..)
+ * # or similarly
+ * (1...)
+ *
+ * Which is equivalent to
+ *
+ * (1..nil) # or similarly (1...nil)
+ * Range.new(1, nil) # or Range.new(1, nil, true)
+ *
+ * Beginless/endless ranges are useful, for example, for idiomatic
+ * slicing of arrays:
+ *
+ * [1, 2, 3, 4, 5][...2] # => [1, 2]
+ * [1, 2, 3, 4, 5][2...] # => [3, 4, 5]
+ *
+ * Some implementation details:
+ *
+ * * +begin+ of beginless range and +end+ of endless range are +nil+;
+ * * +each+ of beginless range raises an exception;
+ * * +each+ of endless range enumerates infinite sequence (may be
+ * useful in combination with Enumerable#take_while or similar
+ * methods);
+ * * <code>(1..)</code> and <code>(1...)</code> are not equal,
+ * although technically representing the same sequence.
+ *
* == Custom Objects in Ranges
*
* Ranges can be constructed using any objects that can be compared
@@ -1299,14 +1843,9 @@ range_alloc(VALUE klass)
void
Init_Range(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
- id_beg = rb_intern("begin");
- id_end = rb_intern("end");
- id_excl = rb_intern("excl");
- id_integer_p = rb_intern("integer?");
- id_div = rb_intern("div");
+ id_beg = rb_intern_const("begin");
+ id_end = rb_intern_const("end");
+ id_excl = rb_intern_const("excl");
rb_cRange = rb_struct_define_without_accessor(
"Range", rb_cObject, range_alloc,
@@ -1322,6 +1861,7 @@ Init_Range(void)
rb_define_method(rb_cRange, "hash", range_hash, 0);
rb_define_method(rb_cRange, "each", range_each, 0);
rb_define_method(rb_cRange, "step", range_step, -1);
+ rb_define_method(rb_cRange, "%", range_percent_step, 1);
rb_define_method(rb_cRange, "bsearch", range_bsearch, 0);
rb_define_method(rb_cRange, "begin", range_begin, 0);
rb_define_method(rb_cRange, "end", range_end, 0);
@@ -1329,7 +1869,10 @@ Init_Range(void)
rb_define_method(rb_cRange, "last", range_last, -1);
rb_define_method(rb_cRange, "min", range_min, -1);
rb_define_method(rb_cRange, "max", range_max, -1);
+ rb_define_method(rb_cRange, "minmax", range_minmax, 0);
rb_define_method(rb_cRange, "size", range_size, 0);
+ rb_define_method(rb_cRange, "to_a", range_to_a, 0);
+ rb_define_method(rb_cRange, "entries", range_to_a, 0);
rb_define_method(rb_cRange, "to_s", range_to_s, 0);
rb_define_method(rb_cRange, "inspect", range_inspect, 0);
@@ -1338,4 +1881,5 @@ Init_Range(void)
rb_define_method(rb_cRange, "member?", range_include, 1);
rb_define_method(rb_cRange, "include?", range_include, 1);
rb_define_method(rb_cRange, "cover?", range_cover, 1);
+ rb_define_method(rb_cRange, "count", range_count, -1);
}
diff --git a/rational.c b/rational.c
index ce95facda0..d621773838 100644
--- a/rational.c
+++ b/rational.c
@@ -5,69 +5,72 @@
which is written in ruby.
*/
-#include "internal.h"
-#include "id.h"
-#include <math.h>
+#include "ruby/internal/config.h"
+
+#include <ctype.h>
#include <float.h>
+#include <math.h>
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
-#define NDEBUG
-#include "ruby_assert.h"
-
#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
#define USE_GMP
#include <gmp.h>
#endif
+#undef NDEBUG
+#define NDEBUG
+#include "id.h"
+#include "internal.h"
+#include "internal/array.h"
+#include "internal/complex.h"
+#include "internal/gc.h"
+#include "internal/numeric.h"
+#include "internal/object.h"
+#include "internal/rational.h"
+#include "ruby_assert.h"
+
#define ZERO INT2FIX(0)
#define ONE INT2FIX(1)
#define TWO INT2FIX(2)
#define GMP_GCD_DIGITS 1
-#define INT_POSITIVE_P(x) (FIXNUM_P(x) ? FIXNUM_POSITIVE_P(x) : BIGNUM_POSITIVE_P(x))
#define INT_ZERO_P(x) (FIXNUM_P(x) ? FIXNUM_ZERO_P(x) : rb_bigzero_p(x))
VALUE rb_cRational;
-static ID id_abs, id_idiv, id_integer_p, id_to_i,
+static ID id_abs, id_integer_p,
id_i_num, id_i_den;
+#define id_idiv idDiv
+#define id_to_i idTo_i
+
#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
#define f_inspect rb_inspect
#define f_to_s rb_obj_as_string
-#define binop(n,op) \
-inline static VALUE \
-f_##n(VALUE x, VALUE y)\
-{\
- return rb_funcall(x, (op), 1, y);\
-}
-
-#define fun1(n) \
-inline static VALUE \
-f_##n(VALUE x)\
-{\
- return rb_funcall(x, id_##n, 0);\
-}
+static VALUE nurat_to_f(VALUE self);
+static VALUE float_to_r(VALUE self);
inline static VALUE
f_add(VALUE x, VALUE y)
{
- if (FIXNUM_P(y) && FIXNUM_ZERO_P(y))
+ if (FIXNUM_ZERO_P(y))
return x;
- else if (FIXNUM_P(x) && FIXNUM_ZERO_P(x))
+ if (FIXNUM_ZERO_P(x))
return y;
+ if (RB_INTEGER_TYPE_P(x))
+ return rb_int_plus(x, y);
return rb_funcall(x, '+', 1, y);
}
inline static VALUE
f_div(VALUE x, VALUE y)
{
- if (FIXNUM_P(y) && FIX2LONG(y) == 1)
+ if (y == ONE)
return x;
if (RB_INTEGER_TYPE_P(x))
return rb_int_div(x, y);
@@ -79,37 +82,34 @@ f_lt_p(VALUE x, VALUE y)
{
if (FIXNUM_P(x) && FIXNUM_P(y))
return (SIGNED_VALUE)x < (SIGNED_VALUE)y;
+ if (RB_INTEGER_TYPE_P(x)) {
+ VALUE r = rb_int_cmp(x, y);
+ if (!NIL_P(r)) return rb_int_negative_p(r);
+ }
return RTEST(rb_funcall(x, '<', 1, y));
}
#ifndef NDEBUG
/* f_mod is used only in f_gcd defined when NDEBUG is not defined */
-binop(mod, '%')
+inline static VALUE
+f_mod(VALUE x, VALUE y)
+{
+ if (RB_INTEGER_TYPE_P(x))
+ return rb_int_modulo(x, y);
+ return rb_funcall(x, '%', 1, y);
+}
#endif
inline static VALUE
f_mul(VALUE x, VALUE y)
{
- if (FIXNUM_P(y)) {
- long iy = FIX2LONG(y);
- if (iy == 0) {
- if (RB_INTEGER_TYPE_P(x))
- return ZERO;
- }
- else if (iy == 1)
- return x;
- }
- else if (FIXNUM_P(x)) {
- long ix = FIX2LONG(x);
- if (ix == 0) {
- if (RB_INTEGER_TYPE_P(y))
- return ZERO;
- }
- else if (ix == 1)
- return y;
- return rb_int_mul(x, y);
- }
- else if (RB_TYPE_P(x, T_BIGNUM))
+ if (FIXNUM_ZERO_P(y) && RB_INTEGER_TYPE_P(x))
+ return ZERO;
+ if (y == ONE) return x;
+ if (FIXNUM_ZERO_P(x) && RB_INTEGER_TYPE_P(y))
+ return ZERO;
+ if (x == ONE) return y;
+ else if (RB_INTEGER_TYPE_P(x))
return rb_int_mul(x, y);
return rb_funcall(x, '*', 1, y);
}
@@ -130,7 +130,12 @@ f_abs(VALUE x)
return rb_funcall(x, id_abs, 0);
}
-fun1(integer_p)
+
+inline static VALUE
+f_integer_p(VALUE x)
+{
+ return RB_INTEGER_TYPE_P(x);
+}
inline static VALUE
f_to_i(VALUE x)
@@ -140,11 +145,13 @@ f_to_i(VALUE x)
return rb_funcall(x, id_to_i, 0);
}
-inline static VALUE
+inline static int
f_eqeq_p(VALUE x, VALUE y)
{
if (FIXNUM_P(x) && FIXNUM_P(y))
return x == y;
+ if (RB_INTEGER_TYPE_P(x))
+ return RTEST(rb_int_equal(x, y));
return (int)rb_equal(x, y);
}
@@ -400,16 +407,14 @@ f_lcm(VALUE x, VALUE y)
#define get_dat2(x,y) \
struct RRational *adat = RRATIONAL(x), *bdat = RRATIONAL(y)
-#define RRATIONAL_SET_NUM(rat, n) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->num,(n))
-#define RRATIONAL_SET_DEN(rat, d) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->den,(d))
-
inline static VALUE
nurat_s_new_internal(VALUE klass, VALUE num, VALUE den)
{
NEWOBJ_OF(obj, struct RRational, klass, T_RATIONAL | (RGENGC_WB_PROTECTED_RATIONAL ? FL_WB_PROTECTED : 0));
- RRATIONAL_SET_NUM(obj, num);
- RRATIONAL_SET_DEN(obj, den);
+ RATIONAL_SET_NUM((VALUE)obj, num);
+ RATIONAL_SET_DEN((VALUE)obj, den);
+ OBJ_FREEZE_RAW((VALUE)obj);
return (VALUE)obj;
}
@@ -420,60 +425,12 @@ nurat_s_alloc(VALUE klass)
return nurat_s_new_internal(klass, ZERO, ONE);
}
-#if 0
-static VALUE
-nurat_s_new_bang(int argc, VALUE *argv, VALUE klass)
-{
- VALUE num, den;
-
- switch (rb_scan_args(argc, argv, "11", &num, &den)) {
- case 1:
- if (!k_integer_p(num))
- num = f_to_i(num);
- den = ONE;
- break;
- default:
- if (!k_integer_p(num))
- num = f_to_i(num);
- if (!k_integer_p(den))
- den = f_to_i(den);
-
- if (INT_NEGATIVE_P(den)) {
- num = rb_int_uminus(num);
- den = rb_int_uminus(den);
- }
- else if (INT_ZERO_P(den)) {
- rb_num_zerodiv();
- }
- break;
- }
-
- return nurat_s_new_internal(klass, num, den);
-}
-#endif
-
inline static VALUE
f_rational_new_bang1(VALUE klass, VALUE x)
{
return nurat_s_new_internal(klass, x, ONE);
}
-#ifdef CANONICALIZATION_FOR_MATHN
-#define CANON
-#endif
-
-#ifdef CANON
-static int canonicalization = 0;
-
-RUBY_FUNC_EXPORTED void
-nurat_canonicalization(int f)
-{
- canonicalization = f;
-}
-#else
-# define canonicalization 0
-#endif
-
inline static void
nurat_int_check(VALUE num)
{
@@ -495,8 +452,8 @@ nurat_int_value(VALUE num)
static void
nurat_canonicalize(VALUE *num, VALUE *den)
{
- assert(num != NULL && RB_INTEGER_TYPE_P(*num));
- assert(den != NULL && RB_INTEGER_TYPE_P(*den));
+ assert(num); assert(RB_INTEGER_TYPE_P(*num));
+ assert(den); assert(RB_INTEGER_TYPE_P(*den));
if (INT_NEGATIVE_P(*den)) {
*num = rb_int_uminus(*num);
*den = rb_int_uminus(*den);
@@ -522,8 +479,6 @@ nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den)
nurat_canonicalize(&num, &den);
nurat_reduce(&num, &den);
- if (canonicalization && f_one_p(den))
- return num;
return nurat_s_new_internal(klass, num, den);
}
@@ -532,30 +487,9 @@ nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den)
{
nurat_canonicalize(&num, &den);
- if (canonicalization && f_one_p(den))
- return num;
return nurat_s_new_internal(klass, num, den);
}
-static VALUE
-nurat_s_new(int argc, VALUE *argv, VALUE klass)
-{
- VALUE num, den;
-
- switch (rb_scan_args(argc, argv, "11", &num, &den)) {
- case 1:
- num = nurat_int_value(num);
- den = ONE;
- break;
- default:
- num = nurat_int_value(num);
- den = nurat_int_value(den);
- break;
- }
-
- return nurat_s_canonicalize_internal(klass, num, den);
-}
-
inline static VALUE
f_rational_new2(VALUE klass, VALUE x, VALUE y)
{
@@ -572,11 +506,13 @@ f_rational_new_no_reduce2(VALUE klass, VALUE x, VALUE y)
return nurat_s_canonicalize_internal_no_reduce(klass, x, y);
}
+static VALUE nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise);
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass);
+
/*
* call-seq:
- * Rational(x, y) -> rational
- * Rational(arg) -> rational
+ * Rational(x, y, exception: true) -> rational or nil
+ * Rational(arg, exception: true) -> rational or nil
*
* Returns +x/y+ or +arg+ as a Rational.
*
@@ -592,6 +528,8 @@ static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass);
* Rational(nil) #=> TypeError
* Rational(1, nil) #=> TypeError
*
+ * Rational("10 cents", exception: false) #=> nil
+ *
* Syntax of the string form:
*
* string form = extra spaces , rational , extra spaces ;
@@ -611,7 +549,16 @@ static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass);
static VALUE
nurat_f_rational(int argc, VALUE *argv, VALUE klass)
{
- return nurat_s_convert(argc, argv, rb_cRational);
+ VALUE a1, a2, opts = Qnil;
+ int raise = TRUE;
+
+ if (rb_scan_args(argc, argv, "11:", &a1, &a2, &opts) == 1) {
+ a2 = Qundef;
+ }
+ if (!NIL_P(opts)) {
+ raise = rb_opts_exception_p(opts, raise);
+ }
+ return nurat_convert(rb_cRational, a1, a2, raise);
}
/*
@@ -729,7 +676,8 @@ f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
a = rb_int_idiv(bden, g);
den = rb_int_mul(a, b);
}
- else {
+ else if (RB_INTEGER_TYPE_P(anum) && RB_INTEGER_TYPE_P(aden) &&
+ RB_INTEGER_TYPE_P(bnum) && RB_INTEGER_TYPE_P(bden)) {
VALUE g = f_gcd(aden, bden);
VALUE a = rb_int_mul(anum, rb_int_idiv(bden, g));
VALUE b = rb_int_mul(bnum, rb_int_idiv(aden, g));
@@ -746,6 +694,12 @@ f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
a = rb_int_idiv(bden, g);
den = rb_int_mul(a, b);
}
+ else {
+ double a = NUM2DBL(anum) / NUM2DBL(aden);
+ double b = NUM2DBL(bnum) / NUM2DBL(bden);
+ double c = k == '+' ? a + b : a - b;
+ return DBL2NUM(c);
+ }
return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
}
@@ -803,8 +757,8 @@ rb_rational_plus(VALUE self, VALUE other)
* Rational(9, 8) - 4 #=> (-23/8)
* Rational(20, 9) - 9.8 #=> -7.577777777777778
*/
-static VALUE
-nurat_sub(VALUE self, VALUE other)
+VALUE
+rb_rational_minus(VALUE self, VALUE other)
{
if (RB_INTEGER_TYPE_P(other)) {
{
@@ -838,6 +792,16 @@ f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
VALUE num, den;
assert(RB_TYPE_P(self, T_RATIONAL));
+
+ /* Integer#** can return Rational with Float right now */
+ if (RB_FLOAT_TYPE_P(anum) || RB_FLOAT_TYPE_P(aden) ||
+ RB_FLOAT_TYPE_P(bnum) || RB_FLOAT_TYPE_P(bden)) {
+ double an = NUM2DBL(anum), ad = NUM2DBL(aden);
+ double bn = NUM2DBL(bnum), bd = NUM2DBL(bden);
+ double x = (an * bn) / (ad * bd);
+ return DBL2NUM(x);
+ }
+
assert(RB_INTEGER_TYPE_P(anum));
assert(RB_INTEGER_TYPE_P(aden));
assert(RB_INTEGER_TYPE_P(bnum));
@@ -889,8 +853,8 @@ f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
* Rational(9, 8) * 4 #=> (9/2)
* Rational(20, 9) * 9.8 #=> 21.77777777777778
*/
-static VALUE
-nurat_mul(VALUE self, VALUE other)
+VALUE
+rb_rational_mul(VALUE self, VALUE other)
{
if (RB_INTEGER_TYPE_P(other)) {
{
@@ -931,8 +895,8 @@ nurat_mul(VALUE self, VALUE other)
* Rational(9, 8) / 4 #=> (9/32)
* Rational(20, 9) / 9.8 #=> 0.22675736961451246
*/
-static VALUE
-nurat_div(VALUE self, VALUE other)
+VALUE
+rb_rational_div(VALUE self, VALUE other)
{
if (RB_INTEGER_TYPE_P(other)) {
if (f_zero_p(other))
@@ -945,8 +909,10 @@ nurat_div(VALUE self, VALUE other)
other, ONE, '/');
}
}
- else if (RB_FLOAT_TYPE_P(other))
- return DBL2NUM(nurat_to_double(self) / RFLOAT_VALUE(other));
+ else if (RB_FLOAT_TYPE_P(other)) {
+ VALUE v = nurat_to_f(self);
+ return rb_flo_div_flo(v, other);
+ }
else if (RB_TYPE_P(other, T_RATIONAL)) {
if (f_zero_p(other))
rb_num_zerodiv();
@@ -967,8 +933,6 @@ nurat_div(VALUE self, VALUE other)
}
}
-static VALUE nurat_to_f(VALUE self);
-
/*
* call-seq:
* rat.fdiv(numeric) -> float
@@ -984,24 +948,15 @@ nurat_fdiv(VALUE self, VALUE other)
{
VALUE div;
if (f_zero_p(other))
- return DBL2NUM(nurat_to_double(self) / 0.0);
+ return rb_rational_div(self, rb_float_new(0.0));
if (FIXNUM_P(other) && other == LONG2FIX(1))
return nurat_to_f(self);
- div = nurat_div(self, other);
+ div = rb_rational_div(self, other);
if (RB_TYPE_P(div, T_RATIONAL))
return nurat_to_f(div);
if (RB_FLOAT_TYPE_P(div))
return div;
- return rb_funcall(div, rb_intern("to_f"), 0);
-}
-
-inline static VALUE
-f_odd_p(VALUE integer)
-{
- if (rb_funcall(integer, '%', 1, INT2FIX(2)) != INT2FIX(0)) {
- return Qtrue;
- }
- return Qfalse;
+ return rb_funcall(div, idTo_f, 0);
}
/*
@@ -1017,8 +972,8 @@ f_odd_p(VALUE integer)
* Rational(1, 2) ** 0 #=> (1/1)
* Rational(1, 2) ** 0.0 #=> 1.0
*/
-static VALUE
-nurat_expt(VALUE self, VALUE other)
+VALUE
+rb_rational_pow(VALUE self, VALUE other)
{
if (k_numeric_p(other) && k_exact_zero_p(other))
return f_rational_new_bang1(CLASS_OF(self), ONE);
@@ -1038,7 +993,7 @@ nurat_expt(VALUE self, VALUE other)
return f_rational_new_bang1(CLASS_OF(self), ONE);
}
else if (f_minus_one_p(dat->num) && RB_INTEGER_TYPE_P(other)) {
- return f_rational_new_bang1(CLASS_OF(self), INT2FIX(f_odd_p(other) ? -1 : 1));
+ return f_rational_new_bang1(CLASS_OF(self), INT2FIX(rb_int_odd_p(other) ? -1 : 1));
}
else if (INT_ZERO_P(dat->num)) {
if (rb_num_negative_p(other)) {
@@ -1071,7 +1026,8 @@ nurat_expt(VALUE self, VALUE other)
den = ONE;
}
if (RB_FLOAT_TYPE_P(num)) { /* infinity due to overflow */
- if (RB_FLOAT_TYPE_P(den)) return DBL2NUM(NAN);
+ if (RB_FLOAT_TYPE_P(den))
+ return DBL2NUM(nan(""));
return num;
}
if (RB_FLOAT_TYPE_P(den)) { /* infinity due to overflow */
@@ -1092,6 +1048,7 @@ nurat_expt(VALUE self, VALUE other)
return rb_num_coerce_bin(self, other, rb_intern("**"));
}
}
+#define nurat_expt rb_rational_pow
/*
* call-seq:
@@ -1113,21 +1070,19 @@ nurat_expt(VALUE self, VALUE other)
VALUE
rb_rational_cmp(VALUE self, VALUE other)
{
- if (RB_INTEGER_TYPE_P(other)) {
+ switch (TYPE(other)) {
+ case T_FIXNUM:
+ case T_BIGNUM:
{
get_dat1(self);
if (dat->den == LONG2FIX(1))
return rb_int_cmp(dat->num, other); /* c14n */
other = f_rational_new_bang1(CLASS_OF(self), other);
- goto other_is_rational;
+ /* FALLTHROUGH */
}
- }
- else if (RB_FLOAT_TYPE_P(other)) {
- return rb_dbl_cmp(nurat_to_double(self), RFLOAT_VALUE(other));
- }
- else if (RB_TYPE_P(other, T_RATIONAL)) {
- other_is_rational:
+
+ case T_RATIONAL:
{
VALUE num1, num2;
@@ -1144,8 +1099,11 @@ rb_rational_cmp(VALUE self, VALUE other)
}
return rb_int_cmp(rb_int_minus(num1, num2), ZERO);
}
- }
- else {
+
+ case T_FLOAT:
+ return rb_dbl_cmp(nurat_to_double(self), RFLOAT_VALUE(other));
+
+ default:
return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
}
}
@@ -1166,9 +1124,9 @@ static VALUE
nurat_eqeq_p(VALUE self, VALUE other)
{
if (RB_INTEGER_TYPE_P(other)) {
- {
- get_dat1(self);
+ get_dat1(self);
+ if (RB_INTEGER_TYPE_P(dat->num) && RB_INTEGER_TYPE_P(dat->den)) {
if (INT_ZERO_P(dat->num) && INT_ZERO_P(other))
return Qtrue;
@@ -1178,6 +1136,10 @@ nurat_eqeq_p(VALUE self, VALUE other)
return Qfalse;
return rb_int_equal(dat->num, other);
}
+ else {
+ const double d = nurat_to_double(self);
+ return f_boolcast(FIXNUM_ZERO_P(rb_dbl_cmp(d, NUM2DBL(other))));
+ }
}
else if (RB_FLOAT_TYPE_P(other)) {
const double d = nurat_to_double(self);
@@ -1213,11 +1175,17 @@ nurat_coerce(VALUE self, VALUE other)
return rb_assoc_new(other, self);
}
else if (RB_TYPE_P(other, T_COMPLEX)) {
- if (k_exact_zero_p(RCOMPLEX(other)->imag))
- return rb_assoc_new(f_rational_new_bang1
- (CLASS_OF(self), RCOMPLEX(other)->real), self);
- else
+ if (!k_exact_zero_p(RCOMPLEX(other)->imag))
return rb_assoc_new(other, rb_Complex(self, INT2FIX(0)));
+ other = RCOMPLEX(other)->real;
+ if (RB_FLOAT_TYPE_P(other)) {
+ other = float_to_r(other);
+ RBASIC_SET_CLASS(other, CLASS_OF(self));
+ }
+ else {
+ other = f_rational_new_bang1(CLASS_OF(self), other);
+ }
+ return rb_assoc_new(other, self);
}
rb_raise(rb_eTypeError, "%s can't be coerced into %s",
@@ -1225,39 +1193,6 @@ nurat_coerce(VALUE self, VALUE other)
return Qnil;
}
-#if 0
-/* :nodoc: */
-static VALUE
-nurat_idiv(VALUE self, VALUE other)
-{
- return f_idiv(self, other);
-}
-
-/* :nodoc: */
-static VALUE
-nurat_quot(VALUE self, VALUE other)
-{
- return f_truncate(f_div(self, other));
-}
-
-/* :nodoc: */
-static VALUE
-nurat_quotrem(VALUE self, VALUE other)
-{
- VALUE val = f_truncate(f_div(self, other));
- return rb_assoc_new(val, f_sub(self, f_mul(other, val)));
-}
-#endif
-
-#if 0
-/* :nodoc: */
-static VALUE
-nurat_true(VALUE self)
-{
- return Qtrue;
-}
-#endif
-
/*
* call-seq:
* rat.positive? -> true or false
@@ -1426,16 +1361,16 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
{
VALUE n, b, s;
- if (argc == 0)
+ if (rb_check_arity(argc, 0, 1) == 0)
return (*func)(self);
- rb_scan_args(argc, argv, "01", &n);
+ n = argv[0];
if (!k_integer_p(n))
rb_raise(rb_eTypeError, "not an integer");
b = f_expt10(n);
- s = nurat_mul(self, b);
+ s = rb_rational_mul(self, b);
if (k_float_p(s)) {
if (INT_NEGATIVE_P(n))
@@ -1449,7 +1384,7 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
s = (*func)(s);
- s = nurat_div(f_rational_new_bang1(CLASS_OF(self), s), b);
+ s = rb_rational_div(f_rational_new_bang1(CLASS_OF(self), s), b);
if (RB_TYPE_P(s, T_RATIONAL) && FIX2INT(rb_int_cmp(n, ONE)) < 0)
s = nurat_truncate(s);
@@ -1457,6 +1392,18 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
return s;
}
+VALUE
+rb_rational_floor(VALUE self, int ndigits)
+{
+ if (ndigits == 0) {
+ return nurat_floor(self);
+ }
+ else {
+ VALUE n = INT2NUM(ndigits);
+ return f_round_common(1, &n, self, nurat_floor);
+ }
+}
+
/*
* call-seq:
* rat.floor([ndigits]) -> integer or rational
@@ -1589,7 +1536,7 @@ nurat_round_n(int argc, VALUE *argv, VALUE self)
{
VALUE opt;
enum ruby_num_rounding_mode mode = (
- argc = rb_scan_args(argc, argv, "*:", NULL, &opt),
+ argc = rb_scan_args(argc, argv, "*:", NULL, &opt),
rb_num_get_rounding_option(opt));
VALUE (*round_func)(VALUE) = ROUND_FUNC(mode, nurat_round);
return f_round_common(argc, argv, self, round_func);
@@ -1599,6 +1546,9 @@ static double
nurat_to_double(VALUE self)
{
get_dat1(self);
+ if (!RB_INTEGER_TYPE_P(dat->num) || !RB_INTEGER_TYPE_P(dat->den)) {
+ return NUM2DBL(dat->num) / NUM2DBL(dat->den);
+ }
return rb_int_fdiv_double(dat->num, dat->den);
}
@@ -1635,10 +1585,28 @@ nurat_to_r(VALUE self)
}
#define id_ceil rb_intern("ceil")
-#define f_ceil(x) rb_funcall((x), id_ceil, 0)
+static VALUE
+f_ceil(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x))
+ return x;
+ if (RB_FLOAT_TYPE_P(x))
+ return rb_float_ceil(x, 0);
-#define id_quo rb_intern("quo")
-#define f_quo(x,y) rb_funcall((x), id_quo, 1, (y))
+ return rb_funcall(x, id_ceil, 0);
+}
+
+#define id_quo idQuo
+static VALUE
+f_quo(VALUE x, VALUE y)
+{
+ if (RB_INTEGER_TYPE_P(x))
+ return rb_int_div(x, y);
+ if (RB_FLOAT_TYPE_P(x))
+ return DBL2NUM(RFLOAT_VALUE(x) / RFLOAT_VALUE(y));
+
+ return rb_funcallv(x, id_quo, 1, &y);
+}
#define f_reciprocal(x) f_quo(ONE, (x))
@@ -1748,28 +1716,36 @@ static VALUE
nurat_rationalize(int argc, VALUE *argv, VALUE self)
{
VALUE e, a, b, p, q;
+ VALUE rat = self;
+ get_dat1(self);
- if (argc == 0)
+ if (rb_check_arity(argc, 0, 1) == 0)
return self;
- if (nurat_negative_p(self))
- return rb_rational_uminus(nurat_rationalize(argc, argv, rb_rational_uminus(self)));
+ e = f_abs(argv[0]);
- rb_scan_args(argc, argv, "01", &e);
- e = f_abs(e);
- a = f_sub(self, e);
- b = f_add(self, e);
+ if (INT_NEGATIVE_P(dat->num)) {
+ rat = f_rational_new2(RBASIC_CLASS(self), rb_int_uminus(dat->num), dat->den);
+ }
+
+ a = FIXNUM_ZERO_P(e) ? rat : rb_rational_minus(rat, e);
+ b = FIXNUM_ZERO_P(e) ? rat : rb_rational_plus(rat, e);
if (f_eqeq_p(a, b))
return self;
nurat_rationalize_internal(a, b, &p, &q);
+ if (rat != self) {
+ RATIONAL_SET_NUM(rat, rb_int_uminus(p));
+ RATIONAL_SET_DEN(rat, q);
+ return rat;
+ }
return f_rational_new2(CLASS_OF(self), p, q);
}
/* :nodoc: */
-static VALUE
-nurat_hash(VALUE self)
+st_index_t
+rb_rational_hash(VALUE self)
{
st_index_t v, h[2];
VALUE n;
@@ -1780,10 +1756,17 @@ nurat_hash(VALUE self)
n = rb_hash(dat->den);
h[1] = NUM2LONG(n);
v = rb_memhash(h, sizeof(h));
- return LONG2FIX(v);
+ return v;
}
static VALUE
+nurat_hash(VALUE self)
+{
+ return ST2FIX(rb_rational_hash(self));
+}
+
+
+static VALUE
f_format(VALUE self, VALUE (*func)(VALUE))
{
VALUE s;
@@ -1853,8 +1836,9 @@ nurat_loader(VALUE self, VALUE a)
nurat_int_check(num);
nurat_int_check(den);
nurat_canonicalize(&num, &den);
- RRATIONAL_SET_NUM(dat, num);
- RRATIONAL_SET_DEN(dat, den);
+ RATIONAL_SET_NUM((VALUE)dat, num);
+ RATIONAL_SET_DEN((VALUE)dat, den);
+ OBJ_FREEZE_RAW(self);
return self;
}
@@ -1878,7 +1862,6 @@ nurat_marshal_load(VALUE self, VALUE a)
VALUE num, den;
rb_check_frozen(self);
- rb_check_trusted(self);
Check_Type(a, T_ARRAY);
if (RARRAY_LEN(a) != 2)
@@ -1901,7 +1884,7 @@ VALUE
rb_rational_reciprocal(VALUE x)
{
get_dat1(x);
- return f_rational_new_no_reduce2(CLASS_OF(x), dat->den, dat->num);
+ return nurat_convert(CLASS_OF(x), dat->den, dat->num, FALSE);
}
/*
@@ -1964,6 +1947,14 @@ rb_gcdlcm(VALUE self, VALUE other)
VALUE
rb_rational_raw(VALUE x, VALUE y)
{
+ if (! RB_INTEGER_TYPE_P(x))
+ x = rb_to_int(x);
+ if (! RB_INTEGER_TYPE_P(y))
+ y = rb_to_int(y);
+ if (INT_NEGATIVE_P(y)) {
+ x = rb_int_uminus(x);
+ y = rb_int_uminus(y);
+ }
return nurat_s_new_internal(rb_cRational, x, y);
}
@@ -2000,7 +1991,7 @@ rb_rational_den(VALUE rat)
#define id_denominator rb_intern("denominator")
#define f_denominator(x) rb_funcall((x), id_denominator, 0)
-#define id_to_r rb_intern("to_r")
+#define id_to_r idTo_r
#define f_to_r(x) rb_funcall((x), id_to_r, 0)
/*
@@ -2039,19 +2030,27 @@ numeric_denominator(VALUE self)
VALUE
rb_numeric_quo(VALUE x, VALUE y)
{
- if (RB_FLOAT_TYPE_P(y)) {
- return rb_funcall(x, rb_intern("fdiv"), 1, y);
+ if (RB_TYPE_P(x, T_COMPLEX)) {
+ return rb_complex_div(x, y);
}
- if (canonicalization) {
- x = rb_rational_raw1(x);
- }
- else {
- x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
+ if (RB_FLOAT_TYPE_P(y)) {
+ return rb_funcallv(x, idFdiv, 1, &y);
}
- return nurat_div(x, y);
+
+ x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
+ return rb_rational_div(x, y);
}
+VALUE
+rb_rational_canonicalize(VALUE x)
+{
+ if (RB_TYPE_P(x, T_RATIONAL)) {
+ get_dat1(x);
+ if (f_one_p(dat->den)) return dat->num;
+ }
+ return x;
+}
/*
* call-seq:
@@ -2077,7 +2076,6 @@ integer_denominator(VALUE self)
return INT2FIX(1);
}
-static VALUE float_to_r(VALUE self);
/*
* call-seq:
* flo.numerator -> integer
@@ -2090,17 +2088,14 @@ static VALUE float_to_r(VALUE self);
*
* See also Float#denominator.
*/
-static VALUE
-float_numerator(VALUE self)
+VALUE
+rb_float_numerator(VALUE self)
{
double d = RFLOAT_VALUE(self);
VALUE r;
if (isinf(d) || isnan(d))
return self;
r = float_to_r(self);
- if (canonicalization && k_integer_p(r)) {
- return r;
- }
return nurat_numerator(r);
}
@@ -2113,17 +2108,14 @@ float_numerator(VALUE self)
*
* See also Float#numerator.
*/
-static VALUE
-float_denominator(VALUE self)
+VALUE
+rb_float_denominator(VALUE self)
{
double d = RFLOAT_VALUE(self);
VALUE r;
if (isinf(d) || isnan(d))
return INT2FIX(1);
r = float_to_r(self);
- if (canonicalization && k_integer_p(r)) {
- return ONE;
- }
return nurat_denominator(r);
}
@@ -2149,7 +2141,7 @@ nilclass_to_r(VALUE self)
static VALUE
nilclass_rationalize(int argc, VALUE *argv, VALUE self)
{
- rb_scan_args(argc, argv, "01", NULL);
+ rb_check_arity(argc, 0, 1);
return nilclass_to_r(self);
}
@@ -2178,33 +2170,20 @@ integer_to_r(VALUE self)
static VALUE
integer_rationalize(int argc, VALUE *argv, VALUE self)
{
- rb_scan_args(argc, argv, "01", NULL);
+ rb_check_arity(argc, 0, 1);
return integer_to_r(self);
}
static void
-float_decode_internal(VALUE self, VALUE *rf, VALUE *rn)
+float_decode_internal(VALUE self, VALUE *rf, int *n)
{
double f;
- int n;
- f = frexp(RFLOAT_VALUE(self), &n);
+ f = frexp(RFLOAT_VALUE(self), n);
f = ldexp(f, DBL_MANT_DIG);
- n -= DBL_MANT_DIG;
+ *n -= DBL_MANT_DIG;
*rf = rb_dbl2big(f);
- *rn = INT2FIX(n);
-}
-
-#if 0
-static VALUE
-float_decode(VALUE self)
-{
- VALUE f, n;
-
- float_decode_internal(self, &f, &n);
- return rb_assoc_new(f, n);
}
-#endif
/*
* call-seq:
@@ -2229,20 +2208,17 @@ float_decode(VALUE self)
static VALUE
float_to_r(VALUE self)
{
- VALUE f, n;
+ VALUE f;
+ int n;
float_decode_internal(self, &f, &n);
#if FLT_RADIX == 2
- {
- long ln = FIX2LONG(n);
-
- if (ln == 0)
- return rb_rational_new1(f);
- if (ln > 0)
- return rb_rational_new1(rb_int_lshift(f, n));
- ln = -ln;
- return rb_rational_new2(f, rb_int_lshift(ONE, INT2FIX(ln)));
- }
+ if (n == 0)
+ return rb_rational_new1(f);
+ if (n > 0)
+ return rb_rational_new1(rb_int_lshift(f, INT2FIX(n)));
+ n = -n;
+ return rb_rational_new2(f, rb_int_lshift(ONE, INT2FIX(n)));
#else
f = rb_int_mul(f, rb_int_pow(INT2FIX(FLT_RADIX), n));
if (RB_TYPE_P(f, T_RATIONAL))
@@ -2270,37 +2246,32 @@ rb_flt_rationalize_with_prec(VALUE flt, VALUE prec)
VALUE
rb_flt_rationalize(VALUE flt)
{
- VALUE a, b, f, n, p, q;
+ VALUE a, b, f, p, q, den;
+ int n;
float_decode_internal(flt, &f, &n);
- if (INT_ZERO_P(f) || FIX2INT(n) >= 0)
- return rb_rational_new1(rb_int_lshift(f, n));
+ if (INT_ZERO_P(f) || n >= 0)
+ return rb_rational_new1(rb_int_lshift(f, INT2FIX(n)));
-#if FLT_RADIX == 2
{
- VALUE two_times_f, den;
-
- two_times_f = rb_int_mul(TWO, f);
- den = rb_int_lshift(ONE, rb_int_minus(ONE, n));
-
- a = rb_rational_new2(rb_int_minus(two_times_f, ONE), den);
- b = rb_rational_new2(rb_int_plus(two_times_f, ONE), den);
- }
-#else
- {
- VALUE radix_times_f, den;
+ VALUE radix_times_f;
radix_times_f = rb_int_mul(INT2FIX(FLT_RADIX), f);
- den = rb_int_pow(INT2FIX(FLT_RADIX), rb_int_minus(ONE, n));
+#if FLT_RADIX == 2 && 0
+ den = rb_int_lshift(ONE, INT2FIX(1-n));
+#else
+ den = rb_int_positive_pow(FLT_RADIX, 1-n);
+#endif
- a = rb_rational_new2(rb_int_minus(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
- b = rb_rational_new2(rb_int_plus(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
+ a = rb_int_minus(radix_times_f, INT2FIX(FLT_RADIX - 1));
+ b = rb_int_plus(radix_times_f, INT2FIX(FLT_RADIX - 1));
}
-#endif
- if (nurat_eqeq_p(a, b))
+ if (f_eqeq_p(a, b))
return float_to_r(flt);
+ a = rb_rational_new2(a, den);
+ b = rb_rational_new2(b, den);
nurat_rationalize_internal(a, b, &p, &q);
return rb_rational_new2(p, q);
}
@@ -2322,24 +2293,21 @@ rb_flt_rationalize(VALUE flt)
static VALUE
float_rationalize(int argc, VALUE *argv, VALUE self)
{
- VALUE e;
double d = RFLOAT_VALUE(self);
+ VALUE rat;
+ int neg = d < 0.0;
+ if (neg) self = DBL2NUM(-d);
- if (d < 0.0)
- return rb_rational_uminus(float_rationalize(argc, argv, DBL2NUM(-d)));
-
- rb_scan_args(argc, argv, "01", &e);
-
- if (argc != 0) {
- return rb_flt_rationalize_with_prec(self, e);
+ if (rb_check_arity(argc, 0, 1)) {
+ rat = rb_flt_rationalize_with_prec(self, argv[0]);
}
else {
- return rb_flt_rationalize(self);
+ rat = rb_flt_rationalize(self);
}
+ if (neg) RATIONAL_SET_NUM(rat, rb_int_uminus(RRATIONAL(rat)->num));
+ return rat;
}
-#include <ctype.h>
-
inline static int
issign(int c)
{
@@ -2364,14 +2332,26 @@ islettere(int c)
return (c == 'e' || c == 'E');
}
+static VALUE
+negate_num(VALUE num)
+{
+ if (FIXNUM_P(num)) {
+ return rb_int_uminus(num);
+ }
+ else {
+ BIGNUM_NEGATE(num);
+ return rb_big_norm(num);
+ }
+}
+
static int
-read_num(const char **s, const char *const end, VALUE *num, VALUE *div)
+read_num(const char **s, const char *const end, VALUE *num, VALUE *nexp)
{
VALUE fp = ONE, exp, fn = ZERO, n = ZERO;
int expsign = 0, ok = 0;
char *e;
- *div = ONE;
+ *nexp = ZERO;
*num = ZERO;
if (*s < end && **s != '.') {
n = rb_int_parse_cstr(*s, end-*s, &e, NULL,
@@ -2393,10 +2373,9 @@ read_num(const char **s, const char *const end, VALUE *num, VALUE *div)
return 1;
*s = e;
{
- VALUE l = f_expt10(SIZET2NUM(count));
+ VALUE l = f_expt10(*nexp = SIZET2NUM(count));
n = n == ZERO ? fp : rb_int_plus(rb_int_mul(*num, l), fp);
*num = n;
- *div = l;
fn = SIZET2NUM(count);
}
ok = 1;
@@ -2413,18 +2392,12 @@ read_num(const char **s, const char *const end, VALUE *num, VALUE *div)
if (exp != ZERO) {
if (expsign == '-') {
if (fn != ZERO) exp = rb_int_plus(exp, fn);
- *div = f_expt10(exp);
}
else {
if (fn != ZERO) exp = rb_int_minus(exp, fn);
- if (INT_NEGATIVE_P(exp)) {
- *div = f_expt10(exp);
- }
- else {
- *num = rb_int_mul(n, f_expt10(exp));
- *div = ONE;
- }
+ exp = negate_num(exp);
}
+ *nexp = exp;
}
}
@@ -2440,74 +2413,93 @@ skip_ws(const char *s, const char *e)
}
static VALUE
-parse_rat(const char *s, const char *const e, int strict)
+parse_rat(const char *s, const char *const e, int strict, int raise)
{
int sign;
- VALUE num, den, ndiv, ddiv;
+ VALUE num, den, nexp, dexp;
s = skip_ws(s, e);
sign = read_sign(&s, e);
- if (!read_num(&s, e, &num, &ndiv)) {
+ if (!read_num(&s, e, &num, &nexp)) {
if (strict) return Qnil;
- return canonicalization ? ZERO : nurat_s_alloc(rb_cRational);
+ return nurat_s_alloc(rb_cRational);
}
- nurat_reduce(&num, &ndiv);
- den = ndiv;
+ den = ONE;
if (s < e && *s == '/') {
s++;
- if (!read_num(&s, e, &den, &ddiv)) {
+ if (!read_num(&s, e, &den, &dexp)) {
if (strict) return Qnil;
- den = ndiv;
+ den = ONE;
}
else if (den == ZERO) {
+ if (!raise) return Qnil;
rb_num_zerodiv();
}
else if (strict && skip_ws(s, e) != e) {
return Qnil;
}
else {
- nurat_reduce(&den, &ddiv);
+ nexp = rb_int_minus(nexp, dexp);
nurat_reduce(&num, &den);
- nurat_reduce(&ndiv, &ddiv);
- if (ndiv != ONE) den = rb_int_mul(den, ndiv);
- if (ddiv != ONE) num = rb_int_mul(num, ddiv);
}
}
else if (strict && skip_ws(s, e) != e) {
return Qnil;
}
+ if (nexp != ZERO) {
+ if (INT_NEGATIVE_P(nexp)) {
+ VALUE mul;
+ if (FIXNUM_P(nexp)) {
+ mul = f_expt10(LONG2NUM(-FIX2LONG(nexp)));
+ if (! RB_FLOAT_TYPE_P(mul)) {
+ num = rb_int_mul(num, mul);
+ goto reduce;
+ }
+ }
+ return sign == '-' ? DBL2NUM(-HUGE_VAL) : DBL2NUM(HUGE_VAL);
+ }
+ else {
+ VALUE div;
+ if (FIXNUM_P(nexp)) {
+ div = f_expt10(nexp);
+ if (! RB_FLOAT_TYPE_P(div)) {
+ den = rb_int_mul(den, div);
+ goto reduce;
+ }
+ }
+ return sign == '-' ? DBL2NUM(-0.0) : DBL2NUM(+0.0);
+ }
+ reduce:
+ nurat_reduce(&num, &den);
+ }
+
if (sign == '-') {
- if (FIXNUM_P(num)) {
- num = rb_int_uminus(num);
- }
- else {
- BIGNUM_NEGATE(num);
- num = rb_big_norm(num);
- }
+ num = negate_num(num);
}
- if (!canonicalization || den != ONE)
- num = rb_rational_raw(num, den);
- return num;
+ return rb_rational_raw(num, den);
}
static VALUE
-string_to_r_strict(VALUE self)
+string_to_r_strict(VALUE self, int raise)
{
VALUE num;
rb_must_asciicompat(self);
- num = parse_rat(RSTRING_PTR(self), RSTRING_END(self), 1);
+ num = parse_rat(RSTRING_PTR(self), RSTRING_END(self), 1, raise);
if (NIL_P(num)) {
- rb_raise(rb_eArgError, "invalid value for convert(): %+"PRIsVALUE,
- self);
+ if (!raise) return Qnil;
+ rb_raise(rb_eArgError, "invalid value for convert(): %+"PRIsVALUE,
+ self);
}
- if (RB_FLOAT_TYPE_P(num))
- rb_raise(rb_eFloatDomainError, "Infinity");
+ if (RB_FLOAT_TYPE_P(num) && !FLOAT_ZERO_P(num)) {
+ if (!raise) return Qnil;
+ rb_raise(rb_eFloatDomainError, "Infinity");
+ }
return num;
}
@@ -2546,9 +2538,9 @@ string_to_r(VALUE self)
rb_must_asciicompat(self);
- num = parse_rat(RSTRING_PTR(self), RSTRING_END(self), 0);
+ num = parse_rat(RSTRING_PTR(self), RSTRING_END(self), 0, TRUE);
- if (RB_FLOAT_TYPE_P(num))
+ if (RB_FLOAT_TYPE_P(num) && !FLOAT_ZERO_P(num))
rb_raise(rb_eFloatDomainError, "Infinity");
return num;
}
@@ -2558,73 +2550,163 @@ rb_cstr_to_rat(const char *s, int strict) /* for complex's internal */
{
VALUE num;
- num = parse_rat(s, s + strlen(s), strict);
+ num = parse_rat(s, s + strlen(s), strict, TRUE);
- if (RB_FLOAT_TYPE_P(num))
+ if (RB_FLOAT_TYPE_P(num) && !FLOAT_ZERO_P(num))
rb_raise(rb_eFloatDomainError, "Infinity");
return num;
}
static VALUE
-nurat_s_convert(int argc, VALUE *argv, VALUE klass)
+to_rational(VALUE val)
{
- VALUE a1, a2, backref;
+ return rb_convert_type_with_id(val, T_RATIONAL, "Rational", idTo_r);
+}
- rb_scan_args(argc, argv, "11", &a1, &a2);
+static VALUE
+nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise)
+{
+ VALUE a1 = numv, a2 = denv;
+ int state;
- if (NIL_P(a1) || (argc == 2 && NIL_P(a2)))
- rb_raise(rb_eTypeError, "can't convert nil into Rational");
+ assert(a1 != Qundef);
+
+ if (NIL_P(a1) || NIL_P(a2)) {
+ if (!raise) return Qnil;
+ rb_raise(rb_eTypeError, "can't convert nil into Rational");
+ }
if (RB_TYPE_P(a1, T_COMPLEX)) {
- if (k_exact_zero_p(RCOMPLEX(a1)->imag))
- a1 = RCOMPLEX(a1)->real;
+ if (k_exact_zero_p(RCOMPLEX(a1)->imag))
+ a1 = RCOMPLEX(a1)->real;
}
if (RB_TYPE_P(a2, T_COMPLEX)) {
- if (k_exact_zero_p(RCOMPLEX(a2)->imag))
- a2 = RCOMPLEX(a2)->real;
+ if (k_exact_zero_p(RCOMPLEX(a2)->imag))
+ a2 = RCOMPLEX(a2)->real;
}
- backref = rb_backref_get();
- rb_match_busy(backref);
-
- if (RB_FLOAT_TYPE_P(a1)) {
- a1 = float_to_r(a1);
+ if (RB_INTEGER_TYPE_P(a1)) {
+ // nothing to do
+ }
+ else if (RB_FLOAT_TYPE_P(a1)) {
+ a1 = float_to_r(a1);
+ }
+ else if (RB_TYPE_P(a1, T_RATIONAL)) {
+ // nothing to do
}
else if (RB_TYPE_P(a1, T_STRING)) {
- a1 = string_to_r_strict(a1);
+ a1 = string_to_r_strict(a1, raise);
+ if (!raise && NIL_P(a1)) return Qnil;
+ }
+ else if (!rb_respond_to(a1, idTo_r)) {
+ VALUE tmp = rb_protect(rb_check_to_int, a1, NULL);
+ rb_set_errinfo(Qnil);
+ if (!NIL_P(tmp)) {
+ a1 = tmp;
+ }
}
- if (RB_FLOAT_TYPE_P(a2)) {
- a2 = float_to_r(a2);
+ if (RB_INTEGER_TYPE_P(a2)) {
+ // nothing to do
+ }
+ else if (RB_FLOAT_TYPE_P(a2)) {
+ a2 = float_to_r(a2);
+ }
+ else if (RB_TYPE_P(a2, T_RATIONAL)) {
+ // nothing to do
}
else if (RB_TYPE_P(a2, T_STRING)) {
- a2 = string_to_r_strict(a2);
+ a2 = string_to_r_strict(a2, raise);
+ if (!raise && NIL_P(a2)) return Qnil;
+ }
+ else if (a2 != Qundef && !rb_respond_to(a2, idTo_r)) {
+ VALUE tmp = rb_protect(rb_check_to_int, a2, NULL);
+ rb_set_errinfo(Qnil);
+ if (!NIL_P(tmp)) {
+ a2 = tmp;
+ }
}
- rb_backref_set(backref);
-
if (RB_TYPE_P(a1, T_RATIONAL)) {
- if (argc == 1 || (k_exact_one_p(a2)))
- return a1;
+ if (a2 == Qundef || (k_exact_one_p(a2)))
+ return a1;
+ }
+
+ if (a2 == Qundef) {
+ if (!RB_INTEGER_TYPE_P(a1)) {
+ if (!raise) {
+ VALUE result = rb_protect(to_rational, a1, NULL);
+ rb_set_errinfo(Qnil);
+ return result;
+ }
+ return to_rational(a1);
+ }
+ }
+ else {
+ if (!k_numeric_p(a1)) {
+ if (!raise) {
+ a1 = rb_protect(to_rational, a1, &state);
+ if (state) {
+ rb_set_errinfo(Qnil);
+ return Qnil;
+ }
+ }
+ else {
+ a1 = rb_check_convert_type_with_id(a1, T_RATIONAL, "Rational", idTo_r);
+ }
+ }
+ if (!k_numeric_p(a2)) {
+ if (!raise) {
+ a2 = rb_protect(to_rational, a2, &state);
+ if (state) {
+ rb_set_errinfo(Qnil);
+ return Qnil;
+ }
+ }
+ else {
+ a2 = rb_check_convert_type_with_id(a2, T_RATIONAL, "Rational", idTo_r);
+ }
+ }
+ if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
+ (!f_integer_p(a1) || !f_integer_p(a2))) {
+ VALUE tmp = rb_protect(to_rational, a1, &state);
+ if (!state) {
+ a1 = tmp;
+ }
+ else {
+ rb_set_errinfo(Qnil);
+ }
+ return f_div(a1, a2);
+ }
}
- if (argc == 1) {
- if (!(k_numeric_p(a1) && k_integer_p(a1)))
- return rb_convert_type_with_id(a1, T_RATIONAL, "Rational", idTo_r);
+ a1 = nurat_int_value(a1);
+
+ if (a2 == Qundef) {
+ a2 = ONE;
+ }
+ else if (!k_integer_p(a2) && !raise) {
+ return Qnil;
}
else {
- if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
- (!f_integer_p(a1) || !f_integer_p(a2)))
- return f_div(a1, a2);
+ a2 = nurat_int_value(a2);
}
- {
- VALUE argv2[2];
- argv2[0] = a1;
- argv2[1] = a2;
- return nurat_s_new(argc, argv2, klass);
+
+ return nurat_s_canonicalize_internal(klass, a1, a2);
+}
+
+static VALUE
+nurat_s_convert(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE a1, a2;
+
+ if (rb_scan_args(argc, argv, "11", &a1, &a2) == 1) {
+ a2 = Qundef;
}
+
+ return nurat_convert(klass, a1, a2, TRUE);
}
/*
@@ -2673,29 +2755,17 @@ void
Init_Rational(void)
{
VALUE compat;
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
- assert(fprintf(stderr, "assert() is now active\n"));
-
- id_abs = rb_intern("abs");
- id_idiv = rb_intern("div");
- id_integer_p = rb_intern("integer?");
- id_to_i = rb_intern("to_i");
- id_i_num = rb_intern("@numerator");
- id_i_den = rb_intern("@denominator");
+ id_abs = rb_intern_const("abs");
+ id_integer_p = rb_intern_const("integer?");
+ id_i_num = rb_intern_const("@numerator");
+ id_i_den = rb_intern_const("@denominator");
rb_cRational = rb_define_class("Rational", rb_cNumeric);
rb_define_alloc_func(rb_cRational, nurat_s_alloc);
rb_undef_method(CLASS_OF(rb_cRational), "allocate");
-#if 0
- rb_define_private_method(CLASS_OF(rb_cRational), "new!", nurat_s_new_bang, -1);
- rb_define_private_method(CLASS_OF(rb_cRational), "new", nurat_s_new, -1);
-#else
rb_undef_method(CLASS_OF(rb_cRational), "new");
-#endif
rb_define_global_function("Rational", nurat_f_rational, -1);
@@ -2704,10 +2774,10 @@ Init_Rational(void)
rb_define_method(rb_cRational, "-@", rb_rational_uminus, 0);
rb_define_method(rb_cRational, "+", rb_rational_plus, 1);
- rb_define_method(rb_cRational, "-", nurat_sub, 1);
- rb_define_method(rb_cRational, "*", nurat_mul, 1);
- rb_define_method(rb_cRational, "/", nurat_div, 1);
- rb_define_method(rb_cRational, "quo", nurat_div, 1);
+ rb_define_method(rb_cRational, "-", rb_rational_minus, 1);
+ rb_define_method(rb_cRational, "*", rb_rational_mul, 1);
+ rb_define_method(rb_cRational, "/", rb_rational_div, 1);
+ rb_define_method(rb_cRational, "quo", rb_rational_div, 1);
rb_define_method(rb_cRational, "fdiv", nurat_fdiv, 1);
rb_define_method(rb_cRational, "**", nurat_expt, 1);
@@ -2715,15 +2785,6 @@ Init_Rational(void)
rb_define_method(rb_cRational, "==", nurat_eqeq_p, 1);
rb_define_method(rb_cRational, "coerce", nurat_coerce, 1);
-#if 0
- rb_define_method(rb_cRational, "quot", nurat_quot, 1);
- rb_define_method(rb_cRational, "quotrem", nurat_quotrem, 1);
-#endif
-
-#if 0
- rb_define_method(rb_cRational, "rational?", nurat_true, 0);
- rb_define_method(rb_cRational, "exact?", nurat_true, 0);
-#endif
rb_define_method(rb_cRational, "positive?", nurat_positive_p, 0);
rb_define_method(rb_cRational, "negative?", nurat_negative_p, 0);
rb_define_method(rb_cRational, "abs", rb_rational_abs, 0);
@@ -2745,6 +2806,7 @@ Init_Rational(void)
rb_define_method(rb_cRational, "inspect", nurat_inspect, 0);
rb_define_private_method(rb_cRational, "marshal_dump", nurat_marshal_dump, 0);
+ /* :nodoc: */
compat = rb_define_class_under(rb_cRational, "compatible", rb_cObject);
rb_define_private_method(compat, "marshal_load", nurat_marshal_load, 1);
rb_marshal_define_compat(rb_cRational, compat, nurat_dumper, nurat_loader);
@@ -2762,8 +2824,8 @@ Init_Rational(void)
rb_define_method(rb_cInteger, "numerator", integer_numerator, 0);
rb_define_method(rb_cInteger, "denominator", integer_denominator, 0);
- rb_define_method(rb_cFloat, "numerator", float_numerator, 0);
- rb_define_method(rb_cFloat, "denominator", float_denominator, 0);
+ rb_define_method(rb_cFloat, "numerator", rb_float_numerator, 0);
+ rb_define_method(rb_cFloat, "denominator", rb_float_denominator, 0);
rb_define_method(rb_cNilClass, "to_r", nilclass_to_r, 0);
rb_define_method(rb_cNilClass, "rationalize", nilclass_rationalize, -1);
@@ -2778,9 +2840,3 @@ Init_Rational(void)
rb_provide("rational.so"); /* for backward compatibility */
}
-
-/*
-Local variables:
-c-file-style: "ruby"
-End:
-*/
diff --git a/re.c b/re.c
index c1c29aea37..5b6f129963 100644
--- a/re.c
+++ b/re.c
@@ -9,12 +9,21 @@
**********************************************************************/
+#include "ruby/internal/config.h"
+
+#include <ctype.h>
+
+#include "encindex.h"
#include "internal.h"
+#include "internal/hash.h"
+#include "internal/imemo.h"
+#include "internal/re.h"
+#include "internal/string.h"
+#include "internal/variable.h"
+#include "regint.h"
+#include "ruby/encoding.h"
#include "ruby/re.h"
#include "ruby/util.h"
-#include "regint.h"
-#include "encindex.h"
-#include <ctype.h>
VALUE rb_eRegexpError;
@@ -94,7 +103,7 @@ rb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long n
{
const unsigned char *y;
- if (y = memmem(ys, n, xs, m))
+ if ((y = memmem(ys, n, xs, m)) != NULL)
return y - ys;
else
return -1;
@@ -105,13 +114,7 @@ rb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long n
{
const unsigned char *x = xs, *xe = xs + m;
const unsigned char *y = ys, *ye = ys + n;
-#ifndef VALUE_MAX
-# if SIZEOF_VALUE == 8
-# define VALUE_MAX 0xFFFFFFFFFFFFFFFFULL
-# elif SIZEOF_VALUE == 4
-# define VALUE_MAX 0xFFFFFFFFUL
-# endif
-#endif
+#define VALUE_MAX ((VALUE)~(VALUE)0)
VALUE hx, hy, mask = VALUE_MAX >> ((SIZEOF_VALUE - m) * CHAR_BIT);
if (m > SIZEOF_VALUE)
@@ -309,8 +312,10 @@ char_to_option(int c)
return val;
}
+enum { OPTBUF_SIZE = 4 };
+
static char *
-option_to_str(char str[4], int options)
+option_to_str(char str[OPTBUF_SIZE], int options)
{
char *p = str;
if (options & ONIG_OPTION_MULTILINE) *p++ = 'm';
@@ -356,7 +361,7 @@ rb_reg_check(VALUE re)
static void
rb_reg_expr_str(VALUE str, const char *s, long len,
- rb_encoding *enc, rb_encoding *resenc)
+ rb_encoding *enc, rb_encoding *resenc, int term)
{
const char *p, *pend;
int cr = ENC_CODERANGE_UNKNOWN;
@@ -377,7 +382,7 @@ rb_reg_expr_str(VALUE str, const char *s, long len,
break;
}
}
- else if (c != '/' && rb_enc_isprint(c, enc)) {
+ else if (c != term && rb_enc_isprint(c, enc)) {
p += clen;
}
else {
@@ -404,11 +409,6 @@ rb_reg_expr_str(VALUE str, const char *s, long len,
p += n;
continue;
}
- else if (c == '/') {
- char c = '\\';
- rb_str_buf_cat(str, &c, 1);
- rb_str_buf_cat(str, p, clen);
- }
else if (c == -1) {
clen = rb_enc_precise_mbclen(p, pend, enc);
if (!MBCLEN_CHARFOUND_P(clen)) {
@@ -425,6 +425,11 @@ rb_reg_expr_str(VALUE str, const char *s, long len,
rb_str_buf_cat(str, p, clen);
}
}
+ else if (c == term) {
+ char c = '\\';
+ rb_str_buf_cat(str, &c, 1);
+ rb_str_buf_cat(str, p, clen);
+ }
else if (rb_enc_isprint(c, enc)) {
rb_str_buf_cat(str, p, clen);
}
@@ -457,17 +462,16 @@ rb_reg_desc(const char *s, long len, VALUE re)
else {
rb_enc_associate(str, rb_usascii_encoding());
}
- rb_reg_expr_str(str, s, len, enc, resenc);
+ rb_reg_expr_str(str, s, len, enc, resenc, '/');
rb_str_buf_cat2(str, "/");
if (re) {
- char opts[4];
+ char opts[OPTBUF_SIZE];
rb_reg_check(re);
if (*option_to_str(opts, RREGEXP_PTR(re)->options))
rb_str_buf_cat2(str, opts);
if (RBASIC(re)->flags & REG_ENCODING_NONE)
rb_str_buf_cat2(str, "n");
}
- OBJ_INFECT(str, re);
return str;
}
@@ -493,7 +497,6 @@ rb_reg_source(VALUE re)
rb_reg_check(re);
str = rb_str_dup(RREGEXP_SRC(re));
- if (OBJ_TAINTED(re)) OBJ_TAINT(str);
return str;
}
@@ -518,6 +521,7 @@ rb_reg_inspect(VALUE re)
return rb_reg_desc(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), re);
}
+static VALUE rb_reg_str_with_term(VALUE re, int term);
/*
* call-seq:
@@ -525,11 +529,11 @@ rb_reg_inspect(VALUE re)
*
* Returns a string containing the regular expression and its options (using the
* <code>(?opts:source)</code> notation. This string can be fed back in to
- * <code>Regexp::new</code> to a regular expression with the same semantics as
- * the original. (However, <code>Regexp#==</code> may not return true when
- * comparing the two, as the source of the regular expression itself may
- * differ, as the example shows). <code>Regexp#inspect</code> produces a
- * generally more readable version of <i>rxp</i>.
+ * Regexp::new to a regular expression with the same semantics as the
+ * original. (However, <code>Regexp#==</code> may not return true
+ * when comparing the two, as the source of the regular expression
+ * itself may differ, as the example shows). Regexp#inspect produces
+ * a generally more readable version of <i>rxp</i>.
*
* r1 = /ab+c/ix #=> /ab+c/ix
* s1 = r1.to_s #=> "(?ix-m:ab+c)"
@@ -542,12 +546,18 @@ rb_reg_inspect(VALUE re)
static VALUE
rb_reg_to_s(VALUE re)
{
+ return rb_reg_str_with_term(re, '/');
+}
+
+static VALUE
+rb_reg_str_with_term(VALUE re, int term)
+{
int options, opt;
const int embeddable = ONIG_OPTION_MULTILINE|ONIG_OPTION_IGNORECASE|ONIG_OPTION_EXTEND;
long len;
const UChar* ptr;
VALUE str = rb_str_buf_new2("(?");
- char optbuf[5];
+ char optbuf[OPTBUF_SIZE + 1]; /* for '-' */
rb_encoding *enc = rb_enc_get(re);
rb_reg_check(re);
@@ -620,7 +630,7 @@ rb_reg_to_s(VALUE re)
rb_str_buf_cat2(str, ":");
if (rb_enc_asciicompat(enc)) {
- rb_reg_expr_str(str, (char*)ptr, len, enc, NULL);
+ rb_reg_expr_str(str, (char*)ptr, len, enc, NULL, term);
rb_str_buf_cat2(str, ")");
}
else {
@@ -640,15 +650,16 @@ rb_reg_to_s(VALUE re)
memcpy(paren, s, n);
rb_str_resize(str, RSTRING_LEN(str) - n);
- rb_reg_expr_str(str, (char*)ptr, len, enc, NULL);
+ rb_reg_expr_str(str, (char*)ptr, len, enc, NULL, term);
rb_str_buf_cat(str, paren, n);
}
rb_enc_copy(str, re);
- OBJ_INFECT(str, re);
return str;
}
+NORETURN(static void rb_reg_raise(const char *s, long len, const char *err, VALUE re));
+
static void
rb_reg_raise(const char *s, long len, const char *err, VALUE re)
{
@@ -660,20 +671,22 @@ rb_reg_raise(const char *s, long len, const char *err, VALUE re)
static VALUE
rb_enc_reg_error_desc(const char *s, long len, rb_encoding *enc, int options, const char *err)
{
- char opts[6];
+ char opts[OPTBUF_SIZE + 1]; /* for '/' */
VALUE desc = rb_str_buf_new2(err);
rb_encoding *resenc = rb_default_internal_encoding();
if (resenc == NULL) resenc = rb_default_external_encoding();
rb_enc_associate(desc, enc);
rb_str_buf_cat2(desc, ": /");
- rb_reg_expr_str(desc, s, len, enc, resenc);
+ rb_reg_expr_str(desc, s, len, enc, resenc, '/');
opts[0] = '/';
option_to_str(opts + 1, options);
rb_str_buf_cat2(desc, opts);
return rb_exc_new3(rb_eRegexpError, desc);
}
+NORETURN(static void rb_enc_reg_raise(const char *s, long len, rb_encoding *enc, int options, const char *err));
+
static void
rb_enc_reg_raise(const char *s, long len, rb_encoding *enc, int options, const char *err)
{
@@ -687,6 +700,8 @@ rb_reg_error_desc(VALUE str, int options, const char *err)
rb_enc_get(str), options, err);
}
+NORETURN(static void rb_reg_raise_str(VALUE str, int options, const char *err));
+
static void
rb_reg_raise_str(VALUE str, int options, const char *err)
{
@@ -718,11 +733,11 @@ rb_reg_casefold_p(VALUE re)
* call-seq:
* rxp.options -> integer
*
- * Returns the set of bits corresponding to the options used when creating this
- * Regexp (see <code>Regexp::new</code> for details. Note that additional bits
- * may be set in the returned options: these are used internally by the regular
- * expression code. These extra bits are ignored if the options are passed to
- * <code>Regexp::new</code>.
+ * Returns the set of bits corresponding to the options used when
+ * creating this Regexp (see Regexp::new for details. Note that
+ * additional bits may be set in the returned options: these are used
+ * internally by the regular expression code. These extra bits are
+ * ignored if the options are passed to Regexp::new.
*
* Regexp::IGNORECASE #=> 1
* Regexp::EXTENDED #=> 2
@@ -876,13 +891,50 @@ make_regexp(const char *s, long len, rb_encoding *enc, int flags, onig_errmsg_bu
/*
* Document-class: MatchData
*
- * <code>MatchData</code> is the type of the special variable <code>$~</code>,
- * and is the type of the object returned by <code>Regexp#match</code> and
- * <code>Regexp.last_match</code>. It encapsulates all the results of a pattern
- * match, results normally accessed through the special variables
- * <code>$&</code>, <code>$'</code>, <code>$`</code>, <code>$1</code>,
- * <code>$2</code>, and so on.
- *
+ * MatchData encapsulates the result of matching a Regexp against
+ * string. It is returned by Regexp#match and String#match, and also
+ * stored in a global variable returned by Regexp.last_match.
+ *
+ * Usage:
+ *
+ * url = 'https://docs.ruby-lang.org/en/2.5.0/MatchData.html'
+ * m = url.match(/(\d\.?)+/) # => #<MatchData "2.5.0" 1:"0">
+ * m.string # => "https://docs.ruby-lang.org/en/2.5.0/MatchData.html"
+ * m.regexp # => /(\d\.?)+/
+ * # entire matched substring:
+ * m[0] # => "2.5.0"
+ *
+ * # Working with unnamed captures
+ * m = url.match(%r{([^/]+)/([^/]+)\.html$})
+ * m.captures # => ["2.5.0", "MatchData"]
+ * m[1] # => "2.5.0"
+ * m.values_at(1, 2) # => ["2.5.0", "MatchData"]
+ *
+ * # Working with named captures
+ * m = url.match(%r{(?<version>[^/]+)/(?<module>[^/]+)\.html$})
+ * m.captures # => ["2.5.0", "MatchData"]
+ * m.named_captures # => {"version"=>"2.5.0", "module"=>"MatchData"}
+ * m[:version] # => "2.5.0"
+ * m.values_at(:version, :module)
+ * # => ["2.5.0", "MatchData"]
+ * # Numerical indexes are working, too
+ * m[1] # => "2.5.0"
+ * m.values_at(1, 2) # => ["2.5.0", "MatchData"]
+ *
+ * == Global variables equivalence
+ *
+ * Parts of last MatchData (returned by Regexp.last_match) are also
+ * aliased as global variables:
+ *
+ * * <code>$~</code> is Regexp.last_match;
+ * * <code>$&</code> is Regexp.last_match<code>[ 0 ]</code>;
+ * * <code>$1</code>, <code>$2</code>, and so on are
+ * Regexp.last_match<code>[ i ]</code> (captures by number);
+ * * <code>$`</code> is Regexp.last_match<code>.pre_match</code>;
+ * * <code>$'</code> is Regexp.last_match<code>.post_match</code>;
+ * * <code>$+</code> is Regexp.last_match<code>[ -1 ]</code> (the last capture).
+ *
+ * See also "Special global variables" section in Regexp documentation.
*/
VALUE rb_cMatch;
@@ -938,7 +990,7 @@ update_char_offset(VALUE match)
rb_encoding *enc;
pair_t *pairs;
- if (rm->char_offset_updated)
+ if (rm->char_offset_num_allocated)
return;
regs = &rm->regs;
@@ -955,7 +1007,6 @@ update_char_offset(VALUE match)
rm->char_offset[i].beg = BEG(i);
rm->char_offset[i].end = END(i);
}
- rm->char_offset_updated = 1;
return;
}
@@ -994,15 +1045,13 @@ update_char_offset(VALUE match)
found = bsearch(&key, pairs, num_pos, sizeof(pair_t), pair_byte_cmp);
rm->char_offset[i].end = found->char_pos;
}
-
- rm->char_offset_updated = 1;
}
static void
match_check(VALUE match)
{
if (!RMATCH(match)->regexp) {
- rb_raise(rb_eTypeError, "uninitialized Match");
+ rb_raise(rb_eTypeError, "uninitialized MatchData");
}
}
@@ -1021,17 +1070,13 @@ match_init_copy(VALUE obj, VALUE orig)
if (rb_reg_region_copy(&rm->regs, RMATCH_REGS(orig)))
rb_memerror();
- if (!RMATCH(orig)->rmatch->char_offset_updated) {
- rm->char_offset_updated = 0;
- }
- else {
+ if (RMATCH(orig)->rmatch->char_offset_num_allocated) {
if (rm->char_offset_num_allocated < rm->regs.num_regs) {
REALLOC_N(rm->char_offset, struct rmatch_offset, rm->regs.num_regs);
rm->char_offset_num_allocated = rm->regs.num_regs;
}
MEMCPY(rm->char_offset, RMATCH(orig)->rmatch->char_offset,
struct rmatch_offset, rm->regs.num_regs);
- rm->char_offset_updated = 1;
RB_GC_GUARD(orig);
}
@@ -1106,6 +1151,14 @@ match_size(VALUE match)
}
static int name_to_backref_number(struct re_registers *, VALUE, const char*, const char*);
+NORETURN(static void name_to_backref_error(VALUE name));
+
+static void
+name_to_backref_error(VALUE name)
+{
+ rb_raise(rb_eIndexError, "undefined group name reference: % "PRIsVALUE,
+ name);
+}
static int
match_backref_number(VALUE match, VALUE backref)
@@ -1125,10 +1178,10 @@ match_backref_number(VALUE match, VALUE backref)
}
name = StringValueCStr(backref);
- num = name_to_backref_number(regs, regexp, name, name + strlen(name));
+ num = name_to_backref_number(regs, regexp, name, name + RSTRING_LEN(backref));
if (num < 1) {
- rb_raise(rb_eIndexError, "undefined group name reference: %s", name);
+ name_to_backref_error(backref);
}
return num;
@@ -1254,6 +1307,12 @@ rb_match_busy(VALUE match)
FL_SET(match, MATCH_BUSY);
}
+void
+rb_match_unbusy(VALUE match)
+{
+ FL_UNSET(match, MATCH_BUSY);
+}
+
int
rb_match_count(VALUE match)
{
@@ -1289,11 +1348,10 @@ match_set_string(VALUE m, VALUE string, long pos, long len)
match->str = string;
match->regexp = Qnil;
- onig_region_resize(&rmatch->regs, 1);
+ int err = onig_region_resize(&rmatch->regs, 1);
+ if (err) rb_memerror();
rmatch->regs.beg[0] = pos;
rmatch->regs.end[0] = pos + len;
- rmatch->char_offset_updated = 0;
- OBJ_INFECT(match, string);
}
void
@@ -1325,14 +1383,14 @@ rb_backref_set_string(VALUE string, long pos, long len)
* r.fixed_encoding? #=> true
* r.encoding #=> #<Encoding:UTF-8>
* r =~ "\u{6666} a" #=> 2
- * r =~ "\xa1\xa2".force_encoding("euc-jp") #=> ArgumentError
+ * r =~ "\xa1\xa2".force_encoding("euc-jp") #=> Encoding::CompatibilityError
* r =~ "abc".force_encoding("euc-jp") #=> 0
*
* r = /\u{6666}/
* r.fixed_encoding? #=> true
* r.encoding #=> #<Encoding:UTF-8>
* r =~ "\u{6666} a" #=> 0
- * r =~ "\xa1\xa2".force_encoding("euc-jp") #=> ArgumentError
+ * r =~ "\xa1\xa2".force_encoding("euc-jp") #=> Encoding::CompatibilityError
* r =~ "abc".force_encoding("euc-jp") #=> nil
*/
@@ -1349,6 +1407,7 @@ static VALUE
rb_reg_preprocess(const char *p, const char *end, rb_encoding *enc,
rb_encoding **fixed_enc, onig_errmsg_buffer err);
+NORETURN(static void reg_enc_error(VALUE re, VALUE str));
static void
reg_enc_error(VALUE re, VALUE str)
@@ -1433,8 +1492,10 @@ rb_reg_prepare_re0(VALUE re, VALUE str, onig_errmsg_buffer err)
rb_raise(rb_eArgError, "regexp preprocess failed: %s", err);
}
- r = onig_new(&reg, (UChar* )RSTRING_PTR(unescaped),
- (UChar* )(RSTRING_PTR(unescaped) + RSTRING_LEN(unescaped)),
+ const char *ptr;
+ long len;
+ RSTRING_GETMEM(unescaped, ptr, len);
+ r = onig_new(&reg, (UChar *)ptr, (UChar *)(ptr + len),
reg->options, enc,
OnigDefaultSyntax, &einfo);
if (r) {
@@ -1485,18 +1546,21 @@ rb_reg_adjust_startpos(VALUE re, VALUE str, long pos, int reverse)
}
/* returns byte offset */
-long
-rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
+static long
+rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_backref_str, VALUE *set_match)
{
long result;
VALUE match;
struct re_registers regi, *regs = &regi;
- char *range = RSTRING_PTR(str);
+ char *start, *range;
+ long len;
regex_t *reg;
int tmpreg;
onig_errmsg_buffer err = "";
- if (pos > RSTRING_LEN(str) || pos < 0) {
+ RSTRING_GETMEM(str, start, len);
+ range = start;
+ if (pos > len || pos < 0) {
rb_backref_set(Qnil);
return -1;
}
@@ -1505,6 +1569,81 @@ rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
tmpreg = reg != RREGEXP_PTR(re);
if (!tmpreg) RREGEXP(re)->usecnt++;
+ MEMZERO(regs, struct re_registers, 1);
+ if (!reverse) {
+ range += len;
+ }
+ result = onig_search(reg,
+ (UChar*)start,
+ ((UChar*)(start + len)),
+ ((UChar*)(start + pos)),
+ ((UChar*)range),
+ regs, ONIG_OPTION_NONE);
+ if (!tmpreg) RREGEXP(re)->usecnt--;
+ if (tmpreg) {
+ if (RREGEXP(re)->usecnt) {
+ onig_free(reg);
+ }
+ else {
+ onig_free(RREGEXP_PTR(re));
+ RREGEXP_PTR(re) = reg;
+ }
+ }
+ if (result < 0) {
+ if (regs == &regi)
+ onig_region_free(regs, 0);
+ if (result == ONIG_MISMATCH) {
+ rb_backref_set(Qnil);
+ return result;
+ }
+ else {
+ onig_error_code_to_str((UChar*)err, (int)result);
+ rb_reg_raise(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), err, re);
+ }
+ }
+
+ match = match_alloc(rb_cMatch);
+ int copy_err = rb_reg_region_copy(RMATCH_REGS(match), regs);
+ onig_region_free(regs, 0);
+ if (copy_err) rb_memerror();
+
+ if (set_backref_str) {
+ RMATCH(match)->str = rb_str_new4(str);
+ }
+
+ RMATCH(match)->regexp = re;
+ rb_backref_set(match);
+ if (set_match) *set_match = match;
+
+ return result;
+}
+
+long
+rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
+{
+ return rb_reg_search_set_match(re, str, pos, reverse, set_backref_str, NULL);
+}
+
+long
+rb_reg_search(VALUE re, VALUE str, long pos, int reverse)
+{
+ return rb_reg_search0(re, str, pos, reverse, 1);
+}
+
+bool
+rb_reg_start_with_p(VALUE re, VALUE str)
+{
+ long result;
+ VALUE match;
+ struct re_registers regi, *regs = &regi;
+ regex_t *reg;
+ int tmpreg;
+ onig_errmsg_buffer err = "";
+
+ reg = rb_reg_prepare_re0(re, str, err);
+ tmpreg = reg != RREGEXP_PTR(re);
+ if (!tmpreg) RREGEXP(re)->usecnt++;
+
match = rb_backref_get();
if (!NIL_P(match)) {
if (FL_TEST(match, MATCH_BUSY)) {
@@ -1517,15 +1656,14 @@ rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
if (NIL_P(match)) {
MEMZERO(regs, struct re_registers, 1);
}
- if (!reverse) {
- range += RSTRING_LEN(str);
- }
- result = onig_search(reg,
- (UChar*)(RSTRING_PTR(str)),
- ((UChar*)(RSTRING_PTR(str)) + RSTRING_LEN(str)),
- ((UChar*)(RSTRING_PTR(str)) + pos),
- ((UChar*)range),
- regs, ONIG_OPTION_NONE);
+ const char *ptr;
+ long len;
+ RSTRING_GETMEM(str, ptr, len);
+ result = onig_match(reg,
+ (UChar*)(ptr),
+ ((UChar*)(ptr + len)),
+ (UChar*)(ptr),
+ regs, ONIG_OPTION_NONE);
if (!tmpreg) RREGEXP(re)->usecnt--;
if (tmpreg) {
if (RREGEXP(re)->usecnt) {
@@ -1541,7 +1679,7 @@ rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
onig_region_free(regs, 0);
if (result == ONIG_MISMATCH) {
rb_backref_set(Qnil);
- return result;
+ return false;
}
else {
onig_error_code_to_str((UChar*)err, (int)result);
@@ -1556,28 +1694,13 @@ rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
onig_region_free(regs, 0);
if (err) rb_memerror();
}
- else {
- FL_UNSET(match, FL_TAINT);
- }
- if (set_backref_str) {
- RMATCH(match)->str = rb_str_new4(str);
- OBJ_INFECT(match, str);
- }
+ RMATCH(match)->str = rb_str_new4(str);
RMATCH(match)->regexp = re;
- RMATCH(match)->rmatch->char_offset_updated = 0;
rb_backref_set(match);
- OBJ_INFECT(match, re);
-
- return result;
-}
-
-long
-rb_reg_search(VALUE re, VALUE str, long pos, int reverse)
-{
- return rb_reg_search0(re, str, pos, reverse, 1);
+ return true;
}
VALUE
@@ -1620,7 +1743,6 @@ rb_reg_nth_match(int nth, VALUE match)
end = END(nth);
len = end - start;
str = rb_str_subseq(RMATCH(match)->str, start, len);
- OBJ_INFECT(str, match);
return str;
}
@@ -1653,7 +1775,6 @@ rb_reg_match_pre(VALUE match)
regs = RMATCH_REGS(match);
if (BEG(0) == -1) return Qnil;
str = rb_str_subseq(RMATCH(match)->str, 0, BEG(0));
- if (OBJ_TAINTED(match)) OBJ_TAINT(str);
return str;
}
@@ -1683,7 +1804,6 @@ rb_reg_match_post(VALUE match)
str = RMATCH(match)->str;
pos = END(0);
str = rb_str_subseq(str, pos, RSTRING_LEN(str) - pos);
- if (OBJ_TAINTED(match)) OBJ_TAINT(str);
return str;
}
@@ -1705,25 +1825,25 @@ rb_reg_match_last(VALUE match)
}
static VALUE
-last_match_getter(void)
+last_match_getter(ID _x, VALUE *_y)
{
return rb_reg_last_match(rb_backref_get());
}
static VALUE
-prematch_getter(void)
+prematch_getter(ID _x, VALUE *_y)
{
return rb_reg_match_pre(rb_backref_get());
}
static VALUE
-postmatch_getter(void)
+postmatch_getter(ID _x, VALUE *_y)
{
return rb_reg_match_post(rb_backref_get());
}
static VALUE
-last_paren_match_getter(void)
+last_paren_match_getter(ID _x, VALUE *_y)
{
return rb_reg_match_last(rb_backref_get());
}
@@ -1735,7 +1855,6 @@ match_array(VALUE match, int start)
VALUE ary;
VALUE target;
int i;
- int taint = OBJ_TAINTED(match);
match_check(match);
regs = RMATCH_REGS(match);
@@ -1748,7 +1867,6 @@ match_array(VALUE match, int start)
}
else {
VALUE str = rb_str_subseq(target, regs->beg[i], regs->end[i]-regs->beg[i]);
- if (taint) OBJ_TAINT(str);
rb_ary_push(ary, str);
}
}
@@ -1806,18 +1924,11 @@ match_captures(VALUE match)
static int
name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name, const char* name_end)
{
+ if (NIL_P(regexp)) return -1;
return onig_name_to_backref_number(RREGEXP_PTR(regexp),
(const unsigned char *)name, (const unsigned char *)name_end, regs);
}
-NORETURN(static void name_to_backref_error(VALUE name));
-static void
-name_to_backref_error(VALUE name)
-{
- rb_raise(rb_eIndexError, "undefined group name reference: % "PRIsVALUE,
- name);
-}
-
#define NAME_TO_NUMBER(regs, re, name, name_ptr, name_end) \
(NIL_P(re) ? 0 : \
!rb_enc_compatible(RREGEXP_SRC(re), (name)) ? 0 : \
@@ -1885,12 +1996,12 @@ match_ary_aref(VALUE match, VALUE idx, VALUE result)
* mtch[range] -> array
* mtch[name] -> str or nil
*
- * Match Reference -- <code>MatchData</code> acts as an array, and may be
- * accessed using the normal array indexing techniques. <code>mtch[0]</code>
- * is equivalent to the special variable <code>$&</code>, and returns the
- * entire matched string. <code>mtch[1]</code>, <code>mtch[2]</code>, and so
- * on return the values of the matched backreferences (portions of the
- * pattern between parentheses).
+ * Match Reference -- MatchData acts as an array, and may be accessed
+ * using the normal array indexing techniques. <code>mtch[0]</code>
+ * is equivalent to the special variable <code>$&</code>, and returns
+ * the entire matched string. <code>mtch[1]</code>,
+ * <code>mtch[2]</code>, and so on return the values of the matched
+ * backreferences (portions of the pattern between parentheses).
*
* m = /(.)(.)(\d+)(\d)/.match("THX1138.")
* m #=> #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
@@ -1951,7 +2062,7 @@ match_aref(int argc, VALUE *argv, VALUE match)
/*
* call-seq:
*
- * mtch.values_at([index]*) -> array
+ * mtch.values_at(index, ...) -> array
*
* Uses each <i>index</i> to access the matching values, returning an array of
* the corresponding matches.
@@ -2009,8 +2120,6 @@ match_to_s(VALUE match)
match_check(match);
if (NIL_P(str)) str = rb_str_new(0,0);
- if (OBJ_TAINTED(match)) OBJ_TAINT(str);
- if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str);
return str;
}
@@ -2303,7 +2412,8 @@ unescape_escaped_nonascii(const char **pp, const char *end, rb_encoding *enc,
{
const char *p = *pp;
int chmaxlen = rb_enc_mbmaxlen(enc);
- char *chbuf = ALLOCA_N(char, chmaxlen);
+ unsigned char *area = ALLOCA_N(unsigned char, chmaxlen);
+ char *chbuf = (char *)area;
int chlen = 0;
int byte;
int l;
@@ -2315,14 +2425,14 @@ unescape_escaped_nonascii(const char **pp, const char *end, rb_encoding *enc,
return -1;
}
- chbuf[chlen++] = byte;
+ area[chlen++] = byte;
while (chlen < chmaxlen &&
MBCLEN_NEEDMORE_P(rb_enc_precise_mbclen(chbuf, chbuf+chlen, enc))) {
byte = read_escaped_byte(&p, end, err);
if (byte == -1) {
return -1;
}
- chbuf[chlen++] = byte;
+ area[chlen++] = byte;
}
l = rb_enc_precise_mbclen(chbuf, chbuf+chlen, enc);
@@ -2330,7 +2440,7 @@ unescape_escaped_nonascii(const char **pp, const char *end, rb_encoding *enc,
errcpy(err, "invalid multibyte escape");
return -1;
}
- if (1 < chlen || (chbuf[0] & 0x80)) {
+ if (1 < chlen || (area[0] & 0x80)) {
rb_str_buf_cat(buf, chbuf, chlen);
if (*encp == 0)
@@ -2342,7 +2452,7 @@ unescape_escaped_nonascii(const char **pp, const char *end, rb_encoding *enc,
}
else {
char escbuf[5];
- snprintf(escbuf, sizeof(escbuf), "\\x%02X", chbuf[0]&0xff);
+ snprintf(escbuf, sizeof(escbuf), "\\x%02X", area[0]&0xff);
rb_str_buf_cat(buf, escbuf, 4);
}
*pp = p;
@@ -2452,17 +2562,19 @@ unescape_nonascii(const char *p, const char *end, rb_encoding *enc,
VALUE buf, rb_encoding **encp, int *has_property,
onig_errmsg_buffer err)
{
- char c;
+ unsigned char c;
char smallbuf[2];
while (p < end) {
int chlen = rb_enc_precise_mbclen(p, end, enc);
if (!MBCLEN_CHARFOUND_P(chlen)) {
+ invalid_multibyte:
errcpy(err, "invalid multibyte character");
return -1;
}
chlen = MBCLEN_CHARFOUND_LEN(chlen);
if (1 < chlen || (*p & 0x80)) {
+ multibyte:
rb_str_buf_cat(buf, p, chlen);
p += chlen;
if (*encp == 0)
@@ -2480,6 +2592,16 @@ unescape_nonascii(const char *p, const char *end, rb_encoding *enc,
errcpy(err, "too short escape sequence");
return -1;
}
+ chlen = rb_enc_precise_mbclen(p, end, enc);
+ if (!MBCLEN_CHARFOUND_P(chlen)) {
+ goto invalid_multibyte;
+ }
+ if ((chlen = MBCLEN_CHARFOUND_LEN(chlen)) > 1) {
+ /* include the previous backslash */
+ --p;
+ ++chlen;
+ goto multibyte;
+ }
switch (c = *p++) {
case '1': case '2': case '3':
case '4': case '5': case '6': case '7': /* \O, \OO, \OOO or backref */
@@ -2503,8 +2625,9 @@ unescape_nonascii(const char *p, const char *end, rb_encoding *enc,
p = p-2;
if (enc == rb_usascii_encoding()) {
const char *pbeg = p;
- c = read_escaped_byte(&p, end, err);
- if (c == (char)-1) return -1;
+ int byte = read_escaped_byte(&p, end, err);
+ if (byte == -1) return -1;
+ c = byte;
rb_str_buf_cat(buf, pbeg, p-pbeg);
}
else {
@@ -2553,7 +2676,7 @@ escape_asis:
break;
default:
- rb_str_buf_cat(buf, &c, 1);
+ rb_str_buf_cat(buf, (char *)&c, 1);
break;
}
}
@@ -2757,7 +2880,6 @@ rb_reg_initialize_str(VALUE obj, VALUE str, int options, onig_errmsg_buffer err,
}
ret = rb_reg_initialize(obj, RSTRING_PTR(str), RSTRING_LEN(str), enc,
options, err, sourcefile, sourceline);
- OBJ_INFECT(obj, str);
if (ret == 0) reg_set_source(obj, str, str_enc);
return ret;
}
@@ -2812,10 +2934,12 @@ rb_reg_init_str_enc(VALUE re, VALUE s, rb_encoding *enc, int options)
return re;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_reg_new_ary(VALUE ary, int opt)
{
- return rb_reg_new_str(rb_reg_preprocess_dregexp(ary, opt), opt);
+ VALUE re = rb_reg_new_str(rb_reg_preprocess_dregexp(ary, opt), opt);
+ rb_obj_freeze(re);
+ return re;
}
VALUE
@@ -2850,6 +2974,7 @@ rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline)
return Qnil;
}
FL_SET(re, REG_LITERAL);
+ rb_obj_freeze(re);
return re;
}
@@ -2986,13 +3111,16 @@ reg_operand(VALUE s, int check)
if (SYMBOL_P(s)) {
return rb_sym2str(s);
}
+ else if (RB_TYPE_P(s, T_STRING)) {
+ return s;
+ }
else {
- return (check ? rb_str_to_str : rb_check_string_type)(s);
+ return check ? rb_str_to_str(s) : rb_check_string_type(s);
}
}
static long
-reg_match_pos(VALUE re, VALUE *strp, long pos)
+reg_match_pos(VALUE re, VALUE *strp, long pos, VALUE* set_match)
{
VALUE str = *strp;
@@ -3011,7 +3139,7 @@ reg_match_pos(VALUE re, VALUE *strp, long pos)
}
pos = rb_str_offset(str, pos);
}
- return rb_reg_search(re, str, pos, 0);
+ return rb_reg_search_set_match(re, str, pos, 0, 1, set_match);
}
/*
@@ -3065,7 +3193,7 @@ reg_match_pos(VALUE re, VALUE *strp, long pos)
VALUE
rb_reg_match(VALUE re, VALUE str)
{
- long pos = reg_match_pos(re, &str, 0);
+ long pos = reg_match_pos(re, &str, 0, NULL);
if (pos < 0) return Qnil;
pos = rb_str_sublen(str, pos);
return LONG2FIX(pos);
@@ -3079,9 +3207,9 @@ rb_reg_match(VALUE re, VALUE str)
*
* a = "HELLO"
* case a
- * when /^[a-z]*$/; print "Lower case\n"
- * when /^[A-Z]*$/; print "Upper case\n"
- * else; print "Mixed case\n"
+ * when /\A[a-z]*\z/; print "Lower case\n"
+ * when /\A[A-Z]*\z/; print "Upper case\n"
+ * else; print "Mixed case\n"
* end
* #=> "Upper case"
*
@@ -3143,14 +3271,14 @@ rb_reg_match2(VALUE re)
/*
* call-seq:
- * rxp.match(str) -> matchdata or nil
- * rxp.match(str,pos) -> matchdata or nil
+ * rxp.match(str, pos=0) -> matchdata or nil
+ * rxp.match(str, pos=0) {|match| block } -> obj
*
- * Returns a <code>MatchData</code> object describing the match, or
- * <code>nil</code> if there was no match. This is equivalent to retrieving the
- * value of the special variable <code>$~</code> following a normal match.
- * If the second parameter is present, it specifies the position in the string
- * to begin the search.
+ * Returns a MatchData object describing the match, or
+ * <code>nil</code> if there was no match. This is equivalent to
+ * retrieving the value of the special variable <code>$~</code>
+ * following a normal match. If the second parameter is present, it
+ * specifies the position in the string to begin the search.
*
* /(.)(.)(.)/.match("abc")[2] #=> "b"
* /(.)(.)/.match("abc", 1)[2] #=> "c"
@@ -3176,7 +3304,7 @@ rb_reg_match2(VALUE re)
static VALUE
rb_reg_match_m(int argc, VALUE *argv, VALUE re)
{
- VALUE result, str, initpos;
+ VALUE result = Qnil, str, initpos;
long pos;
if (rb_scan_args(argc, argv, "11", &str, &initpos) == 2) {
@@ -3186,12 +3314,11 @@ rb_reg_match_m(int argc, VALUE *argv, VALUE re)
pos = 0;
}
- pos = reg_match_pos(re, &str, pos);
+ pos = reg_match_pos(re, &str, pos, &result);
if (pos < 0) {
rb_backref_set(Qnil);
return Qnil;
}
- result = rb_backref_get();
rb_match_busy(result);
if (!NIL_P(result) && rb_block_given_p()) {
return rb_yield(result);
@@ -3277,7 +3404,7 @@ rb_reg_match_p(VALUE re, VALUE str, long pos)
/*
* Document-method: compile
*
- * Alias for <code>Regexp.new</code>
+ * Alias for Regexp.new
*/
/*
@@ -3332,7 +3459,7 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
flags |= ARG_ENCODING_NONE;
}
else {
- rb_warn("encoding option is ignored - %s", kcode);
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "encoding option is ignored - %s", kcode);
}
}
str = StringValue(argv[0]);
@@ -3388,8 +3515,9 @@ rb_reg_quote(VALUE str)
}
t = RSTRING_PTR(tmp);
/* copy upto metacharacter */
- memcpy(t, RSTRING_PTR(str), s - RSTRING_PTR(str));
- t += s - RSTRING_PTR(str);
+ const char *p = RSTRING_PTR(str);
+ memcpy(t, p, s - p);
+ t += s - p;
while (s < send) {
c = rb_enc_ascget(s, send, &clen, enc);
@@ -3437,7 +3565,6 @@ rb_reg_quote(VALUE str)
t += rb_enc_mbcput(c, t, enc);
}
rb_str_resize(tmp, t - RSTRING_PTR(tmp));
- OBJ_INFECT(tmp, str);
return tmp;
}
@@ -3448,8 +3575,8 @@ rb_reg_quote(VALUE str)
* Regexp.quote(str) -> string
*
* Escapes any characters that would have special meaning in a regular
- * expression. Returns a new escaped string, or self if no characters are
- * escaped. For any string,
+ * expression. Returns a new escaped string with the same or compatible
+ * encoding. For any string,
* <code>Regexp.new(Regexp.escape(<i>str</i>))=~<i>str</i></code> will be true.
*
* Regexp.escape('\*?{}.') #=> \\\*\?\{\}\.
@@ -3560,7 +3687,7 @@ rb_reg_s_union(VALUE self, VALUE args0)
else {
has_asciionly = 1;
}
- v = rb_reg_to_s(v);
+ v = rb_reg_str_with_term(v, -1);
}
else {
rb_encoding *enc;
@@ -3622,11 +3749,12 @@ rb_reg_s_union(VALUE self, VALUE args0)
* Regexp.union(pat1, pat2, ...) -> new_regexp
* Regexp.union(pats_ary) -> new_regexp
*
- * Return a <code>Regexp</code> object that is the union of the given
- * <em>pattern</em>s, i.e., will match any of its parts. The <em>pattern</em>s
- * can be Regexp objects, in which case their options will be preserved, or
- * Strings. If no patterns are given, returns <code>/(?!)/</code>.
- * The behavior is unspecified if any given <em>pattern</em> contains capture.
+ * Return a Regexp object that is the union of the given
+ * <em>pattern</em>s, i.e., will match any of its parts. The
+ * <em>pattern</em>s can be Regexp objects, in which case their
+ * options will be preserved, or Strings. If no patterns are given,
+ * returns <code>/(?!)/</code>. The behavior is unspecified if any
+ * given <em>pattern</em> contains capture.
*
* Regexp.union #=> /(?!)/
* Regexp.union("penzance") #=> /penzance/
@@ -3667,10 +3795,12 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp)
rb_encoding *str_enc = rb_enc_get(str);
rb_encoding *src_enc = rb_enc_get(src);
int acompat = rb_enc_asciicompat(str_enc);
+ long n;
#define ASCGET(s,e,cl) (acompat ? (*(cl)=1,ISASCII((s)[0])?(s)[0]:-1) : rb_enc_ascget((s), (e), (cl), str_enc))
- p = s = RSTRING_PTR(str);
- e = s + RSTRING_LEN(str);
+ RSTRING_GETMEM(str, s, n);
+ p = s;
+ e = s + n;
while (s < e) {
int c = ASCGET(s, e, &clen);
@@ -3782,29 +3912,16 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp)
}
static VALUE
-kcode_getter(void)
-{
- rb_warn("variable $KCODE is no longer effective");
- return Qnil;
-}
-
-static void
-kcode_setter(VALUE val, ID id)
+ignorecase_getter(ID _x, VALUE *_y)
{
- rb_warn("variable $KCODE is no longer effective; ignored");
-}
-
-static VALUE
-ignorecase_getter(void)
-{
- rb_warn("variable $= is no longer effective");
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "variable $= is no longer effective");
return Qfalse;
}
static void
-ignorecase_setter(VALUE val, ID id)
+ignorecase_setter(VALUE val, ID id, VALUE *_)
{
- rb_warn("variable $= is no longer effective; ignored");
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "variable $= is no longer effective; ignored");
}
static VALUE
@@ -3817,8 +3934,14 @@ match_getter(void)
return match;
}
+static VALUE
+get_LAST_MATCH_INFO(ID _x, VALUE *_y)
+{
+ return match_getter();
+}
+
static void
-match_setter(VALUE val)
+match_setter(VALUE val, ID _x, VALUE *_y)
{
if (!NIL_P(val)) {
Check_Type(val, T_MATCH);
@@ -3855,15 +3978,13 @@ match_setter(VALUE val)
*/
static VALUE
-rb_reg_s_last_match(int argc, VALUE *argv)
+rb_reg_s_last_match(int argc, VALUE *argv, VALUE _)
{
- VALUE nth;
-
- if (argc > 0 && rb_scan_args(argc, argv, "01", &nth) == 1) {
+ if (rb_check_arity(argc, 0, 1) == 1) {
VALUE match = rb_backref_get();
int n;
if (NIL_P(match)) return Qnil;
- n = match_backref_number(match, nth);
+ n = match_backref_number(match, argv[0]);
return rb_reg_nth_match(n, match);
}
return match_getter();
@@ -3890,9 +4011,9 @@ re_warn(const char *s)
/*
* Document-class: Regexp
*
- * A <code>Regexp</code> holds a regular expression, used to match a pattern
- * against strings. Regexps are created using the <code>/.../</code> and
- * <code>%r{...}</code> literals, and by the <code>Regexp::new</code>
+ * A Regexp holds a regular expression, used to match a pattern
+ * against strings. Regexps are created using the <code>/.../</code>
+ * and <code>%r{...}</code> literals, and by the Regexp::new
* constructor.
*
* :include: doc/regexp.rdoc
@@ -3907,15 +4028,19 @@ Init_Regexp(void)
onig_set_warn_func(re_warn);
onig_set_verb_warn_func(re_warn);
- rb_define_virtual_variable("$~", match_getter, match_setter);
+ rb_define_virtual_variable("$~", get_LAST_MATCH_INFO, match_setter);
rb_define_virtual_variable("$&", last_match_getter, 0);
rb_define_virtual_variable("$`", prematch_getter, 0);
rb_define_virtual_variable("$'", postmatch_getter, 0);
rb_define_virtual_variable("$+", last_paren_match_getter, 0);
+ rb_gvar_ractor_local("$~");
+ rb_gvar_ractor_local("$&");
+ rb_gvar_ractor_local("$`");
+ rb_gvar_ractor_local("$'");
+ rb_gvar_ractor_local("$+");
+
rb_define_virtual_variable("$=", ignorecase_getter, ignorecase_setter);
- rb_define_virtual_variable("$KCODE", kcode_getter, kcode_setter);
- rb_define_virtual_variable("$-K", kcode_getter, kcode_setter);
rb_cRegexp = rb_define_class("Regexp", rb_cObject);
rb_define_alloc_func(rb_cRegexp, rb_reg_s_alloc);
@@ -3962,6 +4087,7 @@ Init_Regexp(void)
rb_cMatch = rb_define_class("MatchData", rb_cObject);
rb_define_alloc_func(rb_cMatch, match_alloc);
rb_undef_method(CLASS_OF(rb_cMatch), "new");
+ rb_undef_method(CLASS_OF(rb_cMatch), "allocate");
rb_define_method(rb_cMatch, "initialize_copy", match_init_copy, 1);
rb_define_method(rb_cMatch, "regexp", match_regexp, 0);
diff --git a/regcomp.c b/regcomp.c
index 59b1f40d46..bd38313875 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -138,6 +138,27 @@ bitset_on_num(BitSetRef bs)
}
#endif
+// Attempt to right size allocated buffers for a regex post compile
+static void
+onig_reg_resize(regex_t *reg)
+{
+ do {
+ if (!reg->used) {
+ xfree(reg->p);
+ reg->alloc = 0;
+ reg->p = 0;
+ }
+ else if (reg->alloc > reg->used) {
+ unsigned char *new_ptr = xrealloc(reg->p, reg->used);
+ // Skip the right size optimization if memory allocation fails
+ if (new_ptr) {
+ reg->alloc = reg->used;
+ reg->p = new_ptr;
+ }
+ }
+ } while ((reg = reg->chain) != 0);
+}
+
extern int
onig_bbuf_init(BBuf* buf, OnigDistance size)
{
@@ -772,7 +793,7 @@ compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
}
}
else if (qn->upper == 0) {
- if (qn->is_refered != 0) /* /(?<n>..){0}/ */
+ if (qn->is_referred != 0) /* /(?<n>..){0}/ */
len = SIZE_OP_JUMP + tlen;
else
len = 0;
@@ -901,7 +922,7 @@ compile_quantifier_node(QtfrNode* qn, regex_t* reg)
}
}
else if (qn->upper == 0) {
- if (qn->is_refered != 0) { /* /(?<n>..){0}/ */
+ if (qn->is_referred != 0) { /* /(?<n>..){0}/ */
r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
if (r) return r;
r = compile_tree(qn->target, reg);
@@ -1005,7 +1026,7 @@ compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
else
len += SIZE_OP_JUMP + mod_tlen + SIZE_OP_PUSH;
}
- else if (qn->upper == 0 && qn->is_refered != 0) { /* /(?<n>..){0}/ */
+ else if (qn->upper == 0 && qn->is_referred != 0) { /* /(?<n>..){0}/ */
len = SIZE_OP_JUMP + tlen;
}
else if (!infinite && qn->greedy &&
@@ -1124,7 +1145,7 @@ compile_quantifier_node(QtfrNode* qn, regex_t* reg)
r = add_opcode_rel_addr(reg, OP_PUSH, -(mod_tlen + (int )SIZE_OP_PUSH));
}
}
- else if (qn->upper == 0 && qn->is_refered != 0) { /* /(?<n>..){0}/ */
+ else if (qn->upper == 0 && qn->is_referred != 0) { /* /(?<n>..){0}/ */
r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
if (r) return r;
r = compile_tree(qn->target, reg);
@@ -1914,7 +1935,7 @@ noname_disable_map(Node** plink, GroupNumRemap* map, int* counter)
}
static int
-renumber_node_backref(Node* node, GroupNumRemap* map)
+renumber_node_backref(Node* node, GroupNumRemap* map, const int num_mem)
{
int i, pos, n, old_num;
int *backs;
@@ -1930,6 +1951,7 @@ renumber_node_backref(Node* node, GroupNumRemap* map)
backs = bn->back_dynamic;
for (i = 0, pos = 0; i < old_num; i++) {
+ if (backs[i] > num_mem) return ONIGERR_INVALID_BACKREF;
n = map[backs[i]].new_val;
if (n > 0) {
backs[pos] = n;
@@ -1942,7 +1964,7 @@ renumber_node_backref(Node* node, GroupNumRemap* map)
}
static int
-renumber_by_map(Node* node, GroupNumRemap* map)
+renumber_by_map(Node* node, GroupNumRemap* map, const int num_mem)
{
int r = 0;
@@ -1950,28 +1972,30 @@ renumber_by_map(Node* node, GroupNumRemap* map)
case NT_LIST:
case NT_ALT:
do {
- r = renumber_by_map(NCAR(node), map);
+ r = renumber_by_map(NCAR(node), map, num_mem);
} while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
case NT_QTFR:
- r = renumber_by_map(NQTFR(node)->target, map);
+ r = renumber_by_map(NQTFR(node)->target, map, num_mem);
break;
case NT_ENCLOSE:
{
EncloseNode* en = NENCLOSE(node);
- if (en->type == ENCLOSE_CONDITION)
+ if (en->type == ENCLOSE_CONDITION) {
+ if (en->regnum > num_mem) return ONIGERR_INVALID_BACKREF;
en->regnum = map[en->regnum].new_val;
- r = renumber_by_map(en->target, map);
+ }
+ r = renumber_by_map(en->target, map, num_mem);
}
break;
case NT_BREF:
- r = renumber_node_backref(node, map);
+ r = renumber_node_backref(node, map, num_mem);
break;
case NT_ANCHOR:
if (NANCHOR(node)->target)
- r = renumber_by_map(NANCHOR(node)->target, map);
+ r = renumber_by_map(NANCHOR(node)->target, map, num_mem);
break;
default:
@@ -2033,7 +2057,7 @@ disable_noname_group_capture(Node** root, regex_t* reg, ScanEnv* env)
r = noname_disable_map(root, map, &counter);
if (r != 0) return r;
- r = renumber_by_map(*root, map);
+ r = renumber_by_map(*root, map, env->num_mem);
if (r != 0) return r;
for (i = 1, pos = 1; i <= env->num_mem; i++) {
@@ -3106,7 +3130,7 @@ subexp_recursive_check_trav(Node* node, ScanEnv* env)
r = subexp_recursive_check_trav(NQTFR(node)->target, env);
if (NQTFR(node)->upper == 0) {
if (r == FOUND_CALLED_NODE)
- NQTFR(node)->is_refered = 1;
+ NQTFR(node)->is_referred = 1;
}
break;
@@ -3596,6 +3620,7 @@ expand_case_fold_string(Node* node, regex_t* reg)
if (n == 0 || varlen == 0) {
if (IS_NULL(snode)) {
if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
+ onig_node_free(top_root);
top_root = root = onig_node_list_add(NULL_NODE, prev_node);
if (IS_NULL(root)) {
onig_node_free(prev_node);
@@ -3627,6 +3652,7 @@ expand_case_fold_string(Node* node, regex_t* reg)
}
}
if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
+ onig_node_free(top_root);
top_root = root = onig_node_list_add(NULL_NODE, prev_node);
if (IS_NULL(root)) {
onig_node_free(prev_node);
@@ -3677,6 +3703,7 @@ expand_case_fold_string(Node* node, regex_t* reg)
if (r != 0) goto mem_err;
if (IS_NOT_NULL(prev_node) && IS_NULL(root)) {
+ onig_node_free(top_root);
top_root = root = onig_node_list_add(NULL_NODE, prev_node);
if (IS_NULL(root)) {
onig_node_free(srem);
@@ -5883,6 +5910,7 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
#endif
end:
+ onig_reg_resize(reg);
return r;
err_unset:
diff --git a/regenc.h b/regenc.h
index 969e114bfd..16ed6c39da 100644
--- a/regenc.h
+++ b/regenc.h
@@ -122,7 +122,7 @@ typedef struct {
} PosixBracketEntryType;
#define POSIX_BRACKET_ENTRY_INIT(name, ctype) \
- {(short int )(sizeof(name) - 1), (name), (ctype)}
+ {(short int )(sizeof(name) - 1), name, (ctype)}
#ifndef numberof
# define numberof(array) (int )(sizeof(array) / sizeof((array)[0]))
diff --git a/regerror.c b/regerror.c
index aff6354196..efcfefffdf 100644
--- a/regerror.c
+++ b/regerror.c
@@ -242,8 +242,8 @@ static int to_ascii(OnigEncoding enc, UChar *s, UChar *end,
}
-/* for ONIG_MAX_ERROR_MESSAGE_LEN */
-#define MAX_ERROR_PAR_LEN 30
+/* < ONIG_MAX_ERROR_MESSAGE_LEN - max length of messages with %n */
+#define MAX_ERROR_PAR_LEN 50
extern int
onig_error_code_to_str(UChar* s, OnigPosition code, ...)
@@ -356,7 +356,8 @@ onig_vsnprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
*s++ = *p++;
}
else if (!ONIGENC_IS_CODE_PRINT(enc, *p) &&
- !ONIGENC_IS_CODE_SPACE(enc, *p)) {
+ (!ONIGENC_IS_CODE_SPACE(enc, *p) ||
+ ONIGENC_IS_CODE_CNTRL(enc, *p))) {
sprint_byte_with_x((char* )bs, (unsigned int )(*p++));
len = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, bs);
bp = bs;
diff --git a/regexec.c b/regexec.c
index 9e5f559731..07900deeb2 100644
--- a/regexec.c
+++ b/regexec.c
@@ -323,7 +323,9 @@ onig_region_init(OnigRegion* region)
region->allocated = 0;
region->beg = (OnigPosition* )0;
region->end = (OnigPosition* )0;
+#ifdef USE_CAPTURE_HISTORY
region->history_root = (OnigCaptureTreeNode* )0;
+#endif
}
extern OnigRegion*
@@ -1461,9 +1463,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
# define CASE(x) L_##x: sbegin = s; OPCODE_EXEC_HOOK;
# define DEFAULT L_DEFAULT:
# define NEXT sprev = sbegin; JUMP
-# define JUMP goto *oplabels[*p++]
+# define JUMP RB_GNUC_EXTENSION_BLOCK(goto *oplabels[*p++])
- static const void *oplabels[] = {
+ RB_GNUC_EXTENSION static const void *oplabels[] = {
&&L_OP_FINISH, /* matching process terminator (no more alternative) */
&&L_OP_END, /* pattern code terminator (success end) */
@@ -1811,14 +1813,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
NEXT;
CASE(OP_EXACT1) MOP_IN(OP_EXACT1);
-#if 0
DATA_ENSURE(1);
if (*p != *s) goto fail;
p++; s++;
-#endif
- if (*p != *s++) goto fail;
- DATA_ENSURE(0);
- p++;
MOP_OUT;
NEXT;
@@ -2164,7 +2161,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
s += n;
}
MOP_OUT;
- NEXT;
+ JUMP;
CASE(OP_ANYCHAR_ML_STAR) MOP_IN(OP_ANYCHAR_ML_STAR);
while (DATA_ENSURE_CHECK1) {
@@ -2181,7 +2178,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
}
}
MOP_OUT;
- NEXT;
+ JUMP;
CASE(OP_ANYCHAR_STAR_PEEK_NEXT) MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
while (DATA_ENSURE_CHECK1) {
@@ -2506,6 +2503,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_MEMORY_START) MOP_IN(OP_MEMORY_START);
GET_MEMNUM_INC(mem, p);
mem_start_stk[mem] = (OnigStackIndex )((void* )s);
+ mem_end_stk[mem] = INVALID_STACK_INDEX;
MOP_OUT;
JUMP;
@@ -2530,8 +2528,8 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_MEMORY_END_PUSH_REC) MOP_IN(OP_MEMORY_END_PUSH_REC);
GET_MEMNUM_INC(mem, p);
STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
- STACK_PUSH_MEM_END(mem, s);
mem_start_stk[mem] = GET_STACK_INDEX(stkp);
+ STACK_PUSH_MEM_END(mem, s);
MOP_OUT;
JUMP;
@@ -3904,12 +3902,17 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
UChar* range, UChar** low, UChar** high, UChar** low_prev)
{
UChar *p, *pprev = (UChar* )NULL;
+ size_t input_len = end - str;
#ifdef ONIG_DEBUG_SEARCH
fprintf(stderr, "forward_search_range: str: %"PRIuPTR" (%p), end: %"PRIuPTR" (%p), s: %"PRIuPTR" (%p), range: %"PRIuPTR" (%p)\n",
(uintptr_t )str, str, (uintptr_t )end, end, (uintptr_t )s, s, (uintptr_t )range, range);
#endif
+ if (reg->dmin > input_len) {
+ return 0;
+ }
+
p = s;
if (reg->dmin > 0) {
if (ONIGENC_IS_SINGLEBYTE(reg->enc)) {
@@ -3917,6 +3920,8 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
}
else {
UChar *q = p + reg->dmin;
+
+ if (q >= end) return 0; /* fail */
while (p < q) p += enclen(reg->enc, p, end);
}
}
@@ -4000,18 +4005,25 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
}
else {
if (reg->dmax != ONIG_INFINITE_DISTANCE) {
- *low = p - reg->dmax;
- if (*low > s) {
- *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
- *low, end, (const UChar** )low_prev);
- if (low_prev && IS_NULL(*low_prev))
- *low_prev = onigenc_get_prev_char_head(reg->enc,
- (pprev ? pprev : s), *low, end);
+ if (p < str + reg->dmax) {
+ *low = (UChar* )str;
+ if (low_prev)
+ *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low, end);
}
else {
- if (low_prev)
- *low_prev = onigenc_get_prev_char_head(reg->enc,
- (pprev ? pprev : str), *low, end);
+ *low = p - reg->dmax;
+ if (*low > s) {
+ *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
+ *low, end, (const UChar** )low_prev);
+ if (low_prev && IS_NULL(*low_prev))
+ *low_prev = onigenc_get_prev_char_head(reg->enc,
+ (pprev ? pprev : s), *low, end);
+ }
+ else {
+ if (low_prev)
+ *low_prev = onigenc_get_prev_char_head(reg->enc,
+ (pprev ? pprev : str), *low, end);
+ }
}
}
}
@@ -4037,6 +4049,11 @@ backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
UChar** low, UChar** high)
{
UChar *p;
+ size_t input_len = end - str;
+
+ if (reg->dmin > input_len) {
+ return 0;
+ }
range += reg->dmin;
p = s;
@@ -4539,8 +4556,10 @@ onig_scan(regex_t* reg, const UChar* str, const UChar* end,
if (rs != 0)
return rs;
- if (region->end[0] == start - str)
- start++;
+ if (region->end[0] == start - str) {
+ if (start >= end) break;
+ start += enclen(reg->enc, start, end);
+ }
else
start = str + region->end[0];
@@ -4610,4 +4629,3 @@ onig_copy_encoding(OnigEncodingType *to, OnigEncoding from)
{
*to = *from;
}
-
diff --git a/regint.h b/regint.h
index a2f5bbba1d..0740429688 100644
--- a/regint.h
+++ b/regint.h
@@ -52,7 +52,7 @@
#ifndef UNALIGNED_WORD_ACCESS
# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
- defined(__powerpc64__) || \
+ defined(__powerpc64__) || defined(__aarch64__) || \
defined(__mc68020__)
# define UNALIGNED_WORD_ACCESS 1
# else
diff --git a/regparse.c b/regparse.c
index 1e0dfd99bb..24ff5b9a18 100644
--- a/regparse.c
+++ b/regparse.c
@@ -108,7 +108,7 @@ extern void onig_set_verb_warn_func(OnigWarnFunc f)
onig_verb_warn = f;
}
-static void CC_DUP_WARN(ScanEnv *env);
+static void CC_DUP_WARN(ScanEnv *env, OnigCodePoint from, OnigCodePoint to);
static unsigned int ParseDepthLimit = DEFAULT_PARSE_DEPTH_LIMIT;
@@ -174,7 +174,7 @@ bbuf_clone(BBuf** rto, BBuf* from)
#define BITSET_SET_BIT_CHKDUP(bs, pos) do { \
- if (BITSET_AT(bs, pos)) CC_DUP_WARN(env); \
+ if (BITSET_AT(bs, pos)) CC_DUP_WARN(env, pos, pos); \
BS_ROOM(bs, pos) |= BS_BIT(pos); \
} while (0)
@@ -493,7 +493,7 @@ onig_print_names(FILE* fp, regex_t* reg)
if (IS_NOT_NULL(t)) {
fprintf(fp, "name table\n");
- onig_st_foreach(t, i_print_name_entry, (HashDataType )fp);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_print_name_entry, (HashDataType )fp);
fputs("\n", fp);
}
return 0;
@@ -516,7 +516,7 @@ names_clear(regex_t* reg)
NameTable* t = (NameTable* )reg->name_table;
if (IS_NOT_NULL(t)) {
- onig_st_foreach(t, i_free_name_entry, 0);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_free_name_entry, 0);
}
return 0;
}
@@ -585,7 +585,7 @@ onig_foreach_name(regex_t* reg,
narg.reg = reg;
narg.arg = arg;
narg.enc = reg->enc; /* should be pattern encoding. */
- onig_st_foreach(t, i_names, (HashDataType )&narg);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_names, (HashDataType )&narg);
}
return narg.ret;
}
@@ -613,7 +613,7 @@ onig_renumber_name_table(regex_t* reg, GroupNumRemap* map)
NameTable* t = (NameTable* )reg->name_table;
if (IS_NOT_NULL(t)) {
- onig_st_foreach(t, i_renumber_name, (HashDataType )map);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_renumber_name, (HashDataType )map);
}
return 0;
}
@@ -1315,7 +1315,7 @@ node_new_quantifier(int lower, int upper, int by_number)
NQTFR(node)->target_empty_info = NQ_TARGET_ISNOT_EMPTY;
NQTFR(node)->head_exact = NULL_NODE;
NQTFR(node)->next_head_exact = NULL_NODE;
- NQTFR(node)->is_refered = 0;
+ NQTFR(node)->is_referred = 0;
if (by_number != 0)
NQTFR(node)->state |= NST_BY_NUMBER;
@@ -1720,7 +1720,7 @@ add_code_range_to_buf0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePo
if (inc_n != 1) {
if (checkdup && from <= data[low*2+1]
&& (data[low*2] <= from || data[low*2+1] <= to))
- CC_DUP_WARN(env);
+ CC_DUP_WARN(env, from, to);
if (from > data[low*2])
from = data[low*2];
if (to < data[(high - 1)*2 + 1])
@@ -2187,7 +2187,6 @@ enum ReduceType {
RQ_AQ, /* to '*?' */
RQ_QQ, /* to '??' */
RQ_P_QQ, /* to '+)??' */
- RQ_PQ_Q /* to '+?)?' */
};
static enum ReduceType const ReduceTypeTable[6][6] = {
@@ -2197,7 +2196,7 @@ static enum ReduceType const ReduceTypeTable[6][6] = {
{RQ_A, RQ_A, RQ_DEL, RQ_ASIS, RQ_P_QQ, RQ_DEL}, /* '+' */
{RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL, RQ_AQ, RQ_AQ}, /* '??' */
{RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL}, /* '*?' */
- {RQ_ASIS, RQ_PQ_Q, RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL} /* '+?' */
+ {RQ_ASIS, RQ_ASIS, RQ_ASIS, RQ_AQ, RQ_AQ, RQ_DEL} /* '+?' */
};
extern void
@@ -2234,12 +2233,6 @@ onig_reduce_nested_quantifier(Node* pnode, Node* cnode)
c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 1;
return ;
break;
- case RQ_PQ_Q:
- p->target = cnode;
- p->lower = 0; p->upper = 1; p->greedy = 1;
- c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 0;
- return ;
- break;
case RQ_ASIS:
p->target = cnode;
return ;
@@ -2886,14 +2879,18 @@ CLOSE_BRACKET_WITHOUT_ESC_WARN(ScanEnv* env, UChar* c)
#endif
static void
-CC_DUP_WARN(ScanEnv *env)
+CC_DUP_WARN(ScanEnv *env, OnigCodePoint from ARG_UNUSED, OnigCodePoint to ARG_UNUSED)
{
if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ;
if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_DUP) &&
!(env->warnings_flag & ONIG_SYN_WARN_CC_DUP)) {
+#ifdef WARN_ALL_CC_DUP
+ onig_syntax_warn(env, "character class has duplicated range: %04x-%04x", from, to);
+#else
env->warnings_flag |= ONIG_SYN_WARN_CC_DUP;
onig_syntax_warn(env, "character class has duplicated range");
+#endif
}
}
@@ -3644,7 +3641,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
prev = p;
num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
- if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
+ if (num < 0 || 0xff < num) return ONIGERR_TOO_BIG_NUMBER;
if (p == prev) { /* can't read nothing. */
num = 0; /* but, it's not error */
}
@@ -4344,7 +4341,7 @@ fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env)
OnigEncoding enc = env->enc;
UChar *prev, *start, *p = *src;
- r = 0;
+ r = ONIGERR_INVALID_CHAR_PROPERTY_NAME;
start = prev = p;
while (!PEND) {
@@ -4358,7 +4355,6 @@ fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env)
return r;
}
else if (c == '(' || c == ')' || c == '{' || c == '|') {
- r = ONIGERR_INVALID_CHAR_PROPERTY_NAME;
break;
}
}
@@ -4440,8 +4436,8 @@ next_state_class(CClassNode* cc, CClassNode* asc_cc,
static int
next_state_val(CClassNode* cc, CClassNode* asc_cc,
- OnigCodePoint *vs, OnigCodePoint v,
- int* vs_israw, int v_israw,
+ OnigCodePoint *from, OnigCodePoint to,
+ int* from_israw, int to_israw,
enum CCVALTYPE intype, enum CCVALTYPE* type,
enum CCSTATE* state, ScanEnv* env)
{
@@ -4450,15 +4446,15 @@ next_state_val(CClassNode* cc, CClassNode* asc_cc,
switch (*state) {
case CCS_VALUE:
if (*type == CCV_SB) {
- BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs));
+ BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*from));
if (IS_NOT_NULL(asc_cc))
- BITSET_SET_BIT(asc_cc->bs, (int )(*vs));
+ BITSET_SET_BIT(asc_cc->bs, (int )(*from));
}
else if (*type == CCV_CODE_POINT) {
- r = add_code_range(&(cc->mbuf), env, *vs, *vs);
+ r = add_code_range(&(cc->mbuf), env, *from, *from);
if (r < 0) return r;
if (IS_NOT_NULL(asc_cc)) {
- r = add_code_range0(&(asc_cc->mbuf), env, *vs, *vs, 0);
+ r = add_code_range0(&(asc_cc->mbuf), env, *from, *from, 0);
if (r < 0) return r;
}
}
@@ -4467,51 +4463,43 @@ next_state_val(CClassNode* cc, CClassNode* asc_cc,
case CCS_RANGE:
if (intype == *type) {
if (intype == CCV_SB) {
- if (*vs > 0xff || v > 0xff)
+ if (*from > 0xff || to > 0xff)
return ONIGERR_INVALID_CODE_POINT_VALUE;
- if (*vs > v) {
+ if (*from > to) {
if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
goto ccs_range_end;
else
return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
}
- bitset_set_range(env, cc->bs, (int )*vs, (int )v);
+ bitset_set_range(env, cc->bs, (int )*from, (int )to);
if (IS_NOT_NULL(asc_cc))
- bitset_set_range(env, asc_cc->bs, (int )*vs, (int )v);
+ bitset_set_range(env, asc_cc->bs, (int )*from, (int )to);
}
else {
- r = add_code_range(&(cc->mbuf), env, *vs, v);
+ r = add_code_range(&(cc->mbuf), env, *from, to);
if (r < 0) return r;
if (IS_NOT_NULL(asc_cc)) {
- r = add_code_range0(&(asc_cc->mbuf), env, *vs, v, 0);
+ r = add_code_range0(&(asc_cc->mbuf), env, *from, to, 0);
if (r < 0) return r;
}
}
}
else {
-#if 0
- if (intype == CCV_CODE_POINT && *type == CCV_SB) {
-#endif
- if (*vs > v) {
- if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
- goto ccs_range_end;
- else
- return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
- }
- bitset_set_range(env, cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
- r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*vs, v);
+ if (*from > to) {
+ if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
+ goto ccs_range_end;
+ else
+ return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
+ }
+ bitset_set_range(env, cc->bs, (int )*from, (int )(to < 0xff ? to : 0xff));
+ r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*from, to);
+ if (r < 0) return r;
+ if (IS_NOT_NULL(asc_cc)) {
+ bitset_set_range(env, asc_cc->bs, (int )*from, (int )(to < 0xff ? to : 0xff));
+ r = add_code_range0(&(asc_cc->mbuf), env, (OnigCodePoint )*from, to, 0);
if (r < 0) return r;
- if (IS_NOT_NULL(asc_cc)) {
- bitset_set_range(env, asc_cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
- r = add_code_range0(&(asc_cc->mbuf), env, (OnigCodePoint )*vs, v, 0);
- if (r < 0) return r;
- }
-#if 0
}
- else
- return ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE;
-#endif
}
ccs_range_end:
*state = CCS_COMPLETE;
@@ -4526,9 +4514,9 @@ next_state_val(CClassNode* cc, CClassNode* asc_cc,
break;
}
- *vs_israw = v_israw;
- *vs = v;
- *type = intype;
+ *from_israw = to_israw;
+ *from = to;
+ *type = intype;
return 0;
}
@@ -4667,7 +4655,7 @@ parse_char_class(Node** np, Node** asc_np, OnigToken* tok, UChar** src, UChar* e
p = psave;
for (i = 1; i < len; i++) {
(void)fetch_token_in_cc(tok, &p, end, env);
- /* no need to check the retun value (already checked above) */
+ /* no need to check the return value (already checked above) */
}
fetched = 0;
}
@@ -4767,6 +4755,12 @@ parse_char_class(Node** np, Node** asc_np, OnigToken* tok, UChar** src, UChar* e
CC_ESC_WARN(env, (UChar* )"-");
goto range_end_val;
}
+
+ if (val_type == CCV_CLASS) {
+ r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS;
+ goto err;
+ }
+
state = CCS_RANGE;
}
else if (state == CCS_START) {
@@ -5699,731 +5693,329 @@ static int
propname2ctype(ScanEnv* env, const char* propname)
{
UChar* name = (UChar* )propname;
+ UChar* name_end = name + strlen(propname);
int ctype = env->enc->property_name_to_ctype(ONIG_ENCODING_ASCII,
- name, name + strlen(propname));
+ name, name_end);
+ if (ctype < 0) {
+ onig_scan_env_set_error_string(env, ctype, name, name_end);
+ }
return ctype;
}
static int
-node_extended_grapheme_cluster(Node** np, ScanEnv* env)
+add_property_to_cc(CClassNode* cc, const char* propname, int not, ScanEnv* env)
{
- Node* tmp = NULL;
- Node* np1 = NULL;
- Node* list = NULL;
- Node* list2 = NULL;
- Node* alt = NULL;
- Node* alt2 = NULL;
- BBuf *pbuf1 = NULL;
- int r = 0;
- int num1;
- UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
- OnigOptionType option;
-
-#ifdef USE_UNICODE_PROPERTIES
- if (ONIGENC_IS_UNICODE(env->enc)) {
- /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
- CClassNode* cc;
- OnigCodePoint sb_out = (ONIGENC_MBC_MINLEN(env->enc) > 1) ? 0x00 : 0x80;
- int extend = propname2ctype(env, "Grapheme_Cluster_Break=Extend");
-
- /* Prepend*
- * ( RI-sequence | Hangul-Syllable | !Control )
- * ( Grapheme_Extend | SpacingMark )* */
-
- /* ( Grapheme_Extend | SpacingMark )* */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, extend, 0, 0, env);
- if (r != 0) goto err;
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=SpacingMark"), 0, 0, env);
- if (r != 0) goto err;
- r = add_code_range(&(cc->mbuf), env, 0x200D, 0x200D);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list = tmp;
- np1 = NULL;
-
- /* ( RI-sequence | Hangul-Syllable | !Control ) */
- /* !Control */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Control"), 1, 0, env);
- if (r != 0) goto err;
- if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
- BBuf *pbuf2 = NULL;
- r = add_code_range(&pbuf1, env, 0x0a, 0x0a);
- if (r != 0) goto err;
- r = add_code_range(&pbuf1, env, 0x0d, 0x0d);
- if (r != 0) goto err;
- r = and_code_range_buf(cc->mbuf, 0, pbuf1, 1, &pbuf2, env);
- if (r != 0) {
- bbuf_free(pbuf2);
- goto err;
- }
- bbuf_free(pbuf1);
- pbuf1 = NULL;
- bbuf_free(cc->mbuf);
- cc->mbuf = pbuf2;
- }
- else {
- BITSET_CLEAR_BIT(cc->bs, 0x0a);
- BITSET_CLEAR_BIT(cc->bs, 0x0d);
- }
-
- tmp = onig_node_new_alt(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- np1 = NULL;
-
- /* Hangul-Syllable
- * := L* V+ T*
- * | L* LV V* T*
- * | L* LVT T*
- * | L+
- * | T+ */
-
- /* T+ */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = onig_node_new_alt(np1, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- np1 = NULL;
-
- /* L+ */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = onig_node_new_alt(np1, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- np1 = NULL;
-
- /* L* LVT T* */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LVT"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list2 = NULL;
-
- /* L* LV V* T* */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LV"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list2 = NULL;
-
- /* L* V+ T* */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
+ int ctype = propname2ctype(env, propname);
+ if (ctype < 0) return ctype;
+ return add_ctype_to_cc(cc, ctype, not, 0, env);
+}
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
- if (r != 0) goto err;
+/*
+ * helper methods for node_extended_grapheme_cluster (/\X/)
+ */
+static int
+create_property_node(Node **np, ScanEnv* env, const char* propname)
+{
+ int r;
+ CClassNode* cc;
- tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
+ *np = node_new_cclass();
+ if (IS_NULL(*np)) return ONIGERR_MEMORY;
+ cc = NCCLASS(*np);
+ r = add_property_to_cc(cc, propname, 0, env);
+ if (r != 0)
+ onig_node_free(*np);
+ return r;
+}
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
+static int
+quantify_node(Node **np, int lower, int upper)
+{
+ Node* tmp = node_new_quantifier(lower, upper, 0);
+ if (IS_NULL(tmp)) return ONIGERR_MEMORY;
+ NQTFR(tmp)->target = *np;
+ *np = tmp;
+ return 0;
+}
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
- if (r != 0) goto err;
+static int
+quantify_property_node(Node **np, ScanEnv* env, const char* propname, char repetitions)
+{
+ int r;
+ int lower = 0;
+ int upper = REPEAT_INFINITE;
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list2 = NULL;
-
- /* Emoji sequence := (E_Base | EBG) Extend* E_Modifier?
- * (ZWJ (Glue_After_Zwj | EBG Extend* E_Modifier?) )* */
-
- /* ZWJ (Glue_After_Zwj | E_Base_GAZ Extend* E_Modifier?) */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
- if (r != 0) goto err;
+ r = create_property_node(np, env, propname);
+ if (r != 0) return r;
+ switch (repetitions) {
+ case '?': upper = 1; break;
+ case '+': lower = 1; break;
+ case '*': break;
+ case '2': lower = upper = 2; break;
+ default : return ONIGERR_PARSER_BUG;
+ }
+ return quantify_node(np, lower, upper);
+}
- tmp = node_new_quantifier(0, 1, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
+#define LIST 0
+#define ALT 1
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
+/* IMPORTANT: Make sure node_array ends with NULL_NODE */
+static int
+create_node_from_array(int kind, Node **np, Node **node_array)
+{
+ Node* tmp = NULL_NODE;
+ int i = 0;
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, extend, 0, 0, env);
- if (r != 0) goto err;
+ while (node_array[i] != NULL_NODE) i++;
+ while (--i >= 0) {
+ *np = kind==LIST ? node_new_list(node_array[i], tmp)
+ : onig_node_new_alt(node_array[i], tmp);
+ if (IS_NULL(*np)) {
+ while (i >= 0) {
+ onig_node_free(node_array[i]);
+ node_array[i--] = NULL_NODE;
+ }
+ onig_node_free(tmp);
+ return ONIGERR_MEMORY;
+ }
+ else
+ node_array[i] = NULL_NODE;
+ tmp = *np;
+ }
+ return 0;
+}
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
+#define R_ERR(call) r=(call);if(r!=0)goto err
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
+/* Memory layout for common node array:
+ * The main purpose is to be able to easily free all leftover nodes
+ * after an error. As a side effect, we share some memory.
+ *
+ * The layout is as shown below (each line corresponds to one call of
+ * create_node_from_array()). Because create_node_from_array sets all
+ * nodes of the source to NULL_NODE, we can overlap the target array
+ * as long as we do not override the actual target location.
+ *
+ * Target Array name Index
+ *
+ * node_array 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ * top_alts alts[5] 0 1 2 3 4*
+ * alts+1 list[4] 0 1 2 3*
+ * list+1 core_alts[7] 0 1 2 3 4 5 6*
+ * core_alts+0 H_list[4] 0 1 2 3*
+ * H_list+1 H_alt2[4] 0 1 2 3*
+ * h_alt2+1 H_list2[3] 0 1 2*
+ * core_alts+4 XP_list[4] 0 1 2 3*
+ * XP_list+1 Ex_list[4] 0 1 2 3*
+ */
+#define NODE_COMMON_SIZE 16
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
- if (r != 0) goto err;
+static int
+node_extended_grapheme_cluster(Node** np, ScanEnv* env)
+{
+ Node* tmp = NULL;
+ Node* np1 = NULL;
+ Node* top_alt = NULL;
+ int r = 0;
+ int num1;
+ int i;
+ int any_target_position;
+ UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
+ OnigOptionType option;
+ /* node_common is function-global so that we can free all nodes
+ * in case of error. Unused slots are set to NULL_NODE at all times. */
+ Node *node_common[NODE_COMMON_SIZE];
+ Node **alts = node_common+0; /* size: 5 */
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- alt2 = tmp;
- list2 = NULL;
-
- /* Glue_After_Zwj */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, extend, 0, 0, env);
- if (r != 0) goto err;
+ for (i=0; i<NODE_COMMON_SIZE; i++)
+ node_common[i] = NULL_NODE;
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
+ /* CRLF, common for both Unicode and non-Unicode */
+ /* \x0D\x0A */
+ r = ONIGENC_CODE_TO_MBC(env->enc, 0x0D, buf);
+ if (r < 0) goto err;
+ num1 = r;
+ r = ONIGENC_CODE_TO_MBC(env->enc, 0x0A, buf + num1);
+ if (r < 0) goto err;
+ alts[0] = node_new_str_raw(buf, buf + num1 + r);
+ if (IS_NULL(alts[0])) goto err;
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
+#ifdef USE_UNICODE_PROPERTIES
+ if (ONIGENC_IS_UNICODE(env->enc)) { /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
+ CClassNode* cc;
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- {
- static const OnigCodePoint ranges[] = {
- 13,
- 0x1F308, 0x1F308,
- 0x1F33E, 0x1F33E,
- 0x1F373, 0x1F373,
- 0x1F393, 0x1F393,
- 0x1F3A4, 0x1F3A4,
- 0x1F3A8, 0x1F3A8,
- 0x1F3EB, 0x1F3EB,
- 0x1F3ED, 0x1F3ED,
- 0x1F4BB, 0x1F4BC,
- 0x1F527, 0x1F527,
- 0x1F52C, 0x1F52C,
- 0x1F680, 0x1F680,
- 0x1F692, 0x1F692,
- };
- r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
- if (r != 0) goto err;
+ if (propname2ctype(env, "Grapheme_Cluster_Break=Extend") < 0) goto err;
+ /* Unicode 11.0.0
+ * CRLF (already done)
+ * | [Control CR LF]
+ * | precore* core postcore*
+ * | . (to catch invalid stuff, because this seems to be spec for String#grapheme_clusters) */
+
+ /* [Control CR LF] (CR and LF are not in the spec, but this is a conformed fix) */
+ alts[1] = node_new_cclass();
+ if (IS_NULL(alts[1])) goto err;
+ cc = NCCLASS(alts[1]);
+ R_ERR(add_property_to_cc(cc, "Grapheme_Cluster_Break=Control", 0, env));
+ if (ONIGENC_MBC_MINLEN(env->enc) > 1) { /* UTF-16/UTF-32 */
+ R_ERR(add_code_range(&(cc->mbuf), env, 0x000A, 0x000A)); /* CR */
+ R_ERR(add_code_range(&(cc->mbuf), env, 0x000D, 0x000D)); /* LF */
}
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt2);
- if (IS_NULL(tmp)) goto err;
- alt2 = tmp;
- list2 = NULL;
-
- /* Emoji variation sequence
- * http://unicode.org/Public/emoji/4.0/emoji-zwj-sequences.txt
- */
- r = ONIGENC_CODE_TO_MBC(env->enc, 0xfe0f, buf);
- if (r < 0) goto err;
- np1 = node_new_str_raw(buf, buf + r);
- if (IS_NULL(np1)) goto err;
-
- tmp = node_new_quantifier(0, 1, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- {
- static const OnigCodePoint ranges[] = {
- 4,
- 0x2640, 0x2640,
- 0x2642, 0x2642,
- 0x2695, 0x2696,
- 0x2708, 0x2708,
- };
- r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
- if (r != 0) goto err;
+ else {
+ BITSET_SET_BIT(cc->bs, 0x0a);
+ BITSET_SET_BIT(cc->bs, 0x0d);
}
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt2);
- if (IS_NULL(tmp)) goto err;
- alt2 = tmp;
- list2 = NULL;
-
- tmp = node_new_list(alt2, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- alt2 = NULL;
-
- /* ZWJ */
- r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
- if (r < 0) goto err;
- np1 = node_new_str_raw(buf, buf + r);
- if (IS_NULL(np1)) goto err;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = list2;
- np1 = tmp;
- list2 = NULL;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- /* E_Modifier? */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, 1, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- /* Extend* */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, extend, 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- /* (E_Base | EBG) */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
+ /* precore* core postcore* */
{
- static const OnigCodePoint ranges[] = {
- 8,
- 0x1F3C2, 0x1F3C2,
- 0x1F3C7, 0x1F3C7,
- 0x1F3CC, 0x1F3CC,
- 0x1F3F3, 0x1F3F3,
- 0x1F441, 0x1F441,
- 0x1F46F, 0x1F46F,
- 0x1F574, 0x1F574,
- 0x1F6CC, 0x1F6CC,
- };
- r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
- if (r != 0) goto err;
- }
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base"), 0, 0, env);
- if (r != 0) goto err;
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list2 = NULL;
-
- /* ZWJ (E_Base_GAZ | Glue_After_Zwj) E_Modifier? */
- /* a sequence starting with ZWJ seems artificial, but GraphemeBreakTest
- * has such examples.
- * http://www.unicode.org/Public/9.0.0/ucd/auxiliary/GraphemeBreakTest.html
- */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, 1, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
- if (r != 0) goto err;
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
- if (r != 0) goto err;
+ Node **list = alts + 3; /* size: 4 */
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
- if (r < 0) goto err;
- np1 = node_new_str_raw(buf, buf + r);
- if (IS_NULL(np1)) goto err;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list2 = NULL;
-
- /* RI-Sequence := Regional_Indicator{2} */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_code_range(&(cc->mbuf), env, 0x1F1E6, 0x1F1FF);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(2, 2, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list2 = NULL;
-
- tmp = node_new_list(alt, list);
- if (IS_NULL(tmp)) goto err;
- list = tmp;
- alt = NULL;
-
- /* Prepend* */
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list);
- if (IS_NULL(tmp)) goto err;
- list = tmp;
- np1 = NULL;
-
- /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
- np1 = node_new_anychar();
- if (IS_NULL(np1)) goto err;
-
- option = env->option;
- ONOFF(option, ONIG_OPTION_MULTILINE, 0);
- tmp = node_new_option(option);
- if (IS_NULL(tmp)) goto err;
- NENCLOSE(tmp)->target = np1;
- np1 = tmp;
-
- tmp = onig_node_new_alt(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- np1 = NULL;
-
- /* Prepend+ */
- r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
- if (r < 0) goto err;
- np1 = node_new_str_raw(buf, buf + r);
- if (IS_NULL(np1)) goto err;
-
- tmp = node_new_quantifier(0, 1, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, NULL_NODE);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- np1 = node_new_cclass();
- if (IS_NULL(np1)) goto err;
- cc = NCCLASS(np1);
- r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
- if (r != 0) goto err;
-
- tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
- if (IS_NULL(tmp)) goto err;
- NQTFR(tmp)->target = np1;
- np1 = tmp;
-
- tmp = node_new_list(np1, list2);
- if (IS_NULL(tmp)) goto err;
- list2 = tmp;
- np1 = NULL;
-
- tmp = onig_node_new_alt(list2, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list2 = NULL;
+ /* precore*; precore := Prepend */
+ R_ERR(quantify_property_node(list+0, env, "Grapheme_Cluster_Break=Prepend", '*'));
- tmp = onig_node_new_alt(list, alt);
- if (IS_NULL(tmp)) goto err;
- alt = tmp;
- list = NULL;
+ /* core := hangul-syllable
+ * | ri-sequence
+ * | xpicto-sequence
+ * | [^Control CR LF] */
+ {
+ Node **core_alts = list + 2; /* size: 7 */
+
+ /* hangul-syllable :=
+ * L* (V+ | LV V* | LVT) T*
+ * | L+
+ * | T+ */
+ /* hangul-syllable is an alternative (would be called H_alt)
+ * inside an alternative, but we flatten it into core_alts */
+
+ /* L* (V+ | LV V* | LVT) T* */
+ {
+ Node **H_list = core_alts + 1; /* size: 4 */
+ R_ERR(quantify_property_node(H_list+0, env, "Grapheme_Cluster_Break=L", '*'));
+
+ /* V+ | LV V* | LVT */
+ {
+ Node **H_alt2 = H_list + 2; /* size: 4 */
+ R_ERR(quantify_property_node(H_alt2+0, env, "Grapheme_Cluster_Break=V", '+'));
+
+ /* LV V* */
+ {
+ Node **H_list2 = H_alt2 + 2; /* size: 3 */
+
+ R_ERR(create_property_node(H_list2+0, env, "Grapheme_Cluster_Break=LV"));
+ R_ERR(quantify_property_node(H_list2+1, env, "Grapheme_Cluster_Break=V", '*'));
+ R_ERR(create_node_from_array(LIST, H_alt2+1, H_list2));
+ }
+
+ R_ERR(create_property_node(H_alt2+2, env, "Grapheme_Cluster_Break=LVT"));
+ R_ERR(create_node_from_array(ALT, H_list+1, H_alt2));
+ }
+
+ R_ERR(quantify_property_node(H_list+2, env, "Grapheme_Cluster_Break=T", '*'));
+ R_ERR(create_node_from_array(LIST, core_alts+0, H_list));
+ }
+
+ R_ERR(quantify_property_node(core_alts+1, env, "Grapheme_Cluster_Break=L", '+'));
+ R_ERR(quantify_property_node(core_alts+2, env, "Grapheme_Cluster_Break=T", '+'));
+ /* end of hangul-syllable */
+
+ /* ri-sequence := RI RI */
+ R_ERR(quantify_property_node(core_alts+3, env, "Regional_Indicator", '2'));
+
+ /* xpicto-sequence := \p{Extended_Pictographic} (Extend* ZWJ \p{Extended_Pictographic})* */
+ {
+ Node **XP_list = core_alts + 5; /* size: 3 */
+ R_ERR(create_property_node(XP_list+0, env, "Extended_Pictographic"));
+
+ /* (Extend* ZWJ \p{Extended_Pictographic})* */
+ {
+ Node **Ex_list = XP_list + 2; /* size: 4 */
+ /* assert(Ex_list+4 == node_common+NODE_COMMON_SIZE); */
+ R_ERR(quantify_property_node(Ex_list+0, env, "Grapheme_Cluster_Break=Extend", '*'));
+
+ /* ZWJ (ZERO WIDTH JOINER) */
+ r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
+ if (r < 0) goto err;
+ Ex_list[1] = node_new_str_raw(buf, buf + r);
+ if (IS_NULL(Ex_list[1])) goto err;
+
+ R_ERR(create_property_node(Ex_list+2, env, "Extended_Pictographic"));
+ R_ERR(create_node_from_array(LIST, XP_list+1, Ex_list));
+ }
+ R_ERR(quantify_node(XP_list+1, 0, REPEAT_INFINITE)); /* TODO: Check about node freeing */
+
+ R_ERR(create_node_from_array(LIST, core_alts+4, XP_list));
+ }
+
+ /* [^Control CR LF] */
+ core_alts[5] = node_new_cclass();
+ if (IS_NULL(core_alts[5])) goto err;
+ cc = NCCLASS(core_alts[5]);
+ if (ONIGENC_MBC_MINLEN(env->enc) > 1) { /* UTF-16/UTF-32 */
+ BBuf *inverted_buf = NULL;
+
+ /* TODO: fix false warning */
+ const int dup_not_warned = env->warnings_flag | ~ONIG_SYN_WARN_CC_DUP;
+ env->warnings_flag |= ONIG_SYN_WARN_CC_DUP;
+
+ /* Start with a positive buffer and invert at the end.
+ * Otherwise, adding single-character ranges work the wrong way. */
+ R_ERR(add_property_to_cc(cc, "Grapheme_Cluster_Break=Control", 0, env));
+ R_ERR(add_code_range(&(cc->mbuf), env, 0x000A, 0x000A)); /* CR */
+ R_ERR(add_code_range(&(cc->mbuf), env, 0x000D, 0x000D)); /* LF */
+ R_ERR(not_code_range_buf(env->enc, cc->mbuf, &inverted_buf, env));
+ cc->mbuf = inverted_buf; /* TODO: check what to do with buffer before inversion */
+
+ env->warnings_flag &= dup_not_warned; /* TODO: fix false warning */
+ }
+ else {
+ R_ERR(add_property_to_cc(cc, "Grapheme_Cluster_Break=Control", 1, env));
+ BITSET_CLEAR_BIT(cc->bs, 0x0a);
+ BITSET_CLEAR_BIT(cc->bs, 0x0d);
+ }
+
+ R_ERR(create_node_from_array(ALT, list+1, core_alts));
+ }
+
+ /* postcore*; postcore = [Extend ZWJ SpacingMark] */
+ R_ERR(create_property_node(list+2, env, "Grapheme_Cluster_Break=Extend"));
+ cc = NCCLASS(list[2]);
+ R_ERR(add_property_to_cc(cc, "Grapheme_Cluster_Break=SpacingMark", 0, env));
+ R_ERR(add_code_range(&(cc->mbuf), env, 0x200D, 0x200D));
+ R_ERR(quantify_node(list+2, 0, REPEAT_INFINITE));
+
+ R_ERR(create_node_from_array(LIST, alts+2, list));
+ }
+
+ any_target_position = 3;
}
else
#endif /* USE_UNICODE_PROPERTIES */
{
- /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
- np1 = node_new_anychar();
- if (IS_NULL(np1)) goto err;
-
- option = env->option;
- ONOFF(option, ONIG_OPTION_MULTILINE, 0);
- tmp = node_new_option(option);
- if (IS_NULL(tmp)) goto err;
- NENCLOSE(tmp)->target = np1;
- np1 = tmp;
-
- alt = onig_node_new_alt(np1, NULL_NODE);
- if (IS_NULL(alt)) goto err;
- np1 = NULL;
+ any_target_position = 1;
}
- /* \x0D\x0A */
- r = ONIGENC_CODE_TO_MBC(env->enc, 0x0D, buf);
- if (r < 0) goto err;
- num1 = r;
- r = ONIGENC_CODE_TO_MBC(env->enc, 0x0A, buf + num1);
- if (r < 0) goto err;
- np1 = node_new_str_raw(buf, buf + num1 + r);
+ /* PerlSyntax: (?s:.), RubySyntax: (?m:.), common for both Unicode and non-Unicode */
+ /* Not in Unicode spec (UAX #29), but added to catch invalid stuff,
+ * because this is Ruby spec for String#grapheme_clusters. */
+ np1 = node_new_anychar();
if (IS_NULL(np1)) goto err;
- tmp = onig_node_new_alt(np1, alt);
+ option = env->option;
+ ONOFF(option, ONIG_OPTION_MULTILINE, 0);
+ tmp = node_new_option(option);
if (IS_NULL(tmp)) goto err;
- alt = tmp;
+ NENCLOSE(tmp)->target = np1;
+ alts[any_target_position] = tmp;
np1 = NULL;
- /* (?>\x0D\x0A|...) */
+ R_ERR(create_node_from_array(ALT, &top_alt, alts));
+
+ /* (?>): For efficiency, because there is no text piece
+ * that is not in a grapheme cluster, and there is only one way
+ * to split a string into grapheme clusters. */
tmp = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
if (IS_NULL(tmp)) goto err;
- NENCLOSE(tmp)->target = alt;
+ NENCLOSE(tmp)->target = top_alt;
np1 = tmp;
#ifdef USE_UNICODE_PROPERTIES
@@ -6444,13 +6036,11 @@ node_extended_grapheme_cluster(Node** np, ScanEnv* env)
err:
onig_node_free(np1);
- onig_node_free(list);
- onig_node_free(list2);
- onig_node_free(alt);
- onig_node_free(alt2);
- bbuf_free(pbuf1);
+ for (i=0; i<NODE_COMMON_SIZE; i++)
+ onig_node_free(node_common[i]);
return (r == 0) ? ONIGERR_MEMORY : r;
}
+#undef R_ERR
static int
countbits(unsigned int bits)
diff --git a/regparse.h b/regparse.h
index 888ebf4ce6..acdd3e2f5c 100644
--- a/regparse.h
+++ b/regparse.h
@@ -186,7 +186,7 @@ typedef struct {
int target_empty_info;
struct _Node* head_exact;
struct _Node* next_head_exact;
- int is_refered; /* include called node. don't eliminate even if {0} */
+ int is_referred; /* include called node. don't eliminate even if {0} */
#ifdef USE_COMBINATION_EXPLOSION_CHECK
int comb_exp_check_num; /* 1,2,3...: check, 0: no check */
#endif
diff --git a/ruby-runner.c b/ruby-runner.c
index 99be4a0013..b756c219fa 100644
--- a/ruby-runner.c
+++ b/ruby-runner.c
@@ -1,10 +1,18 @@
#define _POSIX_C_SOURCE 200809L
+#include "ruby/internal/config.h"
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "ruby-runner.h"
+#ifdef MAKE_MJIT_BUILD_DIR
+const char MJIT_HEADER[] = BUILDDIR "/" MJIT_MIN_HEADER;
+#else
+
#define STRINGIZE(expr) STRINGIZE0(expr)
#define STRINGIZE0(expr) #expr
@@ -56,6 +64,10 @@ main(int argc, char **argv)
PATH_SEPARATOR
EXTOUT_DIR"/"ARCH
;
+#ifndef LOAD_RELATIVE
+ static const char mjit_build_dir[] = BUILDDIR"/mjit_build_dir."SOEXT;
+ struct stat stbuf;
+#endif
const size_t dirsize = sizeof(builddir);
const size_t namesize = sizeof(rubypath) - dirsize;
const char *rubyname = rubypath + dirsize;
@@ -63,6 +75,12 @@ main(int argc, char **argv)
insert_env_path(LIBPATHENV, builddir, dirsize, 1);
insert_env_path("RUBYLIB", rubylib, sizeof(rubylib), 0);
+#ifndef LOAD_RELATIVE
+ if (PRELOADENV[0] && stat(mjit_build_dir, &stbuf) == 0) {
+ insert_env_path(PRELOADENV, mjit_build_dir, sizeof(mjit_build_dir), 1);
+ setenv("MJIT_SEARCH_BUILD_DIR", "true", 0);
+ }
+#endif
if (!(p = strrchr(arg0, '/'))) p = arg0; else p++;
if (strlen(p) < namesize - 1) {
@@ -73,5 +91,8 @@ main(int argc, char **argv)
memcpy(p, rubyname, namesize);
execv(rubypath, argv);
+ perror(rubypath);
return -1;
}
+
+#endif /* MAKE_MJIT_BUILD_DIR */
diff --git a/ruby.c b/ruby.c
index c26a5dd8de..f502157e97 100644
--- a/ruby.c
+++ b/ruby.c
@@ -11,36 +11,60 @@
**********************************************************************/
-#ifdef __CYGWIN__
-#include <windows.h>
-#include <sys/cygwin.h>
-#endif
-#include "internal.h"
-#include "ruby/thread.h"
-#include "eval_intern.h"
-#include "dln.h"
+#include "ruby/internal/config.h"
+
+#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
-#include <ctype.h>
+
+#ifdef __CYGWIN__
+# include <windows.h>
+# include <sys/cygwin.h>
+#endif
#ifdef __hpux
-#include <sys/pstat.h>
+# include <sys/pstat.h>
#endif
-#if defined(LOAD_RELATIVE) && defined(HAVE_DLADDR)
-#include <dlfcn.h>
+
+#if (defined(LOAD_RELATIVE) || defined(__MACH__)) && defined(HAVE_DLADDR)
+# include <dlfcn.h>
#endif
#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+# include <unistd.h>
#endif
+
#if defined(HAVE_FCNTL_H)
-#include <fcntl.h>
+# include <fcntl.h>
#elif defined(HAVE_SYS_FCNTL_H)
-#include <sys/fcntl.h>
+# include <sys/fcntl.h>
#endif
+
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
+
+#include "dln.h"
+#include "eval_intern.h"
+#include "internal.h"
+#include "internal/error.h"
+#include "internal/file.h"
+#include "internal/inits.h"
+#include "internal/io.h"
+#include "internal/load.h"
+#include "internal/loadpath.h"
+#include "internal/missing.h"
+#include "internal/object.h"
+#include "internal/parse.h"
+#include "internal/process.h"
+#include "internal/variable.h"
+#include "mjit.h"
+#include "ruby/encoding.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+#include "ruby/version.h"
+#include "ruby/internal/error.h"
+
#ifndef MAXPATHLEN
# define MAXPATHLEN 1024
#endif
@@ -48,7 +72,7 @@
# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
-#include "ruby/util.h"
+void Init_ruby_description(void);
#ifndef HAVE_STDLIB_H
char *getenv();
@@ -63,6 +87,8 @@ char *getenv();
#define DEFAULT_RUBYGEMS_ENABLED "enabled"
#endif
+void rb_warning_category_update(unsigned int mask, unsigned int bits);
+
#define COMMA ,
#define FEATURE_BIT(bit) (1U << feature_##bit)
#define EACH_FEATURES(X, SEP) \
@@ -73,6 +99,8 @@ char *getenv();
X(rubyopt) \
SEP \
X(frozen_string_literal) \
+ SEP \
+ X(jit) \
/* END OF FEATURES */
#define EACH_DEBUG_FEATURES(X, SEP) \
X(frozen_string_literal) \
@@ -121,6 +149,24 @@ enum dump_flag_bits {
typedef struct ruby_cmdline_options ruby_cmdline_options_t;
+typedef struct {
+ unsigned int mask;
+ unsigned int set;
+} ruby_features_t;
+
+static inline void
+rb_feature_set_to(ruby_features_t *feat, unsigned int bit_mask, unsigned int bit_set)
+{
+ feat->mask |= bit_mask;
+ feat->set = (feat->set & ~bit_mask) | bit_set;
+}
+
+#define FEATURE_SET_TO(feat, bit_mask, bit_set) \
+ rb_feature_set_to(&(feat), bit_mask, bit_set)
+#define FEATURE_SET(feat, bits) FEATURE_SET_TO(feat, bits, bits)
+#define FEATURE_SET_RESTORE(feat, save) FEATURE_SET_TO(feat, (save).mask, (save).set & (save).mask)
+#define FEATURE_SET_P(feat, bits) ((feat).set & (bits))
+
struct ruby_cmdline_options {
const char *script;
VALUE script_name;
@@ -132,9 +178,12 @@ struct ruby_cmdline_options {
} enc;
} src, ext, intern;
VALUE req_list;
- unsigned int features;
+ ruby_features_t features;
+ ruby_features_t warn;
unsigned int dump;
- int safe_level;
+#if USE_MJIT
+ struct mjit_options mjit;
+#endif
int sflag, xflag;
unsigned int warning: 1;
unsigned int verbose: 1;
@@ -162,6 +211,7 @@ enum {
& ~FEATURE_BIT(gems)
#endif
& ~FEATURE_BIT(frozen_string_literal)
+ & ~FEATURE_BIT(jit)
)
};
@@ -173,11 +223,14 @@ cmdline_options_init(ruby_cmdline_options_t *opt)
opt->src.enc.index = src_encoding_index;
opt->ext.enc.index = -1;
opt->intern.enc.index = -1;
- opt->features = DEFAULT_FEATURES;
+ opt->features.set = DEFAULT_FEATURES;
+#ifdef MJIT_FORCE_ENABLE /* to use with: ./configure cppflags="-DMJIT_FORCE_ENABLE" */
+ opt->features.set |= FEATURE_BIT(jit);
+#endif
return opt;
}
-static NODE *load_file(VALUE parser, VALUE fname, VALUE f, int script,
+static rb_ast_t *load_file(VALUE parser, VALUE fname, VALUE f, int script,
ruby_cmdline_options_t *opt);
static VALUE open_load_file(VALUE fname_v, int *xflag);
static void forbid_setid(const char *, const ruby_cmdline_options_t *);
@@ -188,20 +241,26 @@ static struct {
char **argv;
} origarg;
+static const char esc_standout[] = "\n\033[1;7m";
+static const char esc_bold[] = "\033[1m";
+static const char esc_reset[] = "\033[0m";
+static const char esc_none[] = "";
+
static void
-show_usage_line(const char *str, unsigned int namelen, unsigned int secondlen, int help)
+show_usage_line(const char *str, unsigned int namelen, unsigned int secondlen, int help, int highlight, unsigned int w)
{
- const unsigned int w = 16;
- const int wrap = help && namelen + secondlen - 2 > w;
- printf(" %.*s%-*.*s%-*s%s\n", namelen-1, str,
+ const char *sb = highlight ? esc_bold : esc_none;
+ const char *se = highlight ? esc_reset : esc_none;
+ const int wrap = help && namelen + secondlen - 1 > w;
+ printf(" %s%.*s%-*.*s%s%-*s%s\n", sb, namelen-1, str,
(wrap ? 0 : w - namelen + 1),
- (help ? secondlen-1 : 0), str + namelen,
+ (help ? secondlen-1 : 0), str + namelen, se,
(wrap ? w + 3 : 0), (wrap ? "\n" : ""),
str + namelen + secondlen);
}
static void
-usage(const char *name, int help)
+usage(const char *name, int help, int highlight, int columns)
{
/* This message really ought to be max 23 lines.
* Removed -h because the user already knows that option. Others? */
@@ -232,11 +291,12 @@ usage(const char *name, int help)
M("-rlibrary", "", "require the library before executing your script"),
M("-s", "", "enable some switch parsing for switches after script name"),
M("-S", "", "look for the script using PATH environment variable"),
- M("-T[level=1]", "", "turn on tainting checks"),
- M("-v", ", --verbose", "print version number, then turn on verbose mode"),
+ M("-v", "", "print the version number, then turn on verbose mode"),
M("-w", "", "turn warnings on for your script"),
- M("-W[level=2]", "", "set warning level; 0=silence, 1=medium, 2=verbose"),
+ M("-W[level=2|:category]", "", "set warning level; 0=silence, 1=medium, 2=verbose"),
M("-x[directory]", "", "strip off text before #!ruby line and perhaps cd to directory"),
+ M("--jit", "", "enable JIT with default options (experimental)"),
+ M("--jit-[option]","", "enable JIT with an option (experimental)"),
M("-h", "", "show this message, --help for more info"),
};
static const struct message help_msg[] = {
@@ -247,8 +307,10 @@ usage(const char *name, int help)
"enable or disable features. see below for available features"),
M("--external-encoding=encoding", ", --internal-encoding=encoding",
"specify the default external or internal character encoding"),
- M("--version", "", "print the version"),
+ M("--verbose", "", "turn on verbose mode and disable script from stdin"),
+ M("--version", "", "print the version number, then exit"),
M("--help", "", "show this message, -h for short message"),
+ M("--backtrace-limit=num", "", "limit the maximum length of backtrace"),
};
static const struct message dumps[] = {
M("insns", "", "instruction sequences"),
@@ -261,25 +323,50 @@ usage(const char *name, int help)
M("did_you_mean", "", "did_you_mean (default: "DEFAULT_RUBYGEMS_ENABLED")"),
M("rubyopt", "", "RUBYOPT environment variable (default: enabled)"),
M("frozen-string-literal", "", "freeze all string literals (default: disabled)"),
+ M("jit", "", "JIT compiler (default: disabled)"),
+ };
+ static const struct message warn_categories[] = {
+ M("deprecated", "", "deprecated features"),
+ M("experimental", "", "experimental features"),
+ };
+ static const struct message mjit_options[] = {
+ M("--jit-warnings", "", "Enable printing JIT warnings"),
+ M("--jit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
+ M("--jit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
+ M("--jit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
+ M("--jit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
+ M("--jit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: 100)"),
+ M("--jit-min-calls=num", "", "Number of calls to trigger JIT (for testing, default: 10000)"),
};
int i;
+ const char *sb = highlight ? esc_standout+1 : esc_none;
+ const char *se = highlight ? esc_reset : esc_none;
const int num = numberof(usage_msg) - (help ? 1 : 0);
-#define SHOW(m) show_usage_line((m).str, (m).namelen, (m).secondlen, help)
+ unsigned int w = (columns > 80 ? (columns - 79) / 2 : 0) + 16;
+#define SHOW(m) show_usage_line((m).str, (m).namelen, (m).secondlen, help, highlight, w)
- printf("Usage: %s [switches] [--] [programfile] [arguments]\n", name);
+ printf("%sUsage:%s %s [switches] [--] [programfile] [arguments]\n", sb, se, name);
for (i = 0; i < num; ++i)
SHOW(usage_msg[i]);
if (!help) return;
+ if (highlight) sb = esc_standout;
+
for (i = 0; i < numberof(help_msg); ++i)
SHOW(help_msg[i]);
- puts("Dump List:");
+ printf("%s""Dump List:%s\n", sb, se);
for (i = 0; i < numberof(dumps); ++i)
SHOW(dumps[i]);
- puts("Features:");
+ printf("%s""Features:%s\n", sb, se);
for (i = 0; i < numberof(features); ++i)
SHOW(features[i]);
+ printf("%s""Warning categories:%s\n", sb, se);
+ for (i = 0; i < numberof(warn_categories); ++i)
+ SHOW(warn_categories[i]);
+ printf("%s""JIT options (experimental):%s\n", sb, se);
+ for (i = 0; i < numberof(mjit_options); ++i)
+ SHOW(mjit_options[i]);
}
#define rubylib_path_new rb_str_new
@@ -442,22 +529,61 @@ str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
# define str_conv_enc(str, from, to) (str)
#endif
-void ruby_init_loadpath_safe(int safe_level);
+void ruby_init_loadpath(void);
-void
-ruby_init_loadpath(void)
-{
- ruby_init_loadpath_safe(0);
-}
-
-#if defined(LOAD_RELATIVE) && defined(HAVE_DLADDR) && !defined(__CYGWIN__)
+#if defined(LOAD_RELATIVE) || defined(__MACH__)
static VALUE
-dladdr_path(const void* addr)
+runtime_libruby_path(void)
{
+#if defined _WIN32 || defined __CYGWIN__
+ DWORD len = RSTRING_EMBED_LEN_MAX, ret;
+ VALUE path;
+ VALUE wsopath = rb_str_new(0, len*sizeof(WCHAR));
+ WCHAR *wlibpath;
+ char *libpath;
+
+ while (wlibpath = (WCHAR *)RSTRING_PTR(wsopath),
+ ret = GetModuleFileNameW(libruby, wlibpath, len),
+ (ret == len))
+ {
+ rb_str_modify_expand(wsopath, len*sizeof(WCHAR));
+ rb_str_set_len(wsopath, (len += len)*sizeof(WCHAR));
+ }
+ if (!ret || ret > len) rb_fatal("failed to get module file name");
+#if defined __CYGWIN__
+ {
+ const int win_to_posix = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
+ size_t newsize = cygwin_conv_path(win_to_posix, wlibpath, 0, 0);
+ if (!newsize) rb_fatal("failed to convert module path to cygwin");
+ path = rb_str_new(0, newsize);
+ libpath = RSTRING_PTR(path);
+ if (cygwin_conv_path(win_to_posix, wlibpath, libpath, newsize)) {
+ rb_str_resize(path, 0);
+ }
+ }
+#else
+ {
+ DWORD i;
+ for (len = ret, i = 0; i < len; ++i) {
+ if (wlibpath[i] == L'\\') {
+ wlibpath[i] = L'/';
+ ret = i+1; /* chop after the last separator */
+ }
+ }
+ }
+ len = WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, NULL, 0, NULL, NULL);
+ path = rb_utf8_str_new(0, len);
+ libpath = RSTRING_PTR(path);
+ WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, libpath, len, NULL, NULL);
+#endif
+ rb_str_resize(wsopath, 0);
+ return path;
+#elif defined(HAVE_DLADDR)
Dl_info dli;
VALUE fname, path;
+ const void* addr = (void *)(VALUE)expand_include_path;
- if (!dladdr(addr, &dli)) {
+ if (!dladdr((void *)addr, &dli)) {
return rb_str_new(0, 0);
}
#ifdef __linux__
@@ -472,102 +598,78 @@ dladdr_path(const void* addr)
}
rb_str_resize(fname, 0);
return path;
+#else
+# error relative load path is not supported on this platform.
+#endif
}
#endif
#define INITIAL_LOAD_PATH_MARK rb_intern_const("@gem_prelude_index")
+VALUE ruby_archlibdir_path, ruby_prefix_path;
+#if defined(__MACH__)
+// A path to libruby.dylib itself or where it's statically linked to.
+VALUE rb_libruby_selfpath;
+#endif
+
void
-ruby_init_loadpath_safe(int safe_level)
+ruby_init_loadpath(void)
{
- VALUE load_path;
+ VALUE load_path, archlibdir = 0;
ID id_initial_load_path_mark;
const char *paths = ruby_initial_load_paths;
-#if defined LOAD_RELATIVE
-# if defined HAVE_DLADDR || defined __CYGWIN__ || defined _WIN32
-# define VARIABLE_LIBPATH 1
-# else
-# define VARIABLE_LIBPATH 0
+#if defined(LOAD_RELATIVE) || defined(__MACH__)
+ VALUE libruby_path = runtime_libruby_path();
+# if defined(__MACH__)
+ rb_libruby_selfpath = libruby_path;
+ rb_gc_register_address(&rb_libruby_selfpath);
# endif
-# if VARIABLE_LIBPATH
+#endif
+
+#if defined LOAD_RELATIVE
+#if !defined ENABLE_MULTIARCH
+# define RUBY_ARCH_PATH ""
+#elif defined RUBY_ARCH
+# define RUBY_ARCH_PATH "/"RUBY_ARCH
+#else
+# define RUBY_ARCH_PATH "/"RUBY_PLATFORM
+#endif
char *libpath;
VALUE sopath;
-# else
- char libpath[MAXPATHLEN + 1];
-# endif
size_t baselen;
- char *p;
+ const char *p;
-#if defined _WIN32 || defined __CYGWIN__
- {
- DWORD len = RSTRING_EMBED_LEN_MAX, ret, i;
- VALUE wsopath = rb_str_new(0, len*sizeof(WCHAR));
- WCHAR *wlibpath;
- while (wlibpath = (WCHAR *)RSTRING_PTR(wsopath),
- ret = GetModuleFileNameW(libruby, wlibpath, len),
- (ret == len))
- {
- rb_str_modify_expand(wsopath, len*sizeof(WCHAR));
- rb_str_set_len(wsopath, (len += len)*sizeof(WCHAR));
- }
- if (!ret || ret > len) rb_fatal("failed to get module file name");
- for (len = ret, i = 0; i < len; ++i) {
- if (wlibpath[i] == L'\\') {
- wlibpath[i] = L'/';
- ret = i+1; /* chop after the last separator */
- }
- }
- len = WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, NULL, 0, NULL, NULL);
- sopath = rb_utf8_str_new(0, len);
- libpath = RSTRING_PTR(sopath);
- WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, libpath, len, NULL, NULL);
- rb_str_resize(wsopath, 0);
- }
-#elif defined(HAVE_DLADDR)
- sopath = dladdr_path((void *)(VALUE)expand_include_path);
+ sopath = libruby_path;
libpath = RSTRING_PTR(sopath);
-#endif
-#if !VARIABLE_LIBPATH
- libpath[sizeof(libpath) - 1] = '\0';
-#endif
-#if defined DOSISH && !defined _WIN32
- translit_char(libpath, '\\', '/');
-#elif defined __CYGWIN__
- {
- const int win_to_posix = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
- size_t newsize = cygwin_conv_path(win_to_posix, libpath, 0, 0);
- if (newsize > 0) {
- VALUE rubylib = rb_str_new(0, newsize);
- p = RSTRING_PTR(rubylib);
- if (cygwin_conv_path(win_to_posix, libpath, p, newsize) == 0) {
- rb_str_resize(sopath, 0);
- sopath = rubylib;
- libpath = p;
- }
- }
- }
-#endif
p = strrchr(libpath, '/');
if (p) {
- static const char bindir[] = "/bin";
+ static const char libdir[] = "/"
#ifdef LIBDIR_BASENAME
- static const char libdir[] = "/"LIBDIR_BASENAME;
+ LIBDIR_BASENAME
#else
- static const char libdir[] = "/lib";
+ "lib"
#endif
+ RUBY_ARCH_PATH;
+ const ptrdiff_t libdir_len = (ptrdiff_t)sizeof(libdir)
+ - rb_strlen_lit(RUBY_ARCH_PATH) - 1;
+ static const char bindir[] = "/bin";
const ptrdiff_t bindir_len = (ptrdiff_t)sizeof(bindir) - 1;
- const ptrdiff_t libdir_len = (ptrdiff_t)sizeof(libdir) - 1;
-#ifdef ENABLE_MULTIARCH
- char *p2 = NULL;
+ const char *p2 = NULL;
+#ifdef ENABLE_MULTIARCH
multiarch:
#endif
if (p - libpath >= bindir_len && !STRNCASECMP(p - bindir_len, bindir, bindir_len)) {
p -= bindir_len;
+ archlibdir = rb_str_subseq(sopath, 0, p - libpath);
+ rb_str_cat_cstr(archlibdir, libdir);
+ OBJ_FREEZE_RAW(archlibdir);
}
else if (p - libpath >= libdir_len && !strncmp(p - libdir_len, libdir, libdir_len)) {
+ archlibdir = rb_str_subseq(sopath, 0, (p2 ? p2 : p) - libpath);
+ OBJ_FREEZE_RAW(archlibdir);
p -= libdir_len;
}
#ifdef ENABLE_MULTIARCH
@@ -581,37 +683,28 @@ ruby_init_loadpath_safe(int safe_level)
p = p2;
}
#endif
-#if !VARIABLE_LIBPATH
- *p = 0;
-#endif
- }
-#if !VARIABLE_LIBPATH
- else {
- strlcpy(libpath, ".", sizeof(libpath));
- p = libpath + 1;
}
baselen = p - libpath;
-#define PREFIX_PATH() rb_str_new(libpath, baselen)
-#else
- baselen = p - libpath;
rb_str_resize(sopath, baselen);
libpath = RSTRING_PTR(sopath);
#define PREFIX_PATH() sopath
-#endif
-
#define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)
-
#define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), (path), (len))
#else
const size_t exec_prefix_len = strlen(ruby_exec_prefix);
#define RUBY_RELATIVE(path, len) rubylib_path_new((path), (len))
#define PREFIX_PATH() RUBY_RELATIVE(ruby_exec_prefix, exec_prefix_len)
#endif
+ rb_gc_register_address(&ruby_prefix_path);
+ ruby_prefix_path = PREFIX_PATH();
+ OBJ_FREEZE_RAW(ruby_prefix_path);
+ if (!archlibdir) archlibdir = ruby_prefix_path;
+ rb_gc_register_address(&ruby_archlibdir_path);
+ ruby_archlibdir_path = archlibdir;
+
load_path = GET_VM()->load_path;
- if (safe_level == 0) {
- ruby_push_include(getenv("RUBYLIB"), identical_path);
- }
+ ruby_push_include(getenv("RUBYLIB"), identical_path);
id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
while (*paths) {
@@ -622,7 +715,7 @@ ruby_init_loadpath_safe(int safe_level)
paths += len + 1;
}
- rb_const_set(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"), rb_obj_freeze(PREFIX_PATH()));
+ rb_const_set(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"), ruby_prefix_path);
}
@@ -633,11 +726,9 @@ add_modules(VALUE *req_list, const char *mod)
VALUE feature;
if (!list) {
- *req_list = list = rb_ary_new();
- RBASIC_CLEAR_CLASS(list);
+ *req_list = list = rb_ary_tmp_new(0);
}
- feature = rb_str_new2(mod);
- RBASIC_CLEAR_CLASS(feature);
+ feature = rb_str_cat_cstr(rb_str_tmp_new(0), mod);
rb_ary_push(list, feature);
}
@@ -739,6 +830,7 @@ moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt)
char **argv, *p;
const char *ap = 0;
VALUE argstr, argary;
+ void *ptr;
while (ISSPACE(*s)) s++;
if (!*s) return;
@@ -761,7 +853,8 @@ moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt)
argc = RSTRING_LEN(argary) / sizeof(ap);
ap = 0;
rb_str_cat(argary, (char *)&ap, sizeof(ap));
- argv = (char **)RSTRING_PTR(argary);
+ argv = ptr = ALLOC_N(char *, argc);
+ MEMMOVE(argv, RSTRING_PTR(argary), char *, argc);
while ((i = proc_options(argc, argv, opt, envopt)) > 1 && envopt && (argc -= i) > 0) {
argv += i;
@@ -774,6 +867,7 @@ moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt)
}
}
+ ruby_xfree(ptr);
/* get rid of GC */
rb_str_resize(argary, 0);
rb_str_resize(argstr, 0);
@@ -783,7 +877,7 @@ static int
name_match_p(const char *name, const char *str, size_t len)
{
if (len == 0) return 0;
- do {
+ while (1) {
while (TOLOWER(*str) == *name) {
if (!--len || !*++str) return 1;
++name;
@@ -793,8 +887,7 @@ name_match_p(const char *name, const char *str, size_t len)
if (*name != '-' && *name != '_') return 0;
++name;
++str;
- } while (len > 0);
- return !*name;
+ }
}
#define NAME_MATCH_P(name, str, len) \
@@ -818,22 +911,20 @@ static void
feature_option(const char *str, int len, void *arg, const unsigned int enable)
{
static const char list[] = EACH_FEATURES(LITERAL_NAME_ELEMENT, ", ");
- unsigned int *argp = arg;
+ ruby_features_t *argp = arg;
unsigned int mask = ~0U;
-#if AMBIGUOUS_FEATURE_NAMES
unsigned int set = 0U;
+#if AMBIGUOUS_FEATURE_NAMES
int matched = 0;
-#define SET_FEATURE(bit) \
- if (NAME_MATCH_P(#bit, str, len)) {set |= mask = FEATURE_BIT(bit); ++matched;}
+# define FEATURE_FOUND ++matched
#else
-#define SET_FEATURE(bit) \
- if (NAME_MATCH_P(#bit, str, len)) {mask = FEATURE_BIT(bit); goto found;}
+# define FEATURE_FOUND goto found
#endif
+#define SET_FEATURE(bit) \
+ if (NAME_MATCH_P(#bit, str, len)) {set |= mask = FEATURE_BIT(bit); FEATURE_FOUND;}
EACH_FEATURES(SET_FEATURE, ;);
if (NAME_MATCH_P("all", str, len)) {
- found:
- *argp = (*argp & ~mask) | (mask & enable);
- return;
+ goto found;
}
#if AMBIGUOUS_FEATURE_NAMES
if (matched == 1) goto found;
@@ -853,6 +944,11 @@ feature_option(const char *str, int len, void *arg, const unsigned int enable)
rb_warn("unknown argument for --%s: `%.*s'",
enable ? "enable" : "disable", len, str);
rb_warn("features are [%.*s].", (int)strlen(list), list);
+ return;
+
+ found:
+ FEATURE_SET_TO(*argp, mask, (mask & enable));
+ return;
}
static void
@@ -874,7 +970,12 @@ static void
debug_option(const char *str, int len, void *arg)
{
static const char list[] = EACH_DEBUG_FEATURES(LITERAL_NAME_ELEMENT, ", ");
-#define SET_WHEN_DEBUG(bit) SET_WHEN(#bit, DEBUG_BIT(bit), str, len)
+ ruby_features_t *argp = arg;
+#define SET_WHEN_DEBUG(bit) \
+ if (NAME_MATCH_P(#bit, str, len)) { \
+ FEATURE_SET(*argp, DEBUG_BIT(bit)); \
+ return; \
+ }
EACH_DEBUG_FEATURES(SET_WHEN_DEBUG, ;);
#ifdef RUBY_DEVEL
if (ruby_patchlevel < 0 && ruby_env_debug_option(str, len, 0)) return;
@@ -916,6 +1017,53 @@ set_option_encoding_once(const char *type, VALUE *name, const char *e, long elen
#define set_source_encoding_once(opt, e, elen) \
set_option_encoding_once("source", &(opt)->src.enc.name, (e), (elen))
+#if USE_MJIT
+static void
+setup_mjit_options(const char *s, struct mjit_options *mjit_opt)
+{
+#define opt_match(s, l, name) \
+ ((((l) > rb_strlen_lit(name)) ? (s)[rb_strlen_lit(name)] == '=' : \
+ (l) == rb_strlen_lit(name)) && \
+ memcmp((s), name, rb_strlen_lit(name)) == 0 && \
+ (((s) += rb_strlen_lit(name)), 1))
+#define opt_match_noarg(s, l, name) \
+ opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --jit-" name " is ignored"), 1) : 1)
+#define opt_match_arg(s, l, name) \
+ opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--jit-" name " needs an argument"), 0))
+ if (*s != '-') return;
+ const size_t l = strlen(++s);
+ if (*s == 0) return;
+ else if (opt_match_noarg(s, l, "warnings")) {
+ mjit_opt->warnings = 1;
+ }
+ else if (opt_match(s, l, "debug")) {
+ if (*s)
+ mjit_opt->debug_flags = strdup(s + 1);
+ else
+ mjit_opt->debug = 1;
+ }
+ else if (opt_match_noarg(s, l, "wait")) {
+ mjit_opt->wait = 1;
+ }
+ else if (opt_match_noarg(s, l, "save-temps")) {
+ mjit_opt->save_temps = 1;
+ }
+ else if (opt_match(s, l, "verbose")) {
+ mjit_opt->verbose = *s ? atoi(s + 1) : 1;
+ }
+ else if (opt_match_arg(s, l, "max-cache")) {
+ mjit_opt->max_cache_size = atoi(s + 1);
+ }
+ else if (opt_match_arg(s, l, "min-calls")) {
+ mjit_opt->min_calls = atoi(s + 1);
+ }
+ else {
+ rb_raise(rb_eRuntimeError,
+ "invalid MJIT option `%s' (--help will show valid MJIT options)", s);
+ }
+}
+#endif
+
static long
proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
{
@@ -974,10 +1122,29 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
warning = 1;
ruby_verbose = Qtrue;
}
+ FEATURE_SET(opt->warn, RB_WARN_CATEGORY_ALL_BITS);
s++;
goto reswitch;
case 'W':
+ if (s[1] == ':') {
+ unsigned int bits = 0;
+ static const char no_prefix[] = "no-";
+ int enable = strncmp(s += 2, no_prefix, sizeof(no_prefix)-1) != 0;
+ if (!enable) s += sizeof(no_prefix)-1;
+ size_t len = strlen(s);
+ if (NAME_MATCH_P("deprecated", s, len)) {
+ bits = 1U << RB_WARN_CATEGORY_DEPRECATED;
+ }
+ else if (NAME_MATCH_P("experimental", s, len)) {
+ bits = 1U << RB_WARN_CATEGORY_EXPERIMENTAL;
+ }
+ else {
+ rb_warn("unknown warning category: `%s'", s);
+ }
+ if (bits) FEATURE_SET_TO(opt->warn, bits, enable ? bits : 0);
+ break;
+ }
{
size_t numlen;
int v = 2; /* -W as -W2 */
@@ -985,7 +1152,7 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
if (*++s) {
v = scan_oct(s, 1, &numlen);
if (numlen == 0)
- v = 1;
+ v = 2;
s += numlen;
}
if (!opt->warning) {
@@ -1002,6 +1169,17 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
}
}
warning = 1;
+ switch (v) {
+ case 0:
+ FEATURE_SET_TO(opt->warn, RB_WARN_CATEGORY_ALL_BITS, 0);
+ break;
+ case 1:
+ FEATURE_SET_TO(opt->warn, 1U << RB_WARN_CATEGORY_DEPRECATED, 0);
+ break;
+ default:
+ FEATURE_SET(opt->warn, RB_WARN_CATEGORY_ALL_BITS);
+ break;
+ }
}
goto reswitch;
@@ -1136,21 +1314,6 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
}
goto reswitch;
- case 'T':
- {
- size_t numlen;
- int v = 1;
-
- if (*++s) {
- v = scan_oct(s, 2, &numlen);
- if (numlen == 0)
- v = 1;
- s += numlen;
- }
- if (v > opt->safe_level) opt->safe_level = v;
- }
- goto reswitch;
-
case 'I':
forbid_setid("-I");
if (*++s)
@@ -1268,6 +1431,14 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
opt->verbose = 1;
ruby_verbose = Qtrue;
}
+ else if (strncmp("jit", s, 3) == 0) {
+#if USE_MJIT
+ FEATURE_SET(opt->features, FEATURE_BIT(jit));
+ setup_mjit_options(s + 3, &opt->mjit);
+#else
+ rb_warn("MJIT support is disabled.");
+#endif
+ }
else if (strcmp("yydebug", s) == 0) {
if (envopt) goto noenvopt_long;
opt->dump |= DUMP_BIT(yydebug);
@@ -1280,6 +1451,12 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
opt->dump |= DUMP_BIT(help);
goto switch_end;
}
+ else if (is_option_with_arg("backtrace-limit", Qfalse, Qfalse)) {
+ char *e;
+ long n = strtol(s, &e, 10);
+ if (errno == ERANGE || n < 0 || *e) rb_raise(rb_eRuntimeError, "wrong limit for backtrace length");
+ rb_backtrace_length_limit = n;
+ }
else {
rb_raise(rb_eRuntimeError,
"invalid option --%s (-h will show valid options)", s);
@@ -1292,16 +1469,9 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
default:
{
- if (ISPRINT(*s)) {
- rb_raise(rb_eRuntimeError,
+ rb_raise(rb_eRuntimeError,
"invalid option -%c (-h will show valid options)",
(int)(unsigned char)*s);
- }
- else {
- rb_raise(rb_eRuntimeError,
- "invalid option -\\x%02X (-h will show valid options)",
- (int)(unsigned char)*s);
- }
}
goto switch_end;
@@ -1329,13 +1499,39 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
return argc0 - argc;
}
+void Init_builtin_features(void);
+
static void
ruby_init_prelude(void)
{
- Init_prelude();
+ Init_builtin_features();
rb_const_remove(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"));
}
+void rb_call_builtin_inits(void);
+
+static void
+ruby_opt_init(ruby_cmdline_options_t *opt)
+{
+ if (opt->dump & dump_exit_bits) return;
+
+ if (opt->features.set & FEATURE_BIT(gems)) {
+ rb_define_module("Gem");
+ if (opt->features.set & FEATURE_BIT(did_you_mean)) {
+ rb_define_module("DidYouMean");
+ }
+ }
+
+ rb_warning_category_update(opt->warn.mask, opt->warn.set);
+
+ Init_ext(); /* load statically linked extensions before rubygems */
+ rb_call_builtin_inits();
+ ruby_init_prelude();
+
+ ruby_set_script_name(opt->script_name);
+ require_libraries(&opt->req_list);
+}
+
static int
opt_enc_index(VALUE enc_name)
{
@@ -1354,15 +1550,16 @@ opt_enc_index(VALUE enc_name)
#define rb_progname (GET_VM()->progname)
#define rb_orig_progname (GET_VM()->orig_progname)
VALUE rb_argv0;
+VALUE rb_e_script;
static VALUE
-false_value(void)
+false_value(ID _x, VALUE *_y)
{
return Qfalse;
}
static VALUE
-true_value(void)
+true_value(ID _x, VALUE *_y)
{
return Qtrue;
}
@@ -1394,7 +1591,7 @@ uscore_get(void)
*/
static VALUE
-rb_f_sub(int argc, VALUE *argv)
+rb_f_sub(int argc, VALUE *argv, VALUE _)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("sub"), argc, argv);
rb_lastline_set(str);
@@ -1413,7 +1610,7 @@ rb_f_sub(int argc, VALUE *argv)
*/
static VALUE
-rb_f_gsub(int argc, VALUE *argv)
+rb_f_gsub(int argc, VALUE *argv, VALUE _)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("gsub"), argc, argv);
rb_lastline_set(str);
@@ -1425,13 +1622,13 @@ rb_f_gsub(int argc, VALUE *argv)
* chop -> $_
*
* Equivalent to <code>($_.dup).chop!</code>, except <code>nil</code>
- * is never returned. See <code>String#chop!</code>.
+ * is never returned. See String#chop!.
* Available only when -p/-n command line option specified.
*
*/
static VALUE
-rb_f_chop(void)
+rb_f_chop(VALUE _)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chop"), 0, 0);
rb_lastline_set(str);
@@ -1445,54 +1642,141 @@ rb_f_chop(void)
* chomp(string) -> $_
*
* Equivalent to <code>$_ = $_.chomp(<em>string</em>)</code>. See
- * <code>String#chomp</code>.
+ * String#chomp.
* Available only when -p/-n command line option specified.
*
*/
static VALUE
-rb_f_chomp(int argc, VALUE *argv)
+rb_f_chomp(int argc, VALUE *argv, VALUE _)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chomp"), argc, argv);
rb_lastline_set(str);
return str;
}
+static void
+setup_pager_env(void)
+{
+ if (!getenv("LESS")) ruby_setenv("LESS", "-R"); // Output "raw" control characters.
+}
+
+#ifdef _WIN32
+static int
+tty_enabled(void)
+{
+ HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
+ DWORD m;
+ if (!GetConsoleMode(h, &m)) return 0;
+# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
+# endif
+ if (!(m & ENABLE_VIRTUAL_TERMINAL_PROCESSING)) return 0;
+ return 1;
+}
+#elif !defined(HAVE_WORKING_FORK)
+# define tty_enabled() 0
+#endif
+
+static VALUE
+copy_str(VALUE str, rb_encoding *enc, bool intern)
+{
+ if (!intern) {
+ if (rb_enc_str_coderange_scan(str, enc) == ENC_CODERANGE_BROKEN)
+ return 0;
+ return rb_enc_associate(rb_str_dup(str), enc);
+ }
+ return rb_enc_interned_str(RSTRING_PTR(str), RSTRING_LEN(str), enc);
+}
+
static VALUE
process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
{
- NODE *tree = 0;
+ rb_ast_t *ast = 0;
VALUE parser;
VALUE script_name;
const rb_iseq_t *iseq;
rb_encoding *enc, *lenc;
#if UTF8_PATH
- rb_encoding *uenc, *ienc = 0;
+ rb_encoding *ienc = 0;
+ rb_encoding *const uenc = rb_utf8_encoding();
#endif
const char *s;
char fbuf[MAXPATHLEN];
int i = (int)proc_options(argc, argv, opt, 0);
- rb_binding_t *toplevel_binding;
- const struct rb_block *base_block;
unsigned int dump = opt->dump & dump_exit_bits;
+ rb_vm_t *vm = GET_VM();
+ const long loaded_before_enc = RARRAY_LEN(vm->loaded_features);
if (opt->dump & (DUMP_BIT(usage)|DUMP_BIT(help))) {
+ int tty = isatty(1);
const char *const progname =
(argc > 0 && argv && argv[0] ? argv[0] :
origarg.argc > 0 && origarg.argv && origarg.argv[0] ? origarg.argv[0] :
ruby_engine);
- usage(progname, (opt->dump & DUMP_BIT(help)));
+ int columns = 0;
+ if ((opt->dump & DUMP_BIT(help)) && tty) {
+ const char *pager_env = getenv("RUBY_PAGER");
+ if (!pager_env) pager_env = getenv("PAGER");
+ if (pager_env && *pager_env && isatty(0)) {
+ const char *columns_env = getenv("COLUMNS");
+ if (columns_env) columns = atoi(columns_env);
+ VALUE pager = rb_str_new_cstr(pager_env);
+#ifdef HAVE_WORKING_FORK
+ int fds[2];
+ if (rb_pipe(fds) == 0) {
+ rb_pid_t pid = rb_fork();
+ if (pid > 0) {
+ /* exec PAGER with reading from child */
+ dup2(fds[0], 0);
+ }
+ else if (pid == 0) {
+ /* send the help message to the parent PAGER */
+ dup2(fds[1], 1);
+ dup2(fds[1], 2);
+ }
+ close(fds[0]);
+ close(fds[1]);
+ if (pid > 0) {
+ setup_pager_env();
+ rb_f_exec(1, &pager);
+ kill(SIGTERM, pid);
+ rb_waitpid(pid, 0, 0);
+ }
+ }
+#else
+ setup_pager_env();
+ VALUE port = rb_io_popen(pager, rb_str_new_lit("w"), Qnil, Qnil);
+ if (!NIL_P(port)) {
+ int oldout = dup(1);
+ int olderr = dup(2);
+ int fd = RFILE(port)->fptr->fd;
+ tty = tty_enabled();
+ dup2(fd, 1);
+ dup2(fd, 2);
+ usage(progname, 1, tty, columns);
+ fflush(stdout);
+ dup2(oldout, 1);
+ dup2(olderr, 2);
+ rb_io_close(port);
+ return Qtrue;
+ }
+#endif
+ }
+ }
+ usage(progname, (opt->dump & DUMP_BIT(help)), tty, columns);
return Qtrue;
}
argc -= i;
argv += i;
- if ((opt->features & FEATURE_BIT(rubyopt)) &&
- opt->safe_level == 0 && (s = getenv("RUBYOPT"))) {
+ if ((opt->features.set & FEATURE_BIT(rubyopt)) && (s = getenv("RUBYOPT"))) {
VALUE src_enc_name = opt->src.enc.name;
VALUE ext_enc_name = opt->ext.enc.name;
VALUE int_enc_name = opt->intern.enc.name;
+ ruby_features_t feat = opt->features;
+ ruby_features_t warn = opt->warn;
opt->src.enc.name = opt->ext.enc.name = opt->intern.enc.name = 0;
moreswitches(s, opt, 1);
@@ -1502,12 +1786,25 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
opt->ext.enc.name = ext_enc_name;
if (int_enc_name)
opt->intern.enc.name = int_enc_name;
+ FEATURE_SET_RESTORE(opt->features, feat);
+ FEATURE_SET_RESTORE(opt->warn, warn);
}
if (opt->src.enc.name)
- rb_warning("-K is specified; it is for 1.8 compatibility and may cause odd behavior");
+ /* cannot set deprecated category, as enabling deprecation warnings based on flags
+ * has not happened yet.
+ */
+ rb_warning("-K is specified; it is for 1.8 compatibility and may cause odd behavior");
+#if USE_MJIT
+ if (opt->features.set & FEATURE_BIT(jit)) {
+ opt->mjit.on = TRUE; /* set mjit.on for ruby_show_version() API and check to call mjit_init() */
+ }
+#endif
if (opt->dump & (DUMP_BIT(version) | DUMP_BIT(version_v))) {
+#if USE_MJIT
+ mjit_opts.on = opt->mjit.on; /* used by ruby_show_version(). mjit_init() still can't be called here. */
+#endif
ruby_show_version();
if (opt->dump & DUMP_BIT(version)) return Qtrue;
}
@@ -1557,8 +1854,16 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
translit_char(RSTRING_PTR(opt->script_name), '\\', '/');
#endif
- ruby_gc_set_params(opt->safe_level);
- ruby_init_loadpath_safe(opt->safe_level);
+ ruby_gc_set_params();
+ ruby_init_loadpath();
+
+#if USE_MJIT
+ if (opt->mjit.on)
+ /* Using TMP_RUBY_PREFIX created by ruby_init_loadpath(). */
+ mjit_init(&opt->mjit);
+#endif
+
+ Init_ruby_description();
Init_enc();
lenc = rb_locale_encoding();
rb_enc_associate(rb_progname, lenc);
@@ -1581,7 +1886,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
enc = rb_enc_from_index(opt->ext.enc.index);
}
else {
- enc = lenc;
+ enc = IF_UTF8_PATH(uenc, lenc);
}
rb_enc_set_default_external(rb_enc_from_encoding(enc));
if (opt->intern.enc.index >= 0) {
@@ -1593,8 +1898,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
#endif
}
script_name = opt->script_name;
- rb_enc_associate(opt->script_name,
- IF_UTF8_PATH(uenc = rb_utf8_encoding(), lenc));
+ rb_enc_associate(opt->script_name, IF_UTF8_PATH(uenc, lenc));
#if UTF8_PATH
if (uenc != lenc) {
opt->script_name = str_conv_enc(opt->script_name, uenc, lenc);
@@ -1604,8 +1908,11 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_obj_freeze(opt->script_name);
if (IF_UTF8_PATH(uenc != lenc, 1)) {
long i;
- VALUE load_path = GET_VM()->load_path;
+ VALUE load_path = vm->load_path;
const ID id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
+ int modifiable = FALSE;
+
+ rb_get_expanded_load_path();
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
VALUE path = RARRAY_AREF(load_path, i);
int mark = rb_attr_get(path, id_initial_load_path_mark) == path;
@@ -1614,25 +1921,38 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
if (newpath == path) continue;
path = newpath;
#else
- path = rb_enc_associate(rb_str_dup(path), lenc);
+ if (!(path = copy_str(path, lenc, !mark))) continue;
#endif
if (mark) rb_ivar_set(path, id_initial_load_path_mark, path);
+ if (!modifiable) {
+ rb_ary_modify(load_path);
+ modifiable = TRUE;
+ }
RARRAY_ASET(load_path, i, path);
}
+ if (modifiable) {
+ rb_ary_replace(vm->load_path_snapshot, load_path);
+ }
}
- Init_ext(); /* load statically linked extensions before rubygems */
- if (opt->features & FEATURE_BIT(gems)) {
- rb_define_module("Gem");
- }
- if (opt->features & FEATURE_BIT(did_you_mean)) {
- rb_define_module("DidYouMean");
+ {
+ VALUE loaded_features = vm->loaded_features;
+ bool modified = false;
+ for (long i = loaded_before_enc; i < RARRAY_LEN(loaded_features); ++i) {
+ VALUE path = RARRAY_AREF(loaded_features, i);
+ if (!(path = copy_str(path, IF_UTF8_PATH(uenc, lenc), true))) continue;
+ modified = true;
+ RARRAY_ASET(loaded_features, i, path);
+ }
+ if (modified) {
+ rb_ary_replace(vm->loaded_features_snapshot, loaded_features);
+ }
}
- ruby_init_prelude();
- if ((opt->features ^ DEFAULT_FEATURES) & COMPILATION_FEATURES) {
+
+ if (opt->features.mask & COMPILATION_FEATURES) {
VALUE option = rb_hash_new();
#define SET_COMPILE_OPTION(h, o, name) \
rb_hash_aset((h), ID2SYM(rb_intern_const(#name)), \
- ((o)->features & FEATURE_BIT(name) ? Qtrue : Qfalse));
+ (FEATURE_SET_P(o->features, FEATURE_BIT(name)) ? Qtrue : Qfalse));
SET_COMPILE_OPTION(option, opt, frozen_string_literal);
SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
rb_funcallv(rb_cISeq, rb_intern_const("compile_option="), 1, &option);
@@ -1641,10 +1961,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
ruby_set_argv(argc, argv);
process_sflag(&opt->sflag);
- GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")),
- toplevel_binding);
- /* need to acquire env from toplevel_binding each time, since it
- * may update after eval() */
+ rb_parser_set_context(parser, 0, TRUE);
if (opt->e_script) {
VALUE progname = rb_progname;
@@ -1664,22 +1981,16 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
}
#endif
rb_enc_associate(opt->e_script, eenc);
- if (!(opt->dump & ~DUMP_BIT(version_v))) {
- ruby_set_script_name(opt->script_name);
- require_libraries(&opt->req_list);
- }
+ ruby_opt_init(opt);
ruby_set_script_name(progname);
-
- base_block = toplevel_context(toplevel_binding);
- rb_parser_set_context(parser, base_block, TRUE);
- tree = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
+ rb_parser_set_options(parser, opt->do_print, opt->do_loop,
+ opt->do_line, opt->do_split);
+ ast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
}
else {
VALUE f;
- base_block = toplevel_context(toplevel_binding);
- rb_parser_set_context(parser, base_block, TRUE);
f = open_load_file(script_name, &opt->xflag);
- tree = load_file(parser, opt->script_name, f, 1, opt);
+ ast = load_file(parser, opt->script_name, f, 1, opt);
}
ruby_set_script_name(opt->script_name);
if (dump & DUMP_BIT(yydebug)) {
@@ -1691,7 +2002,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
enc = rb_enc_from_index(opt->ext.enc.index);
}
else {
- enc = lenc;
+ enc = IF_UTF8_PATH(uenc, lenc);
}
rb_enc_set_default_external(rb_enc_from_encoding(enc));
if (opt->intern.enc.index >= 0) {
@@ -1704,7 +2015,10 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_enc_set_default_internal(Qnil);
rb_stdio_set_default_encoding();
- if (!tree) return Qfalse;
+ if (!ast->body.root) {
+ rb_ast_dispose(ast);
+ return Qfalse;
+ }
process_sflag(&opt->sflag);
opt->xflag = 0;
@@ -1715,11 +2029,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
if (!dump) return Qtrue;
}
- if (opt->do_print) {
- tree = rb_parser_append_print(parser, tree);
- }
if (opt->do_loop) {
- tree = rb_parser_while_loop(parser, tree, opt->do_line, opt->do_split);
rb_define_global_function("sub", rb_f_sub, -1);
rb_define_global_function("gsub", rb_f_gsub, -1);
rb_define_global_function("chop", rb_f_chop, 0);
@@ -1727,19 +2037,35 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
}
if (dump & (DUMP_BIT(parsetree)|DUMP_BIT(parsetree_with_comment))) {
- rb_io_write(rb_stdout, rb_parser_dump_tree(tree, dump & DUMP_BIT(parsetree_with_comment)));
+ rb_io_write(rb_stdout, rb_parser_dump_tree(ast->body.root, dump & DUMP_BIT(parsetree_with_comment)));
rb_io_flush(rb_stdout);
dump &= ~DUMP_BIT(parsetree)&~DUMP_BIT(parsetree_with_comment);
- if (!dump) return Qtrue;
+ if (!dump) {
+ rb_ast_dispose(ast);
+ return Qtrue;
+ }
}
{
VALUE path = Qnil;
if (!opt->e_script && strcmp(opt->script, "-")) {
path = rb_realpath_internal(Qnil, script_name, 1);
+#if UTF8_PATH
+ if (uenc != lenc) {
+ path = str_conv_enc(path, uenc, lenc);
+ }
+#endif
+ if (!ENCODING_GET(path)) { /* ASCII-8BIT */
+ rb_enc_copy(path, opt->script_name);
+ }
}
- base_block = toplevel_context(toplevel_binding);
- iseq = rb_iseq_new_main(tree, opt->script_name, path, vm_block_iseq(base_block));
+
+ rb_binding_t *toplevel_binding;
+ GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")),
+ toplevel_binding);
+ const struct rb_block *base_block = toplevel_context(toplevel_binding);
+ iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, vm_block_iseq(base_block));
+ rb_ast_dispose(ast);
}
if (dump & DUMP_BIT(insns)) {
@@ -1754,8 +2080,26 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_define_readonly_boolean("$-l", opt->do_line);
rb_define_readonly_boolean("$-a", opt->do_split);
- rb_set_safe_level(opt->safe_level);
+ rb_gvar_ractor_local("$-p");
+ rb_gvar_ractor_local("$-l");
+ rb_gvar_ractor_local("$-a");
+
+ if ((rb_e_script = opt->e_script) != 0) {
+ rb_gc_register_mark_object(opt->e_script);
+ }
+
+ {
+ rb_execution_context_t *ec = GET_EC();
+ if (opt->e_script) {
+ /* -e */
+ rb_exec_event_hook_script_compiled(ec, iseq, opt->e_script);
+ }
+ else {
+ /* file */
+ rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
+ }
+ }
return (VALUE)iseq;
}
@@ -1789,7 +2133,7 @@ load_file_internal(VALUE argp_v)
ruby_cmdline_options_t *opt = argp->opt;
VALUE f = argp->f;
int line_start = 1;
- NODE *tree = 0;
+ rb_ast_t *ast = 0;
rb_encoding *enc;
ID set_encoding;
@@ -1825,11 +2169,7 @@ load_file_internal(VALUE argp_v)
c = rb_io_getbyte(f);
if (c == INT2FIX('#')) {
c = rb_io_getbyte(f);
- if (c == INT2FIX('!')) {
- line = rb_io_gets(f);
- if (NIL_P(line))
- return 0;
-
+ if (c == INT2FIX('!') && !NIL_P(line = rb_io_gets(f))) {
RSTRING_GETMEM(line, str, len);
warn_cr_in_shebang(str, len);
if ((p = strstr(str, ruby_engine)) == 0) {
@@ -1868,13 +2208,10 @@ load_file_internal(VALUE argp_v)
else if (!NIL_P(c)) {
rb_io_ungetbyte(f, c);
}
- else {
+ if (NIL_P(c)) {
argp->f = f = Qnil;
}
- if (!(opt->dump & ~DUMP_BIT(version_v))) {
- ruby_set_script_name(opt->script_name);
- require_libraries(&opt->req_list); /* Why here? unnatural */
- }
+ ruby_opt_init(opt);
}
if (opt->src.enc.index >= 0) {
enc = rb_enc_from_index(opt->src.enc.index);
@@ -1885,13 +2222,15 @@ load_file_internal(VALUE argp_v)
else {
enc = rb_utf8_encoding();
}
+ rb_parser_set_options(parser, opt->do_print, opt->do_loop,
+ opt->do_line, opt->do_split);
if (NIL_P(f)) {
f = rb_str_new(0, 0);
rb_enc_associate(f, enc);
return (VALUE)rb_parser_compile_string_path(parser, orig_fname, f, line_start);
}
rb_funcall(f, set_encoding, 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
- tree = rb_parser_compile_file_path(parser, orig_fname, f, line_start);
+ ast = rb_parser_compile_file_path(parser, orig_fname, f, line_start);
rb_funcall(f, set_encoding, 1, rb_parser_encoding(parser));
if (script && rb_parser_end_seen_p(parser)) {
/*
@@ -1909,7 +2248,7 @@ load_file_internal(VALUE argp_v)
rb_define_global_const("DATA", f);
argp->f = Qnil;
}
- return (VALUE)tree;
+ return (VALUE)ast;
}
static VALUE
@@ -1951,7 +2290,7 @@ open_load_file(VALUE fname_v, int *xflag)
#endif
if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
- int e = errno;
+ e = errno;
if (!rb_gc_for_fd(e)) {
rb_load_fail(fname_v, strerror(e));
}
@@ -1962,9 +2301,13 @@ open_load_file(VALUE fname_v, int *xflag)
rb_update_max_fd(fd);
#if defined HAVE_FCNTL && MODE_TO_LOAD != O_RDONLY
+# ifdef ENOTSUP
+# define IS_SUPPORTED_OP(e) ((e) != ENOTSUP)
+# else
+# define IS_SUPPORTED_OP(e) ((void)(e), 1)
+# endif
/* disabling O_NONBLOCK */
- if (fcntl(fd, F_SETFL, 0) < 0) {
- e = errno;
+ if (fcntl(fd, F_SETFL, 0) < 0 && IS_SUPPORTED_OP(e = errno)) {
(void)close(fd);
rb_load_fail(fname_v, strerror(e));
}
@@ -2001,7 +2344,7 @@ restore_load_file(VALUE arg)
return Qnil;
}
-static NODE *
+static rb_ast_t *
load_file(VALUE parser, VALUE fname, VALUE f, int script, ruby_cmdline_options_t *opt)
{
struct load_file_arg arg;
@@ -2010,8 +2353,8 @@ load_file(VALUE parser, VALUE fname, VALUE f, int script, ruby_cmdline_options_t
arg.script = script;
arg.opt = opt;
arg.f = f;
- return (NODE *)rb_ensure(load_file_internal, (VALUE)&arg,
- restore_load_file, (VALUE)&arg);
+ return (rb_ast_t *)rb_ensure(load_file_internal, (VALUE)&arg,
+ restore_load_file, (VALUE)&arg);
}
void *
@@ -2052,6 +2395,8 @@ proc_argv0(VALUE process)
return rb_orig_progname;
}
+static VALUE ruby_setproctitle(VALUE title);
+
/*
* call-seq:
* Process.setproctitle(string) -> string
@@ -2072,20 +2417,24 @@ proc_argv0(VALUE process)
static VALUE
proc_setproctitle(VALUE process, VALUE title)
{
- StringValue(title);
-
- setproctitle("%.*s", RSTRING_LENINT(title), RSTRING_PTR(title));
+ return ruby_setproctitle(title);
+}
+static VALUE
+ruby_setproctitle(VALUE title)
+{
+ const char *ptr = StringValueCStr(title);
+ setproctitle("%.*s", RSTRING_LENINT(title), ptr);
return title;
}
static void
-set_arg0(VALUE val, ID id)
+set_arg0(VALUE val, ID id, VALUE *_)
{
if (origarg.argv == 0)
rb_raise(rb_eRuntimeError, "$0 not initialized");
- rb_progname = rb_str_new_frozen(proc_setproctitle(rb_mProcess, val));
+ rb_progname = rb_str_new_frozen(ruby_setproctitle(val));
}
static inline VALUE
@@ -2093,7 +2442,8 @@ external_str_new_cstr(const char *p)
{
#if UTF8_PATH
VALUE str = rb_utf8_str_new_cstr(p);
- return str_conv_enc(str, NULL, rb_default_external_encoding());
+ str = str_conv_enc(str, NULL, rb_default_external_encoding());
+ return str;
#else
return rb_external_str_new_cstr(p);
#endif
@@ -2134,9 +2484,6 @@ init_ids(ruby_cmdline_options_t *opt)
if (uid != euid) opt->setids |= 1;
if (egid != gid) opt->setids |= 2;
- if (uid && opt->setids) {
- if (opt->safe_level < 1) opt->safe_level = 1;
- }
}
#undef forbid_setid
@@ -2147,22 +2494,26 @@ forbid_setid(const char *s, const ruby_cmdline_options_t *opt)
rb_raise(rb_eSecurityError, "no %s allowed while running setuid", s);
if (opt->setids & 2)
rb_raise(rb_eSecurityError, "no %s allowed while running setgid", s);
- if (opt->safe_level > 0)
- rb_raise(rb_eSecurityError, "no %s allowed in tainted mode", s);
+}
+
+static VALUE
+verbose_getter(ID id, VALUE *ptr)
+{
+ return *rb_ruby_verbose_ptr();
}
static void
-verbose_setter(VALUE val, ID id, void *data)
+verbose_setter(VALUE val, ID id, VALUE *variable)
{
- VALUE *variable = data;
- *variable = RTEST(val) ? Qtrue : val;
+ *rb_ruby_verbose_ptr() = RTEST(val) ? Qtrue : val;
}
static VALUE
-opt_W_getter(ID id, void *data)
+opt_W_getter(ID id, VALUE *dmy)
{
- VALUE *variable = data;
- switch (*variable) {
+ VALUE v = *rb_ruby_verbose_ptr();
+
+ switch (v) {
case Qnil:
return INT2FIX(0);
case Qfalse:
@@ -2174,16 +2525,35 @@ opt_W_getter(ID id, void *data)
}
}
+static VALUE
+debug_getter(ID id, VALUE *dmy)
+{
+ return *rb_ruby_debug_ptr();
+}
+
+static void
+debug_setter(VALUE val, ID id, VALUE *dmy)
+{
+ *rb_ruby_debug_ptr() = val;
+}
+
/*! Defines built-in variables */
void
ruby_prog_init(void)
{
- rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-W", &ruby_verbose, opt_W_getter, rb_gvar_readonly_setter);
- rb_define_variable("$DEBUG", &ruby_debug);
- rb_define_variable("$-d", &ruby_debug);
+ rb_define_virtual_variable("$VERBOSE", verbose_getter, verbose_setter);
+ rb_define_virtual_variable("$-v", verbose_getter, verbose_setter);
+ rb_define_virtual_variable("$-w", verbose_getter, verbose_setter);
+ rb_define_virtual_variable("$-W", opt_W_getter, rb_gvar_readonly_setter);
+ rb_define_virtual_variable("$DEBUG", debug_getter, debug_setter);
+ rb_define_virtual_variable("$-d", debug_getter, debug_setter);
+
+ rb_gvar_ractor_local("$VERBOSE");
+ rb_gvar_ractor_local("$-v");
+ rb_gvar_ractor_local("$-w");
+ rb_gvar_ractor_local("$-W");
+ rb_gvar_ractor_local("$DEBUG");
+ rb_gvar_ractor_local("$-d");
rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0);
diff --git a/ruby_assert.h b/ruby_assert.h
index 3383e4fc6c..ddd348c7d3 100644
--- a/ruby_assert.h
+++ b/ruby_assert.h
@@ -1,54 +1,15 @@
-#ifndef RUBY_ASSERT_H
-#define RUBY_ASSERT_H
-
-#include "ruby/ruby.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-NORETURN(void rb_assert_failure(const char *, int, const char *, const char *));
-#ifdef RUBY_FUNCTION_NAME_STRING
-# define RUBY_ASSERT_FAIL(expr) \
- rb_assert_failure(__FILE__, __LINE__, RUBY_FUNCTION_NAME_STRING, expr)
-#else
-# define RUBY_ASSERT_FAIL(expr) \
- rb_assert_failure(__FILE__, __LINE__, NULL, expr)
-#endif
-#define RUBY_ASSERT_MESG(expr, mesg) \
- ((expr) ? (void)0 : RUBY_ASSERT_FAIL(mesg))
-#ifdef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
-# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
- __builtin_choose_expr( \
- __builtin_constant_p(cond), \
- __builtin_choose_expr(cond, RUBY_ASSERT_MESG(expr, mesg), (void)0), \
- RUBY_ASSERT_MESG(!(cond) || (expr), mesg))
-#else
-# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
- RUBY_ASSERT_MESG(!(cond) || (expr), mesg)
-#endif
-#define RUBY_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(!RUBY_NDEBUG+0, expr, #expr)
-#define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN(cond, expr, #expr)
-
+#ifndef RUBY_TOPLEVEL_ASSERT_H /*-*-C-*-vi:se ft=c:*/
+#define RUBY_TOPLEVEL_ASSERT_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+#include "ruby/assert.h"
#undef assert
-#define assert RUBY_ASSERT
-
-#ifndef RUBY_NDEBUG
-# ifdef NDEBUG
-# define RUBY_NDEBUG 1
-# else
-# define RUBY_NDEBUG 0
-# endif
-#endif
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
+#define assert RUBY_ASSERT_NDEBUG
-#endif
+#endif /* RUBY_TOPLEVEL_ASSERT_H */
diff --git a/ruby_atomic.h b/ruby_atomic.h
index 4bc9f37e0d..57d341082d 100644
--- a/ruby_atomic.h
+++ b/ruby_atomic.h
@@ -1,233 +1,23 @@
-#ifndef RUBY_ATOMIC_H
-#define RUBY_ATOMIC_H
-
-#if 0
-#elif defined HAVE_GCC_ATOMIC_BUILTINS
-typedef unsigned int rb_atomic_t;
-# define ATOMIC_SET(var, val) (void)__atomic_exchange_n(&(var), (val), __ATOMIC_SEQ_CST)
-# define ATOMIC_INC(var) __atomic_fetch_add(&(var), 1, __ATOMIC_SEQ_CST)
-# define ATOMIC_DEC(var) __atomic_fetch_sub(&(var), 1, __ATOMIC_SEQ_CST)
-# define ATOMIC_OR(var, val) __atomic_fetch_or(&(var), (val), __ATOMIC_SEQ_CST)
-# define ATOMIC_EXCHANGE(var, val) __atomic_exchange_n(&(var), (val), __ATOMIC_SEQ_CST)
-# define ATOMIC_CAS(var, oldval, newval) \
-({ __typeof__(var) oldvaldup = (oldval); /* oldval should not be modified */ \
- __atomic_compare_exchange_n(&(var), &oldvaldup, (newval), 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
- oldvaldup; })
-
-# define ATOMIC_SIZE_ADD(var, val) __atomic_fetch_add(&(var), (val), __ATOMIC_SEQ_CST)
-# define ATOMIC_SIZE_SUB(var, val) __atomic_fetch_sub(&(var), (val), __ATOMIC_SEQ_CST)
-
-# define RUBY_ATOMIC_GENERIC_MACRO 1
-
-#elif defined HAVE_GCC_SYNC_BUILTINS
-/* @shyouhei hack to support atomic operations in case of gcc. Gcc
- * has its own pseudo-insns to support them. See info, or
- * http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html */
-
-typedef unsigned int rb_atomic_t; /* Anything OK */
-# define ATOMIC_SET(var, val) (void)__sync_lock_test_and_set(&(var), (val))
-# define ATOMIC_INC(var) __sync_fetch_and_add(&(var), 1)
-# define ATOMIC_DEC(var) __sync_fetch_and_sub(&(var), 1)
-# define ATOMIC_OR(var, val) __sync_fetch_and_or(&(var), (val))
-# define ATOMIC_EXCHANGE(var, val) __sync_lock_test_and_set(&(var), (val))
-# define ATOMIC_CAS(var, oldval, newval) __sync_val_compare_and_swap(&(var), (oldval), (newval))
-
-# define ATOMIC_SIZE_ADD(var, val) __sync_fetch_and_add(&(var), (val))
-# define ATOMIC_SIZE_SUB(var, val) __sync_fetch_and_sub(&(var), (val))
-
-# define RUBY_ATOMIC_GENERIC_MACRO 1
-
-#elif defined _WIN32
-#if defined _MSC_VER && _MSC_VER > 1200
-#pragma intrinsic(_InterlockedOr)
-#endif
-typedef LONG rb_atomic_t;
-
-# define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
-# define ATOMIC_INC(var) InterlockedIncrement(&(var))
-# define ATOMIC_DEC(var) InterlockedDecrement(&(var))
-#if defined __GNUC__
-# define ATOMIC_OR(var, val) __asm__("lock\n\t" "orl\t%1, %0" : "=m"(var) : "Ir"(val))
-#elif defined _MSC_VER && _MSC_VER <= 1200
-# define ATOMIC_OR(var, val) rb_w32_atomic_or(&(var), (val))
-static inline void
-rb_w32_atomic_or(volatile rb_atomic_t *var, rb_atomic_t val)
-{
-#ifdef _M_IX86
- __asm mov eax, var;
- __asm mov ecx, val;
- __asm lock or [eax], ecx;
-#else
-#error unsupported architecture
-#endif
-}
-#else
-# define ATOMIC_OR(var, val) _InterlockedOr(&(var), (val))
-#endif
-# define ATOMIC_EXCHANGE(var, val) InterlockedExchange(&(var), (val))
-# define ATOMIC_CAS(var, oldval, newval) InterlockedCompareExchange(&(var), (newval), (oldval))
-# if defined _MSC_VER && _MSC_VER <= 1200
-static inline rb_atomic_t
-rb_w32_atomic_cas(volatile rb_atomic_t *var, rb_atomic_t oldval, rb_atomic_t newval)
-{
- return (rb_atomic_t)InterlockedCompareExchange((PVOID *)var, (PVOID)newval, (PVOID)oldval);
-}
-# undef ATOMIC_CAS
-# define ATOMIC_CAS(var, oldval, newval) rb_w32_atomic_cas(&(var), (oldval), (newval))
-# endif
-# ifdef _M_AMD64
-# define ATOMIC_SIZE_ADD(var, val) InterlockedExchangeAdd64((LONG_LONG *)&(var), (val))
-# define ATOMIC_SIZE_SUB(var, val) InterlockedExchangeAdd64((LONG_LONG *)&(var), -(LONG)(val))
-# define ATOMIC_SIZE_INC(var) InterlockedIncrement64(&(var))
-# define ATOMIC_SIZE_DEC(var) InterlockedDecrement64(&(var))
-# define ATOMIC_SIZE_EXCHANGE(var, val) InterlockedExchange64(&(var), (val))
-# define ATOMIC_SIZE_CAS(var, oldval, newval) InterlockedCompareExchange64(&(var), (newval), (oldval))
-# else
-# define ATOMIC_SIZE_ADD(var, val) InterlockedExchangeAdd((LONG *)&(var), (val))
-# define ATOMIC_SIZE_SUB(var, val) InterlockedExchangeAdd((LONG *)&(var), -(LONG)(val))
-# define ATOMIC_SIZE_INC(var) InterlockedIncrement((LONG *)&(var))
-# define ATOMIC_SIZE_DEC(var) InterlockedDecrement((LONG *)&(var))
-# define ATOMIC_SIZE_EXCHANGE(var, val) InterlockedExchange((LONG *)&(var), (val))
-# endif
-
-#elif defined(__sun) && defined(HAVE_ATOMIC_H)
-#include <atomic.h>
-typedef unsigned int rb_atomic_t;
-
-# define ATOMIC_SET(var, val) (void)atomic_swap_uint(&(var), (val))
-# define ATOMIC_INC(var) atomic_inc_uint(&(var))
-# define ATOMIC_DEC(var) atomic_dec_uint(&(var))
-# define ATOMIC_OR(var, val) atomic_or_uint(&(var), (val))
-# define ATOMIC_EXCHANGE(var, val) atomic_swap_uint(&(var), (val))
-# define ATOMIC_CAS(var, oldval, newval) atomic_cas_uint(&(var), (oldval), (newval))
-
-# if SIZEOF_SIZE_T == SIZEOF_LONG
-# define ATOMIC_SIZE_ADD(var, val) atomic_add_long(&(var), (val))
-# define ATOMIC_SIZE_SUB(var, val) atomic_add_long(&(var), -(val))
-# define ATOMIC_SIZE_INC(var) atomic_inc_ulong(&(var))
-# define ATOMIC_SIZE_DEC(var) atomic_dec_ulong(&(var))
-# define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_ulong(&(var), (val))
-# define ATOMIC_SIZE_CAS(var, oldval, val) atomic_cas_ulong(&(var), (oldval), (val))
-# else
-# define ATOMIC_SIZE_ADD(var, val) atomic_add_int(&(var), (val))
-# define ATOMIC_SIZE_SUB(var, val) atomic_add_int(&(var), -(val))
-# define ATOMIC_SIZE_INC(var) atomic_inc_uint(&(var))
-# define ATOMIC_SIZE_DEC(var) atomic_dec_uint(&(var))
-# define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_uint(&(var), (val))
-# endif
-
-#else
-typedef int rb_atomic_t;
-#define NEED_RUBY_ATOMIC_OPS
-extern rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val);
-extern rb_atomic_t ruby_atomic_compare_and_swap(rb_atomic_t *ptr,
- rb_atomic_t cmp,
- rb_atomic_t newval);
-
-# define ATOMIC_SET(var, val) (void)((var) = (val))
-# define ATOMIC_INC(var) ((var)++)
-# define ATOMIC_DEC(var) ((var)--)
-# define ATOMIC_OR(var, val) ((var) |= (val))
-# define ATOMIC_EXCHANGE(var, val) ruby_atomic_exchange(&(var), (val))
-# define ATOMIC_CAS(var, oldval, newval) ruby_atomic_compare_and_swap(&(var), (oldval), (newval))
-
-# define ATOMIC_SIZE_ADD(var, val) (void)((var) += (val))
-# define ATOMIC_SIZE_SUB(var, val) (void)((var) -= (val))
-# define ATOMIC_SIZE_EXCHANGE(var, val) ruby_atomic_size_exchange(&(var), (val))
-static inline size_t
-ruby_atomic_size_exchange(size_t *ptr, size_t val)
-{
- size_t old = *ptr;
- *ptr = val;
- return old;
-}
-#endif
-
-#ifndef ATOMIC_SIZE_INC
-# define ATOMIC_SIZE_INC(var) ATOMIC_INC(var)
-#endif
-#ifndef ATOMIC_SIZE_DEC
-# define ATOMIC_SIZE_DEC(var) ATOMIC_DEC(var)
-#endif
-#ifndef ATOMIC_SIZE_EXCHANGE
-# define ATOMIC_SIZE_EXCHANGE(var, val) ATOMIC_EXCHANGE(var, val)
-#endif
-#ifndef ATOMIC_SIZE_CAS
-# define ATOMIC_SIZE_CAS(var, oldval, val) ATOMIC_CAS(var, oldval, val)
-#endif
-
-#if RUBY_ATOMIC_GENERIC_MACRO
-# ifndef ATOMIC_PTR_EXCHANGE
-# define ATOMIC_PTR_EXCHANGE(var, val) ATOMIC_EXCHANGE(var, val)
-# endif
-# ifndef ATOMIC_PTR_CAS
-# define ATOMIC_PTR_CAS(var, oldval, newval) ATOMIC_CAS(var, oldval, newval)
-# endif
-
-# ifndef ATOMIC_VALUE_EXCHANGE
-# define ATOMIC_VALUE_EXCHANGE(var, val) ATOMIC_EXCHANGE(var, val)
-# endif
-# ifndef ATOMIC_VALUE_CAS
-# define ATOMIC_VALUE_CAS(var, oldval, val) ATOMIC_CAS(var, oldval, val)
-# endif
-#endif
-
-#ifndef ATOMIC_PTR_EXCHANGE
-# if SIZEOF_VOIDP == SIZEOF_SIZE_T
-# define ATOMIC_PTR_EXCHANGE(var, val) (void *)ATOMIC_SIZE_EXCHANGE(*(size_t *)&(var), (size_t)(val))
-# else
-# define ATOMIC_PTR_EXCHANGE(var, val) ruby_atomic_ptr_exchange((const void **)&(var), (val))
-static inline void *
-ruby_atomic_ptr_exchange(const void **ptr, const void *val)
-{
- const void *const old = *ptr;
- *ptr = val;
- return (void *)old;
-}
-# endif
-#endif
-#ifndef ATOMIC_PTR_CAS
-# if SIZEOF_VOIDP == SIZEOF_SIZE_T
-# define ATOMIC_PTR_CAS(var, oldval, val) (void *)ATOMIC_SIZE_CAS(*(size_t *)&(var), (size_t)(oldval), (size_t)(val))
-# else
-# define ATOMIC_PTR_CAS(var, oldval, val) ruby_atomic_ptr_cas(&(var), (oldval), (val))
-static inline void *
-ruby_atomic_ptr_cas(const void **ptr, const void *oldval, const void *val)
-{
- const void *const old = *ptr;
- if (old == oldval) *ptr = val;
- return (void *)old;
-}
-# endif
-#endif
-
-#ifndef ATOMIC_VALUE_EXCHANGE
-# if SIZEOF_VALUE == SIZEOF_SIZE_T
-# define ATOMIC_VALUE_EXCHANGE(var, val) ATOMIC_SIZE_EXCHANGE(*(size_t *)&(var), (size_t)(val))
-# else
-# define ATOMIC_VALUE_EXCHANGE(var, val) ruby_atomic_value_exchange(&(var), (val))
-static inline VALUE
-ruby_atomic_value_exchange(VALUE *ptr, VALUE val)
-{
- const VALUE old = *ptr;
- *ptr = val;
- return old;
-}
-# endif
-#endif
-#ifndef ATOMIC_VALUE_CAS
-# if SIZEOF_VALUE == SIZEOF_SIZE_T
-# define ATOMIC_VALUE_CAS(var, oldval, val) ATOMIC_SIZE_CAS(*(size_t *)&(var), (size_t)(oldval), (size_t)(val))
-# else
-# define ATOMIC_VALUE_CAS(var, oldval, val) ruby_atomic_value_cas(&(var), (oldval), (val))
-static inline VALUE
-ruby_atomic_value_cas(VALUE *ptr, VALUE oldval, VALUE val)
-{
- const VALUE old = *ptr;
- if (old == oldval) *ptr = val;
- return old;
-}
-# endif
-#endif
-
-#endif /* RUBY_ATOMIC_H */
+#include "ruby/atomic.h"
+
+/* shim macros only */
+#define ATOMIC_ADD(var, val) RUBY_ATOMIC_ADD(var, val)
+#define ATOMIC_CAS(var, oldval, newval) RUBY_ATOMIC_CAS(var, oldval, newval)
+#define ATOMIC_DEC(var) RUBY_ATOMIC_DEC(var)
+#define ATOMIC_EXCHANGE(var, val) RUBY_ATOMIC_EXCHANGE(var, val)
+#define ATOMIC_FETCH_ADD(var, val) RUBY_ATOMIC_FETCH_ADD(var, val)
+#define ATOMIC_FETCH_SUB(var, val) RUBY_ATOMIC_FETCH_SUB(var, val)
+#define ATOMIC_INC(var) RUBY_ATOMIC_INC(var)
+#define ATOMIC_OR(var, val) RUBY_ATOMIC_OR(var, val)
+#define ATOMIC_PTR_CAS(var, oldval, newval) RUBY_ATOMIC_PTR_CAS(var, oldval, newval)
+#define ATOMIC_PTR_EXCHANGE(var, val) RUBY_ATOMIC_PTR_EXCHANGE(var, val)
+#define ATOMIC_SET(var, val) RUBY_ATOMIC_SET(var, val)
+#define ATOMIC_SIZE_ADD(var, val) RUBY_ATOMIC_SIZE_ADD(var, val)
+#define ATOMIC_SIZE_CAS(var, oldval, newval) RUBY_ATOMIC_SIZE_CAS(var, oldval, newval)
+#define ATOMIC_SIZE_DEC(var) RUBY_ATOMIC_SIZE_DEC(var)
+#define ATOMIC_SIZE_EXCHANGE(var, val) RUBY_ATOMIC_SIZE_EXCHANGE(var, val)
+#define ATOMIC_SIZE_INC(var) RUBY_ATOMIC_SIZE_INC(var)
+#define ATOMIC_SIZE_SUB(var, val) RUBY_ATOMIC_SIZE_SUB(var, val)
+#define ATOMIC_SUB(var, val) RUBY_ATOMIC_SUB(var, val)
+#define ATOMIC_VALUE_CAS(var, oldval, val) RUBY_ATOMIC_VALUE_CAS(var, oldval, val)
+#define ATOMIC_VALUE_EXCHANGE(var, val) RUBY_ATOMIC_VALUE_EXCHANGE(var, val)
diff --git a/safe.c b/safe.c
deleted file mode 100644
index d938082d64..0000000000
--- a/safe.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/**********************************************************************
-
- safe.c -
-
- $Author$
- created at: Tue Sep 23 09:44:32 JST 2008
-
- Copyright (C) 2008 Yukihiro Matsumoto
-
-**********************************************************************/
-
-/* safe-level:
- 0 - strings from streams/environment/ARGV are tainted (default)
- 1 - no dangerous operation by tainted value
-*/
-
-#define SAFE_LEVEL_MAX RUBY_SAFE_LEVEL_MAX
-
-#include "ruby/ruby.h"
-#include "vm_core.h"
-
-/* $SAFE accessor */
-
-#undef rb_secure
-#undef rb_set_safe_level
-#undef ruby_safe_level_2_warning
-
-int
-ruby_safe_level_2_warning(void)
-{
- return 2;
-}
-
-int
-rb_safe_level(void)
-{
- return GET_THREAD()->ec.safe_level;
-}
-
-void
-rb_set_safe_level_force(int safe)
-{
- GET_THREAD()->ec.safe_level = safe;
-}
-
-void
-rb_set_safe_level(int level)
-{
- rb_thread_t *th = GET_THREAD();
-
- if (level > th->ec.safe_level) {
- if (level > SAFE_LEVEL_MAX) {
- rb_raise(rb_eArgError, "$SAFE=2 to 4 are obsolete");
- }
- th->ec.safe_level = level;
- }
-}
-
-static VALUE
-safe_getter(void)
-{
- return INT2NUM(rb_safe_level());
-}
-
-static void
-safe_setter(VALUE val)
-{
- int level = NUM2INT(val);
- rb_thread_t *th = GET_THREAD();
-
- if (level < th->ec.safe_level) {
- rb_raise(rb_eSecurityError,
- "tried to downgrade safe level from %d to %d",
- th->ec.safe_level, level);
- }
- if (level > SAFE_LEVEL_MAX) {
- rb_raise(rb_eArgError, "$SAFE=2 to 4 are obsolete");
- }
- th->ec.safe_level = level;
-}
-
-void
-rb_secure(int level)
-{
- if (level <= rb_safe_level()) {
- ID caller_name = rb_frame_callee();
- if (caller_name) {
- rb_raise(rb_eSecurityError, "Insecure operation `%"PRIsVALUE"' at level %d",
- rb_id2str(caller_name), rb_safe_level());
- }
- else {
- rb_raise(rb_eSecurityError, "Insecure operation at level %d",
- rb_safe_level());
- }
- }
-}
-
-void
-rb_secure_update(VALUE obj)
-{
-}
-
-void
-rb_insecure_operation(void)
-{
- ID caller_name = rb_frame_callee();
- if (caller_name) {
- rb_raise(rb_eSecurityError, "Insecure operation - %"PRIsVALUE,
- rb_id2str(caller_name));
- }
- else {
- rb_raise(rb_eSecurityError, "Insecure operation: -r");
- }
-}
-
-void
-rb_check_safe_obj(VALUE x)
-{
- if (rb_safe_level() > 0 && OBJ_TAINTED(x)) {
- rb_insecure_operation();
- }
-}
-
-void
-Init_safe(void)
-{
- rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
-}
diff --git a/sample/README b/sample/README
index 796aba1dc3..b55234a947 100644
--- a/sample/README
+++ b/sample/README
@@ -16,7 +16,6 @@ fib.pl Fibonacci number (Perl)
fib.py Fibonacci number (Python)
fib.rb Fibonacci number (Ruby)
fib.scm Fibonacci number (Scheme)
-freq.rb count word occurrence
from.rb scan mail spool
fullpath.rb convert ls -lR to fullpath format
less.rb front end for less
@@ -29,7 +28,6 @@ mpart.rb split file int multi part
observ.rb observer design pattern sample
occur.pl count word occurrence (Perl)
occur.rb count word occurrence (Ruby)
-occur2.rb count word occurrence - another style
philos.rb famous dining philosophers
pi.rb calculate PI
rcs.awk random character stereogram (AWK)
diff --git a/sample/biorhythm.rb b/sample/biorhythm.rb
index bd7c39f5aa..f5d189014b 100644
--- a/sample/biorhythm.rb
+++ b/sample/biorhythm.rb
@@ -25,7 +25,7 @@
# Environment: basic, dos, os9
include Math
-require "date.rb"
+require "date"
require "optparse"
require "optparse/date"
@@ -36,11 +36,10 @@ def print_header(y, m, d, p, w)
end
def get_position(z)
- pi = Math::PI
z = Integer(z)
- phys = (50.0 * (1.0 + sin((z / 23.0 - (z / 23)) * 360.0 * pi / 180.0))).to_i
- emot = (50.0 * (1.0 + sin((z / 28.0 - (z / 28)) * 360.0 * pi / 180.0))).to_i
- geist =(50.0 * (1.0 + sin((z / 33.0 - (z / 33)) * 360.0 * pi / 180.0))).to_i
+ phys = (50.0 * (1.0 + sin((z / 23.0 - (z / 23)) * 360.0 * PI / 180.0))).to_i
+ emot = (50.0 * (1.0 + sin((z / 28.0 - (z / 28)) * 360.0 * PI / 180.0))).to_i
+ geist =(50.0 * (1.0 + sin((z / 33.0 - (z / 33)) * 360.0 * PI / 180.0))).to_i
return phys, emot, geist
end
diff --git a/sample/dir.rb b/sample/dir.rb
index 44733c2cf4..0c55078973 100644
--- a/sample/dir.rb
+++ b/sample/dir.rb
@@ -3,7 +3,7 @@
dirp = Dir.open(".")
for f in dirp
case f
- when /\A\./, /~\z/, /\.o/
+ when /\A\./, /~\z/, /\.o\z/
# do not print
else
print f, "\n"
diff --git a/sample/drb/http0serv.rb b/sample/drb/http0serv.rb
index 1a58811fed..2e853312e1 100644
--- a/sample/drb/http0serv.rb
+++ b/sample/drb/http0serv.rb
@@ -1,6 +1,6 @@
require 'webrick'
require 'drb/drb'
-require 'drb/http0'
+require_relative 'http0'
module DRb
module HTTP0
@@ -61,7 +61,7 @@ module DRb
def accept
client = @queue.pop
- ServerSide.new(client, @config)
+ ServerSide.new(uri, client, @config)
end
def setup_webrick(uri)
@@ -79,12 +79,14 @@ module DRb
end
class ServerSide
- def initialize(callback, config)
+ def initialize(uri, callback, config)
+ @uri = uri
@callback = callback
@config = config
@msg = DRbMessage.new(@config)
@req_stream = StrStream.new(@callback.req_body)
end
+ attr_reader :uri
def close
@callback.close if @callback
diff --git a/sample/drb/name.rb b/sample/drb/name.rb
index a8ad28749d..6d88186dab 100644
--- a/sample/drb/name.rb
+++ b/sample/drb/name.rb
@@ -39,11 +39,12 @@ require 'drb/drb'
module DRbNamedObject
DRbNAMEDICT = {}
+ DRBNAMEMUTEX = Thread::Mutex.new
attr_reader(:drb_name)
def drb_name=(name)
@drb_name = name
- Thread.exclusive do
+ DRBNAMEMUTEX.synchronize do
raise(IndexError, name) if DRbNAMEDICT[name]
DRbNAMEDICT[name] = self
end
diff --git a/sample/drb/old_tuplespace.rb b/sample/drb/old_tuplespace.rb
index 8be1542c06..2d5310086e 100644
--- a/sample/drb/old_tuplespace.rb
+++ b/sample/drb/old_tuplespace.rb
@@ -31,7 +31,7 @@ class TupleSpace
def initialize
@que = {}
@waiting = {}
- @que.taint # enable tainted comunication
+ @que.taint # enable tainted communication
@waiting.taint
self.taint
end
diff --git a/sample/fact.rb b/sample/fact.rb
index d8147a40f1..9f6ca72ca7 100644
--- a/sample/fact.rb
+++ b/sample/fact.rb
@@ -4,6 +4,6 @@ def fact(n)
n.downto(1) do |i|
f *= i
end
- return f
+ f
end
-print fact(ARGV[0].to_i), "\n"
+puts fact(ARGV[0].to_i)
diff --git a/sample/fib.py b/sample/fib.py
index 8318021d24..90dc1e09ed 100644
--- a/sample/fib.py
+++ b/sample/fib.py
@@ -6,5 +6,5 @@ def fib(n):
else:
return fib(n-2)+fib(n-1)
-print fib(20)
+print(fib(20))
diff --git a/sample/freq.rb b/sample/freq.rb
deleted file mode 100644
index 1b2194c69a..0000000000
--- a/sample/freq.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# word occurrence listing
-# usage: ruby freq.rb file..
-freq = Hash.new(0)
-while line = gets()
- line.scan(/\w+/) do |word|
- freq[word] += 1
- end
-end
-
-for word in freq.keys.sort!
- print word, " -- ", freq[word], "\n"
-end
diff --git a/sample/iseq_loader.rb b/sample/iseq_loader.rb
index bb2d92ea77..8c271405d6 100644
--- a/sample/iseq_loader.rb
+++ b/sample/iseq_loader.rb
@@ -41,7 +41,7 @@ class RubyVM::InstructionSequence
at_exit{
STDERR.puts "[ISEQ_LOADER] #{Process.pid} time: #{Time.now - LAUNCHED_TIME}, " +
"loaded: #{$ISEQ_LOADER_LOADED}, " +
- "compied: #{$ISEQ_LOADER_COMPILED}, " +
+ "compiled: #{$ISEQ_LOADER_COMPILED}, " +
"ignored: #{$ISEQ_LOADER_IGNORED}"
} if COMPILE_VERBOSE
@@ -141,11 +141,11 @@ class RubyVM::InstructionSequence
end
def read_compiled_iseq fname, iseq_key
- open(iseq_key, 'rb'){|f| f.read}
+ File.open(iseq_key, 'rb'){|f| f.read}
end
def write_compiled_iseq fname, iseq_key, binary
- open(iseq_key, 'wb'){|f| f.write(binary)}
+ File.open(iseq_key, 'wb'){|f| f.write(binary)}
end
end
diff --git a/sample/list.rb b/sample/list.rb
index b4d1d653e4..7458ba0244 100644
--- a/sample/list.rb
+++ b/sample/list.rb
@@ -5,7 +5,6 @@ class MyElem
# @variables are instance variable, no declaration needed
@data = item
@succ = nil
- @head = nil
end
def data
@@ -23,6 +22,10 @@ class MyElem
end
class MyList
+ def initialize
+ @head = nil
+ end
+
def add_to_list(obj)
elt = MyElem.new(obj)
if @head
diff --git a/sample/list3.rb b/sample/list3.rb
index 1d9f04b710..110e405cf9 100644
--- a/sample/list3.rb
+++ b/sample/list3.rb
@@ -7,7 +7,7 @@ class Point
self
end
- def to_s
+ def inspect
sprintf("%d@%d", @x, @y)
end
end
diff --git a/sample/observ.rb b/sample/observ.rb
index a7ea45271d..ef4a9f60f5 100644
--- a/sample/observ.rb
+++ b/sample/observ.rb
@@ -27,5 +27,5 @@ class Clock
end
end
-clock = Clock.new(Tick.new)
+Clock.new(Tick.new)
sleep
diff --git a/sample/occur.rb b/sample/occur.rb
index 42151d85e8..5927ebc889 100644
--- a/sample/occur.rb
+++ b/sample/occur.rb
@@ -2,7 +2,7 @@
# usage: ruby occur.rb file..
freq = Hash.new(0)
while line = gets()
- for word in line.split(/\W+/)
+ line.scan(/\w+/) do |word|
freq[word] += 1
end
end
diff --git a/sample/occur2.rb b/sample/occur2.rb
deleted file mode 100644
index ef8ad2c541..0000000000
--- a/sample/occur2.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# word occurrence listing
-# usage: ruby occur2.rb file..
-freq = {}
-ARGF.each_line do |line|
- for word in line.split(/\W+/)
- freq[word] ||= 0
- freq[word] += 1
- end
-end
-
-for word in freq.keys.sort
- printf("%s -- %d\n", word, freq[word])
-end
diff --git a/sample/openssl/c_rehash.rb b/sample/openssl/c_rehash.rb
index cd6c9d5fd4..8282816b9d 100644
--- a/sample/openssl/c_rehash.rb
+++ b/sample/openssl/c_rehash.rb
@@ -161,7 +161,7 @@ private
end
def fingerprint(der)
- Digest::MD5.hexdigest(der).upcase
+ Digest.hexdigest('MD5', der).upcase
end
end
diff --git a/sample/openssl/echo_svr.rb b/sample/openssl/echo_svr.rb
index 719de6be84..ba15394e6f 100644
--- a/sample/openssl/echo_svr.rb
+++ b/sample/openssl/echo_svr.rb
@@ -37,7 +37,7 @@ else
ef.issuer_certificate = cert
cert.add_extension ef.create_extension("authorityKeyIdentifier",
"keyid:always,issuer:always")
- cert.sign(key, OpenSSL::Digest::SHA1.new)
+ cert.sign(key, OpenSSL::Digest.new('SHA1'))
end
ctx = OpenSSL::SSL::SSLContext.new()
diff --git a/sample/openssl/gen_csr.rb b/sample/openssl/gen_csr.rb
index 4228707fdb..a061260cd7 100644
--- a/sample/openssl/gen_csr.rb
+++ b/sample/openssl/gen_csr.rb
@@ -41,7 +41,7 @@ req = X509::Request.new
req.version = 0
req.subject = name
req.public_key = keypair.public_key
-req.sign(keypair, Digest::MD5.new)
+req.sign(keypair, Digest.new('MD5'))
puts "Writing #{csrout}..."
File.open(csrout, "w") do |f|
diff --git a/sample/ripper/ruby2html.rb b/sample/ripper/ruby2html.rb
index 8f64f5a713..1e6b3bf550 100644
--- a/sample/ripper/ruby2html.rb
+++ b/sample/ripper/ruby2html.rb
@@ -73,7 +73,11 @@ class ERB
end
def ruby2html(f, encoding, css, print_line_number)
- erb = ERB.new(TEMPLATE, nil, '>')
+ if RUBY_VERSION >= '2.6'
+ erb = ERB.new(TEMPLATE, trim_mode: '>')
+ else
+ erb = ERB.new(TEMPLATE, nil, '>')
+ end
erb.filename = __FILE__
erb.lineno = TEMPLATE_LINE
erb.result(binding())
diff --git a/sample/test.rb b/sample/test.rb
index 65dd9abd10..65dd9abd10 100755..100644
--- a/sample/test.rb
+++ b/sample/test.rb
diff --git a/sample/timeout.rb b/sample/timeout.rb
index 8d25d72a76..ad4459aff0 100644
--- a/sample/timeout.rb
+++ b/sample/timeout.rb
@@ -1,31 +1,31 @@
require 'timeout'
def progress(n = 5)
- n.times {|i| print i; STDOUT.flush; sleep 1; i+= 1}
+ n.times {|i| print i; STDOUT.flush; sleep 1}
puts "never reach"
end
-p timeout(5) {
+p Timeout.timeout(5) {
45
}
-p timeout(5, Timeout::Error) {
+p Timeout.timeout(5, Timeout::Error) {
45
}
-p timeout(nil) {
+p Timeout.timeout(nil) {
54
}
-p timeout(0) {
+p Timeout.timeout(0) {
54
}
begin
- timeout(5) {progress}
+ Timeout.timeout(5) {progress}
rescue => e
puts e.message
end
begin
- timeout(3) {
+ Timeout.timeout(3) {
begin
- timeout(5) {progress}
+ Timeout.timeout(5) {progress}
rescue => e
puts "never reach"
end
@@ -36,7 +36,7 @@ end
class MyTimeout < StandardError
end
begin
- timeout(2, MyTimeout) {progress}
+ Timeout.timeout(2, MyTimeout) {progress}
rescue MyTimeout => e
puts e.message
end
diff --git a/sample/trick2013/kinaba/remarks.markdown b/sample/trick2013/kinaba/remarks.markdown
index a454a5f0a1..dcdce7e9ae 100644
--- a/sample/trick2013/kinaba/remarks.markdown
+++ b/sample/trick2013/kinaba/remarks.markdown
@@ -16,11 +16,11 @@ The program contains each ASCII character from 0x20 ' ' to 0x7e '~' exactly once
### Internals
-The algorthim is the obvious loop "32.upto(126){|x| putc x}".
+The algorithm is the obvious loop "32.upto(126){|x| putc x}".
It is not so hard to transform it to use each character *at most once*. The only slight difficulty comes from the constraint that we cannot "declare and then use" variables, because then the code will contain the variable name twice. This restriction is worked around by the $. global variable, the best friend of Ruby golfers.
-The relatively interesting part is to use all the charcters *at least once*. Of course, this is easily accomplished by putting everything into a comment (i.e., #unused...) or to a string literal (%(unused...), note that normal string literals are forbidden since they use quotation marks twice). Hey, but that's not fun at all! I tried to minimize the escapeway.
+The relatively interesting part is to use all the characters *at least once*. Of course, this is easily accomplished by putting everything into a comment (i.e., #unused...) or to a string literal (%(unused...), note that normal string literals are forbidden since they use quotation marks twice). Hey, but that's not fun at all! I tried to minimize the escapeway.
* "@THEqQUICKbBROWNfFXjJMPSvVLAZYDGgkyz". Trash box of unused alphabet. I wish I could have used "gkyz" somewhere else.
diff --git a/sample/trick2013/mame/music-box.mp4 b/sample/trick2013/mame/music-box.mp4
deleted file mode 100644
index 6d1e87c01c..0000000000
--- a/sample/trick2013/mame/music-box.mp4
+++ /dev/null
Binary files differ
diff --git a/sample/trick2013/mame/remarks.markdown b/sample/trick2013/mame/remarks.markdown
index 8c1988c809..488681d88d 100644
--- a/sample/trick2013/mame/remarks.markdown
+++ b/sample/trick2013/mame/remarks.markdown
@@ -27,7 +27,7 @@ In the piano roll, `#` represents a pin that hits a note, and `|` represents a s
The leftmost column corresponds 110Hz (low A).
Every column corresponds a semitone higher than the left one.
-This program uses [the frequency modulation synthesis](http://en.wikipedia.org/wiki/Frequency_modulation_synthesis) to play the sound like a music-box.
+This program uses [the frequency modulation synthesis](https://en.wikipedia.org/wiki/Frequency_modulation_synthesis) to play the sound like a music-box.
You can create a different-sounding tone by changing the parameter.
For example, the following will play the sound like a harpsichord.
@@ -44,4 +44,4 @@ You have to use sox by replacing the following part:
with:
- IO.popen("./pl","wb") \ No newline at end of file
+ IO.popen("./pl","wb")
diff --git a/sample/trick2013/yhara/entry.rb b/sample/trick2013/yhara/entry.rb
index ce125ed3df..3666f271fa 100644
--- a/sample/trick2013/yhara/entry.rb
+++ b/sample/trick2013/yhara/entry.rb
@@ -2,7 +2,7 @@ def _(&b)$><<->(x){x ? (String===x ?x.upcase:
(Class===x ? x : x.class).name[$a?0:($a=5)]):
" "}[ begin b[];rescue Exception;$!;end ] end
-_ { yield }
+_ { 1.tap }
_ { method(:p).unbind }
_ { eval "{ " }
_ { Thread.current.join }
diff --git a/sample/trick2015/kinaba/entry.rb b/sample/trick2015/kinaba/entry.rb
index 18923a6a9f..aa077dc240 100644
--- a/sample/trick2015/kinaba/entry.rb
+++ b/sample/trick2015/kinaba/entry.rb
@@ -62,7 +62,7 @@ while 0x00012345 >= $counter
TrueClass
Dir
Encoding
- Data
+ Proc
Hash
Method
Enumerator
diff --git a/sample/trick2015/ksk_1/remarks.markdown b/sample/trick2015/ksk_1/remarks.markdown
index b822dc55c8..a0b8bbcdcc 100644
--- a/sample/trick2015/ksk_1/remarks.markdown
+++ b/sample/trick2015/ksk_1/remarks.markdown
@@ -110,7 +110,7 @@ is simply `/=/` and removing a padding `",,,,,"`. The program no
longer terminates, though.
-### Limination
+### Limitation
The implementation requires to manipulate long strings even for some
small starting numbers. For example, starting from 1,819, the number
diff --git a/sample/trick2015/ksk_2/remarks.markdown b/sample/trick2015/ksk_2/remarks.markdown
index bb9b705773..187a6804d2 100644
--- a/sample/trick2015/ksk_2/remarks.markdown
+++ b/sample/trick2015/ksk_2/remarks.markdown
@@ -199,6 +199,6 @@ succeed to return 0. The meaning of ``\1nn`` in regular expression
seems to depend on the existence of capturing expressions.
In spite of these Ruby's behaviors, we have a good news! The present
-SAT sover does not suffer from the issues because the program cannot
+SAT solver does not suffer from the issues because the program cannot
return solutions in practical time for inputs with variables more than
-40. \ No newline at end of file
+40.
diff --git a/sample/trick2018/01-kinaba/authors.markdown b/sample/trick2018/01-kinaba/authors.markdown
new file mode 100644
index 0000000000..d0df0b379d
--- /dev/null
+++ b/sample/trick2018/01-kinaba/authors.markdown
@@ -0,0 +1,3 @@
+* kinaba
+ * twitter.com/kinaba
+ * cctld: jp
diff --git a/sample/trick2018/01-kinaba/entry.rb b/sample/trick2018/01-kinaba/entry.rb
new file mode 100644
index 0000000000..eb8284d5ab
--- /dev/null
+++ b/sample/trick2018/01-kinaba/entry.rb
@@ -0,0 +1,8 @@
+alias BEGIN for unless def class
+super true or return defined? next
+break while begin undef do end
+rescue then retry else undef module
+nil ensure case if yield __LINE__
+self and redo elsif not __FILE__
+alias END in end when __ENCODING__
+end until false end
diff --git a/sample/trick2018/01-kinaba/remarks.markdown b/sample/trick2018/01-kinaba/remarks.markdown
new file mode 100644
index 0000000000..a1a05bfd73
--- /dev/null
+++ b/sample/trick2018/01-kinaba/remarks.markdown
@@ -0,0 +1,55 @@
+### Remarks
+
+Just run it with no argument:
+
+ ruby entry.rb
+
+(Anyway it is just a no-op program. The above command only verifies
+that entry.rb is a valid Ruby program.)
+
+I confirmed the following implementations/platforms:
+
+* ruby 2.5.0p0 (2017-12-25 revision 61468) [x64-mingw32]
+
+### Description
+
+First, look at
+
+https://docs.ruby-lang.org/ja/latest/doc/spec=2flexical.html#reserved
+
+and then, look at entry.rb.
+
+The source code of entry.rb consists only of reserved words of Ruby,
+and all the reserved words are used in the code, in a way that the code
+forms a valid Ruby program. No compile error, no warning, or no runtime error.
+
+
+### Internals
+
+Difficult (and interesting) points of the theme are:
+
+* Since many of the reserved words define program structures, we cannot
+ use them independently. For instance, `retry` must be inside `rescue`,
+ or `break`/`next`/`redo` must be inside a looping construct.
+ Or, jump-out statements cannot occur at a position that requires a
+ value; `if return then true end` is a "void value expression" syntax error.
+* Inserting newlines for each 6 word (to match with the spec html) is also
+ an interseting challenge, since Ruby is sensitive to newlines.
+
+Tricks used in the code are:
+
+* def/alias/undef can take even reserved words as parameters.
+ That is, `def class ... end` defines a method named `class`.
+ The feature is crucial since otherwise `BEGIN` etc inevitably
+ introduces non-reserved tokens (like `{}`).
+* `defined?` can take some reserved words too (which I didn't know
+ until trying to write this program.)
+* "void value expression" can be avoided by using `or` or `and`.
+ `if begin return end then true end` is a syntax error, but
+ `if begin false or return end then true end` is not.
+
+
+### Limitation
+
+Sad to say that it's not a "perfect pangram".
+It uses 'alias' and 'undef' twice, and 'end' 4 times.
diff --git a/sample/trick2018/02-mame/authors.markdown b/sample/trick2018/02-mame/authors.markdown
new file mode 100644
index 0000000000..0e420fdf5d
--- /dev/null
+++ b/sample/trick2018/02-mame/authors.markdown
@@ -0,0 +1,3 @@
+* Yusuke Endoh
+ * mame@ruby-lang.org
+ * cctld: jp
diff --git a/sample/trick2018/02-mame/entry.rb b/sample/trick2018/02-mame/entry.rb
new file mode 100644
index 0000000000..cc4ef9cbc4
--- /dev/null
+++ b/sample/trick2018/02-mame/entry.rb
@@ -0,0 +1,15 @@
+'';eval(r=%q(->z{r="'';eval(r=\
+%q(#{r}))[%q`#{z}`]";i=-040;30.
+times{|n|(15+n%2*15-n/2).times{
+r<<r[i+=(1.-n&2)*(32-n%2*31)]}}
+i=r[524,0]=?\0;eval(r[479..-1])
+c['"']}))[%q`GFEDCBA"+"[e\"'"'t
+kE*;;\";" TRICK2018 ";tb,;{{r
+2E0$ob[us@*0)[90,336])_#i\n}s#i
+0H}>["t]];};o[1,?\n*8];ex"-}eac
+1Hl<1[-1]*2*t=n%2];o[14-n,0)mvk
+8M$<4,?\n];15.times{|n|;o[35ie2
+!Pss.slice!(0,1)+x;sleep(0.0t;0
+'W=%q"<<95<<$s<<95;o=->n,x{n.'1
+;@[2]}|\e../,%@s="'%trick2018!8
+eval$s=%q_eval($s.gsub!(/#{%@`]
diff --git a/sample/trick2018/02-mame/remarks.markdown b/sample/trick2018/02-mame/remarks.markdown
new file mode 100644
index 0000000000..88b32c205a
--- /dev/null
+++ b/sample/trick2018/02-mame/remarks.markdown
@@ -0,0 +1,16 @@
+This program quines with animation.
+
+```
+$ ruby entry.rb
+```
+
+Of course, the output is executable.
+
+```
+$ ruby entry.rb > output
+$ ruby output
+```
+
+Note, we don't cheat. This program uses escape sequences just for moving the cursor. It doesn't use attribution change nor overwrite to hide any code.
+
+The program is crafted so that it works in two ways; it works as a normal program text, and, it also works when it is rearranged in a spiral order. Some parts of the code are actually overlapped.
diff --git a/sample/trick2018/03-tompng/Gemfile b/sample/trick2018/03-tompng/Gemfile
new file mode 100644
index 0000000000..a24ff779dc
--- /dev/null
+++ b/sample/trick2018/03-tompng/Gemfile
@@ -0,0 +1,2 @@
+source 'https://rubygems.org'
+gem 'chunky_png'
diff --git a/sample/trick2018/03-tompng/Gemfile.lock b/sample/trick2018/03-tompng/Gemfile.lock
new file mode 100644
index 0000000000..467f5c3495
--- /dev/null
+++ b/sample/trick2018/03-tompng/Gemfile.lock
@@ -0,0 +1,13 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ chunky_png (1.3.8)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ chunky_png
+
+BUNDLED WITH
+ 1.16.1
diff --git a/sample/trick2018/03-tompng/authors.markdown b/sample/trick2018/03-tompng/authors.markdown
new file mode 100644
index 0000000000..26ebe24da6
--- /dev/null
+++ b/sample/trick2018/03-tompng/authors.markdown
@@ -0,0 +1,3 @@
+* Tomoya Ishida (tompng)
+ * tomoyapenguin@gmail.com
+ * cctld: jp
diff --git a/sample/trick2018/03-tompng/entry.rb b/sample/trick2018/03-tompng/entry.rb
new file mode 100644
index 0000000000..26416c7019
--- /dev/null
+++ b/sample/trick2018/03-tompng/entry.rb
@@ -0,0 +1,31 @@
+X=[];class String def-@;replace ?-+self end;def-a;X.reject!{|x|x.
+__id__==__id__};a.replace(self+?-+a) end end;at_exit{eval C=(Zlib
+.inflate((X*?-).tr(?-,'').tr('q-z','0-9').to_i(26).digits(0x100).
+pack'C*'))};def method_missing n;(X<<n.to_s)[-1]end;require'zlib'
+fzygtoxyzgntmdmuwvfoffbpmvzojpkhczvjvjdbtscnldwbdoprackddovivvmkz
+ponzmosvtjciwkgaslscxxxwudeesmmqpfhislxuxnnypulxstzgobyaekqqhbjcg
+mvko------------ddkeys----eivhnccaqyiw---bzyccmt-----------ymtnge
+jwhi--------------pjxf------mdarbtumnv---qasda--------------gmwdt
+wrtk---qtpzgnce----fsl-------fkgzgtbpp---gwnm----pxkpqkdiw---owga
+momz---yjjvpnvar---zeo---v-----duvalwu---nsqt---waofemwakivnyqkjd
+fzag---uhvusmkl----kzb---rhc----iutzjr---mqlh---ayijpwativpweaato
+xexs--------------rvgv---pjdz-----lkkg---uiaw---lovitupw-----fwmn
+kfru------------jvjpgv---jskycf----pal---gbuf---hfdnywog-----iuca
+pntn---apmkqroeuzwuwkw---gqnmgof-----b---hlpl---vkkyhfyrqfr--jwrl
+kmdb---dhspujhmtgrkccu---uonfummdt-------rqfw----bpiactehwp--fncq
+yzvz---gdaxebplhfndran---ytfmviryeh------hqwkl---------------nced
+bibu---fnkdthgldhkxxjg---rwnmpudhbqin----gucoyki------------hfura
+cqdgqpyzqfzknvdjoxxhpjulwwyebtocxdrvklbuviwwcatlmdosxfvwntzbijguy
+iglrvvzlxerflupxvsyujfacuwhrvmnecgtewtqkhtdggcltejiyqcluclkycwvzg
+vvxfysvttfbeglvrlngntdngzyhqrmltazwdydxrsvjploembhgxdvfmmhepbschm
+brn--iqrcdb--evv----tqp------lg--uein-wzut--mr------wkh------foqz
+zsf--srjnjp--ampb--pfio--hgtekx--rrr---fwd--jn--xqkezcz--vsb--nya
+khrc--evlr--oioxs--mqce--bqfmag--bwz---xda--qw--jnuzelr--qzi--itx
+mdxd--duso--wxbot--nmon--ugnbdpc--a--c--e--hlg--twxndre--tby--rhg
+evhbn--zb--dtxmiz--dpia------vie--h--i--t--shh------kfn------owna
+ealmt--kb--scxdjy--smvl--dqmgebk--t--s--t--gfd--updcbnc--rh--dwwp
+dvpnxb----wpljjdy--kolc--qflyleok---xkv---usbj--jhrawbn--ewx--bgf
+eaqwrw----ejwxhet--dice--eoczconm---urz---rqyp--hovvvfc--bskj--el
+aocjcts--jtumwxm----mgy------xpaoq-jtwqr-aipay------dhy--iync--hk
+sckddmvuvvuhhqstumaykvczaaujrumqbbqsdvdycplyrlkkojlxnkrhbbrmnjxyf
+cdtcmpfmjvthwkpzucbblttgumomlxnxwjeypfeagaukfzeokzxjebkpigcvlqnso
diff --git a/sample/trick2018/03-tompng/output.txt b/sample/trick2018/03-tompng/output.txt
new file mode 100644
index 0000000000..ed9a4079cc
--- /dev/null
+++ b/sample/trick2018/03-tompng/output.txt
@@ -0,0 +1,44 @@
+undef p;X=[];class String def-@;replace ?-+dup end;def-a;X.reject!{|x|x.__id__==__id__};a.replace(self+?-+a) end end;at_exit{eval C=
+(Zlib.inflate (X*?-).tr(?-,'').tr('q-z','0-9').to_i(26).digits(256).pack'C*')};def method_missing n;(X<<n.to_s)[-1]end;require'zlib'
+gmlztzdculbtzgtjfetuh---k--htf----d-----------------------------------------------------g-b-----s--t-g--------jmuwescmgchftikfjafccs
+ivchcveidpvxdabnvwyga-f--v-------xf----------------------------------------------------q-v---l-------q---------liiNeawriayymwooxgxqw
+rfosepqsmojseyezmwbhi--------------ew--------------------------------------------------m---k-r-----------vwu--hiotltdmczwyjmlvbyfqwq
+uvvykqdjednoqgtcmtfbzs---------f----o--------------------------------------------------t--a------m----x---f-----dldzsakyofetfozfpmrq
+geusutariiiNiulkjbwlm-----d------------------------------------------------------------j---------o---------x--j-uitzrgwpupwhvendhyno
+uubvnssiywkklwwdufhhi-rw----k---v-------------------------------------------------------sty-----yg---l---c-v----wkffpskpumolqmkeryzg
+zrxdaiposwybbzgxdnegh-----g-----ma--n---------------------------------------------------------j----n--b-n-------yqavmscswdogpcgopygt
+axiqfswlhzeamvymdnteo---q-q-w--------------------------fhrmj-----------------hkou-----------f-----d----u-o------evcuxxegekfgivzzujan
+nslioftsvqvtkeigvfgwr-------------lyco-----------------igyvg-----------------okuk---------m--b-u--d--y------s---dadjrlykfhtermzfyktu
+btoxzfpPicxxfligbivvf--------h----yrat---------------------------------------vjwd---------------------d-ki--o--tyqosehopkwttigwwfskp
+komzvnyrvkjcjwbmdwdkp----------vxphiNdtawn--xms-saketo--jnld----ezulntdaz----nzna-----vhjwt------h----x--x--o--saxxsrkgktqotaluylbkk
+sclegratyaarmgmepheml----------hwgglhlrfcx--znvmpfsgjx-onhju---gtxsmzqprlt---mjzy---frhdk-------------v---mj----dzjujmbgldfwoybgicwu
+tfhgnhlzxlwtdtkgzlaca-------------gmex------arlm--------rvmh-ajtgf-----pqal--wcux-zatyi-------------------------xnluwybcugjclmablshn
+tnjohqtqzivgmyutrssil-------------lcwq------jrf--------gcaii-maie------------vvnfjfqwo--------------------------filivosyhkxcvuwdibwj
+tyxjiopiFqypvwdzoatuq-------------tdln------cnx---------ffuf-ajvq------------tyyypglpzmj------------------------vtqzwewqdsijrbymvpwn
+niNffphoehukpvvmzvhyd-------------ahqd------nfr---------jeqk--toap-----mxhyg-tedv---otrwy-----------------------mjxnrktackwxwiajdnuc
+kkxhuwbvibpvgvcampadi-------------ebmencqz--obf--------wfprz---qmrotkijiqv---ggfp-----hlzw----------------------kastwdpxiyftmypuxbtu
+xetudmwzpomktgnjkcsyc---------------fwpdx---xb----j-----se-k------tllakc-----gjoo-------we------mic---lktk------ubtnrxvrjzuqlrfrsnmf
+okdvfvcdbdqkckjialskk---------------------------v---u-------l----------------------------------z--q--qfg--------aaliNbxbjjpxebboneye
+kcbkjmdclwnfawtfnwkeq----------------------------------j---y-------------------------------a---jmbyo-sgef--gf---extljbozuoofgyvsilct
+xzoqmsqgzjxxpjqwkjkdd------------------------o--------m-------f---------------------------------n--de-ajz-rzv---fhnpbkrwdxoozpxeaxaf
+mbcwxuiqdwcmadheiykaa-----------------------q-f------l---i---------------------------------r----zf---k--y---fi--dcnycheytylcgnioauee
+yekiNacriqoevtdjerqbp----------------------------w---yy-----my----------------------------ko--mnbpskr--c-----j--ozyqpbfovhbhyoprzgqr
+czwtuopxkdbphocfawvbk--------------------------q-s----j--b---------------------------------hd-xsb----bfiNp--w---fmwuvfambdqvxtzldwmh
+xysnyrseydlkjcwfbsjnr-------------------------d-d-------------------------------------------f-enpss---qllpwr----almsdidvjwoigvldfqoa
+lrpbixjpofxocxlflscpo------------------------------q-fyu--z-------------------------------------kfd-z---n-------bqxurujnxzurrdgcojks
+jetyfdkcekckxbyosbfws-------------wdfhgwuvejjmf-----sxjubpvgcsl-------tnmixpv---------eurabjsdvstfv-------------qcyiqhonwoyixqeonfvp
+mopPhywsozohitutgmmrb------------zxwtxe--riedeo---mspgpnv--pimlh------jhtzajk--------qqovvq---ldbrh-------------xtooxpayonpcvvtmvpra
+vvuyiunpoeagdzqjecsub------------klrw------snrc---rrct------aajom--------nsyk--------peea-------azq-------------iNjefdkfhnagjicqwmsm
+mbwwbfgehhbdmvvlflmee---------------------hkejn---jtbo-------jdtje-------jcei---------afyz-----smtc-------------kksvfjyuaqtohxiohhlz
+dvfmfrzcmnsfruhqgjuxz------------------dfxdnlk----kkra-------xmmtf-------jwkw----------rdoozxtcho---------------bbwwferxwnnmdzcniicv
+mfneisdlyeqwynldjgonj----------------jgrjvc-------uxga-------ghnpr-------sers--------scbknx----gmjo-------------moedtnlbflhtlkjibrqk
+gobwqshnpbdcpjmjaeczr--------------iscsxs---------zfpo-------hhfwy-------qbba-------vhlxc-------ntod------------ndwzdomaptumzejiwqbn
+snucynymvfpnadyqkzfcv-------------ggze------------kuvfs-----zuhod--------mylo-------jhwyp-----z-pywd------------dqfmpnevmtqcikbrilto
+aotyxkipebdkassogpcbl-----------wgackesmvvsrihhd---orzndjndlzpb----------eobf-------kkayixzyotqfafa-w-----------mjjxoomwdglwvccozzut
+rthesuszfwycsqqrtxlot-----------ejcqlhriilqbtrys------lwbkzmvp-----------zzwm-------l--qijwfllndzb-ik-----------mmokqomjepdcotnsiNig
+nloryyoswwdmefywnnuhph------------------------------------------------------r--r-nd-----h--x--------------------hlgzeqqslwxgtjgghquf
+nssngjtiudsrvfuxjzclhjhj----------------------------------------------------------t----------------k-f-mp-------obhyehqebtpjbkeepqzt
+ezogzsimfynqmkteaipejo-g-yser-----------------------------------------------e------h-------------i---y----------qpgcqnltivmmsximbbsy
+wtjjolwyoselcumgklqwpldkl-ulm-m---------------------------------------------------------------q---u-f--l--------buixfiitufktsqdtnrei
+tgrtitcewseetlpeuuujb-osdokjozc------------------------------------------n---d-----f--------g--------q--g-------jyyqtezuzmcxgpcwuwfx
+dpPayqmzxrwhbswwalygfurtkruw-u-k---------------------------------------------d---h------i----------c----i-------ulowcddvjbxthqlxjzbe
diff --git a/sample/trick2018/03-tompng/remarks.markdown b/sample/trick2018/03-tompng/remarks.markdown
new file mode 100644
index 0000000000..fe9eec5989
--- /dev/null
+++ b/sample/trick2018/03-tompng/remarks.markdown
@@ -0,0 +1,19 @@
+### Remarks
+
+Bundle install
+ this program depends on `gem chunky_png`
+
+Run it with the following command:
+ bundle exec ruby entry.rb trick.png
+ bundle exec ruby entry.rb [other png file]
+
+I confirmed the following implementations/platforms:
+
+* ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin16]
+* ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
+
+### Description
+
+This program is a png image viewer.
+The output is an asciiart of the given png file,
+and it is also a source code of the png viewer itself.
diff --git a/sample/trick2018/03-tompng/trick.png b/sample/trick2018/03-tompng/trick.png
new file mode 100644
index 0000000000..d4bb0bd7c3
--- /dev/null
+++ b/sample/trick2018/03-tompng/trick.png
Binary files differ
diff --git a/sample/trick2018/04-colin/authors.markdown b/sample/trick2018/04-colin/authors.markdown
new file mode 100644
index 0000000000..a846d12535
--- /dev/null
+++ b/sample/trick2018/04-colin/authors.markdown
@@ -0,0 +1,3 @@
+* Colin Fulton
+ * justcolin@gmail.com
+ * cctld: us
diff --git a/sample/trick2018/04-colin/entry.rb b/sample/trick2018/04-colin/entry.rb
new file mode 100644
index 0000000000..442a8ea3a8
--- /dev/null
+++ b/sample/trick2018/04-colin/entry.rb
@@ -0,0 +1,2 @@
+# Copyright 2018. Available for use under the terms of the MIT License.
+$🚀=0;def 🤔 ðŸ·,🤔=0,&b;puts ' '*$🚀+(🤔 ?"":"🚫 ")+ðŸ·;$🚀+=4;b&.[];$🚀-=4;end
diff --git a/sample/trick2018/04-colin/remarks.markdown b/sample/trick2018/04-colin/remarks.markdown
new file mode 100644
index 0000000000..5f4f1a8dfe
--- /dev/null
+++ b/sample/trick2018/04-colin/remarks.markdown
@@ -0,0 +1,62 @@
+### Remarks
+
+Create a Ruby file that requires entry.rb with a series of test in it the run the file using ruby:
+
+```
+ruby name_of_test_file.rb
+```
+
+To create a test, call 🤔 with two arguments. The first is a string describing what this tests, the second argument is the test assertion. If the assertion is truthy, the test passes. If the assertion is falsy, the test fails.
+
+```
+string_1 = "Hello world!"
+string_2 = "This is not the same!"
+
+🤔 "The two strings are equal",
+ string_1 == string_2
+```
+
+To create a group of tests under a label, call 🤔 with a string describing the group and a block containing the tests in that group.
+
+```
+🤔 "This is a group of tests" do
+ # Add other groups and/or tests here.
+end
+```
+
+Here is an example:
+
+```
+require './entry'
+
+🤔 "Math" do
+ 🤔 "Addition" do
+ 🤔 "One plus one equals two.",
+ 1+1 == 2
+ 🤔 "One plus one equals eleven. (This should fail.)",
+ 1+1 == 11
+ end
+
+ 🤔 "Subtraction" do
+ 🤔 "One minus one equals zero.",
+ 1-1 == 0
+ 🤔 "Ten minus one equal nine.",
+ 10-1 == 9
+ end
+end
+```
+
+It has been tested with the following Ruby versions:
+
+* ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
+* ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]
+* If you replace `b&.[]` with `b&&b[]` it will work with ruby 2.0.0 as well, but it will be one character longer.
+
+
+### Description
+
+The goal was to create a testing library where the test files looked good and the output looked good in as few characters as possible. The result is 68 characters and has one method to handle everything.
+
+### Limitation
+
+Your terminal program must support Unicode characters for the test output to look correct. If your terminal does not support Unicode, simply replace the 🚫 in the code with whatever character you want to prefix failing tests.
diff --git a/sample/trick2018/05-tompng/authors.markdown b/sample/trick2018/05-tompng/authors.markdown
new file mode 100644
index 0000000000..26ebe24da6
--- /dev/null
+++ b/sample/trick2018/05-tompng/authors.markdown
@@ -0,0 +1,3 @@
+* Tomoya Ishida (tompng)
+ * tomoyapenguin@gmail.com
+ * cctld: jp
diff --git a/sample/trick2018/05-tompng/entry.rb b/sample/trick2018/05-tompng/entry.rb
new file mode 100644
index 0000000000..31522b6de2
--- /dev/null
+++ b/sample/trick2018/05-tompng/entry.rb
@@ -0,0 +1,41 @@
+ X=[];def self.method_missing n;n.to_s.chars;end
+ l=[];def l.-a;X<<a=[nil,*a];a;end;def l.+a;self-a;end
+ class Array;def-@;[]-self;end;def-a;replace [*self,nil,*a
+ ]end;alias +@ -@;alias + -;end;def gen3d f;yield;b=['solid obj'];w,
+ h=X[0].size,X.size;X<<[];a=->r,z,dr,dz{;r-=w/2.0;z*=2;r2,z2=r+dr,z+dz*2;if r>0||r2>
+ 0;r=[0,r].max;r2=[0,r2].max;16.times{|i|m=Math;p=m::PI/8;;c,s=m.cos(t=i*p),m.sin(t)
+ c2,s2=m.cos(t=(i+1)*p),m.sin(t);t-=p/2;[[0,1,2],[0,2,3]].map{|a|b.push [:facet,'n'+
+ + 'ormal',dz*m.cos(t),dz*m.sin(t),-dr]*' ','outer loop',a.map{|i|'v'+
+ ++ "ertex #{[[r*c,r*s,z],[r*c2,r*s2,z],[r2*c2,r2*s2,z2],[r2*
+ +c, r2*s,z2]][i]*' '}"},:endloop,:endfacet}}end};(0...h).
+ map{| y|w.times{|x|[X[y-1][x]||a[x,y,1,0],X[y+1][x]||
+ a[x+1,y+
+ 1,-1,0],X[
+ y][x-+1]||a[
+ x,y+1,0,-1],X[y
+ ][x++1]||a[x+1,y,
+ 0,1]]if X[y][x]}}
+ s=[b,'end'+b[0]]*
+ $/;File.write(f,
+ s);X.replace(
+ []);end
+
+gen3d 'wine_glass.stl' do
+ l--ww------------------ww--l
+ l--ww------------------ww--l
+ l--ww++++++++++++++++++ww--l
+ l--ww++++++++++++++++++ww--l
+ l--ww++++++++++++++++++ww--l
+ l--ww++++++++++++++++++ww--l
+ l---ww++++++++++++++++ww---l
+ l----www++++++++++++www----l
+ l------www++++++++www------l
+ l--------wwwwwwwwww--------l
+ l-----------wwww-----------l
+ l------------ww------------l
+ l------------ww------------l
+ l------------ww------------l
+ l-----------wwww-----------l
+ l---------wwwwwwww---------l
+ l----wwwwwwwwwwwwwwwwww----l
+end
diff --git a/sample/trick2018/05-tompng/preview_of_output.png b/sample/trick2018/05-tompng/preview_of_output.png
new file mode 100644
index 0000000000..db511ee2f3
--- /dev/null
+++ b/sample/trick2018/05-tompng/preview_of_output.png
Binary files differ
diff --git a/sample/trick2018/05-tompng/remarks.markdown b/sample/trick2018/05-tompng/remarks.markdown
new file mode 100644
index 0000000000..b4e5708a43
--- /dev/null
+++ b/sample/trick2018/05-tompng/remarks.markdown
@@ -0,0 +1,31 @@
+### Remarks
+
+Just run it with no argument:
+
+ ruby entry.rb
+
+I confirmed the following implementations/platforms:
+
+* ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin16]
+* ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
+* ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
+
+### Description
+
+This program will generate `wine_glass.stl`, a 3D data file(STL format) of a wine glass.
+You can change the shape by modifying the DSL part.
+For sake cup:
+```ruby
+gen3d 'ochoko.stl' do
+ l------------------------l
+ l-ww------------------ww-l
+ l-ww------------------ww-l
+ l-ww++++++++++++++++++ww-l
+ l-ww++++++++++++++++++ww-l
+ l--ww++++++++++++++++ww--l
+ l---wwww++++++++++wwww---l
+ l----wwwwwwwwwwwwwwww----l
+ l----www----------www----l
+end
+```
+`+` and `-` are the same meaning(just for appearance)
diff --git a/sample/trick2018/README.md b/sample/trick2018/README.md
new file mode 100644
index 0000000000..345500b00a
--- /dev/null
+++ b/sample/trick2018/README.md
@@ -0,0 +1,16 @@
+This directory contains the award-winning entries of
+the 3rd Transcendental Ruby Imbroglio Contest for rubyKaigi (TRICK 2018).
+
+THESE ARE BAD EXAMPLES! You must NOT use them as a sample code.
+
+* 01-kinaba/entry.rb: "Most reserved" - **Gold award**
+* 02-mame/entry.rb: "Best spiral" - **Silver award**
+* 03-tompng/entry.rb: "Best png viewer" - **Bronze award**
+* 04-colin/entry.rb: "Best one-liner" - 4th prize
+* 05-tompng/entry.rb: "Most three-dimensional" - 5th prize
+
+These files are licensed under MIT license.
+
+For the contest outline and other winning entries, see:
+
+https://github.com/tric/trick2018
diff --git a/sample/webrick/demo-app.rb b/sample/webrick/demo-app.rb
deleted file mode 100644
index c7a2a0a6a4..0000000000
--- a/sample/webrick/demo-app.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-require "pp"
-
-module DemoApplication
- def initialize(config, enctype)
- super
- @enctype = enctype
- end
-
- def do_GET(req, res)
- if req.path_info != "/"
- res.set_redirect(WEBrick::HTTPStatus::Found, req.script_name + "/")
- end
- res.body =<<-_end_of_html_
- <HTML>
- <FORM method="POST" enctype=#{@enctype}>
- text: <INPUT type="text" name="text"><BR>
- file: <INPUT type="file" name="file"><BR>
- check:
- <INPUT type="checkbox" name="check" value="a">a,
- <INPUT type="checkbox" name="check" value="b">b,
- <INPUT type="checkbox" name="check" value="c">c,
- <BR>
- <INPUT type="submit">
- </FORM>
- </HTML>
- _end_of_html_
- res['content-type'] = 'text/html; charset=iso-8859-1'
- end
-
- def do_POST(req, res)
- if req["content-length"].to_i > 1024*10
- raise WEBrick::HTTPStatus::Forbidden, "file size too large"
- end
- res.body =<<-_end_of_html_
- <HTML>
- <H2>Query Parameters</H2>
- #{display_query(req.query)}
- <A href="#{req.path}">return</A>
- <H2>Request</H2>
- <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(req, "", 80))}</PRE>
- <H2>Response</H2>
- <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(res, "", 80))}</PRE>
- </HTML>
- _end_of_html_
- res['content-type'] = 'text/html; charset=iso-8859-1'
- end
-
- private
-
- def display_query(q)
- ret = ""
- q.each{|key, val|
- ret << "<H3>#{WEBrick::HTMLUtils::escape(key)}</H3>"
- ret << "<TABLE border=1>"
- ret << make_tr("val", val.inspect)
- ret << make_tr("val.to_a", val.to_a.inspect)
- ret << make_tr("val.to_ary", val.to_ary.inspect)
- ret << "</TABLE>"
- }
- ret
- end
-
- def make_tr(arg0, arg1)
- "<TR><TD>#{arg0}</TD><TD>#{WEBrick::HTMLUtils::escape(arg1)}</TD></TR>"
- end
-end
diff --git a/sample/webrick/demo-multipart.cgi b/sample/webrick/demo-multipart.cgi
deleted file mode 100644
index 0893fadadf..0000000000
--- a/sample/webrick/demo-multipart.cgi
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env ruby
-require "webrick/cgi"
-require "webrick/https" # should load if it runs on HTTPS server
-require "./demo-app"
-
-class DemoCGI < WEBrick::CGI
- include DemoApplication
-end
-
-config = { :NPH => false }
-cgi = DemoCGI.new(config, "multipart/form-data")
-cgi.start
diff --git a/sample/webrick/demo-servlet.rb b/sample/webrick/demo-servlet.rb
deleted file mode 100644
index 9c18cc65d1..0000000000
--- a/sample/webrick/demo-servlet.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require "webrick"
-require "./demo-app"
-
-class DemoServlet < WEBrick::HTTPServlet::AbstractServlet
- include DemoApplication
-end
diff --git a/sample/webrick/demo-urlencoded.cgi b/sample/webrick/demo-urlencoded.cgi
deleted file mode 100644
index e4706f8b59..0000000000
--- a/sample/webrick/demo-urlencoded.cgi
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env ruby
-require "webrick/cgi"
-require "webrick/https" # should load if it runs on HTTPS server
-require "./demo-app"
-
-class DemoCGI < WEBrick::CGI
- include DemoApplication
-end
-
-config = { :NPH => false }
-cgi = DemoCGI.new(config, "application/x-www-form-urlencoded")
-cgi.start
diff --git a/sample/webrick/hello.cgi b/sample/webrick/hello.cgi
deleted file mode 100644
index 35d2240df0..0000000000
--- a/sample/webrick/hello.cgi
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env ruby
-require "webrick/cgi"
-
-class HelloCGI < WEBrick::CGI
- def do_GET(req, res)
- res["content-type"] = "text/plain"
- res.body = "Hello, world.\n"
- end
-end
-
-HelloCGI.new.start
diff --git a/sample/webrick/hello.rb b/sample/webrick/hello.rb
deleted file mode 100644
index 4d02676818..0000000000
--- a/sample/webrick/hello.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "webrick"
-
-class HelloServlet < WEBrick::HTTPServlet::AbstractServlet
- def do_GET(req, res)
- res["content-type"] = "text/plain"
- res.body = "Hello, world.\n"
- end
-end
diff --git a/sample/webrick/httpd.rb b/sample/webrick/httpd.rb
deleted file mode 100644
index b0edf47582..0000000000
--- a/sample/webrick/httpd.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require "webrick"
-
-httpd = WEBrick::HTTPServer.new(
- :DocumentRoot => File::dirname(__FILE__),
- :Port => 10080,
- :Logger => WEBrick::Log.new($stderr, WEBrick::Log::DEBUG),
- :AccessLog => [
- [ $stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
- [ $stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
- [ $stderr, WEBrick::AccessLog::AGENT_LOG_FORMAT ],
- ],
- :CGIPathEnv => ENV["PATH"] # PATH environment variable for CGI.
-)
-
-require "./hello"
-httpd.mount("/hello", HelloServlet)
-
-require "./demo-servlet"
-httpd.mount("/urlencoded", DemoServlet, "application/x-www-form-urlencoded")
-httpd.mount("/multipart", DemoServlet, "multipart/form-data")
-
-trap(:INT){ httpd.shutdown }
-httpd.start
diff --git a/sample/webrick/httpproxy.rb b/sample/webrick/httpproxy.rb
deleted file mode 100644
index c84457ece7..0000000000
--- a/sample/webrick/httpproxy.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require "webrick"
-require "webrick/httpproxy"
-
-# The :ProxyContentHandler proc will be invoked before sending a response to
-# the User-Agent. You can inspect the pair of request and response messages
-# (or edit the response message if necessary).
-
-pch = Proc.new{|req, res|
- p [ req.request_line, res.status_line ]
-}
-
-def upstream_proxy
- if prx = ENV["http_proxy"]
- return URI.parse(prx)
- end
- return nil
-end
-
-httpd = WEBrick::HTTPProxyServer.new(
- :Port => 10080,
- :ProxyContentHandler => pch,
- :ProxyURI => upstream_proxy
-)
-Signal.trap(:INT){ httpd.shutdown }
-httpd.start
diff --git a/sample/webrick/httpsd.rb b/sample/webrick/httpsd.rb
deleted file mode 100644
index a120782c3c..0000000000
--- a/sample/webrick/httpsd.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require "webrick"
-require "webrick/https"
-
-hostname = WEBrick::Utils::getservername
-subject = [["O", "ruby-lang.org"], ["OU", "sample"], ["CN", hostname]]
-comment = "Comment for self-signed certificate"
-
-httpd = WEBrick::HTTPServer.new(
- :DocumentRoot => File::dirname(__FILE__),
- :Port => 10443,
- :SSLEnable => true,
-
- # Specify key pair and server certificate.
- # :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.read("server.key")),
- # :SSLCertificate => OpenSSL::X509::Certificate.new(File.read("server.crt")),
-
- # specify the following SSL options if you want to use auto
- # generated self-signed certificate.
- :SSLCertName => subject,
- :SSLComment => comment,
-
- :CGIPathEnv => ENV["PATH"] # PATH environment variable for CGI.
-)
-
-require "./hello"
-httpd.mount("/hello", HelloServlet)
-
-require "./demo-servlet"
-httpd.mount("/urlencoded", DemoServlet, "application/x-www-form-urlencoded")
-httpd.mount("/multipart", DemoServlet, "multipart/form-data")
-
-trap(:INT){ httpd.shutdown }
-httpd.start
diff --git a/scheduler.c b/scheduler.c
new file mode 100644
index 0000000000..66cbfc6f10
--- /dev/null
+++ b/scheduler.c
@@ -0,0 +1,212 @@
+/**********************************************************************
+
+ scheduler.c
+
+ $Author$
+
+ Copyright (C) 2020 Samuel Grant Dawson Williams
+
+**********************************************************************/
+
+#include "vm_core.h"
+#include "internal/scheduler.h"
+#include "ruby/io.h"
+
+static ID id_close;
+
+static ID id_block;
+static ID id_unblock;
+
+static ID id_kernel_sleep;
+static ID id_process_wait;
+
+static ID id_io_read;
+static ID id_io_write;
+static ID id_io_wait;
+
+void
+Init_Scheduler(void)
+{
+ id_close = rb_intern_const("close");
+
+ id_block = rb_intern_const("block");
+ id_unblock = rb_intern_const("unblock");
+
+ id_kernel_sleep = rb_intern_const("kernel_sleep");
+ id_process_wait = rb_intern_const("process_wait");
+
+ id_io_read = rb_intern_const("io_read");
+ id_io_write = rb_intern_const("io_write");
+ id_io_wait = rb_intern_const("io_wait");
+}
+
+VALUE
+rb_scheduler_get(void)
+{
+ rb_thread_t *thread = GET_THREAD();
+ VM_ASSERT(thread);
+
+ return thread->scheduler;
+}
+
+static void
+verify_interface(VALUE scheduler)
+{
+ if (!rb_respond_to(scheduler, id_block)) {
+ rb_raise(rb_eArgError, "Scheduler must implement #block!");
+ }
+
+ if (!rb_respond_to(scheduler, id_unblock)) {
+ rb_raise(rb_eArgError, "Scheduler must implement #unblock!");
+ }
+
+ if (!rb_respond_to(scheduler, id_kernel_sleep)) {
+ rb_raise(rb_eArgError, "Scheduler must implement #kernel_sleep!");
+ }
+
+ if (!rb_respond_to(scheduler, id_io_wait)) {
+ rb_raise(rb_eArgError, "Scheduler must implement #io_wait!");
+ }
+}
+
+VALUE
+rb_scheduler_set(VALUE scheduler)
+{
+ rb_thread_t *thread = GET_THREAD();
+ VM_ASSERT(thread);
+
+ if (scheduler != Qnil) {
+ verify_interface(scheduler);
+ }
+
+ // We invoke Scheduler#close when setting it to something else, to ensure the previous scheduler runs to completion before changing the scheduler. That way, we do not need to consider interactions, e.g., of a Fiber from the previous scheduler with the new scheduler.
+ if (thread->scheduler != Qnil) {
+ rb_scheduler_close(thread->scheduler);
+ }
+
+ thread->scheduler = scheduler;
+
+ return thread->scheduler;
+}
+
+static VALUE
+rb_threadptr_scheduler_current(rb_thread_t *thread)
+{
+ VM_ASSERT(thread);
+
+ if (thread->blocking == 0) {
+ return thread->scheduler;
+ } else {
+ return Qnil;
+ }
+}
+
+VALUE
+rb_scheduler_current(void)
+{
+ return rb_threadptr_scheduler_current(GET_THREAD());
+}
+
+VALUE rb_thread_scheduler_current(VALUE thread)
+{
+ return rb_threadptr_scheduler_current(rb_thread_ptr(thread));
+}
+
+VALUE
+rb_scheduler_close(VALUE scheduler)
+{
+ if (rb_respond_to(scheduler, id_close)) {
+ return rb_funcall(scheduler, id_close, 0);
+ }
+
+ return Qnil;
+}
+
+VALUE
+rb_scheduler_timeout(struct timeval *timeout)
+{
+ if (timeout) {
+ return rb_float_new((double)timeout->tv_sec + (0.000001f * timeout->tv_usec));
+ }
+
+ return Qnil;
+}
+
+VALUE
+rb_scheduler_kernel_sleep(VALUE scheduler, VALUE timeout)
+{
+ return rb_funcall(scheduler, id_kernel_sleep, 1, timeout);
+}
+
+VALUE
+rb_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv)
+{
+ return rb_funcallv(scheduler, id_kernel_sleep, argc, argv);
+}
+
+int
+rb_scheduler_supports_process_wait(VALUE scheduler)
+{
+ return rb_respond_to(scheduler, id_process_wait);
+}
+
+VALUE
+rb_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
+{
+ return rb_funcall(scheduler, id_process_wait, 2, PIDT2NUM(pid), RB_INT2NUM(flags));
+}
+
+VALUE
+rb_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout)
+{
+ return rb_funcall(scheduler, id_block, 2, blocker, timeout);
+}
+
+VALUE
+rb_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
+{
+ return rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
+}
+
+VALUE
+rb_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout)
+{
+ return rb_funcall(scheduler, id_io_wait, 3, io, events, timeout);
+}
+
+VALUE
+rb_scheduler_io_wait_readable(VALUE scheduler, VALUE io)
+{
+ return rb_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_READABLE), Qnil);
+}
+
+VALUE
+rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io)
+{
+ return rb_scheduler_io_wait(scheduler, io, RB_UINT2NUM(RUBY_IO_WRITABLE), Qnil);
+}
+
+int
+rb_scheduler_supports_io_read(VALUE scheduler)
+{
+ return rb_respond_to(scheduler, id_io_read);
+}
+
+VALUE
+rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
+{
+ return rb_funcall(scheduler, id_io_read, 4, io, buffer, SIZET2NUM(offset), SIZET2NUM(length));
+}
+
+int
+rb_scheduler_supports_io_write(VALUE scheduler)
+{
+ return rb_respond_to(scheduler, id_io_write);
+}
+
+VALUE
+rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
+{
+ // We should ensure string has capacity to receive data, and then resize it afterwards.
+ return rb_funcall(scheduler, id_io_write, 4, io, buffer, SIZET2NUM(offset), SIZET2NUM(length));
+}
diff --git a/signal.c b/signal.c
index 113bfe7d24..c13bc19f1c 100644
--- a/signal.c
+++ b/signal.c
@@ -11,42 +11,39 @@
**********************************************************************/
-#include "internal.h"
-#include "vm_core.h"
+#include "ruby/internal/config.h"
+
+#include <errno.h>
#include <signal.h>
#include <stdio.h>
-#include <errno.h>
-#include "ruby_atomic.h"
-#include "eval_intern.h"
+
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
+
#ifdef HAVE_SYS_UIO_H
-#include <sys/uio.h>
-#endif
-#ifdef HAVE_UCONTEXT_H
-#include <ucontext.h>
+# include <sys/uio.h>
#endif
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-# include <valgrind/memcheck.h>
-# ifndef VALGRIND_MAKE_MEM_DEFINED
-# define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
-# endif
-# ifndef VALGRIND_MAKE_MEM_UNDEFINED
-# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
-# endif
-#else
-# define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
-# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
+#ifdef HAVE_UCONTEXT_H
+# include <ucontext.h>
#endif
-#if defined(__native_client__) && defined(NACL_NEWLIB)
-# include "nacl/signal.h"
+#if HAVE_PTHREAD_H
+# include <pthread.h>
#endif
-extern ID ruby_static_id_signo;
-#define id_signo ruby_static_id_signo
+#include "debug_counter.h"
+#include "eval_intern.h"
+#include "internal.h"
+#include "internal/eval.h"
+#include "internal/sanitizers.h"
+#include "internal/signal.h"
+#include "internal/string.h"
+#include "internal/thread.h"
+#include "ruby_atomic.h"
+#include "vm_core.h"
+#include "ractor_core.h"
#ifdef NEED_RUBY_ATOMIC_OPS
rb_atomic_t
@@ -69,12 +66,11 @@ ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp,
}
#endif
-#ifndef NSIG
-# define NSIG (_SIGMAX + 1) /* For QNX */
-#endif
-
+#define FOREACH_SIGNAL(sig, offset) \
+ for (sig = siglist + (offset); sig < siglist + numberof(siglist); ++sig)
+enum { LONGEST_SIGNAME = 7 }; /* MIGRATE and RETRACT */
static const struct signals {
- const char *signm;
+ char signm[LONGEST_SIGNAME + 1];
int signo;
} siglist [] = {
{"EXIT", 0},
@@ -136,15 +132,9 @@ static const struct signals {
#ifdef SIGCONT
{"CONT", SIGCONT},
#endif
-#ifdef SIGCHLD
- {"CHLD", SIGCHLD},
-#endif
-#ifdef SIGCLD
- {"CLD", SIGCLD},
-#else
-# ifdef SIGCHLD
- {"CLD", SIGCHLD},
-# endif
+#if RUBY_SIGCHLD
+ {"CHLD", RUBY_SIGCHLD },
+ {"CLD", RUBY_SIGCHLD },
#endif
#ifdef SIGTTIN
{"TTIN", SIGTTIN},
@@ -209,20 +199,83 @@ static const struct signals {
#ifdef SIGINFO
{"INFO", SIGINFO},
#endif
- {NULL, 0}
};
-static const char signame_prefix[3] = "SIG";
+static const char signame_prefix[] = "SIG";
+static const int signame_prefix_len = 3;
static int
-signm2signo(const char *nm)
+signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr)
{
const struct signals *sigs;
+ VALUE vsig = *sig_ptr;
+ const char *nm;
+ long len, nmlen;
+ int prefix = 0;
- for (sigs = siglist; sigs->signm; sigs++)
- if (strcmp(sigs->signm, nm) == 0)
- return sigs->signo;
- return 0;
+ if (RB_SYMBOL_P(vsig)) {
+ *sig_ptr = vsig = rb_sym2str(vsig);
+ }
+ else if (!RB_TYPE_P(vsig, T_STRING)) {
+ VALUE str = rb_check_string_type(vsig);
+ if (NIL_P(str)) {
+ rb_raise(rb_eArgError, "bad signal type %s",
+ rb_obj_classname(vsig));
+ }
+ *sig_ptr = vsig = str;
+ }
+
+ rb_must_asciicompat(vsig);
+ RSTRING_GETMEM(vsig, nm, len);
+ if (memchr(nm, '\0', len)) {
+ rb_raise(rb_eArgError, "signal name with null byte");
+ }
+
+ if (len > 0 && nm[0] == '-') {
+ if (!negative)
+ rb_raise(rb_eArgError, "negative signal name: % "PRIsVALUE, vsig);
+ prefix = 1;
+ }
+ else {
+ negative = 0;
+ }
+ if (len >= prefix + signame_prefix_len) {
+ if (memcmp(nm + prefix, signame_prefix, signame_prefix_len) == 0)
+ prefix += signame_prefix_len;
+ }
+ if (len <= (long)prefix) {
+ goto unsupported;
+ }
+
+ if (prefix_ptr) *prefix_ptr = prefix;
+ nmlen = len - prefix;
+ nm += prefix;
+ if (nmlen > LONGEST_SIGNAME) goto unsupported;
+ FOREACH_SIGNAL(sigs, !exit) {
+ if (memcmp(sigs->signm, nm, nmlen) == 0 &&
+ sigs->signm[nmlen] == '\0') {
+ return negative ? -sigs->signo : sigs->signo;
+ }
+ }
+
+ unsupported:
+ if (prefix == signame_prefix_len) {
+ prefix = 0;
+ }
+ else if (prefix > signame_prefix_len) {
+ prefix -= signame_prefix_len;
+ len -= prefix;
+ vsig = rb_str_subseq(vsig, prefix, len);
+ prefix = 0;
+ }
+ else {
+ len -= prefix;
+ vsig = rb_str_subseq(vsig, prefix, len);
+ prefix = signame_prefix_len;
+ }
+ rb_raise(rb_eArgError, "unsupported signal `%.*s%"PRIsVALUE"'",
+ prefix, signame_prefix, vsig);
+ UNREACHABLE_RETURN(0);
}
static const char*
@@ -230,9 +283,10 @@ signo2signm(int no)
{
const struct signals *sigs;
- for (sigs = siglist; sigs->signm; sigs++)
+ FOREACH_SIGNAL(sigs, 0) {
if (sigs->signo == no)
return sigs->signm;
+ }
return 0;
}
@@ -291,7 +345,6 @@ esignal_init(int argc, VALUE *argv, VALUE self)
int argnum = 1;
VALUE sig = Qnil;
int signo;
- const char *signm;
if (argc > 0) {
sig = rb_check_to_integer(argv[0], "to_int");
@@ -312,19 +365,11 @@ esignal_init(int argc, VALUE *argv, VALUE self)
}
}
else {
- int len = sizeof(signame_prefix);
- if (SYMBOL_P(sig)) sig = rb_sym2str(sig); else StringValue(sig);
- signm = RSTRING_PTR(sig);
- if (strncmp(signm, signame_prefix, len) == 0) {
- signm += len;
- len = 0;
- }
- signo = signm2signo(signm);
- if (!signo) {
- rb_raise(rb_eArgError, "unsupported name `%.*s%"PRIsVALUE"'",
- len, signame_prefix, sig);
+ int prefix;
+ signo = signm2signo(&sig, FALSE, FALSE, &prefix);
+ if (prefix != signame_prefix_len) {
+ sig = rb_str_append(rb_str_new_cstr("SIG"), sig);
}
- sig = rb_sprintf("SIG%s", signm);
}
rb_call_super(1, &sig);
rb_ivar_set(self, id_signo, INT2NUM(signo));
@@ -352,108 +397,46 @@ interrupt_init(int argc, VALUE *argv, VALUE self)
VALUE args[2];
args[0] = INT2FIX(SIGINT);
- rb_scan_args(argc, argv, "01", &args[1]);
+ args[1] = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
return rb_call_super(2, args);
}
+void rb_malloc_info_show_results(void); /* gc.c */
+
void
ruby_default_signal(int sig)
{
+#if USE_DEBUG_COUNTER
+ rb_debug_counter_show_results("killed by signal.");
+#endif
+ rb_malloc_info_show_results();
+
signal(sig, SIG_DFL);
raise(sig);
}
-static RETSIGTYPE sighandler(int sig);
+static void sighandler(int sig);
static int signal_ignored(int sig);
static void signal_enque(int sig);
-/*
- * call-seq:
- * Process.kill(signal, pid, ...) -> integer
- *
- * Sends the given signal to the specified process id(s) if _pid_ is positive.
- * If _pid_ is zero _signal_ is sent to all processes whose group ID is equal
- * to the group ID of the process. _signal_ may be an integer signal number or
- * a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is
- * negative (or starts with a minus sign), kills process groups instead of
- * processes. Not all signals are available on all platforms.
- * The keys and values of +Signal.list+ are known signal names and numbers,
- * respectively.
- *
- * pid = fork do
- * Signal.trap("HUP") { puts "Ouch!"; exit }
- * # ... do some work ...
- * end
- * # ...
- * Process.kill("HUP", pid)
- * Process.wait
- *
- * <em>produces:</em>
- *
- * Ouch!
- *
- * If _signal_ is an integer but wrong for signal,
- * <code>Errno::EINVAL</code> or +RangeError+ will be raised.
- * Otherwise unless _signal_ is a +String+ or a +Symbol+, and a known
- * signal name, +ArgumentError+ will be raised.
- *
- * Also, <code>Errno::ESRCH</code> or +RangeError+ for invalid _pid_,
- * <code>Errno::EPERM</code> when failed because of no privilege,
- * will be raised. In these cases, signals may have been sent to
- * preceding processes.
- */
-
VALUE
rb_f_kill(int argc, const VALUE *argv)
{
#ifndef HAVE_KILLPG
#define killpg(pg, sig) kill(-(pg), (sig))
#endif
- int negative = 0;
int sig;
int i;
VALUE str;
- const char *s;
rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
- switch (TYPE(argv[0])) {
- case T_FIXNUM:
+ if (FIXNUM_P(argv[0])) {
sig = FIX2INT(argv[0]);
- break;
-
- case T_SYMBOL:
- str = rb_sym2str(argv[0]);
- goto str_signal;
-
- case T_STRING:
+ }
+ else {
str = argv[0];
- str_signal:
- s = RSTRING_PTR(str);
- if (s[0] == '-') {
- negative++;
- s++;
- }
- if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0)
- s += 3;
- if ((sig = signm2signo(s)) == 0) {
- long ofs = s - RSTRING_PTR(str);
- if (ofs) str = rb_str_subseq(str, ofs, RSTRING_LEN(str)-ofs);
- rb_raise(rb_eArgError, "unsupported name `SIG%"PRIsVALUE"'", str);
- }
-
- if (negative)
- sig = -sig;
- break;
-
- default:
- str = rb_check_string_type(argv[0]);
- if (!NIL_P(str)) {
- goto str_signal;
- }
- rb_raise(rb_eArgError, "bad signal type %s",
- rb_obj_classname(argv[0]));
- break;
+ sig = signm2signo(&str, TRUE, FALSE, NULL);
}
if (argc <= 1) return INT2FIX(0);
@@ -466,7 +449,7 @@ rb_f_kill(int argc, const VALUE *argv)
}
}
else {
- const rb_pid_t self = (GET_THREAD() == GET_VM()->main_thread) ? getpid() : -1;
+ const rb_pid_t self = (GET_THREAD() == GET_VM()->ractor.main_thread) ? getpid() : -1;
int wakeup = 0;
for (i=1; i<argc; i++) {
@@ -513,7 +496,7 @@ rb_f_kill(int argc, const VALUE *argv)
}
}
if (wakeup) {
- rb_threadptr_check_signal(GET_VM()->main_thread);
+ rb_threadptr_check_signal(GET_VM()->ractor.main_thread);
}
}
rb_thread_execute_interrupts(rb_thread_current());
@@ -525,34 +508,37 @@ static struct {
rb_atomic_t cnt[RUBY_NSIG];
rb_atomic_t size;
} signal_buff;
+#if RUBY_SIGCHLD
+volatile unsigned int ruby_nocldwait;
+#endif
-#ifdef __dietlibc__
-#define sighandler_t sh_t
-#else
#define sighandler_t ruby_sighandler_t
-#endif
-typedef RETSIGTYPE (*sighandler_t)(int);
#ifdef USE_SIGALTSTACK
typedef void ruby_sigaction_t(int, siginfo_t*, void*);
#define SIGINFO_ARG , siginfo_t *info, void *ctx
#define SIGINFO_CTX ctx
#else
-typedef RETSIGTYPE ruby_sigaction_t(int);
+typedef void ruby_sigaction_t(int);
#define SIGINFO_ARG
#define SIGINFO_CTX 0
#endif
#ifdef USE_SIGALTSTACK
-int
+/* XXX: BSD_vfprintf() uses >1500B stack and x86-64 need >5KiB stack. */
+#define RUBY_SIGALTSTACK_SIZE (16*1024)
+
+static int
rb_sigaltstack_size(void)
{
- /* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */
- int size = 16*1024;
+ int size = RUBY_SIGALTSTACK_SIZE;
#ifdef MINSIGSTKSZ
- if (size < MINSIGSTKSZ)
- size = MINSIGSTKSZ;
+ {
+ int minsigstksz = (int)MINSIGSTKSZ;
+ if (size < minsigstksz)
+ size = minsigstksz;
+ }
#endif
#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
{
@@ -566,20 +552,33 @@ rb_sigaltstack_size(void)
return size;
}
+static int rb_sigaltstack_size_value = 0;
+
+void *
+rb_allocate_sigaltstack(void)
+{
+ void *altstack;
+ if (!rb_sigaltstack_size_value) {
+ rb_sigaltstack_size_value = rb_sigaltstack_size();
+ }
+ altstack = malloc(rb_sigaltstack_size_value);
+ if (!altstack) rb_memerror();
+ return altstack;
+}
+
/* alternate stack for SIGSEGV */
-void
-rb_register_sigaltstack(rb_thread_t *th)
+void *
+rb_register_sigaltstack(void *altstack)
{
stack_t newSS, oldSS;
- if (!th->altstack)
- rb_bug("rb_register_sigaltstack: th->altstack not initialized\n");
-
- newSS.ss_sp = th->altstack;
- newSS.ss_size = rb_sigaltstack_size();
+ newSS.ss_size = rb_sigaltstack_size_value;
+ newSS.ss_sp = altstack;
newSS.ss_flags = 0;
sigaltstack(&newSS, &oldSS); /* ignore error. */
+
+ return newSS.ss_sp;
}
#endif /* USE_SIGALTSTACK */
@@ -609,10 +608,25 @@ ruby_signal(int signum, sighandler_t handler)
#endif
switch (signum) {
-#ifdef SA_NOCLDWAIT
- case SIGCHLD:
- if (handler == SIG_IGN)
- sigact.sa_flags |= SA_NOCLDWAIT;
+#if RUBY_SIGCHLD
+ case RUBY_SIGCHLD:
+ if (handler == SIG_IGN) {
+ ruby_nocldwait = 1;
+# ifdef USE_SIGALTSTACK
+ if (sigact.sa_flags & SA_SIGINFO) {
+ sigact.sa_sigaction = (ruby_sigaction_t*)sighandler;
+ }
+ else {
+ sigact.sa_handler = sighandler;
+ }
+# else
+ sigact.sa_handler = handler;
+ sigact.sa_flags = 0;
+# endif
+ }
+ else {
+ ruby_nocldwait = 0;
+ }
break;
#endif
#if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK)
@@ -693,13 +707,35 @@ signal_enque(int sig)
ATOMIC_INC(signal_buff.size);
}
-static RETSIGTYPE
+#if RUBY_SIGCHLD
+static rb_atomic_t sigchld_hit;
+/* destructive getter than simple predicate */
+# define GET_SIGCHLD_HIT() ATOMIC_EXCHANGE(sigchld_hit, 0)
+#else
+# define GET_SIGCHLD_HIT() 0
+#endif
+
+static void
sighandler(int sig)
{
int old_errnum = errno;
- signal_enque(sig);
- rb_thread_wakeup_timer_thread();
+ /* the VM always needs to handle SIGCHLD for rb_waitpid */
+ if (sig == RUBY_SIGCHLD) {
+#if RUBY_SIGCHLD
+ rb_vm_t *vm = GET_VM();
+ ATOMIC_EXCHANGE(sigchld_hit, 1);
+
+ /* avoid spurious wakeup in main thread iff nobody uses trap(:CHLD) */
+ if (vm && ACCESS_ONCE(VALUE, vm->trap_list.cmd[sig])) {
+ signal_enque(sig);
+ }
+#endif
+ }
+ else {
+ signal_enque(sig);
+ }
+ rb_thread_wakeup_timer_thread(sig);
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
ruby_signal(sig, sighandler);
#endif
@@ -713,10 +749,6 @@ rb_signal_buff_size(void)
return signal_buff.size;
}
-#if HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
static void
rb_disable_interrupt(void)
{
@@ -763,7 +795,7 @@ static const char *received_signal;
#endif
#if defined(USE_SIGALTSTACK) || defined(_WIN32)
-NORETURN(void rb_threadptr_stack_overflow(rb_thread_t *th, int crit));
+NORETURN(void rb_ec_stack_overflow(rb_execution_context_t *ec, int crit));
# if defined __HAIKU__
# define USE_UCONTEXT_REG 1
# elif !(defined(HAVE_UCONTEXT_H) && (defined __i386__ || defined __x86_64__ || defined __amd64__))
@@ -809,12 +841,17 @@ check_stack_overflow(int sig, const uintptr_t addr, const ucontext_t *ctx)
const greg_t bp = mctx->gregs[REG_EBP];
# endif
# elif defined __APPLE__
+# if __DARWIN_UNIX03
+# define MCTX_SS_REG(reg) __ss.__##reg
+# else
+# define MCTX_SS_REG(reg) ss.reg
+# endif
# if defined(__LP64__)
- const uintptr_t sp = mctx->__ss.__rsp;
- const uintptr_t bp = mctx->__ss.__rbp;
+ const uintptr_t sp = mctx->MCTX_SS_REG(rsp);
+ const uintptr_t bp = mctx->MCTX_SS_REG(rbp);
# else
- const uintptr_t sp = mctx->__ss.__esp;
- const uintptr_t bp = mctx->__ss.__ebp;
+ const uintptr_t sp = mctx->MCTX_SS_REG(esp);
+ const uintptr_t bp = mctx->MCTX_SS_REG(ebp);
# endif
# elif defined __FreeBSD__
# if defined(__amd64__)
@@ -841,18 +878,18 @@ check_stack_overflow(int sig, const uintptr_t addr, const ucontext_t *ctx)
/* SP in ucontext is not decremented yet when `push` failed, so
* the fault page can be the next. */
if (sp_page == fault_page || sp_page == fault_page + 1 ||
- sp_page <= fault_page && fault_page <= bp_page) {
- rb_thread_t *th = ruby_current_thread;
+ (sp_page <= fault_page && fault_page <= bp_page)) {
+ rb_execution_context_t *ec = GET_EC();
int crit = FALSE;
- if ((uintptr_t)th->ec.tag->buf / pagesize <= fault_page + 1) {
+ if ((uintptr_t)ec->tag->buf / pagesize <= fault_page + 1) {
/* drop the last tag if it is close to the fault,
* otherwise it can cause stack overflow again at the same
* place. */
- th->ec.tag = th->ec.tag->prev;
+ ec->tag = ec->tag->prev;
crit = TRUE;
}
reset_sigmask(sig);
- rb_threadptr_stack_overflow(th, crit);
+ rb_ec_stack_overflow(ec, crit);
}
}
# else
@@ -860,10 +897,10 @@ static void
check_stack_overflow(int sig, const void *addr)
{
int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
- rb_thread_t *th = ruby_current_thread;
+ rb_thread_t *th = GET_THREAD();
if (ruby_stack_overflowed_p(th, addr)) {
reset_sigmask(sig);
- rb_threadptr_stack_overflow(th, FALSE);
+ rb_ec_stack_overflow(th->ec, FALSE);
}
}
# endif
@@ -892,7 +929,11 @@ NOINLINE(static void check_reserved_signal_(const char *name, size_t name_len));
#define check_reserved_signal(name) check_reserved_signal_(name, sizeof(name)-1)
#ifdef SIGBUS
-static RETSIGTYPE
+
+static sighandler_t default_sigbus_handler;
+NORETURN(static ruby_sigaction_t sigbus);
+
+static void
sigbus(int sig SIGINFO_ARG)
{
check_reserved_signal("BUS");
@@ -905,46 +946,57 @@ sigbus(int sig SIGINFO_ARG)
#if defined __APPLE__ || defined __linux__
CHECK_STACK_OVERFLOW();
#endif
- rb_bug_context(SIGINFO_CTX, "Bus Error" MESSAGE_FAULT_ADDRESS);
+ rb_bug_for_fatal_signal(default_sigbus_handler, sig, SIGINFO_CTX, "Bus Error" MESSAGE_FAULT_ADDRESS);
}
#endif
-static void
-ruby_abort(void)
-{
-#ifdef __sun
- /* Solaris's abort() is async signal unsafe. Of course, it is not
- * POSIX compliant.
- */
- raise(SIGABRT);
-#else
- abort();
-#endif
+#ifdef SIGSEGV
-}
+static sighandler_t default_sigsegv_handler;
+NORETURN(static ruby_sigaction_t sigsegv);
-#ifdef SIGSEGV
-static RETSIGTYPE
+static void
sigsegv(int sig SIGINFO_ARG)
{
check_reserved_signal("SEGV");
CHECK_STACK_OVERFLOW();
- rb_bug_context(SIGINFO_CTX, "Segmentation fault" MESSAGE_FAULT_ADDRESS);
+ rb_bug_for_fatal_signal(default_sigsegv_handler, sig, SIGINFO_CTX, "Segmentation fault" MESSAGE_FAULT_ADDRESS);
}
#endif
#ifdef SIGILL
-static RETSIGTYPE
+
+static sighandler_t default_sigill_handler;
+NORETURN(static ruby_sigaction_t sigill);
+
+static void
sigill(int sig SIGINFO_ARG)
{
check_reserved_signal("ILL");
#if defined __APPLE__
CHECK_STACK_OVERFLOW();
#endif
- rb_bug_context(SIGINFO_CTX, "Illegal instruction" MESSAGE_FAULT_ADDRESS);
+ rb_bug_for_fatal_signal(default_sigill_handler, sig, SIGINFO_CTX, "Illegal instruction" MESSAGE_FAULT_ADDRESS);
}
#endif
+#ifndef __sun
+NORETURN(static void ruby_abort(void));
+#endif
+
+static void
+ruby_abort(void)
+{
+#ifdef __sun
+ /* Solaris's abort() is async signal unsafe. Of course, it is not
+ * POSIX compliant.
+ */
+ raise(SIGABRT);
+#else
+ abort();
+#endif
+}
+
static void
check_reserved_signal_(const char *name, size_t name_len)
{
@@ -982,17 +1034,17 @@ check_reserved_signal_(const char *name, size_t name_len)
#endif
#if defined SIGPIPE || defined SIGSYS
-static RETSIGTYPE
+static void
sig_do_nothing(int sig)
{
}
#endif
-static void
-signal_exec(VALUE cmd, int safe, int sig)
+static int
+signal_exec(VALUE cmd, int sig)
{
- rb_thread_t *cur_th = GET_THREAD();
- volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
+ rb_execution_context_t *ec = GET_EC();
+ volatile rb_atomic_t old_interrupt_mask = ec->interrupt_mask;
enum ruby_tag_type state;
/*
@@ -1002,42 +1054,52 @@ signal_exec(VALUE cmd, int safe, int sig)
* 3. rb_signal_exec runs on queued signal
*/
if (IMMEDIATE_P(cmd))
- return;
+ return FALSE;
- cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK;
- TH_PUSH_TAG(cur_th);
- if ((state = EXEC_TAG()) == TAG_NONE) {
+ ec->interrupt_mask |= TRAP_INTERRUPT_MASK;
+ EC_PUSH_TAG(ec);
+ if ((state = EC_EXEC_TAG()) == TAG_NONE) {
VALUE signum = INT2NUM(sig);
- rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
+ rb_eval_cmd_kw(cmd, rb_ary_new3(1, signum), RB_NO_KEYWORDS);
}
- TH_POP_TAG();
- cur_th = GET_THREAD();
- cur_th->interrupt_mask = old_interrupt_mask;
+ EC_POP_TAG();
+ ec = GET_EC();
+ ec->interrupt_mask = old_interrupt_mask;
if (state) {
/* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
- TH_JUMP_TAG(cur_th, state);
+ EC_JUMP_TAG(ec, state);
}
+ return TRUE;
}
void
-rb_trap_exit(void)
+rb_vm_trap_exit(rb_vm_t *vm)
{
- rb_vm_t *vm = GET_VM();
VALUE trap_exit = vm->trap_list.cmd[0];
if (trap_exit) {
vm->trap_list.cmd[0] = 0;
- signal_exec(trap_exit, vm->trap_list.safe[0], 0);
+ signal_exec(trap_exit, 0);
}
}
+void ruby_waitpid_all(rb_vm_t *); /* process.c */
+
void
+ruby_sigchld_handler(rb_vm_t *vm)
+{
+ if (SIGCHLD_LOSSY || GET_SIGCHLD_HIT()) {
+ ruby_waitpid_all(vm);
+ }
+}
+
+/* returns true if a trap handler was run, false otherwise */
+int
rb_signal_exec(rb_thread_t *th, int sig)
{
rb_vm_t *vm = GET_VM();
VALUE cmd = vm->trap_list.cmd[sig];
- int safe = vm->trap_list.safe[sig];
if (cmd == 0) {
switch (sig) {
@@ -1070,8 +1132,9 @@ rb_signal_exec(rb_thread_t *th, int sig)
rb_threadptr_signal_exit(th);
}
else {
- signal_exec(cmd, safe, sig);
+ return signal_exec(cmd, sig);
}
+ return FALSE;
}
static sighandler_t
@@ -1098,6 +1161,9 @@ default_handler(int sig)
#ifdef SIGUSR2
case SIGUSR2:
#endif
+#if RUBY_SIGCHLD
+ case RUBY_SIGCHLD:
+#endif
func = sighandler;
break;
#ifdef SIGBUS
@@ -1146,29 +1212,36 @@ trap_handler(VALUE *cmd, int sig)
if (!NIL_P(command)) {
const char *cptr;
long len;
- SafeStringValue(command); /* taint check */
+ StringValue(command);
*cmd = command;
RSTRING_GETMEM(command, cptr, len);
switch (len) {
+ sig_ign:
+ func = SIG_IGN;
+ *cmd = Qtrue;
+ break;
+ sig_dfl:
+ func = default_handler(sig);
+ *cmd = 0;
+ break;
case 0:
goto sig_ign;
break;
case 14:
if (memcmp(cptr, "SYSTEM_DEFAULT", 14) == 0) {
+ if (sig == RUBY_SIGCHLD) {
+ goto sig_dfl;
+ }
func = SIG_DFL;
*cmd = 0;
}
break;
case 7:
if (memcmp(cptr, "SIG_IGN", 7) == 0) {
-sig_ign:
- func = SIG_IGN;
- *cmd = Qtrue;
+ goto sig_ign;
}
else if (memcmp(cptr, "SIG_DFL", 7) == 0) {
-sig_dfl:
- func = default_handler(sig);
- *cmd = 0;
+ goto sig_dfl;
}
else if (memcmp(cptr, "DEFAULT", 7) == 0) {
goto sig_dfl;
@@ -1200,33 +1273,15 @@ static int
trap_signm(VALUE vsig)
{
int sig = -1;
- const char *s;
- switch (TYPE(vsig)) {
- case T_FIXNUM:
+ if (FIXNUM_P(vsig)) {
sig = FIX2INT(vsig);
if (sig < 0 || sig >= NSIG) {
rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
}
- break;
-
- case T_SYMBOL:
- vsig = rb_sym2str(vsig);
- s = RSTRING_PTR(vsig);
- goto str_signal;
-
- default:
- s = StringValuePtr(vsig);
-
- str_signal:
- if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0)
- s += 3;
- sig = signm2signo(s);
- if (sig == 0 && strcmp(s, "EXIT") != 0) {
- long ofs = s - RSTRING_PTR(vsig);
- if (ofs) vsig = rb_str_subseq(vsig, ofs, RSTRING_LEN(vsig)-ofs);
- rb_raise(rb_eArgError, "unsupported signal SIG%"PRIsVALUE"", vsig);
- }
+ }
+ else {
+ sig = signm2signo(&vsig, FALSE, TRUE, NULL);
}
return sig;
}
@@ -1266,8 +1321,7 @@ trap(int sig, sighandler_t func, VALUE command)
break;
}
- vm->trap_list.cmd[sig] = command;
- vm->trap_list.safe[sig] = rb_safe_level();
+ ACCESS_ONCE(VALUE, vm->trap_list.cmd[sig]) = command;
return oldcmd;
}
@@ -1334,7 +1388,7 @@ reserved_signal_p(int signo)
* Terminating: 27460
*/
static VALUE
-sig_trap(int argc, VALUE *argv)
+sig_trap(int argc, VALUE *argv, VALUE _)
{
int sig;
sighandler_t func;
@@ -1360,8 +1414,9 @@ sig_trap(int argc, VALUE *argv)
func = trap_handler(&cmd, sig);
}
- if (OBJ_TAINTED(cmd)) {
- rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
+ if (rb_obj_is_proc(cmd) &&
+ !rb_ractor_main_p() && !rb_ractor_shareable_p(cmd)) {
+ cmd = rb_proc_isolate(cmd);
}
return trap(sig, func, cmd);
@@ -1377,12 +1432,12 @@ sig_trap(int argc, VALUE *argv)
* Signal.list #=> {"EXIT"=>0, "HUP"=>1, "INT"=>2, "QUIT"=>3, "ILL"=>4, "TRAP"=>5, "IOT"=>6, "ABRT"=>6, "FPE"=>8, "KILL"=>9, "BUS"=>7, "SEGV"=>11, "SYS"=>31, "PIPE"=>13, "ALRM"=>14, "TERM"=>15, "URG"=>23, "STOP"=>19, "TSTP"=>20, "CONT"=>18, "CHLD"=>17, "CLD"=>17, "TTIN"=>21, "TTOU"=>22, "IO"=>29, "XCPU"=>24, "XFSZ"=>25, "VTALRM"=>26, "PROF"=>27, "WINCH"=>28, "USR1"=>10, "USR2"=>12, "PWR"=>30, "POLL"=>29}
*/
static VALUE
-sig_list(void)
+sig_list(VALUE _)
{
VALUE h = rb_hash_new();
const struct signals *sigs;
- for (sigs = siglist; sigs->signm; sigs++) {
+ FOREACH_SIGNAL(sigs, 0) {
rb_hash_aset(h, rb_fstring_cstr(sigs->signm), INT2FIX(sigs->signo));
}
return h;
@@ -1395,43 +1450,46 @@ sig_list(void)
perror(failed); \
} while (0)
static int
-install_sighandler(int signum, sighandler_t handler)
+install_sighandler_core(int signum, sighandler_t handler, sighandler_t *old_handler)
{
sighandler_t old;
old = ruby_signal(signum, handler);
if (old == SIG_ERR) return -1;
- /* signal handler should be inherited during exec. */
- if (old != SIG_DFL) {
- ruby_signal(signum, old);
+ if (old_handler) {
+ *old_handler = (old == SIG_DFL || old == SIG_IGN) ? 0 : old;
+ }
+ else {
+ /* signal handler should be inherited during exec. */
+ if (old != SIG_DFL) {
+ ruby_signal(signum, old);
+ }
}
return 0;
}
-#ifndef __native_client__
+
# define install_sighandler(signum, handler) \
- INSTALL_SIGHANDLER(install_sighandler(signum, handler), #signum, signum)
-#endif
+ INSTALL_SIGHANDLER(install_sighandler_core(signum, handler, NULL), #signum, signum)
+# define force_install_sighandler(signum, handler, old_handler) \
+ INSTALL_SIGHANDLER(install_sighandler_core(signum, handler, old_handler), #signum, signum)
-#if defined(SIGCLD) || defined(SIGCHLD)
+#if RUBY_SIGCHLD
static int
init_sigchld(int sig)
{
sighandler_t oldfunc;
+ sighandler_t func = sighandler;
oldfunc = ruby_signal(sig, SIG_DFL);
if (oldfunc == SIG_ERR) return -1;
- if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
- ruby_signal(sig, oldfunc);
- }
- else {
- GET_VM()->trap_list.cmd[sig] = 0;
- }
+ ruby_signal(sig, func);
+ ACCESS_ONCE(VALUE, GET_VM()->trap_list.cmd[sig]) = 0;
+
return 0;
}
-# ifndef __native_client__
+
# define init_sigchld(signum) \
INSTALL_SIGHANDLER(init_sigchld(signum), #signum, signum)
-# endif
#endif
void
@@ -1525,16 +1583,14 @@ Init_signal(void)
if (!ruby_enable_coredump) {
#ifdef SIGBUS
- install_sighandler(SIGBUS, (sighandler_t)sigbus);
+ force_install_sighandler(SIGBUS, (sighandler_t)sigbus, &default_sigbus_handler);
#endif
#ifdef SIGILL
- install_sighandler(SIGILL, (sighandler_t)sigill);
+ force_install_sighandler(SIGILL, (sighandler_t)sigill, &default_sigill_handler);
#endif
#ifdef SIGSEGV
-# ifdef USE_SIGALTSTACK
- rb_register_sigaltstack(GET_THREAD());
-# endif
- install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
+ RB_ALTSTACK_INIT(GET_VM()->main_altstack, rb_allocate_sigaltstack());
+ force_install_sighandler(SIGSEGV, (sighandler_t)sigsegv, &default_sigsegv_handler);
#endif
}
#ifdef SIGPIPE
@@ -1544,11 +1600,55 @@ Init_signal(void)
install_sighandler(SIGSYS, sig_do_nothing);
#endif
-#if defined(SIGCLD)
- init_sigchld(SIGCLD);
-#elif defined(SIGCHLD)
- init_sigchld(SIGCHLD);
+#if RUBY_SIGCHLD
+ init_sigchld(RUBY_SIGCHLD);
#endif
rb_enable_interrupt();
}
+
+#if defined(HAVE_GRANTPT)
+extern int grantpt(int);
+#else
+static int
+fake_grantfd(int masterfd)
+{
+ errno = ENOSYS;
+ return -1;
+}
+#define grantpt(fd) fake_grantfd(fd)
+#endif
+
+int
+rb_grantpt(int masterfd)
+{
+ if (RUBY_SIGCHLD) {
+ rb_vm_t *vm = GET_VM();
+ int ret, e;
+
+ /*
+ * Prevent waitpid calls from Ruby by taking waitpid_lock.
+ * Pedantically, grantpt(3) is undefined if a non-default
+ * SIGCHLD handler is defined, but preventing conflicting
+ * waitpid calls ought to be sufficient.
+ *
+ * We could install the default sighandler temporarily, but that
+ * could cause SIGCHLD to be missed by other threads. Blocking
+ * SIGCHLD won't work here, either, unless we stop and restart
+ * timer-thread (as only timer-thread sees SIGCHLD), but that
+ * seems like overkill.
+ */
+ rb_nativethread_lock_lock(&vm->waitpid_lock);
+ {
+ ret = grantpt(masterfd); /* may spawn `pt_chown' and wait on it */
+ if (ret < 0) e = errno;
+ }
+ rb_nativethread_lock_unlock(&vm->waitpid_lock);
+
+ if (ret < 0) errno = e;
+ return ret;
+ }
+ else {
+ return grantpt(masterfd);
+ }
+}
diff --git a/siphash.c b/siphash.c
index 153d2c690a..ddf8ee245d 100644
--- a/siphash.c
+++ b/siphash.c
@@ -30,7 +30,7 @@
#ifndef UNALIGNED_WORD_ACCESS
# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
- defined(__powerpc64__) || \
+ defined(__powerpc64__) || defined(__aarch64__) || \
defined(__mc68020__)
# define UNALIGNED_WORD_ACCESS 1
# endif
diff --git a/siphash.h b/siphash.h
index 2e7553f208..f49bc511b1 100644
--- a/siphash.h
+++ b/siphash.h
@@ -43,6 +43,6 @@ int sip_hash_digest_integer(sip_hash *h, const uint8_t *data, size_t data_len, u
void sip_hash_free(sip_hash *h);
void sip_hash_dump(sip_hash *h);
-uint64_t sip_hash13(const uint8_t key[16], const uint8_t *data, size_t len);
+NO_SANITIZE("unsigned-integer-overflow", uint64_t sip_hash13(const uint8_t key[16], const uint8_t *data, size_t len));
#endif
diff --git a/spec/README.md b/spec/README.md
index 830279afc8..c67aedbb80 100644
--- a/spec/README.md
+++ b/spec/README.md
@@ -30,7 +30,47 @@ In other words: If adding a spec might reveal a bug in
another implementation, then it is worth adding it.
Currently, the only module which is MRI-specific is `RubyVM`.
-## Runing ruby/spec
+## Changing behavior and versions guards
+
+Version guards (`ruby_version_is`) must be added for new features or features
+which change behavior or are removed. This is necessary for other Ruby implementations
+to still be able to run the specs and contribute new specs.
+
+For example, change:
+```ruby
+describe "Some spec" do
+ it "some example" do
+ # Old behavior for Ruby < 2.7
+ end
+end
+```
+to:
+```ruby
+describe "Some spec" do
+ ruby_version_is ""..."2.7" do
+ it "some example" do
+ # Old behavior for Ruby < 2.7
+ end
+ end
+
+ ruby_version_is "2.7" do
+ it "some example" do
+ # New behavior for Ruby >= 2.7
+ end
+ end
+end
+```
+
+See `spec/ruby/CONTRIBUTING.md` for more documentation about guards.
+
+To verify specs are compatible with older Ruby versions:
+```
+cd spec/ruby
+$RUBY_MANAGER use 2.4.9
+../mspec/bin/mspec -j
+```
+
+## Running ruby/spec
To run all specs:
```bash
@@ -63,8 +103,8 @@ spec/mspec/bin/mspec spec/ruby/language/for_spec.rb
## ruby/spec and test/
-The main difference between a "spec" under spec/ruby and
-a test under test/ is that specs are documenting what they test.
+The main difference between a "spec" under `spec/ruby/` and
+a test under `test/` is that specs are documenting what they test.
This is extremely valuable when reading these tests, as it
helps to quickly understand what specific behavior is tested,
and how a method should behave. Basic English is fine for spec descriptions.
@@ -87,4 +127,4 @@ describe "The for expression" do
end
```
-For more details, see spec/ruby/CONTRIBUTING.md.
+For more details, see `spec/ruby/CONTRIBUTING.md`.
diff --git a/spec/bundler/bundler/build_metadata_spec.rb b/spec/bundler/bundler/build_metadata_spec.rb
new file mode 100644
index 0000000000..afa2d1716f
--- /dev/null
+++ b/spec/bundler/bundler/build_metadata_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require "bundler"
+require "bundler/build_metadata"
+
+RSpec.describe Bundler::BuildMetadata do
+ before do
+ allow(Time).to receive(:now).and_return(Time.at(0))
+ Bundler::BuildMetadata.instance_variable_set(:@built_at, nil)
+ end
+
+ describe "#built_at" do
+ it "returns %Y-%m-%d formatted time" do
+ expect(Bundler::BuildMetadata.built_at).to eq "1970-01-01"
+ end
+ end
+
+ describe "#release?" do
+ it "returns false as default" do
+ expect(Bundler::BuildMetadata.release?).to be_falsey
+ end
+ end
+
+ describe "#git_commit_sha" do
+ context "if instance valuable is defined" do
+ before do
+ Bundler::BuildMetadata.instance_variable_set(:@git_commit_sha, "foo")
+ end
+
+ after do
+ Bundler::BuildMetadata.remove_instance_variable(:@git_commit_sha)
+ end
+
+ it "returns set value" do
+ expect(Bundler::BuildMetadata.git_commit_sha).to eq "foo"
+ end
+ end
+ end
+
+ describe "#to_h" do
+ subject { Bundler::BuildMetadata.to_h }
+
+ it "returns a hash includes Built At, Git SHA and Released Version" do
+ expect(subject["Built At"]).to eq "1970-01-01"
+ expect(subject["Git SHA"]).to be_instance_of(String)
+ expect(subject["Released Version"]).to be_falsey
+ end
+ end
+end
diff --git a/spec/bundler/bundler/bundler_spec.rb b/spec/bundler/bundler/bundler_spec.rb
index 268c0d99ac..b8191fe20f 100644
--- a/spec/bundler/bundler/bundler_spec.rb
+++ b/spec/bundler/bundler/bundler_spec.rb
@@ -1,7 +1,7 @@
-# encoding: utf-8
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler"
+require "tmpdir"
RSpec.describe Bundler do
describe "#load_gemspec_uncached" do
@@ -102,11 +102,37 @@ RSpec.describe Bundler do
subject
end
end
+
+ context "with gemspec containing local variables" do
+ before do
+ File.open(app_gemspec_path, "wb") do |f|
+ f.write strip_whitespace(<<-GEMSPEC)
+ must_not_leak = true
+ Gem::Specification.new do |gem|
+ gem.name = "leak check"
+ end
+ GEMSPEC
+ end
+ end
+
+ it "should not pollute the TOPLEVEL_BINDING" do
+ subject
+ expect(TOPLEVEL_BINDING.eval("local_variables")).to_not include(:must_not_leak)
+ end
+ end
end
describe "#which" do
let(:executable) { "executable" }
- let(:path) { %w(/a /b c ../d /e) }
+
+ let(:path) do
+ if Gem.win_platform?
+ %w[C:/a C:/b C:/c C:/../d C:/e]
+ else
+ %w[/a /b c ../d /e]
+ end
+ end
+
let(:expected) { "executable" }
before do
@@ -131,7 +157,13 @@ RSpec.describe Bundler do
it_behaves_like "it returns the correct executable"
context "when the executable in inside a quoted path" do
- let(:expected) { "/e/executable" }
+ let(:expected) do
+ if Gem.win_platform?
+ "C:/e/executable"
+ else
+ "/e/executable"
+ end
+ end
it_behaves_like "it returns the correct executable"
end
@@ -144,11 +176,9 @@ RSpec.describe Bundler do
describe "configuration" do
context "disable_shared_gems" do
it "should unset GEM_PATH with empty string" do
- env = {}
- settings = { :disable_shared_gems => true }
- Bundler.send(:configure_gem_path, env, settings)
- expect(env.keys).to include("GEM_PATH")
- expect(env["GEM_PATH"]).to eq ""
+ expect(Bundler).to receive(:use_system_gems?).and_return(false)
+ Bundler.send(:configure_gem_path)
+ expect(ENV["GEM_PATH"]).to eq ""
end
end
end
@@ -158,12 +188,12 @@ RSpec.describe Bundler do
let(:bundler_ui) { Bundler.ui }
it "should raise a friendly error" do
allow(File).to receive(:exist?).and_return(true)
- allow(FileUtils).to receive(:remove_entry_secure).and_raise(ArgumentError)
+ allow(::Bundler::FileUtils).to receive(:remove_entry_secure).and_raise(ArgumentError)
allow(File).to receive(:world_writable?).and_return(true)
message = <<EOF
It is a security vulnerability to allow your home directory to be world-writable, and bundler can not continue.
You should probably consider fixing this issue by running `chmod o-w ~` on *nix.
-Please refer to http://ruby-doc.org/stdlib-2.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
+Please refer to https://ruby-doc.org/stdlib-2.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
EOF
expect(bundler_ui).to receive(:warn).with(message)
expect { Bundler.send(:rm_rf, bundled_app) }.to raise_error(Bundler::PathError)
@@ -171,6 +201,36 @@ EOF
end
end
+ describe "#mkdir_p" do
+ it "creates a folder at the given path" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ allow(Bundler).to receive(:root).and_return(bundled_app)
+
+ Bundler.mkdir_p(bundled_app.join("foo", "bar"))
+ expect(bundled_app.join("foo", "bar")).to exist
+ end
+
+ context "when mkdir_p requires sudo" do
+ it "creates a new folder using sudo" do
+ expect(Bundler).to receive(:requires_sudo?).and_return(true)
+ expect(Bundler).to receive(:sudo).and_return true
+ Bundler.mkdir_p(bundled_app.join("foo"))
+ end
+ end
+
+ context "with :no_sudo option" do
+ it "forces mkdir_p to not use sudo" do
+ expect(Bundler).to receive(:requires_sudo?).and_return(true)
+ expect(Bundler).to_not receive(:sudo)
+ Bundler.mkdir_p(bundled_app.join("foo"), :no_sudo => true)
+ end
+ end
+ end
+
describe "#user_home" do
context "home directory is set" do
it "should return the user home" do
@@ -180,33 +240,226 @@ EOF
allow(File).to receive(:writable?).with(path).and_return true
expect(Bundler.user_home).to eq(Pathname(path))
end
+
+ context "is not a directory" do
+ it "should issue a warning and return a temporary user home" do
+ path = "/home/oggy"
+ allow(Bundler.rubygems).to receive(:user_home).and_return(path)
+ allow(File).to receive(:directory?).with(path).and_return false
+ allow(Bundler).to receive(:tmp).and_return(Pathname.new("/tmp/trulyrandom"))
+ expect(Bundler.ui).to receive(:warn).with("`/home/oggy` is not a directory.\n")
+ expect(Bundler.ui).to receive(:warn).with("Bundler will use `/tmp/trulyrandom' as your home directory temporarily.\n")
+ expect(Bundler.user_home).to eq(Pathname("/tmp/trulyrandom"))
+ end
+ end
+
+ context "is not writable" do
+ let(:path) { "/home/oggy" }
+ let(:dotbundle) { "/home/oggy/.bundle" }
+
+ it "should issue a warning and return a temporary user home" do
+ allow(Bundler.rubygems).to receive(:user_home).and_return(path)
+ allow(File).to receive(:directory?).with(path).and_return true
+ allow(File).to receive(:writable?).with(path).and_return false
+ allow(File).to receive(:directory?).with(dotbundle).and_return false
+ allow(Bundler).to receive(:tmp).and_return(Pathname.new("/tmp/trulyrandom"))
+ expect(Bundler.ui).to receive(:warn).with("`/home/oggy` is not writable.\n")
+ expect(Bundler.ui).to receive(:warn).with("Bundler will use `/tmp/trulyrandom' as your home directory temporarily.\n")
+ expect(Bundler.user_home).to eq(Pathname("/tmp/trulyrandom"))
+ end
+
+ context ".bundle exists and have correct permissions" do
+ it "should return the user home" do
+ allow(Bundler.rubygems).to receive(:user_home).and_return(path)
+ allow(File).to receive(:directory?).with(path).and_return true
+ allow(File).to receive(:writable?).with(path).and_return false
+ allow(File).to receive(:directory?).with(dotbundle).and_return true
+ allow(File).to receive(:writable?).with(dotbundle).and_return true
+ expect(Bundler.user_home).to eq(Pathname(path))
+ end
+ end
+ end
end
context "home directory is not set" do
it "should issue warning and return a temporary user home" do
allow(Bundler.rubygems).to receive(:user_home).and_return(nil)
- allow(Etc).to receive(:getlogin).and_return("USER")
- allow(Dir).to receive(:tmpdir).and_return("/TMP")
- allow(FileTest).to receive(:exist?).with("/TMP/bundler/home").and_return(true)
- expect(FileUtils).to receive(:mkpath).with("/TMP/bundler/home/USER")
- message = <<EOF
-Your home directory is not set.
-Bundler will use `/TMP/bundler/home/USER' as your home directory temporarily.
-EOF
- expect(Bundler.ui).to receive(:warn).with(message)
- expect(Bundler.user_home).to eq(Pathname("/TMP/bundler/home/USER"))
+ allow(Bundler).to receive(:tmp).and_return(Pathname.new("/tmp/trulyrandom"))
+ expect(Bundler.ui).to receive(:warn).with("Your home directory is not set.\n")
+ expect(Bundler.ui).to receive(:warn).with("Bundler will use `/tmp/trulyrandom' as your home directory temporarily.\n")
+ expect(Bundler.user_home).to eq(Pathname("/tmp/trulyrandom"))
+ end
+ end
+ end
+
+ describe "#requires_sudo?" do
+ let!(:tmpdir) { Dir.mktmpdir }
+ let(:bundle_path) { Pathname("#{tmpdir}/bundle") }
+
+ def clear_cached_requires_sudo
+ return unless Bundler.instance_variable_defined?(:@requires_sudo_ran)
+ Bundler.remove_instance_variable(:@requires_sudo_ran)
+ Bundler.remove_instance_variable(:@requires_sudo)
+ end
+
+ before do
+ clear_cached_requires_sudo
+ allow(Bundler).to receive(:which).with("sudo").and_return("/usr/bin/sudo")
+ allow(Bundler).to receive(:bundle_path).and_return(bundle_path)
+ end
+
+ after do
+ FileUtils.rm_rf(tmpdir)
+ clear_cached_requires_sudo
+ end
+
+ subject { Bundler.requires_sudo? }
+
+ context "bundle_path doesn't exist" do
+ it { should be false }
+
+ context "and parent dir can't be written" do
+ before do
+ FileUtils.chmod(0o500, tmpdir)
+ end
+
+ it { should be true }
+ end
+
+ context "with unwritable files in a parent dir" do
+ # Regression test for https://github.com/rubygems/bundler/pull/6316
+ # It doesn't matter if there are other unwritable files so long as
+ # bundle_path can be created
+ before do
+ file = File.join(tmpdir, "unrelated_file")
+ FileUtils.touch(file)
+ FileUtils.chmod(0o400, file)
+ end
+
+ it { should be false }
+ end
+ end
+
+ context "bundle_path exists" do
+ before do
+ FileUtils.mkdir_p(bundle_path)
+ end
+
+ it { should be false }
+
+ context "and is unwritable" do
+ before do
+ FileUtils.chmod(0o500, bundle_path)
+ end
+
+ it { should be true }
+ end
+ end
+
+ context "path writability" do
+ before do
+ FileUtils.mkdir_p("tmp/vendor/bundle")
+ FileUtils.mkdir_p("tmp/vendor/bin_dir")
+ end
+ after do
+ FileUtils.rm_rf("tmp/vendor/bundle")
+ FileUtils.rm_rf("tmp/vendor/bin_dir")
+ end
+ context "writable paths" do
+ it "should return false and display nothing" do
+ allow(Bundler).to receive(:bundle_path).and_return(Pathname("tmp/vendor/bundle"))
+ expect(Bundler.ui).to_not receive(:warn)
+ expect(Bundler.requires_sudo?).to eq(false)
+ end
+ end
+ context "unwritable paths" do
+ before do
+ FileUtils.touch("tmp/vendor/bundle/unwritable1.txt")
+ FileUtils.touch("tmp/vendor/bundle/unwritable2.txt")
+ FileUtils.touch("tmp/vendor/bin_dir/unwritable3.txt")
+ FileUtils.chmod(0o400, "tmp/vendor/bundle/unwritable1.txt")
+ FileUtils.chmod(0o400, "tmp/vendor/bundle/unwritable2.txt")
+ FileUtils.chmod(0o400, "tmp/vendor/bin_dir/unwritable3.txt")
+ end
+ it "should return true and display warn message" do
+ allow(Bundler).to receive(:bundle_path).and_return(Pathname("tmp/vendor/bundle"))
+ bin_dir = Pathname("tmp/vendor/bin_dir/")
+
+ # allow File#writable? to be called with args other than the stubbed on below
+ allow(File).to receive(:writable?).and_call_original
+
+ # fake make the directory unwritable
+ allow(File).to receive(:writable?).with(bin_dir).and_return(false)
+ allow(Bundler).to receive(:system_bindir).and_return(Pathname("tmp/vendor/bin_dir/"))
+ message = <<-MESSAGE.chomp
+Following files may not be writable, so sudo is needed:
+ tmp/vendor/bin_dir/
+ tmp/vendor/bundle/unwritable1.txt
+ tmp/vendor/bundle/unwritable2.txt
+MESSAGE
+ expect(Bundler.ui).to receive(:warn).with(message)
+ expect(Bundler.requires_sudo?).to eq(true)
+ end
end
end
end
- describe "#tmp_home_path" do
- it "should create temporary user home" do
- allow(Dir).to receive(:tmpdir).and_return("/TMP")
- allow(FileTest).to receive(:exist?).with("/TMP/bundler/home").and_return(false)
- expect(FileUtils).to receive(:mkpath).once.ordered.with("/TMP/bundler/home")
- expect(FileUtils).to receive(:mkpath).once.ordered.with("/TMP/bundler/home/USER")
- expect(File).to receive(:chmod).with(0o777, "/TMP/bundler/home")
- expect(Bundler.tmp_home_path("USER", "")).to eq(Pathname("/TMP/bundler/home/USER"))
+ context "user cache dir" do
+ let(:home_path) { Pathname.new(ENV["HOME"]) }
+
+ let(:xdg_data_home) { home_path.join(".local") }
+ let(:xdg_cache_home) { home_path.join(".cache") }
+ let(:xdg_config_home) { home_path.join(".config") }
+
+ let(:bundle_user_home_default) { home_path.join(".bundle") }
+ let(:bundle_user_home_custom) { xdg_data_home.join("bundle") }
+
+ let(:bundle_user_cache_default) { bundle_user_home_default.join("cache") }
+ let(:bundle_user_cache_custom) { xdg_cache_home.join("bundle") }
+
+ let(:bundle_user_config_default) { bundle_user_home_default.join("config") }
+ let(:bundle_user_config_custom) { xdg_config_home.join("bundle") }
+
+ let(:bundle_user_plugin_default) { bundle_user_home_default.join("plugin") }
+ let(:bundle_user_plugin_custom) { xdg_data_home.join("bundle").join("plugin") }
+
+ describe "#user_bundle_path" do
+ before do
+ allow(Bundler.rubygems).to receive(:user_home).and_return(home_path)
+ end
+
+ it "should use the default home path" do
+ expect(Bundler.user_bundle_path).to eq(bundle_user_home_default)
+ expect(Bundler.user_bundle_path("home")).to eq(bundle_user_home_default)
+ expect(Bundler.user_bundle_path("cache")).to eq(bundle_user_cache_default)
+ expect(Bundler.user_cache).to eq(bundle_user_cache_default)
+ expect(Bundler.user_bundle_path("config")).to eq(bundle_user_config_default)
+ expect(Bundler.user_bundle_path("plugin")).to eq(bundle_user_plugin_default)
+ end
+
+ it "should use custom home path as root for other paths" do
+ ENV["BUNDLE_USER_HOME"] = bundle_user_home_custom.to_s
+ allow(Bundler.rubygems).to receive(:user_home).and_raise
+ expect(Bundler.user_bundle_path).to eq(bundle_user_home_custom)
+ expect(Bundler.user_bundle_path("home")).to eq(bundle_user_home_custom)
+ expect(Bundler.user_bundle_path("cache")).to eq(bundle_user_home_custom.join("cache"))
+ expect(Bundler.user_cache).to eq(bundle_user_home_custom.join("cache"))
+ expect(Bundler.user_bundle_path("config")).to eq(bundle_user_home_custom.join("config"))
+ expect(Bundler.user_bundle_path("plugin")).to eq(bundle_user_home_custom.join("plugin"))
+ end
+
+ it "should use all custom paths, except home" do
+ ENV.delete("BUNDLE_USER_HOME")
+ ENV["BUNDLE_USER_CACHE"] = bundle_user_cache_custom.to_s
+ ENV["BUNDLE_USER_CONFIG"] = bundle_user_config_custom.to_s
+ ENV["BUNDLE_USER_PLUGIN"] = bundle_user_plugin_custom.to_s
+ expect(Bundler.user_bundle_path).to eq(bundle_user_home_default)
+ expect(Bundler.user_bundle_path("home")).to eq(bundle_user_home_default)
+ expect(Bundler.user_bundle_path("cache")).to eq(bundle_user_cache_custom)
+ expect(Bundler.user_cache).to eq(bundle_user_cache_custom)
+ expect(Bundler.user_bundle_path("config")).to eq(bundle_user_config_custom)
+ expect(Bundler.user_bundle_path("plugin")).to eq(bundle_user_plugin_custom)
+ end
end
end
end
diff --git a/spec/bundler/bundler/cli_spec.rb b/spec/bundler/bundler/cli_spec.rb
index d41e6de4a7..c5de12c211 100644
--- a/spec/bundler/bundler/cli_spec.rb
+++ b/spec/bundler/bundler/cli_spec.rb
@@ -1,21 +1,23 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/cli"
RSpec.describe "bundle executable" do
it "returns non-zero exit status when passed unrecognized options" do
- bundle "--invalid_argument"
- expect(exitstatus).to_not be_zero if exitstatus
+ bundle "--invalid_argument", :raise_on_error => false
+ expect(exitstatus).to_not be_zero
end
it "returns non-zero exit status when passed unrecognized task" do
- bundle "unrecognized-task"
- expect(exitstatus).to_not be_zero if exitstatus
+ bundle "unrecognized-task", :raise_on_error => false
+ expect(exitstatus).to_not be_zero
end
it "looks for a binary and executes it if it's named bundler-<task>" do
+ skip "Could not find command testtasks, probably because not a windows friendly executable" if Gem.win_platform?
+
File.open(tmp("bundler-testtasks"), "w", 0o755) do |f|
- ruby = ENV['BUNDLE_RUBY'] || "/usr/bin/env ruby"
+ ruby = ENV["RUBY"] || "/usr/bin/env ruby"
f.puts "#!#{ruby}\nputs 'Hello, world'\n"
end
@@ -23,64 +25,124 @@ RSpec.describe "bundle executable" do
bundle "testtasks"
end
- expect(exitstatus).to be_zero if exitstatus
expect(out).to eq("Hello, world")
end
- context "when ENV['BUNDLE_GEMFILE'] is set to an empty string" do
- it "ignores it" do
- gemfile bundled_app("Gemfile"), <<-G
- source "file://#{gem_repo1}"
- gem 'rack'
- G
+ describe "aliases" do
+ it "aliases e to exec" do
+ bundle "e --help"
- bundle :install, :env => { "BUNDLE_GEMFILE" => "" }
+ expect(out_with_macos_man_workaround).to include("bundle-exec")
+ end
- expect(the_bundle).to include_gems "rack 1.0.0"
+ it "aliases ex to exec" do
+ bundle "ex --help"
+
+ expect(out_with_macos_man_workaround).to include("bundle-exec")
+ end
+
+ it "aliases exe to exec" do
+ bundle "exe --help"
+
+ expect(out_with_macos_man_workaround).to include("bundle-exec")
+ end
+
+ it "aliases c to check" do
+ bundle "c --help"
+
+ expect(out_with_macos_man_workaround).to include("bundle-check")
+ end
+
+ it "aliases i to install" do
+ bundle "i --help"
+
+ expect(out_with_macos_man_workaround).to include("bundle-install")
+ end
+
+ it "aliases ls to list" do
+ bundle "ls --help"
+
+ expect(out_with_macos_man_workaround).to include("bundle-list")
+ end
+
+ it "aliases package to cache" do
+ bundle "package --help"
+
+ expect(out_with_macos_man_workaround).to include("bundle-cache")
+ end
+
+ it "aliases pack to cache" do
+ bundle "pack --help"
+
+ expect(out_with_macos_man_workaround).to include("bundle-cache")
+ end
+
+ private
+
+ # Some `man` (e.g., on macOS) always highlights the output even to
+ # non-tty.
+ def out_with_macos_man_workaround
+ out.gsub(/.[\b]/, "")
+ end
+ end
+
+ context "with no arguments" do
+ it "prints a concise help message", :bundler => "3" do
+ bundle ""
+ expect(err).to be_empty
+ expect(out).to include("Bundler version #{Bundler::VERSION}").
+ and include("\n\nBundler commands:\n\n").
+ and include("\n\n Primary commands:\n").
+ and include("\n\n Utilities:\n").
+ and include("\n\nOptions:\n")
end
end
- context "when ENV['RUBYGEMS_GEMDEPS'] is set" do
- it "displays a warning" do
- gemfile bundled_app("Gemfile"), <<-G
- source "file://#{gem_repo1}"
+ context "when ENV['BUNDLE_GEMFILE'] is set to an empty string" do
+ it "ignores it" do
+ gemfile bundled_app_gemfile, <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
- bundle :install, :env => { "RUBYGEMS_GEMDEPS" => "foo" }
- expect(out).to include("RUBYGEMS_GEMDEPS")
- expect(out).to include("conflict with Bundler")
+ bundle :install, :env => { "BUNDLE_GEMFILE" => "" }
- bundle :install, :env => { "RUBYGEMS_GEMDEPS" => "" }
- expect(out).not_to include("RUBYGEMS_GEMDEPS")
+ expect(the_bundle).to include_gems "rack 1.0.0"
end
end
context "with --verbose" do
it "prints the running command" do
- gemfile ""
- bundle! "info bundler", :verbose => true
- expect(out).to start_with("Running `bundle info bundler --no-color --verbose` with bundler #{Bundler::VERSION}")
+ gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ bundle "info bundler", :verbose => true
+ expect(out).to start_with("Running `bundle info bundler --verbose` with bundler #{Bundler::VERSION}")
end
it "doesn't print defaults" do
- install_gemfile! "", :verbose => true
- expect(out).to start_with("Running `bundle install --no-color --retry 0 --verbose` with bundler #{Bundler::VERSION}")
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", :verbose => true
+ expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}")
+ end
+
+ it "doesn't print defaults" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", :verbose => true
+ expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}")
end
end
describe "printing the outdated warning" do
shared_examples_for "no warning" do
it "prints no warning" do
- bundle "fail"
- expect(err + out).to eq("Could not find command \"fail\".")
+ bundle "fail", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
+ expect(last_command.stdboth).to eq("Could not find command \"fail\".")
end
end
- let(:bundler_version) { "1.1" }
+ let(:bundler_version) { "2.0" }
let(:latest_version) { nil }
before do
- simulate_bundler_version(bundler_version)
+ bundle "config set --global disable_version_check false"
+
+ pristine_system_gems "bundler-#{bundler_version}"
if latest_version
info_path = home(".bundle/cache/compact_index/rubygems.org.443.29b0360b937aa4d161703e6160654e47/info/bundler")
info_path.parent.mkpath
@@ -103,39 +165,37 @@ RSpec.describe "bundle executable" do
end
context "when the latest version is greater than the current version" do
- let(:latest_version) { "2.0" }
+ let(:latest_version) { "222.0" }
it "prints the version warning" do
- bundle "fail"
- expect(err + out).to eq(<<-EOS.strip)
+ bundle "fail", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
+ expect(err).to start_with(<<-EOS.strip)
The latest bundler is #{latest_version}, but you are currently running #{bundler_version}.
-To update, run `gem install bundler`
-Could not find command "fail".
+To install the latest version, run `gem install bundler`
EOS
end
context "and disable_version_check is set" do
- before { bundle! "config disable_version_check true" }
+ before { bundle "config set disable_version_check true", :env => { "BUNDLER_VERSION" => bundler_version } }
include_examples "no warning"
end
context "running a parseable command" do
it "prints no warning" do
- bundle! "config --parseable foo"
- expect(out).to eq ""
+ bundle "config get --parseable foo", :env => { "BUNDLER_VERSION" => bundler_version }
+ expect(last_command.stdboth).to eq ""
- bundle "platform --ruby"
- expect(out).to eq "Could not locate Gemfile"
+ bundle "platform --ruby", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
+ expect(last_command.stdboth).to eq "Could not locate Gemfile"
end
end
context "and is a pre-release" do
- let(:latest_version) { "2.0.0.pre.4" }
+ let(:latest_version) { "222.0.0.pre.4" }
it "prints the version warning" do
- bundle "fail"
- expect(err + out).to eq(<<-EOS.strip)
+ bundle "fail", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
+ expect(err).to start_with(<<-EOS.strip)
The latest bundler is #{latest_version}, but you are currently running #{bundler_version}.
-To update, run `gem install bundler --pre`
-Could not find command "fail".
+To install the latest version, run `gem install bundler --pre`
EOS
end
end
@@ -144,8 +204,13 @@ Could not find command "fail".
end
RSpec.describe "bundler executable" do
- it "shows the bundler version just as the `bundle` executable does" do
+ it "shows the bundler version just as the `bundle` executable does", :bundler => "< 3" do
bundler "--version"
expect(out).to eq("Bundler version #{Bundler::VERSION}")
end
+
+ it "shows the bundler version just as the `bundle` executable does", :bundler => "3" do
+ bundler "--version"
+ expect(out).to eq(Bundler::VERSION)
+ end
end
diff --git a/spec/bundler/bundler/compact_index_client/updater_spec.rb b/spec/bundler/bundler/compact_index_client/updater_spec.rb
index c1cae31956..fe417e3920 100644
--- a/spec/bundler/bundler/compact_index_client/updater_spec.rb
+++ b/spec/bundler/bundler/compact_index_client/updater_spec.rb
@@ -1,30 +1,59 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "net/http"
require "bundler/compact_index_client"
require "bundler/compact_index_client/updater"
+require "tmpdir"
RSpec.describe Bundler::CompactIndexClient::Updater do
- subject(:updater) { described_class.new(fetcher) }
-
let(:fetcher) { double(:fetcher) }
+ let(:local_path) { Pathname.new Dir.mktmpdir("localpath") }
+ let(:remote_path) { double(:remote_path) }
+
+ let!(:updater) { described_class.new(fetcher) }
context "when the ETag header is missing" do
- # Regression test for https://github.com/bundler/bundler/issues/5463
+ # Regression test for https://github.com/rubygems/bundler/issues/5463
+ let(:response) { double(:response, :body => "abc123") }
+
+ it "treats the response as an update" do
+ expect(response).to receive(:[]).with("ETag") { nil }
+ expect(fetcher).to receive(:call) { response }
+
+ updater.update(local_path, remote_path)
+ end
+ end
+ context "when the download is corrupt" do
let(:response) { double(:response, :body => "") }
- let(:local_path) { Pathname("/tmp/localpath") }
- let(:remote_path) { double(:remote_path) }
- it "MisMatchedChecksumError is raised" do
- # Twice: #update retries on failure
- expect(response).to receive(:[]).with("Content-Encoding").twice { "" }
- expect(response).to receive(:[]).with("ETag").twice { nil }
- expect(fetcher).to receive(:call).twice { response }
+ it "raises HTTPError" do
+ expect(fetcher).to receive(:call).and_raise(Zlib::GzipFile::Error)
expect do
updater.update(local_path, remote_path)
- end.to raise_error(Bundler::CompactIndexClient::Updater::MisMatchedChecksumError)
+ end.to raise_error(Bundler::HTTPError)
+ end
+ end
+
+ context "when receiving non UTF-8 data and default internal encoding set to ASCII" do
+ let(:response) { double(:response, :body => "\x8B".b) }
+
+ it "works just fine" do
+ old_verbose = $VERBOSE
+ previous_internal_encoding = Encoding.default_internal
+
+ begin
+ $VERBOSE = false
+ Encoding.default_internal = "ASCII"
+ expect(response).to receive(:[]).with("ETag") { nil }
+ expect(fetcher).to receive(:call) { response }
+
+ updater.update(local_path, remote_path)
+ ensure
+ Encoding.default_internal = previous_internal_encoding
+ $VERBOSE = old_verbose
+ end
end
end
end
diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb
index 73d44a93ab..cd70d77cba 100644
--- a/spec/bundler/bundler/definition_spec.rb
+++ b/spec/bundler/bundler/definition_spec.rb
@@ -1,18 +1,19 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/definition"
RSpec.describe Bundler::Definition do
describe "#lock" do
before do
allow(Bundler).to receive(:settings) { Bundler::Settings.new(".") }
- allow(Bundler).to receive(:default_gemfile) { Pathname.new("Gemfile") }
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile) { Pathname.new("Gemfile") }
allow(Bundler).to receive(:ui) { double("UI", :info => "", :debug => "") }
end
context "when it's not possible to write to the file" do
subject { Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) }
it "raises an PermissionError with explanation" do
+ allow(File).to receive(:open).and_call_original
expect(File).to receive(:open).with("Gemfile.lock", "wb").
and_raise(Errno::EACCES)
expect { subject.lock("Gemfile.lock") }.
@@ -23,6 +24,7 @@ RSpec.describe Bundler::Definition do
subject { Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) }
it "raises a TemporaryResourceError with explanation" do
+ allow(File).to receive(:open).and_call_original
expect(File).to receive(:open).with("Gemfile.lock", "wb").
and_raise(Errno::EAGAIN)
expect { subject.lock("Gemfile.lock") }.
@@ -36,7 +38,7 @@ RSpec.describe Bundler::Definition do
build_lib "foo", "1.0", :path => lib_path("foo")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
@@ -44,10 +46,10 @@ RSpec.describe Bundler::Definition do
s.add_dependency "rack", "1.0"
end
- bundle :install, :env => { "DEBUG" => 1 }
+ bundle :install, :env => { "DEBUG" => "1" }
expect(out).to match(/re-resolving dependencies/)
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo")}
specs:
@@ -55,12 +57,12 @@ RSpec.describe Bundler::Definition do
rack (= 1.0)
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -77,14 +79,14 @@ RSpec.describe Bundler::Definition do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
- bundle :check, :env => { "DEBUG" => 1 }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo")}
specs:
@@ -92,12 +94,12 @@ RSpec.describe Bundler::Definition do
rack (= 1.0)
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -107,23 +109,50 @@ RSpec.describe Bundler::Definition do
G
end
+ it "for a locked gem for another platform" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "only_java", platform: :jruby
+ G
+
+ bundle "lock --add-platform java"
+ bundle :check, :env => { "DEBUG" => "1" }
+
+ expect(out).to match(/using resolution from the lockfile/)
+ expect(lockfile).to eq <<~G
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ only_java (1.1-java)
+
+ PLATFORMS
+ #{lockfile_platforms_for(["java"] + local_platforms)}
+
+ DEPENDENCIES
+ only_java
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
it "for a rubygems gem" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
- bundle :check, :env => { "DEBUG" => 1 }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
foo (1.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
foo
@@ -139,13 +168,15 @@ RSpec.describe Bundler::Definition do
context "with lockfile" do
before do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
it "should get a locked specs list when updating all" do
- definition = Bundler::Definition.new(bundled_app("Gemfile.lock"), [], Bundler::SourceList.new, true)
+ definition = Bundler::Definition.new(bundled_app_lock, [], Bundler::SourceList.new, true)
locked_specs = definition.gem_version_promoter.locked_specs
expect(locked_specs.to_a.map(&:name)).to eq ["foo"]
expect(definition.instance_variable_get("@locked_specs").empty?).to eq true
@@ -160,9 +191,15 @@ RSpec.describe Bundler::Definition do
end
context "eager unlock" do
+ let(:source_list) do
+ Bundler::SourceList.new.tap do |source_list|
+ source_list.add_global_rubygems_remote(file_uri_for(gem_repo4))
+ end
+ end
+
before do
gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'isolated_owner'
gem 'shared_owner_a'
@@ -171,7 +208,7 @@ RSpec.describe Bundler::Definition do
lockfile <<-L
GEM
- remote: file://#{gem_repo4}
+ remote: #{file_uri_for(gem_repo4)}
specs:
isolated_dep (2.0.1)
isolated_owner (1.0.1)
@@ -193,6 +230,8 @@ RSpec.describe Bundler::Definition do
BUNDLED WITH
1.13.0
L
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
it "should not eagerly unlock shared dependency with bundle install conservative updating behavior" do
@@ -201,13 +240,13 @@ RSpec.describe Bundler::Definition do
Bundler::Dependency.new("shared_owner_b", ">= 0")]
unlock_hash_for_bundle_install = {}
definition = Bundler::Definition.new(
- bundled_app("Gemfile.lock"),
+ bundled_app_lock,
updated_deps_in_gemfile,
- Bundler::SourceList.new,
+ source_list,
unlock_hash_for_bundle_install
)
locked = definition.send(:converge_locked_specs).map(&:name)
- expect(locked.include?("shared_dep")).to be_truthy
+ expect(locked).to include "shared_dep"
end
it "should not eagerly unlock shared dependency with bundle update conservative updating behavior" do
@@ -215,46 +254,19 @@ RSpec.describe Bundler::Definition do
Bundler::Dependency.new("shared_owner_a", ">= 0"),
Bundler::Dependency.new("shared_owner_b", ">= 0")]
definition = Bundler::Definition.new(
- bundled_app("Gemfile.lock"),
+ bundled_app_lock,
updated_deps_in_gemfile,
- Bundler::SourceList.new,
- :gems => ["shared_owner_a"], :lock_shared_dependencies => true
+ source_list,
+ :gems => ["shared_owner_a"], :conservative => true
)
locked = definition.send(:converge_locked_specs).map(&:name)
- expect(locked).to eq %w(isolated_dep isolated_owner shared_dep shared_owner_b)
+ expect(locked).to eq %w[isolated_dep isolated_owner shared_dep shared_owner_b]
expect(locked.include?("shared_dep")).to be_truthy
end
end
end
end
- describe "find_resolved_spec" do
- it "with no platform set in SpecSet" do
- ss = Bundler::SpecSet.new([build_stub_spec("a", "1.0"), build_stub_spec("b", "1.0")])
- dfn = Bundler::Definition.new(nil, [], mock_source_list, true)
- dfn.instance_variable_set("@specs", ss)
- found = dfn.find_resolved_spec(build_spec("a", "0.9", "ruby").first)
- expect(found.name).to eq "a"
- expect(found.version.to_s).to eq "1.0"
- end
- end
-
- describe "find_indexed_specs" do
- it "with no platform set in indexed specs" do
- index = Bundler::Index.new
- %w(1.0.0 1.0.1 1.1.0).each {|v| index << build_stub_spec("foo", v) }
-
- dfn = Bundler::Definition.new(nil, [], mock_source_list, true)
- dfn.instance_variable_set("@index", index)
- found = dfn.find_indexed_specs(build_spec("foo", "0.9", "ruby").first)
- expect(found.length).to eq 3
- end
- end
-
- def build_stub_spec(name, version)
- Bundler::StubSpecification.new(name, version, nil, nil)
- end
-
def mock_source_list
Class.new do
def all_sources
diff --git a/spec/bundler/bundler/dep_proxy_spec.rb b/spec/bundler/bundler/dep_proxy_spec.rb
new file mode 100644
index 0000000000..8d02a33725
--- /dev/null
+++ b/spec/bundler/bundler/dep_proxy_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+RSpec.describe Bundler::DepProxy do
+ let(:dep) { Bundler::Dependency.new("rake", ">= 0") }
+ subject { described_class.get_proxy(dep, Gem::Platform::RUBY) }
+ let(:same) { subject }
+ let(:other) { described_class.get_proxy(dep, Gem::Platform::RUBY) }
+ let(:different) { described_class.get_proxy(dep, Gem::Platform::JAVA) }
+
+ describe "#eql?" do
+ it { expect(subject.eql?(same)).to be true }
+ it { expect(subject.eql?(other)).to be true }
+ it { expect(subject.eql?(different)).to be false }
+ it { expect(subject.eql?(nil)).to be false }
+ it { expect(subject.eql?("foobar")).to be false }
+ end
+
+ describe "must use factory methods" do
+ it { expect { described_class.new(dep, Gem::Platform::RUBY) }.to raise_error NoMethodError }
+ it { expect { subject.dup }.to raise_error NoMethodError }
+ it { expect { subject.clone }.to raise_error NoMethodError }
+ end
+
+ describe "frozen" do
+ if Gem.ruby_version >= Gem::Version.new("2.5.0")
+ error = Object.const_get("FrozenError")
+ else
+ error = RuntimeError
+ end
+ it { expect { subject.instance_variable_set(:@__platform, {}) }.to raise_error error }
+ end
+end
diff --git a/spec/bundler/bundler/digest_spec.rb b/spec/bundler/bundler/digest_spec.rb
new file mode 100644
index 0000000000..d6bb043fd0
--- /dev/null
+++ b/spec/bundler/bundler/digest_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require "digest"
+require "bundler/digest"
+
+RSpec.describe Bundler::Digest do
+ context "SHA1" do
+ subject { Bundler::Digest }
+ let(:stdlib) { ::Digest::SHA1 }
+
+ it "is compatible with stdlib" do
+ ["foo", "skfjsdlkfjsdf", "3924m", "ldskfj"].each do |payload|
+ expect(subject.sha1(payload)).to be == stdlib.hexdigest(payload)
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/dsl_spec.rb b/spec/bundler/bundler/dsl_spec.rb
index 4f5eb6dc92..a44a12924c 100644
--- a/spec/bundler/bundler/dsl_spec.rb
+++ b/spec/bundler/bundler/dsl_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Dsl do
before do
@@ -26,10 +25,55 @@ RSpec.describe Bundler::Dsl do
expect { subject.git_source(:example) }.to raise_error(Bundler::InvalidOption)
end
- context "default hosts (git, gist)" do
- it "converts :github to :git" do
+ it "converts :github PR to URI using https" do
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5")
+ github_uri = "https://github.com/indirect/sparks.git"
+ expect(subject.dependencies.first.source.uri).to eq(github_uri)
+ expect(subject.dependencies.first.source.branch).to eq("refs/pull/5/head")
+ end
+
+ it "rejects :github PR URI with a branch, ref or tag" do
+ expect do
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5", :branch => "foo")
+ end.to raise_error(
+ Bundler::GemfileError,
+ %(The :branch option can't be used with `github: "https://github.com/indirect/sparks/pull/5"`),
+ )
+
+ expect do
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5", :ref => "foo")
+ end.to raise_error(
+ Bundler::GemfileError,
+ %(The :ref option can't be used with `github: "https://github.com/indirect/sparks/pull/5"`),
+ )
+
+ expect do
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5", :tag => "foo")
+ end.to raise_error(
+ Bundler::GemfileError,
+ %(The :tag option can't be used with `github: "https://github.com/indirect/sparks/pull/5"`),
+ )
+ end
+
+ it "rejects :github with :git" do
+ expect do
+ subject.gem("sparks", :github => "indirect/sparks", :git => "https://github.com/indirect/sparks.git")
+ end.to raise_error(
+ Bundler::GemfileError,
+ %(The :git option can't be used with `github: "indirect/sparks"`),
+ )
+ end
+
+ context "default hosts", :bundler => "< 3" do
+ it "converts :github to URI using https" do
subject.gem("sparks", :github => "indirect/sparks")
- github_uri = "git://github.com/indirect/sparks.git"
+ github_uri = "https://github.com/indirect/sparks.git"
+ expect(subject.dependencies.first.source.uri).to eq(github_uri)
+ end
+
+ it "converts :github shortcut to URI using https" do
+ subject.gem("sparks", :github => "rails")
+ github_uri = "https://github.com/rails/rails.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
@@ -45,12 +89,6 @@ RSpec.describe Bundler::Dsl do
expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
- it "converts 'rails' to 'rails/rails'" do
- subject.gem("rails", :github => "rails")
- github_uri = "git://github.com/rails/rails.git"
- expect(subject.dependencies.first.source.uri).to eq(github_uri)
- end
-
it "converts :bitbucket to :git" do
subject.gem("not-really-a-gem", :bitbucket => "mcorp/flatlab-rails")
bitbucket_uri = "https://mcorp@bitbucket.org/mcorp/flatlab-rails.git"
@@ -63,11 +101,17 @@ RSpec.describe Bundler::Dsl do
expect(subject.dependencies.first.source.uri).to eq(bitbucket_uri)
end
end
+
+ context "default git sources" do
+ it "has bitbucket, gist, and github" do
+ expect(subject.instance_variable_get(:@git_sources).keys.sort).to eq(%w[bitbucket gist github])
+ end
+ end
end
describe "#method_missing" do
it "raises an error for unknown DSL methods" do
- expect(Bundler).to receive(:read_file).with("Gemfile").
+ expect(Bundler).to receive(:read_file).with(source_root.join("Gemfile").to_s).
and_return("unknown")
error_msg = "There was an error parsing `Gemfile`: Undefined local variable or method `unknown' for Gemfile. Bundler cannot continue."
@@ -78,13 +122,13 @@ RSpec.describe Bundler::Dsl do
describe "#eval_gemfile" do
it "handles syntax errors with a useful message" do
- expect(Bundler).to receive(:read_file).with("Gemfile").and_return("}")
+ expect(Bundler).to receive(:read_file).with(source_root.join("Gemfile").to_s).and_return("}")
expect { subject.eval_gemfile("Gemfile") }.
to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`: (syntax error, unexpected tSTRING_DEND|(compile error - )?syntax error, unexpected '\}'). Bundler cannot continue./)
end
it "distinguishes syntax errors from evaluation errors" do
- expect(Bundler).to receive(:read_file).with("Gemfile").and_return(
+ expect(Bundler).to receive(:read_file).with(source_root.join("Gemfile").to_s).and_return(
"ruby '2.1.5', :engine => 'ruby', :engine_version => '1.2.4'"
)
expect { subject.eval_gemfile("Gemfile") }.
@@ -93,8 +137,8 @@ RSpec.describe Bundler::Dsl do
end
describe "#gem" do
- [:ruby, :ruby_18, :ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24, :ruby_25, :mri, :mri_18, :mri_19,
- :mri_20, :mri_21, :mri_22, :mri_23, :mri_24, :mri_25, :jruby, :rbx].each do |platform|
+ [:ruby, :ruby_18, :ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24, :ruby_25, :ruby_26, :mri, :mri_18, :mri_19,
+ :mri_20, :mri_21, :mri_22, :mri_23, :mri_24, :mri_25, :mri_26, :jruby, :rbx, :truffleruby].each do |platform|
it "allows #{platform} as a valid platform" do
subject.gem("foo", :platform => platform)
end
@@ -105,6 +149,11 @@ RSpec.describe Bundler::Dsl do
to raise_error(Bundler::GemfileError, /is not a valid platform/)
end
+ it "rejects empty gem name" do
+ expect { subject.gem("") }.
+ to raise_error(Bundler::GemfileError, /an empty gem name is not valid/)
+ end
+
it "rejects with a leading space in the name" do
expect { subject.gem(" foo") }.
to raise_error(Bundler::GemfileError, /' foo' is not a valid gem name because it contains whitespace/)
@@ -150,13 +199,13 @@ RSpec.describe Bundler::Dsl do
to raise_error(Bundler::GemfileError, /The `branch` option for `gem 'foo'` is not allowed. Only gems with a git source can specify a branch/)
end
- it "allows specifiying a branch on git gems" do
+ it "allows specifying a branch on git gems" do
subject.gem("foo", :branch => "test", :git => "http://mytestrepo")
dep = subject.dependencies.last
expect(dep.name).to eq "foo"
end
- it "allows specifiying a branch on git gems with a git_source" do
+ it "allows specifying a branch on git gems with a git_source" do
subject.git_source(:test_source) {|n| "https://github.com/#{n}" }
subject.gem("foo", :branch => "test", :test_source => "bundler/bundler")
dep = subject.dependencies.last
@@ -164,40 +213,6 @@ RSpec.describe Bundler::Dsl do
end
end
- describe "#gemspec" do
- let(:spec) do
- Gem::Specification.new do |gem|
- gem.name = "example"
- gem.platform = platform
- end
- end
-
- before do
- allow(Dir).to receive(:[]).and_return(["spec_path"])
- allow(Bundler).to receive(:load_gemspec).with("spec_path").and_return(spec)
- allow(Bundler).to receive(:default_gemfile).and_return(Pathname.new("./Gemfile"))
- end
-
- context "with a ruby platform" do
- let(:platform) { "ruby" }
-
- it "keeps track of the ruby platforms in the dependency" do
- subject.gemspec
- expect(subject.dependencies.last.platforms).to eq(Bundler::Dependency::REVERSE_PLATFORM_MAP[Gem::Platform::RUBY])
- end
- end
-
- context "with a jruby platform" do
- let(:platform) { "java" }
-
- it "keeps track of the jruby platforms in the dependency" do
- allow(Gem::Platform).to receive(:local).and_return(java)
- subject.gemspec
- expect(subject.dependencies.last.platforms).to eq(Bundler::Dependency::REVERSE_PLATFORM_MAP[Gem::Platform::JAVA])
- end
- end
- end
-
context "can bundle groups of gems with" do
# git "https://github.com/rails/rails.git" do
# gem "railties"
@@ -206,7 +221,7 @@ RSpec.describe Bundler::Dsl do
# end
describe "#git" do
it "from a single repo" do
- rails_gems = %w(railties action_pack active_model)
+ rails_gems = %w[railties action_pack active_model]
subject.git "https://github.com/rails/rails.git" do
rails_gems.each {|rails_gem| subject.send :gem, rails_gem }
end
@@ -221,13 +236,13 @@ RSpec.describe Bundler::Dsl do
# end
describe "#github" do
it "from github" do
- spree_gems = %w(spree_core spree_api spree_backend)
+ spree_gems = %w[spree_core spree_api spree_backend]
subject.github "spree" do
spree_gems.each {|spree_gem| subject.send :gem, spree_gem }
end
subject.dependencies.each do |d|
- expect(d.source.uri).to eq("git://github.com/spree/spree.git")
+ expect(d.source.uri).to eq("https://github.com/spree/spree.git")
end
end
end
@@ -236,16 +251,16 @@ RSpec.describe Bundler::Dsl do
describe "syntax errors" do
it "will raise a Bundler::GemfileError" do
gemfile "gem 'foo', :path => /unquoted/string/syntax/error"
- expect { Bundler::Dsl.evaluate(bundled_app("Gemfile"), nil, true) }.
- to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`:( compile error -)? unknown regexp options - trg. Bundler cannot continue./)
+ expect { Bundler::Dsl.evaluate(bundled_app_gemfile, nil, true) }.
+ to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`:( compile error -)? unknown regexp options - trg.+ Bundler cannot continue./)
end
end
- describe "Runtime errors", :unless => Bundler.current_ruby.on_18? do
+ describe "Runtime errors" do
it "will raise a Bundler::GemfileError" do
- gemfile "s = 'foo'.freeze; s.strip!"
- expect { Bundler::Dsl.evaluate(bundled_app("Gemfile"), nil, true) }.
- to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`: can't modify frozen String. Bundler cannot continue./i)
+ gemfile "raise RuntimeError, 'foo'"
+ expect { Bundler::Dsl.evaluate(bundled_app_gemfile, nil, true) }.
+ to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`: foo. Bundler cannot continue./i)
end
end
@@ -265,4 +280,21 @@ RSpec.describe Bundler::Dsl do
end
end
end
+
+ describe "#check_primary_source_safety" do
+ context "when a global source is not defined implicitly" do
+ it "will raise a major deprecation warning" do
+ not_a_global_source = double("not-a-global-source", :no_remotes? => true)
+ allow(Bundler::Source::Rubygems).to receive(:new).and_return(not_a_global_source)
+
+ warning = "This Gemfile does not include an explicit global source. " \
+ "Not using an explicit global source may result in a different lockfile being generated depending on " \
+ "the gems you have installed locally before bundler is run. " \
+ "Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
+ expect(Bundler::SharedHelpers).to receive(:major_deprecation).with(2, warning)
+
+ subject.check_primary_source_safety
+ end
+ end
+ end
end
diff --git a/spec/bundler/bundler/endpoint_specification_spec.rb b/spec/bundler/bundler/endpoint_specification_spec.rb
index 0b8da840d2..a9371f6617 100644
--- a/spec/bundler/bundler/endpoint_specification_spec.rb
+++ b/spec/bundler/bundler/endpoint_specification_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::EndpointSpecification do
let(:name) { "foo" }
@@ -8,7 +7,7 @@ RSpec.describe Bundler::EndpointSpecification do
let(:dependencies) { [] }
let(:metadata) { nil }
- subject { described_class.new(name, version, platform, dependencies, metadata) }
+ subject(:spec) { described_class.new(name, version, platform, dependencies, metadata) }
describe "#build_dependency" do
let(:name) { "foo" }
@@ -63,4 +62,10 @@ RSpec.describe Bundler::EndpointSpecification do
end
end
end
+
+ it "supports equality comparison" do
+ other_spec = described_class.new("bar", version, platform, dependencies, metadata)
+ expect(spec).to eql(spec)
+ expect(spec).to_not eql(other_spec)
+ end
end
diff --git a/spec/bundler/bundler/env_spec.rb b/spec/bundler/bundler/env_spec.rb
index 269c323ac6..8cd59311b2 100644
--- a/spec/bundler/bundler/env_spec.rb
+++ b/spec/bundler/bundler/env_spec.rb
@@ -1,30 +1,83 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/settings"
RSpec.describe Bundler::Env do
- let(:env) { described_class.new }
let(:git_proxy_stub) { Bundler::Source::Git::GitProxy.new(nil, nil, nil) }
describe "#report" do
it "prints the environment" do
- out = env.report
+ out = described_class.report
expect(out).to include("Environment")
expect(out).to include(Bundler::VERSION)
expect(out).to include(Gem::VERSION)
- expect(out).to include(env.send(:ruby_version))
- expect(out).to include(env.send(:git_version))
+ expect(out).to include(described_class.send(:ruby_version))
+ expect(out).to include(described_class.send(:git_version))
expect(out).to include(OpenSSL::OPENSSL_VERSION)
end
+ describe "rubygems paths" do
+ it "prints gem home" do
+ with_clear_paths("GEM_HOME", "/a/b/c") do
+ out = described_class.report
+ expect(out).to include("Gem Home /a/b/c")
+ end
+ end
+
+ it "prints gem path" do
+ with_clear_paths("GEM_PATH", "/a/b/c#{File::PATH_SEPARATOR}d/e/f") do
+ out = described_class.report
+ expect(out).to include("Gem Path /a/b/c#{File::PATH_SEPARATOR}d/e/f")
+ end
+ end
+
+ it "prints user home" do
+ skip "needs to use a valid HOME" if Gem.win_platform? && RUBY_VERSION < "2.6.0"
+
+ with_clear_paths("HOME", "/a/b/c") do
+ out = described_class.report
+ expect(out).to include("User Home /a/b/c")
+ end
+ end
+
+ it "prints user path" do
+ skip "needs to use a valid HOME" if Gem.win_platform? && RUBY_VERSION < "2.6.0"
+
+ with_clear_paths("HOME", "/a/b/c") do
+ allow(File).to receive(:exist?)
+ allow(File).to receive(:exist?).with("/a/b/c/.gem").and_return(true)
+ out = described_class.report
+ expect(out).to include("User Path /a/b/c/.gem")
+ end
+ end
+
+ it "prints bin dir" do
+ with_clear_paths("GEM_HOME", "/a/b/c") do
+ out = described_class.report
+ expect(out).to include("Bin Dir /a/b/c/bin")
+ end
+ end
+
+ private
+
+ def with_clear_paths(env_var, env_value)
+ old_env_var = ENV[env_var]
+ ENV[env_var] = env_value
+ Gem.clear_paths
+ yield
+ ensure
+ ENV[env_var] = old_env_var
+ end
+ end
+
context "when there is a Gemfile and a lockfile and print_gemfile is true" do
before do
- gemfile "gem 'rack', '1.0.0'"
+ gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem 'rack', '1.0.0'"
lockfile <<-L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0.0)
@@ -34,9 +87,11 @@ RSpec.describe Bundler::Env do
BUNDLED WITH
1.10.0
L
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
- let(:output) { env.report(:print_gemfile => true) }
+ let(:output) { described_class.report(:print_gemfile => true) }
it "prints the Gemfile" do
expect(output).to include("Gemfile")
@@ -50,13 +105,41 @@ RSpec.describe Bundler::Env do
end
context "when there no Gemfile and print_gemfile is true" do
- let(:output) { env.report(:print_gemfile => true) }
+ let(:output) { described_class.report(:print_gemfile => true) }
it "prints the environment" do
expect(output).to start_with("## Environment")
end
end
+ context "when there's bundler config with credentials" do
+ before do
+ bundle "config set https://localgemserver.test/ user:pass"
+ end
+
+ let(:output) { described_class.report(:print_gemfile => true) }
+
+ it "prints the config with redacted values" do
+ expect(output).to include("https://localgemserver.test")
+ expect(output).to include("user:[REDACTED]")
+ expect(output).to_not include("user:pass")
+ end
+ end
+
+ context "when there's bundler config with OAuth token credentials" do
+ before do
+ bundle "config set https://localgemserver.test/ api_token:x-oauth-basic"
+ end
+
+ let(:output) { described_class.report(:print_gemfile => true) }
+
+ it "prints the config with redacted values" do
+ expect(output).to include("https://localgemserver.test")
+ expect(output).to include("[REDACTED]:x-oauth-basic")
+ expect(output).to_not include("api_token:x-oauth-basic")
+ end
+ end
+
context "when Gemfile contains a gemspec and print_gemspecs is true" do
let(:gemspec) do
strip_whitespace(<<-GEMSPEC)
@@ -68,29 +151,89 @@ RSpec.describe Bundler::Env do
end
before do
- gemfile("gemspec")
+ gemfile("source \"#{file_uri_for(gem_repo1)}\"; gemspec")
File.open(bundled_app.join("foo.gemspec"), "wb") do |f|
f.write(gemspec)
end
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
it "prints the gemspec" do
- output = env.report(:print_gemspecs => true)
+ output = described_class.report(:print_gemspecs => true)
expect(output).to include("foo.gemspec")
expect(output).to include(gemspec)
end
end
+ context "when eval_gemfile is used" do
+ it "prints all gemfiles" do
+ create_file bundled_app("other/Gemfile-other"), "gem 'rack'"
+ create_file bundled_app("other/Gemfile"), "eval_gemfile 'Gemfile-other'"
+ create_file bundled_app("Gemfile-alt"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ eval_gemfile "other/Gemfile"
+ G
+ gemfile "eval_gemfile #{bundled_app("Gemfile-alt").to_s.dump}"
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app)
+
+ output = described_class.report(:print_gemspecs => true)
+ expect(output).to include(strip_whitespace(<<-ENV))
+ ## Gemfile
+
+ ### Gemfile
+
+ ```ruby
+ eval_gemfile #{bundled_app("Gemfile-alt").to_s.dump}
+ ```
+
+ ### Gemfile-alt
+
+ ```ruby
+ source "#{file_uri_for(gem_repo1)}"
+ eval_gemfile "other/Gemfile"
+ ```
+
+ ### other/Gemfile
+
+ ```ruby
+ eval_gemfile 'Gemfile-other'
+ ```
+
+ ### other/Gemfile-other
+
+ ```ruby
+ gem 'rack'
+ ```
+
+ ### Gemfile.lock
+
+ ```
+ <No #{bundled_app_lock} found>
+ ```
+ ENV
+ end
+ end
+
context "when the git version is OS specific" do
it "includes OS specific information with the version number" do
expect(git_proxy_stub).to receive(:git).with("--version").
and_return("git version 1.2.3 (Apple Git-BS)")
expect(Bundler::Source::Git::GitProxy).to receive(:new).and_return(git_proxy_stub)
- expect(env.report).to include("Git 1.2.3 (Apple Git-BS)")
+ expect(described_class.report).to include("Git 1.2.3 (Apple Git-BS)")
end
end
end
+
+ describe ".version_of" do
+ let(:parsed_version) { described_class.send(:version_of, "ruby") }
+
+ it "strips version of new line characters" do
+ expect(parsed_version).to_not end_with("\n")
+ end
+ end
end
diff --git a/spec/bundler/bundler/environment_preserver_spec.rb b/spec/bundler/bundler/environment_preserver_spec.rb
index 41d2650055..530ca6f835 100644
--- a/spec/bundler/bundler/environment_preserver_spec.rb
+++ b/spec/bundler/bundler/environment_preserver_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::EnvironmentPreserver do
let(:preserver) { described_class.new(env, ["foo"]) }
@@ -22,14 +21,14 @@ RSpec.describe Bundler::EnvironmentPreserver do
it "should not affect the original env" do
subject
- expect(env.keys.sort).to eq(%w(bar foo))
+ expect(env.keys.sort).to eq(%w[bar foo])
end
context "when a key is empty" do
let(:env) { { "foo" => "" } }
it "should not create backup entries" do
- expect(subject.key?("BUNDLER_ORIG_foo")).to eq(false)
+ expect(subject).not_to have_key "BUNDLER_ORIG_foo"
end
end
diff --git a/spec/bundler/bundler/fetcher/base_spec.rb b/spec/bundler/bundler/fetcher/base_spec.rb
index 38b69429bc..02506591f3 100644
--- a/spec/bundler/bundler/fetcher/base_spec.rb
+++ b/spec/bundler/bundler/fetcher/base_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Fetcher::Base do
let(:downloader) { double(:downloader) }
@@ -37,7 +36,7 @@ RSpec.describe Bundler::Fetcher::Base do
end
describe "#fetch_uri" do
- let(:remote_uri_obj) { URI("http://rubygems.org") }
+ let(:remote_uri_obj) { Bundler::URI("http://rubygems.org") }
before { allow(subject).to receive(:remote_uri).and_return(remote_uri_obj) }
@@ -50,10 +49,10 @@ RSpec.describe Bundler::Fetcher::Base do
end
context "when the remote uri's host is not rubygems.org" do
- let(:remote_uri_obj) { URI("http://otherhost.org") }
+ let(:remote_uri_obj) { Bundler::URI("http://otherhost.org") }
it "should return the remote uri" do
- expect(subject.fetch_uri).to eq(URI("http://otherhost.org"))
+ expect(subject.fetch_uri).to eq(Bundler::URI("http://otherhost.org"))
end
end
diff --git a/spec/bundler/bundler/fetcher/compact_index_spec.rb b/spec/bundler/bundler/fetcher/compact_index_spec.rb
index e653c1ea43..00eb27edea 100644
--- a/spec/bundler/bundler/fetcher/compact_index_spec.rb
+++ b/spec/bundler/bundler/fetcher/compact_index_spec.rb
@@ -1,9 +1,11 @@
# frozen_string_literal: true
-require "spec_helper"
+
+# load CompactIndexClient upfront to prevent thread safety issues during parallel specs
+require "bundler/compact_index_client"
RSpec.describe Bundler::Fetcher::CompactIndex do
let(:downloader) { double(:downloader) }
- let(:display_uri) { URI("http://sampleuri.com") }
+ let(:display_uri) { Bundler::URI("http://sampleuri.com") }
let(:remote) { double(:remote, :cache_slug => "lsjdf", :uri => display_uri) }
let(:compact_index) { described_class.new(downloader, remote, display_uri) }
@@ -12,15 +14,18 @@ RSpec.describe Bundler::Fetcher::CompactIndex do
end
describe "#specs_for_names" do
+ let(:thread_list) { Thread.list.select {|thread| thread.status == "run" } }
+ let(:thread_inspection) { thread_list.map {|th| " * #{th}:\n #{th.backtrace_locations.join("\n ")}" }.join("\n") }
+
it "has only one thread open at the end of the run" do
compact_index.specs_for_names(["lskdjf"])
- thread_count = Thread.list.count {|thread| thread.status == "run" }
- expect(thread_count).to eq 1
+ thread_count = thread_list.count
+ expect(thread_count).to eq(1), "Expected 1 active thread after `#specs_for_names`, but found #{thread_count}. In particular, found:\n#{thread_inspection}"
end
it "calls worker#stop during the run" do
- expect_any_instance_of(Bundler::Worker).to receive(:stop).at_least(:once)
+ expect_any_instance_of(Bundler::Worker).to receive(:stop).at_least(:once).and_call_original
compact_index.specs_for_names(["lskdjf"])
end
@@ -45,12 +50,22 @@ RSpec.describe Bundler::Fetcher::CompactIndex do
end
end
- context "when OpenSSL is FIPS-enabled", :ruby => ">= 2.0.0" do
- before { stub_const("OpenSSL::OPENSSL_FIPS", true) }
+ context "when OpenSSL is FIPS-enabled" do
+ def remove_cached_md5_availability
+ return unless Bundler::SharedHelpers.instance_variable_defined?(:@md5_available)
+ Bundler::SharedHelpers.remove_instance_variable(:@md5_available)
+ end
+
+ before do
+ remove_cached_md5_availability
+ stub_const("OpenSSL::OPENSSL_FIPS", true)
+ end
+
+ after { remove_cached_md5_availability }
context "when FIPS-mode is active" do
before do
- allow(OpenSSL::Digest::MD5).to receive(:digest).
+ allow(OpenSSL::Digest).to receive(:digest).with("MD5", "").
and_raise(OpenSSL::Digest::DigestError)
end
diff --git a/spec/bundler/bundler/fetcher/dependency_spec.rb b/spec/bundler/bundler/fetcher/dependency_spec.rb
index 134ca1bc57..53249116cd 100644
--- a/spec/bundler/bundler/fetcher/dependency_spec.rb
+++ b/spec/bundler/bundler/fetcher/dependency_spec.rb
@@ -1,9 +1,8 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Fetcher::Dependency do
let(:downloader) { double(:downloader) }
- let(:remote) { double(:remote, :uri => URI("http://localhost:5000")) }
+ let(:remote) { double(:remote, :uri => Bundler::URI("http://localhost:5000")) }
let(:display_uri) { "http://sample_uri.com" }
subject { described_class.new(downloader, remote, display_uri) }
@@ -64,7 +63,7 @@ RSpec.describe Bundler::Fetcher::Dependency do
end
describe "#specs" do
- let(:gem_names) { %w(foo bar) }
+ let(:gem_names) { %w[foo bar] }
let(:full_dependency_list) { ["bar"] }
let(:last_spec_list) { [["boulder", gem_version1, "ruby", resque]] }
let(:fail_errors) { double(:fail_errors) }
@@ -103,7 +102,7 @@ RSpec.describe Bundler::Fetcher::Dependency do
context "when all given gem names are in the full dependency list" do
let(:gem_names) { ["foo"] }
- let(:full_dependency_list) { %w(foo bar) }
+ let(:full_dependency_list) { %w[foo bar] }
let(:last_spec_list) { ["boulder"] }
it "should return a hash with the remote_uri and the last spec list" do
@@ -190,7 +189,7 @@ RSpec.describe Bundler::Fetcher::Dependency do
end
describe "#dependency_specs" do
- let(:gem_names) { [%w(foo bar), %w(bundler rubocop)] }
+ let(:gem_names) { [%w[foo bar], %w[bundler rubocop]] }
let(:gem_list) { double(:gem_list) }
let(:formatted_specs_and_deps) { double(:formatted_specs_and_deps) }
@@ -212,7 +211,7 @@ RSpec.describe Bundler::Fetcher::Dependency do
end
describe "#unmarshalled_dep_gems" do
- let(:gem_names) { [%w(foo bar), %w(bundler rubocop)] }
+ let(:gem_names) { [%w[foo bar], %w[bundler rubocop]] }
let(:dep_api_uri) { double(:dep_api_uri) }
let(:unmarshalled_gems) { double(:unmarshalled_gems) }
let(:fetch_response) { double(:fetch_response, :body => double(:body)) }
@@ -220,7 +219,7 @@ RSpec.describe Bundler::Fetcher::Dependency do
before { allow(subject).to receive(:dependency_api_uri).with(gem_names).and_return(dep_api_uri) }
- it "should fetch dependencies from Rubygems and unmarshal them" do
+ it "should fetch dependencies from RubyGems and unmarshal them" do
expect(gem_names).to receive(:each_slice).with(rubygems_limit).and_call_original
expect(downloader).to receive(:fetch).with(dep_api_uri).and_return(fetch_response)
expect(Bundler).to receive(:load_marshal).with(fetch_response.body).and_return([unmarshalled_gems])
@@ -254,15 +253,15 @@ RSpec.describe Bundler::Fetcher::Dependency do
spec_list, deps_list = subject.get_formatted_specs_and_deps(gem_list)
expect(spec_list).to eq([["typhoeus", "1.0.1", "ruby", [["resque", ["req3,req4"]]]],
["grape", "2.0.2", "jruby", [["faraday", ["req1,req2"]]]]])
- expect(deps_list).to eq(%w(resque faraday))
+ expect(deps_list).to eq(%w[resque faraday])
end
end
describe "#dependency_api_uri" do
- let(:uri) { URI("http://gem-api.com") }
+ let(:uri) { Bundler::URI("http://gem-api.com") }
context "with gem names" do
- let(:gem_names) { %w(foo bar bundler rubocop) }
+ let(:gem_names) { %w[foo bar bundler rubocop] }
before { allow(subject).to receive(:fetch_uri).and_return(uri) }
diff --git a/spec/bundler/bundler/fetcher/downloader_spec.rb b/spec/bundler/bundler/fetcher/downloader_spec.rb
index 4dcd94b1b2..94a0993a54 100644
--- a/spec/bundler/bundler/fetcher/downloader_spec.rb
+++ b/spec/bundler/bundler/fetcher/downloader_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Fetcher::Downloader do
let(:connection) { double(:connection) }
let(:redirect_limit) { 5 }
- let(:uri) { URI("http://www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://www.uri-to-fetch.com/api/v2/endpoint") }
let(:options) { double(:options) }
subject { described_class.new(connection, redirect_limit) }
@@ -42,19 +41,19 @@ RSpec.describe Bundler::Fetcher::Downloader do
before { http_response["location"] = "http://www.redirect-uri.com/api/v2/endpoint" }
it "should try to fetch the redirect uri and iterate the # requests counter" do
- expect(subject).to receive(:fetch).with(URI("http://www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
- expect(subject).to receive(:fetch).with(URI("http://www.redirect-uri.com/api/v2/endpoint"), options, 1)
+ expect(subject).to receive(:fetch).with(Bundler::URI("http://www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
+ expect(subject).to receive(:fetch).with(Bundler::URI("http://www.redirect-uri.com/api/v2/endpoint"), options, 1)
subject.fetch(uri, options, counter)
end
context "when the redirect uri and original uri are the same" do
- let(:uri) { URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
before { http_response["location"] = "ssh://www.uri-to-fetch.com/api/v1/endpoint" }
it "should set the same user and password for the redirect uri" do
- expect(subject).to receive(:fetch).with(URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
- expect(subject).to receive(:fetch).with(URI("ssh://username:password@www.uri-to-fetch.com/api/v1/endpoint"), options, 1)
+ expect(subject).to receive(:fetch).with(Bundler::URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
+ expect(subject).to receive(:fetch).with(Bundler::URI("ssh://username:password@www.uri-to-fetch.com/api/v1/endpoint"), options, 1)
subject.fetch(uri, options, counter)
end
end
@@ -83,13 +82,37 @@ RSpec.describe Bundler::Fetcher::Downloader do
expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
/Authentication is required for www.uri-to-fetch.com/)
end
+
+ it "should raise a Bundler::Fetcher::AuthenticationRequiredError with advices" do
+ expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
+ /`bundle config set --global www\.uri-to-fetch\.com username:password`.*`BUNDLE_WWW__URI___TO___FETCH__COM`/m)
+ end
+
+ context "when the there are credentials provided in the request" do
+ let(:uri) { Bundler::URI("http://user:password@www.uri-to-fetch.com") }
+
+ it "should raise a Bundler::Fetcher::BadAuthenticationError that doesn't contain the password" do
+ expect { subject.fetch(uri, options, counter) }.
+ to raise_error(Bundler::Fetcher::BadAuthenticationError, /Bad username or password for www.uri-to-fetch.com/)
+ end
+ end
end
context "when the request response is a Net::HTTPNotFound" do
let(:http_response) { Net::HTTPNotFound.new("1.1", 404, "Not Found") }
it "should raise a Bundler::Fetcher::FallbackError with Net::HTTPNotFound" do
- expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::FallbackError, "Net::HTTPNotFound")
+ expect { subject.fetch(uri, options, counter) }.
+ to raise_error(Bundler::Fetcher::FallbackError, "Net::HTTPNotFound: http://www.uri-to-fetch.com/api/v2/endpoint")
+ end
+
+ context "when the there are credentials provided in the request" do
+ let(:uri) { Bundler::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+
+ it "should raise a Bundler::Fetcher::FallbackError that doesn't contain the password" do
+ expect { subject.fetch(uri, options, counter) }.
+ to raise_error(Bundler::Fetcher::FallbackError, "Net::HTTPNotFound: http://username@www.uri-to-fetch.com/api/v2/endpoint")
+ end
end
end
@@ -119,7 +142,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
context "when there is a user provided in the request" do
context "and there is also a password provided" do
context "that contains cgi escaped characters" do
- let(:uri) { URI("http://username:password%24@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username:password%24@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with the username and password" do
expect(net_http_get).to receive(:basic_auth).with("username", "password$")
@@ -128,7 +151,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "that is all unescaped characters" do
- let(:uri) { URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with the username and proper cgi compliant password" do
expect(net_http_get).to receive(:basic_auth).with("username", "password")
subject.request(uri, options)
@@ -137,7 +160,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "and there is no password provided" do
- let(:uri) { URI("http://username@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with just the user" do
expect(net_http_get).to receive(:basic_auth).with("username", nil)
@@ -146,7 +169,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "that contains cgi escaped characters" do
- let(:uri) { URI("http://username%24@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username%24@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with the proper cgi compliant password user" do
expect(net_http_get).to receive(:basic_auth).with("username$", nil)
@@ -170,7 +193,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
let(:message) { "undefined method 'undefined_method_call'" }
it "should raise the original NoMethodError" do
- expect { subject.request(uri, options) }.to raise_error(NoMethodError, "undefined method 'undefined_method_call'")
+ expect { subject.request(uri, options) }.to raise_error(NoMethodError, /undefined method 'undefined_method_call'/)
end
end
end
@@ -208,16 +231,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
end
- context "when error message is about getaddrinfo issues" do
- let(:message) { "getaddrinfo: nodename nor servname provided for http://www.uri-to-fetch.com" }
-
- it "should raise a Bundler::Fetcher::NetworkDownError" do
- expect { subject.request(uri, options) }.to raise_error(Bundler::Fetcher::NetworkDownError,
- /Could not reach host www.uri-to-fetch.com/)
- end
- end
-
- context "when error message is about neither host down or getaddrinfo" do
+ context "when error message is not about host down" do
let(:message) { "other error about network" }
it "should raise a Bundler::HTTPError" do
@@ -226,7 +240,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "when the there are credentials provided in the request" do
- let(:uri) { URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
before do
allow(net_http_get).to receive(:basic_auth).with("username", "password")
end
diff --git a/spec/bundler/bundler/fetcher/index_spec.rb b/spec/bundler/bundler/fetcher/index_spec.rb
index b17e0d1727..f0db07583c 100644
--- a/spec/bundler/bundler/fetcher/index_spec.rb
+++ b/spec/bundler/bundler/fetcher/index_spec.rb
@@ -1,12 +1,13 @@
# frozen_string_literal: true
-require "spec_helper"
+
+require "rubygems/remote_fetcher"
RSpec.describe Bundler::Fetcher::Index do
let(:downloader) { nil }
let(:remote) { nil }
let(:display_uri) { "http://sample_uri.com" }
let(:rubygems) { double(:rubygems) }
- let(:gem_names) { %w(foo bar) }
+ let(:gem_names) { %w[foo bar] }
subject { described_class.new(downloader, remote, display_uri) }
@@ -18,83 +19,81 @@ RSpec.describe Bundler::Fetcher::Index do
end
context "error handling" do
- shared_examples_for "the error is properly handled" do
- let(:remote_uri) { URI("http://remote-uri.org") }
+ let(:remote_uri) { Bundler::URI("http://remote-uri.org") }
+ before do
+ allow(rubygems).to receive(:fetch_all_remote_specs) { raise Gem::RemoteFetcher::FetchError.new(error_message, display_uri) }
+ allow(subject).to receive(:remote_uri).and_return(remote_uri)
+ end
+
+ context "when certificate verify failed" do
+ let(:error_message) { "certificate verify failed" }
+
+ it "should raise a Bundler::Fetcher::CertificateFailureError" do
+ expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::CertificateFailureError,
+ %r{Could not verify the SSL certificate for http://sample_uri.com})
+ end
+ end
+
+ context "when a 401 response occurs" do
+ let(:error_message) { "401" }
+
before do
- allow(subject).to receive(:remote_uri).and_return(remote_uri)
+ allow(remote_uri).to receive(:userinfo).and_return(userinfo)
end
- context "when certificate verify failed" do
- let(:error_message) { "certificate verify failed" }
+ context "and there was userinfo" do
+ let(:userinfo) { double(:userinfo) }
- it "should raise a Bundler::Fetcher::CertificateFailureError" do
- expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::CertificateFailureError,
- %r{Could not verify the SSL certificate for http://sample_uri.com})
+ it "should raise a Bundler::Fetcher::BadAuthenticationError" do
+ expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError,
+ %r{Bad username or password for http://remote-uri.org})
end
end
- context "when a 401 response occurs" do
- let(:error_message) { "401" }
+ context "and there was no userinfo" do
+ let(:userinfo) { nil }
it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
%r{Authentication is required for http://remote-uri.org})
end
end
+ end
- context "when a 403 response occurs" do
- let(:error_message) { "403" }
-
- before do
- allow(remote_uri).to receive(:userinfo).and_return(userinfo)
- end
-
- context "and there was userinfo" do
- let(:userinfo) { double(:userinfo) }
+ context "when a 403 response occurs" do
+ let(:error_message) { "403" }
- it "should raise a Bundler::Fetcher::BadAuthenticationError" do
- expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError,
- %r{Bad username or password for http://remote-uri.org})
- end
- end
+ before do
+ allow(remote_uri).to receive(:userinfo).and_return(userinfo)
+ end
- context "and there was no userinfo" do
- let(:userinfo) { nil }
+ context "and there was userinfo" do
+ let(:userinfo) { double(:userinfo) }
- it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do
- expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
- %r{Authentication is required for http://remote-uri.org})
- end
+ it "should raise a Bundler::Fetcher::BadAuthenticationError" do
+ expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError,
+ %r{Bad username or password for http://remote-uri.org})
end
end
- context "any other message is returned" do
- let(:error_message) { "You get an error, you get an error!" }
-
- before { allow(Bundler).to receive(:ui).and_return(double(:trace => nil)) }
+ context "and there was no userinfo" do
+ let(:userinfo) { nil }
- it "should raise a Bundler::HTTPError" do
- expect { subject.specs(gem_names) }.to raise_error(Bundler::HTTPError, "Could not fetch specs from http://sample_uri.com")
+ it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do
+ expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
+ %r{Authentication is required for http://remote-uri.org})
end
end
end
- context "when a Gem::RemoteFetcher::FetchError occurs" do
- before { allow(rubygems).to receive(:fetch_all_remote_specs) { raise Gem::RemoteFetcher::FetchError.new(error_message, nil) } }
+ context "any other message is returned" do
+ let(:error_message) { "You get an error, you get an error!" }
- it_behaves_like "the error is properly handled"
- end
-
- context "when a OpenSSL::SSL::SSLError occurs" do
- before { allow(rubygems).to receive(:fetch_all_remote_specs) { raise OpenSSL::SSL::SSLError.new(error_message) } }
-
- it_behaves_like "the error is properly handled"
- end
-
- context "when a Net::HTTPFatalError occurs" do
- before { allow(rubygems).to receive(:fetch_all_remote_specs) { raise Net::HTTPFatalError.new(error_message, 404) } }
+ before { allow(Bundler).to receive(:ui).and_return(double(:trace => nil)) }
- it_behaves_like "the error is properly handled"
+ it "should raise a Bundler::HTTPError" do
+ expect { subject.specs(gem_names) }.to raise_error(Bundler::HTTPError, "Could not fetch specs from http://sample_uri.com due to underlying error <You get an error, you get an error! (http://sample_uri.com)>")
+ end
end
end
end
diff --git a/spec/bundler/bundler/fetcher_spec.rb b/spec/bundler/bundler/fetcher_spec.rb
index 585768343f..256d342775 100644
--- a/spec/bundler/bundler/fetcher_spec.rb
+++ b/spec/bundler/bundler/fetcher_spec.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/fetcher"
RSpec.describe Bundler::Fetcher do
- let(:uri) { URI("https://example.com") }
+ let(:uri) { Bundler::URI("https://example.com") }
let(:remote) { double("remote", :uri => uri, :original_uri => nil) }
subject(:fetcher) { Bundler::Fetcher.new(remote) }
@@ -45,7 +45,7 @@ RSpec.describe Bundler::Fetcher do
end
context "when a rubygems source mirror is set" do
- let(:orig_uri) { URI("http://zombo.com") }
+ let(:orig_uri) { Bundler::URI("http://zombo.com") }
let(:remote_with_mirror) do
double("remote", :uri => uri, :original_uri => orig_uri, :anonymized_uri => uri)
end
@@ -85,11 +85,56 @@ RSpec.describe Bundler::Fetcher do
end
end
end
+
+ context "when no ssl configuration is set" do
+ it "no cert" do
+ expect(fetcher.send(:connection).cert).to be_nil
+ expect(fetcher.send(:connection).key).to be_nil
+ end
+ end
+
+ context "when bunder ssl ssl configuration is set" do
+ before do
+ cert = File.join(Spec::Path.tmpdir, "cert")
+ File.open(cert, "w") {|f| f.write "PEM" }
+ allow(Bundler.settings).to receive(:[]).and_return(nil)
+ allow(Bundler.settings).to receive(:[]).with(:ssl_client_cert).and_return(cert)
+ expect(OpenSSL::X509::Certificate).to receive(:new).with("PEM").and_return("cert")
+ expect(OpenSSL::PKey::RSA).to receive(:new).with("PEM").and_return("key")
+ end
+ after do
+ FileUtils.rm File.join(Spec::Path.tmpdir, "cert")
+ end
+ it "use bundler configuration" do
+ expect(fetcher.send(:connection).cert).to eq("cert")
+ expect(fetcher.send(:connection).key).to eq("key")
+ end
+ end
+
+ context "when gem ssl configuration is set" do
+ before do
+ allow(Bundler.rubygems.configuration).to receive_messages(
+ :http_proxy => nil,
+ :ssl_client_cert => "cert",
+ :ssl_ca_cert => "ca"
+ )
+ expect(File).to receive(:read).and_return("")
+ expect(OpenSSL::X509::Certificate).to receive(:new).and_return("cert")
+ expect(OpenSSL::PKey::RSA).to receive(:new).and_return("key")
+ store = double("ca store")
+ expect(store).to receive(:add_file)
+ expect(OpenSSL::X509::Store).to receive(:new).and_return(store)
+ end
+ it "use gem configuration" do
+ expect(fetcher.send(:connection).cert).to eq("cert")
+ expect(fetcher.send(:connection).key).to eq("key")
+ end
+ end
end
describe "#user_agent" do
it "builds user_agent with current ruby version and Bundler settings" do
- allow(Bundler.settings).to receive(:all).and_return(%w(foo bar))
+ allow(Bundler.settings).to receive(:all).and_return(%w[foo bar])
expect(fetcher.user_agent).to match(%r{bundler/(\d.)})
expect(fetcher.user_agent).to match(%r{rubygems/(\d.)})
expect(fetcher.user_agent).to match(%r{ruby/(\d.)})
@@ -99,15 +144,16 @@ RSpec.describe Bundler::Fetcher do
describe "include CI information" do
it "from one CI" do
with_env_vars("JENKINS_URL" => "foo") do
- ci_part = fetcher.user_agent.split(" ").find {|x| x.match(%r{\Aci/}) }
+ ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") }
expect(ci_part).to match("jenkins")
end
end
it "from many CI" do
- with_env_vars("TRAVIS" => "foo", "CI_NAME" => "my_ci") do
- ci_part = fetcher.user_agent.split(" ").find {|x| x.match(%r{\Aci/}) }
+ with_env_vars("TRAVIS" => "foo", "GITLAB_CI" => "gitlab", "CI_NAME" => "my_ci") do
+ ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") }
expect(ci_part).to match("travis")
+ expect(ci_part).to match("gitlab")
expect(ci_part).to match("my_ci")
end
end
diff --git a/spec/bundler/bundler/friendly_errors_spec.rb b/spec/bundler/bundler/friendly_errors_spec.rb
index 19799d5495..496191f891 100644
--- a/spec/bundler/bundler/friendly_errors_spec.rb
+++ b/spec/bundler/bundler/friendly_errors_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler"
require "bundler/friendly_errors"
require "cgi"
@@ -7,40 +7,24 @@ require "cgi"
RSpec.describe Bundler, "friendly errors" do
context "with invalid YAML in .gemrc" do
before do
- File.open(Gem.configuration.config_file_name, "w") do |f|
+ File.open(home(".gemrc"), "w") do |f|
f.write "invalid: yaml: hah"
end
end
after do
- FileUtils.rm(Gem.configuration.config_file_name)
+ FileUtils.rm(home(".gemrc"))
end
- it "reports a relevant friendly error message", :ruby => ">= 1.9", :rubygems => "< 2.5.0" do
+ it "reports a relevant friendly error message" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle :install, :env => { "DEBUG" => true }
-
- expect(out).to include("Your RubyGems configuration")
- expect(out).to include("invalid YAML syntax")
- expect(out).to include("Psych::SyntaxError")
- expect(out).not_to include("ERROR REPORT TEMPLATE")
- expect(exitstatus).to eq(25) if exitstatus
- end
-
- it "reports a relevant friendly error message", :ruby => ">= 1.9", :rubygems => ">= 2.5.0" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
-
- bundle :install, :env => { "DEBUG" => true }
+ bundle :install, :env => { "DEBUG" => "true" }
expect(err).to include("Failed to load #{home(".gemrc")}")
- expect(exitstatus).to eq(0) if exitstatus
end
end
@@ -109,7 +93,7 @@ RSpec.describe Bundler, "friendly errors" do
end
it "writes to Bundler.ui.trace" do
- expect(Bundler.ui).to receive(:trace).with(orig_error, nil, true)
+ expect(Bundler.ui).to receive(:trace).with(orig_error)
Bundler::FriendlyErrors.log_error(error)
end
end
@@ -130,18 +114,12 @@ RSpec.describe Bundler, "friendly errors" do
context "LoadError" do
let(:error) { LoadError.new("cannot load such file -- openssl") }
- it "Bundler.ui receive error" do
- expect(Bundler.ui).to receive(:error).with("\nCould not load OpenSSL.")
- Bundler::FriendlyErrors.log_error(error)
- end
-
- it "Bundler.ui receive warn" do
- expect(Bundler.ui).to receive(:warn).with(any_args, :wrap => true)
- Bundler::FriendlyErrors.log_error(error)
+ before do
+ allow(error).to receive(:backtrace).and_return(["backtrace"])
end
- it "Bundler.ui receive trace" do
- expect(Bundler.ui).to receive(:trace).with(error)
+ it "Bundler.ui receive error" do
+ expect(Bundler.ui).to receive(:error).with("\nCould not load OpenSSL. LoadError: cannot load such file -- openssl\nbacktrace")
Bundler::FriendlyErrors.log_error(error)
end
end
@@ -215,9 +193,9 @@ RSpec.describe Bundler, "friendly errors" do
describe "#request_issue_report_for" do
it "calls relevant methods for Bundler.ui" do
- expect(Bundler.ui).to receive(:info)
- expect(Bundler.ui).to receive(:error)
- expect(Bundler.ui).to receive(:warn)
+ expect(Bundler.ui).not_to receive(:info)
+ expect(Bundler.ui).to receive(:error).exactly(3).times
+ expect(Bundler.ui).not_to receive(:warn)
Bundler::FriendlyErrors.request_issue_report_for(StandardError.new)
end
@@ -236,7 +214,7 @@ RSpec.describe Bundler, "friendly errors" do
it "generates a search URL for the exception message" do
exception = Exception.new("Exception message")
- expect(Bundler::FriendlyErrors.issues_url(exception)).to eq("https://github.com/bundler/bundler/search?q=Exception+message&type=Issues")
+ expect(Bundler::FriendlyErrors.issues_url(exception)).to eq("https://github.com/rubygems/rubygems/search?q=Exception+message&type=Issues")
end
it "generates a search URL for only the first line of a multi-line exception message" do
@@ -245,7 +223,7 @@ First line of the exception message
Second line of the exception message
END
- expect(Bundler::FriendlyErrors.issues_url(exception)).to eq("https://github.com/bundler/bundler/search?q=First+line+of+the+exception+message&type=Issues")
+ expect(Bundler::FriendlyErrors.issues_url(exception)).to eq("https://github.com/rubygems/rubygems/search?q=First+line+of+the+exception+message&type=Issues")
end
it "generates the url without colons" do
@@ -254,7 +232,7 @@ Exception ::: with ::: colons :::
END
issues_url = Bundler::FriendlyErrors.issues_url(exception)
expect(issues_url).not_to include("%3A")
- expect(issues_url).to eq("https://github.com/bundler/bundler/search?q=#{CGI.escape("Exception with colons ")}&type=Issues")
+ expect(issues_url).to eq("https://github.com/rubygems/rubygems/search?q=#{CGI.escape("Exception with colons ")}&type=Issues")
end
it "removes information after - for Errono::EACCES" do
@@ -264,7 +242,7 @@ END
allow(exception).to receive(:is_a?).with(Errno).and_return(true)
issues_url = Bundler::FriendlyErrors.issues_url(exception)
expect(issues_url).not_to include("/Users/foo/bar")
- expect(issues_url).to eq("https://github.com/bundler/bundler/search?q=#{CGI.escape("Errno EACCES Permission denied @ dir_s_mkdir ")}&type=Issues")
+ expect(issues_url).to eq("https://github.com/rubygems/rubygems/search?q=#{CGI.escape("Errno EACCES Permission denied @ dir_s_mkdir ")}&type=Issues")
end
end
end
diff --git a/spec/bundler/bundler/gem_helper_spec.rb b/spec/bundler/bundler/gem_helper_spec.rb
index 498ed89447..2c43719aa1 100644
--- a/spec/bundler/bundler/gem_helper_spec.rb
+++ b/spec/bundler/bundler/gem_helper_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "rake"
require "bundler/gem_helper"
@@ -9,8 +9,10 @@ RSpec.describe Bundler::GemHelper do
let(:app_gemspec_path) { app_path.join("#{app_name}.gemspec") }
before(:each) do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false"
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false",
+ "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
bundle "gem #{app_name}"
+ prepare_gemspec(app_gemspec_path)
end
context "determining gemspec" do
@@ -29,15 +31,6 @@ RSpec.describe Bundler::GemHelper do
end
context "interpolates the name" do
- before do
- # Remove exception that prevents public pushes on older RubyGems versions
- if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0")
- content = File.read(app_gemspec_path)
- content.sub!(/raise "RubyGems 2\.0 or newer.*/, "")
- File.open(app_gemspec_path, "w") {|f| f.write(content) }
- end
- end
-
it "when there is only one gemspec" do
expect(subject.gemspec.name).to eq(app_name)
end
@@ -68,26 +61,25 @@ RSpec.describe Bundler::GemHelper do
mock_confirm_message message
end
+ def mock_checksum_message(name, version)
+ message = "#{name} #{version} checksum written to checksums/#{name}-#{version}.gem.sha512."
+ mock_confirm_message message
+ end
+
subject! { Bundler::GemHelper.new(app_path) }
let(:app_version) { "0.1.0" }
let(:app_gem_dir) { app_path.join("pkg") }
let(:app_gem_path) { app_gem_dir.join("#{app_name}-#{app_version}.gem") }
- let(:app_gemspec_content) { remove_push_guard(File.read(app_gemspec_path)) }
+ let(:app_sha_path) { app_path.join("checksums", "#{app_name}-#{app_version}.gem.sha512") }
+ let(:app_gemspec_content) { File.read(app_gemspec_path) }
before(:each) do
content = app_gemspec_content.gsub("TODO: ", "")
content.sub!(/homepage\s+= ".*"/, 'homepage = ""')
+ content.gsub!(/spec\.metadata.+\n/, "")
File.open(app_gemspec_path, "w") {|file| file << content }
end
- def remove_push_guard(gemspec_content)
- # Remove exception that prevents public pushes on older RubyGems versions
- if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0")
- gemspec_content.sub!(/raise "RubyGems 2\.0 or newer.*/, "")
- end
- gemspec_content
- end
-
it "uses a shell UI for output" do
expect(Bundler.ui).to be_a(Bundler::UI::Shell)
end
@@ -105,13 +97,14 @@ RSpec.describe Bundler::GemHelper do
context "defines Rake tasks" do
let(:task_names) do
- %w(build install release release:guard_clean
- release:source_control_push release:rubygem_push)
+ %w[build install release release:guard_clean
+ release:source_control_push release:rubygem_push]
end
context "before installation" do
it "raises an error with appropriate message" do
task_names.each do |name|
+ skip "Rake::FileTask '#{name}' exists" if File.exist?(name)
expect { Rake.application[name] }.
to raise_error(/^Don't know how to build task '#{name}'/)
end
@@ -153,6 +146,57 @@ RSpec.describe Bundler::GemHelper do
expect(app_gem_path).to exist
end
end
+
+ context "when building in the current working directory" do
+ it "creates .gem file" do
+ mock_build_message app_name, app_version
+ Dir.chdir app_path do
+ Bundler::GemHelper.new.build_gem
+ end
+ expect(app_gem_path).to exist
+ end
+ end
+
+ context "when building in a location relative to the current working directory" do
+ it "creates .gem file" do
+ mock_build_message app_name, app_version
+ Dir.chdir File.dirname(app_path) do
+ Bundler::GemHelper.new(File.basename(app_path)).build_gem
+ end
+ expect(app_gem_path).to exist
+ end
+ end
+ end
+
+ describe "#build_checksum" do
+ context "when build was successful" do
+ it "creates .sha512 file" do
+ mock_build_message app_name, app_version
+ mock_checksum_message app_name, app_version
+ subject.build_checksum
+ expect(app_sha_path).to exist
+ end
+ end
+ context "when building in the current working directory" do
+ it "creates a .sha512 file" do
+ mock_build_message app_name, app_version
+ mock_checksum_message app_name, app_version
+ Dir.chdir app_path do
+ Bundler::GemHelper.new.build_checksum
+ end
+ expect(app_sha_path).to exist
+ end
+ end
+ context "when building in a location relative to the current working directory" do
+ it "creates a .sha512 file" do
+ mock_build_message app_name, app_version
+ mock_checksum_message app_name, app_version
+ Dir.chdir File.dirname(app_path) do
+ Bundler::GemHelper.new(File.basename(app_path)).build_checksum
+ end
+ expect(app_sha_path).to exist
+ end
+ end
end
describe "#install_gem" do
@@ -162,7 +206,7 @@ RSpec.describe Bundler::GemHelper do
mock_confirm_message "#{app_name} (#{app_version}) installed."
subject.install_gem(nil, :local)
expect(app_gem_path).to exist
- gem_command! :list
+ gem_command :list
expect(out).to include("#{app_name} (#{app_version})")
end
end
@@ -175,7 +219,7 @@ RSpec.describe Bundler::GemHelper do
FileUtils.touch app_gem_path
app_gem_path
end
- expect { subject.install_gem }.to raise_error(/Couldn't install gem/)
+ expect { subject.install_gem }.to raise_error(/Running `#{gem_bin} install #{app_gem_path}` failed/)
end
end
end
@@ -193,12 +237,11 @@ RSpec.describe Bundler::GemHelper do
end
before do
- Dir.chdir(app_path) do
- `git init`
- `git config user.email "you@example.com"`
- `git config user.name "name"`
- `git config push.default simple`
- end
+ sys_exec("git init", :dir => app_path)
+ sys_exec("git config user.email \"you@example.com\"", :dir => app_path)
+ sys_exec("git config user.name \"name\"", :dir => app_path)
+ sys_exec("git config commit.gpgsign false", :dir => app_path)
+ sys_exec("git config push.default simple", :dir => app_path)
# silence messages
allow(Bundler.ui).to receive(:confirm)
@@ -212,35 +255,81 @@ RSpec.describe Bundler::GemHelper do
end
it "when there are uncommitted files" do
- Dir.chdir(app_path) { `git add .` }
+ sys_exec("git add .", :dir => app_path)
expect { Rake.application["release"].invoke }.
to raise_error("There are files that need to be committed first.")
end
it "when there is no git remote" do
- Dir.chdir(app_path) { `git commit -a -m "initial commit"` }
+ sys_exec("git commit -a -m \"initial commit\"", :dir => app_path)
expect { Rake.application["release"].invoke }.to raise_error(RuntimeError)
end
end
context "succeeds" do
+ let(:repo) { build_git("foo", :bare => true) }
+
before do
- Dir.chdir(gem_repo1) { `git init --bare` }
- Dir.chdir(app_path) do
- `git remote add origin file://#{gem_repo1}`
- `git commit -a -m "initial commit"`
+ sys_exec("git remote add origin #{file_uri_for(repo.path)}", :dir => app_path)
+ sys_exec('git commit -a -m "initial commit"', :dir => app_path)
+ end
+
+ context "on releasing" do
+ before do
+ mock_build_message app_name, app_version
+ mock_confirm_message "Tagged v#{app_version}."
+ mock_confirm_message "Pushed git commits and release tag."
+
+ sys_exec("git push -u origin master", :dir => app_path)
+ end
+
+ it "calls rubygem_push with proper arguments" do
+ expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
+
+ Rake.application["release"].invoke
+ end
+
+ it "uses Kernel.system" do
+ cmd = gem_bin.shellsplit
+ expect(Kernel).to receive(:system).with(*cmd, "push", app_gem_path.to_s, "--host", "http://example.org").and_return(true)
+
+ Rake.application["release"].invoke
+ end
+
+ it "also works when releasing from an ambiguous reference" do
+ # Create a branch with the same name as the tag
+ sys_exec("git checkout -b v#{app_version}", :dir => app_path)
+ sys_exec("git push -u origin v#{app_version}", :dir => app_path)
+
+ expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
+
+ Rake.application["release"].invoke
+ end
+
+ it "also works with releasing from a branch not yet pushed" do
+ sys_exec("git checkout -b module_function", :dir => app_path)
+
+ expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
+
+ Rake.application["release"].invoke
end
end
- it "on releasing" do
- mock_build_message app_name, app_version
- mock_confirm_message "Tagged v#{app_version}."
- mock_confirm_message "Pushed git commits and tags."
- expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
+ context "on releasing with a custom tag prefix" do
+ before do
+ Bundler::GemHelper.tag_prefix = "foo-"
+ mock_build_message app_name, app_version
+ mock_confirm_message "Pushed git commits and release tag."
+
+ sys_exec("git push -u origin master", :dir => app_path)
+ expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
+ end
- Dir.chdir(app_path) { sys_exec("git push -u origin master") }
+ it "prepends the custom prefix to the tag" do
+ mock_confirm_message "Tagged foo-v#{app_version}."
- Rake.application["release"].invoke
+ Rake.application["release"].invoke
+ end
end
it "even if tag already exists" do
@@ -248,13 +337,99 @@ RSpec.describe Bundler::GemHelper do
mock_confirm_message "Tag v#{app_version} has already been created."
expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
- Dir.chdir(app_path) do
- `git tag -a -m \"Version #{app_version}\" v#{app_version}`
- end
+ sys_exec("git tag -a -m \"Version #{app_version}\" v#{app_version}", :dir => app_path)
Rake.application["release"].invoke
end
end
end
+
+ describe "release:rubygem_push" do
+ let!(:rake_application) { Rake.application }
+
+ before(:each) do
+ Rake.application = Rake::Application.new
+ subject.install
+ allow(subject).to receive(:sh_with_input)
+ end
+
+ after(:each) do
+ Rake.application = rake_application
+ end
+
+ before do
+ sys_exec("git init", :dir => app_path)
+ sys_exec("git config user.email \"you@example.com\"", :dir => app_path)
+ sys_exec("git config user.name \"name\"", :dir => app_path)
+ sys_exec("git config push.gpgsign simple", :dir => app_path)
+
+ # silence messages
+ allow(Bundler.ui).to receive(:confirm)
+ allow(Bundler.ui).to receive(:error)
+
+ credentials = double("credentials", "file?" => true)
+ allow(Bundler.user_home).to receive(:join).
+ with(".gem/credentials").and_return(credentials)
+ end
+
+ describe "success messaging" do
+ context "No allowed_push_host set" do
+ before do
+ allow(subject).to receive(:allowed_push_host).and_return(nil)
+ end
+
+ around do |example|
+ orig_host = ENV["RUBYGEMS_HOST"]
+ ENV["RUBYGEMS_HOST"] = rubygems_host_env
+
+ example.run
+
+ ENV["RUBYGEMS_HOST"] = orig_host
+ end
+
+ context "RUBYGEMS_HOST env var is set" do
+ let(:rubygems_host_env) { "https://custom.env.gemhost.com" }
+
+ it "should report successful push to the host from the environment" do
+ mock_confirm_message "Pushed #{app_name} #{app_version} to #{rubygems_host_env}"
+
+ Rake.application["release:rubygem_push"].invoke
+ end
+ end
+
+ context "RUBYGEMS_HOST env var is not set" do
+ let(:rubygems_host_env) { nil }
+
+ it "should report successful push to rubygems.org" do
+ mock_confirm_message "Pushed #{app_name} #{app_version} to rubygems.org"
+
+ Rake.application["release:rubygem_push"].invoke
+ end
+ end
+
+ context "RUBYGEMS_HOST env var is an empty string" do
+ let(:rubygems_host_env) { "" }
+
+ it "should report successful push to rubygems.org" do
+ mock_confirm_message "Pushed #{app_name} #{app_version} to rubygems.org"
+
+ Rake.application["release:rubygem_push"].invoke
+ end
+ end
+ end
+
+ context "allowed_push_host set in gemspec" do
+ before do
+ allow(subject).to receive(:allowed_push_host).and_return("https://my.gemhost.com")
+ end
+
+ it "should report successful push to the allowed gem host" do
+ mock_confirm_message "Pushed #{app_name} #{app_version} to https://my.gemhost.com"
+
+ Rake.application["release:rubygem_push"].invoke
+ end
+ end
+ end
+ end
end
end
diff --git a/spec/bundler/bundler/gem_version_promoter_spec.rb b/spec/bundler/bundler/gem_version_promoter_spec.rb
index c7620e2620..43a3630bbb 100644
--- a/spec/bundler/bundler/gem_version_promoter_spec.rb
+++ b/spec/bundler/bundler/gem_version_promoter_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::GemVersionPromoter do
context "conservative resolver" do
@@ -27,13 +26,15 @@ RSpec.describe Bundler::GemVersionPromoter do
end
end
- def build_spec_group(name, version)
- Bundler::Resolver::SpecGroup.new(build_spec(name, version))
+ def build_spec_groups(name, versions)
+ versions.map do |v|
+ Bundler::Resolver::SpecGroup.create_for({ Gem::Platform::RUBY => build_spec(name, v) }, [Gem::Platform::RUBY], Gem::Platform::RUBY)
+ end
end
# Rightmost (highest array index) in result is most preferred.
# Leftmost (lowest array index) in result is least preferred.
- # `build_spec_group` has all version of gem in index.
+ # `build_spec_groups` has all versions of gem in index.
# `build_spec` is the version currently in the .lock file.
#
# In default (not strict) mode, all versions in the index will
@@ -44,28 +45,28 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when keeping build_spec, keep current, next release" do
keep_locked(:level => :patch)
res = @gvp.filter_dep_specs(
- build_spec_group("foo", %w(1.7.8 1.7.9 1.8.0)),
+ build_spec_groups("foo", %w[1.7.8 1.7.9 1.8.0]),
build_spec("foo", "1.7.8").first
)
- expect(versions(res)).to eq %w(1.7.9 1.7.8)
+ expect(versions(res)).to eq %w[1.7.9 1.7.8]
end
it "when unlocking prefer next release first" do
unlocking(:level => :patch)
res = @gvp.filter_dep_specs(
- build_spec_group("foo", %w(1.7.8 1.7.9 1.8.0)),
+ build_spec_groups("foo", %w[1.7.8 1.7.9 1.8.0]),
build_spec("foo", "1.7.8").first
)
- expect(versions(res)).to eq %w(1.7.8 1.7.9)
+ expect(versions(res)).to eq %w[1.7.8 1.7.9]
end
it "when unlocking keep current when already at latest release" do
unlocking(:level => :patch)
res = @gvp.filter_dep_specs(
- build_spec_group("foo", %w(1.7.9 1.8.0 2.0.0)),
+ build_spec_groups("foo", %w[1.7.9 1.8.0 2.0.0]),
build_spec("foo", "1.7.9").first
)
- expect(versions(res)).to eq %w(1.7.9)
+ expect(versions(res)).to eq %w[1.7.9]
end
end
@@ -73,19 +74,19 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking favor next releases, remove minor and major increases" do
unlocking(:level => :minor)
res = @gvp.filter_dep_specs(
- build_spec_group("foo", %w(0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1)),
+ build_spec_groups("foo", %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]),
build_spec("foo", "0.2.0").first
)
- expect(versions(res)).to eq %w(0.2.0 0.3.0 0.3.1 0.9.0)
+ expect(versions(res)).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0]
end
it "when keep locked, keep current, then favor next release, remove minor and major increases" do
keep_locked(:level => :minor)
res = @gvp.filter_dep_specs(
- build_spec_group("foo", %w(0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1)),
+ build_spec_groups("foo", %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]),
build_spec("foo", "0.2.0").first
)
- expect(versions(res)).to eq %w(0.3.0 0.3.1 0.9.0 0.2.0)
+ expect(versions(res)).to eq %w[0.3.0 0.3.1 0.9.0 0.2.0]
end
end
@@ -93,37 +94,37 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when not unlocking, same order but make sure build_spec version is most preferred to stay put" do
keep_locked(:level => :patch)
res = @gvp.sort_dep_specs(
- build_spec_group("foo", %w(1.5.4 1.6.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 2.0.0 2.0.1)),
+ build_spec_groups("foo", %w[1.5.4 1.6.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 2.0.0 2.0.1]),
build_spec("foo", "1.7.7").first
)
- expect(versions(res)).to eq %w(1.5.4 1.6.5 1.7.6 2.0.0 2.0.1 1.8.0 1.8.1 1.7.8 1.7.9 1.7.7)
+ expect(versions(res)).to eq %w[1.5.4 1.6.5 1.7.6 2.0.0 2.0.1 1.8.0 1.8.1 1.7.8 1.7.9 1.7.7]
end
it "when unlocking favor next release, then current over minor increase" do
unlocking(:level => :patch)
res = @gvp.sort_dep_specs(
- build_spec_group("foo", %w(1.7.7 1.7.8 1.7.9 1.8.0)),
+ build_spec_groups("foo", %w[1.7.7 1.7.8 1.7.9 1.8.0]),
build_spec("foo", "1.7.8").first
)
- expect(versions(res)).to eq %w(1.7.7 1.8.0 1.7.8 1.7.9)
+ expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9]
end
it "when unlocking do proper integer comparison, not string" do
unlocking(:level => :patch)
res = @gvp.sort_dep_specs(
- build_spec_group("foo", %w(1.7.7 1.7.8 1.7.9 1.7.15 1.8.0)),
+ build_spec_groups("foo", %w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0]),
build_spec("foo", "1.7.8").first
)
- expect(versions(res)).to eq %w(1.7.7 1.8.0 1.7.8 1.7.9 1.7.15)
+ expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9 1.7.15]
end
it "leave current when unlocking but already at latest release" do
unlocking(:level => :patch)
res = @gvp.sort_dep_specs(
- build_spec_group("foo", %w(1.7.9 1.8.0 2.0.0)),
+ build_spec_groups("foo", %w[1.7.9 1.8.0 2.0.0]),
build_spec("foo", "1.7.9").first
)
- expect(versions(res)).to eq %w(2.0.0 1.8.0 1.7.9)
+ expect(versions(res)).to eq %w[2.0.0 1.8.0 1.7.9]
end
end
@@ -131,10 +132,10 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking favor next release, then minor increase over current" do
unlocking(:level => :minor)
res = @gvp.sort_dep_specs(
- build_spec_group("foo", %w(0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1)),
+ build_spec_groups("foo", %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]),
build_spec("foo", "0.2.0").first
)
- expect(versions(res)).to eq %w(2.0.0 2.0.1 1.0.0 0.2.0 0.3.0 0.3.1 0.9.0)
+ expect(versions(res)).to eq %w[2.0.0 2.0.1 1.0.0 0.2.0 0.3.0 0.3.1 0.9.0]
end
end
@@ -159,7 +160,7 @@ RSpec.describe Bundler::GemVersionPromoter do
end
it "should accept major, minor patch strings" do
- %w(major minor patch).each do |value|
+ %w[major minor patch].each do |value|
subject.level = value
expect(subject.level).to eq value.to_sym
end
@@ -169,9 +170,8 @@ RSpec.describe Bundler::GemVersionPromoter do
context "debug output" do
it "should not kerblooie on its own debug output" do
gvp = unlocking(:level => :patch)
- dep = Bundler::DepProxy.new(dep("foo", "1.2.0").first, "ruby")
- result = gvp.send(:debug_format_result, dep, [build_spec_group("foo", "1.2.0"),
- build_spec_group("foo", "1.3.0")])
+ dep = Bundler::DepProxy.get_proxy(dep("foo", "1.2.0").first, "ruby")
+ result = gvp.send(:debug_format_result, dep, build_spec_groups("foo", %w[1.2.0 1.3.0]))
expect(result.class).to eq Array
end
end
diff --git a/spec/bundler/bundler/index_spec.rb b/spec/bundler/bundler/index_spec.rb
index 09b09e08fa..0f3f6e4944 100644
--- a/spec/bundler/bundler/index_spec.rb
+++ b/spec/bundler/bundler/index_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Index do
let(:specs) { [] }
diff --git a/spec/bundler/bundler/installer/gem_installer_spec.rb b/spec/bundler/bundler/installer/gem_installer_spec.rb
index e2f30cdd70..8f8d1c6d15 100644
--- a/spec/bundler/bundler/installer/gem_installer_spec.rb
+++ b/spec/bundler/bundler/installer/gem_installer_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/installer/gem_installer"
RSpec.describe Bundler::GemInstaller do
@@ -10,19 +10,31 @@ RSpec.describe Bundler::GemInstaller do
subject { described_class.new(spec, installer) }
context "spec_settings is nil" do
- it "invokes install method with empty build_args", :rubygems => ">= 2" do
+ it "invokes install method with empty build_args" do
allow(spec_source).to receive(:install).with(spec, :force => false, :ensure_builtin_gems_cached => false, :build_args => [])
subject.install_from_spec
end
end
context "spec_settings is build option" do
- it "invokes install method with build_args", :rubygems => ">= 2" do
+ it "invokes install method with build_args" do
allow(Bundler.settings).to receive(:[]).with(:bin)
allow(Bundler.settings).to receive(:[]).with(:inline)
+ allow(Bundler.settings).to receive(:[]).with(:forget_cli_options)
allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy")
expect(spec_source).to receive(:install).with(spec, :force => false, :ensure_builtin_gems_cached => false, :build_args => ["--with-dummy-config=dummy"])
subject.install_from_spec
end
end
+
+ context "spec_settings is build option with spaces" do
+ it "invokes install method with build_args" do
+ allow(Bundler.settings).to receive(:[]).with(:bin)
+ allow(Bundler.settings).to receive(:[]).with(:inline)
+ allow(Bundler.settings).to receive(:[]).with(:forget_cli_options)
+ allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy --with-another-dummy-config")
+ expect(spec_source).to receive(:install).with(spec, :force => false, :ensure_builtin_gems_cached => false, :build_args => ["--with-dummy-config=dummy", "--with-another-dummy-config"])
+ subject.install_from_spec
+ end
+ end
end
diff --git a/spec/bundler/bundler/installer/parallel_installer_spec.rb b/spec/bundler/bundler/installer/parallel_installer_spec.rb
index 7d2c441399..e680633862 100644
--- a/spec/bundler/bundler/installer/parallel_installer_spec.rb
+++ b/spec/bundler/bundler/installer/parallel_installer_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/installer/parallel_installer"
RSpec.describe Bundler::ParallelInstaller do
@@ -44,4 +44,37 @@ The missing gems are:
end
end
end
+
+ context "when the spec set is not a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.4.4"),
+ ].flatten
+ end
+
+ it "prints a warning" do
+ expect(Bundler.ui).to receive(:warn).with(<<-W.strip)
+Your lockfile doesn't include a valid resolution.
+You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies.
+The unmet dependencies are:
+* diff-lcs (< 1.4), depended upon cucumber-4.1.0, unsatisfied by diff-lcs-1.4.4
+ W
+ subject.check_for_unmet_dependencies
+ end
+ end
+
+ context "when the spec set is a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.3"),
+ ].flatten
+ end
+
+ it "doesn't print a warning" do
+ expect(Bundler.ui).not_to receive(:warn)
+ subject.check_for_unmet_dependencies
+ end
+ end
end
diff --git a/spec/bundler/bundler/installer/spec_installation_spec.rb b/spec/bundler/bundler/installer/spec_installation_spec.rb
index 1e368ab7c5..e63ef26cb3 100644
--- a/spec/bundler/bundler/installer/spec_installation_spec.rb
+++ b/spec/bundler/bundler/installer/spec_installation_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/installer/parallel_installer"
RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
@@ -8,6 +8,10 @@ RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
def a_spec.name
"I like tests"
end
+
+ def a_spec.full_name
+ "I really like tests"
+ end
a_spec
end
diff --git a/spec/bundler/bundler/lockfile_parser_spec.rb b/spec/bundler/bundler/lockfile_parser_spec.rb
index 17bb447194..3a6d61336f 100644
--- a/spec/bundler/bundler/lockfile_parser_spec.rb
+++ b/spec/bundler/bundler/lockfile_parser_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/lockfile_parser"
RSpec.describe Bundler::LockfileParser do
@@ -91,4 +91,63 @@ RSpec.describe Bundler::LockfileParser do
end
end
end
+
+ describe "#initialize" do
+ before { allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app("gems.rb")) }
+ subject { described_class.new(lockfile_contents) }
+
+ let(:sources) do
+ [Bundler::Source::Git.new("uri" => "https://github.com/alloy/peiji-san.git", "revision" => "eca485d8dc95f12aaec1a434b49d295c7e91844b"),
+ Bundler::Source::Rubygems.new("remotes" => ["https://rubygems.org"])]
+ end
+ let(:dependencies) do
+ {
+ "peiji-san" => Bundler::Dependency.new("peiji-san", ">= 0"),
+ "rake" => Bundler::Dependency.new("rake", ">= 0"),
+ }
+ end
+ let(:specs) do
+ [
+ Bundler::LazySpecification.new("peiji-san", v("1.2.0"), rb),
+ Bundler::LazySpecification.new("rake", v("10.3.2"), rb),
+ ]
+ end
+ let(:platforms) { [rb] }
+ let(:bundler_version) { Gem::Version.new("1.12.0.rc.2") }
+ let(:ruby_version) { "ruby 2.1.3p242" }
+
+ shared_examples_for "parsing" do
+ it "parses correctly" do
+ expect(subject.sources).to eq sources
+ expect(subject.dependencies).to eq dependencies
+ expect(subject.specs).to eq specs
+ expect(Hash[subject.specs.map {|s| [s, s.dependencies] }]).to eq Hash[subject.specs.map {|s| [s, s.dependencies] }]
+ expect(subject.platforms).to eq platforms
+ expect(subject.bundler_version).to eq bundler_version
+ expect(subject.ruby_version).to eq ruby_version
+ end
+ end
+
+ include_examples "parsing"
+
+ context "when an extra section is at the end" do
+ let(:lockfile_contents) { super() + "\n\nFOO BAR\n baz\n baa\n qux\n" }
+ include_examples "parsing"
+ end
+
+ context "when an extra section is at the start" do
+ let(:lockfile_contents) { "FOO BAR\n baz\n baa\n qux\n\n" + super() }
+ include_examples "parsing"
+ end
+
+ context "when an extra section is in the middle" do
+ let(:lockfile_contents) { super().split(/(?=GEM)/).insert(1, "FOO BAR\n baz\n baa\n qux\n\n").join }
+ include_examples "parsing"
+ end
+
+ context "when a dependency has options" do
+ let(:lockfile_contents) { super().sub("peiji-san!", "peiji-san!\n foo: bar") }
+ include_examples "parsing"
+ end
+ end
end
diff --git a/spec/bundler/bundler/mirror_spec.rb b/spec/bundler/bundler/mirror_spec.rb
index 9051a80465..1eaf1e9a8e 100644
--- a/spec/bundler/bundler/mirror_spec.rb
+++ b/spec/bundler/bundler/mirror_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/mirror"
RSpec.describe Bundler::Settings::Mirror do
@@ -36,12 +36,12 @@ RSpec.describe Bundler::Settings::Mirror do
it "takes a string for the uri but returns an uri object" do
mirror.uri = "http://localhost:9292"
- expect(mirror.uri).to eq(URI("http://localhost:9292"))
+ expect(mirror.uri).to eq(Bundler::URI("http://localhost:9292"))
end
it "takes an uri object for the uri" do
- mirror.uri = URI("http://localhost:9293")
- expect(mirror.uri).to eq(URI("http://localhost:9293"))
+ mirror.uri = Bundler::URI("http://localhost:9293")
+ expect(mirror.uri).to eq(Bundler::URI("http://localhost:9293"))
end
context "without a uri" do
@@ -145,7 +145,7 @@ RSpec.describe Bundler::Settings::Mirror do
end
RSpec.describe Bundler::Settings::Mirrors do
- let(:localhost_uri) { URI("http://localhost:9292") }
+ let(:localhost_uri) { Bundler::URI("http://localhost:9292") }
context "with a just created mirror" do
let(:mirrors) do
@@ -260,7 +260,7 @@ RSpec.describe Bundler::Settings::Mirrors do
before { mirrors.parse("mirror.all.fallback_timeout", "true") }
it "returns the source uri, not localhost" do
- expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/"))
+ expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/"))
end
end
end
@@ -270,7 +270,7 @@ RSpec.describe Bundler::Settings::Mirrors do
context "without a fallback timeout" do
it "returns the uri that is not mirrored" do
- expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/"))
+ expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/"))
end
it "returns localhost for rubygems.org" do
@@ -282,11 +282,11 @@ RSpec.describe Bundler::Settings::Mirrors do
before { mirrors.parse("mirror.http://rubygems.org/.fallback_timeout", "true") }
it "returns the uri that is not mirrored" do
- expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/"))
+ expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/"))
end
it "returns rubygems.org for rubygems.org" do
- expect(mirrors.for("http://rubygems.org/").uri).to eq(URI("http://rubygems.org/"))
+ expect(mirrors.for("http://rubygems.org/").uri).to eq(Bundler::URI("http://rubygems.org/"))
end
end
end
@@ -298,13 +298,15 @@ RSpec.describe Bundler::Settings::TCPSocketProbe do
context "with a listening TCP Server" do
def with_server_and_mirror
- server = TCPServer.new("127.0.0.1", 0)
- mirror = Bundler::Settings::Mirror.new("http://localhost:#{server.addr[1]}", 1)
+ server = TCPServer.new("0.0.0.0", 0)
+ mirror = Bundler::Settings::Mirror.new("http://0.0.0.0:#{server.addr[1]}", 1)
yield server, mirror
server.close unless server.closed?
end
it "probes the server correctly" do
+ skip "obscure error" if Gem.win_platform?
+
with_server_and_mirror do |server, mirror|
expect(server.closed?).to be_falsey
expect(probe.replies?(mirror)).to be_truthy
diff --git a/spec/bundler/bundler/plugin/api/source_spec.rb b/spec/bundler/bundler/plugin/api/source_spec.rb
index 4dbb993b89..428ceb220a 100644
--- a/spec/bundler/bundler/plugin/api/source_spec.rb
+++ b/spec/bundler/bundler/plugin/api/source_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Plugin::API::Source do
let(:uri) { "uri://to/test" }
@@ -37,7 +36,7 @@ RSpec.describe Bundler::Plugin::API::Source do
context "install_path" do
let(:uri) { "uri://to/a/repository-name" }
- let(:hash) { Digest::SHA1.hexdigest(uri) }
+ let(:hash) { Digest(:SHA1).hexdigest(uri) }
let(:install_path) { Pathname.new "/bundler/install/path" }
before do
@@ -80,4 +79,10 @@ RSpec.describe Bundler::Plugin::API::Source do
end
end
end
+
+ describe "to_s" do
+ it "returns the string with type and uri" do
+ expect(source.to_s).to eq("plugin source for spec_type with uri uri://to/test")
+ end
+ end
end
diff --git a/spec/bundler/bundler/plugin/api_spec.rb b/spec/bundler/bundler/plugin/api_spec.rb
index e40b9adb0f..58fb908572 100644
--- a/spec/bundler/bundler/plugin/api_spec.rb
+++ b/spec/bundler/bundler/plugin/api_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Plugin::API do
context "plugin declarations" do
@@ -60,15 +59,15 @@ RSpec.describe Bundler::Plugin::API do
# A test of delegation
it "provides the Bundler's functions" do
- expect(Bundler).to receive(:an_unkown_function).once
+ expect(Bundler).to receive(:an_unknown_function).once
- api.an_unkown_function
+ api.an_unknown_function
end
it "includes Bundler::SharedHelpers' functions" do
- expect(Bundler::SharedHelpers).to receive(:an_unkown_helper).once
+ expect(Bundler::SharedHelpers).to receive(:an_unknown_helper).once
- api.an_unkown_helper
+ api.an_unknown_helper
end
context "#tmp" do
diff --git a/spec/bundler/bundler/plugin/dsl_spec.rb b/spec/bundler/bundler/plugin/dsl_spec.rb
index cd15b6ea9d..00e39dca69 100644
--- a/spec/bundler/bundler/plugin/dsl_spec.rb
+++ b/spec/bundler/bundler/plugin/dsl_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Plugin::DSL do
DSL = Bundler::Plugin::DSL
@@ -29,7 +28,7 @@ RSpec.describe Bundler::Plugin::DSL do
expect(dsl.inferred_plugins).to eq(["bundler-source-news"])
end
- it "registers a source type plugin only once for multiple declataions" do
+ it "registers a source type plugin only once for multiple declarations" do
expect(dsl).to receive(:plugin).with("bundler-source-news").and_call_original.once
dsl.source("some_random_url", :type => "news") {}
diff --git a/spec/bundler/bundler/plugin/events_spec.rb b/spec/bundler/bundler/plugin/events_spec.rb
new file mode 100644
index 0000000000..28d70c6fdd
--- /dev/null
+++ b/spec/bundler/bundler/plugin/events_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+RSpec.describe Bundler::Plugin::Events do
+ context "plugin events" do
+ before { Bundler::Plugin::Events.send :reset }
+
+ describe "#define" do
+ it "raises when redefining a constant" do
+ Bundler::Plugin::Events.send(:define, :TEST_EVENT, "foo")
+
+ expect do
+ Bundler::Plugin::Events.send(:define, :TEST_EVENT, "bar")
+ end.to raise_error(ArgumentError)
+ end
+
+ it "can define a new constant" do
+ Bundler::Plugin::Events.send(:define, :NEW_CONSTANT, "value")
+ expect(Bundler::Plugin::Events::NEW_CONSTANT).to eq("value")
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/plugin/index_spec.rb b/spec/bundler/bundler/plugin/index_spec.rb
index 24b9a408ff..d34b0de342 100644
--- a/spec/bundler/bundler/plugin/index_spec.rb
+++ b/spec/bundler/bundler/plugin/index_spec.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Plugin::Index do
Index = Bundler::Plugin::Index
before do
- gemfile ""
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ gemfile "source \"#{file_uri_for(gem_repo1)}\""
path = lib_path(plugin_name)
index.register_plugin("new-plugin", path.to_s, [path.join("lib").to_s], commands, sources, hooks)
end
@@ -22,7 +22,7 @@ RSpec.describe Bundler::Plugin::Index do
expect(index.plugin_path(plugin_name)).to eq(lib_path(plugin_name))
end
- it "load_paths is available for retrival" do
+ it "load_paths is available for retrieval" do
expect(index.load_paths(plugin_name)).to eq([lib_path(plugin_name).join("lib").to_s])
end
@@ -87,7 +87,24 @@ RSpec.describe Bundler::Plugin::Index do
expect(new_index.hook_plugins("after-bar")).to eq([plugin_name])
end
- context "that are not registered", :focused do
+ it "only registers a gem once for an event" do
+ path = lib_path(plugin_name)
+ index.register_plugin(plugin_name,
+ path.to_s,
+ [path.join("lib").to_s],
+ commands,
+ sources,
+ hooks + hooks)
+ expect(index.hook_plugins("after-bar")).to eq([plugin_name])
+ end
+
+ it "is gone after unregistration" do
+ expect(index.index_file.read).to include("after-bar:\n - \"new-plugin\"\n")
+ index.unregister_plugin(plugin_name)
+ expect(index.index_file.read).to_not include("after-bar:\n - \n")
+ end
+
+ context "that are not registered" do
let(:file) { double("index-file") }
before do
@@ -107,11 +124,11 @@ RSpec.describe Bundler::Plugin::Index do
describe "global index" do
before do
- Dir.chdir(tmp) do
- Bundler::Plugin.reset!
- path = lib_path("gplugin")
- index.register_plugin("gplugin", path.to_s, [path.join("lib").to_s], [], ["glb_source"], [])
- end
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(nil)
+
+ Bundler::Plugin.reset!
+ path = lib_path("gplugin")
+ index.register_plugin("gplugin", path.to_s, [path.join("lib").to_s], [], ["glb_source"], [])
end
it "skips sources" do
@@ -176,4 +193,12 @@ RSpec.describe Bundler::Plugin::Index do
include_examples "it cleans up"
end
end
+
+ describe "readonly disk without home" do
+ it "ignores being unable to create temp home dir" do
+ expect_any_instance_of(Bundler::Plugin::Index).to receive(:global_index_file).
+ and_raise(Bundler::GenericSystemCallError.new("foo", "bar"))
+ Bundler::Plugin::Index.new
+ end
+ end
end
diff --git a/spec/bundler/bundler/plugin/installer_spec.rb b/spec/bundler/bundler/plugin/installer_spec.rb
index e8d5941e33..e89720f6f7 100644
--- a/spec/bundler/bundler/plugin/installer_spec.rb
+++ b/spec/bundler/bundler/plugin/installer_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Plugin::Installer do
subject(:installer) { Bundler::Plugin::Installer.new }
@@ -7,6 +6,7 @@ RSpec.describe Bundler::Plugin::Installer do
describe "cli install" do
it "uses Gem.sources when non of the source is provided" do
sources = double(:sources)
+ Bundler.settings # initialize it before we have to touch rubygems.ext_lock
allow(Bundler).to receive_message_chain("rubygems.sources") { sources }
allow(installer).to receive(:install_rubygems).
@@ -25,6 +25,14 @@ RSpec.describe Bundler::Plugin::Installer do
to eq("new-plugin" => spec)
end
+ it "returns the installed spec after installing local git plugins" do
+ allow(installer).to receive(:install_local_git).
+ and_return("new-plugin" => spec)
+
+ expect(installer.install(["new-plugin"], :local_git => "/phony/path/repo")).
+ to eq("new-plugin" => spec)
+ end
+
it "returns the installed spec after installing rubygems plugins" do
allow(installer).to receive(:install_rubygems).
and_return("new-plugin" => spec)
@@ -50,7 +58,30 @@ RSpec.describe Bundler::Plugin::Installer do
end
let(:result) do
- installer.install(["ga-plugin"], :git => "file://#{lib_path("ga-plugin")}")
+ installer.install(["ga-plugin"], :git => file_uri_for(lib_path("ga-plugin")))
+ end
+
+ it "returns the installed spec after installing" do
+ spec = result["ga-plugin"]
+ expect(spec.full_name).to eq "ga-plugin-1.0"
+ end
+
+ it "has expected full_gem_path" do
+ rev = revision_for(lib_path("ga-plugin"))
+ expect(result["ga-plugin"].full_gem_path).
+ to eq(Bundler::Plugin.root.join("bundler", "gems", "ga-plugin-#{rev[0..11]}").to_s)
+ end
+ end
+
+ context "local git plugins" do
+ before do
+ build_git "ga-plugin", :path => lib_path("ga-plugin") do |s|
+ s.write "plugins.rb"
+ end
+ end
+
+ let(:result) do
+ installer.install(["ga-plugin"], :local_git => lib_path("ga-plugin").to_s)
end
it "returns the installed spec after installing" do
@@ -58,7 +89,7 @@ RSpec.describe Bundler::Plugin::Installer do
expect(spec.full_name).to eq "ga-plugin-1.0"
end
- it "has expected full gem path" do
+ it "has expected full_gem_path" do
rev = revision_for(lib_path("ga-plugin"))
expect(result["ga-plugin"].full_gem_path).
to eq(Bundler::Plugin.root.join("bundler", "gems", "ga-plugin-#{rev[0..11]}").to_s)
@@ -67,14 +98,14 @@ RSpec.describe Bundler::Plugin::Installer do
context "rubygems plugins" do
let(:result) do
- installer.install(["re-plugin"], :source => "file://#{gem_repo2}")
+ installer.install(["re-plugin"], :source => file_uri_for(gem_repo2))
end
it "returns the installed spec after installing " do
expect(result["re-plugin"]).to be_kind_of(Bundler::RemoteSpecification)
end
- it "has expected full_gem)path" do
+ it "has expected full_gem_path" do
expect(result["re-plugin"].full_gem_path).
to eq(global_plugin_gem("re-plugin-1.0").to_s)
end
@@ -82,7 +113,7 @@ RSpec.describe Bundler::Plugin::Installer do
context "multiple plugins" do
let(:result) do
- installer.install(["re-plugin", "ma-plugin"], :source => "file://#{gem_repo2}")
+ installer.install(["re-plugin", "ma-plugin"], :source => file_uri_for(gem_repo2))
end
it "returns the installed spec after installing " do
@@ -90,7 +121,7 @@ RSpec.describe Bundler::Plugin::Installer do
expect(result["ma-plugin"]).to be_kind_of(Bundler::RemoteSpecification)
end
- it "has expected full_gem)path" do
+ it "has expected full_gem_path" do
expect(result["re-plugin"].full_gem_path).to eq(global_plugin_gem("re-plugin-1.0").to_s)
expect(result["ma-plugin"].full_gem_path).to eq(global_plugin_gem("ma-plugin-1.0").to_s)
end
diff --git a/spec/bundler/bundler/plugin/source_list_spec.rb b/spec/bundler/bundler/plugin/source_list_spec.rb
index 86cc4ac4ed..64a1233dd1 100644
--- a/spec/bundler/bundler/plugin/source_list_spec.rb
+++ b/spec/bundler/bundler/plugin/source_list_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Plugin::SourceList do
SourceList = Bundler::Plugin::SourceList
diff --git a/spec/bundler/bundler/plugin_spec.rb b/spec/bundler/bundler/plugin_spec.rb
index 5bbb7384c8..25cae014dd 100644
--- a/spec/bundler/bundler/plugin_spec.rb
+++ b/spec/bundler/bundler/plugin_spec.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require "spec_helper"
+
+require_relative "../support/streams"
RSpec.describe Bundler::Plugin do
Plugin = Bundler::Plugin
@@ -33,6 +34,29 @@ RSpec.describe Bundler::Plugin do
allow(index).to receive(:register_plugin)
end
+ describe "list command" do
+ context "when no plugins are installed" do
+ before { allow(index).to receive(:installed_plugins) { [] } }
+ it "outputs no plugins installed" do
+ expect(Bundler.ui).to receive(:info).with("No plugins installed")
+ subject.list
+ end
+ end
+
+ context "with installed plugins" do
+ before do
+ allow(index).to receive(:installed_plugins) { %w[plug1 plug2] }
+ allow(index).to receive(:plugin_commands).with("plug1") { %w[c11 c12] }
+ allow(index).to receive(:plugin_commands).with("plug2") { %w[c21 c22] }
+ end
+ it "list plugins followed by commands" do
+ expected_output = "plug1\n-----\n c11\n c12\n\nplug2\n-----\n c21\n c22\n\n"
+ expect(Bundler.ui).to receive(:info).with(expected_output)
+ subject.list
+ end
+ end
+ end
+
describe "install command" do
let(:opts) { { "version" => "~> 1.0", "source" => "foo" } }
@@ -43,6 +67,8 @@ RSpec.describe Bundler::Plugin do
end
it "passes the name and options to installer" do
+ allow(index).to receive(:installed?).
+ with("new-plugin")
allow(installer).to receive(:install).with(["new-plugin"], opts) do
{ "new-plugin" => spec }
end.once
@@ -51,6 +77,8 @@ RSpec.describe Bundler::Plugin do
end
it "validates the installed plugin" do
+ allow(index).to receive(:installed?).
+ with("new-plugin")
allow(subject).
to receive(:validate_plugin!).with(lib_path("new-plugin")).once
@@ -58,6 +86,8 @@ RSpec.describe Bundler::Plugin do
end
it "registers the plugin with index" do
+ allow(index).to receive(:installed?).
+ with("new-plugin")
allow(index).to receive(:register_plugin).
with("new-plugin", lib_path("new-plugin").to_s, [lib_path("new-plugin").join("lib").to_s], []).once
subject.install ["new-plugin"], opts
@@ -74,6 +104,7 @@ RSpec.describe Bundler::Plugin do
end.once
allow(subject).to receive(:validate_plugin!).twice
+ allow(index).to receive(:installed?).twice
allow(index).to receive(:register_plugin).twice
subject.install ["new-plugin", "another-plugin"], opts
end
@@ -83,11 +114,12 @@ RSpec.describe Bundler::Plugin do
describe "evaluate gemfile for plugins" do
let(:definition) { double("definition") }
let(:builder) { double("builder") }
- let(:gemfile) { bundled_app("Gemfile") }
+ let(:gemfile) { bundled_app_gemfile }
before do
allow(Plugin::DSL).to receive(:new) { builder }
allow(builder).to receive(:eval_gemfile).with(gemfile)
+ allow(builder).to receive(:check_primary_source_safety)
allow(builder).to receive(:to_definition) { definition }
allow(builder).to receive(:inferred_plugins) { [] }
end
@@ -213,7 +245,7 @@ RSpec.describe Bundler::Plugin do
describe "#root" do
context "in app dir" do
before do
- gemfile ""
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
it "returns plugin dir in app .bundle path" do
@@ -222,13 +254,26 @@ RSpec.describe Bundler::Plugin do
end
context "outside app dir" do
+ before do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(nil)
+ end
+
it "returns plugin dir in global bundle path" do
- Dir.chdir tmp
expect(subject.root).to eq(home.join(".bundle/plugin"))
end
end
end
+ describe "#add_hook" do
+ it "raises an ArgumentError on an unregistered event" do
+ ran = false
+ expect do
+ Plugin.add_hook("unregistered-hook") { ran = true }
+ end.to raise_error(ArgumentError)
+ expect(ran).to be(false)
+ end
+ end
+
describe "#hook" do
before do
path = lib_path("foo-plugin")
@@ -236,7 +281,13 @@ RSpec.describe Bundler::Plugin do
s.write "plugins.rb", code
end
- allow(index).to receive(:hook_plugins).with(event).
+ Bundler::Plugin::Events.send(:reset)
+ Bundler::Plugin::Events.send(:define, :EVENT_1, "event-1")
+ Bundler::Plugin::Events.send(:define, :EVENT_2, "event-2")
+
+ allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT_1).
+ and_return(["foo-plugin", "", nil])
+ allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT_2).
and_return(["foo-plugin"])
allow(index).to receive(:plugin_path).with("foo-plugin").and_return(path)
allow(index).to receive(:load_paths).with("foo-plugin").and_return([])
@@ -246,11 +297,15 @@ RSpec.describe Bundler::Plugin do
Bundler::Plugin::API.hook("event-1") { puts "hook for event 1" }
RUBY
- let(:event) { "event-1" }
+ it "raises an ArgumentError on an unregistered event" do
+ expect do
+ Plugin.hook("unregistered-hook")
+ end.to raise_error(ArgumentError)
+ end
it "executes the hook" do
out = capture(:stdout) do
- Plugin.hook("event-1")
+ Plugin.hook(Bundler::Plugin::Events::EVENT_1)
end.strip
expect(out).to eq("hook for event 1")
@@ -258,17 +313,15 @@ RSpec.describe Bundler::Plugin do
context "single plugin declaring more than one hook" do
let(:code) { <<-RUBY }
- Bundler::Plugin::API.hook("event-1") {}
- Bundler::Plugin::API.hook("event-2") {}
+ Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_1) {}
+ Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_2) {}
puts "loaded"
RUBY
- let(:event) { /event-1|event-2/ }
-
it "evals plugins.rb once" do
out = capture(:stdout) do
- Plugin.hook("event-1")
- Plugin.hook("event-2")
+ Plugin.hook(Bundler::Plugin::Events::EVENT_1)
+ Plugin.hook(Bundler::Plugin::Events::EVENT_2)
end.strip
expect(out).to eq("loaded")
@@ -277,12 +330,12 @@ RSpec.describe Bundler::Plugin do
context "a block is passed" do
let(:code) { <<-RUBY }
- Bundler::Plugin::API.hook("#{event}") { |&blk| blk.call }
+ Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_1) { |&blk| blk.call }
RUBY
it "is passed to the hook" do
out = capture(:stdout) do
- Plugin.hook("event-1") { puts "win" }
+ Plugin.hook(Bundler::Plugin::Events::EVENT_1) { puts "win" }
end.strip
expect(out).to eq("win")
diff --git a/spec/bundler/bundler/psyched_yaml_spec.rb b/spec/bundler/bundler/psyched_yaml_spec.rb
index 18e40d6b5a..d5d68c5cc3 100644
--- a/spec/bundler/bundler/psyched_yaml_spec.rb
+++ b/spec/bundler/bundler/psyched_yaml_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/psyched_yaml"
RSpec.describe "Bundler::YamlLibrarySyntaxError" do
diff --git a/spec/bundler/bundler/remote_specification_spec.rb b/spec/bundler/bundler/remote_specification_spec.rb
index 644814c563..8115e026d8 100644
--- a/spec/bundler/bundler/remote_specification_spec.rb
+++ b/spec/bundler/bundler/remote_specification_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::RemoteSpecification do
let(:name) { "foo" }
diff --git a/spec/bundler/bundler/retry_spec.rb b/spec/bundler/bundler/retry_spec.rb
index 525f05d327..b893580d72 100644
--- a/spec/bundler/bundler/retry_spec.rb
+++ b/spec/bundler/bundler/retry_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Retry do
it "return successful result if no errors" do
diff --git a/spec/bundler/bundler/ruby_dsl_spec.rb b/spec/bundler/bundler/ruby_dsl_spec.rb
index 3e0ec9d7f0..bc1ca98457 100644
--- a/spec/bundler/bundler/ruby_dsl_spec.rb
+++ b/spec/bundler/bundler/ruby_dsl_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/ruby_dsl"
RSpec.describe Bundler::RubyDsl do
diff --git a/spec/bundler/bundler/ruby_version_spec.rb b/spec/bundler/bundler/ruby_version_spec.rb
index f77ec606fc..8c6c071d7f 100644
--- a/spec/bundler/bundler/ruby_version_spec.rb
+++ b/spec/bundler/bundler/ruby_version_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/ruby_version"
RSpec.describe "Bundler::RubyVersion and its subclasses" do
@@ -399,8 +399,22 @@ RSpec.describe "Bundler::RubyVersion and its subclasses" do
let(:bundler_system_ruby_version) { subject }
- before do
- Bundler::RubyVersion.instance_variable_set("@ruby_version", nil)
+ around do |example|
+ if Bundler::RubyVersion.instance_variable_defined?("@ruby_version")
+ begin
+ old_ruby_version = Bundler::RubyVersion.instance_variable_get("@ruby_version")
+ Bundler::RubyVersion.remove_instance_variable("@ruby_version")
+ example.run
+ ensure
+ Bundler::RubyVersion.instance_variable_set("@ruby_version", old_ruby_version)
+ end
+ else
+ begin
+ example.run
+ ensure
+ Bundler::RubyVersion.remove_instance_variable("@ruby_version")
+ end
+ end
end
it "should return an instance of Bundler::RubyVersion" do
@@ -420,70 +434,60 @@ RSpec.describe "Bundler::RubyVersion and its subclasses" do
end
describe "#engine" do
- context "RUBY_ENGINE is defined" do
- before { stub_const("RUBY_ENGINE", "jruby") }
- before { stub_const("JRUBY_VERSION", "2.1.1") }
+ before { stub_const("RUBY_ENGINE", "jruby") }
+ before { stub_const("RUBY_ENGINE_VERSION", "2.1.1") }
- it "should return a copy of the value of RUBY_ENGINE" do
- expect(subject.engine).to eq("jruby")
- expect(subject.engine).to_not be(RUBY_ENGINE)
- end
- end
-
- context "RUBY_ENGINE is not defined" do
- before { stub_const("RUBY_ENGINE", nil) }
-
- it "should return the string 'ruby'" do
- expect(subject.engine).to eq("ruby")
- end
+ it "should return a copy of the value of RUBY_ENGINE" do
+ expect(subject.engine).to eq("jruby")
+ expect(subject.engine).to_not be(RUBY_ENGINE)
end
end
describe "#engine_version" do
context "engine is ruby" do
before do
- stub_const("RUBY_VERSION", "2.2.4")
- allow(Bundler).to receive(:ruby_engine).and_return("ruby")
+ stub_const("RUBY_ENGINE_VERSION", "2.2.4")
+ stub_const("RUBY_ENGINE", "ruby")
end
- it "should return a copy of the value of RUBY_VERSION" do
+ it "should return a copy of the value of RUBY_ENGINE_VERSION" do
expect(bundler_system_ruby_version.engine_versions).to eq(["2.2.4"])
- expect(bundler_system_ruby_version.engine_versions.first).to_not be(RUBY_VERSION)
+ expect(bundler_system_ruby_version.engine_versions.first).to_not be(RUBY_ENGINE_VERSION)
end
end
context "engine is rbx" do
before do
stub_const("RUBY_ENGINE", "rbx")
- stub_const("Rubinius::VERSION", "2.0.0")
+ stub_const("RUBY_ENGINE_VERSION", "2.0.0")
end
- it "should return a copy of the value of Rubinius::VERSION" do
+ it "should return a copy of the value of RUBY_ENGINE_VERSION" do
expect(bundler_system_ruby_version.engine_versions).to eq(["2.0.0"])
- expect(bundler_system_ruby_version.engine_versions.first).to_not be(Rubinius::VERSION)
+ expect(bundler_system_ruby_version.engine_versions.first).to_not be(RUBY_ENGINE_VERSION)
end
end
context "engine is jruby" do
before do
stub_const("RUBY_ENGINE", "jruby")
- stub_const("JRUBY_VERSION", "2.1.1")
+ stub_const("RUBY_ENGINE_VERSION", "2.1.1")
end
- it "should return a copy of the value of JRUBY_VERSION" do
+ it "should return a copy of the value of RUBY_ENGINE_VERSION" do
expect(subject.engine_versions).to eq(["2.1.1"])
- expect(bundler_system_ruby_version.engine_versions.first).to_not be(JRUBY_VERSION)
+ expect(bundler_system_ruby_version.engine_versions.first).to_not be(RUBY_ENGINE_VERSION)
end
end
context "engine is some other ruby engine" do
before do
stub_const("RUBY_ENGINE", "not_supported_ruby_engine")
- allow(Bundler).to receive(:ruby_engine).and_return("not_supported_ruby_engine")
+ stub_const("RUBY_ENGINE_VERSION", "1.2.3")
end
- it "should raise a BundlerError with a 'not recognized' message" do
- expect { bundler_system_ruby_version.engine_versions }.to raise_error(Bundler::BundlerError, "RUBY_ENGINE value not_supported_ruby_engine is not recognized")
+ it "returns RUBY_ENGINE_VERSION" do
+ expect(bundler_system_ruby_version.engine_versions).to eq(["1.2.3"])
end
end
end
diff --git a/spec/bundler/bundler/rubygems_integration_spec.rb b/spec/bundler/bundler/rubygems_integration_spec.rb
index 38ff9dae7e..7557c806fe 100644
--- a/spec/bundler/bundler/rubygems_integration_spec.rb
+++ b/spec/bundler/bundler/rubygems_integration_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::RubygemsIntegration do
- it "uses the same chdir lock as rubygems", :rubygems => "2.1" do
+ it "uses the same chdir lock as rubygems" do
expect(Bundler.rubygems.ext_lock).to eq(Gem::Ext::Builder::CHDIR_MONITOR)
end
@@ -16,30 +15,18 @@ RSpec.describe Bundler::RubygemsIntegration do
end
subject { Bundler.rubygems.validate(spec) }
- it "skips overly-strict gemspec validation", :rubygems => "< 1.7" do
- expect(spec).to_not receive(:validate)
- subject
- end
-
- it "validates with packaging mode disabled", :rubygems => "1.7" do
+ it "validates with packaging mode disabled" do
expect(spec).to receive(:validate).with(false)
subject
end
- it "should set a summary to avoid an overly-strict error", :rubygems => "~> 1.7.0" do
- spec.summary = nil
- expect { subject }.not_to raise_error
- expect(spec.summary).to eq("")
- end
-
context "with an invalid spec" do
before do
expect(spec).to receive(:validate).with(false).
and_raise(Gem::InvalidSpecificationException.new("TODO is not an author"))
end
- it "should raise a Gem::InvalidSpecificationException and produce a helpful warning message",
- :rubygems => "1.7" do
+ it "should raise a Gem::InvalidSpecificationException and produce a helpful warning message" do
expect { subject }.to raise_error(Gem::InvalidSpecificationException,
"The gemspec at #{__FILE__} is not valid. "\
"Please fix this gemspec.\nThe validation error was 'TODO is not an author'\n")
@@ -54,48 +41,46 @@ RSpec.describe Bundler::RubygemsIntegration do
end
end
- describe "#download_gem", :rubygems => ">= 2.0" do
+ describe "#download_gem" do
let(:bundler_retry) { double(Bundler::Retry) }
- let(:retry) { double("Bundler::Retry") }
- let(:uri) { URI.parse("https://foo.bar") }
- let(:path) { Gem.path.first }
+ let(:uri) { Bundler::URI.parse("https://foo.bar") }
+ let(:cache_dir) { "#{Gem.path.first}/cache" }
let(:spec) do
- spec = Bundler::RemoteSpecification.new("Foo", Gem::Version.new("2.5.2"),
- Gem::Platform::RUBY, nil)
+ spec = Gem::Specification.new("Foo", Gem::Version.new("2.5.2"))
spec.remote = Bundler::Source::Rubygems::Remote.new(uri.to_s)
spec
end
let(:fetcher) { double("gem_remote_fetcher") }
- it "succesfully downloads gem with retries" do
+ it "successfully downloads gem with retries" do
expect(Bundler.rubygems).to receive(:gem_remote_fetcher).and_return(fetcher)
- expect(fetcher).to receive(:headers=).with("X-Gemfile-Source" => "https://foo.bar")
+ expect(fetcher).to receive(:headers=).with({ "X-Gemfile-Source" => "https://foo.bar" })
expect(Bundler::Retry).to receive(:new).with("download gem from #{uri}/").
and_return(bundler_retry)
expect(bundler_retry).to receive(:attempts).and_yield
- expect(fetcher).to receive(:download).with(spec, uri, path)
+ expect(fetcher).to receive(:cache_update_path)
- Bundler.rubygems.download_gem(spec, uri, path)
+ Bundler.rubygems.download_gem(spec, uri, cache_dir)
end
end
- describe "#fetch_all_remote_specs", :rubygems => ">= 2.0" do
- let(:uri) { URI("https://example.com") }
+ describe "#fetch_all_remote_specs" do
+ let(:uri) { "https://example.com" }
let(:fetcher) { double("gem_remote_fetcher") }
let(:specs_response) { Marshal.dump(["specs"]) }
let(:prerelease_specs_response) { Marshal.dump(["prerelease_specs"]) }
context "when a rubygems source mirror is set" do
- let(:orig_uri) { URI("http://zombo.com") }
+ let(:orig_uri) { Bundler::URI("http://zombo.com") }
let(:remote_with_mirror) { double("remote", :uri => uri, :original_uri => orig_uri) }
it "sets the 'X-Gemfile-Source' header containing the original source" do
expect(Bundler.rubygems).to receive(:gem_remote_fetcher).twice.and_return(fetcher)
- expect(fetcher).to receive(:headers=).with("X-Gemfile-Source" => "http://zombo.com").twice
+ expect(fetcher).to receive(:headers=).with({ "X-Gemfile-Source" => "http://zombo.com" }).twice
expect(fetcher).to receive(:fetch_path).with(uri + "specs.4.8.gz").and_return(specs_response)
expect(fetcher).to receive(:fetch_path).with(uri + "prerelease_specs.4.8.gz").and_return(prerelease_specs_response)
result = Bundler.rubygems.fetch_all_remote_specs(remote_with_mirror)
- expect(result).to eq(%w(specs prerelease_specs))
+ expect(result).to eq(%w[specs prerelease_specs])
end
end
@@ -108,7 +93,7 @@ RSpec.describe Bundler::RubygemsIntegration do
expect(fetcher).to receive(:fetch_path).with(uri + "specs.4.8.gz").and_return(specs_response)
expect(fetcher).to receive(:fetch_path).with(uri + "prerelease_specs.4.8.gz").and_return(prerelease_specs_response)
result = Bundler.rubygems.fetch_all_remote_specs(remote_no_mirror)
- expect(result).to eq(%w(specs prerelease_specs))
+ expect(result).to eq(%w[specs prerelease_specs])
end
end
end
diff --git a/spec/bundler/bundler/settings/validator_spec.rb b/spec/bundler/bundler/settings/validator_spec.rb
new file mode 100644
index 0000000000..e4ffd89435
--- /dev/null
+++ b/spec/bundler/bundler/settings/validator_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+RSpec.describe Bundler::Settings::Validator do
+ describe ".validate!" do
+ def validate!(key, value, settings)
+ transformed_key = Bundler.settings.key_for(key)
+ if value.nil?
+ settings.delete(transformed_key)
+ else
+ settings[transformed_key] = value
+ end
+ described_class.validate!(key, value, settings)
+ settings
+ end
+
+ it "path and path.system are mutually exclusive" do
+ expect(validate!("path", "bundle", {})).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path", "bundle", "BUNDLE_PATH__SYSTEM" => false)).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path", "bundle", "BUNDLE_PATH__SYSTEM" => true)).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path", nil, "BUNDLE_PATH__SYSTEM" => true)).to eq("BUNDLE_PATH__SYSTEM" => true)
+ expect(validate!("path", nil, "BUNDLE_PATH__SYSTEM" => false)).to eq("BUNDLE_PATH__SYSTEM" => false)
+ expect(validate!("path", nil, {})).to eq({})
+
+ expect(validate!("path.system", true, "BUNDLE_PATH" => "bundle")).to eq("BUNDLE_PATH__SYSTEM" => true)
+ expect(validate!("path.system", false, "BUNDLE_PATH" => "bundle")).to eq("BUNDLE_PATH" => "bundle", "BUNDLE_PATH__SYSTEM" => false)
+ expect(validate!("path.system", nil, "BUNDLE_PATH" => "bundle")).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path.system", true, {})).to eq("BUNDLE_PATH__SYSTEM" => true)
+ expect(validate!("path.system", false, {})).to eq("BUNDLE_PATH__SYSTEM" => false)
+ expect(validate!("path.system", nil, {})).to eq({})
+ end
+
+ it "a group cannot be in both `with` & `without` simultaneously" do
+ expect do
+ validate!("with", "", {})
+ validate!("with", nil, {})
+ validate!("with", "", "BUNDLE_WITHOUT" => "a")
+ validate!("with", nil, "BUNDLE_WITHOUT" => "a")
+ validate!("with", "b:c", "BUNDLE_WITHOUT" => "a")
+
+ validate!("without", "", {})
+ validate!("without", nil, {})
+ validate!("without", "", "BUNDLE_WITH" => "a")
+ validate!("without", nil, "BUNDLE_WITH" => "a")
+ validate!("without", "b:c", "BUNDLE_WITH" => "a")
+ end.not_to raise_error
+
+ expect { validate!("with", "b:c", "BUNDLE_WITHOUT" => "c:d") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
+ Setting `with` to "b:c" failed:
+ - a group cannot be in both `with` & `without` simultaneously
+ - `without` is current set to [:c, :d]
+ - the `c` groups conflict
+ EOS
+
+ expect { validate!("without", "b:c", "BUNDLE_WITH" => "c:d") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
+ Setting `without` to "b:c" failed:
+ - a group cannot be in both `with` & `without` simultaneously
+ - `with` is current set to [:c, :d]
+ - the `c` groups conflict
+ EOS
+ end
+ end
+
+ describe described_class::Rule do
+ let(:keys) { %w[key] }
+ let(:description) { "rule description" }
+ let(:validate) { proc { raise "validate called!" } }
+ subject(:rule) { described_class.new(keys, description, &validate) }
+
+ describe "#validate!" do
+ it "calls the block" do
+ expect { rule.validate!("key", nil, {}) }.to raise_error(RuntimeError, /validate called!/)
+ end
+ end
+
+ describe "#fail!" do
+ it "raises with a helpful message" do
+ expect { subject.fail!("key", "value", "reason1", "reason2") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
+ Setting `key` to "value" failed:
+ - rule description
+ - reason1
+ - reason2
+ EOS
+ end
+ end
+
+ describe "#set" do
+ it "works when the value has not changed" do
+ allow(Bundler.ui).to receive(:info).never
+
+ subject.set({}, "key", nil)
+ subject.set({ "BUNDLE_KEY" => "value" }, "key", "value")
+ end
+
+ it "prints out when the value is changing" do
+ settings = {}
+
+ expect(Bundler.ui).to receive(:info).with("Setting `key` to \"value\", since rule description, reason1")
+ subject.set(settings, "key", "value", "reason1")
+ expect(settings).to eq("BUNDLE_KEY" => "value")
+
+ expect(Bundler.ui).to receive(:info).with("Setting `key` to \"value2\", since rule description, reason2")
+ subject.set(settings, "key", "value2", "reason2")
+ expect(settings).to eq("BUNDLE_KEY" => "value2")
+
+ expect(Bundler.ui).to receive(:info).with("Setting `key` to nil, since rule description, reason3")
+ subject.set(settings, "key", nil, "reason3")
+ expect(settings).to eq({})
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/settings_spec.rb b/spec/bundler/bundler/settings_spec.rb
index 7302da5421..24e3de7ba8 100644
--- a/spec/bundler/bundler/settings_spec.rb
+++ b/spec/bundler/bundler/settings_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/settings"
RSpec.describe Bundler::Settings do
@@ -40,7 +40,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
before do
hash.each do |key, value|
- settings[key] = value
+ settings.set_local key, value
end
end
@@ -64,13 +64,10 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
describe "#global_config_file" do
context "when $HOME is not accessible" do
- context "when $TMPDIR is not writable" do
- it "does not raise" do
- expect(Bundler.rubygems).to receive(:user_home).twice.and_return(nil)
- expect(FileUtils).to receive(:mkpath).twice.with(File.join(Dir.tmpdir, "bundler", "home")).and_raise(Errno::EROFS, "Read-only file system @ dir_s_mkdir - /tmp/bundler")
+ it "does not raise" do
+ expect(Bundler.rubygems).to receive(:user_home).twice.and_return(nil)
- expect(subject.send(:global_config_file)).to be_nil
- end
+ expect(subject.send(:global_config_file)).to be_nil
end
end
end
@@ -100,12 +97,12 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
context "when is boolean" do
it "returns a boolean" do
- settings[:frozen] = "true"
+ settings.set_local :frozen, "true"
expect(settings[:frozen]).to be true
end
context "when specific gem is configured" do
it "returns a boolean" do
- settings["ignore_messages.foobar"] = "true"
+ settings.set_local "ignore_messages.foobar", "true"
expect(settings["ignore_messages.foobar"]).to be true
end
end
@@ -113,16 +110,16 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
context "when is number" do
it "returns a number" do
- settings[:ssl_verify_mode] = "1"
+ settings.set_local :ssl_verify_mode, "1"
expect(settings[:ssl_verify_mode]).to be 1
end
end
context "when it's not possible to write to the file" do
it "raises an PermissionError with explanation" do
- expect(FileUtils).to receive(:mkdir_p).with(settings.send(:local_config_file).dirname).
+ expect(::Bundler::FileUtils).to receive(:mkdir_p).with(settings.send(:local_config_file).dirname).
and_raise(Errno::EACCES)
- expect { settings[:frozen] = "1" }.
+ expect { settings.set_local :frozen, "1" }.
to raise_error(Bundler::PermissionError, /config/)
end
end
@@ -130,20 +127,40 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
describe "#temporary" do
it "reset after used" do
- Bundler.settings[:no_install] = true
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+
+ Bundler.settings.set_command_option :no_install, true
Bundler.settings.temporary(:no_install => false) do
expect(Bundler.settings[:no_install]).to eq false
end
expect(Bundler.settings[:no_install]).to eq true
+
+ Bundler.settings.set_command_option :no_install, nil
+ end
+
+ it "returns the return value of the block" do
+ ret = Bundler.settings.temporary({}) { :ret }
+ expect(ret).to eq :ret
+ end
+
+ context "when called without a block" do
+ it "leaves the setting changed" do
+ Bundler.settings.temporary(:foo => :random)
+ expect(Bundler.settings[:foo]).to eq "random"
+ end
+
+ it "returns nil" do
+ expect(Bundler.settings.temporary(:foo => :bar)).to be_nil
+ end
end
end
describe "#set_global" do
context "when it's not possible to write to the file" do
it "raises an PermissionError with explanation" do
- expect(FileUtils).to receive(:mkdir_p).with(settings.send(:global_config_file).dirname).
+ expect(::Bundler::FileUtils).to receive(:mkdir_p).with(settings.send(:global_config_file).dirname).
and_raise(Errno::EACCES)
expect { settings.set_global(:frozen, "1") }.
to raise_error(Bundler::PermissionError, %r{\.bundle/config})
@@ -154,7 +171,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
describe "#pretty_values_for" do
it "prints the converted value rather than the raw string" do
bool_key = described_class::BOOL_KEYS.first
- settings[bool_key] = false
+ settings.set_local(bool_key, "false")
expect(subject.pretty_values_for(bool_key)).to eq [
"Set for your local app (#{bundled_app("config")}): false",
]
@@ -162,7 +179,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
describe "#mirror_for" do
- let(:uri) { URI("https://rubygems.org/") }
+ let(:uri) { Bundler::URI("https://rubygems.org/") }
context "with no configured mirror" do
it "returns the original URI" do
@@ -175,9 +192,9 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
context "with a configured mirror" do
- let(:mirror_uri) { URI("https://rubygems-mirror.org/") }
+ let(:mirror_uri) { Bundler::URI("https://rubygems-mirror.org/") }
- before { settings["mirror.https://rubygems.org/"] = mirror_uri.to_s }
+ before { settings.set_local "mirror.https://rubygems.org/", mirror_uri.to_s }
it "returns the mirror URI" do
expect(settings.mirror_for(uri)).to eq(mirror_uri)
@@ -194,11 +211,27 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
it "is case insensitive" do
expect(settings.mirror_for("HTTPS://RUBYGEMS.ORG/")).to eq(mirror_uri)
end
+
+ context "with a file URI" do
+ let(:mirror_uri) { Bundler::URI("file:/foo/BAR/baz/qUx/") }
+
+ it "returns the mirror URI" do
+ expect(settings.mirror_for(uri)).to eq(mirror_uri)
+ end
+
+ it "converts a string parameter to a URI" do
+ expect(settings.mirror_for("file:/foo/BAR/baz/qUx/")).to eq(mirror_uri)
+ end
+
+ it "normalizes the URI" do
+ expect(settings.mirror_for("file:/foo/BAR/baz/qUx")).to eq(mirror_uri)
+ end
+ end
end
end
describe "#credentials_for" do
- let(:uri) { URI("https://gemserver.example.org/") }
+ let(:uri) { Bundler::URI("https://gemserver.example.org/") }
let(:credentials) { "username:password" }
context "with no configured credentials" do
@@ -208,7 +241,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
context "with credentials configured by URL" do
- before { settings["https://gemserver.example.org/"] = credentials }
+ before { settings.set_local "https://gemserver.example.org/", credentials }
it "returns the configured credentials" do
expect(settings.credentials_for(uri)).to eq(credentials)
@@ -216,7 +249,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
context "with credentials configured by hostname" do
- before { settings["gemserver.example.org"] = credentials }
+ before { settings.set_local "gemserver.example.org", credentials }
it "returns the configured credentials" do
expect(settings.credentials_for(uri)).to eq(credentials)
@@ -226,56 +259,76 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
describe "URI normalization" do
it "normalizes HTTP URIs in credentials configuration" do
- settings["http://gemserver.example.org"] = "username:password"
+ settings.set_local "http://gemserver.example.org", "username:password"
expect(settings.all).to include("http://gemserver.example.org/")
end
it "normalizes HTTPS URIs in credentials configuration" do
- settings["https://gemserver.example.org"] = "username:password"
+ settings.set_local "https://gemserver.example.org", "username:password"
expect(settings.all).to include("https://gemserver.example.org/")
end
it "normalizes HTTP URIs in mirror configuration" do
- settings["mirror.http://rubygems.org"] = "http://rubygems-mirror.org"
+ settings.set_local "mirror.http://rubygems.org", "http://rubygems-mirror.org"
expect(settings.all).to include("mirror.http://rubygems.org/")
end
it "normalizes HTTPS URIs in mirror configuration" do
- settings["mirror.https://rubygems.org"] = "http://rubygems-mirror.org"
+ settings.set_local "mirror.https://rubygems.org", "http://rubygems-mirror.org"
expect(settings.all).to include("mirror.https://rubygems.org/")
end
it "does not normalize other config keys that happen to contain 'http'" do
- settings["local.httparty"] = home("httparty")
+ settings.set_local "local.httparty", home("httparty")
expect(settings.all).to include("local.httparty")
end
it "does not normalize other config keys that happen to contain 'https'" do
- settings["local.httpsmarty"] = home("httpsmarty")
+ settings.set_local "local.httpsmarty", home("httpsmarty")
expect(settings.all).to include("local.httpsmarty")
end
it "reads older keys without trailing slashes" do
- settings["mirror.https://rubygems.org"] = "http://rubygems-mirror.org"
+ settings.set_local "mirror.https://rubygems.org", "http://rubygems-mirror.org"
expect(settings.mirror_for("https://rubygems.org/")).to eq(
- URI("http://rubygems-mirror.org/")
+ Bundler::URI("http://rubygems-mirror.org/")
)
end
+
+ it "normalizes URIs with a fallback_timeout option" do
+ settings.set_local "mirror.https://rubygems.org/.fallback_timeout", "true"
+ expect(settings.all).to include("mirror.https://rubygems.org/.fallback_timeout")
+ end
+
+ it "normalizes URIs with a fallback_timeout option without a trailing slash" do
+ settings.set_local "mirror.https://rubygems.org.fallback_timeout", "true"
+ expect(settings.all).to include("mirror.https://rubygems.org/.fallback_timeout")
+ end
end
describe "BUNDLE_ keys format" do
let(:settings) { described_class.new(bundled_app(".bundle")) }
- it "converts older keys without double dashes" do
+ it "converts older keys without double underscore" do
config("BUNDLE_MY__PERSONAL.RACK" => "~/Work/git/rack")
expect(settings["my.personal.rack"]).to eq("~/Work/git/rack")
end
- it "converts older keys without trailing slashes and double dashes" do
+ it "converts older keys without trailing slashes and double underscore" do
config("BUNDLE_MIRROR__HTTPS://RUBYGEMS.ORG" => "http://rubygems-mirror.org")
expect(settings["mirror.https://rubygems.org/"]).to eq("http://rubygems-mirror.org")
end
+ it "converts older keys with dashes" do
+ config("BUNDLE_MY-PERSONAL-SERVER__ORG" => "my-personal-server.org")
+ expect(Bundler.ui).to receive(:warn).with(
+ "Your #{bundled_app(".bundle/config")} config includes `BUNDLE_MY-PERSONAL-SERVER__ORG`, which contains the dash character (`-`).\n" \
+ "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
+ "Please edit #{bundled_app(".bundle/config")} and replace any dashes in configuration keys with a triple underscore (`___`)."
+ )
+ expect(settings["my-personal-server.org"]).to eq("my-personal-server.org")
+ end
+
it "reads newer keys format properly" do
config("BUNDLE_MIRROR__HTTPS://RUBYGEMS__ORG/" => "http://rubygems-mirror.org")
expect(settings["mirror.https://rubygems.org/"]).to eq("http://rubygems-mirror.org")
diff --git a/spec/bundler/bundler/shared_helpers_spec.rb b/spec/bundler/bundler/shared_helpers_spec.rb
index d3b93b56d0..97647dc6eb 100644
--- a/spec/bundler/bundler/shared_helpers_spec.rb
+++ b/spec/bundler/bundler/shared_helpers_spec.rb
@@ -1,21 +1,23 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::SharedHelpers do
let(:ext_lock_double) { double(:ext_lock) }
before do
+ pwd_stub
allow(Bundler.rubygems).to receive(:ext_lock).and_return(ext_lock_double)
allow(ext_lock_double).to receive(:synchronize) {|&block| block.call }
end
+ let(:pwd_stub) { allow(subject).to receive(:pwd).and_return(bundled_app) }
+
subject { Bundler::SharedHelpers }
describe "#default_gemfile" do
before { ENV["BUNDLE_GEMFILE"] = "/path/Gemfile" }
context "Gemfile is present" do
- let(:expected_gemfile_path) { Pathname.new("/path/Gemfile") }
+ let(:expected_gemfile_path) { Pathname.new("/path/Gemfile").expand_path }
it "returns the Gemfile path" do
expect(subject.default_gemfile).to eq(expected_gemfile_path)
@@ -31,6 +33,16 @@ RSpec.describe Bundler::SharedHelpers do
)
end
end
+
+ context "Gemfile is not an absolute path" do
+ before { ENV["BUNDLE_GEMFILE"] = "Gemfile" }
+
+ let(:expected_gemfile_path) { Pathname.new("Gemfile").expand_path }
+
+ it "returns the Gemfile path" do
+ expect(subject.default_gemfile).to eq(expected_gemfile_path)
+ end
+ end
end
describe "#default_lockfile" do
@@ -65,10 +77,10 @@ RSpec.describe Bundler::SharedHelpers do
end
context ".bundle is global .bundle" do
- let(:global_rubygems_dir) { Pathname.new("#{bundled_app}") }
+ let(:global_rubygems_dir) { Pathname.new(bundled_app) }
before do
- Dir.mkdir ".bundle"
+ Dir.mkdir bundled_app(".bundle")
allow(Bundler.rubygems).to receive(:user_home).and_return(global_rubygems_dir)
end
@@ -82,7 +94,7 @@ RSpec.describe Bundler::SharedHelpers do
let(:expected_bundle_dir_path) { Pathname.new("#{bundled_app}/.bundle") }
before do
- Dir.mkdir ".bundle"
+ Dir.mkdir bundled_app(".bundle")
allow(Bundler.rubygems).to receive(:user_home).and_return(global_rubygems_dir)
end
@@ -100,9 +112,10 @@ RSpec.describe Bundler::SharedHelpers do
shared_examples_for "correctly determines whether to return a Gemfile path" do
context "currently in directory with a Gemfile" do
- before { File.new("Gemfile", "w") }
+ before { FileUtils.touch(bundled_app_gemfile) }
+ after { FileUtils.rm(bundled_app_gemfile) }
- it "returns path of the bundle gemfile" do
+ it "returns path of the bundle Gemfile" do
expect(subject.in_bundle?).to eq("#{bundled_app}/Gemfile")
end
end
@@ -138,22 +151,24 @@ RSpec.describe Bundler::SharedHelpers do
describe "#chdir" do
let(:op_block) { proc { Dir.mkdir "nested_dir" } }
- before { Dir.mkdir "chdir_test_dir" }
+ before { Dir.mkdir bundled_app("chdir_test_dir") }
it "executes the passed block while in the specified directory" do
- subject.chdir("chdir_test_dir", &op_block)
- expect(Pathname.new("chdir_test_dir/nested_dir")).to exist
+ subject.chdir(bundled_app("chdir_test_dir"), &op_block)
+ expect(bundled_app("chdir_test_dir/nested_dir")).to exist
end
end
describe "#pwd" do
+ let(:pwd_stub) { nil }
+
it "returns the current absolute path" do
- expect(subject.pwd).to eq(bundled_app)
+ expect(subject.pwd).to eq(source_root)
end
end
describe "#with_clean_git_env" do
- let(:with_clean_git_env_block) { proc { Dir.mkdir "with_clean_git_env_test_dir" } }
+ let(:with_clean_git_env_block) { proc { Dir.mkdir bundled_app("with_clean_git_env_test_dir") } }
before do
ENV["GIT_DIR"] = "ORIGINAL_ENV_GIT_DIR"
@@ -162,20 +177,20 @@ RSpec.describe Bundler::SharedHelpers do
it "executes the passed block" do
subject.with_clean_git_env(&with_clean_git_env_block)
- expect(Pathname.new("with_clean_git_env_test_dir")).to exist
+ expect(bundled_app("with_clean_git_env_test_dir")).to exist
end
context "when a block is passed" do
let(:with_clean_git_env_block) do
proc do
- Dir.mkdir "git_dir_test_dir" unless ENV["GIT_DIR"].nil?
- Dir.mkdir "git_work_tree_test_dir" unless ENV["GIT_WORK_TREE"].nil?
+ Dir.mkdir bundled_app("git_dir_test_dir") unless ENV["GIT_DIR"].nil?
+ Dir.mkdir bundled_app("git_work_tree_test_dir") unless ENV["GIT_WORK_TREE"].nil?
end end
it "uses a fresh git env for execution" do
subject.with_clean_git_env(&with_clean_git_env_block)
- expect(Pathname.new("git_dir_test_dir")).to_not exist
- expect(Pathname.new("git_work_tree_test_dir")).to_not exist
+ expect(bundled_app("git_dir_test_dir")).to_not exist
+ expect(bundled_app("git_work_tree_test_dir")).to_not exist
end
end
@@ -215,7 +230,7 @@ RSpec.describe Bundler::SharedHelpers do
end
shared_examples_for "ENV['PATH'] gets set correctly" do
- before { Dir.mkdir ".bundle" }
+ before { Dir.mkdir bundled_app(".bundle") }
it "ensures bundle bin path is in ENV['PATH']" do
subject.set_bundle_environment
@@ -227,7 +242,7 @@ RSpec.describe Bundler::SharedHelpers do
shared_examples_for "ENV['RUBYOPT'] gets set correctly" do
it "ensures -rbundler/setup is at the beginning of ENV['RUBYOPT']" do
subject.set_bundle_environment
- expect(ENV["RUBYOPT"].split(" ")).to start_with("-rbundler/setup")
+ expect(ENV["RUBYOPT"].split(" ")).to start_with("-r#{source_lib_dir}/bundler/setup")
end
end
@@ -235,7 +250,7 @@ RSpec.describe Bundler::SharedHelpers do
let(:ruby_lib_path) { "stubbed_ruby_lib_dir" }
before do
- allow(Bundler::SharedHelpers).to receive(:bundler_ruby_lib).and_return(ruby_lib_path)
+ allow(subject).to receive(:bundler_ruby_lib).and_return(ruby_lib_path)
end
it "ensures bundler's ruby version lib path is in ENV['RUBYLIB']" do
@@ -246,26 +261,69 @@ RSpec.describe Bundler::SharedHelpers do
end
it "calls the appropriate set methods" do
+ expect(subject).to receive(:set_bundle_variables)
expect(subject).to receive(:set_path)
expect(subject).to receive(:set_rubyopt)
expect(subject).to receive(:set_rubylib)
subject.set_bundle_environment
end
- it "exits if bundle path contains the path seperator" do
- stub_const("File::PATH_SEPARATOR", ":".freeze)
+ it "ignores if bundler_ruby_lib is same as rubylibdir" do
+ allow(subject).to receive(:bundler_ruby_lib).and_return(RbConfig::CONFIG["rubylibdir"])
+
+ subject.set_bundle_environment
+
+ paths = (ENV["RUBYLIB"]).split(File::PATH_SEPARATOR)
+ expect(paths.count(RbConfig::CONFIG["rubylibdir"])).to eq(0)
+ end
+
+ it "exits if bundle path contains the unix-like path separator" do
+ if Gem.respond_to?(:path_separator)
+ allow(Gem).to receive(:path_separator).and_return(":")
+ else
+ stub_const("File::PATH_SEPARATOR", ":".freeze)
+ end
allow(Bundler).to receive(:bundle_path) { Pathname.new("so:me/dir/bin") }
expect { subject.send(:validate_bundle_path) }.to raise_error(
Bundler::PathError,
- "Your bundle path contains a ':', which is the " \
+ "Your bundle path contains text matching \":\", which is the " \
"path separator for your system. Bundler cannot " \
"function correctly when the Bundle path contains the " \
"system's PATH separator. Please change your " \
- "bundle path to not include ':'.\nYour current bundle " \
+ "bundle path to not match \":\".\nYour current bundle " \
"path is '#{Bundler.bundle_path}'."
)
end
+ context "with a jruby path_separator regex" do
+ # In versions of jruby that supported ruby 1.8, the path separator was the standard File::PATH_SEPARATOR
+ let(:regex) { Regexp.new("(?<!jar:file|jar|file|classpath|uri:classloader|uri|http|https):") }
+ it "does not exit if bundle path is the standard uri path" do
+ allow(Bundler.rubygems).to receive(:path_separator).and_return(regex)
+ allow(Bundler).to receive(:bundle_path) { Pathname.new("uri:classloader:/WEB-INF/gems") }
+ expect { subject.send(:validate_bundle_path) }.not_to raise_error
+ end
+
+ it "exits if bundle path contains another directory" do
+ allow(Bundler.rubygems).to receive(:path_separator).and_return(regex)
+ allow(Bundler).to receive(:bundle_path) {
+ Pathname.new("uri:classloader:/WEB-INF/gems:other/dir")
+ }
+
+ expect { subject.send(:validate_bundle_path) }.to raise_error(
+ Bundler::PathError,
+ "Your bundle path contains text matching " \
+ "/(?<!jar:file|jar|file|classpath|uri:classloader|uri|http|https):/, which is the " \
+ "path separator for your system. Bundler cannot " \
+ "function correctly when the Bundle path contains the " \
+ "system's PATH separator. Please change your " \
+ "bundle path to not match " \
+ "/(?<!jar:file|jar|file|classpath|uri:classloader|uri|http|https):/." \
+ "\nYour current bundle path is '#{Bundler.bundle_path}'."
+ )
+ end
+ end
+
context "ENV['PATH'] does not exist" do
before { ENV.delete("PATH") }
@@ -336,6 +394,18 @@ RSpec.describe Bundler::SharedHelpers do
it_behaves_like "ENV['RUBYLIB'] gets set correctly"
end
+ context "bundle executable in ENV['BUNDLE_BIN_PATH'] does not exist" do
+ before { ENV["BUNDLE_BIN_PATH"] = "/does/not/exist" }
+ before { Bundler.rubygems.replace_bin_path [] }
+
+ it "sets BUNDLE_BIN_PATH to the bundle executable file" do
+ subject.set_bundle_environment
+ bin_path = ENV["BUNDLE_BIN_PATH"]
+ expect(bin_path).to eq(bindir.join("bundle").to_s)
+ expect(File.exist?(bin_path)).to be true
+ end
+ end
+
context "ENV['RUBYLIB'] already contains the bundler's ruby version lib path" do
let(:ruby_lib_path) { "stubbed_ruby_lib_dir" }
@@ -358,8 +428,8 @@ RSpec.describe Bundler::SharedHelpers do
let(:file_op_block) { proc {|path| FileUtils.mkdir_p(path) } }
it "performs the operation in the passed block" do
- subject.filesystem_access("./test_dir", &file_op_block)
- expect(Pathname.new("test_dir")).to exist
+ subject.filesystem_access(bundled_app("test_dir"), &file_op_block)
+ expect(bundled_app("test_dir")).to exist
end
end
@@ -393,7 +463,7 @@ RSpec.describe Bundler::SharedHelpers do
end
end
- context "system throws Errno::ENOTSUP", :ruby => "1.9" do
+ context "system throws Errno::ENOTSUP" do
let(:file_op_block) { proc {|_path| raise Errno::ENOTSUP } }
it "raises a OperationNotSupportedError" do
diff --git a/spec/bundler/bundler/source/git/git_proxy_spec.rb b/spec/bundler/bundler/source/git/git_proxy_spec.rb
index 34fe21e9fb..cffd72cc3f 100644
--- a/spec/bundler/bundler/source/git/git_proxy_spec.rb
+++ b/spec/bundler/bundler/source/git/git_proxy_spec.rb
@@ -1,35 +1,42 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Source::Git::GitProxy do
- let(:uri) { "https://github.com/bundler/bundler.git" }
- subject { described_class.new(Pathname("path"), uri, "HEAD") }
+ let(:path) { Pathname("path") }
+ let(:uri) { "https://github.com/rubygems/rubygems.git" }
+ let(:ref) { "HEAD" }
+ let(:revision) { nil }
+ let(:git_source) { nil }
+ subject { described_class.new(path, uri, ref, revision, git_source) }
context "with configured credentials" do
it "adds username and password to URI" do
- Bundler.settings[uri] = "u:p"
- expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/bundler/bundler.git"))
- subject.checkout
+ Bundler.settings.temporary(uri => "u:p") do
+ expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s)
+ subject.checkout
+ end
end
it "adds username and password to URI for host" do
- Bundler.settings["github.com"] = "u:p"
- expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/bundler/bundler.git"))
- subject.checkout
+ Bundler.settings.temporary("github.com" => "u:p") do
+ expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s)
+ subject.checkout
+ end
end
it "does not add username and password to mismatched URI" do
- Bundler.settings["https://u:p@github.com/bundler/bundler-mismatch.git"] = "u:p"
- expect(subject).to receive(:git_retry).with(match(uri))
- subject.checkout
+ Bundler.settings.temporary("https://u:p@github.com/rubygems/rubygems-mismatch.git" => "u:p") do
+ expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", uri, path.to_s)
+ subject.checkout
+ end
end
it "keeps original userinfo" do
- Bundler.settings["github.com"] = "u:p"
- original = "https://orig:info@github.com/bundler/bundler.git"
- subject = described_class.new(Pathname("path"), original, "HEAD")
- expect(subject).to receive(:git_retry).with(match(original))
- subject.checkout
+ Bundler.settings.temporary("github.com" => "u:p") do
+ original = "https://orig:info@github.com/rubygems/rubygems.git"
+ subject = described_class.new(Pathname("path"), original, "HEAD")
+ expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", original, path.to_s)
+ subject.checkout
+ end
end
end
@@ -114,4 +121,51 @@ RSpec.describe Bundler::Source::Git::GitProxy do
end
end
end
+
+ describe "#copy_to" do
+ let(:cache) { tmpdir("cache_path") }
+ let(:destination) { tmpdir("copy_to_path") }
+ let(:submodules) { false }
+
+ context "when given a SHA as a revision" do
+ let(:revision) { "abcd" * 10 }
+ let(:command) { ["reset", "--hard", revision] }
+ let(:command_for_display) { "git #{command.shelljoin}" }
+
+ it "fails gracefully when resetting to the revision fails" do
+ expect(subject).to receive(:git_retry).with("clone", any_args) { destination.mkpath }
+ expect(subject).to receive(:git_retry).with("fetch", any_args, :dir => destination)
+ expect(subject).to receive(:git).with(*command, :dir => destination).and_raise(Bundler::Source::Git::GitCommandError.new(command_for_display, destination))
+ expect(subject).not_to receive(:git)
+
+ expect { subject.copy_to(destination, submodules) }.
+ to raise_error(
+ Bundler::Source::Git::MissingGitRevisionError,
+ "Git error: command `#{command_for_display}` in directory #{destination} has failed.\n" \
+ "Revision #{revision} does not exist in the repository #{uri}. Maybe you misspelled it?\n" \
+ "If this error persists you could try removing the cache directory '#{destination}'"
+ )
+ end
+ end
+ end
+
+ it "doesn't allow arbitrary code execution through Gemfile uris with a leading dash" do
+ gemfile <<~G
+ gem "poc", git: "-u./pay:load.sh"
+ G
+
+ file = bundled_app("pay:load.sh")
+
+ create_file file, <<~RUBY
+ #!/bin/sh
+
+ touch #{bundled_app("canary")}
+ RUBY
+
+ FileUtils.chmod("+x", file)
+
+ bundle :lock, :raise_on_error => false
+
+ expect(Pathname.new(bundled_app("canary"))).not_to exist
+ end
end
diff --git a/spec/bundler/bundler/source/git_spec.rb b/spec/bundler/bundler/source/git_spec.rb
new file mode 100644
index 0000000000..ed6dc3cd29
--- /dev/null
+++ b/spec/bundler/bundler/source/git_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+RSpec.describe Bundler::Source::Git do
+ before do
+ allow(Bundler).to receive(:root) { Pathname.new("root") }
+ end
+
+ let(:uri) { "https://github.com/foo/bar.git" }
+ let(:options) do
+ { "uri" => uri }
+ end
+
+ subject { described_class.new(options) }
+
+ describe "#to_s" do
+ it "returns a description" do
+ expect(subject.to_s).to eq "https://github.com/foo/bar.git"
+ end
+
+ context "when the URI contains credentials" do
+ let(:uri) { "https://my-secret-token:x-oauth-basic@github.com/foo/bar.git" }
+
+ it "filters credentials" do
+ expect(subject.to_s).to eq "https://x-oauth-basic@github.com/foo/bar.git"
+ end
+ end
+
+ context "when the source has a glob specifier" do
+ let(:glob) { "bar/baz/*.gemspec" }
+ let(:options) do
+ { "uri" => uri, "glob" => glob }
+ end
+
+ it "includes it" do
+ expect(subject.to_s).to eq "https://github.com/foo/bar.git (glob: bar/baz/*.gemspec)"
+ end
+ end
+
+ context "when the source has a reference" do
+ let(:git_proxy_stub) do
+ instance_double(Bundler::Source::Git::GitProxy, :revision => "123abc", :branch => "v1.0.0")
+ end
+ let(:options) do
+ { "uri" => uri, "ref" => "v1.0.0" }
+ end
+
+ before do
+ allow(Bundler::Source::Git::GitProxy).to receive(:new).and_return(git_proxy_stub)
+ end
+
+ it "includes it" do
+ expect(subject.to_s).to eq "https://github.com/foo/bar.git (at v1.0.0@123abc)"
+ end
+ end
+
+ context "when the source has both reference and glob specifiers" do
+ let(:git_proxy_stub) do
+ instance_double(Bundler::Source::Git::GitProxy, :revision => "123abc", :branch => "v1.0.0")
+ end
+ let(:options) do
+ { "uri" => uri, "ref" => "v1.0.0", "glob" => "gems/foo/*.gemspec" }
+ end
+
+ before do
+ allow(Bundler::Source::Git::GitProxy).to receive(:new).and_return(git_proxy_stub)
+ end
+
+ it "includes both" do
+ expect(subject.to_s).to eq "https://github.com/foo/bar.git (at v1.0.0@123abc, glob: gems/foo/*.gemspec)"
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/source/rubygems/remote_spec.rb b/spec/bundler/bundler/source/rubygems/remote_spec.rb
index 54394fc0ca..07ce4f968e 100644
--- a/spec/bundler/bundler/source/rubygems/remote_spec.rb
+++ b/spec/bundler/bundler/source/rubygems/remote_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/source/rubygems/remote"
RSpec.describe Bundler::Source::Rubygems::Remote do
@@ -8,11 +8,11 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
before do
- allow(Digest::MD5).to receive(:hexdigest).with(duck_type(:to_s)) {|string| "MD5HEX(#{string})" }
+ allow(Digest(:MD5)).to receive(:hexdigest).with(duck_type(:to_s)) {|string| "MD5HEX(#{string})" }
end
- let(:uri_no_auth) { URI("https://gems.example.com") }
- let(:uri_with_auth) { URI("https://#{credentials}@gems.example.com") }
+ let(:uri_no_auth) { Bundler::URI("https://gems.example.com") }
+ let(:uri_with_auth) { Bundler::URI("https://#{credentials}@gems.example.com") }
let(:credentials) { "username:password" }
context "when the original URI has no credentials" do
@@ -22,8 +22,9 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
it "applies configured credentials" do
- Bundler.settings[uri_no_auth.to_s] = credentials
- expect(remote(uri_no_auth).uri).to eq(uri_with_auth)
+ Bundler.settings.temporary(uri_no_auth.to_s => credentials) do
+ expect(remote(uri_no_auth).uri).to eq(uri_with_auth)
+ end
end
end
@@ -33,8 +34,9 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
it "does not apply given credentials" do
- Bundler.settings[uri_no_auth.to_s] = credentials
- expect(remote(uri_no_auth).anonymized_uri).to eq(uri_no_auth)
+ Bundler.settings.temporary(uri_no_auth.to_s => credentials) do
+ expect(remote(uri_no_auth).anonymized_uri).to eq(uri_no_auth)
+ end
end
end
@@ -44,8 +46,9 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
it "only applies the given user" do
- Bundler.settings[uri_no_auth.to_s] = credentials
- expect(remote(uri_no_auth).cache_slug).to eq("gems.example.com.username.443.MD5HEX(gems.example.com.username.443./)")
+ Bundler.settings.temporary(uri_no_auth.to_s => credentials) do
+ expect(remote(uri_no_auth).cache_slug).to eq("gems.example.com.username.443.MD5HEX(gems.example.com.username.443./)")
+ end
end
end
end
@@ -57,7 +60,7 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
it "does not apply configured credentials" do
- Bundler.settings[uri_no_auth.to_s] = "other:stuff"
+ Bundler.settings.temporary(uri_no_auth.to_s => "other:stuff")
expect(remote(uri_with_auth).uri).to eq(uri_with_auth)
end
end
@@ -68,7 +71,7 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
it "does not apply given credentials" do
- Bundler.settings[uri_no_auth.to_s] = "other:stuff"
+ Bundler.settings.temporary(uri_no_auth.to_s => "other:stuff")
expect(remote(uri_with_auth).anonymized_uri).to eq(uri_no_auth)
end
end
@@ -79,18 +82,18 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
it "does not apply given credentials" do
- Bundler.settings[uri_with_auth.to_s] = credentials
+ Bundler.settings.temporary(uri_with_auth.to_s => credentials)
expect(remote(uri_with_auth).cache_slug).to eq("gems.example.com.username.443.MD5HEX(gems.example.com.username.443./)")
end
end
end
context "when the original URI has only a username" do
- let(:uri) { URI("https://SeCrEt-ToKeN@gem.fury.io/me/") }
+ let(:uri) { Bundler::URI("https://SeCrEt-ToKeN@gem.fury.io/me/") }
describe "#anonymized_uri" do
it "returns the URI without username and password" do
- expect(remote(uri).anonymized_uri).to eq(URI("https://gem.fury.io/me/"))
+ expect(remote(uri).anonymized_uri).to eq(Bundler::URI("https://gem.fury.io/me/"))
end
end
@@ -102,11 +105,13 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
context "when a mirror with inline credentials is configured for the URI" do
- let(:uri) { URI("https://rubygems.org/") }
- let(:mirror_uri_with_auth) { URI("https://username:password@rubygems-mirror.org/") }
- let(:mirror_uri_no_auth) { URI("https://rubygems-mirror.org/") }
+ let(:uri) { Bundler::URI("https://rubygems.org/") }
+ let(:mirror_uri_with_auth) { Bundler::URI("https://username:password@rubygems-mirror.org/") }
+ let(:mirror_uri_no_auth) { Bundler::URI("https://rubygems-mirror.org/") }
+
+ before { Bundler.settings.temporary("mirror.https://rubygems.org/" => mirror_uri_with_auth.to_s) }
- before { Bundler.settings["mirror.https://rubygems.org/"] = mirror_uri_with_auth.to_s }
+ after { Bundler.settings.temporary("mirror.https://rubygems.org/" => nil) }
specify "#uri returns the mirror URI with credentials" do
expect(remote(uri).uri).to eq(mirror_uri_with_auth)
@@ -126,13 +131,18 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
context "when a mirror with configured credentials is configured for the URI" do
- let(:uri) { URI("https://rubygems.org/") }
- let(:mirror_uri_with_auth) { URI("https://#{credentials}@rubygems-mirror.org/") }
- let(:mirror_uri_no_auth) { URI("https://rubygems-mirror.org/") }
+ let(:uri) { Bundler::URI("https://rubygems.org/") }
+ let(:mirror_uri_with_auth) { Bundler::URI("https://#{credentials}@rubygems-mirror.org/") }
+ let(:mirror_uri_no_auth) { Bundler::URI("https://rubygems-mirror.org/") }
before do
- Bundler.settings["mirror.https://rubygems.org/"] = mirror_uri_no_auth.to_s
- Bundler.settings[mirror_uri_no_auth.to_s] = credentials
+ Bundler.settings.temporary("mirror.https://rubygems.org/" => mirror_uri_no_auth.to_s)
+ Bundler.settings.temporary(mirror_uri_no_auth.to_s => credentials)
+ end
+
+ after do
+ Bundler.settings.temporary("mirror.https://rubygems.org/" => nil)
+ Bundler.settings.temporary(mirror_uri_no_auth.to_s => nil)
end
specify "#uri returns the mirror URI with credentials" do
diff --git a/spec/bundler/bundler/source/rubygems_spec.rb b/spec/bundler/bundler/source/rubygems_spec.rb
index b8f9f09c20..884fa81046 100644
--- a/spec/bundler/bundler/source/rubygems_spec.rb
+++ b/spec/bundler/bundler/source/rubygems_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Source::Rubygems do
before do
@@ -31,4 +30,18 @@ RSpec.describe Bundler::Source::Rubygems do
end
end
end
+
+ describe "#no_remotes?" do
+ context "when no remote provided" do
+ it "returns a truthy value" do
+ expect(described_class.new("remotes" => []).no_remotes?).to be_truthy
+ end
+ end
+
+ context "when a remote provided" do
+ it "returns a falsey value" do
+ expect(described_class.new("remotes" => ["https://rubygems.org"]).no_remotes?).to be_falsey
+ end
+ end
+ end
end
diff --git a/spec/bundler/bundler/source_list_spec.rb b/spec/bundler/bundler/source_list_spec.rb
index 6a23c8bcbf..f860e9ff58 100644
--- a/spec/bundler/bundler/source_list_spec.rb
+++ b/spec/bundler/bundler/source_list_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::SourceList do
before do
@@ -13,6 +12,7 @@ RSpec.describe Bundler::SourceList do
subject(:source_list) { Bundler::SourceList.new }
let(:rubygems_aggregate) { Bundler::Source::Rubygems.new }
+ let(:metadata_source) { Bundler::Source::Metadata.new }
describe "adding sources" do
before do
@@ -75,7 +75,7 @@ RSpec.describe Bundler::SourceList do
let(:msg) do
"The git source `git://existing-git.org/path.git` " \
"uses the `git` protocol, which transmits data without encryption. " \
- "Disable this warning with `bundle config git.allow_insecure true`, " \
+ "Disable this warning with `bundle config set --local git.allow_insecure true`, " \
"or switch to the `https` protocol to keep your data secure."
end
@@ -85,7 +85,7 @@ RSpec.describe Bundler::SourceList do
end
it "ignores git protocols on request" do
- Bundler.settings["git.allow_insecure"] = true
+ Bundler.settings.temporary(:"git.allow_insecure" => true)
expect(Bundler.ui).to_not receive(:warn).with(msg)
source_list.add_git_source("uri" => "git://existing-git.org/path.git")
end
@@ -115,18 +115,19 @@ RSpec.describe Bundler::SourceList do
end
end
- describe "#add_rubygems_remote" do
- before do
- @returned_source = source_list.add_rubygems_remote("https://rubygems.org/")
- end
+ describe "#add_global_rubygems_remote" do
+ let!(:returned_source) { source_list.add_global_rubygems_remote("https://rubygems.org/") }
it "returns the aggregate rubygems source" do
- expect(@returned_source).to be_instance_of(Bundler::Source::Rubygems)
+ expect(returned_source).to be_instance_of(Bundler::Source::Rubygems)
end
it "adds the provided remote to the beginning of the aggregate source" do
- source_list.add_rubygems_remote("https://othersource.org")
- expect(@returned_source.remotes.first).to eq(URI("https://othersource.org/"))
+ source_list.add_global_rubygems_remote("https://othersource.org")
+ expect(returned_source.remotes).to eq [
+ Bundler::URI("https://othersource.org/"),
+ Bundler::URI("https://rubygems.org/"),
+ ]
end
end
@@ -204,28 +205,29 @@ RSpec.describe Bundler::SourceList do
Bundler::Source::Rubygems.new("remotes" => ["https://fourth-rubygems.org"]),
Bundler::Source::Rubygems.new("remotes" => ["https://fifth-rubygems.org"]),
rubygems_aggregate,
+ metadata_source,
]
end
end
describe "#path_sources" do
it "returns an empty array when no path sources have been added" do
- source_list.add_rubygems_remote("https://rubygems.org")
+ source_list.add_global_rubygems_remote("https://rubygems.org")
source_list.add_git_source("uri" => "git://host/path.git")
expect(source_list.path_sources).to be_empty
end
it "returns path sources in the reverse order that they were added" do
source_list.add_git_source("uri" => "git://third-git.org/path.git")
- source_list.add_rubygems_remote("https://fifth-rubygems.org")
+ source_list.add_global_rubygems_remote("https://fifth-rubygems.org")
source_list.add_path_source("path" => "/third/path/to/gem")
- source_list.add_rubygems_remote("https://fourth-rubygems.org")
+ source_list.add_global_rubygems_remote("https://fourth-rubygems.org")
source_list.add_path_source("path" => "/second/path/to/gem")
- source_list.add_rubygems_remote("https://third-rubygems.org")
+ source_list.add_global_rubygems_remote("https://third-rubygems.org")
source_list.add_git_source("uri" => "git://second-git.org/path.git")
- source_list.add_rubygems_remote("https://second-rubygems.org")
+ source_list.add_global_rubygems_remote("https://second-rubygems.org")
source_list.add_path_source("path" => "/first/path/to/gem")
- source_list.add_rubygems_remote("https://first-rubygems.org")
+ source_list.add_global_rubygems_remote("https://first-rubygems.org")
source_list.add_git_source("uri" => "git://first-git.org/path.git")
expect(source_list.path_sources).to eq [
@@ -238,7 +240,7 @@ RSpec.describe Bundler::SourceList do
describe "#git_sources" do
it "returns an empty array when no git sources have been added" do
- source_list.add_rubygems_remote("https://rubygems.org")
+ source_list.add_global_rubygems_remote("https://rubygems.org")
source_list.add_path_source("path" => "/path/to/gem")
expect(source_list.git_sources).to be_empty
@@ -246,15 +248,15 @@ RSpec.describe Bundler::SourceList do
it "returns git sources in the reverse order that they were added" do
source_list.add_git_source("uri" => "git://third-git.org/path.git")
- source_list.add_rubygems_remote("https://fifth-rubygems.org")
+ source_list.add_global_rubygems_remote("https://fifth-rubygems.org")
source_list.add_path_source("path" => "/third/path/to/gem")
- source_list.add_rubygems_remote("https://fourth-rubygems.org")
+ source_list.add_global_rubygems_remote("https://fourth-rubygems.org")
source_list.add_path_source("path" => "/second/path/to/gem")
- source_list.add_rubygems_remote("https://third-rubygems.org")
+ source_list.add_global_rubygems_remote("https://third-rubygems.org")
source_list.add_git_source("uri" => "git://second-git.org/path.git")
- source_list.add_rubygems_remote("https://second-rubygems.org")
+ source_list.add_global_rubygems_remote("https://second-rubygems.org")
source_list.add_path_source("path" => "/first/path/to/gem")
- source_list.add_rubygems_remote("https://first-rubygems.org")
+ source_list.add_global_rubygems_remote("https://first-rubygems.org")
source_list.add_git_source("uri" => "git://first-git.org/path.git")
expect(source_list.git_sources).to eq [
@@ -267,7 +269,7 @@ RSpec.describe Bundler::SourceList do
describe "#plugin_sources" do
it "returns an empty array when no plugin sources have been added" do
- source_list.add_rubygems_remote("https://rubygems.org")
+ source_list.add_global_rubygems_remote("https://rubygems.org")
source_list.add_path_source("path" => "/path/to/gem")
expect(source_list.plugin_sources).to be_empty
@@ -277,13 +279,13 @@ RSpec.describe Bundler::SourceList do
source_list.add_plugin_source("new_source", "uri" => "https://third-git.org/path.git")
source_list.add_git_source("https://new-git.org")
source_list.add_path_source("path" => "/third/path/to/gem")
- source_list.add_rubygems_remote("https://fourth-rubygems.org")
+ source_list.add_global_rubygems_remote("https://fourth-rubygems.org")
source_list.add_path_source("path" => "/second/path/to/gem")
- source_list.add_rubygems_remote("https://third-rubygems.org")
+ source_list.add_global_rubygems_remote("https://third-rubygems.org")
source_list.add_plugin_source("new_source", "uri" => "git://second-git.org/path.git")
- source_list.add_rubygems_remote("https://second-rubygems.org")
+ source_list.add_global_rubygems_remote("https://second-rubygems.org")
source_list.add_path_source("path" => "/first/path/to/gem")
- source_list.add_rubygems_remote("https://first-rubygems.org")
+ source_list.add_global_rubygems_remote("https://first-rubygems.org")
source_list.add_plugin_source("new_source", "uri" => "git://first-git.org/path.git")
expect(source_list.plugin_sources).to eq [
@@ -337,7 +339,7 @@ RSpec.describe Bundler::SourceList do
describe "#get" do
context "when it includes an equal source" do
let(:rubygems_source) { Bundler::Source::Rubygems.new("remotes" => ["https://rubygems.org"]) }
- before { @equal_source = source_list.add_rubygems_remote("https://rubygems.org") }
+ before { @equal_source = source_list.add_global_rubygems_remote("https://rubygems.org") }
it "returns the equal source" do
expect(source_list.get(rubygems_source)).to be @equal_source
@@ -354,7 +356,7 @@ RSpec.describe Bundler::SourceList do
end
describe "#lock_sources" do
- it "combines the rubygems sources into a single instance, removing duplicate remotes from the end" do
+ before do
source_list.add_git_source("uri" => "git://third-git.org/path.git")
source_list.add_rubygems_source("remotes" => ["https://duplicate-rubygems.org"])
source_list.add_plugin_source("new_source", "uri" => "https://third-bar.org/foo")
@@ -368,7 +370,9 @@ RSpec.describe Bundler::SourceList do
source_list.add_path_source("path" => "/first/path/to/gem")
source_list.add_rubygems_source("remotes" => ["https://duplicate-rubygems.org"])
source_list.add_git_source("uri" => "git://first-git.org/path.git")
+ end
+ it "returns all sources, without combining rubygems sources" do
expect(source_list.lock_sources).to eq [
Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),
@@ -378,12 +382,11 @@ RSpec.describe Bundler::SourceList do
Bundler::Source::Path.new("path" => "/first/path/to/gem"),
Bundler::Source::Path.new("path" => "/second/path/to/gem"),
Bundler::Source::Path.new("path" => "/third/path/to/gem"),
- Bundler::Source::Rubygems.new("remotes" => [
- "https://duplicate-rubygems.org",
- "https://first-rubygems.org",
- "https://second-rubygems.org",
- "https://third-rubygems.org",
- ]),
+ Bundler::Source::Rubygems.new,
+ Bundler::Source::Rubygems.new("remotes" => ["https://duplicate-rubygems.org"]),
+ Bundler::Source::Rubygems.new("remotes" => ["https://first-rubygems.org"]),
+ Bundler::Source::Rubygems.new("remotes" => ["https://second-rubygems.org"]),
+ Bundler::Source::Rubygems.new("remotes" => ["https://third-rubygems.org"]),
]
end
end
@@ -414,7 +417,7 @@ RSpec.describe Bundler::SourceList do
end
describe "#cached!" do
- let(:rubygems_source) { source_list.add_rubygems_remote("https://rubygems.org") }
+ let(:rubygems_source) { source_list.add_rubygems_source("remotes" => ["https://rubygems.org"]) }
let(:git_source) { source_list.add_git_source("uri" => "git://host/path.git") }
let(:path_source) { source_list.add_path_source("path" => "/path/to/gem") }
@@ -427,7 +430,7 @@ RSpec.describe Bundler::SourceList do
end
describe "#remote!" do
- let(:rubygems_source) { source_list.add_rubygems_remote("https://rubygems.org") }
+ let(:rubygems_source) { source_list.add_rubygems_source("remotes" => ["https://rubygems.org"]) }
let(:git_source) { source_list.add_git_source("uri" => "git://host/path.git") }
let(:path_source) { source_list.add_path_source("path" => "/path/to/gem") }
@@ -438,4 +441,19 @@ RSpec.describe Bundler::SourceList do
source_list.remote!
end
end
+
+ describe "implicit_global_source?" do
+ context "when a global rubygem source provided" do
+ it "returns a falsy value" do
+ source_list.add_global_rubygems_remote("https://rubygems.org")
+
+ expect(source_list.implicit_global_source?).to be_falsey
+ end
+ end
+ context "when no global rubygem source provided" do
+ it "returns a truthy value" do
+ expect(source_list.implicit_global_source?).to be_truthy
+ end
+ end
+ end
end
diff --git a/spec/bundler/bundler/source_spec.rb b/spec/bundler/bundler/source_spec.rb
index 08d1698fcd..af370bb45c 100644
--- a/spec/bundler/bundler/source_spec.rb
+++ b/spec/bundler/bundler/source_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::Source do
class ExampleSource < Bundler::Source
@@ -57,8 +56,10 @@ RSpec.describe Bundler::Source do
context "with a different version" do
let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => "< 1.5") }
- context "with color" do
- before { Bundler.ui = Bundler::UI::Shell.new }
+ context "with color", :no_color_tty do
+ before do
+ allow($stdout).to receive(:tty?).and_return(true)
+ end
it "should return a string with the spec name and version and locked spec version" do
expect(subject.version_message(spec)).to eq("nokogiri >= 1.6\e[32m (was < 1.5)\e[0m")
@@ -66,6 +67,12 @@ RSpec.describe Bundler::Source do
end
context "without color" do
+ around do |example|
+ with_ui(Bundler::UI::Shell.new("no-color" => true)) do
+ example.run
+ end
+ end
+
it "should return a string with the spec name and version and locked spec version" do
expect(subject.version_message(spec)).to eq("nokogiri >= 1.6 (was < 1.5)")
end
@@ -76,26 +83,54 @@ RSpec.describe Bundler::Source do
let(:spec) { double(:spec, :name => "nokogiri", :version => "1.6.1", :platform => rb) }
let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => "1.7.0") }
- context "with color" do
- before { Bundler.ui = Bundler::UI::Shell.new }
+ context "with color", :no_color_tty do
+ before do
+ allow($stdout).to receive(:tty?).and_return(true)
+ end
it "should return a string with the locked spec version in yellow" do
expect(subject.version_message(spec)).to eq("nokogiri 1.6.1\e[33m (was 1.7.0)\e[0m")
end
end
+
+ context "without color" do
+ around do |example|
+ with_ui(Bundler::UI::Shell.new("no-color" => true)) do
+ example.run
+ end
+ end
+
+ it "should return a string with the locked spec version in yellow" do
+ expect(subject.version_message(spec)).to eq("nokogiri 1.6.1 (was 1.7.0)")
+ end
+ end
end
context "with an older version" do
let(:spec) { double(:spec, :name => "nokogiri", :version => "1.7.1", :platform => rb) }
let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => "1.7.0") }
- context "with color" do
- before { Bundler.ui = Bundler::UI::Shell.new }
+ context "with color", :no_color_tty do
+ before do
+ allow($stdout).to receive(:tty?).and_return(true)
+ end
it "should return a string with the locked spec version in green" do
expect(subject.version_message(spec)).to eq("nokogiri 1.7.1\e[32m (was 1.7.0)\e[0m")
end
end
+
+ context "without color" do
+ around do |example|
+ with_ui(Bundler::UI::Shell.new("no-color" => true)) do
+ example.run
+ end
+ end
+
+ it "should return a string with the locked spec version in yellow" do
+ expect(subject.version_message(spec)).to eq("nokogiri 1.7.1 (was 1.7.0)")
+ end
+ end
end
end
@@ -152,4 +187,14 @@ RSpec.describe Bundler::Source do
end
end
end
+
+ private
+
+ def with_ui(ui)
+ old_ui = Bundler.ui
+ Bundler.ui = ui
+ yield
+ ensure
+ Bundler.ui = old_ui
+ end
end
diff --git a/spec/bundler/bundler/spec_set_spec.rb b/spec/bundler/bundler/spec_set_spec.rb
index 8f7c27f065..6fedd38b50 100644
--- a/spec/bundler/bundler/spec_set_spec.rb
+++ b/spec/bundler/bundler/spec_set_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::SpecSet do
let(:specs) do
@@ -17,6 +16,7 @@ RSpec.describe Bundler::SpecSet do
build_spec("e", "1.0.0.pre.1"),
].flatten
end
+
subject { described_class.new(specs) }
context "enumerable methods" do
@@ -29,15 +29,49 @@ RSpec.describe Bundler::SpecSet do
end
end
+ describe "#find_by_name_and_platform" do
+ let(:platform) { Gem::Platform.new("universal-darwin-64") }
+ let(:platform_spec) { build_spec("b", "2.0", platform).first }
+ let(:specs) do
+ [
+ build_spec("a", "1.0"),
+ platform_spec,
+ ].flatten
+ end
+
+ it "finds spec with given name and platform" do
+ spec = described_class.new(specs).find_by_name_and_platform("b", platform)
+ expect(spec).to eq platform_spec
+ end
+ end
+
+ describe "#merge" do
+ let(:other_specs) do
+ [
+ build_spec("f", "1.0"),
+ build_spec("g", "2.0"),
+ ].flatten
+ end
+
+ let(:other_spec_set) { described_class.new(other_specs) }
+
+ it "merges the items in each gemspec" do
+ new_spec_set = subject.merge(other_spec_set)
+ specs = new_spec_set.to_a.map(&:full_name)
+ expect(specs).to include("a-1.0")
+ expect(specs).to include("f-1.0")
+ end
+ end
+
describe "#to_a" do
it "returns the specs in order" do
- expect(subject.to_a.map(&:full_name)).to eq %w(
+ expect(subject.to_a.map(&:full_name)).to eq %w[
a-1.0
b-1.0
e-1.0.0.pre.1
c-1.1
d-2.0
- )
+ ]
end
end
end
diff --git a/spec/bundler/bundler/ssl_certs/certificate_manager_spec.rb b/spec/bundler/bundler/ssl_certs/certificate_manager_spec.rb
deleted file mode 100644
index 66853a6815..0000000000
--- a/spec/bundler/bundler/ssl_certs/certificate_manager_spec.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-require "bundler/ssl_certs/certificate_manager"
-
-RSpec.describe Bundler::SSLCerts::CertificateManager do
- let(:rubygems_path) { root }
- let(:stub_cert) { File.join(root.to_s, "lib", "rubygems", "ssl_certs", "rubygems.org", "ssl-cert.pem") }
- let(:rubygems_certs_dir) { File.join(root.to_s, "lib", "rubygems", "ssl_certs", "rubygems.org") }
-
- subject { described_class.new(rubygems_path) }
-
- # Pretend bundler root is rubygems root
- before do
- # Backing up rubygems ceriticates
- FileUtils.mv(rubygems_certs_dir, rubygems_certs_dir + ".back") if !!(ENV["BUNDLE_RUBY"] && ENV["BUNDLE_GEM"])
-
- FileUtils.mkdir_p(rubygems_certs_dir)
- FileUtils.touch(stub_cert)
- end
-
- after do
- rubygems_dir = File.join(root.to_s, "lib", "rubygems")
- FileUtils.rm_rf(rubygems_certs_dir)
-
- # Restore rubygems certificates
- FileUtils.mv(rubygems_certs_dir + ".back", rubygems_certs_dir) if !!(ENV["BUNDLE_RUBY"] && ENV["BUNDLE_GEM"])
- end
-
- describe "#update_from" do
- let(:cert_manager) { double(:cert_manager) }
-
- before { allow(described_class).to receive(:new).with(rubygems_path).and_return(cert_manager) }
-
- it "should update the certs through a new certificate manager" do
- allow(cert_manager).to receive(:update!)
- expect(described_class.update_from!(rubygems_path)).to be_nil
- end
- end
-
- describe "#initialize" do
- it "should set bundler_cert_path as path of the subdir with bundler ssl certs" do
- expect(subject.bundler_cert_path).to eq(File.join(root, "lib/bundler/ssl_certs"))
- end
-
- it "should set bundler_certs as the paths of the bundler ssl certs" do
- expect(subject.bundler_certs).to include(File.join(root, "lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem"))
- expect(subject.bundler_certs).to include(File.join(root, "lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem"))
- end
-
- context "when rubygems_path is not nil" do
- it "should set rubygems_certs" do
- expect(subject.rubygems_certs).to include(File.join(root, "lib", "rubygems", "ssl_certs", "rubygems.org", "ssl-cert.pem"))
- end
- end
- end
-
- describe "#up_to_date?" do
- context "when bundler certs and rubygems certs are the same" do
- before do
- bundler_certs = Dir[File.join(root.to_s, "lib", "bundler", "ssl_certs", "**", "*.pem")]
- FileUtils.rm(stub_cert)
- FileUtils.cp(bundler_certs, rubygems_certs_dir)
- end
-
- it "should return true" do
- expect(subject).to be_up_to_date
- end
- end
-
- context "when bundler certs and rubygems certs are not the same" do
- it "should return false" do
- expect(subject).to_not be_up_to_date
- end
- end
- end
-
- describe "#update!" do
- context "when certificate manager is not up to date" do
- before do
- allow(subject).to receive(:up_to_date?).and_return(false)
- allow(FileUtils).to receive(:rm)
- allow(FileUtils).to receive(:cp)
- end
-
- it "should remove the current bundler certs" do
- expect(FileUtils).to receive(:rm).with(subject.bundler_certs)
- subject.update!
- end
-
- it "should copy the rubygems certs into bundler certs" do
- expect(FileUtils).to receive(:cp).with(subject.rubygems_certs, subject.bundler_cert_path)
- subject.update!
- end
-
- it "should return nil" do
- expect(subject.update!).to be_nil
- end
- end
-
- context "when certificate manager is up to date" do
- before { allow(subject).to receive(:up_to_date?).and_return(true) }
-
- it "should return nil" do
- expect(subject.update!).to be_nil
- end
- end
- end
-
- describe "#connect_to" do
- let(:host) { "http://www.host.com" }
- let(:http) { Net::HTTP.new(host, 443) }
- let(:cert_store) { OpenSSL::X509::Store.new }
- let(:http_header_response) { double(:http_header_response) }
-
- before do
- allow(Net::HTTP).to receive(:new).with(host, 443).and_return(http)
- allow(OpenSSL::X509::Store).to receive(:new).and_return(cert_store)
- allow(http).to receive(:head).with("/").and_return(http_header_response)
- end
-
- it "should use ssl for the http request" do
- expect(http).to receive(:use_ssl=).with(true)
- subject.connect_to(host)
- end
-
- it "use verify peer mode" do
- expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
- subject.connect_to(host)
- end
-
- it "set its cert store as a OpenSSL::X509::Store populated with bundler certs" do
- expect(cert_store).to receive(:add_file).at_least(:once)
- expect(http).to receive(:cert_store=).with(cert_store)
- subject.connect_to(host)
- end
-
- it "return the headers of the request response" do
- expect(subject.connect_to(host)).to eq(http_header_response)
- end
- end
-end
diff --git a/spec/bundler/bundler/stub_specification_spec.rb b/spec/bundler/bundler/stub_specification_spec.rb
index f1ddf43bb4..fb612813c2 100644
--- a/spec/bundler/bundler/stub_specification_spec.rb
+++ b/spec/bundler/bundler/stub_specification_spec.rb
@@ -1,25 +1,47 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::StubSpecification do
- let(:gemspec) do
- Gem::Specification.new do |s|
+ let(:with_bundler_stub_spec) do
+ gemspec = Gem::Specification.new do |s|
s.name = "gemname"
s.version = "1.0.0"
s.loaded_from = __FILE__
+ s.extensions = "ext/gemname"
end
- end
- let(:with_bundler_stub_spec) do
described_class.from_stub(gemspec)
end
- if Bundler.rubygems.provides?(">= 2.1")
- describe "#from_stub" do
- it "returns the same stub if already a Bundler::StubSpecification" do
- stub = described_class.from_stub(with_bundler_stub_spec)
- expect(stub).to be(with_bundler_stub_spec)
- end
+ describe "#from_stub" do
+ it "returns the same stub if already a Bundler::StubSpecification" do
+ stub = described_class.from_stub(with_bundler_stub_spec)
+ expect(stub).to be(with_bundler_stub_spec)
+ end
+ end
+
+ describe "#manually_installed?" do
+ it "returns true if installed_by_version is nil or 0" do
+ stub = described_class.from_stub(with_bundler_stub_spec)
+ expect(stub.manually_installed?).to be true
+ end
+
+ it "returns false if installed_by_version is greater than 0" do
+ stub = described_class.from_stub(with_bundler_stub_spec)
+ stub.installed_by_version = Gem::Version.new(1)
+ expect(stub.manually_installed?).to be false
+ end
+ end
+
+ describe "#missing_extensions?" do
+ it "returns false if manually_installed?" do
+ stub = described_class.from_stub(with_bundler_stub_spec)
+ expect(stub.missing_extensions?).to be false
+ end
+
+ it "returns true if not manually_installed?" do
+ stub = described_class.from_stub(with_bundler_stub_spec)
+ stub.installed_by_version = Gem::Version.new(1)
+ expect(stub.missing_extensions?).to be true
end
end
end
diff --git a/spec/bundler/bundler/ui/shell_spec.rb b/spec/bundler/bundler/ui/shell_spec.rb
new file mode 100644
index 0000000000..536014c6aa
--- /dev/null
+++ b/spec/bundler/bundler/ui/shell_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require_relative "../../support/streams"
+
+RSpec.describe Bundler::UI::Shell do
+ subject { described_class.new }
+
+ before { subject.level = "debug" }
+
+ describe "#info" do
+ before { subject.level = "info" }
+ it "prints to stdout" do
+ expect { subject.info("info") }.to output("info\n").to_stdout
+ end
+ end
+
+ describe "#confirm" do
+ before { subject.level = "confirm" }
+ it "prints to stdout" do
+ expect { subject.confirm("confirm") }.to output("confirm\n").to_stdout
+ end
+ end
+
+ describe "#warn" do
+ before { subject.level = "warn" }
+ it "prints to stderr" do
+ expect { subject.warn("warning") }.to output("warning\n").to_stderr
+ end
+ end
+
+ describe "#debug" do
+ it "prints to stdout" do
+ expect { subject.debug("debug") }.to output("debug\n").to_stdout
+ end
+ end
+
+ describe "#error" do
+ before { subject.level = "error" }
+
+ it "prints to stderr" do
+ expect { subject.error("error!!!") }.to output("error!!!\n").to_stderr
+ end
+
+ context "when stderr is closed" do
+ it "doesn't report anything" do
+ output = capture(:stderr, :closed => true) do
+ subject.error("Something went wrong")
+ end
+ expect(output).to_not eq("Something went wrong\n")
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/ui_spec.rb b/spec/bundler/bundler/ui_spec.rb
index fc76eb1ee7..6df0d2e290 100644
--- a/spec/bundler/bundler/ui_spec.rb
+++ b/spec/bundler/bundler/ui_spec.rb
@@ -1,9 +1,8 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::UI do
describe Bundler::UI::Silent do
- it "has the same instance methods as Shell", :ruby => ">= 1.9" do
+ it "has the same instance methods as Shell" do
shell = Bundler::UI::Shell
methods = proc do |cls|
cls.instance_methods.map do |i|
@@ -14,7 +13,7 @@ RSpec.describe Bundler::UI do
expect(methods.call(described_class)).to eq(methods.call(shell))
end
- it "has the same instance class as Shell", :ruby => ">= 1.9" do
+ it "has the same instance class as Shell" do
shell = Bundler::UI::Shell
methods = proc do |cls|
cls.methods.map do |i|
diff --git a/spec/bundler/bundler/uri_credentials_filter_spec.rb b/spec/bundler/bundler/uri_credentials_filter_spec.rb
index 1dd01b4be0..466c1b8594 100644
--- a/spec/bundler/bundler/uri_credentials_filter_spec.rb
+++ b/spec/bundler/bundler/uri_credentials_filter_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe Bundler::URICredentialsFilter do
subject { described_class }
@@ -17,7 +16,7 @@ RSpec.describe Bundler::URICredentialsFilter do
let(:credentials) { "oauth_token:x-oauth-basic@" }
it "returns the uri without the oauth token" do
- expect(subject.credential_filtered_uri(uri).to_s).to eq(URI("https://x-oauth-basic@github.com/company/private-repo").to_s)
+ expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://x-oauth-basic@github.com/company/private-repo").to_s)
end
it_behaves_like "original type of uri is maintained"
@@ -27,7 +26,7 @@ RSpec.describe Bundler::URICredentialsFilter do
let(:credentials) { "oauth_token:x@" }
it "returns the uri without the oauth token" do
- expect(subject.credential_filtered_uri(uri).to_s).to eq(URI("https://x@github.com/company/private-repo").to_s)
+ expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://x@github.com/company/private-repo").to_s)
end
it_behaves_like "original type of uri is maintained"
@@ -38,7 +37,7 @@ RSpec.describe Bundler::URICredentialsFilter do
let(:credentials) { "username1:hunter3@" }
it "returns the uri without the password" do
- expect(subject.credential_filtered_uri(uri).to_s).to eq(URI("https://username1@github.com/company/private-repo").to_s)
+ expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://username1@github.com/company/private-repo").to_s)
end
it_behaves_like "original type of uri is maintained"
@@ -56,7 +55,7 @@ RSpec.describe Bundler::URICredentialsFilter do
end
context "uri is a uri object" do
- let(:uri) { URI("https://#{credentials}github.com/company/private-repo") }
+ let(:uri) { Bundler::URI("https://#{credentials}github.com/company/private-repo") }
it_behaves_like "sensitive credentials in uri are filtered out"
end
@@ -91,7 +90,7 @@ RSpec.describe Bundler::URICredentialsFilter do
describe "#credential_filtered_string" do
let(:str_to_filter) { "This is a git message containing a uri #{uri}!" }
let(:credentials) { "" }
- let(:uri) { URI("https://#{credentials}github.com/company/private-repo") }
+ let(:uri) { Bundler::URI("https://#{credentials}github.com/company/private-repo") }
context "with a uri that contains credentials" do
let(:credentials) { "oauth_token:x-oauth-basic@" }
diff --git a/spec/bundler/bundler/vendored_persistent_spec.rb b/spec/bundler/bundler/vendored_persistent_spec.rb
new file mode 100644
index 0000000000..3ed899dbcf
--- /dev/null
+++ b/spec/bundler/bundler/vendored_persistent_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require "bundler/vendored_persistent"
+
+RSpec.describe Bundler::PersistentHTTP do
+ describe "#warn_old_tls_version_rubygems_connection" do
+ let(:uri) { "https://index.rubygems.org" }
+ let(:connection) { instance_double(Bundler::Persistent::Net::HTTP::Persistent::Connection) }
+ let(:tls_version) { "TLSv1.2" }
+ let(:socket) { double("Socket") }
+ let(:socket_io) { double("SocketIO") }
+
+ before do
+ allow(connection).to receive_message_chain(:http, :use_ssl?).and_return(!tls_version.nil?)
+ allow(socket).to receive(:io).and_return(socket_io) if socket
+ connection.instance_variable_set(:@socket, socket)
+
+ if tls_version
+ allow(socket_io).to receive(:ssl_version).and_return(tls_version)
+ end
+ end
+
+ shared_examples_for "does not warn" do
+ it "does not warn" do
+ allow(Bundler.ui).to receive(:warn).never
+ subject.warn_old_tls_version_rubygems_connection(Bundler::URI(uri), connection)
+ end
+ end
+
+ shared_examples_for "does warn" do |*expected|
+ it "warns" do
+ expect(Bundler.ui).to receive(:warn).with(*expected)
+ subject.warn_old_tls_version_rubygems_connection(Bundler::URI(uri), connection)
+ end
+ end
+
+ context "an HTTPS uri with TLSv1.2" do
+ include_examples "does not warn"
+ end
+
+ context "without SSL" do
+ let(:tls_version) { nil }
+
+ include_examples "does not warn"
+ end
+
+ context "without a socket" do
+ let(:socket) { nil }
+
+ include_examples "does not warn"
+ end
+
+ context "with a different TLD" do
+ let(:uri) { "https://foo.bar" }
+ include_examples "does not warn"
+
+ context "and an outdated TLS version" do
+ let(:tls_version) { "TLSv1" }
+ include_examples "does not warn"
+ end
+ end
+
+ context "with a nonsense TLS version" do
+ let(:tls_version) { "BlahBlah2.0Blah" }
+ include_examples "does not warn"
+ end
+
+ context "with an outdated TLS version" do
+ let(:tls_version) { "TLSv1" }
+ include_examples "does warn",
+ "Warning: Your Ruby version is compiled against a copy of OpenSSL that is very old. " \
+ "Starting in January 2018, RubyGems.org will refuse connection requests from these very old versions of OpenSSL. " \
+ "If you will need to continue installing gems after January 2018, please follow this guide to upgrade: http://ruby.to/tls-outdated.",
+ :wrap => true
+ end
+ end
+end
diff --git a/spec/bundler/bundler/version_ranges_spec.rb b/spec/bundler/bundler/version_ranges_spec.rb
index f746aa88ad..bca044b0c0 100644
--- a/spec/bundler/bundler/version_ranges_spec.rb
+++ b/spec/bundler/bundler/version_ranges_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/version_ranges"
RSpec.describe Bundler::VersionRanges do
@@ -25,9 +25,12 @@ RSpec.describe Bundler::VersionRanges do
include_examples "empty?", false, ">= 1.0.0", "< 2.0.0"
include_examples "empty?", false, "~> 1"
include_examples "empty?", false, "~> 2.0", "~> 2.1"
+ include_examples "empty?", true, ">= 4.1.0", "< 5.0", "= 5.2.1"
+ include_examples "empty?", true, "< 5.0", "< 5.3", "< 6.0", "< 6", "= 5.2.0", "> 2", ">= 3.0", ">= 3.1", ">= 3.2", ">= 4.0.0", ">= 4.1.0", ">= 4.2.0", ">= 4.2", ">= 4"
include_examples "empty?", true, "!= 1", "< 2", "> 2"
include_examples "empty?", true, "!= 1", "<= 1", ">= 1"
include_examples "empty?", true, "< 2", "> 2"
+ include_examples "empty?", true, "< 2", "> 2", "= 2"
include_examples "empty?", true, "= 1", "!= 1"
include_examples "empty?", true, "= 1", "= 2"
include_examples "empty?", true, "= 1", "~> 2"
diff --git a/spec/bundler/bundler/worker_spec.rb b/spec/bundler/bundler/worker_spec.rb
index fbfe6ddab3..e4ebbd2932 100644
--- a/spec/bundler/bundler/worker_spec.rb
+++ b/spec/bundler/bundler/worker_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/worker"
RSpec.describe Bundler::Worker do
@@ -19,4 +19,51 @@ RSpec.describe Bundler::Worker do
end
end
end
+
+ describe "handling interrupts" do
+ let(:status) do
+ pid = Process.fork do
+ $stderr.reopen File.new("/dev/null", "w")
+ Signal.trap "INT", previous_interrupt_handler
+ subject.enq "a"
+ subject.stop unless interrupt_before_stopping
+ Process.kill "INT", Process.pid
+ end
+
+ Process.wait2(pid).last
+ end
+
+ before do
+ skip "requires Process.fork" unless Process.respond_to?(:fork)
+ end
+
+ context "when interrupted before stopping" do
+ let(:interrupt_before_stopping) { true }
+ let(:previous_interrupt_handler) { ->(*) { exit 0 } }
+
+ it "aborts" do
+ expect(status.exitstatus).to eq(1)
+ end
+ end
+
+ context "when interrupted after stopping" do
+ let(:interrupt_before_stopping) { false }
+
+ context "when the previous interrupt handler was the default" do
+ let(:previous_interrupt_handler) { "DEFAULT" }
+
+ it "uses the default interrupt handler" do
+ expect(status).to be_signaled
+ end
+ end
+
+ context "when the previous interrupt handler was customized" do
+ let(:previous_interrupt_handler) { ->(*) { exit 42 } }
+
+ it "restores the custom interrupt handler after stopping" do
+ expect(status.exitstatus).to eq(42)
+ end
+ end
+ end
+ end
end
diff --git a/spec/bundler/bundler/yaml_serializer_spec.rb b/spec/bundler/bundler/yaml_serializer_spec.rb
index c28db59223..1241c74bbf 100644
--- a/spec/bundler/bundler/yaml_serializer_spec.rb
+++ b/spec/bundler/bundler/yaml_serializer_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "bundler/yaml_serializer"
RSpec.describe Bundler::YAMLSerializer do
@@ -156,6 +156,7 @@ RSpec.describe Bundler::YAMLSerializer do
"a_joke" => {
"my-stand" => "I can totally keep secrets",
"but" => "The people I tell them to can't :P",
+ "wouldn't it be funny if this string were empty?" => "",
},
"more" => {
"first" => [
diff --git a/spec/bundler/cache/cache_path_spec.rb b/spec/bundler/cache/cache_path_spec.rb
index ec6d6e312a..12385427b1 100644
--- a/spec/bundler/cache/cache_path_spec.rb
+++ b/spec/bundler/cache/cache_path_spec.rb
@@ -1,34 +1,32 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle package" do
before do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
context "with --cache-path" do
it "caches gems at given path" do
- bundle :package, "cache-path" => "vendor/cache-foo"
+ bundle :cache, "cache-path" => "vendor/cache-foo"
expect(bundled_app("vendor/cache-foo/rack-1.0.0.gem")).to exist
end
end
context "with config cache_path" do
it "caches gems at given path" do
- bundle "config cache_path vendor/cache-foo"
- bundle :package
+ bundle "config set cache_path vendor/cache-foo"
+ bundle :cache
expect(bundled_app("vendor/cache-foo/rack-1.0.0.gem")).to exist
end
end
- context "when given an absolute path" do
- it "exits with non-zero status" do
- bundle :package, "cache-path" => "/tmp/cache-foo"
- expect(out).to match(/must be relative/)
- expect(exitstatus).to eq(15) if exitstatus
+ context "with absolute --cache-path" do
+ it "caches gems at given path" do
+ bundle :cache, "cache-path" => "/tmp/cache-foo"
+ expect(bundled_app("/tmp/cache-foo/rack-1.0.0.gem")).to exist
end
end
end
diff --git a/spec/bundler/cache/gems_spec.rb b/spec/bundler/cache/gems_spec.rb
index 7828c87fec..a8382a5d8c 100644
--- a/spec/bundler/cache/gems_spec.rb
+++ b/spec/bundler/cache/gems_spec.rb
@@ -1,14 +1,14 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle cache" do
- describe "when there are only gemsources" do
+ shared_examples_for "when there are only gemsources" do
before :each do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
- system_gems "rack-1.0.0"
+ system_gems "rack-1.0.0", :path => path
bundle :cache
end
@@ -20,7 +20,7 @@ RSpec.describe "bundle cache" do
build_gem "omg", :path => bundled_app("vendor/cache")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "omg"
G
@@ -28,7 +28,7 @@ RSpec.describe "bundle cache" do
end
it "uses the cache as a source when installing gems with --local" do
- system_gems []
+ system_gems [], :path => default_bundle_path
bundle "install --local"
expect(the_bundle).to include_gems("rack 1.0.0")
@@ -40,6 +40,7 @@ RSpec.describe "bundle cache" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -47,9 +48,10 @@ RSpec.describe "bundle cache" do
end
it "does not reinstall gems from the cache if they exist in the bundle" do
- system_gems "rack-1.0.0"
+ system_gems "rack-1.0.0", :path => default_bundle_path
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -57,7 +59,7 @@ RSpec.describe "bundle cache" do
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
- bundle "install --local"
+ bundle :install, :local => true
expect(the_bundle).to include_gems("rack 1.0.0")
end
@@ -65,43 +67,55 @@ RSpec.describe "bundle cache" do
cache_gems "rack-1.0.0"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "cache"
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
end
- describe "when there is a built-in gem", :ruby => "2.0" do
+ context "using system gems" do
+ before { bundle "config set path.system true" }
+ let(:path) { system_gem_path }
+ it_behaves_like "when there are only gemsources"
+ end
+
+ context "installing into a local path" do
+ before { bundle "config set path ./.bundle" }
+ let(:path) { local_gem_path }
+ it_behaves_like "when there are only gemsources"
+ end
+
+ describe "when there is a built-in gem", :ruby_repo do
+ let(:default_json_version) { ruby "gem 'json'; require 'json'; puts JSON::VERSION" }
+
before :each do
build_repo2 do
- build_gem "builtin_gem", "1.0.2"
+ build_gem "json", default_json_version
end
- build_gem "builtin_gem", "1.0.2", :to_system => true do |s|
- s.summary = "This builtin_gem is bundled with Ruby"
- end
-
- FileUtils.rm("#{system_gem_path}/cache/builtin_gem-1.0.2.gem")
+ build_gem "json", default_json_version, :to_system => true, :default => true
end
- it "uses builtin gems" do
- install_gemfile %(gem 'builtin_gem', '1.0.2')
- expect(the_bundle).to include_gems("builtin_gem 1.0.2")
+ it "uses builtin gems when installing to system gems" do
+ bundle "config set path.system true"
+ install_gemfile %(source "#{file_uri_for(gem_repo1)}"; gem 'json', '#{default_json_version}'), :verbose => true
+ expect(out).to include("Using json #{default_json_version}")
end
it "caches remote and builtin gems" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem 'builtin_gem', '1.0.2'
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'json', '#{default_json_version}'
gem 'rack', '1.0.0'
G
bundle :cache
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- expect(bundled_app("vendor/cache/builtin_gem-1.0.2.gem")).to exist
+ expect(bundled_app("vendor/cache/json-#{default_json_version}.gem")).to exist
end
it "doesn't make remote request after caching the gem" do
@@ -110,7 +124,7 @@ RSpec.describe "bundle cache" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'builtin_gem_2', '1.0.2'
G
@@ -119,13 +133,16 @@ RSpec.describe "bundle cache" do
end
it "errors if the builtin gem isn't available to cache" do
+ bundle "config set path.system true"
+
install_gemfile <<-G
- gem 'builtin_gem', '1.0.2'
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'json', '#{default_json_version}'
G
- bundle :cache
- expect(exitstatus).to_not eq(0) if exitstatus
- expect(out).to include("builtin_gem-1.0.2 is built in to Ruby, and can't be cached")
+ bundle :cache, :raise_on_error => false
+ expect(exitstatus).to_not eq(0)
+ expect(err).to include("json-#{default_json_version} is built in to Ruby, and can't be cached")
end
end
@@ -135,7 +152,7 @@ RSpec.describe "bundle cache" do
system_gems "rack-1.0.0"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem 'foo'
end
@@ -153,11 +170,11 @@ RSpec.describe "bundle cache" do
end
it "should not explode if the lockfile is not present" do
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
bundle :cache
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
end
@@ -165,7 +182,7 @@ RSpec.describe "bundle cache" do
before :each do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
gem "actionpack"
G
@@ -183,15 +200,20 @@ RSpec.describe "bundle cache" do
end
it "adds and removes when gems are updated" do
- update_repo2
- bundle "update"
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+ end
+
+ bundle "update", :all => true
expect(cached_gem("rack-1.2")).to exist
expect(cached_gem("rack-1.0.0")).not_to exist
end
it "adds new gems and dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails"
G
expect(cached_gem("rails-2.3.2")).to exist
@@ -200,7 +222,7 @@ RSpec.describe "bundle cache" do
it "removes .gems for removed gems and dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
expect(cached_gem("rack-1.0.0")).to exist
@@ -212,7 +234,7 @@ RSpec.describe "bundle cache" do
build_git "rack"
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack", :git => "#{lib_path("rack-1.0")}"
gem "actionpack"
G
@@ -224,7 +246,7 @@ RSpec.describe "bundle cache" do
it "doesn't remove gems that are for another platform" do
simulate_platform "java" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
@@ -234,7 +256,7 @@ RSpec.describe "bundle cache" do
simulate_new_machine
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
@@ -261,7 +283,7 @@ RSpec.describe "bundle cache" do
it "does not say that it is removing gems when it isn't actually doing so" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "cache"
@@ -271,7 +293,7 @@ RSpec.describe "bundle cache" do
it "does not warn about all if it doesn't have any git/path dependency" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "cache"
@@ -283,6 +305,7 @@ RSpec.describe "bundle cache" do
:path => bundled_app("vendor/cache")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo-bundler"
G
diff --git a/spec/bundler/cache/git_spec.rb b/spec/bundler/cache/git_spec.rb
index 31b3816a3b..10e44656b8 100644
--- a/spec/bundler/cache/git_spec.rb
+++ b/spec/bundler/cache/git_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "git base name" do
it "base_name should strip private repo uris" do
@@ -13,203 +12,213 @@ RSpec.describe "git base name" do
end
end
-%w(cache package).each do |cmd|
- RSpec.describe "bundle #{cmd} with git" do
- it "copies repository to vendor cache and uses it" do
- git = build_git "foo"
- ref = git.ref_for("master", 11)
+RSpec.describe "bundle cache with git" do
+ it "copies repository to vendor cache and uses it" do
+ git = build_git "foo"
+ ref = git.ref_for("master", 11)
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
- bundle "#{cmd} --all"
- expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
- expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist
- expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.bundlecache")).to be_file
+ bundle "config set cache_all true"
+ bundle :cache
+ expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
+ expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist
+ expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.bundlecache")).to be_file
- FileUtils.rm_rf lib_path("foo-1.0")
- expect(the_bundle).to include_gems "foo 1.0"
- end
-
- it "copies repository to vendor cache and uses it even when installed with bundle --path" do
- git = build_git "foo"
- ref = git.ref_for("master", 11)
-
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
-
- bundle "install --path vendor/bundle"
- bundle "#{cmd} --all"
-
- expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
- expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist
+ FileUtils.rm_rf lib_path("foo-1.0")
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
- FileUtils.rm_rf lib_path("foo-1.0")
- expect(the_bundle).to include_gems "foo 1.0"
- end
+ it "copies repository to vendor cache and uses it even when configured with `path`" do
+ git = build_git "foo"
+ ref = git.ref_for("master", 11)
- it "runs twice without exploding" do
- build_git "foo"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
+ bundle "config set --local path vendor/bundle"
+ bundle "install"
+ bundle "config set cache_all true"
+ bundle :cache
- bundle "#{cmd} --all"
- bundle "#{cmd} --all"
+ expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
+ expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist
- expect(err).to lack_errors
- FileUtils.rm_rf lib_path("foo-1.0")
- expect(the_bundle).to include_gems "foo 1.0"
- end
+ FileUtils.rm_rf lib_path("foo-1.0")
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
- it "tracks updates" do
- git = build_git "foo"
- old_ref = git.ref_for("master", 11)
+ it "runs twice without exploding" do
+ build_git "foo"
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
- bundle "#{cmd} --all"
+ bundle "config set cache_all true"
+ bundle :cache
+ bundle :cache
- update_git "foo" do |s|
- s.write "lib/foo.rb", "puts :CACHE"
- end
+ expect(out).to include "Updating files in vendor/cache"
+ FileUtils.rm_rf lib_path("foo-1.0")
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
- ref = git.ref_for("master", 11)
- expect(ref).not_to eq(old_ref)
+ it "tracks updates" do
+ git = build_git "foo"
+ old_ref = git.ref_for("master", 11)
- bundle "update"
- bundle "#{cmd} --all"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
- expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
- expect(bundled_app("vendor/cache/foo-1.0-#{old_ref}")).not_to exist
+ bundle "config set cache_all true"
+ bundle :cache
- FileUtils.rm_rf lib_path("foo-1.0")
- run "require 'foo'"
- expect(out).to eq("CACHE")
+ update_git "foo" do |s|
+ s.write "lib/foo.rb", "puts :CACHE"
end
- it "tracks updates when specifying the gem" do
- git = build_git "foo"
- old_ref = git.ref_for("master", 11)
+ ref = git.ref_for("master", 11)
+ expect(ref).not_to eq(old_ref)
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
+ bundle "update", :all => true
+ bundle "config set cache_all true"
+ bundle :cache
- bundle "#{cmd} --all"
+ expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
+ expect(bundled_app("vendor/cache/foo-1.0-#{old_ref}")).not_to exist
- update_git "foo" do |s|
- s.write "lib/foo.rb", "puts :CACHE"
- end
+ FileUtils.rm_rf lib_path("foo-1.0")
+ run "require 'foo'"
+ expect(out).to eq("CACHE")
+ end
- ref = git.ref_for("master", 11)
- expect(ref).not_to eq(old_ref)
+ it "tracks updates when specifying the gem" do
+ git = build_git "foo"
+ old_ref = git.ref_for("master", 11)
- bundle "update foo"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
- expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
- expect(bundled_app("vendor/cache/foo-1.0-#{old_ref}")).not_to exist
+ bundle "config set cache_all true"
+ bundle :cache
- FileUtils.rm_rf lib_path("foo-1.0")
- run "require 'foo'"
- expect(out).to eq("CACHE")
+ update_git "foo" do |s|
+ s.write "lib/foo.rb", "puts :CACHE"
end
- it "uses the local repository to generate the cache" do
- git = build_git "foo"
- ref = git.ref_for("master", 11)
-
- gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-invalid")}', :branch => :master
- G
+ ref = git.ref_for("master", 11)
+ expect(ref).not_to eq(old_ref)
- bundle %(config local.foo #{lib_path("foo-1.0")})
- bundle "install"
- bundle "#{cmd} --all"
+ bundle "update foo"
- expect(bundled_app("vendor/cache/foo-invalid-#{ref}")).to exist
+ expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
+ expect(bundled_app("vendor/cache/foo-1.0-#{old_ref}")).not_to exist
- # Updating the local still uses the local.
- update_git "foo" do |s|
- s.write "lib/foo.rb", "puts :LOCAL"
- end
-
- run "require 'foo'"
- expect(out).to eq("LOCAL")
- end
-
- it "copies repository to vendor cache, including submodules" do
- build_git "submodule", "1.0"
+ FileUtils.rm_rf lib_path("foo-1.0")
+ run "require 'foo'"
+ expect(out).to eq("CACHE")
+ end
- git = build_git "has_submodule", "1.0" do |s|
- s.add_dependency "submodule"
- end
+ it "uses the local repository to generate the cache" do
+ git = build_git "foo"
+ ref = git.ref_for("master", 11)
- Dir.chdir(lib_path("has_submodule-1.0")) do
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0"
- `git commit -m "submodulator"`
- end
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-invalid")}', :branch => :master
+ G
- install_gemfile <<-G
- git "#{lib_path("has_submodule-1.0")}", :submodules => true do
- gem "has_submodule"
- end
- G
+ bundle %(config set local.foo #{lib_path("foo-1.0")})
+ bundle "install"
+ bundle "config set cache_all true"
+ bundle :cache
- ref = git.ref_for("master", 11)
- bundle "#{cmd} --all"
+ expect(bundled_app("vendor/cache/foo-invalid-#{ref}")).to exist
- expect(bundled_app("vendor/cache/has_submodule-1.0-#{ref}")).to exist
- expect(bundled_app("vendor/cache/has_submodule-1.0-#{ref}/submodule-1.0")).to exist
- expect(the_bundle).to include_gems "has_submodule 1.0"
+ # Updating the local still uses the local.
+ update_git "foo" do |s|
+ s.write "lib/foo.rb", "puts :LOCAL"
end
- it "displays warning message when detecting git repo in Gemfile" do
- build_git "foo"
+ run "require 'foo'"
+ expect(out).to eq("LOCAL")
+ end
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
+ it "copies repository to vendor cache, including submodules" do
+ # CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
+ system(*%W[git config --global protocol.file.allow always])
- bundle "#{cmd}"
+ build_git "submodule", "1.0"
- expect(out).to include("Your Gemfile contains path and git dependencies.")
+ git = build_git "has_submodule", "1.0" do |s|
+ s.add_dependency "submodule"
end
- it "does not display warning message if cache_all is set in bundle config" do
- build_git "foo"
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ git "#{lib_path("has_submodule-1.0")}", :submodules => true do
+ gem "has_submodule"
+ end
+ G
- bundle "#{cmd} --all"
- bundle "#{cmd}"
+ ref = git.ref_for("master", 11)
+ bundle "config set cache_all true"
+ bundle :cache
- expect(out).not_to include("Your Gemfile contains path and git dependencies.")
- end
+ expect(bundled_app("vendor/cache/has_submodule-1.0-#{ref}")).to exist
+ expect(bundled_app("vendor/cache/has_submodule-1.0-#{ref}/submodule-1.0")).to exist
+ expect(the_bundle).to include_gems "has_submodule 1.0"
+ end
+
+ it "caches pre-evaluated gemspecs" do
+ git = build_git "foo"
- it "caches pre-evaluated gemspecs" do
- git = build_git "foo"
+ # Insert a gemspec method that shells out
+ spec_lines = lib_path("foo-1.0/foo.gemspec").read.split("\n")
+ spec_lines.insert(-2, "s.description = `echo bob`")
+ update_git("foo") {|s| s.write "foo.gemspec", spec_lines.join("\n") }
- # Insert a gemspec method that shells out
- spec_lines = lib_path("foo-1.0/foo.gemspec").read.split("\n")
- spec_lines.insert(-2, "s.description = `echo bob`")
- update_git("foo") {|s| s.write "foo.gemspec", spec_lines.join("\n") }
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
+ bundle "config set cache_all true"
+ bundle :cache
- install_gemfile <<-G
- gem "foo", :git => '#{lib_path("foo-1.0")}'
- G
- bundle "#{cmd} --all"
+ ref = git.ref_for("master", 11)
+ gemspec = bundled_app("vendor/cache/foo-1.0-#{ref}/foo.gemspec").read
+ expect(gemspec).to_not match("`echo bob`")
+ end
- ref = git.ref_for("master", 11)
- gemspec = bundled_app("vendor/cache/foo-1.0-#{ref}/foo.gemspec").read
- expect(gemspec).to_not match("`echo bob`")
+ it "can install after bundle cache with git not installed" do
+ build_git "foo"
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
+ bundle "config set cache_all true"
+ bundle :cache, "all-platforms" => true, :install => false
+
+ simulate_new_machine
+ with_path_as "" do
+ bundle "config set deployment true"
+ bundle :install, :local => true
+ expect(the_bundle).to include_gem "foo 1.0"
end
end
end
diff --git a/spec/bundler/cache/path_spec.rb b/spec/bundler/cache/path_spec.rb
index bbce448759..2ad136a008 100644
--- a/spec/bundler/cache/path_spec.rb
+++ b/spec/bundler/cache/path_spec.rb
@@ -1,140 +1,169 @@
# frozen_string_literal: true
-require "spec_helper"
-%w(cache package).each do |cmd|
- RSpec.describe "bundle #{cmd} with path" do
- it "is no-op when the path is within the bundle" do
- build_lib "foo", :path => bundled_app("lib/foo")
+RSpec.describe "bundle cache with path" do
+ it "is no-op when the path is within the bundle" do
+ build_lib "foo", :path => bundled_app("lib/foo")
- install_gemfile <<-G
- gem "foo", :path => '#{bundled_app("lib/foo")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{bundled_app("lib/foo")}'
+ G
- bundle "#{cmd} --all"
- expect(bundled_app("vendor/cache/foo-1.0")).not_to exist
- expect(the_bundle).to include_gems "foo 1.0"
- end
+ bundle "config set cache_all true"
+ bundle :cache
+ expect(bundled_app("vendor/cache/foo-1.0")).not_to exist
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
- it "copies when the path is outside the bundle " do
- build_lib "foo"
+ it "copies when the path is outside the bundle " do
+ build_lib "foo"
- install_gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ G
- bundle "#{cmd} --all"
- expect(bundled_app("vendor/cache/foo-1.0")).to exist
- expect(bundled_app("vendor/cache/foo-1.0/.bundlecache")).to be_file
+ bundle "config set cache_all true"
+ bundle :cache
+ expect(bundled_app("vendor/cache/foo-1.0")).to exist
+ expect(bundled_app("vendor/cache/foo-1.0/.bundlecache")).to be_file
- FileUtils.rm_rf lib_path("foo-1.0")
- expect(the_bundle).to include_gems "foo 1.0"
- end
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
+
+ it "copies when the path is outside the bundle and the paths intersect" do
+ libname = File.basename(bundled_app) + "_gem"
+ libpath = File.join(File.dirname(bundled_app), libname)
- it "copies when the path is outside the bundle and the paths intersect" do
- libname = File.basename(Dir.pwd) + "_gem"
- libpath = File.join(File.dirname(Dir.pwd), libname)
+ build_lib libname, :path => libpath
- build_lib libname, :path => libpath
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "#{libname}", :path => '#{libpath}'
+ G
- install_gemfile <<-G
- gem "#{libname}", :path => '#{libpath}'
- G
+ bundle "config set cache_all true"
+ bundle :cache
+ expect(bundled_app("vendor/cache/#{libname}")).to exist
+ expect(bundled_app("vendor/cache/#{libname}/.bundlecache")).to be_file
- bundle "#{cmd} --all"
- expect(bundled_app("vendor/cache/#{libname}")).to exist
- expect(bundled_app("vendor/cache/#{libname}/.bundlecache")).to be_file
+ expect(the_bundle).to include_gems "#{libname} 1.0"
+ end
+
+ it "updates the path on each cache" do
+ build_lib "foo"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ G
- FileUtils.rm_rf libpath
- expect(the_bundle).to include_gems "#{libname} 1.0"
+ bundle "config set cache_all true"
+ bundle :cache
+
+ build_lib "foo" do |s|
+ s.write "lib/foo.rb", "puts :CACHE"
end
- it "updates the path on each cache" do
- build_lib "foo"
+ bundle :cache
+
+ expect(bundled_app("vendor/cache/foo-1.0")).to exist
- install_gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- G
+ run "require 'foo'"
+ expect(out).to eq("CACHE")
+ end
- bundle "#{cmd} --all"
+ it "removes stale entries cache" do
+ build_lib "foo"
- build_lib "foo" do |s|
- s.write "lib/foo.rb", "puts :CACHE"
- end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ G
- bundle "#{cmd} --all"
+ bundle "config set cache_all true"
+ bundle :cache
- expect(bundled_app("vendor/cache/foo-1.0")).to exist
- FileUtils.rm_rf lib_path("foo-1.0")
+ expect(bundled_app("vendor/cache/foo-1.0")).to exist
- run "require 'foo'"
- expect(out).to eq("CACHE")
- end
+ build_lib "bar"
- it "removes stale entries cache" do
- build_lib "foo"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "bar", :path => '#{lib_path("bar-1.0")}'
+ G
- install_gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- G
+ bundle :cache
+ expect(bundled_app("vendor/cache/foo-1.0")).not_to exist
+ end
- bundle "#{cmd} --all"
+ it "does not cache path gems by default", :bundler => "< 3" do
+ build_lib "foo"
- install_gemfile <<-G
- gem "bar", :path => '#{lib_path("bar-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ G
- bundle "#{cmd} --all"
- expect(bundled_app("vendor/cache/bar-1.0")).not_to exist
- end
+ bundle :cache
+ expect(err).to be_empty
+ expect(bundled_app("vendor/cache/foo-1.0")).not_to exist
+ end
- it "raises a warning without --all" do
- build_lib "foo"
+ it "caches path gems by default", :bundler => "3" do
+ build_lib "foo"
- install_gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ G
- bundle cmd
- expect(out).to match(/please pass the \-\-all flag/)
- expect(bundled_app("vendor/cache/foo-1.0")).not_to exist
- end
+ bundle :cache
+ expect(err).to be_empty
+ expect(bundled_app("vendor/cache/foo-1.0")).to exist
+ end
- it "stores the given flag" do
- build_lib "foo"
+ it "stores the given flag" do
+ build_lib "foo"
- install_gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ G
- bundle "#{cmd} --all"
- build_lib "bar"
+ bundle "config set cache_all true"
+ bundle :cache
+ build_lib "bar"
- install_gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- gem "bar", :path => '#{lib_path("bar-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ gem "bar", :path => '#{lib_path("bar-1.0")}'
+ G
- bundle cmd
- expect(bundled_app("vendor/cache/bar-1.0")).to exist
- end
+ bundle :cache
+ expect(bundled_app("vendor/cache/bar-1.0")).to exist
+ end
- it "can rewind chosen configuration" do
- build_lib "foo"
+ it "can rewind chosen configuration" do
+ build_lib "foo"
- install_gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ G
- bundle "#{cmd} --all"
- build_lib "baz"
+ bundle "config set cache_all true"
+ bundle :cache
+ build_lib "baz"
- gemfile <<-G
- gem "foo", :path => '#{lib_path("foo-1.0")}'
- gem "baz", :path => '#{lib_path("baz-1.0")}'
- G
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
+ gem "baz", :path => '#{lib_path("baz-1.0")}'
+ G
- bundle "#{cmd} --no-all"
- expect(bundled_app("vendor/cache/baz-1.0")).not_to exist
- end
+ bundle "cache --no-all", :raise_on_error => false
+ expect(bundled_app("vendor/cache/baz-1.0")).not_to exist
end
end
diff --git a/spec/bundler/cache/platform_spec.rb b/spec/bundler/cache/platform_spec.rb
index ed80c949aa..128278956c 100644
--- a/spec/bundler/cache/platform_spec.rb
+++ b/spec/bundler/cache/platform_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle cache with multiple platforms" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
platforms :mri, :rbx do
gem "rack", "1.0.0"
@@ -17,7 +16,7 @@ RSpec.describe "bundle cache with multiple platforms" do
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0.0)
activesupport (2.3.5)
@@ -37,16 +36,12 @@ RSpec.describe "bundle cache with multiple platforms" do
it "ensures that a successful bundle install does not delete gems for other platforms" do
bundle "install"
- expect(exitstatus).to eq 0 if exitstatus
-
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
expect(bundled_app("vendor/cache/activesupport-2.3.5.gem")).to exist
end
it "ensures that a successful bundle update does not delete gems for other platforms" do
- bundle "update"
-
- expect(exitstatus).to eq 0 if exitstatus
+ bundle "update", :all => true
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
expect(bundled_app("vendor/cache/activesupport-2.3.5.gem")).to exist
diff --git a/spec/bundler/commands/add_spec.rb b/spec/bundler/commands/add_spec.rb
index 4931402c33..4c533652ca 100644
--- a/spec/bundler/commands/add_spec.rb
+++ b/spec/bundler/commands/add_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle add" do
before :each do
@@ -12,34 +11,44 @@ RSpec.describe "bundle add" do
build_gem "dog", "1.1.3.pre"
end
- install_gemfile <<-G
- source "file://#{gem_repo2}"
+ build_git "foo", "2.0"
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
gem "weakling", "~> 0.0.1"
G
end
+ context "when no gems are specified" do
+ it "shows error" do
+ bundle "add", :raise_on_error => false
+
+ expect(err).to include("Please specify gems to add")
+ end
+ end
+
describe "without version specified" do
it "version requirement becomes ~> major.minor.patch when resolved version is < 1.0" do
bundle "add 'bar'"
- expect(bundled_app("Gemfile").read).to match(/gem "bar", "~> 0.12.3"/)
+ expect(bundled_app_gemfile.read).to match(/gem "bar", "~> 0.12.3"/)
expect(the_bundle).to include_gems "bar 0.12.3"
end
it "version requirement becomes ~> major.minor when resolved version is > 1.0" do
bundle "add 'baz'"
- expect(bundled_app("Gemfile").read).to match(/gem "baz", "~> 1.2"/)
+ expect(bundled_app_gemfile.read).to match(/gem "baz", "~> 1.2"/)
expect(the_bundle).to include_gems "baz 1.2.3"
end
it "version requirement becomes ~> major.minor.patch.pre when resolved version is < 1.0" do
bundle "add 'cat'"
- expect(bundled_app("Gemfile").read).to match(/gem "cat", "~> 0.12.3.pre"/)
+ expect(bundled_app_gemfile.read).to match(/gem "cat", "~> 0.12.3.pre"/)
expect(the_bundle).to include_gems "cat 0.12.3.pre"
end
it "version requirement becomes ~> major.minor.pre when resolved version is > 1.0.pre" do
bundle "add 'dog'"
- expect(bundled_app("Gemfile").read).to match(/gem "dog", "~> 1.1.pre"/)
+ expect(bundled_app_gemfile.read).to match(/gem "dog", "~> 1.1.pre"/)
expect(the_bundle).to include_gems "dog 1.1.3.pre"
end
end
@@ -47,13 +56,14 @@ RSpec.describe "bundle add" do
describe "with --version" do
it "adds dependency of specified version and runs install" do
bundle "add 'foo' --version='~> 1.0'"
- expect(bundled_app("Gemfile").read).to match(/gem "foo", "~> 1.0"/)
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 1.0"/)
expect(the_bundle).to include_gems "foo 1.1"
end
it "adds multiple version constraints when specified" do
- bundle "add 'foo' --version='< 3.0, > 1.1'"
- expect(bundled_app("Gemfile").read).to match(/gem "foo", "< 3.0", "> 1.1"/)
+ requirements = ["< 3.0", "> 1.0"]
+ bundle "add 'foo' --version='#{requirements.join(", ")}'"
+ expect(bundled_app_gemfile.read).to match(/gem "foo", #{Gem::Requirement.new(requirements).as_list.map(&:dump).join(', ')}/)
expect(the_bundle).to include_gems "foo 2.0"
end
end
@@ -61,49 +71,181 @@ RSpec.describe "bundle add" do
describe "with --group" do
it "adds dependency for the specified group" do
bundle "add 'foo' --group='development'"
- expect(bundled_app("Gemfile").read).to match(/gem "foo", "~> 2.0", :group => \[:development\]/)
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :group => :development/)
expect(the_bundle).to include_gems "foo 2.0"
end
it "adds dependency to more than one group" do
bundle "add 'foo' --group='development, test'"
- expect(bundled_app("Gemfile").read).to match(/gem "foo", "~> 2.0", :groups => \[:development, :test\]/)
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :groups => \[:development, :test\]/)
expect(the_bundle).to include_gems "foo 2.0"
end
end
describe "with --source" do
it "adds dependency with specified source" do
- bundle "add 'foo' --source='file://#{gem_repo2}'"
- expect(bundled_app("Gemfile").read).to match(%r{gem "foo", "~> 2.0", :source => "file:\/\/#{gem_repo2}"})
+ bundle "add 'foo' --source='#{file_uri_for(gem_repo2)}'"
+
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :source => "#{file_uri_for(gem_repo2)}"/)
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --git" do
+ it "adds dependency with specified github source" do
+ bundle "add foo --git=#{lib_path("foo-2.0")}"
+
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}"/)
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --git and --branch" do
+ before do
+ update_git "foo", "2.0", :branch => "test"
+ end
+
+ it "adds dependency with specified github source and branch" do
+ bundle "add foo --git=#{lib_path("foo-2.0")} --branch=test"
+
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}", :branch => "test"/)
expect(the_bundle).to include_gems "foo 2.0"
end
end
+ describe "with --skip-install" do
+ it "adds gem to Gemfile but is not installed" do
+ bundle "add foo --skip-install --version=2.0"
+
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "= 2.0"/)
+ expect(the_bundle).to_not include_gems "foo 2.0"
+ end
+ end
+
it "using combination of short form options works like long form" do
- bundle "add 'foo' -s='file://#{gem_repo2}' -g='development' -v='~>1.0'"
- expect(bundled_app("Gemfile").read).to match(%r{gem "foo", "~> 1.0", :group => \[:development\], :source => "file:\/\/#{gem_repo2}"})
+ bundle "add 'foo' -s='#{file_uri_for(gem_repo2)}' -g='development' -v='~>1.0'"
+ expect(bundled_app_gemfile.read).to include %(gem "foo", "~> 1.0", :group => :development, :source => "#{file_uri_for(gem_repo2)}")
expect(the_bundle).to include_gems "foo 1.1"
end
it "shows error message when version is not formatted correctly" do
- bundle "add 'foo' -v='~>1 . 0'"
- expect(out).to match("Invalid gem requirement pattern '~>1 . 0'")
+ bundle "add 'foo' -v='~>1 . 0'", :raise_on_error => false
+ expect(err).to match("Invalid gem requirement pattern '~>1 . 0'")
end
it "shows error message when gem cannot be found" do
- bundle "add 'werk_it'"
- expect(out).to match("Could not find gem 'werk_it' in any of the gem sources listed in your Gemfile.")
+ bundle "config set force_ruby_platform true"
+ bundle "add 'werk_it'", :raise_on_error => false
+ expect(err).to match("Could not find gem 'werk_it' in")
- bundle "add 'werk_it' -s='file://#{gem_repo2}'"
- expect(out).to match("Could not find gem 'werk_it' in rubygems repository")
+ bundle "add 'werk_it' -s='#{file_uri_for(gem_repo2)}'", :raise_on_error => false
+ expect(err).to match("Could not find gem 'werk_it' in rubygems repository")
end
it "shows error message when source cannot be reached" do
- bundle "add 'baz' --source='http://badhostasdf'"
- expect(out).to include("Could not reach host badhostasdf. Check your network connection and try again.")
+ bundle "add 'baz' --source='http://badhostasdf'", :raise_on_error => false
+ expect(err).to include("Could not reach host badhostasdf. Check your network connection and try again.")
+
+ bundle "add 'baz' --source='file://does/not/exist'", :raise_on_error => false
+ expect(err).to include("Could not fetch specs from file://does/not/exist/")
+ end
+
+ describe "with --optimistic" do
+ it "adds optimistic version" do
+ bundle "add 'foo' --optimistic"
+ expect(bundled_app_gemfile.read).to include %(gem "foo", ">= 2.0")
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --strict option" do
+ it "adds strict version" do
+ bundle "add 'foo' --strict"
+ expect(bundled_app_gemfile.read).to include %(gem "foo", "= 2.0")
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
- bundle "add 'baz' --source='file://does/not/exist'"
- expect(out).to include("Could not fetch specs from file://does/not/exist/")
+ describe "with no option" do
+ it "adds pessimistic version" do
+ bundle "add 'foo'"
+ expect(bundled_app_gemfile.read).to include %(gem "foo", "~> 2.0")
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --optimistic and --strict" do
+ it "throws error" do
+ bundle "add 'foo' --strict --optimistic", :raise_on_error => false
+
+ expect(err).to include("You can not specify `--strict` and `--optimistic` at the same time")
+ end
+ end
+
+ context "multiple gems" do
+ it "adds multiple gems to gemfile" do
+ bundle "add bar baz"
+
+ expect(bundled_app_gemfile.read).to match(/gem "bar", "~> 0.12.3"/)
+ expect(bundled_app_gemfile.read).to match(/gem "baz", "~> 1.2"/)
+ end
+
+ it "throws error if any of the specified gems are present in the gemfile with different version" do
+ bundle "add weakling bar", :raise_on_error => false
+
+ expect(err).to include("You cannot specify the same gem twice with different version requirements")
+ expect(err).to include("You specified: weakling (~> 0.0.1) and weakling (>= 0).")
+ end
+ end
+
+ describe "when a gem is added which is already specified in Gemfile with version" do
+ it "shows an error when added with different version requirement" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack", "1.0"
+ G
+
+ bundle "add 'rack' --version=1.1", :raise_on_error => false
+
+ expect(err).to include("You cannot specify the same gem twice with different version requirements")
+ expect(err).to include("If you want to update the gem version, run `bundle update rack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive")
+ end
+
+ it "shows error when added without version requirements" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack", "1.0"
+ G
+
+ bundle "add 'rack'", :raise_on_error => false
+
+ expect(err).to include("Gem already added.")
+ expect(err).to include("You cannot specify the same gem twice with different version requirements")
+ expect(err).not_to include("If you want to update the gem version, run `bundle update rack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive")
+ end
+ end
+
+ describe "when a gem is added which is already specified in Gemfile without version" do
+ it "shows an error when added with different version requirement" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ G
+
+ bundle "add 'rack' --version=1.1", :raise_on_error => false
+
+ expect(err).to include("You cannot specify the same gem twice with different version requirements")
+ expect(err).to include("If you want to update the gem version, run `bundle update rack`.")
+ expect(err).not_to include("You may also need to change the version requirement specified in the Gemfile if it's too restrictive")
+ end
+ end
+
+ describe "when a gem is added and cache exists" do
+ it "caches all new dependencies added for the specified gem" do
+ bundle :cache
+
+ bundle "add 'rack' --version=1.0.0"
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
end
end
diff --git a/spec/bundler/commands/binstubs_spec.rb b/spec/bundler/commands/binstubs_spec.rb
index cb0999348e..1cd0e16d95 100644
--- a/spec/bundler/commands/binstubs_spec.rb
+++ b/spec/bundler/commands/binstubs_spec.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle binstubs <gem>" do
context "when the gem exists in the lockfile" do
it "sets up the binstub" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -16,7 +15,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "does not install other binstubs" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rails"
G
@@ -29,7 +28,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "does install multiple binstubs" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rails"
G
@@ -40,35 +39,229 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("bin/rails")).to exist
end
+ it "allows installing all binstubs" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ G
+
+ bundle :binstubs, :all => true
+
+ expect(bundled_app("bin/rails")).to exist
+ expect(bundled_app("bin/rake")).to exist
+ end
+
+ it "allows installing binstubs for all platforms" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "binstubs rack --all-platforms"
+
+ expect(bundled_app("bin/rackup")).to exist
+ expect(bundled_app("bin/rackup.cmd")).to exist
+ end
+
it "displays an error when used without any gem" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "binstubs"
- expect(exitstatus).to eq(1) if exitstatus
- expect(out).to include("`bundle binstubs` needs at least one gem to run.")
+ bundle "binstubs", :raise_on_error => false
+ expect(exitstatus).to eq(1)
+ expect(err).to include("`bundle binstubs` needs at least one gem to run.")
end
- it "does not bundle the bundler binary" do
+ it "displays an error when used with --all and gems" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
G
- bundle "binstubs bundler"
+ bundle "binstubs rack", :all => true, :raise_on_error => false
+ expect(last_command).to be_failure
+ expect(err).to include("Cannot specify --all with specific gems")
+ end
+
+ context "when generating bundle binstub outside bundler" do
+ it "should abort" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
- expect(bundled_app("bin/bundle")).not_to exist
- expect(out).to include("Sorry, Bundler can only be run via Rubygems.")
+ bundle "binstubs rack"
+
+ File.open(bundled_app("bin/bundle"), "wb") do |file|
+ file.print "OMG"
+ end
+
+ sys_exec "bin/rackup", :raise_on_error => false
+
+ expect(err).to include("was not generated by Bundler")
+ end
+ end
+
+ context "the bundle binstub" do
+ before do
+ pristine_system_gems "bundler-#{system_bundler_version}"
+ build_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
+ build_gem "prints_loaded_gems", "1.0" do |s|
+ s.executables = "print_loaded_gems"
+ s.bindir = "exe"
+ s.write "exe/print_loaded_gems", <<-R
+ specs = Gem.loaded_specs.values.reject {|s| s.default_gem? }
+ puts specs.map(&:full_name).sort.inspect
+ R
+ end
+ end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ gem "prints_loaded_gems"
+ G
+ bundle "binstubs bundler rack prints_loaded_gems"
+ end
+
+ let(:system_bundler_version) { Bundler::VERSION }
+
+ it "runs bundler" do
+ sys_exec "bin/bundle install", :env => { "DEBUG" => "1" }
+ expect(out).to include %(Using bundler #{system_bundler_version}\n)
+ end
+
+ context "when BUNDLER_VERSION is set" do
+ it "runs the correct version of bundler" do
+ sys_exec "bin/bundle install", :env => { "BUNDLER_VERSION" => "999.999.999" }, :raise_on_error => false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (999.999.999) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
+ end
+
+ it "runs the correct version of bundler even if a higher version is installed" do
+ system_gems "bundler-999.999.998", "bundler-999.999.999"
+
+ sys_exec "bin/bundle install", :env => { "BUNDLER_VERSION" => "999.999.998", "DEBUG" => "1" }, :raise_on_error => false
+ expect(out).to include %(Using bundler 999.999.998\n)
+ end
+ end
+
+ context "when a lockfile exists with a locked bundler version" do
+ context "and the version is newer" do
+ before do
+ lockfile lockfile.gsub(system_bundler_version, "999.999")
+ end
+
+ it "runs the correct version of bundler" do
+ sys_exec "bin/bundle install", :raise_on_error => false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (~> 999.999) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`")
+ end
+ end
+
+ context "and the version is older and a different major" do
+ let(:system_bundler_version) { "55" }
+
+ before do
+ lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 44.0")
+ end
+
+ it "runs the correct version of bundler" do
+ sys_exec "bin/bundle install", :raise_on_error => false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (~> 44.0) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`")
+ end
+ end
+
+ context "and the version is older and the same major" do
+ let(:system_bundler_version) { "55.1" }
+
+ before do
+ lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 55.0")
+ end
+
+ it "runs the available version of bundler when the version is older and the same major" do
+ sys_exec "bin/bundle install"
+ expect(exitstatus).not_to eq(42)
+ expect(err).not_to include("Activating bundler (~> 55.0) failed:")
+ end
+ end
+
+ context "and the version is a pre-releaser" do
+ let(:system_bundler_version) { "55" }
+
+ before do
+ lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.12.0.a")
+ end
+
+ it "runs the correct version of bundler when the version is a pre-release" do
+ sys_exec "bin/bundle install", :raise_on_error => false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (~> 2.12.a) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 2.12.a'`")
+ end
+ end
+ end
+
+ context "when update --bundler is called" do
+ before { lockfile.gsub(system_bundler_version, "1.1.1") }
+
+ it "calls through to the latest bundler version" do
+ sys_exec "bin/bundle update --bundler", :env => { "DEBUG" => "1" }
+ expect(out).to include %(Using bundler #{system_bundler_version}\n)
+ end
+
+ it "calls through to the explicit bundler version" do
+ sys_exec "bin/bundle update --bundler=999.999.999", :raise_on_error => false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (999.999.999) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
+ end
+ end
+
+ context "without a lockfile" do
+ it "falls back to the latest installed bundler" do
+ FileUtils.rm bundled_app_lock
+ sys_exec "bin/bundle install", :env => { "DEBUG" => "1" }
+ expect(out).to include "Using bundler #{system_bundler_version}\n"
+ end
+ end
+
+ context "using another binstub" do
+ it "loads all gems" do
+ sys_exec bundled_app("bin/print_loaded_gems").to_s
+ expect(out).to eq %(["bundler-#{Bundler::VERSION}", "prints_loaded_gems-1.0", "rack-1.2"])
+ end
+
+ context "when requesting a different bundler version" do
+ before { lockfile lockfile.gsub(Bundler::VERSION, "999.999.999") }
+
+ it "attempts to load that version" do
+ sys_exec bundled_app("bin/rackup").to_s, :raise_on_error => false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (~> 999.999) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`")
+ end
+ end
+ end
end
it "installs binstubs from git gems" do
FileUtils.mkdir_p(lib_path("foo/bin"))
FileUtils.touch(lib_path("foo/bin/foo"))
build_git "foo", "1.0", :path => lib_path("foo") do |s|
- s.executables = %w(foo)
+ s.executables = %w[foo]
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo")}"
G
@@ -81,9 +274,10 @@ RSpec.describe "bundle binstubs <gem>" do
FileUtils.mkdir_p(lib_path("foo/bin"))
FileUtils.touch(lib_path("foo/bin/foo"))
build_lib "foo", "1.0", :path => lib_path("foo") do |s|
- s.executables = %w(foo)
+ s.executables = %w[foo]
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
@@ -95,13 +289,25 @@ RSpec.describe "bundle binstubs <gem>" do
it "sets correct permissions for binstubs" do
with_umask(0o002) do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "binstubs rack"
binary = bundled_app("bin/rackup")
- expect(File.stat(binary).mode.to_s(8)).to eq("100775")
+ expect(File.stat(binary).mode.to_s(8)).to eq(Gem.win_platform? ? "100644" : "100775")
+ end
+ end
+
+ context "when using --shebang" do
+ it "sets the specified shebang for the binstub" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "binstubs rack --shebang jruby"
+ expect(File.readlines(bundled_app("bin/rackup")).first).to eq("#!/usr/bin/env jruby\n")
end
end
end
@@ -109,20 +315,20 @@ RSpec.describe "bundle binstubs <gem>" do
context "when the gem doesn't exist" do
it "displays an error with correct status" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
G
- bundle "binstubs doesnt_exist"
+ bundle "binstubs doesnt_exist", :raise_on_error => false
- expect(exitstatus).to eq(7) if exitstatus
- expect(out).to include("Could not find gem 'doesnt_exist'.")
+ expect(exitstatus).to eq(7)
+ expect(err).to include("Could not find gem 'doesnt_exist'.")
end
end
context "--path" do
it "sets the binstubs dir" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -131,33 +337,51 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("exec/rackup")).to exist
end
- it "setting is saved for bundle install" do
+ it "setting is saved for bundle install", :bundler => "< 3" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rails"
G
- bundle "binstubs rack --path exec"
+ bundle "binstubs rack", :path => "exec"
bundle :install
expect(bundled_app("exec/rails")).to exist
end
end
- context "after installing with --standalone" do
+ context "with --standalone option" do
before do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "install --standalone"
end
- it "includes the standalone path" do
+ it "generates a standalone binstub" do
+ bundle "binstubs rack --standalone"
+ expect(bundled_app("bin/rackup")).to exist
+ end
+
+ it "generates a binstub that does not depend on rubygems or bundler" do
bundle "binstubs rack --standalone"
- standalone_line = File.read(bundled_app("bin/rackup")).each_line.find {|line| line.include? "$:.unshift" }.strip
- expect(standalone_line).to eq %($:.unshift File.expand_path "../../bundle", path.realpath)
+ expect(File.read(bundled_app("bin/rackup"))).to_not include("Gem.bin_path")
+ end
+
+ context "when specified --path option" do
+ it "generates a standalone binstub at the given path" do
+ bundle "binstubs rack --standalone --path foo"
+ expect(bundled_app("foo/rackup")).to exist
+ end
+ end
+
+ context "when specified --all-platforms option" do
+ it "generates standalone binstubs for all platforms" do
+ bundle "binstubs rack --standalone --all-platforms"
+ expect(bundled_app("bin/rackup")).to exist
+ expect(bundled_app("bin/rackup.cmd")).to exist
+ end
end
end
@@ -169,7 +393,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -177,8 +401,8 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("bin/rackup")).to exist
expect(File.read(bundled_app("bin/rackup"))).to eq("OMG")
- expect(out).to include("Skipped rackup")
- expect(out).to include("overwrite skipped stubs, use --force")
+ expect(err).to include("Skipped rackup")
+ expect(err).to include("overwrite skipped stubs, use --force")
end
context "when using --force" do
@@ -189,7 +413,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -204,44 +428,50 @@ RSpec.describe "bundle binstubs <gem>" do
context "when the gem has no bins" do
it "suggests child gems if they have bins" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack-obama"
G
bundle "binstubs rack-obama"
- expect(out).to include("rack-obama has no executables")
- expect(out).to include("rack has: rackup")
+ expect(err).to include("rack-obama has no executables")
+ expect(err).to include("rack has: rackup")
end
it "works if child gems don't have bins" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "actionpack"
G
bundle "binstubs actionpack"
- expect(out).to include("no executables for the gem actionpack")
+ expect(err).to include("no executables for the gem actionpack")
end
it "works if the gem has development dependencies" do
+ build_repo2 do
+ build_gem "with_development_dependency" do |s|
+ s.add_development_dependency "activesupport", "= 2.3.5"
+ end
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "with_development_dependency"
G
bundle "binstubs with_development_dependency"
- expect(out).to include("no executables for the gem with_development_dependency")
+ expect(err).to include("no executables for the gem with_development_dependency")
end
end
context "when BUNDLE_INSTALL is specified" do
it "performs an automatic bundle install" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "config auto_install 1"
+ bundle "config set auto_install 1"
bundle "binstubs rack"
expect(out).to include("Installing rack 1.0.0")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -249,12 +479,12 @@ RSpec.describe "bundle binstubs <gem>" do
it "does nothing when already up to date" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "config auto_install 1"
- bundle "binstubs rack", :env => { "BUNDLE_INSTALL" => 1 }
+ bundle "config set auto_install 1"
+ bundle "binstubs rack", :env => { "BUNDLE_INSTALL" => "1" }
expect(out).not_to include("Installing rack 1.0.0")
end
end
diff --git a/spec/bundler/commands/cache_spec.rb b/spec/bundler/commands/cache_spec.rb
new file mode 100644
index 0000000000..9bb85c6587
--- /dev/null
+++ b/spec/bundler/commands/cache_spec.rb
@@ -0,0 +1,432 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle cache" do
+ it "doesn't update the cache multiple times, even if it already exists" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle :cache
+ expect(out).to include("Updating files in vendor/cache").once
+
+ bundle :cache
+ expect(out).to include("Updating files in vendor/cache").once
+ end
+
+ context "with --gemfile" do
+ it "finds the gemfile" do
+ gemfile bundled_app("NotGemfile"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+
+ bundle "cache --gemfile=NotGemfile"
+
+ ENV["BUNDLE_GEMFILE"] = "NotGemfile"
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+ end
+
+ context "with --all" do
+ context "without a gemspec" do
+ it "caches all dependencies except bundler itself" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ gem 'bundler'
+ D
+
+ bundle "config set cache_all true"
+ bundle :cache
+
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
+ end
+ end
+
+ context "with a gemspec" do
+ context "that has the same name as the gem" do
+ before do
+ File.open(bundled_app("mygem.gemspec"), "w") do |f|
+ f.write <<-G
+ Gem::Specification.new do |s|
+ s.name = "mygem"
+ s.version = "0.1.1"
+ s.summary = ""
+ s.authors = ["gem author"]
+ s.add_development_dependency "nokogiri", "=1.4.2"
+ end
+ G
+ end
+ end
+
+ it "caches all dependencies except bundler and the gemspec specified gem" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ gemspec
+ D
+
+ bundle "config set cache_all true"
+ bundle :cache
+
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
+ expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
+ expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
+ end
+ end
+
+ context "that has a different name as the gem" do
+ before do
+ File.open(bundled_app("mygem_diffname.gemspec"), "w") do |f|
+ f.write <<-G
+ Gem::Specification.new do |s|
+ s.name = "mygem"
+ s.version = "0.1.1"
+ s.summary = ""
+ s.authors = ["gem author"]
+ s.add_development_dependency "nokogiri", "=1.4.2"
+ end
+ G
+ end
+ end
+
+ it "caches all dependencies except bundler and the gemspec specified gem" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ gemspec
+ D
+
+ bundle "config set cache_all true"
+ bundle :cache
+
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
+ expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
+ expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
+ end
+ end
+ end
+
+ context "with multiple gemspecs" do
+ before do
+ File.open(bundled_app("mygem.gemspec"), "w") do |f|
+ f.write <<-G
+ Gem::Specification.new do |s|
+ s.name = "mygem"
+ s.version = "0.1.1"
+ s.summary = ""
+ s.authors = ["gem author"]
+ s.add_development_dependency "nokogiri", "=1.4.2"
+ end
+ G
+ end
+ File.open(bundled_app("mygem_client.gemspec"), "w") do |f|
+ f.write <<-G
+ Gem::Specification.new do |s|
+ s.name = "mygem_test"
+ s.version = "0.1.1"
+ s.summary = ""
+ s.authors = ["gem author"]
+ s.add_development_dependency "weakling", "=0.0.3"
+ end
+ G
+ end
+ end
+
+ it "caches all dependencies except bundler and the gemspec specified gems" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ gemspec :name => 'mygem'
+ gemspec :name => 'mygem_test'
+ D
+
+ bundle "config set cache_all true"
+ bundle :cache
+
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
+ expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
+ expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
+ expect(bundled_app("vendor/cache/mygem_test-0.1.1.gem")).to_not exist
+ expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
+ end
+ end
+ end
+
+ context "with --path", :bundler => "< 3" do
+ it "sets root directory for gems" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ D
+
+ bundle "cache --path #{bundled_app("test")}"
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ expect(bundled_app("test/vendor/cache/")).to exist
+ end
+ end
+
+ context "with --no-install" do
+ it "puts the gems in vendor/cache but does not install them" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ D
+
+ bundle "cache --no-install"
+
+ expect(the_bundle).not_to include_gems "rack 1.0.0"
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
+
+ it "does not prevent installing gems with bundle install" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ D
+
+ bundle "cache --no-install"
+ bundle "install"
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "does not prevent installing gems with bundle update" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ D
+
+ bundle "cache --no-install"
+ bundle "update --all"
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+ end
+
+ context "with --all-platforms" do
+ before do
+ skip "doesn't put gems where it should" if Gem.win_platform?
+ end
+
+ it "puts the gems in vendor/cache even for other rubies" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack', :platforms => :ruby_19
+ D
+
+ bundle "cache --all-platforms"
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
+
+ it "does not attempt to install gems in without groups" do
+ build_repo4 do
+ build_gem "uninstallable", "2.0" do |s|
+ s.add_development_dependency "rake"
+ s.extensions << "Rakefile"
+ s.write "Rakefile", "task(:default) { raise 'CANNOT INSTALL' }"
+ end
+ end
+
+ bundle "config set --local without wo"
+ install_gemfile <<-G
+ source "file:#{gem_repo1}"
+ gem "rack"
+ group :wo do
+ gem "weakling"
+ gem "uninstallable", :source => "file:#{gem_repo4}"
+ end
+ G
+
+ bundle :cache, "all-platforms" => true
+ expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
+ expect(bundled_app("vendor/cache/uninstallable-2.0.gem")).to exist
+ expect(the_bundle).to include_gem "rack 1.0"
+ expect(the_bundle).not_to include_gems "weakling", "uninstallable"
+
+ bundle "config set --local without wo"
+ bundle :install
+ expect(the_bundle).to include_gem "rack 1.0"
+ expect(the_bundle).not_to include_gems "weakling", "uninstallable"
+ end
+
+ it "does not fail to cache gems in excluded groups when there's a lockfile but gems not previously installed" do
+ bundle "config set --local without wo"
+ gemfile <<-G
+ source "https://my.gem.repo.1"
+ gem "rack"
+ group :wo do
+ gem "weakling"
+ end
+ G
+
+ bundle :lock, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
+ bundle :cache, "all-platforms" => true, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
+ expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
+ end
+ end
+
+ context "with frozen configured" do
+ before do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ bundle "install"
+ end
+
+ subject do
+ bundle "config set --local frozen true"
+ bundle :cache, :raise_on_error => false
+ end
+
+ it "tries to install with frozen" do
+ bundle "config set deployment true"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "rack-obama"
+ G
+ subject
+ expect(exitstatus).to eq(16)
+ expect(err).to include("deployment mode")
+ expect(err).to include("You have added to the Gemfile")
+ expect(err).to include("* rack-obama")
+ bundle "env"
+ expect(out).to include("frozen").or include("deployment")
+ end
+ end
+
+ context "with gems with extensions" do
+ before do
+ build_repo2 do
+ build_gem "racc", "2.0" do |s|
+ s.add_dependency "rake"
+ s.extensions << "Rakefile"
+ s.write "Rakefile", "task(:default) { puts 'INSTALLING rack' }"
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "racc"
+ G
+ end
+
+ it "installs them properly from cache to a different path" do
+ bundle "cache"
+ bundle "config set --local path vendor/bundle"
+ bundle "install --local"
+ end
+ end
+end
+
+RSpec.describe "bundle install with gem sources" do
+ describe "when cached and locked" do
+ it "does not hit the remote at all" do
+ build_repo2
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ G
+
+ bundle :cache
+ simulate_new_machine
+ FileUtils.rm_rf gem_repo2
+
+ bundle "install --local"
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "does not hit the remote at all in frozen mode" do
+ build_repo2
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ G
+
+ bundle :cache
+ simulate_new_machine
+ FileUtils.rm_rf gem_repo2
+
+ bundle "config set --local deployment true"
+ bundle "config set --local path vendor/bundle"
+ bundle :install
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "does not hit the remote at all when cache_all_platforms configured" do
+ build_repo2
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ G
+
+ bundle :cache
+ simulate_new_machine
+ FileUtils.rm_rf gem_repo2
+
+ bundle "config set --local cache_all_platforms true"
+ bundle "config set --local path vendor/bundle"
+ bundle "install --local"
+ expect(out).not_to include("Fetching gem metadata")
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "does not reinstall already-installed gems" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ bundle :cache
+
+ build_gem "rack", "1.0.0", :path => bundled_app("vendor/cache") do |s|
+ s.write "lib/rack.rb", "raise 'omg'"
+ end
+
+ bundle :install
+ expect(err).to be_empty
+ expect(the_bundle).to include_gems "rack 1.0"
+ end
+
+ it "ignores cached gems for the wrong platform" do
+ simulate_platform "java" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "platform_specific"
+ G
+ bundle :cache
+ end
+
+ simulate_new_machine
+
+ simulate_platform "ruby" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "platform_specific"
+ G
+ run "require 'platform_specific' ; puts PLATFORM_SPECIFIC"
+ expect(out).to eq("1.0.0 RUBY")
+ end
+ end
+
+ it "does not update the cache if --no-cache is passed" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ bundled_app("vendor/cache").mkpath
+ expect(bundled_app("vendor/cache").children).to be_empty
+
+ bundle "install --no-cache"
+ expect(bundled_app("vendor/cache").children).to be_empty
+ end
+ end
+end
diff --git a/spec/bundler/commands/check_spec.rb b/spec/bundler/commands/check_spec.rb
index 532be07c3f..1fa35136eb 100644
--- a/spec/bundler/commands/check_spec.rb
+++ b/spec/bundler/commands/check_spec.rb
@@ -1,101 +1,100 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle check" do
it "returns success when the Gemfile is satisfied" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
bundle :check
- expect(exitstatus).to eq(0) if exitstatus
expect(out).to include("The Gemfile's dependencies are satisfied")
end
it "works with the --gemfile flag when not in the directory" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
- Dir.chdir tmp
- bundle "check --gemfile bundled_app/Gemfile"
+ bundle "check --gemfile bundled_app/Gemfile", :dir => tmp
expect(out).to include("The Gemfile's dependencies are satisfied")
end
it "creates a Gemfile.lock by default if one does not exist" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
- FileUtils.rm("Gemfile.lock")
+ FileUtils.rm(bundled_app_lock)
bundle "check"
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
it "does not create a Gemfile.lock if --dry-run was passed" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
- FileUtils.rm("Gemfile.lock")
+ FileUtils.rm(bundled_app_lock)
bundle "check --dry-run"
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
end
it "prints a generic error if the missing gems are unresolvable" do
system_gems ["rails-2.3.2"]
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
- bundle :check
- expect(out).to include("Bundler can't satisfy your Gemfile's dependencies.")
+ bundle :check, :raise_on_error => false
+ expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
it "prints a generic error if a Gemfile.lock does not exist and a toplevel dependency does not exist" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
- bundle :check
- expect(exitstatus).to be > 0 if exitstatus
- expect(out).to include("Bundler can't satisfy your Gemfile's dependencies.")
+ bundle :check, :raise_on_error => false
+ expect(exitstatus).to be > 0
+ expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
it "prints a generic message if you changed your lockfile" do
+ build_repo2 do
+ build_gem "rails_pinned_to_old_activesupport" do |s|
+ s.add_dependency "activesupport", "= 1.2.3"
+ end
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rails'
G
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem 'rails_fail'
- G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails"
- gem "rails_fail"
+ gem "rails_pinned_to_old_activesupport"
G
- bundle :check
- expect(out).to include("Bundler can't satisfy your Gemfile's dependencies.")
+ bundle :check, :raise_on_error => false
+ expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
- it "remembers --without option from install" do
+ it "remembers --without option from install", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
group :foo do
gem "rack"
end
@@ -103,42 +102,71 @@ RSpec.describe "bundle check" do
bundle "install --without foo"
bundle "check"
- expect(exitstatus).to eq(0) if exitstatus
+ expect(out).to include("The Gemfile's dependencies are satisfied")
+ end
+
+ it "uses the without setting" do
+ bundle "config set without foo"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ group :foo do
+ gem "rack"
+ end
+ G
+
+ bundle "check"
expect(out).to include("The Gemfile's dependencies are satisfied")
end
it "ensures that gems are actually installed and not just cached" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :group => :foo
G
- bundle "install --without foo"
+ bundle "config set --local without foo"
+ bundle :install
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "check"
- expect(out).to include("* rack (1.0.0)")
- expect(exitstatus).to eq(1) if exitstatus
+ bundle "check", :raise_on_error => false
+ expect(err).to include("* rack (1.0.0)")
+ expect(exitstatus).to eq(1)
end
- it "ignores missing gems restricted to other platforms" do
- system_gems "rack-1.0.0"
+ it "ensures that gems are actually installed and not just cached in applications' cache" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ bundle "config set --local path vendor/bundle"
+ bundle :cache
+
+ gem_command "uninstall rack", :env => { "GEM_HOME" => vendored_gems.to_s }
+
+ bundle "check", :raise_on_error => false
+ expect(err).to include("* rack (1.0.0)")
+ expect(exitstatus).to eq(1)
+ end
+
+ it "ignores missing gems restricted to other platforms" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
platforms :#{not_local_tag} do
gem "activesupport"
end
G
+ system_gems "rack-1.0.0", :path => default_bundle_path
+
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
activesupport (2.3.5)
rack (1.0.0)
@@ -157,19 +185,19 @@ RSpec.describe "bundle check" do
end
it "works with env conditionals" do
- system_gems "rack-1.0.0"
-
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
env :NOT_GOING_TO_BE_SET do
gem "activesupport"
end
G
+ system_gems "rack-1.0.0", :path => default_bundle_path
+
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
activesupport (2.3.5)
rack (1.0.0)
@@ -188,81 +216,68 @@ RSpec.describe "bundle check" do
end
it "outputs an error when the default Gemfile is not found" do
- bundle :check
- expect(exitstatus).to eq(10) if exitstatus
- expect(out).to include("Could not locate Gemfile")
+ bundle :check, :raise_on_error => false
+ expect(exitstatus).to eq(10)
+ expect(err).to include("Could not locate Gemfile")
end
it "does not output fatal error message" do
- bundle :check
- expect(exitstatus).to eq(10) if exitstatus
- expect(out).not_to include("Unfortunately, a fatal error has occurred. ")
- end
-
- it "should not crash when called multiple times on a new machine" do
- gemfile <<-G
- gem 'rails', '3.0.0.beta3'
- gem 'paperclip', :git => 'git://github.com/thoughtbot/paperclip.git'
- G
-
- simulate_new_machine
- bundle "check"
- last_out = out
- 3.times do
- bundle :check
- expect(out).to eq(last_out)
- expect(err).to lack_errors
- end
+ bundle :check, :raise_on_error => false
+ expect(exitstatus).to eq(10)
+ expect(err).not_to include("Unfortunately, a fatal error has occurred. ")
end
it "fails when there's no lock file and frozen is set" do
- gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
+ bundle "config set --local deployment true"
bundle "install"
- bundle "install --deployment"
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
- bundle :check
- expect(exitstatus).not_to eq(0) if exitstatus
+ bundle :check, :raise_on_error => false
+ expect(last_command).to be_failure
end
- context "--path" do
- before do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rails"
- G
- bundle "install --path vendor/bundle"
+ context "--path", :bundler => "< 3" do
+ context "after installing gems in the proper directory" do
+ before do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ G
+ bundle "install --path vendor/bundle"
- FileUtils.rm_rf(bundled_app(".bundle"))
- end
+ FileUtils.rm_rf(bundled_app(".bundle"))
+ end
- it "returns success" do
- bundle "check --path vendor/bundle"
- expect(exitstatus).to eq(0) if exitstatus
- expect(out).to include("The Gemfile's dependencies are satisfied")
- end
+ it "returns success" do
+ bundle "check --path vendor/bundle"
+ expect(out).to include("The Gemfile's dependencies are satisfied")
+ end
- it "should write to .bundle/config" do
- bundle "check --path vendor/bundle"
- bundle "check"
- expect(exitstatus).to eq(0) if exitstatus
+ it "should write to .bundle/config" do
+ bundle "check --path vendor/bundle"
+ bundle "check"
+ end
end
- end
- context "--path vendor/bundle after installing gems in the default directory" do
- it "returns false" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rails"
- G
+ context "after installing gems on a different directory" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ G
+
+ bundle "check --path vendor/bundle", :raise_on_error => false
+ end
- bundle "check --path vendor/bundle"
- expect(exitstatus).to eq(1) if exitstatus
- expect(out).to match(/The following gems are missing/)
+ it "returns false" do
+ expect(exitstatus).to eq(1)
+ expect(err).to match(/The following gems are missing/)
+ end
end
end
@@ -270,7 +285,7 @@ RSpec.describe "bundle check" do
before :each do
system_gems "rack-1.0.0"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0"
G
end
@@ -278,43 +293,171 @@ RSpec.describe "bundle check" do
it "returns success when the Gemfile is satisfied" do
bundle :install
bundle :check
- expect(exitstatus).to eq(0) if exitstatus
expect(out).to include("The Gemfile's dependencies are satisfied")
end
it "shows what is missing with the current Gemfile if it is not satisfied" do
simulate_new_machine
+ bundle :check, :raise_on_error => false
+ expect(err).to match(/The following gems are missing/)
+ expect(err).to include("* rack (1.0")
+ end
+ end
+
+ describe "when locked with multiple dependents with different requirements" do
+ before :each do
+ build_repo4 do
+ build_gem "depends_on_rack" do |s|
+ s.add_dependency "rack", ">= 1.0"
+ end
+ build_gem "also_depends_on_rack" do |s|
+ s.add_dependency "rack", "~> 1.0"
+ end
+ build_gem "rack"
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "depends_on_rack"
+ gem "also_depends_on_rack"
+ G
+
+ bundle "lock"
+ end
+
+ it "shows what is missing with the current Gemfile without duplications" do
+ bundle :check, :raise_on_error => false
+ expect(err).to match(/The following gems are missing/)
+ expect(err).to include("* rack (1.0").once
+ end
+ end
+
+ describe "when locked under multiple platforms" do
+ before :each do
+ build_repo4 do
+ build_gem "rack"
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ ruby
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "shows what is missing with the current Gemfile without duplications" do
+ bundle :check, :raise_on_error => false
+ expect(err).to match(/The following gems are missing/)
+ expect(err).to include("* rack (1.0").once
+ end
+ end
+
+ describe "when using only scoped rubygems sources" do
+ before do
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo2)}"
+ source "#{file_uri_for(gem_repo1)}" do
+ gem "rack"
+ end
+ G
+ end
+
+ it "returns success when the Gemfile is satisfied" do
+ system_gems "rack-1.0.0", :path => default_bundle_path
bundle :check
- expect(out).to match(/The following gems are missing/)
- expect(out).to include("* rack (1.0")
+ expect(out).to include("The Gemfile's dependencies are satisfied")
+ end
+ end
+
+ describe "when using only scoped rubygems sources with indirect dependencies" do
+ before do
+ build_repo4 do
+ build_gem "depends_on_rack" do |s|
+ s.add_dependency "rack"
+ end
+
+ build_gem "rack"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo4)}" do
+ gem "depends_on_rack"
+ end
+ G
+ end
+
+ it "returns success when the Gemfile is satisfied and generates a correct lockfile" do
+ system_gems "depends_on_rack-1.0", "rack-1.0", :gem_repo => gem_repo4, :path => default_bundle_path
+ bundle :check
+ expect(out).to include("The Gemfile's dependencies are satisfied")
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ depends_on_rack (1.0)
+ rack
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ depends_on_rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
end
describe "BUNDLED WITH" do
def lock_with(bundler_version = nil)
- lock = <<-L
+ lock = <<~L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
L
if bundler_version
- lock += "\n BUNDLED WITH\n #{bundler_version}\n"
+ lock += "\nBUNDLED WITH\n #{bundler_version}\n"
end
lock
end
before do
+ bundle "config set --local path vendor/bundle"
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
@@ -323,7 +466,7 @@ RSpec.describe "bundle check" do
it "does not change the lock" do
lockfile lock_with(nil)
bundle :check
- lockfile_should_be lock_with(nil)
+ expect(lockfile).to eq lock_with(nil)
end
end
@@ -331,17 +474,17 @@ RSpec.describe "bundle check" do
it "does not change the lock but warns" do
lockfile lock_with(Bundler::VERSION.succ)
bundle :check
- expect(out).to include("the running version of Bundler (#{Bundler::VERSION}) is older than the version that created the lockfile (#{Bundler::VERSION.succ})")
- expect(err).to lack_errors
- lockfile_should_be lock_with(Bundler::VERSION.succ)
+ expect(err).to include("the running version of Bundler (#{Bundler::VERSION}) is older than the version that created the lockfile (#{Bundler::VERSION.succ})")
+ expect(lockfile).to eq lock_with(Bundler::VERSION.succ)
end
end
context "is older" do
it "does not change the lock" do
- lockfile lock_with("1.10.1")
+ system_gems "bundler-1.18.0"
+ lockfile lock_with("1.18.0")
bundle :check
- lockfile_should_be lock_with("1.10.1")
+ expect(lockfile).to eq lock_with("1.18.0")
end
end
end
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
index 02d96a0ff7..9cce998416 100644
--- a/spec/bundler/commands/clean_spec.rb
+++ b/spec/bundler/commands/clean_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle clean" do
def should_have_gems(*gems)
@@ -20,16 +19,18 @@ RSpec.describe "bundle clean" do
it "removes unused gems that are different" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "foo"
G
- bundle "install --path vendor/bundle --no-clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
G
@@ -47,16 +48,18 @@ RSpec.describe "bundle clean" do
it "removes old version of gem if unused" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
gem "foo"
G
- bundle "install --path vendor/bundle --no-clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
gem "foo"
@@ -75,21 +78,23 @@ RSpec.describe "bundle clean" do
it "removes new version of gem if unused" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
gem "foo"
G
- bundle "install --path vendor/bundle --no-clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
gem "foo"
G
- bundle "install"
+ bundle "update rack"
bundle :clean
@@ -103,7 +108,7 @@ RSpec.describe "bundle clean" do
it "removes gems in bundle without groups" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
@@ -112,8 +117,10 @@ RSpec.describe "bundle clean" do
end
G
- bundle "install --path vendor/bundle"
- bundle "install --without test_group"
+ bundle "config set path vendor/bundle"
+ bundle "install"
+ bundle "config set without test_group"
+ bundle "install"
bundle :clean
expect(out).to include("Removing rack (1.0.0)")
@@ -130,7 +137,7 @@ RSpec.describe "bundle clean" do
git_path = lib_path("foo-1.0")
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
git "#{git_path}", :ref => "#{revision}" do
@@ -138,12 +145,14 @@ RSpec.describe "bundle clean" do
end
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
bundle :clean
- digest = Digest::SHA1.hexdigest(git_path.to_s)
- expect(vendored_gems("cache/bundler/git/foo-1.0-#{digest}")).to exist
+ digest = Digest(:SHA1).hexdigest(git_path.to_s)
+ cache_path = Bundler::VERSION.start_with?("2.") ? vendored_gems("cache/bundler/git/foo-1.0-#{digest}") : home(".bundle/cache/git/foo-1.0-#{digest}")
+ expect(cache_path).to exist
end
it "removes unused git gems" do
@@ -152,7 +161,7 @@ RSpec.describe "bundle clean" do
revision = revision_for(git_path)
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
git "#{git_path}", :ref => "#{revision}" do
@@ -160,10 +169,11 @@ RSpec.describe "bundle clean" do
end
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
G
@@ -175,7 +185,7 @@ RSpec.describe "bundle clean" do
expect(vendored_gems("gems/rack-1.0.0")).to exist
expect(vendored_gems("bundler/gems/foo-#{revision[0..11]}")).not_to exist
- digest = Digest::SHA1.hexdigest(git_path.to_s)
+ digest = Digest(:SHA1).hexdigest(git_path.to_s)
expect(vendored_gems("cache/bundler/git/foo-#{digest}")).not_to exist
expect(vendored_gems("specifications/rack-1.0.0.gemspec")).to exist
@@ -183,12 +193,39 @@ RSpec.describe "bundle clean" do
expect(vendored_gems("bin/rackup")).to exist
end
+ it "keeps used git gems even if installed to a symlinked location" do
+ build_git "foo", :path => lib_path("foo")
+ git_path = lib_path("foo")
+ revision = revision_for(git_path)
+
+ gemfile <<-G
+ source "file://#{gem_repo1}"
+
+ gem "rack", "1.0.0"
+ git "#{git_path}", :ref => "#{revision}" do
+ gem "foo"
+ end
+ G
+
+ FileUtils.mkdir_p(bundled_app("real-path"))
+ FileUtils.ln_sf(bundled_app("real-path"), bundled_app("symlink-path"))
+
+ bundle "config set path #{bundled_app("symlink-path")}"
+ bundle "install"
+
+ bundle :clean
+
+ expect(out).not_to include("Removing foo (#{revision[0..11]})")
+
+ expect(bundled_app("symlink-path/#{Bundler.ruby_scope}/bundler/gems/foo-#{revision[0..11]}")).to exist
+ end
+
it "removes old git gems" do
build_git "foo-bar", :path => lib_path("foo-bar")
revision = revision_for(lib_path("foo-bar"))
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
git "#{lib_path("foo-bar")}" do
@@ -196,12 +233,13 @@ RSpec.describe "bundle clean" do
end
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
- update_git "foo", :path => lib_path("foo-bar")
+ update_git "foo-bar", :path => lib_path("foo-bar")
revision2 = revision_for(lib_path("foo-bar"))
- bundle "update"
+ bundle "update", :all => true
bundle :clean
expect(out).to include("Removing foo-bar (#{revision[0..11]})")
@@ -223,10 +261,12 @@ RSpec.describe "bundle clean" do
revision = revision_for(lib_path("rails"))
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport", :git => "#{lib_path("rails")}", :ref => '#{revision}'
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
bundle :clean
expect(out).to include("")
@@ -239,7 +279,7 @@ RSpec.describe "bundle clean" do
revision = revision_for(git_path)
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
group :test do
@@ -248,19 +288,21 @@ RSpec.describe "bundle clean" do
end
end
G
- bundle "install --path vendor/bundle --without test"
+ bundle "config set path vendor/bundle"
+ bundle "config set without test"
+ bundle "install"
bundle :clean
expect(out).to include("")
expect(vendored_gems("bundler/gems/foo-#{revision[0..11]}")).to exist
- digest = Digest::SHA1.hexdigest(git_path.to_s)
+ digest = Digest(:SHA1).hexdigest(git_path.to_s)
expect(vendored_gems("cache/bundler/git/foo-#{digest}")).to_not exist
end
it "does not blow up when using without groups" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -269,38 +311,41 @@ RSpec.describe "bundle clean" do
end
G
- bundle "install --path vendor/bundle --without development"
+ bundle "config set path vendor/bundle"
+ bundle "config set without development"
+ bundle "install"
bundle :clean
- expect(exitstatus).to eq(0) if exitstatus
end
it "displays an error when used without --path" do
+ bundle "config set path.system true"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
G
- bundle :clean
+ bundle :clean, :raise_on_error => false
- expect(exitstatus).to eq(1) if exitstatus
- expect(out).to include("--force")
+ expect(exitstatus).to eq(15)
+ expect(err).to include("--force")
end
# handling bundle clean upgrade path from the pre's
it "removes .gem/.gemspec file even if there's no corresponding gem dir" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "foo"
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
@@ -319,37 +364,38 @@ RSpec.describe "bundle clean" do
end
it "does not call clean automatically when using system gems" do
- gemfile <<-G
- source "file://#{gem_repo1}"
+ bundle "config set path.system true"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "rack"
G
- bundle :install
- gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle :install
- sys_exec "gem list"
- expect(out).to include("rack (1.0.0)")
- expect(out).to include("thin (1.0)")
+ gem_command :list
+ expect(out).to include("rack (1.0.0)").and include("thin (1.0)")
end
- it "--clean should override the bundle setting on install" do
+ it "--clean should override the bundle setting on install", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "rack"
G
- bundle "install --path vendor/bundle --clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install --clean true"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -359,37 +405,64 @@ RSpec.describe "bundle clean" do
should_not_have_gems "thin-1.0"
end
- it "--clean should override the bundle setting on update" do
+ it "--clean should override the bundle setting on update", :bundler => "< 3" do
build_repo2
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "foo"
G
- bundle "install --path vendor/bundle --clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install --clean true"
update_repo2 do
build_gem "foo", "1.0.1"
end
- bundle "update"
+ bundle "update", :all => true
should_have_gems "foo-1.0.1"
should_not_have_gems "foo-1.0"
end
+ it "automatically cleans when path has not been set", :bundler => "3" do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "foo"
+ G
+
+ update_repo2 do
+ build_gem "foo", "1.0.1"
+ end
+
+ bundle "update", :all => true
+
+ files = Pathname.glob(bundled_app(".bundle", Bundler.ruby_scope, "*", "*"))
+ files.map! {|f| f.to_s.sub(bundled_app(".bundle", Bundler.ruby_scope).to_s, "") }
+ expect(files.sort).to eq %w[
+ /cache/foo-1.0.1.gem
+ /gems/foo-1.0.1
+ /specifications/foo-1.0.1.gemspec
+ ]
+ end
+
it "does not clean automatically on --path" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "rack"
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -402,25 +475,28 @@ RSpec.describe "bundle clean" do
build_repo2
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "foo"
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
update_repo2 do
build_gem "foo", "1.0.1"
end
- bundle :update
+ bundle :update, :all => true
should_have_gems "foo-1.0", "foo-1.0.1"
end
it "does not clean on bundle update when using --system" do
+ bundle "config set path.system true"
+
build_repo2
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "foo"
G
@@ -429,15 +505,17 @@ RSpec.describe "bundle clean" do
update_repo2 do
build_gem "foo", "1.0.1"
end
- bundle :update
+ bundle :update, :all => true
- sys_exec "gem list"
+ gem_command :list
expect(out).to include("foo (1.0.1, 1.0)")
end
it "cleans system gems when --force is used" do
+ bundle "config set path.system true"
+
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
gem "rack"
@@ -445,7 +523,7 @@ RSpec.describe "bundle clean" do
bundle :install
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -453,18 +531,20 @@ RSpec.describe "bundle clean" do
bundle "clean --force"
expect(out).to include("Removing foo (1.0)")
- sys_exec "gem list"
+ gem_command :list
expect(out).not_to include("foo (1.0)")
expect(out).to include("rack (1.0.0)")
end
- describe "when missing permissions" do
+ describe "when missing permissions", :permissions do
+ before { ENV["BUNDLE_PATH__SYSTEM"] = "true" }
+ let(:system_cache_path) { system_gem_path("cache") }
after do
- FileUtils.chmod(0o755, default_bundle_path("cache"))
+ FileUtils.chmod(0o755, system_cache_path)
end
it "returns a helpful error message" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
gem "rack"
@@ -472,21 +552,20 @@ RSpec.describe "bundle clean" do
bundle :install
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle :install
- system_cache_path = default_bundle_path("cache")
FileUtils.chmod(0o500, system_cache_path)
- bundle :clean, :force => true
+ bundle :clean, :force => true, :raise_on_error => false
- expect(out).to include(system_gem_path.to_s)
- expect(out).to include("grant write permissions")
+ expect(err).to include(system_gem_path.to_s)
+ expect(err).to include("grant write permissions")
- sys_exec "gem list"
+ gem_command :list
expect(out).to include("foo (1.0)")
expect(out).to include("rack (1.0.0)")
end
@@ -497,23 +576,23 @@ RSpec.describe "bundle clean" do
revision = revision_for(lib_path("foo-1.0"))
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
# mimic 7 length git revisions in Gemfile.lock
- gemfile_lock = File.read(bundled_app("Gemfile.lock")).split("\n")
+ gemfile_lock = File.read(bundled_app_lock).split("\n")
gemfile_lock.each_with_index do |line, index|
gemfile_lock[index] = line[0..(11 + 7)] if line.include?(" revision:")
end
- File.open(bundled_app("Gemfile.lock"), "w") do |file|
- file.print gemfile_lock.join("\n")
- end
+ lockfile(bundled_app_lock, gemfile_lock.join("\n"))
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
bundle :clean
@@ -523,8 +602,9 @@ RSpec.describe "bundle clean" do
end
it "when using --force on system gems, it doesn't remove binaries" do
- build_repo2
- update_repo2 do
+ bundle "config set path.system true"
+
+ build_repo2 do
build_gem "bindir" do |s|
s.bindir = "exe"
s.executables = "foo"
@@ -532,7 +612,7 @@ RSpec.describe "bundle clean" do
end
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "bindir"
G
@@ -542,11 +622,34 @@ RSpec.describe "bundle clean" do
sys_exec "foo"
- expect(exitstatus).to eq(0) if exitstatus
expect(out).to eq("1.0")
end
- it "doesn't blow up on path gems without a .gempsec" do
+ it "when using --force, it doesn't remove default gem binaries" do
+ skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
+
+ skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
+
+ default_irb_version = ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", :raise_on_error => false
+ skip "irb isn't a default gem" if default_irb_version.empty?
+
+ # simulate executable for default gem
+ build_gem "irb", default_irb_version, :to_system => true, :default => true do |s|
+ s.executables = "irb"
+ end
+
+ realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ G
+
+ bundle "clean --force", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
+
+ expect(out).not_to include("Removing irb")
+ end
+
+ it "doesn't blow up on path gems without a .gemspec" do
relative_path = "vendor/private_gems/bar-1.0"
absolute_path = bundled_app(relative_path)
FileUtils.mkdir_p("#{absolute_path}/lib/bar")
@@ -555,30 +658,31 @@ RSpec.describe "bundle clean" do
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
gem "bar", "1.0", :path => "#{relative_path}"
G
- bundle "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
bundle :clean
-
- expect(exitstatus).to eq(0) if exitstatus
end
it "doesn't remove gems in dry-run mode with path set" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "foo"
G
- bundle "install --path vendor/bundle --no-clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
G
@@ -597,24 +701,24 @@ RSpec.describe "bundle clean" do
it "doesn't remove gems in dry-run mode with no path set" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "foo"
G
- bundle "install --path vendor/bundle --no-clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
G
bundle :install
- bundle "configuration --delete path"
-
bundle "clean --dry-run"
expect(out).not_to include("Removing foo (1.0)")
@@ -627,17 +731,19 @@ RSpec.describe "bundle clean" do
it "doesn't store dry run as a config setting" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "foo"
G
- bundle "install --path vendor/bundle --no-clean"
- bundle "config dry_run false"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install"
+ bundle "config set dry_run false"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
G
@@ -657,47 +763,154 @@ RSpec.describe "bundle clean" do
it "performs an automatic bundle install" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "foo"
G
- bundle "install --path vendor/bundle --no-clean"
+ bundle "config set path vendor/bundle"
+ bundle "config set clean false"
+ bundle "install"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "thin"
gem "weakling"
G
- bundle "config auto_install 1"
+ bundle "config set auto_install 1"
bundle :clean
expect(out).to include("Installing weakling 0.0.3")
should_have_gems "thin-1.0", "rack-1.0.0", "weakling-0.0.3"
should_not_have_gems "foo-1.0"
end
- it "doesn't remove extensions artifacts from bundled git gems after clean", :ruby_repo, :rubygems => "2.2" do
+ it "doesn't remove extensions artifacts from bundled git gems after clean", :ruby_repo do
build_git "very_simple_git_binary", &:add_c_extension
revision = revision_for(lib_path("very_simple_git_binary-1.0"))
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}"
G
- bundle! "install --path vendor/bundle"
+ bundle "config set path vendor/bundle"
+ bundle "install"
expect(vendored_gems("bundler/gems/extensions")).to exist
expect(vendored_gems("bundler/gems/very_simple_git_binary-1.0-#{revision[0..11]}")).to exist
- bundle! :clean
- expect(out).to eq("")
+ bundle :clean
+ expect(out).to be_empty
expect(vendored_gems("bundler/gems/extensions")).to exist
expect(vendored_gems("bundler/gems/very_simple_git_binary-1.0-#{revision[0..11]}")).to exist
end
+
+ it "removes extension directories", :ruby_repo do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "thin"
+ gem "very_simple_binary"
+ gem "simple_binary"
+ G
+
+ bundle "config set path vendor/bundle"
+ bundle "install"
+
+ very_simple_binary_extensions_dir =
+ Pathname.glob("#{vendored_gems}/extensions/*/*/very_simple_binary-1.0").first
+
+ simple_binary_extensions_dir =
+ Pathname.glob("#{vendored_gems}/extensions/*/*/simple_binary-1.0").first
+
+ expect(very_simple_binary_extensions_dir).to exist
+ expect(simple_binary_extensions_dir).to exist
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "thin"
+ gem "simple_binary"
+ G
+
+ bundle "install"
+ bundle :clean
+ expect(out).to eq("Removing very_simple_binary (1.0)")
+
+ expect(very_simple_binary_extensions_dir).not_to exist
+ expect(simple_binary_extensions_dir).to exist
+ end
+
+ it "removes git extension directories", :ruby_repo do
+ build_git "very_simple_git_binary", &:add_c_extension
+
+ revision = revision_for(lib_path("very_simple_git_binary-1.0"))
+ short_revision = revision[0..11]
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "thin"
+ gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}"
+ G
+
+ bundle "config set path vendor/bundle"
+ bundle "install"
+
+ very_simple_binary_extensions_dir =
+ Pathname.glob("#{vendored_gems}/bundler/gems/extensions/*/*/very_simple_git_binary-1.0-#{short_revision}").first
+
+ expect(very_simple_binary_extensions_dir).to exist
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}"
+ G
+
+ bundle "install"
+ bundle :clean
+ expect(out).to include("Removing thin (1.0)")
+ expect(very_simple_binary_extensions_dir).to exist
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
+ bundle "install"
+ bundle :clean
+ expect(out).to eq("Removing very_simple_git_binary-1.0 (#{short_revision})")
+
+ expect(very_simple_binary_extensions_dir).not_to exist
+ end
+
+ it "keeps git extension directories when excluded by group" do
+ build_git "very_simple_git_binary", &:add_c_extension
+
+ revision = revision_for(lib_path("very_simple_git_binary-1.0"))
+ short_revision = revision[0..11]
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :development do
+ gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}"
+ end
+ G
+
+ bundle :lock
+ bundle "config set without development"
+ bundle "config set path vendor/bundle"
+ bundle "install"
+ bundle :clean
+
+ very_simple_binary_extensions_dir =
+ Pathname.glob("#{vendored_gems}/bundler/gems/extensions/*/*/very_simple_git_binary-1.0-#{short_revision}").first
+
+ expect(very_simple_binary_extensions_dir).to be_nil
+ end
end
diff --git a/spec/bundler/commands/config_spec.rb b/spec/bundler/commands/config_spec.rb
index a3ca696ec1..2d0a7dc989 100644
--- a/spec/bundler/commands/config_spec.rb
+++ b/spec/bundler/commands/config_spec.rb
@@ -1,19 +1,11 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe ".bundle/config" do
- before :each do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack", "1.0.0"
- G
- end
-
describe "config" do
- before { bundle "config foo bar" }
+ before { bundle "config set foo bar" }
it "prints a detailed report of local and user configuration" do
- bundle "config"
+ bundle "config list"
expect(out).to include("Settings are listed in order of priority. The top value will be used")
expect(out).to include("foo\nSet for the current user")
@@ -22,31 +14,39 @@ RSpec.describe ".bundle/config" do
context "given --parseable flag" do
it "prints a minimal report of local and user configuration" do
- bundle "config --parseable"
+ bundle "config list --parseable"
expect(out).to include("foo=bar")
end
context "with global config" do
it "prints config assigned to local scope" do
- bundle "config --local foo bar2"
- bundle "config --parseable"
+ bundle "config set --local foo bar2"
+ bundle "config list --parseable"
expect(out).to include("foo=bar2")
end
end
context "with env overwrite" do
it "prints config with env" do
- bundle "config --parseable", :env => { "BUNDLE_FOO" => "bar3" }
+ bundle "config list --parseable", :env => { "BUNDLE_FOO" => "bar3" }
expect(out).to include("foo=bar3")
end
end
end
end
- describe "BUNDLE_APP_CONFIG" do
+ describe "location with a gemfile" do
+ before :each do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ G
+ end
+
it "can be moved with an environment variable" do
ENV["BUNDLE_APP_CONFIG"] = tmp("foo/bar").to_s
- bundle "install --path vendor/bundle"
+ bundle "config set --local path vendor/bundle"
+ bundle "install"
expect(bundled_app(".bundle")).not_to exist
expect(tmp("foo/bar/config")).to exist
@@ -55,36 +55,75 @@ RSpec.describe ".bundle/config" do
it "can provide a relative path with the environment variable" do
FileUtils.mkdir_p bundled_app("omg")
- Dir.chdir bundled_app("omg")
ENV["BUNDLE_APP_CONFIG"] = "../foo"
- bundle "install --path vendor/bundle"
+ bundle "config set --local path vendor/bundle"
+ bundle "install", :dir => bundled_app("omg")
expect(bundled_app(".bundle")).not_to exist
expect(bundled_app("../foo/config")).to exist
- expect(the_bundle).to include_gems "rack 1.0.0"
+ expect(the_bundle).to include_gems "rack 1.0.0", :dir => bundled_app("omg")
+ end
+ end
+
+ describe "location without a gemfile" do
+ it "works with an absolute path" do
+ ENV["BUNDLE_APP_CONFIG"] = tmp("foo/bar").to_s
+ bundle "config set --local path vendor/bundle"
+
+ expect(bundled_app(".bundle")).not_to exist
+ expect(tmp("foo/bar/config")).to exist
+ end
+ end
+
+ describe "config location" do
+ let(:bundle_user_config) { File.join(Dir.home, ".config/bundler") }
+
+ before do
+ Dir.mkdir File.dirname(bundle_user_config)
+ end
+
+ it "can be configured through BUNDLE_USER_CONFIG" do
+ bundle "config set path vendor", :env => { "BUNDLE_USER_CONFIG" => bundle_user_config }
+ bundle "config get path", :env => { "BUNDLE_USER_CONFIG" => bundle_user_config }
+ expect(out).to include("Set for the current user (#{bundle_user_config}): \"vendor\"")
+ end
+
+ context "when not explicitly configured, but BUNDLE_USER_HOME set" do
+ let(:bundle_user_home) { bundled_app(".bundle").to_s }
+
+ it "uses the right location" do
+ bundle "config set path vendor", :env => { "BUNDLE_USER_HOME" => bundle_user_home }
+ bundle "config get path", :env => { "BUNDLE_USER_HOME" => bundle_user_home }
+ expect(out).to include("Set for the current user (#{bundle_user_home}/config): \"vendor\"")
+ end
end
end
describe "global" do
- before(:each) { bundle :install }
+ before(:each) do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ G
+ end
it "is the default" do
- bundle "config foo global"
+ bundle "config set foo global"
run "puts Bundler.settings[:foo]"
expect(out).to eq("global")
end
it "can also be set explicitly" do
- bundle! "config --global foo global"
- run! "puts Bundler.settings[:foo]"
+ bundle "config set --global foo global"
+ run "puts Bundler.settings[:foo]"
expect(out).to eq("global")
end
it "has lower precedence than local" do
- bundle "config --local foo local"
+ bundle "config set --local foo local"
- bundle "config --global foo global"
+ bundle "config set --global foo global"
expect(out).to match(/Your application has set foo to "local"/)
run "puts Bundler.settings[:foo]"
@@ -95,7 +134,7 @@ RSpec.describe ".bundle/config" do
begin
ENV["BUNDLE_FOO"] = "env"
- bundle "config --global foo global"
+ bundle "config set --global foo global"
expect(out).to match(/You have a bundler environment variable for foo set to "env"/)
run "puts Bundler.settings[:foo]"
@@ -106,16 +145,16 @@ RSpec.describe ".bundle/config" do
end
it "can be deleted" do
- bundle "config --global foo global"
- bundle "config --delete foo"
+ bundle "config set --global foo global"
+ bundle "config unset foo"
run "puts Bundler.settings[:foo] == nil"
expect(out).to eq("true")
end
it "warns when overriding" do
- bundle "config --global foo previous"
- bundle "config --global foo global"
+ bundle "config set --global foo previous"
+ bundle "config set --global foo global"
expect(out).to match(/You are replacing the current global value of foo/)
run "puts Bundler.settings[:foo]"
@@ -123,8 +162,8 @@ RSpec.describe ".bundle/config" do
end
it "does not warn when using the same value twice" do
- bundle "config --global foo value"
- bundle "config --global foo value"
+ bundle "config set --global foo value"
+ bundle "config set --global foo value"
expect(out).not_to match(/You are replacing the current global value of foo/)
run "puts Bundler.settings[:foo]"
@@ -132,22 +171,22 @@ RSpec.describe ".bundle/config" do
end
it "expands the path at time of setting" do
- bundle "config --global local.foo .."
+ bundle "config set --global local.foo .."
run "puts Bundler.settings['local.foo']"
- expect(out).to eq(File.expand_path(Dir.pwd + "/.."))
+ expect(out).to eq(File.expand_path(bundled_app.to_s + "/.."))
end
it "saves with parseable option" do
- bundle "config --global --parseable foo value"
+ bundle "config set --global --parseable foo value"
expect(out).to eq("foo=value")
run "puts Bundler.settings['foo']"
expect(out).to eq("value")
end
context "when replacing a current value with the parseable flag" do
- before { bundle "config --global foo value" }
+ before { bundle "config set --global foo value" }
it "prints the current value in a parseable format" do
- bundle "config --global --parseable foo value2"
+ bundle "config set --global --parseable foo value2"
expect(out).to eq "foo=value2"
run "puts Bundler.settings['foo']"
expect(out).to eq("value2")
@@ -156,10 +195,15 @@ RSpec.describe ".bundle/config" do
end
describe "local" do
- before(:each) { bundle :install }
+ before(:each) do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ G
+ end
it "can also be set explicitly" do
- bundle "config --local foo local"
+ bundle "config set --local foo local"
run "puts Bundler.settings[:foo]"
expect(out).to eq("local")
end
@@ -167,7 +211,7 @@ RSpec.describe ".bundle/config" do
it "has higher precedence than env" do
begin
ENV["BUNDLE_FOO"] = "env"
- bundle "config --local foo local"
+ bundle "config set --local foo local"
run "puts Bundler.settings[:foo]"
expect(out).to eq("local")
@@ -177,16 +221,16 @@ RSpec.describe ".bundle/config" do
end
it "can be deleted" do
- bundle "config --local foo local"
- bundle "config --delete foo"
+ bundle "config set --local foo local"
+ bundle "config unset foo"
run "puts Bundler.settings[:foo] == nil"
expect(out).to eq("true")
end
it "warns when overriding" do
- bundle "config --local foo previous"
- bundle "config --local foo local"
+ bundle "config set --local foo previous"
+ bundle "config set --local foo local"
expect(out).to match(/You are replacing the current local value of foo/)
run "puts Bundler.settings[:foo]"
@@ -194,14 +238,14 @@ RSpec.describe ".bundle/config" do
end
it "expands the path at time of setting" do
- bundle "config --local local.foo .."
+ bundle "config set --local local.foo .."
run "puts Bundler.settings['local.foo']"
- expect(out).to eq(File.expand_path(Dir.pwd + "/.."))
+ expect(out).to eq(File.expand_path(bundled_app.to_s + "/.."))
end
it "can be deleted with parseable option" do
- bundle "config --local foo value"
- bundle "config --delete --parseable foo"
+ bundle "config set --local foo value"
+ bundle "config unset --parseable foo"
expect(out).to eq ""
run "puts Bundler.settings['foo'] == nil"
expect(out).to eq("true")
@@ -209,7 +253,12 @@ RSpec.describe ".bundle/config" do
end
describe "env" do
- before(:each) { bundle :install }
+ before(:each) do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ G
+ end
it "can set boolean properties via the environment" do
ENV["BUNDLE_FROZEN"] = "true"
@@ -248,39 +297,44 @@ RSpec.describe ".bundle/config" do
describe "parseable option" do
it "prints an empty string" do
- bundle "config foo --parseable"
+ bundle "config get foo --parseable"
expect(out).to eq ""
end
it "only prints the value of the config" do
- bundle "config foo local"
- bundle "config foo --parseable"
+ bundle "config set foo local"
+ bundle "config get foo --parseable"
expect(out).to eq "foo=local"
end
it "can print global config" do
- bundle "config --global bar value"
- bundle "config bar --parseable"
+ bundle "config set --global bar value"
+ bundle "config get bar --parseable"
expect(out).to eq "bar=value"
end
- it "preferes local config over global" do
- bundle "config --local bar value2"
- bundle "config --global bar value"
- bundle "config bar --parseable"
+ it "prefers local config over global" do
+ bundle "config set --local bar value2"
+ bundle "config set --global bar value"
+ bundle "config get bar --parseable"
expect(out).to eq "bar=value2"
end
end
describe "gem mirrors" do
- before(:each) { bundle :install }
+ before(:each) do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ G
+ end
it "configures mirrors using keys with `mirror.`" do
- bundle "config --local mirror.http://gems.example.org http://gem-mirror.example.org"
+ bundle "config set --local mirror.http://gems.example.org http://gem-mirror.example.org"
run(<<-E)
Bundler.settings.gem_mirrors.each do |k, v|
puts "\#{k} => \#{v}"
@@ -291,33 +345,33 @@ E
end
describe "quoting" do
- before(:each) { gemfile "# no gems" }
+ before(:each) { gemfile "source \"#{file_uri_for(gem_repo1)}\"" }
let(:long_string) do
"--with-xml2-include=/usr/pkg/include/libxml2 --with-xml2-lib=/usr/pkg/lib " \
"--with-xslt-dir=/usr/pkg"
end
it "saves quotes" do
- bundle "config foo something\\'"
+ bundle "config set foo something\\'"
run "puts Bundler.settings[:foo]"
expect(out).to eq("something'")
end
- it "doesn't return quotes around values", :ruby => "1.9" do
- bundle "config foo '1'"
+ it "doesn't return quotes around values" do
+ bundle "config set foo '1'"
run "puts Bundler.settings.send(:global_config_file).read"
expect(out).to include('"1"')
run "puts Bundler.settings[:foo]"
expect(out).to eq("1")
end
- it "doesn't duplicate quotes around values", :if => (RUBY_VERSION >= "2.1") do
+ it "doesn't duplicate quotes around values" do
bundled_app(".bundle").mkpath
File.open(bundled_app(".bundle/config"), "w") do |f|
f.write 'BUNDLE_FOO: "$BUILD_DIR"'
end
- bundle "config bar baz"
+ bundle "config set bar baz"
run "puts Bundler.settings.send(:local_config_file).read"
# Starting in Ruby 2.1, YAML automatically adds double quotes
@@ -326,12 +380,12 @@ E
end
it "doesn't duplicate quotes around long wrapped values" do
- bundle "config foo #{long_string}"
+ bundle "config set foo #{long_string}"
run "puts Bundler.settings[:foo]"
expect(out).to eq(long_string)
- bundle "config bar baz"
+ bundle "config set bar baz"
run "puts Bundler.settings[:foo]"
expect(out).to eq(long_string)
@@ -339,7 +393,12 @@ E
end
describe "very long lines" do
- before(:each) { bundle :install }
+ before(:each) do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ G
+ end
let(:long_string) do
"--with-xml2-include=/usr/pkg/include/libxml2 --with-xml2-lib=/usr/pkg/lib " \
@@ -352,33 +411,133 @@ E
end
it "doesn't wrap values" do
- bundle "config foo #{long_string}"
+ bundle "config set foo #{long_string}"
run "puts Bundler.settings[:foo]"
expect(out).to match(long_string)
end
it "can read wrapped unquoted values" do
- bundle "config foo #{long_string_without_special_characters}"
+ bundle "config set foo #{long_string_without_special_characters}"
run "puts Bundler.settings[:foo]"
expect(out).to match(long_string_without_special_characters)
end
end
+
+ describe "subcommands" do
+ it "list" do
+ bundle "config list"
+ expect(out).to eq "Settings are listed in order of priority. The top value will be used.\nspec_run\nSet via BUNDLE_SPEC_RUN: \"true\""
+
+ bundle "config list", :parseable => true
+ expect(out).to eq "spec_run=true"
+ end
+
+ it "list with credentials" do
+ bundle "config list", :env => { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
+ expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"user:[REDACTED]\"\n\nspec_run\nSet via BUNDLE_SPEC_RUN: \"true\""
+
+ bundle "config list", :parseable => true, :env => { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
+ expect(out).to eq "gems.myserver.com=user:password\nspec_run=true"
+ end
+
+ it "list with API token credentials" do
+ bundle "config list", :env => { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
+ expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"[REDACTED]:x-oauth-basic\"\n\nspec_run\nSet via BUNDLE_SPEC_RUN: \"true\""
+
+ bundle "config list", :parseable => true, :env => { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
+ expect(out).to eq "gems.myserver.com=api_token:x-oauth-basic\nspec_run=true"
+ end
+
+ it "get" do
+ ENV["BUNDLE_BAR"] = "bar_val"
+
+ bundle "config get foo"
+ expect(out).to eq "Settings for `foo` in order of priority. The top value will be used\nYou have not configured a value for `foo`"
+
+ ENV["BUNDLE_FOO"] = "foo_val"
+
+ bundle "config get foo --parseable"
+ expect(out).to eq "foo=foo_val"
+
+ bundle "config get foo"
+ expect(out).to eq "Settings for `foo` in order of priority. The top value will be used\nSet via BUNDLE_FOO: \"foo_val\""
+ end
+
+ it "set" do
+ bundle "config set foo 1"
+ expect(out).to eq ""
+
+ bundle "config set --local foo 2"
+ expect(out).to eq ""
+
+ bundle "config set --global foo 3"
+ expect(out).to eq "Your application has set foo to \"2\". This will override the global value you are currently setting"
+
+ bundle "config set --parseable --local foo 4"
+ expect(out).to eq "foo=4"
+
+ bundle "config set --local foo 4.1"
+ expect(out).to eq "You are replacing the current local value of foo, which is currently \"4\""
+
+ bundle "config set --global --local foo 5", :raise_on_error => false
+ expect(last_command).to be_failure
+ expect(err).to eq "The options global and local were specified. Please only use one of the switches at a time."
+ end
+
+ it "unset" do
+ bundle "config unset foo"
+ expect(out).to eq ""
+
+ bundle "config set foo 1"
+ bundle "config unset foo --parseable"
+ expect(out).to eq ""
+
+ bundle "config set --local foo 1"
+ bundle "config set --global foo 2"
+
+ bundle "config unset foo"
+ expect(out).to eq ""
+ expect(bundle("config get foo")).to eq "Settings for `foo` in order of priority. The top value will be used\nYou have not configured a value for `foo`"
+
+ bundle "config set --local foo 1"
+ bundle "config set --global foo 2"
+
+ bundle "config unset foo --local"
+ expect(out).to eq ""
+ expect(bundle("config get foo")).to eq "Settings for `foo` in order of priority. The top value will be used\nSet for the current user (#{home(".bundle/config")}): \"2\""
+ bundle "config unset foo --global"
+ expect(out).to eq ""
+ expect(bundle("config get foo")).to eq "Settings for `foo` in order of priority. The top value will be used\nYou have not configured a value for `foo`"
+
+ bundle "config set --local foo 1"
+ bundle "config set --global foo 2"
+
+ bundle "config unset foo --global"
+ expect(out).to eq ""
+ expect(bundle("config get foo")).to eq "Settings for `foo` in order of priority. The top value will be used\nSet for your local app (#{bundled_app(".bundle/config")}): \"1\""
+ bundle "config unset foo --local"
+ expect(out).to eq ""
+ expect(bundle("config get foo")).to eq "Settings for `foo` in order of priority. The top value will be used\nYou have not configured a value for `foo`"
+
+ bundle "config unset foo --local --global", :raise_on_error => false
+ expect(last_command).to be_failure
+ expect(err).to eq "The options global and local were specified. Please only use one of the switches at a time."
+ end
+ end
end
RSpec.describe "setting gemfile via config" do
context "when only the non-default Gemfile exists" do
it "persists the gemfile location to .bundle/config" do
- File.open(bundled_app("NotGemfile"), "w") do |f|
- f.write <<-G
- source "file://#{gem_repo1}"
- gem 'rack'
- G
- end
+ gemfile bundled_app("NotGemfile"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
- bundle "config --local gemfile #{bundled_app("NotGemfile")}"
- expect(File.exist?(".bundle/config")).to eq(true)
+ bundle "config set --local gemfile #{bundled_app("NotGemfile")}"
+ expect(File.exist?(bundled_app(".bundle/config"))).to eq(true)
- bundle "config"
+ bundle "config list"
expect(out).to include("NotGemfile")
end
end
diff --git a/spec/bundler/commands/console_spec.rb b/spec/bundler/commands/console_spec.rb
index de14b6db5f..aa76096e3d 100644
--- a/spec/bundler/commands/console_spec.rb
+++ b/spec/bundler/commands/console_spec.rb
@@ -1,10 +1,44 @@
# frozen_string_literal: true
-require "spec_helper"
-RSpec.describe "bundle console" do
+RSpec.describe "bundle console", :bundler => "< 3", :readline => true do
before :each do
+ build_repo2 do
+ # A minimal fake pry console
+ build_gem "pry" do |s|
+ s.write "lib/pry.rb", <<-RUBY
+ class Pry
+ class << self
+ def toplevel_binding
+ unless defined?(@toplevel_binding) && @toplevel_binding
+ TOPLEVEL_BINDING.eval %{
+ def self.__pry__; binding; end
+ Pry.instance_variable_set(:@toplevel_binding, __pry__)
+ class << self; undef __pry__; end
+ }
+ end
+ @toplevel_binding.eval('private')
+ @toplevel_binding
+ end
+
+ def __pry__
+ while line = gets
+ begin
+ puts eval(line, toplevel_binding).inspect.sub(/^"(.*)"$/, '=> \\1')
+ rescue Exception => e
+ puts "\#{e.class}: \#{e.message}"
+ puts e.backtrace.first
+ end
+ end
+ end
+ alias start __pry__
+ end
+ end
+ RUBY
+ end
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
gem "activesupport", :group => :test
gem "rack_middleware", :group => :development
@@ -21,18 +55,18 @@ RSpec.describe "bundle console" do
it "uses IRB as default console" do
bundle "console" do |input, _, _|
- input.puts("__method__")
+ input.puts("__FILE__")
input.puts("exit")
end
- expect(out).to include(":irb_binding")
+ expect(out).to include("(irb)")
end
it "starts another REPL if configured as such" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "pry"
G
- bundle "config console pry"
+ bundle "config set console pry"
bundle "console" do |input, _, _|
input.puts("__method__")
@@ -42,14 +76,14 @@ RSpec.describe "bundle console" do
end
it "falls back to IRB if the other REPL isn't available" do
- bundle "config console pry"
+ bundle "config set console pry"
# make sure pry isn't there
bundle "console" do |input, _, _|
- input.puts("__method__")
+ input.puts("__FILE__")
input.puts("exit")
end
- expect(out).to include(":irb_binding")
+ expect(out).to include("(irb)")
end
it "doesn't load any other groups" do
@@ -88,14 +122,14 @@ RSpec.describe "bundle console" do
it "performs an automatic bundle install" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
gem "activesupport", :group => :test
gem "rack_middleware", :group => :development
gem "foo"
G
- bundle "config auto_install 1"
+ bundle "config set auto_install 1"
bundle :console do |input, _, _|
input.puts("puts 'hello'")
input.puts("exit")
diff --git a/spec/bundler/commands/doctor_spec.rb b/spec/bundler/commands/doctor_spec.rb
index 7c6e48ce19..860b638f06 100644
--- a/spec/bundler/commands/doctor_spec.rb
+++ b/spec/bundler/commands/doctor_spec.rb
@@ -1,11 +1,17 @@
# frozen_string_literal: true
-require "spec_helper"
+
+require "find"
require "stringio"
require "bundler/cli"
require "bundler/cli/doctor"
RSpec.describe "bundle doctor" do
before(:each) do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
@stdout = StringIO.new
[:error, :warn].each do |method|
@@ -16,49 +22,125 @@ RSpec.describe "bundle doctor" do
end
end
- it "exits with no message if the installed gem has no C extensions" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
+ it "succeeds on a sane installation" do
+ bundle :doctor
+ end
+
+ context "when all files in home are readable/writable" do
+ before(:each) do
+ stat = double("stat")
+ unwritable_file = double("file")
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [unwritable_file] }
+ allow(File).to receive(:exist?).and_call_original
+ allow(File).to receive(:exist?).with(unwritable_file).and_return(true)
+ allow(File).to receive(:stat).with(unwritable_file) { stat }
+ allow(stat).to receive(:uid) { Process.uid }
+ allow(File).to receive(:writable?).with(unwritable_file) { true }
+ allow(File).to receive(:readable?).with(unwritable_file) { true }
+ end
+
+ it "exits with no message if the installed gem has no C extensions" do
+ expect { Bundler::CLI::Doctor.new({}).run }.not_to raise_error
+ expect(@stdout.string).to be_empty
+ end
+
+ it "exits with no message if the installed gem's C extension dylib breakage is fine" do
+ doctor = Bundler::CLI::Doctor.new({})
+ expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
+ expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/lib/libSystem.dylib"]
+ allow(File).to receive(:exist?).with("/usr/lib/libSystem.dylib").and_return(true)
+ expect { doctor.run }.not_to(raise_error, @stdout.string)
+ expect(@stdout.string).to be_empty
+ end
- bundle :install
- Bundler::CLI::Doctor.new({}).run
- expect(@stdout.string).to be_empty
+ it "exits with a message if one of the linked libraries is missing" do
+ doctor = Bundler::CLI::Doctor.new({})
+ expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
+ expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"]
+ allow(File).to receive(:exist?).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_return(false)
+ expect { doctor.run }.to raise_error(Bundler::ProductionError, strip_whitespace(<<-E).strip), @stdout.string
+ The following gems are missing OS dependencies:
+ * bundler: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
+ * rack: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
+ E
+ end
end
- it "exits with no message if the installed gem's C extension dylib breakage is fine" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
+ context "when home contains broken symlinks" do
+ before(:each) do
+ @broken_symlink = double("file")
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [@broken_symlink] }
+ allow(File).to receive(:exist?).and_call_original
+ allow(File).to receive(:exist?).with(@broken_symlink) { false }
+ end
- bundle :install
- doctor = Bundler::CLI::Doctor.new({})
- expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
- expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/lib/libSystem.dylib"]
- allow(File).to receive(:exist?).and_call_original
- allow(File).to receive(:exist?).with("/usr/lib/libSystem.dylib").and_return(true)
- doctor.run
- expect(@stdout.string).to be_empty
+ it "exits with an error if home contains files that are not readable/writable" do
+ expect { Bundler::CLI::Doctor.new({}).run }.not_to raise_error
+ expect(@stdout.string).to include(
+ "Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{@broken_symlink}"
+ )
+ expect(@stdout.string).not_to include("No issues")
+ end
end
- it "exits with a message if one of the linked libraries is missing" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
+ context "when home contains files that are not readable/writable" do
+ before(:each) do
+ @stat = double("stat")
+ @unwritable_file = double("file")
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [@unwritable_file] }
+ allow(File).to receive(:exist?).and_call_original
+ allow(File).to receive(:exist?).with(@unwritable_file) { true }
+ allow(File).to receive(:stat).with(@unwritable_file) { @stat }
+ end
+
+ it "exits with an error if home contains files that are not readable/writable" do
+ allow(@stat).to receive(:uid) { Process.uid }
+ allow(File).to receive(:writable?).with(@unwritable_file) { false }
+ allow(File).to receive(:readable?).with(@unwritable_file) { false }
+ expect { Bundler::CLI::Doctor.new({}).run }.not_to raise_error
+ expect(@stdout.string).to include(
+ "Files exist in the Bundler home that are not readable/writable by the current user. These files are:\n - #{@unwritable_file}"
+ )
+ expect(@stdout.string).not_to include("No issues")
+ end
+
+ context "when home contains files that are not owned by the current process", :permissions do
+ before(:each) do
+ allow(@stat).to receive(:uid) { 0o0000 }
+ end
+
+ it "exits with an error if home contains files that are not readable/writable and are not owned by the current user" do
+ allow(File).to receive(:writable?).with(@unwritable_file) { false }
+ allow(File).to receive(:readable?).with(@unwritable_file) { false }
+ expect { Bundler::CLI::Doctor.new({}).run }.not_to raise_error
+ expect(@stdout.string).to include(
+ "Files exist in the Bundler home that are owned by another user, and are not readable/writable. These files are:\n - #{@unwritable_file}"
+ )
+ expect(@stdout.string).not_to include("No issues")
+ end
+
+ it "exits with a warning if home contains files that are read/write but not owned by current user" do
+ allow(File).to receive(:writable?).with(@unwritable_file) { true }
+ allow(File).to receive(:readable?).with(@unwritable_file) { true }
+ expect { Bundler::CLI::Doctor.new({}).run }.not_to raise_error
+ expect(@stdout.string).to include(
+ "Files exist in the Bundler home that are owned by another user, but are still readable/writable. These files are:\n - #{@unwritable_file}"
+ )
+ expect(@stdout.string).not_to include("No issues")
+ end
+ end
+ end
- bundle :install
- doctor = Bundler::CLI::Doctor.new({})
- expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
- expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"]
- allow(File).to receive(:exist?).and_call_original
- allow(File).to receive(:exist?).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_return(false)
- expect { doctor.run }.to raise_error Bundler::ProductionError, strip_whitespace(<<-E).strip
- The following gems are missing OS dependencies:
- * bundler: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
- * rack: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
- E
+ context "when home contains filesname with special characters" do
+ it "escape filename before command execute" do
+ doctor = Bundler::CLI::Doctor.new({})
+ expect(doctor).to receive(:`).with("/usr/bin/otool -L \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string")
+ doctor.dylibs_darwin('$(date) "\'\.bundle')
+ expect(doctor).to receive(:`).with("/usr/bin/ldd \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string")
+ doctor.dylibs_ldd('$(date) "\'\.bundle')
+ end
end
end
diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb
index 7736adefe1..e67e5b96ef 100644
--- a/spec/bundler/commands/exec_spec.rb
+++ b/spec/bundler/commands/exec_spec.rb
@@ -1,14 +1,24 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle exec" do
- let(:system_gems_to_install) { %w(rack-1.0.0 rack-0.9.1) }
+ let(:system_gems_to_install) { %w[rack-1.0.0 rack-0.9.1] }
before :each do
- system_gems(system_gems_to_install)
+ system_gems(system_gems_to_install, :path => default_bundle_path)
+ end
+
+ it "works with --gemfile flag" do
+ create_file "CustomGemfile", <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ G
+
+ bundle "exec --gemfile CustomGemfile rackup"
+ expect(out).to eq("1.0.0")
end
it "activates the correct gem" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
G
@@ -16,8 +26,20 @@ RSpec.describe "bundle exec" do
expect(out).to eq("0.9.1")
end
+ it "works and prints no warnings when HOME is not writable" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+ G
+
+ bundle "exec rackup", :env => { "HOME" => "/" }
+ expect(out).to eq("0.9.1")
+ expect(err).to be_empty
+ end
+
it "works when the bins are in ~/.bundle" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -25,41 +47,97 @@ RSpec.describe "bundle exec" do
expect(out).to eq("1.0.0")
end
- it "works when running from a random directory", :ruby_repo do
+ it "works when running from a random directory" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "exec 'cd #{tmp("gems")} && rackup'"
- expect(out).to include("1.0.0")
+ expect(out).to eq("1.0.0")
end
it "works when exec'ing something else" do
- install_gemfile 'gem "rack"'
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\""
bundle "exec echo exec"
expect(out).to eq("exec")
end
it "works when exec'ing to ruby" do
- install_gemfile 'gem "rack"'
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\""
bundle "exec ruby -e 'puts %{hi}'"
expect(out).to eq("hi")
end
+ it "works when exec'ing to rubygems" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\""
+ bundle "exec #{gem_cmd} --version"
+ expect(out).to eq(Gem::VERSION)
+ end
+
+ it "works when exec'ing to rubygems through sh -c" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\""
+ bundle "exec sh -c '#{gem_cmd} --version'"
+ expect(out).to eq(Gem::VERSION)
+ end
+
+ it "works when exec'ing back to bundler with a lockfile that doesn't include the current platform" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+ G
+
+ # simulate lockfile generated with old version not including specific platform
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ RUBY
+
+ DEPENDENCIES
+ rack (= 0.9.1)
+
+ BUNDLED WITH
+ 2.1.4
+ L
+
+ bundle "exec bundle cache", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
+
+ expect(out).to include("Updating files in vendor/cache")
+ end
+
+ it "respects custom process title when loading through ruby" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ script_that_changes_its_own_title_and_checks_if_picked_up_by_ps_unix_utility = <<~'RUBY'
+ Process.setproctitle("1-2-3-4-5-6-7")
+ puts `ps -ocommand= -p#{$$}`
+ RUBY
+ create_file "Gemfile", "source \"#{file_uri_for(gem_repo1)}\""
+ create_file "a.rb", script_that_changes_its_own_title_and_checks_if_picked_up_by_ps_unix_utility
+ bundle "exec ruby a.rb"
+ expect(out).to eq("1-2-3-4-5-6-7")
+ end
+
it "accepts --verbose" do
- install_gemfile 'gem "rack"'
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\""
bundle "exec --verbose echo foobar"
expect(out).to eq("foobar")
end
it "passes --verbose to command if it is given after the command" do
- install_gemfile 'gem "rack"'
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\""
bundle "exec echo --verbose"
expect(out).to eq("--verbose")
end
it "handles --keep-file-descriptors" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
require "tempfile"
command = Tempfile.new("io-test")
@@ -70,38 +148,35 @@ RSpec.describe "bundle exec" do
else
require 'tempfile'
io = Tempfile.new("io-test-fd")
- args = %W[#{Gem.ruby} -I#{lib} #{bindir.join("bundle")} exec --keep-file-descriptors #{Gem.ruby} #{command.path} \#{io.to_i}]
- args << { io.to_i => io } if RUBY_VERSION >= "2.0"
+ args = %W[#{Gem.ruby} -I#{lib_dir} #{bindir.join("bundle")} exec --keep-file-descriptors #{Gem.ruby} #{command.path} \#{io.to_i}]
+ args << { io.to_i => io }
exec(*args)
end
G
- install_gemfile ""
- sys_exec("#{Gem.ruby} #{command.path}")
-
- if Bundler.current_ruby.ruby_2?
- expect(out).to eq("")
- else
- expect(out).to eq("Ruby version #{RUBY_VERSION} defaults to keeping non-standard file descriptors on Kernel#exec.")
- end
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ sys_exec "#{Gem.ruby} #{command.path}"
- expect(err).to lack_errors
+ expect(out).to be_empty
+ expect(err).to be_empty
end
it "accepts --keep-file-descriptors" do
- install_gemfile ""
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
bundle "exec --keep-file-descriptors echo foobar"
- expect(err).to lack_errors
+ expect(err).to be_empty
end
it "can run a command named --verbose" do
- install_gemfile 'gem "rack"'
- File.open("--verbose", "w") do |f|
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\""
+ File.open(bundled_app("--verbose"), "w") do |f|
f.puts "#!/bin/sh"
f.puts "echo foobar"
end
- File.chmod(0o744, "--verbose")
+ File.chmod(0o744, bundled_app("--verbose"))
with_path_as(".") do
bundle "exec -- --verbose"
end
@@ -116,30 +191,130 @@ RSpec.describe "bundle exec" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
G
- Dir.chdir bundled_app2 do
- install_gemfile bundled_app2("Gemfile"), <<-G
- source "file://#{gem_repo2}"
- gem "rack_two", "1.0.0"
- G
- end
+ install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack_two", "1.0.0"
+ G
- bundle! "exec rackup"
+ bundle "exec rackup"
expect(out).to eq("0.9.1")
- Dir.chdir bundled_app2 do
- bundle! "exec rackup"
- expect(out).to eq("1.0.0")
+ bundle "exec rackup", :dir => bundled_app2
+ expect(out).to eq("1.0.0")
+ end
+
+ context "with default gems" do
+ let(:system_gems_to_install) { [] }
+
+ let(:default_irb_version) { ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", :raise_on_error => false }
+
+ context "when not specified in Gemfile" do
+ before do
+ skip "irb isn't a default gem" if default_irb_version.empty?
+
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ end
+
+ it "uses version provided by ruby" do
+ bundle "exec irb --version"
+
+ expect(out).to include(default_irb_version)
+ end
+ end
+
+ context "when specified in Gemfile directly" do
+ let(:specified_irb_version) { "0.9.6" }
+
+ before do
+ skip "irb isn't a default gem" if default_irb_version.empty?
+
+ build_repo2 do
+ build_gem "irb", specified_irb_version do |s|
+ s.executables = "irb"
+ end
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "irb", "#{specified_irb_version}"
+ G
+ end
+
+ it "uses version specified" do
+ bundle "exec irb --version"
+
+ expect(out).to eq(specified_irb_version)
+ expect(err).to be_empty
+ end
end
+
+ context "when specified in Gemfile indirectly" do
+ let(:indirect_irb_version) { "0.9.6" }
+
+ before do
+ skip "irb isn't a default gem" if default_irb_version.empty?
+
+ build_repo2 do
+ build_gem "irb", indirect_irb_version do |s|
+ s.executables = "irb"
+ end
+
+ build_gem "gem_depending_on_old_irb" do |s|
+ s.add_dependency "irb", indirect_irb_version
+ end
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "gem_depending_on_old_irb"
+ G
+
+ bundle "exec irb --version"
+ end
+
+ it "uses resolved version" do
+ expect(out).to eq(indirect_irb_version)
+ expect(err).to be_empty
+ end
+ end
+ end
+
+ it "warns about executable conflicts" do
+ build_repo2 do
+ build_gem "rack_two", "1.0.0" do |s|
+ s.executables = "rackup"
+ end
+ end
+
+ bundle "config set path.system true"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+ G
+
+ install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack_two", "1.0.0"
+ G
+
+ bundle "exec rackup"
+
+ expect(last_command.stderr).to eq(
+ "Bundler is using a binstub that was created for a different gem (rack).\n" \
+ "You should run `bundle binstub rack_two` to work around a system/bundle conflict."
+ )
end
it "handles gems installed with --without" do
- install_gemfile <<-G, :without => :middleware
- source "file://#{gem_repo1}"
+ bundle "config set --local without middleware"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack" # rack 0.9.1 and 1.0 exist
group :middleware do
@@ -154,27 +329,34 @@ RSpec.describe "bundle exec" do
end
it "does not duplicate already exec'ed RUBYOPT" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- rubyopt = ENV["RUBYOPT"]
- rubyopt = "-rbundler/setup #{rubyopt}"
+ bundler_setup_opt = "-r#{lib_dir}/bundler/setup"
+
+ rubyopt = opt_add(bundler_setup_opt, ENV["RUBYOPT"])
bundle "exec 'echo $RUBYOPT'"
- expect(out).to have_rubyopts(rubyopt)
+ expect(out.split(" ").count(bundler_setup_opt)).to eq(1)
bundle "exec 'echo $RUBYOPT'", :env => { "RUBYOPT" => rubyopt }
- expect(out).to have_rubyopts(rubyopt)
+ expect(out.split(" ").count(bundler_setup_opt)).to eq(1)
end
- it "does not duplicate already exec'ed RUBYLIB", :ruby_repo do
+ it "does not duplicate already exec'ed RUBYLIB" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
rubylib = ENV["RUBYLIB"]
- rubylib = "#{rubylib}".split(File::PATH_SEPARATOR).unshift "#{bundler_path}"
+ rubylib = rubylib.to_s.split(File::PATH_SEPARATOR).unshift lib_dir.to_s
rubylib = rubylib.uniq.join(File::PATH_SEPARATOR)
bundle "exec 'echo $RUBYLIB'"
@@ -186,62 +368,52 @@ RSpec.describe "bundle exec" do
it "errors nicely when the argument doesn't exist" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "exec foobarbaz"
- expect(exitstatus).to eq(127) if exitstatus
- expect(out).to include("bundler: command not found: foobarbaz")
- expect(out).to include("Install missing gem executables with `bundle install`")
+ bundle "exec foobarbaz", :raise_on_error => false
+ expect(exitstatus).to eq(127)
+ expect(err).to include("bundler: command not found: foobarbaz")
+ expect(err).to include("Install missing gem executables with `bundle install`")
end
it "errors nicely when the argument is not executable" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "exec touch foo"
- bundle "exec ./foo"
- expect(exitstatus).to eq(126) if exitstatus
- expect(out).to include("bundler: not executable: ./foo")
+ bundle "exec ./foo", :raise_on_error => false
+ expect(exitstatus).to eq(126)
+ expect(err).to include("bundler: not executable: ./foo")
end
it "errors nicely when no arguments are passed" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "exec"
- expect(exitstatus).to eq(128) if exitstatus
- expect(out).to include("bundler: exec needs a command to run")
+ bundle "exec", :raise_on_error => false
+ expect(exitstatus).to eq(128)
+ expect(err).to include("bundler: exec needs a command to run")
end
- it "raises a helpful error when exec'ing to something outside of the bundle", :ruby_repo, :rubygems => ">= 2.5.2" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
- gem "with_license"
+ it "raises a helpful error when exec'ing to something outside of the bundle" do
+ bundle "config set clean false" # want to keep the rackup binstub
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo"
G
[true, false].each do |l|
- bundle! "config disable_exec_load #{l}"
- bundle "exec rackup"
+ bundle "config set disable_exec_load #{l}"
+ bundle "exec rackup", :raise_on_error => false
expect(err).to include "can't find executable rackup for gem rack. rack is not currently included in the bundle, perhaps you meant to add it to your Gemfile?"
end
end
- # Different error message on old RG versions (before activate_bin_path) because they
- # called `Kernel#gem` directly
- it "raises a helpful error when exec'ing to something outside of the bundle", :rubygems => "< 2.5.2" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
- gem "with_license"
- G
- [true, false].each do |l|
- bundle! "config disable_exec_load #{l}"
- bundle "exec rackup"
- expect(err).to include "rack is not part of the bundle. Add it to your Gemfile."
- end
- end
-
describe "with help flags" do
each_prefix = proc do |string, &blk|
1.upto(string.length) {|l| blk.call(string[0, l]) }
@@ -249,7 +421,10 @@ RSpec.describe "bundle exec" do
each_prefix.call("exec") do |exec|
describe "when #{exec} is used" do
before(:each) do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -292,39 +467,39 @@ RSpec.describe "bundle exec" do
expect(out).to eq('args: ["-h"]')
end
- it "shows bundle-exec's man page when --help is between exec and the executable", :ruby_repo do
+ it "shows bundle-exec's man page when --help is between exec and the executable" do
with_fake_man do
bundle "#{exec} --help cat"
end
- expect(out).to include(%(["#{root}/man/bundle-exec.1"]))
+ expect(out).to include(%(["#{man_dir}/bundle-exec.1"]))
end
- it "shows bundle-exec's man page when --help is before exec", :ruby_repo do
+ it "shows bundle-exec's man page when --help is before exec" do
with_fake_man do
bundle "--help #{exec}"
end
- expect(out).to include(%(["#{root}/man/bundle-exec.1"]))
+ expect(out).to include(%(["#{man_dir}/bundle-exec.1"]))
end
- it "shows bundle-exec's man page when -h is before exec", :ruby_repo do
+ it "shows bundle-exec's man page when -h is before exec" do
with_fake_man do
bundle "-h #{exec}"
end
- expect(out).to include(%(["#{root}/man/bundle-exec.1"]))
+ expect(out).to include(%(["#{man_dir}/bundle-exec.1"]))
end
- it "shows bundle-exec's man page when --help is after exec", :ruby_repo do
+ it "shows bundle-exec's man page when --help is after exec" do
with_fake_man do
bundle "#{exec} --help"
end
- expect(out).to include(%(["#{root}/man/bundle-exec.1"]))
+ expect(out).to include(%(["#{man_dir}/bundle-exec.1"]))
end
- it "shows bundle-exec's man page when -h is after exec", :ruby_repo do
+ it "shows bundle-exec's man page when -h is after exec" do
with_fake_man do
bundle "#{exec} -h"
end
- expect(out).to include(%(["#{root}/man/bundle-exec.1"]))
+ expect(out).to include(%(["#{man_dir}/bundle-exec.1"]))
end
end
end
@@ -334,20 +509,20 @@ RSpec.describe "bundle exec" do
describe "run from a random directory" do
before(:each) do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
- it "works when unlocked", :ruby_repo do
+ it "works when unlocked" do
bundle "exec 'cd #{tmp("gems")} && rackup'"
expect(out).to eq("1.0.0")
- expect(out).to include("1.0.0")
end
- it "works when locked", :ruby_repo do
+ it "works when locked" do
expect(the_bundle).to be_locked
bundle "exec 'cd #{tmp("gems")} && rackup'"
- expect(out).to include("1.0.0")
+ expect(out).to eq("1.0.0")
end
end
@@ -358,6 +533,7 @@ RSpec.describe "bundle exec" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "fizz", :path => "#{File.expand_path(home("fizz"))}"
G
end
@@ -382,6 +558,7 @@ RSpec.describe "bundle exec" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "fizz_git", :git => "#{lib_path("fizz_git-1.0")}"
G
end
@@ -405,6 +582,7 @@ RSpec.describe "bundle exec" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "fizz_no_gemspec", "1.0", :git => "#{lib_path("fizz_no_gemspec-1.0")}"
G
end
@@ -424,18 +602,48 @@ RSpec.describe "bundle exec" do
it "performs an automatic bundle install" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
gem "foo"
G
- bundle "config auto_install 1"
+ bundle "config set auto_install 1"
bundle "exec rackup"
expect(out).to include("Installing foo 1.0")
end
+ it "loads the correct optparse when `auto_install` is set, and optparse is a dependency" do
+ if Gem.ruby_version >= Gem::Version.new("3.0.0") && Gem.rubygems_version < Gem::Version.new("3.3.0.a")
+ skip "optparse is a default gem, and rubygems loads it during install"
+ end
+
+ build_repo4 do
+ build_gem "fastlane", "2.192.0" do |s|
+ s.executables = "fastlane"
+ s.add_dependency "optparse", "~> 999.999.999"
+ end
+
+ build_gem "optparse", "999.999.998"
+ build_gem "optparse", "999.999.999"
+ end
+
+ system_gems "optparse-999.999.998", :gem_repo => gem_repo4
+
+ bundle "config set auto_install 1"
+ bundle "config set --local path vendor/bundle"
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "fastlane"
+ G
+
+ bundle "exec fastlane"
+ expect(out).to include("Installing optparse 999.999.999")
+ expect(out).to include("2.192.0")
+ end
+
describe "with gems bundled via :path with invalid gemspecs" do
- it "outputs the gemspec validation errors", :rubygems => ">= 1.7.2" do
+ it "outputs the gemspec validation errors" do
build_lib "foo"
gemspec = lib_path("foo-1.0").join("foo.gemspec").to_s
@@ -450,11 +658,12 @@ RSpec.describe "bundle exec" do
G
end
- install_gemfile <<-G
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
- bundle "exec irb"
+ bundle "exec irb", :raise_on_error => false
expect(err).to match("The gemspec at #{lib_path("foo-1.0").join("foo.gemspec")} is not valid")
expect(err).to match('"TODO" is not a summary')
@@ -463,7 +672,11 @@ RSpec.describe "bundle exec" do
describe "with gems bundled for deployment" do
it "works when calling bundler from another script" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
module Monkey
def bin_path(a,b,c)
raise Gem::GemNotFoundException.new('Fail')
@@ -471,8 +684,9 @@ RSpec.describe "bundle exec" do
end
Bundler.rubygems.extend(Monkey)
G
- bundle "install --deployment"
- bundle "exec ruby -e '`#{bindir.join("bundler")} -v`; puts $?.success?'"
+ bundle "config set path.system true"
+ bundle "install"
+ bundle "exec ruby -e '`bundle -v`; puts $?.success?'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(out).to match("true")
end
end
@@ -492,10 +706,11 @@ RSpec.describe "bundle exec" do
RUBY
before do
- path.open("w") {|f| f << executable }
- path.chmod(0o755)
+ bundled_app(path).open("w") {|f| f << executable }
+ bundled_app(path).chmod(0o755)
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
@@ -505,36 +720,73 @@ RSpec.describe "bundle exec" do
let(:rack) { "RACK: 1.0.0" }
let(:process) do
title = "PROCESS: #{path}"
- title += " arg1 arg2" if RUBY_VERSION >= "2.1"
+ title += " arg1 arg2"
title
end
let(:exit_code) { 0 }
let(:expected) { [exec, args, rack, process].join("\n") }
let(:expected_err) { "" }
- subject { bundle "exec #{path} arg1 arg2" }
+ subject { bundle "exec #{path} arg1 arg2", :raise_on_error => false }
- shared_examples_for "it runs" do
- it "like a normally executed executable" do
- subject
- expect(exitstatus).to eq(exit_code) if exitstatus
- expect(err).to eq(expected_err)
- expect(out).to eq(expected)
- end
- end
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
- it_behaves_like "it runs"
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
context "the executable exits explicitly" do
let(:executable) { super() << "\nexit #{exit_code}\nputs 'POST_EXIT'\n" }
context "with exit 0" do
- it_behaves_like "it runs"
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
end
context "with exit 99" do
let(:exit_code) { 99 }
- it_behaves_like "it runs"
+
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
+ end
+ end
+
+ context "the executable exits by SignalException" do
+ let(:executable) do
+ ex = super()
+ ex << "\n"
+ ex << "raise SignalException, 'SIGTERM'\n"
+ ex
+ end
+ let(:expected_err) { "" }
+ let(:exit_code) do
+ # signal mask 128 + plus signal 15 -> TERM
+ # this is specified by C99
+ 128 + 15
+ end
+
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
end
end
@@ -542,55 +794,132 @@ RSpec.describe "bundle exec" do
let(:executable) { "" }
let(:exit_code) { 0 }
- let(:expected) { "#{path} is empty" }
- let(:expected_err) { "" }
- if LessThanProc.with(RUBY_VERSION).call("1.9")
- # Kernel#exec in ruby < 1.9 will raise Errno::ENOEXEC if the command content is empty,
- # even if the command is set as an executable.
- pending "Kernel#exec is different"
- else
- it_behaves_like "it runs"
+ let(:expected_err) { "#{path} is empty" }
+ let(:expected) { "" }
+
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
end
end
context "the executable raises" do
let(:executable) { super() << "\nraise 'ERROR'" }
let(:exit_code) { 1 }
- let(:expected) { super() << "\nbundler: failed to load command: #{path} (#{path})" }
let(:expected_err) do
- "RuntimeError: ERROR\n #{path}:10" +
- (Bundler.current_ruby.ruby_18? ? "" : ":in `<top (required)>'")
+ "bundler: failed to load command: #{path} (#{path})" \
+ "\n#{path}:10:in `<top (required)>': ERROR (RuntimeError)"
+ end
+
+ it "runs like a normally executed executable" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to start_with(expected_err)
+ expect(out).to eq(expected)
+ end
+ end
+
+ context "the executable raises an error without a backtrace" do
+ let(:executable) { super() << "\nclass Err < Exception\ndef backtrace; end;\nend\nraise Err" }
+ let(:exit_code) { 1 }
+ let(:expected_err) { "bundler: failed to load command: #{path} (#{path})\n#{system_gem_path("bin/bundle")}: Err (Err)" }
+ let(:expected) { super() }
+
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
end
- it_behaves_like "it runs"
end
- context "when the file uses the current ruby shebang", :ruby_repo do
+ context "when the file uses the current ruby shebang" do
let(:shebang) { "#!#{Gem.ruby}" }
- it_behaves_like "it runs"
+
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
+ end
+
+ context "when Bundler.setup fails", :bundler => "< 3" do
+ before do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack', '2'
+ G
+ ENV["BUNDLER_FORCE_TTY"] = "true"
+ end
+
+ let(:exit_code) { Bundler::GemNotFound.new.status_code }
+ let(:expected) { "" }
+ let(:expected_err) { <<-EOS.strip }
+Could not find gem 'rack (= 2)' in locally installed gems.
+The source contains the following versions of 'rack': 0.9.1, 1.0.0
+Run `bundle install` to install missing gems.
+ EOS
+
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
end
- context "when Bundler.setup fails" do
+ context "when Bundler.setup fails", :bundler => "3" do
before do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack', '2'
G
ENV["BUNDLER_FORCE_TTY"] = "true"
end
let(:exit_code) { Bundler::GemNotFound.new.status_code }
- let(:expected) { <<-EOS.strip }
-\e[31mCould not find gem 'rack (= 2)' in any of the gem sources listed in your Gemfile.\e[0m
-\e[33mRun `bundle install` to install missing gems.\e[0m
+ let(:expected) { "" }
+ let(:expected_err) { <<-EOS.strip }
+Could not find gem 'rack (= 2)' in locally installed gems.
+The source contains the following versions of 'rack': 1.0.0
+Run `bundle install` to install missing gems.
EOS
- it_behaves_like "it runs"
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
end
context "when the executable exits non-zero via at_exit" do
let(:executable) { super() + "\n\nat_exit { $! ? raise($!) : exit(1) }" }
let(:exit_code) { 1 }
- it_behaves_like "it runs"
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
end
context "when disable_exec_load is set" do
@@ -598,10 +927,17 @@ RSpec.describe "bundle exec" do
let(:process) { "PROCESS: ruby #{path} arg1 arg2" }
before do
- bundle "config disable_exec_load true"
+ bundle "config set disable_exec_load true"
end
- it_behaves_like "it runs"
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
end
context "regarding $0 and __FILE__" do
@@ -617,120 +953,270 @@ $0: #{path.to_s.inspect}
__FILE__: #{path.to_s.inspect}
EOS
- it_behaves_like "it runs"
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
+ end
context "when the path is relative" do
let(:path) { super().relative_path_from(bundled_app) }
- if LessThanProc.with(RUBY_VERSION).call("1.9")
- pending "relative paths have ./ __FILE__"
- else
- it_behaves_like "it runs"
+ it "runs" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ subject
+ expect(exitstatus).to eq(exit_code)
+ expect(err).to eq(expected_err)
+ expect(out).to eq(expected)
end
end
context "when the path is relative with a leading ./" do
- let(:path) { Pathname.new("./#{super().relative_path_from(Pathname.pwd)}") }
+ let(:path) { Pathname.new("./#{super().relative_path_from(bundled_app)}") }
- if LessThanProc.with(RUBY_VERSION).call("< 1.9")
- pending "relative paths with ./ have absolute __FILE__"
- else
- it_behaves_like "it runs"
- end
+ pending "relative paths with ./ have absolute __FILE__"
end
end
- context "signals being trapped by bundler" do
- let(:executable) { strip_whitespace <<-RUBY }
- #{shebang}
- begin
- Thread.new do
- puts 'Started' # For process sync
- STDOUT.flush
- sleep 1 # ignore quality_spec
- raise "Didn't receive INT at all"
- end.join
- rescue Interrupt
- puts "foo"
- end
- RUBY
+ context "signal handling" do
+ let(:test_signals) do
+ open3_reserved_signals = %w[CHLD CLD PIPE]
+ reserved_signals = %w[SEGV BUS ILL FPE VTALRM KILL STOP EXIT]
+ bundler_signals = %w[INT]
+
+ Signal.list.keys - (bundler_signals + reserved_signals + open3_reserved_signals)
+ end
+
+ context "signals being trapped by bundler" do
+ let(:executable) { strip_whitespace <<-RUBY }
+ #{shebang}
+ begin
+ Thread.new do
+ puts 'Started' # For process sync
+ STDOUT.flush
+ sleep 1 # ignore quality_spec
+ raise "Didn't receive INT at all"
+ end.join
+ rescue Interrupt
+ puts "foo"
+ end
+ RUBY
+
+ it "receives the signal" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
- it "receives the signal" do
- skip "popen3 doesn't provide a way to get pid " unless RUBY_VERSION >= "1.9.3"
+ bundle("exec #{path}") do |_, o, thr|
+ o.gets # Consumes 'Started' and ensures that thread has started
+ Process.kill("INT", thr.pid)
+ end
- bundle("exec #{path}") do |_, o, thr|
- o.gets # Consumes 'Started' and ensures that thread has started
- Process.kill("INT", thr.pid)
+ expect(out).to eq("foo")
end
+ end
- expect(out).to eq("foo")
+ context "signals not being trapped by bunder" do
+ let(:executable) { strip_whitespace <<-RUBY }
+ #{shebang}
+
+ signals = #{test_signals.inspect}
+ result = signals.map do |sig|
+ Signal.trap(sig, "IGNORE")
+ end
+ puts result.select { |ret| ret == "IGNORE" }.count
+ RUBY
+
+ it "makes sure no unexpected signals are restored to DEFAULT" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ test_signals.each do |n|
+ Signal.trap(n, "IGNORE")
+ end
+
+ bundle("exec #{path}")
+
+ expect(out).to eq(test_signals.count.to_s)
+ end
end
end
end
- context "nested bundle exec", :ruby_repo do
- let(:system_gems_to_install) { super() << :bundler }
-
- context "with shared gems disabled" do
+ context "nested bundle exec" do
+ context "when bundle in a local path" do
before do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle :install, :system_bundler => true, :path => "vendor/bundler"
+ bundle "config set path vendor/bundler"
+ bundle :install
end
- it "overrides disable_shared_gems so bundler can be found" do
+ it "correctly shells out" do
file = bundled_app("file_that_bundle_execs.rb")
- create_file(file, <<-RB)
+ create_file(file, <<-RUBY)
#!#{Gem.ruby}
puts `bundle exec echo foo`
- RB
+ RUBY
file.chmod(0o777)
- bundle! "exec #{file}", :system_bundler => true
+ bundle "exec #{file}", :env => { "PATH" => path }
expect(out).to eq("foo")
end
end
+ context "when Kernel.require uses extra monkeypatches" do
+ before do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ end
+
+ it "does not undo the monkeypatches" do
+ karafka = bundled_app("bin/karafka")
+ create_file(karafka, <<~RUBY)
+ #!#{Gem.ruby}
+
+ module Kernel
+ module_function
+
+ alias_method :require_before_extra_monkeypatches, :require
+
+ def require(path)
+ puts "requiring \#{path} used the monkeypatch"
+
+ require_before_extra_monkeypatches(path)
+ end
+ end
+
+ Bundler.setup(:default)
+
+ require "foo"
+ RUBY
+ karafka.chmod(0o777)
+
+ foreman = bundled_app("bin/foreman")
+ create_file(foreman, <<~RUBY)
+ #!#{Gem.ruby}
+
+ puts `bundle exec bin/karafka`
+ RUBY
+ foreman.chmod(0o777)
+
+ bundle "exec #{foreman}"
+ expect(out).to eq("requiring foo used the monkeypatch")
+ end
+ end
+
+ context "when gemfile and path are configured", :ruby_repo do
+ before do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
+
+ build_repo2 do
+ build_gem "rails", "6.1.0" do |s|
+ s.executables = "rails"
+ end
+ end
+
+ bundle "config set path vendor/bundle"
+ bundle "config set gemfile gemfiles/rack_6_1.gemfile"
+
+ create_file(bundled_app("gemfiles/rack_6_1.gemfile"), <<~RUBY)
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "rails", "6.1.0"
+ RUBY
+
+ # A Gemfile needs to be in the root to trick bundler's root resolution
+ create_file(bundled_app("Gemfile"), "source \"#{file_uri_for(gem_repo1)}\"")
+
+ bundle "install"
+ end
+
+ it "can still find gems after a nested subprocess" do
+ script = bundled_app("bin/myscript")
+
+ create_file(script, <<~RUBY)
+ #!#{Gem.ruby}
+
+ puts `bundle exec rails`
+ RUBY
+
+ script.chmod(0o777)
+
+ bundle "exec #{script}"
+
+ expect(err).to be_empty
+ expect(out).to eq("6.1.0")
+ end
+ end
+
context "with a system gem that shadows a default gem" do
let(:openssl_version) { "99.9.9" }
- let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", :artifice => nil }
+ let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", :artifice => nil, :raise_on_error => false }
it "only leaves the default gem in the stdlib available" do
+ skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
skip "openssl isn't a default gem" if expected.empty?
- install_gemfile! "" # must happen before installing the broken system gem
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" # must happen before installing the broken system gem
build_repo4 do
build_gem "openssl", openssl_version do |s|
- s.write("lib/openssl.rb", <<-RB)
+ s.write("lib/openssl.rb", <<-RUBY)
raise "custom openssl should not be loaded, it's not in the gemfile!"
- RB
+ RUBY
end
end
- system_gems(:bundler, "openssl-#{openssl_version}", :gem_repo => gem_repo4)
+ system_gems("openssl-#{openssl_version}", :gem_repo => gem_repo4)
file = bundled_app("require_openssl.rb")
- create_file(file, <<-RB)
+ create_file(file, <<-RUBY)
#!/usr/bin/env ruby
require "openssl"
puts OpenSSL::VERSION
warn Gem.loaded_specs.values.map(&:full_name)
- RB
+ RUBY
file.chmod(0o777)
+ env = { "PATH" => path }
aggregate_failures do
- expect(bundle!("exec #{file}", :system_bundler => true, :artifice => nil)).to eq(expected)
- expect(bundle!("exec bundle exec #{file}", :system_bundler => true, :artifice => nil)).to eq(expected)
- expect(bundle!("exec ruby #{file}", :system_bundler => true, :artifice => nil)).to eq(expected)
- expect(run!(file.read, :no_lib => true, :artifice => nil)).to eq(expected)
+ expect(bundle("exec #{file}", :artifice => nil, :env => env)).to eq(expected)
+ expect(bundle("exec bundle exec #{file}", :artifice => nil, :env => env)).to eq(expected)
+ expect(bundle("exec ruby #{file}", :artifice => nil, :env => env)).to eq(expected)
+ expect(run(file.read, :artifice => nil, :env => env)).to eq(expected)
end
+ skip "ruby_core has openssl and rubygems in the same folder, and this test needs rubygems require but default openssl not in a directly added entry in $LOAD_PATH" if ruby_core?
# sanity check that we get the newer, custom version without bundler
- sys_exec("#{Gem.ruby} #{file}")
+ sys_exec "#{Gem.ruby} #{file}", :env => env, :raise_on_error => false
expect(err).to include("custom openssl should not be loaded")
end
end
+
+ context "with a git gem that includes extensions", :ruby_repo do
+ before do
+ build_git "simple_git_binary", &:add_c_extension
+ bundle "config set --local path .bundle"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "simple_git_binary", :git => '#{lib_path("simple_git_binary-1.0")}'
+ G
+ end
+
+ it "allows calling bundle install" do
+ bundle "exec bundle install"
+ end
+
+ it "allows calling bundle install after removing gem.build_complete" do
+ FileUtils.rm_rf Dir[bundled_app(".bundle/**/gem.build_complete")]
+ bundle "exec #{Gem.ruby} -S bundle install"
+ end
+ end
end
end
diff --git a/spec/bundler/commands/fund_spec.rb b/spec/bundler/commands/fund_spec.rb
new file mode 100644
index 0000000000..5a0c5411da
--- /dev/null
+++ b/spec/bundler/commands/fund_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle fund" do
+ before do
+ build_repo2 do
+ build_gem "has_funding_and_other_metadata" do |s|
+ s.metadata = {
+ "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
+ "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
+ "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
+ "homepage_uri" => "https://bestgemever.example.io",
+ "mailing_list_uri" => "https://groups.example.com/bestgemever",
+ "funding_uri" => "https://example.com/has_funding_and_other_metadata/funding",
+ "source_code_uri" => "https://example.com/user/bestgemever",
+ "wiki_uri" => "https://example.com/user/bestgemever/wiki",
+ }
+ end
+
+ build_gem "has_funding", "1.2.3" do |s|
+ s.metadata = {
+ "funding_uri" => "https://example.com/has_funding/funding",
+ }
+ end
+
+ build_gem "gem_with_dependent_funding", "1.0" do |s|
+ s.add_dependency "has_funding"
+ end
+ end
+ end
+
+ it "prints fund information for all gems in the bundle" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'has_funding_and_other_metadata'
+ gem 'has_funding'
+ gem 'rack-obama'
+ G
+
+ bundle "fund"
+
+ expect(out).to include("* has_funding_and_other_metadata (1.0)\n Funding: https://example.com/has_funding_and_other_metadata/funding")
+ expect(out).to include("* has_funding (1.2.3)\n Funding: https://example.com/has_funding/funding")
+ expect(out).to_not include("rack-obama")
+ end
+
+ it "does not consider fund information for gem dependencies" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'gem_with_dependent_funding'
+ G
+
+ bundle "fund"
+
+ expect(out).to_not include("* has_funding (1.2.3)\n Funding: https://example.com/has_funding/funding")
+ expect(out).to_not include("gem_with_dependent_funding")
+ end
+
+ it "prints message if none of the gems have fund information" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'rack-obama'
+ G
+
+ bundle "fund"
+
+ expect(out).to include("None of the installed gems you directly depend on are looking for funding.")
+ end
+
+ describe "with --group option" do
+ it "prints fund message for only specified group gems" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'has_funding_and_other_metadata', :group => :development
+ gem 'has_funding'
+ G
+
+ bundle "fund --group development"
+ expect(out).to include("* has_funding_and_other_metadata (1.0)\n Funding: https://example.com/has_funding_and_other_metadata/funding")
+ expect(out).to_not include("* has_funding (1.2.3)\n Funding: https://example.com/has_funding/funding")
+ end
+ end
+end
diff --git a/spec/bundler/commands/help_spec.rb b/spec/bundler/commands/help_spec.rb
index 6faeed058e..f72763900e 100644
--- a/spec/bundler/commands/help_spec.rb
+++ b/spec/bundler/commands/help_spec.rb
@@ -1,35 +1,25 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle help" do
- # Rubygems 1.4+ no longer load gem plugins so this test is no longer needed
- it "complains if older versions of bundler are installed", :rubygems => "< 1.4" do
- system_gems "bundler-0.8.1"
-
- bundle "help"
- expect(err).to include("older than 0.9")
- expect(err).to include("running `gem cleanup bundler`.")
- end
-
- it "uses mann when available", :ruby_repo do
+ it "uses man when available" do
with_fake_man do
bundle "help gemfile"
end
- expect(out).to eq(%(["#{root}/man/gemfile.5"]))
+ expect(out).to eq(%(["#{man_dir}/gemfile.5"]))
end
- it "prefixes bundle commands with bundle- when finding the groff files", :ruby_repo do
+ it "prefixes bundle commands with bundle- when finding the man files" do
with_fake_man do
bundle "help install"
end
- expect(out).to eq(%(["#{root}/man/bundle-install.1"]))
+ expect(out).to eq(%(["#{man_dir}/bundle-install.1"]))
end
- it "simply outputs the txt file when there is no man on the path", :ruby_repo do
+ it "simply outputs the human readable file when there is no man on the path" do
with_path_as("") do
bundle "help install"
end
- expect(out).to match(/BUNDLE-INSTALL/)
+ expect(out).to match(/bundle-install/)
end
it "still outputs the old help for commands that do not have man pages yet" do
@@ -38,6 +28,8 @@ RSpec.describe "bundle help" do
end
it "looks for a binary and executes it with --help option if it's named bundler-<task>" do
+ skip "Could not find command testtasks, probably because not a windows friendly executable" if Gem.win_platform?
+
File.open(tmp("bundler-testtasks"), "w", 0o755) do |f|
f.puts "#!/usr/bin/env ruby\nputs ARGV.join(' ')\n"
end
@@ -46,54 +38,53 @@ RSpec.describe "bundle help" do
bundle "help testtasks"
end
- expect(exitstatus).to be_zero if exitstatus
expect(out).to eq("--help")
end
- it "is called when the --help flag is used after the command", :ruby_repo do
+ it "is called when the --help flag is used after the command" do
with_fake_man do
bundle "install --help"
end
- expect(out).to eq(%(["#{root}/man/bundle-install.1"]))
+ expect(out).to eq(%(["#{man_dir}/bundle-install.1"]))
end
- it "is called when the --help flag is used before the command", :ruby_repo do
+ it "is called when the --help flag is used before the command" do
with_fake_man do
bundle "--help install"
end
- expect(out).to eq(%(["#{root}/man/bundle-install.1"]))
+ expect(out).to eq(%(["#{man_dir}/bundle-install.1"]))
end
- it "is called when the -h flag is used before the command", :ruby_repo do
+ it "is called when the -h flag is used before the command" do
with_fake_man do
bundle "-h install"
end
- expect(out).to eq(%(["#{root}/man/bundle-install.1"]))
+ expect(out).to eq(%(["#{man_dir}/bundle-install.1"]))
end
- it "is called when the -h flag is used after the command", :ruby_repo do
+ it "is called when the -h flag is used after the command" do
with_fake_man do
bundle "install -h"
end
- expect(out).to eq(%(["#{root}/man/bundle-install.1"]))
+ expect(out).to eq(%(["#{man_dir}/bundle-install.1"]))
end
it "has helpful output when using --help flag for a non-existent command" do
with_fake_man do
- bundle "instill -h"
+ bundle "instill -h", :raise_on_error => false
end
- expect(out).to include('Could not find command "instill".')
+ expect(err).to include('Could not find command "instill".')
end
- it "is called when only using the --help flag", :ruby_repo do
+ it "is called when only using the --help flag" do
with_fake_man do
bundle "--help"
end
- expect(out).to eq(%(["#{root}/man/bundle.1"]))
+ expect(out).to eq(%(["#{man_dir}/bundle.1"]))
with_fake_man do
bundle "-h"
end
- expect(out).to eq(%(["#{root}/man/bundle.1"]))
+ expect(out).to eq(%(["#{man_dir}/bundle.1"]))
end
end
diff --git a/spec/bundler/commands/info_spec.rb b/spec/bundler/commands/info_spec.rb
index cdfea983dc..7f618b5f6c 100644
--- a/spec/bundler/commands/info_spec.rb
+++ b/spec/bundler/commands/info_spec.rb
@@ -1,41 +1,117 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle info" do
- context "info from specific gem in gemfile" do
+ context "with a standard Gemfile" do
before do
+ build_repo2 do
+ build_gem "has_metadata" do |s|
+ s.metadata = {
+ "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
+ "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
+ "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
+ "homepage_uri" => "https://bestgemever.example.io",
+ "mailing_list_uri" => "https://groups.example.com/bestgemever",
+ "source_code_uri" => "https://example.com/user/bestgemever",
+ "wiki_uri" => "https://example.com/user/bestgemever/wiki",
+ }
+ end
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails"
+ gem "has_metadata"
G
end
- it "prints information about the current gem" do
+ it "creates a Gemfile.lock when invoked with a gem name" do
+ FileUtils.rm(bundled_app_lock)
+
+ bundle "info rails"
+
+ expect(bundled_app_lock).to exist
+ end
+
+ it "prints information if gem exists in bundle" do
bundle "info rails"
expect(out).to include "* rails (2.3.2)
\tSummary: This is just a fake gem for testing
-\tHomepage: http://example.com"
- expect(out).to match(%r{Path\: .*\/rails\-2\.3\.2})
+\tHomepage: http://example.com
+\tPath: #{default_bundle_path("gems", "rails-2.3.2")}"
end
- context "given a gem that is not installed" do
- it "prints missing gem error" do
- bundle "info foo"
- expect(out).to eq "Could not find gem 'foo'."
- end
+ it "prints path if gem exists in bundle" do
+ bundle "info rails --path"
+ expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
+ end
+
+ it "prints the path to the running bundler" do
+ bundle "info bundler --path"
+ expect(out).to eq(root.to_s)
+ end
+
+ it "prints gem version if exists in bundle" do
+ bundle "info rails --version"
+ expect(out).to eq("2.3.2")
+ end
+
+ it "doesn't claim that bundler has been deleted, even if using a custom path without bundler there" do
+ bundle "config set --local path vendor/bundle"
+ bundle "install"
+ bundle "info bundler"
+ expect(out).to include("\tPath: #{root}")
+ expect(err).not_to match(/The gem bundler has been deleted/i)
+ end
+
+ it "complains if gem not in bundle" do
+ bundle "info missing", :raise_on_error => false
+ expect(err).to eq("Could not find gem 'missing'.")
+ end
+
+ it "warns if path no longer exists on disk" do
+ FileUtils.rm_rf(default_bundle_path("gems", "rails-2.3.2"))
+
+ bundle "info rails --path"
+
+ expect(err).to match(/The gem rails has been deleted/i)
+ expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
+
+ bundle "info rail --path"
+ expect(err).to match(/The gem rails has been deleted/i)
+ expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
+
+ bundle "info rails"
+ expect(err).to match(/The gem rails has been deleted/i)
+ expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
end
context "given a default gem shippped in ruby", :ruby_repo do
- it "prints information about the default gem", :if => (RUBY_VERSION >= "2.0") do
+ it "prints information about the default gem" do
bundle "info rdoc"
expect(out).to include("* rdoc")
expect(out).to include("Default Gem: yes")
end
end
+ context "given a gem with metadata" do
+ it "prints the gem metadata" do
+ bundle "info has_metadata"
+ expect(out).to include "* has_metadata (1.0)
+\tSummary: This is just a fake gem for testing
+\tHomepage: http://example.com
+\tDocumentation: https://www.example.info/gems/bestgemever/0.0.1
+\tSource Code: https://example.com/user/bestgemever
+\tWiki: https://example.com/user/bestgemever/wiki
+\tChangelog: https://example.com/user/bestgemever/CHANGELOG.md
+\tBug Tracker: https://example.com/user/bestgemever/issues
+\tMailing List: https://groups.example.com/bestgemever
+\tPath: #{default_bundle_path("gems", "has_metadata-1.0")}"
+ end
+ end
+
context "when gem does not have homepage" do
before do
- build_repo1 do
+ build_repo2 do
build_gem "rails", "2.3.2" do |s|
s.executables = "rails"
s.summary = "Just another test gem"
@@ -47,12 +123,102 @@ RSpec.describe "bundle info" do
expect(out).to_not include("Homepage:")
end
end
+ end
+
+ context "with a git repo in the Gemfile" do
+ before :each do
+ @git = build_git "foo", "1.0"
+ end
+
+ it "prints out git info" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}"
+ G
+ expect(the_bundle).to include_gems "foo 1.0"
+
+ bundle "info foo"
+ expect(out).to include("foo (1.0 #{@git.ref_for("master", 6)}")
+ end
- context "given --path option" do
- it "prints the path to the gem" do
- bundle "info rails"
- expect(out).to match(%r{.*\/rails\-2\.3\.2})
+ it "prints out branch names other than master" do
+ update_git "foo", :branch => "omg" do |s|
+ s.write "lib/foo.rb", "FOO = '1.0.omg'"
end
+ @revision = revision_for(lib_path("foo-1.0"))[0...6]
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "omg"
+ G
+ expect(the_bundle).to include_gems "foo 1.0.omg"
+
+ bundle "info foo"
+ expect(out).to include("foo (1.0 #{@git.ref_for("omg", 6)}")
+ end
+
+ it "doesn't print the branch when tied to a ref" do
+ sha = revision_for(lib_path("foo-1.0"))
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{sha}"
+ G
+
+ bundle "info foo"
+ expect(out).to include("foo (1.0 #{sha[0..6]})")
+ end
+
+ it "handles when a version is a '-' prerelease" do
+ @git = build_git("foo", "1.0.0-beta.1", :path => lib_path("foo"))
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", "1.0.0-beta.1", :git => "#{lib_path("foo")}"
+ G
+ expect(the_bundle).to include_gems "foo 1.0.0.pre.beta.1"
+
+ bundle "info foo"
+ expect(out).to include("foo (1.0.0.pre.beta.1")
+ end
+ end
+
+ context "with a valid regexp for gem name" do
+ it "presents alternatives", :readline do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "rack-obama"
+ G
+
+ bundle "info rac"
+ expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>)?\z/)
+ end
+ end
+
+ context "with an invalid regexp for gem name" do
+ it "does not find the gem" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ G
+
+ invalid_regexp = "[]"
+
+ bundle "info #{invalid_regexp}", :raise_on_error => false
+ expect(err).to include("Could not find gem '#{invalid_regexp}'.")
+ end
+ end
+
+ context "with without configured" do
+ it "does not find the gem, but gives a helpful error" do
+ bundle "config without test"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails", group: :test
+ G
+
+ bundle "info rails", :raise_on_error => false
+ expect(err).to include("Could not find gem 'rails', because it's in the group 'test', configured to be ignored.")
end
end
end
diff --git a/spec/bundler/commands/init_spec.rb b/spec/bundler/commands/init_spec.rb
index 6ab7e25cc3..683a453c7d 100644
--- a/spec/bundler/commands/init_spec.rb
+++ b/spec/bundler/commands/init_spec.rb
@@ -1,26 +1,57 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle init" do
it "generates a Gemfile" do
bundle :init
- expect(bundled_app("Gemfile")).to exist
+ expect(out).to include("Writing new Gemfile")
+ expect(bundled_app_gemfile).to be_file
end
context "when a Gemfile already exists" do
before do
- gemfile <<-G
+ create_file "Gemfile", <<-G
gem "rails"
G
end
it "does not change existing Gemfiles" do
- expect { bundle :init }.not_to change { File.read(bundled_app("Gemfile")) }
+ expect { bundle :init, :raise_on_error => false }.not_to change { File.read(bundled_app_gemfile) }
end
it "notifies the user that an existing Gemfile already exists" do
+ bundle :init, :raise_on_error => false
+ expect(err).to include("Gemfile already exists")
+ end
+ end
+
+ context "when a Gemfile exists in a parent directory" do
+ let(:subdir) { "child_dir" }
+
+ it "lets users generate a Gemfile in a child directory" do
bundle :init
- expect(out).to include("Gemfile already exists")
+
+ FileUtils.mkdir bundled_app(subdir)
+
+ bundle :init, :dir => bundled_app(subdir)
+
+ expect(out).to include("Writing new Gemfile")
+ expect(bundled_app("#{subdir}/Gemfile")).to be_file
+ end
+ end
+
+ context "when the dir is not writable by the current user" do
+ let(:subdir) { "child_dir" }
+
+ it "notifies the user that it can not write to it" do
+ FileUtils.mkdir bundled_app(subdir)
+ # chmod a-w it
+ mode = File.stat(bundled_app(subdir)).mode ^ 0o222
+ FileUtils.chmod mode, bundled_app(subdir)
+
+ bundle :init, :dir => bundled_app(subdir), :raise_on_error => false
+
+ expect(err).to include("directory is not writable")
+ expect(Dir[bundled_app("#{subdir}/*")]).to be_empty
end
end
@@ -40,7 +71,7 @@ RSpec.describe "bundle init" do
bundle :init, :gemspec => spec_file
- gemfile = bundled_app("Gemfile").read
+ gemfile = bundled_app_gemfile.read
expect(gemfile).to match(%r{source 'https://rubygems.org'})
expect(gemfile.scan(/gem "rack", "= 1.0.1"/).size).to eq(1)
expect(gemfile.scan(/gem "rspec", "= 1.2"/).size).to eq(1)
@@ -58,8 +89,82 @@ RSpec.describe "bundle init" do
S
end
+ bundle :init, :gemspec => spec_file, :raise_on_error => false
+ expect(err).to include("There was an error while loading `test.gemspec`")
+ end
+ end
+ end
+
+ context "when init_gems_rb setting is enabled" do
+ before { bundle "config set init_gems_rb true" }
+
+ it "generates a gems.rb" do
+ bundle :init
+ expect(out).to include("Writing new gems.rb")
+ expect(bundled_app("gems.rb")).to be_file
+ end
+
+ context "when gems.rb already exists" do
+ before do
+ create_file("gems.rb", <<-G)
+ gem "rails"
+ G
+ end
+
+ it "does not change existing Gemfiles" do
+ expect { bundle :init, :raise_on_error => false }.not_to change { File.read(bundled_app("gems.rb")) }
+ end
+
+ it "notifies the user that an existing gems.rb already exists" do
+ bundle :init, :raise_on_error => false
+ expect(err).to include("gems.rb already exists")
+ end
+ end
+
+ context "when a gems.rb file exists in a parent directory" do
+ let(:subdir) { "child_dir" }
+
+ it "lets users generate a Gemfile in a child directory" do
+ bundle :init
+
+ FileUtils.mkdir bundled_app(subdir)
+
+ bundle :init, :dir => bundled_app(subdir)
+
+ expect(out).to include("Writing new gems.rb")
+ expect(bundled_app("#{subdir}/gems.rb")).to be_file
+ end
+ end
+
+ context "given --gemspec option" do
+ let(:spec_file) { tmp.join("test.gemspec") }
+
+ before do
+ File.open(spec_file, "w") do |file|
+ file << <<-S
+ Gem::Specification.new do |s|
+ s.name = 'test'
+ s.add_dependency 'rack', '= 1.0.1'
+ s.add_development_dependency 'rspec', '1.2'
+ end
+ S
+ end
+ end
+
+ it "should generate from an existing gemspec" do
+ bundle :init, :gemspec => spec_file
+
+ gemfile = bundled_app("gems.rb").read
+ expect(gemfile).to match(%r{source 'https://rubygems.org'})
+ expect(gemfile.scan(/gem "rack", "= 1.0.1"/).size).to eq(1)
+ expect(gemfile.scan(/gem "rspec", "= 1.2"/).size).to eq(1)
+ expect(gemfile.scan(/group :development/).size).to eq(1)
+ end
+
+ it "prints message to user" do
bundle :init, :gemspec => spec_file
- expect(out).to include("There was an error while loading `test.gemspec`")
+
+ expect(out).to include("Writing new gems.rb")
end
end
end
diff --git a/spec/bundler/commands/inject_spec.rb b/spec/bundler/commands/inject_spec.rb
index dd0f1348cc..2d97bf6ff0 100644
--- a/spec/bundler/commands/inject_spec.rb
+++ b/spec/bundler/commands/inject_spec.rb
@@ -1,19 +1,18 @@
# frozen_string_literal: true
-require "spec_helper"
-RSpec.describe "bundle inject" do
+RSpec.describe "bundle inject", :bundler => "< 3" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
context "without a lockfile" do
it "locks with the injected gems" do
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
bundle "inject 'rack-obama' '> 0'"
- expect(bundled_app("Gemfile.lock").read).to match(/rack-obama/)
+ expect(bundled_app_lock.read).to match(/rack-obama/)
end
end
@@ -23,29 +22,29 @@ RSpec.describe "bundle inject" do
end
it "adds the injected gems to the Gemfile" do
- expect(bundled_app("Gemfile").read).not_to match(/rack-obama/)
+ expect(bundled_app_gemfile.read).not_to match(/rack-obama/)
bundle "inject 'rack-obama' '> 0'"
- expect(bundled_app("Gemfile").read).to match(/rack-obama/)
+ expect(bundled_app_gemfile.read).to match(/rack-obama/)
end
it "locks with the injected gems" do
- expect(bundled_app("Gemfile.lock").read).not_to match(/rack-obama/)
+ expect(bundled_app_lock.read).not_to match(/rack-obama/)
bundle "inject 'rack-obama' '> 0'"
- expect(bundled_app("Gemfile.lock").read).to match(/rack-obama/)
+ expect(bundled_app_lock.read).to match(/rack-obama/)
end
end
context "with injected gems already in the Gemfile" do
it "doesn't add existing gems" do
- bundle "inject 'rack' '> 0'"
- expect(out).to match(/cannot specify the same gem twice/i)
+ bundle "inject 'rack' '> 0'", :raise_on_error => false
+ expect(err).to match(/cannot specify the same gem twice/i)
end
end
context "incorrect arguments" do
it "fails when more than 2 arguments are passed" do
- bundle "inject gem_name 1 v"
- expect(out).to eq(<<-E.strip)
+ bundle "inject gem_name 1 v", :raise_on_error => false
+ expect(err).to eq(<<-E.strip)
ERROR: "bundle inject" was called with arguments ["gem_name", "1", "v"]
Usage: "bundle inject GEM VERSION"
E
@@ -54,9 +53,9 @@ Usage: "bundle inject GEM VERSION"
context "with source option" do
it "add gem with source option in gemfile" do
- bundle "inject 'foo' '>0' --source file://#{gem_repo1}"
- gemfile = bundled_app("Gemfile").read
- str = "gem \"foo\", \"> 0\", :source => \"file://#{gem_repo1}\""
+ bundle "inject 'foo' '>0' --source #{file_uri_for(gem_repo1)}"
+ gemfile = bundled_app_gemfile.read
+ str = "gem \"foo\", \"> 0\", :source => \"#{file_uri_for(gem_repo1)}\""
expect(gemfile).to include str
end
end
@@ -64,14 +63,14 @@ Usage: "bundle inject GEM VERSION"
context "with group option" do
it "add gem with group option in gemfile" do
bundle "inject 'rack-obama' '>0' --group=development"
- gemfile = bundled_app("Gemfile").read
- str = "gem \"rack-obama\", \"> 0\", :group => [:development]"
+ gemfile = bundled_app_gemfile.read
+ str = "gem \"rack-obama\", \"> 0\", :group => :development"
expect(gemfile).to include str
end
it "add gem with multiple groups in gemfile" do
bundle "inject 'rack-obama' '>0' --group=development,test"
- gemfile = bundled_app("Gemfile").read
+ gemfile = bundled_app_gemfile.read
str = "gem \"rack-obama\", \"> 0\", :groups => [:development, :test]"
expect(gemfile).to include str
end
@@ -80,35 +79,39 @@ Usage: "bundle inject GEM VERSION"
context "when frozen" do
before do
bundle "install"
- bundle "config --local frozen 1"
+ if Bundler.feature_flag.bundler_3_mode?
+ bundle "config set --local deployment true"
+ else
+ bundle "config set --local frozen true"
+ end
end
it "injects anyway" do
bundle "inject 'rack-obama' '> 0'"
- expect(bundled_app("Gemfile").read).to match(/rack-obama/)
+ expect(bundled_app_gemfile.read).to match(/rack-obama/)
end
it "locks with the injected gems" do
- expect(bundled_app("Gemfile.lock").read).not_to match(/rack-obama/)
+ expect(bundled_app_lock.read).not_to match(/rack-obama/)
bundle "inject 'rack-obama' '> 0'"
- expect(bundled_app("Gemfile.lock").read).to match(/rack-obama/)
+ expect(bundled_app_lock.read).to match(/rack-obama/)
end
it "restores frozen afterwards" do
bundle "inject 'rack-obama' '> 0'"
config = YAML.load(bundled_app(".bundle/config").read)
- expect(config["BUNDLE_FROZEN"]).to eq("1")
+ expect(config["BUNDLE_DEPLOYMENT"] || config["BUNDLE_FROZEN"]).to eq("true")
end
it "doesn't allow Gemfile changes" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack-obama"
G
- bundle "inject 'rack' '> 0'"
- expect(out).to match(/trying to install in deployment mode after changing/)
+ bundle "inject 'rack' '> 0'", :raise_on_error => false
+ expect(err).to match(/trying to install in deployment mode after changing/)
- expect(bundled_app("Gemfile.lock").read).not_to match(/rack-obama/)
+ expect(bundled_app_lock.read).not_to match(/rack-obama/)
end
end
end
diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb
index 2d67a39f1e..e00caa5315 100644
--- a/spec/bundler/commands/install_spec.rb
+++ b/spec/bundler/commands/install_spec.rb
@@ -1,39 +1,37 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with gem sources" do
describe "the simple case" do
it "prints output and returns if no dependencies are specified" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
G
bundle :install
- expect(out).to match(/no dependencies/)
+ expect(err).to match(/no dependencies/)
end
it "does not make a lockfile if the install fails" do
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
raise StandardError, "FAIL"
G
- expect(err).to lack_errors
- expect(out).to match(/StandardError, "FAIL"/)
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(err).to include('StandardError, "FAIL"')
+ expect(bundled_app_lock).not_to exist
end
it "creates a Gemfile.lock" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
- it "does not create ./.bundle by default" do
+ it "does not create ./.bundle by default", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -41,9 +39,19 @@ RSpec.describe "bundle install with gem sources" do
expect(bundled_app(".bundle")).not_to exist
end
+ it "does not create ./.bundle by default when installing to system gems" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle :install, :env => { "BUNDLE_PATH__SYSTEM" => "true" } # can't use install_gemfile since it sets retry
+ expect(bundled_app(".bundle")).not_to exist
+ end
+
it "creates lock files based on the Gemfile name" do
gemfile bundled_app("OmgFile"), <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0"
G
@@ -54,41 +62,56 @@ RSpec.describe "bundle install with gem sources" do
it "doesn't delete the lockfile if one already exists" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
- lockfile = File.read(bundled_app("Gemfile.lock"))
+ lockfile = File.read(bundled_app_lock)
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
raise StandardError, "FAIL"
G
- expect(File.read(bundled_app("Gemfile.lock"))).to eq(lockfile)
+ expect(File.read(bundled_app_lock)).to eq(lockfile)
end
it "does not touch the lockfile if nothing changed" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- expect { run "1" }.not_to change { File.mtime(bundled_app("Gemfile.lock")) }
+ expect { run "1" }.not_to change { File.mtime(bundled_app_lock) }
end
it "fetches gems" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+
+ expect(default_bundle_path("gems/rack-1.0.0")).to exist
+ expect(the_bundle).to include_gems("rack 1.0.0")
+ end
+
+ it "auto-heals missing gems" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
+ FileUtils.rm_rf(default_bundle_path("gems/rack-1.0.0"))
+
+ bundle "install --verbose"
+
+ expect(out).to include("Installing rack 1.0.0")
expect(default_bundle_path("gems/rack-1.0.0")).to exist
expect(the_bundle).to include_gems("rack 1.0.0")
end
it "fetches gems when multiple versions are specified" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack', "> 0.9", "< 1.0"
G
@@ -98,7 +121,7 @@ RSpec.describe "bundle install with gem sources" do
it "fetches gems when multiple versions are specified take 2" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack', "< 1.0", "> 0.9"
G
@@ -107,16 +130,16 @@ RSpec.describe "bundle install with gem sources" do
end
it "raises an appropriate error when gems are specified using symbols" do
- install_gemfile(<<-G)
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem :rack
G
- expect(exitstatus).to eq(4) if exitstatus
+ expect(exitstatus).to eq(4)
end
it "pulls in dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
@@ -125,7 +148,7 @@ RSpec.describe "bundle install with gem sources" do
it "does the right version" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
G
@@ -133,8 +156,14 @@ RSpec.describe "bundle install with gem sources" do
end
it "does not install the development dependency" do
+ build_repo2 do
+ build_gem "with_development_dependency" do |s|
+ s.add_development_dependency "activesupport", "= 2.3.5"
+ end
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "with_development_dependency"
G
@@ -144,7 +173,7 @@ RSpec.describe "bundle install with gem sources" do
it "resolves correctly" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activemerchant"
gem "rails"
G
@@ -154,12 +183,12 @@ RSpec.describe "bundle install with gem sources" do
it "activates gem correctly according to the resolved gems" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport", "2.3.5"
G
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activemerchant"
gem "rails"
G
@@ -168,7 +197,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "does not reinstall any gem that is already available locally" do
- system_gems "activesupport-2.3.2"
+ system_gems "activesupport-2.3.2", :path => default_bundle_path
build_repo2 do
build_gem "activesupport", "2.3.2" do |s|
@@ -177,7 +206,7 @@ RSpec.describe "bundle install with gem sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activerecord", "2.3.2"
G
@@ -185,9 +214,9 @@ RSpec.describe "bundle install with gem sources" do
end
it "works when the gemfile specifies gems that only exist in the system" do
- build_gem "foo", :to_system => true
+ build_gem "foo", :to_bundle => true
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "foo"
G
@@ -196,22 +225,36 @@ RSpec.describe "bundle install with gem sources" do
end
it "prioritizes local gems over remote gems" do
- build_gem "rack", "1.0.0", :to_system => true do |s|
+ build_gem "rack", "1.0.0", :to_bundle => true do |s|
s.add_dependency "activesupport", "2.3.5"
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.5"
end
+ it "loads env plugins" do
+ plugin_msg = "hello from an env plugin!"
+ create_file "plugins/rubygems_plugin.rb", "puts '#{plugin_msg}'"
+ rubylib = ENV["RUBYLIB"].to_s.split(File::PATH_SEPARATOR).unshift(bundled_app("plugins").to_s).join(File::PATH_SEPARATOR)
+ install_gemfile <<-G, :env => { "RUBYLIB" => rubylib }
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ expect(last_command.stdboth).to include(plugin_msg)
+ end
+
describe "with a gem that installs multiple platforms" do
it "installs gems for the local platform as first choice" do
+ skip "version is 1.0, not 1.0.0" if Gem.win_platform?
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
@@ -222,7 +265,7 @@ RSpec.describe "bundle install with gem sources" do
it "falls back on plain ruby" do
simulate_platform "foo-bar-baz"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
@@ -233,7 +276,7 @@ RSpec.describe "bundle install with gem sources" do
it "installs gems for java" do
simulate_platform "java"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
@@ -245,7 +288,7 @@ RSpec.describe "bundle install with gem sources" do
simulate_platform mswin
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
@@ -257,24 +300,25 @@ RSpec.describe "bundle install with gem sources" do
describe "doing bundle install foo" do
before do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
it "works" do
- bundle "install --path vendor"
+ bundle "config set --local path vendor"
+ bundle "install"
expect(the_bundle).to include_gems "rack 1.0"
end
- it "allows running bundle install --system without deleting foo" do
+ it "allows running bundle install --system without deleting foo", :bundler => "< 3" do
bundle "install --path vendor"
bundle "install --system"
FileUtils.rm_rf(bundled_app("vendor"))
expect(the_bundle).to include_gems "rack 1.0"
end
- it "allows running bundle install --system after deleting foo" do
+ it "allows running bundle install --system after deleting foo", :bundler => "< 3" do
bundle "install --path vendor"
FileUtils.rm_rf(bundled_app("vendor"))
bundle "install --system"
@@ -282,13 +326,16 @@ RSpec.describe "bundle install with gem sources" do
end
end
- it "finds gems in multiple sources" do
- build_repo2
- update_repo2
+ it "finds gems in multiple sources", :bundler => "< 3" do
+ build_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+ end
install_gemfile <<-G
- source "file://#{gem_repo1}"
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "1.2.3"
gem "rack", "1.2"
@@ -298,35 +345,108 @@ RSpec.describe "bundle install with gem sources" do
end
it "gives a useful error if no sources are set" do
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
gem "rack"
G
- bundle :install
- expect(out).to include("Your Gemfile has no gem server sources")
+ expect(err).to include("This Gemfile does not include an explicit global source. " \
+ "Not using an explicit global source may result in a different lockfile being generated depending on " \
+ "the gems you have installed locally before bundler is run. " \
+ "Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\".")
end
it "creates a Gemfile.lock on a blank Gemfile" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
+ expect(File.exist?(bundled_app_lock)).to eq(true)
+ end
+
+ it "throws a warning if a gem is added twice in Gemfile without version requirements" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ gem "rack"
G
- expect(File.exist?(bundled_app("Gemfile.lock"))).to eq(true)
+ expect(err).to include("Your Gemfile lists the gem rack (>= 0) more than once.")
+ expect(err).to include("Remove any duplicate entries and specify the gem only once.")
+ expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.")
+ end
+
+ it "throws a warning if a gem is added twice in Gemfile with same versions" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack", "1.0"
+ gem "rack", "1.0"
+ G
+
+ expect(err).to include("Your Gemfile lists the gem rack (= 1.0) more than once.")
+ expect(err).to include("Remove any duplicate entries and specify the gem only once.")
+ expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.")
+ end
+
+ it "does not throw a warning if a gem is added once in Gemfile and also inside a gemspec as a development dependency" do
+ build_lib "my-gem", :path => bundled_app do |s|
+ s.add_development_dependency "my-private-gem"
+ end
+
+ build_repo2 do
+ build_gem "my-private-gem"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gemspec
+
+ gem "my-private-gem", :group => :development
+ G
+
+ bundle :install
+
+ expect(err).to be_empty
+ expect(the_bundle).to include_gems("my-private-gem 1.0")
+ end
+
+ it "throws an error if a gem is added twice in Gemfile when version of one dependency is not specified" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ gem "rack", "1.0"
+ G
+
+ expect(err).to include("You cannot specify the same gem twice with different version requirements")
+ expect(err).to include("You specified: rack (>= 0) and rack (= 1.0).")
+ end
+
+ it "throws an error if a gem is added twice in Gemfile when different versions of both dependencies are specified" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack", "1.0"
+ gem "rack", "1.1"
+ G
+
+ expect(err).to include("You cannot specify the same gem twice with different version requirements")
+ expect(err).to include("You specified: rack (= 1.0) and rack (= 1.1).")
end
it "gracefully handles error when rubygems server is unavailable" do
- install_gemfile <<-G, :artifice => nil
- source "file://#{gem_repo1}"
- source "http://localhost:9384"
+ skip "networking issue" if Gem.win_platform?
- gem 'foo'
+ install_gemfile <<-G, :artifice => nil, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ source "http://0.0.0.0:9384" do
+ gem 'foo'
+ end
G
- bundle :install, :artifice => nil
- expect(out).to include("Could not fetch specs from http://localhost:9384/")
- expect(out).not_to include("file://")
+ expect(err).to include("Could not fetch specs from http://0.0.0.0:9384/")
+ expect(err).not_to include("file://")
end
- it "fails gracefully when downloading an invalid specification from the full index", :rubygems => "2.5" do
+ it "fails gracefully when downloading an invalid specification from the full index" do
build_repo2 do
build_gem "ajp-rails", "0.0.0", :gemspec => false, :skip_validation => true do |s|
bad_deps = [["ruby-ajp", ">= 0.2.0"], ["rails", ">= 0.14"]]
@@ -339,16 +459,15 @@ RSpec.describe "bundle install with gem sources" do
build_gem "ruby-ajp", "1.0.0"
end
- install_gemfile <<-G, :full_index => true
- source "file://#{gem_repo2}"
+ install_gemfile <<-G, :full_index => true, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gem "ajp-rails", "0.0.0"
G
- expect(out).not_to match(/Error Report/i)
- expect(err).not_to match(/Error Report/i)
- expect(out).to include("An error occurred while installing ajp-rails (0.0.0), and Bundler cannot continue.").
- and include("Make sure that `gem install ajp-rails -v '0.0.0'` succeeds before bundling.")
+ expect(last_command.stdboth).not_to match(/Error Report/i)
+ expect(err).to include("An error occurred while installing ajp-rails (0.0.0), and Bundler cannot continue.").
+ and include("Bundler::APIResponseInvalidDependenciesError")
end
it "doesn't blow up when the local .bundle/config is empty" do
@@ -356,11 +475,10 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.touch(bundled_app(".bundle/config"))
install_gemfile(<<-G)
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo'
G
- expect(exitstatus).to eq(0) if exitstatus
end
it "doesn't blow up when the global .bundle/config is empty" do
@@ -368,11 +486,10 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.touch("#{Bundler.rubygems.user_home}/.bundle/config")
install_gemfile(<<-G)
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo'
G
- expect(exitstatus).to eq(0) if exitstatus
end
end
@@ -381,11 +498,12 @@ RSpec.describe "bundle install with gem sources" do
context "and using an unsupported Ruby version" do
it "prints an error" do
- install_gemfile <<-G
- ::RUBY_VERSION = '1.8.7'
- ruby '~> 2.1'
+ install_gemfile <<-G, :raise_on_error => false
+ ::RUBY_VERSION = '2.0.1'
+ ruby '~> 2.2'
+ source "#{file_uri_for(gem_repo1)}"
G
- expect(out).to include("Your Ruby version is 1.8.7, but your Gemfile specified ~> 2.1")
+ expect(err).to include("Your Ruby version is 2.0.1, but your Gemfile specified ~> 2.2")
end
end
@@ -395,16 +513,18 @@ RSpec.describe "bundle install with gem sources" do
::RUBY_VERSION = '2.1.3'
::RUBY_PATCHLEVEL = 100
ruby '~> 2.1.0'
+ source "#{file_uri_for(gem_repo1)}"
G
end
it "writes current Ruby version to Gemfile.lock" do
- lockfile_should_be <<-L
+ expect(lockfile).to eq <<~L
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
@@ -421,14 +541,16 @@ RSpec.describe "bundle install with gem sources" do
::RUBY_VERSION = '2.2.3'
::RUBY_PATCHLEVEL = 100
ruby '~> 2.2.0'
+ source "#{file_uri_for(gem_repo1)}"
G
- lockfile_should_be <<-L
+ expect(lockfile).to eq <<~L
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
@@ -439,59 +561,229 @@ RSpec.describe "bundle install with gem sources" do
#{Bundler::VERSION}
L
end
+
+ it "does not crash when unlocking" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby '>= 2.1.0'
+ G
+
+ bundle "update"
+
+ expect(err).not_to include("Could not find gem 'Ruby")
+ end
end
end
describe "when Bundler root contains regex chars" do
- before do
+ it "doesn't blow up when using the `gem` DSL" do
root_dir = tmp("foo[]bar")
FileUtils.mkdir_p(root_dir)
- in_app_root_custom(root_dir)
- end
- it "doesn't blow up" do
build_lib "foo"
gemfile = <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "#{lib_path("foo-1.0")}"
G
- File.open("Gemfile", "w") do |file|
+ File.open("#{root_dir}/Gemfile", "w") do |file|
file.puts gemfile
end
- bundle :install
+ bundle :install, :dir => root_dir
+ end
+
+ it "doesn't blow up when using the `gemspec` DSL" do
+ root_dir = tmp("foo[]bar")
+
+ FileUtils.mkdir_p(root_dir)
- expect(exitstatus).to eq(0) if exitstatus
+ build_lib "foo", :path => root_dir
+ gemfile = <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gemspec
+ G
+ File.open("#{root_dir}/Gemfile", "w") do |file|
+ file.puts gemfile
+ end
+
+ bundle :install, :dir => root_dir
end
end
describe "when requesting a quiet install via --quiet" do
- it "should be quiet" do
+ it "should be quiet if there are no warnings" do
+ bundle "config set force_ruby_platform true"
+
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
bundle :install, :quiet => true
- expect(out).to include("Could not find gem 'rack'")
- expect(out).to_not include("Your Gemfile has no gem server sources")
+ expect(out).to be_empty
+ expect(err).to be_empty
+ end
+
+ it "should still display warnings and errors" do
+ bundle "config set force_ruby_platform true"
+
+ create_file("install_with_warning.rb", <<~RUBY)
+ require "#{lib_dir}/bundler"
+ require "#{lib_dir}/bundler/cli"
+ require "#{lib_dir}/bundler/cli/install"
+
+ module RunWithWarning
+ def run
+ super
+ rescue
+ Bundler.ui.warn "BOOOOO"
+ raise
+ end
+ end
+
+ Bundler::CLI::Install.prepend(RunWithWarning)
+ RUBY
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'non-existing-gem'
+ G
+
+ bundle :install, :quiet => true, :raise_on_error => false, :env => { "RUBYOPT" => "-r#{bundled_app("install_with_warning.rb")}" }
+ expect(out).to be_empty
+ expect(err).to include("Could not find gem 'non-existing-gem'")
+ expect(err).to include("BOOOOO")
+ end
+ end
+
+ describe "when bundle path does not have write access", :permissions do
+ let(:bundle_path) { bundled_app("vendor") }
+
+ before do
+ FileUtils.mkdir_p(bundle_path)
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+ end
+
+ it "should display a proper message to explain the problem" do
+ FileUtils.chmod(0o500, bundle_path)
+
+ bundle "config set --local path vendor"
+ bundle :install, :raise_on_error => false
+ expect(err).to include(bundle_path.to_s)
+ expect(err).to include("grant write permissions")
end
end
- describe "when bundle path does not have write access" do
+ describe "when bundle gems path does not have write access", :permissions do
+ let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") }
+
before do
- FileUtils.mkdir_p(bundled_app("vendor"))
+ FileUtils.mkdir_p(gems_path)
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
end
it "should display a proper message to explain the problem" do
- FileUtils.chmod(0o500, bundled_app("vendor"))
+ FileUtils.chmod("-x", gems_path)
+ bundle "config set --local path vendor"
+
+ begin
+ bundle :install, :raise_on_error => false
+ ensure
+ FileUtils.chmod("+x", gems_path)
+ end
- bundle :install, :path => "vendor"
- expect(out).to include(bundled_app("vendor").to_s)
- expect(out).to include("grant write permissions")
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+
+ expect(err).to include(
+ "There was an error while trying to create `#{gems_path.join("rack-1.0.0")}`. " \
+ "It is likely that you need to grant executable permissions for all parent directories and write permissions for `#{gems_path}`."
+ )
+ end
+ end
+
+ describe "when the path of a specific gem is not writable", :permissions do
+ let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") }
+ let(:foo_path) { gems_path.join("foo-1.0.0") }
+
+ before do
+ build_repo4 do
+ build_gem "foo", "1.0.0" do |s|
+ s.write "CHANGELOG.md", "foo"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'foo'
+ G
+ end
+
+ it "should display a proper message to explain the problem" do
+ bundle "config set --local path vendor"
+ bundle :install
+ expect(out).to include("Bundle complete!")
+ expect(err).to be_empty
+
+ FileUtils.chmod("-x", foo_path)
+
+ begin
+ bundle "install --redownload", :raise_on_error => false
+ ensure
+ FileUtils.chmod("+x", foo_path)
+ end
+
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+
+ expect(err).to include(
+ "There was an error while trying to delete `#{foo_path}`. " \
+ "It is likely that you need to grant executable permissions for all parent directories " \
+ "and write permissions for `#{gems_path}`, and the same thing for all subdirectories inside #{foo_path}."
+ )
+ end
+ end
+
+ describe "when bundle cache path does not have write access", :permissions do
+ let(:cache_path) { bundled_app("vendor/#{Bundler.ruby_scope}/cache") }
+
+ before do
+ FileUtils.mkdir_p(cache_path)
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+ end
+
+ it "should display a proper message to explain the problem" do
+ FileUtils.chmod(0o500, cache_path)
+
+ bundle "config set --local path vendor"
+ bundle :install, :raise_on_error => false
+ expect(err).to include(cache_path.to_s)
+ expect(err).to include("grant write permissions")
+ end
+ end
+
+ context "after installing with --standalone" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ bundle "config set --local path bundle"
+ bundle "install", :standalone => true
+ end
+
+ it "includes the standalone path" do
+ bundle "binstubs rack", :standalone => true
+ standalone_line = File.read(bundled_app("bin/rackup")).each_line.find {|line| line.include? "$:.unshift" }.strip
+ expect(standalone_line).to eq %($:.unshift File.expand_path "../../bundle", path.realpath)
end
end
@@ -499,15 +791,171 @@ RSpec.describe "bundle install with gem sources" do
before do
gemfile <<-G
source 'https://rubygems.org/'
- gem 'bundler'
+ gem "."
G
end
- it "should display a helpful messag explaining how to fix it" do
- bundle :install, :env => { "BUNDLE_RUBYGEMS__ORG" => "user:pass{word" }
- expect(exitstatus).to eq(17) if exitstatus
- expect(out).to eq("Please CGI escape your usernames and passwords before " \
+ it "should display a helpful message explaining how to fix it" do
+ bundle :install, :env => { "BUNDLE_RUBYGEMS__ORG" => "user:pass{word" }, :raise_on_error => false
+ expect(exitstatus).to eq(17)
+ expect(err).to eq("Please CGI escape your usernames and passwords before " \
"setting them for authentication.")
end
end
+
+ context "in a frozen bundle" do
+ before do
+ build_repo4 do
+ build_gem "libv8", "8.4.255.0" do |s|
+ s.platform = "x86_64-darwin-19"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "libv8"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ libv8 (8.4.255.0-x86_64-darwin-19)
+
+ PLATFORMS
+ x86_64-darwin-19
+
+ DEPENDENCIES
+ libv8
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "config set --local deployment true"
+ end
+
+ it "should fail loudly if the lockfile platforms don't include the current platform" do
+ simulate_platform(Gem::Platform.new("x86_64-linux")) { bundle "install", :raise_on_error => false }
+
+ expect(err).to eq(
+ "Your bundle only supports platforms [\"x86_64-darwin-19\"] but your local platform is x86_64-linux. " \
+ "Add the current platform to the lockfile with `bundle lock --add-platform x86_64-linux` and try again."
+ )
+ end
+ end
+
+ context "with missing platform specific gems in lockfile" do
+ before do
+ build_repo4 do
+ build_gem "racc", "1.5.2"
+
+ build_gem "nokogiri", "1.12.4" do |s|
+ s.platform = "x86_64-darwin"
+ s.add_runtime_dependency "racc", "~> 1.4"
+ end
+
+ build_gem "nokogiri", "1.12.4" do |s|
+ s.platform = "x86_64-linux"
+ s.add_runtime_dependency "racc", "~> 1.4"
+ end
+
+ build_gem "crass", "1.0.6"
+
+ build_gem "loofah", "2.12.0" do |s|
+ s.add_runtime_dependency "crass", "~> 1.0.2"
+ s.add_runtime_dependency "nokogiri", ">= 1.5.9"
+ end
+ end
+
+ gemfile <<-G
+ source "https://gem.repo4"
+
+ ruby "#{RUBY_VERSION}"
+
+ gem "loofah", "~> 2.12.0"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: https://gem.repo4/
+ specs:
+ crass (1.0.6)
+ loofah (2.12.0)
+ crass (~> 1.0.2)
+ nokogiri (>= 1.5.9)
+ nokogiri (1.12.4-x86_64-darwin)
+ racc (~> 1.4)
+ racc (1.5.2)
+
+ PLATFORMS
+ x86_64-darwin-20
+ x86_64-linux
+
+ DEPENDENCIES
+ loofah (~> 2.12.0)
+
+ RUBY VERSION
+ #{Bundler::RubyVersion.system}
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "automatically fixes the lockfile" do
+ bundle "config set --local path vendor/bundle"
+
+ simulate_platform "x86_64-linux" do
+ bundle "install", :artifice => "compact_index"
+ end
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo4/
+ specs:
+ crass (1.0.6)
+ loofah (2.12.0)
+ crass (~> 1.0.2)
+ nokogiri (>= 1.5.9)
+ nokogiri (1.12.4-x86_64-darwin)
+ racc (~> 1.4)
+ nokogiri (1.12.4-x86_64-linux)
+ racc (~> 1.4)
+ racc (1.5.2)
+
+ PLATFORMS
+ x86_64-darwin-20
+ x86_64-linux
+
+ DEPENDENCIES
+ loofah (~> 2.12.0)
+
+ RUBY VERSION
+ #{Bundler::RubyVersion.system}
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "with --local flag" do
+ before do
+ system_gems "rack-1.0.0", :path => default_bundle_path
+ end
+
+ it "respects installed gems without fetching any remote sources" do
+ install_gemfile <<-G, :local => true
+ source "#{file_uri_for(gem_repo1)}"
+
+ source "https://not-existing-source" do
+ gem "rack"
+ end
+ G
+
+ expect(last_command).to be_success
+ end
+ end
end
diff --git a/spec/bundler/commands/issue_spec.rb b/spec/bundler/commands/issue_spec.rb
index 056ef0f300..143f6333ce 100644
--- a/spec/bundler/commands/issue_spec.rb
+++ b/spec/bundler/commands/issue_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle issue" do
it "exits with a message" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
diff --git a/spec/bundler/commands/licenses_spec.rb b/spec/bundler/commands/licenses_spec.rb
index 0ee1a46945..a203984890 100644
--- a/spec/bundler/commands/licenses_spec.rb
+++ b/spec/bundler/commands/licenses_spec.rb
@@ -1,10 +1,15 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle licenses" do
before :each do
+ build_repo2 do
+ build_gem "with_license" do |s|
+ s.license = "MIT"
+ end
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails"
gem "with_license"
G
@@ -13,19 +18,19 @@ RSpec.describe "bundle licenses" do
it "prints license information for all gems in the bundle" do
bundle "licenses"
- expect(out).to include("bundler: Unknown")
+ expect(out).to include("bundler: MIT")
expect(out).to include("with_license: MIT")
end
it "performs an automatic bundle install" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails"
gem "with_license"
gem "foo"
G
- bundle "config auto_install 1"
+ bundle "config set auto_install 1"
bundle :licenses
expect(out).to include("Installing foo 1.0")
end
diff --git a/spec/bundler/commands/list_spec.rb b/spec/bundler/commands/list_spec.rb
new file mode 100644
index 0000000000..66930ded75
--- /dev/null
+++ b/spec/bundler/commands/list_spec.rb
@@ -0,0 +1,195 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle list" do
+ context "with name-only and paths option" do
+ it "raises an error" do
+ bundle "list --name-only --paths", :raise_on_error => false
+
+ expect(err).to eq "The `--name-only` and `--paths` options cannot be used together"
+ end
+ end
+
+ context "with without-group and only-group option" do
+ it "raises an error" do
+ bundle "list --without-group dev --only-group test", :raise_on_error => false
+
+ expect(err).to eq "The `--only-group` and `--without-group` options cannot be used together"
+ end
+ end
+
+ describe "with without-group option" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ gem "rspec", :group => [:test]
+ gem "rails", :group => [:production]
+ G
+ end
+
+ context "when group is present" do
+ it "prints the gems not in the specified group" do
+ bundle "list --without-group test"
+
+ expect(out).to include(" * rack (1.0.0)")
+ expect(out).to include(" * rails (2.3.2)")
+ expect(out).not_to include(" * rspec (1.2.7)")
+ end
+ end
+
+ context "when group is not found" do
+ it "raises an error" do
+ bundle "list --without-group random", :raise_on_error => false
+
+ expect(err).to eq "`random` group could not be found."
+ end
+ end
+
+ context "when multiple groups" do
+ it "prints the gems not in the specified groups" do
+ bundle "list --without-group test production"
+
+ expect(out).to include(" * rack (1.0.0)")
+ expect(out).not_to include(" * rails (2.3.2)")
+ expect(out).not_to include(" * rspec (1.2.7)")
+ end
+ end
+ end
+
+ describe "with only-group option" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ gem "rspec", :group => [:test]
+ gem "rails", :group => [:production]
+ G
+ end
+
+ context "when group is present" do
+ it "prints the gems in the specified group" do
+ bundle "list --only-group default"
+
+ expect(out).to include(" * rack (1.0.0)")
+ expect(out).not_to include(" * rspec (1.2.7)")
+ end
+ end
+
+ context "when group is not found" do
+ it "raises an error" do
+ bundle "list --only-group random", :raise_on_error => false
+
+ expect(err).to eq "`random` group could not be found."
+ end
+ end
+
+ context "when multiple groups" do
+ it "prints the gems in the specified groups" do
+ bundle "list --only-group default production"
+
+ expect(out).to include(" * rack (1.0.0)")
+ expect(out).to include(" * rails (2.3.2)")
+ expect(out).not_to include(" * rspec (1.2.7)")
+ end
+ end
+ end
+
+ context "with name-only option" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ gem "rspec", :group => [:test]
+ G
+ end
+
+ it "prints only the name of the gems in the bundle" do
+ bundle "list --name-only"
+
+ expect(out).to include("rack")
+ expect(out).to include("rspec")
+ end
+ end
+
+ context "with paths option" do
+ before do
+ build_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
+ build_gem "bar"
+ end
+
+ build_git "git_test", "1.0.0", :path => lib_path("git_test")
+
+ build_lib("gemspec_test", :path => tmp.join("gemspec_test")) do |s|
+ s.add_dependency "bar", "=1.0.0"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+ gem "rails"
+ gem "git_test", :git => "#{lib_path("git_test")}"
+ gemspec :path => "#{tmp.join("gemspec_test")}"
+ G
+ end
+
+ it "prints the path of each gem in the bundle" do
+ bundle "list --paths"
+ expect(out).to match(%r{.*\/rails\-2\.3\.2})
+ expect(out).to match(%r{.*\/rack\-1\.2})
+ expect(out).to match(%r{.*\/git_test\-\w})
+ expect(out).to match(%r{.*\/gemspec_test})
+ end
+ end
+
+ context "when no gems are in the gemfile" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+
+ it "prints message saying no gems are in the bundle" do
+ bundle "list"
+ expect(out).to include("No gems in the Gemfile")
+ end
+ end
+
+ context "without options" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ gem "rspec", :group => [:test]
+ G
+ end
+
+ it "lists gems installed in the bundle" do
+ bundle "list"
+ expect(out).to include(" * rack (1.0.0)")
+ end
+ end
+
+ context "when using the ls alias" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ gem "rspec", :group => [:test]
+ G
+ end
+
+ it "runs the list command" do
+ bundle "ls"
+ expect(out).to include("Gems included by the bundle")
+ end
+ end
+end
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index 5c15b6a7f6..22709f4528 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle lock" do
def strip_lockfile(lockfile)
@@ -14,15 +13,15 @@ RSpec.describe "bundle lock" do
before :each do
gemfile <<-G
- source "file://#{repo}"
+ source "#{file_uri_for(repo)}"
gem "rails"
- gem "with_license"
+ gem "weakling"
gem "foo"
G
- @lockfile = strip_lockfile <<-L
+ @lockfile = strip_lockfile(<<-L)
GEM
- remote: file:#{repo}/
+ remote: #{file_uri_for(repo)}/
specs:
actionmailer (2.3.2)
activesupport (= 2.3.2)
@@ -39,17 +38,17 @@ RSpec.describe "bundle lock" do
actionpack (= 2.3.2)
activerecord (= 2.3.2)
activeresource (= 2.3.2)
- rake (= 10.0.2)
- rake (10.0.2)
- with_license (1.0)
+ rake (= 13.0.1)
+ rake (13.0.1)
+ weakling (0.0.3)
PLATFORMS
- #{local}
+ #{lockfile_platforms}
DEPENDENCIES
foo
rails
- with_license
+ weakling
BUNDLED WITH
#{Bundler::VERSION}
@@ -59,7 +58,7 @@ RSpec.describe "bundle lock" do
it "prints a lockfile when there is no existing lockfile with --print" do
bundle "lock --print"
- expect(out).to include(@lockfile)
+ expect(out).to eq(@lockfile)
end
it "prints a lockfile when there is an existing lockfile with --print" do
@@ -79,27 +78,62 @@ RSpec.describe "bundle lock" do
it "writes a lockfile when there is an outdated lockfile using --update" do
lockfile @lockfile.gsub("2.3.2", "2.3.1")
- bundle! "lock --update"
+ bundle "lock --update"
expect(read_lockfile).to eq(@lockfile)
end
it "does not fetch remote specs when using the --local option" do
- bundle "lock --update --local"
+ bundle "lock --update --local", :raise_on_error => false
+
+ expect(err).to match(/locally installed gems/)
+ end
+
+ it "works with --gemfile flag" do
+ create_file "CustomGemfile", <<-G
+ source "#{file_uri_for(repo)}"
+ gem "foo"
+ G
+ lockfile = strip_lockfile(<<-L)
+ GEM
+ remote: #{file_uri_for(repo)}/
+ specs:
+ foo (1.0)
- expect(out).to include("sources listed in your Gemfile")
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ bundle "lock --gemfile CustomGemfile"
+
+ expect(out).to match(/Writing lockfile to.+CustomGemfile\.lock/)
+ expect(read_lockfile("CustomGemfile.lock")).to eq(lockfile)
+ expect { read_lockfile }.to raise_error(Errno::ENOENT)
end
it "writes to a custom location using --lockfile" do
bundle "lock --lockfile=lock"
expect(out).to match(/Writing lockfile to.+lock/)
- expect(read_lockfile "lock").to eq(@lockfile)
+ expect(read_lockfile("lock")).to eq(@lockfile)
expect { read_lockfile }.to raise_error(Errno::ENOENT)
end
+ it "writes to custom location using --lockfile when a default lockfile is present" do
+ bundle "install"
+ bundle "lock --lockfile=lock"
+
+ expect(out).to match(/Writing lockfile to.+lock/)
+ expect(read_lockfile("lock")).to eq(@lockfile)
+ end
+
it "update specific gems using --update" do
- lockfile @lockfile.gsub("2.3.2", "2.3.1").gsub("10.0.2", "10.0.1")
+ lockfile @lockfile.gsub("2.3.2", "2.3.1").gsub("13.0.1", "10.0.1")
bundle "lock --update rails rake"
@@ -109,33 +143,46 @@ RSpec.describe "bundle lock" do
it "errors when updating a missing specific gems using --update" do
lockfile @lockfile
- bundle "lock --update blahblah"
- expect(out).to eq("Could not find gem 'blahblah'.")
+ bundle "lock --update blahblah", :raise_on_error => false
+ expect(err).to eq("Could not find gem 'blahblah'.")
expect(read_lockfile).to eq(@lockfile)
end
+ it "can lock without downloading gems" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "thin"
+ gem "rack_middleware", :group => "test"
+ G
+ bundle "config set without test"
+ bundle "config set path .bundle"
+ bundle "lock"
+ expect(bundled_app(".bundle")).not_to exist
+ end
+
# see update_spec for more coverage on same options. logic is shared so it's not necessary
# to repeat coverage here.
context "conservative updates" do
before do
build_repo4 do
- build_gem "foo", %w(1.4.3 1.4.4) do |s|
+ build_gem "foo", %w[1.4.3 1.4.4] do |s|
s.add_dependency "bar", "~> 2.0"
end
- build_gem "foo", %w(1.4.5 1.5.0) do |s|
+ build_gem "foo", %w[1.4.5 1.5.0] do |s|
s.add_dependency "bar", "~> 2.1"
end
- build_gem "foo", %w(1.5.1) do |s|
+ build_gem "foo", %w[1.5.1] do |s|
s.add_dependency "bar", "~> 3.0"
end
- build_gem "bar", %w(2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0)
- build_gem "qux", %w(1.0.0 1.0.1 1.1.0 2.0.0)
+ build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
+ build_gem "qux", %w[1.0.0 1.0.1 1.1.0 2.0.0]
end
# establish a lockfile set to 1.4.3
install_gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'foo', '1.4.3'
gem 'bar', '2.0.3'
gem 'qux', '1.0.0'
@@ -144,61 +191,91 @@ RSpec.describe "bundle lock" do
# remove 1.4.3 requirement and bar altogether
# to setup update specs below
gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'foo'
gem 'qux'
G
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
it "single gem updates dependent gem to minor" do
bundle "lock --update foo --patch"
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w(foo-1.4.5 bar-2.1.1 qux-1.0.0).sort)
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-1.4.5 bar-2.1.1 qux-1.0.0].sort)
end
it "minor preferred with strict" do
bundle "lock --update --minor --strict"
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w(foo-1.5.0 bar-2.1.1 qux-1.1.0).sort)
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-1.5.0 bar-2.1.1 qux-1.1.0].sort)
end
end
it "supports adding new platforms" do
- bundle! "lock --add-platform java x86-mingw32"
+ bundle "lock --add-platform java x86-mingw32"
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to eq([java, local, mingw])
+ expect(lockfile.platforms).to match_array(local_platforms.unshift(java, mingw).uniq)
+ end
+
+ it "supports adding new platforms with force_ruby_platform = true" do
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ platform_specific (1.0)
+ platform_specific (1.0-x86-linux)
+
+ PLATFORMS
+ ruby
+ x86-linux
+
+ DEPENDENCIES
+ platform_specific
+ L
+
+ bundle "config set force_ruby_platform true"
+ bundle "lock --add-platform java x86-mingw32"
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ lockfile = Bundler::LockfileParser.new(read_lockfile)
+ expect(lockfile.platforms).to contain_exactly(rb, linux, java, mingw)
end
it "supports adding the `ruby` platform" do
- bundle! "lock --add-platform ruby"
+ bundle "lock --add-platform ruby"
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to eq([local, "ruby"].uniq)
+ expect(lockfile.platforms).to match_array(local_platforms.unshift("ruby").uniq)
end
it "warns when adding an unknown platform" do
bundle "lock --add-platform foobarbaz"
- expect(out).to include("The platform `foobarbaz` is unknown to RubyGems and adding it will likely lead to resolution errors")
+ expect(err).to include("The platform `foobarbaz` is unknown to RubyGems and adding it will likely lead to resolution errors")
end
it "allows removing platforms" do
- bundle! "lock --add-platform java x86-mingw32"
+ bundle "lock --add-platform java x86-mingw32"
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to eq([java, local, mingw])
+ expect(lockfile.platforms).to match_array(local_platforms.unshift(java, mingw).uniq)
- bundle! "lock --remove-platform java"
+ bundle "lock --remove-platform java"
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to eq([local, mingw])
+ expect(lockfile.platforms).to match_array(local_platforms.unshift(mingw).uniq)
end
it "errors when removing all platforms" do
- bundle "lock --remove-platform #{local}"
- expect(out).to include("Removing all platforms from the bundle is not allowed")
+ bundle "lock --remove-platform #{local_platforms.join(" ")}", :raise_on_error => false
+ expect(err).to include("Removing all platforms from the bundle is not allowed")
end
- # from https://github.com/bundler/bundler/issues/4896
+ # from https://github.com/rubygems/bundler/issues/4896
it "properly adds platforms when platform requirements come from different dependencies" do
build_repo4 do
build_gem "ffi", "1.9.14"
@@ -221,7 +298,7 @@ RSpec.describe "bundle lock" do
# we need all these versions to get the sorting the same as it would be
# pulling from rubygems.org
- %w(0.8.3 0.8.2 0.8.1 0.8.0).each do |v|
+ %w[0.8.3 0.8.2 0.8.1 0.8.0].each do |v|
build_gem "win32-process", v do |s|
s.add_dependency "ffi", ">= 1.0.0"
end
@@ -229,17 +306,17 @@ RSpec.describe "bundle lock" do
end
gemfile <<-G
- source "file:#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem "mixlib-shellout"
gem "gssapi"
G
- simulate_platform(mingw) { bundle! :lock }
+ simulate_platform(mingw) { bundle :lock }
- expect(the_bundle.lockfile).to read_as(strip_whitespace(<<-G))
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo4}/
+ remote: #{file_uri_for(gem_repo4)}/
specs:
ffi (1.9.14-x86-mingw32)
gssapi (1.2.0)
@@ -260,11 +337,11 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION}
G
- simulate_platform(rb) { bundle! :lock }
+ simulate_platform(rb) { bundle :lock }
- expect(the_bundle.lockfile).to read_as(strip_whitespace(<<-G))
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo4}/
+ remote: #{file_uri_for(gem_repo4)}/
specs:
ffi (1.9.14)
ffi (1.9.14-x86-mingw32)
@@ -289,6 +366,176 @@ RSpec.describe "bundle lock" do
G
end
+ it "doesn't crash when an update candidate doesn't have any matching platform" do
+ build_repo4 do
+ build_gem "libv8", "8.4.255.0"
+ build_gem "libv8", "8.4.255.0" do |s|
+ s.platform = "x86_64-darwin-19"
+ end
+
+ build_gem "libv8", "15.0.71.48.1beta2" do |s|
+ s.platform = "x86_64-linux"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "libv8"
+ G
+
+ lockfile <<-G
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ libv8 (8.4.255.0)
+ libv8 (8.4.255.0-x86_64-darwin-19)
+
+ PLATFORMS
+ ruby
+ x86_64-darwin-19
+
+ DEPENDENCIES
+ libv8
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+
+ simulate_platform(Gem::Platform.new("x86_64-darwin-19")) { bundle "lock --update" }
+
+ expect(out).to match(/Writing lockfile to.+Gemfile\.lock/)
+ end
+
+ it "adds all more specific candidates when they all have the same dependencies" do
+ build_repo4 do
+ build_gem "libv8", "8.4.255.0" do |s|
+ s.platform = "x86_64-darwin-19"
+ end
+
+ build_gem "libv8", "8.4.255.0" do |s|
+ s.platform = "x86_64-darwin-20"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "libv8"
+ G
+
+ simulate_platform(Gem::Platform.new("x86_64-darwin")) { bundle "lock" }
+
+ expect(lockfile).to eq <<~G
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ libv8 (8.4.255.0-x86_64-darwin-19)
+ libv8 (8.4.255.0-x86_64-darwin-20)
+
+ PLATFORMS
+ x86_64-darwin
+
+ DEPENDENCIES
+ libv8
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
+ it "respects the previous lockfile if it had a matching less specific platform already locked, and installs the best variant for each platform" do
+ build_repo4 do
+ build_gem "libv8", "8.4.255.0" do |s|
+ s.platform = "x86_64-darwin-19"
+ end
+
+ build_gem "libv8", "8.4.255.0" do |s|
+ s.platform = "x86_64-darwin-20"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "libv8"
+ G
+
+ lockfile <<-G
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ libv8 (8.4.255.0-x86_64-darwin-19)
+ libv8 (8.4.255.0-x86_64-darwin-20)
+
+ PLATFORMS
+ x86_64-darwin
+
+ DEPENDENCIES
+ libv8
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+
+ previous_lockfile = lockfile
+
+ %w[x86_64-darwin-19 x86_64-darwin-20].each do |platform|
+ simulate_platform(Gem::Platform.new(platform)) do
+ bundle "lock"
+ expect(lockfile).to eq(previous_lockfile)
+
+ bundle "install"
+ expect(the_bundle).to include_gem("libv8 8.4.255.0 #{platform}")
+ end
+ end
+ end
+
+ it "does not conflict on ruby requirements when adding new platforms" do
+ next_minor = Gem.ruby_version.segments[0..1].map.with_index {|s, i| i == 1 ? s + 1 : s }.join(".")
+
+ build_repo4 do
+ build_gem "raygun-apm", "1.0.78" do |s|
+ s.platform = "x86_64-linux"
+ s.required_ruby_version = "< #{next_minor}.dev"
+ end
+
+ build_gem "raygun-apm", "1.0.78" do |s|
+ s.platform = "universal-darwin"
+ s.required_ruby_version = "< #{next_minor}.dev"
+ end
+
+ build_gem "raygun-apm", "1.0.78" do |s|
+ s.platform = "x64-mingw32"
+ s.required_ruby_version = "< #{next_minor}.dev"
+ end
+ end
+
+ gemfile <<-G
+ source "https://localgemserver.test"
+
+ gem "raygun-apm"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: https://localgemserver.test/
+ specs:
+ raygun-apm (1.0.78-universal-darwin)
+
+ PLATFORMS
+ x86_64-darwin-19
+
+ DEPENDENCIES
+ raygun-apm
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "lock --add-platform x86_64-linux", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ end
+
context "when an update is available" do
let(:repo) { gem_repo2 }
@@ -300,14 +547,14 @@ RSpec.describe "bundle lock" do
end
it "does not implicitly update" do
- bundle! "lock"
+ bundle "lock"
expect(read_lockfile).to eq(@lockfile)
end
it "accounts for changes in the gemfile" do
gemfile gemfile.gsub('"foo"', '"foo", "2.0"')
- bundle! "lock"
+ bundle "lock"
expect(read_lockfile).to eq(@lockfile.sub("foo (1.0)", "foo (2.0)").sub(/foo$/, "foo (= 2.0)"))
end
diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb
index e9c19005eb..db5228ebc2 100644
--- a/spec/bundler/commands/newgem_spec.rb
+++ b/spec/bundler/commands/newgem_spec.rb
@@ -1,180 +1,402 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle gem" do
- def reset!
- super
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false"
+ def gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/#{gem_name}.gemspec")).to exist
+ expect(bundled_app("#{gem_name}/README.md")).to exist
+ expect(bundled_app("#{gem_name}/Gemfile")).to exist
+ expect(bundled_app("#{gem_name}/Rakefile")).to exist
+ expect(bundled_app("#{gem_name}/lib/#{require_path}.rb")).to exist
+ expect(bundled_app("#{gem_name}/lib/#{require_path}/version.rb")).to exist
end
- def remove_push_guard(gem_name)
- # Remove exception that prevents public pushes on older RubyGems versions
- if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0")
- path = "#{gem_name}/#{gem_name}.gemspec"
- content = File.read(path).sub(/raise "RubyGems 2\.0 or newer.*/, "")
- File.open(path, "w") {|f| f.write(content) }
- end
+ def bundle_exec_rubocop
+ prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
+ bundle "config set path #{rubocop_gems}", :dir => bundled_app(gem_name)
+ bundle "exec rubocop --debug --config .rubocop.yml", :dir => bundled_app(gem_name)
end
- def execute_bundle_gem(gem_name, flag = "", to_remove_push_guard = true)
- bundle! "gem #{gem_name} #{flag}"
- remove_push_guard(gem_name) if to_remove_push_guard
- # reset gemspec cache for each test because of commit 3d4163a
- Bundler.clear_gemspec_cache
+ def bundle_exec_standardrb
+ prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
+ bundle "config set path #{standard_gems}", :dir => bundled_app(gem_name)
+ bundle "exec standardrb --debug", :dir => bundled_app(gem_name)
end
- def gem_skeleton_assertions(gem_name)
- expect(bundled_app("#{gem_name}/#{gem_name}.gemspec")).to exist
- expect(bundled_app("#{gem_name}/README.md")).to exist
- expect(bundled_app("#{gem_name}/Gemfile")).to exist
- expect(bundled_app("#{gem_name}/Rakefile")).to exist
- expect(bundled_app("#{gem_name}/lib/test/gem.rb")).to exist
- expect(bundled_app("#{gem_name}/lib/test/gem/version.rb")).to exist
- end
+ let(:generated_gemspec) { Bundler.load_gemspec_uncached(bundled_app(gem_name).join("#{gem_name}.gemspec")) }
+
+ let(:gem_name) { "mygem" }
+
+ let(:require_path) { "mygem" }
before do
- git_config_content = <<-EOF
- [user]
- name = "Bundler User"
- email = user@example.com
- [github]
- user = bundleuser
- EOF
- @git_config_location = ENV["GIT_CONFIG"]
- path = "#{File.expand_path(tmp, File.dirname(__FILE__))}/test_git_config.txt"
- File.open(path, "w") {|f| f.write(git_config_content) }
- ENV["GIT_CONFIG"] = path
- end
-
- after do
- FileUtils.rm(ENV["GIT_CONFIG"]) if File.exist?(ENV["GIT_CONFIG"])
- ENV["GIT_CONFIG"] = @git_config_location
- end
-
- shared_examples_for "git config is present" do
- context "git config user.{name,email} present" do
- it "sets gemspec author to git user.name if available" do
- expect(generated_gem.gemspec.authors.first).to eq("Bundler User")
- end
+ sys_exec("git config --global user.name 'Bundler User'")
+ sys_exec("git config --global user.email user@example.com")
+ sys_exec("git config --global github.user bundleuser")
+ end
- it "sets gemspec email to git user.email if available" do
- expect(generated_gem.gemspec.email.first).to eq("user@example.com")
- end
+ describe "git repo initialization" do
+ it "generates a gem skeleton with a .git folder", :readline do
+ bundle "gem #{gem_name}"
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/.git")).to exist
+ end
+
+ it "generates a gem skeleton with a .git folder when passing --git", :readline do
+ bundle "gem #{gem_name} --git"
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/.git")).to exist
end
- end
- shared_examples_for "git config is absent" do
- it "sets gemspec author to default message if git user.name is not set or empty" do
- expect(generated_gem.gemspec.authors.first).to eq("TODO: Write your name")
+ it "generates a gem skeleton without a .git folder when passing --no-git", :readline do
+ bundle "gem #{gem_name} --no-git"
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/.git")).not_to exist
end
- it "sets gemspec email to default message if git user.email is not set or empty" do
- expect(generated_gem.gemspec.email.first).to eq("TODO: Write your email address")
+ context "on a path with spaces" do
+ before do
+ Dir.mkdir(bundled_app("path with spaces"))
+ end
+
+ it "properly initializes git repo", :readline do
+ bundle "gem #{gem_name}", :dir => bundled_app("path with spaces")
+ expect(bundled_app("path with spaces/#{gem_name}/.git")).to exist
+ end
end
end
shared_examples_for "--mit flag" do
before do
- execute_bundle_gem(gem_name, "--mit")
+ bundle "gem #{gem_name} --mit"
end
it "generates a gem skeleton with MIT license" do
- gem_skeleton_assertions(gem_name)
- expect(bundled_app("test-gem/LICENSE.txt")).to exist
- skel = Bundler::GemHelper.new(bundled_app(gem_name).to_s)
- expect(skel.gemspec.license).to eq("MIT")
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/LICENSE.txt")).to exist
+ expect(generated_gemspec.license).to eq("MIT")
end
end
shared_examples_for "--no-mit flag" do
before do
- execute_bundle_gem(gem_name, "--no-mit")
+ bundle "gem #{gem_name} --no-mit"
end
it "generates a gem skeleton without MIT license" do
- gem_skeleton_assertions(gem_name)
- expect(bundled_app("test-gem/LICENSE.txt")).to_not exist
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/LICENSE.txt")).to_not exist
end
end
shared_examples_for "--coc flag" do
- before do
- execute_bundle_gem(gem_name, "--coc", false)
- end
it "generates a gem skeleton with MIT license" do
- gem_skeleton_assertions(gem_name)
- expect(bundled_app("test-gem/CODE_OF_CONDUCT.md")).to exist
+ bundle "gem #{gem_name} --coc"
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/CODE_OF_CONDUCT.md")).to exist
end
- describe "README additions" do
- it "generates the README with a section for the Code of Conduct" do
- expect(bundled_app("test-gem/README.md").read).to include("## Code of Conduct")
- expect(bundled_app("test-gem/README.md").read).to include("https://github.com/bundleuser/#{gem_name}/blob/master/CODE_OF_CONDUCT.md")
- end
+ it "generates the README with a section for the Code of Conduct" do
+ bundle "gem #{gem_name} --coc"
+ expect(bundled_app("#{gem_name}/README.md").read).to include("## Code of Conduct")
+ expect(bundled_app("#{gem_name}/README.md").read).to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
+ end
+
+ it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", :git => ">= 2.28.0" do
+ sys_exec("git config --global init.defaultBranch main")
+ bundle "gem #{gem_name} --coc"
+
+ expect(bundled_app("#{gem_name}/README.md").read).to include("## Code of Conduct")
+ expect(bundled_app("#{gem_name}/README.md").read).to include("https://github.com/bundleuser/#{gem_name}/blob/main/CODE_OF_CONDUCT.md")
end
end
shared_examples_for "--no-coc flag" do
before do
- execute_bundle_gem(gem_name, "--no-coc", false)
+ bundle "gem #{gem_name} --no-coc"
end
it "generates a gem skeleton without Code of Conduct" do
- gem_skeleton_assertions(gem_name)
- expect(bundled_app("test-gem/CODE_OF_CONDUCT.md")).to_not exist
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/CODE_OF_CONDUCT.md")).to_not exist
end
- describe "README additions" do
- it "generates the README without a section for the Code of Conduct" do
- expect(bundled_app("test-gem/README.md").read).not_to include("## Code of Conduct")
- expect(bundled_app("test-gem/README.md").read).not_to include("https://github.com/bundleuser/#{gem_name}/blob/master/CODE_OF_CONDUCT.md")
+ it "generates the README without a section for the Code of Conduct" do
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("## Code of Conduct")
+ expect(bundled_app("#{gem_name}/README.md").read).not_to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
+ end
+ end
+
+ shared_examples_for "--changelog flag" do
+ before do
+ bundle "gem #{gem_name} --changelog"
+ end
+ it "generates a gem skeleton with a CHANGELOG", :readline do
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/CHANGELOG.md")).to exist
+ end
+ end
+
+ shared_examples_for "--no-changelog flag" do
+ before do
+ bundle "gem #{gem_name} --no-changelog"
+ end
+ it "generates a gem skeleton without a CHANGELOG", :readline do
+ gem_skeleton_assertions
+ expect(bundled_app("#{gem_name}/CHANGELOG.md")).to_not exist
+ end
+ end
+
+ shared_examples_for "--rubocop flag" do
+ context "is deprecated", :bundler => "< 3" do
+ before do
+ bundle "gem #{gem_name} --rubocop"
+ end
+
+ it "generates a gem skeleton with rubocop" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(
+ include("# frozen_string_literal: true").
+ and(include('require "rubocop/rake_task"').
+ and(include("RuboCop::RakeTask.new").
+ and(match(/default:.+:rubocop/))))
+ )
+ end
+
+ it "includes rubocop in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
+ expect(rubocop_dep).not_to be_nil
+ end
+
+ it "generates a default .rubocop.yml" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
end
end
end
- context "README.md" do
- let(:gem_name) { "test_gem" }
- let(:generated_gem) { Bundler::GemHelper.new(bundled_app(gem_name).to_s) }
+ shared_examples_for "--no-rubocop flag" do
+ context "is deprecated", :bundler => "< 3" do
+ define_negated_matcher :exclude, :include
+
+ before do
+ bundle "gem #{gem_name} --no-rubocop"
+ end
+ it "generates a gem skeleton without rubocop" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(exclude("rubocop"))
+ expect(bundled_app("test-gem/#{gem_name}.gemspec")).to read_as(exclude("rubocop"))
+ end
+
+ it "does not include rubocop in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
+ expect(rubocop_dep).to be_nil
+ end
+
+ it "doesn't generate a default .rubocop.yml" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ end
+ end
+ end
+
+ shared_examples_for "--linter=rubocop flag" do
+ before do
+ bundle "gem #{gem_name} --linter=rubocop"
+ end
+
+ it "generates a gem skeleton with rubocop" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(
+ include("# frozen_string_literal: true").
+ and(include('require "rubocop/rake_task"').
+ and(include("RuboCop::RakeTask.new").
+ and(match(/default:.+:rubocop/))))
+ )
+ end
+
+ it "includes rubocop in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
+ expect(rubocop_dep).not_to be_nil
+ end
+
+ it "generates a default .rubocop.yml" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ end
+ end
+
+ shared_examples_for "--linter=standard flag" do
+ before do
+ bundle "gem #{gem_name} --linter=standard"
+ end
+
+ it "generates a gem skeleton with standard" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(
+ include('require "standard/rake"').
+ and(match(/default:.+:standard/))
+ )
+ end
+
+ it "includes standard in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ standard_dep = builder.dependencies.find {|d| d.name == "standard" }
+ expect(standard_dep).not_to be_nil
+ end
+
+ it "generates a default .standard.yml" do
+ expect(bundled_app("#{gem_name}/.standard.yml")).to exist
+ end
+ end
+
+ shared_examples_for "--linter=none flag" do
+ define_negated_matcher :exclude, :include
+
+ before do
+ bundle "gem #{gem_name} --linter=none"
+ end
+
+ it "generates a gem skeleton without rubocop" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(exclude("rubocop"))
+ expect(bundled_app("test-gem/#{gem_name}.gemspec")).to read_as(exclude("rubocop"))
+ end
+
+ it "does not include rubocop in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
+ expect(rubocop_dep).to be_nil
+ end
+
+ it "does not include standard in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ standard_dep = builder.dependencies.find {|d| d.name == "standard" }
+ expect(standard_dep).to be_nil
+ end
+
+ it "doesn't generate a default .rubocop.yml" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ end
+
+ it "doesn't generate a default .standard.yml" do
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
+ end
+ end
+
+ it "has no rubocop offenses when using --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ bundle "gem #{gem_name} --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no rubocop offenses when using --ext and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ bundle "gem #{gem_name} --ext --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no rubocop offenses when using --ext, --test=minitest, and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ bundle "gem #{gem_name} --ext --test=minitest --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no rubocop offenses when using --ext, --test=rspec, and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ bundle "gem #{gem_name} --ext --test=rspec --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no rubocop offenses when using --ext, --ext=test-unit, and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ bundle "gem #{gem_name} --ext --test=test-unit --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no standard offenses when using --linter=standard flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ bundle "gem #{gem_name} --linter=standard"
+ bundle_exec_standardrb
+ expect(err).to be_empty
+ end
+
+ shared_examples_for "CI config is absent" do
+ it "does not create any CI files" do
+ expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist
+ end
+ end
+
+ shared_examples_for "test framework is absent" do
+ it "does not create any test framework files" do
+ expect(bundled_app("#{gem_name}/.rspec")).to_not exist
+ expect(bundled_app("#{gem_name}/spec/#{require_path}_spec.rb")).to_not exist
+ expect(bundled_app("#{gem_name}/spec/spec_helper.rb")).to_not exist
+ expect(bundled_app("#{gem_name}/test/#{require_path}.rb")).to_not exist
+ expect(bundled_app("#{gem_name}/test/test_helper.rb")).to_not exist
+ end
+ end
+
+ context "README.md", :readline do
context "git config github.user present" do
before do
- execute_bundle_gem(gem_name)
+ bundle "gem #{gem_name}"
end
it "contribute URL set to git username" do
- expect(bundled_app("test_gem/README.md").read).not_to include("[USERNAME]")
- expect(bundled_app("test_gem/README.md").read).to include("github.com/bundleuser")
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).to include("github.com/bundleuser")
end
end
context "git config github.user is absent" do
before do
- sys_exec("git config --unset github.user")
- reset!
- in_app_root
+ sys_exec("git config --global --unset github.user")
bundle "gem #{gem_name}"
- remove_push_guard(gem_name)
end
it "contribute URL set to [USERNAME]" do
- expect(bundled_app("test_gem/README.md").read).to include("[USERNAME]")
- expect(bundled_app("test_gem/README.md").read).not_to include("github.com/bundleuser")
+ expect(bundled_app("#{gem_name}/README.md").read).to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("github.com/bundleuser")
end
end
end
- it "creates a new git repository" do
- in_app_root
- bundle "gem test_gem"
- expect(bundled_app("test_gem/.git")).to exist
+ it "creates a new git repository", :readline do
+ bundle "gem #{gem_name}"
+ expect(bundled_app("#{gem_name}/.git")).to exist
end
- context "when git is not avaiable" do
- let(:gem_name) { "test_gem" }
-
- # This spec cannot have `git` avaiable in the test env
+ context "when git is not available", :readline do
+ # This spec cannot have `git` available in the test env
before do
- load_paths = [lib, spec]
+ load_paths = [lib_dir, spec_dir]
load_path_str = "-I#{load_paths.join(File::PATH_SEPARATOR)}"
- sys_exec "PATH=\"\" #{Gem.ruby} #{load_path_str} #{bindir.join("bundle")} gem #{gem_name}"
+ sys_exec "#{Gem.ruby} #{load_path_str} #{bindir.join("bundle")} gem #{gem_name}", :env => { "PATH" => "" }
end
it "creates the gem without the need for git" do
@@ -190,48 +412,24 @@ RSpec.describe "bundle gem" do
end
end
- it "generates a valid gemspec" do
- system_gems ["rake-10.0.2"]
-
- in_app_root
+ it "generates a valid gemspec", :readline, :ruby_repo do
bundle "gem newgem --bin"
- process_file(bundled_app("newgem", "newgem.gemspec")) do |line|
- # Simulate replacing TODOs with real values
- case line
- when /spec\.metadata\['allowed_push_host'\]/, /spec\.homepage/
- line.gsub(/\=.*$/, "= 'http://example.org'")
- when /spec\.summary/
- line.gsub(/\=.*$/, "= %q{A short summary of my new gem.}")
- when /spec\.description/
- line.gsub(/\=.*$/, "= %q{A longer description of my new gem.}")
- # Remove exception that prevents public pushes on older RubyGems versions
- when /raise "RubyGems 2.0 or newer/
- line.gsub(/.*/, "") if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0")
- else
- line
- end
- end
+ prepare_gemspec(bundled_app("newgem", "newgem.gemspec"))
- Dir.chdir(bundled_app("newgem")) do
- bundle "exec rake build"
- end
+ gems = ["rake-13.0.1"]
+ path = Bundler.feature_flag.default_install_uses_path? ? local_gem_path(:base => bundled_app("newgem")) : system_gem_path
+ system_gems gems, :path => path
+ bundle "exec rake build", :dir => bundled_app("newgem")
- expect(exitstatus).to be_zero if exitstatus
- expect(out).not_to include("ERROR")
- expect(err).not_to include("ERROR")
+ expect(last_command.stdboth).not_to include("ERROR")
end
- context "gem naming with relative paths" do
- before do
- reset!
- in_app_root
- end
-
+ context "gem naming with relative paths", :readline do
it "resolves ." do
create_temporary_dir("tmp")
- bundle "gem ."
+ bundle "gem .", :dir => bundled_app("tmp")
expect(bundled_app("tmp/lib/tmp.rb")).to exist
end
@@ -239,7 +437,7 @@ RSpec.describe "bundle gem" do
it "resolves .." do
create_temporary_dir("temp/empty_dir")
- bundle "gem .."
+ bundle "gem ..", :dir => bundled_app("temp/empty_dir")
expect(bundled_app("temp/lib/temp.rb")).to exist
end
@@ -247,237 +445,310 @@ RSpec.describe "bundle gem" do
it "resolves relative directory" do
create_temporary_dir("tmp/empty/tmp")
- bundle "gem ../../empty"
+ bundle "gem ../../empty", :dir => bundled_app("tmp/empty/tmp")
expect(bundled_app("tmp/empty/lib/empty.rb")).to exist
end
def create_temporary_dir(dir)
- FileUtils.mkdir_p(dir)
- Dir.chdir(dir)
+ FileUtils.mkdir_p(bundled_app(dir))
end
end
- context "gem naming with underscore" do
- let(:gem_name) { "test_gem" }
-
+ shared_examples_for "--github-username option" do |github_username|
before do
- execute_bundle_gem(gem_name)
+ bundle "gem #{gem_name} --github-username=#{github_username}"
+ end
+
+ it "generates a gem skeleton" do
+ gem_skeleton_assertions
+ end
+
+ it "contribute URL set to given github username" do
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).to include("github.com/#{github_username}")
+ end
+ end
+
+ shared_examples_for "github_username configuration" do
+ context "with github_username setting set to some value" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
+ bundle "gem #{gem_name}"
+ end
+
+ it "generates a gem skeleton" do
+ gem_skeleton_assertions
+ end
+
+ it "contribute URL set to bundle config setting" do
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).to include("github.com/different_username")
+ end
end
- let(:generated_gem) { Bundler::GemHelper.new(bundled_app(gem_name).to_s) }
+ context "with github_username setting set to false" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
+ bundle "gem #{gem_name}"
+ end
+
+ it "generates a gem skeleton" do
+ gem_skeleton_assertions
+ end
+
+ it "contribute URL set to [USERNAME]" do
+ expect(bundled_app("#{gem_name}/README.md").read).to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("github.com/bundleuser")
+ end
+ end
+ end
+ shared_examples_for "generating a gem" do
it "generates a gem skeleton" do
- expect(bundled_app("test_gem/test_gem.gemspec")).to exist
- expect(bundled_app("test_gem/Gemfile")).to exist
- expect(bundled_app("test_gem/Rakefile")).to exist
- expect(bundled_app("test_gem/lib/test_gem.rb")).to exist
- expect(bundled_app("test_gem/lib/test_gem/version.rb")).to exist
- expect(bundled_app("test_gem/.gitignore")).to exist
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/#{gem_name}.gemspec")).to exist
+ expect(bundled_app("#{gem_name}/Gemfile")).to exist
+ expect(bundled_app("#{gem_name}/Rakefile")).to exist
+ expect(bundled_app("#{gem_name}/lib/#{require_path}.rb")).to exist
+ expect(bundled_app("#{gem_name}/lib/#{require_path}/version.rb")).to exist
+ expect(bundled_app("#{gem_name}/sig/#{require_path}.rbs")).to exist
+ expect(bundled_app("#{gem_name}/.gitignore")).to exist
- expect(bundled_app("test_gem/bin/setup")).to exist
- expect(bundled_app("test_gem/bin/console")).to exist
- expect(bundled_app("test_gem/bin/setup")).to be_executable
- expect(bundled_app("test_gem/bin/console")).to be_executable
+ expect(bundled_app("#{gem_name}/bin/setup")).to exist
+ expect(bundled_app("#{gem_name}/bin/console")).to exist
+ expect(bundled_app("#{gem_name}/bin/setup")).to be_executable
+ expect(bundled_app("#{gem_name}/bin/console")).to be_executable
+ expect(bundled_app("#{gem_name}/bin/setup").read).to start_with("#!")
+ expect(bundled_app("#{gem_name}/bin/console").read).to start_with("#!")
end
it "starts with version 0.1.0" do
- expect(bundled_app("test_gem/lib/test_gem/version.rb").read).to match(/VERSION = "0.1.0"/)
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/lib/#{require_path}/version.rb").read).to match(/VERSION = "0.1.0"/)
end
- it "does not nest constants" do
- expect(bundled_app("test_gem/lib/test_gem/version.rb").read).to match(/module TestGem/)
- expect(bundled_app("test_gem/lib/test_gem.rb").read).to match(/module TestGem/)
+ it "declare String type for VERSION constant" do
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/sig/#{require_path}.rbs").read).to match(/VERSION: String/)
end
- it_should_behave_like "git config is present"
+ context "git config user.{name,email} is set" do
+ before do
+ bundle "gem #{gem_name}"
+ end
+
+ it "sets gemspec author to git user.name if available" do
+ expect(generated_gemspec.authors.first).to eq("Bundler User")
+ end
+
+ it "sets gemspec email to git user.email if available" do
+ expect(generated_gemspec.email.first).to eq("user@example.com")
+ end
+ end
context "git config user.{name,email} is not set" do
before do
- `git config --unset user.name`
- `git config --unset user.email`
- reset!
- in_app_root
+ sys_exec("git config --global --unset user.name")
+ sys_exec("git config --global --unset user.email")
bundle "gem #{gem_name}"
- remove_push_guard(gem_name)
end
- it_should_behave_like "git config is absent"
+ it "sets gemspec author to default message if git user.name is not set or empty" do
+ expect(generated_gemspec.authors.first).to eq("TODO: Write your name")
+ end
+
+ it "sets gemspec email to default message if git user.email is not set or empty" do
+ expect(generated_gemspec.email.first).to eq("TODO: Write your email address")
+ end
+ end
+
+ it "sets gemspec metadata['allowed_push_host']" do
+ bundle "gem #{gem_name}"
+
+ expect(generated_gemspec.metadata["allowed_push_host"]).
+ to match(/example\.com/)
end
- it "sets gemspec metadata['allowed_push_host']", :rubygems => "2.0" do
- expect(generated_gem.gemspec.metadata["allowed_push_host"]).
- to match(/mygemserver\.com/)
+ it "sets a minimum ruby version" do
+ bundle "gem #{gem_name}"
+
+ expect(generated_gemspec.required_ruby_version.to_s).to start_with(">=")
end
it "requires the version file" do
- expect(bundled_app("test_gem/lib/test_gem.rb").read).to match(%r{require "test_gem/version"})
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/lib/#{require_path}.rb").read).to match(%r{require_relative "#{require_relative_path}/version"})
+ end
+
+ it "creates a base error class" do
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/lib/#{require_path}.rb").read).to match(/class Error < StandardError; end$/)
+ end
+
+ it "does not include the gemspec file in files" do
+ bundle "gem #{gem_name}"
+
+ bundler_gemspec = Bundler::GemHelper.new(gemspec_dir).gemspec
+
+ expect(bundler_gemspec.files).not_to include("#{gem_name}.gemspec")
end
it "runs rake without problems" do
- system_gems ["rake-10.0.2"]
+ bundle "gem #{gem_name}"
+
+ system_gems ["rake-13.0.1"]
rakefile = strip_whitespace <<-RAKEFILE
task :default do
puts 'SUCCESS'
end
RAKEFILE
- File.open(bundled_app("test_gem/Rakefile"), "w") do |file|
+ File.open(bundled_app("#{gem_name}/Rakefile"), "w") do |file|
file.puts rakefile
end
- Dir.chdir(bundled_app(gem_name)) do
- sys_exec(rake)
- expect(out).to include("SUCCESS")
- end
+ sys_exec(rake, :dir => bundled_app(gem_name))
+ expect(out).to include("SUCCESS")
end
context "--exe parameter set" do
before do
- reset!
- in_app_root
bundle "gem #{gem_name} --exe"
end
it "builds exe skeleton" do
- expect(bundled_app("test_gem/exe/test_gem")).to exist
+ expect(bundled_app("#{gem_name}/exe/#{gem_name}")).to exist
end
- it "requires 'test-gem'" do
- expect(bundled_app("test_gem/exe/test_gem").read).to match(/require "test_gem"/)
+ it "requires the main file" do
+ expect(bundled_app("#{gem_name}/exe/#{gem_name}").read).to match(/require "#{require_path}"/)
end
end
context "--bin parameter set" do
before do
- reset!
- in_app_root
bundle "gem #{gem_name} --bin"
end
it "builds exe skeleton" do
- expect(bundled_app("test_gem/exe/test_gem")).to exist
+ expect(bundled_app("#{gem_name}/exe/#{gem_name}")).to exist
end
- it "requires 'test-gem'" do
- expect(bundled_app("test_gem/exe/test_gem").read).to match(/require "test_gem"/)
+ it "requires the main file" do
+ expect(bundled_app("#{gem_name}/exe/#{gem_name}").read).to match(/require "#{require_path}"/)
end
end
context "no --test parameter" do
before do
- reset!
- in_app_root
bundle "gem #{gem_name}"
end
- it "doesn't create any spec/test file" do
- expect(bundled_app("test_gem/.rspec")).to_not exist
- expect(bundled_app("test_gem/spec/test_gem_spec.rb")).to_not exist
- expect(bundled_app("test_gem/spec/spec_helper.rb")).to_not exist
- expect(bundled_app("test_gem/test/test_test_gem.rb")).to_not exist
- expect(bundled_app("test_gem/test/minitest_helper.rb")).to_not exist
- end
+ it_behaves_like "test framework is absent"
end
context "--test parameter set to rspec" do
before do
- reset!
- in_app_root
bundle "gem #{gem_name} --test=rspec"
end
it "builds spec skeleton" do
- expect(bundled_app("test_gem/.rspec")).to exist
- expect(bundled_app("test_gem/spec/test_gem_spec.rb")).to exist
- expect(bundled_app("test_gem/spec/spec_helper.rb")).to exist
+ expect(bundled_app("#{gem_name}/.rspec")).to exist
+ expect(bundled_app("#{gem_name}/spec/#{require_path}_spec.rb")).to exist
+ expect(bundled_app("#{gem_name}/spec/spec_helper.rb")).to exist
end
- it "depends on a specific version of rspec", :rubygems => ">= 1.8.1" do
- remove_push_guard(gem_name)
- rspec_dep = generated_gem.gemspec.development_dependencies.find {|d| d.name == "rspec" }
+ it "depends on a specific version of rspec in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ rspec_dep = builder.dependencies.find {|d| d.name == "rspec" }
expect(rspec_dep).to be_specific
end
- it "requires 'test-gem'" do
- expect(bundled_app("test_gem/spec/spec_helper.rb").read).to include(%(require "test_gem"))
+ it "requires the main file" do
+ expect(bundled_app("#{gem_name}/spec/spec_helper.rb").read).to include(%(require "#{require_path}"))
end
it "creates a default test which fails" do
- expect(bundled_app("test_gem/spec/test_gem_spec.rb").read).to include("expect(false).to eq(true)")
+ expect(bundled_app("#{gem_name}/spec/#{require_path}_spec.rb").read).to include("expect(false).to eq(true)")
end
end
context "gem.test setting set to rspec" do
before do
- reset!
- in_app_root
- bundle "config gem.test rspec"
+ bundle "config set gem.test rspec"
bundle "gem #{gem_name}"
end
it "builds spec skeleton" do
- expect(bundled_app("test_gem/.rspec")).to exist
- expect(bundled_app("test_gem/spec/test_gem_spec.rb")).to exist
- expect(bundled_app("test_gem/spec/spec_helper.rb")).to exist
+ expect(bundled_app("#{gem_name}/.rspec")).to exist
+ expect(bundled_app("#{gem_name}/spec/#{require_path}_spec.rb")).to exist
+ expect(bundled_app("#{gem_name}/spec/spec_helper.rb")).to exist
end
end
context "gem.test setting set to rspec and --test is set to minitest" do
before do
- reset!
- in_app_root
- bundle "config gem.test rspec"
+ bundle "config set gem.test rspec"
bundle "gem #{gem_name} --test=minitest"
end
it "builds spec skeleton" do
- expect(bundled_app("test_gem/test/test_gem_test.rb")).to exist
- expect(bundled_app("test_gem/test/test_helper.rb")).to exist
+ expect(bundled_app("#{gem_name}/test/#{require_path}_test.rb")).to exist
+ expect(bundled_app("#{gem_name}/test/test_helper.rb")).to exist
end
end
context "--test parameter set to minitest" do
before do
- reset!
- in_app_root
bundle "gem #{gem_name} --test=minitest"
end
- it "depends on a specific version of minitest", :rubygems => ">= 1.8.1" do
- remove_push_guard(gem_name)
- rspec_dep = generated_gem.gemspec.development_dependencies.find {|d| d.name == "minitest" }
- expect(rspec_dep).to be_specific
+ it "depends on a specific version of minitest" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ minitest_dep = builder.dependencies.find {|d| d.name == "minitest" }
+ expect(minitest_dep).to be_specific
end
it "builds spec skeleton" do
- expect(bundled_app("test_gem/test/test_gem_test.rb")).to exist
- expect(bundled_app("test_gem/test/test_helper.rb")).to exist
+ expect(bundled_app("#{gem_name}/test/#{require_path}_test.rb")).to exist
+ expect(bundled_app("#{gem_name}/test/test_helper.rb")).to exist
end
- it "requires 'test-gem'" do
- expect(bundled_app("test_gem/test/test_helper.rb").read).to include(%(require "test_gem"))
+ it "requires the main file" do
+ expect(bundled_app("#{gem_name}/test/test_helper.rb").read).to include(%(require "#{require_path}"))
end
- it "requires 'minitest_helper'" do
- expect(bundled_app("test_gem/test/test_gem_test.rb").read).to include(%(require "test_helper"))
+ it "requires 'test_helper'" do
+ expect(bundled_app("#{gem_name}/test/#{require_path}_test.rb").read).to include(%(require "test_helper"))
end
it "creates a default test which fails" do
- expect(bundled_app("test_gem/test/test_gem_test.rb").read).to include("assert false")
+ expect(bundled_app("#{gem_name}/test/#{require_path}_test.rb").read).to include("assert false")
end
end
context "gem.test setting set to minitest" do
before do
- reset!
- in_app_root
- bundle "config gem.test minitest"
+ bundle "config set gem.test minitest"
bundle "gem #{gem_name}"
end
it "creates a default rake task to run the test suite" do
rakefile = strip_whitespace <<-RAKEFILE
+ # frozen_string_literal: true
+
require "bundler/gem_tasks"
require "rake/testtask"
@@ -487,360 +758,670 @@ RSpec.describe "bundle gem" do
t.test_files = FileList["test/**/*_test.rb"]
end
- task :default => :test
+ task default: :test
RAKEFILE
- expect(bundled_app("test_gem/Rakefile").read).to eq(rakefile)
+ expect(bundled_app("#{gem_name}/Rakefile").read).to eq(rakefile)
end
end
- context "--test with no arguments" do
+ context "--test parameter set to test-unit" do
before do
- reset!
- in_app_root
- bundle "gem #{gem_name} --test"
+ bundle "gem #{gem_name} --test=test-unit"
end
- it "defaults to rspec" do
- expect(bundled_app("test_gem/spec/spec_helper.rb")).to exist
- expect(bundled_app("test_gem/test/minitest_helper.rb")).to_not exist
+ it "depends on a specific version of test-unit" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ test_unit_dep = builder.dependencies.find {|d| d.name == "test-unit" }
+ expect(test_unit_dep).to be_specific
end
- it "creates a .travis.yml file to test the library against the current Ruby version on Travis CI" do
- expect(bundled_app("test_gem/.travis.yml").read).to match(/- #{RUBY_VERSION}/)
+ it "builds spec skeleton" do
+ expect(bundled_app("#{gem_name}/test/#{require_path}_test.rb")).to exist
+ expect(bundled_app("#{gem_name}/test/test_helper.rb")).to exist
end
- end
- context "--edit option" do
- it "opens the generated gemspec in the user's text editor" do
- reset!
- in_app_root
- output = bundle "gem #{gem_name} --edit=echo"
- gemspec_path = File.join(Dir.pwd, gem_name, "#{gem_name}.gemspec")
- expect(output).to include("echo \"#{gemspec_path}\"")
+ it "requires the main file" do
+ expect(bundled_app("#{gem_name}/test/test_helper.rb").read).to include(%(require "#{require_path}"))
+ end
+
+ it "requires 'test_helper'" do
+ expect(bundled_app("#{gem_name}/test/#{require_path}_test.rb").read).to include(%(require "test_helper"))
+ end
+
+ it "creates a default test which fails" do
+ expect(bundled_app("#{gem_name}/test/#{require_path}_test.rb").read).to include("assert_equal(\"expected\", \"actual\")")
end
end
- end
- context "testing --mit and --coc options against bundle config settings" do
- let(:gem_name) { "test-gem" }
+ context "gem.test setting set to test-unit" do
+ before do
+ bundle "config set gem.test test-unit"
+ bundle "gem #{gem_name}"
+ end
- context "with mit option in bundle config settings set to true" do
+ it "creates a default rake task to run the test suite" do
+ rakefile = strip_whitespace <<-RAKEFILE
+ # frozen_string_literal: true
+
+ require "bundler/gem_tasks"
+ require "rake/testtask"
+
+ Rake::TestTask.new(:test) do |t|
+ t.libs << "test"
+ t.libs << "lib"
+ t.test_files = FileList["test/**/*_test.rb"]
+ end
+
+ task default: :test
+ RAKEFILE
+
+ expect(bundled_app("#{gem_name}/Rakefile").read).to eq(rakefile)
+ end
+ end
+
+ context "gem.test set to rspec and --test with no arguments", :hint_text do
before do
- global_config "BUNDLE_GEM__MIT" => "true", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false"
+ bundle "config set gem.test rspec"
+ bundle "gem #{gem_name} --test"
+ end
+
+ it "builds spec skeleton" do
+ expect(bundled_app("#{gem_name}/.rspec")).to exist
+ expect(bundled_app("#{gem_name}/spec/#{require_path}_spec.rb")).to exist
+ expect(bundled_app("#{gem_name}/spec/spec_helper.rb")).to exist
+ end
+
+ it "hints that --test is already configured" do
+ expect(out).to match("rspec is already configured, ignoring --test flag.")
end
- after { reset! }
- it_behaves_like "--mit flag"
- it_behaves_like "--no-mit flag"
end
- context "with mit option in bundle config settings set to false" do
- it_behaves_like "--mit flag"
- it_behaves_like "--no-mit flag"
+ context "gem.test setting set to false and --test with no arguments", :hint_text do
+ before do
+ bundle "config set gem.test false"
+ bundle "gem #{gem_name} --test"
+ end
+
+ it "asks to generate test files" do
+ expect(out).to match("Do you want to generate tests with your gem?")
+ end
+
+ it "hints that the choice will only be applied to the current gem" do
+ expect(out).to match("Your choice will only be applied to this gem.")
+ end
+
+ it_behaves_like "test framework is absent"
end
- context "with coc option in bundle config settings set to true" do
+ context "gem.test setting not set and --test with no arguments", :hint_text do
before do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "true"
+ bundle "gem #{gem_name} --test"
end
- after { reset! }
- it_behaves_like "--coc flag"
- it_behaves_like "--no-coc flag"
+
+ it "asks to generate test files" do
+ expect(out).to match("Do you want to generate tests with your gem?")
+ end
+
+ it "hints that the choice will be applied to future bundle gem calls" do
+ hint = "Future `bundle gem` calls will use your choice. " \
+ "This setting can be changed anytime with `bundle config gem.test`."
+ expect(out).to match(hint)
+ end
+
+ it_behaves_like "test framework is absent"
end
- context "with coc option in bundle config settings set to false" do
- it_behaves_like "--coc flag"
- it_behaves_like "--no-coc flag"
+ context "--ci with no argument" do
+ it "does not generate any CI config" do
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist
+ end
end
- end
- context "gem naming with dashed" do
- let(:gem_name) { "test-gem" }
+ context "--ci set to github" do
+ it "generates a GitHub Actions config file" do
+ bundle "gem #{gem_name} --ci=github"
- before do
- execute_bundle_gem(gem_name)
+ expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to exist
+ end
end
- let(:generated_gem) { Bundler::GemHelper.new(bundled_app(gem_name).to_s) }
+ context "--ci set to gitlab" do
+ it "generates a GitLab CI config file" do
+ bundle "gem #{gem_name} --ci=gitlab"
- it "generates a gem skeleton" do
- expect(bundled_app("test-gem/test-gem.gemspec")).to exist
- expect(bundled_app("test-gem/Gemfile")).to exist
- expect(bundled_app("test-gem/Rakefile")).to exist
- expect(bundled_app("test-gem/lib/test/gem.rb")).to exist
- expect(bundled_app("test-gem/lib/test/gem/version.rb")).to exist
+ expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to exist
+ end
end
- it "starts with version 0.1.0" do
- expect(bundled_app("test-gem/lib/test/gem/version.rb").read).to match(/VERSION = "0.1.0"/)
+ context "--ci set to circle" do
+ it "generates a CircleCI config file" do
+ bundle "gem #{gem_name} --ci=circle"
+
+ expect(bundled_app("#{gem_name}/.circleci/config.yml")).to exist
+ end
end
- it "nests constants so they work" do
- expect(bundled_app("test-gem/lib/test/gem/version.rb").read).to match(/module Test\n module Gem/)
- expect(bundled_app("test-gem/lib/test/gem.rb").read).to match(/module Test\n module Gem/)
+ context "--ci set to travis" do
+ it "generates a Travis CI config file" do
+ bundle "gem #{gem_name} --ci=travis"
+
+ expect(bundled_app("#{gem_name}/.travis.yml")).to exist
+ end
+ end
+
+ context "gem.ci setting set to none" do
+ it "doesn't generate any CI config" do
+ expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist
+ end
end
- it_should_behave_like "git config is present"
+ context "gem.ci setting set to github" do
+ it "generates a GitHub Actions config file" do
+ bundle "config set gem.ci github"
+ bundle "gem #{gem_name}"
- context "git config user.{name,email} is not set" do
- before do
- `git config --unset user.name`
- `git config --unset user.email`
- reset!
- in_app_root
+ expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to exist
+ end
+ end
+
+ context "gem.ci setting set to travis" do
+ it "generates a Travis CI config file" do
+ bundle "config set gem.ci travis"
bundle "gem #{gem_name}"
- remove_push_guard(gem_name)
+
+ expect(bundled_app("#{gem_name}/.travis.yml")).to exist
end
+ end
+
+ context "gem.ci setting set to gitlab" do
+ it "generates a GitLab CI config file" do
+ bundle "config set gem.ci gitlab"
+ bundle "gem #{gem_name}"
- it_should_behave_like "git config is absent"
+ expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to exist
+ end
end
- it "requires the version file" do
- expect(bundled_app("test-gem/lib/test/gem.rb").read).to match(%r{require "test/gem/version"})
+ context "gem.ci setting set to circle" do
+ it "generates a CircleCI config file" do
+ bundle "config set gem.ci circle"
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.circleci/config.yml")).to exist
+ end
end
- it "runs rake without problems" do
- system_gems ["rake-10.0.2"]
+ context "gem.ci set to github and --ci with no arguments", :hint_text do
+ before do
+ bundle "config set gem.ci github"
+ bundle "gem #{gem_name} --ci"
+ end
- rakefile = strip_whitespace <<-RAKEFILE
- task :default do
- puts 'SUCCESS'
- end
- RAKEFILE
- File.open(bundled_app("test-gem/Rakefile"), "w") do |file|
- file.puts rakefile
+ it "generates a GitHub Actions config file" do
+ expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to exist
end
- Dir.chdir(bundled_app(gem_name)) do
- sys_exec(rake)
- expect(out).to include("SUCCESS")
+ it "hints that --ci is already configured" do
+ expect(out).to match("github is already configured, ignoring --ci flag.")
end
end
- context "--bin parameter set" do
+ context "gem.ci setting set to false and --ci with no arguments", :hint_text do
before do
- reset!
- in_app_root
- bundle "gem #{gem_name} --bin"
+ bundle "config set gem.ci false"
+ bundle "gem #{gem_name} --ci"
end
- it "builds bin skeleton" do
- expect(bundled_app("test-gem/exe/test-gem")).to exist
+ it "asks to setup CI" do
+ expect(out).to match("Do you want to set up continuous integration for your gem?")
end
- it "requires 'test/gem'" do
- expect(bundled_app("test-gem/exe/test-gem").read).to match(%r{require "test/gem"})
+ it "hints that the choice will only be applied to the current gem" do
+ expect(out).to match("Your choice will only be applied to this gem.")
end
end
- context "no --test parameter" do
+ context "gem.ci setting not set and --ci with no arguments", :hint_text do
before do
- reset!
- in_app_root
+ bundle "gem #{gem_name} --ci"
+ end
+
+ it "asks to setup CI" do
+ expect(out).to match("Do you want to set up continuous integration for your gem?")
+ end
+
+ it "hints that the choice will be applied to future bundle gem calls" do
+ hint = "Future `bundle gem` calls will use your choice. " \
+ "This setting can be changed anytime with `bundle config gem.ci`."
+ expect(out).to match(hint)
+ end
+ end
+
+ context "--linter with no argument" do
+ it "does not generate any linter config" do
bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
end
+ end
+
+ context "--linter set to rubocop" do
+ it "generates a RuboCop config" do
+ bundle "gem #{gem_name} --linter=rubocop"
- it "doesn't create any spec/test file" do
- expect(bundled_app("test-gem/.rspec")).to_not exist
- expect(bundled_app("test-gem/spec/test/gem_spec.rb")).to_not exist
- expect(bundled_app("test-gem/spec/spec_helper.rb")).to_not exist
- expect(bundled_app("test-gem/test/test_test/gem.rb")).to_not exist
- expect(bundled_app("test-gem/test/minitest_helper.rb")).to_not exist
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
end
end
- context "--test parameter set to rspec" do
+ context "--linter set to standard" do
+ it "generates a Standard config" do
+ bundle "gem #{gem_name} --linter=standard"
+
+ expect(bundled_app("#{gem_name}/.standard.yml")).to exist
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ end
+ end
+
+ context "gem.linter setting set to none" do
+ it "doesn't generate any linter config" do
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
+ end
+ end
+
+ context "gem.linter setting set to rubocop" do
+ it "generates a RuboCop config file" do
+ bundle "config set gem.linter rubocop"
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ end
+ end
+
+ context "gem.linter setting set to standard" do
+ it "generates a Standard config file" do
+ bundle "config set gem.linter standard"
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.standard.yml")).to exist
+ end
+ end
+
+ context "gem.rubocop setting set to true", :bundler => "< 3" do
before do
- reset!
- in_app_root
- bundle "gem #{gem_name} --test=rspec"
+ bundle "config set gem.rubocop true"
+ bundle "gem #{gem_name}"
end
- it "builds spec skeleton" do
- expect(bundled_app("test-gem/.rspec")).to exist
- expect(bundled_app("test-gem/spec/test/gem_spec.rb")).to exist
- expect(bundled_app("test-gem/spec/spec_helper.rb")).to exist
+ it "generates rubocop config" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
end
- it "requires 'test/gem'" do
- expect(bundled_app("test-gem/spec/spec_helper.rb").read).to include(%(require "test/gem"))
+ it "unsets gem.rubocop" do
+ bundle "config gem.rubocop"
+ expect(out).to include("You have not configured a value for `gem.rubocop`")
end
- it "creates a default test which fails" do
- expect(bundled_app("test-gem/spec/test/gem_spec.rb").read).to include("expect(false).to eq(true)")
+ it "sets gem.linter=rubocop instead" do
+ bundle "config gem.linter"
+ expect(out).to match(/Set for the current user .*: "rubocop"/)
end
+ end
- it "creates a default rake task to run the specs" do
- rakefile = strip_whitespace <<-RAKEFILE
- require "bundler/gem_tasks"
- require "rspec/core/rake_task"
+ context "gem.linter set to rubocop and --linter with no arguments", :hint_text do
+ before do
+ bundle "config set gem.linter rubocop"
+ bundle "gem #{gem_name} --linter"
+ end
- RSpec::Core::RakeTask.new(:spec)
+ it "generates a RuboCop config file" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ end
- task :default => :spec
- RAKEFILE
+ it "hints that --linter is already configured" do
+ expect(out).to match("rubocop is already configured, ignoring --linter flag.")
+ end
+ end
+
+ context "gem.linter setting set to false and --linter with no arguments", :hint_text do
+ before do
+ bundle "config set gem.linter false"
+ bundle "gem #{gem_name} --linter"
+ end
+
+ it "asks to setup a linter" do
+ expect(out).to match("Do you want to add a code linter and formatter to your gem?")
+ end
- expect(bundled_app("test-gem/Rakefile").read).to eq(rakefile)
+ it "hints that the choice will only be applied to the current gem" do
+ expect(out).to match("Your choice will only be applied to this gem.")
end
end
- context "--test parameter set to minitest" do
+ context "gem.linter setting not set and --linter with no arguments", :hint_text do
before do
- reset!
- in_app_root
- bundle "gem #{gem_name} --test=minitest"
+ bundle "gem #{gem_name} --linter"
end
- it "builds spec skeleton" do
- expect(bundled_app("test-gem/test/test/gem_test.rb")).to exist
- expect(bundled_app("test-gem/test/test_helper.rb")).to exist
+ it "asks to setup a linter" do
+ expect(out).to match("Do you want to add a code linter and formatter to your gem?")
end
- it "requires 'test/gem'" do
- expect(bundled_app("test-gem/test/test_helper.rb").read).to match(%r{require "test/gem"})
+ it "hints that the choice will be applied to future bundle gem calls" do
+ hint = "Future `bundle gem` calls will use your choice. " \
+ "This setting can be changed anytime with `bundle config gem.linter`."
+ expect(out).to match(hint)
end
+ end
- it "requires 'test_helper'" do
- expect(bundled_app("test-gem/test/test/gem_test.rb").read).to match(/require "test_helper"/)
+ context "--edit option" do
+ it "opens the generated gemspec in the user's text editor" do
+ output = bundle "gem #{gem_name} --edit=echo"
+ gemspec_path = File.join(bundled_app, gem_name, "#{gem_name}.gemspec")
+ expect(output).to include("echo \"#{gemspec_path}\"")
end
+ end
+ end
- it "creates a default test which fails" do
- expect(bundled_app("test-gem/test/test/gem_test.rb").read).to match(/assert false/)
+ context "testing --mit and --coc options against bundle config settings", :readline do
+ let(:gem_name) { "test-gem" }
+
+ let(:require_path) { "test/gem" }
+
+ context "with mit option in bundle config settings set to true" do
+ before do
+ global_config "BUNDLE_GEM__MIT" => "true"
end
+ it_behaves_like "--mit flag"
+ it_behaves_like "--no-mit flag"
+ end
- it "creates a default rake task to run the test suite" do
- rakefile = strip_whitespace <<-RAKEFILE
- require "bundler/gem_tasks"
- require "rake/testtask"
+ context "with mit option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__MIT" => "false"
+ end
+ it_behaves_like "--mit flag"
+ it_behaves_like "--no-mit flag"
+ end
- Rake::TestTask.new(:test) do |t|
- t.libs << "test"
- t.libs << "lib"
- t.test_files = FileList["test/**/*_test.rb"]
- end
+ context "with coc option in bundle config settings set to true" do
+ before do
+ global_config "BUNDLE_GEM__COC" => "true"
+ end
+ it_behaves_like "--coc flag"
+ it_behaves_like "--no-coc flag"
+ end
- task :default => :test
- RAKEFILE
+ context "with coc option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__COC" => "false"
+ end
+ it_behaves_like "--coc flag"
+ it_behaves_like "--no-coc flag"
+ end
- expect(bundled_app("test-gem/Rakefile").read).to eq(rakefile)
+ context "with rubocop option in bundle config settings set to true" do
+ before do
+ global_config "BUNDLE_GEM__RUBOCOP" => "true"
end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ it_behaves_like "--rubocop flag"
+ it_behaves_like "--no-rubocop flag"
end
- context "--test with no arguments" do
+ context "with rubocop option in bundle config settings set to false" do
before do
- reset!
- in_app_root
- bundle "gem #{gem_name} --test"
+ global_config "BUNDLE_GEM__RUBOCOP" => "false"
+ end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ it_behaves_like "--rubocop flag"
+ it_behaves_like "--no-rubocop flag"
+ end
+
+ context "with linter option in bundle config settings set to rubocop" do
+ before do
+ global_config "BUNDLE_GEM__LINTER" => "rubocop"
+ end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ end
+
+ context "with linter option in bundle config settings set to standard" do
+ before do
+ global_config "BUNDLE_GEM__LINTER" => "standard"
+ end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ end
+
+ context "with linter option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__LINTER" => "false"
+ end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ end
+
+ context "with changelog option in bundle config settings set to true" do
+ before do
+ global_config "BUNDLE_GEM__CHANGELOG" => "true"
+ end
+ it_behaves_like "--changelog flag"
+ it_behaves_like "--no-changelog flag"
+ end
+
+ context "with changelog option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__CHANGELOG" => "false"
+ end
+ it_behaves_like "--changelog flag"
+ it_behaves_like "--no-changelog flag"
+ end
+ end
+
+ context "testing --github-username option against git and bundle config settings", :readline do
+ context "without git config set" do
+ before do
+ sys_exec("git config --global --unset github.user")
+ end
+ context "with github-username option in bundle config settings set to some value" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
+ end
+ it_behaves_like "--github-username option", "gh_user"
+ end
+
+ context "with github-username option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
+ end
+ it_behaves_like "--github-username option", "gh_user"
end
+ end
+
+ context "with git config set" do
+ context "with github-username option in bundle config settings set to some value" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
+ end
+ it_behaves_like "--github-username option", "gh_user"
+ end
+
+ context "with github-username option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
+ end
+ it_behaves_like "--github-username option", "gh_user"
+ end
+ end
+ end
- it "defaults to rspec" do
- expect(bundled_app("test-gem/spec/spec_helper.rb")).to exist
- expect(bundled_app("test-gem/test/minitest_helper.rb")).to_not exist
+ context "testing github_username bundle config against git config settings", :readline do
+ context "without git config set" do
+ before do
+ sys_exec("git config --global --unset github.user")
end
+
+ it_behaves_like "github_username configuration"
+ end
+
+ context "with git config set" do
+ it_behaves_like "github_username configuration"
end
+ end
+
+ context "gem naming with underscore", :readline do
+ let(:gem_name) { "test_gem" }
+
+ let(:require_path) { "test_gem" }
+
+ let(:require_relative_path) { "test_gem" }
+
+ let(:flags) { nil }
+
+ it "does not nest constants" do
+ bundle ["gem", gem_name, flags].compact.join(" ")
+ expect(bundled_app("#{gem_name}/lib/#{require_path}/version.rb").read).to match(/module TestGem/)
+ expect(bundled_app("#{gem_name}/lib/#{require_path}.rb").read).to match(/module TestGem/)
+ end
+
+ include_examples "generating a gem"
context "--ext parameter set" do
+ let(:flags) { "--ext" }
+
before do
- reset!
- in_app_root
- bundle "gem test_gem --ext"
+ bundle ["gem", gem_name, flags].compact.join(" ")
end
it "builds ext skeleton" do
- expect(bundled_app("test_gem/ext/test_gem/extconf.rb")).to exist
- expect(bundled_app("test_gem/ext/test_gem/test_gem.h")).to exist
- expect(bundled_app("test_gem/ext/test_gem/test_gem.c")).to exist
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/extconf.rb")).to exist
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.h")).to exist
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.c")).to exist
end
it "includes rake-compiler" do
- expect(bundled_app("test_gem/test_gem.gemspec").read).to include('spec.add_development_dependency "rake-compiler"')
+ expect(bundled_app("#{gem_name}/Gemfile").read).to include('gem "rake-compiler"')
end
it "depends on compile task for build" do
rakefile = strip_whitespace <<-RAKEFILE
+ # frozen_string_literal: true
+
require "bundler/gem_tasks"
require "rake/extensiontask"
- task :build => :compile
+ task build: :compile
- Rake::ExtensionTask.new("test_gem") do |ext|
- ext.lib_dir = "lib/test_gem"
+ Rake::ExtensionTask.new("#{gem_name}") do |ext|
+ ext.lib_dir = "lib/#{gem_name}"
end
- task :default => [:clobber, :compile, :spec]
+ task default: %i[clobber compile]
RAKEFILE
- expect(bundled_app("test_gem/Rakefile").read).to eq(rakefile)
+ expect(bundled_app("#{gem_name}/Rakefile").read).to eq(rakefile)
end
end
end
+ context "gem naming with dashed", :readline do
+ let(:gem_name) { "test-gem" }
+
+ let(:require_path) { "test/gem" }
+
+ let(:require_relative_path) { "gem" }
+
+ it "nests constants so they work" do
+ bundle "gem #{gem_name}"
+ expect(bundled_app("#{gem_name}/lib/#{require_path}/version.rb").read).to match(/module Test\n module Gem/)
+ expect(bundled_app("#{gem_name}/lib/#{require_path}.rb").read).to match(/module Test\n module Gem/)
+ end
+
+ include_examples "generating a gem"
+ end
+
describe "uncommon gem names" do
- it "can deal with two dashes" do
+ it "can deal with two dashes", :readline do
bundle "gem a--a"
- Bundler.clear_gemspec_cache
expect(bundled_app("a--a/a--a.gemspec")).to exist
end
it "fails gracefully with a ." do
- bundle "gem foo.gemspec"
- expect(out).to end_with("Invalid gem name foo.gemspec -- `Foo.gemspec` is an invalid constant name")
+ bundle "gem foo.gemspec", :raise_on_error => false
+ expect(err).to end_with("Invalid gem name foo.gemspec -- `Foo.gemspec` is an invalid constant name")
end
it "fails gracefully with a ^" do
- bundle "gem ^"
- expect(out).to end_with("Invalid gem name ^ -- `^` is an invalid constant name")
+ bundle "gem ^", :raise_on_error => false
+ expect(err).to end_with("Invalid gem name ^ -- `^` is an invalid constant name")
end
it "fails gracefully with a space" do
- bundle "gem 'foo bar'"
- expect(out).to end_with("Invalid gem name foo bar -- `Foo bar` is an invalid constant name")
+ bundle "gem 'foo bar'", :raise_on_error => false
+ expect(err).to end_with("Invalid gem name foo bar -- `Foo bar` is an invalid constant name")
end
it "fails gracefully when multiple names are passed" do
- bundle "gem foo bar baz"
- expect(out).to eq(<<-E.strip)
+ bundle "gem foo bar baz", :raise_on_error => false
+ expect(err).to eq(<<-E.strip)
ERROR: "bundle gem" was called with arguments ["foo", "bar", "baz"]
-Usage: "bundle gem GEM [OPTIONS]"
+Usage: "bundle gem NAME [OPTIONS]"
E
end
end
- describe "#ensure_safe_gem_name" do
+ describe "#ensure_safe_gem_name", :readline do
before do
- bundle "gem #{subject}"
- end
- after do
- Bundler.clear_gemspec_cache
+ bundle "gem #{subject}", :raise_on_error => false
end
context "with an existing const name" do
subject { "gem" }
- it { expect(out).to include("Invalid gem name #{subject}") }
+ it { expect(err).to include("Invalid gem name #{subject}") }
end
context "with an existing hyphenated const name" do
subject { "gem-specification" }
- it { expect(out).to include("Invalid gem name #{subject}") }
+ it { expect(err).to include("Invalid gem name #{subject}") }
end
context "starting with an existing const name" do
subject { "gem-somenewconstantname" }
- it { expect(out).not_to include("Invalid gem name #{subject}") }
+ it { expect(err).not_to include("Invalid gem name #{subject}") }
end
context "ending with an existing const name" do
subject { "somenewconstantname-gem" }
- it { expect(out).not_to include("Invalid gem name #{subject}") }
+ it { expect(err).not_to include("Invalid gem name #{subject}") }
end
end
- context "on first run" do
- before do
- in_app_root
- end
-
+ context "on first run", :readline do
it "asks about test framework" do
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false"
@@ -850,22 +1431,34 @@ Usage: "bundle gem GEM [OPTIONS]"
expect(bundled_app("foobar/spec/spec_helper.rb")).to exist
rakefile = strip_whitespace <<-RAKEFILE
+ # frozen_string_literal: true
+
require "bundler/gem_tasks"
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec)
- task :default => :spec
+ task default: :spec
RAKEFILE
expect(bundled_app("foobar/Rakefile").read).to eq(rakefile)
- expect(bundled_app("foobar/foobar.gemspec").read).to include('spec.add_development_dependency "rspec"')
+ expect(bundled_app("foobar/Gemfile").read).to include('gem "rspec"')
+ end
+
+ it "asks about CI service" do
+ global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false"
+
+ bundle "gem foobar" do |input, _, _|
+ input.puts "github"
+ end
+
+ expect(bundled_app("foobar/.github/workflows/main.yml")).to exist
end
it "asks about MIT license" do
- global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false"
+ global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
- bundle :config
+ bundle "config list"
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@@ -875,7 +1468,7 @@ Usage: "bundle gem GEM [OPTIONS]"
end
it "asks about CoC" do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false"
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@@ -883,25 +1476,32 @@ Usage: "bundle gem GEM [OPTIONS]"
expect(bundled_app("foobar/CODE_OF_CONDUCT.md")).to exist
end
+
+ it "asks about CHANGELOG" do
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false",
+ "BUNDLE_GEM__COC" => "false"
+
+ bundle "gem foobar" do |input, _, _|
+ input.puts "yes"
+ end
+
+ expect(bundled_app("foobar/CHANGELOG.md")).to exist
+ end
end
- context "on conflicts with a previously created file" do
+ context "on conflicts with a previously created file", :readline do
it "should fail gracefully" do
- in_app_root do
- FileUtils.touch("conflict-foobar")
- end
- output = bundle "gem conflict-foobar"
- expect(output).to include("Errno::ENOTDIR")
- expect(exitstatus).to eql(32) if exitstatus
+ FileUtils.touch(bundled_app("conflict-foobar"))
+ bundle "gem conflict-foobar", :raise_on_error => false
+ expect(err).to eq("Couldn't create a new gem named `conflict-foobar` because there's an existing file named `conflict-foobar`.")
+ expect(exitstatus).to eql(32)
end
end
- context "on conflicts with a previously created directory" do
+ context "on conflicts with a previously created directory", :readline do
it "should succeed" do
- in_app_root do
- FileUtils.mkdir_p("conflict-foobar/Gemfile")
- end
- bundle! "gem conflict-foobar"
+ FileUtils.mkdir_p(bundled_app("conflict-foobar/Gemfile"))
+ bundle "gem conflict-foobar"
expect(out).to include("file_clash conflict-foobar/Gemfile").
and include "Initializing git repo in #{bundled_app("conflict-foobar")}"
end
diff --git a/spec/bundler/commands/open_spec.rb b/spec/bundler/commands/open_spec.rb
index 6872e859d2..53dc35c2c7 100644
--- a/spec/bundler/commands/open_spec.rb
+++ b/spec/bundler/commands/open_spec.rb
@@ -1,93 +1,118 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle open" do
- before :each do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rails"
- G
- end
+ context "when opening a regular gem" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ G
+ end
- it "opens the gem with BUNDLER_EDITOR as highest priority" do
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- expect(out).to include("bundler_editor #{default_bundle_path("gems", "rails-2.3.2")}")
- end
+ it "opens the gem with BUNDLER_EDITOR as highest priority" do
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ expect(out).to include("bundler_editor #{default_bundle_path("gems", "rails-2.3.2")}")
+ end
- it "opens the gem with VISUAL as 2nd highest priority" do
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "" }
- expect(out).to include("visual #{default_bundle_path("gems", "rails-2.3.2")}")
- end
+ it "opens the gem with VISUAL as 2nd highest priority" do
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("visual #{default_bundle_path("gems", "rails-2.3.2")}")
+ end
- it "opens the gem with EDITOR as 3rd highest priority" do
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to include("editor #{default_bundle_path("gems", "rails-2.3.2")}")
- end
+ it "opens the gem with EDITOR as 3rd highest priority" do
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("editor #{default_bundle_path("gems", "rails-2.3.2")}")
+ end
- it "complains if no EDITOR is set" do
- bundle "open rails", :env => { "EDITOR" => "", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to eq("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR")
- end
+ it "complains if no EDITOR is set" do
+ bundle "open rails", :env => { "EDITOR" => "", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to eq("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR")
+ end
- it "complains if gem not in bundle" do
- bundle "open missing", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to match(/could not find gem 'missing'/i)
- end
+ it "complains if gem not in bundle" do
+ bundle "open missing", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
+ expect(err).to match(/could not find gem 'missing'/i)
+ end
- it "does not blow up if the gem to open does not have a Gemfile" do
- git = build_git "foo"
- ref = git.ref_for("master", 11)
+ it "does not blow up if the gem to open does not have a Gemfile" do
+ git = build_git "foo"
+ ref = git.ref_for("master", 11)
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem 'foo', :git => "#{lib_path("foo-1.0")}"
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'foo', :git => "#{lib_path("foo-1.0")}"
+ G
- bundle "open foo", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to match("editor #{default_bundle_path.join("bundler/gems/foo-1.0-#{ref}")}")
- end
+ bundle "open foo", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to match("editor #{default_bundle_path.join("bundler/gems/foo-1.0-#{ref}")}")
+ end
- it "suggests alternatives for similar-sounding gems" do
- bundle "open Rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to match(/did you mean rails\?/i)
- end
+ it "suggests alternatives for similar-sounding gems" do
+ bundle "open Rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
+ expect(err).to match(/did you mean rails\?/i)
+ end
- it "opens the gem with short words" do
- bundle "open rec", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ it "opens the gem with short words" do
+ bundle "open rec", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}")
- end
+ expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}")
+ end
+
+ it "select the gem from many match gems", :readline do
+ env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open active", :env => env do |input, _, _|
+ input.puts "2"
+ end
- it "select the gem from many match gems" do
- env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle "open active", :env => env do |input, _, _|
- input.puts "2"
+ expect(out).to match(/bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}\z/)
end
- expect(out).to match(/bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}\z/)
- end
+ it "allows selecting exit from many match gems", :readline do
+ env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open active", :env => env do |input, _, _|
+ input.puts "0"
+ end
+ end
+
+ it "performs an automatic bundle install" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ gem "foo"
+ G
- it "allows selecting exit from many match gems" do
- env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle! "open active", :env => env do |input, _, _|
- input.puts "0"
+ bundle "config set auto_install 1"
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("Installing foo 1.0")
+ end
+
+ it "opens the editor with a clean env" do
+ bundle "open", :env => { "EDITOR" => "sh -c 'env'", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
+ expect(out).not_to include("BUNDLE_GEMFILE=")
end
end
- it "performs an automatic bundle install" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rails"
- gem "foo"
- G
+ context "when opening a default gem" do
+ let(:default_gems) do
+ ruby(<<-RUBY).split("\n")
+ if Gem::Specification.is_a?(Enumerable)
+ puts Gem::Specification.select(&:default_gem?).map(&:name)
+ end
+ RUBY
+ end
- bundle "config auto_install 1"
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to include("Installing foo 1.0")
- end
+ before do
+ skip "No default gems available on this test run" if default_gems.empty?
- it "opens the editor with a clean env" do
- bundle "open", :env => { "EDITOR" => "sh -c 'env'", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).not_to include("BUNDLE_GEMFILE=")
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "json"
+ G
+ end
+
+ it "throws proper error when trying to open default gem" do
+ bundle "open json", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ expect(out).to include("Unable to open json because it's a default gem, so the directory it would normally be installed to does not exist.")
+ end
end
end
diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb
index c6b6c9f59e..731d67af1b 100644
--- a/spec/bundler/commands/outdated_spec.rb
+++ b/spec/bundler/commands/outdated_spec.rb
@@ -1,25 +1,24 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle outdated" do
- before :each do
- build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
- end
-
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "zebra", :git => "#{lib_path("zebra")}"
- gem "foo", :git => "#{lib_path("foo")}"
- gem "activesupport", "2.3.5"
- gem "weakling", "~> 0.0.1"
- gem "duradura", '7.0'
- gem "terranova", '8'
- G
- end
-
describe "with no arguments" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+ end
+
it "returns a sorted list of outdated gems" do
update_repo2 do
build_gem "activesupport", "3.0"
@@ -28,15 +27,37 @@ RSpec.describe "bundle outdated" do
update_git "zebra", :path => lib_path("zebra")
end
- bundle "outdated"
+ bundle "outdated", :raise_on_error => false
- expect(out).to include("activesupport (newest 3.0, installed 2.3.5, requested = 2.3.5)")
- expect(out).to include("weakling (newest 0.2, installed 0.0.3, requested ~> 0.0.1)")
- expect(out).to include("foo (newest 1.0")
+ expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 default
+ foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default
+ weakling 0.0.3 0.2 ~> 0.0.1 default
+ zebra 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default
+ TABLE
- # Gem names are one per-line, between "*" and their parenthesized version.
- gem_list = out.split("\n").map {|g| g[/\* (.*) \(/, 1] }.compact
- expect(gem_list).to eq(gem_list.sort)
+ expect(out).to match(Regexp.new(expected_output))
+ end
+
+ it "excludes header row from the sorting" do
+ update_repo2 do
+ build_gem "AAA", %w[1.0.0 2.0.0]
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "AAA", "1.0.0"
+ G
+
+ bundle "outdated", :raise_on_error => false
+
+ expected_output = <<~TABLE
+ Gem Current Latest Requested Groups
+ AAA 1.0.0 2.0.0 = 1.0.0 default
+ TABLE
+
+ expect(out).to include(expected_output.strip)
end
it "returns non zero exit status if outdated gems present" do
@@ -45,20 +66,20 @@ RSpec.describe "bundle outdated" do
update_git "foo", :path => lib_path("foo")
end
- bundle "outdated"
+ bundle "outdated", :raise_on_error => false
- expect(exitstatus).to_not be_zero if exitstatus
+ expect(exitstatus).to_not be_zero
end
it "returns success exit status if no outdated gems present" do
bundle "outdated"
-
- expect(exitstatus).to be_zero if exitstatus
end
it "adds gem group to dependency output when repo is updated" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "terranova", '8'
group :development, :test do
gem 'activesupport', '2.3.5'
@@ -66,98 +87,251 @@ RSpec.describe "bundle outdated" do
G
update_repo2 { build_gem "activesupport", "3.0" }
+ update_repo2 { build_gem "terranova", "9" }
+
+ bundle "outdated", :raise_on_error => false
- bundle "outdated --verbose"
- expect(out).to include("activesupport (newest 3.0, installed 2.3.5, requested = 2.3.5) in groups \"development, test\"")
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 development, test
+ terranova 8 9 = 8 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
end
- describe "with --group option" do
- def test_group_option(group = nil, gems_list_size = 1)
- install_gemfile <<-G
- source "file://#{gem_repo2}"
+ describe "with --verbose option" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
gem "terranova", '8'
- group :development, :test do
- gem "duradura", '7.0'
- gem 'activesupport', '2.3.5'
- end
G
+ end
- update_repo2 do
- build_gem "activesupport", "3.0"
- build_gem "terranova", "9"
- build_gem "duradura", "8.0"
+ it "shows the location of the latest version's gemspec if installed" do
+ bundle "config set clean false"
+
+ update_repo2 { build_gem "activesupport", "3.0" }
+ update_repo2 { build_gem "terranova", "9" }
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "terranova", '9'
+ gem 'activesupport', '2.3.5'
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "terranova", '8'
+ gem 'activesupport', '2.3.5'
+ G
+
+ bundle "outdated --verbose", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups Path
+ activesupport 2.3.5 3.0 = 2.3.5 default
+ terranova 8 9 = 8 default #{default_bundle_path("specifications/terranova-9.gemspec")}
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+ end
+
+ describe "with multiple, duplicated sources, with lockfile in old format", :bundler => "< 3" do
+ before do
+ build_repo2 do
+ build_gem "dotenv", "2.7.6"
+
+ build_gem "oj", "3.11.3"
+ build_gem "oj", "3.11.5"
+
+ build_gem "vcr", "6.0.0"
+ end
+
+ build_repo gem_repo3 do
+ build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s|
+ s.add_dependency "oj"
+ end
end
- bundle "outdated --group #{group}"
+ gemfile <<~G
+ source "https://gem.repo2"
- # Gem names are one per-line, between "*" and their parenthesized version.
- gem_list = out.split("\n").map {|g| g[/\* (.*) \(/, 1] }.compact
- expect(gem_list).to eq(gem_list.sort)
- expect(gem_list.size).to eq gems_list_size
+ gem "dotenv"
+
+ source "https://gem.repo3" do
+ gem 'pkg-gem-flowbyte-with-dep'
+ end
+
+ gem "vcr",source: "https://gem.repo2"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gem.repo2/
+ remote: https://gem.repo3/
+ specs:
+ dotenv (2.7.6)
+ oj (3.11.3)
+ pkg-gem-flowbyte-with-dep (1.0.0)
+ oj
+ vcr (6.0.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ dotenv
+ pkg-gem-flowbyte-with-dep!
+ vcr!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
- it "not outdated gems" do
+ it "works" do
+ bundle :install, :artifice => "compact_index"
+ bundle :outdated, :artifice => "compact_index", :raise_on_error => false
+
+ expected_output = <<~TABLE
+ Gem Current Latest Requested Groups
+ oj 3.11.3 3.11.5
+ TABLE
+
+ expect(out).to include(expected_output.strip)
+ end
+ end
+
+ describe "with --group option" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "weakling", "~> 0.0.1"
gem "terranova", '8'
group :development, :test do
- gem 'activesupport', '2.3.5'
gem "duradura", '7.0'
+ gem 'activesupport', '2.3.5'
end
G
+ end
+ def test_group_option(group)
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ build_gem "terranova", "9"
+ build_gem "duradura", "8.0"
+ end
+
+ bundle "outdated --group #{group}", :raise_on_error => false
+ end
+
+ it "works when the bundle is up to date" do
bundle "outdated --group"
- expect(out).to include("Bundle up to date!")
+ expect(out).to end_with("Bundle up to date!")
end
it "returns a sorted list of outdated gems from one group => 'default'" do
test_group_option("default")
- expect(out).to include("===== Group default =====")
- expect(out).to include("terranova (")
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ terranova 8 9 = 8 default
+ TABLE
- expect(out).not_to include("===== Group development, test =====")
- expect(out).not_to include("activesupport")
- expect(out).not_to include("duradura")
+ expect(out).to end_with(expected_output)
end
it "returns a sorted list of outdated gems from one group => 'development'" do
- test_group_option("development", 2)
+ test_group_option("development")
- expect(out).not_to include("===== Group default =====")
- expect(out).not_to include("terranova (")
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 development, test
+ duradura 7.0 8.0 = 7.0 development, test
+ TABLE
- expect(out).to include("===== Group development, test =====")
- expect(out).to include("activesupport")
- expect(out).to include("duradura")
+ expect(out).to end_with(expected_output)
+ end
+
+ it "returns a sorted list of outdated gems from one group => 'test'" do
+ test_group_option("test")
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 development, test
+ duradura 7.0 8.0 = 7.0 development, test
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
end
- describe "with --groups option" do
- it "not outdated gems" do
- install_gemfile <<-G
- source "file://#{gem_repo2}"
+ describe "with --groups option and outdated transitive dependencies" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
- gem "weakling", "~> 0.0.1"
- gem "terranova", '8'
- group :development, :test do
- gem 'activesupport', '2.3.5'
- gem "duradura", '7.0'
+ build_gem "bar", %w[2.0.0]
+
+ build_gem "bar_dependant", "7.0" do |s|
+ s.add_dependency "bar", "~> 2.0"
end
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "bar_dependant", '7.0'
G
- bundle "outdated --groups"
- expect(out).to include("Bundle up to date!")
+ update_repo2 do
+ build_gem "bar", %w[3.0.0]
+ end
end
- it "returns a sorted list of outdated gems by groups" do
+ it "returns a sorted list of outdated gems" do
+ bundle "outdated --groups", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ bar 2.0.0 3.0.0
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+ end
+
+ describe "with --groups option" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "weakling", "~> 0.0.1"
gem "terranova", '8'
@@ -166,40 +340,72 @@ RSpec.describe "bundle outdated" do
gem "duradura", '7.0'
end
G
+ end
+ it "not outdated gems" do
+ bundle "outdated --groups"
+ expect(out).to end_with("Bundle up to date!")
+ end
+
+ it "returns a sorted list of outdated gems by groups" do
update_repo2 do
build_gem "activesupport", "3.0"
build_gem "terranova", "9"
build_gem "duradura", "8.0"
end
- bundle "outdated --groups"
- expect(out).to include("===== Group default =====")
- expect(out).to include("terranova (newest 9, installed 8, requested = 8)")
- expect(out).to include("===== Group development, test =====")
- expect(out).to include("activesupport (newest 3.0, installed 2.3.5, requested = 2.3.5)")
- expect(out).to include("duradura (newest 8.0, installed 7.0, requested = 7.0)")
+ bundle "outdated --groups", :raise_on_error => false
- expect(out).not_to include("weakling (")
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 development, test
+ duradura 7.0 8.0 = 7.0 development, test
+ terranova 8 9 = 8 default
+ TABLE
- # TODO: check gems order inside the group
+ expect(out).to end_with(expected_output)
end
end
describe "with --local option" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "weakling", "~> 0.0.1"
+ gem "terranova", '8'
+ group :development, :test do
+ gem 'activesupport', '2.3.5'
+ gem "duradura", '7.0'
+ end
+ G
+ end
+
it "uses local cache to return a list of outdated gems" do
update_repo2 do
build_gem "activesupport", "2.3.4"
end
+ bundle "config set clean false"
+
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "2.3.4"
G
- bundle "outdated --local"
+ bundle "outdated --local", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.4 2.3.5 = 2.3.4 default
+ TABLE
- expect(out).to include("activesupport (newest 2.3.5, installed 2.3.4, requested = 2.3.4)")
+ expect(out).to end_with(expected_output)
end
it "doesn't hit repo2" do
@@ -213,10 +419,23 @@ RSpec.describe "bundle outdated" do
shared_examples_for "a minimal output is desired" do
context "and gems are outdated" do
before do
- update_repo2 do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+
build_gem "activesupport", "3.0"
build_gem "weakling", "0.2"
end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
end
it "outputs a sorted list of outdated gems with a more minimal format" do
@@ -230,37 +449,74 @@ RSpec.describe "bundle outdated" do
context "and no gems are outdated" do
it "has empty output" do
subject
- expect(out).to eq("")
+ expect(out).to be_empty
end
end
end
describe "with --parseable option" do
- subject { bundle "outdated --parseable" }
+ subject { bundle "outdated --parseable", :raise_on_error => false }
it_behaves_like "a minimal output is desired"
end
describe "with aliased --porcelain option" do
- subject { bundle "outdated --porcelain" }
+ subject { bundle "outdated --porcelain", :raise_on_error => false }
it_behaves_like "a minimal output is desired"
end
describe "with specified gems" do
it "returns list of outdated gems" do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
update_repo2 do
build_gem "activesupport", "3.0"
update_git "foo", :path => lib_path("foo")
end
- bundle "outdated foo"
- expect(out).not_to include("activesupport (newest")
- expect(out).to include("foo (newest 1.0")
+ bundle "outdated foo", :raise_on_error => false
+
+ expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
+ Gem Current Latest Requested Groups
+ foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default
+ TABLE
+
+ expect(out).to match(Regexp.new(expected_output))
end
end
describe "pre-release gems" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+ end
+
context "without the --pre option" do
it "ignores pre-release versions" do
update_repo2 do
@@ -268,7 +524,8 @@ RSpec.describe "bundle outdated" do
end
bundle "outdated"
- expect(out).not_to include("activesupport (3.0.0.beta > 2.3.5)")
+
+ expect(out).to end_with("Bundle up to date!")
end
end
@@ -278,8 +535,14 @@ RSpec.describe "bundle outdated" do
build_gem "activesupport", "3.0.0.beta"
end
- bundle "outdated --pre"
- expect(out).to include("activesupport (newest 3.0.0.beta, installed 2.3.5, requested = 2.3.5)")
+ bundle "outdated --pre", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0.0.beta = 2.3.5 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
end
@@ -291,195 +554,318 @@ RSpec.describe "bundle outdated" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "3.0.0.beta.1"
G
- bundle "outdated"
- expect(out).to include("(newest 3.0.0.beta.2, installed 3.0.0.beta.1, requested = 3.0.0.beta.1)")
+ bundle "outdated", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ activesupport 3.0.0.beta.1 3.0.0.beta.2 = 3.0.0.beta.1 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
end
end
- describe "with --strict option" do
+ filter_strict_option = Bundler.feature_flag.bundler_2_mode? ? :"filter-strict" : :strict
+ describe "with --#{filter_strict_option} option" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+ end
+
it "only reports gems that have a newer version that matches the specified dependency version requirements" do
update_repo2 do
build_gem "activesupport", "3.0"
build_gem "weakling", "0.0.5"
end
- bundle "outdated --strict"
+ bundle :outdated, filter_strict_option => true, :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ weakling 0.0.3 0.0.5 ~> 0.0.1 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+
+ it "doesn't crash when some deps unused on the current platform" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", platforms: [:ruby_22]
+ G
+
+ bundle :outdated, filter_strict_option => true
- expect(out).to_not include("activesupport (newest")
- expect(out).to include("(newest 0.0.5, installed 0.0.3, requested ~> 0.0.1)")
+ expect(out).to end_with("Bundle up to date!")
end
it "only reports gem dependencies when they can actually be updated" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack_middleware", "1.0"
G
- bundle "outdated --strict"
+ bundle :outdated, filter_strict_option => true
- expect(out).to_not include("rack (1.2")
+ expect(out).to end_with("Bundle up to date!")
end
describe "and filter options" do
it "only reports gems that match requirement and patch filter level" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "~> 2.3"
gem "weakling", ">= 0.0.1"
G
update_repo2 do
- build_gem "activesupport", %w(2.4.0 3.0.0)
+ build_gem "activesupport", %w[2.4.0 3.0.0]
build_gem "weakling", "0.0.5"
end
- bundle "outdated --strict --filter-patch"
+ bundle :outdated, filter_strict_option => true, "filter-patch" => true, :raise_on_error => false
- expect(out).to_not include("activesupport (newest")
- expect(out).to include("(newest 0.0.5, installed 0.0.3")
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ weakling 0.0.3 0.0.5 >= 0.0.1 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
it "only reports gems that match requirement and minor filter level" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "~> 2.3"
gem "weakling", ">= 0.0.1"
G
update_repo2 do
- build_gem "activesupport", %w(2.3.9)
+ build_gem "activesupport", %w[2.3.9]
build_gem "weakling", "0.1.5"
end
- bundle "outdated --strict --filter-minor"
+ bundle :outdated, filter_strict_option => true, "filter-minor" => true, :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ weakling 0.0.3 0.1.5 >= 0.0.1 default
+ TABLE
- expect(out).to_not include("activesupport (newest")
- expect(out).to include("(newest 0.1.5, installed 0.0.3")
+ expect(out).to end_with(expected_output)
end
it "only reports gems that match requirement and major filter level" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "~> 2.3"
gem "weakling", ">= 0.0.1"
G
update_repo2 do
- build_gem "activesupport", %w(2.4.0 2.5.0)
+ build_gem "activesupport", %w[2.4.0 2.5.0]
build_gem "weakling", "1.1.5"
end
- bundle "outdated --strict --filter-major"
+ bundle :outdated, filter_strict_option => true, "filter-major" => true, :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ weakling 0.0.3 1.1.5 >= 0.0.1 default
+ TABLE
- expect(out).to_not include("activesupport (newest")
- expect(out).to include("(newest 1.1.5, installed 0.0.3")
+ expect(out).to end_with(expected_output)
end
end
end
describe "with invalid gem name" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+ end
+
it "returns could not find gem name" do
- bundle "outdated invalid_gem_name"
- expect(out).to include("Could not find gem 'invalid_gem_name'.")
+ bundle "outdated invalid_gem_name", :raise_on_error => false
+ expect(err).to include("Could not find gem 'invalid_gem_name'.")
end
it "returns non-zero exit code" do
- bundle "outdated invalid_gem_name"
- expect(exitstatus).to_not be_zero if exitstatus
+ bundle "outdated invalid_gem_name", :raise_on_error => false
+ expect(exitstatus).to_not be_zero
end
end
it "performs an automatic bundle install" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
gem "foo"
G
- bundle "config auto_install 1"
- bundle :outdated
+ bundle "config set auto_install 1"
+ bundle :outdated, :raise_on_error => false
expect(out).to include("Installing foo 1.0")
end
- context "after bundle install --deployment" do
+ context "after bundle install --deployment", :bundler => "< 3" do
before do
- install_gemfile <<-G, :deployment => true
- source "file://#{gem_repo2}"
+ build_repo2
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
gem "foo"
G
+ bundle :lock
+ bundle :install, :deployment => true
end
it "outputs a helpful message about being in deployment mode" do
update_repo2 { build_gem "activesupport", "3.0" }
- bundle "outdated"
- expect(exitstatus).to_not be_zero if exitstatus
- expect(out).to include("You are trying to check outdated gems in deployment mode.")
- expect(out).to include("Run `bundle outdated` elsewhere.")
- expect(out).to include("If this is a development machine, remove the ")
- expect(out).to include("Gemfile freeze\nby running `bundle install --no-deployment`.")
+ bundle "outdated", :raise_on_error => false
+ expect(last_command).to be_failure
+ expect(err).to include("You are trying to check outdated gems in deployment mode.")
+ expect(err).to include("Run `bundle outdated` elsewhere.")
+ expect(err).to include("If this is a development machine, remove the ")
+ expect(err).to include("Gemfile freeze\nby running `bundle config unset deployment`.")
+ end
+ end
+
+ context "after bundle config set --local deployment true" do
+ before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "rack"
+ gem "foo"
+ G
+ bundle "config set --local deployment true"
+ end
+
+ it "outputs a helpful message about being in deployment mode" do
+ update_repo2 { build_gem "activesupport", "3.0" }
+
+ bundle "outdated", :raise_on_error => false
+ expect(last_command).to be_failure
+ expect(err).to include("You are trying to check outdated gems in deployment mode.")
+ expect(err).to include("Run `bundle outdated` elsewhere.")
+ expect(err).to include("If this is a development machine, remove the ")
+ expect(err).to include("Gemfile freeze\nby running `bundle config unset deployment`.")
end
end
context "update available for a gem on a different platform" do
before do
+ build_repo2
+
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "laduradura", '= 5.15.2'
G
end
it "reports that no updates are available" do
bundle "outdated"
- expect(out).to include("Bundle up to date!")
+ expect(out).to end_with("Bundle up to date!")
end
end
context "update available for a gem on the same platform while multiple platforms used for gem" do
+ before do
+ build_repo2
+ end
+
it "reports that updates are available if the Ruby platform is used" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby]
G
bundle "outdated"
- expect(out).to include("Bundle up to date!")
+ expect(out).to end_with("Bundle up to date!")
end
- it "reports that updates are available if the JRuby platform is used" do
- simulate_ruby_engine "jruby", "1.6.7" do
- simulate_platform "jruby" do
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby]
- G
+ it "reports that updates are available if the JRuby platform is used", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby]
+ G
+
+ bundle "outdated", :raise_on_error => false
- bundle "outdated"
- expect(out).to include("Outdated gems included in the bundle:")
- expect(out).to include("laduradura (newest 5.15.3, installed 5.15.2, requested = 5.15.2)")
- end
- end
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ laduradura 5.15.2 5.15.3 = 5.15.2 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
end
shared_examples_for "version update is detected" do
it "reports that a gem has a newer version" do
subject
- expect(out).to include("Outdated gems included in the bundle:")
- expect(out).to include("activesupport (newest")
- expect(out).to_not include("ERROR REPORT TEMPLATE")
+
+ outdated_gems = out.split("\n").drop_while {|l| !l.start_with?("Gem") }[1..-1]
+
+ expect(outdated_gems.size).to be > 0
end
end
shared_examples_for "major version updates are detected" do
before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
update_repo2 do
build_gem "activesupport", "3.3.5"
build_gem "weakling", "0.8.0"
@@ -491,6 +877,21 @@ RSpec.describe "bundle outdated" do
context "when on a new machine" do
before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
simulate_new_machine
update_git "foo", :path => lib_path("foo")
@@ -500,12 +901,27 @@ RSpec.describe "bundle outdated" do
end
end
- subject { bundle "outdated" }
+ subject { bundle "outdated", :raise_on_error => false }
it_behaves_like "version update is detected"
end
shared_examples_for "minor version updates are detected" do
before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
update_repo2 do
build_gem "activesupport", "2.7.5"
build_gem "weakling", "2.0.1"
@@ -517,6 +933,21 @@ RSpec.describe "bundle outdated" do
shared_examples_for "patch version updates are detected" do
before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
update_repo2 do
build_gem "activesupport", "2.3.7"
build_gem "weakling", "0.3.1"
@@ -529,15 +960,27 @@ RSpec.describe "bundle outdated" do
shared_examples_for "no version updates are detected" do
it "does not detect any version updates" do
subject
- expect(out).to include("updates to display.")
- expect(out).to_not include("ERROR REPORT TEMPLATE")
- expect(out).to_not include("activesupport (newest")
- expect(out).to_not include("weakling (newest")
+ expect(out).to end_with("updates to display.")
end
end
shared_examples_for "major version is ignored" do
before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
update_repo2 do
build_gem "activesupport", "3.3.5"
build_gem "weakling", "1.0.1"
@@ -549,6 +992,21 @@ RSpec.describe "bundle outdated" do
shared_examples_for "minor version is ignored" do
before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
update_repo2 do
build_gem "activesupport", "2.4.5"
build_gem "weakling", "0.3.1"
@@ -560,6 +1018,21 @@ RSpec.describe "bundle outdated" do
shared_examples_for "patch version is ignored" do
before do
+ build_repo2 do
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "zebra", :git => "#{lib_path("zebra")}"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "activesupport", "2.3.5"
+ gem "weakling", "~> 0.0.1"
+ gem "duradura", '7.0'
+ gem "terranova", '8'
+ G
+
update_repo2 do
build_gem "activesupport", "2.3.6"
build_gem "weakling", "0.0.4"
@@ -570,7 +1043,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major option" do
- subject { bundle "outdated --filter-major" }
+ subject { bundle "outdated --filter-major", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version is ignored"
@@ -578,7 +1051,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-minor option" do
- subject { bundle "outdated --filter-minor" }
+ subject { bundle "outdated --filter-minor", :raise_on_error => false }
it_behaves_like "minor version updates are detected"
it_behaves_like "major version is ignored"
@@ -586,7 +1059,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-patch option" do
- subject { bundle "outdated --filter-patch" }
+ subject { bundle "outdated --filter-patch", :raise_on_error => false }
it_behaves_like "patch version updates are detected"
it_behaves_like "major version is ignored"
@@ -594,7 +1067,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-minor --filter-patch options" do
- subject { bundle "outdated --filter-minor --filter-patch" }
+ subject { bundle "outdated --filter-minor --filter-patch", :raise_on_error => false }
it_behaves_like "minor version updates are detected"
it_behaves_like "patch version updates are detected"
@@ -602,7 +1075,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-minor options" do
- subject { bundle "outdated --filter-major --filter-minor" }
+ subject { bundle "outdated --filter-major --filter-minor", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version updates are detected"
@@ -610,7 +1083,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-patch options" do
- subject { bundle "outdated --filter-major --filter-patch" }
+ subject { bundle "outdated --filter-major --filter-patch", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "patch version updates are detected"
@@ -618,7 +1091,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-minor --filter-patch options" do
- subject { bundle "outdated --filter-major --filter-minor --filter-patch" }
+ subject { bundle "outdated --filter-major --filter-minor --filter-patch", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version updates are detected"
@@ -629,56 +1102,62 @@ RSpec.describe "bundle outdated" do
context "without update-strict" do
before do
build_repo4 do
- build_gem "patch", %w(1.0.0 1.0.1)
- build_gem "minor", %w(1.0.0 1.0.1 1.1.0)
- build_gem "major", %w(1.0.0 1.0.1 1.1.0 2.0.0)
+ build_gem "patch", %w[1.0.0 1.0.1]
+ build_gem "minor", %w[1.0.0 1.0.1 1.1.0]
+ build_gem "major", %w[1.0.0 1.0.1 1.1.0 2.0.0]
end
# establish a lockfile set to 1.0.0
install_gemfile <<-G
- source "file://#{gem_repo4}"
- gem 'patch', '1.0.0'
- gem 'minor', '1.0.0'
- gem 'major', '1.0.0'
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'patch', '1.0.0'
+ gem 'minor', '1.0.0'
+ gem 'major', '1.0.0'
G
# remove 1.4.3 requirement and bar altogether
# to setup update specs below
gemfile <<-G
- source "file://#{gem_repo4}"
- gem 'patch'
- gem 'minor'
- gem 'major'
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'patch'
+ gem 'minor'
+ gem 'major'
G
end
it "shows nothing when patching and filtering to minor" do
bundle "outdated --patch --filter-minor"
- expect(out).to include("No minor updates to display.")
- expect(out).not_to include("patch (newest")
- expect(out).not_to include("minor (newest")
- expect(out).not_to include("major (newest")
+ expect(out).to end_with("No minor updates to display.")
end
it "shows all gems when patching and filtering to patch" do
- bundle "outdated --patch --filter-patch"
+ bundle "outdated --patch --filter-patch", :raise_on_error => false
- expect(out).to include("patch (newest 1.0.1")
- expect(out).to include("minor (newest 1.0.1")
- expect(out).to include("major (newest 1.0.1")
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ major 1.0.0 1.0.1 >= 0 default
+ minor 1.0.0 1.0.1 >= 0 default
+ patch 1.0.0 1.0.1 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
it "shows minor and major when updating to minor and filtering to patch and minor" do
- bundle "outdated --minor --filter-minor"
+ bundle "outdated --minor --filter-minor", :raise_on_error => false
- expect(out).not_to include("patch (newest")
- expect(out).to include("minor (newest 1.1.0")
- expect(out).to include("major (newest 1.1.0")
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ major 1.0.0 1.1.0 >= 0 default
+ minor 1.0.0 1.1.0 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
it "shows minor when updating to major and filtering to minor with parseable" do
- bundle "outdated --major --filter-minor --parseable"
+ bundle "outdated --major --filter-minor --parseable", :raise_on_error => false
expect(out).not_to include("patch (newest")
expect(out).to include("minor (newest")
@@ -689,22 +1168,22 @@ RSpec.describe "bundle outdated" do
context "with update-strict" do
before do
build_repo4 do
- build_gem "foo", %w(1.4.3 1.4.4) do |s|
+ build_gem "foo", %w[1.4.3 1.4.4] do |s|
s.add_dependency "bar", "~> 2.0"
end
- build_gem "foo", %w(1.4.5 1.5.0) do |s|
+ build_gem "foo", %w[1.4.5 1.5.0] do |s|
s.add_dependency "bar", "~> 2.1"
end
- build_gem "foo", %w(1.5.1) do |s|
+ build_gem "foo", %w[1.5.1] do |s|
s.add_dependency "bar", "~> 3.0"
end
- build_gem "bar", %w(2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0)
- build_gem "qux", %w(1.0.0 1.1.0 2.0.0)
+ build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
+ build_gem "qux", %w[1.0.0 1.1.0 2.0.0]
end
# establish a lockfile set to 1.4.3
install_gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'foo', '1.4.3'
gem 'bar', '2.0.3'
gem 'qux', '1.0.0'
@@ -713,19 +1192,153 @@ RSpec.describe "bundle outdated" do
# remove 1.4.3 requirement and bar altogether
# to setup update specs below
gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'foo'
gem 'qux'
G
end
it "shows gems with update-strict updating to patch and filtering to patch" do
- bundle "outdated --patch --update-strict --filter-patch"
+ bundle "outdated --patch --update-strict --filter-patch", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ bar 2.0.3 2.0.5
+ foo 1.4.3 1.4.4 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+ end
+ end
- expect(out).to include("foo (newest 1.4.4")
- expect(out).to include("bar (newest 2.0.5")
- expect(out).not_to include("qux (newest")
+ describe "with --only-explicit" do
+ it "does not report outdated dependent gems" do
+ build_repo4 do
+ build_gem "weakling", %w[0.2 0.3] do |s|
+ s.add_dependency "bar", "~> 2.1"
+ end
+ build_gem "bar", %w[2.1 2.2]
end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'weakling', '0.2'
+ gem 'bar', '2.1'
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'weakling'
+ G
+
+ bundle "outdated --only-explicit", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ weakling 0.2 0.3 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+ end
+
+ describe "with a multiplatform lockfile" do
+ before do
+ build_repo4 do
+ build_gem "nokogiri", "1.11.1"
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.platform = Bundler.local_platform
+ end
+
+ build_gem "nokogiri", "1.11.2"
+ build_gem "nokogiri", "1.11.2" do |s|
+ s.platform = Bundler.local_platform
+ end
+ end
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.11.1)
+ nokogiri (1.11.1-#{Bundler.local_platform})
+
+ PLATFORMS
+ ruby
+ #{Bundler.local_platform}
+
+ DEPENDENCIES
+ nokogiri
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "nokogiri"
+ G
+ end
+
+ it "reports a single entry per gem" do
+ bundle "outdated", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ nokogiri 1.11.1 1.11.2 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+ end
+
+ context "when a gem is no longer a dependency after a full update" do
+ before do
+ build_repo4 do
+ build_gem "mini_portile2", "2.5.2" do |s|
+ s.add_dependency "net-ftp", "~> 0.1"
+ end
+
+ build_gem "mini_portile2", "2.5.3"
+
+ build_gem "net-ftp", "0.1.2"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "mini_portile2"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ mini_portile2 (2.5.2)
+ net-ftp (~> 0.1)
+ net-ftp (0.1.2)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ mini_portile2
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "works" do
+ bundle "outdated", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ mini_portile2 2.5.2 2.5.3 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
end
end
diff --git a/spec/bundler/commands/package_spec.rb b/spec/bundler/commands/package_spec.rb
deleted file mode 100644
index 86c09db3ca..0000000000
--- a/spec/bundler/commands/package_spec.rb
+++ /dev/null
@@ -1,306 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-
-RSpec.describe "bundle package" do
- context "with --gemfile" do
- it "finds the gemfile" do
- gemfile bundled_app("NotGemfile"), <<-G
- source "file://#{gem_repo1}"
- gem 'rack'
- G
-
- bundle "package --gemfile=NotGemfile"
-
- ENV["BUNDLE_GEMFILE"] = "NotGemfile"
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
- end
-
- context "with --all" do
- context "without a gemspec" do
- it "caches all dependencies except bundler itself" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack'
- gem 'bundler'
- D
-
- bundle "package --all"
-
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
- end
- end
-
- context "with a gemspec" do
- context "that has the same name as the gem" do
- before do
- File.open(bundled_app("mygem.gemspec"), "w") do |f|
- f.write <<-G
- Gem::Specification.new do |s|
- s.name = "mygem"
- s.version = "0.1.1"
- s.summary = ""
- s.authors = ["gem author"]
- s.add_development_dependency "nokogiri", "=1.4.2"
- end
- G
- end
- end
-
- it "caches all dependencies except bundler and the gemspec specified gem" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack'
- gemspec
- D
-
- bundle! "package --all"
-
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
- expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
- expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
- end
- end
-
- context "that has a different name as the gem" do
- before do
- File.open(bundled_app("mygem_diffname.gemspec"), "w") do |f|
- f.write <<-G
- Gem::Specification.new do |s|
- s.name = "mygem"
- s.version = "0.1.1"
- s.summary = ""
- s.authors = ["gem author"]
- s.add_development_dependency "nokogiri", "=1.4.2"
- end
- G
- end
- end
-
- it "caches all dependencies except bundler and the gemspec specified gem" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack'
- gemspec
- D
-
- bundle! "package --all"
-
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
- expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
- expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
- end
- end
- end
-
- context "with multiple gemspecs" do
- before do
- File.open(bundled_app("mygem.gemspec"), "w") do |f|
- f.write <<-G
- Gem::Specification.new do |s|
- s.name = "mygem"
- s.version = "0.1.1"
- s.summary = ""
- s.authors = ["gem author"]
- s.add_development_dependency "nokogiri", "=1.4.2"
- end
- G
- end
- File.open(bundled_app("mygem_client.gemspec"), "w") do |f|
- f.write <<-G
- Gem::Specification.new do |s|
- s.name = "mygem_test"
- s.version = "0.1.1"
- s.summary = ""
- s.authors = ["gem author"]
- s.add_development_dependency "weakling", "=0.0.3"
- end
- G
- end
- end
-
- it "caches all dependencies except bundler and the gemspec specified gems" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack'
- gemspec :name => 'mygem'
- gemspec :name => 'mygem_test'
- D
-
- bundle! "package --all"
-
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
- expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
- expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
- expect(bundled_app("vendor/cache/mygem_test-0.1.1.gem")).to_not exist
- expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
- end
- end
- end
-
- context "with --path" do
- it "sets root directory for gems" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack'
- D
-
- bundle "package --path=#{bundled_app("test")}"
-
- expect(the_bundle).to include_gems "rack 1.0.0"
- expect(bundled_app("test/vendor/cache/")).to exist
- end
- end
-
- context "with --no-install" do
- it "puts the gems in vendor/cache but does not install them" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack'
- D
-
- bundle "package --no-install"
-
- expect(the_bundle).not_to include_gems "rack 1.0.0"
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- end
-
- it "does not prevent installing gems with bundle install" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack'
- D
-
- bundle "package --no-install"
- bundle "install"
-
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
- end
-
- context "with --all-platforms" do
- it "puts the gems in vendor/cache even for other rubies", :ruby => "2.1" do
- gemfile <<-D
- source "file://#{gem_repo1}"
- gem 'rack', :platforms => :ruby_19
- D
-
- bundle "package --all-platforms"
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- end
- end
-
- context "with --frozen" do
- before do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
- bundle "install"
- end
-
- subject { bundle "package --frozen" }
-
- it "tries to install with frozen" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- gem "rack-obama"
- G
- subject
- expect(exitstatus).to eq(16) if exitstatus
- expect(out).to include("deployment mode")
- expect(out).to include("You have added to the Gemfile")
- expect(out).to include("* rack-obama")
- bundle "env"
- expect(out).to include("frozen")
- end
- end
-end
-
-RSpec.describe "bundle install with gem sources" do
- describe "when cached and locked" do
- it "does not hit the remote at all" do
- build_repo2
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "rack"
- G
-
- bundle :pack
- simulate_new_machine
- FileUtils.rm_rf gem_repo2
-
- bundle "install --local"
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
-
- it "does not hit the remote at all" do
- build_repo2
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "rack"
- G
-
- bundle :pack
- simulate_new_machine
- FileUtils.rm_rf gem_repo2
-
- bundle "install --deployment"
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
-
- it "does not reinstall already-installed gems" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
- bundle :pack
-
- build_gem "rack", "1.0.0", :path => bundled_app("vendor/cache") do |s|
- s.write "lib/rack.rb", "raise 'omg'"
- end
-
- bundle :install
- expect(err).to lack_errors
- expect(the_bundle).to include_gems "rack 1.0"
- end
-
- it "ignores cached gems for the wrong platform" do
- simulate_platform "java" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "platform_specific"
- G
- bundle :pack
- end
-
- simulate_new_machine
-
- simulate_platform "ruby" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "platform_specific"
- G
- run "require 'platform_specific' ; puts PLATFORM_SPECIFIC"
- expect(out).to eq("1.0.0 RUBY")
- end
- end
-
- it "does not update the cache if --no-cache is passed" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
- bundled_app("vendor/cache").mkpath
- expect(bundled_app("vendor/cache").children).to be_empty
-
- bundle "install --no-cache"
- expect(bundled_app("vendor/cache").children).to be_empty
- end
- end
-end
diff --git a/spec/bundler/commands/post_bundle_message_spec.rb b/spec/bundler/commands/post_bundle_message_spec.rb
new file mode 100644
index 0000000000..3050b87754
--- /dev/null
+++ b/spec/bundler/commands/post_bundle_message_spec.rb
@@ -0,0 +1,205 @@
+# frozen_string_literal: true
+
+RSpec.describe "post bundle message" do
+ before :each do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", "2.3.5", :group => [:emo, :test]
+ group :test do
+ gem "rspec"
+ end
+ gem "rack-obama", :group => :obama
+ G
+ end
+
+ let(:bundle_path) { "./.bundle" }
+ let(:bundle_show_system_message) { "Use `bundle info [gemname]` to see where a bundled gem is installed." }
+ let(:bundle_show_path_message) { "Bundled gems are installed into `#{bundle_path}`" }
+ let(:bundle_complete_message) { "Bundle complete!" }
+ let(:bundle_updated_message) { "Bundle updated!" }
+ let(:installed_gems_stats) { "4 Gemfile dependencies, 5 gems now installed." }
+ let(:bundle_show_message) { Bundler::VERSION.split(".").first.to_i < 3 ? bundle_show_system_message : bundle_show_path_message }
+
+ describe "for fresh bundle install" do
+ it "shows proper messages according to the configured groups" do
+ bundle :install
+ expect(out).to include(bundle_show_message)
+ expect(out).not_to include("Gems in the group")
+ expect(out).to include(bundle_complete_message)
+ expect(out).to include(installed_gems_stats)
+
+ bundle "config set --local without emo"
+ bundle :install
+ expect(out).to include(bundle_show_message)
+ expect(out).to include("Gems in the group 'emo' were not installed")
+ expect(out).to include(bundle_complete_message)
+ expect(out).to include(installed_gems_stats)
+
+ bundle "config set --local without emo test"
+ bundle :install
+ expect(out).to include(bundle_show_message)
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
+ expect(out).to include(bundle_complete_message)
+ expect(out).to include("4 Gemfile dependencies, 3 gems now installed.")
+
+ bundle "config set --local without emo obama test"
+ bundle :install
+ expect(out).to include(bundle_show_message)
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
+ expect(out).to include(bundle_complete_message)
+ expect(out).to include("4 Gemfile dependencies, 2 gems now installed.")
+ end
+
+ describe "with `path` configured" do
+ let(:bundle_path) { "./vendor" }
+
+ it "shows proper messages according to the configured groups" do
+ bundle "config set --local path vendor"
+ bundle :install
+ expect(out).to include(bundle_show_path_message)
+ expect(out).to_not include("Gems in the group")
+ expect(out).to include(bundle_complete_message)
+
+ bundle "config set --local path vendor"
+ bundle "config set --local without emo"
+ bundle :install
+ expect(out).to include(bundle_show_path_message)
+ expect(out).to include("Gems in the group 'emo' were not installed")
+ expect(out).to include(bundle_complete_message)
+
+ bundle "config set --local path vendor"
+ bundle "config set --local without emo test"
+ bundle :install
+ expect(out).to include(bundle_show_path_message)
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
+ expect(out).to include(bundle_complete_message)
+
+ bundle "config set --local path vendor"
+ bundle "config set --local without emo obama test"
+ bundle :install
+ expect(out).to include(bundle_show_path_message)
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
+ expect(out).to include(bundle_complete_message)
+ end
+ end
+
+ describe "with an absolute `path` inside the cwd configured" do
+ let(:bundle_path) { bundled_app("cache") }
+
+ it "shows proper messages according to the configured groups" do
+ bundle "config set --local path #{bundle_path}"
+ bundle :install
+ expect(out).to include("Bundled gems are installed into `./cache`")
+ expect(out).to_not include("Gems in the group")
+ expect(out).to include(bundle_complete_message)
+ end
+ end
+
+ describe "with `path` configured to an absolute path outside the cwd" do
+ let(:bundle_path) { tmp("not_bundled_app") }
+
+ it "shows proper messages according to the configured groups" do
+ bundle "config set --local path #{bundle_path}"
+ bundle :install
+ expect(out).to include("Bundled gems are installed into `#{tmp("not_bundled_app")}`")
+ expect(out).to_not include("Gems in the group")
+ expect(out).to include(bundle_complete_message)
+ end
+ end
+
+ describe "with misspelled or non-existent gem name" do
+ before do
+ bundle "config set force_ruby_platform true"
+ end
+
+ it "should report a helpful error message" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "not-a-gem", :group => :development
+ G
+ expect(err).to include <<-EOS.strip
+Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}/ or installed locally.
+ EOS
+ end
+
+ it "should report a helpful error message with reference to cache if available" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ bundle :cache
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "not-a-gem", :group => :development
+ G
+ expect(err).to include("Could not find gem 'not-a-gem' in").
+ and include("or in gems cached in vendor/cache.")
+ end
+ end
+ end
+
+ describe "for second bundle install run", :bundler => "< 3" do
+ it "without any options" do
+ 2.times { bundle :install }
+ expect(out).to include(bundle_show_message)
+ expect(out).to_not include("Gems in the groups")
+ expect(out).to include(bundle_complete_message)
+ expect(out).to include(installed_gems_stats)
+ end
+
+ it "with --without one group" do
+ bundle "install --without emo"
+ bundle :install
+ expect(out).to include(bundle_show_message)
+ expect(out).to include("Gems in the group 'emo' were not installed")
+ expect(out).to include(bundle_complete_message)
+ expect(out).to include(installed_gems_stats)
+ end
+
+ it "with --without two groups" do
+ bundle "install --without emo test"
+ bundle :install
+ expect(out).to include(bundle_show_message)
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
+ expect(out).to include(bundle_complete_message)
+ end
+
+ it "with --without more groups" do
+ bundle "install --without emo obama test"
+ bundle :install
+ expect(out).to include(bundle_show_message)
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
+ expect(out).to include(bundle_complete_message)
+ end
+ end
+
+ describe "for bundle update" do
+ it "shows proper messages according to the configured groups" do
+ bundle :update, :all => true
+ expect(out).not_to include("Gems in the groups")
+ expect(out).to include(bundle_updated_message)
+
+ bundle "config set --local without emo"
+ bundle :install
+ bundle :update, :all => true
+ expect(out).to include("Gems in the group 'emo' were not updated")
+ expect(out).to include(bundle_updated_message)
+
+ bundle "config set --local without emo test"
+ bundle :install
+ bundle :update, :all => true
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not updated")
+ expect(out).to include(bundle_updated_message)
+
+ bundle "config set --local without emo obama test"
+ bundle :install
+ bundle :update, :all => true
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not updated")
+ expect(out).to include(bundle_updated_message)
+ end
+ end
+end
diff --git a/spec/bundler/commands/pristine_spec.rb b/spec/bundler/commands/pristine_spec.rb
index 3aca313e0f..2f730bd4e2 100644
--- a/spec/bundler/commands/pristine_spec.rb
+++ b/spec/bundler/commands/pristine_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require "spec_helper"
-require "fileutils"
+
+require "bundler/vendored_fileutils"
RSpec.describe "bundle pristine", :ruby_repo do
before :each do
@@ -14,23 +14,27 @@ RSpec.describe "bundle pristine", :ruby_repo do
build_gem "baz-dev", "1.0.0"
build_gem "very_simple_binary", &:add_c_extension
build_git "foo", :path => lib_path("foo")
+ build_git "git_with_ext", :path => lib_path("git_with_ext"), &:add_c_extension
build_lib "bar", :path => lib_path("bar")
end
- install_gemfile! <<-G
- source "file://#{gem_repo2}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
gem "weakling"
gem "very_simple_binary"
- gem "foo", :git => "#{lib_path("foo")}"
+ gem "foo", :git => "#{lib_path("foo")}", :branch => "master"
+ gem "git_with_ext", :git => "#{lib_path("git_with_ext")}"
gem "bar", :path => "#{lib_path("bar")}"
gemspec
G
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
- context "when sourced from Rubygems" do
+ context "when sourced from RubyGems" do
it "reverts using cached .gem file" do
- spec = Bundler.definition.specs["weakling"].first
+ spec = find_spec("weakling")
changes_txt = Pathname.new(spec.full_gem_path).join("lib/changes.txt")
FileUtils.touch(changes_txt)
@@ -40,46 +44,76 @@ RSpec.describe "bundle pristine", :ruby_repo do
expect(changes_txt).to_not be_file
end
- it "does not delete the bundler gem", :ruby_repo do
- system_gems :bundler
- bundle! "install"
- bundle! "pristine", :system_bundler => true
- bundle! "-v", :system_bundler => true
- expect(out).to end_with(Bundler::VERSION)
+ it "does not delete the bundler gem" do
+ bundle "install"
+ bundle "pristine"
+ bundle "-v"
+
+ expected = if Bundler::VERSION < "3.0"
+ "Bundler version"
+ else
+ Bundler::VERSION
+ end
+
+ expect(out).to start_with(expected)
end
end
context "when sourced from git repo" do
it "reverts by resetting to current revision`" do
- spec = Bundler.definition.specs["foo"].first
+ spec = find_spec("foo")
changed_file = Pathname.new(spec.full_gem_path).join("lib/foo.rb")
diff = "#Pristine spec changes"
- File.open(changed_file, "a") {|f| f.puts "#Pristine spec changes" }
+ File.open(changed_file, "a") {|f| f.puts diff }
expect(File.read(changed_file)).to include(diff)
bundle "pristine"
expect(File.read(changed_file)).to_not include(diff)
end
+
+ it "removes added files" do
+ spec = find_spec("foo")
+ changes_txt = Pathname.new(spec.full_gem_path).join("lib/changes.txt")
+
+ FileUtils.touch(changes_txt)
+ expect(changes_txt).to be_file
+
+ bundle "pristine"
+ expect(changes_txt).not_to be_file
+ end
+
+ it "displays warning and ignores changes when a local config exists" do
+ spec = find_spec("foo")
+ bundle "config set local.#{spec.name} #{lib_path(spec.name)}"
+
+ changes_txt = Pathname.new(spec.full_gem_path).join("lib/changes.txt")
+ FileUtils.touch(changes_txt)
+ expect(changes_txt).to be_file
+
+ bundle "pristine"
+ expect(changes_txt).to be_file
+ expect(err).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is locally overridden.")
+ end
end
context "when sourced from gemspec" do
it "displays warning and ignores changes when sourced from gemspec" do
- spec = Bundler.definition.specs["baz"].first
+ spec = find_spec("baz")
changed_file = Pathname.new(spec.full_gem_path).join("lib/baz.rb")
diff = "#Pristine spec changes"
- File.open(changed_file, "a") {|f| f.puts "#Pristine spec changes" }
+ File.open(changed_file, "a") {|f| f.puts diff }
expect(File.read(changed_file)).to include(diff)
bundle "pristine"
expect(File.read(changed_file)).to include(diff)
- expect(out).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is sourced from local path.")
+ expect(err).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is sourced from local path.")
end
it "reinstall gemspec dependency" do
- spec = Bundler.definition.specs["baz-dev"].first
- changed_file = Pathname.new(spec.full_gem_path).join("lib/baz-dev.rb")
+ spec = find_spec("baz-dev")
+ changed_file = Pathname.new(spec.full_gem_path).join("lib/baz/dev.rb")
diff = "#Pristine spec changes"
File.open(changed_file, "a") {|f| f.puts "#Pristine spec changes" }
@@ -92,30 +126,96 @@ RSpec.describe "bundle pristine", :ruby_repo do
context "when sourced from path" do
it "displays warning and ignores changes when sourced from local path" do
- spec = Bundler.definition.specs["bar"].first
+ spec = find_spec("bar")
changes_txt = Pathname.new(spec.full_gem_path).join("lib/changes.txt")
FileUtils.touch(changes_txt)
expect(changes_txt).to be_file
bundle "pristine"
- expect(out).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is sourced from local path.")
+ expect(err).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is sourced from local path.")
expect(changes_txt).to be_file
end
end
+ context "when passing a list of gems to pristine" do
+ it "resets them" do
+ foo = find_spec("foo")
+ foo_changes_txt = Pathname.new(foo.full_gem_path).join("lib/changes.txt")
+ FileUtils.touch(foo_changes_txt)
+ expect(foo_changes_txt).to be_file
+
+ bar = find_spec("bar")
+ bar_changes_txt = Pathname.new(bar.full_gem_path).join("lib/changes.txt")
+ FileUtils.touch(bar_changes_txt)
+ expect(bar_changes_txt).to be_file
+
+ weakling = find_spec("weakling")
+ weakling_changes_txt = Pathname.new(weakling.full_gem_path).join("lib/changes.txt")
+ FileUtils.touch(weakling_changes_txt)
+ expect(weakling_changes_txt).to be_file
+
+ bundle "pristine foo bar weakling"
+
+ expect(err).to include("Cannot pristine bar (1.0). Gem is sourced from local path.")
+ expect(out).to include("Installing weakling 1.0")
+
+ expect(weakling_changes_txt).not_to be_file
+ expect(foo_changes_txt).not_to be_file
+ expect(bar_changes_txt).to be_file
+ end
+
+ it "raises when one of them is not in the lockfile" do
+ bundle "pristine abcabcabc", :raise_on_error => false
+ expect(err).to include("Could not find gem 'abcabcabc'.")
+ end
+ end
+
context "when a build config exists for one of the gems" do
- let(:very_simple_binary) { Bundler.definition.specs["very_simple_binary"].first }
+ let(:very_simple_binary) { find_spec("very_simple_binary") }
let(:c_ext_dir) { Pathname.new(very_simple_binary.full_gem_path).join("ext") }
let(:build_opt) { "--with-ext-lib=#{c_ext_dir}" }
- before { bundle "config build.very_simple_binary -- #{build_opt}" }
+ before { bundle "config set build.very_simple_binary -- #{build_opt}" }
+
+ # This just verifies that the generated Makefile from the c_ext gem makes
+ # use of the build_args from the bundle config
+ it "applies the config when installing the gem" do
+ bundle "pristine"
+
+ makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
+ expect(makefile_contents).to match(/libpath =.*#{c_ext_dir}/)
+ expect(makefile_contents).to match(/LIBPATH =.*-L#{c_ext_dir}/)
+ end
+ end
+
+ context "when a build config exists for a git sourced gem" do
+ let(:git_with_ext) { find_spec("git_with_ext") }
+ let(:c_ext_dir) { Pathname.new(git_with_ext.full_gem_path).join("ext") }
+ let(:build_opt) { "--with-ext-lib=#{c_ext_dir}" }
+ before { bundle "config set build.git_with_ext -- #{build_opt}" }
# This just verifies that the generated Makefile from the c_ext gem makes
# use of the build_args from the bundle config
it "applies the config when installing the gem" do
- bundle! "pristine"
+ bundle "pristine"
makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
expect(makefile_contents).to match(/libpath =.*#{c_ext_dir}/)
expect(makefile_contents).to match(/LIBPATH =.*-L#{c_ext_dir}/)
end
end
+
+ context "when BUNDLE_GEMFILE doesn't exist" do
+ before do
+ bundle "pristine", :env => { "BUNDLE_GEMFILE" => "does/not/exist" }, :raise_on_error => false
+ end
+
+ it "shows a meaningful error" do
+ expect(err).to eq("#{bundled_app("does/not/exist")} not found")
+ end
+ end
+
+ def find_spec(name)
+ without_env_side_effects do
+ Bundler.definition.specs[name].first
+ end
+ end
end
diff --git a/spec/bundler/commands/remove_spec.rb b/spec/bundler/commands/remove_spec.rb
new file mode 100644
index 0000000000..95d6e75e9f
--- /dev/null
+++ b/spec/bundler/commands/remove_spec.rb
@@ -0,0 +1,702 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle remove" do
+ context "when no gems are specified" do
+ it "throws error" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
+ bundle "remove", :raise_on_error => false
+
+ expect(err).to include("Please specify gems to remove.")
+ end
+ end
+
+ context "when --install flag is specified", :bundler => "< 3" do
+ it "removes gems from .bundle" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ G
+
+ bundle "remove rack --install"
+
+ expect(out).to include("rack was removed.")
+ expect(the_bundle).to_not include_gems "rack"
+ end
+ end
+
+ describe "remove single gem from gemfile" do
+ context "when gem is present in gemfile" do
+ it "shows success for removed gem" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(the_bundle).to_not include_gems "rack"
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+
+ context "when gem is specified in multiple lines" do
+ it "shows success for removed gem" do
+ build_git "rack"
+
+ gemfile <<-G
+ source '#{file_uri_for(gem_repo1)}'
+
+ gem 'git'
+ gem 'rack',
+ git: "#{lib_path("rack-1.0")}",
+ branch: 'master'
+ gem 'nokogiri'
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source '#{file_uri_for(gem_repo1)}'
+
+ gem 'git'
+ gem 'nokogiri'
+ G
+ end
+ end
+ end
+
+ context "when gem is not present in gemfile" do
+ it "shows warning for gem that could not be removed" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
+ bundle "remove rack", :raise_on_error => false
+
+ expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
+ end
+ end
+ end
+
+ describe "remove multiple gems from gemfile" do
+ context "when all gems are present in gemfile" do
+ it "shows success fir all removed gems" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ gem "rails"
+ G
+
+ bundle "remove rack rails"
+
+ expect(out).to include("rack was removed.")
+ expect(out).to include("rails was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "when some gems are not present in the gemfile" do
+ it "shows warning for those not present and success for those that can be removed" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rails"
+ gem "minitest"
+ gem "rspec"
+ G
+
+ bundle "remove rails rack minitest", :raise_on_error => false
+
+ expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rails"
+ gem "minitest"
+ gem "rspec"
+ G
+ end
+ end
+ end
+
+ context "with inline groups" do
+ it "removes the specified gem" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack", :group => [:dev]
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ describe "with group blocks" do
+ context "when single group block with gem to be removed is present" do
+ it "removes the group block" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ gem "rspec"
+ end
+ G
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "when gem to be removed is outside block" do
+ it "does not modify group" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ group :test do
+ gem "coffee-script-source"
+ end
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ gem "coffee-script-source"
+ end
+ G
+ end
+ end
+
+ context "when an empty block is also present" do
+ it "removes all empty blocks" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ gem "rspec"
+ end
+
+ group :dev do
+ end
+ G
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "when the gem belongs to multiple groups" do
+ it "removes the groups" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test, :serioustest do
+ gem "rspec"
+ end
+ G
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "when the gem is present in multiple groups" do
+ it "removes all empty blocks" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :one do
+ gem "rspec"
+ end
+
+ group :two do
+ gem "rspec"
+ end
+ G
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+ end
+
+ describe "nested group blocks" do
+ context "when all the groups will be empty after removal" do
+ it "removes the empty nested blocks" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ group :serioustest do
+ gem "rspec"
+ end
+ end
+ G
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "when outer group will not be empty after removal" do
+ it "removes only empty blocks" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ gem "rack-test"
+
+ group :serioustest do
+ gem "rspec"
+ end
+ end
+ G
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ gem "rack-test"
+
+ end
+ G
+ end
+ end
+
+ context "when inner group will not be empty after removal" do
+ it "removes only empty blocks" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ group :serioustest do
+ gem "rspec"
+ gem "rack-test"
+ end
+ end
+ G
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ group :test do
+ group :serioustest do
+ gem "rack-test"
+ end
+ end
+ G
+ end
+ end
+ end
+
+ describe "arbitrary gemfile" do
+ context "when multiple gems are present in same line" do
+ it "shows warning for gems not removed" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"; gem "rails"
+ G
+
+ bundle "remove rails", :raise_on_error => false
+
+ expect(err).to include("Gems could not be removed. rack (>= 0) would also have been removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"; gem "rails"
+ G
+ end
+ end
+
+ context "when some gems could not be removed" do
+ it "shows warning for gems not removed and success for those removed" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ gem"rack"
+ gem"rspec"
+ gem "rails"
+ gem "minitest"
+ G
+
+ bundle "remove rails rack rspec minitest"
+
+ expect(out).to include("rails was removed.")
+ expect(out).to include("minitest was removed.")
+ expect(out).to include("rack, rspec could not be removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ gem"rack"
+ gem"rspec"
+ G
+ end
+ end
+ end
+
+ context "with sources" do
+ before do
+ build_repo gem_repo3 do
+ build_gem "rspec"
+ end
+ end
+
+ it "removes gems and empty source blocks" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+
+ source "#{file_uri_for(gem_repo3)}" do
+ gem "rspec"
+ end
+ G
+
+ bundle "install"
+
+ bundle "remove rspec"
+
+ expect(out).to include("rspec was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ G
+ end
+ end
+
+ describe "with eval_gemfile" do
+ context "when gems are present in both gemfiles" do
+ it "removes the gems" do
+ create_file "Gemfile-other", <<-G
+ gem "rack"
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+
+ gem "rack"
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ end
+ end
+
+ context "when gems are present in other gemfile" do
+ it "removes the gems" do
+ create_file "Gemfile-other", <<-G
+ gem "rack"
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ G
+
+ bundle "remove rack"
+
+ expect(bundled_app("Gemfile-other").read).to_not include("gem \"rack\"")
+ expect(out).to include("rack was removed.")
+ end
+ end
+
+ context "when gems to be removed are not specified in any of the gemfiles" do
+ it "throws error for the gems not present" do
+ # an empty gemfile
+ # indicating the gem is not present in the gemfile
+ create_file "Gemfile-other", <<-G
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ G
+
+ bundle "remove rack", :raise_on_error => false
+
+ expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
+ end
+ end
+
+ context "when the gem is present in parent file but not in gemfile specified by eval_gemfile" do
+ it "removes the gem" do
+ create_file "Gemfile-other", <<-G
+ gem "rails"
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ gem "rack"
+ G
+
+ bundle "remove rack", :raise_on_error => false
+
+ expect(out).to include("rack was removed.")
+ expect(err).to include("`rack` is not specified in #{bundled_app("Gemfile-other")} so it could not be removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ G
+ end
+ end
+
+ context "when gems can not be removed from other gemfile" do
+ it "shows error" do
+ create_file "Gemfile-other", <<-G
+ gem "rails"; gem "rack"
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ gem "rack"
+ G
+
+ bundle "remove rack", :raise_on_error => false
+
+ expect(out).to include("rack was removed.")
+ expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ G
+ end
+ end
+
+ context "when gems could not be removed from parent gemfile" do
+ it "shows error" do
+ create_file "Gemfile-other", <<-G
+ gem "rack"
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ gem "rails"; gem "rack"
+ G
+
+ bundle "remove rack", :raise_on_error => false
+
+ expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.")
+ expect(bundled_app("Gemfile-other").read).to include("gem \"rack\"")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ gem "rails"; gem "rack"
+ G
+ end
+ end
+
+ context "when gem present in gemfiles but could not be removed from one from one of them" do
+ it "removes gem which can be removed and shows warning for file from which it can not be removed" do
+ create_file "Gemfile-other", <<-G
+ gem "rack"
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ eval_gemfile "Gemfile-other"
+ gem"rack"
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(bundled_app("Gemfile-other").read).to_not include("gem \"rack\"")
+ end
+ end
+ end
+
+ context "with install_if" do
+ it "removes gems inside blocks and empty blocks" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ install_if(lambda { false }) do
+ gem "rack"
+ end
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "with env" do
+ it "removes gems inside blocks and empty blocks" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ env "BUNDLER_TEST" do
+ gem "rack"
+ end
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "with gemspec" do
+ it "should not remove the gem" do
+ build_lib("foo", :path => tmp.join("foo")) do |s|
+ s.write("foo.gemspec", "")
+ s.add_dependency "rack"
+ end
+
+ install_gemfile(<<-G)
+ source "#{file_uri_for(gem_repo1)}"
+ gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
+ G
+
+ bundle "remove foo"
+
+ expect(out).to include("foo could not be removed.")
+ end
+ end
+
+ describe "with comments that mention gems" do
+ context "when comment is a separate line comment" do
+ it "does not remove the line comment" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ # gem "rack" might be used in the future
+ gem "rack"
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ # gem "rack" might be used in the future
+ G
+ end
+ end
+
+ context "when gem specified for removal has an inline comment" do
+ it "removes the inline comment" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack" # this can be removed
+ G
+
+ bundle "remove rack"
+
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+ end
+
+ context "when gem specified for removal is mentioned in other gem's comment" do
+ it "does not remove other gem" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "puma" # implements interface provided by gem "rack"
+
+ gem "rack"
+ G
+
+ bundle "remove rack"
+
+ expect(out).to_not include("puma was removed.")
+ expect(out).to include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "puma" # implements interface provided by gem "rack"
+ G
+ end
+ end
+
+ context "when gem specified for removal has a comment that mentions other gem" do
+ it "does not remove other gem" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "puma" # implements interface provided by gem "rack"
+
+ gem "rack"
+ G
+
+ bundle "remove puma"
+
+ expect(out).to include("puma was removed.")
+ expect(out).to_not include("rack was removed.")
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ G
+ end
+ end
+ end
+end
diff --git a/spec/bundler/commands/show_spec.rb b/spec/bundler/commands/show_spec.rb
index fc34831a72..2adb121616 100644
--- a/spec/bundler/commands/show_spec.rb
+++ b/spec/bundler/commands/show_spec.rb
@@ -1,29 +1,28 @@
# frozen_string_literal: true
-require "spec_helper"
-RSpec.describe "bundle show" do
+RSpec.describe "bundle show", :bundler => "< 3" do
context "with a standard Gemfile" do
before :each do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
end
it "creates a Gemfile.lock if one did not exist" do
- FileUtils.rm("Gemfile.lock")
+ FileUtils.rm(bundled_app_lock)
bundle "show"
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
it "creates a Gemfile.lock when invoked with a gem name" do
- FileUtils.rm("Gemfile.lock")
+ FileUtils.rm(bundled_app_lock)
bundle "show rails"
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
it "prints path if gem exists in bundle" do
@@ -31,13 +30,18 @@ RSpec.describe "bundle show" do
expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
end
+ it "prints path if gem exists in bundle (with --paths option)" do
+ bundle "show rails --paths"
+ expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
+ end
+
it "warns if path no longer exists on disk" do
- FileUtils.rm_rf("#{system_gem_path}/gems/rails-2.3.2")
+ FileUtils.rm_rf(default_bundle_path("gems", "rails-2.3.2"))
bundle "show rails"
- expect(out).to match(/has been deleted/i)
- expect(out).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
+ expect(err).to match(/has been deleted/i)
+ expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
end
it "prints the path to the running bundler" do
@@ -46,14 +50,14 @@ RSpec.describe "bundle show" do
end
it "complains if gem not in bundle" do
- bundle "show missing"
- expect(out).to match(/could not find gem 'missing'/i)
+ bundle "show missing", :raise_on_error => false
+ expect(err).to match(/could not find gem 'missing'/i)
end
it "prints path of all gems in bundle sorted by name" do
bundle "show --paths"
- expect(out).to include(default_bundle_path("gems", "rake-10.0.2").to_s)
+ expect(out).to include(default_bundle_path("gems", "rake-13.0.1").to_s)
expect(out).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
# Gem names are the last component of their path.
@@ -64,10 +68,23 @@ RSpec.describe "bundle show" do
it "prints summary of gems" do
bundle "show --verbose"
- expect(out).to include("* actionmailer (2.3.2)")
- expect(out).to include("\tSummary: This is just a fake gem for testing")
- expect(out).to include("\tHomepage: No website available.")
- expect(out).to include("\tStatus: Up to date")
+ expect(out).to include <<~MSG
+ * actionmailer (2.3.2)
+ \tSummary: This is just a fake gem for testing
+ \tHomepage: http://example.com
+ \tStatus: Up to date
+ MSG
+ end
+
+ it "includes bundler in the summary of gems" do
+ bundle "show --verbose"
+
+ expect(out).to include <<~MSG
+ * bundler (#{Bundler::VERSION})
+ \tSummary: The best way to manage your application's dependencies
+ \tHomepage: https://bundler.io
+ \tStatus: Up to date
+ MSG
end
end
@@ -111,14 +128,14 @@ RSpec.describe "bundle show" do
expect(out).to include("foo (1.0 #{sha[0..6]})")
end
- it "handles when a version is a '-' prerelease", :rubygems => "2.1" do
+ it "handles when a version is a '-' prerelease" do
@git = build_git("foo", "1.0.0-beta.1", :path => lib_path("foo"))
install_gemfile <<-G
gem "foo", "1.0.0-beta.1", :git => "#{lib_path("foo")}"
G
expect(the_bundle).to include_gems "foo 1.0.0.pre.beta.1"
- bundle! :show
+ bundle :show
expect(out).to include("foo (1.0.0.pre.beta.1")
end
end
@@ -126,51 +143,63 @@ RSpec.describe "bundle show" do
context "in a fresh gem in a blank git repo" do
before :each do
build_git "foo", :path => lib_path("foo")
- in_app_root_custom lib_path("foo")
- File.open("Gemfile", "w") {|f| f.puts "gemspec" }
- sys_exec "rm -rf .git && git init"
+ File.open(lib_path("foo/Gemfile"), "w") {|f| f.puts "gemspec" }
+ sys_exec "rm -rf .git && git init", :dir => lib_path("foo")
end
it "does not output git errors" do
- bundle :show
- expect(err).to lack_errors
+ bundle :show, :dir => lib_path("foo")
+ expect(err_without_deprecations).to be_empty
end
end
it "performs an automatic bundle install" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
- bundle "config auto_install 1"
+ bundle "config set auto_install 1"
bundle :show
expect(out).to include("Installing foo 1.0")
end
+ context "with a valid regexp for gem name" do
+ it "presents alternatives", :readline do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "rack-obama"
+ G
+
+ bundle "show rac"
+ expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>)?\z/)
+ end
+ end
+
context "with an invalid regexp for gem name" do
it "does not find the gem" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
invalid_regexp = "[]"
- bundle "show #{invalid_regexp}"
- expect(out).to include("Could not find gem '#{invalid_regexp}'.")
+ bundle "show #{invalid_regexp}", :raise_on_error => false
+ expect(err).to include("Could not find gem '#{invalid_regexp}'.")
end
end
context "--outdated option" do
- # Regression test for https://github.com/bundler/bundler/issues/5375
+ # Regression test for https://github.com/rubygems/bundler/issues/5375
before do
build_repo2
end
it "doesn't update gems to newer versions" do
- install_gemfile! <<-G
- source "file://#{gem_repo2}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
gem "rails"
G
@@ -182,10 +211,14 @@ RSpec.describe "bundle show" do
end
end
- bundle! "show --outdated"
+ bundle "show --outdated"
- bundle! "install"
+ bundle "install"
expect(the_bundle).to include_gem("rails 2.3.2")
end
end
end
+
+RSpec.describe "bundle show", :bundler => "3" do
+ pending "shows a friendly error about the command removal"
+end
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index 4992e428da..403a48a508 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -1,20 +1,24 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle update" do
- before :each do
- build_repo2
+ describe "with no arguments" do
+ before do
+ build_repo2
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport"
- gem "rack-obama"
- G
- end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
- describe "with no arguments" do
it "updates the entire bundle" do
update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
build_gem "activesupport", "3.0"
end
@@ -25,17 +29,103 @@ RSpec.describe "bundle update" do
it "doesn't delete the Gemfile.lock file if something goes wrong" do
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
exit!
G
- bundle "update"
- expect(bundled_app("Gemfile.lock")).to exist
+ bundle "update", :raise_on_error => false
+ expect(bundled_app_lock).to exist
+ end
+ end
+
+ describe "with --all" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
+
+ it "updates the entire bundle" do
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle "update", :all => true
+ expect(out).to include("Bundle updated!")
+ expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
+ end
+
+ it "doesn't delete the Gemfile.lock file if something goes wrong" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ exit!
+ G
+ bundle "update", :all => true, :raise_on_error => false
+ expect(bundled_app_lock).to exist
+ end
+ end
+
+ describe "with --gemfile" do
+ it "creates lock files based on the Gemfile name" do
+ gemfile bundled_app("OmgFile"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0"
+ G
+
+ bundle "update --gemfile OmgFile", :all => true
+
+ expect(bundled_app("OmgFile.lock")).to exist
+ end
+ end
+
+ context "when update_requires_all_flag is set" do
+ before { bundle "config set update_requires_all_flag true" }
+
+ it "errors when passed nothing" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ bundle :update, :raise_on_error => false
+ expect(err).to eq("To update everything, pass the `--all` flag.")
+ end
+
+ it "errors when passed --all and another option" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ bundle "update --all foo", :raise_on_error => false
+ expect(err).to eq("Cannot specify --all along with specific options.")
+ end
+
+ it "updates everything when passed --all" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ bundle "update --all"
+ expect(out).to include("Bundle updated!")
end
end
describe "--quiet argument" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
+
it "hides UI messages" do
bundle "update --quiet"
expect(out).not_to include("Bundle updated!")
@@ -43,8 +133,23 @@ RSpec.describe "bundle update" do
end
describe "with a top level dependency" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
+
it "unlocks all child dependencies that are unrelated to other locked dependencies" do
update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
build_gem "activesupport", "3.0"
end
@@ -54,77 +159,300 @@ RSpec.describe "bundle update" do
end
describe "with an unknown dependency" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
+
it "should inform the user" do
- bundle "update halting-problem-solver"
- expect(out).to include "Could not find gem 'halting-problem-solver'"
+ bundle "update halting-problem-solver", :raise_on_error => false
+ expect(err).to include "Could not find gem 'halting-problem-solver'"
end
it "should suggest alternatives" do
- bundle "update active-support"
- expect(out).to include "Did you mean activesupport?"
+ bundle "update platformspecific", :raise_on_error => false
+ expect(err).to include "Did you mean platform_specific?"
end
end
describe "with a child dependency" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
+
it "should update the child dependency" do
- update_repo2
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+ end
+
bundle "update rack"
expect(the_bundle).to include_gems "rack 1.2"
end
end
describe "when a possible resolve requires an older version of a locked gem" do
- context "and only_update_to_newer_versions is set" do
- before do
- bundle! "config only_update_to_newer_versions true"
+ it "does not go to an older version" do
+ build_repo4 do
+ build_gem "tilt", "2.0.8"
+ build_gem "slim", "3.0.9" do |s|
+ s.add_dependency "tilt", [">= 1.3.3", "< 2.1"]
+ end
+ build_gem "slim_lint", "0.16.1" do |s|
+ s.add_dependency "slim", [">= 3.0", "< 5.0"]
+ end
+ build_gem "slim-rails", "0.2.1" do |s|
+ s.add_dependency "slim", ">= 0.9.2"
+ end
+ build_gem "slim-rails", "3.1.3" do |s|
+ s.add_dependency "slim", "~> 3.0"
+ end
end
- it "does not go to an older version" do
- build_repo4 do
- build_gem "a" do |s|
- s.add_dependency "b"
- s.add_dependency "c"
- end
- build_gem "b"
- build_gem "c"
- build_gem "c", "2.0"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "slim-rails"
+ gem "slim_lint"
+ G
+
+ expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
+
+ update_repo4 do
+ build_gem "slim", "4.0.0" do |s|
+ s.add_dependency "tilt", [">= 2.0.6", "< 2.1"]
end
+ end
- install_gemfile! <<-G
- source "file:#{gem_repo4}"
- gem "a"
- G
+ bundle "update", :all => true
- expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
+ expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
+ end
- update_repo4 do
- build_gem "b", "2.0" do |s|
- s.add_dependency "c", "< 2"
- end
+ it "does not go to an older version, even if the version upgrade that could cause another gem to downgrade is activated first" do
+ build_repo4 do
+ # countries is processed before country_select by the resolver due to having less spec groups (groups of versions with the same dependencies) (2 vs 3)
+
+ build_gem "countries", "2.1.4"
+ build_gem "countries", "3.1.0"
+
+ build_gem "countries", "4.0.0" do |s|
+ s.add_dependency "sixarm_ruby_unaccent", "~> 1.1"
end
- bundle! "update"
+ build_gem "country_select", "1.2.0"
- expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
+ build_gem "country_select", "2.1.4" do |s|
+ s.add_dependency "countries", "~> 2.0"
+ end
+ build_gem "country_select", "3.1.1" do |s|
+ s.add_dependency "countries", "~> 2.0"
+ end
+
+ build_gem "country_select", "5.1.0" do |s|
+ s.add_dependency "countries", "~> 3.0"
+ end
+
+ build_gem "sixarm_ruby_unaccent", "1.1.0"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "country_select"
+ gem "countries"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ countries (3.1.0)
+ country_select (5.1.0)
+ countries (~> 3.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ countries
+ country_select
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ previous_lockfile = lockfile
+
+ bundle "lock --update"
+
+ expect(lockfile).to eq(previous_lockfile)
+ end
+
+ it "does not downgrade indirect dependencies unnecessarily" do
+ build_repo4 do
+ build_gem "a" do |s|
+ s.add_dependency "b"
+ s.add_dependency "c"
+ end
+ build_gem "b"
+ build_gem "c"
+ build_gem "c", "2.0"
end
+
+ install_gemfile <<-G, :verbose => true
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a"
+ G
+
+ expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
+
+ update_repo4 do
+ build_gem "b", "2.0" do |s|
+ s.add_dependency "c", "< 2"
+ end
+ end
+
+ bundle "update", :all => true, :verbose => true
+ expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
+ end
+
+ it "should still downgrade if forced by the Gemfile" do
+ build_repo4 do
+ build_gem "a"
+ build_gem "b", "1.0"
+ build_gem "b", "2.0"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a"
+ gem "b"
+ G
+
+ expect(the_bundle).to include_gems("a 1.0", "b 2.0")
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a"
+ gem "b", "1.0"
+ G
+
+ bundle "update b"
+
+ expect(the_bundle).to include_gems("a 1.0", "b 1.0")
+ end
+
+ it "should still downgrade if forced by the Gemfile, when transitive dependencies also need downgrade" do
+ build_repo4 do
+ build_gem "activesupport", "6.1.4.1" do |s|
+ s.add_dependency "tzinfo", "~> 2.0"
+ end
+
+ build_gem "activesupport", "6.0.4.1" do |s|
+ s.add_dependency "tzinfo", "~> 1.1"
+ end
+
+ build_gem "tzinfo", "2.0.4"
+ build_gem "tzinfo", "1.2.9"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "activesupport", "~> 6.1.0"
+ G
+
+ expect(the_bundle).to include_gems("activesupport 6.1.4.1", "tzinfo 2.0.4")
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "activesupport", "~> 6.0.0"
+ G
+
+ original_lockfile = lockfile
+
+ expected_lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ activesupport (6.0.4.1)
+ tzinfo (~> 1.1)
+ tzinfo (1.2.9)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ activesupport (~> 6.0.0)
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "update activesupport"
+ expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9")
+ expect(lockfile).to eq(expected_lockfile)
+
+ lockfile original_lockfile
+ bundle "update"
+ expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9")
+ expect(lockfile).to eq(expected_lockfile)
+
+ lockfile original_lockfile
+ bundle "lock --update"
+ expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9")
+ expect(lockfile).to eq(expected_lockfile)
end
end
describe "with --local option" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
+
it "doesn't hit repo2" do
FileUtils.rm_rf(gem_repo2)
- bundle "update --local"
- expect(out).not_to match(/Fetching source index/)
+ bundle "update --local --all"
+ expect(out).not_to include("Fetching source index")
end
end
describe "with --group option" do
- it "should update only specifed group gems" do
+ before do
+ build_repo2
+ end
+
+ it "should update only specified group gems" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", :group => :development
gem "rack"
G
update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
build_gem "activesupport", "3.0"
end
bundle "update --group development"
@@ -132,11 +460,28 @@ RSpec.describe "bundle update" do
expect(the_bundle).not_to include_gems "rack 1.2"
end
+ context "when conservatively updating a group with non-group sub-deps" do
+ it "should update only specified group gems" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activemerchant", :group => :development
+ gem "activesupport"
+ G
+ update_repo2 do
+ build_gem "activemerchant", "2.0"
+ build_gem "activesupport", "3.0"
+ end
+ bundle "update --conservative --group development"
+ expect(the_bundle).to include_gems "activemerchant 2.0"
+ expect(the_bundle).not_to include_gems "activesupport 3.0"
+ end
+ end
+
context "when there is a source with the same name as a gem in a group" do
- before :each do
+ before do
build_git "foo", :path => lib_path("activesupport")
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", :group => :development
gem "foo", :git => "#{lib_path("activesupport")}"
G
@@ -151,49 +496,90 @@ RSpec.describe "bundle update" do
expect(the_bundle).not_to include_gems "foo 2.0"
end
end
+
+ context "when bundler itself is a transitive dependency" do
+ it "executes without error" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "activesupport", :group => :development
+ gem "rack"
+ G
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
+ build_gem "activesupport", "3.0"
+ end
+ bundle "update --group development"
+ expect(the_bundle).to include_gems "activesupport 2.3.5"
+ expect(the_bundle).to include_gems "bundler #{Bundler::VERSION}"
+ expect(the_bundle).not_to include_gems "rack 1.2"
+ end
+ end
end
describe "in a frozen bundle" do
- it "should fail loudly" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ gem "platform_specific"
+ G
+ end
+
+ it "should fail loudly", :bundler => "< 3" do
bundle "install --deployment"
- bundle "update"
+ bundle "update", :all => true, :raise_on_error => false
- expect(out).to match(/You are trying to install in deployment mode after changing.your Gemfile/m)
- expect(out).to match(/freeze \nby running `bundle install --no-deployment`./m)
- expect(exitstatus).not_to eq(0) if exitstatus
+ expect(last_command).to be_failure
+ expect(err).to match(/You are trying to install in deployment mode after changing.your Gemfile/m)
+ expect(err).to match(/freeze \nby running `bundle config unset deployment`./m)
end
- it "should suggest different command when frozen is set globally" do
- bundler "config --global frozen 1"
- bundle "update"
- expect(out).to match(/You are trying to install in deployment mode after changing.your Gemfile/m)
- expect(out).to match(/freeze \nby running `bundle config --delete frozen`./m)
+ it "should suggest different command when frozen is set globally", :bundler => "< 3" do
+ bundle "config set --global frozen 1"
+ bundle "update", :all => true, :raise_on_error => false
+ expect(err).to match(/You are trying to install in deployment mode after changing.your Gemfile/m).
+ and match(/freeze \nby running `bundle config unset frozen`./m)
+ end
+
+ it "should suggest different command when frozen is set globally", :bundler => "3" do
+ bundle "config set --global deployment true"
+ bundle "update", :all => true, :raise_on_error => false
+ expect(err).to match(/You are trying to install in deployment mode after changing.your Gemfile/m).
+ and match(/freeze \nby running `bundle config unset deployment`./m)
end
end
describe "with --source option" do
- it "should not update gems not included in the source that happen to have the same name" do
- pending("Allowed to fail to preserve backwards-compatibility")
+ before do
+ build_repo2
+ end
+ it "should not update gems not included in the source that happen to have the same name" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
G
update_repo2 { build_gem "activesupport", "3.0" }
bundle "update --source activesupport"
- expect(the_bundle).not_to include_gems "activesupport 3.0"
+ expect(the_bundle).not_to include_gem "activesupport 3.0"
end
- it "should update gems not included in the source that happen to have the same name" do
+ it "should not update gems not included in the source that happen to have the same name" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
G
update_repo2 { build_gem "activesupport", "3.0" }
bundle "update --source activesupport"
- expect(the_bundle).to include_gems "activesupport 3.0"
+ expect(the_bundle).not_to include_gems "activesupport 3.0"
end
end
@@ -207,7 +593,7 @@ RSpec.describe "bundle update" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "harry"
gem "fred"
G
@@ -222,8 +608,7 @@ RSpec.describe "bundle update" do
end
bundle "update --source harry"
- expect(the_bundle).to include_gems "harry 2.0"
- expect(the_bundle).to include_gems "fred 1.0"
+ expect(the_bundle).to include_gems "harry 1.0", "fred 1.0"
end
end
@@ -240,7 +625,7 @@ RSpec.describe "bundle update" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "harry"
gem "fred"
G
@@ -255,27 +640,149 @@ RSpec.describe "bundle update" do
end
bundle "update --source harry"
- expect(the_bundle).to include_gems "harry 2.0"
- expect(the_bundle).to include_gems "fred 1.0"
- expect(the_bundle).to include_gems "george 1.0"
+ expect(the_bundle).to include_gems "harry 1.0", "fred 1.0", "george 1.0"
+ end
+ end
+
+ it "shows the previous version of the gem when updated from rubygems source", :bundler => "< 3" do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ G
+
+ bundle "update", :all => true
+ expect(out).to include("Using activesupport 2.3.5")
+
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle "update", :all => true
+ expect(out).to include("Installing activesupport 3.0 (was 2.3.5)")
+ end
+
+ context "with suppress_install_using_messages set" do
+ before { bundle "config set suppress_install_using_messages true" }
+
+ it "only prints `Using` for versions that have changed" do
+ build_repo4 do
+ build_gem "bar"
+ build_gem "foo"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "bar"
+ gem "foo"
+ G
+
+ bundle "update", :all => true
+ expect(out).to match(/Resolving dependencies\.\.\.\.*\nBundle updated!/)
+
+ update_repo4 do
+ build_gem "foo", "2.0"
+ end
+
+ bundle "update", :all => true
+ out.sub!("Removing foo (1.0)\n", "")
+ expect(out).to match(/Resolving dependencies\.\.\.\.*\nFetching foo 2\.0 \(was 1\.0\)\nInstalling foo 2\.0 \(was 1\.0\)\nBundle updated/)
+ end
+ end
+
+ it "shows error message when Gemfile.lock is not preset and gem is specified" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ G
+
+ bundle "update nonexisting", :raise_on_error => false
+ expect(err).to include("This Bundle hasn't been installed yet. Run `bundle install` to update and install the bundled gems.")
+ expect(exitstatus).to eq(22)
+ end
+
+ context "with multiple, duplicated sources, with lockfile in old format", :bundler => "< 3" do
+ before do
+ build_repo2 do
+ build_gem "dotenv", "2.7.6"
+
+ build_gem "oj", "3.11.3"
+ build_gem "oj", "3.11.5"
+
+ build_gem "vcr", "6.0.0"
+ end
+
+ build_repo gem_repo3 do
+ build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s|
+ s.add_dependency "oj"
+ end
+ end
+
+ gemfile <<~G
+ source "https://gem.repo2"
+
+ gem "dotenv"
+
+ source "https://gem.repo3" do
+ gem 'pkg-gem-flowbyte-with-dep'
+ end
+
+ gem "vcr",source: "https://gem.repo2"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gem.repo2/
+ remote: https://gem.repo3/
+ specs:
+ dotenv (2.7.6)
+ oj (3.11.3)
+ pkg-gem-flowbyte-with-dep (1.0.0)
+ oj
+ vcr (6.0.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ dotenv
+ pkg-gem-flowbyte-with-dep!
+ vcr!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "works" do
+ bundle :install, :artifice => "compact_index"
+ bundle "update oj", :artifice => "compact_index"
+
+ expect(out).to include("Bundle updated!")
+ expect(the_bundle).to include_gems "oj 3.11.5"
end
end
end
RSpec.describe "bundle update in more complicated situations" do
- before :each do
+ before do
build_repo2
end
it "will eagerly unlock dependencies of a specified gem" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "thin"
gem "rack-obama"
G
update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
build_gem "thin", "2.0" do |s|
s.add_dependency "rack"
end
@@ -285,11 +792,64 @@ RSpec.describe "bundle update in more complicated situations" do
expect(the_bundle).to include_gems "thin 2.0", "rack 1.2", "rack-obama 1.0"
end
+ it "will warn when some explicitly updated gems are not updated" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "thin"
+ gem "rack-obama"
+ G
+
+ update_repo2 do
+ build_gem("thin", "2.0") {|s| s.add_dependency "rack" }
+ build_gem "rack", "10.0"
+ end
+
+ bundle "update thin rack-obama"
+ expect(last_command.stdboth).to include "Bundler attempted to update rack-obama but its version stayed the same"
+ expect(the_bundle).to include_gems "thin 2.0", "rack 10.0", "rack-obama 1.0"
+ end
+
+ it "will not warn when an explicitly updated git gem changes sha but not version" do
+ build_git "foo"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
+ G
+
+ update_git "foo" do |s|
+ s.write "lib/foo2.rb", "puts :foo2"
+ end
+
+ bundle "update foo"
+
+ expect(last_command.stdboth).not_to include "attempted to update"
+ end
+
+ it "will not warn when changing gem sources but not versions" do
+ build_git "rack"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack", :git => '#{lib_path("rack-1.0")}'
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "update rack"
+
+ expect(last_command.stdboth).not_to include "attempted to update"
+ end
+
it "will update only from pinned source" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
- source "file://#{gem_repo1}" do
+ source "#{file_uri_for(gem_repo1)}" do
gem "thin"
end
G
@@ -301,6 +861,82 @@ RSpec.describe "bundle update in more complicated situations" do
bundle "update"
expect(the_bundle).to include_gems "thin 1.0"
end
+
+ context "when the lockfile is for a different platform" do
+ before do
+ build_repo4 do
+ build_gem("a", "0.9")
+ build_gem("a", "0.9") {|s| s.platform = "java" }
+ build_gem("a", "1.1")
+ build_gem("a", "1.1") {|s| s.platform = "java" }
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}
+ specs:
+ a (0.9-java)
+
+ PLATFORMS
+ java
+
+ DEPENDENCIES
+ a
+ L
+
+ simulate_platform linux
+ end
+
+ it "allows updating" do
+ bundle :update, :all => true
+ expect(the_bundle).to include_gem "a 1.1"
+ end
+
+ it "allows updating a specific gem" do
+ bundle "update a"
+ expect(the_bundle).to include_gem "a 1.1"
+ end
+ end
+
+ context "when the dependency is for a different platform" do
+ before do
+ build_repo4 do
+ build_gem("a", "0.9") {|s| s.platform = "java" }
+ build_gem("a", "1.1") {|s| s.platform = "java" }
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a", platform: :jruby
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}
+ specs:
+ a (0.9-java)
+
+ PLATFORMS
+ java
+
+ DEPENDENCIES
+ a
+ L
+
+ simulate_platform linux
+ end
+
+ it "is not updated because it is not actually included in the bundle" do
+ bundle "update a"
+ expect(last_command.stdboth).to include "Bundler attempted to update a but it was not considered because it is for a different platform from the current one"
+ expect(the_bundle).to_not include_gem "a"
+ end
+ end
end
RSpec.describe "bundle update without a Gemfile.lock" do
@@ -308,73 +944,38 @@ RSpec.describe "bundle update without a Gemfile.lock" do
build_repo2
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack", "1.0"
G
- bundle "update"
+ bundle "update", :all => true
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
RSpec.describe "bundle update when a gem depends on a newer version of bundler" do
- before(:each) do
+ before do
build_repo2 do
build_gem "rails", "3.0.1" do |s|
s.add_dependency "bundler", Bundler::VERSION.succ
end
+
+ build_gem "bundler", Bundler::VERSION.succ
end
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0.1"
G
end
- it "should not explode" do
- bundle "update"
- expect(err).to lack_errors
- end
-
- it "should explain that bundler conflicted" do
- bundle "update"
- expect(out).not_to match(/in snapshot/i)
- expect(out).to match(/current Bundler version/i)
- expect(out).to match(/perhaps you need to update bundler/i)
- end
-end
-
-RSpec.describe "bundle update" do
- it "shows the previous version of the gem when updated from rubygems source" do
- build_repo2
-
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport"
- G
-
- bundle "update"
- expect(out).to include("Using activesupport 2.3.5")
-
- update_repo2 do
- build_gem "activesupport", "3.0"
- end
-
- bundle "update"
- expect(out).to include("Installing activesupport 3.0 (was 2.3.5)")
- end
-
- it "shows error message when Gemfile.lock is not preset and gem is specified" do
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport"
- G
-
- bundle "update nonexisting"
- expect(out).to include("This Bundle hasn't been installed yet. Run `bundle install` to update and install the bundled gems.")
- expect(exitstatus).to eq(22) if exitstatus
+ it "should explain that bundler conflicted and how to resolve the conflict" do
+ bundle "update", :all => true, :raise_on_error => false
+ expect(last_command.stdboth).not_to match(/in snapshot/i)
+ expect(err).to match(/current Bundler version/i).
+ and match(/Install the necessary version with `gem install bundler:#{Bundler::VERSION.succ}`/i)
end
end
@@ -384,26 +985,28 @@ RSpec.describe "bundle update --ruby" do
::RUBY_VERSION = '2.1.3'
::RUBY_PATCHLEVEL = 100
ruby '~> 2.1.0'
+ source "#{file_uri_for(gem_repo1)}"
G
- bundle "update --ruby"
end
context "when the Gemfile removes the ruby" do
before do
- install_gemfile <<-G
+ gemfile <<-G
::RUBY_VERSION = '2.1.4'
::RUBY_PATCHLEVEL = 222
+ source "#{file_uri_for(gem_repo1)}"
G
end
it "removes the Ruby from the Gemfile.lock" do
bundle "update --ruby"
- lockfile_should_be <<-L
+ expect(lockfile).to eq <<~L
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
@@ -415,21 +1018,23 @@ RSpec.describe "bundle update --ruby" do
context "when the Gemfile specified an updated Ruby version" do
before do
- install_gemfile <<-G
+ gemfile <<-G
::RUBY_VERSION = '2.1.4'
::RUBY_PATCHLEVEL = 222
ruby '~> 2.1.0'
+ source "#{file_uri_for(gem_repo1)}"
G
end
it "updates the Gemfile.lock with the latest version" do
bundle "update --ruby"
- lockfile_should_be <<-L
+ expect(lockfile).to eq <<~L
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
@@ -444,36 +1049,39 @@ RSpec.describe "bundle update --ruby" do
context "when a different Ruby is being used than has been versioned" do
before do
- install_gemfile <<-G
+ gemfile <<-G
::RUBY_VERSION = '2.2.2'
::RUBY_PATCHLEVEL = 505
ruby '~> 2.1.0'
+ source "#{file_uri_for(gem_repo1)}"
G
end
it "shows a helpful error message" do
- bundle "update --ruby"
+ bundle "update --ruby", :raise_on_error => false
- expect(out).to include("Your Ruby version is 2.2.2, but your Gemfile specified ~> 2.1.0")
+ expect(err).to include("Your Ruby version is 2.2.2, but your Gemfile specified ~> 2.1.0")
end
end
context "when updating Ruby version and Gemfile `ruby`" do
before do
- install_gemfile <<-G
+ gemfile <<-G
::RUBY_VERSION = '1.8.3'
::RUBY_PATCHLEVEL = 55
ruby '~> 1.8.0'
+ source "#{file_uri_for(gem_repo1)}"
G
end
it "updates the Gemfile.lock with the latest version" do
bundle "update --ruby"
- lockfile_should_be <<-L
+ expect(lockfile).to eq <<~L
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
@@ -487,27 +1095,49 @@ RSpec.describe "bundle update --ruby" do
end
end
+RSpec.describe "bundle update --bundler" do
+ it "updates the bundler version in the lockfile without re-resolving" do
+ build_repo4 do
+ build_gem "rack", "1.0"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2')
+
+ FileUtils.rm_r gem_repo4
+
+ bundle :update, :bundler => true, :verbose => true
+ expect(the_bundle).to include_gem "rack 1.0"
+
+ expect(the_bundle.locked_gems.bundler_version).to eq v(Bundler::VERSION)
+ end
+end
+
# these specs are slow and focus on integration and therefore are not exhaustive. unit specs elsewhere handle that.
RSpec.describe "bundle update conservative" do
context "patch and minor options" do
before do
build_repo4 do
- build_gem "foo", %w(1.4.3 1.4.4) do |s|
+ build_gem "foo", %w[1.4.3 1.4.4] do |s|
s.add_dependency "bar", "~> 2.0"
end
- build_gem "foo", %w(1.4.5 1.5.0) do |s|
+ build_gem "foo", %w[1.4.5 1.5.0] do |s|
s.add_dependency "bar", "~> 2.1"
end
- build_gem "foo", %w(1.5.1) do |s|
+ build_gem "foo", %w[1.5.1] do |s|
s.add_dependency "bar", "~> 3.0"
end
- build_gem "bar", %w(2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0)
- build_gem "qux", %w(1.0.0 1.0.1 1.1.0 2.0.0)
+ build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
+ build_gem "qux", %w[1.0.0 1.0.1 1.1.0 2.0.0]
end
# establish a lockfile set to 1.4.3
install_gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'foo', '1.4.3'
gem 'bar', '2.0.3'
gem 'qux', '1.0.0'
@@ -516,12 +1146,21 @@ RSpec.describe "bundle update conservative" do
# remove 1.4.3 requirement and bar altogether
# to setup update specs below
gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'foo'
gem 'qux'
G
end
+ context "with patch set as default update level in config" do
+ it "should do a patch level update" do
+ bundle "config set --local prefer_patch true"
+ bundle "update foo"
+
+ expect(the_bundle).to include_gems "foo 1.4.5", "bar 2.1.1", "qux 1.0.0"
+ end
+ end
+
context "patch preferred" do
it "single gem updates dependent gem to minor" do
bundle "update --patch foo"
@@ -530,7 +1169,7 @@ RSpec.describe "bundle update conservative" do
end
it "update all" do
- bundle "update --patch"
+ bundle "update --patch", :all => true
expect(the_bundle).to include_gems "foo 1.4.5", "bar 2.1.1", "qux 1.0.1"
end
@@ -552,7 +1191,7 @@ RSpec.describe "bundle update conservative" do
end
it "minor preferred" do
- bundle "update --minor --strict"
+ bundle "update --minor --strict", :all => true
expect(the_bundle).to include_gems "foo 1.5.0", "bar 2.1.1", "qux 1.1.0"
end
@@ -562,31 +1201,31 @@ RSpec.describe "bundle update conservative" do
context "eager unlocking" do
before do
build_repo4 do
- build_gem "isolated_owner", %w(1.0.1 1.0.2) do |s|
+ build_gem "isolated_owner", %w[1.0.1 1.0.2] do |s|
s.add_dependency "isolated_dep", "~> 2.0"
end
- build_gem "isolated_dep", %w(2.0.1 2.0.2)
+ build_gem "isolated_dep", %w[2.0.1 2.0.2]
- build_gem "shared_owner_a", %w(3.0.1 3.0.2) do |s|
+ build_gem "shared_owner_a", %w[3.0.1 3.0.2] do |s|
s.add_dependency "shared_dep", "~> 5.0"
end
- build_gem "shared_owner_b", %w(4.0.1 4.0.2) do |s|
+ build_gem "shared_owner_b", %w[4.0.1 4.0.2] do |s|
s.add_dependency "shared_dep", "~> 5.0"
end
- build_gem "shared_dep", %w(5.0.1 5.0.2)
+ build_gem "shared_dep", %w[5.0.1 5.0.2]
end
gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'isolated_owner'
gem 'shared_owner_a'
gem 'shared_owner_b'
G
- lockfile <<-L
+ lockfile <<~L
GEM
- remote: file://#{gem_repo4}
+ remote: #{file_uri_for(gem_repo4)}/
specs:
isolated_dep (2.0.1)
isolated_owner (1.0.1)
@@ -598,15 +1237,15 @@ RSpec.describe "bundle update conservative" do
shared_dep (~> 5.0)
PLATFORMS
- ruby
+ #{specific_local_platform}
DEPENDENCIES
+ isolated_owner
shared_owner_a
shared_owner_b
- isolated_owner
BUNDLED WITH
- 1.13.0
+ #{Bundler::VERSION}
L
end
@@ -625,12 +1264,47 @@ RSpec.describe "bundle update conservative" do
it "should not eagerly unlock with --conservative" do
bundle "update --conservative shared_owner_a isolated_owner"
- expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.2", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.1"
+ expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.1", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.1"
+ end
+
+ it "should only update direct dependencies when fully updating with --conservative" do
+ bundle "update --conservative"
+
+ expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.1", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.2"
+ end
+
+ it "should only change direct dependencies when updating the lockfile with --conservative" do
+ bundle "lock --update --conservative"
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ isolated_dep (2.0.1)
+ isolated_owner (1.0.2)
+ isolated_dep (~> 2.0)
+ shared_dep (5.0.1)
+ shared_owner_a (3.0.2)
+ shared_dep (~> 5.0)
+ shared_owner_b (4.0.2)
+ shared_dep (~> 5.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ isolated_owner
+ shared_owner_a
+ shared_owner_b
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
it "should match bundle install conservative update behavior when not eagerly unlocking" do
gemfile <<-G
- source "file://#{gem_repo4}"
+ source "#{file_uri_for(gem_repo4)}"
gem 'isolated_owner', '1.0.2'
gem 'shared_owner_a', '3.0.2'
@@ -645,13 +1319,13 @@ RSpec.describe "bundle update conservative" do
context "error handling" do
before do
- gemfile ""
+ gemfile "source \"#{file_uri_for(gem_repo1)}\""
end
it "raises if too many flags are provided" do
- bundle "update --patch --minor"
+ bundle "update --patch --minor", :all => true, :raise_on_error => false
- expect(out).to eq "Provide only one of the following options: minor, patch"
+ expect(err).to eq "Provide only one of the following options: minor, patch"
end
end
end
diff --git a/spec/bundler/commands/version_spec.rb b/spec/bundler/commands/version_spec.rb
new file mode 100644
index 0000000000..53d545f5fa
--- /dev/null
+++ b/spec/bundler/commands/version_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require_relative "../support/path"
+
+RSpec.describe "bundle version" do
+ if Spec::Path.ruby_core?
+ COMMIT_HASH = /unknown|[a-fA-F0-9]{7,}/.freeze
+ else
+ COMMIT_HASH = /[a-fA-F0-9]{7,}/.freeze
+ end
+
+ context "with -v" do
+ it "outputs the version", :bundler => "< 3" do
+ bundle "-v"
+ expect(out).to eq("Bundler version #{Bundler::VERSION}")
+ end
+
+ it "outputs the version", :bundler => "3" do
+ bundle "-v"
+ expect(out).to eq(Bundler::VERSION)
+ end
+ end
+
+ context "with --version" do
+ it "outputs the version", :bundler => "< 3" do
+ bundle "--version"
+ expect(out).to eq("Bundler version #{Bundler::VERSION}")
+ end
+
+ it "outputs the version", :bundler => "3" do
+ bundle "--version"
+ expect(out).to eq(Bundler::VERSION)
+ end
+ end
+
+ context "with version" do
+ it "outputs the version with build metadata", :bundler => "< 3" do
+ bundle "version"
+ expect(out).to match(/\ABundler version #{Regexp.escape(Bundler::VERSION)} \(\d{4}-\d{2}-\d{2} commit #{COMMIT_HASH}\)\z/)
+ end
+
+ it "outputs the version with build metadata", :bundler => "3" do
+ bundle "version"
+ expect(out).to match(/\A#{Regexp.escape(Bundler::VERSION)} \(\d{4}-\d{2}-\d{2} commit #{COMMIT_HASH}\)\z/)
+ end
+ end
+end
diff --git a/spec/bundler/commands/viz_spec.rb b/spec/bundler/commands/viz_spec.rb
index 77112aace4..0efb24b504 100644
--- a/spec/bundler/commands/viz_spec.rb
+++ b/spec/bundler/commands/viz_spec.rb
@@ -1,27 +1,23 @@
# frozen_string_literal: true
-require "spec_helper"
-
-RSpec.describe "bundle viz", :ruby => "1.9.3", :if => Bundler.which("dot") do
- let(:ruby_graphviz) do
- graphviz_glob = base_system_gems.join("cache/ruby-graphviz*")
- Pathname.glob(graphviz_glob).first
- end
+RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do
before do
- system_gems ruby_graphviz
+ graphviz_version = RUBY_VERSION >= "2.4" ? "1.2.5" : "1.2.4"
+
+ realworld_system_gems "ruby-graphviz --version #{graphviz_version}"
end
it "graphs gems from the Gemfile" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rack-obama"
G
- bundle! "viz"
+ bundle "viz"
expect(out).to include("gem_graph.png")
- bundle! "viz", :format => "debug"
+ bundle "viz", :format => "debug"
expect(out).to eq(strip_whitespace(<<-DOT).strip)
digraph Gemfile {
concentrate = "true";
@@ -47,15 +43,15 @@ RSpec.describe "bundle viz", :ruby => "1.9.3", :if => Bundler.which("dot") do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack", "= 1.3.pre"
gem "rack-obama"
G
- bundle! "viz"
+ bundle "viz"
expect(out).to include("gem_graph.png")
- bundle! "viz", :format => :debug, :version => true
+ bundle "viz", :format => :debug, :version => true
expect(out).to eq(strip_whitespace(<<-EOS).strip)
digraph Gemfile {
concentrate = "true";
@@ -83,17 +79,17 @@ RSpec.describe "bundle viz", :ruby => "1.9.3", :if => Bundler.which("dot") do
end
end
- system_gems ruby_graphviz, "graphviz-999", :gem_repo => gem_repo4
+ system_gems "graphviz-999", :gem_repo => gem_repo4
end
it "loads the correct ruby-graphviz gem" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rack-obama"
G
- bundle! "viz", :format => "debug"
+ bundle "viz", :format => "debug"
expect(out).to eq(strip_whitespace(<<-DOT).strip)
digraph Gemfile {
concentrate = "true";
@@ -117,7 +113,7 @@ RSpec.describe "bundle viz", :ruby => "1.9.3", :if => Bundler.which("dot") do
context "--without option" do
it "one group" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
group :rails do
@@ -125,13 +121,13 @@ RSpec.describe "bundle viz", :ruby => "1.9.3", :if => Bundler.which("dot") do
end
G
- bundle! "viz --without=rails"
+ bundle "viz --without=rails"
expect(out).to include("gem_graph.png")
end
it "two groups" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
group :rack do
@@ -143,7 +139,7 @@ RSpec.describe "bundle viz", :ruby => "1.9.3", :if => Bundler.which("dot") do
end
G
- bundle! "viz --without=rails:rack"
+ bundle "viz --without=rails:rack"
expect(out).to include("gem_graph.png")
end
end
diff --git a/spec/bundler/install/allow_offline_install_spec.rb b/spec/bundler/install/allow_offline_install_spec.rb
index 1bca055c9f..524363fde5 100644
--- a/spec/bundler/install/allow_offline_install_spec.rb
+++ b/spec/bundler/install/allow_offline_install_spec.rb
@@ -1,14 +1,13 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with :allow_offline_install" do
before do
- bundle "config allow_offline_install true"
+ bundle "config set allow_offline_install true"
end
context "with no cached data locally" do
it "still installs" do
- install_gemfile! <<-G, :artifice => "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "http://testgemserver.local"
gem "rack-obama"
G
@@ -16,20 +15,21 @@ RSpec.describe "bundle install with :allow_offline_install" do
end
it "still fails when the network is down" do
- install_gemfile <<-G, :artifice => "fail"
+ install_gemfile <<-G, :artifice => "fail", :raise_on_error => false
source "http://testgemserver.local"
gem "rack-obama"
G
- expect(out).to include("Could not reach host testgemserver.local.")
+ expect(err).to include("Could not reach host testgemserver.local.")
expect(the_bundle).to_not be_locked
end
end
context "with cached data locally" do
it "will install from the compact index" do
- system_gems ["rack-1.0.0"]
+ system_gems ["rack-1.0.0"], :path => default_bundle_path
- install_gemfile! <<-G, :artifice => "compact_index"
+ bundle "config set clean false"
+ install_gemfile <<-G, :artifice => "compact_index"
source "http://testgemserver.local"
gem "rack-obama"
gem "rack", "< 1.0"
@@ -42,8 +42,8 @@ RSpec.describe "bundle install with :allow_offline_install" do
gem "rack-obama"
G
- bundle! :update, :artifice => "fail"
- expect(out).to include("Using the cached data for the new index because of a network error")
+ bundle :update, :artifice => "fail", :all => true
+ expect(last_command.stdboth).to include "Using the cached data for the new index because of a network error"
expect(the_bundle).to include_gems("rack-obama 1.0", "rack 1.0.0")
end
@@ -70,22 +70,26 @@ RSpec.describe "bundle install with :allow_offline_install" do
end
it "will install from a cached git repo" do
+ skip "doesn't print errors" if Gem.win_platform?
+
git = build_git "a", "1.0.0", :path => lib_path("a")
update_git("a", :path => git.path, :branch => "new_branch")
- install_gemfile! <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "a", :git => #{git.path.to_s.dump}
G
- break_git_remote_ops! { bundle! :update }
- expect(out).to include("Using cached git data because of network errors")
+ break_git_remote_ops! { bundle :update, :all => true }
+ expect(err).to include("Using cached git data because of network errors")
expect(the_bundle).to be_locked
break_git_remote_ops! do
- install_gemfile! <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "a", :git => #{git.path.to_s.dump}, :branch => "new_branch"
G
end
- expect(out).to include("Using cached git data because of network errors")
+ expect(err).to include("Using cached git data because of network errors")
expect(the_bundle).to be_locked
end
end
diff --git a/spec/bundler/install/binstubs_spec.rb b/spec/bundler/install/binstubs_spec.rb
index a1a9ab167d..6961171f4f 100644
--- a/spec/bundler/install/binstubs_spec.rb
+++ b/spec/bundler/install/binstubs_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
describe "when system_bindir is set" do
@@ -8,9 +7,8 @@ RSpec.describe "bundle install" do
it "overrides Gem.bindir" do
expect(Pathname.new("/usr/bin")).not_to be_writable unless Process.euid == 0
gemfile <<-G
- require 'rubygems'
def Gem.bindir; "/usr/bin"; end
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -29,22 +27,25 @@ RSpec.describe "bundle install" do
end
end
- install_gemfile <<-G, :binstubs => true
- source "file://#{gem_repo2}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
gem "fake"
gem "rack"
G
end
- it "prints a deprecation notice" do
- bundle "config major_deprecations true"
- gembin("rackup")
- expect(out).to include("Bundler is using a binstub that was created for a different gem.")
- end
+ it "warns about the situation" do
+ bundle "exec rackup"
- it "loads the correct spec's executable" do
- gembin("rackup")
- expect(out).to eq("1.2")
+ expect(last_command.stderr).to include(
+ "The `rackup` executable in the `fake` gem is being loaded, but it's also present in other gems (rack).\n" \
+ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
+ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
+ ).or include(
+ "The `rackup` executable in the `rack` gem is being loaded, but it's also present in other gems (fake).\n" \
+ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
+ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
+ )
end
end
end
diff --git a/spec/bundler/install/bundler_spec.rb b/spec/bundler/install/bundler_spec.rb
index c1ce57e60e..963ce82db8 100644
--- a/spec/bundler/install/bundler_spec.rb
+++ b/spec/bundler/install/bundler_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
describe "with bundler dependencies" do
@@ -15,54 +14,98 @@ RSpec.describe "bundle install" do
it "are forced to the current bundler version" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0"
G
expect(the_bundle).to include_gems "bundler #{Bundler::VERSION}"
end
- it "are not added if not already present" do
+ it "are forced to the current bundler version even if not already present" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- expect(the_bundle).not_to include_gems "bundler #{Bundler::VERSION}"
+ expect(the_bundle).to include_gems "bundler #{Bundler::VERSION}"
end
- it "causes a conflict if explicitly requesting a different version" do
- install_gemfile <<-G
- source "file://#{gem_repo2}"
+ it "causes a conflict if explicitly requesting a different version of bundler" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rails", "3.0"
+ gem "bundler", "0.9.1"
+ G
+
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
+ Bundler could not find compatible versions for gem "bundler":
+ In Gemfile:
+ bundler (= 0.9.1)
+
+ Current Bundler version:
+ bundler (#{Bundler::VERSION})
+
+ Your bundle requires a different version of Bundler than the one you're running.
+ Install the necessary version with `gem install bundler:0.9.1` and rerun bundler using `bundle _0.9.1_ install`
+ E
+ expect(err).to include(nice_error)
+ end
+
+ it "causes a conflict if explicitly requesting a non matching requirement on bundler" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rails", "3.0"
+ gem "bundler", "~> 0.8"
+ G
+
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
+ Bundler could not find compatible versions for gem "bundler":
+ In Gemfile:
+ bundler (~> 0.8)
+
+ Current Bundler version:
+ bundler (#{Bundler::VERSION})
+
+ Your bundle requires a different version of Bundler than the one you're running.
+ Install the necessary version with `gem install bundler:0.9.1` and rerun bundler using `bundle _0.9.1_ install`
+ E
+ expect(err).to include(nice_error)
+ end
+
+ it "causes a conflict if explicitly requesting a version of bundler that doesn't exist" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0"
gem "bundler", "0.9.2"
G
nice_error = <<-E.strip.gsub(/^ {8}/, "")
- Fetching source index from file:#{gem_repo2}/
- Resolving dependencies...
Bundler could not find compatible versions for gem "bundler":
In Gemfile:
bundler (= 0.9.2)
Current Bundler version:
bundler (#{Bundler::VERSION})
- This Gemfile requires a different version of Bundler.
- Perhaps you need to update Bundler by running `gem install bundler`?
- Could not find gem 'bundler (= 0.9.2)' in any of the sources
+ Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.
E
- expect(out).to eq(nice_error)
+ expect(err).to include(nice_error)
end
it "works for gems with multiple versions in its dependencies" do
+ build_repo2 do
+ build_gem "multiple_versioned_deps" do |s|
+ s.add_dependency "weakling", ">= 0.0.1", "< 0.1"
+ end
+ end
+
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "multiple_versioned_deps"
G
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "multiple_versioned_deps"
gem "rack"
@@ -73,7 +116,7 @@ RSpec.describe "bundle install" do
it "includes bundler in the bundle when it's a child dependency" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0"
G
@@ -83,7 +126,7 @@ RSpec.describe "bundle install" do
it "allows gem 'bundler' when Bundler is not in the Gemfile or its dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
@@ -92,53 +135,102 @@ RSpec.describe "bundle install" do
end
it "causes a conflict if child dependencies conflict" do
- install_gemfile <<-G
- source "file://#{gem_repo2}"
+ bundle "config set force_ruby_platform true"
+
+ update_repo2 do
+ build_gem "rails_pinned_to_old_activesupport" do |s|
+ s.add_dependency "activesupport", "= 1.2.3"
+ end
+ end
+
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gem "activemerchant"
- gem "rails_fail"
+ gem "rails_pinned_to_old_activesupport"
G
nice_error = <<-E.strip.gsub(/^ {8}/, "")
- Fetching source index from file:#{gem_repo2}/
- Resolving dependencies...
Bundler could not find compatible versions for gem "activesupport":
In Gemfile:
activemerchant was resolved to 1.0, which depends on
activesupport (>= 2.0.0)
- rails_fail was resolved to 1.0, which depends on
+ rails_pinned_to_old_activesupport was resolved to 1.0, which depends on
activesupport (= 1.2.3)
E
- expect(out).to include(nice_error)
+ expect(err).to include(nice_error)
end
it "causes a conflict if a child dependency conflicts with the Gemfile" do
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gem "rails_fail"
+ bundle "config set force_ruby_platform true"
+
+ update_repo2 do
+ build_gem "rails_pinned_to_old_activesupport" do |s|
+ s.add_dependency "activesupport", "= 1.2.3"
+ end
+ end
+
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rails_pinned_to_old_activesupport"
gem "activesupport", "2.3.5"
G
nice_error = <<-E.strip.gsub(/^ {8}/, "")
- Fetching source index from file:#{gem_repo2}/
- Resolving dependencies...
Bundler could not find compatible versions for gem "activesupport":
In Gemfile:
activesupport (= 2.3.5)
- rails_fail was resolved to 1.0, which depends on
+ rails_pinned_to_old_activesupport was resolved to 1.0, which depends on
activesupport (= 1.2.3)
E
- expect(out).to include(nice_error)
+ expect(err).to include(nice_error)
+ end
+
+ it "does not cause a conflict if new dependencies in the Gemfile require older dependencies than the lockfile" do
+ update_repo2 do
+ build_gem "rails_pinned_to_old_activesupport" do |s|
+ s.add_dependency "activesupport", "= 1.2.3"
+ end
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'rails', "2.3.2"
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rails_pinned_to_old_activesupport"
+ G
+
+ expect(out).to include("Installing activesupport 1.2.3 (was 2.3.2)")
+ expect(err).to be_empty
end
- it "can install dependencies with newer bundler version" do
+ it "can install dependencies with newer bundler version with system gems" do
+ bundle "config set path.system true"
+
+ system_gems "bundler-99999999.99.1"
+
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0"
G
- simulate_bundler_version "10.0.0"
+ bundle "check"
+ expect(out).to include("The Gemfile's dependencies are satisfied")
+ end
+
+ it "can install dependencies with newer bundler version with a local path" do
+ bundle "config set path .bundle"
+
+ system_gems "bundler-99999999.99.1"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rails", "3.0"
+ G
bundle "check"
expect(out).to include("The Gemfile's dependencies are satisfied")
diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb
index bcbd57bc4f..54fc6371cb 100644
--- a/spec/bundler/install/deploy_spec.rb
+++ b/spec/bundler/install/deploy_spec.rb
@@ -1,84 +1,103 @@
# frozen_string_literal: true
-require "spec_helper"
-RSpec.describe "install with --deployment or --frozen" do
+RSpec.describe "install in deployment or frozen mode" do
before do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
- it "fails without a lockfile and says that --deployment requires a lock" do
- bundle "install --deployment"
- expect(out).to include("The --deployment flag requires a Gemfile.lock")
- end
+ context "with CLI flags", :bundler => "< 3" do
+ it "fails without a lockfile and says that --deployment requires a lock" do
+ bundle "install --deployment", :raise_on_error => false
+ expect(err).to include("The --deployment flag requires a Gemfile.lock")
+ end
- it "fails without a lockfile and says that --frozen requires a lock" do
- bundle "install --frozen"
- expect(out).to include("The --frozen flag requires a Gemfile.lock")
- end
+ it "fails without a lockfile and says that --frozen requires a lock" do
+ bundle "install --frozen", :raise_on_error => false
+ expect(err).to include("The --frozen flag requires a Gemfile.lock")
+ end
- it "disallows --deployment --system" do
- bundle "install --deployment --system"
- expect(out).to include("You have specified both --deployment")
- expect(out).to include("Please choose only one option")
- expect(exitstatus).to eq(15) if exitstatus
- end
+ it "disallows --deployment --system" do
+ bundle "install --deployment --system", :raise_on_error => false
+ expect(err).to include("You have specified both --deployment")
+ expect(err).to include("Please choose only one option")
+ expect(exitstatus).to eq(15)
+ end
- it "disallows --deployment --path --system" do
- bundle "install --deployment --path . --system"
- expect(out).to include("You have specified both --path")
- expect(out).to include("as well as --system")
- expect(out).to include("Please choose only one option")
- expect(exitstatus).to eq(15) if exitstatus
- end
+ it "disallows --deployment --path --system" do
+ bundle "install --deployment --path . --system", :raise_on_error => false
+ expect(err).to include("You have specified both --path")
+ expect(err).to include("as well as --system")
+ expect(err).to include("Please choose only one option")
+ expect(exitstatus).to eq(15)
+ end
- it "works after you try to deploy without a lock" do
- bundle "install --deployment"
- bundle :install
- expect(exitstatus).to eq(0) if exitstatus
- expect(the_bundle).to include_gems "rack 1.0"
+ it "doesn't mess up a subsequent `bundle install` after you try to deploy without a lock" do
+ bundle "install --deployment", :raise_on_error => false
+ bundle :install
+ expect(the_bundle).to include_gems "rack 1.0"
+ end
end
it "still works if you are not in the app directory and specify --gemfile" do
bundle "install"
- Dir.chdir tmp
simulate_new_machine
- bundle "install --gemfile #{tmp}/bundled_app/Gemfile --deployment"
- Dir.chdir bundled_app
+ bundle "config set --local deployment true"
+ bundle "config set --local path vendor/bundle"
+ bundle "install --gemfile #{tmp}/bundled_app/Gemfile", :dir => tmp
expect(the_bundle).to include_gems "rack 1.0"
end
it "works if you exclude a group with a git gem" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
group :test do
gem "foo", :git => "#{lib_path("foo-1.0")}"
end
G
bundle :install
- bundle "install --deployment --without test"
- expect(exitstatus).to eq(0) if exitstatus
+ bundle "config set --local deployment true"
+ bundle "config set --local without test"
+ bundle :install
end
it "works when you bundle exec bundle" do
+ skip "doesn't find bundle" if Gem.win_platform?
+
+ bundle :install
+ bundle "config set --local deployment true"
bundle :install
- bundle "install --deployment"
- bundle "exec bundle check"
- expect(exitstatus).to eq(0) if exitstatus
+ bundle "exec bundle check", :env => { "PATH" => path }
end
it "works when using path gems from the same path and the version is specified" do
build_lib "foo", :path => lib_path("nested/foo")
build_lib "bar", :path => lib_path("nested/bar")
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0", :path => "#{lib_path("nested")}"
gem "bar", :path => "#{lib_path("nested")}"
G
- bundle! :install
- bundle! "install --deployment"
+ bundle :install
+ bundle "config set --local deployment true"
+ bundle :install
+ end
+
+ it "works when path gems are specified twice" do
+ build_lib "foo", :path => lib_path("nested/foo")
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => "#{lib_path("nested/foo")}"
+ gem "foo", :path => "#{lib_path("nested/foo")}"
+ G
+
+ bundle :install
+ bundle "config set --local deployment true"
+ bundle :install
end
it "works when there are credentials in the source URL" do
@@ -88,177 +107,317 @@ RSpec.describe "install with --deployment or --frozen" do
gem "rack-obama", ">= 1.0"
G
- bundle "install --deployment", :artifice => "endpoint_strict_basic_authentication"
-
- expect(exitstatus).to eq(0) if exitstatus
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "endpoint_strict_basic_authentication"
end
it "works with sources given by a block" do
install_gemfile <<-G
- source "file://#{gem_repo1}" do
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo1)}" do
gem "rack"
end
G
- bundle "install --deployment"
+ bundle "config set --local deployment true"
+ bundle :install
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems "rack 1.0"
end
+ context "when replacing a host with the same host with credentials" do
+ before do
+ bundle "config set --local path vendor/bundle"
+ bundle "install"
+ gemfile <<-G
+ source "http://user_name:password@localgemserver.test/"
+ gem "rack"
+ G
+
+ lockfile <<-G
+ GEM
+ remote: http://localgemserver.test/
+ specs:
+ rack (1.0.0)
+
+ PLATFORMS
+ #{local}
+
+ DEPENDENCIES
+ rack
+ G
+
+ bundle "config set --local deployment true"
+ end
+
+ it "prevents the replace by default" do
+ bundle :install, :raise_on_error => false
+
+ expect(err).to match(/The list of sources changed/)
+ end
+
+ context "when allow_deployment_source_credential_changes is true" do
+ before { bundle "config set allow_deployment_source_credential_changes true" }
+
+ it "allows the replace" do
+ bundle :install
+
+ expect(out).to match(/Bundle complete!/)
+ end
+ end
+
+ context "when allow_deployment_source_credential_changes is false" do
+ before { bundle "config set allow_deployment_source_credential_changes false" }
+
+ it "prevents the replace" do
+ bundle :install, :raise_on_error => false
+
+ expect(err).to match(/The list of sources changed/)
+ end
+ end
+
+ context "when BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES env var is true" do
+ before { ENV["BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES"] = "true" }
+
+ it "allows the replace" do
+ bundle :install
+
+ expect(out).to match(/Bundle complete!/)
+ end
+ end
+
+ context "when BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES env var is false" do
+ before { ENV["BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES"] = "false" }
+
+ it "prevents the replace" do
+ bundle :install, :raise_on_error => false
+
+ expect(err).to match(/The list of sources changed/)
+ end
+ end
+ end
+
describe "with an existing lockfile" do
before do
bundle "install"
end
- it "works with the --deployment flag if you didn't change anything" do
+ it "installs gems by default to vendor/bundle", :bundler => "< 3" do
+ bundle "install --deployment"
+ expect(out).to include("vendor/bundle")
+ end
+
+ it "installs gems to custom path if specified", :bundler => "< 3" do
+ bundle "install --path vendor/bundle2 --deployment"
+ expect(out).to include("vendor/bundle2")
+ end
+
+ it "works with the --deployment flag if you didn't change anything", :bundler => "< 3" do
bundle "install --deployment"
- expect(exitstatus).to eq(0) if exitstatus
end
- it "works with the --frozen flag if you didn't change anything" do
+ it "works with the --frozen flag if you didn't change anything", :bundler => "< 3" do
bundle "install --frozen"
- expect(exitstatus).to eq(0) if exitstatus
+ end
+
+ it "works with BUNDLE_FROZEN if you didn't change anything" do
+ bundle :install, :env => { "BUNDLE_FROZEN" => "true" }
end
it "explodes with the --deployment flag if you make a change and don't check in the lockfile" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rack-obama"
G
- bundle "install --deployment"
- expect(out).to include("deployment mode")
- expect(out).to include("You have added to the Gemfile")
- expect(out).to include("* rack-obama")
- expect(out).not_to include("You have deleted from the Gemfile")
- expect(out).not_to include("You have changed in the Gemfile")
+ bundle "config set --local deployment true"
+ bundle :install, :raise_on_error => false
+ expect(err).to include("deployment mode")
+ expect(err).to include("You have added to the Gemfile")
+ expect(err).to include("* rack-obama")
+ expect(err).not_to include("You have deleted from the Gemfile")
+ expect(err).not_to include("You have changed in the Gemfile")
end
- it "can have --frozen set via an environment variable" do
+ it "works if a path gem is missing but is in a without group" do
+ build_lib "path_gem"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rake"
+ gem "path_gem", :path => "#{lib_path("path_gem-1.0")}", :group => :development
+ G
+ expect(the_bundle).to include_gems "path_gem 1.0"
+ FileUtils.rm_r lib_path("path_gem-1.0")
+
+ bundle "config set --local path .bundle"
+ bundle "config set --local without development"
+ bundle "config set --local deployment true"
+ bundle :install, :env => { "DEBUG" => "1" }
+ run "puts :WIN"
+ expect(out).to eq("WIN")
+ end
+
+ it "explodes if a path gem is missing" do
+ build_lib "path_gem"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rake"
+ gem "path_gem", :path => "#{lib_path("path_gem-1.0")}", :group => :development
+ G
+ expect(the_bundle).to include_gems "path_gem 1.0"
+ FileUtils.rm_r lib_path("path_gem-1.0")
+
+ bundle "config set --local path .bundle"
+ bundle "config set --local deployment true"
+ bundle :install, :raise_on_error => false
+ expect(err).to include("The path `#{lib_path("path_gem-1.0")}` does not exist.")
+ end
+
+ it "can have --frozen set via an environment variable", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rack-obama"
G
ENV["BUNDLE_FROZEN"] = "1"
- bundle "install"
- expect(out).to include("deployment mode")
- expect(out).to include("You have added to the Gemfile")
- expect(out).to include("* rack-obama")
- expect(out).not_to include("You have deleted from the Gemfile")
- expect(out).not_to include("You have changed in the Gemfile")
+ bundle "install", :raise_on_error => false
+ expect(err).to include("deployment mode")
+ expect(err).to include("You have added to the Gemfile")
+ expect(err).to include("* rack-obama")
+ expect(err).not_to include("You have deleted from the Gemfile")
+ expect(err).not_to include("You have changed in the Gemfile")
end
- it "can have --frozen set to false via an environment variable" do
+ it "can have --deployment set via an environment variable" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rack-obama"
G
- ENV["BUNDLE_FROZEN"] = "false"
+ ENV["BUNDLE_DEPLOYMENT"] = "true"
+ bundle "install", :raise_on_error => false
+ expect(err).to include("deployment mode")
+ expect(err).to include("You have added to the Gemfile")
+ expect(err).to include("* rack-obama")
+ expect(err).not_to include("You have deleted from the Gemfile")
+ expect(err).not_to include("You have changed in the Gemfile")
+ end
+
+ it "installs gems by default to vendor/bundle when deployment mode is set via an environment variable", :bundler => "< 3" do
+ ENV["BUNDLE_DEPLOYMENT"] = "true"
bundle "install"
- expect(out).not_to include("deployment mode")
- expect(out).not_to include("You have added to the Gemfile")
- expect(out).not_to include("* rack-obama")
+ expect(out).to include("vendor/bundle")
+ end
+
+ it "installs gems to custom path when deployment mode is set via an environment variable ", :bundler => "< 3" do
+ ENV["BUNDLE_DEPLOYMENT"] = "true"
+ ENV["BUNDLE_PATH"] = "vendor/bundle2"
+ bundle "install"
+ expect(out).to include("vendor/bundle2")
end
- it "explodes with the --frozen flag if you make a change and don't check in the lockfile" do
+ it "can have --frozen set to false via an environment variable" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
- gem "rack-obama", "1.1"
+ gem "rack-obama"
G
- bundle "install --frozen"
- expect(out).to include("deployment mode")
- expect(out).to include("You have added to the Gemfile")
- expect(out).to include("* rack-obama (= 1.1)")
- expect(out).not_to include("You have deleted from the Gemfile")
- expect(out).not_to include("You have changed in the Gemfile")
+ ENV["BUNDLE_FROZEN"] = "false"
+ ENV["BUNDLE_DEPLOYMENT"] = "false"
+ bundle "install"
+ expect(out).not_to include("deployment mode")
+ expect(out).not_to include("You have added to the Gemfile")
+ expect(out).not_to include("* rack-obama")
end
it "explodes if you remove a gem and don't check in the lockfile" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
G
- bundle "install --deployment"
- expect(out).to include("deployment mode")
- expect(out).to include("You have added to the Gemfile:\n* activesupport\n\n")
- expect(out).to include("You have deleted from the Gemfile:\n* rack")
- expect(out).not_to include("You have changed in the Gemfile")
+ bundle "config set --local deployment true"
+ bundle :install, :raise_on_error => false
+ expect(err).to include("deployment mode")
+ expect(err).to include("You have added to the Gemfile:\n* activesupport\n\n")
+ expect(err).to include("You have deleted from the Gemfile:\n* rack")
+ expect(err).not_to include("You have changed in the Gemfile")
end
it "explodes if you add a source" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "git://hubz.com"
G
- bundle "install --deployment"
- expect(out).to include("deployment mode")
- expect(out).to include("You have added to the Gemfile:\n* source: git://hubz.com (at master)")
- expect(out).not_to include("You have changed in the Gemfile")
+ bundle "config set --local deployment true"
+ bundle :install, :raise_on_error => false
+ expect(err).to include("deployment mode")
+ expect(err).not_to include("You have added to the Gemfile")
+ expect(err).to include("You have changed in the Gemfile:\n* rack from `no specified source` to `git://hubz.com`")
end
- it "explodes if you unpin a source" do
+ it "explodes if you change a source" do
build_git "rack"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-1.0")}"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "install --deployment"
- expect(out).to include("deployment mode")
- expect(out).to include("You have deleted from the Gemfile:\n* source: #{lib_path("rack-1.0")} (at master@#{revision_for(lib_path("rack-1.0"))[0..6]}")
- expect(out).not_to include("You have added to the Gemfile")
- expect(out).not_to include("You have changed in the Gemfile")
+ bundle "config set --local deployment true"
+ bundle :install, :raise_on_error => false
+ expect(err).to include("deployment mode")
+ expect(err).not_to include("You have deleted from the Gemfile")
+ expect(err).not_to include("You have added to the Gemfile")
+ expect(err).to include("You have changed in the Gemfile:\n* rack from `#{lib_path("rack-1.0")}` to `no specified source`")
end
- it "explodes if you unpin a source, leaving it pinned somewhere else" do
+ it "explodes if you change a source" do
build_lib "foo", :path => lib_path("rack/foo")
build_git "rack", :path => lib_path("rack")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack")}"
gem "foo", :git => "#{lib_path("rack")}"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "foo", :git => "#{lib_path("rack")}"
G
- bundle "install --deployment"
- expect(out).to include("deployment mode")
- expect(out).to include("You have changed in the Gemfile:\n* rack from `no specified source` to `#{lib_path("rack")} (at master@#{revision_for(lib_path("rack"))[0..6]})`")
- expect(out).not_to include("You have added to the Gemfile")
- expect(out).not_to include("You have deleted from the Gemfile")
+ bundle "config set --local deployment true"
+ bundle :install, :raise_on_error => false
+ expect(err).to include("deployment mode")
+ expect(err).to include("You have changed in the Gemfile:\n* rack from `#{lib_path("rack")}` to `no specified source`")
+ expect(err).not_to include("You have added to the Gemfile")
+ expect(err).not_to include("You have deleted from the Gemfile")
end
it "remembers that the bundle is frozen at runtime" do
- bundle "install --deployment"
+ bundle :lock
+
+ bundle "config set --local deployment true"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
gem "rack-obama"
G
- expect(the_bundle).not_to include_gems "rack 1.0.0"
+ run "require 'rack'", :raise_on_error => false
expect(err).to include strip_whitespace(<<-E).strip
The dependencies in your gemfile changed
@@ -275,25 +434,27 @@ You have deleted from the Gemfile:
context "with path in Gemfile and packed" do
it "works fine after bundle package and bundle install --local" do
build_lib "foo", :path => lib_path("foo")
- install_gemfile! <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
- bundle! :install
+ bundle :install
expect(the_bundle).to include_gems "foo 1.0"
- bundle! "package --all"
+
+ bundle "config set cache_all true"
+ bundle :cache
expect(bundled_app("vendor/cache/foo")).to be_directory
- bundle! "install --local"
- expect(out).to include("Using foo 1.0 from source at")
- expect(out).to include("vendor/cache/foo")
+ bundle "install --local"
+ expect(out).to include("Updating files in vendor/cache")
simulate_new_machine
- bundle! "install --deployment --verbose"
+ bundle "config set --local deployment true"
+ bundle "install --verbose"
expect(out).not_to include("You are trying to install in deployment mode after changing your Gemfile")
expect(out).not_to include("You have added to the Gemfile")
expect(out).not_to include("You have deleted from the Gemfile")
- expect(out).to include("Using foo 1.0 from source at")
expect(out).to include("vendor/cache/foo")
expect(the_bundle).to include_gems "foo 1.0"
end
diff --git a/spec/bundler/install/failure_spec.rb b/spec/bundler/install/failure_spec.rb
index 738b2cf1bd..4a9c33754f 100644
--- a/spec/bundler/install/failure_spec.rb
+++ b/spec/bundler/install/failure_spec.rb
@@ -1,9 +1,8 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
context "installing a gem fails" do
- it "prints out why that gem was being installed" do
+ it "prints out why that gem was being installed and the underlying error" do
build_repo2 do
build_gem "activesupport", "2.3.2" do |s|
s.extensions << "Rakefile"
@@ -15,13 +14,13 @@ RSpec.describe "bundle install" do
end
end
- install_gemfile <<-G
- source "file:#{gem_repo2}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gem "rails"
G
- expect(out).to end_with(<<-M.strip)
+ expect(err).to start_with("Gem::Ext::BuildError: ERROR: Failed to build gem native extension.")
+ expect(err).to end_with(<<-M.strip)
An error occurred while installing activesupport (2.3.2), and Bundler cannot continue.
-Make sure that `gem install activesupport -v '2.3.2'` succeeds before bundling.
In Gemfile:
rails was resolved to 2.3.2, which depends on
@@ -29,5 +28,24 @@ In Gemfile:
activesupport
M
end
+
+ context "because the downloaded .gem was invalid" do
+ before do
+ build_repo4 do
+ build_gem "a"
+ end
+
+ gem_repo4("gems", "a-1.0.gem").open("w") {|f| f << "<html></html>" }
+ end
+
+ it "removes the downloaded .gem" do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a"
+ G
+
+ expect(default_bundle_path("cache", "a-1.0.gem")).not_to exist
+ end
+ end
end
end
diff --git a/spec/bundler/install/force_spec.rb b/spec/bundler/install/force_spec.rb
deleted file mode 100644
index dc4956a7ae..0000000000
--- a/spec/bundler/install/force_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-
-RSpec.describe "bundle install" do
- describe "with --force" do
- before :each do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
- end
-
- it "re-installs installed gems" do
- rack_lib = default_bundle_path("gems/rack-1.0.0/lib/rack.rb")
-
- bundle "install"
- rack_lib.open("w") {|f| f.write("blah blah blah") }
- bundle "install --force"
-
- expect(exitstatus).to eq(0) if exitstatus
- expect(out).to include "Using bundler"
- expect(out).to include "Installing rack 1.0.0"
- expect(rack_lib.open(&:read)).to eq("RACK = '1.0.0'\n")
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
-
- it "works on first bundle install" do
- bundle "install --force"
-
- expect(exitstatus).to eq(0) if exitstatus
- expect(out).to include "Using bundler"
- expect(out).to include "Installing rack 1.0.0"
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
-
- context "with a git gem" do
- let!(:ref) { build_git("foo", "1.0").ref_for("HEAD", 11) }
-
- before do
- gemfile <<-G
- gem "foo", :git => "#{lib_path("foo-1.0")}"
- G
- end
-
- it "re-installs installed gems" do
- foo_lib = default_bundle_path("bundler/gems/foo-1.0-#{ref}/lib/foo.rb")
-
- bundle! "install"
- foo_lib.open("w") {|f| f.write("blah blah blah") }
- bundle! "install --force"
-
- expect(out).to include "Using bundler"
- expect(out).to include "Using foo 1.0 from #{lib_path("foo-1.0")} (at master@#{ref[0, 7]})"
- expect(foo_lib.open(&:read)).to eq("FOO = '1.0'\n")
- expect(the_bundle).to include_gems "foo 1.0"
- end
-
- it "works on first bundle install" do
- bundle! "install --force"
-
- expect(out).to include "Using bundler"
- expect(out).to include "Using foo 1.0 from #{lib_path("foo-1.0")} (at master@#{ref[0, 7]})"
- expect(the_bundle).to include_gems "foo 1.0"
- end
- end
- end
-end
diff --git a/spec/bundler/install/gemfile/eval_gemfile_spec.rb b/spec/bundler/install/gemfile/eval_gemfile_spec.rb
index f02223d34d..02283291b4 100644
--- a/spec/bundler/install/gemfile/eval_gemfile_spec.rb
+++ b/spec/bundler/install/gemfile/eval_gemfile_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
before do
@@ -12,42 +11,82 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
context "eval-ed Gemfile points to an internal gemspec" do
before do
create_file "Gemfile-other", <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => 'gems/gunks'
G
end
it "installs the gemspec specified gem" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
eval_gemfile 'Gemfile-other'
G
expect(out).to include("Resolving dependencies")
- expect(out).to include("Using gunks 0.0.1 from source at `gems/gunks`")
expect(out).to include("Bundle complete")
+
+ expect(the_bundle).to include_gem "gunks 0.0.1", :source => "path@#{bundled_app("gems", "gunks")}"
+ end
+ end
+
+ context "eval-ed Gemfile points to an internal gemspec and uses a scoped source that duplicates the main Gemfile global source" do
+ before do
+ build_repo2 do
+ build_gem "rails", "6.1.3.2"
+
+ build_gem "zip-zip", "0.3"
+ end
+
+ create_file bundled_app("gems/Gemfile"), <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gemspec :path => "\#{__dir__}/gunks"
+
+ source "#{file_uri_for(gem_repo2)}" do
+ gem "zip-zip"
+ end
+ G
+ end
+
+ it "installs and finds gems correctly" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "rails"
+
+ eval_gemfile File.join(__dir__, "gems/Gemfile")
+ G
+ expect(out).to include("Resolving dependencies")
+ expect(out).to include("Bundle complete")
+
+ expect(the_bundle).to include_gem "rails 6.1.3.2"
end
end
context "eval-ed Gemfile has relative-path gems" do
before do
- build_lib("a", :path => "gems/a")
- create_file "nested/Gemfile-nested", <<-G
+ build_lib("a", :path => bundled_app("gems/a"))
+ create_file bundled_app("nested/Gemfile-nested"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "a", :path => "../gems/a"
G
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
eval_gemfile "nested/Gemfile-nested"
G
end
it "installs the path gem" do
- bundle! :install
+ bundle :install
expect(the_bundle).to include_gem("a 1.0")
end
# Make sure that we are properly comparing path based gems between the
# parsed lockfile and the evaluated gemfile.
- it "bundles with --deployment" do
- bundle! :install
- bundle! "install --deployment"
+ it "bundles with deployment mode configured" do
+ bundle :install
+ bundle "config set --local deployment true"
+ bundle :install
end
end
@@ -56,12 +95,28 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
it "installs the gemspec specified gem" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
eval_gemfile 'other/Gemfile-other'
gemspec :path => 'gems/gunks'
G
expect(out).to include("Resolving dependencies")
- expect(out).to include("Using gunks 0.0.1 from source at `gems/gunks`")
expect(out).to include("Bundle complete")
+
+ expect(the_bundle).to include_gem "gunks 0.0.1", :source => "path@#{bundled_app("gems", "gunks")}"
+ end
+ end
+
+ context "eval-ed Gemfile references other gemfiles" do
+ it "works with relative paths" do
+ create_file "other/Gemfile-other", "gem 'rack'"
+ create_file "other/Gemfile", "eval_gemfile 'Gemfile-other'"
+ create_file "Gemfile-alt", <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ eval_gemfile "other/Gemfile"
+ G
+ install_gemfile "eval_gemfile File.expand_path('Gemfile-alt')"
+
+ expect(the_bundle).to include_gem "rack 1.0.0"
end
end
end
diff --git a/spec/bundler/install/gemfile/gemspec_spec.rb b/spec/bundler/install/gemfile/gemspec_spec.rb
index 1ea613c9d2..6d9cd2daff 100644
--- a/spec/bundler/install/gemfile/gemspec_spec.rb
+++ b/spec/bundler/install/gemfile/gemspec_spec.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install from an existing gemspec" do
before(:each) do
- build_gem "bar", :to_system => true
- build_gem "bar-dev", :to_system => true
+ build_repo2 do
+ build_gem "bar"
+ build_gem "bar-dev"
+ end
end
it "should install runtime and development dependencies" do
@@ -14,7 +15,7 @@ RSpec.describe "bundle install from an existing gemspec" do
s.add_development_dependency "bar-dev", "=1.0.0"
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}'
G
@@ -31,7 +32,7 @@ RSpec.describe "bundle install from an existing gemspec" do
FileUtils.mv tmp.join("foo", "foo.gemspec"), tmp.join("foo", ".gemspec")
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}'
G
@@ -40,15 +41,17 @@ RSpec.describe "bundle install from an existing gemspec" do
end
it "should handle a list of requirements" do
- build_gem "baz", "1.0", :to_system => true
- build_gem "baz", "1.1", :to_system => true
+ update_repo2 do
+ build_gem "baz", "1.0"
+ build_gem "baz", "1.1"
+ end
build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("Gemfile", "source :rubygems\ngemspec")
s.add_dependency "baz", ">= 1.0", "< 1.1"
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}'
G
@@ -58,11 +61,11 @@ RSpec.describe "bundle install from an existing gemspec" do
it "should raise if there are no gemspecs available" do
build_lib("foo", :path => tmp.join("foo"), :gemspec => false)
- error = install_gemfile(<<-G)
- source "file://#{gem_repo2}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}'
G
- expect(error).to match(/There are no gemspecs at #{tmp.join('foo')}/)
+ expect(err).to match(/There are no gemspecs at #{tmp.join('foo')}/)
end
it "should raise if there are too many gemspecs available" do
@@ -70,11 +73,11 @@ RSpec.describe "bundle install from an existing gemspec" do
s.write("foo2.gemspec", build_spec("foo", "4.0").first.to_ruby)
end
- error = install_gemfile(<<-G)
- source "file://#{gem_repo2}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}'
G
- expect(error).to match(/There are multiple gemspecs at #{tmp.join('foo')}/)
+ expect(err).to match(/There are multiple gemspecs at #{tmp.join('foo')}/)
end
it "should pick a specific gemspec" do
@@ -85,7 +88,7 @@ RSpec.describe "bundle install from an existing gemspec" do
end
install_gemfile(<<-G)
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
G
@@ -101,7 +104,7 @@ RSpec.describe "bundle install from an existing gemspec" do
end
install_gemfile(<<-G)
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}', :name => 'foo', :development_group => :dev
G
@@ -112,23 +115,22 @@ RSpec.describe "bundle install from an existing gemspec" do
it "should match a lockfile even if the gemspec defines development dependencies" do
build_lib("foo", :path => tmp.join("foo")) do |s|
- s.write("Gemfile", "source 'file://#{gem_repo1}'\ngemspec")
+ s.write("Gemfile", "source '#{file_uri_for(gem_repo1)}'\ngemspec")
s.add_dependency "actionpack", "=2.3.2"
- s.add_development_dependency "rake", "=10.0.2"
+ s.add_development_dependency "rake", "=13.0.1"
end
- Dir.chdir(tmp.join("foo")) do
- bundle "install"
- # This should really be able to rely on $stderr, but, it's not written
- # right, so we can't. In fact, this is a bug negation test, and so it'll
- # ghost pass in future, and will only catch a regression if the message
- # doesn't change. Exit codes should be used correctly (they can be more
- # than just 0 and 1).
- output = bundle("install --deployment")
- expect(output).not_to match(/You have added to the Gemfile/)
- expect(output).not_to match(/You have deleted from the Gemfile/)
- expect(output).not_to match(/install in deployment mode after changing/)
- end
+ bundle "install", :dir => tmp.join("foo")
+ # This should really be able to rely on $stderr, but, it's not written
+ # right, so we can't. In fact, this is a bug negation test, and so it'll
+ # ghost pass in future, and will only catch a regression if the message
+ # doesn't change. Exit codes should be used correctly (they can be more
+ # than just 0 and 1).
+ bundle "config set --local deployment true"
+ output = bundle("install", :dir => tmp.join("foo"))
+ expect(output).not_to match(/You have added to the Gemfile/)
+ expect(output).not_to match(/You have deleted from the Gemfile/)
+ expect(output).not_to match(/install in deployment mode after changing/)
end
it "should match a lockfile without needing to re-resolve" do
@@ -136,13 +138,15 @@ RSpec.describe "bundle install from an existing gemspec" do
s.add_dependency "rack"
end
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => '#{tmp.join("foo")}'
G
- bundle! "install", :verbose => true
- expect(out).to include("Found no changes, using resolution from the lockfile")
+ bundle "install", :verbose => true
+
+ message = "Found no changes, using resolution from the lockfile"
+ expect(out.scan(message).size).to eq(1)
end
it "should match a lockfile without needing to re-resolve with development dependencies" do
@@ -153,30 +157,29 @@ RSpec.describe "bundle install from an existing gemspec" do
s.add_development_dependency "thin"
end
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => '#{tmp.join("foo")}'
G
- bundle! "install", :verbose => true
- expect(out).to include("Found no changes, using resolution from the lockfile")
- end
+ bundle "install", :verbose => true
- it "should match a lockfile on non-ruby platforms with a transitive platform dependency" do
- simulate_platform java
- simulate_ruby_engine "jruby"
+ message = "Found no changes, using resolution from the lockfile"
+ expect(out.scan(message).size).to eq(1)
+ end
+ it "should match a lockfile on non-ruby platforms with a transitive platform dependency", :jruby do
build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "platform_specific"
end
- install_gem "platform_specific-1.0-java"
+ system_gems "platform_specific-1.0-java", :path => default_bundle_path
- install_gemfile! <<-G
+ install_gemfile <<-G
gemspec :path => '#{tmp.join("foo")}'
G
- bundle! "update --bundler", :verbose => true
+ bundle "update --bundler", :verbose => true
expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 JAVA"
end
@@ -186,26 +189,28 @@ RSpec.describe "bundle install from an existing gemspec" do
s.write "raise 'ahh' unless Dir.pwd == '#{tmp.join("foo")}'"
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
gemspec :path => '#{tmp.join("foo")}'
G
- expect(@err).not_to match(/ahh/)
+ expect(last_command.stdboth).not_to include("ahh")
end
it "allows the gemspec to activate other gems" do
- # see https://github.com/bundler/bundler/issues/5409
+ ENV["BUNDLE_PATH__SYSTEM"] = "true"
+ # see https://github.com/rubygems/bundler/issues/5409
#
# issue was caused by rubygems having an unresolved gem during a require,
# so emulate that
- system_gems %w(rack-1.0.0 rack-0.9.1 rack-obama-1.0)
+ system_gems %w[rack-1.0.0 rack-0.9.1 rack-obama-1.0]
build_lib("foo", :path => bundled_app)
gemspec = bundled_app("foo.gemspec").read
bundled_app("foo.gemspec").open("w") do |f|
- f.write "#{gemspec.strip}.tap { gem 'rack-obama'; require 'rack-obama' }"
+ f.write "#{gemspec.strip}.tap { gem 'rack-obama'; require 'rack/obama' }"
end
- install_gemfile! <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
@@ -217,13 +222,13 @@ RSpec.describe "bundle install from an existing gemspec" do
s.version = "1.0.0"
s.add_dependency "bar", "= 1.0.0"
end
- build_gem "deps", :to_system => true do |s|
+ build_gem "deps", :to_bundle => true do |s|
s.add_dependency "foo", "= 0.0.1"
end
- build_gem "foo", "0.0.1", :to_system => true
+ build_gem "foo", "0.0.1", :to_bundle => true
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "deps"
gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
G
@@ -231,30 +236,45 @@ RSpec.describe "bundle install from an existing gemspec" do
expect(the_bundle).to include_gems "foo 1.0.0"
end
- it "does not break Gem.finish_resolve with conflicts", :rubygems => ">= 2" do
+ it "does not break Gem.finish_resolve with conflicts" do
build_lib("foo", :path => tmp.join("foo")) do |s|
s.version = "1.0.0"
s.add_dependency "bar", "= 1.0.0"
end
- build_repo2 do
+ update_repo2 do
build_gem "deps" do |s|
s.add_dependency "foo", "= 0.0.1"
end
build_gem "foo", "0.0.1"
end
- install_gemfile! <<-G
- source "file://#{gem_repo2}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
gem "deps"
gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
G
expect(the_bundle).to include_gems "foo 1.0.0"
- run! "Gem.finish_resolve; puts 'WIN'"
+ run "Gem.finish_resolve; puts 'WIN'"
expect(out).to eq("WIN")
end
+ it "handles downgrades" do
+ build_lib "omg", "2.0", :path => lib_path("omg")
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gemspec :path => "#{lib_path("omg")}"
+ G
+
+ build_lib "omg", "1.0", :path => lib_path("omg")
+
+ bundle :install
+
+ expect(the_bundle).to include_gems "omg 1.0"
+ end
+
context "in deployment mode" do
context "when the lockfile was not updated after a change to the gemspec's dependencies" do
it "reports that installation failed" do
@@ -262,8 +282,8 @@ RSpec.describe "bundle install from an existing gemspec" do
s.add_dependency "activesupport", ">= 1"
end
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
@@ -273,9 +293,10 @@ RSpec.describe "bundle install from an existing gemspec" do
s.add_dependency "activesupport", ">= 1.0.1"
end
- bundle "install --deployment"
+ bundle "config set --local deployment true"
+ bundle :install, :raise_on_error => false
- expect(out).to include("changed")
+ expect(err).to include("changed")
end
end
end
@@ -296,7 +317,7 @@ RSpec.describe "bundle install from an existing gemspec" do
it "should install the child gemspec's deps" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
@@ -309,24 +330,14 @@ RSpec.describe "bundle install from an existing gemspec" do
context "previously bundled for Ruby" do
let(:platform) { "ruby" }
- let(:explicit_platform) { false }
before do
+ skip "not installing for some reason" if Gem.win_platform?
+
build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack", "=1.0.0"
end
- if explicit_platform
- create_file(
- tmp.join("foo", "foo-#{platform}.gemspec"),
- build_spec("foo", "1.0", platform) do
- dep "rack", "=1.0.0"
- @spec.authors = "authors"
- @spec.summary = "summary"
- end.first.to_ruby
- )
- end
-
gemfile <<-G
source "#{source_uri}"
gemspec :path => "../foo"
@@ -355,32 +366,30 @@ RSpec.describe "bundle install from an existing gemspec" do
L
end
- context "using JRuby with explicit platform" do
- let(:platform) { "java" }
- let(:explicit_platform) { true }
+ context "using JRuby with explicit platform", :jruby do
+ before do
+ create_file(
+ tmp.join("foo", "foo-java.gemspec"),
+ build_spec("foo", "1.0", "java") do
+ dep "rack", "=1.0.0"
+ @spec.authors = "authors"
+ @spec.summary = "summary"
+ end.first.to_ruby
+ )
+ end
it "should install" do
- simulate_ruby_engine "jruby" do
- simulate_platform "java" do
- results = bundle "install", :artifice => "endpoint"
- expect(results).to include("Installing rack 1.0.0")
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
- end
+ results = bundle "install", :artifice => "endpoint"
+ expect(results).to include("Installing rack 1.0.0")
+ expect(the_bundle).to include_gems "rack 1.0.0"
end
end
- context "using JRuby" do
- let(:platform) { "java" }
-
+ context "using JRuby", :jruby do
it "should install" do
- simulate_ruby_engine "jruby" do
- simulate_platform "java" do
- results = bundle "install", :artifice => "endpoint"
- expect(results).to include("Installing rack 1.0.0")
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
- end
+ results = bundle "install", :artifice => "endpoint"
+ expect(results).to include("Installing rack 1.0.0")
+ expect(the_bundle).to include_gems "rack 1.0.0"
end
end
@@ -405,7 +414,7 @@ RSpec.describe "bundle install from an existing gemspec" do
end
end
- build_lib "foo", :path => "." do |s|
+ build_lib "foo", :path => bundled_app do |s|
if platform_specific_type == :runtime
s.add_runtime_dependency dependency
elsif platform_specific_type == :development
@@ -415,14 +424,13 @@ RSpec.describe "bundle install from an existing gemspec" do
end
end
- %w(ruby jruby).each do |platform|
- simulate_platform(platform) do
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- gemspec
- G
- end
- end
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gemspec
+ G
+
+ simulate_platform("ruby") { bundle "install" }
+ simulate_platform("jruby") { bundle "install" }
end
context "on ruby" do
@@ -442,7 +450,7 @@ RSpec.describe "bundle install from an existing gemspec" do
platform_specific
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
platform_specific (1.0)
platform_specific (1.0-java)
@@ -472,7 +480,7 @@ RSpec.describe "bundle install from an existing gemspec" do
foo (1.0)
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
platform_specific (1.0)
platform_specific (1.0-java)
@@ -504,7 +512,7 @@ RSpec.describe "bundle install from an existing gemspec" do
foo (1.0)
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
indirect_platform_specific (1.0)
platform_specific
@@ -540,19 +548,20 @@ RSpec.describe "bundle install from an existing gemspec" do
it "installs the ruby platform gemspec" do
simulate_platform "ruby"
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
G
expect(the_bundle).to include_gems "foo 1.0.0", "rack 1.0.0"
end
- it "installs the ruby platform gemspec and skips dev deps with --without development" do
+ it "installs the ruby platform gemspec and skips dev deps with `without development` configured" do
simulate_platform "ruby"
- install_gemfile! <<-G, :without => "development"
- source "file://#{gem_repo1}"
+ bundle "config set --local without development"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
G
@@ -560,4 +569,57 @@ RSpec.describe "bundle install from an existing gemspec" do
expect(the_bundle).not_to include_gem "rack"
end
end
+
+ context "with multiple platforms and resolving for more specific platforms" do
+ before do
+ build_lib("chef", :path => tmp.join("chef")) do |s|
+ s.version = "17.1.17"
+ s.write "chef-universal-mingw32.gemspec", build_spec("chef", "17.1.17", "universal-mingw32") {|sw| sw.runtime "win32-api", "~> 1.5.3" }.first.to_ruby
+ end
+ end
+
+ it "does not remove the platform specific specs from the lockfile when updating" do
+ build_repo4 do
+ build_gem "win32-api", "1.5.3" do |s|
+ s.platform = "universal-mingw32"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gemspec :path => "../chef"
+ G
+
+ initial_lockfile = <<~L
+ PATH
+ remote: ../chef
+ specs:
+ chef (17.1.17)
+ chef (17.1.17-universal-mingw32)
+ win32-api (~> 1.5.3)
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ win32-api (1.5.3-universal-mingw32)
+
+ PLATFORMS
+ ruby
+ x64-mingw32
+ x86-mingw32
+
+ DEPENDENCIES
+ chef!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ lockfile initial_lockfile
+
+ bundle "update"
+
+ expect(lockfile).to eq initial_lockfile
+ end
+ end
end
diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb
index 5868c76570..fd3afe366a 100644
--- a/spec/bundler/install/gemfile/git_spec.rb
+++ b/spec/bundler/install/gemfile/git_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with git sources" do
describe "when floating on master" do
@@ -9,7 +8,7 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem 'foo'
end
@@ -27,8 +26,19 @@ RSpec.describe "bundle install with git sources" do
expect(out).to eq("WIN")
end
- it "caches the git repo" do
- expect(Dir["#{default_bundle_path}/cache/bundler/git/foo-1.0-*"].size).to eq(1)
+ it "caches the git repo", :bundler => "< 3" do
+ expect(Dir["#{default_bundle_path}/cache/bundler/git/foo-1.0-*"]).to have_attributes :size => 1
+ end
+
+ it "caches the git repo globally and properly uses the cached repo on the next invocation" do
+ simulate_new_machine
+ bundle "config set global_gem_cache true"
+ bundle :install
+ expect(Dir["#{home}/.bundle/cache/git/foo-1.0-*"]).to have_attributes :size => 1
+
+ bundle "install --verbose"
+ expect(err).to be_empty
+ expect(out).to include("Using foo 1.0 from #{lib_path("foo")}")
end
it "caches the evaluated gemspec" do
@@ -51,22 +61,19 @@ RSpec.describe "bundle install with git sources" do
it "does not update the git source implicitly" do
update_git "foo"
- in_app_root2 do
- install_gemfile bundled_app2("Gemfile"), <<-G
- git "#{lib_path("foo-1.0")}" do
- gem 'foo'
- end
- G
- end
+ install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2
+ source "#{file_uri_for(gem_repo1)}"
+ git "#{lib_path("foo-1.0")}" do
+ gem 'foo'
+ end
+ G
- in_app_root do
- run <<-RUBY
- require 'foo'
- puts "fail" if defined?(FOO_PREV_REF)
- RUBY
+ run <<-RUBY
+ require 'foo'
+ puts "fail" if defined?(FOO_PREV_REF)
+ RUBY
- expect(out).to be_empty
- end
+ expect(out).to be_empty
end
it "sets up git gem executables on the path" do
@@ -77,11 +84,12 @@ RSpec.describe "bundle install with git sources" do
it "complains if pinned specs don't exist in the git repo" do
build_git "foo"
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.1", :git => "#{lib_path("foo-1.0")}"
G
- expect(out).to include("Source contains 'foo' at: 1.0 ruby")
+ expect(err).to include("The source contains the following versions of 'foo': 1.0")
end
it "complains with version and platform if pinned specs don't exist in the git repo" do
@@ -91,13 +99,14 @@ RSpec.describe "bundle install with git sources" do
s.platform = "java"
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
platforms :jruby do
gem "only_java", "1.2", :git => "#{lib_path("only_java-1.0-java")}"
end
G
- expect(out).to include("Source contains 'only_java' at: 1.0 java")
+ expect(err).to include("The source contains the following versions of 'only_java': 1.0 java")
end
it "complains with multiple versions and platforms if pinned specs don't exist in the git repo" do
@@ -112,32 +121,35 @@ RSpec.describe "bundle install with git sources" do
s.write "only_java1-0.gemspec", File.read("#{lib_path("only_java-1.0-java")}/only_java.gemspec")
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
platforms :jruby do
gem "only_java", "1.2", :git => "#{lib_path("only_java-1.1-java")}"
end
G
- expect(out).to include("Source contains 'only_java' at: 1.0 java, 1.1 java")
+ expect(err).to include("The source contains the following versions of 'only_java': 1.0 java, 1.1 java")
end
it "still works after moving the application directory" do
- bundle "install --path vendor/bundle"
+ bundle "config set --local path vendor/bundle"
+ bundle "install"
+
FileUtils.mv bundled_app, tmp("bundled_app.bck")
- Dir.chdir tmp("bundled_app.bck")
- expect(the_bundle).to include_gems "foo 1.0"
+ expect(the_bundle).to include_gems "foo 1.0", :dir => tmp("bundled_app.bck")
end
it "can still install after moving the application directory" do
- bundle "install --path vendor/bundle"
+ bundle "config set --local path vendor/bundle"
+ bundle "install"
+
FileUtils.mv bundled_app, tmp("bundled_app.bck")
update_git "foo", "1.1", :path => lib_path("foo-1.0")
- Dir.chdir tmp("bundled_app.bck")
gemfile tmp("bundled_app.bck/Gemfile"), <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem 'foo'
end
@@ -145,9 +157,9 @@ RSpec.describe "bundle install with git sources" do
gem "rack", "1.0"
G
- bundle "update foo"
+ bundle "update foo", :dir => tmp("bundled_app.bck")
- expect(the_bundle).to include_gems "foo 1.1", "rack 1.0"
+ expect(the_bundle).to include_gems "foo 1.1", "rack 1.0", :dir => tmp("bundled_app.bck")
end
end
@@ -155,7 +167,7 @@ RSpec.describe "bundle install with git sources" do
before do
build_git "foo"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
git "#{lib_path("foo-1.0")}" do
@@ -179,6 +191,7 @@ RSpec.describe "bundle install with git sources" do
it "works" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}", :ref => "#{@revision}" do
gem "foo"
end
@@ -194,11 +207,12 @@ RSpec.describe "bundle install with git sources" do
it "works when the revision is a symbol" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}", :ref => #{@revision.to_sym.inspect} do
gem "foo"
end
G
- expect(err).to lack_errors
+ expect(err).to be_empty
run <<-RUBY
require 'foo'
@@ -207,17 +221,102 @@ RSpec.describe "bundle install with git sources" do
expect(out).to eq("WIN")
end
+
+ it "works when the revision is a non-head ref" do
+ # want to ensure we don't fallback to master
+ update_git "foo", :path => lib_path("foo-1.0") do |s|
+ s.write("lib/foo.rb", "raise 'FAIL'")
+ end
+
+ sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 master~1", :dir => lib_path("foo-1.0"))
+
+ # want to ensure we don't fallback to HEAD
+ update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s|
+ s.write("lib/foo.rb", "raise 'FAIL_FROM_RANDO'")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ git "#{lib_path("foo-1.0")}", :ref => "refs/bundler/1" do
+ gem "foo"
+ end
+ G
+ expect(err).to be_empty
+
+ run <<-RUBY
+ require 'foo'
+ puts "WIN" if defined?(FOO)
+ RUBY
+
+ expect(out).to eq("WIN")
+ end
+
+ it "works when the revision is a non-head ref and it was previously downloaded" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ git "#{lib_path("foo-1.0")}" do
+ gem "foo"
+ end
+ G
+
+ # want to ensure we don't fallback to master
+ update_git "foo", :path => lib_path("foo-1.0") do |s|
+ s.write("lib/foo.rb", "raise 'FAIL'")
+ end
+
+ sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 master~1", :dir => lib_path("foo-1.0"))
+
+ # want to ensure we don't fallback to HEAD
+ update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s|
+ s.write("lib/foo.rb", "raise 'FAIL_FROM_RANDO'")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ git "#{lib_path("foo-1.0")}", :ref => "refs/bundler/1" do
+ gem "foo"
+ end
+ G
+ expect(err).to be_empty
+
+ run <<-RUBY
+ require 'foo'
+ puts "WIN" if defined?(FOO)
+ RUBY
+
+ expect(out).to eq("WIN")
+ end
+
+ it "does not download random non-head refs" do
+ sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 master~1", :dir => lib_path("foo-1.0"))
+
+ bundle "config set global_gem_cache true"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ git "#{lib_path("foo-1.0")}" do
+ gem "foo"
+ end
+ G
+
+ # ensure we also git fetch after cloning
+ bundle :update, :all => true
+
+ sys_exec("git ls-remote .", :dir => Dir[home(".bundle/cache/git/foo-*")].first)
+
+ expect(out).not_to include("refs/bundler/1")
+ end
end
describe "when specifying a branch" do
let(:branch) { "branch" }
let(:repo) { build_git("foo").path }
- before(:each) do
- update_git("foo", :path => repo, :branch => branch)
- end
it "works" do
+ update_git("foo", :path => repo, :branch => branch)
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{repo}", :branch => #{branch.dump} do
gem "foo"
end
@@ -229,7 +328,12 @@ RSpec.describe "bundle install with git sources" do
context "when the branch starts with a `#`" do
let(:branch) { "#149/redirect-url-fragment" }
it "works" do
+ skip "git does not accept this" if Gem.win_platform?
+
+ update_git("foo", :path => repo, :branch => branch)
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{repo}", :branch => #{branch.dump} do
gem "foo"
end
@@ -242,7 +346,12 @@ RSpec.describe "bundle install with git sources" do
context "when the branch includes quotes" do
let(:branch) { %('") }
it "works" do
+ skip "git does not accept this" if Gem.win_platform?
+
+ update_git("foo", :path => repo, :branch => branch)
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{repo}", :branch => #{branch.dump} do
gem "foo"
end
@@ -256,12 +365,12 @@ RSpec.describe "bundle install with git sources" do
describe "when specifying a tag" do
let(:tag) { "tag" }
let(:repo) { build_git("foo").path }
- before(:each) do
- update_git("foo", :path => repo, :tag => tag)
- end
it "works" do
+ update_git("foo", :path => repo, :tag => tag)
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{repo}", :tag => #{tag.dump} do
gem "foo"
end
@@ -273,7 +382,12 @@ RSpec.describe "bundle install with git sources" do
context "when the tag starts with a `#`" do
let(:tag) { "#149/redirect-url-fragment" }
it "works" do
+ skip "git does not accept this" if Gem.win_platform?
+
+ update_git("foo", :path => repo, :tag => tag)
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{repo}", :tag => #{tag.dump} do
gem "foo"
end
@@ -286,7 +400,12 @@ RSpec.describe "bundle install with git sources" do
context "when the tag includes quotes" do
let(:tag) { %('") }
it "works" do
+ skip "git does not accept this" if Gem.win_platform?
+
+ update_git("foo", :path => repo, :tag => tag)
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{repo}", :tag => #{tag.dump} do
gem "foo"
end
@@ -307,13 +426,12 @@ RSpec.describe "bundle install with git sources" do
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
bundle :install
- expect(out).to match(/at #{lib_path('local-rack')}/)
run "require 'rack'"
expect(out).to eq("LOCAL")
@@ -329,11 +447,11 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
run "require 'rack'"
expect(out).to eq("LOCAL")
end
@@ -348,14 +466,14 @@ RSpec.describe "bundle install with git sources" do
s.write "lib/rack.rb", "puts :LOCAL"
end
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle! %(config local.rack #{lib_path("local-rack")})
- bundle! :install
- run! "require 'rack'"
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ bundle :install
+ run "require 'rack'"
expect(out).to eq("LOCAL")
end
@@ -365,21 +483,21 @@ RSpec.describe "bundle install with git sources" do
build_git "rack", "0.8"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- lockfile0 = File.read(bundled_app("Gemfile.lock"))
+ lockfile0 = File.read(bundled_app_lock)
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
update_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.add_dependency "nokogiri", "1.4.2"
end
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
run "require 'rack'"
- lockfile1 = File.read(bundled_app("Gemfile.lock"))
+ lockfile1 = File.read(bundled_app_lock)
expect(lockfile1).not_to eq(lockfile0)
end
@@ -387,47 +505,63 @@ RSpec.describe "bundle install with git sources" do
build_git "rack", "0.8"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- lockfile0 = File.read(bundled_app("Gemfile.lock"))
+ lockfile0 = File.read(bundled_app_lock)
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
update_git "rack", "0.8", :path => lib_path("local-rack")
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
bundle :install
- lockfile1 = File.read(bundled_app("Gemfile.lock"))
+ lockfile1 = File.read(bundled_app_lock)
expect(lockfile1).not_to eq(lockfile0)
end
- it "explodes if given path does not exist on install" do
+ it "explodes and gives correct solution if given path does not exist on install" do
build_git "rack", "0.8"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
+
+ solution = "config unset local.rack"
+ expect(err).to match(/Run `bundle #{solution}` to remove the local override/)
+
+ bundle solution
bundle :install
- expect(out).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
+
+ expect(err).to be_empty
end
- it "explodes if branch is not given on install" do
+ it "explodes and gives correct solution if branch is not given on install" do
build_git "rack", "0.8"
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/Cannot use local override for rack-0.8 at #{Regexp.escape(lib_path('local-rack').to_s)} because :branch is not specified in Gemfile/)
+
+ solution = "config unset local.rack"
+ expect(err).to match(/Specify a branch or run `bundle #{solution}` to remove the local override/)
+
+ bundle solution
bundle :install
- expect(out).to match(/cannot use local override/i)
+
+ expect(err).to be_empty
end
it "does not explode if disable_local_branch_check is given" do
@@ -435,12 +569,12 @@ RSpec.describe "bundle install with git sources" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}"
G
- bundle %(config local.rack #{lib_path("local-rack")})
- bundle %(config disable_local_branch_check true)
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ bundle %(config set disable_local_branch_check true)
bundle :install
expect(out).to match(/Bundle complete!/)
end
@@ -455,13 +589,13 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
- bundle :install
- expect(out).to match(/is using branch another but Gemfile specifies master/)
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/is using branch another but Gemfile specifies master/)
end
it "explodes on invalid revision on install" do
@@ -472,13 +606,31 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
+ G
+
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/The Gemfile lock is pointing to revision \w+/)
+ end
+
+ it "does not explode on invalid revision on install" do
+ build_git "rack", "0.8"
+
+ build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
+ s.write "lib/rack.rb", "puts :LOCAL"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ bundle %(config set disable_local_revision_check true)
bundle :install
- expect(out).to match(/The Gemfile lock is pointing to revision \w+/)
+ expect(out).to match(/Bundle complete!/)
end
end
@@ -503,7 +655,7 @@ RSpec.describe "bundle install with git sources" do
build_git "rack", "0.8"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}"
G
@@ -522,7 +674,7 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("nested")}"
G
@@ -532,14 +684,14 @@ RSpec.describe "bundle install with git sources" do
it "correctly unlocks when changing to a git source" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
G
build_git "rack", :path => lib_path("rack")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0", :git => "#{lib_path("rack")}"
G
@@ -548,14 +700,14 @@ RSpec.describe "bundle install with git sources" do
it "correctly unlocks when changing to a git source without versions" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
build_git "rack", "1.2", :path => lib_path("rack")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack")}"
G
@@ -569,6 +721,7 @@ RSpec.describe "bundle install with git sources" do
build_lib "hi2u", :path => lib_path("hi2u")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
path "#{lib_path("hi2u")}" do
gem "omg"
gem "hi2u"
@@ -585,6 +738,7 @@ RSpec.describe "bundle install with git sources" do
update_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{@revision}"
G
@@ -602,7 +756,7 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
gem "rails", "2.3.2"
G
@@ -615,7 +769,7 @@ RSpec.describe "bundle install with git sources" do
build_lib "bar", :path => lib_path("foo/bar"), :gemspec => false do |s|
s.write lib_path("foo/bar/lib/version.rb"), %(BAR_VERSION = '1.0')
s.write "bar.gemspec", <<-G
- $:.unshift Dir.pwd # For 1.9
+ $:.unshift Dir.pwd
require 'lib/version'
Gem::Specification.new do |s|
s.name = 'bar'
@@ -632,7 +786,7 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "bar", :git => "#{lib_path("foo")}"
gem "rails", "2.3.2"
G
@@ -649,6 +803,7 @@ RSpec.describe "bundle install with git sources" do
build_git "foo", "1.0"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0", :git => "#{lib_path("foo-1.0")}"
G
@@ -659,7 +814,7 @@ RSpec.describe "bundle install with git sources" do
build_git "foo", :gemspec => false
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0", :git => "#{lib_path("foo-1.0")}"
gem "rails", "2.3.2"
G
@@ -670,12 +825,13 @@ RSpec.describe "bundle install with git sources" do
it "catches git errors and spits out useful output" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0", :git => "omgomg"
G
- bundle :install
+ bundle :install, :raise_on_error => false
- expect(out).to include("Git error:")
+ expect(err).to include("Git error:")
expect(err).to include("fatal")
expect(err).to include("omgomg")
end
@@ -684,6 +840,7 @@ RSpec.describe "bundle install with git sources" do
build_git "foo", :path => lib_path("foo space-1.0")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo space-1.0")}"
G
@@ -694,6 +851,7 @@ RSpec.describe "bundle install with git sources" do
build_git "forced", "1.0"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("forced-1.0")}" do
gem 'forced'
end
@@ -704,48 +862,50 @@ RSpec.describe "bundle install with git sources" do
s.write "lib/forced.rb", "FORCED = '1.1'"
end
- bundle "update"
+ bundle "update", :all => true
expect(the_bundle).to include_gems "forced 1.1"
- Dir.chdir(lib_path("forced-1.0")) do
- `git reset --hard HEAD^`
- end
+ sys_exec("git reset --hard HEAD^", :dir => lib_path("forced-1.0"))
- bundle "update"
+ bundle "update", :all => true
expect(the_bundle).to include_gems "forced 1.0"
end
it "ignores submodules if :submodule is not passed" do
+ # CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
+ system(*%W[git config --global protocol.file.allow always])
+
build_git "submodule", "1.0"
build_git "has_submodule", "1.0" do |s|
s.add_dependency "submodule"
end
- Dir.chdir(lib_path("has_submodule-1.0")) do
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0"
- `git commit -m "submodulator"`
- end
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("has_submodule-1.0")}" do
gem "has_submodule"
end
G
- expect(out).to match(/could not find gem 'submodule/i)
+ expect(err).to match(/could not find gem 'submodule/i)
expect(the_bundle).not_to include_gems "has_submodule 1.0"
end
it "handles repos with submodules" do
+ # CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
+ system(*%W[git config --global protocol.file.allow always])
+
build_git "submodule", "1.0"
build_git "has_submodule", "1.0" do |s|
s.add_dependency "submodule"
end
- Dir.chdir(lib_path("has_submodule-1.0")) do
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0"
- `git commit -m "submodulator"`
- end
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("has_submodule-1.0")}", :submodules => true do
gem "has_submodule"
end
@@ -754,10 +914,33 @@ RSpec.describe "bundle install with git sources" do
expect(the_bundle).to include_gems "has_submodule 1.0"
end
+ it "does not warn when deiniting submodules" do
+ # CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
+ system(*%W[git config --global protocol.file.allow always])
+
+ build_git "submodule", "1.0"
+ build_git "has_submodule", "1.0"
+
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ git "#{lib_path("has_submodule-1.0")}" do
+ gem "has_submodule"
+ end
+ G
+ expect(err).to be_empty
+
+ expect(the_bundle).to include_gems "has_submodule 1.0"
+ expect(the_bundle).to_not include_gems "submodule 1.0"
+ end
+
it "handles implicit updates when modifying the source info" do
git = build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem "foo"
end
@@ -767,6 +950,7 @@ RSpec.describe "bundle install with git sources" do
update_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}", :ref => "#{git.ref_for("HEAD^")}" do
gem "foo"
end
@@ -784,6 +968,7 @@ RSpec.describe "bundle install with git sources" do
build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
@@ -797,25 +982,27 @@ RSpec.describe "bundle install with git sources" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
bundle "install"
bundle "install"
- expect(exitstatus).to eq(0) if exitstatus
end
it "prints a friendly error if a file blocks the git repo" do
build_git "foo"
+ FileUtils.mkdir_p(default_bundle_path)
FileUtils.touch(default_bundle_path("bundler"))
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- expect(exitstatus).to_not eq(0) if exitstatus
- expect(out).to include("Bundler could not install a gem because it " \
+ expect(exitstatus).to_not eq(0)
+ expect(err).to include("Bundler could not install a gem because it " \
"needs to create a directory, but a file exists " \
"- #{default_bundle_path("bundler")}")
end
@@ -827,13 +1014,13 @@ RSpec.describe "bundle install with git sources" do
build_git "foo", :path => lib_path("nested")
build_git "bar", :path => lib_path("nested")
- gemfile <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("nested")}"
gem "bar", :git => "#{lib_path("nested")}"
G
- bundle "install"
- expect(File.read(bundled_app("Gemfile.lock")).scan("GIT").size).to eq(1)
+ expect(File.read(bundled_app_lock).scan("GIT").size).to eq(1)
end
describe "switching sources" do
@@ -847,12 +1034,12 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "bar", :path => "#{lib_path("bar")}"
G
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "bar", :git => "#{lib_path("bar")}"
G
@@ -861,7 +1048,7 @@ RSpec.describe "bundle install with git sources" do
it "doesn't explode when switching Gem to Git source" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack-obama"
gem "rack", "1.0.0"
G
@@ -871,7 +1058,7 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack-obama"
gem "rack", "1.0.0", :git => "#{lib_path("rack-1.0")}"
G
@@ -886,17 +1073,16 @@ RSpec.describe "bundle install with git sources" do
build_git "valim"
install_gemfile <<-G
- gem "valim", :git => "file://#{lib_path("valim-1.0")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "valim", :git => "#{file_uri_for(lib_path("valim-1.0"))}"
G
old_revision = revision_for(lib_path("valim-1.0"))
update_git "valim"
new_revision = revision_for(lib_path("valim-1.0"))
- lockfile = File.read(bundled_app("Gemfile.lock"))
- File.open(bundled_app("Gemfile.lock"), "w") do |file|
- file.puts lockfile.gsub(/revision: #{old_revision}/, "revision: #{new_revision}")
- end
+ old_lockfile = File.read(bundled_app_lock)
+ lockfile(bundled_app_lock, old_lockfile.gsub(/revision: #{old_revision}/, "revision: #{new_revision}"))
bundle "install"
@@ -913,32 +1099,32 @@ RSpec.describe "bundle install with git sources" do
revision = revision_for(lib_path("foo-1.0"))
install_gemfile <<-G
- gem "foo", :git => "file://#{lib_path("foo-1.0")}", :ref => "#{revision}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :ref => "#{revision}"
G
- bundle "install"
expect(out).to_not match(/Revision.*does not exist/)
- install_gemfile <<-G
- gem "foo", :git => "file://#{lib_path("foo-1.0")}", :ref => "deadbeef"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :ref => "deadbeef"
G
- bundle "install"
- expect(out).to include("Revision deadbeef does not exist in the repository")
+ expect(err).to include("Revision deadbeef does not exist in the repository")
end
end
- describe "bundle install --deployment with git sources" do
+ describe "bundle install with deployment mode configured and git sources" do
it "works" do
build_git "valim", :path => lib_path("valim")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "valim", "= 1.0", :git => "#{lib_path("valim")}"
G
simulate_new_machine
- bundle "install --deployment"
- expect(exitstatus).to eq(0) if exitstatus
+ bundle "config set --local deployment true"
+ bundle :install
end
end
@@ -946,12 +1132,12 @@ RSpec.describe "bundle install with git sources" do
it "runs pre-install hooks" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
File.open(lib_path("install_hooks.rb"), "w") do |h|
h.write <<-H
- require 'rubygems'
Gem.pre_install_hooks << lambda do |inst|
STDERR.puts "Ran pre-install hook: \#{inst.spec.full_name}"
end
@@ -960,18 +1146,18 @@ RSpec.describe "bundle install with git sources" do
bundle :install,
:requires => [lib_path("install_hooks.rb")]
- expect(err).to eq_err("Ran pre-install hook: foo-1.0")
+ expect(err_without_deprecations).to eq("Ran pre-install hook: foo-1.0")
end
it "runs post-install hooks" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
File.open(lib_path("install_hooks.rb"), "w") do |h|
h.write <<-H
- require 'rubygems'
Gem.post_install_hooks << lambda do |inst|
STDERR.puts "Ran post-install hook: \#{inst.spec.full_name}"
end
@@ -980,32 +1166,31 @@ RSpec.describe "bundle install with git sources" do
bundle :install,
:requires => [lib_path("install_hooks.rb")]
- expect(err).to eq_err("Ran post-install hook: foo-1.0")
+ expect(err_without_deprecations).to eq("Ran post-install hook: foo-1.0")
end
it "complains if the install hook fails" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
File.open(lib_path("install_hooks.rb"), "w") do |h|
h.write <<-H
- require 'rubygems'
Gem.pre_install_hooks << lambda do |inst|
false
end
H
end
- bundle :install,
- :requires => [lib_path("install_hooks.rb")]
- expect(out).to include("failed for foo-1.0")
+ bundle :install, :requires => [lib_path("install_hooks.rb")], :raise_on_error => false
+ expect(err).to include("failed for foo-1.0")
end
end
context "with an extension" do
- it "installs the extension", :ruby_repo do
+ it "installs the extension" do
build_git "foo" do |s|
s.add_dependency "rake"
s.extensions << "Rakefile"
@@ -1021,7 +1206,7 @@ RSpec.describe "bundle install with git sources" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
@@ -1031,10 +1216,10 @@ RSpec.describe "bundle install with git sources" do
R
expect(out).to eq("YES")
- run! <<-R
+ run <<-R
puts $:.grep(/ext/)
R
- expect(out).to eq(Pathname.glob(system_gem_path("bundler/gems/extensions/**/foo-1.0-*")).first.to_s)
+ expect(out).to include(Pathname.glob(default_bundle_path("bundler/gems/extensions/**/foo-1.0-*")).first.to_s)
end
it "does not use old extension after ref changes", :ruby_repo do
@@ -1048,21 +1233,20 @@ RSpec.describe "bundle install with git sources" do
end
2.times do |i|
- Dir.chdir(git_reader.path) do
- File.open("ext/foo.c", "w") do |file|
- file.write <<-C
- #include "ruby.h"
- VALUE foo() { return INT2FIX(#{i}); }
- void Init_foo() { rb_define_global_function("foo", &foo, 0); }
- C
- end
- `git commit -m 'commit for iteration #{i}' ext/foo.c`
+ File.open(git_reader.path.join("ext/foo.c"), "w") do |file|
+ file.write <<-C
+ #include "ruby.h"
+ VALUE foo() { return INT2FIX(#{i}); }
+ void Init_foo() { rb_define_global_function("foo", &foo, 0); }
+ C
end
- git_sha = git_reader.ref_for("HEAD")
+ sys_exec("git commit -m \"commit for iteration #{i}\" ext/foo.c", :dir => git_reader.path)
+
+ git_commit_sha = git_reader.ref_for("HEAD")
install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{git_sha}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{git_commit_sha}"
G
run <<-R
@@ -1085,12 +1269,12 @@ RSpec.describe "bundle install with git sources" do
RUBY
end
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- expect(out).to end_with(<<-M.strip)
+ expect(err).to end_with(<<-M.strip)
An error occurred while installing foo (1.0), and Bundler cannot continue.
In Gemfile:
@@ -1099,7 +1283,7 @@ In Gemfile:
expect(out).not_to include("gem install foo")
end
- it "does not reinstall the extension", :ruby_repo, :rubygems => ">= 2.3.0" do
+ it "does not reinstall the extension" do
build_git "foo" do |s|
s.add_dependency "rake"
s.extensions << "Rakefile"
@@ -1116,11 +1300,11 @@ In Gemfile:
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- run! <<-R
+ run <<-R
require 'foo'
puts FOO
R
@@ -1129,16 +1313,114 @@ In Gemfile:
expect(installed_time).to match(/\A\d+\.\d+\z/)
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- run! <<-R
+ run <<-R
require 'foo'
puts FOO
R
expect(out).to eq(installed_time)
end
+
+ it "does not reinstall the extension when changing another gem" do
+ build_git "foo" do |s|
+ s.add_dependency "rake"
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ cur_time = Time.now.to_f.to_s
+ File.open("\#{path}/foo.rb", "w") do |f|
+ f.puts "FOO = \#{cur_time}"
+ end
+ end
+ RUBY
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+ gem "foo", :git => "#{lib_path("foo-1.0")}"
+ G
+
+ run <<-R
+ require 'foo'
+ puts FOO
+ R
+
+ installed_time = out
+ expect(installed_time).to match(/\A\d+\.\d+\z/)
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "1.0.0"
+ gem "foo", :git => "#{lib_path("foo-1.0")}"
+ G
+
+ run <<-R
+ require 'foo'
+ puts FOO
+ R
+ expect(out).to eq(installed_time)
+ end
+
+ it "does reinstall the extension when changing refs" do
+ build_git "foo" do |s|
+ s.add_dependency "rake"
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ cur_time = Time.now.to_f.to_s
+ File.open("\#{path}/foo.rb", "w") do |f|
+ f.puts "FOO = \#{cur_time}"
+ end
+ end
+ RUBY
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}"
+ G
+
+ run <<-R
+ require 'foo'
+ puts FOO
+ R
+
+ installed_time = out
+
+ update_git("foo", :branch => "branch2")
+
+ expect(installed_time).to match(/\A\d+\.\d+\z/)
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "branch2"
+ G
+
+ run <<-R
+ require 'foo'
+ puts FOO
+ R
+ expect(out).not_to eq(installed_time)
+
+ installed_time = out
+
+ update_git("foo")
+ bundle "update foo"
+
+ run <<-R
+ require 'foo'
+ puts FOO
+ R
+ expect(out).not_to eq(installed_time)
+ end
end
it "ignores git environment variables" do
@@ -1151,54 +1433,93 @@ In Gemfile:
ENV["GIT_WORK_TREE"] = "bar"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("xxxxxx-1.0")}" do
gem 'xxxxxx'
end
G
- expect(exitstatus).to eq(0) if exitstatus
expect(ENV["GIT_DIR"]).to eq("bar")
expect(ENV["GIT_WORK_TREE"]).to eq("bar")
end
end
describe "without git installed" do
- it "prints a better error message" do
+ it "prints a better error message when installing" do
+ build_git "foo"
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rake", git: "https://github.com/ruby/rake"
+ G
+
+ lockfile <<-L
+ GIT
+ remote: https://github.com/ruby/rake
+ revision: 5c60da8644a9e4f655e819252e3b6ca77f42b7af
+ specs:
+ rake (13.0.6)
+
+ GEM
+ remote: https://rubygems.org/
+ specs:
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rake!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ with_path_as("") do
+ bundle "install", :raise_on_error => false
+ end
+ expect(err).
+ to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
+ end
+
+ it "prints a better error message when updating" do
build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem 'foo'
end
G
with_path_as("") do
- bundle "update"
+ bundle "update", :all => true, :raise_on_error => false
end
- expect(out).to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
+ expect(err).
+ to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
end
it "installs a packaged git gem successfully" do
build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem 'foo'
end
G
- bundle "package --all"
+ bundle "config set cache_all true"
+ bundle :cache
simulate_new_machine
bundle "install", :env => { "PATH" => "" }
expect(out).to_not include("You need to install git to be able to use gems from git repositories.")
- expect(exitstatus).to be_zero if exitstatus
end
end
- describe "when the git source is overriden with a local git repo" do
+ describe "when the git source is overridden with a local git repo" do
before do
- bundle "config --global local.foo #{lib_path("foo")}"
+ bundle "config set --global local.foo #{lib_path("foo")}"
end
describe "and git output is colorized" do
@@ -1212,6 +1533,7 @@ In Gemfile:
build_git "foo", "1.0", :path => lib_path("foo")
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo")}", :branch => "master"
G
@@ -1226,15 +1548,14 @@ In Gemfile:
let(:credentials) { "user1:password1" }
it "does not display the password" do
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
git "https://#{credentials}@github.com/company/private-repo" do
gem "foo"
end
G
- bundle :install
- expect(out).to_not include("password1")
- expect(err).to_not include("password1")
+ expect(last_command.stdboth).to_not include("password1")
expect(out).to include("Fetching https://user1@github.com/company/private-repo")
end
end
@@ -1243,15 +1564,14 @@ In Gemfile:
let(:credentials) { "oauth_token" }
it "displays the oauth scheme but not the oauth token" do
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
git "https://#{credentials}:x-oauth-basic@github.com/company/private-repo" do
gem "foo"
end
G
- bundle :install
- expect(out).to_not include("oauth_token")
- expect(err).to_not include("oauth_token")
+ expect(last_command.stdboth).to_not include("oauth_token")
expect(out).to include("Fetching https://x-oauth-basic@github.com/company/private-repo")
end
end
diff --git a/spec/bundler/install/gemfile/groups_spec.rb b/spec/bundler/install/gemfile/groups_spec.rb
index a3a5eeefdf..c92b5dcc57 100644
--- a/spec/bundler/install/gemfile/groups_spec.rb
+++ b/spec/bundler/install/gemfile/groups_spec.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with groups" do
describe "installing with no options" do
before :each do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
group :emo do
gem "activesupport", "2.3.5"
@@ -26,7 +25,7 @@ RSpec.describe "bundle install with groups" do
puts ACTIVESUPPORT
R
- expect(err).to eq_err("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
end
it "installs gems with inline :groups into those groups" do
@@ -37,7 +36,7 @@ RSpec.describe "bundle install with groups" do
puts THIN
R
- expect(err).to eq_err("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
end
it "sets up everything if Bundler.setup is used with no groups" do
@@ -58,7 +57,7 @@ RSpec.describe "bundle install with groups" do
puts THIN
RUBY
- expect(err).to eq_err("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
end
it "sets up old groups when they have previously been removed" do
@@ -71,11 +70,11 @@ RSpec.describe "bundle install with groups" do
end
end
- describe "installing --without" do
+ describe "without option" do
describe "with gems assigned to a single group" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
group :emo do
gem "activesupport", "2.3.5"
@@ -87,56 +86,76 @@ RSpec.describe "bundle install with groups" do
end
it "installs gems in the default group" do
- bundle :install, :without => "emo"
+ bundle "config set --local without emo"
+ bundle :install
+ expect(the_bundle).to include_gems "rack 1.0.0", :groups => [:default]
+ end
+
+ it "respects global `without` configuration, and saves it locally", :bundler => "< 3" do
+ bundle "config set without emo"
+ bundle :install
+ expect(the_bundle).to include_gems "rack 1.0.0", :groups => [:default]
+ bundle "config list"
+ expect(out).to include("Set for your local app (#{bundled_app(".bundle/config")}): [:emo]")
+ expect(out).to include("Set for the current user (#{home(".bundle/config")}): [:emo]")
+ end
+
+ it "respects global `without` configuration, but does not save it locally", :bundler => "3" do
+ bundle "config set without emo"
+ bundle :install
expect(the_bundle).to include_gems "rack 1.0.0", :groups => [:default]
+ bundle "config list"
+ expect(out).not_to include("Set for your local app (#{bundled_app(".bundle/config")}): [:emo]")
+ expect(out).to include("Set for the current user (#{home(".bundle/config")}): [:emo]")
+ end
+
+ it "allows running application where groups where configured by a different user", :bundler => "< 3" do
+ bundle "config set without emo"
+ bundle :install
+ bundle "exec ruby -e 'puts 42'", :env => { "BUNDLE_USER_HOME" => tmp("new_home").to_s }
+ expect(out).to include("42")
end
it "does not install gems from the excluded group" do
- bundle :install, :without => "emo"
+ bundle "config set --local without emo"
+ bundle :install
expect(the_bundle).not_to include_gems "activesupport 2.3.5", :groups => [:default]
end
- it "does not install gems from the previously excluded group" do
- bundle :install, :without => "emo"
+ it "remembers previous exclusion with `--without`", :bundler => "< 3" do
+ bundle "install --without emo"
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
bundle :install
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
end
it "does not say it installed gems from the excluded group" do
- bundle :install, :without => "emo"
+ bundle "config set --local without emo"
+ bundle :install
expect(out).not_to include("activesupport")
end
it "allows Bundler.setup for specific groups" do
- bundle :install, :without => "emo"
+ bundle "config set --local without emo"
+ bundle :install
run("require 'rack'; puts RACK", :default)
expect(out).to eq("1.0.0")
end
it "does not effect the resolve" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
group :emo do
gem "rails", "2.3.2"
end
G
- bundle :install, :without => "emo"
+ bundle "config set --local without emo"
+ bundle :install
expect(the_bundle).to include_gems "activesupport 2.3.2", :groups => [:default]
end
- it "still works on a different machine and excludes gems" do
- bundle :install, :without => "emo"
-
- simulate_new_machine
- bundle :install, :without => "emo"
-
- expect(the_bundle).to include_gems "rack 1.0.0", :groups => [:default]
- expect(the_bundle).not_to include_gems "activesupport 2.3.5", :groups => [:default]
- end
-
it "still works when BUNDLE_WITHOUT is set" do
ENV["BUNDLE_WITHOUT"] = "emo"
@@ -149,15 +168,15 @@ RSpec.describe "bundle install with groups" do
ENV["BUNDLE_WITHOUT"] = nil
end
- it "clears without when passed an empty list" do
- bundle :install, :without => "emo"
+ it "clears --without when passed an empty list", :bundler => "< 3" do
+ bundle "install --without emo"
- bundle 'install --without ""'
+ bundle "install --without ''"
expect(the_bundle).to include_gems "activesupport 2.3.5"
end
- it "doesn't clear without when nothing is passed" do
- bundle :install, :without => "emo"
+ it "doesn't clear without when nothing is passed", :bundler => "< 3" do
+ bundle "install --without emo"
bundle :install
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
@@ -168,61 +187,78 @@ RSpec.describe "bundle install with groups" do
expect(the_bundle).not_to include_gems "thin 1.0"
end
- it "does install gems from the optional group when requested" do
- bundle :install, :with => "debugging"
+ it "installs gems from the optional group when requested" do
+ bundle "config set --local with debugging"
+ bundle :install
expect(the_bundle).to include_gems "thin 1.0"
end
- it "does install gems from the previously requested group" do
- bundle :install, :with => "debugging"
+ it "installs gems from the previously requested group", :bundler => "< 3" do
+ bundle "install --with debugging"
expect(the_bundle).to include_gems "thin 1.0"
bundle :install
expect(the_bundle).to include_gems "thin 1.0"
end
- it "does install gems from the optional groups requested with BUNDLE_WITH" do
+ it "installs gems from the optional groups requested with BUNDLE_WITH" do
ENV["BUNDLE_WITH"] = "debugging"
bundle :install
expect(the_bundle).to include_gems "thin 1.0"
ENV["BUNDLE_WITH"] = nil
end
- it "clears with when passed an empty list" do
- bundle :install, :with => "debugging"
- bundle 'install --with ""'
+ it "clears --with when passed an empty list", :bundler => "< 3" do
+ bundle "install --with debugging"
+ bundle "install --with ''"
expect(the_bundle).not_to include_gems "thin 1.0"
end
- it "does remove groups from without when passed at with" do
- bundle :install, :without => "emo"
- bundle :install, :with => "emo"
+ it "removes groups from without when passed at --with", :bundler => "< 3" do
+ bundle "config set --local without emo"
+ bundle "install --with emo"
expect(the_bundle).to include_gems "activesupport 2.3.5"
end
- it "does remove groups from with when passed at without" do
- bundle :install, :with => "debugging"
- bundle :install, :without => "debugging"
- expect(the_bundle).not_to include_gems "thin 1.0"
+ it "removes groups from with when passed at --without", :bundler => "< 3" do
+ bundle "config set --local with debugging"
+ bundle "install --without debugging", :raise_on_error => false
+ expect(the_bundle).not_to include_gem "thin 1.0"
+ end
+
+ it "errors out when passing a group to with and without via CLI flags", :bundler => "< 3" do
+ bundle "install --with emo debugging --without emo", :raise_on_error => false
+ expect(last_command).to be_failure
+ expect(err).to include("The offending groups are: emo")
end
- it "errors out when passing a group to with and without" do
- bundle :install, :with => "emo debugging", :without => "emo"
- expect(out).to include("The offending groups are: emo")
+ it "allows the BUNDLE_WITH setting to override BUNDLE_WITHOUT" do
+ ENV["BUNDLE_WITH"] = "debugging"
+
+ bundle :install
+ expect(the_bundle).to include_gem "thin 1.0"
+
+ ENV["BUNDLE_WITHOUT"] = "debugging"
+ expect(the_bundle).to include_gem "thin 1.0"
+
+ bundle :install
+ expect(the_bundle).to include_gem "thin 1.0"
end
- it "can add and remove a group at the same time" do
- bundle :install, :with => "debugging", :without => "emo"
+ it "can add and remove a group at the same time", :bundler => "< 3" do
+ bundle "install --with debugging --without emo"
expect(the_bundle).to include_gems "thin 1.0"
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
end
- it "does have no effect when listing a not optional group in with" do
- bundle :install, :with => "emo"
+ it "has no effect when listing a not optional group in with" do
+ bundle "config set --local with emo"
+ bundle :install
expect(the_bundle).to include_gems "activesupport 2.3.5"
end
- it "does have no effect when listing an optional group in without" do
- bundle :install, :without => "debugging"
+ it "has no effect when listing an optional group in without" do
+ bundle "config set --local without debugging"
+ bundle :install
expect(the_bundle).not_to include_gems "thin 1.0"
end
end
@@ -230,7 +266,7 @@ RSpec.describe "bundle install with groups" do
describe "with gems assigned to multiple groups" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
group :emo, :lolercoaster do
gem "activesupport", "2.3.5"
@@ -239,19 +275,21 @@ RSpec.describe "bundle install with groups" do
end
it "installs gems in the default group" do
- bundle :install, :without => "emo lolercoaster"
+ bundle "config set --local without emo lolercoaster"
+ bundle :install
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "installs the gem if any of its groups are installed" do
- bundle "install --without emo"
+ bundle "config set --local without emo"
+ bundle :install
expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.5"
end
describe "with a gem defined multiple times in different groups" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
group :emo do
@@ -264,23 +302,21 @@ RSpec.describe "bundle install with groups" do
G
end
- it "installs the gem w/ option --without emo" do
- bundle "install --without emo"
+ it "installs the gem unless all groups are excluded" do
+ bundle "config set --local without emo"
+ bundle :install
expect(the_bundle).to include_gems "activesupport 2.3.5"
- end
- it "installs the gem w/ option --without lolercoaster" do
- bundle "install --without lolercoaster"
+ bundle "config set --local without lolercoaster"
+ bundle :install
expect(the_bundle).to include_gems "activesupport 2.3.5"
- end
- it "does not install the gem w/ option --without emo lolercoaster" do
- bundle "install --without emo lolercoaster"
+ bundle "config set --local without emo lolercoaster"
+ bundle :install
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
- end
- it "does not install the gem w/ option --without 'emo lolercoaster'" do
- bundle "install --without 'emo lolercoaster'"
+ bundle "config set --local without 'emo lolercoaster'"
+ bundle :install
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
end
end
@@ -289,7 +325,7 @@ RSpec.describe "bundle install with groups" do
describe "nesting groups" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
group :emo do
group :lolercoaster do
@@ -300,12 +336,14 @@ RSpec.describe "bundle install with groups" do
end
it "installs gems in the default group" do
- bundle :install, :without => "emo lolercoaster"
+ bundle "config set --local without emo lolercoaster"
+ bundle :install
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "installs the gem if any of its groups are installed" do
- bundle "install --without emo"
+ bundle "config set --local without emo"
+ bundle :install
expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.5"
end
end
@@ -314,13 +352,13 @@ RSpec.describe "bundle install with groups" do
describe "when loading only the default group" do
it "should not load all groups" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "activesupport", :groups => :development
G
ruby <<-R
- require "bundler"
+ require "#{entrypoint}"
Bundler.setup :default
Bundler.require :default
puts RACK
@@ -336,19 +374,21 @@ RSpec.describe "bundle install with groups" do
end
end
- describe "when locked and installed with --without" do
+ describe "when locked and installed with `without` option" do
before(:each) do
build_repo2
- system_gems "rack-0.9.1" do
- install_gemfile <<-G, :without => :rack
- source "file://#{gem_repo2}"
- gem "rack"
- group :rack do
- gem "rack_middleware"
- end
- G
- end
+ system_gems "rack-0.9.1"
+
+ bundle "config set --local without rack"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack"
+
+ group :rack do
+ gem "rack_middleware"
+ end
+ G
end
it "uses the correct versions even if --without was used on the original" do
@@ -364,8 +404,9 @@ RSpec.describe "bundle install with groups" do
it "does not hit the remote a second time" do
FileUtils.rm_rf gem_repo2
- bundle "install --without rack"
- expect(err).to lack_errors
+ bundle "config set --local without rack"
+ bundle :install, :verbose => true
+ expect(last_command.stdboth).not_to match(/fetching/i)
end
end
end
diff --git a/spec/bundler/install/gemfile/install_if.rb b/spec/bundler/install/gemfile/install_if.rb
deleted file mode 100644
index b1717ad583..0000000000
--- a/spec/bundler/install/gemfile/install_if.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-
-describe "bundle install with install_if conditionals" do
- it "follows the install_if DSL" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- install_if(lambda { true }) do
- gem "activesupport", "2.3.5"
- end
- gem "thin", :install_if => false
- install_if(lambda { false }) do
- gem "foo"
- end
- gem "rack"
- G
-
- expect(the_bundle).to include_gems("rack 1.0", "activesupport 2.3.5")
- expect(the_bundle).not_to include_gems("thin")
- expect(the_bundle).not_to include_gems("foo")
-
- lockfile_should_be <<-L
- GEM
- remote: file:#{gem_repo1}/
- specs:
- activesupport (2.3.5)
- foo (1.0)
- rack (1.0.0)
- thin (1.0)
- rack
-
- PLATFORMS
- ruby
-
- DEPENDENCIES
- activesupport (= 2.3.5)
- foo
- rack
- thin
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-end
diff --git a/spec/bundler/install/gemfile/install_if_spec.rb b/spec/bundler/install/gemfile/install_if_spec.rb
new file mode 100644
index 0000000000..3d2d15a698
--- /dev/null
+++ b/spec/bundler/install/gemfile/install_if_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle install with install_if conditionals" do
+ it "follows the install_if DSL" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ install_if(lambda { true }) do
+ gem "activesupport", "2.3.5"
+ end
+ gem "thin", :install_if => false
+ install_if(lambda { false }) do
+ gem "foo"
+ end
+ gem "rack"
+ G
+
+ expect(the_bundle).to include_gems("rack 1.0", "activesupport 2.3.5")
+ expect(the_bundle).not_to include_gems("thin")
+ expect(the_bundle).not_to include_gems("foo")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ activesupport (2.3.5)
+ foo (1.0)
+ rack (1.0.0)
+ thin (1.0)
+ rack
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ activesupport (= 2.3.5)
+ foo
+ rack
+ thin
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+end
diff --git a/spec/bundler/install/gemfile/lockfile_spec.rb b/spec/bundler/install/gemfile/lockfile_spec.rb
new file mode 100644
index 0000000000..313e99d0b8
--- /dev/null
+++ b/spec/bundler/install/gemfile/lockfile_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle install with a lockfile present" do
+ let(:gf) { <<-G }
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack", "1.0.0"
+ G
+
+ subject do
+ install_gemfile(gf)
+ end
+
+ context "gemfile evaluation" do
+ let(:gf) { super() + "\n\n File.open('evals', 'a') {|f| f << %(1\n) } unless ENV['BUNDLER_SPEC_NO_APPEND']" }
+
+ context "with plugins disabled" do
+ before do
+ bundle "config set plugins false"
+ subject
+ end
+
+ it "does not evaluate the gemfile twice" do
+ bundle :install
+
+ with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" }
+
+ # The first eval is from the initial install, we're testing that the
+ # second install doesn't double-eval
+ expect(bundled_app("evals").read.lines.to_a.size).to eq(2)
+ end
+
+ context "when the gem is not installed" do
+ before { FileUtils.rm_rf bundled_app(".bundle") }
+
+ it "does not evaluate the gemfile twice" do
+ bundle :install
+
+ with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" }
+
+ # The first eval is from the initial install, we're testing that the
+ # second install doesn't double-eval
+ expect(bundled_app("evals").read.lines.to_a.size).to eq(2)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb
index a1c41aebbb..bea7c11dec 100644
--- a/spec/bundler/install/gemfile/path_spec.rb
+++ b/spec/bundler/install/gemfile/path_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with explicit source paths" do
- it "fetches gems" do
+ it "fetches gems with a global path source", :bundler => "< 3" do
build_lib "foo"
install_gemfile <<-G
@@ -13,10 +12,24 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems("foo 1.0")
end
+ it "fetches gems" do
+ build_lib "foo"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path("foo-1.0")}" do
+ gem 'foo'
+ end
+ G
+
+ expect(the_bundle).to include_gems("foo 1.0")
+ end
+
it "supports pinned paths" do
build_lib "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "#{lib_path("foo-1.0")}"
G
@@ -26,9 +39,10 @@ RSpec.describe "bundle install with explicit source paths" do
it "supports relative paths" do
build_lib "foo"
- relative_path = lib_path("foo-1.0").relative_path_from(Pathname.new(Dir.pwd))
+ relative_path = lib_path("foo-1.0").relative_path_from(bundled_app)
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "#{relative_path}"
G
@@ -41,6 +55,7 @@ RSpec.describe "bundle install with explicit source paths" do
relative_path = lib_path("foo-1.0").relative_path_from(Pathname.new("~").expand_path)
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "~/#{relative_path}"
G
@@ -48,39 +63,85 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "expands paths raise error with not existing user's home dir" do
+ skip "problems with ~ expansion" if Gem.win_platform?
+
build_lib "foo"
username = "some_unexisting_user"
relative_path = lib_path("foo-1.0").relative_path_from(Pathname.new("/home/#{username}").expand_path)
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "~#{username}/#{relative_path}"
G
- expect(out).to match("There was an error while trying to use the path `~#{username}/#{relative_path}`.")
- expect(out).to match("user #{username} doesn't exist")
+ expect(err).to match("There was an error while trying to use the path `~#{username}/#{relative_path}`.")
+ expect(err).to match("user #{username} doesn't exist")
end
it "expands paths relative to Bundler.root" do
build_lib "foo", :path => bundled_app("foo-1.0")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "./foo-1.0"
G
- bundled_app("subdir").mkpath
- Dir.chdir(bundled_app("subdir")) do
- expect(the_bundle).to include_gems("foo 1.0")
- end
+ expect(the_bundle).to include_gems("foo 1.0", :dir => bundled_app("subdir").mkpath)
+ end
+
+ it "sorts paths consistently on install and update when they start with ./" do
+ build_lib "demo", :path => lib_path("demo")
+ build_lib "aaa", :path => lib_path("demo/aaa")
+
+ gemfile = <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gemspec
+ gem "aaa", :path => "./aaa"
+ G
+
+ File.open(lib_path("demo/Gemfile"), "w") {|f| f.puts gemfile }
+
+ lockfile = <<~L
+ PATH
+ remote: .
+ specs:
+ demo (1.0)
+
+ PATH
+ remote: aaa
+ specs:
+ aaa (1.0)
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ aaa!
+ demo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle :install, :dir => lib_path("demo")
+ expect(lib_path("demo/Gemfile.lock")).to read_as(lockfile)
+ bundle :update, :all => true, :dir => lib_path("demo")
+ expect(lib_path("demo/Gemfile.lock")).to read_as(lockfile)
end
it "expands paths when comparing locked paths to Gemfile paths" do
build_lib "foo", :path => bundled_app("foo-1.0")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => File.expand_path("../foo-1.0", __FILE__)
G
- bundle "install --frozen"
- expect(exitstatus).to eq(0) if exitstatus
+ bundle "config set --local frozen true"
+ bundle :install
end
it "installs dependencies from the path even if a newer gem is available elsewhere" do
@@ -95,7 +156,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("nested")}"
G
@@ -115,12 +176,94 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "foo", "1.0.0", :path => lib_path("omg/foo")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "omg", :path => "#{lib_path("omg")}"
G
expect(the_bundle).to include_gems "foo 1.0"
end
+ it "works when using prereleases of 0.0.0" do
+ build_lib "foo", "0.0.0.dev", :path => lib_path("foo")
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => "#{lib_path("foo")}"
+ G
+
+ lockfile <<~L
+ PATH
+ remote: #{lib_path("foo")}
+ specs:
+ foo (0.0.0.dev)
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle :install
+
+ expect(the_bundle).to include_gems "foo 0.0.0.dev"
+ end
+
+ it "works when using uppercase prereleases of 0.0.0" do
+ build_lib "foo", "0.0.0.SNAPSHOT", :path => lib_path("foo")
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => "#{lib_path("foo")}"
+ G
+
+ lockfile <<~L
+ PATH
+ remote: #{lib_path("foo")}
+ specs:
+ foo (0.0.0.SNAPSHOT)
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle :install
+
+ expect(the_bundle).to include_gems "foo 0.0.0.SNAPSHOT"
+ end
+
+ it "handles downgrades" do
+ build_lib "omg", "2.0", :path => lib_path("omg")
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "omg", :path => "#{lib_path("omg")}"
+ G
+
+ build_lib "omg", "1.0", :path => lib_path("omg")
+
+ bundle :install
+
+ expect(the_bundle).to include_gems "omg 1.0"
+ end
+
it "prefers gemspecs closer to the path root" do
build_lib "premailer", "1.0.0", :path => lib_path("premailer") do |s|
s.write "gemfiles/ruby187.gemspec", <<-G
@@ -134,6 +277,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "premailer", :path => "#{lib_path("premailer")}"
G
@@ -142,7 +286,7 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems "premailer 1.0.0"
end
- it "warns on invalid specs", :rubygems => "1.7" do
+ it "warns on invalid specs" do
build_lib "foo"
gemspec = lib_path("foo-1.0").join("foo.gemspec").to_s
@@ -154,15 +298,15 @@ RSpec.describe "bundle install with explicit source paths" do
G
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
- expect(out).to_not include("ERROR REPORT")
- expect(out).to_not include("Your Gemfile has no gem server sources.")
- expect(out).to match(/is not valid. Please fix this gemspec./)
- expect(out).to match(/The validation error was 'missing value for attribute version'/)
- expect(out).to match(/You have one or more invalid gemspecs that need to be fixed/)
+ expect(err).to_not include("Your Gemfile has no gem server sources.")
+ expect(err).to match(/is not valid. Please fix this gemspec./)
+ expect(err).to match(/The validation error was 'missing value for attribute version'/)
+ expect(err).to match(/You have one or more invalid gemspecs that need to be fixed/)
end
it "supports gemspec syntax" do
@@ -171,17 +315,15 @@ RSpec.describe "bundle install with explicit source paths" do
end
gemfile = <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
File.open(lib_path("foo/Gemfile"), "w") {|f| f.puts gemfile }
- Dir.chdir(lib_path("foo")) do
- bundle "install"
- expect(the_bundle).to include_gems "foo 1.0"
- expect(the_bundle).to include_gems "rack 1.0"
- end
+ bundle "install", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "foo 1.0", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("foo")
end
it "supports gemspec syntax with an alternative path" do
@@ -190,7 +332,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => "#{lib_path("foo")}"
G
@@ -203,19 +345,17 @@ RSpec.describe "bundle install with explicit source paths" do
s.add_dependency "rack", ">= 1.0"
end
- Dir.chdir lib_path("foo")
-
- install_gemfile lib_path("foo/Gemfile"), <<-G
- source "file://#{gem_repo1}"
+ install_gemfile lib_path("foo/Gemfile"), <<-G, :dir => lib_path("foo")
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
build_gem "rack", "1.0.1", :to_system => true
- bundle "install"
+ bundle "install", :dir => lib_path("foo")
- expect(the_bundle).to include_gems "foo 1.0"
- expect(the_bundle).to include_gems "rack 1.0"
+ expect(the_bundle).to include_gems "foo 1.0", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("foo")
end
it "doesn't automatically unlock dependencies when using the gemspec syntax and the gem has development dependencies" do
@@ -224,19 +364,17 @@ RSpec.describe "bundle install with explicit source paths" do
s.add_development_dependency "activesupport"
end
- Dir.chdir lib_path("foo")
-
- install_gemfile lib_path("foo/Gemfile"), <<-G
- source "file://#{gem_repo1}"
+ install_gemfile lib_path("foo/Gemfile"), <<-G, :dir => lib_path("foo")
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
build_gem "rack", "1.0.1", :to_system => true
- bundle "install"
+ bundle "install", :dir => lib_path("foo")
- expect(the_bundle).to include_gems "foo 1.0"
- expect(the_bundle).to include_gems "rack 1.0"
+ expect(the_bundle).to include_gems "foo 1.0", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("foo")
end
it "raises if there are multiple gemspecs" do
@@ -244,12 +382,13 @@ RSpec.describe "bundle install with explicit source paths" do
s.write "bar.gemspec", build_spec("bar", "1.0").first.to_ruby
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => "#{lib_path("foo")}"
G
- expect(exitstatus).to eq(15) if exitstatus
- expect(out).to match(/There are multiple gemspecs/)
+ expect(exitstatus).to eq(15)
+ expect(err).to match(/There are multiple gemspecs/)
end
it "allows :name to be specified to resolve ambiguity" do
@@ -258,6 +397,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => "#{lib_path("foo")}", :name => "foo"
G
@@ -269,10 +409,13 @@ RSpec.describe "bundle install with explicit source paths" do
s.executables = "foobar"
end
- install_gemfile <<-G
- path "#{lib_path("foo-1.0")}"
- gem 'foo'
+ install_gemfile <<-G, :verbose => true
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path("foo-1.0")}" do
+ gem 'foo'
+ end
G
+ expect(out).to include("Using foo 1.0 from source at `#{lib_path("foo-1.0")}` and installing its executables")
expect(the_bundle).to include_gems "foo 1.0"
bundle "exec foobar"
@@ -285,15 +428,17 @@ RSpec.describe "bundle install with explicit source paths" do
lib_path("foo-1.0").join("bin/performance").mkpath
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', '1.0', :path => "#{lib_path("foo-1.0")}"
G
- expect(err).to lack_errors
+ expect(err).to be_empty
end
it "removes the .gem file after installing" do
build_lib "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "#{lib_path("foo-1.0")}"
G
@@ -306,6 +451,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "hi2u"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
path "#{lib_path}" do
gem "omg"
gem "hi2u"
@@ -324,6 +470,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
gem "omg", :path => "#{lib_path("omg")}"
G
@@ -335,6 +482,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "foo", :gemspec => false
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0", :path => "#{lib_path("foo-1.0")}"
G
@@ -344,32 +492,32 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "works when the path does not have a gemspec but there is a lockfile" do
- lockfile <<-L
- PATH
- remote: vendor/bar
- specs:
+ lockfile <<~L
+ PATH
+ remote: vendor/bar
+ specs:
- GEM
- remote: http://rubygems.org
+ GEM
+ remote: http://rubygems.org/
L
- in_app_root { FileUtils.mkdir_p("vendor/bar") }
+ FileUtils.mkdir_p(bundled_app("vendor/bar"))
install_gemfile <<-G
+ source "http://rubygems.org"
gem "bar", "1.0.0", path: "vendor/bar", require: "bar/nyard"
G
- expect(exitstatus).to eq(0) if exitstatus
end
context "existing lockfile" do
it "rubygems gems don't re-resolve without changes" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack-obama', '1.0'
gem 'net-ssh', '1.0'
G
- bundle :check, :env => { "DEBUG" => 1 }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0"
end
@@ -384,12 +532,12 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack-obama', :path => "#{lib_path("omg")}"
gem 'net-ssh', :path => "#{lib_path("omg")}"
G
- bundle :check, :env => { "DEBUG" => 1 }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0"
end
@@ -401,6 +549,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
@@ -416,6 +565,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "bar", "1.0", :path => lib_path("foo/bar")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
end
@@ -444,7 +594,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "foo", "1.0", :path => lib_path("foo")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
end
@@ -458,6 +608,133 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
+
+ it "keeps using the same version if it's compatible" do
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
+ s.add_dependency "rack", "0.9.1"
+ end
+
+ bundle "install"
+
+ expect(the_bundle).to include_gems "rack 0.9.1"
+
+ expect(lockfile).to eq <<~G
+ PATH
+ remote: #{lib_path("foo")}
+ specs:
+ foo (1.0)
+ rack (= 0.9.1)
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
+ s.add_dependency "rack"
+ end
+
+ bundle "install"
+
+ expect(lockfile).to eq <<~G
+ PATH
+ remote: #{lib_path("foo")}
+ specs:
+ foo (1.0)
+ rack
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+
+ expect(the_bundle).to include_gems "rack 0.9.1"
+ end
+
+ it "keeps using the same version even when another dependency is added" do
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
+ s.add_dependency "rack", "0.9.1"
+ end
+
+ bundle "install"
+
+ expect(the_bundle).to include_gems "rack 0.9.1"
+
+ expect(lockfile).to eq <<~G
+ PATH
+ remote: #{lib_path("foo")}
+ specs:
+ foo (1.0)
+ rack (= 0.9.1)
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
+ s.add_dependency "rack"
+ s.add_dependency "rake", "13.0.1"
+ end
+
+ bundle "install"
+
+ expect(lockfile).to eq <<~G
+ PATH
+ remote: #{lib_path("foo")}
+ specs:
+ foo (1.0)
+ rack
+ rake (= 13.0.1)
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rack (0.9.1)
+ rake (13.0.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+
+ expect(the_bundle).to include_gems "rack 0.9.1"
+ end
end
describe "switching sources" do
@@ -471,12 +748,12 @@ RSpec.describe "bundle install with explicit source paths" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "bar", :git => "#{lib_path("bar")}"
G
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "bar", :path => "#{lib_path("bar")}"
G
@@ -485,12 +762,12 @@ RSpec.describe "bundle install with explicit source paths" do
it "switches the source when the gem existed in rubygems and the path was already being used for another gem" do
build_lib "foo", "1.0", :path => lib_path("foo")
- build_gem "bar", "1.0", :to_system => true do |s|
+ build_gem "bar", "1.0", :to_bundle => true do |s|
s.write "lib/bar.rb", "raise 'fail'"
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "bar"
path "#{lib_path("foo")}" do
gem "foo"
@@ -500,7 +777,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "bar", "1.0", :path => lib_path("foo/bar")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
path "#{lib_path("foo")}" do
gem "foo"
gem "bar"
@@ -521,13 +798,11 @@ RSpec.describe "bundle install with explicit source paths" do
G
File.open(lib_path("private_lib/Gemfile"), "w") {|f| f.puts gemfile }
- Dir.chdir(lib_path("private_lib")) do
- bundle :install, :env => { "DEBUG" => 1 }, :artifice => "endpoint"
- expect(out).to match(%r{^HTTP GET http://localgemserver\.test/api/v1/dependencies\?gems=rack$})
- expect(out).not_to match(/^HTTP GET.*private_lib/)
- expect(the_bundle).to include_gems "private_lib 2.2"
- expect(the_bundle).to include_gems "rack 1.0"
- end
+ bundle :install, :env => { "DEBUG" => "1" }, :artifice => "endpoint", :dir => lib_path("private_lib")
+ expect(out).to match(%r{^HTTP GET http://localgemserver\.test/api/v1/dependencies\?gems=rack$})
+ expect(out).not_to match(/^HTTP GET.*private_lib/)
+ expect(the_bundle).to include_gems "private_lib 2.2", :dir => lib_path("private_lib")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("private_lib")
end
end
@@ -535,12 +810,12 @@ RSpec.describe "bundle install with explicit source paths" do
it "runs pre-install hooks" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
File.open(lib_path("install_hooks.rb"), "w") do |h|
h.write <<-H
- require 'rubygems'
Gem.pre_install_hooks << lambda do |inst|
STDERR.puts "Ran pre-install hook: \#{inst.spec.full_name}"
end
@@ -549,18 +824,18 @@ RSpec.describe "bundle install with explicit source paths" do
bundle :install,
:requires => [lib_path("install_hooks.rb")]
- expect(err).to eq_err("Ran pre-install hook: foo-1.0")
+ expect(err_without_deprecations).to eq("Ran pre-install hook: foo-1.0")
end
it "runs post-install hooks" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
File.open(lib_path("install_hooks.rb"), "w") do |h|
h.write <<-H
- require 'rubygems'
Gem.post_install_hooks << lambda do |inst|
STDERR.puts "Ran post-install hook: \#{inst.spec.full_name}"
end
@@ -569,27 +844,50 @@ RSpec.describe "bundle install with explicit source paths" do
bundle :install,
:requires => [lib_path("install_hooks.rb")]
- expect(err).to eq_err("Ran post-install hook: foo-1.0")
+ expect(err_without_deprecations).to eq("Ran post-install hook: foo-1.0")
end
it "complains if the install hook fails" do
build_git "foo"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
File.open(lib_path("install_hooks.rb"), "w") do |h|
h.write <<-H
- require 'rubygems'
Gem.pre_install_hooks << lambda do |inst|
false
end
H
end
- bundle :install,
- :requires => [lib_path("install_hooks.rb")]
- expect(out).to include("failed for foo-1.0")
+ bundle :install, :requires => [lib_path("install_hooks.rb")], :raise_on_error => false
+ expect(err).to include("failed for foo-1.0")
+ end
+
+ it "loads plugins from the path gem" do
+ foo_file = home("foo_plugin_loaded")
+ bar_file = home("bar_plugin_loaded")
+ expect(foo_file).not_to be_file
+ expect(bar_file).not_to be_file
+
+ build_lib "foo" do |s|
+ s.write("lib/rubygems_plugin.rb", "require 'fileutils'; FileUtils.touch('#{foo_file}')")
+ end
+
+ build_git "bar" do |s|
+ s.write("lib/rubygems_plugin.rb", "require 'fileutils'; FileUtils.touch('#{bar_file}')")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :path => "#{lib_path("foo-1.0")}"
+ gem "bar", :path => "#{lib_path("bar-1.0")}"
+ G
+
+ expect(foo_file).to be_file
+ expect(bar_file).to be_file
end
end
end
diff --git a/spec/bundler/install/gemfile/platform_spec.rb b/spec/bundler/install/gemfile/platform_spec.rb
index c6eaec7ca6..35a3872c03 100644
--- a/spec/bundler/install/gemfile/platform_spec.rb
+++ b/spec/bundler/install/gemfile/platform_spec.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install across platforms" do
it "maintains the same lockfile if all gems are compatible across platforms" do
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (0.9.1)
@@ -17,7 +16,7 @@ RSpec.describe "bundle install across platforms" do
G
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -28,7 +27,7 @@ RSpec.describe "bundle install across platforms" do
it "pulls in the correct platform specific gem" do
lockfile <<-G
GEM
- remote: file:#{gem_repo1}
+ remote: #{file_uri_for(gem_repo1)}
specs:
platform_specific (1.0)
platform_specific (1.0-java)
@@ -43,7 +42,7 @@ RSpec.describe "bundle install across platforms" do
simulate_platform "java"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
@@ -51,10 +50,35 @@ RSpec.describe "bundle install across platforms" do
expect(the_bundle).to include_gems "platform_specific 1.0 JAVA"
end
+ it "pulls the pure ruby version on jruby if the java platform is not present in the lockfile and bundler is run in frozen mode", :jruby do
+ lockfile <<-G
+ GEM
+ remote: #{file_uri_for(gem_repo1)}
+ specs:
+ platform_specific (1.0)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ platform_specific
+ G
+
+ bundle "config set --local frozen true"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "platform_specific"
+ G
+
+ expect(the_bundle).to include_gems "platform_specific 1.0 RUBY"
+ end
+
it "works with gems that have different dependencies" do
simulate_platform "java"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri"
G
@@ -64,77 +88,254 @@ RSpec.describe "bundle install across platforms" do
simulate_new_machine
simulate_platform "ruby"
- install_gemfile <<-G
- source "file://#{gem_repo1}"
-
- gem "nokogiri"
- G
+ bundle "install"
expect(the_bundle).to include_gems "nokogiri 1.4.2"
expect(the_bundle).not_to include_gems "weakling"
+
+ simulate_platform "java"
+ bundle "install"
+
+ expect(the_bundle).to include_gems "nokogiri 1.4.2 JAVA", "weakling 0.0.3"
end
- it "works the other way with gems that have different dependencies" do
- simulate_platform "ruby"
+ it "does not keep unneeded platforms for gems that are used" do
+ build_repo4 do
+ build_gem "empyrean", "0.1.0"
+ build_gem "coderay", "1.1.2"
+ build_gem "method_source", "0.9.0"
+ build_gem("spoon", "0.0.6") {|s| s.add_runtime_dependency "ffi" }
+ build_gem "pry", "0.11.3" do |s|
+ s.platform = "java"
+ s.add_runtime_dependency "coderay", "~> 1.1.0"
+ s.add_runtime_dependency "method_source", "~> 0.9.0"
+ s.add_runtime_dependency "spoon", "~> 0.0"
+ end
+ build_gem "pry", "0.11.3" do |s|
+ s.add_runtime_dependency "coderay", "~> 1.1.0"
+ s.add_runtime_dependency "method_source", "~> 0.9.0"
+ end
+ build_gem("ffi", "1.9.23") {|s| s.platform = "java" }
+ build_gem("ffi", "1.9.23")
+ end
+
+ simulate_platform java
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo4)}"
- gem "nokogiri"
+ gem "empyrean", "0.1.0"
+ gem "pry"
G
- simulate_platform "java"
- bundle "install"
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ coderay (1.1.2)
+ empyrean (0.1.0)
+ ffi (1.9.23-java)
+ method_source (0.9.0)
+ pry (0.11.3-java)
+ coderay (~> 1.1.0)
+ method_source (~> 0.9.0)
+ spoon (~> 0.0)
+ spoon (0.0.6)
+ ffi
- expect(the_bundle).to include_gems "nokogiri 1.4.2 JAVA", "weakling 0.0.3"
+ PLATFORMS
+ java
+
+ DEPENDENCIES
+ empyrean (= 0.1.0)
+ pry
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "lock --add-platform ruby"
+
+ good_lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ coderay (1.1.2)
+ empyrean (0.1.0)
+ ffi (1.9.23-java)
+ method_source (0.9.0)
+ pry (0.11.3)
+ coderay (~> 1.1.0)
+ method_source (~> 0.9.0)
+ pry (0.11.3-java)
+ coderay (~> 1.1.0)
+ method_source (~> 0.9.0)
+ spoon (~> 0.0)
+ spoon (0.0.6)
+ ffi
+
+ PLATFORMS
+ java
+ ruby
+
+ DEPENDENCIES
+ empyrean (= 0.1.0)
+ pry
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ expect(lockfile).to eq good_lockfile
+
+ bad_lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ coderay (1.1.2)
+ empyrean (0.1.0)
+ ffi (1.9.23)
+ ffi (1.9.23-java)
+ method_source (0.9.0)
+ pry (0.11.3)
+ coderay (~> 1.1.0)
+ method_source (~> 0.9.0)
+ pry (0.11.3-java)
+ coderay (~> 1.1.0)
+ method_source (~> 0.9.0)
+ spoon (~> 0.0)
+ spoon (0.0.6)
+ ffi
+
+ PLATFORMS
+ java
+ ruby
+
+ DEPENDENCIES
+ empyrean (= 0.1.0)
+ pry
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ aggregate_failures do
+ lockfile bad_lockfile
+ bundle :install
+ expect(lockfile).to eq good_lockfile
+
+ lockfile bad_lockfile
+ bundle :update, :all => true
+ expect(lockfile).to eq good_lockfile
+
+ lockfile bad_lockfile
+ bundle "update ffi"
+ expect(lockfile).to eq good_lockfile
+
+ lockfile bad_lockfile
+ bundle "update empyrean"
+ expect(lockfile).to eq good_lockfile
+
+ lockfile bad_lockfile
+ bundle :lock
+ expect(lockfile).to eq good_lockfile
+ end
end
- it "works with gems that have extra platform-specific runtime dependencies" do
+ it "works with gems with platform-specific dependency having different requirements order" do
simulate_platform x64_mac
update_repo2 do
- build_gem "facter", "2.4.6"
- build_gem "facter", "2.4.6" do |s|
+ build_gem "fspath", "3"
+ build_gem "image_optim_pack", "1.2.3" do |s|
+ s.add_runtime_dependency "fspath", ">= 2.1", "< 4"
+ end
+ build_gem "image_optim_pack", "1.2.3" do |s|
s.platform = "universal-darwin"
- s.add_runtime_dependency "CFPropertyList"
+ s.add_runtime_dependency "fspath", "< 4", ">= 2.1"
end
- build_gem "CFPropertyList"
end
- install_gemfile! <<-G
- source "file://#{gem_repo2}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ G
- gem "facter"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "image_optim_pack"
G
- expect(out).to include "Unable to use the platform-specific (universal-darwin) version of facter (2.4.6) " \
- "because it has different dependencies from the ruby version. " \
- "To use the platform-specific version of the gem, run `bundle config specific_platform true` and install again."
+ expect(err).not_to include "Unable to use the platform-specific"
- expect(the_bundle).to include_gem "facter 2.4.6"
- expect(the_bundle).not_to include_gem "CFPropertyList"
+ expect(the_bundle).to include_gem "image_optim_pack 1.2.3 universal-darwin"
end
it "fetches gems again after changing the version of Ruby" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
G
- bundle "install --path vendor/bundle"
+ bundle "config set --local path vendor/bundle"
+ bundle :install
- new_version = Gem::ConfigMap[:ruby_version] == "1.8" ? "1.9.1" : "1.8"
- FileUtils.mv(vendored_gems, bundled_app("vendor/bundle", Gem.ruby_engine, new_version))
+ FileUtils.mv(vendored_gems, bundled_app("vendor/bundle", Gem.ruby_engine, "1.8"))
- bundle "install --path vendor/bundle"
+ bundle :install
expect(vendored_gems("gems/rack-1.0.0")).to exist
end
+
+ it "keeps existing platforms when installing with force_ruby_platform" do
+ lockfile <<-G
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ platform_specific (1.0-java)
+
+ PLATFORMS
+ java
+
+ DEPENDENCIES
+ platform_specific
+ G
+
+ bundle "config set --local force_ruby_platform true"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "platform_specific"
+ G
+
+ expect(the_bundle).to include_gem "platform_specific 1.0 RUBY"
+
+ expect(lockfile).to eq <<~G
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ platform_specific (1.0)
+ platform_specific (1.0-java)
+
+ PLATFORMS
+ java
+ ruby
+
+ DEPENDENCIES
+ platform_specific
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
end
RSpec.describe "bundle install with platform conditionals" do
it "installs gems tagged w/ the current platforms" do
+ skip "platform issues" if Gem.win_platform?
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
platforms :#{local_tag} do
gem "nokogiri"
@@ -146,7 +347,7 @@ RSpec.describe "bundle install with platform conditionals" do
it "does not install gems tagged w/ another platforms" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
platforms :#{not_local_tag} do
gem "nokogiri"
@@ -157,9 +358,54 @@ RSpec.describe "bundle install with platform conditionals" do
expect(the_bundle).not_to include_gems "nokogiri 1.4.2"
end
+ it "installs gems tagged w/ another platform but also dependent on the current one transitively" do
+ build_repo4 do
+ build_gem "activesupport", "6.1.4.1" do |s|
+ s.add_dependency "tzinfo", "~> 2.0"
+ end
+
+ build_gem "tzinfo", "2.0.4"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "activesupport"
+
+ platforms :#{not_local_tag} do
+ gem "tzinfo", "~> 1.2"
+ end
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ activesupport (6.1.4.1)
+ tzinfo (~> 2.0)
+ tzinfo (2.0.4)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ tzinfo (~> 1.2)
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install --verbose"
+
+ expect(the_bundle).to include_gems "tzinfo 2.0.4"
+ end
+
it "installs gems tagged w/ the current platforms inline" do
+ skip "platform issues" if Gem.win_platform?
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platforms => :#{local_tag}
G
expect(the_bundle).to include_gems "nokogiri 1.4.2"
@@ -167,7 +413,7 @@ RSpec.describe "bundle install with platform conditionals" do
it "does not install gems tagged w/ another platforms inline" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "nokogiri", :platforms => :#{not_local_tag}
G
@@ -176,8 +422,10 @@ RSpec.describe "bundle install with platform conditionals" do
end
it "installs gems tagged w/ the current platform inline" do
+ skip "platform issues" if Gem.win_platform?
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platform => :#{local_tag}
G
expect(the_bundle).to include_gems "nokogiri 1.4.2"
@@ -185,7 +433,7 @@ RSpec.describe "bundle install with platform conditionals" do
it "doesn't install gems tagged w/ another platform inline" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platform => :#{not_local_tag}
G
expect(the_bundle).not_to include_gems "nokogiri 1.4.2"
@@ -195,21 +443,20 @@ RSpec.describe "bundle install with platform conditionals" do
build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
platform :#{not_local_tag} do
gem "foo", :git => "#{lib_path("foo-1.0")}"
end
G
- bundle :show
- expect(exitstatus).to eq(0) if exitstatus
+ bundle :list
end
it "does not attempt to install gems from :rbx when using --local" do
simulate_platform "ruby"
- simulate_ruby_engine "ruby"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "some_gem", :platform => :rbx
G
@@ -219,11 +466,10 @@ RSpec.describe "bundle install with platform conditionals" do
it "does not attempt to install gems from other rubies when using --local" do
simulate_platform "ruby"
- simulate_ruby_engine "ruby"
other_ruby_version_tag = RUBY_VERSION =~ /^1\.8/ ? :ruby_19 : :ruby_18
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "some_gem", platform: :#{other_ruby_version_tag}
G
@@ -231,21 +477,33 @@ RSpec.describe "bundle install with platform conditionals" do
expect(out).not_to match(/Could not find gem 'some_gem/)
end
- it "prints a helpful warning when a dependency is unused on any platform" do
+ it "does not print a warning when a dependency is unused on a platform different from the current one" do
simulate_platform "ruby"
- simulate_ruby_engine "ruby"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :platform => [:mingw, :mswin, :x64_mingw, :jruby]
G
- bundle! "install"
+ bundle "install"
+
+ expect(err).to be_empty
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ ruby
- expect(out).to include <<-O.strip
-The dependency #{Gem::Dependency.new("rack", ">= 0")} will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
- O
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
end
@@ -253,13 +511,21 @@ RSpec.describe "when a gem has no architecture" do
it "still installs correctly" do
simulate_platform mswin
+ build_repo2 do
+ # The rcov gem is platform mswin32, but has no arch
+ build_gem "rcov" do |s|
+ s.platform = Gem::Platform.new([nil, "mswin32", nil])
+ s.write "lib/rcov.rb", "RCOV = '1.0.0'"
+ end
+ end
+
gemfile <<-G
# Try to install gem with nil arch
source "http://localgemserver.test/"
gem "rcov"
G
- bundle :install, :artifice => "windows"
+ bundle :install, :artifice => "windows", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(the_bundle).to include_gems "rcov 1.0.0"
end
end
diff --git a/spec/bundler/install/gemfile/ruby_spec.rb b/spec/bundler/install/gemfile/ruby_spec.rb
index b9d9683758..fd4300c042 100644
--- a/spec/bundler/install/gemfile/ruby_spec.rb
+++ b/spec/bundler/install/gemfile/ruby_spec.rb
@@ -1,35 +1,33 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "ruby requirement" do
def locked_ruby_version
- Bundler::RubyVersion.from_string(Bundler::LockfileParser.new(lockfile).ruby_version)
+ Bundler::RubyVersion.from_string(Bundler::LockfileParser.new(File.read(bundled_app_lock)).ruby_version)
end
- # As discovered by https://github.com/bundler/bundler/issues/4147, there is
+ # As discovered by https://github.com/rubygems/bundler/issues/4147, there is
# no test coverage to ensure that adding a gem is possible with a ruby
# requirement. This test verifies the fix, committed in bfbad5c5.
it "allows adding gems" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "#{RUBY_VERSION}"
gem "rack"
G
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "#{RUBY_VERSION}"
gem "rack"
gem "rack-obama"
G
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems "rack-obama 1.0"
end
it "allows removing the ruby version requirement" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "~> #{RUBY_VERSION}"
gem "rack"
G
@@ -37,7 +35,7 @@ RSpec.describe "ruby requirement" do
expect(lockfile).to include("RUBY VERSION")
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -47,17 +45,18 @@ RSpec.describe "ruby requirement" do
it "allows changing the ruby version requirement to something compatible" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby ">= 1.0.0"
gem "rack"
G
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
expect(locked_ruby_version).to eq(Bundler::RubyVersion.system)
simulate_ruby_version "5100"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby ">= 1.0.1"
gem "rack"
G
@@ -68,17 +67,18 @@ RSpec.describe "ruby requirement" do
it "allows changing the ruby version requirement to something incompatible" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby ">= 1.0.0"
gem "rack"
G
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
expect(locked_ruby_version).to eq(Bundler::RubyVersion.system)
simulate_ruby_version "5100"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby ">= 5000.0"
gem "rack"
G
@@ -88,8 +88,8 @@ RSpec.describe "ruby requirement" do
end
it "allows requirements with trailing whitespace" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
ruby "#{RUBY_VERSION}\\n \t\\n"
gem "rack"
G
@@ -98,12 +98,12 @@ RSpec.describe "ruby requirement" do
end
it "fails gracefully with malformed requirements" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
ruby ">= 0", "-.\\0"
gem "rack"
G
- expect(out).to include("There was an error parsing") # i.e. DSL error, not error template
+ expect(err).to include("There was an error parsing") # i.e. DSL error, not error template
end
end
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index c5375b4abf..5456e95f33 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with gems on multiple sources" do
# repo1 is built automatically before all of the specs run
@@ -21,28 +20,25 @@ RSpec.describe "bundle install with gems on multiple sources" do
before do
gemfile <<-G
- source "file://#{gem_repo3}"
- source "file://#{gem_repo1}"
+ source "https://gem.repo3"
+ source "https://gem.repo1"
gem "rack-obama"
gem "rack"
G
- bundle "config major_deprecations true"
end
- it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first" do
- bundle :install
+ it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
- expect(out).to have_major_deprecation a_string_including("Your Gemfile contains multiple primary sources.")
- expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(out).to include("Installed from: file:#{gem_repo1}")
+ expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).to include("Installed from: https://gem.repo1")
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", :source => "remote1")
end
- it "errors when disable_multisource is set" do
- bundle "config disable_multisource true"
- bundle :install
- expect(out).to include("Each source after the first must include a block")
- expect(exitstatus).to eq(4) if exitstatus
+ it "fails", :bundler => "3" do
+ bundle :instal, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Each source after the first must include a block")
+ expect(exitstatus).to eq(4)
end
end
@@ -51,22 +47,25 @@ RSpec.describe "bundle install with gems on multiple sources" do
before do
gemfile <<-G
- source "file://#{gem_repo3}"
- source "file://#{gem_repo1}"
+ source "https://gem.repo3"
+ source "https://gem.repo1"
gem "rack-obama"
gem "rack", "1.0.0" # force it to install the working version in repo1
G
- bundle "config major_deprecations true"
end
- it "warns about ambiguous gems, but installs anyway" do
- bundle :install
-
- expect(out).to have_major_deprecation a_string_including("Your Gemfile contains multiple primary sources.")
- expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(out).to include("Installed from: file:#{gem_repo1}")
+ it "warns about ambiguous gems, but installs anyway", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).to include("Installed from: https://gem.repo1")
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", :source => "remote1")
end
+
+ it "fails", :bundler => "3" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Each source after the first must include a block")
+ expect(exitstatus).to eq(4)
+ end
end
end
@@ -79,34 +78,38 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
+
+ build_gem "rack-obama" do |s|
+ s.add_dependency "rack"
+ end
end
gemfile <<-G
- source "file://#{gem_repo3}"
- source "file://#{gem_repo1}" do
+ source "https://gem.repo3"
+ source "https://gem.repo1" do
gem "thin" # comes first to test name sorting
gem "rack"
end
- gem "rack-obama" # shoud come from repo3!
+ gem "rack-obama" # should come from repo3!
G
end
it "installs the gems without any warning" do
- bundle :install
- expect(out).not_to include("Warning")
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("rack-obama 1.0.0")
expect(the_bundle).to include_gems("rack 1.0.0", :source => "remote1")
end
it "can cache and deploy" do
- bundle :package
+ bundle :cache, :artifice => "compact_index"
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
expect(bundled_app("vendor/cache/rack-obama-1.0.gem")).to exist
- bundle "install --deployment"
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "compact_index"
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0")
end
end
@@ -119,155 +122,819 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
+
+ build_gem "rack-obama" do |s|
+ s.add_dependency "rack"
+ end
end
- gemfile <<-G
- source "file://#{gem_repo3}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo3"
gem "rack-obama" # should come from repo3!
- gem "rack", :source => "file://#{gem_repo1}"
+ gem "rack", :source => "https://gem.repo1"
G
end
it "installs the gems without any warning" do
- bundle :install
- expect(out).not_to include("Warning")
+ expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0")
end
end
- context "with an indirect dependency" do
+ context "when a pinned gem has an indirect dependency in the pinned source" do
before do
build_repo gem_repo3 do
build_gem "depends_on_rack", "1.0.1" do |s|
s.add_dependency "rack"
end
end
+
+ # we need a working rack gem in repo3
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0"
+ end
+
+ gemfile <<-G
+ source "https://gem.repo2"
+ source "https://gem.repo3" do
+ gem "depends_on_rack"
+ end
+ G
end
- context "when the indirect dependency is in the pinned source" do
+ context "and not in any other sources" do
before do
- # we need a working rack gem in repo3
- update_repo gem_repo3 do
- build_gem "rack", "1.0.0"
+ build_repo(gem_repo2) {}
+ end
+
+ it "installs from the same source without any warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ end
+ end
+
+ context "and in another source" do
+ before do
+ # need this to be broken to check for correct source ordering
+ build_repo gem_repo2 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
+ end
end
+ end
+
+ it "installs from the same source without any warning" do
+ bundle :install, :artifice => "compact_index"
+
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+
+ # In https://github.com/bundler/bundler/issues/3585 this failed
+ # when there is already a lock file, and the gems are missing, so try again
+ system_gems []
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ end
+ end
+ end
+
+ context "when a pinned gem has an indirect dependency in a different source" do
+ before do
+ # In these tests, we need a working rack gem in repo2 and not repo3
+
+ build_repo gem_repo3 do
+ build_gem "depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "rack"
+ end
+ end
+
+ build_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
+ end
+ end
+
+ context "and not in any other sources" do
+ before do
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo2"
+ source "https://gem.repo3" do
+ gem "depends_on_rack"
+ end
+ G
+ end
+
+ it "installs from the other source without any warning" do
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ end
+ end
+
+ context "and in yet another source" do
+ before do
gemfile <<-G
- source "file://#{gem_repo2}"
- source "file://#{gem_repo3}" do
+ source "https://gem.repo1"
+ source "https://gem.repo2"
+ source "https://gem.repo3" do
gem "depends_on_rack"
end
G
end
- context "and not in any other sources" do
- before do
- build_repo(gem_repo2) {}
+ it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).to include("Installed from: https://gem.repo2")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo1/
+ remote: https://gem.repo2/
+ specs:
+ rack (1.0.0)
+
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ depends_on_rack (1.0.1)
+ rack
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ depends_on_rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ previous_lockfile = lockfile
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ expect(lockfile).to eq(previous_lockfile)
+ end
+
+ it "fails", :bundler => "3" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Each source after the first must include a block")
+ expect(exitstatus).to eq(4)
+ end
+ end
+
+ context "and only the dependency is pinned" do
+ before do
+ # need this to be broken to check for correct source ordering
+ build_repo gem_repo2 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
+ end
+ end
+
+ gemfile <<-G
+ source "https://gem.repo3" # contains depends_on_rack
+ source "https://gem.repo2" # contains broken rack
+
+ gem "depends_on_rack" # installed from gem_repo3
+ gem "rack", :source => "https://gem.repo1"
+ G
+ end
+
+ it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
+
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+
+ # In https://github.com/rubygems/bundler/issues/3585 this failed
+ # when there is already a lock file, and the gems are missing, so try again
+ system_gems []
+ bundle :install, :artifice => "compact_index"
+
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ end
+
+ it "fails", :bundler => "3" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Each source after the first must include a block")
+ expect(exitstatus).to eq(4)
+ end
+ end
+ end
+
+ context "when a top-level gem can only be found in an scoped source" do
+ before do
+ build_repo2
+
+ build_repo gem_repo3 do
+ build_gem "private_gem_1", "1.0.0"
+ build_gem "private_gem_2", "1.0.0"
+ end
+
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ gem "private_gem_1"
+
+ source "https://gem.repo3" do
+ gem "private_gem_2"
end
+ G
+ end
- it "installs from the same source without any warning" do
- bundle :install
- expect(out).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ it "fails" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository https://gem.repo2/ or installed locally.")
+ end
+ end
+
+ context "when an indirect dependency can't be found in the aggregate rubygems source", :bundler => "< 3" do
+ before do
+ build_repo2
+
+ build_repo gem_repo3 do
+ build_gem "depends_on_missing", "1.0.1" do |s|
+ s.add_dependency "missing"
end
end
- context "and in another source" do
- before do
- # need this to be broken to check for correct source ordering
- build_repo gem_repo2 do
- build_gem "rack", "1.0.0" do |s|
- s.write "lib/rack.rb", "RACK = 'FAIL'"
- end
- end
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ source "https://gem.repo3"
+
+ gem "depends_on_missing"
+ G
+ end
+
+ it "fails" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Could not find gem 'missing', which is required by gem 'depends_on_missing', in any of the sources.")
+ end
+ end
+
+ context "when a top-level gem has an indirect dependency" do
+ before do
+ build_repo gem_repo2 do
+ build_gem "depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "rack"
end
+ end
+
+ build_repo gem_repo3 do
+ build_gem "unrelated_gem", "1.0.0"
+ end
+
+ gemfile <<-G
+ source "https://gem.repo2"
- it "installs from the same source without any warning" do
- bundle :install
- expect(out).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ gem "depends_on_rack"
+
+ source "https://gem.repo3" do
+ gem "unrelated_gem"
+ end
+ G
+ end
+
+ context "and the dependency is only in the top-level source" do
+ before do
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
end
end
+
+ it "installs the dependency from the top-level source without warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("unrelated_gem 1.0.0", :source => "remote3")
+ end
end
- context "when the indirect dependency is in a different source" do
+ context "and the dependency is only in a pinned source" do
before do
- # In these tests, we need a working rack gem in repo2 and not repo3
- build_repo gem_repo2 do
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
+ end
+ end
+ end
+
+ it "does not find the dependency" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include(
+ "Could not find gem 'rack', which is required by gem 'depends_on_rack', in rubygems repository https://gem.repo2/ or installed locally."
+ )
+ end
+ end
+
+ context "and the dependency is in both the top-level and a pinned source" do
+ before do
+ update_repo gem_repo2 do
build_gem "rack", "1.0.0"
end
+
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
+ end
+ end
end
- context "and not in any other sources" do
- before do
- gemfile <<-G
- source "file://#{gem_repo2}"
- source "file://#{gem_repo3}" do
- gem "depends_on_rack"
- end
- G
+ it "installs the dependency from the top-level source without warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(run("require 'rack'; puts RACK")).to eq("1.0.0")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("unrelated_gem 1.0.0", :source => "remote3")
+ end
+ end
+ end
+
+ context "when a scoped gem has a deeply nested indirect dependency" do
+ before do
+ build_repo gem_repo3 do
+ build_gem "depends_on_depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "depends_on_rack"
end
- it "installs from the other source without any warning" do
- bundle :install
- expect(out).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ build_gem "depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "rack"
end
end
- context "and in yet another source" do
- before do
- gemfile <<-G
- source "file://#{gem_repo1}"
- source "file://#{gem_repo2}"
- source "file://#{gem_repo3}" do
- gem "depends_on_rack"
- end
- G
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ source "https://gem.repo3" do
+ gem "depends_on_depends_on_rack"
end
+ G
+ end
- it "installs from the other source and warns about ambiguous gems" do
- bundle "config major_deprecations true"
- bundle :install
- expect(out).to have_major_deprecation a_string_including("Your Gemfile contains multiple primary sources.")
- expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(out).to include("Installed from: file:#{gem_repo2}")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ context "and the dependency is only in the top-level source" do
+ before do
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
end
end
- context "and only the dependency is pinned" do
- before do
- # need this to be broken to check for correct source ordering
- build_repo gem_repo2 do
- build_gem "rack", "1.0.0" do |s|
- s.write "lib/rack.rb", "RACK = 'FAIL'"
- end
+ it "installs the dependency from the top-level source" do
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0")
+ expect(the_bundle).to include_gems("rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", :source => "remote3")
+ end
+ end
+
+ context "and the dependency is only in a pinned source" do
+ before do
+ build_repo2
+
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0"
+ end
+ end
+
+ it "installs the dependency from the pinned source" do
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ end
+ end
+
+ context "and the dependency is in both the top-level and a pinned source" do
+ before do
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
end
+ end
+
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0"
+ end
+ end
- gemfile <<-G
- source "file://#{gem_repo3}" # contains depends_on_rack
- source "file://#{gem_repo2}" # contains broken rack
+ it "installs the dependency from the pinned source without warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ end
+ end
+ end
- gem "depends_on_rack" # installed from gem_repo3
- gem "rack", :source => "file://#{gem_repo1}"
- G
+ context "when the lockfile has aggregated rubygems sources and newer versions of dependencies are available" do
+ before do
+ build_repo gem_repo2 do
+ build_gem "activesupport", "6.0.3.4" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
+ s.add_dependency "i18n", ">= 0.7", "< 2"
+ s.add_dependency "minitest", "~> 5.1"
+ s.add_dependency "tzinfo", "~> 1.1"
+ s.add_dependency "zeitwerk", "~> 2.2", ">= 2.2.2"
end
- it "installs the dependency from the pinned source without warning" do
- bundle :install
+ build_gem "activesupport", "6.1.2.1" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
+ s.add_dependency "i18n", ">= 1.6", "< 2"
+ s.add_dependency "minitest", ">= 5.1"
+ s.add_dependency "tzinfo", "~> 2.0"
+ s.add_dependency "zeitwerk", "~> 2.3"
+ end
+
+ build_gem "concurrent-ruby", "1.1.8"
+ build_gem "concurrent-ruby", "1.1.9"
+ build_gem "connection_pool", "2.2.3"
- expect(out).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ build_gem "i18n", "1.8.9" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0"
+ end
- # In https://github.com/bundler/bundler/issues/3585 this failed
- # when there is already a lock file, and the gems are missing, so try again
- system_gems []
- bundle :install
+ build_gem "minitest", "5.14.3"
+ build_gem "rack", "2.2.3"
+ build_gem "redis", "4.2.5"
- expect(out).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ build_gem "sidekiq", "6.1.3" do |s|
+ s.add_dependency "connection_pool", ">= 2.2.2"
+ s.add_dependency "rack", "~> 2.0"
+ s.add_dependency "redis", ">= 4.2.0"
+ end
+
+ build_gem "thread_safe", "0.3.6"
+
+ build_gem "tzinfo", "1.2.9" do |s|
+ s.add_dependency "thread_safe", "~> 0.1"
+ end
+
+ build_gem "tzinfo", "2.0.4" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0"
+ end
+
+ build_gem "zeitwerk", "2.4.2"
+ end
+
+ build_repo gem_repo3 do
+ build_gem "sidekiq-pro", "5.2.1" do |s|
+ s.add_dependency "connection_pool", ">= 2.2.3"
+ s.add_dependency "sidekiq", ">= 6.1.0"
end
end
+
+ gemfile <<-G
+ # frozen_string_literal: true
+
+ source "https://gem.repo2"
+
+ gem "activesupport"
+
+ source "https://gem.repo3" do
+ gem "sidekiq-pro"
+ end
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gem.repo2/
+ remote: https://gem.repo3/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ concurrent-ruby (1.1.8)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+ thread_safe (0.3.6)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ zeitwerk (2.4.2)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "does not install newer versions but updates the lockfile format when running bundle install in non frozen mode, and doesn't warn" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).to be_empty
+
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ concurrent-ruby (1.1.8)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ thread_safe (0.3.6)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ zeitwerk (2.4.2)
+
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "does not install newer versions or generate lockfile changes when running bundle install in frozen mode, and warns", :bundler => "< 3" do
+ initial_lockfile = lockfile
+
+ bundle "config set --local frozen true"
+ bundle :install, :artifice => "compact_index"
+
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
+
+ expect(lockfile).to eq(initial_lockfile)
+ end
+
+ it "fails when running bundle install in frozen mode", :bundler => "3" do
+ initial_lockfile = lockfile
+
+ bundle "config set --local frozen true"
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+
+ expect(lockfile).to eq(initial_lockfile)
+ end
+
+ it "splits sections and upgrades gems when running bundle update, and doesn't warn" do
+ bundle "update --all", :artifice => "compact_index"
+ expect(err).to be_empty
+
+ expect(the_bundle).not_to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).not_to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ activesupport (6.1.2.1)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ zeitwerk (~> 2.3)
+ concurrent-ruby (1.1.9)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ tzinfo (2.0.4)
+ concurrent-ruby (~> 1.0)
+ zeitwerk (2.4.2)
+
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "upgrades the lockfile format and upgrades the requested gem when running bundle update with an argument" do
+ bundle "update concurrent-ruby", :artifice => "compact_index"
+ expect(err).to be_empty
+
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ concurrent-ruby (1.1.9)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ thread_safe (0.3.6)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ zeitwerk (2.4.2)
+
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "when a top-level gem has an indirect dependency present in the default source, but with a different version from the one resolved" do
+ before do
+ build_lib "activesupport", "7.0.0.alpha", :path => lib_path("rails/activesupport")
+ build_lib "rails", "7.0.0.alpha", :path => lib_path("rails") do |s|
+ s.add_dependency "activesupport", "= 7.0.0.alpha"
+ end
+
+ build_repo gem_repo2 do
+ build_gem "activesupport", "6.1.2"
+
+ build_gem "webpacker", "5.2.1" do |s|
+ s.add_dependency "activesupport", ">= 5.2"
+ end
+ end
+
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ gemspec :path => "#{lib_path("rails")}"
+
+ gem "webpacker", "~> 5.0"
+ G
+ end
+
+ it "installs all gems without warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", "rails 7.0.0.alpha")
+ expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", :source => "path@#{lib_path("rails/activesupport")}")
+ expect(the_bundle).to include_gems("rails 7.0.0.alpha", :source => "path@#{lib_path("rails")}")
+ end
+ end
+
+ context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source " do
+ before do
+ build_repo gem_repo3 do
+ build_gem "handsoap", "0.2.5.5" do |s|
+ s.add_dependency "nokogiri", ">= 1.2.3"
+ end
+ end
+
+ update_repo gem_repo2 do
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.add_dependency "racca", "~> 1.4"
+ end
+
+ build_gem "racca", "1.5.2"
+ end
+
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ source "https://gem.repo3" do
+ gem "handsoap"
+ end
+
+ gem "nokogiri"
+ G
+ end
+
+ it "installs from the default source without any warnings or errors and generates a proper lockfile" do
+ expected_lockfile = <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ nokogiri (1.11.1)
+ racca (~> 1.4)
+ racca (1.5.2)
+
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ handsoap (0.2.5.5)
+ nokogiri (>= 1.2.3)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ handsoap!
+ nokogiri
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install --verbose", :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
+ expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
+ expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
+ expect(lockfile).to eq(expected_lockfile)
+
+ # Even if the gems are already installed
+ FileUtils.rm bundled_app_lock
+ bundle "install --verbose", :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
+ expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
+ expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
+ expect(lockfile).to eq(expected_lockfile)
end
end
@@ -277,67 +944,147 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "not_in_repo1", "1.0.0"
end
- gemfile <<-G
- source "file://#{gem_repo3}"
- gem "not_in_repo1", :source => "file://#{gem_repo1}"
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
+ source "https://gem.repo3"
+ gem "not_in_repo1", :source => "https://gem.repo1"
G
end
it "does not install the gem" do
- bundle :install
- expect(out).to include("Could not find gem 'not_in_repo1'")
+ expect(err).to include("Could not find gem 'not_in_repo1'")
end
end
context "with an existing lockfile" do
before do
- system_gems "rack-0.9.1", "rack-1.0.0"
+ system_gems "rack-0.9.1", "rack-1.0.0", :path => default_bundle_path
lockfile <<-L
GEM
- remote: file:#{gem_repo1}
- remote: file:#{gem_repo3}
+ remote: https://gem.repo1
+ specs:
+
+ GEM
+ remote: https://gem.repo3
specs:
rack (0.9.1)
PLATFORMS
- ruby
+ #{specific_local_platform}
DEPENDENCIES
rack!
L
gemfile <<-G
- source "file://#{gem_repo1}"
- source "file://#{gem_repo3}" do
+ source "https://gem.repo1"
+ source "https://gem.repo3" do
gem 'rack'
end
G
end
- # Reproduction of https://github.com/bundler/bundler/issues/3298
+ # Reproduction of https://github.com/rubygems/bundler/issues/3298
it "does not unlock the installed gem on exec" do
expect(the_bundle).to include_gems("rack 0.9.1")
end
end
+ context "with a lockfile with aggregated rubygems sources" do
+ let(:aggregate_gem_section_lockfile) do
+ <<~L
+ GEM
+ remote: https://gem.repo1/
+ remote: https://gem.repo3/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ let(:split_gem_section_lockfile) do
+ <<~L
+ GEM
+ remote: https://gem.repo1/
+ specs:
+
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ before do
+ build_repo gem_repo3 do
+ build_gem "rack", "0.9.1"
+ end
+
+ gemfile <<-G
+ source "https://gem.repo1"
+ source "https://gem.repo3" do
+ gem 'rack'
+ end
+ G
+
+ lockfile aggregate_gem_section_lockfile
+ end
+
+ it "installs the existing lockfile but prints a warning", :bundler => "< 3" do
+ bundle "config set --local deployment true"
+
+ bundle "install", :artifice => "compact_index"
+
+ expect(lockfile).to eq(aggregate_gem_section_lockfile)
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ expect(the_bundle).to include_gems("rack 0.9.1", :source => "remote3")
+ end
+
+ it "refuses to install the existing lockfile and prints an error", :bundler => "3" do
+ bundle "config set --local deployment true"
+
+ bundle "install", :artifice => "compact_index", :raise_on_error =>false
+
+ expect(lockfile).to eq(aggregate_gem_section_lockfile)
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ expect(out).to be_empty
+ end
+ end
+
context "with a path gem in the same Gemfile" do
before do
build_lib "foo"
gemfile <<-G
- gem "rack", :source => "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", :source => "https://gem.repo1"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
end
it "does not unlock the non-path gem after install" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
bundle %(exec ruby -e 'puts "OK"')
expect(out).to include("OK")
- expect(exitstatus).to eq(0) if exitstatus
end
end
end
@@ -346,57 +1093,38 @@ RSpec.describe "bundle install with gems on multiple sources" do
before do
system_gems "rack-0.9.1"
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack" # shoud come from repo1!
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
+ gem "rack" # should come from repo1!
G
end
it "installs the gems without any warning" do
- bundle :install
- expect(out).not_to include("Warning")
+ expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("rack 1.0.0")
end
end
context "when a single source contains multiple locked gems" do
before do
- # 1. With these gems,
+ # With these gems,
build_repo4 do
build_gem "foo", "0.1"
build_gem "bar", "0.1"
end
- # 2. Installing this gemfile will produce...
+ # Installing this gemfile...
gemfile <<-G
- source 'file://#{gem_repo1}'
+ source 'https://gem.repo1'
gem 'rack'
- gem 'foo', '~> 0.1', :source => 'file://#{gem_repo4}'
- gem 'bar', '~> 0.1', :source => 'file://#{gem_repo4}'
+ gem 'foo', '~> 0.1', :source => 'https://gem.repo4'
+ gem 'bar', '~> 0.1', :source => 'https://gem.repo4'
G
- # 3. this lockfile.
- lockfile <<-L
- GEM
- remote: file:/Users/andre/src/bundler/bundler/tmp/gems/remote1/
- remote: file:/Users/andre/src/bundler/bundler/tmp/gems/remote4/
- specs:
- bar (0.1)
- foo (0.1)
- rack (1.0.0)
-
- PLATFORMS
- ruby
-
- DEPENDENCIES
- bar (~> 0.1)!
- foo (~> 0.1)!
- rack
- L
+ bundle "config set --local path ../gems/system"
+ bundle :install, :artifice => "compact_index"
- bundle "install --path ../gems/system"
-
- # 4. Then we add some new versions...
+ # And then we add some new versions...
update_repo4 do
build_gem "foo", "0.2"
build_gem "bar", "0.3"
@@ -404,34 +1132,36 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "allows them to be unlocked separately" do
- # 5. and install this gemfile, updating only foo.
- install_gemfile <<-G
- source 'file://#{gem_repo1}'
+ # And install this gemfile, updating only foo.
+ install_gemfile <<-G, :artifice => "compact_index"
+ source 'https://gem.repo1'
gem 'rack'
- gem 'foo', '~> 0.2', :source => 'file://#{gem_repo4}'
- gem 'bar', '~> 0.1', :source => 'file://#{gem_repo4}'
+ gem 'foo', '~> 0.2', :source => 'https://gem.repo4'
+ gem 'bar', '~> 0.1', :source => 'https://gem.repo4'
G
- # 6. Which should update foo to 0.2, but not the (locked) bar 0.1
- expect(the_bundle).to include_gems("foo 0.2")
- expect(the_bundle).to include_gems("bar 0.1")
+ # It should update foo to 0.2, but not the (locked) bar 0.1
+ expect(the_bundle).to include_gems("foo 0.2", "bar 0.1")
end
end
context "re-resolving" do
context "when there is a mix of sources in the gemfile" do
before do
- build_repo3
+ build_repo gem_repo3 do
+ build_gem "rack"
+ end
+
build_lib "path1"
build_lib "path2"
build_git "git1"
build_git "git2"
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
gem "rails"
- source "file://#{gem_repo3}" do
+ source "https://gem.repo3" do
gem "rack"
end
@@ -443,7 +1173,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "does not re-resolve" do
- bundle :install, :verbose => true
+ bundle :install, :artifice => "compact_index", :verbose => true
expect(out).to include("using resolution from the lockfile")
expect(out).not_to include("re-resolving dependencies")
end
@@ -452,58 +1182,35 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "when a gem is installed to system gems" do
before do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
gem "rack"
G
end
context "and the gemfile changes" do
it "is still able to find that gem from remote sources" do
- source_uri = "file://#{gem_repo1}"
- second_uri = "file://#{gem_repo4}"
-
build_repo4 do
build_gem "rack", "2.0.1.1.forked"
build_gem "thor", "0.19.1.1.forked"
end
# When this gemfile is installed...
- gemfile <<-G
- source "#{source_uri}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
- source "#{second_uri}" do
+ source "https://gem.repo4" do
gem "rack", "2.0.1.1.forked"
gem "thor"
end
gem "rack-obama"
G
- # It creates this lockfile.
- lockfile <<-L
- GEM
- remote: #{source_uri}/
- remote: #{second_uri}/
- specs:
- rack (2.0.1.1.forked)
- rack-obama (1.0)
- rack
- thor (0.19.1.1.forked)
-
- PLATFORMS
- ruby
-
- DEPENDENCIES
- rack (= 2.0.1.1.forked)!
- rack-obama
- thor!
- L
-
# Then we change the Gemfile by adding a version to thor
gemfile <<-G
- source "#{source_uri}"
+ source "https://gem.repo1"
- source "#{second_uri}" do
+ source "https://gem.repo4" do
gem "rack", "2.0.1.1.forked"
gem "thor", "0.19.1.1.forked"
end
@@ -511,8 +1218,229 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
# But we should still be able to find rack 2.0.1.1.forked and install it
- bundle! :install
+ bundle :install, :artifice => "compact_index"
end
end
end
+
+ describe "source changed to one containing a higher version of a dependency" do
+ before do
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
+
+ gem "rack"
+ G
+
+ build_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
+ build_gem "bar"
+ end
+
+ build_lib("gemspec_test", :path => tmp.join("gemspec_test")) do |s|
+ s.add_dependency "bar", "=1.0.0"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo2"
+ gem "rack"
+ gemspec :path => "#{tmp.join("gemspec_test")}"
+ G
+ end
+
+ it "conservatively installs the existing locked version" do
+ expect(the_bundle).to include_gems("rack 1.0.0")
+ end
+ end
+
+ it "doesn't update version when a gem uses a source block but a higher version from another source is already installed locally" do
+ build_repo2 do
+ build_gem "example", "0.1.0"
+ end
+
+ build_repo4 do
+ build_gem "example", "1.0.2"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo4"
+
+ gem "example", :source => "https://gem.repo2"
+ G
+
+ bundle "info example"
+ expect(out).to include("example (0.1.0)")
+
+ system_gems "example-1.0.2", :path => default_bundle_path, :gem_repo => gem_repo4
+
+ bundle "update example --verbose", :artifice => "compact_index"
+ expect(out).not_to include("Using example 1.0.2")
+ expect(out).to include("Using example 0.1.0")
+ end
+
+ it "fails inmmediately with a helpful error when a rubygems source does not exist and bundler/setup is required" do
+ gemfile <<-G
+ source "https://gem.repo1"
+
+ source "https://gem.repo4" do
+ gem "example"
+ end
+ G
+
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ ruby <<~R, :raise_on_error => false
+ require 'bundler/setup'
+ R
+ end
+
+ expect(last_command).to be_failure
+ expect(err).to include("Could not find gem 'example' in locally installed gems.")
+ end
+
+ it "fails inmmediately with a helpful error when a non retriable network error happens while resolving sources" do
+ gemfile <<-G
+ source "https://gem.repo1"
+
+ source "https://gem.repo4" do
+ gem "example"
+ end
+ G
+
+ bundle "install", :artifice => nil, :raise_on_error => false
+
+ expect(last_command).to be_failure
+ expect(err).to include("Could not reach host gem.repo4. Check your network connection and try again.")
+ end
+
+ context "when an indirect dependency is available from multiple ambiguous sources", :bundler => "< 3" do
+ it "succeeds but warns, suggesting a source block" do
+ build_repo4 do
+ build_gem "depends_on_rack" do |s|
+ s.add_dependency "rack"
+ end
+ build_gem "rack"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+
+ source "https://gem.repo4" do
+ gem "depends_on_rack"
+ end
+
+ source "https://gem.repo1" do
+ gem "thin"
+ end
+ G
+ expect(err).to eq strip_whitespace(<<-EOS).strip
+ Warning: The gem 'rack' was found in multiple relevant sources.
+ * rubygems repository https://gem.repo1/
+ * rubygems repository https://gem.repo4/
+ You should add this gem to the source block for the source you wish it to be installed from.
+ EOS
+ expect(last_command).to be_success
+ expect(the_bundle).to be_locked
+ end
+ end
+
+ context "when an indirect dependency is available from multiple ambiguous sources", :bundler => "3" do
+ it "raises, suggesting a source block" do
+ build_repo4 do
+ build_gem "depends_on_rack" do |s|
+ s.add_dependency "rack"
+ end
+ build_gem "rack"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ source "https://gem.repo4" do
+ gem "depends_on_rack"
+ end
+ source "https://gem.repo1" do
+ gem "thin"
+ end
+ G
+ expect(last_command).to be_failure
+ expect(err).to eq strip_whitespace(<<-EOS).strip
+ The gem 'rack' was found in multiple relevant sources.
+ * rubygems repository https://gem.repo1/
+ * rubygems repository https://gem.repo4/
+ You must add this gem to the source block for the source you wish it to be installed from.
+ EOS
+ expect(the_bundle).not_to be_locked
+ end
+ end
+
+ context "when upgrading a lockfile suffering from dependency confusion" do
+ before do
+ build_repo4 do
+ build_gem "mime-types", "3.0.0"
+ end
+
+ build_repo2 do
+ build_gem "capybara", "2.5.0" do |s|
+ s.add_dependency "mime-types", ">= 1.16"
+ end
+
+ build_gem "mime-types", "3.3.1"
+ end
+
+ gemfile <<~G
+ source "https://gem.repo2"
+
+ gem "capybara", "~> 2.5.0"
+
+ source "https://gem.repo4" do
+ gem "mime-types", "~> 3.0"
+ end
+ G
+
+ lockfile <<-L
+ GEM
+ remote: https://gem.repo2/
+ remote: https://gem.repo4/
+ specs:
+ capybara (2.5.0)
+ mime-types (>= 1.16)
+ mime-types (3.3.1)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ capybara (~> 2.5.0)
+ mime-types (~> 3.0)!
+ L
+ end
+
+ it "upgrades the lockfile correctly" do
+ bundle "lock --update", :artifice => "compact_index"
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ capybara (2.5.0)
+ mime-types (>= 1.16)
+
+ GEM
+ remote: https://gem.repo4/
+ specs:
+ mime-types (3.0.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ capybara (~> 2.5.0)
+ mime-types (~> 3.0)!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
end
diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb
index cc6c82c0ff..ce2823ce9a 100644
--- a/spec/bundler/install/gemfile/specific_platform_spec.rb
+++ b/spec/bundler/install/gemfile/specific_platform_spec.rb
@@ -1,115 +1,315 @@
# frozen_string_literal: true
-require "spec_helper"
-RSpec.describe "bundle install with specific_platform enabled" do
- before do
- bundle "config specific_platform true"
+RSpec.describe "bundle install with specific platforms" do
+ let(:google_protobuf) { <<-G }
+ source "#{file_uri_for(gem_repo2)}"
+ gem "google-protobuf"
+ G
- build_repo2 do
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1")
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "x86_64-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "x86-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "x86-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "x64-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "universal-darwin" }
+ context "when on a darwin machine" do
+ before { simulate_platform "x86_64-darwin-15" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5") {|s| s.platform = "x86_64-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5") {|s| s.platform = "x86-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5") {|s| s.platform = "x64-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5") {|s| s.platform = "x86-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.5")
+ it "locks to the specific darwin platform" do
+ setup_multiplatform_gem
+ install_gemfile(google_protobuf)
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ expect(the_bundle.locked_gems.platforms).to eq([pl("x86_64-darwin-15")])
+ expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
+ google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
+ ])
+ end
- build_gem("google-protobuf", "3.0.0.alpha.5.0.4") {|s| s.platform = "universal-darwin" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.4") {|s| s.platform = "x86_64-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.4") {|s| s.platform = "x86-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.4") {|s| s.platform = "x86-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.4") {|s| s.platform = "x64-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.4")
-
- build_gem("google-protobuf", "3.0.0.alpha.5.0.3")
- build_gem("google-protobuf", "3.0.0.alpha.5.0.3") {|s| s.platform = "x86_64-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.3") {|s| s.platform = "x86-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.3") {|s| s.platform = "x86-linux" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.3") {|s| s.platform = "x64-mingw32" }
- build_gem("google-protobuf", "3.0.0.alpha.5.0.3") {|s| s.platform = "universal-darwin" }
+ it "understands that a non-platform specific gem in a old lockfile doesn't necessarily mean installing the non-specific variant" do
+ setup_multiplatform_gem
- build_gem("google-protobuf", "3.0.0.alpha.4.0")
- build_gem("google-protobuf", "3.0.0.alpha.3.1.pre")
- build_gem("google-protobuf", "3.0.0.alpha.3")
- build_gem("google-protobuf", "3.0.0.alpha.2.0")
- build_gem("google-protobuf", "3.0.0.alpha.1.1")
- build_gem("google-protobuf", "3.0.0.alpha.1.0")
+ system_gems "bundler-2.1.4"
- build_gem("facter", "2.4.6")
- build_gem("facter", "2.4.6") do |s|
- s.platform = "universal-darwin"
- s.add_runtime_dependency "CFPropertyList"
- end
- build_gem("CFPropertyList")
+ # Consistent location to install and look for gems
+ bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
+
+ install_gemfile(google_protobuf, :env => { "BUNDLER_VERSION" => "2.1.4" })
+
+ # simulate lockfile created with old bundler, which only locks for ruby platform
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ google-protobuf (3.0.0.alpha.5.0.5.1)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ google-protobuf
+
+ BUNDLED WITH
+ 2.1.4
+ L
+
+ # force strict usage of the lock file by setting frozen mode
+ bundle "config set --local frozen true", :env => { "BUNDLER_VERSION" => "2.1.4" }
+
+ # make sure the platform that got actually installed with the old bundler is used
+ expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
end
- end
- let(:google_protobuf) { <<-G }
- source "file:#{gem_repo2}"
- gem "google-protobuf"
- G
+ it "understands that a non-platform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do
+ setup_multiplatform_gem
- context "when on a darwin machine" do
- before { simulate_platform "x86_64-darwin-15" }
+ system_gems "bundler-2.1.4"
- it "locks to both the specific darwin platform and ruby" do
- install_gemfile!(google_protobuf)
- expect(the_bundle.locked_gems.platforms).to eq([pl("ruby"), pl("x86_64-darwin-15")])
+ # Consistent location to install and look for gems
+ bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
+
+ gemfile google_protobuf
+
+ # simulate lockfile created with old bundler, which only locks for ruby platform
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ google-protobuf (3.0.0.alpha.4.0)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ google-protobuf
+
+ BUNDLED WITH
+ 2.1.4
+ L
+
+ bundle "update", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
+
+ # make sure the platform that the platform specific dependency is used, since we're only locked to ruby
expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w(
- google-protobuf-3.0.0.alpha.5.0.5.1
- google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
- ))
+
+ # make sure we're still only locked to ruby
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ google-protobuf (3.0.0.alpha.5.0.5.1)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ google-protobuf
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
- it "caches both the universal-darwin and ruby gems when --all-platforms is passed" do
+ it "doesn't discard previously installed platform specific gem and fall back to ruby on subsequent bundles" do
+ build_repo2 do
+ build_gem("libv8", "8.4.255.0")
+ build_gem("libv8", "8.4.255.0") {|s| s.platform = "universal-darwin" }
+
+ build_gem("mini_racer", "1.0.0") do |s|
+ s.add_runtime_dependency "libv8"
+ end
+ end
+
+ system_gems "bundler-2.1.4"
+
+ # Consistent location to install and look for gems
+ bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
+
+ gemfile <<-G
+ source "https://localgemserver.test"
+ gem "libv8"
+ G
+
+ # simulate lockfile created with old bundler, which only locks for ruby platform
+ lockfile <<-L
+ GEM
+ remote: https://localgemserver.test/
+ specs:
+ libv8 (8.4.255.0)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ libv8
+
+ BUNDLED WITH
+ 2.1.4
+ L
+
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ expect(out).to include("Installing libv8 8.4.255.0 (universal-darwin)")
+
+ bundle "add mini_racer --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)")
+ end
+
+ it "caches the universal-darwin gem when --all-platforms is passed and properly picks it up on further bundler invocations" do
+ setup_multiplatform_gem
+ gemfile(google_protobuf)
+ bundle "cache --all-platforms"
+ expect(cached_gem("google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin")).to exist
+
+ bundle "install --verbose"
+ expect(err).to be_empty
+ end
+
+ it "caches the universal-darwin gem when cache_all_platforms is configured and properly picks it up on further bundler invocations" do
+ setup_multiplatform_gem
gemfile(google_protobuf)
- bundle! "package --all-platforms"
- expect([cached_gem("google-protobuf-3.0.0.alpha.5.0.5.1"), cached_gem("google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin")]).
- to all(exist)
+ bundle "config set --local cache_all_platforms true"
+ bundle "cache"
+ expect(cached_gem("google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin")).to exist
+
+ bundle "install --verbose"
+ expect(err).to be_empty
+ end
+
+ it "caches multiplatform git gems with a single gemspec when --all-platforms is passed" do
+ git = build_git "pg_array_parser", "1.0"
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "pg_array_parser", :git => "#{lib_path("pg_array_parser-1.0")}"
+ G
+
+ lockfile <<-L
+ GIT
+ remote: #{lib_path("pg_array_parser-1.0")}
+ revision: #{git.ref_for("master")}
+ specs:
+ pg_array_parser (1.0-java)
+ pg_array_parser (1.0)
+
+ GEM
+ specs:
+
+ PLATFORMS
+ java
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ pg_array_parser!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "config set --local cache_all true"
+ bundle "cache --all-platforms"
+
+ expect(err).to be_empty
end
it "uses the platform-specific gem with extra dependencies" do
- install_gemfile! <<-G
- source "file:#{gem_repo2}"
+ setup_multiplatform_gem_with_different_dependencies_per_platform
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
gem "facter"
G
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
- expect(the_bundle.locked_gems.platforms).to eq([pl("ruby"), pl("x86_64-darwin-15")])
+ expect(the_bundle.locked_gems.platforms).to eq([pl("x86_64-darwin-15")])
expect(the_bundle).to include_gems("facter 2.4.6 universal-darwin", "CFPropertyList 1.0")
expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(["CFPropertyList-1.0",
- "facter-2.4.6",
"facter-2.4.6-universal-darwin"])
end
context "when adding a platform via lock --add_platform" do
+ before do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ end
+
it "adds the foreign platform" do
- install_gemfile!(google_protobuf)
- bundle! "lock --add-platform=#{x64_mingw}"
+ setup_multiplatform_gem
+ install_gemfile(google_protobuf)
+ bundle "lock --add-platform=#{x64_mingw}"
- expect(the_bundle.locked_gems.platforms).to eq([rb, x64_mingw, pl("x86_64-darwin-15")])
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w(
- google-protobuf-3.0.0.alpha.5.0.5.1
+ expect(the_bundle.locked_gems.platforms).to eq([x64_mingw, pl("x86_64-darwin-15")])
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
google-protobuf-3.0.0.alpha.5.0.5.1-x64-mingw32
- ))
+ ])
end
it "falls back on plain ruby when that version doesnt have a platform-specific gem" do
- install_gemfile!(google_protobuf)
- bundle! "lock --add-platform=#{java}"
+ setup_multiplatform_gem
+ install_gemfile(google_protobuf)
+ bundle "lock --add-platform=#{java}"
- expect(the_bundle.locked_gems.platforms).to eq([java, rb, pl("x86_64-darwin-15")])
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w(
+ expect(the_bundle.locked_gems.platforms).to eq([java, pl("x86_64-darwin-15")])
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
google-protobuf-3.0.0.alpha.5.0.5.1
google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
- ))
+ ])
end
end
end
+
+ it "installs sorbet-static, which does not provide a pure ruby variant, just fine on truffleruby", :truffleruby do
+ build_repo2 do
+ build_gem("sorbet-static", "0.5.6403") {|s| s.platform = "x86_64-linux" }
+ build_gem("sorbet-static", "0.5.6403") {|s| s.platform = "universal-darwin-20" }
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "sorbet-static", "0.5.6403"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ sorbet-static (0.5.6403-universal-darwin-20)
+ sorbet-static (0.5.6403-x86_64-linux)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ sorbet-static (= 0.5.6403)
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install --verbose"
+ end
+
+ private
+
+ def setup_multiplatform_gem
+ build_repo2 do
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1")
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "x86_64-linux" }
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "x64-mingw32" }
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.5.1") {|s| s.platform = "universal-darwin" }
+
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.5") {|s| s.platform = "x86_64-linux" }
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.5") {|s| s.platform = "x64-mingw32" }
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.5")
+
+ build_gem("google-protobuf", "3.0.0.alpha.5.0.4") {|s| s.platform = "universal-darwin" }
+
+ build_gem("google-protobuf", "3.0.0.alpha.4.0")
+ build_gem("google-protobuf", "3.0.0.alpha.3.1.pre")
+ end
+ end
+
+ def setup_multiplatform_gem_with_different_dependencies_per_platform
+ build_repo2 do
+ build_gem("facter", "2.4.6")
+ build_gem("facter", "2.4.6") do |s|
+ s.platform = "universal-darwin"
+ s.add_runtime_dependency "CFPropertyList"
+ end
+ build_gem("CFPropertyList")
+ end
+ end
end
diff --git a/spec/bundler/install/gemfile_spec.rb b/spec/bundler/install/gemfile_spec.rb
index bc49053081..0f8f1ecfa8 100644
--- a/spec/bundler/install/gemfile_spec.rb
+++ b/spec/bundler/install/gemfile_spec.rb
@@ -1,26 +1,29 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
context "with duplicated gems" do
it "will display a warning" do
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+
gem 'rails', '~> 4.0.0'
gem 'rails', '~> 4.0.0'
G
- expect(out).to include("more than once")
+ expect(err).to include("more than once")
end
end
context "with --gemfile" do
it "finds the gemfile" do
gemfile bundled_app("NotGemfile"), <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
bundle :install, :gemfile => bundled_app("NotGemfile")
+ # Specify BUNDLE_GEMFILE for `the_bundle`
+ # to retrieve the proper Gemfile
ENV["BUNDLE_GEMFILE"] = "NotGemfile"
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -29,70 +32,87 @@ RSpec.describe "bundle install" do
context "with gemfile set via config" do
before do
gemfile bundled_app("NotGemfile"), <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
- bundle "config --local gemfile #{bundled_app("NotGemfile")}"
+ bundle "config set --local gemfile #{bundled_app("NotGemfile")}"
end
it "uses the gemfile to install" do
bundle "install"
- bundle "show"
+ bundle "list"
expect(out).to include("rack (1.0.0)")
end
it "uses the gemfile while in a subdirectory" do
bundled_app("subdir").mkpath
- Dir.chdir(bundled_app("subdir")) do
- bundle "install"
- bundle "show"
+ bundle "install", :dir => bundled_app("subdir")
+ bundle "list", :dir => bundled_app("subdir")
- expect(out).to include("rack (1.0.0)")
- end
+ expect(out).to include("rack (1.0.0)")
end
end
context "with deprecated features" do
- before :each do
- in_app_root
- end
-
it "reports that lib is an invalid option" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
gem "rack", :lib => "rack"
G
- bundle :install
- expect(out).to match(/You passed :lib as an option for gem 'rack', but it is invalid/)
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/You passed :lib as an option for gem 'rack', but it is invalid/)
end
end
- context "with engine specified in symbol" do
+ context "with engine specified in symbol", :jruby do
it "does not raise any error parsing Gemfile" do
- simulate_ruby_version "2.3.0" do
- simulate_ruby_engine "jruby", "9.1.2.0" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
- ruby "2.3.0", :engine => :jruby, :engine_version => "9.1.2.0"
- G
-
- expect(out).to match(/Bundle complete!/)
- end
- end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "#{RUBY_VERSION}", :engine => :jruby, :engine_version => "#{RUBY_ENGINE_VERSION}"
+ G
+
+ expect(out).to match(/Bundle complete!/)
end
it "installation succeeds" do
- simulate_ruby_version "2.3.0" do
- simulate_ruby_engine "jruby", "9.1.2.0" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
- ruby "2.3.0", :engine => :jruby, :engine_version => "9.1.2.0"
- gem "rack"
- G
-
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
- end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "#{RUBY_VERSION}", :engine => :jruby, :engine_version => "#{RUBY_ENGINE_VERSION}"
+ gem "rack"
+ G
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+ end
+
+ context "with a Gemfile containing non-US-ASCII characters" do
+ it "reads the Gemfile with the UTF-8 encoding by default" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ str = "Il était une fois ..."
+ puts "The source encoding is: " + str.encoding.name
+ G
+
+ expect(out).to include("The source encoding is: UTF-8")
+ expect(out).not_to include("The source encoding is: ASCII-8BIT")
+ expect(out).to include("Bundle complete!")
+ end
+
+ it "respects the magic encoding comment" do
+ # NOTE: This works thanks to #eval interpreting the magic encoding comment
+ install_gemfile <<-G
+ # encoding: iso-8859-1
+ source "#{file_uri_for(gem_repo1)}"
+
+ str = "Il #{"\xE9".dup.force_encoding("binary")}tait une fois ..."
+ puts "The source encoding is: " + str.encoding.name
+ G
+
+ expect(out).to include("The source encoding is: ISO-8859-1")
+ expect(out).to include("Bundle complete!")
end
end
end
diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb
index 825185c82e..0cee69f702 100644
--- a/spec/bundler/install/gems/compact_index_spec.rb
+++ b/spec/bundler/install/gems/compact_index_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "compact index api" do
let(:source_hostname) { "localgemserver.test" }
@@ -11,7 +10,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -22,8 +21,8 @@ RSpec.describe "compact index api" do
gem " sinatra"
G
- bundle :install, :artifice => "compact_index"
- expect(out).to include("' sinatra' is not a valid gem name because it contains whitespace.")
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("' sinatra' is not a valid gem name because it contains whitespace.")
end
it "should handle nested dependencies" do
@@ -32,7 +31,7 @@ RSpec.describe "compact index api" do
gem "rails"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems(
"rails 2.3.2",
@@ -52,7 +51,7 @@ RSpec.describe "compact index api" do
build_gem "Rack", "0.1"
end
- install_gemfile! <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4 }
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
source "#{source_uri}"
gem "rack", "1.0"
gem "Rack", "0.1"
@@ -60,7 +59,7 @@ RSpec.describe "compact index api" do
# can't use `include_gems` here since the `require` will conflict on a
# case-insensitive FS
- run! "Bundler.require; puts Gem.loaded_specs.values_at('rack', 'Rack').map(&:full_name)"
+ run "Bundler.require; puts Gem.loaded_specs.values_at('rack', 'Rack').map(&:full_name)"
expect(out).to eq("rack-1.0\nRack-0.1")
end
@@ -70,18 +69,20 @@ RSpec.describe "compact index api" do
gem "net-sftp"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems "net-sftp 1.1.1"
end
- it "should use the endpoint when using --deployment" do
+ it "should use the endpoint when using deployment mode" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
- bundle "install --deployment", :artifice => "compact_index"
+ bundle "config set --local deployment true"
+ bundle "config set --local path vendor/bundle"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -94,17 +95,17 @@ RSpec.describe "compact index api" do
gemfile <<-G
source "#{source_uri}"
- git "file:///#{lib_path("foo-1.0")}" do
+ git "#{file_uri_for(lib_path("foo-1.0"))}" do
gem 'foo'
end
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("rails 2.3.2")
end
- it "handles git dependencies that are in rubygems using --deployment" do
+ it "handles git dependencies that are in rubygems using deployment mode" do
build_git "foo" do |s|
s.executables = "foobar"
s.add_dependency "rails", "2.3.2"
@@ -112,50 +113,38 @@ RSpec.describe "compact index api" do
gemfile <<-G
source "#{source_uri}"
- gem 'foo', :git => "file:///#{lib_path("foo-1.0")}"
+ gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
- bundle "install --deployment", :artifice => "compact_index"
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("rails 2.3.2")
end
- it "doesn't fail if you only have a git gem with no deps when using --deployment" do
+ it "doesn't fail if you only have a git gem with no deps when using deployment mode" do
build_git "foo"
gemfile <<-G
source "#{source_uri}"
- gem 'foo', :git => "file:///#{lib_path("foo-1.0")}"
+ gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
bundle "install", :artifice => "compact_index"
- bundle "install --deployment", :artifice => "compact_index"
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "compact_index"
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems("foo 1.0")
end
- it "falls back when the API errors out" do
- simulate_platform mswin
-
- gemfile <<-G
- source "#{source_uri}"
- gem "rcov"
- G
-
- bundle! :install, :artifice => "windows"
- expect(out).to include("Fetching source index from #{source_uri}")
- expect(the_bundle).to include_gems "rcov 1.0.0"
- end
-
it "falls back when the API URL returns 403 Forbidden" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle! :install, :verbose => true, :artifice => "compact_index_forbidden"
+ bundle :install, :verbose => true, :artifice => "compact_index_forbidden"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -166,7 +155,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle! :install, :verbose => true, :artifice => "compact_index_checksum_mismatch"
+ bundle :install, :verbose => true, :artifice => "compact_index_checksum_mismatch"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(out).to include <<-'WARN'
The checksum of /versions does not match the checksum provided by the server! Something is wrong (local checksum is "\"d41d8cd98f00b204e9800998ecf8427e\"", was expecting "\"123\"").
@@ -175,14 +164,14 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "falls back when the user's home directory does not exist or is not writable" do
- ENV["HOME"] = nil
+ ENV["HOME"] = tmp("missing_home").to_s
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -193,7 +182,7 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle! :install, :artifice => "compact_index_host_redirect"
+ bundle :install, :artifice => "compact_index_host_redirect"
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -216,7 +205,7 @@ The checksum of /versions does not match the checksum provided by the server! So
H
end
- bundle! :install, :artifice => "compact_index_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")]
+ bundle :install, :artifice => "compact_index_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")]
expect(out).to_not match(/Too many redirects/)
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -227,8 +216,8 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle :install, :artifice => "compact_index_redirects"
- expect(out).to match(/Too many redirects/)
+ bundle :install, :artifice => "compact_index_redirects", :raise_on_error => false
+ expect(err).to match(/Too many redirects/)
end
context "when --full-index is specified" do
@@ -249,13 +238,52 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle "update --full-index", :artifice => "compact_index"
+ bundle "update --full-index", :artifice => "compact_index", :all => true
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
- it "fetches again when more dependencies are found in subsequent sources" do
+ it "does not double check for gems that are only installed locally" do
+ build_repo2 do
+ build_gem "net_a" do |s|
+ s.add_dependency "net_b"
+ s.add_dependency "net_build_extensions"
+ end
+
+ build_gem "net_b"
+
+ build_gem "net_build_extensions" do |s|
+ s.add_dependency "rake"
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/net_build_extensions.rb", "w") do |f|
+ f.puts "NET_BUILD_EXTENSIONS = 'YES'"
+ end
+ end
+ RUBY
+ end
+ end
+
+ system_gems %w[rack-1.0.0 thin-1.0 net_a-1.0], :gem_repo => gem_repo2
+ bundle "config set --local path.system true"
+ ENV["BUNDLER_SPEC_ALL_REQUESTS"] = strip_whitespace(<<-EOS).strip
+ #{source_uri}/versions
+ #{source_uri}/info/rack
+ EOS
+
+ install_gemfile <<-G, :artifice => "compact_index", :verbose => true, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ source "#{source_uri}"
+ gem "rack"
+ G
+
+ expect(last_command.stdboth).not_to include "Double checking"
+ end
+
+ it "fetches again when more dependencies are found in subsequent sources", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -269,8 +297,26 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "back_deps"
G
- bundle! :install, :artifice => "compact_index_extra"
- expect(the_bundle).to include_gems "back_deps 1.0"
+ bundle :install, :artifice => "compact_index_extra"
+ expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
+ end
+
+ it "fetches again when more dependencies are found in subsequent sources with source blocks" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index_extra", :verbose => true
+ source "#{source_uri}"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
+ G
+
+ expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
end
it "fetches gem versions even when those gems are already installed" do
@@ -278,7 +324,7 @@ The checksum of /versions does not match the checksum provided by the server! So
source "#{source_uri}"
gem "rack", "1.0.0"
G
- bundle! :install, :artifice => "compact_index_extra_api"
+ bundle :install, :artifice => "compact_index_extra_api"
expect(the_bundle).to include_gems "rack 1.0.0"
build_repo4 do
@@ -292,11 +338,11 @@ The checksum of /versions does not match the checksum provided by the server! So
source "#{source_uri}/extra"
gem "rack", "1.2"
G
- bundle! :install, :artifice => "compact_index_extra_api"
+ bundle :install, :artifice => "compact_index_extra_api"
expect(the_bundle).to include_gems "rack 1.2"
end
- it "considers all possible versions of dependencies from all api gem sources" do
+ it "considers all possible versions of dependencies from all api gem sources", :bundler => "< 3" do
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
@@ -314,7 +360,7 @@ The checksum of /versions does not match the checksum provided by the server! So
gem 'somegem', '1.0.0'
G
- bundle! :install, :artifice => "compact_index_extra_api"
+ bundle :install, :artifice => "compact_index_extra_api"
expect(the_bundle).to include_gems "somegem 1.0.0"
expect(the_bundle).to include_gems "activesupport 1.2.3"
@@ -330,11 +376,12 @@ The checksum of /versions does not match the checksum provided by the server! So
gemfile <<-G
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
G
- bundle! :install, :artifice => "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
expect(out).to include("Fetching gem metadata from http://localgemserver.test/")
expect(out).to include("Fetching source index from http://localgemserver.test/extra")
@@ -346,24 +393,44 @@ The checksum of /versions does not match the checksum provided by the server! So
s.add_dependency "foo"
end
build_gem "missing"
- # need to hit the limit
- 1.upto(Bundler::Source::Rubygems::API_REQUEST_LIMIT) do |i|
- build_gem "gem#{i}"
- end
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end
- gemfile <<-G
+ api_request_limit = low_api_request_limit_for(gem_repo2)
+
+ install_gemfile <<-G, :artifice => "compact_index_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
G
- bundle! :install, :artifice => "compact_index_extra_missing"
expect(the_bundle).to include_gems "back_deps 1.0"
end
+ it "does not fetch every spec if the index of gems is large when doing back deps & everything is the compact index" do
+ build_repo4 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ build_gem "missing"
+
+ FileUtils.rm_rf Dir[gem_repo4("gems/foo-*.gem")]
+ end
+
+ api_request_limit = low_api_request_limit_for(gem_repo4)
+
+ install_gemfile <<-G, :artifice => "compact_index_extra_api_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
+ source "#{source_uri}"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
+ G
+
+ expect(the_bundle).to include_gem "back_deps 1.0"
+ end
+
it "uses the endpoint if all sources support it" do
gemfile <<-G
source "#{source_uri}"
@@ -371,11 +438,11 @@ The checksum of /versions does not match the checksum provided by the server! So
gem 'foo'
G
- bundle! :install, :artifice => "compact_index_api_missing"
+ bundle :install, :artifice => "compact_index_api_missing"
expect(the_bundle).to include_gems "foo 1.0"
end
- it "fetches again when more dependencies are found in subsequent sources using --deployment" do
+ it "fetches again when more dependencies are found in subsequent sources using deployment mode", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -389,20 +456,47 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "back_deps"
G
- bundle! :install, :artifice => "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
+ bundle "config --set local deployment true"
+ bundle :install, :artifice => "compact_index_extra"
+ expect(the_bundle).to include_gems "back_deps 1.0"
+ end
+
+ it "fetches again when more dependencies are found in subsequent sources using deployment mode with blocks" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
- bundle "install --deployment", :artifice => "compact_index_extra"
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
+ G
+
+ bundle :install, :artifice => "compact_index_extra"
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "compact_index_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end
it "does not refetch if the only unmet dependency is bundler" do
+ build_repo2 do
+ build_gem "bundler_dep" do |s|
+ s.add_dependency "bundler"
+ end
+ end
+
gemfile <<-G
source "#{source_uri}"
gem "bundler_dep"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Fetching gem metadata from #{source_uri}")
end
@@ -414,11 +508,11 @@ The checksum of /versions does not match the checksum provided by the server! So
source "#{source_uri}"
gem "rails"
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems "rails 2.3.2"
end
- it "installs the binstubs" do
+ it "installs the binstubs", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -430,7 +524,7 @@ The checksum of /versions does not match the checksum provided by the server! So
expect(out).to eq("1.0.0")
end
- it "installs the bins when using --path and uses autoclean" do
+ it "installs the bins when using --path and uses autoclean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -441,7 +535,7 @@ The checksum of /versions does not match the checksum provided by the server! So
expect(vendored_gems("bin/rackup")).to exist
end
- it "installs the bins when using --path and uses bundle clean" do
+ it "installs the bins when using --path and uses bundle clean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -458,7 +552,7 @@ The checksum of /versions does not match the checksum provided by the server! So
gem 'rack-obama'
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Post-install message from rack:")
end
@@ -468,7 +562,7 @@ The checksum of /versions does not match the checksum provided by the server! So
gem 'rack_middleware'
G
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Post-install message from rack:")
expect(out).to include("Rack's post install message")
end
@@ -477,7 +571,7 @@ The checksum of /versions does not match the checksum provided by the server! So
let(:user) { "user" }
let(:password) { "pass" }
let(:basic_auth_source_uri) do
- uri = URI.parse(source_uri)
+ uri = Bundler::URI.parse(source_uri)
uri.user = user
uri.password = password
@@ -490,42 +584,32 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle! :install, :artifice => "compact_index_basic_authentication"
+ bundle :install, :artifice => "compact_index_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "strips http basic authentication creds for modern index" do
+ it "passes basic authentication details and strips out creds also in verbose mode" do
gemfile <<-G
source "#{basic_auth_source_uri}"
gem "rack"
G
- bundle! :install, :artifice => "endopint_marshal_fail_basic_authentication"
+ bundle :install, :verbose => true, :artifice => "compact_index_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "strips http basic auth creds when it can't reach the server" do
- gemfile <<-G
- source "#{basic_auth_source_uri}"
- gem "rack"
- G
-
- bundle :install, :artifice => "endpoint_500"
- expect(out).not_to include("#{user}:#{password}")
- end
-
- it "strips http basic auth creds when warning about ambiguous sources" do
+ it "strips http basic auth creds when warning about ambiguous sources", :bundler => "< 3" do
gemfile <<-G
source "#{basic_auth_source_uri}"
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle! :install, :artifice => "compact_index_basic_authentication"
- expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(out).not_to include("#{user}:#{password}")
+ bundle :install, :artifice => "compact_index_basic_authentication"
+ expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -535,7 +619,7 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle! :install, :artifice => "compact_index_creds_diff_host"
+ bundle :install, :artifice => "compact_index_creds_diff_host"
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -548,9 +632,9 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "reads authentication details by host name from bundle config" do
- bundle "config #{source_hostname} #{user}:#{password}"
+ bundle "config set #{source_hostname} #{user}:#{password}"
- bundle! :install, :artifice => "compact_index_strict_basic_authentication"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -558,17 +642,17 @@ The checksum of /versions does not match the checksum provided by the server! So
it "reads authentication details by full url from bundle config" do
# The trailing slash is necessary here; Fetcher canonicalizes the URI.
- bundle "config #{source_uri}/ #{user}:#{password}"
+ bundle "config set #{source_uri}/ #{user}:#{password}"
- bundle! :install, :artifice => "compact_index_strict_basic_authentication"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "should use the API" do
- bundle "config #{source_hostname} #{user}:#{password}"
- bundle! :install, :artifice => "compact_index_strict_basic_authentication"
+ bundle "config set #{source_hostname} #{user}:#{password}"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -579,22 +663,22 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle "config #{source_hostname} otheruser:wrong"
+ bundle "config set #{source_hostname} otheruser:wrong"
- bundle! :install, :artifice => "compact_index_strict_basic_authentication"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "shows instructions if auth is not provided for the source" do
- bundle :install, :artifice => "compact_index_strict_basic_authentication"
- expect(out).to include("bundle config #{source_hostname} username:password")
+ bundle :install, :artifice => "compact_index_strict_basic_authentication", :raise_on_error => false
+ expect(err).to include("bundle config set --global #{source_hostname} username:password")
end
it "fails if authentication has already been provided, but failed" do
- bundle "config #{source_hostname} #{user}:wrong"
+ bundle "config set #{source_hostname} #{user}:wrong"
- bundle :install, :artifice => "compact_index_strict_basic_authentication"
- expect(out).to include("Bad username or password")
+ bundle :install, :artifice => "compact_index_strict_basic_authentication", :raise_on_error => false
+ expect(err).to include("Bad username or password")
end
end
@@ -607,7 +691,7 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle! :install, :artifice => "compact_index_basic_authentication"
+ bundle :install, :artifice => "compact_index_basic_authentication"
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
@@ -632,15 +716,15 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle :install, :env => { "RUBYOPT" => "-I#{bundled_app("broken_ssl")}" }
- expect(out).to include("OpenSSL")
+ bundle :install, :env => { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, :raise_on_error => false
+ expect(err).to include("OpenSSL")
end
end
context "when SSL certificate verification fails" do
it "explains what happened" do
# Install a monkeypatch that reproduces the effects of openssl raising
- # a certificate validation error when Rubygems tries to connect.
+ # a certificate validation error when RubyGems tries to connect.
gemfile <<-G
class Net::HTTP
def start
@@ -652,40 +736,40 @@ The checksum of /versions does not match the checksum provided by the server! So
gem "rack"
G
- bundle :install
- expect(out).to match(/could not verify the SSL certificate/i)
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/could not verify the SSL certificate/i)
end
end
context ".gemrc with sources is present" do
- before do
+ it "uses other sources declared in the Gemfile" do
File.open(home(".gemrc"), "w") do |file|
file.puts({ :sources => ["https://rubygems.org"] }.to_yaml)
end
- end
- after do
- home(".gemrc").rmtree
- end
-
- it "uses other sources declared in the Gemfile" do
- gemfile <<-G
- source "#{source_uri}"
- gem 'rack'
- G
+ begin
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'rack'
+ G
- bundle! :install, :artifice => "compact_index_forbidden"
+ bundle :install, :artifice => "compact_index_forbidden"
+ ensure
+ home(".gemrc").rmtree
+ end
end
end
it "performs partial update with a non-empty range" do
+ skip "HTTP_RANGE not set" if Gem.win_platform?
+
gemfile <<-G
source "#{source_uri}"
gem 'rack', '0.9.1'
G
# Initial install creates the cached versions file
- bundle! :install, :artifice => "compact_index"
+ bundle :install, :artifice => "compact_index"
# Update the Gemfile so we can check subsequent install was successful
gemfile <<-G
@@ -694,7 +778,7 @@ The checksum of /versions does not match the checksum provided by the server! So
G
# Second install should make only a partial request to /versions
- bundle! :install, :artifice => "compact_index_partial_update"
+ bundle :install, :artifice => "compact_index_partial_update"
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -711,56 +795,109 @@ The checksum of /versions does not match the checksum provided by the server! So
FileUtils.mkdir_p(File.dirname(versions))
FileUtils.touch(versions)
- bundle! :install, :artifice => "compact_index_concurrent_download"
+ bundle :install, :artifice => "compact_index_concurrent_download"
expect(File.read(versions)).to start_with("created_at")
expect(the_bundle).to include_gems "rack 1.0.0"
end
+ it "performs full update if server endpoints serve partial content responses but don't have incremental content and provide no Etag" do
+ build_repo4 do
+ build_gem "rack", "0.9.1"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ source "#{source_uri}"
+ gem 'rack', '0.9.1'
+ G
+
+ update_repo4 do
+ build_gem "rack", "1.0.0"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index_partial_update_no_etag_not_incremental", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ source "#{source_uri}"
+ gem 'rack', '1.0.0'
+ G
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "performs full update of compact index info cache if range is not satisfiable" do
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'rack', '0.9.1'
+ G
+
+ rake_info_path = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
+ "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "info", "rack")
+
+ bundle :install, :artifice => "compact_index"
+
+ expected_rack_info_content = File.read(rake_info_path)
+
+ # Modify the cache files. We expect them to be reset to the normal ones when we re-run :install
+ File.open(rake_info_path, "w") {|f| f << (expected_rack_info_content + "this is different") }
+
+ # Update the Gemfile so the next install does its normal things
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'rack', '1.0.0'
+ G
+
+ # The cache files now being longer means the requested range is going to be not satisfiable
+ # Bundler must end up requesting the whole file to fix things up.
+ bundle :install, :artifice => "compact_index_range_not_satisfiable"
+
+ resulting_rack_info_content = File.read(rake_info_path)
+
+ expect(resulting_rack_info_content).to eq(expected_rack_info_content)
+ end
+
it "fails gracefully when the source URI has an invalid scheme" do
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
source "htps://rubygems.org"
gem "rack"
G
- expect(exitstatus).to eq(15) if exitstatus
- expect(out).to end_with(<<-E.strip)
+ expect(exitstatus).to eq(15)
+ expect(err).to end_with(<<-E.strip)
The request uri `htps://index.rubygems.org/versions` has an invalid scheme (`htps`). Did you mean `http` or `https`?
E
end
- describe "checksum validation", :rubygems => ">= 2.3.0" do
+ describe "checksum validation" do
it "raises when the checksum does not match" do
- install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum"
+ install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum", :raise_on_error => false
source "#{source_uri}"
gem "rack"
G
- expect(exitstatus).to eq(19) if exitstatus
- expect(out).
+ expect(exitstatus).to eq(19)
+ expect(err).
to include("Bundler cannot continue installing rack (1.0.0).").
and include("The checksum for the downloaded `rack-1.0.0.gem` does not match the checksum given by the server.").
and include("This means the contents of the downloaded gem is different from what was uploaded to the server, and could be a potential security issue.").
and include("To resolve this issue:").
- and include("1. delete the downloaded gem located at: `#{system_gem_path}/gems/rack-1.0.0/rack-1.0.0.gem`").
+ and include("1. delete the downloaded gem located at: `#{default_bundle_path}/gems/rack-1.0.0/rack-1.0.0.gem`").
and include("2. run `bundle install`").
and include("If you wish to continue installing the downloaded gem, and are certain it does not pose a security issue despite the mismatching checksum, do the following:").
- and include("1. run `bundle config disable_checksum_validation true` to turn off checksum verification").
+ and include("1. run `bundle config set --local disable_checksum_validation true` to turn off checksum verification").
and include("2. run `bundle install`").
and match(/\(More info: The expected SHA256 checksum was "#{"ab" * 22}", but the checksum for the downloaded gem was ".+?"\.\)/)
end
it "raises when the checksum is the wrong length" do
- install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum", :env => { "BUNDLER_SPEC_RACK_CHECKSUM" => "checksum!" }
+ install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum", :env => { "BUNDLER_SPEC_RACK_CHECKSUM" => "checksum!", "DEBUG" => "1" }, :verbose => true, :raise_on_error => false
source "#{source_uri}"
gem "rack"
G
- expect(exitstatus).to eq(5) if exitstatus
- expect(out).to include("The given checksum for rack-1.0.0 (\"checksum!\") is not a valid SHA256 hexdigest nor base64digest")
+ expect(exitstatus).to eq(5)
+ expect(err).to include("The given checksum for rack-1.0.0 (\"checksum!\") is not a valid SHA256 hexdigest nor base64digest")
end
it "does not raise when disable_checksum_validation is set" do
- bundle! "config disable_checksum_validation true"
- install_gemfile! <<-G, :artifice => "compact_index_wrong_gem_checksum"
+ bundle "config set disable_checksum_validation true"
+ install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum"
source "#{source_uri}"
gem "rack"
G
@@ -768,7 +905,7 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "works when cache dir is world-writable" do
- install_gemfile! <<-G, :artifice => "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
File.umask(0000)
source "#{source_uri}"
gem "rack"
@@ -776,11 +913,11 @@ The checksum of /versions does not match the checksum provided by the server! So
end
it "doesn't explode when the API dependencies are wrong" do
- install_gemfile <<-G, :artifice => "compact_index_wrong_dependencies", :env => { "DEBUG" => "true" }
+ install_gemfile <<-G, :artifice => "compact_index_wrong_dependencies", :env => { "DEBUG" => "true" }, :raise_on_error => false
source "#{source_uri}"
gem "rails"
G
- deps = [Gem::Dependency.new("rake", "= 10.0.2"),
+ deps = [Gem::Dependency.new("rake", "= 13.0.1"),
Gem::Dependency.new("actionpack", "= 2.3.2"),
Gem::Dependency.new("activerecord", "= 2.3.2"),
Gem::Dependency.new("actionmailer", "= 2.3.2"),
@@ -792,14 +929,15 @@ Either installing with `--full-index` or running `bundle update rails` should fi
end
it "does not duplicate specs in the lockfile when updating and a dependency is not installed" do
- install_gemfile! <<-G, :artifice => "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "#{file_uri_for(gem_repo1)}"
source "#{source_uri}" do
gem "rails"
gem "activemerchant"
end
G
- gem_command! :uninstall, "activemerchant"
- bundle! "update rails", :artifice => "compact_index"
+ gem_command "uninstall activemerchant"
+ bundle "update rails", :artifice => "compact_index"
expect(lockfile.scan(/activemerchant \(/).size).to eq(1)
end
end
diff --git a/spec/bundler/install/gems/dependency_api_spec.rb b/spec/bundler/install/gems/dependency_api_spec.rb
index d2de0d358b..9738a75474 100644
--- a/spec/bundler/install/gems/dependency_api_spec.rb
+++ b/spec/bundler/install/gems/dependency_api_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "gemcutter's dependency API" do
let(:source_hostname) { "localgemserver.test" }
@@ -22,8 +21,8 @@ RSpec.describe "gemcutter's dependency API" do
gem " sinatra"
G
- bundle :install, :artifice => "endpoint"
- expect(out).to include("' sinatra' is not a valid gem name because it contains whitespace.")
+ bundle :install, :artifice => "endpoint", :raise_on_error => false
+ expect(err).to include("' sinatra' is not a valid gem name because it contains whitespace.")
end
it "should handle nested dependencies" do
@@ -54,14 +53,16 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "net-sftp 1.1.1"
end
- it "should use the endpoint when using --deployment" do
+ it "should use the endpoint when using deployment mode" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
bundle :install, :artifice => "endpoint"
- bundle "install --deployment", :artifice => "endpoint"
+ bundle "config set --local deployment true"
+ bundle "config set --local path vendor/bundle"
+ bundle :install, :artifice => "endpoint"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -74,7 +75,7 @@ RSpec.describe "gemcutter's dependency API" do
gemfile <<-G
source "#{source_uri}"
- git "file:///#{lib_path("foo-1.0")}" do
+ git "#{file_uri_for(lib_path("foo-1.0"))}" do
gem 'foo'
end
G
@@ -84,7 +85,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems("rails 2.3.2")
end
- it "handles git dependencies that are in rubygems using --deployment" do
+ it "handles git dependencies that are in rubygems using deployment mode" do
build_git "foo" do |s|
s.executables = "foobar"
s.add_dependency "rails", "2.3.2"
@@ -92,39 +93,48 @@ RSpec.describe "gemcutter's dependency API" do
gemfile <<-G
source "#{source_uri}"
- gem 'foo', :git => "file:///#{lib_path("foo-1.0")}"
+ gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
bundle :install, :artifice => "endpoint"
- bundle "install --deployment", :artifice => "endpoint"
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "endpoint"
expect(the_bundle).to include_gems("rails 2.3.2")
end
- it "doesn't fail if you only have a git gem with no deps when using --deployment" do
+ it "doesn't fail if you only have a git gem with no deps when using deployment mode" do
build_git "foo"
gemfile <<-G
source "#{source_uri}"
- gem 'foo', :git => "file:///#{lib_path("foo-1.0")}"
+ gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
bundle "install", :artifice => "endpoint"
- bundle "install --deployment", :artifice => "endpoint"
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "endpoint"
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems("foo 1.0")
end
it "falls back when the API errors out" do
simulate_platform mswin
+ build_repo2 do
+ # The rcov gem is platform mswin32, but has no arch
+ build_gem "rcov" do |s|
+ s.platform = Gem::Platform.new([nil, "mswin32", nil])
+ s.write "lib/rcov.rb", "RCOV = '1.0.0'"
+ end
+ end
+
gemfile <<-G
source "#{source_uri}"
gem "rcov"
G
- bundle :install, :artifice => "windows"
+ bundle :install, :artifice => "windows", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rcov 1.0.0"
end
@@ -217,8 +227,8 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, :artifice => "endpoint_redirect"
- expect(out).to match(/Too many redirects/)
+ bundle :install, :artifice => "endpoint_redirect", :raise_on_error => false
+ expect(err).to match(/Too many redirects/)
end
context "when --full-index is specified" do
@@ -239,13 +249,13 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle "update --full-index", :artifice => "endpoint"
+ bundle "update --full-index", :artifice => "endpoint", :all => true
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
- it "fetches again when more dependencies are found in subsequent sources" do
+ it "fetches again when more dependencies are found in subsequent sources", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -260,7 +270,26 @@ RSpec.describe "gemcutter's dependency API" do
G
bundle :install, :artifice => "endpoint_extra"
- expect(the_bundle).to include_gems "back_deps 1.0"
+ expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
+ end
+
+ it "fetches again when more dependencies are found in subsequent sources using blocks" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
+ G
+
+ bundle :install, :artifice => "endpoint_extra"
+ expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
end
it "fetches gem versions even when those gems are already installed" do
@@ -285,7 +314,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "rack 1.2"
end
- it "considers all possible versions of dependencies from all api gem sources" do
+ it "considers all possible versions of dependencies from all api gem sources", :bundler => "< 3" do
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
@@ -319,37 +348,57 @@ RSpec.describe "gemcutter's dependency API" do
gemfile <<-G
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
G
bundle :install, :artifice => "endpoint_extra"
- expect(out).to include("Fetching gem metadata from http://localgemserver.test/..")
+ expect(out).to include("Fetching gem metadata from http://localgemserver.test/.")
expect(out).to include("Fetching source index from http://localgemserver.test/extra")
end
- it "does not fetch every spec if the index of gems is large when doing back deps" do
+ it "does not fetch every spec if the index of gems is large when doing back deps", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
end
build_gem "missing"
- # need to hit the limit
- 1.upto(Bundler::Source::Rubygems::API_REQUEST_LIMIT) do |i|
- build_gem "gem#{i}"
- end
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end
- gemfile <<-G
+ api_request_limit = low_api_request_limit_for(gem_repo2)
+
+ install_gemfile <<-G, :artifice => "endpoint_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
source "#{source_uri}"
source "#{source_uri}/extra"
gem "back_deps"
G
- bundle :install, :artifice => "endpoint_extra_missing"
+ expect(the_bundle).to include_gems "back_deps 1.0"
+ end
+
+ it "does not fetch every spec if the index of gems is large when doing back deps using blocks" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ build_gem "missing"
+
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ api_request_limit = low_api_request_limit_for(gem_repo2)
+
+ install_gemfile <<-G, :artifice => "endpoint_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
+ source "#{source_uri}"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
+ G
+
expect(the_bundle).to include_gems "back_deps 1.0"
end
@@ -364,7 +413,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "foo 1.0"
end
- it "fetches again when more dependencies are found in subsequent sources using --deployment" do
+ it "fetches again when more dependencies are found in subsequent sources using deployment mode", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -379,19 +428,46 @@ RSpec.describe "gemcutter's dependency API" do
G
bundle :install, :artifice => "endpoint_extra"
+ bundle "config set --local deployment true"
+ bundle :install, :artifice => "endpoint_extra"
+ expect(the_bundle).to include_gems "back_deps 1.0"
+ end
- bundle "install --deployment", :artifice => "endpoint_extra"
+ it "fetches again when more dependencies are found in subsequent sources using deployment mode with blocks" do
+ build_repo2 do
+ build_gem "back_deps" do |s|
+ s.add_dependency "foo"
+ end
+ FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
+ end
+
+ gemfile <<-G
+ source "#{source_uri}"
+ source "#{source_uri}/extra" do
+ gem "back_deps"
+ end
+ G
+
+ bundle :install, :artifice => "endpoint_extra"
+ bundle "config set --local deployment true"
+ bundle "install", :artifice => "endpoint_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end
it "does not refetch if the only unmet dependency is bundler" do
+ build_repo2 do
+ build_gem "bundler_dep" do |s|
+ s.add_dependency "bundler"
+ end
+ end
+
gemfile <<-G
source "#{source_uri}"
gem "bundler_dep"
G
- bundle :install, :artifice => "endpoint"
+ bundle :install, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Fetching gem metadata from #{source_uri}")
end
@@ -407,7 +483,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "rails 2.3.2"
end
- it "installs the binstubs" do
+ it "installs the binstubs", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -419,7 +495,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(out).to eq("1.0.0")
end
- it "installs the bins when using --path and uses autoclean" do
+ it "installs the bins when using --path and uses autoclean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -430,7 +506,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(vendored_gems("bin/rackup")).to exist
end
- it "installs the bins when using --path and uses bundle clean" do
+ it "installs the bins when using --path and uses bundle clean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -466,7 +542,7 @@ RSpec.describe "gemcutter's dependency API" do
let(:user) { "user" }
let(:password) { "pass" }
let(:basic_auth_source_uri) do
- uri = URI.parse(source_uri)
+ uri = Bundler::URI.parse(source_uri)
uri.user = user
uri.password = password
@@ -484,13 +560,24 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
+ it "passes basic authentication details and strips out creds also in verbose mode" do
+ gemfile <<-G
+ source "#{basic_auth_source_uri}"
+ gem "rack"
+ G
+
+ bundle :install, :verbose => true, :artifice => "endpoint_basic_authentication"
+ expect(out).not_to include("#{user}:#{password}")
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
it "strips http basic authentication creds for modern index" do
gemfile <<-G
source "#{basic_auth_source_uri}"
gem "rack"
G
- bundle :install, :artifice => "endopint_marshal_fail_basic_authentication"
+ bundle :install, :artifice => "endpoint_marshal_fail_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -501,20 +588,20 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, :artifice => "endpoint_500"
+ bundle :install, :artifice => "endpoint_500", :raise_on_error => false
expect(out).not_to include("#{user}:#{password}")
end
- it "strips http basic auth creds when warning about ambiguous sources" do
+ it "strips http basic auth creds when warning about ambiguous sources", :bundler => "< 3" do
gemfile <<-G
source "#{basic_auth_source_uri}"
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle :install, :artifice => "endpoint_basic_authentication"
- expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(out).not_to include("#{user}:#{password}")
+ expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -528,6 +615,22 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
+ describe "with host including dashes" do
+ before do
+ gemfile <<-G
+ source "http://local-gemserver.test"
+ gem "rack"
+ G
+ end
+
+ it "reads authentication details from a valid ENV variable" do
+ bundle :install, :artifice => "endpoint_strict_basic_authentication", :env => { "BUNDLE_LOCAL___GEMSERVER__TEST" => "#{user}:#{password}" }
+
+ expect(out).to include("Fetching gem metadata from http://local-gemserver.test")
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+ end
+
describe "with authentication details in bundle config" do
before do
gemfile <<-G
@@ -537,7 +640,7 @@ RSpec.describe "gemcutter's dependency API" do
end
it "reads authentication details by host name from bundle config" do
- bundle "config #{source_hostname} #{user}:#{password}"
+ bundle "config set #{source_hostname} #{user}:#{password}"
bundle :install, :artifice => "endpoint_strict_basic_authentication"
@@ -547,7 +650,7 @@ RSpec.describe "gemcutter's dependency API" do
it "reads authentication details by full url from bundle config" do
# The trailing slash is necessary here; Fetcher canonicalizes the URI.
- bundle "config #{source_uri}/ #{user}:#{password}"
+ bundle "config set #{source_uri}/ #{user}:#{password}"
bundle :install, :artifice => "endpoint_strict_basic_authentication"
@@ -556,7 +659,7 @@ RSpec.describe "gemcutter's dependency API" do
end
it "should use the API" do
- bundle "config #{source_hostname} #{user}:#{password}"
+ bundle "config set #{source_hostname} #{user}:#{password}"
bundle :install, :artifice => "endpoint_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -568,22 +671,22 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle "config #{source_hostname} otheruser:wrong"
+ bundle "config set #{source_hostname} otheruser:wrong"
bundle :install, :artifice => "endpoint_strict_basic_authentication"
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "shows instructions if auth is not provided for the source" do
- bundle :install, :artifice => "endpoint_strict_basic_authentication"
- expect(out).to include("bundle config #{source_hostname} username:password")
+ bundle :install, :artifice => "endpoint_strict_basic_authentication", :raise_on_error => false
+ expect(err).to include("bundle config set --global #{source_hostname} username:password")
end
it "fails if authentication has already been provided, but failed" do
- bundle "config #{source_hostname} #{user}:wrong"
+ bundle "config set #{source_hostname} #{user}:wrong"
- bundle :install, :artifice => "endpoint_strict_basic_authentication"
- expect(out).to include("Bad username or password")
+ bundle :install, :artifice => "endpoint_strict_basic_authentication", :raise_on_error => false
+ expect(err).to include("Bad username or password")
end
end
@@ -621,15 +724,15 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, :env => { "RUBYOPT" => "-I#{bundled_app("broken_ssl")}" }
- expect(out).to include("OpenSSL")
+ bundle :install, :env => { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, :raise_on_error => false
+ expect(err).to include("OpenSSL")
end
end
context "when SSL certificate verification fails" do
it "explains what happened" do
# Install a monkeypatch that reproduces the effects of openssl raising
- # a certificate validation error when Rubygems tries to connect.
+ # a certificate validation error when RubyGems tries to connect.
gemfile <<-G
class Net::HTTP
def start
@@ -641,31 +744,27 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install
- expect(out).to match(/could not verify the SSL certificate/i)
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/could not verify the SSL certificate/i)
end
end
context ".gemrc with sources is present" do
- before do
+ it "uses other sources declared in the Gemfile" do
File.open(home(".gemrc"), "w") do |file|
file.puts({ :sources => ["https://rubygems.org"] }.to_yaml)
end
- end
-
- after do
- home(".gemrc").rmtree
- end
- it "uses other sources declared in the Gemfile" do
- gemfile <<-G
- source "#{source_uri}"
- gem 'rack'
- G
-
- bundle "install", :artifice => "endpoint_marshal_fail"
+ begin
+ gemfile <<-G
+ source "#{source_uri}"
+ gem 'rack'
+ G
- expect(exitstatus).to eq(0) if exitstatus
+ bundle "install", :artifice => "endpoint_marshal_fail"
+ ensure
+ home(".gemrc").rmtree
+ end
end
end
end
diff --git a/spec/bundler/install/gems/env_spec.rb b/spec/bundler/install/gems/env_spec.rb
index 9b1d8e5424..a6dfadcfc8 100644
--- a/spec/bundler/install/gems/env_spec.rb
+++ b/spec/bundler/install/gems/env_spec.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with ENV conditionals" do
describe "when just setting an ENV key as a string" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
env "BUNDLER_TEST" do
gem "rack"
@@ -28,7 +27,7 @@ RSpec.describe "bundle install with ENV conditionals" do
describe "when just setting an ENV key as a symbol" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
env :BUNDLER_TEST do
gem "rack"
@@ -51,7 +50,7 @@ RSpec.describe "bundle install with ENV conditionals" do
describe "when setting a string to match the env" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
env "BUNDLER_TEST" => "foo" do
gem "rack"
@@ -80,7 +79,7 @@ RSpec.describe "bundle install with ENV conditionals" do
describe "when setting a regex to match the env" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
env "BUNDLER_TEST" => /foo/ do
gem "rack"
diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb
index 2c2d3c16a1..f9b374cf01 100644
--- a/spec/bundler/install/gems/flex_spec.rb
+++ b/spec/bundler/install/gems/flex_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle flex_install" do
it "installs the gems as expected" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
@@ -14,7 +13,7 @@ RSpec.describe "bundle flex_install" do
it "installs even when the lockfile is invalid" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
@@ -22,7 +21,7 @@ RSpec.describe "bundle flex_install" do
expect(the_bundle).to be_locked
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack', '1.0'
G
@@ -35,7 +34,7 @@ RSpec.describe "bundle flex_install" do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack-obama"
G
@@ -43,7 +42,7 @@ RSpec.describe "bundle flex_install" do
update_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack-obama", "1.0"
G
@@ -55,14 +54,14 @@ RSpec.describe "bundle flex_install" do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack'
G
update_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack'
gem 'activesupport', '2.3.5'
G
@@ -74,14 +73,14 @@ RSpec.describe "bundle flex_install" do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack-obama"
G
update_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack-obama"
gem "thin"
G
@@ -94,7 +93,7 @@ RSpec.describe "bundle flex_install" do
it "removes gems without changing the versions of remaining gems" do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack'
gem 'activesupport', '2.3.5'
G
@@ -102,7 +101,7 @@ RSpec.describe "bundle flex_install" do
update_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack'
G
@@ -110,7 +109,7 @@ RSpec.describe "bundle flex_install" do
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack'
gem 'activesupport', '2.3.2'
G
@@ -121,7 +120,7 @@ RSpec.describe "bundle flex_install" do
it "removes top level dependencies when removed from the Gemfile while leaving other dependencies intact" do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack'
gem 'activesupport', '2.3.5'
G
@@ -129,7 +128,7 @@ RSpec.describe "bundle flex_install" do
update_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack'
G
@@ -139,7 +138,7 @@ RSpec.describe "bundle flex_install" do
it "removes child dependencies" do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'rack-obama'
gem 'activesupport'
G
@@ -148,7 +147,7 @@ RSpec.describe "bundle flex_install" do
update_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem 'activesupport'
G
@@ -161,14 +160,13 @@ RSpec.describe "bundle flex_install" do
before(:each) do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack_middleware"
G
expect(the_bundle).to include_gems "rack_middleware 1.0", "rack 0.9.1"
- build_repo2
- update_repo2 do
+ build_repo2 do
build_gem "rack-obama", "2.0" do |s|
s.add_dependency "rack", "=1.2"
end
@@ -178,24 +176,24 @@ RSpec.describe "bundle flex_install" do
end
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack-obama", "2.0"
gem "rack_middleware"
G
end
it "does not install gems whose dependencies are not met" do
- bundle :install
- ruby <<-RUBY
+ bundle :install, :raise_on_error => false
+ ruby <<-RUBY, :raise_on_error => false
require 'bundler/setup'
RUBY
expect(err).to match(/could not find gem 'rack-obama/i)
end
it "suggests bundle update when the Gemfile requires different versions than the lock" do
+ bundle "config set force_ruby_platform true"
+
nice_error = <<-E.strip.gsub(/^ {8}/, "")
- Fetching source index from file:#{gem_repo2}/
- Resolving dependencies...
Bundler could not find compatible versions for gem "rack":
In snapshot (Gemfile.lock):
rack (= 0.9.1)
@@ -211,34 +209,47 @@ RSpec.describe "bundle flex_install" do
the gems in your Gemfile, which may resolve the conflict.
E
- bundle :install, :retry => 0
- expect(out).to eq(nice_error)
+ bundle :install, :retry => 0, :raise_on_error => false
+ expect(err).to end_with(nice_error)
end
end
describe "subtler cases" do
before :each do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rack-obama"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
gem "rack-obama"
G
end
- it "does something" do
- expect do
- bundle "install"
- end.not_to change { File.read(bundled_app("Gemfile.lock")) }
+ it "should work when you install" do
+ bundle "install"
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rack (0.9.1)
+ rack-obama (1.0)
+ rack
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack (= 0.9.1)
+ rack-obama
- expect(out).to include("rack = 0.9.1")
- expect(out).to include("locked at 1.0.0")
- expect(out).to include("bundle update rack")
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
it "should work when you update" do
@@ -250,30 +261,35 @@ RSpec.describe "bundle flex_install" do
it "updates the lockfile" do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo2)}" do
+ end
gem "rack"
G
- lockfile_should_be <<-L
- GEM
- remote: file:#{gem_repo1}/
- remote: file:#{gem_repo2}/
- specs:
- rack (1.0.0)
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rack (1.0.0)
- PLATFORMS
- ruby
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
- DEPENDENCIES
- rack
+ PLATFORMS
+ #{lockfile_platforms}
- BUNDLED WITH
- #{Bundler::VERSION}
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
L
end
end
@@ -301,19 +317,19 @@ RSpec.describe "bundle flex_install" do
it "prints the correct error message" do
# install Rails 3.0.0.rc
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0.0.rc4"
gem "capybara", "0.3.9"
G
# upgrade Rails to 3.0.0 and then install again
- install_gemfile <<-G
- source "file://#{gem_repo2}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0.0"
gem "capybara", "0.3.9"
G
- expect(out).to include("Gemfile.lock")
+ expect(err).to include("Gemfile.lock")
end
end
end
diff --git a/spec/bundler/install/gems/fund_spec.rb b/spec/bundler/install/gems/fund_spec.rb
new file mode 100644
index 0000000000..f521b0296f
--- /dev/null
+++ b/spec/bundler/install/gems/fund_spec.rb
@@ -0,0 +1,137 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle install" do
+ context "with gem sources" do
+ before do
+ build_repo2 do
+ build_gem "has_funding_and_other_metadata" do |s|
+ s.metadata = {
+ "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
+ "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
+ "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
+ "homepage_uri" => "https://bestgemever.example.io",
+ "mailing_list_uri" => "https://groups.example.com/bestgemever",
+ "funding_uri" => "https://example.com/has_funding_and_other_metadata/funding",
+ "source_code_uri" => "https://example.com/user/bestgemever",
+ "wiki_uri" => "https://example.com/user/bestgemever/wiki",
+ }
+ end
+
+ build_gem "has_funding", "1.2.3" do |s|
+ s.metadata = {
+ "funding_uri" => "https://example.com/has_funding/funding",
+ }
+ end
+
+ build_gem "gem_with_dependent_funding", "1.0" do |s|
+ s.add_dependency "has_funding"
+ end
+ end
+ end
+
+ context "when gems include a fund URI" do
+ it "displays the plural fund message after installing" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'has_funding_and_other_metadata'
+ gem 'has_funding'
+ gem 'rack-obama'
+ G
+
+ expect(out).to include("2 installed gems you directly depend on are looking for funding.")
+ end
+
+ it "displays the singular fund message after installing" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'has_funding'
+ gem 'rack-obama'
+ G
+
+ expect(out).to include("1 installed gem you directly depend on is looking for funding.")
+ end
+ end
+
+ context "when gems do not include fund messages" do
+ it "does not display any fund messages" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ G
+
+ expect(out).not_to include("gem you depend on")
+ end
+ end
+
+ context "when a dependency includes a fund message" do
+ it "does not display the fund message" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'gem_with_dependent_funding'
+ G
+
+ expect(out).not_to include("gem you depend on")
+ end
+ end
+ end
+
+ context "with git sources" do
+ context "when gems include fund URI" do
+ it "displays the fund message after installing" do
+ build_git "also_has_funding" do |s|
+ s.metadata = {
+ "funding_uri" => "https://example.com/also_has_funding/funding",
+ }
+ end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}'
+ G
+
+ expect(out).to include("1 installed gem you directly depend on is looking for funding.")
+ end
+
+ it "displays the fund message if repo is updated" do
+ build_git "also_has_funding" do |s|
+ s.metadata = {
+ "funding_uri" => "https://example.com/also_has_funding/funding",
+ }
+ end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}'
+ G
+
+ build_git "also_has_funding", "1.1" do |s|
+ s.metadata = {
+ "funding_uri" => "https://example.com/also_has_funding/funding",
+ }
+ end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.1")}'
+ G
+
+ expect(out).to include("1 installed gem you directly depend on is looking for funding.")
+ end
+
+ it "displays the fund message if repo is not updated" do
+ build_git "also_has_funding" do |s|
+ s.metadata = {
+ "funding_uri" => "https://example.com/also_has_funding/funding",
+ }
+ end
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}'
+ G
+
+ bundle :install
+ expect(out).to include("1 installed gem you directly depend on is looking for funding.")
+
+ bundle :install
+ expect(out).to include("1 installed gem you directly depend on is looking for funding.")
+ end
+ end
+ end
+end
diff --git a/spec/bundler/install/gems/mirror_spec.rb b/spec/bundler/install/gems/mirror_spec.rb
index 798156fb12..9611973701 100644
--- a/spec/bundler/install/gems/mirror_spec.rb
+++ b/spec/bundler/install/gems/mirror_spec.rb
@@ -1,20 +1,19 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with a mirror configured" do
describe "when the mirror does not match the gem source" do
before :each do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "config --local mirror.http://gems.example.org http://gem-mirror.example.org"
+ bundle "config set --local mirror.http://gems.example.org http://gem-mirror.example.org"
end
it "installs from the normal location" do
bundle :install
- expect(out).to include("Fetching source index from file:#{gem_repo1}")
+ expect(out).to include("Fetching source index from #{file_uri_for(gem_repo1)}")
expect(the_bundle).to include_gems "rack 1.0"
end
end
@@ -23,17 +22,17 @@ RSpec.describe "bundle install with a mirror configured" do
before :each do
gemfile <<-G
# This source is bogus and doesn't have the gem we're looking for
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- bundle "config --local mirror.file://#{gem_repo2} file://#{gem_repo1}"
+ bundle "config set --local mirror.#{file_uri_for(gem_repo2)} #{file_uri_for(gem_repo1)}"
end
it "installs the gem from the mirror" do
bundle :install
- expect(out).to include("Fetching source index from file:#{gem_repo1}")
- expect(out).not_to include("Fetching source index from file:#{gem_repo2}")
+ expect(out).to include("Fetching source index from #{file_uri_for(gem_repo1)}")
+ expect(out).not_to include("Fetching source index from #{file_uri_for(gem_repo2)}")
expect(the_bundle).to include_gems "rack 1.0"
end
end
diff --git a/spec/bundler/install/gems/native_extensions_spec.rb b/spec/bundler/install/gems/native_extensions_spec.rb
index dcf67e976e..d5cafcfc2c 100644
--- a/spec/bundler/install/gems/native_extensions_spec.rb
+++ b/spec/bundler/install/gems/native_extensions_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "installing a gem with native extensions", :ruby_repo do
it "installs" do
@@ -34,14 +33,13 @@ RSpec.describe "installing a gem with native extensions", :ruby_repo do
end
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "c_extension"
G
- bundle "config build.c_extension --with-c_extension=hello"
+ bundle "config set build.c_extension --with-c_extension=hello"
bundle "install"
- expect(out).not_to include("extconf.rb failed")
expect(out).to include("Installing c_extension 1.0 with native extensions")
run "Bundler.require; puts CExtension.new.its_true"
@@ -77,16 +75,110 @@ RSpec.describe "installing a gem with native extensions", :ruby_repo do
C
end
- bundle! "config build.c_extension --with-c_extension=hello"
+ bundle "config set build.c_extension --with-c_extension=hello"
- install_gemfile! <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "c_extension", :git => #{lib_path("c_extension-1.0").to_s.dump}
G
- expect(out).not_to include("extconf.rb failed")
- expect(out).to include("Using c_extension 1.0")
+ expect(err).to_not include("warning: conflicting chdir during another chdir block")
- run! "Bundler.require; puts CExtension.new.its_true"
+ run "Bundler.require; puts CExtension.new.its_true"
+ expect(out).to eq("true")
+ end
+
+ it "installs correctly from git when multiple gems with extensions share one repository" do
+ build_repo2 do
+ ["one", "two"].each do |n|
+ build_lib "c_extension_#{n}", "1.0", :path => lib_path("gems/c_extension_#{n}") do |s|
+ s.extensions = ["ext/extconf.rb"]
+ s.write "ext/extconf.rb", <<-E
+ require "mkmf"
+ name = "c_extension_bundle_#{n}"
+ dir_config(name)
+ raise "OMG" unless with_config("c_extension_#{n}") == "#{n}"
+ create_makefile(name)
+ E
+
+ s.write "ext/c_extension_#{n}.c", <<-C
+ #include "ruby.h"
+
+ VALUE c_extension_#{n}_value(VALUE self) {
+ return rb_str_new_cstr("#{n}");
+ }
+
+ void Init_c_extension_bundle_#{n}() {
+ VALUE c_Extension = rb_define_class("CExtension_#{n}", rb_cObject);
+ rb_define_method(c_Extension, "value", c_extension_#{n}_value, 0);
+ }
+ C
+
+ s.write "lib/c_extension_#{n}.rb", <<-C
+ require "c_extension_bundle_#{n}"
+ C
+ end
+ end
+ build_git "gems", :path => lib_path("gems"), :gemspec => false
+ end
+
+ bundle "config set build.c_extension_one --with-c_extension_one=one"
+ bundle "config set build.c_extension_two --with-c_extension_two=two"
+
+ # 1st time, require only one gem -- only one of the extensions gets built.
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "c_extension_one", :git => #{lib_path("gems").to_s.dump}
+ G
+
+ # 2nd time, require both gems -- we need both extensions to be built now.
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "c_extension_one", :git => #{lib_path("gems").to_s.dump}
+ gem "c_extension_two", :git => #{lib_path("gems").to_s.dump}
+ G
+
+ run "Bundler.require; puts CExtension_one.new.value; puts CExtension_two.new.value"
+ expect(out).to eq("one\ntwo")
+ end
+
+ it "install with multiple build flags" do
+ build_git "c_extension" do |s|
+ s.extensions = ["ext/extconf.rb"]
+ s.write "ext/extconf.rb", <<-E
+ require "mkmf"
+ name = "c_extension_bundle"
+ dir_config(name)
+ raise "OMG" unless with_config("c_extension") == "hello" && with_config("c_extension_bundle-dir") == "hola"
+ create_makefile(name)
+ E
+
+ s.write "ext/c_extension.c", <<-C
+ #include "ruby.h"
+
+ VALUE c_extension_true(VALUE self) {
+ return Qtrue;
+ }
+
+ void Init_c_extension_bundle() {
+ VALUE c_Extension = rb_define_class("CExtension", rb_cObject);
+ rb_define_method(c_Extension, "its_true", c_extension_true, 0);
+ }
+ C
+
+ s.write "lib/c_extension.rb", <<-C
+ require "c_extension_bundle"
+ C
+ end
+
+ bundle "config set build.c_extension --with-c_extension=hello --with-c_extension_bundle-dir=hola"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "c_extension", :git => #{lib_path("c_extension-1.0").to_s.dump}
+ G
+
+ run "Bundler.require; puts CExtension.new.its_true"
expect(out).to eq("true")
end
end
diff --git a/spec/bundler/install/gems/post_install_spec.rb b/spec/bundler/install/gems/post_install_spec.rb
index c3ea3e7c51..7426f54877 100644
--- a/spec/bundler/install/gems/post_install_spec.rb
+++ b/spec/bundler/install/gems/post_install_spec.rb
@@ -1,12 +1,11 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
context "with gem sources" do
context "when gems include post install messages" do
it "should display the post-install messages after installing" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
gem 'thin'
gem 'rack-obama'
@@ -25,7 +24,7 @@ RSpec.describe "bundle install" do
context "when gems do not include post install messages" do
it "should not display any post-install messages" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
G
@@ -34,10 +33,10 @@ RSpec.describe "bundle install" do
end
end
- context "when a dependecy includes a post install message" do
+ context "when a dependency includes a post install message" do
it "should display the post install message" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack_middleware'
G
@@ -55,7 +54,7 @@ RSpec.describe "bundle install" do
s.post_install_message = "Foo's post install message"
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => '#{lib_path("foo-1.0")}'
G
@@ -69,7 +68,7 @@ RSpec.describe "bundle install" do
s.post_install_message = "Foo's post install message"
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => '#{lib_path("foo-1.0")}'
G
bundle :install
@@ -78,7 +77,7 @@ RSpec.describe "bundle install" do
s.post_install_message = "Foo's 1.1 post install message"
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => '#{lib_path("foo-1.1")}'
G
bundle :install
@@ -92,7 +91,7 @@ RSpec.describe "bundle install" do
s.post_install_message = "Foo's post install message"
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => '#{lib_path("foo-1.0")}'
G
@@ -111,7 +110,7 @@ RSpec.describe "bundle install" do
s.post_install_message = nil
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => '#{lib_path("foo-1.0")}'
G
@@ -124,11 +123,11 @@ RSpec.describe "bundle install" do
context "when ignore post-install messages for gem is set" do
it "doesn't display any post-install messages" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "config ignore_messages.rack true"
+ bundle "config set ignore_messages.rack true"
bundle :install
expect(out).not_to include("Post-install message")
@@ -138,11 +137,11 @@ RSpec.describe "bundle install" do
context "when ignore post-install messages for all gems" do
it "doesn't display any post-install messages" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "config ignore_messages true"
+ bundle "config set ignore_messages true"
bundle :install
expect(out).not_to include("Post-install message")
diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb
index 7a341fd14f..94fac0052c 100644
--- a/spec/bundler/install/gems/resolving_spec.rb
+++ b/spec/bundler/install/gems/resolving_spec.rb
@@ -1,10 +1,72 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with install-time dependencies" do
- it "installs gems with implicit rake dependencies", :ruby_repo do
+ before do
+ build_repo2 do
+ build_gem "with_implicit_rake_dep" do |s|
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
+ f.puts "IMPLICIT_RAKE_DEP = 'YES'"
+ end
+ end
+ RUBY
+ end
+
+ build_gem "another_implicit_rake_dep" do |s|
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
+ f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
+ end
+ end
+ RUBY
+ end
+
+ # Test complicated gem dependencies for install
+ build_gem "net_a" do |s|
+ s.add_dependency "net_b"
+ s.add_dependency "net_build_extensions"
+ end
+
+ build_gem "net_b"
+
+ build_gem "net_build_extensions" do |s|
+ s.add_dependency "rake"
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/net_build_extensions.rb", "w") do |f|
+ f.puts "NET_BUILD_EXTENSIONS = 'YES'"
+ end
+ end
+ RUBY
+ end
+
+ build_gem "net_c" do |s|
+ s.add_dependency "net_a"
+ s.add_dependency "net_d"
+ end
+
+ build_gem "net_d"
+
+ build_gem "net_e" do |s|
+ s.add_dependency "net_d"
+ end
+ end
+ end
+
+ it "installs gems with implicit rake dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "with_implicit_rake_dep"
gem "another_implicit_rake_dep"
gem "rake"
@@ -19,11 +81,32 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to eq("YES\nYES")
end
+ it "installs gems with implicit rake dependencies without rake previously installed" do
+ with_path_as("") do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "with_implicit_rake_dep"
+ gem "another_implicit_rake_dep"
+ gem "rake"
+ G
+ end
+
+ run <<-R
+ require 'implicit_rake_dep'
+ require 'another_implicit_rake_dep'
+ puts IMPLICIT_RAKE_DEP
+ puts ANOTHER_IMPLICIT_RAKE_DEP
+ R
+ expect(out).to eq("YES\nYES")
+ end
+
it "installs gems with a dependency with no type" do
+ skip "incorrect data check error" if Gem.win_platform?
+
build_repo2
path = "#{gem_repo2}/#{Gem::MARSHAL_SPEC_DIR}/actionpack-2.3.2.gemspec.rz"
- spec = Marshal.load(Gem.inflate(File.read(path)))
+ spec = Marshal.load(Bundler.rubygems.inflate(File.binread(path)))
spec.dependencies.each do |d|
d.instance_variable_set(:@type, :fail)
end
@@ -32,7 +115,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "actionpack", "2.3.2"
G
@@ -42,25 +125,25 @@ RSpec.describe "bundle install with install-time dependencies" do
describe "with crazy rubygem plugin stuff" do
it "installs plugins" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "net_b"
G
expect(the_bundle).to include_gems "net_b 1.0"
end
- it "installs plugins depended on by other plugins", :ruby_repo do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ it "installs plugins depended on by other plugins" do
+ install_gemfile <<-G, :env => { "DEBUG" => "1" }
+ source "#{file_uri_for(gem_repo2)}"
gem "net_a"
G
expect(the_bundle).to include_gems "net_a 1.0", "net_b 1.0"
end
- it "installs multiple levels of dependencies", :ruby_repo do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ it "installs multiple levels of dependencies" do
+ install_gemfile <<-G, :env => { "DEBUG" => "1" }
+ source "#{file_uri_for(gem_repo2)}"
gem "net_c"
gem "net_e"
G
@@ -68,32 +151,54 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(the_bundle).to include_gems "net_a 1.0", "net_b 1.0", "net_c 1.0", "net_d 1.0", "net_e 1.0"
end
+ context "with ENV['BUNDLER_DEBUG_RESOLVER'] set" do
+ it "produces debug output" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "net_c"
+ gem "net_e"
+ G
+
+ bundle :install, :env => { "BUNDLER_DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
+
+ expect(out).to include("BUNDLER: Starting resolution")
+ end
+ end
+
context "with ENV['DEBUG_RESOLVER'] set" do
it "produces debug output" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "net_c"
gem "net_e"
G
- bundle :install, :env => { "DEBUG_RESOLVER" => "1" }
+ bundle :install, :env => { "DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
- expect(err).to include("Creating possibility state for net_c")
+ expect(out).to include("BUNDLER: Starting resolution")
end
end
context "with ENV['DEBUG_RESOLVER_TREE'] set" do
it "produces debug output" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "net_c"
gem "net_e"
G
- bundle :install, :env => { "DEBUG_RESOLVER_TREE" => "1" }
+ bundle :install, :env => { "DEBUG_RESOLVER_TREE" => "1", "DEBUG" => "1" }
+
+ activated_groups = if local_platforms.any?
+ "net_b (1.0) (ruby), net_b (1.0) (#{local_platforms.join(", ")})"
+ else
+ "net_b (1.0) (ruby)"
+ end
- expect(err).to include(" net_b")
- expect(err).to include(" net_build_extensions (1.0)")
+ expect(out).to include(" net_b").
+ and include("BUNDLER: Starting resolution").
+ and include("BUNDLER: Finished resolution").
+ and include("Attempting to activate [#{activated_groups}]")
end
end
end
@@ -102,12 +207,16 @@ RSpec.describe "bundle install with install-time dependencies" do
context "allows only an older version" do
it "installs the older version" do
build_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
build_gem "rack", "9001.0.0" do |s|
s.required_ruby_version = "> 9000"
end
end
- install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2 }
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
ruby "#{RUBY_VERSION}"
source "http://localgemserver.test/"
gem 'rack'
@@ -116,6 +225,51 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to_not include("rack-9001.0.0 requires ruby version > 9000")
expect(the_bundle).to include_gems("rack 1.2")
end
+
+ it "installs the older version under rate limiting conditions" do
+ build_repo4 do
+ build_gem "rack", "9001.0.0" do |s|
+ s.required_ruby_version = "> 9000"
+ end
+ build_gem "rack", "1.2"
+ build_gem "foo1", "1.0"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index_rate_limited", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ ruby "#{RUBY_VERSION}"
+ source "http://localgemserver.test/"
+ gem 'rack'
+ gem 'foo1'
+ G
+
+ expect(out).to_not include("rack-9001.0.0 requires ruby version > 9000")
+ expect(the_bundle).to include_gems("rack 1.2")
+ end
+
+ it "installs the older not platform specific version" do
+ build_repo4 do
+ build_gem "rack", "9001.0.0" do |s|
+ s.required_ruby_version = "> 9000"
+ end
+ build_gem "rack", "1.2" do |s|
+ s.platform = mingw
+ s.required_ruby_version = "> 9000"
+ end
+ build_gem "rack", "1.2"
+ end
+
+ simulate_platform mingw do
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ ruby "#{RUBY_VERSION}"
+ source "http://localgemserver.test/"
+ gem 'rack'
+ G
+ end
+
+ expect(out).to_not include("rack-9001.0.0 requires ruby version > 9000")
+ expect(out).to_not include("rack-1.2-#{Bundler.local_platform} requires ruby version > 9000")
+ expect(the_bundle).to include_gems("rack 1.2")
+ end
end
context "allows no gems" do
@@ -132,7 +286,9 @@ RSpec.describe "bundle install with install-time dependencies" do
shared_examples_for "ruby version conflicts" do
it "raises an error during resolution" do
- install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2 }
+ skip "ruby requirement includes platform and it shouldn't" if Gem.win_platform?
+
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false
source "http://localgemserver.test/"
ruby #{ruby_requirement}
gem 'require_ruby'
@@ -141,19 +297,16 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to_not include("Gem::InstallError: require_ruby requires Ruby version > 9000")
nice_error = strip_whitespace(<<-E).strip
- Fetching gem metadata from http://localgemserver.test/.
- Fetching version metadata from http://localgemserver.test/
- Resolving dependencies...
- Bundler could not find compatible versions for gem "ruby\0":
+ Bundler found conflicting requirements for the Ruby\0 version:
In Gemfile:
- ruby\0 (#{error_message_requirement})
+ Ruby\0 (#{error_message_requirement})
require_ruby was resolved to 1.0, which depends on
- ruby\0 (> 9000)
+ Ruby\0 (> 9000)
- Could not find gem 'ruby\0 (> 9000)', which is required by gem 'require_ruby', in any of the sources.
+ Ruby\0 (> 9000), which is required by gem 'require_ruby', is not available in the local ruby installation
E
- expect(out).to eq(nice_error)
+ expect(err).to end_with(nice_error)
end
end
@@ -167,8 +320,9 @@ RSpec.describe "bundle install with install-time dependencies" do
end
describe "with a compound requirement" do
- let(:ruby_requirement) { %("< 5000", "> 0.1") }
- let(:error_message_requirement) { "< 5000, > 0.1" }
+ let(:reqs) { ["> 0.1", "< 5000"] }
+ let(:ruby_requirement) { reqs.map(&:dump).join(", ") }
+ let(:error_message_requirement) { Gem::Requirement.new(reqs).to_s }
it_behaves_like "ruby version conflicts"
end
@@ -183,13 +337,13 @@ RSpec.describe "bundle install with install-time dependencies" do
end
end
- install_gemfile <<-G
- source "file://#{gem_repo2}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gem 'require_rubygems'
G
- expect(out).to_not include("Gem::InstallError: require_rubygems requires RubyGems version > 9000")
- expect(out).to include("require_rubygems-1.0 requires rubygems version > 9000, which is incompatible with the current version, #{Gem::VERSION}")
+ expect(err).to_not include("Gem::InstallError: require_rubygems requires RubyGems version > 9000")
+ expect(err).to include("require_rubygems-1.0 requires rubygems version > 9000, which is incompatible with the current version, #{Gem::VERSION}")
end
end
end
diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb
index 9a79a05b32..db16a1b0e1 100644
--- a/spec/bundler/install/gems/standalone_spec.rb
+++ b/spec/bundler/install/gems/standalone_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.shared_examples "bundle install --standalone" do
shared_examples "common functionality" do
@@ -8,6 +7,12 @@ RSpec.shared_examples "bundle install --standalone" do
expect(the_bundle).to include_gems(*args)
end
+ it "still makes system gems unavailable to normal bundler" do
+ system_gems "rack-1.0.0"
+
+ expect(the_bundle).to_not include_gems("rack")
+ end
+
it "generates a bundle/bundler/setup.rb" do
expect(bundled_app("bundle/bundler/setup.rb")).to exist
end
@@ -22,15 +27,51 @@ RSpec.shared_examples "bundle install --standalone" do
testrb << "\nrequire \"#{k}\""
testrb << "\nputs #{k.upcase}"
end
- Dir.chdir(bundled_app) do
- ruby testrb, :no_lib => true
+ ruby testrb
+
+ expect(out).to eq(expected_gems.values.join("\n"))
+ end
+
+ it "makes the gems available without bundler via Kernel.require" do
+ testrb = String.new <<-RUBY
+ $:.unshift File.expand_path("bundle")
+ require "bundler/setup"
+
+ RUBY
+ expected_gems.each do |k, _|
+ testrb << "\nKernel.require \"#{k}\""
+ testrb << "\nputs #{k.upcase}"
end
+ ruby testrb
expect(out).to eq(expected_gems.values.join("\n"))
end
+ it "makes system gems unavailable without bundler" do
+ system_gems "rack-1.0.0"
+
+ testrb = String.new <<-RUBY
+ $:.unshift File.expand_path("bundle")
+ require "bundler/setup"
+
+ begin
+ require "rack"
+ rescue LoadError
+ puts "LoadError"
+ end
+ RUBY
+ ruby testrb
+
+ expect(out).to eq("LoadError")
+ end
+
it "works on a different system" do
- FileUtils.mv(bundled_app, "#{bundled_app}2")
+ begin
+ FileUtils.mv(bundled_app, "#{bundled_app}2")
+ rescue Errno::ENOTEMPTY
+ puts "Couldn't rename test app since the target folder has these files: #{Dir.glob("#{bundled_app}2/*")}"
+ raise
+ end
testrb = String.new <<-RUBY
$:.unshift File.expand_path("bundle")
@@ -41,9 +82,7 @@ RSpec.shared_examples "bundle install --standalone" do
testrb << "\nrequire \"#{k}\""
testrb << "\nputs #{k.upcase}"
end
- Dir.chdir("#{bundled_app}2") do
- ruby testrb, :no_lib => true
- end
+ ruby testrb, :dir => "#{bundled_app}2"
expect(out).to eq(expected_gems.values.join("\n"))
end
@@ -51,10 +90,12 @@ RSpec.shared_examples "bundle install --standalone" do
describe "with simple gems" do
before do
- install_gemfile <<-G, :standalone => true
- source "file://#{gem_repo1}"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => true, :dir => cwd
end
let(:expected_gems) do
@@ -67,18 +108,89 @@ RSpec.shared_examples "bundle install --standalone" do
include_examples "common functionality"
end
+ describe "with default gems and a lockfile", :ruby_repo do
+ before do
+ skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
+ skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
+
+ realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0"
+
+ necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"]
+ necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a")
+ realworld_system_gems(*necessary_system_gems, :path => scoped_gem_path(bundled_app("bundle")))
+
+ build_gem "foo", "1.0.0", :to_system => true, :default => true do |s|
+ s.add_dependency "bar"
+ end
+
+ build_gem "bar", "1.0.0", :to_system => true, :default => true
+
+ build_repo4 do
+ build_gem "foo", "1.0.0" do |s|
+ s.add_dependency "bar"
+ end
+
+ build_gem "bar", "1.0.0"
+ end
+
+ gemfile <<-G
+ source "https://gem.repo4"
+ gem "foo"
+ G
+
+ bundle "lock", :dir => cwd, :artifice => "compact_index"
+ end
+
+ it "works" do
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => true, :dir => cwd, :artifice => "compact_index", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
+ end
+ end
+
+ describe "with Gemfiles using path sources and resulting bundle moved to a folder hierarchy with different nesting" do
+ before do
+ build_lib "minitest", "1.0.0", :path => lib_path("minitest")
+
+ Dir.mkdir bundled_app("app")
+
+ gemfile bundled_app("app/Gemfile"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "minitest", :path => "#{lib_path("minitest")}"
+ G
+
+ bundle "install", :standalone => true, :dir => bundled_app("app")
+
+ Dir.mkdir tmp("one_more_level")
+ FileUtils.mv bundled_app, tmp("one_more_level")
+ end
+
+ it "also works" do
+ ruby <<-RUBY, :dir => tmp("one_more_level/bundled_app/app")
+ require "./bundle/bundler/setup"
+
+ require "minitest"
+ puts MINITEST
+ RUBY
+
+ expect(out).to eq("1.0.0")
+ expect(err).to be_empty
+ end
+ end
+
describe "with gems with native extension", :ruby_repo do
before do
- install_gemfile <<-G, :standalone => true
- source "file://#{gem_repo1}"
+ bundle "config set --local path #{bundled_app("bundle")}"
+ install_gemfile <<-G, :standalone => true, :dir => cwd
+ source "#{file_uri_for(gem_repo1)}"
gem "very_simple_binary"
G
end
- it "generates a bundle/bundler/setup.rb with the proper paths", :rubygems => "2.4" do
- extension_line = File.read(bundled_app("bundle/bundler/setup.rb")).each_line.find {|line| line.include? "/extensions/" }.strip
- expect(extension_line).to start_with '$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/'
- expect(extension_line).to end_with '/very_simple_binary-1.0"'
+ it "generates a bundle/bundler/setup.rb with the proper paths" do
+ expected_path = bundled_app("bundle/bundler/setup.rb")
+ extension_line = File.read(expected_path).each_line.find {|line| line.include? "/extensions/" }.strip
+ expect(extension_line).to start_with '$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}/extensions/'
+ expect(extension_line).to end_with '/very_simple_binary-1.0")'
end
end
@@ -101,14 +213,16 @@ RSpec.shared_examples "bundle install --standalone" do
end
G
end
- install_gemfile <<-G, :standalone => true
+ bundle "config set --local path #{bundled_app("bundle")}"
+ install_gemfile <<-G, :standalone => true, :dir => cwd, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "bar", :git => "#{lib_path("bar-1.0")}"
G
end
it "outputs a helpful error message" do
- expect(out).to include("You have one or more invalid gemspecs that need to be fixed.")
- expect(out).to include("bar 1.0 has an invalid gemspec")
+ expect(err).to include("You have one or more invalid gemspecs that need to be fixed.")
+ expect(err).to include("bar 1.0 has an invalid gemspec")
end
end
@@ -116,11 +230,13 @@ RSpec.shared_examples "bundle install --standalone" do
before do
build_git "devise", "1.0"
- install_gemfile <<-G, :standalone => true
- source "file://#{gem_repo1}"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
gem "devise", :git => "#{lib_path("devise-1.0")}"
G
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => true, :dir => cwd
end
let(:expected_gems) do
@@ -138,8 +254,8 @@ RSpec.shared_examples "bundle install --standalone" do
before do
build_git "devise", "1.0"
- install_gemfile <<-G, :standalone => true
- source "file://#{gem_repo1}"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
group :test do
@@ -147,6 +263,8 @@ RSpec.shared_examples "bundle install --standalone" do
gem "rack-test"
end
G
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => true, :dir => cwd
end
let(:expected_gems) do
@@ -159,71 +277,69 @@ RSpec.shared_examples "bundle install --standalone" do
include_examples "common functionality"
it "allows creating a standalone file with limited groups" do
- bundle "install --standalone default"
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => "default", :dir => cwd
- Dir.chdir(bundled_app) do
- load_error_ruby <<-RUBY, "spec", :no_lib => true
- $:.unshift File.expand_path("bundle")
- require "bundler/setup"
+ load_error_ruby <<-RUBY, "spec"
+ $:.unshift File.expand_path("bundle")
+ require "bundler/setup"
- require "actionpack"
- puts ACTIONPACK
- require "spec"
- RUBY
- end
+ require "actionpack"
+ puts ACTIONPACK
+ require "spec"
+ RUBY
expect(out).to eq("2.3.2")
expect(err).to eq("ZOMG LOAD ERROR")
end
- it "allows --without to limit the groups used in a standalone" do
- bundle "install --standalone --without test"
+ it "allows `without` configuration to limit the groups used in a standalone" do
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle "config set --local without test"
+ bundle :install, :standalone => true, :dir => cwd
- Dir.chdir(bundled_app) do
- load_error_ruby <<-RUBY, "spec", :no_lib => true
- $:.unshift File.expand_path("bundle")
- require "bundler/setup"
+ load_error_ruby <<-RUBY, "spec"
+ $:.unshift File.expand_path("bundle")
+ require "bundler/setup"
- require "actionpack"
- puts ACTIONPACK
- require "spec"
- RUBY
- end
+ require "actionpack"
+ puts ACTIONPACK
+ require "spec"
+ RUBY
expect(out).to eq("2.3.2")
expect(err).to eq("ZOMG LOAD ERROR")
end
- it "allows --path to change the location of the standalone bundle" do
- bundle "install --standalone --path path/to/bundle"
+ it "allows `path` configuration to change the location of the standalone bundle" do
+ bundle "config set --local path path/to/bundle"
+ bundle "install", :standalone => true, :dir => cwd
- Dir.chdir(bundled_app) do
- ruby <<-RUBY, :no_lib => true
- $:.unshift File.expand_path("path/to/bundle")
- require "bundler/setup"
+ ruby <<-RUBY
+ $:.unshift File.expand_path("path/to/bundle")
+ require "bundler/setup"
- require "actionpack"
- puts ACTIONPACK
- RUBY
- end
+ require "actionpack"
+ puts ACTIONPACK
+ RUBY
expect(out).to eq("2.3.2")
end
- it "allows remembered --without to limit the groups used in a standalone" do
- bundle "install --without test"
- bundle "install --standalone"
+ it "allows `without` to limit the groups used in a standalone" do
+ bundle "config set --local without test"
+ bundle :install, :dir => cwd
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => true, :dir => cwd
- Dir.chdir(bundled_app) do
- load_error_ruby <<-RUBY, "spec", :no_lib => true
- $:.unshift File.expand_path("bundle")
- require "bundler/setup"
+ load_error_ruby <<-RUBY, "spec"
+ $:.unshift File.expand_path("bundle")
+ require "bundler/setup"
- require "actionpack"
- puts ACTIONPACK
- require "spec"
- RUBY
- end
+ require "actionpack"
+ puts ACTIONPACK
+ require "spec"
+ RUBY
expect(out).to eq("2.3.2")
expect(err).to eq("ZOMG LOAD ERROR")
@@ -239,7 +355,8 @@ RSpec.shared_examples "bundle install --standalone" do
source "#{source_uri}"
gem "rails"
G
- bundle "install --standalone", :artifice => "endpoint"
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => true, :artifice => "endpoint", :dir => cwd
end
let(:expected_gems) do
@@ -253,12 +370,14 @@ RSpec.shared_examples "bundle install --standalone" do
end
end
- describe "with --binstubs" do
+ describe "with --binstubs", :bundler => "< 3" do
before do
- install_gemfile <<-G, :standalone => true, :binstubs => true
- source "file://#{gem_repo1}"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
+ bundle "config set --local path #{bundled_app("bundle")}"
+ bundle :install, :standalone => true, :binstubs => true, :dir => cwd
end
let(:expected_gems) do
@@ -271,28 +390,24 @@ RSpec.shared_examples "bundle install --standalone" do
include_examples "common functionality"
it "creates stubs that use the standalone load path" do
- Dir.chdir(bundled_app) do
- expect(`bin/rails -v`.chomp).to eql "2.3.2"
- end
+ expect(sys_exec("bin/rails -v").chomp).to eql "2.3.2"
end
it "creates stubs that can be executed from anywhere" do
require "tmpdir"
- Dir.chdir(Dir.tmpdir) do
- sys_exec!(%(#{bundled_app("bin/rails")} -v))
- expect(out).to eq("2.3.2")
- end
+ sys_exec(%(#{bundled_app("bin/rails")} -v), :dir => Dir.tmpdir)
+ expect(out).to eq("2.3.2")
end
it "creates stubs that can be symlinked" do
- pending "File.symlink is unsupported on Windows" if Bundler::WINDOWS
+ skip "symlinks unsupported" if Gem.win_platform?
symlink_dir = tmp("symlink")
FileUtils.mkdir_p(symlink_dir)
symlink = File.join(symlink_dir, "rails")
File.symlink(bundled_app("bin/rails"), symlink)
- sys_exec!("#{symlink} -v")
+ sys_exec("#{symlink} -v")
expect(out).to eq("2.3.2")
end
@@ -304,15 +419,13 @@ RSpec.shared_examples "bundle install --standalone" do
end
RSpec.describe "bundle install --standalone" do
+ let(:cwd) { bundled_app }
+
include_examples("bundle install --standalone")
end
RSpec.describe "bundle install --standalone run in a subdirectory" do
- before do
- subdir = bundled_app("bob")
- FileUtils.mkdir_p(subdir)
- Dir.chdir(subdir)
- end
+ let(:cwd) { bundled_app("bob").tap(&:mkpath) }
include_examples("bundle install --standalone")
end
diff --git a/spec/bundler/install/gems/sudo_spec.rb b/spec/bundler/install/gems/sudo_spec.rb
index 13abffc14e..3e5d38ea4c 100644
--- a/spec/bundler/install/gems/sudo_spec.rb
+++ b/spec/bundler/install/gems/sudo_spec.rb
@@ -1,18 +1,25 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "when using sudo", :sudo => true do
describe "and BUNDLE_PATH is writable" do
context "but BUNDLE_PATH/build_info is not writable" do
+ let(:subdir) do
+ system_gem_path("cache")
+ end
+
before do
- subdir = system_gem_path("cache")
+ bundle "config set path.system true"
subdir.mkpath
sudo "chmod u-w #{subdir}"
end
+ after do
+ sudo "chmod u+w #{subdir}"
+ end
+
it "installs" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -25,12 +32,13 @@ RSpec.describe "when using sudo", :sudo => true do
describe "and GEM_HOME is owned by root" do
before :each do
+ bundle "config set path.system true"
chown_system_gems_to_root
end
it "installs" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
gem "thin"
G
@@ -41,8 +49,23 @@ RSpec.describe "when using sudo", :sudo => true do
end
it "installs rake and a gem dependent on rake in the same session" do
+ build_repo2 do
+ build_gem "another_implicit_rake_dep" do |s|
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
+ f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
+ end
+ end
+ RUBY
+ end
+ end
+
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rake"
gem "another_implicit_rake_dep"
G
@@ -57,12 +80,12 @@ RSpec.describe "when using sudo", :sudo => true do
ENV["BUNDLE_PATH"] = bundle_path.to_s
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
- expect(bundle_path.join("gems/rack-1.0.0")).to exist
- expect(bundle_path.join("gems/rack-1.0.0").stat.uid).to eq(0)
+ expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0")).to exist
+ expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0").stat.uid).to eq(0)
expect(the_bundle).to include_gems "rack 1.0"
end
@@ -74,18 +97,18 @@ RSpec.describe "when using sudo", :sudo => true do
ENV["BUNDLE_PATH"] = bundle_path.to_s
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
- expect(bundle_path.join("gems/rack-1.0.0")).to exist
- expect(bundle_path.join("gems/rack-1.0.0").stat.uid).to eq(0)
+ expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0")).to exist
+ expect(bundle_path.join(Bundler.ruby_scope, "gems/rack-1.0.0").stat.uid).to eq(0)
expect(the_bundle).to include_gems "rack 1.0"
end
- it "installs extensions/ compiled by Rubygems 2.2", :rubygems => "2.2" do
+ it "installs extensions/" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "very_simple_binary"
G
@@ -97,16 +120,21 @@ RSpec.describe "when using sudo", :sudo => true do
describe "and BUNDLE_PATH is not writable" do
before do
- sudo "chmod ugo-w #{default_bundle_path}"
+ bundle "config set --local path .bundle"
+ sudo "chmod ugo-w .bundle"
+ end
+
+ after do
+ sudo "chmod ugo+w .bundle"
end
it "installs" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
- expect(default_bundle_path("gems/rack-1.0.0")).to exist
+ expect(local_gem_path("gems/rack-1.0.0")).to exist
expect(the_bundle).to include_gems "rack 1.0"
end
@@ -117,7 +145,7 @@ RSpec.describe "when using sudo", :sudo => true do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
tmpdirs = Dir.glob("#{Dir.tmpdir}/bundler*")
@@ -128,18 +156,23 @@ RSpec.describe "when using sudo", :sudo => true do
describe "and GEM_HOME is not writable" do
it "installs" do
+ bundle "config set path.system true"
gem_home = tmp("sudo_gem_home")
sudo "mkdir -p #{gem_home}"
sudo "chmod ugo-w #{gem_home}"
+ system_gems :bundler, :path => gem_home
+
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", '1.0'
G
bundle :install, :env => { "GEM_HOME" => gem_home.to_s, "GEM_PATH" => nil }
expect(gem_home.join("bin/rackup")).to exist
expect(the_bundle).to include_gems "rack 1.0", :env => { "GEM_HOME" => gem_home.to_s, "GEM_PATH" => nil }
+
+ sudo "rm -rf #{tmp("sudo_gem_home")}"
end
end
@@ -147,32 +180,25 @@ RSpec.describe "when using sudo", :sudo => true do
let(:warning) { "Don't run Bundler as root." }
before do
- gemfile %(source "file://#{gem_repo1}")
+ gemfile %(source "#{file_uri_for(gem_repo1)}")
end
it "warns against that" do
- bundle :install, :sudo => true
- expect(out).to include(warning)
+ bundle :install, :sudo => :preserve_env
+ expect(err).to include(warning)
end
context "when ENV['BUNDLE_SILENCE_ROOT_WARNING'] is set" do
it "skips the warning" do
- bundle :install, :sudo => :preserve_env, :env => { "BUNDLE_SILENCE_ROOT_WARNING" => true }
- expect(out).to_not include(warning)
- end
- end
-
- context "when silence_root_warning is passed as an option" do
- it "skips the warning" do
- bundle :install, :sudo => true, :silence_root_warning => true
- expect(out).to_not include(warning)
+ bundle :install, :sudo => :preserve_env, :env => { "BUNDLE_SILENCE_ROOT_WARNING" => "true" }
+ expect(err).to_not include(warning)
end
end
context "when silence_root_warning = false" do
it "warns against that" do
- bundle :install, :sudo => true, :silence_root_warning => false
- expect(out).to include(warning)
+ bundle :install, :sudo => :preserve_env, :env => { "BUNDLE_SILENCE_ROOT_WARNING" => "false" }
+ expect(err).to include(warning)
end
end
end
diff --git a/spec/bundler/install/gems/win32_spec.rb b/spec/bundler/install/gems/win32_spec.rb
index cdad9a8821..419b14ff0f 100644
--- a/spec/bundler/install/gems/win32_spec.rb
+++ b/spec/bundler/install/gems/win32_spec.rb
@@ -1,11 +1,10 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install with win32-generated lockfile" do
it "should read lockfile" do
- File.open(bundled_app("Gemfile.lock"), "wb") do |f|
+ File.open(bundled_app_lock, "wb") do |f|
f << "GEM\r\n"
- f << " remote: file:#{gem_repo1}/\r\n"
+ f << " remote: #{file_uri_for(gem_repo1)}/\r\n"
f << " specs:\r\n"
f << "\r\n"
f << " rack (1.0.0)\r\n"
@@ -18,10 +17,9 @@ RSpec.describe "bundle install with win32-generated lockfile" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- expect(exitstatus).to eq(0) if exitstatus
end
end
diff --git a/spec/bundler/install/gemspecs_spec.rb b/spec/bundler/install/gemspecs_spec.rb
index 97eaf149c1..3684d8749d 100644
--- a/spec/bundler/install/gemspecs_spec.rb
+++ b/spec/bundler/install/gemspecs_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
describe "when a gem has a YAML gemspec" do
@@ -11,20 +10,21 @@ RSpec.describe "bundle install" do
it "still installs correctly" do
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "yaml_spec"
G
bundle :install
- expect(err).to lack_errors
+ expect(err).to be_empty
end
it "still installs correctly when using path" do
build_lib "yaml_spec", :gemspec => :yaml
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'yaml_spec', :path => "#{lib_path("yaml_spec-1.0")}"
G
- expect(err).to lack_errors
+ expect(err).to be_empty
end
end
@@ -34,8 +34,10 @@ RSpec.describe "bundle install" do
gem 'rack'
G
- FileUtils.mkdir_p "#{tmp}/gems/system/specifications"
- File.open("#{tmp}/gems/system/specifications/rack-1.0.0.gemspec", "w+") do |f|
+ system_gems "rack-1.0.0", :path => default_bundle_path
+
+ FileUtils.mkdir_p "#{default_bundle_path}/specifications"
+ File.open("#{default_bundle_path}/specifications/rack-1.0.0.gemspec", "w+") do |f|
spec = Gem::Specification.new do |s|
s.name = "rack"
s.version = "1.0.0"
@@ -44,7 +46,51 @@ RSpec.describe "bundle install" do
f.write spec.to_ruby
end
bundle :install, :artifice => "endpoint_marshal_fail" # force gemspec load
- expect(the_bundle).to include_gems "activesupport 2.3.2"
+ expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.2"
+ end
+
+ it "does not hang when gemspec has incompatible encoding" do
+ create_file("foo.gemspec", <<-G)
+ Gem::Specification.new do |gem|
+ gem.name = "pry-byebug"
+ gem.version = "3.4.2"
+ gem.author = "David Rodríguez"
+ gem.summary = "Good stuff"
+ end
+ G
+
+ install_gemfile <<-G, :env => { "LANG" => "C" }
+ source "#{file_uri_for(gem_repo1)}"
+ gemspec
+ G
+
+ expect(out).to include("Bundle complete!")
+ end
+
+ it "reads gemspecs respecting their encoding" do
+ create_file "version.rb", <<-RUBY
+ module Persistent💎
+ VERSION = "0.0.1"
+ end
+ RUBY
+
+ create_file "persistent-dmnd.gemspec", <<-G
+ require_relative "version"
+
+ Gem::Specification.new do |gem|
+ gem.name = "persistent-dmnd"
+ gem.version = Persistent💎::VERSION
+ gem.author = "Ivo Anjo"
+ gem.summary = "Unscratchable stuff"
+ end
+ G
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gemspec
+ G
+
+ expect(out).to include("Bundle complete!")
end
context "when ruby version is specified in gemspec and gemfile" do
@@ -55,6 +101,7 @@ RSpec.describe "bundle install" do
install_gemfile <<-G
ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby'
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
expect(the_bundle).to include_gems "foo 1.0"
@@ -66,8 +113,9 @@ RSpec.describe "bundle install" do
s.required_ruby_version = "#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby', :patchlevel => '#{RUBY_PATCHLEVEL}'
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
expect(the_bundle).to include_gems "foo 1.0"
@@ -80,14 +128,15 @@ RSpec.describe "bundle install" do
s.required_ruby_version = "#{RUBY_VERSION}.#{patchlevel}"
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby', :patchlevel => '#{patchlevel}'
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
- expect(out).to include("Ruby patchlevel")
- expect(out).to include("but your Gemfile specified")
- expect(exitstatus).to eq(18) if exitstatus
+ expect(err).to include("Ruby patchlevel")
+ expect(err).to include("but your Gemfile specified")
+ expect(exitstatus).to eq(18)
end
it "fails and complains about version on version mismatch" do
@@ -97,14 +146,15 @@ RSpec.describe "bundle install" do
s.required_ruby_version = version
end
- install_gemfile <<-G
+ install_gemfile <<-G, :raise_on_error => false
ruby '#{version}', :engine_version => '#{version}', :engine => 'ruby'
+ source "#{file_uri_for(gem_repo1)}"
gemspec
G
- expect(out).to include("Ruby version")
- expect(out).to include("but your Gemfile specified")
- expect(exitstatus).to eq(18) if exitstatus
+ expect(err).to include("Ruby version")
+ expect(err).to include("but your Gemfile specified")
+ expect(exitstatus).to eq(18)
end
end
end
diff --git a/spec/bundler/install/git_spec.rb b/spec/bundler/install/git_spec.rb
index 04f2380b45..d43aacee7e 100644
--- a/spec/bundler/install/git_spec.rb
+++ b/spec/bundler/install/git_spec.rb
@@ -1,52 +1,67 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
context "git sources" do
it "displays the revision hash of the gem repository" do
build_git "foo", "1.0", :path => lib_path("foo")
- install_gemfile <<-G
- gem "foo", :git => "#{lib_path("foo")}"
+ install_gemfile <<-G, :verbose => true
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo"))}"
G
- bundle :install
- expect(out).to include("Using foo 1.0 from #{lib_path("foo")} (at master@#{revision_for(lib_path("foo"))[0..6]})")
+ expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at master@#{revision_for(lib_path("foo"))[0..6]})")
+ expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
+ end
+
+ it "displays the correct default branch", :git => ">= 2.28.0" do
+ build_git "foo", "1.0", :path => lib_path("foo"), :default_branch => "main"
+
+ install_gemfile <<-G, :verbose => true
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo"))}"
+ G
+
+ expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{revision_for(lib_path("foo"))[0..6]})")
expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
end
it "displays the ref of the gem repository when using branch~num as a ref" do
+ skip "maybe branch~num notation doesn't work on Windows' git" if Gem.win_platform?
+
build_git "foo", "1.0", :path => lib_path("foo")
rev = revision_for(lib_path("foo"))[0..6]
update_git "foo", "2.0", :path => lib_path("foo"), :gemspec => true
rev2 = revision_for(lib_path("foo"))[0..6]
update_git "foo", "3.0", :path => lib_path("foo"), :gemspec => true
- install_gemfile! <<-G
- gem "foo", :git => "#{lib_path("foo")}", :ref => "master~2"
+ install_gemfile <<-G, :verbose => true
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo"))}", :ref => "master~2"
G
- bundle! :install
- expect(out).to include("Using foo 1.0 from #{lib_path("foo")} (at master~2@#{rev})")
+ expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at master~2@#{rev})")
expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
update_git "foo", "4.0", :path => lib_path("foo"), :gemspec => true
- bundle! :update
- expect(out).to include("Using foo 2.0 (was 1.0) from #{lib_path("foo")} (at master~2@#{rev2})")
+ bundle :update, :all => true, :verbose => true
+ expect(out).to include("Using foo 2.0 (was 1.0) from #{file_uri_for(lib_path("foo"))} (at master~2@#{rev2})")
expect(the_bundle).to include_gems "foo 2.0", :source => "git@#{lib_path("foo")}"
end
- it "should check out git repos that are missing but not being installed" do
- build_git "foo"
+ it "should allows git repos that are missing but not being installed" do
+ revision = build_git("foo").ref_for("HEAD")
gemfile <<-G
- gem "foo", :git => "file://#{lib_path("foo-1.0")}", :group => :development
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :group => :development
G
lockfile <<-L
GIT
- remote: file://#{lib_path("foo-1.0")}
+ remote: #{file_uri_for(lib_path("foo-1.0"))}
+ revision: #{revision}
specs:
foo (1.0)
@@ -57,10 +72,31 @@ RSpec.describe "bundle install" do
foo!
L
- bundle "install --path=vendor/bundle --without development"
+ bundle "config set --local path vendor/bundle"
+ bundle "config set --local without development"
+ bundle :install
expect(out).to include("Bundle complete!")
- expect(vendored_gems("bundler/gems/foo-1.0-#{revision_for(lib_path("foo-1.0"))[0..11]}")).to be_directory
+ end
+
+ it "allows multiple gems from the same git source" do
+ build_repo2 do
+ build_lib "foo", "1.0", :path => lib_path("gems/foo")
+ build_lib "zebra", "2.0", :path => lib_path("gems/zebra")
+ build_git "gems", :path => lib_path("gems"), :gemspec => false
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("gems"))}", :glob => "foo/*.gemspec"
+ gem "zebra", :git => "#{file_uri_for(lib_path("gems"))}", :glob => "zebra/*.gemspec"
+ G
+
+ bundle "info foo"
+ expect(out).to include("* foo (1.0 #{revision_for(lib_path("gems"))[0..6]})")
+
+ bundle "info zebra"
+ expect(out).to include("* zebra (2.0 #{revision_for(lib_path("gems"))[0..6]})")
end
end
end
diff --git a/spec/bundler/install/global_cache_spec.rb b/spec/bundler/install/global_cache_spec.rb
new file mode 100644
index 0000000000..afa0ff76c1
--- /dev/null
+++ b/spec/bundler/install/global_cache_spec.rb
@@ -0,0 +1,254 @@
+# frozen_string_literal: true
+
+RSpec.describe "global gem caching" do
+ before { bundle "config set global_gem_cache true" }
+
+ describe "using the cross-application user cache" do
+ let(:source) { "http://localgemserver.test" }
+ let(:source2) { "http://gemserver.example.org" }
+
+ def source_global_cache(*segments)
+ home(".bundle", "cache", "gems", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", *segments)
+ end
+
+ def source2_global_cache(*segments)
+ home(".bundle", "cache", "gems", "gemserver.example.org.80.1ae1663619ffe0a3c9d97712f44c705b", *segments)
+ end
+
+ it "caches gems into the global cache on download" do
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "#{source}"
+ gem "rack"
+ G
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ end
+
+ it "uses globally cached gems if they exist" do
+ source_global_cache.mkpath
+ FileUtils.cp(gem_repo1("gems/rack-1.0.0.gem"), source_global_cache("rack-1.0.0.gem"))
+
+ install_gemfile <<-G, :artifice => "compact_index_no_gem"
+ source "#{source}"
+ gem "rack"
+ G
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "shows a proper error message if a cached gem is corrupted" do
+ source_global_cache.mkpath
+ FileUtils.touch(source_global_cache("rack-1.0.0.gem"))
+
+ install_gemfile <<-G, :artifice => "compact_index_no_gem", :raise_on_error => false
+ source "#{source}"
+ gem "rack"
+ G
+
+ expect(err).to include("Gem::Package::FormatError: package metadata is missing in #{source_global_cache("rack-1.0.0.gem")}")
+ end
+
+ describe "when the same gem from different sources is installed" do
+ it "should use the appropriate one from the global cache" do
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "#{source}"
+ gem "rack"
+ G
+
+ simulate_new_machine
+ expect(the_bundle).not_to include_gems "rack 1.0.0"
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ # rack 1.0.0 is not installed and it is in the global cache
+
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "#{source2}"
+ gem "rack", "0.9.1"
+ G
+
+ simulate_new_machine
+ expect(the_bundle).not_to include_gems "rack 0.9.1"
+ expect(source2_global_cache("rack-0.9.1.gem")).to exist
+ # rack 0.9.1 is not installed and it is in the global cache
+
+ gemfile <<-G
+ source "#{source}"
+ gem "rack", "1.0.0"
+ G
+
+ bundle :install, :artifice => "compact_index_no_gem"
+ # rack 1.0.0 is installed and rack 0.9.1 is not
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ expect(the_bundle).not_to include_gems "rack 0.9.1"
+ simulate_new_machine
+
+ gemfile <<-G
+ source "#{source2}"
+ gem "rack", "0.9.1"
+ G
+
+ bundle :install, :artifice => "compact_index_no_gem"
+ # rack 0.9.1 is installed and rack 1.0.0 is not
+ expect(the_bundle).to include_gems "rack 0.9.1"
+ expect(the_bundle).not_to include_gems "rack 1.0.0"
+ end
+
+ it "should not install if the wrong source is provided" do
+ gemfile <<-G
+ source "#{source}"
+ gem "rack"
+ G
+
+ bundle :install, :artifice => "compact_index"
+ simulate_new_machine
+ expect(the_bundle).not_to include_gems "rack 1.0.0"
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ # rack 1.0.0 is not installed and it is in the global cache
+
+ gemfile <<-G
+ source "#{source2}"
+ gem "rack", "0.9.1"
+ G
+
+ bundle :install, :artifice => "compact_index"
+ simulate_new_machine
+ expect(the_bundle).not_to include_gems "rack 0.9.1"
+ expect(source2_global_cache("rack-0.9.1.gem")).to exist
+ # rack 0.9.1 is not installed and it is in the global cache
+
+ gemfile <<-G
+ source "#{source2}"
+ gem "rack", "1.0.0"
+ G
+
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ expect(source2_global_cache("rack-0.9.1.gem")).to exist
+ bundle :install, :artifice => "compact_index_no_gem", :raise_on_error => false
+ expect(err).to include("Internal Server Error 500")
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+
+ # rack 1.0.0 is not installed and rack 0.9.1 is not
+ expect(the_bundle).not_to include_gems "rack 1.0.0"
+ expect(the_bundle).not_to include_gems "rack 0.9.1"
+
+ gemfile <<-G
+ source "#{source}"
+ gem "rack", "0.9.1"
+ G
+
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ expect(source2_global_cache("rack-0.9.1.gem")).to exist
+ bundle :install, :artifice => "compact_index_no_gem", :raise_on_error => false
+ expect(err).to include("Internal Server Error 500")
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+
+ # rack 0.9.1 is not installed and rack 1.0.0 is not
+ expect(the_bundle).not_to include_gems "rack 0.9.1"
+ expect(the_bundle).not_to include_gems "rack 1.0.0"
+ end
+ end
+
+ describe "when installing gems from a different directory" do
+ it "uses the global cache as a source" do
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "#{source}"
+ gem "rack"
+ gem "activesupport"
+ G
+
+ # Both gems are installed and in the global cache
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ expect(the_bundle).to include_gems "activesupport 2.3.5"
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ expect(source_global_cache("activesupport-2.3.5.gem")).to exist
+ simulate_new_machine
+ # Both gems are now only in the global cache
+ expect(the_bundle).not_to include_gems "rack 1.0.0"
+ expect(the_bundle).not_to include_gems "activesupport 2.3.5"
+
+ install_gemfile <<-G, :artifice => "compact_index_no_gem"
+ source "#{source}"
+ gem "rack"
+ G
+
+ # rack is installed and both are in the global cache
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ expect(the_bundle).not_to include_gems "activesupport 2.3.5"
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ expect(source_global_cache("activesupport-2.3.5.gem")).to exist
+
+ create_file bundled_app2("gems.rb"), <<-G
+ source "#{source}"
+ gem "activesupport"
+ G
+
+ # Neither gem is installed and both are in the global cache
+ expect(the_bundle).not_to include_gems "rack 1.0.0", :dir => bundled_app2
+ expect(the_bundle).not_to include_gems "activesupport 2.3.5", :dir => bundled_app2
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ expect(source_global_cache("activesupport-2.3.5.gem")).to exist
+
+ # Install using the global cache instead of by downloading the .gem
+ # from the server
+ bundle :install, :artifice => "compact_index_no_gem", :dir => bundled_app2
+
+ # activesupport is installed and both are in the global cache
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ expect(the_bundle).not_to include_gems "rack 1.0.0", :dir => bundled_app2
+ expect(the_bundle).to include_gems "activesupport 2.3.5", :dir => bundled_app2
+ end
+
+ expect(source_global_cache("rack-1.0.0.gem")).to exist
+ expect(source_global_cache("activesupport-2.3.5.gem")).to exist
+ end
+ end
+ end
+
+ describe "extension caching" do
+ it "works", :ruby_repo do
+ skip "gets incorrect ref in path" if Gem.win_platform?
+
+ build_git "very_simple_git_binary", &:add_c_extension
+ build_lib "very_simple_path_binary", &:add_c_extension
+ revision = revision_for(lib_path("very_simple_git_binary-1.0"))[0, 12]
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "very_simple_binary"
+ gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}"
+ gem "very_simple_path_binary", :path => "#{lib_path("very_simple_path_binary-1.0")}"
+ G
+
+ gem_binary_cache = home(".bundle", "cache", "extensions", specific_local_platform.to_s, Bundler.ruby_scope,
+ Digest(:MD5).hexdigest("#{gem_repo1}/"), "very_simple_binary-1.0")
+ git_binary_cache = home(".bundle", "cache", "extensions", specific_local_platform.to_s, Bundler.ruby_scope,
+ "very_simple_git_binary-1.0-#{revision}", "very_simple_git_binary-1.0")
+
+ cached_extensions = Pathname.glob(home(".bundle", "cache", "extensions", "*", "*", "*", "*", "*")).sort
+ expect(cached_extensions).to eq [gem_binary_cache, git_binary_cache].sort
+
+ run <<-R
+ require 'very_simple_binary_c'; puts ::VERY_SIMPLE_BINARY_IN_C
+ require 'very_simple_git_binary_c'; puts ::VERY_SIMPLE_GIT_BINARY_IN_C
+ R
+ expect(out).to eq "VERY_SIMPLE_BINARY_IN_C\nVERY_SIMPLE_GIT_BINARY_IN_C"
+
+ FileUtils.rm Dir[home(".bundle", "cache", "extensions", "**", "*binary_c*")]
+
+ gem_binary_cache.join("very_simple_binary_c.rb").open("w") {|f| f << "puts File.basename(__FILE__)" }
+ git_binary_cache.join("very_simple_git_binary_c.rb").open("w") {|f| f << "puts File.basename(__FILE__)" }
+
+ bundle "config set --local path different_path"
+ bundle :install
+
+ expect(Dir[home(".bundle", "cache", "extensions", "**", "*binary_c*")]).to all(end_with(".rb"))
+
+ run <<-R
+ require 'very_simple_binary_c'
+ require 'very_simple_git_binary_c'
+ R
+ expect(out).to eq "very_simple_binary_c.rb\nvery_simple_git_binary_c.rb"
+ end
+ end
+end
diff --git a/spec/bundler/install/path_spec.rb b/spec/bundler/install/path_spec.rb
index 7a501d42b3..b0392c4ed2 100644
--- a/spec/bundler/install/path_spec.rb
+++ b/spec/bundler/install/path_spec.rb
@@ -1,48 +1,56 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
- describe "with --path" do
+ describe "with path configured" do
before :each do
build_gem "rack", "1.0.0", :to_system => true do |s|
s.write "lib/rack.rb", "puts 'FAIL'"
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
- it "does not use available system gems with bundle --path vendor/bundle" do
- bundle "install --path vendor/bundle"
+ it "does not use available system gems with `vendor/bundle" do
+ bundle "config set --local path vendor/bundle"
+ bundle :install
expect(the_bundle).to include_gems "rack 1.0.0"
end
+ it "uses system gems with `path.system` configured with more priority than `path`" do
+ bundle "config set --local path.system true"
+ bundle "config set --global path vendor/bundle"
+ bundle :install
+ run "require 'rack'", :raise_on_error => false
+ expect(out).to include("FAIL")
+ end
+
it "handles paths with regex characters in them" do
dir = bundled_app("bun++dle")
dir.mkpath
- Dir.chdir(dir) do
- bundle "install --path vendor/bundle"
- expect(out).to include("installed into ./vendor/bundle")
- end
+ bundle "config set --local path #{dir.join("vendor/bundle")}"
+ bundle :install, :dir => dir
+ expect(out).to include("installed into `./vendor/bundle`")
dir.rmtree
end
- it "prints a warning to let the user know what has happened with bundle --path vendor/bundle" do
- bundle "install --path vendor/bundle"
- expect(out).to include("gems are installed into ./vendor")
+ it "prints a message to let the user know where gems where installed" do
+ bundle "config set --local path vendor/bundle"
+ bundle :install
+ expect(out).to include("gems are installed into `./vendor/bundle`")
end
- it "disallows --path vendor/bundle --system" do
- bundle "install --path vendor/bundle --system"
- expect(out).to include("Please choose only one option.")
- expect(exitstatus).to eq(15) if exitstatus
+ it "disallows --path vendor/bundle --system", :bundler => "< 3" do
+ bundle "install --path vendor/bundle --system", :raise_on_error => false
+ expect(err).to include("Please choose only one option.")
+ expect(exitstatus).to eq(15)
end
- it "remembers to disable system gems after the first time with bundle --path vendor/bundle" do
+ it "remembers to disable system gems after the first time with bundle --path vendor/bundle", :bundler => "< 3" do
bundle "install --path vendor/bundle"
FileUtils.rm_rf bundled_app("vendor")
bundle "install"
@@ -50,6 +58,31 @@ RSpec.describe "bundle install" do
expect(vendored_gems("gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end
+
+ context "with path_relative_to_cwd set to true" do
+ before { bundle "config set path_relative_to_cwd true" }
+
+ it "installs the bundle relatively to current working directory", :bundler => "< 3" do
+ bundle "install --gemfile='#{bundled_app}/Gemfile' --path vendor/bundle", :dir => bundled_app.parent
+ expect(out).to include("installed into `./vendor/bundle`")
+ expect(bundled_app("../vendor/bundle")).to be_directory
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "installs the standalone bundle relative to the cwd" do
+ bundle :install, :gemfile => bundled_app_gemfile, :standalone => true, :dir => bundled_app.parent
+ expect(out).to include("installed into `./bundled_app/bundle`")
+ expect(bundled_app("bundle")).to be_directory
+ expect(bundled_app("bundle/ruby")).to be_directory
+
+ bundle "config unset path"
+
+ bundle :install, :gemfile => bundled_app_gemfile, :standalone => true, :dir => bundled_app("subdir").tap(&:mkpath)
+ expect(out).to include("installed into `../bundle`")
+ expect(bundled_app("bundle")).to be_directory
+ expect(bundled_app("bundle/ruby")).to be_directory
+ end
+ end
end
describe "when BUNDLE_PATH or the global path config is set" do
@@ -59,7 +92,7 @@ RSpec.describe "bundle install" do
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
@@ -68,39 +101,51 @@ RSpec.describe "bundle install" do
if type == :env
ENV["BUNDLE_PATH"] = location
elsif type == :global
- bundle "config path #{location}", "no-color" => nil
+ bundle "config set path #{location}", "no-color" => nil
end
end
[:env, :global].each do |type|
- it "installs gems to a path if one is specified" do
- set_bundle_path(type, bundled_app("vendor2").to_s)
- bundle "install --path vendor/bundle"
+ context "when set via #{type}" do
+ it "installs gems to a path if one is specified" do
+ set_bundle_path(type, bundled_app("vendor2").to_s)
+ bundle "config set --local path vendor/bundle"
+ bundle :install
- expect(vendored_gems("gems/rack-1.0.0")).to be_directory
- expect(bundled_app("vendor2")).not_to be_directory
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
+ expect(vendored_gems("gems/rack-1.0.0")).to be_directory
+ expect(bundled_app("vendor2")).not_to be_directory
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
- it "installs gems to BUNDLE_PATH with #{type}" do
- set_bundle_path(type, bundled_app("vendor").to_s)
+ it "installs gems to ." do
+ set_bundle_path(type, ".")
+ bundle "config set --global disable_shared_gems true"
- bundle :install
+ bundle :install
- expect(bundled_app("vendor/gems/rack-1.0.0")).to be_directory
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
+ paths_to_exist = %w[cache/rack-1.0.0.gem gems/rack-1.0.0 specifications/rack-1.0.0.gemspec].map {|path| bundled_app(Bundler.ruby_scope, path) }
+ expect(paths_to_exist).to all exist
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
- it "installs gems to BUNDLE_PATH relative to root when relative" do
- set_bundle_path(type, "vendor")
+ it "installs gems to the path" do
+ set_bundle_path(type, bundled_app("vendor").to_s)
- FileUtils.mkdir_p bundled_app("lol")
- Dir.chdir(bundled_app("lol")) do
bundle :install
+
+ expect(bundled_app("vendor", Bundler.ruby_scope, "gems/rack-1.0.0")).to be_directory
+ expect(the_bundle).to include_gems "rack 1.0.0"
end
- expect(bundled_app("vendor/gems/rack-1.0.0")).to be_directory
- expect(the_bundle).to include_gems "rack 1.0.0"
+ it "installs gems to the path relative to root when relative" do
+ set_bundle_path(type, "vendor")
+
+ FileUtils.mkdir_p bundled_app("lol")
+ bundle :install, :dir => bundled_app("lol")
+
+ expect(bundled_app("vendor", Bundler.ruby_scope, "gems/rack-1.0.0")).to be_directory
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
end
end
@@ -114,7 +159,8 @@ RSpec.describe "bundle install" do
end
it "sets BUNDLE_PATH as the first argument to bundle install" do
- bundle "install --path ./vendor/bundle"
+ bundle "config set --local path ./vendor/bundle"
+ bundle :install
expect(vendored_gems("gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -123,23 +169,25 @@ RSpec.describe "bundle install" do
it "disables system gems when passing a path to install" do
# This is so that vendored gems can be distributed to others
build_gem "rack", "1.1.0", :to_system => true
- bundle "install --path ./vendor/bundle"
+ bundle "config set --local path ./vendor/bundle"
+ bundle :install
expect(vendored_gems("gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "re-installs gems whose extensions have been deleted", :ruby_repo, :rubygems => ">= 2.3" do
+ it "re-installs gems whose extensions have been deleted", :ruby_repo do
build_lib "very_simple_binary", "1.0.0", :to_system => true do |s|
s.write "lib/very_simple_binary.rb", "raise 'FAIL'"
end
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "very_simple_binary"
G
- bundle "install --path ./vendor/bundle"
+ bundle "config set --local path ./vendor/bundle"
+ bundle :install
expect(vendored_gems("gems/very_simple_binary-1.0")).to be_directory
expect(vendored_gems("extensions")).to be_directory
@@ -147,10 +195,11 @@ RSpec.describe "bundle install" do
vendored_gems("extensions").rmtree
- run "require 'very_simple_binary_c'"
+ run "require 'very_simple_binary_c'", :raise_on_error => false
expect(err).to include("Bundler::GemNotFound")
- bundle "install --path ./vendor/bundle"
+ bundle "config set --local path ./vendor/bundle"
+ bundle :install
expect(vendored_gems("gems/very_simple_binary-1.0")).to be_directory
expect(vendored_gems("extensions")).to be_directory
@@ -160,19 +209,18 @@ RSpec.describe "bundle install" do
describe "to a file" do
before do
- in_app_root do
- `touch /tmp/idontexist bundle`
- end
+ FileUtils.touch bundled_app("bundle")
end
it "reports the file exists" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "install --path bundle"
- expect(out).to match(/file already exists/)
+ bundle "config set --local path bundle"
+ bundle :install, :raise_on_error => false
+ expect(err).to include("file already exists")
end
end
end
diff --git a/spec/bundler/install/post_bundle_message_spec.rb b/spec/bundler/install/post_bundle_message_spec.rb
deleted file mode 100644
index 4453e4190f..0000000000
--- a/spec/bundler/install/post_bundle_message_spec.rb
+++ /dev/null
@@ -1,190 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-
-RSpec.describe "post bundle message" do
- before :each do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- gem "activesupport", "2.3.5", :group => [:emo, :test]
- group :test do
- gem "rspec"
- end
- gem "rack-obama", :group => :obama
- G
- end
-
- let(:bundle_show_message) { "Use `bundle info [gemname]` to see where a bundled gem is installed." }
- let(:bundle_deployment_message) { "Bundled gems are installed into ./vendor" }
- let(:bundle_complete_message) { "Bundle complete!" }
- let(:bundle_updated_message) { "Bundle updated!" }
- let(:installed_gems_stats) { "4 Gemfile dependencies, 5 gems now installed." }
-
- describe "for fresh bundle install" do
- it "without any options" do
- bundle :install
- expect(out).to include(bundle_show_message)
- expect(out).not_to include("Gems in the group")
- expect(out).to include(bundle_complete_message)
- expect(out).to include(installed_gems_stats)
- end
-
- it "with --without one group" do
- bundle "install --without emo"
- expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the group emo were not installed")
- expect(out).to include(bundle_complete_message)
- expect(out).to include(installed_gems_stats)
- end
-
- it "with --without two groups" do
- bundle "install --without emo test"
- expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo and test were not installed")
- expect(out).to include(bundle_complete_message)
- expect(out).to include("4 Gemfile dependencies, 3 gems now installed.")
- end
-
- it "with --without more groups" do
- bundle "install --without emo obama test"
- expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo, obama and test were not installed")
- expect(out).to include(bundle_complete_message)
- expect(out).to include("4 Gemfile dependencies, 2 gems now installed.")
- end
-
- describe "with --path and" do
- it "without any options" do
- bundle "install --path vendor"
- expect(out).to include(bundle_deployment_message)
- expect(out).to_not include("Gems in the group")
- expect(out).to include(bundle_complete_message)
- end
-
- it "with --without one group" do
- bundle "install --without emo --path vendor"
- expect(out).to include(bundle_deployment_message)
- expect(out).to include("Gems in the group emo were not installed")
- expect(out).to include(bundle_complete_message)
- end
-
- it "with --without two groups" do
- bundle "install --without emo test --path vendor"
- expect(out).to include(bundle_deployment_message)
- expect(out).to include("Gems in the groups emo and test were not installed")
- expect(out).to include(bundle_complete_message)
- end
-
- it "with --without more groups" do
- bundle "install --without emo obama test --path vendor"
- expect(out).to include(bundle_deployment_message)
- expect(out).to include("Gems in the groups emo, obama and test were not installed")
- expect(out).to include(bundle_complete_message)
- end
-
- it "with an absolute --path inside the cwd" do
- bundle "install --path #{bundled_app}/cache"
- expect(out).to include("Bundled gems are installed into ./cache")
- expect(out).to_not include("Gems in the group")
- expect(out).to include(bundle_complete_message)
- end
-
- it "with an absolute --path outside the cwd" do
- bundle "install --path #{bundled_app}_cache"
- expect(out).to include("Bundled gems are installed into #{bundled_app}_cache")
- expect(out).to_not include("Gems in the group")
- expect(out).to include(bundle_complete_message)
- end
- end
-
- describe "with misspelled or non-existent gem name" do
- it "should report a helpful error message" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- gem "not-a-gem", :group => :development
- G
- expect(out).to include("Could not find gem 'not-a-gem' in any of the gem sources listed in your Gemfile.")
- end
-
- it "should report a helpful error message with reference to cache if available" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
- bundle :cache
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- gem "not-a-gem", :group => :development
- G
- expect(out).to include("Could not find gem 'not-a-gem' in any of the gem sources listed in your Gemfile or in gems cached in vendor/cache.")
- end
- end
- end
-
- describe "for second bundle install run" do
- it "without any options" do
- 2.times { bundle :install }
- expect(out).to include(bundle_show_message)
- expect(out).to_not include("Gems in the groups")
- expect(out).to include(bundle_complete_message)
- expect(out).to include(installed_gems_stats)
- end
-
- it "with --without one group" do
- bundle "install --without emo"
- bundle :install
- expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the group emo were not installed")
- expect(out).to include(bundle_complete_message)
- expect(out).to include(installed_gems_stats)
- end
-
- it "with --without two groups" do
- bundle "install --without emo test"
- bundle :install
- expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo and test were not installed")
- expect(out).to include(bundle_complete_message)
- end
-
- it "with --without more groups" do
- bundle "install --without emo obama test"
- bundle :install
- expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo, obama and test were not installed")
- expect(out).to include(bundle_complete_message)
- end
- end
-
- describe "for bundle update" do
- it "without any options" do
- bundle :update
- expect(out).not_to include("Gems in the groups")
- expect(out).to include(bundle_updated_message)
- end
-
- it "with --without one group" do
- bundle :install, :without => :emo
- bundle :update
- expect(out).to include("Gems in the group emo were not installed")
- expect(out).to include(bundle_updated_message)
- end
-
- it "with --without two groups" do
- bundle "install --without emo test"
- bundle :update
- expect(out).to include("Gems in the groups emo and test were not installed")
- expect(out).to include(bundle_updated_message)
- end
-
- it "with --without more groups" do
- bundle "install --without emo obama test"
- bundle :update
- expect(out).to include("Gems in the groups emo, obama and test were not installed")
- expect(out).to include(bundle_updated_message)
- end
- end
-end
diff --git a/spec/bundler/install/prereleases_spec.rb b/spec/bundler/install/prereleases_spec.rb
index 6c32094d90..629eb89dac 100644
--- a/spec/bundler/install/prereleases_spec.rb
+++ b/spec/bundler/install/prereleases_spec.rb
@@ -1,11 +1,19 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle install" do
+ before do
+ build_repo2 do
+ build_gem "not_released", "1.0.pre"
+
+ build_gem "has_prerelease", "1.0"
+ build_gem "has_prerelease", "1.1.pre"
+ end
+ end
+
describe "when prerelease gems are available" do
it "finds prereleases" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "not_released"
G
expect(the_bundle).to include_gems "not_released 1.0.pre"
@@ -13,7 +21,7 @@ RSpec.describe "bundle install" do
it "uses regular releases if available" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "has_prerelease"
G
expect(the_bundle).to include_gems "has_prerelease 1.0"
@@ -21,7 +29,7 @@ RSpec.describe "bundle install" do
it "uses prereleases if requested" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "has_prerelease", "1.1.pre"
G
expect(the_bundle).to include_gems "has_prerelease 1.1.pre"
@@ -30,9 +38,13 @@ RSpec.describe "bundle install" do
describe "when prerelease gems are not available" do
it "still works" do
- build_repo3
+ build_repo gem_repo3 do
+ build_gem "rack"
+ end
+ FileUtils.rm_rf Dir[gem_repo3("prerelease*")]
+
install_gemfile <<-G
- source "file://#{gem_repo3}"
+ source "#{file_uri_for(gem_repo3)}"
gem "rack"
G
diff --git a/spec/bundler/install/process_lock_spec.rb b/spec/bundler/install/process_lock_spec.rb
new file mode 100644
index 0000000000..dac0d34bc4
--- /dev/null
+++ b/spec/bundler/install/process_lock_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+RSpec.describe "process lock spec" do
+ describe "when an install operation is already holding a process lock" do
+ before { FileUtils.mkdir_p(default_bundle_path) }
+
+ it "will not run a second concurrent bundle install until the lock is released" do
+ thread = Thread.new do
+ Bundler::ProcessLock.lock(default_bundle_path) do
+ sleep 1 # ignore quality_spec
+ expect(the_bundle).not_to include_gems "rack 1.0"
+ end
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ thread.join
+ expect(the_bundle).to include_gems "rack 1.0"
+ end
+
+ context "when creating a lock raises Errno::ENOTSUP" do
+ before { allow(File).to receive(:open).and_raise(Errno::ENOTSUP) }
+
+ it "skips creating the lock file and yields" do
+ processed = false
+ Bundler::ProcessLock.lock(default_bundle_path) { processed = true }
+
+ expect(processed).to eq true
+ end
+ end
+ end
+end
diff --git a/spec/bundler/install/redownload_spec.rb b/spec/bundler/install/redownload_spec.rb
new file mode 100644
index 0000000000..a936b2b536
--- /dev/null
+++ b/spec/bundler/install/redownload_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle install" do
+ before :each do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ end
+
+ shared_examples_for "an option to force redownloading gems" do
+ it "re-installs installed gems" do
+ rack_lib = default_bundle_path("gems/rack-1.0.0/lib/rack.rb")
+
+ bundle :install
+ rack_lib.open("w") {|f| f.write("blah blah blah") }
+ bundle :install, flag => true
+
+ expect(out).to include "Installing rack 1.0.0"
+ expect(rack_lib.open(&:read)).to eq("RACK = '1.0.0'\n")
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ it "works on first bundle install" do
+ bundle :install, flag => true
+
+ expect(out).to include "Installing rack 1.0.0"
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+
+ context "with a git gem" do
+ let!(:ref) { build_git("foo", "1.0").ref_for("HEAD", 11) }
+
+ before do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{lib_path("foo-1.0")}"
+ G
+ end
+
+ it "re-installs installed gems" do
+ foo_lib = default_bundle_path("bundler/gems/foo-1.0-#{ref}/lib/foo.rb")
+
+ bundle :install
+ foo_lib.open("w") {|f| f.write("blah blah blah") }
+ bundle :install, flag => true
+
+ expect(foo_lib.open(&:read)).to eq("FOO = '1.0'\n")
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
+
+ it "works on first bundle install" do
+ bundle :install, flag => true
+
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
+ end
+ end
+
+ describe "with --force", :bundler => 2 do
+ it_behaves_like "an option to force redownloading gems" do
+ let(:flag) { "force" }
+ end
+
+ it "shows a deprecation when single flag passed" do
+ bundle "install --force"
+ expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+
+ it "shows a deprecation when multiple flags passed" do
+ bundle "install --no-color --force"
+ expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+ end
+
+ describe "with --redownload" do
+ it_behaves_like "an option to force redownloading gems" do
+ let(:flag) { "redownload" }
+ end
+
+ it "does not show a deprecation when single flag passed" do
+ bundle "install --redownload"
+ expect(err).not_to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+
+ it "does not show a deprecation when single multiple flags passed" do
+ bundle "install --no-color --redownload"
+ expect(err).not_to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+ end
+end
diff --git a/spec/bundler/install/security_policy_spec.rb b/spec/bundler/install/security_policy_spec.rb
index ab531bdad6..43c3069c4e 100644
--- a/spec/bundler/install/security_policy_spec.rb
+++ b/spec/bundler/install/security_policy_spec.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require "spec_helper"
+
require "rubygems/security"
# unfortunately, testing signed gems with a provided CA is extremely difficult
@@ -9,38 +9,35 @@ RSpec.describe "policies with unsigned gems" do
before do
build_security_repo
gemfile <<-G
- source "file://#{security_repo}"
+ source "#{file_uri_for(security_repo)}"
gem "rack"
gem "signed_gem"
G
end
it "will work after you try to deploy without a lock" do
- bundle "install --deployment"
+ bundle "install --deployment", :raise_on_error => false
bundle :install
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems "rack 1.0", "signed_gem 1.0"
end
it "will fail when given invalid security policy" do
- bundle "install --trust-policy=InvalidPolicyName"
- expect(out).to include("Rubygems doesn't know about trust policy")
+ bundle "install --trust-policy=InvalidPolicyName", :raise_on_error => false
+ expect(err).to include("RubyGems doesn't know about trust policy")
end
it "will fail with High Security setting due to presence of unsigned gem" do
- bundle "install --trust-policy=HighSecurity"
- expect(out).to include("security policy didn't allow")
+ bundle "install --trust-policy=HighSecurity", :raise_on_error => false
+ expect(err).to include("security policy didn't allow")
end
- # This spec will fail on Rubygems 2 rc1 due to a bug in policy.rb. the bug is fixed in rc3.
- it "will fail with Medium Security setting due to presence of unsigned gem", :unless => ENV["RGV"] == "v2.0.0.rc.1" do
- bundle "install --trust-policy=MediumSecurity"
- expect(out).to include("security policy didn't allow")
+ it "will fail with Medium Security setting due to presence of unsigned gem" do
+ bundle "install --trust-policy=MediumSecurity", :raise_on_error => false
+ expect(err).to include("security policy didn't allow")
end
it "will succeed with no policy" do
bundle "install"
- expect(exitstatus).to eq(0) if exitstatus
end
end
@@ -48,30 +45,28 @@ RSpec.describe "policies with signed gems and no CA" do
before do
build_security_repo
gemfile <<-G
- source "file://#{security_repo}"
+ source "#{file_uri_for(security_repo)}"
gem "signed_gem"
G
end
it "will fail with High Security setting, gem is self-signed" do
- bundle "install --trust-policy=HighSecurity"
- expect(out).to include("security policy didn't allow")
+ bundle "install --trust-policy=HighSecurity", :raise_on_error => false
+ expect(err).to include("security policy didn't allow")
end
it "will fail with Medium Security setting, gem is self-signed" do
- bundle "install --trust-policy=MediumSecurity"
- expect(out).to include("security policy didn't allow")
+ bundle "install --trust-policy=MediumSecurity", :raise_on_error => false
+ expect(err).to include("security policy didn't allow")
end
it "will succeed with Low Security setting, low security accepts self signed gem" do
bundle "install --trust-policy=LowSecurity"
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems "signed_gem 1.0"
end
it "will succeed with no policy" do
bundle "install"
- expect(exitstatus).to eq(0) if exitstatus
expect(the_bundle).to include_gems "signed_gem 1.0"
end
end
diff --git a/spec/bundler/install/yanked_spec.rb b/spec/bundler/install/yanked_spec.rb
index d42978ce4c..c5f3d788ba 100644
--- a/spec/bundler/install/yanked_spec.rb
+++ b/spec/bundler/install/yanked_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.context "when installing a bundle that includes yanked gems" do
before(:each) do
@@ -11,7 +10,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do
it "throws an error when the original gem version is yanked" do
lockfile <<-L
GEM
- remote: file://#{gem_repo4}
+ remote: #{file_uri_for(gem_repo4)}
specs:
foo (10.0.0)
@@ -23,50 +22,83 @@ RSpec.context "when installing a bundle that includes yanked gems" do
L
- install_gemfile <<-G
- source "file://#{gem_repo4}"
- gem "foo", "10.0.0"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo4)}"
+ gem "foo", "10.0.0"
G
- expect(out).to include("Your bundle is locked to foo (10.0.0)")
+ expect(err).to include("Your bundle is locked to foo (10.0.0)")
end
it "throws the original error when only the Gemfile specifies a gem version that doesn't exist" do
- install_gemfile <<-G
- source "file://#{gem_repo4}"
- gem "foo", "10.0.0"
+ bundle "config set force_ruby_platform true"
+
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo4)}"
+ gem "foo", "10.0.0"
G
- expect(out).not_to include("Your bundle is locked to foo (10.0.0)")
- expect(out).to include("Could not find gem 'foo (= 10.0.0)' in any of the gem sources")
+ expect(err).not_to include("Your bundle is locked to foo (10.0.0)")
+ expect(err).to include("Could not find gem 'foo (= 10.0.0)' in")
end
end
RSpec.context "when using gem before installing" do
it "does not suggest the author has yanked the gem" do
gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack", "0.9.1"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
G
lockfile <<-L
- GEM
- remote: file://#{gem_repo1}
- specs:
- rack (0.9.1)
+ GEM
+ remote: #{file_uri_for(gem_repo1)}
+ specs:
+ rack (0.9.1)
- PLATFORMS
- ruby
+ PLATFORMS
+ ruby
- DEPENDENCIES
- rack (= 0.9.1)
+ DEPENDENCIES
+ rack (= 0.9.1)
+ L
+
+ bundle :list, :raise_on_error => false
+
+ expect(err).to include("Could not find rack-0.9.1 in any of the sources")
+ expect(err).to_not include("Your bundle is locked to rack (0.9.1), but that version could not be found in any of the sources listed in your Gemfile.")
+ expect(err).to_not include("If you haven't changed sources, that means the author of rack (0.9.1) has removed it.")
+ expect(err).to_not include("You'll need to update your bundle to a different version of rack (0.9.1) that hasn't been removed in order to install.")
+ end
+
+ it "does not suggest the author has yanked the gem when using more than one gem, but shows all gems that couldn't be found in the source" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+ gem "rack_middleware", "1.0"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}
+ specs:
+ rack (0.9.1)
+ rack_middleware (1.0)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ rack (= 0.9.1)
+ rack_middleware (1.0)
L
- bundle :list
+ bundle :list, :raise_on_error => false
- expect(out).to include("Could not find rack-0.9.1 in any of the sources")
- expect(out).to_not include("Your bundle is locked to rack (0.9.1), but that version could not be found in any of the sources listed in your Gemfile.")
- expect(out).to_not include("If you haven't changed sources, that means the author of rack (0.9.1) has removed it.")
- expect(out).to_not include("You'll need to update your bundle to a different version of rack (0.9.1) that hasn't been removed in order to install.")
+ expect(err).to include("Could not find rack-0.9.1, rack_middleware-1.0 in any of the sources")
+ expect(err).to include("Install missing gems with `bundle install`.")
+ expect(err).to_not include("Your bundle is locked to rack (0.9.1), but that version could not be found in any of the sources listed in your Gemfile.")
+ expect(err).to_not include("If you haven't changed sources, that means the author of rack (0.9.1) has removed it.")
+ expect(err).to_not include("You'll need to update your bundle to a different version of rack (0.9.1) that hasn't been removed in order to install.")
end
end
diff --git a/spec/bundler/lock/git_spec.rb b/spec/bundler/lock/git_spec.rb
index b36f61338d..56db5d8305 100644
--- a/spec/bundler/lock/git_spec.rb
+++ b/spec/bundler/lock/git_spec.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle lock with git gems" do
before :each do
build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => "#{lib_path("foo-1.0")}"
G
end
@@ -30,6 +30,6 @@ RSpec.describe "bundle lock with git gems" do
run <<-RUBY
puts Bundler.rubygems.find_name('foo').first.full_gem_path
RUBY
- expect(out).to eq(bundle("show foo"))
+ expect(out).to eq(bundle("info foo --path"))
end
end
diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb
index 968c969a55..8befb0d400 100644
--- a/spec/bundler/lock/lockfile_spec.rb
+++ b/spec/bundler/lock/lockfile_spec.rb
@@ -1,24 +1,35 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "the lockfile format" do
include Bundler::GemHelpers
+ before do
+ build_repo2 do
+ # Capistrano did this (at least until version 2.5.10)
+ # RubyGems 2.2 doesn't allow the specifying of a dependency twice
+ # See https://github.com/rubygems/rubygems/commit/03dbac93a3396a80db258d9bc63500333c25bd2f
+ build_gem "double_deps", "1.0", :skip_validation => true do |s|
+ s.add_dependency "net-ssh", ">= 1.0.0"
+ s.add_dependency "net-ssh"
+ end
+ end
+ end
+
it "generates a simple lockfile for a single source, gem" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
@@ -29,6 +40,8 @@ RSpec.describe "the lockfile format" do
end
it "updates the lockfile's bundler version if current ver. is newer" do
+ system_gems "bundler-1.8.2"
+
lockfile <<-L
GIT
remote: git://github.com/nex3/haml.git
@@ -36,12 +49,12 @@ RSpec.describe "the lockfile format" do
specs:
GEM
- remote: file://#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
omg!
@@ -51,20 +64,20 @@ RSpec.describe "the lockfile format" do
1.8.2
L
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
@@ -75,73 +88,75 @@ RSpec.describe "the lockfile format" do
end
it "does not update the lockfile's bundler version if nothing changed during bundle install" do
+ version = "#{Bundler::VERSION.split(".").first}.0.0.a"
+
lockfile <<-L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
- 1.10.0
+ #{version}
L
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
- 1.10.0
+ #{version}
G
end
it "updates the lockfile's bundler version if not present" do
lockfile <<-L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
L
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack", "> 0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack (> 0)
@@ -151,179 +166,219 @@ RSpec.describe "the lockfile format" do
G
end
- it "outputs a warning if the current is older than lockfile's bundler version" do
+ it "warns if the current version is older than lockfile's bundler version, and locked version is a final release" do
+ current_version = "999.998.999"
+ system_gems "bundler-#{current_version}"
+ newer_minor = "999.999.0"
+
lockfile <<-L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
- 9999999.1.0
+ #{newer_minor}
L
- simulate_bundler_version "9999999.0.0" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :env => { "BUNDLER_VERSION" => current_version }
+ source "#{file_uri_for(gem_repo2)}"
- gem "rack"
- G
- end
+ gem "rack"
+ G
- warning_message = "the running version of Bundler (9999999.0.0) is older " \
- "than the version that created the lockfile (9999999.1.0)"
- expect(out.scan(warning_message).size).to eq(1)
+ warning_message = "the running version of Bundler (#{current_version}) is older " \
+ "than the version that created the lockfile (#{newer_minor}). " \
+ "We suggest you to upgrade to the version that created the " \
+ "lockfile by running `gem install bundler:#{newer_minor}`."
+ expect(err).to include warning_message
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
- 9999999.1.0
+ #{newer_minor}
G
end
- it "errors if the current is a major version older than lockfile's bundler version" do
+ it "warns if the current version is older than lockfile's bundler version, and locked version is a prerelease" do
+ current_version = "999.998.999"
+ system_gems "bundler-#{current_version}"
+ newer_minor = "999.999.0.pre1"
+
lockfile <<-L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
- 9999999.0.0
+ #{newer_minor}
L
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :env => { "BUNDLER_VERSION" => current_version }
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- expect(exitstatus > 0) if exitstatus
- expect(out).to include("You must use Bundler 9999999 or greater with this lockfile.")
- end
+ warning_message = "the running version of Bundler (#{current_version}) is older " \
+ "than the version that created the lockfile (#{newer_minor}). " \
+ "We suggest you to upgrade to the version that created the " \
+ "lockfile by running `gem install bundler:#{newer_minor} --pre`."
+ expect(err).to include warning_message
- it "shows a friendly error when running with a new bundler 2 lockfile" do
- lockfile <<-L
+ expect(lockfile).to eq <<~G
GEM
- remote: https://rails-assets.org/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
- rails-assets-bootstrap (3.3.4)
- rails-assets-jquery (>= 1.9.1)
- rails-assets-jquery (2.1.4)
+ rack (1.0.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ #{newer_minor}
+ G
+ end
+ it "doesn't warn if the current version is older than lockfile's bundler version, and locked version is a dev version" do
+ current_version = "999.998.999"
+ system_gems "bundler-#{current_version}"
+ newer_minor = "999.999.0.dev"
+
+ lockfile <<-L
GEM
- remote: https://rubygems.org/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
- rake (10.4.2)
+ rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
- rails-assets-bootstrap!
- rake
+ rack
BUNDLED WITH
- 9999999.0.0
+ #{newer_minor}
L
- install_gemfile <<-G
- source 'https://rubygems.org'
- gem 'rake'
+ install_gemfile <<-G, :env => { "BUNDLER_VERSION" => current_version }
+ source "#{file_uri_for(gem_repo2)}"
- source 'https://rails-assets.org' do
- gem 'rails-assets-bootstrap'
- end
+ gem "rack"
G
- expect(exitstatus > 0) if exitstatus
- expect(out).to include("You must use Bundler 9999999 or greater with this lockfile.")
+ expect(err).to be_empty
+
+ expect(lockfile).to eq <<~G
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack (1.0.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ #{newer_minor}
+ G
end
it "warns when updating bundler major version" do
+ current_version = Bundler::VERSION
+ older_major = previous_major(current_version)
+
+ system_gems "bundler-#{older_major}"
+
lockfile <<-L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
- 1.10.0
+ #{older_major}
L
- simulate_bundler_version "9999999.0.0" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
+ source "#{file_uri_for(gem_repo2)}/"
- gem "rack"
- G
- end
+ gem "rack"
+ G
- expect(out).to include("Warning: the lockfile is being updated to Bundler " \
- "9999999, after which you will be unable to return to Bundler 1.")
+ expect(err).to include(
+ "Warning: the lockfile is being updated to Bundler " \
+ "#{current_version.split(".").first}, after which you will be unable to return to Bundler #{older_major.split(".").first}."
+ )
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
- 9999999.0.0
+ #{current_version}
G
end
it "generates a simple lockfile for a single source, gem with dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack-obama"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
rack-obama (1.0)
rack
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack-obama
@@ -335,21 +390,21 @@ RSpec.describe "the lockfile format" do
it "generates a simple lockfile for a single source, gem with a version requirement" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack-obama", ">= 1.0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
rack-obama (1.0)
rack
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack-obama (>= 1.0)
@@ -359,19 +414,31 @@ RSpec.describe "the lockfile format" do
G
end
- it "generates a lockfile wihout credentials for a configured source" do
- bundle "config http://localgemserver.test/ user:pass"
+ it "generates a lockfile without credentials for a configured source" do
+ bundle "config set http://localgemserver.test/ user:pass"
install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
- source "http://localgemserver.test/"
- source "http://user:pass@othergemserver.test/"
+ source "#{file_uri_for(gem_repo1)}"
- gem "rack-obama", ">= 1.0"
+ source "http://localgemserver.test/" do
+
+ end
+
+ source "http://user:pass@othergemserver.test/" do
+ gem "rack-obama", ">= 1.0"
+ end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
GEM
remote: http://localgemserver.test/
+ specs:
+
+ GEM
remote: http://user:pass@othergemserver.test/
specs:
rack (1.0.0)
@@ -379,10 +446,10 @@ RSpec.describe "the lockfile format" do
rack
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
- rack-obama (>= 1.0)
+ rack-obama (>= 1.0)!
BUNDLED WITH
#{Bundler::VERSION}
@@ -391,20 +458,20 @@ RSpec.describe "the lockfile format" do
it "generates lockfiles with multiple requirements" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "net-sftp"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
net-sftp (1.1.1)
net-ssh (>= 1.0.0, < 1.99.0)
net-ssh (1.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
net-sftp
@@ -420,10 +487,11 @@ RSpec.describe "the lockfile format" do
git = build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("master")}
@@ -431,10 +499,11 @@ RSpec.describe "the lockfile format" do
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -448,7 +517,7 @@ RSpec.describe "the lockfile format" do
build_lib "omg", :path => lib_path("omg")
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
platforms :#{not_local_tag} do
gem "omg", :path => "#{lib_path("omg")}"
@@ -464,7 +533,7 @@ RSpec.describe "the lockfile format" do
specs:
GEM
- remote: file://#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}//
specs:
rack (1.0.0)
@@ -487,12 +556,13 @@ RSpec.describe "the lockfile format" do
git = build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem "foo"
end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("master")}
@@ -500,10 +570,11 @@ RSpec.describe "the lockfile format" do
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -518,10 +589,11 @@ RSpec.describe "the lockfile format" do
update_git "foo", :branch => "omg"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "omg"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
@@ -530,10 +602,11 @@ RSpec.describe "the lockfile format" do
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -548,10 +621,11 @@ RSpec.describe "the lockfile format" do
update_git "foo", :tag => "omg"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}", :tag => "omg"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
@@ -560,10 +634,11 @@ RSpec.describe "the lockfile format" do
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -577,20 +652,22 @@ RSpec.describe "the lockfile format" do
build_lib "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -603,24 +680,27 @@ RSpec.describe "the lockfile format" do
it "serializes pinned path sources to the lockfile even when packaging" do
build_lib "foo"
- install_gemfile! <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
- bundle! "package --all"
- bundle! "install --local"
+ bundle "config set cache_all true"
+ bundle :cache
+ bundle :install, :local => true
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -635,14 +715,14 @@ RSpec.describe "the lockfile format" do
bar = build_git "bar"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack"
gem "foo", :path => "#{lib_path("foo-1.0")}"
gem "bar", :git => "#{lib_path("bar-1.0")}"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("bar-1.0")}
revision: #{bar.ref_for("master")}
@@ -655,12 +735,12 @@ RSpec.describe "the lockfile format" do
foo (1.0)
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
bar!
@@ -672,18 +752,42 @@ RSpec.describe "the lockfile format" do
G
end
+ it "removes redundant sources" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}/"
+
+ gem "rack", :source => "#{file_uri_for(gem_repo2)}/"
+ G
+
+ expect(lockfile).to eq <<~G
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack (1.0.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
it "lists gems alphabetically" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "thin"
gem "actionpack"
gem "rack-obama"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
actionpack (2.3.2)
activesupport (= 2.3.2)
@@ -695,7 +799,7 @@ RSpec.describe "the lockfile format" do
rack
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
actionpack
@@ -709,14 +813,14 @@ RSpec.describe "the lockfile format" do
it "orders dependencies' dependencies in alphabetical order" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rails"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
actionmailer (2.3.2)
activesupport (= 2.3.2)
@@ -732,11 +836,11 @@ RSpec.describe "the lockfile format" do
actionpack (= 2.3.2)
activerecord (= 2.3.2)
activeresource (= 2.3.2)
- rake (= 10.0.2)
- rake (10.0.2)
+ rake (= 13.0.1)
+ rake (13.0.1)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rails
@@ -748,13 +852,13 @@ RSpec.describe "the lockfile format" do
it "orders dependencies by version" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem 'double_deps'
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
double_deps (1.0)
net-ssh
@@ -762,7 +866,7 @@ RSpec.describe "the lockfile format" do
net-ssh (1.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
double_deps
@@ -774,21 +878,21 @@ RSpec.describe "the lockfile format" do
it "does not add the :require option to the lockfile" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack-obama", ">= 1.0", :require => "rack/obama"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
rack-obama (1.0)
rack
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack-obama (>= 1.0)
@@ -800,21 +904,21 @@ RSpec.describe "the lockfile format" do
it "does not add the :group option to the lockfile" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack-obama", ">= 1.0", :group => :test
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
rack-obama (1.0)
rack
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack-obama (>= 1.0)
@@ -828,24 +932,27 @@ RSpec.describe "the lockfile format" do
build_lib "foo", :path => bundled_app("foo")
install_gemfile <<-G
- path "foo"
- gem "foo"
+ source "#{file_uri_for(gem_repo1)}"
+ path "foo" do
+ gem "foo"
+ end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
- foo
+ foo!
BUNDLED WITH
#{Bundler::VERSION}
@@ -856,24 +963,27 @@ RSpec.describe "the lockfile format" do
build_lib "foo", :path => bundled_app(File.join("..", "foo"))
install_gemfile <<-G
- path "../foo"
- gem "foo"
+ source "#{file_uri_for(gem_repo1)}"
+ path "../foo" do
+ gem "foo"
+ end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: ../foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
- foo
+ foo!
BUNDLED WITH
#{Bundler::VERSION}
@@ -884,24 +994,27 @@ RSpec.describe "the lockfile format" do
build_lib "foo", :path => bundled_app("foo")
install_gemfile <<-G
- path File.expand_path("../foo", __FILE__)
- gem "foo"
+ source "#{file_uri_for(gem_repo1)}"
+ path File.expand_path("../foo", __FILE__) do
+ gem "foo"
+ end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
- foo
+ foo!
BUNDLED WITH
#{Bundler::VERSION}
@@ -912,20 +1025,22 @@ RSpec.describe "the lockfile format" do
build_lib("foo", :path => tmp.join("foo"))
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => "../foo"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: ../foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
foo!
@@ -938,7 +1053,7 @@ RSpec.describe "the lockfile format" do
it "keeps existing platforms in the lockfile" do
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
@@ -953,22 +1068,19 @@ RSpec.describe "the lockfile format" do
G
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack"
G
- platforms = ["java", generic_local_platform.to_s].sort
-
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- #{platforms[0]}
- #{platforms[1]}
+ #{lockfile_platforms_for(["java"] + local_platforms)}
DEPENDENCIES
rack
@@ -978,26 +1090,28 @@ RSpec.describe "the lockfile format" do
G
end
- it "persists the spec's platform to the lockfile" do
- build_gem "platform_specific", "1.0.0", :to_system => true do |s|
- s.platform = Gem::Platform.new("universal-java-16")
+ it "persists the spec's specific platform to the lockfile" do
+ build_repo2 do
+ build_gem "platform_specific", "1.0" do |s|
+ s.platform = Gem::Platform.new("universal-java-16")
+ end
end
simulate_platform "universal-java-16"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}"
gem "platform_specific"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
- platform_specific (1.0-java)
+ platform_specific (1.0-universal-java-16)
PLATFORMS
- java
+ universal-java-16
DEPENDENCIES
platform_specific
@@ -1009,25 +1123,25 @@ RSpec.describe "the lockfile format" do
it "does not add duplicate gems" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack"
G
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack"
gem "activesupport"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
activesupport (2.3.5)
rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
activesupport
@@ -1040,19 +1154,19 @@ RSpec.describe "the lockfile format" do
it "does not add duplicate dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
rack
@@ -1064,19 +1178,19 @@ RSpec.describe "the lockfile format" do
it "does not add duplicate dependencies with versions" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0"
gem "rack", "1.0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
rack (= 1.0)
@@ -1088,19 +1202,19 @@ RSpec.describe "the lockfile format" do
it "does not add duplicate dependencies in different groups" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0", :group => :one
gem "rack", "1.0", :group => :two
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
rack (= 1.0)
@@ -1111,41 +1225,41 @@ RSpec.describe "the lockfile format" do
end
it "raises if two different versions are used" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0"
gem "rack", "1.1"
G
- expect(bundled_app("Gemfile.lock")).not_to exist
- expect(out).to include "rack (= 1.0) and rack (= 1.1)"
+ expect(bundled_app_lock).not_to exist
+ expect(err).to include "rack (= 1.0) and rack (= 1.1)"
end
it "raises if two different sources are used" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack"
gem "rack", :git => "git://hubz.com"
G
- expect(bundled_app("Gemfile.lock")).not_to exist
- expect(out).to include "rack (>= 0) should come from an unspecified source and git://hubz.com (at master)"
+ expect(bundled_app_lock).not_to exist
+ expect(err).to include "rack (>= 0) should come from an unspecified source and git://hubz.com"
end
it "works correctly with multiple version dependencies" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack", "> 0.9", "< 1.0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (0.9.1)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
rack (> 0.9, < 1.0)
@@ -1157,19 +1271,19 @@ RSpec.describe "the lockfile format" do
it "captures the Ruby version in the lockfile" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo2)}/"
ruby '#{RUBY_VERSION}'
gem "rack", "> 0.9", "< 1.0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (0.9.1)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
rack (> 0.9, < 1.0)
@@ -1182,143 +1296,81 @@ RSpec.describe "the lockfile format" do
G
end
- # Some versions of the Bundler 1.1 RC series introduced corrupted
- # lockfiles. There were two major problems:
- #
- # * multiple copies of the same GIT section appeared in the lockfile
- # * when this happened, those sections got multiple copies of gems
- # in those sections.
- it "fixes corrupted lockfiles" do
- build_git "omg", :path => lib_path("omg")
- revision = revision_for(lib_path("omg"))
-
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "omg", :git => "#{lib_path("omg")}", :branch => 'master'
- G
-
- bundle "install --path vendor"
- expect(the_bundle).to include_gems "omg 1.0"
-
- # Create a Gemfile.lock that has duplicate GIT sections
- lockfile <<-L
- GIT
- remote: #{lib_path("omg")}
- revision: #{revision}
- branch: master
- specs:
- omg (1.0)
-
- GIT
- remote: #{lib_path("omg")}
- revision: #{revision}
- branch: master
- specs:
- omg (1.0)
-
- GEM
- remote: file:#{gem_repo1}/
- specs:
-
- PLATFORMS
- #{local}
-
- DEPENDENCIES
- omg!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- FileUtils.rm_rf(bundled_app("vendor"))
- bundle "install"
- expect(the_bundle).to include_gems "omg 1.0"
-
- # Confirm that duplicate specs do not appear
- expect(File.read(bundled_app("Gemfile.lock"))).to eq(strip_whitespace(<<-L))
- GIT
- remote: #{lib_path("omg")}
- revision: #{revision}
- branch: master
- specs:
- omg (1.0)
-
- GEM
- remote: file:#{gem_repo1}/
- specs:
-
- PLATFORMS
- #{local}
-
- DEPENDENCIES
- omg!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
it "raises a helpful error message when the lockfile is missing deps" do
lockfile <<-L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack_middleware (1.0)
PLATFORMS
- #{local}
+ #{lockfile_platforms}
DEPENDENCIES
rack_middleware
L
- install_gemfile <<-G
- source "file:#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}"
gem "rack_middleware"
G
- expect(out).to include("Downloading rack_middleware-1.0 revealed dependencies not in the API or the lockfile (#{Gem::Dependency.new("rack", "= 0.9.1")}).").
+ expect(err).to include("Downloading rack_middleware-1.0 revealed dependencies not in the API or the lockfile (#{Gem::Dependency.new("rack", "= 0.9.1")}).").
and include("Either installing with `--full-index` or running `bundle update rack_middleware` should fix the problem.")
end
describe "a line ending" do
def set_lockfile_mtime_to_known_value
time = Time.local(2000, 1, 1, 0, 0, 0)
- File.utime(time, time, bundled_app("Gemfile.lock"))
+ File.utime(time, time, bundled_app_lock)
end
before(:each) do
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
set_lockfile_mtime_to_known_value
end
it "generates Gemfile.lock with \\n line endings" do
- expect(File.read(bundled_app("Gemfile.lock"))).not_to match("\r\n")
+ expect(File.read(bundled_app_lock)).not_to match("\r\n")
expect(the_bundle).to include_gems "rack 1.0"
end
context "during updates" do
it "preserves Gemfile.lock \\n line endings" do
- update_repo2
-
- expect { bundle "update" }.to change { File.mtime(bundled_app("Gemfile.lock")) }
- expect(File.read(bundled_app("Gemfile.lock"))).not_to match("\r\n")
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+ end
+
+ expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
+ expect(File.read(bundled_app_lock)).not_to match("\r\n")
expect(the_bundle).to include_gems "rack 1.2"
end
it "preserves Gemfile.lock \\n\\r line endings" do
- update_repo2
- win_lock = File.read(bundled_app("Gemfile.lock")).gsub(/\n/, "\r\n")
- File.open(bundled_app("Gemfile.lock"), "wb") {|f| f.puts(win_lock) }
+ skip "needs to be adapted" if Gem.win_platform?
+
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+ end
+
+ win_lock = File.read(bundled_app_lock).gsub(/\n/, "\r\n")
+ File.open(bundled_app_lock, "wb") {|f| f.puts(win_lock) }
set_lockfile_mtime_to_known_value
- expect { bundle "update" }.to change { File.mtime(bundled_app("Gemfile.lock")) }
- expect(File.read(bundled_app("Gemfile.lock"))).to match("\r\n")
- expect(the_bundle).to include_gems "rack 1.2"
+ expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
+ expect(File.read(bundled_app_lock)).to match("\r\n")
+
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ expect(the_bundle).to include_gems "rack 1.2"
+ end
end
end
@@ -1326,25 +1378,23 @@ RSpec.describe "the lockfile format" do
it "preserves Gemfile.lock \\n line endings" do
expect do
ruby <<-RUBY
- require 'rubygems'
require 'bundler'
Bundler.setup
RUBY
- end.not_to change { File.mtime(bundled_app("Gemfile.lock")) }
+ end.not_to change { File.mtime(bundled_app_lock) }
end
it "preserves Gemfile.lock \\n\\r line endings" do
- win_lock = File.read(bundled_app("Gemfile.lock")).gsub(/\n/, "\r\n")
- File.open(bundled_app("Gemfile.lock"), "wb") {|f| f.puts(win_lock) }
+ win_lock = File.read(bundled_app_lock).gsub(/\n/, "\r\n")
+ File.open(bundled_app_lock, "wb") {|f| f.puts(win_lock) }
set_lockfile_mtime_to_known_value
expect do
ruby <<-RUBY
- require 'rubygems'
- require 'bundler'
+ require '#{entrypoint}'
Bundler.setup
RUBY
- end.not_to change { File.mtime(bundled_app("Gemfile.lock")) }
+ end.not_to change { File.mtime(bundled_app_lock) }
end
end
end
@@ -1352,7 +1402,7 @@ RSpec.describe "the lockfile format" do
it "refuses to install if Gemfile.lock contains conflict markers" do
lockfile <<-L
GEM
- remote: file://#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo2)}//
specs:
<<<<<<<
rack (1.0.0)
@@ -1361,7 +1411,7 @@ RSpec.describe "the lockfile format" do
>>>>>>>
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
rack
@@ -1370,12 +1420,30 @@ RSpec.describe "the lockfile format" do
#{Bundler::VERSION}
L
- error = install_gemfile(<<-G)
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo2)}/"
gem "rack"
G
- expect(error).to match(/your Gemfile.lock contains merge conflicts/i)
- expect(error).to match(/git checkout HEAD -- Gemfile.lock/i)
+ expect(err).to match(/your Gemfile.lock contains merge conflicts/i)
+ expect(err).to match(/git checkout HEAD -- Gemfile.lock/i)
+ end
+
+ private
+
+ def prerelease?(version)
+ Gem::Version.new(version).prerelease?
+ end
+
+ def previous_major(version)
+ version.split(".").map.with_index {|v, i| i == 0 ? v.to_i - 1 : v }.join(".")
+ end
+
+ def bump_minor(version)
+ bump(version, 1)
+ end
+
+ def bump(version, segment)
+ version.split(".").map.with_index {|v, i| i == segment ? v.to_i + 1 : v }.join(".")
end
end
diff --git a/spec/bundler/other/bundle_ruby_spec.rb b/spec/bundler/other/bundle_ruby_spec.rb
deleted file mode 100644
index 0ef6f407bf..0000000000
--- a/spec/bundler/other/bundle_ruby_spec.rb
+++ /dev/null
@@ -1,143 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-
-RSpec.describe "bundle_ruby", :ruby_repo do
- context "without patchlevel" do
- it "returns the ruby version" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.9.3", :engine => 'ruby', :engine_version => '1.9.3'
-
- gem "foo"
- G
-
- bundle_ruby
-
- expect(out).to include("ruby 1.9.3")
- end
-
- it "engine defaults to MRI" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.9.3"
-
- gem "foo"
- G
-
- bundle_ruby
-
- expect(out).to include("ruby 1.9.3")
- end
-
- it "handles jruby" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.8.7", :engine => 'jruby', :engine_version => '1.6.5'
-
- gem "foo"
- G
-
- bundle_ruby
-
- expect(out).to include("ruby 1.8.7 (jruby 1.6.5)")
- end
-
- it "handles rbx" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.8.7", :engine => 'rbx', :engine_version => '1.2.4'
-
- gem "foo"
- G
-
- bundle_ruby
-
- expect(out).to include("ruby 1.8.7 (rbx 1.2.4)")
- end
-
- it "raises an error if engine is used but engine version is not" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.8.7", :engine => 'rbx'
-
- gem "foo"
- G
-
- bundle_ruby
- expect(exitstatus).not_to eq(0) if exitstatus
-
- bundle_ruby
- expect(out).to include("Please define :engine_version")
- end
-
- it "raises an error if engine_version is used but engine is not" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.8.7", :engine_version => '1.2.4'
-
- gem "foo"
- G
-
- bundle_ruby
- expect(exitstatus).not_to eq(0) if exitstatus
-
- bundle_ruby
- expect(out).to include("Please define :engine")
- end
-
- it "raises an error if engine version doesn't match ruby version for MRI" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.8.7", :engine => 'ruby', :engine_version => '1.2.4'
-
- gem "foo"
- G
-
- bundle_ruby
- expect(exitstatus).not_to eq(0) if exitstatus
-
- bundle_ruby
- expect(out).to include("ruby_version must match the :engine_version for MRI")
- end
-
- it "should print if no ruby version is specified" do
- gemfile <<-G
- source "file://#{gem_repo1}"
-
- gem "foo"
- G
-
- bundle_ruby
-
- expect(out).to include("No ruby version specified")
- end
- end
-
- context "when using patchlevel" do
- it "returns the ruby version" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.9.3", :patchlevel => '429', :engine => 'ruby', :engine_version => '1.9.3'
-
- gem "foo"
- G
-
- bundle_ruby
-
- expect(out).to include("ruby 1.9.3p429")
- end
-
- it "handles an engine" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- ruby "1.9.3", :patchlevel => '392', :engine => 'jruby', :engine_version => '1.7.4'
-
- gem "foo"
- G
-
- bundle_ruby
-
- expect(out).to include("ruby 1.9.3p392 (jruby 1.7.4)")
- end
- end
-end
diff --git a/spec/bundler/other/cli_dispatch_spec.rb b/spec/bundler/other/cli_dispatch_spec.rb
index 8b34a457ef..2d6080296f 100644
--- a/spec/bundler/other/cli_dispatch_spec.rb
+++ b/spec/bundler/other/cli_dispatch_spec.rb
@@ -1,22 +1,20 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle command names" do
it "work when given fully" do
- bundle "install"
- expect(err).to lack_errors
- expect(out).not_to match(/Ambiguous command/)
+ bundle "install", :raise_on_error => false
+ expect(err).to eq("Could not locate Gemfile")
+ expect(last_command.stdboth).not_to include("Ambiguous command")
end
it "work when not ambiguous" do
- bundle "ins"
- expect(err).to lack_errors
- expect(out).not_to match(/Ambiguous command/)
+ bundle "ins", :raise_on_error => false
+ expect(err).to eq("Could not locate Gemfile")
+ expect(last_command.stdboth).not_to include("Ambiguous command")
end
it "print a friendly error when ambiguous" do
- bundle "in"
- expect(err).to lack_errors
- expect(out).to match(/Ambiguous command/)
+ bundle "in", :raise_on_error => false
+ expect(err).to eq("Ambiguous command in matches [info, init, inject, install]")
end
end
diff --git a/spec/bundler/other/ext_spec.rb b/spec/bundler/other/ext_spec.rb
index 2d6ab941b8..e13f62a856 100644
--- a/spec/bundler/other/ext_spec.rb
+++ b/spec/bundler/other/ext_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "Gem::Specification#match_platform" do
it "does not match platforms other than the gem platform" do
@@ -50,18 +49,13 @@ end
RSpec.describe "Gem::SourceIndex#refresh!" do
before do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
- it "does not explode when called", :rubygems => "1.7" do
- run "Gem.source_index.refresh!"
- run "Gem::SourceIndex.new([]).refresh!"
- end
-
- it "does not explode when called", :rubygems => "< 1.7" do
- run "Gem.source_index.refresh!"
- run "Gem::SourceIndex.from_gems_in([]).refresh!"
+ it "does not explode when called" do
+ run "Gem.source_index.refresh!", :raise_on_error => false
+ run "Gem::SourceIndex.new([]).refresh!", :raise_on_error => false
end
end
diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb
index 196fbe0c31..b228027c03 100644
--- a/spec/bundler/other/major_deprecation_spec.rb
+++ b/spec/bundler/other/major_deprecation_spec.rb
@@ -1,174 +1,537 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "major deprecations" do
- let(:warnings) { out } # change to err in 2.0
+ let(:warnings) { err }
- context "in a .99 version" do
+ describe "Bundler" do
before do
- simulate_bundler_version "1.99.1"
- bundle "config --delete major_deprecations"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
end
- it "prints major deprecations without being configured" do
- ruby <<-R
- require "bundler"
- Bundler::SharedHelpers.major_deprecation(Bundler::VERSION)
- R
+ describe ".clean_env" do
+ before do
+ source = "Bundler.clean_env"
+ bundle "exec ruby -e #{source.dump}"
+ end
+
+ it "is deprecated in favor of .unbundled_env", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "`Bundler.clean_env` has been deprecated in favor of `Bundler.unbundled_env`. " \
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env` " \
+ "(called at -e:1)"
+ end
- expect(warnings).to have_major_deprecation("1.99.1")
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
- end
- before do
- bundle "config major_deprecations true"
+ describe ".with_clean_env" do
+ before do
+ source = "Bundler.with_clean_env {}"
+ bundle "exec ruby -e #{source.dump}"
+ end
- install_gemfile <<-G
- source "file:#{gem_repo1}"
- ruby #{RUBY_VERSION.dump}
- gem "rack"
- G
- end
+ it "is deprecated in favor of .unbundled_env", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "`Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. " \
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env` " \
+ "(called at -e:1)"
+ )
+ end
- describe "bundle_ruby", :ruby_repo do
- it "prints a deprecation" do
- bundle_ruby
- out.gsub! "\nruby #{RUBY_VERSION}", ""
- expect(warnings).to have_major_deprecation "the bundle_ruby executable has been removed in favor of `bundle platform --ruby`"
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
- end
- describe "Bundler" do
- describe ".clean_env" do
- it "is deprecated in favor of .original_env" do
- source = "Bundler.clean_env"
+ describe ".clean_system" do
+ before do
+ source = "Bundler.clean_system('ls')"
+ bundle "exec ruby -e #{source.dump}"
+ end
+
+ it "is deprecated in favor of .unbundled_system", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "`Bundler.clean_system` has been deprecated in favor of `Bundler.unbundled_system`. " \
+ "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system` " \
+ "(called at -e:1)"
+ )
+ end
+
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
+ end
+
+ describe ".clean_exec" do
+ before do
+ source = "Bundler.clean_exec('ls')"
bundle "exec ruby -e #{source.dump}"
- expect(warnings).to have_major_deprecation "`Bundler.clean_env` has weird edge cases, use `.original_env` instead"
end
+
+ it "is deprecated in favor of .unbundled_exec", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "`Bundler.clean_exec` has been deprecated in favor of `Bundler.unbundled_exec`. " \
+ "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec` " \
+ "(called at -e:1)"
+ )
+ end
+
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
describe ".environment" do
- it "is deprecated in favor of .load" do
+ before do
source = "Bundler.environment"
bundle "exec ruby -e #{source.dump}"
- expect(warnings).to have_major_deprecation "Bundler.environment has been removed in favor of Bundler.load"
end
+
+ it "is deprecated in favor of .load", :bundler => "< 3" do
+ expect(deprecations).to include "Bundler.environment has been removed in favor of Bundler.load (called at -e:1)"
+ end
+
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
+ end
+ end
+
+ describe "bundle exec --no-keep-file-descriptors" do
+ before do
+ bundle "exec --no-keep-file-descriptors -e 1", :raise_on_error => false
end
- shared_examples_for "environmental deprecations" do |trigger|
- describe "ruby version", :ruby => "< 2.0" do
- it "requires a newer ruby version" do
- instance_eval(&trigger)
- expect(warnings).to have_major_deprecation "Bundler will only support ruby >= 2.0, you are running #{RUBY_VERSION}"
- end
+ it "is deprecated", :bundler => "< 3" do
+ expect(deprecations).to include "The `--no-keep-file-descriptors` has been deprecated. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to"
+ end
+
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
+ end
+
+ describe "bundle update --quiet" do
+ it "does not print any deprecations" do
+ bundle :update, :quiet => true, :raise_on_error => false
+ expect(deprecations).to be_empty
+ end
+ end
+
+ context "bundle check --path" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "check --path vendor/bundle", :raise_on_error => false
+ end
+
+ it "should print a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "The `--path` flag is deprecated because it relies on being " \
+ "remembered across bundler invocations, which bundler will no " \
+ "longer do in future versions. Instead please use `bundle config set --local " \
+ "path 'vendor/bundle'`, and stop using this flag"
+ )
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
+ context "bundle check --path=" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "check --path=vendor/bundle", :raise_on_error => false
+ end
+
+ it "should print a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "The `--path` flag is deprecated because it relies on being " \
+ "remembered across bundler invocations, which bundler will no " \
+ "longer do in future versions. Instead please use `bundle config set --local " \
+ "path 'vendor/bundle'`, and stop using this flag"
+ )
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
+ context "bundle cache --all" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "cache --all", :raise_on_error => false
+ end
+
+ it "should print a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "The `--all` flag is deprecated because it relies on being " \
+ "remembered across bundler invocations, which bundler will no " \
+ "longer do in future versions. Instead please use `bundle config set " \
+ "cache_all true`, and stop using this flag"
+ )
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
+ context "bundle cache --path" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "cache --path foo", :raise_on_error => false
+ end
+
+ it "should print a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "The `--path` flag is deprecated because its semantics are unclear. " \
+ "Use `bundle config cache_path` to configure the path of your cache of gems, " \
+ "and `bundle config path` to configure the path where your gems are installed, " \
+ "and stop using this flag"
+ )
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
+ describe "bundle config" do
+ describe "old list interface" do
+ before do
+ bundle "config"
end
- describe "rubygems version", :rubygems => "< 2.0" do
- it "requires a newer rubygems version" do
- instance_eval(&trigger)
- expect(warnings).to have_major_deprecation "Bundler will only support rubygems >= 2.0, you are running #{Gem::VERSION}"
- end
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config list` instead.")
end
+
+ pending "fails with a helpful error", :bundler => "3"
end
- describe "-rbundler/setup" do
- it_behaves_like "environmental deprecations", proc { ruby "require 'bundler/setup'" }
+ describe "old get interface" do
+ before do
+ bundle "config waka"
+ end
+
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config get waka` instead.")
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
end
- describe "Bundler.setup" do
- it_behaves_like "environmental deprecations", proc { ruby "require 'bundler'; Bundler.setup" }
+ describe "old set interface" do
+ before do
+ bundle "config waka wakapun"
+ end
+
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set waka wakapun` instead.")
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
end
- describe "bundle check" do
- it_behaves_like "environmental deprecations", proc { bundle :check }
+ describe "old set interface with --local" do
+ before do
+ bundle "config --local waka wakapun"
+ end
+
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set --local waka wakapun` instead.")
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
end
- describe "bundle update --quiet" do
- it "does not print any deprecations" do
- bundle :update, :quiet => true
- expect(warnings).not_to have_major_deprecation
+ describe "old set interface with --global" do
+ before do
+ bundle "config --global waka wakapun"
+ end
+
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set --global waka wakapun` instead.")
end
+
+ pending "fails with a helpful error", :bundler => "3"
end
- describe "bundle install --binstubs" do
- it "should output a deprecation warning" do
- gemfile <<-G
- gem 'rack'
- G
+ describe "old unset interface" do
+ before do
+ bundle "config --delete waka"
+ end
- bundle :install, :binstubs => true
- expect(warnings).to have_major_deprecation a_string_including("The --binstubs option will be removed")
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset waka` instead.")
end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
+ describe "old unset interface with --local" do
+ before do
+ bundle "config --delete --local waka"
+ end
+
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset --local waka` instead.")
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
+ describe "old unset interface with --global" do
+ before do
+ bundle "config --delete --global waka"
+ end
+
+ it "warns", :bundler => "3" do
+ expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset --global waka` instead.")
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+ end
+
+ describe "bundle update" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ end
+
+ it "warns when no options are given", :bundler => "3" do
+ bundle "update"
+ expect(deprecations).to include("Pass --all to `bundle update` to update everything")
+ end
+
+ pending "fails with a helpful error when no options are given", :bundler => "3"
+
+ it "does not warn when --all is passed" do
+ bundle "update --all"
+ expect(deprecations).to be_empty
+ end
+ end
+
+ describe "bundle install --binstubs" do
+ before do
+ install_gemfile <<-G, :binstubs => true
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ end
+
+ it "should output a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include("The --binstubs option will be removed in favor of `bundle binstubs --all`")
end
+
+ pending "fails with a helpful error", :bundler => "3"
end
- context "when bundle is run" do
+ context "bundle install with both gems.rb and Gemfile present" do
it "should not warn about gems.rb" do
create_file "gems.rb", <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle :install
- expect(err).not_to have_major_deprecation
- expect(out).not_to have_major_deprecation
+ expect(deprecations).to be_empty
end
- it "should print a Gemfile deprecation warning" do
+ it "should print a proper warning, and use gems.rb" do
+ create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\""
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- expect(warnings).to have_major_deprecation("gems.rb and gems.locked will be preferred to Gemfile and Gemfile.lock.")
+ expect(warnings).to include(
+ "Multiple gemfiles (gems.rb and Gemfile) detected. Make sure you remove Gemfile and Gemfile.lock since bundler is ignoring them in favor of gems.rb and gems.rb.locked."
+ )
+
+ expect(the_bundle).not_to include_gem "rack 1.0"
end
+ end
- context "with flags" do
- it "should print a deprecation warning about autoremembering flags" do
- install_gemfile <<-G, :path => "vendor/bundle"
- source "file://#{gem_repo1}"
- gem "rack"
- G
+ context "bundle install with flags" do
+ before do
+ bundle "config set --local path vendor/bundle"
- expect(warnings).to have_major_deprecation a_string_including(
- "flags passed to commands will no longer be automatically remembered."
- )
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ end
+
+ {
+ "clean" => ["clean", true],
+ "deployment" => ["deployment", true],
+ "frozen" => ["frozen", true],
+ "no-deployment" => ["deployment", false],
+ "no-prune" => ["no_prune", true],
+ "path" => ["path", "vendor/bundle"],
+ "shebang" => ["shebang", "ruby27"],
+ "system" => ["system", true],
+ "without" => ["without", "development"],
+ "with" => ["with", "development"],
+ }.each do |name, expectations|
+ option_name, value = *expectations
+ flag_name = "--#{name}"
+
+ context "with the #{flag_name} flag" do
+ before do
+ bundle "install" # to create a lockfile, which deployment or frozen need
+ bundle "install #{flag_name} #{value}"
+ end
+
+ it "should print a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "The `#{flag_name}` flag is deprecated because it relies on " \
+ "being remembered across bundler invocations, which bundler " \
+ "will no longer do in future versions. Instead please use " \
+ "`bundle config set --local #{option_name} '#{value}'`, and stop using this flag"
+ )
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+ end
+ end
+
+ context "bundle install with multiple sources" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo3)}"
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ end
+
+ it "shows a deprecation", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "Your Gemfile contains multiple primary sources. " \
+ "Using `source` more than once without a block is a security risk, and " \
+ "may result in installing unexpected gems. To resolve this warning, use " \
+ "a block to indicate which gems should come from the secondary source."
+ )
+ end
+
+ it "doesn't show lockfile deprecations if there's a lockfile", :bundler => "< 3" do
+ bundle "install"
+
+ expect(deprecations).to include(
+ "Your Gemfile contains multiple primary sources. " \
+ "Using `source` more than once without a block is a security risk, and " \
+ "may result in installing unexpected gems. To resolve this warning, use " \
+ "a block to indicate which gems should come from the secondary source."
+ )
+ expect(deprecations).not_to include(
+ "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. " \
+ "Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
+ )
+ bundle "config set --local frozen true"
+ bundle "install"
+
+ expect(deprecations).to include(
+ "Your Gemfile contains multiple primary sources. " \
+ "Using `source` more than once without a block is a security risk, and " \
+ "may result in installing unexpected gems. To resolve this warning, use " \
+ "a block to indicate which gems should come from the secondary source."
+ )
+ expect(deprecations).not_to include(
+ "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. " \
+ "Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
+ )
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
+ context "bundle install in frozen mode with a lockfile with a single rubygems section with multiple remotes" do
+ before do
+ build_repo gem_repo3 do
+ build_gem "rack", "0.9.1"
end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo3)}" do
+ gem 'rack'
+ end
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ remote: #{file_uri_for(gem_repo3)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "config set --local frozen true"
+ end
+
+ it "shows a deprecation", :bundler => "< 3" do
+ bundle "install"
+
+ expect(deprecations).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure.")
end
+
+ pending "fails with a helpful error", :bundler => "3"
end
context "when Bundler.setup is run in a ruby script" do
- it "should print a single deprecation warning" do
+ before do
+ create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\""
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :group => :test
G
ruby <<-RUBY
- require 'rubygems'
- require 'bundler'
- require 'bundler/vendored_thor'
+ require '#{entrypoint}'
- Bundler.ui = Bundler::UI::Shell.new
Bundler.setup
Bundler.setup
RUBY
+ end
- expect(warnings).to have_major_deprecation("gems.rb and gems.locked will be preferred to Gemfile and Gemfile.lock.")
+ it "should print a single deprecation warning" do
+ expect(warnings).to include(
+ "Multiple gemfiles (gems.rb and Gemfile) detected. Make sure you remove Gemfile and Gemfile.lock since bundler is ignoring them in favor of gems.rb and gems.rb.locked."
+ )
end
end
context "when `bundler/deployment` is required in a ruby script" do
- it "should print a capistrano deprecation warning" do
- ruby(<<-RUBY)
+ before do
+ ruby(<<-RUBY, :env => env_for_missing_prerelease_default_gem_activation)
require 'bundler/deployment'
RUBY
+ end
- expect(warnings).to have_major_deprecation("Bundler no longer integrates " \
+ it "should print a capistrano deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include("Bundler no longer integrates " \
"with Capistrano, but Capistrano provides " \
"its own integration with Bundler via the " \
"capistrano-bundler gem. Use it instead.")
end
+
+ pending "fails with a helpful error", :bundler => "3"
end
describe Bundler::Dsl do
@@ -178,71 +541,179 @@ RSpec.describe "major deprecations" do
end
context "with github gems" do
- it "warns about the https change" do
- msg = "The :github option uses the git: protocol, which is not secure. " \
- "Bundler 2.0 will use the https: protocol, which is secure. Enable this change now by " \
- "running `bundle config github.https true`."
- expect(Bundler::SharedHelpers).to receive(:major_deprecation).with(msg)
+ it "does not warn about removal", :bundler => "< 3" do
+ expect(Bundler.ui).not_to receive(:warn)
subject.gem("sparks", :github => "indirect/sparks")
+ github_uri = "https://github.com/indirect/sparks.git"
+ expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
- it "upgrades to https on request" do
- Bundler.settings["github.https"] = true
+ it "warns about removal", :bundler => "3" do
+ msg = <<-EOS
+The :github git source is deprecated, and will be removed in the future. Change any "reponame" :github sources to "username/reponame". Add this code to the top of your Gemfile to ensure it continues to work:
+
+ git_source(:github) {|repo_name| "https://github.com/\#{repo_name}.git" }
+
+ EOS
+ expect(Bundler.ui).to receive(:warn).with("[DEPRECATED] #{msg}")
subject.gem("sparks", :github => "indirect/sparks")
- expect(Bundler::SharedHelpers).to receive(:major_deprecation).never
github_uri = "https://github.com/indirect/sparks.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
end
context "with bitbucket gems" do
- it "warns about removal" do
- allow(Bundler.ui).to receive(:deprecate)
- msg = "The :bitbucket git source is deprecated, and will be removed " \
- "in Bundler 2.0. Add this code to your Gemfile to ensure it " \
- "continues to work:\n git_source(:bitbucket) do |repo_name|\n " \
- " \"https://\#{user_name}@bitbucket.org/\#{user_name}/\#{repo_name}" \
- ".git\"\n end\n"
- expect(Bundler::SharedHelpers).to receive(:major_deprecation).with(msg)
+ it "does not warn about removal", :bundler => "< 3" do
+ expect(Bundler.ui).not_to receive(:warn)
+ subject.gem("not-really-a-gem", :bitbucket => "mcorp/flatlab-rails")
+ end
+
+ it "warns about removal", :bundler => "3" do
+ msg = <<-EOS
+The :bitbucket git source is deprecated, and will be removed in the future. Add this code to the top of your Gemfile to ensure it continues to work:
+
+ git_source(:bitbucket) do |repo_name|
+ user_name, repo_name = repo_name.split("/")
+ repo_name ||= user_name
+ "https://\#{user_name}@bitbucket.org/\#{user_name}/\#{repo_name}.git"
+ end
+
+ EOS
+ expect(Bundler.ui).to receive(:warn).with("[DEPRECATED] #{msg}")
subject.gem("not-really-a-gem", :bitbucket => "mcorp/flatlab-rails")
end
end
context "with gist gems" do
- it "warns about removal" do
- allow(Bundler.ui).to receive(:deprecate)
- msg = "The :gist git source is deprecated, and will be removed " \
- "in Bundler 2.0. Add this code to your Gemfile to ensure it " \
- "continues to work:\n git_source(:gist) do |repo_name|\n " \
- " \"https://gist.github.com/\#{repo_name}.git\"\n" \
- " end\n"
- expect(Bundler::SharedHelpers).to receive(:major_deprecation).with(msg)
+ it "does not warn about removal", :bundler => "< 3" do
+ expect(Bundler.ui).not_to receive(:warn)
+ subject.gem("not-really-a-gem", :gist => "1234")
+ end
+
+ it "warns about removal", :bundler => "3" do
+ msg = <<-EOS
+The :gist git source is deprecated, and will be removed in the future. Add this code to the top of your Gemfile to ensure it continues to work:
+
+ git_source(:gist) {|repo_name| "https://gist.github.com/\#{repo_name}.git" }
+
+ EOS
+ expect(Bundler.ui).to receive(:warn).with("[DEPRECATED] #{msg}")
subject.gem("not-really-a-gem", :gist => "1234")
end
end
end
- context "bundle list" do
- it "prints a deprecation warning" do
+ context "bundle show" do
+ before do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ end
+
+ context "with --outdated flag" do
+ before do
+ bundle "show --outdated"
+ end
+
+ it "prints a deprecation warning informing about its removal", :bundler => "< 3" do
+ expect(deprecations).to include("the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement")
+ end
+
+ pending "fails with a helpful message", :bundler => "3"
+ end
+ end
+
+ context "bundle remove" do
+ before do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
+ end
- bundle :list
+ context "with --install" do
+ it "shows a deprecation warning", :bundler => "< 3" do
+ bundle "remove rack --install"
- out.gsub!(/gems included.*?\[DEPRECATED/im, "[DEPRECATED")
+ expect(err).to include "[DEPRECATED] The `--install` flag has been deprecated. `bundle install` is triggered by default."
+ end
- expect(warnings).to have_major_deprecation("use `bundle show` instead of `bundle list`")
+ pending "fails with a helpful message", :bundler => "3"
end
end
context "bundle console" do
- it "prints a deprecation warning" do
- bundle "console"
+ before do
+ bundle "console", :raise_on_error => false
+ end
- expect(warnings).to have_major_deprecation \
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
"bundle console will be replaced by `bin/console` generated by `bundle gem <name>`"
end
+
+ pending "fails with a helpful message", :bundler => "3"
+ end
+
+ context "bundle viz" do
+ before do
+ graphviz_version = RUBY_VERSION >= "2.4" ? "1.2.5" : "1.2.4"
+ realworld_system_gems "ruby-graphviz --version #{graphviz_version}"
+ create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\""
+ bundle "viz"
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
+ end
+
+ pending "fails with a helpful message", :bundler => "3"
+ end
+
+ describe "deprecating rubocop", :readline do
+ context "bundle gem --rubocop" do
+ before do
+ bundle "gem my_new_gem --rubocop", :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "--rubocop is deprecated, use --linter=rubocop"
+ end
+ end
+
+ context "bundle gem --no-rubocop" do
+ before do
+ bundle "gem my_new_gem --no-rubocop", :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "--no-rubocop is deprecated, use --linter"
+ end
+ end
+
+ context "bundle gem with gem.rubocop set to true" do
+ before do
+ bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "true" }, :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
+ end
+ end
+
+ context "bundle gem with gem.rubocop set to false" do
+ before do
+ bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "false" }, :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
+ end
+ end
end
end
diff --git a/spec/bundler/other/platform_spec.rb b/spec/bundler/other/platform_spec.rb
index 6adbcef111..5693d6bce6 100644
--- a/spec/bundler/other/platform_spec.rb
+++ b/spec/bundler/other/platform_spec.rb
@@ -1,11 +1,14 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle platform" do
context "without flags" do
+ let(:bundle_platform_platforms_string) do
+ local_platforms.reverse.map {|pl| "* #{pl}" }.join("\n")
+ end
+
it "returns all the output" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
#{ruby_version_correct}
@@ -17,7 +20,7 @@ RSpec.describe "bundle platform" do
Your platform is: #{RUBY_PLATFORM}
Your app has gems that work on these platforms:
-* ruby
+#{bundle_platform_platforms_string}
Your Gemfile specifies a Ruby version requirement:
* ruby #{RUBY_VERSION}
@@ -28,7 +31,7 @@ G
it "returns all the output including the patchlevel" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
#{ruby_version_correct_patchlevel}
@@ -40,7 +43,7 @@ G
Your platform is: #{RUBY_PLATFORM}
Your app has gems that work on these platforms:
-* ruby
+#{bundle_platform_platforms_string}
Your Gemfile specifies a Ruby version requirement:
* ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}
@@ -51,7 +54,7 @@ G
it "doesn't print ruby version requirement if it isn't specified" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
@@ -61,7 +64,7 @@ G
Your platform is: #{RUBY_PLATFORM}
Your app has gems that work on these platforms:
-* ruby
+#{bundle_platform_platforms_string}
Your Gemfile does not specify a Ruby version requirement.
G
@@ -69,7 +72,7 @@ G
it "doesn't match the ruby version requirement" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
#{ruby_version_incorrect}
@@ -81,7 +84,7 @@ G
Your platform is: #{RUBY_PLATFORM}
Your app has gems that work on these platforms:
-* ruby
+#{bundle_platform_platforms_string}
Your Gemfile specifies a Ruby version requirement:
* ruby #{not_local_ruby_version}
@@ -94,7 +97,7 @@ G
context "--ruby" do
it "returns ruby version when explicit" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "1.9.3", :engine => 'ruby', :engine_version => '1.9.3'
gem "foo"
@@ -107,7 +110,7 @@ G
it "defaults to MRI" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "1.9.3"
gem "foo"
@@ -120,7 +123,7 @@ G
it "handles jruby" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "1.8.7", :engine => 'jruby', :engine_version => '1.6.5'
gem "foo"
@@ -133,7 +136,7 @@ G
it "handles rbx" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "1.8.7", :engine => 'rbx', :engine_version => '1.2.4'
gem "foo"
@@ -144,48 +147,61 @@ G
expect(out).to eq("ruby 1.8.7 (rbx 1.2.4)")
end
+ it "handles truffleruby" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "2.5.1", :engine => 'truffleruby', :engine_version => '1.0.0-rc6'
+
+ gem "foo"
+ G
+
+ bundle "platform --ruby"
+
+ expect(out).to eq("ruby 2.5.1 (truffleruby 1.0.0-rc6)")
+ end
+
it "raises an error if engine is used but engine version is not" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "1.8.7", :engine => 'rbx'
gem "foo"
G
- bundle "platform"
+ bundle "platform", :raise_on_error => false
- expect(exitstatus).not_to eq(0) if exitstatus
+ expect(exitstatus).not_to eq(0)
end
it "raises an error if engine_version is used but engine is not" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "1.8.7", :engine_version => '1.2.4'
gem "foo"
G
- bundle "platform"
+ bundle "platform", :raise_on_error => false
- expect(exitstatus).not_to eq(0) if exitstatus
+ expect(exitstatus).not_to eq(0)
end
it "raises an error if engine version doesn't match ruby version for MRI" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
ruby "1.8.7", :engine => 'ruby', :engine_version => '1.2.4'
gem "foo"
G
- bundle "platform"
+ bundle "platform", :raise_on_error => false
- expect(exitstatus).not_to eq(0) if exitstatus
+ expect(exitstatus).not_to eq(0)
end
it "should print if no ruby version is specified" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
@@ -197,11 +213,13 @@ G
it "handles when there is a locked requirement" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
ruby "< 1.8.7"
G
lockfile <<-L
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -216,25 +234,27 @@ G
#{Bundler::VERSION}
L
- bundle! "platform --ruby"
+ bundle "platform --ruby"
expect(out).to eq("ruby 1.0.0p127")
end
it "handles when there is a requirement in the gemfile" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
ruby ">= 1.8.7"
G
- bundle! "platform --ruby"
+ bundle "platform --ruby"
expect(out).to eq("ruby 1.8.7")
end
it "handles when there are multiple requirements in the gemfile" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
ruby ">= 1.8.7", "< 2.0.0"
G
- bundle! "platform --ruby"
+ bundle "platform --ruby"
expect(out).to eq("ruby 1.8.7")
end
end
@@ -249,113 +269,109 @@ G
let(:patchlevel_fixnum) { "#{ruby_version_correct}, :patchlevel => #{RUBY_PATCHLEVEL}1" }
def should_be_ruby_version_incorrect
- expect(exitstatus).to eq(18) if exitstatus
- expect(out).to be_include("Your Ruby version is #{RUBY_VERSION}, but your Gemfile specified #{not_local_ruby_version}")
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your Ruby version is #{RUBY_VERSION}, but your Gemfile specified #{not_local_ruby_version}")
end
def should_be_engine_incorrect
- expect(exitstatus).to eq(18) if exitstatus
- expect(out).to be_include("Your Ruby engine is #{local_ruby_engine}, but your Gemfile specified #{not_local_tag}")
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your Ruby engine is #{local_ruby_engine}, but your Gemfile specified #{not_local_tag}")
end
def should_be_engine_version_incorrect
- expect(exitstatus).to eq(18) if exitstatus
- expect(out).to be_include("Your #{local_ruby_engine} version is #{local_engine_version}, but your Gemfile specified #{local_ruby_engine} #{not_local_engine_version}")
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your #{local_ruby_engine} version is #{local_engine_version}, but your Gemfile specified #{local_ruby_engine} #{not_local_engine_version}")
end
def should_be_patchlevel_incorrect
- expect(exitstatus).to eq(18) if exitstatus
- expect(out).to be_include("Your Ruby patchlevel is #{RUBY_PATCHLEVEL}, but your Gemfile specified #{not_local_patchlevel}")
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your Ruby patchlevel is #{RUBY_PATCHLEVEL}, but your Gemfile specified #{not_local_patchlevel}")
end
def should_be_patchlevel_fixnum
- expect(exitstatus).to eq(18) if exitstatus
- expect(out).to be_include("The Ruby patchlevel in your Gemfile must be a string")
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("The Ruby patchlevel in your Gemfile must be a string")
end
context "bundle install" do
it "installs fine when the ruby version matches" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{ruby_version_correct}
G
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
- it "installs fine with any engine" do
- simulate_ruby_engine "jruby" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
+ it "installs fine with any engine", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- expect(bundled_app("Gemfile.lock")).to exist
- end
+ expect(bundled_app_lock).to exist
end
it "installs fine when the patchlevel matches" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{ruby_version_correct_patchlevel}
G
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
it "doesn't install when the ruby version doesn't match" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{ruby_version_incorrect}
G
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
should_be_ruby_version_incorrect
end
it "doesn't install when engine doesn't match" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{engine_incorrect}
G
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
should_be_engine_incorrect
end
- it "doesn't install when engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
+ it "doesn't install when engine version doesn't match", :jruby do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- expect(bundled_app("Gemfile.lock")).not_to exist
- should_be_engine_version_incorrect
- end
+ expect(bundled_app_lock).not_to exist
+ should_be_engine_version_incorrect
end
it "doesn't install when patchlevel doesn't match" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{patchlevel_incorrect}
G
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
should_be_patchlevel_incorrect
end
end
@@ -363,109 +379,103 @@ G
context "bundle check" do
it "checks fine when the ruby version matches" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{ruby_version_correct}
G
bundle :check
- expect(exitstatus).to eq(0) if exitstatus
- expect(out).to eq("Resolving dependencies...\nThe Gemfile's dependencies are satisfied")
+ expect(out).to match(/\AResolving dependencies\.\.\.\.*\nThe Gemfile's dependencies are satisfied\z/)
end
- it "checks fine with any engine" do
- simulate_ruby_engine "jruby" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
+ it "checks fine with any engine", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- bundle :check
- expect(exitstatus).to eq(0) if exitstatus
- expect(out).to eq("Resolving dependencies...\nThe Gemfile's dependencies are satisfied")
- end
+ bundle :check
+ expect(out).to match(/\AResolving dependencies\.\.\.\.*\nThe Gemfile's dependencies are satisfied\z/)
end
it "fails when ruby version doesn't match" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{ruby_version_incorrect}
G
- bundle :check
+ bundle :check, :raise_on_error => false
should_be_ruby_version_incorrect
end
it "fails when engine doesn't match" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{engine_incorrect}
G
- bundle :check
+ bundle :check, :raise_on_error => false
should_be_engine_incorrect
end
- it "fails when engine version doesn't match" do
- simulate_ruby_engine "ruby" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
+ it "fails when engine version doesn't match", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- bundle :check
- should_be_engine_version_incorrect
- end
+ bundle :check, :raise_on_error => false
+ should_be_engine_version_incorrect
end
it "fails when patchlevel doesn't match" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{patchlevel_incorrect}
G
- bundle :check
+ bundle :check, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -475,7 +485,7 @@ G
build_repo2
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
G
@@ -483,41 +493,47 @@ G
it "updates successfully when the ruby version matches" do
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
#{ruby_version_correct}
G
update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
build_gem "activesupport", "3.0"
end
- bundle "update"
+ bundle "update", :all => true
expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end
- it "updates fine with any engine" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport"
- gem "rack-obama"
+ it "updates fine with any engine", :jruby do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
- #{ruby_version_correct_engineless}
- G
- update_repo2 do
- build_gem "activesupport", "3.0"
+ #{ruby_version_correct_engineless}
+ G
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
end
- bundle "update"
- expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
+ build_gem "activesupport", "3.0"
end
+
+ bundle "update", :all => true
+ expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end
it "fails when ruby version doesn't match" do
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
@@ -527,13 +543,13 @@ G
build_gem "activesupport", "3.0"
end
- bundle :update
+ bundle :update, :all => true, :raise_on_error => false
should_be_ruby_version_incorrect
end
- it "fails when ruby engine doesn't match" do
+ it "fails when ruby engine doesn't match", :jruby do
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
@@ -543,31 +559,29 @@ G
build_gem "activesupport", "3.0"
end
- bundle :update
+ bundle :update, :all => true, :raise_on_error => false
should_be_engine_incorrect
end
- it "fails when ruby engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport"
- gem "rack-obama"
-
- #{engine_version_incorrect}
- G
- update_repo2 do
- build_gem "activesupport", "3.0"
- end
+ it "fails when ruby engine version doesn't match", :jruby do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
- bundle :update
- should_be_engine_version_incorrect
+ #{engine_version_incorrect}
+ G
+ update_repo2 do
+ build_gem "activesupport", "3.0"
end
+
+ bundle :update, :all => true, :raise_on_error => false
+ should_be_engine_version_incorrect
end
it "fails when patchlevel doesn't match" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{patchlevel_incorrect}
@@ -576,86 +590,82 @@ G
build_gem "activesupport", "3.0"
end
- bundle :update
+ bundle :update, :all => true, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
- context "bundle show" do
+ context "bundle info" do
before do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
end
it "prints path if ruby version is correct" do
- gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
#{ruby_version_correct}
G
- bundle "show rails"
+ bundle "info rails --path"
expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
end
- it "prints path if ruby version is correct for any engine" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rails"
+ it "prints path if ruby version is correct for any engine", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- bundle "show rails"
- expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
- end
+ bundle "info rails --path"
+ expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
end
- it "fails if ruby version doesn't match" do
+ it "fails if ruby version doesn't match", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
#{ruby_version_incorrect}
G
- bundle "show rails"
+ bundle "show rails", :raise_on_error => false
should_be_ruby_version_incorrect
end
- it "fails if engine doesn't match" do
+ it "fails if engine doesn't match", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
#{engine_incorrect}
G
- bundle "show rails"
+ bundle "show rails", :raise_on_error => false
should_be_engine_incorrect
end
- it "fails if engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rails"
+ it "fails if engine version doesn't match", :bundler => "< 3", :jruby => true do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- bundle "show rails"
- should_be_engine_version_incorrect
- end
+ bundle "show rails", :raise_on_error => false
+ should_be_engine_version_incorrect
end
- it "fails when patchlevel doesn't match" do
+ it "fails when patchlevel doesn't match", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{patchlevel_incorrect}
@@ -664,22 +674,22 @@ G
build_gem "activesupport", "3.0"
end
- bundle "show rails"
+ bundle "show rails", :raise_on_error => false
should_be_patchlevel_incorrect
end
end
context "bundle cache" do
before do
- gemfile <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
-
- system_gems "rack-1.0.0"
end
it "copies the .gem file to vendor/cache when ruby version matches" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
#{ruby_version_correct}
@@ -689,144 +699,144 @@ G
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
end
- it "copies the .gem file to vendor/cache when ruby version matches for any engine" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- gem 'rack'
+ it "copies the .gem file to vendor/cache when ruby version matches for any engine", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- bundle :cache
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- end
+ bundle :cache
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
end
it "fails if the ruby version doesn't match" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
#{ruby_version_incorrect}
G
- bundle :cache
+ bundle :cache, :raise_on_error => false
should_be_ruby_version_incorrect
end
it "fails if the engine doesn't match" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
#{engine_incorrect}
G
- bundle :cache
+ bundle :cache, :raise_on_error => false
should_be_engine_incorrect
end
- it "fails if the engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- gem 'rack'
+ it "fails if the engine version doesn't match", :jruby do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- bundle :cache
- should_be_engine_version_incorrect
- end
+ bundle :cache, :raise_on_error => false
+ should_be_engine_version_incorrect
end
it "fails when patchlevel doesn't match" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{patchlevel_incorrect}
G
- bundle :cache
+ bundle :cache, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
context "bundle pack" do
before do
- gemfile <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
G
-
- system_gems "rack-1.0.0"
end
it "copies the .gem file to vendor/cache when ruby version matches" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
#{ruby_version_correct}
G
- bundle :pack
+ bundle :cache
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
end
- it "copies the .gem file to vendor/cache when ruby version matches any engine" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- gem 'rack'
+ it "copies the .gem file to vendor/cache when ruby version matches any engine", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- bundle :pack
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- end
+ bundle :cache
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
end
it "fails if the ruby version doesn't match" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
#{ruby_version_incorrect}
G
- bundle :pack
+ bundle :cache, :raise_on_error => false
should_be_ruby_version_incorrect
end
it "fails if the engine doesn't match" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
#{engine_incorrect}
G
- bundle :pack
+ bundle :cache, :raise_on_error => false
should_be_engine_incorrect
end
- it "fails if the engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- gem 'rack'
+ it "fails if the engine version doesn't match", :jruby do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- bundle :pack
- should_be_engine_version_incorrect
- end
+ bundle :cache, :raise_on_error => false
+ should_be_engine_version_incorrect
end
it "fails when patchlevel doesn't match" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{patchlevel_incorrect}
G
- bundle :pack
+ bundle :cache, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -834,94 +844,95 @@ G
context "bundle exec" do
before do
ENV["BUNDLER_FORCE_TTY"] = "true"
- system_gems "rack-1.0.0", "rack-0.9.1"
+ system_gems "rack-1.0.0", "rack-0.9.1", :path => default_bundle_path
end
it "activates the correct gem when ruby version matches" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
#{ruby_version_correct}
G
bundle "exec rackup"
- expect(out).to eq("0.9.1")
+ expect(out).to include("0.9.1")
end
- it "activates the correct gem when ruby version matches any engine" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- gem "rack", "0.9.1"
+ it "activates the correct gem when ruby version matches any engine", :jruby do
+ system_gems "rack-1.0.0", "rack-0.9.1", :path => default_bundle_path
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- bundle "exec rackup"
- expect(out).to eq("0.9.1")
- end
+ bundle "exec rackup"
+ expect(out).to include("0.9.1")
end
it "fails when the ruby version doesn't match" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
#{ruby_version_incorrect}
G
- bundle "exec rackup"
+ bundle "exec rackup", :raise_on_error => false
should_be_ruby_version_incorrect
end
it "fails when the engine doesn't match" do
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
#{engine_incorrect}
G
- bundle "exec rackup"
+ bundle "exec rackup", :raise_on_error => false
should_be_engine_incorrect
end
- # it "fails when the engine version doesn't match" do
- # simulate_ruby_engine "jruby" do
- # gemfile <<-G
- # gem "rack", "0.9.1"
+ # it "fails when the engine version doesn't match", :jruby do
+ # gemfile <<-G
+ # gem "rack", "0.9.1"
#
- # #{engine_version_incorrect}
- # G
+ # #{engine_version_incorrect}
+ # G
#
- # bundle "exec rackup"
- # should_be_engine_version_incorrect
- # end
+ # bundle "exec rackup"
+ # should_be_engine_version_incorrect
# end
it "fails when patchlevel doesn't match" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
#{patchlevel_incorrect}
G
- bundle "exec rackup"
+ bundle "exec rackup", :raise_on_error => false
should_be_patchlevel_incorrect
end
end
- context "bundle console" do
+ context "bundle console", :bundler => "< 3" do
before do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "activesupport", :group => :test
gem "rack_middleware", :group => :development
G
end
- it "starts IRB with the default group loaded when ruby version matches" do
+ it "starts IRB with the default group loaded when ruby version matches", :readline do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "activesupport", :group => :test
gem "rack_middleware", :group => :development
@@ -936,28 +947,26 @@ G
expect(out).to include("0.9.1")
end
- it "starts IRB with the default group loaded when ruby version matches any engine" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- gem "activesupport", :group => :test
- gem "rack_middleware", :group => :development
+ it "starts IRB with the default group loaded when ruby version matches", :readline, :jruby do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- bundle "console" do |input, _, _|
- input.puts("puts RACK")
- input.puts("exit")
- end
- expect(out).to include("0.9.1")
+ bundle "console" do |input, _, _|
+ input.puts("puts RACK")
+ input.puts("exit")
end
+ expect(out).to include("0.9.1")
end
it "fails when ruby version doesn't match" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "activesupport", :group => :test
gem "rack_middleware", :group => :development
@@ -965,13 +974,13 @@ G
#{ruby_version_incorrect}
G
- bundle "console"
+ bundle "console", :raise_on_error => false
should_be_ruby_version_incorrect
end
it "fails when engine doesn't match" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "activesupport", :group => :test
gem "rack_middleware", :group => :development
@@ -979,29 +988,27 @@ G
#{engine_incorrect}
G
- bundle "console"
+ bundle "console", :raise_on_error => false
should_be_engine_incorrect
end
- it "fails when engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- gem "activesupport", :group => :test
- gem "rack_middleware", :group => :development
+ it "fails when engine version doesn't match", :jruby do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- bundle "console"
- should_be_engine_version_incorrect
- end
+ bundle "console", :raise_on_error => false
+ should_be_engine_version_incorrect
end
it "fails when patchlevel doesn't match" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "activesupport", :group => :test
gem "rack_middleware", :group => :development
@@ -1009,7 +1016,7 @@ G
#{patchlevel_incorrect}
G
- bundle "console"
+ bundle "console", :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -1017,7 +1024,7 @@ G
context "Bundler.setup" do
before do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack", :group => :test
G
@@ -1027,115 +1034,99 @@ G
it "makes a Gemfile.lock if setup succeeds" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
#{ruby_version_correct}
G
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
run "1"
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
- it "makes a Gemfile.lock if setup succeeds for any engine" do
- simulate_ruby_engine "jruby" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "yard"
- gem "rack"
+ it "makes a Gemfile.lock if setup succeeds for any engine", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
- #{ruby_version_correct_engineless}
- G
+ #{ruby_version_correct_engineless}
+ G
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
- run "1"
- expect(bundled_app("Gemfile.lock")).to exist
- end
+ run "1"
+ expect(bundled_app_lock).to exist
end
it "fails when ruby version doesn't match" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
#{ruby_version_incorrect}
G
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
- ruby <<-R
- require 'rubygems'
- require 'bundler/setup'
- R
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
should_be_ruby_version_incorrect
end
it "fails when engine doesn't match" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
#{engine_incorrect}
G
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
- ruby <<-R
- require 'rubygems'
- require 'bundler/setup'
- R
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
should_be_engine_incorrect
end
- it "fails when engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "yard"
- gem "rack"
+ it "fails when engine version doesn't match", :jruby do
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
- ruby <<-R
- require 'rubygems'
- require 'bundler/setup'
- R
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
- expect(bundled_app("Gemfile.lock")).not_to exist
- should_be_engine_version_incorrect
- end
+ expect(bundled_app_lock).not_to exist
+ should_be_engine_version_incorrect
end
it "fails when patchlevel doesn't match" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G, :raise_on_error => false
+ source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
#{patchlevel_incorrect}
G
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
- ruby <<-R
- require 'rubygems'
- require 'bundler/setup'
- R
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
should_be_patchlevel_incorrect
end
end
@@ -1147,7 +1138,7 @@ G
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "2.3.5"
gem "foo", :git => "#{lib_path("foo")}"
G
@@ -1160,37 +1151,48 @@ G
end
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "2.3.5"
gem "foo", :git => "#{lib_path("foo")}"
#{ruby_version_correct}
G
- bundle "outdated"
- expect(out).to include("activesupport (newest 3.0, installed 2.3.5, requested = 2.3.5")
- expect(out).to include("foo (newest 1.0")
+ bundle "outdated", :raise_on_error => false
+
+ expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 default
+ foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default
+ TABLE
+
+ expect(out).to match(Regexp.new(expected_output))
end
- it "returns list of outdated gems when the ruby version matches for any engine" do
- simulate_ruby_engine "jruby" do
- update_repo2 do
- build_gem "activesupport", "3.0"
- update_git "foo", :path => lib_path("foo")
- end
+ it "returns list of outdated gems when the ruby version matches for any engine", :jruby do
+ bundle :install
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", :path => lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
- gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport", "2.3.5"
- gem "foo", :git => "#{lib_path("foo")}"
+ #{ruby_version_correct_engineless}
+ G
- #{ruby_version_correct_engineless}
- G
+ bundle "outdated", :raise_on_error => false
- bundle "outdated"
- expect(out).to include("activesupport (newest 3.0, installed 2.3.5, requested = 2.3.5)")
- expect(out).to include("foo (newest 1.0")
- end
+ expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 default
+ foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default
+ TABLE
+
+ expect(out).to match(Regexp.new(expected_output))
end
it "fails when the ruby version doesn't match" do
@@ -1200,14 +1202,14 @@ G
end
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "2.3.5"
gem "foo", :git => "#{lib_path("foo")}"
#{ruby_version_incorrect}
G
- bundle "outdated"
+ bundle "outdated", :raise_on_error => false
should_be_ruby_version_incorrect
end
@@ -1218,75 +1220,69 @@ G
end
gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "activesupport", "2.3.5"
gem "foo", :git => "#{lib_path("foo")}"
#{engine_incorrect}
G
- bundle "outdated"
+ bundle "outdated", :raise_on_error => false
should_be_engine_incorrect
end
- it "fails when the engine version doesn't match" do
- simulate_ruby_engine "jruby" do
- update_repo2 do
- build_gem "activesupport", "3.0"
- update_git "foo", :path => lib_path("foo")
- end
+ it "fails when the engine version doesn't match", :jruby do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", :path => lib_path("foo")
+ end
- gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport", "2.3.5"
- gem "foo", :git => "#{lib_path("foo")}"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
- #{engine_version_incorrect}
- G
+ #{engine_version_incorrect}
+ G
- bundle "outdated"
- should_be_engine_version_incorrect
- end
+ bundle "outdated", :raise_on_error => false
+ should_be_engine_version_incorrect
end
- it "fails when the patchlevel doesn't match" do
- simulate_ruby_engine "jruby" do
- update_repo2 do
- build_gem "activesupport", "3.0"
- update_git "foo", :path => lib_path("foo")
- end
+ it "fails when the patchlevel doesn't match", :jruby do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", :path => lib_path("foo")
+ end
- gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport", "2.3.5"
- gem "foo", :git => "#{lib_path("foo")}"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
- #{patchlevel_incorrect}
- G
+ #{patchlevel_incorrect}
+ G
- bundle "outdated"
- should_be_patchlevel_incorrect
- end
+ bundle "outdated", :raise_on_error => false
+ should_be_patchlevel_incorrect
end
- it "fails when the patchlevel is a fixnum" do
- simulate_ruby_engine "jruby" do
- update_repo2 do
- build_gem "activesupport", "3.0"
- update_git "foo", :path => lib_path("foo")
- end
+ it "fails when the patchlevel is a fixnum", :jruby do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", :path => lib_path("foo")
+ end
- gemfile <<-G
- source "file://#{gem_repo2}"
- gem "activesupport", "2.3.5"
- gem "foo", :git => "#{lib_path("foo")}"
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
- #{patchlevel_fixnum}
- G
+ #{patchlevel_fixnum}
+ G
- bundle "outdated"
- should_be_patchlevel_fixnum
- end
+ bundle "outdated", :raise_on_error => false
+ should_be_patchlevel_fixnum
end
end
end
diff --git a/spec/bundler/other/ssl_cert_spec.rb b/spec/bundler/other/ssl_cert_spec.rb
deleted file mode 100644
index 2de4dfdd0c..0000000000
--- a/spec/bundler/other/ssl_cert_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-require "bundler/ssl_certs/certificate_manager"
-
-RSpec.describe "SSL Certificates", :rubygems_master do
- hosts = %w(
- rubygems.org
- index.rubygems.org
- rubygems.global.ssl.fastly.net
- staging.rubygems.org
- )
-
- hosts.each do |host|
- it "can securely connect to #{host}", :realworld do
- Bundler::SSLCerts::CertificateManager.new.connect_to(host)
- end
- end
-end
diff --git a/spec/bundler/plugins/command_spec.rb b/spec/bundler/plugins/command_spec.rb
index 6ad782b758..3a7adf4b48 100644
--- a/spec/bundler/plugins/command_spec.rb
+++ b/spec/bundler/plugins/command_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "command plugins" do
before do
@@ -19,7 +18,7 @@ RSpec.describe "command plugins" do
end
end
- bundle "plugin install command-mah --source file://#{gem_repo2}"
+ bundle "plugin install command-mah --source #{file_uri_for(gem_repo2)}"
end
it "executes without arguments" do
@@ -47,10 +46,10 @@ RSpec.describe "command plugins" do
end
end
- bundle "plugin install the-echoer --source file://#{gem_repo2}"
+ bundle "plugin install the-echoer --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installed plugin the-echoer")
- bundle "echo tacos tofu lasange", "no-color" => false
+ bundle "echo tacos tofu lasange"
expect(out).to eq("You gave me tacos, tofu, lasange")
end
@@ -70,12 +69,10 @@ RSpec.describe "command plugins" do
end
end
- bundle "plugin install copycat --source file://#{gem_repo2}"
+ bundle "plugin install copycat --source #{file_uri_for(gem_repo2)}", :raise_on_error => false
expect(out).not_to include("Installed plugin copycat")
- expect(out).to include("Failed to install plugin")
-
- expect(out).to include("Command(s) `mahcommand` declared by copycat are already registered.")
+ expect(err).to include("Failed to install plugin `copycat`, due to Bundler::Plugin::Index::CommandConflict (Command(s) `mahcommand` declared by copycat are already registered.)")
end
end
diff --git a/spec/bundler/plugins/hook_spec.rb b/spec/bundler/plugins/hook_spec.rb
index 9850d850ac..72feb14d84 100644
--- a/spec/bundler/plugins/hook_spec.rb
+++ b/spec/bundler/plugins/hook_spec.rb
@@ -1,28 +1,109 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "hook plugins" do
- before do
- build_repo2 do
- build_plugin "before-install-plugin" do |s|
- s.write "plugins.rb", <<-RUBY
- Bundler::Plugin::API.hook "before-install-all" do |deps|
- puts "gems to be installed \#{deps.map(&:name).join(", ")}"
- end
- RUBY
+ context "before-install-all hook" do
+ before do
+ build_repo2 do
+ build_plugin "before-install-all-plugin" do |s|
+ s.write "plugins.rb", <<-RUBY
+ Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_INSTALL_ALL do |deps|
+ puts "gems to be installed \#{deps.map(&:name).join(", ")}"
+ end
+ RUBY
+ end
end
+
+ bundle "plugin install before-install-all-plugin --source #{file_uri_for(gem_repo2)}"
+ end
+
+ it "runs before all rubygems are installed" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rake"
+ gem "rack"
+ G
+
+ expect(out).to include "gems to be installed rake, rack"
+ end
+ end
+
+ context "before-install hook" do
+ before do
+ build_repo2 do
+ build_plugin "before-install-plugin" do |s|
+ s.write "plugins.rb", <<-RUBY
+ Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_INSTALL do |spec_install|
+ puts "installing gem \#{spec_install.name}"
+ end
+ RUBY
+ end
+ end
+
+ bundle "plugin install before-install-plugin --source #{file_uri_for(gem_repo2)}"
+ end
+
+ it "runs before each rubygem is installed" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rake"
+ gem "rack"
+ G
+
+ expect(out).to include "installing gem rake"
+ expect(out).to include "installing gem rack"
end
+ end
+
+ context "after-install-all hook" do
+ before do
+ build_repo2 do
+ build_plugin "after-install-all-plugin" do |s|
+ s.write "plugins.rb", <<-RUBY
+ Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_INSTALL_ALL do |deps|
+ puts "installed gems \#{deps.map(&:name).join(", ")}"
+ end
+ RUBY
+ end
+ end
+
+ bundle "plugin install after-install-all-plugin --source #{file_uri_for(gem_repo2)}"
+ end
+
+ it "runs after each rubygem is installed" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rake"
+ gem "rack"
+ G
- bundle "plugin install before-install-plugin --source file://#{gem_repo2}"
+ expect(out).to include "installed gems rake, rack"
+ end
end
- it "runs after a rubygem is installed" do
- install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rake"
- gem "rack"
- G
+ context "after-install hook" do
+ before do
+ build_repo2 do
+ build_plugin "after-install-plugin" do |s|
+ s.write "plugins.rb", <<-RUBY
+ Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_INSTALL do |spec_install|
+ puts "installed gem \#{spec_install.name} : \#{spec_install.state}"
+ end
+ RUBY
+ end
+ end
+
+ bundle "plugin install after-install-plugin --source #{file_uri_for(gem_repo2)}"
+ end
+
+ it "runs after each rubygem is installed" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rake"
+ gem "rack"
+ G
- expect(out).to include "gems to be installed rake, rack"
+ expect(out).to include "installed gem rake : installed"
+ expect(out).to include "installed gem rack : installed"
+ end
end
end
diff --git a/spec/bundler/plugins/install_spec.rb b/spec/bundler/plugins/install_spec.rb
index e2d351181c..009516260a 100644
--- a/spec/bundler/plugins/install_spec.rb
+++ b/spec/bundler/plugins/install_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundler plugin install" do
before do
@@ -10,21 +9,46 @@ RSpec.describe "bundler plugin install" do
end
it "shows proper message when gem in not found in the source" do
- bundle "plugin install no-foo --source file://#{gem_repo1}"
+ bundle "plugin install no-foo --source #{file_uri_for(gem_repo1)}", :raise_on_error => false
- expect(out).to include("Could not find")
+ expect(err).to include("Could not find")
plugin_should_not_be_installed("no-foo")
end
it "installs from rubygems source" do
- bundle "plugin install foo --source file://#{gem_repo2}"
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installed plugin foo")
plugin_should_be_installed("foo")
end
+ it "installs from sources configured as Gem.sources without any flags" do
+ bundle "plugin install foo", :env => { "BUNDLER_SPEC_GEM_SOURCES" => file_uri_for(gem_repo2).to_s }
+
+ expect(out).to include("Installed plugin foo")
+ plugin_should_be_installed("foo")
+ end
+
+ it "shows help when --help flag is given" do
+ bundle "plugin install --help"
+
+ expect(out).to include("bundle plugin install PLUGINS # Install the plugin from the source")
+ end
+
+ context "plugin is already installed" do
+ before do
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)}"
+ end
+
+ it "doesn't install plugin again" do
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)}"
+ expect(out).not_to include("Installing plugin foo")
+ expect(out).not_to include("Installed plugin foo")
+ end
+ end
+
it "installs multiple plugins" do
- bundle "plugin install foo kung-foo --source file://#{gem_repo2}"
+ bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installed plugin foo")
expect(out).to include("Installed plugin kung-foo")
@@ -38,13 +62,28 @@ RSpec.describe "bundler plugin install" do
build_plugin "kung-foo", "1.1"
end
- bundle "plugin install foo kung-foo --version '1.0' --source file://#{gem_repo2}"
+ bundle "plugin install foo kung-foo --version '1.0' --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installing foo 1.0")
expect(out).to include("Installing kung-foo 1.0")
plugin_should_be_installed("foo", "kung-foo")
end
+ it "installs the latest version if not installed" do
+ update_repo2 do
+ build_plugin "foo", "1.1"
+ end
+
+ bundle "plugin install foo --version 1.0 --source #{file_uri_for(gem_repo2)} --verbose"
+ expect(out).to include("Installing foo 1.0")
+
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --verbose"
+ expect(out).to include("Installing foo 1.1")
+
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --verbose"
+ expect(out).to include("Using foo 1.1")
+ end
+
it "works with different load paths" do
build_repo2 do
build_plugin "testing" do |s|
@@ -58,11 +97,11 @@ RSpec.describe "bundler plugin install" do
end
end
RUBY
- s.require_paths = %w(lib src)
+ s.require_paths = %w[lib src]
s.write("src/fubar.rb")
end
end
- bundle "plugin install testing --source file://#{gem_repo2}"
+ bundle "plugin install testing --source #{file_uri_for(gem_repo2)}"
bundle "check2", "no-color" => false
expect(out).to eq("mate")
@@ -75,7 +114,7 @@ RSpec.describe "bundler plugin install" do
build_plugin "kung-foo", "1.1"
end
- bundle "plugin install foo kung-foo --version '1.0' --source file://#{gem_repo2}"
+ bundle "plugin install foo kung-foo --version '1.0' --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installing foo 1.0")
expect(out).to include("Installing kung-foo 1.0")
@@ -85,9 +124,9 @@ RSpec.describe "bundler plugin install" do
build_gem "charlie"
end
- bundle "plugin install charlie --source file://#{gem_repo2}"
+ bundle "plugin install charlie --source #{file_uri_for(gem_repo2)}", :raise_on_error => false
- expect(out).to include("plugins.rb was not found")
+ expect(err).to include("Failed to install plugin `charlie`, due to Bundler::Plugin::MalformattedPlugin (plugins.rb was not found in the plugin.)")
expect(global_plugin_gem("charlie-1.0")).not_to be_directory
@@ -104,7 +143,7 @@ RSpec.describe "bundler plugin install" do
end
end
- bundle "plugin install chaplin --source file://#{gem_repo2}"
+ bundle "plugin install chaplin --source #{file_uri_for(gem_repo2)}", :raise_on_error => false
expect(global_plugin_gem("chaplin-1.0")).not_to be_directory
@@ -118,17 +157,39 @@ RSpec.describe "bundler plugin install" do
s.write "plugins.rb"
end
- bundle "plugin install foo --git file://#{lib_path("foo-1.0")}"
+ bundle "plugin install foo --git #{file_uri_for(lib_path("foo-1.0"))}"
expect(out).to include("Installed plugin foo")
plugin_should_be_installed("foo")
end
+
+ it "installs form a local git source" do
+ build_git "foo" do |s|
+ s.write "plugins.rb"
+ end
+
+ bundle "plugin install foo --local_git #{lib_path("foo-1.0")}"
+
+ expect(out).to include("Installed plugin foo")
+ plugin_should_be_installed("foo")
+ end
+
+ it "raises an error when both git and local git sources are specified" do
+ bundle "plugin install foo --local_git /phony/path/project --git git@gitphony.com:/repo/project", :raise_on_error => false
+
+ expect(exitstatus).not_to eq(0)
+ expect(err).to eq("Remote and local plugin git sources can't be both specified")
+ end
end
context "Gemfile eval" do
+ before do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ end
+
it "installs plugins listed in gemfile" do
gemfile <<-G
- source 'file://#{gem_repo2}'
+ source '#{file_uri_for(gem_repo2)}'
plugin 'foo'
gem 'rack', "1.0.0"
G
@@ -148,8 +209,8 @@ RSpec.describe "bundler plugin install" do
build_plugin "foo", "1.1.0"
end
- install_gemfile <<-G
- source 'file://#{gem_repo2}'
+ gemfile <<-G
+ source '#{file_uri_for(gem_repo2)}'
plugin 'foo', "1.0"
G
@@ -168,12 +229,50 @@ RSpec.describe "bundler plugin install" do
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
plugin 'ga-plugin', :git => "#{lib_path("ga-plugin-1.0")}"
G
expect(out).to include("Installed plugin ga-plugin")
plugin_should_be_installed("ga-plugin")
end
+
+ it "accepts path sources" do
+ build_lib "ga-plugin" do |s|
+ s.write "plugins.rb"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ plugin 'ga-plugin', :path => "#{lib_path("ga-plugin-1.0")}"
+ G
+
+ expect(out).to include("Installed plugin ga-plugin")
+ plugin_should_be_installed("ga-plugin")
+ end
+
+ context "in deployment mode" do
+ it "installs plugins" do
+ install_gemfile <<-G
+ source '#{file_uri_for(gem_repo2)}'
+ gem 'rack', "1.0.0"
+ G
+
+ bundle "config set --local deployment true"
+ install_gemfile <<-G
+ source '#{file_uri_for(gem_repo2)}'
+ plugin 'foo'
+ gem 'rack', "1.0.0"
+ G
+
+ expect(out).to include("Installed plugin foo")
+
+ expect(out).to include("Bundle complete!")
+
+ expect(the_bundle).to include_gems("rack 1.0.0")
+ plugin_should_be_installed("foo")
+ end
+ end
end
context "inline gemfiles" do
@@ -182,20 +281,21 @@ RSpec.describe "bundler plugin install" do
require "bundler/inline"
gemfile do
- source 'file://#{gem_repo2}'
+ source '#{file_uri_for(gem_repo2)}'
plugin 'foo'
end
RUBY
- ruby code
+ ruby code, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(local_plugin_gem("foo-1.0", "plugins.rb")).to exist
end
end
describe "local plugin" do
it "is installed when inside an app" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
gemfile ""
- bundle "plugin install foo --source file://#{gem_repo2}"
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)}"
plugin_should_be_installed("foo")
expect(local_plugin_gem("foo-1.0")).to be_directory
@@ -218,7 +318,7 @@ RSpec.describe "bundler plugin install" do
end
# inside the app
- gemfile "source 'file://#{gem_repo2}'\nplugin 'fubar'"
+ gemfile "source '#{file_uri_for(gem_repo2)}'\nplugin 'fubar'"
bundle "install"
update_repo2 do
@@ -236,21 +336,16 @@ RSpec.describe "bundler plugin install" do
end
# outside the app
- Dir.chdir tmp
- bundle "plugin install fubar --source file://#{gem_repo2}"
+ bundle "plugin install fubar --source #{file_uri_for(gem_repo2)}", :dir => tmp
end
it "inside the app takes precedence over global plugin" do
- Dir.chdir bundled_app
-
bundle "shout"
expect(out).to eq("local_one")
end
it "outside the app global plugin is used" do
- Dir.chdir tmp
-
- bundle "shout"
+ bundle "shout", :dir => tmp
expect(out).to eq("global_one")
end
end
diff --git a/spec/bundler/plugins/list_spec.rb b/spec/bundler/plugins/list_spec.rb
new file mode 100644
index 0000000000..4a686415ad
--- /dev/null
+++ b/spec/bundler/plugins/list_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundler plugin list" do
+ before do
+ build_repo2 do
+ build_plugin "foo" do |s|
+ s.write "plugins.rb", <<-RUBY
+ class Foo < Bundler::Plugin::API
+ command "shout"
+
+ def exec(command, args)
+ puts "Foo shout"
+ end
+ end
+ RUBY
+ end
+ build_plugin "bar" do |s|
+ s.write "plugins.rb", <<-RUBY
+ class Bar < Bundler::Plugin::API
+ command "scream"
+
+ def exec(command, args)
+ puts "Bar scream"
+ end
+ end
+ RUBY
+ end
+ end
+ end
+
+ context "no plugins installed" do
+ it "shows proper no plugins installed message" do
+ bundle "plugin list"
+
+ expect(out).to include("No plugins installed")
+ end
+ end
+
+ context "single plugin installed" do
+ it "shows plugin name with commands list" do
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)}"
+ plugin_should_be_installed("foo")
+ bundle "plugin list"
+
+ expected_output = "foo\n-----\n shout"
+ expect(out).to include(expected_output)
+ end
+ end
+
+ context "multiple plugins installed" do
+ it "shows plugin names with commands list" do
+ bundle "plugin install foo bar --source #{file_uri_for(gem_repo2)}"
+ plugin_should_be_installed("foo", "bar")
+ bundle "plugin list"
+
+ expected_output = "foo\n-----\n shout\n\nbar\n-----\n scream"
+ expect(out).to include(expected_output)
+ end
+ end
+end
diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb
index 2ae34caf73..7d098997ec 100644
--- a/spec/bundler/plugins/source/example_spec.rb
+++ b/spec/bundler/plugins/source/example_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "real source plugins" do
context "with a minimal source plugin" do
@@ -7,7 +6,6 @@ RSpec.describe "real source plugins" do
build_repo2 do
build_plugin "bundler-source-mpath" do |s|
s.write "plugins.rb", <<-RUBY
- require "fileutils"
require "bundler-source-mpath"
class MPath < Bundler::Plugin::API
@@ -35,8 +33,13 @@ RSpec.describe "real source plugins" do
def install(spec, opts)
mkdir_p(install_path.parent)
+ require 'fileutils'
FileUtils.cp_r(path, install_path)
+ spec_path = install_path.join("\#{spec.full_name}.gemspec")
+ spec_path.open("wb") {|f| f.write spec.to_ruby }
+ spec.loaded_from = spec_path.to_s
+
post_install(spec)
nil
@@ -49,7 +52,7 @@ RSpec.describe "real source plugins" do
build_lib "a-path-gem"
gemfile <<-G
- source "file://#{gem_repo2}" # plugin source
+ source "#{file_uri_for(gem_repo2)}" # plugin source
source "#{lib_path("a-path-gem-1.0")}", :type => :mpath do
gem "a-path-gem"
end
@@ -67,7 +70,7 @@ RSpec.describe "real source plugins" do
it "writes to lock file" do
bundle "install"
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PLUGIN SOURCE
remote: #{lib_path("a-path-gem-1.0")}
type: mpath
@@ -75,11 +78,11 @@ RSpec.describe "real source plugins" do
a-path-gem (1.0)
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
a-path-gem!
@@ -94,18 +97,18 @@ RSpec.describe "real source plugins" do
run <<-RUBY
puts Bundler.rubygems.find_name('a-path-gem').first.full_gem_path
RUBY
- expect(out).to eq(bundle("show a-path-gem"))
+ expect(out).to eq(bundle("info a-path-gem --path"))
end
it "installs the gem executables" do
- build_lib "gem-with-bin" do |s|
+ build_lib "gem_with_bin" do |s|
s.executables = ["foo"]
end
install_gemfile <<-G
- source "file://#{gem_repo2}" # plugin source
- source "#{lib_path("gem-with-bin-1.0")}", :type => :mpath do
- gem "gem-with-bin"
+ source "#{file_uri_for(gem_repo2)}" # plugin source
+ source "#{lib_path("gem_with_bin-1.0")}", :type => :mpath do
+ gem "gem_with_bin"
end
G
@@ -114,10 +117,11 @@ RSpec.describe "real source plugins" do
end
describe "bundle cache/package" do
- let(:uri_hash) { Digest::SHA1.hexdigest(lib_path("a-path-gem-1.0").to_s) }
+ let(:uri_hash) { Digest(:SHA1).hexdigest(lib_path("a-path-gem-1.0").to_s) }
it "copies repository to vendor cache and uses it" do
bundle "install"
- bundle "cache --all"
+ bundle "config set cache_all true"
+ bundle :cache
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}/.git")).not_to exist
@@ -127,9 +131,11 @@ RSpec.describe "real source plugins" do
expect(the_bundle).to include_gems("a-path-gem 1.0")
end
- it "copies repository to vendor cache and uses it even when installed with bundle --path" do
- bundle "install --path vendor/bundle"
- bundle "cache --all"
+ it "copies repository to vendor cache and uses it even when installed with `path` configured" do
+ bundle "config set --local path vendor/bundle"
+ bundle :install
+ bundle "config set cache_all true"
+ bundle :cache
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
@@ -138,8 +144,10 @@ RSpec.describe "real source plugins" do
end
it "bundler package copies repository to vendor cache" do
- bundle "install --path vendor/bundle"
- bundle "package --all"
+ bundle "config set --local path vendor/bundle"
+ bundle :install
+ bundle "config set cache_all true"
+ bundle :cache
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
@@ -158,7 +166,7 @@ RSpec.describe "real source plugins" do
a-path-gem (1.0)
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
PLATFORMS
@@ -185,6 +193,8 @@ RSpec.describe "real source plugins" do
build_repo2 do
build_plugin "bundler-source-gitp" do |s|
s.write "plugins.rb", <<-RUBY
+ require "open3"
+
class SPlugin < Bundler::Plugin::API
source "gitp"
@@ -224,9 +234,11 @@ RSpec.describe "real source plugins" do
mkdir_p(install_path.dirname)
rm_rf(install_path)
`git clone --no-checkout --quiet "\#{cache_path}" "\#{install_path}"`
- Dir.chdir install_path do
- `git reset --hard \#{revision}`
- end
+ Open3.capture2e("git reset --hard \#{revision}", :chdir => install_path)
+
+ spec_path = install_path.join("\#{spec.full_name}.gemspec")
+ spec_path.open("wb") {|f| f.write spec.to_ruby }
+ spec.loaded_from = spec_path.to_s
post_install(spec)
@@ -276,9 +288,8 @@ RSpec.describe "real source plugins" do
cache_repo
end
- Dir.chdir cache_path do
- `git rev-parse --verify \#{@ref}`.strip
- end
+ output, _status = Open3.capture2e("git rev-parse --verify \#{@ref}", :chdir => cache_path)
+ output.strip
end
def base_name
@@ -314,8 +325,8 @@ RSpec.describe "real source plugins" do
build_git "ma-gitp-gem"
gemfile <<-G
- source "file://#{gem_repo2}" # plugin source
- source "file://#{lib_path("ma-gitp-gem-1.0")}", :type => :gitp do
+ source "#{file_uri_for(gem_repo2)}" # plugin source
+ source "#{file_uri_for(lib_path("ma-gitp-gem-1.0"))}", :type => :gitp do
gem "ma-gitp-gem"
end
G
@@ -331,20 +342,20 @@ RSpec.describe "real source plugins" do
revision = revision_for(lib_path("ma-gitp-gem-1.0"))
bundle "install"
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PLUGIN SOURCE
- remote: file://#{lib_path("ma-gitp-gem-1.0")}
+ remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))}
type: gitp
revision: #{revision}
specs:
ma-gitp-gem (1.0)
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
ma-gitp-gem!
@@ -359,14 +370,14 @@ RSpec.describe "real source plugins" do
revision = revision_for(lib_path("ma-gitp-gem-1.0"))
lockfile <<-G
PLUGIN SOURCE
- remote: file://#{lib_path("ma-gitp-gem-1.0")}
+ remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))}
type: gitp
revision: #{revision}
specs:
ma-gitp-gem (1.0)
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
PLATFORMS
@@ -390,7 +401,7 @@ RSpec.describe "real source plugins" do
bundle "install"
run <<-RUBY
- require 'ma-gitp-gem'
+ require 'ma/gitp/gem'
puts "WIN" unless defined?(MAGITPGEM_PREV_REF)
RUBY
expect(out).to eq("WIN")
@@ -401,7 +412,7 @@ RSpec.describe "real source plugins" do
bundle "update ma-gitp-gem"
run <<-RUBY
- require 'ma-gitp-gem'
+ require 'ma/gitp/gem'
puts "WIN" if defined?(MAGITPGEM_PREV_REF)
RUBY
expect(out).to eq("WIN")
@@ -410,8 +421,8 @@ RSpec.describe "real source plugins" do
it "updates the deps on change in gemfile" do
update_git "ma-gitp-gem", "1.1", :path => lib_path("ma-gitp-gem-1.0"), :gemspec => true
gemfile <<-G
- source "file://#{gem_repo2}" # plugin source
- source "file://#{lib_path("ma-gitp-gem-1.0")}", :type => :gitp do
+ source "#{file_uri_for(gem_repo2)}" # plugin source
+ source "#{file_uri_for(lib_path("ma-gitp-gem-1.0"))}", :type => :gitp do
gem "ma-gitp-gem", "1.1"
end
G
@@ -427,13 +438,14 @@ RSpec.describe "real source plugins" do
ref = git.ref_for("master", 11)
install_gemfile <<-G
- source "file://#{gem_repo2}" # plugin source
+ source "#{file_uri_for(gem_repo2)}" # plugin source
source '#{lib_path("foo-1.0")}', :type => :gitp do
gem "foo"
end
G
- bundle "cache --all"
+ bundle "config set cache_all true"
+ bundle :cache
expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist
expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.bundlecache")).to be_file
diff --git a/spec/bundler/plugins/source_spec.rb b/spec/bundler/plugins/source_spec.rb
index 0448bc409a..14643e5c81 100644
--- a/spec/bundler/plugins/source_spec.rb
+++ b/spec/bundler/plugins/source_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundler source plugin" do
describe "plugins dsl eval for #source with :type option" do
@@ -17,11 +16,12 @@ RSpec.describe "bundler source plugin" do
it "installs bundler-source-* gem when no handler for source is present" do
install_gemfile <<-G
- source "file://#{gem_repo2}"
- source "file://#{lib_path("gitp")}", :type => :psource do
+ source "#{file_uri_for(gem_repo2)}"
+ source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do
end
G
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
plugin_should_be_installed("bundler-source-psource")
end
@@ -38,8 +38,8 @@ RSpec.describe "bundler source plugin" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
- source "file://#{lib_path("gitp")}", :type => :psource do
+ source "#{file_uri_for(gem_repo2)}"
+ source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do
end
G
@@ -62,11 +62,11 @@ RSpec.describe "bundler source plugin" do
context "explicit presence in gemfile" do
before do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
plugin "another-psource"
- source "file://#{lib_path("gitp")}", :type => :psource do
+ source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do
end
G
end
@@ -76,6 +76,7 @@ RSpec.describe "bundler source plugin" do
end
it "installs the explicit one" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
plugin_should_be_installed("another-psource")
end
@@ -87,11 +88,11 @@ RSpec.describe "bundler source plugin" do
context "explicit default source" do
before do
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
plugin "bundler-source-psource"
- source "file://#{lib_path("gitp")}", :type => :psource do
+ source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do
end
G
end
@@ -101,6 +102,7 @@ RSpec.describe "bundler source plugin" do
end
it "installs the default one" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
plugin_should_be_installed("bundler-source-psource")
end
end
diff --git a/spec/bundler/plugins/uninstall_spec.rb b/spec/bundler/plugins/uninstall_spec.rb
new file mode 100644
index 0000000000..8180241911
--- /dev/null
+++ b/spec/bundler/plugins/uninstall_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundler plugin uninstall" do
+ before do
+ build_repo2 do
+ build_plugin "foo"
+ build_plugin "kung-foo"
+ end
+ end
+
+ it "shows proper error message when plugins are not specified" do
+ bundle "plugin uninstall"
+ expect(err).to include("No plugins to uninstall")
+ end
+
+ it "uninstalls specified plugins" do
+ bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}"
+ plugin_should_be_installed("foo")
+ plugin_should_be_installed("kung-foo")
+
+ bundle "plugin uninstall foo"
+ expect(out).to include("Uninstalled plugin foo")
+ plugin_should_not_be_installed("foo")
+ plugin_should_be_installed("kung-foo")
+ end
+
+ it "shows proper message when plugin is not installed" do
+ bundle "plugin uninstall foo"
+ expect(err).to include("Plugin foo is not installed")
+ plugin_should_not_be_installed("foo")
+ end
+
+ describe "with --all" do
+ it "uninstalls all installed plugins" do
+ bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}"
+ plugin_should_be_installed("foo")
+ plugin_should_be_installed("kung-foo")
+
+ bundle "plugin uninstall --all"
+ plugin_should_not_be_installed("foo")
+ plugin_should_not_be_installed("kung-foo")
+ end
+
+ it "shows proper no plugins installed message when no plugins installed" do
+ bundle "plugin uninstall --all"
+ expect(out).to include("No plugins installed")
+ end
+ end
+end
diff --git a/spec/bundler/quality_es_spec.rb b/spec/bundler/quality_es_spec.rb
new file mode 100644
index 0000000000..90968e6270
--- /dev/null
+++ b/spec/bundler/quality_es_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+RSpec.describe "La biblioteca si misma" do
+ def check_for_expendable_words(filename)
+ failing_line_message = []
+ useless_words = %w[
+ básicamente
+ claramente
+ sólo
+ solamente
+ obvio
+ obviamente
+ fácil
+ fácilmente
+ sencillamente
+ simplemente
+ ]
+ pattern = /\b#{Regexp.union(useless_words)}\b/i
+
+ File.readlines(filename).each_with_index do |line, number|
+ next unless word_found = pattern.match(line)
+ failing_line_message << "#{filename}:#{number.succ} contiene '#{word_found}'. Esta palabra tiene un significado subjetivo y es mejor obviarla en textos técnicos."
+ end
+
+ failing_line_message unless failing_line_message.empty?
+ end
+
+ def check_for_specific_pronouns(filename)
+ failing_line_message = []
+ specific_pronouns = /\b(él|ella|ellos|ellas)\b/i
+
+ File.readlines(filename).each_with_index do |line, number|
+ next unless word_found = specific_pronouns.match(line)
+ failing_line_message << "#{filename}:#{number.succ} contiene '#{word_found}'. Use pronombres más genéricos en la documentación."
+ end
+
+ failing_line_message unless failing_line_message.empty?
+ end
+
+ it "mantiene la calidad de lenguaje de la documentación" do
+ included = /ronn/
+ error_messages = []
+ man_tracked_files.each do |filename|
+ next unless filename =~ included
+ error_messages << check_for_expendable_words(filename)
+ error_messages << check_for_specific_pronouns(filename)
+ end
+ expect(error_messages.compact).to be_well_formed
+ end
+
+ it "mantiene la calidad de lenguaje de oraciones usadas en el código fuente" do
+ error_messages = []
+ exempt = /vendor/
+ lib_tracked_files.each do |filename|
+ next if filename =~ exempt
+ error_messages << check_for_expendable_words(filename)
+ error_messages << check_for_specific_pronouns(filename)
+ end
+ expect(error_messages.compact).to be_well_formed
+ end
+end
diff --git a/spec/bundler/quality_spec.rb b/spec/bundler/quality_spec.rb
index b87b4a0731..62f3722a39 100644
--- a/spec/bundler/quality_spec.rb
+++ b/spec/bundler/quality_spec.rb
@@ -1,42 +1,8 @@
# frozen_string_literal: true
-require "spec_helper"
-if defined?(Encoding) && Encoding.default_external.name != "UTF-8"
- # Poor man's ruby -E UTF-8, since it works on 1.8.7
- Encoding.default_external = Encoding.find("UTF-8")
-end
+require "set"
RSpec.describe "The library itself" do
- def check_for_spec_defs_with_single_quotes(filename)
- failing_lines = []
-
- File.readlines(filename).each_with_index do |line, number|
- failing_lines << number + 1 if line =~ /^ *(describe|it|context) {1}'{1}/
- end
-
- return if failing_lines.empty?
- "#{filename} uses inconsistent single quotes on lines #{failing_lines.join(", ")}"
- end
-
- def check_for_debugging_mechanisms(filename)
- debugging_mechanisms_regex = /
- (binding\.pry)|
- (debugger)|
- (sleep\s*\(?\d+)|
- (fit\s*\(?("|\w))
- /x
-
- failing_lines = []
- File.readlines(filename).each_with_index do |line, number|
- if line =~ debugging_mechanisms_regex && !line.end_with?("# ignore quality_spec\n")
- failing_lines << number + 1
- end
- end
-
- return if failing_lines.empty?
- "#{filename} has debugging mechanisms (like binding.pry, sleep, debugger, rspec focusing, etc.) on lines #{failing_lines.join(", ")}"
- end
-
def check_for_git_merge_conflicts(filename)
merge_conflicts_regex = /
<<<<<<<|
@@ -45,7 +11,7 @@ RSpec.describe "The library itself" do
/x
failing_lines = []
- File.readlines(filename).each_with_index do |line, number|
+ each_line(filename) do |line, number|
failing_lines << number + 1 if line =~ merge_conflicts_regex
end
@@ -55,7 +21,7 @@ RSpec.describe "The library itself" do
def check_for_tab_characters(filename)
failing_lines = []
- File.readlines(filename).each_with_index do |line, number|
+ each_line(filename) do |line, number|
failing_lines << number + 1 if line =~ /\t/
end
@@ -65,9 +31,8 @@ RSpec.describe "The library itself" do
def check_for_extra_spaces(filename)
failing_lines = []
- File.readlines(filename).each_with_index do |line, number|
+ each_line(filename) do |line, number|
next if line =~ /^\s+#.*\s+\n$/
- next if %w(LICENCE.md).include?(line)
failing_lines << number + 1 if line =~ /\s+\n$/
end
@@ -75,9 +40,21 @@ RSpec.describe "The library itself" do
"#{filename} has spaces on the EOL on lines #{failing_lines.join(", ")}"
end
+ def check_for_straneous_quotes(filename)
+ return if File.expand_path(filename) == __FILE__
+
+ failing_lines = []
+ each_line(filename) do |line, number|
+ failing_lines << number + 1 if line =~ /’/
+ end
+
+ return if failing_lines.empty?
+ "#{filename} has an straneous quote on lines #{failing_lines.join(", ")}"
+ end
+
def check_for_expendable_words(filename)
failing_line_message = []
- useless_words = %w(
+ useless_words = %w[
actually
basically
clearly
@@ -85,12 +62,12 @@ RSpec.describe "The library itself" do
obviously
really
simply
- )
+ ]
pattern = /\b#{Regexp.union(useless_words)}\b/i
- File.readlines(filename).each_with_index do |line, number|
+ each_line(filename) do |line, number|
next unless word_found = pattern.match(line)
- failing_line_message << "#{filename} has '#{word_found}' on line #{number + 1}. Avoid using these kinds of weak modifiers."
+ failing_line_message << "#{filename}:#{number.succ} has '#{word_found}'. Avoid using these kinds of weak modifiers."
end
failing_line_message unless failing_line_message.empty?
@@ -100,164 +77,171 @@ RSpec.describe "The library itself" do
failing_line_message = []
specific_pronouns = /\b(he|she|his|hers|him|her|himself|herself)\b/i
- File.readlines(filename).each_with_index do |line, number|
+ each_line(filename) do |line, number|
next unless word_found = specific_pronouns.match(line)
- failing_line_message << "#{filename} has '#{word_found}' on line #{number + 1}. Use more generic pronouns in documentation."
+ failing_line_message << "#{filename}:#{number.succ} has '#{word_found}'. Use more generic pronouns in documentation."
end
failing_line_message unless failing_line_message.empty?
end
- RSpec::Matchers.define :be_well_formed do
- match(&:empty?)
-
- failure_message do |actual|
- actual.join("\n")
- end
- end
-
- it "has no malformed whitespace", :ruby_repo do
- exempt = /\.gitmodules|\.marshal|fixtures|vendor|ssl_certs|LICENSE/
+ it "has no malformed whitespace" do
+ exempt = /\.gitmodules|fixtures|vendor|LICENSE|vcr_cassettes|rbreadline\.diff|index\.txt$/
error_messages = []
- Dir.chdir(File.expand_path("../..", __FILE__)) do
- `git ls-files -z`.split("\x0").each do |filename|
- next if filename =~ exempt
- error_messages << check_for_tab_characters(filename)
- error_messages << check_for_extra_spaces(filename)
- end
+ tracked_files.each do |filename|
+ next if filename =~ exempt
+ error_messages << check_for_tab_characters(filename)
+ error_messages << check_for_extra_spaces(filename)
end
expect(error_messages.compact).to be_well_formed
end
- it "uses double-quotes consistently in specs", :ruby_repo do
- included = /spec/
+ it "has no estraneous quotes" do
+ exempt = /vendor|vcr_cassettes|LICENSE|rbreadline\.diff/
error_messages = []
- Dir.chdir(File.expand_path("../", __FILE__)) do
- `git ls-files -z`.split("\x0").each do |filename|
- next unless filename =~ included
- error_messages << check_for_spec_defs_with_single_quotes(filename)
- end
- end
- expect(error_messages.compact).to be_well_formed
- end
-
- it "does not include any leftover debugging or development mechanisms", :ruby_repo do
- exempt = %r{quality_spec.rb|support/helpers}
- error_messages = []
- Dir.chdir(File.expand_path("../", __FILE__)) do
- `git ls-files -z`.split("\x0").each do |filename|
- next if filename =~ exempt
- error_messages << check_for_debugging_mechanisms(filename)
- end
+ tracked_files.each do |filename|
+ next if filename =~ exempt
+ error_messages << check_for_straneous_quotes(filename)
end
expect(error_messages.compact).to be_well_formed
end
- it "does not include any unresolved merge conflicts", :ruby_repo do
+ it "does not include any unresolved merge conflicts" do
error_messages = []
- exempt = %r{lock/lockfile_spec|quality_spec}
- Dir.chdir(File.expand_path("../", __FILE__)) do
- `git ls-files -z`.split("\x0").each do |filename|
- next if filename =~ exempt
- error_messages << check_for_git_merge_conflicts(filename)
- end
+ exempt = %r{lock/lockfile_spec|quality_spec|vcr_cassettes|\.ronn|lockfile_parser\.rb}
+ tracked_files.each do |filename|
+ next if filename =~ exempt
+ error_messages << check_for_git_merge_conflicts(filename)
end
expect(error_messages.compact).to be_well_formed
end
- it "maintains language quality of the documentation", :ruby_repo do
+ it "maintains language quality of the documentation" do
included = /ronn/
error_messages = []
- Dir.chdir(File.expand_path("../../man", __FILE__)) do
- `git ls-files -z`.split("\x0").each do |filename|
- next unless filename =~ included
- error_messages << check_for_expendable_words(filename)
- error_messages << check_for_specific_pronouns(filename)
- end
+ man_tracked_files.each do |filename|
+ next unless filename =~ included
+ error_messages << check_for_expendable_words(filename)
+ error_messages << check_for_specific_pronouns(filename)
end
expect(error_messages.compact).to be_well_formed
end
- it "maintains language quality of sentences used in source code", :ruby_repo do
+ it "maintains language quality of sentences used in source code" do
error_messages = []
- exempt = /vendor/
- Dir.chdir(File.expand_path("../../lib", __FILE__)) do
- `git ls-files -z`.split("\x0").each do |filename|
- next if filename =~ exempt
- error_messages << check_for_expendable_words(filename)
- error_messages << check_for_specific_pronouns(filename)
- end
+ exempt = /vendor|vcr_cassettes|CODE_OF_CONDUCT/
+ lib_tracked_files.each do |filename|
+ next if filename =~ exempt
+ error_messages << check_for_expendable_words(filename)
+ error_messages << check_for_specific_pronouns(filename)
end
expect(error_messages.compact).to be_well_formed
end
- it "documents all used settings", :ruby_repo do
- exemptions = %w(
+ it "documents all used settings" do
+ exemptions = %w[
+ forget_cli_options
+ gem.changelog
+ gem.ci
gem.coc
+ gem.linter
gem.mit
+ gem.rubocop
+ gem.test
+ git.allow_insecure
inline
- warned_version
- )
+ trust-policy
+ use_gem_version_promoter_for_major_updates
+ ]
all_settings = Hash.new {|h, k| h[k] = [] }
- documented_settings = exemptions
+ documented_settings = []
Bundler::Settings::BOOL_KEYS.each {|k| all_settings[k] << "in Bundler::Settings::BOOL_KEYS" }
Bundler::Settings::NUMBER_KEYS.each {|k| all_settings[k] << "in Bundler::Settings::NUMBER_KEYS" }
+ Bundler::Settings::ARRAY_KEYS.each {|k| all_settings[k] << "in Bundler::Settings::ARRAY_KEYS" }
+ Bundler::Settings::STRING_KEYS.each {|k| all_settings[k] << "in Bundler::Settings::STRING_KEYS" }
- Dir.chdir(File.expand_path("../../lib", __FILE__)) do
- key_pattern = /([a-z\._-]+)/i
- `git ls-files -z`.split("\x0").each do |filename|
- File.readlines(filename).each_with_index do |line, number|
- line.scan(/Bundler\.settings\[:#{key_pattern}\]/).flatten.each {|s| all_settings[s] << "referenced at `lib/#{filename}:#{number.succ}`" }
- end
+ key_pattern = /([a-z\._-]+)/i
+ lib_tracked_files.each do |filename|
+ each_line(filename) do |line, number|
+ line.scan(/Bundler\.settings\[:#{key_pattern}\]/).flatten.each {|s| all_settings[s] << "referenced at `#{filename}:#{number.succ}`" }
end
- documented_settings = File.read("../man/bundle-config.ronn").scan(/^\* `#{key_pattern}`/).flatten
end
+ documented_settings = File.read("lib/bundler/man/bundle-config.1.ronn")[/LIST OF AVAILABLE KEYS.*/m].scan(/^\* `#{key_pattern}`/).flatten
- documented_settings.each {|s| all_settings.delete(s) }
- exemptions.each {|s| all_settings.delete(s) }
+ documented_settings.each do |s|
+ all_settings.delete(s)
+ expect(exemptions.delete(s)).to be_nil, "setting #{s} was exempted but was actually documented"
+ end
+
+ exemptions.each do |s|
+ expect(all_settings.delete(s)).to be_truthy, "setting #{s} was exempted but unused"
+ end
error_messages = all_settings.map do |setting, refs|
"The `#{setting}` setting is undocumented\n\t- #{refs.join("\n\t- ")}\n"
end
expect(error_messages.sort).to be_well_formed
+
+ expect(documented_settings).to be_sorted
end
- it "can still be built", :ruby_repo do
- Dir.chdir(root) do
- begin
- gem_command! :build, "bundler.gemspec"
- if Bundler.rubygems.provides?(">= 2.4")
- # older rubygems have weird warnings, and we won't actually be using them
- # to build the gem for releases anyways
- expect(err).to be_empty, "bundler should build as a gem without warnings, but\n#{err}"
- end
- ensure
- # clean up the .gem generated
- FileUtils.rm("bundler-#{Bundler::VERSION}.gem")
- end
+ it "can still be built" do
+ with_built_bundler do |_gem_path|
+ expect(err).to be_empty, "bundler should build as a gem without warnings, but\n#{err}"
end
end
- it "does not contain any warnings", :ruby_repo do
- Dir.chdir(root.join("lib")) do
- exclusions = %w(
- bundler/capistrano.rb
- bundler/gem_tasks.rb
- bundler/vlad.rb
- )
- lib_files = `git ls-files -z`.split("\x0").grep(/\.rb$/) - exclusions
- lib_files.reject! {|f| f.start_with?("bundler/vendor") }
- lib_files.map! {|f| f.chomp(".rb") }
- sys_exec!("ruby -w -I.") do |input, _, _|
- lib_files.each do |f|
- input.puts "require '#{f}'"
- end
+ it "ships the correct set of files" do
+ git_list = git_ls_files(ruby_core? ? "lib/bundler lib/bundler.rb libexec/bundle*" : "lib exe CHANGELOG.md LICENSE.md README.md bundler.gemspec")
+
+ gem_list = loaded_gemspec.files
+
+ expect(git_list.sort).to eq(gem_list.sort)
+ end
+
+ it "does not contain any warnings" do
+ exclusions = %w[
+ lib/bundler/capistrano.rb
+ lib/bundler/deployment.rb
+ lib/bundler/gem_tasks.rb
+ lib/bundler/vlad.rb
+ lib/bundler/templates/gems.rb
+ ]
+ files_to_require = lib_tracked_files.grep(/\.rb$/) - exclusions
+ files_to_require.reject! {|f| f.start_with?("lib/bundler/vendor") }
+ files_to_require.map! {|f| File.expand_path(f, source_root) }
+ files_to_require.sort!
+ sys_exec("ruby -w") do |input, _, _|
+ files_to_require.each do |f|
+ input.puts "require '#{f}'"
end
+ end
+
+ warnings = last_command.stdboth.split("\n")
+ # ignore warnings around deprecated Object#=~ method in RubyGems
+ warnings.reject! {|w| w =~ %r{rubygems\/version.rb.*deprecated\ Object#=~} }
- expect(@err.split("\n")).to be_well_formed
- expect(@out.split("\n")).to be_well_formed
+ expect(warnings).to be_well_formed
+ end
+
+ it "does not use require internally, but require_relative" do
+ exempt = %r{templates/|\.5|\.1|vendor/}
+ all_bad_requires = []
+ lib_tracked_files.each do |filename|
+ next if filename =~ exempt
+ each_line(filename) do |line, number|
+ line.scan(/^ *require "bundler/).each { all_bad_requires << "#{filename}:#{number.succ}" }
+ end
end
+
+ expect(all_bad_requires).to be_empty, "#{all_bad_requires.size} internal requires that should use `require_relative`: #{all_bad_requires}"
+ end
+
+ private
+
+ def each_line(filename, &block)
+ File.readlines(filename, :encoding => "UTF-8").each_with_index(&block)
end
end
diff --git a/spec/bundler/realworld/dependency_api_spec.rb b/spec/bundler/realworld/dependency_api_spec.rb
index 468fa3644c..08c6acf190 100644
--- a/spec/bundler/realworld/dependency_api_spec.rb
+++ b/spec/bundler/realworld/dependency_api_spec.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require "spec_helper"
+
+require_relative "../support/silent_logger"
RSpec.describe "gemcutter's dependency API", :realworld => true do
context "when Gemcutter API takes too long to respond" do
@@ -9,8 +10,8 @@ RSpec.describe "gemcutter's dependency API", :realworld => true do
port = find_unused_port
@server_uri = "http://127.0.0.1:#{port}"
- require File.expand_path("../../support/artifice/endpoint_timeout", __FILE__)
- require "thread"
+ require_relative "../support/artifice/endpoint_timeout"
+
@t = Thread.new do
server = Rack::Server.start(:app => EndpointTimeout,
:Host => "0.0.0.0",
@@ -23,6 +24,7 @@ RSpec.describe "gemcutter's dependency API", :realworld => true do
@t.run
wait_for_server("127.0.0.1", port)
+ bundle "config set timeout 1"
end
after do
@@ -32,16 +34,11 @@ RSpec.describe "gemcutter's dependency API", :realworld => true do
end
it "times out and falls back on the modern index" do
- gemfile <<-G
+ install_gemfile <<-G, :artifice => nil
source "#{@server_uri}"
gem "rack"
-
- old_v, $VERBOSE = $VERBOSE, nil
- Bundler::Fetcher.api_timeout = 1
- $VERBOSE = old_v
G
- bundle :install
expect(out).to include("Fetching source index from #{@server_uri}/")
expect(the_bundle).to include_gems "rack 1.0.0"
end
diff --git a/spec/bundler/realworld/double_check_spec.rb b/spec/bundler/realworld/double_check_spec.rb
new file mode 100644
index 0000000000..d7f28d10bb
--- /dev/null
+++ b/spec/bundler/realworld/double_check_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+RSpec.describe "double checking sources", :realworld => true do
+ it "finds already-installed gems" do
+ create_file("rails.gemspec", <<-RUBY)
+ Gem::Specification.new do |s|
+ s.name = "rails"
+ s.version = "5.1.4"
+ s.summary = ""
+ s.description = ""
+ s.author = ""
+ s.add_dependency "actionpack", "5.1.4"
+ end
+ RUBY
+
+ create_file("actionpack.gemspec", <<-RUBY)
+ Gem::Specification.new do |s|
+ s.name = "actionpack"
+ s.version = "5.1.4"
+ s.summary = ""
+ s.description = ""
+ s.author = ""
+ s.add_dependency "rack", "~> 2.0.0"
+ end
+ RUBY
+
+ cmd = <<-RUBY
+ require "#{entrypoint}"
+ require "#{spec_dir}/support/artifice/vcr"
+ require "#{entrypoint}/inline"
+ gemfile(true) do
+ source "https://rubygems.org"
+ gem "rails", path: "."
+ end
+ RUBY
+
+ ruby cmd
+ ruby cmd
+ end
+end
diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb
index 302fd57cf0..df5eeda9fe 100644
--- a/spec/bundler/realworld/edgecases_spec.rb
+++ b/spec/bundler/realworld/edgecases_spec.rb
@@ -1,78 +1,45 @@
# frozen_string_literal: true
-require "spec_helper"
-RSpec.describe "real world edgecases", :realworld => true, :sometimes => true do
+RSpec.describe "real world edgecases", :realworld => true do
def rubygems_version(name, requirement)
- require "bundler/source/rubygems/remote"
- require "bundler/fetcher"
- source = Bundler::Source::Rubygems::Remote.new(URI("https://rubygems.org"))
- fetcher = Bundler::Fetcher.new(source)
- index = fetcher.specs([name], nil)
- rubygem = index.search(Gem::Dependency.new(name, requirement)).last
- if rubygem.nil?
- raise "Could not find #{name} (#{requirement}) on rubygems.org!\n" \
- "Found specs:\n#{index.send(:specs).inspect}"
- end
- "#{name} (#{rubygem.version})"
+ ruby <<-RUBY
+ require "#{spec_dir}/support/artifice/vcr"
+ require "#{entrypoint}"
+ require "#{entrypoint}/source/rubygems/remote"
+ require "#{entrypoint}/fetcher"
+ rubygem = Bundler.ui.silence do
+ source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org"))
+ fetcher = Bundler::Fetcher.new(source)
+ index = fetcher.specs([#{name.dump}], nil)
+ index.search(Gem::Dependency.new(#{name.dump}, #{requirement.dump})).last
+ end
+ if rubygem.nil?
+ raise "Could not find #{name} (#{requirement}) on rubygems.org!\n" \
+ "Found specs:\n\#{index.send(:specs).inspect}"
+ end
+ puts "#{name} (\#{rubygem.version})"
+ RUBY
end
- # there is no rbx-relative-require gem that will install on 1.9
- it "ignores extra gems with bad platforms", :ruby => "~> 1.8.7" do
+ it "resolves dependencies correctly" do
gemfile <<-G
source "https://rubygems.org"
- gem "linecache", "0.46"
- G
- bundle :lock
- expect(err).to lack_errors
- expect(exitstatus).to eq(0) if exitstatus
- end
- # https://github.com/bundler/bundler/issues/1202
- it "bundle cache works with rubygems 1.3.7 and pre gems",
- :ruby => "~> 1.8.7", :rubygems => "~> 1.3.7" do
- install_gemfile <<-G
- source "https://rubygems.org"
- gem "rack", "1.3.0.beta2"
- gem "will_paginate", "3.0.pre2"
- G
- bundle :cache
- expect(out).not_to include("Removing outdated .gem files from vendor/cache")
- end
-
- # https://github.com/bundler/bundler/issues/1486
- # this is a hash collision that only manifests on 1.8.7
- it "finds the correct child versions", :ruby => "~> 1.8.7" do
- gemfile <<-G
- source "https://rubygems.org"
-
- gem 'i18n', '~> 0.6.0'
- gem 'activesupport', '~> 3.0.5'
- gem 'activerecord', '~> 3.0.5'
- gem 'builder', '~> 2.1.2'
- G
- bundle :lock
- expect(lockfile).to include("activemodel (3.0.5)")
- end
-
- it "resolves dependencies correctly", :ruby => "1.9.3" do
- gemfile <<-G
- source "https://rubygems.org"
-
- gem 'rails', '~> 3.0'
+ gem 'rails', '~> 5.0'
gem 'capybara', '~> 2.2.0'
gem 'rack-cache', '1.2.0' # last version that works on Ruby 1.9
G
- bundle! :lock
- expect(lockfile).to include(rubygems_version("rails", "~> 3.0"))
+ bundle :lock
+ expect(lockfile).to include(rubygems_version("rails", "~> 5.0"))
expect(lockfile).to include("capybara (2.2.1)")
end
- it "installs the latest version of gxapi_rails", :ruby => "1.9.3" do
+ it "installs the latest version of gxapi_rails" do
gemfile <<-G
source "https://rubygems.org"
gem "sass-rails"
- gem "rails", "~> 3"
+ gem "rails", "~> 5"
gem "gxapi_rails", "< 0.1.0" # 0.1.0 was released way after the test was written
gem 'rack-cache', '1.2.0' # last version that works on Ruby 1.9
G
@@ -94,8 +61,10 @@ RSpec.describe "real world edgecases", :realworld => true, :sometimes => true do
expect(lockfile).to include(rubygems_version("activesupport", "~> 3.0"))
end
- it "is able to update a top-level dependency when there is a conflict on a shared transitive child", :ruby => "2.1" do
- # from https://github.com/bundler/bundler/issues/5031
+ it "is able to update a top-level dependency when there is a conflict on a shared transitive child" do
+ # from https://github.com/rubygems/bundler/issues/5031
+
+ system_gems "bundler-2.99.0"
gemfile <<-G
source "https://rubygems.org"
@@ -185,7 +154,7 @@ RSpec.describe "real world edgecases", :realworld => true, :sometimes => true do
activemodel (= 4.2.7.1)
activerecord (= 4.2.7.1)
activesupport (= 4.2.7.1)
- bundler (>= 1.3.0, < 2.0)
+ bundler (>= 1.3.0, < 3.0)
railties (= 4.2.7.1)
sprockets-rails
rails-deprecated_sanitizer (1.0.3)
@@ -220,163 +189,339 @@ RSpec.describe "real world edgecases", :realworld => true, :sometimes => true do
DEPENDENCIES
paperclip (~> 5.1.0)
rails (~> 4.2.7.1)
-
- BUNDLED WITH
- 1.13.1
L
- bundle! "lock --update paperclip"
+ bundle "lock --update paperclip", :env => { "BUNDLER_VERSION" => "2.99.0" }
expect(lockfile).to include(rubygems_version("paperclip", "~> 5.1.0"))
end
- # https://github.com/bundler/bundler/issues/1500
- it "does not fail install because of gem plugins" do
- realworld_system_gems("open_gem --version 1.4.2", "rake --version 0.9.2")
- gemfile <<-G
+ it "outputs a helpful error message when gems have invalid gemspecs" do
+ install_gemfile <<-G, :standalone => true, :raise_on_error => false, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" }
+ source 'https://rubygems.org'
+ gem "resque-scheduler", "2.2.0"
+ gem "redis-namespace", "1.6.0" # for a consistent resolution including ruby 2.3.0
+ gem "ruby2_keywords", "0.0.5"
+ G
+ expect(err).to include("You have one or more invalid gemspecs that need to be fixed.")
+ expect(err).to include("resque-scheduler 2.2.0 has an invalid gemspec")
+ end
+
+ it "doesn't hang on big gemfile" do
+ skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM =~ /darwin/
+
+ gemfile <<~G
+ # frozen_string_literal: true
+
source "https://rubygems.org"
- gem 'rack', '1.0.1'
+ ruby "2.7.3"
+
+ gem "rails"
+ gem "pg", ">= 0.18", "< 2.0"
+ gem "goldiloader"
+ gem "awesome_nested_set"
+ gem "circuitbox"
+ gem "passenger"
+ gem "globalid"
+ gem "rack-cors"
+ gem "rails-pg-extras"
+ gem "linear_regression_trend"
+ gem "rack-protection"
+ gem "pundit"
+ gem "remote_ip_proxy_scrubber"
+ gem "bcrypt"
+ gem "searchkick"
+ gem "excon"
+ gem "faraday_middleware-aws-sigv4"
+ gem "typhoeus"
+ gem "sidekiq"
+ gem "sidekiq-undertaker"
+ gem "sidekiq-cron"
+ gem "storext"
+ gem "appsignal"
+ gem "fcm"
+ gem "business_time"
+ gem "tzinfo"
+ gem "holidays"
+ gem "bigdecimal"
+ gem "progress_bar"
+ gem "redis"
+ gem "hiredis"
+ gem "state_machines"
+ gem "state_machines-audit_trail"
+ gem "state_machines-activerecord"
+ gem "interactor"
+ gem "ar_transaction_changes"
+ gem "redis-rails"
+ gem "seed_migration"
+ gem "lograge"
+ gem "graphiql-rails", group: :development
+ gem "graphql"
+ gem "pusher"
+ gem "rbnacl"
+ gem "jwt"
+ gem "json-schema"
+ gem "discard"
+ gem "money"
+ gem "strip_attributes"
+ gem "validates_email_format_of"
+ gem "audited"
+ gem "concurrent-ruby"
+ gem "with_advisory_lock"
+
+ group :test do
+ gem "rspec-sidekiq"
+ gem "simplecov", require: false
+ end
+
+ group :development, :test do
+ gem "byebug", platform: :mri
+ gem "guard"
+ gem "guard-bundler"
+ gem "guard-rspec"
+ gem "rb-fsevent"
+ gem "rspec_junit_formatter"
+ gem "rspec-collection_matchers"
+ gem "rspec-rails"
+ gem "rspec-retry"
+ gem "state_machines-rspec"
+ gem "dotenv-rails"
+ gem "database_cleaner-active_record"
+ gem "database_cleaner-redis"
+ gem "timecop"
+ end
+
+ gem "factory_bot_rails"
+ gem "faker"
+
+ group :development do
+ gem "listen"
+ gem "sql_queries_count"
+ gem "rubocop"
+ gem "rubocop-performance"
+ gem "rubocop-rspec"
+ gem "rubocop-rails"
+ gem "brakeman"
+ gem "bundler-audit"
+ gem "solargraph"
+ gem "annotate"
+ end
G
- bundle "install --path vendor/bundle"
- expect(err).not_to include("Could not find rake")
- expect(err).to lack_errors
+ if Bundler.feature_flag.bundler_3_mode?
+ # Conflicts on bundler version, so fails earlier
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }, :raise_on_error => false
+ expect(out).to display_total_steps_of(435)
+ else
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
+ expect(out).to display_total_steps_of(1025)
+ end
end
- it "checks out git repos when the lockfile is corrupted" do
- gemfile <<-G
- source "https://rubygems.org"
+ it "doesn't hang on tricky gemfile" do
+ skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM =~ /darwin/
- gem 'activerecord', :github => 'carlhuda/rails-bundler-test', :branch => 'master'
- gem 'activesupport', :github => 'carlhuda/rails-bundler-test', :branch => 'master'
- gem 'actionpack', :github => 'carlhuda/rails-bundler-test', :branch => 'master'
+ gemfile <<~G
+ source 'https://rubygems.org'
+
+ group :development do
+ gem "puppet-module-posix-default-r2.7", '~> 0.3'
+ gem "puppet-module-posix-dev-r2.7", '~> 0.3'
+ gem "beaker-rspec"
+ gem "beaker-puppet"
+ gem "beaker-docker"
+ gem "beaker-puppet_install_helper"
+ gem "beaker-module_install_helper"
+ end
G
- lockfile <<-L
- GIT
- remote: git://github.com/carlhuda/rails-bundler-test.git
- revision: 369e28a87419565f1940815219ea9200474589d4
- branch: master
- specs:
- actionpack (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
- builder (~> 3.0.0)
- erubis (~> 2.7.0)
- journey (~> 1.0.1)
- rack (~> 1.4.0)
- rack-cache (~> 1.2)
- rack-test (~> 0.6.1)
- sprockets (~> 2.1.2)
- activemodel (3.2.2)
- activesupport (= 3.2.2)
- builder (~> 3.0.0)
- activerecord (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
- arel (~> 3.0.2)
- tzinfo (~> 0.3.29)
- activesupport (3.2.2)
- i18n (~> 0.6)
- multi_json (~> 1.0)
-
- GIT
- remote: git://github.com/carlhuda/rails-bundler-test.git
- revision: 369e28a87419565f1940815219ea9200474589d4
- branch: master
- specs:
- actionpack (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
- builder (~> 3.0.0)
- erubis (~> 2.7.0)
- journey (~> 1.0.1)
- rack (~> 1.4.0)
- rack-cache (~> 1.2)
- rack-test (~> 0.6.1)
- sprockets (~> 2.1.2)
- activemodel (3.2.2)
- activesupport (= 3.2.2)
- builder (~> 3.0.0)
- activerecord (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
- arel (~> 3.0.2)
- tzinfo (~> 0.3.29)
- activesupport (3.2.2)
- i18n (~> 0.6)
- multi_json (~> 1.0)
-
- GIT
- remote: git://github.com/carlhuda/rails-bundler-test.git
- revision: 369e28a87419565f1940815219ea9200474589d4
- branch: master
- specs:
- actionpack (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
- builder (~> 3.0.0)
- erubis (~> 2.7.0)
- journey (~> 1.0.1)
- rack (~> 1.4.0)
- rack-cache (~> 1.2)
- rack-test (~> 0.6.1)
- sprockets (~> 2.1.2)
- activemodel (3.2.2)
- activesupport (= 3.2.2)
- builder (~> 3.0.0)
- activerecord (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
- arel (~> 3.0.2)
- tzinfo (~> 0.3.29)
- activesupport (3.2.2)
- i18n (~> 0.6)
- multi_json (~> 1.0)
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
- GEM
- remote: https://rubygems.org/
- specs:
- arel (3.0.2)
- builder (3.0.0)
- erubis (2.7.0)
- hike (1.2.1)
- i18n (0.6.0)
- journey (1.0.3)
- multi_json (1.1.0)
- rack (1.4.1)
- rack-cache (1.2)
- rack (>= 0.4)
- rack-test (0.6.1)
- rack (>= 1.0)
- sprockets (2.1.2)
- hike (~> 1.2)
- rack (~> 1.0)
- tilt (~> 1.1, != 1.3.0)
- tilt (1.3.3)
- tzinfo (0.3.32)
+ if Bundler.feature_flag.bundler_3_mode?
+ expect(out).to display_total_steps_of(890)
+ else
+ expect(out).to display_total_steps_of(891)
+ end
+ end
- PLATFORMS
- ruby
+ it "doesn't hang on nix gemfile" do
+ skip "Only for ruby 3.0.1" if RUBY_VERSION != "3.0.1" || RUBY_PLATFORM =~ /darwin/
+
+ gemfile <<~G
+ source "https://rubygems.org" do
+ gem "addressable"
+ gem "atk"
+ gem "awesome_print"
+ gem "bacon"
+ gem "byebug"
+ gem "cairo"
+ gem "cairo-gobject"
+ gem "camping"
+ gem "charlock_holmes"
+ gem "cld3"
+ gem "cocoapods"
+ gem "cocoapods-acknowledgements"
+ gem "cocoapods-art"
+ gem "cocoapods-bin"
+ gem "cocoapods-browser"
+ gem "cocoapods-bugsnag"
+ gem "cocoapods-check"
+ gem "cocoapods-clean"
+ gem "cocoapods-clean_build_phases_scripts"
+ gem "cocoapods-core"
+ gem "cocoapods-coverage"
+ gem "cocoapods-deintegrate"
+ gem "cocoapods-dependencies"
+ gem "cocoapods-deploy"
+ gem "cocoapods-downloader"
+ gem "cocoapods-expert-difficulty"
+ gem "cocoapods-fix-react-native"
+ gem "cocoapods-generate"
+ gem "cocoapods-git_url_rewriter"
+ gem "cocoapods-keys"
+ gem "cocoapods-no-dev-schemes"
+ gem "cocoapods-open"
+ gem "cocoapods-packager"
+ gem "cocoapods-playgrounds"
+ gem "cocoapods-plugins"
+ gem "cocoapods-prune-localizations"
+ gem "cocoapods-rome"
+ gem "cocoapods-search"
+ gem "cocoapods-sorted-search"
+ gem "cocoapods-static-swift-framework"
+ gem "cocoapods-stats"
+ gem "cocoapods-tdfire-binary"
+ gem "cocoapods-testing"
+ gem "cocoapods-trunk"
+ gem "cocoapods-try"
+ gem "cocoapods-try-release-fix"
+ gem "cocoapods-update-if-you-dare"
+ gem "cocoapods-whitelist"
+ gem "cocoapods-wholemodule"
+ gem "coderay"
+ gem "concurrent-ruby"
+ gem "curb"
+ gem "curses"
+ gem "daemons"
+ gem "dep-selector-libgecode"
+ gem "digest-sha3"
+ gem "domain_name"
+ gem "do_sqlite3"
+ gem "ethon"
+ gem "eventmachine"
+ gem "excon"
+ gem "faraday"
+ gem "ffi"
+ gem "ffi-rzmq-core"
+ gem "fog-dnsimple"
+ gem "gdk_pixbuf2"
+ gem "gio2"
+ gem "gitlab-markup"
+ gem "glib2"
+ gem "gpgme"
+ gem "gtk2"
+ gem "hashie"
+ gem "highline"
+ gem "hike"
+ gem "hitimes"
+ gem "hpricot"
+ gem "httpclient"
+ gem "http-cookie"
+ gem "iconv"
+ gem "idn-ruby"
+ gem "jbuilder"
+ gem "jekyll"
+ gem "jmespath"
+ gem "jwt"
+ gem "libv8"
+ gem "libxml-ruby"
+ gem "magic"
+ gem "markaby"
+ gem "method_source"
+ gem "mini_magick"
+ gem "msgpack"
+ gem "mysql2"
+ gem "ncursesw"
+ gem "netrc"
+ gem "net-scp"
+ gem "net-ssh"
+ gem "nokogiri"
+ gem "opus-ruby"
+ gem "ovirt-engine-sdk"
+ gem "pango"
+ gem "patron"
+ gem "pcaprub"
+ gem "pg"
+ gem "pry"
+ gem "pry-byebug"
+ gem "pry-doc"
+ gem "public_suffix"
+ gem "puma"
+ gem "rails"
+ gem "rainbow"
+ gem "rbnacl"
+ gem "rb-readline"
+ gem "re2"
+ gem "redis"
+ gem "redis-rack"
+ gem "rest-client"
+ gem "rmagick"
+ gem "rpam2"
+ gem "rspec"
+ gem "rubocop"
+ gem "rubocop-performance"
+ gem "ruby-libvirt"
+ gem "ruby-lxc"
+ gem "ruby-progressbar"
+ gem "ruby-terminfo"
+ gem "ruby-vips"
+ gem "rubyzip"
+ gem "rugged"
+ gem "sassc"
+ gem "scrypt"
+ gem "semian"
+ gem "sequel"
+ gem "sequel_pg"
+ gem "simplecov"
+ gem "sinatra"
+ gem "slop"
+ gem "snappy"
+ gem "sqlite3"
+ gem "taglib-ruby"
+ gem "thrift"
+ gem "tilt"
+ gem "tiny_tds"
+ gem "treetop"
+ gem "typhoeus"
+ gem "tzinfo"
+ gem "unf_ext"
+ gem "uuid4r"
+ gem "whois"
+ gem "zookeeper"
+ end
+ G
- DEPENDENCIES
- actionpack!
- activerecord!
- activesupport!
- L
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
- bundle :lock
- expect(err).to eq("")
- expect(exitstatus).to eq(0) if exitstatus
+ if Bundler.feature_flag.bundler_3_mode?
+ expect(out).to display_total_steps_of(1874)
+ else
+ expect(out).to display_total_steps_of(1922)
+ end
end
- it "outputs a helpful error message when gems have invalid gemspecs" do
- install_gemfile <<-G, :standalone => true
- source 'https://rubygems.org'
- gem "resque-scheduler", "2.2.0"
- G
- expect(out).to include("You have one or more invalid gemspecs that need to be fixed.")
- expect(out).to include("resque-scheduler 2.2.0 has an invalid gemspec")
+ private
+
+ RSpec::Matchers.define :display_total_steps_of do |expected_steps|
+ match do |out|
+ out.include?("BUNDLER: Finished resolution (#{expected_steps} steps)")
+ end
+
+ failure_message do |out|
+ actual_steps = out.scan(/BUNDLER: Finished resolution \((\d+) steps\)/).first.first
+
+ "Expected resolution to finish in #{expected_steps} steps, but took #{actual_steps}"
+ end
end
end
diff --git a/spec/bundler/realworld/ffi_spec.rb b/spec/bundler/realworld/ffi_spec.rb
new file mode 100644
index 0000000000..083ea38901
--- /dev/null
+++ b/spec/bundler/realworld/ffi_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+RSpec.describe "loading dinamically linked library on a bundle exec context", :realworld => true do
+ it "passes ENV right after argv in memory" do
+ create_file "foo.rb", <<~RUBY
+ require 'ffi'
+
+ module FOO
+ extend FFI::Library
+ ffi_lib './libfoo.so'
+
+ attach_function :Hello, [], :void
+ end
+
+ FOO.Hello()
+ RUBY
+
+ create_file "libfoo.c", <<~'C'
+ #include <stdio.h>
+
+ static int foo_init(int argc, char** argv, char** envp) {
+ if (argv[argc+1] == NULL) {
+ printf("FAIL\n");
+ } else {
+ printf("OK\n");
+ }
+
+ return 0;
+ }
+
+ #if defined(__APPLE__) && defined(__MACH__)
+ __attribute__((section("__DATA,__mod_init_func"), used, aligned(sizeof(void*))))
+ #else
+ __attribute__((section(".init_array")))
+ #endif
+ static void *ctr = &foo_init;
+
+ extern char** environ;
+
+ void Hello() {
+ return;
+ }
+ C
+
+ sys_exec "gcc -g -o libfoo.so -shared -fpic libfoo.c"
+
+ install_gemfile <<-G
+ source "https://rubygems.org"
+
+ gem 'ffi'
+ G
+
+ bundle "exec ruby foo.rb"
+
+ expect(out).to eq("OK")
+ end
+end
diff --git a/spec/bundler/realworld/fixtures/warbler/.gitignore b/spec/bundler/realworld/fixtures/warbler/.gitignore
new file mode 100644
index 0000000000..d392f0e82c
--- /dev/null
+++ b/spec/bundler/realworld/fixtures/warbler/.gitignore
@@ -0,0 +1 @@
+*.jar
diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile b/spec/bundler/realworld/fixtures/warbler/Gemfile
new file mode 100644
index 0000000000..4fbf2d05a7
--- /dev/null
+++ b/spec/bundler/realworld/fixtures/warbler/Gemfile
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+source "https://rubygems.org"
+
+gem "demo", :path => "./demo"
+gem "jruby-jars", "~> 9.2"
+gem "warbler", "~> 2.0"
diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
new file mode 100644
index 0000000000..05bcb877db
--- /dev/null
+++ b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
@@ -0,0 +1,30 @@
+PATH
+ remote: demo
+ specs:
+ demo (1.0)
+
+GEM
+ remote: https://rubygems.org/
+ specs:
+ jruby-jars (9.2.16.0)
+ jruby-rack (1.1.21)
+ rake (13.0.1)
+ rubyzip (1.3.0)
+ warbler (2.0.5)
+ jruby-jars (>= 9.0.0.0)
+ jruby-rack (>= 1.1.1, < 1.3)
+ rake (>= 10.1.0)
+ rubyzip (~> 1.0, < 1.4)
+
+PLATFORMS
+ java
+ ruby
+ universal-java-11
+
+DEPENDENCIES
+ demo!
+ jruby-jars (~> 9.2)
+ warbler (~> 2.0)
+
+BUNDLED WITH
+ 2.3.0.dev
diff --git a/spec/bundler/realworld/fixtures/warbler/bin/warbler-example.rb b/spec/bundler/realworld/fixtures/warbler/bin/warbler-example.rb
new file mode 100644
index 0000000000..25f614ecc2
--- /dev/null
+++ b/spec/bundler/realworld/fixtures/warbler/bin/warbler-example.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+puts require "bundler/setup"
diff --git a/spec/bundler/realworld/fixtures/warbler/demo/demo.gemspec b/spec/bundler/realworld/fixtures/warbler/demo/demo.gemspec
new file mode 100644
index 0000000000..ed5a0dc080
--- /dev/null
+++ b/spec/bundler/realworld/fixtures/warbler/demo/demo.gemspec
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+Gem::Specification.new do |spec|
+ spec.name = "demo"
+ spec.version = "1.0"
+ spec.author = "Somebody"
+ spec.summary = "A demo gem"
+ spec.license = "MIT"
+ spec.homepage = "https://example.org"
+end
diff --git a/spec/bundler/realworld/gemfile_source_header_spec.rb b/spec/bundler/realworld/gemfile_source_header_spec.rb
index ba888d43bd..ada2fc92ee 100644
--- a/spec/bundler/realworld/gemfile_source_header_spec.rb
+++ b/spec/bundler/realworld/gemfile_source_header_spec.rb
@@ -1,14 +1,14 @@
# frozen_string_literal: true
-require "spec_helper"
-require "thread"
-RSpec.describe "fetching dependencies with a mirrored source", :realworld => true, :rubygems => ">= 2.0" do
+require_relative "../support/silent_logger"
+
+RSpec.describe "fetching dependencies with a mirrored source", :realworld => true do
let(:mirror) { "https://server.example.org" }
let(:original) { "http://127.0.0.1:#{@port}" }
before do
setup_server
- bundle "config --local mirror.#{mirror} #{original}"
+ bundle "config set --local mirror.#{mirror} #{original}"
end
after do
@@ -23,7 +23,7 @@ RSpec.describe "fetching dependencies with a mirrored source", :realworld => tru
gem 'weakling'
G
- bundle :install
+ bundle :install, :artifice => nil
expect(out).to include("Installing weakling")
expect(out).to include("Bundle complete")
@@ -37,7 +37,7 @@ RSpec.describe "fetching dependencies with a mirrored source", :realworld => tru
@port = find_unused_port
@server_uri = "http://127.0.0.1:#{@port}"
- require File.expand_path("../../support/artifice/endpoint_mirror_source", __FILE__)
+ require_relative "../support/artifice/endpoint_mirror_source"
@t = Thread.new do
Rack::Server.start(:app => EndpointMirrorSource,
diff --git a/spec/bundler/realworld/mirror_probe_spec.rb b/spec/bundler/realworld/mirror_probe_spec.rb
index 93dca0c173..84d6a9c782 100644
--- a/spec/bundler/realworld/mirror_probe_spec.rb
+++ b/spec/bundler/realworld/mirror_probe_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require "spec_helper"
-require "thread"
+
+require_relative "../support/silent_logger"
RSpec.describe "fetching dependencies with a not available mirror", :realworld => true do
let(:mirror) { @mirror_uri }
@@ -32,7 +32,7 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld =
gem 'weakling'
G
- bundle :install
+ bundle :install, :artifice => nil
expect(out).to include("Installing weakling")
expect(out).to include("Bundle complete")
@@ -52,7 +52,7 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld =
gem 'weakling'
G
- bundle :install
+ bundle :install, :artifice => nil
expect(out).to include("Installing weakling")
expect(out).to include("Bundle complete")
@@ -71,13 +71,13 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld =
gem 'weakling'
G
- bundle :install
+ bundle :install, :artifice => nil, :raise_on_error => false
expect(out).to include("Fetching source index from #{mirror}")
- expect(out).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}")
- expect(out).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}")
- expect(out).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}")
- expect(out).to include("Could not fetch specs from #{mirror}")
+ expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
+ expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
+ expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
+ expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
end
it "prints each error and warning on a new line" do
@@ -86,14 +86,10 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld =
gem 'weakling'
G
- bundle :install
-
- expect(out).to eq "Fetching source index from #{mirror}/
+ bundle :install, :artifice => nil, :raise_on_error => false
-Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/
-Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/
-Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/
-Could not fetch specs from #{mirror}/"
+ expect(out).to include "Fetching source index from #{mirror}/"
+ expect(err.split("\n").count).to eq(4)
end
end
@@ -108,13 +104,13 @@ Could not fetch specs from #{mirror}/"
gem 'weakling'
G
- bundle :install
+ bundle :install, :artifice => nil, :raise_on_error => false
expect(out).to include("Fetching source index from #{mirror}")
- expect(out).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}")
- expect(out).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}")
- expect(out).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}")
- expect(out).to include("Could not fetch specs from #{mirror}")
+ expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
+ expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
+ expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
+ expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)")
end
end
@@ -122,7 +118,7 @@ Could not fetch specs from #{mirror}/"
@server_port = find_unused_port
@server_uri = "http://#{host}:#{@server_port}"
- require File.expand_path("../../support/artifice/endpoint", __FILE__)
+ require_relative "../support/artifice/endpoint"
@server_thread = Thread.new do
Rack::Server.start(:app => Endpoint,
@@ -137,7 +133,7 @@ Could not fetch specs from #{mirror}/"
end
def setup_mirror
- mirror_port = find_unused_port
- @mirror_uri = "http://#{host}:#{mirror_port}"
+ @mirror_port = find_unused_port
+ @mirror_uri = "http://#{host}:#{@mirror_port}"
end
end
diff --git a/spec/bundler/realworld/parallel_spec.rb b/spec/bundler/realworld/parallel_spec.rb
index 6950bead19..97c0e0cab4 100644
--- a/spec/bundler/realworld/parallel_spec.rb
+++ b/spec/bundler/realworld/parallel_spec.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
-require "spec_helper"
-RSpec.describe "parallel", :realworld => true, :sometimes => true do
+RSpec.describe "parallel", :realworld => true do
it "installs" do
gemfile <<-G
source "https://rubygems.org"
@@ -12,20 +11,13 @@ RSpec.describe "parallel", :realworld => true, :sometimes => true do
bundle :install, :jobs => 4, :env => { "DEBUG" => "1" }
- if Bundler.rubygems.provides?(">= 2.1.0")
- expect(out).to match(/[1-3]: /)
- else
- expect(out).to include("is not threadsafe")
- end
+ expect(out).to match(/[1-3]: /)
- bundle "show activesupport"
+ bundle "info activesupport --path"
expect(out).to match(/activesupport/)
- bundle "show faker"
+ bundle "info faker --path"
expect(out).to match(/faker/)
-
- bundle "config jobs"
- expect(out).to match(/: "4"/)
end
it "updates" do
@@ -42,22 +34,15 @@ RSpec.describe "parallel", :realworld => true, :sometimes => true do
gem 'i18n', '~> 0.6.0' # Because 0.7+ requires Ruby 1.9.3+
G
- bundle :update, :jobs => 4, :env => { "DEBUG" => "1" }
+ bundle :update, :jobs => 4, :env => { "DEBUG" => "1" }, :all => true
- if Bundler.rubygems.provides?(">= 2.1.0")
- expect(out).to match(/[1-3]: /)
- else
- expect(out).to include("is not threadsafe")
- end
+ expect(out).to match(/[1-3]: /)
- bundle "show activesupport"
+ bundle "info activesupport --path"
expect(out).to match(/activesupport-3\.2\.\d+/)
- bundle "show faker"
+ bundle "info faker --path"
expect(out).to match(/faker/)
-
- bundle "config jobs"
- expect(out).to match(/: "4"/)
end
it "works with --standalone" do
@@ -68,7 +53,7 @@ RSpec.describe "parallel", :realworld => true, :sometimes => true do
bundle :install, :standalone => true, :jobs => 4
- ruby <<-RUBY, :no_lib => true
+ ruby <<-RUBY
$:.unshift File.expand_path("bundle")
require "bundler/setup"
diff --git a/spec/bundler/realworld/slow_perf_spec.rb b/spec/bundler/realworld/slow_perf_spec.rb
new file mode 100644
index 0000000000..aced5a1641
--- /dev/null
+++ b/spec/bundler/realworld/slow_perf_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe "bundle install with complex dependencies", :realworld => true do
+ it "resolves quickly" do
+ gemfile <<-G
+ source 'https://rubygems.org'
+
+ gem "actionmailer"
+ gem "mongoid", ">= 0.10.2"
+ G
+
+ start_time = Time.now
+
+ bundle "lock"
+
+ duration = Time.now - start_time
+
+ expect(duration.to_f).to be < 12 # seconds
+ end
+end
diff --git a/spec/bundler/resolver/basic_spec.rb b/spec/bundler/resolver/basic_spec.rb
index 9e93847ab5..ee62dc3577 100644
--- a/spec/bundler/resolver/basic_spec.rb
+++ b/spec/bundler/resolver/basic_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "Resolving" do
before :each do
@@ -9,31 +8,45 @@ RSpec.describe "Resolving" do
it "resolves a single gem" do
dep "rack"
- should_resolve_as %w(rack-1.1)
+ should_resolve_as %w[rack-1.1]
end
it "resolves a gem with dependencies" do
dep "actionpack"
- should_resolve_as %w(actionpack-2.3.5 activesupport-2.3.5 rack-1.0)
+ should_resolve_as %w[actionpack-2.3.5 activesupport-2.3.5 rack-1.0]
end
it "resolves a conflicting index" do
@index = a_conflict_index
dep "my_app"
- should_resolve_as %w(activemodel-3.2.11 builder-3.0.4 grape-0.2.6 my_app-1.0.0)
+ should_resolve_as %w[activemodel-3.2.11 builder-3.0.4 grape-0.2.6 my_app-1.0.0]
end
it "resolves a complex conflicting index" do
@index = a_complex_conflict_index
dep "my_app"
- should_resolve_as %w(a-1.4.0 b-0.3.5 c-3.2 d-0.9.8 my_app-1.1.0)
+ should_resolve_as %w[a-1.4.0 b-0.3.5 c-3.2 d-0.9.8 my_app-1.1.0]
end
it "resolves a index with conflict on child" do
@index = index_with_conflict_on_child
dep "chef_app"
- should_resolve_as %w(berkshelf-2.0.7 chef-10.26 chef_app-1.0.0 json-1.7.7)
+ should_resolve_as %w[berkshelf-2.0.7 chef-10.26 chef_app-1.0.0 json-1.7.7]
+ end
+
+ it "prefers explicitly requested dependencies when resolving an index which would otherwise be ambiguous" do
+ @index = an_ambiguous_index
+ dep "a"
+ dep "b"
+ should_resolve_as %w[a-1.0.0 b-2.0.0 c-1.0.0 d-1.0.0]
+ end
+
+ it "prefers non-prerelease resolutions in sort order" do
+ @index = optional_prereleases_index
+ dep "a"
+ dep "b"
+ should_resolve_as %w[a-1.0.0 b-1.5.0]
end
it "resolves a index with root level conflict on child" do
@@ -42,7 +55,48 @@ RSpec.describe "Resolving" do
dep "activesupport", "~> 3.0"
dep "activerecord", "~> 3.0"
dep "builder", "~> 2.1.2"
- should_resolve_as %w(activesupport-3.0.5 i18n-0.4.2 builder-2.1.2 activerecord-3.0.5 activemodel-3.0.5)
+ should_resolve_as %w[activesupport-3.0.5 i18n-0.4.2 builder-2.1.2 activerecord-3.0.5 activemodel-3.0.5]
+ end
+
+ it "resolves a gem specified with a pre-release version" do
+ dep "activesupport", "~> 3.0.0.beta"
+ dep "activemerchant"
+ should_resolve_as %w[activemerchant-2.3.5 activesupport-3.0.0.beta1]
+ end
+
+ it "doesn't select a pre-release if not specified in the Gemfile" do
+ dep "activesupport"
+ dep "reform"
+ should_resolve_as %w[reform-1.0.0 activesupport-2.3.5]
+ end
+
+ it "doesn't select a pre-release for sub-dependencies" do
+ dep "reform"
+ should_resolve_as %w[reform-1.0.0 activesupport-2.3.5]
+ end
+
+ it "selects a pre-release for sub-dependencies if it's the only option" do
+ dep "need-pre"
+ should_resolve_as %w[need-pre-1.0.0 activesupport-3.0.0.beta1]
+ end
+
+ it "selects a pre-release if it's specified in the Gemfile" do
+ dep "activesupport", "= 3.0.0.beta"
+ dep "actionpack"
+
+ should_resolve_as %w[activesupport-3.0.0.beta actionpack-3.0.0.beta rack-1.1 rack-mount-0.6]
+ end
+
+ it "prefers non-pre-releases when doing conservative updates" do
+ @index = build_index do
+ gem "mail", "2.7.0"
+ gem "mail", "2.7.1.rc1"
+ gem "RubyGems\0", Gem::VERSION
+ end
+ dep "mail"
+ @locked = locked ["mail", "2.7.0"]
+ @base = locked
+ should_conservative_resolve_and_include [:patch], [], ["mail-2.7.0"]
end
it "raises an exception if a child dependency is not resolved" do
@@ -55,7 +109,7 @@ RSpec.describe "Resolving" do
it "raises an exception with the minimal set of conflicting dependencies" do
@index = build_index do
- %w(0.9 1.0 2.0).each {|v| gem("a", v) }
+ %w[0.9 1.0 2.0].each {|v| gem("a", v) }
gem("b", "1.0") { dep "a", ">= 2" }
gem("c", "1.0") { dep "a", "< 1" }
end
@@ -88,14 +142,14 @@ Bundler could not find compatible versions for gem "a":
it "should install the latest possible version of a direct requirement with no constraints given" do
@index = a_complicated_index
dep "foo"
- should_resolve_and_include %w(foo-3.0.5)
+ should_resolve_and_include %w[foo-3.0.5]
end
# Issue #3459
it "should install the latest possible version of a direct requirement with constraints given" do
@index = a_complicated_index
dep "foo", ">= 3.0.0"
- should_resolve_and_include %w(foo-3.0.5)
+ should_resolve_and_include %w[foo-3.0.5]
end
it "takes into account required_ruby_version" do
@@ -115,17 +169,17 @@ Bundler could not find compatible versions for gem "a":
s.required_ruby_version = "~> 2.0.0"
end
- gem "ruby\0", "1.8.7"
+ gem "Ruby\0", "1.8.7"
end
dep "foo"
- dep "ruby\0", "1.8.7"
+ dep "Ruby\0", "1.8.7"
deps = []
@deps.each do |d|
- deps << Bundler::DepProxy.new(d, "ruby")
+ deps << Bundler::DepProxy.get_proxy(d, "ruby")
end
- should_resolve_and_include %w(foo-1.0.0 bar-1.0.0), [{}, []]
+ should_resolve_and_include %w[foo-1.0.0 bar-1.0.0], [[]]
end
context "conservative" do
@@ -139,7 +193,7 @@ Bundler could not find compatible versions for gem "a":
gem("foo", "1.5.0") { dep "bar", "~> 2.1" }
gem("foo", "1.5.1") { dep "bar", "~> 3.0" }
gem("foo", "2.0.0") { dep "bar", "~> 3.0" }
- gem "bar", %w(2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0)
+ gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
end
dep "foo"
@@ -147,23 +201,23 @@ Bundler could not find compatible versions for gem "a":
@base = Bundler::SpecSet.new([])
# locked represents versions in lockfile
- @locked = locked(%w(foo 1.4.3), %w(bar 2.0.3))
+ @locked = locked(%w[foo 1.4.3], %w[bar 2.0.3])
end
it "resolves all gems to latest patch" do
# strict is not set, so bar goes up a minor version due to dependency from foo 1.4.5
- should_conservative_resolve_and_include :patch, [], %w(foo-1.4.5 bar-2.1.1)
+ should_conservative_resolve_and_include :patch, [], %w[foo-1.4.5 bar-2.1.1]
end
it "resolves all gems to latest patch strict" do
# strict is set, so foo can only go up to 1.4.4 to avoid bar going up a minor version, and bar can go up to 2.0.5
- should_conservative_resolve_and_include [:patch, :strict], [], %w(foo-1.4.4 bar-2.0.5)
+ should_conservative_resolve_and_include [:patch, :strict], [], %w[foo-1.4.4 bar-2.0.5]
end
it "resolves foo only to latest patch - same dependency case" do
- @locked = locked(%w(foo 1.3.7), %w(bar 2.0.3))
+ @locked = locked(%w[foo 1.3.7], %w[bar 2.0.3])
# bar is locked, and the lock holds here because the dependency on bar doesn't change on the matching foo version.
- should_conservative_resolve_and_include :patch, ["foo"], %w(foo-1.3.8 bar-2.0.3)
+ should_conservative_resolve_and_include :patch, ["foo"], %w[foo-1.3.8 bar-2.0.3]
end
it "resolves foo only to latest patch - changing dependency not declared case" do
@@ -172,45 +226,45 @@ Bundler could not find compatible versions for gem "a":
# dependencies and since the dependency of the selected foo gem changes, the latest matching
# dependency of "bar", "~> 2.1" -- bar-2.1.1 -- is selected. This is not a bug and follows
# the long-standing documented Conservative Updating behavior of bundle install.
- # http://bundler.io/v1.12/man/bundle-install.1.html#CONSERVATIVE-UPDATING
- should_conservative_resolve_and_include :patch, ["foo"], %w(foo-1.4.5 bar-2.1.1)
+ # https://bundler.io/v1.12/man/bundle-install.1.html#CONSERVATIVE-UPDATING
+ should_conservative_resolve_and_include :patch, ["foo"], %w[foo-1.4.5 bar-2.1.1]
end
it "resolves foo only to latest patch - changing dependency declared case" do
# bar is locked AND a declared dependency in the Gemfile, so it will not move, and therefore
# foo can only move up to 1.4.4.
@base << build_spec("bar", "2.0.3").first
- should_conservative_resolve_and_include :patch, ["foo"], %w(foo-1.4.4 bar-2.0.3)
+ should_conservative_resolve_and_include :patch, ["foo"], %w[foo-1.4.4 bar-2.0.3]
end
it "resolves foo only to latest patch strict" do
# adding strict helps solve the possibly unexpected behavior of bar changing in the prior test case,
# because no versions will be returned for bar ~> 2.1, so the engine falls back to ~> 2.0 (turn on
# debugging to see this happen).
- should_conservative_resolve_and_include [:patch, :strict], ["foo"], %w(foo-1.4.4 bar-2.0.3)
+ should_conservative_resolve_and_include [:patch, :strict], ["foo"], %w[foo-1.4.4 bar-2.0.3]
end
it "resolves bar only to latest patch" do
# bar is locked, so foo can only go up to 1.4.4
- should_conservative_resolve_and_include :patch, ["bar"], %w(foo-1.4.3 bar-2.0.5)
+ should_conservative_resolve_and_include :patch, ["bar"], %w[foo-1.4.3 bar-2.0.5]
end
it "resolves all gems to latest minor" do
# strict is not set, so bar goes up a major version due to dependency from foo 1.4.5
- should_conservative_resolve_and_include :minor, [], %w(foo-1.5.1 bar-3.0.0)
+ should_conservative_resolve_and_include :minor, [], %w[foo-1.5.1 bar-3.0.0]
end
it "resolves all gems to latest minor strict" do
# strict is set, so foo can only go up to 1.5.0 to avoid bar going up a major version
- should_conservative_resolve_and_include [:minor, :strict], [], %w(foo-1.5.0 bar-2.1.1)
+ should_conservative_resolve_and_include [:minor, :strict], [], %w[foo-1.5.0 bar-2.1.1]
end
it "resolves all gems to latest major" do
- should_conservative_resolve_and_include :major, [], %w(foo-2.0.0 bar-3.0.0)
+ should_conservative_resolve_and_include :major, [], %w[foo-2.0.0 bar-3.0.0]
end
it "resolves all gems to latest major strict" do
- should_conservative_resolve_and_include [:major, :strict], [], %w(foo-2.0.0 bar-3.0.0)
+ should_conservative_resolve_and_include [:major, :strict], [], %w[foo-2.0.0 bar-3.0.0]
end
# Why would this happen in real life? If bar 2.2 has a bug that the author of foo wants to bypass
@@ -221,7 +275,7 @@ Bundler could not find compatible versions for gem "a":
gem("foo", "1.4.3") { dep "bar", "~> 2.2" }
gem("foo", "1.4.4") { dep "bar", "~> 2.1.0" }
gem("foo", "1.5.0") { dep "bar", "~> 2.0.0" }
- gem "bar", %w(2.0.5 2.1.1 2.2.3)
+ gem "bar", %w[2.0.5 2.1.1 2.2.3]
end
dep "foo"
@@ -229,29 +283,25 @@ Bundler could not find compatible versions for gem "a":
@base = Bundler::SpecSet.new([])
# locked represents versions in lockfile
- @locked = locked(%w(foo 1.4.3), %w(bar 2.2.3))
+ @locked = locked(%w[foo 1.4.3], %w[bar 2.2.3])
end
it "could revert to a previous version level patch" do
- should_conservative_resolve_and_include :patch, [], %w(foo-1.4.4 bar-2.1.1)
+ should_conservative_resolve_and_include :patch, [], %w[foo-1.4.4 bar-2.1.1]
end
it "cannot revert to a previous version in strict mode level patch" do
- # the strict option removes the version required to match, so a version conflict results
- expect do
- should_conservative_resolve_and_include [:patch, :strict], [], %w(foo-1.4.3 bar-2.1.1)
- end.to raise_error Bundler::VersionConflict, /#{Regexp.escape("Could not find gem 'bar (~> 2.1.0)'")}/
+ # fall back to the locked resolution since strict means we can't regress either version
+ should_conservative_resolve_and_include [:patch, :strict], [], %w[foo-1.4.3 bar-2.2.3]
end
it "could revert to a previous version level minor" do
- should_conservative_resolve_and_include :minor, [], %w(foo-1.5.0 bar-2.0.5)
+ should_conservative_resolve_and_include :minor, [], %w[foo-1.5.0 bar-2.0.5]
end
it "cannot revert to a previous version in strict mode level minor" do
- # the strict option removes the version required to match, so a version conflict results
- expect do
- should_conservative_resolve_and_include [:minor, :strict], [], %w(foo-1.4.3 bar-2.1.1)
- end.to raise_error Bundler::VersionConflict, /#{Regexp.escape("Could not find gem 'bar (~> 2.0.0)'")}/
+ # fall back to the locked resolution since strict means we can't regress either version
+ should_conservative_resolve_and_include [:minor, :strict], [], %w[foo-1.4.3 bar-2.2.3]
end
end
end
diff --git a/spec/bundler/resolver/platform_spec.rb b/spec/bundler/resolver/platform_spec.rb
index 90d6f637ce..bc4081f8b5 100644
--- a/spec/bundler/resolver/platform_spec.rb
+++ b/spec/bundler/resolver/platform_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "Resolving platform craziness" do
describe "with cross-platform gems" do
@@ -11,24 +10,284 @@ RSpec.describe "Resolving platform craziness" do
dep "nokogiri"
platforms "ruby", "java"
- should_resolve_as %w(nokogiri-1.4.2 nokogiri-1.4.2-java weakling-0.0.3)
+ should_resolve_as %w[nokogiri-1.4.2 nokogiri-1.4.2-java weakling-0.0.3]
end
it "doesn't pull gems that don't exist for the current platform" do
dep "nokogiri"
platforms "ruby"
- should_resolve_as %w(nokogiri-1.4.2)
+ should_resolve_as %w[nokogiri-1.4.2]
end
it "doesn't pull gems when the version is available for all requested platforms" do
dep "nokogiri"
platforms "mswin32"
- should_resolve_as %w(nokogiri-1.4.2.1-x86-mswin32)
+ should_resolve_as %w[nokogiri-1.4.2.1-x86-mswin32]
end
end
+ it "resolves multiplatform gems with redundant platforms correctly" do
+ @index = build_index do
+ gem "zookeeper", "1.4.11"
+ gem "zookeeper", "1.4.11", "java" do
+ dep "slyphon-log4j", "= 1.2.15"
+ dep "slyphon-zookeeper_jar", "= 3.3.5"
+ end
+ gem "slyphon-log4j", "1.2.15"
+ gem "slyphon-zookeeper_jar", "3.3.5", "java"
+ end
+
+ dep "zookeeper"
+ platforms "java", "ruby", "universal-java-11"
+
+ should_resolve_as %w[zookeeper-1.4.11 zookeeper-1.4.11-java slyphon-log4j-1.2.15 slyphon-zookeeper_jar-3.3.5-java]
+ end
+
+ it "takes the latest ruby gem, even if an older platform specific version is available" do
+ @index = build_index do
+ gem "foo", "1.0.0"
+ gem "foo", "1.0.0", "x64-mingw32"
+ gem "foo", "1.1.0"
+ end
+ dep "foo"
+ platforms "x64-mingw32"
+
+ should_resolve_as %w[foo-1.1.0]
+ end
+
+ it "takes the ruby version if the platform version is incompatible" do
+ @index = build_index do
+ gem "bar", "1.0.0"
+ gem "foo", "1.0.0"
+ gem "foo", "1.0.0", "x64-mingw32" do
+ dep "bar", "< 1"
+ end
+ end
+ dep "foo"
+ platforms "x64-mingw32"
+
+ should_resolve_as %w[foo-1.0.0]
+ end
+
+ it "prefers the platform specific gem to the ruby version" do
+ @index = build_index do
+ gem "foo", "1.0.0"
+ gem "foo", "1.0.0", "x64-mingw32"
+ end
+ dep "foo"
+ platforms "x64-mingw32"
+
+ should_resolve_as %w[foo-1.0.0-x64-mingw32]
+ end
+
+ it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version" do
+ @index = build_index do
+ gem "foo", "1.0.0"
+ gem "foo", "1.0.0", "x64-mingw32"
+ gem "foo", "1.1.0"
+ gem "foo", "1.1.0", "x64-mingw32" do |s|
+ s.required_ruby_version = [">= 2.0", "< 2.4"]
+ end
+ gem "Ruby\0", "2.5.1"
+ end
+ dep "foo"
+ dep "Ruby\0", "2.5.1"
+ platforms "x64-mingw32"
+
+ should_resolve_as %w[foo-1.1.0]
+ end
+
+ it "takes the latest ruby gem with required_ruby_version if the platform specific gem doesn't match the required_ruby_version" do
+ @index = build_index do
+ gem "foo", "1.0.0"
+ gem "foo", "1.0.0", "x64-mingw32"
+ gem "foo", "1.1.0" do |s|
+ s.required_ruby_version = [">= 2.0"]
+ end
+ gem "foo", "1.1.0", "x64-mingw32" do |s|
+ s.required_ruby_version = [">= 2.0", "< 2.4"]
+ end
+ gem "Ruby\0", "2.5.1"
+ end
+ dep "foo"
+ dep "Ruby\0", "2.5.1"
+ platforms "x64-mingw32"
+
+ should_resolve_as %w[foo-1.1.0]
+ end
+
+ it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version with multiple platforms" do
+ @index = build_index do
+ gem "foo", "1.0.0"
+ gem "foo", "1.0.0", "x64-mingw32"
+ gem "foo", "1.1.0" do |s|
+ s.required_ruby_version = [">= 2.0"]
+ end
+ gem "foo", "1.1.0", "x64-mingw32" do |s|
+ s.required_ruby_version = [">= 2.0", "< 2.4"]
+ end
+ gem "Ruby\0", "2.5.1"
+ end
+ dep "foo"
+ dep "Ruby\0", "2.5.1"
+ platforms "x86_64-linux", "x64-mingw32"
+
+ should_resolve_as %w[foo-1.1.0]
+ end
+
+ it "doesn't include gems not needed for none of the platforms" do
+ @index = build_index do
+ gem "empyrean", "0.1.0"
+ gem "coderay", "1.1.2"
+ gem "method_source", "0.9.0"
+
+ gem "spoon", "0.0.6" do
+ dep "ffi", ">= 0"
+ end
+
+ gem "pry", "0.11.3", "java" do
+ dep "coderay", "~> 1.1.0"
+ dep "method_source", "~> 0.9.0"
+ dep "spoon", "~> 0.0"
+ end
+
+ gem "pry", "0.11.3" do
+ dep "coderay", "~> 1.1.0"
+ dep "method_source", "~> 0.9.0"
+ end
+
+ gem "ffi", "1.9.23", "java"
+ gem "ffi", "1.9.23"
+ end
+
+ dep "empyrean", "0.1.0"
+ dep "pry"
+
+ platforms "ruby", "java"
+
+ should_resolve_as %w[coderay-1.1.2 empyrean-0.1.0 ffi-1.9.23-java method_source-0.9.0 pry-0.11.3 pry-0.11.3-java spoon-0.0.6]
+ end
+
+ it "includes gems needed for at least one platform" do
+ @index = build_index do
+ gem "empyrean", "0.1.0"
+ gem "coderay", "1.1.2"
+ gem "method_source", "0.9.0"
+
+ gem "spoon", "0.0.6" do
+ dep "ffi", ">= 0"
+ end
+
+ gem "pry", "0.11.3", "java" do
+ dep "coderay", "~> 1.1.0"
+ dep "method_source", "~> 0.9.0"
+ dep "spoon", "~> 0.0"
+ end
+
+ gem "pry", "0.11.3" do
+ dep "coderay", "~> 1.1.0"
+ dep "method_source", "~> 0.9.0"
+ end
+
+ gem "ffi", "1.9.23", "java"
+ gem "ffi", "1.9.23"
+
+ gem "extra", "1.0.0" do
+ dep "ffi", ">= 0"
+ end
+ end
+
+ dep "empyrean", "0.1.0"
+ dep "pry"
+ dep "extra"
+
+ platforms "ruby", "java"
+
+ should_resolve_as %w[coderay-1.1.2 empyrean-0.1.0 extra-1.0.0 ffi-1.9.23 ffi-1.9.23-java method_source-0.9.0 pry-0.11.3 pry-0.11.3-java spoon-0.0.6]
+ end
+
+ it "includes gems needed for at least one platform even when the platform specific requirement is processed earlier than the generic requirement" do
+ @index = build_index do
+ gem "empyrean", "0.1.0"
+ gem "coderay", "1.1.2"
+ gem "method_source", "0.9.0"
+
+ gem "spoon", "0.0.6" do
+ dep "ffi", ">= 0"
+ end
+
+ gem "pry", "0.11.3", "java" do
+ dep "coderay", "~> 1.1.0"
+ dep "method_source", "~> 0.9.0"
+ dep "spoon", "~> 0.0"
+ end
+
+ gem "pry", "0.11.3" do
+ dep "coderay", "~> 1.1.0"
+ dep "method_source", "~> 0.9.0"
+ end
+
+ gem "ffi", "1.9.23", "java"
+ gem "ffi", "1.9.23"
+
+ gem "extra", "1.0.0" do
+ dep "extra2", ">= 0"
+ end
+
+ gem "extra2", "1.0.0" do
+ dep "extra3", ">= 0"
+ end
+
+ gem "extra3", "1.0.0" do
+ dep "ffi", ">= 0"
+ end
+ end
+
+ dep "empyrean", "0.1.0"
+ dep "pry"
+ dep "extra"
+
+ platforms "ruby", "java"
+
+ should_resolve_as %w[coderay-1.1.2 empyrean-0.1.0 extra-1.0.0 extra2-1.0.0 extra3-1.0.0 ffi-1.9.23 ffi-1.9.23-java method_source-0.9.0 pry-0.11.3 pry-0.11.3-java spoon-0.0.6]
+ end
+
+ it "properly adds platforms when platform requirements come from different dependencies" do
+ @index = build_index do
+ gem "ffi", "1.9.14"
+ gem "ffi", "1.9.14", "universal-mingw32"
+
+ gem "gssapi", "0.1"
+ gem "gssapi", "0.2"
+ gem "gssapi", "0.3"
+ gem "gssapi", "1.2.0" do
+ dep "ffi", ">= 1.0.1"
+ end
+
+ gem "mixlib-shellout", "2.2.6"
+ gem "mixlib-shellout", "2.2.6", "universal-mingw32" do
+ dep "win32-process", "~> 0.8.2"
+ end
+
+ # we need all these versions to get the sorting the same as it would be
+ # pulling from rubygems.org
+ %w[0.8.3 0.8.2 0.8.1 0.8.0].each do |v|
+ gem "win32-process", v do
+ dep "ffi", ">= 1.0.0"
+ end
+ end
+ end
+
+ dep "mixlib-shellout"
+ dep "gssapi"
+
+ platforms "universal-mingw32", "ruby"
+
+ should_resolve_as %w[ffi-1.9.14 ffi-1.9.14-universal-mingw32 gssapi-1.2.0 mixlib-shellout-2.2.6 mixlib-shellout-2.2.6-universal-mingw32 win32-process-0.8.3]
+ end
+
describe "with mingw32" do
before :each do
@index = build_index do
@@ -43,32 +302,32 @@ RSpec.describe "Resolving platform craziness" do
# win32 is hardcoded to get CPU x86 in rubygems
platforms "mswin32"
dep "thin"
- should_resolve_as %w(thin-1.2.7-x86-mswin32)
+ should_resolve_as %w[thin-1.2.7-x86-mswin32]
end
it "finds mingw gems" do
# mingw is _not_ hardcoded to add CPU x86 in rubygems
platforms "x86-mingw32"
dep "thin"
- should_resolve_as %w(thin-1.2.7-mingw32)
+ should_resolve_as %w[thin-1.2.7-mingw32]
end
it "finds x64-mingw gems" do
platforms "x64-mingw32"
dep "thin"
- should_resolve_as %w(thin-1.2.7-x64-mingw32)
+ should_resolve_as %w[thin-1.2.7-x64-mingw32]
end
it "finds universal-mingw gems on x86-mingw" do
platform "x86-mingw32"
dep "win32-api"
- should_resolve_as %w(win32-api-1.5.1-universal-mingw32)
+ should_resolve_as %w[win32-api-1.5.1-universal-mingw32]
end
it "finds universal-mingw gems on x64-mingw" do
platform "x64-mingw32"
dep "win32-api"
- should_resolve_as %w(win32-api-1.5.1-universal-mingw32)
+ should_resolve_as %w[win32-api-1.5.1-universal-mingw32]
end
end
@@ -87,15 +346,15 @@ RSpec.describe "Resolving platform craziness" do
dep "baz", " ~> 1.1.0"
end
- gem "baz", %w(1.0.0 1.1.0 1.2.0)
+ gem "baz", %w[1.0.0 1.1.0 1.2.0]
end
end
- it "reports on the conflict" do
+ it "takes the ruby version as fallback" do
platforms "ruby", "java"
dep "foo"
- should_conflict_on "baz"
+ should_resolve_as %w[bar-1.0.0 baz-1.0.0 foo-1.0.0]
end
end
end
diff --git a/spec/bundler/runtime/executable_spec.rb b/spec/bundler/runtime/executable_spec.rb
index ff27d0b415..a11f547648 100644
--- a/spec/bundler/runtime/executable_spec.rb
+++ b/spec/bundler/runtime/executable_spec.rb
@@ -1,16 +1,15 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "Running bin/* commands" do
before :each do
- gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
it "runs the bundled command when in the bundle" do
- bundle "install --binstubs"
+ bundle "binstubs rack"
build_gem "rack", "2.0", :to_system => true do |s|
s.executables = "rackup"
@@ -21,7 +20,7 @@ RSpec.describe "Running bin/* commands" do
end
it "allows the location of the gem stubs to be specified" do
- bundle "install --binstubs gbin"
+ bundle "binstubs rack", :path => "gbin"
expect(bundled_app("bin")).not_to exist
expect(bundled_app("gbin/rackup")).to exist
@@ -31,33 +30,31 @@ RSpec.describe "Running bin/* commands" do
end
it "allows absolute paths as a specification of where to install bin stubs" do
- bundle "install --binstubs #{tmp}/bin"
+ bundle "binstubs rack", :path => tmp("bin")
gembin tmp("bin/rackup")
expect(out).to eq("1.0.0")
end
it "uses the default ruby install name when shebang is not specified" do
- bundle "install --binstubs"
- expect(File.open("bin/rackup").gets).to eq("#!/usr/bin/env #{RbConfig::CONFIG["ruby_install_name"]}\n")
+ bundle "binstubs rack"
+ expect(File.readlines(bundled_app("bin/rackup")).first).to eq("#!/usr/bin/env #{RbConfig::CONFIG["ruby_install_name"]}\n")
end
it "allows the name of the shebang executable to be specified" do
- bundle "install --binstubs --shebang ruby-foo"
- expect(File.open("bin/rackup").gets).to eq("#!/usr/bin/env ruby-foo\n")
+ bundle "binstubs rack", :shebang => "ruby-foo"
+ expect(File.readlines(bundled_app("bin/rackup")).first).to eq("#!/usr/bin/env ruby-foo\n")
end
it "runs the bundled command when out of the bundle" do
- bundle "install --binstubs"
+ bundle "binstubs rack"
build_gem "rack", "2.0", :to_system => true do |s|
s.executables = "rackup"
end
- Dir.chdir(tmp) do
- gembin "rackup"
- expect(out).to eq("1.0.0")
- end
+ gembin "rackup", :dir => tmp
+ expect(out).to eq("1.0.0")
end
it "works with gems in path" do
@@ -66,10 +63,11 @@ RSpec.describe "Running bin/* commands" do
end
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :path => "#{lib_path("rack")}"
G
- bundle "install --binstubs"
+ bundle "binstubs rack"
build_gem "rack", "2.0", :to_system => true do |s|
s.executables = "rackup"
@@ -79,19 +77,15 @@ RSpec.describe "Running bin/* commands" do
expect(out).to eq("1.0")
end
- it "don't bundle da bundla" do
- build_gem "bundler", Bundler::VERSION, :to_system => true do |s|
- s.executables = "bundle"
- end
-
+ it "creates a bundle binstub" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "bundler"
G
- bundle "install --binstubs"
+ bundle "binstubs bundler"
- expect(bundled_app("bin/bundle")).not_to exist
+ expect(bundled_app("bin/bundle")).to exist
end
it "does not generate bin stubs if the option was not specified" do
@@ -100,7 +94,9 @@ RSpec.describe "Running bin/* commands" do
expect(bundled_app("bin/rackup")).not_to exist
end
- it "allows you to stop installing binstubs" do
+ it "allows you to stop installing binstubs", :bundler => "< 3" do
+ skip "delete permission error" if Gem.win_platform?
+
bundle "install --binstubs bin/"
bundled_app("bin/rackup").rmtree
bundle "install --binstubs \"\""
@@ -111,16 +107,16 @@ RSpec.describe "Running bin/* commands" do
expect(out).to include("You have not configured a value for `bin`")
end
- it "remembers that the option was specified" do
+ it "remembers that the option was specified", :bundler => "< 3" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
G
- bundle "install --binstubs"
+ bundle :install, :binstubs => "bin"
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
gem "rack"
G
@@ -130,20 +126,44 @@ RSpec.describe "Running bin/* commands" do
expect(bundled_app("bin/rackup")).to exist
end
- it "rewrites bins on --binstubs (to maintain backwards compatibility)" do
- gemfile <<-G
- source "file://#{gem_repo1}"
+ it "rewrites bins on binstubs (to maintain backwards compatibility)" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle "install --binstubs bin/"
+ create_file("bin/rackup", "OMG")
- File.open(bundled_app("bin/rackup"), "wb") do |file|
- file.print "OMG"
+ bundle "binstubs rack"
+
+ expect(bundled_app("bin/rackup").read).to_not eq("OMG")
+ end
+
+ it "use BUNDLE_GEMFILE gemfile for binstub" do
+ # context with bin/bundler w/ default Gemfile
+ bundle "binstubs bundler"
+
+ # generate other Gemfile with executable gem
+ build_repo2 do
+ build_gem("bindir") {|s| s.executables = "foo" }
end
+ create_file("OtherGemfile", <<-G)
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'bindir'
+ G
+
+ # generate binstub for executable from non default Gemfile (other then bin/bundler version)
+ ENV["BUNDLE_GEMFILE"] = "OtherGemfile"
bundle "install"
+ bundle "binstubs bindir"
- expect(bundled_app("bin/rackup").read).to_not eq("OMG")
+ # remove user settings
+ ENV["BUNDLE_GEMFILE"] = nil
+
+ # run binstub for non default Gemfile
+ gembin "foo"
+
+ expect(out).to eq("1.0")
end
end
diff --git a/spec/bundler/runtime/gem_tasks_spec.rb b/spec/bundler/runtime/gem_tasks_spec.rb
index 7cb0f32c0c..b0ef0cc144 100644
--- a/spec/bundler/runtime/gem_tasks_spec.rb
+++ b/spec/bundler/runtime/gem_tasks_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "require 'bundler/gem_tasks'" do
before :each do
@@ -7,23 +6,32 @@ RSpec.describe "require 'bundler/gem_tasks'" do
f.write <<-GEMSPEC
Gem::Specification.new do |s|
s.name = "foo"
+ s.version = "1.0"
+ s.summary = "dummy"
+ s.author = "Perry Mason"
end
GEMSPEC
end
+
bundled_app("Rakefile").open("w") do |f|
f.write <<-RAKEFILE
- $:.unshift("#{bundler_path}")
require "bundler/gem_tasks"
RAKEFILE
end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rake"
+ G
end
it "includes the relevant tasks" do
- with_gem_path_as(Spec::Path.base_system_gems.to_s) do
- sys_exec "#{rake} -T"
+ with_gem_path_as(base_system_gems.to_s) do
+ sys_exec "#{rake} -T", :env => { "GEM_HOME" => system_gem_path.to_s }
end
- expect(err).to eq("")
+ expect(err).to be_empty
expected_tasks = [
"rake build",
"rake clean",
@@ -33,11 +41,66 @@ RSpec.describe "require 'bundler/gem_tasks'" do
]
tasks = out.lines.to_a.map {|s| s.split("#").first.strip }
expect(tasks & expected_tasks).to eq(expected_tasks)
- expect(exitstatus).to eq(0) if exitstatus
+ end
+
+ it "defines a working `rake install` task", :ruby_repo do
+ with_gem_path_as(base_system_gems.to_s) do
+ sys_exec "#{rake} install", :env => { "GEM_HOME" => system_gem_path.to_s }
+ end
+
+ expect(err).to be_empty
+
+ bundle "exec rake install"
+
+ expect(err).to be_empty
+ end
+
+ context "rake build when path has spaces", :ruby_repo do
+ before do
+ spaced_bundled_app = tmp.join("bundled app")
+ FileUtils.cp_r bundled_app, spaced_bundled_app
+ bundle "exec rake build", :dir => spaced_bundled_app
+ end
+
+ it "still runs successfully" do
+ expect(err).to be_empty
+ end
+ end
+
+ context "rake build when path has brackets", :ruby_repo do
+ before do
+ bracketed_bundled_app = tmp.join("bundled[app")
+ FileUtils.cp_r bundled_app, bracketed_bundled_app
+ bundle "exec rake build", :dir => bracketed_bundled_app
+ end
+
+ it "still runs successfully" do
+ expect(err).to be_empty
+ end
+ end
+
+ context "bundle path configured locally" do
+ before do
+ bundle "config set path vendor/bundle"
+ end
+
+ it "works", :ruby_repo do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rake"
+ G
+
+ bundle "exec rake -T"
+
+ expect(err).to be_empty
+ end
end
it "adds 'pkg' to rake/clean's CLOBBER" do
- require "bundler/gem_tasks"
- expect(CLOBBER).to include("pkg")
+ with_gem_path_as(base_system_gems.to_s) do
+ sys_exec %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect'), :env => { "GEM_HOME" => system_gem_path.to_s }
+ end
+ expect(out).to eq '["pkg"]'
end
end
diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb
index e816799d08..3b5ede41ee 100644
--- a/spec/bundler/runtime/inline_spec.rb
+++ b/spec/bundler/runtime/inline_spec.rb
@@ -1,12 +1,11 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundler/inline#gemfile" do
def script(code, options = {})
- requires = ["bundler/inline"]
- requires.unshift File.expand_path("../../support/artifice/" + options.delete(:artifice) + ".rb", __FILE__) if options.key?(:artifice)
+ requires = ["#{entrypoint}/inline"]
+ requires.unshift "#{spec_dir}/support/artifice/" + options.delete(:artifice) if options.key?(:artifice)
requires = requires.map {|r| "require '#{r}'" }.join("\n")
- @out = ruby("#{requires}\n\n" + code, options)
+ ruby("#{requires}\n\n" + code, options)
end
before :each do
@@ -44,27 +43,26 @@ RSpec.describe "bundler/inline#gemfile" do
build_lib "eight", "1.0.0" do |s|
s.write "lib/eight.rb", "puts 'eight'"
end
-
- build_lib "four", "1.0.0" do |s|
- s.write "lib/four.rb", "puts 'four'"
- end
end
it "requires the gems" do
script <<-RUBY
gemfile do
- path "#{lib_path}"
- gem "two"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "two"
+ end
end
RUBY
expect(out).to eq("two")
- expect(exitstatus).to be_zero if exitstatus
- script <<-RUBY
+ script <<-RUBY, :raise_on_error => false
gemfile do
- path "#{lib_path}"
- gem "eleven"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "eleven"
+ end
end
puts "success"
@@ -75,13 +73,12 @@ RSpec.describe "bundler/inline#gemfile" do
script <<-RUBY
gemfile(true) do
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
end
RUBY
expect(out).to include("Rack's post install message")
- expect(exitstatus).to be_zero if exitstatus
script <<-RUBY, :artifice => "endpoint"
gemfile(true) do
@@ -91,15 +88,14 @@ RSpec.describe "bundler/inline#gemfile" do
RUBY
expect(out).to include("Installing activesupport")
- err.gsub! %r{.*lib/sinatra/base\.rb:\d+: warning: constant ::Fixnum is deprecated$}, ""
- err.strip!
- expect(err).to lack_errors
- expect(exitstatus).to be_zero if exitstatus
+ err_lines = err.split("\n")
+ err_lines.reject!{|line| line =~ /\.rb:\d+: warning: / } unless RUBY_VERSION < "2.7"
+ expect(err_lines).to be_empty
end
it "lets me use my own ui object" do
script <<-RUBY, :artifice => "endpoint"
- require 'bundler'
+ require '#{entrypoint}'
class MyBundlerUI < Bundler::UI::Silent
def confirm(msg, newline = nil)
puts "CONFIRMED!"
@@ -112,11 +108,23 @@ RSpec.describe "bundler/inline#gemfile" do
RUBY
expect(out).to eq("CONFIRMED!\nCONFIRMED!")
- expect(exitstatus).to be_zero if exitstatus
+ end
+
+ it "has an option for quiet installation" do
+ script <<-RUBY, :artifice => "endpoint"
+ require '#{entrypoint}/inline'
+
+ gemfile(true, :quiet => true) do
+ source "https://notaserver.com"
+ gem "activesupport", :require => true
+ end
+ RUBY
+
+ expect(out).to be_empty
end
it "raises an exception if passed unknown arguments" do
- script <<-RUBY
+ script <<-RUBY, :raise_on_error => false
gemfile(true, :arglebargle => true) do
path "#{lib_path}"
gem "two"
@@ -130,23 +138,24 @@ RSpec.describe "bundler/inline#gemfile" do
it "does not mutate the option argument" do
script <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
options = { :ui => Bundler::UI::Shell.new }
gemfile(false, options) do
- path "#{lib_path}"
- gem "two"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "two"
+ end
end
puts "OKAY" if options.key?(:ui)
RUBY
expect(out).to match("OKAY")
- expect(exitstatus).to be_zero if exitstatus
end
it "installs quietly if necessary when the install option is not set" do
script <<-RUBY
gemfile do
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
end
@@ -155,7 +164,6 @@ RSpec.describe "bundler/inline#gemfile" do
expect(out).to eq("1.0.0")
expect(err).to be_empty
- expect(exitstatus).to be_zero if exitstatus
end
it "installs quietly from git if necessary when the install option is not set" do
@@ -163,6 +171,7 @@ RSpec.describe "bundler/inline#gemfile" do
baz_ref = build_git("baz", "2.0.0").ref_for("HEAD")
script <<-RUBY
gemfile do
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => #{lib_path("foo-1.0.0").to_s.dump}
gem "baz", :git => #{lib_path("baz-2.0.0").to_s.dump}, :ref => #{baz_ref.dump}
end
@@ -173,19 +182,20 @@ RSpec.describe "bundler/inline#gemfile" do
expect(out).to eq("1.0.0\n2.0.0")
expect(err).to be_empty
- expect(exitstatus).to be_zero if exitstatus
end
it "allows calling gemfile twice" do
script <<-RUBY
gemfile do
path "#{lib_path}" do
+ source "#{file_uri_for(gem_repo1)}"
gem "two"
end
end
gemfile do
path "#{lib_path}" do
+ source "#{file_uri_for(gem_repo1)}"
gem "four"
end
end
@@ -193,7 +203,6 @@ RSpec.describe "bundler/inline#gemfile" do
expect(out).to eq("two\nfour")
expect(err).to be_empty
- expect(exitstatus).to be_zero if exitstatus
end
it "installs inline gems when a Gemfile.lock is present" do
@@ -215,40 +224,60 @@ RSpec.describe "bundler/inline#gemfile" do
rake
BUNDLED WITH
- 1.13.6
+ #{Bundler::VERSION}
G
- in_app_root do
- script <<-RUBY
- gemfile do
- source "file://#{gem_repo1}"
- gem "rack"
- end
+ script <<-RUBY
+ gemfile do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ end
- puts RACK
- RUBY
- end
+ puts RACK
+ RUBY
expect(err).to be_empty
- expect(exitstatus).to be_zero if exitstatus
+ end
+
+ it "installs inline gems when frozen is set" do
+ script <<-RUBY, :env => { "BUNDLE_FROZEN" => "true" }
+ gemfile do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ end
+
+ puts RACK
+ RUBY
+
+ expect(last_command.stderr).to be_empty
+ end
+
+ it "installs inline gems when deployment is set" do
+ script <<-RUBY, :env => { "BUNDLE_DEPLOYMENT" => "true" }
+ gemfile do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ end
+
+ puts RACK
+ RUBY
+
+ expect(last_command.stderr).to be_empty
end
it "installs inline gems when BUNDLE_GEMFILE is set to an empty string" do
ENV["BUNDLE_GEMFILE"] = ""
- in_app_root do
- script <<-RUBY
- gemfile do
- source "file://#{gem_repo1}"
- gem "rack"
- end
+ script <<-RUBY
+ gemfile do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ end
- puts RACK
- RUBY
- end
+ puts RACK
+ RUBY
expect(err).to be_empty
- expect(exitstatus).to be_zero if exitstatus
end
it "installs inline gems when BUNDLE_BIN is set" do
@@ -256,13 +285,136 @@ RSpec.describe "bundler/inline#gemfile" do
script <<-RUBY
gemfile do
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack" # has the rackup executable
end
puts RACK
RUBY
- expect(exitstatus).to eq(0) if exitstatus
+ expect(last_command).to be_success
expect(out).to eq "1.0.0"
end
+
+ context "when BUNDLE_PATH is set" do
+ it "installs inline gems to the system path regardless" do
+ script <<-RUBY, :env => { "BUNDLE_PATH" => "./vendor/inline" }
+ gemfile(true) do
+ source "file://#{gem_repo1}"
+ gem "rack"
+ end
+ RUBY
+ expect(last_command).to be_success
+ expect(system_gem_path("gems/rack-1.0.0")).to exist
+ end
+ end
+
+ it "skips platform warnings" do
+ simulate_platform "ruby"
+
+ script <<-RUBY
+ gemfile(true) do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", platform: :jruby
+ end
+ RUBY
+
+ expect(err).to be_empty
+ end
+
+ it "preserves previous BUNDLE_GEMFILE value" do
+ ENV["BUNDLE_GEMFILE"] = ""
+ script <<-RUBY
+ gemfile do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ end
+
+ puts "BUNDLE_GEMFILE is empty" if ENV["BUNDLE_GEMFILE"].empty?
+ system("#{Gem.ruby} -w -e '42'") # this should see original value of BUNDLE_GEMFILE
+ exit $?.exitstatus
+ RUBY
+
+ expect(last_command).to be_success
+ expect(out).to include("BUNDLE_GEMFILE is empty")
+ end
+
+ it "resets BUNDLE_GEMFILE to the empty string if it wasn't set previously" do
+ ENV["BUNDLE_GEMFILE"] = nil
+ script <<-RUBY
+ gemfile do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ end
+
+ puts "BUNDLE_GEMFILE is empty" if ENV["BUNDLE_GEMFILE"].empty?
+ system("#{Gem.ruby} -w -e '42'") # this should see original value of BUNDLE_GEMFILE
+ exit $?.exitstatus
+ RUBY
+
+ expect(last_command).to be_success
+ expect(out).to include("BUNDLE_GEMFILE is empty")
+ end
+
+ it "does not error out if library requires optional dependencies" do
+ Dir.mkdir tmp("path_without_gemfile")
+
+ foo_code = <<~RUBY
+ begin
+ gem "bar"
+ rescue LoadError
+ end
+
+ puts "WIN"
+ RUBY
+
+ build_lib "foo", "1.0.0" do |s|
+ s.write "lib/foo.rb", foo_code
+ end
+
+ script <<-RUBY, :dir => tmp("path_without_gemfile")
+ gemfile do
+ source "#{file_uri_for(gem_repo2)}"
+ path "#{lib_path}" do
+ gem "foo", require: false
+ end
+ end
+
+ require "foo"
+ RUBY
+
+ expect(out).to eq("WIN")
+ expect(err).to be_empty
+ end
+
+ it "when requiring fileutils after does not show redefinition warnings" do
+ dependency_installer_loads_fileutils = ruby "require 'rubygems/dependency_installer'; puts $LOADED_FEATURES.grep(/fileutils/)", :raise_on_error => false
+ skip "does not work if rubygems/dependency_installer loads fileutils, which happens until rubygems 3.2.0" unless dependency_installer_loads_fileutils.empty?
+
+ skip "pathname does not install cleanly on this ruby" if RUBY_VERSION < "2.7.0"
+
+ Dir.mkdir tmp("path_without_gemfile")
+
+ default_fileutils_version = ruby "gem 'fileutils', '< 999999'; require 'fileutils'; puts FileUtils::VERSION", :raise_on_error => false
+ skip "fileutils isn't a default gem" if default_fileutils_version.empty?
+
+ realworld_system_gems "fileutils --version 1.4.1"
+
+ realworld_system_gems "pathname --version 0.2.0"
+
+ realworld_system_gems "fiddle" # not sure why, but this is needed on Windows to boot rubygems successfully
+
+ realworld_system_gems "timeout uri" # this spec uses net/http which requires these default gems
+
+ script <<-RUBY, :dir => tmp("path_without_gemfile"), :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
+ require "bundler/inline"
+
+ gemfile(true) do
+ source "#{file_uri_for(gem_repo2)}"
+ end
+
+ require "fileutils"
+ RUBY
+
+ expect(err).to eq("The Gemfile specifies no dependencies")
+ end
end
diff --git a/spec/bundler/runtime/load_spec.rb b/spec/bundler/runtime/load_spec.rb
index d0e308ed3e..96a22a46cc 100644
--- a/spec/bundler/runtime/load_spec.rb
+++ b/spec/bundler/runtime/load_spec.rb
@@ -1,17 +1,13 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "Bundler.load" do
- before :each do
- system_gems "rack-1.0.0"
- end
-
describe "with a gemfile" do
before(:each) do
- gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
+ allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app)
end
it "provides a list of the env dependencies" do
@@ -33,9 +29,11 @@ RSpec.describe "Bundler.load" do
describe "with a gems.rb file" do
before(:each) do
create_file "gems.rb", <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
+ bundle :install
+ allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app)
end
it "provides a list of the env dependencies" do
@@ -62,7 +60,7 @@ RSpec.describe "Bundler.load" do
end
it "does not find a Gemfile above the testing directory" do
- bundler_gemfile = tmp.join("../Gemfile")
+ bundler_gemfile = Pathname.new(__dir__).join("../../Gemfile")
unless File.exist?(bundler_gemfile)
FileUtils.touch(bundler_gemfile)
@remove_bundler_gemfile = true
@@ -77,14 +75,14 @@ RSpec.describe "Bundler.load" do
describe "when called twice" do
it "doesn't try to load the runtime twice" do
- system_gems "rack-1.0.0", "activesupport-2.3.5"
- gemfile <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "activesupport", :group => :test
G
ruby <<-RUBY
- require "bundler"
+ require "#{entrypoint}"
Bundler.setup :default
Bundler.require :default
puts RACK
@@ -101,11 +99,11 @@ RSpec.describe "Bundler.load" do
describe "not hurting brittle rubygems" do
it "does not inject #source into the generated YAML of the gem specs" do
- system_gems "activerecord-2.3.2", "activesupport-2.3.2"
- gemfile <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "activerecord"
G
-
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
Bundler.load.specs.each do |spec|
expect(spec.to_yaml).not_to match(/^\s+source:/)
expect(spec.to_yaml).not_to match(/^\s+groups:/)
diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb
index 4df934e71f..433396d106 100644
--- a/spec/bundler/runtime/platform_spec.rb
+++ b/spec/bundler/runtime/platform_spec.rb
@@ -1,16 +1,15 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "Bundler.setup with multi platform stuff" do
it "raises a friendly error when gems are missing locally" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0)
@@ -23,8 +22,8 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
ruby <<-R
begin
- require 'bundler'
- Bundler.setup
+ require '#{entrypoint}'
+ Bundler.ui.silence { Bundler.setup }
rescue Bundler::GemNotFound => e
puts "WIN"
end
@@ -33,10 +32,10 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(out).to eq("WIN")
end
- it "will resolve correctly on the current platform when the lockfile was targetted for a different one" do
+ it "will resolve correctly on the current platform when the lockfile was targeted for a different one" do
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
nokogiri (1.4.2-java)
weakling (= 0.0.3)
@@ -49,21 +48,139 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
nokogiri
G
- system_gems "nokogiri-1.4.2"
-
simulate_platform "x86-darwin-10"
- gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri"
G
expect(the_bundle).to include_gems "nokogiri 1.4.2"
end
+ it "will keep both platforms when both ruby and a specific ruby platform are locked and the bundle is unlocked" do
+ build_repo4 do
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.add_dependency "mini_portile2", "~> 2.5.0"
+ s.add_dependency "racc", "~> 1.5.2"
+ end
+
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.platform = Bundler.local_platform
+ s.add_dependency "racc", "~> 1.4"
+ end
+
+ build_gem "mini_portile2", "2.5.0"
+ build_gem "racc", "1.5.2"
+ end
+
+ good_lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ mini_portile2 (2.5.0)
+ nokogiri (1.11.1)
+ mini_portile2 (~> 2.5.0)
+ racc (~> 1.5.2)
+ nokogiri (1.11.1-#{Bundler.local_platform})
+ racc (~> 1.4)
+ racc (1.5.2)
+
+ PLATFORMS
+ #{lockfile_platforms_for(["ruby"] + local_platforms)}
+
+ DEPENDENCIES
+ nokogiri (~> 1.11)
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "nokogiri", "~> 1.11"
+ G
+
+ lockfile good_lockfile
+
+ bundle "update nokogiri"
+
+ expect(lockfile).to eq(good_lockfile)
+ end
+
+ it "will not try to install platform specific gems when they don't match the current ruby if locked only to ruby" do
+ build_repo4 do
+ build_gem "nokogiri", "1.11.1"
+
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.platform = Bundler.local_platform
+ s.required_ruby_version = "< #{Gem.ruby_version}"
+ end
+ end
+
+ gemfile <<-G
+ source "https://gems.repo4"
+ gem "nokogiri"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gems.repo4/
+ specs:
+ nokogiri (1.11.1)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ nokogiri
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+
+ expect(out).to include("Fetching nokogiri 1.11.1")
+ expect(the_bundle).to include_gems "nokogiri 1.11.1"
+ expect(the_bundle).not_to include_gems "nokogiri 1.11.1 #{Bundler.local_platform}"
+ end
+
+ it "will use the java platform if both generic java and generic ruby platforms are locked", :jruby do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "nokogiri"
+ G
+
+ lockfile <<-G
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ nokogiri (1.4.2)
+ nokogiri (1.4.2-java)
+ weakling (>= 0.0.3)
+ weakling (0.0.3)
+
+ PLATFORMS
+ java
+ ruby
+
+ DEPENDENCIES
+ nokogiri
+
+ BUNDLED WITH
+ 2.1.4
+ G
+
+ bundle "install"
+
+ expect(out).to include("Fetching nokogiri 1.4.2 (java)")
+ expect(the_bundle).to include_gems "nokogiri 1.4.2 JAVA"
+ end
+
it "will add the resolve for the current platform" do
lockfile <<-G
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
nokogiri (1.4.2-java)
weakling (= 0.0.3)
@@ -78,10 +195,8 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
simulate_platform "x86-darwin-100"
- system_gems "nokogiri-1.4.2", "platform_specific-1.0-x86-darwin-100"
-
- gemfile <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri"
gem "platform_specific"
G
@@ -89,35 +204,108 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 x86-darwin-100"
end
- it "allows specifying only-ruby-platform" do
- simulate_platform "java"
+ it "allows specifying only-ruby-platform on jruby", :jruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "nokogiri"
+ gem "platform_specific"
+ G
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ bundle "config set force_ruby_platform true"
+
+ bundle "install"
+
+ expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 RUBY"
+ end
+
+ it "allows specifying only-ruby-platform" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri"
gem "platform_specific"
G
- bundle! "config force_ruby_platform true"
+ bundle "config set force_ruby_platform true"
- bundle! "install"
+ bundle "install"
expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 RUBY"
end
+ it "doesn't pull platform specific gems on truffleruby", :truffleruby do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "platform_specific"
+ G
+
+ expect(the_bundle).to include_gems "platform_specific 1.0 RUBY"
+ end
+
it "allows specifying only-ruby-platform on windows with dependency platforms" do
simulate_windows do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platforms => [:mingw, :mswin, :x64_mingw, :jruby]
gem "platform_specific"
G
- bundle! "config force_ruby_platform true"
+ bundle "config set force_ruby_platform true"
- bundle! "install"
+ bundle "install"
expect(the_bundle).to include_gems "platform_specific 1.0 RUBY"
+ expect(the_bundle).to not_include_gems "nokogiri"
+ end
+ end
+
+ it "allows specifying only-ruby-platform on windows with gemspec dependency" do
+ build_lib("foo", "1.0", :path => bundled_app) do |s|
+ s.add_dependency "rack"
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gemspec
+ G
+ bundle :lock
+
+ simulate_windows do
+ bundle "config set force_ruby_platform true"
+ bundle "install"
+
+ expect(the_bundle).to include_gems "rack 1.0"
+ end
+ end
+
+ it "recovers when the lockfile is missing a platform-specific gem" do
+ build_repo2 do
+ build_gem "requires_platform_specific" do |s|
+ s.add_dependency "platform_specific"
+ end
+ end
+ simulate_windows x64_mingw do
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ platform_specific (1.0-x86-mingw32)
+ requires_platform_specific (1.0)
+ platform_specific
+
+ PLATFORMS
+ x64-mingw32
+ x86-mingw32
+
+ DEPENDENCIES
+ requires_platform_specific
+ L
+
+ install_gemfile <<-G, :verbose => true
+ source "#{file_uri_for(gem_repo2)}"
+ gem "requires_platform_specific"
+ G
+
+ expect(the_bundle).to include_gem "platform_specific 1.0 x64-mingw32"
end
end
end
diff --git a/spec/bundler/runtime/require_spec.rb b/spec/bundler/runtime/require_spec.rb
index b68313726b..d91b5f8666 100644
--- a/spec/bundler/runtime/require_spec.rb
+++ b/spec/bundler/runtime/require_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "Bundler.require" do
before :each do
@@ -47,19 +46,21 @@ RSpec.describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "one", :group => :bar, :require => %w[baz qux]
- gem "two"
- gem "three", :group => :not
- gem "four", :require => false
- gem "five"
- gem "six", :group => "string"
- gem "seven", :group => :not
- gem "eight", :require => true, :group => :require_true
- env "BUNDLER_TEST" => "nine" do
- gem "nine", :require => true
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "one", :group => :bar, :require => %w[baz qux]
+ gem "two"
+ gem "three", :group => :not
+ gem "four", :require => false
+ gem "five"
+ gem "six", :group => "string"
+ gem "seven", :group => :not
+ gem "eight", :require => true, :group => :require_true
+ env "BUNDLER_TEST" => "nine" do
+ gem "nine", :require => true
+ end
+ gem "ten", :install_if => lambda { ENV["BUNDLER_TEST"] == "ten" }
end
- gem "ten", :install_if => lambda { ENV["BUNDLER_TEST"] == "ten" }
G
end
@@ -86,7 +87,7 @@ RSpec.describe "Bundler.require" do
# required in resolver order instead of gemfile order
run("Bundler.require(:not)")
- expect(out.split("\n").sort).to eq(%w(seven three))
+ expect(out.split("\n").sort).to eq(%w[seven three])
# test require: true
run "Bundler.require(:require_true)"
@@ -112,15 +113,17 @@ RSpec.describe "Bundler.require" do
it "raises an exception if a require is specified but the file does not exist" do
gemfile <<-G
- path "#{lib_path}"
- gem "two", :require => 'fail'
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "two", :require => 'fail'
+ end
G
load_error_run <<-R, "fail"
Bundler.require
R
- expect(err).to eq_err("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
end
it "displays a helpful message if the required gem throws an error" do
@@ -129,11 +132,13 @@ RSpec.describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "faulty"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "faulty"
+ end
G
- run "Bundler.require"
+ run "Bundler.require", :raise_on_error => false
expect(err).to match("error while trying to load the gem 'faulty'")
expect(err).to match("Gem Internal Error Message")
end
@@ -144,20 +149,22 @@ RSpec.describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "loadfuuu"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "loadfuuu"
+ end
G
cmd = <<-RUBY
begin
Bundler.require
rescue LoadError => e
- $stderr.puts "ZOMG LOAD ERROR: \#{e.message}"
+ warn "ZOMG LOAD ERROR: \#{e.message}"
end
RUBY
run(cmd)
- expect(err).to eq_err("ZOMG LOAD ERROR: cannot load such file -- load-bar")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR: cannot load such file -- load-bar")
end
describe "with namespaced gems" do
@@ -165,13 +172,14 @@ RSpec.describe "Bundler.require" do
build_lib "jquery-rails", "1.0.0" do |s|
s.write "lib/jquery/rails.rb", "puts 'jquery/rails'"
end
- lib_path("jquery-rails-1.0.0/lib/jquery-rails.rb").rmtree
end
it "requires gem names that are namespaced" do
gemfile <<-G
- path '#{lib_path}'
- gem 'jquery-rails'
+ source "#{file_uri_for(gem_repo1)}"
+ path '#{lib_path}' do
+ gem 'jquery-rails'
+ end
G
run "Bundler.require"
@@ -183,29 +191,34 @@ RSpec.describe "Bundler.require" do
s.write "lib/brcrypt.rb", "BCrypt = '1.0.0'"
end
gemfile <<-G
- path "#{lib_path}"
- gem "bcrypt-ruby"
+ source "#{file_uri_for(gem_repo1)}"
+
+ path "#{lib_path}" do
+ gem "bcrypt-ruby"
+ end
G
cmd = <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
Bundler.require
RUBY
ruby(cmd)
- expect(err).to lack_errors
+ expect(err).to be_empty
end
it "does not mangle explicitly given requires" do
gemfile <<-G
- path "#{lib_path}"
- gem 'jquery-rails', :require => 'jquery-rails'
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem 'jquery-rails', :require => 'jquery-rails'
+ end
G
load_error_run <<-R, "jquery-rails"
Bundler.require
R
- expect(err).to eq_err("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
end
it "handles the case where regex fails" do
@@ -214,43 +227,46 @@ RSpec.describe "Bundler.require" do
end
gemfile <<-G
- path "#{lib_path}"
- gem "load-fuuu"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "load-fuuu"
+ end
G
cmd = <<-RUBY
begin
Bundler.require
rescue LoadError => e
- $stderr.puts "ZOMG LOAD ERROR" if e.message.include?("Could not open library 'libfuuu-1.0'")
+ warn "ZOMG LOAD ERROR" if e.message.include?("Could not open library 'libfuuu-1.0'")
end
RUBY
run(cmd)
- expect(err).to eq_err("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
end
it "doesn't swallow the error when the library has an unrelated error" do
build_lib "load-fuuu", "1.0.0" do |s|
s.write "lib/load/fuuu.rb", "raise LoadError.new(\"cannot load such file -- load-bar\")"
end
- lib_path("load-fuuu-1.0.0/lib/load-fuuu.rb").rmtree
gemfile <<-G
- path "#{lib_path}"
- gem "load-fuuu"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "load-fuuu"
+ end
G
cmd = <<-RUBY
begin
Bundler.require
rescue LoadError => e
- $stderr.puts "ZOMG LOAD ERROR: \#{e.message}"
+ warn "ZOMG LOAD ERROR: \#{e.message}"
end
RUBY
run(cmd)
- expect(err).to eq_err("ZOMG LOAD ERROR: cannot load such file -- load-bar")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR: cannot load such file -- load-bar")
end
end
@@ -294,9 +310,11 @@ RSpec.describe "Bundler.require" do
it "works when the gems are in the Gemfile in the correct order" do
gemfile <<-G
- path "#{lib_path}"
- gem "two"
- gem "one"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "two"
+ gem "one"
+ end
G
run "Bundler.require"
@@ -305,12 +323,13 @@ RSpec.describe "Bundler.require" do
describe "a gem with different requires for different envs" do
before(:each) do
- build_gem "multi_gem", :to_system => true do |s|
+ build_gem "multi_gem", :to_bundle => true do |s|
s.write "lib/one.rb", "puts 'ONE'"
s.write "lib/two.rb", "puts 'TWO'"
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "multi_gem", :require => "one", :group => :one
gem "multi_gem", :require => "two", :group => :two
G
@@ -334,9 +353,11 @@ RSpec.describe "Bundler.require" do
it "fails when the gems are in the Gemfile in the wrong order" do
gemfile <<-G
- path "#{lib_path}"
- gem "one"
- gem "two"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path}" do
+ gem "one"
+ gem "two"
+ end
G
run "Bundler.require"
@@ -345,29 +366,30 @@ RSpec.describe "Bundler.require" do
describe "with busted gems" do
it "should be busted" do
- build_gem "busted_require", :to_system => true do |s|
+ build_gem "busted_require", :to_bundle => true do |s|
s.write "lib/busted_require.rb", "require 'no_such_file_omg'"
end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "busted_require"
G
load_error_run <<-R, "no_such_file_omg"
Bundler.require
R
- expect(err).to eq_err("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
end
end
end
- it "does not load rubygems gemspecs that are used", :rubygems => ">= 2.5.2" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ it "does not load rubygems gemspecs that are used" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- run! <<-R
+ run <<-R
path = File.join(Gem.dir, "specifications", "rack-1.0.0.gemspec")
contents = File.read(path)
contents = contents.lines.to_a.insert(-2, "\n raise 'broken gemspec'\n").join
@@ -376,7 +398,7 @@ RSpec.describe "Bundler.require" do
end
R
- run! <<-R
+ run <<-R
Bundler.require
puts "WIN"
R
@@ -384,14 +406,15 @@ RSpec.describe "Bundler.require" do
expect(out).to eq("WIN")
end
- it "does not load git gemspecs that are used", :rubygems => ">= 2.5.2" do
+ it "does not load git gemspecs that are used" do
build_git "foo"
- install_gemfile! <<-G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- run! <<-R
+ run <<-R
path = Gem.loaded_specs["foo"].loaded_from
contents = File.read(path)
contents = contents.lines.to_a.insert(-2, "\n raise 'broken gemspec'\n").join
@@ -400,7 +423,7 @@ RSpec.describe "Bundler.require" do
end
R
- run! <<-R
+ run <<-R
Bundler.require
puts "WIN"
R
@@ -412,22 +435,24 @@ end
RSpec.describe "Bundler.require with platform specific dependencies" do
it "does not require the gems that are pinned to other platforms" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
platforms :#{not_local_tag} do
- gem "fail", :require => "omgomg"
+ gem "platform_specific", :require => "omgomg"
end
gem "rack", "1.0.0"
G
run "Bundler.require"
- expect(err).to lack_errors
+ expect(err).to be_empty
end
it "requires gems pinned to multiple platforms, including the current one" do
+ skip "platform issues" if Gem.win_platform?
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
platforms :#{not_local_tag}, :#{local_tag} do
gem "rack", :require => "rack"
@@ -437,6 +462,6 @@ RSpec.describe "Bundler.require with platform specific dependencies" do
run "Bundler.require; puts RACK"
expect(out).to eq("1.0.0")
- expect(err).to lack_errors
+ expect(err).to be_empty
end
end
diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb
index dc7af07188..35873dcaa9 100644
--- a/spec/bundler/runtime/setup_spec.rb
+++ b/spec/bundler/runtime/setup_spec.rb
@@ -1,23 +1,24 @@
# frozen_string_literal: true
-require "spec_helper"
+
+require "tmpdir"
+require "tempfile"
RSpec.describe "Bundler.setup" do
describe "with no arguments" do
it "makes all groups available" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :group => :test
G
ruby <<-RUBY
- require 'rubygems'
require 'bundler'
Bundler.setup
require 'rack'
puts RACK
RUBY
- expect(err).to lack_errors
+ expect(err).to be_empty
expect(out).to eq("1.0.0")
end
end
@@ -25,7 +26,7 @@ RSpec.describe "Bundler.setup" do
describe "when called with groups" do
before(:each) do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack", :group => :test
G
@@ -33,7 +34,6 @@ RSpec.describe "Bundler.setup" do
it "doesn't make all groups available" do
ruby <<-RUBY
- require 'rubygems'
require 'bundler'
Bundler.setup(:default)
@@ -43,26 +43,24 @@ RSpec.describe "Bundler.setup" do
puts "WIN"
end
RUBY
- expect(err).to lack_errors
+ expect(err).to be_empty
expect(out).to eq("WIN")
end
it "accepts string for group name" do
ruby <<-RUBY
- require 'rubygems'
require 'bundler'
Bundler.setup(:default, 'test')
require 'rack'
puts RACK
RUBY
- expect(err).to lack_errors
+ expect(err).to be_empty
expect(out).to eq("1.0.0")
end
it "leaves all groups available if they were already" do
ruby <<-RUBY
- require 'rubygems'
require 'bundler'
Bundler.setup
Bundler.setup(:default)
@@ -70,13 +68,12 @@ RSpec.describe "Bundler.setup" do
require 'rack'
puts RACK
RUBY
- expect(err).to lack_errors
+ expect(err).to be_empty
expect(out).to eq("1.0.0")
end
it "leaves :default available if setup is called twice" do
ruby <<-RUBY
- require 'rubygems'
require 'bundler'
Bundler.setup(:default)
Bundler.setup(:default, :test)
@@ -88,12 +85,12 @@ RSpec.describe "Bundler.setup" do
puts "FAIL"
end
RUBY
- expect(err).to lack_errors
+ expect(err).to be_empty
expect(out).to match("WIN")
end
it "handles multiple non-additive invocations" do
- ruby <<-RUBY
+ ruby <<-RUBY, :raise_on_error => false
require 'bundler'
Bundler.setup(:default, :test)
Bundler.setup(:default)
@@ -110,27 +107,21 @@ RSpec.describe "Bundler.setup" do
context "load order" do
def clean_load_path(lp)
- without_bundler_load_path = ruby!("puts $LOAD_PATH").split("\n")
- lp = lp - [
- bundler_path.to_s,
- bundler_path.join("gems/bundler-#{Bundler::VERSION}/lib").to_s,
- tmp("rubygems/lib").to_s,
- root.join("../lib").expand_path.to_s,
- ] - without_bundler_load_path
- lp.map! {|p| p.sub(/^#{system_gem_path}/, "") }
+ without_bundler_load_path = ruby("puts $LOAD_PATH").split("\n")
+ lp -= [*without_bundler_load_path, lib_dir.to_s]
+ lp.map! {|p| p.sub(system_gem_path.to_s, "") }
end
it "puts loaded gems after -I and RUBYLIB", :ruby_repo do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- ENV["RUBYOPT"] = "-Idash_i_dir"
+ ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -Idash_i_dir"
ENV["RUBYLIB"] = "rubylib_dir"
ruby <<-RUBY
- require 'rubygems'
require 'bundler'
Bundler.setup
puts $LOAD_PATH
@@ -139,20 +130,20 @@ RSpec.describe "Bundler.setup" do
load_path = out.split("\n")
rack_load_order = load_path.index {|path| path.include?("rack") }
- expect(err).to eq("")
- expect(load_path[1]).to include "dash_i_dir"
- expect(load_path[2]).to include "rubylib_dir"
+ expect(err).to be_empty
+ expect(load_path).to include(a_string_ending_with("dash_i_dir"), "rubylib_dir")
expect(rack_load_order).to be > 0
end
- it "orders the load path correctly when there are dependencies", :ruby_repo do
+ it "orders the load path correctly when there are dependencies" do
+ bundle "config set path.system true"
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
- ruby! <<-RUBY
- require 'rubygems'
+ ruby <<-RUBY
require 'bundler'
Bundler.setup
puts $LOAD_PATH
@@ -167,20 +158,21 @@ RSpec.describe "Bundler.setup" do
"/gems/actionpack-2.3.2/lib",
"/gems/actionmailer-2.3.2/lib",
"/gems/activesupport-2.3.2/lib",
- "/gems/rake-10.0.2/lib"
+ "/gems/rake-13.0.1/lib"
)
end
it "falls back to order the load path alphabetically for backwards compatibility" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ bundle "config set path.system true"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "weakling"
gem "duradura"
gem "terranova"
G
- ruby! <<-RUBY
- require 'rubygems'
+ ruby <<-RUBY
require 'bundler/setup'
puts $LOAD_PATH
RUBY
@@ -197,13 +189,12 @@ RSpec.describe "Bundler.setup" do
it "raises if the Gemfile was not yet installed" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
ruby <<-R
- require 'rubygems'
- require 'bundler'
+ require '#{entrypoint}'
begin
Bundler.setup
@@ -218,79 +209,106 @@ RSpec.describe "Bundler.setup" do
it "doesn't create a Gemfile.lock if the setup fails" do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- ruby <<-R
- require 'rubygems'
+ ruby <<-R, :raise_on_error => false
require 'bundler'
Bundler.setup
R
- expect(bundled_app("Gemfile.lock")).not_to exist
+ expect(bundled_app_lock).not_to exist
end
it "doesn't change the Gemfile.lock if the setup fails" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- lockfile = File.read(bundled_app("Gemfile.lock"))
+ lockfile = File.read(bundled_app_lock)
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "nosuchgem", "10.0"
G
- ruby <<-R
- require 'rubygems'
+ ruby <<-R, :raise_on_error => false
require 'bundler'
Bundler.setup
R
- expect(File.read(bundled_app("Gemfile.lock"))).to eq(lockfile)
+ expect(File.read(bundled_app_lock)).to eq(lockfile)
end
it "makes a Gemfile.lock if setup succeeds" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- File.read(bundled_app("Gemfile.lock"))
+ File.read(bundled_app_lock)
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
run "1"
- expect(bundled_app("Gemfile.lock")).to exist
+ expect(bundled_app_lock).to exist
end
- it "uses BUNDLE_GEMFILE to locate the gemfile if present" do
- gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack"
- G
+ describe "$BUNDLE_GEMFILE" do
+ context "user provides an absolute path" do
+ it "uses BUNDLE_GEMFILE to locate the gemfile if present" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
- gemfile bundled_app("4realz"), <<-G
- source "file://#{gem_repo1}"
- gem "activesupport", "2.3.5"
- G
+ gemfile bundled_app("4realz"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "activesupport", "2.3.5"
+ G
+
+ ENV["BUNDLE_GEMFILE"] = bundled_app("4realz").to_s
+ bundle :install
+
+ expect(the_bundle).to include_gems "activesupport 2.3.5"
+ end
+ end
+
+ context "an absolute path is not provided" do
+ it "uses BUNDLE_GEMFILE to locate the gemfile if present and doesn't fail in deployment mode" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
+ bundle "install"
+ bundle "config set --local deployment true"
- ENV["BUNDLE_GEMFILE"] = bundled_app("4realz").to_s
- bundle :install
+ ENV["BUNDLE_GEMFILE"] = "Gemfile"
+ ruby <<-R
+ require 'bundler'
+
+ begin
+ Bundler.setup
+ puts "WIN"
+ rescue ArgumentError => e
+ puts "FAIL"
+ end
+ R
- expect(the_bundle).to include_gems "activesupport 2.3.5"
+ expect(out).to eq("WIN")
+ end
+ end
end
it "prioritizes gems in BUNDLE_PATH over gems in GEM_HOME" do
ENV["BUNDLE_PATH"] = bundled_app(".bundle").to_s
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
G
@@ -305,7 +323,7 @@ RSpec.describe "Bundler.setup" do
describe "by replacing #gem" do
before :each do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
G
end
@@ -333,7 +351,7 @@ RSpec.describe "Bundler.setup" do
end
R
- expect(err).to lack_errors
+ expect(err).to be_empty
end
it "replaces #gem but raises when the version is wrong" do
@@ -359,7 +377,7 @@ RSpec.describe "Bundler.setup" do
end
R
- expect(err).to lack_errors
+ expect(err).to be_empty
end
end
@@ -367,7 +385,7 @@ RSpec.describe "Bundler.setup" do
before :each do
system_gems "activesupport-2.3.5"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "yard"
G
end
@@ -396,9 +414,10 @@ RSpec.describe "Bundler.setup" do
end
gemfile <<-G
- path "#{lib_path("rack-1.0.0")}"
- source "file://#{gem_repo1}"
- gem "rack"
+ source "#{file_uri_for(gem_repo1)}"
+ path "#{lib_path("rack-1.0.0")}" do
+ gem "rack"
+ end
G
run "require 'rack'"
@@ -411,12 +430,13 @@ RSpec.describe "Bundler.setup" do
build_git "rack", "1.0.0"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-1.0.0")}"
G
end
it "provides a useful exception when the git repo is not checked out yet" do
- run "1"
+ run "1", :raise_on_error => false
expect(err).to match(/the git source #{lib_path('rack-1.0.0')} is not yet checked out. Please run `bundle install`/i)
end
@@ -426,7 +446,6 @@ RSpec.describe "Bundler.setup" do
break_git!
ruby <<-R
- require 'rubygems'
require 'bundler'
begin
@@ -443,13 +462,12 @@ RSpec.describe "Bundler.setup" do
it "provides a good exception if the lockfile is unavailable" do
bundle "install"
- FileUtils.rm(bundled_app("Gemfile.lock"))
+ FileUtils.rm(bundled_app_lock)
break_git!
ruby <<-R
- require "rubygems"
- require "bundler"
+ require "#{entrypoint}"
begin
Bundler.setup
@@ -459,29 +477,32 @@ RSpec.describe "Bundler.setup" do
end
R
- run "puts 'FAIL'"
+ run "puts 'FAIL'", :raise_on_error => false
expect(err).not_to include "This is not the git you are looking for"
end
it "works even when the cache directory has been deleted" do
- bundle "install --path vendor/bundle"
+ bundle "config set --local path vendor/bundle"
+ bundle :install
FileUtils.rm_rf vendored_gems("cache")
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "does not randomly change the path when specifying --path and the bundle directory becomes read only" do
- bundle "install --path vendor/bundle"
+ bundle "config set --local path vendor/bundle"
+ bundle :install
- with_read_only("**/*") do
+ with_read_only("#{bundled_app}/**/*") do
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
it "finds git gem when default bundle path becomes read only" do
+ bundle "config set --local path .bundle"
bundle "install"
- with_read_only("#{Bundler.bundle_path}/**/*") do
+ with_read_only("#{bundled_app(".bundle")}/**/*") do
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
@@ -494,16 +515,15 @@ RSpec.describe "Bundler.setup" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
bundle :install
- expect(out).to match(/at #{lib_path('local-rack')}/)
FileUtils.rm_rf(lib_path("local-rack"))
- run "require 'rack'"
+ run "require 'rack'", :raise_on_error => false
expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
end
@@ -513,20 +533,19 @@ RSpec.describe "Bundler.setup" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
bundle :install
- expect(out).to match(/at #{lib_path('local-rack')}/)
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}"
G
- run "require 'rack'"
+ run "require 'rack'", :raise_on_error => false
expect(err).to match(/because :branch is not specified in Gemfile/)
end
@@ -536,20 +555,19 @@ RSpec.describe "Bundler.setup" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
bundle :install
- expect(out).to match(/at #{lib_path('local-rack')}/)
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "changed"
G
- run "require 'rack'"
+ run "require 'rack'", :raise_on_error => false
expect(err).to match(/is using branch master but Gemfile specifies changed/)
end
@@ -559,25 +577,26 @@ RSpec.describe "Bundler.setup" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "master", :branch => "master"
G
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "master", :branch => "nonexistant"
G
- bundle %(config local.rack #{lib_path("local-rack")})
- run "require 'rack'"
+ bundle %(config set local.rack #{lib_path("local-rack")})
+ run "require 'rack'", :raise_on_error => false
expect(err).to match(/is using branch master but Gemfile specifies nonexistant/)
end
end
describe "when excluding groups" do
it "doesn't change the resolve if --without is used" do
- install_gemfile <<-G, :without => :rails
- source "file://#{gem_repo1}"
+ bundle "config set --local without rails"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
group :rails do
@@ -585,14 +604,15 @@ RSpec.describe "Bundler.setup" do
end
G
- install_gems "activesupport-2.3.5"
+ system_gems "activesupport-2.3.5"
expect(the_bundle).to include_gems "activesupport 2.3.2", :groups => :default
end
it "remembers --without and does not bail on bare Bundler.setup" do
- install_gemfile <<-G, :without => :rails
- source "file://#{gem_repo1}"
+ bundle "config set --local without rails"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
group :rails do
@@ -600,93 +620,77 @@ RSpec.describe "Bundler.setup" do
end
G
- install_gems "activesupport-2.3.5"
+ system_gems "activesupport-2.3.5"
expect(the_bundle).to include_gems "activesupport 2.3.2"
end
- it "remembers --without and does not include groups passed to Bundler.setup" do
- install_gemfile <<-G, :without => :rails
- source "file://#{gem_repo1}"
- gem "activesupport"
+ it "remembers --without and does not bail on bare Bundler.setup, even in the case of path gems no longer available" do
+ bundle "config set --local without development"
- group :rack do
- gem "rack"
- end
+ path = bundled_app(File.join("vendor", "foo"))
+ build_lib "foo", :path => path
- group :rails do
- gem "rails", "2.3.2"
- end
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "activesupport", "2.3.2"
+ gem 'foo', :path => 'vendor/foo', :group => :development
G
- expect(the_bundle).not_to include_gems "activesupport 2.3.2", :groups => :rack
- expect(the_bundle).to include_gems "rack 1.0.0", :groups => :rack
+ FileUtils.rm_rf(path)
+
+ ruby "require 'bundler'; Bundler.setup", :env => { "DEBUG" => "1" }
+ expect(out).to include("Assuming that source at `vendor/foo` has not changed since fetching its specs errored")
+ expect(out).to include("Found no changes, using resolution from the lockfile")
+ expect(err).to be_empty
end
- end
- # Unfortunately, gem_prelude does not record the information about
- # activated gems, so this test cannot work on 1.9 :(
- if RUBY_VERSION < "1.9"
- describe "preactivated gems" do
- it "raises an exception if a pre activated gem conflicts with the bundle" do
- system_gems "thin-1.0", "rack-1.0.0"
- build_gem "thin", "1.1", :to_system => true do |s|
- s.add_dependency "rack"
+ it "doesn't re-resolve when a pre-release bundler is used and a dependency includes a dependency on bundler" do
+ system_gems "bundler-9.99.9.beta1"
+
+ build_repo4 do
+ build_gem "depends_on_bundler", "1.0" do |s|
+ s.add_dependency "bundler", ">= 1.5.0"
end
+ end
- gemfile <<-G
- gem "thin", "1.0"
- G
+ install_gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "depends_on_bundler"
+ G
- ruby <<-R
- require 'rubygems'
- gem "thin"
- require 'bundler'
- begin
- Bundler.setup
- puts "FAIL"
- rescue Gem::LoadError => e
- puts e.message
- end
- R
+ ruby "require '#{system_gem_path("gems/bundler-9.99.9.beta1/lib/bundler.rb")}'; Bundler.setup", :env => { "DEBUG" => "1" }
+ expect(out).to include("Found no changes, using resolution from the lockfile")
+ expect(err).to be_empty
+ end
- expect(out).to eq("You have already activated thin 1.1, but your Gemfile requires thin 1.0. Prepending `bundle exec` to your command may solve this.")
- end
+ it "remembers --without and does not include groups passed to Bundler.setup" do
+ bundle "config set --local without rails"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "activesupport"
- it "version_requirement is now deprecated in rubygems 1.4.0+" do
- system_gems "thin-1.0", "rack-1.0.0"
- build_gem "thin", "1.1", :to_system => true do |s|
- s.add_dependency "rack"
+ group :rack do
+ gem "rack"
end
- gemfile <<-G
- gem "thin", "1.0"
- G
-
- ruby <<-R
- require 'rubygems'
- gem "thin"
- require 'bundler'
- begin
- Bundler.setup
- puts "FAIL"
- rescue Gem::LoadError => e
- puts e.message
- end
- R
+ group :rails do
+ gem "rails", "2.3.2"
+ end
+ G
- expect(err).to lack_errors
- end
+ expect(the_bundle).not_to include_gems "activesupport 2.3.2", :groups => :rack
+ expect(the_bundle).to include_gems "rack 1.0.0", :groups => :rack
end
end
- # Rubygems returns loaded_from as a string
+ # RubyGems returns loaded_from as a string
it "has loaded_from as a string on all specs" do
build_git "foo"
build_git "no-gemspec", :gemspec => false
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "foo", :git => "#{lib_path("foo-1.0")}"
gem "no-gemspec", "1.0", :git => "#{lib_path("no-gemspec-1.0")}"
@@ -701,13 +705,13 @@ RSpec.describe "Bundler.setup" do
expect(out).to be_empty
end
- it "does not load all gemspecs", :rubygems => ">= 2.3" do
- install_gemfile! <<-G
- source "file://#{gem_repo1}"
+ it "does not load all gemspecs" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- run! <<-R
+ run <<-R
File.open(File.join(Gem.dir, "specifications", "broken.gemspec"), "w") do |f|
f.write <<-RUBY
# -*- encoding: utf-8 -*-
@@ -722,7 +726,7 @@ end
end
R
- run! <<-R
+ run <<-R
puts "WIN"
R
@@ -731,14 +735,79 @@ end
it "ignores empty gem paths" do
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
ENV["GEM_HOME"] = ""
bundle %(exec ruby -e "require 'set'")
- expect(err).to lack_errors
+ expect(err).to be_empty
+ end
+
+ context "when the user has `MANPATH` set", :man do
+ before { ENV["MANPATH"] = "/foo#{File::PATH_SEPARATOR}" }
+
+ it "adds the gem's man dir to the MANPATH" do
+ build_repo4 do
+ build_gem "with_man" do |s|
+ s.write("man/man1/page.1", "MANPAGE")
+ end
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "with_man"
+ G
+
+ run "puts ENV['MANPATH']"
+ expect(out).to eq("#{default_bundle_path("gems/with_man-1.0/man")}#{File::PATH_SEPARATOR}/foo")
+ end
+ end
+
+ context "when the user does not have `MANPATH` set", :man do
+ before { ENV.delete("MANPATH") }
+
+ it "adds the gem's man dir to the MANPATH, leaving : in the end so that system man pages still work" do
+ build_repo4 do
+ build_gem "with_man" do |s|
+ s.write("man/man1/page.1", "MANPAGE")
+ end
+
+ build_gem "with_man_overriding_system_man" do |s|
+ s.write("man/man1/ls.1", "LS MANPAGE")
+ end
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "with_man"
+ G
+
+ run <<~RUBY
+ puts ENV['MANPATH']
+ require "open3"
+ puts Open3.capture2e("man", "ls")[1].success?
+ RUBY
+
+ expect(out).to eq("#{default_bundle_path("gems/with_man-1.0/man")}#{File::PATH_SEPARATOR}\ntrue")
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "with_man_overriding_system_man"
+ G
+
+ run <<~RUBY
+ puts ENV['MANPATH']
+ require "open3"
+ puts Open3.capture2e("man", "ls")[0]
+ RUBY
+
+ lines = out.split("\n")
+
+ expect(lines).to include("#{default_bundle_path("gems/with_man_overriding_system_man-1.0/man")}#{File::PATH_SEPARATOR}")
+ expect(lines).to include("LS MANPAGE")
+ end
end
it "should prepend gemspec require paths to $LOAD_PATH in order" do
@@ -746,12 +815,12 @@ end
build_gem("requirepaths") do |s|
s.write("lib/rq.rb", "puts 'yay'")
s.write("src/rq.rb", "puts 'nooo'")
- s.require_paths = %w(lib src)
+ s.require_paths = %w[lib src]
end
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
gem "requirepaths", :require => nil
G
@@ -762,22 +831,20 @@ end
it "should clean $LOAD_PATH properly", :ruby_repo do
gem_name = "very_simple_binary"
full_gem_name = gem_name + "-1.0"
- ext_dir = File.join(tmp "extenstions", full_gem_name)
+ ext_dir = File.join(tmp("extensions", full_gem_name))
- install_gem full_gem_name
+ system_gems full_gem_name
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
G
ruby <<-R
- if Gem::Specification.method_defined? :extension_dir
- s = Gem::Specification.find_by_name '#{gem_name}'
- s.extension_dir = '#{ext_dir}'
+ s = Gem::Specification.find_by_name '#{gem_name}'
+ s.extension_dir = '#{ext_dir}'
- # Don't build extensions.
- s.class.send(:define_method, :build_extensions) { nil }
- end
+ # Don't build extensions.
+ s.class.send(:define_method, :build_extensions) { nil }
require 'bundler'
gem '#{gem_name}'
@@ -792,24 +859,72 @@ end
expect(out).to eq("true\ntrue")
end
- it "stubs out Gem.refresh so it does not reveal system gems" do
+ context "with bundler is located in symlinked GEM_HOME" do
+ let(:gem_home) { Dir.mktmpdir }
+ let(:symlinked_gem_home) { Tempfile.new("gem_home").path }
+ let(:full_name) { "bundler-#{Bundler::VERSION}" }
+
+ before do
+ skip "symlink destination exists" if Gem.win_platform?
+
+ FileUtils.ln_sf(gem_home, symlinked_gem_home)
+ gems_dir = File.join(gem_home, "gems")
+ specifications_dir = File.join(gem_home, "specifications")
+ Dir.mkdir(gems_dir)
+ Dir.mkdir(specifications_dir)
+
+ FileUtils.ln_s(source_root, File.join(gems_dir, full_name))
+
+ gemspec_content = File.binread(gemspec).
+ sub("Bundler::VERSION", %("#{Bundler::VERSION}")).
+ lines.reject {|line| line =~ %r{lib/bundler/version} }.join
+
+ File.open(File.join(specifications_dir, "#{full_name}.gemspec"), "wb") do |f|
+ f.write(gemspec_content)
+ end
+ end
+
+ it "should not remove itself from the LOAD_PATH and require a different copy of 'bundler/setup'" do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+
+ ruby <<-R, :env => { "GEM_PATH" => symlinked_gem_home }
+ TracePoint.trace(:class) do |tp|
+ if tp.path.include?("bundler") && !tp.path.start_with?("#{source_root}")
+ puts "OMG. Defining a class from another bundler at \#{tp.path}:\#{tp.lineno}"
+ end
+ end
+ gem 'bundler', '#{Bundler::VERSION}'
+ require 'bundler/setup'
+ R
+
+ expect(out).to be_empty
+ end
+ end
+
+ it "does not reveal system gems even when Gem.refresh is called" do
system_gems "rack-1.0.0"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
G
run <<-R
- puts Bundler.rubygems.find_name("rack").inspect
+ puts Bundler.rubygems.all_specs.map(&:name)
Gem.refresh
- puts Bundler.rubygems.find_name("rack").inspect
+ puts Bundler.rubygems.all_specs.map(&:name)
R
- expect(out).to eq("[]\n[]")
+ expect(out).to eq("activesupport\nbundler\nactivesupport\nbundler")
end
describe "when a vendored gem specification uses the :path option" do
+ let(:filesystem_root) do
+ current = Pathname.new(Dir.pwd)
+ current = current.parent until current == current.parent
+ current
+ end
+
it "should resolve paths relative to the Gemfile" do
path = bundled_app(File.join("vendor", "foo"))
build_lib "foo", :path => path
@@ -819,19 +934,18 @@ end
FileUtils.rm(File.join(path, "foo.gemspec"))
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', '1.2.3', :path => 'vendor/foo'
G
- Dir.chdir(bundled_app.parent) do
- run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app("Gemfile") }
- require 'foo'
- R
- end
- expect(err).to lack_errors
+ run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app_gemfile.to_s }, :dir => bundled_app.parent
+ require 'foo'
+ R
+ expect(err).to be_empty
end
it "should make sure the Bundler.root is really included in the path relative to the Gemfile" do
- relative_path = File.join("vendor", Dir.pwd[1..-1], "foo")
+ relative_path = File.join("vendor", Dir.pwd.gsub(/^#{filesystem_root}/, ""))
absolute_path = bundled_app(relative_path)
FileUtils.mkdir_p(absolute_path)
build_lib "foo", :path => absolute_path
@@ -841,34 +955,34 @@ end
FileUtils.rm(File.join(absolute_path, "foo.gemspec"))
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', '1.2.3', :path => '#{relative_path}'
G
bundle :install
- Dir.chdir(bundled_app.parent) do
- run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app("Gemfile") }
- require 'foo'
- R
- end
+ run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app_gemfile.to_s }, :dir => bundled_app.parent
+ require 'foo'
+ R
- expect(err).to lack_errors
+ expect(err).to be_empty
end
end
describe "with git gems that don't have gemspecs" do
before :each do
- build_git "no-gemspec", :gemspec => false
+ build_git "no_gemspec", :gemspec => false
install_gemfile <<-G
- gem "no-gemspec", "1.0", :git => "#{lib_path("no-gemspec-1.0")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "no_gemspec", "1.0", :git => "#{lib_path("no_gemspec-1.0")}"
G
end
it "loads the library via a virtual spec" do
run <<-R
- require 'no-gemspec'
- puts NOGEMSPEC
+ require 'no_gemspec'
+ puts NO_GEMSPEC
R
expect(out).to eq("1.0")
@@ -880,7 +994,7 @@ end
system_gems "rack-1.0.0"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport", "2.3.5"
G
@@ -888,8 +1002,6 @@ end
it "does not pull in system gems" do
run <<-R
- require 'rubygems'
-
begin;
require 'rack'
rescue LoadError
@@ -930,10 +1042,11 @@ end
describe "with system gems in the bundle" do
before :each do
+ bundle "config set path.system true"
system_gems "rack-1.0.0"
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack", "1.0.0"
gem "activesupport", "2.3.5"
G
@@ -943,7 +1056,6 @@ end
run "puts Gem.path"
paths = out.split("\n")
expect(paths).to include(system_gem_path.to_s)
- expect(paths).to include(default_bundle_path.to_s)
end
end
@@ -952,9 +1064,7 @@ end
build_git "bar", :gemspec => false do |s|
s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0')
s.write "bar.gemspec", <<-G
- lib = File.expand_path('../lib/', __FILE__)
- $:.unshift lib unless $:.include?(lib)
- require 'bar/version'
+ require_relative 'lib/bar/version'
Gem::Specification.new do |s|
s.name = 'bar'
@@ -967,6 +1077,7 @@ end
end
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "bar", :git => "#{lib_path("bar-1.0")}"
G
end
@@ -978,14 +1089,15 @@ end
end
it "error intelligently if the gemspec has a LoadError" do
+ skip "whitespace issue?" if Gem.win_platform?
+
ref = update_git "bar", :gemspec => false do |s|
s.write "bar.gemspec", "require 'foobarbaz'"
end.ref_for("HEAD")
- bundle :install
+ bundle :install, :raise_on_error => false
- expect(out.lines.map(&:chomp)).to include(
+ expect(err.lines.map(&:chomp)).to include(
a_string_starting_with("[!] There was an error while loading `bar.gemspec`:"),
- RUBY_VERSION >= "1.9" ? a_string_starting_with("Does it try to require a relative path? That's been removed in Ruby 1.9.") : "",
" # from #{default_bundle_path "bundler", "gems", "bar-1.0-#{ref[0, 12]}", "bar.gemspec"}:1",
" > require 'foobarbaz'"
)
@@ -996,53 +1108,58 @@ end
ruby <<-RUBY
require 'bundler'
+ bundler_module = class << Bundler; self; end
+ bundler_module.send(:remove_method, :require)
def Bundler.require(path)
raise "LOSE"
end
Bundler.load
RUBY
- expect(err).to lack_errors
- expect(out).to eq("")
+ expect(err).to be_empty
+ expect(out).to be_empty
end
end
describe "when Bundler is bundled" do
it "doesn't blow up" do
install_gemfile <<-G
- gem "bundler", :path => "#{File.expand_path("..", lib)}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "bundler", :path => "#{root}"
G
bundle %(exec ruby -e "require 'bundler'; Bundler.setup")
- expect(err).to lack_errors
+ expect(err).to be_empty
end
end
describe "when BUNDLED WITH" do
def lock_with(bundler_version = nil)
- lock = <<-L
+ lock = <<~L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
L
if bundler_version
- lock += "\n BUNDLED WITH\n #{bundler_version}\n"
+ lock += "\nBUNDLED WITH\n #{bundler_version}\n"
end
lock
end
before do
+ bundle "config set --local path.system true"
+
install_gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
@@ -1050,8 +1167,8 @@ end
context "is not present" do
it "does not change the lock" do
lockfile lock_with(nil)
- ruby "require 'bundler/setup'"
- lockfile_should_be lock_with(nil)
+ ruby "require '#{entrypoint}/setup'"
+ expect(lockfile).to eq lock_with(nil)
end
end
@@ -1059,17 +1176,18 @@ end
it "does not change the lock or warn" do
lockfile lock_with(Bundler::VERSION.succ)
ruby "require 'bundler/setup'"
- expect(out).to eq("")
- expect(err).to eq("")
- lockfile_should_be lock_with(Bundler::VERSION.succ)
+ expect(out).to be_empty
+ expect(err).to be_empty
+ expect(lockfile).to eq lock_with(Bundler::VERSION.succ)
end
end
context "is older" do
it "does not change the lock" do
+ system_gems "bundler-1.10.1"
lockfile lock_with("1.10.1")
- ruby "require 'bundler/setup'"
- lockfile_should_be lock_with("1.10.1")
+ ruby "require '#{entrypoint}/setup'"
+ expect(lockfile).to eq lock_with("1.10.1")
end
end
end
@@ -1078,24 +1196,24 @@ end
let(:ruby_version) { nil }
def lock_with(ruby_version = nil)
- lock = <<-L
+ lock = <<~L
GEM
- remote: file:#{gem_repo1}/
+ remote: #{file_uri_for(gem_repo1)}/
specs:
rack (1.0.0)
PLATFORMS
- #{generic_local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack
L
if ruby_version
- lock += "\n RUBY VERSION\n ruby #{ruby_version}\n"
+ lock += "\nRUBY VERSION\n ruby #{ruby_version}\n"
end
- lock += <<-L
+ lock += <<~L
BUNDLED WITH
#{Bundler::VERSION}
@@ -1107,7 +1225,7 @@ end
before do
install_gemfile <<-G
ruby ">= 0"
- source "file:#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
lockfile lock_with(ruby_version)
@@ -1115,32 +1233,67 @@ end
context "is not present" do
it "does not change the lock" do
- expect { ruby! "require 'bundler/setup'" }.not_to change { lockfile }
+ expect { ruby "require 'bundler/setup'" }.not_to change { lockfile }
end
end
context "is newer" do
let(:ruby_version) { "5.5.5" }
it "does not change the lock or warn" do
- expect { ruby! "require 'bundler/setup'" }.not_to change { lockfile }
- expect(out).to eq("")
- expect(err).to eq("")
+ expect { ruby "require 'bundler/setup'" }.not_to change { lockfile }
+ expect(out).to be_empty
+ expect(err).to be_empty
end
end
context "is older" do
let(:ruby_version) { "1.0.0" }
it "does not change the lock" do
- expect { ruby! "require 'bundler/setup'" }.not_to change { lockfile }
+ expect { ruby "require 'bundler/setup'" }.not_to change { lockfile }
end
end
end
describe "with gemified standard libraries" do
- it "does not load Psych", :ruby => "~> 2.2" do
- gemfile ""
+ it "does not load Digest", :ruby_repo do
+ skip "Only for Ruby 3.0+" unless RUBY_VERSION >= "3.0"
+
+ build_git "bar", :gemspec => false do |s|
+ s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0')
+ s.write "bar.gemspec", <<-G
+ require_relative 'lib/bar/version'
+
+ Gem::Specification.new do |s|
+ s.name = 'bar'
+ s.version = BAR_VERSION
+ s.summary = 'Bar'
+ s.files = Dir["lib/**/*.rb"]
+ s.author = 'no one'
+
+ s.add_runtime_dependency 'digest'
+ end
+ G
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "bar", :git => "#{lib_path("bar-1.0")}"
+ G
+
+ bundle :install
+
ruby <<-RUBY
- require 'bundler/setup'
+ require '#{entrypoint}/setup'
+ puts defined?(::Digest) ? "Digest defined" : "Digest undefined"
+ require 'digest'
+ RUBY
+ expect(out).to eq("Digest undefined")
+ end
+
+ it "does not load Psych" do
+ gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ ruby <<-RUBY
+ require '#{entrypoint}/setup'
puts defined?(Psych::VERSION) ? Psych::VERSION : "undefined"
require 'psych'
puts Psych::VERSION
@@ -1151,8 +1304,8 @@ end
end
it "does not load openssl" do
- install_gemfile! ""
- ruby! <<-RUBY
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ ruby <<-RUBY
require "bundler/setup"
puts defined?(OpenSSL) || "undefined"
require "openssl"
@@ -1161,32 +1314,44 @@ end
expect(out).to eq("undefined\nconstant")
end
- describe "default gem activation", :ruby_repo do
+ describe "default gem activation" do
let(:exemptions) do
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("2.7") || ENV["RGV"] == "master"
- []
+ exempts = if Gem.rubygems_version >= Gem::Version.new("2.7")
+ %w[did_you_mean]
else
- %w(io-console openssl)
+ %w[io-console openssl]
end << "bundler"
+ exempts << "fiddle" if Gem.win_platform? && Gem.rubygems_version >= Gem::Version.new("2.7")
+ exempts << "uri" if Gem.ruby_version >= Gem::Version.new("2.7")
+ exempts << "pathname" if Gem.ruby_version >= Gem::Version.new("3.0")
+ exempts << "set" unless Gem.rubygems_version >= Gem::Version.new("3.2.6")
+ exempts << "tsort" unless Gem.rubygems_version >= Gem::Version.new("3.2.31")
+ exempts << "error_highlight" # added in Ruby 3.1 as a default gem
+ exempts << "ruby2_keywords" # added in Ruby 3.1 as a default gem
+ exempts
end
- let(:code) { strip_whitespace(<<-RUBY) }
- require "rubygems"
-
- if Gem::Specification.instance_methods.map(&:to_sym).include?(:activate)
- Gem::Specification.send(:alias_method, :bundler_spec_activate, :activate)
- Gem::Specification.send(:define_method, :activate) do
- unless #{exemptions.inspect}.include?(name)
- warn '-' * 80
- warn "activating \#{full_name}"
- warn *caller
- warn '*' * 80
- end
- bundler_spec_activate
+ let(:activation_warning_hack) { strip_whitespace(<<-RUBY) }
+ require #{spec_dir.join("support/hax").to_s.dump}
+
+ Gem::Specification.send(:alias_method, :bundler_spec_activate, :activate)
+ Gem::Specification.send(:define_method, :activate) do
+ unless #{exemptions.inspect}.include?(name)
+ warn '-' * 80
+ warn "activating \#{full_name}"
+ warn(*caller)
+ warn '*' * 80
end
+ bundler_spec_activate
end
+ RUBY
- require "bundler/setup"
+ let(:activation_warning_hack_rubyopt) do
+ create_file("activation_warning_hack.rb", activation_warning_hack)
+ "-r#{bundled_app("activation_warning_hack.rb")} #{ENV["RUBYOPT"]}"
+ end
+
+ let(:code) { strip_whitespace(<<-RUBY) }
require "pp"
loaded_specs = Gem.loaded_specs.dup
#{exemptions.inspect}.each {|s| loaded_specs.delete(s) }
@@ -1200,90 +1365,174 @@ end
RUBY
it "activates no gems with -rbundler/setup" do
- install_gemfile! ""
- ruby!(code)
- expect(err).to eq("")
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ ruby code, :env => { "RUBYOPT" => activation_warning_hack_rubyopt + " -rbundler/setup" }
expect(out).to eq("{}")
end
it "activates no gems with bundle exec" do
- install_gemfile! ""
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
create_file("script.rb", code)
- bundle! "exec ruby ./script.rb"
- expect(err).to eq("")
+ bundle "exec ruby ./script.rb", :env => { "RUBYOPT" => activation_warning_hack_rubyopt }
expect(out).to eq("{}")
end
it "activates no gems with bundle exec that is loaded" do
- # TODO: remove once https://github.com/erikhuda/thor/pull/539 is released
- exemptions << "io-console"
+ skip "not executable" if Gem.win_platform?
- install_gemfile! ""
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
create_file("script.rb", "#!/usr/bin/env ruby\n\n#{code}")
FileUtils.chmod(0o777, bundled_app("script.rb"))
- bundle! "exec ./script.rb", :artifice => nil
- expect(err).to eq("")
+ bundle "exec ./script.rb", :artifice => nil, :env => { "RUBYOPT" => activation_warning_hack_rubyopt }
expect(out).to eq("{}")
end
- let(:default_gems) do
- ruby!(<<-RUBY).split("\n")
- if Gem::Specification.is_a?(Enumerable)
- puts Gem::Specification.select(&:default_gem?).map(&:name)
- end
- RUBY
- end
-
- it "activates newer versions of default gems" do
+ it "does not load net-http-pipeline too early" do
build_repo4 do
- default_gems.each do |g|
- build_gem g, "999999"
- end
+ build_gem "net-http-pipeline", "1.0.1"
end
- install_gemfile! <<-G
- source "file:#{gem_repo4}"
- #{default_gems}.each do |g|
- gem g, "999999"
- end
+ system_gems "net-http-pipeline-1.0.1", :gem_repo => gem_repo4
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "net-http-pipeline", "1.0.1"
G
- expect(the_bundle).to include_gems(*default_gems.map {|g| "#{g} 999999" })
+ bundle "config set --local path vendor/bundle"
+
+ bundle :install
+
+ bundle :check
+
+ expect(out).to eq("The Gemfile's dependencies are satisfied")
end
- it "activates older versions of default gems" do
- build_repo4 do
- default_gems.each do |g|
- build_gem g, "0.0.0.a"
+ Gem::Specification.select(&:default_gem?).map(&:name).each do |g|
+ it "activates newer versions of #{g}", :ruby_repo do
+ skip if exemptions.include?(g)
+
+ build_repo4 do
+ build_gem g, "999999"
end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "#{g}", "999999"
+ G
+
+ expect(the_bundle).to include_gem("#{g} 999999", :env => { "RUBYOPT" => activation_warning_hack_rubyopt })
end
- default_gems.reject! {|g| exemptions.include?(g) }
+ it "activates older versions of #{g}", :ruby_repo do
+ skip if exemptions.include?(g)
- install_gemfile! <<-G
- source "file:#{gem_repo4}"
- #{default_gems}.each do |g|
- gem g, "0.0.0.a"
+ build_repo4 do
+ build_gem g, "0.0.0.a"
end
- G
- expect(the_bundle).to include_gems(*default_gems.map {|g| "#{g} 0.0.0.a" })
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "#{g}", "0.0.0.a"
+ G
+
+ expect(the_bundle).to include_gem("#{g} 0.0.0.a", :env => { "RUBYOPT" => activation_warning_hack_rubyopt })
+ end
end
end
end
describe "after setup" do
- it "allows calling #gem on random objects" do
+ it "allows calling #gem on random objects", :bundler => "< 3" do
install_gemfile <<-G
- source "file:#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- ruby! <<-RUBY
+
+ ruby <<-RUBY
require "bundler/setup"
Object.new.gem "rack"
puts Gem.loaded_specs["rack"].full_name
RUBY
+
expect(out).to eq("rack-1.0.0")
end
+
+ it "keeps Kernel#gem private", :bundler => "3" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ ruby <<-RUBY, :raise_on_error => false
+ require "bundler/setup"
+ Object.new.gem "rack"
+ puts "FAIL"
+ RUBY
+
+ expect(last_command.stdboth).not_to include "FAIL"
+ expect(err).to include "private method `gem'"
+ end
+
+ it "keeps Kernel#require private" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ ruby <<-RUBY, :raise_on_error => false
+ require "bundler/setup"
+ Object.new.require "rack"
+ puts "FAIL"
+ RUBY
+
+ expect(last_command.stdboth).not_to include "FAIL"
+ expect(err).to include "private method `require'"
+ end
+
+ it "takes care of requiring rubygems" do
+ sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler/setup -e'puts true'", :env => { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
+
+ expect(last_command.stdboth).to eq("true")
+ end
+
+ it "memoizes initial set of specs when requiring bundler/setup, so that even if further code mutates dependencies, Bundler.definition.specs is not affected" do
+ install_gemfile <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack", :group => :test
+ G
+
+ ruby <<-RUBY, :raise_on_error => false
+ require "bundler/setup"
+ Bundler.require(:test).select! {|d| (d.groups & [:test]).any? }
+ puts Bundler.definition.specs.map(&:name).join(", ")
+ RUBY
+
+ expect(out).to include("rack, yard")
+ end
+
+ it "does not cause double loads when higher versions of default gems are activated before bundler" do
+ build_repo2 do
+ build_gem "json", "999.999.999" do |s|
+ s.write "lib/json.rb", <<~RUBY
+ module JSON
+ VERSION = "999.999.999"
+ end
+ RUBY
+ end
+ end
+
+ system_gems "json-999.999.999", :gem_repo => gem_repo2
+
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ ruby <<-RUBY
+ require "json"
+ require "bundler/setup"
+ require "json"
+ RUBY
+
+ expect(err).to be_empty
+ end
end
end
diff --git a/spec/bundler/runtime/with_clean_env_spec.rb b/spec/bundler/runtime/with_clean_env_spec.rb
deleted file mode 100644
index d18a0de485..0000000000
--- a/spec/bundler/runtime/with_clean_env_spec.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-
-RSpec.describe "Bundler.with_env helpers" do
- describe "Bundler.original_env" do
- before do
- gemfile ""
- bundle "install --path vendor/bundle"
- end
-
- it "should return the PATH present before bundle was activated", :ruby_repo do
- code = "print Bundler.original_env['PATH']"
- path = `getconf PATH`.strip + "#{File::PATH_SEPARATOR}/foo"
- with_path_as(path) do
- result = bundle("exec ruby -e #{code.dump}")
- expect(result).to eq(path)
- end
- end
-
- it "should return the GEM_PATH present before bundle was activated" do
- code = "print Bundler.original_env['GEM_PATH']"
- gem_path = ENV["GEM_PATH"] + ":/foo"
- with_gem_path_as(gem_path) do
- result = bundle("exec ruby -e #{code.inspect}")
- expect(result).to eq(gem_path)
- end
- end
-
- it "works with nested bundle exec invocations", :ruby_repo do
- create_file("exe.rb", <<-'RB')
- count = ARGV.first.to_i
- exit if count < 0
- STDERR.puts "#{count} #{ENV["PATH"].end_with?(":/foo")}"
- if count == 2
- ENV["PATH"] = "#{ENV["PATH"]}:/foo"
- end
- exec("ruby", __FILE__, (count - 1).to_s)
- RB
- path = `getconf PATH`.strip + File::PATH_SEPARATOR + File.dirname(Gem.ruby)
- with_path_as(path) do
- bundle!("exec ruby #{bundled_app("exe.rb")} 2")
- end
- expect(err).to eq <<-EOS.strip
-2 false
-1 true
-0 true
- EOS
- end
- end
-
- describe "Bundler.clean_env" do
- before do
- gemfile ""
- bundle "install --path vendor/bundle"
- end
-
- it "should delete BUNDLE_PATH" do
- code = "print Bundler.clean_env.has_key?('BUNDLE_PATH')"
- ENV["BUNDLE_PATH"] = "./foo"
- result = bundle("exec ruby -e #{code.inspect}")
- expect(result).to eq("false")
- end
-
- it "should remove '-rbundler/setup' from RUBYOPT" do
- code = "print Bundler.clean_env['RUBYOPT']"
- ENV["RUBYOPT"] = "-W2 -rbundler/setup"
- result = bundle("exec ruby -e #{code.inspect}")
- expect(result).not_to include("-rbundler/setup")
- end
-
- it "should clean up RUBYLIB", :ruby_repo do
- code = "print Bundler.clean_env['RUBYLIB']"
- ENV["RUBYLIB"] = root.join("lib").to_s + File::PATH_SEPARATOR + "/foo"
- result = bundle("exec ruby -e #{code.inspect}")
- expect(result).to eq("/foo")
- end
-
- it "should restore the original MANPATH" do
- code = "print Bundler.clean_env['MANPATH']"
- ENV["MANPATH"] = "/foo"
- ENV["BUNDLER_ORIG_MANPATH"] = "/foo-original"
- result = bundle("exec ruby -e #{code.inspect}")
- expect(result).to eq("/foo-original")
- end
- end
-
- describe "Bundler.with_original_env" do
- it "should set ENV to original_env in the block" do
- expected = Bundler.original_env
- actual = Bundler.with_original_env { ENV.to_hash }
- expect(actual).to eq(expected)
- end
-
- it "should restore the environment after execution" do
- Bundler.with_original_env do
- ENV["FOO"] = "hello"
- end
-
- expect(ENV).not_to have_key("FOO")
- end
- end
-
- describe "Bundler.with_clean_env" do
- it "should set ENV to clean_env in the block" do
- expected = Bundler.clean_env
- actual = Bundler.with_clean_env { ENV.to_hash }
- expect(actual).to eq(expected)
- end
-
- it "should restore the environment after execution" do
- Bundler.with_clean_env do
- ENV["FOO"] = "hello"
- end
-
- expect(ENV).not_to have_key("FOO")
- end
- end
-
- describe "Bundler.clean_system", :ruby => ">= 1.9" do
- it "runs system inside with_clean_env" do
- Bundler.clean_system(%(echo 'if [ "$BUNDLE_PATH" = "" ]; then exit 42; else exit 1; fi' | /bin/sh))
- expect($?.exitstatus).to eq(42)
- end
- end
-
- describe "Bundler.clean_exec", :ruby => ">= 1.9" do
- it "runs exec inside with_clean_env" do
- pid = Kernel.fork do
- Bundler.clean_exec(%(echo 'if [ "$BUNDLE_PATH" = "" ]; then exit 42; else exit 1; fi' | /bin/sh))
- end
- Process.wait(pid)
- expect($?.exitstatus).to eq(42)
- end
- end
-end
diff --git a/spec/bundler/runtime/with_unbundled_env_spec.rb b/spec/bundler/runtime/with_unbundled_env_spec.rb
new file mode 100644
index 0000000000..731a9921a2
--- /dev/null
+++ b/spec/bundler/runtime/with_unbundled_env_spec.rb
@@ -0,0 +1,302 @@
+# frozen_string_literal: true
+
+RSpec.describe "Bundler.with_env helpers" do
+ def bundle_exec_ruby(args, options = {})
+ build_bundler_context options
+ bundle "exec '#{Gem.ruby}' #{args}", options
+ end
+
+ def build_bundler_context(options = {})
+ bundle "config set path vendor/bundle"
+ gemfile "source \"#{file_uri_for(gem_repo1)}\""
+ bundle "install", options
+ end
+
+ def run_bundler_script(env, script)
+ system(env, "ruby", "-I#{lib_dir}", "-rbundler", script.to_s)
+ end
+
+ describe "Bundler.original_env" do
+ it "should return the PATH present before bundle was activated" do
+ create_file("source.rb", <<-RUBY)
+ print Bundler.original_env["PATH"]
+ RUBY
+ path = `getconf PATH`.strip + "#{File::PATH_SEPARATOR}/foo"
+ with_path_as(path) do
+ bundle_exec_ruby(bundled_app("source.rb").to_s)
+ expect(last_command.stdboth).to eq(path)
+ end
+ end
+
+ it "should return the GEM_PATH present before bundle was activated" do
+ create_file("source.rb", <<-RUBY)
+ print Bundler.original_env['GEM_PATH']
+ RUBY
+ gem_path = ENV["GEM_PATH"] + "#{File::PATH_SEPARATOR}/foo"
+ with_gem_path_as(gem_path) do
+ bundle_exec_ruby(bundled_app("source.rb").to_s)
+ expect(last_command.stdboth).to eq(gem_path)
+ end
+ end
+
+ it "works with nested bundle exec invocations", :ruby_repo do
+ create_file("exe.rb", <<-'RUBY')
+ count = ARGV.first.to_i
+ exit if count < 0
+ STDERR.puts "#{count} #{ENV["PATH"].end_with?("#{File::PATH_SEPARATOR}/foo")}"
+ if count == 2
+ ENV["PATH"] = "#{ENV["PATH"]}#{File::PATH_SEPARATOR}/foo"
+ end
+ exec(Gem.ruby, __FILE__, (count - 1).to_s)
+ RUBY
+ path = `getconf PATH`.strip + File::PATH_SEPARATOR + File.dirname(Gem.ruby)
+ with_path_as(path) do
+ build_bundler_context
+ bundle_exec_ruby("#{bundled_app("exe.rb")} 2")
+ end
+ expect(err).to eq <<-EOS.strip
+2 false
+1 true
+0 true
+ EOS
+ end
+
+ it "removes variables that bundler added", :ruby_repo do
+ # Simulate bundler has not yet been loaded
+ ENV.replace(ENV.to_hash.delete_if {|k, _v| k.start_with?(Bundler::EnvironmentPreserver::BUNDLER_PREFIX) })
+
+ original = ruby('puts ENV.to_a.map {|e| e.join("=") }.sort.join("\n")')
+ create_file("source.rb", <<-RUBY)
+ puts Bundler.original_env.to_a.map {|e| e.join("=") }.sort.join("\n")
+ RUBY
+ bundle_exec_ruby bundled_app("source.rb")
+ expect(out).to eq original
+ end
+ end
+
+ shared_examples_for "an unbundling helper" do
+ it "should delete BUNDLE_PATH" do
+ create_file("source.rb", <<-RUBY)
+ print #{modified_env}.has_key?('BUNDLE_PATH')
+ RUBY
+ ENV["BUNDLE_PATH"] = "./foo"
+ bundle_exec_ruby bundled_app("source.rb")
+ expect(last_command.stdboth).to include "false"
+ end
+
+ it "should remove absolute path to 'bundler/setup' from RUBYOPT even if it was present in original env" do
+ create_file("source.rb", <<-RUBY)
+ print #{modified_env}['RUBYOPT']
+ RUBY
+ setup_require = "-r#{lib_dir}/bundler/setup"
+ ENV["BUNDLER_ORIG_RUBYOPT"] = "-W2 #{setup_require} #{ENV["RUBYOPT"]}"
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ bundle_exec_ruby bundled_app("source.rb")
+ end
+ expect(last_command.stdboth).not_to include(setup_require)
+ end
+
+ it "should remove relative path to 'bundler/setup' from RUBYOPT even if it was present in original env" do
+ create_file("source.rb", <<-RUBY)
+ print #{modified_env}['RUBYOPT']
+ RUBY
+ ENV["BUNDLER_ORIG_RUBYOPT"] = "-W2 -rbundler/setup #{ENV["RUBYOPT"]}"
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ bundle_exec_ruby bundled_app("source.rb")
+ end
+ expect(last_command.stdboth).not_to include("-rbundler/setup")
+ end
+
+ it "should restore RUBYLIB", :ruby_repo do
+ create_file("source.rb", <<-RUBY)
+ print #{modified_env}['RUBYLIB']
+ RUBY
+ ENV["RUBYLIB"] = lib_dir.to_s + File::PATH_SEPARATOR + "/foo"
+ ENV["BUNDLER_ORIG_RUBYLIB"] = lib_dir.to_s + File::PATH_SEPARATOR + "/foo-original"
+ bundle_exec_ruby bundled_app("source.rb")
+ expect(last_command.stdboth).to include("/foo-original")
+ end
+
+ it "should restore the original MANPATH" do
+ create_file("source.rb", <<-RUBY)
+ print #{modified_env}['MANPATH']
+ RUBY
+ ENV["MANPATH"] = "/foo"
+ ENV["BUNDLER_ORIG_MANPATH"] = "/foo-original"
+ bundle_exec_ruby bundled_app("source.rb")
+ expect(last_command.stdboth).to include("/foo-original")
+ end
+ end
+
+ describe "Bundler.unbundled_env" do
+ let(:modified_env) { "Bundler.unbundled_env" }
+
+ it_behaves_like "an unbundling helper"
+ end
+
+ describe "Bundler.clean_env", :bundler => 2 do
+ let(:modified_env) { "Bundler.clean_env" }
+
+ it_behaves_like "an unbundling helper"
+ end
+
+ describe "Bundler.with_original_env" do
+ it "should set ENV to original_env in the block" do
+ expected = Bundler.original_env
+ actual = Bundler.with_original_env { Bundler::EnvironmentPreserver.env_to_hash(ENV) }
+ expect(actual).to eq(expected)
+ end
+
+ it "should restore the environment after execution" do
+ Bundler.with_original_env do
+ ENV["FOO"] = "hello"
+ end
+
+ expect(ENV).not_to have_key("FOO")
+ end
+ end
+
+ describe "Bundler.with_clean_env", :bundler => 2 do
+ it "should set ENV to unbundled_env in the block" do
+ expected = Bundler.unbundled_env
+
+ actual = Bundler.ui.silence do
+ Bundler.with_clean_env { Bundler::EnvironmentPreserver.env_to_hash(ENV) }
+ end
+
+ expect(actual).to eq(expected)
+ end
+
+ it "should restore the environment after execution" do
+ Bundler.ui.silence do
+ Bundler.with_clean_env { ENV["FOO"] = "hello" }
+ end
+
+ expect(ENV).not_to have_key("FOO")
+ end
+ end
+
+ describe "Bundler.with_unbundled_env" do
+ it "should set ENV to unbundled_env in the block" do
+ expected = Bundler.unbundled_env
+ actual = Bundler.with_unbundled_env { Bundler::EnvironmentPreserver.env_to_hash(ENV) }
+ expect(actual).to eq(expected)
+ end
+
+ it "should restore the environment after execution" do
+ Bundler.with_unbundled_env do
+ ENV["FOO"] = "hello"
+ end
+
+ expect(ENV).not_to have_key("FOO")
+ end
+ end
+
+ describe "Bundler.original_system" do
+ before do
+ create_file("source.rb", <<-'RUBY')
+ Bundler.original_system("ruby", "-e", "exit(42) if ENV['BUNDLE_FOO'] == 'bar'")
+
+ exit $?.exitstatus
+ RUBY
+ end
+
+ it "runs system inside with_original_env" do
+ run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
+ expect($?.exitstatus).to eq(42)
+ end
+ end
+
+ describe "Bundler.clean_system", :bundler => 2 do
+ before do
+ create_file("source.rb", <<-'RUBY')
+ Bundler.ui.silence { Bundler.clean_system("ruby", "-e", "exit(42) unless ENV['BUNDLE_FOO'] == 'bar'") }
+
+ exit $?.exitstatus
+ RUBY
+ end
+
+ it "runs system inside with_clean_env" do
+ run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
+ expect($?.exitstatus).to eq(42)
+ end
+ end
+
+ describe "Bundler.unbundled_system" do
+ before do
+ create_file("source.rb", <<-'RUBY')
+ Bundler.unbundled_system("ruby", "-e", "exit(42) unless ENV['BUNDLE_FOO'] == 'bar'")
+
+ exit $?.exitstatus
+ RUBY
+ end
+
+ it "runs system inside with_unbundled_env" do
+ run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
+ expect($?.exitstatus).to eq(42)
+ end
+ end
+
+ describe "Bundler.original_exec" do
+ before do
+ create_file("source.rb", <<-'RUBY')
+ Process.fork do
+ exit Bundler.original_exec(%(test "\$BUNDLE_FOO" = "bar"))
+ end
+
+ _, status = Process.wait2
+
+ exit(status.exitstatus)
+ RUBY
+ end
+
+ it "runs exec inside with_original_env" do
+ skip "Fork not implemented" if Gem.win_platform?
+
+ run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
+ expect($?.exitstatus).to eq(0)
+ end
+ end
+
+ describe "Bundler.clean_exec", :bundler => 2 do
+ before do
+ create_file("source.rb", <<-'RUBY')
+ Process.fork do
+ exit Bundler.ui.silence { Bundler.clean_exec(%(test "\$BUNDLE_FOO" = "bar")) }
+ end
+
+ _, status = Process.wait2
+
+ exit(status.exitstatus)
+ RUBY
+ end
+
+ it "runs exec inside with_clean_env" do
+ skip "Fork not implemented" if Gem.win_platform?
+
+ run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
+ expect($?.exitstatus).to eq(1)
+ end
+ end
+
+ describe "Bundler.unbundled_exec" do
+ before do
+ create_file("source.rb", <<-'RUBY')
+ Process.fork do
+ exit Bundler.unbundled_exec(%(test "\$BUNDLE_FOO" = "bar"))
+ end
+
+ _, status = Process.wait2
+
+ exit(status.exitstatus)
+ RUBY
+ end
+
+ it "runs exec inside with_clean_env" do
+ skip "Fork not implemented" if Gem.win_platform?
+
+ run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
+ expect($?.exitstatus).to eq(1)
+ end
+ end
+end
diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb
index 7293f0e57b..4d558b9907 100644
--- a/spec/bundler/spec_helper.rb
+++ b/spec/bundler/spec_helper.rb
@@ -1,59 +1,34 @@
# frozen_string_literal: true
-$:.unshift File.expand_path("..", __FILE__)
-$:.unshift File.expand_path("../../lib", __FILE__)
require "bundler/psyched_yaml"
-require "fileutils"
-require "uri"
-require "digest/sha1"
-require File.expand_path("../support/path.rb", __FILE__)
-
-begin
- require "rubygems"
- spec = Gem::Specification.load(Spec::Path.gemspec.to_s)
- rspec = spec.dependencies.find {|d| d.name == "rspec" }
- gem "rspec", rspec.requirement.to_s
- require "rspec"
-rescue LoadError
- abort "Run rake spec:deps to install development dependencies"
-end
+require "bundler/vendored_fileutils"
+require "bundler/vendored_uri"
+require "digest"
-if File.expand_path(__FILE__) =~ %r{([^\w/\.])}
+if File.expand_path(__FILE__) =~ %r{([^\w/\.:\-])}
abort "The bundler specs cannot be run from a path that contains special characters (particularly #{$1.inspect})"
end
require "bundler"
-
-# Require the correct version of popen for the current platform
-if RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
- begin
- require "win32/open3"
- rescue LoadError
- abort "Run `gem install win32-open3` to be able to run specs"
- end
-else
- require "open3"
-end
-
-Dir["#{File.expand_path("../support", __FILE__)}/*.rb"].each do |file|
- require file unless file.end_with?("hax.rb")
-end
+require "rspec/core"
+require "rspec/expectations"
+require "rspec/mocks"
+require "rspec/support/differ"
+
+require_relative "support/builders"
+require_relative "support/build_metadata"
+require_relative "support/filters"
+require_relative "support/helpers"
+require_relative "support/indexes"
+require_relative "support/matchers"
+require_relative "support/permissions"
+require_relative "support/platforms"
+require_relative "support/sudo"
$debug = false
-Spec::Rubygems.setup
-FileUtils.rm_rf(Spec::Path.gem_repo1)
-ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -r#{Spec::Path.spec_dir}/support/hax.rb"
-ENV["BUNDLE_SPEC_RUN"] = "true"
-ENV["BUNDLE_PLUGINS"] = "true"
-
-# Don't wrap output in tests
-ENV["THOR_COLUMNS"] = "10000"
-
-Spec::CodeClimate.setup
-
module Gem
- def self.ruby= ruby
+ def self.ruby=(ruby)
@ruby = ruby
end
end
@@ -64,7 +39,6 @@ RSpec.configure do |config|
config.include Spec::Indexes
config.include Spec::Matchers
config.include Spec::Path
- config.include Spec::Rubygems
config.include Spec::Platforms
config.include Spec::Sudo
config.include Spec::Permissions
@@ -72,85 +46,73 @@ RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = ".rspec_status"
+ config.silence_filter_announcements = !ENV["TEST_ENV_NUMBER"].nil?
+
config.disable_monkey_patching!
# Since failures cause us to keep a bunch of long strings in memory, stop
# once we have a large number of failures (indicative of core pieces of
# bundler being broken) so that running the full test suite doesn't take
# forever due to memory constraints
- config.fail_fast ||= 25
+ config.fail_fast ||= 25 if ENV["CI"]
- if ENV["BUNDLER_SUDO_TESTS"] && Spec::Sudo.present?
- config.filter_run :sudo => true
- else
- config.filter_run_excluding :sudo => true
- end
+ config.bisect_runner = :shell
- if ENV["BUNDLER_REALWORLD_TESTS"]
- config.filter_run :realworld => true
- else
- config.filter_run_excluding :realworld => true
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
end
- git_version = Bundler::Source::Git::GitProxy.new(nil, nil, nil).version
-
- config.filter_run_excluding :ruby => LessThanProc.with(RUBY_VERSION)
- config.filter_run_excluding :rubygems => LessThanProc.with(Gem::VERSION)
- config.filter_run_excluding :git => LessThanProc.with(git_version)
- config.filter_run_excluding :rubygems_master => (ENV["RGV"] != "master")
- config.filter_run_excluding :ruby_repo => !!(ENV["BUNDLE_RUBY"] && ENV["BUNDLE_GEM"])
+ config.mock_with :rspec do |mocks|
+ mocks.allow_message_expectations_on_nil = false
+ end
- config.filter_run_when_matching :focus unless ENV["CI"]
+ config.before :suite do
+ Gem.ruby = ENV["RUBY"] if ENV["RUBY"]
- original_wd = Dir.pwd
- original_env = ENV.to_hash
+ require_relative "support/rubygems_ext"
+ Spec::Rubygems.test_setup
+ ENV["BUNDLE_SPEC_RUN"] = "true"
+ ENV["BUNDLE_USER_CONFIG"] = ENV["BUNDLE_USER_CACHE"] = ENV["BUNDLE_USER_PLUGIN"] = nil
+ ENV["RUBYGEMS_GEMDEPS"] = nil
+ ENV["XDG_CONFIG_HOME"] = nil
+ ENV["GEMRC"] = nil
- config.expect_with :rspec do |c|
- c.syntax = :expect
- end
+ # Don't wrap output in tests
+ ENV["THOR_COLUMNS"] = "10000"
- config.before :suite do
- @orig_ruby = if ENV['BUNDLE_RUBY']
- ruby = Gem.ruby
- Gem.ruby = ENV['BUNDLE_RUBY']
- ruby
- end
+ extend(Spec::Helpers)
+ system_gems :bundler, :path => pristine_system_gem_path
end
config.before :all do
+ check_test_gems!
+
build_repo1
- # HACK: necessary until rspec-mocks > 3.5.0 is used
- # see https://github.com/bundler/bundler/pull/5363#issuecomment-278089256
- if RUBY_VERSION < "1.9"
- FileUtils.module_eval do
- alias_method :mkpath, :mkdir_p
- module_function :mkpath
- end
- end
- end
- config.before :each do
- reset!
- system_gems []
- in_app_root
- @all_output = String.new
+ reset_paths!
end
- config.after :each do |example|
- @all_output.strip!
- if example.exception && !@all_output.empty?
- warn @all_output unless config.formatters.grep(RSpec::Core::Formatters::DocumentationFormatter).empty?
- message = example.exception.message + "\n\nCommands:\n#{@all_output}"
- (class << example.exception; self; end).send(:define_method, :message) do
- message
+ config.around :each do |example|
+ begin
+ FileUtils.cp_r pristine_system_gem_path, system_gem_path
+
+ with_gem_path_as(system_gem_path) do
+ Bundler.ui.silence { example.run }
+
+ all_output = all_commands_output
+ if example.exception && !all_output.empty?
+ message = all_output + "\n" + example.exception.message
+ (class << example.exception; self; end).send(:define_method, :message) do
+ message
+ end
+ end
end
+ ensure
+ reset!
end
-
- Dir.chdir(original_wd)
- ENV.replace(original_env)
end
config.after :suite do
- Gem.ruby = @orig_ruby
+ FileUtils.rm_r Spec::Path.pristine_system_gem_path
end
end
diff --git a/spec/bundler/support/api_request_limit_hax.rb b/spec/bundler/support/api_request_limit_hax.rb
new file mode 100644
index 0000000000..37ff0203b3
--- /dev/null
+++ b/spec/bundler/support/api_request_limit_hax.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+if ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"]
+ require_relative "path"
+ require "bundler/source"
+ require "bundler/source/rubygems"
+
+ module Bundler
+ class Source
+ class Rubygems < Source
+ remove_const :API_REQUEST_LIMIT
+ API_REQUEST_LIMIT = ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"].to_i
+ end
+ end
+ end
+end
diff --git a/spec/bundler/support/artifice/compact_index.rb b/spec/bundler/support/artifice/compact_index.rb
index 9111ed8211..1b314e89ef 100644
--- a/spec/bundler/support/artifice/compact_index.rb
+++ b/spec/bundler/support/artifice/compact_index.rb
@@ -1,26 +1,29 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
-$LOAD_PATH.unshift Dir[base_system_gems.join("gems/compact_index*/lib")].first.to_s
+require_relative "endpoint"
+
+$LOAD_PATH.unshift Dir[Spec::Path.base_system_gems.join("gems/compact_index*/lib")].first.to_s
require "compact_index"
class CompactIndexAPI < Endpoint
helpers do
+ include Spec::Path
+
def load_spec(name, version, platform, gem_repo)
full_name = "#{name}-#{version}"
full_name += "-#{platform}" if platform != "ruby"
- Marshal.load(Gem.inflate(File.open(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read))
+ Marshal.load(Bundler.rubygems.inflate(File.binread(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz"))))
end
def etag_response
response_body = yield
- checksum = Digest::MD5.hexdigest(response_body)
+ checksum = Digest(:MD5).hexdigest(response_body)
return if not_modified?(checksum)
headers "ETag" => quote(checksum)
headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60"
content_type "text/plain"
requested_range_for(response_body)
- rescue => e
+ rescue StandardError => e
puts e
puts e.backtrace
raise
@@ -56,18 +59,14 @@ class CompactIndexAPI < Endpoint
end
def slice_body(body, range)
- if body.respond_to?(:byteslice)
- body.byteslice(range)
- else # pre-1.9.3
- body.unpack("@#{range.first}a#{range.end + 1}").first
- end
+ body.byteslice(range)
end
- def gems(gem_repo = GEM_REPO)
+ def gems(gem_repo = default_gem_repo)
@gems ||= {}
@gems[gem_repo] ||= begin
specs = Bundler::Deprecate.skip_during do
- %w(specs.4.8 prerelease_specs.4.8).map do |filename|
+ %w[specs.4.8 prerelease_specs.4.8].map do |filename|
Marshal.load(File.open(gem_repo.join(filename)).read).map do |name, version, platform|
load_spec(name, version, platform, gem_repo)
end
@@ -81,12 +80,12 @@ class CompactIndexAPI < Endpoint
CompactIndex::Dependency.new(d.name, reqs)
end
checksum = begin
- Digest::SHA256.file("#{GEM_REPO}/gems/#{spec.original_name}.gem").base64digest
- rescue
+ Digest(:SHA256).file("#{gem_repo}/gems/#{spec.original_name}.gem").base64digest
+ rescue StandardError
nil
end
CompactIndex::GemVersion.new(spec.version.version, spec.platform.to_s, checksum, nil,
- deps, spec.required_ruby_version, spec.required_rubygems_version)
+ deps, spec.required_ruby_version.to_s, spec.required_rubygems_version.to_s)
end
CompactIndex::Gem.new(name, gem_versions)
end
@@ -103,7 +102,7 @@ class CompactIndexAPI < Endpoint
get "/versions" do
etag_response do
file = tmp("versions.list")
- file.delete if file.file?
+ FileUtils.rm_f(file)
file = CompactIndex::VersionsFile.new(file.to_s)
file.create(gems)
file.contents
diff --git a/spec/bundler/support/artifice/compact_index_api_missing.rb b/spec/bundler/support/artifice/compact_index_api_missing.rb
index 6d15b54b85..6514fde01e 100644
--- a/spec/bundler/support/artifice/compact_index_api_missing.rb
+++ b/spec/bundler/support/artifice/compact_index_api_missing.rb
@@ -1,15 +1,16 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
class CompactIndexApiMissing < CompactIndexAPI
get "/fetch/actual/gem/:id" do
- $stderr.puts params[:id]
+ warn params[:id]
if params[:id] == "rack-1.0.gemspec.rz"
halt 404
else
- File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
end
end
end
diff --git a/spec/bundler/support/artifice/compact_index_basic_authentication.rb b/spec/bundler/support/artifice/compact_index_basic_authentication.rb
index bffb5b9e2b..775f1a3977 100644
--- a/spec/bundler/support/artifice/compact_index_basic_authentication.rb
+++ b/spec/bundler/support/artifice/compact_index_basic_authentication.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb b/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb
index 4ac328736c..1abe64236c 100644
--- a/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb
+++ b/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/compact_index_concurrent_download.rb b/spec/bundler/support/artifice/compact_index_concurrent_download.rb
index b788a852cf..14c31f35a4 100644
--- a/spec/bundler/support/artifice/compact_index_concurrent_download.rb
+++ b/spec/bundler/support/artifice/compact_index_concurrent_download.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
@@ -9,7 +10,7 @@ class CompactIndexConcurrentDownload < CompactIndexAPI
"localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions")
# Verify the original (empty) content hasn't been deleted, e.g. on a retry
- File.read(versions) == "" || raise("Original file should be present and empty")
+ File.binread(versions) == "" || raise("Original file should be present and empty")
# Verify this is only requested once for a partial download
env["HTTP_RANGE"] || raise("Missing Range header for expected partial download")
@@ -20,7 +21,7 @@ class CompactIndexConcurrentDownload < CompactIndexAPI
etag_response do
file = tmp("versions.list")
- file.delete if file.file?
+ FileUtils.rm_f(file)
file = CompactIndex::VersionsFile.new(file.to_s)
file.create(gems)
file.contents
diff --git a/spec/bundler/support/artifice/compact_index_creds_diff_host.rb b/spec/bundler/support/artifice/compact_index_creds_diff_host.rb
index 0c417f0580..cfe22c7f51 100644
--- a/spec/bundler/support/artifice/compact_index_creds_diff_host.rb
+++ b/spec/bundler/support/artifice/compact_index_creds_diff_host.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
@@ -10,7 +11,7 @@ class CompactIndexCredsDiffHost < CompactIndexAPI
end
def authorized?
- auth.provided? && auth.basic? && auth.credentials && auth.credentials == %w(user pass)
+ auth.provided? && auth.basic? && auth.credentials && auth.credentials == %w[user pass]
end
def protected!
@@ -30,7 +31,7 @@ class CompactIndexCredsDiffHost < CompactIndexAPI
get "/no/creds/:id" do
if request.host.include?("diffhost") && !auth.provided?
- File.read("#{gem_repo1}/gems/#{params[:id]}")
+ File.binread("#{gem_repo1}/gems/#{params[:id]}")
end
end
end
diff --git a/spec/bundler/support/artifice/compact_index_extra.rb b/spec/bundler/support/artifice/compact_index_extra.rb
index 8a87fc4343..cec368276a 100644
--- a/spec/bundler/support/artifice/compact_index_extra.rb
+++ b/spec/bundler/support/artifice/compact_index_extra.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
@@ -13,11 +14,11 @@ class CompactIndexExtra < CompactIndexAPI
end
get "/extra/specs.4.8.gz" do
- File.read("#{gem_repo2}/specs.4.8.gz")
+ File.binread("#{gem_repo2}/specs.4.8.gz")
end
get "/extra/prerelease_specs.4.8.gz" do
- File.read("#{gem_repo2}/prerelease_specs.4.8.gz")
+ File.binread("#{gem_repo2}/prerelease_specs.4.8.gz")
end
get "/extra/quick/Marshal.4.8/:id" do
@@ -25,11 +26,11 @@ class CompactIndexExtra < CompactIndexAPI
end
get "/extra/fetch/actual/gem/:id" do
- File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
end
get "/extra/gems/:id" do
- File.read("#{gem_repo2}/gems/#{params[:id]}")
+ File.binread("#{gem_repo2}/gems/#{params[:id]}")
end
end
diff --git a/spec/bundler/support/artifice/compact_index_extra_api.rb b/spec/bundler/support/artifice/compact_index_extra_api.rb
index 844a9ca9f2..5cc13421a8 100644
--- a/spec/bundler/support/artifice/compact_index_extra_api.rb
+++ b/spec/bundler/support/artifice/compact_index_extra_api.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
@@ -13,7 +14,7 @@ class CompactIndexExtraApi < CompactIndexAPI
get "/extra/versions" do
etag_response do
file = tmp("versions.list")
- file.delete if file.file?
+ FileUtils.rm_f(file)
file = CompactIndex::VersionsFile.new(file.to_s)
file.create(gems(gem_repo4))
file.contents
@@ -28,11 +29,11 @@ class CompactIndexExtraApi < CompactIndexAPI
end
get "/extra/specs.4.8.gz" do
- File.read("#{gem_repo4}/specs.4.8.gz")
+ File.binread("#{gem_repo4}/specs.4.8.gz")
end
get "/extra/prerelease_specs.4.8.gz" do
- File.read("#{gem_repo4}/prerelease_specs.4.8.gz")
+ File.binread("#{gem_repo4}/prerelease_specs.4.8.gz")
end
get "/extra/quick/Marshal.4.8/:id" do
@@ -40,11 +41,11 @@ class CompactIndexExtraApi < CompactIndexAPI
end
get "/extra/fetch/actual/gem/:id" do
- File.read("#{gem_repo4}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo4}/quick/Marshal.4.8/#{params[:id]}")
end
get "/extra/gems/:id" do
- File.read("#{gem_repo4}/gems/#{params[:id]}")
+ File.binread("#{gem_repo4}/gems/#{params[:id]}")
end
end
diff --git a/spec/bundler/support/artifice/compact_index_extra_api_missing.rb b/spec/bundler/support/artifice/compact_index_extra_api_missing.rb
new file mode 100644
index 0000000000..b9d757c266
--- /dev/null
+++ b/spec/bundler/support/artifice/compact_index_extra_api_missing.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative "compact_index_extra_api"
+
+Artifice.deactivate
+
+class CompactIndexExtraAPIMissing < CompactIndexExtraApi
+ get "/extra/fetch/actual/gem/:id" do
+ if params[:id] == "missing-1.0.gemspec.rz"
+ halt 404
+ else
+ File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexExtraAPIMissing)
diff --git a/spec/bundler/support/artifice/compact_index_extra_missing.rb b/spec/bundler/support/artifice/compact_index_extra_missing.rb
index 2af5ce9c27..ff1e47a1bb 100644
--- a/spec/bundler/support/artifice/compact_index_extra_missing.rb
+++ b/spec/bundler/support/artifice/compact_index_extra_missing.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index_extra", __FILE__)
+
+require_relative "compact_index_extra"
Artifice.deactivate
@@ -8,7 +9,7 @@ class CompactIndexExtraMissing < CompactIndexExtra
if params[:id] == "missing-1.0.gemspec.rz"
halt 404
else
- File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
end
end
end
diff --git a/spec/bundler/support/artifice/compact_index_forbidden.rb b/spec/bundler/support/artifice/compact_index_forbidden.rb
index b25eea94e7..3eebe0fbd8 100644
--- a/spec/bundler/support/artifice/compact_index_forbidden.rb
+++ b/spec/bundler/support/artifice/compact_index_forbidden.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/compact_index_host_redirect.rb b/spec/bundler/support/artifice/compact_index_host_redirect.rb
index 6c1ab2def6..304c897d68 100644
--- a/spec/bundler/support/artifice/compact_index_host_redirect.rb
+++ b/spec/bundler/support/artifice/compact_index_host_redirect.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/compact_index_no_gem.rb b/spec/bundler/support/artifice/compact_index_no_gem.rb
new file mode 100644
index 0000000000..0a4be08a46
--- /dev/null
+++ b/spec/bundler/support/artifice/compact_index_no_gem.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require_relative "compact_index"
+
+Artifice.deactivate
+
+class CompactIndexNoGem < CompactIndexAPI
+ get "/gems/:id" do
+ halt 500
+ end
+end
+
+Artifice.activate_with(CompactIndexNoGem)
diff --git a/spec/bundler/support/artifice/compact_index_partial_update.rb b/spec/bundler/support/artifice/compact_index_partial_update.rb
index bf6feab877..cb1c7b9481 100644
--- a/spec/bundler/support/artifice/compact_index_partial_update.rb
+++ b/spec/bundler/support/artifice/compact_index_partial_update.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
@@ -17,19 +18,19 @@ class CompactIndexPartialUpdate < CompactIndexAPI
)
# Verify a cached copy of the versions file exists
- unless File.read(cached_versions_path).start_with?("created_at: ")
+ unless File.binread(cached_versions_path).start_with?("created_at: ")
raise("Cached versions file should be present and have content")
end
# Verify that a partial request is made, starting from the index of the
# final byte of the cached file.
- unless env["HTTP_RANGE"] == "bytes=#{File.read(cached_versions_path).bytesize - 1}-"
+ unless env["HTTP_RANGE"] == "bytes=#{File.binread(cached_versions_path).bytesize - 1}-"
raise("Range header should be present, and start from the index of the final byte of the cache.")
end
etag_response do
# Return the exact contents of the cache.
- File.read(cached_versions_path)
+ File.binread(cached_versions_path)
end
end
end
diff --git a/spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb b/spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb
new file mode 100644
index 0000000000..acf76dfbf0
--- /dev/null
+++ b/spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require_relative "compact_index"
+
+Artifice.deactivate
+
+class CompactIndexPartialUpdateNoEtagNotIncremental < CompactIndexAPI
+ def partial_update_no_etag
+ response_body = yield
+ headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60"
+ content_type "text/plain"
+ requested_range_for(response_body)
+ end
+
+ get "/versions" do
+ partial_update_no_etag do
+ file = tmp("versions.list")
+ FileUtils.rm_f(file)
+ file = CompactIndex::VersionsFile.new(file.to_s)
+ file.create(gems)
+ lines = file.contents([], :calculate_info_checksums => true).split("\n")
+ name, versions, checksum = lines.last.split(" ")
+
+ # shuffle versions so new versions are not appended to the end
+ [*lines[0..-2], [name, versions.split(",").reverse.join(","), checksum].join(" ")].join("\n")
+ end
+ end
+
+ get "/info/:name" do
+ partial_update_no_etag do
+ gem = gems.find {|g| g.name == params[:name] }
+ lines = CompactIndex.info(gem ? gem.versions : []).split("\n")
+
+ # shuffle versions so new versions are not appended to the end
+ [lines.first, lines.last, *lines[1..-2]].join("\n")
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexPartialUpdateNoEtagNotIncremental)
diff --git a/spec/bundler/support/artifice/compact_index_range_not_satisfiable.rb b/spec/bundler/support/artifice/compact_index_range_not_satisfiable.rb
new file mode 100644
index 0000000000..bb616125bb
--- /dev/null
+++ b/spec/bundler/support/artifice/compact_index_range_not_satisfiable.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require_relative "compact_index"
+
+Artifice.deactivate
+
+class CompactIndexRangeNotSatisfiable < CompactIndexAPI
+ get "/versions" do
+ if env["HTTP_RANGE"]
+ status 416
+ else
+ etag_response do
+ file = tmp("versions.list")
+ FileUtils.rm_f(file)
+ file = CompactIndex::VersionsFile.new(file.to_s)
+ file.create(gems)
+ file.contents
+ end
+ end
+ end
+
+ get "/info/:name" do
+ if env["HTTP_RANGE"]
+ status 416
+ else
+ etag_response do
+ gem = gems.find {|g| g.name == params[:name] }
+ CompactIndex.info(gem ? gem.versions : [])
+ end
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexRangeNotSatisfiable)
diff --git a/spec/bundler/support/artifice/compact_index_rate_limited.rb b/spec/bundler/support/artifice/compact_index_rate_limited.rb
new file mode 100644
index 0000000000..570105e2a0
--- /dev/null
+++ b/spec/bundler/support/artifice/compact_index_rate_limited.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require_relative "compact_index"
+
+Artifice.deactivate
+
+class CompactIndexRateLimited < CompactIndexAPI
+ class RequestCounter
+ def self.queue
+ @queue ||= Thread::Queue.new
+ end
+
+ def self.size
+ @queue.size
+ end
+
+ def self.enq(name)
+ @queue.enq(name)
+ end
+
+ def self.deq
+ @queue.deq
+ end
+ end
+
+ configure do
+ RequestCounter.queue
+ end
+
+ get "/info/:name" do
+ RequestCounter.enq(params[:name])
+
+ begin
+ if RequestCounter.size == 1
+ etag_response do
+ gem = gems.find {|g| g.name == params[:name] }
+ CompactIndex.info(gem ? gem.versions : [])
+ end
+ else
+ status 429
+ end
+ ensure
+ RequestCounter.deq
+ end
+ end
+end
+
+Artifice.activate_with(CompactIndexRateLimited)
diff --git a/spec/bundler/support/artifice/compact_index_redirects.rb b/spec/bundler/support/artifice/compact_index_redirects.rb
index ff1d3e43bc..99adc797bf 100644
--- a/spec/bundler/support/artifice/compact_index_redirects.rb
+++ b/spec/bundler/support/artifice/compact_index_redirects.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/compact_index_strict_basic_authentication.rb b/spec/bundler/support/artifice/compact_index_strict_basic_authentication.rb
index 49a072d2b9..7d427b5382 100644
--- a/spec/bundler/support/artifice/compact_index_strict_basic_authentication.rb
+++ b/spec/bundler/support/artifice/compact_index_strict_basic_authentication.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/compact_index_wrong_dependencies.rb b/spec/bundler/support/artifice/compact_index_wrong_dependencies.rb
index 25935f5e5d..036fac70b3 100644
--- a/spec/bundler/support/artifice/compact_index_wrong_dependencies.rb
+++ b/spec/bundler/support/artifice/compact_index_wrong_dependencies.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb b/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb
index 3a12a59ae7..8add32b88f 100644
--- a/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb
+++ b/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../compact_index", __FILE__)
+
+require_relative "compact_index"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endopint_marshal_fail_basic_authentication.rb b/spec/bundler/support/artifice/endopint_marshal_fail_basic_authentication.rb
deleted file mode 100644
index f1f8dc5700..0000000000
--- a/spec/bundler/support/artifice/endopint_marshal_fail_basic_authentication.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-require File.expand_path("../endpoint_marshal_fail", __FILE__)
-
-Artifice.deactivate
-
-class EndpointMarshalFailBasicAuthentication < EndpointMarshalFail
- before do
- unless env["HTTP_AUTHORIZATION"]
- halt 401, "Authentication info not supplied"
- end
- end
-end
-
-Artifice.activate_with(EndpointMarshalFailBasicAuthentication)
diff --git a/spec/bundler/support/artifice/endpoint.rb b/spec/bundler/support/artifice/endpoint.rb
index 771d431f22..4a820e5a3f 100644
--- a/spec/bundler/support/artifice/endpoint.rb
+++ b/spec/bundler/support/artifice/endpoint.rb
@@ -1,47 +1,89 @@
# frozen_string_literal: true
-require File.expand_path("../../path.rb", __FILE__)
-require Spec::Path.root.join("lib/bundler/deprecate")
-include Spec::Path
-$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,rack,tilt,sinatra}-*/lib")].map(&:to_s))
+require_relative "../path"
+
+$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s))
+
require "artifice"
require "sinatra/base"
+ALL_REQUESTS = [] # rubocop:disable Style/MutableConstant
+ALL_REQUESTS_MUTEX = Thread::Mutex.new
+
+at_exit do
+ if expected = ENV["BUNDLER_SPEC_ALL_REQUESTS"]
+ expected = expected.split("\n").sort
+ actual = ALL_REQUESTS.sort
+
+ unless expected == actual
+ raise "Unexpected requests!\nExpected:\n\t#{expected.join("\n\t")}\n\nActual:\n\t#{actual.join("\n\t")}"
+ end
+ end
+end
+
class Endpoint < Sinatra::Base
- GEM_REPO = Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"] || Spec::Path.gem_repo1)
+ def self.all_requests
+ @all_requests ||= []
+ end
+
set :raise_errors, true
set :show_exceptions, false
+ def call!(*)
+ super.tap do
+ ALL_REQUESTS_MUTEX.synchronize do
+ ALL_REQUESTS << @request.url
+ end
+ end
+ end
+
helpers do
- def dependencies_for(gem_names, gem_repo = GEM_REPO)
- return [] if gem_names.nil? || gem_names.empty?
+ include Spec::Path
- require "rubygems"
- require "bundler"
- Bundler::Deprecate.skip_during do
- all_specs = %w(specs.4.8 prerelease_specs.4.8).map do |filename|
- Marshal.load(File.open(gem_repo.join(filename)).read)
- end.inject(:+)
-
- all_specs.map do |name, version, platform|
- spec = load_spec(name, version, platform, gem_repo)
- next unless gem_names.include?(spec.name)
- {
- :name => spec.name,
- :number => spec.version.version,
- :platform => spec.platform.to_s,
- :dependencies => spec.dependencies.select {|dep| dep.type == :runtime }.map do |dep|
- [dep.name, dep.requirement.requirements.map {|a| a.join(" ") }.join(", ")]
- end
- }
- end.compact
+ def default_gem_repo
+ if ENV["BUNDLER_SPEC_GEM_REPO"]
+ Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"])
+ else
+ case request.host
+ when "gem.repo1"
+ Spec::Path.gem_repo1
+ when "gem.repo2"
+ Spec::Path.gem_repo2
+ when "gem.repo3"
+ Spec::Path.gem_repo3
+ when "gem.repo4"
+ Spec::Path.gem_repo4
+ else
+ Spec::Path.gem_repo1
+ end
end
end
+ def dependencies_for(gem_names, gem_repo = default_gem_repo)
+ return [] if gem_names.nil? || gem_names.empty?
+
+ all_specs = %w[specs.4.8 prerelease_specs.4.8].map do |filename|
+ Marshal.load(File.open(gem_repo.join(filename)).read)
+ end.inject(:+)
+
+ all_specs.map do |name, version, platform|
+ spec = load_spec(name, version, platform, gem_repo)
+ next unless gem_names.include?(spec.name)
+ {
+ :name => spec.name,
+ :number => spec.version.version,
+ :platform => spec.platform.to_s,
+ :dependencies => spec.dependencies.select {|dep| dep.type == :runtime }.map do |dep|
+ [dep.name, dep.requirement.requirements.map {|a| a.join(" ") }.join(", ")]
+ end,
+ }
+ end.compact
+ end
+
def load_spec(name, version, platform, gem_repo)
full_name = "#{name}-#{version}"
full_name += "-#{platform}" if platform != "ruby"
- Marshal.load(Gem.inflate(File.open(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read))
+ Marshal.load(Bundler.rubygems.inflate(File.binread(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz"))))
end
end
@@ -50,11 +92,11 @@ class Endpoint < Sinatra::Base
end
get "/fetch/actual/gem/:id" do
- File.read("#{GEM_REPO}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{default_gem_repo}/quick/Marshal.4.8/#{params[:id]}")
end
get "/gems/:id" do
- File.read("#{GEM_REPO}/gems/#{params[:id]}")
+ File.binread("#{default_gem_repo}/gems/#{params[:id]}")
end
get "/api/v1/dependencies" do
@@ -62,11 +104,11 @@ class Endpoint < Sinatra::Base
end
get "/specs.4.8.gz" do
- File.read("#{GEM_REPO}/specs.4.8.gz")
+ File.binread("#{default_gem_repo}/specs.4.8.gz")
end
get "/prerelease_specs.4.8.gz" do
- File.read("#{GEM_REPO}/prerelease_specs.4.8.gz")
+ File.binread("#{default_gem_repo}/prerelease_specs.4.8.gz")
end
end
diff --git a/spec/bundler/support/artifice/endpoint_500.rb b/spec/bundler/support/artifice/endpoint_500.rb
index 993630b79e..0ce8dfeaad 100644
--- a/spec/bundler/support/artifice/endpoint_500.rb
+++ b/spec/bundler/support/artifice/endpoint_500.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require File.expand_path("../../path.rb", __FILE__)
-include Spec::Path
-$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,rack,tilt,sinatra}-*/lib")].map(&:to_s))
+require_relative "../path"
+
+$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s))
require "artifice"
require "sinatra/base"
diff --git a/spec/bundler/support/artifice/endpoint_api_forbidden.rb b/spec/bundler/support/artifice/endpoint_api_forbidden.rb
index 21ad9117ed..edc2463424 100644
--- a/spec/bundler/support/artifice/endpoint_api_forbidden.rb
+++ b/spec/bundler/support/artifice/endpoint_api_forbidden.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endpoint_api_missing.rb b/spec/bundler/support/artifice/endpoint_api_missing.rb
index 6f5b5f1323..755c42e836 100644
--- a/spec/bundler/support/artifice/endpoint_api_missing.rb
+++ b/spec/bundler/support/artifice/endpoint_api_missing.rb
@@ -1,15 +1,16 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
class EndpointApiMissing < Endpoint
get "/fetch/actual/gem/:id" do
- $stderr.puts params[:id]
+ warn params[:id]
if params[:id] == "rack-1.0.gemspec.rz"
halt 404
else
- File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
end
end
end
diff --git a/spec/bundler/support/artifice/endpoint_basic_authentication.rb b/spec/bundler/support/artifice/endpoint_basic_authentication.rb
index 9fafd51a3d..ff3d1493d6 100644
--- a/spec/bundler/support/artifice/endpoint_basic_authentication.rb
+++ b/spec/bundler/support/artifice/endpoint_basic_authentication.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endpoint_creds_diff_host.rb b/spec/bundler/support/artifice/endpoint_creds_diff_host.rb
index cd152848fe..8b8972cedd 100644
--- a/spec/bundler/support/artifice/endpoint_creds_diff_host.rb
+++ b/spec/bundler/support/artifice/endpoint_creds_diff_host.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
@@ -10,7 +11,7 @@ class EndpointCredsDiffHost < Endpoint
end
def authorized?
- auth.provided? && auth.basic? && auth.credentials && auth.credentials == %w(user pass)
+ auth.provided? && auth.basic? && auth.credentials && auth.credentials == %w[user pass]
end
def protected!
@@ -30,7 +31,7 @@ class EndpointCredsDiffHost < Endpoint
get "/no/creds/:id" do
if request.host.include?("diffhost") && !auth.provided?
- File.read("#{gem_repo1}/gems/#{params[:id]}")
+ File.binread("#{gem_repo1}/gems/#{params[:id]}")
end
end
end
diff --git a/spec/bundler/support/artifice/endpoint_extra.rb b/spec/bundler/support/artifice/endpoint_extra.rb
index ed4e87e65f..942c4352b7 100644
--- a/spec/bundler/support/artifice/endpoint_extra.rb
+++ b/spec/bundler/support/artifice/endpoint_extra.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
@@ -9,11 +10,11 @@ class EndpointExtra < Endpoint
end
get "/extra/specs.4.8.gz" do
- File.read("#{gem_repo2}/specs.4.8.gz")
+ File.binread("#{gem_repo2}/specs.4.8.gz")
end
get "/extra/prerelease_specs.4.8.gz" do
- File.read("#{gem_repo2}/prerelease_specs.4.8.gz")
+ File.binread("#{gem_repo2}/prerelease_specs.4.8.gz")
end
get "/extra/quick/Marshal.4.8/:id" do
@@ -21,11 +22,11 @@ class EndpointExtra < Endpoint
end
get "/extra/fetch/actual/gem/:id" do
- File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
end
get "/extra/gems/:id" do
- File.read("#{gem_repo2}/gems/#{params[:id]}")
+ File.binread("#{gem_repo2}/gems/#{params[:id]}")
end
end
diff --git a/spec/bundler/support/artifice/endpoint_extra_api.rb b/spec/bundler/support/artifice/endpoint_extra_api.rb
index 1e9e1dc60d..1cfef7a7fc 100644
--- a/spec/bundler/support/artifice/endpoint_extra_api.rb
+++ b/spec/bundler/support/artifice/endpoint_extra_api.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
@@ -10,11 +11,11 @@ class EndpointExtraApi < Endpoint
end
get "/extra/specs.4.8.gz" do
- File.read("#{gem_repo4}/specs.4.8.gz")
+ File.binread("#{gem_repo4}/specs.4.8.gz")
end
get "/extra/prerelease_specs.4.8.gz" do
- File.read("#{gem_repo4}/prerelease_specs.4.8.gz")
+ File.binread("#{gem_repo4}/prerelease_specs.4.8.gz")
end
get "/extra/quick/Marshal.4.8/:id" do
@@ -22,11 +23,11 @@ class EndpointExtraApi < Endpoint
end
get "/extra/fetch/actual/gem/:id" do
- File.read("#{gem_repo4}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo4}/quick/Marshal.4.8/#{params[:id]}")
end
get "/extra/gems/:id" do
- File.read("#{gem_repo4}/gems/#{params[:id]}")
+ File.binread("#{gem_repo4}/gems/#{params[:id]}")
end
end
diff --git a/spec/bundler/support/artifice/endpoint_extra_missing.rb b/spec/bundler/support/artifice/endpoint_extra_missing.rb
index dc79705a26..5fd9238207 100644
--- a/spec/bundler/support/artifice/endpoint_extra_missing.rb
+++ b/spec/bundler/support/artifice/endpoint_extra_missing.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint_extra", __FILE__)
+
+require_relative "endpoint_extra"
Artifice.deactivate
@@ -8,7 +9,7 @@ class EndpointExtraMissing < EndpointExtra
if params[:id] == "missing-1.0.gemspec.rz"
halt 404
else
- File.read("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
+ File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
end
end
end
diff --git a/spec/bundler/support/artifice/endpoint_fallback.rb b/spec/bundler/support/artifice/endpoint_fallback.rb
index 8a85a41784..08edf232e3 100644
--- a/spec/bundler/support/artifice/endpoint_fallback.rb
+++ b/spec/bundler/support/artifice/endpoint_fallback.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endpoint_host_redirect.rb b/spec/bundler/support/artifice/endpoint_host_redirect.rb
index 250416d8cc..338cbcad00 100644
--- a/spec/bundler/support/artifice/endpoint_host_redirect.rb
+++ b/spec/bundler/support/artifice/endpoint_host_redirect.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endpoint_marshal_fail.rb b/spec/bundler/support/artifice/endpoint_marshal_fail.rb
index 0fb75ebf31..22c13e3e17 100644
--- a/spec/bundler/support/artifice/endpoint_marshal_fail.rb
+++ b/spec/bundler/support/artifice/endpoint_marshal_fail.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint_fallback", __FILE__)
+
+require_relative "endpoint_fallback"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endpoint_marshal_fail_basic_authentication.rb b/spec/bundler/support/artifice/endpoint_marshal_fail_basic_authentication.rb
new file mode 100644
index 0000000000..c341c3993f
--- /dev/null
+++ b/spec/bundler/support/artifice/endpoint_marshal_fail_basic_authentication.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require_relative "endpoint_marshal_fail"
+
+Artifice.deactivate
+
+class EndpointMarshalFailBasicAuthentication < EndpointMarshalFail
+ before do
+ unless env["HTTP_AUTHORIZATION"]
+ halt 401, "Authentication info not supplied"
+ end
+ end
+end
+
+Artifice.activate_with(EndpointMarshalFailBasicAuthentication)
diff --git a/spec/bundler/support/artifice/endpoint_mirror_source.rb b/spec/bundler/support/artifice/endpoint_mirror_source.rb
index 9fb58ecb29..788a9027f3 100644
--- a/spec/bundler/support/artifice/endpoint_mirror_source.rb
+++ b/spec/bundler/support/artifice/endpoint_mirror_source.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
class EndpointMirrorSource < Endpoint
get "/gems/:id" do
if request.env["HTTP_X_GEMFILE_SOURCE"] == "https://server.example.org/"
- File.read("#{gem_repo1}/gems/#{params[:id]}")
+ File.binread("#{gem_repo1}/gems/#{params[:id]}")
else
halt 500
end
diff --git a/spec/bundler/support/artifice/endpoint_redirect.rb b/spec/bundler/support/artifice/endpoint_redirect.rb
index f80d7600c2..ee97fccf64 100644
--- a/spec/bundler/support/artifice/endpoint_redirect.rb
+++ b/spec/bundler/support/artifice/endpoint_redirect.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endpoint_strict_basic_authentication.rb b/spec/bundler/support/artifice/endpoint_strict_basic_authentication.rb
index 4b32cbbf5b..4d4da08770 100644
--- a/spec/bundler/support/artifice/endpoint_strict_basic_authentication.rb
+++ b/spec/bundler/support/artifice/endpoint_strict_basic_authentication.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint", __FILE__)
+
+require_relative "endpoint"
Artifice.deactivate
diff --git a/spec/bundler/support/artifice/endpoint_timeout.rb b/spec/bundler/support/artifice/endpoint_timeout.rb
index b15650f226..c118da1893 100644
--- a/spec/bundler/support/artifice/endpoint_timeout.rb
+++ b/spec/bundler/support/artifice/endpoint_timeout.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
-require File.expand_path("../endpoint_fallback", __FILE__)
+
+require_relative "endpoint_fallback"
Artifice.deactivate
class EndpointTimeout < EndpointFallback
- SLEEP_TIMEOUT = 15
+ SLEEP_TIMEOUT = 3
get "/api/v1/dependencies" do
sleep(SLEEP_TIMEOUT)
diff --git a/spec/bundler/support/artifice/fail.rb b/spec/bundler/support/artifice/fail.rb
index 1059c6df4e..f69f2eccc6 100644
--- a/spec/bundler/support/artifice/fail.rb
+++ b/spec/bundler/support/artifice/fail.rb
@@ -1,11 +1,6 @@
# frozen_string_literal: true
require "net/http"
-begin
- require "net/https"
-rescue LoadError
- nil # net/https or openssl
-end
# We can't use artifice here because it uses rack
diff --git a/spec/bundler/support/artifice/vcr.rb b/spec/bundler/support/artifice/vcr.rb
new file mode 100644
index 0000000000..0d51201bef
--- /dev/null
+++ b/spec/bundler/support/artifice/vcr.rb
@@ -0,0 +1,165 @@
+# frozen_string_literal: true
+
+require "net/http"
+require_relative "../path"
+
+CASSETTE_PATH = "#{Spec::Path.spec_dir}/support/artifice/vcr_cassettes"
+CASSETTE_NAME = ENV.fetch("BUNDLER_SPEC_VCR_CASSETTE_NAME") { "realworld" }
+
+class BundlerVCRHTTP < Net::HTTP
+ class RequestHandler
+ attr_reader :http, :request, :body, :response_block
+ def initialize(http, request, body = nil, &response_block)
+ @http = http
+ @request = request
+ @body = body
+ @response_block = response_block
+ end
+
+ def handle_request
+ handler = self
+ request.instance_eval do
+ @__vcr_request_handler = handler
+ end
+
+ if recorded_response?
+ recorded_response
+ else
+ record_response
+ end
+ end
+
+ def recorded_response?
+ return true if ENV["BUNDLER_SPEC_PRE_RECORDED"]
+ request_pair_paths.all? {|f| File.exist?(f) }
+ end
+
+ def recorded_response
+ File.open(request_pair_paths.last, "rb:ASCII-8BIT") do |response_file|
+ response_io = ::Net::BufferedIO.new(response_file)
+ ::Net::HTTPResponse.read_new(response_io).tap do |response|
+ response.decode_content = request.decode_content if request.respond_to?(:decode_content)
+ response.uri = request.uri
+
+ response.reading_body(response_io, request.response_body_permitted?) do
+ response_block.call(response) if response_block
+ end
+ end
+ end
+ end
+
+ def record_response
+ request_path, response_path = *request_pair_paths
+
+ @recording = true
+
+ response = http.request_without_vcr(request, body, &response_block)
+ @recording = false
+ unless @recording
+ require "fileutils"
+ FileUtils.mkdir_p(File.dirname(request_path))
+ binwrite(request_path, request_to_string(request))
+ binwrite(response_path, response_to_string(response))
+ end
+ response
+ end
+
+ def key
+ [request["host"] || http.address, request.path, request.method].compact
+ end
+
+ def file_name_for_key(key)
+ key.join("/").gsub(/[\:*?"<>|]/, "-")
+ end
+
+ def request_pair_paths
+ %w[request response].map do |kind|
+ File.join(CASSETTE_PATH, CASSETTE_NAME, file_name_for_key(key + [kind]))
+ end
+ end
+
+ def read_stored_request(path)
+ contents = File.binread(path)
+ headers = {}
+ method = nil
+ path = nil
+ contents.lines.grep(/^> /).each do |line|
+ if line =~ /^> (GET|HEAD|POST|PATCH|PUT|DELETE) (.*)/
+ method = $1
+ path = $2.strip
+ elsif line =~ /^> (.*?): (.*)/
+ headers[$1] = $2
+ end
+ end
+ body = contents =~ /^([^>].*)/m && $1
+ Net::HTTP.const_get(method.capitalize).new(path, headers).tap {|r| r.body = body if body }
+ end
+
+ def request_to_string(request)
+ request_string = []
+ request_string << "> #{request.method.upcase} #{request.path}"
+ request.to_hash.each do |key, value|
+ request_string << "> #{key}: #{Array(value).first}"
+ end
+ request << "" << request.body if request.body
+ request_string.join("\n")
+ end
+
+ def response_to_string(response)
+ headers = response.to_hash
+ body = response.body
+
+ response_string = []
+ response_string << "HTTP/1.1 #{response.code} #{response.message}"
+
+ headers["content-length"] = [body.bytesize.to_s] if body
+
+ headers.each do |header, value|
+ response_string << "#{header}: #{value.join(", ")}"
+ end
+
+ response_string << "" << body
+
+ response_string = response_string.join("\n")
+ if response_string.respond_to?(:force_encoding)
+ response_string.force_encoding("ASCII-8BIT")
+ else
+ response_string
+ end
+ end
+
+ def binwrite(path, contents)
+ File.open(path, "wb:ASCII-8BIT") {|f| f.write(contents) }
+ end
+ end
+
+ def start_with_vcr
+ if ENV["BUNDLER_SPEC_PRE_RECORDED"]
+ raise IOError, "HTTP session already opened" if @started
+ @socket = nil
+ @started = true
+ else
+ start_without_vcr
+ end
+ end
+
+ alias_method :start_without_vcr, :start
+ alias_method :start, :start_with_vcr
+
+ def request_with_vcr(request, *args, &block)
+ handler = request.instance_eval do
+ remove_instance_variable(:@__vcr_request_handler) if defined?(@__vcr_request_handler)
+ end || RequestHandler.new(self, request, *args, &block)
+
+ handler.handle_request
+ end
+
+ alias_method :request_without_vcr, :request
+ alias_method :request, :request_with_vcr
+end
+
+# Replace Net::HTTP with our VCR subclass
+::Net.class_eval do
+ remove_const(:HTTP)
+ const_set(:HTTP, BundlerVCRHTTP)
+end
diff --git a/spec/bundler/support/artifice/windows.rb b/spec/bundler/support/artifice/windows.rb
index c18ca454ec..ddbbd62b96 100644
--- a/spec/bundler/support/artifice/windows.rb
+++ b/spec/bundler/support/artifice/windows.rb
@@ -1,11 +1,9 @@
# frozen_string_literal: true
-require File.expand_path("../../path.rb", __FILE__)
-include Spec::Path
-$LOAD_PATH.unshift Dir[base_system_gems.join("gems/artifice*/lib")].first.to_s
-$LOAD_PATH.unshift(*Dir[base_system_gems.join("gems/rack-*/lib")])
-$LOAD_PATH.unshift Dir[base_system_gems.join("gems/tilt*/lib")].first.to_s
-$LOAD_PATH.unshift Dir[base_system_gems.join("gems/sinatra*/lib")].first.to_s
+require_relative "../path"
+
+$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s))
+
require "artifice"
require "sinatra/base"
@@ -16,7 +14,7 @@ class Windows < Sinatra::Base
set :show_exceptions, false
helpers do
- def gem_repo
+ def default_gem_repo
Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"] || Spec::Path.gem_repo1)
end
end
@@ -28,7 +26,7 @@ class Windows < Sinatra::Base
files.each do |file|
get "/#{file}" do
- File.read gem_repo.join(file)
+ File.binread default_gem_repo.join(file)
end
end
diff --git a/spec/bundler/support/build_metadata.rb b/spec/bundler/support/build_metadata.rb
new file mode 100644
index 0000000000..98d8ac23c8
--- /dev/null
+++ b/spec/bundler/support/build_metadata.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require_relative "path"
+require_relative "helpers"
+
+module Spec
+ module BuildMetadata
+ include Spec::Path
+ include Spec::Helpers
+
+ def write_build_metadata(dir: source_root)
+ build_metadata = {
+ :git_commit_sha => git_commit_sha,
+ :built_at => loaded_gemspec.date.utc.strftime("%Y-%m-%d"),
+ :release => true,
+ }
+
+ replace_build_metadata(build_metadata, dir: dir) # rubocop:disable Style/HashSyntax
+ end
+
+ def reset_build_metadata(dir: source_root)
+ build_metadata = {
+ :release => false,
+ }
+
+ replace_build_metadata(build_metadata, dir: dir) # rubocop:disable Style/HashSyntax
+ end
+
+ private
+
+ def replace_build_metadata(build_metadata, dir:)
+ build_metadata_file = File.expand_path("lib/bundler/build_metadata.rb", dir)
+
+ ivars = build_metadata.sort.map do |k, v|
+ " @#{k} = #{loaded_gemspec.send(:ruby_code, v)}"
+ end.join("\n")
+
+ contents = File.read(build_metadata_file)
+ contents.sub!(/^(\s+# begin ivars).+(^\s+# end ivars)/m, "\\1\n#{ivars}\n\\2")
+ File.open(build_metadata_file, "w") {|f| f << contents }
+ end
+
+ def git_commit_sha
+ ruby_core_tarball? ? "unknown" : sys_exec("git rev-parse --short HEAD", :dir => source_root).strip
+ end
+
+ extend self
+ end
+end
diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb
index db128d497b..90e9cbb242 100644
--- a/spec/bundler/support/builders.rb
+++ b/spec/bundler/support/builders.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "bundler/shared_helpers"
require "shellwords"
@@ -16,9 +17,30 @@ module Spec
Gem::Platform.new(platform)
end
+ # Returns a number smaller than the size of the index. Useful for specs that
+ # need the API request limit to be reached for some reason.
+ def low_api_request_limit_for(gem_repo)
+ all_gems = Dir[gem_repo.join("gems/*.gem")]
+
+ all_gem_names = all_gems.map do |file|
+ File.basename(file, ".gem").match(/\A(?<gem_name>[^-]+)-.*\z/)[:gem_name]
+ end.uniq
+
+ (all_gem_names - ["bundler"]).size
+ end
+
def build_repo1
+ rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
+
build_repo gem_repo1 do
- build_gem "rack", %w(0.9.1 1.0.0) do |s|
+ FileUtils.cp rake_path, "#{gem_repo1}/gems/"
+
+ build_gem "coffee-script-source"
+ build_gem "git"
+ build_gem "puma"
+ build_gem "minitest"
+
+ build_gem "rack", %w[0.9.1 1.0.0] do |s|
s.executables = "rackup"
s.post_install_message = "Rack's post install message"
end
@@ -39,7 +61,7 @@ module Spec
build_gem "rails", "2.3.2" do |s|
s.executables = "rails"
- s.add_dependency "rake", "10.0.2"
+ s.add_dependency "rake", "13.0.1"
s.add_dependency "actionpack", "2.3.2"
s.add_dependency "activerecord", "2.3.2"
s.add_dependency "actionmailer", "2.3.2"
@@ -57,20 +79,12 @@ module Spec
build_gem "activeresource", "2.3.2" do |s|
s.add_dependency "activesupport", "2.3.2"
end
- build_gem "activesupport", %w(1.2.3 2.3.2 2.3.5)
+ build_gem "activesupport", %w[1.2.3 2.3.2 2.3.5]
build_gem "activemerchant" do |s|
s.add_dependency "activesupport", ">= 2.0.0"
end
- build_gem "rails_fail" do |s|
- s.add_dependency "activesupport", "= 1.2.3"
- end
-
- build_gem "missing_dep" do |s|
- s.add_dependency "not_here"
- end
-
build_gem "rspec", "1.2.7", :no_default => true do |s|
s.write "lib/spec.rb", "SPEC = '1.2.7'"
end
@@ -100,6 +114,14 @@ module Spec
end
build_gem "platform_specific" do |s|
+ s.platform = "x86-mingw32"
+ end
+
+ build_gem "platform_specific" do |s|
+ s.platform = "x64-mingw32"
+ end
+
+ build_gem "platform_specific" do |s|
s.platform = "x86-darwin-100"
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 x86-darwin-100'"
end
@@ -137,50 +159,8 @@ module Spec
build_gem "duradura", "7.0"
- build_gem "multiple_versioned_deps" do |s|
- s.add_dependency "weakling", ">= 0.0.1", "< 0.1"
- end
-
- build_gem "not_released", "1.0.pre"
-
- build_gem "has_prerelease", "1.0"
- build_gem "has_prerelease", "1.1.pre"
-
- build_gem "with_development_dependency" do |s|
- s.add_development_dependency "activesupport", "= 2.3.5"
- end
-
- build_gem "with_license" do |s|
- s.license = "MIT"
- end
-
- build_gem "with_implicit_rake_dep" do |s|
- s.extensions << "Rakefile"
- s.write "Rakefile", <<-RUBY
- task :default do
- path = File.expand_path("../lib", __FILE__)
- FileUtils.mkdir_p(path)
- File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
- f.puts "IMPLICIT_RAKE_DEP = 'YES'"
- end
- end
- RUBY
- end
-
- build_gem "another_implicit_rake_dep" do |s|
- s.extensions << "Rakefile"
- s.write "Rakefile", <<-RUBY
- task :default do
- path = File.expand_path("../lib", __FILE__)
- FileUtils.mkdir_p(path)
- File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
- f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
- end
- end
- RUBY
- end
-
build_gem "very_simple_binary", &:add_c_extension
+ build_gem "simple_binary", &:add_c_extension
build_gem "bundler", "0.9" do |s|
s.executables = "bundle"
@@ -193,110 +173,21 @@ module Spec
s.write "lib/rubygems_plugin.rb", "require 'bundler/omg' ; puts 'FAIL'"
end
- build_gem "bundler_dep" do |s|
- s.add_dependency "bundler"
- end
-
# The yard gem iterates over Gem.source_index looking for plugins
build_gem "yard" do |s|
s.write "lib/yard.rb", <<-Y
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("1.8.10")
- specs = Gem::Specification
- else
- specs = Gem.source_index.find_name('')
- end
- specs.sort_by(&:name).each do |gem|
+ Gem::Specification.sort_by(&:name).each do |gem|
puts gem.full_name
end
Y
end
- # The rcov gem is platform mswin32, but has no arch
- build_gem "rcov" do |s|
- s.platform = Gem::Platform.new([nil, "mswin32", nil])
- s.write "lib/rcov.rb", "RCOV = '1.0.0'"
- end
-
build_gem "net-ssh"
build_gem "net-sftp", "1.1.1" do |s|
s.add_dependency "net-ssh", ">= 1.0.0", "< 1.99.0"
end
- # Test complicated gem dependencies for install
- build_gem "net_a" do |s|
- s.add_dependency "net_b"
- s.add_dependency "net_build_extensions"
- end
-
- build_gem "net_b"
-
- build_gem "net_build_extensions" do |s|
- s.add_dependency "rake"
- s.extensions << "Rakefile"
- s.write "Rakefile", <<-RUBY
- task :default do
- path = File.expand_path("../lib", __FILE__)
- FileUtils.mkdir_p(path)
- File.open("\#{path}/net_build_extensions.rb", "w") do |f|
- f.puts "NET_BUILD_EXTENSIONS = 'YES'"
- end
- end
- RUBY
- end
-
- build_gem "net_c" do |s|
- s.add_dependency "net_a"
- s.add_dependency "net_d"
- end
-
- build_gem "net_d"
-
- build_gem "net_e" do |s|
- s.add_dependency "net_d"
- end
-
- # Capistrano did this (at least until version 2.5.10)
- # Rubygems 2.2 doesn't allow the specifying of a dependency twice
- # See https://github.com/rubygems/rubygems/commit/03dbac93a3396a80db258d9bc63500333c25bd2f
- build_gem "double_deps", "1.0", :skip_validation => true do |s|
- s.add_dependency "net-ssh", ">= 1.0.0"
- s.add_dependency "net-ssh"
- end
-
build_gem "foo"
-
- # A minimal fake pry console
- build_gem "pry" do |s|
- s.write "lib/pry.rb", <<-RUBY
- class Pry
- class << self
- def toplevel_binding
- unless defined?(@toplevel_binding) && @toplevel_binding
- TOPLEVEL_BINDING.eval %{
- def self.__pry__; binding; end
- Pry.instance_variable_set(:@toplevel_binding, __pry__)
- class << self; undef __pry__; end
- }
- end
- @toplevel_binding.eval('private')
- @toplevel_binding
- end
-
- def __pry__
- while line = gets
- begin
- puts eval(line, toplevel_binding).inspect.sub(/^"(.*)"$/, '=> \\1')
- rescue Exception => e
- puts "\#{e.class}: \#{e.message}"
- puts e.backtrace.first
- end
- end
- end
- alias start __pry__
- end
- end
- RUBY
- end
end
end
@@ -306,13 +197,6 @@ module Spec
update_repo2(&blk) if block_given?
end
- def build_repo3
- build_repo gem_repo3 do
- build_gem "rack"
- end
- FileUtils.rm_rf Dir[gem_repo3("prerelease*")]
- end
-
# A repo that has no pre-installed gems included. (The caller completely
# determines the contents with the block.)
def build_repo4(&blk)
@@ -326,9 +210,6 @@ module Spec
def update_repo2
update_repo gem_repo2 do
- build_gem "rack", "1.2" do |s|
- s.executables = "rackup"
- end
yield if block_given?
end
end
@@ -350,22 +231,24 @@ module Spec
def build_repo(path, &blk)
return if File.directory?(path)
+
+ FileUtils.mkdir_p("#{path}/gems")
+
+ update_repo(path, &blk)
+ end
+
+ def check_test_gems!
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
if rake_path.nil?
- Spec::Path.base_system_gems.rmtree
- Spec::Rubygems.setup
+ FileUtils.rm_rf(Path.base_system_gems)
+ Spec::Rubygems.install_test_deps
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
end
- if rake_path
- FileUtils.mkdir_p("#{path}/gems")
- FileUtils.cp rake_path, "#{path}/gems/"
- else
+ if rake_path.nil?
abort "Your test gems are missing! Run `rm -rf #{tmp}` and try again."
end
-
- update_repo(path, &blk)
end
def update_repo(path)
@@ -377,7 +260,7 @@ module Spec
@_build_repo = File.basename(path)
yield
with_gem_path_as Path.base_system_gems do
- Dir.chdir(path) { gem_command! :generate_index }
+ gem_command :generate_index, :dir => path
end
ensure
@_build_path = nil
@@ -390,7 +273,7 @@ module Spec
index
end
- def build_spec(name, version, platform = nil, &block)
+ def build_spec(name, version = "0.0.1", platform = nil, &block)
Array(version).map do |v|
Gem::Specification.new do |s|
s.name = name
@@ -419,20 +302,20 @@ module Spec
opts = args.last.is_a?(Hash) ? args.last : {}
builder = opts[:bare] ? GitBareBuilder : GitBuilder
spec = build_with(builder, name, args, &block)
- GitReader.new(opts[:path] || lib_path(spec.full_name))
+ GitReader.new(self, opts[:path] || lib_path(spec.full_name))
end
def update_git(name, *args, &block)
opts = args.last.is_a?(Hash) ? args.last : {}
spec = build_with(GitUpdater, name, args, &block)
- GitReader.new(opts[:path] || lib_path(spec.full_name))
+ GitReader.new(self, opts[:path] || lib_path(spec.full_name))
end
def build_plugin(name, *args, &blk)
build_with(PluginBuilder, name, args, &blk)
end
- private
+ private
def build_with(builder, name, args, &blk)
@_build_path ||= nil
@@ -446,7 +329,6 @@ module Spec
Array(versions).each do |version|
spec = builder.new(self, name, version)
- spec.authors = ["no one"] if !spec.authors || spec.authors.empty?
yield spec if block_given?
spec._build(options)
end
@@ -552,7 +434,7 @@ module Spec
"#!/usr/bin/env ruby\n"
end
@spec.files << executable
- write executable, "#{shebang}require '#{@name}' ; puts #{Builders.constantize(@name)}"
+ write executable, "#{shebang}require_relative '../lib/#{@name}' ; puts #{Builders.constantize(@name)}"
end
end
@@ -565,7 +447,7 @@ module Spec
# exit 1 unless with_config("simple")
- extension_name = "very_simple_binary_c"
+ extension_name = "#{name}_c"
if extra_lib_dir = with_config("ext-lib")
# add extra libpath if --with-ext-lib is
# passed in as a build_arg
@@ -575,11 +457,11 @@ module Spec
end
create_makefile extension_name
RUBY
- write "ext/very_simple_binary.c", <<-C
+ write "ext/#{name}.c", <<-C
#include "ruby.h"
- void Init_very_simple_binary_c() {
- rb_define_module("VerySimpleBinaryInC");
+ void Init_#{name}_c() {
+ rb_define_module("#{Builders.constantize(name)}_IN_C");
}
C
end
@@ -591,60 +473,69 @@ module Spec
@spec.rubygems_version = options[:rubygems_version]
def @spec.mark_version; end
- def @spec.validate; end
+ def @spec.validate(*); end
+ end
+
+ unless options[:no_default]
+ gem_source = options[:source] || "path@#{path}"
+ @files = _default_files.
+ merge("lib/#{entrypoint}/source.rb" => "#{Builders.constantize(name)}_SOURCE = #{gem_source.to_s.dump}").
+ merge(@files)
end
+ @spec.authors = ["no one"]
+ @spec.files = @files.keys
+
case options[:gemspec]
when false
# do nothing
when :yaml
+ @spec.files << "#{name}.gemspec"
@files["#{name}.gemspec"] = @spec.to_yaml
else
+ @spec.files << "#{name}.gemspec"
@files["#{name}.gemspec"] = @spec.to_ruby
end
- unless options[:no_default]
- gem_source = options[:source] || "path@#{path}"
- @files = _default_files.
- merge("lib/#{name}/source.rb" => "#{Builders.constantize(name)}_SOURCE = #{gem_source.to_s.dump}").
- merge(@files)
- end
-
- @spec.authors = ["no one"]
-
@files.each do |file, source|
file = Pathname.new(path).join(file)
FileUtils.mkdir_p(file.dirname)
File.open(file, "w") {|f| f.puts source }
+ File.chmod("+x", file) if @spec.executables.map {|exe| "#{@spec.bindir}/#{exe}" }.include?(file)
end
- @spec.files = @files.keys
path
end
def _default_files
- @_default_files ||= begin
- platform_string = " #{@spec.platform}" unless @spec.platform == Gem::Platform::RUBY
- { "lib/#{name}.rb" => "#{Builders.constantize(name)} = '#{version}#{platform_string}'" }
- end
+ @_default_files ||= { "lib/#{entrypoint}.rb" => "#{Builders.constantize(name)} = '#{version}#{platform_string}'" }
+ end
+
+ def entrypoint
+ name.tr("-", "/")
end
def _default_path
@context.tmp("libs", @spec.full_name)
end
+
+ def platform_string
+ " #{@spec.platform}" unless @spec.platform == Gem::Platform::RUBY
+ end
end
class GitBuilder < LibBuilder
def _build(options)
+ default_branch = options[:default_branch] || "master"
path = options[:path] || _default_path
source = options[:source] || "git@#{path}"
super(options.merge(:path => path, :source => source))
- Dir.chdir(path) do
- `git init`
- `git add *`
- `git config user.email "lol@wut.com"`
- `git config user.name "lolwut"`
- `git commit -m 'OMG INITIAL COMMIT'`
- end
+ @context.git("config --global init.defaultBranch #{default_branch}", path)
+ @context.git("init", path)
+ @context.git("add *", path)
+ @context.git("config user.email lol@wut.com", path)
+ @context.git("config user.name lolwut", path)
+ @context.git("config commit.gpgsign false", path)
+ @context.git("commit -m OMG_INITIAL_COMMIT", path)
end
end
@@ -652,90 +543,73 @@ module Spec
def _build(options)
path = options[:path] || _default_path
super(options.merge(:path => path))
- Dir.chdir(path) do
- `git init --bare`
- end
+ @context.git("init --bare", path)
end
end
class GitUpdater < LibBuilder
- def silently(str)
- `#{str} 2>#{Bundler::NULL}`
- end
-
def _build(options)
libpath = options[:path] || _default_path
update_gemspec = options[:gemspec] || false
source = options[:source] || "git@#{libpath}"
- Dir.chdir(libpath) do
- silently "git checkout master"
-
- if branch = options[:branch]
- raise "You can't specify `master` as the branch" if branch == "master"
- escaped_branch = Shellwords.shellescape(branch)
-
- if `git branch | grep #{escaped_branch}`.empty?
- silently("git branch #{escaped_branch}")
- end
-
- silently("git checkout #{escaped_branch}")
- elsif tag = options[:tag]
- `git tag #{Shellwords.shellescape(tag)}`
- elsif options[:remote]
- silently("git remote add origin file://#{options[:remote]}")
- elsif options[:push]
- silently("git push origin #{options[:push]}")
- end
+ if branch = options[:branch]
+ @context.git("checkout -b #{Shellwords.shellescape(branch)}", libpath)
+ elsif tag = options[:tag]
+ @context.git("tag #{Shellwords.shellescape(tag)}", libpath)
+ elsif options[:remote]
+ @context.git("remote add origin #{options[:remote]}", libpath)
+ elsif options[:push]
+ @context.git("push origin #{options[:push]}", libpath)
+ end
- current_ref = `git rev-parse HEAD`.strip
- _default_files.keys.each do |path|
- _default_files[path] += "\n#{Builders.constantize(name)}_PREV_REF = '#{current_ref}'"
- end
- super(options.merge(:path => libpath, :gemspec => update_gemspec, :source => source))
- `git add *`
- `git commit -m "BUMP"`
+ current_ref = @context.git("rev-parse HEAD", libpath).strip
+ _default_files.keys.each do |path|
+ _default_files[path] += "\n#{Builders.constantize(name)}_PREV_REF = '#{current_ref}'"
end
+ super(options.merge(:path => libpath, :gemspec => update_gemspec, :source => source))
+ @context.git("commit -am BUMP", libpath)
end
end
class GitReader
- attr_reader :path
+ attr_reader :context, :path
- def initialize(path)
+ def initialize(context, path)
+ @context = context
@path = path
end
def ref_for(ref, len = nil)
- ref = git "rev-parse #{ref}"
+ ref = context.git "rev-parse #{ref}", path
ref = ref[0..len] if len
ref
end
-
- private
-
- def git(cmd)
- Bundler::SharedHelpers.with_clean_git_env do
- Dir.chdir(@path) { `git #{cmd}`.strip }
- end
- end
end
class GemBuilder < LibBuilder
def _build(opts)
lib_path = super(opts.merge(:path => @context.tmp(".tmp/#{@spec.full_name}"), :no_default => opts[:no_default]))
- Dir.chdir(lib_path) do
- destination = opts[:path] || _default_path
- FileUtils.mkdir_p(destination)
-
- @spec.authors = ["that guy"] if !@spec.authors || @spec.authors.empty?
+ destination = opts[:path] || _default_path
+ FileUtils.mkdir_p(lib_path.join(destination))
- Bundler.rubygems.build(@spec, opts[:skip_validation])
- if opts[:to_system]
- `gem install --ignore-dependencies --no-ri --no-rdoc #{@spec.full_name}.gem`
- else
- FileUtils.mv("#{@spec.full_name}.gem", opts[:path] || _default_path)
+ if opts[:gemspec] == :yaml || opts[:gemspec] == false
+ Dir.chdir(lib_path) do
+ Bundler.rubygems.build(@spec, opts[:skip_validation])
end
+ elsif opts[:skip_validation]
+ @context.gem_command "build --force #{@spec.name}", :dir => lib_path
+ else
+ @context.gem_command "build #{@spec.name}", :dir => lib_path
+ end
+
+ gem_path = File.expand_path("#{@spec.full_name}.gem", lib_path)
+ if opts[:to_system]
+ @context.system_gems gem_path, :default => opts[:default]
+ elsif opts[:to_bundle]
+ @context.system_gems gem_path, :path => @context.default_bundle_path
+ else
+ FileUtils.mv(gem_path, destination)
end
end
@@ -746,7 +620,10 @@ module Spec
class PluginBuilder < GemBuilder
def _default_files
- @_default_files ||= super.merge("plugins.rb" => "")
+ @_default_files ||= {
+ "lib/#{name}.rb" => "#{Builders.constantize(name)} = '#{version}#{platform_string}'",
+ "plugins.rb" => "",
+ }
end
end
diff --git a/spec/bundler/support/bundle.rb b/spec/bundler/support/bundle.rb
new file mode 100644
index 0000000000..bb21526d35
--- /dev/null
+++ b/spec/bundler/support/bundle.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+require "rubygems"
+require_relative "path"
+bundler_gemspec = Spec::Path.loaded_gemspec
+bundler_gemspec.instance_variable_set(:@full_gem_path, Spec::Path.source_root)
+bundler_gemspec.activate if bundler_gemspec.respond_to?(:activate)
+load File.expand_path("bundle", Spec::Path.bindir)
diff --git a/spec/bundler/support/code_climate.rb b/spec/bundler/support/code_climate.rb
deleted file mode 100644
index 8f1fb35bcd..0000000000
--- a/spec/bundler/support/code_climate.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-module Spec
- module CodeClimate
- def self.setup
- require "codeclimate-test-reporter"
- ::CodeClimate::TestReporter.start
- configure_exclusions
- rescue LoadError
- # it's fine if CodeClimate isn't set up
- nil
- end
-
- def self.configure_exclusions
- SimpleCov.start do
- add_filter "/bin/"
- add_filter "/lib/bundler/man/"
- add_filter "/lib/bundler/vendor/"
- add_filter "/man/"
- add_filter "/pkg/"
- add_filter "/spec/"
- add_filter "/tmp/"
- end
- end
- end
-end
diff --git a/spec/bundler/support/command_execution.rb b/spec/bundler/support/command_execution.rb
new file mode 100644
index 0000000000..68e5c56c75
--- /dev/null
+++ b/spec/bundler/support/command_execution.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Spec
+ CommandExecution = Struct.new(:command, :working_directory, :exitstatus, :stdout, :stderr) do
+ def to_s
+ "$ #{command}"
+ end
+ alias_method :inspect, :to_s
+
+ def stdboth
+ @stdboth ||= [stderr, stdout].join("\n").strip
+ end
+
+ def to_s_verbose
+ [
+ to_s,
+ stdout,
+ stderr,
+ exitstatus ? "# $? => #{exitstatus}" : "",
+ ].reject(&:empty?).join("\n")
+ end
+
+ def success?
+ return true unless exitstatus
+ exitstatus == 0
+ end
+
+ def failure?
+ return true unless exitstatus
+ exitstatus > 0
+ end
+ end
+end
diff --git a/spec/bundler/support/filters.rb b/spec/bundler/support/filters.rb
new file mode 100644
index 0000000000..3b91897a2e
--- /dev/null
+++ b/spec/bundler/support/filters.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require_relative "sudo"
+
+class RequirementChecker < Proc
+ def self.against(present)
+ provided = Gem::Version.new(present)
+
+ new do |required|
+ !Gem::Requirement.new(required).satisfied_by?(provided)
+ end.tap do |checker|
+ checker.provided = provided
+ end
+ end
+
+ attr_accessor :provided
+
+ def inspect
+ "\"!= #{provided}\""
+ end
+end
+
+RSpec.configure do |config|
+ config.filter_run_excluding :sudo => true
+ config.filter_run_excluding :realworld => true
+
+ git_version = Bundler::Source::Git::GitProxy.new(nil, nil, nil).version
+
+ config.filter_run_excluding :git => RequirementChecker.against(git_version)
+ config.filter_run_excluding :bundler => RequirementChecker.against(Bundler::VERSION.split(".")[0])
+ config.filter_run_excluding :ruby_repo => !ENV["GEM_COMMAND"].nil?
+ config.filter_run_excluding :no_color_tty => Gem.win_platform? || !ENV["GITHUB_ACTION"].nil?
+ config.filter_run_excluding :permissions => Gem.win_platform?
+ config.filter_run_excluding :readline => Gem.win_platform?
+ config.filter_run_excluding :jruby => RUBY_ENGINE != "jruby"
+ config.filter_run_excluding :truffleruby => RUBY_ENGINE != "truffleruby"
+ config.filter_run_excluding :man => Gem.win_platform?
+
+ config.filter_run_when_matching :focus unless ENV["CI"]
+end
diff --git a/spec/bundler/support/hax.rb b/spec/bundler/support/hax.rb
index 663d3527c5..0ad5239128 100644
--- a/spec/bundler/support/hax.rb
+++ b/spec/bundler/support/hax.rb
@@ -1,47 +1,44 @@
# frozen_string_literal: true
-require "rubygems"
module Gem
- class Platform
- @local = new(ENV["BUNDLER_SPEC_PLATFORM"]) if ENV["BUNDLER_SPEC_PLATFORM"]
+ def self.ruby=(ruby)
+ @ruby = ruby
end
- @platforms = [Gem::Platform::RUBY, Gem::Platform.local]
-end
-if ENV["BUNDLER_SPEC_VERSION"]
- module Bundler
- remove_const(:VERSION) if const_defined?(:VERSION)
- VERSION = ENV["BUNDLER_SPEC_VERSION"].dup
+ if ENV["RUBY"]
+ Gem.ruby = ENV["RUBY"]
end
-end
-
-if ENV["BUNDLER_SPEC_WINDOWS"] == "true"
- require "bundler/constants"
- module Bundler
- remove_const :WINDOWS if defined?(WINDOWS)
- WINDOWS = true
+ if ENV["BUNDLER_GEM_DEFAULT_DIR"]
+ @default_dir = ENV["BUNDLER_GEM_DEFAULT_DIR"]
+ @default_specifications_dir = nil
end
-end
-class Object
- if ENV["BUNDLER_SPEC_RUBY_ENGINE"]
- if defined?(RUBY_ENGINE) && RUBY_ENGINE != "jruby" && ENV["BUNDLER_SPEC_RUBY_ENGINE"] == "jruby"
- begin
- # this has to be done up front because psych will try to load a .jar
- # if it thinks its on jruby
- require "psych"
- rescue LoadError
- nil
+ if ENV["BUNDLER_SPEC_PLATFORM"]
+ class Platform
+ @local = new(ENV["BUNDLER_SPEC_PLATFORM"])
+ end
+ @platforms = [Gem::Platform::RUBY, Gem::Platform.local]
+
+ if ENV["BUNDLER_SPEC_PLATFORM"] == "ruby"
+ class << self
+ remove_method :finish_resolve
+
+ def finish_resolve
+ []
+ end
end
end
+ end
- remove_const :RUBY_ENGINE if defined?(RUBY_ENGINE)
- RUBY_ENGINE = ENV["BUNDLER_SPEC_RUBY_ENGINE"]
+ if ENV["BUNDLER_SPEC_GEM_SOURCES"]
+ @sources = [ENV["BUNDLER_SPEC_GEM_SOURCES"]]
+ end
- if RUBY_ENGINE == "jruby"
- remove_const :JRUBY_VERSION if defined?(JRUBY_VERSION)
- JRUBY_VERSION = ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"]
+ # We only need this hack for rubygems versions without the BundlerVersionFinder
+ if Gem.rubygems_version < Gem::Version.new("2.7.0")
+ @path_to_default_spec_map.delete_if do |_path, spec|
+ spec.name == "bundler"
end
end
end
diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb
index 192747da05..e44c67835f 100644
--- a/spec/bundler/support/helpers.rb
+++ b/spec/bundler/support/helpers.rb
@@ -1,69 +1,75 @@
# frozen_string_literal: true
+require_relative "command_execution"
+require_relative "the_bundle"
+require_relative "path"
+
module Spec
module Helpers
+ include Spec::Path
+
def reset!
Dir.glob("#{tmp}/{gems/*,*}", File::FNM_DOTMATCH).each do |dir|
- next if %w(base remote1 gems rubygems . ..).include?(File.basename(dir))
- if ENV["BUNDLER_SUDO_TESTS"]
- `sudo rm -rf "#{dir}"`
- else
- FileUtils.rm_rf(dir)
- end
+ next if %w[base base_system remote1 rubocop standard gems rubygems . ..].include?(File.basename(dir))
+ FileUtils.rm_rf(dir)
end
FileUtils.mkdir_p(home)
FileUtils.mkdir_p(tmpdir)
- Bundler.reset!
- Bundler.ui = nil
- Bundler.ui # force it to initialize
- end
-
- def self.bang(method)
- define_method("#{method}!") do |*args, &blk|
- send(method, *args, &blk).tap do
- if exitstatus && exitstatus != 0
- error = out + "\n" + err
- error.strip!
- raise RuntimeError,
- "Invoking #{method}!(#{args.map(&:inspect).join(", ")}) failed:\n#{error}",
- caller.drop_while {|bt| bt.start_with?(__FILE__) }
- end
- end
- end
+ reset_paths!
end
- attr_reader :out, :err, :exitstatus
+ def reset_paths!
+ Bundler.reset!
+ Gem.clear_paths
+ end
def the_bundle(*args)
TheBundle.new(*args)
end
- def in_app_root(&blk)
- Dir.chdir(bundled_app, &blk)
+ def command_executions
+ @command_executions ||= []
+ end
+
+ def last_command
+ command_executions.last || raise("There is no last command")
+ end
+
+ def out
+ last_command.stdout
+ end
+
+ def err
+ last_command.stderr
end
- def in_app_root2(&blk)
- Dir.chdir(bundled_app2, &blk)
+ MAJOR_DEPRECATION = /^\[DEPRECATED\]\s*/.freeze
+
+ def err_without_deprecations
+ err.gsub(/#{MAJOR_DEPRECATION}.+[\n]?/, "")
+ end
+
+ def deprecations
+ err.split("\n").select {|l| l =~ MAJOR_DEPRECATION }.join("\n").split(MAJOR_DEPRECATION)
end
- def in_app_root_custom(root, &blk)
- Dir.chdir(root, &blk)
+ def exitstatus
+ last_command.exitstatus
end
def run(cmd, *args)
opts = args.last.is_a?(Hash) ? args.pop : {}
groups = args.map(&:inspect).join(", ")
- setup = "require 'rubygems' ; require 'bundler' ; Bundler.setup(#{groups})\n"
- @out = ruby(setup + cmd, opts)
+ setup = "require '#{entrypoint}' ; Bundler.ui.silence { Bundler.setup(#{groups}) }"
+ ruby([setup, cmd].join(" ; "), opts)
end
- bang :run
def load_error_run(ruby, name, *args)
cmd = <<-RUBY
begin
#{ruby}
rescue LoadError => e
- $stderr.puts "ZOMG LOAD ERROR" if e.message.include?("-- #{name}")
+ warn "ZOMG LOAD ERROR" if e.message.include?("-- #{name}")
end
RUBY
opts = args.last.is_a?(Hash) ? args.pop : {}
@@ -71,126 +77,151 @@ module Spec
run(cmd, *args)
end
- def lib
- root.join("lib")
- end
-
- def spec
- spec_dir.to_s
- end
-
- def bundle(cmd, options = {})
+ def bundle(cmd, options = {}, &block)
with_sudo = options.delete(:sudo)
- sudo = with_sudo == :preserve_env ? "sudo -E" : "sudo" if with_sudo
+ sudo = with_sudo == :preserve_env ? "sudo -E --preserve-env=RUBYOPT" : "sudo" if with_sudo
- options["no-color"] = true unless options.key?("no-color") || cmd.to_s =~ /\A(e|ex|exe|exec|conf|confi|config)(\s|\z)/
+ bundle_bin = options.delete(:bundle_bin)
+ bundle_bin ||= installed_bindir.join("bundle")
- bundle_bin = options.delete("bundle_bin") || bindir.join("bundle")
-
- if system_bundler = options.delete(:system_bundler)
- bundle_bin = "-S bundle"
- end
+ env = options.delete(:env) || {}
requires = options.delete(:requires) || []
- if artifice = options.delete(:artifice) { "fail" unless RSpec.current_example.metadata[:realworld] }
- requires << File.expand_path("../artifice/#{artifice}.rb", __FILE__)
+
+ artifice = options.delete(:artifice) do
+ if RSpec.current_example.metadata[:realworld]
+ "vcr"
+ else
+ "fail"
+ end
+ end
+ if artifice
+ requires << "#{Path.spec_dir}/support/artifice/#{artifice}.rb"
end
- requires << "support/hax"
- requires_str = requires.map {|r| "-r#{r}" }.join(" ")
load_path = []
- load_path << lib unless system_bundler
- load_path << spec
- load_path_str = "-I#{load_path.join(File::PATH_SEPARATOR)}"
+ load_path << spec_dir
+
+ dir = options.delete(:dir) || bundled_app
+ raise_on_error = options.delete(:raise_on_error)
- env = (options.delete(:env) || {}).map {|k, v| "#{k}='#{v}'" }.join(" ")
- env["PATH"].gsub!(Path.bindir, "") if env["PATH"] && system_bundler
args = options.map do |k, v|
- v == true ? " --#{k}" : " --#{k} #{v}" if v
+ case v
+ when nil
+ next
+ when true
+ " --#{k}"
+ when false
+ " --no-#{k}"
+ else
+ " --#{k} #{v}"
+ end
end.join
- cmd = "#{env} #{sudo} #{Gem.ruby} #{load_path_str} #{requires_str} #{bundle_bin} #{cmd}#{args}"
- sys_exec(cmd) {|i, o, thr| yield i, o, thr if block_given? }
+ ruby_cmd = build_ruby_cmd({ :sudo => sudo, :load_path => load_path, :requires => requires })
+ cmd = "#{ruby_cmd} #{bundle_bin} #{cmd}#{args}"
+ sys_exec(cmd, { :env => env, :dir => dir, :raise_on_error => raise_on_error }, &block)
end
- bang :bundle
def bundler(cmd, options = {})
- options["bundle_bin"] = bindir.join("bundler")
+ options[:bundle_bin] = system_gem_path.join("bin/bundler")
bundle(cmd, options)
end
- def bundle_ruby(options = {})
- options["bundle_bin"] = bindir.join("bundle_ruby")
- bundle("", options)
- end
-
def ruby(ruby, options = {})
- env = (options.delete(:env) || {}).map {|k, v| "#{k}='#{v}' " }.join
- ruby = ruby.gsub(/["`\$]/) {|m| "\\#{m}" }
- lib_option = options[:no_lib] ? "" : " -I#{lib}"
- sys_exec(%(#{env}#{Gem.ruby}#{lib_option} -e "#{ruby}"))
+ ruby_cmd = build_ruby_cmd
+ escaped_ruby = ruby.shellescape
+ sys_exec(%(#{ruby_cmd} -w -e #{escaped_ruby}), options)
end
- bang :ruby
def load_error_ruby(ruby, name, opts = {})
ruby(<<-R)
begin
#{ruby}
rescue LoadError => e
- $stderr.puts "ZOMG LOAD ERROR"# if e.message.include?("-- #{name}")
+ warn "ZOMG LOAD ERROR" if e.message.include?("-- #{name}")
end
R
end
- def gembin(cmd)
- lib = File.expand_path("../../../lib", __FILE__)
- old = ENV["RUBYOPT"]
- ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -I#{lib}"
+ def build_ruby_cmd(options = {})
+ sudo = options.delete(:sudo)
+
+ libs = options.delete(:load_path)
+ lib_option = libs ? "-I#{libs.join(File::PATH_SEPARATOR)}" : []
+
+ requires = options.delete(:requires) || []
+ requires << "#{Path.spec_dir}/support/hax.rb"
+ require_option = requires.map {|r| "-r#{r}" }
+
+ [sudo, Gem.ruby, *lib_option, *require_option].compact.join(" ")
+ end
+
+ def gembin(cmd, options = {})
cmd = bundled_app("bin/#{cmd}") unless cmd.to_s.include?("/")
- sys_exec(cmd.to_s)
- ensure
- ENV["RUBYOPT"] = old
+ sys_exec(cmd.to_s, options)
end
- def gem_command(command, args = "", options = {})
- if command == :exec && !options[:no_quote]
- args = args.gsub(/(?=")/, "\\")
- args = %("#{args}")
- end
- gem = ENV['BUNDLE_GEM'] || "#{Gem.ruby} -rrubygems -S gem --backtrace"
- sys_exec("#{gem} #{command} #{args}")
+ def gem_command(command, options = {})
+ env = options[:env] || {}
+ env["RUBYOPT"] = opt_add("-r#{spec_dir}/support/hax.rb", env["RUBYOPT"] || ENV["RUBYOPT"])
+ options[:env] = env
+ sys_exec("#{Path.gem_bin} #{command}", options)
end
- bang :gem_command
def rake
- if ENV['BUNDLE_RUBY'] && ENV['BUNDLE_GEM']
- "#{ENV['BUNDLE_RUBY']} #{ENV['GEM_PATH']}/bin/rake"
- else
- 'rake'
- end
+ "#{Gem.ruby} -S #{ENV["GEM_PATH"]}/bin/rake"
+ end
+
+ def git(cmd, path, options = {})
+ sys_exec("git #{cmd}", options.merge(:dir => path))
end
- def sys_exec(cmd)
- Open3.popen3(cmd.to_s) do |stdin, stdout, stderr, wait_thr|
+ def sys_exec(cmd, options = {})
+ env = options[:env] || {}
+ env["RUBYOPT"] = opt_add("-r#{spec_dir}/support/switch_rubygems.rb", env["RUBYOPT"] || ENV["RUBYOPT"])
+ dir = options[:dir] || bundled_app
+ command_execution = CommandExecution.new(cmd.to_s, dir)
+
+ require "open3"
+ require "shellwords"
+ Open3.popen3(env, *cmd.shellsplit, :chdir => dir) do |stdin, stdout, stderr, wait_thr|
yield stdin, stdout, wait_thr if block_given?
stdin.close
- @exitstatus = wait_thr && wait_thr.value.exitstatus
- @out = Thread.new { stdout.read }.value.strip
- @err = Thread.new { stderr.read }.value.strip
+ stdout_read_thread = Thread.new { stdout.read }
+ stderr_read_thread = Thread.new { stderr.read }
+ command_execution.stdout = stdout_read_thread.value.strip
+ command_execution.stderr = stderr_read_thread.value.strip
+
+ status = wait_thr.value
+ command_execution.exitstatus = if status.exited?
+ status.exitstatus
+ elsif status.signaled?
+ 128 + status.termsig
+ end
+ end
+
+ unless options[:raise_on_error] == false || command_execution.success?
+ raise <<~ERROR
+
+ Invoking `#{cmd}` failed with output:
+ ----------------------------------------------------------------------
+ #{command_execution.stdboth}
+ ----------------------------------------------------------------------
+ ERROR
end
- (@all_output ||= String.new) << [
- "$ #{cmd.to_s.strip}",
- out,
- err,
- @exitstatus ? "# $? => #{@exitstatus}" : "",
- "\n",
- ].reject(&:empty?).join("\n")
+ command_executions << command_execution
+
+ command_execution.stdout
+ end
+
+ def all_commands_output
+ return "" if command_executions.empty?
- @out
+ "\n\nCommands:\n#{command_executions.map(&:to_s_verbose).join("\n\n")}"
end
- bang :sys_exec
def config(config = nil, path = bundled_app(".bundle/config"))
return YAML.load_file(path) unless config
@@ -216,18 +247,22 @@ module Spec
end
def gemfile(*args)
- if args.empty?
- File.open("Gemfile", "r", &:read)
+ contents = args.shift
+
+ if contents.nil?
+ File.open(bundled_app_gemfile, "r", &:read)
else
- create_file("Gemfile", *args)
+ create_file("Gemfile", contents, *args)
end
end
def lockfile(*args)
- if args.empty?
- File.open("Gemfile.lock", "r", &:read)
+ contents = args.shift
+
+ if contents.nil?
+ File.open(bundled_app_lock, "r", &:read)
else
- create_file("Gemfile.lock", *args)
+ create_file("Gemfile.lock", contents, *args)
end
end
@@ -240,65 +275,113 @@ module Spec
def install_gemfile(*args)
gemfile(*args)
opts = args.last.is_a?(Hash) ? args.last : {}
- opts[:retry] ||= 0
bundle :install, opts
end
- bang :install_gemfile
def lock_gemfile(*args)
gemfile(*args)
opts = args.last.is_a?(Hash) ? args.last : {}
- opts[:retry] ||= 0
bundle :lock, opts
end
- def install_gems(*gems)
+ def system_gems(*gems)
+ gems = gems.flatten
options = gems.last.is_a?(Hash) ? gems.pop : {}
- gem_repo = options.fetch(:gem_repo) { gem_repo1 }
- gems.each do |g|
- path = if g == :bundler
- Dir.chdir(root) { gem_command! :build, gemspec.to_s }
- bundler_path = root + "bundler-#{Bundler::VERSION}.gem"
- elsif g.to_s =~ %r{\A/.*\.gem\z}
- g
- else
- "#{gem_repo}/gems/#{g}.gem"
+ path = options.fetch(:path, system_gem_path)
+ default = options.fetch(:default, false)
+ with_gem_path_as(path) do
+ gem_repo = options.fetch(:gem_repo, gem_repo1)
+ gems.each do |g|
+ gem_name = g.to_s
+ if gem_name.start_with?("bundler")
+ version = gem_name.match(/\Abundler-(?<version>.*)\z/)[:version] if gem_name != "bundler"
+ with_built_bundler(version) {|gem_path| install_gem(gem_path, default) }
+ elsif gem_name =~ %r{\A(?:[a-zA-Z]:)?/.*\.gem\z}
+ install_gem(gem_name, default)
+ else
+ install_gem("#{gem_repo}/gems/#{gem_name}.gem", default)
+ end
end
+ end
+ end
- raise "OMG `#{path}` does not exist!" unless File.exist?(path)
+ def install_gem(path, default = false)
+ raise "OMG `#{path}` does not exist!" unless File.exist?(path)
- gem_command! :install, "--no-rdoc --no-ri --ignore-dependencies '#{path}'"
- bundler_path && bundler_path.rmtree
- end
+ args = "--no-document --ignore-dependencies"
+ args += " --default --install-dir #{system_gem_path}" if default
+
+ gem_command "install #{args} '#{path}'"
end
- alias_method :install_gem, :install_gems
+ def with_built_bundler(version = nil)
+ version ||= Bundler::VERSION
+ full_name = "bundler-#{version}"
+ build_path = tmp + full_name
+ bundler_path = build_path + "#{full_name}.gem"
+
+ Dir.mkdir build_path
+
+ begin
+ shipped_files.each do |shipped_file|
+ target_shipped_file = build_path + shipped_file
+ target_shipped_dir = File.dirname(target_shipped_file)
+ FileUtils.mkdir_p target_shipped_dir unless File.directory?(target_shipped_dir)
+ FileUtils.cp shipped_file, target_shipped_file, :preserve => true
+ end
+
+ replace_version_file(version, dir: build_path) # rubocop:disable Style/HashSyntax
+
+ Spec::BuildMetadata.write_build_metadata(dir: build_path) # rubocop:disable Style/HashSyntax
+
+ gem_command "build #{relative_gemspec}", :dir => build_path
+
+ yield(bundler_path)
+ ensure
+ build_path.rmtree
+ end
+ end
def with_gem_path_as(path)
- backup = ENV.to_hash
- ENV["GEM_HOME"] = path.to_s
- ENV["GEM_PATH"] = path.to_s
- ENV["BUNDLER_ORIG_GEM_PATH"] = nil
- yield
- ensure
- ENV.replace(backup)
+ without_env_side_effects do
+ ENV["GEM_HOME"] = path.to_s
+ ENV["GEM_PATH"] = path.to_s
+ ENV["BUNDLER_ORIG_GEM_PATH"] = nil
+ yield
+ end
end
def with_path_as(path)
+ without_env_side_effects do
+ ENV["PATH"] = path.to_s
+ ENV["BUNDLER_ORIG_PATH"] = nil
+ yield
+ end
+ end
+
+ def without_env_side_effects
backup = ENV.to_hash
- ENV["PATH"] = path.to_s
- ENV["BUNDLER_ORIG_PATH"] = nil
yield
ensure
ENV.replace(backup)
end
def with_path_added(path)
- with_path_as(path.to_s + ":" + ENV["PATH"]) do
+ with_path_as([path.to_s, ENV["PATH"]].join(File::PATH_SEPARATOR)) do
yield
end
end
+ def opt_add(option, options)
+ [option.strip, options].compact.reject(&:empty?).join(" ")
+ end
+
+ def opt_remove(option, options)
+ return unless options
+
+ options.split(" ").reject {|opt| opt.strip == option.strip }.join(" ")
+ end
+
def break_git!
FileUtils.mkdir_p(tmp("broken_path"))
File.open(tmp("broken_path/git"), "w", 0o755) do |f|
@@ -309,6 +392,8 @@ module Spec
end
def with_fake_man
+ skip "fake_man is not a Windows friendly binstub" if Gem.win_platform?
+
FileUtils.mkdir_p(tmp("fake_man"))
File.open(tmp("fake_man/man"), "w", 0o755) do |f|
f.puts "#!/usr/bin/env ruby\nputs ARGV.inspect\n"
@@ -316,52 +401,21 @@ module Spec
with_path_added(tmp("fake_man")) { yield }
end
- def system_gems(*gems)
- gems = gems.flatten
-
+ def pristine_system_gems(*gems)
FileUtils.rm_rf(system_gem_path)
- FileUtils.mkdir_p(system_gem_path)
- Gem.clear_paths
-
- env_backup = ENV.to_hash
- ENV["GEM_HOME"] = system_gem_path.to_s
- ENV["GEM_PATH"] = system_gem_path.to_s
- ENV["BUNDLER_ORIG_GEM_PATH"] = nil
-
- install_gems(*gems)
- return unless block_given?
- begin
- yield
- ensure
- ENV.replace(env_backup)
- end
+ system_gems(*gems)
end
def realworld_system_gems(*gems)
gems = gems.flatten
+ opts = gems.last.is_a?(Hash) ? gems.pop : {}
+ path = opts.fetch(:path, system_gem_path)
- FileUtils.rm_rf(system_gem_path)
- FileUtils.mkdir_p(system_gem_path)
-
- Gem.clear_paths
-
- gem_home = ENV["GEM_HOME"]
- gem_path = ENV["GEM_PATH"]
- path = ENV["PATH"]
- ENV["GEM_HOME"] = system_gem_path.to_s
- ENV["GEM_PATH"] = system_gem_path.to_s
-
- gems.each do |gem|
- gem_command :install, "--no-rdoc --no-ri #{gem}"
- end
- return unless block_given?
- begin
- yield
- ensure
- ENV["GEM_HOME"] = gem_home
- ENV["GEM_PATH"] = gem_path
- ENV["PATH"] = path
+ with_gem_path_as(path) do
+ gems.each do |gem|
+ gem_command "install --no-document #{gem}"
+ end
end
end
@@ -379,9 +433,8 @@ module Spec
end
def simulate_new_machine
- system_gems []
- FileUtils.rm_rf default_bundle_path
FileUtils.rm_rf bundled_app(".bundle")
+ pristine_system_gems :bundler
end
def simulate_platform(platform)
@@ -401,43 +454,40 @@ module Spec
ENV["BUNDLER_SPEC_RUBY_VERSION"] = old if block_given?
end
- def simulate_ruby_engine(engine, version = "1.6.0")
- return if engine == local_ruby_engine
-
- old = ENV["BUNDLER_SPEC_RUBY_ENGINE"]
- ENV["BUNDLER_SPEC_RUBY_ENGINE"] = engine
- old_version = ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"]
- ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"] = version
- yield if block_given?
- ensure
- ENV["BUNDLER_SPEC_RUBY_ENGINE"] = old if block_given?
- ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"] = old_version if block_given?
+ def simulate_windows(platform = mswin)
+ simulate_platform platform do
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ yield
+ end
+ end
end
- def simulate_bundler_version(version)
- old = ENV["BUNDLER_SPEC_VERSION"]
- ENV["BUNDLER_SPEC_VERSION"] = version.to_s
- yield if block_given?
+ def simulate_bundler_version_when_missing_prerelease_default_gem_activation
+ return yield unless rubygems_version_failing_to_activate_bundler_prereleases
+
+ old = ENV["BUNDLER_VERSION"]
+ ENV["BUNDLER_VERSION"] = Bundler::VERSION
+ yield
ensure
- ENV["BUNDLER_SPEC_VERSION"] = old if block_given?
+ ENV["BUNDLER_VERSION"] = old
end
- def simulate_windows
- old = ENV["BUNDLER_SPEC_WINDOWS"]
- ENV["BUNDLER_SPEC_WINDOWS"] = "true"
- simulate_platform mswin do
- yield
+ def env_for_missing_prerelease_default_gem_activation
+ if rubygems_version_failing_to_activate_bundler_prereleases
+ { "BUNDLER_VERSION" => Bundler::VERSION }
+ else
+ {}
end
- ensure
- ENV["BUNDLER_SPEC_WINDOWS"] = old
end
- def revision_for(path)
- Dir.chdir(path) { `git rev-parse HEAD`.strip }
+ # versions providing a bundler version finder but not including
+ # https://github.com/rubygems/rubygems/commit/929e92d752baad3a08f3ac92eaec162cb96aedd1
+ def rubygems_version_failing_to_activate_bundler_prereleases
+ Gem.rubygems_version < Gem::Version.new("3.1.0.pre.1") && Gem.rubygems_version >= Gem::Version.new("2.7.0")
end
- def capture_output
- capture(:stdout)
+ def revision_for(path)
+ sys_exec("git rev-parse HEAD", :dir => path).strip
end
def with_read_only(pattern)
@@ -454,6 +504,22 @@ module Spec
Dir[pattern].each(&chmod[0o755, 0o644])
end
+ # Simulate replacing TODOs with real values
+ def prepare_gemspec(pathname)
+ process_file(pathname) do |line|
+ case line
+ when /spec\.metadata\["(?:allowed_push_host|homepage_uri|source_code_uri|changelog_uri)"\]/, /spec\.homepage/
+ line.gsub(/\=.*$/, '= "http://example.org"')
+ when /spec\.summary/
+ line.gsub(/\=.*$/, '= "A short summary of my new gem."')
+ when /spec\.description/
+ line.gsub(/\=.*$/, '= "A longer description of my new gem."')
+ else
+ line
+ end
+ end
+ end
+
def process_file(pathname)
changed_lines = pathname.readlines.map do |line|
yield line
@@ -485,7 +551,7 @@ module Spec
tries = 0
sleep 0.5
TCPSocket.new(host, port)
- rescue => e
+ rescue StandardError => e
raise(e) if tries > (seconds * 2)
tries += 1
retry
@@ -495,10 +561,16 @@ module Spec
port = 21_453
begin
port += 1 while TCPSocket.new("127.0.0.1", port)
- rescue
+ rescue StandardError
false
end
port
end
+
+ private
+
+ def git_root_dir?
+ root.to_s == `git rev-parse --show-toplevel`.chomp
+ end
end
end
diff --git a/spec/bundler/support/indexes.rb b/spec/bundler/support/indexes.rb
index 29780014fc..638f394e76 100644
--- a/spec/bundler/support/indexes.rb
+++ b/spec/bundler/support/indexes.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Spec
module Indexes
def dep(name, reqs = nil)
@@ -16,12 +17,19 @@ module Spec
def resolve(args = [])
@platforms ||= ["ruby"]
deps = []
+ default_source = instance_double("Bundler::Source::Rubygems", :specs => @index, :to_s => "locally install gems")
+ source_requirements = { :default => default_source }
@deps.each do |d|
+ source_requirements[d.name] = d.source = default_source
@platforms.each do |p|
- deps << Bundler::DepProxy.new(d, p)
+ deps << Bundler::DepProxy.get_proxy(d, p)
end
end
- Bundler::Resolver.resolve(deps, @index, *args)
+ args[0] ||= [] # base
+ args[1] ||= Bundler::GemVersionPromoter.new # gem_version_promoter
+ args[2] ||= [] # additional_base_requirements
+ args[3] ||= @platforms # platforms
+ Bundler::Resolver.resolve(deps, source_requirements, *args)
end
def should_resolve_as(specs)
@@ -40,7 +48,7 @@ module Spec
def should_conflict_on(names)
got = resolve
- flunk "The resolve succeeded with: #{got.map(&:full_name).sort.inspect}"
+ raise "The resolve succeeded with: #{got.map(&:full_name).sort.inspect}"
rescue Bundler::VersionConflict => e
expect(Array(names).sort).to eq(e.conflicts.sort)
end
@@ -61,14 +69,18 @@ module Spec
search = Bundler::GemVersionPromoter.new(@locked, unlock).tap do |s|
s.level = opts.first
s.strict = opts.include?(:strict)
+ s.prerelease_specified = Hash[@deps.map {|d| [d.name, d.requirement.prerelease?] }]
end
- should_resolve_and_include specs, [{}, @base, search]
+ should_resolve_and_include specs, [@base, search]
end
def an_awesome_index
build_index do
- gem "rack", %w(0.8 0.9 0.9.1 0.9.2 1.0 1.1)
- gem "rack-mount", %w(0.4 0.5 0.5.1 0.5.2 0.6)
+ gem "rack", %w[0.8 0.9 0.9.1 0.9.2 1.0 1.1]
+ gem "rack-mount", %w[0.4 0.5 0.5.1 0.5.2 0.6]
+
+ # --- Pre-release support
+ gem "RubyGems\0", ["1.3.2"]
# --- Rails
versions "1.2.3 2.2.3 2.3.5 3.0.0.beta 3.0.0.beta1" do |version|
@@ -129,6 +141,14 @@ module Spec
dep "activesupport", ">= #{version}"
end
end
+
+ gem "reform", ["1.0.0"] do
+ dep "activesupport", ">= 1.0.0.beta1"
+ end
+
+ gem "need-pre", ["1.0.0"] do
+ dep "activesupport", "~> 3.0.0.beta1"
+ end
end
end
@@ -136,7 +156,7 @@ module Spec
# goes well, it should resolve to 3.0.4
def a_conflict_index
build_index do
- gem "builder", %w(3.0.4 3.1.4)
+ gem "builder", %w[3.0.4 3.1.4]
gem("grape", "0.2.6") do
dep "builder", ">= 0"
end
@@ -156,11 +176,11 @@ module Spec
def a_complex_conflict_index
build_index do
- gem("a", %w(1.0.2 1.1.4 1.2.0 1.4.0)) do
+ gem("a", %w[1.0.2 1.1.4 1.2.0 1.4.0]) do
dep "d", ">= 0"
end
- gem("d", %w(1.3.0 1.4.1)) do
+ gem("d", %w[1.3.0 1.4.1]) do
dep "x", ">= 0"
end
@@ -203,7 +223,7 @@ module Spec
def index_with_conflict_on_child
build_index do
- gem "json", %w(1.6.5 1.7.7 1.8.0)
+ gem "json", %w[1.6.5 1.7.7 1.8.0]
gem("chef", "10.26") do
dep "json", [">= 1.4.4", "<= 1.7.7"]
@@ -223,7 +243,7 @@ module Spec
# Issue #3459
def a_complicated_index
build_index do
- gem "foo", %w(3.0.0 3.0.5) do
+ gem "foo", %w[3.0.0 3.0.5] do
dep "qux", ["~> 3.1"]
dep "baz", ["< 9.0", ">= 5.0"]
dep "bar", ["~> 1.0"]
@@ -262,7 +282,7 @@ module Spec
dep "garply", [">= 0.3.1"]
end
- gem "grault", %w(2.6.3 3.1.1)
+ gem "grault", %w[2.6.3 3.1.1]
gem "garply", "0.5.1" do
dep "waldo", ["~> 0.1.3"]
@@ -272,7 +292,7 @@ module Spec
dep "plugh", ["~> 0.6.0"]
end
- gem "plugh", %w(0.6.3 0.6.11 0.7.0)
+ gem "plugh", %w[0.6.3 0.6.11 0.7.0]
gem "qux", "3.2.21" do
dep "plugh", [">= 0.6.4", "~> 0.6"]
@@ -285,7 +305,7 @@ module Spec
def a_unresovable_child_index
build_index do
- gem "json", %w(1.8.0)
+ gem "json", %w[1.8.0]
gem("chef", "10.26") do
dep "json", [">= 1.4.4", "<= 1.7.7"]
@@ -304,10 +324,10 @@ module Spec
def a_index_with_root_conflict_on_child
build_index do
- gem "builder", %w(2.1.2 3.0.1 3.1.3)
- gem "i18n", %w(0.4.1 0.4.2)
+ gem "builder", %w[2.1.2 3.0.1 3.1.3]
+ gem "i18n", %w[0.4.1 0.4.2]
- gem "activesupport", %w(3.0.0 3.0.1 3.0.5 3.1.7)
+ gem "activesupport", %w[3.0.0 3.0.1 3.0.5 3.1.7]
gem("activemodel", "3.0.5") do
dep "activesupport", "= 3.0.5"
@@ -361,5 +381,44 @@ module Spec
end
end
end
+
+ def an_ambiguous_index
+ build_index do
+ gem("a", "1.0.0") do
+ dep "c", ">= 0"
+ end
+
+ gem("b", %w[0.5.0 1.0.0])
+
+ gem("b", "2.0.0") do
+ dep "c", "< 2.0.0"
+ end
+
+ gem("c", "1.0.0") do
+ dep "d", "1.0.0"
+ end
+
+ gem("c", "2.0.0") do
+ dep "d", "2.0.0"
+ end
+
+ gem("d", %w[1.0.0 2.0.0])
+ end
+ end
+
+ def optional_prereleases_index
+ build_index do
+ gem("a", %w[1.0.0])
+
+ gem("a", "2.0.0") do
+ dep "b", ">= 2.0.0.pre"
+ end
+
+ gem("b", %w[0.9.0 1.5.0 2.0.0.pre])
+
+ # --- Pre-release support
+ gem "RubyGems\0", ["1.3.2"]
+ end
+ end
end
end
diff --git a/spec/bundler/support/less_than_proc.rb b/spec/bundler/support/less_than_proc.rb
deleted file mode 100644
index 27966aa6ed..0000000000
--- a/spec/bundler/support/less_than_proc.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-class LessThanProc < Proc
- attr_accessor :present
-
- def self.with(present)
- provided = Gem::Version.new(present.dup)
- new do |required|
- if required =~ /[=><~]/
- !Gem::Requirement.new(required).satisfied_by?(provided)
- else
- provided < Gem::Version.new(required)
- end
- end.tap {|l| l.present = present }
- end
-
- def inspect
- "\"=< #{present}\""
- end
-end
diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb
index 9248360639..3c2a7f9f58 100644
--- a/spec/bundler/support/matchers.rb
+++ b/spec/bundler/support/matchers.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
+
require "forwardable"
-require "support/the_bundle"
+require_relative "the_bundle"
+
module Spec
module Matchers
extend RSpec::Matchers
@@ -59,52 +61,39 @@ module Spec
end
end
- MAJOR_DEPRECATION = /^\[DEPRECATED FOR 2\.0\]\s*/
+ RSpec::Matchers.define :have_dep do |*args|
+ dep = Bundler::Dependency.new(*args)
- RSpec::Matchers.define :lack_errors do
- diffable
match do |actual|
- actual.gsub(/#{MAJOR_DEPRECATION}.+[\n]?/, "") == ""
+ actual.length == 1 && actual.all? {|d| d == dep }
end
end
- RSpec::Matchers.define :eq_err do |expected|
- diffable
+ RSpec::Matchers.define :have_gem do |*args|
match do |actual|
- actual.gsub(/#{MAJOR_DEPRECATION}.+[\n]?/, "") == expected
+ actual.length == args.length && actual.all? {|a| args.include?(a.full_name) }
end
end
- RSpec::Matchers.define :have_major_deprecation do |expected|
+ RSpec::Matchers.define :be_sorted do
diffable
+ attr_reader :expected
match do |actual|
- actual.split(MAJOR_DEPRECATION).any? do |d|
- !d.empty? && values_match?(expected, d.strip)
+ expected = block_arg ? actual.sort_by(&block_arg) : actual.sort
+ actual.==(expected).tap do
+ # HACK: since rspec won't show a diff when everything is a string
+ differ = RSpec::Support::Differ.new
+ @actual = differ.send(:object_to_string, actual)
+ @expected = differ.send(:object_to_string, expected)
end
end
end
- RSpec::Matchers.define :have_dep do |*args|
- dep = Bundler::Dependency.new(*args)
+ RSpec::Matchers.define :be_well_formed do
+ match(&:empty?)
- match do |actual|
- actual.length == 1 && actual.all? {|d| d == dep }
- end
- end
-
- RSpec::Matchers.define :have_gem do |*args|
- match do |actual|
- actual.length == args.length && actual.all? {|a| args.include?(a.full_name) }
- end
- end
-
- RSpec::Matchers.define :have_rubyopts do |*args|
- args = args.flatten
- args = args.first.split(/\s+/) if args.size == 1
-
- match do |actual|
- actual = actual.split(/\s+/) if actual.is_a?(String)
- args.all? {|arg| actual.include?(arg) } && actual.uniq.size == actual.size
+ failure_message do |actual|
+ actual.join("\n")
end
end
@@ -125,35 +114,49 @@ module Spec
match do
opts = names.last.is_a?(Hash) ? names.pop : {}
source = opts.delete(:source)
- groups = Array(opts[:groups])
- groups << opts
- @errors = names.map do |name|
- name, version, platform = name.split(/\s+/)
+ groups = Array(opts.delete(:groups)).map(&:inspect).join(", ")
+ opts[:raise_on_error] = false
+ @errors = names.map do |full_name|
+ name, version, platform = full_name.split(/\s+/)
+ require_path = name.tr("-", "/")
version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name)
- begin
- run! "require '#{name}.rb'; puts #{version_const}", *groups
- rescue => e
- next "#{name} is not installed:\n#{indent(e)}"
- end
- out.gsub!(/#{MAJOR_DEPRECATION}.*$/, "")
- actual_version, actual_platform = out.strip.split(/\s+/, 2)
- unless Gem::Version.new(actual_version) == Gem::Version.new(version)
+ source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
+ ruby <<~R, opts
+ require 'bundler'
+ Bundler.setup(#{groups})
+
+ require '#{require_path}'
+ actual_version, actual_platform = #{version_const}.split(/\s+/, 2)
+ unless Gem::Version.new(actual_version) == Gem::Version.new('#{version}')
+ puts actual_version
+ exit 64
+ end
+ unless actual_platform.to_s == '#{platform}'
+ puts actual_platform
+ exit 65
+ end
+ require '#{require_path}/source'
+ exit 0 if #{source.nil?}
+ actual_source = #{source_const}
+ unless actual_source == '#{source}'
+ puts actual_source
+ exit 66
+ end
+ R
+ next if exitstatus == 0
+ if exitstatus == 64
+ actual_version = out.split("\n").last
next "#{name} was expected to be at version #{version} but was #{actual_version}"
end
- unless actual_platform == platform
+ if exitstatus == 65
+ actual_platform = out.split("\n").last
next "#{name} was expected to be of platform #{platform} but was #{actual_platform}"
end
- next unless source
- begin
- source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
- run! "require '#{name}/source'; puts #{source_const}", *groups
- rescue
- next "#{name} does not have a source defined:\n#{indent(e)}"
- end
- out.gsub!(/#{MAJOR_DEPRECATION}.*$/, "")
- unless out.strip == source
- next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{out}`"
+ if exitstatus == 66
+ actual_source = out.split("\n").last
+ next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{actual_source}`"
end
+ next "Command to check for inclusion of gem #{full_name} failed"
end.compact
@errors.empty?
@@ -161,26 +164,34 @@ module Spec
match_when_negated do
opts = names.last.is_a?(Hash) ? names.pop : {}
- groups = Array(opts[:groups]) || []
+ groups = Array(opts.delete(:groups)).map(&:inspect).join(", ")
+ opts[:raise_on_error] = false
@errors = names.map do |name|
name, version = name.split(/\s+/, 2)
- begin
- run <<-R, *(groups + [opts])
- begin
- require '#{name}'
- puts #{Spec::Builders.constantize(name)}
- rescue LoadError, NameError
- puts "WIN"
+ ruby <<-R, opts
+ begin
+ require 'bundler'
+ Bundler.setup(#{groups})
+ rescue Bundler::GemNotFound, Bundler::GitError
+ exit 0
+ end
+
+ begin
+ require '#{name}'
+ name_constant = '#{Spec::Builders.constantize(name)}'
+ if #{version.nil?} || name_constant == '#{version}'
+ exit 64
+ else
+ exit 0
end
- R
- rescue => e
- next "checking for #{name} failed:\n#{e}"
- end
- next if out == "WIN"
+ rescue LoadError, NameError
+ exit 0
+ end
+ R
+ next if exitstatus == 0
+ next "command to check version of #{name} installed failed" unless exitstatus == 64
next "expected #{name} to not be installed, but it was" if version.nil?
- if Gem::Version.new(out) == Gem::Version.new(version)
- next "expected #{name} (#{version}) not to be installed, but it was"
- end
+ next "expected #{name} (#{version}) not to be installed, but it was"
end.compact
@errors.empty?
@@ -197,10 +208,6 @@ module Spec
RSpec::Matchers.define_negated_matcher :not_include_gems, :include_gems
RSpec::Matchers.alias_matcher :include_gem, :include_gems
- def have_lockfile(expected)
- read_as(strip_whitespace(expected))
- end
-
def plugin_should_be_installed(*names)
names.each do |name|
expect(Bundler::Plugin).to be_installed(name)
@@ -214,9 +221,5 @@ module Spec
expect(Bundler::Plugin).not_to be_installed(name)
end
end
-
- def lockfile_should_be(expected)
- expect(bundled_app("Gemfile.lock")).to read_as(strip_whitespace(expected))
- end
end
end
diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb
index b58658e71a..a73b3e699e 100644
--- a/spec/bundler/support/path.rb
+++ b/spec/bundler/support/path.rb
@@ -1,27 +1,109 @@
# frozen_string_literal: true
+
require "pathname"
+require "rbconfig"
module Spec
module Path
+ def source_root
+ @source_root ||= Pathname.new(ruby_core? ? "../../.." : "../..").expand_path(__dir__)
+ end
+
def root
- @root ||=
- Pathname.new(for_ruby_core? ? "../../../.." : "../../..").expand_path(__FILE__)
+ @root ||= system_gem_path("gems/bundler-#{Bundler::VERSION}")
end
def gemspec
- @gemspec ||= root.join(for_ruby_core? ? "lib/bundler.gemspec" : "bundler.gemspec")
+ @gemspec ||= source_root.join(relative_gemspec)
+ end
+
+ def relative_gemspec
+ @relative_gemspec ||= ruby_core? ? "lib/bundler/bundler.gemspec" : "bundler.gemspec"
+ end
+
+ def gemspec_dir
+ @gemspec_dir ||= gemspec.parent
+ end
+
+ def loaded_gemspec
+ @loaded_gemspec ||= Gem::Specification.load(gemspec.to_s)
+ end
+
+ def test_gemfile
+ @test_gemfile ||= source_root.join("tool/bundler/test_gems.rb")
+ end
+
+ def rubocop_gemfile
+ @rubocop_gemfile ||= source_root.join(rubocop_gemfile_basename)
+ end
+
+ def standard_gemfile
+ @standard_gemfile ||= source_root.join(standard_gemfile_basename)
+ end
+
+ def dev_gemfile
+ @dev_gemfile ||= git_root.join("dev_gems.rb")
end
def bindir
- @bindir ||= root.join(for_ruby_core? ? "bin" : "exe")
+ @bindir ||= source_root.join(ruby_core? ? "libexec" : "exe")
+ end
+
+ def installed_bindir
+ @installed_bindir ||= system_gem_path("bin")
+ end
+
+ def gem_cmd
+ @gem_cmd ||= ruby_core? ? source_root.join("bin/gem") : "gem"
+ end
+
+ def gem_bin
+ @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "gem"
+ end
+
+ def path
+ env_path = ENV["PATH"]
+ env_path = env_path.split(File::PATH_SEPARATOR).reject {|path| path == bindir.to_s }.join(File::PATH_SEPARATOR) if ruby_core?
+ env_path
end
def spec_dir
- @spec_dir ||= root.join(for_ruby_core? ? "spec/bundler" : "spec")
+ @spec_dir ||= source_root.join(ruby_core? ? "spec/bundler" : "spec")
+ end
+
+ def api_request_limit_hack_file
+ spec_dir.join("support/api_request_limit_hax.rb")
+ end
+
+ def man_dir
+ @man_dir ||= lib_dir.join("bundler/man")
+ end
+
+ def tracked_files
+ @tracked_files ||= git_ls_files(tracked_files_glob)
+ end
+
+ def shipped_files
+ @shipped_files ||= loaded_gemspec.files
+ end
+
+ def lib_tracked_files
+ @lib_tracked_files ||= git_ls_files(lib_tracked_files_glob)
+ end
+
+ def man_tracked_files
+ @man_tracked_files ||= git_ls_files(man_tracked_files_glob)
end
def tmp(*path)
- root.join("tmp", *path)
+ source_root.join("tmp", scope, *path)
+ end
+
+ def scope
+ test_number = ENV["TEST_ENV_NUMBER"]
+ return "1" if test_number.nil?
+
+ test_number.empty? ? "1" : test_number
end
def home(*path)
@@ -29,7 +111,11 @@ module Spec
end
def default_bundle_path(*path)
- system_gem_path(*path)
+ if Bundler.feature_flag.default_install_uses_path?
+ local_gem_path(*path)
+ else
+ system_gem_path(*path)
+ end
end
def bundled_app(*path)
@@ -38,8 +124,6 @@ module Spec
root.join(*path)
end
- alias_method :bundled_app1, :bundled_app
-
def bundled_app2(*path)
root = tmp.join("bundled_app2")
FileUtils.mkdir_p(root)
@@ -47,17 +131,40 @@ module Spec
end
def vendored_gems(path = nil)
- bundled_app(*["vendor/bundle", Gem.ruby_engine, Gem::ConfigMap[:ruby_version], path].compact)
+ scoped_gem_path(bundled_app("vendor/bundle")).join(*[path].compact)
end
def cached_gem(path)
bundled_app("vendor/cache/#{path}.gem")
end
+ def bundled_app_gemfile
+ bundled_app("Gemfile")
+ end
+
+ def bundled_app_lock
+ bundled_app("Gemfile.lock")
+ end
+
def base_system_gems
tmp.join("gems/base")
end
+ def rubocop_gems
+ tmp.join("gems/rubocop")
+ end
+
+ def standard_gems
+ tmp.join("gems/standard")
+ end
+
+ def file_uri_for(path)
+ protocol = "file://"
+ root = Gem.win_platform? ? "/" : ""
+
+ protocol + root + path.to_s
+ end
+
def gem_repo1(*args)
tmp("gems/remote1", *args)
end
@@ -86,12 +193,35 @@ module Spec
tmp("gems/system", *path)
end
+ def pristine_system_gem_path
+ tmp("gems/base_system")
+ end
+
+ def local_gem_path(*path, base: bundled_app)
+ scoped_gem_path(base.join(".bundle")).join(*path)
+ end
+
+ def scoped_gem_path(base)
+ base.join(Gem.ruby_engine, RbConfig::CONFIG["ruby_version"])
+ end
+
def lib_path(*args)
tmp("libs", *args)
end
- def bundler_path
- Pathname.new(File.expand_path(root.join("lib"), __FILE__))
+ def source_lib_dir
+ source_root.join("lib")
+ end
+
+ def lib_dir
+ root.join("lib")
+ end
+
+ # Sometimes rubygems version under test does not include
+ # https://github.com/rubygems/rubygems/pull/2728 and will not always end up
+ # activating the current bundler. In that case, require bundler absolutely.
+ def entrypoint
+ Gem.rubygems_version < Gem::Version.new("3.1.a") ? "#{lib_dir}/bundler" : "bundler"
end
def global_plugin_gem(*args)
@@ -106,15 +236,74 @@ module Spec
tmp "tmpdir", *args
end
- extend self
+ def replace_version_file(version, dir: source_root)
+ version_file = File.expand_path("lib/bundler/version.rb", dir)
+ contents = File.read(version_file)
+ contents.sub!(/(^\s+VERSION\s*=\s*)"#{Gem::Version::VERSION_PATTERN}"/, %(\\1"#{version}"))
+ File.open(version_file, "w") {|f| f << contents }
+ end
+
+ def ruby_core?
+ # avoid to warnings
+ @ruby_core ||= nil
+
+ if @ruby_core.nil?
+ @ruby_core = true & ENV["GEM_COMMAND"]
+ else
+ @ruby_core
+ end
+ end
private
- def for_ruby_core?
- if @for_ruby_core.nil?
- @for_ruby_core = true & (ENV["BUNDLE_RUBY"] && ENV["BUNDLE_GEM"])
+
+ def git_ls_files(glob)
+ skip "Not running on a git context, since running tests from a tarball" if ruby_core_tarball?
+
+ sys_exec("git ls-files -z -- #{glob}", :dir => source_root).split("\x0")
+ end
+
+ def tracked_files_glob
+ ruby_core? ? "lib/bundler lib/bundler.rb spec/bundler man/bundle*" : ""
+ end
+
+ def lib_tracked_files_glob
+ ruby_core? ? "lib/bundler lib/bundler.rb" : "lib"
+ end
+
+ def man_tracked_files_glob
+ ruby_core? ? "man/bundle* man/gemfile*" : "lib/bundler/man/bundle*.1 lib/bundler/man/gemfile*.5"
+ end
+
+ def git_root
+ ruby_core? ? source_root : source_root.parent
+ end
+
+ def ruby_core_tarball?
+ !git_root.join(".git").directory?
+ end
+
+ def rubocop_gemfile_basename
+ filename = if RUBY_VERSION.start_with?("2.3")
+ "rubocop23_gems"
+ elsif RUBY_VERSION.start_with?("2.4")
+ "rubocop24_gems"
else
- @for_ruby_core
+ "rubocop_gems"
end
+ source_root.join("tool/bundler/#{filename}.rb")
end
+
+ def standard_gemfile_basename
+ filename = if RUBY_VERSION.start_with?("2.3")
+ "standard23_gems"
+ elsif RUBY_VERSION.start_with?("2.4")
+ "standard24_gems"
+ else
+ "standard_gems"
+ end
+ source_root.join("tool/bundler/#{filename}.rb")
+ end
+
+ extend self
end
end
diff --git a/spec/bundler/support/permissions.rb b/spec/bundler/support/permissions.rb
index f5636dd70a..b21ce3848d 100644
--- a/spec/bundler/support/permissions.rb
+++ b/spec/bundler/support/permissions.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Spec
module Permissions
def with_umask(new_umask)
diff --git a/spec/bundler/support/platforms.rb b/spec/bundler/support/platforms.rb
index a2a3afba00..07973fd727 100644
--- a/spec/bundler/support/platforms.rb
+++ b/spec/bundler/support/platforms.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Spec
module Platforms
include Bundler::GemHelpers
@@ -43,6 +44,10 @@ module Spec
generic_local_platform
end
+ def specific_local_platform
+ Bundler.local_platform
+ end
+
def not_local
all_platforms.find {|p| p != generic_local_platform }
end
@@ -60,22 +65,11 @@ module Spec
end
def local_ruby_engine
- ENV["BUNDLER_SPEC_RUBY_ENGINE"] || (defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby")
+ RUBY_ENGINE
end
def local_engine_version
- return ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"] if ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"]
-
- case local_ruby_engine
- when "ruby"
- RUBY_VERSION
- when "rbx"
- Rubinius::VERSION
- when "jruby"
- JRUBY_VERSION
- else
- raise BundlerError, "That RUBY_ENGINE is not recognized"
- end
+ RUBY_ENGINE_VERSION
end
def not_local_engine_version
@@ -94,5 +88,17 @@ module Spec
def not_local_patchlevel
9999
end
+
+ def lockfile_platforms
+ lockfile_platforms_for(local_platforms)
+ end
+
+ def lockfile_platforms_for(platforms)
+ platforms.map(&:to_s).sort.join("\n ")
+ end
+
+ def local_platforms
+ [specific_local_platform]
+ end
end
end
diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb
index 596e1530d2..f957440ab0 100644
--- a/spec/bundler/support/rubygems_ext.rb
+++ b/spec/bundler/support/rubygems_ext.rb
@@ -1,64 +1,138 @@
# frozen_string_literal: true
-require "rubygems/user_interaction"
-require "support/path" unless defined?(Spec::Path)
+
+require_relative "path"
+
+$LOAD_PATH.unshift(Spec::Path.source_lib_dir.to_s)
module Spec
module Rubygems
- DEPS = begin
- deps = {
- # rack 2.x requires Ruby version >= 2.2.2.
- # artifice doesn't support rack 2.x now.
- "rack" => "< 2",
- # rack-test 0.7.0 dropped 1.8.7 support
- # https://github.com/rack-test/rack-test/issues/193#issuecomment-314230318
- "rack-test" => "< 0.7.0",
- "artifice" => "~> 0.6.0",
- "compact_index" => "~> 0.11.0",
- "sinatra" => "~> 1.4.7",
- # Rake version has to be consistent for tests to pass
- "rake" => "10.0.2",
- # 3.0.0 breaks 1.9.2 specs
- "builder" => "2.1.2",
- "bundler" => "1.12.0",
- }
- # ruby-graphviz is used by the viz tests
- deps["ruby-graphviz"] = nil if RUBY_VERSION >= "1.9.3"
- deps
- end
-
- def self.setup
+ extend self
+
+ def dev_setup
+ install_gems(dev_gemfile)
+ end
+
+ def gem_load(gem_name, bin_container)
+ require_relative "switch_rubygems"
+
+ gem_load_and_activate(gem_name, bin_container)
+ end
+
+ def gem_require(gem_name)
+ gem_activate(gem_name)
+ require gem_name
+ end
+
+ def test_setup
+ setup_test_paths
+
+ require "fileutils"
+
+ FileUtils.mkdir_p(Path.home)
+ FileUtils.mkdir_p(Path.tmpdir)
+
+ ENV["HOME"] = Path.home.to_s
+ ENV["TMPDIR"] = Path.tmpdir.to_s
+
+ require "rubygems/user_interaction"
+ Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
+ end
+
+ def install_parallel_test_deps
+ Gem.clear_paths
+
+ require "parallel"
+ require "fileutils"
+
+ install_test_deps
+
+ (2..Parallel.processor_count).each do |n|
+ source = Path.source_root.join("tmp", "1")
+ destination = Path.source_root.join("tmp", n.to_s)
+
+ FileUtils.rm_rf destination
+ FileUtils.cp_r source, destination
+ end
+ end
+
+ def setup_test_paths
Gem.clear_paths
ENV["BUNDLE_PATH"] = nil
ENV["GEM_HOME"] = ENV["GEM_PATH"] = Path.base_system_gems.to_s
- ENV["PATH"] = [Path.bindir, "#{Path.system_gem_path}/bin", ENV["PATH"]].join(File::PATH_SEPARATOR)
-
- manifest = DEPS.to_a.sort_by(&:first).map {|k, v| "#{k} => #{v}\n" }
- manifest_path = "#{Path.base_system_gems}/manifest.txt"
- # it's OK if there are extra gems
- if !File.exist?(manifest_path) || !(manifest - File.readlines(manifest_path)).empty?
- FileUtils.rm_rf(Path.base_system_gems)
- FileUtils.mkdir_p(Path.base_system_gems)
- puts "installing gems for the tests to use..."
- install_gems(DEPS)
- File.open(manifest_path, "w") {|f| f << manifest.join }
+ ENV["PATH"] = [Path.system_gem_path.join("bin"), ENV["PATH"]].join(File::PATH_SEPARATOR)
+ ENV["PATH"] = [Path.bindir, ENV["PATH"]].join(File::PATH_SEPARATOR) if Path.ruby_core?
+ end
+
+ def install_test_deps
+ setup_test_paths
+
+ install_gems(test_gemfile)
+ install_gems(rubocop_gemfile, Path.rubocop_gems.to_s)
+ install_gems(standard_gemfile, Path.standard_gems.to_s)
+ end
+
+ private
+
+ def gem_load_and_activate(gem_name, bin_container)
+ gem_activate(gem_name)
+ load Gem.bin_path(gem_name, bin_container)
+ rescue Gem::LoadError => e
+ abort "We couldn't activate #{gem_name} (#{e.requirement}). Run `gem install #{gem_name}:'#{e.requirement}'`"
+ end
+
+ def gem_activate(gem_name)
+ require "bundler"
+ gem_requirement = Bundler::LockfileParser.new(File.read(dev_lockfile)).dependencies[gem_name]&.requirement
+ gem gem_name, gem_requirement
+ end
+
+ def install_gems(gemfile, path = nil)
+ old_gemfile = ENV["BUNDLE_GEMFILE"]
+ ENV["BUNDLE_GEMFILE"] = gemfile.to_s
+
+ if path
+ old_path = ENV["BUNDLE_PATH"]
+ ENV["BUNDLE_PATH"] = path
+ else
+ old_path__system = ENV["BUNDLE_PATH__SYSTEM"]
+ ENV["BUNDLE_PATH__SYSTEM"] = "true"
end
- ENV["HOME"] = Path.home.to_s
- ENV["TMPDIR"] = Path.tmpdir.to_s
+ output = `#{Gem.ruby} #{File.expand_path("support/bundle.rb", Path.spec_dir)} install`
+ raise "Error when installing gems in #{gemfile}: #{output}" unless $?.success?
+ ensure
+ if path
+ ENV["BUNDLE_PATH"] = old_path
+ else
+ ENV["BUNDLE_PATH__SYSTEM"] = old_path__system
+ end
- Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
+ ENV["BUNDLE_GEMFILE"] = old_gemfile
+ end
+
+ def test_gemfile
+ Path.test_gemfile
+ end
+
+ def rubocop_gemfile
+ Path.rubocop_gemfile
+ end
+
+ def standard_gemfile
+ Path.standard_gemfile
+ end
+
+ def dev_gemfile
+ Path.dev_gemfile
+ end
+
+ def dev_lockfile
+ lockfile_for(dev_gemfile)
end
- def self.install_gems(gems)
- reqs, no_reqs = gems.partition {|_, req| !req.nil? && !req.split(" ").empty? }
- reqs = reqs.sort_by {|name, _| name == "rack" ? 0 : 1 } # TODO: remove when we drop ruby 1.8.7 support
- no_reqs.map!(&:first)
- reqs.map! {|name, req| "'#{name}:#{req}'" }
- deps = reqs.concat(no_reqs).join(" ")
- cmd = "#{ENV['BUNDLE_GEM'] || 'gem'} install #{deps} --no-rdoc --no-ri --conservative"
- puts cmd
- system(cmd) || raise("Installing gems #{deps} for the tests to use failed!")
+ def lockfile_for(gemfile)
+ Pathname.new("#{gemfile.expand_path}.lock")
end
end
end
diff --git a/spec/bundler/support/rubygems_version_manager.rb b/spec/bundler/support/rubygems_version_manager.rb
new file mode 100644
index 0000000000..d1b1f8dd03
--- /dev/null
+++ b/spec/bundler/support/rubygems_version_manager.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+require "pathname"
+require_relative "helpers"
+require_relative "path"
+
+class RubygemsVersionManager
+ include Spec::Helpers
+ include Spec::Path
+
+ def initialize(source)
+ @source = source
+ end
+
+ def switch
+ return if use_system?
+
+ assert_system_features_not_loaded!
+
+ switch_local_copy_if_needed
+
+ reexec_if_needed
+ end
+
+ def assert_system_features_not_loaded!
+ at_exit do
+ rubylibdir = RbConfig::CONFIG["rubylibdir"]
+
+ rubygems_path = rubylibdir + "/rubygems"
+ rubygems_default_path = rubygems_path + "/defaults"
+
+ bundler_path = rubylibdir + "/bundler"
+ bundler_exemptions = Gem.rubygems_version < Gem::Version.new("3.2.0") ? [bundler_path + "/errors.rb"] : []
+
+ bad_loaded_features = $LOADED_FEATURES.select do |loaded_feature|
+ (loaded_feature.start_with?(rubygems_path) && !loaded_feature.start_with?(rubygems_default_path)) ||
+ (loaded_feature.start_with?(bundler_path) && !bundler_exemptions.any? {|bundler_exemption| loaded_feature.start_with?(bundler_exemption) })
+ end
+
+ errors = if bad_loaded_features.any?
+ all_commands_output + "the following features were incorrectly loaded:\n#{bad_loaded_features.join("\n")}"
+ end
+
+ raise errors if errors
+ end
+ end
+
+ private
+
+ def use_system?
+ @source.nil?
+ end
+
+ def reexec_if_needed
+ return unless rubygems_unrequire_needed?
+
+ require "rbconfig"
+
+ cmd = [RbConfig.ruby, $0, *ARGV].compact
+
+ ENV["RUBYOPT"] = opt_add("-I#{local_copy_path.join("lib")}", opt_remove("--disable-gems", ENV["RUBYOPT"]))
+
+ exec(ENV, *cmd)
+ end
+
+ def switch_local_copy_if_needed
+ return unless local_copy_switch_needed?
+
+ sys_exec("git checkout #{target_tag}", :dir => local_copy_path)
+
+ ENV["RGV"] = local_copy_path.to_s
+ end
+
+ def rubygems_unrequire_needed?
+ require "rubygems"
+ !$LOADED_FEATURES.include?(local_copy_path.join("lib/rubygems.rb").to_s)
+ end
+
+ def local_copy_switch_needed?
+ !source_is_path? && target_tag != local_copy_tag
+ end
+
+ def target_tag
+ @target_tag ||= resolve_target_tag
+ end
+
+ def local_copy_tag
+ sys_exec("git rev-parse --abbrev-ref HEAD", :dir => local_copy_path)
+ end
+
+ def local_copy_path
+ @local_copy_path ||= resolve_local_copy_path
+ end
+
+ def resolve_local_copy_path
+ return expanded_source if source_is_path?
+
+ rubygems_path = source_root.join("tmp/rubygems")
+
+ unless rubygems_path.directory?
+ sys_exec("git clone .. #{rubygems_path}", :dir => source_root)
+ end
+
+ rubygems_path
+ end
+
+ def source_is_path?
+ expanded_source.directory?
+ end
+
+ def expanded_source
+ @expanded_source ||= Pathname.new(@source).expand_path(source_root)
+ end
+
+ def resolve_target_tag
+ return "v#{@source}" if @source.match(/^\d/)
+
+ @source
+ end
+end
diff --git a/spec/bundler/support/silent_logger.rb b/spec/bundler/support/silent_logger.rb
index 1a8f91b3ba..8665beb2c9 100644
--- a/spec/bundler/support/silent_logger.rb
+++ b/spec/bundler/support/silent_logger.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "logger"
module Spec
class SilentLogger
diff --git a/spec/bundler/support/sometimes.rb b/spec/bundler/support/sometimes.rb
deleted file mode 100644
index 6a50f5ff4c..0000000000
--- a/spec/bundler/support/sometimes.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-module Sometimes
- def run_with_retries(example_to_run, retries)
- example = RSpec.current_example
- example.metadata[:retries] ||= retries
-
- retries.times do |t|
- example.metadata[:retried] = t + 1
- example.instance_variable_set(:@exception, nil)
- example_to_run.run
- break unless example.exception
- end
-
- if e = example.exception
- new_exception = e.exception(e.message + "[Retried #{retries} times]")
- new_exception.set_backtrace e.backtrace
- example.instance_variable_set(:@exception, new_exception)
- end
- end
-end
-
-RSpec.configure do |config|
- config.include Sometimes
- config.alias_example_to :sometimes, :sometimes => true
- config.add_setting :sometimes_retry_count, :default => 5
-
- config.around(:each, :sometimes => true) do |example|
- retries = example.metadata[:retries] || RSpec.configuration.sometimes_retry_count
- run_with_retries(example, retries)
- end
-
- config.after(:suite) do
- message = proc do |color, text|
- colored = RSpec::Core::Formatters::ConsoleCodes.wrap(text, color)
- notification = RSpec::Core::Notifications::MessageNotification.new(colored)
- formatter = RSpec.configuration.formatters.first
- formatter.message(notification) if formatter.respond_to?(:message)
- end
-
- retried_examples = RSpec.world.example_groups.map do |g|
- g.descendants.map do |d|
- d.filtered_examples.select do |e|
- e.metadata[:sometimes] && e.metadata.fetch(:retried, 1) > 1
- end
- end
- end.flatten
-
- message.call(retried_examples.empty? ? :green : :yellow, "\n\nRetried examples: #{retried_examples.count}")
-
- retried_examples.each do |e|
- message.call(:cyan, " #{e.full_description}")
- path = RSpec::Core::Metadata.relative_path(e.location)
- message.call(:cyan, " [#{e.metadata[:retried]}/#{e.metadata[:retries]}] " + path)
- end
- end
-end
diff --git a/spec/bundler/support/streams.rb b/spec/bundler/support/streams.rb
index 561b29092b..a947eebf6f 100644
--- a/spec/bundler/support/streams.rb
+++ b/spec/bundler/support/streams.rb
@@ -1,14 +1,19 @@
# frozen_string_literal: true
+
require "stringio"
-def capture(*streams)
- streams.map!(&:to_s)
+def capture(*args)
+ opts = args.pop if args.last.is_a?(Hash)
+ opts ||= {}
+
+ args.map!(&:to_s)
begin
result = StringIO.new
- streams.each {|stream| eval "$#{stream} = result" }
+ result.close if opts[:closed]
+ args.each {|stream| eval "$#{stream} = result" }
yield
ensure
- streams.each {|stream| eval("$#{stream} = #{stream.upcase}") }
+ args.each {|stream| eval("$#{stream} = #{stream.upcase}") }
end
result.string
end
diff --git a/spec/bundler/support/sudo.rb b/spec/bundler/support/sudo.rb
index 8c82bb8c0f..04e9443945 100644
--- a/spec/bundler/support/sudo.rb
+++ b/spec/bundler/support/sudo.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Spec
module Sudo
def self.present?
diff --git a/spec/bundler/support/switch_rubygems.rb b/spec/bundler/support/switch_rubygems.rb
new file mode 100644
index 0000000000..a138d22333
--- /dev/null
+++ b/spec/bundler/support/switch_rubygems.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+require_relative "rubygems_version_manager"
+RubygemsVersionManager.new(ENV["RGV"]).switch
diff --git a/spec/bundler/support/the_bundle.rb b/spec/bundler/support/the_bundle.rb
index 742d393425..f252a4515b 100644
--- a/spec/bundler/support/the_bundle.rb
+++ b/spec/bundler/support/the_bundle.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
-require "support/helpers"
-require "support/path"
+
+require_relative "path"
module Spec
class TheBundle
- include Spec::Helpers
include Spec::Path
attr_accessor :bundle_dir
diff --git a/spec/bundler/update/gemfile_spec.rb b/spec/bundler/update/gemfile_spec.rb
new file mode 100644
index 0000000000..1c5294101e
--- /dev/null
+++ b/spec/bundler/update/gemfile_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle update" do
+ context "with --gemfile" do
+ it "finds the gemfile" do
+ gemfile bundled_app("NotGemfile"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+
+ bundle :install, :gemfile => bundled_app("NotGemfile")
+ bundle :update, :gemfile => bundled_app("NotGemfile"), :all => true
+
+ # Specify BUNDLE_GEMFILE for `the_bundle`
+ # to retrieve the proper Gemfile
+ ENV["BUNDLE_GEMFILE"] = "NotGemfile"
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+ end
+
+ context "with gemfile set via config" do
+ before do
+ gemfile bundled_app("NotGemfile"), <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+
+ bundle "config set --local gemfile #{bundled_app("NotGemfile")}"
+ bundle :install
+ end
+
+ it "uses the gemfile to update" do
+ bundle "update", :all => true
+ bundle "list"
+
+ expect(out).to include("rack (1.0.0)")
+ end
+
+ it "uses the gemfile while in a subdirectory" do
+ bundled_app("subdir").mkpath
+ bundle "update", :all => true, :dir => bundled_app("subdir")
+ bundle "list", :dir => bundled_app("subdir")
+
+ expect(out).to include("rack (1.0.0)")
+ end
+ end
+end
diff --git a/spec/bundler/update/gems/fund_spec.rb b/spec/bundler/update/gems/fund_spec.rb
new file mode 100644
index 0000000000..0dfe63d36d
--- /dev/null
+++ b/spec/bundler/update/gems/fund_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle update" do
+ before do
+ build_repo2 do
+ build_gem "has_funding_and_other_metadata" do |s|
+ s.metadata = {
+ "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
+ "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
+ "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
+ "homepage_uri" => "https://bestgemever.example.io",
+ "mailing_list_uri" => "https://groups.example.com/bestgemever",
+ "funding_uri" => "https://example.com/has_funding_and_other_metadata/funding",
+ "source_code_uri" => "https://example.com/user/bestgemever",
+ "wiki_uri" => "https://example.com/user/bestgemever/wiki",
+ }
+ end
+
+ build_gem "has_funding", "1.2.3" do |s|
+ s.metadata = {
+ "funding_uri" => "https://example.com/has_funding/funding",
+ }
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'has_funding_and_other_metadata'
+ gem 'has_funding', '< 2.0'
+ G
+
+ bundle :install
+ end
+
+ context "when listed gems are updated" do
+ before do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem 'has_funding_and_other_metadata'
+ gem 'has_funding'
+ G
+
+ bundle :update, :all => true
+ end
+
+ it "displays fund message" do
+ expect(out).to include("2 installed gems you directly depend on are looking for funding.")
+ end
+ end
+end
diff --git a/spec/bundler/update/gems/post_install_spec.rb b/spec/bundler/update/gems/post_install_spec.rb
index 5a4fe7f321..3aaa659d57 100644
--- a/spec/bundler/update/gems/post_install_spec.rb
+++ b/spec/bundler/update/gems/post_install_spec.rb
@@ -1,19 +1,18 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle update" do
let(:config) {}
before do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack', "< 1.0"
gem 'thin'
G
- bundle! "config #{config}" if config
+ bundle "config set #{config}" if config
- bundle! :install
+ bundle :install
end
shared_examples "a config observer" do
@@ -48,12 +47,12 @@ RSpec.describe "bundle update" do
context "when listed gem is updated" do
before do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack'
gem 'thin'
G
- bundle! :update
+ bundle :update, :all => true
end
it_behaves_like "a post-install message outputter"
@@ -63,12 +62,12 @@ RSpec.describe "bundle update" do
context "when dependency triggers update" do
before do
gemfile <<-G
- source "file://#{gem_repo1}"
+ source "#{file_uri_for(gem_repo1)}"
gem 'rack-obama'
gem 'thin'
G
- bundle! :update
+ bundle :update, :all => true
end
it_behaves_like "a post-install message outputter"
diff --git a/spec/bundler/update/git_spec.rb b/spec/bundler/update/git_spec.rb
index 021c8c942b..f02fb37d0f 100644
--- a/spec/bundler/update/git_spec.rb
+++ b/spec/bundler/update/git_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "bundle update" do
describe "git sources" do
@@ -8,16 +7,17 @@ RSpec.describe "bundle update" do
update_git "foo", :branch => "omg"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}", :branch => "omg" do
gem 'foo'
end
G
- update_git "foo", :branch => "omg" do |s|
+ update_git "foo" do |s|
s.write "lib/foo.rb", "FOO = '1.1'"
end
- bundle "update"
+ bundle "update", :all => true
expect(the_bundle).to include_gems "foo 1.1"
end
@@ -29,11 +29,11 @@ RSpec.describe "bundle update" do
end
install_gemfile <<-G
- gem "rails", :git => "#{lib_path("rails")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails", :git => "#{file_uri_for(lib_path("rails"))}"
G
bundle "update rails"
- expect(out).to include("Using activesupport 3.0 from #{lib_path("rails")} (at master@#{revision_for(lib_path("rails"))[0..6]})")
expect(the_bundle).to include_gems "rails 3.0", "activesupport 3.0"
end
@@ -42,12 +42,13 @@ RSpec.describe "bundle update" do
update_git "foo", :branch => "omg", :path => lib_path("foo")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo")}", :branch => "omg" do
gem 'foo'
end
G
- update_git "foo", :branch => "omg", :path => lib_path("foo") do |s|
+ update_git "foo", :path => lib_path("foo") do |s|
s.write "lib/foo.rb", "FOO = '1.1'"
end
@@ -58,12 +59,13 @@ RSpec.describe "bundle update" do
it "floats on master when updating all gems that are pinned to the source even if you have child dependencies" do
build_git "foo", :path => lib_path("foo")
- build_gem "bar", :to_system => true do |s|
+ build_gem "bar", :to_bundle => true do |s|
s.add_dependency "foo"
end
install_gemfile <<-G
- gem "foo", :git => "#{lib_path("foo")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo"))}"
gem "bar"
G
@@ -81,27 +83,30 @@ RSpec.describe "bundle update" do
build_git "foo", :path => lib_path("foo_two")
install_gemfile <<-G
- gem "foo", "1.0", :git => "#{lib_path("foo_one")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", "1.0", :git => "#{file_uri_for(lib_path("foo_one"))}"
G
FileUtils.rm_rf lib_path("foo_one")
install_gemfile <<-G
- gem "foo", "1.0", :git => "#{lib_path("foo_two")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", "1.0", :git => "#{file_uri_for(lib_path("foo_two"))}"
G
- expect(err).to lack_errors
- expect(out).to include("Fetching #{lib_path}/foo_two")
+ expect(err).to be_empty
+ expect(out).to include("Fetching #{file_uri_for(lib_path)}/foo_two")
expect(out).to include("Bundle complete!")
end
it "fetches tags from the remote" do
build_git "foo"
@remote = build_git("bar", :bare => true)
- update_git "foo", :remote => @remote.path
+ update_git "foo", :remote => file_uri_for(@remote.path)
update_git "foo", :push => "master"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => "#{@remote.path}"
G
@@ -110,17 +115,22 @@ RSpec.describe "bundle update" do
update_git "foo", :push => "fubar"
gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => "#{@remote.path}", :tag => "fubar"
G
- bundle "update"
- expect(exitstatus).to eq(0) if exitstatus
+ bundle "update", :all => true
end
describe "with submodules" do
before :each do
- build_gem "submodule", :to_system => true do |s|
- s.write "lib/submodule.rb", "puts 'GEM'"
+ # CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
+ system(*%W[git config --global protocol.file.allow always])
+
+ build_repo4 do
+ build_gem "submodule" do |s|
+ s.write "lib/submodule.rb", "puts 'GEM'"
+ end
end
build_git "submodule", "1.0" do |s|
@@ -131,14 +141,13 @@ RSpec.describe "bundle update" do
s.add_dependency "submodule"
end
- Dir.chdir(lib_path("has_submodule-1.0")) do
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0"
- `git commit -m "submodulator"`
- end
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
end
it "it unlocks the source when submodules are added to a git source" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
git "#{lib_path("has_submodule-1.0")}" do
gem "has_submodule"
end
@@ -148,6 +157,7 @@ RSpec.describe "bundle update" do
expect(out).to eq("GEM")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
git "#{lib_path("has_submodule-1.0")}", :submodules => true do
gem "has_submodule"
end
@@ -159,6 +169,7 @@ RSpec.describe "bundle update" do
it "unlocks the source when submodules are removed from git source", :git => ">= 2.9.0" do
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
git "#{lib_path("has_submodule-1.0")}", :submodules => true do
gem "has_submodule"
end
@@ -168,6 +179,7 @@ RSpec.describe "bundle update" do
expect(out).to eq("GIT")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
git "#{lib_path("has_submodule-1.0")}" do
gem "has_submodule"
end
@@ -182,13 +194,15 @@ RSpec.describe "bundle update" do
build_git "foo", "1.0"
install_gemfile <<-G
- gem "foo", :git => "#{lib_path("foo-1.0")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
lib_path("foo-1.0").join(".git").rmtree
- bundle :update
- expect(out).to include(lib_path("foo-1.0").to_s)
+ bundle :update, :all => true, :raise_on_error => false
+ expect(err).to include(lib_path("foo-1.0").to_s).
+ and match(/Git error: command `git fetch.+has failed/)
end
it "should not explode on invalid revision on update of gem by name" do
@@ -199,37 +213,27 @@ RSpec.describe "bundle update" do
end
install_gemfile <<-G
- source "file://#{gem_repo1}"
- gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", :git => "#{file_uri_for(lib_path("rack-0.8"))}", :branch => "master"
G
- bundle %(config local.rack #{lib_path("local-rack")})
+ bundle %(config set local.rack #{lib_path("local-rack")})
bundle "update rack"
expect(out).to include("Bundle updated!")
end
it "shows the previous version of the gem" do
- build_git "rails", "3.0", :path => lib_path("rails")
+ build_git "rails", "2.3.2", :path => lib_path("rails")
install_gemfile <<-G
- gem "rails", :git => "#{lib_path("rails")}"
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails", :git => "#{file_uri_for(lib_path("rails"))}"
G
- lockfile <<-G
- GIT
- remote: #{lib_path("rails")}
- specs:
- rails (2.3.2)
-
- PLATFORMS
- #{generic_local_platform}
-
- DEPENDENCIES
- rails!
- G
+ update_git "rails", "3.0", :path => lib_path("rails"), :gemspec => true
- bundle "update"
- expect(out).to include("Using rails 3.0 (was 2.3.2) from #{lib_path("rails")} (at master@#{revision_for(lib_path("rails"))[0..6]})")
+ bundle "update", :all => true
+ expect(out).to include("Using rails 3.0 (was 2.3.2) from #{file_uri_for(lib_path("rails"))} (at master@#{revision_for(lib_path("rails"))[0..6]})")
end
end
@@ -241,7 +245,7 @@ RSpec.describe "bundle update" do
end
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
git "#{lib_path("foo")}" do
gem 'foo'
end
@@ -254,14 +258,12 @@ RSpec.describe "bundle update" do
bundle "update --source foo"
- in_app_root do
- run <<-RUBY
- require 'foo'
- puts "WIN" if defined?(FOO_PREV_REF)
- RUBY
+ run <<-RUBY
+ require 'foo'
+ puts "WIN" if defined?(FOO_PREV_REF)
+ RUBY
- expect(out).to eq("WIN")
- end
+ expect(out).to eq("WIN")
end
it "unlocks gems that were originally pulled in by the source" do
@@ -286,7 +288,7 @@ RSpec.describe "bundle update" do
@git = build_git "foo", :path => lib_path("bar")
install_gemfile <<-G
- source "file://#{gem_repo2}"
+ source "#{file_uri_for(gem_repo2)}"
git "#{lib_path("bar")}" do
gem 'foo'
end
@@ -306,7 +308,7 @@ RSpec.describe "bundle update" do
bundle "update --source bar"
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{@git.path}
revision: #{ref}
@@ -314,12 +316,12 @@ RSpec.describe "bundle update" do
foo (2.0)
GEM
- remote: file:#{gem_repo2}/
+ remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- ruby
+ #{lockfile_platforms}
DEPENDENCIES
foo!
diff --git a/spec/bundler/update/path_spec.rb b/spec/bundler/update/path_spec.rb
index 5ac4f7b1fe..756770313b 100644
--- a/spec/bundler/update/path_spec.rb
+++ b/spec/bundler/update/path_spec.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require "spec_helper"
RSpec.describe "path sources" do
describe "bundle update --source" do
@@ -7,6 +6,7 @@ RSpec.describe "path sources" do
build_lib "activesupport", "2.3.5", :path => lib_path("rails/activesupport")
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "activesupport", :path => "#{lib_path("rails/activesupport")}"
G
diff --git a/spec/bundler/update/redownload_spec.rb b/spec/bundler/update/redownload_spec.rb
new file mode 100644
index 0000000000..147be823f5
--- /dev/null
+++ b/spec/bundler/update/redownload_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle update" do
+ before :each do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+ end
+
+ describe "with --force" do
+ it "shows a deprecation when single flag passed", :bundler => 2 do
+ bundle "update rack --force"
+ expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+
+ it "shows a deprecation when multiple flags passed", :bundler => 2 do
+ bundle "update rack --no-color --force"
+ expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+ end
+
+ describe "with --redownload" do
+ it "does not show a deprecation when single flag passed" do
+ bundle "update rack --redownload"
+ expect(err).not_to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+
+ it "does not show a deprecation when single multiple flags passed" do
+ bundle "update rack --no-color --redownload"
+ expect(err).not_to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
+ end
+ end
+end
diff --git a/spec/mspec/.gitignore b/spec/mspec/.gitignore
deleted file mode 100644
index 5c5ecd9731..0000000000
--- a/spec/mspec/.gitignore
+++ /dev/null
@@ -1,26 +0,0 @@
-pkg
-*.rbc
-*.iml
-*.iws
-*.ipr
-*.sw?
-
-.rbx
-
-# ctags dir
-/tags
-
-*.gem
-.bundle
-.config
-.yardoc
-InstalledFiles
-_yardoc
-coverage
-doc/
-lib/bundler/man
-rdoc
-spec/reports
-test/tmp
-test/version_tmp
-tmp
diff --git a/spec/mspec/.travis.yml b/spec/mspec/.travis.yml
deleted file mode 100644
index c710e536fc..0000000000
--- a/spec/mspec/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-sudo: false
-language: ruby
-before_script:
- # https://github.com/travis-ci/travis-ci/issues/8408
- - unset _JAVA_OPTIONS
-script:
- - bundle exec rspec
-matrix:
- include:
- - rvm: 2.2.7
- - rvm: 2.3.4
- - rvm: 2.4.1
- - rvm: ruby-head
- - jdk: oraclejdk8
- install:
- - curl -L https://github.com/graalvm/truffleruby/releases/download/vm-enterprise-0.27/truffleruby-testing-0.27.tar.gz | tar xz
- - source truffleruby/setup_env
- - bundle install
diff --git a/spec/mspec/Gemfile b/spec/mspec/Gemfile
index 3dc3c4145b..8e463cd71d 100644
--- a/spec/mspec/Gemfile
+++ b/spec/mspec/Gemfile
@@ -1,4 +1,4 @@
source 'https://rubygems.org'
-gem "rake", "~> 10.0"
+gem "rake", "~> 12.3"
gem "rspec", "~> 2.14.1"
diff --git a/spec/mspec/Gemfile.lock b/spec/mspec/Gemfile.lock
index d07c04638b..74489c5aca 100644
--- a/spec/mspec/Gemfile.lock
+++ b/spec/mspec/Gemfile.lock
@@ -1,8 +1,8 @@
GEM
remote: https://rubygems.org/
specs:
- diff-lcs (1.2.5)
- rake (10.4.2)
+ diff-lcs (1.3)
+ rake (12.3.3)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
@@ -17,8 +17,5 @@ PLATFORMS
ruby
DEPENDENCIES
- rake (~> 10.0)
+ rake (~> 12.3)
rspec (~> 2.14.1)
-
-BUNDLED WITH
- 1.14.5
diff --git a/spec/mspec/README.md b/spec/mspec/README.md
index 18ca8fcdd3..d4054bcf0f 100644
--- a/spec/mspec/README.md
+++ b/spec/mspec/README.md
@@ -1,14 +1,13 @@
-[![Build Status](https://travis-ci.org/ruby/mspec.svg?branch=master)](https://travis-ci.org/ruby/mspec)
-
## Overview
-MSpec is a specialized framework that is syntax-compatible with RSpec for
-basic things like 'describe', 'it' blocks and 'before', 'after' actions. MSpec
-contains additional features that assist in writing the RubySpecs used by
-multiple Ruby implementations.
+MSpec is a specialized framework that is syntax-compatible with RSpec 2 for
+basic things like `describe`, `it` blocks and `before`, `after` actions.
+MSpec contains additional features that assist in writing specs for
+Ruby implementations in [ruby/spec](https://github.com/ruby/spec).
MSpec attempts to use the simplest Ruby language features so that beginning
-Ruby implementations can run the Ruby specs.
+Ruby implementations can run the Ruby specs. For example, no file from the
+standard library or RubyGems is necessary to run MSpec.
MSpec is not intended as a replacement for RSpec. MSpec attempts to provide a
subset of RSpec's features in some cases and a superset in others. It does not
@@ -23,8 +22,6 @@ specs in a manner compatible with multiple Ruby implementations.
2. MSpec provides a different shared spec implementation specifically
designed to ease writing specs for the numerous aliased methods in Ruby.
- The MSpec shared spec implementation should not conflict with RSpec's own
- shared behavior facility.
3. MSpec provides various helper methods to simplify some specs, for
example, creating temporary file names.
@@ -33,9 +30,13 @@ specs in a manner compatible with multiple Ruby implementations.
configuration facility with a default project file and user-specific
overrides.
+ 5. MSpec support "tagging", that is excluding specs known as failing on
+ a particular Ruby implementation, and automatically adding and removing tags
+ while running the specs.
+
## Requirements
-MSpec requires Ruby 2.2 or more recent.
+MSpec requires Ruby 2.5 or more recent.
## Bundler
@@ -55,7 +56,7 @@ ruby -S bundle install
## Running Specs
Use RSpec to run the MSpec specs. There are no plans currently to make the
-MSpec specs runnable by MSpec.
+MSpec specs runnable by MSpec: https://github.com/ruby/mspec/issues/19.
After installing the gem dependencies, the specs can be run as follows:
@@ -63,29 +64,21 @@ After installing the gem dependencies, the specs can be run as follows:
ruby -S bundle exec rspec
```
-Or
-
-```bash
-ruby -S rake
-```
-
To run an individual spec file, use the following example:
```bash
ruby -S bundle exec rspec spec/helpers/ruby_exe_spec.rb
```
-
## Documentation
-See http://ruby.github.io/rubyspec.github.io/
-
+See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md) in ruby/spec
+for a list of matchers and how to use `mspec`.
## Source Code
See https://github.com/ruby/mspec
-
## License
See the LICENSE in the source code.
diff --git a/spec/mspec/Rakefile b/spec/mspec/Rakefile
index 0e294cde8e..6a9de7a95e 100644
--- a/spec/mspec/Rakefile
+++ b/spec/mspec/Rakefile
@@ -1,4 +1,3 @@
-require 'bundler/gem_tasks'
require 'bundler/setup'
require 'rspec/core/rake_task'
diff --git a/spec/mspec/lib/mspec.rb b/spec/mspec/lib/mspec.rb
index 42d590c99a..d24abd96f1 100644
--- a/spec/mspec/lib/mspec.rb
+++ b/spec/mspec/lib/mspec.rb
@@ -1,3 +1,4 @@
+require 'mspec/utils/format'
require 'mspec/matchers'
require 'mspec/expectations'
require 'mspec/mocks'
@@ -5,16 +6,3 @@ require 'mspec/runner'
require 'mspec/guards'
require 'mspec/helpers'
require 'mspec/version'
-
-# If the implementation on which the specs are run cannot
-# load pp from the standard library, add a pp.rb file that
-# defines the #pretty_inspect method on Object or Kernel.
-begin
- require 'pp'
-rescue LoadError
- module Kernel
- def pretty_inspect
- inspect
- end
- end
-end
diff --git a/spec/mspec/lib/mspec/commands/mkspec.rb b/spec/mspec/lib/mspec/commands/mkspec.rb
index 7a943aa1fe..d10cc35d18 100755
--- a/spec/mspec/lib/mspec/commands/mkspec.rb
+++ b/spec/mspec/lib/mspec/commands/mkspec.rb
@@ -19,7 +19,7 @@ class MkSpec
@map = NameMap.new true
end
- def options(argv=ARGV)
+ def options(argv = ARGV)
options = MSpecOptions.new "mkspec [options]", 32
options.on("-c", "--constant", "CONSTANT",
@@ -75,7 +75,7 @@ class MkSpec
parents = '../' * (sub.split('/').length + 1)
File.open(file, 'w') do |f|
- f.puts "require File.expand_path('../#{parents}spec_helper', __FILE__)"
+ f.puts "require_relative '#{parents}spec_helper'"
config[:requires].each do |lib|
f.puts "require '#{lib}'"
end
diff --git a/spec/mspec/lib/mspec/commands/mspec-ci.rb b/spec/mspec/lib/mspec/commands/mspec-ci.rb
index cb0193f42d..a31db1d7dc 100644
--- a/spec/mspec/lib/mspec/commands/mspec-ci.rb
+++ b/spec/mspec/lib/mspec/commands/mspec-ci.rb
@@ -8,7 +8,7 @@ require 'mspec/utils/script'
class MSpecCI < MSpecScript
- def options(argv=ARGV)
+ def options(argv = ARGV)
options = MSpecOptions.new "mspec ci [options] (FILE|DIRECTORY|GLOB)+", 30, config
options.doc " Ask yourself:"
@@ -24,6 +24,7 @@ class MSpecCI < MSpecScript
options.configure { |f| load f }
options.pretend
options.interrupt
+ options.timeout
options.doc "\n How to modify the guard behavior"
options.unguarded
diff --git a/spec/mspec/lib/mspec/commands/mspec-run.rb b/spec/mspec/lib/mspec/commands/mspec-run.rb
index 249f9f5771..4d8f4d9984 100644
--- a/spec/mspec/lib/mspec/commands/mspec-run.rb
+++ b/spec/mspec/lib/mspec/commands/mspec-run.rb
@@ -14,7 +14,7 @@ class MSpecRun < MSpecScript
config[:files] = []
end
- def options(argv=ARGV)
+ def options(argv = ARGV)
options = MSpecOptions.new "mspec run [options] (FILE|DIRECTORY|GLOB)+", 30, config
options.doc " Ask yourself:"
@@ -36,6 +36,7 @@ class MSpecRun < MSpecScript
options.repeat
options.pretend
options.interrupt
+ options.timeout
options.doc "\n How to modify the guard behavior"
options.unguarded
diff --git a/spec/mspec/lib/mspec/commands/mspec-tag.rb b/spec/mspec/lib/mspec/commands/mspec-tag.rb
index 8bc3382e91..e1d04d1446 100644
--- a/spec/mspec/lib/mspec/commands/mspec-tag.rb
+++ b/spec/mspec/lib/mspec/commands/mspec-tag.rb
@@ -15,7 +15,7 @@ class MSpecTag < MSpecScript
config[:ltags] = []
end
- def options(argv=ARGV)
+ def options(argv = ARGV)
options = MSpecOptions.new "mspec tag [options] (FILE|DIRECTORY|GLOB)+", 30, config
options.doc " Ask yourself:"
@@ -33,6 +33,7 @@ class MSpecTag < MSpecScript
options.pretend
options.unguarded
options.interrupt
+ options.timeout
options.doc "\n How to display their output"
options.formatters
diff --git a/spec/mspec/lib/mspec/commands/mspec.rb b/spec/mspec/lib/mspec/commands/mspec.rb
index cb1c0fbacb..9d82949ff1 100755
--- a/spec/mspec/lib/mspec/commands/mspec.rb
+++ b/spec/mspec/lib/mspec/commands/mspec.rb
@@ -21,7 +21,7 @@ class MSpecMain < MSpecScript
config[:launch] = []
end
- def options(argv=ARGV)
+ def options(argv = ARGV)
config[:command] = argv.shift if ["ci", "run", "tag"].include?(argv[0])
options = MSpecOptions.new "mspec [COMMAND] [options] (FILE|DIRECTORY|GLOB)+", 30, config
@@ -37,7 +37,7 @@ class MSpecMain < MSpecScript
options.targets
- options.on("--warnings", "Don't supress warnings") do
+ options.on("--warnings", "Don't suppress warnings") do
config[:flags] << '-w'
ENV['OUTPUT_WARNINGS'] = '1'
end
@@ -89,72 +89,12 @@ class MSpecMain < MSpecScript
def register; end
def multi_exec(argv)
- MSpec.register_files @files
-
require 'mspec/runner/formatters/multi'
- formatter = MultiFormatter.new
- if config[:formatter]
- warn "formatter options is ignored due to multi option"
- end
+ formatter = config_formatter.extend(MultiFormatter)
- output_files = []
+ require 'mspec/runner/parallel'
processes = cores(@files.size)
- children = processes.times.map { |i|
- name = tmp "mspec-multi-#{i}"
- output_files << name
-
- env = {
- "SPEC_TEMP_DIR" => "rubyspec_temp_#{i}",
- "MSPEC_MULTI" => i.to_s
- }
- command = argv + ["-fy", "-o", name]
- $stderr.puts "$ #{command.join(' ')}" if $MSPEC_DEBUG
- IO.popen([env, *command, close_others: false], "rb+")
- }
-
- puts children.map { |child| child.gets }.uniq
- formatter.start
- last_files = {}
-
- until @files.empty?
- IO.select(children)[0].each { |io|
- reply = io.read(1)
- case reply
- when '.'
- formatter.unload
- when nil
- raise "Worker died!"
- else
- while chunk = (io.read_nonblock(4096) rescue nil)
- reply += chunk
- end
- reply.chomp!('.')
- msg = "A child mspec-run process printed unexpected output on STDOUT"
- if last_file = last_files[io]
- msg += " while running #{last_file}"
- end
- abort "\n#{msg}: #{reply.inspect}"
- end
-
- unless @files.empty?
- file = @files.shift
- last_files[io] = file
- io.puts file
- end
- }
- end
-
- success = true
- children.each { |child|
- child.puts "QUIT"
- _pid, status = Process.wait2(child.pid)
- success &&= status.success?
- child.close
- }
-
- formatter.aggregate_results(output_files)
- formatter.finish
- success
+ ParallelRunner.new(@files, processes, formatter, argv).run
end
def run
@@ -171,6 +111,7 @@ class MSpecMain < MSpecScript
exit multi_exec(argv)
else
$stderr.puts "$ #{argv.join(' ')}"
+ $stderr.flush
exec(*argv, close_others: false)
end
end
diff --git a/spec/mspec/lib/mspec/expectations/expectations.rb b/spec/mspec/lib/mspec/expectations/expectations.rb
index cfdc2b63a3..8d01dc22ab 100644
--- a/spec/mspec/lib/mspec/expectations/expectations.rb
+++ b/spec/mspec/lib/mspec/expectations/expectations.rb
@@ -7,15 +7,29 @@ class SpecExpectationNotFoundError < StandardError
end
end
+class SkippedSpecError < StandardError
+end
+
class SpecExpectation
def self.fail_with(expected, actual)
expected_to_s = expected.to_s
actual_to_s = actual.to_s
if expected_to_s.size + actual_to_s.size > 80
- message = "#{expected_to_s.chomp}\n#{actual_to_s}"
+ message = "#{expected_to_s}\n#{actual_to_s}"
else
message = "#{expected_to_s} #{actual_to_s}"
end
- Kernel.raise SpecExpectationNotMetError, message
+ raise SpecExpectationNotMetError, message
+ end
+
+ def self.fail_predicate(receiver, predicate, args, block, result, expectation)
+ receiver_to_s = MSpec.format(receiver)
+ before_method = predicate.to_s =~ /^[a-z]/ ? "." : " "
+ predicate_to_s = "#{before_method}#{predicate}"
+ predicate_to_s += " " unless args.empty?
+ args_to_s = args.map { |arg| MSpec.format(arg) }.join(', ')
+ args_to_s += " { ... }" if block
+ result_to_s = MSpec.format(result)
+ raise SpecExpectationNotMetError, "Expected #{receiver_to_s}#{predicate_to_s}#{args_to_s}\n#{expectation} but was #{result_to_s}"
end
end
diff --git a/spec/mspec/lib/mspec/expectations/should.rb b/spec/mspec/lib/mspec/expectations/should.rb
index f6d83053f5..ca0617484c 100644
--- a/spec/mspec/lib/mspec/expectations/should.rb
+++ b/spec/mspec/lib/mspec/expectations/should.rb
@@ -3,27 +3,33 @@ class Object
def should(matcher = NO_MATCHER_GIVEN)
MSpec.expectation
- MSpec.actions :expectation, MSpec.current.state
- unless matcher.equal? NO_MATCHER_GIVEN
+ state = MSpec.current.state
+ raise "should outside example" unless state
+ MSpec.actions :expectation, state
+
+ if NO_MATCHER_GIVEN.equal?(matcher)
+ SpecPositiveOperatorMatcher.new(self)
+ else
unless matcher.matches? self
expected, actual = matcher.failure_message
SpecExpectation.fail_with(expected, actual)
end
- else
- SpecPositiveOperatorMatcher.new(self)
end
end
def should_not(matcher = NO_MATCHER_GIVEN)
MSpec.expectation
- MSpec.actions :expectation, MSpec.current.state
- unless matcher.equal? NO_MATCHER_GIVEN
+ state = MSpec.current.state
+ raise "should_not outside example" unless state
+ MSpec.actions :expectation, state
+
+ if NO_MATCHER_GIVEN.equal?(matcher)
+ SpecNegativeOperatorMatcher.new(self)
+ else
if matcher.matches? self
expected, actual = matcher.negative_failure_message
SpecExpectation.fail_with(expected, actual)
end
- else
- SpecNegativeOperatorMatcher.new(self)
end
end
end
diff --git a/spec/mspec/lib/mspec/guards/bug.rb b/spec/mspec/lib/mspec/guards/bug.rb
index b1bfc6413e..a6af0ef964 100644
--- a/spec/mspec/lib/mspec/guards/bug.rb
+++ b/spec/mspec/lib/mspec/guards/bug.rb
@@ -1,28 +1,29 @@
require 'mspec/guards/version'
class BugGuard < VersionGuard
- def initialize(bug, version)
+ def initialize(bug, requirement)
@bug = bug
- if String === version
+ if String === requirement
MSpec.deprecate "ruby_bug with a single version", 'an exclusive range ("2.1"..."2.3")'
- @version = SpecVersion.new version, true
+ super(FULL_RUBY_VERSION, requirement)
+ @requirement = SpecVersion.new requirement, true
else
- super(version)
+ super(FULL_RUBY_VERSION, requirement)
end
- @parameters = [@bug, @version]
end
def match?
return false if MSpec.mode? :no_ruby_bug
return false unless PlatformGuard.standard?
- if Range === @version
+
+ if Range === @requirement
super
else
- FULL_RUBY_VERSION <= @version
+ FULL_RUBY_VERSION <= @requirement
end
end
end
-def ruby_bug(bug, version, &block)
- BugGuard.new(bug, version).run_unless(:ruby_bug, &block)
+def ruby_bug(bug, requirement, &block)
+ BugGuard.new(bug, requirement).run_unless(:ruby_bug, &block)
end
diff --git a/spec/mspec/lib/mspec/guards/conflict.rb b/spec/mspec/lib/mspec/guards/conflict.rb
index 7a27671c1e..4930e5734d 100644
--- a/spec/mspec/lib/mspec/guards/conflict.rb
+++ b/spec/mspec/lib/mspec/guards/conflict.rb
@@ -1,6 +1,12 @@
require 'mspec/guards/guard'
+require 'mspec/utils/deprecate'
class ConflictsGuard < SpecGuard
+ def initialize(*args)
+ MSpec.deprecate 'conflicts_with', 'guard -> { condition } do'
+ super(*args)
+ end
+
def match?
# Always convert constants to symbols regardless of version.
constants = Object.constants.map { |x| x.to_sym }
diff --git a/spec/mspec/lib/mspec/guards/feature.rb b/spec/mspec/lib/mspec/guards/feature.rb
index 30984e0cc5..d4c6dd1cde 100644
--- a/spec/mspec/lib/mspec/guards/feature.rb
+++ b/spec/mspec/lib/mspec/guards/feature.rb
@@ -39,3 +39,7 @@ end
def with_feature(*features, &block)
FeatureGuard.new(*features).run_if(:with_feature, &block)
end
+
+def without_feature(*features, &block)
+ FeatureGuard.new(*features).run_unless(:without_feature, &block)
+end
diff --git a/spec/mspec/lib/mspec/guards/guard.rb b/spec/mspec/lib/mspec/guards/guard.rb
index 322a08145d..3a6372a660 100644
--- a/spec/mspec/lib/mspec/guards/guard.rb
+++ b/spec/mspec/lib/mspec/guards/guard.rb
@@ -111,7 +111,7 @@ class SpecGuard
def add(example)
record example.description
- MSpec.retrieve(:formatter).tally.counter.guards!
+ MSpec.formatter.tally.counter.guards!
end
def unregister
diff --git a/spec/mspec/lib/mspec/guards/platform.rb b/spec/mspec/lib/mspec/guards/platform.rb
index 96176b8753..2d5c2de6b6 100644
--- a/spec/mspec/lib/mspec/guards/platform.rb
+++ b/spec/mspec/lib/mspec/guards/platform.rb
@@ -6,10 +6,8 @@ class PlatformGuard < SpecGuard
case name
when :rubinius
RUBY_ENGINE.start_with?('rbx')
- when :ruby, :jruby, :truffleruby, :ironruby, :macruby, :maglev, :topaz, :opal
- RUBY_ENGINE.start_with?(name.to_s)
else
- raise "unknown implementation #{name}"
+ RUBY_ENGINE.start_with?(name.to_s)
end
end
end
@@ -18,20 +16,23 @@ class PlatformGuard < SpecGuard
implementation? :ruby
end
- HOST_OS = begin
+ PLATFORM = if RUBY_ENGINE == "jruby"
require 'rbconfig'
- RbConfig::CONFIG['host_os'] || RUBY_PLATFORM
- rescue LoadError
+ "#{RbConfig::CONFIG['host_cpu']}-#{RbConfig::CONFIG['host_os']}"
+ else
RUBY_PLATFORM
- end.downcase
+ end
def self.os?(*oses)
oses.any? do |os|
raise ":java is not a valid OS" if os == :java
- if os == :windows
- HOST_OS =~ /(mswin|mingw)/
+ case os
+ when :windows
+ PLATFORM =~ /(mswin|mingw)/
+ when :wsl
+ wsl?
else
- HOST_OS.include?(os.to_s)
+ PLATFORM.include?(os.to_s)
end
end
end
@@ -40,8 +41,29 @@ class PlatformGuard < SpecGuard
os?(:windows)
end
+ def self.wsl?
+ if defined?(@wsl_p)
+ @wsl_p
+ else
+ @wsl_p = `uname -r`.match?(/microsoft/i)
+ end
+ end
+
+ WORD_SIZE = 1.size * 8
+
+ POINTER_SIZE = begin
+ require 'rbconfig/sizeof'
+ RbConfig::SIZEOF["void*"] * 8
+ rescue LoadError
+ WORD_SIZE
+ end
+
def self.wordsize?(size)
- size == 8 * 1.size
+ size == WORD_SIZE
+ end
+
+ def self.pointer_size?(size)
+ size == POINTER_SIZE
end
def initialize(*args)
@@ -61,6 +83,8 @@ class PlatformGuard < SpecGuard
match &&= PlatformGuard.os?(*value)
when :wordsize
match &&= PlatformGuard.wordsize? value
+ when :pointer_size
+ match &&= PlatformGuard.pointer_size? value
end
end
match
diff --git a/spec/mspec/lib/mspec/guards/version.rb b/spec/mspec/lib/mspec/guards/version.rb
index cb08fdac73..20f8c06d38 100644
--- a/spec/mspec/lib/mspec/guards/version.rb
+++ b/spec/mspec/lib/mspec/guards/version.rb
@@ -5,33 +5,40 @@ require 'mspec/guards/guard'
class VersionGuard < SpecGuard
FULL_RUBY_VERSION = SpecVersion.new SpecGuard.ruby_version(:full)
- def initialize(version)
- case version
+ def initialize(version, requirement)
+ version = SpecVersion.new(version) unless SpecVersion === version
+ @version = version
+
+ case requirement
when String
- @version = SpecVersion.new version
+ @requirement = SpecVersion.new requirement
when Range
- MSpec.deprecate "an empty version range end", 'a specific version' if version.end.empty?
- a = SpecVersion.new version.begin
- b = SpecVersion.new version.end
- unless version.exclude_end?
+ MSpec.deprecate "an empty version range end", 'a specific version' if requirement.end.empty?
+ a = SpecVersion.new requirement.begin
+ b = SpecVersion.new requirement.end
+ unless requirement.exclude_end?
MSpec.deprecate "ruby_version_is with an inclusive range", 'an exclusive range ("2.1"..."2.3")'
end
- @version = version.exclude_end? ? a...b : a..b
+ @requirement = requirement.exclude_end? ? a...b : a..b
else
- raise "version must be a String or Range but was a #{version.class}"
+ raise "version must be a String or Range but was a #{requirement.class}"
end
- @parameters = [version]
+ super(@version, @requirement)
end
def match?
- if Range === @version
- @version.include? FULL_RUBY_VERSION
+ if Range === @requirement
+ @requirement.include? @version
else
- FULL_RUBY_VERSION >= @version
+ @version >= @requirement
end
end
end
-def ruby_version_is(*args, &block)
- VersionGuard.new(*args).run_if(:ruby_version_is, &block)
+def version_is(base_version, requirement, &block)
+ VersionGuard.new(base_version, requirement).run_if(:version_is, &block)
+end
+
+def ruby_version_is(requirement, &block)
+ VersionGuard.new(VersionGuard::FULL_RUBY_VERSION, requirement).run_if(:ruby_version_is, &block)
end
diff --git a/spec/mspec/lib/mspec/helpers/datetime.rb b/spec/mspec/lib/mspec/helpers/datetime.rb
index 1520b971ea..3a40cc0902 100644
--- a/spec/mspec/lib/mspec/helpers/datetime.rb
+++ b/spec/mspec/lib/mspec/helpers/datetime.rb
@@ -6,7 +6,7 @@
#
# Possible keys are:
# :year, :month, :day, :hour, :minute, :second, :offset and :sg.
-def new_datetime(opts={})
+def new_datetime(opts = {})
require 'date'
value = {
diff --git a/spec/mspec/lib/mspec/helpers/flunk.rb b/spec/mspec/lib/mspec/helpers/flunk.rb
index 68fb3cadac..84fb3ab39c 100644
--- a/spec/mspec/lib/mspec/helpers/flunk.rb
+++ b/spec/mspec/lib/mspec/helpers/flunk.rb
@@ -1,3 +1,3 @@
-def flunk(msg="This example is a failure")
+def flunk(msg = "This example is a failure")
SpecExpectation.fail_with "Failed:", msg
end
diff --git a/spec/mspec/lib/mspec/helpers/fs.rb b/spec/mspec/lib/mspec/helpers/fs.rb
index fb2c0f702c..67453eb302 100644
--- a/spec/mspec/lib/mspec/helpers/fs.rb
+++ b/spec/mspec/lib/mspec/helpers/fs.rb
@@ -1,12 +1,6 @@
# Copies a file
def cp(source, dest)
- File.open(dest, "wb") do |d|
- File.open(source, "rb") do |s|
- while data = s.read(1024)
- d.write data
- end
- end
- end
+ IO.copy_stream source, dest
end
# Creates each directory in path that does not exist.
@@ -61,7 +55,7 @@ end
# Creates a file +name+. Creates the directory for +name+
# if it does not exist.
-def touch(name, mode="w")
+def touch(name, mode = "w")
mkdir_p File.dirname(name)
File.open(name, mode) do |f|
diff --git a/spec/mspec/lib/mspec/helpers/io.rb b/spec/mspec/lib/mspec/helpers/io.rb
index 57dc0d53a4..29c6c37a1a 100644
--- a/spec/mspec/lib/mspec/helpers/io.rb
+++ b/spec/mspec/lib/mspec/helpers/io.rb
@@ -64,9 +64,7 @@ end
# Creates a "bare" file descriptor (i.e. one that is not associated
# with any Ruby object). The file descriptor can safely be passed
# to IO.new without creating a Ruby object alias to the fd.
-def new_fd(name, mode="w:utf-8")
- mode = options_or_mode(mode)
-
+def new_fd(name, mode = "w:utf-8")
if mode.kind_of? Hash
if mode.key? :mode
mode = mode[:mode]
@@ -75,37 +73,15 @@ def new_fd(name, mode="w:utf-8")
end
end
- IO.sysopen name, fmode(mode)
+ IO.sysopen name, mode
end
# Creates an IO instance for a temporary file name. The file
# must be deleted.
-def new_io(name, mode="w:utf-8")
- IO.new new_fd(name, options_or_mode(mode)), options_or_mode(mode)
-end
-
-# This helper simplifies passing file access modes regardless of
-# whether the :encoding feature is enabled. Only the access specifier
-# itself will be returned if :encoding is not enabled. Otherwise,
-# the full mode string will be returned (i.e. the helper is a no-op).
-def fmode(mode)
- if FeatureGuard.enabled? :encoding
- mode
- else
- mode.split(':').first
- end
-end
-
-# This helper simplifies passing file access modes or options regardless of
-# whether the :encoding feature is enabled. Only the access specifier itself
-# will be returned if :encoding is not enabled. Otherwise, the full mode
-# string or option will be returned (i.e. the helper is a no-op).
-def options_or_mode(oom)
- return fmode(oom) if oom.kind_of? String
-
- if FeatureGuard.enabled? :encoding
- oom
+def new_io(name, mode = "w:utf-8")
+ if Hash === mode # Avoid kwargs warnings on Ruby 2.7+
+ File.new(name, **mode)
else
- fmode(oom[:mode] || "r:utf-8")
+ File.new(name, mode)
end
end
diff --git a/spec/mspec/lib/mspec/helpers/numeric.rb b/spec/mspec/lib/mspec/helpers/numeric.rb
index 312aafae35..db1fde64d8 100644
--- a/spec/mspec/lib/mspec/helpers/numeric.rb
+++ b/spec/mspec/lib/mspec/helpers/numeric.rb
@@ -8,10 +8,18 @@ def infinity_value
1/0.0
end
-def bignum_value(plus=0)
+def bignum_value(plus = 0)
0x8000_0000_0000_0000 + plus
end
+def max_long
+ 2**(0.size * 8 - 1) - 1
+end
+
+def min_long
+ -(2**(0.size * 8 - 1))
+end
+
# This is a bit hairy, but we need to be able to write specs that cover the
# boundary between Fixnum and Bignum for operations like Fixnum#<<. Since
# this boundary is implementation-dependent, we use these helpers to write
diff --git a/spec/mspec/lib/mspec/helpers/ruby_exe.rb b/spec/mspec/lib/mspec/helpers/ruby_exe.rb
index f74ed014ce..075a8aaef5 100644
--- a/spec/mspec/lib/mspec/helpers/ruby_exe.rb
+++ b/spec/mspec/lib/mspec/helpers/ruby_exe.rb
@@ -2,11 +2,12 @@ require 'mspec/guards/platform'
require 'mspec/helpers/tmp'
# The ruby_exe helper provides a wrapper for invoking the
-# same Ruby interpreter with the same falgs as the one running
+# same Ruby interpreter with the same flags as the one running
# the specs and getting the output from running the code.
+#
# If +code+ is a file that exists, it will be run.
-# Otherwise, +code+ should be Ruby code that will be run with
-# the -e command line option. For example:
+# Otherwise, +code+ will be written to a temporary file and be run.
+# For example:
#
# ruby_exe('path/to/some/file.rb')
#
@@ -14,24 +15,16 @@ require 'mspec/helpers/tmp'
#
# `#{RUBY_EXE} 'path/to/some/file.rb'`
#
-# while
-#
-# ruby_exe('puts "hello, world."')
-#
-# will be executed as
-#
-# `#{RUBY_EXE} -e 'puts "hello, world."'`
-#
# The ruby_exe helper also accepts an options hash with three
# keys: :options, :args and :env. For example:
#
# ruby_exe('file.rb', :options => "-w",
-# :args => "> file.txt",
+# :args => "arg1 arg2",
# :env => { :FOO => "bar" })
#
# will be executed as
#
-# `#{RUBY_EXE} -w #{'file.rb'} > file.txt`
+# `#{RUBY_EXE} -w file.rb arg1 arg2`
#
# with access to ENV["FOO"] with value "bar".
#
@@ -49,33 +42,11 @@ require 'mspec/helpers/tmp'
# The RUBY_EXE constant is setup by mspec automatically
# and is used by ruby_exe and ruby_cmd. The mspec runner script
# will set ENV['RUBY_EXE'] to the name of the executable used
-# to invoke the mspec-run script. The value of RUBY_EXE will be
-# constructed as follows:
-#
-# 1. the value of ENV['RUBY_EXE']
-# 2. an explicit value based on RUBY_ENGINE
-# 3. cwd/(RUBY_ENGINE + $(EXEEXT) || $(exeext) || '')
-# 4. $(bindir)/$(RUBY_INSTALL_NAME)
+# to invoke the mspec-run script.
#
# The value will only be used if the file exists and is executable.
-# The flags will then be appended to the resulting value.
-#
-# These 4 ways correspond to the following scenarios:
-#
-# 1. Using the MSpec runner scripts, the name of the
-# executable is explicitly passed by ENV['RUBY_EXE']
-# so there is no ambiguity.
-#
-# Otherwise, if using RSpec (or something else)
-#
-# 2. Running the specs while developing an alternative
-# Ruby implementation. This explicitly names the
-# executable in the development directory based on
-# the value of RUBY_ENGINE.
-# 3. Running the specs within the source directory for
-# some implementation. (E.g. a local build directory.)
-# 4. Running the specs against some installed Ruby
-# implementation.
+# The flags will then be appended to the resulting value, such that
+# the RUBY_EXE constant contains both the executable and the flags.
#
# Additionally, the flags passed to mspec
# (with -T on the command line or in the config with set :flags)
@@ -101,12 +72,12 @@ def ruby_exe_options(option)
end
when :name
require 'rbconfig'
- bin = RUBY_ENGINE + (RbConfig::CONFIG['EXEEXT'] || RbConfig::CONFIG['exeext'] || '')
+ bin = RUBY_ENGINE + (RbConfig::CONFIG['EXEEXT'] || '')
File.join(".", bin)
when :install_name
require 'rbconfig'
bin = RbConfig::CONFIG["RUBY_INSTALL_NAME"] || RbConfig::CONFIG["ruby_install_name"]
- bin << (RbConfig::CONFIG['EXEEXT'] || RbConfig::CONFIG['exeext'] || '')
+ bin << (RbConfig::CONFIG['EXEEXT'] || '')
File.join(RbConfig::CONFIG['bindir'], bin)
end
end
@@ -129,6 +100,10 @@ def resolve_ruby_exe
raise Exception, "Unable to find a suitable ruby executable."
end
+unless Object.const_defined?(:RUBY_EXE) and RUBY_EXE
+ RUBY_EXE = resolve_ruby_exe
+end
+
def ruby_exe(code = :not_given, opts = {})
if opts[:dir]
raise "ruby_exe(..., dir: dir) is no longer supported, use Dir.chdir"
@@ -178,9 +153,7 @@ def ruby_cmd(code, opts = {})
body = "-e #{code.inspect}"
end
- [RUBY_EXE, opts[:options], body, opts[:args]].compact.join(' ')
-end
-
-unless Object.const_defined?(:RUBY_EXE) and RUBY_EXE
- RUBY_EXE = resolve_ruby_exe
+ command = [RUBY_EXE, opts[:options], body, opts[:args]].compact.join(' ')
+ STDERR.puts "\nruby_cmd: #{command}" if ENV["DEBUG_MSPEC_RUBY_CMD"] == "true"
+ command
end
diff --git a/spec/mspec/lib/mspec/helpers/scratch.rb b/spec/mspec/lib/mspec/helpers/scratch.rb
index a6b0c02748..0da3315cd8 100644
--- a/spec/mspec/lib/mspec/helpers/scratch.rb
+++ b/spec/mspec/lib/mspec/helpers/scratch.rb
@@ -14,4 +14,8 @@ module ScratchPad
def self.recorded
@record
end
+
+ def self.inspect
+ "<ScratchPad @record=#{@record.inspect}>"
+ end
end
diff --git a/spec/mspec/lib/mspec/helpers/tmp.rb b/spec/mspec/lib/mspec/helpers/tmp.rb
index 4e1273dcfe..b2a38ee983 100644
--- a/spec/mspec/lib/mspec/helpers/tmp.rb
+++ b/spec/mspec/lib/mspec/helpers/tmp.rb
@@ -3,11 +3,16 @@
# should clean up any temporary files created so that the temp
# directory is empty when the process exits.
-SPEC_TEMP_DIR = File.expand_path(ENV["SPEC_TEMP_DIR"] || "rubyspec_temp")
+SPEC_TEMP_DIR_PID = Process.pid
-SPEC_TEMP_UNIQUIFIER = "0"
+if spec_temp_dir = ENV["SPEC_TEMP_DIR"]
+ spec_temp_dir = File.realdirpath(spec_temp_dir)
+else
+ spec_temp_dir = "#{File.realpath(Dir.pwd)}/rubyspec_temp/#{SPEC_TEMP_DIR_PID}"
+end
+SPEC_TEMP_DIR = spec_temp_dir
-SPEC_TEMP_DIR_PID = Process.pid
+SPEC_TEMP_UNIQUIFIER = "0"
at_exit do
begin
@@ -30,8 +35,8 @@ all specs are cleaning up temporary files:
end
end
-def tmp(name, uniquify=true)
- Dir.mkdir SPEC_TEMP_DIR unless Dir.exist? SPEC_TEMP_DIR
+def tmp(name, uniquify = true)
+ mkdir_p SPEC_TEMP_DIR unless Dir.exist? SPEC_TEMP_DIR
if uniquify and !name.empty?
slash = name.rindex "/"
diff --git a/spec/mspec/lib/mspec/helpers/warning.rb b/spec/mspec/lib/mspec/helpers/warning.rb
index 9e093074e5..f94551c185 100644
--- a/spec/mspec/lib/mspec/helpers/warning.rb
+++ b/spec/mspec/lib/mspec/helpers/warning.rb
@@ -1,3 +1,5 @@
+require 'mspec/guards/version'
+
def suppress_warning
verbose = $VERBOSE
$VERBOSE = nil
@@ -5,3 +7,13 @@ def suppress_warning
ensure
$VERBOSE = verbose
end
+
+if ruby_version_is("2.7")
+ def suppress_keyword_warning(&block)
+ suppress_warning(&block)
+ end
+else
+ def suppress_keyword_warning
+ yield
+ end
+end
diff --git a/spec/mspec/lib/mspec/matchers.rb b/spec/mspec/lib/mspec/matchers.rb
index 8eab73198a..356e4a9f32 100644
--- a/spec/mspec/lib/mspec/matchers.rb
+++ b/spec/mspec/lib/mspec/matchers.rb
@@ -25,6 +25,7 @@ require 'mspec/matchers/have_protected_instance_method'
require 'mspec/matchers/have_public_instance_method'
require 'mspec/matchers/have_singleton_method'
require 'mspec/matchers/include'
+require 'mspec/matchers/include_any_of'
require 'mspec/matchers/infinity'
require 'mspec/matchers/match_yaml'
require 'mspec/matchers/raise_error'
@@ -33,3 +34,4 @@ require 'mspec/matchers/output_to_fd'
require 'mspec/matchers/respond_to'
require 'mspec/matchers/signed_zero'
require 'mspec/matchers/block_caller'
+require 'mspec/matchers/skip'
diff --git a/spec/mspec/lib/mspec/matchers/base.rb b/spec/mspec/lib/mspec/matchers/base.rb
index fc2d36c84a..94d3b71e55 100644
--- a/spec/mspec/lib/mspec/matchers/base.rb
+++ b/spec/mspec/lib/mspec/matchers/base.rb
@@ -10,98 +10,52 @@ class Module
include MSpecMatchers
end
-class SpecPositiveOperatorMatcher
+class SpecPositiveOperatorMatcher < BasicObject
def initialize(actual)
@actual = actual
end
def ==(expected)
- unless @actual == expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "to equal #{expected.pretty_inspect}")
- end
+ method_missing(:==, expected)
end
- def <(expected)
- unless @actual < expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "to be less than #{expected.pretty_inspect}")
- end
- end
-
- def <=(expected)
- unless @actual <= expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "to be less than or equal to #{expected.pretty_inspect}")
- end
+ def !=(expected)
+ method_missing(:!=, expected)
end
- def >(expected)
- unless @actual > expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "to be greater than #{expected.pretty_inspect}")
- end
- end
-
- def >=(expected)
- unless @actual >= expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "to be greater than or equal to #{expected.pretty_inspect}")
- end
+ def equal?(expected)
+ method_missing(:equal?, expected)
end
- def =~(expected)
- unless @actual =~ expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "to match #{expected.pretty_inspect}")
+ def method_missing(name, *args, &block)
+ result = @actual.__send__(name, *args, &block)
+ unless result
+ ::SpecExpectation.fail_predicate(@actual, name, args, block, result, "to be truthy")
end
end
end
-class SpecNegativeOperatorMatcher
+class SpecNegativeOperatorMatcher < BasicObject
def initialize(actual)
@actual = actual
end
def ==(expected)
- if @actual == expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "not to equal #{expected.pretty_inspect}")
- end
+ method_missing(:==, expected)
end
- def <(expected)
- if @actual < expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "not to be less than #{expected.pretty_inspect}")
- end
- end
-
- def <=(expected)
- if @actual <= expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "not to be less than or equal to #{expected.pretty_inspect}")
- end
+ def !=(expected)
+ method_missing(:!=, expected)
end
- def >(expected)
- if @actual > expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "not to be greater than #{expected.pretty_inspect}")
- end
- end
-
- def >=(expected)
- if @actual >= expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "not to be greater than or equal to #{expected.pretty_inspect}")
- end
+ def equal?(expected)
+ method_missing(:equal?, expected)
end
- def =~(expected)
- if @actual =~ expected
- SpecExpectation.fail_with("Expected #{@actual.pretty_inspect}",
- "not to match #{expected.pretty_inspect}")
+ def method_missing(name, *args, &block)
+ result = @actual.__send__(name, *args, &block)
+ if result
+ ::SpecExpectation.fail_predicate(@actual, name, args, block, result, "to be falsy")
end
end
end
diff --git a/spec/mspec/lib/mspec/matchers/be_close.rb b/spec/mspec/lib/mspec/matchers/be_close.rb
index 2cf0fba41f..d6a6626f31 100644
--- a/spec/mspec/lib/mspec/matchers/be_close.rb
+++ b/spec/mspec/lib/mspec/matchers/be_close.rb
@@ -1,4 +1,6 @@
TOLERANCE = 0.00003 unless Object.const_defined?(:TOLERANCE)
+# To account for GC, context switches, other processes, load, etc.
+TIME_TOLERANCE = 20.0 unless Object.const_defined?(:TIME_TOLERANCE)
class BeCloseMatcher
def initialize(expected, tolerance)
@@ -8,15 +10,15 @@ class BeCloseMatcher
def matches?(actual)
@actual = actual
- (@actual - @expected).abs < @tolerance
+ (@actual - @expected).abs <= @tolerance
end
def failure_message
- ["Expected #{@expected}", "to be within +/- #{@tolerance} of #{@actual}"]
+ ["Expected #{@actual}", "to be within #{@expected} +/- #{@tolerance}"]
end
def negative_failure_message
- ["Expected #{@expected}", "not to be within +/- #{@tolerance} of #{@actual}"]
+ ["Expected #{@actual}", "not to be within #{@expected} +/- #{@tolerance}"]
end
end
diff --git a/spec/mspec/lib/mspec/matchers/block_caller.rb b/spec/mspec/lib/mspec/matchers/block_caller.rb
index 017bce3cb7..30fab4fc68 100644
--- a/spec/mspec/lib/mspec/matchers/block_caller.rb
+++ b/spec/mspec/lib/mspec/matchers/block_caller.rb
@@ -1,22 +1,24 @@
class BlockingMatcher
def matches?(block)
- started = false
- blocking = true
-
- thread = Thread.new do
- started = true
+ t = Thread.new do
block.call
-
- blocking = false
end
- while !started and status = thread.status and status != "sleep"
- Thread.pass
+ loop do
+ case t.status
+ when "sleep" # blocked
+ t.kill
+ t.join
+ return true
+ when false # terminated normally, so never blocked
+ t.join
+ return false
+ when nil # terminated exceptionally
+ t.value
+ else
+ Thread.pass
+ end
end
- thread.kill
- thread.join
-
- blocking
end
def failure_message
@@ -29,7 +31,7 @@ class BlockingMatcher
end
module MSpecMatchers
- private def block_caller(timeout = 0.1)
+ private def block_caller
BlockingMatcher.new
end
end
diff --git a/spec/mspec/lib/mspec/matchers/complain.rb b/spec/mspec/lib/mspec/matchers/complain.rb
index 71b6a77680..887e72b4b0 100644
--- a/spec/mspec/lib/mspec/matchers/complain.rb
+++ b/spec/mspec/lib/mspec/matchers/complain.rb
@@ -1,56 +1,71 @@
require 'mspec/helpers/io'
class ComplainMatcher
- def initialize(complaint)
- @complaint = complaint
+ def initialize(complaint = nil, options = nil)
+ # the proper solution is to use double splat operator e.g.
+ # def initialize(complaint = nil, **options)
+ # but we are trying to minimize language features required to run MSpec
+ if complaint.is_a?(Hash)
+ @complaint = nil
+ @options = complaint
+ else
+ @complaint = complaint
+ @options = options || {}
+ end
end
def matches?(proc)
@saved_err = $stderr
- @stderr = $stderr = IOStub.new
@verbose = $VERBOSE
- $VERBOSE = false
+ err = IOStub.new
- proc.call
+ Thread.current[:in_mspec_complain_matcher] = true
+ $stderr = err
+ $VERBOSE = @options.key?(:verbose) ? @options[:verbose] : false
+ begin
+ proc.call
+ ensure
+ $VERBOSE = @verbose
+ $stderr = @saved_err
+ Thread.current[:in_mspec_complain_matcher] = false
+ end
+ @warning = err.to_s
unless @complaint.nil?
case @complaint
when Regexp
- return false unless $stderr =~ @complaint
+ return false unless @warning =~ @complaint
else
- return false unless $stderr == @complaint
+ return false unless @warning == @complaint
end
end
- return $stderr.empty? ? false : true
- ensure
- $VERBOSE = @verbose
- $stderr = @saved_err
+ return @warning.empty? ? false : true
end
def failure_message
if @complaint.nil?
["Expected a warning", "but received none"]
elsif @complaint.kind_of? Regexp
- ["Expected warning to match: #{@complaint.inspect}", "but got: #{@stderr.chomp.inspect}"]
+ ["Expected warning to match: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
else
- ["Expected warning: #{@complaint.inspect}", "but got: #{@stderr.chomp.inspect}"]
+ ["Expected warning: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
end
end
def negative_failure_message
if @complaint.nil?
- ["Unexpected warning: ", @stderr.chomp.inspect]
+ ["Unexpected warning: ", @warning.chomp.inspect]
elsif @complaint.kind_of? Regexp
- ["Expected warning not to match: #{@complaint.inspect}", "but got: #{@stderr.chomp.inspect}"]
+ ["Expected warning not to match: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
else
- ["Expected warning: #{@complaint.inspect}", "but got: #{@stderr.chomp.inspect}"]
+ ["Expected warning: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
end
end
end
module MSpecMatchers
- private def complain(complaint=nil)
- ComplainMatcher.new(complaint)
+ private def complain(complaint = nil, options = nil)
+ ComplainMatcher.new(complaint, options)
end
end
diff --git a/spec/mspec/lib/mspec/matchers/eql.rb b/spec/mspec/lib/mspec/matchers/eql.rb
index a855789550..bcab88ebee 100644
--- a/spec/mspec/lib/mspec/matchers/eql.rb
+++ b/spec/mspec/lib/mspec/matchers/eql.rb
@@ -9,13 +9,13 @@ class EqlMatcher
end
def failure_message
- ["Expected #{@actual.pretty_inspect}",
- "to have same value and type as #{@expected.pretty_inspect}"]
+ ["Expected #{MSpec.format(@actual)}",
+ "to have same value and type as #{MSpec.format(@expected)}"]
end
def negative_failure_message
- ["Expected #{@actual.pretty_inspect}",
- "not to have same value or type as #{@expected.pretty_inspect}"]
+ ["Expected #{MSpec.format(@actual)}",
+ "not to have same value or type as #{MSpec.format(@expected)}"]
end
end
diff --git a/spec/mspec/lib/mspec/matchers/equal.rb b/spec/mspec/lib/mspec/matchers/equal.rb
index 5dc77d27ea..5ba4856d82 100644
--- a/spec/mspec/lib/mspec/matchers/equal.rb
+++ b/spec/mspec/lib/mspec/matchers/equal.rb
@@ -9,13 +9,13 @@ class EqualMatcher
end
def failure_message
- ["Expected #{@actual.pretty_inspect}",
- "to be identical to #{@expected.pretty_inspect}"]
+ ["Expected #{MSpec.format(@actual)}",
+ "to be identical to #{MSpec.format(@expected)}"]
end
def negative_failure_message
- ["Expected #{@actual.pretty_inspect}",
- "not to be identical to #{@expected.pretty_inspect}"]
+ ["Expected #{MSpec.format(@actual)}",
+ "not to be identical to #{MSpec.format(@expected)}"]
end
end
diff --git a/spec/mspec/lib/mspec/matchers/equal_element.rb b/spec/mspec/lib/mspec/matchers/equal_element.rb
index 1e9dfbcca1..8da2567fcf 100644
--- a/spec/mspec/lib/mspec/matchers/equal_element.rb
+++ b/spec/mspec/lib/mspec/matchers/equal_element.rb
@@ -37,12 +37,12 @@ class EqualElementMatcher
end
def failure_message
- ["Expected #{@actual.pretty_inspect}",
+ ["Expected #{MSpec.format(@actual)}",
"to be a '#{@element}' element with #{attributes_for_failure_message} and #{content_for_failure_message}"]
end
def negative_failure_message
- ["Expected #{@actual.pretty_inspect}",
+ ["Expected #{MSpec.format(@actual)}",
"not to be a '#{@element}' element with #{attributes_for_failure_message} and #{content_for_failure_message}"]
end
diff --git a/spec/mspec/lib/mspec/matchers/have_instance_method.rb b/spec/mspec/lib/mspec/matchers/have_instance_method.rb
index 636aaf3e47..9a5a31aa0f 100644
--- a/spec/mspec/lib/mspec/matchers/have_instance_method.rb
+++ b/spec/mspec/lib/mspec/matchers/have_instance_method.rb
@@ -18,7 +18,7 @@ class HaveInstanceMethodMatcher < MethodMatcher
end
module MSpecMatchers
- private def have_instance_method(method, include_super=true)
+ private def have_instance_method(method, include_super = true)
HaveInstanceMethodMatcher.new method, include_super
end
end
diff --git a/spec/mspec/lib/mspec/matchers/have_method.rb b/spec/mspec/lib/mspec/matchers/have_method.rb
index 35dae03af0..e962e69e0a 100644
--- a/spec/mspec/lib/mspec/matchers/have_method.rb
+++ b/spec/mspec/lib/mspec/matchers/have_method.rb
@@ -18,7 +18,7 @@ class HaveMethodMatcher < MethodMatcher
end
module MSpecMatchers
- private def have_method(method, include_super=true)
+ private def have_method(method, include_super = true)
HaveMethodMatcher.new method, include_super
end
end
diff --git a/spec/mspec/lib/mspec/matchers/have_private_instance_method.rb b/spec/mspec/lib/mspec/matchers/have_private_instance_method.rb
index 4eb7133055..d32db76c6a 100644
--- a/spec/mspec/lib/mspec/matchers/have_private_instance_method.rb
+++ b/spec/mspec/lib/mspec/matchers/have_private_instance_method.rb
@@ -18,7 +18,7 @@ class HavePrivateInstanceMethodMatcher < MethodMatcher
end
module MSpecMatchers
- private def have_private_instance_method(method, include_super=true)
+ private def have_private_instance_method(method, include_super = true)
HavePrivateInstanceMethodMatcher.new method, include_super
end
end
diff --git a/spec/mspec/lib/mspec/matchers/have_private_method.rb b/spec/mspec/lib/mspec/matchers/have_private_method.rb
index 3433d982cc..c74165cfc7 100644
--- a/spec/mspec/lib/mspec/matchers/have_private_method.rb
+++ b/spec/mspec/lib/mspec/matchers/have_private_method.rb
@@ -18,7 +18,7 @@ class HavePrivateMethodMatcher < MethodMatcher
end
module MSpecMatchers
- private def have_private_method(method, include_super=true)
+ private def have_private_method(method, include_super = true)
HavePrivateMethodMatcher.new method, include_super
end
end
diff --git a/spec/mspec/lib/mspec/matchers/have_protected_instance_method.rb b/spec/mspec/lib/mspec/matchers/have_protected_instance_method.rb
index 641d4d0dc2..1deb2f995d 100644
--- a/spec/mspec/lib/mspec/matchers/have_protected_instance_method.rb
+++ b/spec/mspec/lib/mspec/matchers/have_protected_instance_method.rb
@@ -18,7 +18,7 @@ class HaveProtectedInstanceMethodMatcher < MethodMatcher
end
module MSpecMatchers
- private def have_protected_instance_method(method, include_super=true)
+ private def have_protected_instance_method(method, include_super = true)
HaveProtectedInstanceMethodMatcher.new method, include_super
end
end
diff --git a/spec/mspec/lib/mspec/matchers/have_public_instance_method.rb b/spec/mspec/lib/mspec/matchers/have_public_instance_method.rb
index 501c0a418e..0e620532c0 100644
--- a/spec/mspec/lib/mspec/matchers/have_public_instance_method.rb
+++ b/spec/mspec/lib/mspec/matchers/have_public_instance_method.rb
@@ -18,7 +18,7 @@ class HavePublicInstanceMethodMatcher < MethodMatcher
end
module MSpecMatchers
- private def have_public_instance_method(method, include_super=true)
+ private def have_public_instance_method(method, include_super = true)
HavePublicInstanceMethodMatcher.new method, include_super
end
end
diff --git a/spec/mspec/lib/mspec/matchers/have_singleton_method.rb b/spec/mspec/lib/mspec/matchers/have_singleton_method.rb
index 95d78709ff..b60dd2536b 100644
--- a/spec/mspec/lib/mspec/matchers/have_singleton_method.rb
+++ b/spec/mspec/lib/mspec/matchers/have_singleton_method.rb
@@ -18,7 +18,7 @@ class HaveSingletonMethodMatcher < MethodMatcher
end
module MSpecMatchers
- private def have_singleton_method(method, include_super=true)
+ private def have_singleton_method(method, include_super = true)
HaveSingletonMethodMatcher.new method, include_super
end
end
diff --git a/spec/mspec/lib/mspec/matchers/include.rb b/spec/mspec/lib/mspec/matchers/include.rb
index 0b7eaf3ce2..3f07f35548 100644
--- a/spec/mspec/lib/mspec/matchers/include.rb
+++ b/spec/mspec/lib/mspec/matchers/include.rb
@@ -15,11 +15,11 @@ class IncludeMatcher
end
def failure_message
- ["Expected #{@actual.inspect}", "to include #{@element.inspect}"]
+ ["Expected #{MSpec.format(@actual)}", "to include #{MSpec.format(@element)}"]
end
def negative_failure_message
- ["Expected #{@actual.inspect}", "not to include #{@element.inspect}"]
+ ["Expected #{MSpec.format(@actual)}", "not to include #{MSpec.format(@element)}"]
end
end
diff --git a/spec/mspec/lib/mspec/matchers/include_any_of.rb b/spec/mspec/lib/mspec/matchers/include_any_of.rb
new file mode 100644
index 0000000000..ce097ccf0f
--- /dev/null
+++ b/spec/mspec/lib/mspec/matchers/include_any_of.rb
@@ -0,0 +1,29 @@
+class IncludeAnyOfMatcher
+ def initialize(*expected)
+ @expected = expected
+ end
+
+ def matches?(actual)
+ @actual = actual
+ @expected.each do |e|
+ if @actual.include?(e)
+ return true
+ end
+ end
+ return false
+ end
+
+ def failure_message
+ ["Expected #{@actual.inspect}", "to include any of #{@expected.inspect}"]
+ end
+
+ def negative_failure_message
+ ["Expected #{@actual.inspect}", "not to include any of #{@expected.inspect}"]
+ end
+end
+
+module MSpecMatchers
+ private def include_any_of(*expected)
+ IncludeAnyOfMatcher.new(*expected)
+ end
+end
diff --git a/spec/mspec/lib/mspec/matchers/method.rb b/spec/mspec/lib/mspec/matchers/method.rb
index e8cdfa62ff..2b54419faa 100644
--- a/spec/mspec/lib/mspec/matchers/method.rb
+++ b/spec/mspec/lib/mspec/matchers/method.rb
@@ -1,5 +1,5 @@
class MethodMatcher
- def initialize(method, include_super=true)
+ def initialize(method, include_super = true)
@include_super = include_super
@method = method.to_sym
end
diff --git a/spec/mspec/lib/mspec/matchers/output.rb b/spec/mspec/lib/mspec/matchers/output.rb
index b89b6ca0f6..20721df743 100644
--- a/spec/mspec/lib/mspec/matchers/output.rb
+++ b/spec/mspec/lib/mspec/matchers/output.rb
@@ -61,7 +61,7 @@ class OutputMatcher
end
module MSpecMatchers
- private def output(stdout=nil, stderr=nil)
+ private def output(stdout = nil, stderr = nil)
OutputMatcher.new(stdout, stderr)
end
end
diff --git a/spec/mspec/lib/mspec/matchers/raise_error.rb b/spec/mspec/lib/mspec/matchers/raise_error.rb
index 28c7a5ea2f..878428d43a 100644
--- a/spec/mspec/lib/mspec/matchers/raise_error.rb
+++ b/spec/mspec/lib/mspec/matchers/raise_error.rb
@@ -1,5 +1,3 @@
-require 'mspec/utils/deprecate'
-
class RaiseErrorMatcher
def initialize(exception, message, &block)
@exception = exception
@@ -8,33 +6,43 @@ class RaiseErrorMatcher
@actual = nil
end
+ # This #matches? method is unusual because it doesn't always return a boolean but instead
+ # re-raises the original exception if proc.call raises an exception and #matching_exception? is false.
+ # The reasoning is the original exception class matters and we don't want to change it by raising another exception,
+ # so instead we attach the #failure_message and extract it in ExceptionState#message.
def matches?(proc)
@result = proc.call
return false
rescue Exception => actual
@actual = actual
+
if matching_exception?(actual)
+ # The block has its own expectations and will throw an exception if it fails
+ @block[actual] if @block
return true
else
+ actual.instance_variable_set(:@mspec_raise_error_message, failure_message)
raise actual
end
end
- def matching_exception?(exc)
- return false unless @exception === exc
- if @message then
- case @message
- when String
- return false if @message != exc.message
- when Regexp
- return false if @message !~ exc.message
- end
- end
+ def matching_class?(exc)
+ @exception === exc
+ end
- # The block has its own expectations and will throw an exception if it fails
- @block[exc] if @block
+ def matching_message?(exc)
+ case @message
+ when String
+ @message == exc.message
+ when Regexp
+ @message =~ exc.message
+ else
+ true
+ end
+ end
- return true
+ def matching_exception?(exc)
+ matching_class?(exc) and matching_message?(exc)
end
def exception_class_and_message(exception_class, message)
@@ -57,9 +65,9 @@ class RaiseErrorMatcher
message = ["Expected #{format_expected_exception}"]
if @actual
- message << "but got #{format_exception(@actual)}"
+ message << "but got: #{format_exception(@actual)}"
else
- message << "but no exception was raised (#{@result.pretty_inspect.chomp} was returned)"
+ message << "but no exception was raised (#{MSpec.format(@result)} was returned)"
end
message
@@ -68,14 +76,14 @@ class RaiseErrorMatcher
def negative_failure_message
message = ["Expected to not get #{format_expected_exception}", ""]
unless @actual.class == @exception
- message[1] = "but got #{format_exception(@actual)}"
+ message[1] = "but got: #{format_exception(@actual)}"
end
message
end
end
module MSpecMatchers
- private def raise_error(exception=Exception, message=nil, &block)
+ private def raise_error(exception = Exception, message = nil, &block)
RaiseErrorMatcher.new(exception, message, &block)
end
end
diff --git a/spec/mspec/lib/mspec/matchers/skip.rb b/spec/mspec/lib/mspec/matchers/skip.rb
new file mode 100644
index 0000000000..7c175d358d
--- /dev/null
+++ b/spec/mspec/lib/mspec/matchers/skip.rb
@@ -0,0 +1,5 @@
+module MSpecMatchers
+ private def skip(reason = 'no reason')
+ raise SkippedSpecError, reason
+ end
+end
diff --git a/spec/mspec/lib/mspec/mocks/mock.rb b/spec/mspec/lib/mspec/mocks/mock.rb
index f833cba371..28a083cc15 100644
--- a/spec/mspec/lib/mspec/mocks/mock.rb
+++ b/spec/mspec/lib/mspec/mocks/mock.rb
@@ -48,12 +48,17 @@ module Mock
end
end
- def self.install_method(obj, sym, type=nil)
+ def self.install_method(obj, sym, type = nil)
meta = obj.singleton_class
key = replaced_key obj, sym
sym = sym.to_sym
+ if type == :stub and mocks.key?(key)
+ # Defining a stub and there is already a mock, ignore the stub
+ return
+ end
+
if (sym == :respond_to? or mock_respond_to?(obj, sym, true)) and !replaced?(key.first)
meta.__send__ :alias_method, key.first, sym
end
@@ -73,6 +78,11 @@ module Mock
MSpec.actions :expectation, MSpec.current.state
end
+ if proxy.mock? and stubs.key?(key)
+ # Defining a mock and there is already a stub, remove the stub
+ stubs.delete key
+ end
+
if proxy.stub?
stubs[key].unshift proxy
else
@@ -87,6 +97,10 @@ module Mock
obj.instance_variable_get(:@name) || obj.inspect
end
+ def self.inspect_args(args)
+ "(#{Array(args).map(&:inspect).join(', ')})"
+ end
+
def self.verify_count
mocks.each do |key, proxies|
obj = objects[key]
@@ -106,7 +120,7 @@ module Mock
end
unless pass
SpecExpectation.fail_with(
- "Mock '#{name_or_inspect obj}' expected to receive '#{key.last}' " + \
+ "Mock '#{name_or_inspect obj}' expected to receive #{key.last}#{inspect_args proxy.arguments} " + \
"#{qualifier.to_s.sub('_', ' ')} #{count} times",
"but received it #{proxy.calls} times")
end
@@ -120,7 +134,7 @@ module Mock
key = replaced_key obj, sym
[mocks, stubs].each do |proxies|
- proxies[key].each do |proxy|
+ proxies.fetch(key, []).each do |proxy|
pass = case proxy.arguments
when :any_args
true
@@ -163,10 +177,10 @@ module Mock
end
if sym.to_sym == :respond_to?
- mock_respond_to? obj, compare
+ mock_respond_to? obj, *args
else
SpecExpectation.fail_with("Mock '#{name_or_inspect obj}': method #{sym}\n",
- "called with unexpected arguments (#{Array(compare).join(' ')})")
+ "called with unexpected arguments #{inspect_args args}")
end
end
diff --git a/spec/mspec/lib/mspec/mocks/object.rb b/spec/mspec/lib/mspec/mocks/object.rb
index 19a50ac4e1..fcaa1caef0 100644
--- a/spec/mspec/lib/mspec/mocks/object.rb
+++ b/spec/mspec/lib/mspec/mocks/object.rb
@@ -15,7 +15,7 @@ class Object
end
end
-def mock(name, options={})
+def mock(name, options = {})
MockObject.new name, options
end
@@ -23,6 +23,6 @@ def mock_int(val)
MockIntObject.new(val)
end
-def mock_numeric(name, options={})
+def mock_numeric(name, options = {})
NumericMockObject.new name, options
end
diff --git a/spec/mspec/lib/mspec/mocks/proxy.rb b/spec/mspec/lib/mspec/mocks/proxy.rb
index f5acc89d62..8473132b0b 100644
--- a/spec/mspec/lib/mspec/mocks/proxy.rb
+++ b/spec/mspec/lib/mspec/mocks/proxy.rb
@@ -1,5 +1,5 @@
class MockObject
- def initialize(name, options={})
+ def initialize(name, options = {})
@name = name
@null = options[:null_object]
end
@@ -11,7 +11,7 @@ class MockObject
end
class NumericMockObject < Numeric
- def initialize(name, options={})
+ def initialize(name, options = {})
@name = name
@null = options[:null_object]
end
@@ -50,7 +50,7 @@ end
class MockProxy
attr_reader :raising, :yielding
- def initialize(type=nil)
+ def initialize(type = nil)
@multiple_returns = nil
@returning = nil
@raising = nil
diff --git a/spec/mspec/lib/mspec/runner/actions/constants_leak_checker.rb b/spec/mspec/lib/mspec/runner/actions/constants_leak_checker.rb
new file mode 100644
index 0000000000..abfb6dd0ee
--- /dev/null
+++ b/spec/mspec/lib/mspec/runner/actions/constants_leak_checker.rb
@@ -0,0 +1,84 @@
+class ConstantsLockFile
+ LOCK_FILE_NAME = '.mspec.constants'
+
+ def self.lock_file
+ @prefix ||= File.expand_path(MSpecScript.get(:prefix) || '.')
+ "#{@prefix}/#{LOCK_FILE_NAME}"
+ end
+
+ def self.load
+ if File.exist?(lock_file)
+ File.readlines(lock_file).map(&:chomp)
+ else
+ []
+ end
+ end
+
+ def self.dump(ary)
+ contents = ary.map(&:to_s).uniq.sort.join("\n") + "\n"
+ File.write(lock_file, contents)
+ end
+end
+
+class ConstantLeakError < StandardError
+end
+
+class ConstantsLeakCheckerAction
+ def initialize(save)
+ @save = save
+ @check = !save
+ @constants_locked = ConstantsLockFile.load
+ @exclude_patterns = MSpecScript.get(:toplevel_constants_excludes) || []
+ end
+
+ def register
+ MSpec.register :start, self
+ MSpec.register :before, self
+ MSpec.register :after, self
+ MSpec.register :finish, self
+ end
+
+ def start
+ @constants_start = constants_now
+ end
+
+ def before(state)
+ @constants_before = constants_now
+ end
+
+ def after(state)
+ constants = remove_excludes(constants_now - @constants_before - @constants_locked)
+
+ if @check && !constants.empty?
+ MSpec.protect 'Constants leak check' do
+ raise ConstantLeakError, "Top level constants leaked: #{constants.join(', ')}"
+ end
+ end
+ end
+
+ def finish
+ constants = remove_excludes(constants_now - @constants_start - @constants_locked)
+
+ if @save
+ ConstantsLockFile.dump(@constants_locked + constants)
+ end
+
+ if @check && !constants.empty?
+ MSpec.protect 'Global constants leak check' do
+ raise ConstantLeakError, "Top level constants leaked in the whole test suite: #{constants.join(', ')}"
+ end
+ end
+ end
+
+ private
+
+ def constants_now
+ Object.constants.map(&:to_s)
+ end
+
+ def remove_excludes(constants)
+ constants.reject { |name|
+ @exclude_patterns.any? { |pattern| pattern === name }
+ }
+ end
+end
diff --git a/spec/mspec/lib/mspec/runner/actions/filter.rb b/spec/mspec/lib/mspec/runner/actions/filter.rb
index 35899c8dc8..b0ad7080da 100644
--- a/spec/mspec/lib/mspec/runner/actions/filter.rb
+++ b/spec/mspec/lib/mspec/runner/actions/filter.rb
@@ -10,7 +10,7 @@ require 'mspec/runner/filters/match'
# trigger the action.
class ActionFilter
- def initialize(tags=nil, descs=nil)
+ def initialize(tags = nil, descs = nil)
@tags = Array(tags)
descs = Array(descs)
@sfilter = descs.empty? ? nil : MatchFilter.new(nil, *descs)
diff --git a/spec/mspec/lib/mspec/runner/actions/leakchecker.rb b/spec/mspec/lib/mspec/runner/actions/leakchecker.rb
index e947cda9ff..596b120d9f 100644
--- a/spec/mspec/lib/mspec/runner/actions/leakchecker.rb
+++ b/spec/mspec/lib/mspec/runner/actions/leakchecker.rb
@@ -24,29 +24,36 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
+class LeakError < StandardError
+end
+
class LeakChecker
+ attr_reader :leaks
+
def initialize
@fd_info = find_fds
@tempfile_info = find_tempfiles
@thread_info = find_threads
@env_info = find_env
@argv_info = find_argv
+ @globals_info = find_globals
@encoding_info = find_encodings
end
- def check(test_name)
- @no_leaks = true
- leaks = [
- check_fd_leak(test_name),
- check_tempfile_leak(test_name),
- check_thread_leak(test_name),
- check_process_leak(test_name),
- check_env(test_name),
- check_argv(test_name),
- check_encodings(test_name)
- ]
- GC.start if leaks.any?
- return leaks.none?
+ def check(state)
+ @state = state
+ @leaks = []
+ check_fd_leak
+ check_tempfile_leak
+ check_thread_leak
+ check_process_leak
+ check_env
+ check_argv
+ check_globals
+ check_encodings
+ check_tracepoints
+ GC.start unless @leaks.empty?
+ @leaks.empty?
end
private
@@ -66,8 +73,7 @@ class LeakChecker
end
end
- def check_fd_leak(test_name)
- leaked = false
+ def check_fd_leak
live1 = @fd_info
if IO.respond_to?(:console) and (m = IO.method(:console)).arity.nonzero?
m[:close]
@@ -76,12 +82,11 @@ class LeakChecker
fd_closed = live1 - live2
if !fd_closed.empty?
fd_closed.each {|fd|
- puts "Closed file descriptor: #{test_name}: #{fd}"
+ leak "Closed file descriptor: #{fd}"
}
end
fd_leaked = live2 - live1
if !fd_leaked.empty?
- leaked = true
h = {}
ObjectSpace.each_object(IO) {|io|
inspect = io.inspect
@@ -105,19 +110,18 @@ class LeakChecker
str << s
}
end
- puts "Leaked file descriptor: #{test_name}: #{fd}#{str}"
+ leak "Leaked file descriptor: #{fd}#{str}"
}
#system("lsof -p #$$") if !fd_leaked.empty?
h.each {|fd, list|
next if list.length <= 1
if 1 < list.count {|io, autoclose, inspect| autoclose }
str = list.map {|io, autoclose, inspect| " #{inspect}" + (autoclose ? "(autoclose)" : "") }.sort.join
- puts "Multiple autoclose IO object for a file descriptor:#{str}"
+ leak "Multiple autoclose IO object for a file descriptor:#{str}"
end
}
end
@fd_info = live2
- return leaked
end
def extend_tempfile_counter
@@ -140,7 +144,7 @@ class LeakChecker
end
end
- def find_tempfiles(prev_count=-1)
+ def find_tempfiles(prev_count = -1)
return [prev_count, []] unless defined? Tempfile
extend_tempfile_counter
count = TempfileCounter.count
@@ -152,22 +156,19 @@ class LeakChecker
end
end
- def check_tempfile_leak(test_name)
+ def check_tempfile_leak
return false unless defined? Tempfile
count1, initial_tempfiles = @tempfile_info
count2, current_tempfiles = find_tempfiles(count1)
- leaked = false
tempfiles_leaked = current_tempfiles - initial_tempfiles
if !tempfiles_leaked.empty?
- leaked = true
list = tempfiles_leaked.map {|t| t.inspect }.sort
list.each {|str|
- puts "Leaked tempfile: #{test_name}: #{str}"
+ leak "Leaked tempfile: #{str}"
}
tempfiles_leaked.each {|t| t.close! }
end
@tempfile_info = [count2, initial_tempfiles]
- return leaked
end
def find_threads
@@ -176,108 +177,119 @@ class LeakChecker
}
end
- def check_thread_leak(test_name)
+ def check_thread_leak
live1 = @thread_info
live2 = find_threads
thread_finished = live1 - live2
- leaked = false
if !thread_finished.empty?
list = thread_finished.map {|t| t.inspect }.sort
list.each {|str|
- puts "Finished thread: #{test_name}: #{str}"
+ leak "Finished thread: #{str}"
}
end
thread_leaked = live2 - live1
if !thread_leaked.empty?
- leaked = true
list = thread_leaked.map {|t| t.inspect }.sort
list.each {|str|
- puts "Leaked thread: #{test_name}: #{str}"
+ leak "Leaked thread: #{str}"
}
end
@thread_info = live2
- return leaked
end
- def check_process_leak(test_name)
+ def check_process_leak
subprocesses_leaked = Process.waitall
subprocesses_leaked.each { |pid, status|
- puts "Leaked subprocess: #{pid}: #{status}"
+ leak "Leaked subprocess: #{pid}: #{status}"
}
- return !subprocesses_leaked.empty?
end
def find_env
ENV.to_h
end
- def check_env(test_name)
+ def check_env
old_env = @env_info
new_env = find_env
- return false if old_env == new_env
+ return if old_env == new_env
+
(old_env.keys | new_env.keys).sort.each {|k|
if old_env.has_key?(k)
if new_env.has_key?(k)
if old_env[k] != new_env[k]
- puts "Environment variable changed: #{test_name} : #{k.inspect} changed : #{old_env[k].inspect} -> #{new_env[k].inspect}"
+ leak "Environment variable changed : #{k.inspect} changed : #{old_env[k].inspect} -> #{new_env[k].inspect}"
end
else
- puts "Environment variable changed: #{test_name} : #{k.inspect} deleted"
+ leak "Environment variable changed: #{k.inspect} deleted"
end
else
if new_env.has_key?(k)
- puts "Environment variable changed: #{test_name} : #{k.inspect} added"
+ leak "Environment variable changed: #{k.inspect} added"
else
flunk "unreachable"
end
end
}
@env_info = new_env
- return true
end
def find_argv
ARGV.map { |e| e.dup }
end
- def check_argv(test_name)
+ def check_argv
old_argv = @argv_info
new_argv = find_argv
- leaked = false
if new_argv != old_argv
- puts "ARGV changed: #{test_name} : #{old_argv.inspect} to #{new_argv.inspect}"
+ leak "ARGV changed: #{old_argv.inspect} to #{new_argv.inspect}"
@argv_info = new_argv
- leaked = true
end
- return leaked
+ end
+
+ def find_globals
+ { verbose: $VERBOSE, debug: $DEBUG }
+ end
+
+ def check_globals
+ old_globals = @globals_info
+ new_globals = find_globals
+ if new_globals != old_globals
+ leak "Globals changed: #{old_globals.inspect} to #{new_globals.inspect}"
+ @globals_info = new_globals
+ end
end
def find_encodings
[Encoding.default_internal, Encoding.default_external]
end
- def check_encodings(test_name)
+ def check_encodings
old_internal, old_external = @encoding_info
new_internal, new_external = find_encodings
- leaked = false
if new_internal != old_internal
- leaked = true
- puts "Encoding.default_internal changed: #{test_name} : #{old_internal} to #{new_internal}"
+ leak "Encoding.default_internal changed: #{old_internal.inspect} to #{new_internal.inspect}"
end
if new_external != old_external
- leaked = true
- puts "Encoding.default_external changed: #{test_name} : #{old_external} to #{new_external}"
+ leak "Encoding.default_external changed: #{old_external.inspect} to #{new_external.inspect}"
end
@encoding_info = [new_internal, new_external]
- return leaked
end
- def puts(*args)
- if @no_leaks
- @no_leaks = false
- print "\n"
+ def check_tracepoints
+ ObjectSpace.each_object(TracePoint) do |tp|
+ if tp.enabled?
+ leak "TracePoint is still enabled: #{tp.inspect}"
+ end
end
- super(*args)
+ end
+
+ def leak(message)
+ if @leaks.empty?
+ $stderr.puts "\n"
+ $stderr.puts @state.description
+ end
+ @leaks << message
+ $stderr.puts message
end
end
@@ -292,9 +304,14 @@ class LeakCheckerAction
end
def after(state)
- unless @checker.check(state.description)
+ unless @checker.check(state)
+ leak_messages = @checker.leaks
+ location = state.description
if state.example
- puts state.example.source_location.join(':')
+ location = "#{location}\n#{state.example.source_location.join(':')}"
+ end
+ MSpec.protect(location) do
+ raise LeakError, leak_messages.join("\n")
end
end
end
diff --git a/spec/mspec/lib/mspec/runner/actions/profile.rb b/spec/mspec/lib/mspec/runner/actions/profile.rb
new file mode 100644
index 0000000000..c743d6e3e8
--- /dev/null
+++ b/spec/mspec/lib/mspec/runner/actions/profile.rb
@@ -0,0 +1,60 @@
+class ProfileAction
+ def initialize
+ @describe_name = nil
+ @describe_time = nil
+ @describes = []
+ @its = []
+ end
+
+ def register
+ MSpec.register :enter, self
+ MSpec.register :before,self
+ MSpec.register :after, self
+ MSpec.register :finish,self
+ end
+
+ def enter(describe)
+ if @describe_time
+ @describes << [@describe_name, now - @describe_time]
+ end
+
+ @describe_name = describe
+ @describe_time = now
+ end
+
+ def before(state)
+ @it_name = state.it
+ @it_time = now
+ end
+
+ def after(state = nil)
+ @its << [@describe_name, @it_name, now - @it_time]
+ end
+
+ def finish
+ puts "\nProfiling info:"
+
+ desc = @describes.sort { |a,b| b.last <=> a.last }
+ desc.delete_if { |a| a.last <= 0.001 }
+ show = desc[0, 100]
+
+ puts "Top #{show.size} describes:"
+
+ show.each do |des, time|
+ printf "%3.3f - %s\n", time, des
+ end
+
+ its = @its.sort { |a,b| b.last <=> a.last }
+ its.delete_if { |a| a.last <= 0.001 }
+ show = its[0, 100]
+
+ puts "\nTop #{show.size} its:"
+ show.each do |des, it, time|
+ printf "%3.3f - %s %s\n", time, des, it
+ end
+ end
+
+ def now
+ Time.now.to_f
+ end
+end
diff --git a/spec/mspec/lib/mspec/runner/actions/tag.rb b/spec/mspec/lib/mspec/runner/actions/tag.rb
index 760152b2a3..d40d562451 100644
--- a/spec/mspec/lib/mspec/runner/actions/tag.rb
+++ b/spec/mspec/lib/mspec/runner/actions/tag.rb
@@ -22,7 +22,7 @@ require 'mspec/runner/actions/filter'
# spec description strings
class TagAction < ActionFilter
- def initialize(action, outcome, tag, comment, tags=nil, descs=nil)
+ def initialize(action, outcome, tag, comment, tags = nil, descs = nil)
super tags, descs
@action = action
@outcome = outcome
diff --git a/spec/mspec/lib/mspec/runner/actions/taglist.rb b/spec/mspec/lib/mspec/runner/actions/taglist.rb
index c1aba53794..3097e655d5 100644
--- a/spec/mspec/lib/mspec/runner/actions/taglist.rb
+++ b/spec/mspec/lib/mspec/runner/actions/taglist.rb
@@ -4,7 +4,7 @@ require 'mspec/runner/actions/filter'
# tagged with +tags+. If +tags+ is an empty list, prints out
# descriptions for any specs that are tagged.
class TagListAction
- def initialize(tags=nil)
+ def initialize(tags = nil)
@tags = tags.nil? || tags.empty? ? nil : Array(tags)
@filter = nil
end
diff --git a/spec/mspec/lib/mspec/runner/actions/tally.rb b/spec/mspec/lib/mspec/runner/actions/tally.rb
index 33f937293c..d6ada53bab 100644
--- a/spec/mspec/lib/mspec/runner/actions/tally.rb
+++ b/spec/mspec/lib/mspec/runner/actions/tally.rb
@@ -5,31 +5,31 @@ class Tally
@files = @examples = @expectations = @failures = @errors = @guards = @tagged = 0
end
- def files!(add=1)
+ def files!(add = 1)
@files += add
end
- def examples!(add=1)
+ def examples!(add = 1)
@examples += add
end
- def expectations!(add=1)
+ def expectations!(add = 1)
@expectations += add
end
- def failures!(add=1)
+ def failures!(add = 1)
@failures += add
end
- def errors!(add=1)
+ def errors!(add = 1)
@errors += add
end
- def guards!(add=1)
+ def guards!(add = 1)
@guards += add
end
- def tagged!(add=1)
+ def tagged!(add = 1)
@tagged += add
end
diff --git a/spec/mspec/lib/mspec/runner/actions/timeout.rb b/spec/mspec/lib/mspec/runner/actions/timeout.rb
new file mode 100644
index 0000000000..c85bf49ad3
--- /dev/null
+++ b/spec/mspec/lib/mspec/runner/actions/timeout.rb
@@ -0,0 +1,60 @@
+class TimeoutAction
+ def initialize(timeout)
+ @timeout = timeout
+ @queue = Queue.new
+ @started = now
+ end
+
+ def register
+ MSpec.register :start, self
+ MSpec.register :before, self
+ MSpec.register :finish, self
+ end
+
+ private def now
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ end
+
+ private def fetch_item
+ @queue.pop(true)
+ rescue ThreadError
+ nil
+ end
+
+ def start
+ @thread = Thread.new do
+ loop do
+ if action = fetch_item
+ action.call
+ else
+ wakeup_at = @started + @timeout
+ left = wakeup_at - now
+ sleep left if left > 0
+ Thread.pass # Let the main thread run
+
+ if @queue.empty?
+ elapsed = now - @started
+ if elapsed > @timeout
+ STDERR.puts "\n#{@current_state.description}"
+ STDERR.flush
+ abort "Example took longer than the configured timeout of #{@timeout}s"
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def before(state = nil)
+ time = now
+ @queue << -> do
+ @current_state = state
+ @started = time
+ end
+ end
+
+ def finish
+ @thread.kill
+ @thread.join
+ end
+end
diff --git a/spec/mspec/lib/mspec/runner/context.rb b/spec/mspec/lib/mspec/runner/context.rb
index 2b470f226a..62483590bb 100644
--- a/spec/mspec/lib/mspec/runner/context.rb
+++ b/spec/mspec/lib/mspec/runner/context.rb
@@ -6,21 +6,20 @@
#--
# A note on naming: this is named _ContextState_ rather
# than _DescribeState_ because +describe+ is the keyword
-# in the DSL for refering to the context in which an example
+# in the DSL for referring to the context in which an example
# is evaluated, just as +it+ refers to the example itself.
#++
class ContextState
attr_reader :state, :parent, :parents, :children, :examples, :to_s
- def initialize(mod, options=nil)
- @to_s = mod.to_s
- if options.is_a? Hash
- @options = options
- else
- @to_s += "#{".:#".include?(options[0,1]) ? "" : " "}#{options}" if options
- @options = { }
- end
- @options[:shared] ||= false
+ MOCK_VERIFY = -> { Mock.verify_count }
+ MOCK_CLEANUP = -> { Mock.cleanup }
+ EXPECTATION_MISSING = -> { raise SpecExpectationNotFoundError }
+
+ def initialize(description, options = nil)
+ raise "#describe options should be a Hash or nil" unless Hash === options or options.nil?
+ @to_s = description.to_s
+ @shared = options && options[:shared]
@parsed = false
@before = { :all => [], :each => [] }
@@ -28,13 +27,10 @@ class ContextState
@pre = {}
@post = {}
@examples = []
+ @state = nil
@parent = nil
@parents = [self]
@children = []
-
- @mock_verify = Proc.new { Mock.verify_count }
- @mock_cleanup = Proc.new { Mock.cleanup }
- @expectation_missing = Proc.new { raise SpecExpectationNotFoundError }
end
# Remove caching when a ContextState is dup'd for shared specs.
@@ -46,7 +42,7 @@ class ContextState
# Returns true if this is a shared +ContextState+. Essentially, when
# created with: describe "Something", :shared => true { ... }
def shared?
- return @options[:shared]
+ @shared
end
# Set the parent (enclosing) +ContextState+ for this state. Creates
@@ -127,6 +123,7 @@ class ContextState
# Creates an ExampleState instance for the block and stores it
# in a list of examples to evaluate unless the example is filtered.
def it(desc, &block)
+ raise "nested #it" if @state
example = ExampleState.new(self, desc, block)
MSpec.actions :add, example
return if MSpec.guarded?
@@ -174,7 +171,7 @@ class ContextState
# so that exceptions are handled and tallied. Returns true and does
# NOT evaluate any blocks if +check+ is true and
# <tt>MSpec.mode?(:pretend)</tt> is true.
- def protect(what, blocks, check=true)
+ def protect(what, blocks, check = true)
return true if check and MSpec.mode? :pretend
Array(blocks).all? { |block| MSpec.protect what, &block }
end
@@ -205,7 +202,7 @@ class ContextState
if protect "before :all", pre(:all)
@examples.each do |state|
MSpec.repeat do
- @state = state
+ @state = state
example = state.example
MSpec.actions :before, state
@@ -214,20 +211,20 @@ class ContextState
if example
passed = protect nil, example
MSpec.actions :example, state, example
- protect nil, @expectation_missing unless MSpec.expectation? or !passed
+ protect nil, EXPECTATION_MISSING if !MSpec.expectation? and passed
end
end
protect "after :each", post(:each)
- protect "Mock.verify_count", @mock_verify
+ protect "Mock.verify_count", MOCK_VERIFY
- protect "Mock.cleanup", @mock_cleanup
+ protect "Mock.cleanup", MOCK_CLEANUP
MSpec.actions :after, state
@state = nil
end
end
protect "after :all", post(:all)
else
- protect "Mock.cleanup", @mock_cleanup
+ protect "Mock.cleanup", MOCK_CLEANUP
end
MSpec.actions :leave
diff --git a/spec/mspec/lib/mspec/runner/evaluate.rb b/spec/mspec/lib/mspec/runner/evaluate.rb
index ecf7460a90..396a84c118 100644
--- a/spec/mspec/lib/mspec/runner/evaluate.rb
+++ b/spec/mspec/lib/mspec/runner/evaluate.rb
@@ -19,7 +19,7 @@ class SpecEvaluate
# single quotes to set if off from the rest of the description string. If
# the source does contain newline characters, sets the indent level to four
# characters.
- def format(ruby, newline=true)
+ def format(ruby, newline = true)
if ruby.include?("\n")
lines = ruby.each_line.to_a
if /( *)/ =~ lines.first
@@ -49,6 +49,6 @@ class SpecEvaluate
end
end
-def evaluate(str, desc=nil, &block)
+def evaluate(str, desc = nil, &block)
SpecEvaluate.new(str, desc).define(&block)
end
diff --git a/spec/mspec/lib/mspec/runner/example.rb b/spec/mspec/lib/mspec/runner/example.rb
index 19eb29b079..0d9f0d618c 100644
--- a/spec/mspec/lib/mspec/runner/example.rb
+++ b/spec/mspec/lib/mspec/runner/example.rb
@@ -3,12 +3,12 @@ require 'mspec/runner/mspec'
# Holds some of the state of the example (i.e. +it+ block) that is
# being evaluated. See also +ContextState+.
class ExampleState
- attr_reader :context, :it, :example
+ attr_reader :context, :it, :example
- def initialize(context, it, example=nil)
- @context = context
- @it = it
- @example = example
+ def initialize(context, it, example = nil)
+ @context = context
+ @it = it
+ @example = example
end
def context=(context)
@@ -25,8 +25,8 @@ class ExampleState
end
def filtered?
- incl = MSpec.retrieve(:include) || []
- excl = MSpec.retrieve(:exclude) || []
+ incl = MSpec.include
+ excl = MSpec.exclude
included = incl.empty? || incl.any? { |f| f === description }
included &&= excl.empty? || !excl.any? { |f| f === description }
!included
diff --git a/spec/mspec/lib/mspec/runner/exception.rb b/spec/mspec/lib/mspec/runner/exception.rb
index 0d9bb43105..e07f02f684 100644
--- a/spec/mspec/lib/mspec/runner/exception.rb
+++ b/spec/mspec/lib/mspec/runner/exception.rb
@@ -6,6 +6,7 @@ class ExceptionState
def initialize(state, location, exception)
@exception = exception
+ @failure = exception.class == SpecExpectationNotMetError || exception.class == SpecExpectationNotFoundError
@description = location ? "An exception occurred during: #{location}" : ""
if state
@@ -19,25 +20,35 @@ class ExceptionState
end
def failure?
- [SpecExpectationNotMetError, SpecExpectationNotFoundError].any? { |e| @exception.is_a? e }
+ @failure
end
def message
- if @exception.message.empty?
- "<No message>"
- elsif @exception.class == SpecExpectationNotMetError ||
- @exception.class == SpecExpectationNotFoundError
- @exception.message
+ message = @exception.message
+ message = "<No message>" if message.empty?
+
+ if @failure
+ message
+ elsif raise_error_message = @exception.instance_variable_get(:@mspec_raise_error_message)
+ raise_error_message.join("\n")
else
- "#{@exception.class}: #{@exception.message}"
+ "#{@exception.class}: #{message}"
end
end
def backtrace
- @backtrace_filter ||= MSpecScript.config[:backtrace_filter]
+ @backtrace_filter ||= MSpecScript.config[:backtrace_filter] || %r{(?:/bin/mspec|/lib/mspec/)}
bt = @exception.backtrace || []
-
- bt.select { |line| $MSPEC_DEBUG or @backtrace_filter !~ line }.join("\n")
+ unless $MSPEC_DEBUG
+ # Exclude <internal: entries inside MSpec code, so only after the first ignored entry
+ first_excluded_line = bt.index { |line| @backtrace_filter =~ line }
+ if first_excluded_line
+ bt = bt[0...first_excluded_line] + bt[first_excluded_line..-1].reject { |line|
+ @backtrace_filter =~ line || /^<internal:/ =~ line
+ }
+ end
+ end
+ bt.join("\n")
end
end
diff --git a/spec/mspec/lib/mspec/runner/filters/regexp.rb b/spec/mspec/lib/mspec/runner/filters/regexp.rb
index 2bd1448d3f..097ec6a755 100644
--- a/spec/mspec/lib/mspec/runner/filters/regexp.rb
+++ b/spec/mspec/lib/mspec/runner/filters/regexp.rb
@@ -1,7 +1,23 @@
-require 'mspec/runner/filters/match'
+class RegexpFilter
+ def initialize(what, *regexps)
+ @what = what
+ @regexps = to_regexp(*regexps)
+ end
+
+ def ===(string)
+ @regexps.any? { |regexp| regexp === string }
+ end
+
+ def register
+ MSpec.register @what, self
+ end
+
+ def unregister
+ MSpec.unregister @what, self
+ end
-class RegexpFilter < MatchFilter
- def to_regexp(*strings)
- strings.map { |str| Regexp.new str }
+ def to_regexp(*regexps)
+ regexps.map { |str| Regexp.new str }
end
+ private :to_regexp
end
diff --git a/spec/mspec/lib/mspec/runner/formatters.rb b/spec/mspec/lib/mspec/runner/formatters.rb
index d085031a12..66f515ddff 100644
--- a/spec/mspec/lib/mspec/runner/formatters.rb
+++ b/spec/mspec/lib/mspec/runner/formatters.rb
@@ -7,6 +7,7 @@ require 'mspec/runner/formatters/summary'
require 'mspec/runner/formatters/unit'
require 'mspec/runner/formatters/spinner'
require 'mspec/runner/formatters/method'
+require 'mspec/runner/formatters/stats'
require 'mspec/runner/formatters/yaml'
require 'mspec/runner/formatters/profile'
require 'mspec/runner/formatters/junit'
diff --git a/spec/mspec/lib/mspec/runner/formatters/base.rb b/spec/mspec/lib/mspec/runner/formatters/base.rb
new file mode 100644
index 0000000000..6c075c4d0a
--- /dev/null
+++ b/spec/mspec/lib/mspec/runner/formatters/base.rb
@@ -0,0 +1,128 @@
+require 'mspec/expectations/expectations'
+require 'mspec/runner/actions/timer'
+require 'mspec/runner/actions/tally'
+
+if ENV['CHECK_LEAKS']
+ require 'mspec/runner/actions/leakchecker'
+ require 'mspec/runner/actions/constants_leak_checker'
+end
+
+class BaseFormatter
+ attr_reader :exceptions, :timer, :tally
+
+ def initialize(out = nil)
+ @current_state = nil
+ @exception = false
+ @failure = false
+ @exceptions = []
+
+ @count = 0 # For subclasses
+
+ if out.nil?
+ @out = $stdout
+ else
+ @out = File.open out, "w"
+ end
+ end
+
+ # Creates the +TimerAction+ and +TallyAction+ instances and registers them.
+ def register
+ (@timer = TimerAction.new).register
+ (@tally = TallyAction.new).register
+ @counter = @tally.counter
+
+ if ENV['CHECK_LEAKS']
+ save = ENV['CHECK_LEAKS'] == 'save'
+ LeakCheckerAction.new.register
+ ConstantsLeakCheckerAction.new(save).register
+ end
+
+ MSpec.register :abort, self
+ MSpec.register :before, self
+ MSpec.register :after, self
+ MSpec.register :exception, self
+ MSpec.register :finish, self
+ end
+
+ def abort
+ if @current_state
+ puts "\naborting example: #{@current_state.description}"
+ end
+ end
+
+ # Returns true if any exception is raised while running
+ # an example. This flag is reset before each example
+ # is evaluated.
+ def exception?
+ @exception
+ end
+
+ # Returns true if all exceptions during the evaluation
+ # of an example are failures rather than errors. See
+ # <tt>ExceptionState#failure</tt>. This flag is reset
+ # before each example is evaluated.
+ def failure?
+ @failure
+ end
+
+ # Callback for the MSpec :before event. Resets the
+ # +#exception?+ and +#failure+ flags.
+ def before(state = nil)
+ @current_state = state
+ @failure = @exception = false
+ end
+
+ # Callback for the MSpec :exception event. Stores the
+ # +ExceptionState+ object to generate the list of backtraces
+ # after all the specs are run. Also updates the internal
+ # +#exception?+ and +#failure?+ flags.
+ def exception(exception)
+ @count += 1
+ @failure = @exception ? @failure && exception.failure? : exception.failure?
+ @exception = true
+ @exceptions << exception
+ end
+
+ # Callback for the MSpec :after event.
+ def after(state = nil)
+ @current_state = nil
+ end
+
+ # Callback for the MSpec :start event. Calls :after event.
+ # Defined here, in the base class, and used by MultiFormatter.
+ def start
+ after
+ end
+
+ # Callback for the MSpec :unload event. Calls :after event.
+ # Defined here, in the base class, and used by MultiFormatter.
+ def unload
+ after
+ end
+
+ # Callback for the MSpec :finish event. Prints a description
+ # and backtrace for every exception that occurred while
+ # evaluating the examples.
+ def finish
+ print "\n"
+ count = 0
+ @exceptions.each do |exc|
+ count += 1
+ print_exception(exc, count)
+ end
+ print "\n#{@timer.format}\n\n#{@tally.format}\n"
+ end
+
+ def print_exception(exc, count)
+ outcome = exc.failure? ? "FAILED" : "ERROR"
+ print "\n#{count})\n#{exc.description} #{outcome}\n"
+ print exc.message, "\n"
+ print exc.backtrace, "\n"
+ end
+
+ # A convenience method to allow printing to different outputs.
+ def print(*args)
+ @out.print(*args)
+ @out.flush
+ end
+end
diff --git a/spec/mspec/lib/mspec/runner/formatters/describe.rb b/spec/mspec/lib/mspec/runner/formatters/describe.rb
index 176bd79279..fc4122d13b 100644
--- a/spec/mspec/lib/mspec/runner/formatters/describe.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/describe.rb
@@ -1,5 +1,4 @@
require 'mspec/runner/formatters/dotted'
-require 'mspec/runner/actions/tally'
class DescribeFormatter < DottedFormatter
# Callback for the MSpec :finish event. Prints a summary of
diff --git a/spec/mspec/lib/mspec/runner/formatters/dotted.rb b/spec/mspec/lib/mspec/runner/formatters/dotted.rb
index 61c8e4c27c..672cdf81dc 100644
--- a/spec/mspec/lib/mspec/runner/formatters/dotted.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/dotted.rb
@@ -1,77 +1,9 @@
-require 'mspec/expectations/expectations'
-require 'mspec/runner/actions/timer'
-require 'mspec/runner/actions/tally'
-require 'mspec/runner/actions/leakchecker' if ENV['CHECK_LEAKS']
+require 'mspec/runner/formatters/base'
-class DottedFormatter
- attr_reader :exceptions, :timer, :tally
-
- def initialize(out=nil)
- @exception = @failure = false
- @exceptions = []
- @count = 0 # For subclasses
- if out.nil?
- @out = $stdout
- else
- @out = File.open out, "w"
- end
-
- @current_state = nil
- end
-
- # Creates the +TimerAction+ and +TallyAction+ instances and
- # registers them. Registers +self+ for the +:exception+,
- # +:before+, +:after+, and +:finish+ actions.
+class DottedFormatter < BaseFormatter
def register
- (@timer = TimerAction.new).register
- (@tally = TallyAction.new).register
- LeakCheckerAction.new.register if ENV['CHECK_LEAKS']
- @counter = @tally.counter
-
- MSpec.register :exception, self
- MSpec.register :before, self
- MSpec.register :after, self
- MSpec.register :finish, self
- MSpec.register :abort, self
- end
-
- def abort
- if @current_state
- puts "\naborting example: #{@current_state.description}"
- end
- end
-
- # Returns true if any exception is raised while running
- # an example. This flag is reset before each example
- # is evaluated.
- def exception?
- @exception
- end
-
- # Returns true if all exceptions during the evaluation
- # of an example are failures rather than errors. See
- # <tt>ExceptionState#failure</tt>. This flag is reset
- # before each example is evaluated.
- def failure?
- @failure
- end
-
- # Callback for the MSpec :before event. Resets the
- # +#exception?+ and +#failure+ flags.
- def before(state=nil)
- @current_state = state
- @failure = @exception = false
- end
-
- # Callback for the MSpec :exception event. Stores the
- # +ExceptionState+ object to generate the list of backtraces
- # after all the specs are run. Also updates the internal
- # +#exception?+ and +#failure?+ flags.
- def exception(exception)
- @count += 1
- @failure = @exception ? @failure && exception.failure? : exception.failure?
- @exception = true
- @exceptions << exception
+ super
+ MSpec.register :after, self
end
# Callback for the MSpec :after event. Prints an indicator
@@ -80,38 +12,12 @@ class DottedFormatter
# F = An SpecExpectationNotMetError was raised
# E = Any exception other than SpecExpectationNotMetError
def after(state = nil)
- @current_state = nil
+ super(state)
- unless exception?
- print "."
- else
+ if exception?
print failure? ? "F" : "E"
+ else
+ print "."
end
end
-
- # Callback for the MSpec :finish event. Prints a description
- # and backtrace for every exception that occurred while
- # evaluating the examples.
- def finish
- print "\n"
- count = 0
- @exceptions.each do |exc|
- count += 1
- print_exception(exc, count)
- end
- print "\n#{@timer.format}\n\n#{@tally.format}\n"
- end
-
- def print_exception(exc, count)
- outcome = exc.failure? ? "FAILED" : "ERROR"
- print "\n#{count})\n#{exc.description} #{outcome}\n"
- print exc.message, "\n"
- print exc.backtrace, "\n"
- end
-
- # A convenience method to allow printing to different outputs.
- def print(*args)
- @out.print(*args)
- @out.flush
- end
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/file.rb b/spec/mspec/lib/mspec/runner/formatters/file.rb
index 6db72af4ff..65cfb1f75b 100644
--- a/spec/mspec/lib/mspec/runner/formatters/file.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/file.rb
@@ -14,6 +14,11 @@ class FileFormatter < DottedFormatter
MSpec.register :unload, self
end
- alias_method :load, :before
- alias_method :unload, :after
+ def load(state = nil)
+ before(state)
+ end
+
+ def unload(state = nil)
+ after(state)
+ end
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/html.rb b/spec/mspec/lib/mspec/runner/formatters/html.rb
index fd64cd0d20..e37e89a088 100644
--- a/spec/mspec/lib/mspec/runner/formatters/html.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/html.rb
@@ -1,7 +1,6 @@
-require 'mspec/expectations/expectations'
-require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/formatters/base'
-class HtmlFormatter < DottedFormatter
+class HtmlFormatter < BaseFormatter
def register
super
MSpec.register :start, self
@@ -44,13 +43,14 @@ EOH
end
def exception(exception)
- super
+ super(exception)
outcome = exception.failure? ? "FAILED" : "ERROR"
print %[<li class="fail">- #{exception.it} (<a href="#details-#{@count}">]
print %[#{outcome} - #{@count}</a>)</li>\n]
end
- def after(state)
+ def after(state = nil)
+ super(state)
print %[<li class="pass">- #{state.it}</li>\n] unless exception?
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/junit.rb b/spec/mspec/lib/mspec/runner/formatters/junit.rb
index 76d46c2414..12e43a3263 100644
--- a/spec/mspec/lib/mspec/runner/formatters/junit.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/junit.rb
@@ -1,19 +1,18 @@
-require 'mspec/expectations/expectations'
require 'mspec/runner/formatters/yaml'
class JUnitFormatter < YamlFormatter
- def initialize(out=nil)
- super
+ def initialize(out = nil)
+ super(out)
@tests = []
end
def after(state = nil)
- super
+ super(state)
@tests << {:test => state, :exception => false} unless exception?
end
def exception(exception)
- super
+ super(exception)
@tests << {:test => exception, :exception => true}
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/method.rb b/spec/mspec/lib/mspec/runner/formatters/method.rb
index ff115193fd..925858c845 100644
--- a/spec/mspec/lib/mspec/runner/formatters/method.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/method.rb
@@ -1,18 +1,18 @@
-require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/formatters/base'
-class MethodFormatter < DottedFormatter
+class MethodFormatter < BaseFormatter
attr_accessor :methods
- def initialize(out=nil)
- super
+ def initialize(out = nil)
+ super(out)
@methods = Hash.new do |h, k|
- hash = {}
- hash[:examples] = 0
- hash[:expectations] = 0
- hash[:failures] = 0
- hash[:errors] = 0
- hash[:exceptions] = []
- h[k] = hash
+ h[k] = {
+ examples: 0,
+ expectations: 0,
+ failures: 0,
+ errors: 0,
+ exceptions: []
+ }
end
end
@@ -34,7 +34,7 @@ class MethodFormatter < DottedFormatter
# Resets the tallies so the counts are only for this
# example.
def before(state)
- super
+ super(state)
# The pattern for a method name is not correctly
# restrictive but it is simplistic and useful
@@ -60,7 +60,9 @@ class MethodFormatter < DottedFormatter
# Callback for the MSpec :after event. Sets or adds to
# tallies for the example block.
- def after(state)
+ def after(state = nil)
+ super(state)
+
h = methods[@key]
h[:examples] += tally.counter.examples
h[:expectations] += tally.counter.expectations
diff --git a/spec/mspec/lib/mspec/runner/formatters/multi.rb b/spec/mspec/lib/mspec/runner/formatters/multi.rb
index f69055025f..a723ae8eb9 100644
--- a/spec/mspec/lib/mspec/runner/formatters/multi.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/multi.rb
@@ -1,13 +1,24 @@
-require 'mspec/runner/formatters/spinner'
+module MultiFormatter
+ def self.extend_object(obj)
+ super
+ obj.multi_initialize
+ end
-class MultiFormatter < SpinnerFormatter
- def initialize(out=nil)
- super(out)
- @counter = @tally = Tally.new
+ def multi_initialize
+ @tally = TallyAction.new
+ @counter = @tally.counter
@timer = TimerAction.new
@timer.start
end
+ def register
+ super
+
+ MSpec.register :start, self
+ MSpec.register :unload, self
+ MSpec.unregister :before, self
+ end
+
def aggregate_results(files)
require 'yaml'
@@ -15,23 +26,22 @@ class MultiFormatter < SpinnerFormatter
@exceptions = []
files.each do |file|
- d = File.open(file, "r") { |f| YAML.load f }
+ contents = File.read(file)
+ d = YAML.load(contents)
File.delete file
- @exceptions += Array(d['exceptions'])
- @tally.files! d['files']
- @tally.examples! d['examples']
- @tally.expectations! d['expectations']
- @tally.errors! d['errors']
- @tally.failures! d['failures']
+ if d # The file might be empty if the child process died
+ @exceptions += Array(d['exceptions'])
+ @counter.files! d['files']
+ @counter.examples! d['examples']
+ @counter.expectations! d['expectations']
+ @counter.errors! d['errors']
+ @counter.failures! d['failures']
+ end
end
end
def print_exception(exc, count)
print "\n#{count})\n#{exc}\n"
end
-
- def finish
- super(false)
- end
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/profile.rb b/spec/mspec/lib/mspec/runner/formatters/profile.rb
index 498cd4a3b7..38ef5b12ed 100644
--- a/spec/mspec/lib/mspec/runner/formatters/profile.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/profile.rb
@@ -1,9 +1,9 @@
-require 'mspec/expectations/expectations'
require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/actions/profile'
class ProfileFormatter < DottedFormatter
- def initialize(out=nil)
- super
+ def initialize(out = nil)
+ super(out)
@describe_name = nil
@describe_time = nil
@@ -12,59 +12,7 @@ class ProfileFormatter < DottedFormatter
end
def register
- super
- MSpec.register :enter, self
- end
-
- # Callback for the MSpec :enter event. Prints the
- # +describe+ block string.
- def enter(describe)
- if @describe_time
- @describes << [@describe_name, Time.now.to_f - @describe_time]
- end
-
- @describe_name = describe
- @describe_time = Time.now.to_f
- end
-
- # Callback for the MSpec :before event. Prints the
- # +it+ block string.
- def before(state)
- super
-
- @it_name = state.it
- @it_time = Time.now.to_f
- end
-
- # Callback for the MSpec :after event. Prints a
- # newline to finish the description string output.
- def after(state)
- @its << [@describe_name, @it_name, Time.now.to_f - @it_time]
- super
- end
-
- def finish
- puts "\nProfiling info:"
-
- desc = @describes.sort { |a,b| b.last <=> a.last }
- desc.delete_if { |a| a.last <= 0.001 }
- show = desc[0, 100]
-
- puts "Top #{show.size} describes:"
-
- show.each do |des, time|
- printf "%3.3f - %s\n", time, des
- end
-
- its = @its.sort { |a,b| b.last <=> a.last }
- its.delete_if { |a| a.last <= 0.001 }
- show = its[0, 100]
-
- puts "\nTop #{show.size} its:"
- show.each do |des, it, time|
- printf "%3.3f - %s %s\n", time, des, it
- end
-
+ (@profile = ProfileAction.new).register
super
end
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/specdoc.rb b/spec/mspec/lib/mspec/runner/formatters/specdoc.rb
index 29adde3c5c..d3a5c3d729 100644
--- a/spec/mspec/lib/mspec/runner/formatters/specdoc.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/specdoc.rb
@@ -1,7 +1,6 @@
-require 'mspec/expectations/expectations'
-require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/formatters/base'
-class SpecdocFormatter < DottedFormatter
+class SpecdocFormatter < BaseFormatter
def register
super
MSpec.register :enter, self
@@ -16,7 +15,7 @@ class SpecdocFormatter < DottedFormatter
# Callback for the MSpec :before event. Prints the
# +it+ block string.
def before(state)
- super
+ super(state)
print "- #{state.it}"
end
@@ -25,17 +24,18 @@ class SpecdocFormatter < DottedFormatter
# the sequential number of the exception raised. If
# there has already been an exception raised while
# evaluating this example, it prints another +it+
- # block description string so that each discription
+ # block description string so that each description
# string has an associated 'ERROR' or 'FAILED'
def exception(exception)
print "\n- #{exception.it}" if exception?
- super
+ super(exception)
print " (#{exception.failure? ? 'FAILED' : 'ERROR'} - #{@count})"
end
# Callback for the MSpec :after event. Prints a
# newline to finish the description string output.
- def after(state)
+ def after(state = nil)
+ super(state)
print "\n"
end
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/spinner.rb b/spec/mspec/lib/mspec/runner/formatters/spinner.rb
index f6f35cc476..817d8c02be 100644
--- a/spec/mspec/lib/mspec/runner/formatters/spinner.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/spinner.rb
@@ -1,14 +1,13 @@
-require 'mspec/expectations/expectations'
-require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/formatters/base'
-class SpinnerFormatter < DottedFormatter
+class SpinnerFormatter < BaseFormatter
attr_reader :length
Spins = %w!| / - \\!
HOUR = 3600
MIN = 60
- def initialize(out=nil)
+ def initialize(out = nil)
super(nil)
@which = 0
@@ -28,7 +27,6 @@ class SpinnerFormatter < DottedFormatter
MSpec.register :start, self
MSpec.register :unload, self
- MSpec.unregister :before, self
end
def length=(length)
@@ -80,7 +78,7 @@ class SpinnerFormatter < DottedFormatter
# Callback for the MSpec :start event. Stores the total
# number of files that will be processed.
def start
- @total = MSpec.retrieve(:files).size
+ @total = MSpec.files_array.size
compute_progress
print progress_line
end
@@ -102,16 +100,12 @@ class SpinnerFormatter < DottedFormatter
clear_progress_line
print_exception(exception, @count)
+ exceptions.clear
end
# Callback for the MSpec :after event. Updates the spinner.
- def after(state)
+ def after(state = nil)
+ super(state)
print progress_line
end
-
- def finish(printed_exceptions = true)
- # We already printed the exceptions
- @exceptions = [] if printed_exceptions
- super()
- end
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/stats.rb b/spec/mspec/lib/mspec/runner/formatters/stats.rb
new file mode 100644
index 0000000000..8cff96d145
--- /dev/null
+++ b/spec/mspec/lib/mspec/runner/formatters/stats.rb
@@ -0,0 +1,57 @@
+require 'mspec/runner/formatters/base'
+
+class StatsPerFileFormatter < BaseFormatter
+ def initialize(out = nil)
+ super(out)
+ @data = {}
+ @root = File.expand_path(MSpecScript.get(:prefix) || '.')
+ end
+
+ def register
+ super
+ MSpec.register :load, self
+ MSpec.register :unload, self
+ end
+
+ # Resets the tallies so the counts are only for this file.
+ def load
+ tally.counter.examples = 0
+ tally.counter.errors = 0
+ tally.counter.failures = 0
+ tally.counter.tagged = 0
+ end
+
+ def unload
+ file = format_file MSpec.file
+
+ raise if @data.key?(file)
+ @data[file] = {
+ examples: tally.counter.examples,
+ errors: tally.counter.errors,
+ failures: tally.counter.failures,
+ tagged: tally.counter.tagged,
+ }
+ end
+
+ def finish
+ width = @data.keys.max_by(&:size).size
+ f = "%3d"
+ @data.each_pair do |file, data|
+ total = data[:examples]
+ passing = total - data[:errors] - data[:failures] - data[:tagged]
+ puts "#{file.ljust(width)} #{f % passing}/#{f % total}"
+ end
+
+ require 'yaml'
+ yaml = YAML.dump(@data)
+ File.write "results-#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}.yml", yaml
+ end
+
+ private def format_file(file)
+ if file.start_with?(@root)
+ file[@root.size+1..-1]
+ else
+ raise file
+ end
+ end
+end
diff --git a/spec/mspec/lib/mspec/runner/formatters/summary.rb b/spec/mspec/lib/mspec/runner/formatters/summary.rb
index 0c9207194c..41819d2158 100644
--- a/spec/mspec/lib/mspec/runner/formatters/summary.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/summary.rb
@@ -1,11 +1,4 @@
-require 'mspec/expectations/expectations'
-require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/formatters/base'
-class SummaryFormatter < DottedFormatter
- # Callback for the MSpec :after event. Overrides the
- # callback provided by +DottedFormatter+ and does not
- # print any output for each example evaluated.
- def after(state)
- # do nothing
- end
+class SummaryFormatter < BaseFormatter
end
diff --git a/spec/mspec/lib/mspec/runner/formatters/unit.rb b/spec/mspec/lib/mspec/runner/formatters/unit.rb
index cebc18a49b..d03ae79e9f 100644
--- a/spec/mspec/lib/mspec/runner/formatters/unit.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/unit.rb
@@ -1,4 +1,3 @@
-require 'mspec/expectations/expectations'
require 'mspec/runner/formatters/dotted'
class UnitdiffFormatter < DottedFormatter
diff --git a/spec/mspec/lib/mspec/runner/formatters/yaml.rb b/spec/mspec/lib/mspec/runner/formatters/yaml.rb
index 090a9b1b9d..6c05cc902f 100644
--- a/spec/mspec/lib/mspec/runner/formatters/yaml.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/yaml.rb
@@ -1,8 +1,7 @@
-require 'mspec/expectations/expectations'
-require 'mspec/runner/formatters/dotted'
+require 'mspec/runner/formatters/base'
-class YamlFormatter < DottedFormatter
- def initialize(out=nil)
+class YamlFormatter < BaseFormatter
+ def initialize(out = nil)
super(nil)
if out.nil?
@@ -16,9 +15,6 @@ class YamlFormatter < DottedFormatter
@out = @finish
end
- def after(state)
- end
-
def finish
switch
diff --git a/spec/mspec/lib/mspec/runner/mspec.rb b/spec/mspec/lib/mspec/runner/mspec.rb
index d47657326b..8331086196 100644
--- a/spec/mspec/lib/mspec/runner/mspec.rb
+++ b/spec/mspec/lib/mspec/runner/mspec.rb
@@ -10,7 +10,6 @@ class MSpecEnv
end
module MSpec
-
@exit = nil
@abort = nil
@start = nil
@@ -20,8 +19,8 @@ module MSpec
@after = nil
@leave = nil
@finish = nil
- @exclude = nil
- @include = nil
+ @exclude = []
+ @include = []
@leave = nil
@load = nil
@unload = nil
@@ -33,13 +32,19 @@ module MSpec
@guarded = []
@features = {}
@exception = nil
- @randomize = nil
- @repeat = nil
+ @randomize = false
+ @repeat = 1
@expectation = nil
@expectations = false
- def self.describe(mod, options=nil, &block)
- state = ContextState.new mod, options
+ class << self
+ attr_reader :file, :include, :exclude
+ attr_writer :repeat, :randomize
+ attr_accessor :formatter
+ end
+
+ def self.describe(description, options = nil, &block)
+ state = ContextState.new description, options
state.parent = current
MSpec.register_current state
@@ -50,17 +55,21 @@ module MSpec
def self.process
STDOUT.puts RUBY_DESCRIPTION
+ STDOUT.flush
actions :start
files
actions :finish
end
+ def self.files_array
+ @files
+ end
+
def self.each_file(&block)
if ENV["MSPEC_MULTI"]
- STDOUT.print "."
- STDOUT.flush
- while file = STDIN.gets and file = file.chomp
+ while file = STDIN.gets
+ file = file.chomp
return if file == "QUIT"
yield file
begin
@@ -74,7 +83,7 @@ module MSpec
# The parent closed the connection without QUIT
abort "the parent did not send QUIT"
else
- return unless files = retrieve(:files)
+ return unless files = @files
shuffle files if randomize?
files.each(&block)
end
@@ -83,10 +92,11 @@ module MSpec
def self.files
each_file do |file|
setup_env
- store :file, file
+ @file = file
actions :load
protect("loading #{file}") { Kernel.load file }
actions :unload
+ raise "#{file} was executed but did not reset the current example: #{@current}" if @current
end
end
@@ -101,10 +111,12 @@ module MSpec
def self.protect(location, &block)
begin
- @env.instance_eval(&block)
+ @env.instance_exec(&block)
return true
rescue SystemExit => e
raise e
+ rescue SkippedSpecError => e
+ return false
rescue Exception => exc
register_exit 1
actions :exception, ExceptionState.new(current && current.state, location, exc)
@@ -128,22 +140,24 @@ module MSpec
# Sets the toplevel ContextState to +state+.
def self.register_current(state)
- store :current, state
+ @current = state
end
# Sets the toplevel ContextState to +nil+.
def self.clear_current
- store :current, nil
+ @current = nil
end
# Returns the toplevel ContextState.
def self.current
- retrieve :current
+ @current
end
# Stores the shared ContextState keyed by description.
def self.register_shared(state)
- @shared[state.to_s] = state
+ name = state.to_s
+ raise "duplicated shared #describe: #{name}" if @shared.key?(name)
+ @shared[name] = state
end
# Returns the shared ContextState matching description.
@@ -153,17 +167,17 @@ module MSpec
# Stores the exit code used by the runner scripts.
def self.register_exit(code)
- store :exit, code
+ @exit = code
end
# Retrieves the stored exit code.
def self.exit_code
- retrieve(:exit).to_i
+ @exit.to_i
end
# Stores the list of files to be evaluated.
def self.register_files(files)
- store :files, files
+ @files = files
end
# Stores one or more substitution patterns for transforming
@@ -174,7 +188,7 @@ module MSpec
#
# See also +tags_file+.
def self.register_tags_patterns(patterns)
- store :tags_patterns, patterns
+ @tags_patterns = patterns
end
# Registers an operating mode. Modes recognized by MSpec:
@@ -185,30 +199,30 @@ module MSpec
# :report - specs that are guarded are reported
# :unguarded - all guards are forced off
def self.register_mode(mode)
- modes = retrieve :modes
+ modes = @modes
modes << mode unless modes.include? mode
end
# Clears all registered modes.
def self.clear_modes
- store :modes, []
+ @modes = []
end
# Returns +true+ if +mode+ is registered.
def self.mode?(mode)
- retrieve(:modes).include? mode
+ @modes.include? mode
end
def self.enable_feature(feature)
- retrieve(:features)[feature] = true
+ @features[feature] = true
end
def self.disable_feature(feature)
- retrieve(:features)[feature] = false
+ @features[feature] = false
end
def self.feature_enabled?(feature)
- retrieve(:features)[feature] || false
+ @features[feature] || false
end
def self.retrieve(symbol)
@@ -257,21 +271,17 @@ module MSpec
end
end
- def self.randomize(flag=true)
- @randomize = flag
- end
-
def self.randomize?
- @randomize == true
- end
-
- def self.repeat=(times)
- @repeat = times
+ @randomize
end
def self.repeat
- (@repeat || 1).times do
+ if @repeat == 1
yield
+ else
+ @repeat.times do
+ yield
+ end
end
end
@@ -287,17 +297,17 @@ module MSpec
# Records that an expectation has been encountered in an example.
def self.expectation
- store :expectations, true
+ @expectations = true
end
# Returns true if an expectation has been encountered
def self.expectation?
- retrieve :expectations
+ @expectations
end
# Resets the flag that an expectation has been encountered in an example.
def self.clear_expectations
- store :expectations, false
+ @expectations = false
end
# Transforms a spec filename into a tags filename by applying each
@@ -311,9 +321,9 @@ module MSpec
#
# See also +register_tags_patterns+.
def self.tags_file
- patterns = retrieve(:tags_patterns) ||
+ patterns = @tags_patterns ||
[[%r(spec/), 'spec/tags/'], [/_spec.rb$/, '_tags.txt']]
- patterns.inject(retrieve(:file).dup) do |file, pattern|
+ patterns.inject(@file.dup) do |file, pattern|
file.gsub(*pattern)
end
end
diff --git a/spec/mspec/lib/mspec/runner/object.rb b/spec/mspec/lib/mspec/runner/object.rb
index 2ea8197165..58d98cc4df 100644
--- a/spec/mspec/lib/mspec/runner/object.rb
+++ b/spec/mspec/lib/mspec/runner/object.rb
@@ -1,18 +1,18 @@
class Object
- private def before(at=:each, &block)
+ private def before(at = :each, &block)
MSpec.current.before at, &block
end
- private def after(at=:each, &block)
+ private def after(at = :each, &block)
MSpec.current.after at, &block
end
- private def describe(mod, msg=nil, options=nil, &block)
- MSpec.describe mod, msg, &block
+ private def describe(description, options = nil, &block)
+ MSpec.describe description, options, &block
end
- private def it(msg, &block)
- MSpec.current.it msg, &block
+ private def it(desc, &block)
+ MSpec.current.it desc, &block
end
private def it_should_behave_like(desc)
diff --git a/spec/mspec/lib/mspec/runner/parallel.rb b/spec/mspec/lib/mspec/runner/parallel.rb
new file mode 100644
index 0000000000..6a9ecd155d
--- /dev/null
+++ b/spec/mspec/lib/mspec/runner/parallel.rb
@@ -0,0 +1,98 @@
+class ParallelRunner
+ def initialize(files, processes, formatter, argv)
+ @files = files
+ @processes = processes
+ @formatter = formatter
+ @argv = argv
+ @last_files = {}
+ @output_files = []
+ @success = true
+ end
+
+ def launch_children
+ @children = @processes.times.map { |i|
+ name = tmp "mspec-multi-#{i}"
+ @output_files << name
+
+ env = {
+ "SPEC_TEMP_DIR" => "#{SPEC_TEMP_DIR}_#{i}",
+ "MSPEC_MULTI" => i.to_s
+ }
+ command = @argv + ["-fy", "-o", name]
+ $stderr.puts "$ #{command.join(' ')}" if $MSPEC_DEBUG
+ IO.popen([env, *command, close_others: false], "rb+")
+ }
+ end
+
+ def handle(child, message)
+ case message
+ when '.'
+ @formatter.unload
+ send_new_file_or_quit(child)
+ else
+ if message == nil
+ msg = "A child mspec-run process died unexpectedly"
+ else
+ msg = "A child mspec-run process printed unexpected output on STDOUT"
+ while chunk = (child.read_nonblock(4096) rescue nil)
+ message += chunk
+ end
+ message.chomp!('.')
+ msg += ": #{message.inspect}"
+ end
+
+ if last_file = @last_files[child]
+ msg += " while running #{last_file}"
+ end
+
+ @success = false
+ quit(child)
+ abort "\n#{msg}"
+ end
+ end
+
+ def quit(child)
+ begin
+ child.puts "QUIT"
+ rescue Errno::EPIPE
+ # The child process already died
+ end
+ _pid, status = Process.wait2(child.pid)
+ @success &&= status.success?
+ child.close
+ @children.delete(child)
+ end
+
+ def send_new_file_or_quit(child)
+ if @files.empty?
+ quit(child)
+ else
+ file = @files.shift
+ @last_files[child] = file
+ child.puts file
+ end
+ end
+
+ def run
+ MSpec.register_files @files
+ launch_children
+
+ puts @children.map { |child| child.gets }.uniq
+ @formatter.start
+ begin
+ @children.each { |child| send_new_file_or_quit(child) }
+
+ until @children.empty?
+ IO.select(@children)[0].each { |child|
+ handle(child, child.read(1))
+ }
+ end
+ ensure
+ @children.dup.each { |child| quit(child) }
+ @formatter.aggregate_results(@output_files)
+ @formatter.finish
+ end
+
+ @success
+ end
+end
diff --git a/spec/mspec/lib/mspec/runner/shared.rb b/spec/mspec/lib/mspec/runner/shared.rb
index b606de473b..1d68365474 100644
--- a/spec/mspec/lib/mspec/runner/shared.rb
+++ b/spec/mspec/lib/mspec/runner/shared.rb
@@ -1,6 +1,6 @@
require 'mspec/runner/mspec'
-def it_behaves_like(desc, meth, obj=nil)
+def it_behaves_like(desc, meth, obj = nil)
send :before, :all do
@method = meth
@object = obj
diff --git a/spec/mspec/lib/mspec/runner/tag.rb b/spec/mspec/lib/mspec/runner/tag.rb
index e2275ad3a6..820df9159e 100644
--- a/spec/mspec/lib/mspec/runner/tag.rb
+++ b/spec/mspec/lib/mspec/runner/tag.rb
@@ -1,7 +1,7 @@
class SpecTag
attr_accessor :tag, :comment, :description
- def initialize(string=nil)
+ def initialize(string = nil)
parse(string) if string
end
diff --git a/spec/mspec/lib/mspec/utils/format.rb b/spec/mspec/lib/mspec/utils/format.rb
new file mode 100644
index 0000000000..425dd4d11c
--- /dev/null
+++ b/spec/mspec/lib/mspec/utils/format.rb
@@ -0,0 +1,24 @@
+# If the implementation on which the specs are run cannot
+# load pp from the standard library, add a pp.rb file that
+# defines the #pretty_inspect method on Object or Kernel.
+begin
+ require 'pp'
+rescue LoadError
+ module Kernel
+ def pretty_inspect
+ inspect
+ end
+ end
+end
+
+module MSpec
+ def self.format(obj)
+ if String === obj and obj.include?("\n")
+ "\n#{obj.inspect.gsub('\n', "\n")}"
+ else
+ obj.pretty_inspect.chomp
+ end
+ rescue => e
+ "#<#{obj.class}>(#pretty_inspect raised #{e.inspect})"
+ end
+end
diff --git a/spec/mspec/lib/mspec/utils/name_map.rb b/spec/mspec/lib/mspec/utils/name_map.rb
index c1de081af0..a389b9d1de 100644
--- a/spec/mspec/lib/mspec/utils/name_map.rb
+++ b/spec/mspec/lib/mspec/utils/name_map.rb
@@ -8,10 +8,9 @@ class NameMap
'*' => 'multiply',
'/' => 'divide',
'%' => 'modulo',
- '<<' => {'Bignum' => 'left_shift',
- 'Fixnum' => 'left_shift',
- 'IO' => 'output',
- :default => 'append' },
+ '<<' => {'Integer' => 'left_shift',
+ 'IO' => 'output',
+ :default => 'append' },
'>>' => 'right_shift',
'<' => 'lt',
'<=' => 'lte',
@@ -25,33 +24,22 @@ class NameMap
'[]=' => 'element_set',
'**' => 'exponent',
'!' => 'not',
- '~' => {'Bignum' => 'complement',
- 'Fixnum' => 'complement',
- 'Regexp' => 'match',
- 'String' => 'match' },
+ '~' => {'Integer' => 'complement',
+ :default => 'match' },
'!=' => 'not_equal',
'!~' => 'not_match',
'=~' => 'match',
- '&' => {'Bignum' => 'bit_and',
- 'Fixnum' => 'bit_and',
+ '&' => {'Integer' => 'bit_and',
'Array' => 'intersection',
- 'TrueClass' => 'and',
- 'FalseClass' => 'and',
- 'NilClass' => 'and',
- 'Set' => 'intersection' },
- '|' => {'Bignum' => 'bit_or',
- 'Fixnum' => 'bit_or',
+ 'Set' => 'intersection',
+ :default => 'and' },
+ '|' => {'Integer' => 'bit_or',
'Array' => 'union',
- 'TrueClass' => 'or',
- 'FalseClass' => 'or',
- 'NilClass' => 'or',
- 'Set' => 'union' },
- '^' => {'Bignum' => 'bit_xor',
- 'Fixnum' => 'bit_xor',
- 'TrueClass' => 'xor',
- 'FalseClass' => 'xor',
- 'NilClass' => 'xor',
- 'Set' => 'exclusion'},
+ 'Set' => 'union',
+ :default => 'or' },
+ '^' => {'Integer' => 'bit_xor',
+ 'Set' => 'exclusion',
+ :default => 'xor' },
}
EXCLUDED = %w[
@@ -63,7 +51,7 @@ class NameMap
SpecVersion
]
- def initialize(filter=false)
+ def initialize(filter = false)
@seen = {}
@filter = filter
end
@@ -85,7 +73,7 @@ class NameMap
"#{mod}::#{const}"
end
- def map(hash, constants, mod=nil)
+ def map(hash, constants, mod = nil)
@seen = {} unless mod
constants.each do |const|
@@ -119,7 +107,12 @@ class NameMap
def file_name(m, c)
if MAP.key?(m)
- name = MAP[m].is_a?(Hash) ? MAP[m][c.split('::').last] || MAP[m][:default] : MAP[m]
+ mapping = MAP[m]
+ if mapping.is_a?(Hash)
+ name = mapping[c.split('::').last] || mapping.fetch(:default)
+ else
+ name = mapping
+ end
else
name = m.gsub(/[?!=]/, '')
end
diff --git a/spec/mspec/lib/mspec/utils/options.rb b/spec/mspec/lib/mspec/utils/options.rb
index 9f8dd01dbf..bef1dbdd2e 100644
--- a/spec/mspec/lib/mspec/utils/options.rb
+++ b/spec/mspec/lib/mspec/utils/options.rb
@@ -34,7 +34,7 @@ class MSpecOptions
attr_accessor :config, :banner, :width, :options
- def initialize(banner="", width=30, config=nil)
+ def initialize(banner = "", width = 30, config = nil)
@banner = banner
@config = config
@width = width
@@ -94,7 +94,7 @@ class MSpecOptions
@options.find { |o| o.match? opt }
end
- # Processes an option. Calles the #on_extra block (or default) for
+ # Processes an option. Calls the #on_extra block (or default) for
# unrecognized options. For registered options, possibly fetches an
# argument and invokes the option's block if it is not nil.
def process(argv, entry, opt, arg)
@@ -123,7 +123,7 @@ class MSpecOptions
# Parses an array of command line entries, calling blocks for
# registered options.
- def parse(argv=ARGV)
+ def parse(argv = ARGV)
argv = Array(argv).dup
while entry = argv.shift
@@ -274,6 +274,8 @@ class MSpecOptions
config[:formatter] = SpinnerFormatter
when 't', 'method'
config[:formatter] = MethodFormatter
+ when 'e', 'stats'
+ config[:formatter] = StatsPerFileFormatter
when 'y', 'yaml'
config[:formatter] = YamlFormatter
when 'p', 'profile'
@@ -281,7 +283,7 @@ class MSpecOptions
when 'j', 'junit'
config[:formatter] = JUnitFormatter
else
- abort "Unknown format: #{o}\n#{@parser}" unless File.exist?(o)
+ abort "Unknown format: #{o}" unless File.exist?(o)
require File.expand_path(o)
if Object.const_defined?(:CUSTOM_MSPEC_FORMATTER)
config[:formatter] = CUSTOM_MSPEC_FORMATTER
@@ -300,6 +302,7 @@ class MSpecOptions
doc " m, summary SummaryFormatter"
doc " a, *, spin SpinnerFormatter"
doc " t, method MethodFormatter"
+ doc " e, stats StatsPerFileFormatter"
doc " y, yaml YamlFormatter"
doc " p, profile ProfileFormatter"
doc " j, junit JUnitFormatter\n"
@@ -377,14 +380,14 @@ class MSpecOptions
def randomize
on("-H", "--random",
"Randomize the list of spec files") do
- MSpec.randomize
+ MSpec.randomize = true
end
end
def repeat
on("-R", "--repeat", "NUMBER",
"Repeatedly run an example NUMBER times") do |o|
- MSpec.repeat = o.to_i
+ MSpec.repeat = Integer(o)
end
end
@@ -392,11 +395,11 @@ class MSpecOptions
on("-V", "--verbose", "Output the name of each file processed") do
obj = Object.new
def obj.start
- @width = MSpec.retrieve(:files).inject(0) { |max, f| f.size > max ? f.size : max }
+ @width = MSpec.files_array.inject(0) { |max, f| f.size > max ? f.size : max }
end
def obj.load
- file = MSpec.retrieve :file
- STDERR.print "\n#{file.ljust(@width)}"
+ file = MSpec.file
+ STDERR.print "\n#{file.ljust(@width)}\n"
end
MSpec.register :start, obj
MSpec.register :load, obj
@@ -414,11 +417,19 @@ class MSpecOptions
end
def interrupt
- on("--int-spec", "Control-C interupts the current spec only") do
+ on("--int-spec", "Control-C interrupts the current spec only") do
config[:abort] = false
end
end
+ def timeout
+ on("--timeout", "TIMEOUT", "Abort if a spec takes longer than TIMEOUT seconds") do |timeout|
+ require 'mspec/runner/actions/timeout'
+ timeout = Float(timeout)
+ TimeoutAction.new(timeout).register
+ end
+ end
+
def verify
on("--report-on", "GUARD", "Report specs guarded by GUARD") do |g|
MSpec.register_mode :report_on
@@ -459,8 +470,6 @@ class MSpecOptions
end
def all
- # Generated with:
- # puts File.read(__FILE__).scan(/def (\w+).*\n\s*on\(/)
configure {}
targets
formatters
@@ -473,6 +482,7 @@ class MSpecOptions
repeat
verbose
interrupt
+ timeout
verify
action_filters
actions
diff --git a/spec/mspec/lib/mspec/utils/script.rb b/spec/mspec/lib/mspec/utils/script.rb
index 0c8922c4a8..e3478ef7b0 100644
--- a/spec/mspec/lib/mspec/utils/script.rb
+++ b/spec/mspec/lib/mspec/utils/script.rb
@@ -1,8 +1,8 @@
require 'mspec/guards/guard'
+require 'mspec/guards/version'
require 'mspec/utils/warnings'
# MSpecScript provides a skeleton for all the MSpec runner scripts.
-
class MSpecScript
# Returns the config object. Maintained at the class
# level to easily enable simple config files. See the
@@ -38,8 +38,8 @@ class MSpecScript
end
def initialize
- if RUBY_VERSION < '2.2'
- abort "MSpec needs Ruby 2.2 or more recent"
+ ruby_version_is ""..."2.5" do
+ abort "MSpec needs Ruby 2.5 or more recent"
end
config[:formatter] = nil
@@ -124,14 +124,9 @@ class MSpecScript
require 'mspec/runner/formatters/file'
require 'mspec/runner/filters'
- if config[:formatter].nil?
- config[:formatter] = STDOUT.tty? ? SpinnerFormatter : @files.size < 50 ? DottedFormatter : FileFormatter
- end
-
- if config[:formatter]
- formatter = config[:formatter].new(config[:output])
+ if formatter = config_formatter
formatter.register
- MSpec.store :formatter, formatter
+ MSpec.formatter = formatter
end
MatchFilter.new(:include, *config[:includes]).register unless config[:includes].empty?
@@ -148,6 +143,17 @@ class MSpecScript
custom_register
end
+ # Makes a formatter specified by :formatter option.
+ def config_formatter
+ if config[:formatter].nil?
+ config[:formatter] = STDOUT.tty? ? SpinnerFormatter : @files.size < 50 ? DottedFormatter : FileFormatter
+ end
+
+ if config[:formatter]
+ config[:formatter].new(config[:output])
+ end
+ end
+
# Callback for enabling custom actions, etc. This version is a
# no-op. Provide an implementation specific version in a config
# file. Called by #register.
@@ -188,7 +194,11 @@ class MSpecScript
end
patterns.each do |pattern|
- expanded = File.expand_path(pattern)
+ begin
+ expanded = File.realpath(pattern)
+ rescue Errno::ENOENT, Errno::ENOTDIR
+ next
+ end
if File.file?(expanded) && expanded.end_with?('.rb')
return [expanded]
elsif File.directory?(expanded)
@@ -200,27 +210,30 @@ class MSpecScript
abort "Could not find spec file #{partial}"
end
- # Resolves each entry in +list+ to a set of files.
+ # Resolves each entry in +patterns+ to a set of files.
#
- # If the entry has a leading '^' character, the list of files
+ # If the pattern has a leading '^' character, the list of files
# is subtracted from the list of files accumulated to that point.
#
# If the entry has a leading ':' character, the corresponding
# key is looked up in the config object and the entries in the
# value retrieved are processed through #entries.
- def files(list)
- list.inject([]) do |files, item|
- case item[0]
+ def files(patterns)
+ list = []
+ patterns.each do |pattern|
+ case pattern[0]
when ?^
- files -= entries(item[1..-1])
+ list -= entries(pattern[1..-1])
when ?:
- key = item[1..-1].to_sym
- files += files(Array(config[key]))
+ key = pattern[1..-1].to_sym
+ value = config[key]
+ abort "Key #{pattern} not found in mspec config." unless value
+ list += files(Array(value))
else
- files += entries(item)
+ list += entries(pattern)
end
- files
end
+ list
end
def files_from_patterns(patterns)
@@ -231,12 +244,10 @@ class MSpecScript
if patterns.empty? and File.directory? "./spec"
patterns = ["spec/"]
end
- if patterns.empty?
- puts "No files specified."
- exit 1
- end
end
- files patterns
+ list = files(patterns)
+ abort "No files specified." if list.empty?
+ list
end
def cores(max)
diff --git a/spec/mspec/lib/mspec/utils/version.rb b/spec/mspec/lib/mspec/utils/version.rb
index 787a76b053..9c1c58b8df 100644
--- a/spec/mspec/lib/mspec/utils/version.rb
+++ b/spec/mspec/lib/mspec/utils/version.rb
@@ -42,7 +42,7 @@ class SpecVersion
def <=>(other)
if other.respond_to? :to_int
- other = Integer other
+ other = Integer(other.to_int)
else
other = SpecVersion.new(String(other)).to_i
end
diff --git a/spec/mspec/lib/mspec/utils/warnings.rb b/spec/mspec/lib/mspec/utils/warnings.rb
index ef5e5c692c..288dbe71aa 100644
--- a/spec/mspec/lib/mspec/utils/warnings.rb
+++ b/spec/mspec/lib/mspec/utils/warnings.rb
@@ -1,24 +1,30 @@
require 'mspec/guards/version'
-if RUBY_ENGINE == "ruby" and RUBY_VERSION >= "2.4.0"
- ruby_version_is "2.4"..."2.5" do
- # Kernel#warn does not delegate to Warning.warn in 2.4
- module Kernel
- remove_method :warn
- def warn(*messages)
- return if $VERBOSE == nil or messages.empty?
- msg = messages.join("\n")
- msg += "\n" unless msg.end_with?("\n")
- Warning.warn(msg)
- end
- private :warn
- end
- end
+# Always enable deprecation warnings when running MSpec, as ruby/spec tests for them,
+# and like in most test frameworks, all warnings should be enabled by default (same as -w).
+if Object.const_defined?(:Warning) and Warning.respond_to?(:[]=)
+ Warning[:deprecated] = true
+end
+if Object.const_defined?(:Warning) and Warning.respond_to?(:warn)
def Warning.warn(message)
+ # Suppress any warning inside the method to prevent recursion
+ verbose = $VERBOSE
+ $VERBOSE = nil
+
+ if Thread.current[:in_mspec_complain_matcher]
+ return $stderr.write(message)
+ end
+
case message
# $VERBOSE = true warnings
- when /possibly useless use of (<|<=|==|>=|>|\+|-) in void context/
+ when /(.+\.rb):(\d+):.+possibly useless use of (<|<=|==|>=|>) in void context/
+ # Make sure there is a .should otherwise it is missing
+ line_nb = Integer($2)
+ unless File.exist?($1) and /\.should(_not)? (<|<=|==|>=|>)/ === File.readlines($1)[line_nb-1]
+ $stderr.write message
+ end
+ when /possibly useless use of (\+|-) in void context/
when /assigned but unused variable/
when /method redefined/
when /previous definition of/
@@ -39,12 +45,14 @@ if RUBY_ENGINE == "ruby" and RUBY_VERSION >= "2.4.0"
when /\/(argf|io|stringio)\/.+(ARGF|IO)#(lines|chars|bytes|codepoints) is deprecated/
when /Thread\.exclusive is deprecated.+\n.+thread\/exclusive_spec\.rb/
when /hash\/shared\/index\.rb:\d+: warning: Hash#index is deprecated; use Hash#key/
- when /env\/shared\/key\.rb:\d+: warning: ENV\.index is deprecated; use ENV\.key/
when /exponent(_spec)?\.rb:\d+: warning: in a\*\*b, b may be too big/
- when /enumerator\/(new|initialize_spec)\.rb:\d+: warning: Enumerator\.new without a block is deprecated/
+ when /enumerator\/(new_spec|initialize_spec)\.rb:\d+: warning: Enumerator\.new without a block is deprecated/
+ when /Pattern matching is experimental, and the behavior may change in future versions of Ruby!/
else
$stderr.write message
end
+ ensure
+ $VERBOSE = verbose
end
else
$VERBOSE = nil unless ENV['OUTPUT_WARNINGS']
diff --git a/spec/mspec/spec/commands/mkspec_spec.rb b/spec/mspec/spec/commands/mkspec_spec.rb
index 14c363f286..1b959dcb78 100644
--- a/spec/mspec/spec/commands/mkspec_spec.rb
+++ b/spec/mspec/spec/commands/mkspec_spec.rb
@@ -167,13 +167,13 @@ describe MkSpec, "#write_requires" do
end
it "writes the spec_helper require line" do
- @file.should_receive(:puts).with("require File.expand_path('../../../../spec_helper', __FILE__)")
+ @file.should_receive(:puts).with("require_relative '../../../spec_helper'")
@script.write_requires("spec/core/tcejbo", "spec/core/tcejbo/inspect_spec.rb")
end
it "writes require lines for each library specified on the command line" do
@file.stub(:puts)
- @file.should_receive(:puts).with("require File.expand_path('../../../../spec_helper', __FILE__)")
+ @file.should_receive(:puts).with("require_relative '../../../spec_helper'")
@file.should_receive(:puts).with("require 'complex'")
@script.config[:requires] << 'complex'
@script.write_requires("spec/core/tcejbo", "spec/core/tcejbo/inspect_spec.rb")
diff --git a/spec/mspec/spec/commands/mspec_run_spec.rb b/spec/mspec/spec/commands/mspec_run_spec.rb
index 90a42bd62b..fcb44ad5a9 100644
--- a/spec/mspec/spec/commands/mspec_run_spec.rb
+++ b/spec/mspec/spec/commands/mspec_run_spec.rb
@@ -17,8 +17,6 @@ end
describe MSpecRun, "#options" do
before :each do
- @stdout, $stdout = $stdout, IOStub.new
-
@argv = [one_spec, two_spec]
@options, @config = new_option
MSpecOptions.stub(:new).and_return(@options)
@@ -27,10 +25,6 @@ describe MSpecRun, "#options" do
@script.stub(:config).and_return(@config)
end
- after :each do
- $stdout = @stdout
- end
-
it "enables the filter options" do
@options.should_receive(:filters)
@script.options @argv
@@ -114,15 +108,14 @@ describe MSpecRun, "#options" do
it "exits if there are no files to process and './spec' is not a directory" do
File.should_receive(:directory?).with("./spec").and_return(false)
@options.should_receive(:parse).and_return([])
- @script.should_receive(:exit)
+ @script.should_receive(:abort).with("No files specified.")
@script.options
- $stdout.should include "No files specified"
end
it "process 'spec/' if it is a directory and no files were specified" do
File.should_receive(:directory?).with("./spec").and_return(true)
@options.should_receive(:parse).and_return([])
- @script.should_receive(:files).with(["spec/"])
+ @script.should_receive(:files).with(["spec/"]).and_return(["spec/a_spec.rb"])
@script.options
end
diff --git a/spec/mspec/spec/expectations/should.rb b/spec/mspec/spec/expectations/should.rb
index 24b1cf2bf8..48503b1631 100644
--- a/spec/mspec/spec/expectations/should.rb
+++ b/spec/mspec/spec/expectations/should.rb
@@ -41,7 +41,7 @@ describe "MSpec expectation method #should" do
:sym.should be_kind_of(Symbol)
end
- it "causes a failue to be recorded" do
+ it "causes a failure to be recorded" do
1.should == 2
end
diff --git a/spec/mspec/spec/expectations/should_spec.rb b/spec/mspec/spec/expectations/should_spec.rb
index 3258caf13c..b8bda8f86f 100644
--- a/spec/mspec/spec/expectations/should_spec.rb
+++ b/spec/mspec/spec/expectations/should_spec.rb
@@ -13,9 +13,9 @@ describe "MSpec" do
it "records failures" do
@out.should include <<-EOS
1)
-MSpec expectation method #should causes a failue to be recorded FAILED
-Expected 1
- to equal 2
+MSpec expectation method #should causes a failure to be recorded FAILED
+Expected 1 == 2
+to be truthy but was false
EOS
end
@@ -33,8 +33,8 @@ EOS
@out.should include <<-EOS
3)
MSpec expectation method #should_not causes a failure to be recorded FAILED
-Expected 1
- not to equal 1
+Expected 1 == 1
+to be falsy but was true
EOS
end
diff --git a/spec/mspec/spec/fixtures/chatty_spec.rb b/spec/mspec/spec/fixtures/chatty_spec.rb
new file mode 100644
index 0000000000..2d110d8ce4
--- /dev/null
+++ b/spec/mspec/spec/fixtures/chatty_spec.rb
@@ -0,0 +1,8 @@
+unless defined?(RSpec)
+ describe "Chatty#spec" do
+ it "prints too much" do
+ STDOUT.puts "Hello\nIt's me!"
+ 1.should == 1
+ end
+ end
+end
diff --git a/spec/mspec/spec/fixtures/config.mspec b/spec/mspec/spec/fixtures/config.mspec
index 4a069e2eb0..01654c5094 100644
--- a/spec/mspec/spec/fixtures/config.mspec
+++ b/spec/mspec/spec/fixtures/config.mspec
@@ -1,8 +1,6 @@
class MSpecScript
set :target, 'ruby'
- set :backtrace_filter, /lib\/mspec\//
-
set :tags_patterns, [
[%r(spec/fixtures/), 'spec/fixtures/tags/'],
[/_spec.rb$/, '_tags.txt']
diff --git a/spec/mspec/spec/fixtures/die_spec.rb b/spec/mspec/spec/fixtures/die_spec.rb
new file mode 100644
index 0000000000..0f66793274
--- /dev/null
+++ b/spec/mspec/spec/fixtures/die_spec.rb
@@ -0,0 +1,7 @@
+unless defined?(RSpec)
+ describe "Deadly#spec" do
+ it "dies" do
+ abort "DEAD"
+ end
+ end
+end
diff --git a/spec/mspec/spec/fixtures/my_ruby b/spec/mspec/spec/fixtures/my_ruby
index 4d552f27fb..eeda3eeeec 100755
--- a/spec/mspec/spec/fixtures/my_ruby
+++ b/spec/mspec/spec/fixtures/my_ruby
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
echo $RUBY_EXE
-ruby "$@"
+exec ruby "$@"
diff --git a/spec/mspec/spec/guards/conflict_spec.rb b/spec/mspec/spec/guards/conflict_spec.rb
index e06a2809ee..deada96821 100644
--- a/spec/mspec/spec/guards/conflict_spec.rb
+++ b/spec/mspec/spec/guards/conflict_spec.rb
@@ -3,6 +3,7 @@ require 'mspec/guards'
describe Object, "#conflicts_with" do
before :each do
+ hide_deprecation_warnings
ScratchPad.clear
end
@@ -33,6 +34,7 @@ end
describe Object, "#conflicts_with" do
before :each do
+ hide_deprecation_warnings
@guard = ConflictsGuard.new
ConflictsGuard.stub(:new).and_return(@guard)
end
diff --git a/spec/mspec/spec/guards/feature_spec.rb b/spec/mspec/spec/guards/feature_spec.rb
index d14e5f8e67..8761cb2fbb 100644
--- a/spec/mspec/spec/guards/feature_spec.rb
+++ b/spec/mspec/spec/guards/feature_spec.rb
@@ -78,3 +78,43 @@ describe Object, "#with_feature" do
ScratchPad.recorded.should be_nil
end
end
+
+describe Object, "#without_feature" do
+ before :each do
+ ScratchPad.clear
+
+ @guard = FeatureGuard.new :encoding
+ FeatureGuard.stub(:new).and_return(@guard)
+ end
+
+ it "sets the name of the guard to :without_feature" do
+ without_feature(:encoding) { }
+ @guard.name.should == :without_feature
+ end
+
+ it "calls #unregister even when an exception is raised in the guard block" do
+ @guard.should_receive(:match?).and_return(false)
+ @guard.should_receive(:unregister)
+ lambda do
+ without_feature { raise Exception }
+ end.should raise_error(Exception)
+ end
+end
+
+describe Object, "#without_feature" do
+ before :each do
+ ScratchPad.clear
+ end
+
+ it "does not yield if the feature is enabled" do
+ MSpec.should_receive(:feature_enabled?).with(:encoding).and_return(true)
+ without_feature(:encoding) { ScratchPad.record :yield }
+ ScratchPad.recorded.should be_nil
+ end
+
+ it "yields if the feature is disabled" do
+ MSpec.should_receive(:feature_enabled?).with(:encoding).and_return(false)
+ without_feature(:encoding) { ScratchPad.record :yield }
+ ScratchPad.recorded.should == :yield
+ end
+end
diff --git a/spec/mspec/spec/guards/guard_spec.rb b/spec/mspec/spec/guards/guard_spec.rb
index 5c3dae4b3f..2c3317afe6 100644
--- a/spec/mspec/spec/guards/guard_spec.rb
+++ b/spec/mspec/spec/guards/guard_spec.rb
@@ -254,7 +254,7 @@ describe Object, "#guard" do
end
it "allows to combine guards" do
- guard1 = VersionGuard.new 'x.x.x'
+ guard1 = VersionGuard.new '1.2.3', 'x.x.x'
VersionGuard.stub(:new).and_return(guard1)
guard2 = PlatformGuard.new :dummy
PlatformGuard.stub(:new).and_return(guard2)
@@ -360,7 +360,7 @@ describe Object, "#guard_not" do
end
it "allows to combine guards" do
- guard1 = VersionGuard.new 'x.x.x'
+ guard1 = VersionGuard.new '1.2.3', 'x.x.x'
VersionGuard.stub(:new).and_return(guard1)
guard2 = PlatformGuard.new :dummy
PlatformGuard.stub(:new).and_return(guard2)
diff --git a/spec/mspec/spec/guards/platform_spec.rb b/spec/mspec/spec/guards/platform_spec.rb
index 749963d3db..6088fb2ba6 100644
--- a/spec/mspec/spec/guards/platform_spec.rb
+++ b/spec/mspec/spec/guards/platform_spec.rb
@@ -165,11 +165,10 @@ describe PlatformGuard, ".implementation?" do
PlatformGuard.implementation?(:ruby).should == true
end
- it "raises an error when passed an unrecognized name" do
- stub_const 'RUBY_ENGINE', 'ruby'
- lambda {
- PlatformGuard.implementation?(:python)
- }.should raise_error(/unknown implementation/)
+ it "works for an unrecognized name" do
+ stub_const 'RUBY_ENGINE', 'myrubyimplementation'
+ PlatformGuard.implementation?(:myrubyimplementation).should == true
+ PlatformGuard.implementation?(:other).should == false
end
end
@@ -197,7 +196,7 @@ end
describe PlatformGuard, ".os?" do
before :each do
- stub_const 'PlatformGuard::HOST_OS', 'solarce'
+ stub_const 'PlatformGuard::PLATFORM', 'solarce'
end
it "returns false when arg does not match the platform" do
@@ -217,26 +216,36 @@ describe PlatformGuard, ".os?" do
end
it "returns true when arg is :windows and the platform contains 'mswin'" do
- stub_const 'PlatformGuard::HOST_OS', 'mswin32'
+ stub_const 'PlatformGuard::PLATFORM', 'mswin32'
PlatformGuard.os?(:windows).should == true
end
it "returns true when arg is :windows and the platform contains 'mingw'" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mingw32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mingw32'
PlatformGuard.os?(:windows).should == true
end
it "returns false when arg is not :windows and RbConfig::CONFIG['host_os'] contains 'mswin'" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mswin32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mswin32'
PlatformGuard.os?(:linux).should == false
end
it "returns false when arg is not :windows and RbConfig::CONFIG['host_os'] contains 'mingw'" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mingw32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mingw32'
PlatformGuard.os?(:linux).should == false
end
end
+describe PlatformGuard, ".os?" do
+ it "returns true if called with the current OS or architecture" do
+ os = RbConfig::CONFIG["host_os"].sub("-gnu", "")
+ arch = RbConfig::CONFIG["host_arch"]
+ PlatformGuard.os?(os).should == true
+ PlatformGuard.os?(arch).should == true
+ PlatformGuard.os?("#{arch}-#{os}").should == true
+ end
+end
+
describe PlatformGuard, ".os? on JRuby" do
before :all do
@verbose = $VERBOSE
@@ -263,19 +272,19 @@ describe PlatformGuard, ".os? on JRuby" do
end
it "returns true when arg is :windows and RUBY_PLATFORM contains 'java' and os?(:windows) is true" do
- stub_const 'PlatformGuard::HOST_OS', 'mswin32'
+ stub_const 'PlatformGuard::PLATFORM', 'mswin32'
PlatformGuard.os?(:windows).should == true
end
it "returns true when RUBY_PLATFORM contains 'java' and os?(argument) is true" do
- stub_const 'PlatformGuard::HOST_OS', 'amiga'
+ stub_const 'PlatformGuard::PLATFORM', 'amiga'
PlatformGuard.os?(:amiga).should == true
end
end
describe PlatformGuard, ".os?" do
before :each do
- stub_const 'PlatformGuard::HOST_OS', 'unreal'
+ stub_const 'PlatformGuard::PLATFORM', 'unreal'
end
it "returns true if argument matches RbConfig::CONFIG['host_os']" do
@@ -295,34 +304,34 @@ describe PlatformGuard, ".os?" do
end
it "returns true when arg is :windows and RbConfig::CONFIG['host_os'] contains 'mswin'" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mswin32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mswin32'
PlatformGuard.os?(:windows).should == true
end
it "returns true when arg is :windows and RbConfig::CONFIG['host_os'] contains 'mingw'" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mingw32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mingw32'
PlatformGuard.os?(:windows).should == true
end
it "returns false when arg is not :windows and RbConfig::CONFIG['host_os'] contains 'mswin'" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mingw32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mingw32'
PlatformGuard.os?(:linux).should == false
end
it "returns false when arg is not :windows and RbConfig::CONFIG['host_os'] contains 'mingw'" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mingw32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mingw32'
PlatformGuard.os?(:linux).should == false
end
end
describe PlatformGuard, ".windows?" do
it "returns true on windows" do
- stub_const 'PlatformGuard::HOST_OS', 'i386-mingw32'
+ stub_const 'PlatformGuard::PLATFORM', 'i386-mingw32'
PlatformGuard.windows?.should == true
end
it "returns false on non-windows" do
- stub_const 'PlatformGuard::HOST_OS', 'i586-linux'
+ stub_const 'PlatformGuard::PLATFORM', 'i586-linux'
PlatformGuard.windows?.should == false
end
end
diff --git a/spec/mspec/spec/guards/version_spec.rb b/spec/mspec/spec/guards/version_spec.rb
index 07eb451ec9..b0025efcfb 100644
--- a/spec/mspec/spec/guards/version_spec.rb
+++ b/spec/mspec/spec/guards/version_spec.rb
@@ -14,44 +14,44 @@ require 'mspec/guards'
describe VersionGuard, "#match?" do
before :each do
hide_deprecation_warnings
- stub_const "VersionGuard::FULL_RUBY_VERSION", SpecVersion.new('1.8.6')
+ @current = '1.8.6'
end
it "returns true when the argument is equal to RUBY_VERSION" do
- VersionGuard.new('1.8.6').match?.should == true
+ VersionGuard.new(@current, '1.8.6').match?.should == true
end
it "returns true when the argument is less than RUBY_VERSION" do
- VersionGuard.new('1.8').match?.should == true
- VersionGuard.new('1.8.5').match?.should == true
+ VersionGuard.new(@current, '1.8').match?.should == true
+ VersionGuard.new(@current, '1.8.5').match?.should == true
end
it "returns false when the argument is greater than RUBY_VERSION" do
- VersionGuard.new('1.8.7').match?.should == false
- VersionGuard.new('1.9.2').match?.should == false
+ VersionGuard.new(@current, '1.8.7').match?.should == false
+ VersionGuard.new(@current, '1.9.2').match?.should == false
end
it "returns true when the argument range includes RUBY_VERSION" do
- VersionGuard.new('1.8.5'..'1.8.7').match?.should == true
- VersionGuard.new('1.8'..'1.9').match?.should == true
- VersionGuard.new('1.8'...'1.9').match?.should == true
- VersionGuard.new('1.8'..'1.8.6').match?.should == true
- VersionGuard.new('1.8.5'..'1.8.6').match?.should == true
- VersionGuard.new(''...'1.8.7').match?.should == true
+ VersionGuard.new(@current, '1.8.5'..'1.8.7').match?.should == true
+ VersionGuard.new(@current, '1.8'..'1.9').match?.should == true
+ VersionGuard.new(@current, '1.8'...'1.9').match?.should == true
+ VersionGuard.new(@current, '1.8'..'1.8.6').match?.should == true
+ VersionGuard.new(@current, '1.8.5'..'1.8.6').match?.should == true
+ VersionGuard.new(@current, ''...'1.8.7').match?.should == true
end
it "returns false when the argument range does not include RUBY_VERSION" do
- VersionGuard.new('1.8.7'..'1.8.9').match?.should == false
- VersionGuard.new('1.8.4'..'1.8.5').match?.should == false
- VersionGuard.new('1.8.4'...'1.8.6').match?.should == false
- VersionGuard.new('1.8.5'...'1.8.6').match?.should == false
- VersionGuard.new(''...'1.8.6').match?.should == false
+ VersionGuard.new(@current, '1.8.7'..'1.8.9').match?.should == false
+ VersionGuard.new(@current, '1.8.4'..'1.8.5').match?.should == false
+ VersionGuard.new(@current, '1.8.4'...'1.8.6').match?.should == false
+ VersionGuard.new(@current, '1.8.5'...'1.8.6').match?.should == false
+ VersionGuard.new(@current, ''...'1.8.6').match?.should == false
end
end
describe Object, "#ruby_version_is" do
before :each do
- @guard = VersionGuard.new 'x.x.x'
+ @guard = VersionGuard.new '1.2.3', 'x.x.x'
VersionGuard.stub(:new).and_return(@guard)
ScratchPad.clear
end
@@ -88,3 +88,25 @@ describe Object, "#ruby_version_is" do
end.should raise_error(Exception)
end
end
+
+describe Object, "#version_is" do
+ before :each do
+ hide_deprecation_warnings
+ end
+
+ it "returns the expected values" do
+ version_is('1.2.3', '1.2.2').should == true
+ version_is('1.2.3', '1.2.3').should == true
+ version_is('1.2.3', '1.2.4').should == false
+
+ version_is('1.2.3', '1').should == true
+ version_is('1.2.3', '1.0').should == true
+ version_is('1.2.3', '2').should == false
+ version_is('1.2.3', '2.0').should == false
+
+ version_is('1.2.3', '1.2.2'..'1.2.4').should == true
+ version_is('1.2.3', '1.2.2'..'1.2.3').should == true
+ version_is('1.2.3', '1.2.2'...'1.2.3').should == false
+ version_is('1.2.3', '1.2.3'..'1.2.4').should == true
+ end
+end
diff --git a/spec/mspec/spec/helpers/io_spec.rb b/spec/mspec/spec/helpers/io_spec.rb
index 3219f59947..4fa1f97d46 100644
--- a/spec/mspec/spec/helpers/io_spec.rb
+++ b/spec/mspec/spec/helpers/io_spec.rb
@@ -60,11 +60,11 @@ describe Object, "#new_fd" do
rm_r @name
end
- it "returns a Integer that can be used to create an IO instance" do
+ it "returns an Integer that can be used to create an IO instance" do
fd = new_fd @name
fd.should be_kind_of(Integer)
- @io = IO.new fd, fmode('w:utf-8')
+ @io = IO.new fd, 'w:utf-8'
@io.sync = true
@io.print "io data"
@@ -76,7 +76,7 @@ describe Object, "#new_fd" do
fd = new_fd @name, { :mode => 'w:utf-8' }
fd.should be_kind_of(Integer)
- @io = IO.new fd, fmode('w:utf-8')
+ @io = IO.new fd, 'w:utf-8'
@io.sync = true
@io.print "io data"
@@ -99,9 +99,9 @@ describe Object, "#new_io" do
rm_r @name
end
- it "returns an IO instance" do
+ it "returns a File instance" do
@io = new_io @name
- @io.should be_an_instance_of(IO)
+ @io.should be_an_instance_of(File)
end
it "opens the IO for reading if passed 'r'" do
@@ -134,41 +134,3 @@ describe Object, "#new_io" do
IO.read(@name).should == "io data"
end
end
-
-describe Object, "#fmode" do
- it "returns the argument unmodified if :encoding feature is enabled" do
- FeatureGuard.should_receive(:enabled?).with(:encoding).and_return(true)
- fmode("rb:binary:utf-8").should == "rb:binary:utf-8"
- end
-
- it "returns only the file access mode if :encoding feature is not enabled" do
- FeatureGuard.should_receive(:enabled?).with(:encoding).and_return(false)
- fmode("rb:binary:utf-8").should == "rb"
- end
-end
-
-describe Object, "#options_or_mode" do
- describe "if passed a Hash" do
- it "returns a mode string if :encoding feature is not enabled" do
- FeatureGuard.should_receive(:enabled?).with(:encoding).twice.and_return(false)
- options_or_mode(:mode => "rb:binary").should == "rb"
- end
-
- it "returns a Hash if :encoding feature is enabled" do
- FeatureGuard.should_receive(:enabled?).with(:encoding).and_return(true)
- options_or_mode(:mode => "rb:utf-8").should == { :mode => "rb:utf-8" }
- end
- end
-
- describe "if passed a String" do
- it "returns only the file access mode if :encoding feature is not enabled" do
- FeatureGuard.should_receive(:enabled?).with(:encoding).and_return(false)
- options_or_mode("rb:binary:utf-8").should == "rb"
- end
-
- it "returns the argument unmodified if :encoding feature is enabled" do
- FeatureGuard.should_receive(:enabled?).with(:encoding).and_return(true)
- options_or_mode("rb:binary:utf-8").should == "rb:binary:utf-8"
- end
- end
-end
diff --git a/spec/mspec/spec/helpers/tmp_spec.rb b/spec/mspec/spec/helpers/tmp_spec.rb
index afadc7f51c..4dcf629d94 100644
--- a/spec/mspec/spec/helpers/tmp_spec.rb
+++ b/spec/mspec/spec/helpers/tmp_spec.rb
@@ -4,7 +4,7 @@ require 'mspec/helpers'
describe Object, "#tmp" do
before :all do
- @dir = "#{File.expand_path(Dir.pwd)}/rubyspec_temp"
+ @dir = SPEC_TEMP_DIR
end
it "returns a name relative to the current working directory" do
diff --git a/spec/mspec/spec/integration/run_spec.rb b/spec/mspec/spec/integration/run_spec.rb
index 93d2ef8b68..99a5416cb0 100644
--- a/spec/mspec/spec/integration/run_spec.rb
+++ b/spec/mspec/spec/integration/run_spec.rb
@@ -5,43 +5,44 @@ describe "Running mspec" do
1)
Foo#bar errors FAILED
-Expected 1
- to equal 2
-
+Expected 1 == 2
+to be truthy but was false
CWD/spec/fixtures/a_spec.rb:8:in `block (2 levels) in <top (required)>'
CWD/spec/fixtures/a_spec.rb:2:in `<top (required)>'
-CWD/bin/mspec-run:7:in `<main>'
2)
Foo#bar fails ERROR
RuntimeError: failure
CWD/spec/fixtures/a_spec.rb:12:in `block (2 levels) in <top (required)>'
CWD/spec/fixtures/a_spec.rb:2:in `<top (required)>'
-CWD/bin/mspec-run:7:in `<main>'
Finished in D.DDDDDD seconds
EOS
a_stats = "1 file, 3 examples, 2 expectations, 1 failure, 1 error, 0 tagged\n"
ab_stats = "2 files, 4 examples, 3 expectations, 1 failure, 1 error, 0 tagged\n"
+ fixtures = "spec/fixtures"
it "runs the specs" do
- fixtures = "spec/fixtures"
out, ret = run_mspec("run", "#{fixtures}/a_spec.rb")
out.should == "RUBY_DESCRIPTION\n.FE\n#{a_spec_output}\n#{a_stats}"
ret.success?.should == false
end
it "directly with mspec-run runs the specs" do
- fixtures = "spec/fixtures"
out, ret = run_mspec("-run", "#{fixtures}/a_spec.rb")
out.should == "RUBY_DESCRIPTION\n.FE\n#{a_spec_output}\n#{a_stats}"
ret.success?.should == false
end
- it "runs the specs in parallel with -j" do
- fixtures = "spec/fixtures"
+ it "runs the specs in parallel with -j using the dotted formatter" do
out, ret = run_mspec("run", "-j #{fixtures}/a_spec.rb #{fixtures}/b_spec.rb")
+ out.should == "RUBY_DESCRIPTION\n...\n#{a_spec_output}\n#{ab_stats}"
+ ret.success?.should == false
+ end
+
+ it "runs the specs in parallel with -j -fa" do
+ out, ret = run_mspec("run", "-j -fa #{fixtures}/a_spec.rb #{fixtures}/b_spec.rb")
progress_bar =
"\r[/ | 0% | 00:00:00] \e[0;32m 0F \e[0;32m 0E\e[0m " +
"\r[- | ==================50% | 00:00:00] \e[0;32m 0F \e[0;32m 0E\e[0m " +
@@ -49,4 +50,22 @@ EOS
out.should == "RUBY_DESCRIPTION\n#{progress_bar}\n#{a_spec_output}\n#{ab_stats}"
ret.success?.should == false
end
+
+ it "gives a useful error message when a subprocess dies in parallel mode" do
+ out, ret = run_mspec("run", "-j #{fixtures}/b_spec.rb #{fixtures}/die_spec.rb")
+ lines = out.lines
+ lines.should include "A child mspec-run process died unexpectedly while running CWD/spec/fixtures/die_spec.rb\n"
+ lines.should include "Finished in D.DDDDDD seconds\n"
+ lines.last.should =~ /^\d files?, \d examples?, \d expectations?, 0 failures, 0 errors, 0 tagged$/
+ ret.success?.should == false
+ end
+
+ it "gives a useful error message when a subprocess prints unexpected output on STDOUT in parallel mode" do
+ out, ret = run_mspec("run", "-j #{fixtures}/b_spec.rb #{fixtures}/chatty_spec.rb")
+ lines = out.lines
+ lines.should include "A child mspec-run process printed unexpected output on STDOUT: #{'"Hello\nIt\'s me!\n"'} while running CWD/spec/fixtures/chatty_spec.rb\n"
+ lines.should include "Finished in D.DDDDDD seconds\n"
+ lines.last.should == "2 files, 2 examples, 2 expectations, 0 failures, 0 errors, 0 tagged\n"
+ ret.success?.should == false
+ end
end
diff --git a/spec/mspec/spec/integration/tag_spec.rb b/spec/mspec/spec/integration/tag_spec.rb
index d980769043..f4df2f0dc4 100644
--- a/spec/mspec/spec/integration/tag_spec.rb
+++ b/spec/mspec/spec/integration/tag_spec.rb
@@ -24,21 +24,17 @@ Tag#me érròrs in unicode
1)
Tag#me errors FAILED
-Expected 1
- to equal 2
-
+Expected 1 == 2
+to be truthy but was false
CWD/spec/fixtures/tagging_spec.rb:9:in `block (2 levels) in <top (required)>'
CWD/spec/fixtures/tagging_spec.rb:3:in `<top (required)>'
-CWD/bin/mspec-tag:7:in `<main>'
2)
Tag#me érròrs in unicode FAILED
-Expected 1
- to equal 2
-
+Expected 1 == 2
+to be truthy but was false
CWD/spec/fixtures/tagging_spec.rb:13:in `block (2 levels) in <top (required)>'
CWD/spec/fixtures/tagging_spec.rb:3:in `<top (required)>'
-CWD/bin/mspec-tag:7:in `<main>'
Finished in D.DDDDDD seconds
diff --git a/spec/mspec/spec/matchers/base_spec.rb b/spec/mspec/spec/matchers/base_spec.rb
index cc13c29d1d..762822bf09 100644
--- a/spec/mspec/spec/matchers/base_spec.rb
+++ b/spec/mspec/spec/matchers/base_spec.rb
@@ -4,222 +4,225 @@ require 'mspec/matchers'
require 'time'
describe SpecPositiveOperatorMatcher, "== operator" do
- it "raises an SpecExpectationNotMetError when expected == actual returns false" do
+ it "provides a failure message that 'Expected x to equal y'" do
lambda {
SpecPositiveOperatorMatcher.new(1) == 2
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 1 == 2\nto be truthy but was false")
end
- it "provides a failure message that 'Expected x to equal y'" do
- SpecExpectation.should_receive(:fail_with).with("Expected 1\n", "to equal 2\n")
- SpecPositiveOperatorMatcher.new(1) == 2
- end
-
- it "does not raise an exception when expected == actual returns true" do
+ it "does not raise an exception when == returns true" do
SpecPositiveOperatorMatcher.new(1) == 1
end
end
describe SpecPositiveOperatorMatcher, "=~ operator" do
- it "raises an SpecExpectationNotMetError when expected =~ actual returns false" do
+ it "provides a failure message that 'Expected \"x\" to match y'" do
lambda {
SpecPositiveOperatorMatcher.new('real') =~ /fake/
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected \"real\" =~ /fake/\nto be truthy but was nil")
end
- it "provides a failure message that 'Expected \"x\" to match y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected \"real\"\n", "to match /fake/\n")
- SpecPositiveOperatorMatcher.new('real') =~ /fake/
- end
-
- it "does not raise an exception when expected =~ actual returns true" do
+ it "does not raise an exception when =~ returns true" do
SpecPositiveOperatorMatcher.new('real') =~ /real/
end
end
describe SpecPositiveOperatorMatcher, "> operator" do
- it "raises an SpecExpectationNotMetError when expected > actual returns false" do
+ it "provides a failure message that 'Expected x to be greater than y'" do
lambda {
SpecPositiveOperatorMatcher.new(4) > 5
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 4 > 5\nto be truthy but was false")
end
- it "provides a failure message that 'Expected x to be greater than y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected 4\n", "to be greater than 5\n")
- SpecPositiveOperatorMatcher.new(4) > 5
- end
-
- it "does not raise an exception when expected > actual returns true" do
+ it "does not raise an exception when > returns true" do
SpecPositiveOperatorMatcher.new(5) > 4
end
end
describe SpecPositiveOperatorMatcher, ">= operator" do
- it "raises an SpecExpectationNotMetError when expected >= actual returns false" do
+ it "provides a failure message that 'Expected x to be greater than or equal to y'" do
lambda {
SpecPositiveOperatorMatcher.new(4) >= 5
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 4 >= 5\nto be truthy but was false")
end
- it "provides a failure message that 'Expected x to be greater than or equal to y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected 4\n", "to be greater than or equal to 5\n")
- SpecPositiveOperatorMatcher.new(4) >= 5
- end
-
- it "does not raise an exception when expected > actual returns true" do
+ it "does not raise an exception when > returns true" do
SpecPositiveOperatorMatcher.new(5) >= 4
SpecPositiveOperatorMatcher.new(5) >= 5
end
end
-describe SpecPositiveOperatorMatcher, "< operater" do
- it "raises an SpecExpectationNotMetError when expected < actual returns false" do
+describe SpecPositiveOperatorMatcher, "< operator" do
+ it "provides a failure message that 'Expected x to be less than y'" do
lambda {
SpecPositiveOperatorMatcher.new(5) < 4
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 5 < 4\nto be truthy but was false")
end
- it "provides a failure message that 'Expected x to be less than y'" do
- SpecExpectation.should_receive(:fail_with).with("Expected 5\n", "to be less than 4\n")
- SpecPositiveOperatorMatcher.new(5) < 4
- end
-
- it "does not raise an exception when expected < actual returns true" do
+ it "does not raise an exception when < returns true" do
SpecPositiveOperatorMatcher.new(4) < 5
end
end
-describe SpecPositiveOperatorMatcher, "<= operater" do
- it "raises an SpecExpectationNotMetError when expected < actual returns false" do
+describe SpecPositiveOperatorMatcher, "<= operator" do
+ it "provides a failure message that 'Expected x to be less than or equal to y'" do
lambda {
SpecPositiveOperatorMatcher.new(5) <= 4
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 5 <= 4\nto be truthy but was false")
end
- it "provides a failure message that 'Expected x to be less than or equal to y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected 5\n", "to be less than or equal to 4\n")
- SpecPositiveOperatorMatcher.new(5) <= 4
- end
-
- it "does not raise an exception when expected < actual returns true" do
+ it "does not raise an exception when < returns true" do
SpecPositiveOperatorMatcher.new(4) <= 5
SpecPositiveOperatorMatcher.new(4) <= 4
end
end
-describe SpecNegativeOperatorMatcher, "== operator" do
- it "raises an SpecExpectationNotMetError when expected == actual returns true" do
+describe SpecPositiveOperatorMatcher, "arbitrary predicates" do
+ it "do not raise an exception when the predicate is truthy" do
+ SpecPositiveOperatorMatcher.new(2).eql?(2)
+ SpecPositiveOperatorMatcher.new(2).equal?(2)
+ SpecPositiveOperatorMatcher.new([1, 2, 3]).include?(2)
+ SpecPositiveOperatorMatcher.new("abc").start_with?("ab")
+ SpecPositiveOperatorMatcher.new("abc").start_with?("d", "a")
+ SpecPositiveOperatorMatcher.new(3).odd?
+ SpecPositiveOperatorMatcher.new([1, 2]).any? { |e| e.even? }
+ end
+
+ it "provide a failure message when the predicate returns a falsy value" do
lambda {
- SpecNegativeOperatorMatcher.new(1) == 1
- }.should raise_error(SpecExpectationNotMetError)
+ SpecPositiveOperatorMatcher.new(2).eql?(3)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 2.eql? 3\nto be truthy but was false")
+ lambda {
+ SpecPositiveOperatorMatcher.new(2).equal?(3)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 2.equal? 3\nto be truthy but was false")
+ lambda {
+ SpecPositiveOperatorMatcher.new([1, 2, 3]).include?(4)
+ }.should raise_error(SpecExpectationNotMetError, "Expected [1, 2, 3].include? 4\nto be truthy but was false")
+ lambda {
+ SpecPositiveOperatorMatcher.new("abc").start_with?("de")
+ }.should raise_error(SpecExpectationNotMetError, "Expected \"abc\".start_with? \"de\"\nto be truthy but was false")
+ lambda {
+ SpecPositiveOperatorMatcher.new("abc").start_with?("d", "e")
+ }.should raise_error(SpecExpectationNotMetError, "Expected \"abc\".start_with? \"d\", \"e\"\nto be truthy but was false")
+ lambda {
+ SpecPositiveOperatorMatcher.new(2).odd?
+ }.should raise_error(SpecExpectationNotMetError, "Expected 2.odd?\nto be truthy but was false")
+ lambda {
+ SpecPositiveOperatorMatcher.new([1, 3]).any? { |e| e.even? }
+ }.should raise_error(SpecExpectationNotMetError, "Expected [1, 3].any? { ... }\nto be truthy but was false")
+ end
+end
+
+describe SpecNegativeOperatorMatcher, "arbitrary predicates" do
+ it "do not raise an exception when the predicate returns a falsy value" do
+ SpecNegativeOperatorMatcher.new(2).eql?(3)
+ SpecNegativeOperatorMatcher.new(2).equal?(3)
+ SpecNegativeOperatorMatcher.new([1, 2, 3]).include?(4)
+ SpecNegativeOperatorMatcher.new("abc").start_with?("de")
+ SpecNegativeOperatorMatcher.new("abc").start_with?("d", "e")
+ SpecNegativeOperatorMatcher.new(2).odd?
+ SpecNegativeOperatorMatcher.new([1, 3]).any? { |e| e.even? }
+ end
+
+ it "provide a failure message when the predicate returns a truthy value" do
+ lambda {
+ SpecNegativeOperatorMatcher.new(2).eql?(2)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 2.eql? 2\nto be falsy but was true")
+ lambda {
+ SpecNegativeOperatorMatcher.new(2).equal?(2)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 2.equal? 2\nto be falsy but was true")
+ lambda {
+ SpecNegativeOperatorMatcher.new([1, 2, 3]).include?(2)
+ }.should raise_error(SpecExpectationNotMetError, "Expected [1, 2, 3].include? 2\nto be falsy but was true")
+ lambda {
+ SpecNegativeOperatorMatcher.new("abc").start_with?("ab")
+ }.should raise_error(SpecExpectationNotMetError, "Expected \"abc\".start_with? \"ab\"\nto be falsy but was true")
+ lambda {
+ SpecNegativeOperatorMatcher.new("abc").start_with?("d", "a")
+ }.should raise_error(SpecExpectationNotMetError, "Expected \"abc\".start_with? \"d\", \"a\"\nto be falsy but was true")
+ lambda {
+ SpecNegativeOperatorMatcher.new(3).odd?
+ }.should raise_error(SpecExpectationNotMetError, "Expected 3.odd?\nto be falsy but was true")
+ lambda {
+ SpecNegativeOperatorMatcher.new([1, 2]).any? { |e| e.even? }
+ }.should raise_error(SpecExpectationNotMetError, "Expected [1, 2].any? { ... }\nto be falsy but was true")
end
+end
+describe SpecNegativeOperatorMatcher, "== operator" do
it "provides a failure message that 'Expected x not to equal y'" do
- SpecExpectation.should_receive(:fail_with).with("Expected 1\n", "not to equal 1\n")
- SpecNegativeOperatorMatcher.new(1) == 1
+ lambda {
+ SpecNegativeOperatorMatcher.new(1) == 1
+ }.should raise_error(SpecExpectationNotMetError, "Expected 1 == 1\nto be falsy but was true")
end
- it "does not raise an exception when expected == actual returns false" do
+ it "does not raise an exception when == returns false" do
SpecNegativeOperatorMatcher.new(1) == 2
end
end
describe SpecNegativeOperatorMatcher, "=~ operator" do
- it "raises an SpecExpectationNotMetError when expected =~ actual returns true" do
+ it "provides a failure message that 'Expected \"x\" not to match /y/'" do
lambda {
SpecNegativeOperatorMatcher.new('real') =~ /real/
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected \"real\" =~ /real/\nto be falsy but was 0")
end
- it "provides a failure message that 'Expected \"x\" not to match /y/'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected \"real\"\n", "not to match /real/\n")
- SpecNegativeOperatorMatcher.new('real') =~ /real/
- end
-
- it "does not raise an exception when expected =~ actual returns false" do
+ it "does not raise an exception when =~ returns false" do
SpecNegativeOperatorMatcher.new('real') =~ /fake/
end
end
describe SpecNegativeOperatorMatcher, "< operator" do
- it "raises an SpecExpectationNotMetError when expected < actual returns true" do
+ it "provides a failure message that 'Expected x not to be less than y'" do
lambda {
SpecNegativeOperatorMatcher.new(4) < 5
- }.should raise_error(SpecExpectationNotMetError)
- end
-
- it "provides a failure message that 'Expected x not to be less than y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected 4\n", "not to be less than 5\n")
- SpecNegativeOperatorMatcher.new(4) < 5
+ }.should raise_error(SpecExpectationNotMetError, "Expected 4 < 5\nto be falsy but was true")
end
- it "does not raise an exception when expected < actual returns false" do
+ it "does not raise an exception when < returns false" do
SpecNegativeOperatorMatcher.new(5) < 4
end
end
describe SpecNegativeOperatorMatcher, "<= operator" do
- it "raises an SpecExpectationNotMetError when expected <= actual returns true" do
+ it "provides a failure message that 'Expected x not to be less than or equal to y'" do
lambda {
SpecNegativeOperatorMatcher.new(4) <= 5
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 4 <= 5\nto be falsy but was true")
lambda {
SpecNegativeOperatorMatcher.new(5) <= 5
- }.should raise_error(SpecExpectationNotMetError)
- end
-
- it "provides a failure message that 'Expected x not to be less than or equal to y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected 4\n", "not to be less than or equal to 5\n")
- SpecNegativeOperatorMatcher.new(4) <= 5
+ }.should raise_error(SpecExpectationNotMetError, "Expected 5 <= 5\nto be falsy but was true")
end
- it "does not raise an exception when expected <= actual returns false" do
+ it "does not raise an exception when <= returns false" do
SpecNegativeOperatorMatcher.new(5) <= 4
end
end
describe SpecNegativeOperatorMatcher, "> operator" do
- it "raises an SpecExpectationNotMetError when expected > actual returns true" do
+ it "provides a failure message that 'Expected x not to be greater than y'" do
lambda {
SpecNegativeOperatorMatcher.new(5) > 4
- }.should raise_error(SpecExpectationNotMetError)
- end
-
- it "provides a failure message that 'Expected x not to be greater than y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected 5\n", "not to be greater than 4\n")
- SpecNegativeOperatorMatcher.new(5) > 4
+ }.should raise_error(SpecExpectationNotMetError, "Expected 5 > 4\nto be falsy but was true")
end
- it "does not raise an exception when expected > actual returns false" do
+ it "does not raise an exception when > returns false" do
SpecNegativeOperatorMatcher.new(4) > 5
end
end
describe SpecNegativeOperatorMatcher, ">= operator" do
- it "raises an SpecExpectationNotMetError when expected >= actual returns true" do
+ it "provides a failure message that 'Expected x not to be greater than or equal to y'" do
lambda {
SpecNegativeOperatorMatcher.new(5) >= 4
- }.should raise_error(SpecExpectationNotMetError)
+ }.should raise_error(SpecExpectationNotMetError, "Expected 5 >= 4\nto be falsy but was true")
lambda {
SpecNegativeOperatorMatcher.new(5) >= 5
- }.should raise_error(SpecExpectationNotMetError)
- end
-
- it "provides a failure message that 'Expected x not to be greater than or equal to y'" do
- SpecExpectation.should_receive(:fail_with).with(
- "Expected 5\n", "not to be greater than or equal to 4\n")
- SpecNegativeOperatorMatcher.new(5) >= 4
+ }.should raise_error(SpecExpectationNotMetError, "Expected 5 >= 5\nto be falsy but was true")
end
- it "does not raise an exception when expected >= actual returns false" do
+ it "does not raise an exception when >= returns false" do
SpecNegativeOperatorMatcher.new(4) >= 5
end
end
diff --git a/spec/mspec/spec/matchers/be_close_spec.rb b/spec/mspec/spec/matchers/be_close_spec.rb
index 3ced61dc7a..6edff98e4a 100644
--- a/spec/mspec/spec/matchers/be_close_spec.rb
+++ b/spec/mspec/spec/matchers/be_close_spec.rb
@@ -16,12 +16,14 @@ describe BeCloseMatcher do
BeCloseMatcher.new(5.0, 0.5).matches?(4.51).should == true
end
- it "does not match when actual == (expected + tolerance)" do
- BeCloseMatcher.new(5.0, 0.5).matches?(5.5).should == false
+ it "matches when actual == (expected + tolerance)" do
+ BeCloseMatcher.new(5.0, 0.5).matches?(5.5).should == true
+ BeCloseMatcher.new(3, 2).matches?(5).should == true
end
- it "does not match when actual == (expected - tolerance)" do
- BeCloseMatcher.new(5.0, 0.5).matches?(4.5).should == false
+ it "matches when actual == (expected - tolerance)" do
+ BeCloseMatcher.new(5.0, 0.5).matches?(4.5).should == true
+ BeCloseMatcher.new(3, 2).matches?(1).should == true
end
it "does not match when actual < (expected - tolerance)" do
@@ -34,13 +36,13 @@ describe BeCloseMatcher do
it "provides a useful failure message" do
matcher = BeCloseMatcher.new(5.0, 0.5)
- matcher.matches?(5.5)
- matcher.failure_message.should == ["Expected 5.0", "to be within +/- 0.5 of 5.5"]
+ matcher.matches?(6.5)
+ matcher.failure_message.should == ["Expected 6.5", "to be within 5.0 +/- 0.5"]
end
it "provides a useful negative failure message" do
matcher = BeCloseMatcher.new(5.0, 0.5)
- matcher.matches?(5.0)
- matcher.negative_failure_message.should == ["Expected 5.0", "not to be within +/- 0.5 of 5.0"]
+ matcher.matches?(4.9)
+ matcher.negative_failure_message.should == ["Expected 4.9", "not to be within 5.0 +/- 0.5"]
end
end
diff --git a/spec/mspec/spec/matchers/complain_spec.rb b/spec/mspec/spec/matchers/complain_spec.rb
index 709b57be6c..90f94c3684 100644
--- a/spec/mspec/spec/matchers/complain_spec.rb
+++ b/spec/mspec/spec/matchers/complain_spec.rb
@@ -8,7 +8,7 @@ describe ComplainMatcher do
ComplainMatcher.new(nil).matches?(proc).should == true
end
- it "maches when executing the proc results in the expected output to $stderr" do
+ it "matches when executing the proc results in the expected output to $stderr" do
proc = lambda { warn "Que haces?" }
ComplainMatcher.new("Que haces?\n").matches?(proc).should == true
ComplainMatcher.new("Que pasa?\n").matches?(proc).should == false
@@ -49,4 +49,49 @@ describe ComplainMatcher do
matcher.negative_failure_message.should ==
["Expected warning not to match: /ou/", "but got: \"ouch\""]
end
+
+ context "`verbose` option specified" do
+ before do
+ $VERBOSE, @verbose = nil, $VERBOSE
+ end
+
+ after do
+ $VERBOSE = @verbose
+ end
+
+ it "sets $VERBOSE with specified second optional parameter" do
+ verbose = nil
+ proc = lambda { verbose = $VERBOSE }
+
+ ComplainMatcher.new(nil, verbose: true).matches?(proc)
+ verbose.should == true
+
+ ComplainMatcher.new(nil, verbose: false).matches?(proc)
+ verbose.should == false
+ end
+
+ it "sets $VERBOSE with false by default" do
+ verbose = nil
+ proc = lambda { verbose = $VERBOSE }
+
+ ComplainMatcher.new(nil).matches?(proc)
+ verbose.should == false
+ end
+
+ it "does not have side effect" do
+ proc = lambda { safe_value = $VERBOSE }
+
+ lambda do
+ ComplainMatcher.new(nil, verbose: true).matches?(proc)
+ end.should_not change { $VERBOSE }
+ end
+
+ it "accepts a verbose level as single argument" do
+ verbose = nil
+ proc = lambda { verbose = $VERBOSE }
+
+ ComplainMatcher.new(verbose: true).matches?(proc)
+ verbose.should == true
+ end
+ end
end
diff --git a/spec/mspec/spec/matchers/eql_spec.rb b/spec/mspec/spec/matchers/eql_spec.rb
index 711ebdb679..f29e6976da 100644
--- a/spec/mspec/spec/matchers/eql_spec.rb
+++ b/spec/mspec/spec/matchers/eql_spec.rb
@@ -22,12 +22,12 @@ describe EqlMatcher do
it "provides a useful failure message" do
matcher = EqlMatcher.new("red")
matcher.matches?("red")
- matcher.failure_message.should == ["Expected \"red\"\n", "to have same value and type as \"red\"\n"]
+ matcher.failure_message.should == ["Expected \"red\"", "to have same value and type as \"red\""]
end
it "provides a useful negative failure message" do
matcher = EqlMatcher.new(1)
matcher.matches?(1.0)
- matcher.negative_failure_message.should == ["Expected 1.0\n", "not to have same value or type as 1\n"]
+ matcher.negative_failure_message.should == ["Expected 1.0", "not to have same value or type as 1"]
end
end
diff --git a/spec/mspec/spec/matchers/equal_element_spec.rb b/spec/mspec/spec/matchers/equal_element_spec.rb
index 45b8390364..06fae762c4 100644
--- a/spec/mspec/spec/matchers/equal_element_spec.rb
+++ b/spec/mspec/spec/matchers/equal_element_spec.rb
@@ -48,28 +48,28 @@ describe EqualElementMatcher do
it "provides a useful failure message" do
equal_element = EqualElementMatcher.new("A", {}, "Test")
equal_element.matches?('<A></A>').should be_false
- equal_element.failure_message.should == [%{Expected "<A></A>"\n}, %{to be a 'A' element with no attributes and "Test" as content}]
+ equal_element.failure_message.should == [%{Expected "<A></A>"}, %{to be a 'A' element with no attributes and "Test" as content}]
equal_element = EqualElementMatcher.new("A", {}, "")
equal_element.matches?('<A>Test</A>').should be_false
- equal_element.failure_message.should == [%{Expected "<A>Test</A>"\n}, %{to be a 'A' element with no attributes and no content}]
+ equal_element.failure_message.should == [%{Expected "<A>Test</A>"}, %{to be a 'A' element with no attributes and no content}]
equal_element = EqualElementMatcher.new("A", "HREF" => "http://www.example.com")
equal_element.matches?('<A>Test</A>').should be_false
- equal_element.failure_message.should == [%{Expected "<A>Test</A>"\n}, %{to be a 'A' element with HREF="http://www.example.com" and any content}]
+ equal_element.failure_message.should == [%{Expected "<A>Test</A>"}, %{to be a 'A' element with HREF="http://www.example.com" and any content}]
end
it "provides a useful negative failure message" do
equal_element = EqualElementMatcher.new("A", {}, "Test")
equal_element.matches?('<A></A>').should be_false
- equal_element.negative_failure_message.should == [%{Expected "<A></A>"\n}, %{not to be a 'A' element with no attributes and "Test" as content}]
+ equal_element.negative_failure_message.should == [%{Expected "<A></A>"}, %{not to be a 'A' element with no attributes and "Test" as content}]
equal_element = EqualElementMatcher.new("A", {}, "")
equal_element.matches?('<A>Test</A>').should be_false
- equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"\n}, %{not to be a 'A' element with no attributes and no content}]
+ equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"}, %{not to be a 'A' element with no attributes and no content}]
equal_element = EqualElementMatcher.new("A", "HREF" => "http://www.example.com")
equal_element.matches?('<A>Test</A>').should be_false
- equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"\n}, %{not to be a 'A' element with HREF="http://www.example.com" and any content}]
+ equal_element.negative_failure_message.should == [%{Expected "<A>Test</A>"}, %{not to be a 'A' element with HREF="http://www.example.com" and any content}]
end
end
diff --git a/spec/mspec/spec/matchers/equal_spec.rb b/spec/mspec/spec/matchers/equal_spec.rb
index ca7bf83fdd..a61432b750 100644
--- a/spec/mspec/spec/matchers/equal_spec.rb
+++ b/spec/mspec/spec/matchers/equal_spec.rb
@@ -21,12 +21,12 @@ describe EqualMatcher do
it "provides a useful failure message" do
matcher = EqualMatcher.new("red")
matcher.matches?("red")
- matcher.failure_message.should == ["Expected \"red\"\n", "to be identical to \"red\"\n"]
+ matcher.failure_message.should == ["Expected \"red\"", "to be identical to \"red\""]
end
it "provides a useful negative failure message" do
matcher = EqualMatcher.new(1)
matcher.matches?(1)
- matcher.negative_failure_message.should == ["Expected 1\n", "not to be identical to 1\n"]
+ matcher.negative_failure_message.should == ["Expected 1", "not to be identical to 1"]
end
end
diff --git a/spec/mspec/spec/matchers/include_any_of_spec.rb b/spec/mspec/spec/matchers/include_any_of_spec.rb
new file mode 100644
index 0000000000..697c8d8886
--- /dev/null
+++ b/spec/mspec/spec/matchers/include_any_of_spec.rb
@@ -0,0 +1,42 @@
+require 'spec_helper'
+require 'mspec/expectations/expectations'
+require 'mspec/matchers'
+
+describe IncludeAnyOfMatcher do
+ it "matches when actual includes expected" do
+ IncludeAnyOfMatcher.new(2).matches?([1,2,3]).should == true
+ IncludeAnyOfMatcher.new("b").matches?("abc").should == true
+ end
+
+ it "does not match when actual does not include expected" do
+ IncludeAnyOfMatcher.new(4).matches?([1,2,3]).should == false
+ IncludeAnyOfMatcher.new("d").matches?("abc").should == false
+ end
+
+ it "matches when actual includes all expected" do
+ IncludeAnyOfMatcher.new(3, 2, 1).matches?([1,2,3]).should == true
+ IncludeAnyOfMatcher.new("a", "b", "c").matches?("abc").should == true
+ end
+
+ it "matches when actual includes any expected" do
+ IncludeAnyOfMatcher.new(3, 4, 5).matches?([1,2,3]).should == true
+ IncludeAnyOfMatcher.new("c", "d", "e").matches?("abc").should == true
+ end
+
+ it "does not match when actual does not include any expected" do
+ IncludeAnyOfMatcher.new(4, 5).matches?([1,2,3]).should == false
+ IncludeAnyOfMatcher.new("de").matches?("abc").should == false
+ end
+
+ it "provides a useful failure message" do
+ matcher = IncludeAnyOfMatcher.new(5, 6)
+ matcher.matches?([1,2,3])
+ matcher.failure_message.should == ["Expected [1, 2, 3]", "to include any of [5, 6]"]
+ end
+
+ it "provides a useful negative failure message" do
+ matcher = IncludeAnyOfMatcher.new(1, 2, 3)
+ matcher.matches?([1,2])
+ matcher.negative_failure_message.should == ["Expected [1, 2]", "not to include any of [1, 2, 3]"]
+ end
+end
diff --git a/spec/mspec/spec/matchers/raise_error_spec.rb b/spec/mspec/spec/matchers/raise_error_spec.rb
index 88aab34d53..a40acc0ea0 100644
--- a/spec/mspec/spec/matchers/raise_error_spec.rb
+++ b/spec/mspec/spec/matchers/raise_error_spec.rb
@@ -12,7 +12,7 @@ describe RaiseErrorMatcher do
matcher.matches?(proc).should == true
end
- it "executes it's optional block if matched" do
+ it "executes its optional block if matched" do
run = false
proc = Proc.new { raise ExpectedException }
matcher = RaiseErrorMatcher.new(ExpectedException, nil) { |error|
@@ -62,16 +62,55 @@ describe RaiseErrorMatcher do
matcher.matches?(proc).should == false
end
- it "provides a useful failure message" do
+ it "provides a useful failure message when the exception class differs" do
+ exc = UnexpectedException.new("message")
+ matcher = RaiseErrorMatcher.new(ExpectedException, "message")
+
+ matcher.matching_exception?(exc).should == false
+ begin
+ matcher.matches?(Proc.new { raise exc })
+ rescue UnexpectedException => e
+ matcher.failure_message.should ==
+ ["Expected ExpectedException (message)", "but got: UnexpectedException (message)"]
+ ExceptionState.new(nil, nil, e).message.should ==
+ "Expected ExpectedException (message)\nbut got: UnexpectedException (message)"
+ else
+ raise "no exception"
+ end
+ end
+
+ it "provides a useful failure message when the proc raises the expected exception with an unexpected message" do
+ exc = ExpectedException.new("unexpected")
+ matcher = RaiseErrorMatcher.new(ExpectedException, "expected")
+
+ matcher.matching_exception?(exc).should == false
+ begin
+ matcher.matches?(Proc.new { raise exc })
+ rescue ExpectedException => e
+ matcher.failure_message.should ==
+ ["Expected ExpectedException (expected)", "but got: ExpectedException (unexpected)"]
+ ExceptionState.new(nil, nil, e).message.should ==
+ "Expected ExpectedException (expected)\nbut got: ExpectedException (unexpected)"
+ else
+ raise "no exception"
+ end
+ end
+
+ it "provides a useful failure message when both the exception class and message differ" do
exc = UnexpectedException.new("unexpected")
matcher = RaiseErrorMatcher.new(ExpectedException, "expected")
matcher.matching_exception?(exc).should == false
- lambda {
+ begin
matcher.matches?(Proc.new { raise exc })
- }.should raise_error(UnexpectedException)
- matcher.failure_message.should ==
- ["Expected ExpectedException (expected)", "but got UnexpectedException (unexpected)"]
+ rescue UnexpectedException => e
+ matcher.failure_message.should ==
+ ["Expected ExpectedException (expected)", "but got: UnexpectedException (unexpected)"]
+ ExceptionState.new(nil, nil, e).message.should ==
+ "Expected ExpectedException (expected)\nbut got: UnexpectedException (unexpected)"
+ else
+ raise "no exception"
+ end
end
it "provides a useful failure message when no exception is raised" do
@@ -90,6 +129,18 @@ describe RaiseErrorMatcher do
["Expected ExpectedException (expected)", "but no exception was raised (nil was returned)"]
end
+ it "provides a useful failure message when no exception is raised and the result raises in #pretty_inspect" do
+ result = Object.new
+ def result.pretty_inspect
+ raise ArgumentError, "bad"
+ end
+ proc = Proc.new { result }
+ matcher = RaiseErrorMatcher.new(ExpectedException, "expected")
+ matcher.matches?(proc)
+ matcher.failure_message.should ==
+ ["Expected ExpectedException (expected)", "but no exception was raised (#<Object>(#pretty_inspect raised #<ArgumentError: bad>) was returned)"]
+ end
+
it "provides a useful negative failure message" do
proc = Proc.new { raise ExpectedException, "expected" }
matcher = RaiseErrorMatcher.new(ExpectedException, "expected")
@@ -103,6 +154,6 @@ describe RaiseErrorMatcher do
matcher = RaiseErrorMatcher.new(Exception, nil)
matcher.matches?(proc)
matcher.negative_failure_message.should ==
- ["Expected to not get Exception", "but got UnexpectedException (unexpected)"]
+ ["Expected to not get Exception", "but got: UnexpectedException (unexpected)"]
end
end
diff --git a/spec/mspec/spec/mocks/mock_spec.rb b/spec/mspec/spec/mocks/mock_spec.rb
index d996b5285c..8cf04cf462 100644
--- a/spec/mspec/spec/mocks/mock_spec.rb
+++ b/spec/mspec/spec/mocks/mock_spec.rb
@@ -284,21 +284,21 @@ describe Mock, ".verify_call" do
ScratchPad.recorded.should == 1
end
- it "raises an expection when it is expected to yield but no block is given" do
+ it "raises an exception when it is expected to yield but no block is given" do
@proxy.and_yield(1, 2, 3)
lambda {
Mock.verify_call(@mock, :method_call)
}.should raise_error(SpecExpectationNotMetError)
end
- it "raises an expection when it is expected to yield more arguments than the block can take" do
+ it "raises an exception when it is expected to yield more arguments than the block can take" do
@proxy.and_yield(1, 2, 3)
lambda {
Mock.verify_call(@mock, :method_call) {|a, b|}
}.should raise_error(SpecExpectationNotMetError)
end
- it "does not raise an expection when it is expected to yield to a block that can take any number of arguments" do
+ it "does not raise an exception when it is expected to yield to a block that can take any number of arguments" do
@proxy.and_yield(1, 2, 3)
expect {
Mock.verify_call(@mock, :method_call) {|*a|}
@@ -313,6 +313,58 @@ describe Mock, ".verify_call" do
end
end
+describe Mock, ".verify_call mixing mocks and stubs" do
+ before :each do
+ MSpec.stub(:actions)
+ MSpec.stub(:current).and_return(double("spec state").as_null_object)
+
+ @mock = double('verify_call')
+ end
+
+ after :each do
+ ScratchPad.clear
+ Mock.cleanup
+ end
+
+ it "checks the mock arguments when a mock is defined after a stub" do
+ Mock.install_method @mock, :method_call, :stub
+ Mock.install_method(@mock, :method_call, :mock).with("arg")
+
+ -> {
+ @mock.method_call
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \(\)/)
+
+ -> {
+ @mock.method_call("a", "b")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("a", "b"\)/)
+
+ -> {
+ @mock.method_call("foo")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("foo"\)/)
+
+ @mock.method_call("arg")
+ end
+
+ it "checks the mock arguments when a stub is defined after a mock" do
+ Mock.install_method(@mock, :method_call, :mock).with("arg")
+ Mock.install_method @mock, :method_call, :stub
+
+ -> {
+ @mock.method_call
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \(\)/)
+
+ -> {
+ @mock.method_call("a", "b")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("a", "b"\)/)
+
+ -> {
+ @mock.method_call("foo")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("foo"\)/)
+
+ @mock.method_call("arg")
+ end
+end
+
describe Mock, ".verify_count" do
before :each do
MSpec.stub(:actions)
@@ -396,6 +448,11 @@ describe Mock, ".verify_count mixing mocks and stubs" do
it "verifies the calls to the mocked method when a mock is defined after a stub" do
Mock.install_method @mock, :method_call, :stub
Mock.install_method @mock, :method_call, :mock
+
+ -> {
+ Mock.verify_count
+ }.should raise_error(SpecExpectationNotMetError, /received it 0 times/)
+
@mock.method_call
Mock.verify_count
end
@@ -403,6 +460,11 @@ describe Mock, ".verify_count mixing mocks and stubs" do
it "verifies the calls to the mocked method when a mock is defined before a stub" do
Mock.install_method @mock, :method_call, :mock
Mock.install_method @mock, :method_call, :stub
+
+ -> {
+ Mock.verify_count
+ }.should raise_error(SpecExpectationNotMetError, /received it 0 times/)
+
@mock.method_call
Mock.verify_count
end
@@ -415,7 +477,6 @@ describe Mock, ".cleanup" do
@mock = double('cleanup')
@proxy = Mock.install_method @mock, :method_call
- @stub = Mock.install_method @mock, :method_call, :stub
end
after :each do
@@ -449,6 +510,8 @@ describe Mock, ".cleanup" do
end
it "removes all stubs" do
+ Mock.cleanup # remove @proxy
+ @stub = Mock.install_method @mock, :method_call, :stub
Mock.stubs.should == { Mock.replaced_key(@mock, :method_call) => [@stub] }
Mock.cleanup
Mock.stubs.should == {}
diff --git a/spec/mspec/spec/runner/context_spec.rb b/spec/mspec/spec/runner/context_spec.rb
index d9c20aa0cf..c5aa691323 100644
--- a/spec/mspec/spec/runner/context_spec.rb
+++ b/spec/mspec/spec/runner/context_spec.rb
@@ -55,22 +55,6 @@ describe ContextState, "#to_s" do
it "returns a description string for self when passed a String" do
ContextState.new("SomeClass").to_s.should == "SomeClass"
end
-
- it "returns a description string for self when passed a Module, String" do
- ContextState.new(Object, "when empty").to_s.should == "Object when empty"
- end
-
- it "returns a description string for self when passed a Module and String beginning with '#'" do
- ContextState.new(Object, "#to_s").to_s.should == "Object#to_s"
- end
-
- it "returns a description string for self when passed a Module and String beginning with '.'" do
- ContextState.new(Object, ".to_s").to_s.should == "Object.to_s"
- end
-
- it "returns a description string for self when passed a Module and String beginning with '::'" do
- ContextState.new(Object, "::to_s").to_s.should == "Object::to_s"
- end
end
describe ContextState, "#description" do
@@ -464,11 +448,14 @@ describe ContextState, "#process" do
end
it "shuffles the spec list if MSpec.randomize? is true" do
- MSpec.randomize
- MSpec.should_receive(:shuffle)
- @state.it("") { }
- @state.process
- MSpec.randomize false
+ MSpec.randomize = true
+ begin
+ MSpec.should_receive(:shuffle)
+ @state.it("") { }
+ @state.process
+ ensure
+ MSpec.randomize = false
+ end
end
it "sets the current MSpec ContextState" do
diff --git a/spec/mspec/spec/runner/example_spec.rb b/spec/mspec/spec/runner/example_spec.rb
index b4391f802d..7d3ad6be30 100644
--- a/spec/mspec/spec/runner/example_spec.rb
+++ b/spec/mspec/spec/runner/example_spec.rb
@@ -14,7 +14,7 @@ end
describe ExampleState, "#describe" do
before :each do
- @context = ContextState.new Object, "#to_s"
+ @context = ContextState.new "Object#to_s"
@state = ExampleState.new @context, "it"
end
@@ -64,16 +64,16 @@ end
describe ExampleState, "#filtered?" do
before :each do
- MSpec.store :include, nil
- MSpec.store :exclude, nil
+ MSpec.store :include, []
+ MSpec.store :exclude, []
@state = ExampleState.new ContextState.new("describe"), "it"
@filter = double("filter")
end
after :each do
- MSpec.store :include, nil
- MSpec.store :exclude, nil
+ MSpec.store :include, []
+ MSpec.store :exclude, []
end
it "returns false if MSpec include filters list is empty" do
diff --git a/spec/mspec/spec/runner/exception_spec.rb b/spec/mspec/spec/runner/exception_spec.rb
index 309442435c..0e0a819992 100644
--- a/spec/mspec/spec/runner/exception_spec.rb
+++ b/spec/mspec/spec/runner/exception_spec.rb
@@ -93,7 +93,7 @@ describe ExceptionState, "#message" do
it "returns <No message> if the exception message is empty" do
exc = ExceptionState.new @state, "", Exception.new("")
- exc.message.should == "<No message>"
+ exc.message.should == "Exception: <No message>"
end
it "returns the message without exception class when the exception is an SpecExpectationNotMetError" do
diff --git a/spec/mspec/spec/runner/filters/profile_spec.rb b/spec/mspec/spec/runner/filters/profile_spec.rb
index 78807bca5c..89d0ad1911 100644
--- a/spec/mspec/spec/runner/filters/profile_spec.rb
+++ b/spec/mspec/spec/runner/filters/profile_spec.rb
@@ -15,25 +15,25 @@ describe ProfileFilter, "#find" do
@filter.find(@file).should == @file
end
- it "attemps to locate the file in 'spec/profiles'" do
+ it "attempts to locate the file in 'spec/profiles'" do
path = File.join "spec/profiles", @file
File.should_receive(:exist?).with(path).and_return(true)
@filter.find(@file).should == path
end
- it "attemps to locate the file in 'spec'" do
+ it "attempts to locate the file in 'spec'" do
path = File.join "spec", @file
File.should_receive(:exist?).with(path).and_return(true)
@filter.find(@file).should == path
end
- it "attemps to locate the file in 'profiles'" do
+ it "attempts to locate the file in 'profiles'" do
path = File.join "profiles", @file
File.should_receive(:exist?).with(path).and_return(true)
@filter.find(@file).should == path
end
- it "attemps to locate the file in '.'" do
+ it "attempts to locate the file in '.'" do
path = File.join ".", @file
File.should_receive(:exist?).with(path).and_return(true)
@filter.find(@file).should == path
diff --git a/spec/mspec/spec/runner/filters/regexp_spec.rb b/spec/mspec/spec/runner/filters/regexp_spec.rb
index 6c05b0f42f..8e9b0ec7e8 100644
--- a/spec/mspec/spec/runner/filters/regexp_spec.rb
+++ b/spec/mspec/spec/runner/filters/regexp_spec.rb
@@ -2,12 +2,30 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'mspec/runner/mspec'
require 'mspec/runner/filters/regexp'
+describe MatchFilter, "#===" do
+ before :each do
+ @filter = RegexpFilter.new nil, 'a(b|c)', 'b[^ab]', 'cc?'
+ end
+
+ it "returns true if the argument matches any of the #initialize strings" do
+ @filter.===('ab').should == true
+ @filter.===('bc suffix').should == true
+ @filter.===('prefix cc').should == true
+ end
+
+ it "returns false if the argument matches none of the #initialize strings" do
+ @filter.===('aa').should == false
+ @filter.===('ba').should == false
+ @filter.===('prefix d suffix').should == false
+ end
+end
+
describe RegexpFilter, "#to_regexp" do
before :each do
@filter = RegexpFilter.new nil
end
it "converts its arguments to Regexp instances" do
- @filter.to_regexp('a(b|c)', 'b[^ab]', 'cc?').should == [/a(b|c)/, /b[^ab]/, /cc?/]
+ @filter.send(:to_regexp, 'a(b|c)', 'b[^ab]', 'cc?').should == [/a(b|c)/, /b[^ab]/, /cc?/]
end
end
diff --git a/spec/mspec/spec/runner/formatters/dotted_spec.rb b/spec/mspec/spec/runner/formatters/dotted_spec.rb
index 1e9b06f6e1..5af2ff55f8 100644
--- a/spec/mspec/spec/runner/formatters/dotted_spec.rb
+++ b/spec/mspec/spec/runner/formatters/dotted_spec.rb
@@ -91,7 +91,7 @@ describe DottedFormatter, "#exception" do
@formatter.exception?.should be_true
end
- it "addes the exception to the list of exceptions" do
+ it "adds the exception to the list of exceptions" do
@formatter.exceptions.should == []
@formatter.exception @error
@formatter.exception @failure
diff --git a/spec/mspec/spec/runner/formatters/multi_spec.rb b/spec/mspec/spec/runner/formatters/multi_spec.rb
index afcc7e9cea..d0ed8edc93 100644
--- a/spec/mspec/spec/runner/formatters/multi_spec.rb
+++ b/spec/mspec/spec/runner/formatters/multi_spec.rb
@@ -1,6 +1,8 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'mspec/runner/formatters/dotted'
require 'mspec/runner/formatters/multi'
require 'mspec/runner/example'
+require 'yaml'
describe MultiFormatter, "#aggregate_results" do
before :each do
@@ -9,12 +11,12 @@ describe MultiFormatter, "#aggregate_results" do
@file = double("file").as_null_object
File.stub(:delete)
- YAML.stub(:load)
+ File.stub(:read)
@hash = { "files"=>1, "examples"=>1, "expectations"=>2, "failures"=>0, "errors"=>0 }
- File.stub(:open).and_yield(@file).and_return(@hash)
+ YAML.stub(:load).and_return(@hash)
- @formatter = MultiFormatter.new
+ @formatter = DottedFormatter.new.extend(MultiFormatter)
@formatter.timer.stub(:format).and_return("Finished in 42 seconds")
end
diff --git a/spec/mspec/spec/runner/mspec_spec.rb b/spec/mspec/spec/runner/mspec_spec.rb
index 91338c6ddb..7dad4458d3 100644
--- a/spec/mspec/spec/runner/mspec_spec.rb
+++ b/spec/mspec/spec/runner/mspec_spec.rb
@@ -1,4 +1,5 @@
require 'spec_helper'
+require 'mspec/expectations/expectations'
require 'mspec/helpers/tmp'
require 'mspec/helpers/fs'
require 'mspec/matchers/base'
@@ -8,7 +9,7 @@ require 'mspec/runner/example'
describe MSpec, ".register_files" do
it "records which spec files to run" do
MSpec.register_files [:one, :two, :three]
- MSpec.retrieve(:files).should == [:one, :two, :three]
+ MSpec.files_array.should == [:one, :two, :three]
end
end
@@ -66,9 +67,9 @@ end
describe MSpec, ".randomize" do
it "sets the flag to randomize spec execution order" do
MSpec.randomize?.should == false
- MSpec.randomize
+ MSpec.randomize = true
MSpec.randomize?.should == true
- MSpec.randomize false
+ MSpec.randomize = false
MSpec.randomize?.should == false
end
end
@@ -342,17 +343,19 @@ describe MSpec, ".files" do
end
it "shuffles the file list if .randomize? is true" do
- MSpec.randomize
+ MSpec.randomize = true
MSpec.should_receive(:shuffle)
MSpec.files
- MSpec.randomize false
+ MSpec.randomize = false
end
it "registers the current file" do
- MSpec.should_receive(:store).with(:file, :one)
- MSpec.should_receive(:store).with(:file, :two)
- MSpec.should_receive(:store).with(:file, :three)
+ load = double("load")
+ files = []
+ load.stub(:load).and_return { files << MSpec.file }
+ MSpec.register :load, load
MSpec.files
+ files.should == [:one, :two, :three]
end
end
diff --git a/spec/mspec/spec/spec_helper.rb b/spec/mspec/spec/spec_helper.rb
index 0d497f6627..a307eaf460 100644
--- a/spec/mspec/spec/spec_helper.rb
+++ b/spec/mspec/spec/spec_helper.rb
@@ -1,4 +1,4 @@
-require 'pp'
+require 'mspec/utils/format'
require 'mspec/helpers/io'
require 'mspec/helpers/scratch'
diff --git a/spec/mspec/spec/utils/name_map_spec.rb b/spec/mspec/spec/utils/name_map_spec.rb
index d38230ce06..d5d2cca84a 100644
--- a/spec/mspec/spec/utils/name_map_spec.rb
+++ b/spec/mspec/spec/utils/name_map_spec.rb
@@ -129,7 +129,7 @@ describe NameMap, "#file_name" do
it "returns the name of the spec file based on the special entry for the method" do
@map.file_name("~", "Regexp").should == "match_spec.rb"
- @map.file_name("~", "Fixnum").should == "complement_spec.rb"
+ @map.file_name("~", "Integer").should == "complement_spec.rb"
end
it "returns the name of the spec file based on the default entry for the method" do
@@ -137,7 +137,7 @@ describe NameMap, "#file_name" do
end
it "uses the last component of the constant to look up the method name" do
- @map.file_name("^", "NameMapSpecs::Fixnum").should == "bit_xor_spec.rb"
+ @map.file_name("^", "NameMapSpecs::Integer").should == "bit_xor_spec.rb"
end
end
diff --git a/spec/mspec/spec/utils/options_spec.rb b/spec/mspec/spec/utils/options_spec.rb
index face909286..f3a7046526 100644
--- a/spec/mspec/spec/utils/options_spec.rb
+++ b/spec/mspec/spec/utils/options_spec.rb
@@ -1044,7 +1044,7 @@ describe "The -H, --random option" do
end
it "registers the MSpec randomize mode" do
- MSpec.should_receive(:randomize).twice
+ MSpec.should_receive(:randomize=).twice
["-H", "--random"].each do |opt|
@options.parse opt
end
@@ -1283,3 +1283,22 @@ describe "The -d, --debug option" do
end
end
end
+
+describe "MSpecOptions#all" do
+ it "includes all options" do
+ meth = MSpecOptions.instance_method(:all)
+ file, line = meth.source_location
+ contents = File.read(file)
+ lines = contents.lines
+
+ from = line
+ to = from
+ to += 1 until /^\s*end\s*$/ =~ lines[to]
+ calls = lines[from...to].map(&:strip)
+
+ option_methods = contents.scan(/def (\w+).*\n\s*on\(/).map(&:first)
+ option_methods[0].sub!("configure", "configure {}")
+
+ calls.should == option_methods
+ end
+end
diff --git a/spec/mspec/spec/utils/script_spec.rb b/spec/mspec/spec/utils/script_spec.rb
index 20b5d293b0..c7fa3eb354 100644
--- a/spec/mspec/spec/utils/script_spec.rb
+++ b/spec/mspec/spec/utils/script_spec.rb
@@ -172,7 +172,7 @@ describe MSpecScript, "#load" do
@script.load(@base).should == :loaded
end
- it "attemps to locate the file in '.'" do
+ it "attempts to locate the file in '.'" do
path = File.expand_path @file, "."
File.should_receive(:exist?).with(path).and_return(true)
Kernel.should_receive(:load).with(path).and_return(:loaded)
@@ -186,7 +186,7 @@ describe MSpecScript, "#load" do
@script.load(@base).should == :loaded
end
- it "attemps to locate the file in 'spec'" do
+ it "attempts to locate the file in 'spec'" do
path = File.expand_path @file, "spec"
File.should_receive(:exist?).with(path).and_return(true)
Kernel.should_receive(:load).with(path).and_return(:loaded)
@@ -250,8 +250,8 @@ describe MSpecScript, "#register" do
it "registers :formatter with the formatter instance" do
@formatter.stub(:new).and_return(@formatter)
- MSpec.should_receive(:store).with(:formatter, @formatter)
@script.register
+ MSpec.formatter.should be(@formatter)
end
it "does not register :formatter if config[:formatter] is false" do
@@ -350,20 +350,20 @@ describe MSpecScript, "#entries" do
before :each do
@script = MSpecScript.new
- File.stub(:expand_path).and_return("name")
+ File.stub(:realpath).and_return("name")
File.stub(:file?).and_return(false)
File.stub(:directory?).and_return(false)
end
it "returns the pattern in an array if it is a file" do
- File.should_receive(:expand_path).with("file").and_return("file/expanded.rb")
+ File.should_receive(:realpath).with("file").and_return("file/expanded.rb")
File.should_receive(:file?).with("file/expanded.rb").and_return(true)
@script.entries("file").should == ["file/expanded.rb"]
end
it "returns Dir['pattern/**/*_spec.rb'] if pattern is a directory" do
File.should_receive(:directory?).with("name").and_return(true)
- File.stub(:expand_path).and_return("name","name/**/*_spec.rb")
+ File.stub(:realpath).and_return("name", "name/**/*_spec.rb")
Dir.should_receive(:[]).with("name/**/*_spec.rb").and_return(["dir1", "dir2"])
@script.entries("name").should == ["dir1", "dir2"]
end
@@ -382,13 +382,13 @@ describe MSpecScript, "#entries" do
it "returns the pattern in an array if it is a file" do
name = "#{@name}.rb"
- File.should_receive(:expand_path).with(name).and_return(name)
+ File.should_receive(:realpath).with(name).and_return(name)
File.should_receive(:file?).with(name).and_return(true)
@script.entries("name.rb").should == [name]
end
it "returns Dir['pattern/**/*_spec.rb'] if pattern is a directory" do
- File.stub(:expand_path).and_return(@name, @name+"/**/*_spec.rb")
+ File.stub(:realpath).and_return(@name, @name+"/**/*_spec.rb")
File.should_receive(:directory?).with(@name).and_return(true)
Dir.should_receive(:[]).with(@name + "/**/*_spec.rb").and_return(["dir1", "dir2"])
@script.entries("name").should == ["dir1", "dir2"]
@@ -406,7 +406,7 @@ describe MSpecScript, "#files" do
@script = MSpecScript.new
end
- it "accumlates the values returned by #entries" do
+ it "accumulates the values returned by #entries" do
@script.should_receive(:entries).and_return(["file1"], ["file2"])
@script.files(["a", "b"]).should == ["file1", "file2"]
end
@@ -438,8 +438,9 @@ describe MSpecScript, "#files" do
@script.files([":files"]).should == ["file1", "file2"]
end
- it "returns an empty list if the config key is not set" do
- @script.files([":all_files"]).should == []
+ it "aborts if the config key is not set" do
+ @script.should_receive(:abort).with("Key :all_files not found in mspec config.")
+ @script.files([":all_files"])
end
end
diff --git a/spec/mspec/tool/pull-latest-mspec-spec b/spec/mspec/tool/pull-latest-mspec-spec
new file mode 100755
index 0000000000..154a353e64
--- /dev/null
+++ b/spec/mspec/tool/pull-latest-mspec-spec
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Assumes all commits have been synchronized to https://github.com/ruby/spec
+# See spec/mspec/tool/sync/sync-rubyspec.rb
+
+function sync {
+ dir="$1"
+ repo="$2"
+ short_repo_name="ruby/$(basename "$repo" .git)"
+
+ rm -rf "$dir"
+ git clone --depth 1 "$repo" "$dir"
+ commit=$(git -C "$dir" log -n 1 --format='%h')
+ rm -rf "$dir/.git"
+
+ # Remove CI files to avoid confusion
+ rm -f "$dir/appveyor.yml"
+ rm -f "$dir/.travis.yml"
+ rm -rf "$dir/.github"
+
+ git add "$dir"
+ git commit -m "Update to ${short_repo_name}@${commit}"
+}
+
+sync spec/mspec https://github.com/ruby/mspec.git
+sync spec/ruby https://github.com/ruby/spec.git
diff --git a/spec/mspec/tool/remove_old_guards.rb b/spec/mspec/tool/remove_old_guards.rb
index d0920344eb..718e351e11 100644
--- a/spec/mspec/tool/remove_old_guards.rb
+++ b/spec/mspec/tool/remove_old_guards.rb
@@ -1,4 +1,6 @@
-# Remove old version guards in ruby/spec
+# Removes old version guards in ruby/spec.
+# Run it from the ruby/spec repository root.
+# The argument is the new minimum supported version.
def dedent(line)
if line.start_with?(" ")
@@ -8,9 +10,13 @@ def dedent(line)
end
end
+def each_spec_file(&block)
+ Dir["*/**/*.rb"].each(&block)
+end
+
def remove_guards(guard, keep)
- Dir["*/**/*.rb"].each do |file|
- contents = File.read(file)
+ each_spec_file do |file|
+ contents = File.binread(file)
if contents =~ guard
puts file
lines = contents.lines.to_a
@@ -31,11 +37,30 @@ def remove_guards(guard, keep)
lines[first..last] = []
end
end
- File.write file, lines.join
+ File.binwrite file, lines.join
+ end
+ end
+end
+
+def search(regexp)
+ each_spec_file do |file|
+ contents = File.binread(file)
+ if contents =~ regexp
+ puts file
+ contents.each_line do |line|
+ if line =~ regexp
+ puts line
+ end
+ end
end
end
end
-version = "2.2"
-remove_guards(/ruby_version_is ["']#{version}["'] do/, true)
-remove_guards(/ruby_version_is ["'][0-9.]*["']...["']#{version}["'] do/, false)
+version = Regexp.escape(ARGV.fetch(0))
+version += "(?:\\.0)?" if version.count(".") < 2
+remove_guards(/ruby_version_is (["'])#{version}\1 do/, true)
+remove_guards(/ruby_version_is (["'])[0-9.]*\1 *... *(["'])#{version}\2 do/, false)
+remove_guards(/ruby_bug "#\d+", (["'])[0-9.]*\1 *... *(["'])#{version}\2 do/, true)
+
+search(/(["'])#{version}\1/)
+search(/^\s*#.+#{version}/)
diff --git a/spec/mspec/tool/sync/sync-rubyspec.rb b/spec/mspec/tool/sync/sync-rubyspec.rb
index fbd37fe95b..93e0f538ba 100644
--- a/spec/mspec/tool/sync/sync-rubyspec.rb
+++ b/spec/mspec/tool/sync/sync-rubyspec.rb
@@ -1,6 +1,6 @@
IMPLS = {
truffleruby: {
- git: "https://github.com/graalvm/truffleruby.git",
+ git: "https://github.com/oracle/truffleruby.git",
from_commit: "f10ab6988d",
},
jruby: {
@@ -12,13 +12,14 @@ IMPLS = {
},
mri: {
git: "https://github.com/ruby/ruby.git",
- master: "trunk",
- merge_message: "Update to ruby/spec@",
},
}
MSPEC = ARGV.delete('--mspec')
+CHECK_LAST_MERGE = ENV['CHECK_LAST_MERGE'] != 'false'
+TEST_MASTER = ENV['TEST_MASTER'] != 'false'
+
MSPEC_REPO = File.expand_path("../../..", __FILE__)
raise MSPEC_REPO if !Dir.exist?(MSPEC_REPO) or !Dir.exist?("#{MSPEC_REPO}/.git")
@@ -34,6 +35,9 @@ BRIGHT_RED = "\e[31;1m"
BRIGHT_YELLOW = "\e[33;1m"
RESET = "\e[0m"
+# git filter-branch --subdirectory-filter works fine for our use case
+ENV['FILTER_BRANCH_SQUELCH_WARNING'] = '1'
+
class RubyImplementation
attr_reader :name
@@ -46,10 +50,6 @@ class RubyImplementation
@data[:git]
end
- def default_branch
- @data[:master] || "master"
- end
-
def repo_name
File.basename(git_url, ".git")
end
@@ -64,7 +64,7 @@ class RubyImplementation
end
def last_merge_message
- message = @data[:merge_message] || "Merge ruby/spec commit"
+ message = @data[:merge_message] || "Update to ruby/spec@"
message.gsub!("ruby/spec", "ruby/mspec") if MSPEC
message
end
@@ -97,7 +97,7 @@ def update_repo(impl)
Dir.chdir(impl.repo_name) do
puts Dir.pwd
- sh "git", "checkout", impl.default_branch
+ sh "git", "checkout", "master"
sh "git", "pull"
end
end
@@ -138,14 +138,14 @@ def rebase_commits(impl)
else
last_merge = `git log --grep='^#{impl.last_merge_message}' -n 1 --format='%H %ct'`
end
- last_merge, commit_timestamp = last_merge.chomp.split(' ')
+ last_merge, commit_timestamp = last_merge.split(' ')
raise "Could not find last merge" unless last_merge
puts "Last merge is #{last_merge}"
commit_date = Time.at(Integer(commit_timestamp))
days_since_last_merge = (NOW-commit_date) / 86400
- if days_since_last_merge > 60
+ if CHECK_LAST_MERGE and days_since_last_merge > 60
raise "#{days_since_last_merge.floor} days since last merge, probably wrong commit"
end
@@ -157,53 +157,50 @@ def rebase_commits(impl)
end
end
+def new_commits?(impl)
+ Dir.chdir(SOURCE_REPO) do
+ diff = `git diff master #{impl.rebased_branch}`
+ !diff.empty?
+ end
+end
+
def test_new_specs
require "yaml"
Dir.chdir(SOURCE_REPO) do
- if MSPEC
- sh "bundle", "exec", "rspec"
- else
- versions = YAML.load_file(".travis.yml")
- versions = versions["matrix"]["include"].map { |job| job["rvm"] }
- versions.delete "ruby-head"
- min_version, max_version = versions.minmax
-
- run_rubyspec = -> version {
- command = "chruby #{version} && ../mspec/bin/mspec -j"
- sh ENV["SHELL"], "-c", command
- }
- run_rubyspec[min_version]
- run_rubyspec[max_version]
- run_rubyspec["trunk"]
- end
+ workflow = YAML.load_file(".github/workflows/ci.yml")
+ job_name = MSPEC ? "test" : "specs"
+ versions = workflow.dig("jobs", job_name, "strategy", "matrix", "ruby")
+ versions = versions.grep(/^\d+\./) # Test on MRI
+ min_version, max_version = versions.minmax
+
+ test_command = MSPEC ? "bundle exec rspec" : "../mspec/bin/mspec -j"
+
+ run_test = -> version {
+ command = "chruby #{version} && #{test_command}"
+ sh ENV["SHELL"], "-c", command
+ }
+
+ run_test[min_version]
+ run_test[max_version]
+ run_test["ruby-master"] if TEST_MASTER
end
end
def verify_commits(impl)
puts
Dir.chdir(SOURCE_REPO) do
- history = `git log master...`
- history.lines.slice_before(/^commit \h{40}$/).each do |commit, *message|
- commit = commit.chomp.split.last
- message = message.join
- if /\W(#\d+)/ === message
- puts "Commit #{commit} contains an unqualified issue number: #{$1}"
- puts "Replace it with #{impl.repo_org}/#{impl.repo_name}#{$1}"
- sh "git", "rebase", "-i", "#{commit}^"
- end
- end
-
puts "Manually check commit messages:"
print "Press enter >"
STDIN.gets
- sh "git", "log", "master..."
+ system "git", "log", "master..."
end
end
def fast_forward_master(impl)
Dir.chdir(SOURCE_REPO) do
sh "git", "checkout", "master"
- sh "git", "merge", "--ff-only", "#{impl.name}-rebased"
+ sh "git", "merge", "--ff-only", impl.rebased_branch
+ sh "git", "branch", "--delete", impl.rebased_branch
end
end
@@ -222,10 +219,15 @@ def main(impls)
update_repo(impl)
filter_commits(impl)
rebase_commits(impl)
- test_new_specs
- verify_commits(impl)
- fast_forward_master(impl)
- check_ci
+ if new_commits?(impl)
+ test_new_specs
+ verify_commits(impl)
+ fast_forward_master(impl)
+ check_ci
+ else
+ STDERR.puts "#{BRIGHT_YELLOW}No new commits#{RESET}"
+ fast_forward_master(impl)
+ end
end
end
diff --git a/spec/mspec/tool/tag_from_output.rb b/spec/mspec/tool/tag_from_output.rb
new file mode 100755
index 0000000000..fba52ec26c
--- /dev/null
+++ b/spec/mspec/tool/tag_from_output.rb
@@ -0,0 +1,44 @@
+#!/usr/bin/env ruby
+
+# Adds tags based on error and failures output (e.g., from a CI log),
+# without running any spec code.
+
+tags_dir = %w[
+ spec/tags
+ spec/tags/ruby
+].find { |dir| Dir.exist?("#{dir}/language") }
+abort 'Could not find tags directory' unless tags_dir
+
+output = ARGF.readlines
+
+NUMBER = /^\d+\)$/
+ERROR_OR_FAILED = / (ERROR|FAILED)$/
+SPEC_FILE = /^(\/.+_spec\.rb)\:\d+/
+
+output.slice_before(NUMBER).select { |number, error_line, *rest|
+ number =~ NUMBER and error_line =~ ERROR_OR_FAILED
+}.each { |number, error_line, *rest|
+ description = error_line.match(ERROR_OR_FAILED).pre_match
+
+ spec_file = rest.find { |line| line =~ SPEC_FILE }
+ unless spec_file
+ warn "Could not find file for:\n#{error_line}"
+ next
+ end
+ spec_file = spec_file[SPEC_FILE, 1]
+ prefix = spec_file.index('spec/ruby/') || spec_file.index('spec/truffle/')
+ spec_file = spec_file[prefix..-1]
+
+ tags_file = spec_file.sub('spec/ruby/', "#{tags_dir}/").sub('spec/truffle/', "#{tags_dir}/truffle/")
+ tags_file = tags_file.sub(/_spec\.rb$/, '_tags.txt')
+
+ dir = File.dirname(tags_file)
+ Dir.mkdir(dir) unless Dir.exist?(dir)
+
+ tag_line = "fails:#{description}"
+ lines = File.exist?(tags_file) ? File.readlines(tags_file, chomp: true) : []
+ unless lines.include?(tag_line)
+ puts tags_file
+ File.write(tags_file, (lines + [tag_line]).join("\n") + "\n")
+ end
+}
diff --git a/spec/mspec/tool/wrap_with_guard.rb b/spec/mspec/tool/wrap_with_guard.rb
new file mode 100755
index 0000000000..5b1bf4d7f7
--- /dev/null
+++ b/spec/mspec/tool/wrap_with_guard.rb
@@ -0,0 +1,28 @@
+#!/usr/bin/env ruby
+# Wrap the passed the files with a guard (e.g., `ruby_version_is ""..."3.0"`).
+# Notably if some methods are removed, this is a convenient way to skip such file from a given version.
+# Example usage:
+# $ spec/mspec/tool/wrap_with_guard.rb 'ruby_version_is ""..."3.0"' spec/ruby/library/set/sortedset/**/*_spec.rb
+
+guard, *files = ARGV
+abort "Usage: #{$0} GUARD FILES..." if files.empty?
+
+files.each do |file|
+ contents = File.binread(file)
+ lines = contents.lines.to_a
+
+ lines = lines.map { |line| line.chomp.empty? ? line : " #{line}" }
+
+ version_line = "#{guard} do\n"
+ if lines[0] =~ /^\s*require.+spec_helper/
+ lines[0] = lines[0].sub(/^ /, '')
+ lines.insert 1, "\n", version_line
+ else
+ warn "Could not find 'require spec_helper' line in #{file}"
+ lines.insert 0, version_line
+ end
+
+ lines << "end\n"
+
+ File.binwrite file, lines.join
+end
diff --git a/spec/ruby/.mspec.constants b/spec/ruby/.mspec.constants
new file mode 100644
index 0000000000..6b70274c52
--- /dev/null
+++ b/spec/ruby/.mspec.constants
@@ -0,0 +1,231 @@
+Abbrev
+Addrinfo
+AliasObject
+AliasObject2
+AnonWithConstant
+ArbitraryException
+ArraySub
+ArraySubPush
+AryChild
+Base64
+BaseClass
+BasicSocket
+BeCloseToMatrixMatcher
+BigDecimal
+BigMath
+BitwiseAndTest
+BreakTest
+BreakTest2
+CAPI_SIZEOF_LONG
+CApiModuleSpecsAutoload
+CApiModuleSpecsModuleA
+CGI
+CMath
+CODE_LOADING_DIR
+CSAutoloadA
+CSAutoloadB
+CSAutoloadC
+CSAutoloadD
+CSV
+ChainedNextTest
+ChildClass
+ClassIdUnderAutoload
+ClassSpecDefineClass
+ClassSpecsKeywordWithSemicolon
+ClassSpecsKeywordWithoutSemicolon
+ClassSpecsNumber
+ClassUnderAutoload
+CodingUS_ASCII
+CodingUTF_8
+ComparisonTest
+ConstantSpecsIncludedModule
+ConstantVisibility
+Coverage
+CoverageSpecs
+CustomArgumentError
+DRb
+DRbIdConv
+DRbObject
+DRbUndumped
+Date
+DateTime
+DefSpecNested
+DefSpecNestedB
+DefSpecSingleton
+DefSpecsLambdaVisibility
+DefineMethodByProcClass
+DefineMethodSpecClass
+DefineSingletonMethodSpecClass
+Delegator
+DescArray
+DescObjectTest
+Digest
+DumpableDir
+ERB
+EnsureInClassExample
+EnumerableSpecGrep
+EnumerableSpecGrep2
+EnumerableSpecIncludeP
+EnumerableSpecIncludeP11
+Etc
+EvalBindingA
+EvalBindingProcA
+Exception2MessageMapper
+ExceptionForMatrix
+Fcntl
+FileStat
+FileUtils
+Find
+Forwardable
+GetoptLong
+HMACConstants
+HashStringsBinary
+HashStringsUSASCII
+HashStringsUTF8
+IPAddr
+IPSocket
+Importer
+IncludeSpecsClass
+IncludeSpecsMiddle
+IncludeSpecsTop
+IncludesMath
+JSON
+KSAutoloadA
+KSAutoloadB
+KSAutoloadBB
+KSAutoloadCallsRequire
+KSAutoloadD
+Logger
+MD5Constants
+MY_INPUT4_FOR_ERB
+Matrix
+MatrixSub
+MethodArity
+Meths
+MethsMore
+Mixin
+ModuleSpecsKeywordWithoutSemicolon
+ModuleSpecsToplevel
+ModuleSpecs_CS1
+ModuleSpecs_CS2
+ModuleSpecs_CS3
+MyClass
+MyClass0ForErb
+MyClass1ForErb
+MyClass1ForErb_
+MyClass2ForErb
+MyClass4ForErb
+MyFiber
+MyModule2ForErb
+MyString
+NamespaceTest
+Net
+OBJDIR
+OBJECT_SPACE_TOP_LEVEL_CONSTANT
+OFor
+ObjectSpaceFixtures
+ObjectSpecDup
+ObjectSpecDupInitCopy
+ObjectTest
+Observable
+Open3
+OpenSSL
+OpenStruct
+OperatorImplementor
+OptParse
+OptionParser
+OrAndXorTest
+OtherCustomException
+ParentClass
+Pathname
+Person
+Prime
+Private
+ProcFromMethod
+Psych
+REXML
+RUBY_SIGNALS
+RbReadline
+Readline
+ReceiverClass
+RegexpSpecsSubclass
+RegexpSpecsSubclassTwo
+Reline
+RescueInClassExample
+Resolv
+Ripper
+SHA1Constants
+SHA256Constants
+SHA384Constants
+SHA512Constants
+SameName
+ScanError
+Scanf
+SecondClass
+SecureRandom
+Set
+Shellwords
+SimpleDelegator
+SingleForwardable
+Singleton
+Socket
+SocketError
+SomeClass
+SortedSet
+SpecificExampleException
+Specs
+StrChild
+StrangeEach
+StringIO
+StringRefinement
+StringScanner
+StringSubclass
+StructClasses
+Syck
+Syslog
+TCPServer
+TCPSocket
+TSort
+Tempfile
+TestServer
+Timeout
+TimeoutError
+UDPSocket
+UNIXServer
+UNIXSocket
+URI
+UnaryMinusTest
+UnicodeNormalize
+UnloadableDumpableDir
+UserArray
+UserCustomConstructorString
+UserDefined
+UserDefinedImmediate
+UserDefinedWithIvar
+UserHash
+UserHashInitParams
+UserMarshal
+UserMarshalWithClassName
+UserMarshalWithIvar
+UserObject
+UserPreviouslyDefinedWithInitializedIvar
+UserRegexp
+UserString
+Vector
+WEBrick
+WIN32OLE
+WIN32OLEQueryInterfaceError
+WIN32OLERuntimeError
+WIN32OLE_EVENT
+WIN32OLE_METHOD
+WIN32OLE_PARAM
+WIN32OLE_RECORD
+WIN32OLE_RUBYSPEC
+WIN32OLE_TYPE
+WIN32OLE_TYPELIB
+WIN32OLE_VARIABLE
+WIN32OLE_VARIANT
+WeakRef
+Win32
+YAML
+Zlib
diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml
index a776517b73..a26b525b1c 100644
--- a/spec/ruby/.rubocop.yml
+++ b/spec/ruby/.rubocop.yml
@@ -1,19 +1,47 @@
inherit_from: .rubocop_todo.yml
AllCops:
- TargetRubyVersion: 2.4
+ TargetRubyVersion: 2.5
DisplayCopNames: true
Exclude:
- command_line/fixtures/bad_syntax.rb
DisabledByDefault: true
+Layout/TrailingWhitespace:
+ Enabled: true
+
+Layout/TrailingEmptyLines:
+ Enabled: true
+ Exclude:
+ - library/coverage/fixtures/some_class.rb
+
+Layout/SpaceInLambdaLiteral:
+ Enabled: true
+ EnforcedStyle: require_space
+
Lint:
Enabled: true
+# {...} has higher precedence than do ... end, on purpose
+Lint/AmbiguousBlockAssociation:
+ Enabled: false
+
Lint/AssignmentInCondition:
Enabled: false
-Lint/LiteralInCondition:
+Lint/BooleanSymbol:
+ Enabled: false
+
+Lint/InterpolationCheck:
+ Enabled: false
+
+Lint/LiteralAsCondition:
+ Enabled: false
+
+Lint/RedundantRequireStatement:
+ Enabled: false
+
+Lint/RedundantSplatExpansion:
Enabled: false
Lint/UnifiedInteger:
@@ -31,10 +59,75 @@ Lint/UselessAssignment:
Lint/UselessComparison:
Enabled: false
-# The cop registers too many false positives to `.should == something`
Lint/Void:
Enabled: false
Lint/EmptyExpression:
Exclude:
- 'language/**/*.rb'
+
+Lint/EmptyWhen:
+ Exclude:
+ - language/case_spec.rb
+ - optional/capi/spec_helper.rb
+
+Lint/FormatParameterMismatch:
+ Exclude:
+ - 'core/kernel/shared/sprintf.rb'
+ - 'core/string/modulo_spec.rb'
+
+Lint/NestedMethodDefinition:
+ Exclude:
+ - language/def_spec.rb
+ - language/fixtures/def.rb
+
+Lint/ShadowingOuterLocalVariable:
+ Exclude:
+ - 'core/binding/local_variables_spec.rb'
+ - 'core/kernel/local_variables_spec.rb'
+ - 'language/block_spec.rb'
+ - 'language/proc_spec.rb'
+
+Lint/UnreachableCode:
+ Exclude:
+ - 'core/enumerator/lazy/fixtures/classes.rb'
+ - 'core/kernel/catch_spec.rb'
+ - 'core/kernel/raise_spec.rb'
+ - 'core/kernel/throw_spec.rb'
+ - 'language/break_spec.rb'
+ - 'language/fixtures/break.rb'
+ - 'language/fixtures/break_lambda_toplevel.rb'
+ - 'language/fixtures/break_lambda_toplevel_block.rb'
+ - 'language/fixtures/break_lambda_toplevel_method.rb'
+ - 'language/fixtures/return.rb'
+ - 'language/next_spec.rb'
+ - 'language/return_spec.rb'
+ - 'optional/capi/kernel_spec.rb'
+ - 'shared/kernel/raise.rb'
+
+Lint/UriRegexp:
+ Exclude:
+ - 'library/uri/regexp_spec.rb'
+
+Lint/Debugger:
+ Exclude:
+ - 'core/binding/fixtures/irb.rb'
+
+Lint/Loop:
+ Enabled: false
+
+Style/Lambda:
+ Enabled: true
+ EnforcedStyle: literal
+ Exclude:
+ - 'language/lambda_spec.rb'
+ - 'language/proc_spec.rb'
+ - 'language/numbered_parameters_spec.rb'
+ - 'core/kernel/lambda_spec.rb'
+
+Style/EmptyLambdaParameter:
+ Enabled: true
+
+Style/StabbyLambdaParentheses:
+ Enabled: true
+ EnforcedStyle: require_no_parentheses
diff --git a/spec/ruby/.rubocop_todo.yml b/spec/ruby/.rubocop_todo.yml
index cb91f43ead..a469213841 100644
--- a/spec/ruby/.rubocop_todo.yml
+++ b/spec/ruby/.rubocop_todo.yml
@@ -1,26 +1,11 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
-# on 2017-06-18 19:12:38 +0200 using RuboCop version 0.49.1.
+# on 2019-12-12 22:16:26 +0900 using RuboCop version 0.77.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
-# Offense count: 6
-Lint/AmbiguousBlockAssociation:
- Exclude:
- - 'core/kernel/trace_var_spec.rb'
- - 'language/fixtures/argv_encoding.rb'
- - 'language/fixtures/break.rb'
- - 'shared/process/abort.rb'
-
-# Offense count: 3
-Lint/CircularArgumentReference:
- Exclude:
- - 'language/block_spec.rb'
- - 'language/def_spec.rb'
- - 'language/lambda_spec.rb'
-
# Offense count: 2
Lint/DuplicateCaseCondition:
Exclude:
@@ -35,12 +20,7 @@ Lint/DuplicateMethods:
- 'core/unboundmethod/fixtures/classes.rb'
- 'fixtures/class.rb'
-# Offense count: 4
-Lint/EmptyWhen:
- Exclude:
- - 'language/case_spec.rb'
-
-# Offense count: 5
+# Offense count: 8
Lint/EnsureReturn:
Exclude:
- 'language/fixtures/ensure.rb'
@@ -48,20 +28,16 @@ Lint/EnsureReturn:
- 'language/return_spec.rb'
# Offense count: 10
-Lint/FloatOutOfRange:
+Lint/FlipFlop:
Exclude:
- - 'core/string/modulo_spec.rb'
+ - 'language/if_spec.rb'
+ - 'language/precedence_spec.rb'
-# Offense count: 46
-Lint/FormatParameterMismatch:
+# Offense count: 10
+Lint/FloatOutOfRange:
Exclude:
- - 'core/kernel/sprintf_spec.rb'
- 'core/string/modulo_spec.rb'
-# Offense count: 25
-Lint/HandleExceptions:
- Enabled: false
-
# Offense count: 2
Lint/ImplicitStringConcatenation:
Exclude:
@@ -74,49 +50,57 @@ Lint/IneffectiveAccessModifier:
- 'core/module/fixtures/classes.rb'
- 'language/fixtures/private.rb'
-# Offense count: 5
+# Offense count: 6
# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# Configuration parameters: EnforcedStyle.
# SupportedStyles: runtime_error, standard_error
Lint/InheritException:
Exclude:
- 'core/enumerator/lazy/fixtures/classes.rb'
- 'core/exception/fixtures/common.rb'
- 'core/module/fixtures/autoload_ex1.rb'
+ - 'shared/kernel/raise.rb'
-# Offense count: 3
+# Offense count: 72
# Cop supports --auto-correct.
Lint/LiteralInInterpolation:
Exclude:
+ - 'core/module/refine_spec.rb'
+ - 'core/regexp/shared/new.rb'
+ - 'core/string/shared/to_sym.rb'
+ - 'language/alias_spec.rb'
- 'language/defined_spec.rb'
- 'language/fixtures/squiggly_heredoc.rb'
-
-# Offense count: 16
-Lint/Loop:
- Exclude:
- - 'language/until_spec.rb'
- - 'language/while_spec.rb'
+ - 'language/string_spec.rb'
+ - 'language/symbol_spec.rb'
+ - 'language/undef_spec.rb'
+ - 'library/net/ftp/connect_spec.rb'
# Offense count: 8
# Cop supports --auto-correct.
-Lint/MultipleCompare:
+Lint/MultipleComparison:
Exclude:
- 'language/precedence_spec.rb'
-# Offense count: 8
-Lint/NestedMethodDefinition:
- Exclude:
- - 'language/def_spec.rb'
-
-# Offense count: 12
+# Offense count: 9
Lint/ParenthesesAsGroupedExpression:
Exclude:
- - 'command_line/rubyopt_spec.rb'
- 'core/string/fixtures/freeze_magic_comment.rb'
- 'language/block_spec.rb'
- 'language/fixtures/send.rb'
- 'language/method_spec.rb'
- - 'library/socket/socket/getaddrinfo_spec.rb'
+
+# Offense count: 2
+# Cop supports --auto-correct.
+Lint/RedundantStringCoercion:
+ Exclude:
+ - 'core/io/print_spec.rb'
+
+# Offense count: 1
+# Cop supports --auto-correct.
+Lint/RedundantWithIndex:
+ Exclude:
+ - 'core/enumerator/with_index_spec.rb'
# Offense count: 22
Lint/RescueException:
@@ -126,79 +110,34 @@ Lint/RescueException:
- 'core/exception/cause_spec.rb'
- 'core/exception/no_method_error_spec.rb'
- 'core/kernel/fixtures/autoload_frozen.rb'
+ - 'core/kernel/raise_spec.rb'
- 'core/module/autoload_spec.rb'
- 'core/mutex/sleep_spec.rb'
- - 'core/process/euid_spec.rb'
- - 'core/process/setsid_spec.rb'
- - 'core/process/uid_spec.rb'
- 'core/thread/abort_on_exception_spec.rb'
- 'core/thread/shared/exit.rb'
- 'language/rescue_spec.rb'
- 'library/erb/filename_spec.rb'
-# Offense count: 1
-Lint/ScriptPermission:
- Exclude:
- - 'command_line/fixtures/bin/launcher.rb'
-
-# Offense count: 10
-Lint/ShadowingOuterLocalVariable:
+# Offense count: 4
+# Configuration parameters: IgnoreImplicitReferences.
+Lint/ShadowedArgument:
Exclude:
- - 'core/binding/local_variables_spec.rb'
- - 'language/block_spec.rb'
- - 'language/proc_spec.rb'
+ - 'language/fixtures/super.rb'
-# Offense count: 2
-# Cop supports --auto-correct.
-Lint/StringConversionInInterpolation:
- Exclude:
- - 'core/io/print_spec.rb'
+# Offense count: 39
+# Configuration parameters: AllowComments.
+Lint/SuppressedException:
+ Enabled: false
# Offense count: 9
+# Configuration parameters: AllowKeywordBlockArguments.
Lint/UnderscorePrefixedVariableName:
Exclude:
- 'core/io/pipe_spec.rb'
- 'core/io/popen_spec.rb'
- 'language/block_spec.rb'
-# Offense count: 91
-# Cop supports --auto-correct.
-Lint/UnneededSplatExpansion:
- Exclude:
- - 'core/array/element_reference_spec.rb'
- - 'core/array/unshift_spec.rb'
- - 'core/enumerable/fixtures/classes.rb'
- - 'core/enumerable/max_by_spec.rb'
- - 'core/enumerable/min_by_spec.rb'
- - 'core/enumerable/minmax_by_spec.rb'
- - 'core/enumerator/lazy/fixtures/classes.rb'
- - 'core/file/basename_spec.rb'
- - 'core/kernel/p_spec.rb'
- - 'language/array_spec.rb'
- - 'language/break_spec.rb'
- - 'language/case_spec.rb'
- - 'language/next_spec.rb'
- - 'language/send_spec.rb'
- - 'language/variables_spec.rb'
-
-# Offense count: 53
-Lint/UnreachableCode:
- Exclude:
- - 'core/enumerator/lazy/fixtures/classes.rb'
- - 'core/kernel/catch_spec.rb'
- - 'core/kernel/throw_spec.rb'
- - 'language/break_spec.rb'
- - 'language/fixtures/break.rb'
- - 'language/fixtures/break_lambda_toplevel.rb'
- - 'language/fixtures/break_lambda_toplevel_block.rb'
- - 'language/fixtures/break_lambda_toplevel_method.rb'
- - 'language/fixtures/return.rb'
- - 'language/next_spec.rb'
- - 'language/return_spec.rb'
- - 'optional/capi/kernel_spec.rb'
- - 'shared/kernel/raise.rb'
-
-# Offense count: 9
+# Offense count: 7
# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
Lint/UselessAccessModifier:
Exclude:
@@ -206,6 +145,4 @@ Lint/UselessAccessModifier:
- 'core/module/fixtures/classes.rb'
- 'core/module/module_function_spec.rb'
- 'core/module/private_class_method_spec.rb'
- - 'core/module/private_spec.rb'
- - 'core/module/protected_spec.rb'
- - 'core/module/public_spec.rb'
+ - 'language/fixtures/send.rb'
diff --git a/spec/ruby/.travis.yml b/spec/ruby/.travis.yml
deleted file mode 100644
index 1a2e64ff84..0000000000
--- a/spec/ruby/.travis.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-sudo: false
-language: ruby
-install:
- - git clone https://github.com/ruby/mspec.git ../mspec
-script:
- - if [ -n "$RUBOCOP" ]; then gem install rubocop -v 0.49.1 && rubocop; fi
- - ../mspec/bin/mspec $MSPEC_OPTS
-matrix:
- include:
- - os: osx
- rvm: 2.4.0
- - os: linux
- rvm: 2.4.1
- env: MSPEC_OPTS="-R2 -ff"
- - os: linux
- rvm: 2.2.7
- - os: linux
- rvm: 2.3.4
- - os: linux
- rvm: 2.4.1
- env: CHECK_LEAKS=true RUBOCOP=true
- - os: linux
- rvm: ruby-head
- allow_failures:
- - os: linux
- rvm: ruby-head
-branches:
- only:
- - master
- - /^try/
-notifications:
- email:
- on_success: change
- on_failure: change
diff --git a/spec/ruby/CHANGES.before-2008-05-10 b/spec/ruby/CHANGES.before-2008-05-10
deleted file mode 100644
index 18778bc146..0000000000
--- a/spec/ruby/CHANGES.before-2008-05-10
+++ /dev/null
@@ -1,17796 +0,0 @@
- Changelog
-===========
-
-This file contains the entire revision history of the specs from
-December 2006 onwards, when the spec project got started more or
-less officially by converting the remaining Test::Unit style tests
-in Rubinius to the spec style. The history is not preserved in the
-git repository history itself, so this data is here for reference.
-All the commit hashes are from the Rubinius repository.
-
-It still misses quite a few of the earlier, disparate specs and
-tests because up to that point the organisation was much looser
-and gathering an exhaustive accounting of the entire history of
-TDD/BDD would be time-consuming, particularly with the few full
-directory moves in there and such. All of the data is preserved
-in the Rubinius repository if someone is interested in that bit
-of history.
-
-Be aware that the history contains some Rubinius-specific specs
-by necessity. If you find any commits listed that were _solely_
-for Rubinius, feel free to strip them out.
-
-Thanks to everyone committing up to this point--over 2600 commits
-in just this incomplete version. Keep it up.
-
-
-
- Revision History
-------------------
-
-
-commit 2b24a1e84c350810817885eeb6532f43c698a95c
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Fri May 9 16:45:07 2008 -0700
-
- Fixed up pack for base64 and uuencode to be MUCH MUCH cleaner and 2x faster
-
-commit 022bc5dbfafcf1f9fd5e25820104718bd4d45661
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 9 23:51:47 2008 +0200
-
- Share common specs for BigDecimal's #mult and #*.
-
-commit 414e7eedce9d0cea982e24f1031c407daccc648b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 9 23:19:38 2008 +0200
-
- New rubyspecs for BigDecimal#mult
-
- * Verifies that proper signs are calculated when
- zero is involved.
-
-commit 6883d7d0c67f7be84e7ea1703912452eaecaac6c
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 9 22:54:49 2008 +0200
-
- New rubyspec for Module#new with block.
-
-commit f8bd3e34014a7351470685676b6b168abd787794
-Author: Phil Hagelberg <technomancy@gmail.com>
-Date: Fri May 9 12:53:00 2008 -0700
-
- Added specs for OpenSSL::HMAC.hexdigest and .digest
-
-commit 686c28493d42b9c798aa791823395d1000423225
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 9 20:20:13 2008 +0200
-
- Some more rubyspecs for BigDecimal's #floor and #ceil.
-
-commit aba022a6620ec8d3a09067e9677f0f9c5d8078ee
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 9 17:51:35 2008 +0200
-
- New rubyspecs for BigDecimal's #floor and #ceil.
-
-commit e4d844ba5851a798b7acb684cf68fdcef353d13c
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu May 8 22:13:58 2008 -0700
-
- Excluded stdlib specs from default CI run. Added spec/full.mspec.
-
-commit 6a133574617cb435ad1684f208430112ff6839f6
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu May 8 16:19:50 2008 -0700
-
- String#unpack overhaul. NO extra methods littered through Fixnum/Integer/String. NO procs. More readable, but still messy.
-
-commit 11dd3ae2c4e0dd81304e85ba662db41196f1ce4c
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed May 7 23:59:31 2008 -0700
-
- Fixed constant type clash for ModuleSpecs modules.
-
-commit 4e702d10b32fdba62cdeae476b8217019839c3b0
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed May 7 21:42:11 2008 -0700
-
- Some specs for Kernel#__add_method__ and Module.__add_method__.
-
-commit 819649f24f59819be185b0562b94f9089f8c000c
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed May 7 14:48:01 2008 -0700
-
- Added spec for Kernel#eval with binding from method defined by #eval.
-
-commit d73b17b88b6084fdf7cab764b0fbdd3b3882dd81
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed May 7 10:06:26 2008 -0700
-
- Use literals in Bignum#to_f specs (alternate fix for #535).
-
-commit ee211770eb8792b3f58f78ff60eec6d5289caa20
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Wed May 7 02:38:00 2008 -0700
-
- Added specs for big uncovered areas, still not 100%
-
-commit 7ce9bc2d7edc64f6886c3d34836bc0394414ed66
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue May 6 03:56:19 2008 -0700
-
- Fixed typo
-
-commit af3407251ee0f287ec80232c354153af169636e4
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue May 6 22:01:23 2008 +1000
-
- Fix bug in Debugger::Output.wrap
-
-commit d9322306ea70f2b847b0f806bdb13ea02f2d6b4d
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon May 5 13:09:32 2008 -0400
-
- Fix some bugs in BigDecimal#/. More may yet lurk.
-
-commit 2f3a4cc14433858b13caa932c8a50c31e024c7e8
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Mon May 5 12:04:26 2008 -0500
-
- Adding more specs for REXML::Element
-
- * Covers REXML::Element#{add_attribute, add_attributes, add_namespace, add_text, clone, comments}
-
-commit 7db8c2b563ea474cf2db5fa14bb2a6345c8c469f
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Mon May 5 10:54:00 2008 -0500
-
- One more case for YAML.load specs
-
-commit 098decdf510b05f82ff9a6cc6769cf478a3236ab
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sun May 4 22:29:35 2008 -0400
-
- Define BigDecimal#ver.
-
-commit f6f1fe6a667570e4c1521649b964dca1352d1c32
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sun May 4 22:12:08 2008 -0400
-
- BigDecimal#new: Make space between '-' and 'Infinity' unparsable, as per spec.
-
-commit 503aae7cdbb208da8f25080762e17f0866845c4d
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon May 5 06:19:40 2008 -0400
-
- Method call parsing spec from Jim Kingdon with minor addition.
-
- * Moved the SyntaxError producing code into an #eval because the file
- cannot be compiled to run otherwise.
-
-commit 398d5de0a0ffaf746e39e5f6a6ded02483fd1842
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon May 5 02:26:39 2008 -0400
-
- Spec for :match node, implicit Regexp matches against $_.
-
- * Compiler and Language specs.
-
-commit 206cea31c6a93fe434948dcb79321e2c119edf21
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat May 3 11:40:17 2008 -0400
-
- Implement BigDecimal#power and #**, fix some bugs in #mult.
-
-commit a197099d9be6e48ad32480ae323302c83146147b
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat May 3 02:18:35 2008 -0400
-
- Fixed a logic and syntax error in BigDecimal#mult specs.
-
- * Removed some parentheses too.
-
-commit 081afd58a29ccd5025b806f53e9d7679b9296a7f
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat May 3 02:25:45 2008 -0400
-
- Make sure subclasses that implement their own Hash#default work (Merb)
-
-commit 203ca288175416fadb110b2aa9cdf8cfbf13215d
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat May 3 01:49:35 2008 -0400
-
- Specs and implementation for module include order (fixes abstract.rb)
-
-commit c788a9f2d9c4561a2837bbf78f68a6885d626917
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 18:14:32 2008 -0400
-
- Implement BigDecimal#*, as well as #mult without precision support.
-
-commit 57d78528ff4cf249d906785ffbfdde1fda4aa3cc
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 17:36:15 2008 -0400
-
- Implement BigDecimal#/ and #quo. Not perfect; still relies on #/.
-
-commit c42cc2cacc347d8284650c7046d4dadf94d7d4a5
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 16:13:07 2008 -0400
-
- Fix a typo in specs.
-
-commit ae179b410665da18628f249e6796f1e07ab83763
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 16:10:43 2008 -0400
-
- Get BigDecimal#floor basically working.
- * The failing specs depend on #/, which isn't implemented yet.
-
-commit f8221117d174b91affe406c8089ed25e887232b3
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 16:06:32 2008 -0400
-
- Fix bugs in BigDecimal#add and #+. This also affects #sub, #-, and #ceil.
-
-commit cdd196daf7643e846b7f3582b1e441b883e02aba
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 15:41:29 2008 -0400
-
- More specs to fix bugs in BigDecimal#add and #+.
-
-commit c1c52a2a531b570fa1025d99e464d93c570cf59e
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 15:22:33 2008 -0400
-
- Write another spec for BigDecimal#ceil.
-
-commit 71b65cdbfa5aae461fc52c997df9fca3bee9c8d5
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri May 2 14:47:34 2008 -0400
-
- Write tests for a bug in BigDecimal#add and #+ where 0 + 1 = 0.1.
-
-commit 55988ef53879c1c489c570b3f37717365c7f8e2b
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat May 3 01:04:11 2008 -0400
-
- Fix use of alias keyword inside instance_eval
-
-commit d4011595a0077e91665f85410d458c57367cf50b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 2 20:38:15 2008 +0200
-
- Added news specs for BigDecimal#mult.
-
-commit b6771644d35b6b8f3c87f7f4461bcaba99cd976f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 2 19:41:09 2008 +0200
-
- More BigDecimal#divmod rubyspecs.
-
- MRI-specific bug is hidden behind ruby-bug guard.
-
-commit 854a011324ce717cfd47ddec6389a9e9abb0db18
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 2 18:45:29 2008 +0200
-
- New BigDecimal#divmod specs.
-
-commit b9806e0efb2a8e51d70f6d51733df7bed88152d9
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 2 16:45:10 2008 +0200
-
- A couple of test cases for BigDecimal's #quo, #div, #/.
-
-commit 3cf6c1e03001ba1dda966e3392b665f5b08a1b9d
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri May 2 15:03:37 2008 +0200
-
- More tests for BigDecimal#floor.
-
-commit b70023978562af89cf4349e14e9443adb37ecbbe
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu May 1 21:15:29 2008 -0400
-
- Improved a spec description for String#index.
-
- * The description looks exactly like we had the wrong implementation
- relying on % 256 and someone wrote a spec to make sure that did not
- happen. However, the description was more or less meaningless to
- what was actually being specced.
-
-commit 6e6aa411ff4c7a837d5d4adb9ab893719cf9e122
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu May 1 10:48:20 2008 -0700
-
- Fix a number of things to pass all def specs
-
- This is the result of ping-pong between Evan and Wilson. It refactors
- out enclosing_class from being used, and instead information is always
- pulled directly from the StaticScope object. This lets us inject proper
- scoping changes in ruby.
-
-commit 2db27aef88e2ca7752beba846d172ede276275e0
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu May 1 19:03:50 2008 +0200
-
- Implemented Socket.unpack_sockaddr_un
-
-commit d515221698e02b52ed4661113d659744fbfae36f
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu May 1 18:18:32 2008 +0200
-
- Forgot to update spec tags for TCPSocket.gethostbyname
-
-commit bf839a99c3a5b773b6b96c6d5a1fcc5056511e7a
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu May 1 14:03:30 2008 +0200
-
- Implement File#mtime specs
-
-commit b8c713e6b972b464788c740b4283a5b4226c123c
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu May 1 13:55:36 2008 +0200
-
- Implemented File.lchmod and initial specs
-
-commit 059c926d7280c2e7c9f8bf710c5aef70cde3e777
-Author: Adam Wiggins <adam@heroku.com>
-Date: Sun Apr 27 15:03:31 2008 -0700
-
- IO.popen read/write pipes
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit d9a050aa45efd00a40395b7ac7ac069f4be1fd1c
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu May 1 16:25:18 2008 +1000
-
- Spec fixes for Tuple#to_a
-
-commit 0b610359fbfe8137fdba95d90b659238168d6788
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Wed Apr 30 17:45:51 2008 -0400
-
- Update spectags.
-
-commit 024ebfdf3fa9c54b8a81134edb52fe10b09e4b91
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 30 22:56:44 2008 +0200
-
- Added BigDecimal#divmod excludes.
-
-commit e12d21a90760df723c0f48265cb49a9c4463db7c
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 30 20:51:06 2008 +0200
-
- More tests for BigDecimal#divmod.
-
-commit 68cfef604f9b5411ca9e0349883bac4f59541f0d
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Wed Apr 30 16:47:31 2008 -0400
-
- Make BigDecimal#finite? handle NaN correctly, and refactor accordingly.
-
-commit 5066bcb8881241caf6d13be625b32633bda6567e
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Wed Apr 30 15:01:12 2008 -0400
-
- Make BigDecimal#<= and #>= pass Vladimir's new specs.
-
-commit 49601aff01c394fe2168f5f221a987be63a9ebc7
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 30 20:20:18 2008 +0200
-
- Various improvements to BigDecimal rubyspecs.
-
- * Corrected comparison specs (properly add arrays there)
- * New reminder specs
- * New modulo and % specs
- * Tagged rbx failures
-
-commit dd1700b747ba26b27eff0b249623aca559db06e1
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 30 17:48:20 2008 +0200
-
- More test cases for BigDecimal#modulo and #%.
-
-commit 8eb9dc1b0aee3587f4da8b9cbe306fd431159d79
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 30 16:57:16 2008 +0200
-
- New specs for BigDecimal#modulo and #%.
-
-commit 4a846f807fe2c4c12d8719bc5c9ccb4ab696aff9
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Tue Apr 29 15:29:34 2008 -0500
-
- Fixes REXML::Element#namespaces specs
-
- * Use sort on the arrays to make sure the specs pass on JRuby too.
-
-commit 823683a864072ef6a81e808dbf792dee45d29c52
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Tue Apr 29 14:54:08 2008 -0500
-
- Adds more specs for REXML.
-
- * Specs for REXML#{inspect, namespace, namespaces, prefixes, text and text=}.
-
-commit a11a10760ce92ee373e04a5445234521a27874cc
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 28 17:55:55 2008 -0400
-
- Committing so we can bisect.
-
-commit df94214b1d132b02e3dd5b166d1c7c5cd5d50a21
-Author: Drew Olson <olsonas@gmail.com>
-Date: Mon Apr 28 19:21:07 2008 -0700
-
- Added spec for Array#remove_outer_arrays
-
-commit ec4ece9c06b42c257b4ffce2cf319f0ad23f65e8
-Author: Drew Olson <olsonas@gmail.com>
-Date: Sun Apr 27 20:15:47 2008 -0500
-
- Added more edge cases for recursive arrays to spec for File#join
- * an empty array containing an empty array which contains a recursive array should return
- '[...]' when File#join is called on it.
-
-commit 698a5d291cf63e56e9a3508a8850c77fa2c23430
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 28 16:17:05 2008 -0400
-
- Implement BigDecimal#=== as alias of #eql?.
-
-commit 18f515e735eecc519be55a6e3253db7135a137ad
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 28 16:09:43 2008 -0400
-
- Implement BigDecimal#sub.
-
-commit b331faa567dc1d98163c6447897221877cf756eb
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 28 16:04:06 2008 -0400
-
- Implement BigDecimal#add.
-
-commit f3f94c9b53045ddde335981897e2f6087dab7ef2
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Apr 28 12:01:41 2008 -0500
-
- hack to fix DRb.start_service spec to at least test start_service
-
-commit 4c8d6d90c69615386e26c71633e242f4e1f19342
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Apr 28 11:56:47 2008 -0500
-
- spec for DRb.stop_service to see if it clears the socket correctly
-
-commit 03cb539f42f0b558fa29911c1dfc71ec5f2b183f
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Apr 28 11:20:17 2008 -0500
-
- Revert "Revert "Made DRb spec depend partially on PID so multiple runs don't clash.""
-
- Apparently this is a supposed fix for concurrent spec runs, not for the spec failure
-
- This reverts commit 08695d9a6940ab74f6eb8965e449a417002a42a6.
-
-commit 2172e2ac20b69a97c2ad66551b3620a43bfda700
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 28 02:14:18 2008 -0400
-
- Make BigDecimal#exponent return Bignums as necessary, not just Fixnums.
-
-commit dc93d06163e80cdf89a67532654a850828119287
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 28 01:23:19 2008 -0400
-
- Correct implementation of BigDecimal#+ and #-. There's still a lot of repetition to be factored out, but this algorithm is more correct than the last try.
-
-commit 1da58bb7f0afbba4f8412e06983304dc7d887ac9
-Author: Luis Lavena <luislavena@gmail.com>
-Date: Thu Apr 24 16:37:59 2008 -0300
-
- Corrected small typo on File#join specs under Windows.
-
-commit b287619579ad11535722a2374b6f849d88fe9931
-Author: Drew Olson <olsonas@gmail.com>
-Date: Thu Apr 24 14:24:10 2008 -0700
-
- Spec for File#join now describes correct behavior for arrays with recursive sub-arrays.
-
-commit 5830380895c0bec16c6af39d0f29d8d70268028d
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Sun Apr 27 14:53:47 2008 -0500
-
- DRb.start_service spec fails because of a timing bug in DRb
-
- See http://jira.codehaus.org/browse/JRUBY-2347
-
-commit 08695d9a6940ab74f6eb8965e449a417002a42a6
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Sun Apr 27 14:51:16 2008 -0500
-
- Revert "Made DRb spec depend partially on PID so multiple runs don't clash."
-
- The spec is designed for sane behavior, if Rubinius or the
- implementation of DRb is causing problems then they should be
- fixed, not the spec in this case. Fixing the spec will only
- hide the bug.
-
- See http://jira.codehaus.org/browse/JRUBY-2347 for more commentary on the problem.
-
- This reverts commit f89bd8c6c425c9d9bcc3e589b8d3b05ce3ccbced.
-
-commit 94ba0884c8e7f398b6fe8d6736834f62f6a49815
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Apr 27 21:23:47 2008 +0200
-
- More checks for BigDecimal#abs specs.
-
-commit 80932d25ca95e2e8c803d244a7636e3004525ade
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Apr 27 21:10:26 2008 +0200
-
- More test cases for BigDecimal#finite? specs.
-
-commit 4b541ed23ccac65f6f4b2ef8aad56e9aa7a69e12
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Apr 27 21:04:08 2008 +0200
-
- Added testcase for BigDecimal#infinite? for NaN.
-
-commit 4a1f39426fc60ae7c2ed0470259fa0752a46d030
-Author: Adam Wiggins <adam@heroku.com>
-Date: Sat Apr 26 22:57:09 2008 -0700
-
- IO#write returns 0 when writing a blank string, to match behavior of MRI
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 56c0088f9b075769933c8c87e3c2d256cff3a3e8
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sun Apr 27 00:28:47 2008 -0400
-
- Typo.
-
-commit c11410654b9046cdb58dba1d116f58ce74f4c263
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sun Apr 27 00:24:32 2008 -0400
-
- Finish implementing #@- and #infinite?. Update spectags, of course
-
-commit dc9f427ecb9d55559d800af70f9c1a3f2f2123b5
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sun Apr 27 00:07:31 2008 -0400
-
- Amplify a comment.
-
-commit b9776b953ae67f2088e44b640145af464a1cf942
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sun Apr 27 00:02:48 2008 -0400
-
- Get BigDecimal#+ working. I hate this algorithm, but it works without running out of memory.
- * Update spec tags.
-
-commit b87ff5c22891f19ad0b956e7e02cc3a3d1adcc93
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 14:27:00 2008 -0400
-
- Implement BigDecimal#coerce.
- * Update spectags.
- * Rewrite one spec so it doesn't depend on BigDecimal#-, which is not yet implemented.
-
-commit f89bd8c6c425c9d9bcc3e589b8d3b05ce3ccbced
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Apr 26 15:52:49 2008 -0700
-
- Made DRb spec depend partially on PID so multiple runs don't clash.
-
-commit 3c49a1d16f20726c4ee2d7eb5f5c671537aa59d5
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Apr 26 15:13:47 2008 -0700
-
- Added wordsize guard for BigDecimal#exponent spec.
-
-commit 3aac5f6d64f4cbbca70ecf01b7ed9be596fa5b76
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Apr 26 15:09:40 2008 -0700
-
- Updated spec_helper and renamed CaptureOutput to IOStub.
-
-commit 94322a6a95770a030d28925cc7213a38c5687ea1
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Apr 26 23:16:59 2008 +0200
-
- A bit more test cases for BigDecimal#-@.
-
-commit 9919c5e3be59562532c967b479c959cf6270046e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Apr 26 21:01:44 2008 +0200
-
- New specs for BigDecimal#uminus.
-
-commit c3e74531f1ca1e70671f529671c0fa474968dc87
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Sat Apr 26 13:08:04 2008 +0200
-
- FreeBSD seems to work like the rest, not darwin
-
- Tested on FreeBSD/i386 7-STABLE
-
-commit c06a091b285f388f09b11037975921662759eea2
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 12:14:33 2008 -0400
-
- Implement BigDecimal#exponent, update spectags. Looks like parts of #** have accidentally stopped failing too. :)
-
-commit e5b753b7e659b29f5ed4aa57018f922111b238f5
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 11:53:55 2008 -0400
-
- Specify return type of BigDecimal#ceil as BigDecimal, as per library documentation.
-
-commit 0ca3b9ceb6ef5ca1898250b89f75c0194b5da481
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 11:50:24 2008 -0400
-
- Fix BigDecimal#inspect output, update spectags.
-
-commit ca99aa062afe9106ec614e2d8969d3491803c9a2
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 11:48:00 2008 -0400
-
- Specify return type of BigDecimal#ceil as BigDecimal, as per library documentation.
-
-commit 587a5cdbbfa4cccdbfe98339ca999f1d63bd66cf
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Apr 26 15:02:33 2008 +0200
-
- Corrected one Array#hash test case.
-
- Now Array#hash pass MRI 1.8.6, 1.8.7, 1.9 and JRuby.
-
-commit f86bdb98b8b9f5ea878c5d142f3a694e5278db77
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Apr 26 14:19:14 2008 +0200
-
- Quarantined couple of specs that fail on *ALL* implmenetations.
-
- Probably, we need a better way to do that, but quarantine
- is a quick and simple way, easily detectable later on.
-
-commit 7ca928211180c66b9879afbc382c376a7649e1b0
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 00:51:39 2008 -0400
-
- Implement BigDecimal#to_f, update tags. Will this need more work?
-
-commit 69dec41f6b5b532c5de7f46e97f97c9e102305c7
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 00:44:40 2008 -0400
-
- Implement BigDecimal#truncate.
- * Update spec tags.
- * Reorganize variables slightly to remove duplication.
-
-commit c823e62c3a6776b62f65c34b16bdca5748d1add9
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 00:36:43 2008 -0400
-
- Implement BigDecimal#truncate.
- * Update spec tags.
- * Reorganize variables slightly to remove duplication.
-
-commit 3f4e5dc78de5bf3e81ae1ce7a0d14852a32aeade
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Sat Apr 26 00:16:38 2008 -0400
-
- Rewrite spec description to bring it in line with what the spec actually does. :)
-
-commit 15d87e8a983d08d99fc3ec6bfbb7f36ed0cd4c4e
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 25 18:09:33 2008 -0400
-
- Implement BigDecimal#to_i, update spec tags.
-
-commit 59873b144ea836e2f9bbef7d5186a1287155e76a
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Apr 25 20:46:17 2008 -0400
-
- Specs for autoload path normalization
-
-commit 71fe2d45d147fe2c41937ae5ef6dbb8814f491c4
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Apr 25 17:05:17 2008 -0400
-
- Use a separate class in Singleton 'new' specs to avoid contamination
-
-commit 2dc8f9eb9c6db014bd6cc132d987fdb4612816f8
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Apr 25 16:45:28 2008 -0400
-
- Handle more nightmare Autoload edge cases by hooking into Kernel#require
-
-commit 5c1a375a15adbe20a9bf3d1b95e1f2d30feaa90e
-Author: Michael Fellinger <m.fellinger@gmail.com>
-Date: Sat Apr 26 04:26:52 2008 +0900
-
- Spec for Module#autoload when the load path has already been required
-
- Signed-off-by: Wilson Bilkovich <wilson@supremetyrant.com>
-
-commit ee47a0cc0da787599479fc8dd085b7481b591176
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Fri Apr 25 15:41:19 2008 -0500
-
- Enabled another $_ spec and added a proc dispatch scoping test to $~ and $_
-
-commit eabc4609758dc99727c77493c58f187782ea957f
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Fri Apr 25 15:32:03 2008 -0500
-
- Added some basic specs for $_: implicit assign, explicit assign, scoping
-
-commit 61194dec429a9f288791156639f058e45a4e72e9
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Fri Apr 25 14:49:53 2008 -0500
-
- Add some specs for $~ scoping and assignment.
-
-commit 4c5cec4f6e10864c68b140e71cc2559e7a7d636b
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 24 18:28:08 2008 -0700
-
- Added incomplete tags for CSV spec stubs.
-
-commit 6e231caef62e678413e86317881aaab200d0802e
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 24 18:15:06 2008 -0700
-
- Reprocessed library CSV specs with new mkspec.
-
-commit 4cdc61a76cce73b52f05f53f820838cc7e3c2823
-Author: Michael Fellinger <m.fellinger@gmail.com>
-Date: Fri Apr 25 08:46:32 2008 +0900
-
- Updating specs for the module #included calling #extend issue.
-
- Signed-off-by: Brian Ford <bford@engineyard.com>
-
-commit 40e775bf036aa59e69268708f8c78b8a56e0f9ce
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 24 17:10:55 2008 -0700
-
- Moved #bignum_value helper to MSpec.
-
-commit 9b52edbb14ff2fc18faa429daf4ceaff5b87db11
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Thu Apr 24 14:37:53 2008 -0400
-
- Implement BigDecimal#fix, make #frac trap for a few common cases without running out of memory for big numbers.
-
- * Update spec tags.
-
-commit 6a604c0a9863073cfd7540ff755e7ca035a7dff5
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Thu Apr 24 19:32:14 2008 +0200
-
- Don't run Process.setpriority spec on FreeBSD
-
-commit 0ab639af500d947c5b5feb1d8f00f5fbc97a0edc
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 13:37:23 2008 +0200
-
- Adjusted IO specs to supply blocks for each-like methods.
-
- See [ruby-core:16557] for more details.
-
-commit a7b603a9ce6bfb570785e803bdb89ae36bb6253d
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 13:14:40 2008 +0200
-
- Fixed IO, Process, Regexp specs ('should' was missing).
-
-commit 26de6c05c050d0dbcb073c407abda47f964bfd29
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 12:50:46 2008 +0200
-
- Fixed File specs ('should' is misspelled)
-
-commit 99a2b23d8fb42cb377cb3fb9ab2569c555aec8bf
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 12:47:57 2008 +0200
-
- Fixed Array specs ('should' was missing).
-
-commit 67b301a03fd6f7f0fa38ce106ab05825f2cbb15c
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 12:43:39 2008 +0200
-
- Fixed specs ('should' was missing), some new test cases for BigDecimal.
-
-commit aecbea57de7ee1b50bd4b06871dd08e762a6ccb8
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 12:35:54 2008 +0200
-
- More test cases for BigDecimal#nan?
-
-commit 7aaf8fa137b8961ca122eb92e7447936ad7a44cc
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 12:26:20 2008 +0200
-
- More test cases for BigDecimal#zero?
-
-commit 58ecee694f191aa05e7867544cf8d63129558447
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 12:19:11 2008 +0200
-
- A bit more test cases for BigDecimas#-.
-
-commit e946dd03d590e29a1d344e7579d5ff047df4a76b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 24 12:17:16 2008 +0200
-
- New and updated specs for BigDecimal#-.
-
-commit 01d82db424b4e447b98e5f2eb3e162b991dece8a
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 24 01:25:20 2008 -0700
-
- Tag for new private setter method spec.
-
-commit c0ee2e133a4e5fc179b96329ffd3934dd9263c2b
-Merge: 374ab81... e9826b9...
-Author: Tony Arcieri <tony@medioh.com>
-Date: Thu Apr 24 02:19:00 2008 -0600
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 374ab81e2c01ea5ac48cda2004ae92a989d7f3d7
-Author: Tony Arcieri <tony@medioh.com>
-Date: Thu Apr 24 02:18:26 2008 -0600
-
- Specs for calling a private setter method on self
-
- * Not presently working under rbx, works under MRI
- * I don't entirely know the process for this, but this is expected to break
-
-commit 39505393f330b5f622788f1d98ea8ff3781499c7
-Author: Luis Lavena <luislavena@gmail.com>
-Date: Thu Apr 24 04:04:32 2008 -0300
-
- Fixes Dir fixtures and specs for Windows.
-
- Usage of special characters *, ?, | and : is not allowed under Windows
- * and ? represent wildcards, | is pipe tunelling and : is drive letter
- separator.
-
- Files or Directories cannot contain slashes (\/), wildcards, double-
- quotes, pipe tunelling or stream redirectors (<>).
-
-commit 2ecc076e488ed1a519fc5b6876c68a3d91d55c87
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Apr 23 22:55:44 2008 -0700
-
- Update tags for newly passing File.join specs.
-
-commit ff3756e179920b84d5a55fc7bbc2688706df044f
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Apr 24 01:09:17 2008 -0400
-
- Add specs for nested method definitions and other complex scenarios
-
-commit 24785f7c28cde09ce0400e5d80f832ae11cddefa
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Apr 23 20:56:55 2008 -0400
-
- Spec for using ||= to initialize a class variable
-
-commit 98b0c44057cb827107cae0f0174b5e81ac2064fd
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Apr 23 19:49:21 2008 -0400
-
- Rewrite descriptions of language/def specs
-
-commit 598c287cc36179644a1bbf2a303a56fc85bb1b12
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Apr 23 12:39:04 2008 -0700
-
- Replaced use of :mswin with :windows in platform_is[_not] guards.
-
-commit 01fe417f27ad43495327a522ece2f02769064df7
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 23 21:30:34 2008 +0200
-
- Added excludes for BigDecimal#div specs.
-
-commit 46f022d49c394b027491295e7fd5cb305af33404
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 23 21:27:42 2008 +0200
-
- More specs for BigDecimal#div
-
-commit 72433091c6a845c5f550b27111748e29fb5eac09
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Apr 23 10:56:57 2008 -0700
-
- Added #tmp helper to MSpec for returning a temp file name.
-
-commit f4e975e5255fb36bb8e9be7d310850135ce3515f
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Wed Apr 23 10:54:42 2008 -0400
-
- Implement BigDecimal#frac, update spec tags.
-
-commit b60deba2368a1212d6acd3e49481ba9495de7f2f
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Wed Apr 23 10:49:39 2008 -0400
-
- Correct a spec error.
-
-commit e19cf9401c029f90e117b1c17083c928b0d1c9ca
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Wed Apr 23 10:24:50 2008 -0400
-
- Implement BigDecimal#-@, update spec tags.
-
-commit c3fc05389c75aca3150038814b324266501fdb8f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 23 16:12:24 2008 +0200
-
- A bit more test cases for BigDecimal#sqrt.
-
-commit b2a220f86887bfe6030a34bc8cd1b748c88cc2b8
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Wed Apr 23 01:43:16 2008 -0400
-
- Get BigDecimal#to_s working according to spec.
-
- * Implement #to_s.
- * Update spec tags.
-
-commit 82638601be12e410413047779f01840d6d0db3d8
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Apr 23 09:56:48 2008 +1000
-
- Refactor Debugger to remove dependencies on Debugger::Interface
-
- Also:
- - Add List#inspect to show number of items in list
- - Fix decode output to show original instructions in place of
- yield_debugger
- - Improve regex used to match method names to handle more
- operators
-
-commit 41c64f2825d347fbe2ef9edc33dd8f1e84773251
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Apr 22 18:12:06 2008 -0400
-
- Spec and implementation for NilClass#dup
-
-commit d3e313ed38a847e29225ba814a956d0929ea6460
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Apr 22 22:03:47 2008 +0200
-
- New and updated specs for Bigdecimal's #abs and #sqrt.
-
-commit 2013e106181879b886f2e1cb78e81f52cd284666
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Apr 22 15:52:10 2008 -0400
-
- Re-implement Module#autoload and autoload?. Now passing all autoload specs.
-
-commit 9156271e2b12138e2b2b712a76f0110f20a757b7
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Apr 22 15:34:43 2008 -0400
-
- Add (failing) spec for toplevel autoloaded constant access
-
-commit 8eb5451f88a37dc247e42913c1d72d072a9b02ef
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Apr 22 19:06:00 2008 +0200
-
- One more test case, for BigDecimal#sqrt with nil.
-
-commit e7894fb78cf92b53e9bdc6dcf023d8dd2d66b2ed
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Apr 22 18:52:24 2008 +0200
-
- More detailed specs for BigDecimal#sqrt and fixes for old ones.
-
-commit 527a4b663c487cd9222ee2e6917e330ff9a130a1
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Apr 22 12:38:53 2008 -0400
-
- Rename ambiguously-worded autoload spec
-
-commit 3e6f16c41569dbba291bc3cececf137fc8952ee2
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Tue Apr 22 12:31:17 2008 -0400
-
- Change to a significand-and-exponent implementation.
-
- * Update spec tags.
-
-commit f1b2bf51042ca563ca74a9cf83db0e46a1bfabce
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Tue Apr 22 09:54:53 2008 -0400
-
- Fix BigDecimal#zero, update spec tags. Also make #precs deal correctly with lowercase exponents.
-
-commit d0171de114e777f07a3e62972663475dd7747b05
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Tue Apr 22 09:24:06 2008 -0400
-
- Implement BigDecimal#precs.
-
- * Get #precs working. This will be less tortured once I implement a significand-and-exponent format.
- * Update spec tags.
-
-commit e1fc7c6dc4c02c1763947c34d05f894661a84525
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Tue Apr 22 01:30:10 2008 -0400
-
- Continue implementing bits of #inspect and updating spec tags.
-
-commit e4371f120c9c5c3c88a26d5f24f0d3ab888c954f
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Tue Apr 22 01:24:14 2008 -0400
-
- Implement BigDecimal#==/eql? and the beginnings of #inspect.
-
- * Find a way of implementing the equality test that satisfies the specs.
- * Don't be so baroque in parsing strings in constructor.
- * Update spec tags.
- * Fix regression in abs_spec.
- * Start implementing #inspect. Not really ready for prime time yet.
-
-commit 0494c1c35582381345194c76f7384eb9044797fc
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Tue Apr 22 00:41:03 2008 -0400
-
- Start implementing BigDecimal#sign and #zero?.
-
- * Clean up specs for #sign.
- * Write some initial code to get these working. Not all there yet.
-
-commit 3c071b5f921898d87437803a500535b639d465ef
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 21 23:43:10 2008 -0400
-
- Get BigDecimal#abs working.
-
- * Implement the function.
- * Improve the spec.
-
-commit 054582f3b89d757f033cd5f09cbf90fa08ad81d6
-Author: MenTaLguY <mental@rydia.net>
-Date: Mon Apr 21 22:32:42 2008 -0400
-
- fix linked actors spec (sort of)
-
-commit d7a7d0c4d0d83d7e69216c96a249c4091fe75323
-Author: MenTaLguY <mental@rydia.net>
-Date: Mon Apr 21 22:28:29 2008 -0400
-
- fix up registration spec
-
-commit 645784c3d39f776f583874e7c9244ff3de64cfe7
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 21 19:56:51 2008 -0400
-
- Update tags on failing specs.
-
-commit 960faf5382d90db376ff14bb836463f1860a4b62
-Merge: 2e2150f... 046ba62...
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 21 18:46:45 2008 -0400
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 046ba622836321f487f241c145a3bdf0968f0a67
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Apr 21 18:44:50 2008 -0400
-
- Specs for failing Module#autoload case (replicates a scenario from Merb)
-
-commit 18a2a26fa511d4943a724e27ce09e5855a257e90
-Merge: 1f5f4b5... 991c6e6...
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Mon Apr 21 14:15:07 2008 -0400
-
- Merge branch 'master' of git://git.rubini.us/code
-
- Conflicts:
-
- lib/bigdecimal.rb
- spec/ruby/1.8/library/matrix/diagonal_spec.rb
- spec/ruby/1.8/library/matrix/element_reference_spec.rb
- spec/ruby/1.8/library/matrix/shared/identity.rb
- spec/ruby/1.8/library/matrix/shared/transpose.rb
-
-commit edd397c82a924e406eabbcd7e84243d94f8e8067
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Sun Apr 20 18:11:23 2008 -0500
-
- Adds MinGW to the IO#popen spec guard
-
-commit 10df9f89189637b2c5a54b01a88eca6c9fbb4601
-Author: Adam Wiggins <adam@heroku.com>
-Date: Sun Apr 20 14:53:41 2008 -0700
-
- IO.popen specs for reading and writing to pipes
-
-commit 3f70eceb3b9415a14f602c5b96121a459dca1e67
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Apr 19 22:32:28 2008 -0700
-
- Fix silly typo in Numeric#quo specs.
-
-commit 6101a4992ddc15c0140f4d7702cf88d2d3a2ac53
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Apr 19 22:23:14 2008 -0700
-
- Guard affected specs with conflicts_with :Rational.
-
-commit 354445f4d20ec66f207d65d1ccceb681bba7fff0
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Sat Apr 19 14:23:14 2008 -0500
-
- Clarifying some of the Matrix specs
-
- * Fixes two errors introduced by 28700c5cf7
-
-commit 2f5ca541fc08f0c033bc6541c72962228ea607de
-Author: Eero Saynatkari <projects@kittensoft.org>
-Date: Sat Apr 19 15:07:49 2008 -0400
-
- Compiler specs' TestGenerator relies on broken #=== semantics, comply.
-
-commit 37cc9d4d6eb3442814ecc51845f025f464da64f7
-Author: Eero Saynatkari <projects@kittensoft.org>
-Date: Sat Apr 19 15:05:30 2008 -0400
-
- Specs for default #=== and its relationship with #== and #equal?
-
- * Rubinius deviates to not check object id directly.
-
-commit 28700c5cf7630be59877122e6470c42622b7365a
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Sat Apr 19 13:53:33 2008 -0500
-
- Additional specs for Matrix
-
- * Some of the constructors in Matrix keep referencing the original arguments after creation, these specs cover those cases.
-
-commit 12b0bc93e5a6b328ad0968c03c47af71f671aae2
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Sat Apr 19 13:06:04 2008 -0500
-
- Replace object_id for equal? in Matrix specs
-
-commit ae377f0e56b8f31356935b3ac0800f561b2d1b2c
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Apr 19 14:49:34 2008 +0200
-
- Fix File::Stat#uid specs
-
-commit 2e01a86a3977fe87f4f0734e50598b41f66f29d7
-Author: MenTaLguY <mental@rydia.net>
-Date: Sat Apr 19 03:24:32 2008 -0400
-
- Gutted and reworked Actor, following Erlang more closely.
-
-commit de40303e17e2de1e7980564b43ee162c5080afa6
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Sat Apr 19 01:05:43 2008 -0500
-
- Fixes Matrix#clone specs for MRI
-
- * Makes sure the values (not the references) of the original rows are copied.
-
-commit 2b3a44158ae93ab5883da22e5f36df92485f3ad4
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Fri Apr 18 22:47:15 2008 -0500
-
- Fixes a few things inside the Matrix specs.
-
- * Removes some of the "needs to be reviewed for completeness" messages.
- * Changes some of the descriptions
-
-commit 3be265a93a75b6a0267b1770f8cad671c4244671
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:26:29 2008 -0400
-
- Matrix.unit, one more alias for .identity.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit 57aa8ba9a1dbdf62e9cf644bbde4603b841ffc76
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:25:55 2008 -0400
-
- Name spec correctly.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit 3390dc4c6725d996eeb0c2e4ec73949bc0be2290
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:23:54 2008 -0400
-
- Specs for Matrix.scalar and .identity/I.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit 958ca1faa1dc60ce591b4b2f768f22ac7f6cb56f
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:22:09 2008 -0400
-
- Move the "needs to be reviewed" indicator to the right place.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit bf3eab630654eaaca9256850d258343e3024989e
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:03:45 2008 -0400
-
- Use size functions instead of constants.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit 3981c931e7f4fde730d51614d40e44b9209347f9
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 11:58:22 2008 -0400
-
- Specs for Matrix#clone and #transpose (alias #t).
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit 72e1ea8900a638c796de9e715c5dffcf4ac90546
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:27:06 2008 -0400
-
- Basic specs for Matrix.zero.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit f5d294ad941c477060e9b5d2329790db7e1e5700
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:20:27 2008 -0400
-
- Move before block to a clearer place.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit b6bc5b224ade56ab96f3585b6b1c25e6dd5e1ad5
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:19:27 2008 -0400
-
- Write specs for Matrix.diagonal.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit b4d056baa33a2181ab64c065ad1eb4adebcfaddf
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:11:11 2008 -0400
-
- Some initial specs for Matrix#[] and Matrix.[].
-
- These are in the same file because of coding conventions, but they probably should not be since .[] is a constructor and has very little in common conceptually with #[], which is a subscript operator.
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit 5476d836577c0fbdbda097762862cf153ffb5e07
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Apr 18 18:35:34 2008 -0700
-
- Some method profiles of data provided by John Lam.
-
- Run these as follows:
-
- bin/mspec -w rails.yaml spec/ruby
-
- We'll be adding our own trace script, but for now, these
- are snapshots of methods used by Rails loading a simple
- "hello world" controller. The rails.yaml file is core
- methods. The core.yaml file is generated by NameMap from
- mspec/bin/name_map.rb.
-
-commit 24c71675cc63c86832ef8bc55d2f0167dff53073
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 17:24:08 2008 -0400
-
- First stab at BigDecimal.
-
- * A skeleton of a somewhat naïve implementation of BigDecimal.
- * Updated spec tags.
-
-commit 1f5f4b59400b8b11df83b274efc8ce98186220ef
-Merge: 9d21b0e... 968a0ec...
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 17:28:02 2008 -0400
-
- Merge branch 'bigdecimal'
-
-commit 9d21b0e890a9394658689af2bdee7e449cd2200b
-Merge: c3f3507... 1a08506...
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 17:25:09 2008 -0400
-
- Merge branch 'master' of git://git.rubini.us/code
-
-commit 968a0ecda8477b33ceab2e7d0c7e7d084a105bdb
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 17:24:08 2008 -0400
-
- First stab at BigDecimal.
-
- * A skeleton of a somewhat naïve implementation of BigDecimal.
- * Updated spec tags.
-
-commit 1f410d918a59b9b49e87a407cc8fba4bbf342a79
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Apr 18 22:34:53 2008 +0200
-
- Fix a bunch of specs and minor issues in File::Stat
-
- Specs for File::Stat#<=>, File::Stat#ino, File::Stat#inspect,
- File::Stat#mode, File#Stat.initialize and some minor bugfixes
- such as the fact that File::Stat needs to include Comparable
- (like MRI).
-
-commit d6f2c6995941762878f4b777a39b0c23ea654605
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Apr 17 22:30:36 2008 +0200
-
- Remove specs for non-existent File::Stat#initialize_copy
-
-commit c3f350716a35cb869b3ea0289c0e404d07b8819f
-Merge: 810afff... b861102...
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 16:18:34 2008 -0400
-
- Merge branch 'master' of git://git.rubini.us/code
-
-commit 72101783ec6e66a4f9ac3f9c90f7e8f5b67058ec
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Apr 8 17:05:26 2008 -0700
-
- Reworked masgn specs to evaluate L2R and assign L2R. excluded.
-
-commit 4e4bec628b21938617bdfa5a2ef17aedf02c112c
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Apr 8 15:17:00 2008 -0700
-
- trailing whitespace is killing me... evan\! fix your editor\!
-
-commit 810afffa2e549048947c07b30d77be255db42d73
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:26:29 2008 -0400
-
- Matrix.unit, one more alias for .identity.
-
-commit 2c84f77535d677a42bee93759c77f79c2cdd4d93
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:25:55 2008 -0400
-
- Name spec correctly.
-
-commit 762f5ee0f7ba4234847c695c92e3ed27dd05e134
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:23:54 2008 -0400
-
- Specs for Matrix.scalar and .identity/I.
-
-commit b68295e0046a2eb1fb911ea891d6e0a29174ea30
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:22:09 2008 -0400
-
- Move the "needs to be reviewed" indicator to the right place.
-
-commit 4b6e1097feafe2247e59d6004a36bb0987734138
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 12:03:45 2008 -0400
-
- Use size functions instead of constants.
-
-commit 2086f0c1f1f899f2e41307a5434a5bb6446e20a2
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 11:58:22 2008 -0400
-
- Specs for Matrix#clone and #transpose (alias #t).
-
-commit 2939c55b2e9f38b5115b98429de97bc4fff6f165
-Merge: a47f2b8... 42d3212...
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 02:09:07 2008 -0400
-
- Merge branch 'master' of git://github.com/evanphx/rubinius
-
-commit a47f2b852ca309a68b687157a6cd973716328887
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:27:06 2008 -0400
-
- Basic specs for Matrix.zero.
-
-commit aa3b2eeef70cb8967ef6c92ee24a226c2d1202c1
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:20:27 2008 -0400
-
- Move before block to a clearer place.
-
-commit ca6ac1e59ddb268b388975a2fb5b11e6026e65c8
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:19:27 2008 -0400
-
- Write specs for Matrix.diagonal.
-
-commit b24216d8b0ecfba6888f909415e2523eaed2aeb2
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Fri Apr 18 01:11:11 2008 -0400
-
- Some initial specs for Matrix#[] and Matrix.[].
-
- These are in the same file because of coding conventions, but they probably should not be since .[] is a constructor and has very little in common conceptually with #[], which is a subscript operator.
-
-commit 9313f29ed952f604e0d124ced38ee930b5780b27
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Thu Apr 17 22:35:43 2008 -0400
-
- New spec tags for Complex#%.
-
-commit 08f316de96c94b7d4865d77873327deddeabb664
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Thu Apr 17 22:32:08 2008 -0400
-
- More specs for Complex.
-
- * Specs for <=>, conj/conjugate, to_s.
-
-commit 973c304cc16fa6b78dba31de11b151da2daae762
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Thu Apr 17 22:09:20 2008 -0400
-
- More specs for Complex
- * Complex#abs, abs2, angle, arg, and %. Not sure that % is correctly specified.
-
-commit e32b26694277065fe28f138dca837b8c0509c735
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Thu Apr 17 21:17:26 2008 -0400
-
- More specs for Complex.
-
- * Write specs for * and /.
- * Rewrite + and - to use alternate constructor syntax.
-
- Signed-off-by: Marnen Laibow-Koser <marnen@marnen.org>
-
-commit 0cbf88a6c61e477f4b9a7758a9fab1258efbf30f
-Author: Marnen Laibow-Koser <marnen@marnen.org>
-Date: Thu Apr 17 20:46:04 2008 -0400
-
- Write some specs for Complex.
-
- * Basic specs for Complex.new, Complex.new!, Complex#+, and Complex#-.
-
- Signed-off-by: Marnen Laibow-Koser <marnen@marnen.org>
-
-commit 71909e78b8d77f7e48d306e30f51fbc21b5fbefb
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 17 15:26:53 2008 -0700
-
- Reorganize and fix Matrix specs.
-
-commit 5a9325457696dfba3c410c0adcbdec706ecda3bf
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 17 12:49:45 2008 -0700
-
- Added spec templates and incomplete tags for CGI.
-
-commit d62de6b4096a9b3bd3fda197b70d6e603596e865
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 17 21:12:08 2008 +0200
-
- More detailed speecs for BigDecimal#new
-
-commit ebd6fb8f879f94ff51b74cb4e76080fad7b66cb5
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 17 19:55:31 2008 +0200
-
- More detailed specs for BigDecimal's <, <=, >, >=, <=>.
-
-commit 8caef40cbe873dc2825bc0ba1e66f983b8219cca
-Author: MenTaLguY <mental@rydia.net>
-Date: Thu Apr 17 01:16:25 2008 -0400
-
- add tag object argument to send_in_*
-
-commit 0596b1aca45a85de5f3d727632585da924fd3eb0
-Author: Matthias Reitinger <m.reitinger@mytum.de>
-Date: Sat Apr 12 10:11:13 2008 +0200
-
- New specs for BigDecimal.new.
-
- Signed-off-by: Marius Nuennerich <marius@nuenneri.ch>
-
-commit 5c176e50fe962de1095a75221b4d63e75acc505f
-Author: Benjamin Stiglitz <ben@tanjero.com>
-Date: Wed Apr 16 11:32:18 2008 -0700
-
- Cleaned up Numeric#div spec
-
- The spec names are no longer quite as atrocious; the spec output is now fairly
- readable. The different Integer-Float quotient permutations are now correctly
- specified as well.
-
- Signed-off-by: Brian Ford <bford@engineyard.com>
-
-commit e1406b19c51bfca5f6936d143087043316c68c13
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 15 20:07:48 2008 -0400
-
- Specs for Kernel#p behaviour.
-
- * Args vs. no args.
- * Record separator is not taken into account.
-
-commit 30c717e1736b65a852df501f71e320599fc17786
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Apr 15 21:32:13 2008 +0200
-
- Fix typo in File.grpowned? spec
-
-commit 1bc17a0b4c8f19b84ffdd0b17ec24243a1df6092
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Apr 15 21:31:02 2008 +0200
-
- Fix File.grpowned? and it's spec
-
-commit f49cf4d0319b5772ede7bcddd763c691d5253b18
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Apr 15 20:44:18 2008 +0200
-
- Update tags for implemented File.grpowned? specs
-
-commit ea19fb07cb7b789165aec5da0f571345b96f1f0f
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Apr 15 20:41:02 2008 +0200
-
- Spec File::Stat#grpowned? and implement File.grpowned?
-
-commit c411b15b9f94fec21b02a9208cbae4b42452431d
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Apr 15 20:19:24 2008 +0200
-
- Properly rename File::Stat#dev_major and File::Stat#dev_minor specs
-
-commit 26ba3ad30cd726b058cd76f23dc7a79555be724e
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Tue Apr 15 10:25:44 2008 -0700
-
- Quarantine the cvar-related instance_eval spec for now; it's not clean.
-
-commit d72c609ce4567d7a7fdfd2ee4713ac07033c81db
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Mon Apr 14 20:13:38 2008 +0200
-
- Use EnvSpecs where possible
-
-commit 8ccdf2d612f15515837095e2e4a570861024294c
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Mon Apr 14 17:42:36 2008 +0200
-
- Use EnvSpecs module for platform dependent stuff
-
-commit 130e4bdb1d9fa9512dfe45d4ff4d718096683cdb
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Mon Apr 14 19:45:24 2008 +0200
-
- Fix specs for a bunch of File::Stat methods and implement File::Stat#<=>
-
- Created specs for atime, blksize, blocks, ctime, mtime and <=>
-
-commit e5aa89ff13128afb9b43ad77678792aeae4d48ea
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Apr 12 17:54:57 2008 +0200
-
- Remove tag for fixed File#lstat
-
-commit 21cd4a10833ef3bdda1593423faccb334de16536
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Apr 12 17:52:33 2008 +0200
-
- Remove unneccary spec placeholders for File#stat / File#lstat
-
- The shared spec already tests this behavior. With the new added spec
- for the difference between the two, File.stat / File.lstat is pretty
- well covered for now.
-
-commit eacb4f8a4d0ba606458a5756ddd6f2ce723a3dfa
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Apr 12 17:45:55 2008 +0200
-
- Specced different behavior between File.stat and File.lstat
-
-commit 4ae163810074effc068babf538f004e9ff117156
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Mon Apr 14 16:49:04 2008 +1000
-
- Refactor Debugger interface into a CmdLineInterface class
-
-commit e61241498f6ca63b7d5e50e94a70456bc40e929b
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Mon Apr 14 14:17:03 2008 +1000
-
- Breakpoint clean-up
-
-commit ae738f21979edf727437438b992629dd0b59a42e
-Author: MenTaLguY <mental@rydia.net>
-Date: Sun Apr 13 16:14:34 2008 -0400
-
- elminate Mailbox#clear; difficult to implement with sane semanitics
-
-commit 76385484049e47f53b840ddf3c0dfe9e365ca8cf
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Sat Apr 12 16:39:19 2008 -0500
-
- More specs for REXML::Element
-
-commit 00547bc562c359ddac13d04a5c955ee25171bcb4
-Author: Matthias Reitinger <m.reitinger@mytum.de>
-Date: Sat Apr 12 11:15:12 2008 +0200
-
- Fixed incorrect check for object equality in BigDecimal#nonzero? spec
-
- One should not use == to check if the method returns self, but equal?
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit e8403792167c86f120ce7bdcd1e2c7ce1bc31fea
-Author: Matthias Reitinger <m.reitinger@mytum.de>
-Date: Sat Apr 12 11:31:25 2008 +0200
-
- Eliminated use of to_s to check for NaN in BigDecimal specs
-
- Changed "to_s.should == 'NaN'" to "nan?.should == true"
-
- Signed-off-by: Federico Builes <federico.builes@gmail.com>
-
-commit 5883dd78ad92031c920bb9ee2b703702969a5854
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Sat Apr 12 09:42:11 2008 -0500
-
- A few more instance_eval specs, for non-immediate numerics and cvars.
-
-commit e8fd8e696d5487fa698a9a8b1bab2fb54b420133
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Sat Apr 12 08:28:41 2008 -0500
-
- Added instance_eval spec for defining methods under immediates.
-
-commit c23b365a95862cd438e6228929a3a4e935d60de9
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 22:09:06 2008 +0200
-
- New rubypsecs for BigDecimal#fix and #frac.
-
-commit 6b6b63ebedb61466b4f04f510bf859574efec7d9
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 20:07:07 2008 +0200
-
- New rubyspecs for Bigdecimal#floor and #ceil.
-
-commit 75e9118aea32baaeec82efedb5106c63bb0eef44
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 17:50:36 2008 +0200
-
- Corrected Bigdecimal specs since they were missing "should" statements. :)
-
- Also, added some more cases.
-
-commit 18fafb2e1f653887fdd3cdef693448d9b2bea29e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 17:21:02 2008 +0200
-
- New rubyspecs for BigDecimal's #power, #** and #exponent.
-
-commit 35e32daa38c7df385aac99f7b709a4038141faaa
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 13:41:13 2008 +0200
-
- New and updated rubyspecs for BigDecimal#precs.
-
-commit e0172d4eee7a775ab53562477997855ed66615a7
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 12:31:22 2008 +0200
-
- More rubyspecs for BigDecimal#split and some corrections for older ones.
-
-commit 37d312770700da5eb124fdce7a7b1687c2d9b839
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Apr 11 13:55:00 2008 +1000
-
- Get breakpoint handling working properly
-
-commit 498b95a720e98b70b56af9dfd2c1ba20c0bf89c3
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Apr 9 17:23:56 2008 +1000
-
- Make ISeq#decode return symbols rather than objects by default
-
-commit b8bda0546cdb9ac04ae629f13ccfce5f474e6f2c
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Mon Mar 17 14:33:45 2008 +1100
-
- Ensure breakpoint original instruction is correct
-
- When multiple breakpoints are set at the same location,
- only the first breakpoint sees the original instruction.
- This commit ensures the BreakpointTracker detects such
- situations, and updates the breakpoint to set the correct
- oringinal instruction to use.
-
-commit 2700924f23e0283a059583f9e92188b1c3c4f220
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu Mar 13 17:20:49 2008 +1100
-
- Reorganize Breakpoint class hierarchy
-
- Refactor Breakpoint class hierarchy in preparation for
- adding PersistentBreakpoint and BreakpointRestorer classes.
-
-commit bfa69d930c38897df18b656d7b86f0b549bed57f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 03:01:37 2008 +0200
-
- Some more test cases for BigDecimas#finite? and #nonzero?.
-
-commit 71a4b0a51ea4da0c41d7b096aa7b88deb8d0d049
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 02:42:33 2008 +0200
-
- A bit more rubyspecs for BigDecimal#sub and #to_s.
-
-commit 8ff9ae455c6c7f4b38f3b4dcbdc6c677759f13e2
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Apr 11 01:35:16 2008 +0200
-
- New rubyspecs for BigDecimal#truncate.
-
-commit f0a5c13f218d1e2187dfff09bd27cbd6dde544ca
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 10 15:09:55 2008 -0700
-
- Converted VMActor specs to dir/files. Added incomplete tags.
-
-commit df74b0fd98597b51d4c1d51ae09706d51e1a5d3c
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 10 15:01:08 2008 -0700
-
- Converted Mailbox specs to dir/files. Added incomplete tags.
-
-commit 29d223d8bfcc36edc16db58d50f8186905df773a
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 10 14:49:52 2008 -0700
-
- Converted Actor specs to dir/files. Added incomplete tags.
-
-commit 08ab8db440cfdaa7e06b19a0d88750678d4fccbf
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 10 22:09:39 2008 +0200
-
- New rubyspecs for bigdecimal, and excludes.
-
-commit b76a9e964899348d667181d288c5d4ec0e422c9f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 10 19:33:03 2008 +0200
-
- One rubyspec for the class definition: def nil:Foo; end
-
-commit c526f5744ece40e312340556991ee54e4504ebcd
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 10 00:53:06 2008 -0700
-
- Processed Rational, Complex, Matrix with mkspec.
-
-commit 3de6f530c42bdca8c9b1202e60d0d14850024d15
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 10 00:27:40 2008 -0700
-
- Processed IO with mkspec. Added incomplete tags.
-
-commit faaf8bdb8893f71234d7e2fab07aa11d6c556384
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 10 00:17:35 2008 -0700
-
- Clean up especially bad whitespace in File specs.
-
-commit fedda8f6865c6cdb07c7599606204f0700042574
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 10 00:09:56 2008 -0700
-
- Processed File specs with mkspec. Added incomplete tags.
-
-commit 09f6f1b5138b7ca1d276a8c68ee6bf1cba7691b7
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Apr 9 23:42:40 2008 -0700
-
- Processed Kernel specs with mkspec. Added incomplete tags.
-
-commit e3ca2e3e077c0e026b96e1e68808b95d44233cf5
-Merge: cf0c855... 4d0d1f6...
-Author: Thomas Lachmann <thomas_lachmann@gmx.de>
-Date: Thu Apr 10 02:48:31 2008 +0200
-
- Merge branch 'master' into bigdecimal_specs
-
-commit cf0c8552f31cfd856822c8aa43a5d9d265481ac0
-Author: Thomas Lachmann <thomas_lachmann@gmx.de>
-Date: Thu Apr 10 02:40:22 2008 +0200
-
- Next bunch of specs for Bigdecimal.
-
-commit 4d0d1f6b98ac2dafa487ece31512443a07bbc928
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Wed Apr 9 23:42:10 2008 +0200
-
- Fix ENV specs
-
- * Try to avoid `env`
-
-commit dfcc69ea8bd78e9e463defdef3b4529a5af40bb5
-Merge: 75e6ccd... 6a50f0d...
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Wed Apr 9 22:26:26 2008 +0200
-
- Merge branch 'master' of git://git.rubini.us/code
-
-commit 75e6ccd48bce9e0e939a0ff1d484f14a029969f9
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Wed Apr 9 22:26:11 2008 +0200
-
- Fixes for ENV
-
- * Add specs
- * Add some missing methods to ENV
-
-commit 6a50f0d2f5146901fe96fe86802df155c9266a21
-Author: Thomas Lachmann <thomas_lachmann@gmx.de>
-Date: Wed Apr 9 21:11:05 2008 +0200
-
- Fixed failures for BigDecimal#specs.
-
-commit 09bc62e39a8b92c25aeb6287f9fbf4e9cd2b9a6f
-Author: Thomas Lachmann <thomas_lachmann@gmx.de>
-Date: Wed Apr 9 19:55:45 2008 +0200
-
- Bunch of specs for BigDecimal.
-
-commit c281add79d621f6327740109895c624dd25a2e1b
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Wed Apr 9 09:13:29 2008 -0500
-
- Cleaning up UPSocket#send specs
-
- * Got rid of the weird exception catching
- * DRY things up a bit with before :each
-
-commit 8ebefe3c0a61b7aab8ac3d0ae9768c35b657cdb6
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Wed Apr 9 09:11:43 2008 -0500
-
- Adding spec helpers to REXML specs
-
-commit e3064084efbbac1147d477435010d933ce101413
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 8 22:20:43 2008 -0400
-
- Amended spec wording for Singleton._load slightly. Updated exclude.
-
-commit 23e621625b95e0db82bd406a5eb8fa7324e41a6e
-Author: Chris Shea <chris@tie-rack.org>
-Date: Tue Apr 8 15:49:11 2008 -0600
-
- Create spec for Marshal.load of Singleton instance
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit eec07baa07d591059c64f32c0ddef169cfcccaef
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Apr 8 20:20:02 2008 -0500
-
- Thread#wakeup deadlock for MRI marked as ruby_bug
-
-commit dbb744d9692c2432d7aebecac17365125efe9087
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Apr 8 20:02:08 2008 -0500
-
- spec for wakeup which causes MRI to deadlock when it shouldn't
-
-commit 208a7df6ec2d3c8f550a7ac24db849e593cdc9f3
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Apr 8 17:58:15 2008 -0500
-
- specs for Thread::list
-
-commit f6f307e75e49cdf597b0b3755ab214c6fc1950dd
-Author: Thomas Lachmann <thomas_lachmann@gmx.de>
-Date: Wed Apr 9 00:54:34 2008 +0200
-
- specs for BigDecimal.new and BigDecimal#zero? (plus tag files).
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 5b1f2043f70b0088f1c32be79eeaa8179c2210a6
-Author: Jeff Rose <jeff@rosejn.net>
-Date: Wed Apr 9 00:44:27 2008 +0200
-
- Specs for Actor linking and registration, and Mailbox timeouts.
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 4eea149d3d503c121fb7c65115e374838fff8c8a
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Apr 8 14:55:18 2008 -0700
-
- Added extra Array subclass dup spec
-
-commit 783a884931b718b8fa65dd9768fbebd8a0d1ac0c
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Apr 8 14:18:45 2008 -0700
-
- minor cleanup
-
-commit 0e047cc97aa6a5acd7193bdde1139f6a89f108b8
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Apr 8 14:18:27 2008 -0700
-
- minor cleanup
-
-commit f4797827393e0d9d0e5df5aa5184ecebb066d766
-Author: Matthias Reitinger <m.reitinger@mytum.de>
-Date: Tue Apr 8 17:08:32 2008 +0200
-
- Extended Symbol#inspect spec and reworked Symbol#inspect to fulfill them
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit b3c3a5f60177f9c52725b6cacf019412d2c747ea
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 8 17:29:58 2008 -0400
-
- Excludes for BigDecimal specs.
-
-commit b7cd3c38d146a7833ef1d426ea8acd4ee4cb09bf
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 8 17:13:48 2008 -0400
-
- Switched #requires around to have access to #pretty_inspect.
-
-commit aba428095e09ead8ed66895b175e5f3673c4310e
-Author: Thomas Lachmann <thomas_lachmann@gmx.de>
-Date: Tue Apr 8 17:45:13 2008 +0200
-
- Spec for BigDecimal#to_f.
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 20a5789f9dc4e6d30dffb594476b354e4aeee201
-Author: Thomas Lachmann <thomas_lachmann@gmx.de>
-Date: Tue Apr 8 17:21:39 2008 +0200
-
- Spec for BigDecimal#finite?
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 896609e7ae8ee12c72e4e3ce86897c1f8b98f3fb
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Apr 8 02:03:22 2008 -0700
-
- overlooked 2 specs
-
-commit 77774ed4300d5245c58dbcc686cd72dc48f08a1f
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Apr 8 02:00:24 2008 -0700
-
- Added a bunch of specs to String#to_f
-
-commit 1b91113c3e8fb46a0d355cae9000ee4c82f95ac3
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Mon Apr 7 21:46:17 2008 -0500
-
- More specs for REXML
-
-commit 2460839e3fbe2967b9df70db3de33b2a102b9a44
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Apr 7 12:19:40 2008 -0700
-
- Reworked how MSpec handles config files. Use 'set :sym, value' now.
-
-commit 67d3869e9b3fef6d47727206d02814da410e02fc
-Author: Jeff <rosejn@warp.(none)>
-Date: Mon Apr 7 15:04:09 2008 +0200
-
- Adding specs for Mailbox and Actor, and renaming the VMActor describe to match the standard scheme.
-
- Signed-off-by: Charles Comstock <dgtized@gmail.com>
-
-commit 7391c1fbc02966165de03724c42fc1d5243ac99f
-Author: Marius Nuennerich <marius@nuenneri.ch>
-Date: Sun Apr 6 22:29:22 2008 +0200
-
- repair UDPSocket spec
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 5a205207faad0a85271bfcb459390793702c4143
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Apr 5 04:54:21 2008 -0400
-
- Partially revert "Add spec files for cgi.rb."
-
- This partially reverts commit e2714f2fd2d8825ac8af761a5a4545e4d0731735.
-
- Conflicts, left these files:
-
- spec/ruby/1.8/library/cgi/escapeHTML_spec.rb
- spec/ruby/1.8/library/cgi/escape_spec.rb
- spec/ruby/1.8/library/cgi/rfc1123_date_spec.rb
- spec/ruby/1.8/library/cgi/unescapeHTML_spec.rb
- spec/ruby/1.8/library/cgi/unescape_spec.rb
-
-commit 22f3042377731cb6ff963b9e322b24014b286895
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Apr 5 03:18:15 2008 -0400
-
- Added excludes for the CGI specs.
-
-commit 7b9f5a213c971636b663e992fcb8578888d27f52
-Author: makoto kuwata <kwa@kuwata-lab.com>
-Date: Sat Apr 5 13:03:59 2008 +0900
-
- Add spec file for CGI::rfc1123_date().
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 31edbd64bba7f352930ac04d51b63e72553796a9
-Author: makoto kuwata <kwa@kuwata-lab.com>
-Date: Sat Apr 5 13:03:14 2008 +0900
-
- Add spec files for CGI::escapeHTML() and CGI::unescapeHTML().
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit fc321869d73f58dcfbb55ba374646c1568528004
-Author: makoto kuwata <kwa@kuwata-lab.com>
-Date: Sat Apr 5 13:01:33 2008 +0900
-
- Add spec files for CGI::escape() and CGI::unescape().
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit e2714f2fd2d8825ac8af761a5a4545e4d0731735
-Author: makoto kuwata <kwa@kuwata-lab.com>
-Date: Sat Apr 5 12:44:57 2008 +0900
-
- Add spec files for cgi.rb.
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 2a1d0ad7e51ba52a918111d53be6a641c41a0445
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Apr 4 22:21:47 2008 -0400
-
- Improved the *rest argument count spec a bit.
-
-commit e8053e4bb108cf877ac8fdafc104eb34bad671f0
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Apr 4 20:38:23 2008 -0400
-
- Specs for unlimited argument count for *rest defns.
-
-commit 03e092e45015f8115f806e11460121c560e60b4b
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Fri Apr 4 17:54:25 2008 -0700
-
- Converted symbol spec to be generative, allowing easier pattern detection
-
-commit bbda617127a8ac319a58fa190d43b3a0d960d309
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Apr 4 14:07:50 2008 -0500
-
- updated File#inspect tags
-
-commit 38eb679d6b6c5aef8bccb2139e681c926b3290c7
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Apr 4 06:00:37 2008 -0400
-
- Specs for ~/ expansion in #require, #load. It has broken at some point.
-
-commit 2d600c01205fbb7ccd98e7f7a88ebcbd0e1d1d43
-Author: Paul Thornthwaite <tokengeek@gmail.com>
-Date: Fri Apr 4 08:43:42 2008 +0100
-
- Updated specs for Set library
-
- * Added specs for Set#subset and Set#proper_subset
- * Added specs covering empty sets and comparisons
- * Corrected spec string to include ? on superset method names
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 3a547c2b82434c64b72967ebd917fc063ff1317d
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Apr 3 23:16:18 2008 -0700
-
- Fixed GetoptLong specs to not depend on value of ARGV.
-
-commit 5dd9b0ecdddfd990d6387a0a7c70173ea0cededa
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Apr 2 23:27:04 2008 -0700
-
- Add config file for and rework MSpec runners.
-
-commit 773a13ed9005628e48ed146180041caa035f4072
-Author: David Yip <yipdw@member.fsf.org>
-Date: Thu Apr 3 03:18:48 2008 -0400
-
- Added spec: full contents of StringIO stream should be accessible after rewind.
-
- Spec tested against Ruby 1.8.6p111 and Ruby 1.8.6p114 on OS X 10.4.11.
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit ba2ca41cb29ac08c94231a2383940464e6fd1c9d
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Thu Apr 3 08:45:49 2008 -0500
-
- Updated tags for REXML specs
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 09c080bf33092b9d147d1b0a5de920fce8527fdc
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Thu Apr 3 08:45:26 2008 -0500
-
- Fixes whitespace in REXML::Element specs
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 3a997bc18f589b91b4cd518448644171f3054abf
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Thu Apr 3 08:29:23 2008 -0500
-
- More specs for REXML::Element
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit d250939060a4a91a6fee59bd4bfa4e86eb271373
-Author: Paul Thornthwaite <tokengeek@gmail.com>
-Date: Thu Apr 3 14:36:42 2008 +0100
-
- Specs for Set#superset and Set#proper_superset added
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 01399738d5ad0136ef205b8501b12012c7e42230
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Apr 3 18:09:20 2008 -0400
-
- Removed excludes for Object#kind_of?, #is_a?.
-
-commit 0e7d1c6e02e5617bb251366e0d60760edb29377e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Apr 3 20:04:34 2008 +0200
-
- Fixed copy-paste error in Object#is_a? specs.
-
- Adjusted the Object#is_a? exclude.
-
-commit 4a9cb7cc0c734b4280c3a65906c85e1c1e2f4990
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Thu Apr 3 19:02:05 2008 +0200
-
- Add specs for #kind_of? / #is_a? behaviour that are failing in Rubinius.
-
-commit e88fdb6cbd9fa829a81e6c7664e88f6956ddae64
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Apr 3 07:18:56 2008 -0400
-
- Spec to check `A = 12; class A; end` raises TypeError. Works as is.
-
-commit 3c0db09626333405bdcb72e62ddb8fb2ea176ff5
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Apr 3 06:44:32 2008 -0400
-
- Spec for const lookup: `A = 12; class A::B; end` should raise TypeError.
-
- * Currently crashes due to a lookup problem.
- * VVSiz discovered and reported.
-
-commit edda5994c293e4d26b4a741e90e0ab61513e8dec
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Apr 2 16:39:09 2008 +1100
-
- Do not strip leading spaces in debugger output
-
-commit eecc2bca5045921368378abfccafcf70339441f9
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 2 21:34:52 2008 +0200
-
- Enabled File#truncate testcase for JRuby.
-
-commit 4d555cf50dfe6a8e9cb2f24a6a636a9df3f03768
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Apr 2 20:03:02 2008 +0200
-
- Added test case to File.open rubyspecs.
-
- Courtesy of David Yip.
-
-commit 42f0b52cd9fbac4a39fc1e5c2a241462bee5bf3b
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Apr 2 01:11:38 2008 -0700
-
- Use kind_of instruction since #kind_of? is not available at all times.
-
-commit 9ee52514eee820b9af7c9e6d2eaaca8d2bca363b
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Apr 1 17:16:47 2008 -0500
-
- IO#reopen should return self
-
-commit f1481283091fcbe662fd01d409f5a2d2d7e3aa59
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Apr 1 18:57:06 2008 -0500
-
- added primitive io_close_ng and tagged IO#close spec failures
-
-commit 3861e75e01af9319e2af879e2644fc8509947903
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Apr 1 16:07:27 2008 -0500
-
- IO#close should return nil and refactored TCPServer.accept specs
-
-commit d6dfbd3b0bab57453e67991c3320744b08346979
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Apr 1 15:04:18 2008 -0500
-
- DRb specs now attempt to check if server is up/down prior to each call to start_server
-
- note that there is something wrong with the way stop_server works in rubinius as it appears that the TCPServer is still binding the port. Spec is tagged to deal with this but technically it's probably a bug in TCPServer
-
-commit 4119fe8baab45be6b1d1370b8a9537e710b1a60a
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 1 12:40:47 2008 -0400
-
- Sanity changes to #load specs to bring them up to date.
-
- * Please change the specs if you change the implementation, sheesh.
-
-commit 3b58cb35abeba31f7ac72e3ab37b2630949406a7
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 1 10:59:58 2008 -0400
-
- Spec for forced recompiling through second parameter of Kernel#load.
-
-commit 5d7a73ae15a4c40e31486a60cbb66f3de1ac4697
-Author: David Whittington <djwhitt@gmail.com>
-Date: Wed Apr 2 02:57:35 2008 +0000
-
- Add tags for failing private keyword specs
-
-commit 1b2f118be7ff9b6adfea736ecbbb8f3fd8dd0f49
-Author: David Whittington <djwhitt@gmail.com>
-Date: Wed Apr 2 02:53:43 2008 +0000
-
- Added a couple evil private keyword tests
-
-commit f58c67e33a99f751c3520ab65c96e28a91c45900
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 1 09:59:22 2008 -0400
-
- Conditional compilation. Rubinius.compile_if($DEBUG) { p somevariable }.
-
- * Hacky and probably fragile but it seems to work. Whenever the gvar
- given as condition evaluates to false, the entire block is omitted
- from the produced bytecode. If it evaluates to true, then the extra
- block itself is stripped and only the block contents remain.
- * Do NOT use indiscriminately until we have played around with it for
- a bit to avoid problems.
- * Manipulates the sexp, not the AST to avoid worrying about locals
- and scopes and whatnot.
- * Enabled by default; for example -d will work out of the box (you
- do need to have the file recompiled obviously.)
-
-commit 4f78ee2b0bebb9170a483927af9c7520ca67f912
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Apr 1 09:58:53 2008 -0400
-
- Specs to verify conditional compilation in the compiler.
-
-commit 8dfece35e3bc83e14e92bfee9ea0ebabb795da70
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Apr 1 01:07:14 2008 -0700
-
- Fix up language symbol specs.
-
-commit 29cc22f2c1f7ce2ce15a7f339d1159cf93510daa
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Apr 1 00:40:34 2008 -0700
-
- Constant lookup only searches class or module (#457).
-
-commit 538611f2aa06a1cf1c3958583bd6a8487deee994
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Mar 31 18:03:41 2008 -0400
-
- Spec for empty loop body.
-
-commit fd0d1079671d7664de3a6a836c5e5624d487a4e1
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Mon Mar 31 23:47:40 2008 +0200
-
- Spec for constant lookup on non Module or Class objects
-
- This exposes the bug also described in ticket \#457
-
-commit 3b7cf550c70db2dd53cb58ef3efd2651ee352134
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 31 21:53:40 2008 +0200
-
- Added a couple of Dir.glob/Dir[] rubyspecs.
- (Courtesy of Roland Swingler)
-
-commit bbfa77a8517390bdc807f41bfe6d101791980d8f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 31 19:04:09 2008 +0200
-
- Fixed DRb rubyspecs (proper spec name, removed invalid file, better cleanup).
-
-commit d8a4fb0b16dc4c722cf148ff83bcad05fbb4af1e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 31 14:29:54 2008 +0200
-
- Make sure Marshall#load rubyspec closes the file.
-
-commit 4082a7663eaef50000be46d909c22fbb97a1a3e8
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 31 13:57:35 2008 +0200
-
- Reverted new Range#step rubyspecs, since they fail on MRI and JRuby.
-
- Partial revert "Fixes for Range#step."
- This (PARTIALLY) reverts commit a6b06a67207c40ffa9ccf191c051fdf2fa0f5359.
-
- The specs are reverted since they fail on:
- MRI 1.8.6 pl 36 (Ubuntu default)
- MRI 1.8.6 pl 114 (Current compatibility target)
- MRI 1.8.6 from 1_8 branch
- MRI 1.9 from Ruby trunk
- JRuby 1.1 from trunk
-
- The specs expect that to_f is invoked, but MRI and JRuby don't behave
- that way. Furthermore, Float is not a special case. There are other
- cases, like Rational. Take a look into MRI code, there is no special
- handling for Float.
-
- Please, test your spec updates at least against the current
- compatibility target (MRI 1.8.6 patchlevel 114) to avoid problems.
-
-commit 6d9680ecaaa2a9aadd35699c8064bf6481acc107
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 31 13:23:20 2008 +0200
-
- Added new rubyspecs for IndexError out of String#[]=
-
-commit c8a52bb7cf191bb35efc89c560bdeced4241f015
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Mar 31 04:38:49 2008 -0400
-
- Split Regexp#=~, #match specs; they behave differently on match.
-
- * #=~ Returns index, #match returns MatchData.
- * Grammar fixes.
-
-commit 6c2727e928991cdf9f809cb5941c3afedb5171ff
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Mar 31 04:07:17 2008 -0400
-
- Fix Regexp#match, #=~ spec to actually be shared. Exposes #454.
-
-commit e258a2bccafffba57ab86d1c1a104839bda424da
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Mar 31 03:30:48 2008 -0400
-
- Spec to verify IO behaviour with an altered BufferSize from Le Huy.
-
- * Moved spec to spec/core/io/ and simply used the first one.
- * This problem seems to have been largely corrected.
-
-commit 7a39be8bea055464838ff24c70e170a91f8df68c
-Author: Ben Burkert <ben@benburkert.com>
-Date: Sat Mar 29 19:39:11 2008 -0500
-
- Added spec for Module#define_method
-
- Methods defined by define_method with a proc should have the
- same scope for local variables as the proc.
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 12c639d90ff3d14f8010ca7c782612bd7c1777ab
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Mar 29 23:58:13 2008 -0400
-
- Tony Arcieri's specs for inter-VM Actors.
-
- * VMActor implements the Actor interface to work in Rubinius' Multi-VM
- context: VMActors can reside on any VM instance.
-
-commit a0d0884aa3c9e7a6fa949cbde1cdf2392bc4ff23
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Mar 29 15:59:42 2008 -0400
-
- Module#attach_foreign allows using a symbol to give the function name.
-
- * Specs for the same.
-
-commit a5f397f38d6c9eafcac163c2cf678d5c55a6b79b
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Mar 28 23:40:04 2008 -0400
-
- Specs for FFI in general and Module#attach_foreign in particular.
-
- * Very basic specs to verify that FFI in fact works correctly.
- * We need to define what the behaviour should be in the case of e.g. an
- incorrect function signature. Currently it may or may not cause SEGVs
- depending on the exact usage. Remainder specs are in but quarantined.
-
-commit 3dc5c635b56bc599a718a94f990976b67ab52b6c
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Mar 26 02:01:12 2008 -0400
-
- Specs for Module#attach_foreign.
-
- * The method is a replacement for #attach_function but allows
- giving the library name as well to access external libs.
- * This acts a higher-level interface to FFI.create_function. The
- "real" FFI specs will be written for that method instead.
-
-commit 677412353409ba4e5d67f19a3d095c62d009c88f
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Mar 28 18:04:40 2008 -0700
-
- Added CType#isctrl, #toprint. Rework String#inspect, #dump.
-
-commit 87ba991b9b488b808ebf729b9e41765df76cc602
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Mar 28 15:09:11 2008 -0700
-
- Reworked String#each and #sum. Added String#modified? and specs.
-
-commit 204d8ce1a792a61882e549953b5b878139ac9cda
-Author: Hongli Lai <hongli@plan99.net>
-Date: Fri Mar 28 23:32:18 2008 +0100
-
- Spec: Marshal raises EOFError on loading an empty file
-
- Signed-off-by: Michael S. Klishin <michael@novemberain.com>
-
-commit f6e698f96ce9e2a8c8abe856322add02931df8b7
-Author: Michael S. Klishin <michael@novemberain.com>
-Date: Sat Mar 29 02:20:23 2008 +0200
-
- Tag new spec for ensure as failing
-
-commit ef7e4436389a0f4346b3a3bc5c275b653f46d6bb
-Author: Hongli Lai <hongli@plan99.net>
-Date: Fri Mar 28 23:22:44 2008 +0100
-
- Add spec for exception handling inside ensure block.
-
- Signed-off-by: Michael S. Klishin <michael@novemberain.com>
-
-commit f54c91f6cb7498fe44b1b05a1372d9f6ed3ea1ee
-Author: Stuart Halloway <stu@thinkrelevance.com>
-Date: Fri Mar 28 10:11:05 2008 -0400
-
- Fixes Pathname#absolute? and #relative?.
-
- * specs now pass
- * underlying cause was corner case in File#basename
- * new passing spec for corner case
-
- Signed-off-by: Charles Comstock <dgtized@gmail.com>
-
-commit 0d4606d53d8fc0bcb2370bd648546abffd402673
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Mar 28 16:45:47 2008 -0500
-
- fixed CSV::Reader.parse spec to use local fixtures
-
-commit 35a15c6c85ebb6eabaec16e03aa88399061844e9
-Author: Alister Lee <rubinius@dev.shortepic.com>
-Date: Sat Mar 8 18:11:24 2008 +1100
-
- Beginning of specs for CVS::Reader.parse
-
- Signed-off-by: Charles Comstock <dgtized@gmail.com>
-
-commit d4161a379eab621e338a8c82f088b834756082e9
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Mar 28 16:39:50 2008 -0500
-
- removed csv/reader/parse_spec to commit alister lee's spec
-
-commit 534806c10a95435873efcb0d215732d7da4f2fd6
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Mar 28 16:38:03 2008 -0500
-
- mkspec generated specs for csv.rb
-
-commit a6b06a67207c40ffa9ccf191c051fdf2fa0f5359
-Author: Stuart Halloway <stu@thinkrelevance.com>
-Date: Fri Mar 28 06:09:34 2008 -0400
-
- Fixes for Range#step.
-
- * previously failing specs pass
- * new spec added to cover float/int difference
-
- Signed-off-by: Michael S. Klishin <michael@novemberain.com>
-
-commit 6886ec5851783c5364ff5bc464ee94071fc8535e
-Author: Michael S. Klishin <michael@novemberain.com>
-Date: Fri Mar 28 00:06:56 2008 +0200
-
- Update stdlib and specs for REXML from 1.8.6 patchlevel 114 (see details!)
-
- * Update stdlib/rexml to use REXML from Ruby 1.8.6 p114.
- * REXML in p114 is screwed up: call sites were not updated
- after REXML::Formatters::Transient#initialize arity
- change. Ruby 1.8.x branch in SVN though has
- completely different REXML layout and organization
- (rev. 15833) so there's no way to fix it until we know
- where REXML changes are headed in 1.8.x branch.
- * Update REXML spec and tags for it.
-
-commit 3145a74a85d72f6ef8a93384a74d96a589bfb5eb
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Mar 26 22:27:41 2008 -0700
-
- Rework and cleanup of various String methods.
-
- Also, ensure that when Strings are converted through FFI
- and passed to C functions, the char array is explicitly
- terminated with \0.
-
-commit 9ba3e515b49729e0cb80181af9e28e3ce4c70e97
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Mar 26 18:40:57 2008 -0700
-
- Shuffle some String methods. Add specs for and rework String#substring.
-
-commit 990d47b84bc6301be2a8bcbaccbae65ef697c417
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Mar 25 16:22:45 2008 -0700
-
- Added String#compare_substring. Reworked String#chop! and #chomp!.
-
- Also, to ensure that ByteArray instances that are accessible in
- Ruby are properly handled by C functions, changed string_equal_p
- to use strncmp instead of strcmp.
-
-commit f47c446daa136e6f31f5c590dd535ba22e89a0b2
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Mar 25 11:36:16 2008 -0700
-
- Fix errors in String#count_table spec descriptions.
-
-commit 9425d0de9a7883c14de6ae9ae5db05ab92141ab9
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Mar 26 22:38:48 2008 +0100
-
- Guarded two failing specs on OpenBSD that also fail on MRI
-
- MRI on OpenBSD also suffers from the 0.0 / -0.0 issue (the
- GCC version on that platform too). The child reaping spec
- also fails on both MRI and Rubinius
-
-commit 288a6e2ca3675a1e60bfd6b8b328c2a4d513c12f
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Mar 26 22:15:16 2008 +0100
-
- Fix Socket specs for more strict BSD behavior
-
-commit 63513d23f16ca7919b8605e016a3a941b79c0834
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Mar 25 17:20:53 2008 -0700
-
- oops! extra exclude
-
-commit a36a4bf8cde95c99282e07f46438430588288736
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Mar 25 17:20:19 2008 -0700
-
- really minor changes
-
-commit e9b759812deaf97e7fe5846c116d53f69b63e244
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Mar 25 17:19:41 2008 -0700
-
- Added the sucky parser spec--not passed yet
-
-commit 90eb74998e132373e6b96e3c66bfa909854e3ef0
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Mar 18 17:41:50 2008 -0700
-
- Added spec for 'a [ 42 ]'
-
-commit 2d34643c75b53b832e89d2473d501ab1c8a5df02
-Author: David Whittington <djwhitt@gmail.com>
-Date: Wed Mar 26 08:01:20 2008 +0000
-
- Tagged Generator specs as unstable due to memory consumption
-
- Each spec consumes > 60MB of memory. After looking at the specs there is no way
- they should be consuming that much memory.
-
-commit 52d81e0593dbca8abfecefe2e9c3d2ab504cfe0b
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Mar 25 10:43:17 2008 -0700
-
- Added String#copy_from primitive. Reworked String justify methods.
-
-commit 1aabda50ea82974b96a7032a0ea13865b2332b5d
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Mar 24 21:57:02 2008 -0700
-
- Added Tuple.template and reworked String#tr and friends.
-
-commit bc7d9ccb8b8ca77d8479f325ea314fc09bc34907
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Mar 21 00:51:10 2008 -0700
-
- Rework methods that behave like String#count.
-
-commit 1e5ac9a6818c972882e080aeb723a105108e0c57
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Mar 19 21:25:07 2008 -0700
-
- Rewrite of String#casecmp, approx 2x faster.
-
-commit c39f2cb708169d35c2fbeb969ee3323c704f0566
-Author: Matt Palmer <mpalmer@engineyard.com>
-Date: Tue Mar 25 21:09:37 2008 +1100
-
- Some specs for the timeout library
-
-commit cb69bdadeb10cf6b4b2c71a095562f8d8371d76d
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Mon Mar 24 17:55:23 2008 -0500
-
- Small fix for Socket.getaddrinfo spec
-
- Signed-off-by: Michael S. Klishin <michael@novemberain.com>
-
-commit 5c3a61edef3c456b8296e65f8e06026347339a36
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Mon Mar 24 17:06:36 2008 -0500
-
- Fix for the socket's issue
-
- Signed-off-by: Michael S. Klishin <michael@novemberain.com>
-
-commit f3fd9ac4eebd0bc2a0a06bbe06921463d03177eb
-Author: Federico Builes <federico.builes@gmail.com>
-Date: Mon Mar 24 14:10:46 2008 -0500
-
- Fixes specs for Socket and adds a gethostname spec
-
- * Changes hardcoded "localhost"s to Socket#gethostname calls.
- * Adds a simple spec for Socket#gethostname
-
- Signed-off-by: Michael S. Klishin <michael@novemberain.com>
-
-commit 7131328bc02057b16071a933fe98f331b27e00bb
-Author: Michael S. Klishin <michael@novemberain.com>
-Date: Tue Mar 25 00:24:01 2008 +0200
-
- Applied slightly modified patch by Federico Builes:
-
- * Add REXML::Document and REXML::Attribute specs
-
-commit cb464295e5accb00e783f7f9e2a0b10c64ad6579
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Mar 23 12:06:07 2008 +0100
-
- Added new Range#step rubyspecs.
-
- Excludes for rbx also updated.
-
-commit 7d181716ac3b92d8a31a20ec30daee455d36fc58
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Sat Mar 22 14:51:30 2008 -0500
-
- Added order-of-evaluation spec and tags for rubinius failures.
-
-commit 5caf94ce6deb5e28c9a3de02e60a9b86cbdaf7ec
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Mar 21 12:37:02 2008 -0500
-
- tagged new specs for pathname
-
-commit 62f88983ee3fa1b09d8f7df56e35cbfdac6d2a06
-Author: Martin Stannard <mstannard@gmail.com>
-Date: Fri Mar 21 12:10:23 2008 +1100
-
- added some specs for pathname library
-
- there are failures in absolute and relative specs
-
- Signed-off-by: Charles Comstock <dgtized@gmail.com>
-
-commit 655f61650bb299f38c9fd978594baa483fc0d0cc
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Mar 18 16:22:24 2008 -0700
-
- Reduced parser todos from 113 to 89
-
-commit f97b2fc2ee3310e81871200125bbd7e33c2636bf
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Tue Mar 18 13:51:31 2008 -0700
-
- Moved sexp_expectations.rb to fixtures subdir
-
-commit 0a185e5ac48954cf4addae0c8f09dcb5be259f8e
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Mon Mar 17 17:55:50 2008 -0700
-
- Added f'd up note about the spec failing
-
-commit 978f043e1ed3a2b7cb7d4129e0002be485b0a78c
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Mar 18 21:17:32 2008 +0100
-
- Fix Process.groups spec
-
- Process.groups can return an array with the same gid multiple
- times on certain platforms (at least on FreeBSD and OpenBSD).
-
-commit 8812658dde5e317dfebd0ea3c159ad0a1b98e8e8
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Mar 18 21:02:00 2008 +0100
-
- Update spec tags for ERB
-
-commit 47216560d4a980cbaac2855e0c5ee302e0754bf8
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Mar 18 20:53:16 2008 +0100
-
- Update spec tags for IO
-
-commit 7d34f4053023d99c3be4964bfebb3a1c74cd40c9
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Mar 18 20:32:39 2008 +0100
-
- Update spec tags for File
-
-commit 8a66bc6f5e378f49febb80fba37723a7de0d2475
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Mar 17 15:46:51 2008 -0700
-
- Added specs for File.[l]chown/#chown, code for File.lchown.
-
-commit 960872ae163a5615f513c58d727a7fd93664673e
-Author: Glenn Davy <glenn@thor.local>
-Date: Mon Mar 10 10:00:40 2008 +1100
-
- Make File.fnmatch respect case when using square brackets
-
-commit 0e32f8e224543a3c152b0351540eaa36fdfcdb06
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Mar 17 11:04:27 2008 -0700
-
- Added exclude for failing spec added in b635fcf0.
-
-commit 62687753b239984acba4f0e80899ca75a8a08cfe
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Mar 17 10:56:31 2008 -0700
-
- Fixes and specs for Module class_variables methods.
-
-commit b635fcf041707fe55a26b7709aef8dc1b2509161
-Author: Charles Oliver Nutter <charles.nutter@sun.com>
-Date: Mon Mar 17 12:52:13 2008 -0500
-
- Add a simple Module#private spec.
-
-commit 2aa98e1df50bba768b57018f6e90c56fe39206f4
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 17 13:28:17 2008 +0100
-
- Make sure no processes left hanging after IO#close specs.
-
-commit 8f332dde4460c03c378f1d1ecc1fbae54557d8ee
-Author: Matt Palmer <mpalmer@engineyard.com>
-Date: Mon Mar 17 16:44:24 2008 +1100
-
- Raise an Errno exception if a write fails
-
-commit 55c830063115e4455eeda3f8de639a7f7e0624f5
-Author: Matt Palmer <mpalmer@engineyard.com>
-Date: Mon Mar 17 16:42:16 2008 +1100
-
- Raise IOError if we attempt to write to a readonly file
-
-commit ad64c0ea7598b8a4c62ba2dd435f70c976186a50
-Author: David Whittington <djwhitt@gmail.com>
-Date: Sun Mar 16 04:24:54 2008 +0000
-
- Modified file type specs to search for sockets in /var/run instead of /var
-
- Doing a find on /var could take quite a while + might do nasty things like do
- finds on backup files etc. Running a find on /var/run should be faster and
- safer.
-
-commit ff5e9d3b9d7f3e484211b66fff96e665ed13614b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Mar 12 17:44:55 2008 +0100
-
- Revert "Added simple spec for range splatting".
-
- This reverts commit 9b3988436a21f61c86168a7566d472c4dfa22162.
-
- The spec uses '=' instead of '==', and it verifies something
- that is not true for MRI (1.8, 1.9) or JRuby.
-
-commit 004662e54477269a98475f84724972b82885d9cb
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Mar 15 01:09:43 2008 -0700
-
- Exclude failing UNIXServer.new spec.
-
-commit 13340924519f607d9c48da04c3f3ab41a1de3e86
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Mar 14 18:14:06 2008 -0700
-
- Tagged unstable Process.kill specs that cause hangup on linux.
-
-commit c4a4dc19a26db058594c8056933cdab42d4f26fd
-Author: Matt Palmer <mpalmer@engineyard.com>
-Date: Fri Mar 14 21:13:31 2008 +1100
-
- Fix up IO#write spec so it works cross-platform
-
- It looks like the Linux implementation of IO#write and IO#read are a bit
- different from the OS X version, because the spec worked on OS X.
- Presumably this tiny change won't cause any conniptions.
-
-commit 33890d9a77d5a34c15263f84b9b415ffc084815a
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Mar 14 14:42:11 2008 +0800
-
- Remove fail tags from passing ruby/1.8/core specs
-
-commit 4bdd3df099fe627d158f4c6d35e5a7df0a891e86
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Mar 14 12:58:40 2008 +1100
-
- Fix bug where stepping by line would sometimes skip a line
-
-commit 260190092afbcfadd1a6e1d6db1674ecf021b686
-Author: Matt Palmer <mpalmer@hezmatt.org>
-Date: Sat Mar 8 19:26:41 2008 +1100
-
- Put in an explicit IO.new test for single-argument
-
- Assuming that your UDPSocket tests passing will prove that IO.new takes
- one argument might have been, in retrospect, a little retarded.
-
-commit 58216e07f0728415762fe5fbe98e1e984dfea31b
-Author: Matt Palmer <mpalmer@hezmatt.org>
-Date: Sat Mar 8 18:45:17 2008 +1100
-
- Mark changing failures in the CI test suite
-
- Fix up so that the CI doesn't fail as a result of my previous changes to the
- UDPSocket specs.
-
-commit 36f91c5da132f309fbf6d047fd74ebd8aa7cbf22
-Author: Matt Palmer <mpalmer@hezmatt.org>
-Date: Sat Mar 8 17:26:49 2008 +1100
-
- Rearrange the UDPSocket test cases for better separation
-
- * open_specs now only contains a spec that calls UDPSocket.open;
- * send_specs now has separate tests for ad-hoc and connection-oriented
- sends.
-
-commit b40c1cf434bd0879f672ec1dc471f1e1dfaccc1c
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Mar 13 17:07:50 2008 -0700
-
- Add (failing) Symbol#to_yaml spec based on ticket 322
-
-commit c0bcb0151379fe9858d0fafd2ef56cf1b08daff3
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Mar 13 16:23:37 2008 -0700
-
- Apply ticket 351 and resolve ticket 350 (RbYAML bugs)
-
-commit a8d6e8cddfd8bc2dccaa93b25adfb31b39b96dba
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Mar 13 16:25:55 2008 -0700
-
- Removed all should_not raise_error from shared/time_params.rb
-
-commit 01f09f4e5697c4a775ac321a71d3b777196d9001
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Mar 13 15:47:37 2008 -0700
-
- cleaned up spec with new raise_error block form
-
-commit e965fc735311915dd43c47cc4853e163376cc6be
-Author: Lachie Cox <lachie@smartbomb.com.au>
-Date: Sat Mar 8 17:14:37 2008 +1100
-
- enhanced syntax error to give same message as MRI
-
-commit 868b38152ca99189fce85542a9068c0d01ee4a41
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Mar 13 15:07:33 2008 -0700
-
- Added exclude for last patch applied
-
-commit 9b3988436a21f61c86168a7566d472c4dfa22162
-Author: Patrick Hurley <phurley@gmail.com>
-Date: Mon Mar 3 14:04:14 2008 -0500
-
- Added simple spec for range splatting
-
-commit 3c7a017e173945d3f9b18d566bb1c3d6d04e97e4
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Thu Mar 13 17:18:39 2008 -0500
-
- fixed tags for new constant specs
-
-commit a966436b7be78bc063e32bc16496f5cabbb0a152
-Author: Matt Palmer <mpalmer@hezmatt.org>
-Date: Sat Mar 8 14:56:58 2008 +1100
-
- Make sure modules included in Object are found
-
- Add a spec to make sure that constants from modules included in Object are
- found. Evan is committing the fix for this separately.
-
- Signed-off-by: Charles Comstock <dgtized@gmail.com>
-
-commit 4e0ddd3e701f68b592cb69972f7d587b90392913
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Mar 13 15:05:54 2008 -0700
-
- Correct a 'defined?' spec added by ticket 388
-
-commit 407095d8ffbf0563fa46e5d4ed6a08423eddb2ad
-Author: Martin Stannard <mstannard@gmail.com>
-Date: Sat Mar 8 15:47:59 2008 +1100
-
- Added tests where defined? method should return string descriptions of objects
-
-commit f366309a8fff28552d7d27101d8b3d7b4352e235
-Author: Gianluigi Spagnuolo <glgspg@gmail.com>
-Date: Fri Feb 29 10:42:42 2008 +0100
-
- Fixed Array set element problem
-
-commit 42c22bf542edc8c8379587507fd9e35ba25b190c
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Thu Mar 13 17:00:31 2008 -0500
-
- updated tags for new read specs
-
-commit 45c43a7ab3310a41b0b3367f4762a1bb55b02405
-Author: Ben Askins <benj@supernova.local>
-Date: Sun Mar 9 11:41:49 2008 +1100
-
- Fix typo in file/open_spec.rb
-
- Signed-off-by: Charles Comstock <dgtized@gmail.com>
-
-commit a221ea56325fe082154a629094abb27d40919a39
-Author: Alister Lee <rubinius@dev.shortepic.com>
-Date: Sun Mar 9 15:27:34 2008 +1100
-
- Specs to expose defect in eof treatment in IO.read
-
- Signed-off-by: Charles Comstock <dgtized@gmail.com>
-
-commit 4967adb3d49252aae75b6b57159fb5879ac75db1
-Author: Myles Byrne <myles@ducknewmedia.com.au>
-Date: Sat Mar 8 12:14:20 2008 +1100
-
- Check existence of ArgumentError
-
-commit 45e46234da288052e639bb5c9c122874fd4d4e1c
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Mar 13 10:28:54 2008 -0700
-
- Fix File[Test].size? and specs for it.
-
-commit d467bf21c4037784a21ba964b24c28fc80b34736
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 17:36:56 2008 +0800
-
- Fix IO::foreach when separator is nil
-
-commit 70615e1c15692b8a8149e1616c802db9eb5bad11
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 17:32:40 2008 +0800
-
- Fix IO#flush to raise IOError on closed stream. Remove empty tag files.
-
-commit 9c9e7f422c98bf6add6c9a426ae25e3a6dbced85
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 17:29:31 2008 +0800
-
- Fix IO#fcntl to raise IOError on closed stream
-
-commit 215d600002948efb949422c0163aa9bbe5790507
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 17:27:43 2008 +0800
-
- Fix IO#dup to raise IOError on closed stream
-
-commit 879ee8124a2ad8ce83bcd9c51b2d6df0baecb40d
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 16:29:03 2008 +0800
-
- Fix a bunch more IOError when closed stream
-
-commit 487d9561992eb03c3d12de5128772cd194b37b8b
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 16:26:33 2008 +0800
-
- Implement IO#read_nonblock
-
-commit 15c58fa2c47d2dc61b3dac436ab3b56a727b7dc5
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 15:46:22 2008 +0800
-
- Fix remaining IO.read specs
-
- * Passing nil to length treats it as no length limit
- * Passing nil to offset treats it as 0
-
-commit 9daee4f9c3b62db34b07d74171d1017fa823533c
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 15:32:13 2008 +0800
-
- Fix IO#sync to raise IOError on closed stream
-
-commit 2ac848c09e055b3eacc8bb18f713d56715484063
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 15:24:36 2008 +0800
-
- Fix IO#sync to raise IOError on closed stream
-
-commit 36aa8577603f1d8ca76344fc3e889bb7c991bfe9
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 14:51:13 2008 +0800
-
- Fix IO#sysseek to raise IOError on closed stream
-
-commit 3307f5a4db121c2097b450278bc3cf19550f267b
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 14:48:30 2008 +0800
-
- Fix IO#pos and #IO#tell to raise IOError, move their specs to shared
-
-commit 72890065371f3e1d1cde43618a3da04c900749aa
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 14:39:21 2008 +0800
-
- Implement IO#to_io
-
-commit 4977bd1f22278e19ba69203c2545ad97c297ae23
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 14:33:03 2008 +0800
-
- Remove IO#isatty tag file also, since they are sharing the same specs
-
-commit 5dd3115465852ddb03b7100b21739f9d38f0ee58
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 14:29:13 2008 +0800
-
- Fix IO#tty? should raise IOError on closed stream
-
-commit 063f56b4c402180c2c989a15b75fe7a15d4c5c61
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 13:55:55 2008 +0800
-
- Make IO#syswrite use the shared IO#write specs
-
-commit 22de413f6cccb3eb100fd29da90c2ded84ea19f3
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 12:08:50 2008 +0800
-
- Update IO#write_nonblock's tag
-
-commit 25a5ac7e9123512e87e6460f1fa5ecbcfc7349b5
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 12:07:22 2008 +0800
-
- Pull out 2 differences between IO#write and IO#write_nonblock specs
-
-commit a40dbd0f36f0237bc27c905c399aba1e62bbfa70
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 11:39:03 2008 +0800
-
- Alias IO#write_nonblock IO#write and make IO#write specs shared
-
-commit 1c8eb4bc04405753dd607af1f5d231df01fd2536
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 11:06:09 2008 +0800
-
- Make the mock return a string to prevent a coercion error
-
-commit a85b2105c826a7d39dc45c90cad37faf75baac86
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 10:39:00 2008 +0800
-
- Fix IO#write should raise IOError on closed stream
-
-commit e8c8af1aa888dc3e5600cad64f03c09aebaf6d22
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Mar 13 10:34:08 2008 +0800
-
- Fix IO#to_i should raise IOError on closed stream
-
-commit 49d48c381b7ed0f2576c2c5bff3ac8825a0dd49e
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Wed Mar 12 17:56:26 2008 -0700
-
- Fix the insanity
-
-commit 646136d0f75b165a3a62266791556d3f4f03c835
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Wed Mar 12 17:04:30 2008 -0700
-
- Finally got compiler specs passing
-
-commit 052bbcbe4f51b322ae44dc387320f9b4964d74cd
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Mar 12 16:23:58 2008 -0700
-
- Correctly set Syslog mask in Syslog::open and add crappy spec for it
-
-commit dbabc5bda94a2bd77b2cb777666d286155c75ee0
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Mar 12 14:55:08 2008 -0700
-
- Correct Syslog specs and modify syslog.rb to pass them
-
-commit 5b8bee08f2a19d6f25df98183a24745ed33ed519
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Mar 12 14:54:38 2008 -0700
-
- Modify Kernel#load specs so that they pass on 1.8.6-p111
-
-commit b96974693cee75772b09052f8ec7110a000c2429
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Wed Mar 12 14:00:42 2008 -0700
-
- Fixed specs for wilson's compiler encloser changes
-
-commit 2a21597719bea1ea7db27a552ea6dfb6865963d7
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Wed Mar 12 14:00:06 2008 -0700
-
- half work on pretty_inspect
-
-commit 6e398ca491b67a6c468798fd92a9764f70bc68a8
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Wed Mar 12 15:18:02 2008 +0800
-
- Share String#to_a a specs with String#entries
-
-commit 2ff775cbcf2ade4315fbdbb37fa78ee84a1e645a
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Wed Mar 12 11:59:26 2008 +0800
-
- Add String#to_a specs
-
-commit 4f1204bac224ad28375f06e5fb77156367895156
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Mar 11 19:53:32 2008 -0700
-
- Spec and implement Array#pack 'v' option
-
-commit 91d51783f44c3a9b1adfe03b7b9fa35476494ce1
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Mar 12 12:45:56 2008 +1100
-
- Debugger::Output#wrap should handle width of 0
-
-commit 51c316464ad44cadad7ecd997ce45e8392695f4c
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Mar 11 15:26:52 2008 -0700
-
- Implement support for :postexe nodes (END { some_code })
-
-commit 569dd9f10d5194c22335ce58a678d1f9c73f91d0
-Author: oleg dashevskii <be9@be9.ru>
-Date: Wed Mar 12 03:54:39 2008 +0600
-
- Import matrix lib with specs (#389 and #400)
-
- Original patches by Chris Lloyd and matta.
-
-commit 6beb50b7cc2dd3a0f57f3dee45767bb363082159
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Mar 11 13:20:07 2008 -0700
-
- More Integer#times specs.
-
-commit 746d89d6d55c82f26be08f182301926efd62d362
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Mar 10 15:39:26 2008 -0700
-
- Correctly set the enclosing class for evaled code.
-
-commit 218cc7fbdd1b5d1c52248e65817752b8a50821ad
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 10 04:46:00 2008 +0100
-
- Added JRuby speciifc guard to singleton rubyspecs (JRUBY-2239).
-
-commit 25e3f23e78f2b17e02d2c0a058925f8a0ec0d790
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Mon Mar 10 11:25:38 2008 +0100
-
- Be sure not to close the socket before the Errno.handle call
-
- Also a small fix for a spec that fails on OpenBSD
-
-commit 9e7fdf3b0040971f7b8402b9cf5422efaedb2f4f
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Mon Mar 10 09:54:16 2008 +0100
-
- Fix TCPSocket#new spec, BSD systems make a distinction between IPv6/IPv4 localhost
-
-commit e5512b2a7725a67471eba086b107b0f4b1f136b2
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Mon Mar 10 08:35:50 2008 +0100
-
- Fix for failing unpack_sockaddr_in spec on Linux
-
-commit b9eab2266e5d1f073b6f876710dc9e848fe25b0c
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 23:37:05 2008 +0100
-
- Remove spec tag for now fixed Hash.allocate
-
-commit b6ba9a757b0531791424df38bce6587a53db6002
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 23:12:16 2008 +0100
-
- Remove tag for now correct Fixnum#[] spec
-
-commit 6785c2b44da90d95ef77e98cba42a953828b622f
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 23:11:37 2008 +0100
-
- Fix Fixnum#[] specs
-
-commit 0aa09ce9b7269d54cdef583a2eaf0cb57c32f773
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 23:05:21 2008 +0100
-
- Removed tags for working Socket specs
-
-commit 18b27b0ebdc3713962771ca75c1321cabee08d61
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 22:48:45 2008 +0100
-
- Untag now working IPAddr specs
-
-commit f4c0d08bec8fb2db7d130363b0609de7b7720d7e
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 19:56:25 2008 +0100
-
- Slow IPAddr specs are now fast
-
-commit ff71385a67b2853130e63f9942bcea6ac69d591f
-Author: Eero <ruerue@yawn.kittensoft.org>
-Date: Sun Mar 9 10:35:27 2008 -0400
-
- Specs for #412. Array#sort and #sort block form calls #<=> on elements.
-
- * Block form should not expect anything of the elements, all is
- done through the return value of the block.
-
-commit e6edd1bb4bc52053bdb834d52e31fa185f2a2d62
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 14:51:00 2008 +0100
-
- Updated tags for IPAddr because of fixed bit operations
-
-commit 4f59fa9bd187822cd836aa046bb8fd40e4412c30
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 14:49:02 2008 +0100
-
- Fix Fixnum and Bignum shift operations to match MRI
-
- Added behavior for the edge cases, but took a different
- approach than the LH tickets. I don't think we should
- change coercion functions for this.
-
-commit ad8c630662dcb611cd955db08a6f4d53d1dc0dfd
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Mar 9 13:43:38 2008 +0100
-
- Fix Bignum#& and specs for Fixnum AND, OR and XOR
-
-commit 2529acd5e1cc8e61bd995e00834ee1f6941b1d9d
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Sun Mar 9 14:18:04 2008 +1100
-
- Fix require_spec and load_spec.
-
-commit 57c7ded8e4d9567aa3c392e8a8262389387ebbfb
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Sun Mar 9 12:25:40 2008 +1100
-
- Don't spec .rba require behavior in spec/ruby/1.8.
-
-commit ac630b23da01dcc3a1de1bfa06bac4d301a5031b
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Mar 8 17:23:34 2008 -0800
-
- Better fix for calling to_proc on BlockPass nodes
-
-commit c17b32d44be8452cd867a8212a0fd8bb49c94821
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Mar 8 16:34:02 2008 -0800
-
- Tag failing Method spec for CI
-
-commit c5d4a3b8f84b7558a5dfedb699a1a3ee4d61f118
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Mar 8 16:26:58 2008 -0800
-
- Call Proc.__from_block__ on block_pass arguments
-
-commit a63f457821e67d138d9cf1c5ac8b0760cb25bfc2
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Sun Mar 9 10:42:51 2008 +1100
-
- Remove support for zip rba files, libzip. rake clean required.
-
-commit 142222e41bddd2138d82f349f73dbc0fe2cf3fc2
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Sat Mar 8 16:23:37 2008 -0600
-
- Adding a spec for Method#to_proc proc used in define_method.
-
-commit b748efa9904baf0be26aa5b7297fc8ba76e46a74
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Mar 8 13:09:44 2008 -0800
-
- Fix Module#method_defined? and friends for accessors
-
-commit 9b9d8216014c95eb7b4a925e93d0db8e9f5fd308
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Mar 8 10:46:18 2008 +0100
-
- Adedd a couple of GzipReader#rewind specs.
-
-commit 4612812bde4a2fccbaa72ea54ef76c7d964d216b
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Mar 8 15:49:57 2008 +0100
-
- Fix the Array#pack specs, network order is the same everywhere
-
-commit a720bba1619deb4358b453f58913d30a1a311b07
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Mar 8 15:27:47 2008 +0100
-
- Fix Sprintf for positive non decimal notation
-
- This fix combined with the pack/unpack implementation for
- type n also fix some IPAddr specs.
-
-commit caef838aca82665d4c2f691e4873e339a9c7238d
-Author: Lachie Cox <lachie@smartbomb.com.au>
-Date: Sat Mar 8 12:47:19 2008 +1100
-
- updated Array#pack specs to work on big endian machines
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit e3763469a224b4b3668bc1ddef2d982245787646
-Author: Lachie Cox <lachie@smartbomb.com.au>
-Date: Sat Mar 8 12:42:36 2008 +1100
-
- Added implementation of pack schemes for "n" and added handling of multiple items for "i","s" and "l"
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 41b26c49f5a16377af2c677eb702d665dd062a56
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Sat Mar 8 15:35:10 2008 +1100
-
- Fix IO#pos EOF spec. Pair: Lincoln, Evan.
-
-commit 1e039fb5c9bcff987769c8644ec47c30aa250952
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Sat Mar 8 14:53:01 2008 +1100
-
- Fix Zlib::GzipWriter#finish. Pair: Lincoln.
-
-commit 8551da47a01ef24eaf31fac55253fb05fe81cfcd
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Sat Mar 8 14:21:08 2008 +1100
-
- Add Zlib::GzipReader #eof?, #pos, #read w/length
-
-commit a4dba8317311cc3a51231895b2eaea09daaa61be
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Sat Mar 8 10:41:33 2008 +1100
-
- Ensure #pos clears internal eof flag
-
-commit 407e1a4191da6ecd59c1347198a60be2556e043b
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Mar 7 17:04:09 2008 -0800
-
- Tweaks to LookupTable. Converted Errno::Mapping to use LT.
-
-commit eb937c8f1041884e412e3d074387ca9f14bb03ef
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Mar 7 13:48:45 2008 -0800
-
- Fixed LookupTable#delete. Added LookupTable#entries, #dup.
-
-commit d7d9bfd01180cf2c4fc74d2709f71fc7dd59f2f6
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Mar 7 15:03:14 2008 -0800
-
- Bandaid fix for failing #autoload specs.
-
- These need to be properly scoped. However, changing
- :A to ModuleSpec:A causes a sigbus.
-
-commit aea5cc446cd2c1b0cbd29e606b21b6d5959eb5ee
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Fri Mar 7 16:18:19 2008 -0500
-
- Add rb_gv_get and rb_gv_set, plus specs.
-
- Add rb_set_safe_level, rb_secure, and rb_safe_level methods, and specs.
-
-commit cd0b8969487af84a4f40466714dab2d5a1efc224
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Mar 6 17:11:20 2008 -0800
-
- excluded
-
-commit e40f2bb09d8e3137de2856cb1e9c9438945603dc
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Mar 6 17:11:00 2008 -0800
-
- More specs to test out const scoping with eval
-
-commit 3926add9039d1af4a60b633ef8805d471f28e02f
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Mar 6 17:01:21 2008 -0800
-
- Further clarified StringIO#getc specs.
- They weren't really testing what they were doing.
- Fixed StringIO#getc. now properly pushes single chars and sets @pos so it can be mixed with puts/write as needed
-
-commit d2d3750c4960d4a6f2a5d2b16b8bae3d598fbe36
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Thu Mar 6 19:16:24 2008 -0500
-
- Add rb_define_global_function to subtend, with tests
-
-commit 4ab5cc17b70b6569cf9311142d4b278dedfd0a64
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Mar 6 09:53:20 2008 -0800
-
- Added LookupTable and specs.
-
-commit 1ca8a272137ed7020cb977bf51dd2b7164ccbd7e
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Wed Mar 5 17:28:40 2008 -0600
-
- TCPServer.new coerces non-integer port to string and uses getservbyname logic.
-
-commit f0c03880972c19d1a12367dc51ed77f69d9ce8ca
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Wed Mar 5 16:44:33 2008 -0600
-
- Add a couple specs for killing/raising in a thread blocked on accept.
-
-commit 9f80ef157851671727653f46225b99af5d1a259e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Mar 4 21:26:33 2008 +0100
-
- Proper spec for %u with negative bignums and comments on MRI behavior.
-
-commit 3f9c36081c9b62bcde40206e64afdc2ac088bee8
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Mar 4 19:09:56 2008 +0100
-
- Update tags for fixed File#chmod specs
-
-commit 735e818c38f8cefe0cd90514dac5282845a67dd4
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Mar 4 15:13:23 2008 +0100
-
- Improve testing of coercion in File#chmod specs
-
-commit 77a717f5962b2965ad9146e16cb36bedac891c80
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Mar 3 18:16:04 2008 +0100
-
- Adjusted syslog specs to better handle impls that don't provide syslog.
-
- For example, JRuby does not provide syslog (yet).
-
-commit 605bdc53e9dd4fb95dae6557d9ee6f9e2b8ceb80
-Author: David Whittington <djwhitt@gmail.com>
-Date: Mon Mar 3 08:44:33 2008 +0000
-
- Modified Bignum threshold specs to take into account platform wordsize
-
-commit 0af27d11d7dd68cfe49985dc4588933cc41f4fc8
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Mar 2 16:40:15 2008 -0500
-
- Tag headius's new to_proc spec as failing
-
-commit b1caeeac673451a960917bb699a20e74cf488432
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Mar 2 13:30:35 2008 +0100
-
- Adjusted Kernel#catch test a bit, to make it more generic.
-
-commit 60f9544ade9d6e71fe3e423ab82cc87838478032
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Sun Mar 2 04:36:53 2008 -0600
-
- Add a spec for #363, & not coercing using to_proc.
-
-commit 70aa320f7f5bc75ed95362b0fb6d724e64224a88
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Mar 1 17:17:55 2008 -0500
-
- Tweak new Marshal spec to pass on MatzRuby
-
-commit 35476e1bde23de26c01df409b750e91ef981fefc
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Mar 1 17:11:53 2008 -0500
-
- Tag new failing Marshal spec
-
-commit d9f83819f1ed2505740ae0737199fecab29809bb
-Author: Jared Luxenberg <jared@jaredlux.com>
-Date: Sat Mar 1 16:20:18 2008 -0500
-
- Added specs for marshalling subclasses of Hash with init parameters
-
- Test that Marshal.dump gives correct output for such an object (passes)
- Test that Marshal.load is able to deal such an object (fails)
-
-commit 6039a3bd457c5d3dc99f5935999da574d17f1e5d
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Mar 1 16:20:08 2008 -0500
-
- Tweak Process.setrlimit spec for odd Linux platforms
-
-commit 25cfa6a96315ee203d06381ee3ddb76b60023360
-Author: Chuck Remes <cremes.devlist@mac.com>
-Date: Sat Mar 1 10:24:55 2008 -0600
-
- Fixes a race condition on OSX when "find"-ing character devices
-
- - on OSX the spec fixture would return /dev/fd/0 as a character
- device when run from the command line. This always succeeded.
- When run as a subprocess (like from cron or rubuildius'
- IO#popen) then OSX uses /dev/fd/0 and /dev/fd/2 for capturing
- stdin, stdout, stderr and others in that environment. While
- the fixture would "find" /dev/fd/2 as a character device, by
- the time the assertion tested it the underlying OS would change
- it to another device type causing the assertion to fail. This
- is just bad luck. We now grab the #last device found rather
- than the first.
-
-commit b6e95321df023ac989c4e5bb926ec55493260bc9
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 29 16:04:10 2008 +0100
-
- New rubyspecs for IO#ungetc.
-
-commit 9bd2f0740c71d426cfa3c3636c2451762f640c14
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Feb 28 21:59:35 2008 -0800
-
- Specs for Hash.allocate. Fix awaits replacing Hash with LookupTable in core.
-
-commit c1d979639bfc19072351211815ffd5c8da772dcd
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Feb 28 21:56:33 2008 -0800
-
- Specs and fixes for Module.allocate.
-
-commit 904fd6136f00bab5fec62e8e702a0508dec44bac
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Feb 28 19:45:39 2008 -0800
-
- Specs and fixes for Array.allocate.
-
-commit 776a24f0d14bbb5127c804cf0579960335c1a049
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Feb 28 19:35:55 2008 -0800
-
- Specs for String.allocate and fixes to make them pass.
-
-commit fa35211f357ff1b9660a318c12b86ca156c5f26d
-Author: Ari Brown <ari@aribrown.com>
-Date: Thu Feb 28 20:27:55 2008 -0500
-
- Moved stdlib/syslog.rb to lib/syslog.rb . it works!
-
- * everything runs! yay!
-
-commit 8f103a6f9d7a168e37d1063e40bee960d64fc609
-Author: Ari Brown <ari@aribrown.com>
-Date: Thu Feb 28 19:42:11 2008 -0500
-
- Added specs and the constant module for stdlib/syslog.rb
-
- * added some specs for that which is testable
- * fixed the constant module so the constants are defined
- * fixed 'undefined method' problem in #write (private)
-
-commit 0c89dc90fdcb7933169e23462197d59f9627f510
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Feb 28 14:31:05 2008 -0800
-
- Added basic throw/catch specs. Fixed raised NameError to contain the name
-
-commit c8f4db4270984b60a087dd423c9e0da3e3760622
-Author: Phil Hagelberg <phil@hagelb.org>
-Date: Thu Feb 28 14:11:30 2008 -0800
-
- tag failing proc spec
-
-commit a1591319696385191f3301516d2f8265cd8fedcb
-Merge: f167f8f... 3f1acce...
-Author: Phil Hagelberg <phil@hagelb.org>
-Date: Thu Feb 28 13:43:52 2008 -0800
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit f167f8f6f7f3a1b8804a5452643236a23c0ce4c4
-Author: Phil Hagelberg <phil@hagelb.org>
-Date: Thu Feb 28 13:43:40 2008 -0800
-
- failing spec for returning from procs
-
-commit 3f1acce781c0dcf43698441036a085a0cef02d29
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Feb 28 16:14:55 2008 -0500
-
- Basic support for UNIXSocket and UNIXServer
- Fix some 'Errno' typos in socket.rb
-
-commit afbf38613364436630933753d99ee94c03b85074
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Feb 28 21:34:10 2008 +0100
-
- Added specs for File.fnmatch with case-sensitive brackets.
-
-commit 28323bda3d1f3295371b6ea99ed8ba6ee15661bb
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Feb 28 20:47:51 2008 +0100
-
- Added specs for File.fnmatch with '**/' patterns.
-
-commit 893ff4729d024198d5b423cc4426153f49cb5ebe
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Feb 28 11:30:49 2008 -0800
-
- Fixed lookup of class variables defined in metaclasses.
-
-commit dee531b18d96199d608d8e2e8e27f54ef500a716
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 27 21:47:13 2008 -0800
-
- Additional Symbol#inspect specs. Another try at making them pass.
-
-commit 3bfb705b709ab35593684a68b35fb0ee8e1e01d7
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 27 21:46:37 2008 -0800
-
- Silence 'woot' echo on ubuntu from #system specs.
-
-commit 7fb76f2c4a9fb0c5695a38b90150ea6f50097237
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Wed Feb 27 18:05:48 2008 -0800
-
- Fixed Symbol#inspect from over quoting
-
-commit 4ac32e4c9d0ff55aad50a00944f1a64931cfd1c6
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Wed Feb 27 17:18:09 2008 -0800
-
- Added some pretty rude specs for Kernel#system and got them to pass.
- Fixed a wierd problem with system/exec not cleaning up the fork process right
-
-commit 73be3b88af1ac96a6d4afabddd2871cfc4691eec
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 27 15:36:17 2008 -0800
-
- Fix String to properly initialize backing store when subclassed.
-
-commit 5ab2f9e594b7e66a04028e60f3517488e345f508
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 27 15:04:09 2008 -0800
-
- Scope classes used in String specs.
-
-commit e45d58100850443fedada905f654bae3f4144790
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Wed Feb 27 17:04:58 2008 -0600
-
- Add /devices to find commands; Solaris uses /devices instead of /dev.
-
-commit 1403477197873d613cfb93d644f78b4067d180d3
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 27 20:21:48 2008 +0100
-
- Adjusted Env spec, to be able to run it on Solaris.
-
- grep is replaced by egrep, since older greps don't
- take -e parameter (like on Solaris).
-
-commit b239a3b615d341f982a7a4a3a1b1200d95f79684
-Author: Adam Shelly <adam.shelly@gmail.com>
-Date: Wed Feb 27 04:09:24 2008 -0500
-
- Amending specs for Array#pack('U')
-
- * rbx is now passing most specs
- * failing specs are due to String#unpack.
-
- Signed-off-by: Brian Ford <bford@engineyard.com>
-
-commit 328c40e0f24601e739f404ab252652deca477513
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 27 02:46:21 2008 -0800
-
- Fixed Array instantiation to work with subclasses.
-
-commit 96c4ea885fbd075765b9d234de2754df3c857b07
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Feb 27 09:26:25 2008 +1100
-
- Move Debugger::Output specs to match new location of class
-
-commit c59f16f34f47860b200c6de4a2c1144c566de3dd
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Feb 26 10:23:14 2008 -0800
-
- Exclude new failing Array specs.
-
-commit 27248a45f079fd5a8cdb9ee71d008d135dcbe63d
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Tue Feb 26 00:10:29 2008 -0600
-
- Add additional Array tests from BFTS.
-
-commit a0e156f4c5bc12bf39950afeb58a6962b37efaa7
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Feb 26 16:53:01 2008 +1100
-
- Fix Debugger help output formatting to use wrapping
-
-commit fa5304d42c72a07b09cece99cb22c90f6b399a51
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Feb 26 13:22:31 2008 +1100
-
- Add wrapping to debugger column output
-
-commit 1a5d830b41eef37bb78168c959dd5b2f0757fde4
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 25 18:58:11 2008 -0800
-
- Conform Bignum#div, #divmod to weird MRI maths.
-
-commit eb5c6e367990bfdd193bcdf3055009f3e3e1aeaf
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Feb 26 13:23:29 2008 +1100
-
- Fix Debugger specs to pass on ci
-
-commit a2feff6782a052a9b71da90e9d4e1b2d991cc598
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Feb 25 18:53:24 2008 -0500
-
- Patch by Jos Backus (josb) - Closes ticket 364 (FreeBSD warnings)
-
-commit cee08883cc3de2e41a88b506f7d7f8d40697eaa2
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Mon Feb 25 13:20:21 2008 -0800
-
- Fixed autotest churn by removing empty.txt and moving to /tmp
-
-commit f26bb0c4e3b8435a853a9f4843173748d98075fd
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 25 11:25:10 2008 -0800
-
- Add the rest of spec/* directories to CI process.
-
-commit 29f36833e79de6115c27d744adf158e1b3ba42f0
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 25 00:29:45 2008 -0800
-
- Excludes for spec/kernel, spec/debugger to run with CI.
-
-commit 12bbdf70af31d5168c2df0a9b53651f94b36899d
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 25 00:22:13 2008 -0800
-
- Excludes for subtend specs so they will run with CI.
-
-commit 0cbc2b1f20d8aee7ea74eb14e1f9cf242f8b47d5
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 24 23:57:56 2008 -0800
-
- Remove specs for removed Compression::ZLib.
-
-commit 1b4fbc76c2eb84e5cb45562f54ac105784f9e134
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 24 23:49:57 2008 -0800
-
- Conform Ar specs.
-
-commit f8e62002711c3cfd8024faca497775f7253a326a
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Mon Feb 25 05:24:54 2008 +0100
-
- Add a second case for truncating IO buffers that specifies too-small size.
-
-commit 9f3e25289cc52cd3f3fb240de1ad82a16a8b135c
-Author: Nikolai Lugovoi <meadow.nnick@gmail.com>
-Date: Tue Feb 12 23:19:27 2008 +0200
-
- Fixes for String#to_sub_replacement:
-
- * removed String#replace_slashes
- * using plain byte-by-byte scan instead of regexps to detect and handle backslash escapes
- * better handle unknown escapes and cases like '\\\1'
- * updated specs for String#sub
-
- Signed-off-by: Brian Ford <bford@engineyard.com>
-
-commit d87df0b7634ae37f85fc8f2795e4c8c425614b11
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Mon Feb 25 02:57:27 2008 +0100
-
- Add a spec for Enumerable#inject with a *arg; JRUBY-2162 exposed it.
-
-commit f04fcabf8c064dfcbf3b118bdc83289da169a30c
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Feb 24 21:24:51 2008 +0100
-
- truncate behaves different on OpenBSD, changed specs according to MRI behavior
-
-commit b74a2f45b32a02469d61d4ace04912ec25f19543
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Feb 24 20:18:02 2008 +0100
-
- Looks like Darwin does provide Process::RLIMIT_AS
-
-commit 7113973abff64eeb1304b15be46f07d301d84f3f
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Feb 24 18:25:55 2008 +0100
-
- OpenBSD doesn't provide Process::RLIMIT_AS, so this spec should be excluded
-
-commit 49b72719bf5c732f4aa2ad0d70e5a224556fb471
-Author: oleg dashevskii <be9@be9.ru>
-Date: Sun Feb 24 11:04:07 2008 +0600
-
- Spec for method taking lambda and block.
-
- * should raise SyntaxError
- * passes on MRI
- * fails on rubinius
-
- Signed-off-by: oleg dashevskii <be9@be9.ru>
-
-commit 60bbc8506d70571249972dbf124df520f0a4a476
-Author: Chuck Remes <cremes.devlist@mac.com>
-Date: Sat Feb 23 10:23:09 2008 -0600
-
- Fix unpack_spec expectation for little-endian byte ordering
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 17e45cee97057684e6c24608f97de48c28947384
-Author: Chuck Remes <cremes.devlist@mac.com>
-Date: Sat Feb 23 09:44:37 2008 -0600
-
- Fix unpack to use native host byte order for formats /ILQS/
-
- - unpack_spec had a bad expectation on little-endian platforms
- - unpack_spec got some updated description strings to correctly identify
- the host byte ordering expected in the spec
- - kernel/core/string.rb now unpacks formats /ILQS/ in the platform's native byte
- ordering
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 1540cb7caa0f200ed6d318971fb7302cd089e27d
-Author: Chuck Remes <cremes.devlist@mac.com>
-Date: Sat Feb 23 08:10:00 2008 -0600
-
- Add some missing endian guards to the unpack_spec
-
- - in my haste, forgot one set of guards around some specs
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 8488676fc0dac5db5d01dd92e061476226d58bd1
-Author: Chuck Remes <cremes.devlist@mac.com>
-Date: Sat Feb 23 00:19:33 2008 -0600
-
- Fix several Array#pack and String#unpack bugs related to byte ordering (endiannes)
-
- - added a small utility method endian? to the kernel module; determines host byte
- ordering by taking a symbol (:big, :little) and comparing it to Rubinius::ENDIAN
- - modified Array#pack to check for the native byte ordering for /ils/i formats
- - modified String#unpack to use native byte ordering for /DdFfIiLlQqSs/ formats
- - modified String#extract_number to do special processing for big-endian platforms
- and for formats using native byte ordering on a big-endian platform
- - added little_endian and big_endian guards around several String#unpack specs;
- now passes running against MRI and rbx
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit f8146d29bfdf67349f3f9c0c7105ce595981255f
-Author: Gianluigi Spagnuolo <glgspg@gmail.com>
-Date: Sat Feb 23 12:44:25 2008 +0100
-
- Added some test to Regexp.quote to manage tab and white space
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 714efa8574687e1fd31f904a4f35cce8056719f5
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Feb 23 00:01:38 2008 -0800
-
- Fixed Digest specs to pass with RSpec.
-
-commit a0fe2f7fa080729b77b32ffe21be5705a162ed71
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 22 22:26:52 2008 -0800
-
- Remove ffi_decode_sockaddr, replace with existing ruby code.
-
-commit b2baf0911e4a88ba2f6c4cb8e3e31d2a3aa1c6bf
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 22 17:06:18 2008 -0800
-
- Move Ar to kernel/core.
-
-commit 01baf002a8c7bd6e249b9477c1f78e6b99a67bf6
-Author: Philipp Bruschweiler <blei42@gmail.com>
-Date: Wed Jan 16 00:11:12 2008 +0100
-
- added specs for SHA256/384/512
-
- these specs were as well shamelessly copied from the md5 specs.
- they work, but every sha* class has a folder for itsself, that's a
- lot of duplicatd code. maybe someone with more experience in
- writing specs should have a look at this.
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 924224fcf655da90148ebd8234033a71e1b23090
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Fri Feb 22 17:13:14 2008 -0500
-
- Catch no block given in rb_yield, raise LocalJumpError
-
- As well, define that as an exception for subtend
-
- Update spec
-
-commit 3748843421832df5b842a677ddd2e55fbefb0b5f
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Fri Feb 22 17:04:33 2008 -0500
-
- Update rb_yield spec
-
-commit f60ca442b1466f29432995700457e8b34f4ff294
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Fri Feb 22 17:00:36 2008 -0500
-
- Fix rb_yield call
-
-commit a75afc4595fd20d7853ff65afe015de88b265b93
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Fri Feb 22 16:48:17 2008 -0500
-
- Add blocks to subtend methods, as they should be able to access them like any other method.
-
- Also, update the spec
-
-commit d9911f8b00243f3c95759612dde35edf6edaa678
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Thu Jan 31 13:54:24 2008 -0500
-
- Add block specs and rb_block_given_p
-
-commit b6c806f0d8213c4751c69638174f60b80f9ba303
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Feb 22 15:31:58 2008 -0500
-
- Failing spec and exclude for left-to-right masgn evaluation order
-
-commit 8f9e3c9e5e7dfc535e8fe6b10b945587586651ec
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Feb 22 13:59:44 2008 +0100
-
- Fix Socket#getservbyname, not every platform defines http/udp
-
-commit f29ff3bcaf0bf83d2924d08ea5f6c0bbb5df9948
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Thu Feb 21 16:47:02 2008 -0800
-
- Allow Ar to create archives
-
-commit e50ec6470dfc905198065a98b65b33a99da60e15
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Feb 21 20:20:41 2008 -0500
-
- Some compiler specs for 'defined?' handling
-
-commit ba5a0d87182d83000205e1202f5c473568a50489
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Feb 22 01:08:51 2008 +0100
-
- Fixed #332 and cleaned up Time a bit. Thanks to gls
-
-commit edf1e0d530ebb39a1b46d0fa518b9ca85db544da
-Author: Evan Phoenix <ephoenix@engineyard.com>
-Date: Thu Feb 21 02:01:21 2008 -0800
-
- Fix the last usage of block return (ie, internal long return).
-
- * LongReturnException is now used whenever a block requests that
- it's home context should return.
-
-commit 83ed7161701202d48490e7f38b568bc504f9690f
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 23:59:47 2008 -0800
-
- Added little/big_endian guards to Array#pack and String#unpack specs.
-
-commit 65b4ed86002371f2b56759aadc61e61c1cbbdba4
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Feb 20 22:49:19 2008 -0800
-
- Exclude Socket#unpack_sockaddr_in spec. See tag comment.
-
-commit 9fbda05c4dffb964a9f10e26d62240fbd52200a0
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Feb 20 22:48:31 2008 -0800
-
- Exclude super slow IPAddr specs.
-
-commit 3d39fb35dcd3c28fa626aeb96057b927c6bfe7c9
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 18:54:50 2008 -0800
-
- Redo expectation in Socket#getaddrinfo spec.
-
-commit 69576ede38d9bf09d1afd0120726ca756a0aa7cf
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 18:31:27 2008 -0800
-
- Account for variable length array in Socket#getaddrinfo.
-
-commit f396bd718572d9402d0d7eeb8da02474914396a8
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 17:59:29 2008 -0800
-
- Use File.delete in YAML specs instead of rm.
-
-commit 7698ec3855ce572f1e10962596804b82f3cd6534
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu Feb 14 10:07:48 2008 +1100
-
- Hook-up new StepBreakpoint to new debugger step commands
-
- * The commands step and stepi have now been added to the
- debugger, and step into called methods.
- * The commands next, nexti and out have been converted
- to use the new StepBreakpoint. The legacy versions
- remain, but have been renamed as ln, lni, and lo; these
- will be removed once the new commands have proven stable.
- * Replaced VM method cache command with VM send site command
- to show details of SendSites in the current method.
-
-commit f192d65ec5eb31b4a807b9c3eb7360b84739d9f2
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu Jan 31 16:43:19 2008 +1100
-
- Initial implementation of StepBreakpoint
-
- StepBreakpoint class moves step logic out of the Debugger
- and into breakpoint, where it more logically belongs.
-
-commit fd0ff43d2d384e221ff8de611843f3406d192657
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 17:04:46 2008 -0800
-
- Fixed YAML spec to pass MRI. Added fails tag for rbx.
-
-commit d69834a5217ddc6667b495fbe7d4dd8ad413ba88
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Feb 20 15:42:25 2008 -0500
-
- Fix dead code in TCPSocket.new specs
-
-commit 4644222e63046783933ca9b2e4514e3ff21fbb57
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 12:31:14 2008 -0800
-
- Add missing tag file for method_spec.
-
-commit 230d5d506f4203bcd3922880fae506fa480e6308
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 12:17:13 2008 -0800
-
- Fix typo in socket specs.
-
-commit a5d49537832a9cc33b07cade265af0834f123533
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 12:09:11 2008 -0800
-
- Move specs for calling methods to language/method_spec.rb.
-
-commit ead32a1f2820a4e2fcc906a8e7f3603490ba901c
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 11:53:45 2008 -0800
-
- Use bignum_value where a Bignum is intended in the specs.
-
-commit 1021345337bca1f928879713cb84a76b9c7935a1
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 10:21:42 2008 -0800
-
- Removed unused require 'stringio' from io/syswrite specs.
-
-commit cfd51af482321b4d672d69569de185f582a21831
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 09:00:36 2008 -0800
-
- Symbols as Fixnums is long deprecated. We don't spec it.
-
-commit a8bd2a1aba97653625a9b568d1a7112b5fce45f6
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 00:15:54 2008 -0800
-
- RbYAML is not in Ruby standard lib. Move specs for it to spec/library/rbyaml.
-
-commit 56b454af2ded18d0459bc974efa666ccf3b8de0f
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 20 00:10:24 2008 -0800
-
- Restrict specs in spec/ruby/1.8 to current stable 1.8 version.
-
-commit 22e01d1914db92d159ee15d3cf73c9d6e9d0a24b
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Feb 19 23:20:27 2008 -0800
-
- Fix Dir#pos=/#seek specs. We shouldn't spec undefined platform behavior.
-
-commit d522af83d0cfcdf39932afff7ba7d75d77dd0453
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 20 11:51:44 2008 +0100
-
- New IO.read specs.
-
-commit 77fdbe404e31f44e1c302eb99a7ff129523183ce
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Feb 19 16:14:43 2008 -0800
-
- Add library to read/write ar(5) files
-
-commit d7702f979732de90358dc35d795c6ac621f815bc
-Author: Matthijs Langenberg <mlangenberg@gmail.com>
-Date: Mon Feb 18 18:04:27 2008 +0100
-
- writen some examples for Base64 module
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 33b189478c05bd687ac8b062cd5307a3290d8931
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Feb 19 00:27:51 2008 -0800
-
- Convert platform guard :size option to :wordsize.
-
-commit cbcdb8346a2c75ba65910b486cee718cd3aa5175
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Feb 18 23:07:41 2008 -0800
-
- Exclude TCPSocket.new for now, hangs on ubuntu gutsy.
-
-commit ec990b6ebcd35cbf9dc192852f37e184c3e4079b
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Feb 19 15:55:25 2008 +1100
-
- Re-enable debug on context change
-
- The cpu_yield_debugger_check was not being performed as
- a result of changes to method dispatch related to the
- implementation of SendSite.
-
-commit aa585b7e637e2fd873602ee6725256429f413582
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 18 18:59:18 2008 -0800
-
- Removed :version guarded specs that are not current stable.
-
-commit 431af5920a0a02dfca927961a2d6457ae5f050e2
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 18 17:40:56 2008 -0800
-
- Added new tags files for excludes.
-
-commit 10dd37903533cac9a6f77ead70f3aa9ee1dc9098
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 18 16:38:58 2008 -0800
-
- Removed deprecated $deferr from getoptlong.rb. Moved to /lib.
-
- Small fixes to other library specs to get them running under CI.
-
-commit ee2dabf771a5e6d8d70c47fa49b1298d2d002c8c
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 18 00:42:54 2008 -0800
-
- Use the spec guards properly.
-
-commit 91d6c64be8827768ba2e39b80a4eb81b9affc122
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 17 22:40:21 2008 -0800
-
- Deprecate #setup, #teardown in specs; use #before, #after.
-
-commit 6ba49012504c08973e1fb2fd1b9fce75c351d148
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 17 22:00:56 2008 -0800
-
- The #fails_on guard has been removed. Use #ruby_bug or tagged excludes.
-
-commit e24231f5c62c0b73768c7503f50b53e8ffc345d1
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 17 21:08:01 2008 -0800
-
- Renamed *_excludes.txt to *_tags.txt for specs.
-
-commit a1c707b517e13115692173bc2048309e74c00915
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 17 20:45:14 2008 -0800
-
- Hand merge recent excludes changes to spec/tags directory.
-
-commit 838bee7e99bb1179c9a3a7782dcab9c2b904e72e
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 17 00:17:51 2008 -0800
-
- Moved excludes from spec/data to spec/tags. Added "fails" tags.
-
-commit 8ad91b03788d89ccd12fbcf19c06c9ef4f0cfee8
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 4 19:19:00 2008 -0800
-
- Misc fixes to get MSpec running specs.
-
-commit a683dd75786ab6c6a255c9bac399dc6be7aaa4b5
-Author: Tyler McMullen <tbmcmullen@gmail.com>
-Date: Sat Feb 16 23:39:38 2008 -0500
-
- Add support for H and h to Array#pack.
-
- * Updated array/pack_spec with specs for H and h, separately
- * Updated Array#pack to handle both with a single block of code
-
- Signed-off-by: Brian Ford <bford@engineyard.com>
-
-commit b1d3ba9d10f6a9ea87d8cb9be21d0d432e973117
-Author: oleg dashevskii <be9@be9.ru>
-Date: Mon Feb 18 01:18:24 2008 +0600
-
- Update specs for calling methods.
-
- Nasty binding stuff (first noted in #293) got specced and put into excludes.
-
-commit 02225daa5cef4fa3f48cac73d4bf0f9d02f3ebe0
-Author: oleg dashevskii <be9@be9.ru>
-Date: Sun Feb 17 23:20:08 2008 +0600
-
- Cross-breed and update for, while & until language specs. Little fix for hash spec.
-
- The compiler drops out on "for @@var in 1..3", so this is commented out.
- Variable scope stuff arrived into excludes.
-
-commit f43383a150131278d30535196e8da4e60dff97b1
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Feb 17 13:10:55 2008 +0100
-
- New specs for RangeExceptions out of Fixnum and Array methods.
-
-commit 7d1c744d9c1ae50376be406a28e383a04ca6b4fc
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Feb 16 13:49:11 2008 +0100
-
- Corrected copy-paste error in recent fixnum specs.
-
-commit 08982321472008f7645212289d2624d19053ed7e
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 15 21:18:53 2008 -0800
-
- Fix IO#read for large files and small parts of files.
-
- Fix IO#read with buffer.
-
- Fix IO#eof? when buffer reaches eof.
-
-commit 1d07588d61b3835a6165c5de1f731277812cff79
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 15 19:11:42 2008 -0800
-
- Add missing spec for IO#eof? and fix.
-
-commit e0a6c8e179e48b423b6eb142b27460cd86d0223b
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 15 17:50:47 2008 -0800
-
- (Last change was ok). Force check for data so #eof? works
-
-commit d7e67c257c213f9e25b3123ce85576feb71a0089
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 15 17:28:48 2008 -0800
-
- Revert "Force a check for more data on the IO for IO#eof?"
-
- This reverts commit 3d4427e802756678608bf9840ba6f26fc81cf7fe.
-
-commit 4c1182c184bb6c2c97c5fc8ce83f242fe5f5144b
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 15 17:26:08 2008 -0800
-
- Force a check for more data on the IO for IO#eof?
-
-commit 94466db3347889850feb25dd7c83883df21bac92
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Feb 15 14:13:29 2008 -0800
-
- Added Float examples to Bignum bitwise operator specs.
-
-commit 3a668451d3bcc46b162a69ce1f8ec5d6a98b2d22
-Author: Brian Ford <bford@engineyard.com>
-Date: Fri Feb 15 13:44:24 2008 -0800
-
- Added bignum_value helper. Added specs for Fixnum bitwise operators.
-
-commit 217eb67a4c2f0bf1222628abfecfadbede5fb3b8
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Feb 15 21:09:43 2008 +0100
-
- Fix process specs for FreeBSD
-
-commit f25e0e130110ebbef0b5bc0c28c9b08db6c73a1f
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Feb 15 13:18:40 2008 +0100
-
- Removed now working exclude for Array#sort
-
-commit 56af7be26dcc9b7270de6d96e73e09a4f17cc710
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Feb 14 20:48:37 2008 -0500
-
- Improved Array#sort, #sort! specs.
-
-commit 714ea4b5245172cc6d5c815ef7399d1a991dd83f
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Feb 13 10:30:22 2008 -0500
-
- Improved Array#sort specs a bit.
-
-commit 8944e873848c610182405c2de466e41e6260573d
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Feb 13 02:34:37 2008 -0500
-
- Tuple#swap specs.
-
-commit 24199f731dba40b72af6d121121dec9f085f890d
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Feb 14 20:03:16 2008 +0100
-
- New rubyspecs for IO#reopen.
-
-commit 4f70320e5b7089c74b3899216763cd37d8854230
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Feb 14 17:27:32 2008 +0100
-
- Removed JRuby-specific guards. Please don't use guards to hide bugs.
-
- Guards to be used only when it is agreed that the JRuby behavior
- is intentionally differs from MRI. For plain bugs, guards should
- not be used. Instead, we maintain spec exclusions in JRuby repository.
-
-commit 0198a11b3bdf60983846a6c722dfa11d1b9f57bb
-Merge: ef3393e... 1f1e32e...
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 15:57:57 2008 +0100
-
- Merge branch 'mutle_file_specs_refactoring'
-
-commit 1f1e32e5e1fd12fb323e2a74a7f5caae96aa867b
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 15:18:14 2008 +0100
-
- Specs for File#chown #flock and #truncate now pass on JRuby
-
-commit 3a8e601d5205e050f83179376d2be3e922e80c20
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu Feb 14 17:25:02 2008 +1100
-
- Fix context specs to wait for debug listener thread
-
-commit 608d7a99e75d293d6f9786cee940c0dd23156be3
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 12:59:32 2008 +0100
-
- Adding guards to only run File#chown and File.chown specs as root.
-
-commit b3a1069cf6c18b844b9eced32b7bcdb91ad7c558
-Author: Brian Ford <bford@engineyard.com>
-Date: Thu Feb 14 01:31:47 2008 -0800
-
- Rework Bignum#==. Change Numeric#== to conform to MRI.
-
-commit 4eb58ebc45b2ee79f01d75fdb3e9104c73ad66e2
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Wed Feb 13 23:56:37 2008 -0800
-
- Common implementation for Zlib::Inflate and Zlib::Deflate.
-
-commit 1804fdacce5c195a90befe502706d1f1e066e886
-Author: Brian Ford <bford@engineyard.com>
-Date: Wed Feb 13 19:31:20 2008 -0800
-
- Port of JRuby's File.fnmatch to Ruby (yeah, like writing Java in Ruby).
-
-commit 1a78da8438535ee8ed231359bdb15ff3624c6b37
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 01:27:52 2008 +0100
-
- Adding File#truncate improvements from #325 and #326
-
-commit 5b62acbdcf0aab2e89be5ac3e12859ae36cd6950
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 00:47:53 2008 +0100
-
- Adding File#truncate with specs
-
-commit 1a2b3dde4f67abe0936e7ec6fb749e5bb8fda7d2
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 00:36:32 2008 +0100
-
- Adding File#chown with specs
-
-commit e132cd6f11285f0e106a5d2a292e23c8375fa1ee
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 00:12:31 2008 +0100
-
- Renamed File#flock spec to properly reflect an instance method
-
-commit 00cd22ccdf2b70fa53693000d4a5bb803c7d6df6
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Thu Feb 14 00:07:05 2008 +0100
-
- Adding File::flock with specs
-
-commit 3c9b3e4e4272889dd26ec9ddb25f7aaf88c6c380
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Wed Feb 13 23:25:30 2008 +0100
-
- Adding File::chown with specs
-
- * The spec works fine on OS X, but was not tested anywhere else
-
-commit c894a6c46b4a3d0b9010020c394d3ba366bf145e
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Feb 13 11:59:38 2008 +0100
-
- Module#undef_method should accept string parameter, not only symbols by Nikolai Lugovoi (#321)
-
-commit c968d5c29cc3126c789cf5bb2005bd9637e85312
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Feb 13 11:52:10 2008 +0100
-
- Update excludes for File#truncate
-
-commit 408e69864546aea061e006073bb452b8db8c4610
-Author: Ragnar Dahlén <r.dahlen@gmail.com>
-Date: Wed Feb 13 11:15:31 2008 +0100
-
- Implement File.truncate, passes specs.
-
- * Adds truncate, ftruncate (not used yet) to posix.rb
-
- Only tested on Mac OS X 10.5.1.
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit 5c75721d5a78e25a77e9f068bf4c95e729604959
-Author: oleg dashevskii <be9@be9.ru>
-Date: Wed Feb 13 11:26:34 2008 +0600
-
- Remove tests that have been superseded by precedence_spec.
-
-commit 83a372674786a0be51a206cadcae644d72a1e8d2
-Author: oleg dashevskii <be9@be9.ru>
-Date: Wed Feb 13 11:05:34 2008 +0600
-
- Made a real precedence_spec.
-
- One test still commented out till the bug with flip2 is fixed.
-
-commit c3988a4a906594c050e058add8aa6996870dc115
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Feb 13 02:10:49 2008 +0100
-
- Remove excludes for File#stats specs
-
-commit 1624b463d0f70a27b6772d90626c94b6eed4e5c4
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Feb 12 18:25:05 2008 -0500
-
- Add specs for pass subclasses of Module to 'include'
-
-commit 64b0fb4131276feda0d0ab13301824b20f8d7f8e
-Author: oleg dashevskii <be9@be9.ru>
-Date: Wed Feb 13 00:49:37 2008 +0600
-
- Make Dir.chdir spec work when /home is symlinked to /usr/home.
-
-commit 8cbf6312df160f30e284a4537039f808a42543fe
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Feb 12 12:30:19 2008 -0500
-
- Add failing Array#sort spec and matching exclude
-
-commit 9bef807b3b469b8790edbe96f1442394d528cb5a
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Feb 12 12:09:11 2008 -0500
-
- Move Time#<=> specs around until the descriptions make sense
-
-commit 60fbbc62cb04b2fddcd406f01f906482fbc84370
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Feb 12 05:33:49 2008 +0100
-
- Mark JRuby as not deviating from MRI on unboundmethod specs.
-
-commit 4e6d8f7e3326f937a6916ed11984172670a71094
-Author: Yehuda Katz <ephoenix@engineyard.com>
-Date: Mon Feb 11 23:26:31 2008 -0800
-
- Zlib.adler32
-
-commit 2f2d10e1aa57bae79f7fcda5e5a30b2a2ef3e37c
-Author: Yehuda Katz <ephoenix@engineyard.com>
-Date: Mon Feb 11 23:12:40 2008 -0800
-
- Zlib.crc_table
-
-commit 49b9e4b624074d151e89f078c4080a0a7584abaa
-Author: Yehuda Katz <ephoenix@engineyard.com>
-Date: Mon Feb 11 22:56:52 2008 -0800
-
- Zlib#crc32
-
-commit 7cb2ebfa008afc96135912ceefdbd81b1cd7e478
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Mon Feb 11 17:36:32 2008 -0800
-
- Fix class variables for RDoc.
-
-commit 571d837bbeff221daacebc79c1ccab7de15c77f2
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Feb 11 08:54:36 2008 -0800
-
- Exclude [r]dev_(major|minor) specs. We need some autoconf facilities.
-
-commit fb2bc81d50bf504e3997d009e3c13f841b859803
-Merge: 55a52f1... 9b58a59...
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Mon Feb 11 16:19:02 2008 +0100
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 55a52f18133fc9f92eef64838008a83dfaab3ffc
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Mon Feb 11 16:18:37 2008 +0100
-
- Removed Math.asinh excludes.
-
- It wasn't working on OS X. Evan fixed the culprit FFI over the weekend.
-
-commit 9b58a59ca21c6622d246e629410230bfbe8cd4ce
-Author: makoto kuwata <kwa@kuwata-lab.com>
-Date: Mon Feb 11 21:24:05 2008 +0900
-
- Modified to address differences of SyntaxError class between MRI and Rubinius in 'erb/filename_spec.rb'
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit d1c4280b70b82d6cd541251e3d7e1a3091fb304f
-Author: makoto kuwata <kwa@kuwata-lab.com>
-Date: Mon Feb 11 20:19:12 2008 +0900
-
- Add 'erb/util/shared/url_encode.rb' which is missed file
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit b4b1114ac7dffabd672d462b5857a7e1957e8f07
-Author: makoto kuwata <kwa@kuwata-lab.com>
-Date: Mon Feb 11 19:10:58 2008 +0900
-
- Add spec files for erb.rb
-
- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
-
-commit dfdf90968e78f14e0755b5f3279ec878034dbdb5
-Author: Yehuda Katz <ephoenix@engineyard.com>
-Date: Mon Feb 11 00:09:23 2008 -0800
-
- Added singleton specs (and reorganized stale one):
- * Singleton#_dump
- * Singleton._load
- * Singleton#instance
- * Singleton.instantiate?
- * Singleton.new and Singleton.allocate
- * Singleton#dup and Singleton#clone
-
-commit 54c4a4cab187be4328d6a810bae4bc4bd01ca1d8
-Author: Brian Ford <bford@engineyard.com>
-Date: Sun Feb 10 20:19:30 2008 -0800
-
- Additional specs for File::Stat#rdev, #rdev_major, #rdev_minor.
-
-commit 6b2f05af4758c488b3e2e3b19ee9d2e872817932
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Feb 10 23:00:41 2008 -0500
-
- Rubinius now passes all 'super' specs
-
-commit 5be84fce241c67bd8439bccbe54cec575b0ea93a
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Feb 10 22:53:11 2008 -0500
-
- Failing spec for 'super' behavior
-
-commit 975d51e80d3df437eaa8ddd3c3384a5766255b12
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Feb 9 15:18:37 2008 -0800
-
- Exclude Process constants spec until LFS is fixed on 32bit linux.
-
-commit 236def62bcfa3dca75a6eebf378a68235c4613ed
-Author: Yehuda Katz <ephoenix@engineyard.com>
-Date: Sat Feb 9 17:04:59 2008 -0500
-
- Fixes exclude
-
-commit 26bedb481b45e77434b487c6395903c6110ef99e
-Author: Yehuda Katz <ephoenix@engineyard.com>
-Date: Sat Feb 9 16:01:58 2008 -0500
-
- Moved bad variables spec out
-
-commit 87efbf9036e5c524e1b40481c89107538d574ba8
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Feb 9 11:26:30 2008 -0800
-
- Revert all File::Stat stuff. We'll fix Dir first.
-
-commit 1f5bc0f98a23fc90b9bd00048af1551df8e534f7
-Author: Brian Ford <bford@engineyard.com>
-Date: Sat Feb 9 00:39:20 2008 -0800
-
- Reduced File::Stat.stat primitive further. Details follow.
-
- * Added ffi_major and ffi_minor to calculate the major, minor
- parts of st_dev and st_rdev.
- * Added (temporary) new primitive basic_stat to change the
- return type from a tuple to a single MemoryPointer instance.
- * Added simple specs for rdev, rdev_major, rdev_minor, nlink.
-
-commit e478731a2fc558c62cecbe327c5b35882d90b53d
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 8 16:45:05 2008 +0100
-
- One more rubyspec for File#open.
-
-commit 5f6ac709500cb64df110a44d31e0c0b89dd68aec
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 8 16:39:47 2008 +0100
-
- New rubyspecs for File#umask.
-
-commit fddaa684bd7e8c403ff96179ca71a5837f609b63
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 8 16:30:20 2008 +0100
-
- New File#chmod rubyspecs.
-
-commit ed20c3f9f36f343a37e2ac05ea91d84b54c87bc8
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Feb 8 12:00:57 2008 -0500
-
- Correctly guard Bignum specs for CI
-
-commit 36e9749984d6e4412c26d348afa8c501cf043ecf
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 8 13:09:37 2008 +0100
-
- Some more specs for File#new and File#open, and permissions.
-
-commit 29376695550c5608f466d63d49de76a6ee163e37
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 8 12:10:27 2008 +0100
-
- New specs for IO#new and IO#open, invoked with permissions parameter..
-
-commit 8cf27fcd86f88b75716b65dc1d94b721c01c3af9
-Author: oleg dashevskii <be9@be9.ru>
-Date: Fri Feb 1 21:03:08 2008 +0600
-
- Heredocs and more stuff added to string_spec.
-
-commit 2cccd38a081c0303f8fa567058e4c26fa354abc5
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Feb 8 12:51:53 2008 +0100
-
- Add exclude for currently failing for_spec
-
-commit 031bb1b565a3446ab995ea55e6ae8890573ba6c0
-Author: oleg dashevskii <be9@be9.ru>
-Date: Fri Feb 1 20:23:56 2008 +0600
-
- Added more tests to for expression spec.
-
-commit 73e40331c6b4c1c1b6e41ae312299f6815e089c2
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Feb 7 19:12:46 2008 -0500
-
- Add a failing spec for Array#join and then fix it
-
-commit fa49548fe704252c352a1bc4833b5da20262061a
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Feb 7 23:12:03 2008 +0100
-
- Fix last two Failing Time specs for Time#+ and Time#-
-
-commit e4e51c6aa39e5a5a61b0df919ba02b88d4878f43
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Feb 7 22:35:57 2008 +0100
-
- Fix Time.at so it also works with floats
-
-commit f5505522fd0396c3864fce155681ac577bf2e7e6
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Feb 7 17:10:48 2008 +0100
-
- Fix Time#<=> for objects other than Time
-
-commit e8ab7b5eb30da84262a9395e20ac420e83674edf
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Wed Feb 6 13:59:18 2008 -0800
-
- Only call Class#inherited once
-
-commit dc9ff28ae919292287f5562b8c105ff6310c5920
-Author: Phil Hagelberg <phil@hagelb.org>
-Date: Wed Feb 6 15:00:59 2008 -0800
-
- Kernel#eval should be a module function
-
- Added a spec as well
-
-commit 7dd83410a2159fd65f951689a8a1297baded4fa6
-Merge: 698ffa4... 339fed9...
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Wed Feb 6 22:54:12 2008 +0100
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 698ffa4e04fee58da5c3f2191372c4e4f2bc070d
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Wed Feb 6 22:51:54 2008 +0100
-
- Adding missing specs for ftools
-
- * specs for chmod, compare, copy, install, makedirs, move and safe_unlink
-
-commit 339fed9821b75de056febc406b32fe52ff9354a9
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Feb 6 22:00:46 2008 +0100
-
- Forgot to remove spec excludes...
-
-commit 7ecca7222823a82252ed09b17eefafe6fec9f12e
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Feb 6 21:46:19 2008 +0100
-
- Fix last two failing Dir#glob specs
-
-commit fec39f27d287ca74becbecc120de8533e346b864
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 18:13:13 2008 +0100
-
- A few more corner cases fo IO#lineno specs.
-
-commit 3691d3f9a202abb22e11024e41b868d531a549be
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 18:02:50 2008 +0100
-
- New rubyspecs for IO#lineno.
-
-commit a5b0f9aa15c9372f74816e77073926780a9cc219
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 15:58:26 2008 +0100
-
- Improved IO#foreach specs.
-
-commit 91ea9f304c75592e7454411ef21391a0e34da5e5
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 15:03:02 2008 +0100
-
- New rubyspecs for IO#gets and IO#foreach.
-
-commit 9c494786fbf400bb295e1f19d142e2c903c21e54
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 13:37:43 2008 +0100
-
- New rubyspecs for IO#foreach.
-
-commit cdbbeba8f3351fe43f44d732348f380599ad5719
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 10:40:13 2008 +0100
-
- New rubyspecs for IO's sysread and read with buffer argument.
-
-commit e1cb4410b7e0a0ba2fd580784334bdfd05ba4b8a
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 10:15:29 2008 +0100
-
- Excluded rbx failure after spec rename.
-
-commit 1fde018b9378b55f6d51cb85bd65813b5cef5493
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Wed Feb 6 02:50:44 2008 -0600
-
- Tidy up an apparent copy/paste mistake in IO#syswrite spec
-
-commit 1aa624e625dafaeebd70eac11819f02ecf570f8e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Feb 6 00:19:39 2008 +0100
-
- New IO specs for writing non-string data.
-
-commit f94a0cffd5fd0e186a9403d97800b55f8c44bdd1
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Feb 5 15:13:47 2008 -0800
-
- Regenerate zlib stubs.
-
-commit 52ce0e702170676ce02dcc288305097d58834cf8
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Feb 5 13:34:47 2008 -0800
-
- Add Zlib spec stubs
-
-commit b24ad594837b974a3ae3b207d63ce5cdc956a1a0
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Feb 5 21:45:09 2008 +0100
-
- Added some boundary test cases for Float.
-
-commit 1a8c9966fa148fc3e912f8aecd42c8c00ca4f89c
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Feb 5 22:46:18 2008 +0100
-
- Removed problematic Marshal spec because 2**40 is a Bignum on some archs and a Fixnum on others
-
-commit 6ad8a0a25f20fd137bcb7fcb83bc88440a2a2069
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Feb 5 17:03:56 2008 +0100
-
- Eliminated file descriptors leakage out of IO tests.
-
- These things make runs unpredictable, causing all kinds
- of troubles (non-deterministic failures, fluctating
- number of tests).
-
-commit 95ac3cb9900c52e4819b37166c71840d4bb4e3d9
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Feb 5 14:50:31 2008 +0100
-
- New rubyspecs for File.open with block.
-
- Also, IO.open specs improved to handle closing better.
-
-commit 66f636c346a63853ae37a06f1c3e8b5083370892
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Feb 5 13:22:34 2008 +0100
-
- New tests for IO.open, and additional cases for IO's inspect and stat.
-
-commit dfb941da0f7503bce58dc88a85ccfd201615e13b
-Author: Brian Ford <bford@engineyard.com>
-Date: Tue Feb 5 01:57:20 2008 -0800
-
- Ezra's patch for Regexp#inspect, #309.
-
-commit c5f9381ee74ed2d9c91cca1dd2ce9719b6f51bd8
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Feb 5 10:07:57 2008 +0100
-
- Corrected IO test to not interfere with Kernel#puts tests.
-
-commit 751293c1ea14de1b1d2757bf5d60b082cc771e7a
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Mon Feb 4 17:43:06 2008 -0800
-
- removed empty excludes
-
-commit 206399aee9ae7845d76c0726702c424b9fc44e80
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Mon Feb 4 17:39:45 2008 -0800
-
- StringIO#seek now raises if passed bignum offset - should be platform specific, but this'll do for now
-
-commit b00f04ec0fcd8f8edf9943abb5999f1cca9e9e9e
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Mon Feb 4 17:06:34 2008 -0800
-
- Knocked off the last of the method excludes.
- Tightened up the spec for #to_s
-
-commit 3d4f87741135343a2e8ec6032fa3a69529cfbf69
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Mon Feb 4 16:51:37 2008 -0800
-
- Fix Hash#key? to work with objects that have the same #hash.
-
-commit f814a15639f6e6ecd47ab99ad9e37e93fd6bc165
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Mon Feb 4 15:17:08 2008 -0800
-
- Fix Marshal format version check
-
-commit 6d9e0afb5600416e5d66d5123abcfa5dd6c40903
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Mon Feb 4 14:24:48 2008 -0800
-
- removed tmpfiles from dir/fixtures and moved them to tmp where they belong
-
-commit 4e18d1cf49573b1fa3f484686352734aa39457d0
-Author: Ruben Nine <ruben@leftbee.net>
-Date: Mon Feb 4 02:32:26 2008 +0100
-
- Added support for tag:yaml.org,2002:sym to RbYAML library.
-
- Signed-off-by: Jonas Pfenniger <zimbatm@oree.ch>
-
-commit 220ed05f204f4b8fe7f1f303fae9a18988f8879b
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Feb 4 17:16:44 2008 -0500
-
- Use an example number that is actually a Bignum everywhere in compiler Bignum spec
-
-commit db3f20c8ec905641de887bbd1ed581aa78f73471
-Merge: e33350e... 6e3dad3...
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Feb 4 16:50:14 2008 -0500
-
- Merge branch 'wilson64'
-
-commit 6e3dad3e5b2e982f96e991e9df2d46de5bf4ee1f
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Feb 4 16:49:09 2008 -0500
-
- Use the correct Fixnum#size spec on 64bit platforms
-
-commit e33350eddc3441b2ebe06336500e6445406285d1
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 22:12:14 2008 +0100
-
- Moved one IO#inspect spec to File#inspect specs.
-
- Since the behavior is File-specific.
-
-commit 1586e3a2c5d12f5438adddb8c84bc90c3defee82
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 20:57:09 2008 +0100
-
- Add more IO specs. God, make it stop!
-
-commit e64f3b02423acb783ba8a62996847b0393e7f3ee
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 20:33:57 2008 +0100
-
- And more IO specs.
-
-commit 3d584f0ee2cf988720bb5985c20b3bec6c2e143f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 20:08:26 2008 +0100
-
- Next batch of IO methods specs with closed streams.
-
-commit 6e22a99350195cfa7a40d6049d6d72a9ae7e1168
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 19:47:06 2008 +0100
-
- And yet more specs for IO methods with closed streams.
-
-commit 12e8d881b90cbd60bc792693e799923fdb1041b0
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 19:20:39 2008 +0100
-
- More rubysecs for IO methods invoked on closed streams.
-
- Plus some refactoring to move repetitive code to the fixture.
-
- NOTE: two specs marked as fails_on :rubinius due to fact
- that they crash rubinius.
-
-commit 3ae3cafcb10725953c8e595641af277f36c88677
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 18:39:34 2008 +0100
-
- New rubyspecs for IO#to_io.
-
-commit 4980bb83f53845e88cd0d1a3b0823fdbf0c0a001
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 18:09:36 2008 +0100
-
- New rubyspecs for IO#ungetc.
-
- Unfortunately, MRI doesn't follow some of its own
- specified behaviors...
-
-commit f27fe4f3e4ccb298dcaa5014dac69d3148ee169e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 17:18:08 2008 +0100
-
- Added rubyspecs for IO's putc, puts, printf, print and closed streams.
-
-commit a1d7b67942aed8d1b185476dee6f2d99403ed227
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 17:07:00 2008 +0100
-
- Added rubyspecs for IO#pid.
-
-commit cfa1ef21ce862a05ae352a4fe49a3ac4c04b9bed
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 16:36:21 2008 +0100
-
- Added new rubyspecs for IO#sync and IO#sync=.
-
-commit b4f6c33c17e57fa44322124af088a97d475905e2
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 16:20:50 2008 +0100
-
- New exclusions for rbx.
-
-commit 60309280c48b2bd1f1d8a5ea018f401e75b7dac1
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 16:17:27 2008 +0100
-
- Added new tests for IO's pos, pos=, rewind, seek on closed streams.
-
-commit 40414ad1b39222494ff2a79a0091890a60b7adf1
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 14:26:13 2008 +0100
-
- One more test for IO#eof?.
-
-commit 29db340f24c043b240fec6722c323fa1567ce855
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 14:19:46 2008 +0100
-
- Added new rubyspecs for IO#getc and IO#getchar.
-
-commit 0e0a987782fc7834ba95a2e8e2c8ab6cd8dcea81
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Feb 4 13:54:59 2008 +0100
-
- More rubyspecs for IO#eof?.
-
-commit f7d1139e4eace4a86f0c0512bf9269964442628d
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Feb 3 15:55:10 2008 +0100
-
- Fix Date#strptime specs
-
-commit ac4600fcb42928aeba508371aea2f76510e70d5c
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Feb 3 13:26:52 2008 +0100
-
- Fixed Time specs for non Rubinius platforms
-
-commit a5081ca646e99ec94fedfabf03b7eb0a8d37afc3
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Feb 2 23:53:52 2008 +0100
-
- Fixed Time specs for 64 bit archs
-
-commit 26eef47571b921fe6b3228033119e5969c4100db
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Feb 2 13:30:16 2008 -0500
-
- Updated IO excludes.
-
-commit 8edd73d9915f72ee70b661b23e8b42f8b985fa9c
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Feb 2 10:45:23 2008 -0600
-
- Repair IO#sysseek spec to not write to fixture file; uses a tmpfile now.
-
-commit bf6348c935c816a981672e9c26a40354cf0d722c
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Feb 2 02:35:42 2008 -0600
-
- Additional IO#sysseek spec for the warning after buffered writes
-
-commit 5241316a1c74e6580fb91940a9f061047e89cdbf
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Feb 2 02:32:36 2008 -0600
-
- Modify IO#seek specs for IO#sysseek, adding appropriate error tests
-
-commit 7f124cbf66b96fdcdaec73917e86eedfb4a9ddf8
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Fri Feb 1 18:05:15 2008 -0800
-
- Refactored Marshal#dump specs and merged with fixtures/marshal_data.rb
-
-commit 3766b3ed41ffba71ecb1bef8079027bffe518e2a
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Fri Feb 1 16:54:32 2008 -0800
-
- Refactored specs for Marshal#load
-
-commit e134d5bf8e247f4a231bfbfc1c3251b262f219e4
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 1 15:36:06 2008 -0800
-
- Update excludes for recent failures
-
-commit 8ded8b443f55b47a1c30b59cfb0d96d8752d5fa9
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 1 15:11:37 2008 -0800
-
- Process.group spec is missing a suplemental group on OS X
-
-commit 4b7de6ff839b220115dd29f34b5a9f46cb8f5bef
-Author: Evan Phoenix <ephoenix@engineyard.com>
-Date: Thu Jan 31 17:16:13 2008 -0800
-
- Add proper primitive failures, fix empty symbol.
-
-commit dc55c88beee6a3a3a7fd352c1e374ecf84863459
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 1 16:17:00 2008 +0100
-
- Fixed 2 Date#strptime specs that otherwise would pass only in January.
-
-commit 86c372d0fb50aeb6235ed1595d18a876e09330db
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 1 15:32:40 2008 +0100
-
- Few specs for Time#<=> with non-Time arguments.
-
-commit 765ef93acd294922dc22a986213a5842ce3e67a7
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 1 14:09:01 2008 +0100
-
- Added more specs to Time#+ and Time#-.
-
-commit af76adac2182e46e34e68d29b3cd8614edd27d50
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 1 13:38:20 2008 +0100
-
- Added more test cases for Array#join on recursive arrays.
-
-commit bb15b72393b34d3d10bb644fb1d6ce47b6dc0826
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Feb 1 13:15:24 2008 +0100
-
- Added more test cases for File::join with recursive arrays.
-
-commit 7041b2aef1e574dfe220a70da5210c683074f8ae
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 1 03:18:31 2008 -0800
-
- Describe an unambiguous method.
-
-commit 84edf54799e0ccd09276a5cda3fccf544f971c48
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Fri Feb 1 03:07:48 2008 -0800
-
- Use fixed Marshal data for all specs and fix many broken or useless specs.
-
- Clean up spec naming and definition.
-
- Use descriptive names for test classes.
-
-commit e0c3aa074c9525450a7a667ec2cc843ff3560e65
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 31 23:29:57 2008 -0500
-
- Hash.new patch from Phil Hagelberg + MethodTable workaround.
-
- * The Hash.new patch splits a separate #setup method so that subclasses
- can override #initialize without problems.
- * Because it is part of the core code, MethodTable needs to explicitly
- call #setup in its #initialize.
-
-commit a32f16d9288c5c0822cc6962ce3caed5e1bac5d0
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 31 15:35:08 2008 -0500
-
- Updated Module excludes.
-
-commit df731f327c4d47373ba6f2fe2f79d5d9acbf398e
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 31 15:30:11 2008 -0500
-
- More Module#module_function specs in #eval and #module_eval.
-
- * #module_eval separates the two scopes but #eval does not.
-
-commit 6358e5893c52042c10c355173d1ad8441a00bcfa
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 31 15:13:49 2008 -0500
-
- Better Module#module_function specs.
-
-commit 1646bb6e99a6b4190641046ae730ea1be9c8be2a
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 31 13:59:20 2008 -0500
-
- Various whitespace removal in preparation to fix #module_function.
-
-commit 108601d85d2c41d05f9c00945664d9980e0e46c3
-Author: Evan Phoenix <ephoenix@engineyard.com>
-Date: Thu Jan 31 13:39:53 2008 -0800
-
- Add meta_send_call instruction, speeds up calling blocks
-
-commit 50f9c50820b4305877af1c7fd7597c5dc94c623c
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 31 12:20:11 2008 -0500
-
- Added LC_ALL=C for all other platforms for Time specs too.
-
- * If it breaks, report and we will figure out something else.
-
-commit 26059c1570c5ad2a64a796e2678ff2d9ace23e58
-Author: Pierre Yager <pierre@levosgien.net>
-Date: Tue Jan 29 22:48:22 2008 +0100
-
- Fix for bin/ci spec failure on localised linux
-
- * Force system date to be executed against "C" locale
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit e5ce9e7c29a34f685f7d3f8a9f855db28aece460
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 31 11:32:56 2008 -0500
-
- Removed trailing whitespace for Time and some Time specs.
-
-commit 3546f721ac86efa318b3802a2f498d41aa830c9f
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Thu Jan 31 10:53:53 2008 -0500
-
- Subtend: Add rb_define_private_method, rb_define_protected_method, rb_define_module_method, etc.
-
-commit 7553cb993a0c7e60c2212800b0ecc033ffc0b206
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Thu Jan 31 10:39:08 2008 -0500
-
- Add rb_class2name in subtend
-
-commit 4570b7c5d837025d765a6a2909d5536c466b9dcb
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Jan 31 02:26:09 2008 -0800
-
- quick addition of 2 exclusions
-
-commit 53c76326e76869a87ad0fc67adbd3aef9059ee35
-Author: Ryan Davis <rdavis@engineyard.com>
-Date: Thu Jan 31 02:15:15 2008 -0800
-
- Parser spec updates
-
-commit 8fb2eb68858a1ee1dafb06b833f43d6da817756f
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 30 19:29:25 2008 -0500
-
- Slightly more permissive TCPServer.new spec for hostname string.
-
-commit 2a60dbbf011e806ae51c30ab2cb2b8e7b9b633a5
-Author: Mutwin Kraus <mutwin.kraus@blogage.de>
-Date: Wed Jan 23 18:41:12 2008 +0100
-
- Fixing TCPSocket#new for localhost (with specs for both IPv4 and IPv6)
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit f485a6818a754c8110feafa9f6dced42a99187d0
-Author: Jacob Maine <jacob.maine@gmail.com>
-Date: Tue Jan 29 21:13:28 2008 -0500
-
- Making Enumerable#inject only accept one paramter
-
- Uses 'Undefined' idiom, which fixes spec, and cleans up code (thanks
- for the pointer Eero)
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit ebfa5a0bf9f8e3efe61c0d34fe63a8cd74b7ddf8
-Author: Jacob Maine <jacob.maine@gmail.com>
-Date: Tue Jan 29 20:52:16 2008 -0500
-
- spec to verify inject accepts one argument, at the most
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit b131b80df72a9ceaa9e920b7f78434f301135a6f
-Author: Jacob Maine <jacob.maine@gmail.com>
-Date: Wed Jan 30 00:33:03 2008 -0500
-
- Adding Enumerable#count spec, including a few failing specs.
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 82b63bc0f5b79735a8021b6c5c69786dc76fa7f6
-Author: Alexandre Perrin <alexandre.perrin@epfl.ch>
-Date: Tue Jan 29 15:59:22 2008 +0100
-
- udpdated language/string_spec.rb
-
- * added spec for class/global variable with the \# simple interpolation
- * added spec for ends of a \# simple interpolation
- * added more delimiter character with the percent String construction
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit c58110bde52d64b30cf36ba3cb342357f3654812
-Author: Evan Phoenix <ephoenix@engineyard.com>
-Date: Wed Jan 30 17:19:26 2008 -0800
-
- Fix break. It now uses LRE to properly return to callsite and appear like
- it returned.
-
-commit 45109c222502de955d705f810333d8e7b331c953
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Jan 31 00:42:12 2008 +0100
-
- Added Date#strptime specs
-
-commit fe60e6a022d9e64bb568ccd47494f07a99382c58
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 30 11:36:46 2008 -0500
-
- Updated excludes for Marshal. Looks like Fixnum/Bignum issues.
-
-commit 209dde412310edc384be7d4a86bdfb0444f3b3bf
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 30 01:45:27 2008 -0500
-
- Updated IO/File excludes.
-
-commit 91031e51e49a1a3ddb9f74da31e2ed65c48e1ef5
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 30 01:43:11 2008 -0500
-
- IO.new and IO#close use stream API.
-
- * IO.new uses fdopen() to open the given fd which also checks the mode
- string for us. The returned FILE* is stored as a MemoryPointer in
- @fptr.
- * IO#close checks for presence of @fptr and if found, uses fflush() and
- fclose() to release the handle instead of going the normal route.
-
-commit f4d64553a2a53c77235ef9acc3353ac455514057
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 30 01:20:32 2008 -0500
-
- Made probably broken File.open spec compliant_on :ruby.
-
- * File.open should not take three args. File.new does.
-
-commit dc496f35502b4642137d3f0f74571c8245a6ae56
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 30 01:19:29 2008 -0500
-
- Slight IO.new spec tweaks.
-
-commit a9d9288315e88cffd59ec1b27e3c3209ceb1a3a9
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Jan 29 20:32:44 2008 -0500
-
- Combined IO.new and IO.open specs for the shared parts.
-
-commit effa81cce1d42f7c1bc2e275cb75bd9069e934b8
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Jan 29 19:14:51 2008 -0500
-
- Changed specs to use the two-argument IO.new.
-
-commit 1394b360fe70966e25809a349b400a69262060ca
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Jan 29 14:56:47 2008 -0500
-
- Rewrote IO.new specs (still a bit sparse.)
-
-commit 94d50eb3e60971ffeff28bffa0beaff405c581bd
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 30 21:47:35 2008 +0100
-
- File#utime specs to use be_close rather than ==.
-
- On some platforms, direct comparison just doesn't work,
- producing non-deterministic test failures.
-
-commit 0f5574c28ff08c96326298b98b4ea50108168044
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Jan 30 13:13:25 2008 +1100
-
- Remove race in debug_context_change specs
-
-commit 00a62c3476dd0717f5c4caece453914e1392de9d
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Jan 29 14:39:06 2008 -0800
-
- Remove bogus Marshal specs for Fixnum/Bignum changeover
-
-commit db1b140db0fbecf70f8adda983e010ef2bbe94c4
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Jan 29 22:58:18 2008 +0100
-
- Finished first version of Date specs. All public methods are specced
-
-commit 8ee52fd8dfd3ef6048c63b30d8aea71da944abb2
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 29 17:21:57 2008 +0100
-
- Follow rbx lead, and allow deviation in UnboundMethod#== for JRuby.
-
-commit f670bcb9e086ac9cc73b6ef6083966b296268f04
-Author: Caleb Tennis <ctennis@engineyard.com>
-Date: Tue Jan 29 09:46:50 2008 -0500
-
- Fix typo
-
-commit 4e990269fd42aabd48cdc29b4288c78984d0e5cf
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Jan 29 02:44:20 2008 -0800
-
- Add File::join recursive Array spec.
-
-commit 4d947218e949e19515a9e89af99d4823048f3bb2
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Jan 29 02:41:54 2008 -0800
-
- Fix File::join spec name, duplication
-
-commit a38e10ddc19ebd59f8775a01f3e899c5348ba23f
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Jan 29 02:40:37 2008 -0800
-
- Make File::join remove extra / appropriately.
-
-commit 074251c03093ba40c0fc3558d512a77844ac45aa
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Tue Jan 29 00:53:23 2008 -0800
-
- Make File::join specs more clear, remove whitespace
-
-commit f968bbe15a27d8ac6716d103119d41c4eef37696
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Mon Jan 28 18:07:24 2008 -0800
-
- Use const_lookup in Marshal, fix #marshal_load.
-
-commit 7e00b857f56879564c1bf27f2e694f3c0783a4bb
-Author: Eric Hodel <ehodel@engineyard.com>
-Date: Mon Jan 28 17:23:26 2008 -0800
-
- Support nested modules in Marshal
-
-commit 5c6e2af3d9ace07ca8387c5aecaa5c1d85e8d81f
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 28 20:22:40 2008 -0500
-
- Added specs for rest of the filetypes to File::Stat#ftype specs.
-
-commit 221a077bef5e9007b548993eaf16c86137c6b0b3
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 28 20:08:12 2008 -0500
-
- Added support to spec file type against sockets too.
-
-commit 9cb4791db10bc79f8c30a86f17e6c099dabeea80
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 28 19:52:07 2008 -0500
-
- Moved File and File::Stat-related fixtures to fixtures.
-
- * Module FileSpecs defines methods that yield filenames corresponding
- to specific file types so they can be easily tested.
-
-commit c28c85602d3ab6770ed567a64b744baa15795511
-Author: Ben Hughes <ben@pixelmachine.org>
-Date: Sat Jan 19 16:10:36 2008 -0500
-
- Added spec for File::Stat#dev, dev_major, and dev_minor
-
- * Check that the result values are Integers for each operation
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 86ce52e32a35cb11564d0d5f306f4eea6d6b714d
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Jan 22 15:21:38 2008 +1100
-
- Added yield_debugger on context change
-
- Added capability to set a flag in the VM that causes a
- yield to the debugger to occur immediately following a
- change in the active context. This provides a foundation
- for step in logic for the debugger, which need only set
- a flag on a task and have a breakpoint triggered at
- whatever receiver is activated following a send.
-
-commit 3904ff2fbb209b8c2d476bb3f4a4ea4825a16f6e
-Author: Brian Ford <bford@engineyard.com>
-Date: Mon Jan 28 17:58:35 2008 -0800
-
- Fixes for mSpec to coexist with autotest.
-
-commit 45f2d6de4b025acfa2429d88c729a3eb58a79528
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Mon Jan 28 17:08:45 2008 -0800
-
- Added more brains to .autotest. Removed bad files that it pointed out
-
-commit 70eaa7feffcfd552c51b67a651cdf6063c9b549a
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Mon Jan 28 15:57:24 2008 -0800
-
- Add File::Stat#dev.
-
-commit 020f4bec691ba658fab0f1ff24fa5df5a6f1921f
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Mon Jan 28 16:13:11 2008 -0800
-
- Added enough process spec exclusions to drop the HUP issues
-
-commit 76b393566f2a89001952dbf1ec46dd52a5750448
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Sat Jan 26 10:58:42 2008 -0800
-
- Fixed autotest support (needs latest version of zentest).
- Minor clean up on bin/ci and kernel/core/module.rb.
- Hacked mspec/matchers/base.rb to output with pretty print.
- Fixed mspec's runner to output time BEFORE failures. Fixes unit_diff.
- Updated Parser excludes.
- Deleted a bunch of excludes.
- Updated spec/parser/sexp_expectations.rb with latest ParseTreeTestCase.
- Started adding a rewriter to make maintaining sexp_expectations easier.
-
-commit d147f6f0a87e30e240750d8c660bc89f8c84a472
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Mon Jan 28 18:20:38 2008 -0600
-
- update CI excludes
-
-commit 159f17a228fa6a42cea79b9e3663e1f2b9dea9e4
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Mon Jan 28 18:07:56 2008 -0600
-
- add Marshal specs
-
-commit 72e739590b6bbe571607df674e2f4106c64c8042
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Mon Jan 28 15:15:26 2008 -0800
-
- Fix String#gsub when matching '^'.
-
-commit fc8c2c5584305b3e0b2a74ba8250a0b7072a372f
-Author: Ben Hughes <ben@pixelmachine.org>
-Date: Sat Jan 19 16:20:55 2008 -0500
-
- Added specs for File::Stat#ftype. #264.
-
- * Tests "file" and "directory"
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 2f9872b66d4dffc82e0a97e617fb9de18105f668
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 19:56:06 2008 -0500
-
- Better living through mocks. String#+ spec cleanup & correction.
-
- * String#+ in fact raises a TypeError when given ANY non-#to_str
- object.
- * Simplified spec code.
-
-commit f5a0f1e0e401db8f28727cdd8be99228c9c6aee3
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 19:37:08 2008 -0500
-
- Removed trailing whitespace in String.
-
-commit 03c1c270236786b66930063669b95ac7cbf17f10
-Author: Matthew Draper <matthew@trebex.net>
-Date: Thu Jan 10 22:40:35 2008 +1030
-
- String#+(65) throws a TypeError, unlike String#<<(65).
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit a17ede3e9c85c1bd2e06efa7381c1e5dbab47f80
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 19:10:33 2008 -0500
-
- Minimal IO#open specs, IO#sysseek. Merged from Chen Yufei's patch.
-
- * Merged patch by hand, most of it was already implemented separately
- too.
-
-commit 30116d672d950687646c1668eac4d9f5b10f4df7
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 18:53:19 2008 -0500
-
- IO#readline EOFError spec modified from Chen Yufei's patch.
-
- * Patch was out-of-date, applied by hand.
-
-commit 1b81e68249741d53b38857440bba897987d00e43
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 17:44:30 2008 -0500
-
- Separated and excluded NUL byte stripping for String#lstrip specs.
-
- * Rubinius does strip leading NULs, MRI does not.
-
-commit 55f50888f22288b0fa45298d873dd265d7340aec
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 16:52:51 2008 -0500
-
- Updated various excludes.
-
-commit b085f63d66519f93b59e3851b7e6796877e97107
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 16:47:24 2008 -0500
-
- Documented Method, deleted unnecessary Method#module spec.
-
-commit f71f5c91e8ceab59d59614fe885dfeff096d7655
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 15:41:26 2008 -0500
-
- More precise specs for Method and UnboundMethod #to_s / #inspect.
-
- * Checks presence of own class, method name, name of the Module where
- the method is defined and name of the Module where the method was
- extracted from.
-
-commit 400b522d27515698e0a35b2507a4a8825ec9bf8f
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 15:22:46 2008 -0500
-
- Rewrote Method#unbind specs, touch-up for Module#instance_method spec.
-
-commit 57bddb7b38dbb762b2469c51eb961e01f03c8518
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 14:50:38 2008 -0500
-
- Updated UnboundMethod#== spec for Rubinius/MRI difference on Modules.
-
- * Rubinius' UnboundMethod#== is true for methods from included Modules also.
-
-commit 8503c92f914d72e72eeeaede225f52242a1afad9
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 14:25:29 2008 -0500
-
- Rewrote and added Module#instance_method specs.
-
-commit 8541f4cf83f8b776276e81ca41eb0f7b595e4fb7
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 13:43:36 2008 -0500
-
- Improved/added UnboundMethod#bind specs.
-
- * Removed unnecessarily specific error message check. Exception type
- is plenty.
- * Specified correct behaviour only in terms of Method since a Method
- is returned and anything after that is not #bind's responsibility.
- * Rubinius allows binding to any object that is kind_of? with respect
- to the Module that the method is *defined* in. MRI requires that it
- can only apply to objects of the same Module that the method was
- extracted from.
-
-commit fc7073c85b5e201265e24a82c19bd6413681f6e1
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 13:02:24 2008 -0500
-
- Removed trailing whitespace in UnboundMethod#bind specs.
-
-commit bde0cacff5f061accab7feb8a27b2417456f2f95
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 12:38:39 2008 -0500
-
- Specced Rubinius to deviate in UnboundMethod#==.
-
- * MRI requires that both UMs were extracted from the exact same
- Module. Subclasses etc. are not OK even if the UMs both refer to
- the original in the parent. This is somewhat nonsensical and
- harder to implement so Rubinius allows it.
-
-commit e7ba146d3d0ef0aed1d297d157008661458723eb
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 12:16:07 2008 -0500
-
- Much more comprehensive and precise UnboundMethod#== specs, documented.
-
- * #== has some stupid behaviour but this is what we get.
- * Explanation of criteria in the method doc.
-
-commit 43f2226c8882900a472f0a5347fa549936e8f000
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 09:37:51 2008 -0500
-
- UnboundMethod String representation specs improved.
-
- * Specs require that the returned String contains this object's class
- and the [Module]#[method_name] it was extracted from.
- * The spec specifies nothing else about the format or order etc.
-
-commit 67e3b5993d92776e0c9535549e8ffdb172225d52
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 09:11:19 2008 -0500
-
- Trimmed whitespace for kernel/core/method.rb for patching.
-
-commit c61c5185589cf5a86b58b2e8c8b8d7a26cdc25ec
-Author: Scott Taylor <scott@railsnewbie.com>
-Date: Mon Jan 14 00:23:27 2008 -0500
-
- fixing the specs for UnboundMethod#inspect
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 48bcca32329d48a20d5a6f2dd19598ea7b4167ce
-Author: Scott Taylor <scott@railsnewbie.com>
-Date: Mon Jan 14 00:16:24 2008 -0500
-
- UnboundMethod#==, plus an extra spec
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 232015fed94b59adf627a7712da0d5d4d44c87d0
-Author: Scott Taylor <scott@railsnewbie.com>
-Date: Mon Jan 14 00:03:32 2008 -0500
-
- UnboundMethod#bind
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit fcd0139307fd48f78f122457af1af43a543343ce
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 12:11:34 2008 -0500
-
- Updated excludes for IO#write.
-
-commit eed253158fe0cc20b91f6c8dcc06f6a671092d84
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Sat Jan 26 14:36:33 2008 -0800
-
- IO#write calls #to_s on it's argument
-
-commit bb5ff251bcc4baceac25a3a1fa64797b94551145
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 03:22:02 2008 -0500
-
- Updated #attr_writer spec that was picking up a stray method.
-
-commit fa985a57f6cf802d6a83a6d02a31dd7fd33ebd36
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 01:20:27 2008 -0500
-
- Module#const_get can now access top-level constants for Modules also.
-
- * Modules explicitly check Object last, Classes already do it since
- they all inherit from Object.
- * Added some more specs too.
-
-commit fbc1cfb2d461891ee478802f44de3736959905a7
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 00:47:52 2008 -0500
-
- Renamed the Module field 'parent' to 'encloser.' Some docs.
-
- * When dealing with Modules and Classes, 'parent' is an ambiguous term.
- In typical OO literature, 'parent' means the superclass which is not
- the case here. Two separate sections of code already showedsome
- uncertainty about the intent of this field.
- * Added a few bits of documentation to Module.
-
-commit 92903e92564857350061d83f8eb3b54886986ac3
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 00:36:10 2008 -0500
-
- Updated Module excludes.
-
-commit a705e687ce0d55e7ea184e1a3e67ba8d9d7c610c
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 27 00:24:20 2008 -0500
-
- Improved Module#const_get specs for better coverage.
-
-commit bca6aef9b81166f9c5f4aeaafc673a54710d4d35
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 19:57:33 2008 -0500
-
- Corrected semantics of spec statements for Module#const_get.
-
- * Specs were correct but the description was inaccurate.
- * Prettified just a little.
-
-commit f699c18b68dee73086afb92d15b61745319a5321
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 19:55:40 2008 -0500
-
- Module#const_get specs for top-level constants by Le Huy.
-
-commit f3831a0693ea90271843bcc5910516e5a40ed3c1
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 19:15:27 2008 -0500
-
- Module whitespace cleanup before patching.
-
-commit e3cbe8136351f055bd99f10646d4f77515078430
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sun Jan 27 00:51:55 2008 -0600
-
- A few basic IO#write specs for file IO
-
-commit fd05adfedf70d795d8d91f650d5b76b05104dd7a
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 18:54:35 2008 -0500
-
- Specs for Enumerable#max_by (Rubinius extension.)
-
-commit 560b6460745c7821b9479b356c032a10daaa61ec
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 18:53:52 2008 -0500
-
- Specs for Enumerable#min_by (Rubinius extension.)
-
-commit 6ab0bc901bdc60bde1e251f72f0028dfb736a2dd
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 14:25:41 2008 -0500
-
- Updated excludes for Enumerable.
-
-commit 2e09eedb31e15c791e491e97bc2af1977a629c2b
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 14:20:19 2008 -0500
-
- Fixed Enumerable#max and #min nil problems using Undefined.
-
-commit d8e6ebf604fdcc228e9158336250dd29c6d35932
-Author: Jacob Maine <jacob.maine@gmail.com>
-Date: Sat Jan 26 13:22:33 2008 -0500
-
- Failing spec for finding max when Enumerable contains nil
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 313ee6badb177c101e39e122c5b5d6ff4d73d93d
-Author: Jacob Maine <jacob.maine@gmail.com>
-Date: Sat Jan 26 13:01:06 2008 -0500
-
- Failing spec for sorting a list that contains nils
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 467e8a60e0e25003894013e68f6d48e7bd6a22fc
-Author: Jacob Maine <jacob.maine@gmail.com>
-Date: Sat Jan 26 12:01:15 2008 -0500
-
- adding failing spec for sorting enumerables that contain nils
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 8719a4ad46d7643c6e54aab3dffedb6831bde5f3
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 13:42:11 2008 -0500
-
- Whitespace cleanup before applying Enumerable patches.
-
-commit 015a0d023e8c649160800ddb8a269aa789266d51
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Jan 26 13:31:00 2008 -0500
-
- Added/changed the Dir open specs after previous simplification.
-
-commit 6735df441af2489d47674b0cc500dab37dd4319e
-Author: Jonathan Younger <jonathan@daikini.com>
-Date: Thu Jan 24 17:09:49 2008 -0700
-
- Simplify Dir#open spec dependencies.
-
- The "takes a block which yields the Dir instance and closes it after"
- expectation was failing because it depended on File.for_fd working
- properly with closed file descriptors which it does not.
-
- This revision removes the dependency on File.for_fd as well as
- IO.sysopen (which is not yet implemented in jruby) such that
- the spec now passes on ruby, rbx and jruby.
-
- Signed-off-by: Eero Saynatkari <rubinius@projects.kittensoft.org>
-
-commit 27834ebec570c78011eaaf37998272d46ab9d118
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Jan 26 21:51:13 2008 +0100
-
- Added Date#strftime specs and fixed some constants
-
-commit 767e58ec38af7c3bc78dd98541fb8235616e9691
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Jan 26 21:45:23 2008 +0100
-
- Add spec for Rational#round, works because of added Numeric#round
-
-commit 2497d3b7b9d6112356204dc429c3c368e1a65573
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 26 12:31:45 2008 -0800
-
- Templates for Rational specs.
-
-commit 5d63550a13cad4acbae3ae67e9ee9f672cbe5e61
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Sat Jan 26 00:47:35 2008 -0800
-
- Revert back old date.rb, but use newer date/format.rb, with some fixes
-
-commit ecd3ee8a0a528f516283558585b86e729bd388ec
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 25 21:47:38 2008 +0100
-
- Updated not_compliant_on --> not_supported_on, where appropriate.
-
-commit 78ca098893d6231f74386eeadf0c30787f3dd2e6
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri Jan 25 12:18:43 2008 -0800
-
- A couple of easy fixes, fix Time to handle 2 digit dates, pull in trunk date
-
-commit fe8433cda8ca49835e2581f35bbf0d31025e84c1
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 25 18:42:31 2008 +0100
-
- Better detection of AF_INET6 support in socket specs.
-
-commit 1834801229bf8b2c0abfea4c18448ed105691682
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 25 18:16:56 2008 +0100
-
- Added a guard for undefined AF_UNIX in Socket specs.
-
-commit 3af242cc180675272ee24d588f3328bc11342048
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 25 14:32:04 2008 +0100
-
- New specs for IO#seek, IO#pos=, StringIO#seek and non-fixnum args.
-
- Rubinius fails all of them.
-
-commit 0ef7d55ebb5108bd5cf2f951236c8fade3999dfb
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 25 13:42:08 2008 +0100
-
- New specs for String#unpack with 'Q/q' patterns.
-
-commit 907081db80262a1403f659433934ef707c2ddee0
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 25 12:35:07 2008 +0100
-
- Adjusted socket specs, so they pass on MacOS (MRI/JRuby).
-
-commit 9cca76acbe066da357692a19d5af1c8f5e4601c9
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 24 17:31:38 2008 -0800
-
- Fix race in compiler version number, fix regex spec
-
-commit be18fcc2e0ee16f861f1e2bff0636c3288bce8d6
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 24 15:10:00 2008 -0800
-
- Be more flexible with set_priority (OSs are a bitch)
-
-commit 845336d81df42b5d1f93123ef148b78c2b220d25
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 24 13:46:08 2008 -0800
-
- Kernel flesh out, passes all but 1 spec now
-
-commit ab87e7641336dfb07f0ad99cc2881ec59a25053a
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Thu Jan 24 12:36:50 2008 +0100
-
- Changed __const_set__ to handle corner cases.
-
- * Kernel#__const_set__ is now the catch-all. It triggers on things like :
- M = 3
- M::M = 3
- * MAIN#__const_set__ is forwarded to Object
- * Module#__const_set__: logic has been moved here, it is no more and alias
- of Module#const_set because it needs to trigger a warning on re-assignment.
-
-commit 13dbdf62e802028cb61f9375196712f0b789ff37
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Jan 24 21:30:02 2008 +0100
-
- Added some SystemCallError specs.
-
- And exclusions for rubinius too.
-
-commit 75e2aac1d4b031fa36c8967549452436521b5eea
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Jan 23 19:41:30 2008 -0800
-
- Rework Class.new and Module.new to initialize without VM help
-
-commit 2551e57644d091d44e5e2fa715a017a557a0b18c
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Jan 23 19:03:51 2008 -0800
-
- Userland now uses __const_set__ for 'A = 3' syntax
-
-commit 400c5ceaf677aa2cd05a451c22144613ad7bdbe9
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Jan 23 14:32:26 2008 -0800
-
- Introduce kernel/user land. Adds use of Module#__add_method__
-
-commit 9ee17f227ebe572b09d44b3b0d703b9f95717751
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Wed Jan 23 14:50:25 2008 -0800
-
- Fix Hash#clone
-
-commit bf4875d337017736bd94781c1bf4cd7500fae5f5
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Jan 23 22:55:02 2008 +0100
-
- Implemented Enumerable#inject fix
-
-commit 0bd07f50ba75910ab579e3356dae93bc32b695bd
-Author: Jacob Maine <jacob.maine@gmail.com>
-Date: Wed Jan 23 15:46:06 2008 -0500
-
- Enumerable#inject(nil) should yield nil as the first 'memo'
-
- * Currently yields the first element of the enumerable instead
-
-commit 319f937284e60acc156c6b7f91e56d460e65ac94
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 23 18:12:56 2008 +0100
-
- Excluded the IO#new spec.
-
-commit 04da4120d939603d4a64aab71bbf94ca202e04b2
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 23 18:11:45 2008 +0100
-
- Added IO#new spec (block should be ignored, warning printed)
-
-commit 5617c3eb81a3f1d8f9a581695fe7897fadee500a
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 23 17:50:48 2008 +0100
-
- Excluded failures after IO specs additions.
-
-commit 107a072689bc9b97842f049f4fab2860ab79237d
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 23 17:48:34 2008 +0100
-
- Added specs for IO#open/popen, File#open with close inside block.
-
-commit bc3393a9041f8116d53bedfa6b604ec6dce3fd19
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Wed Jan 23 14:25:13 2008 +0100
-
- Revert "Added Module#name memoization spec". dbussink told me this behavior
- is not wished.
-
- This reverts commit ff411600202a59d00ffaca2c51330599c6b84966.
-
-commit 73e7d61d756cb7a06ea18b7f92c49bbebb06cc3f
-Merge: ff41160... 1dab607...
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Wed Jan 23 13:57:28 2008 +0100
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit ff411600202a59d00ffaca2c51330599c6b84966
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Wed Jan 23 13:55:36 2008 +0100
-
- Added Module#name memoization spec
-
-commit 1dab607a79b79b370eda4776daf07a262451aea0
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 23 13:28:29 2008 +0100
-
- Added IO#close specs.
-
-commit c78091236495f4a16aa874de97cce3ec485c1f5b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 23 12:54:25 2008 +0100
-
- Added IO#close_write and IO#close_read specs.
-
- And all of them fail in rubinius. (not implemented)
- And most of them fail in JRuby. (recent bugs)
- They pass just fine on MRI 1.8.6 (p111 and latest)
-
-commit dc39943a4595855d64f23f9155a4e9cf658c39a3
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Jan 23 10:37:45 2008 +0100
-
- Small refactor of regexp_new
-
-commit 132ac4986a648dbf1354216145e5715a727a735b
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 23 00:14:34 2008 -0500
-
- Type.coerce_to no longer falls prey to identity fraudsters.
-
- * Type.obj_kind_of? directly uses the internal kind_of instruction
- so that overridden #kind_of? does not get in the way.
- * Type.coerce_to uses Type.obj_kind_of? for its checks so that
- Core can safely use it without worrying about breakage due to
- overridden #kind_of?.
- * Specs for both and a little documentation.
-
-commit 192882902154c9a68554337ccd1b8f3ee9aedd9e
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Jan 23 00:42:24 2008 -0800
-
- Remove Symbol#to_i and Symbol#to_int. Farewell bastard children.
-
-commit f854667ff62528fe541c8cf67b9a1b291598d654
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Jan 23 00:35:29 2008 -0800
-
- Removed Fixnum#to_sym and Fixnum#id2name, as well as fixed specs
-
-commit eb6cbc3604c81cc093edb1c182be1e456b05bef6
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Jan 23 16:30:22 2008 +1100
-
- Added specs for context iseq manipulation
-
- Added specs to test MethodContext#reload_method and
-
-commit fd5fb764ee21b354b75b84f34906663874a24639
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Jan 22 22:28:02 2008 -0600
-
- spec for DRb method call using a block
-
-commit a928762b48f7dc84bba0d43125063e9d8d54f183
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Jan 22 19:15:10 2008 -0800
-
- Better test of #instance_method.
-
-commit c055a5981bf4ecfd2efc0df74adb071056ff83b9
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Tue Jan 22 15:40:59 2008 -0800
-
- removed remove_method_excludes.txt
-
-commit 08cb27454e7ae73e79bb432887dba917feaa1f92
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Tue Jan 22 15:36:36 2008 -0800
-
- Clarified undef/remove specs a bit.
- Fixed remove_method to raise NameError if you're not acting on local method.
- Removed some fails_on calls to make specs pass... gonna remove them all soon.
-
-commit 62d93ac7916ff0d56a5b40ae1b9b501f10081638
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 22 15:35:05 2008 -0800
-
- Fix up sysread and syswrite, disable testing for warnings on rubinius
-
-commit a482b17c4bfe9f40474839ba0cce2a37d8524c62
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 22 15:13:19 2008 -0800
-
- Remove stale binding excludes
-
-commit f45030d33a9e1fe3c6bc111401a893e5649239f7
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 22 15:03:37 2008 -0800
-
- Update Proc excludes
-
-commit 7f932fbdf5fa4e16df10d7731313d458ca21966c
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 22 14:55:50 2008 -0800
-
- Add Proc#==
-
-commit 811cbe8ef876ef452051a9b07b3c95dbf57a7d9f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 22 23:41:55 2008 +0100
-
- Removed debugging stdout from one spec.
-
-commit 2bf52de43bb90721d921f6d29504a8f098ed09b5
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Tue Jan 22 14:11:17 2008 -0800
-
- Removed a lot of passing specs from the excludes
-
-commit b0e5a9ba6577c301f2737682d745128e268ebdab
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Tue Jan 22 14:02:38 2008 -0800
-
- Fixed Symbol::all_symbols
-
-commit 68ae0b5acd647b9ebd73e53638b728cfaee6b6e0
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 22 22:09:45 2008 +0100
-
- Revert "Completed MRI's Module#name spec with corner case."
-
- This reverts commit 970ede321d31ec75dd578866c683defe768fa356.
-
- This spec seems like an implementation detail rather than
- a specified behavior. It was agreed on IRC to revert it,
- and that rbx won't support it.
-
-commit cc0e45cab2167e0fbc1d29308a5dcb4e7e077319
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 22 22:06:28 2008 +0100
-
- Revert "Module#name memoization work."
-
- This reverts commit 7cd9fce4908aaeea9a35e273a3f15ed7ee7aa783.
-
-commit 996f9f4e5fc05f1b3aa618db3e1a4947730780b7
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 22 12:23:39 2008 -0800
-
- Fix LongReturnException to be terminated in the correct place
-
-commit f453121dd2f3b4d9506a3f1c1e61d24e46bc9083
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 22 20:53:45 2008 +0100
-
- Corrected Module#instance_method failing spec. It was failing on all impls.
-
-commit c1d59239ddea95e73e2edd3a97ed6e1113a35d3c
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 22 19:58:32 2008 +0100
-
- Corrected Module#instance_method spec, it was failing on MRI/1.8/1.9/JRuby.
-
-commit ef5f4489caac2ad4bad94783a780aa40a054481c
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 22 19:30:48 2008 +0100
-
- Corrected String#to_f spec.
-
-commit 7cd9fce4908aaeea9a35e273a3f15ed7ee7aa783
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sun Jan 20 22:00:34 2008 -0600
-
- Module#name memoization work.
-
- * Module#name is now memoized on access if @name is set
- * Full module path is lazily calculcated on memoization
- * Module#const_set(Ruby) and module_const_set(C) only set @name and @parent.
- * The following methods unifily use module_const_set:
- * cpu_const_set
- * cpu_open_class
- * cpu_open_module
- * module_setup_name
- * Module#calculate_name reworked, hack removed
-
-commit 7b4ef1344812faa76018ab41cc7fba97a3af8448
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Tue Jan 22 02:47:49 2008 -0600
-
- implement more of Marshal.load
-
- Float, obj._load, obj.marshal_load, IO.read, proc arg
-
-commit 41f07f0253a8fba205dbb0402e5d5e88c115d76c
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Jan 22 16:32:01 2008 +1100
-
- Fix Task#get_stack_value to not raise exception from primitive
-
-commit 14c811adaba3e8cfc5104d70e67c2e89c18cac4d
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 21 19:28:18 2008 -0800
-
- Exclude Kernel#require is private spec when running with RSpec.
-
-commit 05a180e0051a0409c685d326a41e882545faaa53
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 21 19:26:41 2008 -0800
-
- Explicitly run /bin/sh to get around limited /bin/pwd on linux.
-
-commit c09b3da391995a0e9006055ce19e838d3f180947
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 21 19:09:07 2008 -0800
-
- Protect String#% specs from segfaulting on linux (ubuntu gutsy).
-
-commit d36b3f65f92b08ae078812788482387077d03380
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 21 17:55:03 2008 -0800
-
- Removed use of `pwd -P` as at least ubuntu bin/pwd doesn't support it.
-
-commit 6d7a8292fb9a68a0dcfbd3f29f595e0ecf5902ae
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 21 17:54:11 2008 -0800
-
- Unexclude Kernel#callcc specs as Evan's recent commits seems to fix it.
-
-commit eb04d409575772a85510770bd0db4f36490de6aa
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Mon Jan 21 13:28:06 2008 +0100
-
- Fix Regexp error handling
-
-commit 93e50808eb7355c404a7f5295923083c8cf63549
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sun Jan 20 22:00:34 2008 -0600
-
- Quarantining IO#dup spec "sharing" example due to platform differences.
-
-commit ae9e2829becc495892c7ddce5eae67514f268120
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 10:26:56 2008 +0800
-
- Update Module instance_method_specs excludes after revert put it back in
-
-commit df6c82f97987c233eab0534740054e2d0f0f2f2c
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 10:25:00 2008 +0800
-
- Revert "Update CI excludes for Module"
-
- This reverts commit 8aa00146f2eee9576094daa76c6f158b0deaf2e2.
-
- * Fails when run with other specs
-
-commit 6f5245d4c20bf009bc120967f4a93d24faae66ba
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 10:23:15 2008 +0800
-
- Revert "Update CI excludes for Symbol.all_symbols spec"
-
- This reverts commit cb27e31b2a757ad108842bfa579eb9170d6cf244.
-
- * Returns an F if run with other specs in ./bin/ci
-
-commit ec9677e593247ed8dfcbfc680151d04ac97936e3
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 10:11:35 2008 +0800
-
- Fix Module instance_method_spec to match the inspect with a regexp
-
-commit 7e3474a16ec20094630e865594405ea7f1658c58
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 10:08:06 2008 +0800
-
- Module#instance_method raises TypeError/ArgumentError on invalid arg
-
- * Fixed spec to expect TypeError when passed nil
- * Fixed spec to expect ArgumentError when passed non-symbol/string
-
-commit 8aa00146f2eee9576094daa76c6f158b0deaf2e2
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 09:41:37 2008 +0800
-
- Update CI excludes for Module
-
-commit 9158b959d30babdceafc416650c1ba3234e5029a
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 09:10:06 2008 +0800
-
- Add alias for Proc.to_s from Proc.inspect
-
-commit cb27e31b2a757ad108842bfa579eb9170d6cf244
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 09:09:40 2008 +0800
-
- Update CI excludes for Symbol.all_symbols spec
-
-commit 7f16f313c907de0e22762d97fbba24e70c3259a3
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 21 08:46:36 2008 +0800
-
- Raise TypeError/ArgumentError for invalid Thread key
-
- * Raise TypeError is key is nil
- * Raise ArgumentError is key is not Symbol or String
- * Correct the description of Thread's element_set_spec to use #[]=
-
-commit 0b849f884beae9d11327e315da5c79fe789b8391
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Jan 20 23:05:33 2008 +0100
-
- Added rubyspecs for Zlib.crc32.
-
-commit 67b52b6fb92b9e9a037e584474cff2dc97ce0163
-Merge: e6d8a61... 6f08d5e...
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Sun Jan 20 22:30:52 2008 +0100
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit e6d8a61771b76198c0784677bb0a8fc97b1988bc
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Sun Jan 20 22:30:29 2008 +0100
-
- Fixed Struct#[] and Struct#[]= with negative indexes.
-
- * Added corresponding specs
- * Fixed kernel/core/struct.rb code
-
- Example:
-
- s = Struct.new(:x, :y)
- x1 = s.new(:a, :b)
- x1[-4] #=> should raise IndexError: offset -2 too small for struct
-
-commit 6f08d5e21473d0f2adff66a32acd46ddd8945fa0
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 20 12:47:11 2008 -0800
-
- Added spec for Kernel.format.
-
-commit 6ab2691b455ac07643d98dc58f8a0f45487ab20d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 20 11:52:56 2008 -0800
-
- Added sane handling of non-reals for #format %e, %E.
-
-commit 1caab1ce237a52d78a402a5f0a7ce1d3ed9ac6b7
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Jan 20 18:55:27 2008 +0100
-
- Add spec for singleton_methods and fix for Fixnum
-
-commit d7c46a0a1660f1d53e03a97571f3ec7b2431d0e4
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sun Jan 20 12:29:10 2008 +0100
-
- Added failing spec for Regexp#new that could cause a segfailt. Needs error handling as stated in shotgut/lib/regexp.c:122
-
-commit d15c6605b7fb7db337d87ac1bd15f9a1371caa42
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 19 19:28:00 2008 -0800
-
- Added language spec for return within a block.
-
-commit 3b516c028c4c9e064fbe839f0f9402a135eb90b0
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 19 17:27:13 2008 -0800
-
- Added spec for class vars set from Kernel#instance_eval based on #267.
-
-commit 970ede321d31ec75dd578866c683defe768fa356
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Sun Jan 20 00:44:04 2008 +0100
-
- Completed MRI's Module#name spec with corner case.
-
- It looks like Module#name is memoized in MRI
-
-commit caf440ac6a8037a2c223834c0ca4c5decd8e68ab
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Jan 19 22:48:31 2008 +0100
-
- Revert "Wrapped one spec to prevent JRuby crash."
-
- This reverts commit 9f266e3c785c7e3edbb6a30271f32debe6c14164.
- JRuby issue is resolved.
-
-commit 9673e2c1c5a1142af52a0d82d8981bdd9e236c27
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 19 12:46:12 2008 -0800
-
- Changed IO#syswrite to use should complain matcher.
-
-commit 8522186df7050782c4911f40aef381106e5e8c5b
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 19 12:29:12 2008 -0800
-
- Added mSpec lambda { .. }.should complain matcher for warnings.
-
-commit 9f266e3c785c7e3edbb6a30271f32debe6c14164
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Jan 19 21:24:13 2008 +0100
-
- Wrapped one spec to prevent JRuby crash.
-
-commit 54d1989997561271553ba72bd99f59ef2deb7c72
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Sat Jan 19 19:13:06 2008 +0100
-
- Fixed "X::X = 3". It would return a tuple instead of 3.
-
- * changed shotgun's const_set instruction to push the variable on the stack.
- * added corresponding specs under `language'
- * found a new problem but added it to excludes
-
-commit d25ec129902789bc7d636ff5ccda8ff858ae38d3
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 19 10:21:19 2008 -0800
-
- Added spec/README. Reformatted mspec/README. Removed old sprintf spec.
-
-commit 5eb06e3010707de1e273c23b3f0addf2ceaa824d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 19 09:37:29 2008 -0800
-
- Removed unused Sprintf, rename YSprintf to Sprintf.
-
-commit c144abc12230175a2a503c4426804ed19c8559e7
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Jan 19 16:21:08 2008 +0100
-
- File::Stat time functions should return Time objects and added stat and lstat instance methods on File
-
-commit 177ef99db435a59e942566f7904167fc5e849d8d
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sat Jan 19 22:24:16 2008 +0800
-
- Fix ThreadGroup's add spec
-
- * Fix is by initializing a new ThreadGroup on Thread setup
-
-commit 3fad84ec370eda1cab596adf5589e43240dfc381
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Sat Jan 19 12:16:55 2008 +0100
-
- Removed empty *excludes.txt for better searchability
-
- `find -name "*excludes.txt" -size 0 -exec git rm {} \;`
-
-commit 9a2b1e6232f36c7a1508085b4606e25fbcf3cb4a
-Author: Jonathan Younger <jonathan@daikini.com>
-Date: Fri Jan 18 23:19:16 2008 -0700
-
- Additional String#% platform specific formatting failure fixes
-
-commit aa32d6fcbed79b9e2afedc00f429ea78f5c540d3
-Author: Jonathan Younger <jonathan@daikini.com>
-Date: Fri Jan 18 22:12:23 2008 -0700
-
- Fix String#% platform specific formatting failure
-
- Darwin and FreeBSD return a different string format than other platforms,
- so a different expectation is needed to match the appropriate format.
-
-commit c64dfd449dc89ec0016f14afd7f85522dbaa4148
-Author: Jonathan Younger <jonathan@daikini.com>
-Date: Fri Jan 18 21:05:44 2008 -0700
-
- Moved String#% specs to ruby/1.8 and fixed to work with rbx and MRI
-
-commit e5e7f44983f1dbbc79726776b56a9cc7cb910e9f
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 18 19:53:50 2008 -0800
-
- Updated IO excludes.
-
-commit b8b549dbc1aaf63e15717c3902d4485c97f845f7
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Jan 18 21:40:01 2008 -0600
-
- Add regexp matching for output matcher and enable warning specs for syswrite.
-
-commit 004bd58b597034cbe734d9b7da318135a689190f
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Fri Jan 18 21:06:38 2008 -0600
-
- implement some of Marshal.load
-
-commit 2c52db8022f060866d839992aaa6bff0f61963cf
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sat Jan 19 11:21:55 2008 +0800
-
- Fix UnboundMethod#bind
-
-commit a5680db20cf998f0db292e3b9aa69ed74fb19b10
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 18 17:49:44 2008 +0800
-
- Implement UnboundMethod#==
-
-commit a1de7b0f405830f6bfe8000c051f4445135d8f63
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Jan 18 20:54:11 2008 -0600
-
- Added some specs for sysread/syswrite on a file and p flushing to File.
-
-commit e7bc994d96398519ca205e87dec8e775bb0e67c6
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Sat Jan 19 01:31:46 2008 +0100
-
- Fixed File#utime segfault
-
-commit 9887c6135e9353c3094dcf3c76d8e788b98f2bed
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 18 22:00:10 2008 +0100
-
- Added Time#strftime specs for '%U' and '%W' patterns.
-
-commit 0338fb5adb325e58d1ce61bccc9310fc7284e235
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 18 20:35:23 2008 +0100
-
- Added two testcases for String#% rubyspecs ('x', 'X').
-
- There was a bug in JRuby's sprintf, which wasn't
- detected by rubyspecs.
-
-commit 97db9fb72d6205227d61d92ed3153331b2328f97
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 18 10:50:00 2008 -0800
-
- File#utime spec. Some cleanup of File#open specs.
-
-commit 10647cf8abfd0ea7a87d39978a22f68fdfa9fbd6
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 18 17:08:04 2008 +0100
-
- Wrapped 3 IO spec tests into fails_on :jruby.
-
- Because these tests just break the spec run completely.
-
-commit cf6195eeabe382c4267e295ab786acedaed89050
-Author: Jonathan Younger <jonathan@daikini.com>
-Date: Thu Jan 17 21:55:48 2008 -0700
-
- Fix specs that use `pwd` to use -P option so that symlinks are resolved
-
-commit 1b79705fb965ecd6fc897b6bf14c605d8325dabe
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Jan 18 15:57:46 2008 +0100
-
- Added IPAddr specs by manveru. Closes #262
-
-commit f05b96b33970e3f08da5c8992f7c6cb710649f42
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Fri Jan 18 02:23:15 2008 -0800
-
- Fix spec for IPv6 environments
-
-commit 2007019ebad7974d7a54e6d599320675548313f0
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 18 17:39:09 2008 +0800
-
- Fix UnboundMethod#inspect to use regexp
-
- * Also aliased UnboundMethod#to_s to UnboundMethod#inspect
-
-commit c47b473b99b59074673adb7e8d50a250e34436e7
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 18 17:37:29 2008 +0800
-
- Use a regexp to match the inspect output instead of deviating on rbx
-
-commit 8dc2a2b3115a49a15ed931301b1999560ee27db5
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri Jan 18 01:05:14 2008 -0800
-
- Fix up specs and finalize LongReturnException
-
-commit 7c30ca7337b56a4194eb58952f74662e222b7707
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 17 23:23:27 2008 -0800
-
- Add support for return in a block obeying ensure properly
-
-commit c06fc665c6bf5898163f2854b93d62b8b314216e
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 17 21:20:42 2008 -0800
-
- Changed Exception#backtrace to return an MRI compatible one.
-
- * Exception#awesome_backtrace returns an Rubinius Backtrace
- instance, as Exception#backtrace used to.
- * Added templates for Backtrace specs.
- * UnHACKed lib/test/unit to use the #backtrace as expected.
-
-commit a29f35c5a45776f10132c3ce0ef058b1e98a4f75
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Jan 17 20:18:04 2008 -0500
-
- Guard failing Process.setpriority spec, add an exclude to CI
-
-commit 333d5c6920c01366c8b2887ecc7e33f775210c00
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 17 16:50:31 2008 -0800
-
- Specs and fixes for Class.inherited.
-
-commit ac90d87a69c19c441b854660105d21ed771989f0
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Thu Jan 17 16:37:31 2008 -0800
-
- One more step into the foray of bootstrap madness... removed useless 0 from lasgn nodes. needs full clean
-
-commit 0dbabefd081be4890d0d789a9c3ec122b9196cf8
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 17 12:00:55 2008 -0800
-
- Fixes to enable RSpec 1.1.2 to run the spec/ruby specs.
-
-commit 9bd611ff5c5b411518c2f4ce5d3cd4b93f4bcebe
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 17 08:25:24 2008 -0500
-
- IO#puts, #isatty fixes from Dan Lucraft, slightly modified.
-
- * The #puts spec exposed an issue with String#suffix? which Ifixed in
- fa9a6c which means IO#puts did not need to be changed.
- * #puts spec uses output_to_fd.
-
-commit 3f519a98bbc3a66d59884add5fcd98d5ca095149
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Jan 17 08:02:51 2008 -0500
-
- String#suffix? specs and correct behaviour.
-
- * The suffix can be the entire string, there is no need for it to
- just be a substring always.
-
-commit ca6fa9cd760b06827f4f953ff28e8baed357f447
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Jan 17 12:48:20 2008 +0100
-
- Additional Date specs
-
-commit 8541022ffc918879142ecb3707e977050f774ece
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 17 00:47:04 2008 -0800
-
- Added ?d, ?e, ?f to Kernel#test.
-
-commit e6f36980c2c94414e5c051b35d9ce403c492f1a2
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Thu Jan 17 02:18:25 2008 -0600
-
- Fix my oops; missing 'do' for the fails_on
-
-commit 44483d8e414f107b3202cc69b8cdfbbe1222ee33
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Thu Jan 17 02:07:57 2008 -0600
-
- Add a fails_on guard to IO#printf spec for JRuby; output dies otherwise
-
-commit 53a36c934ec44fad7e6d18424cb13b37496cf720
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 16 18:39:34 2008 -0800
-
- Updates to compiler and core to protect Fixnum#/.
-
- * Added compiler plugin SafeMathOperators.
- * Added very simplistic way to pass flags to the compiler.
- * Added -frbx-safe-math flag
- * Changed core Fixnum, Float, Bignum, and Numeric methods
- to use #divide rather than #/. Aliased #/ to #divide.
- * Updated Rakefile to send flag when compiling core.
-
-commit feb260b904d87487428b558f7b7e9ac0170c160c
-Author: Ryan T Mulligan <ryan@ryantm.com>
-Date: Wed Jan 16 22:47:02 2008 -0600
-
- very minimal SHA1 specs
-
-commit 511732d932d2fe934968c78b89cefa46e699b996
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Wed Jan 16 16:30:40 2008 -0800
-
- Moved old spec excludes to new location and deleted all old
-
-commit cae6bba077190e158ceee7b8991daf16fd8c55d1
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Wed Jan 16 13:36:19 2008 +0100
-
- Added more Date specs
-
-commit 75d49657f31091d37dfdba1fc5487164db861802
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Jan 16 15:58:42 2008 -0600
-
- more specs for TcpServer and TcpSocket
-
-commit b1d45cb0fdc573bfe5995456d846c11747d48b90
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Jan 16 13:31:33 2008 -0800
-
- Implement ObjectSpace.define_finalizer, using WeakRef.
-
-commit 4e8a0d264dc7d5a4866a1a1b83238bebb47e4ab6
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Wed Jan 16 21:51:52 2008 +0100
-
- Removed platform-specific specs in spec/ruby/1.8/core/signal/list_spec.rb
-
- There is not direct way to know if a signal exists or not, since it all
- depends on <signal.h>. In practice, there is no real risk for rubinius
- to miss a signal.
-
-commit 32537f8d3378154f7f52c278cd56a7d4159a3446
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 16 12:41:54 2008 -0800
-
- Added IO#printf, fixed Kernel#printf to use IO's.
-
-commit e7bccb3f38f6ace3cb25a9f227ab5f6b1d2be346
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Wed Jan 16 21:19:48 2008 +0100
-
- Signal.list spec now passes. bin/ci removed list_excludes.txt
-
-commit b3a6461af30f2c144b4ee65e8539c51291e0156b
-Author: Jonas Pfenniger <zimbatm@oree.ch>
-Date: Wed Jan 16 20:03:15 2008 +0100
-
- kernel/core/signal is no more platform dependent
-
- * Now publishing platform.conf with rbx.platform.signal.* (only using the ones
- defined in MRI's "signal.c")
- * Signal::Names is now published with those values on @after_loaded@
- * New method: Signal.list => Signal::Names
- * Added EXIT=>0 and CLD=CHLD exceptions (see "signal.c" in MRI)
- * Updated the corresponding specs for more details (on FIXME, please help !)
-
-commit bdbd712a5953f011f8d6f1142d50a452e1607f65
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Jan 16 13:42:01 2008 -0600
-
- updated Continuation excludes -- Kernel#callcc specs still bleedover
-
-commit 22d32d3461660ee7cd29760163b622fc94b6ea5b
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Wed Jan 16 01:55:21 2008 -0600
-
- apply Marshal.dump patch by Justin Bradford. #252
-
-commit 513de8ab67ab9c017285a48108ccceb185ebaf24
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Jan 16 16:44:34 2008 +1100
-
- Bunch of Debugger fixes
-
- * Debugger now has proper quit behaviour, which causes
- the debugger to remove all breakpoints, clear the debug
- channel, and resume the debuggee.
- * Fix singleton(-ish) semantics of Debugger; essentially,
- only a single Debugger instance can be instantiated at
- one time.
- * Added a bunch of specs for the above
- * Changed Rubinius::VM.set_debug_channel to accessor
- style Rubinius::VM.debug_channel.
-
-commit 2174009b215ce2f0445fc8df4711e7e6c64b0332
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Tue Jan 15 21:59:30 2008 -0600
-
- add Marshal.load specs
-
-commit ec002dd0f0daddedaa5241c4f8f6d85fad0e9768
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Jan 16 09:47:28 2008 +1100
-
- Move VM under Rubinius namespace
-
-commit 983c54400542a03535accf2705ae227ae58970dc
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Tue Jan 15 15:24:10 2008 -0600
-
- Added spec for File.new coercing filename using to_str.
-
-commit ff6a081de28711b0d8c1136e6e4272baf769043c
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Jan 15 14:29:43 2008 -0600
-
- since DRbObject is within DRb it should be a subdirectory but mkspec generated the wrong path to helper
-
-commit a48cbbd3f5da3c971a215423b3e27b058de04196
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Jan 15 21:15:09 2008 +0100
-
- Add more Date specs
-
-commit 9de289f1bbae86b12bc383e7e535de404f8aaa5f
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Tue Jan 15 14:58:31 2008 -0500
-
- Add a servent class to StructGenerator for Socket.getservbyname
-
- Also, add Socket.htons and Socket.ntohs for byte order encoding
-
- And complete Socket.getservbyname along with specs.
-
-commit d9e37ff3c0f975a418fafbc7163ee1a9717dd92b
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Wed Jan 16 03:31:05 2008 +0800
-
- Fix Proc#[] calling the wrong #call method
-
- * Re-aliasing in Proc::Function because aiases don't follow subclass
- methods
-
-commit 2273c919e80ab7186e3139941dc4d73a292bcd2d
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Jan 15 19:30:23 2008 +0100
-
- Add add and minus specs for Date
-
-commit 1325e22c11c48c366d9f0387823de5941b59df66
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Jan 15 16:35:23 2008 +0100
-
- First specs for Date object
-
-commit a3b76d162e58e75b4523151bb6911c840db8319f
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Tue Jan 15 12:58:14 2008 -0500
-
- Implement Socket#pair (and Socket#socketpair) with corresponding spec.
-
-commit 836f1cf828ab62606a6b0e2f7313228b7482dcbe
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Jan 15 11:47:11 2008 -0600
-
- generate spec files for DRbObject
-
-commit ef99f25be36f6ccd33b297bed14c1175847f1ecc
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Jan 15 11:31:08 2008 -0600
-
- generated spec files for DRb with a basic spec for DRb.start_service
-
-commit 9637cf1e77efd1a3b53e6c4d82a7c7afe8509621
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Jan 15 18:48:09 2008 +0100
-
- Eliminate stdout from IO#dup spec runs.
-
- At least, under JRuby it was printing things like:
- "No such file or directory".
-
-commit 30a2fce2a4fd7e840586ce8ae390ecb632c8bee0
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Tue Jan 15 23:00:32 2008 +0800
-
- Implemented Dir#pos which fixes #pos, #pos=, #seek, and #rewind specs
-
-commit 013ab2e88ecd8d887c6a0009e7f8d2add4849143
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Tue Jan 15 22:52:26 2008 +0800
-
- Revert "Updated CI excludes"
-
- This reverts commit 15d1c7674496a99bf1d5ec42420864b22bf1569a.
-
-commit 15d1c7674496a99bf1d5ec42420864b22bf1569a
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Tue Jan 15 21:50:55 2008 +0800
-
- Updated CI excludes
-
-commit 18470055d83a43c3371609aaac4471767adb3b1b
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Jan 15 04:32:54 2008 -0800
-
- Make TCPSocket.new work. Use socket library names for familiarity.
-
- Make inheritance hierarchy of sockets better match MRI.
-
- Add syscall names to Errno.handle checks.
-
- Spec less of the socket library.
-
-commit bd34303986a068b40cce1366c85ea288fc24a3f5
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 14 23:55:38 2008 -0500
-
- Regexp subclasses work now. Documented Regexp.new.
-
-commit 343acee55519fc97a35a9d50e8bdcfd679d432b7
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 14 23:49:47 2008 -0500
-
- More Regexp.new specs.
-
- * Subclass initialization verification.
- * Multibyte options are case-insensitive.
-
-commit 758a468ffafdeea78016dbbce78f21e19f6735f6
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Mon Jan 14 18:22:32 2008 -0800
-
- Fixed require modifying LOADED_FEATURES even if require raises an exception
-
-commit 5c8ff74b64f7ec6bd4c413b0e0e93334dff009ca
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 14 21:57:19 2008 -0500
-
- Fixed Regexp#kcode specs.
-
-commit 34867cc1f1f3b7ac3145fb926491c0dc44629312
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Mon Jan 14 22:41:58 2008 -0800
-
- Add Socket::getaddrinfo. Raise SocketError appropriately.
-
-commit e2009a38a8e1ef0dff6394b92a677f3120280f72
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Mon Jan 14 22:39:55 2008 -0800
-
- Remove platform-specific code, remove spec of socket library behavior.
-
-commit 5afa1c34808c68c17bc02f5f76c42d64efdd7dd2
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Tue Jan 15 00:32:14 2008 -0600
-
- Modified retry-in-rescue example to test nested blocks and be clearer.
-
-commit 17fd0cb781ec90d268668c5678e1135eb5f6e323
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 22:28:46 2008 -0800
-
- Added Module#autload?.
-
-commit 96ca83312d1b5a1e38e25f94504f6f69a137b96d
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 21:50:37 2008 -0800
-
- Updated CI excludes for language.
-
-commit ef4f49de672d40f43f53dadff1aa8fdbcafe1d45
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Jan 14 21:37:23 2008 -0800
-
- Fix specs for dregx change, fix regexp for specs
-
-commit 5cd2ef2a173394910249d93d8ef433d220f2d9a9
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Jan 15 16:32:15 2008 +1100
-
- Fix breakpoint specs
-
- The breakpoint specs were interfering with one another,
- due to the fact that each was modifying the bytecode for
- a fixture class that is compiled only once.
-
- Workaround this by saving off the bytecode and resetting
- before each test.
-
-commit 29bf88b07f87182d94fcf7c550724efc07067239
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 20:00:27 2008 -0800
-
- File spec/data/critical.txt is empty! Congrats to everyone!
-
-commit 8082760cc2215742464a9846295ec4a8a0c49244
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 19:37:33 2008 -0800
-
- Removed Module methods from critical excludes.
-
-commit d075c115087c001d0d35562aeeea21efadc5e3b6
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 18:53:46 2008 -0800
-
- Added not_compliant_on :rbx for class variable specs that use Fixnums.
-
-commit 23f1b523da2478f2ad962f0045dca3e7034f9b56
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 18:16:46 2008 -0800
-
- Multiple fixes for #class_variable_get/set. Updated CI excludes.
-
-commit dbc5675058aa426dbfbbf7489d5393819edb16f8
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Jan 14 16:42:27 2008 -0800
-
- Fix attrasgn usage to pass specs
-
-commit 3e250999d6f1a7fdaf2bb5cd169a1024e2ab5ddc
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 16:07:08 2008 -0800
-
- Removed leftover excludes for compiler[12].
-
-commit a2b8b5511e79b47fa7777e716ee16511fdec3fd4
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Mon Jan 14 16:47:21 2008 -0600
-
- Remove the goofy Hash#delete spec and replace with two others.
-
- The old version of this example depended on individual hash buckets having a
- specific ordering, which overreaches a bit. The new version, while a little
- cumbersome, should work correctly regardless of hash implementation or hash
- and bucket ordering.
-
- I also moved out a few lines that were unrelated to this example into a
- separate one.
-
-commit 67d858885f1841e9c9aa295150da3c472949198d
-Author: Gregor Schmidt <ruby@schmidtwisser.de>
-Date: Mon Jan 14 14:57:53 2008 +0100
-
- Passes Module#extended specs by added extended method to module and adding a call to it in Object#extend
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 302ba965def902ccc5d3e97ed6bd5841f09d8f00
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 14 14:14:08 2008 -0800
-
- Philipp Brüschweiler's patch for String#%, #242.
-
-commit abaf2efa9e467bb7b5ef3b53b8490f1e056a832e
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Mon Jan 14 16:59:23 2008 -0500
-
- Another round of socket specs, and add a Rake StructGenerator to find sockaddr_un if it's available
-
-commit f5d0e435023a80bcc4c101a8d3ab9fc056a14c80
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Mon Jan 14 15:52:47 2008 -0500
-
- More socket specs
-
-commit 7bbc927a9d8a6f9202025be62a3db861ced3216f
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Mon Jan 14 14:58:34 2008 -0500
-
- More socket functions and specs.
-
- Namely, this implements a Socket::SockAddr_In class that is a FFI::Struct around the
- sockaddr_in C struct. This gives us a better ability to inspect what's going on in the
- struct from the Ruby side of things.
-
-commit f351c6d3d8831705f0398abdae240abba9252a75
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Mon Jan 14 11:09:04 2008 -0500
-
- More socket specs update
-
-commit cb8ce936394cafa00f77008083bccf9cded59f28
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Jan 14 14:39:41 2008 -0500
-
- Split process/constant expectations into Linux and BSD sections
-
-commit 0964d53edd80367611f63cd6eb4b294ec898cc8d
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 14 10:04:53 2008 -0500
-
- Revert IO#dup spec to unmask errors, removed FileUtils dependency.
-
- * Any errors occurring in specs should generally be raised normally
- so that any potential problem or spec deficiency is exposed.
-
-commit 04f542e928c5fa0df460d8f11b4d87e008fa343f
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Jan 14 13:36:49 2008 -0500
-
- Update Process::Constants to fetch values from RUBY_CONFIG
- Update process/constants_spec so that it passes on MRI as well
-
-commit 0ad02b57fd040196d11662bd1ab9b259dc2ce6d2
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Mon Jan 14 12:23:20 2008 -0600
-
- squash Marshal.dump bugs
-
- * fix order of evaluation problem
- * put more objects in links and symlinks hashes
-
-commit ed98b9a14459b011f97fee5c781410c4d413ed9a
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Jan 14 17:36:00 2008 +0100
-
- Updated Arry#pack specs to guard for always big-endian JRuby.
-
-commit 550f07dc7551573a975183209ba8904fdbd62607
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Jan 14 15:57:04 2008 +0100
-
- More robust cleanup in IO#dup specs.
-
- Without it, mspec against JRuby was reporting EIGHT
- failures, while only 5 tests are actually exist.
-
-commit 1ea4f82183190c4c87da48c381f1db417c7403ac
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Mon Jan 14 09:26:36 2008 -0500
-
- Updated some socket specs
-
-commit e20ab7ea377cd39209011b44204d2688b53611c5
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 14 02:23:26 2008 -0500
-
- Fixed Regexp.new kcode setting, improved Regexp specs.
-
- * Regexp kcode can be upper- or lowercase.
- * More robust Regexp#options and #inspect specs.
- * Updated Regexp excludes.
-
-commit cc71f359aa65101d2c00cfbb0c396b7cdc697ef2
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Jan 14 01:25:21 2008 -0800
-
- Improve bytecode performance a tiny bit, fix Kernel#`
-
-commit c561368c03c605de41746fac2ce5a6386fcf4f54
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Mon Jan 14 03:17:15 2008 -0600
-
- Quarantine a suspicious TCPSocket.new speck failing on MRI on OS X.
-
-commit 71a9cf2afbbe6903b8d652b3ee201957e0b0c633
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 13 22:58:16 2008 -0500
-
- Finished IO#print specs.
-
-commit ff75b95a690051736f49a9a113d21027f7f03e92
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 13 22:44:21 2008 -0500
-
- IO#dup and specs.
-
-commit 02f1c03f4df3327ce1ddd20e2249a5e9830627a0
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 13 23:11:48 2008 -0800
-
- Justin Bradford's patch for Float failure, #237.
-
-commit e43c148954ad609c438e5a4f14811c0349239374
-Author: Matthew Draper <matthew@trebex.net>
-Date: Fri Jan 11 21:35:57 2008 +1030
-
- Kernel#Integer is very fussy about the strings it accepts.
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit adad84f7a26bf40809366f2f7b6acfc61dcfefc2
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Mon Jan 14 00:31:12 2008 -0600
-
- Class.inherited gets invoked regardless of visibility
-
-commit c746fad52e9503d04c3cf65de979b0a5a9f9e495
-Author: Matthew Draper <matthew@trebex.net>
-Date: Mon Jan 14 10:25:58 2008 +1030
-
- Many of Kernel's methods should be module_functions.
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 0b8a4bfefaed3179f96721fdde35e32ed8ff7263
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 13 21:43:45 2008 -0800
-
- Update CI excludes for Regexp. Remove empty CI exclude files.
-
-commit 89a87edbc61a877621c6f43266000aff32e92ae7
-Author: Warren Seen <warren@warrenseen.com>
-Date: Mon Jan 14 07:12:13 2008 +1100
-
- Fixes visibility of methods passed to Module#module_function
-
- * Make instance methods versions of functions passed to Module#module_function private
- * Correctly identify visibility in error message raised in Module#set_visibility
- * Added specs for module_function
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 25d6fa558f88732d1aa28c68b0eb7c9910366243
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 13 20:42:52 2008 -0500
-
- Updated Regexp excludes.
-
-commit 69e200276898f1c9208be527bdc64c318c56f86e
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 13 20:24:42 2008 -0500
-
- Shared spec for Object#dup and Object#clone.
-
-commit 8a6fe609224c126bcf86987edd3f0690fc9e45ff
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Jan 13 18:19:56 2008 -0500
-
- VM calls private hook methods now. Object#dup and #clone specs.
-
- * Object#dup and #clone have rudimentary specs which also partially
- confirm the private hook fix through #initialize_copy.
-
-commit 84773b6ba63ea6f715dcc4e99e0a8a2e2b739152
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Jan 11 10:46:15 2008 -0500
-
- Specs for Regexp.{new,compile}, updated excludes for same.
-
-commit 6c1603723bba7d58203aa9b03bbf92b4900e53d1
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 13 18:49:40 2008 -0800
-
- Numerous fixes for File::Stat.
-
- * Implemented readable(_real)?, writable(_real)?, executable(_real)?.
- * Implemented a number of helper methods like rowned?, rgrpowned?,
- superuser?, rsuperuser?. Made these private.
- * Implemented owned?, grpowned?.
-
-commit d1b05e0bf98a3cdfda8a3d2398e78035a49c0c66
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Mon Jan 14 12:25:41 2008 +1100
-
- Deprecate meta_send_stack* opcodes
-
- The code path for these opcodes is almost identical to
- send_stack, and no measurable performance improvement
- comes from using them.
-
-commit 154fe5e1faad94f371c51a979240a6d7f5cd8909
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Sun Jan 13 20:07:12 2008 -0500
-
- Implement BasicSocket#setsocketopt for String optvals, and add a spec for it.
-
-commit c21636d6b2502db344049e7dc62d42ff8c18b040
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Sun Jan 13 19:34:50 2008 -0500
-
- Add specs for BasicSocket#getsockopt
-
-commit 1584f41148b8d8967df4c3ee6376b59919cb7db3
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Sun Jan 13 19:24:58 2008 -0500
-
- Add Array.pack for i, s and l arguments.
-
-commit 7131e187e19bf0889f8ece802495865f7b3f1e5c
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Sat Jan 12 13:55:20 2008 -0800
-
- Cleanup String#split, add edge case check
-
-commit 4ff46602c8a54a61697bb8d9eaa9ae89e56f7abe
-Merge: 1c95721... 908ccff...
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Sun Jan 13 14:49:48 2008 -0500
-
- Merge branch 'socketspecs'
-
-commit 908ccff0a854038372dad0780e1de35727e2d657
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Sun Jan 13 14:49:17 2008 -0500
-
- Some TCPSocket spec mods
-
-commit 1c95721bd873c4b30c187bfa7673cd7e3568a0fb
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 13 10:20:43 2008 -0800
-
- Fixed File::Stat specs to output method name correctly with -f s.
-
-commit acb7505d41aa789157e50962253e686827a702d5
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Sun Jan 13 12:07:06 2008 -0600
-
- update CI excludes
-
-commit c8db419ae06e9642b346e1bcae99367f3b72845f
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Sun Jan 13 11:55:50 2008 -0600
-
- squash bug in Marshal.dump
-
- symbols need a separate links hash
-
-commit eb953ae2c3fdeac4ae13b5461246b9f51b0f39cc
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Sun Jan 13 09:40:39 2008 -0500
-
- Make the spec text more verbose
-
-commit db013bc06cef2dea4b77a215d4437e2172b391b6
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Sun Jan 13 09:04:08 2008 -0500
-
- Commit an updated spec that shows the failure on rbx and passes MRI,
- w.r.t. opening a module and aliasing a private module function from that
- module.
-
-commit 759a9f8bd70ead9b5d2fc67b3872e3bf3bd34001
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 13 01:45:07 2008 -0800
-
- Updated CI excludes for File::Stat.
-
-commit 107feb74eaf01c09d8c5bd14ac29e53900a5ed26
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 13 00:38:00 2008 -0800
-
- Modified File, File::Stat, FileTest specs.
-
- * Added templates for File::Stat specs.
- * Added shared specs for some File::Stat methods.
- * Altered toplevel File shared specs to take the name
- of the constant to enable File::Stat to use a fixture
- proxy but still have the correct name show with -f s.
- * Split out specs for missing files because File.[l]stat
- behaves differently than e.g. File.file?.
-
-commit e1a13f7ecfe7f2d18fd6ac20dd8c63cbd6d11855
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Sun Jan 13 02:26:09 2008 -0600
-
- implement more of Marshal.dump
-
- obj.marshal_dump, IO.write, depth limit, exceptions
-
-commit bc070232eab1bfa5d294897487339d259a406e74
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Sat Jan 12 15:16:21 2008 -0600
-
- implement more of Marshal.dump
-
- Float, obj._dump
-
-commit ad7a67ed5a3a1399773dda74c4688e9b00c8f9aa
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sun Jan 13 01:46:36 2008 +0800
-
- Update CI excludes for Process.initgroups
-
- * It was affected earlier by the Enumerable lambda/Proc-arity issue
-
-commit 7b7a1e3e4712f35688823543b7a7c3c25405ef77
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sun Jan 13 01:40:22 2008 +0800
-
- Fix implicit block in Enumerable not passing the arg check in Proc#call
-
- * Changed instances of lambda to Proc.new and arity once again
- returned the correct value. Will investigate, but until then, this
- passes.
-
-commit d9c21aaa18044bd54ed3b1f6ec5daacf9bd250fa
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sun Jan 13 01:02:00 2008 +0800
-
- WIP Fix block argument checking
-
- * Passes all the proc/lambda call specs
- * However, specs for methods that add implicit blocks like
- Enumerable#all fail because their arity is somehow 0 - excluded for now
-
-commit 3d400bc8a91a793f49dcf5655dc28e6141d999d0
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sat Jan 12 20:03:26 2008 +0800
-
- Update CI excludes and add Module#class_variable_get to critical.txt
-
-commit 6bf7b8616837649ddd2c1435a54c86ed30910985
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sat Jan 12 19:27:12 2008 +0800
-
- Move custom classes for NoMethodError specs into fixtures
-
-commit 10cc61bb816ae67a7fad5b135f66d263d7ee07b1
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sat Jan 12 19:20:27 2008 +0800
-
- Swap the protected/private method calls around in the NoMethodError spec
-
-commit 6b2e66d3f9222b52cdae42b57206363ad47949e2
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sat Jan 12 11:51:28 2008 +0100
-
- Corrected Module#alias_method spec.
-
- Now it should pass on both MRI and JRuby.
-
-commit 67f74a936655b72c689d09c77d9fbe9d7194a0a0
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sat Jan 12 17:50:22 2008 +0800
-
- Fix proc/lambda/Proc.new arity
-
-commit 03440114d5e3f07111cdcae3657258cae4c803e7
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 11 13:24:26 2008 +0800
-
- Fix Kernel.Integer parsing of invalid String
-
-commit 598598c10c66de38b52a8092cdd2fa99604eda6e
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Sat Jan 12 00:21:22 2008 -0800
-
- Clean up expectations to use a common list.
-
- Update excludes for other things using shared glob specs.
-
-commit 55aa5a1f10655618e45d0ec84502cc13c982227e
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Fri Jan 11 23:31:45 2008 -0800
-
- Specs for File.fnmatch handling of Regexp specials.
-
-commit 7c0dc7edfcdf4948047ba051b0cbed7ba761f1dc
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Fri Jan 11 21:57:10 2008 -0800
-
- Dir.glob support for {}.
-
-commit 9a097fe5634c1109919d1e120b1276827371c332
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Fri Jan 11 19:42:31 2008 -0800
-
- Exclude {} specs for WIP Dir.glob
-
-commit ccdc6f5ae5fabbd0d2c32072811e2ecf7cca8987
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Fri Jan 11 21:40:04 2008 -0500
-
- In MRI, you can alias private module methods. Not so here. This spec catches it.
-
-commit 8b402d1e32dc283124375374532024f6cfe7020d
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 11 17:35:21 2008 -0800
-
- Added toplevel shared specs. Converted File, FileTest specs.
-
- * spec/ruby/1.8/shared is the directory for sharing
- specs across multiple classes.
- * Added methods for FileTest
-
-commit c6aea2e10d7a4d0ee14175d5b79894e1e11699b1
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 11 15:59:34 2008 -0800
-
- Converted File/FileTest#exist(s)? to toplevel shared specs.
-
-commit 06a5d8a3d5874303a71e4e9b939b44c204041edf
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Fri Jan 11 17:39:39 2008 -0500
-
- Fix failing specs in udpsocket/open_spec.rb
-
-commit 530e40005d09140fdb55608890f0994f3a48d8be
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Fri Jan 11 13:11:58 2008 -0500
-
- Observer specs
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 0907a20d2bad2207be8e937c403c49634f3a23b6
-Author: Caleb Tennis <caleb@tarknology.com>
-Date: Fri Jan 11 12:24:44 2008 -0500
-
- Add observer to lib and base-spec file
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit ec0ff1dfa1ee9de38d35537bec5071f6bb31cf7f
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Fri Jan 11 13:11:02 2008 -0600
-
- implement more of Marshal.dump
-
- Array, Hash, links
-
-commit 640e81394ad2385b535b08b535a4fca06a5f3eec
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 11 10:24:54 2008 -0800
-
- Added CI exclude for failing MD5#== spec.
-
-commit 3c238cc9f4b32f63bc681bd64a507fc2ff49b017
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 11 10:00:50 2008 -0800
-
- Converted Socket specs to use subdirs for subclasses.
-
-commit 2b98950eaa33b532fcef079b0997f9793228c608
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Jan 11 09:23:23 2008 -0500
-
- Specs and implementation for IO#print. Closes #222.
-
- * IO#print without arguments spec excluded due to a lack of a lower
- level output matcher. To be added shortly.
-
-commit d65c8c6899cf8e4a1fa56486cf417451e0c7fce6
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Fri Jan 11 19:19:56 2008 +0100
-
- Fix String#* spec.
-
-commit 481e075bfeb9f8fb3bd4db645129a463307de09e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 11 17:41:07 2008 +0100
-
- Improved digest/md5 specs a bit, some new test cases.
-
-commit 67f48236da3d114638310ab37bcc706719bf7fcd
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 11 11:59:06 2008 +0800
-
- Updated Method's specs as Method#inspect and #to_s deviates on Rubinius
-
-commit 76846154773a87bc8d99c97e91250abda22f6378
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 10 19:24:57 2008 -0800
-
- A bunch of fixes found while working on Socket
-
-commit f69613740662d3ba4f85573c6c860a5987b29765
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Fri Jan 11 00:17:14 2008 +0100
-
- Fixed Time object for throwing errors where appropriate
-
-commit 9396386f700646d0c55b9a7a75bc399dfe055d2c
-Merge: baae72c... 4d2e53e...
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Jan 10 22:39:24 2008 +0100
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit baae72cc47c9c1f41c3478732b7bbfdfe514024a
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Jan 10 22:39:11 2008 +0100
-
- Fixed Time#xmlschema conversion
-
-commit 4d2e53e7376080e42b84dca486debcf4f153f32f
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Thu Jan 10 15:17:00 2008 -0600
-
- implement more of Marshal.dump
-
- negative Fixnum, Bignum, Regexp, Struct
-
-commit abdbcd70bba99149b7391effa48452971407b4d2
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 13:18:52 2008 -0800
-
- Annotate Rubinius spec as non compliant.
-
-commit 2a2b3a016bfd70eb8cd14b6a043d59f119e0ad7c
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Jan 10 21:52:18 2008 +0100
-
- Re-added divmod specs for Ruby/JRuby, with comments.
-
-commit 2f079e416e4389b091c8c9b5522d49c6f356c6c9
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 12:29:39 2008 -0800
-
- Updated Bignum#divmod specs.
-
-commit 7a5c79415f2e6555bf2c69e416f6d3189f2e0c3e
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 10:46:05 2008 -0800
-
- Simplify wording of VM.coerce_to_array specs.
-
-commit abc1237a0c96ecd77baee6ecbcf71a7bba338139
-Author: Ryan T Mulligan <ryan@ryantm.com>
-Date: Thu Jan 10 12:35:23 2008 -0600
-
- md5 is now fully 1.8.6 MRI compatible
-
- * MD5 digest specs
- * Specs pass on MRI and RBX
- * Platform::POSIX.memcpy hooked
-
-commit 9f991bd850c51cd624169b51768c2215d4b56edb
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 11 01:35:15 2008 +0800
-
- Method#bind raises TypeError when binding a method from a non-descendant
-
-commit fc029ab13ded7eeb1ba838b99f00e2f14e232d65
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 11 00:12:44 2008 +0800
-
- Implement that Precision.induced_from raises TypeError in certain cases
-
- * For case when mixer class doesn't define it's own induced_from method
- * Update CI exclude for precision
-
-commit 35d1a7bc3694bdcc327dd5ac89ca0f261e0bd705
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Jan 10 16:57:38 2008 +0100
-
- Added one more Bignum#divmod testcase, known to fail on some implementations.
-
- In fact, this test case fails on Rubinius and JRuby.
-
-commit 955676613f5e38cf029998e2712013e4575dd03e
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Jan 10 16:12:37 2008 +0100
-
- Changed spec failing on MRI
-
-commit f7b4f3fe02833081cc7f40c0feebbef0e5012f10
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Jan 10 15:58:23 2008 +0100
-
- Fixed Float#divmod
-
-commit aff6e1fc1a16eb9e7b7e207ebc2234154d891a92
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Jan 10 22:53:25 2008 +0800
-
- Converted VM specs
-
-commit 969c0d8e0dbf43caa3999976cf259c623ff05ff1
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Jan 10 22:50:17 2008 +0800
-
- Convert Options specs
-
-commit cc7c9dcb6697dea991342328a9b00fa01740e809
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Jan 10 22:28:42 2008 +0800
-
- Replace example blocks using 'specify' with 'it'
-
-commit 7a5fa30a71072346abda17cdb79c2aa3b3922239
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Thu Jan 10 15:27:49 2008 +0100
-
- Fixed Bignum#quo
-
-commit f2aafe4a352fd884d217b0361d2e7e617f58ebd5
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Jan 10 20:38:45 2008 +0800
-
- Converted Generator specs and generated new CI exclude files for it
-
-commit edb7e341d9b3ab1c3bdc08bc57ec55d6bf8ace8b
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Thu Jan 10 19:33:53 2008 +0800
-
- Remove generator_spec.rb because of spec conversion
-
-commit bb4de530c5980f0205875bdb5548e40a22ef6a62
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 01:45:47 2008 -0800
-
- Updated CI excludes for library because of spec conversions.
-
-commit 61a66f69fe3a94d9ad5568ee2dd846cfc0b5211a
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 01:45:17 2008 -0800
-
- Converted Socket specs.
-
-commit 167e05039eeeeb959f7aab1f3611268170037296
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 00:59:20 2008 -0800
-
- Converted YAML specs and added template files for other methods.
-
-commit 027f568f79222cdee492f088edf8a2f14250635a
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 00:47:35 2008 -0800
-
- Converted ostruct specs and added template files for other methods.
-
-commit e964c9342ade9341518bc46cf998703a2c16aa2b
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 00:39:49 2008 -0800
-
- Converted ftools specs.
-
-commit 6263280187c81b0ee27893eae90f9d6a8a511b65
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 00:26:40 2008 -0800
-
- Converted Etc specs.
-
-commit 7b94284063222eef42b9b7ad0d1c820adabe210d
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 10 00:39:01 2008 -0800
-
- Fix a few more Kernel bugs
-
-commit 1c58ee51f388da0490a7815c9a1787d21e151aab
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 10 00:08:15 2008 -0800
-
- Fixed path for mock dirs in Dir specs.
-
-commit 320f7e7d3503d53216733f9b6eb75c387155ae5f
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 9 22:44:37 2008 -0800
-
- Converted StringIO and Singleton specs.
-
-commit 5a94a7c3b73103c99a337a089f9cf2c7e601d2bc
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 9 21:50:14 2008 -0800
-
- Converted stdlib Singleton specs.
-
-commit 12864a2057d1b6f5fa392f34d1fa3e8873a8c566
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Mon Dec 24 23:06:12 2007 +1100
-
- Initial commit of Rubinius Debugger
-
- * Created Debugger class for debugging Ruby code in Rubinius
- * Added Kernel#debugger convenience method to set a breakpoint
- and activate the debugger at the point at which the
- debugger statement is encountered.
- * Implemented the following debug commands:
- - h: get a listing of commands
- - b: list breakpoints
- - b <Method>: set a breakpoint at the start of the method
- - n: Step to the next line
- - ni: step to the next VM instruction
- - c: continue execution until the next breakpoint
- - l: list source code around the current breakpoint
- - d: decode VM bytecode around the current breakpoint
- - v: display local variables and their values
- - vs: display the contents of the VM stack
- - Anything else is evaluated as a Ruby expression in the
- context of the current breakpoint (so you can, e.g. change
- the value of locals before resuming, etc)
-
-commit 01a189cc3e52e8bcc6f22bcc5713e765bba84160
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 9 10:29:27 2008 -0500
-
- Object#is_a?, #kind_of? and #instance_of? specs.
-
- * Removed obsolete kernel specs for same.
-
-commit ab9645614bbbd0bca63c215819c12cc85a1507b1
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 9 21:35:39 2008 -0800
-
- Converted specs for stdlib Time.
-
-commit 733b069f11c7136175036154a45b924cf89cc8ff
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Wed Jan 9 20:01:09 2008 -0600
-
- update CI excludes
-
-commit 01e98dee4c24838ca518610443e43473ffdcf43c
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Wed Jan 9 16:42:07 2008 -0800
-
- Fixed block args for |*a|
-
-commit dc9c1d05dd5e0e828a77acc09220f5894a9aa453
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 9 16:04:11 2008 -0800
-
- Fixed Enumerator spec style. Updated YAML excludes.
-
-commit 0363685a97df83feb0d07f40a7a5c4d7a78e2a27
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Wed Jan 9 14:55:53 2008 -0800
-
- Spec for String#sub bug.
-
-commit 23052eb5f993c959fdb2b327895df08e0a344edb
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Jan 8 23:47:27 2008 -0800
-
- Implement { } matching for Dir.glob
-
-commit c90b2531d183e4534268d4699634828f29e803cb
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Jan 8 23:44:35 2008 -0800
-
- Spec File::Stat#blksize.
-
-commit 62d2a1809936a304c0cf0b94fd28f5b83932f58f
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Jan 8 22:47:37 2008 -0800
-
- Implement Dir.glob '{a,b}'
-
-commit d9430ad1a3e582e830a994a83d6f99e017bfbe4d
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Jan 8 20:56:37 2008 -0800
-
- Fix module X::Y; end; X::Y.name
-
-commit 1baa9468e0d89777fdb6f23e78e8ab510a19d534
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Wed Jan 9 16:16:35 2008 -0600
-
- incomplete Marshal.dump
-
- an evil ivar_as_index is added to Object to hold
- the names of modules that extend the object
-
-commit 85e98490fe45446e03801840d4628149f8977098
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Jan 9 12:26:19 2008 -0800
-
- Move compiler2 => compiler, and Compiler2 => Compiler
-
-commit 5aa5cc66e2b0196728c80eb394ec3b2dfccd77ae
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 9 10:30:42 2008 -0500
-
- Centralised specs for Object#=~.
-
-commit e1fe9f57c942460338a18e38f66fbf6feb69b4bc
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 9 13:23:59 2008 +0100
-
- Added few edge cases to Numeric#eql? tests.
-
-commit b8dfd675fad5e82ebfd50c737beb9a9b919a9c8b
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Wed Jan 9 15:52:18 2008 +0800
-
- Remove excludes for String#slice with the fixed send in place
-
-commit d7f69f17ac30f6b3161851e8df6a1e0a7694219d
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 8 22:42:43 2008 -0800
-
- A couple more fixups
-
-commit 055d7545c7046102cd92b7054992b1b47f711c4a
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 8 22:31:50 2008 -0800
-
- A boatload of fixes done while getting flexmock and rake running
-
-commit fd7c266e52c25d151214512cc801901813630d7a
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Wed Jan 9 11:49:02 2008 +0800
-
- Removed last array exclude due to fix in 02e6e28
-
-commit 690626f43f7b4ce888de081033eaadfba543acff
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 8 18:58:50 2008 -0800
-
- Removed subtend specs from CI run. Increase File#mtime tolerance.
-
-commit dec4f25a47a9a962b77a97dea47985fe17421e5f
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Jan 9 13:39:51 2008 +1100
-
- Specs for stack usage
-
-commit d699f6605db86e6f6bc61d0f3a79fc1535816c70
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Wed Jan 9 10:38:06 2008 +0800
-
- Add spec to illustrate Numeric#divmod bug in MRI and rubinius (excluded)
-
-commit 8a55f3047dc0fd502bb632dc9f5bdb9668b180fe
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 8 18:32:18 2008 -0800
-
- Subtend CI exclude to (hopefully) fix the build server runs.
-
-commit 33bde75b57a88baa850edccea382e1130ed586da
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 8 17:19:30 2008 -0800
-
- Added spec/compiler2 to CI. Added CI excludes for compiler2.
-
-commit 6964fc5644fddeef2238591674786f035d9db842
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Tue Jan 8 17:19:20 2008 -0800
-
- Fixed up against evan's changes. ping
-
-commit 9423d1e8e9ed91fb9f0934b939899c753972cee1
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue Jan 8 20:11:54 2008 -0500
-
- Fix warnings encountered when running compiler2 specs under MRI
-
-commit d71ad87c14a4378ad2f01c49d90304c29be548f3
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jan 8 17:02:02 2008 -0800
-
- Fix a block_arg bytecode generation case
-
-commit 57199b5b468c0009512a479e13bbcf086d0d9526
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Tue Jan 8 16:16:07 2008 -0800
-
- Added new combo bytecode/runtime tests for block args
-
-commit 8a88699af73d272a61332e11d022bd629aa0460d
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Tue Jan 8 16:15:24 2008 -0800
-
- Improved inspect output for compiler spec objects. Added convencience methods for testing iter bytecode generation.
-
-commit 0dd9cd298cf735dc13cc2a2410ad6b5195790c11
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 8 13:19:21 2008 -0800
-
- Added subtend specs to CI. Updated subtend excludes.
-
-commit c07a5273844b32fe39090bb16d0e4ad59ecb0564
-Author: Dirkjan Bussink <d.bussink@gmail.com>
-Date: Tue Jan 8 21:28:48 2008 +0100
-
- Fixed given_spec? because of changed block_given? behavior
-
-commit 0f9a8dfee9dd1c7af1f8ba69497c8dd85539760a
-Author: Nitay <nitay@powerset.com>
-Date: Tue Jan 8 11:49:41 2008 -0800
-
- Fix setpgid spec using pipes to avoid race condition
-
-commit 09feb8677c529d04969e63d1ff4e3746037611cf
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 8 10:00:06 2008 -0800
-
- CI excludes for ruby/1.8/library.
-
-commit cda3d86fa44f1d62fe503e54f42c5c5df361b8f9
-Author: Benjamin Andresen <bandresen@gmail.com>
-Date: Tue Jan 8 08:22:49 2008 +0100
-
- Added explicit umask to File permission spec so it won't fail on
- non-standard umasks.
-
-commit 6df303e29d7fd04f4a1a0af379f4947854dd4635
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Mon Jan 7 23:20:22 2008 -0500
-
- Method#== and specs from Scott Taylor, slightly tweaked. Closes #137.
-
-commit 9b86b12be687bb29e25d0292786351d89a698adc
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 7 19:45:24 2008 -0800
-
- Added CI exclude for Array#pack.
-
-commit 17a746b0aa2c89aa9e61b8965d125e962748c20d
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Mon Jan 7 21:07:25 2008 -0600
-
- adds Marshal.dump and Float#to_s specs
-
-commit d5c19db2778e0cc3cbee5bf994b511448cb6bd78
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Mon Jan 7 15:31:11 2008 -0800
-
- Fix IO#pos=
-
-commit 21f44f03f0aa44b2f172f89ad27797c943dc618b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Jan 7 22:03:28 2008 +0100
-
- Remove non-needed std output from Array#pack test.
-
-commit 9ec20509ad6533876bbbc984052e6b7e05d2ea55
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Jan 7 21:50:46 2008 +0100
-
- Added Array#pack tests with empty array.
-
-commit 35170103bdba14d824780a41112f12034cb5c79e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Jan 7 21:13:47 2008 +0100
-
- Added Array#pack tests with 'w' pattern.
-
-commit 71b00e03ce2c6424fd262d737feb991835605da2
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Jan 7 20:46:58 2008 +0100
-
- Added Array#pack('U') test with negative values.
-
-commit 7be0813127635ea54909179c9553c5052c4a3d90
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 7 18:00:03 2008 +0800
-
- Add specs for Array.[]
-
-commit 0b762336e8c6040cbbe794cece64c56bfa46c296
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Sun Jan 6 23:35:35 2008 -0800
-
- Fix breakages, comment out at_exit spec (need a better way to test)
-
-commit 8896e459f1bffb7ae2da2f2aa708419e6316cb4b
-Author: Matijs van Zuijlen <Matijs.van.Zuijlen@xs4all.nl>
-Date: Mon Jan 7 14:03:03 2008 +0900
-
- Spec to demo failure of cases like "yield 1, *[1, 2]"
-
-commit 79da85bb1b1d63e617251b3a3ea6b0657c1e8ddb
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Mon Jan 7 13:04:22 2008 +1100
-
- Modified CompiledMethod#decode to use #local_names
-
- * CompiledMethod#decode now leverages new #local_names
- method to return the names of locals accessed via
- push_local/set_local etc.
- * Removed excludes, as all decode specs now pass
-
-commit 89c1026cecbb9fcd09a62139e2d28b24b5658c25
-Author: David Whittington <djwhitt@gmail.com>
-Date: Mon Jan 7 01:37:10 2008 +0000
-
- Added args to NoMethodError raised by Object.method_missing
-
-commit 0e4a02f0e2fede5d785b15a6b34c582c6ba586f1
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Sun Jan 6 12:43:14 2008 -0800
-
- Removed redundant Bignum#to_s. Moved private radix_to_s to bottom. Cleaned up to_s spec a bit
-
-commit 48446c40a759d60b7465d82b40f2911d0f7e444b
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sun Jan 6 13:45:22 2008 -0600
-
- Add some additional Math.asinh specs from JRuby.
-
-commit 7c81ca307cd01d3752a08487bc3742c8452d61c4
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Mon Jan 7 00:41:10 2008 +0800
-
- Add failing specs for Time.{local|mktime|utc|gm}
-
-commit 35816e118b327a150a2d26638f289633f5e51f16
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sun Jan 6 17:56:23 2008 +0800
-
- Add spec for Time.local to handle string arguments (excluded for now)
-
-commit f9f36f5bb99ddb62e15cb9a9ddd98414e3df93e2
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Sat Jan 5 23:44:33 2008 -0800
-
- Allow Regexp to match nil.
-
-commit e650c39627b81498fc97c51725f2ac1277870e15
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Sat Jan 5 23:38:52 2008 -0800
-
- Add some IO#read specs
-
-commit 20257ecce0d3161fae7ac78454f2b8672f2c1de3
-Merge: bc576b8... e549cc5...
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sun Jan 6 14:45:13 2008 +0800
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit bc576b8e26fdb43d050df4fe3ad5ed974ec85057
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Sun Jan 6 14:44:44 2008 +0800
-
- Fix handling of string-like second parameter to Time.local
-
-commit e549cc53a4905f21082a97cd6bcb279ace6d9eae
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Sat Jan 5 22:31:42 2008 -0800
-
- Don't shift more bytes than available in the Buffer.
-
-commit 71285a2a9a8d0d3e71c678872ff2a146d5b2dc16
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Sat Jan 5 22:53:51 2008 -0500
-
- Fixup the Process specs for setpgrp, getpgrp, setpgid, and getpgid.
-
- They no longer may unwarranted assumptions about the relationship
- between a progress group ids and process ids.
-
-commit 7b57b3ac6df612f81d60d3a31b030ba054b357a6
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 5 13:22:51 2008 -0800
-
- Patch from Brandon Mitchell for #195, Float#to_s bug.
-
-commit 70ddfd43fd727122f56e8bdfcf3febd1ac1b5479
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 4 01:01:11 2008 +0800
-
- Fix for Time#yday spec when Time.at might return yday+1 depending on tz
-
- * Wrapped Time.at in a with_timezone("UTC") for consistent results
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 7d4396e4e69fb7b046efdaaf87d1090a02c883a0
-Author: Kamal Fariz Mahyuddin <kamal.fariz@gmail.com>
-Date: Fri Jan 4 02:26:38 2008 +0800
-
- Fixed Array#fill behavior when passed index and negative count
-
- * Added additional spec when negative count is acceptable
- * raise ArgumentError when negative count absolute value exceeds index
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 8af2b55313eb55082df6a71cd3e6bd865f2901fc
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Jan 5 13:33:26 2008 -0600
-
- Save mtime during file creation to make mtime spec more reliable.
-
-commit 7043933af0475370462984c8d2df2b9301e58cfa
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 5 00:45:01 2008 -0800
-
- Updated CI excludes after spec description changes.
-
-commit 3d7650100ba1756a4d67be8044e31498ea96d88e
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 4 21:13:28 2008 -0800
-
- Multitudinous style cleanups in spec description strings.
-
-commit d54ed8791a74661adb87c938e92e037ece924c90
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Sat Jan 5 00:29:22 2008 -0800
-
- A real, working eval and friends.
-
- * Implements binding, eval, etc.
- * Passes all eval and instance_eval specs currently
-
-commit 02ad19ab4132bf5d3ae35c2e11fa1a963d1f1805
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri Jan 4 00:25:39 2008 -0800
-
- Fix a few more String specs, fix Integer()
-
-commit d67cfbcf4e7d35641de555ac1edd61b51780def8
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Fri Jan 4 19:16:43 2008 -0800
-
- Make class variables work with inheritance.
-
- Move class_variable* to Module.
-
-commit d79836e04d72796b723cdaab228871c87abe064a
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Fri Jan 4 16:26:21 2008 -0800
-
- Replace Struct with a Struct that can be subclassed
-
-commit 8efb042a9c160af9e9c177ca14aed220dedcc26f
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Fri Jan 4 15:41:43 2008 -0800
-
- Finished |*args| spec. Fixed MethodDescription and TestGenerator inspect methods
-
-commit 76cc487434f6cd9d60356560f1bbc3fba000397c
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Thu Jan 3 16:54:56 2008 -0800
-
- Fuck you git. Adds a broken spec to compiler2/masgn for splatted goalpost arg
-
-commit dd2697b602a732e3e00c131f54f9cc557ae0cbe3
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Fri Jan 4 15:40:50 2008 -0800
-
- Failing spec for case when with an empty body
-
-commit 22dcedebd484f655bba51399e38e83c5a14d4053
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Jan 4 18:31:48 2008 +0100
-
- Added Time#local specs with string-like second arg.
-
-commit 43ff733a3097fff44ba8a12334f20a1bf77a965f
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu Jan 3 23:54:34 2008 +1100
-
- CompiledMethod#decode now uses local variable names (if avail)
-
- * CompiledMethod#decode now looks in the bonus tuple for the names
- of stack and slot local variables
- * Moved compiledmethod specs to spec/core/compiledmethod
-
- Note: Compiler2 appears not to be setting the bonus tuple, so code
- compiled under it cannot decode local names at present.
-
-commit 06006ec2a053ae49b243fa0aa98fc71c2ea7a524
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 4 01:24:49 2008 -0800
-
- Updated CI excludes.
-
-commit dff2e75df3c371522b6a3ba4495d269bf793fe97
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 4 01:01:24 2008 -0800
-
- Updated CI excludes for Bignum.
-
-commit 569fa3b9fc81410ce9fe6568427f0a0bc65b7036
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 3 19:26:22 2008 -0800
-
- Updated CI excludes for String, Regexp.
-
-commit 7aedec383850eacad5db8248bfcea7615a3d1793
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 3 17:48:32 2008 -0800
-
- Fix up setrlimit/getrlimit on darwin
-
-commit d9aea8bba7276b53ca7c18b8625531be389d2cdc
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 3 16:40:09 2008 -0800
-
- Refactor $~ out as a global, into Regexp.last_match directly
-
- * Uses MethodContext to store $~ now, so it's method local.
-
-commit c19dde305fd751c14a1b4dc798557e0b63c08c8d
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 3 16:25:54 2008 -0800
-
- Clean up compiler2 specs
-
- * For is still broken, needs more love
-
-commit d02603a7e225d3b48ecf7899ea74768880aba7ec
-Author: Gregor Schmidt <ruby@schmidtwisser.de>
-Date: Wed Dec 12 16:56:11 2007 +0100
-
- Add default implementation of Module#method_added
-
-commit 7ba5d1478106e4e0f5fcf21c66029df2f38d7e2f
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Sun Dec 30 17:55:21 2007 -0500
-
- Unquarantine Process.kill specs.
-
-commit d68b380bdd2e0a0ec3bd968ffabd02f6e30a3aa1
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Tue Jan 1 22:14:59 2008 -0500
-
- Improve kill, wait, detach, and setpriority specs for Process.
-
- Restore any previously installed signal handler after the spec has run.
-
- User IO.read(1) instead of IO.getc since rubinius has it implemented.
-
- Fix a failing Process.detach spec uncovered by the raise_error fix.
-
-commit da7329d094b6ff437d37e6a1fcaf93883ac9172f
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Mon Dec 31 16:23:24 2007 -0500
-
- Add specs for Process.setrlimit, Process.getrlimit, and Process.setsid.
-
-commit 42bef2feb46434b0ea67bc3f93d941d587c2d9c9
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 3 12:46:57 2008 -0800
-
- Updated Process spec excludes.
-
-commit ca98172b8a923cce1691b0fcc5d2418417d82662
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 3 10:07:55 2008 -0800
-
- Update CI excludes for IO from Evan's fixes.
-
-commit cde20d6c32156e4fc06859f1e84414f81f5af69e
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Jan 2 23:40:59 2008 -0500
-
- Fixed #require specs.
-
-commit 06d99a2ac4be06b50848056b381c91531293a49e
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Jan 3 01:12:29 2008 -0800
-
- Add read buffering to IO, passes 100% of IO specs
-
-commit 86170283715371b5a87c0518f89c2b882a49bc93
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Thu Jan 3 01:21:52 2008 -0600
-
- Fix off-by-one on a few signal values. Doh!
-
-commit c7a64b10410308cec83077a66cda5859b326f296
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Thu Jan 3 01:13:27 2008 -0600
-
- Modify Signal.list spec to not depend on hash ordering.
-
-commit f2980d9584c08d873cf1646c281d083946bcbc6c
-Author: Nitay <nitay@powerset.com>
-Date: Wed Jan 2 14:36:56 2008 -0800
-
- Module#autoload:
- * raises a NameError when an invalid constant name is given
- * raises an ArgumentError when an empty filename is given
- * does not autoload when the specified constant was already set
- * registers the given filename to be loaded the first time that the Module
- with the given name is accessed
-
-commit e68bd05defe5ab749110af507c86769c9a036b25
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Wed Jan 2 19:04:48 2008 -0600
-
- Removing 'Range#initialize can't be called twice' spec.
-
- Evan agreed that these specs aren't useful, and I don't believe they're
- within the bounds of reasonable language specification since they're
- going around visibility and testing behaviors no sane programmer would
- ever be able to see.
-
-commit 1870720bac174feb627654f08c1749e1666c2acc
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Wed Jan 2 18:54:33 2008 -0600
-
- Fix inspect spec to guarantee the target thread is actually sleeping.
-
- A reminder for folks adding Thread specs: You *CAN NOT* know that a target
- thread is sleeping unless you are polling for status == 'sleep'. No amount
- of channel, lock, or state variable tricks will get around that. Please
- use polling if you want to guarantee a target thread is asleep.
-
-commit df3057a541862bbd1c5c72b8626bb591bb5ae6fd
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Wed Jan 2 16:39:37 2008 -0800
-
- Refactor Module#undef_method spec to #respond_to? and #instance_methods.
-
- Now only method dispatch is tested for #undef_method. #respond_to? and
-
-commit d2ecd4119a152370210ccb6c2a816c9dccb9fe90
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Wed Jan 2 16:00:09 2008 -0800
-
- Fix Rails indenting and whitespace
-
-commit f5b8afee4931bd09b0ce9fb88fc959c2ea0a1743
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Wed Jan 2 15:30:41 2008 -0800
-
- Fix Module#undef_method and Module#instance_methods
-
-commit 82bf31562361a21f85a90d5628a40ff50280c555
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Wed Jan 2 14:10:35 2008 -0800
-
- Rebuild excludes for #eof?
-
-commit b2aa0d56b04d7da5d333ba1449acda7c0b64c0c4
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Wed Jan 2 14:09:21 2008 -0800
-
- Add IO#eof? spec.
-
-commit addeb47d834d1ce60f8146f747defacf1682e6c4
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 2 22:31:30 2008 +0100
-
- Removed JRuby spec excludes.
-
- The JRuby excludes will reside in JRuby repository.
-
-commit 3239661ed5c38b37c966588341a043d6cdd9445b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Jan 2 21:28:11 2008 +0100
-
- Corrected String#modulo tests after clarifications from ruby-core.
-
-commit a0f3ba6632f8486e8f07a21a8e4720d8727ba4d2
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 2 11:28:42 2008 -0800
-
- Fix require_spec_recursive on Ubuntu.
-
-commit 857c39564df2d8da480f549fff46ec3ab880066e
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 2 00:48:53 2008 -0800
-
- A couple fixes. Updated CI excludes for last couple failures.
-
-commit 58c48ed05b493c71ee445062f27d47909e18b395
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 1 23:49:14 2008 -0800
-
- Updated CI excludes.
-
-commit 426f5a15eaac05ed1e900433837de0b9d0246c8d
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 1 22:43:47 2008 -0800
-
- Moved CI excludes files from .spec dirs to spec/data/*.
-
-commit a1d6211f3185f23cbc2c929f0352feca05fd079c
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 1 22:03:43 2008 -0800
-
- Moved ruby specs to spec/ruby/1.8/...
-
-commit af55eefd29c8acaf462efe03d2e0b3d95195cb21
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 1 21:44:35 2008 -0800
-
- Updates for bin/ci and bin/mspec.
-
- * Removed -2 switch from both because compiler 2 is default.
- * Added CI_EXCLUDES_DIR and -E switch to bin/ci to allow for
- specifying the exclude directories. The default is '.spec'
- in each directory containing spec files. Use a path starting
- with a '/' to create the exclude directories relative to
- that path, otherwise the exclude directories are created
- relative to the directories containing the spec files.
- * Moved spec/excludes.txt to spec/data/critical.txt
-
-commit 0e6645eb74f1f63b84f674dbcdfa991153a3ccd0
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Jan 2 12:10:39 2008 +1100
-
- Couple of Breakpoint changes
-
- * Raise ArgumentError if no block given (spec for this
- existed, but was masked by RaiseErrorMatcher bug)
- * Added line property to Breakpoint
-
-commit 36a7acddfe74ab25895d13dd775741b042ba3b0c
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Jan 1 23:10:13 2008 +1100
-
- Reorganise breakpoint specs to new dir layout
-
-commit 8aa6712dd9e5e870194f77ff74dc8cf11c273805
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Dec 21 16:15:19 2007 +1100
-
- Refactored BreakpointTracker in preparation for debugger
-
- * Moved code from debugger.rb to breakpoint.rb
- * Refactored code extensively to support debugger
- * Added breakpoint specs
-
-commit d16e905a67d64f67d7a24ce113f39b4b059c4139
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 31 17:51:59 2007 -0800
-
- Removed the rubinius dir from specs. It was redundant.
-
-commit 85ed07b6d739f013892a6cbcae5d0bb2c19f6e80
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 29 15:45:31 2007 -0800
-
- Split Ruby specs proper from Rubinius specs.
-
-commit b8e1466dc1b814bfb2022c1e4319d5ba63f5d762
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 29 15:02:55 2007 -0800
-
- Updated guards in specs.
-
- * Changed guard names to new, more descriptive names.
- * Removed all #extended_on guards for Rubinius-only specs.
-
-commit 5773ebe9e6f78abec9bfb03f144b5c7a86a27c7e
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 29 00:50:56 2007 -0800
-
- Changed Float constants specs to compare against precise values.
-
-commit 71874fcdc9eaf45a5adecf57d7609831a2a8e6c2
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Dec 29 17:26:06 2007 -0600
-
- Fix dump_spec to expect 1 or more write calls, rather than exactly 1.
-
-commit d4bfb39910aa4adf2c0c4e2dee214487bac34093
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Dec 29 14:51:38 2007 -0600
-
- Add a spec for procs being block-passed and some peculiarities therein.
-
-commit 1b0333479bf6da2c76c8d3c1e1640dc156086d9f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Dec 28 08:24:30 2007 +0100
-
- Improved ObjectSpace#each_object spec test.
-
- Previously, the test was failing from time to time,
- depending on Garbage Collector behavior.
-
-commit 3d7e628acc6699f9652383317bd416d8c75329d5
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Fri Dec 28 05:27:24 2007 +0100
-
- Updated Time specs to use new :os guard.
-
- The Time specs use this :os guard to properly detect
- which external program with proper parameters to invoke.
-
-commit 7662638e9afa631f0581fc1c2b2b422b1b926f98
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Sat Dec 29 03:06:51 2007 -0600
-
- adds Marshal.dump specs
-
- for nil, true, false, String, Symbol, Fixnum, Bignum
-
-commit 93431a28d687372b95f1a1420a3bd1f24e660117
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Dec 29 00:15:44 2007 -0600
-
- Guard Continuation specs to not run on JRuby (JRuby does not, will not support continuations)
-
-commit ccf745b9eafe068de6f888de24387bc0a0e68859
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Sat Dec 29 00:08:04 2007 -0600
-
- Fix for Fixnum size spec to guard "java" platform with 8 byte size
-
-commit 6f448f0dd72b5df2cc69e28db3d5593f897a9dbd
-Author: MenTaLguY <mental@rydia.net>
-Date: Sat Dec 29 00:58:58 2007 -0500
-
- a more modest spec for Thread.pass
-
-commit b32c2d95d044a4979ab92b5881e32fc8b169d931
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 23:51:10 2007 -0600
-
- Adjust Float MAX spec tolerance to work on both JRuby and MRI, since there's a few powers of precision difference.
-
-commit af7bb00beeb359fd6183def039b9a1fcd0ce7c48
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 23:39:15 2007 -0600
-
- Expand Float divmod array equality comparisons to use be_close with a default tolerance.
-
-commit dbdf373751bce2c8a334315c8c5ed21458614c70
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 23:34:09 2007 -0600
-
- Add a tolerance to the Float induced spec around the same scale as the value under test.
-
-commit a713d277e6a8148d4c53b66a3a8fa3aedbd6a108
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 23:31:25 2007 -0600
-
- Modify Float multiply spec to be_close with a TOLERANCE multiplied by a similar scale as the value under test.
-
-commit b82d8af43356de31d16b1c36296d9e819ce70d46
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 23:13:38 2007 -0600
-
- Fix Module class_variables spec to sort the variables before checking if they are all there.
-
-commit 1e60a25b57273dd6fd7e21b0a443da1f5c0be9e5
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 19:44:51 2007 -0600
-
- Mark Process#fork specs as not_compliant_on jruby.
-
-commit 021a6ff317ed826a46ca2168f4ee9c7540a27214
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 19:19:14 2007 -0600
-
- Remove fail and "failure" guard around the require/extension spec, since an unimplemented spec isn't necessarily a failure of any kind.
-
-commit 520c423860ef6553dae34eefd85188ab9b4773f6
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 19:12:52 2007 -0600
-
- Modify previous compliance change to callcc spec to use not_compliant_on instead.
-
-commit ab85bfff2f9fea8e28f9518311aacccd30f380dd
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 17:56:42 2007 -0600
-
- Remove compliance guards on identical spec's link/unlink, since they don't blow up now and JRuby supports them.
-
-commit e79c8af0ad6fb7ddf094b6ba4747932145f9b89b
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 15:19:24 2007 -0600
-
- Removing "fail" and "failure" wrapper from unimplemented "loads extension files" spec; an empty or unimplemented spec is not a failing spec.
-
-commit 0f6b7387bcc8df946ec8d7504cc3935b6d0f9c58
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 15:06:07 2007 -0600
-
- Add compliance to callcc specs, so JRuby doesn't run them (since it never will)
-
-commit ed43292ce58468e31b771eb4926a39dff8d70793
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 14:48:45 2007 -0600
-
- Make umask spec work with different host process starting umasks, clean up literals to be easier to read through.
-
-commit 7e9f96741739e544c547f2898e8b5183dec87323
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 14:43:02 2007 -0600
-
- Fix goofed-up paths in requires for rubinius-specific Integer spec
-
-commit d54fb1e7c3f586a6d8ac200d6de839ebe6cb4c46
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 28 14:40:50 2007 -0600
-
- Move rubinius-specific spec from core/kernel/Integer_spec to rubinius/core/kernel/Integer_spec.
-
-commit eb561025707736ebe196eab3b4ff2bd1c98f45a4
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 27 23:51:42 2007 -0800
-
- Fixed language/block specs to guard ruby18 feature.
-
-commit 5659d057d756effe3acba1037d0ad6d638d930dd
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 27 22:58:17 2007 -0800
-
- Changed Bignum specs to use value suitable for all implementations.
-
-commit 2646b1a17f898f05233622c9251c3c36632e82a7
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Thu Dec 27 23:43:42 2007 -0600
-
- implements m directive for String#unpack
-
- moves a couple misplaced methods from Numeric to Integer
-
-commit 496d6761d7377081ff76b263a51bb39d0e30d80a
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Dec 26 18:07:45 2007 +0100
-
- Marked one Rubinius-specific Kernel spec test as such.
-
- Kernel#compile is not official part of Ruby.
-
-commit 50e35293bd3a117874203a75d214c3435170e5d3
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Dec 26 17:43:03 2007 +0100
-
- Corrected String#pack with 'DEFG' pattern test.
-
- Now, numeric comparison of values is used, with precision,
- not literal string comparison.
-
-commit 0ef00fe14a04ef240fcca17d15271f92f2a44525
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Dec 26 16:00:20 2007 +0100
-
- Added String#inspect test case with malformed UTF-8 string.
-
-commit 5bbde0cda03ea782090586a9afdb620663633456
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Thu Dec 27 13:30:34 2007 -0600
-
- switched ThreadGroup specs to use Channels
-
-commit e3abd8b834b9f923d94ae381e81977feb4a4f6f8
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Thu Dec 27 13:22:20 2007 -0600
-
- added Thread#stop? and fixed Thread#status + specs for Thread#status
-
-commit f8835353bc8be47760f70811616991463e4e681e
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Dec 26 09:18:24 2007 +0100
-
- "Unexcluded" one Struct spec test for JRuby.
-
-commit 8a1b127cb33e43b916b0ccd820c6e16680cd4030
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Dec 26 09:12:23 2007 +0100
-
- "Unexcluded" 6 Hash tests for JRuby.
-
-commit ae4ce805fb7611ea6de12b01b2500f501b54bd6a
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Wed Dec 26 09:01:35 2007 +0100
-
- "Unexcluded" 27 Array tests for JRuby.
-
-commit c84540f96d7e265732a204ed72b3873545624444
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 27 00:08:06 2007 -0800
-
- Fixed Set#delete? spec to actually call delete?.
-
-commit e137c3279f511b49442ce2cea1b1832c1a0c6ab0
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 27 00:00:56 2007 -0800
-
- Added some specs for Set.
-
-commit 8054ed86a93a72ad4629d6f52455892d620138b0
-Author: Nitay <nitay@powerset.com>
-Date: Tue Dec 25 17:30:56 2007 -0800
-
- require should prevent recursive includes infinite loop
-
-commit 23fb497a7ba2a853cbdc5e8a38b091df284a377e
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 26 16:50:22 2007 -0800
-
- Updated status output options for bin/ci and bin/mspec.
-
- * Made dotted the default output format for bin/ci.
- * Added -m MARKER option to ci and mspec.
- * Added "Started" output as requested by autotest folks.
-
-commit 036b073753763afe86330d3f7fa0f61d755ac991
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Dec 26 10:41:01 2007 -0500
-
- Moved class fixture back to spec/fixtures/.
-
-commit 91d46b86a86270bb3174909a2d5cbc343ea138c7
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Dec 25 19:20:18 2007 -0500
-
- Added specs for $~, $&, $`, $', $+ and $1..N.
-
-commit c434614505511b8816548efcf4a4cf56d77220f4
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Dec 25 19:19:11 2007 -0500
-
- Improved language-level class specs, moved fixture.
-
- * Class fixture copied to spec/language/fixtures/.
- * Disabled unnecessary class instance variable check and added
- new ones.
-
-commit 0a49f3485fe7e26cc7d7d5bc3cb800ddf9fd6231
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Dec 25 19:13:22 2007 -0500
-
- Changed strange_block_args_subspec.rb to block_args_subspec_strange.rb
-
- * Name change to improve alphabetical sorting.
-
-commit 2ac50215dd32fd7ad2f2c20c7ae06ed73dc9f856
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Dec 25 13:32:06 2007 +0100
-
- Added tests for Array#pack with "U" pattern.
-
- Note: The tests are exclided for Rubinius.
-
-commit 4c0993fa90010322bb823a9799a8b3ccdd585e2e
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Wed Dec 26 04:07:02 2007 -0600
-
- return excluded spec
-
-commit 0a69d9cd5a7d3a0be9411fa00c4eeebe5d270a0c
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Wed Dec 26 03:55:43 2007 -0600
-
- implements @AM directives for String#unpack
-
- squashes bug in a regexp where an alternation of things
- between begin and end assertions wasn't wrapped in group delimiters
-
-commit ddda4d49f5535577c147d2154ecdae7cb4e32e24
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 26 01:16:13 2007 -0800
-
- Moved Kernel#load/#require fixtures to spec/fixtures.
-
-commit 0438e9e61c5958c5daf691b025e34bc79e7b2573
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 26 01:06:12 2007 -0800
-
- Reorganized specs to group all Rubinius specs under spec/rubinius.
-
-commit a4c3e286e44ee3df88395b9b5f44d5804154ed2b
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 25 19:32:55 2007 -0800
-
- Updated CI excludes.
-
-commit 8535481571712cf8c35f437c42ec53dcbfd44bc0
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 25 15:52:53 2007 -0800
-
- Enhanced guard for detecting :ruby, :ruby18, :ruby19 engines.
-
- Changed dir specs to create the fixture directories with every
- run to prevent pollution of the directories from causing spurious
- errors.
-
- Added spec/core/dir/fixtures/mock to .gitignore.
-
-commit a6b07ec37da7a59f34f45dfc84a66729b12f63b7
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 24 16:25:16 2007 -0800
-
- Removed Dir specs mock directories from version control.
-
-commit b0e4addbf7c6505c760e143e5fac0dab0109d8ac
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Dec 25 13:17:28 2007 -0500
-
- Updated CI excludes for Dir.
-
-commit 80a9c6c2e2e5cd2acdcb6492c4a06fef258bb49e
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Dec 25 13:17:09 2007 -0500
-
- Moved Rubinius-specific parts of #load/#require specs to extensions.
-
-commit 85f6b6e24518868f39ff39a5014a41a233237671
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Tue Dec 25 02:53:45 2007 -0600
-
- implements U directive for String#unpack
-
- uses only one of the exception messages every time
-
-commit b414c94db1fa1af8e6cd3382c34fc6de5ed3bd1e
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Mon Dec 24 16:42:22 2007 -0800
-
- Merge identical specs
-
-commit e0f28c224a2348dbf7c005694971a86f8e6162e1
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Mon Dec 24 15:59:24 2007 -0800
-
- Kernel.Integer() shouldn't pass a base to String#to_inum
-
-commit eb93da7c578599469fe209f7b1d30f0f77d148f5
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Dec 23 16:43:33 2007 +0100
-
- Wrapped one String#crypt case into compliant block for JRuby.
-
- "hello".crypt("\x00\x00") is not really defined,
- and heavily platform dependent.
-
-commit 7594c89cf2f017cb1fffad16bac6fcc7c9629422
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Sun Dec 23 10:53:30 2007 +0100
-
- Added JRuby wrapper for String#% test.
-
- Allow "%e" % (0.0/0) in JRuby to return "NaN", and not "nan".
- I think, returning "NaN" is a proper behavior, and
- it seems that MRI 1.9 is also following it.
-
-commit eaf9e328e81f9c1d4e80737a96d0eea6b511fabb
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Mon Dec 24 06:55:30 2007 -0600
-
- implements BbHhIiLlSs directives for String#unpack
-
-commit 701945421d6a656f8b0b183052c4535a895e2afd
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 24 00:44:26 2007 -0800
-
- Converted specs to use the new #platform guard syntax.
-
-commit 238fbbc2331a1926f3d3f447d8433b046e7d34ac
-Author: Tom Mornini <tmornini@engineyard.com>
-Date: Sun Dec 23 15:43:26 2007 -0800
-
- Clean up language on now understood and fixed alias_method e2mmap spec.
- Fixing the alias_method problem has now uncovered something in const_set,
- so I've included a very vague test (require 'e2mmap') to document the
- problem until it's better understood.
-
-commit 69149b261ac13cc1a2b7c80c7b103d397fd96b9b
-Author: Tom Mornini <tmornini@engineyard.com>
-Date: Sun Dec 23 14:13:22 2007 -0800
-
- Add spec for alias usage that breaks e2mmap.rb
-
-commit 71d9a4144811b2c9c74edc55f348637c57b0cb84
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Sun Dec 23 05:25:37 2007 -0600
-
- implements aDdEeFfGgXx directives for String#unpack
-
-commit bebafb1383a5126c959c33a1336f3a2e4b6993f6
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 18:16:14 2007 -0500
-
- Saner specs for stream-style Dir access. Passes 1.8.6-p111.
-
- * Dir#read, #tell, #pos, #pos=, #seek and #rewind which are a part
- of the stream interface to Dir no longer rely on platform-specific
- position values, instead opting to just ensure they work as expected.
-
-commit a2e4c318a3406c9532404611f14d2790695c0a7a
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 16:29:00 2007 -0500
-
- Enabled Time#at spec to work with BSD `date`.
-
-commit 0e983f2e948ab997834dbc703e9eeb11d86a7022
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 16:17:14 2007 -0500
-
- String#to_i spec to check for correctly parsing 0x-1 and the like.
-
- * This was fixed in 1.8.6-p111.
-
-commit 5e635a46f4733bcc2071b52ea076584614fe5655
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 15:52:03 2007 -0500
-
- Fixed various String spec issues and added a few. Passes 1.8.6-p111.
-
- * String#% with o for octal numbers is still broken but that seems
- to be due to MRI's sprintf.c.
-
-commit 780f22bde03e280f5af2509bef260585341f4e0b
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 15:48:55 2007 -0500
-
- Fixed incorrect use of #should raise_error.
-
-commit 0b239b4f66c20ad5690e429639c4bf11a809ab58
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 12:22:20 2007 -0500
-
- Hash specs fixed. Pass under 1.8.6-p111.
-
- * Changed to use HashSpecs#frozen_hash and #empty_frozen_hash
- for clarity and being less error-prone.
- * Fixed various typos causing problems.
-
-commit 9a2450e5c51333474cf012c3a1364e95384af9e0
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 12:20:48 2007 -0500
-
- Kernel.caller specs revised. Pass 1.8.6-p111.
-
- * Fuzzier matching of the data in the call stack.
- * Fixed specs for omitting frames.
-
-commit 692f4e8a652e273096c0f77ffe571318c59d2b12
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 10:59:19 2007 -0500
-
- File.ftype specs pass on 1.8.6.
-
- * Use `find` to locate specific file types instead of relying on
- predefined paths being correct.
- * Re-enabled character devices.
- * FreeBSD does not implement block devices.
-
-commit f1251ebc602311ec305a4b1b35a765ee45b9c164
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 10:11:07 2007 -0500
-
- Bignum#div returns an Integer if evenly divided.
-
-commit b62e1b7a21df1d7736767530f216148b8a93e38a
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 09:52:33 2007 -0500
-
- Fixed Array spec failures under 1.8.6-p111.
-
- * Array#fill raises if given a negative count.
- * Array#initialize will always raise if frozen.
-
-commit e3d6a3df6c1dfc37731ff4de5de32dc996bb61bb
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 09:37:46 2007 -0500
-
- Silence warnings from removing *.rbc in #load and #require specs.
-
-commit a11171e853b3efb94b4cba03786ea851d81411c6
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Sat Dec 22 07:39:40 2007 -0600
-
- implements CcQqVv directives for String#unpack
-
-commit eea90994f2a1b76ed11b29e05a16c9c299d59235
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Dec 22 00:23:29 2007 -0500
-
- Added __FILE__ specs to #load.
-
-commit 0e04ca49ebdba35a7a293b6de82d9d67c6ff4ac5
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Dec 21 22:59:50 2007 -0500
-
- Correct __FILE__ information from #load and #require.
-
-commit 51c2543fe032b680a6c8f8cf8121196070c61c66
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 21 23:51:37 2007 -0800
-
- Replaced use of @path1 with equivalent nil in File#fnmatch.
-
-commit b9f979393456dc3c93250e3a50b54b489a25c5d1
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 21 23:29:51 2007 -0800
-
- Added -w to bin/mspec to emit warnings. Fixed warning in mSpec.
-
-commit 16ce249216f490b9f7921aa69932f9e8bd60ca0e
-Author: Jeremy Roach <jero_rub@yahoo.com>
-Date: Fri Dec 21 22:50:40 2007 -0800
-
- Implements N, n, and Z directives for String#unpack.
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit e1d292e28fe409c087f314bb139371a1f248850d
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Thu Dec 20 15:04:12 2007 +0100
-
- Fixed race condition in ThreadGroup#add specs.
-
-commit 469527ddf33484a4a77f3d73c611e9a393bd48ad
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Dec 21 12:02:50 2007 +1100
-
- Added CompiledMethod#decode specs
-
- * Added UnboundMethod#compiled_method accessor
- * Improved robustness of ISeq decode when dealing with junk at
- the end of an iseq
-
-commit 08c2f5c29a2debed90ae1fff817c30e269913609
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Dec 20 23:45:53 2007 -0500
-
- Re-enabled purging .rbc files in require_spec and fixed the masked problem.
-
-commit dd4f3c52e79d01e826918e49fa626d7358f87901
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Dec 20 22:53:48 2007 -0800
-
- Clean up a couple of failures seen in ci. spec/core passes.
-
-commit a5667632ae8d112c0271e00cbba53a274075cd1a
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 20 22:49:05 2007 -0800
-
- Removed legacy, unused spec/reports/base.txt.
-
-commit 853e100b6f7fff24e4aaa40ed30c6add523f8df2
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Dec 20 17:49:36 2007 -0800
-
- Fix a bunch of String specs (thanks random8r)
-
- * Note: rubinius now has the same behavior as MRI for Nan,
- Infinity and -Infinity when using String#to_f
-
-commit b220f4921fd799ac28c60132ca08cf16df6f713e
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Thu Dec 20 15:37:25 2007 -0600
-
- fixed require specs to work correctly on any run including first
-
-commit 56ac483e3559e1d4913e4c36c9a8f007523fdab0
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Thu Dec 20 19:36:21 2007 +0000
-
- Fix typo in spec/core/regexp/union_spec.rb
-
-commit 634300eed40ef0ded16ab7cac7865dd783486c2d
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Thu Dec 20 03:46:59 2007 -0600
-
- Add 'sleep' checks to threadgroup spec to avoid the same race conditions seen in kernel/sleep_spec.
-
-commit 72b7123c9b3d1d266f4ce035b4e99dd0c2dbd88d
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Dec 19 22:46:17 2007 -0500
-
- New compliant (moreso, anyway) #load and #require.
-
- * Improved #load and #require.
- * Specs for the above.
- * File.to_sexp and String#to_sexp allow empty input. They are
- processed as a file containing 'nil'.
- * Archive#get_object_fuzzy allows no extension or .rb instead
- of .rbc only.
-
-commit fe633062095096fe00599cbb89aa4370ab5ccb3e
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Dec 19 23:03:08 2007 -0800
-
- Fix Kernel#puts
-
-commit 364ca08cbbb1848b549d99deb11e2449ad99334a
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 19 23:10:17 2007 -0800
-
- Updated CI excludes.
-
-commit 5f1c381560a8d4d594749d42b5b2feeec341d4e5
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Dec 19 22:24:10 2007 -0800
-
- Fix Kernel#open
-
-commit 3b3ed6304deab01cb448665c5f4b17d813f04e65
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Dec 19 21:43:58 2007 -0800
-
- Cleanup more method specs, all pass on rubinius now
-
-commit 76bbbf275f4e835444f684b2e688b292f20c1ffe
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Dec 19 18:08:09 2007 -0800
-
- Implement protected methods
-
- * Added a bit more verbose specs to methods_spec.rb, to show
- specific cases.
-
-commit dce06b35481bb1951c587d36f63abaae069d0ae4
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Dec 18 22:28:30 2007 +0100
-
- Wrapped one String#unpack test case into compliant block.
-
- The test case is platform-specific, and not suitable for, say, JRuby.
-
-commit bb4945ea7b9253150f753508e92633b6e355194a
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Dec 18 21:30:24 2007 +0100
-
- Added new String#unpack test to exclude file for CI.
-
-commit 1bd8beb8e0b335f1de309d6320312a1b64af1e4d
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Tue Dec 18 19:51:47 2007 +0100
-
- Added more tests for String#unpack with Z/Z* patterns.
-
- These patterns are known to be tricky, and their
- handling was changed during Ruby's life.
- See [ruby-talk:98364].
-
-commit d26edc2269a77667dbefcfb1ea6212d8ada9ef97
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Dec 19 01:25:27 2007 -0800
-
- Fix a bunch of Task GC problems, better memory management.
-
- * Use ALLOC* macros instead of malloc/calloc directly
- * Also, simple fix for Time
- * A Kernel#loop implementation
-
-commit 4143b92e6112241ff2facd64047491ce579bf0e9
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 19 00:43:32 2007 -0800
-
- Finished converting Object.new to mock() in specs.
-
-commit 9cae61f827d2eeca0a744e551551efd6bc85a2ae
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 19 00:02:46 2007 -0800
-
- Spec #it blocks must be inside #describe blocks for RSpec.
-
-commit 7df00ef6d2471d0b37829e0a4d1ef45edf782a44
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 18 23:28:43 2007 -0800
-
- More conversion of Object.new to mock() in specs.
-
-commit 12463512d0ad48fae3a1843d9d409649551dd13b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 22:53:38 2007 +0100
-
- Corrected String#* test to pick large enough Bignum, even on x64.
-
-commit 79cbff2c9a0cb15e9e5767f94242fa4360a0c4a0
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 16:43:16 2007 +0100
-
- Removed race condition from Kernel.sleep spec.
-
- This problem caused JRuby spec runs to hang.
-
-commit 3032e60e10dd1ae61ffb40b351f4f6731395602b
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 15:43:42 2007 +0100
-
- Enabled one Hash#rehash test case for JRuby
-
-commit 1808106191856f4f82b948abc5c7e708a747d059
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 15:40:49 2007 +0100
-
- Issue #153: Hash#rehash test enforces unspecified impl detail
-
- Wrapped the test so that it won't run with JRuby.
-
-commit efbf30477ea289911d9cafbde89ecbe2c8c65089
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 15:25:23 2007 +0100
-
- Corrected :mri --> :ruby
-
-commit 60a3ede3c64b62fb26905ed1c236c0e241b64515
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 15:23:42 2007 +0100
-
- Issue #182: String#to_f spec corrections for NaN, Infinity
-
- JRuby AND Rubinius treat "Infinity".to_f, "-Infinity".to_f ,
- "NaN".to_f differently than MRI.
-
- MRI returns 0.0 in all those cases, but JRuby and Rubinius probably
- do something more meaningful, they return Infinity, -Infinity and Nan
- respectively.
-
- It was agreed that JRuby's and Rubinius' behavior is a feature rather
- than a bug, and worth preserving and checking for.
-
-commit 521a82d8c325a33b3409423d61b589c7b8681870
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 15:14:28 2007 +0100
-
- Refactored commonly used generators into fixtures.
-
- Thus reducing copy-paste.
-
-commit 86820a339c74e3ca8fc9515e5fdf31ad42780201
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 14:12:43 2007 +0100
-
- Initial version of Generator specs.
-
-commit 91353183ace65d8e751db14a829e8f24d043710c
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 03:18:19 2007 -0600
-
- updated excludes for Kernel#sleep and Thread
-
-commit 6de193c0819f74717eb2e9eff8480f0d801b0e41
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 18 01:01:31 2007 -0800
-
- Replaced Object.new with mock() where appropriate.
-
-commit 1217fa030ff26712e9718ebecfe351830c543d7e
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 02:16:10 2007 -0600
-
- fixed redo in loop by save/restore condmod around loop context in compiler1
-
-commit df757142c774becfc2cbc4b38e43e31056acbae2
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 02:00:27 2007 -0600
-
- spec for using redo,next, and break in one loop
-
-commit 7169fd31b7c22750241212c242bc8aacdafe632f
-Author: Vladimir Sizikov <vsizikov@gmail.com>
-Date: Mon Dec 17 13:08:09 2007 +0100
-
- String#sub specs wrapped to correct JRuby test failures.
-
- JRuby reports Ruby version to be 1.8.5, but in this
- particular case it behaves like Ruby 1.8.6
-
- Differences between Ruby 1.8.5 and Ruby 1.8.6:
- different error raised.
-
-commit 04e228e131d06cd764d69375ddfdf44e4fec2b38
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 01:27:00 2007 -0600
-
- spec for Thread.pass and updated :mri to :ruby
-
-commit 11348e25ba30199e3beb05f8c38c18820fbefc3f
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 01:11:38 2007 -0600
-
- Some minor fixes in Thread specs
-
-commit 5cb3bcbf8f1d2a2237200ca0a9a9c6408d478ad6
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 01:11:05 2007 -0600
-
- spec and basic functionality for Thread.stop
-
-commit 3301fbb3ec43b5252c0aa6d45eb2f0e21581ff0a
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 01:09:49 2007 -0600
-
- Thread.sleep doesn't even exist in rubinius
-
-commit bd964f579f84a39097ecee1271664d672b6553a7
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 17 21:40:16 2007 -0800
-
- Replaced :mri with :ruby for spec guards.
-
-commit d21810882621356c35dcd101daca5ee5549f6607
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 00:42:32 2007 -0600
-
- Threads should report there status of sleep, aborting, and run
-
-commit 85a6476a236bd1e65d42ca03846c662a10842f37
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 18 00:41:09 2007 -0600
-
- Thread#status should return nil if Thread terminates with an exception
-
-commit ecb4455a75f4af2ae0059ca4960c2282b4ec632a
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Dec 17 23:50:24 2007 -0600
-
- specs for Thread#{key?,keys} and added key type checks for Thread#{[],[]=}
-
-commit c1a5d7e52b33ba6686441c61652bcc41ae0547f8
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Dec 17 22:15:37 2007 -0600
-
- specs for Thread#[]
-
-commit c2c7f0adc6ebbad925adb2471b6064b67528b420
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Dec 17 21:47:52 2007 -0600
-
- ensure LocalThread#current != Thread.current
-
-commit d05dac276f36326e143aa75bb43e4ab07bd8ddc9
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Dec 17 21:28:44 2007 -0800
-
- Fix a bunch more Kernel specs
-
-commit 4ddd0e144b4e4f64c51fc8d64952826d92a5e83f
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Dec 17 19:45:26 2007 -0800
-
- Fix Thread.abort_on_exception and Thread#inspect
-
-commit a12ad6fbc2589a7864a7c784386fb6ce7dae1db1
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Dec 17 21:29:49 2007 -0600
-
- Kernel#sleep and Thread#join specs now use locks to maintain automaticity instead of while th.status == 'run' loops
- added a Channel fixture to Kernel to support the use of locks in Kernel#sleep specs
-
-commit 72e3fb453c266e514b817daa66bf6033f1d19e40
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Dec 17 19:01:18 2007 -0800
-
- Fix callcc specs, revert all locals back to using the locals tuple
-
- * compiler1 now does what compiler2 is going to do, ie, only use the
- locals tuple to store locals. Storing them on the stack has proved
- to be a pain, and wont be used further.
-
-commit 6e35be2ddef8d055e064462c88a8b3f33eb4fe0f
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Dec 17 18:37:16 2007 -0800
-
- Faster Class#new, initialize can be private
-
- * Class#new now uses a bunch of inline assembly to be able
- to call a private initialize
- * Clean up Module#name a little
- * Made machine's rbt a little more robust
-
-commit 47a5bbf34ef8a60a18c1c8c6130d493a299ff852
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Tue Dec 18 01:10:33 2007 +0000
-
- Make sure files opened with "w" are truncated.
-
-commit 0fdc8c9b7d05cc2e96908b280ac144de0d04f646
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Tue Dec 18 00:16:27 2007 +0000
-
- Fix excludes for spec/core/stuct/{new,struct}_spec.rb
-
-commit 5b1252e6b2d8f8d70343b06f3520114de2040524
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Sat Dec 15 17:31:25 2007 +0000
-
- Minor fix to struct_spec to include fixture.
-
-commit 4fd0356ab9e9bb5c2a805b1f863b3177458966fe
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Sat Dec 15 16:29:49 2007 +0000
-
- Add case to spec/core/class/new_spec for names of nested classes.
-
- * Updated spec
- * Add some comments where this may be fixed
-
-commit 86736d564f34a2f97f7c7bedcab09c2472861b01
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Sat Dec 15 16:16:26 2007 +0000
-
- Fixes for struct class names.
-
- * Tighten up specs to show what class names should be.
- * Fixes #inspect
- * (Partially) solves the larger issue of an anon class getting a name when
- assigned to a constant - works now when Module.const_set is called.
-
-commit ad0d5ff2396baf43c8b2e37a3132765a074b241d
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Fri Dec 14 02:33:23 2007 +0000
-
- Fixes related to Struct.new
-
- * Fix to method_table to correctly handle DelegatedMethods
- * Changed spec/core/stuct/new_spec.rb to allow :rbx to call
- to_sym on objects passed to Struct.new to get the symbol
- value.
-
-commit 18f10dc700fe24f3bd230063bc7c1e8a82e8348f
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 17 08:58:22 2007 -0800
-
- Updated spec excludes to run with bin/ci under the new mspec.
-
-commit 678fb90c5c8aa96e10a9f95f520312f12f8fa3f2
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 15 22:43:44 2007 -0800
-
- Changed true/false/nil specs to not use def in describe block.
-
-commit 9e132474aafb6a0f0c968c2e085b09bfc07e1a0d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 15 18:49:31 2007 -0800
-
- Fixes to run the specs under RSpec and mSpec.
-
-commit cd3ecf52645b94921db92393e6e4d295d12bba88
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 15 00:59:11 2007 -0800
-
- Misc fixes to mspec. bin/mspec -t r spec finally runs!
-
-commit f3b3f70bb47b04e7a67c1dbc3ae38711857b5184
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 13 22:46:54 2007 -0800
-
- Multitudinous miscellaneous fixups for mspec and mmock.
-
-commit 55ab5b2ee42e4fabcfd8c51d6fac304cdfec31c7
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 10 01:01:58 2007 -0800
-
- Various fixes to mspec to run Rubinius specs.
-
-commit 86c0f131608b4ad7cba93eabd172a48e5b60ca0f
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 7 15:34:06 2007 -0800
-
- Added runner guards to omit specs that will always fail under RSpec.
-
-commit 75706dbfabbe359b6410f0d3743f0ea682146ac1
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 7 14:03:46 2007 -0800
-
- Added #runner guards to mspec.
-
-commit 3da390988031bf0066a849934ee758475ebbfa04
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 7 02:38:13 2007 -0800
-
- More fixes to run the specs under RSpec.
-
-commit 2b0f4e408b733dcd9089a19d78cd8e4cce20b99c
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 6 18:40:33 2007 -0800
-
- Yet more spec cleanup to run under RSpec.
-
-commit 1e4171d4682f55776e01e42f564714548c1d9bd9
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 6 02:16:42 2007 -0800
-
- More changes to run specs under RSpec.
-
-commit db020d30374e419792f76077757784008953c0a6
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 5 02:01:30 2007 -0800
-
- Various changes to get the specs running under RSpec.
-
-commit 968c2daa5345a0cddb8d3d5bd2b6bf2eeb0c1d6f
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 4 23:51:52 2007 -0800
-
- Convert remaining mocks to RSpec syntax.
-
-commit e5dc3ac814d1cda923131257dfbc9a30bf501b62
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 4 23:28:17 2007 -0800
-
- Convert remaining 'should_raise' to 'should raise_error'.
-
-commit a7be230ac71ece2bb8dcece72d629bcd0ce6a5e0
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 4 18:29:26 2007 -0800
-
- Converted specs from mini_mock to RSpec mock syntax.
-
-commit 4136e2fef4a81eb6e9e14070ff5301638f9acf14
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 4 02:25:31 2007 -0800
-
- Integrated mini mock with mspec. Updated spec_helper for main specs.
-
-commit d71c0c7412af01d6295d8caab43a80d0221ea16d
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 4 01:49:17 2007 -0800
-
- Added #shared and #it_behaves_like to mspec.
-
-commit da61adc0a079c858385773b12d683e2f5e2cc0e8
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 4 00:43:15 2007 -0800
-
- Converted 'should_be_ancestor_of' to 'should be_ancestor_of'.
-
-commit 5ed0096aac58fef09fc766d808aea74356aacfa8
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 3 17:57:56 2007 -0800
-
- Replaced dev_null with CaptureOutput.
-
-commit 62282bd5cb5c555e6447dcf2d6d0da355913fe8b
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 3 17:30:01 2007 -0800
-
- Replaced 'should_include' with 'should include'.
-
-commit f990a7c58a7eee6dbbb3c50df7682942048b959f
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 3 17:21:50 2007 -0800
-
- Replaced 'should_be_close' to 'should be_close'.
-
-commit c53601c56bd222dfacf03f134132869eb71c5146
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 3 17:10:41 2007 -0800
-
- Finished converting should_raise to raise_error.
-
-commit 165dd99535b0829d2e2364fac24375068969c6ab
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Dec 2 23:22:54 2007 -0800
-
- Convert should_raise to should raise_error for RSpec compatibility.
-
-commit c9ff50a4b4be25614cc0ac2ea5540cfe87a939d3
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 23:30:44 2007 -0800
-
- Moved mspec out of spec dir.
-
-commit e9a40a77b6fa7d08969ea195aabbb930b665fe02
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 23:25:59 2007 -0800
-
- MSpec base formatter and specs.
-
-commit 2fc3ac3f8efbaf0861cadfd59bcdf926d2196284
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 20:32:42 2007 -0800
-
- Port fix to ruby engine detection from mainline.
-
-commit 9a52e660536b4723bf24e2717fec757a1bdfa49f
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 01:35:52 2007 -0800
-
- Match RUBY_NAME against /^ruby/ to pick up e.g. ruby1.8.
-
-commit 85536b98862f6abec310bfad03be17652ee65944
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 01:01:46 2007 -0800
-
- Implemented mspec matchers.
-
-commit c953335397c6c8b9d7b27a3d240fde3b3518cb48
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Nov 27 01:35:07 2007 -0800
-
- The rest of the mspec big picture.
-
-commit 2f598f193eb1b10065c8e1a8d5c2aaa89c689072
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Nov 27 00:39:59 2007 -0800
-
- Added base operator matchers and specs.
-
-commit 0cc0b5a97661970d4cbb5e46406e7ee06421e637
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 26 21:03:33 2007 -0800
-
- Migrated mspec and ci runners to mspec dir.
-
- Created stubs in bin/ci and bin/mspec that call the respective
- scripts in spec/mspec/scripts.
-
-commit b98d65eaa90d966fc2f7b8f8387266e241c202de
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 25 01:03:26 2007 -0800
-
- Added specs and guards for mspec.
-
-commit 7bb316d1291c9d0a16904d4a3ee60094a713f215
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Nov 24 21:40:46 2007 -0800
-
- Prevent MSpec's #should(_not) from overriding RSpec's.
-
-commit c446988257a2104d72abd4a362dc21ca6183aab0
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Nov 20 22:47:25 2007 -0800
-
- Defines #should and #should_not for mspec.
-
- Specs for #should and #should_not.
- Adds example for using mspec "base" layer.
-
-commit 1aecf8e828dfd3d86f43d8c9c927e7c0ccb16b68
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 12 00:40:04 2007 -0800
-
- The mini rspec big picture.
-
-commit f2979b03f29e7ac810b81f9087ea53923de5a35c
-Author: Charles Lowe <aquasync@gmail.com>
-Date: Mon Dec 17 15:18:24 2007 +0100
-
- Added missing error checks to Dir.chdir block form.
-
-commit 028fee4e6d48514cae53f87c143bb68501bf58e9
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Wed Dec 12 20:01:35 2007 -0500
-
- Add further specification of size changes during Hash#delete.
-
- This was actually failing a while ago but now passes after recent
- changes.
-
-commit f757f4359c86f778ac8e5931b8915511fd03506d
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Wed Dec 12 19:59:28 2007 -0500
-
- Tighten another spec in core/hash/equal_value_spec.rb
-
- Hash#== compares keys with matching hash codes via eql?
-
- This spec was using hash keys where key.eql?(key) was false.
-
- That's pretty pathological, but there's probably some real
- non-conformance with MRI here. MRI can test for object identity
- without calling eql? so a key is still found even if it doesn't
- eql? itself.
-
- That's not really related to the behavior this spec is specifying,
- though. So, this patch just uses a less pathological implementation
- of eql?
-
-commit 3f73ddf6bec5c704ceb5ed43481971860293353d
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Wed Dec 12 19:49:49 2007 -0500
-
- Tighten spec in core/hash/equal_value_spec.rb
-
- "Hash does not compare keys with different hash codes via eql?" was
- failing because it detected that eql? was called on a key. However,
- eql? was not being used to compare keys with different hash codes
- from the two hashes. Instead, eql? is used to compare a key to itself
- during hash element reference, in order to distinguish between two keys
- with equal hash codes that aren't eql?.
-
- The tightened spec only fails if the keys are compared eql? to each other.
-
-commit e355e98a32f34619628a17f5052750da6881cda9
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Wed Dec 12 12:26:15 2007 -0500
-
- Add specs for hash stability of various Numeric subclasses.
-
-commit 0d774c99254b2c5992a17ecb2a5a12dcd2cad05e
-Author: Chris Shoemaker <chris.shoemaker@cox.net>
-Date: Tue Dec 11 20:37:45 2007 -0500
-
- Add a Hash#store spec for storing unequal keys w/ same hash.
-
-commit edfff4981285007ecac132f565243150a8a8bd7e
-Author: Curtis Schofield <123@noself.net>
-Date: Tue Nov 27 19:02:45 2007 -0800
-
- Specs created for Process#gid and Process#uid
-
- * both are using the unix system command 'id'
-
-commit 4e269d01238537cc45f4c347b12053616007d94d
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Dec 16 23:46:50 2007 +0100
-
- Excluded evil Thread specs.
-
- This makes bin/ci usable (pass) again on my system, where it was horribly
- broken before.
-
-commit b32c46ba95f2ecdaf646a030b96ee9b3737929a0
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Dec 16 23:37:26 2007 +0100
-
- Excluded failing Kernel#eval specs.
-
-commit 0c56f3a1f84dd94d1f9685af9e9d6e0efd0cfabf
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Sun Dec 16 20:24:54 2007 +0000
-
- Tighten up specs for what should happen when array shrinks during iteration.
-
-commit bfa8c532605c9e3b3d7f853516de9aae596c611d
-Author: Hunter Kelly <retnuh@gmail.com>
-Date: Sun Dec 16 19:11:25 2007 +0000
-
- Added specs for Array#each when the array is changed during iteration.
-
- Ditto for Array#each_index.
-
-commit b3aa2af4a3467b4eeb8765010286c12bd5adfbf9
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Dec 15 22:53:35 2007 +0100
-
- Sanitized Object#id spec.
-
-commit cce5b7004a774041d78c3b2e55af8063335a9512
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri Dec 14 19:02:57 2007 -0800
-
- Fix sleep spec, implement Thread sleep status and death detection
-
-commit c2475838be23ae287075b7e9ea832013f1db77c4
-Merge: 30f20cf... d061b86...
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 14 10:56:53 2007 +0100
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 30f20cfbd67487c426827406890fdb06fac8045c
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Fri Dec 14 10:56:17 2007 +0100
-
- Fix race conditions in Kernel#sleep spec by ensuring target thread is actually sleeping before continuing.
-
-commit d061b864f636210e40982d961b0aa5afc24543d0
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Dec 13 23:04:27 2007 -0800
-
- Fix require specs to not require checked in .rbc or .rba files
-
-commit 41831976d25a4d5a8e26673199276098cc45b4d3
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Dec 13 22:40:43 2007 -0800
-
- Fixed Thread#run, added corruption detection to rbc files
-
- * Thread#run was confusing the Thread scheduler, cause things the VM
- to quit running.
- * Added corruption detection to .rbc files in the form of a SHA1
- hash placed in the .rbc, just after the header.
-
-commit 77f0f29060d5ba3f33dc45029525acb715eb61c2
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Dec 14 15:10:59 2007 +1100
-
- Compiler2 fix for attrasgn in masgn
-
- An attrasgn node contained within an masgn does not include
- the assigned value in the attrasgn sexp. This was leading
- to the argument count to []= to be understated by 1.
-
-commit faaa1932fe05ee4d506b768f8d9d884af5345547
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Dec 12 19:59:11 2007 -0600
-
- fix non-determinism from Thread.sleep by removing blocking sleep
- add check for duration of 0 or 0.0 to instant return and added more specs
-
-commit e98b2d1f9788c1813bef2d920779c95effbd3d9f
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 11 17:27:43 2007 -0600
-
- spec and fix to allow floating point timeouts to Thread#join
-
-commit 801cb5ef58a6debfd348a33f864737cbce7c3d77
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 11 17:26:58 2007 -0600
-
- added noncompliant spec showing that sleep(nil) is allowed in rubinius
-
-commit 84d280810c840d6699b5c9ad094964fe779235df
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Tue Dec 11 16:30:41 2007 -0600
-
- fixed Thread#sleep to allows floats, and switched Thread::sleep, Kernel::sleep to use Thread#sleep on current thread
-
-commit 3d10a8a10741786ba76a4cc1083934f908d52ec2
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Mon Dec 10 17:13:34 2007 -0800
-
- Allow Thread.new to take arguments
-
-commit 4f5258b938a7aacf31e73b5fe6312e3c927d9cf8
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Mon Dec 10 00:21:20 2007 -0800
-
- Fix rb_define_alloc_func
-
-commit 7ab0f524de5a6b796ec1000402392cb138150eed
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Fri Dec 7 15:06:45 2007 -0800
-
- Initial ThreadGroup implementation
-
-commit 53fff95e300b1b26ed16f12c13684eadf8235d7a
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Fri Dec 7 01:30:55 2007 -0800
-
- Add rb_str_substr
-
-commit ec82de9f67e271718b874c0d777765da696bef88
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sat Dec 8 15:26:17 2007 -0800
-
- Add wrapped struct spec
-
-commit 65998d601aae601b3b43878f534362136a01ff17
-Author: Brian Takita & Nathan Sobo <brian.takita@gmail.com>
-Date: Fri Dec 7 17:18:24 2007 -0800
-
- Added specs for Module#undef_method.
-
-commit 97f8c9c32b9400ae42d0dc80aa7e17b22864fce9
-Author: Brian Takita & Nathan Sobo <brian.takita@gmail.com>
-Date: Fri Dec 7 16:13:02 2007 -0800
-
- Moved Object#to_a to Kernel#to_a. Added VM.coerce_to_array.
-
- VM.coerce_to_array will be used for splatting any object.
-
-commit 865ce7d771a101bc8c2c9ae3a82cbc3f37450c4b
-Author: Brian Takita <brian.takita@gmail.com>
-Date: Fri Dec 7 12:47:08 2007 -0800
-
- Merge branch 'array'; commit 'nathan/array' into array
-
-commit b4541a90f84c898e3cd9851ac4b207d559078a59
-Author: Nathan Sobo <nathansobo@gmail.com>
-Date: Thu Dec 6 23:33:10 2007 -0800
-
- Updated language/array_spec.rb for more detail on splat operator.
-
-commit 577b2f1c395dc49165842c405fb47bbb7591158a
-Author: Nathan Sobo <nathansobo@gmail.com>
-Date: Thu Dec 6 18:30:16 2007 -0800
-
- Fixed :many_if for compiler 1.
-
- Before it was translating many_ifs to a flat array of if statements instead
- of nesting them. Also, multiple boolean expressions in the case were not
- expanded to a boolean disjunction.
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 1d555fa07aaed8e59e728cb0013daa10b3b17b25
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Dec 6 21:24:44 2007 -0500
-
- Add some JRuby-inspired eval specs
-
-commit 3131fb81eef380d163d028f5587475bbf170befb
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Dec 6 12:19:49 2007 -0800
-
- Fix minor constant lookup issue and add timing to mspec
-
-commit 26897cd85c693cac10229d7467436717552088c0
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Dec 6 11:42:36 2007 -0800
-
- Fix another constant lookup bug
-
-commit 06a3f07999aeb4f7379ea40205451d326d1ba596
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Dec 6 16:37:15 2007 +0100
-
- Updated CI excludes for IO#each and IO#each_line.
-
-commit b495ab1019e9ee136e9d099faa51cba03c48e947
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Dec 6 16:01:31 2007 +0100
-
- Extended argument checking in IO.read.
-
- We're now checking that offset isn't negative either. This is done
- before the length argument is checked, mirroring MRI's behaviour.
- Also fixed a typo in the length check.
-
-commit 4fa2fbb6b6c27ced5d6cf902e63e3989c2d29b64
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Dec 6 14:56:41 2007 +0100
-
- File.truncate raises Errno::ENOENT if the given file doesn't exist.
-
-commit cb7a0a7315e57f1adff0976bcd6b0c4a1a94d8c5
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Dec 6 14:15:55 2007 +0100
-
- Added support for the length and offset arguments to IO.read.
-
-commit 9fe8f2bd73e28d28b7a9249e629ab7681321e4d5
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Dec 6 14:07:21 2007 +0100
-
- IO.read only accepts file names and uses File to open and read them.
-
-commit 7ab1d9f3434e3f3b021de2f4087f2502e229c7a0
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Dec 6 14:00:19 2007 +0100
-
- IO.new(nil) raises TypeError now.
-
-commit 227f6b4bf45b55eb659d41507d38fe5071ef7424
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Dec 6 13:24:31 2007 +0100
-
- Fixed a typo in File.writable?.
-
-commit 645f30882c9dd39d13f49e45f2f32c43ebe25182
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Thu Dec 6 03:51:11 2007 -0800
-
- Update Dir excludes
-
-commit e60ee517013d44c2ec6faf147f7dbd685fa520c2
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Thu Dec 6 00:40:17 2007 -0800
-
- Fix flag checking in Dir.glob
-
- Also clean ".", ".." skipping
-
-commit fa681ad7a3c1d0e1b4fb0702c2fc63cd80ec9377
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Wed Dec 5 18:08:41 2007 -0800
-
- File.fnmatch? should accept escaped wildcards
-
- Also fixes more Dir.glob specs
-
-commit e6b8ce23729606bf6fa748ea63c0e0a59b48a476
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Wed Dec 5 15:35:32 2007 -0800
-
- Don't unescape leading period in File.fnmatch?
-
-commit 1cf054a08b0aeea7c348ff26c71ccaf22c02ce70
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Dec 6 02:36:54 2007 -0500
-
- Rename Array#pretty_inspect to avoid conflict with pp
- Hardcore bikeshed action on the way TestGenerators are inspected
- Change describe.rb to call the renamed pretty_inspect
-
-commit 519d1226027623274766641a256e2a9753257266
-Author: Nitay <nitay@powerset.com>
-Date: Wed Dec 5 16:07:25 2007 -0800
-
- Fix Constant = Class.new setting of name
-
- Signed-off-by: Kevin Clark <kevin.clark@gmail.com>
-
-commit 568c57ca57d4a9183e492024e17aa1352902d1d2
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Dec 5 20:31:43 2007 -0500
-
- Clean up mspec output to prepare for unit_diff support
- Use pretty_inspect to display compiler2 TestGenerator output
-
-commit e250521194380f4c942fd6d53664b746ca63e3e3
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Dec 5 17:27:27 2007 -0800
-
- Fix constants spec to scope the fixtures
-
-commit 7010073617a4fa95ea5491284fef97a083d9d4f3
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Dec 5 14:42:27 2007 -0800
-
- Vastly simplify and fix constant lookup
-
- * New constant lookup specs to test behavior
- * Added StaticScope object and field on CompiledMethod which stores
- a StaticScope instance which indicates the lexical scope of the CM.
-
-commit 163e56646a817301201af843b45c973da058688c
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Wed Dec 5 23:00:16 2007 +0100
-
- The spec for Dir#rewind doesn't pass on Rubinius.
-
- It's not platform specific, but we don't have a working Dir#pos yet
- and the Dir#rewind spec relies on it.
-
-commit 3afe61bd78aa9e850f081b83ca2c478ae297bda1
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 5 13:51:05 2007 -0800
-
- Changed mini_rspec to show failures unless being run by autotest.
-
- Added dir_entry.rb to .gitignore.
-
-commit 0c661894b54615ee4915d61569e072ffdfa8826d
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Wed Dec 5 09:17:24 2007 -0500
-
- Much-improved tiny option parser lib/options.rb.
-
- * The Options API is much more user-friendly now,
- size is still about 100 LoC
- * Specs for the API.
-
-commit 092e0081c26eeda2ca6561eb19123b468965c84a
-Author: Ryan Davis <ryand-ruby@zenspider.com>
-Date: Wed Dec 5 01:40:31 2007 -0800
-
- Added support for autotest.
- Requires a new release of ZenTest to actually work.
- I'm tired, I'll do that tomorrow
-
-commit 9e3e41d71d1bab8104ae17ff34aaa2311be3b0b1
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Dec 4 22:59:49 2007 -0800
-
- Commit miss for require specs
-
-commit d1a6f0805b739930e54406188e32ac1e0f30a74b
-Author: Eric Hodel <drbrain@segment7.net>
-Date: Tue Dec 4 22:24:49 2007 -0800
-
- Add specs for Kernel#require, never add .rbc files to $LOADED_FEATURES
-
-commit a60e3bf901b62fbbbef59acb2c6c9f164be1fbbc
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Dec 5 14:10:15 2007 +1100
-
- Cleanup case spec, update excludes
-
- * converted case specs to not use should
- * separated out case specs with target expressions from those without
- * updated excludes for two failing specs under compiler1
-
-commit f0de77911ff0b4532a47fb9803685e8d968d51ec
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Tue Dec 4 09:42:49 2007 +1100
-
- Fixes for compiler2 when_spec failures
-
- * Added compiler2 spec for when without an arg
- * Added spec for when without arg with an else to
- spec/language/case_spec.rb
- * Implemented many_if sexp compilation
-
-commit c9c67738ecae341441098993923838a15b64d166
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Dec 4 20:42:27 2007 +0100
-
- Test Etc.getgrnam() with "daemon" instead of "root".
-
- The "root" group seems to be a Linux-ism.
-
-commit 1fd6d97e8eb20ce9908cc0abd09b7c5555ff5720
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Dec 4 19:31:24 2007 +0100
-
- Post-move fix for the Options spec.
-
-commit ead52428d99549b6b53b8897d969e80072395ef6
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Dec 4 19:12:28 2007 +0100
-
- Moved codearchive.rb, options.rb and readline.rb from kernel/core to lib.
-
-commit 0e4568bcc23011957cc250de2a93031648281b21
-Merge: 78fba04... fbc5ad5...
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Tue Dec 4 00:50:46 2007 -0600
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 78fba04c31e9d97c32862e9e104e3917dcff9137
-Author: Charles Nutter <headius@wlan100.headius.com>
-Date: Tue Dec 4 00:39:05 2007 -0600
-
- Making socket spec more reliable by using nonblocking accept for TCPServer and adding a "ready" flag for UDPServer.
-
-commit 7e925ea53239207f5dd9ac5daddda8e0f1f3b687
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Dec 2 23:33:29 2007 +0100
-
- Implemented Etc.
-
-commit 450778cf5f416f6b9531664d4fff2c159c93cbe7
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Sun Dec 2 01:39:28 2007 -0600
-
- Shared spec for class_eval.
-
- - removed method-arguments from describe string
- This was causing bin/completeness to report 0 examples for Module#class_eval/module_eval
- - examples checking for TypeErrors test the exception is raised, but don't check
- the exact message as it is not part of the interface.
-
-commit cd0d11c7eb23d881f1dd73701bd3edc12c5bd744
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 1 15:28:41 2007 -0800
-
- Updated CI excludes for Dir.[].
-
-commit e41e501bcf686937fbd3b8cfc86f325d7e06184d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 1 10:54:35 2007 -0800
-
- CI spec excludes updates.
-
- * Fixed rake pristine task to whitelist Kernel#require fixtures.
- * Updated CI excludes for Dir.glob and Dir.[].
-
-commit 8f362a0350238366565a373f1feb9594efe03407
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Dec 1 18:50:55 2007 +0100
-
- Make sure we delete the directories we're creating in the mock dir.
-
-commit dfc1b1cd32f47b48dd358ca50226d614425ef8b2
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Dec 1 18:08:27 2007 +0100
-
- Dir.chdir now always resets the working directory when called with a block.
-
-commit 02f41a92bbafd1a555344e1082970e090cd1f9a5
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 30 23:41:29 2007 +0100
-
- Call StringValue on require's and load's argument.
-
-commit 601fd404ba04f383ee286be015edb7e8c58574d5
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri Nov 30 14:27:44 2007 -0800
-
- Refactor Kernel#require
-
- * Refactor a bunch of Kernel#require into Compile#require_feature
- * VM.load_library now detects if the extension is already there
- and doesn't readd it
- * Added specs for #require
-
-commit 9b903cb7c5c6a3bfbaa3a7a91dc7bad830af7294
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Nov 30 10:56:02 2007 +1100
-
- Compiler2 fix for anonymous masgn, e.g. * = 1,2
-
-commit 08bc0a2f14494a30d5956d5bdcca9eb37c921780
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 30 00:16:07 2007 +0100
-
- Made check_argcount work with methods that don't take any arguments.
-
-commit 96108240fead7d764f3ec37d5eb20294f3a9dd97
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Nov 29 21:45:32 2007 +0100
-
- Updated the CI excludes for Method#call.
-
-commit 61805ab7fac6ae9855baa05b42aebe66c3a2b3d3
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Nov 29 21:44:49 2007 +0100
-
- Made Method#[] an alias for Method#call.
-
-commit 219d34dedf6ff0ed083cb5f1e8b6a5c437ad366c
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Nov 29 21:22:05 2007 +0100
-
- Enabled the Kernel#method_missing specs.
-
- They pass now that they specs aren't confused by the Dir spec helper
- methods anymore.
-
-commit de5320efe8095e612e235bea7053084bb61d300d
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Nov 29 21:17:58 2007 +0100
-
- Moved the Dir spec helper methods in their own module.
-
-commit 1ae47b5c091c209597bec7475935bbcff34b50b5
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 23:45:09 2007 -0800
-
- Applied patch from #151.
-
-commit adb5b139afa452869464fe53b710d7cb8b93131b
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 20:29:38 2007 -0800
-
- Better fix for guards to distinguish ruby, ruby1.x from ruby1.9.
-
-commit e53f72172e395c7766dcecadd2ffd6c7caf303e7
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 28 20:15:27 2007 -0800
-
- Patches (or modified patches) from #157-162.
-
-commit b07eeee79ea5a0c0160c34aec2d690f1b46f7380
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Wed Nov 28 14:43:41 2007 +0100
-
- Fixed Bignum#modulo and Bignum#remainder.
-
-commit 85b05b5103aaeb5d946e0f691f77af2dafa6f30a
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Wed Nov 28 01:00:07 2007 +0100
-
- Unified the File.unlink and File.delete specs.
-
-commit 2ec59a82f279a4ba6b5b781c90a7714aba767ed9
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Nov 27 23:30:43 2007 +0100
-
- Be more specific wrt the expected exception.
-
-commit 54236949e9b974d4c4dcf95b63318c844c62aca4
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Tue Nov 27 19:58:50 2007 -0600
-
- Module#<=> is working, Updated CI excludes for Module specs.
-
-commit 55c7529f4c8b02eff7e0b594f33b28750877fca2
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Tue Nov 27 14:53:02 2007 -0600
-
- Specs for Module#private/public/protected
-
-commit 5b693fae3464abb6a5aa05d8236bd8f4610c89d4
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Nov 27 19:36:06 2007 +0100
-
- We cannot use File.exists? to check whether a symlink exists.
-
- Use File.symlink? instead.
-
-commit e7eb6a8e1e1310c08220db0ed7979ec4c721fccb
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Nov 27 19:34:48 2007 +0100
-
- Moved the after(:each) block before the specs, so the block is actually run.
-
-commit 4c284abb32029029ab7002147ef544493c7070f6
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Nov 27 19:00:30 2007 +0100
-
- Added a missing Errno.handle to File.readlink.
-
-commit f163ca7c5e4a03d698a881853d1e0fab8a5be1a4
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Nov 27 18:42:08 2007 +0100
-
- readlink() only works with symbolic links.
-
- This makes the spec pass on MRI.
-
-commit ca1cb21b5f694b3850a838f88d3ac5ded7de3e1f
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Nov 27 18:40:43 2007 +0100
-
- Naming convention fixes.
-
-commit cbf351cb59152a5528f6c6105cee96c67f7f6fcd
-Merge: f70d531... 5452983...
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Mon Nov 26 19:48:21 2007 +1100
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit f70d5314fcc75ef2e32fbd484de58bd5f7ed6cbc
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Sat Nov 24 17:29:29 2007 +1100
-
- Implemented File::symlink and spec.
-
- Kudos to the Melbourne Railscamp :)
-
-commit c4a6a804185c18a182206afc1b8d5209d208077e
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Sat Nov 24 01:08:41 2007 +1100
-
- Removed trailing whitespace.
-
-commit 9b9820e512f56b2c23c760887251d72c187aa297
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Sat Nov 24 00:50:11 2007 +1100
-
- "Added File::readlink spec"
-
-commit 2dd272afe315dae0ad0b9bd49b6dfa9e98e50b1c
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Nov 23 17:11:54 2007 +1100
-
- Spec-ed implementation differences on masgn RHS eval order
-
- Rubinius is (for now) deliberately non-compliant wrt eval
- order of RHS expressions in an masgn.
- * MRI, JRuby eval left-to-right
- * Rubinius evals right-to-left
-
-commit 361a1adcee182cf069352effd0949064b621bddc
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Fri Nov 23 16:16:08 2007 +1100
-
- Additional parallel assignment specs - use of to_ary
-
- * Added spec for when to_ary should be called on the RHS of an masgn
- * Added additional example of a complex masgn (from JRuby tests)
-
-commit 97cb3f5758f102cf8a07262c4c9bef4b22ca88b7
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Thu Nov 22 22:04:51 2007 -0600
-
- Added specs for metaclasses of true/false/nil on metaclass_spec as suggested by rue.
-
-commit d4f9eb7cd5fb17e3e8ce52db39e95a96362d3ad0
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Nov 22 13:05:10 2007 -0800
-
- Fixed wording of Rubinius extension Bignum domain specs.
-
-commit 50e1f80ef54d25aaa69d52a3d422547593836ac6
-Author: Jeremy Durham <jeremydurham@gmail.com>
-Date: Thu Nov 22 17:18:54 2007 -0500
-
- Added excludes for Kernel#open and Thread#abort_on_exception
-
- * Excludes Kernel#open raise specs
- * Excludes Thread#abort_on_exception specs
-
-commit 25607d4d884b4597bc69560e9390cd9dc1f4e44d
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Thu Nov 22 13:47:50 2007 -0600
-
- Specs for Module#alias_method
-
-commit c207618ad4113501aa5df4adb5d5aa3a60f5b9ff
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Nov 22 10:59:34 2007 -0800
-
- Use RUBY_ENGINE first, then pull in rbconfig
-
-commit ed5a46e13b35d6ad48cce1d3eed96c2f78ace049
-Author: Jeremy Durham <jeremydurham@gmail.com>
-Date: Thu Nov 22 11:42:36 2007 -0500
-
- Added basic specs for abort_on_exception
-
- * Added specs for Thread#abort_on_exception ($DEBUG on and off)
- * Added specs for Thread#abort_on_exception=
-
-commit 05ecef9162ba2c4a0da90c966a20a4f45c353d93
-Author: Jeremy Durham <jeremydurham@gmail.com>
-Date: Thu Nov 22 08:39:53 2007 -0500
-
- Added specs for when parameters are missing or invalid parameters are given
-
-commit 25d2c940d561dcac2c06df747762a229dddfbed1
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu Nov 22 15:33:17 2007 +1100
-
- Another parallel assignment spec - rhs should evaluate l->r
-
-commit 8e4f8de446b842c13ad45a8e0e2c3c1ebf30bddb
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 21 17:42:17 2007 -0800
-
- Stop-gap prevention for Kernel#callcc hanging CI specs.
-
-commit a9d7163e4d9e8d4fb79c9769691b232676a44bd8
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Nov 21 15:50:39 2007 -0600
-
- remove compliant(MRI) from callcc specs
-
-commit 812e922c8e7cda728d6b7f32933b75eb009eef11
-Merge: 2e221b9... f24bb1f...
-Author: Nathan Witmer <nwitmer@gmail.com>
-Date: Wed Nov 21 12:32:18 2007 -0700
-
- Merge branch 'callcc_spec'
-
-commit f24bb1ffdf941df78098da262a62e881653b1a99
-Author: Nathan Witmer <nwitmer@gmail.com>
-Date: Wed Nov 21 12:31:28 2007 -0700
-
- Added scope-related callcc specs, compliant(:ruby) only.
-
-commit 2e221b9f1d7ffa41431e5bd51fdd36434e7f838f
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Wed Nov 21 14:41:43 2007 +0100
-
- Spec and fix some more String#slice bugs when given nil, also use Undefined.
-
-commit db338d9d8705fd668a5639d483ff47908aa014ca
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Nov 6 16:53:13 2007 +0100
-
- Fix String#rindex when given nil as offset.
-
-commit 6eab3b692a50c1a37cc39c21d743de1488402f64
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 21 00:00:24 2007 -0800
-
- Added MRI stdlib Fcntl to lib/ext with build script.
-
- Added lib/fcntl to load extension. This may need a better solution.
- Added INT2FIX to subtend.
-
-commit 5268c0b29c1fb07a911fe601e30b21ffe04f7e81
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Nov 21 17:02:14 2007 +1100
-
- Additional specs for parallel assignment
-
- MRI allows parallel assignment to:
- - assign via object.method=
- - assign via []=
- - use a lhs arg as an arg to another lhs assignment
-
- All three scenarios currently fail in Rubinius, apparently due to
- miscalculating the number of args to an assignment method under
- parallel assignment.
-
-commit 462f68b95a70c24e41cad5a40969c4651c7de181
-Author: Jeremy Durham <jeremydurham@gmail.com>
-Date: Tue Nov 20 02:12:44 2007 -0500
-
- Added specs for Kernel#open when block is given
-
-commit ab9e40600fd2522d4abce86f7b8bdc632f6e9018
-Author: Jeremy Durham <jeremydurham@gmail.com>
-Date: Mon Nov 19 23:42:55 2007 -0500
-
- Added very basic specs for Kernel#open
-
-commit b47efc9f9872ecca68a06f6864f39617e06762b0
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 19 00:24:15 2007 -0800
-
- Updated CI excludes. Runs clean on Leopard.
-
-commit 3ff04e52bc9cb03439567ddb9b3b63b3034b30c3
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Nov 19 00:03:58 2007 -0600
-
- more specs for Kernel.callcc, ensures callcc return value semantics
-
-commit 06d5312c51b09faef87d2deb53f3c472eaa94100
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Sun Nov 18 17:49:44 2007 -0600
-
- basic callcc behavioral specs
-
-commit 53433f0e9ddba2eac876f7a1fb0f9d292ee37286
-Author: Nathan Witmer <nwitmer@gmail.com>
-Date: Fri Nov 16 16:51:18 2007 -0700
-
- Added Kernel#callcc spec and fix for LocalJumpError with no block given
-
-commit d324779b8b5c8dd84438c08ec4f2b2574282f93e
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 16 15:17:21 2007 -0600
-
- Added Module.nesting
-
- Some specs are failing on rubinius because the parent
- field is not being properly set.
-
-commit cff726c9dc3631b2e0ddc3e12bd3af532f7e1ef4
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 16 14:49:38 2007 -0600
-
- Added spec for calling Module.nesting on root level
-
-commit 05adb6070889d7021a1e53ab82b855c3554d4f5c
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 16 14:45:23 2007 -0600
-
- Fixed specs for Module#constants
-
-commit 1f1c857e1d8c37213a91daaad3fc3bfcbf2bef61
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 16 14:43:55 2007 -0600
-
- Fixed spec description for calling Module.nesting from methods.
-
-commit 242c947c6e4d007685e8aa0c44ac505c7dab4239
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 16 14:38:32 2007 -0600
-
- More specs for Module.nesting
-
-commit 3560fd7ef0d5a65a9cb055d87fa7103ed3bdb029
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 16 10:24:45 2007 -0600
-
- private keyword specs reflecting problem described on ticket #133
-
-commit fd31e1e592237832bd5e605f604d15385df0615a
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 16 04:15:27 2007 -0600
-
- specs for Kernel#block_given? by Francisco Laguna
-
-commit 87ebce4cf2430198578decdb4c7dc1003db37f8e
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Nov 15 22:07:39 2007 -0800
-
- Ticket #121 by Jeremy Durham -- File modes
-
-commit 4a67e0ade233aaaa3a2ff17161b298872f8a5f83
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Thu Nov 15 14:20:19 2007 -0600
-
- Splitted enumerable_spec.rb into a file per method.
-
- Added some specs by Francisco Laguna.
-
-commit 0b933650330f57e7db1bf8574d0b7eecf0635996
-Author: Bryan Helmkamp <bryan@brynary.com>
-Date: Tue Nov 13 11:34:20 2007 -0500
-
- Added specs for File.mtime.
-
-commit 42a7de27c1a6082fee7b9baaf05b9394ffe90ddd
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Mon Nov 12 19:57:38 2007 +0100
-
- Updated CI excludes for File#atime and File.new.
-
-commit 3d106d6a9b8ce0b34e7b6f9426da51b83fe5f676
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Mon Nov 12 19:54:43 2007 +0100
-
- Added File#path.
-
-commit 247da25a0120d468fe9f189a6235962f9658b65e
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Mon Nov 12 19:23:09 2007 +0100
-
- File now deals with numeric modes and accepts a permission argument, too.
-
-commit 087deaed0dcf4ae2c8dc713eeccfed9a0ebabe6f
-Merge: 4355e96... 1c9d213...
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 11 23:15:01 2007 -0800
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 4355e96b05de4d4d086dfa86b8fe19bdcecfbe82
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 11 23:14:16 2007 -0800
-
- -a
-
-commit 7e975d1aca38a3bfe07fda431aeaba376bce19c1
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 11 23:09:47 2007 -0800
-
- Get rid of irrelevant specs
-
-commit 1c9d2133fc294964ce08e9a7020083c379f74ca0
-Author: David Waite <david@alkaline-solutions.com>
-Date: Sun Nov 11 23:46:08 2007 -0700
-
- Remove temp directories within mkdir spec on exception.
-
-commit 2110fc75dc6a7ab521249f259bc6fdc78d565b11
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 11 22:36:08 2007 -0800
-
- Update CI Excludes
-
- * Expected failure of "raise an Exception if it has
- the wrong number of argments" due to dispatcher bug
-
-commit 0f2a183a46ba085d9c99ed4767cd18c0482e6d45
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 11 22:14:07 2007 -0800
-
- Implement File#atime
-
-commit 671b340f340ab6b8d9c13b27d52a782ce3268b2a
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 11 21:24:34 2007 -0800
-
- Update CI excludes
-
-commit f7ba96f6b41de9a3696a03e9efe25c8b037a4f07
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sat Nov 10 11:24:12 2007 -0800
-
- Adds spec for File.open
-
- * In resonse to Lighthouse Ticket #102
- "File.open should throw Errno::EACCES opening non-permitted file"
- * Passes MRI, doesn't yet pass RBX
-
-commit 719329b3f5179766e23a27e427cd0c0846c85ffa
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Mon Nov 12 10:38:42 2007 +1100
-
- Added IO#to_i implementation and spec.
-
-commit cc100fc08be101ecdf0daba1966977fb8e39fa6e
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Mon Nov 12 10:30:25 2007 +1100
-
- Added IO#fileno implementation and spec.
-
-commit d036f5c16a4836d638be83108be35df532d9221a
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Nov 11 23:17:12 2007 +0100
-
- Made SystemStackError subclass of StandardError.
-
-commit bf1c3dc3e463aeaf4e0cee1cbd46b15e7693a395
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Nov 11 20:36:25 2007 +0100
-
- Removed an old Method#arity spec exclude.
-
-commit 72c3495f3513e54c2488292bcdaca9208b6f0339
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 11 10:44:53 2007 -0800
-
- Removed transient dirs from Dir specs.
-
-commit 11f0ed51b4bfb3bea2b544a82b3158fd3daf2ad8
-Author: Victor Hugo Borja <vic.borja@gmail.com>
-Date: Fri Nov 2 03:02:28 2007 -0600
-
- Specs for Module#remove_const
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit e8158f14f0f02e3b0cdcb4182e1277928324cc0c
-Author: Nathan Witmer <nwitmer@gmail.com>
-Date: Sun Nov 11 08:19:10 2007 -0700
-
- Fixes for UDPSocket spec
-
- * Renamed the description to match what was actually being tested
- * Uncommented the code and wrapped it in an "it" block, to prevent
- conflicts/hangs with bin/completeness runs.
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 9b973a98d2ebddacd50f0fcb58903bb53bdff3f5
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Nov 11 13:30:22 2007 +0100
-
- Ticket #98: Dir includes Enumerable now.
-
-commit 8d957f186cd4d2c5e6b236de4a0878d38b464848
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Nov 11 13:26:00 2007 +0100
-
- Implemented Module#included_modules.
-
-commit 0021b24ba490fe01f96ef17957328feeedfc4c29
-Author: Nathan Witmer <nwitmer@gmail.com>
-Date: Thu Nov 8 21:42:41 2007 -0700
-
- Commented out code in UDPSocket spec so bin/completeness doesn't hang
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 56687aed201fb864587807cca893268a9f1e2050
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 11 00:10:14 2007 -0800
-
- Method fixture for yield specs.
-
-commit 421aa58f9135807487864adcdcac79f7b6da33c1
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 11 00:08:35 2007 -0800
-
- Specs for yield keyword based on patch in #114.
-
-commit 5ba0b2030c55474f9d8a096d309678ca24a4699b
-Author: Jeremy Durham <jeremydurham@gmail.com>
-Date: Sun Nov 11 01:35:08 2007 +0100
-
- Ticket #105: Implemented Bignum#eql?.
-
-commit 47356fe39033f8571559a4fef933681fda871efd
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Nov 11 01:14:26 2007 +0100
-
- Made specs for Kernel#respond_to? and Kernel#method pass.
-
- KernelSpecs::Foo#baz is defined in another spec, so these two specs
- may not rely on #baz being undefined. This is a horrible workaround
- for the problem that multiple specs make use of the same module and modify
- it freely.
-
-commit 68b4fc7c0192f537fe9727927ac35c440dbdc03a
-Author: Akshay Rawat <akshay.rawat@gmail.com>
-Date: Thu Nov 8 18:21:03 2007 +0530
-
- Updated CI excludes.
-
-commit a1eee3814a5d054cd00e26b40c063d41880bf6c7
-Author: Chris Pettitt <cpettitt@gmail.com>
-Date: Sat Nov 10 14:10:47 2007 -0800
-
- Refactor IO.gets spec to have less duplication.
-
-commit 56497d27bdb3a82d549f89b9fc9fcf0709f99b3e
-Author: Chris Pettitt <cpettitt@gmail.com>
-Date: Sat Nov 10 14:07:21 2007 -0800
-
- New spec: IO.gets('') should advance the file position to the next non $/ character.
-
-commit 95158f5a4141d5d3e2893304e49bfeb62cc7b226
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Nov 10 13:35:03 2007 -0800
-
- Added rescue to prevent meltdown until rbx begin/rescue/ensure is fixed.
-
-commit a39155cb029ca3c1e5e5d69e0e269c685c040f6e
-Author: Chen Yufei <cyfdecyf@gmail.com>
-Date: Sat Nov 10 12:24:38 2007 +0000
-
- Fixed IO#gets when separator is empty.
-
-commit f9c31ce1d2a68c15def98aad6c6ff35eb56cd523
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Fri Nov 9 20:24:40 2007 -0800
-
- Clean up Enumerable#include? specs
-
-commit f017fad69be5d4034a4c5437acf77ec4749b0d75
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 4 20:54:06 2007 -0500
-
- Clean up Enumerable#(collect, entries, find, find_all) specs
-
-commit 81550f082396b4455c3681ae966be1371be0a5db
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 4 13:18:52 2007 -0500
-
- Update excludes
-
-commit d5fd2ee893ea608c7e19cb674a4da7b9f49542e6
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 4 12:16:58 2007 -0500
-
- Cleanup/rewrite Enumerable#find tests for sanity and clarity
-
-commit 39f21aa76f6ddc45be79e4e4e978b4c1c2beed71
-Merge: 17d2e4c... c1b9f74...
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Fri Nov 9 20:25:13 2007 -0800
-
- Merge branch 'master' of http://git.rubini.us/code
-
-commit c1b9f74f88be963e72de763da9130f46869d89fb
-Author: Chris Pettitt <cpettitt@gmail.com>
-Date: Fri Nov 9 12:36:04 2007 -0800
-
- Fix some failing specs for IO#each and IO#each_line.
-
- Also refactor some common code into a helper method.
-
-commit 74af37b849507e504503359a08245effaad7634a
-Author: Chris Pettitt <cpettitt@gmail.com>
-Date: Fri Nov 9 10:58:33 2007 -0800
-
- New specs for IO#each and IO#each_line
-
- This change adds some new specs for IO#each and IO#each_line factored into
- a shared .rb, because one is the alias of the other. Added failing specs to
- excludes.
-
-commit d162a396b566846445328d6c42d3d5f10fcf7ee6
-Author: Matt Pelletier <matt@eastmedia.com>
-Date: Fri Nov 9 02:32:25 2007 -0500
-
- Add and refactor patches from Andrea OK regarding #send
-
-commit 63f0ed010e65549597f6bddb0686ba04157ca478
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Nov 7 09:52:25 2007 -0800
-
- Fixed Method#call spec failing from renamed fixture method name.
-
-commit 1ef46468d7808c52b07388130069cb2e7854bff8
-Author: Matt Pelletier <matt@eastmedia.com>
-Date: Wed Nov 7 04:48:39 2007 -0500
-
- * Update CompiledMethod#arity to be accurate for cases of required and/or optional arguments, with or without blocks
- * CompiledMethod#arity is still inaccurate when splat argument is present (the presence of splat overrides #required)
- * Add specs for more thorough coverage of various argument use cases
- * Includes known Rubinius-failing specs for splat-related arity
-
-commit b7726f26dae95936aa1c3fdf2c52dd18ef7413cf
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 5 17:48:51 2007 -0800
-
- Updated CI excludes for fixes to public|private_class_method.
-
-commit eb18f898e3ae8e5a1bf3b01291a12516c6a22301
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 5 17:18:22 2007 -0800
-
- Added Module#protected_method_defined?. Updated CI excludes.
-
-commit aa8904cdbd8b4851be4f05cec3000b04cfc9f6c1
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 5 17:14:12 2007 -0800
-
- Added Module#private_method_defined?.
-
- Fixed specs for Module#public_method_defined? and
- private_method_defined?. Updated CI excludes.
-
-commit 063b61759ee86f5def2422d16f1eb854c8b9eb76
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 5 13:39:21 2007 -0800
-
- Updated CI excludes for StringIO.
-
-commit 3c79f871379d2d4b5431138033f723efbf4a795d
-Author: Dr Nic <drnicwilliams@gmail.com>
-Date: Sun Nov 4 16:45:30 2007 -0500
-
- Extended StringIO spec "flattens a nested array before writing it" to ensure deeper test scenario
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 916d617a60cf83ac26c3090310236193f5842ff6
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 5 13:11:54 2007 -0800
-
- Updated CI excludes for String#scan.
-
-commit fee1d904197c369c561ae3b11aaf582f1b87d1b0
-Author: Matt Pelletier <matt@eastmedia.com>
-Date: Sat Nov 3 16:06:16 2007 -0400
-
- Fix test of String#scan. Do not force matches into array using splat.
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit cc9182cfcde60a63bf566f73c6004b7e46347e77
-Author: Daniel Lucraft <dan@fluentradical.com>
-Date: Thu Nov 1 17:01:03 2007 +0000
-
- Added File.rename
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit fc2b7aa65ab338d8ff543552659046c93659c3ce
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 5 12:06:13 2007 -0800
-
- Commit rework of Carl Drinkwater's patch from #72.
-
-commit 7f6564b96762d7b3deb9f021789182f5c664a766
-Author: Chris Pettitt <cpettitt@gmail.com>
-Date: Sun Nov 4 10:38:04 2007 -0800
-
- Fixes for two IO#gets spec failures.
-
- This patch fixes the following two IO#gets spec failures:
-
- IO#gets assigns the returned line to $_
- IO#gets returns the entire content if the separator is nil
-
- Signed-off-by: Brian Ford <brixen@gmail.com>
-
-commit 705e8e05496167b1af3a1e3ff3446d325ca54e07
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Nov 5 02:10:56 2007 -0800
-
- Added Module#public_method_defined?.
-
- Updated CI specs for #public_method_defined?.
- Small fix to find_method_in_hierarchy to symbolize arg.
- Updated some spec wording and removed spec'ing exception string.
-
-commit 17d2e4c6ae0c40376fe121786a362c8bc8ce951c
-Merge: 2b77ee8... c07472c...
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 4 20:58:42 2007 -0500
-
- Merge branch 'master' of http://git.rubini.us/code
-
-commit bd6c27f4724bdc461a7036e6373a0ad23060020a
-Author: Trotter Cashion <cashion@gmail.com>
-Date: Sat Nov 3 15:57:21 2007 -0400
-
- Added operator precedence specs for '&&' and 'and'.
-
-commit 2b77ee8b74373a3251973d96c931422909605e29
-Merge: 30d7618... 76aa72e...
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sun Nov 4 13:43:23 2007 -0500
-
- Merge branch 'master' of http://git.rubini.us/code
-
-commit 2c90ce28cc73e08d9fb74b5c7e815807314ba269
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 4 07:18:09 2007 -0800
-
- Updated CI excludes from 85d63b676e.
-
-commit 85d63b676e463a2bec9a322bc8eeffd2daee433b
-Author: Chen Yufei <cyfdecyf@gmail.com>
-Date: Sat Nov 3 23:39:23 2007 +0000
-
- Added specs for IO#gets
-
-commit be5b9595f2077080c0c1179ab9689352d8faea3a
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 4 00:31:12 2007 -0700
-
- Updated CI excludes.
-
-commit d46ad4b63d4a5f77609b0880b7f24e8e27404805
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 4 00:11:52 2007 -0700
-
- Updated CI excludes.
-
-commit 1f307223c673c6744f8b85fc3e707a3419b1a0e8
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Nov 4 00:06:48 2007 -0700
-
- Guarded #freeze specs for MRI and JRuby.
-
-commit ca50fd7d979c36f8af306e0e1474aac5408dd66d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Nov 3 23:22:31 2007 -0700
-
- Guarded specs for #frozen? for MRI and JRuby.
-
-commit 16b36030a796b877809d5d6ea556266c4b4a6413
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Nov 3 20:53:26 2007 -0700
-
- Removed NULL characters from language/precedence.
-
- Enhanced rescue output when loading spec files.
-
-commit 10510ece16ebb5e0ba921e0be631a4740f3e4453
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Sat Nov 3 23:09:30 2007 -0400
-
- Fix a method_missing cache error.
-
-commit b313c5632b039c03a448ae3b1046701c8b3243a2
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Nov 3 14:10:29 2007 -0700
-
- Changed shared spec behavior to be compatible with RSpec.
-
-commit 7b825b89e96b3c8e38f9b8bcc8edf2bc6ec6ff22
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Nov 3 14:09:47 2007 -0700
-
- Fixed language/class specs.
-
-commit 30d76181b0b3a9c5ac99c9d0e22a6a451346eff4
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Sat Nov 3 16:47:49 2007 -0400
-
- Fix Dir#each/Dir#entries/Dir.foreach specs. They weren't updated for fixtures
-
-commit f44a8cceb9a186a7127276db2207dfc79957ee8d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Nov 3 13:06:35 2007 -0700
-
- Guard File.(un)link for jruby.
-
-commit 1ec2c3a99ca562c8944aac1f4a60f8e0af0aaf17
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Nov 3 18:20:48 2007 +0100
-
- Properly resize the array in Array#<<.
-
-commit 8dec9918d8a6233ec2cde29d54687a5d950dc8df
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Nov 3 17:13:57 2007 +0100
-
- Fixed Array#unshift for the case when @start > 0 && @start < values.size.
-
- Also extended the Array#unshift specs to cover this case.
-
-commit 50b90918cd5a9a05e475690703c7867b443d191b
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Nov 2 13:47:53 2007 -0500
-
- added IO::foreach, fixed gets to use string separator, and fixed IO::readlines to use File.open
-
-commit 3efc01e110473d003ffb0a1376ec179f30e600de
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Nov 2 13:30:44 2007 -0500
-
- specs for IO::foreach and specs to test IO::readlines,IO.readlines with string separator
-
-commit fad18610b4416dfcfaf35db5029e880dff7e9820
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Oct 29 14:10:11 2007 -0500
-
- basic exec implementation and a single basic spec (not sure how test test exec)
-
-commit 730fc3ed9afc54612d14093148fb8583c9e39fe3
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 2 21:41:25 2007 +0100
-
- Return mkdir()'s return value from Dir.mkdir.
-
-commit f5766696e701a069f908b3b5d5cfbccfee15ef1f
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 2 20:46:11 2007 +0100
-
- Implemented Dir.foreach.
-
-commit c696f1edc50c58b87270811c0c9aa0e49b356fe7
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 2 20:38:36 2007 +0100
-
- Implemented Dir.entries.
-
-commit e8e6188b252172690c1b584e528e3c71035897cd
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 2 18:16:13 2007 +0100
-
- Raise an error if the opendir() call in Dir#initialize fails.
-
-commit 024309b560c6c69f6f331c614df1da221be7054c
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 2 16:15:19 2007 +0100
-
- The Array#[]= spec seems to work now, so enable it.
-
-commit 76f118e62a0784326f5edf1c0fe46f6b6e682eee
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 2 14:28:49 2007 +0100
-
- Made Math.ldexp only accept integers as the second argument.
-
-commit 22bd7369efd1f738835e9c0a6a4624a26dae02d1
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Nov 2 13:30:50 2007 +0100
-
- Implemented some missing File::Stat methods.
-
-commit d6dc42d9085fed5f8bf482d7f84dd9c5fbd4423c
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Nov 1 12:24:53 2007 -0700
-
- Fixed specs failing MRI for File.stat and File.basename.
-
-commit 46f4de189e987f3071ede57f2bb1f7c892d67bd4
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Nov 1 17:30:47 2007 +0100
-
- Fixed ticket #83: Array#push doesn't die anymore after calling Array#shift.
-
-commit 8debed24e957e48b10d60885d9a43083aab4d923
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Nov 1 11:14:22 2007 +0100
-
- In the Numeric#coerce spec, coercing strings to numerics should work.
-
- We can remove the TypeError checks from this spec, since those
- are included in the specs for the Numeric operators.
-
-commit 28cf656fb25ce38453acb2efdcf2e9ac16bb4460
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Nov 1 01:33:31 2007 -0700
-
- Removed Hash#fetch definition from fetch spec.
-
- Fixed spelling of Hash#find_unambiguous.
- Updated CI excludes.
-
-commit a6a69b469d94d0912ccbf123fdb9f53cbaf32830
-Author: Akshay Rawat <akshay.rawat@gmail.com>
-Date: Tue Oct 30 21:47:51 2007 +0530
-
- In the Time#isdst spec, don't depend on the system's current time zone.
-
-commit 1be129f98e0d548a023cc32f5ab763361e2a9c6b
-Author: Daniel Lucraft <dan@fluentradical.com>
-Date: Wed Oct 31 21:05:04 2007 +0000
-
- Fixed String#split to not return non-matching captures anymore.
-
-commit 5f7f798ef26fc8ee1e83c5e392c1fb2e60e31382
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Wed Oct 31 21:54:56 2007 +0100
-
- In the Numeric#coerce spec, don't try to coerce strings to numerics.
-
-commit e26b7645af27d5bfc250c2c11f7e72349750f5c7
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Wed Oct 31 10:52:13 2007 +0100
-
- Added a failing spec for Ticket #83.
-
-commit 9144f0c55eb5f40409bec514f08f89bdba61f800
-Author: Daniel Lucraft <dan@fluentradical.com>
-Date: Wed Oct 31 13:57:54 2007 +0100
-
- Fixed math/constants_spec.rb.
-
-commit 4b521cacb667ca5245954bc03ebfec67c0ac235c
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Wed Oct 31 23:26:45 2007 +1100
-
- Modified spec to reflect expected differences in masgn retval behavior
- between rbx (true) and MRI (array of rhs vals).
-
-commit 1f6c50f5c77566e66cb0b842733b7f4f4b24e937
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Oct 30 18:13:47 2007 +0100
-
- Use a fixed timezone for the Time#strftime spec.
-
-commit 60a25e997def085f3ae29773ce70ddc5b7c38d46
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 30 00:47:38 2007 -0700
-
- Fixed Kernel#raise to not output if $VERBOSE == nil.
-
- Guard Marshal.dump specs to eliminate error output until
- a proper Marshal is implemented.
-
-commit e446f2e329a6dfaacb45b5b86ba43ebd9ec606a3
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 29 23:17:49 2007 -0700
-
- Added IO::SEEK_SET, SEEK_CUR, SEEK_END with FFI.
-
- Fixed IO#close to raise IOError if already closed.
-
-commit fcb1ac4d076c07065878c2e65bf7bb44ddef400c
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 29 22:37:23 2007 -0700
-
- Specs for IO#seek and IO::SEEK_SET, SEEK_CUR, SEEK_END.
-
-commit a3570f6702dabd303fcd10d4cfc0e753cff69bb5
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Mon Oct 29 22:33:34 2007 +0100
-
- Make Module.new actually work.
-
-commit 9709fa96b91afe5140f76726f1f7d4b89f8a6d54
-Author: Brian Donovan <brian.donovan@gmail.com>
-Date: Mon Oct 29 11:30:32 2007 -0700
-
- Ticket #75: Fixed Enumerable#sort_by.
-
- We must not call the comparison proc when the object and pivot are
- identical.
-
-commit 52e97da6bbcd28ec4349abcf25b089648d085652
-Author: Akshay Rawat <akshay.rawat@gmail.com>
-Date: Tue Oct 30 02:18:56 2007 +0530
-
- Enabled Math specs that were fixed by Ticket #59.
-
-commit 0f98800d4ab1db526304f1d26597ca3880c811da
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Mon Oct 29 19:29:16 2007 +0100
-
- Ticket #59: Kernel#send now calls private methods, too.
-
-commit 754e48c223c3464c7d048452585c07b8d0b3d8c7
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 29 00:11:41 2007 -0700
-
- Specs for IO#rewind.
-
-commit 0bfd6bcca8fb287899fadeae81dd7c00b05d07e9
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Oct 28 23:40:37 2007 +0100
-
- Module#public_instance_methods now handles attribute accessor methods.
-
-commit 0a22b36b9bc50a34f1da1d0e994f1a6689195652
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Oct 28 23:26:17 2007 +0100
-
- Added a failing spec for Enumerable#sort_by.
-
-commit 006534b173a186c25c228b653d5ac9d81b20f57e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 28 21:51:40 2007 +0100
-
- Update Module spec excludes.
-
-commit 496df827eeeb600858fa8c7b26482aa3f653fee1
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 28 21:50:47 2007 +0100
-
- Make Module#ancestors specs pass.
-
-commit 18185cde2b47374c304e2528a084ea1f7b5178d2
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sun Oct 28 19:46:22 2007 +0100
-
- Added a failing spec for building an array that includes a splatted array.
-
-commit f120a470a5e07a7e53b1e006173942d58956e86b
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 28 19:33:10 2007 +0100
-
- Extended Kernel#` specs.
-
-commit 7e184c5bbc7be16cc8f7be01713543f222edd267
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 28 19:00:52 2007 +0100
-
- Removed Exception message dependencies and extended Kernel.String specs.
-
-commit 2853dc58209b3b8d122cee66c7d83e967d0879de
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Sun Oct 28 23:01:54 2007 +1100
-
- Fix for multi-arg operator assign through [], e.g. x[0,3] += 5
-
-commit 91b88710ddc1e8553e51c404cee4039f4d6abf24
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 28 13:05:08 2007 +0100
-
- Fixed File.ftype specs.
-
-commit 448fdc2def3a9ab249dadf9335568ca30b76f70e
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Oct 28 00:36:11 2007 -0700
-
- Updated compiler specs.
-
-commit 0fb510c14ee8787b5965d5665e50da92a988faa6
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Oct 28 00:32:41 2007 -0700
-
- Fixed Bignum#coerce specs.
-
-commit 5e52a259b91e81fe5497f44107dee6ffd613b3be
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Oct 28 00:22:40 2007 -0700
-
- Fixed wording on Rubinius Bignum#coerce extension specs.
-
-commit 19e0259ca51691afe341b1217ab92862b307fe17
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Oct 28 00:15:18 2007 -0700
-
- Revert "Remove invalid and failing Bignum#coerce spec."
-
- This reverts commit 2371b920ca3f956213ab9e406a3b5d2afab4f18e.
-
-commit 4986ec283ee5aa9e392065c74d64952d36554b91
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Oct 27 23:50:05 2007 -0700
-
- Updated CI excludes for Array#pack.
-
-commit 5472f30201d7cddd4465adb246fa32927fe03d91
-Author: Alan Hurdle <alan.hurdle@gmail.com>
-Date: Sat Oct 27 18:38:30 2007 +1000
-
- Bunch of fixes to Array#pack to pass the current set of pack specs
-
-commit 20210a617a3f31c5dc0eda9fa371c49200c11f67
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 28 02:30:02 2007 +0100
-
- Updated spec excludes for Module specs.
-
-commit 712e3cc6a5d8a69834449e1039dfae3e07fcdcc2
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 28 02:18:00 2007 +0100
-
- Removed the dependency on some Exception messages.
-
-commit 2371b920ca3f956213ab9e406a3b5d2afab4f18e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 27 16:15:33 2007 +0200
-
- Remove invalid and failing Bignum#coerce spec.
-
-commit e1e62e7749d47c838d6b7cd1e95863c0c90d3de0
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Oct 27 20:59:49 2007 +0200
-
- Fixnum#div now always rounds towards negative infinity.
-
-commit 9a4ccbe8381db5b6280c9d1dfcf6fa21a4838c4e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 27 15:09:57 2007 +0200
-
- Updated Spec excludes for Bignum and Fixnum specs.
-
-commit 889c939a668b9b1a4fd8f5a0cfd8bad85c3a5977
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 27 14:24:27 2007 +0200
-
- Fix Integer#[] when given a Bignum.
-
-commit 45d97332f4ec5a174884024c954ceeb6eb852f5f
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 27 13:46:51 2007 +0200
-
- Partial fix for #68: Fix Hash#fetch to correctly handle yielding with a default value passed.
-
-commit a785ea28f39c71a98007a7fafc23985dd21b596f
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Oct 27 13:39:42 2007 +0200
-
- Updated CI excludes for recent Hash fixes.
-
-commit 6dd909fede466ed813ec7c5d207c5deeb69c9eb7
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 27 11:33:22 2007 +0200
-
- Fix for #67: Enumerable#sort should not depend on #size.
-
-commit 720489aa52bfabd492c307330204772b5eba6755
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 26 00:21:37 2007 -0700
-
- Updated CI excludes for spec/language.
-
-commit 41e8a07252b2df9c1e858922195a72f9a40c882c
-Author: Akshay Rawat <akshay.rawat@gmail.com>
-Date: Fri Oct 26 02:37:18 2007 +0530
-
- private keyword should mark a Module method private
-
-commit a201e631cbaabcc5964cfa3eb28a9fa8be1bf347
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 26 00:11:01 2007 -0700
-
- Added spec/language into CI specs.
-
- Updated CI excludes for spec/language.
-
-commit 833fe76de0c0b900ef5255b2abecd19943404c0c
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Oct 25 23:53:35 2007 -0700
-
- Updated compiler specs and CI excludes.
-
-commit f31e5af358d2b5c3ff4afd3819b3a3e571427f8e
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Oct 25 23:28:13 2007 -0700
-
- Migrated Adam Gardiner's compiler patch 236d213de8 to stable.
-
- Updated CI excludes for language/variables specs.
-
-commit bd9e47b1b7624df5e2ae0f31a7fd53c787ecc7e4
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Oct 25 22:50:22 2007 -0700
-
- Fixed language/variables spec to use fixture class.
-
- Added CI exclude file for language/variables specs.
-
-commit 688f03ac452f698105812c28c29dcc7162b7037c
-Author: Adam Gardiner <adam.b.gardiner@gmail.com>
-Date: Thu Oct 25 22:43:20 2007 +1000
-
- Added specs for operator assignment, i.e. +=, *=, ||= etc
-
-commit 982dfee01bedb55e8dbf62d279bc4a375e58ec50
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Oct 25 16:53:45 2007 +0200
-
- Don't hardcode the result of Hash#to_a in the Hash#shift spec.
-
-commit 4bf7c8d2d387c002004da5df9f9c2a06fb65e61e
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Oct 25 01:42:32 2007 -0700
-
- Commit tilman's language block spec additions with some modifications.
-
-commit ff8f6f5b5f5285b0fcf361d84523bf21320074b2
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Wed Oct 24 20:20:12 2007 +0200
-
- Extended the Hash#[] spec with a test case for ticket #65.
-
-commit dc61b1e771c70e54f98859da3dd31a4ea61384e1
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Oct 24 07:11:07 2007 -0700
-
- Specs after(:each) MUST come before it blocks.
-
- Updated CI excludes for IO.read specs.
-
-commit 06539bad037e0ef7368ea5cbb5780fce7bbea443
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Wed Oct 24 21:26:49 2007 +1000
-
- Initial IO::read specs.
-
-commit a2f26d7a7b1997510edff1792eaec6507ba38208
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Oct 23 19:30:46 2007 +0200
-
- Implemented Numeric#remainder.
-
-commit 2bc5fcee6be4db3e0e0c46aa7c1b8ef5a5c57957
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Oct 23 19:10:54 2007 +0200
-
- Fixed Bignum#modulo(0.0).
-
-commit 68965dc12ea369f6db64c208cb2ce123c1398bb8
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Oct 23 10:20:04 2007 +0200
-
- Extended the Numeric#nonzero? spec a bit.
-
-commit 290ddde29d6c64e9c81f69780b7b0c967b2b4901
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Oct 23 10:15:57 2007 +0200
-
- Added Numeric#nonzero? and killed bad Fixnum#nonzero? in bootstrap.
-
- This fixes the Numeric#nonzero? specs.
-
-commit e9a1b257fc95c181e46c679d301a324134a725d4
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Oct 23 16:07:58 2007 +0200
-
- Enabled the Numeric#step spec now that it works fine.
-
-commit f4016db94eee2ec93a2cc487181c9ec2fa0d59d0
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Oct 17 13:51:04 2007 -0700
-
- A number of fixes found while debugging test/unit and optparse
-
-commit 7c7920c3e7727c3514b493ba299a52c5e5cde8f6
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Oct 22 18:12:42 2007 -0500
-
- Numeric#step is capable of floats and passes all tests
-
-commit ebc6ec5be0239bba544c55ff77fdc88903f4bb28
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Mon Oct 22 20:56:33 2007 +0200
-
- Made the Symbol#inspect spec pass.
-
-commit f0db8c3d1bb5dc444fc72ed5ca222f4cf5df8b35
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 21 14:00:30 2007 +0200
-
- Fixed a bug in process_op_asgn1 and added a simple spec for it.
-
-commit 4fbce6e8a6ab8fbb6b69944677678611db68bcf2
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 20 20:03:50 2007 +0200
-
- Fixed a failure in String#sub specs
-
-commit ca0332f9edb9e01ae216dee90674fb6f9809951c
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Oct 20 22:33:42 2007 +0200
-
- Fixed the Bignum#size spec for Rubinius' implementation.
-
-commit ae9c2ac3fe9dc59a027af7571d6d3083bcccb490
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 20 14:14:49 2007 +0200
-
- Don't rely on #respond_to? calls.
-
-commit 94938622aaf74e1f068c3b7ec8bfeccf763792ba
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Fri Oct 19 20:56:50 2007 +0200
-
- Extended the private spec.
-
-commit bf000a15edcfdd30c43ae6563b5766617f245a60
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 19 00:49:16 2007 -0700
-
- Updated CI excludes.
-
-commit ad146fc7ae22bfc26a536a40cf8dc4c0338cf25c
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Oct 18 19:45:27 2007 +0200
-
- Added a spec for the 'private' keyword.
-
-commit f15b5a8c818932d0ab5bea46f48a326e468b3511
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Thu Oct 18 19:44:54 2007 +0200
-
- Added Object#should_not_include.
-
-commit 80fdbd626d8ff99dc7ba4cf23a05d44ad98bd0cb
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Oct 18 09:31:51 2007 -0700
-
- Updates Hash so:
- * No longer freezes keys
- * Specs reflect the lack of freezing
- * shift spec doesn't fail purely because to_a is broken
-
-commit 197f36b6626b61203709704db869324a539764d5
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 17 20:11:50 2007 -0500
-
- moved File::expand_path to platform and made several fixes + new specs
-
-commit 7e8506fd510ab4e6f07e6d36456fdfef6e5b080a
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Wed Oct 17 21:07:44 2007 +0200
-
- Make sure that File.dirname doesn't modify its argument.
-
-commit 271bc31ba814e68fb414ebf29cf9648f57fe4cb6
-Author: David Altenburg <david@gensym.org>
-Date: Wed Oct 17 00:39:59 2007 -0500
-
- Added to fork spec: check that fork returns a nil pid for the child process
-
-commit 5d45341c55400a51d8cae3128bba265e7d441fab
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 17 05:19:49 2007 -0500
-
- moved File.basename to platform, added specs, and fixed specs for all but a disputable behavior
-
-commit ae7afd794881a4dedadf876f61369e5e88da695b
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 17 04:47:24 2007 -0500
-
- added platform/file.rb and fixed File.dirname for all and updated specs
-
-commit 71bf9b1c9cd7fb81692186d21b133fde43e8a6b7
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 17 03:44:33 2007 -0500
-
- spec to check if break exits all types of yields and loops correctly
-
-commit 3a546b40271d35bf7c60bb56a68ca49089ac9a34
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 17 03:01:40 2007 -0500
-
- clarified include_spec
-
-commit 40d8ed96fa689daf31039e71f91ed5520a821aa2
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 17 02:38:46 2007 -0500
-
- specs Module#include and Class#include that check to see if constants, public_methods and instance_methods are imported correctly
-
-commit ff462080a58aaa61759830e18f3a5757a883980d
-Merge: 5a2c858... 5cf41ab...
-Author: Jon Guymon <gnarg@kiryo.(none)>
-Date: Wed Oct 17 01:55:33 2007 -0400
-
- Merge branch 'puts_specs'
-
-commit 5cf41abaff9dc04cdba5fe50492d4ebfdde2a274
-Author: Jon Guymon <gnarg@kiryo.(none)>
-Date: Wed Oct 17 01:55:01 2007 -0400
-
- normalized specs for IO#puts StringIO#puts and Kernel#puts
-
-commit 5a2c858086c1b02a54864ff82c12d4bf3a559535
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 17 00:43:24 2007 -0500
-
- fixed posix File.join and added edge cases to specs
-
-commit e7972b8617b8b0ef2a19a1f7ddedd4d93ab80f5c
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 16 21:17:21 2007 -0700
-
- Commit gnarg's loop specs (#49).
-
-commit 3fcdd60b4c9fc20081987bb13aab37b9419939a3
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Tue Oct 16 19:46:36 2007 +0200
-
- Make this spec usable by loading pathname.
-
-commit 276b6cc5620a5a3629d56b04ade7c397a48c2488
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 16 00:53:11 2007 -0700
-
- Exclude metaclass instances from Module#ancestors list.
-
-commit e108e7f3f8a6ef7cf2acf4bb7e7a6609900a3ebc
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 16 00:06:54 2007 -0700
-
- Updated CI excludes.
-
- Updated compiler specs to match recent changes.
- Added compiled core/string.rb from changes in edeffe90517.
-
-commit 1a1410f394b3de23b63560f2a5c1312cc6451d2e
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Oct 15 19:49:40 2007 -0500
-
- spec for __FILE__ added
-
-commit e158c3130f033a1029ae26888b8e7e541f2b388a
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Oct 15 19:46:58 2007 -0500
-
- spec for __LINE__ added
-
-commit d09ad9e6b28c91f5d00db5d0b369c4932eabbe2b
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Oct 15 18:45:48 2007 -0500
-
- spec for throw/catch inside of ensure reverted and clarified
-
-commit 0e5336f1572fc1ad766cff61d8843410d28df9db
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Oct 15 18:33:27 2007 -0500
-
- spec super refactored into fixtures and expanded to test all methods on each class
-
-commit b998ec8e682c3a0f2160066bb84f40b68f748407
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Oct 15 16:26:58 2007 -0700
-
- Implement undef and Module#undef_method
-
-commit fed8486110930cabce64e0421638a867740e4d21
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon Oct 15 15:54:44 2007 -0700
-
- A bunch more language spec cleanups.
-
-commit 66086cb333432a29d4c4ce4fec6a01c0ac88c5a5
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri Oct 12 19:33:59 2007 -0700
-
- Bunch of compiler fixes to pass more language specs
-
-commit 680e0ca4cafb20fa053f0dd5cd72915da9fbc86f
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Mon Oct 15 17:36:09 2007 -0500
-
- specs for super involving inheritence, modules and metaclasses
-
-commit 167febd232f5cf4696cf8e81a96d1c9d80744e36
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 15 15:32:48 2007 -0700
-
- Update CI excludes on OS X.
-
-commit 948e2573800859931e8c61e72069c21e9a50193b
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 15 14:23:02 2007 -0700
-
- Update compiler specs to match recent changes.
-
-commit a015bac050e1080548bd947c5f59b344175a809d
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Mon Oct 15 23:51:01 2007 +0200
-
- Enabled the remaining Bignum#& spec.
-
-commit 0b37b2946772ea41fe7b14c762be7fdbaa4a6f8d
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Mon Oct 15 18:20:56 2007 +0200
-
- Updated Spec excludes for Bignum.
-
-commit ae613272bcf0c260ad3da00ffd14d4a76422ac46
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Mon Oct 15 08:30:11 2007 +0200
-
- Added the beginnings of a File.stat spec.
-
-commit 81147d2eadb0397c2bcc1b9dd620bb55b6e0e53d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Oct 14 11:33:21 2007 -0700
-
- Fixed Float#to_s for numbers of the form "\d+.0".
-
-commit 2f9ba53190ca19ca425126d1319f47b3bbce12f6
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 14 18:57:04 2007 +0200
-
- Updated Bignum excludes.
-
-commit 0c81822cf703da13f6a8783cc6cd4ad453d2ff74
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 14 18:05:45 2007 +0200
-
- Add some OpenStruct specs.
-
-commit add2a900029530cb35b6463525313f432b7f36f4
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 14 17:29:38 2007 +0200
-
- Extended some more Bignum specs.
-
-commit 45cf3a275d390d4ae1d995eca89e10ba82d2288f
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 14 17:29:01 2007 +0200
-
- Extended the Fixnum#to_s specs a bit.
-
-commit d8a42cdd57967ee07cccfa5f3f814d97353c48c9
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Oct 13 23:16:37 2007 +0200
-
- Fixed the bug that broke 'case' blocks with a single 'when' statement.
-
- Acked-by: Wilson Bilkovich <wilson@supremetyrant.com>
-
-commit 5624627fd61378fce65aebf2ffacc39c45ac5ee6
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Oct 13 23:48:32 2007 +0200
-
- Ticket #37: Fixed Bignum#& segfaults when the argument isn't a bignum.
-
-commit 2081e5f53ba80cb9aa2ee272d4e543db1d4e732e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 13 23:43:08 2007 +0200
-
- Modify and extend Bignum specs a bit.
-
-commit 7917f4f8a538a3251e3cb17d55e4cf2a523af8d5
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 13 23:42:44 2007 +0200
-
- Modify the fixnum specs a bit.
-
- Remove dependencies on Exception messages.
-
-commit 171f25c25865da618c2e2a9a7b221abda613efa4
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 13 02:02:12 2007 +0200
-
- Extended Fixnum#<=> specs a bit.
-
-commit f708429a161c52dd713b4239527247c57fa158af
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 13 23:30:37 2007 +0200
-
- Guard bin/ci from running the new Bignum#& specs, which segfault (on OS X at least).
-
-commit 19f40e0ae1b60c037d0c38537a0924ad5726902a
-Author: Ben Curren <ben@esomnie.com>
-Date: Sat Oct 13 13:46:35 2007 -0700
-
- Refactored const_name_to_sym to share logic with Class#attr.
-
-commit ee9daad614fa746a3fe2fc1b9123c65dbb0814c7
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Oct 13 11:52:08 2007 -0700
-
- Identify which ruby platform and version before changing this spec!
-
- Revert "Fix spec to expect correct result."
-
- This reverts commit 8268469c563943cba6c1afce5d84defbc35f1789.
-
-commit 14a7781944491e5a1c3f5c664adcac4e1c383f2f
-Author: Tilman Sauerbeck <tilman@code-monkey.de>
-Date: Sat Oct 13 17:15:24 2007 +0200
-
- Added a failing spec for 'case' with only one 'when' statement.
-
-commit 8268469c563943cba6c1afce5d84defbc35f1789
-Author: Tom Mornini <tmornini@engineyard.com>
-Date: Sat Oct 13 03:22:47 2007 -0700
-
- Fix spec to expect correct result.
-
-commit 671f93c69e74976c3f5886c7fe8eb32402ccd338
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Oct 12 19:06:07 2007 -0500
-
- specs exiting threads using return, raise, and throw
-
-commit 119154a3ea5ecee20e77726b38fb58ee4b536d48
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Oct 12 18:59:47 2007 -0500
-
- spec to ensure throw exits from correct nesting and can return a value
-
-commit f36f68f075b34b5436257aba1ae41c14c04adcae
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 13 01:54:42 2007 +0200
-
- Method#[] specs should include the fixture classes.
-
-commit 22d32a24eb799307e42af55b04752c74ff500080
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 13 01:40:01 2007 +0200
-
- Extend Bignum#coerce, Bignum#&, Bignum#| and Bignum#^ specs.
-
-commit e1f682e27d2486d65297cf2121c354a99954a56e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 13 01:38:55 2007 +0200
-
- Removed a dependency on an exception message in Fixnum#coerce specs.
-
-commit 9754ed5e74eeb6d62f0015f3615d077aa2e58a6f
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Fri Oct 12 21:41:56 2007 +0200
-
- Fixed File.chmod and File#chmod specs on win32.
-
-commit 5ad3a4b7035bdade48586191c6e26cde1e74976c
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 13 01:37:46 2007 +0200
-
- Remove wrong spec from Bignum#divmod.
- Update CI excludes.
-
-commit b068c8634b56cd9129f9fc7c309bfa81869209c8
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Oct 12 18:21:52 2007 -0500
-
- specs for behavior of throw/catch and how they interact with ensure
-
-commit 45d4a8be8f20b2b70d32d0fdd340feb8897a1ad7
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 13 01:21:21 2007 +0200
-
- Add (skeletal) Process::Status.
- Set $? in Kernel#system and Kernel#`.
-
-commit ef1499962a16a7ce85bffe9e61863d2806caf6ec
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 12 23:52:16 2007 +0200
-
- Regenerate core/dir.rbc and CI excludes for Dir.
-
-commit b999f31ded2a7eccb856d95653a2826a3a190204
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 12 23:02:39 2007 +0200
-
- Fix typo in Dir.mkdir.
-
-commit de235630aa08df803be0420084b0a61ee35f5448
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 12 13:56:13 2007 -0700
-
- Added dev_null spec helper for capturing or silencing $stderr, etc.
-
- Fixed failing specs on OS X MRI 1.8.5.
-
-commit 01e27ea5fa0e0f0d170cd88f128adfbb2a2703bd
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 12 22:01:43 2007 +0200
-
- Add spec for backticks and their setting of $?.
-
-commit f7b18c19e47c15f3ab05f8fa548eff034206b0d8
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 12 13:21:03 2007 -0700
-
- Added guards to make specs pass on ubuntu feisty MRI 1.8.5.
-
- Fixed rspec_helper should_include to take multiple args.
-
-commit b2d25d4a502dca79ea98f60d937be7dbd8f496d2
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Oct 12 14:19:55 2007 -0500
-
- spec for retry/redo to control order of an enumeration
-
-commit eec535a19dc2b20156349720dc3bb526c9fa4f1e
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 12 18:53:33 2007 +0200
-
- Revert "Fix Kernel#`: set $? to the subprocesses exit status. Add a spec to check that."
-
- This reverts commit 40da2d5c68196c3c9002c4ca75ead0fefc520bef.
-
-commit 40da2d5c68196c3c9002c4ca75ead0fefc520bef
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 12 18:43:44 2007 +0200
-
- Fix Kernel#`: set $? to the subprocesses exit status. Add a spec to check that.
-
-commit 5da57253750e854bd9baf5378684222a895e7fd9
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 12 16:24:18 2007 +0200
-
- Shield "strange block args" spec from being run by mspec.
-
-commit 2a8f7d7dd6b0f7f800320f84d16d5d089357e085
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 12 14:48:42 2007 +0200
-
- Fix block specs for MRI.
-
-commit ade6c39f6199198e0015558698bc7d0333f7bcd0
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Fri Oct 12 12:07:49 2007 +0200
-
- Fix Array#delete specs.
-
-commit 825af45d5effb6909bb0832f92621b96e51dc380
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 12 01:15:23 2007 -0700
-
- Updated CI excludes.
-
-commit e1bfb47d3560929512cbdf5c27f56c92435ce29f
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 12 00:40:53 2007 -0700
-
- Removed printing summary at exit in mini_rspec.
-
- Set $VERBOSE=nil when running the specs.
- Fixed specs failing MRI.
-
-commit 1f1a041d8bcfaeb8dd3cb17f7d31b21281e690a2
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Oct 11 18:26:14 2007 -0700
-
- Moved shared specs to shared directories.
-
- Rewrote Module#method_missing specs.
-
-commit f9177eb198003b495f485a13910808fe603030ad
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 20:54:22 2007 -0700
-
- Added a failing test for setting and getting constants on an instance of a module.
-
-commit d9cbad87fd4d578e4f637627fa03cab312882a36
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 20:51:27 2007 -0700
-
- Updated the excludes for module tests.
-
-commit 938f034bad41f4fe3391b941e536bce9e1be0af6
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 20:49:57 2007 -0700
-
- Updated const_set_spec to not create a new instance of Module for testing purposes.
-
-commit 550caaf78723b00f95c5f8f38215b15a0940698a
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 18:21:01 2007 -0700
-
- Updated the excludes for the tests that are now passing.
-
-commit 82c51fc652e215f0dc421099329c03a37af8e8f8
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 17:56:48 2007 -0700
-
- Updated const_set and refactored the valid_const_name? further.
-
-commit c6323c74d0ee7b554d2cfbff3bd8d85ea910e0c9
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 12:01:27 2007 -0700
-
- Added logic to remove Object and empty from a recursive string for const_get and const_defined?
-
-commit c108d2a623f5041f46b6efa32d0b331f4f91d669
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 11:58:04 2007 -0700
-
- Added back the recursive case for const_get and const_defined?
-
-commit b976f184d8ade3b5d32d3e7ec11027c21c2bce2a
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 11:33:41 2007 -0700
-
- Refactored const_defined to use const_get.
-
-commit 82c5c14b948cedbf3bed5f7996634b0238e4de55
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Oct 11 17:38:05 2007 -0700
-
- Bunch of compiler fixes, almost have test/unit and optparse running.
-
- * Adds support for /ao#{name}/o (aka dregx_once)
- * Invalid redo's raise an exception at runtime instead of compile time
- * defined?(a.foo) works
- * Lots of work on getting the block arg semantics right, including a new
- instruction, passed_blockarg which is used to detect at runtime how
- many block args were passed in.
- * bug in 'yield 1, 2' versus 'yield [1, 2]' fixed
- * A little better error reporting on compile errors
- * Fixed Class#<, added #>, #<=, and #>=
- * Fixed Hash.new
- * Fixed nested case problem
-
-commit 1369b104a3f966dd4d279362afdc6ccb72f06de3
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Thu Oct 11 22:47:16 2007 +0200
-
- Fix String#eql? specs.
-
-commit b190009707c120edb257a9ad92697145092c5612
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Oct 11 10:57:10 2007 -0700
-
- Shield parse errors in block args properly
-
-commit 0509ecbd6aeb973061866c5e04c590f975174b41
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 10:21:08 2007 -0700
-
- Updated tests to test FixNum being passed to const_defined?
-
-commit 80116298779dc5afd3294cd83d758d76d0dcdf50
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 10:16:46 2007 -0700
-
- Added error checking to const_defined?
-
-commit eed3ae097b1dae17e45cdb959b75d1fa7cf21c1b
-Author: Ben Curren <ben@esomnie.com>
-Date: Thu Oct 11 09:25:53 2007 -0700
-
- Convert paramter to_str if it responds to the method.
-
-commit 348df85a082eee56c301bce594d6c522050e34dd
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 10 18:49:34 2007 -0500
-
- specs for language/retry and updated redo to show differences between them
-
-commit e924e2bb206317e8f5375c979f5e4e1046fccca9
-Author: Tom Mornini <tmornini@engineyard.com>
-Date: Wed Oct 10 00:55:47 2007 -0700
-
- Add Class#attr, refactor Class#attr_reader, Class#attr_writer and
- Class#attr_accessor, pass all specs for Class#attr_*, fix a couple of issues
- with said specs.
-
-commit 21b0bdc67c6a8cc4ad4b9d3942a2608fb45da31d
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 9 15:10:04 2007 -0700
-
- Commit #198, patch from Will for Module#(private|public)_class_method.
-
-commit 2cf5f0b4683d0a65181c1450d0714c4e165db1cd
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Oct 9 21:00:13 2007 +0200
-
- Moved shared specs.
-
- Moved shared specs into the 'shared'-subdirectory so specs don't depend on each other anymore. Added some more shared specs.
-
-commit e558fab61ce9f7c5211d005aff2c5e8fc1b39931
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Oct 9 19:53:46 2007 +0200
-
- Fixed a failing Array#each spec. Closes #14.
-
-commit 0d77eefd718c826e02376edc8643364eb511773d
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Oct 9 19:09:17 2007 +0200
-
- Removed remaining dependencies on Exception messages in Fixnum specs.
-
-commit dd4063ba46eb313a57957d76dce3608dd8e5c161
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Oct 9 18:58:01 2007 +0200
-
- Fixed String#crypt spec.
-
-commit d5a2bb2b000fae7391e512c5bcab054ce967de3b
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 9 09:35:51 2007 -0700
-
- Updated CI excludes after applying Akshay's Precision specs patch.
-
-commit 10cd5764bbf51f1defa6815f8b07fcdce0de8875
-Author: Akshay Rawat <akshay.rawat@gmail.com>
-Date: Thu Oct 4 21:48:15 2007 +0530
-
- Specs for the module Precision
-
-commit 2e711c30e4e9ce50d9c20ab14a3b99ea47be32e9
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 9 13:56:45 2007 +0200
-
- Make IO#puts specs pass in MRI.
-
-commit 13dc28c47c3211f01663d002847badb50277f277
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 9 13:44:51 2007 +0200
-
- Silence warnings when running Hash specs in MRI.
-
-commit 52f903938f4eacf4465f7a36cacb25aa662aa559
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 9 13:44:02 2007 +0200
-
- Turn Hash#values_at into a shared spec.
-
-commit 1e02ced5a68f16b8a65809136d954c68c9fdc590
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 9 12:59:58 2007 +0200
-
- Add a few more specs for Struct#new.
- Regenerate CI excludes for Struct.
-
-commit 94ea8c1f25761384796e9499e0b4b3faeba9da66
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 9 12:48:03 2007 +0200
-
- Silence warnings when running Struct specs in MRI.
-
-commit 5ea6b219a8465cfad86dae9ae12d6a8d85812532
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 9 12:42:58 2007 +0200
-
- Apply patch from ticker #23 by Jon Guymon (gnarg).
- Make Struct specs not depend on method argument evaluation order.
-
-commit 8cbf7b94300e6ebcc0ee3cbe0de8123ef3563e96
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 8 22:08:29 2007 -0700
-
- Fixed that including a module includes the whole chain.
-
- Fixed that Module#include only allows modules.
- Simplified some module fixtures.
- Updated CI specs for module.
-
-commit 4e7e2768d50392831a4d26f236d4cff733418225
-Author: Ben Curren <ben@esomnie.com>
-Date: Mon Oct 8 11:54:51 2007 -0700
-
- Added puts spec for io and updated IO implementation to match MRI's. Updated Kernal#puts to delegate to $stdout.puts.
-
-commit edc724086e84725995ed1720d4fa7a781fd9c3c6
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 8 09:24:40 2007 -0700
-
- Updated CI excludes for Module#define_method.
-
-commit a53ddb723a10d692223f05a49679e17f403fa128
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Mon Oct 8 01:05:04 2007 +0200
-
- Fixed some Fixnum specs to not depend on error messages.
-
-commit d6bc4b47f3f395980c92f323cf029da1ccdba709
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 7 23:42:12 2007 +0200
-
- Added another failing spec for Module#define_method.
-
-commit 49435e31289f593a118377b3513ec9e7cdfea06b
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 7 23:37:19 2007 +0200
-
- Added failing specs for Module#define_method when given an UnboundMethod.
-
-commit 821c0114777fb2a77f1c85f216ee54e4c5340943
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Oct 7 22:29:47 2007 +0200
-
- Apply patch from ticket #15 by Jon Guymon (gnarg).
- Add Struct#eql?.
- Rebuild core/struct.rbc.
- Add more struct specs.
- Update CI excludes for Struct.
-
-commit 1f14c3510d4563930d11155f36717c0fb851c678
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Oct 7 18:13:33 2007 +0200
-
- Added some GetoptLong Specs.
-
-commit f9c8c00649212b924561300abbd0cb037c1d278d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Oct 6 23:00:05 2007 -0700
-
- Update CI excludes for File#executable.
-
-commit 6d4427d07fc474e2404cdd2b6f3b925d99d90e67
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Oct 6 22:50:45 2007 -0700
-
- Updated spec/excludes.txt from 72 items to 17.
-
- Added -V | --verbose flag to bin/mspec.
- Updated CI excludes.
-
-commit d4f5e44a8e2f8e682b779f45d12d060e83eb9fc7
-Merge: a035e9d... 42abc5e...
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 15:18:45 2007 -0400
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit a035e9d3d204cf7e5ddb2fec72ca471ff33c3b9b
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 15:13:28 2007 -0400
-
- fix a bug in the File.executable? spec
-
-commit 3c23c945aaf143aa8706b1cd2956908a71940e26
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 15:09:55 2007 -0400
-
- fix bug in File.executable? spec
-
-commit 94e59065bf921ae167a6b04edfef40de336978a1
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 15:03:14 2007 -0400
-
- Revert "Revert "Add a few more Proc#call specs. And CI excludes.""
-
- This reverts commit 7658362c3882c6be2ef67f6b57d6c6796ff5de98.
-
-commit 42abc5ed6e1ced2fa86e9dc9379c6bed4da4537e
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Oct 6 11:40:49 2007 -0700
-
- Updated CI excludes for Kernel specs.
-
-commit 7658362c3882c6be2ef67f6b57d6c6796ff5de98
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 14:29:28 2007 -0400
-
- Revert "Add a few more Proc#call specs. And CI excludes."
-
- This reverts commit 567659dee34014d037d4797bf0c171597e0ac05d.
-
-commit 567659dee34014d037d4797bf0c171597e0ac05d
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 16:23:54 2007 +0200
-
- Add a few more Proc#call specs. And CI excludes.
-
-commit d8e737b09f8ed984e57b4fbbd5c016a7643aa67d
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 15:56:33 2007 +0200
-
- Fix Array#slice specs. Regenerate CI excludes.
-
-commit c79eeb620296a1802e6d194463063555638911bf
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 14:34:05 2007 +0200
-
- Fix Array specs that depended on respond_to? being called on coercion.
- Regenerate CI excludes for core/array.
-
-commit 8a60522fd8237fdfa36ef5518c9642216c66f8d6
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 14:08:22 2007 +0200
-
- Guard Array specs for #freeze. Fix MRI Array specs for #freeze.
- Regenerate CI excludes.
-
-commit eaaab65c54c3b81397441169761774ef95867297
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 12:47:55 2007 +0200
-
- Add specs for Proc#call. Regenerate CI excludes.
- (Most of these seem to be from e6cf8978.)
-
-commit 19bcb0f6ec1b2247985823492f0c25f0aa5d94ab
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 12:09:29 2007 +0200
-
- Slightly amend the core/hash specs.
- Regenerate CI excludes.
-
-commit 6d1afe325098a73757980bb208fb2c8c64bd016b
-Merge: ac9365e... 0d22ef5...
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 01:13:59 2007 -0400
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit ac9365e384263b6f062353f2afab3e33d8f84f3e
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 01:13:23 2007 -0400
-
- added spec for OpenStruct
-
-commit e6cf8978a6dd441d5d4793c48438fab4150ca750
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Sat Oct 6 00:14:01 2007 -0400
-
- added several tests to Proc
- added tests for Kernel#lambda and Kernel#proc
-
-commit 7b69ae066cab2252375d1ad19c6f17b365c47c32
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 5 18:51:11 2007 -0700
-
- Updated CI excludes for Array.
-
-commit f216e89033d10f3500798561282e48aa0e5b5537
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Fri Oct 5 20:45:41 2007 -0400
-
- really simple spec for the Singleton class.
-
-commit d682b176237a988afa7ebdb3460d64ea41fab919
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Oct 6 01:54:31 2007 +0200
-
- Applied esomnies
-
-commit b3018362c0cad86a5a026eb39b5f6ea4a8af1192
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 01:24:05 2007 +0200
-
- Guard Hash specs for #freeze.
-
-commit a185f463adbab1d6f82126dde9abe88a29e83283
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 01:15:23 2007 +0200
-
- Fix workarounds in core/hash specs.
-
-commit d796eb3d8a5d9a070b105f1fe0e9f46be5bfaaee
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Fri Oct 5 17:09:48 2007 -0500
-
- specs for UDPSocket client/server
-
-commit 46a9c1a0d0610865b659c289293b444f0b3d6ae9
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 5 15:32:56 2007 -0700
-
- Fixed bin/ci to not load spec/excludes.txt for every file.
-
- Fixed bin/mkspec to not overwrite an existing spec file.
- Updated Fixnum CI excludes.
-
-commit 1099f49c06de5621aff36216179f46c308e60a38
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 5 14:40:24 2007 -0700
-
- Added basic IO#readlines spec and implementation.
-
-commit edc438039ee503c7b9d1fb83b04bd9bc1664cda5
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sat Oct 6 00:09:41 2007 +0200
-
- Regenerate core/hash.rbc, core/hash CI excludes.
-
-commit 2ad7d015a316620a488ed1cdeb45fe696b9d410a
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 5 23:56:59 2007 +0200
-
- Extend core/hash specs to check for LocalJumpErrors.
-
-commit 42d961f0ab8a7e23a822b41ca82aaed5a48da2bf
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 5 23:21:20 2007 +0200
-
- Refactor and fix Hash#inspect.
-
-commit b51402d8724478b85789d19857a2a48442470fcb
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 5 11:29:08 2007 -0700
-
- Fixed bin/mkspec to not create the spec file stub if the file exists.
-
-commit efe79de398db491ce97666a3f4f3b38265c1ab95
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 5 10:55:52 2007 -0700
-
- Updated CI specs. Guarded String specs for #freeze.
-
-commit 8647951df433d427be31bec060edf5b7efb46e46
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Fri Oct 5 17:04:25 2007 +0200
-
- Replaced all occurrences of Object#coerce_to with Type.coerce_to and removed Object#coerce_to.
-
-commit 778e11d2df647cf91a712bb30df34152c71dbc3f
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 5 11:42:40 2007 +0200
-
- Don't work around rbx bugs in Hash specs.
-
-commit 4b42923eb2cdebe43f9e9dd80fff98d9ded26e4b
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 5 11:29:33 2007 +0200
-
- Fix Hash specs to pass in MRI again. (Doh!)
-
-commit 8a4f0b1c0d95b7a87ed99583797cf7d3710fb15a
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 5 02:24:30 2007 -0700
-
- Updated CI excludes for Hash.
-
-commit cecbf342546f37f4923728e8381e7fafcb039633
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Oct 5 02:22:41 2007 -0700
-
- Changed bin/ci to run in a single process. Updated CI excludes.
-
-commit ba0f4ef5405665c84af4410d70be5ef911a93195
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Oct 4 22:58:50 2007 -0700
-
- Adds the intern spec from Ticket #8
-
-commit 0721f6ea40f51202ec9d2d421061be92e05a18b9
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Thu Oct 4 22:39:00 2007 -0400
-
- Commit #207 Xavier Shay Enhanced specs for Hash
- fixed Binding#dup spec
-
-commit ce4a1866ef65e041fbed224c3f694ca534d0a0d1
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Oct 4 18:24:21 2007 -0700
-
- makes String#delete faster
-
-commit 7ec0eeadf554150159f0a04468b16de8f06c2e8a
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Fri Oct 5 00:32:25 2007 +0200
-
- Whoops, two more frozen TypeErrors I forgot.
-
-commit 78a3de42bf0e6f1478b2aac903c25143fd56195a
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Thu Oct 4 23:17:42 2007 +0200
-
- Regenerate CI excludes and core/hash.rbc after revert.
-
-commit beaa5d022b19cb70213d4fe14e10d7f1a5f90a3a
-Merge: c7ea881... 8cb4b0b...
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Thu Oct 4 16:12:41 2007 -0500
-
- Merge branch 'spec_block_parameters'
-
-commit 8cb4b0b2c3c766618a523a0ef9a83106761ee2f8
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Thu Oct 4 16:11:15 2007 -0500
-
- specs for setting variables in block parameters
-
-commit c7ea8812f74184e6ee33bb236766f32fface2f95
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Thu Oct 4 22:57:09 2007 +0200
-
- Regenerate CI excludes for spec/core/hash. New hash.rbc.
-
-commit 939e8c533fb70586f8c7c6f3506d6be13f492d78
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Thu Oct 4 22:11:18 2007 +0200
-
- Fix Hash specs: don't depend on coercion to call respond_to?
-
-commit 422e45f210ec9dc2438ae3b11544823bb6ffdd50
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Thu Oct 4 16:21:27 2007 -0400
-
- added specs for FileTest#exists? and FileTest#exist?
-
-commit e43466b52184a042bd38d33273acf7afa4580a96
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Thu Oct 4 16:12:58 2007 -0400
-
- added spec for File.exists?
-
-commit 9f69c8193d92752a2be7c21d23dfe90fb9765f11
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Thu Oct 4 16:03:33 2007 -0400
-
- fixed grammar error in Method#clone
-
-commit 9321aacf703eaec6d6bc26cce83ed7475cb27d46
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Thu Oct 4 16:00:31 2007 -0400
-
- added several specs for Module
-
-commit a282c1c4c137e1bdeae34f2f9cd58bc73f257809
-Author: Jason Yates <jaywhy@gmail.com>
-Date: Thu Oct 4 14:19:07 2007 -0400
-
- added specs for Kernel#binding and Binding
-
-commit 3e92b4528dbf47b80a25232979554f7e4309460a
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Oct 4 10:45:10 2007 -0700
-
- Fixed ffi_sprintf_[fd]. Updated String spec CI excludes.
-
-commit 9e9a292a8a4befeb8a928d476119b02ac0df976e
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Thu Oct 4 18:53:47 2007 +0200
-
- Alias Object#object_id to Object#__id__
- Regenerate CI excludes for spec/core/kernel
-
-commit 8790e93c6d231baf7da07f11d02b91a38d28375e
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Oct 3 18:23:42 2007 -0700
-
- Superclass checking and loop {} fix.
-
-commit 718ae6f28223e94b8ca0f3af7ce321c81a597804
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Thu Oct 4 15:05:59 2007 +0200
-
- Slightly extend Object#kind_of? specs.
-
-commit 7fa087a7058fe8872bb9743abd6dd472cd2119d7
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Thu Oct 4 08:43:55 2007 +0200
-
- Fixed some String#slice specs.
-
-commit b9be176a9e64669f2a787c9bdebc1ba30e344d97
-Author: Paul Meserve <pmeserve@gmail.com>
-Date: Thu Oct 4 01:37:56 2007 -0400
-
- adding String#each_char
-
-commit c1b17108a78a4dc5d3e224158f8f9d76232003e6
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 3 17:42:06 2007 -0500
-
- basic specs for Kernel#sleep
-
-commit 1fe895518bdccb93991f85a92f53876ed3d4df13
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 3 14:16:14 2007 -0500
-
- added spec for Kernel.local_variables
-
-commit 00417283b36dcb58da82c6fc2e9be7580de945b0
-Author: Charles Comstock <dgtized@gmail.com>
-Date: Wed Oct 3 14:15:25 2007 -0500
-
- added specs for Kernel#global_variables
-
-commit 5b944520099f129462c3b03fa6ee7d1bb0636fc0
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Wed Oct 3 14:07:09 2007 +0200
-
- Fix String#index specs.
-
-commit c9cdef77c7fa8dda92c91cee5a47624b9c9dc9e8
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Wed Oct 3 14:05:34 2007 +0200
-
- Fix String#hex specs
-
-commit 4625a7afe509545f782cd4631632b4d7a58011aa
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Tue Oct 2 23:53:20 2007 -0700
-
- String#% works with a few exceptions:
-
- * %u doesn't work (it's aliased to %d for now, as in 1.9)
- * There's a weird glitch in Float(10_1_0.5_5_5) that I can't track down
-
-commit 54ab6f559093e66f78cfa30db8aa6587061552d6
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 02:05:41 2007 +0200
-
- Extend Kernel#kind_of? specs.
- Regenerate CI excludes.
-
-commit 4583be7e7ed76e5843dcb396f8bae735f341de73
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 02:03:58 2007 +0200
-
- Remove superfluous whitespace from Object#kind_of? specs.
-
-commit 5c237626469f4b0f4d227916752dd2e03510fcf9
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:50:33 2007 +0200
-
- Remove superfluous comment from Object#kind_of? specs.
-
-commit 7a2c673d04b0d0506e89073ff231104e21c3304c
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:47:56 2007 +0200
-
- Simplify Kernel#freeze specs.
- Move Object#extend vs. frozen? spec to extend_spec.
- Rebuild CI excludes for Object#extend specs.
-
-commit 3f6a27603b0b1f91ce32b9ff2a5fe3222fa7220b
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 2 17:03:37 2007 -0700
-
- Commit Charles Comstock's language return specs.
-
-commit ad4e7affcbaae4f0e967c97da485313168595a5e
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:36:27 2007 +0200
-
- Fix Kernel#caller.
- New core/kernel.rbc.
- Regenerate CI excludes for Kernel#caller.
-
-commit 73b2ef1c889c940d22da6ad6bb8882eef66592fa
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:34:10 2007 +0200
-
- Add spec for checking the default argument value for Kernel#caller.
-
-commit 180ecd6a7fa1d32e1932a322b1f8f82efd558e7f
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:32:29 2007 +0200
-
- Add spec for checking that Kernel#caller returns nil.
-
-commit 9ad0c1428df70c9fd9e0081651e3b60cf5773267
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:30:46 2007 +0200
-
- Add spec for checking the argument handling of Kernel#caller.
-
-commit 7a9483b823115b3122a4e42b21dfcb5b0f369a54
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:23:17 2007 +0200
-
- Refactor the tedious part of the Kernel#caller specs.
-
-commit e204755859e4dc147217816ab3bf587db3d51dd6
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Wed Oct 3 01:22:26 2007 +0200
-
- Cleanup description of Kernel#caller specs.
-
-commit dadbbb7930b62a4a6e47c8c32a4d9f26fcea38b4
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 2 23:52:49 2007 +0200
-
- Regenerate CI excludes for spec/core/kernel. Again. Because I fixed the typos.
-
-commit 4a3587da37fd27effb30356fdd2e496f8c898be7
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 2 23:45:33 2007 +0200
-
- Fix CI specs to pass in MRI 1.8.6.
-
-commit a46f5085f3c2a4849fe709044e447e5d6dacda4f
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 2 23:27:51 2007 +0200
-
- Fix typos in spec/core/kernel specs.
-
-commit cb3d5867ec91a59a2a75136eb5210a10540b0ce0
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 2 23:27:23 2007 +0200
-
- Regenerate spec/core/kernel excludes.
-
-commit 22e6fe0ef8dbf13aa01124447e09c9dc96f63fe3
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 2 23:26:51 2007 +0200
-
- Fix Kernel#Array spec: don't depend on the exception message.
-
-commit 7b79130f38925cb48712be617cef5a80c71f0ba4
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 2 14:29:42 2007 -0700
-
- Commit #5 (LH) Charles Comstock Process.wait2 spec.
-
-commit 859c119a48909030f29a2085fbe0a80ed96d2408
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Oct 2 20:57:31 2007 +0200
-
- Fix Float#to_i and add a spec to catch the old misbehaviour.
-
-commit f2b5b2304588b4fb0efd9818c79a4b9774b2c850
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Oct 2 19:07:49 2007 +0200
-
- Fix some String#scan specs.
-
-commit 8e0ce11df329181efa440cbd55f29848e12188bf
-Author: Kevin Clark <kevin.clark@gmail.com>
-Date: Tue Oct 2 00:39:15 2007 -0700
-
- Add error handling for Dir.mkdir/rmdir
-
- Add aliases for Dir.delete/unlink
-
-commit 20e66dd965bfceb29e4939090a0fd543d05392a3
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Oct 2 00:21:49 2007 -0700
-
- Commit #206 Jason Yates' UnboundMethod specs.
-
-commit 00d7d22b7d106c6aac5d9664cb444e14811171b0
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Mon Oct 1 17:57:29 2007 -0700
-
- First pass at actually getting my modulo impl working
-
-commit c90766a09c7e1fe7a2261f8b09d9caa8eaf2214e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Mon Oct 1 21:21:34 2007 +0200
-
- Fix the String#crypt spec.
-
-commit a0f6f8e51a6f7a65230f8f2ea53587ccb09f9270
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Mon Oct 1 20:18:29 2007 +0200
-
- Changed the String#to_f specs a bit.
-
-commit 21d43e565bb55a31b45dc9fabbefface156ec516
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Oct 1 16:13:28 2007 -0400
-
- Add failing Array#pack spec for use case taken from Mongrel
-
-commit b1d70b4a847fc1c8df3eb4a219c4318420121e82
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Oct 1 09:04:03 2007 -0700
-
- Commit #205 Jason Yates' Method specs.
-
-commit de7e0f0183d072f101e0781635fc2fdb1af1b851
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Mon Oct 1 00:11:12 2007 +0200
-
- Fix compiler specs to expect sret when appropriate.
- Rewrite compiler specs for multiple assignments.
- Regenerate CI excludes for compiler specs.
-
-commit 1d1e704306fca4453d600259e87175dcdc9de314
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 23:27:12 2007 +0200
-
- Add edge cases for File#extname specs.
-
-commit 108d757e6c24447b89fa785b2bf091b72d29933d
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 22:34:15 2007 +0200
-
- Regenerate CI excludes for Dir specs.
-
-commit 20c6c3cd9b5d59b9782b702ac6afeb828e895d5f
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 21:49:52 2007 +0200
-
- Make Dir specs pass in MRI.
-
-commit dcd172338bce5b70cb367db3c1e6f4653c05f9e8
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 21:10:36 2007 +0200
-
- Fix case comparison with Symbols.
-
-commit 2a45cd71d1eb90a7c11ff62d81371df9479b0d43
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 13:28:32 2007 +0200
-
- Add specs for String#tr! and String#tr_s!.
- Cleanup specs for String#tr! and String#tr_s!.
- Regenerate CI excludes for String#tr! and String#tr_s!.
-
-commit 6418bd672c8ea031d8ac2364c8a98bb631e53deb
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 13:26:19 2007 +0200
-
- Add specs for multiple asignments with splats vs. Array#dup.
-
-commit 10b04881d286acab9dc97147750743e03ee4509f
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 13:25:14 2007 +0200
-
- Fix Class.new to raise TypeError when the superclass is not a class.
-
-commit 0b9debba0672305f8551f5d5f35cdd3aaf16c1f1
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 13:20:49 2007 +0200
-
- Add specs for the names of classes generated with Class.new.
-
-commit e15cef6eb851318838351a4d8717b708bb09d31d
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 13:15:43 2007 +0200
-
- Remove debugging output from spec/core/dir/chdir_spec.rb
-
-commit f3251ba0e8ade79f157bc02dca550481488bf888
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Sun Sep 30 13:15:17 2007 +0200
-
- Remove debugging output from spec/core/extensions/rubinius/options_spec.rb
-
-commit 5d4d2abaf02aef6caa7e532208da5e5f57bc6373
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Sep 30 20:54:14 2007 -0400
-
- Working Socket implementation and specs. Still needs readpartial to support Mongrel.
-
-commit b514e53f589d509c287516d8dd985f96e66d9a1c
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat Sep 29 15:44:06 2007 -0400
-
- Working IPSocket#peername implementation
-
-commit 965ed2d88527ae8aa4ac962e8ca84180f61e6345
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Sep 24 02:34:26 2007 -0400
-
- Yet another interim socket commit
-
-commit ecd54e981a1098c4b3abf14587212e7d1d9049a6
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Sep 20 16:29:21 2007 -0400
-
- Another interim Socket commit
-
-commit 351bbdf08f190e24328328df7b3f995b8dc27a9f
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Sep 19 22:17:52 2007 -0400
-
- Interim commit of Socket work so I can generate a patch
-
-commit 65a73cdfea95c5991f2044bee150e53643216ad3
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Wed Sep 26 13:15:45 2007 +0200
-
- Added some Marshal#load and Marshal#dump specs.
-
-commit 89e1b91c606dfe18581c3ed3923340b952471d8e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Wed Sep 26 13:15:19 2007 +0200
-
- Extended Specs for Kernel.Float and Kernel.Array
-
-commit 5d46933362b8c54cb5d0370bbf61e063459de514
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Wed Sep 26 13:14:41 2007 +0200
-
- Added specs for Symbol.all_symbols.
-
-commit b3324808584d7b4ee6af58d98eeb7c2162c31208
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Sep 27 10:57:46 2007 -0700
-
- Commit #180, Jason Barton's specs for Module#undef_method, #remove_method.
-
-commit 2e1219fc03d9cb673074ee34b1f8af4bdffe9c0e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Thu Sep 27 18:49:26 2007 +0200
-
- Fix Kernel.Integer by making use of String#to_inum. Add some more Kernel.Integer specs.
-
-commit b0d4747cab49f4a17e9899392171087d7b67f687
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Thu Sep 27 18:23:42 2007 +0200
-
- Fixed String#to_i. Added String#to_inum. Extended String#to_i specs.
-
-commit 2799c392b3f5383e9e74745ceb9cf7a52f82918b
-Author: Paul Meserve <pmeserve@gmail.com>
-Date: Thu Sep 27 01:20:00 2007 -0400
-
- fix for Struct#new and a small struct spec changes
-
- (also re-ran bin/ci on struct specs - most of the changes were from previous commits though)
-
-commit 30d9bf1f6ef9dcff067d427d6226bbce985f5e69
-Author: Paul Meserve <pmeserve@gmail.com>
-Date: Wed Sep 26 19:08:37 2007 -0400
-
- raise proper error when passing non-block args to Enumerable#all?
-
-commit 1ef1e0ef65ef3c86558da3d313dee5cada6dd4c5
-Author: Paul Meserve <pmeserve@gmail.com>
-Date: Wed Sep 26 17:25:17 2007 -0400
-
- adding alias for Float#quo to fix a couple number specs, and some modifications to Enumerable#min/#max, along with a couple new spec assertions. fixes failing specs and implementation should be a lot closer to MRI
-
-commit 547dd89791d92f061afcaef7184f054affae871d
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 26 09:46:50 2007 -0700
-
- Fixed placement of after(:each) block in numerous File specs.
-
-commit fa3dcbfdd623a7a7cdb15bc29b38ae47bb4056d5
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Sep 25 20:25:36 2007 +0200
-
- Added specs for UnboundMethod#arity
-
-commit 33783408b8ce1bdfcd205fd02bc3848119a632cc
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Sep 25 18:00:10 2007 +0200
-
- Added specs for Class.
-
-commit 0edea3c3a7dda5c453c527b2cef3ffba1eef1396
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Tue Sep 25 17:25:40 2007 +0200
-
- Created some specs for Proc.
-
-commit 62c92f1c3aef6c2ff7ab8cbcd49eefb236d5caed
-Merge: b79d04d... 2d9c698...
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 26 01:09:42 2007 -0700
-
- Merge branch 'dir'
-
-commit 2d9c69848f4ca34685b95b07e17d1b5fe1ec2391
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 26 01:09:28 2007 -0700
-
- Updated CI spec excludes for Array, Dir, Fixnum, Enumerable, Hash.
-
-commit b79d04db673d9b7b5cc47f2918bccf1b0400bdbd
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 26 00:56:01 2007 -0700
-
- Commit crayz's patch from #195, #196, #197.
-
-commit ec960578671a327469d9545d6ced827736ceafa0
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Sep 25 19:40:54 2007 -0700
-
- Fixed Dir specs failing MRI after conversion.
-
-commit 00b398352ed0f4cbcd326d56b7f8a4469056ee0d
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Sep 25 00:54:06 2007 -0700
-
- Many cleanups of Dir specs.
-
- Added Dir specs fixture directories and files.
-
-commit b75cfa7c0a9871dc34b8b315ca2311e65000b2f3
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Sep 23 00:41:36 2007 -0700
-
- Converted Dir.glob specs.
-
-commit 3d8ea2a55e67cc6cfb85d2f4f7845a45984f6504
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Sep 25 21:52:54 2007 +0200
-
- Fix a few Struct specs. Failures are down to 15.
-
-commit a477ff678e9f5f39d3d2b94e559c77b34f0c56c5
-Author: Martin Kuehl <martin.kuehl@gmail.com>
-Date: Tue Sep 25 20:51:38 2007 +0200
-
- Fix compiler warnings in Subtend spec extensions.
-
-commit db3e1be4e25b7e8cc463443d050afe9a5acaa7de
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Mon Sep 24 22:31:03 2007 +0200
-
- Extended Fixnum specs.
-
-commit d136b779736af52d1eac08a40814ab4a47de93b3
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Sun Sep 23 17:47:30 2007 -0700
-
- Array#each explosion spec
-
-commit 8a24a71ff13aac465f7f4a14587981c3c23dc800
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Sep 23 20:06:04 2007 +0200
-
- Extended Comparable specs.
-
-commit ea9ba046ddfe91601d4453972a6d6f8fce96c392
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Sep 23 12:17:17 2007 +0200
-
- Fix Numeric#divmod and Fixnum#divmod.
-
-commit 1c5ecb9d2e9066c66b9f0625d65cc4cefaee1f83
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Sep 23 12:00:16 2007 +0200
-
- Fix Float#to_i for infinite, negative values. Fix Numeric#/ and Numeric#div. Add Numeric#do_coerce.
-
-commit 2d67d024e11e887eb07622963bfc36b0ec377746
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Sat Sep 22 20:08:38 2007 -0700
-
- Added Onig 5 and got rindex working with it
-
-commit adc26eb525447010e28fc884eaa54b9d2228f4d6
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Sep 23 01:35:11 2007 +0200
-
- Fix Kernel.Float specs
-
-commit 9a2ecf258fee3bda410776b3d3b77366590d64fe
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Sep 22 23:18:46 2007 +0200
-
- Extended more Fixnum specs. Removed the spec/fixnum/induced_from_spec.rb.
-
-commit 53b0042824bb1b1c523d790cb3645aec6b789abe
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Sep 22 22:35:53 2007 +0200
-
- Extended many Fixnum specs.
-
-commit 8661cdb78cd2c4afa0fb231aa9cc959e338e097e
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Sep 22 22:35:11 2007 +0200
-
- Extended nil#to_s spec.
-
-commit 4008d8b39032ffa5667e95fb445ff816b1428330
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Sep 22 14:25:27 2007 +0200
-
- Added some more specs and fixed some bugs in Range#initialize, Range#step and Range#each.
-
-commit 254e3d57dc6e859616ca7e0c44058d4b73211f68
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sat Sep 22 11:31:02 2007 +0200
-
- Some updates to Range specs.
-
-commit b87e28bfc06e81fe5c4c3d6e285947f635f79f61
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Sep 21 20:12:18 2007 -0700
-
- Commit wycats Regexp.regexp_match_region primitive.
-
-commit eaa56811836b4b5ed09a5e26d00f26eb004f2853
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Sep 21 18:44:25 2007 -0700
-
- Added StringValue to some File methods.
-
- Upated File CI spec excludes.
-
-commit 83f7b6020dbc881fbd6bd13da6ebb049d6080c2c
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Sep 21 17:54:53 2007 -0700
-
- Upated spec excludes for Float, Fixnum, and Math.
-
-commit af0b0c8da8357fcae7437f6cdfd7797f03ffd73b
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 20 22:10:54 2007 -0700
-
- Fixed a number of string-related issues:
-
- String#inspect respects $KCODE
- String#inspect returns tainted subclass
- String#dump is no longer a copy of inspect, and does not respect $KCODE
- String#match tries to call #to_str if it can before throwing an error
-
-commit 9409ace6d3e97946d10f9f7fcefa69ebcae43c47
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 20 16:55:11 2007 -0700
-
- String#index works
-
- Tweaked spec because [[x,y], [x,y]].each{|x,y| ... } wasn't working
-
-commit 6a72e4c4defef170f53a31c930c112022934dbc4
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Sep 20 15:22:28 2007 -0400
-
- Correct StringIO#reopen specs and implementation. Submitted patch for 1.8.x stable.
-
-commit 2b10dd99c2de4f97b5faa45060eba929d02052c4
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Wed Sep 19 22:20:33 2007 +0200
-
- Implemented File.identical?
-
-commit 2c3c1fc7bd2f6365b28262cae46872eb0925c2e7
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Wed Sep 19 21:48:13 2007 +0200
-
- Implemented File.link.
-
- Kudos to the Frankfurt Rails User Group! :)
-
-commit 0330b22006e39b5b173c78800f412831296de59a
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 20 01:32:43 2007 -0700
-
- String#gsub works correctly
-
- There was a weird segfault issue which I tracked down to a use of gsub inside of gsub.
- I got things working by extracting that functionality into a mini-gsub for just that
- use case, but we should fix it.
-
-commit 6c825ce63ca0eb7d6f882a767ee0e6a597219883
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Sep 19 22:14:31 2007 -0400
-
- Discover and fix an edge case in StringIO
-
-commit 6bd7adcfa115f11829a7efe8f526fabbb56d5c4c
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Sep 18 19:00:20 2007 -0700
-
- File.fnmatch(?) now passes all existing specs.
-
-commit f626f4199b88ca09a2ba75127270c0bec2ec2c86
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Mon Sep 17 15:04:44 2007 -0700
-
- Adds a new match_all primitive
-
- * will be used as the base of regex-related String functions
- * is called match_all instead of scan because it's more primitive than Ruby's scan
-
-commit 0b42d4d2610ec36a4ae5e21c37d5b587f2b9dcf8
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Sep 17 02:06:50 2007 -0400
-
- Avoid using $/ in IO#puts and StringIO#puts
- Additional StringIO specs and fixes for failures
-
-commit 75969031a57bea50e4a6450bbc9ae9e5adf76fa7
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Sep 16 18:26:29 2007 -0700
-
- Replaced File.fnmatch FFI version with custom version.
-
- The custom version is needed to be as compliant as possible
- with MRI on different platforms.
-
- Lots of fixups to File.fnmatch specs.
-
-commit 18d098062cb1b996a571a946740eea7c52421e12
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Sep 17 01:11:45 2007 -0400
-
- Some failing sprintf specs and then the fixes for said failures
-
-commit 84f94ab41d72012e4ec3d0d236b183fd8a51fbe0
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon Sep 17 00:53:30 2007 -0400
-
- Additional StringIO specs and fixes for the failures that arose
-
-commit 9b44df55c682f239f036d46efe45edc2190a7345
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Sep 16 12:55:27 2007 -0400
-
- Add StringIO spec for $/ global handling
-
-commit dfcba62eb69f88d373359c75c3fa7fe827e24c69
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Sun Sep 16 00:43:41 2007 -0700
-
- Fixes string/equal_spec to pass
-
-commit 5026350a166b94fc5fffff70dae510fa2abf2094
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Sun Sep 16 00:20:52 2007 -0700
-
- String#slice works
-
-commit a4f3aa09d3aeb8d2b0a640ca9f659a5945692e04
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Sep 15 13:49:42 2007 -0700
-
- Added ability to read/write to pointer to int or double in FFI.
-
- * Fixed Math.frexp to use pointer to int to return exponent.
- * Completed Math specs.
-
-commit 1a88ca4def8d7aa566a4254eebee3236a1359fc8
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Sep 14 20:57:01 2007 -0400
-
- mini_rspec.expectation_messages.yak_shave!
-
-commit 64f53c8b40b3a80b41a2c27b4ac7255b7aad5f4d
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Sep 14 02:18:16 2007 -0400
-
- Hopefully full StringIO coverage now
-
-commit 7cf9fe62bc9a5a00ae69ed3cac82e50012f3bb69
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Sep 14 00:54:33 2007 -0400
-
- Yet more StringIO specs
-
-commit 92da0550bd32db984fbb54f105b9701867d4faf9
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Sep 14 00:38:55 2007 -0400
-
- More StringIO specs
-
-commit 29826669197f44850d323910c7e60897e1ef7796
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Sep 14 00:23:45 2007 -0400
-
- Beginnings of StringIO specs
-
-commit 0c19e3557125dd366ddd119a34451715bfe5e7a1
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Wed Sep 12 18:11:49 2007 -0700
-
- Fixed object allocation bug and Bignum spec
-
-commit e42a1b960f530a987527d8795a98b2de18fea824
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Sep 13 19:19:03 2007 -0400
-
- Re-implement Module#define_method. Passes existing specs.
-
-commit a8b1a148e5fbfeb3c91558fd6caccc95006a5617
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Thu Sep 13 03:55:15 2007 -0500
-
- Adding a non-compiling spec to case_spec and updating core.rba that didn't seem to get updated correctly.
-
-commit bbd682ba2e12ba5907fe2edf2f14f11fb110cac8
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Sep 13 04:04:33 2007 -0400
-
- Fix anonymous 'rest' arguments
- Suppress stray STDOUT traffic from 'defined?'
-
-commit 8f11498019eb49a4dd8bf52c4361432ebb1175d5
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 12 22:21:30 2007 -0700
-
- Updated CI process.
-
- * Changed bin/ci to generate an exclude file per file put
- in .spec directory.
- * Generated CI spec excludes files.
- * Updated .gitignore to not exclude .spec directory.
- * Moved the critical excludes file to spec/excludes.txt
-
-commit b736263ff325efabb907f300c1c69a2e63bd5620
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 12 22:21:30 2007 -0700
-
- Updated CI process.
-
- * Changed bin/ci to generate an exclude file per file put
- in .spec directory.
- * Generated CI spec excludes files.
- * Updated .gitignore to not exclude .spec directory.
- * Moved the critical excludes file to spec/excludes.txt
-
-commit 58ff9428a2a20e93e3682f834e32f754ed2c47d4
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 12 18:39:48 2007 -0700
-
- Fixed specs failing MRI.
-
-commit f54b1dffb9372e5cb1c71d93c67f2407fce0a1d0
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 12 17:17:46 2007 -0700
-
- Fixes to specs failing MRI for hash, float, fixnum, file, enumerable.
-
-commit e1d359eec451a69deb67ffdedd09b86d00774cc2
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 12 14:34:50 2007 -0700
-
- Fixes to Hash specs based on Ruby version differences.
-
-commit ee5eec5d32bb42fbf549068905ddebe215fbcf70
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 12 08:53:47 2007 -0700
-
- Fixed failing specs in kernel, module, numeric, string.
-
-commit 4f0af824f132428762f1e06409ca16c1022867bc
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Sep 12 06:24:16 2007 -0700
-
- Added #platform and #version guards for specs.
-
-commit 355c602704cd402a1d7cbadc9b4d8fae0b34f1f4
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Sep 11 00:35:03 2007 -0700
-
- Misc changes to specs to cleanup after the breakup.
-
-commit 85336c6a83736b01d63b645baf0e7e18bb5ce569
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Sep 10 23:21:24 2007 -0700
-
- Converted exception, kernel, struct, object specs.
-
-commit e10bc8cbbaa26123724dad9f97f44d82e8cbf600
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Sep 10 21:48:15 2007 -0700
-
- Converted string and numeric specs.
-
-commit 8ec64d24811a7951756c840c98a66a7c7d2ae7c8
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Sep 10 18:35:18 2007 -0700
-
- Converted array and module specs.
-
-commit 2849f4a41b3fbda6c626d934bbf3d7476ea31848
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Sep 10 15:22:36 2007 -0700
-
- Converted enumerable, file, hash, process, regexp, thread.
-
- Fixed bin/mkspec to remove '=' from string for file name.
-
-commit ffa5328aa8ed7ea079c0cc8b4228ababa5919cf6
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Sep 10 13:16:14 2007 -0700
-
- Converted time and bignum specs.
-
-commit 7798952047471d28a8e12a796092c4df7ae002f2
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Sep 10 01:21:38 2007 -0700
-
- Converted range, math, matchdata, integer, float, fixnum, comparable, io.
-
-commit 423d85f4a7eb4b40d2eea83a462f5c38c4a6aee3
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Sep 9 23:43:14 2007 -0700
-
- Added dir and files for ENV. Converted true, false, nil, symbol, process.
-
- Added .spec to .gitignore.
-
-commit 8274bdcd0c747c21806065feb743e7794231f48f
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Sep 9 22:40:37 2007 -0700
-
- Converted kernel specs.
-
-commit bc1917d630d7938b62a866c3825dfa08e5ec99e1
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Sep 9 21:57:03 2007 -0700
-
- Initial create of spec/core subdirectories and files.
-
- Updated bin/mkspec to exclude Exception subclasses and
- OptionParser (which is in Object.constants because of
- the script requiring it). Also normalize TrueClass etc.
- to directory 'true'.
-
-commit b941eceb681c57d23d35f952b11b2a2d3a1ea4dd
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Sep 13 01:00:22 2007 -0400
-
- Add a minimal spec for the 'undef' keyword
-
-commit 3af389594f3828763a85d8eef65f773b183e1b46
-Author: Charles Nutter <headius@charles-nutters-computer.local>
-Date: Wed Sep 12 19:33:36 2007 -0500
-
- Adding a bunch of default argument specs to language/def_spec.
-
-commit 6b4936e834a2814602be54f01e08dcdc1f9433b5
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Sep 9 16:58:35 2007 +0200
-
- Another fix for multiple mock expectations on the same method.
-
-commit f686ff256289263eb473249dd734cf2214c41cc2
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Sun Sep 9 16:13:53 2007 +0200
-
- Mocks now support multiple expectations of the same method with different arguments.
-
-commit 860e0d08adc8cdee9ac4d9ff3bd0e30d5d3aaa49
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Sep 8 02:36:19 2007 -0700
-
- Added to critical-excludes and ci-excludes. bin/ci -f s -C runs to completion.
-
- rake build:core compiled string.rb, so checking in core.rba.
-
-commit c9c79c910a57e5628d1743f3b440c0066875500e
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Sep 7 23:24:44 2007 -0700
-
- Added Math methods using FFI.
-
- Added Kernel.coerce_to and rewrote Float(), Integer(),
- Array(), and String() with it. Float() needs to be fixed
- to raise on strings like rb_cstr_to_dbl does.
-
- Fixed -C options for bin/ci and bin/mspec.
-
-commit b8d8b8c8475fde1ce3519e29788a34780dffae8c
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 19:40:02 2007 -0700
-
- Fixes String#<<
-
- * Added taint if other has taint
- * Fixed 10 spec failures
-
-commit b0b85547ab9dd16ba88a75c64a91c3ae0d079b27
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 15:36:44 2007 -0700
-
- Added bus error to critical-excludes
-
-commit ed13a10112d0a262a48c8e5db7d1eaaa3e076e55
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 15:19:51 2007 -0700
-
- String specs work in 1.8.6 MRI
-
-commit 6fc507c96e990139c311900c73c7e31447879071
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Sep 7 12:03:09 2007 -0700
-
- Changed VERSION and RUBY_VERSION to shadow MRI (currently 1.8.6).
-
- Added RBX_VERSION (currently 0.8.0). Updated loader -v to display
- RBX_VERSION and RUBY_VERSION and truncated BUILDREV.
-
- Enabled before|after(:all) for mini_rspec.
-
-commit 8ce602f80b35f5859c58730968a9a7053a87bd59
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Sep 7 11:16:16 2007 -0400
-
- Array#uniq, #uniq! simplified. 72 failures.
-
-commit 38f271a1b7d49074d8db9285553756fb75ffe78b
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 11:23:36 2007 -0700
-
- define_attr added to subtend
-
-commit 843706d585334c30943c8bbdd3ef6ca22297d42d
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 10:48:51 2007 -0700
-
- Added rb_cstr2inum to subtend
-
-commit 97a22e2144b623a62780995333d65986c98c4ba2
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 10:42:30 2007 -0700
-
- Added rb_const_defined to subtend
-
- It also seems that my fixture for require didn't make it in; adding that as well
-
-commit 0ac9ec2b0f381bf2fb3a36cd0b6f30748771e818
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 10:21:28 2007 -0700
-
- Added check_*_type to subtend
-
- * check_array_type
- * check_string_type
- * check_convert_type
-
-commit b2bf1c44fa7c2663e6fc0b27127aa4f5e38e073f
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 09:45:03 2007 -0700
-
- Added rb_attr_get to subtend
-
-commit 81605662ab8acc5a50536f1fc613e7d24e142df1
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 00:27:38 2007 -0700
-
- int2inum added to subtend as well as INT2NUM
-
-commit e80084e6b245173c17403891c65d86db1e6b3022
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Fri Sep 7 00:02:06 2007 -0700
-
- rb_str_split added to subtend
-
-commit 90f1fa95825caa8b21e147248d1a7d999579b937
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 6 23:51:56 2007 -0700
-
- rb_require in subtend added
-
-commit 5bb87f516b2a26f77a864a15636331102d6d8499
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 6 22:58:29 2007 -0700
-
- rb_to_id added
-
-commit e0532b3fb62089da7b7362ec2232997878a1221d
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 6 22:31:30 2007 -0700
-
- Added specs
-
-commit 75f7a1d2b37067f55099dd117e8fcd905baa748d
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 6 21:59:12 2007 -0700
-
- string subtend fixes
-
- * rb_str_cmp added
- * rb_str_cat fixed with working spec
-
-commit f058cea3e5291c349f5b2b1cfbdad4d734240f95
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 6 21:34:52 2007 -0700
-
- added rb_define_const
-
-commit ec7ca7f45ef32794afb919851e4bfd5e8d7aa46d
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 6 21:03:44 2007 -0700
-
- rb_include_module added
-
-commit 5b3471544508e973ba6afbd16daf47f5796f8b30
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Sep 6 20:41:09 2007 -0700
-
- float_new added and some functions missing in ruby.h added
-
-commit cd2af0bae996a4addfe23baa0558125a8a5523e7
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Sep 6 17:09:06 2007 -0700
-
- Fixed subtend. Added diagram of the context chain.
-
- NMCs (NativeMethodContext) now use the proper context stack.
- The stack maintenance was all screwed up when calling in and out of
- native methods, which was the source of a few problems.
-
-commit da5f9e6f942c11d906760e952debae4d05b3d872
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Sep 4 22:26:48 2007 -0700
-
- Added load-order dependency generation to rake build:(core|platform) task.
-
- Added 'depends on:' declarations to kernel/platform and kernel/core files.
-
- Updated ci-excludes.txt to reflect recent spec checkins.
-
-commit 7b1ca6f305e33b34a99e8c9e049843a76cceeca7
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Sep 2 21:29:49 2007 -0400
-
- Add more 'alias' specs. Show singleton methods in 'public_methods' output.
-
-commit 5c0b5fcb2a0c9f47a04e6a5d5027484224d0a942
-Merge: 4896039... 01c2126...
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Sep 2 18:58:53 2007 -0400
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 48960394ab7f36ccd1b18609677b40721c30d7a2
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun Sep 2 18:57:29 2007 -0400
-
- Add some 'alias' specs that fail on rbx and pass on MRI
-
-commit 01c2126b705327d99aa183d51dc014169e8b4e07
-Merge: 04602c6... b6d92ec...
-Author: Florian Gross <flgr@ccan.de>
-Date: Sun Sep 2 19:45:25 2007 +0200
-
- Merge branch 'master' of git@git.rubini.us:code
-
- Conflicts:
-
- spec/core/string_spec.rb
-
-commit 04602c6756a9199b64e7d909c01dc995b25fa8a7
-Author: Florian Gross <flgr@ccan.de>
-Date: Sun Sep 2 19:32:47 2007 +0200
-
- * New specs for String#tr_s(!) and upcase(!)
- * Improved specs for String#capitalize!, downcase(!) and swapcase
-
-commit c94f83b20f7b11dc48c523c84de59b9ac6f76cce
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Aug 31 23:15:07 2007 -0400
-
- Array#reverse_each, #rindex fixed and cleaned. 80 failures.
-
-commit f531f812f87283b950c62648e3cf08a7400c2779
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Aug 31 22:03:05 2007 -0400
-
- Array#replace fixed, specs. 88 failures. * Disabled specs for #initialize_copy which is private.
-
-commit 1656b8a04a40bc5a43adec88ffd1480d9da6ba28
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Aug 31 11:50:56 2007 -0400
-
- Array#reject, #reject!, specs fixed and cleaned * Added spec to check #reject returning Array and corrected implementation.
-
-commit e1c499c6feafc19788addd098a6da052904cb09c
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Aug 31 11:25:45 2007 -0400
-
- Fixed logic in Array#rassoc, specs. 91 failures.
-
-commit da79b116d3fdc5fd4cd04f5ad1ad44b2c269ad77
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Aug 31 10:38:39 2007 -0400
-
- Array#push checks frozenness, specs. 92 failures.
-
-commit 290aa6fe561453821f59be3fa92695d0b0d77c04
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Aug 31 10:26:25 2007 -0400
-
- Uncommented most of Array#pack specs. * float -> int conversions still hang both C and c and are therefore disabled.
-
-commit 885f2522244c1792f45260194aba085028d5c919
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Fri Aug 31 09:59:30 2007 -0400
-
- Fixed logic errors in Array#assoc, Array#include? * Both, contrary to docs, compare elem == obj, not the other way around.
-
-commit d825038a409f4d931e80736e2de49ff0752857a9
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Aug 31 00:12:06 2007 -0700
-
- bin/ci supports options for separately running spec files
-
- Use bin/ci -s to separately process each spec file. Use
- bin/ci -m to run all the spec files in a single VM process.
- -s is the default for --create, but -m is the default for
- everything else.
-
- Updated ci-excludes.txt and critical-excludes.txt.
-
-commit 7dfe5cb7936051685a2c79effb6295b9aa179810
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Aug 30 23:44:28 2007 -0700
-
- Updated ci-excludes.txt to only exclude failing specs.
-
-commit fb09f0a7a6969adffd8d99bf869eb50c91eef097
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu Aug 30 20:31:20 2007 -0400
-
- Fix object and array specs that failed under MRI
-
-commit 6fb73244537b61a20538c1f3d5a060a40a358be5
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Thu Aug 30 17:08:12 2007 -0700
-
- Fixed two typos in the subtend string specs
-
-commit 00256f41d4e3ebfcdafdc25e27bfbf4bc7d3de3f
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Aug 30 11:19:09 2007 -0400
-
- Array#last fixed. 48 failures.
-
-commit 887d41c64c6bdff693f6ecd8d3078f8453669648
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Aug 30 11:02:27 2007 -0400
-
- Array#insert, specs corrected. 49 failures.
- * Fixed Array#insert
- * Re-complianced frozenness specs for Array#inspect.
-
-commit 1bc536e1128bc76b1c9efae593340f67bdcb5fb5
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Aug 30 10:42:05 2007 -0400
-
- Array#indexes correct implementation. 51 failures.
- * Array#indexes and #indices is now correct although
- both methods are deprecated in favour of #values_at.
-
-commit 5de09c707b1ce43bf689e8ded9ea19784e77a49e
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Aug 30 10:09:27 2007 -0400
-
- Array#include? implemented. 53 failures.
- * Replaced use of Enumerable#include?
- * Re-complianced to a simpler Array#include? spec to
- avoid implementation-dependedness.
-
-commit 14ca6c2533764eea508b24b0ec89475a7aae5e94
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Aug 30 09:32:40 2007 -0400
-
- Array#hash spec compliance change. 54 failures.
- * Disabled an Array#hash spec for Rubinius because it
- relies too much on implementation details.
-
-commit fc4f392fa7fba88b36bfdec61db3acaa1f1fadc2
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Thu Aug 30 00:42:03 2007 -0400
-
- Array#flatten, #flatten!. Improved Array specs. 384 ex, 55 failures.
- * Array#flatten, #flatten! implementation improved, they
- also work recursively now.
- * Re-enabled Array#flatten, #flatten! specs and the
- recursive test for Array#inspect.
-
-commit efeaa622994e9868b9324247b0ff1fd5743792ac
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Wed Aug 29 23:29:36 2007 -0700
-
- A series of rb_str functions in subtend, plus fixes to some of the tests earlier committed
-
-commit e4f5281148799ed716065c489d384a42d208290d
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Wed Aug 29 19:16:26 2007 -0700
-
- rb_str_append() added
-
-commit a05c376478f7407da4e0aa2a6a7e3de98176a63b
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Wed Aug 29 13:25:17 2007 -0700
-
- Updated subtend array functions
-
- * rb_ary_reverse() added
- * tests added for rb_ary_join() and rb_ary_reverse()
-
-commit 779fb97c35b78b9749cbb118fcb555096957e4c6
-Merge: 2793a99... e17987e...
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Wed Aug 29 12:40:33 2007 -0700
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 2793a9917f8f5cc2f0fc14ba605cec499532e680
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Wed Aug 29 12:40:21 2007 -0700
-
- Slightly improved rb_ary_pop() test
-
-commit c196c60b6cd32c85b18bdab31ee000cf097309b5
-Author: Me <rue@meow.kittensoft.org>
-Date: Tue Aug 28 23:49:46 2007 -0400
-
- Array#fill fixed, cleaned up. 375 examples, 59 failures.
-
-commit 7736413f262357479c2f3354a73533fd89b3c9a6
-Author: Yehuda Katz <wycats@gmail.com>
-Date: Tue Aug 28 17:54:28 2007 -0700
-
- added rb_ary_join() to subtend
-
- Trying to get tests working but it's hard to see if I'm correct without the ability to run them.
- I'll take care of making sure there are passing tests as soon as I can.
-
-commit 0effcaf3e948d80ae3ad17b33f0483313d85cdbe
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Tue Aug 28 00:24:41 2007 -0400
-
- Array#fetch, specs, slightly cleaned array.rb. 62 failures.
- * Array#fetch uses to_int.
- * Specs for Array#fetch check for correct block var.
- * Removed extra comments from array.rb.
- * Removed old implementations from array.rb.
-
-commit 51737d35c24f853a23e14f7a227138d4d0f6b457
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Aug 27 21:46:30 2007 -0700
-
- Added failing File specs to ci-excludes
-
-commit a195970e2b2d34fa4388e6a72e91ada13b4b0d32
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Tue Aug 28 09:20:33 2007 +1000
-
- Ensure exists? is prefixed by File.
-
-commit 804b6f3358c1bb73492beaa0e978d4df8dbac138
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Tue Aug 28 00:18:41 2007 +1000
-
- Minor refactoring work on file spec.
-
- Removed duplicated constant tests.
-
-commit ef18eaaaa1a79b964667900b19f3f10e1b67032b
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Aug 27 14:25:06 2007 -0700
-
- Updates to enable bin/ci to run to completion.
-
- Changed mini_rspec to not use File.open with a block to work
- around IO#read failing to catch EOFError.
-
- Commented out object_spec.rb specs that need to be completely redone.
-
- Updated spec/reports exclude files to enable bin/ci to work.
-
-commit 505617b26829d5f489c4488ed934a6dc720f64f0
-Author: Florian Gross <flgr@ccan.de>
-Date: Sun Aug 26 22:53:42 2007 +0200
-
- A few new specs for String#sum, #to_i, #to_s, #to_str, #tr and #tr!
-
-commit a6a24a97dce2a4072a6ea17e48259b76f0c3681a
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Aug 26 02:52:55 2007 -0400
-
- Array#delete, Array#delete_at, Array#delete_if. 63 failures.
- * Fixed the three delete* methods, they still need clean-up
- * The specs reflect difference in frozen handling for rbx and r18
-
-commit 063f8c25d45e0934bca236ecb8af36dcb517187f
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Aug 26 02:26:15 2007 -0400
-
- Array#concat fixed. 69 failures.
- * Array#concat checks frozenness and cleaned up
- * Improved specs for #concat
-
-commit a9f3593593948cf72d94712765d05bfcc27f2e78
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sun Aug 26 01:53:05 2007 -0400
-
- Array#dup, Array#compact, Array#compact!. 71 failing.
- * Array#dup properly returns subclass
- * Array#compact(!) improved to pass specs
-
-commit 7be3bc12ea2e5432e442cb44103b4b1c6d981163
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 23:57:38 2007 -0400
-
- Array#clear, Array#frozen?. 372 examples, 73 failures. * Array#frozen? checks for sorting freezes * Array#clear fails on frozen Arrays
-
-commit 5c958242fe25f8a18cd8d315f81fb3db80dc7a40
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 17:19:23 2007 -0400
-
- Array#==, Array#assoc improvements. 75 failures
- * Cleaned up Array#==
- * Array#assoc processes correctly
-
-commit f82f8a300ee394f9f1038cc84de1cf6b132d7ef5
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 16:24:22 2007 -0400
-
- Array#* improved. 371 specs, 81 failures
- * Array#* processes to_int and to_ary correctly and forwards
- to #join when needed.
-
-commit 91e16f06d5b5b16f1fa7ffc1d3673d7f1c681587
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 15:54:12 2007 -0400
-
- Array#join can process recursive Arrays.
- * Rubinius cannot create recursive Arrays so this is somewhat moot.
-
-commit 2d7427bb638f1af6d7437beed4beafde5274dbdf
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 13:46:45 2007 -0400
-
- Array#|, better Array#&. 371 examples, 86 failures.
- * Array#& explicitly uses #eql? semantics
- * Cleaned up Array#|, uses to_ary
-
-commit 2b8707466f763662d52efaeab71b4789b132bb40
-Merge: c61b1e5... 76be87f...
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 12:41:06 2007 -0400
-
- Merge branch 'array'
-
-commit 76be87f74d352d79425e9c46d3df55678257fda9
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 12:28:32 2007 -0400
-
- Array#<< improvements. 371 examples, 89 failures.
- * Specced and fixed resizing bug in Array#<<
-
-commit c61b1e54cc11c297b9e9a9eca70cb6a354ed21d9
-Merge: 3618a8b... c6cc98f...
-Author: Pedro Del Gallego Vida <pedro@la-vaca-roja.(none)>
-Date: Sat Aug 25 18:16:45 2007 +0200
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 3618a8bc588588ef8fb0dcc4753bc42606b86c13
-Author: Pedro Del Gallego Vida <pedro@la-vaca-roja.(none)>
-Date: Sat Aug 25 18:16:05 2007 +0200
-
- Update object specs
- Update the object_spec.rb file
- * add more specs
- * refactor using it_behave_like
-
-commit 294e5aacda8a74a9d8f57d05bb433f2fadcd08f1
-Author: Eero Saynatkari <rubinius@projects.kittensoft.org>
-Date: Sat Aug 25 12:07:06 2007 -0400
-
- Array#[], modified parts of array_spec. 369 examples, 90 failures.
- * Array#[] passes its specs
- * Disabled some parts of array_spec while fixing Array. These
- will be re-enabled as soon as possible.
-
-commit 1369465aefcd1d50ddd268ba9af968c62137e2b2
-Author: Pedro Del Gallego Vida <pedro@la-vaca-roja.(none)>
-Date: Fri Aug 24 11:14:20 2007 +0200
-
- Array#new correct implementation
-
-commit e321427a52878ef9d9c7c04aa7c3c4f1e3a6c940
-Merge: bff7c05... 69c0407...
-Author: Pedro Del Gallego Vida <pedro@la-vaca-roja.(none)>
-Date: Fri Aug 24 11:14:20 2007 +0200
-
- Merge branch 'master' of git@git.rubini.us:code
-
-commit 07c7f93a64fc37f3cf94a0a2c272468d015a7fb3
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Aug 23 21:18:13 2007 -0700
-
- Converted Regexp specs to new describe style.
-
- Fixed String specs to be compatible with bin/completeness.
- Fixed bin/completeness to use dotted reporter instead of CI
- reporter since the latter no longer outputs summary info.
-
-commit 6776e1478fa7e78a0944a1ee59c55c3839f51ea4
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Fri Aug 24 13:14:47 2007 +1000
-
- Added implementation of File.split and updated specs.
-
-commit 4053b9076b4b996f544095a75317453967723faa
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Wed Aug 22 21:58:13 2007 +1000
-
- Added spec for mocking methods on a class
-
-commit 54cae1196db08f6a734c35079db8df62e491f300
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Thu Aug 23 17:38:40 2007 -0700
-
- Added more IO stuff and platform methods.
-
- I'm still a little unhappy with the input buffer situation.
- (ie, there is none.)
-
- Adds IO#sysread and IO#syswrite as well as a bunch of POSIX stuff.
-
-commit 12a755004c0a8a0319212965da61385738166f98
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Aug 21 12:44:48 2007 -0700
-
- Beginnings of ftools spec, fix backtrace generation.
-
- Backtraces were failing to be properly built if the sender was a Block.
-
-commit bff7c05ce12c79ef111422ecf4525f1a65e7a5f0
-Author: Pedro Del Gallego Vida <pedro@la-vaca-roja.(none)>
-Date: Fri Aug 24 01:15:41 2007 +0200
-
- More specs dor enumerable
- * add inject, min, grep, find, detect, find_all, select
-
-commit ed9a8fefcc384bb6548a7f66bbafb97192ec8fd3
-Merge: 4ef0b9f... 8dd800e...
-Author: Arthur Schreiber <schreiber.arthur@gmail.com>
-Date: Thu Aug 23 11:01:25 2007 +0200
-
- Merge branch 'specs'
-
-commit 8dd800e8189f616dc54390c0ebf96c331de41230
-Author: schreiber.arthur@gmail.com <arthur@arthur-desktop.(none)>
-Date: Thu Aug 23 10:45:56 2007 +0200
-
- * Some more Module Specs.
-
-commit 0f414f56f9050d86011df75e7fd23428fe378996
-Author: schreiber.arthur@gmail.com <arthur@arthur-desktop.(none)>
-Date: Thu Aug 23 10:44:59 2007 +0200
-
- * Added :count => :any option to mock expectations
-
-commit 4ef0b9feddfebfd1b6177fce6e3a1a4077f4f098
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Aug 22 23:10:22 2007 -0700
-
- Updated exclusion list for CI specs.
- Updated rake spec:ci task.
- Changed ci spec run action to execute all specs in one process.
- Added guard on file specs to prevent compilation exception.
-
-commit c3b61b239fa6a02327e5651513986d998d826eaf
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Aug 22 21:48:08 2007 -0700
-
- Updated CI spec process to exclude specs failing on compilation.
-
- Added critical failures to enable running especially spec/core.
- Added failure guards to struct specs.
-
-commit f339a284c66357bc52749e5fe9c0d59bbbdc7ade
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Aug 20 22:31:56 2007 -0700
-
- Fleshed out bin/ci constructs for running specs.
-
-commit 4f750d59adfff6c1751372c0d2853778dc7ae16d
-Author: Pedro Del Gallego Vida <pedro@la-vaca-roja.(none)>
-Date: Tue Aug 21 22:40:33 2007 +0200
-
- * more enumerable specs
- * refactor to it_behaves_like
-
-commit 3c79d5cf67b40b945602d5c5fa77589e0d7bae2c
-Author: Pedro Del Gallego Vida <pedro@la-vaca-roja.(none)>
-Date: Tue Aug 21 20:52:16 2007 +0200
-
- update file_spec.rb
-
-commit b2a64089bffe5afb9148a665ecb6e70c3bc62b67
-Merge: 6865b97... 1b6a8a1...
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Aug 19 16:22:53 2007 -0700
-
- merge 1b6a8a157
-
-commit bf54767922eb8d494c683ed8d57c6ffb5164fc29
-Merge: 6c6032e... 37d71c9...
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Aug 19 15:24:21 2007 -0700
-
- merge from e83bcd022
-
-commit 05db33909c319231ac375812025ea2378710a299
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Sun Aug 19 21:26:15 2007 +1000
-
- Add conditional when deleting a file in after(:each) block to prevent an exception if the file is missing.
-
-commit 138ab001175987cd38aff092a850e515745f9292
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Sun Aug 19 21:18:22 2007 +1000
-
- Converted remaining context/specify spec's into describe/it, and followed class/method naming convention.
-
-commit 749b883d0260326573c581cc63eab67e1a4bc590
-Author: Marcus Crafter <crafterm@redartisan.com>
-Date: Sun Aug 19 20:23:11 2007 +1000
-
- Added implementation of exists? blockdev? chardev? zero? size size? writable_real? executable_real? readable_real? unlink delete and chmod using ffi where needed. Specs for most of these methods existed already, added specs for those that weren't. Fixed a few typos.
-
-commit ddcb14f9f2311ec843a1f1f8d2b3fa868384ff0d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Aug 18 23:19:32 2007 -0700
-
- more misc changes to get ci specs working
- added alias for File.exists? and File.exist?
- added Dir.getcwd
- added empty File.delete
-
-commit afb252fd6170ed051e97f1911e5f1200414ebf98
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Aug 18 22:20:10 2007 -0700
-
- updated compiler specs.
-
-commit d0e6b658d9065b0fbc9180cd5d19139834f64f59
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Aug 18 21:04:18 2007 -0700
-
- changes to support better CI specs
- hat mini_rspec will take a filename as an exclude/include argument and read the actual excludes/includes from the file.
- added that mspec will take -o FILE to use an alternate to STDOUT for the spec reporter output.
- updated spec tasks. misc spec changes.
- added naive implementation of IO#each.
-
-commit 541bcb521a8ee589c7d28c095ad7ee1489af42db
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri Aug 17 19:30:05 2007 -0700
-
- Complete reorganization of bootstrap. Addition of kernel/platform. FFI fixed.
-
- New restrictions for meta-programming in core bodies (not in methods).
- kernel/platform is now where platform specific code, mainly related to FFI, lives.
- A bunch of FFI bugs have been fixed and it should be working much better now.
-
- FFI Note: you may now only specify :state as your first argument, and you must
- leave it off when you call the method (rather than passing nil like before).
-
-commit af245dfbc80ff942de62408e70db7499a798fb0a
-Author: schreiber.arthur@gmail.com <arthur@arthur-desktop.(none)>
-Date: Tue Aug 14 01:30:09 2007 +0200
-
- Forgot to add the autoloaded file for Module#autoload
-
-commit b946940f463028de067ef2e082c96fe431c94b0a
-Author: schreiber.arthur@gmail.com <arthur@arthur-desktop.(none)>
-Date: Tue Aug 14 01:09:10 2007 +0200
-
- Updated Module Specs
-
-commit 6cd6aa53a5d20c78941442f7e367ef8c7aee17c2
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Aug 10 00:14:09 2007 +0000
-
- converted array specs with a few edits.
-
-commit c075f7f70da2a029c69f3fff1f9caec419db64d5
-Author: Arthur <arthur@unknown>
-Date: Wed Aug 8 12:47:18 2007 +0000
-
- fix a small typo
-
-commit c7262df9ee1c2544890b001574c8cb0f8ae26a75
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Aug 8 01:24:25 2007 +0000
-
- converted exception specs. added #should_be_ancestor_of. use ExpectationNotMetError in mini_rspec like rspec does.
-
-commit f591e18978b73c508505db73f274f4bd69c372c5
-Author: Arthur <arthur@unknown>
-Date: Tue Aug 7 08:36:15 2007 +0000
-
- * String#to_str specs should actually use String#to_str
-
-commit 80f69571c5378d6bbb2e7a118ada00db66226797
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Aug 7 06:47:53 2007 +0000
-
- converted range specs.
-
-commit aca62d253a6b2df891ca4ec4b177ea95b621d636
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Aug 7 03:52:46 2007 +0000
-
- fixed mini_rspec -e option, allows multiples. converted hash specs.
-
-commit 928c9a392102fa7b7945f332480a7477ec203467
-Author: Florian Gross <florgro@gmail.com>
-Date: Mon Aug 6 22:04:16 2007 +0000
-
- New specs for String#swapcase(!), to_f, to_i, to_str, to_sym
-
-commit 6d0a6b0051a55af32743d9d98d6425489a622ebe
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Mon Aug 6 21:58:55 2007 +0000
-
- * more specs for File.open. Specs for File.truncate
-
-commit 8b19b683a8593b4dd5024841d8023df827a44875
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Aug 5 23:39:36 2007 +0000
-
- fixed completeness to not over match methods. converted comparable specs.
-
-commit c6f4d90df72b103884fa5470a433f5513d2c524d
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Sun Aug 5 22:52:17 2007 +0000
-
- * more specs for File.open. Some of them are plataform dependent
-
-commit 38bfff9d014b90409e272ddf041dc63f53d48f5d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Aug 5 22:45:31 2007 +0000
-
- converted bignum specs. misc cleanup.
-
-commit 14890b68c447731417ce53ca2e4310175e39b440
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Aug 5 22:00:04 2007 +0000
-
- Small spec fix
-
-commit b6c3cfca5cf1b2cb85dc216180ad21a6bf653a10
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Aug 5 17:20:32 2007 +0000
-
- converted time specs. according to completeness, need to spec 9 more methods.
-
-commit 8829cf7e94ec0434f642fafa7dbf117a860045b9
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Aug 5 07:53:47 2007 +0000
-
- more converted specs.
-
-commit 5bf174780e893b7ee9b82b6ca3964db7cad84e30
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Aug 5 07:08:08 2007 +0000
-
- converted fixnum specs to describe per method.
-
-commit 88023701a88c1113e4874c193d26c6bf21fad383
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Aug 4 22:19:18 2007 +0000
-
- misc noise cleanup in specs. use bin/completeness to find missing specs rather than warns.
-
-commit 3d960a021cb9ac2bdc2a204f94b4f024f3ef60a4
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Aug 4 22:06:12 2007 +0000
-
- fixed completeness to pass correct spec example string for class methods. changed float specs to describe per method.
-
-commit 8a7abb5996e5bdf8b9d6c5884e0e0d8ae73d060e
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Aug 4 20:10:38 2007 +0000
-
- beginning of a completeness reporter. use 'bin/completeness -t ruby' to report on the completeness of the specs against MRI. use 'bin/completeness' to report on the completeness of rbx relative to MRI. use -t target for other implementations. updated some specs to the 'describe Class#method' style.
-
-commit 463f13be4462e22bc3f4491a475658624c5832ab
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Sat Aug 4 17:09:25 2007 +0000
-
- * fix some bugs in bignum_spec
- * changed the File::Foo.shouid == bar assert to defined?(File::Foo).should == "constant". The specific value dependence on OS.
-
-commit 989d72394f1e175b058f55ccf3e60f09a2c76401
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Aug 4 04:15:01 2007 +0000
-
- fixed mini_rspec specdox reporter to not output describe message until examples are executed. fixed specdox and dotted reporter to distinguish between errors and failures.
-
-commit f98fe7f211e5784a35e99643fb52c9350b20d7ae
-Author: Florian Gross <florgro@gmail.com>
-Date: Sat Aug 4 01:40:52 2007 +0000
-
- More compatibility and a few small fixes
-
-commit c78ba9f96d7d4d229d6b1b1b11cf314fb5a0271d
-Author: Florian Gross <florgro@gmail.com>
-Date: Sat Aug 4 00:40:42 2007 +0000
-
- Compatibility for USE_RSPEC=1, sanity, some clean-up
-
-commit 761d05b5cbd92339f9d02e65d005a65c5155618e
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Aug 3 21:49:26 2007 +0000
-
- * Compiler and Normalizer fixes for method definitions without bodies
-
-commit ad7abe4d61171f9650d08b277d45c7f680f37950
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Aug 3 17:07:19 2007 +0000
-
- fixed mini_rspec shared behavior to be compatible with rspec.
-
-commit 1e1ccb902d11547e9f67db82c31a5898e6227d67
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Aug 3 16:39:07 2007 +0000
-
- added an implementation of shared behavior for mini_rspec. altered Array#[] and Array#slice specs to use shared behavior.
-
-commit 7697b2ae3db6ed1d8697010a7e0f52f8e3587c8a
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Aug 2 20:41:43 2007 +0000
-
- added SpecRunner class to mini_rspec to properly encapsulate behavior. added --example option to specify a regexp to match examples to execute.
-
-commit b80bb3d295d3648988b15a29553189f219d8ac0a
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Thu Aug 2 15:56:07 2007 +0000
-
- * added specs for file_spec
-
-commit c277fd3de82678f055693422af19c3f45ffc2a88
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Aug 2 00:46:27 2007 +0000
-
- mspec: Add -x option for excluding specs by RE
-
-commit aa53967c694ed7621aa1a8a8b542d067d9e58925
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Aug 2 00:05:53 2007 +0000
-
- New specs for String#succ(!)
-
-commit eafa5b0fd43168b4ae649b145f9528f7deae3aa7
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Aug 1 22:59:38 2007 +0000
-
- New specs for String#sub(!)
-
-commit 3406e64032251a2a9849da3f6c27d872dd339175
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Aug 1 22:17:18 2007 +0000
-
- New specs for String#squeeze(!) and String#strip(!)
-
-commit fa4d66576528725085ef47cca27c5c85c55b3150
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Aug 1 21:08:26 2007 +0000
-
- added Object#(public|private|protected)_methods and Module#(public|private|protected)_instance_methods. added Tuple#first, last.
-
-commit 4ca071ba4a48aa984308e0ba9448718a6e214d7a
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jul 31 20:56:37 2007 +0000
-
- Some Object#methods et al specs.
-
-commit 67be404ac0714ec01c1c92c77465915d90fd794b
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jul 31 18:41:54 2007 +0000
-
- Renamed variables_spec.rb to assignment_spec.rb
-
-commit c0187db3e51297dfffabebe9acb6d6321bd04578
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jul 31 18:22:41 2007 +0000
-
- New specs for String#split
-
-commit 06cb5ab7c39866c99bb8d9a5fbb678f2f8a19cf2
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jul 22 06:47:54 2007 +0000
-
- Removed the .rbc files from externals dir and set svn:ignore. Added Tuple specs, fixed a couple small problems with Tuple. Modified mspec to pass -I, -r to the target; added -n RUBY_NAME to affect which specs are run. Added hashi dir as an experiment to implement a bootstrap that could be run on e.g. MRI or JRuby to allow the core libs to be run and tested against the specs.
-
-commit 567d4f710bc232fc9223972e22a7d92e4abe940d
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue Jul 17 17:49:53 2007 +0000
-
- Stack allocated lvars, GC fixes, compiler changes, oh my!
-
- This is a biggy (too big in fact). It started as a change to allow
- arguments to be accessed directly from the stack, and turned into a
- monster.
-
- Arguments and some lvars can now be accessed directly from the stack,
- making them cheaper to create and use. This turned out to expose
- a large number of bugs in the VM related to stack access, as well
- as some in the GC.
-
- The big GC change here is that the mark/sweep GC is actually run now,
- as opposed to before when it would just allocated more and more memory
- (the source of memory issues I suspect).
-
-commit 564ac024e14a790f4a3d257ddf1d9fa0cb93ee3b
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jul 17 00:20:52 2007 +0000
-
- $~ specs all over the place;
- Revised % format string specs (match MRI trunk);
- Revised hex and oct specs (match MRI trunk);
- Merged slice together with [];
- New specs for scan and slice!
-
-commit 2389eb4b36d86732dbb621be1cad3edca0e36aa5
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Mon Jul 16 09:26:20 2007 +0000
-
- * added specs for file_spec
-
-commit a6453b6184353633d14c271533c2e2af7a6c4b12
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Jul 15 17:53:58 2007 +0000
-
- A few specs for char numbers outside of 0..255;
- A few specs for modifying strings while iterating;
- New specs for hex, index, initialize(_copy), ljust, lstrip(!), match, next(!), oct, replace, reverse(!), rindex, rjust, rstrip(!);
- Small additions, fixes & refactoring
-
-commit 217dd5dae127c146559dd1512edac23a94565ae9
-Author: Florian Gross <florgro@gmail.com>
-Date: Sat Jul 14 23:52:52 2007 +0000
-
- Taintedness specs all over the place;
- String subclass specs for String#%;
- Range subclass specs for access methods;
- str[idx, count] = str specs (contributed by John Lam);
- New cases for capitalize(!) / center / gsub(!);
- Refactoring
-
-commit b8b0c3dd380335260c3870934ca51dce736ce15d
-Author: Florian Gross <florgro@gmail.com>
-Date: Sat Jul 14 23:39:38 2007 +0000
-
- Added custom range subclass cases for access methods
-
-commit 558552ec549fd605bed2c8f5c384e8c944e780a2
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Fri Jul 13 14:40:15 2007 +0000
-
- * added cases for file_spec
-
-commit 5218708c630bd8a631522a00aa6cba4e91cbec54
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Fri Jul 13 13:36:53 2007 +0000
-
- * added cases for file_spec
- * refactoring numeric_spec.rb
-
-commit 3e9dbc15a81950e55a15a7fcca0ab04a5fd5353f
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Jul 11 22:09:49 2007 +0000
-
- Add specs for to_* calls having correct semantics with method_missing() and respond_to?();
- Small clean up
-
-commit 23961f46af6f74d2d6b9019972e451a5ae12b728
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Jul 11 22:00:26 2007 +0000
-
- Add specs for to_* calls having correct semantics with method_missing() and respond_to?();
- Removed a few duplicate specs (probably resulting from a mismerge)
-
-commit 639c64ca0965ff79401989ca7dbde862815f13fb
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Jul 11 21:09:33 2007 +0000
-
- Add specs for to_* calls having correct semantics with method_missing() and respond_to?();
- Fixed String#%'s %E/e/f/G/g and %b/d/i/o/u/X/x specs to verify Kernel#Float / Kernel#Integer semantics instead of to_f / to_i ones
-
-commit e97879670bbc8425810a3c83f15a523066899a89
-Author: Arthur <arthur@unknown>
-Date: Tue Jul 10 20:04:48 2007 +0000
-
- * fix a typo
-
-commit 1e8890613a215c61ef90629b8b6023ac4612c499
-Author: Arthur <arthur@unknown>
-Date: Tue Jul 10 20:03:44 2007 +0000
-
- * Update Symbol Specs to the new format.
- * make Symbol#to_int show a warning as in MRI.
-
-commit 1262f24460463628c7cc4e275b7c814048937b57
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jul 10 18:28:06 2007 +0000
-
- New specs for gsub() without block
-
-commit 0ba87f6edc183385551e4cf8c05212fadaf36427
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jul 10 16:48:46 2007 +0000
-
- New specs for capitalize, chomp, concat, crypt, eql?;
- Added missing methods chop, chop!, count;
- Small improvements and refactoring
-
-commit 226942caef6bd217a13dc235a89c5ccf4a18f98b
-Author: Florian Gross <florgro@gmail.com>
-Date: Mon Jul 9 21:29:19 2007 +0000
-
- Strings specs for letters c through e
-
-commit e41c027537f1e4f8ea4b8b5b6fe90df9a21e3aff
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Fri Jul 6 17:13:39 2007 +0000
-
- * added 62 cases for file_spec
- * remove a bug from obejct#method_missing_spec that break the specs
-
-commit 06d2fd71b847e139a39ab3b7a132ab041a8d4c1e
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Wed Jul 4 16:05:21 2007 +0000
-
- * add 84 cases to the numeric_spec.rb
-
-commit b8d334f575322c65932279346bba61caead61555
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Wed Jul 4 10:28:27 2007 +0000
-
- * 14 cases for Object.method_missing
- * Add File#atime, File.atime, File#ctime, File.ctime, File.delete, File.executable?, File.executable?
-
-commit f2276130c4bf1894ffb6efb451203dcbfe9322bb
-Author: Charles Nutter <charles.nutter@sun.com>
-Date: Wed Jul 4 08:48:57 2007 +0000
-
- Added a spec for Process::times...it's not great, but it's something.
-
-commit f71bb57b3fc69c35d34abdb9959e27efb71bbdff
-Author: Charles Nutter <charles.nutter@sun.com>
-Date: Wed Jul 4 06:14:06 2007 +0000
-
- Fixes for #150; handle Time - Time correctly, don't assume it's a number of seconds.
-
-commit 895f1abdc0bfcdb213f97067704b1bb87a7e6d17
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jul 3 17:01:27 2007 +0000
-
- New specs for casecmp
-
-commit 2aa7cb37925cd92c3b23d4a33a6d7bc7c2b66737
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jul 3 14:07:56 2007 +0000
-
- New #[] and #[]=, capitalize and casecmp specs;
- Converted "should work" messages to "works" using a few regular expressions -- I'm still going through the file so bad replacements (if any) will be fixed
-
-commit 719ff3b8959d93d7da8165d6e5b44989afde92d7
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Tue Jul 3 00:33:59 2007 +0000
-
- * new NoMethodErro_spec.rb
-
-commit 5363324044fdc1457cfbf1b738dd931d3255b191
-Author: Florian Gross <florgro@gmail.com>
-Date: Mon Jul 2 23:58:09 2007 +0000
-
- Some more new specs
-
-commit fa1b3694e366bf087a8d1ac107257c38ce447251
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Mon Jul 2 20:29:20 2007 +0000
-
- * Add to_s with a base spec
- * Change foo.aMethod.to_s.should == "bar" with foo.aMethod.should_be_close(bar,TOLERANCE) because floats representation are plataform/implementation dependents, but not changed aBignum.to_s.should = ...
-
-commit 2a5c93afd4ddfef7c30de17c531f49849e9bb957
-Author: Pedro Del Gallego <pedro.delgallego@gmail.com>
-Date: Mon Jul 2 00:10:06 2007 +0000
-
- * Add Float::Constant specs
- * Change foo.aMethod.to_s.should == "bar" with foo.aMethod.should_be_close(bar,TOLERANCE) because floats representation are plataform/implementation dependents
-
-commit 7d3dcc24cb72d6548cf44d8519691f4cd7344801
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Jul 1 21:00:37 2007 +0000
-
- Heavily extended and refactored String#% specs;
- some cleanup
-
-commit 79ce6628df39d20d03efcd715ea42ba70ae9f03e
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Jul 1 20:59:38 2007 +0000
-
- Add support for MRI as :mri for failure() and similar methods
-
-commit 7e43cd858c0380aaf17dd7bacd8a24cef96bb309
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Jul 1 17:11:08 2007 +0000
-
- rindex terror specs
-
-commit e5b7cf88092cf59357124e3d8f35bc19f8ee589a
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Jul 1 01:14:09 2007 +0000
-
- Added a few new format specs (Most of these should probably be moved to Kernel::format later)
-
-commit a533693824608a03ab6a66882b607fecab3a3a75
-Author: Florian Gross <florgro@gmail.com>
-Date: Sat Jun 30 00:29:29 2007 +0000
-
- A few more specs, clean up and compatibility with MRI 1.9 head
-
-commit b9e8936562ec23db63879f9c127dadeadd8adf2e
-Author: Florian Gross <florgro@gmail.com>
-Date: Fri Jun 29 02:41:40 2007 +0000
-
- New specs for [], default(), delete(), shift(), yield argument count semantics and modifying hashes while iterating over them;
- Also removed some warnings and cleaned up the code a bit
-
-commit 72d1b106c1de4b00b9af184eb890e950854a9c77
-Author: Florian Gross <florgro@gmail.com>
-Date: Fri Jun 29 02:37:55 2007 +0000
-
- Adding spec for join passing along separator argument for nested arrays
-
-commit 6e2848b7143cd0ae47a7b9ac632a567df7fd30fc
-Author: Florian Gross <florgro@gmail.com>
-Date: Fri Jun 29 02:35:09 2007 +0000
-
- Adding message argument for should_raise()
-
-commit 31591886dde4bfd9b4e9de34c26960e45566b7ee
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jun 27 05:15:15 2007 +0000
-
- Commiting (#147) math specs by pedro (modified for style, structure, and legibility).
-
-commit c7d623ee836363d0f3d443ba1c676ef0f86e34f7
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jun 26 04:06:49 2007 +0000
-
- enhanced spec:ci to take a target on the command line, invoke like: SPEC_TARGET=jruby rake spec:ci. removed deprecated #only and #except from spec_helper.
-
-commit c13a588cb7e37c20ce7e8a9430d854cc51be7b00
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 25 08:28:10 2007 +0000
-
- misc cleanups to specs to eliminate interaction effects.
-
-commit 280296208bd699cb574c662f92b585519a739c6b
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 25 02:42:07 2007 +0000
-
- removed extension dir and added README for subtend specs.
-
-commit 7ce8d4addc77ea9da0daf3ea3dc1fc7b00030b29
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 25 02:30:15 2007 +0000
-
- reorganized subtend specs. stragglers from spec/language reorg.
-
-commit d499ebfd98d8fb9bd50c0f7a46b3587aa1f28c8a
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jun 24 19:44:12 2007 +0000
-
- significant reorganization of spec/language, added files that correspond to the desired layout of this section. there remains to be done a large amount of cleanup for existing language specs, and especially spec description strings.
-
-commit bc0d0965bb5a6b3966884b63edd37218359aa46d
-Author: Tilman <tilman@unknown>
-Date: Sun Jun 24 14:52:15 2007 +0000
-
- Extended specs for File.join.
-
-commit a4e189f31a8c256821564041c4dbce2a832ba78e
-Author: Tilman <tilman@unknown>
-Date: Sun Jun 24 13:00:33 2007 +0000
-
- Fixed a typo.
-
-commit ecaf1abafeb69994b05463742ca4220797f62ad3
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Fri Jun 22 23:25:13 2007 +0000
-
- * Array specs by Josh Susser (hasmanyjosh)
-
-commit 1c8987b6195d356126ebc3cc9c21e473be915240
-Author: Arthur <arthur@unknown>
-Date: Fri Jun 22 21:22:30 2007 +0000
-
- * Heavily extended String specs
-
-commit 663e2cbe0c026aa7e792b6aab682301570ccd766
-Author: Tilman <tilman@unknown>
-Date: Fri Jun 22 08:59:42 2007 +0000
-
- Added specs for Time#dup.
-
-commit f9dd8149bd7d794e8686053e8dca010ea71eacba
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jun 21 06:47:57 2007 +0000
-
- added methods #compliant, #noncompliant, #extension, #failure. Please read the comments for them in spec_helper.rb. #only, #except are deprecated but have not yet been removed.
-
-commit 389b3cef5176b0244f78294a3c820cc84797e0df
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jun 21 05:22:36 2007 +0000
-
- added -f i (immediate) reporter for mini_rspec.
-
-commit d113f855e32d09abaa74bb0ccafa4a65ffce66b1
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Jun 20 21:59:27 2007 +0000
-
- A few more hash order consistency specs
-
-commit 8df2a605937c29b0ca4e89fae37b725e7244fbee
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Jun 20 21:24:01 2007 +0000
-
- Small spec improvements all over the place
-
-commit 5c2472584637b6f5accaaf2450d4c23904b0bbd7
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jun 19 23:06:33 2007 +0000
-
- Small tweaks to let us run specs against Ruby 1.9
-
-commit 18b06659146f00f0ecf72846c445b03268305328
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jun 19 15:56:02 2007 +0000
-
- More specs, including frozen hash ones
-
-commit 3cc17a6c7d4c4e4d13b67da4e2bd8937160916f0
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jun 19 15:02:21 2007 +0000
-
- Specs for methods involving to_hash and more
-
-commit a33e72ba27dc7c80fb7c3947d4fe86521b8987e0
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jun 19 13:35:14 2007 +0000
-
- New specs for each, each_key, each_pair, each_value, fetch, has_value?, index, initialize_copy, inspect, invert, key?, keys, length, merge, merge!, rehash, to_a and value?
-
-commit f5ec55b0233fd6b7825b04afc6157caac0c529ce
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jun 19 13:18:33 2007 +0000
-
- Using except(:rbx) for "inspect should handle recursive arrays" instead of commenting it out
-
-commit 7fec6cb5534d22dbfa4dd245cf3b0c0776b3b465
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jun 19 00:56:35 2007 +0000
-
- New specs for Hash.new, #==, #[], #[]=, #clear, #default=, #delete and #empty?
-
-commit e3085af8e97177f8b7e4ff1c2aad2f306a4f474d
-Author: Florian Gross <florgro@gmail.com>
-Date: Tue Jun 19 00:53:43 2007 +0000
-
- Specs for how Array#uniq should use eql?() and hash()
-
-commit 01799e95c71453e8dff9730dd283bf76989e75e5
-Author: Florian Gross <florgro@gmail.com>
-Date: Mon Jun 18 11:22:47 2007 +0000
-
- Adding new specs from rue plus more. The diff is a bit chaotic, but everything should be OK.
-
-commit 890deed76153d05c6874b46ec29c474eb4e36e41
-Author: Florian Gross <florgro@gmail.com>
-Date: Mon Jun 18 11:12:04 2007 +0000
-
- Moving only() to general spec helpers, adding expect()
-
-commit bf89af6c3b632b88e3cc74bead42f21561da58a7
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 18 07:19:15 2007 +0000
-
- (Jason Toy) added some specs for File (with some modifications) (#130).
-
-commit a7a6d8e336f8d331c60e973fb8f9e0aac1fb61ac
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 18 05:20:29 2007 +0000
-
- (Jason Toy) initial specs for YAML (#123).
-
-commit 4c2f70040050e35da28a8684296f913a3dd4a198
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 18 05:14:41 2007 +0000
-
- (nitay) patch for Bignum#size (#120).
-
-commit b1e57c9c718acfc7f1e61ae1fb60f10b918f8e5c
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 18 01:40:29 2007 +0000
-
- Range specs and code from Ryan Mulligan (#141).
-
-commit 9fa70f392bf83c55d67e682c36d9ebd247cff62c
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Jun 17 22:02:48 2007 +0000
-
- New specs from Ryan Mulligan (#140)
-
-commit 64c970bddeb754115ed193d2f786c797ea90dab3
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jun 17 20:08:40 2007 +0000
-
- reorganized specs to put implementation-specific extensions in a subdirectory within the logical division of the specs into core, library, language.
-
-commit 8d437f0f63d4d3f9eea6e4436a28f437e6e76053
-Author: Florian Gross <florgro@gmail.com>
-Date: Sun Jun 17 19:39:37 2007 +0000
-
- Initial work on hash specs -- a few new cases and a bit of reorganization
-
-commit d8222049004ba0d6ec51db0c962b5200bb180aec
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jun 17 03:53:45 2007 +0000
-
- (yipstar) module specs for undef_method, define_method, remove_method. all pass MRI.
-
-commit 0162cfe6a443ded5d6c8e01a866f5a8d1fbce901
-Author: Florian Gross <florgro@gmail.com>
-Date: Sat Jun 16 23:11:31 2007 +0000
-
- Added specs for * / join / to_s with recursive arrays
-
-commit 0744e57d7860b9f6eefcc8e14962d7ee777d2ec4
-Author: Florian Gross <florgro@gmail.com>
-Date: Sat Jun 16 22:05:32 2007 +0000
-
- A few more specs for array sub classes with to_ary [ruby-core:11472]
-
-commit 07e0df5111c8ceeda83e50ef434948ee17e92aae
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jun 16 19:09:19 2007 +0000
-
- commented out specs that cause the VM to seriously misbehave allocating memory without bound or causing SIGBUS. currently 434 examples, 130 failures at r1357 on MBP.
-
-commit 2abc6e6dc5df662e8f0587636bd1cf3573e39f28
-Author: Tilman <tilman@unknown>
-Date: Sat Jun 16 16:41:07 2007 +0000
-
- Don't use timezone names that aren't portable.
- Instead, specify timezones by their standard name and the offset from GMT.
- This makes the specs pass on FreeBSD w/ MRI.
-
-commit d4106115c2ca9a4678b7060b6ac0091d66312624
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jun 16 08:20:29 2007 +0000
-
- a first, big step to making the entire set of specs more agnostic about the ruby implementation/engine by, paradoxically, qualifying certain specs to only run under certain ruby engines. removed incompatible and rubinius directories. folded in specs where appropriate and moved spec files (e.g. bytearray, tuple, compression) into the appropriate directories. the spec/parser and spec/compiler dividing line is not clearly defined given the range of types of implementations and perhaps should be merged.
-
-commit 3de0340e693e20b5e32c643f1f4dae7e1943e077
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jun 16 07:07:41 2007 +0000
-
- migrated more tests from shotgun-tests to specs.
-
-commit 369813306643d98c277841c1e9b400f6b60d3316
-Author: Florian Gross <florgro@gmail.com>
-Date: Fri Jun 15 22:43:05 2007 +0000
-
- Add spec for elements returning odd stuff on <=>
-
-commit d70ab64def5ebdcb0e1946618b06e810270eb2aa
-Author: Florian Gross <florgro@gmail.com>
-Date: Fri Jun 15 22:17:03 2007 +0000
-
- New specs for frozen arrays
-
-commit fda7128521254d2db2668fec55ef7ce9337ecf1a
-Author: Florian Gross <florgro@gmail.com>
-Date: Fri Jun 15 21:55:30 2007 +0000
-
- More specs, mostly for array subclasses
-
-commit 2d57166d2ef2ff63f333b7ee0c196f5c4e10b8cf
-Author: Florian Gross <florgro@gmail.com>
-Date: Fri Jun 15 16:56:25 2007 +0000
-
- More than five bazillion new specs including a ton for the very evil []= method (letters i through s)
-
-commit b905a952af41a96f72499750c4635b1352b237ba
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 14 23:06:33 2007 +0000
-
- A few more specs.
-
-commit e17aa3690f7dcd2dab346bf7def0dd26b38072f1
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 14 22:16:54 2007 +0000
-
- A bunch of new specs. Includes highly exotic corner cases.
-
-commit 7845d8928d138353ad03bd496d1800c03e82b538
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 14 20:52:23 2007 +0000
-
- Fix cleanup to work with symbolic method names like ==
-
-commit c677ac036baa847cef3de6a34b2b56c9fd09213c
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 14 18:04:43 2007 +0000
-
- Fixed the test for DATA to match MRI (it's only supposed to be defined when the main file contains __END__);
- Added test for TOPLEVEL_BINDING
-
-commit 27b2767cd21b5a69ee10a2a629a68de64fd8ae5a
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 14 18:03:26 2007 +0000
-
- Introducing RUBY_NAME so we can spawn a new Ruby for things that can't be tested otherwise
-
-commit 4c4a96f51b4c06dd6896f996ae0e87a68152a3bc
-Author: Tilman <tilman@unknown>
-Date: Thu Jun 14 15:15:56 2007 +0000
-
- Don't call Time.now multiple times when comparing their values.
-
-commit cde774be8b188f5870b1ee387b5e5fffd9948163
-Author: Tilman <tilman@unknown>
-Date: Thu Jun 14 15:00:17 2007 +0000
-
- Fixed a typo.
-
-commit 6e51eee65c310255183d81d97a98be313ca68afc
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 11 04:07:03 2007 +0000
-
- put guards on imcompatible specs to prevent ruby, jruby from running them. work around for Dir ** globbing being broken.
-
-commit 03dfae6b896a6b67ac6066e94284d992833afac5
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jun 11 02:00:25 2007 +0000
-
- Added rake task spec:ci. added svn:executable for bin/mspec. enhanced readability of system command in mspec. added globbing across directories to mspec command.
-
-commit 96425667fbff044333c13c5a88c3b8cad156504f
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jun 10 21:45:52 2007 +0000
-
- modified mini_rspec to include proper reporters. converted mspec to use ruby to generate a command line to run specs. mspec usage should be similar to spec: mspec spec/core spec/language/class_spec.rb will execute any spec/core/*_spec.rb plus spec/language/class_spec.rb and output a single summary of exceptions, examples, failures.
-
-commit 1075f2cf34a81c00a1b06d2474c78300ae013161
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Sun Jun 10 06:59:40 2007 +0000
-
- Cleaned up MatchData, added support for accessing named groups.
-
-commit c678d79f125d67328e267001e5fe353f5ef38a2c
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sat Jun 9 04:20:51 2007 +0000
-
- * =~ for regexps to mini_rspec by dean (Ticket #136)
- * Kernel.caller spec relocation for reliability
-
-commit 00eec364dbf3cef03915a68a359ed06b7e501553
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jun 8 07:10:56 2007 +0000
-
- reintegrated String specs. all specs in core follow the convention that there is one file named <class>_spec.
-
-commit 9f9817bbb9fea5cc02eb280f01eb50e45ea03118
-Author: Arthur <arthur@unknown>
-Date: Thu Jun 7 23:49:47 2007 +0000
-
- * String#replace, String#chop! and String#chop behave now as in MRI.
- * Specs
-
-commit 129e492fcacf937473bb1c602176b48a352f8572
-Author: Arthur <arthur@unknown>
-Date: Thu Jun 7 23:39:00 2007 +0000
-
- * Fix String#<=> when the given object is not a String.
- * Fix String#to_sym for invalid symbols.
- * String#to_i raises an error when invalid radix is given.
- * More specs.
-
-commit 8d7a9e21874d9e44c63d17dd8f6832b942805707
-Author: Arthur <arthur@unknown>
-Date: Thu Jun 7 23:31:25 2007 +0000
-
- * Make String#capitalize!, String#downcase! and String#upcase! check for the 'frozenness' of self
- * Specs
-
-commit 10087a0c92217d1fbadfede9fdb0099c7eb195e6
-Author: Arthur <arthur@unknown>
-Date: Thu Jun 7 23:25:08 2007 +0000
-
- * Spec for String#==
-
-commit e51ca54f6f4e9e3dabd48895fa2cb746fb0d3c17
-Author: Arthur <arthur@unknown>
-Date: Thu Jun 7 23:23:23 2007 +0000
-
- * Fix String#=~ to work as in MRI.
- * Specs
-
-commit d2c7d6e6bb624c23e994888b6a235022486e0c69
-Author: Arthur <arthur@unknown>
-Date: Thu Jun 7 23:16:35 2007 +0000
-
- * Alias String#size to String#length.
- * String#<< now correctly checks and converts (where applicable) arguments.
- * String#<< raises an error if used on frozen string.
- * Added extended specs for String#<<.
-
-commit c389493556e3394cce846698aa4fc6a67a5f4b40
-Author: Tilman <tilman@unknown>
-Date: Thu Jun 7 18:14:02 2007 +0000
-
- Time#zone_offset and #zone_utc? are also in stdlib already.
-
-commit 7dcd86dca123edaec7edec2853cba2af27ca6d52
-Author: Tilman <tilman@unknown>
-Date: Thu Jun 7 18:07:59 2007 +0000
-
- Moved the specs for Time methods that should be in stdlib rather than in core to spec/lib/time_spec.rb
-
-commit 953dfdfdea395ead465a9e19339d94f8b8c7d684
-Author: Hapk <hapk@unknown>
-Date: Thu Jun 7 17:36:20 2007 +0000
-
- Added more specs for Array#pack: covering %#bB.
-
-commit 7aa84bc102ad6943aed46cbb357f233ac4b6d3f9
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 7 16:47:03 2007 +0000
-
- Make next with arg match MRI; Fixed typos and a copy&paste error
-
-commit 40c354444d6d7a2fd3aeb940c3bdcf6fd2a28940
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 7 16:43:17 2007 +0000
-
- Fixed to run on MRI (uses Object.const_get now)
-
-commit 95dd0ca698d0b1f79a11f4a556c171bea33ba176
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 7 12:52:40 2007 +0000
-
- Make behaviour match MRI, fixed copy&paste errors, did some refactoring
-
-commit 191d4e80406a6e4ffd08594ddeada47fb3219bf0
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 7 01:41:08 2007 +0000
-
- Fix chaos introduced in rev 1283
-
-commit e0f5184493607f7d9c216146207dc298893a744c
-Author: Florian Gross <florgro@gmail.com>
-Date: Thu Jun 7 01:28:55 2007 +0000
-
- Fix Dir.chdir test on OS X (/tmp is symlinked to /private/tmp)
-
-commit a32062d6099556a93afee61f0b0000a28675fbb6
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 21:44:00 2007 +0000
-
- Deleted old specs.
-
-commit de7b3ecaa61c4d3514c8a3534805e9c8d0d1bb2f
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 21:09:48 2007 +0000
-
- Made the Time#to_a spec pass with any time zone, too. MRI passes all the specs for me now.
-
-commit ac1e295da36f23184e583f5e62a4909959550dbd
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 21:06:32 2007 +0000
-
- Fixed specs for Time#localtime, #gmtime and friends.
-
-commit 064a5967f5550cf4a2e10885ab2c9f22afa59da2
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 20:56:41 2007 +0000
-
- Fixed a few more Time specs. Instead of the imaginary time zone "PDT"
- I'm now using Asia/Kuwait for some specs, because those lucky people
- don't have DST, which means we don't have to flip the spec expectations
- every 6 months.
-
-commit 8f6b6a5a5f8e62631a58061b6cdeeaff5654aeb0
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Jun 6 20:41:32 2007 +0000
-
- module_function specs matched to MRI (module_function makes the instance methods private)
-
-commit 8cc656b95cb71ea476e787ce635df889090f8050
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 20:41:02 2007 +0000
-
- Fixed the Time#year spec. Using CET, too, since specc'ing using 1969 just feels wrong.
-
-commit ed7be9eaa73b8b1d85964f5c8fdfc250e2e8f62f
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 20:38:43 2007 +0000
-
- Oops, fixed a stupid error in r1281.
-
-commit e81d716092e0c6a8b52775ca2b9e0d44c4e3ef7f
-Author: Florian Gross <florgro@gmail.com>
-Date: Wed Jun 6 20:35:42 2007 +0000
-
- Divmod matched to MRI (Special casing darwin on MRI because it doesn't raise FloatDomainError exceptions in some cases)
-
-commit fc5f461c47b7212f05f8699110e313aeab46d46d
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 20:35:34 2007 +0000
-
- Fixed the Time#hour, #min and #day specs.
-
-commit 6847a1e49ff4ad4dfe7c6e9e4d7352f92d72b4cd
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 20:26:26 2007 +0000
-
- Don't call Time#seconds as MRI doesn't have it and it doesn't seem to be needed anyway.
-
-commit b9a6ccc89d46ffa910c9bdc0fece9d013440872d
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 20:14:15 2007 +0000
-
- Time#asctime needs to use %e to print the day of the month.
-
-commit 7311fdf31481ba7a4373d5b007efb62c1f84c389
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 20:03:30 2007 +0000
-
- Hardcode output for Time.gm(...).inspect. This makes utctime superfluous for now.
-
-commit 229e7eefe7944df92ab2f84e553992fc0c868dbd
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 19:19:38 2007 +0000
-
- Fixed two more Time specs.
-
-commit 7f490d752ed97bfb9b830d24f4e2c2f44107c141
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 18:41:47 2007 +0000
-
- Make sure that with_timezone resets .
-
-commit 9c8d25c4d072510215407209fa52a06b85e95d35
-Author: Tilman <tilman@unknown>
-Date: Wed Jun 6 15:57:32 2007 +0000
-
- Made the wday spec work with any timezone.
-
-commit 4882f8a676d5234339296d6a4489f3a7134cf5fd
-Author: Tilman <tilman@unknown>
-Date: Tue Jun 5 20:08:22 2007 +0000
-
- Fixed a typo.
-
-commit fb63faa2165cafdc7907f173344638609f884833
-Author: Tilman <tilman@unknown>
-Date: Tue Jun 5 20:03:06 2007 +0000
-
- Make sure that a GMT Time object returns true from gmt?
-
-commit deae4911588b555264f529e765dc5baf7a2c6e69
-Author: Tilman <tilman@unknown>
-Date: Tue Jun 5 20:00:45 2007 +0000
-
- Use with_timezone for the gmtoff specs.
-
-commit 625dd8e366f846cf15165e323a719199627ae422
-Author: Tilman <tilman@unknown>
-Date: Tue Jun 5 19:47:29 2007 +0000
-
- Added a helper method to temporarily override the TZ env var and fixed one of the specs by using it.
-
-commit b359eb74d41749919c6177ec2af6b5b516308bd8
-Author: Tilman <tilman@unknown>
-Date: Tue Jun 5 19:33:01 2007 +0000
-
- Provided 'date' calls for coreutils' date program.
- Checking for coreutils using RUBY_PLATFORM isn't the right way,
- but it will do for now.
-
-commit b19c3c8d886885adc08ac69469792b14e47ba265
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Mon Jun 4 23:42:20 2007 +0000
-
- * Improved Array#sort with additional spec by wycats (ticket #135)
-
-commit 8513e72a5af7596c8782ee45dff39607489dbf12
-Author: Tilman <tilman@unknown>
-Date: Mon Jun 4 16:39:53 2007 +0000
-
- Ticket #132: Implemented ENV in core and removed read-only ENV from shotgun.
-
-commit 03d75a78855213f6267fb8f80f9c71d0a031641f
-Author: Mojombo <mojombo@unknown>
-Date: Sun Jun 3 20:49:41 2007 +0000
-
- Implemented most of Time, updated time specs accordingly
-
-commit 36975b1b79abbd38de68223cdc8ecbca9ba0feee
-Author: Bremac <bremac@unknown>
-Date: Sun Jun 3 16:20:59 2007 +0000
-
- Add Functions::abort, Functions::printf, and Functions::sprintf, and minimal specs. Closes ticket 87.
-
-commit 9d25d95a4aa3fd22d3f3a340427d40410488a770
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sun Jun 3 12:41:49 2007 +0000
-
- * Lots of new assignment specs by crafterm (Marcus Crafter) (Ticket #133)
- * MatchData#inspect and #to_s now indicate it is an MD object
- * -dc notes which file/method is being compiled
-
-commit ec0fb5beed68155c9e1ff67185cc2c8e4e474c04
-Author: Arthur <arthur@unknown>
-Date: Fri Jun 1 22:23:39 2007 +0000
-
- * Fix String#[] and add some edge cases to the specs
-
-commit 068b48538ec574558ab787d59b14ebd2925f1126
-Author: Tilman <tilman@unknown>
-Date: Fri Jun 1 18:12:10 2007 +0000
-
- Renamed module 'B' to something more meaningful to avoid name clashes.
-
-commit eb3de8af03d070b03216daa4fc0c2216d9d3e2a2
-Author: Arthur <arthur@unknown>
-Date: Fri Jun 1 18:09:52 2007 +0000
-
- * Extend String#slice! specs
-
-commit db4775403d57ea29165165b9cbf0110739d91e2a
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Jun 1 02:26:30 2007 +0000
-
- * Ticket #128 - Patch by Marcus Crafter to enhance assignment specs
-
-commit 6098aa16357ce4261feb51bdf083c02442b1f074
-Author: Tilman <tilman@unknown>
-Date: Thu May 31 19:05:45 2007 +0000
-
- Implemented rb_obj_alloc() and friends in subtend.
- The spec for rb_class_new_instance() is still failing because of strange
- subtend behavior.
-
-commit ae2c3cb4502ba9475111eeef10b2b70780a1b9f4
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Thu May 31 13:54:24 2007 +0000
-
- * Fixed shotgun compile failure (possibly r1204)
- * Various casts to avoid warnings
-
-commit d317d336412d0c1778d4c015dfe96287c44e1bd9
-Author: Hapk <hapk@unknown>
-Date: Thu May 31 11:12:02 2007 +0000
-
- Added specs for "break", "next" and "redo" keywords.
-
-commit a33f801f8f142d997a553e41cde9f5b10d75ee65
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Thu May 31 04:23:33 2007 +0000
-
- * Kernel.caller spec by jtoy (Ticket #112)
- (kernel_spec is badly broken still)
-
-commit ce15eb69e721820e75b0f7aeae6488701cbe9555
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Thu May 31 03:55:27 2007 +0000
-
- * Fixed String#dump spec expectation (Ticket #105)
- * Moved RUBY_ENGINE to rubinius-specific variables_spec (Ticket #109)
-
-commit 7d2c575164dfbbd436d7c6ff400c088a68b29fa8
-Author: Hapk <hapk@unknown>
-Date: Thu May 31 00:42:50 2007 +0000
-
- Added "if" specs for variable scoping.
-
-commit ceb4430f9c713f409f2567a0aa324f19afb09b79
-Author: Hapk <hapk@unknown>
-Date: Thu May 31 00:35:49 2007 +0000
-
- Added specs for while / until condition/block evaluation order.
- Added specs for next and redo statements.
-
-commit 4adeecf9333236800396bd77f928fb902e785692
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed May 30 22:17:04 2007 +0000
-
- * Fixes to RSpec cleanliness of specs, most patches by zimbatm.
- (Tickets #97 #98 #100 #103, partially #99)
-
-commit bbb0714b6ae60adb0af7445ed56544ceec3bc890
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed May 30 21:41:03 2007 +0000
-
- * Array specs are RSpec/MRI-clean and pass (Ticket #95)
- * Fix to should_raise for MRI by zimbatm
-
-commit d627ab36d3839745e057d9f5de781269ba7b154a
-Author: Hapk <hapk@unknown>
-Date: Wed May 30 21:15:39 2007 +0000
-
- Added specs for 'while' and 'until' statements.
-
-commit 8a2177c7f23181909c5dcb51dd6df1e5b930fdbe
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 30 20:32:13 2007 +0000
-
- * Enhanced hatefulness of 'for' specs
-
-commit 9f64f2a1c584420fcabfc73a7c464aa3b1ba2e90
-Author: Hapk <hapk@unknown>
-Date: Wed May 30 19:46:57 2007 +0000
-
- Added specs for postfix "if" form.
-
-commit 9dd8a846adf356d75ceac566612f35d1d30840bf
-Author: Hapk <hapk@unknown>
-Date: Wed May 30 19:34:50 2007 +0000
-
- Moved loop specs from spec/language/expressions into spec/core/kernel_spec.rb.
- Added more specs for Kernel#loop.
-
-commit ddf2e3169c3a8b587f9abfb0ddf196635aec5186
-Author: Hapk <hapk@unknown>
-Date: Wed May 30 18:57:38 2007 +0000
-
- Removed obsolete "elsif" statement spec.
-
-commit 3b6dca92ea810aa7866a2c7aa0b8812e72b6630e
-Author: Hapk <hapk@unknown>
-Date: Wed May 30 18:56:00 2007 +0000
-
- Updated specs for "if" statement to cover more cases.
-
-commit 678f609bfe826538ec16e75f7362bcb3f50c8d6d
-Author: Arthur <arthur@unknown>
-Date: Wed May 30 17:09:09 2007 +0000
-
- * Extend Specs for expressions
- * Break the Specs up
-
-commit df60cc21e4213ac8344b5ed91e802d8cbbfa47a0
-Author: Tilman <tilman@unknown>
-Date: Wed May 30 17:00:17 2007 +0000
-
- Implemented rb_ary_store() in subtend. The last spec still fails, but we'll fix that later.
-
-commit 8e0fea820c1683913625dfe95c7d3210d4548814
-Author: Arthur <arthur@unknown>
-Date: Wed May 30 10:09:55 2007 +0000
-
- * Extend Specs for Class Definitions (nested class definitions, class definitions that extend objects, Multiple Definitions of the same class).
- * Lots of them are failing in rbx.
-
-commit ce16f2b568ea89cb5f13660d3175165b105e4233
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 30 01:18:39 2007 +0000
-
- * OK, that should really be in 'rubinius', not 'incompatible'
-
-commit 888b777539baa116eedc14191ac85d57aec54349
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 30 01:15:37 2007 +0000
-
- * 'Options' is a Rubinius-only class, and should therefore be in 'incompatible'. Closes ticket #102
-
-commit 46a58344fa2f03fb4154b78f34239a815b2d9944
-Author: Bremac <bremac@unknown>
-Date: Tue May 29 23:52:52 2007 +0000
-
- Fix typos in specc'ing module_function, and make that spec play nicer with MRI.
-
-commit e0cedb691f76af4554bfc7522a7668ff861492f0
-Author: Bremac <bremac@unknown>
-Date: Tue May 29 20:49:42 2007 +0000
-
- More complete raise implementation and specs: Handle instantiation.
-
-commit 9f3a3bfe9d2610dd7e9e752c86a1b8aba47f7fdf
-Author: Hapk <hapk@unknown>
-Date: Tue May 29 20:39:07 2007 +0000
-
- Added 'case' spec for case with empty 'else' body.
-
-commit 8f888bd3d0a01afc945c45c0502a0b97f3227c48
-Author: Arthur <arthur@unknown>
-Date: Tue May 29 20:34:18 2007 +0000
-
- Extend Class specs. Some specs failing in rbx.
-
-commit f52d9faadc1eac31e7b92c1edb1cf45ca1d42c89
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 20:29:53 2007 +0000
-
- Implemented rb_str_new2() in subtend.
-
-commit d4d5e3d1eb8e5ee44acff6697a29a37b9eca25b2
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 29 20:00:51 2007 +0000
-
- * Patch by HaPK - Add specs for 'case', and enhance specs for 'for'
-
-commit f3e736731e852dacbf90e8e3e33d840384909354
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 18:56:41 2007 +0000
-
- Actually exercise rb_ary_unshift() in the spec.
-
-commit 69d756ae17fce1fb53be5e7a1b5b7169b69c4aa2
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 18:55:32 2007 +0000
-
- Implemented rb_ary_shift() in subtend.
-
-commit 9f84a5ecddae6c0daf1fd7e46815275c7d7429db
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Tue May 29 18:50:41 2007 +0000
-
- * Fix to Array#to_a for subclasses
-
-commit 2bbc87fc1b5261b57927a02f75915829b398b478
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 18:50:33 2007 +0000
-
- Implemented rb_ary_unshift() in subtend.
-
-commit 4e69b95ad7991a57fd3f9b7cbf350cb5b13c6a5c
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 18:46:53 2007 +0000
-
- Implemented rb_ary_dup() in subtend.
-
-commit 122a9cfbe79e872146116c8e045a243fffd333e6
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 18:31:48 2007 +0000
-
- Marked SubtendArray method functions as static.
-
-commit 0e3319c07aa1d536343343fbbe1004c4cdce2df0
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 18:28:05 2007 +0000
-
- Implemented rb_ary_clear() in subtend.
-
-commit 621f0082fca85140791e2c40aabc8ad3fe3318a6
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 17:58:31 2007 +0000
-
- Implemented rb_ary_entry() in subtend.
-
-commit 9c7d05c0bb19e65f57fc6aab778785e2a727c4a4
-Author: Tilman <tilman@unknown>
-Date: Tue May 29 17:42:40 2007 +0000
-
- Ticket #91: Made spec/subtend/rake_helper.rb more portable.
-
-commit 5dba201079bdf8da63364ea760342f3cef85df74
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 29 15:56:01 2007 +0000
-
- * Add specs for Array#pack, patch by HaPK
-
-commit 2d71e18c6f08144d4fb402904a9226a8500343bd
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 29 15:28:45 2007 +0000
-
- * Better fix to method argument scoping, to support: def foo(a, b=a.length)
-
-commit f9deebb38b80cdea3dff44d7461404e5f501f566
-Author: Defunkt <defunkt@unknown>
-Date: Tue May 29 09:59:00 2007 +0000
-
- * Add spec for Struct subclasses. Closes ticket #110
- * Add failing specs for Class.new. Closes tickets #89 and #94
-
-commit 3be02f950f32a288fac1cd5cff0ae014057c96fb
-Author: Defunkt <defunkt@unknown>
-Date: Tue May 29 09:12:00 2007 +0000
-
- * Add should_include convenience method to make rspec more compatible with mspec. Closes ticket #106
-
-commit 68e716e1874e7dd4186c7eef2aea5e25157a44fd
-Author: Vagabond <vagabond@unknown>
-Date: Tue May 29 03:46:33 2007 +0000
-
- * Add HaPk's fix to Numeric#== to handle failed coersion with corresponding specs
- * Removed duplicate definition of Numeric#==
-
-commit a63e6fcb08e34c625957d8d23bbe602964863c5b
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 29 02:59:43 2007 +0000
-
- * Add Kernel#eval. Probably lacks some crazy MRI semantics at the moment
- * Method definitions should properly create a clean scope for locals
- * Support wacky default arguments, such as blah = lambda {|z| z.foo(another_arg) }
- * Optional label prefixes in assembly output, for easier debugging
-
-commit f1295ac58d2b601f539efe0e660dfed9d043d1d7
-Author: Vagabond <vagabond@unknown>
-Date: Tue May 29 01:39:46 2007 +0000
-
- Change Time specs to use ENV['TZ'] instead of `date` in hopes of being more portable
-
-commit 404faeca93c007f3eb9b3df52c2bde7673565113
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Mon May 28 19:20:27 2007 +0000
-
- * Fix some mistakes in method_spec that caused it not to pass under MRI
-
-commit d336078c02e1306acb4b2664a427b63e93b02788
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun May 27 06:03:25 2007 +0000
-
- * Fix local scoping to allow for method definitions on local variables
- * Pass all the horrible method definition specs
-
-commit 7759a0f91f794d05a32d48dd2e67d05c0b1dace7
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sun May 27 05:03:53 2007 +0000
-
- * Rename Thread.yield to Thread.pass
- * Implementation of 'module_function' by bremac, with minor tweaks
-
-commit 55f30c5e59d16ebbf045be93a7d406fed9a4dcbd
-Author: Vagabond <vagabond@unknown>
-Date: Sun May 27 00:34:44 2007 +0000
-
- Added defunkt's implementation of Module#const_set and const_get and associated specs (Ticket #72)
-
-commit 9cebe0c56fda41b83ab14d39275e327daf0bdcc9
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sun May 27 00:31:47 2007 +0000
-
- * Fixes to mini_mock by bremac (Tickets #85 and #86)
-
-commit f33756f22597bd280e453d5c7ad97685fa284579
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sun May 27 00:24:51 2007 +0000
-
- * Fix typos in splat_spec (Ticket #77) by tilman
-
-commit ea13a828e5fc19694fc24da25b2224a75462a88c
-Author: Vagabond <vagabond@unknown>
-Date: Sun May 27 00:11:58 2007 +0000
-
- Add Chris Wanstrath's (defunkt) Struct patches. Tested working against MRI.
-
-commit 3ca0ddcc2c39fec74f10b75df2af5c1581b9eaa3
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sat May 26 23:56:26 2007 +0000
-
- * Array fixes. Only spec failure remaining is #pack
-
-commit 4d91aa707a47189398455eb1c40b341dc3766ccf
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sat May 26 20:05:13 2007 +0000
-
- * Array fixes to pass specs (including HaPK's code).
- All remaining failing Array specs except #pack are
- not Array bugs. Test this heavily.
-
-commit 6793b34a54ab8e24e8a66a8af026a34315ac9f5b
-Author: Vagabond <vagabond@unknown>
-Date: Sat May 26 07:34:12 2007 +0000
-
- Add cdcarter's Enumerator implementation and specs translated from his test/unit tests
-
-commit fd10c39192825aeef68c8843c2813cf50b8137f2
-Author: Vagabond <vagabond@unknown>
-Date: Fri May 25 20:12:22 2007 +0000
-
- Some fixes to rand with associated specs
-
-commit 60d37d28b715854f5186598c90101824665ce715
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri May 25 19:43:11 2007 +0000
-
- * Properly normalize default method arguments, to support: def(x, y=puts('hi'))
- * Fix 'for' loops so that they use 'create_block' in the proper way
- * Move all 'for' processing out of compiler.rb
-
-commit 3c04a44e8ff9e84f48fbd2d3afabb886494b5a98
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri May 25 06:35:48 2007 +0000
-
- * Patch by HaPK - Fixes String#dump / inspect / upto
-
-commit 9e2442110ec33ff9ca4875407b227f2cf79a606a
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri May 25 05:36:31 2007 +0000
-
- * Use a random pivot point for better worst-case Array#sort performance
- * Add 'rake pristine' task to kill all .rbc files
- * More tricky specs for splats and multiple-assignments
-
-commit 7bea77d8d3e8f190dba4f34fead888551fd07730
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu May 24 23:50:06 2007 +0000
-
- * HaPK's patch to String#<=>, along with its specs
-
-commit 0e6007e7eb9eee5e3ab1acdf55da00f4ab8c4be0
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu May 24 23:29:49 2007 +0000
-
- * Add spec for masgn semantics
- * Fix numerous multiple assignment bugs
-
-commit 6d68d22efd7d2dba75c77cf957edb28dca6df6ef
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu May 24 07:05:00 2007 +0000
-
- * New Array#sort implementation, fixes several Array and Hash specs
- * Add a warning comment to bytearray.rb about some incorrect <=> behavior
- * Prevent unimplemented Array specs from crashing the spec run
-
-commit 0ca089c7354ec96103cb637f861751ca7df01136
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Thu May 24 01:15:40 2007 +0000
-
- * Support all kinda crazy splat syntax
- * Updated some compiler specs, though some TODOs remain
- * Added a comment above unshift_tuple, since it really shifts
-
-commit bbe0b73b07a393f94724964941d2fdd717a2d72e
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 23 19:58:10 2007 +0000
-
- * Add compiler support for: yield(*args)
- * Update some compiler specs to match recent fixes
-
-commit 32a7082205d3d214ad43a477286270a96076b140
-Author: Kev <kev@unknown>
-Date: Wed May 23 17:32:06 2007 +0000
-
- Make spec titles consistent (describing C api behavior)
-
-commit 699c66f8c8304522fbb3589356fe2bcd298277c8
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 23 06:56:25 2007 +0000
-
- * Use yield instead of &prc.call when initializing a thread.
- * Fixes VM crash / closes ticket #68
- * TODO - Why the HELL does this fix it?
-
-commit f8b6e1ff9e19e786b08fee30988eb874eae748b5
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 23 03:18:26 2007 +0000
-
- * Implement Thread.main
- * Prevent Object#inspect from crashing the VM when the inspected object has itself as one of its instance variables
-
-commit f24f573608ee5569b29754a017769db0f866cf4c
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 22 22:35:14 2007 +0000
-
- * Implement 'class_variables' method
- * instance_variables and class_variables now accept an optional argument, causing them to return symbols instead of strings
- * Support defined?(@@class_var)
- * Support defined?(a_vcall)
- * Fix false-positives in defined_spec.rb
-
-commit da540b51c47b2349b0ab8d4ca0bd11124138f9ce
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 22 20:52:30 2007 +0000
-
- * Add compiler support for begin/rescue/else/end syntax
- * Default rescue clause should be StandardError, not RuntimeError
- * Add specs for 'else' and empty begin sections
- * All Exception specs now pass
-
-commit 82abf73fd99ec45f7cb6d98d19b219a61af59a61
-Author: Vagabond <vagabond@unknown>
-Date: Tue May 22 18:39:59 2007 +0000
-
- * Fix Object#instance_eval to bring it into line with the specs and MRI
- * Fix Object#instance_variable_validate to not accept fixnums as instance variable names
- * Add another Object#send spec that tests exception raising for missing singleton method names
-
-commit 3b624f3f49c0433289224baf656b3d7be78cecd8
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue May 22 08:15:48 2007 +0000
-
- Fix the block arg scoping problem, also add a missing file from the compiler specs.
-
-commit 59af7028c060c8e3f9b9c107fb750a71dd37a1d6
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Tue May 22 07:14:54 2007 +0000
-
- A bunch of yummy-ness. Local variables now conform to the 'standard' behavior, ie they're allocated at different depths inside blocks (this is the yarv/jruby behavior).
-
- Cleaned up a couple of subtend things.
-
-commit f8ed63efac6fa661dd39db2c207b66c34d132546
-Author: Vagabond <vagabond@unknown>
-Date: Tue May 22 03:28:17 2007 +0000
-
- Add specs for Object #method, #respond_to? and #__send__. These currently fail with singleton methods on rubinius.
-
-commit 0d6e6b7109014c97d8f8be136166b3279d5a1108
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 22 02:06:19 2007 +0000
-
- * Handle 'call' nodes containing newlines, e.g. x = [5,6,7,8];p Hash[*x]
- * This is probably the wrong implementation, but it does work
-
-commit 518f7d34112e536d726cecfb2473c7b3db9ec33e
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 22 00:52:01 2007 +0000
-
- * Fix mini_mock's cleanup process
- * Add the ParseTree sexp test cases as specs. Currently in serious need of auditing
-
-commit 17ad76c162ff0cfe9662c20d418f455581389b42
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon May 21 21:50:13 2007 +0000
-
- Add a failing spec
-
-commit 1744773b7f57c766c75d188b04e55540d45e19d0
-Author: Vagabond <vagabond@unknown>
-Date: Mon May 21 20:22:04 2007 +0000
-
- Do some env trickery to make Kernel#at_exit testable
- Improve implementation and specs for Kernel#warn
-
-commit 45733aa44e8daee9e8c5e552ac9312f21163fe39
-Author: Vagabond <vagabond@unknown>
-Date: Mon May 21 20:16:18 2007 +0000
-
- Convert time specs to compare against output of the date command
- Change Time#inspect to use %z (GMT offset) instead of %Z (timezone)
-
-commit e58ef35a05d2a565befeaf3600bc00f21203a84c
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon May 21 20:12:34 2007 +0000
-
- Add spec for breakage caused by 1089.
-
-commit a5d54efe9a45f3acc1cdb0183a8c13ce6ed5e327
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Mon May 21 04:57:41 2007 +0000
-
- * Options implements a minimal lightweight option parser
-
-commit b28b77af82d99a7a3ec5a78f6ab8b4e138ac577b
-Author: Kev <kev@unknown>
-Date: Mon May 21 03:54:33 2007 +0000
-
- Add missing hash spec
-
-commit 81496352bdc2b6b27e293b7542908c6be54b9b6b
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon May 21 02:08:57 2007 +0000
-
- added specs from ticket #38 (David Anderson), but not patch because implementation was invalid (e.g. [].first(0) => [] not nil) and superceded by recent patches. fixed Array#[i,0] => [] exposed by the added specs.
-
-commit 4ed6afc81262a4197f1ddc646ada94277cd9abe6
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon May 21 01:07:36 2007 +0000
-
- HaPK's patch to Array#[] with specs. Knocks 14 failures down to 6. Ticket #60.
-
-commit b267aee1c10b6092d954c72d5776f4eafc109e51
-Author: Kev <kev@unknown>
-Date: Sun May 20 21:09:49 2007 +0000
-
- rb_raise, rb_const_get, exception definitions. Wooooo exceptions from C
-
-commit 37793ed650e6ce7352a7547cf4bc68f2ceb2f0b4
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat May 19 08:42:23 2007 +0000
-
- * Added nastier multiple-assignment-with-splat specs
-
-commit 39c9817fa1932f9fe708a8ba78f43cb39e7cb68b
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat May 19 08:30:06 2007 +0000
-
- twifkak's Kernel.fail patch with slightly modified specs.
-
-commit 264a42e8c11d08afa895b415453d59e1e1efe2e1
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Sat May 19 08:01:47 2007 +0000
-
- * Remove a misleading comment in exception_spec
- * Pre-compile bin/*.rb after a make install
-
-commit 7608e585e02283677275aaf5e5283e397ed2d671
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri May 18 23:57:09 2007 +0000
-
- Vagabond's Kernel.warn.
-
-commit 9a41c5a21bbc822ff9ff758eb2962ba80e2d454b
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri May 18 18:52:36 2007 +0000
-
- * Re-enable tr and unpack String specs
- * Change 'Nan' to 'nan' in Sprintf to match MRI
-
-commit fdc7032c6e4823727312cc7e5c33386cf9d91429
-Author: Mental <mental@unknown>
-Date: Fri May 18 06:01:20 2007 +0000
-
- add spec for ensure result elision
-
-commit 37438dc826624c3fee3afc1d30a9f661bbb1ab8d
-Author: Mental <mental@unknown>
-Date: Fri May 18 05:45:28 2007 +0000
-
- basic thread spec
-
-commit d89b7728d148ba8c1ddd74323aa8f9e3dae79691
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri May 18 02:37:55 2007 +0000
-
- * Fix 'should_raise' in mspec and rspec helpers
- * Added some new Module specs, and fixed existing failures
-
-commit f63e0cf797158a239f65714918debf7a6c1bb687
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Thu May 17 04:12:58 2007 +0000
-
- * First draft of a mock lib for mini_rspec
-
-commit c7fd82a8b4b84088de45463dbc25ae7eea5aabe2
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 16 22:38:27 2007 +0000
-
- * at_exit handlers should run in reverse order of registration
-
-commit 2fb5c6e46f1682d927be8a9e116a609c75ec8be5
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 16 22:14:21 2007 +0000
-
- * Fix Kernel.Array(). All core/kernel specs pass now
- * Add Kernel#at_exit specs
- * Fix Kernel#`
- * Move AtExit handler array from Ruby namespace to Rubinius
- * It's spelled 'occurred', not 'occured'
-
-commit 3d1605a3ca731b05b5c03ebd8a6edcf386612930
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed May 16 06:04:16 2007 +0000
-
- added incompatible specs for #instance_methods returning symbols.
-
-commit 8ba8409ae0ab94a33cd082f02a81d4d1eab35b59
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 16 04:27:22 2007 +0000
-
- * Patch by shadowfiend - Enhance Module specs and implement Module#instance_methods
- * Make sure instance_methods always returns symbols, not strings
-
-commit 1e9b0066d712d4507260be02cf2bf116b2519af2
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed May 16 03:24:35 2007 +0000
-
- * MethodTable 'is a' Hash, and does not need its own fields in the bootstrap. Fixes 'Object.methods.keys'
-
-commit 8c57dd0e26cb5468c1b0150c5d9c5d80ae6f2de2
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon May 14 06:18:42 2007 +0000
-
- fixed class specs to pass on MRI. put rbx-specific integer specs in spec/rubinius.
-
-commit 8b43acd25a14f540447a9f958f7671822f836817
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon May 14 05:59:06 2007 +0000
-
- moved rbx-specific proc specs to a new home. made core proc_specs pass MRI.
-
-commit 4feb384d0a02b272bd1a3581dd4070ef475b25af
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon May 14 02:59:22 2007 +0000
-
- added RUBY_ENGINE == 'rbx' to global constants and exposed Rubinius::<const> on Object like MRI. converted sprintf specs.
-
-commit 34ad791d5f60177de7992a24f07992bb0d6c8b09
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Mon May 14 02:25:06 2007 +0000
-
- * Disabled Lightning's dissembler on amd64
- * Split specrunner into bin/mspec and a wrapper
-
-commit 8796b1f00501813c62676266508a6f89a82ec48e
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun May 13 22:47:28 2007 +0000
-
- minor reorganization, cleanup of spec dir.
-
-commit 9be73815e2037dcc5347c2ef9876e76316efc504
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun May 13 22:06:54 2007 +0000
-
- specrunner outputs summary with 'examples'. converted language/literals, keywords, straggler method_spec.
-
-commit 647fe38ce5f132b7944cca8550233249d8b3c113
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun May 13 21:21:04 2007 +0000
-
- converted language, parser, library specs.
-
-commit d9e8f1fd3bc70231c89a1bdc17a9af5a46fce819
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun May 13 08:28:21 2007 +0000
-
- converted incompatible specs.
-
-commit 9a07bb52c526ce8883c53d437077d78510b0ac73
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun May 13 08:09:34 2007 +0000
-
- added Object#coerce_string that should act like 1.8.x StringValue function. added String#crypt and a couple other String things.
-
-commit 2bae9b5e3baa33da21c1335e84c2eab062eac3a4
-Author: Kev <kev@unknown>
-Date: Sun May 13 06:21:06 2007 +0000
-
- add rb_hash_delete
-
-commit 0ca1a5baa94b5984b0812365a408688420168d24
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Sun May 13 05:31:24 2007 +0000
-
- Imported GNU Lightning. subtend's rb_define_method_ now generates stub's to pop the args and call the function. Next step, add type conversion to call functions that don't take handles.
-
-commit 141e795d5042cb4ea398c9b8eaa9cd7045f5625e
-Author: Kev <kev@unknown>
-Date: Sun May 13 05:15:33 2007 +0000
-
- Add rb_hash_aset
-
-commit 0988a253d8e23b400a738ad74637e8b3655eae8c
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat May 12 19:40:35 2007 +0000
-
- new .rba's with rue's changes. converted spec/shotgun specs. added specs for Tuple. added aliases size, length for Tuple#fields.
-
-commit abd44484b4b2a28a4c7f0bf7acdf12ff30123729
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sat May 12 19:32:06 2007 +0000
-
- * Fixed class variables, should work everywhere now
- * Specs for cvar behaviour
-
-commit 8ec7dac58577cea314ff0fcd976219b23591bc4d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat May 12 07:40:42 2007 +0000
-
- reimplemented Object#instance_variable_get|set and #instance_variables. now works with immediate values, and classes with no __ivars__.
-
-commit 30c4dd441243277ec5b814ad9b4d4697e87641d0
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri May 11 07:56:14 2007 +0000
-
- added primitives for instance_variable_get|set so that methods operate identically on objects that do not have an __ivars__ field (e.g. Array, String). this needs more work because an exception occurs when attempting to set|get instance vars on an immediate value.
-
-commit 998a0ab62542f36f9e36bdd497116349421951ce
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed May 9 23:07:35 2007 +0000
-
- * Converted rest of spec/core/
- * mini_rspec/specrunner improvements
-
-commit 0cac71dd1e4dbb728bd3401e73fda5b3fbe95e38
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed May 9 08:18:59 2007 +0000
-
- updated expectations to be the actual compiler output. these specs should be carefully reviewed.
-
-commit 8d551887fd1fabc7700f9f0a432b728829dcef96
-Author: Kev <kev@unknown>
-Date: Wed May 9 07:42:15 2007 +0000
-
- Pull out bundle that got caught in the commit
-
-commit 736916decc6d9bfd7096079a0118f41a168d735d
-Author: Kev <kev@unknown>
-Date: Wed May 9 07:41:42 2007 +0000
-
- Add hash specs, and impl of rb_hash_new
-
-commit 2352f0a526be0f277f2e5d60f18acddc216045c1
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed May 9 07:06:45 2007 +0000
-
- converted test/bytecode/test_compiler to specs.
-
-commit 1f1d30f9ca690214a61f299a4bb408c2d28ef004
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed May 9 06:08:41 2007 +0000
-
- * Converted MatchData specs
- * Default warnings for empty spec files
- * Improved specrunner
-
-commit 04c03e648ca83de2c2aee37f9aef9079d0493bd7
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Tue May 8 06:24:48 2007 +0000
-
- * Converted Integer and Kernel specs
-
-commit a202ef1dfb21cebf3ee33376775d86b9dc89269d
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue May 8 05:45:33 2007 +0000
-
- added before, after methods to mini_rspec. started adding compiler specs as conversion from test/bytecode/test_compiler. removed all host/target junk. thanks. bye.
-
-commit 692da2d89089bc94c95915c90da756480a057dc1
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue May 8 03:36:51 2007 +0000
-
- converted object specs. these really blow up rubinius.
-
-commit 714f5df86f583158d73eda366e2f2527156c3b8e
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Mon May 7 17:29:56 2007 +0000
-
- The first compiler spec, testing the masgn assembly. Some are commented out because they don't yet work.
-
-commit 8ccfe13ca0eca4ceae6a201905a64666a75dd6ba
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Mon May 7 05:52:41 2007 +0000
-
- * Converted and reviewed Hash specs
- * specrunner reports specifications and failures
-
-commit aa32b8e94de5c1ccd49a9d6ddca5836d6303c460
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun May 6 06:50:52 2007 +0000
-
- finished converting fixnum specs.
-
-commit 7c55264dc15ed2b8a1b341a5d605701c6626ad34
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Sat May 5 06:22:37 2007 +0000
-
- * Converted Enumerable specs
-
-commit 1c660edd87fa91d8c244289b00eb9252d5654c3d
-Author: Evan Phoenix <evan@fallingsnow.net>
-Date: Fri May 4 23:45:08 2007 +0000
-
- Fix array_append as well as the logic to call the extension function so the arguments are correct.
-
-commit 6b9c27b8f8d12be443d37635e17b23b7f0d76388
-Author: Kev <kev@unknown>
-Date: Fri May 4 07:54:10 2007 +0000
-
- Complete rspec coverage of subtend string compat to date.
-
-commit 32db2e9a157cee24ae883b7b8fd563d98fc2dce5
-Author: Kev <kev@unknown>
-Date: Fri May 4 07:11:21 2007 +0000
-
- Add loading of C extensions via require.
- Stop grammar.c from generating every fricking time
- Cleanup formatting on subtend
- Add proper minispec tests for subtend
- Remove old subtend test extension
-
-commit 851fbe6e587596fd074b4c99e42c43865118ae00
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri May 4 06:58:35 2007 +0000
-
- converted (but not to the new new style) fixnum specs. fixed mini_rspec to rescue backtrace.show on MRI.
-
-commit 3e8deacb57ef80684281b1329778bc52681a8601
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri May 4 06:22:53 2007 +0000
-
- converted module specs. added incompatible spec for const_defined?(Some::Class). made mini_rspec print backtrace on error.
-
-commit 3c1cc4ff4f6bf4fa28f65d9909a74f77f6524aa8
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri May 4 05:45:50 2007 +0000
-
- converted math and exception. added two helper methods: should_be_close, should_include. I think spec_translator should handle converting these to 0.9.x syntax as soon as rspec runs.
-
-commit 28e3cdba63f2853b9e9a084f27ad764437830799
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu May 3 15:26:39 2007 +0000
-
- converted float specs. added ignore for *.rbc on externals/rspec-0.9.1.
-
-commit 69ea5db15fb0562d8a4114d4e8ec54f2e19ad8fd
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu May 3 06:40:17 2007 +0000
-
- converted range, nil, regexp specs. added ignore *.rbc on rspec dirs.
-
-commit 6cc364770406e4e04ef7baf2fdaab7425a7f5a6c
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Thu May 3 03:27:04 2007 +0000
-
- * Converted Dir specs
-
-commit 5e39be7f97d5cd131b0cf564746d881245030f7d
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu May 3 03:04:24 2007 +0000
-
- okay, rue insists that we use describe ... it now. (see spec_translator with rspec 0.9.1).
-
-commit 99f05b9d6572600ed0bf6a732048c1c4a2d2bb0b
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu May 3 03:00:06 2007 +0000
-
- converted bignum specs. 100% pass on MRI.
-
-commit f9e4df4bdb721eb32c4ac7e5abd4a646daaf20d2
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu May 3 00:06:19 2007 +0000
-
- fixed mini_rspec aliases for specify, etc. to work around exception: No method 'alias_method' on an instance of Object. (NoMethodError)
-
-commit 89d3ca0681816afd389907cbb52f7e0372dbecef
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed May 2 07:13:56 2007 +0000
-
- * Converted spec/core/ binding, class and continuation
-
-commit 086f889a9bae2e40dd6a8b1ffa80113070f3ad46
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed May 2 04:22:12 2007 +0000
-
- * bin/specrunner is a small bash kludge for running mini_rspec over
- a directory (recursively) or a single file
- * Rakefile allows diffing a current spec run against a base run to
- easily see all changes among the thousands of specs as well as
- storing a base run
- * specrunner produces decent output for the minimal spec output
- from mini_rspec
-
-commit ba89b2c015d2754b6470b324a013f018d8202cfe
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Tue May 1 22:57:22 2007 +0000
-
- * Converted spec/core/array_spec.rb to mini_rspec
- * Reviewed and fixed some specs for Array
- * Spec-style output to mini_rspec (manual comment/uncomment to switch)
- * should_raise for slightly more natural exception verification
-
-commit 0330bcc23fa1609db291cd382cb13fc168ec5bf3
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Tue May 1 22:44:40 2007 +0000
-
- * Implement correct behavior for String#split when called with a zero-width Regexp
-
-commit c8e806e2dafd237fa8117ead21553a195900613e
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue May 1 02:29:35 2007 +0000
-
- converted symbol_spec. 100% pass.
-
-commit 76e31065df70ebc5790fdb604f1b07d28ffaa81c
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue May 1 02:19:33 2007 +0000
-
- commented out specs that cause rubinius to hang. String#delete and #tr (and methods that are implemented in terms of these).
-
-commit 2ae8aea13161a71c3fb4ca8e0486acd55c897579
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue May 1 01:17:14 2007 +0000
-
- converted core/string_spec to regular syntax. added mspec_helper.
-
-commit ff84053991295b259ca8b1c17adff95f5d471961
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Apr 30 22:31:26 2007 +0000
-
- converted false_spec. added svn:ignore *.rbc on all spec dirs.
-
-commit 3fc864ba235c56118e1db66dbf9537d6ff8c0c5f
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Apr 30 22:00:12 2007 +0000
-
- Let the breakage begin. Converting all specs to use mini_rspec with 100% compatible syntax with rspec proper. usage: 'USE_RSPEC=1 spec spec/core/false_spec.rb' for any specs that use example {} method. spec spec/core/true_spec.rb OR ./shotgun/rubinius spec/core/true_spec.rb for converted specs.
-
-commit 4c6c7f406d0e5504a72c52b1ae5339a9dba36865
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Apr 29 17:28:11 2007 +0000
-
- added setup method and print to STDERR and STDOUT to support a shell script runner.
-
-commit 958a0e9b1a066cf2d825b960b66788b05c928f36
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Apr 29 08:26:09 2007 +0000
-
- mini rspec implementation. example {} method is dead.
-
-commit a323b3d424f226322cf20e65e87f8a4e962ed497
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Apr 29 03:23:17 2007 +0000
-
- Added Array#first, Array#last that take numeric args to core. Added a bunch of failing specs for Array#[]. #first and #last are implemented using #[] so several of the specs for those fail, but the implementation of #first and #last was tested in MRI.
-
-commit 3897c943069582b1e5d1649a097bd77c0c895e0a
-Author: Hurdlea <hurdlea@unknown>
-Date: Thu Mar 29 13:51:13 2007 +0000
-
- * Support for Floats in Sprintf
- - Sprintf is still missing support for unsigned twos complement
- * String#% now implemented
- * Fixed a minor issue in the Rakefile
-
-commit 5ed87ff88793f8d44cfe34b443eb032d27dc2a4c
-Author: Hurdlea <hurdlea@unknown>
-Date: Thu Mar 15 05:08:34 2007 +0000
-
- * Added Sprintf core module and classes for string % and Kernel
- - Still needs some work with floats and requires a couple of
- primitives to achieve this.
- * Fixed a small issue with String#Index(Fixnum, offset)
-
-commit 982c09b15710429fc97d8d43d9f24a3a0badb6d5
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Mar 10 22:35:18 2007 +0000
-
- Fixed array spec for #sort which improperly depended on the accidental order in which two elements of the array were being compared.
-
-commit 32fe004da7f35e9b7dcc96f8e57e1acb37164748
-Author: Hornbeck <hornbeck@unknown>
-Date: Sat Mar 10 06:38:23 2007 +0000
-
- Two tests in the ObjectSpace spec. It was bare and needed love.
-
-commit e1530bb1999118bf88037dccc27d78f54bdbe5e4
-Author: Tlockney <tlockney@unknown>
-Date: Sat Mar 3 23:28:27 2007 +0000
-
- updated all rspec exceptions. exception specs all pass in MRI. still a few rubinius exception spec issues
-
-commit 2c278533cbfe0efc7076d2c947323640be5f207a
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Mar 3 21:29:55 2007 +0000
-
- Committing tlockney's additions to core/exception_spec.rb. These pass on MRI but illustrate areas to fix on rubinius.
-
-commit fd8993c0996e4524440a6572c45dad4ab112fb2f
-Author: Hornbeck <hornbeck@unknown>
-Date: Fri Feb 23 15:58:33 2007 +0000
-
- committing Aki Reijonen's Hash patches for hash.rb and the hash_spec.rb. Also included is Thomas Lockney's exception_spec.rb patches.
-
-commit 08e6d924b8c0175242c1c40322ed3e45855a86c2
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Feb 18 07:48:46 2007 +0000
-
- Altered Object#instance_variable_[get|set] rearranging flow control. Added specs for instance_variable_[get|set] for Array, IO, String.
-
-commit 2a2385413c03f21dfc038e110f46a7a3bd2fc9c7
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Feb 18 06:05:47 2007 +0000
-
- Increased time out value when running rspec error report. Minor changes to text in class specs.
-
-commit bd0d7fcf72546a0a3a5a6a59b1a6f2aadd8e4262
-Author: Mae <mae@unknown>
-Date: Sun Feb 18 03:53:00 2007 +0000
-
- Integer#bits for future refactoring of shift
- * added Integer#bits which calculates minimum bit storage required for (signed int) form of the Integer
- * spec'd it too
-
-commit 4e6b39d5e69c04d92ceac76ce5a5bd792fb65f39
-Author: Mae <mae@unknown>
-Date: Sun Feb 18 02:55:55 2007 +0000
-
- Object#extend-a-gogo
- *Fixed Small bug in rubinius_target where failures wouldn't be reported
- *Implemented Object#extend and changed math.rb to use it accordingly
-
-commit 5472c10579cef38f9f28c904710246509633a040
-Author: Mae <mae@unknown>
-Date: Sun Feb 18 01:21:11 2007 +0000
-
- A great Time patch from John Hornbeck <hornbeck@gmail.com>:
-
- A more complete Time diff. This includes many of the instance methods for Time and a new primitive for usec. This diff also includes some failing specs as I went ahead and added the specs for the rest of the class methods. Also included is the constants for Time.
-
- Keep the good work coming John!
-
-commit 83ab11e0ab6679b1c9eefc5095d3f20af9a61661
-Author: Mae <mae@unknown>
-Date: Sat Feb 17 23:26:33 2007 +0000
-
- Patch from Aki Reijonen <aki.reijonen@gmail.com> without the Float.induced_from part
-
- Summary of the changes:
-
- ** Added methods **
-
- Numeric#integer?
- Numeric#div
-
- Integer#to_int
- Integer#round
- Integer#truncate
- Integer#next
- Integer#succ
- Integer#integer?
-
- String#slice!
-
- Object#to_a
-
- Kernel#Array
- Kernel#String
-
- ** Fixed methods **
- Float.induced_from
- - Now return the passed object if it's an Float insted of calling #to_f
-
- ** Removed methods **
- Fixnum#div was broken, the end result should be converted to Integer,
- not the number passed as a argument. (superceded by Numeric#div)
-
- --
- Aki Reijonen
-
-commit 243a4e9ba46149b8ba39c7238f8ff3d5f267689e
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Feb 17 06:17:44 2007 +0000
-
- Ditched all the instance vars in array specs since we've got locals now.
-
-commit be5363e22e04b8baf26cb4abd8a8a67e7dd3cc0c
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed Feb 14 01:05:49 2007 +0000
-
- Fixed * varargs to work in method definitions. Currently still
- does not work as the single named parameter (foo(*a)). This
- means that lib/bytecode/encoder.rb now compiles under Shotgun.
-
-commit 3bb810688e848c90d5c20929c630f36a32796d2d
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 13 18:42:09 2007 +0000
-
- Added Object#instance_variable_set and specs.
-
-commit 54392c99dc3db5b58c85799416cc528c60b12533
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 13 18:25:24 2007 +0000
-
- Added Object#instance_variable_get and specs. Uncommented Math module constants specs.
-
-commit 84267901502ca1e8e8b13afa0e3a16e0cdc8e493
-Author: Mae <mae@unknown>
-Date: Sun Feb 11 10:30:13 2007 +0000
-
- * Primitive Specs
- - Added spec for bignum_div (and fixed a problem where it would always fail)
- - Fixed primitive_spec_helper (because it broke the old specs last time)
- - Removed magic method chaining because it sucks
- - DISCLAIMER: primitive specs atm just test functional things, _NOT_ stateful side-effects
- - We can do this properly once rubinius can run rspec
-
- * SIRB
- - Made it so that => wouldn't get printed before the command prompt if you typed "exit"
- - Made Kernel#p, Kernel#puts, Kernel#print return nil (like MRI)
- - added #!shotgun/rubinius to top of sirb and symlinked it to bin/sirb.rb as well (for convenience)
-
- * Removed unused local from __loader
-
-commit efce7d8a56748ab1831a34d21b8c92ff8b2eb977
-Author: Mae <mae@unknown>
-Date: Sun Feb 11 07:25:51 2007 +0000
-
- Moved math to math_spec; added object_spec for primitives; made primitives_spec_helper maybe too smart? -- they chain methods on to the remote target
-
-commit 087a5e5a6e89e4a53a39e025ffe08d21e96b8f6e
-Author: Mae <mae@unknown>
-Date: Sun Feb 11 05:51:30 2007 +0000
-
- * Made rubinius_target and example much more helpful
- - backtraces are shown on failure now
- - you can do this: example { 1 + nil }.should_raise(TypeError) and it works :) (with bt and all)
- - injected some extra code in example snippets so try(exc) syntax still works
- - Float, Nil, True, False specs all pass 100 %
- - made rubinius_target make use of @src (used in bignum)
-
- * Made Kernel.Float() and Kernel.Integer() behave appropriately like MRI _with_ the exception of Float() also checking for to_i method
- - Integer(nil) => 0 and Float(nil) => 0.0
- - lots of spec coverage
-
- * Numeric#coerce was slightly tweaked to use new Float() and Integer() behavior
- - Specifically complains about other being nil (so 1 == nil doesn't work)
-
- * Made Float.induced_from() more anal retentive (only accepts core Fixnum, Bignum, Float types like mri)
- - specs cover it
-
- * Fixed infinite loop on Bignum#& and moved & out of Numeric into Integer (Float doesn't have &)
-
-commit eadf1ead754d3dbfaf703c205f6f5e8f4dc5c430
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Feb 11 03:00:25 2007 +0000
-
- Put object flags values into a single include file. Added Object#taint, tainted?, freeze, frozen?. Neither of these states actually effect execution yet. Fixed up Object specs.
-
-commit 38e7f757e67b4ec985835e0e93ba4d32bbee5ca4
-Author: Mae <mae@unknown>
-Date: Sat Feb 10 23:57:37 2007 +0000
-
- - Created specs for math_sqrt primitive (and created spec/primitives/math_spec.rb)
- - Tweaked primitives_spec_helper to properly transport NaN's to testing environment
- - Removed non-needed self parameter from math_sqrt c function
-
-commit a4267a136d7f0bf7f92421fcebd8011600a1d92e
-Author: Mae <mae@unknown>
-Date: Sat Feb 10 22:29:46 2007 +0000
-
- Float.induced_from love
- - made Float.induced_from work for any to_f item (controversial whether this should be done in Kernel.Float() or not)
- - apparently this fixed some float failures
- - made Float.induced_from safer because it now complains if to_f returns a non-float
- - wrote specs for new induced_from behavior
- - try (spec_helper) needs to be investigated, manual running of the premises of 'Float divmod should raise FloatDomainError if other is zero' show this to be a spec that _should_ pass
-
-commit 65a4e8abfc7f690456e4f44e7e4cc38911288516
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Feb 10 18:54:15 2007 +0000
-
- Added spec files for the rest of the core classes documented in Pickaxe book. Add simple class hierarchy specs for exception classes.
-
-commit c7a2f68c36dd95f51af88e8fa62b24b71d68578a
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Feb 10 17:29:46 2007 +0000
-
- Commit of scoopr's Math module beginnings. Thanks scoopr.
-
-commit b1e8d150460f2ae9ea2e5ef87d0df3b705c1d0d6
-Author: Mae <mae@unknown>
-Date: Fri Feb 9 08:54:25 2007 +0000
-
- Bignum primitive specs
- - Added spec and changed to metaprogramming style for primitives: bignum_add, bignum_compare, bignum_equal, bignum_and, bignum_divmod
- - fixed bug that bignum_divmod spec found where bignum_divmod would always fail on divide by zero GUARD
-
-commit 0487a39ec9995af8eb5a8dff5ec64492261852e7
-Author: Mae <mae@unknown>
-Date: Fri Feb 9 07:48:56 2007 +0000
-
- Primitive Spec Sexiness
- - Added spec and changed to metaprogramming style for primitive fixnum_to_f
- - Made usage of run_primitive(:add, 1, 5) more sexy i.e. 1.prim.add(5)
- - converted fixnum spes to use sexiness
-
-commit 95fa48f29eaa7e3f10ccd63d385fb3f582f57eea
-Author: Hurdlea <hurdlea@unknown>
-Date: Fri Feb 9 01:36:14 2007 +0000
-
- * Added String#delete, delete!, tr, tr!, tr_s, tr_s!
- - String#count and squeeze to follow ...
- * String#<< now accepts Fixnums
-
-commit 017bdc57602e2e5d55705de070c07edba46a347f
-Author: Mae <mae@unknown>
-Date: Thu Feb 8 09:23:55 2007 +0000
-
- - removed noop from primitives (it does nothing)
- - removed noop primitive spec
- - changed CPU::Primitives.name_to_index to offset by +1 (to leave room for special 0 value)
- - still having same closed parens issue with spec:primitives:
- syntax error, unexpected $end, expecting ')' (SyntaxError)
-
-commit 18a3347bb32d8ac5269438376f0100ecce2c9e73
-Author: Mae <mae@unknown>
-Date: Thu Feb 8 08:20:14 2007 +0000
-
- - made shotgun/lib/primitives.rb have less dependencies
- - fixed bug where if a false was popped of the stack it wouldn't be recognized as an argument in primitives_spec_helper (nil will only do this now)
- - fixed regression in primitives_spec_helper where the proper code wasn't showed when shotgun crashes
- - noop_spec works again
-
-commit 16b08e446b69344da1edbc1f793e0161deac8e6c
-Author: Mae <mae@unknown>
-Date: Wed Feb 7 23:59:14 2007 +0000
-
- More Primitive Goodness, Conform to unified rspec standards
- - Added specs and changed to new metaprogramming style for the following primitives: fixnum_and, fixnum_or, fixnum_xor, fixnum_invert, fixnum_neg
-
-commit cb2ac85b45a41a63100cac673919ad8db1f93f43
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed Feb 7 23:16:35 2007 +0000
-
- Basic specs for Symbol literals.
-
-commit 3ab7aced51f3a63c8f76706a2f159d0d5753dc64
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Feb 7 20:35:27 2007 +0000
-
- Changed Fixnum primitives specs to be in a single file, spec/primitives/fixnum_spec.rb. Added back the alternative example of writing specs for others to evaluate or use. Updated the wiki specs page to lay down the law on spec files. Kindly follow it.
-
-commit cf16d691990f43f5bf8807bbef2ba1876892be57
-Author: Mae <mae@unknown>
-Date: Wed Feb 7 18:27:15 2007 +0000
-
- Autotest, C warnings cleanup, and some primitive_spec usage cleanup
- - Added Autotest Facilities for primitive bin/autotest/primitives
- - need to gem install zentest to use this (and some diff gem i can't remember)
- - Removed ugly require statement from cpu/primitives it was causing annoying ruby errors
- - Added missing prototypes to cpu.h and regexp.h (primitives.gen was complaining)
- - Localized bt and bt_size variable declarations to where they would be included by the preprocessor to make more warnings go away
- - Added newlines to the end of numeric.c, numeric.h, float.c
- - Used one of brixens suggestions (injection of primitive spec helper automatically)
- - Removed extraneous primitive helper inclusion in each spec
-
-commit f4bbce9d761d27e1381b95a4ff6076e85577074d
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Feb 7 16:56:21 2007 +0000
-
- This shows an example to 'fix' mae's rubyesquely-challenged (bluntly, ugly) primitive specs. Also, there should be one spec file for a group of related contexts. In this case, the group is the class Fixnum. So, mae, fixnum_spec.rb, NOT fixnum_xxx_spec.rb. Sorry. Cry tyrany, weep and gnash thy teeth, howl in protest, but please fix it. This is non-negotiable. Thank you and good work on the primitive specs. :)
-
-commit e5f6215824a40beb0ca678575596bd06afa8dd3a
-Author: Mae <mae@unknown>
-Date: Wed Feb 7 09:54:54 2007 +0000
-
- - Added specs for primitives: add, sub, fixnum_mul, fixnum_size, fixnum_div, fixnum_modulo, fixnum_divmod, fixnum_to_s
- - Updated primitives to new metaprogramming style: sub, fixnum_mul, fixnum_size, fixnum_div, fixnum_modulo, fixnum_divmod, fixnum_to_s
- - Changed wording in a couple primitive spec files to be more explicit
- - Made reporting by primitive_spec_helper more helpful when shotgun crashes from injected code
-
-commit 3032c6bd869a04c1517508850f94119975c36e54
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Feb 7 02:26:47 2007 +0000
-
- Fixed up String#to_i a bit; added a bunch more specs for it.
-
-commit d8a24ffa8d9983a85b0f03784a89bfa667af1615
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Wed Feb 7 01:46:30 2007 +0000
-
- Added very basic set of specs for assignment and multiple assignment semantics.
-
-commit edb7c82523b36b26e24437de42fd2638eef1653f
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 6 19:02:46 2007 +0000
-
- Added specs for and methods CType#isalnum, isdigit.
-
-commit e84ba1b12c51331d00bdd06684dcff96ea229322
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 6 17:30:55 2007 +0000
-
- Added spec/shotgun/bytearray_spec.rb. Added spec for ByteArray#[], []=. Modified various string methods to use BA#[], []= instead of get_byte, set_byte.
-
-commit be9589cc47cbf35edd94ca22407de4b1527a3fdb
-Author: Mae <mae@unknown>
-Date: Tue Feb 6 11:26:31 2007 +0000
-
- Tweaks to primitive metaprogramming and addition of noop spec
- - Added types 'qnil' 'qtrue' 'qfalse' to be used in primitive metaprogramming
- - Added spec for noop primitive
- - Added run_asm method to primitives_spec_helper for those tricky tests
- - Converted noop primitive to new metaprogramming style
-
-commit e31f1af903dd8dd31427e34a718b30f5c63af8df
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 6 10:33:00 2007 +0000
-
- Some fixes to String#to_i and additions to specs. Added String#oct and hex.
-
-commit 2a157827bd72b6c7ce8a025928cdd9d7f2f8d00f
-Author: Mae <mae@unknown>
-Date: Tue Feb 6 10:18:16 2007 +0000
-
- moved equal and compare to use new primitive technique
- - also updated equal_spec to ask for ArgumentError instead
- - uploaded new rba *glares at brixen*
-
-commit 771d0fede3086ce58d225ac4001ea0934f3bb0e3
-Author: Mae <mae@unknown>
-Date: Tue Feb 6 09:33:03 2007 +0000
-
- ARITY macro raises ArgumentError directly from the primtive now and made specs pass
- - Made ARITY macro raise an argument error exception instead of just ambiguously failing
- - Made _ret return TRUE on arity failure (exception directly raised)
- - Moved GUARD and POP macros to shotgun/lib/cpu_primitives.c where they belong (localized)
- - Removed side-effect printf in cpu_raise_arg_error since stack trace is fine now
- - Tweaked primitives_spec_helper should_raise to work for all exceptions
- - Made specs for equal/compare pass again (expect ArgumentError instead of PrimitiveFailure)
- - New compiler.rba (update these ppl!)
-
-commit e89190c8fdc4a71c7b8cd9c8b873a63b9d1888c5
-Author: Hurdlea <hurdlea@unknown>
-Date: Tue Feb 6 07:51:08 2007 +0000
-
- * Finished String#[]= for string index
- * found odd bug with spec where string[1,2]="foo" is not interpreted correctly
- changed methods to use send(:[]=, ... and the tests pass
-
-commit c6e1bb68e930a537bd51d77afd37cdc8b5d62d31
-Author: Hurdlea <hurdlea@unknown>
-Date: Tue Feb 6 07:18:15 2007 +0000
-
- * Added String#[]= slice functionality
-
-commit e405d4f5f32fd8192c435b3488f394b2635c7db7
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 6 06:37:31 2007 +0000
-
- Added String#chomp[(bang)].
-
-commit ff48a6c333f34c1b1882c260db7145facce3d71f
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 6 06:00:56 2007 +0000
-
- Added String#replace_if that calls replace if self != other else returns nil; Added upcase, downcase.
-
-commit f46d747eba82c215fa07b067a30f2a2e8868d284
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 6 05:31:13 2007 +0000
-
- Implemented String#reverse directly rather than with String#<<. Modified some string specs for [lr]strip but forgot to commit them earlier.
-
-commit d3b0e71e810a985f3b8f2e5f5c7d5c4619f151f9
-Author: Hurdlea <hurdlea@unknown>
-Date: Tue Feb 6 03:00:28 2007 +0000
-
- * Added NilClass specs to detect NilClass coercion
-
-commit c570ca475cabeb3fcfcca26d4c57b8e57f6606b4
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Feb 6 02:01:19 2007 +0000
-
- Added module CType mixin for Integer to provide isspace, isupper and friends. Added specs for CType in spec/shotgun. Implemented String#capitalize[(bang)]. Moved ByteArray into it's own file. Updated various string specs and commented out temporarily index spec.
-
-commit 4694d1511e880e43dfccb3e3f5309f0920395ba0
-Author: Hurdlea <hurdlea@unknown>
-Date: Tue Feb 6 00:22:17 2007 +0000
-
- * Fixed operation of Regexp#=~
- * Updated Regexp spec for =~
- * String#== now works correcly for duck typed objects
-
-commit 8e42aa9c789fcc9bc475d460e7158f2adcc8ab64
-Author: Mae <mae@unknown>
-Date: Mon Feb 5 22:46:21 2007 +0000
-
- Added arity checking for primitives
- -for use in primitives: #define ARITY(length) GUARD( (length) == num_args )
- -for instance if i have a primitive that takes one argument (self + arg) i put ARITY(1) at the top
- -changed specs with regard to arity accordingly
- -made block_given conform to the "self rule for primitives" by padding Qtrue where self would be
- -fixed block_given? to pass the right arity (0) in the compiler
- -specs for compare and equal pass now
- -added primitives_spec_helper (forgot last time)
-
- NOTE: Binary .rbc compatibility is broken now since there are arity checks done on block_given?
- -the rba's i uploaded should be fine but if they arent...
- do find -type f | grep .rbc | grep -v .svn | xargs rm
- then rake build:rubinius
-
-commit 2d5c9bc3170bf959390627def10c0208088b48ee
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Feb 5 22:39:08 2007 +0000
-
- Added Integer#isspace and spec in spec/incompatible. Added spec/incompatible/string_spec to describe behavior of stripping runs of whitespace and nulls from end of a string. Added or modified String#lstrip, lstrip(bang), strip, strip(bang), rstrip, rstrip(bang).
-
-commit d4b07b06ca85543423a308f12b82ae4671bdd0c2
-Author: Mae <mae@unknown>
-Date: Mon Feb 5 21:01:59 2007 +0000
-
- -split out common primitive testing functionality to primitives_spec_helper.rb
- -added spec for primitive "equal"
- -again primitive specs are rake spec:primitives
-
-commit c1a7896f24e018df13af7f0d3d60db9f461130a5
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Feb 5 20:58:21 2007 +0000
-
- Added that Module#include passes off to append_features. Added Module#include that takes multiple args later in the bootstrap sequence. Added specs for include and append_features.
-
-commit d407ecab13722599b75fecc20bdebd86c9f76fa6
-Author: Mae <mae@unknown>
-Date: Mon Feb 5 20:48:02 2007 +0000
-
- Misc Changes to Tweak primitive specs
- -Added spec to test arity restrictions of compare
- -Fixed bug where should_raise for primitives was not catching the error condition
- -Changed wording of some specs to be english rather than engrish :)
-
-commit f68ad63065002d4a3c9a0742770da4a112780aa7
-Author: Mae <mae@unknown>
-Date: Mon Feb 5 20:02:24 2007 +0000
-
- - Remove printf from cpu_raise_primitive_failure so that the screen doesn't get littered
- - Created PrimitiveSpecHelper and a "primitives" spec subdirectory
- - Added rake task spec:primitives
- - Added compare_spec as an example
- - New rba's
-
-commit f997d3791099912001d09a427f24252182ba1d6c
-Author: Hurdlea <hurdlea@unknown>
-Date: Sat Feb 3 08:10:48 2007 +0000
-
- * Added MatchData#values_at
- * Fixed implementation of MatchData#select
- * Updated specs for MatchData#values_at, select
-
-commit 4f8301aeb3a5a296a64b887b0f164ca02be2a71f
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Feb 2 17:00:10 2007 +0000
-
- Added specs for and empty module methods private, protected, public as a first approximation to allow code that uses them to not choke. Added String#match.
-
-commit 15c3678ddcc365891fd92cc9cd33eb22308916e8
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Feb 2 10:43:58 2007 +0000
-
- Committing Adam Ritter's patch to recognize 'for i in ...' expression, and associated spec. Uncommented line in float_spec.
-
-commit 370d7a955bf6e41c4ea7cf0f9217128ae7a72fd4
-Author: Hurdlea <hurdlea@unknown>
-Date: Fri Feb 2 07:06:22 2007 +0000
-
- * Added MatchData#inspect, select, to_a, size, to_s
- * MatchData#[] is now more compliant - behaves more like Array#[]
- * Added Regexp#hash
- * Added Regexp#hash spec
-
-commit b496d50c0ebf7d5c523efe2ef5383dd8043aa3f0
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Fri Feb 2 00:36:37 2007 +0000
-
- Added specs for Dir and modified rubinius_target to allow
- specs to change directories safely.
-
-commit 6ddf4051f3a6be7076e947bf3eccbc5dd9a7803f
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 19:11:14 2007 +0000
-
- Fixed Float#divmod, returning 0 guard on primitive, raising FloatDomainError rather than ZeroDivisionError. Fixed Float#% when other is zero. Spec try helper doesn't yet work with rubinius_target
-
-commit 679f3fbe54960a690f4e41e1403fdc8f50c0f346
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 18:36:44 2007 +0000
-
- Added more zero division behavior specs.
-
-commit b4d739a7cb68d6f82d657b69aee00923e0bfdbb4
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 18:12:02 2007 +0000
-
- oops, damn keystrokes. Previous commit msg should just include Fixnum. This change points out a problem that I'm not sure about: 1.quo(0) => Infinity in irb and run from a file, but in the spec I get zero division error. wth?
-
-commit 4e24fe43a7d6c55a53880a1c347e836f12937ed4
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 18:03:13 2007 +0000
-
- Added more specs around zero division behavior for Float and Fixnum.
-
-commit b8f412ee2bf3701acd211372d28ec596d6858ac8
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 18:01:44 2007 +0000
-
- Added more specs around zero division behavior for Float and Fixnum.
-
-commit 17a17e3008422bab9e91f8464d1ce2823c13ce78
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 17:51:47 2007 +0000
-
- Added try spec helper method for spec'ing things that raise exceptions. Added more Float specs that describe division by 0 behavior.
-
-commit 2c2bfc3663a34fbf4fd70a5787236ec8b9a87024
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 17:22:39 2007 +0000
-
- Added spec for Float#% when other is zero to show current implementation is broken.
-
-commit d1ddd71d5bd45df0c16651ecad2db3c1b75d90f8
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Feb 1 17:06:56 2007 +0000
-
- Reverted mae's breakage to Float. seriously mae: you did NOT run the float specs and you did NOT write new specs for the behavior you were changing so you did NOT understand what you were doing. As a good CS student, you can negate the above to know what you SHOULD do. ;) Please, WRITE and RUN your specs.
-
-commit b2e08a170d1ab222d67d8767fa880a5e21c5bf74
-Author: Mae <mae@unknown>
-Date: Thu Feb 1 10:53:48 2007 +0000
-
- know when to shoot your baby in the crib -- cleanup outdated unused code
-
-commit aac75dd658c96cf930852d86dbc79b66830bace5
-Author: Eero Saynatkari <eero@kittensoft.org>
-Date: Thu Feb 1 09:12:03 2007 +0000
-
- Improved specs for Hash.[].
-
-commit 40f637f2685e969f097fbbb2ffa3f0173e6f9866
-Author: Mae <mae@unknown>
-Date: Thu Feb 1 02:44:14 2007 +0000
-
- Fixed my pure ruby Numeric#floor and Numeric#ceil methods
- - Please smash your c primitive brix BWAHAHA
- - Also implemented eql? for float and now all 32 float specs pass
- - Added some edge cases for ceil/float that were not previously covered in specs
-
-commit 5cc6f6b6068e945c6f5896370ee20567e57122e7
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 31 11:24:23 2007 +0000
-
- Added Float#round. We now have 32 of 32 float specs passing. Please confirm on your platform.
-
-commit 9b902a80a008120a86ae18d4abff04d42efefc8f
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 31 06:22:10 2007 +0000
-
- Folded in coerce specs.
-
-commit 09e61132d5b9e9b08d27f2f51db9580808bb370e
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 31 03:22:23 2007 +0000
-
- Created spec/incompatible for specs that show where Rubinius is incompatible with other implementations. Added bignum_spec and fixnum_spec to incompatible dir. Under MRI, Bignum.coerce(Fixnum) => [Bignum, Bignum] whereas Fixnum.coerce(Bignum) => [Float, Float]. Since Bignum should be a seamless extension of Fixnum, this behavior in MRI seems less than consistent. Under Rubinius, mixed Fixnum and Bignum promote to Bignum uniformly, and this makes much more sense. There are other places where Rubinius implementation may deviate from MRI, so spec/incompatible is for describing those behaviors. Updated coerce specs.
-
-commit cb52bb9633d0e323d2f7d6c90879fb7decfea7d7
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 30 10:44:46 2007 +0000
-
- Added Numeric#coerce primitive. Reimplemented a number of primitves and methods on Fixnum, Float, Bignum to use Numeric#coerce rather than implementing knowledge of one another all over the place. Folded in mae's coerce specs. There is currently a (desirable IMHO) incompatibility in Numeric#coerce in that Bignum.coerce(Fixnum) == Fixnum.coerce(Bignum). There are a lot of other methods that need to be reimplemented using Numeric#coerce. Also, bignum_compare needs to be implemented (just returns 0 atm).
-
-commit e1aa382f2d596a73ef20dfde4184af7a721724e9
-Author: Mae <mae@unknown>
-Date: Tue Jan 30 00:26:11 2007 +0000
-
- added specs for coercion of Fixnum, Bignum, and Float
-
-commit bd292d64a511eba51ea1569870bcf0fa365c903d
-Author: Cabo <cabo@unknown>
-Date: Sun Jan 28 21:05:10 2007 +0000
-
- include yesterday's failed cases
-
-commit 7cac7f32e5c80e78aa75dfed7f4822e65d1ab4df
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 28 08:08:12 2007 +0000
-
- committing rue's continuation specs. doomo arigatoo.
-
-commit f542b93031f8982daa13777d2eada81068e96ad5
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 28 07:03:46 2007 +0000
-
- committing rue's class specs. thanks rue!
-
-commit 319b6f194d3c699a75de8da2ba3b53b8a4feffb1
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 28 04:49:01 2007 +0000
-
- Commiting rue's binding specs.
-
-commit d8326b1321cc09c0aa64f441d2a81df6735603fd
-Author: Cabo <cabo@unknown>
-Date: Sat Jan 27 00:02:33 2007 +0000
-
- remove superfluous p from "& should create an array with no
- duplicates" (which now passes)
-
-commit 7d3baf10a79c1500e660fe5566ba8f3107d5a826
-Author: Hurdlea <hurdlea@unknown>
-Date: Thu Jan 25 05:43:50 2007 +0000
-
- * Added MatchData specs
-
-commit 2d9966c9c30e541c18ac77ca646a1af41daf702e
-Author: Hurdlea <hurdlea@unknown>
-Date: Thu Jan 25 05:42:44 2007 +0000
-
- * Added Match2 and correct Match3 in compiler.rb
- * Added alias String#to_str
- * Tweaked a few regexep specs for string return types
- * Fixed MatchData#length so it uses Tuple#fields to get the no. items
-
-commit 0d9f9e21c2a268e0710c963c745f07d494e2ab1f
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 24 21:43:17 2007 +0000
-
- Commiting zimbatm's update to exception_spec.
-
-commit 037d8b29872f1c4a81108a0713afd78cbdf9b484
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 20 04:03:20 2007 +0000
-
- a few more tweaks to get string specs to execute with rcompile and shotgun.
-
-commit cfe7a6b4c87ac3ffccaeb7e70b9e6c386054e052
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 20 03:49:01 2007 +0000
-
- added parser dir under spec. added parser/symbol_spec.rb to capture parsing a complex symbol like :' for one or two', which rcompile and shotgun choke on at the moment. removed this from core/string_spec because it crashes shotgun and makes it impossible to run all the specs.
-
-commit d39040ab1563f063192a3835723cfbae7bf147cb
-Author: Cabo <cabo@unknown>
-Date: Fri Jan 19 23:45:52 2007 +0000
-
- lib/kernel.rbc is no longer a required (or wanted) command line argument
-
-commit 4774788e0ae9b24b3ff0b769aede0ba2de3f00b1
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 19 21:05:10 2007 +0000
-
- added correct guard on Array#first to return nil when array is empty. added specs for #first and #last to describe this behavior. Thanks to cabo for finding this.
-
-commit baf1453678c9906c65b2f7c82bdb0e179e22d1b8
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 19 02:49:02 2007 +0000
-
- added some minor changes to structure and wording of language/expression_spec. removed array and defined spec from language directory since they were added to language/literals directory. renamed several spec files to follow naming conventions.
-
-commit 7a24923ab9b79b226b6d8831e834ab509d5d2b76
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 19 01:27:10 2007 +0000
-
- committing zimbatm's patch to language specs. super nice and thank you. please give zimbatm a commit bit!
-
-commit 9cd8c779a88f48604733afbe4357b7101a487669
-Author: Vic <vic@unknown>
-Date: Thu Jan 18 22:20:34 2007 +0000
-
- Added Proc.given, the analog of MethodContext.current
- Proc.given obtains the proc given to the current MethodContext.
- Later will be able to get a Proc from a given Binding.
-
- Original author: Victor Hugo Borja <vic@rubyforge.org>
- Date: 2007-01-18 16:16:06+00:00
-
-commit 50c42413d33951397a46edb55ca910a2e8fb87e6
-Author: Vic <vic@unknown>
-Date: Thu Jan 18 21:34:29 2007 +0000
-
- No output is available for specs if the returning value is a Numeric or Symbol
- When the :example execution on shotgun evaluates to a Numeric or Symbol, no method
- :stdout is added, because these object do not have singleton-classes on MRI.
- If you really need both, stdout and a Numeric/Symbol, your evaluation may lead to
- an array containing that Numeric/Symbol.
-
- Also saved MRI from getting eval errors in cases like the following:
-
- example do
- class A; end
- A.new
- end
-
- This leads to the following being evaled by MRI: [ #<A:0xb7a69c8c> , stdout]
- which causes an error because of #<A:0xb7a69c8c> being invalid ruby syntax.
- This patch fixes this situation by converting #<A:0xb7a69c8c> into "#<A:0xb7a69c8c>"
-
- Original author: Victor Hugo Borja <vic@rubyforge.org>
- Date: 2007-01-18 15:23:55+00:00
-
-commit ec5bea103b4b96ecde54668e47ab9e10ac8ec4ee
-Author: Hurdlea <hurdlea@unknown>
-Date: Thu Jan 18 21:04:22 2007 +0000
-
- * Added bitwsie operators to Fixnum & | ^ << >> ~
- * Split the fixnum specs into coerced and non-coerced tests
- * Added primitives to support fixnum bitwise ops
- * Fixed a bounds tests in Interger#chr
-
-commit 238d7e0611e9198c28a5e0ebe684bc7f1f03bf0f
-Author: Vic <vic@unknown>
-Date: Thu Jan 18 20:11:58 2007 +0000
-
- [rAdded specs for the new STDOUT support] Empty log message
-
- Original author: Victor Hugo Borja <vic@rubyforge.org>
- Date: 2007-01-18 13:44:19+00:00
-
-commit 859b26f38749f160a706ed9dbb8f2a80886e94ef
-Author: Vic <vic@unknown>
-Date: Thu Jan 18 19:37:03 2007 +0000
-
- Allow to specs to test what is written to STDOUT
-
- also added String#unindent on spec_helper to help make output heredocs more readable.
-
- You can access both the evaluation result and the stdout produced, ej:
-
- context "Rubinius target" do
-
- specify "should allow to get the resulting STDOUT" do
- example do
- puts "hola"
- puts "space is significant in this heredoc"
- puts "unindent removes the first blanks found on the first line"
- puts "on each of these lines"
- puts "adios"
- end.stdout.should == <<-OUT.unindent
- hola
- space is significant in this heredoc
- unindent removes the first blanks found on the first line
- on each of these lines
- adios
- OUT
- end
-
- specify "should allow to get the lines written to STDOUT" do
- example do
- puts "hello"
- end.stdout_lines.length == 1
-
- example do
- print "bye"
- end.stdout_lines.first.should == "bye"
- end
-
- specify "should allow to access the evaluation result along with STDOUT" do
- result = example do
- puts "ok"
- Object.new.class
- end
- result.should == Object
- result.stdout_lines.should == ["ok\n"]
- end
-
- end
-
-commit e17069925d139c93acec00161a7111e6c78d54bb
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 18 08:44:33 2007 +0000
-
- converted shotgun-test/test_sexp to spec/shotgun/sexp_spec. thanks to Victor Borja's recent additions to rubinius_target, it was a breeze.
-
-commit 46e9a259bc2212dee1fa7efa8ead468e63970731
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 17 08:02:35 2007 +0000
-
- filled in the rest of the documented String instance methods except #pack.
-
-commit dfd08d6536ea497cf86d06ca503206d54b19479d
-Author: Cabo <cabo@unknown>
-Date: Tue Jan 16 10:24:18 2007 +0000
-
- A bit more array fun (and lots of FIXMEs)
-
-commit b1e50e43d8d79a5dbd82345134ecd4bdffc6d182
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 16 08:46:48 2007 +0000
-
- and yet a few more string specs. these will asymptotically approach done.
-
-commit 4048d3dfa90a6de54ea2ed0aec2ec6adafb50b0c
-Author: Cabo <cabo@unknown>
-Date: Tue Jan 16 07:02:50 2007 +0000
-
- I want to see what 'Shotgun has crashed' means, beautiful backtrace and all
-
-commit 0387baa914cb35c589c7872f7f98cf9f8ee10711
-Author: Cabo <cabo@unknown>
-Date: Tue Jan 16 02:19:45 2007 +0000
-
- Fix Array#slice! bug workarounds
-
-commit c6b110b47667c5d6750492177492434f4c0446f8
-Author: Cabo <cabo@unknown>
-Date: Tue Jan 16 01:33:18 2007 +0000
-
- add shift spec and fix String#strip so it works
-
-commit 19bcc086b7674f12e01f879a6ca83f3289feb770
-Author: Cabo <cabo@unknown>
-Date: Tue Jan 16 00:06:03 2007 +0000
-
- Integer#chr should return a new string (spec)
-
-commit 5aa81499711ad5e57f5dfc03417f23705eb79b44
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 15 23:48:16 2007 +0000
-
- a few more string specs.
-
-commit 8cd873e183c62b8929305ea54b9a437ca22ddb28
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 15 22:42:24 2007 +0000
-
- committing Victor's define_method patch.
-
-commit cd04f4c570cd95fb869f025c4dac6e9342e2ba2a
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 15 22:02:23 2007 +0000
-
- committing Victor Hugo Borja's instance_eval patch.
-
-commit a481142988d585bb8fa54e0186f5c9cf88ada8d9
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 15 20:13:03 2007 +0000
-
- added a code method to mri_target and jruby_target to parallel the behavior of the code method for rubinius_target. now core/proc_spec.rb is passing with mri target.
-
-commit a4c621e8319349eda766f73ed9ca55f2a9323ac2
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 15 19:08:22 2007 +0000
-
- checked in nicksieger's patch to spec_helper that enables specs to run on jruby, woohoo!
-
-commit 6b02aac6107b01258f85f9d15a77b498ad15e5b0
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 15 18:06:23 2007 +0000
-
- checking in cabo's changes to target specs for jruby and rubinius. modified rubinius_target specs that compared paths to use should_match because a hash is used to generate part of the path.
-
-commit 6aa175d3367d76152476888ff1c52479530c56a2
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 15 17:57:25 2007 +0000
-
- committing cabo's changes to remove heredocs from a number of specs. It is still possible to pass code as a source string to the example method. Use this if the block method is causing rubinius to choke on the ruby2ruby generated source. soon, soon, we'll have rspec running (I hope\!).
-
-commit 6679194f8e6afdbbb71f5213508bb81f12fdb2e7
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 14 17:28:06 2007 +0000
-
- incorporated nicksieger's changes to mri_target removing needless requires. added jruby_target.rb and spec to parallel mri_target.rb.
-
-commit f573b9c16efccb92eec98d923831deafc7a3c809
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 14 08:10:24 2007 +0000
-
- converted mri_target to use eval, yield to execute specs. converted some specs to new style. addressed issues with hash specs that implicitly relied on hash ordering, fixed numerous issues that result from loss of floating-point precision by using #inspect where necessary (more of these issues may arise in the specs on different platforms). added spec templates for documented String instance methods (many of which need to be filled in).
-
-commit 917cd03e5bee749d18d8d0c257381bca2362abbd
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 14 00:11:17 2007 +0000
-
- checking in Alan Hurdles patch to allow running specific files, e.g. COMPILER=rcompile rake spec:core:array .
-
-commit 508eaacf9aaf67465a78ac53284ba6f06c3bcb3d
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 21:09:51 2007 +0000
-
- added integer specs. these should be platform independent but other platforms may have some trouble with spec for 'chr' ;)
-
-commit 21463a87bac2121fa61c1c99927cdb039c724d89
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 20:37:37 2007 +0000
-
- implemented the rest of the hash specs, this should cover the documented class, instance methods.
-
-commit 3656a95a1829b0be1a8b0d968e0a9e433ef9c847
-Author: Frederick <frederick@unknown>
-Date: Sat Jan 13 13:14:41 2007 +0000
-
- Implements Fixnum#size
-
-commit ca38e49022f6bdf41b0e98409d3fec3528e59bfd
-Author: Frederick <frederick@unknown>
-Date: Sat Jan 13 12:54:30 2007 +0000
-
- shotgun/string_spec.rb now follow new spec conventions
-
-commit 1b684385fe970f11a526e280d15c3f147a826886
-Author: Frederick <frederick@unknown>
-Date: Sat Jan 13 12:42:38 2007 +0000
-
- language/expression_spec.rb and language/exception_spec.rb now use new spec style
-
-commit f62c2539a1eef27b356e4d809d76c4f9ddecd2a5
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 08:14:12 2007 +0000
-
- new style specs for hash. numerous of these need to be implemented but there should be templates for all the documented class and instance methods.
-
-commit 28083a6e6dc89502d1c76e2a16f0003a589f01e0
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 08:12:37 2007 +0000
-
- one more, bignum.
-
-commit 076aab00b795ff777c5ac11955130f12f69e1377
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 08:07:30 2007 +0000
-
- new style specs for float, fixnum, symbol, string, object, file, module, regexp, range.
-
-commit 0161ab3527e91674eed4eeaad029eee654325155
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 07:39:26 2007 +0000
-
- true, false, nil, enumerable specs are new style.
-
-commit bb11cce41a472606312eb0a62948c4a339f23dd9
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 07:27:05 2007 +0000
-
- converted existing class and comparable specs to new style.
-
-commit 595b83a75044772136b83eaf84402ed73eb79da5
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Jan 13 07:08:14 2007 +0000
-
- ladies and gentlemen, a huge round of applause and gratitude to headius for inspiration and help getting specs in a form that will easily run on MRI, JRuby, and Rubinius. Checking in the modified spec/core/array_spec.rb. The rest to follow. The mri_target is still using the sub-process method, but that should be superfluous now.
-
-commit ae75e76915432757be3c9a7126c2ee8c6656652c
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 12 08:13:29 2007 +0000
-
- added a bunch more specs for array. two still need to be filled out. I think that covers all the documented class and instance methods.
-
-commit 8daf38e0f99eed3e42d654086a98e673d9855bef
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 12 01:14:35 2007 +0000
-
- checking in more of cabo's changes to kernel/core/array.rb and array specs.
-
-commit 0a349583aba629748d5e85de0ede6f38730512f1
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 12 00:57:22 2007 +0000
-
- checking in cabo's changes to array and array spec.
-
-commit 052512fea9b74e532ef6b68612c81061ad84e4f2
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 11 05:16:47 2007 +0000
-
- finished Bignum specs for documented instance methods.
-
-commit 7f4786c85b2e0e95abc2728492ed1a7424d01dbe
-Author: Frederick <frederick@unknown>
-Date: Wed Jan 10 23:44:34 2007 +0000
-
- Added File.mtime, File.atime, File.ctime
- Avoid reusing old .rbc is .rb is newer
- Remove useless CHECK_PTR
-
-commit 70458d6446f0858570571a64b5294c0bb4ac358f
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 10 17:40:36 2007 +0000
-
- moved exception and expression specs to spec/language. added stub for time_spec in spec/library. updated a string spec that was failing. added specs for all (I think) float and fixnum instance methods. added specs for bignum, but about half need examples.
-
-commit ffe4a7a48dcc116f73b89b9a046d4430ed51975a
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 9 18:07:31 2007 +0000
-
- removed duplicate bk task from Rakefile. removed shotgun-tests/test-array.rb as all tests have corresponding specs in spec/core. added beginning of specs for bignum separated into spec/core for stuff that should be indendent of mri or rubinius, and spec/shotgun for implementation specific.
-
-commit 946d0b42293ea081666e71e13c4b77d5b5dba886
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 7 05:38:33 2007 +0000
-
- checking in Alan Hurdles patches to regexp, string, and spec_string.
-
-commit 5f035040c4b3ce842fff4b39d1ca657c97deb7a4
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 7 03:03:31 2007 +0000
-
- updated mri and rubinius target impl specs. added environment option for running rubinius target using obsolete.rcompile, e.g.: COMPILER=rcompile spec spec/core/symbol_spec -f s. If you don't use the COMPILER env var, rubinius target will use shotgun to compile.
-
-commit 6ea911ae5740508cdbd8feb5cddba5b8bf7fe1c3
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Jan 7 02:32:35 2007 +0000
-
- changed some Hash specs to use instance vars rather than local vars because some versions of Ruby2Ruby output borked sexp for block local vars. E.g. use @h rather than h.
-
-commit 256fe9a8cada7ed512556e1701a5264670c6c28f
-Author: Mae <mae@unknown>
-Date: Sat Jan 6 07:55:32 2007 +0000
-
- made regression spec for buggy behavior of [1,2,3][2..-1]
-
-commit 0ffe8a3e6cd92bc5cd872cc22919885ea80366a0
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 5 20:05:03 2007 +0000
-
- added spec for String#reverse! to Laurent Julliard's spec for String#reverse and his implementation of both methods.
-
-commit 170737d2c77a4b2de862380cb87f7705560cca64
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Jan 5 18:24:32 2007 +0000
-
- * Much better implementation of Hash#key?
- * Added working support for default Hash values and procs
- * Added hash_get_undef for situations where nil and undefined hash values need to be differentiated
-
-commit 332378a8900f09009626cb7c4dbf0c8740a657c7
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 5 07:31:56 2007 +0000
-
- added specs for aliases of Hash#key?
-
-commit 27c3b2aeaa3208a7e0218f051f623b93e2e635d8
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 5 07:28:29 2007 +0000
-
- added spec for Hash#key?
-
-commit 2e88d941bc1b1ea506396a915e3c3c4e3dfd1601
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Jan 5 06:35:09 2007 +0000
-
- updated and simplified float and fixnum specs.
-
-commit e4a5b6d8529d60e62875004bb60f33c6452ccf98
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Fri Jan 5 06:28:04 2007 +0000
-
- * defined?() now handles: defined?(Kernel.puts) flavors of arguments.
-
-commit 27660379c09e561590cf1bc48a9459e29fc00e9c
-Author: Mae <mae@unknown>
-Date: Fri Jan 5 06:10:11 2007 +0000
-
- Added spec for cvar declaration in class bodies
-
-commit a9b7b9f7db02ba78514eb869c2c52d4e5067f8d2
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 4 08:08:59 2007 +0000
-
- added class def source code to specs.
-
-commit cdfa499ee238671c655800a81b51611704383500
-Author: Mae <mae@unknown>
-Date: Thu Jan 4 07:54:20 2007 +0000
-
- fixed typo in spec still 7 failing specs *GLARES AT DEFILER*
-
-commit 03be9ca7da61363f8f0a02ee951bbafaf297c31b
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 4 07:43:58 2007 +0000
-
- added specs for Module#const_defined?.
-
-commit c511d4c7a75001f2597b13f9fc2e910d2dd4d9a2
-Author: Mae <mae@unknown>
-Date: Thu Jan 4 06:54:07 2007 +0000
-
- changed defined spec to be more dumb and just figure out whether its a true/false evaluation
-
-commit 4d9135f9694e4b692faf6a4c7b8dcd59f79f5069
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 4 06:38:57 2007 +0000
-
- added library spec (beginning) for enumerator. trivial update for comparable specs. added specs for enumerable.
-
-commit 3de6e339526b1402f8995a5acc38fde707ec0695
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Jan 4 00:34:50 2007 +0000
-
- added specs for comparable methods.
-
-commit ea25c6b17533c280e640dc97e3fec1207fb4be7b
-Author: Mae <mae@unknown>
-Date: Wed Jan 3 17:47:09 2007 +0000
-
- almost done with defined? spec -- still need 'yield' and 'zsuper' test cases
- from project dir: SPEC_TARGET=mri spec spec/language/defined_spec.rb
- change SPEC_TARGET to rubinius to test on rubinius
-
-commit b795f6c2dc98952e7fa7231cded9156ade962b18
-Author: Mae <mae@unknown>
-Date: Wed Jan 3 17:25:31 2007 +0000
-
- added incomplete specs for defined? behavior -- more work to be done
-
-commit 25e30e4668f1ef814bfb1182e032449263651590
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 3 17:17:03 2007 +0000
-
- small fix to mri_target to generate reasonable cache soure name. added a couple specs.
-
-commit 3b5bc977ea2a4a3ad42ff83bcab2966459c262c0
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 3 08:51:18 2007 +0000
-
- added object_spec for methods provided by Object, even mixed in ones. added a few specs for basic class, module, exceptions.
-
-commit c4f4dd722658b2a09ae273092744b76e65ce05b2
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Jan 3 02:36:58 2007 +0000
-
- renamed flow_control_spec to expression_spec as these are all covered under heading expressions in pickaxe. run expression spec with mri target and then rubinius target to see an interesting rubinius failure. updated an incorrect string splice spec.
-
-commit ef8aa2f74896944134f5a8884ccc723ca9b472c1
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Jan 2 01:40:16 2007 +0000
-
- separated specs that are shotgun specific methods (e.g. String#prefix?) into spec/shotgun/... fixed wrong specs so that all pass under mri/mir configuration.
-
-commit 8661488b40b9fccccf356889834c6a9162c8bebf
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 1 22:37:41 2007 +0000
-
- very quick n' dirty implementation of example et al to run specs under mri like under rubinius.
-
-commit 0ebfa43e222ca4794243d36f10c2e429e930f527
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 1 20:47:13 2007 +0000
-
- added methods for TrueClass and FalseClass, updated specs for each.
-
-commit e9bb50ced8bf997535f0bc9c6deeeffb86c40879
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 1 20:29:37 2007 +0000
-
- added specs for true, false, nil.
-
-commit c30b0e38b88c686c11c6f7442e027d685d405505
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 1 18:59:59 2007 +0000
-
- added spec templates for true, false, nil, class, module, enumerable, comparable, flow_control, exception. added specs to various others.
-
-commit b26777261970c213506e444b90412543f39b3c59
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 1 18:58:37 2007 +0000
-
- added that rubinius target example method takes a default argument to pass strings of code to allow for creating classes, since classes can't be defined in a method body and for now example puts the block code into a method using ruby2ruby.
-
-commit 560c5a1331c76bce07289f1e5950b816fe7c9c24
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Jan 1 01:17:44 2007 +0000
-
- added more string specs.
-
-commit 807864c76b701f6f976f3f2935599ba875fcc10e
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Dec 31 23:13:16 2006 +0000
-
- added more core specs (or templates for specs) to cover existing tests in shotgun-tests.
-
-commit 8f83b600b12722d46b9791b2e2c3a399618474a0
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Dec 31 21:23:07 2006 +0000
-
- removed shotgun/primitives_spec as spec/shotgun should be for shotgun-specific code. created spec/core for ruby core classes. spec/library is now for ruby stdlib classes. added more array specs.
-
-commit 58cc3ce5bd8b84a151b1a6e2334845f268ab894a
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Dec 31 08:58:50 2006 +0000
-
- added specs for class methods of Regexp. added alias Regexp.compile for Regexp.new.
-
-commit 0a5a31bc6ef539eeda3de951ab633f5152d58153
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Dec 31 02:01:34 2006 +0000
-
- added specs for symbol methods. added aliases to symbol for to_i, to_int, and id2name.
-
-commit cdfa28e492b8edfa55b950b06ce05ebb04b64643
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 30 17:27:18 2006 +0000
-
- changed example method for rubinius_target to raise exception if compile fails. added specs for range.
-
-commit 5316e652084b8624828d0a9306f580bfc93184dc
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 29 20:37:46 2006 +0000
-
- added spec files in spec/library for basic types (according to pickaxe book). added specs for all the methods in Regexp. there are many failing specs for a variety of reasons, but the goal is to get a good overview of where work needs to be done. more specs to follow.
-
-commit 06cd5ad6da819f2894996e42f4da70321767c9c7
-Author: Mae <mae@unknown>
-Date: Thu Dec 28 07:36:21 2006 +0000
-
- Added Array expressions gleaned from spec/library/array_spec.rb as proof of concept for rapid compatibility testing
- - A thought occurred to me that the scope for this type of testing might be limited severely to simple compatibility testing
- - Its not very human understandable as a spec -- it just unravels incompatibilities given no hint as to why things are the way they are.
- - It lets the ruby rval speak for itself
- - Is this useful for rubinius?!
-
-commit 1c1fc9335aee4acbcd692c555b0ca194c5301013
-Author: Frederick <frederick@unknown>
-Date: Wed Dec 27 22:46:43 2006 +0000
-
- Fix a bug in the allocation of a string. The underlying storage (byte array) did not have the correct size, leading to a write in a non allocated memory area.
- The rationale is that, the storage are should be able to store the string plus a terminal \0. As we're allocating per block of 4 bytes (a word) we need to get the nearest multiple of 4.
- This patch adds a spec to highlight the bug, and a fix to .. well, fix it ;)
-
-commit cdfdc272b71bbfca23b4c17e5572ebd2b966615e
-Author: Mae <mae@unknown>
-Date: Tue Dec 26 17:52:24 2006 +0000
-
- Added my idea of a sanity check against MRI for compatibility purposes
- - try it out!
- - rake spec:compatibility
- - example compatibility expressions go in spec/compatibility/expressions/*
- - all the expression files are line-separated ruby expressions that return something basic and eval-able
-
-commit f9887648c7f239f8c862158b39f44b2410377204
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 22 19:20:58 2006 +0000
-
- added spec file for String methods.
-
-commit 8178e4478977c81940ac4bdcd8bea608be11708b
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 22 17:14:46 2006 +0000
-
- fixed that ruby2ruby was not generating correct ruby source when a local var was used in a block. changed local var to instance var and it works, converted primitives_spec to new block-style.
-
-commit 8a00080a1edb864af7573e8f9761f65fa1202d07
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 22 06:58:28 2006 +0000
-
- changed array_spec to not use local variables in blocks where possible because rubytoruby is not converting them to ruby source correctly. Array#uniq! fails at the moment. re-added that compile checks code-cache first so specs run faster.
-
-commit 4a199c559eebe73cd21d0997126b799f5d4e2be5
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 22 06:00:21 2006 +0000
-
- converted array_spec.rb to block-style specs, but they still depend on strings to be output. rewrote spec_helper based on nicksieger's example code. some specs are failing due to bugs converting to sexp and back to ruby source.
-
-commit 854bbc3617559a2ceac975d79a57ffa825a5cda6
-Author: Brian Ford <brixen@gmail.com>
-Date: Fri Dec 22 03:34:18 2006 +0000
-
- added spec/targets for specs for 'target' part of host/target spec runner configuration. added mri_target and rubinius_target and specs.
-
-commit db81559c9c914413d2064b4202ec8ce43e503af2
-Author: Brian Ford <brixen@gmail.com>
-Date: Thu Dec 21 05:51:55 2006 +0000
-
- added spec:targets task to run specs for target part of host/target spec configuration. added specs for mri_target and rubinius_target.
-
-commit a243a70bd17ec7e9839b69bb18e63d5d943b6095
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 20 19:02:01 2006 +0000
-
- updated primitives_spec to use example method.
-
-commit 9ce077283dd10c21377add499c5bcc4ea87cfe0f
-Author: Brian Ford <brixen@gmail.com>
-Date: Wed Dec 20 17:11:00 2006 +0000
-
- Changed method from rubinius to example for specs. This is in anticipation of having independent 'host' (system running rspec) and 'target' (system executing spec). Created parallel arrayb_spec that illustrates this with a mri/mri configuration. Also added spec_bhelper that is a *very rough* beginning for having mri/rubinius configuration using block-style specs.
-
-commit a8ad71a0da9e1a866521074743ea1dfcceb596cb
-Author: Wilson Bilkovich <wilson@supremetyrant.com>
-Date: Wed Dec 20 15:39:36 2006 +0000
-
- Applying 'array patch' from Jason Perkins (2006-12-20 8:30 EST)
-
-commit 82b3d880131e7080ebc6b4289b3954d89a988c13
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 19 17:30:21 2006 +0000
-
- added more specs to array_spec. most of these are failing, so there seems to be a lot of Array that needs implementing.
-
-commit c24f0e83b4d446afd541ffefbcb313f199b684ee
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 19 08:24:00 2006 +0000
-
- added specs for Array#* and <<, simplified other specs.
-
-commit 62b0737ce69768a8292bd3d9f13401ec8056f6eb
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 19 07:46:39 2006 +0000
-
- fixed messed up spec for &.
-
-commit 7635389b2abf5c492952a49eb8251d6fb34250c7
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 19 07:40:01 2006 +0000
-
- added spec for Array#&, which is currently unimplemented. updated spec_helper.
-
-commit 42b5e9fc47bcf6bcd403d25795c9bcf07bb5c007
-Author: Brian Ford <brixen@gmail.com>
-Date: Tue Dec 19 06:13:15 2006 +0000
-
- added spec tasks :only to run only spec, :language for high level language conformance spcs, :library for ruby stdlib implementation specs, and :shotgun for specs related to shotgun. rake spec will run all specs and tests. removed spec/spec_suite.rb because all specs can be run from rake. minor updates to spec_helper.
-
-commit da4c42890f4b8163b8d49de64bdb76c16b0e5d1f
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 18 17:41:44 2006 +0000
-
- added shotgun dir under spec for things that relate to shotgun implementation of VM, like the prmitives_spec, while reserving spec/library for general ruby implementation of the std lib.
-
-commit 925cbf9f84f78a48189f7030c205942d266a6f66
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 18 09:45:25 2006 +0000
-
- added Fixnum#% primitive implementation. changed array_spec to use Fixnum#%. fixed test_primitive test for Fixnum#%.
-
-commit 06e50e48a92e3fa7d1fc4d6b681872d08e5aeba3
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 18 09:10:37 2006 +0000
-
- Added Fixnum#% primitive test, spec, cpu/primitive, stub.
-
-commit e0fbcf29f46dde89f65d13c1b6d7601a470cf223
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 18 07:54:02 2006 +0000
-
- all ports of test_array test to array_spec are now passing.
-
-commit c2330c2ff65cfa964d954340fb0eb2507972efd5
-Author: Brian Ford <brixen@gmail.com>
-Date: Mon Dec 18 07:39:55 2006 +0000
-
- updated spec_helper to ensure code-cache dir exists. fixed several failing specs in array_spec by correcting expected value.
-
-commit 81cc03c6f7ce499da563543f00d273d3a9c3a184
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Dec 17 06:27:15 2006 +0000
-
- Ported the rest of test_array.rb tests to specs. Several of these specs are not passing but ported them all to illustrate behavior of specs.
-
-commit b4cb073931f403119a5ed9b63a2c915612a9c46f
-Author: Brian Ford <brixen@gmail.com>
-Date: Sun Dec 17 04:42:55 2006 +0000
-
- spec/spec_helper.rb rubinius method is a very naive port of shotgun-tests/helper.rb run_code method. spec/library/array_spec.rb is several ports of the tests in shotgun-tests/test_array.rb, which is testing /kernel/array.rb. In other words, you can now create specs that run under RSpec (which is running under MRI 1.8.x) that exercises the rubinius vm, shotgun, and the stdlib that is being written in ruby. Confused? Read the source, Luke. :)
-
-commit 1b37cd1ee800060fb215a52d2902c3f4b778a656
-Author: Brian Ford <brixen@gmail.com>
-Date: Sat Dec 16 07:55:41 2006 +0000
-
- Added spec dir with spec_suite.rb and spec_helper.rb provided by nullstyle.
diff --git a/spec/ruby/CONTRIBUTING.md b/spec/ruby/CONTRIBUTING.md
index e675a61afa..56e12736fc 100644
--- a/spec/ruby/CONTRIBUTING.md
+++ b/spec/ruby/CONTRIBUTING.md
@@ -8,7 +8,7 @@ Spec are grouped in 5 separate top-level groups:
* `command_line`: for the ruby executable command-line flags (`-v`, `-e`, etc)
* `language`: for the language keywords and syntax constructs (`if`, `def`, `A::B`, etc)
-* `core`: for the core methods (`Fixnum#+`, `String#upcase`, no need to require anything)
+* `core`: for the core methods (`Integer#+`, `String#upcase`, no need to require anything)
* `library`: for the standard libraries methods (`CSV.new`, `YAML.parse`, need to require the stdlib)
* `optional/capi`: for functions available to the Ruby C-extension API
@@ -48,9 +48,167 @@ You might also want to search for:
which indicates the file was generated but the method unspecified.
+### Matchers and expectations
+
+Here is a list of frequently-used matchers, which should be enough for most specs.
+There are a few extra specific matchers used in the couple specs that need it.
+
+#### Comparison matchers
+
+```ruby
+(1 + 2).should == 3 # Calls #==
+(1 + 2).should_not == 5
+
+File.should.equal?(File) # Calls #equal? (tests identity)
+(1 + 2).should.eql?(3) # Calls #eql? (Hash equality)
+
+1.should < 2
+2.should <= 2
+3.should >= 3
+4.should > 3
+
+"Hello".should =~ /l{2}/ # Calls #=~ (Regexp match)
+```
+
+#### Predicate matchers
+
+```ruby
+[].should.empty?
+[1,2,3].should.include?(2)
+
+"hello".should.start_with?("h")
+"hello".should.end_with?("o")
+
+(0.1 + 0.2).should be_close(0.3, TOLERANCE) # (0.2-0.1).abs < TOLERANCE
+(0.0/0.0).should.nan?
+(1.0/0.0).should be_positive_infinity
+(-1.0/0.0).should be_negative_infinity
+
+3.14.should be_an_instance_of(Float) # Calls #instance_of?
+3.14.should be_kind_of(Numeric) # Calls #is_a?
+Numeric.should be_ancestor_of(Float) # Float.ancestors.include?(Numeric)
+
+3.14.should.respond_to?(:to_i)
+Integer.should have_instance_method(:+)
+Array.should have_method(:new)
+```
+
+Also `have_constant`, `have_private_instance_method`, `have_singleton_method`, etc.
+
+#### Exception matchers
+
+```ruby
+-> {
+ raise "oops"
+}.should raise_error(RuntimeError, /oops/)
+
+-> {
+ raise "oops"
+}.should raise_error(RuntimeError) { |e|
+ # Custom checks on the Exception object
+ e.message.should.include?("oops")
+ e.cause.should == nil
+}
+```
+
+##### should_not raise_error
+
+**To avoid!** Instead, use an expectation testing what the code in the lambda does.
+If an exception is raised, it will fail the example anyway.
+
+```ruby
+-> { ... }.should_not raise_error
+```
+
+#### Warning matcher
+
+```ruby
+-> {
+ Integer
+}.should complain(/constant ::Integer is deprecated/) # Expect a warning
+```
+
### Guards
Different guards are available as defined by mspec.
+Here is a list of the most commonly-used guards:
+
+#### Version guards
+
+```ruby
+ruby_version_is ""..."2.6" do
+ # Specs for RUBY_VERSION < 2.6
+end
+
+ruby_version_is "2.6" do
+ # Specs for RUBY_VERSION >= 2.6
+end
+```
+
+#### Platform guards
+
+```ruby
+platform_is :windows do
+ # Specs only valid on Windows
+end
+
+platform_is_not :windows do
+ # Specs valid on platforms other than Windows
+end
+
+platform_is :linux, :darwin do # OR
+end
+
+platform_is_not :linux, :darwin do # Not Linux and not Darwin
+end
+
+platform_is wordsize: 64 do
+ # 64-bit platform
+end
+
+big_endian do
+ # Big-endian platform
+end
+```
+
+#### Guard for bug
+
+In case there is a bug in MRI but the expected behavior is obvious.
+First, file a bug at https://bugs.ruby-lang.org/.
+It is better to use a `ruby_version_is` guard if there was a release with the fix.
+
+```ruby
+ruby_bug '#13669', ''...'2.5' do
+ it "works like this" do
+ # Specify the expected behavior here, not the bug
+ end
+end
+```
+
+#### Combining guards
+
+```ruby
+guard -> { platform_is :windows and ruby_version_is ""..."2.6" } do
+ # Windows and RUBY_VERSION < 2.6
+end
+
+guard_not -> { platform_is :windows and ruby_version_is ""..."2.6" } do
+ # The opposite
+end
+```
+
+#### Custom guard
+
+```ruby
+max_uint = (1 << 32) - 1
+guard -> { max_uint <= fixnum_max } do
+end
+```
+
+Custom guards are better than a simple `if` as they allow [mspec commands](https://github.com/ruby/mspec/issues/30#issuecomment-312487779) to work properly.
+
+#### Implementation-specific behaviors
+
In general, the usage of guards should be minimized as possible.
There are no guards to define implementation-specific behavior because
@@ -59,6 +217,76 @@ Use the implementation test suite for these.
If an implementation does not support some feature, simply tag the related specs as failing instead.
+### Shared Specs
+
+Often throughout Ruby, identical functionality is used by different methods and modules. In order
+to avoid duplication of specs, we have shared specs that are re-used in other specs. The use is a
+bit tricky however, so let's go over it.
+
+Commonly, if a shared spec is only reused within its own module, the shared spec will live within a
+shared directory inside that module's directory. For example, the `core/hash/shared/key.rb` spec is
+only used by `Hash` specs, and so it lives inside `core/hash/shared/`.
+
+When a shared spec is used across multiple modules or classes, it lives within the `shared/` directory.
+An example of this is the `shared/file/socket.rb` which is used by `core/file/socket_spec.rb`,
+`core/filetest/socket_spec.rb`, and `core/file/state/socket_spec.rb` and so it lives in the root `shared/`.
+
+Defining a shared spec involves adding a `shared: true` option to the top-level `describe` block. This
+will signal not to run the specs directly by the runner. Shared specs have access to two instance
+variables from the implementor spec: `@method` and `@object`, which the implementor spec will pass in.
+
+Here's an example of a snippet of a shared spec and two specs which integrates it:
+
+```ruby
+# core/hash/shared/key.rb
+describe :hash_key_p, shared: true do
+ it "returns true if the key's matching value was false" do
+ { xyz: false }.send(@method, :xyz).should == true
+ end
+end
+
+# core/hash/key_spec.rb
+describe "Hash#key?" do
+ it_behaves_like :hash_key_p, :key?
+end
+
+# core/hash/include_spec.rb
+describe "Hash#include?" do
+ it_behaves_like :hash_key_p, :include?
+end
+```
+
+In the example, the first `describe` defines the shared spec `:hash_key_p`, which defines a spec that
+calls the `@method` method with an expectation. In the implementor spec, we use `it_behaves_like` to
+integrate the shared spec. `it_behaves_like` takes 3 parameters: the key of the shared spec, a method,
+and an object. These last two parameters are accessible via `@method` and `@object` in the shared spec.
+
+Sometimes, shared specs require more context from the implementor class than a simple object. We can address
+this by passing a lambda as the method, which will have the scope of the implementor. Here's an example of
+how this is used currently:
+
+```ruby
+describe :kernel_sprintf, shared: true do
+ it "raises TypeError exception if cannot convert to Integer" do
+ -> { @method.call("%b", Object.new) }.should raise_error(TypeError)
+ end
+end
+
+describe "Kernel#sprintf" do
+ it_behaves_like :kernel_sprintf, -> (format, *args) {
+ sprintf(format, *args)
+ }
+end
+
+describe "Kernel.sprintf" do
+ it_behaves_like :kernel_sprintf, -> (format, *args) {
+ Kernel.sprintf(format, *args)
+ }
+end
+```
+
+In the above example, the method being passed is a lambda that triggers the specific conditions of the shared spec.
+
### Style
-Do not leave any trailing space and respect the existing style.
+Do not leave any trailing space and follow the existing style.
diff --git a/spec/ruby/README.md b/spec/ruby/README.md
index 970688a623..932cd83061 100644
--- a/spec/ruby/README.md
+++ b/spec/ruby/README.md
@@ -1,9 +1,11 @@
# The Ruby Spec Suite
-[![Build Status](https://travis-ci.org/ruby/spec.svg)](https://travis-ci.org/ruby/spec)
-[![Build Status](https://ci.appveyor.com/api/projects/status/1gs6f399320o44b1?svg=true)](https://ci.appveyor.com/project/eregon/spec-x948i)
+[![Actions Build Status](https://github.com/ruby/spec/workflows/CI/badge.svg)](https://github.com/ruby/spec/actions)
+[![Gitter](https://badges.gitter.im/ruby/spec.svg)](https://gitter.im/ruby/spec)
-The Ruby Spec Suite is a test suite for the behavior of the Ruby programming language.
+The Ruby Spec Suite, abbreviated `ruby/spec`, is a test suite for the behavior of the Ruby programming language.
+
+### Description and Motivation
It is not a standardized specification like the ISO one, and does not aim to become one.
Instead, it is a practical tool to describe and test the behavior of Ruby with code.
@@ -23,17 +25,37 @@ The language specs are grouped by keyword while the core and standard library sp
ruby/spec is known to be tested in these implementations for every commit:
* [MRI](http://rubyci.org/) on 30 platforms and 4 versions
-* [JRuby](https://github.com/jruby/jruby/tree/master/spec/ruby) on Travis for both 1.7 and 9.x
-* [TruffleRuby](https://github.com/graalvm/truffleruby) on Travis
-* [Opal](https://github.com/opal/opal/tree/master/spec) on Travis
+* [JRuby](https://github.com/jruby/jruby/tree/master/spec/ruby) for both 1.7 and 9.x
+* [TruffleRuby](https://github.com/oracle/truffleruby/tree/master/spec/ruby)
+* [Opal](https://github.com/opal/opal/tree/master/spec)
+
+ruby/spec describes the behavior of Ruby 2.5 and more recent Ruby versions.
+More precisely, every latest stable MRI release should [pass](https://travis-ci.org/ruby/spec) all specs of ruby/spec (2.5.x, 2.6.x, 2.7.x, etc), and those are tested in TravisCI.
+
+### Synchronization with Ruby Implementations
+
+The specs are synchronized both ways around once a month by @eregon between ruby/spec, MRI, JRuby and TruffleRuby.
+Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs.
+Any of these repositories can be used to add or edit specs, use what is most convenient for you.
+
+For *testing* the development version of a Ruby implementation, one should always test against that implementation's copy of the specs under `spec/ruby`, as that's what the Ruby implementation tests against in their CI.
+Also, this repository doesn't always contain the latest spec changes from MRI (it's synchronized monthly), and does not contain tags (specs marked as failing on that Ruby implementation).
+Running specs on a Ruby implementation can be done with:
-ruby/spec describes the behavior of Ruby 2.2 and more recent Ruby versions.
-More precisely, every latest stable MRI release [passes](https://rubyci.org/) all specs of ruby/spec
-(latest 2.2.x, 2.3.x, 2.4.x, etc).
+```
+$ cd ruby_implementation/spec/ruby
+# Add ../ruby_implementation/bin in PATH, or pass -t /path/to/bin/ruby
+$ ../mspec/bin/mspec
+```
+
+### Specs for old Ruby versions
For older specs try these commits:
* Ruby 2.0.0-p647 - [Suite](https://github.com/ruby/spec/commit/245862558761d5abc676843ef74f86c9bcc8ea8d) using [MSpec](https://github.com/ruby/mspec/commit/f90efa068791064f955de7a843e96e2d7d3041c2) (may encounter 2 failures)
* Ruby 2.1.9 - [Suite](https://github.com/ruby/spec/commit/f029e65241374386077ac500add557ae65069b55) using [MSpec](https://github.com/ruby/mspec/commit/55568ea3918c6380e64db8c567d732fa5781efed)
+* Ruby 2.2.10 - [Suite](https://github.com/ruby/spec/commit/cbaa0e412270c944df0c2532fc500c920dba0e92) using [MSpec](https://github.com/ruby/mspec/commit/d84d7668449e96856c5f6bac8cb1526b6d357ce3)
+* Ruby 2.3.8 - [Suite](https://github.com/ruby/spec/commit/dc733114d8ae66a3368ba3a98422c50147a76ba5) using [MSpec](https://github.com/ruby/mspec/commit/4599bc195fb109f2a482a01c32a7d659518369ea)
+* Ruby 2.4.10 - [Suite](https://github.com/ruby/spec/commit/bce4f2b81d6c31db67cf4d023a0625ceadde59bd) using [MSpec](https://github.com/ruby/mspec/commit/e7eb8aa4c26495b7b461e687d950b96eb08b3ff2)
### Running the specs
@@ -58,7 +80,7 @@ This will execute all the specs using the executable named `ruby` on your curren
### Running Specs with a Specific Ruby Implementation
Use the `-t` option to specify the Ruby implementation with which to run the specs.
-The argument may be a full path to the Ruby binary.
+The argument is either a full path to the Ruby binary, or an executable in `$PATH`.
$ ../mspec/bin/mspec -t /path/to/some/bin/ruby
@@ -83,13 +105,48 @@ In similar fashion, the following commands run the respective specs:
$ ../mspec/bin/mspec :library
$ ../mspec/bin/mspec :capi
-### Contributing
+### Sanity Checks When Running Specs
+
+A number of checks for various kind of "leaks" (file descriptors, temporary files,
+threads, subprocesses, `ENV`, `ARGV`, global encodings, top-level constants) can be
+enabled with `CHECK_LEAKS=true`:
+
+ $ CHECK_LEAKS=true ../mspec/bin/mspec
+
+New top-level constants should only be introduced when needed or follow the
+pattern `<ClassBeingTested>Specs` such as `module StringSpecs`.
+Other constants used for testing should be nested under such a module.
+
+Exceptions to these rules are contained in the file `.mspec.constants`.
+MSpec can automatically add new top-level constants in this file with:
+
+ $ CHECK_LEAKS=save mspec ../mspec/bin/mspec file
+
+### Contributing and Writing Specs
+
+See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md) for documentation about contributing and writing specs (guards, matchers, etc).
+
+### Dependencies
+
+These command-line executables are needed to run the specs.
+
+* `echo`
+* `stat` for `core/file/*time_spec.rb`
+* `find` for `core/file/fixtures/file_types.rb` (package `findutils`, not needed on Windows)
+
+The file `/etc/services` is required for socket specs (package `netbase` on Debian, not needed on Windows).
+
+### Socket specs from rubysl-socket
-See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md).
+Most specs under `library/socket` were imported from [the rubysl-socket project](https://github.com/rubysl/rubysl-socket).
+The 3 copyright holders of rubysl-socket, Yorick Peterse, Chuck Remes and
+Brian Shirai, [agreed to relicense those specs](https://github.com/rubysl/rubysl-socket/issues/15)
+under the MIT license in ruby/spec.
### History and RubySpec
This project was originally born from [Rubinius](https://github.com/rubinius/rubinius) tests being converted to the spec style.
+The revision history of these specs is available [here](https://github.com/ruby/spec/blob/2b886623/CHANGES.before-2008-05-10).
These specs were later extracted to their own project, RubySpec, with a specific vision and principles.
At the end of 2014, Brian Shirai, the creator of RubySpec, decided to [end RubySpec](http://rubinius.com/2014/12/31/matz-s-ruby-developers-don-t-use-rubyspec/).
A couple months later, the different repositories were merged and [the project was revived](http://eregon.github.io/rubyspec/2015/07/29/rubyspec-is-reborn.html).
diff --git a/spec/ruby/appveyor.yml b/spec/ruby/appveyor.yml
deleted file mode 100644
index 8ee5abd8b4..0000000000
--- a/spec/ruby/appveyor.yml
+++ /dev/null
@@ -1,30 +0,0 @@
----
-version: "{build}"
-clone_depth: 5
-init:
- # To avoid duplicated executables in PATH, see https://github.com/ruby/spec/pull/468
- - set PATH=C:\ruby%RUBY_VERSION%\bin;C:\Program Files\7-Zip;C:\Program Files\AppVeyor\BuildAgent;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Program Files;C:\Windows
- # Loads trunk build and updates MSYS2 / MinGW to most recent gcc compiler
- - if %ruby_version%==_trunk (
- appveyor DownloadFile https://ci.appveyor.com/api/projects/MSP-Greg/ruby-loco/artifacts/ruby_trunk.7z -FileName C:\ruby_trunk.7z &
- 7z x C:\ruby_trunk.7z -oC:\ruby_trunk & C:\ruby_trunk\trunk_msys2.cmd)
-environment:
- matrix:
- - RUBY_VERSION: 23-x64
- - RUBY_VERSION: 24-x64
- - RUBY_VERSION: _trunk # So the folder name is ruby_trunk
-install:
- - git clone https://github.com/ruby/mspec.git ../mspec
-build: off
-test_script:
- - SET CHECK_LEAKS=true
- - ../mspec/bin/mspec -rdevkit -ff
-on_finish:
- - ruby -v
-matrix:
- allow_failures:
- - ruby_version: _trunk
-branches:
- only:
- - master
- - /^try/
diff --git a/spec/ruby/command_line/dash_a_spec.rb b/spec/ruby/command_line/dash_a_spec.rb
index 65f79ec208..9ea135dc76 100644
--- a/spec/ruby/command_line/dash_a_spec.rb
+++ b/spec/ruby/command_line/dash_a_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../spec_helper'
+
describe "The -a command line option" do
before :each do
@names = fixture __FILE__, "full_names.txt"
diff --git a/spec/ruby/command_line/dash_c_spec.rb b/spec/ruby/command_line/dash_c_spec.rb
index 375d945a07..6b3a5de685 100644
--- a/spec/ruby/command_line/dash_c_spec.rb
+++ b/spec/ruby/command_line/dash_c_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The -c command line option" do
it "checks syntax in given file" do
diff --git a/spec/ruby/command_line/dash_d_spec.rb b/spec/ruby/command_line/dash_d_spec.rb
index 009a14e16c..26891b4791 100644
--- a/spec/ruby/command_line/dash_d_spec.rb
+++ b/spec/ruby/command_line/dash_d_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The -d command line option" do
before :each do
diff --git a/spec/ruby/command_line/dash_e_spec.rb b/spec/ruby/command_line/dash_e_spec.rb
index 3435e78e29..24ed34376d 100644
--- a/spec/ruby/command_line/dash_e_spec.rb
+++ b/spec/ruby/command_line/dash_e_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The -e command line option" do
it "evaluates the given string" do
@@ -23,7 +23,7 @@ describe "The -e command line option" do
#needs to test return => LocalJumpError
- describe "with -n and a Fixnum range" do
+ describe "with -n and an Integer range" do
before :each do
@script = "-ne 'print if %s' #{fixture(__FILE__, "conditional_range.txt")}"
end
diff --git a/spec/ruby/command_line/dash_encoding_spec.rb b/spec/ruby/command_line/dash_encoding_spec.rb
new file mode 100644
index 0000000000..36ce55af5f
--- /dev/null
+++ b/spec/ruby/command_line/dash_encoding_spec.rb
@@ -0,0 +1,30 @@
+require_relative '../spec_helper'
+
+describe "The --encoding command line option" do
+ before :each do
+ @test_string = "print [Encoding.default_external.name, Encoding.default_internal&.name].inspect"
+ @enc2 = Encoding::ISO_8859_1
+ end
+
+ describe "sets Encoding.default_external and optionally Encoding.default_internal" do
+ it "if given a single encoding with an =" do
+ ruby_exe(@test_string, options: "--disable-gems --encoding=big5").should == [Encoding::Big5.name, nil].inspect
+ end
+
+ it "if given a single encoding as a separate argument" do
+ ruby_exe(@test_string, options: "--disable-gems --encoding big5").should == [Encoding::Big5.name, nil].inspect
+ end
+
+ it "if given two encodings with an =" do
+ ruby_exe(@test_string, options: "--disable-gems --encoding=big5:#{@enc2}").should == [Encoding::Big5.name, @enc2.name].inspect
+ end
+
+ it "if given two encodings as a separate argument" do
+ ruby_exe(@test_string, options: "--disable-gems --encoding big5:#{@enc2}").should == [Encoding::Big5.name, @enc2.name].inspect
+ end
+ end
+
+ it "does not accept a third encoding" do
+ ruby_exe(@test_string, options: "--disable-gems --encoding big5:#{@enc2}:utf-32le", args: "2>&1").should =~ /extra argument for --encoding: utf-32le/
+ end
+end
diff --git a/spec/ruby/command_line/dash_external_encoding_spec.rb b/spec/ruby/command_line/dash_external_encoding_spec.rb
new file mode 100644
index 0000000000..f052674dc8
--- /dev/null
+++ b/spec/ruby/command_line/dash_external_encoding_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../spec_helper'
+
+describe 'The --external-encoding command line option sets Encoding.default_external' do
+ before :each do
+ @test_string = "print Encoding.default_external.name"
+ end
+
+ it "if given an encoding with an =" do
+ ruby_exe(@test_string, options: '--external-encoding=big5').should == Encoding::Big5.name
+ end
+
+ it "if given an encoding as a separate argument" do
+ ruby_exe(@test_string, options: '--external-encoding big5').should == Encoding::Big5.name
+ end
+end
diff --git a/spec/ruby/command_line/dash_internal_encoding_spec.rb b/spec/ruby/command_line/dash_internal_encoding_spec.rb
new file mode 100644
index 0000000000..3049040bb4
--- /dev/null
+++ b/spec/ruby/command_line/dash_internal_encoding_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../spec_helper'
+
+describe 'The --internal-encoding command line option sets Encoding.default_internal' do
+ before :each do
+ @test_string = "print Encoding.default_internal.name"
+ end
+
+ it "if given an encoding with an =" do
+ ruby_exe(@test_string, options: '--internal-encoding=big5').should == Encoding::Big5.name
+ end
+
+ it "if given an encoding as a separate argument" do
+ ruby_exe(@test_string, options: '--internal-encoding big5').should == Encoding::Big5.name
+ end
+end
diff --git a/spec/ruby/command_line/dash_l_spec.rb b/spec/ruby/command_line/dash_l_spec.rb
new file mode 100644
index 0000000000..5c1d3cf4cd
--- /dev/null
+++ b/spec/ruby/command_line/dash_l_spec.rb
@@ -0,0 +1,31 @@
+require_relative '../spec_helper'
+
+describe "The -l command line option" do
+ before :each do
+ @names = fixture __FILE__, "full_names.txt"
+ end
+
+ it "chomps lines with default separator" do
+ ruby_exe('puts $_.end_with?("\n")', options: "-n -l", escape: true,
+ args: " < #{@names}").should ==
+ "false\nfalse\nfalse\n"
+ end
+
+ it "chomps last line based on $/" do
+ ruby_exe('BEGIN { $/ = "ones\n" }; puts $_', options: "-W0 -n -l", escape: true,
+ args: " < #{@names}").should ==
+ "alice j\nbob field\njames grey\n"
+ end
+
+ it "sets $\\ to the value of $/" do
+ ruby_exe("puts $\\ == $/", options: "-W0 -n -l", escape: true,
+ args: " < #{@names}").should ==
+ "true\ntrue\ntrue\n"
+ end
+
+ it "sets $-l" do
+ ruby_exe("puts $-l", options: "-n -l", escape: true,
+ args: " < #{@names}").should ==
+ "true\ntrue\ntrue\n"
+ end
+end
diff --git a/spec/ruby/command_line/dash_n_spec.rb b/spec/ruby/command_line/dash_n_spec.rb
index f4dd9f1851..9d331d6065 100644
--- a/spec/ruby/command_line/dash_n_spec.rb
+++ b/spec/ruby/command_line/dash_n_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../spec_helper'
+
describe "The -n command line option" do
before :each do
@names = fixture __FILE__, "names.txt"
diff --git a/spec/ruby/command_line/dash_p_spec.rb b/spec/ruby/command_line/dash_p_spec.rb
index 67562b5bc3..39827c3868 100644
--- a/spec/ruby/command_line/dash_p_spec.rb
+++ b/spec/ruby/command_line/dash_p_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../spec_helper'
+
describe "The -p command line option" do
before :each do
@names = fixture __FILE__, "names.txt"
diff --git a/spec/ruby/command_line/dash_r_spec.rb b/spec/ruby/command_line/dash_r_spec.rb
index 3d3abcf0b7..46c000b9e7 100644
--- a/spec/ruby/command_line/dash_r_spec.rb
+++ b/spec/ruby/command_line/dash_r_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The -r command line option" do
before :each do
@@ -7,7 +7,22 @@ describe "The -r command line option" do
end
it "requires the specified file" do
- result = ruby_exe(@script, options: "-r #{@test_file}")
- result.should include(@test_file + ".rb")
+ out = ruby_exe(@script, options: "-r #{@test_file}")
+ out.should include("REQUIRED")
+ out.should include(@test_file + ".rb")
+ end
+
+ it "requires the file before parsing the main script" do
+ out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), options: "-r #{@test_file}", args: "2>&1")
+ $?.should_not.success?
+ out.should include("REQUIRED")
+ out.should include("syntax error")
+ end
+
+ it "does not require the file if the main script file does not exist" do
+ out = `#{ruby_exe.to_a.join(' ')} -r #{@test_file} #{fixture(__FILE__, "does_not_exist.rb")} 2>&1`
+ $?.should_not.success?
+ out.should_not.include?("REQUIRED")
+ out.should.include?("No such file or directory")
end
end
diff --git a/spec/ruby/command_line/dash_s_spec.rb b/spec/ruby/command_line/dash_s_spec.rb
index 70e41208e0..eaaeea7c96 100644
--- a/spec/ruby/command_line/dash_s_spec.rb
+++ b/spec/ruby/command_line/dash_s_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The -s command line option" do
describe "when using -- to stop parsing" do
diff --git a/spec/ruby/command_line/dash_upper_c_spec.rb b/spec/ruby/command_line/dash_upper_c_spec.rb
index e8a54b01c1..ece1b32105 100644
--- a/spec/ruby/command_line/dash_upper_c_spec.rb
+++ b/spec/ruby/command_line/dash_upper_c_spec.rb
@@ -1,18 +1,6 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
+require_relative 'shared/change_directory'
-describe 'The -C command line option' do
- before :all do
- @script = fixture(__FILE__, 'dash_upper_c_script.rb')
- @tempdir = File.dirname(@script)
- end
-
- it 'changes the PWD when using a file' do
- output = ruby_exe(@script, options: "-C #{@tempdir}")
- output.should == @tempdir
- end
-
- it 'changes the PWD when using -e' do
- output = ruby_exe(nil, options: "-C #{@tempdir} -e 'print Dir.pwd'")
- output.should == @tempdir
- end
+describe "The -C command line option" do
+ it_behaves_like :command_line_change_directory, "-C"
end
diff --git a/spec/ruby/command_line/dash_upper_e_spec.rb b/spec/ruby/command_line/dash_upper_e_spec.rb
index 716f1304b7..b3c6ce262b 100644
--- a/spec/ruby/command_line/dash_upper_e_spec.rb
+++ b/spec/ruby/command_line/dash_upper_e_spec.rb
@@ -1,4 +1,33 @@
+require_relative '../spec_helper'
+
describe "ruby -E" do
+ it "sets the external encoding with '-E external'" do
+ result = ruby_exe("print Encoding.default_external", options: '-E euc-jp')
+ result.should == "EUC-JP"
+ end
+
+ platform_is_not :windows do
+ it "also sets the filesystem encoding with '-E external'" do
+ result = ruby_exe("print Encoding.find('filesystem')", options: '-E euc-jp')
+ result.should == "EUC-JP"
+ end
+ end
+
+ it "sets the external encoding with '-E external:'" do
+ result = ruby_exe("print Encoding.default_external", options: '-E Shift_JIS:')
+ result.should == "Shift_JIS"
+ end
+
+ it "sets the internal encoding with '-E :internal'" do
+ ruby_exe("print Encoding.default_internal", options: '-E :SHIFT_JIS').
+ should == 'Shift_JIS'
+ end
+
+ it "sets the external and internal encodings with '-E external:internal'" do
+ ruby_exe("puts Encoding.default_external, Encoding.default_internal", options: '-E euc-jp:SHIFT_JIS').
+ should == "EUC-JP\nShift_JIS\n"
+ end
+
it "raises a RuntimeError if used with -U" do
ruby_exe("p 1",
options: '-Eascii:ascii -U',
diff --git a/spec/ruby/command_line/dash_upper_f_spec.rb b/spec/ruby/command_line/dash_upper_f_spec.rb
index 020968b1f9..967acc2ece 100644
--- a/spec/ruby/command_line/dash_upper_f_spec.rb
+++ b/spec/ruby/command_line/dash_upper_f_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../spec_helper'
+
describe "the -F command line option" do
before :each do
@passwd = fixture __FILE__, "passwd_file.txt"
diff --git a/spec/ruby/command_line/dash_upper_i_spec.rb b/spec/ruby/command_line/dash_upper_i_spec.rb
index 0a00059949..4cafb724e3 100644
--- a/spec/ruby/command_line/dash_upper_i_spec.rb
+++ b/spec/ruby/command_line/dash_upper_i_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The -I command line option" do
before :each do
@@ -8,4 +8,44 @@ describe "The -I command line option" do
it "adds the path to the load path ($:)" do
ruby_exe(@script, options: "-I fixtures").should include("fixtures")
end
+
+ it "adds the path at the front of $LOAD_PATH" do
+ lines = ruby_exe(@script, options: "-I fixtures").lines
+ if PlatformGuard.implementation? :ruby
+ # In a MRI checkout, $PWD ends up as the first entry in $LOAD_PATH.
+ # So just assert that it's at the beginning.
+ idx = lines.index { |l| l.include?("fixtures") }
+ idx.should < 2
+ idx.should < lines.size-1
+ else
+ lines[0].should include("fixtures")
+ end
+ end
+
+ it "adds the path expanded from CWD to $LOAD_PATH" do
+ ruby_exe(@script, options: "-I fixtures").lines.should include "#{Dir.pwd}/fixtures\n"
+ end
+
+ it "expands a path from CWD even if it does not exist" do
+ ruby_exe(@script, options: "-I not_exist/not_exist").lines.should include "#{Dir.pwd}/not_exist/not_exist\n"
+ end
+end
+
+platform_is_not :windows do
+ describe "The -I command line option" do
+ before :each do
+ @script = fixture __FILE__, "loadpath.rb"
+ @fixtures = File.dirname(@script)
+ @symlink = tmp("loadpath_symlink")
+ File.symlink(@fixtures, @symlink)
+ end
+
+ after :each do
+ rm_r @symlink
+ end
+
+ it "does not expand symlinks" do
+ ruby_exe(@script, options: "-I #{@symlink}").lines.should include "#{@symlink}\n"
+ end
+ end
end
diff --git a/spec/ruby/command_line/dash_upper_k_spec.rb b/spec/ruby/command_line/dash_upper_k_spec.rb
index 3c3b9fa4d3..7e71532295 100644
--- a/spec/ruby/command_line/dash_upper_k_spec.rb
+++ b/spec/ruby/command_line/dash_upper_k_spec.rb
@@ -1,33 +1,65 @@
-describe 'The -K command line option sets __ENCODING__' do
- it "to Encoding::ASCII_8BIT with -Ka" do
- ruby_exe("print __ENCODING__", options: '-Ka').should == Encoding::ASCII_8BIT.to_s
- end
+require_relative '../spec_helper'
- it "to Encoding::ASCII_8BIT with -KA" do
- ruby_exe("print __ENCODING__", options: '-KA').should == Encoding::ASCII_8BIT.to_s
+describe 'The -K command line option' do
+ before :each do
+ @test_string = "print [__ENCODING__&.name, Encoding.default_external&.name, Encoding.default_internal&.name].inspect"
end
- it "to Encoding::EUC_JP with -Ke" do
- ruby_exe("print __ENCODING__", options: '-Ke').should == Encoding::EUC_JP.to_s
- end
+ describe 'sets __ENCODING__ and Encoding.default_external' do
+ it "to Encoding::BINARY with -Ka" do
+ ruby_exe(@test_string, options: '-Ka').should ==
+ [Encoding::BINARY.name, Encoding::BINARY.name, nil].inspect
+ end
- it "to Encoding::EUC_JP with -KE" do
- ruby_exe("print __ENCODING__", options: '-KE').should == Encoding::EUC_JP.to_s
- end
+ it "to Encoding::BINARY with -KA" do
+ ruby_exe(@test_string, options: '-KA').should ==
+ [Encoding::BINARY.name, Encoding::BINARY.name, nil].inspect
+ end
- it "to Encoding::UTF_8 with -Ku" do
- ruby_exe("print __ENCODING__", options: '-Ku').should == Encoding::UTF_8.to_s
- end
+ it "to Encoding::BINARY with -Kn" do
+ ruby_exe(@test_string, options: '-Kn').should ==
+ [Encoding::BINARY.name, Encoding::BINARY.name, nil].inspect
+ end
- it "to Encoding::UTF_8 with -KU" do
- ruby_exe("print __ENCODING__", options: '-KU').should == Encoding::UTF_8.to_s
- end
+ it "to Encoding::BINARY with -KN" do
+ ruby_exe(@test_string, options: '-KN').should ==
+ [Encoding::BINARY.name, Encoding::BINARY.name, nil].inspect
+ end
+
+ it "to Encoding::EUC_JP with -Ke" do
+ ruby_exe(@test_string, options: '-Ke').should ==
+ [Encoding::EUC_JP.name, Encoding::EUC_JP.name, nil].inspect
+ end
+
+ it "to Encoding::EUC_JP with -KE" do
+ ruby_exe(@test_string, options: '-KE').should ==
+ [Encoding::EUC_JP.name, Encoding::EUC_JP.name, nil].inspect
+ end
+
+ it "to Encoding::UTF_8 with -Ku" do
+ ruby_exe(@test_string, options: '-Ku').should ==
+ [Encoding::UTF_8.name, Encoding::UTF_8.name, nil].inspect
+ end
+
+ it "to Encoding::UTF_8 with -KU" do
+ ruby_exe(@test_string, options: '-KU').should ==
+ [Encoding::UTF_8.name, Encoding::UTF_8.name, nil].inspect
+ end
+
+ it "to Encoding::Windows_31J with -Ks" do
+ ruby_exe(@test_string, options: '-Ks').should ==
+ [Encoding::Windows_31J.name, Encoding::Windows_31J.name, nil].inspect
+ end
- it "to Encoding::Windows_31J with -Ks" do
- ruby_exe("print __ENCODING__", options: '-Ks').should == Encoding::Windows_31J.to_s
+ it "to Encoding::Windows_31J with -KS" do
+ ruby_exe(@test_string, options: '-KS').should ==
+ [Encoding::Windows_31J.name, Encoding::Windows_31J.name, nil].inspect
+ end
end
- it "to Encoding::Windows_31J with -KS" do
- ruby_exe("print __ENCODING__", options: '-KS').should == Encoding::Windows_31J.to_s
+ it "ignores unknown codes" do
+ external = Encoding.find('external')
+ ruby_exe(@test_string, options: '-KZ').should ==
+ [Encoding::UTF_8.name, external.name, nil].inspect
end
end
diff --git a/spec/ruby/command_line/dash_upper_s_spec.rb b/spec/ruby/command_line/dash_upper_s_spec.rb
index 2e293e9a62..3a28fa2ad2 100644
--- a/spec/ruby/command_line/dash_upper_s_spec.rb
+++ b/spec/ruby/command_line/dash_upper_s_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe 'The -S command line option' do
before :each do
diff --git a/spec/ruby/command_line/dash_upper_u_spec.rb b/spec/ruby/command_line/dash_upper_u_spec.rb
index 6cd52a3647..2546b5b9f4 100644
--- a/spec/ruby/command_line/dash_upper_u_spec.rb
+++ b/spec/ruby/command_line/dash_upper_u_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../spec_helper'
+
describe "ruby -U" do
it "sets Encoding.default_internal to UTF-8" do
ruby_exe('print Encoding.default_internal.name',
diff --git a/spec/ruby/command_line/dash_upper_w_spec.rb b/spec/ruby/command_line/dash_upper_w_spec.rb
index 4e517a422a..b705638606 100644
--- a/spec/ruby/command_line/dash_upper_w_spec.rb
+++ b/spec/ruby/command_line/dash_upper_w_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../spec_helper', __FILE__)
-require File.expand_path('../shared/verbose', __FILE__)
+require_relative '../spec_helper'
+require_relative 'shared/verbose'
describe "The -W command line option" do
before :each do
@@ -18,3 +18,35 @@ end
describe "The -W command line option with 2" do
it_behaves_like :command_line_verbose, "-W2"
end
+
+ruby_version_is "2.7" do
+ describe "The -W command line option with :no-deprecated" do
+ it "suppresses deprecation warnings" do
+ result = ruby_exe('$; = ""', options: '-w', args: '2>&1')
+ result.should =~ /is deprecated/
+
+ result = ruby_exe('$; = ""', options: '-w -W:no-deprecated', args: '2>&1')
+ result.should == ""
+ end
+ end
+
+ describe "The -W command line option with :no-experimental" do
+ before do
+ ruby_version_is ""..."3.0" do
+ @src = 'case [0, 1]; in [a, b]; end'
+ end
+
+ ruby_version_is "3.0" do
+ @src = '[0, 1] => [a, b]'
+ end
+ end
+
+ it "suppresses experimental warnings" do
+ result = ruby_exe(@src, args: '2>&1')
+ result.should =~ /is experimental/
+
+ result = ruby_exe(@src, options: '-W:no-experimental', args: '2>&1')
+ result.should == ""
+ end
+ end
+end
diff --git a/spec/ruby/command_line/dash_upper_x_spec.rb b/spec/ruby/command_line/dash_upper_x_spec.rb
new file mode 100644
index 0000000000..8ef9aae4b1
--- /dev/null
+++ b/spec/ruby/command_line/dash_upper_x_spec.rb
@@ -0,0 +1,6 @@
+require_relative '../spec_helper'
+require_relative 'shared/change_directory'
+
+describe "The -X command line option" do
+ it_behaves_like :command_line_change_directory, "-X"
+end
diff --git a/spec/ruby/command_line/dash_v_spec.rb b/spec/ruby/command_line/dash_v_spec.rb
index 2ee9099419..04d684fdad 100644
--- a/spec/ruby/command_line/dash_v_spec.rb
+++ b/spec/ruby/command_line/dash_v_spec.rb
@@ -1,12 +1,12 @@
-require File.expand_path('../../spec_helper', __FILE__)
-require File.expand_path('../shared/verbose', __FILE__)
+require_relative '../spec_helper'
+require_relative 'shared/verbose'
describe "The -v command line option" do
it_behaves_like :command_line_verbose, "-v"
describe "when used alone" do
it "prints version and ends" do
- ruby_exe(nil, args: '-v').include?(RUBY_DESCRIPTION).should == true
+ ruby_exe(nil, args: '-v').should include(RUBY_DESCRIPTION)
end
end
end
diff --git a/spec/ruby/command_line/dash_w_spec.rb b/spec/ruby/command_line/dash_w_spec.rb
index bb038cb10c..1d93e0347b 100644
--- a/spec/ruby/command_line/dash_w_spec.rb
+++ b/spec/ruby/command_line/dash_w_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../spec_helper', __FILE__)
-require File.expand_path('../shared/verbose', __FILE__)
+require_relative '../spec_helper'
+require_relative 'shared/verbose'
describe "The -w command line option" do
it_behaves_like :command_line_verbose, "-w"
diff --git a/spec/ruby/command_line/dash_x_spec.rb b/spec/ruby/command_line/dash_x_spec.rb
index a5306b4f75..eb89db0144 100644
--- a/spec/ruby/command_line/dash_x_spec.rb
+++ b/spec/ruby/command_line/dash_x_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../spec_helper'
+
describe "The -x command line option" do
it "runs code after the first /\#!.*ruby.*/-ish line in target file" do
embedded_ruby = fixture __FILE__, "bin/embedded_ruby.txt"
@@ -16,6 +18,4 @@ describe "The -x command line option" do
result = ruby_exe(embedded_ruby)
result.should == "success\n"
end
-
- it "needs to be reviewed for spec completeness"
end
diff --git a/spec/ruby/command_line/error_message_spec.rb b/spec/ruby/command_line/error_message_spec.rb
index 6212452739..f3f7de4fd4 100644
--- a/spec/ruby/command_line/error_message_spec.rb
+++ b/spec/ruby/command_line/error_message_spec.rb
@@ -1,11 +1,11 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The error message caused by an exception" do
it "is not printed to stdout" do
out = ruby_exe("this_does_not_exist", args: "2> #{File::NULL}")
- out.chomp.empty?.should == true
+ out.chomp.should.empty?
out = ruby_exe("end #syntax error", args: "2> #{File::NULL}")
- out.chomp.empty?.should == true
+ out.chomp.should.empty?
end
end
diff --git a/spec/ruby/command_line/feature_spec.rb b/spec/ruby/command_line/feature_spec.rb
new file mode 100644
index 0000000000..16e106b37d
--- /dev/null
+++ b/spec/ruby/command_line/feature_spec.rb
@@ -0,0 +1,63 @@
+require_relative '../spec_helper'
+
+describe "The --enable and --disable flags" do
+
+ it "can be used with gems" do
+ ruby_exe("p defined?(Gem)", options: "--enable=gems").chomp.should == "\"constant\""
+ ruby_exe("p defined?(Gem)", options: "--disable=gems").chomp.should == "nil"
+ ruby_exe("p defined?(Gem)", options: "--enable-gems").chomp.should == "\"constant\""
+ ruby_exe("p defined?(Gem)", options: "--disable-gems").chomp.should == "nil"
+ end
+
+ it "can be used with gem" do
+ ruby_exe("p defined?(Gem)", options: "--enable=gem").chomp.should == "\"constant\""
+ ruby_exe("p defined?(Gem)", options: "--disable=gem").chomp.should == "nil"
+ ruby_exe("p defined?(Gem)", options: "--enable-gem").chomp.should == "\"constant\""
+ ruby_exe("p defined?(Gem)", options: "--disable-gem").chomp.should == "nil"
+ end
+
+ it "can be used with did_you_mean" do
+ ruby_exe("p defined?(DidYouMean)", options: "--enable=did_you_mean").chomp.should == "\"constant\""
+ ruby_exe("p defined?(DidYouMean)", options: "--disable=did_you_mean").chomp.should == "nil"
+ ruby_exe("p defined?(DidYouMean)", options: "--enable-did_you_mean").chomp.should == "\"constant\""
+ ruby_exe("p defined?(DidYouMean)", options: "--disable-did_you_mean").chomp.should == "nil"
+ end
+
+ it "can be used with rubyopt" do
+ ruby_exe("p $VERBOSE", options: "--enable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true"
+ ruby_exe("p $VERBOSE", options: "--disable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
+ ruby_exe("p $VERBOSE", options: "--enable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true"
+ ruby_exe("p $VERBOSE", options: "--disable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
+ end
+
+ it "can be used with frozen-string-literal" do
+ ruby_exe("p 'foo'.frozen?", options: "--enable=frozen-string-literal").chomp.should == "true"
+ ruby_exe("p 'foo'.frozen?", options: "--disable=frozen-string-literal").chomp.should == "false"
+ ruby_exe("p 'foo'.frozen?", options: "--enable-frozen-string-literal").chomp.should == "true"
+ ruby_exe("p 'foo'.frozen?", options: "--disable-frozen-string-literal").chomp.should == "false"
+ end
+
+ platform_is_not :darwin do # frequently hangs for >60s on GitHub Actions macos-latest
+ it "can be used with all for enable" do
+ e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]"
+ env = {'RUBYOPT' => '-w'}
+ # Use a single variant here because it can be quite slow as it might enable jit, etc
+ ruby_exe(e, options: "--enable-all", env: env).chomp.should == "[\"constant\", \"constant\", true, true]"
+ end
+ end
+
+ it "can be used with all for disable" do
+ e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]"
+ env = {'RUBYOPT' => '-w'}
+ ruby_exe(e, options: "--disable=all", env: env).chomp.should == "[nil, nil, false, false]"
+ ruby_exe(e, options: "--disable-all", env: env).chomp.should == "[nil, nil, false, false]"
+ end
+
+ it "prints a warning for unknown features" do
+ ruby_exe("p 14", options: "--enable=ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --enable')
+ ruby_exe("p 14", options: "--disable=ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --disable')
+ ruby_exe("p 14", options: "--enable-ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --enable')
+ ruby_exe("p 14", options: "--disable-ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --disable')
+ end
+
+end
diff --git a/spec/ruby/command_line/fixtures/bin/hybrid_launcher.sh b/spec/ruby/command_line/fixtures/bin/hybrid_launcher.sh
index 0eede2a99f..fd3249f0e5 100644
--- a/spec/ruby/command_line/fixtures/bin/hybrid_launcher.sh
+++ b/spec/ruby/command_line/fixtures/bin/hybrid_launcher.sh
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
-exec somehow this file
+echo 'error' && exit 1
#!ruby
puts 'success'
diff --git a/spec/ruby/command_line/fixtures/bin/launcher.rb b/spec/ruby/command_line/fixtures/bin/launcher.rb
index 92a0ee2b49..92a0ee2b49 100644..100755
--- a/spec/ruby/command_line/fixtures/bin/launcher.rb
+++ b/spec/ruby/command_line/fixtures/bin/launcher.rb
diff --git a/spec/ruby/command_line/fixtures/dash_upper_c_script.rb b/spec/ruby/command_line/fixtures/change_directory_script.rb
index abe244705f..abe244705f 100644
--- a/spec/ruby/command_line/fixtures/dash_upper_c_script.rb
+++ b/spec/ruby/command_line/fixtures/change_directory_script.rb
diff --git a/spec/ruby/command_line/fixtures/test_file.rb b/spec/ruby/command_line/fixtures/test_file.rb
index 961e3c0b0c..30a832299e 100644
--- a/spec/ruby/command_line/fixtures/test_file.rb
+++ b/spec/ruby/command_line/fixtures/test_file.rb
@@ -1 +1 @@
-"test file"
+puts "REQUIRED"
diff --git a/spec/ruby/command_line/frozen_strings_spec.rb b/spec/ruby/command_line/frozen_strings_spec.rb
index f3ee797c78..647b69daed 100644
--- a/spec/ruby/command_line/frozen_strings_spec.rb
+++ b/spec/ruby/command_line/frozen_strings_spec.rb
@@ -1,30 +1,29 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
-ruby_version_is "2.3" do
- describe "The --enable-frozen-string-literal flag causes string literals to" do
+describe "The --enable-frozen-string-literal flag causes string literals to" do
- it "produce the same object each time" do
- ruby_exe(fixture(__FILE__, "freeze_flag_one_literal.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
- end
+ it "produce the same object each time" do
+ ruby_exe(fixture(__FILE__, "freeze_flag_one_literal.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
+ end
- it "produce the same object for literals with the same content" do
- ruby_exe(fixture(__FILE__, "freeze_flag_two_literals.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
- end
+ it "produce the same object for literals with the same content" do
+ ruby_exe(fixture(__FILE__, "freeze_flag_two_literals.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
+ end
- it "produce the same object for literals with the same content in different files" do
- ruby_exe(fixture(__FILE__, "freeze_flag_across_files.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
- end
+ it "produce the same object for literals with the same content in different files" do
+ ruby_exe(fixture(__FILE__, "freeze_flag_across_files.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
+ end
- it "produce different objects for literals with the same content in different files if they have different encodings" do
- ruby_exe(fixture(__FILE__, "freeze_flag_across_files_diff_enc.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
- end
+ it "produce different objects for literals with the same content in different files if they have different encodings" do
+ ruby_exe(fixture(__FILE__, "freeze_flag_across_files_diff_enc.rb"), options: "--enable-frozen-string-literal").chomp.should == "true"
end
+end
- describe "The --debug flag produces" do
- it "debugging info on attempted frozen string modification" do
- error_str = ruby_exe(fixture(__FILE__, 'debug_info.rb'), options: '--debug', args: "2>&1")
- error_str.should include("can't modify frozen String, created at ")
- error_str.should include("command_line/fixtures/debug_info.rb:2")
- end
+describe "The --debug flag produces" do
+ it "debugging info on attempted frozen string modification" do
+ error_str = ruby_exe(fixture(__FILE__, 'debug_info.rb'), options: '--debug', args: "2>&1")
+ error_str.should include("can't modify frozen String")
+ error_str.should include("created at")
+ error_str.should include("command_line/fixtures/debug_info.rb:2")
end
end
diff --git a/spec/ruby/command_line/rubylib_spec.rb b/spec/ruby/command_line/rubylib_spec.rb
new file mode 100644
index 0000000000..b45919b997
--- /dev/null
+++ b/spec/ruby/command_line/rubylib_spec.rb
@@ -0,0 +1,69 @@
+require_relative '../spec_helper'
+
+describe "The RUBYLIB environment variable" do
+ before :each do
+ @rubylib, ENV["RUBYLIB"] = ENV["RUBYLIB"], nil
+ @pre = @rubylib.nil? ? '' : @rubylib + File::PATH_SEPARATOR
+ end
+
+ after :each do
+ ENV["RUBYLIB"] = @rubylib
+ end
+
+ it "adds a directory to $LOAD_PATH" do
+ dir = tmp("rubylib/incl")
+ ENV["RUBYLIB"] = @pre + dir
+ paths = ruby_exe("puts $LOAD_PATH").lines.map(&:chomp)
+ paths.should include(dir)
+ end
+
+ it "adds a File::PATH_SEPARATOR-separated list of directories to $LOAD_PATH" do
+ dir1, dir2 = tmp("rubylib/incl1"), tmp("rubylib/incl2")
+ ENV["RUBYLIB"] = @pre + "#{dir1}#{File::PATH_SEPARATOR}#{dir2}"
+ paths = ruby_exe("puts $LOAD_PATH").lines.map(&:chomp)
+ paths.should include(dir1)
+ paths.should include(dir2)
+ paths.index(dir1).should < paths.index(dir2)
+ end
+
+ it "adds the directory at the front of $LOAD_PATH" do
+ dir = tmp("rubylib/incl_front")
+ ENV["RUBYLIB"] = @pre + dir
+ paths = ruby_exe("puts $LOAD_PATH").lines.map(&:chomp)
+ paths.shift if paths.first.end_with?('/gem-rehash')
+ if PlatformGuard.implementation? :ruby
+ # In a MRI checkout, $PWD and some extra -I entries end up as
+ # the first entries in $LOAD_PATH. So just assert that it's not last.
+ idx = paths.index(dir)
+ idx.should < paths.size-1
+ else
+ paths[0].should == dir
+ end
+ end
+
+ it "adds the directory after directories added by -I" do
+ dash_i_dir = tmp("dash_I_include")
+ rubylib_dir = tmp("rubylib_include")
+ ENV["RUBYLIB"] = @pre + rubylib_dir
+ paths = ruby_exe("puts $LOAD_PATH", options: "-I #{dash_i_dir}").lines.map(&:chomp)
+ paths.should include(dash_i_dir)
+ paths.should include(rubylib_dir)
+ paths.index(dash_i_dir).should < paths.index(rubylib_dir)
+ end
+
+ it "adds the directory after directories added by -I within RUBYOPT" do
+ rubyopt_dir = tmp("rubyopt_include")
+ rubylib_dir = tmp("rubylib_include")
+ ENV["RUBYLIB"] = @pre + rubylib_dir
+ paths = ruby_exe("puts $LOAD_PATH", env: { "RUBYOPT" => "-I#{rubyopt_dir}" }).lines.map(&:chomp)
+ paths.should include(rubyopt_dir)
+ paths.should include(rubylib_dir)
+ paths.index(rubyopt_dir).should < paths.index(rubylib_dir)
+ end
+
+ it "keeps spaces in the value" do
+ ENV["RUBYLIB"] = @pre + " rubylib/incl "
+ out = ruby_exe("puts $LOAD_PATH")
+ out.should include(" rubylib/incl ")
+ end
+end
diff --git a/spec/ruby/command_line/rubyopt_spec.rb b/spec/ruby/command_line/rubyopt_spec.rb
index a80cb51a94..a739f23eb8 100644
--- a/spec/ruby/command_line/rubyopt_spec.rb
+++ b/spec/ruby/command_line/rubyopt_spec.rb
@@ -1,11 +1,11 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "Processing RUBYOPT" do
- before (:each) do
+ before :each do
@rubyopt, ENV["RUBYOPT"] = ENV["RUBYOPT"], nil
end
- after (:each) do
+ after :each do
ENV["RUBYOPT"] = @rubyopt
end
@@ -22,9 +22,16 @@ describe "Processing RUBYOPT" do
result.should =~ /value of \$DEBUG is true/
end
- it "prints the version number for '-v'" do
- ENV["RUBYOPT"] = '-v'
- ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION
+ guard -> { not CROSS_COMPILING } do
+ it "prints the version number for '-v'" do
+ ENV["RUBYOPT"] = '-v'
+ ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION
+ end
+
+ it "ignores whitespace around the option" do
+ ENV["RUBYOPT"] = ' -v '
+ ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION
+ end
end
it "sets $VERBOSE to true for '-w'" do
@@ -52,6 +59,26 @@ describe "Processing RUBYOPT" do
ruby_exe("p $VERBOSE", escape: true).chomp.should == "true"
end
+ ruby_version_is "2.7" do
+ it "suppresses deprecation warnings for '-W:no-deprecated'" do
+ ENV["RUBYOPT"] = '-W:no-deprecated'
+ result = ruby_exe('$; = ""', args: '2>&1')
+ result.should == ""
+ end
+
+ it "suppresses experimental warnings for '-W:no-experimental'" do
+ ENV["RUBYOPT"] = '-W:no-experimental'
+ result = ruby_exe('case 0; in a; end', args: '2>&1')
+ result.should == ""
+ end
+
+ it "suppresses deprecation and experimental warnings for '-W:no-deprecated -W:no-experimental'" do
+ ENV["RUBYOPT"] = '-W:no-deprecated -W:no-experimental'
+ result = ruby_exe('case ($; = ""); in a; end', args: '2>&1')
+ result.should == ""
+ end
+ end
+
it "requires the file for '-r'" do
f = fixture __FILE__, "rubyopt"
ENV["RUBYOPT"] = "-r#{f}"
diff --git a/spec/ruby/command_line/shared/change_directory.rb b/spec/ruby/command_line/shared/change_directory.rb
new file mode 100644
index 0000000000..9cb6e90ac6
--- /dev/null
+++ b/spec/ruby/command_line/shared/change_directory.rb
@@ -0,0 +1,21 @@
+describe :command_line_change_directory, shared: true do
+ before :all do
+ @script = fixture(__FILE__, 'change_directory_script.rb')
+ @tempdir = File.dirname(@script)
+ end
+
+ it 'changes the PWD when using a file' do
+ output = ruby_exe(@script, options: "#{@method} #{@tempdir}")
+ output.should == @tempdir
+ end
+
+ it 'does not need a space after -C for the argument' do
+ output = ruby_exe(@script, options: "#{@method}#{@tempdir}")
+ output.should == @tempdir
+ end
+
+ it 'changes the PWD when using -e' do
+ output = ruby_exe(nil, options: "#{@method} #{@tempdir} -e 'print Dir.pwd'")
+ output.should == @tempdir
+ end
+end
diff --git a/spec/ruby/command_line/shared/verbose.rb b/spec/ruby/command_line/shared/verbose.rb
index 457fe3006a..c5c44c269e 100644
--- a/spec/ruby/command_line/shared/verbose.rb
+++ b/spec/ruby/command_line/shared/verbose.rb
@@ -4,6 +4,6 @@ describe :command_line_verbose, shared: true do
end
it "sets $VERBOSE to true" do
- ruby_exe(@script, options: @method).chomp.split.last.should == "true"
+ ruby_exe(@script, options: @method).chomp.b.split.last.should == "true"
end
end
diff --git a/spec/ruby/command_line/syntax_error_spec.rb b/spec/ruby/command_line/syntax_error_spec.rb
index 71cee32e23..f61cfe928d 100644
--- a/spec/ruby/command_line/syntax_error_spec.rb
+++ b/spec/ruby/command_line/syntax_error_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../spec_helper', __FILE__)
+require_relative '../spec_helper'
describe "The interpreter" do
it "prints an error when given a file with invalid syntax" do
diff --git a/spec/ruby/core/argf/argf_spec.rb b/spec/ruby/core/argf/argf_spec.rb
index b47e77c17f..af67170b98 100644
--- a/spec/ruby/core/argf/argf_spec.rb
+++ b/spec/ruby/core/argf/argf_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF" do
it "is extended by the Enumerable module" do
diff --git a/spec/ruby/core/argf/argv_spec.rb b/spec/ruby/core/argf/argv_spec.rb
index e294b3993f..eab03c450f 100644
--- a/spec/ruby/core/argf/argv_spec.rb
+++ b/spec/ruby/core/argf/argv_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.argv" do
before :each do
diff --git a/spec/ruby/core/argf/binmode_spec.rb b/spec/ruby/core/argf/binmode_spec.rb
index 62202360e3..e083a30a27 100644
--- a/spec/ruby/core/argf/binmode_spec.rb
+++ b/spec/ruby/core/argf/binmode_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.binmode" do
before :each do
@@ -22,7 +22,7 @@ describe "ARGF.binmode" do
end
end
- it "puts alls subsequent stream reading through ARGF into binmode" do
+ it "puts all subsequent streams reading through ARGF into binmode" do
argf [@bin_file, @bin_file] do
@argf.binmode
@argf.gets.should == "test\r\n"
@@ -31,13 +31,13 @@ describe "ARGF.binmode" do
end
end
- it "sets the file's encoding to ASCII-8BIT" do
+ it "sets the file's encoding to BINARY" do
argf [@bin_file, @file1] do
@argf.binmode
- @argf.binmode?.should == true
- @argf.gets.encoding.should == Encoding::ASCII_8BIT
+ @argf.should.binmode?
+ @argf.gets.encoding.should == Encoding::BINARY
@argf.skip
- @argf.read.encoding.should == Encoding::ASCII_8BIT
+ @argf.read.encoding.should == Encoding::BINARY
end
end
end
diff --git a/spec/ruby/core/argf/bytes_spec.rb b/spec/ruby/core/argf/bytes_spec.rb
index 01a3a3db0d..3e11a4f5c4 100644
--- a/spec/ruby/core/argf/bytes_spec.rb
+++ b/spec/ruby/core/argf/bytes_spec.rb
@@ -1,6 +1,8 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_byte', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_byte'
-describe "ARGF.bytes" do
- it_behaves_like :argf_each_byte, :bytes
+ruby_version_is ''...'3.0' do
+ describe "ARGF.bytes" do
+ it_behaves_like :argf_each_byte, :bytes
+ end
end
diff --git a/spec/ruby/core/argf/chars_spec.rb b/spec/ruby/core/argf/chars_spec.rb
index 8c9e4844c0..a864ce6d52 100644
--- a/spec/ruby/core/argf/chars_spec.rb
+++ b/spec/ruby/core/argf/chars_spec.rb
@@ -1,6 +1,8 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_char', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_char'
-describe "ARGF.chars" do
- it_behaves_like :argf_each_char, :chars
+ruby_version_is ''...'3.0' do
+ describe "ARGF.chars" do
+ it_behaves_like :argf_each_char, :chars
+ end
end
diff --git a/spec/ruby/core/argf/close_spec.rb b/spec/ruby/core/argf/close_spec.rb
index b56f7f5564..d4d6a51e72 100644
--- a/spec/ruby/core/argf/close_spec.rb
+++ b/spec/ruby/core/argf/close_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.close" do
before :each do
@@ -20,21 +20,10 @@ describe "ARGF.close" do
end
end
- ruby_version_is ""..."2.3" do
- it "raises an IOError if called on a closed stream" do
- argf [@file1_name] do
- lambda { @argf.close }.should_not raise_error
- lambda { @argf.close }.should raise_error(IOError)
- end
- end
- end
-
- ruby_version_is "2.3" do
- it "doesn't raise an IOError if called on a closed stream" do
- argf [@file1_name] do
- lambda { @argf.close }.should_not raise_error
- lambda { @argf.close }.should_not raise_error
- end
+ it "doesn't raise an IOError if called on a closed stream" do
+ argf [@file1_name] do
+ -> { @argf.close }.should_not raise_error
+ -> { @argf.close }.should_not raise_error
end
end
end
diff --git a/spec/ruby/core/argf/closed_spec.rb b/spec/ruby/core/argf/closed_spec.rb
index 745f102484..e2dd6134e5 100644
--- a/spec/ruby/core/argf/closed_spec.rb
+++ b/spec/ruby/core/argf/closed_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.closed?" do
before :each do
diff --git a/spec/ruby/core/argf/codepoints_spec.rb b/spec/ruby/core/argf/codepoints_spec.rb
index cd839cbb8c..d3007c4c5b 100644
--- a/spec/ruby/core/argf/codepoints_spec.rb
+++ b/spec/ruby/core/argf/codepoints_spec.rb
@@ -1,6 +1,8 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_codepoint', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_codepoint'
-describe "ARGF.codepoints" do
- it_behaves_like :argf_each_codepoint, :codepoints
+ruby_version_is ''...'3.0' do
+ describe "ARGF.codepoints" do
+ it_behaves_like :argf_each_codepoint, :codepoints
+ end
end
diff --git a/spec/ruby/core/argf/each_byte_spec.rb b/spec/ruby/core/argf/each_byte_spec.rb
index 8b4a62c2b1..c5cce9f250 100644
--- a/spec/ruby/core/argf/each_byte_spec.rb
+++ b/spec/ruby/core/argf/each_byte_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_byte', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_byte'
describe "ARGF.each_byte" do
it_behaves_like :argf_each_byte, :each_byte
diff --git a/spec/ruby/core/argf/each_char_spec.rb b/spec/ruby/core/argf/each_char_spec.rb
index 58ac0bf783..724e5e6e3e 100644
--- a/spec/ruby/core/argf/each_char_spec.rb
+++ b/spec/ruby/core/argf/each_char_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_char', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_char'
describe "ARGF.each_char" do
it_behaves_like :argf_each_char, :each_char
diff --git a/spec/ruby/core/argf/each_codepoint_spec.rb b/spec/ruby/core/argf/each_codepoint_spec.rb
index d0725841a7..0bf8bf9764 100644
--- a/spec/ruby/core/argf/each_codepoint_spec.rb
+++ b/spec/ruby/core/argf/each_codepoint_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_codepoint', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_codepoint'
describe "ARGF.each_codepoint" do
it_behaves_like :argf_each_codepoint, :each_codepoint
diff --git a/spec/ruby/core/argf/each_line_spec.rb b/spec/ruby/core/argf/each_line_spec.rb
index d37968af3d..52a7e5c411 100644
--- a/spec/ruby/core/argf/each_line_spec.rb
+++ b/spec/ruby/core/argf/each_line_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_line', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_line'
describe "ARGF.each_line" do
it_behaves_like :argf_each_line, :each_line
diff --git a/spec/ruby/core/argf/each_spec.rb b/spec/ruby/core/argf/each_spec.rb
index 5a1e0dc73c..5742ba43bd 100644
--- a/spec/ruby/core/argf/each_spec.rb
+++ b/spec/ruby/core/argf/each_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_line', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_line'
describe "ARGF.each" do
it_behaves_like :argf_each_line, :each
diff --git a/spec/ruby/core/argf/eof_spec.rb b/spec/ruby/core/argf/eof_spec.rb
index 534bf1f8d8..518f6e566e 100644
--- a/spec/ruby/core/argf/eof_spec.rb
+++ b/spec/ruby/core/argf/eof_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/eof', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/eof'
describe "ARGF.eof" do
it_behaves_like :argf_eof, :eof
diff --git a/spec/ruby/core/argf/file_spec.rb b/spec/ruby/core/argf/file_spec.rb
index 248ffeff17..df8552d457 100644
--- a/spec/ruby/core/argf/file_spec.rb
+++ b/spec/ruby/core/argf/file_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.file" do
before :each do
diff --git a/spec/ruby/core/argf/filename_spec.rb b/spec/ruby/core/argf/filename_spec.rb
index f7ebafa7c5..7c0446269d 100644
--- a/spec/ruby/core/argf/filename_spec.rb
+++ b/spec/ruby/core/argf/filename_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/filename', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/filename'
describe "ARGF.filename" do
it_behaves_like :argf_filename, :filename
diff --git a/spec/ruby/core/argf/fileno_spec.rb b/spec/ruby/core/argf/fileno_spec.rb
index b35047695c..29d50c3582 100644
--- a/spec/ruby/core/argf/fileno_spec.rb
+++ b/spec/ruby/core/argf/fileno_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/fileno', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/fileno'
describe "ARGF.fileno" do
it_behaves_like :argf_fileno, :fileno
diff --git a/spec/ruby/core/argf/getc_spec.rb b/spec/ruby/core/argf/getc_spec.rb
index de5e6fa73c..dc5de9b7df 100644
--- a/spec/ruby/core/argf/getc_spec.rb
+++ b/spec/ruby/core/argf/getc_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/getc', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/getc'
describe "ARGF.getc" do
it_behaves_like :argf_getc, :getc
diff --git a/spec/ruby/core/argf/gets_spec.rb b/spec/ruby/core/argf/gets_spec.rb
index b65aa076bd..cc7673b190 100644
--- a/spec/ruby/core/argf/gets_spec.rb
+++ b/spec/ruby/core/argf/gets_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/gets', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/gets'
describe "ARGF.gets" do
it_behaves_like :argf_gets, :gets
@@ -26,25 +26,23 @@ describe "ARGF.gets" do
end
end
- with_feature :encoding do
- before :each do
- @external = Encoding.default_external
- @internal = Encoding.default_internal
+ before :each do
+ @external = Encoding.default_external
+ @internal = Encoding.default_internal
- Encoding.default_external = Encoding::UTF_8
- Encoding.default_internal = nil
- end
+ Encoding.default_external = Encoding::UTF_8
+ Encoding.default_internal = nil
+ end
- after :each do
- Encoding.default_external = @external
- Encoding.default_internal = @internal
- end
+ after :each do
+ Encoding.default_external = @external
+ Encoding.default_internal = @internal
+ end
- it "reads the contents of the file with default encoding" do
- Encoding.default_external = Encoding::US_ASCII
- argf [@file1_name, @file2_name] do
- @argf.gets.encoding.should == Encoding::US_ASCII
- end
+ it "reads the contents of the file with default encoding" do
+ Encoding.default_external = Encoding::US_ASCII
+ argf [@file1_name, @file2_name] do
+ @argf.gets.encoding.should == Encoding::US_ASCII
end
end
diff --git a/spec/ruby/core/argf/lineno_spec.rb b/spec/ruby/core/argf/lineno_spec.rb
index 13b1916fb1..72a108c187 100644
--- a/spec/ruby/core/argf/lineno_spec.rb
+++ b/spec/ruby/core/argf/lineno_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.lineno" do
before :each do
diff --git a/spec/ruby/core/argf/lines_spec.rb b/spec/ruby/core/argf/lines_spec.rb
index ea3578e3a2..0bf5bb0d73 100644
--- a/spec/ruby/core/argf/lines_spec.rb
+++ b/spec/ruby/core/argf/lines_spec.rb
@@ -1,6 +1,8 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each_line', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/each_line'
-describe "ARGF.lines" do
- it_behaves_like :argf_each_line, :lines
+ruby_version_is ''...'3.0' do
+ describe "ARGF.lines" do
+ it_behaves_like :argf_each_line, :lines
+ end
end
diff --git a/spec/ruby/core/argf/path_spec.rb b/spec/ruby/core/argf/path_spec.rb
index 098de8693a..7120f7d0e3 100644
--- a/spec/ruby/core/argf/path_spec.rb
+++ b/spec/ruby/core/argf/path_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/filename', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/filename'
describe "ARGF.path" do
it_behaves_like :argf_filename, :path
diff --git a/spec/ruby/core/argf/pos_spec.rb b/spec/ruby/core/argf/pos_spec.rb
index b6e5c3a254..fb3f25b945 100644
--- a/spec/ruby/core/argf/pos_spec.rb
+++ b/spec/ruby/core/argf/pos_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/pos', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/pos'
describe "ARGF.pos" do
it_behaves_like :argf_pos, :pos
diff --git a/spec/ruby/core/argf/read_nonblock_spec.rb b/spec/ruby/core/argf/read_nonblock_spec.rb
index 8176a206e5..804a459a62 100644
--- a/spec/ruby/core/argf/read_nonblock_spec.rb
+++ b/spec/ruby/core/argf/read_nonblock_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/read', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/read'
platform_is_not :windows do
describe 'ARGF.read_nonblock' do
@@ -64,17 +64,15 @@ platform_is_not :windows do
it 'raises IO::EAGAINWaitReadable when empty' do
argf ['-'] do
- lambda {
+ -> {
@argf.read_nonblock(4)
}.should raise_error(IO::EAGAINWaitReadable)
end
end
- ruby_version_is "2.3" do
- it 'returns :wait_readable when the :exception is set to false' do
- argf ['-'] do
- @argf.read_nonblock(4, nil, exception: false).should == :wait_readable
- end
+ it 'returns :wait_readable when the :exception is set to false' do
+ argf ['-'] do
+ @argf.read_nonblock(4, nil, exception: false).should == :wait_readable
end
end
end
diff --git a/spec/ruby/core/argf/read_spec.rb b/spec/ruby/core/argf/read_spec.rb
index 4eaaea46bb..bbeef95456 100644
--- a/spec/ruby/core/argf/read_spec.rb
+++ b/spec/ruby/core/argf/read_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/read', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/read'
describe "ARGF.read" do
it_behaves_like :argf_read, :read
@@ -62,26 +62,24 @@ describe "ARGF.read" do
end
end
- with_feature :encoding do
- before :each do
- @external = Encoding.default_external
- @internal = Encoding.default_internal
+ before :each do
+ @external = Encoding.default_external
+ @internal = Encoding.default_internal
- Encoding.default_external = Encoding::UTF_8
- Encoding.default_internal = nil
- end
+ Encoding.default_external = Encoding::UTF_8
+ Encoding.default_internal = nil
+ end
- after :each do
- Encoding.default_external = @external
- Encoding.default_internal = @internal
- end
+ after :each do
+ Encoding.default_external = @external
+ Encoding.default_internal = @internal
+ end
- it "reads the contents of the file with default encoding" do
- Encoding.default_external = Encoding::US_ASCII
- argf [@file1_name, @file2_name] do
- @argf.read.encoding.should == Encoding::US_ASCII
- end
+ it "reads the contents of the file with default encoding" do
+ Encoding.default_external = Encoding::US_ASCII
+ argf [@file1_name, @file2_name] do
+ @argf.read.encoding.should == Encoding::US_ASCII
end
end
end
diff --git a/spec/ruby/core/argf/readchar_spec.rb b/spec/ruby/core/argf/readchar_spec.rb
index 71e2a6c742..4eca2efcf7 100644
--- a/spec/ruby/core/argf/readchar_spec.rb
+++ b/spec/ruby/core/argf/readchar_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/getc', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/getc'
describe "ARGF.getc" do
it_behaves_like :argf_getc, :readchar
@@ -13,7 +13,7 @@ describe "ARGF.readchar" do
it "raises EOFError when end of stream reached" do
argf [@file1, @file2] do
- lambda { while @argf.readchar; end }.should raise_error(EOFError)
+ -> { while @argf.readchar; end }.should raise_error(EOFError)
end
end
end
diff --git a/spec/ruby/core/argf/readline_spec.rb b/spec/ruby/core/argf/readline_spec.rb
index d31cfce415..db53c499e9 100644
--- a/spec/ruby/core/argf/readline_spec.rb
+++ b/spec/ruby/core/argf/readline_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/gets', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/gets'
describe "ARGF.readline" do
it_behaves_like :argf_gets, :readline
@@ -17,7 +17,7 @@ describe "ARGF.readline" do
it "raises an EOFError when reaching end of files" do
argf [@file1, @file2] do
- lambda { while @argf.readline; end }.should raise_error(EOFError)
+ -> { while @argf.readline; end }.should raise_error(EOFError)
end
end
end
diff --git a/spec/ruby/core/argf/readlines_spec.rb b/spec/ruby/core/argf/readlines_spec.rb
index 8e68429aa8..30be936dab 100644
--- a/spec/ruby/core/argf/readlines_spec.rb
+++ b/spec/ruby/core/argf/readlines_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/readlines', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/readlines'
describe "ARGF.readlines" do
it_behaves_like :argf_readlines, :readlines
diff --git a/spec/ruby/core/argf/readpartial_spec.rb b/spec/ruby/core/argf/readpartial_spec.rb
index 61c330182c..5e284b3423 100644
--- a/spec/ruby/core/argf/readpartial_spec.rb
+++ b/spec/ruby/core/argf/readpartial_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/read', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/read'
describe "ARGF.readpartial" do
it_behaves_like :argf_read, :readpartial
@@ -16,7 +16,7 @@ describe "ARGF.readpartial" do
it "raises an ArgumentError if called without a maximum read length" do
argf [@file1_name] do
- lambda { @argf.readpartial }.should raise_error(ArgumentError)
+ -> { @argf.readpartial }.should raise_error(ArgumentError)
end
end
@@ -54,15 +54,13 @@ describe "ARGF.readpartial" do
end
end
- ruby_version_is "2.3" do
- it "raises an EOFError if the exception was raised while reading the last file" do
- argf [@file1_name, @file2_name] do
- @argf.readpartial(@file1.size)
- @argf.readpartial(1)
- @argf.readpartial(@file2.size)
- lambda { @argf.readpartial(1) }.should raise_error(EOFError)
- lambda { @argf.readpartial(1) }.should raise_error(EOFError)
- end
+ it "raises an EOFError if the exception was raised while reading the last file" do
+ argf [@file1_name, @file2_name] do
+ @argf.readpartial(@file1.size)
+ @argf.readpartial(1)
+ @argf.readpartial(@file2.size)
+ -> { @argf.readpartial(1) }.should raise_error(EOFError)
+ -> { @argf.readpartial(1) }.should raise_error(EOFError)
end
end
diff --git a/spec/ruby/core/argf/rewind_spec.rb b/spec/ruby/core/argf/rewind_spec.rb
index d6abc3a856..b29f0b75b7 100644
--- a/spec/ruby/core/argf/rewind_spec.rb
+++ b/spec/ruby/core/argf/rewind_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.rewind" do
before :each do
@@ -33,7 +33,7 @@ describe "ARGF.rewind" do
it "raises an ArgumentError when end of stream reached" do
argf [@file1_name, @file2_name] do
@argf.read
- lambda { @argf.rewind }.should raise_error(ArgumentError)
+ -> { @argf.rewind }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/argf/seek_spec.rb b/spec/ruby/core/argf/seek_spec.rb
index 97dacb6cfc..2b73bd46fb 100644
--- a/spec/ruby/core/argf/seek_spec.rb
+++ b/spec/ruby/core/argf/seek_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.seek" do
before :each do
@@ -57,7 +57,7 @@ describe "ARGF.seek" do
it "takes at least one argument (offset)" do
argf [@file1_name] do
- lambda { @argf.seek }.should raise_error(ArgumentError)
+ -> { @argf.seek }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/argf/set_encoding_spec.rb b/spec/ruby/core/argf/set_encoding_spec.rb
index f6ec74ded1..a871e084b6 100644
--- a/spec/ruby/core/argf/set_encoding_spec.rb
+++ b/spec/ruby/core/argf/set_encoding_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.set_encoding" do
before :each do
diff --git a/spec/ruby/core/argf/shared/eof.rb b/spec/ruby/core/argf/shared/eof.rb
index bba18ede50..0e684f943f 100644
--- a/spec/ruby/core/argf/shared/eof.rb
+++ b/spec/ruby/core/argf/shared/eof.rb
@@ -18,7 +18,7 @@ describe :argf_eof, shared: true do
it "raises IOError when called on a closed stream" do
argf [@file1] do
@argf.read
- lambda { @argf.send(@method) }.should raise_error(IOError)
+ -> { @argf.send(@method) }.should raise_error(IOError)
end
end
end
diff --git a/spec/ruby/core/argf/shared/fileno.rb b/spec/ruby/core/argf/shared/fileno.rb
index 891e250ad9..4350d43747 100644
--- a/spec/ruby/core/argf/shared/fileno.rb
+++ b/spec/ruby/core/argf/shared/fileno.rb
@@ -11,14 +11,14 @@ describe :argf_fileno, shared: true do
# returns first current file even when not yet open
result << @argf.send(@method) while @argf.gets
# returns last current file even when closed
- result.map { |d| d.class }.should == [Fixnum, Fixnum, Fixnum, Fixnum]
+ result.map { |d| d.class }.should == [Integer, Integer, Integer, Integer]
end
end
it "raises an ArgumentError when called on a closed stream" do
argf [@file1] do
@argf.read
- lambda { @argf.send(@method) }.should raise_error(ArgumentError)
+ -> { @argf.send(@method) }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/argf/shared/pos.rb b/spec/ruby/core/argf/shared/pos.rb
index f7184f3d7c..9836d5f1e4 100644
--- a/spec/ruby/core/argf/shared/pos.rb
+++ b/spec/ruby/core/argf/shared/pos.rb
@@ -25,7 +25,7 @@ describe :argf_pos, shared: true do
it "raises an ArgumentError when called on a closed stream" do
argf [@file1] do
@argf.read
- lambda { @argf.send(@method) }.should raise_error(ArgumentError)
+ -> { @argf.send(@method) }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/argf/skip_spec.rb b/spec/ruby/core/argf/skip_spec.rb
index 5f5e9eb79a..0181801c2d 100644
--- a/spec/ruby/core/argf/skip_spec.rb
+++ b/spec/ruby/core/argf/skip_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.skip" do
before :each do
@@ -37,6 +37,6 @@ describe "ARGF.skip" do
# which as a side-effect calls argf.file which will initialize
# internals of ARGF enough for this to work.
it "has no effect when nothing has been processed yet" do
- lambda { ARGF.class.new(@file1_name).skip }.should_not raise_error
+ -> { ARGF.class.new(@file1_name).skip }.should_not raise_error
end
end
diff --git a/spec/ruby/core/argf/tell_spec.rb b/spec/ruby/core/argf/tell_spec.rb
index bcd824f087..16d9f29920 100644
--- a/spec/ruby/core/argf/tell_spec.rb
+++ b/spec/ruby/core/argf/tell_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/pos', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/pos'
describe "ARGF.tell" do
it_behaves_like :argf_pos, :tell
diff --git a/spec/ruby/core/argf/to_a_spec.rb b/spec/ruby/core/argf/to_a_spec.rb
index 75b5c10c9b..b17a93db33 100644
--- a/spec/ruby/core/argf/to_a_spec.rb
+++ b/spec/ruby/core/argf/to_a_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/readlines', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/readlines'
describe "ARGF.to_a" do
it_behaves_like :argf_readlines, :to_a
diff --git a/spec/ruby/core/argf/to_i_spec.rb b/spec/ruby/core/argf/to_i_spec.rb
index 27359014af..2183de6cd4 100644
--- a/spec/ruby/core/argf/to_i_spec.rb
+++ b/spec/ruby/core/argf/to_i_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/fileno', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/fileno'
describe "ARGF.to_i" do
it_behaves_like :argf_fileno, :to_i
diff --git a/spec/ruby/core/argf/to_io_spec.rb b/spec/ruby/core/argf/to_io_spec.rb
index 0575c35f25..062383d291 100644
--- a/spec/ruby/core/argf/to_io_spec.rb
+++ b/spec/ruby/core/argf/to_io_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.to_io" do
before :each do
diff --git a/spec/ruby/core/argf/to_s_spec.rb b/spec/ruby/core/argf/to_s_spec.rb
index 0128049c3f..3f505898f4 100644
--- a/spec/ruby/core/argf/to_s_spec.rb
+++ b/spec/ruby/core/argf/to_s_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ARGF.to_s" do
before :each do
diff --git a/spec/ruby/core/array/allocate_spec.rb b/spec/ruby/core/array/allocate_spec.rb
index bb5168cb74..04f7c0d0ad 100644
--- a/spec/ruby/core/array/allocate_spec.rb
+++ b/spec/ruby/core/array/allocate_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array.allocate" do
it "returns an instance of Array" do
@@ -14,6 +14,6 @@ describe "Array.allocate" do
end
it "does not accept any arguments" do
- lambda { Array.allocate(1) }.should raise_error(ArgumentError)
+ -> { Array.allocate(1) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/array/any_spec.rb b/spec/ruby/core/array/any_spec.rb
index 7e9863420f..09d949fe6e 100644
--- a/spec/ruby/core/array/any_spec.rb
+++ b/spec/ruby/core/array/any_spec.rb
@@ -1,20 +1,20 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#any?" do
describe 'with no block given (a default block of { |x| x } is implicit)' do
it "is false if the array is empty" do
empty_array = []
- empty_array.any?.should == false
+ empty_array.should_not.any?
end
it "is false if the array is not empty, but all the members of the array are falsy" do
falsy_array = [false, nil, false]
- falsy_array.any?.should == false
+ falsy_array.should_not.any?
end
it "is true if the array has any truthy members" do
not_empty_array = ['anything', nil]
- not_empty_array.any?.should == true
+ not_empty_array.should.any?
end
end
diff --git a/spec/ruby/core/array/append_spec.rb b/spec/ruby/core/array/append_spec.rb
index 4c65004c58..c12473dc07 100644
--- a/spec/ruby/core/array/append_spec.rb
+++ b/spec/ruby/core/array/append_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/push'
describe "Array#<<" do
it "pushes the object onto the end of the array" do
@@ -29,7 +30,11 @@ describe "Array#<<" do
a.should == [:foo]
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array << 5 }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array << 5 }.should raise_error(FrozenError)
end
end
+
+describe "Array#append" do
+ it_behaves_like :array_push, :append
+end
diff --git a/spec/ruby/core/array/array_spec.rb b/spec/ruby/core/array/array_spec.rb
index 186bd40f10..855f17348f 100644
--- a/spec/ruby/core/array/array_spec.rb
+++ b/spec/ruby/core/array/array_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array" do
it "includes Enumerable" do
diff --git a/spec/ruby/core/array/assoc_spec.rb b/spec/ruby/core/array/assoc_spec.rb
index 37b0357806..f8479d763c 100644
--- a/spec/ruby/core/array/assoc_spec.rb
+++ b/spec/ruby/core/array/assoc_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#assoc" do
it "returns the first array whose 1st item is == obj or nil" do
diff --git a/spec/ruby/core/array/at_spec.rb b/spec/ruby/core/array/at_spec.rb
index e40c26f2cc..8bc789fef7 100644
--- a/spec/ruby/core/array/at_spec.rb
+++ b/spec/ruby/core/array/at_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#at" do
it "returns the (n+1)'th element for the passed index n" do
@@ -15,7 +15,7 @@ describe "Array#at" do
a.at(7).should == nil
end
- it "returns the (-n)'th elemet from the last, for the given negative index n" do
+ it "returns the (-n)'th element from the last, for the given negative index n" do
a = [1, 2, 3, 4, 5, 6]
a.at(-1).should == 6
a.at(-2).should == 5
@@ -47,10 +47,10 @@ describe "Array#at" do
end
it "raises a TypeError when the passed argument can't be coerced to Integer" do
- lambda { [].at("cat") }.should raise_error(TypeError)
+ -> { [].at("cat") }.should raise_error(TypeError)
end
- it "raises an ArgumentError when 2 or more arguments is passed" do
- lambda { [:a, :b].at(0,1) }.should raise_error(ArgumentError)
+ it "raises an ArgumentError when 2 or more arguments are passed" do
+ -> { [:a, :b].at(0,1) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/array/bsearch_index_spec.rb b/spec/ruby/core/array/bsearch_index_spec.rb
index 1ed11876b4..df2c7c098e 100644
--- a/spec/ruby/core/array/bsearch_index_spec.rb
+++ b/spec/ruby/core/array/bsearch_index_spec.rb
@@ -1,86 +1,84 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
-
-ruby_version_is "2.3" do
- describe "Array#bsearch_index" do
- context "when not passed a block" do
- before :each do
- @enum = [1, 2, 42, 100, 666].bsearch_index
- end
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
- it "returns an Enumerator" do
- @enum.should be_an_instance_of(Enumerator)
- end
+describe "Array#bsearch_index" do
+ context "when not passed a block" do
+ before :each do
+ @enum = [1, 2, 42, 100, 666].bsearch_index
+ end
- it "returns an Enumerator with unknown size" do
- @enum.size.should be_nil
- end
+ it "returns an Enumerator" do
+ @enum.should be_an_instance_of(Enumerator)
+ end
- it "returns index of element when block condition is satisfied" do
- @enum.each { |x| x >= 33 }.should == 2
- end
+ it "returns an Enumerator with unknown size" do
+ @enum.size.should be_nil
end
- it "raises a TypeError when block returns a String" do
- lambda { [1, 2, 3].bsearch_index { "not ok" } }.should raise_error(TypeError)
+ it "returns index of element when block condition is satisfied" do
+ @enum.each { |x| x >= 33 }.should == 2
end
+ end
- it "returns nil when block is empty" do
- [1, 2, 3].bsearch_index {}.should be_nil
+ it "raises a TypeError when block returns a String" do
+ -> { [1, 2, 3].bsearch_index { "not ok" } }.should raise_error(TypeError)
+ end
+
+ it "returns nil when block is empty" do
+ [1, 2, 3].bsearch_index {}.should be_nil
+ end
+
+ context "minimum mode" do
+ before :each do
+ @array = [0, 4, 7, 10, 12]
end
- context "minimum mode" do
- before :each do
- @array = [0, 4, 7, 10, 12]
- end
+ it "returns index of first element which satisfies the block" do
+ @array.bsearch_index { |x| x >= 4 }.should == 1
+ @array.bsearch_index { |x| x >= 6 }.should == 2
+ @array.bsearch_index { |x| x >= -1 }.should == 0
+ end
- it "returns index of first element which satisfies the block" do
- @array.bsearch_index { |x| x >= 4 }.should == 1
- @array.bsearch_index { |x| x >= 6 }.should == 2
- @array.bsearch_index { |x| x >= -1 }.should == 0
- end
+ it "returns nil when block condition is never satisfied" do
+ @array.bsearch_index { false }.should be_nil
+ @array.bsearch_index { |x| x >= 100 }.should be_nil
+ end
+ end
- it "returns nil when block condition is never satisfied" do
- @array.bsearch_index { false }.should be_nil
- @array.bsearch_index { |x| x >= 100 }.should be_nil
- end
+ context "find any mode" do
+ before :each do
+ @array = [0, 4, 7, 10, 12]
end
- context "find any mode" do
- before :each do
- @array = [0, 4, 7, 10, 12]
- end
+ it "returns the index of any matched elements where element is between 4 <= x < 8" do
+ [1, 2].should include(@array.bsearch_index { |x| 1 - x / 4 })
+ end
- it "returns the index of any matched elements where element is between 4 <= x < 8" do
- [1, 2].should include(@array.bsearch_index { |x| 1 - x / 4 })
- end
+ it "returns the index of any matched elements where element is between 8 <= x < 10" do
+ @array.bsearch_index { |x| 4 - x / 2 }.should be_nil
+ end
- it "returns the index of any matched elements where element is between 8 <= x < 10" do
- @array.bsearch_index { |x| 4 - x / 2 }.should be_nil
- end
+ it "returns nil when block never returns 0" do
+ @array.bsearch_index { |x| 1 }.should be_nil
+ @array.bsearch_index { |x| -1 }.should be_nil
+ end
- it "returns nil when block never returns 0" do
- @array.bsearch_index { |x| 1 }.should be_nil
- @array.bsearch_index { |x| -1 }.should be_nil
- end
+ it "returns the middle element when block always returns zero" do
+ @array.bsearch_index { |x| 0 }.should == 2
+ end
- it "returns the middle element when block always returns zero" do
- @array.bsearch_index { |x| 0 }.should == 2
+ context "magnitude does not effect the result" do
+ it "returns the index of any matched elements where element is between 4n <= xn < 8n" do
+ [1, 2].should include(@array.bsearch_index { |x| (1 - x / 4) * (2**100) })
end
- context "magnitude does not effect the result" do
- it "returns the index of any matched elements where element is between 4n <= xn < 8n" do
- [1, 2].should include(@array.bsearch_index { |x| (1 - x / 4) * (2**100) })
- end
-
- it "returns nil when block never returns 0" do
- @array.bsearch_index { |x| 1 * (2**100) }.should be_nil
- @array.bsearch_index { |x| (-1) * (2**100) }.should be_nil
- end
+ it "returns nil when block never returns 0" do
+ @array.bsearch_index { |x| 1 * (2**100) }.should be_nil
+ @array.bsearch_index { |x| (-1) * (2**100) }.should be_nil
+ end
- it "handles values from Bignum#coerce" do
- [1, 2].should include(@array.bsearch_index { |x| (2**100).coerce((1 - x / 4) * (2**100)).first })
- end
+ it "handles values from Integer#coerce" do
+ [1, 2].should include(@array.bsearch_index { |x| (2**100).coerce((1 - x / 4) * (2**100)).first })
end
end
end
diff --git a/spec/ruby/core/array/bsearch_spec.rb b/spec/ruby/core/array/bsearch_spec.rb
index 71e945f390..8fa6245dbf 100644
--- a/spec/ruby/core/array/bsearch_spec.rb
+++ b/spec/ruby/core/array/bsearch_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
describe "Array#bsearch" do
it "returns an Enumerator when not passed a block" do
@@ -9,11 +9,11 @@ describe "Array#bsearch" do
it_behaves_like :enumeratorized_with_unknown_size, :bsearch, [1,2,3]
it "raises a TypeError if the block returns an Object" do
- lambda { [1].bsearch { Object.new } }.should raise_error(TypeError)
+ -> { [1].bsearch { Object.new } }.should raise_error(TypeError)
end
it "raises a TypeError if the block returns a String" do
- lambda { [1].bsearch { "1" } }.should raise_error(TypeError)
+ -> { [1].bsearch { "1" } }.should raise_error(TypeError)
end
context "with a block returning true or false" do
diff --git a/spec/ruby/core/array/clear_spec.rb b/spec/ruby/core/array/clear_spec.rb
index 851c90d654..bddc672d3b 100644
--- a/spec/ruby/core/array/clear_spec.rb
+++ b/spec/ruby/core/array/clear_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#clear" do
it "removes all elements" do
@@ -10,40 +10,43 @@ describe "Array#clear" do
it "returns self" do
a = [1]
- oid = a.object_id
- a.clear.object_id.should == oid
+ a.should equal a.clear
end
it "leaves the Array empty" do
a = [1]
a.clear
- a.empty?.should == true
+ a.should.empty?
a.size.should == 0
end
- it "keeps tainted status" do
- a = [1]
- a.taint
- a.tainted?.should be_true
- a.clear
- a.tainted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "keeps tainted status" do
+ a = [1]
+ a.taint
+ a.tainted?.should be_true
+ a.clear
+ a.tainted?.should be_true
+ end
end
it "does not accept any arguments" do
- lambda { [1].clear(true) }.should raise_error(ArgumentError)
+ -> { [1].clear(true) }.should raise_error(ArgumentError)
end
- it "keeps untrusted status" do
- a = [1]
- a.untrust
- a.untrusted?.should be_true
- a.clear
- a.untrusted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "keeps untrusted status" do
+ a = [1]
+ a.untrust
+ a.untrusted?.should be_true
+ a.clear
+ a.untrusted?.should be_true
+ end
end
- it "raises a RuntimeError on a frozen array" do
+ it "raises a FrozenError on a frozen array" do
a = [1]
a.freeze
- lambda { a.clear }.should raise_error(RuntimeError)
+ -> { a.clear }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/clone_spec.rb b/spec/ruby/core/array/clone_spec.rb
index c88e10337f..e22a6c6d53 100644
--- a/spec/ruby/core/array/clone_spec.rb
+++ b/spec/ruby/core/array/clone_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/clone', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/clone'
describe "Array#clone" do
it_behaves_like :array_clone, :clone
@@ -12,8 +12,8 @@ describe "Array#clone" do
aa = a.clone
bb = b.clone
- aa.frozen?.should == true
- bb.frozen?.should == false
+ aa.should.frozen?
+ bb.should_not.frozen?
end
it "copies singleton methods" do
diff --git a/spec/ruby/core/array/collect_spec.rb b/spec/ruby/core/array/collect_spec.rb
index 1c2c28c6bd..0ad4c283b1 100644
--- a/spec/ruby/core/array/collect_spec.rb
+++ b/spec/ruby/core/array/collect_spec.rb
@@ -1,11 +1,11 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/collect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/collect'
describe "Array#collect" do
- it_behaves_like(:array_collect, :collect)
+ it_behaves_like :array_collect, :collect
end
describe "Array#collect!" do
- it_behaves_like(:array_collect_b, :collect!)
+ it_behaves_like :array_collect_b, :collect!
end
diff --git a/spec/ruby/core/array/combination_spec.rb b/spec/ruby/core/array/combination_spec.rb
index 7869783d1e..f16d6f98fc 100644
--- a/spec/ruby/core/array/combination_spec.rb
+++ b/spec/ruby/core/array/combination_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#combination" do
before :each do
@@ -58,7 +58,7 @@ describe "Array#combination" do
@array.combination(-1).size.should == 0
[].combination(-2).size.should == 0
end
- it "returns the binomial coeficient between the array size the number of combinations" do
+ it "returns the binomial coefficient between the array size the number of combinations" do
@array.combination(5).size.should == 0
@array.combination(4).size.should == 1
@array.combination(3).size.should == 4
diff --git a/spec/ruby/core/array/compact_spec.rb b/spec/ruby/core/array/compact_spec.rb
index b80f0214ec..aa3c1c0446 100644
--- a/spec/ruby/core/array/compact_spec.rb
+++ b/spec/ruby/core/array/compact_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#compact" do
it "returns a copy of array with all nil elements removed" do
@@ -22,16 +22,18 @@ describe "Array#compact" do
ArraySpecs::MyArray[1, 2, 3, nil].compact.should be_an_instance_of(Array)
end
- it "does not keep tainted status even if all elements are removed" do
- a = [nil, nil]
- a.taint
- a.compact.tainted?.should be_false
- end
+ ruby_version_is ''...'2.7' do
+ it "does not keep tainted status even if all elements are removed" do
+ a = [nil, nil]
+ a.taint
+ a.compact.tainted?.should be_false
+ end
- it "does not keep untrusted status even if all elements are removed" do
- a = [nil, nil]
- a.untrust
- a.compact.untrusted?.should be_false
+ it "does not keep untrusted status even if all elements are removed" do
+ a = [nil, nil]
+ a.untrust
+ a.compact.untrusted?.should be_false
+ end
end
end
@@ -50,28 +52,30 @@ describe "Array#compact!" do
it "returns self if some nil elements are removed" do
a = ['a', nil, 'b', false, 'c']
- a.compact!.object_id.should == a.object_id
+ a.compact!.should equal a
end
it "returns nil if there are no nil elements to remove" do
[1, 2, false, 3].compact!.should == nil
end
- it "keeps tainted status even if all elements are removed" do
- a = [nil, nil]
- a.taint
- a.compact!
- a.tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "keeps tainted status even if all elements are removed" do
+ a = [nil, nil]
+ a.taint
+ a.compact!
+ a.tainted?.should be_true
+ end
- it "keeps untrusted status even if all elements are removed" do
- a = [nil, nil]
- a.untrust
- a.compact!
- a.untrusted?.should be_true
+ it "keeps untrusted status even if all elements are removed" do
+ a = [nil, nil]
+ a.untrust
+ a.compact!
+ a.untrusted?.should be_true
+ end
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.compact! }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.compact! }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/comparison_spec.rb b/spec/ruby/core/array/comparison_spec.rb
index e5a5f4da10..5d1c3265f1 100644
--- a/spec/ruby/core/array/comparison_spec.rb
+++ b/spec/ruby/core/array/comparison_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#<=>" do
it "calls <=> left to right and return first non-0 result" do
diff --git a/spec/ruby/core/array/concat_spec.rb b/spec/ruby/core/array/concat_spec.rb
index 86ec557bde..da6763bfd6 100644
--- a/spec/ruby/core/array/concat_spec.rb
+++ b/spec/ruby/core/array/concat_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#concat" do
it "returns the array itself" do
@@ -32,69 +32,71 @@ describe "Array#concat" do
[].concat(obj).should == [5, 6, 7]
end
- it "raises a RuntimeError when Array is frozen and modification occurs" do
- lambda { ArraySpecs.frozen_array.concat [1] }.should raise_error(RuntimeError)
+ it "raises a FrozenError when Array is frozen and modification occurs" do
+ -> { ArraySpecs.frozen_array.concat [1] }.should raise_error(FrozenError)
end
# see [ruby-core:23666]
- it "raises a RuntimeError when Array is frozen and no modification occurs" do
- lambda { ArraySpecs.frozen_array.concat([]) }.should raise_error(RuntimeError)
+ it "raises a FrozenError when Array is frozen and no modification occurs" do
+ -> { ArraySpecs.frozen_array.concat([]) }.should raise_error(FrozenError)
end
- it "keeps tainted status" do
- ary = [1, 2]
- ary.taint
- ary.concat([3])
- ary.tainted?.should be_true
- ary.concat([])
- ary.tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "keeps tainted status" do
+ ary = [1, 2]
+ ary.taint
+ ary.concat([3])
+ ary.tainted?.should be_true
+ ary.concat([])
+ ary.tainted?.should be_true
+ end
- it "is not infected by the other" do
- ary = [1,2]
- other = [3]; other.taint
- ary.tainted?.should be_false
- ary.concat(other)
- ary.tainted?.should be_false
- end
+ it "is not infected by the other" do
+ ary = [1,2]
+ other = [3]; other.taint
+ ary.tainted?.should be_false
+ ary.concat(other)
+ ary.tainted?.should be_false
+ end
- it "keeps the tainted status of elements" do
- ary = [ Object.new, Object.new, Object.new ]
- ary.each {|x| x.taint }
+ it "keeps the tainted status of elements" do
+ ary = [ Object.new, Object.new, Object.new ]
+ ary.each {|x| x.taint }
- ary.concat([ Object.new ])
- ary[0].tainted?.should be_true
- ary[1].tainted?.should be_true
- ary[2].tainted?.should be_true
- ary[3].tainted?.should be_false
- end
+ ary.concat([ Object.new ])
+ ary[0].tainted?.should be_true
+ ary[1].tainted?.should be_true
+ ary[2].tainted?.should be_true
+ ary[3].tainted?.should be_false
+ end
- it "keeps untrusted status" do
- ary = [1, 2]
- ary.untrust
- ary.concat([3])
- ary.untrusted?.should be_true
- ary.concat([])
- ary.untrusted?.should be_true
- end
+ it "keeps untrusted status" do
+ ary = [1, 2]
+ ary.untrust
+ ary.concat([3])
+ ary.untrusted?.should be_true
+ ary.concat([])
+ ary.untrusted?.should be_true
+ end
- it "is not infected untrustedness by the other" do
- ary = [1,2]
- other = [3]; other.untrust
- ary.untrusted?.should be_false
- ary.concat(other)
- ary.untrusted?.should be_false
- end
+ it "is not infected untrustedness by the other" do
+ ary = [1,2]
+ other = [3]; other.untrust
+ ary.untrusted?.should be_false
+ ary.concat(other)
+ ary.untrusted?.should be_false
+ end
- it "keeps the untrusted status of elements" do
- ary = [ Object.new, Object.new, Object.new ]
- ary.each {|x| x.untrust }
+ it "keeps the untrusted status of elements" do
+ ary = [ Object.new, Object.new, Object.new ]
+ ary.each {|x| x.untrust }
- ary.concat([ Object.new ])
- ary[0].untrusted?.should be_true
- ary[1].untrusted?.should be_true
- ary[2].untrusted?.should be_true
- ary[3].untrusted?.should be_false
+ ary.concat([ Object.new ])
+ ary[0].untrusted?.should be_true
+ ary[1].untrusted?.should be_true
+ ary[2].untrusted?.should be_true
+ ary[3].untrusted?.should be_false
+ end
end
it "appends elements to an Array with enough capacity that has been shifted" do
@@ -110,23 +112,21 @@ describe "Array#concat" do
ary.concat([5, 6]).should == [4, 5, 6]
end
- ruby_version_is "2.4" do
- it "takes multiple arguments" do
- ary = [1, 2]
- ary.concat [3, 4]
- ary.should == [1, 2, 3, 4]
- end
+ it "takes multiple arguments" do
+ ary = [1, 2]
+ ary.concat [3, 4]
+ ary.should == [1, 2, 3, 4]
+ end
- it "concatenates the initial value when given arguments contain 2 self" do
- ary = [1, 2]
- ary.concat ary, ary
- ary.should == [1, 2, 1, 2, 1, 2]
- end
+ it "concatenates the initial value when given arguments contain 2 self" do
+ ary = [1, 2]
+ ary.concat ary, ary
+ ary.should == [1, 2, 1, 2, 1, 2]
+ end
- it "returns self when given no arguments" do
- ary = [1, 2]
- ary.concat.should equal(ary)
- ary.should == [1, 2]
- end
+ it "returns self when given no arguments" do
+ ary = [1, 2]
+ ary.concat.should equal(ary)
+ ary.should == [1, 2]
end
end
diff --git a/spec/ruby/core/array/constructor_spec.rb b/spec/ruby/core/array/constructor_spec.rb
index 8ec2e5de1e..6f36074c45 100644
--- a/spec/ruby/core/array/constructor_spec.rb
+++ b/spec/ruby/core/array/constructor_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array.[]" do
it "returns a new array populated with the given elements" do
diff --git a/spec/ruby/core/array/count_spec.rb b/spec/ruby/core/array/count_spec.rb
index 52314d8579..eaf275aeb7 100644
--- a/spec/ruby/core/array/count_spec.rb
+++ b/spec/ruby/core/array/count_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#count" do
it "returns the number of elements" do
diff --git a/spec/ruby/core/array/cycle_spec.rb b/spec/ruby/core/array/cycle_spec.rb
index 2e60798c8c..7219b49883 100644
--- a/spec/ruby/core/array/cycle_spec.rb
+++ b/spec/ruby/core/array/cycle_spec.rb
@@ -1,12 +1,12 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
describe "Array#cycle" do
before :each do
ScratchPad.record []
@array = [1, 2, 3]
- @prc = lambda { |x| ScratchPad << x }
+ @prc = -> x { ScratchPad << x }
end
it "does not yield and returns nil when the array is empty and passed value is an integer" do
@@ -46,13 +46,13 @@ describe "Array#cycle" do
end
it "does not rescue StopIteration when not passed a count" do
- lambda do
+ -> do
@array.cycle { raise StopIteration }
end.should raise_error(StopIteration)
end
it "does not rescue StopIteration when passed a count" do
- lambda do
+ -> do
@array.cycle(3) { raise StopIteration }
end.should raise_error(StopIteration)
end
@@ -74,23 +74,23 @@ describe "Array#cycle" do
count = mock("cycle count 2")
count.should_receive(:to_int).and_return("2")
- lambda { @array.cycle(count, &@prc) }.should raise_error(TypeError)
+ -> { @array.cycle(count, &@prc) }.should raise_error(TypeError)
end
it "raises a TypeError if passed a String" do
- lambda { @array.cycle("4") { } }.should raise_error(TypeError)
+ -> { @array.cycle("4") { } }.should raise_error(TypeError)
end
it "raises a TypeError if passed an Object" do
- lambda { @array.cycle(mock("cycle count")) { } }.should raise_error(TypeError)
+ -> { @array.cycle(mock("cycle count")) { } }.should raise_error(TypeError)
end
it "raises a TypeError if passed true" do
- lambda { @array.cycle(true) { } }.should raise_error(TypeError)
+ -> { @array.cycle(true) { } }.should raise_error(TypeError)
end
it "raises a TypeError if passed false" do
- lambda { @array.cycle(false) { } }.should raise_error(TypeError)
+ -> { @array.cycle(false) { } }.should raise_error(TypeError)
end
before :all do
diff --git a/spec/ruby/core/array/deconstruct_spec.rb b/spec/ruby/core/array/deconstruct_spec.rb
new file mode 100644
index 0000000000..2b07152dfc
--- /dev/null
+++ b/spec/ruby/core/array/deconstruct_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "2.7" do
+ describe "Array#deconstruct" do
+ it "returns self" do
+ array = [1]
+
+ array.deconstruct.should equal array
+ end
+ end
+end
diff --git a/spec/ruby/core/array/delete_at_spec.rb b/spec/ruby/core/array/delete_at_spec.rb
index 1d73ceb33a..fc225a03f1 100644
--- a/spec/ruby/core/array/delete_at_spec.rb
+++ b/spec/ruby/core/array/delete_at_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#delete_at" do
it "removes the element at the specified index" do
@@ -35,27 +35,29 @@ describe "Array#delete_at" do
a.delete_at(-2).should == 1
end
- it "raises a RuntimeError on a frozen array" do
- lambda { [1,2,3].freeze.delete_at(0) }.should raise_error(RuntimeError)
- end
-
- it "keeps tainted status" do
- ary = [1, 2]
- ary.taint
- ary.tainted?.should be_true
- ary.delete_at(0)
- ary.tainted?.should be_true
- ary.delete_at(0) # now empty
- ary.tainted?.should be_true
- end
-
- it "keeps untrusted status" do
- ary = [1, 2]
- ary.untrust
- ary.untrusted?.should be_true
- ary.delete_at(0)
- ary.untrusted?.should be_true
- ary.delete_at(0) # now empty
- ary.untrusted?.should be_true
+ it "raises a FrozenError on a frozen array" do
+ -> { [1,2,3].freeze.delete_at(0) }.should raise_error(FrozenError)
+ end
+
+ ruby_version_is ''...'2.7' do
+ it "keeps tainted status" do
+ ary = [1, 2]
+ ary.taint
+ ary.tainted?.should be_true
+ ary.delete_at(0)
+ ary.tainted?.should be_true
+ ary.delete_at(0) # now empty
+ ary.tainted?.should be_true
+ end
+
+ it "keeps untrusted status" do
+ ary = [1, 2]
+ ary.untrust
+ ary.untrusted?.should be_true
+ ary.delete_at(0)
+ ary.untrusted?.should be_true
+ ary.delete_at(0) # now empty
+ ary.untrusted?.should be_true
+ end
end
end
diff --git a/spec/ruby/core/array/delete_if_spec.rb b/spec/ruby/core/array/delete_if_spec.rb
index 4276a1fb65..e1931220f5 100644
--- a/spec/ruby/core/array/delete_if_spec.rb
+++ b/spec/ruby/core/array/delete_if_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorize', __FILE__)
-require File.expand_path('../shared/delete_if', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorize'
+require_relative 'shared/delete_if'
+require_relative '../enumerable/shared/enumeratorized'
describe "Array#delete_if" do
before do
@@ -39,26 +39,28 @@ describe "Array#delete_if" do
@a.freeze.delete_if.should be_an_instance_of(Enumerator)
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.delete_if {} }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.delete_if {} }.should raise_error(FrozenError)
end
- it "raises a RuntimeError on an empty frozen array" do
- lambda { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(RuntimeError)
+ it "raises a FrozenError on an empty frozen array" do
+ -> { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(FrozenError)
end
- it "keeps tainted status" do
- @a.taint
- @a.tainted?.should be_true
- @a.delete_if{ true }
- @a.tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "keeps tainted status" do
+ @a.taint
+ @a.tainted?.should be_true
+ @a.delete_if{ true }
+ @a.tainted?.should be_true
+ end
- it "keeps untrusted status" do
- @a.untrust
- @a.untrusted?.should be_true
- @a.delete_if{ true }
- @a.untrusted?.should be_true
+ it "keeps untrusted status" do
+ @a.untrust
+ @a.untrusted?.should be_true
+ @a.delete_if{ true }
+ @a.untrusted?.should be_true
+ end
end
it_behaves_like :enumeratorized_with_origin_size, :delete_if, [1,2,3]
diff --git a/spec/ruby/core/array/delete_spec.rb b/spec/ruby/core/array/delete_spec.rb
index 7b6bf3930c..5d53c74e47 100644
--- a/spec/ruby/core/array/delete_spec.rb
+++ b/spec/ruby/core/array/delete_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#delete" do
it "removes elements that are #== to object" do
@@ -40,27 +40,29 @@ describe "Array#delete" do
[1, 2, 3].freeze.delete(0).should == nil
end
- it "raises a RuntimeError on a frozen array" do
- lambda { [1, 2, 3].freeze.delete(1) }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { [1, 2, 3].freeze.delete(1) }.should raise_error(FrozenError)
end
- it "keeps tainted status" do
- a = [1, 2]
- a.taint
- a.tainted?.should be_true
- a.delete(2)
- a.tainted?.should be_true
- a.delete(1) # now empty
- a.tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "keeps tainted status" do
+ a = [1, 2]
+ a.taint
+ a.tainted?.should be_true
+ a.delete(2)
+ a.tainted?.should be_true
+ a.delete(1) # now empty
+ a.tainted?.should be_true
+ end
- it "keeps untrusted status" do
- a = [1, 2]
- a.untrust
- a.untrusted?.should be_true
- a.delete(2)
- a.untrusted?.should be_true
- a.delete(1) # now empty
- a.untrusted?.should be_true
+ it "keeps untrusted status" do
+ a = [1, 2]
+ a.untrust
+ a.untrusted?.should be_true
+ a.delete(2)
+ a.untrusted?.should be_true
+ a.delete(1) # now empty
+ a.untrusted?.should be_true
+ end
end
end
diff --git a/spec/ruby/core/array/difference_spec.rb b/spec/ruby/core/array/difference_spec.rb
new file mode 100644
index 0000000000..a357657967
--- /dev/null
+++ b/spec/ruby/core/array/difference_spec.rb
@@ -0,0 +1,24 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/difference'
+
+ruby_version_is "2.6" do
+ describe "Array#difference" do
+ it_behaves_like :array_binary_difference, :difference
+
+ it "returns a copy when called without any parameter" do
+ x = [1, 2, 3, 2]
+ x.difference.should == x
+ x.difference.should_not equal x
+ end
+
+ it "does not return subclass instances for Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].difference.should be_an_instance_of(Array)
+ end
+
+ it "accepts multiple arguments" do
+ x = [1, 2, 3, 1]
+ x.difference([], [0, 1], [3, 4], [3]).should == [2]
+ end
+ end
+end
diff --git a/spec/ruby/core/array/dig_spec.rb b/spec/ruby/core/array/dig_spec.rb
index 9c20b2d160..f2d8ff47fd 100644
--- a/spec/ruby/core/array/dig_spec.rb
+++ b/spec/ruby/core/array/dig_spec.rb
@@ -1,54 +1,52 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-ruby_version_is '2.3' do
- describe "Array#dig" do
-
- it "returns #at with one arg" do
- ['a'].dig(0).should == 'a'
- ['a'].dig(1).should be_nil
- end
-
- it "recurses array elements" do
- a = [ [ 1, [2, '3'] ] ]
- a.dig(0, 0).should == 1
- a.dig(0, 1, 1).should == '3'
- a.dig(0, -1, 0).should == 2
- end
-
- it "returns the nested value specified if the sequence includes a key" do
- a = [42, { foo: :bar }]
- a.dig(1, :foo).should == :bar
- end
-
- it "raises a TypeError for a non-numeric index" do
- lambda {
- ['a'].dig(:first)
- }.should raise_error(TypeError)
- end
-
- it "raises a TypeError if any intermediate step does not respond to #dig" do
- a = [1, 2]
- lambda {
- a.dig(0, 1)
- }.should raise_error(TypeError)
- end
-
- it "raises an ArgumentError if no arguments provided" do
- lambda {
- [10].dig()
- }.should raise_error(ArgumentError)
- end
-
- it "returns nil if any intermediate step is nil" do
- a = [[1, [2, 3]]]
- a.dig(1, 2, 3).should == nil
- end
-
- it "calls #dig on the result of #at with the remaining arguments" do
- h = [[nil, [nil, nil, 42]]]
- h[0].should_receive(:dig).with(1, 2).and_return(42)
- h.dig(0, 1, 2).should == 42
- end
+require_relative '../../spec_helper'
+describe "Array#dig" do
+
+ it "returns #at with one arg" do
+ ['a'].dig(0).should == 'a'
+ ['a'].dig(1).should be_nil
+ end
+
+ it "recurses array elements" do
+ a = [ [ 1, [2, '3'] ] ]
+ a.dig(0, 0).should == 1
+ a.dig(0, 1, 1).should == '3'
+ a.dig(0, -1, 0).should == 2
+ end
+
+ it "returns the nested value specified if the sequence includes a key" do
+ a = [42, { foo: :bar }]
+ a.dig(1, :foo).should == :bar
+ end
+
+ it "raises a TypeError for a non-numeric index" do
+ -> {
+ ['a'].dig(:first)
+ }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError if any intermediate step does not respond to #dig" do
+ a = [1, 2]
+ -> {
+ a.dig(0, 1)
+ }.should raise_error(TypeError)
+ end
+
+ it "raises an ArgumentError if no arguments provided" do
+ -> {
+ [10].dig()
+ }.should raise_error(ArgumentError)
+ end
+
+ it "returns nil if any intermediate step is nil" do
+ a = [[1, [2, 3]]]
+ a.dig(1, 2, 3).should == nil
+ end
+
+ it "calls #dig on the result of #at with the remaining arguments" do
+ h = [[nil, [nil, nil, 42]]]
+ h[0].should_receive(:dig).with(1, 2).and_return(42)
+ h.dig(0, 1, 2).should == 42
end
+
end
diff --git a/spec/ruby/core/array/drop_spec.rb b/spec/ruby/core/array/drop_spec.rb
index 763b45e05a..84ea86b04c 100644
--- a/spec/ruby/core/array/drop_spec.rb
+++ b/spec/ruby/core/array/drop_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#drop" do
it "removes the specified number of elements from the start of the array" do
@@ -6,7 +6,7 @@ describe "Array#drop" do
end
it "raises an ArgumentError if the number of elements specified is negative" do
- lambda { [1, 2].drop(-3) }.should raise_error(ArgumentError)
+ -> { [1, 2].drop(-3) }.should raise_error(ArgumentError)
end
it "returns an empty Array if all elements are dropped" do
@@ -30,4 +30,22 @@ describe "Array#drop" do
ary.shift
ary.drop(1).should == [2]
end
+
+ it "tries to convert the passed argument to an Integer using #to_int" do
+ obj = mock("to_int")
+ obj.should_receive(:to_int).and_return(2)
+
+ [1, 2, 3].drop(obj).should == [3]
+ end
+
+ it "raises a TypeError when the passed argument can't be coerced to Integer" do
+ -> { [1, 2].drop("cat") }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when the passed argument isn't an integer and #to_int returns non-Integer" do
+ obj = mock("to_int")
+ obj.should_receive(:to_int).and_return("cat")
+
+ -> { [1, 2].drop(obj) }.should raise_error(TypeError)
+ end
end
diff --git a/spec/ruby/core/array/drop_while_spec.rb b/spec/ruby/core/array/drop_while_spec.rb
index 40cc29d6b3..cfb6b1e267 100644
--- a/spec/ruby/core/array/drop_while_spec.rb
+++ b/spec/ruby/core/array/drop_while_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#drop_while" do
it "removes elements from the start of the array while the block evaluates to true" do
diff --git a/spec/ruby/core/array/dup_spec.rb b/spec/ruby/core/array/dup_spec.rb
index 01ad12523d..17f467d5fc 100644
--- a/spec/ruby/core/array/dup_spec.rb
+++ b/spec/ruby/core/array/dup_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/clone', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/clone'
describe "Array#dup" do
it_behaves_like :array_clone, :dup # FIX: no, clone and dup are not alike
diff --git a/spec/ruby/core/array/each_index_spec.rb b/spec/ruby/core/array/each_index_spec.rb
index 8872c00f8c..51af5842c4 100644
--- a/spec/ruby/core/array/each_index_spec.rb
+++ b/spec/ruby/core/array/each_index_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorize', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorize'
+require_relative '../enumerable/shared/enumeratorized'
# Modifying a collection while the contents are being iterated
# gives undefined behavior. See
diff --git a/spec/ruby/core/array/each_spec.rb b/spec/ruby/core/array/each_spec.rb
index a8bac6442e..256647d61e 100644
--- a/spec/ruby/core/array/each_spec.rb
+++ b/spec/ruby/core/array/each_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorize', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorize'
+require_relative '../enumerable/shared/enumeratorized'
# Modifying a collection while the contents are being iterated
# gives undefined behavior. See
@@ -27,6 +27,22 @@ describe "Array#each" do
b.should == [2, nil, 4]
end
+ it "yields elements added to the end of the array by the block" do
+ a = [2]
+ iterated = []
+ a.each { |x| iterated << x; x.times { a << 0 } }
+
+ iterated.should == [2, 0, 0]
+ end
+
+ it "does not yield elements deleted from the end of the array" do
+ a = [2, 3, 1]
+ iterated = []
+ a.each { |x| iterated << x; a.delete_at(2) if x == 3 }
+
+ iterated.should == [2, 3]
+ end
+
it_behaves_like :enumeratorize, :each
it_behaves_like :enumeratorized_with_origin_size, :each, [1,2,3]
end
diff --git a/spec/ruby/core/array/element_reference_spec.rb b/spec/ruby/core/array/element_reference_spec.rb
index 55b6b73d1e..31e5578a09 100644
--- a/spec/ruby/core/array/element_reference_spec.rb
+++ b/spec/ruby/core/array/element_reference_spec.rb
@@ -1,9 +1,9 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/slice', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/slice'
describe "Array#[]" do
- it_behaves_like(:array_slice, :[])
+ it_behaves_like :array_slice, :[]
end
describe "Array.[]" do
diff --git a/spec/ruby/core/array/element_set_spec.rb b/spec/ruby/core/array/element_set_spec.rb
index 6544ad9b6f..2e01e838e9 100644
--- a/spec/ruby/core/array/element_set_spec.rb
+++ b/spec/ruby/core/array/element_set_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#[]=" do
it "sets the value of the element at index" do
@@ -94,8 +94,8 @@ describe "Array#[]=" do
it "checks frozen before attempting to coerce arguments" do
a = [1,2,3,4].freeze
- lambda {a[:foo] = 1}.should raise_error(RuntimeError)
- lambda {a[:foo, :bar] = 1}.should raise_error(RuntimeError)
+ -> {a[:foo] = 1}.should raise_error(FrozenError)
+ -> {a[:foo, :bar] = 1}.should raise_error(FrozenError)
end
it "sets elements in the range arguments when passed ranges" do
@@ -195,25 +195,25 @@ describe "Array#[]=" do
a[to .. from] = ["x"]
a.should == [1, "a", "b", "x", "c", 4]
- lambda { a["a" .. "b"] = [] }.should raise_error(TypeError)
- lambda { a[from .. "b"] = [] }.should raise_error(TypeError)
+ -> { a["a" .. "b"] = [] }.should raise_error(TypeError)
+ -> { a[from .. "b"] = [] }.should raise_error(TypeError)
end
it "raises an IndexError when passed indexes out of bounds" do
a = [1, 2, 3, 4]
- lambda { a[-5] = "" }.should raise_error(IndexError)
- lambda { a[-5, -1] = "" }.should raise_error(IndexError)
- lambda { a[-5, 0] = "" }.should raise_error(IndexError)
- lambda { a[-5, 1] = "" }.should raise_error(IndexError)
- lambda { a[-5, 2] = "" }.should raise_error(IndexError)
- lambda { a[-5, 10] = "" }.should raise_error(IndexError)
-
- lambda { a[-5..-5] = "" }.should raise_error(RangeError)
- lambda { a[-5...-5] = "" }.should raise_error(RangeError)
- lambda { a[-5..-4] = "" }.should raise_error(RangeError)
- lambda { a[-5...-4] = "" }.should raise_error(RangeError)
- lambda { a[-5..10] = "" }.should raise_error(RangeError)
- lambda { a[-5...10] = "" }.should raise_error(RangeError)
+ -> { a[-5] = "" }.should raise_error(IndexError)
+ -> { a[-5, -1] = "" }.should raise_error(IndexError)
+ -> { a[-5, 0] = "" }.should raise_error(IndexError)
+ -> { a[-5, 1] = "" }.should raise_error(IndexError)
+ -> { a[-5, 2] = "" }.should raise_error(IndexError)
+ -> { a[-5, 10] = "" }.should raise_error(IndexError)
+
+ -> { a[-5..-5] = "" }.should raise_error(RangeError)
+ -> { a[-5...-5] = "" }.should raise_error(RangeError)
+ -> { a[-5..-4] = "" }.should raise_error(RangeError)
+ -> { a[-5...-4] = "" }.should raise_error(RangeError)
+ -> { a[-5..10] = "" }.should raise_error(RangeError)
+ -> { a[-5...10] = "" }.should raise_error(RangeError)
# ok
a[0..-9] = [1]
@@ -236,8 +236,8 @@ describe "Array#[]=" do
ary.should == [5, 6, 7]
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array[0, 0] = [] }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array[0, 0] = [] }.should raise_error(FrozenError)
end
end
@@ -323,6 +323,10 @@ describe "Array#[]= with [index, count]" do
b = [1, 2, 3, 4, 5]
b[10, 0] = [1]
a.should == [1, 2, 3, 4, 5, nil, nil, nil, nil, nil, 1]
+
+ c = [1, 2, 3, 4, 5]
+ c[10, 0] = []
+ c.should == [1, 2, 3, 4, 5, nil, nil, nil, nil, nil]
end
it "inserts other section in place defined by idx" do
@@ -337,12 +341,12 @@ describe "Array#[]= with [index, count]" do
it "raises an IndexError when passed start and negative length" do
a = [1, 2, 3, 4]
- lambda { a[-2, -1] = "" }.should raise_error(IndexError)
- lambda { a[0, -1] = "" }.should raise_error(IndexError)
- lambda { a[2, -1] = "" }.should raise_error(IndexError)
- lambda { a[4, -1] = "" }.should raise_error(IndexError)
- lambda { a[10, -1] = "" }.should raise_error(IndexError)
- lambda { [1, 2, 3, 4, 5][2, -1] = [7, 8] }.should raise_error(IndexError)
+ -> { a[-2, -1] = "" }.should raise_error(IndexError)
+ -> { a[0, -1] = "" }.should raise_error(IndexError)
+ -> { a[2, -1] = "" }.should raise_error(IndexError)
+ -> { a[4, -1] = "" }.should raise_error(IndexError)
+ -> { a[10, -1] = "" }.should raise_error(IndexError)
+ -> { [1, 2, 3, 4, 5][2, -1] = [7, 8] }.should raise_error(IndexError)
end
end
@@ -350,11 +354,13 @@ describe "Array#[]= with [m..n]" do
it "returns non-array value if non-array value assigned" do
a = [1, 2, 3, 4, 5]
(a[2..4] = 10).should == 10
+ (a.[]=(2..4, 10)).should == 10
end
it "returns array if array assigned" do
a = [1, 2, 3, 4, 5]
(a[2..4] = [7, 8]).should == [7, 8]
+ (a.[]=(2..4, [7, 8])).should == [7, 8]
end
it "just sets the section defined by range to nil even if the rhs is nil" do
@@ -394,15 +400,79 @@ describe "Array#[]= with [m..n]" do
a.should == [1, 2, 3, 8, 4, 5]
end
- it "accepts Range subclasses" do
- a = [1, 2, 3, 4]
- range_incl = ArraySpecs::MyRange.new(1, 2)
- range_excl = ArraySpecs::MyRange.new(-3, -1, true)
+ it "inserts at the end if m > the array size" do
+ a = [1, 2, 3]
+ a[3..3] = [4]
+ a.should == [1, 2, 3, 4]
+ a[5..7] = [6]
+ a.should == [1, 2, 3, 4, nil, 6]
+ end
+
+ describe "Range subclasses" do
+ before :each do
+ @range_incl = ArraySpecs::MyRange.new(1, 2)
+ @range_excl = ArraySpecs::MyRange.new(-3, -1, true)
+ end
+
+ it "accepts Range subclasses" do
+ a = [1, 2, 3, 4]
- a[range_incl] = ["a", "b"]
- a.should == [1, "a", "b", 4]
- a[range_excl] = ["A", "B"]
- a.should == [1, "A", "B", 4]
+ a[@range_incl] = ["a", "b"]
+ a.should == [1, "a", "b", 4]
+ a[@range_excl] = ["A", "B"]
+ a.should == [1, "A", "B", 4]
+ end
+
+ it "returns non-array value if non-array value assigned" do
+ a = [1, 2, 3, 4, 5]
+ (a[@range_incl] = 10).should == 10
+ (a.[]=(@range_incl, 10)).should == 10
+ end
+
+ it "returns array if array assigned" do
+ a = [1, 2, 3, 4, 5]
+ (a[@range_incl] = [7, 8]).should == [7, 8]
+ a.[]=(@range_incl, [7, 8]).should == [7, 8]
+ end
+ end
+end
+
+ruby_version_is "2.6" do
+ describe "Array#[]= with [m..]" do
+
+ it "just sets the section defined by range to nil even if the rhs is nil" do
+ a = [1, 2, 3, 4, 5]
+ a[eval("(2..)")] = nil
+ a.should == [1, 2, nil]
+ end
+
+ it "just sets the section defined by range to nil if m and n < 0 and the rhs is nil" do
+ a = [1, 2, 3, 4, 5]
+ a[eval("(-3..)")] = nil
+ a.should == [1, 2, nil]
+ end
+
+ it "replaces the section defined by range" do
+ a = [6, 5, 4, 3, 2, 1]
+ a[eval("(3...)")] = 9
+ a.should == [6, 5, 4, 9]
+ a[eval("(2..)")] = [7, 7, 7]
+ a.should == [6, 5, 7, 7, 7]
+ end
+
+ it "replaces the section if m and n < 0" do
+ a = [1, 2, 3, 4, 5]
+ a[eval("(-3..)")] = [7, 8, 9]
+ a.should == [1, 2, 7, 8, 9]
+ end
+
+ it "inserts at the end if m > the array size" do
+ a = [1, 2, 3]
+ a[eval("(3..)")] = [4]
+ a.should == [1, 2, 3, 4]
+ a[eval("(5..)")] = [6]
+ a.should == [1, 2, 3, 4, nil, 6]
+ end
end
end
diff --git a/spec/ruby/core/array/empty_spec.rb b/spec/ruby/core/array/empty_spec.rb
index d6235114b7..f70b1b6ebe 100644
--- a/spec/ruby/core/array/empty_spec.rb
+++ b/spec/ruby/core/array/empty_spec.rb
@@ -1,10 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#empty?" do
it "returns true if the array has no elements" do
- [].empty?.should == true
- [1].empty?.should == false
- [1, 2].empty?.should == false
+ [].should.empty?
+ [1].should_not.empty?
+ [1, 2].should_not.empty?
end
end
diff --git a/spec/ruby/core/array/eql_spec.rb b/spec/ruby/core/array/eql_spec.rb
index 7621316e07..8565b94c60 100644
--- a/spec/ruby/core/array/eql_spec.rb
+++ b/spec/ruby/core/array/eql_spec.rb
@@ -1,19 +1,19 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/eql', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/eql'
describe "Array#eql?" do
it_behaves_like :array_eql, :eql?
it "returns false if any corresponding elements are not #eql?" do
- [1, 2, 3, 4].send(@method, [1, 2, 3, 4.0]).should be_false
+ [1, 2, 3, 4].should_not eql([1, 2, 3, 4.0])
end
it "returns false if other is not a kind of Array" do
obj = mock("array eql?")
obj.should_not_receive(:to_ary)
- obj.should_not_receive(@method)
+ obj.should_not_receive(:eql?)
- [1, 2, 3].send(@method, obj).should be_false
+ [1, 2, 3].should_not eql(obj)
end
end
diff --git a/spec/ruby/core/array/equal_value_spec.rb b/spec/ruby/core/array/equal_value_spec.rb
index d923d0e503..a82e07b218 100644
--- a/spec/ruby/core/array/equal_value_spec.rb
+++ b/spec/ruby/core/array/equal_value_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/eql', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/eql'
describe "Array#==" do
it_behaves_like :array_eql, :==
@@ -44,8 +44,8 @@ describe "Array#==" do
[obj].should == [5]
end
- # As per bug #1720
- it "returns false for [NaN] == [NaN]" do
- [nan_value].should_not == [nan_value]
+ # See https://bugs.ruby-lang.org/issues/1720
+ it "returns true for [NaN] == [NaN] because Array#== first checks with #equal? and NaN.equal?(NaN) is true" do
+ [Float::NAN].should == [Float::NAN]
end
end
diff --git a/spec/ruby/core/array/fetch_spec.rb b/spec/ruby/core/array/fetch_spec.rb
index 5adf96fed8..b81c0b48d7 100644
--- a/spec/ruby/core/array/fetch_spec.rb
+++ b/spec/ruby/core/array/fetch_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#fetch" do
it "returns the element at the passed index" do
@@ -12,9 +12,9 @@ describe "Array#fetch" do
end
it "raises an IndexError if there is no element at index" do
- lambda { [1, 2, 3].fetch(3) }.should raise_error(IndexError)
- lambda { [1, 2, 3].fetch(-4) }.should raise_error(IndexError)
- lambda { [].fetch(0) }.should raise_error(IndexError)
+ -> { [1, 2, 3].fetch(3) }.should raise_error(IndexError)
+ -> { [1, 2, 3].fetch(-4) }.should raise_error(IndexError)
+ -> { [].fetch(0) }.should raise_error(IndexError)
end
it "returns default if there is no element at index if passed a default value" do
@@ -37,7 +37,7 @@ describe "Array#fetch" do
end
it "gives precedence to the default block over the default argument" do
- lambda {
+ -> {
@result = [1, 2, 3].fetch(9, :foo) { |i| i * i }
}.should complain(/block supersedes default value argument/)
@result.should == 81
@@ -50,6 +50,6 @@ describe "Array#fetch" do
end
it "raises a TypeError when the passed argument can't be coerced to Integer" do
- lambda { [].fetch("cat") }.should raise_error(TypeError)
+ -> { [].fetch("cat") }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/array/fill_spec.rb b/spec/ruby/core/array/fill_spec.rb
index 5ff7f8a250..6745bc8d09 100644
--- a/spec/ruby/core/array/fill_spec.rb
+++ b/spec/ruby/core/array/fill_spec.rb
@@ -1,9 +1,9 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#fill" do
before :all do
- @never_passed = lambda do |i|
+ @never_passed = -> i do
raise ExpectationNotMetError, "the control path should not pass here"
end
end
@@ -43,34 +43,34 @@ describe "Array#fill" do
[nil, nil, nil, nil].fill { |i| i * 2 }.should == [0, 2, 4, 6]
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.fill('x') }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.fill('x') }.should raise_error(FrozenError)
end
- it "raises a RuntimeError on an empty frozen array" do
- lambda { ArraySpecs.empty_frozen_array.fill('x') }.should raise_error(RuntimeError)
+ it "raises a FrozenError on an empty frozen array" do
+ -> { ArraySpecs.empty_frozen_array.fill('x') }.should raise_error(FrozenError)
end
it "raises an ArgumentError if 4 or more arguments are passed when no block given" do
- lambda { [].fill('a') }.should_not raise_error(ArgumentError)
+ -> { [].fill('a') }.should_not raise_error(ArgumentError)
- lambda { [].fill('a', 1) }.should_not raise_error(ArgumentError)
+ -> { [].fill('a', 1) }.should_not raise_error(ArgumentError)
- lambda { [].fill('a', 1, 2) }.should_not raise_error(ArgumentError)
- lambda { [].fill('a', 1, 2, true) }.should raise_error(ArgumentError)
+ -> { [].fill('a', 1, 2) }.should_not raise_error(ArgumentError)
+ -> { [].fill('a', 1, 2, true) }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if no argument passed and no block given" do
- lambda { [].fill }.should raise_error(ArgumentError)
+ -> { [].fill }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if 3 or more arguments are passed when a block given" do
- lambda { [].fill() {|i|} }.should_not raise_error(ArgumentError)
+ -> { [].fill() {|i|} }.should_not raise_error(ArgumentError)
- lambda { [].fill(1) {|i|} }.should_not raise_error(ArgumentError)
+ -> { [].fill(1) {|i|} }.should_not raise_error(ArgumentError)
- lambda { [].fill(1, 2) {|i|} }.should_not raise_error(ArgumentError)
- lambda { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError)
+ -> { [].fill(1, 2) {|i|} }.should_not raise_error(ArgumentError)
+ -> { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError)
end
end
@@ -171,23 +171,23 @@ describe "Array#fill with (filler, index, length)" do
# See: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17481
it "does not raise an exception if the given length is negative and its absolute value does not exceed the index" do
- lambda { [1, 2, 3, 4].fill('a', 3, -1)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill('a', 3, -2)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill('a', 3, -3)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -1)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -2)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -3)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill(3, -1, &@never_passed)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill(3, -2, &@never_passed)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill(3, -3, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -1, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -2, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -3, &@never_passed)}.should_not raise_error(ArgumentError)
end
it "does not raise an exception even if the given length is negative and its absolute value exceeds the index" do
- lambda { [1, 2, 3, 4].fill('a', 3, -4)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill('a', 3, -5)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill('a', 3, -10000)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -4)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -5)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -10000)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill(3, -4, &@never_passed)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill(3, -5, &@never_passed)}.should_not raise_error(ArgumentError)
- lambda { [1, 2, 3, 4].fill(3, -10000, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -4, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -5, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -10000, &@never_passed)}.should_not raise_error(ArgumentError)
end
it "tries to convert the second and third arguments to Integers using #to_int" do
@@ -199,17 +199,18 @@ describe "Array#fill with (filler, index, length)" do
end
it "raises a TypeError if the index is not numeric" do
- lambda { [].fill 'a', true }.should raise_error(TypeError)
+ -> { [].fill 'a', true }.should raise_error(TypeError)
obj = mock('nonnumeric')
- lambda { [].fill('a', obj) }.should raise_error(TypeError)
+ -> { [].fill('a', obj) }.should raise_error(TypeError)
end
not_supported_on :opal do
it "raises an ArgumentError or RangeError for too-large sizes" do
+ error_types = [RangeError, ArgumentError]
arr = [1, 2, 3]
- lambda { arr.fill(10, 1, fixnum_max) }.should raise_error(ArgumentError)
- lambda { arr.fill(10, 1, bignum_value) }.should raise_error(RangeError)
+ -> { arr.fill(10, 1, fixnum_max) }.should raise_error { |err| error_types.should include(err.class) }
+ -> { arr.fill(10, 1, bignum_value) }.should raise_error(RangeError)
end
end
end
@@ -239,7 +240,7 @@ describe "Array#fill with (filler, range)" do
end
it "raises a TypeError with range and length argument" do
- lambda { [].fill('x', 0 .. 2, 5) }.should raise_error(TypeError)
+ -> { [].fill('x', 0 .. 2, 5) }.should raise_error(TypeError)
end
it "replaces elements between the (-m)th to the last and the (n+1)th from the first if given an range m..n where m < 0 and n >= 0" do
@@ -291,13 +292,13 @@ describe "Array#fill with (filler, range)" do
end
it "raises an exception if some of the given range lies before the first of the array" do
- lambda { [1, 2, 3].fill('x', -5..-3) }.should raise_error(RangeError)
- lambda { [1, 2, 3].fill('x', -5...-3) }.should raise_error(RangeError)
- lambda { [1, 2, 3].fill('x', -5..-4) }.should raise_error(RangeError)
+ -> { [1, 2, 3].fill('x', -5..-3) }.should raise_error(RangeError)
+ -> { [1, 2, 3].fill('x', -5...-3) }.should raise_error(RangeError)
+ -> { [1, 2, 3].fill('x', -5..-4) }.should raise_error(RangeError)
- lambda { [1, 2, 3].fill(-5..-3, &@never_passed) }.should raise_error(RangeError)
- lambda { [1, 2, 3].fill(-5...-3, &@never_passed) }.should raise_error(RangeError)
- lambda { [1, 2, 3].fill(-5..-4, &@never_passed) }.should raise_error(RangeError)
+ -> { [1, 2, 3].fill(-5..-3, &@never_passed) }.should raise_error(RangeError)
+ -> { [1, 2, 3].fill(-5...-3, &@never_passed) }.should raise_error(RangeError)
+ -> { [1, 2, 3].fill(-5..-4, &@never_passed) }.should raise_error(RangeError)
end
it "tries to convert the start and end of the passed range to Integers using #to_int" do
@@ -312,6 +313,15 @@ describe "Array#fill with (filler, range)" do
it "raises a TypeError if the start or end of the passed range is not numeric" do
obj = mock('nonnumeric')
def obj.<=>(rhs); rhs == self ? 0 : nil end
- lambda { [].fill('a', obj..obj) }.should raise_error(TypeError)
+ -> { [].fill('a', obj..obj) }.should raise_error(TypeError)
+ end
+
+ ruby_version_is "2.6" do
+ it "works with endless ranges" do
+ [1, 2, 3, 4].fill('x', eval("(1..)")).should == [1, 'x', 'x', 'x']
+ [1, 2, 3, 4].fill('x', eval("(3...)")).should == [1, 2, 3, 'x']
+ [1, 2, 3, 4].fill(eval("(1..)")) { |x| x + 2 }.should == [1, 3, 4, 5]
+ [1, 2, 3, 4].fill(eval("(3...)")) { |x| x + 2 }.should == [1, 2, 3, 5]
+ end
end
end
diff --git a/spec/ruby/core/array/filter_spec.rb b/spec/ruby/core/array/filter_spec.rb
new file mode 100644
index 0000000000..ee4f71ca28
--- /dev/null
+++ b/spec/ruby/core/array/filter_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+require_relative 'shared/select'
+
+ruby_version_is "2.6" do
+ describe "Array#filter" do
+ it_behaves_like :array_select, :filter
+ end
+
+ describe "Array#filter!" do
+ it "returns nil if no changes were made in the array" do
+ [1, 2, 3].filter! { true }.should be_nil
+ end
+
+ it_behaves_like :keep_if, :filter!
+ end
+end
diff --git a/spec/ruby/core/array/find_index_spec.rb b/spec/ruby/core/array/find_index_spec.rb
index 522b4b31c6..759472024a 100644
--- a/spec/ruby/core/array/find_index_spec.rb
+++ b/spec/ruby/core/array/find_index_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/index', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/index'
describe "Array#find_index" do
it_behaves_like :array_index, :find_index
diff --git a/spec/ruby/core/array/first_spec.rb b/spec/ruby/core/array/first_spec.rb
index 60a0a76594..463da829a2 100644
--- a/spec/ruby/core/array/first_spec.rb
+++ b/spec/ruby/core/array/first_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#first" do
it "returns the first element" do
@@ -30,11 +30,11 @@ describe "Array#first" do
end
it "raises an ArgumentError when count is negative" do
- lambda { [1, 2].first(-1) }.should raise_error(ArgumentError)
+ -> { [1, 2].first(-1) }.should raise_error(ArgumentError)
end
- it "raises a RangeError when count is a Bignum" do
- lambda { [].first(bignum_value) }.should raise_error(RangeError)
+ it "raises a RangeError when count is an Integer" do
+ -> { [].first(bignum_value) }.should raise_error(RangeError)
end
it "returns the entire array when count > length" do
@@ -66,11 +66,11 @@ describe "Array#first" do
end
it "raises a TypeError if the passed argument is not numeric" do
- lambda { [1,2].first(nil) }.should raise_error(TypeError)
- lambda { [1,2].first("a") }.should raise_error(TypeError)
+ -> { [1,2].first(nil) }.should raise_error(TypeError)
+ -> { [1,2].first("a") }.should raise_error(TypeError)
obj = mock("nonnumeric")
- lambda { [1,2].first(obj) }.should raise_error(TypeError)
+ -> { [1,2].first(obj) }.should raise_error(TypeError)
end
it "does not return subclass instance when passed count on Array subclasses" do
diff --git a/spec/ruby/core/array/fixtures/classes.rb b/spec/ruby/core/array/fixtures/classes.rb
index 4292554724..affb3b49e6 100644
--- a/spec/ruby/core/array/fixtures/classes.rb
+++ b/spec/ruby/core/array/fixtures/classes.rb
@@ -2,9 +2,10 @@ class Object
# This helper is defined here rather than in MSpec because
# it is only used in #pack specs.
def pack_format(count=nil, repeat=nil)
- format = "#{instance_variable_get(:@method)}#{count}"
+ format = instance_variable_get(:@method)
+ format += count.to_s unless format == 'P' || format == 'p'
format *= repeat if repeat
- format
+ format.dup # because it may then become tainted
end
end
@@ -13,15 +14,11 @@ module ArraySpecs
SampleCount = 1000
def self.frozen_array
- frozen_array = [1,2,3]
- frozen_array.freeze
- frozen_array
+ [1,2,3].freeze
end
def self.empty_frozen_array
- frozen_array = []
- frozen_array.freeze
- frozen_array
+ [].freeze
end
def self.recursive_array
@@ -84,7 +81,7 @@ module ArraySpecs
end
end
- class ArrayConvertable
+ class ArrayConvertible
attr_accessor :called
def initialize(*values, &block)
@values = values;
@@ -129,7 +126,7 @@ module ArraySpecs
attr_accessor :order
end
- class ComparableWithFixnum
+ class ComparableWithInteger
include Comparable
def initialize(num)
@num = num
@@ -147,7 +144,7 @@ module ArraySpecs
end
def self.universal_pack_object
- obj = mock("string float int")
+ obj = mock("string float int".freeze)
obj.stub!(:to_int).and_return(1)
obj.stub!(:to_str).and_return("1")
obj.stub!(:to_f).and_return(1.0)
@@ -429,7 +426,7 @@ module ArraySpecs
"assert_no_queries",
"test_change_column_quotes_column_names",
"assert_match",
- "test_keeping_default_and_notnull_constaint_on_change",
+ "test_keeping_default_and_notnull_constraint_on_change",
"methods",
"connection_allow_concurrency_setup",
"connection_allow_concurrency_teardown",
@@ -479,7 +476,7 @@ module ArraySpecs
"test_create_table_without_id",
"test_finds_migrations",
"test_finds_pending_migrations",
- "test_keeping_default_and_notnull_constaint_on_change",
+ "test_keeping_default_and_notnull_constraint_on_change",
"test_migrator",
"test_migrator_db_has_no_schema_migrations_table",
"test_migrator_double_down",
diff --git a/spec/ruby/core/array/fixtures/encoded_strings.rb b/spec/ruby/core/array/fixtures/encoded_strings.rb
index e31e247afe..5b85bd0e06 100644
--- a/spec/ruby/core/array/fixtures/encoded_strings.rb
+++ b/spec/ruby/core/array/fixtures/encoded_strings.rb
@@ -37,33 +37,33 @@ module ArraySpecs
]
end
- def self.array_with_utf8_and_7bit_ascii8bit_strings
+ def self.array_with_utf8_and_7bit_binary_strings
[
'bar',
'báz',
- 'foo'.force_encoding('ASCII-8BIT')
+ 'foo'.force_encoding('BINARY')
]
end
- def self.array_with_utf8_and_ascii8bit_strings
+ def self.array_with_utf8_and_binary_strings
[
'bar',
'báz',
- [255].pack('C').force_encoding('ASCII-8BIT')
+ [255].pack('C').force_encoding('BINARY')
]
end
- def self.array_with_usascii_and_7bit_ascii8bit_strings
+ def self.array_with_usascii_and_7bit_binary_strings
[
'bar'.force_encoding('US-ASCII'),
- 'foo'.force_encoding('ASCII-8BIT')
+ 'foo'.force_encoding('BINARY')
]
end
- def self.array_with_usascii_and_ascii8bit_strings
+ def self.array_with_usascii_and_binary_strings
[
'bar'.force_encoding('US-ASCII'),
- [255].pack('C').force_encoding('ASCII-8BIT')
+ [255].pack('C').force_encoding('BINARY')
]
end
end
diff --git a/spec/ruby/core/array/flatten_spec.rb b/spec/ruby/core/array/flatten_spec.rb
index 3b20e976b6..2f9fb8a3ec 100644
--- a/spec/ruby/core/array/flatten_spec.rb
+++ b/spec/ruby/core/array/flatten_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#flatten" do
it "returns a one-dimensional flattening recursively" do
@@ -30,7 +30,7 @@ describe "Array#flatten" do
it "raises a TypeError when the passed Object can't be converted to an Integer" do
obj = mock("Not converted")
- lambda { [ 1, 2, [3, [4, 5] ] ].flatten(obj) }.should raise_error(TypeError)
+ -> { [ 1, 2, [3, [4, 5] ] ].flatten(obj) }.should raise_error(TypeError)
end
it "does not call flatten on elements" do
@@ -46,13 +46,13 @@ describe "Array#flatten" do
it "raises an ArgumentError on recursive arrays" do
x = []
x << x
- lambda { x.flatten }.should raise_error(ArgumentError)
+ -> { x.flatten }.should raise_error(ArgumentError)
x = []
y = []
x << y
y << x
- lambda { x.flatten }.should raise_error(ArgumentError)
+ -> { x.flatten }.should raise_error(ArgumentError)
end
it "flattens any element which responds to #to_ary, using the return value of said method" do
@@ -69,20 +69,30 @@ describe "Array#flatten" do
[1, z, 6].flatten.should == [1, 2, 3, 4, 5, 6]
end
- ruby_version_is "2.3" do
- it "does not call #to_ary on elements beyond the given level" do
- obj = mock("1")
- obj.should_not_receive(:to_ary)
- [[obj]].flatten(1)
+ it "does not call #to_ary on elements beyond the given level" do
+ obj = mock("1")
+ obj.should_not_receive(:to_ary)
+ [[obj]].flatten(1)
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instance for Array subclasses" do
+ ArraySpecs::MyArray[].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+ ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+ ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+ ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == ArraySpecs::MyArray[1, 2, 3, 4]
+ [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
end
end
- it "returns subclass instance for Array subclasses" do
- ArraySpecs::MyArray[].flatten.should be_an_instance_of(ArraySpecs::MyArray)
- ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
- ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
- ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == ArraySpecs::MyArray[1, 2, 3, 4]
- [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+ ruby_version_is '3.0' do
+ it "returns Array instance for Array subclasses" do
+ ArraySpecs::MyArray[].flatten.should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == [1, 2, 3, 4]
+ [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+ end
end
it "is not destructive" do
@@ -108,23 +118,13 @@ describe "Array#flatten" do
it "raises a TypeError if #to_ary does not return an Array" do
@obj.should_receive(:to_ary).and_return(1)
- lambda { [@obj].flatten }.should raise_error(TypeError)
- end
-
- ruby_version_is ""..."2.5" do
- it "calls respond_to_missing?(:to_ary, false) to try coercing" do
- def @obj.respond_to_missing?(*args) ScratchPad << args; false end
- [@obj].flatten.should == [@obj]
- ScratchPad.recorded.should == [[:to_ary, false]]
- end
+ -> { [@obj].flatten }.should raise_error(TypeError)
end
- ruby_version_is "2.5" do
- it "calls respond_to_missing?(:to_ary, true) to try coercing" do
- def @obj.respond_to_missing?(*args) ScratchPad << args; false end
- [@obj].flatten.should == [@obj]
- ScratchPad.recorded.should == [[:to_ary, true]]
- end
+ it "calls respond_to_missing?(:to_ary, true) to try coercing" do
+ def @obj.respond_to_missing?(*args) ScratchPad << args; false end
+ [@obj].flatten.should == [@obj]
+ ScratchPad.recorded.should == [[:to_ary, true]]
end
it "does not call #to_ary if not defined when #respond_to_missing? returns false" do
@@ -137,7 +137,7 @@ describe "Array#flatten" do
it "calls #to_ary if not defined when #respond_to_missing? returns true" do
def @obj.respond_to_missing?(name, priv) ScratchPad << name; true end
- lambda { [@obj].flatten }.should raise_error(NoMethodError)
+ -> { [@obj].flatten }.should raise_error(NoMethodError)
ScratchPad.recorded.should == [:to_ary]
end
@@ -147,12 +147,14 @@ describe "Array#flatten" do
end
end
- it "returns a tainted array if self is tainted" do
- [].taint.flatten.tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "returns a tainted array if self is tainted" do
+ [].taint.flatten.tainted?.should be_true
+ end
- it "returns an untrusted array if self is untrusted" do
- [].untrust.flatten.untrusted?.should be_true
+ it "returns an untrusted array if self is untrusted" do
+ [].untrust.flatten.untrusted?.should be_true
+ end
end
it "performs respond_to? and method_missing-aware checks when coercing elements to array" do
@@ -228,7 +230,7 @@ describe "Array#flatten!" do
it "raises a TypeError when the passed Object can't be converted to an Integer" do
obj = mock("Not converted")
- lambda { [ 1, 2, [3, [4, 5] ] ].flatten!(obj) }.should raise_error(TypeError)
+ -> { [ 1, 2, [3, [4, 5] ] ].flatten!(obj) }.should raise_error(TypeError)
end
it "does not call flatten! on elements" do
@@ -244,13 +246,13 @@ describe "Array#flatten!" do
it "raises an ArgumentError on recursive arrays" do
x = []
x << x
- lambda { x.flatten! }.should raise_error(ArgumentError)
+ -> { x.flatten! }.should raise_error(ArgumentError)
x = []
y = []
x << y
y << x
- lambda { x.flatten! }.should raise_error(ArgumentError)
+ -> { x.flatten! }.should raise_error(ArgumentError)
end
it "flattens any elements which responds to #to_ary, using the return value of said method" do
@@ -272,15 +274,15 @@ describe "Array#flatten!" do
ary.should == [1, 2, 3]
end
- it "raises a RuntimeError on frozen arrays when the array is modified" do
+ it "raises a FrozenError on frozen arrays when the array is modified" do
nested_ary = [1, 2, []]
nested_ary.freeze
- lambda { nested_ary.flatten! }.should raise_error(RuntimeError)
+ -> { nested_ary.flatten! }.should raise_error(FrozenError)
end
# see [ruby-core:23663]
- it "raises a RuntimeError on frozen arrays when the array would not be modified" do
- lambda { ArraySpecs.frozen_array.flatten! }.should raise_error(RuntimeError)
- lambda { ArraySpecs.empty_frozen_array.flatten! }.should raise_error(RuntimeError)
+ it "raises a FrozenError on frozen arrays when the array would not be modified" do
+ -> { ArraySpecs.frozen_array.flatten! }.should raise_error(FrozenError)
+ -> { ArraySpecs.empty_frozen_array.flatten! }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/frozen_spec.rb b/spec/ruby/core/array/frozen_spec.rb
index 6c8384f5f7..3ba54be46b 100644
--- a/spec/ruby/core/array/frozen_spec.rb
+++ b/spec/ruby/core/array/frozen_spec.rb
@@ -1,16 +1,16 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#frozen?" do
it "returns true if array is frozen" do
a = [1, 2, 3]
- a.frozen?.should == false
+ a.should_not.frozen?
a.freeze
- a.frozen?.should == true
+ a.should.frozen?
end
it "returns false for an array being sorted by #sort" do
a = [1, 2, 3]
- a.sort { |x,y| a.frozen?.should == false; x <=> y }
+ a.sort { |x,y| a.should_not.frozen?; x <=> y }
end
end
diff --git a/spec/ruby/core/array/hash_spec.rb b/spec/ruby/core/array/hash_spec.rb
index b576cbbdc6..f3bcc83fce 100644
--- a/spec/ruby/core/array/hash_spec.rb
+++ b/spec/ruby/core/array/hash_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#hash" do
it "returns the same fixnum for arrays with the same content" do
@@ -7,16 +7,16 @@ describe "Array#hash" do
[[], [1, 2, 3]].each do |ary|
ary.hash.should == ary.dup.hash
- ary.hash.should be_an_instance_of(Fixnum)
+ ary.hash.should be_an_instance_of(Integer)
end
end
it "properly handles recursive arrays" do
empty = ArraySpecs.empty_recursive_array
- lambda { empty.hash }.should_not raise_error
+ -> { empty.hash }.should_not raise_error
array = ArraySpecs.recursive_array
- lambda { array.hash }.should_not raise_error
+ -> { array.hash }.should_not raise_error
end
it "returns the same hash for equal recursive arrays" do
diff --git a/spec/ruby/core/array/include_spec.rb b/spec/ruby/core/array/include_spec.rb
index 26d788afeb..227173218f 100644
--- a/spec/ruby/core/array/include_spec.rb
+++ b/spec/ruby/core/array/include_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#include?" do
it "returns true if object is present, false otherwise" do
diff --git a/spec/ruby/core/array/index_spec.rb b/spec/ruby/core/array/index_spec.rb
index 55ed7b2a94..3acb7d0ef3 100644
--- a/spec/ruby/core/array/index_spec.rb
+++ b/spec/ruby/core/array/index_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/index', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/index'
describe "Array#index" do
- it_behaves_like(:array_index, :index)
+ it_behaves_like :array_index, :index
end
diff --git a/spec/ruby/core/array/initialize_spec.rb b/spec/ruby/core/array/initialize_spec.rb
index 0c37c6136d..a8deed2b84 100644
--- a/spec/ruby/core/array/initialize_spec.rb
+++ b/spec/ruby/core/array/initialize_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#initialize" do
before :each do
@@ -24,21 +24,21 @@ describe "Array#initialize" do
end
it "raises an ArgumentError if passed 3 or more arguments" do
- lambda do
+ -> do
[1, 2].send :initialize, 1, 'x', true
end.should raise_error(ArgumentError)
- lambda do
+ -> do
[1, 2].send(:initialize, 1, 'x', true) {}
end.should raise_error(ArgumentError)
end
- it "raises a RuntimeError on frozen arrays" do
- lambda do
+ it "raises a FrozenError on frozen arrays" do
+ -> do
ArraySpecs.frozen_array.send :initialize
- end.should raise_error(RuntimeError)
- lambda do
+ end.should raise_error(FrozenError)
+ -> do
ArraySpecs.frozen_array.send :initialize, ArraySpecs.frozen_array
- end.should raise_error(RuntimeError)
+ end.should raise_error(FrozenError)
end
it "calls #to_ary to convert the value to an array, even if it's private" do
@@ -53,7 +53,7 @@ describe "Array#initialize with no arguments" do
end
it "does not use the given block" do
- lambda{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
+ ->{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
end
end
@@ -64,7 +64,7 @@ describe "Array#initialize with (array)" do
end
it "does not use the given block" do
- lambda{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
+ ->{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
end
it "calls #to_ary to convert the value to an array" do
@@ -81,7 +81,7 @@ describe "Array#initialize with (array)" do
end
it "raises a TypeError if an Array type argument and a default object" do
- lambda { [].send(:initialize, [1, 2], 1) }.should raise_error(TypeError)
+ -> { [].send(:initialize, [1, 2], 1) }.should raise_error(TypeError)
end
end
@@ -103,12 +103,12 @@ describe "Array#initialize with (size, object=nil)" do
end
it "raises an ArgumentError if size is negative" do
- lambda { [].send(:initialize, -1, :a) }.should raise_error(ArgumentError)
- lambda { [].send(:initialize, -1) }.should raise_error(ArgumentError)
+ -> { [].send(:initialize, -1, :a) }.should raise_error(ArgumentError)
+ -> { [].send(:initialize, -1) }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if size is too large" do
- lambda { [].send(:initialize, fixnum_max+1) }.should raise_error(ArgumentError)
+ -> { [].send(:initialize, fixnum_max+1) }.should raise_error(ArgumentError)
end
it "calls #to_int to convert the size argument to an Integer when object is given" do
@@ -126,7 +126,7 @@ describe "Array#initialize with (size, object=nil)" do
it "raises a TypeError if the size argument is not an Integer type" do
obj = mock('nonnumeric')
obj.stub!(:to_ary).and_return([1, 2])
- lambda{ [].send(:initialize, obj, :a) }.should raise_error(TypeError)
+ ->{ [].send(:initialize, obj, :a) }.should raise_error(TypeError)
end
it "yields the index of the element and sets the element to the value of the block" do
@@ -134,7 +134,7 @@ describe "Array#initialize with (size, object=nil)" do
end
it "uses the block value instead of using the default value" do
- lambda {
+ -> {
@result = [].send(:initialize, 3, :obj) { |i| i.to_s }
}.should complain(/block supersedes default value argument/)
@result.should == ['0', '1', '2']
diff --git a/spec/ruby/core/array/insert_spec.rb b/spec/ruby/core/array/insert_spec.rb
index cdf870df2a..9e1757f68b 100644
--- a/spec/ruby/core/array/insert_spec.rb
+++ b/spec/ruby/core/array/insert_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#insert" do
it "returns self" do
@@ -46,8 +46,8 @@ describe "Array#insert" do
end
it "raises an IndexError if the negative index is out of bounds" do
- lambda { [].insert(-2, 1) }.should raise_error(IndexError)
- lambda { [1].insert(-3, 2) }.should raise_error(IndexError)
+ -> { [].insert(-2, 1) }.should raise_error(IndexError)
+ -> { [1].insert(-3, 2) }.should raise_error(IndexError)
end
it "does nothing of no object is passed" do
@@ -64,15 +64,15 @@ describe "Array#insert" do
end
it "raises an ArgumentError if no argument passed" do
- lambda { [].insert() }.should raise_error(ArgumentError)
+ -> { [].insert() }.should raise_error(ArgumentError)
end
- it "raises a RuntimeError on frozen arrays when the array is modified" do
- lambda { ArraySpecs.frozen_array.insert(0, 'x') }.should raise_error(RuntimeError)
+ it "raises a FrozenError on frozen arrays when the array is modified" do
+ -> { ArraySpecs.frozen_array.insert(0, 'x') }.should raise_error(FrozenError)
end
# see [ruby-core:23666]
- it "raises a RuntimeError on frozen arrays when the array would not be modified" do
- lambda { ArraySpecs.frozen_array.insert(0) }.should raise_error(RuntimeError)
+ it "raises a FrozenError on frozen arrays when the array would not be modified" do
+ -> { ArraySpecs.frozen_array.insert(0) }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/inspect_spec.rb b/spec/ruby/core/array/inspect_spec.rb
index 9896406fd5..0832224f5a 100644
--- a/spec/ruby/core/array/inspect_spec.rb
+++ b/spec/ruby/core/array/inspect_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/inspect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/inspect'
describe "Array#inspect" do
it_behaves_like :array_inspect, :inspect
diff --git a/spec/ruby/core/array/intersection_spec.rb b/spec/ruby/core/array/intersection_spec.rb
index 4d6c2a12d3..27d90f1e44 100644
--- a/spec/ruby/core/array/intersection_spec.rb
+++ b/spec/ruby/core/array/intersection_spec.rb
@@ -1,87 +1,21 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/intersection'
describe "Array#&" do
- it "creates an array with elements common to both arrays (intersection)" do
- ([] & []).should == []
- ([1, 2] & []).should == []
- ([] & [1, 2]).should == []
- ([ 1, 3, 5 ] & [ 1, 2, 3 ]).should == [1, 3]
- end
-
- it "creates an array with no duplicates" do
- ([ 1, 1, 3, 5 ] & [ 1, 2, 3 ]).uniq!.should == nil
- end
-
- it "creates an array with elements in order they are first encountered" do
- ([ 1, 2, 3, 2, 5 ] & [ 5, 2, 3, 4 ]).should == [2, 3, 5]
- end
-
- it "does not modify the original Array" do
- a = [1, 1, 3, 5]
- a & [1, 2, 3]
- a.should == [1, 1, 3, 5]
- end
-
- it "properly handles recursive arrays" do
- empty = ArraySpecs.empty_recursive_array
- (empty & empty).should == empty
-
- (ArraySpecs.recursive_array & []).should == []
- ([] & ArraySpecs.recursive_array).should == []
-
- (ArraySpecs.recursive_array & ArraySpecs.recursive_array).should == [1, 'two', 3.0, ArraySpecs.recursive_array]
- end
+ it_behaves_like :array_intersection, :&
+end
- it "tries to convert the passed argument to an Array using #to_ary" do
- obj = mock('[1,2,3]')
- obj.should_receive(:to_ary).and_return([1, 2, 3])
- ([1, 2] & obj).should == ([1, 2])
- end
+ruby_version_is "2.7" do
+ describe "Array#intersection" do
+ it_behaves_like :array_intersection, :intersection
- it "determines equivalence between elements in the sense of eql?" do
- not_supported_on :opal do
- ([5.0, 4.0] & [5, 4]).should == []
+ it "accepts multiple arguments" do
+ [1, 2, 3, 4].intersection([1, 2, 3], [2, 3, 4]).should == [2, 3]
end
- str = "x"
- ([str] & [str.dup]).should == [str]
-
- obj1 = mock('1')
- obj2 = mock('2')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.should_receive(:eql?).at_least(1).and_return(true)
- obj2.should_receive(:eql?).at_least(1).and_return(true)
-
- ([obj1] & [obj2]).should == [obj1]
- ([obj1, obj1, obj2, obj2] & [obj2]).should == [obj1]
-
- obj1 = mock('3')
- obj2 = mock('4')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.should_receive(:eql?).at_least(1).and_return(false)
-
- ([obj1] & [obj2]).should == []
- ([obj1, obj1, obj2, obj2] & [obj2]).should == [obj2]
- end
-
- it "does return subclass instances for Array subclasses" do
- (ArraySpecs::MyArray[1, 2, 3] & []).should be_an_instance_of(Array)
- (ArraySpecs::MyArray[1, 2, 3] & ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
- ([] & ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
- end
-
- it "does not call to_ary on array subclasses" do
- ([5, 6] & ArraySpecs::ToAryArray[1, 2, 5, 6]).should == [5, 6]
- end
-
- it "properly handles an identical item even when its #eql? isn't reflexive" do
- x = mock('x')
- x.stub!(:hash).and_return(42)
- x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
-
- ([x] & [x]).should == [x]
+ it "preserves elements order from original array" do
+ [1, 2, 3, 4].intersection([3, 2, 1]).should == [1, 2, 3]
+ end
end
end
diff --git a/spec/ruby/core/array/join_spec.rb b/spec/ruby/core/array/join_spec.rb
index c4c6277c87..e78ea6f9e1 100644
--- a/spec/ruby/core/array/join_spec.rb
+++ b/spec/ruby/core/array/join_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/join', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/join'
describe "Array#join" do
it_behaves_like :array_join_with_string_separator, :join
@@ -24,11 +24,11 @@ describe "Array#join" do
it "raises a TypeError if the separator cannot be coerced to a String by calling #to_str" do
obj = mock("not a string")
- lambda { [1, 2].join(obj) }.should raise_error(TypeError)
+ -> { [1, 2].join(obj) }.should raise_error(TypeError)
end
it "raises a TypeError if passed false as the separator" do
- lambda { [1, 2].join(false) }.should raise_error(TypeError)
+ -> { [1, 2].join(false) }.should raise_error(TypeError)
end
end
@@ -38,11 +38,13 @@ describe "Array#join with $," do
end
after :each do
- $, = @before_separator
+ suppress_warning {$, = @before_separator}
end
it "separates elements with default separator when the passed separator is nil" do
- $, = "_"
- [1, 2, 3].join(nil).should == '1_2_3'
+ suppress_warning {
+ $, = "_"
+ [1, 2, 3].join(nil).should == '1_2_3'
+ }
end
end
diff --git a/spec/ruby/core/array/keep_if_spec.rb b/spec/ruby/core/array/keep_if_spec.rb
index 2657d5e3b6..bf2bdeaf91 100644
--- a/spec/ruby/core/array/keep_if_spec.rb
+++ b/spec/ruby/core/array/keep_if_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../shared/keep_if', __FILE__)
+require_relative 'shared/keep_if'
describe "Array#keep_if" do
it "returns the same array if no changes were made" do
diff --git a/spec/ruby/core/array/last_spec.rb b/spec/ruby/core/array/last_spec.rb
index c707e3ff7e..d6fefada09 100644
--- a/spec/ruby/core/array/last_spec.rb
+++ b/spec/ruby/core/array/last_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#last" do
it "returns the last element" do
@@ -28,7 +28,7 @@ describe "Array#last" do
end
it "raises an ArgumentError when count is negative" do
- lambda { [1, 2].last(-1) }.should raise_error(ArgumentError)
+ -> { [1, 2].last(-1) }.should raise_error(ArgumentError)
end
it "returns the entire array when count > length" do
@@ -53,18 +53,18 @@ describe "Array#last" do
array.last.should equal(array)
end
- it "tries to convert the passed argument to an Integer usinig #to_int" do
+ it "tries to convert the passed argument to an Integer using #to_int" do
obj = mock('to_int')
obj.should_receive(:to_int).and_return(2)
[1, 2, 3, 4, 5].last(obj).should == [4, 5]
end
it "raises a TypeError if the passed argument is not numeric" do
- lambda { [1,2].last(nil) }.should raise_error(TypeError)
- lambda { [1,2].last("a") }.should raise_error(TypeError)
+ -> { [1,2].last(nil) }.should raise_error(TypeError)
+ -> { [1,2].last("a") }.should raise_error(TypeError)
obj = mock("nonnumeric")
- lambda { [1,2].last(obj) }.should raise_error(TypeError)
+ -> { [1,2].last(obj) }.should raise_error(TypeError)
end
it "does not return subclass instance on Array subclasses" do
diff --git a/spec/ruby/core/array/length_spec.rb b/spec/ruby/core/array/length_spec.rb
index 6f4469dda5..a90c001300 100644
--- a/spec/ruby/core/array/length_spec.rb
+++ b/spec/ruby/core/array/length_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/length', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/length'
describe "Array#length" do
- it_behaves_like(:array_length, :length)
+ it_behaves_like :array_length, :length
end
diff --git a/spec/ruby/core/array/map_spec.rb b/spec/ruby/core/array/map_spec.rb
index c23bb4241a..0c7f3afa8c 100644
--- a/spec/ruby/core/array/map_spec.rb
+++ b/spec/ruby/core/array/map_spec.rb
@@ -1,11 +1,11 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/collect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/collect'
describe "Array#map" do
- it_behaves_like(:array_collect, :map)
+ it_behaves_like :array_collect, :map
end
describe "Array#map!" do
- it_behaves_like(:array_collect_b, :map!)
+ it_behaves_like :array_collect_b, :map!
end
diff --git a/spec/ruby/core/array/max_spec.rb b/spec/ruby/core/array/max_spec.rb
index cf6a48c2e3..d1c64519d0 100644
--- a/spec/ruby/core/array/max_spec.rb
+++ b/spec/ruby/core/array/max_spec.rb
@@ -1,6 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#max" do
+ it "is defined on Array" do
+ [1].method(:max).owner.should equal Array
+ end
+
it "returns nil with no values" do
[].max.should == nil
end
@@ -64,16 +68,16 @@ describe "Array#max" do
end
it "raises a NoMethodError for elements without #<=>" do
- lambda do
+ -> do
[BasicObject.new, BasicObject.new].max
end.should raise_error(NoMethodError)
end
it "raises an ArgumentError for incomparable elements" do
- lambda do
+ -> do
[11,"22"].max
end.should raise_error(ArgumentError)
- lambda do
+ -> do
[11,12,22,33].max{|a, b| nil}
end.should raise_error(ArgumentError)
end
diff --git a/spec/ruby/core/array/min_spec.rb b/spec/ruby/core/array/min_spec.rb
index 53fe4e0692..3bdef0dd00 100644
--- a/spec/ruby/core/array/min_spec.rb
+++ b/spec/ruby/core/array/min_spec.rb
@@ -1,6 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#min" do
+ it "is defined on Array" do
+ [1].method(:max).owner.should equal Array
+ end
+
it "returns nil with no values" do
[].min.should == nil
end
@@ -64,16 +68,16 @@ describe "Array#min" do
end
it "raises a NoMethodError for elements without #<=>" do
- lambda do
+ -> do
[BasicObject.new, BasicObject.new].min
end.should raise_error(NoMethodError)
end
it "raises an ArgumentError for incomparable elements" do
- lambda do
+ -> do
[11,"22"].min
end.should raise_error(ArgumentError)
- lambda do
+ -> do
[11,12,22,33].min{|a, b| nil}
end.should raise_error(ArgumentError)
end
diff --git a/spec/ruby/core/array/minmax_spec.rb b/spec/ruby/core/array/minmax_spec.rb
new file mode 100644
index 0000000000..e11fe63347
--- /dev/null
+++ b/spec/ruby/core/array/minmax_spec.rb
@@ -0,0 +1,14 @@
+require_relative '../../spec_helper'
+require_relative '../../shared/enumerable/minmax'
+
+describe "Array#minmax" do
+ before :each do
+ @enum = [6, 4, 5, 10, 8]
+ @empty_enum = []
+ @incomparable_enum = [BasicObject.new, BasicObject.new]
+ @incompatible_enum = [11, "22"]
+ @strs = ["333", "2", "60", "55555", "1010", "111"]
+ end
+
+ it_behaves_like :enumerable_minmax, :minmax
+end
diff --git a/spec/ruby/core/array/minus_spec.rb b/spec/ruby/core/array/minus_spec.rb
index ffb8d7db06..cb1bf56d76 100644
--- a/spec/ruby/core/array/minus_spec.rb
+++ b/spec/ruby/core/array/minus_spec.rb
@@ -1,87 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/difference'
describe "Array#-" do
- it "creates an array minus any items from other array" do
- ([] - [ 1, 2, 4 ]).should == []
- ([1, 2, 4] - []).should == [1, 2, 4]
- ([ 1, 2, 3, 4, 5 ] - [ 1, 2, 4 ]).should == [3, 5]
- end
-
- it "removes multiple items on the lhs equal to one on the rhs" do
- ([1, 1, 2, 2, 3, 3, 4, 5] - [1, 2, 4]).should == [3, 3, 5]
- end
-
- it "properly handles recursive arrays" do
- empty = ArraySpecs.empty_recursive_array
- (empty - empty).should == []
-
- ([] - ArraySpecs.recursive_array).should == []
-
- array = ArraySpecs.recursive_array
- (array - array).should == []
- end
-
- it "tries to convert the passed arguments to Arrays using #to_ary" do
- obj = mock('[2,3,3,4]')
- obj.should_receive(:to_ary).and_return([2, 3, 3, 4])
- ([1, 1, 2, 2, 3, 4] - obj).should == [1, 1]
- end
-
- it "raises a TypeError if the argument cannot be coerced to an Array by calling #to_ary" do
- obj = mock('not an array')
- lambda { [1, 2, 3] - obj }.should raise_error(TypeError)
- end
-
- it "does not return subclass instance for Array subclasses" do
- (ArraySpecs::MyArray[1, 2, 3] - []).should be_an_instance_of(Array)
- (ArraySpecs::MyArray[1, 2, 3] - ArraySpecs::MyArray[]).should be_an_instance_of(Array)
- ([1, 2, 3] - ArraySpecs::MyArray[]).should be_an_instance_of(Array)
- end
-
- it "does not call to_ary on array subclasses" do
- ([5, 6, 7] - ArraySpecs::ToAryArray[7]).should == [5, 6]
- end
-
- it "removes an item identified as equivalent via #hash and #eql?" do
- obj1 = mock('1')
- obj2 = mock('2')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.should_receive(:eql?).at_least(1).and_return(true)
-
- ([obj1] - [obj2]).should == []
- ([obj1, obj1, obj2, obj2] - [obj2]).should == []
- end
-
- it "doesn't remove an item with the same hash but not #eql?" do
- obj1 = mock('1')
- obj2 = mock('2')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.should_receive(:eql?).at_least(1).and_return(false)
-
- ([obj1] - [obj2]).should == [obj1]
- ([obj1, obj1, obj2, obj2] - [obj2]).should == [obj1, obj1]
- end
-
- it "removes an identical item even when its #eql? isn't reflexive" do
- x = mock('x')
- x.stub!(:hash).and_return(42)
- x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
-
- ([x] - [x]).should == []
- end
-
- it "is not destructive" do
- a = [1, 2, 3]
- a - []
- a.should == [1, 2, 3]
- a - [1]
- a.should == [1, 2, 3]
- a - [1,2,3]
- a.should == [1, 2, 3]
- a - [:a, :b, :c]
- a.should == [1, 2, 3]
- end
+ it_behaves_like :array_binary_difference, :-
end
diff --git a/spec/ruby/core/array/multiply_spec.rb b/spec/ruby/core/array/multiply_spec.rb
index ecd5eba5f7..16e407348b 100644
--- a/spec/ruby/core/array/multiply_spec.rb
+++ b/spec/ruby/core/array/multiply_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/join', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/join'
describe "Array#*" do
it "tries to convert the passed argument to a String using #to_str" do
@@ -17,7 +17,7 @@ describe "Array#*" do
it "raises a TypeError if the argument can neither be converted to a string nor an integer" do
obj = mock('not a string or integer')
- lambda{ [1,2] * obj }.should raise_error(TypeError)
+ ->{ [1,2] * obj }.should raise_error(TypeError)
end
it "converts the passed argument to a String rather than an Integer" do
@@ -28,15 +28,15 @@ describe "Array#*" do
end
it "raises a TypeError is the passed argument is nil" do
- lambda{ [1,2] * nil }.should raise_error(TypeError)
+ ->{ [1,2] * nil }.should raise_error(TypeError)
end
it "raises an ArgumentError when passed 2 or more arguments" do
- lambda{ [1,2].send(:*, 1, 2) }.should raise_error(ArgumentError)
+ ->{ [1,2].send(:*, 1, 2) }.should raise_error(ArgumentError)
end
it "raises an ArgumentError when passed no arguments" do
- lambda{ [1,2].send(:*) }.should raise_error(ArgumentError)
+ ->{ [1,2].send(:*) }.should raise_error(ArgumentError)
end
end
@@ -65,8 +65,8 @@ describe "Array#* with an integer" do
end
it "raises an ArgumentError when passed a negative integer" do
- lambda { [ 1, 2, 3 ] * -1 }.should raise_error(ArgumentError)
- lambda { [] * -1 }.should raise_error(ArgumentError)
+ -> { [ 1, 2, 3 ] * -1 }.should raise_error(ArgumentError)
+ -> { [] * -1 }.should raise_error(ArgumentError)
end
describe "with a subclass of Array" do
@@ -76,10 +76,20 @@ describe "Array#* with an integer" do
@array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
end
- it "returns a subclass instance" do
- (@array * 0).should be_an_instance_of(ArraySpecs::MyArray)
- (@array * 1).should be_an_instance_of(ArraySpecs::MyArray)
- (@array * 2).should be_an_instance_of(ArraySpecs::MyArray)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance" do
+ (@array * 0).should be_an_instance_of(ArraySpecs::MyArray)
+ (@array * 1).should be_an_instance_of(ArraySpecs::MyArray)
+ (@array * 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns an Array instance" do
+ (@array * 0).should be_an_instance_of(Array)
+ (@array * 1).should be_an_instance_of(Array)
+ (@array * 2).should be_an_instance_of(Array)
+ end
end
it "does not call #initialize on the subclass instance" do
@@ -88,42 +98,44 @@ describe "Array#* with an integer" do
end
end
- it "copies the taint status of the original array even if the passed count is 0" do
- ary = [1, 2, 3]
- ary.taint
- (ary * 0).tainted?.should == true
- end
+ ruby_version_is ''...'2.7' do
+ it "copies the taint status of the original array even if the passed count is 0" do
+ ary = [1, 2, 3]
+ ary.taint
+ (ary * 0).should.tainted?
+ end
- it "copies the taint status of the original array even if the array is empty" do
- ary = []
- ary.taint
- (ary * 3).tainted?.should == true
- end
+ it "copies the taint status of the original array even if the array is empty" do
+ ary = []
+ ary.taint
+ (ary * 3).should.tainted?
+ end
- it "copies the taint status of the original array if the passed count is not 0" do
- ary = [1, 2, 3]
- ary.taint
- (ary * 1).tainted?.should == true
- (ary * 2).tainted?.should == true
- end
+ it "copies the taint status of the original array if the passed count is not 0" do
+ ary = [1, 2, 3]
+ ary.taint
+ (ary * 1).should.tainted?
+ (ary * 2).should.tainted?
+ end
- it "copies the untrusted status of the original array even if the passed count is 0" do
- ary = [1, 2, 3]
- ary.untrust
- (ary * 0).untrusted?.should == true
- end
+ it "copies the untrusted status of the original array even if the passed count is 0" do
+ ary = [1, 2, 3]
+ ary.untrust
+ (ary * 0).should.untrusted?
+ end
- it "copies the untrusted status of the original array even if the array is empty" do
- ary = []
- ary.untrust
- (ary * 3).untrusted?.should == true
- end
+ it "copies the untrusted status of the original array even if the array is empty" do
+ ary = []
+ ary.untrust
+ (ary * 3).should.untrusted?
+ end
- it "copies the untrusted status of the original array if the passed count is not 0" do
- ary = [1, 2, 3]
- ary.untrust
- (ary * 1).untrusted?.should == true
- (ary * 2).untrusted?.should == true
+ it "copies the untrusted status of the original array if the passed count is not 0" do
+ ary = [1, 2, 3]
+ ary.untrust
+ (ary * 1).should.untrusted?
+ (ary * 2).should.untrusted?
+ end
end
end
diff --git a/spec/ruby/core/array/new_spec.rb b/spec/ruby/core/array/new_spec.rb
index 4d26024ff2..96ec6b8198 100644
--- a/spec/ruby/core/array/new_spec.rb
+++ b/spec/ruby/core/array/new_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array.new" do
it "returns an instance of Array" do
@@ -11,10 +11,10 @@ describe "Array.new" do
end
it "raises an ArgumentError if passed 3 or more arguments" do
- lambda do
+ -> do
[1, 2].send :initialize, 1, 'x', true
end.should raise_error(ArgumentError)
- lambda do
+ -> do
[1, 2].send(:initialize, 1, 'x', true) {}
end.should raise_error(ArgumentError)
end
@@ -26,7 +26,7 @@ describe "Array.new with no arguments" do
end
it "does not use the given block" do
- lambda{ Array.new { raise } }.should_not raise_error
+ ->{ Array.new { raise } }.should_not raise_error
end
end
@@ -37,7 +37,7 @@ describe "Array.new with (array)" do
end
it "does not use the given block" do
- lambda{ Array.new([1, 2]) { raise } }.should_not raise_error
+ ->{ Array.new([1, 2]) { raise } }.should_not raise_error
end
it "calls #to_ary to convert the value to an array" do
@@ -54,7 +54,7 @@ describe "Array.new with (array)" do
end
it "raises a TypeError if an Array type argument and a default object" do
- lambda { Array.new([1, 2], 1) }.should raise_error(TypeError)
+ -> { Array.new([1, 2], 1) }.should raise_error(TypeError)
end
end
@@ -74,12 +74,12 @@ describe "Array.new with (size, object=nil)" do
end
it "raises an ArgumentError if size is negative" do
- lambda { Array.new(-1, :a) }.should raise_error(ArgumentError)
- lambda { Array.new(-1) }.should raise_error(ArgumentError)
+ -> { Array.new(-1, :a) }.should raise_error(ArgumentError)
+ -> { Array.new(-1) }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if size is too large" do
- lambda { Array.new(fixnum_max+1) }.should raise_error(ArgumentError)
+ -> { Array.new(fixnum_max+1) }.should raise_error(ArgumentError)
end
it "calls #to_int to convert the size argument to an Integer when object is given" do
@@ -97,7 +97,7 @@ describe "Array.new with (size, object=nil)" do
it "raises a TypeError if the size argument is not an Integer type" do
obj = mock('nonnumeric')
obj.stub!(:to_ary).and_return([1, 2])
- lambda{ Array.new(obj, :a) }.should raise_error(TypeError)
+ ->{ Array.new(obj, :a) }.should raise_error(TypeError)
end
it "yields the index of the element and sets the element to the value of the block" do
@@ -105,7 +105,7 @@ describe "Array.new with (size, object=nil)" do
end
it "uses the block value instead of using the default value" do
- lambda {
+ -> {
@result = Array.new(3, :obj) { |i| i.to_s }
}.should complain(/block supersedes default value argument/)
@result.should == ['0', '1', '2']
diff --git a/spec/ruby/core/array/pack/a_spec.rb b/spec/ruby/core/array/pack/a_spec.rb
index e7fbdcd179..7af7a16c68 100644
--- a/spec/ruby/core/array/pack/a_spec.rb
+++ b/spec/ruby/core/array/pack/a_spec.rb
@@ -1,14 +1,16 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/string', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/string'
+require_relative 'shared/taint'
describe "Array#pack with format 'A'" do
it_behaves_like :array_pack_basic, 'A'
it_behaves_like :array_pack_basic_non_float, 'A'
it_behaves_like :array_pack_no_platform, 'A'
it_behaves_like :array_pack_string, 'A'
+ it_behaves_like :array_pack_taint, 'A'
it "adds all the bytes to the output when passed the '*' modifier" do
["abc"].pack("A*").should == "abc"
@@ -36,6 +38,7 @@ describe "Array#pack with format 'a'" do
it_behaves_like :array_pack_basic_non_float, 'a'
it_behaves_like :array_pack_no_platform, 'a'
it_behaves_like :array_pack_string, 'a'
+ it_behaves_like :array_pack_taint, 'a'
it "adds all the bytes to the output when passed the '*' modifier" do
["abc"].pack("a*").should == "abc"
diff --git a/spec/ruby/core/array/pack/at_spec.rb b/spec/ruby/core/array/pack/at_spec.rb
index dd538e8951..3942677913 100644
--- a/spec/ruby/core/array/pack/at_spec.rb
+++ b/spec/ruby/core/array/pack/at_spec.rb
@@ -1,7 +1,7 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
describe "Array#pack with format '@'" do
it_behaves_like :array_pack_basic, '@'
diff --git a/spec/ruby/core/array/pack/b_spec.rb b/spec/ruby/core/array/pack/b_spec.rb
index 62294ab8d1..872c1b88d5 100644
--- a/spec/ruby/core/array/pack/b_spec.rb
+++ b/spec/ruby/core/array/pack/b_spec.rb
@@ -1,14 +1,16 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/encodings', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/encodings'
+require_relative 'shared/taint'
describe "Array#pack with format 'B'" do
it_behaves_like :array_pack_basic, 'B'
it_behaves_like :array_pack_basic_non_float, 'B'
it_behaves_like :array_pack_arguments, 'B'
it_behaves_like :array_pack_hex, 'B'
+ it_behaves_like :array_pack_taint, 'B'
it "calls #to_str to convert an Object to a String" do
obj = mock("pack H string")
@@ -45,8 +47,8 @@ describe "Array#pack with format 'B'" do
].should be_computed_by(:pack, "B*")
end
- it "returns an ASCII-8BIT string" do
- ["1"].pack("B").encoding.should == Encoding::ASCII_8BIT
+ it "returns a binary string" do
+ ["1"].pack("B").encoding.should == Encoding::BINARY
end
it "encodes the string as a sequence of bytes" do
@@ -59,6 +61,7 @@ describe "Array#pack with format 'b'" do
it_behaves_like :array_pack_basic_non_float, 'b'
it_behaves_like :array_pack_arguments, 'b'
it_behaves_like :array_pack_hex, 'b'
+ it_behaves_like :array_pack_taint, 'b'
it "calls #to_str to convert an Object to a String" do
obj = mock("pack H string")
@@ -95,8 +98,8 @@ describe "Array#pack with format 'b'" do
].should be_computed_by(:pack, "b*")
end
- it "returns an ASCII-8BIT string" do
- ["1"].pack("b").encoding.should == Encoding::ASCII_8BIT
+ it "returns a binary string" do
+ ["1"].pack("b").encoding.should == Encoding::BINARY
end
it "encodes the string as a sequence of bytes" do
diff --git a/spec/ruby/core/array/pack/buffer_spec.rb b/spec/ruby/core/array/pack/buffer_spec.rb
new file mode 100644
index 0000000000..ecb40bfd06
--- /dev/null
+++ b/spec/ruby/core/array/pack/buffer_spec.rb
@@ -0,0 +1,50 @@
+# encoding: binary
+
+require_relative '../../../spec_helper'
+
+describe "Array#pack with :buffer option" do
+ it "returns specified buffer" do
+ n = [ 65, 66, 67 ]
+ buffer = " "*3
+ result = n.pack("ccc", buffer: buffer) #=> "ABC"
+ result.should equal(buffer)
+ end
+
+ it "adds result at the end of buffer content" do
+ n = [ 65, 66, 67 ] # result without buffer is "ABC"
+
+ buffer = ""
+ n.pack("ccc", buffer: buffer).should == "ABC"
+
+ buffer = "123"
+ n.pack("ccc", buffer: buffer).should == "123ABC"
+
+ buffer = "12345"
+ n.pack("ccc", buffer: buffer).should == "12345ABC"
+ end
+
+ it "raises TypeError exception if buffer is not String" do
+ -> { [65].pack("ccc", buffer: []) }.should raise_error(
+ TypeError, "buffer must be String, not Array")
+ end
+
+ context "offset (@) is specified" do
+ it 'keeps buffer content if it is longer than offset' do
+ n = [ 65, 66, 67 ]
+ buffer = "123456"
+ n.pack("@3ccc", buffer: buffer).should == "123ABC"
+ end
+
+ it "fills the gap with \\0 if buffer content is shorter than offset" do
+ n = [ 65, 66, 67 ]
+ buffer = "123"
+ n.pack("@6ccc", buffer: buffer).should == "123\0\0\0ABC"
+ end
+
+ it 'does not keep buffer content if it is longer than offset + result' do
+ n = [ 65, 66, 67 ]
+ buffer = "1234567890"
+ n.pack("@3ccc", buffer: buffer).should == "123ABC"
+ end
+ end
+end
diff --git a/spec/ruby/core/array/pack/c_spec.rb b/spec/ruby/core/array/pack/c_spec.rb
index 74afa72f56..7200830331 100644
--- a/spec/ruby/core/array/pack/c_spec.rb
+++ b/spec/ruby/core/array/pack/c_spec.rb
@@ -1,9 +1,9 @@
-# -*- encoding: ascii-8bit -*-
+# -*- encoding: binary -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
describe :array_pack_8bit, shared: true do
it "encodes the least significant eight bits of a positive number" do
diff --git a/spec/ruby/core/array/pack/comment_spec.rb b/spec/ruby/core/array/pack/comment_spec.rb
index 00c5fb6ecd..254c827ccc 100644
--- a/spec/ruby/core/array/pack/comment_spec.rb
+++ b/spec/ruby/core/array/pack/comment_spec.rb
@@ -1,6 +1,6 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
describe "Array#pack" do
it "ignores directives text from '#' to the first newline" do
diff --git a/spec/ruby/core/array/pack/d_spec.rb b/spec/ruby/core/array/pack/d_spec.rb
index 40f28d1e52..8bb3654633 100644
--- a/spec/ruby/core/array/pack/d_spec.rb
+++ b/spec/ruby/core/array/pack/d_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/float', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/float'
describe "Array#pack with format 'D'" do
it_behaves_like :array_pack_basic, 'D'
diff --git a/spec/ruby/core/array/pack/e_spec.rb b/spec/ruby/core/array/pack/e_spec.rb
index 9c6a1b5485..ab61ef578f 100644
--- a/spec/ruby/core/array/pack/e_spec.rb
+++ b/spec/ruby/core/array/pack/e_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/float', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/float'
describe "Array#pack with format 'E'" do
it_behaves_like :array_pack_basic, 'E'
diff --git a/spec/ruby/core/array/pack/empty_spec.rb b/spec/ruby/core/array/pack/empty_spec.rb
index 701e20b0af..d635d6a563 100644
--- a/spec/ruby/core/array/pack/empty_spec.rb
+++ b/spec/ruby/core/array/pack/empty_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Array#pack with empty format" do
it "returns an empty String" do
diff --git a/spec/ruby/core/array/pack/f_spec.rb b/spec/ruby/core/array/pack/f_spec.rb
index 94ce57f34d..d436e0787c 100644
--- a/spec/ruby/core/array/pack/f_spec.rb
+++ b/spec/ruby/core/array/pack/f_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/float', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/float'
describe "Array#pack with format 'F'" do
it_behaves_like :array_pack_basic, 'F'
diff --git a/spec/ruby/core/array/pack/g_spec.rb b/spec/ruby/core/array/pack/g_spec.rb
index a0a902ebbe..83b7f81acc 100644
--- a/spec/ruby/core/array/pack/g_spec.rb
+++ b/spec/ruby/core/array/pack/g_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/float', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/float'
describe "Array#pack with format 'G'" do
it_behaves_like :array_pack_basic, 'G'
diff --git a/spec/ruby/core/array/pack/h_spec.rb b/spec/ruby/core/array/pack/h_spec.rb
index 2412bf57c9..85a875fc8b 100644
--- a/spec/ruby/core/array/pack/h_spec.rb
+++ b/spec/ruby/core/array/pack/h_spec.rb
@@ -1,14 +1,16 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/encodings', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/encodings'
+require_relative 'shared/taint'
describe "Array#pack with format 'H'" do
it_behaves_like :array_pack_basic, 'H'
it_behaves_like :array_pack_basic_non_float, 'H'
it_behaves_like :array_pack_arguments, 'H'
it_behaves_like :array_pack_hex, 'H'
+ it_behaves_like :array_pack_taint, 'H'
it "calls #to_str to convert an Object to a String" do
obj = mock("pack H string")
@@ -95,8 +97,8 @@ describe "Array#pack with format 'H'" do
].should be_computed_by(:pack, "H")
end
- it "returns an ASCII-8BIT string" do
- ["41"].pack("H").encoding.should == Encoding::ASCII_8BIT
+ it "returns a binary string" do
+ ["41"].pack("H").encoding.should == Encoding::BINARY
end
end
@@ -105,6 +107,7 @@ describe "Array#pack with format 'h'" do
it_behaves_like :array_pack_basic_non_float, 'h'
it_behaves_like :array_pack_arguments, 'h'
it_behaves_like :array_pack_hex, 'h'
+ it_behaves_like :array_pack_taint, 'h'
it "calls #to_str to convert an Object to a String" do
obj = mock("pack H string")
@@ -191,7 +194,7 @@ describe "Array#pack with format 'h'" do
].should be_computed_by(:pack, "h")
end
- it "returns an ASCII-8BIT string" do
- ["41"].pack("h").encoding.should == Encoding::ASCII_8BIT
+ it "returns a binary string" do
+ ["41"].pack("h").encoding.should == Encoding::BINARY
end
end
diff --git a/spec/ruby/core/array/pack/i_spec.rb b/spec/ruby/core/array/pack/i_spec.rb
index c22f367a65..a237071227 100644
--- a/spec/ruby/core/array/pack/i_spec.rb
+++ b/spec/ruby/core/array/pack/i_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/integer', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/integer'
describe "Array#pack with format 'I'" do
it_behaves_like :array_pack_basic, 'I'
diff --git a/spec/ruby/core/array/pack/j_spec.rb b/spec/ruby/core/array/pack/j_spec.rb
index 88f074724c..7b62d5efdf 100644
--- a/spec/ruby/core/array/pack/j_spec.rb
+++ b/spec/ruby/core/array/pack/j_spec.rb
@@ -1,222 +1,217 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/integer', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/integer'
+
+platform_is pointer_size: 64 do
+ describe "Array#pack with format 'J'" do
+ it_behaves_like :array_pack_basic, 'J'
+ it_behaves_like :array_pack_basic_non_float, 'J'
+ it_behaves_like :array_pack_arguments, 'J'
+ it_behaves_like :array_pack_numeric_basic, 'J'
+ it_behaves_like :array_pack_integer, 'J'
+ end
-ruby_version_is '2.3' do
- # To handle the special case of x64-mingw32
- pointer_size = RUBY_PLATFORM =~ /\bx64\b/ ? 64 : 1.size * 8
+ describe "Array#pack with format 'j'" do
+ it_behaves_like :array_pack_basic, 'j'
+ it_behaves_like :array_pack_basic_non_float, 'j'
+ it_behaves_like :array_pack_arguments, 'j'
+ it_behaves_like :array_pack_numeric_basic, 'j'
+ it_behaves_like :array_pack_integer, 'j'
+ end
- guard -> { pointer_size == 64 } do
+ little_endian do
describe "Array#pack with format 'J'" do
- it_behaves_like :array_pack_basic, 'J'
- it_behaves_like :array_pack_basic_non_float, 'J'
- it_behaves_like :array_pack_arguments, 'J'
- it_behaves_like :array_pack_numeric_basic, 'J'
- it_behaves_like :array_pack_integer, 'J'
- end
-
- describe "Array#pack with format 'j'" do
- it_behaves_like :array_pack_basic, 'j'
- it_behaves_like :array_pack_basic_non_float, 'j'
- it_behaves_like :array_pack_arguments, 'j'
- it_behaves_like :array_pack_numeric_basic, 'j'
- it_behaves_like :array_pack_integer, 'j'
- end
-
- little_endian do
- describe "Array#pack with format 'J'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_64bit_le, 'J_'
- end
-
- describe "with modifier '!'" do
- it_behaves_like :array_pack_64bit_le, 'J!'
- end
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_64bit_le, 'J_'
end
- describe "Array#pack with format 'j'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_64bit_le, 'j_'
- end
-
- describe "with modifier '!'" do
- it_behaves_like :array_pack_64bit_le, 'j!'
- end
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_64bit_le, 'J!'
end
end
- big_endian do
- describe "Array#pack with format 'J'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_64bit_be, 'J_'
- end
-
- describe "with modifier '!'" do
- it_behaves_like :array_pack_64bit_be, 'J!'
- end
+ describe "Array#pack with format 'j'" do
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_64bit_le, 'j_'
end
- describe "Array#pack with format 'j'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_64bit_be, 'j_'
- end
-
- describe "with modifier '!'" do
- it_behaves_like :array_pack_64bit_be, 'j!'
- end
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_64bit_le, 'j!'
end
end
+ end
+ big_endian do
describe "Array#pack with format 'J'" do
- describe "with modifier '<' and '_'" do
- it_behaves_like :array_pack_64bit_le, 'J<_'
- it_behaves_like :array_pack_64bit_le, 'J_<'
- end
-
- describe "with modifier '<' and '!'" do
- it_behaves_like :array_pack_64bit_le, 'J<!'
- it_behaves_like :array_pack_64bit_le, 'J!<'
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_64bit_be, 'J_'
end
- describe "with modifier '>' and '_'" do
- it_behaves_like :array_pack_64bit_be, 'J>_'
- it_behaves_like :array_pack_64bit_be, 'J_>'
- end
-
- describe "with modifier '>' and '!'" do
- it_behaves_like :array_pack_64bit_be, 'J>!'
- it_behaves_like :array_pack_64bit_be, 'J!>'
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_64bit_be, 'J!'
end
end
describe "Array#pack with format 'j'" do
- describe "with modifier '<' and '_'" do
- it_behaves_like :array_pack_64bit_le, 'j<_'
- it_behaves_like :array_pack_64bit_le, 'j_<'
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_64bit_be, 'j_'
end
- describe "with modifier '<' and '!'" do
- it_behaves_like :array_pack_64bit_le, 'j<!'
- it_behaves_like :array_pack_64bit_le, 'j!<'
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_64bit_be, 'j!'
end
+ end
+ end
- describe "with modifier '>' and '_'" do
- it_behaves_like :array_pack_64bit_be, 'j>_'
- it_behaves_like :array_pack_64bit_be, 'j_>'
- end
+ describe "Array#pack with format 'J'" do
+ describe "with modifier '<' and '_'" do
+ it_behaves_like :array_pack_64bit_le, 'J<_'
+ it_behaves_like :array_pack_64bit_le, 'J_<'
+ end
- describe "with modifier '>' and '!'" do
- it_behaves_like :array_pack_64bit_be, 'j>!'
- it_behaves_like :array_pack_64bit_be, 'j!>'
- end
+ describe "with modifier '<' and '!'" do
+ it_behaves_like :array_pack_64bit_le, 'J<!'
+ it_behaves_like :array_pack_64bit_le, 'J!<'
end
- end
- guard -> { pointer_size == 32 } do
- describe "Array#pack with format 'J'" do
- it_behaves_like :array_pack_basic, 'J'
- it_behaves_like :array_pack_basic_non_float, 'J'
- it_behaves_like :array_pack_arguments, 'J'
- it_behaves_like :array_pack_numeric_basic, 'J'
- it_behaves_like :array_pack_integer, 'J'
+ describe "with modifier '>' and '_'" do
+ it_behaves_like :array_pack_64bit_be, 'J>_'
+ it_behaves_like :array_pack_64bit_be, 'J_>'
end
- describe "Array#pack with format 'j'" do
- it_behaves_like :array_pack_basic, 'j'
- it_behaves_like :array_pack_basic_non_float, 'j'
- it_behaves_like :array_pack_arguments, 'j'
- it_behaves_like :array_pack_numeric_basic, 'j'
- it_behaves_like :array_pack_integer, 'j'
+ describe "with modifier '>' and '!'" do
+ it_behaves_like :array_pack_64bit_be, 'J>!'
+ it_behaves_like :array_pack_64bit_be, 'J!>'
end
+ end
- big_endian do
- describe "Array#pack with format 'J'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_32bit_be, 'J_'
- end
+ describe "Array#pack with format 'j'" do
+ describe "with modifier '<' and '_'" do
+ it_behaves_like :array_pack_64bit_le, 'j<_'
+ it_behaves_like :array_pack_64bit_le, 'j_<'
+ end
- describe "with modifier '!'" do
- it_behaves_like :array_pack_32bit_be, 'J!'
- end
- end
+ describe "with modifier '<' and '!'" do
+ it_behaves_like :array_pack_64bit_le, 'j<!'
+ it_behaves_like :array_pack_64bit_le, 'j!<'
+ end
- describe "Array#pack with format 'j'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_32bit_be, 'j_'
- end
+ describe "with modifier '>' and '_'" do
+ it_behaves_like :array_pack_64bit_be, 'j>_'
+ it_behaves_like :array_pack_64bit_be, 'j_>'
+ end
- describe "with modifier '!'" do
- it_behaves_like :array_pack_32bit_be, 'j!'
- end
- end
+ describe "with modifier '>' and '!'" do
+ it_behaves_like :array_pack_64bit_be, 'j>!'
+ it_behaves_like :array_pack_64bit_be, 'j!>'
end
+ end
+end
- little_endian do
- describe "Array#pack with format 'J'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_32bit_le, 'J_'
- end
+platform_is pointer_size: 32 do
+ describe "Array#pack with format 'J'" do
+ it_behaves_like :array_pack_basic, 'J'
+ it_behaves_like :array_pack_basic_non_float, 'J'
+ it_behaves_like :array_pack_arguments, 'J'
+ it_behaves_like :array_pack_numeric_basic, 'J'
+ it_behaves_like :array_pack_integer, 'J'
+ end
- describe "with modifier '!'" do
- it_behaves_like :array_pack_32bit_le, 'J!'
- end
- end
+ describe "Array#pack with format 'j'" do
+ it_behaves_like :array_pack_basic, 'j'
+ it_behaves_like :array_pack_basic_non_float, 'j'
+ it_behaves_like :array_pack_arguments, 'j'
+ it_behaves_like :array_pack_numeric_basic, 'j'
+ it_behaves_like :array_pack_integer, 'j'
+ end
- describe "Array#pack with format 'j'" do
- describe "with modifier '_'" do
- it_behaves_like :array_pack_32bit_le, 'j_'
- end
+ big_endian do
+ describe "Array#pack with format 'J'" do
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_32bit_be, 'J_'
+ end
- describe "with modifier '!'" do
- it_behaves_like :array_pack_32bit_le, 'j!'
- end
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_32bit_be, 'J!'
end
end
- describe "Array#pack with format 'J'" do
- describe "with modifier '<' and '_'" do
- it_behaves_like :array_pack_32bit_le, 'J<_'
- it_behaves_like :array_pack_32bit_le, 'J_<'
+ describe "Array#pack with format 'j'" do
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_32bit_be, 'j_'
end
- describe "with modifier '<' and '!'" do
- it_behaves_like :array_pack_32bit_le, 'J<!'
- it_behaves_like :array_pack_32bit_le, 'J!<'
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_32bit_be, 'j!'
end
+ end
+ end
- describe "with modifier '>' and '_'" do
- it_behaves_like :array_pack_32bit_be, 'J>_'
- it_behaves_like :array_pack_32bit_be, 'J_>'
+ little_endian do
+ describe "Array#pack with format 'J'" do
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_32bit_le, 'J_'
end
- describe "with modifier '>' and '!'" do
- it_behaves_like :array_pack_32bit_be, 'J>!'
- it_behaves_like :array_pack_32bit_be, 'J!>'
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_32bit_le, 'J!'
end
end
describe "Array#pack with format 'j'" do
- describe "with modifier '<' and '_'" do
- it_behaves_like :array_pack_32bit_le, 'j<_'
- it_behaves_like :array_pack_32bit_le, 'j_<'
+ describe "with modifier '_'" do
+ it_behaves_like :array_pack_32bit_le, 'j_'
end
- describe "with modifier '<' and '!'" do
- it_behaves_like :array_pack_32bit_le, 'j<!'
- it_behaves_like :array_pack_32bit_le, 'j!<'
+ describe "with modifier '!'" do
+ it_behaves_like :array_pack_32bit_le, 'j!'
end
+ end
+ end
- describe "with modifier '>' and '_'" do
- it_behaves_like :array_pack_32bit_be, 'j>_'
- it_behaves_like :array_pack_32bit_be, 'j_>'
- end
+ describe "Array#pack with format 'J'" do
+ describe "with modifier '<' and '_'" do
+ it_behaves_like :array_pack_32bit_le, 'J<_'
+ it_behaves_like :array_pack_32bit_le, 'J_<'
+ end
- describe "with modifier '>' and '!'" do
- it_behaves_like :array_pack_32bit_be, 'j>!'
- it_behaves_like :array_pack_32bit_be, 'j!>'
- end
+ describe "with modifier '<' and '!'" do
+ it_behaves_like :array_pack_32bit_le, 'J<!'
+ it_behaves_like :array_pack_32bit_le, 'J!<'
+ end
+
+ describe "with modifier '>' and '_'" do
+ it_behaves_like :array_pack_32bit_be, 'J>_'
+ it_behaves_like :array_pack_32bit_be, 'J_>'
+ end
+
+ describe "with modifier '>' and '!'" do
+ it_behaves_like :array_pack_32bit_be, 'J>!'
+ it_behaves_like :array_pack_32bit_be, 'J!>'
+ end
+ end
+
+ describe "Array#pack with format 'j'" do
+ describe "with modifier '<' and '_'" do
+ it_behaves_like :array_pack_32bit_le, 'j<_'
+ it_behaves_like :array_pack_32bit_le, 'j_<'
+ end
+
+ describe "with modifier '<' and '!'" do
+ it_behaves_like :array_pack_32bit_le, 'j<!'
+ it_behaves_like :array_pack_32bit_le, 'j!<'
+ end
+
+ describe "with modifier '>' and '_'" do
+ it_behaves_like :array_pack_32bit_be, 'j>_'
+ it_behaves_like :array_pack_32bit_be, 'j_>'
+ end
+
+ describe "with modifier '>' and '!'" do
+ it_behaves_like :array_pack_32bit_be, 'j>!'
+ it_behaves_like :array_pack_32bit_be, 'j!>'
end
end
end
diff --git a/spec/ruby/core/array/pack/l_spec.rb b/spec/ruby/core/array/pack/l_spec.rb
index 5c1ad21d12..b446a7a36a 100644
--- a/spec/ruby/core/array/pack/l_spec.rb
+++ b/spec/ruby/core/array/pack/l_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/integer', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/integer'
describe "Array#pack with format 'L'" do
it_behaves_like :array_pack_basic, 'L'
@@ -29,7 +29,7 @@ describe "Array#pack with format 'L'" do
it_behaves_like :array_pack_32bit_be, 'L>'
end
- guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
+ platform_is wordsize: 32 do
describe "with modifier '<' and '_'" do
it_behaves_like :array_pack_32bit_le, 'L<_'
it_behaves_like :array_pack_32bit_le, 'L_<'
@@ -51,7 +51,7 @@ describe "Array#pack with format 'L'" do
end
end
- guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
+ platform_is wordsize: 64 do
describe "with modifier '<' and '_'" do
it_behaves_like :array_pack_64bit_le, 'L<_'
it_behaves_like :array_pack_64bit_le, 'L_<'
@@ -83,7 +83,7 @@ describe "Array#pack with format 'l'" do
it_behaves_like :array_pack_32bit_be, 'l>'
end
- guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
+ platform_is wordsize: 32 do
describe "with modifier '<' and '_'" do
it_behaves_like :array_pack_32bit_le, 'l<_'
it_behaves_like :array_pack_32bit_le, 'l_<'
@@ -105,7 +105,7 @@ describe "Array#pack with format 'l'" do
end
end
- guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
+ platform_is wordsize: 64 do
describe "with modifier '<' and '_'" do
it_behaves_like :array_pack_64bit_le, 'l<_'
it_behaves_like :array_pack_64bit_le, 'l_<'
@@ -137,7 +137,7 @@ little_endian do
it_behaves_like :array_pack_32bit_le, 'l'
end
- guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
+ platform_is wordsize: 32 do
describe "Array#pack with format 'L' with modifier '_'" do
it_behaves_like :array_pack_32bit_le, 'L_'
end
@@ -155,7 +155,7 @@ little_endian do
end
end
- guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
+ platform_is wordsize: 64 do
describe "Array#pack with format 'L' with modifier '_'" do
it_behaves_like :array_pack_64bit_le, 'L_'
end
@@ -183,7 +183,7 @@ big_endian do
it_behaves_like :array_pack_32bit_be, 'l'
end
- guard -> { platform_is wordsize: 32 or platform_is :mingw32 } do
+ platform_is wordsize: 32 do
describe "Array#pack with format 'L' with modifier '_'" do
it_behaves_like :array_pack_32bit_be, 'L_'
end
@@ -201,7 +201,7 @@ big_endian do
end
end
- guard -> { platform_is wordsize: 64 and platform_is_not :mingw32 } do
+ platform_is wordsize: 64 do
describe "Array#pack with format 'L' with modifier '_'" do
it_behaves_like :array_pack_64bit_be, 'L_'
end
diff --git a/spec/ruby/core/array/pack/m_spec.rb b/spec/ruby/core/array/pack/m_spec.rb
index 36d996cba6..2b1a84abca 100644
--- a/spec/ruby/core/array/pack/m_spec.rb
+++ b/spec/ruby/core/array/pack/m_spec.rb
@@ -1,12 +1,14 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/taint'
describe "Array#pack with format 'M'" do
it_behaves_like :array_pack_basic, 'M'
it_behaves_like :array_pack_basic_non_float, 'M'
it_behaves_like :array_pack_arguments, 'M'
+ it_behaves_like :array_pack_taint, 'M'
it "encodes an empty string as an empty string" do
[""].pack("M").should == ""
@@ -192,6 +194,7 @@ describe "Array#pack with format 'm'" do
it_behaves_like :array_pack_basic, 'm'
it_behaves_like :array_pack_basic_non_float, 'm'
it_behaves_like :array_pack_arguments, 'm'
+ it_behaves_like :array_pack_taint, 'm'
it "encodes an empty string as an empty string" do
[""].pack("m").should == ""
@@ -282,16 +285,16 @@ describe "Array#pack with format 'm'" do
it "raises a TypeError if #to_str does not return a String" do
obj = mock("pack m non-string")
- lambda { [obj].pack("m") }.should raise_error(TypeError)
+ -> { [obj].pack("m") }.should raise_error(TypeError)
end
it "raises a TypeError if passed nil" do
- lambda { [nil].pack("m") }.should raise_error(TypeError)
+ -> { [nil].pack("m") }.should raise_error(TypeError)
end
it "raises a TypeError if passed an Integer" do
- lambda { [0].pack("m") }.should raise_error(TypeError)
- lambda { [bignum_value].pack("m") }.should raise_error(TypeError)
+ -> { [0].pack("m") }.should raise_error(TypeError)
+ -> { [bignum_value].pack("m") }.should raise_error(TypeError)
end
it "does not emit a newline if passed zero as the count modifier" do
diff --git a/spec/ruby/core/array/pack/n_spec.rb b/spec/ruby/core/array/pack/n_spec.rb
index 72a83e082b..ab9409fc1e 100644
--- a/spec/ruby/core/array/pack/n_spec.rb
+++ b/spec/ruby/core/array/pack/n_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/integer', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/integer'
describe "Array#pack with format 'N'" do
it_behaves_like :array_pack_basic, 'N'
diff --git a/spec/ruby/core/array/pack/p_spec.rb b/spec/ruby/core/array/pack/p_spec.rb
index 65a08281e2..d7dff8a4da 100644
--- a/spec/ruby/core/array/pack/p_spec.rb
+++ b/spec/ruby/core/array/pack/p_spec.rb
@@ -1,11 +1,62 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/taint'
describe "Array#pack with format 'P'" do
it_behaves_like :array_pack_basic_non_float, 'P'
+ it_behaves_like :array_pack_taint, 'P'
+
+ it "produces as many bytes as there are in a pointer" do
+ ["hello"].pack("P").size.should == [0].pack("J").size
+ end
+
+ it "round-trips a string through pack and unpack" do
+ ["hello"].pack("P").unpack("P5").should == ["hello"]
+ end
+
+ ruby_version_is ''...'2.7' do
+ it "taints the input string" do
+ input_string = "hello"
+ [input_string].pack("P")
+ input_string.tainted?.should be_true
+ end
+
+ it "does not taint the output string in normal cases" do
+ ["hello"].pack("P").tainted?.should be_false
+ end
+ end
+
+ it "with nil gives a null pointer" do
+ [nil].pack("P").unpack("J").should == [0]
+ end
end
describe "Array#pack with format 'p'" do
it_behaves_like :array_pack_basic_non_float, 'p'
+ it_behaves_like :array_pack_taint, 'p'
+
+ it "produces as many bytes as there are in a pointer" do
+ ["hello"].pack("p").size.should == [0].pack("J").size
+ end
+
+ it "round-trips a string through pack and unpack" do
+ ["hello"].pack("p").unpack("p").should == ["hello"]
+ end
+
+ ruby_version_is ''...'2.7' do
+ it "taints the input string" do
+ input_string = "hello"
+ [input_string].pack("p")
+ input_string.tainted?.should be_true
+ end
+
+ it "does not taint the output string in normal cases" do
+ ["hello"].pack("p").tainted?.should be_false
+ end
+ end
+
+ it "with nil gives a null pointer" do
+ [nil].pack("p").unpack("J").should == [0]
+ end
end
diff --git a/spec/ruby/core/array/pack/percent_spec.rb b/spec/ruby/core/array/pack/percent_spec.rb
index 55d6de3424..5d56dea5fe 100644
--- a/spec/ruby/core/array/pack/percent_spec.rb
+++ b/spec/ruby/core/array/pack/percent_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Array#pack with format '%'" do
it "raises an Argument Error" do
- lambda { [1].pack("%") }.should raise_error(ArgumentError)
+ -> { [1].pack("%") }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/array/pack/q_spec.rb b/spec/ruby/core/array/pack/q_spec.rb
index 83e115c54a..bd6b2a4b71 100644
--- a/spec/ruby/core/array/pack/q_spec.rb
+++ b/spec/ruby/core/array/pack/q_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/integer', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/integer'
describe "Array#pack with format 'Q'" do
it_behaves_like :array_pack_basic, 'Q'
diff --git a/spec/ruby/core/array/pack/s_spec.rb b/spec/ruby/core/array/pack/s_spec.rb
index b2f8cb48f8..4212d6a0b1 100644
--- a/spec/ruby/core/array/pack/s_spec.rb
+++ b/spec/ruby/core/array/pack/s_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/integer', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/integer'
describe "Array#pack with format 'S'" do
it_behaves_like :array_pack_basic, 'S'
diff --git a/spec/ruby/core/array/pack/shared/basic.rb b/spec/ruby/core/array/pack/shared/basic.rb
index 39ab15308d..9061273ad6 100644
--- a/spec/ruby/core/array/pack/shared/basic.rb
+++ b/spec/ruby/core/array/pack/shared/basic.rb
@@ -1,6 +1,6 @@
describe :array_pack_arguments, shared: true do
it "raises an ArgumentError if there are fewer elements than the format requires" do
- lambda { [].pack(pack_format(1)) }.should raise_error(ArgumentError)
+ -> { [].pack(pack_format(1)) }.should raise_error(ArgumentError)
end
end
@@ -10,11 +10,11 @@ describe :array_pack_basic, shared: true do
end
it "raises a TypeError when passed nil" do
- lambda { [@obj].pack(nil) }.should raise_error(TypeError)
+ -> { [@obj].pack(nil) }.should raise_error(TypeError)
end
it "raises a TypeError when passed an Integer" do
- lambda { [@obj].pack(1) }.should raise_error(TypeError)
+ -> { [@obj].pack(1) }.should raise_error(TypeError)
end
end
@@ -33,8 +33,10 @@ describe :array_pack_basic_non_float, shared: true do
[@obj, @obj].pack(d).should be_an_instance_of(String)
end
- it "taints the output string if the format string is tainted" do
- [@obj, @obj].pack("x"+pack_format.taint).tainted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "taints the output string if the format string is tainted" do
+ [@obj, @obj].pack("x"+pack_format.taint).tainted?.should be_true
+ end
end
end
@@ -49,17 +51,19 @@ describe :array_pack_basic_float, shared: true do
[1.2, 4.7].pack(d).should be_an_instance_of(String)
end
- it "taints the output string if the format string is tainted" do
- [3.2, 2.8].pack("x"+pack_format.taint).tainted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "taints the output string if the format string is tainted" do
+ [3.2, 2.8].pack("x"+pack_format.taint).tainted?.should be_true
+ end
end
end
describe :array_pack_no_platform, shared: true do
it "raises ArgumentError when the format modifier is '_'" do
- lambda{ [1].pack(pack_format("_")) }.should raise_error(ArgumentError)
+ ->{ [1].pack(pack_format("_")) }.should raise_error(ArgumentError)
end
it "raises ArgumentError when the format modifier is '!'" do
- lambda{ [1].pack(pack_format("!")) }.should raise_error(ArgumentError)
+ ->{ [1].pack(pack_format("!")) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/array/pack/shared/encodings.rb b/spec/ruby/core/array/pack/shared/encodings.rb
index 3724a5d859..6b7ffac764 100644
--- a/spec/ruby/core/array/pack/shared/encodings.rb
+++ b/spec/ruby/core/array/pack/shared/encodings.rb
@@ -5,12 +5,12 @@ describe :array_pack_hex, shared: true do
it "raises a TypeError if the object does not respond to #to_str" do
obj = mock("pack hex non-string")
- lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
+ -> { [obj].pack(pack_format) }.should raise_error(TypeError)
end
it "raises a TypeError if #to_str does not return a String" do
obj = mock("pack hex non-string")
obj.should_receive(:to_str).and_return(1)
- lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
+ -> { [obj].pack(pack_format) }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/array/pack/shared/float.rb b/spec/ruby/core/array/pack/shared/float.rb
index 082de27acd..c6b194007f 100644
--- a/spec/ruby/core/array/pack/shared/float.rb
+++ b/spec/ruby/core/array/pack/shared/float.rb
@@ -1,4 +1,4 @@
-# -*- encoding: ascii-8bit -*-
+# -*- encoding: binary -*-
describe :array_pack_float_le, shared: true do
it "encodes a positive Float" do
@@ -14,7 +14,7 @@ describe :array_pack_float_le, shared: true do
end
it "raises a TypeError if passed a String representation of a floating point number" do
- lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
+ -> { ["13"].pack(pack_format) }.should raise_error(TypeError)
end
it "encodes the number of array elements specified by the count modifier" do
@@ -41,16 +41,9 @@ describe :array_pack_float_le, shared: true do
[-infinity_value].pack(pack_format).should == "\x00\x00\x80\xff"
end
- platform_is "86" do # x86 / x86_64
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\x00\x00\xc0\xff"
- end
- end
-
- platform_is "powerpc64" do
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\x00\x00\xc0\x7f"
- end
+ it "encodes NaN" do
+ nans = ["\x00\x00\xc0\xff", "\x00\x00\xc0\x7f", "\xFF\xFF\xFF\x7F"]
+ nans.should include([nan_value].pack(pack_format))
end
it "encodes a positive Float outside the range of a single precision float" do
@@ -76,7 +69,7 @@ describe :array_pack_float_be, shared: true do
end
it "raises a TypeError if passed a String representation of a floating point number" do
- lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
+ -> { ["13"].pack(pack_format) }.should raise_error(TypeError)
end
it "encodes the number of array elements specified by the count modifier" do
@@ -103,16 +96,9 @@ describe :array_pack_float_be, shared: true do
[-infinity_value].pack(pack_format).should == "\xff\x80\x00\x00"
end
- platform_is "86" do # x86 / x86_64
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\xff\xc0\x00\x00"
- end
- end
-
- platform_is "powerpc64" do
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\x7f\xc0\x00\x00"
- end
+ it "encodes NaN" do
+ nans = ["\xff\xc0\x00\x00", "\x7f\xc0\x00\x00", "\x7F\xFF\xFF\xFF"]
+ nans.should include([nan_value].pack(pack_format))
end
it "encodes a positive Float outside the range of a single precision float" do
@@ -138,7 +124,7 @@ describe :array_pack_double_le, shared: true do
end
it "raises a TypeError if passed a String representation of a floating point number" do
- lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
+ -> { ["13"].pack(pack_format) }.should raise_error(TypeError)
end
it "encodes the number of array elements specified by the count modifier" do
@@ -165,16 +151,13 @@ describe :array_pack_double_le, shared: true do
[-infinity_value].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\xf0\xff"
end
- platform_is "86" do # x86 / x86_64
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\xf8\xff"
- end
- end
-
- platform_is "powerpc64" do
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\x00\x00\x00\x00\x00\x00\xf8\x7f"
- end
+ it "encodes NaN" do
+ nans = [
+ "\x00\x00\x00\x00\x00\x00\xf8\xff",
+ "\x00\x00\x00\x00\x00\x00\xf8\x7f",
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F"
+ ]
+ nans.should include([nan_value].pack(pack_format))
end
it "encodes a positive Float outside the range of a single precision float" do
@@ -200,7 +183,7 @@ describe :array_pack_double_be, shared: true do
end
it "raises a TypeError if passed a String representation of a floating point number" do
- lambda { ["13"].pack(pack_format) }.should raise_error(TypeError)
+ -> { ["13"].pack(pack_format) }.should raise_error(TypeError)
end
it "encodes the number of array elements specified by the count modifier" do
@@ -227,16 +210,13 @@ describe :array_pack_double_be, shared: true do
[-infinity_value].pack(pack_format).should == "\xff\xf0\x00\x00\x00\x00\x00\x00"
end
- platform_is "86" do # x86 / x86_64
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\xff\xf8\x00\x00\x00\x00\x00\x00"
- end
- end
-
- platform_is "powerpc64" do
- it "encodes NaN" do
- [nan_value].pack(pack_format).should == "\x7f\xf8\x00\x00\x00\x00\x00\x00"
- end
+ it "encodes NaN" do
+ nans = [
+ "\xff\xf8\x00\x00\x00\x00\x00\x00",
+ "\x7f\xf8\x00\x00\x00\x00\x00\x00",
+ "\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ ]
+ nans.should include([nan_value].pack(pack_format))
end
it "encodes a positive Float outside the range of a single precision float" do
diff --git a/spec/ruby/core/array/pack/shared/integer.rb b/spec/ruby/core/array/pack/shared/integer.rb
index 0df03bbfd1..6592f85022 100644
--- a/spec/ruby/core/array/pack/shared/integer.rb
+++ b/spec/ruby/core/array/pack/shared/integer.rb
@@ -1,4 +1,4 @@
-# -*- encoding: ascii-8bit -*-
+# -*- encoding: binary -*-
describe :array_pack_16bit_le, shared: true do
it "encodes the least significant 16 bits of a positive number" do
diff --git a/spec/ruby/core/array/pack/shared/numeric_basic.rb b/spec/ruby/core/array/pack/shared/numeric_basic.rb
index 9224d6080e..7c36ba4a32 100644
--- a/spec/ruby/core/array/pack/shared/numeric_basic.rb
+++ b/spec/ruby/core/array/pack/shared/numeric_basic.rb
@@ -4,41 +4,41 @@ describe :array_pack_numeric_basic, shared: true do
end
it "raises a TypeError when passed nil" do
- lambda { [nil].pack(pack_format) }.should raise_error(TypeError)
+ -> { [nil].pack(pack_format) }.should raise_error(TypeError)
end
it "raises a TypeError when passed true" do
- lambda { [true].pack(pack_format) }.should raise_error(TypeError)
+ -> { [true].pack(pack_format) }.should raise_error(TypeError)
end
it "raises a TypeError when passed false" do
- lambda { [false].pack(pack_format) }.should raise_error(TypeError)
+ -> { [false].pack(pack_format) }.should raise_error(TypeError)
end
- it "returns an ASCII-8BIT string" do
- [0xFF].pack(pack_format).encoding.should == Encoding::ASCII_8BIT
- [0xE3, 0x81, 0x82].pack(pack_format(3)).encoding.should == Encoding::ASCII_8BIT
+ it "returns a binary string" do
+ [0xFF].pack(pack_format).encoding.should == Encoding::BINARY
+ [0xE3, 0x81, 0x82].pack(pack_format(3)).encoding.should == Encoding::BINARY
end
end
describe :array_pack_integer, shared: true do
it "raises a TypeError when the object does not respond to #to_int" do
obj = mock('not an integer')
- lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
+ -> { [obj].pack(pack_format) }.should raise_error(TypeError)
end
it "raises a TypeError when passed a String" do
- lambda { ["5"].pack(pack_format) }.should raise_error(TypeError)
+ -> { ["5"].pack(pack_format) }.should raise_error(TypeError)
end
end
describe :array_pack_float, shared: true do
it "raises a TypeError if a String does not represent a floating point number" do
- lambda { ["a"].pack(pack_format) }.should raise_error(TypeError)
+ -> { ["a"].pack(pack_format) }.should raise_error(TypeError)
end
it "raises a TypeError when the object does not respond to #to_f" do
obj = mock('not an float')
- lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
+ -> { [obj].pack(pack_format) }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/array/pack/shared/string.rb b/spec/ruby/core/array/pack/shared/string.rb
index cedb0886e2..8c82e8c617 100644
--- a/spec/ruby/core/array/pack/shared/string.rb
+++ b/spec/ruby/core/array/pack/shared/string.rb
@@ -17,11 +17,11 @@ describe :array_pack_string, shared: true do
end
it "raises an ArgumentError when the Array is empty" do
- lambda { [].pack(pack_format) }.should raise_error(ArgumentError)
+ -> { [].pack(pack_format) }.should raise_error(ArgumentError)
end
it "raises an ArgumentError when the Array has too few elements" do
- lambda { ["a"].pack(pack_format(nil, 2)) }.should raise_error(ArgumentError)
+ -> { ["a"].pack(pack_format(nil, 2)) }.should raise_error(ArgumentError)
end
it "calls #to_str to convert the element to a String" do
@@ -33,48 +33,16 @@ describe :array_pack_string, shared: true do
it "raises a TypeError when the object does not respond to #to_str" do
obj = mock("not a string")
- lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
- end
-
- it "returns a tainted string when a pack argument is tainted" do
- ["abcd".taint, 0x20].pack(pack_format("3C")).tainted?.should be_true
- end
-
- it "does not return a tainted string when the array is tainted" do
- ["abcd", 0x20].taint.pack(pack_format("3C")).tainted?.should be_false
- end
-
- it "returns a tainted string when the format is tainted" do
- ["abcd", 0x20].pack(pack_format("3C").taint).tainted?.should be_true
- end
-
- it "returns a tainted string when an empty format is tainted" do
- ["abcd", 0x20].pack("".taint).tainted?.should be_true
- end
-
- it "returns a untrusted string when the format is untrusted" do
- ["abcd", 0x20].pack(pack_format("3C").untrust).untrusted?.should be_true
- end
-
- it "returns a untrusted string when the empty format is untrusted" do
- ["abcd", 0x20].pack("".untrust).untrusted?.should be_true
- end
-
- it "returns a untrusted string when a pack argument is untrusted" do
- ["abcd".untrust, 0x20].pack(pack_format("3C")).untrusted?.should be_true
- end
-
- it "returns a trusted string when the array is untrusted" do
- ["abcd", 0x20].untrust.pack(pack_format("3C")).untrusted?.should be_false
+ -> { [obj].pack(pack_format) }.should raise_error(TypeError)
end
it "returns a string in encoding of common to the concatenated results" do
f = pack_format("*")
- [ [["\u{3042 3044 3046 3048}", 0x2000B].pack(f+"U"), Encoding::ASCII_8BIT],
- [["abcde\xd1", "\xFF\xFe\x81\x82"].pack(f+"u"), Encoding::ASCII_8BIT],
- [["a".force_encoding("ascii"), "\xFF\xFe\x81\x82"].pack(f+"u"), Encoding::ASCII_8BIT],
+ [ [["\u{3042 3044 3046 3048}", 0x2000B].pack(f+"U"), Encoding::BINARY],
+ [["abcde\xd1", "\xFF\xFe\x81\x82"].pack(f+"u"), Encoding::BINARY],
+ [["a".force_encoding("ascii"), "\xFF\xFe\x81\x82"].pack(f+"u"), Encoding::BINARY],
# under discussion [ruby-dev:37294]
- [["\u{3042 3044 3046 3048}", 1].pack(f+"N"), Encoding::ASCII_8BIT]
+ [["\u{3042 3044 3046 3048}", 1].pack(f+"N"), Encoding::BINARY]
].should be_computed_by(:encoding)
end
end
diff --git a/spec/ruby/core/array/pack/shared/taint.rb b/spec/ruby/core/array/pack/shared/taint.rb
new file mode 100644
index 0000000000..565f04b8b9
--- /dev/null
+++ b/spec/ruby/core/array/pack/shared/taint.rb
@@ -0,0 +1,35 @@
+describe :array_pack_taint, shared: true do
+ ruby_version_is ''...'2.7' do
+ it "returns a tainted string when a pack argument is tainted" do
+ ["abcd".taint, 0x20].pack(pack_format("3C")).tainted?.should be_true
+ end
+
+ it "does not return a tainted string when the array is tainted" do
+ ["abcd", 0x20].taint.pack(pack_format("3C")).tainted?.should be_false
+ end
+
+ it "returns a tainted string when the format is tainted" do
+ ["abcd", 0x20].pack(pack_format("3C").taint).tainted?.should be_true
+ end
+
+ it "returns a tainted string when an empty format is tainted" do
+ ["abcd", 0x20].pack("".taint).tainted?.should be_true
+ end
+
+ it "returns a untrusted string when the format is untrusted" do
+ ["abcd", 0x20].pack(pack_format("3C").untrust).untrusted?.should be_true
+ end
+
+ it "returns a untrusted string when the empty format is untrusted" do
+ ["abcd", 0x20].pack("".untrust).untrusted?.should be_true
+ end
+
+ it "returns a untrusted string when a pack argument is untrusted" do
+ ["abcd".untrust, 0x20].pack(pack_format("3C")).untrusted?.should be_true
+ end
+
+ it "returns a trusted string when the array is untrusted" do
+ ["abcd", 0x20].untrust.pack(pack_format("3C")).untrusted?.should be_false
+ end
+ end
+end
diff --git a/spec/ruby/core/array/pack/shared/unicode.rb b/spec/ruby/core/array/pack/shared/unicode.rb
index e16110c491..dd0f8b38aa 100644
--- a/spec/ruby/core/array/pack/shared/unicode.rb
+++ b/spec/ruby/core/array/pack/shared/unicode.rb
@@ -64,7 +64,7 @@ describe :array_pack_unicode, shared: true do
it "raises a TypeError if #to_int does not return an Integer" do
obj = mock('to_int')
obj.should_receive(:to_int).and_return("5")
- lambda { [obj].pack("U") }.should raise_error(TypeError)
+ -> { [obj].pack("U") }.should raise_error(TypeError)
end
it "ignores NULL bytes between directives" do
@@ -76,11 +76,11 @@ describe :array_pack_unicode, shared: true do
end
it "raises a RangeError if passed a negative number" do
- lambda { [-1].pack("U") }.should raise_error(RangeError)
+ -> { [-1].pack("U") }.should raise_error(RangeError)
end
it "raises a RangeError if passed a number larger than an unsigned 32-bit integer" do
- lambda { [2**32].pack("U") }.should raise_error(RangeError)
+ -> { [2**32].pack("U") }.should raise_error(RangeError)
end
it "sets the output string to UTF-8 encoding" do
diff --git a/spec/ruby/core/array/pack/u_spec.rb b/spec/ruby/core/array/pack/u_spec.rb
index 0bc78fcb88..fe969cbb2d 100644
--- a/spec/ruby/core/array/pack/u_spec.rb
+++ b/spec/ruby/core/array/pack/u_spec.rb
@@ -1,8 +1,9 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/unicode', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/unicode'
+require_relative 'shared/taint'
describe "Array#pack with format 'U'" do
it_behaves_like :array_pack_basic, 'U'
@@ -15,6 +16,7 @@ describe "Array#pack with format 'u'" do
it_behaves_like :array_pack_basic, 'u'
it_behaves_like :array_pack_basic_non_float, 'u'
it_behaves_like :array_pack_arguments, 'u'
+ it_behaves_like :array_pack_taint, 'u'
it "encodes an empty string as an empty string" do
[""].pack("u").should == ""
@@ -110,16 +112,16 @@ describe "Array#pack with format 'u'" do
it "raises a TypeError if #to_str does not return a String" do
obj = mock("pack m non-string")
- lambda { [obj].pack("u") }.should raise_error(TypeError)
+ -> { [obj].pack("u") }.should raise_error(TypeError)
end
it "raises a TypeError if passed nil" do
- lambda { [nil].pack("u") }.should raise_error(TypeError)
+ -> { [nil].pack("u") }.should raise_error(TypeError)
end
it "raises a TypeError if passed an Integer" do
- lambda { [0].pack("u") }.should raise_error(TypeError)
- lambda { [bignum_value].pack("u") }.should raise_error(TypeError)
+ -> { [0].pack("u") }.should raise_error(TypeError)
+ -> { [bignum_value].pack("u") }.should raise_error(TypeError)
end
it "sets the output string to US-ASCII encoding" do
diff --git a/spec/ruby/core/array/pack/v_spec.rb b/spec/ruby/core/array/pack/v_spec.rb
index 8ebb863686..d3932c84af 100644
--- a/spec/ruby/core/array/pack/v_spec.rb
+++ b/spec/ruby/core/array/pack/v_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
-require File.expand_path('../shared/integer', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
+require_relative 'shared/integer'
describe "Array#pack with format 'V'" do
it_behaves_like :array_pack_basic, 'V'
diff --git a/spec/ruby/core/array/pack/w_spec.rb b/spec/ruby/core/array/pack/w_spec.rb
index 9ada3e84cb..439fa02198 100644
--- a/spec/ruby/core/array/pack/w_spec.rb
+++ b/spec/ruby/core/array/pack/w_spec.rb
@@ -1,8 +1,8 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/numeric_basic', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/numeric_basic'
describe "Array#pack with format 'w'" do
it_behaves_like :array_pack_basic, 'w'
@@ -33,10 +33,10 @@ describe "Array#pack with format 'w'" do
end
it "raises an ArgumentError when passed a negative value" do
- lambda { [-1].pack("w") }.should raise_error(ArgumentError)
+ -> { [-1].pack("w") }.should raise_error(ArgumentError)
end
- it "returns an ASCII-8BIT string" do
- [1].pack('w').encoding.should == Encoding::ASCII_8BIT
+ it "returns a binary string" do
+ [1].pack('w').encoding.should == Encoding::BINARY
end
end
diff --git a/spec/ruby/core/array/pack/x_spec.rb b/spec/ruby/core/array/pack/x_spec.rb
index 8d54ab84ee..a28dd0bf21 100644
--- a/spec/ruby/core/array/pack/x_spec.rb
+++ b/spec/ruby/core/array/pack/x_spec.rb
@@ -1,7 +1,7 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
describe "Array#pack with format 'x'" do
it_behaves_like :array_pack_basic, 'x'
@@ -55,10 +55,10 @@ describe "Array#pack with format 'X'" do
end
it "raises an ArgumentError if the output string is empty" do
- lambda { [1, 2, 3].pack("XC") }.should raise_error(ArgumentError)
+ -> { [1, 2, 3].pack("XC") }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if the count modifier is greater than the bytes in the string" do
- lambda { [1, 2, 3].pack("C2X3") }.should raise_error(ArgumentError)
+ -> { [1, 2, 3].pack("C2X3") }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/array/pack/z_spec.rb b/spec/ruby/core/array/pack/z_spec.rb
index b28a460a8e..82ce7b4a1c 100644
--- a/spec/ruby/core/array/pack/z_spec.rb
+++ b/spec/ruby/core/array/pack/z_spec.rb
@@ -1,14 +1,16 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../shared/basic', __FILE__)
-require File.expand_path('../shared/string', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative 'shared/basic'
+require_relative 'shared/string'
+require_relative 'shared/taint'
describe "Array#pack with format 'Z'" do
it_behaves_like :array_pack_basic, 'Z'
it_behaves_like :array_pack_basic_non_float, 'Z'
it_behaves_like :array_pack_no_platform, 'Z'
it_behaves_like :array_pack_string, 'Z'
+ it_behaves_like :array_pack_taint, 'Z'
it "adds all the bytes and appends a NULL byte when passed the '*' modifier" do
["abc"].pack("Z*").should == "abc\x00"
diff --git a/spec/ruby/core/array/partition_spec.rb b/spec/ruby/core/array/partition_spec.rb
index 787b574c28..be36fffcab 100644
--- a/spec/ruby/core/array/partition_spec.rb
+++ b/spec/ruby/core/array/partition_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#partition" do
it "returns two arrays" do
diff --git a/spec/ruby/core/array/permutation_spec.rb b/spec/ruby/core/array/permutation_spec.rb
index 8a80b93c3b..f15bd76639 100644
--- a/spec/ruby/core/array/permutation_spec.rb
+++ b/spec/ruby/core/array/permutation_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#permutation" do
@@ -52,7 +52,7 @@ describe "Array#permutation" do
end
it "returns no permutations when the given length has no permutations" do
- @numbers.permutation(9).entries.size == 0
+ @numbers.permutation(9).entries.size.should == 0
@numbers.permutation(9) { |n| @yielded << n }
@yielded.should == []
end
diff --git a/spec/ruby/core/array/plus_spec.rb b/spec/ruby/core/array/plus_spec.rb
index 4517087550..45f8438208 100644
--- a/spec/ruby/core/array/plus_spec.rb
+++ b/spec/ruby/core/array/plus_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#+" do
it "concatenates two arrays" do
@@ -41,17 +41,19 @@ describe "Array#+" do
([5, 6] + ArraySpecs::ToAryArray[1, 2]).should == [5, 6, 1, 2]
end
- it "does not get infected even if an original array is tainted" do
- ([1, 2] + [3, 4]).tainted?.should be_false
- ([1, 2].taint + [3, 4]).tainted?.should be_false
- ([1, 2] + [3, 4].taint).tainted?.should be_false
- ([1, 2].taint + [3, 4].taint).tainted?.should be_false
- end
-
- it "does not infected even if an original array is untrusted" do
- ([1, 2] + [3, 4]).untrusted?.should be_false
- ([1, 2].untrust + [3, 4]).untrusted?.should be_false
- ([1, 2] + [3, 4].untrust).untrusted?.should be_false
- ([1, 2].untrust + [3, 4].untrust).untrusted?.should be_false
+ ruby_version_is ''...'2.7' do
+ it "does not get infected even if an original array is tainted" do
+ ([1, 2] + [3, 4]).tainted?.should be_false
+ ([1, 2].taint + [3, 4]).tainted?.should be_false
+ ([1, 2] + [3, 4].taint).tainted?.should be_false
+ ([1, 2].taint + [3, 4].taint).tainted?.should be_false
+ end
+
+ it "does not infected even if an original array is untrusted" do
+ ([1, 2] + [3, 4]).untrusted?.should be_false
+ ([1, 2].untrust + [3, 4]).untrusted?.should be_false
+ ([1, 2] + [3, 4].untrust).untrusted?.should be_false
+ ([1, 2].untrust + [3, 4].untrust).untrusted?.should be_false
+ end
end
end
diff --git a/spec/ruby/core/array/pop_spec.rb b/spec/ruby/core/array/pop_spec.rb
index 313dc4189e..96ef78da32 100644
--- a/spec/ruby/core/array/pop_spec.rb
+++ b/spec/ruby/core/array/pop_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#pop" do
it "removes and returns the last element of the array" do
@@ -30,28 +30,32 @@ describe "Array#pop" do
array.pop.should == [1, 'two', 3.0, array, array, array, array]
end
- it "keeps taint status" do
- a = [1, 2].taint
- a.pop
- a.tainted?.should be_true
- a.pop
- a.tainted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "keeps taint status" do
+ a = [1, 2].taint
+ a.pop
+ a.tainted?.should be_true
+ a.pop
+ a.tainted?.should be_true
+ end
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.pop }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.pop }.should raise_error(FrozenError)
end
- it "raises a RuntimeError on an empty frozen array" do
- lambda { ArraySpecs.empty_frozen_array.pop }.should raise_error(RuntimeError)
+ it "raises a FrozenError on an empty frozen array" do
+ -> { ArraySpecs.empty_frozen_array.pop }.should raise_error(FrozenError)
end
- it "keeps untrusted status" do
- a = [1, 2].untrust
- a.pop
- a.untrusted?.should be_true
- a.pop
- a.untrusted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "keeps untrusted status" do
+ a = [1, 2].untrust
+ a.pop
+ a.untrusted?.should be_true
+ a.pop
+ a.untrusted?.should be_true
+ end
end
describe "passed a number n as an argument" do
@@ -105,7 +109,7 @@ describe "Array#pop" do
end
it "raises an ArgumentError if n is negative" do
- lambda{ [1, 2, 3].pop(-1) }.should raise_error(ArgumentError)
+ ->{ [1, 2, 3].pop(-1) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
@@ -119,50 +123,54 @@ describe "Array#pop" do
a.should == []
end
- it "raises a TypeError when the passed n can be coerced to Integer" do
- lambda{ [1, 2].pop("cat") }.should raise_error(TypeError)
- lambda{ [1, 2].pop(nil) }.should raise_error(TypeError)
+ it "raises a TypeError when the passed n cannot be coerced to Integer" do
+ ->{ [1, 2].pop("cat") }.should raise_error(TypeError)
+ ->{ [1, 2].pop(nil) }.should raise_error(TypeError)
end
it "raises an ArgumentError if more arguments are passed" do
- lambda{ [1, 2].pop(1, 2) }.should raise_error(ArgumentError)
+ ->{ [1, 2].pop(1, 2) }.should raise_error(ArgumentError)
end
it "does not return subclass instances with Array subclass" do
ArraySpecs::MyArray[1, 2, 3].pop(2).should be_an_instance_of(Array)
end
- it "returns an untainted array even if the array is tainted" do
- ary = [1, 2].taint
- ary.pop(2).tainted?.should be_false
- ary.pop(0).tainted?.should be_false
- end
-
- it "keeps taint status" do
- a = [1, 2].taint
- a.pop(2)
- a.tainted?.should be_true
- a.pop(2)
- a.tainted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "returns an untainted array even if the array is tainted" do
+ ary = [1, 2].taint
+ ary.pop(2).tainted?.should be_false
+ ary.pop(0).tainted?.should be_false
+ end
+
+ it "keeps taint status" do
+ a = [1, 2].taint
+ a.pop(2)
+ a.tainted?.should be_true
+ a.pop(2)
+ a.tainted?.should be_true
+ end
+
+ it "returns a trusted array even if the array is untrusted" do
+ ary = [1, 2].untrust
+ ary.pop(2).untrusted?.should be_false
+ ary.pop(0).untrusted?.should be_false
+ end
end
- it "returns a trusted array even if the array is untrusted" do
- ary = [1, 2].untrust
- ary.pop(2).untrusted?.should be_false
- ary.pop(0).untrusted?.should be_false
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.pop(2) }.should raise_error(FrozenError)
+ -> { ArraySpecs.frozen_array.pop(0) }.should raise_error(FrozenError)
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.pop(2) }.should raise_error(RuntimeError)
- lambda { ArraySpecs.frozen_array.pop(0) }.should raise_error(RuntimeError)
- end
-
- it "keeps untrusted status" do
- a = [1, 2].untrust
- a.pop(2)
- a.untrusted?.should be_true
- a.pop(2)
- a.untrusted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "keeps untrusted status" do
+ a = [1, 2].untrust
+ a.pop(2)
+ a.untrusted?.should be_true
+ a.pop(2)
+ a.untrusted?.should be_true
+ end
end
end
end
diff --git a/spec/ruby/core/array/prepend_spec.rb b/spec/ruby/core/array/prepend_spec.rb
new file mode 100644
index 0000000000..368b8dcfcd
--- /dev/null
+++ b/spec/ruby/core/array/prepend_spec.rb
@@ -0,0 +1,7 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/unshift'
+
+describe "Array#prepend" do
+ it_behaves_like :array_unshift, :prepend
+end
diff --git a/spec/ruby/core/array/product_spec.rb b/spec/ruby/core/array/product_spec.rb
index 1ab38e34be..07d2880a96 100644
--- a/spec/ruby/core/array/product_spec.rb
+++ b/spec/ruby/core/array/product_spec.rb
@@ -1,10 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#product" do
it "returns converted arguments using :to_ary" do
- lambda{ [1].product(2..3) }.should raise_error(TypeError)
- ar = ArraySpecs::ArrayConvertable.new(2,3)
+ ->{ [1].product(2..3) }.should raise_error(TypeError)
+ ar = ArraySpecs::ArrayConvertible.new(2,3)
[1].product(ar).should == [[1,2],[1,3]]
ar.called.should == :to_ary
end
@@ -24,7 +24,7 @@ describe "Array#product" do
it "does not attempt to produce an unreasonable number of products" do
a = (0..100).to_a
- lambda do
+ -> do
a.product(a, a, a, a, a, a, a, a, a, a)
end.should raise_error(RangeError)
end
@@ -49,7 +49,7 @@ describe "Array#product" do
it "will ignore unreasonable numbers of products and yield anyway" do
a = (0..100).to_a
- lambda do
+ -> do
a.product(a, a, a, a, a, a, a, a, a, a)
end.should raise_error(RangeError)
end
diff --git a/spec/ruby/core/array/push_spec.rb b/spec/ruby/core/array/push_spec.rb
index 562a6888dd..607cbc7b4d 100644
--- a/spec/ruby/core/array/push_spec.rb
+++ b/spec/ruby/core/array/push_spec.rb
@@ -1,36 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/push'
describe "Array#push" do
- it "appends the arguments to the array" do
- a = [ "a", "b", "c" ]
- a.push("d", "e", "f").should equal(a)
- a.push().should == ["a", "b", "c", "d", "e", "f"]
- a.push(5)
- a.should == ["a", "b", "c", "d", "e", "f", 5]
-
- a = [0, 1]
- a.push(2)
- a.should == [0, 1, 2]
- end
-
- it "isn't confused by previous shift" do
- a = [ "a", "b", "c" ]
- a.shift
- a.push("foo")
- a.should == ["b", "c", "foo"]
- end
-
- it "properly handles recursive arrays" do
- empty = ArraySpecs.empty_recursive_array
- empty.push(:last).should == [empty, :last]
-
- array = ArraySpecs.recursive_array
- array.push(:last).should == [1, 'two', 3.0, array, array, array, array, array, :last]
- end
-
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.push(1) }.should raise_error(RuntimeError)
- lambda { ArraySpecs.frozen_array.push }.should raise_error(RuntimeError)
- end
+ it_behaves_like :array_push, :push
end
diff --git a/spec/ruby/core/array/rassoc_spec.rb b/spec/ruby/core/array/rassoc_spec.rb
index cf3daccfc9..62fbd40611 100644
--- a/spec/ruby/core/array/rassoc_spec.rb
+++ b/spec/ruby/core/array/rassoc_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#rassoc" do
it "returns the first contained array whose second element is == object" do
@@ -28,7 +28,7 @@ describe "Array#rassoc" do
[[1, :foobar], [2, o], [3, mock('foo')]].rassoc(key).should == [2, o]
end
- it "does not check the last element in each contained but speficically the second" do
+ it "does not check the last element in each contained but specifically the second" do
key = 'foobar'
o = mock('foobar')
def o.==(other); other == 'foobar'; end
diff --git a/spec/ruby/core/array/reject_spec.rb b/spec/ruby/core/array/reject_spec.rb
index 857cbf6a4d..fcf43fabde 100644
--- a/spec/ruby/core/array/reject_spec.rb
+++ b/spec/ruby/core/array/reject_spec.rb
@@ -1,17 +1,17 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorize', __FILE__)
-require File.expand_path('../shared/delete_if', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorize'
+require_relative 'shared/delete_if'
+require_relative '../enumerable/shared/enumeratorized'
describe "Array#reject" do
it "returns a new array without elements for which block is true" do
ary = [1, 2, 3, 4, 5]
ary.reject { true }.should == []
ary.reject { false }.should == ary
- ary.reject { false }.object_id.should_not == ary.object_id
+ ary.reject { false }.should_not equal ary
ary.reject { nil }.should == ary
- ary.reject { nil }.object_id.should_not == ary.object_id
+ ary.reject { nil }.should_not equal ary
ary.reject { 5 }.should == []
ary.reject { |i| i < 3 }.should == [3, 4, 5]
ary.reject { |i| i % 2 == 0 }.should == [1, 3, 5]
@@ -103,12 +103,38 @@ describe "Array#reject!" do
ArraySpecs.frozen_array.reject!.should be_an_instance_of(Enumerator)
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.reject! {} }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.reject! {} }.should raise_error(FrozenError)
end
- it "raises a RuntimeError on an empty frozen array" do
- lambda { ArraySpecs.empty_frozen_array.reject! {} }.should raise_error(RuntimeError)
+ it "raises a FrozenError on an empty frozen array" do
+ -> { ArraySpecs.empty_frozen_array.reject! {} }.should raise_error(FrozenError)
+ end
+
+ it "does not truncate the array is the block raises an exception" do
+ a = [1, 2, 3]
+ begin
+ a.reject! { raise StandardError, 'Oops' }
+ rescue
+ end
+
+ a.should == [1, 2, 3]
+ end
+
+ it "only removes elements for which the block returns true, keeping the element which raised an error." do
+ a = [1, 2, 3, 4]
+ begin
+ a.reject! do |x|
+ case x
+ when 2 then true
+ when 3 then raise StandardError, 'Oops'
+ else false
+ end
+ end
+ rescue StandardError
+ end
+
+ a.should == [1, 3, 4]
end
it_behaves_like :enumeratorize, :reject!
diff --git a/spec/ruby/core/array/repeated_combination_spec.rb b/spec/ruby/core/array/repeated_combination_spec.rb
index e79c34a520..b62382024a 100644
--- a/spec/ruby/core/array/repeated_combination_spec.rb
+++ b/spec/ruby/core/array/repeated_combination_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#repeated_combination" do
before :each do
@@ -68,7 +68,7 @@ describe "Array#repeated_combination" do
[].repeated_combination(0).size.should == 1
end
- it "returns the binomial coeficient between combination_size and array size + combination_size -1" do
+ it "returns the binomial coefficient between combination_size and array size + combination_size -1" do
@array.repeated_combination(5).size.should == 21
@array.repeated_combination(4).size.should == 15
@array.repeated_combination(3).size.should == 10
diff --git a/spec/ruby/core/array/repeated_permutation_spec.rb b/spec/ruby/core/array/repeated_permutation_spec.rb
index 9038d49560..a165fda09e 100644
--- a/spec/ruby/core/array/repeated_permutation_spec.rb
+++ b/spec/ruby/core/array/repeated_permutation_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#repeated_permutation" do
diff --git a/spec/ruby/core/array/replace_spec.rb b/spec/ruby/core/array/replace_spec.rb
index e8b0d53e04..2f53338f5e 100644
--- a/spec/ruby/core/array/replace_spec.rb
+++ b/spec/ruby/core/array/replace_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/replace', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/replace'
describe "Array#replace" do
- it_behaves_like(:array_replace, :replace)
+ it_behaves_like :array_replace, :replace
end
diff --git a/spec/ruby/core/array/reverse_each_spec.rb b/spec/ruby/core/array/reverse_each_spec.rb
index 1bc0ed5ac5..28b8bfcb34 100644
--- a/spec/ruby/core/array/reverse_each_spec.rb
+++ b/spec/ruby/core/array/reverse_each_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorize', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorize'
+require_relative '../enumerable/shared/enumeratorized'
# Modifying a collection while the contents are being iterated
# gives undefined behavior. See
diff --git a/spec/ruby/core/array/reverse_spec.rb b/spec/ruby/core/array/reverse_spec.rb
index a3a6db9506..05dbd2efcf 100644
--- a/spec/ruby/core/array/reverse_spec.rb
+++ b/spec/ruby/core/array/reverse_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#reverse" do
it "returns a new array with the elements in reverse order" do
@@ -36,7 +36,7 @@ describe "Array#reverse!" do
array.reverse!.should == [array, array, array, array, array, 3.0, 'two', 1]
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.reverse! }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.reverse! }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/rindex_spec.rb b/spec/ruby/core/array/rindex_spec.rb
index 19a6f04c85..175c7bcfe2 100644
--- a/spec/ruby/core/array/rindex_spec.rb
+++ b/spec/ruby/core/array/rindex_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative '../enumerable/shared/enumeratorized'
# Modifying a collection while the contents are being iterated
# gives undefined behavior. See
diff --git a/spec/ruby/core/array/rotate_spec.rb b/spec/ruby/core/array/rotate_spec.rb
index 270bfeb446..60dcc8b113 100644
--- a/spec/ruby/core/array/rotate_spec.rb
+++ b/spec/ruby/core/array/rotate_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#rotate" do
describe "when passed no argument" do
@@ -27,10 +27,10 @@ describe "Array#rotate" do
end
it "raises a TypeError if not passed an integer-like argument" do
- lambda {
+ -> {
[1, 2].rotate(nil)
}.should raise_error(TypeError)
- lambda {
+ -> {
[1, 2].rotate("4")
}.should raise_error(TypeError)
end
@@ -46,7 +46,7 @@ describe "Array#rotate" do
end
it "does not mutate the receiver" do
- lambda {
+ -> {
[].freeze.rotate
[2].freeze.rotate(2)
[1,2,3].freeze.rotate(-3)
@@ -94,10 +94,10 @@ describe "Array#rotate!" do
end
it "raises a TypeError if not passed an integer-like argument" do
- lambda {
+ -> {
[1, 2].rotate!(nil)
}.should raise_error(TypeError)
- lambda {
+ -> {
[1, 2].rotate!("4")
}.should raise_error(TypeError)
end
@@ -121,9 +121,9 @@ describe "Array#rotate!" do
a.should == []
end
- it "raises a RuntimeError on a frozen array" do
- lambda { [1, 2, 3].freeze.rotate!(0) }.should raise_error(RuntimeError)
- lambda { [1].freeze.rotate!(42) }.should raise_error(RuntimeError)
- lambda { [].freeze.rotate! }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { [1, 2, 3].freeze.rotate!(0) }.should raise_error(FrozenError)
+ -> { [1].freeze.rotate!(42) }.should raise_error(FrozenError)
+ -> { [].freeze.rotate! }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/sample_spec.rb b/spec/ruby/core/array/sample_spec.rb
index 53601dd5c4..565d7ff7f9 100644
--- a/spec/ruby/core/array/sample_spec.rb
+++ b/spec/ruby/core/array/sample_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#sample" do
it "samples evenly" do
@@ -57,7 +57,7 @@ describe "Array#sample" do
end
it "raises ArgumentError when passed a negative count" do
- lambda { [1, 2].sample(-1) }.should raise_error(ArgumentError)
+ -> { [1, 2].sample(-1) }.should raise_error(ArgumentError)
end
it "does not return subclass instances with Array subclass" do
@@ -65,38 +65,21 @@ describe "Array#sample" do
end
describe "with options" do
- it "calls #to_hash to convert the passed Object" do
- obj = mock("array_sample")
- obj.should_receive(:to_hash).and_return({})
- obj.should_not_receive(:to_int)
-
- [1, 2].sample(obj).should be_an_instance_of(Fixnum)
- end
-
- it "calls #to_int on the first argument and #to_hash on the second when passed Objects" do
- count = mock("array_sample_count")
- count.should_receive(:to_int).and_return(2)
- options = mock("array_sample_options")
- options.should_receive(:to_hash).and_return({})
-
- [1, 2].sample(count, options).size.should == 2
- end
-
it "calls #rand on the Object passed by the :random key in the arguments Hash" do
obj = mock("array_sample_random")
obj.should_receive(:rand).and_return(0.5)
- [1, 2].sample(random: obj).should be_an_instance_of(Fixnum)
+ [1, 2].sample(random: obj).should be_an_instance_of(Integer)
end
it "raises a NoMethodError if an object passed for the RNG does not define #rand" do
obj = BasicObject.new
- lambda { [1, 2].sample(random: obj) }.should raise_error(NoMethodError)
+ -> { [1, 2].sample(random: obj) }.should raise_error(NoMethodError)
end
- describe "when the object returned by #rand is a Fixnum" do
- it "uses the fixnum as index" do
+ describe "when the object returned by #rand is an Integer" do
+ it "uses the integer as index" do
random = mock("array_sample_random_ret")
random.should_receive(:rand).and_return(0)
@@ -112,19 +95,19 @@ describe "Array#sample" do
random = mock("array_sample_random")
random.should_receive(:rand).and_return(-1)
- lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
+ -> { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
it "raises a RangeError if the value is equal to the Array size" do
random = mock("array_sample_random")
random.should_receive(:rand).and_return(2)
- lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
+ -> { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
end
end
- describe "when the object returned by #rand is not a Fixnum but responds to #to_int" do
+ describe "when the object returned by #rand is not an Integer but responds to #to_int" do
it "calls #to_int on the Object" do
value = mock("array_sample_random_value")
value.should_receive(:to_int).and_return(1)
@@ -140,7 +123,7 @@ describe "Array#sample" do
random = mock("array_sample_random")
random.should_receive(:rand).and_return(value)
- lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
+ -> { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
it "raises a RangeError if the value is equal to the Array size" do
@@ -149,7 +132,7 @@ describe "Array#sample" do
random = mock("array_sample_random")
random.should_receive(:rand).and_return(value)
- lambda { [1, 2].sample(random: random) }.should raise_error(RangeError)
+ -> { [1, 2].sample(random: random) }.should raise_error(RangeError)
end
end
end
diff --git a/spec/ruby/core/array/select_spec.rb b/spec/ruby/core/array/select_spec.rb
index 8b83acaa5f..298b591744 100644
--- a/spec/ruby/core/array/select_spec.rb
+++ b/spec/ruby/core/array/select_spec.rb
@@ -1,30 +1,8 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorize', __FILE__)
-require File.expand_path('../shared/keep_if', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/select'
describe "Array#select" do
- it_behaves_like :enumeratorize, :select
- it_behaves_like :enumeratorized_with_origin_size, :select, [1,2,3]
-
- it "returns a new array of elements for which block is true" do
- [1, 3, 4, 5, 6, 9].select { |i| i % ((i + 1) / 2) == 0}.should == [1, 4, 6]
- end
-
- it "does not return subclass instance on Array subclasses" do
- ArraySpecs::MyArray[1, 2, 3].select { true }.should be_an_instance_of(Array)
- end
-
- it "properly handles recursive arrays" do
- empty = ArraySpecs.empty_recursive_array
- empty.select { true }.should == empty
- empty.select { false }.should == []
-
- array = ArraySpecs.recursive_array
- array.select { true }.should == [1, 'two', 3.0, array, array, array, array, array]
- array.select { false }.should == []
- end
+ it_behaves_like :array_select, :select
end
describe "Array#select!" do
diff --git a/spec/ruby/core/array/shared/clone.rb b/spec/ruby/core/array/shared/clone.rb
index 6fc7ae31eb..3c17b1f10f 100644
--- a/spec/ruby/core/array/shared/clone.rb
+++ b/spec/ruby/core/array/shared/clone.rb
@@ -7,8 +7,8 @@ describe :array_clone, shared: true do
it "produces a shallow copy where the references are directly copied" do
a = [mock('1'), mock('2')]
b = a.send @method
- b.first.object_id.should == a.first.object_id
- b.last.object_id.should == a.last.object_id
+ b.first.should equal a.first
+ b.last.should equal a.last
end
it "creates a new array containing all elements or the original" do
@@ -18,25 +18,27 @@ describe :array_clone, shared: true do
b.__id__.should_not == a.__id__
end
- it "copies taint status from the original" do
- a = [1, 2, 3, 4]
- b = [1, 2, 3, 4]
- a.taint
- aa = a.send @method
- bb = b.send @method
+ ruby_version_is ''...'2.7' do
+ it "copies taint status from the original" do
+ a = [1, 2, 3, 4]
+ b = [1, 2, 3, 4]
+ a.taint
+ aa = a.send @method
+ bb = b.send @method
- aa.tainted?.should == true
- bb.tainted?.should == false
- end
+ aa.should.tainted?
+ bb.should_not.tainted?
+ end
- it "copies untrusted status from the original" do
- a = [1, 2, 3, 4]
- b = [1, 2, 3, 4]
- a.untrust
- aa = a.send @method
- bb = b.send @method
+ it "copies untrusted status from the original" do
+ a = [1, 2, 3, 4]
+ b = [1, 2, 3, 4]
+ a.untrust
+ aa = a.send @method
+ bb = b.send @method
- aa.untrusted?.should == true
- bb.untrusted?.should == false
+ aa.should.untrusted?
+ bb.should_not.untrusted?
+ end
end
end
diff --git a/spec/ruby/core/array/shared/collect.rb b/spec/ruby/core/array/shared/collect.rb
index f6bcfd8904..d84432734a 100644
--- a/spec/ruby/core/array/shared/collect.rb
+++ b/spec/ruby/core/array/shared/collect.rb
@@ -1,11 +1,11 @@
-require File.expand_path('../../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../enumerable/shared/enumeratorized'
describe :array_collect, shared: true do
it "returns a copy of array with each element replaced by the value returned by block" do
a = ['a', 'b', 'c', 'd']
b = a.send(@method) { |i| i + '!' }
b.should == ["a!", "b!", "c!", "d!"]
- b.object_id.should_not == a.object_id
+ b.should_not equal a
end
it "does not return subclass instance" do
@@ -37,21 +37,23 @@ describe :array_collect, shared: true do
it "raises an ArgumentError when no block and with arguments" do
a = [1, 2, 3]
- lambda {
+ -> {
a.send(@method, :foo)
}.should raise_error(ArgumentError)
end
- it "does not copy tainted status" do
- a = [1, 2, 3]
- a.taint
- a.send(@method){|x| x}.tainted?.should be_false
- end
+ ruby_version_is ''...'2.7' do
+ it "does not copy tainted status" do
+ a = [1, 2, 3]
+ a.taint
+ a.send(@method){|x| x}.tainted?.should be_false
+ end
- it "does not copy untrusted status" do
- a = [1, 2, 3]
- a.untrust
- a.send(@method){|x| x}.untrusted?.should be_false
+ it "does not copy untrusted status" do
+ a = [1, 2, 3]
+ a.untrust
+ a.send(@method){|x| x}.untrusted?.should be_false
+ end
end
before :all do
@@ -70,7 +72,7 @@ describe :array_collect_b, shared: true do
it "returns self" do
a = [1, 2, 3, 4, 5]
b = a.send(@method) {|i| i+1 }
- a.object_id.should == b.object_id
+ a.should equal b
end
it "returns the evaluated value of block but its contents is partially modified, if it broke in the block" do
@@ -94,38 +96,40 @@ describe :array_collect_b, shared: true do
a.should == ["1!", "2!", "3!"]
end
- it "keeps tainted status" do
- a = [1, 2, 3]
- a.taint
- a.tainted?.should be_true
- a.send(@method){|x| x}
- a.tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "keeps tainted status" do
+ a = [1, 2, 3]
+ a.taint
+ a.tainted?.should be_true
+ a.send(@method){|x| x}
+ a.tainted?.should be_true
+ end
- it "keeps untrusted status" do
- a = [1, 2, 3]
- a.untrust
- a.send(@method){|x| x}
- a.untrusted?.should be_true
+ it "keeps untrusted status" do
+ a = [1, 2, 3]
+ a.untrust
+ a.send(@method){|x| x}
+ a.untrusted?.should be_true
+ end
end
describe "when frozen" do
- it "raises a RuntimeError" do
- lambda { ArraySpecs.frozen_array.send(@method) {} }.should raise_error(RuntimeError)
+ it "raises a FrozenError" do
+ -> { ArraySpecs.frozen_array.send(@method) {} }.should raise_error(FrozenError)
end
- it "raises a RuntimeError when empty" do
- lambda { ArraySpecs.empty_frozen_array.send(@method) {} }.should raise_error(RuntimeError)
+ it "raises a FrozenError when empty" do
+ -> { ArraySpecs.empty_frozen_array.send(@method) {} }.should raise_error(FrozenError)
end
- it "raises a RuntimeError when calling #each on the returned Enumerator" do
+ it "raises a FrozenError when calling #each on the returned Enumerator" do
enumerator = ArraySpecs.frozen_array.send(@method)
- lambda { enumerator.each {|x| x } }.should raise_error(RuntimeError)
+ -> { enumerator.each {|x| x } }.should raise_error(FrozenError)
end
- it "raises a RuntimeError when calling #each on the returned Enumerator when empty" do
+ it "raises a FrozenError when calling #each on the returned Enumerator when empty" do
enumerator = ArraySpecs.empty_frozen_array.send(@method)
- lambda { enumerator.each {|x| x } }.should raise_error(RuntimeError)
+ -> { enumerator.each {|x| x } }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/shared/delete_if.rb b/spec/ruby/core/array/shared/delete_if.rb
index a9fb57e0d9..a3fdcf4fac 100644
--- a/spec/ruby/core/array/shared/delete_if.rb
+++ b/spec/ruby/core/array/shared/delete_if.rb
@@ -3,25 +3,11 @@ describe :delete_if, shared: true do
@object = [1,2,3]
end
- ruby_version_is "2.3" do
- it "updates the receiver after all blocks" do
- @object.send(@method) do |e|
- @object.length.should == 3
- true
- end
- @object.length.should == 0
- end
- end
-
- ruby_version_is ""..."2.3" do
- it "updates the receiver after each true block" do
- count = 0
- @object.send(@method) do |e|
- @object.length.should == (3 - count)
- count += 1
- true
- end
- @object.length.should == 0
+ it "updates the receiver after all blocks" do
+ @object.send(@method) do |e|
+ @object.length.should == 3
+ true
end
+ @object.length.should == 0
end
end
diff --git a/spec/ruby/core/array/shared/difference.rb b/spec/ruby/core/array/shared/difference.rb
new file mode 100644
index 0000000000..3e69050d82
--- /dev/null
+++ b/spec/ruby/core/array/shared/difference.rb
@@ -0,0 +1,78 @@
+describe :array_binary_difference, shared: true do
+ it "creates an array minus any items from other array" do
+ [].send(@method, [ 1, 2, 4 ]).should == []
+ [1, 2, 4].send(@method, []).should == [1, 2, 4]
+ [ 1, 2, 3, 4, 5 ].send(@method, [ 1, 2, 4 ]).should == [3, 5]
+ end
+
+ it "removes multiple items on the lhs equal to one on the rhs" do
+ [1, 1, 2, 2, 3, 3, 4, 5].send(@method, [1, 2, 4]).should == [3, 3, 5]
+ end
+
+ it "properly handles recursive arrays" do
+ empty = ArraySpecs.empty_recursive_array
+ empty.send(@method, empty).should == []
+
+ [].send(@method, ArraySpecs.recursive_array).should == []
+
+ array = ArraySpecs.recursive_array
+ array.send(@method, array).should == []
+ end
+
+ it "tries to convert the passed arguments to Arrays using #to_ary" do
+ obj = mock('[2,3,3,4]')
+ obj.should_receive(:to_ary).and_return([2, 3, 3, 4])
+ [1, 1, 2, 2, 3, 4].send(@method, obj).should == [1, 1]
+ end
+
+ it "raises a TypeError if the argument cannot be coerced to an Array by calling #to_ary" do
+ obj = mock('not an array')
+ -> { [1, 2, 3].send(@method, obj) }.should raise_error(TypeError)
+ end
+
+ it "does not return subclass instance for Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].send(@method, []).should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[]).should be_an_instance_of(Array)
+ [1, 2, 3].send(@method, ArraySpecs::MyArray[]).should be_an_instance_of(Array)
+ end
+
+ it "does not call to_ary on array subclasses" do
+ [5, 6, 7].send(@method, ArraySpecs::ToAryArray[7]).should == [5, 6]
+ end
+
+ it "removes an item identified as equivalent via #hash and #eql?" do
+ obj1 = mock('1')
+ obj2 = mock('2')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj1.should_receive(:eql?).at_least(1).and_return(true)
+
+ [obj1].send(@method, [obj2]).should == []
+ [obj1, obj1, obj2, obj2].send(@method, [obj2]).should == []
+ end
+
+ it "doesn't remove an item with the same hash but not #eql?" do
+ obj1 = mock('1')
+ obj2 = mock('2')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj1.should_receive(:eql?).at_least(1).and_return(false)
+
+ [obj1].send(@method, [obj2]).should == [obj1]
+ [obj1, obj1, obj2, obj2].send(@method, [obj2]).should == [obj1, obj1]
+ end
+
+ it "removes an identical item even when its #eql? isn't reflexive" do
+ x = mock('x')
+ x.stub!(:hash).and_return(42)
+ x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
+
+ [x].send(@method, [x]).should == []
+ end
+
+ it "is not destructive" do
+ a = [1, 2, 3]
+ a.send(@method, [1])
+ a.should == [1, 2, 3]
+ end
+end
diff --git a/spec/ruby/core/array/shared/inspect.rb b/spec/ruby/core/array/shared/inspect.rb
index 6a60781b45..736f8d946b 100644
--- a/spec/ruby/core/array/shared/inspect.rb
+++ b/spec/ruby/core/array/shared/inspect.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../fixtures/encoded_strings', __FILE__)
+require_relative '../fixtures/encoded_strings'
describe :array_inspect, shared: true do
it "returns a string" do
@@ -55,7 +55,7 @@ describe :array_inspect, shared: true do
obj.should_receive(:inspect).and_return(obj)
obj.should_receive(:to_s).and_raise(Exception)
- lambda { [obj].send(@method) }.should raise_error(Exception)
+ -> { [obj].send(@method) }.should raise_error(Exception)
end
it "represents a recursive element with '[...]'" do
@@ -64,28 +64,30 @@ describe :array_inspect, shared: true do
ArraySpecs.empty_recursive_array.send(@method).should == "[[...]]"
end
- it "taints the result if the Array is non-empty and tainted" do
- [1, 2].taint.send(@method).tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "taints the result if the Array is non-empty and tainted" do
+ [1, 2].taint.send(@method).tainted?.should be_true
+ end
- it "does not taint the result if the Array is tainted but empty" do
- [].taint.send(@method).tainted?.should be_false
- end
+ it "does not taint the result if the Array is tainted but empty" do
+ [].taint.send(@method).tainted?.should be_false
+ end
- it "taints the result if an element is tainted" do
- ["str".taint].send(@method).tainted?.should be_true
- end
+ it "taints the result if an element is tainted" do
+ ["str".taint].send(@method).tainted?.should be_true
+ end
- it "untrusts the result if the Array is untrusted" do
- [1, 2].untrust.send(@method).untrusted?.should be_true
- end
+ it "untrusts the result if the Array is untrusted" do
+ [1, 2].untrust.send(@method).untrusted?.should be_true
+ end
- it "does not untrust the result if the Array is untrusted but empty" do
- [].untrust.send(@method).untrusted?.should be_false
- end
+ it "does not untrust the result if the Array is untrusted but empty" do
+ [].untrust.send(@method).untrusted?.should be_false
+ end
- it "untrusts the result if an element is untrusted" do
- ["str".untrust].send(@method).untrusted?.should be_true
+ it "untrusts the result if an element is untrusted" do
+ ["str".untrust].send(@method).untrusted?.should be_true
+ end
end
describe "with encoding" do
@@ -121,24 +123,11 @@ describe :array_inspect, shared: true do
array.send(@method).encoding.name.should == "US-ASCII"
end
- ruby_version_is ''...'2.3' do
- it "raises if inspected result is not default external encoding" do
- utf_16be = mock("utf_16be")
- utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode!(Encoding::UTF_16BE))
-
- lambda {
- [utf_16be].send(@method)
- }.should raise_error(Encoding::CompatibilityError)
- end
- end
-
- ruby_version_is '2.3' do
- it "does not raise if inspected result is not default external encoding" do
- utf_16be = mock("utf_16be")
- utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode!(Encoding::UTF_16BE))
+ it "does not raise if inspected result is not default external encoding" do
+ utf_16be = mock("utf_16be")
+ utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode!(Encoding::UTF_16BE))
- [utf_16be].send(@method).should == '["utf_16be \u3042"]'
- end
+ [utf_16be].send(@method).should == '["utf_16be \u3042"]'
end
end
end
diff --git a/spec/ruby/core/array/shared/intersection.rb b/spec/ruby/core/array/shared/intersection.rb
new file mode 100644
index 0000000000..49849b08c2
--- /dev/null
+++ b/spec/ruby/core/array/shared/intersection.rb
@@ -0,0 +1,84 @@
+describe :array_intersection, shared: true do
+ it "creates an array with elements common to both arrays (intersection)" do
+ [].send(@method, []).should == []
+ [1, 2].send(@method, []).should == []
+ [].send(@method, [1, 2]).should == []
+ [ 1, 3, 5 ].send(@method, [ 1, 2, 3 ]).should == [1, 3]
+ end
+
+ it "creates an array with no duplicates" do
+ [ 1, 1, 3, 5 ].send(@method, [ 1, 2, 3 ]).uniq!.should == nil
+ end
+
+ it "creates an array with elements in order they are first encountered" do
+ [ 1, 2, 3, 2, 5 ].send(@method, [ 5, 2, 3, 4 ]).should == [2, 3, 5]
+ end
+
+ it "does not modify the original Array" do
+ a = [1, 1, 3, 5]
+ a.send(@method, [1, 2, 3]).should == [1, 3]
+ a.should == [1, 1, 3, 5]
+ end
+
+ it "properly handles recursive arrays" do
+ empty = ArraySpecs.empty_recursive_array
+ empty.send(@method, empty).should == empty
+
+ ArraySpecs.recursive_array.send(@method, []).should == []
+ [].send(@method, ArraySpecs.recursive_array).should == []
+
+ ArraySpecs.recursive_array.send(@method, ArraySpecs.recursive_array).should == [1, 'two', 3.0, ArraySpecs.recursive_array]
+ end
+
+ it "tries to convert the passed argument to an Array using #to_ary" do
+ obj = mock('[1,2,3]')
+ obj.should_receive(:to_ary).and_return([1, 2, 3])
+ [1, 2].send(@method, obj).should == ([1, 2])
+ end
+
+ it "determines equivalence between elements in the sense of eql?" do
+ not_supported_on :opal do
+ [5.0, 4.0].send(@method, [5, 4]).should == []
+ end
+
+ str = "x"
+ [str].send(@method, [str.dup]).should == [str]
+
+ obj1 = mock('1')
+ obj2 = mock('2')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj1.should_receive(:eql?).at_least(1).and_return(true)
+ obj2.stub!(:eql?).and_return(true)
+
+ [obj1].send(@method, [obj2]).should == [obj1]
+ [obj1, obj1, obj2, obj2].send(@method, [obj2]).should == [obj1]
+
+ obj1 = mock('3')
+ obj2 = mock('4')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj1.should_receive(:eql?).at_least(1).and_return(false)
+
+ [obj1].send(@method, [obj2]).should == []
+ [obj1, obj1, obj2, obj2].send(@method, [obj2]).should == [obj2]
+ end
+
+ it "does return subclass instances for Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].send(@method, []).should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
+ [].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
+ end
+
+ it "does not call to_ary on array subclasses" do
+ [5, 6].send(@method, ArraySpecs::ToAryArray[1, 2, 5, 6]).should == [5, 6]
+ end
+
+ it "properly handles an identical item even when its #eql? isn't reflexive" do
+ x = mock('x')
+ x.stub!(:hash).and_return(42)
+ x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
+
+ [x].send(@method, [x]).should == [x]
+ end
+end
diff --git a/spec/ruby/core/array/shared/join.rb b/spec/ruby/core/array/shared/join.rb
index fa66588b47..c443d9a628 100644
--- a/spec/ruby/core/array/shared/join.rb
+++ b/spec/ruby/core/array/shared/join.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
-require File.expand_path('../../fixtures/encoded_strings', __FILE__)
+require_relative '../fixtures/classes'
+require_relative '../fixtures/encoded_strings'
describe :array_join_with_default_separator, shared: true do
before :each do
@@ -19,8 +19,10 @@ describe :array_join_with_default_separator, shared: true do
end
it "returns a string formed by concatenating each String element separated by $," do
- $, = " | "
- ["1", "2", "3"].send(@method).should == "1 | 2 | 3"
+ suppress_warning {
+ $, = " | "
+ ["1", "2", "3"].send(@method).should == "1 | 2 | 3"
+ }
end
it "attempts coercion via #to_str first" do
@@ -47,48 +49,50 @@ describe :array_join_with_default_separator, shared: true do
it "raises a NoMethodError if an element does not respond to #to_str, #to_ary, or #to_s" do
obj = mock('o')
class << obj; undef :to_s; end
- lambda { [1, obj].send(@method) }.should raise_error(NoMethodError)
+ -> { [1, obj].send(@method) }.should raise_error(NoMethodError)
end
it "raises an ArgumentError when the Array is recursive" do
- lambda { ArraySpecs.recursive_array.send(@method) }.should raise_error(ArgumentError)
- lambda { ArraySpecs.head_recursive_array.send(@method) }.should raise_error(ArgumentError)
- lambda { ArraySpecs.empty_recursive_array.send(@method) }.should raise_error(ArgumentError)
+ -> { ArraySpecs.recursive_array.send(@method) }.should raise_error(ArgumentError)
+ -> { ArraySpecs.head_recursive_array.send(@method) }.should raise_error(ArgumentError)
+ -> { ArraySpecs.empty_recursive_array.send(@method) }.should raise_error(ArgumentError)
end
- it "taints the result if the Array is tainted and non-empty" do
- [1, 2].taint.send(@method).tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "taints the result if the Array is tainted and non-empty" do
+ [1, 2].taint.send(@method).tainted?.should be_true
+ end
- it "does not taint the result if the Array is tainted but empty" do
- [].taint.send(@method).tainted?.should be_false
- end
+ it "does not taint the result if the Array is tainted but empty" do
+ [].taint.send(@method).tainted?.should be_false
+ end
- it "taints the result if the result of coercing an element is tainted" do
- s = mock("taint")
- s.should_receive(:to_s).and_return("str".taint)
- [s].send(@method).tainted?.should be_true
- end
+ it "taints the result if the result of coercing an element is tainted" do
+ s = mock("taint")
+ s.should_receive(:to_s).and_return("str".taint)
+ [s].send(@method).tainted?.should be_true
+ end
- it "untrusts the result if the Array is untrusted and non-empty" do
- [1, 2].untrust.send(@method).untrusted?.should be_true
- end
+ it "untrusts the result if the Array is untrusted and non-empty" do
+ [1, 2].untrust.send(@method).untrusted?.should be_true
+ end
- it "does not untrust the result if the Array is untrusted but empty" do
- [].untrust.send(@method).untrusted?.should be_false
- end
+ it "does not untrust the result if the Array is untrusted but empty" do
+ [].untrust.send(@method).untrusted?.should be_false
+ end
- it "untrusts the result if the result of coercing an element is untrusted" do
- s = mock("untrust")
- s.should_receive(:to_s).and_return("str".untrust)
- [s].send(@method).untrusted?.should be_true
+ it "untrusts the result if the result of coercing an element is untrusted" do
+ s = mock("untrust")
+ s.should_receive(:to_s).and_return("str".untrust)
+ [s].send(@method).untrusted?.should be_true
+ end
end
it "uses the first encoding when other strings are compatible" do
ary1 = ArraySpecs.array_with_7bit_utf8_and_usascii_strings
ary2 = ArraySpecs.array_with_usascii_and_7bit_utf8_strings
- ary3 = ArraySpecs.array_with_utf8_and_7bit_ascii8bit_strings
- ary4 = ArraySpecs.array_with_usascii_and_7bit_ascii8bit_strings
+ ary3 = ArraySpecs.array_with_utf8_and_7bit_binary_strings
+ ary4 = ArraySpecs.array_with_usascii_and_7bit_binary_strings
ary1.send(@method).encoding.should == Encoding::UTF_8
ary2.send(@method).encoding.should == Encoding::US_ASCII
@@ -105,9 +109,23 @@ describe :array_join_with_default_separator, shared: true do
end
it "fails for arrays with incompatibly-encoded strings" do
- ary_utf8_bad_ascii8bit = ArraySpecs.array_with_utf8_and_ascii8bit_strings
+ ary_utf8_bad_binary = ArraySpecs.array_with_utf8_and_binary_strings
- lambda { ary_utf8_bad_ascii8bit.send(@method) }.should raise_error(EncodingError)
+ -> { ary_utf8_bad_binary.send(@method) }.should raise_error(EncodingError)
+ end
+
+ ruby_version_is "2.7" do
+ context "when $, is not nil" do
+ before do
+ suppress_warning do
+ $, = '*'
+ end
+ end
+
+ it "warns" do
+ -> { [].join }.should complain(/warning: \$, is set to non-nil value/)
+ end
+ end
end
end
@@ -123,39 +141,41 @@ describe :array_join_with_string_separator, shared: true do
[1, [2, ArraySpecs::MyArray[3, 4], 5], 6].send(@method, ":").should == "1:2:3:4:5:6"
end
- describe "with a tainted separator" do
- before :each do
- @sep = ":".taint
- end
+ ruby_version_is ''...'2.7' do
+ describe "with a tainted separator" do
+ before :each do
+ @sep = ":".taint
+ end
- it "does not taint the result if the array is empty" do
- [].send(@method, @sep).tainted?.should be_false
- end
+ it "does not taint the result if the array is empty" do
+ [].send(@method, @sep).tainted?.should be_false
+ end
- it "does not taint the result if the array has only one element" do
- [1].send(@method, @sep).tainted?.should be_false
- end
+ it "does not taint the result if the array has only one element" do
+ [1].send(@method, @sep).tainted?.should be_false
+ end
- it "taints the result if the array has two or more elements" do
- [1, 2].send(@method, @sep).tainted?.should be_true
+ it "taints the result if the array has two or more elements" do
+ [1, 2].send(@method, @sep).tainted?.should be_true
+ end
end
- end
- describe "with an untrusted separator" do
- before :each do
- @sep = ":".untrust
- end
+ describe "with an untrusted separator" do
+ before :each do
+ @sep = ":".untrust
+ end
- it "does not untrust the result if the array is empty" do
- [].send(@method, @sep).untrusted?.should be_false
- end
+ it "does not untrust the result if the array is empty" do
+ [].send(@method, @sep).untrusted?.should be_false
+ end
- it "does not untrust the result if the array has only one element" do
- [1].send(@method, @sep).untrusted?.should be_false
- end
+ it "does not untrust the result if the array has only one element" do
+ [1].send(@method, @sep).untrusted?.should be_false
+ end
- it "untrusts the result if the array has two or more elements" do
- [1, 2].send(@method, @sep).untrusted?.should be_true
+ it "untrusts the result if the array has two or more elements" do
+ [1, 2].send(@method, @sep).untrusted?.should be_true
+ end
end
end
end
diff --git a/spec/ruby/core/array/shared/keep_if.rb b/spec/ruby/core/array/shared/keep_if.rb
index 581ba31d1b..f26aff028c 100644
--- a/spec/ruby/core/array/shared/keep_if.rb
+++ b/spec/ruby/core/array/shared/keep_if.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../enumerable/shared/enumeratorized'
describe :keep_if, shared: true do
it "deletes elements for which the block returns a false value" do
@@ -37,23 +37,23 @@ describe :keep_if, shared: true do
describe "with truthy block" do
it "keeps elements after any exception" do
- lambda { @frozen.send(@method) { true } }.should raise_error(Exception)
+ -> { @frozen.send(@method) { true } }.should raise_error(Exception)
@frozen.should == @origin
end
- it "raises a RuntimeError" do
- lambda { @frozen.send(@method) { true } }.should raise_error(RuntimeError)
+ it "raises a FrozenError" do
+ -> { @frozen.send(@method) { true } }.should raise_error(FrozenError)
end
end
describe "with falsy block" do
it "keeps elements after any exception" do
- lambda { @frozen.send(@method) { false } }.should raise_error(Exception)
+ -> { @frozen.send(@method) { false } }.should raise_error(Exception)
@frozen.should == @origin
end
- it "raises a RuntimeError" do
- lambda { @frozen.send(@method) { false } }.should raise_error(RuntimeError)
+ it "raises a FrozenError" do
+ -> { @frozen.send(@method) { false } }.should raise_error(FrozenError)
end
end
end
diff --git a/spec/ruby/core/array/shared/push.rb b/spec/ruby/core/array/shared/push.rb
new file mode 100644
index 0000000000..ac790fb6a4
--- /dev/null
+++ b/spec/ruby/core/array/shared/push.rb
@@ -0,0 +1,33 @@
+describe :array_push, shared: true do
+ it "appends the arguments to the array" do
+ a = [ "a", "b", "c" ]
+ a.send(@method, "d", "e", "f").should equal(a)
+ a.send(@method).should == ["a", "b", "c", "d", "e", "f"]
+ a.send(@method, 5)
+ a.should == ["a", "b", "c", "d", "e", "f", 5]
+
+ a = [0, 1]
+ a.send(@method, 2)
+ a.should == [0, 1, 2]
+ end
+
+ it "isn't confused by previous shift" do
+ a = [ "a", "b", "c" ]
+ a.shift
+ a.send(@method, "foo")
+ a.should == ["b", "c", "foo"]
+ end
+
+ it "properly handles recursive arrays" do
+ empty = ArraySpecs.empty_recursive_array
+ empty.send(@method, :last).should == [empty, :last]
+
+ array = ArraySpecs.recursive_array
+ array.send(@method, :last).should == [1, 'two', 3.0, array, array, array, array, array, :last]
+ end
+
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.send(@method, 1) }.should raise_error(FrozenError)
+ -> { ArraySpecs.frozen_array.send(@method) }.should raise_error(FrozenError)
+ end
+end
diff --git a/spec/ruby/core/array/shared/replace.rb b/spec/ruby/core/array/shared/replace.rb
index 8442d9a841..9a6e60c1b0 100644
--- a/spec/ruby/core/array/shared/replace.rb
+++ b/spec/ruby/core/array/shared/replace.rb
@@ -52,9 +52,9 @@ describe :array_replace, shared: true do
[].send(@method, ArraySpecs::ToAryArray[5, 6, 7]).should == [5, 6, 7]
end
- it "raises a RuntimeError on a frozen array" do
- lambda {
+ it "raises a FrozenError on a frozen array" do
+ -> {
ArraySpecs.frozen_array.send(@method, ArraySpecs.frozen_array)
- }.should raise_error(RuntimeError)
+ }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/shared/select.rb b/spec/ruby/core/array/shared/select.rb
new file mode 100644
index 0000000000..09101e8ab5
--- /dev/null
+++ b/spec/ruby/core/array/shared/select.rb
@@ -0,0 +1,32 @@
+require_relative '../../../spec_helper'
+require_relative '../fixtures/classes'
+require_relative '../shared/enumeratorize'
+require_relative '../shared/keep_if'
+require_relative '../../enumerable/shared/enumeratorized'
+
+describe :array_select, shared: true do
+ it_should_behave_like :enumeratorize
+
+ before :each do
+ @object = [1,2,3]
+ end
+ it_should_behave_like :enumeratorized_with_origin_size
+
+ it "returns a new array of elements for which block is true" do
+ [1, 3, 4, 5, 6, 9].send(@method) { |i| i % ((i + 1) / 2) == 0}.should == [1, 4, 6]
+ end
+
+ it "does not return subclass instance on Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].send(@method) { true }.should be_an_instance_of(Array)
+ end
+
+ it "properly handles recursive arrays" do
+ empty = ArraySpecs.empty_recursive_array
+ empty.send(@method) { true }.should == empty
+ empty.send(@method) { false }.should == []
+
+ array = ArraySpecs.recursive_array
+ array.send(@method) { true }.should == [1, 'two', 3.0, array, array, array, array, array]
+ array.send(@method) { false }.should == []
+ end
+end
diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb
index b3f4ccb9a6..820047cdb2 100644
--- a/spec/ruby/core/array/shared/slice.rb
+++ b/spec/ruby/core/array/shared/slice.rb
@@ -117,6 +117,27 @@ describe :array_slice, shared: true do
a.send(@method, 0, obj).should == [1, 2]
end
+ it "raises TypeError if to_int returns non-integer" do
+ from = mock('from')
+ to = mock('to')
+
+ # So we can construct a range out of them...
+ def from.<=>(o) 0 end
+ def to.<=>(o) 0 end
+
+ a = [1, 2, 3, 4, 5]
+
+ def from.to_int() 'cat' end
+ def to.to_int() -2 end
+
+ -> { a.send(@method, from..to) }.should raise_error(TypeError)
+
+ def from.to_int() 1 end
+ def to.to_int() 'cat' end
+
+ -> { a.send(@method, from..to) }.should raise_error(TypeError)
+ end
+
it "returns the elements specified by Range indexes with [m..n]" do
[ "a", "b", "c", "d", "e" ].send(@method, 1..3).should == ["b", "c", "d"]
[ "a", "b", "c", "d", "e" ].send(@method, 4..-1).should == ['e']
@@ -266,10 +287,10 @@ describe :array_slice, shared: true do
a.send(@method, 1..0).should == []
a.send(@method, 1...0).should == []
- lambda { a.send(@method, "a" .. "b") }.should raise_error(TypeError)
- lambda { a.send(@method, "a" ... "b") }.should raise_error(TypeError)
- lambda { a.send(@method, from .. "b") }.should raise_error(TypeError)
- lambda { a.send(@method, from ... "b") }.should raise_error(TypeError)
+ -> { a.send(@method, "a" .. "b") }.should raise_error(TypeError)
+ -> { a.send(@method, "a" ... "b") }.should raise_error(TypeError)
+ -> { a.send(@method, from .. "b") }.should raise_error(TypeError)
+ -> { a.send(@method, from ... "b") }.should raise_error(TypeError)
end
it "returns the same elements as [m..n] and [m...n] with Range subclasses" do
@@ -376,28 +397,56 @@ describe :array_slice, shared: true do
@array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
end
- it "returns a subclass instance with [n, m]" do
- @array.send(@method, 0, 2).should be_an_instance_of(ArraySpecs::MyArray)
- end
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance with [n, m]" do
+ @array.send(@method, 0, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a subclass instance with [-n, m]" do
- @array.send(@method, -3, 2).should be_an_instance_of(ArraySpecs::MyArray)
- end
+ it "returns a subclass instance with [-n, m]" do
+ @array.send(@method, -3, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a subclass instance with [n..m]" do
- @array.send(@method, 1..3).should be_an_instance_of(ArraySpecs::MyArray)
- end
+ it "returns a subclass instance with [n..m]" do
+ @array.send(@method, 1..3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a subclass instance with [n...m]" do
- @array.send(@method, 1...3).should be_an_instance_of(ArraySpecs::MyArray)
- end
+ it "returns a subclass instance with [n...m]" do
+ @array.send(@method, 1...3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n..-m]" do
+ @array.send(@method, -3..-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a subclass instance with [-n..-m]" do
- @array.send(@method, -3..-1).should be_an_instance_of(ArraySpecs::MyArray)
+ it "returns a subclass instance with [-n...-m]" do
+ @array.send(@method, -3...-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
end
- it "returns a subclass instance with [-n...-m]" do
- @array.send(@method, -3...-1).should be_an_instance_of(ArraySpecs::MyArray)
+ ruby_version_is '3.0' do
+ it "returns a Array instance with [n, m]" do
+ @array.send(@method, 0, 2).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n, m]" do
+ @array.send(@method, -3, 2).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [n..m]" do
+ @array.send(@method, 1..3).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [n...m]" do
+ @array.send(@method, 1...3).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n..-m]" do
+ @array.send(@method, -3..-1).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n...-m]" do
+ @array.send(@method, -3...-1).should be_an_instance_of(Array)
+ end
end
it "returns an empty array when m == n with [m...n]" do
@@ -437,23 +486,38 @@ describe :array_slice, shared: true do
end
end
- it "raises a RangeError when the start index is out of range of Fixnum" do
+ it "raises a RangeError when the start index is out of range of Integer" do
array = [1, 2, 3, 4, 5, 6]
obj = mock('large value')
- obj.should_receive(:to_int).and_return(0x8000_0000_0000_0000_0000)
- lambda { array.send(@method, obj) }.should raise_error(RangeError)
+ obj.should_receive(:to_int).and_return(bignum_value)
+ -> { array.send(@method, obj) }.should raise_error(RangeError)
obj = 8e19
- lambda { array.send(@method, obj) }.should raise_error(RangeError)
+ -> { array.send(@method, obj) }.should raise_error(RangeError)
+
+ # boundary value when longs are 64 bits
+ -> { array.send(@method, 2.0**63) }.should raise_error(RangeError)
+
+ # just under the boundary value when longs are 64 bits
+ array.send(@method, max_long.to_f.prev_float).should == nil
end
- it "raises a RangeError when the length is out of range of Fixnum" do
+ it "raises a RangeError when the length is out of range of Integer" do
array = [1, 2, 3, 4, 5, 6]
obj = mock('large value')
- obj.should_receive(:to_int).and_return(0x8000_0000_0000_0000_0000)
- lambda { array.send(@method, 1, obj) }.should raise_error(RangeError)
+ obj.should_receive(:to_int).and_return(bignum_value)
+ -> { array.send(@method, 1, obj) }.should raise_error(RangeError)
obj = 8e19
- lambda { array.send(@method, 1, obj) }.should raise_error(RangeError)
+ -> { array.send(@method, 1, obj) }.should raise_error(RangeError)
+ end
+
+ it "raises a type error if a range is passed with a length" do
+ ->{ [1, 2, 3].send(@method, 1..2, 1) }.should raise_error(TypeError)
+ end
+
+ it "raises a RangeError if passed a range with a bound that is too large" do
+ -> { "hello".send(@method, bignum_value..(bignum_value + 1)) }.should raise_error(RangeError)
+ -> { "hello".send(@method, 0..bignum_value) }.should raise_error(RangeError)
end
end
diff --git a/spec/ruby/core/array/shared/union.rb b/spec/ruby/core/array/shared/union.rb
new file mode 100644
index 0000000000..0b60df9ca4
--- /dev/null
+++ b/spec/ruby/core/array/shared/union.rb
@@ -0,0 +1,79 @@
+describe :array_binary_union, shared: true do
+ it "returns an array of elements that appear in either array (union)" do
+ [].send(@method, []).should == []
+ [1, 2].send(@method, []).should == [1, 2]
+ [].send(@method, [1, 2]).should == [1, 2]
+ [ 1, 2, 3, 4 ].send(@method, [ 3, 4, 5 ]).should == [1, 2, 3, 4, 5]
+ end
+
+ it "creates an array with no duplicates" do
+ [ 1, 2, 3, 1, 4, 5 ].send(@method, [ 1, 3, 4, 5, 3, 6 ]).should == [1, 2, 3, 4, 5, 6]
+ end
+
+ it "creates an array with elements in order they are first encountered" do
+ [ 1, 2, 3, 1 ].send(@method, [ 1, 3, 4, 5 ]).should == [1, 2, 3, 4, 5]
+ end
+
+ it "properly handles recursive arrays" do
+ empty = ArraySpecs.empty_recursive_array
+ empty.send(@method, empty).should == empty
+
+ array = ArraySpecs.recursive_array
+ array.send(@method, []).should == [1, 'two', 3.0, array]
+ [].send(@method, array).should == [1, 'two', 3.0, array]
+ array.send(@method, array).should == [1, 'two', 3.0, array]
+ array.send(@method, empty).should == [1, 'two', 3.0, array, empty]
+ end
+
+ it "tries to convert the passed argument to an Array using #to_ary" do
+ obj = mock('[1,2,3]')
+ obj.should_receive(:to_ary).and_return([1, 2, 3])
+ [0].send(@method, obj).should == ([0] | [1, 2, 3])
+ end
+
+ # MRI follows hashing semantics here, so doesn't actually call eql?/hash for Integer/Symbol
+ it "acts as if using an intermediate hash to collect values" do
+ not_supported_on :opal do
+ [5.0, 4.0].send(@method, [5, 4]).should == [5.0, 4.0, 5, 4]
+ end
+
+ str = "x"
+ [str].send(@method, [str.dup]).should == [str]
+
+ obj1 = mock('1')
+ obj2 = mock('2')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj2.should_receive(:eql?).at_least(1).and_return(true)
+
+ [obj1].send(@method, [obj2]).should == [obj1]
+ [obj1, obj1, obj2, obj2].send(@method, [obj2]).should == [obj1]
+
+ obj1 = mock('3')
+ obj2 = mock('4')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj2.should_receive(:eql?).at_least(1).and_return(false)
+
+ [obj1].send(@method, [obj2]).should == [obj1, obj2]
+ [obj1, obj1, obj2, obj2].send(@method, [obj2]).should == [obj1, obj2]
+ end
+
+ it "does not return subclass instances for Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].send(@method, []).should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
+ [].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
+ end
+
+ it "does not call to_ary on array subclasses" do
+ [1, 2].send(@method, ArraySpecs::ToAryArray[5, 6]).should == [1, 2, 5, 6]
+ end
+
+ it "properly handles an identical item even when its #eql? isn't reflexive" do
+ x = mock('x')
+ x.stub!(:hash).and_return(42)
+ x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
+
+ [x].send(@method, [x]).should == [x]
+ end
+end
diff --git a/spec/ruby/core/array/shared/unshift.rb b/spec/ruby/core/array/shared/unshift.rb
new file mode 100644
index 0000000000..fc82e19e2a
--- /dev/null
+++ b/spec/ruby/core/array/shared/unshift.rb
@@ -0,0 +1,46 @@
+describe :array_unshift, shared: true do
+ it "prepends object to the original array" do
+ a = [1, 2, 3]
+ a.send(@method, "a").should equal(a)
+ a.should == ['a', 1, 2, 3]
+ a.send(@method).should equal(a)
+ a.should == ['a', 1, 2, 3]
+ a.send(@method, 5, 4, 3)
+ a.should == [5, 4, 3, 'a', 1, 2, 3]
+
+ # shift all but one element
+ a = [1, 2]
+ a.shift
+ a.send(@method, 3, 4)
+ a.should == [3, 4, 2]
+
+ # now shift all elements
+ a.shift
+ a.shift
+ a.shift
+ a.send(@method, 3, 4)
+ a.should == [3, 4]
+ end
+
+ it "quietly ignores unshifting nothing" do
+ [].send(@method).should == []
+ end
+
+ it "properly handles recursive arrays" do
+ empty = ArraySpecs.empty_recursive_array
+ empty.send(@method, :new).should == [:new, empty]
+
+ array = ArraySpecs.recursive_array
+ array.send(@method, :new)
+ array[0..5].should == [:new, 1, 'two', 3.0, array, array]
+ end
+
+ it "raises a FrozenError on a frozen array when the array is modified" do
+ -> { ArraySpecs.frozen_array.send(@method, 1) }.should raise_error(FrozenError)
+ end
+
+ # see [ruby-core:23666]
+ it "raises a FrozenError on a frozen array when the array would not be modified" do
+ -> { ArraySpecs.frozen_array.send(@method) }.should raise_error(FrozenError)
+ end
+end
diff --git a/spec/ruby/core/array/shift_spec.rb b/spec/ruby/core/array/shift_spec.rb
index e5d25e2050..b998e45d28 100644
--- a/spec/ruby/core/array/shift_spec.rb
+++ b/spec/ruby/core/array/shift_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#shift" do
it "removes and returns the first element" do
@@ -30,11 +30,11 @@ describe "Array#shift" do
array[0..2].should == ['two', 3.0, array]
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.shift }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.shift }.should raise_error(FrozenError)
end
- it "raises a RuntimeError on an empty frozen array" do
- lambda { ArraySpecs.empty_frozen_array.shift }.should raise_error(RuntimeError)
+ it "raises a FrozenError on an empty frozen array" do
+ -> { ArraySpecs.empty_frozen_array.shift }.should raise_error(FrozenError)
end
describe "passed a number n as an argument" do
@@ -90,7 +90,7 @@ describe "Array#shift" do
end
it "raises an ArgumentError if n is negative" do
- lambda{ [1, 2, 3].shift(-1) }.should raise_error(ArgumentError)
+ ->{ [1, 2, 3].shift(-1) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
@@ -104,31 +104,33 @@ describe "Array#shift" do
a.should == []
end
- it "raises a TypeError when the passed n can be coerced to Integer" do
- lambda{ [1, 2].shift("cat") }.should raise_error(TypeError)
- lambda{ [1, 2].shift(nil) }.should raise_error(TypeError)
+ it "raises a TypeError when the passed n cannot be coerced to Integer" do
+ ->{ [1, 2].shift("cat") }.should raise_error(TypeError)
+ ->{ [1, 2].shift(nil) }.should raise_error(TypeError)
end
it "raises an ArgumentError if more arguments are passed" do
- lambda{ [1, 2].shift(1, 2) }.should raise_error(ArgumentError)
+ ->{ [1, 2].shift(1, 2) }.should raise_error(ArgumentError)
end
it "does not return subclass instances with Array subclass" do
ArraySpecs::MyArray[1, 2, 3].shift(2).should be_an_instance_of(Array)
end
- it "returns an untainted array even if the array is tainted" do
- ary = [1, 2].taint
- ary.shift(2).tainted?.should be_false
- ary.shift(0).tainted?.should be_false
- end
-
- it "keeps taint status" do
- a = [1, 2].taint
- a.shift(2)
- a.tainted?.should be_true
- a.shift(2)
- a.tainted?.should be_true
+ ruby_version_is ''...'2.7' do
+ it "returns an untainted array even if the array is tainted" do
+ ary = [1, 2].taint
+ ary.shift(2).tainted?.should be_false
+ ary.shift(0).tainted?.should be_false
+ end
+
+ it "keeps taint status" do
+ a = [1, 2].taint
+ a.shift(2)
+ a.tainted?.should be_true
+ a.shift(2)
+ a.tainted?.should be_true
+ end
end
end
end
diff --git a/spec/ruby/core/array/shuffle_spec.rb b/spec/ruby/core/array/shuffle_spec.rb
index 4c3b820186..b255147c75 100644
--- a/spec/ruby/core/array/shuffle_spec.rb
+++ b/spec/ruby/core/array/shuffle_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#shuffle" do
it "returns the same values, in a usually different order" do
@@ -25,12 +25,6 @@ describe "Array#shuffle" do
ArraySpecs::MyArray[1, 2, 3].shuffle.should be_an_instance_of(Array)
end
- it "attempts coercion via #to_hash" do
- obj = mock('hash')
- obj.should_receive(:to_hash).once.and_return({})
- [2, 3].shuffle(obj)
- end
-
it "calls #rand on the Object passed by the :random key in the arguments Hash" do
obj = mock("array_shuffle_random")
obj.should_receive(:rand).at_least(1).times.and_return(0.5)
@@ -43,7 +37,7 @@ describe "Array#shuffle" do
it "raises a NoMethodError if an object passed for the RNG does not define #rand" do
obj = BasicObject.new
- lambda { [1, 2].shuffle(random: obj) }.should raise_error(NoMethodError)
+ -> { [1, 2].shuffle(random: obj) }.should raise_error(NoMethodError)
end
it "accepts a Float for the value returned by #rand" do
@@ -68,7 +62,7 @@ describe "Array#shuffle" do
random = mock("array_shuffle_random")
random.should_receive(:rand).and_return(value)
- lambda { [1, 2].shuffle(random: random) }.should raise_error(RangeError)
+ -> { [1, 2].shuffle(random: random) }.should raise_error(RangeError)
end
it "raises a RangeError if the value is equal to one" do
@@ -77,7 +71,7 @@ describe "Array#shuffle" do
random = mock("array_shuffle_random")
random.should_receive(:rand).at_least(1).times.and_return(value)
- lambda { [1, 2].shuffle(random: random) }.should raise_error(RangeError)
+ -> { [1, 2].shuffle(random: random) }.should raise_error(RangeError)
end
end
@@ -95,8 +89,8 @@ describe "Array#shuffle!" do
a.should equal(original)
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.shuffle! }.should raise_error(RuntimeError)
- lambda { ArraySpecs.empty_frozen_array.shuffle! }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.shuffle! }.should raise_error(FrozenError)
+ -> { ArraySpecs.empty_frozen_array.shuffle! }.should raise_error(FrozenError)
end
end
diff --git a/spec/ruby/core/array/size_spec.rb b/spec/ruby/core/array/size_spec.rb
index 2c8a18ade6..d68f956a83 100644
--- a/spec/ruby/core/array/size_spec.rb
+++ b/spec/ruby/core/array/size_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/length', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/length'
describe "Array#size" do
- it_behaves_like(:array_length, :size)
+ it_behaves_like :array_length, :size
end
diff --git a/spec/ruby/core/array/slice_spec.rb b/spec/ruby/core/array/slice_spec.rb
index f6cbd1bcc4..3829794938 100644
--- a/spec/ruby/core/array/slice_spec.rb
+++ b/spec/ruby/core/array/slice_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/slice', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/slice'
describe "Array#slice!" do
it "removes and return the element at index" do
@@ -116,8 +116,8 @@ describe "Array#slice!" do
a.slice!(from .. to).should == [2, 3, 4]
a.should == [1, 5]
- lambda { a.slice!("a" .. "b") }.should raise_error(TypeError)
- lambda { a.slice!(from .. "b") }.should raise_error(TypeError)
+ -> { a.slice!("a" .. "b") }.should raise_error(TypeError)
+ -> { a.slice!(from .. "b") }.should raise_error(TypeError)
end
it "returns last element for consecutive calls at zero index" do
@@ -150,11 +150,23 @@ describe "Array#slice!" do
a.should == [1, 2]
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.slice!(0, 0) }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.slice!(0, 0) }.should raise_error(FrozenError)
+ end
+
+ ruby_version_is "2.6" do
+ it "works with endless ranges" do
+ a = [1, 2, 3]
+ a.slice!(eval("(1..)")).should == [2, 3]
+ a.should == [1]
+
+ a = [1, 2, 3]
+ a.slice!(eval("(2...)")).should == [3]
+ a.should == [1, 2]
+ end
end
end
describe "Array#slice" do
- it_behaves_like(:array_slice, :slice)
+ it_behaves_like :array_slice, :slice
end
diff --git a/spec/ruby/core/array/sort_by_spec.rb b/spec/ruby/core/array/sort_by_spec.rb
index 9f45f3ef4d..7cea6ec6d3 100644
--- a/spec/ruby/core/array/sort_by_spec.rb
+++ b/spec/ruby/core/array/sort_by_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative '../enumerable/shared/enumeratorized'
describe "Array#sort_by!" do
it "sorts array in place by passing each element to the given block" do
@@ -23,12 +23,12 @@ describe "Array#sort_by!" do
a.should be_an_instance_of(Array)
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.sort_by! {}}.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.sort_by! {}}.should raise_error(FrozenError)
end
- it "raises a RuntimeError on an empty frozen array" do
- lambda { ArraySpecs.empty_frozen_array.sort_by! {}}.should raise_error(RuntimeError)
+ it "raises a FrozenError on an empty frozen array" do
+ -> { ArraySpecs.empty_frozen_array.sort_by! {}}.should raise_error(FrozenError)
end
it "returns the specified value when it would break in the given block" do
diff --git a/spec/ruby/core/array/sort_spec.rb b/spec/ruby/core/array/sort_spec.rb
index 584b818caf..e20b650516 100644
--- a/spec/ruby/core/array/sort_spec.rb
+++ b/spec/ruby/core/array/sort_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#sort" do
it "returns a new array sorted based on comparing elements with <=>" do
@@ -58,15 +58,17 @@ describe "Array#sort" do
b = ArraySpecs::MockForCompared.new
c = ArraySpecs::MockForCompared.new
- ArraySpecs::MockForCompared.compared?.should == false
+ ArraySpecs::MockForCompared.should_not.compared?
[a, b, c].sort.should == [c, b, a]
- ArraySpecs::MockForCompared.compared?.should == true
+ ArraySpecs::MockForCompared.should.compared?
end
it "does not deal with exceptions raised by unimplemented or incorrect #<=>" do
o = Object.new
- lambda { [o, 1].sort }.should raise_error
+ -> {
+ [o, 1].sort
+ }.should raise_error(ArgumentError)
end
it "may take a block which is used to determine the order of objects a and b described as -1, 0 or +1" do
@@ -76,7 +78,7 @@ describe "Array#sort" do
end
it "raises an error when a given block returns nil" do
- lambda { [1, 2].sort {} }.should raise_error(ArgumentError)
+ -> { [1, 2].sort {} }.should raise_error(ArgumentError)
end
it "does not call #<=> on contained objects when invoked with a block" do
@@ -102,17 +104,17 @@ describe "Array#sort" do
it "does not freezes self during being sorted" do
a = [1, 2, 3]
- a.sort { |x,y| a.frozen?.should == false; x <=> y }
+ a.sort { |x,y| a.should_not.frozen?; x <=> y }
end
it "returns the specified value when it would break in the given block" do
[1, 2, 3].sort{ break :a }.should == :a
end
- it "uses the sign of Bignum block results as the sort result" do
+ it "uses the sign of Integer block results as the sort result" do
a = [1, 2, 5, 10, 7, -4, 12]
begin
- class Bignum;
+ class Integer
alias old_spaceship <=>
def <=>(other)
raise
@@ -120,7 +122,7 @@ describe "Array#sort" do
end
a.sort {|n, m| (n - m) * (2 ** 200)}.should == [-4, 1, 2, 5, 7, 10, 12]
ensure
- class Bignum
+ class Integer
alias <=> old_spaceship
end
end
@@ -130,9 +132,9 @@ describe "Array#sort" do
a = [1, 2, 5, 10, 7, -4, 12]
a.sort { |n, m| n - m }.should == [-4, 1, 2, 5, 7, 10, 12]
a.sort { |n, m|
- ArraySpecs::ComparableWithFixnum.new(n-m)
+ ArraySpecs::ComparableWithInteger.new(n-m)
}.should == [-4, 1, 2, 5, 7, 10, 12]
- lambda {
+ -> {
a.sort { |n, m| (n - m).to_s }
}.should raise_error(ArgumentError)
end
@@ -153,7 +155,7 @@ describe "Array#sort" do
it "raises an error if objects can't be compared" do
a=[ArraySpecs::Uncomparable.new, ArraySpecs::Uncomparable.new]
- lambda {a.sort}.should raise_error(ArgumentError)
+ -> {a.sort}.should raise_error(ArgumentError)
end
# From a strange Rubinius bug
@@ -205,9 +207,9 @@ describe "Array#sort!" do
b = ArraySpecs::MockForCompared.new
c = ArraySpecs::MockForCompared.new
- ArraySpecs::MockForCompared.compared?.should == false
+ ArraySpecs::MockForCompared.should_not.compared?
[a, b, c].sort!.should == [c, b, a]
- ArraySpecs::MockForCompared.compared?.should == true
+ ArraySpecs::MockForCompared.should.compared?
end
it "does not call #<=> on contained objects when invoked with a block" do
@@ -231,8 +233,8 @@ describe "Array#sort!" do
a.sort!{ -1 }.should be_an_instance_of(Array)
end
- it "raises a RuntimeError on a frozen array" do
- lambda { ArraySpecs.frozen_array.sort! }.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array" do
+ -> { ArraySpecs.frozen_array.sort! }.should raise_error(FrozenError)
end
it "returns the specified value when it would break in the given block" do
diff --git a/spec/ruby/core/array/sum_spec.rb b/spec/ruby/core/array/sum_spec.rb
new file mode 100644
index 0000000000..39c769d328
--- /dev/null
+++ b/spec/ruby/core/array/sum_spec.rb
@@ -0,0 +1,42 @@
+require_relative '../../spec_helper'
+
+describe "Array#sum" do
+ it "returns the sum of elements" do
+ [1, 2, 3].sum.should == 6
+ end
+
+ it "applies a block to each element before adding if it's given" do
+ [1, 2, 3].sum { |i| i * 10 }.should == 60
+ end
+
+ it "returns init value if array is empty" do
+ [].sum(-1).should == -1
+ end
+
+ it "returns 0 if array is empty and init is omitted" do
+ [].sum.should == 0
+ end
+
+ it "adds init value to the sum of elements" do
+ [1, 2, 3].sum(10).should == 16
+ end
+
+ it "can be used for non-numeric objects by providing init value" do
+ ["a", "b", "c"].sum("").should == "abc"
+ end
+
+ it 'raises TypeError if any element are not numeric' do
+ -> { ["a"].sum }.should raise_error(TypeError)
+ end
+
+ it 'raises TypeError if any element cannot be added to init value' do
+ -> { [1].sum([]) }.should raise_error(TypeError)
+ end
+
+ it "calls + to sum the elements" do
+ a = mock("a")
+ b = mock("b")
+ a.should_receive(:+).with(b).and_return(42)
+ [b].sum(a).should == 42
+ end
+end
diff --git a/spec/ruby/core/array/take_spec.rb b/spec/ruby/core/array/take_spec.rb
index 6ba87706cf..0de99b0a7e 100644
--- a/spec/ruby/core/array/take_spec.rb
+++ b/spec/ruby/core/array/take_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#take" do
it "returns the first specified number of elements" do
@@ -22,6 +22,6 @@ describe "Array#take" do
end
it "raises an ArgumentError when the argument is negative" do
- lambda{ [1].take(-3) }.should raise_error(ArgumentError)
+ ->{ [1].take(-3) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/array/take_while_spec.rb b/spec/ruby/core/array/take_while_spec.rb
index a97f304490..f159e6f251 100644
--- a/spec/ruby/core/array/take_while_spec.rb
+++ b/spec/ruby/core/array/take_while_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Array#take_while" do
it "returns all elements until the block returns false" do
diff --git a/spec/ruby/core/array/to_a_spec.rb b/spec/ruby/core/array/to_a_spec.rb
index f3761a275e..49d0a4782e 100644
--- a/spec/ruby/core/array/to_a_spec.rb
+++ b/spec/ruby/core/array/to_a_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#to_a" do
it "returns self" do
diff --git a/spec/ruby/core/array/to_ary_spec.rb b/spec/ruby/core/array/to_ary_spec.rb
index ab4dfdb5ed..314699b709 100644
--- a/spec/ruby/core/array/to_ary_spec.rb
+++ b/spec/ruby/core/array/to_ary_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#to_ary" do
it "returns self" do
diff --git a/spec/ruby/core/array/to_h_spec.rb b/spec/ruby/core/array/to_h_spec.rb
index 17783914aa..46a79ba58b 100644
--- a/spec/ruby/core/array/to_h_spec.rb
+++ b/spec/ruby/core/array/to_h_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#to_h" do
it "converts empty array to empty hash" do
@@ -24,14 +24,58 @@ describe "Array#to_h" do
end
it "raises TypeError if an element is not an array" do
- lambda { [:x].to_h }.should raise_error(TypeError)
+ -> { [:x].to_h }.should raise_error(TypeError)
end
it "raises ArgumentError if an element is not a [key, value] pair" do
- lambda { [[:x]].to_h }.should raise_error(ArgumentError)
+ -> { [[:x]].to_h }.should raise_error(ArgumentError)
end
it "does not accept arguments" do
- lambda { [].to_h(:a, :b) }.should raise_error(ArgumentError)
+ -> { [].to_h(:a, :b) }.should raise_error(ArgumentError)
+ end
+
+ it "produces a hash that returns nil for a missing element" do
+ [[:a, 1], [:b, 2]].to_h[:c].should be_nil
+ end
+
+ ruby_version_is "2.6" do
+ context "with block" do
+ it "converts [key, value] pairs returned by the block to a Hash" do
+ [:a, :b].to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' }
+ end
+
+ it "raises ArgumentError if block returns longer or shorter array" do
+ -> do
+ [:a, :b].to_h { |k| [k, k.to_s, 1] }
+ end.should raise_error(ArgumentError, /wrong array length at 0/)
+
+ -> do
+ [:a, :b].to_h { |k| [k] }
+ end.should raise_error(ArgumentError, /wrong array length at 0/)
+ end
+
+ it "raises TypeError if block returns something other than Array" do
+ -> do
+ [:a, :b].to_h { |k| "not-array" }
+ end.should raise_error(TypeError, /wrong element type String at 0/)
+ end
+
+ it "coerces returned pair to Array with #to_ary" do
+ x = mock('x')
+ x.stub!(:to_ary).and_return([:b, 'b'])
+
+ [:a].to_h { |k| x }.should == { :b => 'b' }
+ end
+
+ it "does not coerce returned pair to Array with #to_a" do
+ x = mock('x')
+ x.stub!(:to_a).and_return([:b, 'b'])
+
+ -> do
+ [:a].to_h { |k| x }
+ end.should raise_error(TypeError, /wrong element type MockObject at 0/)
+ end
+ end
end
end
diff --git a/spec/ruby/core/array/to_s_spec.rb b/spec/ruby/core/array/to_s_spec.rb
index 3a34d5ee0e..e8476702ec 100644
--- a/spec/ruby/core/array/to_s_spec.rb
+++ b/spec/ruby/core/array/to_s_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/join', __FILE__)
-require File.expand_path('../shared/inspect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/join'
+require_relative 'shared/inspect'
describe "Array#to_s" do
it_behaves_like :array_inspect, :to_s
diff --git a/spec/ruby/core/array/transpose_spec.rb b/spec/ruby/core/array/transpose_spec.rb
index a8edad7bab..b39077f4c9 100644
--- a/spec/ruby/core/array/transpose_spec.rb
+++ b/spec/ruby/core/array/transpose_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#transpose" do
it "assumes an array of arrays and returns the result of transposing rows and columns" do
@@ -32,7 +32,7 @@ describe "Array#transpose" do
end
it "raises a TypeError if the passed Argument does not respond to #to_ary" do
- lambda { [Object.new, [:a, :b]].transpose }.should raise_error(TypeError)
+ -> { [Object.new, [:a, :b]].transpose }.should raise_error(TypeError)
end
it "does not call to_ary on array subclass elements" do
@@ -41,7 +41,7 @@ describe "Array#transpose" do
end
it "raises an IndexError if the arrays are not of the same length" do
- lambda { [[1, 2], [:a]].transpose }.should raise_error(IndexError)
+ -> { [[1, 2], [:a]].transpose }.should raise_error(IndexError)
end
it "does not return subclass instance on Array subclasses" do
diff --git a/spec/ruby/core/array/try_convert_spec.rb b/spec/ruby/core/array/try_convert_spec.rb
index 5d8f9f100f..47b4722d80 100644
--- a/spec/ruby/core/array/try_convert_spec.rb
+++ b/spec/ruby/core/array/try_convert_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array.try_convert" do
it "returns the argument if it's an Array" do
@@ -39,12 +39,12 @@ describe "Array.try_convert" do
it "sends #to_ary to the argument and raises TypeError if it's not a kind of Array" do
obj = mock("to_ary")
obj.should_receive(:to_ary).and_return(Object.new)
- lambda { Array.try_convert obj }.should raise_error(TypeError)
+ -> { Array.try_convert obj }.should raise_error(TypeError)
end
it "does not rescue exceptions raised by #to_ary" do
obj = mock("to_ary")
obj.should_receive(:to_ary).and_raise(RuntimeError)
- lambda { Array.try_convert obj }.should raise_error(RuntimeError)
+ -> { Array.try_convert obj }.should raise_error(RuntimeError)
end
end
diff --git a/spec/ruby/core/array/union_spec.rb b/spec/ruby/core/array/union_spec.rb
index 58fe23448d..1dca47696d 100644
--- a/spec/ruby/core/array/union_spec.rb
+++ b/spec/ruby/core/array/union_spec.rb
@@ -1,82 +1,27 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/union'
describe "Array#|" do
- it "returns an array of elements that appear in either array (union)" do
- ([] | []).should == []
- ([1, 2] | []).should == [1, 2]
- ([] | [1, 2]).should == [1, 2]
- ([ 1, 2, 3, 4 ] | [ 3, 4, 5 ]).should == [1, 2, 3, 4, 5]
- end
-
- it "creates an array with no duplicates" do
- ([ 1, 2, 3, 1, 4, 5 ] | [ 1, 3, 4, 5, 3, 6 ]).should == [1, 2, 3, 4, 5, 6]
- end
-
- it "creates an array with elements in order they are first encountered" do
- ([ 1, 2, 3, 1 ] | [ 1, 3, 4, 5 ]).should == [1, 2, 3, 4, 5]
- end
-
- it "properly handles recursive arrays" do
- empty = ArraySpecs.empty_recursive_array
- (empty | empty).should == empty
+ it_behaves_like :array_binary_union, :|
+end
- array = ArraySpecs.recursive_array
- (array | []).should == [1, 'two', 3.0, array]
- ([] | array).should == [1, 'two', 3.0, array]
- (array | array).should == [1, 'two', 3.0, array]
- (array | empty).should == [1, 'two', 3.0, array, empty]
- end
+ruby_version_is "2.6" do
+ describe "Array#union" do
+ it_behaves_like :array_binary_union, :union
- it "tries to convert the passed argument to an Array using #to_ary" do
- obj = mock('[1,2,3]')
- obj.should_receive(:to_ary).and_return([1, 2, 3])
- ([0] | obj).should == ([0] | [1, 2, 3])
- end
-
- # MRI follows hashing semantics here, so doesn't actually call eql?/hash for Fixnum/Symbol
- it "acts as if using an intermediate hash to collect values" do
- not_supported_on :opal do
- ([5.0, 4.0] | [5, 4]).should == [5.0, 4.0, 5, 4]
+ it "returns unique elements when given no argument" do
+ x = [1, 2, 3, 2]
+ x.union.should == [1, 2, 3]
end
- str = "x"
- ([str] | [str.dup]).should == [str]
-
- obj1 = mock('1')
- obj2 = mock('2')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj2.should_receive(:eql?).at_least(1).and_return(true)
-
- ([obj1] | [obj2]).should == [obj1]
- ([obj1, obj1, obj2, obj2] | [obj2]).should == [obj1]
-
- obj1 = mock('3')
- obj2 = mock('4')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj2.should_receive(:eql?).at_least(1).and_return(false)
-
- ([obj1] | [obj2]).should == [obj1, obj2]
- ([obj1, obj1, obj2, obj2] | [obj2]).should == [obj1, obj2]
- end
-
- it "does not return subclass instances for Array subclasses" do
- (ArraySpecs::MyArray[1, 2, 3] | []).should be_an_instance_of(Array)
- (ArraySpecs::MyArray[1, 2, 3] | ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
- ([] | ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array)
- end
-
- it "does not call to_ary on array subclasses" do
- ([1, 2] | ArraySpecs::ToAryArray[5, 6]).should == [1, 2, 5, 6]
- end
-
- it "properly handles an identical item even when its #eql? isn't reflexive" do
- x = mock('x')
- x.stub!(:hash).and_return(42)
- x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
+ it "does not return subclass instances for Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].union.should be_an_instance_of(Array)
+ end
- ([x] | [x]).should == [x]
+ it "accepts multiple arguments" do
+ x = [1, 2, 3]
+ x.union(x, x, x, x, [3, 4], x).should == [1, 2, 3, 4]
+ end
end
end
diff --git a/spec/ruby/core/array/uniq_spec.rb b/spec/ruby/core/array/uniq_spec.rb
index 199b084376..5911c23e6a 100644
--- a/spec/ruby/core/array/uniq_spec.rb
+++ b/spec/ruby/core/array/uniq_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#uniq" do
it "returns an array with no duplicates" do
@@ -39,44 +39,76 @@ describe "Array#uniq" do
[x, y].uniq.should == [x, y]
end
- it "compares elements with matching hash codes with #eql?" do
- a = Array.new(2) do
- obj = mock('0')
- obj.should_receive(:hash).at_least(1).and_return(0)
+ ruby_version_is '2.7' do
+ it "compares elements with matching hash codes with #eql?" do
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
- def obj.eql?(o)
- # It's undefined whether the impl does a[0].eql?(a[1]) or
- # a[1].eql?(a[0]) so we taint both.
- taint
- o.taint
- false
+ def obj.eql?(o)
+ false
+ end
+
+ obj
end
- obj
- end
+ a.uniq.should == a
- a.uniq.should == a
- a[0].tainted?.should == true
- a[1].tainted?.should == true
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
- a = Array.new(2) do
- obj = mock('0')
- obj.should_receive(:hash).at_least(1).and_return(0)
+ def obj.eql?(o)
+ true
+ end
- def obj.eql?(o)
- # It's undefined whether the impl does a[0].eql?(a[1]) or
- # a[1].eql?(a[0]) so we taint both.
- taint
- o.taint
- true
+ obj
end
- obj
+ a.uniq.size.should == 1
end
+ end
+
+ ruby_version_is ''...'2.7' do
+ it "compares elements with matching hash codes with #eql?" do
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
+
+ def obj.eql?(o)
+ # It's undefined whether the impl does a[0].eql?(a[1]) or
+ # a[1].eql?(a[0]) so we taint both.
+ taint
+ o.taint
+ false
+ end
+
+ obj
+ end
+
+ a.uniq.should == a
+ a[0].should.tainted?
+ a[1].should.tainted?
- a.uniq.size.should == 1
- a[0].tainted?.should == true
- a[1].tainted?.should == true
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
+
+ def obj.eql?(o)
+ # It's undefined whether the impl does a[0].eql?(a[1]) or
+ # a[1].eql?(a[0]) so we taint both.
+ taint
+ o.taint
+ true
+ end
+
+ obj
+ end
+
+ a.uniq.size.should == 1
+ a[0].should.tainted?
+ a[1].should.tainted?
+ end
end
it "compares elements based on the value returned from the block" do
@@ -96,8 +128,16 @@ describe "Array#uniq" do
[false, nil, 42].uniq { :bar }.should == [false]
end
- it "returns subclass instance on Array subclasses" do
- ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(ArraySpecs::MyArray)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instance on Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns Array instance on Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(Array)
+ end
end
it "properly handles an identical item even when its #eql? isn't reflexive" do
@@ -188,20 +228,20 @@ describe "Array#uniq!" do
[ "a", "b", "c" ].uniq!.should == nil
end
- it "raises a RuntimeError on a frozen array when the array is modified" do
+ it "raises a FrozenError on a frozen array when the array is modified" do
dup_ary = [1, 1, 2]
dup_ary.freeze
- lambda { dup_ary.uniq! }.should raise_error(RuntimeError)
+ -> { dup_ary.uniq! }.should raise_error(FrozenError)
end
# see [ruby-core:23666]
- it "raises a RuntimeError on a frozen array when the array would not be modified" do
- lambda { ArraySpecs.frozen_array.uniq!}.should raise_error(RuntimeError)
- lambda { ArraySpecs.empty_frozen_array.uniq!}.should raise_error(RuntimeError)
+ it "raises a FrozenError on a frozen array when the array would not be modified" do
+ -> { ArraySpecs.frozen_array.uniq!}.should raise_error(FrozenError)
+ -> { ArraySpecs.empty_frozen_array.uniq!}.should raise_error(FrozenError)
end
it "doesn't yield to the block on a frozen array" do
- lambda { ArraySpecs.frozen_array.uniq!{ raise RangeError, "shouldn't yield"}}.should raise_error(RuntimeError)
+ -> { ArraySpecs.frozen_array.uniq!{ raise RangeError, "shouldn't yield"}}.should raise_error(FrozenError)
end
it "compares elements based on the value returned from the block" do
diff --git a/spec/ruby/core/array/unshift_spec.rb b/spec/ruby/core/array/unshift_spec.rb
index 9467a1a6df..b8b675e5f8 100644
--- a/spec/ruby/core/array/unshift_spec.rb
+++ b/spec/ruby/core/array/unshift_spec.rb
@@ -1,50 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/unshift'
describe "Array#unshift" do
- it "prepends object to the original array" do
- a = [1, 2, 3]
- a.unshift("a").should equal(a)
- a.should == ['a', 1, 2, 3]
- a.unshift().should equal(a)
- a.should == ['a', 1, 2, 3]
- a.unshift(5, 4, 3)
- a.should == [5, 4, 3, 'a', 1, 2, 3]
-
- # shift all but one element
- a = [1, 2]
- a.shift
- a.unshift(3, 4)
- a.should == [3, 4, 2]
-
- # now shift all elements
- a.shift
- a.shift
- a.shift
- a.unshift(3, 4)
- a.should == [3, 4]
- end
-
- it "quietly ignores unshifting nothing" do
- [].unshift().should == []
- [].unshift(*[]).should == []
- end
-
- it "properly handles recursive arrays" do
- empty = ArraySpecs.empty_recursive_array
- empty.unshift(:new).should == [:new, empty]
-
- array = ArraySpecs.recursive_array
- array.unshift(:new)
- array[0..5].should == [:new, 1, 'two', 3.0, array, array]
- end
-
- it "raises a RuntimeError on a frozen array when the array is modified" do
- lambda { ArraySpecs.frozen_array.unshift(1) }.should raise_error(RuntimeError)
- end
-
- # see [ruby-core:23666]
- it "raises a RuntimeError on a frozen array when the array would not be modified" do
- lambda { ArraySpecs.frozen_array.unshift }.should raise_error(RuntimeError)
- end
+ it_behaves_like :array_unshift, :unshift
end
diff --git a/spec/ruby/core/array/values_at_spec.rb b/spec/ruby/core/array/values_at_spec.rb
index f36356f0d3..f6801335f8 100644
--- a/spec/ruby/core/array/values_at_spec.rb
+++ b/spec/ruby/core/array/values_at_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#values_at" do
it "returns an array of elements at the indexes when passed indexes" do
@@ -60,4 +60,11 @@ describe "Array#values_at" do
it "does not return subclass instance on Array subclasses" do
ArraySpecs::MyArray[1, 2, 3].values_at(0, 1..2, 1).should be_an_instance_of(Array)
end
+
+ ruby_version_is "2.6" do
+ it "works when given endless ranges" do
+ [1, 2, 3, 4].values_at(eval("(1..)")).should == [2, 3, 4]
+ [1, 2, 3, 4].values_at(eval("(3...)")).should == [4]
+ end
+ end
end
diff --git a/spec/ruby/core/array/zip_spec.rb b/spec/ruby/core/array/zip_spec.rb
index 7aac13536b..af4013debe 100644
--- a/spec/ruby/core/array/zip_spec.rb
+++ b/spec/ruby/core/array/zip_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#zip" do
it "returns an array of arrays containing corresponding elements of each array" do
@@ -42,7 +42,7 @@ describe "Array#zip" do
[1, 2].zip(10.upto(Float::INFINITY)).should == [[1, 10], [2, 11]]
end
- it "fills nil when the given enumereator is shorter than self" do
+ it "fills nil when the given enumerator is shorter than self" do
obj = Object.new
def obj.each
yield 10
diff --git a/spec/ruby/core/basicobject/__id__spec.rb b/spec/ruby/core/basicobject/__id__spec.rb
index fba9ed3b34..6766db4e82 100644
--- a/spec/ruby/core/basicobject/__id__spec.rb
+++ b/spec/ruby/core/basicobject/__id__spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/kernel/object_id', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/kernel/object_id'
describe "BasicObject#__id__" do
it_behaves_like :object_id, :__id__, BasicObject
diff --git a/spec/ruby/core/basicobject/__send___spec.rb b/spec/ruby/core/basicobject/__send___spec.rb
index f25339fac7..005b1d0d90 100644
--- a/spec/ruby/core/basicobject/__send___spec.rb
+++ b/spec/ruby/core/basicobject/__send___spec.rb
@@ -1,10 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/basicobject/send', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/basicobject/send'
describe "BasicObject#__send__" do
it "is a public instance method" do
BasicObject.should have_public_instance_method(:__send__)
end
- it_behaves_like(:basicobject_send, :__send__)
+ it_behaves_like :basicobject_send, :__send__
end
diff --git a/spec/ruby/core/basicobject/basicobject_spec.rb b/spec/ruby/core/basicobject/basicobject_spec.rb
index f58c17a0c0..27a322e72c 100644
--- a/spec/ruby/core/basicobject/basicobject_spec.rb
+++ b/spec/ruby/core/basicobject/basicobject_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "BasicObject" do
it "raises NoMethodError for nonexistent methods after #method_missing is removed" do
@@ -8,7 +8,7 @@ describe "BasicObject" do
end
it "raises NameError when referencing built-in constants" do
- lambda { class BasicObjectSpecs::BOSubclass; Kernel; end }.should raise_error(NameError)
+ -> { class BasicObjectSpecs::BOSubclass; Kernel; end }.should raise_error(NameError)
end
it "does not define built-in constants (according to const_defined?)" do
@@ -19,8 +19,12 @@ describe "BasicObject" do
BasicObjectSpecs::BOSubclass.kernel_defined?.should be_nil
end
+ it "is included in Object's list of constants" do
+ Object.constants(false).should include(:BasicObject)
+ end
+
it "includes itself in its list of constants" do
- BasicObject.constants.should include(:BasicObject)
+ BasicObject.constants(false).should include(:BasicObject)
end
end
@@ -81,7 +85,7 @@ describe "BasicObject subclass" do
describe "BasicObject references" do
it "can refer to BasicObject from within itself" do
- lambda { BasicObject::BasicObject }.should_not raise_error
+ -> { BasicObject::BasicObject }.should_not raise_error
end
end
end
diff --git a/spec/ruby/core/basicobject/equal_spec.rb b/spec/ruby/core/basicobject/equal_spec.rb
index 8120df836f..3c1ad56d4a 100644
--- a/spec/ruby/core/basicobject/equal_spec.rb
+++ b/spec/ruby/core/basicobject/equal_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/kernel/equal', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/kernel/equal'
describe "BasicObject#equal?" do
it "is a public instance method" do
diff --git a/spec/ruby/core/basicobject/equal_value_spec.rb b/spec/ruby/core/basicobject/equal_value_spec.rb
index 7d67634884..6c825513c1 100644
--- a/spec/ruby/core/basicobject/equal_value_spec.rb
+++ b/spec/ruby/core/basicobject/equal_value_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/kernel/equal', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/kernel/equal'
describe "BasicObject#==" do
it "is a public instance method" do
diff --git a/spec/ruby/core/basicobject/initialize_spec.rb b/spec/ruby/core/basicobject/initialize_spec.rb
index 7e6680df61..b7ce73ffd5 100644
--- a/spec/ruby/core/basicobject/initialize_spec.rb
+++ b/spec/ruby/core/basicobject/initialize_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "BasicObject#initialize" do
it "is a private instance method" do
@@ -6,7 +6,7 @@ describe "BasicObject#initialize" do
end
it "does not accept arguments" do
- lambda {
+ -> {
BasicObject.new("This", "makes it easier", "to call super", "from other constructors")
}.should raise_error(ArgumentError)
end
diff --git a/spec/ruby/core/basicobject/instance_eval_spec.rb b/spec/ruby/core/basicobject/instance_eval_spec.rb
index 3898e96b8b..b6a146095d 100644
--- a/spec/ruby/core/basicobject/instance_eval_spec.rb
+++ b/spec/ruby/core/basicobject/instance_eval_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "BasicObject#instance_eval" do
before :each do
@@ -21,11 +21,11 @@ describe "BasicObject#instance_eval" do
end
it "expects a block with no arguments" do
- lambda { "hola".instance_eval }.should raise_error(ArgumentError)
+ -> { "hola".instance_eval }.should raise_error(ArgumentError)
end
it "takes no arguments with a block" do
- lambda { "hola".instance_eval(4, 5) {|a,b| a + b } }.should raise_error(ArgumentError)
+ -> { "hola".instance_eval(4, 5) {|a,b| a + b } }.should raise_error(ArgumentError)
end
it "yields the object to the block" do
@@ -45,7 +45,7 @@ describe "BasicObject#instance_eval" do
end
end
f.foo.should == 1
- lambda { Object.new.foo }.should raise_error(NoMethodError)
+ -> { Object.new.foo }.should raise_error(NoMethodError)
end
it "preserves self in the original block when passed a block argument" do
@@ -122,31 +122,31 @@ describe "BasicObject#instance_eval" do
end
it "raises a TypeError when defining methods on an immediate" do
- lambda do
+ -> do
1.instance_eval { def foo; end }
end.should raise_error(TypeError)
- lambda do
+ -> do
:foo.instance_eval { def foo; end }
end.should raise_error(TypeError)
end
quarantine! do # Not clean, leaves cvars lying around to break other specs
- it "scopes class var accesses in the caller when called on a Fixnum" do
- # Fixnum can take instance vars
- Fixnum.class_eval "@@__tmp_instance_eval_spec = 1"
+ it "scopes class var accesses in the caller when called on an Integer" do
+ # Integer can take instance vars
+ Integer.class_eval "@@__tmp_instance_eval_spec = 1"
(defined? @@__tmp_instance_eval_spec).should be_nil
@@__tmp_instance_eval_spec = 2
1.instance_eval { @@__tmp_instance_eval_spec }.should == 2
- Fixnum.__send__(:remove_class_variable, :@@__tmp_instance_eval_spec)
+ Integer.__send__(:remove_class_variable, :@@__tmp_instance_eval_spec)
end
end
it "raises a TypeError when defining methods on numerics" do
- lambda do
+ -> do
(1.0).instance_eval { def foo; end }
end.should raise_error(TypeError)
- lambda do
+ -> do
(1 << 64).instance_eval { def foo; end }
end.should raise_error(TypeError)
end
@@ -177,4 +177,12 @@ end
end
err.backtrace.first.split(":")[0..1].should == ["b_file", "-98"]
end
+
+ it "has access to the caller's local variables" do
+ x = nil
+
+ instance_eval "x = :value"
+
+ x.should == :value
+ end
end
diff --git a/spec/ruby/core/basicobject/instance_exec_spec.rb b/spec/ruby/core/basicobject/instance_exec_spec.rb
index f41af6f64f..289fdd889b 100644
--- a/spec/ruby/core/basicobject/instance_exec_spec.rb
+++ b/spec/ruby/core/basicobject/instance_exec_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "BasicObject#instance_exec" do
it "is a public instance method" do
@@ -17,7 +17,7 @@ describe "BasicObject#instance_exec" do
end
it "raises a LocalJumpError unless given a block" do
- lambda { "hola".instance_exec }.should raise_error(LocalJumpError)
+ -> { "hola".instance_exec }.should raise_error(LocalJumpError)
end
it "has an arity of -1" do
@@ -25,7 +25,7 @@ describe "BasicObject#instance_exec" do
end
it "accepts arguments with a block" do
- lambda { "hola".instance_exec(4, 5) { |a,b| a + b } }.should_not raise_error
+ -> { "hola".instance_exec(4, 5) { |a,b| a + b } }.should_not raise_error
end
it "doesn't pass self to the block as an argument" do
@@ -44,7 +44,7 @@ describe "BasicObject#instance_exec" do
end
end
f.foo.should == 1
- lambda { Object.new.foo }.should raise_error(NoMethodError)
+ -> { Object.new.foo }.should raise_error(NoMethodError)
end
# TODO: This should probably be replaced with a "should behave like" that uses
@@ -76,31 +76,31 @@ describe "BasicObject#instance_exec" do
end
it "raises a TypeError when defining methods on an immediate" do
- lambda do
+ -> do
1.instance_exec { def foo; end }
end.should raise_error(TypeError)
- lambda do
+ -> do
:foo.instance_exec { def foo; end }
end.should raise_error(TypeError)
end
quarantine! do # Not clean, leaves cvars lying around to break other specs
- it "scopes class var accesses in the caller when called on a Fixnum" do
- # Fixnum can take instance vars
- Fixnum.class_eval "@@__tmp_instance_exec_spec = 1"
+ it "scopes class var accesses in the caller when called on an Integer" do
+ # Integer can take instance vars
+ Integer.class_eval "@@__tmp_instance_exec_spec = 1"
(defined? @@__tmp_instance_exec_spec).should == nil
@@__tmp_instance_exec_spec = 2
1.instance_exec { @@__tmp_instance_exec_spec }.should == 2
- Fixnum.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec)
+ Integer.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec)
end
end
it "raises a TypeError when defining methods on numerics" do
- lambda do
+ -> do
(1.0).instance_exec { def foo; end }
end.should raise_error(TypeError)
- lambda do
+ -> do
(1 << 64).instance_exec { def foo; end }
end.should raise_error(TypeError)
end
diff --git a/spec/ruby/core/basicobject/method_missing_spec.rb b/spec/ruby/core/basicobject/method_missing_spec.rb
index eea45a8ddc..b048780ee8 100644
--- a/spec/ruby/core/basicobject/method_missing_spec.rb
+++ b/spec/ruby/core/basicobject/method_missing_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../shared/basicobject/method_missing', __FILE__)
+require_relative '../../shared/basicobject/method_missing'
describe "BasicObject#method_missing" do
it "is a private method" do
diff --git a/spec/ruby/core/basicobject/not_equal_spec.rb b/spec/ruby/core/basicobject/not_equal_spec.rb
index 9177380154..9329128c43 100644
--- a/spec/ruby/core/basicobject/not_equal_spec.rb
+++ b/spec/ruby/core/basicobject/not_equal_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "BasicObject#!=" do
it "is a public instance method" do
diff --git a/spec/ruby/core/basicobject/not_spec.rb b/spec/ruby/core/basicobject/not_spec.rb
index f02b31edb2..ca4cb6f5ff 100644
--- a/spec/ruby/core/basicobject/not_spec.rb
+++ b/spec/ruby/core/basicobject/not_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "BasicObject#!" do
it "is a public instance method" do
diff --git a/spec/ruby/core/basicobject/singleton_method_added_spec.rb b/spec/ruby/core/basicobject/singleton_method_added_spec.rb
index 7622798dee..8d256e22db 100644
--- a/spec/ruby/core/basicobject/singleton_method_added_spec.rb
+++ b/spec/ruby/core/basicobject/singleton_method_added_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/singleton_method', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/singleton_method'
describe "BasicObject#singleton_method_added" do
before :each do
diff --git a/spec/ruby/core/basicobject/singleton_method_removed_spec.rb b/spec/ruby/core/basicobject/singleton_method_removed_spec.rb
index 406f4a888e..46f9a6894c 100644
--- a/spec/ruby/core/basicobject/singleton_method_removed_spec.rb
+++ b/spec/ruby/core/basicobject/singleton_method_removed_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "BasicObject#singleton_method_removed" do
before :each do
diff --git a/spec/ruby/core/basicobject/singleton_method_undefined_spec.rb b/spec/ruby/core/basicobject/singleton_method_undefined_spec.rb
index 4f33cc5dbe..7d6c7207db 100644
--- a/spec/ruby/core/basicobject/singleton_method_undefined_spec.rb
+++ b/spec/ruby/core/basicobject/singleton_method_undefined_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "BasicObject#singleton_method_undefined" do
before :each do
diff --git a/spec/ruby/core/bignum/abs_spec.rb b/spec/ruby/core/bignum/abs_spec.rb
deleted file mode 100644
index b551dd95ad..0000000000
--- a/spec/ruby/core/bignum/abs_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/abs', __FILE__)
-
-describe "Bignum#abs" do
- it_behaves_like(:bignum_abs, :abs)
-end
-
diff --git a/spec/ruby/core/bignum/bignum_spec.rb b/spec/ruby/core/bignum/bignum_spec.rb
deleted file mode 100644
index cf99bb4937..0000000000
--- a/spec/ruby/core/bignum/bignum_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum" do
- it "includes Comparable" do
- Bignum.include?(Comparable).should == true
- end
-
- it ".allocate raises a TypeError" do
- lambda do
- Bignum.allocate
- end.should raise_error(TypeError)
- end
-
- it ".new is undefined" do
- lambda do
- Bignum.new
- end.should raise_error(NoMethodError)
- end
-end
diff --git a/spec/ruby/core/bignum/bit_and_spec.rb b/spec/ruby/core/bignum/bit_and_spec.rb
deleted file mode 100644
index 4bc5c11e1b..0000000000
--- a/spec/ruby/core/bignum/bit_and_spec.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#&" do
- before :each do
- @bignum = bignum_value(5)
- end
-
- it "returns self bitwise AND other" do
- @bignum = bignum_value(5)
- (@bignum & 3).should == 1
- (@bignum & 52).should == 4
- (@bignum & bignum_value(9921)).should == 9223372036854775809
-
- ((2*bignum_value) & 1).should == 0
- ((2*bignum_value) & (2*bignum_value)).should == 18446744073709551616
- end
-
- it "returns self bitwise AND other when one operand is negative" do
- ((2*bignum_value) & -1).should == (2*bignum_value)
- ((4*bignum_value) & -1).should == (4*bignum_value)
- (@bignum & -0xffffffffffffff5).should == 9223372036854775809
- (@bignum & -@bignum).should == 1
- (@bignum & -0x8000000000000000).should == 9223372036854775808
- end
-
- it "returns self bitwise AND other when both operands are negative" do
- (-@bignum & -0x4000000000000005).should == -13835058055282163717
- (-@bignum & -@bignum).should == -9223372036854775813
- (-@bignum & -0x4000000000000000).should == -13835058055282163712
- end
-
- it "returns self bitwise AND other when both are negative and a multiple in bitsize of Fixnum::MIN" do
- val = - ((1 << 93) - 1)
- (val & val).should == val
-
- val = - ((1 << 126) - 1)
- (val & val).should == val
- end
-
- it "raises a TypeError when passed a Float" do
- lambda { (@bignum & 3.4) }.should raise_error(TypeError)
- end
-
- it "raises a TypeError and does not call #to_int when defined on an object" do
- obj = mock("bignum bit and")
- obj.should_not_receive(:to_int)
-
- lambda { @bignum & obj }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/bit_length_spec.rb b/spec/ruby/core/bignum/bit_length_spec.rb
deleted file mode 100644
index 1c4c518345..0000000000
--- a/spec/ruby/core/bignum/bit_length_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#bit_length" do
- it "returns the position of the leftmost bit of a positive number" do
- (2**1000-1).bit_length.should == 1000
- (2**1000).bit_length.should == 1001
- (2**1000+1).bit_length.should == 1001
-
- (2**10000-1).bit_length.should == 10000
- (2**10000).bit_length.should == 10001
- (2**10000+1).bit_length.should == 10001
-
- (1 << 100).bit_length.should == 101
- (1 << 100).succ.bit_length.should == 101
- (1 << 100).pred.bit_length.should == 100
- (1 << 10000).bit_length.should == 10001
- end
-
- it "returns the position of the leftmost 0 bit of a negative number" do
- (-2**10000-1).bit_length.should == 10001
- (-2**10000).bit_length.should == 10000
- (-2**10000+1).bit_length.should == 10000
-
- (-2**1000-1).bit_length.should == 1001
- (-2**1000).bit_length.should == 1000
- (-2**1000+1).bit_length.should == 1000
-
- ((-1 << 100)-1).bit_length.should == 101
- ((-1 << 100)-1).succ.bit_length.should == 100
- ((-1 << 100)-1).pred.bit_length.should == 101
- ((-1 << 10000)-1).bit_length.should == 10001
- end
-end
diff --git a/spec/ruby/core/bignum/bit_or_spec.rb b/spec/ruby/core/bignum/bit_or_spec.rb
deleted file mode 100644
index 6bcb6ead6b..0000000000
--- a/spec/ruby/core/bignum/bit_or_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#|" do
- before :each do
- @bignum = bignum_value(11)
- end
-
- it "returns self bitwise OR other" do
- (@bignum | 2).should == 9223372036854775819
- (@bignum | 9).should == 9223372036854775819
- (@bignum | bignum_value).should == 9223372036854775819
- end
-
- it "returns self bitwise OR other when one operand is negative" do
- (@bignum | -0x40000000000000000).should == -64563604257983430645
- (@bignum | -@bignum).should == -1
- (@bignum | -0x8000000000000000).should == -9223372036854775797
- end
-
- it "returns self bitwise OR other when both operands are negative" do
- (-@bignum | -0x4000000000000005).should == -1
- (-@bignum | -@bignum).should == -9223372036854775819
- (-@bignum | -0x4000000000000000).should == -11
- end
-
- it "raises a TypeError when passed a Float" do
- not_supported_on :opal do
- lambda {
- bignum_value | bignum_value(0xffff).to_f
- }.should raise_error(TypeError)
- end
- lambda { @bignum | 9.9 }.should raise_error(TypeError)
- end
-
- it "raises a TypeError and does not call #to_int when defined on an object" do
- obj = mock("bignum bit or")
- obj.should_not_receive(:to_int)
-
- lambda { @bignum | obj }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/bit_xor_spec.rb b/spec/ruby/core/bignum/bit_xor_spec.rb
deleted file mode 100644
index ef4b4e6ae3..0000000000
--- a/spec/ruby/core/bignum/bit_xor_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#^" do
- before :each do
- @bignum = bignum_value(18)
- end
-
- it "returns self bitwise EXCLUSIVE OR other" do
- (@bignum ^ 2).should == 9223372036854775824
- (@bignum ^ @bignum).should == 0
- (@bignum ^ 14).should == 9223372036854775836
- end
-
- it "returns self bitwise EXCLUSIVE OR other when one operand is negative" do
- (@bignum ^ -0x40000000000000000).should == -64563604257983430638
- (@bignum ^ -@bignum).should == -4
- (@bignum ^ -0x8000000000000000).should == -18446744073709551598
- end
-
- it "returns self bitwise EXCLUSIVE OR other when both operands are negative" do
- (-@bignum ^ -0x40000000000000000).should == 64563604257983430638
- (-@bignum ^ -@bignum).should == 0
- (-@bignum ^ -0x4000000000000000).should == 13835058055282163694
- end
-
- it "returns self bitwise EXCLUSIVE OR other when all bits are 1 and other value is negative" do
- (9903520314283042199192993791 ^ -1).should == -9903520314283042199192993792
- (784637716923335095479473677900958302012794430558004314111 ^ -1).should ==
- -784637716923335095479473677900958302012794430558004314112
- end
-
- it "raises a TypeError when passed a Float" do
- not_supported_on :opal do
- lambda {
- bignum_value ^ bignum_value(0xffff).to_f
- }.should raise_error(TypeError)
- end
- lambda { @bignum ^ 14.5 }.should raise_error(TypeError)
- end
-
- it "raises a TypeError and does not call #to_int when defined on an object" do
- obj = mock("bignum bit xor")
- obj.should_not_receive(:to_int)
-
- lambda { @bignum ^ obj }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/case_compare_spec.rb b/spec/ruby/core/bignum/case_compare_spec.rb
deleted file mode 100644
index d7e0a89487..0000000000
--- a/spec/ruby/core/bignum/case_compare_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/equal', __FILE__)
-
-describe "Bignum#===" do
- it_behaves_like :bignum_equal, :===
-end
diff --git a/spec/ruby/core/bignum/coerce_spec.rb b/spec/ruby/core/bignum/coerce_spec.rb
deleted file mode 100644
index 40decaf51a..0000000000
--- a/spec/ruby/core/bignum/coerce_spec.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#coerce" do
- it "coerces other to a Bignum and returns [other, self] when passed a Fixnum" do
- a = bignum_value
- ary = a.coerce(2)
-
- ary[0].should be_kind_of(Bignum)
- ary[1].should be_kind_of(Bignum)
- ary.should == [2, a]
- end
-
- it "returns [other, self] when passed a Bignum" do
- a = bignum_value
- b = bignum_value
- ary = a.coerce(b)
-
- ary[0].should be_kind_of(Bignum)
- ary[1].should be_kind_of(Bignum)
- ary.should == [b, a]
- end
-
- it "raises a TypeError when not passed a Fixnum or Bignum" do
- a = bignum_value
-
- lambda { a.coerce(nil) }.should raise_error(TypeError)
- lambda { a.coerce(mock('str')) }.should raise_error(TypeError)
- lambda { a.coerce(1..4) }.should raise_error(TypeError)
- lambda { a.coerce(:test) }.should raise_error(TypeError)
- end
-
- ruby_version_is ""..."2.4" do
- it "raises a TypeError when passed a String" do
- a = bignum_value
- lambda { a.coerce("123") }.should raise_error(TypeError)
- end
-
- it "raises a TypeError when passed a Float" do
- a = bignum_value
- lambda { a.coerce(12.3) }.should raise_error(TypeError)
- end
- end
-
- ruby_version_is "2.4" do
- it "coerces both values to Floats and returns [other, self] when passed a Float" do
- a = bignum_value
- a.coerce(1.2).should == [1.2, a.to_f]
- end
-
- it "coerces both values to Floats and returns [other, self] when passed a String" do
- a = bignum_value
- a.coerce("123").should == [123.0, a.to_f]
- end
-
- it "calls #to_f to coerce other to a Float" do
- b = mock("bignum value")
- b.should_receive(:to_f).and_return(1.2)
-
- a = bignum_value
- ary = a.coerce(b)
-
- ary.should == [1.2, a.to_f]
- end
- end
-end
diff --git a/spec/ruby/core/bignum/comparison_spec.rb b/spec/ruby/core/bignum/comparison_spec.rb
deleted file mode 100644
index 435cc9aea2..0000000000
--- a/spec/ruby/core/bignum/comparison_spec.rb
+++ /dev/null
@@ -1,162 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#<=>" do
- describe "with a Fixnum" do
- it "returns -1 when other is larger" do
- (-bignum_value <=> 2).should == -1
- end
-
- it "returns 1 when other is smaller" do
- (bignum_value <=> 2).should == 1
- end
- end
-
- describe "with a Bignum" do
- describe "when other is negative" do
- it "returns -1 when self is negative and other is larger" do
- (-bignum_value(42) <=> -bignum_value).should == -1
- end
-
- it "returns 0 when other is equal" do
- (-bignum_value <=> -bignum_value).should == 0
- end
-
- it "returns 1 when self is negative and other is smaller" do
- (-bignum_value <=> -bignum_value(94)).should == 1
- end
-
- it "returns 1 when self is positive" do
- (bignum_value <=> -bignum_value).should == 1
- end
- end
-
- describe "when other is positive" do
- it "returns -1 when self is negative" do
- (-bignum_value <=> bignum_value).should == -1
- end
-
- it "returns -1 when self is positive and other is larger" do
- (bignum_value <=> bignum_value(38)).should == -1
- end
-
- it "returns 0 when other is equal" do
- (bignum_value <=> bignum_value).should == 0
- end
-
- it "returns 1 when other is smaller" do
- (bignum_value(56) <=> bignum_value).should == 1
- end
- end
- end
-
- describe "with a Float" do
- describe "when other is negative" do
- it "returns -1 when self is negative and other is larger" do
- (-bignum_value(0xffff) <=> -bignum_value.to_f).should == -1
- end
-
- it "returns 0 when other is equal" do
- (-bignum_value <=> -bignum_value.to_f).should == 0
- end
-
- it "returns 1 when self is negative and other is smaller" do
- (-bignum_value <=> -bignum_value(0xffef).to_f).should == 1
- end
-
- it "returns 1 when self is positive" do
- (bignum_value <=> -bignum_value.to_f).should == 1
- end
- end
-
- describe "when other is positive" do
- it "returns -1 when self is negative" do
- (-bignum_value <=> bignum_value.to_f).should == -1
- end
-
- it "returns -1 when self is positive and other is larger" do
- (bignum_value <=> bignum_value(0xfffe).to_f).should == -1
- end
-
- it "returns 0 when other is equal" do
- (bignum_value <=> bignum_value.to_f).should == 0
- end
-
- it "returns 1 when other is smaller" do
- (bignum_value(0xfeff) <=> bignum_value.to_f).should == 1
- end
- end
- end
-
- describe "with an Object" do
- before :each do
- @big = bignum_value
- @num = mock("value for Bignum#<=>")
- end
-
- it "calls #coerce on other" do
- @num.should_receive(:coerce).with(@big).and_return([@big.to_f, 2.5])
- @big <=> @num
- end
-
- ruby_version_is ""..."2.5" do
- it "returns nil if #coerce raises an exception" do
- @num.should_receive(:coerce).with(@big).and_raise(RuntimeError)
- lambda {
- @result = (@big <=> @num)
- }.should complain(/Numerical comparison operators will no more rescue exceptions/)
- @result.should be_nil
- end
- end
-
- ruby_version_is "2.5" do
- it "lets the exception go through if #coerce raises an exception" do
- @num.should_receive(:coerce).with(@big).and_raise(RuntimeError.new("my error"))
- lambda {
- @big <=> @num
- }.should raise_error(RuntimeError, "my error")
- end
- end
-
- it "raises an exception if #coerce raises a non-StandardError exception" do
- @num.should_receive(:coerce).with(@big).and_raise(Exception)
- lambda { @big <=> @num }.should raise_error(Exception)
- end
-
- it "returns nil if #coerce does not return an Array" do
- @num.should_receive(:coerce).with(@big).and_return(nil)
- (@big <=> @num).should be_nil
- end
-
- it "returns -1 if the coerced value is larger" do
- @num.should_receive(:coerce).with(@big).and_return([@big, bignum_value(10)])
- (@big <=> @num).should == -1
- end
-
- it "returns 0 if the coerced value is equal" do
- @num.should_receive(:coerce).with(@big).and_return([@big, bignum_value])
- (@big <=> @num).should == 0
- end
-
- it "returns 1 if the coerced value is smaller" do
- @num.should_receive(:coerce).with(@big).and_return([@big, 22])
- (@big <=> @num).should == 1
- end
- end
-
- # The tests below are taken from matz's revision 23730 for Ruby trunk
- it "returns 1 when self is Infinity and other is a Bignum" do
- (infinity_value <=> Float::MAX.to_i*2).should == 1
- end
-
- it "returns -1 when self is negative and other is Infinty" do
- (-Float::MAX.to_i*2 <=> infinity_value).should == -1
- end
-
- it "returns 1 when self is negative and other is -Infinity" do
- (-Float::MAX.to_i*2 <=> -infinity_value).should == 1
- end
-
- it "returns -1 when self is -Infinity and other is negative" do
- (-infinity_value <=> -Float::MAX.to_i*2).should == -1
- end
-end
diff --git a/spec/ruby/core/bignum/complement_spec.rb b/spec/ruby/core/bignum/complement_spec.rb
deleted file mode 100644
index be6bc21b19..0000000000
--- a/spec/ruby/core/bignum/complement_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#~" do
- it "returns self with each bit flipped" do
- (~bignum_value(48)).should == -9223372036854775857
- (~(-bignum_value(21))).should == 9223372036854775828
- (~bignum_value(1)).should == -9223372036854775810
- end
-end
diff --git a/spec/ruby/core/bignum/div_spec.rb b/spec/ruby/core/bignum/div_spec.rb
deleted file mode 100644
index 6c165289e8..0000000000
--- a/spec/ruby/core/bignum/div_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/divide', __FILE__)
-
-describe "Bignum#div" do
- it_behaves_like(:bignum_divide, :div)
-
- it "returns a result of integer division of self by a float argument" do
- bignum_value(88).div(4294967295.5).should eql(2147483648)
- not_supported_on :opal do
- bignum_value(88).div(4294967295.0).should eql(2147483648)
- bignum_value(88).div(bignum_value(88).to_f).should eql(1)
- bignum_value(88).div(-bignum_value(88).to_f).should eql(-1)
- end
- end
-
- # #5490
- it "raises ZeroDivisionError if the argument is Float zero" do
- lambda { bignum_value(88).div(0.0) }.should raise_error(ZeroDivisionError)
- lambda { bignum_value(88).div(-0.0) }.should raise_error(ZeroDivisionError)
- end
-end
diff --git a/spec/ruby/core/bignum/divide_spec.rb b/spec/ruby/core/bignum/divide_spec.rb
deleted file mode 100644
index b81938b707..0000000000
--- a/spec/ruby/core/bignum/divide_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/divide', __FILE__)
-
-describe "Bignum#/" do
- it_behaves_like(:bignum_divide, :/)
-
- it "returns self divided by float" do
- not_supported_on :opal do
- (bignum_value(88) / 4294967295.0).should be_close(2147483648.5, TOLERANCE)
- end
- (bignum_value(88) / 4294967295.5).should be_close(2147483648.25, TOLERANCE)
- end
-
- it "does NOT raise ZeroDivisionError if other is zero and is a Float" do
- (bignum_value / 0.0).to_s.should == 'Infinity'
- (bignum_value / -0.0).to_s.should == '-Infinity'
- end
-end
diff --git a/spec/ruby/core/bignum/divmod_spec.rb b/spec/ruby/core/bignum/divmod_spec.rb
deleted file mode 100644
index 656f23482b..0000000000
--- a/spec/ruby/core/bignum/divmod_spec.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#divmod" do
- before :each do
- @bignum = bignum_value(55)
- end
-
- # Based on MRI's test/test_integer.rb (test_divmod),
- # MRI maintains the following property:
- # if q, r = a.divmod(b) ==>
- # assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))
- # So, r is always between 0 and b.
- it "returns an Array containing quotient and modulus obtained from dividing self by the given argument" do
- @bignum.divmod(4).should == [2305843009213693965, 3]
- @bignum.divmod(13).should == [709490156681136604, 11]
-
- @bignum.divmod(4.5).should == [2049638230412172288, 3.5]
-
- not_supported_on :opal do
- @bignum.divmod(4.0).should == [2305843009213693952, 0.0]
- @bignum.divmod(13.0).should == [709490156681136640, 8.0]
-
- @bignum.divmod(2.0).should == [4611686018427387904, 0.0]
- end
-
- @bignum.divmod(bignum_value).should == [1, 55]
-
- (-(10**50)).divmod(-(10**40 + 1)).should == [9999999999, -9999999999999999999999999999990000000001]
- (10**50).divmod(10**40 + 1).should == [9999999999, 9999999999999999999999999999990000000001]
-
- (-10**50).divmod(10**40 + 1).should == [-10000000000, 10000000000]
- (10**50).divmod(-(10**40 + 1)).should == [-10000000000, -10000000000]
- end
-
- describe "with q = floor(x/y), a = q*b + r," do
- it "returns [q,r] when a < 0, b > 0 and |a| < b" do
- a = -@bignum + 1
- b = @bignum
- a.divmod(b).should == [-1, 1]
- end
-
- it "returns [q,r] when a > 0, b < 0 and a > |b|" do
- b = -@bignum + 1
- a = @bignum
- a.divmod(b).should == [-2, -@bignum + 2]
- end
-
- it "returns [q,r] when a > 0, b < 0 and a < |b|" do
- a = @bignum - 1
- b = -@bignum
- a.divmod(b).should == [-1, -1]
- end
-
- it "returns [q,r] when a < 0, b < 0 and |a| < |b|" do
- a = -@bignum + 1
- b = -@bignum
- a.divmod(b).should == [0, -@bignum + 1]
- end
- end
-
- it "raises a ZeroDivisionError when the given argument is 0" do
- lambda { @bignum.divmod(0) }.should raise_error(ZeroDivisionError)
- lambda { (-@bignum).divmod(0) }.should raise_error(ZeroDivisionError)
- end
-
- # Behaviour established as correct in r23953
- it "raises a FloatDomainError if other is NaN" do
- lambda { @bignum.divmod(nan_value) }.should raise_error(FloatDomainError)
- end
-
- it "raises a ZeroDivisionError when the given argument is 0 and a Float" do
- lambda { @bignum.divmod(0.0) }.should raise_error(ZeroDivisionError)
- lambda { (-@bignum).divmod(0.0) }.should raise_error(ZeroDivisionError)
- end
-
- it "raises a TypeError when the given argument is not an Integer" do
- lambda { @bignum.divmod(mock('10')) }.should raise_error(TypeError)
- lambda { @bignum.divmod("10") }.should raise_error(TypeError)
- lambda { @bignum.divmod(:symbol) }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/element_reference_spec.rb b/spec/ruby/core/bignum/element_reference_spec.rb
deleted file mode 100644
index e5ee9e15ac..0000000000
--- a/spec/ruby/core/bignum/element_reference_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#[]" do
- before :each do
- @bignum = bignum_value(4996)
- end
-
- it "returns the nth bit in the binary representation of self" do
- @bignum[2].should == 1
- @bignum[9.2].should == 1
- @bignum[21].should == 0
- @bignum[0xffffffff].should == 0
- @bignum[-0xffffffff].should == 0
- end
-
- it "tries to convert the given argument to an Integer using #to_int" do
- @bignum[1.3].should == @bignum[1]
-
- (obj = mock('2')).should_receive(:to_int).at_least(1).and_return(2)
- @bignum[obj].should == 1
- end
-
- it "raises a TypeError when the given argument can't be converted to Integer" do
- obj = mock('asdf')
- lambda { @bignum[obj] }.should raise_error(TypeError)
-
- obj.should_receive(:to_int).and_return("asdf")
- lambda { @bignum[obj] }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/eql_spec.rb b/spec/ruby/core/bignum/eql_spec.rb
deleted file mode 100644
index c9eff9ef08..0000000000
--- a/spec/ruby/core/bignum/eql_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#eql? when given a Bignum" do
- it "returns true if the given argument has the same value" do
- a = bignum_value(13)
- a.should eql(bignum_value(13))
- (-a).should eql(-bignum_value(13))
- end
-end
-
-describe "Bignum#eql? when given a non-Bignum" do
- it "returns false" do
- a = bignum_value(13)
- a.should_not eql(a.to_f)
-
- a.should_not eql(2)
- a.should_not eql(3.14)
- a.should_not eql(:symbol)
- a.should_not eql("String")
- a.should_not eql(mock('str'))
- end
-end
diff --git a/spec/ruby/core/bignum/equal_value_spec.rb b/spec/ruby/core/bignum/equal_value_spec.rb
deleted file mode 100644
index 0117d58683..0000000000
--- a/spec/ruby/core/bignum/equal_value_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/equal', __FILE__)
-
-describe "Bignum#==" do
- it_behaves_like :bignum_equal, :==
-end
diff --git a/spec/ruby/core/bignum/even_spec.rb b/spec/ruby/core/bignum/even_spec.rb
deleted file mode 100644
index a84ea80075..0000000000
--- a/spec/ruby/core/bignum/even_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#even?" do
- it "returns true if self is even and positive" do
- (10000**10).even?.should be_true
- end
-
- it "returns true if self is even and negative" do
- (-10000**10).even?.should be_true
- end
-
- it "returns false if self is odd and positive" do
- (9879**976).even?.should be_false
- end
-
- it "returns false if self is odd and negative" do
- (-9879**976).even?.should be_false
- end
-end
diff --git a/spec/ruby/core/bignum/exponent_spec.rb b/spec/ruby/core/bignum/exponent_spec.rb
deleted file mode 100644
index f69da833fd..0000000000
--- a/spec/ruby/core/bignum/exponent_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#**" do
- before :each do
- @bignum = bignum_value(47)
- end
-
- it "returns self raised to other power" do
- (@bignum ** 4).should == 7237005577332262361485077344629993318496048279512298547155833600056910050625
- (@bignum ** 1.2).should be_close(57262152889751597425762.57804, TOLERANCE)
- end
-
- it "raises a TypeError when given a non-Integer" do
- lambda { @bignum ** mock('10') }.should raise_error
- lambda { @bignum ** "10" }.should raise_error
- lambda { @bignum ** :symbol }.should raise_error
- end
-
- it "switch to a Float when the values is too big" do
- flt = (@bignum ** @bignum)
- flt.should be_kind_of(Float)
- flt.infinite?.should == 1
- end
-
- it "returns a complex number when negative and raised to a fractional power" do
- ((-@bignum) ** (1.0/3)) .should be_close(Complex(1048576,1816186.907597341), TOLERANCE)
- ((-@bignum) ** Rational(1,3)).should be_close(Complex(1048576,1816186.907597341), TOLERANCE)
- end
-end
diff --git a/spec/ruby/core/bignum/fdiv_spec.rb b/spec/ruby/core/bignum/fdiv_spec.rb
deleted file mode 100644
index 35f3ede010..0000000000
--- a/spec/ruby/core/bignum/fdiv_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#fdiv" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/bignum/gt_spec.rb b/spec/ruby/core/bignum/gt_spec.rb
deleted file mode 100644
index 5c814eedd1..0000000000
--- a/spec/ruby/core/bignum/gt_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#>" do
- before :each do
- @bignum = bignum_value(732)
- end
-
- it "returns true if self is greater than the given argument" do
- (@bignum > (@bignum - 1)).should == true
- (@bignum > 14.6).should == true
- (@bignum > 10).should == true
-
- (@bignum > (@bignum + 500)).should == false
- end
-
- it "raises an ArgumentError when given a non-Integer" do
- lambda { @bignum > "4" }.should raise_error(ArgumentError)
- lambda { @bignum > mock('str') }.should raise_error(ArgumentError)
- end
-end
diff --git a/spec/ruby/core/bignum/gte_spec.rb b/spec/ruby/core/bignum/gte_spec.rb
deleted file mode 100644
index e32ce19e0f..0000000000
--- a/spec/ruby/core/bignum/gte_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#>=" do
- before :each do
- @bignum = bignum_value(14)
- end
-
- it "returns true if self is greater than or equal to other" do
- (@bignum >= @bignum).should == true
- (@bignum >= (@bignum + 2)).should == false
- (@bignum >= 5664.2).should == true
- (@bignum >= 4).should == true
- end
-
- it "raises an ArgumentError when given a non-Integer" do
- lambda { @bignum >= "4" }.should raise_error(ArgumentError)
- lambda { @bignum >= mock('str') }.should raise_error(ArgumentError)
- end
-end
diff --git a/spec/ruby/core/bignum/hash_spec.rb b/spec/ruby/core/bignum/hash_spec.rb
deleted file mode 100644
index bdc85c3fdc..0000000000
--- a/spec/ruby/core/bignum/hash_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#hash" do
- it "is provided" do
- bignum_value.respond_to?(:hash).should == true
- end
-
- it "is stable" do
- bignum_value.hash.should == bignum_value.hash
- bignum_value.hash.should_not == bignum_value(1).hash
- end
-end
diff --git a/spec/ruby/core/bignum/left_shift_spec.rb b/spec/ruby/core/bignum/left_shift_spec.rb
deleted file mode 100644
index 364f51b708..0000000000
--- a/spec/ruby/core/bignum/left_shift_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#<< with n << m" do
- before :each do
- @bignum = bignum_value * 16
- end
-
- it "returns n shifted left m bits when n > 0, m > 0" do
- (@bignum << 4).should == 2361183241434822606848
- end
-
- it "returns n shifted left m bits when n < 0, m > 0" do
- (-@bignum << 9).should == -75557863725914323419136
- end
-
- it "returns n shifted right m bits when n > 0, m < 0" do
- (@bignum << -1).should == 73786976294838206464
- end
-
- it "returns n shifted right m bits when n < 0, m < 0" do
- (-@bignum << -2).should == -36893488147419103232
- end
-
- it "returns n when n > 0, m == 0" do
- (@bignum << 0).should == @bignum
- end
-
- it "returns n when n < 0, m == 0" do
- (-@bignum << 0).should == -@bignum
- end
-
- it "returns 0 when m < 0 and m == p where 2**p > n >= 2**(p-1)" do
- (@bignum << -68).should == 0
- end
-
- it "returns 0 when m < 0 and m is a Bignum" do
- (@bignum << -bignum_value).should == 0
- end
-
- it "returns a Fixnum == fixnum_max when (fixnum_max * 2) << -1 and n > 0" do
- result = (fixnum_max * 2) << -1
- result.should be_an_instance_of(Fixnum)
- result.should == fixnum_max
- end
-
- it "returns a Fixnum == fixnum_min when (fixnum_min * 2) << -1 and n < 0" do
- result = (fixnum_min * 2) << -1
- result.should be_an_instance_of(Fixnum)
- result.should == fixnum_min
- end
-
- it "calls #to_int to convert the argument to an Integer" do
- obj = mock("4")
- obj.should_receive(:to_int).and_return(4)
-
- (@bignum << obj).should == 2361183241434822606848
- end
-
- it "raises a TypeError when #to_int does not return an Integer" do
- obj = mock("a string")
- obj.should_receive(:to_int).and_return("asdf")
-
- lambda { @bignum << obj }.should raise_error(TypeError)
- end
-
- it "raises a TypeError when passed nil" do
- lambda { @bignum << nil }.should raise_error(TypeError)
- end
-
- it "raises a TypeError when passed a String" do
- lambda { @bignum << "4" }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/lt_spec.rb b/spec/ruby/core/bignum/lt_spec.rb
deleted file mode 100644
index 802c68a58b..0000000000
--- a/spec/ruby/core/bignum/lt_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#<" do
- before :each do
- @bignum = bignum_value(32)
- end
-
- it "returns true if self is less than the given argument" do
- (@bignum < @bignum + 1).should == true
- (-@bignum < -(@bignum - 1)).should == true
-
- (@bignum < 1).should == false
- (@bignum < 5).should == false
-
- (@bignum < 4.999).should == false
- end
-
- it "raises an ArgumentError when given a non-Integer" do
- lambda { @bignum < "4" }.should raise_error(ArgumentError)
- lambda { @bignum < mock('str') }.should raise_error(ArgumentError)
- end
-end
diff --git a/spec/ruby/core/bignum/lte_spec.rb b/spec/ruby/core/bignum/lte_spec.rb
deleted file mode 100644
index 9a1d22d3be..0000000000
--- a/spec/ruby/core/bignum/lte_spec.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#<=" do
- before :each do
- @bignum = bignum_value(39)
- end
-
- it "returns true if self is less than or equal to other" do
- (@bignum <= @bignum).should == true
- (-@bignum <= -(@bignum - 1)).should == true
-
- (@bignum <= 4.999).should == false
- end
-
- it "returns false if compares with near float" do
- (@bignum <= (@bignum + 0.0)).should == false
- (@bignum <= (@bignum + 0.5)).should == false
- end
-
- it "raises an ArgumentError when given a non-Integer" do
- lambda { @bignum <= "4" }.should raise_error(ArgumentError)
- lambda { @bignum <= mock('str') }.should raise_error(ArgumentError)
- end
-end
diff --git a/spec/ruby/core/bignum/magnitude_spec.rb b/spec/ruby/core/bignum/magnitude_spec.rb
deleted file mode 100644
index 35b9ba6f1e..0000000000
--- a/spec/ruby/core/bignum/magnitude_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/abs', __FILE__)
-
-describe "Bignum#magnitude" do
- it_behaves_like(:bignum_abs, :magnitude)
-end
diff --git a/spec/ruby/core/bignum/minus_spec.rb b/spec/ruby/core/bignum/minus_spec.rb
deleted file mode 100644
index 754ef7fa42..0000000000
--- a/spec/ruby/core/bignum/minus_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#-" do
- before :each do
- @bignum = bignum_value(314)
- end
-
- it "returns self minus the given Integer" do
- (@bignum - 9).should == 9223372036854776113
- (@bignum - 12.57).should be_close(9223372036854776109.43, TOLERANCE)
- (@bignum - bignum_value(42)).should == 272
- end
-
- it "raises a TypeError when given a non-Integer" do
- lambda { @bignum - mock('10') }.should raise_error(TypeError)
- lambda { @bignum - "10" }.should raise_error(TypeError)
- lambda { @bignum - :symbol }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/modulo_spec.rb b/spec/ruby/core/bignum/modulo_spec.rb
deleted file mode 100644
index eee1dc76a6..0000000000
--- a/spec/ruby/core/bignum/modulo_spec.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/modulo', __FILE__)
-
-describe "Bignum#%" do
- it_behaves_like(:bignum_modulo, :%)
-end
-
-describe "Bignum#modulo" do
- it_behaves_like(:bignum_modulo, :modulo)
-end
diff --git a/spec/ruby/core/bignum/multiply_spec.rb b/spec/ruby/core/bignum/multiply_spec.rb
deleted file mode 100644
index 486e36ecbc..0000000000
--- a/spec/ruby/core/bignum/multiply_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#*" do
- before :each do
- @bignum = bignum_value(772)
- end
-
- it "returns self multiplied by the given Integer" do
- (@bignum * (1/bignum_value(0xffff).to_f)).should be_close(1.0, TOLERANCE)
- (@bignum * (1/bignum_value(0xffff).to_f)).should be_close(1.0, TOLERANCE)
- (@bignum * 10).should == 92233720368547765800
- (@bignum * (@bignum - 40)).should == 85070591730234629737795195287525433200
- end
-
- it "raises a TypeError when given a non-Integer" do
- lambda { @bignum * mock('10') }.should raise_error(TypeError)
- lambda { @bignum * "10" }.should raise_error(TypeError)
- lambda { @bignum * :symbol }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/odd_spec.rb b/spec/ruby/core/bignum/odd_spec.rb
deleted file mode 100644
index 9d4c1191f6..0000000000
--- a/spec/ruby/core/bignum/odd_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#odd?" do
- it "returns true if self is odd and positive" do
- (987279**19).odd?.should be_true
- end
-
- it "returns true if self is odd and negative" do
- (-9873389**97).odd?.should be_true
- end
-
- it "returns false if self is even and positive" do
- (10000000**10).odd?.should be_false
- end
-
- it "returns false if self is even and negative" do
- (-1000000**100).odd?.should be_false
- end
-end
diff --git a/spec/ruby/core/bignum/plus_spec.rb b/spec/ruby/core/bignum/plus_spec.rb
deleted file mode 100644
index 411e226649..0000000000
--- a/spec/ruby/core/bignum/plus_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#+" do
- before :each do
- @bignum = bignum_value(76)
- end
-
- it "returns self plus the given Integer" do
- (@bignum + 4).should == 9223372036854775888
- (@bignum + 4.2).should be_close(9223372036854775888.2, TOLERANCE)
- (@bignum + bignum_value(3)).should == 18446744073709551695
- end
-
- it "raises a TypeError when given a non-Integer" do
- lambda { @bignum + mock('10') }.should raise_error(TypeError)
- lambda { @bignum + "10" }.should raise_error(TypeError)
- lambda { @bignum + :symbol}.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/remainder_spec.rb b/spec/ruby/core/bignum/remainder_spec.rb
deleted file mode 100644
index 59f7eb4326..0000000000
--- a/spec/ruby/core/bignum/remainder_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#remainder" do
- it "returns the remainder of dividing self by other" do
- a = bignum_value(79)
- a.remainder(2).should == 1
- a.remainder(97.345).should be_close(46.5674996147722, TOLERANCE)
- a.remainder(bignum_value).should == 79
- end
-
- it "raises a ZeroDivisionError if other is zero and not a Float" do
- lambda { bignum_value(66).remainder(0) }.should raise_error(ZeroDivisionError)
- end
-
- it "does raises ZeroDivisionError if other is zero and a Float" do
- a = bignum_value(7)
- b = bignum_value(32)
- lambda { a.remainder(0.0) }.should raise_error(ZeroDivisionError)
- lambda { b.remainder(-0.0) }.should raise_error(ZeroDivisionError)
- end
-end
diff --git a/spec/ruby/core/bignum/right_shift_spec.rb b/spec/ruby/core/bignum/right_shift_spec.rb
deleted file mode 100644
index d65f7c00a9..0000000000
--- a/spec/ruby/core/bignum/right_shift_spec.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#>> with n >> m" do
- before :each do
- @bignum = bignum_value * 16
- end
-
- it "returns n shifted right m bits when n > 0, m > 0" do
- (@bignum >> 1).should == 73786976294838206464
- end
-
- it "returns n shifted right m bits when n < 0, m > 0" do
- (-@bignum >> 2).should == -36893488147419103232
- end
-
- it "respects twos complement signed shifting" do
- # This explicit left hand value is important because it is the
- # exact bit pattern that matters, so it's important it's right
- # here to show the significance.
- #
-
- (-42949672980000000000000 >> 14).should == -2621440001220703125
- (-42949672980000000000001 >> 14).should == -2621440001220703126
- # Note the off by one -------------------- ^^^^^^^^^^^^^^^^^^^^
- # This is because even though we discard the lowest bit, in twos
- # complement it would influence the bits to the left of it.
-
- (-42949672980000000000000 >> 15).should == -1310720000610351563
- (-42949672980000000000001 >> 15).should == -1310720000610351563
-
- (-0xfffffffffffffffff >> 32).should == -68719476736
- end
-
- it "respects twos complement signed shifting for very large values" do
- giant = 42949672980000000000000000000000000000000000000000000000000000000000000000000000000000000000
- neg = -giant
-
- (giant >> 84).should == 2220446050284288846538547929770901490087453566957265138626098632812
- (neg >> 84).should == -2220446050284288846538547929770901490087453566957265138626098632813
- end
-
- it "returns n shifted left m bits when n > 0, m < 0" do
- (@bignum >> -2).should == 590295810358705651712
- end
-
- it "returns n shifted left m bits when n < 0, m < 0" do
- (-@bignum >> -3).should == -1180591620717411303424
- end
-
- it "returns n when n > 0, m == 0" do
- (@bignum >> 0).should == @bignum
- end
-
- it "returns n when n < 0, m == 0" do
- (-@bignum >> 0).should == -@bignum
- end
-
- it "returns 0 when m > 0 and m == p where 2**p > n >= 2**(p-1)" do
- (@bignum >> 68).should == 0
- end
-
- it "returns 0 when m is a Bignum" do
- (@bignum >> bignum_value).should == 0
- end
-
- it "returns a Fixnum == fixnum_max when (fixnum_max * 2) >> 1 and n > 0" do
- result = (fixnum_max * 2) >> 1
- result.should be_an_instance_of(Fixnum)
- result.should == fixnum_max
- end
-
- it "returns a Fixnum == fixnum_min when (fixnum_min * 2) >> 1 and n < 0" do
- result = (fixnum_min * 2) >> 1
- result.should be_an_instance_of(Fixnum)
- result.should == fixnum_min
- end
-
- it "calls #to_int to convert the argument to an Integer" do
- obj = mock("2")
- obj.should_receive(:to_int).and_return(2)
-
- (@bignum >> obj).should == 36893488147419103232
- end
-
- it "raises a TypeError when #to_int does not return an Integer" do
- obj = mock("a string")
- obj.should_receive(:to_int).and_return("asdf")
-
- lambda { @bignum >> obj }.should raise_error(TypeError)
- end
-
- it "raises a TypeError when passed nil" do
- lambda { @bignum >> nil }.should raise_error(TypeError)
- end
-
- it "raises a TypeError when passed a String" do
- lambda { @bignum >> "4" }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/shared/abs.rb b/spec/ruby/core/bignum/shared/abs.rb
deleted file mode 100644
index 35fd85060c..0000000000
--- a/spec/ruby/core/bignum/shared/abs.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-describe :bignum_abs, shared: true do
- it "returns the absolute value" do
- bignum_value(39).send(@method).should == 9223372036854775847
- (-bignum_value(18)).send(@method).should == 9223372036854775826
- end
-end
diff --git a/spec/ruby/core/bignum/shared/divide.rb b/spec/ruby/core/bignum/shared/divide.rb
deleted file mode 100644
index cbde69bbb2..0000000000
--- a/spec/ruby/core/bignum/shared/divide.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-describe :bignum_divide, shared: true do
- before :each do
- @bignum = bignum_value(88)
- end
-
- it "returns self divided by other" do
- @bignum.send(@method, 4).should == 2305843009213693974
-
- @bignum.send(@method, bignum_value(2)).should be_close(1, TOLERANCE)
-
- (-(10**50)).send(@method, -(10**40 + 1)).should == 9999999999
- (10**50).send(@method, 10**40 + 1).should == 9999999999
-
- (-10**50).send(@method, 10**40 + 1).should == -10000000000
- (10**50).send(@method, -(10**40 + 1)).should == -10000000000
- end
-
- it "raises a ZeroDivisionError if other is zero and not a Float" do
- lambda { @bignum.send(@method, 0) }.should raise_error(ZeroDivisionError)
- end
-
- it "raises a TypeError when given a non-Integer" do
- lambda { @bignum.send(@method, mock('10')) }.should raise_error(TypeError)
- lambda { @bignum.send(@method, "2") }.should raise_error(TypeError)
- lambda { @bignum.send(@method, :symbol) }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/shared/equal.rb b/spec/ruby/core/bignum/shared/equal.rb
deleted file mode 100644
index ffe4daf4f1..0000000000
--- a/spec/ruby/core/bignum/shared/equal.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-describe :bignum_equal, shared: true do
- before :each do
- @bignum = bignum_value
- end
-
- it "returns true if self has the same value as the given argument" do
- @bignum.send(@method, @bignum).should == true
- @bignum.send(@method, @bignum.to_f).should == true
-
- @bignum.send(@method, @bignum + 1).should == false
- (@bignum + 1).send(@method, @bignum).should == false
-
- @bignum.send(@method, 9).should == false
- @bignum.send(@method, 9.01).should == false
-
- @bignum.send(@method, bignum_value(10)).should == false
- end
-
- it "calls 'other == self' if the given argument is not an Integer" do
- obj = mock('not integer')
- obj.should_receive(:==).and_return(true)
- @bignum.send(@method, obj).should == true
- end
-
- it "returns the result of 'other == self' as a boolean" do
- obj = mock('not integer')
- obj.should_receive(:==).exactly(2).times.and_return("woot", nil)
- @bignum.send(@method, obj).should == true
- @bignum.send(@method, obj).should == false
- end
-end
diff --git a/spec/ruby/core/bignum/shared/modulo.rb b/spec/ruby/core/bignum/shared/modulo.rb
deleted file mode 100644
index 9814e22f3b..0000000000
--- a/spec/ruby/core/bignum/shared/modulo.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-describe :bignum_modulo, shared: true do
- before :each do
- @bignum = bignum_value
- end
-
- it "returns the modulus obtained from dividing self by the given argument" do
- @bignum.send(@method, 5).should == 3
- @bignum.send(@method, -5).should == -2
- @bignum.send(@method, -100).should == -92
- @bignum.send(@method, 2.22).should be_close(0.780180180180252, TOLERANCE)
- @bignum.send(@method, bignum_value(10)).should == 9223372036854775808
- end
-
- it "raises a ZeroDivisionError when the given argument is 0" do
- lambda { @bignum.send(@method, 0) }.should raise_error(ZeroDivisionError)
- lambda { (-@bignum).send(@method, 0) }.should raise_error(ZeroDivisionError)
- end
-
- it "raises a ZeroDivisionError when the given argument is 0 and a Float" do
- lambda { @bignum.send(@method, 0.0) }.should raise_error(ZeroDivisionError)
- lambda { -@bignum.send(@method, 0.0) }.should raise_error(ZeroDivisionError)
- end
-
- it "raises a TypeError when given a non-Integer" do
- lambda { @bignum.send(@method, mock('10')) }.should raise_error(TypeError)
- lambda { @bignum.send(@method, "10") }.should raise_error(TypeError)
- lambda { @bignum.send(@method, :symbol) }.should raise_error(TypeError)
- end
-end
diff --git a/spec/ruby/core/bignum/size_spec.rb b/spec/ruby/core/bignum/size_spec.rb
deleted file mode 100644
index 8629cba972..0000000000
--- a/spec/ruby/core/bignum/size_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#size" do
- it "returns the number of bytes required to hold the unsigned bignum data" do
- # that is, n such that 256 * n <= val.abs < 256 * (n+1)
- (256**7).size.should == 8
- (256**8).size.should == 9
- (256**9).size.should == 10
- (256**10).size.should == 11
- (256**10-1).size.should == 10
- (256**11).size.should == 12
- (256**12).size.should == 13
- (256**20-1).size.should == 20
- (256**40-1).size.should == 40
- end
-end
diff --git a/spec/ruby/core/bignum/to_f_spec.rb b/spec/ruby/core/bignum/to_f_spec.rb
deleted file mode 100644
index 8d99045c95..0000000000
--- a/spec/ruby/core/bignum/to_f_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#to_f" do
- it "returns self converted to a Float" do
- bignum_value(0x4000_0aa0_0bb0_0000).to_f.should eql(13_835_069_737_789_292_544.00)
- bignum_value(0x8000_0000_0000_0ccc).to_f.should eql(18_446_744_073_709_555_712.00)
- (-bignum_value(99)).to_f.should eql(-9_223_372_036_854_775_808.00)
- end
-
- it "converts number close to Float::MAX without exceeding MAX or producing NaN" do
- (10**308).to_f.should == 10.0 ** 308
- end
-end
diff --git a/spec/ruby/core/bignum/to_s_spec.rb b/spec/ruby/core/bignum/to_s_spec.rb
deleted file mode 100644
index 524639adb6..0000000000
--- a/spec/ruby/core/bignum/to_s_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#to_s when given a base" do
- it "returns self converted to a String using the given base" do
- a = 2**64
- a.to_s(2).should == "10000000000000000000000000000000000000000000000000000000000000000"
- a.to_s(8).should == "2000000000000000000000"
- a.to_s(16).should == "10000000000000000"
- a.to_s(32).should == "g000000000000"
- end
-
- it "raises an ArgumentError if the base is less than 2 or higher than 36" do
- lambda { 123.to_s(-1) }.should raise_error(ArgumentError)
- lambda { 123.to_s(0) }.should raise_error(ArgumentError)
- lambda { 123.to_s(1) }.should raise_error(ArgumentError)
- lambda { 123.to_s(37) }.should raise_error(ArgumentError)
- end
-end
-
-describe "Bignum#to_s when given no base" do
- it "returns self converted to a String using base 10" do
- bignum_value(9).to_s.should == "9223372036854775817"
- bignum_value.to_s.should == "9223372036854775808"
- (-bignum_value(675)).to_s.should == "-9223372036854776483"
- end
-end
-
-with_feature :encoding do
- describe "Bignum#to_s" do
- before :each do
- @internal = Encoding.default_internal
- end
-
- after :each do
- Encoding.default_internal = @internal
- end
-
- it "returns a String in US-ASCII encoding when Encoding.default_internal is nil" do
- Encoding.default_internal = nil
- bignum_value.to_s.encoding.should equal(Encoding::US_ASCII)
- end
-
- it "returns a String in US-ASCII encoding when Encoding.default_internal is not nil" do
- Encoding.default_internal = Encoding::IBM437
- bignum_value.to_s.encoding.should equal(Encoding::US_ASCII)
- end
- end
-end
diff --git a/spec/ruby/core/bignum/uminus_spec.rb b/spec/ruby/core/bignum/uminus_spec.rb
deleted file mode 100644
index 7ec432ac71..0000000000
--- a/spec/ruby/core/bignum/uminus_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Bignum#-@" do
- it "returns self as a negative value" do
- bignum_value.send(:-@).should == -9223372036854775808
- (-bignum_value).send(:-@).should == 9223372036854775808
-
- bignum_value(921).send(:-@).should == -9223372036854776729
- (-bignum_value(921).send(:-@)).should == 9223372036854776729
- end
-end
diff --git a/spec/ruby/core/binding/clone_spec.rb b/spec/ruby/core/binding/clone_spec.rb
index d607ae2a9e..ebd40f5377 100644
--- a/spec/ruby/core/binding/clone_spec.rb
+++ b/spec/ruby/core/binding/clone_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/clone', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/clone'
describe "Binding#clone" do
- it_behaves_like(:binding_clone, :clone)
+ it_behaves_like :binding_clone, :clone
end
diff --git a/spec/ruby/core/binding/dup_spec.rb b/spec/ruby/core/binding/dup_spec.rb
index 7f242626d7..43968213c8 100644
--- a/spec/ruby/core/binding/dup_spec.rb
+++ b/spec/ruby/core/binding/dup_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/clone', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/clone'
describe "Binding#dup" do
- it_behaves_like(:binding_clone, :dup)
+ it_behaves_like :binding_clone, :dup
end
diff --git a/spec/ruby/core/binding/eval_spec.rb b/spec/ruby/core/binding/eval_spec.rb
index 4864b9f61f..b36bec799e 100644
--- a/spec/ruby/core/binding/eval_spec.rb
+++ b/spec/ruby/core/binding/eval_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Binding#eval" do
it "behaves like Kernel.eval(..., self)" do
@@ -23,15 +23,118 @@ describe "Binding#eval" do
bind2.local_variables.should == []
end
+ ruby_version_is ""..."3.0" do
+ it "inherits __LINE__ from the enclosing scope" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+ end
+
+ it "preserves __LINE__ across multiple calls to eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+ suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+ end
+
+ it "increments __LINE__ on each line of a multiline eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning {bind.eval("#foo\n__LINE__")}.should == obj.get_line_of_binding + 1
+ end
+
+ it "inherits __LINE__ from the enclosing scope even if the Binding is created with #send" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, line = obj.get_binding_with_send_and_line
+ suppress_warning {bind.eval("__LINE__")}.should == line
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "starts with line 1 if single argument is given" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ bind.eval("__LINE__").should == 1
+ end
+
+ it "preserves __LINE__ across multiple calls to eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ bind.eval("__LINE__").should == 1
+ bind.eval("__LINE__").should == 1
+ end
+
+ it "increments __LINE__ on each line of a multiline eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ bind.eval("#foo\n__LINE__").should == 2
+ end
+
+ it "starts with line 1 if the Binding is created with #send" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, line = obj.get_binding_with_send_and_line
+ bind.eval("__LINE__").should == 1
+ end
+ end
+
+ it "starts with a __LINE__ of 1 if a filename is passed" do
+ bind = BindingSpecs::Demo.new(1).get_binding
+ bind.eval("__LINE__", "(test)").should == 1
+ bind.eval("#foo\n__LINE__", "(test)").should == 2
+ end
+
+ it "starts with a __LINE__ from the third argument if passed" do
+ bind = BindingSpecs::Demo.new(1).get_binding
+ bind.eval("__LINE__", "(test)", 88).should == 88
+ bind.eval("#foo\n__LINE__", "(test)", 88).should == 89
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "inherits __FILE__ from the enclosing scope" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning {bind.eval("__FILE__")}.should == obj.get_file_of_binding
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "Uses (eval) as __FILE__ if single argument given" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ bind.eval("__FILE__").should == '(eval)'
+ end
+ end
+
+ it "uses the __FILE__ that is passed in" do
+ bind = BindingSpecs::Demo.new(1).get_binding
+ bind.eval("__FILE__", "(test)").should == "(test)"
+ end
+
describe "with a file given" do
it "does not store the filename permanently" do
obj = BindingSpecs::Demo.new(1)
bind = obj.get_binding
bind.eval("__FILE__", "test.rb").should == "test.rb"
- bind.eval("__FILE__").should_not == "test.rb"
+ suppress_warning {bind.eval("__FILE__")}.should_not == "test.rb"
end
end
- it "needs to be reviewed for spec completeness"
+ it "with __method__ returns the method where the Binding was created" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, meth = obj.get_binding_and_method
+ bind.eval("__method__").should == meth
+ end
+
+ it "with __method__ returns the method where the Binding was created, ignoring #send" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, meth = obj.get_binding_with_send_and_method
+ bind.eval("__method__").should == meth
+ end
+
+ it "reflects refinements activated in the binding scope" do
+ bind = BindingSpecs::Refined.refined_binding
+
+ bind.eval("'bar'.foo").should == "foo"
+ end
end
diff --git a/spec/ruby/core/binding/fixtures/classes.rb b/spec/ruby/core/binding/fixtures/classes.rb
index 05ca2479ba..b5f3ce9008 100644
--- a/spec/ruby/core/binding/fixtures/classes.rb
+++ b/spec/ruby/core/binding/fixtures/classes.rb
@@ -25,6 +25,18 @@ module BindingSpecs
__FILE__
end
+ def get_binding_with_send_and_line
+ [send(:binding), __LINE__]
+ end
+
+ def get_binding_and_method
+ [binding, :get_binding_and_method]
+ end
+
+ def get_binding_with_send_and_method
+ [send(:binding), :get_binding_with_send_and_method]
+ end
+
def get_empty_binding
binding
end
@@ -37,4 +49,18 @@ module BindingSpecs
end
end
end
+
+ module AddFooToString
+ refine(String) do
+ def foo
+ "foo"
+ end
+ end
+ end
+ class Refined
+ using AddFooToString
+ def self.refined_binding
+ binding
+ end
+ end
end
diff --git a/spec/ruby/core/binding/fixtures/irb.rb b/spec/ruby/core/binding/fixtures/irb.rb
new file mode 100644
index 0000000000..5f305f2d5d
--- /dev/null
+++ b/spec/ruby/core/binding/fixtures/irb.rb
@@ -0,0 +1,3 @@
+a = 10
+
+binding.irb
diff --git a/spec/ruby/core/binding/fixtures/irbrc b/spec/ruby/core/binding/fixtures/irbrc
new file mode 100644
index 0000000000..2bc12af2f7
--- /dev/null
+++ b/spec/ruby/core/binding/fixtures/irbrc
@@ -0,0 +1 @@
+# empty configuration
diff --git a/spec/ruby/core/binding/fixtures/location.rb b/spec/ruby/core/binding/fixtures/location.rb
new file mode 100644
index 0000000000..a78ae75731
--- /dev/null
+++ b/spec/ruby/core/binding/fixtures/location.rb
@@ -0,0 +1,6 @@
+module BindingSpecs
+ module LocationMethod
+ FILE_PATH = __FILE__
+ TEST_BINDING = binding
+ end
+end
diff --git a/spec/ruby/core/binding/irb_spec.rb b/spec/ruby/core/binding/irb_spec.rb
new file mode 100644
index 0000000000..b3bc274f78
--- /dev/null
+++ b/spec/ruby/core/binding/irb_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+
+describe "Binding#irb" do
+ it "creates an IRB session with the binding in scope" do
+ irb_fixture = fixture __FILE__, "irb.rb"
+ irbrc_fixture = fixture __FILE__, "irbrc"
+
+ out = IO.popen([{"IRBRC"=>irbrc_fixture}, *ruby_exe, irb_fixture], "r+") do |pipe|
+ pipe.puts "a ** 2"
+ pipe.puts "exit"
+ pipe.readlines.map(&:chomp)
+ end
+
+ out[-3..-1].should == ["a ** 2", "100", "exit"]
+ end
+end
diff --git a/spec/ruby/core/binding/local_variable_defined_spec.rb b/spec/ruby/core/binding/local_variable_defined_spec.rb
index 5fa79b19e2..2fc6504ee5 100644
--- a/spec/ruby/core/binding/local_variable_defined_spec.rb
+++ b/spec/ruby/core/binding/local_variable_defined_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe 'Binding#local_variable_defined?' do
it 'returns false when a variable is not defined' do
@@ -26,7 +26,7 @@ describe 'Binding#local_variable_defined?' do
it 'returns true when a local variable is defined in a parent scope' do
foo = 10
- lambda {
+ -> {
binding.local_variable_defined?(:foo)
}.call.should == true
end
diff --git a/spec/ruby/core/binding/local_variable_get_spec.rb b/spec/ruby/core/binding/local_variable_get_spec.rb
index e65d08130e..005670becc 100644
--- a/spec/ruby/core/binding/local_variable_get_spec.rb
+++ b/spec/ruby/core/binding/local_variable_get_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Binding#local_variable_get" do
it "reads local variables captured in the binding" do
@@ -11,7 +11,7 @@ describe "Binding#local_variable_get" do
it "raises a NameError for missing variables" do
bind = BindingSpecs::Demo.new(1).get_empty_binding
- lambda {
+ -> {
bind.local_variable_get(:no_such_variable)
}.should raise_error(NameError)
end
@@ -19,7 +19,7 @@ describe "Binding#local_variable_get" do
it "reads variables added later to the binding" do
bind = BindingSpecs::Demo.new(1).get_empty_binding
- lambda {
+ -> {
bind.local_variable_get(:a)
}.should raise_error(NameError)
@@ -31,7 +31,7 @@ describe "Binding#local_variable_get" do
it 'gets a local variable defined in a parent scope' do
number = 10
- lambda {
+ -> {
binding.local_variable_get(:number)
}.call.should == 10
end
@@ -45,12 +45,12 @@ describe "Binding#local_variable_get" do
it "raises a NameError on global access" do
bind = binding
- lambda { bind.local_variable_get(:$0) }.should raise_error(NameError)
+ -> { bind.local_variable_get(:$0) }.should raise_error(NameError)
end
it "raises a NameError on special variable access" do
bind = binding
- lambda { bind.local_variable_get(:$~) }.should raise_error(NameError)
- lambda { bind.local_variable_get(:$_) }.should raise_error(NameError)
+ -> { bind.local_variable_get(:$~) }.should raise_error(NameError)
+ -> { bind.local_variable_get(:$_) }.should raise_error(NameError)
end
end
diff --git a/spec/ruby/core/binding/local_variable_set_spec.rb b/spec/ruby/core/binding/local_variable_set_spec.rb
index 067dcbd03e..1456c6dda1 100644
--- a/spec/ruby/core/binding/local_variable_set_spec.rb
+++ b/spec/ruby/core/binding/local_variable_set_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Binding#local_variable_set" do
it "adds nonexistent variables to the binding's eval scope" do
@@ -38,7 +38,7 @@ describe "Binding#local_variable_set" do
bind = binding
bind.local_variable_set(:number, 10)
- lambda { number }.should raise_error(NameError)
+ -> { number }.should raise_error(NameError)
end
it 'overwrites an existing local variable defined before a Binding' do
@@ -59,13 +59,13 @@ describe "Binding#local_variable_set" do
it "raises a NameError on global access" do
bind = binding
- lambda { bind.local_variable_set(:$0, "") }.should raise_error(NameError)
+ -> { bind.local_variable_set(:$0, "") }.should raise_error(NameError)
end
it "raises a NameError on special variable access" do
bind = binding
- lambda { bind.local_variable_set(:$~, "") }.should raise_error(NameError)
- lambda { bind.local_variable_set(:$_, "") }.should raise_error(NameError)
+ -> { bind.local_variable_set(:$~, "") }.should raise_error(NameError)
+ -> { bind.local_variable_set(:$_, "") }.should raise_error(NameError)
end
end
diff --git a/spec/ruby/core/binding/local_variables_spec.rb b/spec/ruby/core/binding/local_variables_spec.rb
index bc6ea71f10..92c817b9a8 100644
--- a/spec/ruby/core/binding/local_variables_spec.rb
+++ b/spec/ruby/core/binding/local_variables_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Binding#local_variables" do
it "returns an Array" do
diff --git a/spec/ruby/core/binding/location_spec.rb b/spec/ruby/core/binding/location_spec.rb
deleted file mode 100644
index b4a066038d..0000000000
--- a/spec/ruby/core/binding/location_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-
-describe "Binding#eval" do
- it "inherits __LINE__ from the enclosing scope" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- bind.eval("__LINE__").should == obj.get_line_of_binding
- end
-
- it "preserves __LINE__ across multiple calls to eval" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- bind.eval("__LINE__").should == obj.get_line_of_binding
- bind.eval("__LINE__").should == obj.get_line_of_binding
- end
-
- it "increments __LINE__ on each line of a multiline eval" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- bind.eval("#foo\n__LINE__").should == obj.get_line_of_binding + 1
- end
-
- it "starts with a __LINE__ of 1 if a filename is passed" do
- bind = BindingSpecs::Demo.new(1).get_binding
- bind.eval("__LINE__", "(test)").should == 1
- bind.eval("#foo\n__LINE__", "(test)").should == 2
- end
-
- it "starts with a __LINE__ from the third argument if passed" do
- bind = BindingSpecs::Demo.new(1).get_binding
- bind.eval("__LINE__", "(test)", 88).should == 88
- bind.eval("#foo\n__LINE__", "(test)", 88).should == 89
- end
-
- it "inherits __FILE__ from the enclosing scope" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- bind.eval("__FILE__").should == obj.get_file_of_binding
- end
-
- it "uses the __FILE__ that is passed in" do
- bind = BindingSpecs::Demo.new(1).get_binding
- bind.eval("__FILE__", "(test)").should == "(test)"
- end
-end
diff --git a/spec/ruby/core/binding/receiver_spec.rb b/spec/ruby/core/binding/receiver_spec.rb
index 8784ab0e38..4bf5e7a7bd 100644
--- a/spec/ruby/core/binding/receiver_spec.rb
+++ b/spec/ruby/core/binding/receiver_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Binding#receiver" do
it "returns the object to which binding is bound" do
diff --git a/spec/ruby/core/binding/source_location_spec.rb b/spec/ruby/core/binding/source_location_spec.rb
new file mode 100644
index 0000000000..e562bc65c8
--- /dev/null
+++ b/spec/ruby/core/binding/source_location_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/location'
+
+ruby_version_is "2.6" do
+ describe "Binding#source_location" do
+ it "returns an [file, line] pair" do
+ b = BindingSpecs::LocationMethod::TEST_BINDING
+ b.source_location.should == [BindingSpecs::LocationMethod::FILE_PATH, 4]
+ end
+ end
+end
diff --git a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb
index 9019b127c2..7c87a970d7 100644
--- a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb
+++ b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "RUBY_VERSION" do
it "is a String" do
@@ -7,8 +7,8 @@ describe "RUBY_VERSION" do
end
describe "RUBY_PATCHLEVEL" do
- it "is a Fixnum" do
- RUBY_PATCHLEVEL.should be_kind_of(Fixnum)
+ it "is an Integer" do
+ RUBY_PATCHLEVEL.should be_kind_of(Integer)
end
end
@@ -34,6 +34,12 @@ describe "RUBY_PLATFORM" do
it "is a String" do
RUBY_PLATFORM.should be_kind_of(String)
end
+
+ platform_is :darwin do
+ it 'ends with the build time kernel major version on darwin' do
+ RUBY_PLATFORM.should =~ /-darwin\d+$/
+ end
+ end
end
describe "RUBY_RELEASE_DATE" do
@@ -43,7 +49,15 @@ describe "RUBY_RELEASE_DATE" do
end
describe "RUBY_REVISION" do
- it "is a Fixnum" do
- RUBY_REVISION.should be_kind_of(Fixnum)
+ ruby_version_is ""..."2.7" do
+ it "is an Integer" do
+ RUBY_REVISION.should be_kind_of(Integer)
+ end
+ end
+
+ ruby_version_is "2.7" do
+ it "is a String" do
+ RUBY_REVISION.should be_kind_of(String)
+ end
end
end
diff --git a/spec/ruby/core/class/allocate_spec.rb b/spec/ruby/core/class/allocate_spec.rb
index 015db292eb..b39622e06a 100644
--- a/spec/ruby/core/class/allocate_spec.rb
+++ b/spec/ruby/core/class/allocate_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Class#allocate" do
it "returns an instance of self" do
@@ -14,7 +14,7 @@ describe "Class#allocate" do
it "throws an exception when calling a method on a new instance" do
klass = Class.allocate
- lambda do
+ -> do
klass.new
end.should raise_error(Exception)
end
@@ -30,11 +30,11 @@ describe "Class#allocate" do
end
end
- klass.allocate.initialized?.should == false
+ klass.allocate.should_not.initialized?
end
it "raises TypeError for #superclass" do
- lambda do
+ -> do
Class.allocate.superclass
end.should raise_error(TypeError)
end
diff --git a/spec/ruby/core/class/dup_spec.rb b/spec/ruby/core/class/dup_spec.rb
index 0548536bd6..701fd72e19 100644
--- a/spec/ruby/core/class/dup_spec.rb
+++ b/spec/ruby/core/class/dup_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
# NOTE: This is actually implemented by Module#initialize_copy
describe "Class#dup" do
diff --git a/spec/ruby/core/class/inherited_spec.rb b/spec/ruby/core/class/inherited_spec.rb
index 356e46be7c..8ef8bb8c35 100644
--- a/spec/ruby/core/class/inherited_spec.rb
+++ b/spec/ruby/core/class/inherited_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Class.inherited" do
@@ -92,11 +92,10 @@ describe "Class.inherited" do
end
class << top; private :inherited; end
- lambda { Class.new(top) }.should_not raise_error
+ -> { Class.new(top) }.should_not raise_error
class << top; protected :inherited; end
- lambda { Class.new(top) }.should_not raise_error
+ -> { Class.new(top) }.should_not raise_error
end
end
-
diff --git a/spec/ruby/core/class/initialize_spec.rb b/spec/ruby/core/class/initialize_spec.rb
index d268596dfe..6348758485 100644
--- a/spec/ruby/core/class/initialize_spec.rb
+++ b/spec/ruby/core/class/initialize_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Class#initialize" do
it "is private" do
@@ -6,18 +6,18 @@ describe "Class#initialize" do
end
it "raises a TypeError when called on already initialized classes" do
- lambda{
- Fixnum.send :initialize
+ ->{
+ Integer.send :initialize
}.should raise_error(TypeError)
- lambda{
+ ->{
Object.send :initialize
}.should raise_error(TypeError)
end
# See [redmine:2601]
it "raises a TypeError when called on BasicObject" do
- lambda{
+ ->{
BasicObject.send :initialize
}.should raise_error(TypeError)
end
@@ -28,7 +28,7 @@ describe "Class#initialize" do
end
it "raises a TypeError" do
- lambda{@uninitialized.send(:initialize, Class)}.should raise_error(TypeError)
+ ->{@uninitialized.send(:initialize, Class)}.should raise_error(TypeError)
end
end
end
diff --git a/spec/ruby/core/class/new_spec.rb b/spec/ruby/core/class/new_spec.rb
index 86323b1575..93152a83ee 100644
--- a/spec/ruby/core/class/new_spec.rb
+++ b/spec/ruby/core/class/new_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Class.new with a block given" do
it "yields the new class as self in the block" do
@@ -70,7 +70,7 @@ describe "Class.new" do
it "raises a TypeError if passed a metaclass" do
obj = mock("Class.new metaclass")
meta = obj.singleton_class
- lambda { Class.new meta }.should raise_error(TypeError)
+ -> { Class.new meta }.should raise_error(TypeError)
end
it "creates a class without a name" do
@@ -95,12 +95,13 @@ describe "Class.new" do
end
it "raises a TypeError when given a non-Class" do
- error_msg = /superclass must be a Class/
- lambda { Class.new("") }.should raise_error(TypeError, error_msg)
- lambda { Class.new(1) }.should raise_error(TypeError, error_msg)
- lambda { Class.new(:symbol) }.should raise_error(TypeError, error_msg)
- lambda { Class.new(mock('o')) }.should raise_error(TypeError, error_msg)
- lambda { Class.new(Module.new) }.should raise_error(TypeError, error_msg)
+ error_msg = /superclass must be a.*Class/
+ -> { Class.new("") }.should raise_error(TypeError, error_msg)
+ -> { Class.new(1) }.should raise_error(TypeError, error_msg)
+ -> { Class.new(:symbol) }.should raise_error(TypeError, error_msg)
+ -> { Class.new(mock('o')) }.should raise_error(TypeError, error_msg)
+ -> { Class.new(Module.new) }.should raise_error(TypeError, error_msg)
+ -> { Class.new(BasicObject.new) }.should raise_error(TypeError, error_msg)
end
end
@@ -126,7 +127,7 @@ describe "Class#new" do
end
end
- klass.new.initialized?.should == true
+ klass.new.should.initialized?
klass.new(1, 2, 3).args.should == [1, 2, 3]
end
diff --git a/spec/ruby/core/class/superclass_spec.rb b/spec/ruby/core/class/superclass_spec.rb
index 18b7ce5bde..00579238a6 100644
--- a/spec/ruby/core/class/superclass_spec.rb
+++ b/spec/ruby/core/class/superclass_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Class#superclass" do
it "returns the superclass of self" do
@@ -8,7 +8,7 @@ describe "Class#superclass" do
Class.superclass.should == Module
Class.new.superclass.should == Object
Class.new(String).superclass.should == String
- Class.new(Fixnum).superclass.should == Fixnum
+ Class.new(Integer).superclass.should == Integer
end
# redmine:567
diff --git a/spec/ruby/core/class/to_s_spec.rb b/spec/ruby/core/class/to_s_spec.rb
deleted file mode 100644
index 693517f0da..0000000000
--- a/spec/ruby/core/class/to_s_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-
-describe "Class#to_s" do
- it 'regular class returns same name as Module#to_s' do
- String.to_s.should == 'String'
- end
-
- describe 'singleton class' do
- it 'for modules includes module name' do
- CoreClassSpecs.singleton_class.to_s.should == '#<Class:CoreClassSpecs>'
- end
-
- it 'for classes includes class name' do
- CoreClassSpecs::Record.singleton_class.to_s.should == '#<Class:CoreClassSpecs::Record>'
- end
-
- it 'for objects includes class name and object ID' do
- obj = CoreClassSpecs::Record.new
- obj.singleton_class.to_s.should =~ /#<Class:#<CoreClassSpecs::Record:0x[0-9a-f]+>>/
- end
- end
-end
diff --git a/spec/ruby/core/comparable/between_spec.rb b/spec/ruby/core/comparable/between_spec.rb
index ebeadb7569..fd79bb9b4c 100644
--- a/spec/ruby/core/comparable/between_spec.rb
+++ b/spec/ruby/core/comparable/between_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Comparable#between?" do
it "returns true if self is greater than or equal to the first and less than or equal to the second argument" do
diff --git a/spec/ruby/core/comparable/clamp_spec.rb b/spec/ruby/core/comparable/clamp_spec.rb
index 75868258b5..393496fc76 100644
--- a/spec/ruby/core/comparable/clamp_spec.rb
+++ b/spec/ruby/core/comparable/clamp_spec.rb
@@ -1,50 +1,88 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
-ruby_version_is '2.4' do
- describe 'Comparable#clamp' do
+describe 'Comparable#clamp' do
+ ruby_version_is ""..."2.7" do
it 'raises an Argument error unless given 2 parameters' do
c = ComparableSpecs::Weird.new(0)
- lambda { c.clamp(c) }.should raise_error(ArgumentError)
- lambda { c.clamp(c, c, c) }.should raise_error(ArgumentError)
+ -> { c.clamp(c) }.should raise_error(ArgumentError)
+ -> { c.clamp(c, c, c) }.should raise_error(ArgumentError)
end
+ end
- it 'raises an Argument error unless the 2 parameters are correctly ordered' do
- one = ComparableSpecs::WithOnlyCompareDefined.new(1)
- two = ComparableSpecs::WithOnlyCompareDefined.new(2)
- c = ComparableSpecs::Weird.new(3)
+ it 'raises an Argument error unless the 2 parameters are correctly ordered' do
+ one = ComparableSpecs::WithOnlyCompareDefined.new(1)
+ two = ComparableSpecs::WithOnlyCompareDefined.new(2)
+ c = ComparableSpecs::Weird.new(3)
- lambda { c.clamp(two, one) }.should raise_error(ArgumentError)
- one.should_receive(:<=>).any_number_of_times.and_return(nil)
- lambda { c.clamp(one, two) }.should raise_error(ArgumentError)
- end
+ -> { c.clamp(two, one) }.should raise_error(ArgumentError)
+ one.should_receive(:<=>).any_number_of_times.and_return(nil)
+ -> { c.clamp(one, two) }.should raise_error(ArgumentError)
+ end
- it 'returns self if within the given parameters' do
+ it 'returns self if within the given parameters' do
+ one = ComparableSpecs::WithOnlyCompareDefined.new(1)
+ two = ComparableSpecs::WithOnlyCompareDefined.new(2)
+ three = ComparableSpecs::WithOnlyCompareDefined.new(3)
+ c = ComparableSpecs::Weird.new(2)
+
+ c.clamp(one, two).should equal(c)
+ c.clamp(two, two).should equal(c)
+ c.clamp(one, three).should equal(c)
+ c.clamp(two, three).should equal(c)
+ end
+
+ it 'returns the min parameter if smaller than it' do
+ one = ComparableSpecs::WithOnlyCompareDefined.new(1)
+ two = ComparableSpecs::WithOnlyCompareDefined.new(2)
+ c = ComparableSpecs::Weird.new(0)
+
+ c.clamp(one, two).should equal(one)
+ end
+
+ it 'returns the max parameter if greater than it' do
+ one = ComparableSpecs::WithOnlyCompareDefined.new(1)
+ two = ComparableSpecs::WithOnlyCompareDefined.new(2)
+ c = ComparableSpecs::Weird.new(3)
+
+ c.clamp(one, two).should equal(two)
+ end
+
+ ruby_version_is "2.7" do
+ it 'returns self if within the given range parameters' do
one = ComparableSpecs::WithOnlyCompareDefined.new(1)
two = ComparableSpecs::WithOnlyCompareDefined.new(2)
three = ComparableSpecs::WithOnlyCompareDefined.new(3)
c = ComparableSpecs::Weird.new(2)
- c.clamp(one, two).should equal(c)
- c.clamp(two, two).should equal(c)
- c.clamp(one, three).should equal(c)
- c.clamp(two, three).should equal(c)
+ c.clamp(one..two).should equal(c)
+ c.clamp(two..two).should equal(c)
+ c.clamp(one..three).should equal(c)
+ c.clamp(two..three).should equal(c)
end
- it 'returns the min parameter if smaller than it' do
+ it 'returns the minimum value of the range parameters if smaller than it' do
one = ComparableSpecs::WithOnlyCompareDefined.new(1)
two = ComparableSpecs::WithOnlyCompareDefined.new(2)
c = ComparableSpecs::Weird.new(0)
- c.clamp(one, two).should equal(one)
+ c.clamp(one..two).should equal(one)
+ end
+
+ it 'returns the maximum value of the range parameters if greater than it' do
+ one = ComparableSpecs::WithOnlyCompareDefined.new(1)
+ two = ComparableSpecs::WithOnlyCompareDefined.new(2)
+ c = ComparableSpecs::Weird.new(3)
+
+ c.clamp(one..two).should equal(two)
end
- it 'returns the max parameter if greater than it' do
+ it 'raises an Argument error if the range parameter is exclusive' do
one = ComparableSpecs::WithOnlyCompareDefined.new(1)
two = ComparableSpecs::WithOnlyCompareDefined.new(2)
c = ComparableSpecs::Weird.new(3)
- c.clamp(one, two).should equal(two)
+ -> { c.clamp(one...two) }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/comparable/equal_value_spec.rb b/spec/ruby/core/comparable/equal_value_spec.rb
index 2bc22771b4..ddcc03cb41 100644
--- a/spec/ruby/core/comparable/equal_value_spec.rb
+++ b/spec/ruby/core/comparable/equal_value_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Comparable#==" do
a = b = nil
@@ -48,16 +48,8 @@ describe "Comparable#==" do
a.should_receive(:<=>).once.and_return("abc")
end
- ruby_version_is ""..."2.3" do
- it "returns false" do
- (a == b).should be_false
- end
- end
-
- ruby_version_is "2.3" do
- it "raises an ArgumentError" do
- lambda { (a == b) }.should raise_error(ArgumentError)
- end
+ it "raises an ArgumentError" do
+ -> { (a == b) }.should raise_error(ArgumentError)
end
end
@@ -67,17 +59,8 @@ describe "Comparable#==" do
a.should_receive(:<=>).once.and_raise(StandardError)
end
- ruby_version_is ""..."2.3" do
- # Behaviour confirmed by MRI test suite
- it "returns false" do
- (a == b).should be_false
- end
- end
-
- ruby_version_is "2.3" do
- it "lets it go through" do
- lambda { (a == b) }.should raise_error(StandardError)
- end
+ it "lets it go through" do
+ -> { (a == b) }.should raise_error(StandardError)
end
end
@@ -87,22 +70,14 @@ describe "Comparable#==" do
a.should_receive(:<=>).once.and_raise(TypeError)
end
- ruby_version_is ""..."2.3" do
- it "returns false" do
- (a == b).should be_false
- end
- end
-
- ruby_version_is "2.3" do
- it "lets it go through" do
- lambda { (a == b) }.should raise_error(TypeError)
- end
+ it "lets it go through" do
+ -> { (a == b) }.should raise_error(TypeError)
end
end
it "lets it go through if it is not a StandardError" do
a.should_receive(:<=>).once.and_raise(Exception)
- lambda { (a == b) }.should raise_error(Exception)
+ -> { (a == b) }.should raise_error(Exception)
end
end
diff --git a/spec/ruby/core/comparable/gt_spec.rb b/spec/ruby/core/comparable/gt_spec.rb
index c4739bcf2a..150e653dc7 100644
--- a/spec/ruby/core/comparable/gt_spec.rb
+++ b/spec/ruby/core/comparable/gt_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Comparable#>" do
it "calls #<=> on self with other and returns true if #<=> returns any Integer greater than 0" do
@@ -38,6 +38,6 @@ describe "Comparable#>" do
b = ComparableSpecs::Weird.new(20)
a.should_receive(:<=>).any_number_of_times.and_return(nil)
- lambda { (a > b) }.should raise_error(ArgumentError)
+ -> { (a > b) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/comparable/gte_spec.rb b/spec/ruby/core/comparable/gte_spec.rb
index c9d8264ee6..328f58c66c 100644
--- a/spec/ruby/core/comparable/gte_spec.rb
+++ b/spec/ruby/core/comparable/gte_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative 'fixtures/classes'
+require_relative '../../spec_helper'
describe "Comparable#>=" do
it "calls #<=> on self with other and returns true if #<=> returns 0 or any Integer greater than 0" do
@@ -42,6 +42,6 @@ describe "Comparable#>=" do
b = ComparableSpecs::Weird.new(20)
a.should_receive(:<=>).any_number_of_times.and_return(nil)
- lambda { (a >= b) }.should raise_error(ArgumentError)
+ -> { (a >= b) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/comparable/lt_spec.rb b/spec/ruby/core/comparable/lt_spec.rb
index e9e76360b9..bca95f8d25 100644
--- a/spec/ruby/core/comparable/lt_spec.rb
+++ b/spec/ruby/core/comparable/lt_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Comparable#<" do
it "calls #<=> on self with other and returns true if #<=> returns any Integer less than 0" do
@@ -38,6 +38,12 @@ describe "Comparable#<" do
b = ComparableSpecs::Weird.new(20)
a.should_receive(:<=>).any_number_of_times.and_return(nil)
- lambda { (a < b) }.should raise_error(ArgumentError)
+ -> { (a < b) }.should raise_error(ArgumentError)
+ end
+
+ it "raises an argument error with a message containing the value" do
+ -> { ("foo" < 7) }.should raise_error(ArgumentError) { |e|
+ e.message.should == "comparison of String with 7 failed"
+ }
end
end
diff --git a/spec/ruby/core/comparable/lte_spec.rb b/spec/ruby/core/comparable/lte_spec.rb
index 96ed38ecd5..b5cb9cc4e7 100644
--- a/spec/ruby/core/comparable/lte_spec.rb
+++ b/spec/ruby/core/comparable/lte_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Comparable#<=" do
it "calls #<=> on self with other and returns true if #<=> returns 0 or any Integer less than 0" do
@@ -41,6 +41,6 @@ describe "Comparable#<=" do
b = ComparableSpecs::Weird.new(20)
a.should_receive(:<=>).any_number_of_times.and_return(nil)
- lambda { (a <= b) }.should raise_error(ArgumentError)
+ -> { (a <= b) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/complex/abs2_spec.rb b/spec/ruby/core/complex/abs2_spec.rb
index debfade075..3e5c5fd225 100644
--- a/spec/ruby/core/complex/abs2_spec.rb
+++ b/spec/ruby/core/complex/abs2_spec.rb
@@ -1,5 +1,9 @@
-require File.expand_path('../../../shared/complex/abs2', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#abs2" do
- it_behaves_like(:complex_abs2, :abs2)
+ it "returns the sum of the squares of the real and imaginary parts" do
+ Complex(1, -2).abs2.should == 1 + 4
+ Complex(-0.1, 0.2).abs2.should be_close(0.01 + 0.04, TOLERANCE)
+ Complex(0).abs2.should == 0
+ end
end
diff --git a/spec/ruby/core/complex/abs_spec.rb b/spec/ruby/core/complex/abs_spec.rb
index a00d161ee9..43912c517f 100644
--- a/spec/ruby/core/complex/abs_spec.rb
+++ b/spec/ruby/core/complex/abs_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../../../shared/complex/abs', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/abs'
describe "Complex#abs" do
- it_behaves_like(:complex_abs, :abs)
+ it_behaves_like :complex_abs, :abs
end
diff --git a/spec/ruby/core/complex/angle_spec.rb b/spec/ruby/core/complex/angle_spec.rb
index f0c46bfd03..4aa176956f 100644
--- a/spec/ruby/core/complex/angle_spec.rb
+++ b/spec/ruby/core/complex/angle_spec.rb
@@ -1,7 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-require File.expand_path('../../../shared/complex/arg', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/arg'
describe "Complex#angle" do
- it_behaves_like(:complex_arg, :angle)
+ it_behaves_like :complex_arg, :angle
end
diff --git a/spec/ruby/core/complex/arg_spec.rb b/spec/ruby/core/complex/arg_spec.rb
index 48f8a94cf5..009f19429f 100644
--- a/spec/ruby/core/complex/arg_spec.rb
+++ b/spec/ruby/core/complex/arg_spec.rb
@@ -1,7 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-require File.expand_path('../../../shared/complex/arg', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/arg'
describe "Complex#arg" do
- it_behaves_like(:complex_arg, :arg)
+ it_behaves_like :complex_arg, :arg
end
diff --git a/spec/ruby/core/complex/coerce_spec.rb b/spec/ruby/core/complex/coerce_spec.rb
index 7c01170fde..9023234e73 100644
--- a/spec/ruby/core/complex/coerce_spec.rb
+++ b/spec/ruby/core/complex/coerce_spec.rb
@@ -1,5 +1,70 @@
-require File.expand_path('../../../shared/complex/coerce', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#coerce" do
- it_behaves_like(:complex_coerce, :coerce)
+ before :each do
+ @one = Complex(1)
+ end
+
+ it "returns an array containing other and self as Complex when other is an Integer" do
+ result = @one.coerce(2)
+ result.should == [2, 1]
+ result.first.should be_kind_of(Complex)
+ result.last.should be_kind_of(Complex)
+ end
+
+ it "returns an array containing other and self as Complex when other is a Float" do
+ result = @one.coerce(20.5)
+ result.should == [20.5, 1]
+ result.first.should be_kind_of(Complex)
+ result.last.should be_kind_of(Complex)
+ end
+
+ it "returns an array containing other and self as Complex when other is an Integer" do
+ result = @one.coerce(4294967296)
+ result.should == [4294967296, 1]
+ result.first.should be_kind_of(Complex)
+ result.last.should be_kind_of(Complex)
+ end
+
+ it "returns an array containing other and self as Complex when other is a Rational" do
+ result = @one.coerce(Rational(5,6))
+ result.should == [Rational(5,6), 1]
+ result.first.should be_kind_of(Complex)
+ result.last.should be_kind_of(Complex)
+ end
+
+ it "returns an array containing other and self when other is a Complex" do
+ other = Complex(2)
+ result = @one.coerce(other)
+ result.should == [other, @one]
+ result.first.should equal(other)
+ result.last.should equal(@one)
+ end
+
+ it "returns an array containing other as Complex and self when other is a Numeric which responds to #real? with true" do
+ other = mock_numeric('other')
+ other.should_receive(:real?).any_number_of_times.and_return(true)
+ result = @one.coerce(other)
+ result.should == [other, @one]
+ result.first.should eql(Complex(other))
+ result.last.should equal(@one)
+ end
+
+ it "raises TypeError when other is a Numeric which responds to #real? with false" do
+ other = mock_numeric('other')
+ other.should_receive(:real?).any_number_of_times.and_return(false)
+ -> { @one.coerce(other) }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when other is a String" do
+ -> { @one.coerce("20") }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when other is nil" do
+ -> { @one.coerce(nil) }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when other is false" do
+ -> { @one.coerce(false) }.should raise_error(TypeError)
+ end
end
diff --git a/spec/ruby/core/complex/comparision_spec.rb b/spec/ruby/core/complex/comparision_spec.rb
new file mode 100644
index 0000000000..2a437afb71
--- /dev/null
+++ b/spec/ruby/core/complex/comparision_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../spec_helper'
+
+describe "Complex#<=>" do
+ ruby_version_is "2.7" do
+ it "returns nil if either self or argument has imaginary part" do
+ (Complex(5, 1) <=> Complex(2)).should be_nil
+ (Complex(1) <=> Complex(2, 1)).should be_nil
+ (5 <=> Complex(2, 1)).should be_nil
+ end
+
+ it "returns nil if argument is not numeric" do
+ (Complex(5, 1) <=> "cmp").should be_nil
+ (Complex(1) <=> "cmp").should be_nil
+ (Complex(1) <=> Object.new).should be_nil
+ end
+
+ it "returns 0, 1, or -1 if self and argument do not have imaginary part" do
+ (Complex(5) <=> Complex(2)).should == 1
+ (Complex(2) <=> Complex(3)).should == -1
+ (Complex(2) <=> Complex(2)).should == 0
+
+ (Complex(5) <=> 2).should == 1
+ (Complex(2) <=> 3).should == -1
+ (Complex(2) <=> 2).should == 0
+ end
+ end
+end
diff --git a/spec/ruby/core/complex/conj_spec.rb b/spec/ruby/core/complex/conj_spec.rb
index ad2c885b3b..5e3bc1acb8 100644
--- a/spec/ruby/core/complex/conj_spec.rb
+++ b/spec/ruby/core/complex/conj_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/conjugate', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/conjugate'
describe "Complex#conj" do
- it_behaves_like(:complex_conjugate, :conj)
+ it_behaves_like :complex_conjugate, :conj
end
diff --git a/spec/ruby/core/complex/conjugate_spec.rb b/spec/ruby/core/complex/conjugate_spec.rb
index 7fc2ddb430..f658bab4da 100644
--- a/spec/ruby/core/complex/conjugate_spec.rb
+++ b/spec/ruby/core/complex/conjugate_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/conjugate', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/conjugate'
describe "Complex#conjugate" do
- it_behaves_like(:complex_conjugate, :conjugate)
+ it_behaves_like :complex_conjugate, :conjugate
end
diff --git a/spec/ruby/core/complex/constants_spec.rb b/spec/ruby/core/complex/constants_spec.rb
index a8fcebbd31..50303de16c 100644
--- a/spec/ruby/core/complex/constants_spec.rb
+++ b/spec/ruby/core/complex/constants_spec.rb
@@ -1,5 +1,7 @@
-require File.expand_path('../../../shared/complex/constants', __FILE__)
+require_relative '../../spec_helper'
describe "Complex::I" do
- it_behaves_like :complex_I, :I
+ it "is Complex(0, 1)" do
+ Complex::I.should eql(Complex(0, 1))
+ end
end
diff --git a/spec/ruby/core/complex/denominator_spec.rb b/spec/ruby/core/complex/denominator_spec.rb
index 2568967968..c1a2003820 100644
--- a/spec/ruby/core/complex/denominator_spec.rb
+++ b/spec/ruby/core/complex/denominator_spec.rb
@@ -1,5 +1,13 @@
-require File.expand_path('../../../shared/complex/denominator', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#denominator" do
- it_behaves_like(:complex_denominator, :denominator)
+ it "returns the least common multiple denominator of the real and imaginary parts" do
+ Complex(3, 4).denominator.should == 1
+ Complex(3, bignum_value).denominator.should == 1
+
+ Complex(3, Rational(3,4)).denominator.should == 4
+
+ Complex(Rational(4,8), Rational(3,4)).denominator.should == 4
+ Complex(Rational(3,8), Rational(3,4)).denominator.should == 8
+ end
end
diff --git a/spec/ruby/core/complex/divide_spec.rb b/spec/ruby/core/complex/divide_spec.rb
index 71614c76e1..bebf862312 100644
--- a/spec/ruby/core/complex/divide_spec.rb
+++ b/spec/ruby/core/complex/divide_spec.rb
@@ -1,4 +1,5 @@
-require File.expand_path('../../../shared/complex/divide', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/divide'
describe "Complex#/" do
it_behaves_like :complex_divide, :/
diff --git a/spec/ruby/core/complex/eql_spec.rb b/spec/ruby/core/complex/eql_spec.rb
index c8e432029f..9194efc074 100644
--- a/spec/ruby/core/complex/eql_spec.rb
+++ b/spec/ruby/core/complex/eql_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#eql?" do
it "returns false if other is not Complex" do
diff --git a/spec/ruby/core/complex/equal_value_spec.rb b/spec/ruby/core/complex/equal_value_spec.rb
index b3d93911bd..ad7236b1bd 100644
--- a/spec/ruby/core/complex/equal_value_spec.rb
+++ b/spec/ruby/core/complex/equal_value_spec.rb
@@ -1,5 +1,93 @@
-require File.expand_path('../../../shared/complex/equal_value', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#==" do
- it_behaves_like :complex_equal_value, :==
+ describe "with Complex" do
+ it "returns true when self and other have numerical equality" do
+ Complex(1, 2).should == Complex(1, 2)
+ Complex(3, 9).should == Complex(3, 9)
+ Complex(-3, -9).should == Complex(-3, -9)
+
+ Complex(1, 2).should_not == Complex(3, 4)
+ Complex(3, 9).should_not == Complex(9, 3)
+
+ Complex(1.0, 2.0).should == Complex(1, 2)
+ Complex(3.0, 9.0).should_not == Complex(9.0, 3.0)
+
+ Complex(1.5, 2.5).should == Complex(1.5, 2.5)
+ Complex(1.5, 2.5).should == Complex(1.5, 2.5)
+ Complex(-1.5, 2.5).should == Complex(-1.5, 2.5)
+
+ Complex(1.5, 2.5).should_not == Complex(2.5, 1.5)
+ Complex(3.75, 2.5).should_not == Complex(1.5, 2.5)
+
+ Complex(bignum_value, 2.5).should == Complex(bignum_value, 2.5)
+ Complex(3.75, bignum_value).should_not == Complex(1.5, bignum_value)
+
+ Complex(nan_value).should_not == Complex(nan_value)
+ end
+ end
+
+ describe "with Numeric" do
+ it "returns true when self's imaginary part is 0 and the real part and other have numerical equality" do
+ Complex(3, 0).should == 3
+ Complex(-3, 0).should == -3
+
+ Complex(3.5, 0).should == 3.5
+ Complex(-3.5, 0).should == -3.5
+
+ Complex(bignum_value, 0).should == bignum_value
+ Complex(-bignum_value, 0).should == -bignum_value
+
+ Complex(3.0, 0).should == 3
+ Complex(-3.0, 0).should == -3
+
+ Complex(3, 0).should_not == 4
+ Complex(-3, 0).should_not == -4
+
+ Complex(3.5, 0).should_not == -4.5
+ Complex(-3.5, 0).should_not == 2.5
+
+ Complex(bignum_value, 0).should_not == bignum_value(10)
+ Complex(-bignum_value, 0).should_not == -bignum_value(20)
+ end
+ end
+
+ describe "with Object" do
+ # Integer#== and Float#== only return booleans - Bug?
+ it "calls other#== with self" do
+ value = Complex(3, 0)
+
+ obj = mock("Object")
+ obj.should_receive(:==).with(value).and_return(:expected)
+
+ (value == obj).should_not be_false
+ end
+ end
+
+ describe "with a Numeric which responds to #real? with true" do
+ before do
+ @other = mock_numeric('other')
+ @other.should_receive(:real?).any_number_of_times.and_return(true)
+ end
+
+ it "returns real == other when the imaginary part is zero" do
+ real = mock_numeric('real')
+ real.should_receive(:==).with(@other).and_return(true)
+ (Complex(real, 0) == @other).should be_true
+ end
+
+ it "returns false when when the imaginary part is not zero" do
+ (Complex(3, 1) == @other).should be_false
+ end
+ end
+
+ describe "with a Numeric which responds to #real? with false" do
+ it "returns other == self" do
+ complex = Complex(3, 0)
+ other = mock_numeric('other')
+ other.should_receive(:real?).any_number_of_times.and_return(false)
+ other.should_receive(:==).with(complex).and_return(true)
+ (complex == other).should be_true
+ end
+ end
end
diff --git a/spec/ruby/core/complex/exponent_spec.rb b/spec/ruby/core/complex/exponent_spec.rb
index 62f61a2bf3..86f827aece 100644
--- a/spec/ruby/core/complex/exponent_spec.rb
+++ b/spec/ruby/core/complex/exponent_spec.rb
@@ -1,5 +1,61 @@
-require File.expand_path('../../../shared/complex/exponent', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#**" do
- it_behaves_like :complex_exponent, :**
+ describe "with Integer 0" do
+ it "returns Complex(1)" do
+ (Complex(3, 4) ** 0).should eql(Complex(1))
+ end
+ end
+
+ describe "with Float 0.0" do
+ it "returns Complex(1.0, 0.0)" do
+ (Complex(3, 4) ** 0.0).should eql(Complex(1.0, 0.0))
+ end
+ end
+
+ describe "with Complex" do
+ it "returns self raised to the given power" do
+ (Complex(2, 1) ** Complex(2, 1)).should be_close(Complex(-0.504824688978319, 3.10414407699553), TOLERANCE)
+ (Complex(2, 1) ** Complex(3, 4)).should be_close(Complex(-0.179174656916581, -1.74071656397662), TOLERANCE)
+
+ (Complex(2, 1) ** Complex(-2, -1)).should be_close(Complex(-0.051041070450869, -0.313849223270419), TOLERANCE)
+ (Complex(-2, -1) ** Complex(2, 1)).should be_close(Complex(-11.6819929610857, 71.8320439736158), TOLERANCE)
+ end
+ end
+
+ describe "with Integer" do
+ it "returns self raised to the given power" do
+ (Complex(2, 1) ** 2).should == Complex(3, 4)
+ (Complex(3, 4) ** 2).should == Complex(-7, 24)
+ (Complex(3, 4) ** -2).should be_close(Complex(-0.0112, -0.0384), TOLERANCE)
+
+
+ (Complex(2, 1) ** 2.5).should be_close(Complex(2.99179707178602, 6.85206901006896), TOLERANCE)
+ (Complex(3, 4) ** 2.5).should be_close(Complex(-38.0, 41.0), TOLERANCE)
+ (Complex(3, 4) ** -2.5).should be_close(Complex(-0.01216, -0.01312), TOLERANCE)
+
+ (Complex(1) ** 1).should == Complex(1)
+
+ # NOTE: Takes way too long...
+ #(Complex(2, 1) ** bignum_value)
+ end
+ end
+
+ describe "with Rational" do
+ it "returns self raised to the given power" do
+ (Complex(2, 1) ** Rational(3, 4)).should be_close(Complex(1.71913265276568, 0.623124744394697), TOLERANCE)
+ (Complex(2, 1) ** Rational(4, 3)).should be_close(Complex(2.3828547125173, 1.69466313833091), TOLERANCE)
+ (Complex(2, 1) ** Rational(-4, 3)).should be_close(Complex(0.278700377879388, -0.198209003071003), TOLERANCE)
+ end
+ end
+
+ describe "with Object" do
+ it "tries to coerce self into other" do
+ value = Complex(3, 9)
+
+ obj = mock("Object")
+ obj.should_receive(:coerce).with(value).and_return([2, 5])
+ (value ** obj).should == 2 ** 5
+ end
+ end
end
diff --git a/spec/ruby/core/complex/fdiv_spec.rb b/spec/ruby/core/complex/fdiv_spec.rb
index 8211dfc9de..68f7d1b309 100644
--- a/spec/ruby/core/complex/fdiv_spec.rb
+++ b/spec/ruby/core/complex/fdiv_spec.rb
@@ -1,22 +1,22 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#fdiv" do
it "accepts a numeric argument" do
- lambda { Complex(20).fdiv(2) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(2.0) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(bignum_value) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(2) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(2.0) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(bignum_value) }.should_not raise_error(TypeError)
end
it "accepts a negative numeric argument" do
- lambda { Complex(20).fdiv(-2) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(-2.0) }.should_not raise_error(TypeError)
- lambda { Complex(20).fdiv(-bignum_value) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(-2) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(-2.0) }.should_not raise_error(TypeError)
+ -> { Complex(20).fdiv(-bignum_value) }.should_not raise_error(TypeError)
end
it "raises a TypeError if passed a non-numeric argument" do
- lambda { Complex(20).fdiv([]) }.should raise_error(TypeError)
- lambda { Complex(20).fdiv(:sym) }.should raise_error(TypeError)
- lambda { Complex(20).fdiv('s') }.should raise_error(TypeError)
+ -> { Complex(20).fdiv([]) }.should raise_error(TypeError)
+ -> { Complex(20).fdiv(:sym) }.should raise_error(TypeError)
+ -> { Complex(20).fdiv('s') }.should raise_error(TypeError)
end
it "sets the real part to NaN if self's real part is NaN" do
diff --git a/spec/ruby/core/complex/finite_spec.rb b/spec/ruby/core/complex/finite_spec.rb
new file mode 100644
index 0000000000..7d9f82404e
--- /dev/null
+++ b/spec/ruby/core/complex/finite_spec.rb
@@ -0,0 +1,32 @@
+require_relative '../../spec_helper'
+
+describe "Complex#finite?" do
+ it "returns true if magnitude is finite" do
+ (1+1i).should.finite?
+ end
+
+ it "returns false for positive infinity" do
+ value = Complex(Float::INFINITY, 42)
+ value.should_not.finite?
+ end
+
+ it "returns false for positive complex with infinite imaginary" do
+ value = Complex(1, Float::INFINITY)
+ value.should_not.finite?
+ end
+
+ it "returns false for negative infinity" do
+ value = -Complex(Float::INFINITY, 42)
+ value.should_not.finite?
+ end
+
+ it "returns false for negative complex with infinite imaginary" do
+ value = -Complex(1, Float::INFINITY)
+ value.should_not.finite?
+ end
+
+ it "returns false for NaN" do
+ value = Complex(Float::NAN, Float::NAN)
+ value.should_not.finite?
+ end
+end
diff --git a/spec/ruby/core/complex/hash_spec.rb b/spec/ruby/core/complex/hash_spec.rb
index db4b3590df..cad283309d 100644
--- a/spec/ruby/core/complex/hash_spec.rb
+++ b/spec/ruby/core/complex/hash_spec.rb
@@ -1,6 +1,16 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/hash', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#hash" do
- it_behaves_like(:complex_hash, :hash)
+ it "is static" do
+ Complex(1).hash.should == Complex(1).hash
+ Complex(1, 0).hash.should == Complex(1).hash
+ Complex(1, 1).hash.should == Complex(1, 1).hash
+ end
+
+ it "is different for different instances" do
+ Complex(1, 2).hash.should_not == Complex(1, 1).hash
+ Complex(2, 1).hash.should_not == Complex(1, 1).hash
+
+ Complex(1, 2).hash.should_not == Complex(2, 1).hash
+ end
end
diff --git a/spec/ruby/core/complex/imag_spec.rb b/spec/ruby/core/complex/imag_spec.rb
index 6aa8803f5d..2bafd1ab54 100644
--- a/spec/ruby/core/complex/imag_spec.rb
+++ b/spec/ruby/core/complex/imag_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../../../shared/complex/image', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/image'
describe "Complex#imag" do
- it_behaves_like(:complex_image, :imag)
+ it_behaves_like :complex_image, :imag
end
diff --git a/spec/ruby/core/complex/imaginary_spec.rb b/spec/ruby/core/complex/imaginary_spec.rb
index ecae19283b..a8a1bfea90 100644
--- a/spec/ruby/core/complex/imaginary_spec.rb
+++ b/spec/ruby/core/complex/imaginary_spec.rb
@@ -1,4 +1,5 @@
-require File.expand_path('../../../shared/complex/image', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/image'
describe "Complex#imaginary" do
it_behaves_like :complex_image, :imaginary
diff --git a/spec/ruby/core/complex/infinite_spec.rb b/spec/ruby/core/complex/infinite_spec.rb
new file mode 100644
index 0000000000..9e48860dee
--- /dev/null
+++ b/spec/ruby/core/complex/infinite_spec.rb
@@ -0,0 +1,32 @@
+require_relative '../../spec_helper'
+
+describe "Complex#infinite?" do
+ it "returns nil if magnitude is finite" do
+ (1+1i).infinite?.should == nil
+ end
+
+ it "returns 1 for positive infinity" do
+ value = Complex(Float::INFINITY, 42).infinite?
+ value.should == 1
+ end
+
+ it "returns 1 for positive complex with infinite imaginary" do
+ value = Complex(1, Float::INFINITY).infinite?
+ value.should == 1
+ end
+
+ it "returns -1 for negative infinity" do
+ value = -Complex(Float::INFINITY, 42).infinite?
+ value.should == -1
+ end
+
+ it "returns -1 for negative complex with infinite imaginary" do
+ value = -Complex(1, Float::INFINITY).infinite?
+ value.should == -1
+ end
+
+ it "returns nil for NaN" do
+ value = Complex(0, Float::NAN).infinite?
+ value.should == nil
+ end
+end
diff --git a/spec/ruby/core/complex/inspect_spec.rb b/spec/ruby/core/complex/inspect_spec.rb
index b766e7f730..71aabde5be 100644
--- a/spec/ruby/core/complex/inspect_spec.rb
+++ b/spec/ruby/core/complex/inspect_spec.rb
@@ -1,5 +1,16 @@
-require File.expand_path('../../../shared/complex/inspect', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#inspect" do
- it_behaves_like(:complex_inspect, :inspect)
+ it "returns (${real}+${image}i) for positive imaginary parts" do
+ Complex(1).inspect.should == "(1+0i)"
+ Complex(7).inspect.should == "(7+0i)"
+ Complex(-1, 4).inspect.should == "(-1+4i)"
+ Complex(-7, 6.7).inspect.should == "(-7+6.7i)"
+ end
+
+ it "returns (${real}-${image}i) for negative imaginary parts" do
+ Complex(0, -1).inspect.should == "(0-1i)"
+ Complex(-1, -4).inspect.should == "(-1-4i)"
+ Complex(-7, -6.7).inspect.should == "(-7-6.7i)"
+ end
end
diff --git a/spec/ruby/core/complex/integer_spec.rb b/spec/ruby/core/complex/integer_spec.rb
index 54b420e62c..0957accb70 100644
--- a/spec/ruby/core/complex/integer_spec.rb
+++ b/spec/ruby/core/complex/integer_spec.rb
@@ -1,3 +1,5 @@
+require_relative '../../spec_helper'
+
describe "Complex#integer?" do
it "returns false for a Complex with no imaginary part" do
Complex(20).integer?.should be_false
diff --git a/spec/ruby/core/complex/magnitude_spec.rb b/spec/ruby/core/complex/magnitude_spec.rb
index e9175d763e..86f3b29868 100644
--- a/spec/ruby/core/complex/magnitude_spec.rb
+++ b/spec/ruby/core/complex/magnitude_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../../../shared/complex/abs', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/abs'
describe "Complex#magnitude" do
- it_behaves_like(:complex_abs, :magnitude)
+ it_behaves_like :complex_abs, :magnitude
end
diff --git a/spec/ruby/core/complex/marshal_dump_spec.rb b/spec/ruby/core/complex/marshal_dump_spec.rb
index 8d37929f54..116899b0ad 100644
--- a/spec/ruby/core/complex/marshal_dump_spec.rb
+++ b/spec/ruby/core/complex/marshal_dump_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#marshal_dump" do
it "is a private method" do
diff --git a/spec/ruby/core/complex/minus_spec.rb b/spec/ruby/core/complex/minus_spec.rb
index 2b7b8bb270..7c104ce784 100644
--- a/spec/ruby/core/complex/minus_spec.rb
+++ b/spec/ruby/core/complex/minus_spec.rb
@@ -1,5 +1,45 @@
-require File.expand_path('../../../shared/complex/minus', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#-" do
- it_behaves_like :complex_minus, :-
+ describe "with Complex" do
+ it "subtracts both the real and imaginary components" do
+ (Complex(1, 2) - Complex(10, 20)).should == Complex(1 - 10, 2 - 20)
+ (Complex(1.5, 2.1) - Complex(100.2, -30.3)).should == Complex(1.5 - 100.2, 2.1 - (-30.3))
+ end
+ end
+
+ describe "with Integer" do
+ it "subtracts the real number from the real component of self" do
+ (Complex(1, 2) - 50).should == Complex(-49, 2)
+ (Complex(1, 2) - 50.5).should == Complex(-49.5, 2)
+ end
+ end
+
+ describe "with Object" do
+ it "tries to coerce self into other" do
+ value = Complex(3, 9)
+
+ obj = mock("Object")
+ obj.should_receive(:coerce).with(value).and_return([2, 5])
+ (value - obj).should == 2 - 5
+ end
+ end
+
+ describe "passed Numeric which responds to #real? with true" do
+ it "coerces the passed argument to the type of the real part and subtracts the resulting elements" do
+ n = mock_numeric('n')
+ n.should_receive(:real?).and_return(true)
+ n.should_receive(:coerce).with(1).and_return([1, 4])
+ (Complex(1, 2) - n).should == Complex(-3, 2)
+ end
+ end
+
+ describe "passed Numeric which responds to #real? with false" do
+ it "coerces the passed argument to Complex and subtracts the resulting elements" do
+ n = mock_numeric('n')
+ n.should_receive(:real?).and_return(false)
+ n.should_receive(:coerce).with(Complex(1, 2)).and_return([Complex(1, 2), Complex(3, 4)])
+ (Complex(1, 2) - n).should == Complex(-2, -2)
+ end
+ end
end
diff --git a/spec/ruby/core/complex/multiply_spec.rb b/spec/ruby/core/complex/multiply_spec.rb
index 7f600fc1ab..35bf7c8455 100644
--- a/spec/ruby/core/complex/multiply_spec.rb
+++ b/spec/ruby/core/complex/multiply_spec.rb
@@ -1,5 +1,49 @@
-require File.expand_path('../../../shared/complex/multiply', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#*" do
- it_behaves_like :complex_multiply, :*
+ describe "with Complex" do
+ it "multiplies according to the usual rule for complex numbers: (a + bi) * (c + di) = ac - bd + (ad + bc)i" do
+ (Complex(1, 2) * Complex(10, 20)).should == Complex((1 * 10) - (2 * 20), (1 * 20) + (2 * 10))
+ (Complex(1.5, 2.1) * Complex(100.2, -30.3)).should == Complex((1.5 * 100.2) - (2.1 * -30.3), (1.5 * -30.3) + (2.1 * 100.2))
+ end
+ end
+
+ describe "with Integer" do
+ it "multiplies both parts of self by the given Integer" do
+ (Complex(3, 2) * 50).should == Complex(150, 100)
+ (Complex(-3, 2) * 50.5).should == Complex(-151.5, 101)
+ end
+ end
+
+ describe "with Object" do
+ it "tries to coerce self into other" do
+ value = Complex(3, 9)
+
+ obj = mock("Object")
+ obj.should_receive(:coerce).with(value).and_return([2, 5])
+ (value * obj).should == 2 * 5
+ end
+ end
+
+ describe "with a Numeric which responds to #real? with true" do
+ it "multiples both parts of self by other" do
+ other = mock_numeric('other')
+ real = mock_numeric('real')
+ imag = mock_numeric('imag')
+ other.should_receive(:real?).and_return(true)
+ real.should_receive(:*).with(other).and_return(1)
+ imag.should_receive(:*).with(other).and_return(2)
+ (Complex(real, imag) * other).should == Complex(1, 2)
+ end
+
+ describe "with a Numeric which responds to #real? with false" do
+ it "coerces the passed argument to Complex and multiplies the resulting elements" do
+ complex = Complex(3, 0)
+ other = mock_numeric('other')
+ other.should_receive(:real?).any_number_of_times.and_return(false)
+ other.should_receive(:coerce).with(complex).and_return([5, 2])
+ (complex * other).should == 10
+ end
+ end
+ end
end
diff --git a/spec/ruby/core/complex/negative_spec.rb b/spec/ruby/core/complex/negative_spec.rb
index 5b51933106..62ab89c04a 100644
--- a/spec/ruby/core/complex/negative_spec.rb
+++ b/spec/ruby/core/complex/negative_spec.rb
@@ -1,10 +1,12 @@
+require_relative '../../spec_helper'
+
describe "Complex#negative?" do
it "is undefined" do
c = Complex(1)
c.methods.should_not include(:negative?)
- lambda {
+ -> {
c.negative?
}.should raise_error(NoMethodError)
end
diff --git a/spec/ruby/core/complex/numerator_spec.rb b/spec/ruby/core/complex/numerator_spec.rb
index 8c0e8761bd..7ab66e6a61 100644
--- a/spec/ruby/core/complex/numerator_spec.rb
+++ b/spec/ruby/core/complex/numerator_spec.rb
@@ -1,5 +1,19 @@
-require File.expand_path('../../../shared/complex/numerator', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#numerator" do
- it_behaves_like(:complex_numerator, :numerator)
+ it "returns self's numerator" do
+ Complex(2).numerator.should == Complex(2)
+ Complex(3, 4).numerator.should == Complex(3, 4)
+
+ Complex(Rational(3, 4), Rational(3, 4)).numerator.should == Complex(3, 3)
+ Complex(Rational(7, 4), Rational(8, 4)).numerator.should == Complex(7, 8)
+
+ Complex(Rational(7, 8), Rational(8, 4)).numerator.should == Complex(7, 16)
+ Complex(Rational(7, 4), Rational(8, 8)).numerator.should == Complex(7, 4)
+
+ # NOTE:
+ # Bug? - Fails with a MethodMissingError
+ # (undefined method `denominator' for 3.5:Float)
+ # Complex(3.5, 3.7).numerator
+ end
end
diff --git a/spec/ruby/core/complex/phase_spec.rb b/spec/ruby/core/complex/phase_spec.rb
index c17f922c7f..89574bf533 100644
--- a/spec/ruby/core/complex/phase_spec.rb
+++ b/spec/ruby/core/complex/phase_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/complex/arg', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/arg'
describe "Complex#phase" do
it_behaves_like :complex_arg, :phase
diff --git a/spec/ruby/core/complex/plus_spec.rb b/spec/ruby/core/complex/plus_spec.rb
index 076582681f..2056ca786c 100644
--- a/spec/ruby/core/complex/plus_spec.rb
+++ b/spec/ruby/core/complex/plus_spec.rb
@@ -1,5 +1,45 @@
-require File.expand_path('../../../shared/complex/plus', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#+" do
- it_behaves_like :complex_plus, :+
+ describe "with Complex" do
+ it "adds both the real and imaginary components" do
+ (Complex(1, 2) + Complex(10, 20)).should == Complex(1 + 10, 2 + 20)
+ (Complex(1.5, 2.1) + Complex(100.2, -30.3)).should == Complex(1.5 + 100.2, 2.1 + (-30.3))
+ end
+ end
+
+ describe "with Integer" do
+ it "adds the real number to the real component of self" do
+ (Complex(1, 2) + 50).should == Complex(51, 2)
+ (Complex(1, 2) + 50.5).should == Complex(51.5, 2)
+ end
+ end
+
+ describe "with Object" do
+ it "tries to coerce self into other" do
+ value = Complex(3, 9)
+
+ obj = mock("Object")
+ obj.should_receive(:coerce).with(value).and_return([2, 5])
+ (value + obj).should == 2 + 5
+ end
+ end
+
+ describe "passed Numeric which responds to #real? with true" do
+ it "coerces the passed argument to the type of the real part and adds the resulting elements" do
+ n = mock_numeric('n')
+ n.should_receive(:real?).and_return(true)
+ n.should_receive(:coerce).with(1).and_return([1, 4])
+ (Complex(1, 2) + n).should == Complex(5, 2)
+ end
+ end
+
+ describe "passed Numeric which responds to #real? with false" do
+ it "coerces the passed argument to Complex and adds the resulting elements" do
+ n = mock_numeric('n')
+ n.should_receive(:real?).and_return(false)
+ n.should_receive(:coerce).with(Complex(1, 2)).and_return([Complex(1, 2), Complex(3, 4)])
+ (Complex(1, 2) + n).should == Complex(4, 6)
+ end
+ end
end
diff --git a/spec/ruby/core/complex/polar_spec.rb b/spec/ruby/core/complex/polar_spec.rb
index d847e916ff..2a5d8ebd69 100644
--- a/spec/ruby/core/complex/polar_spec.rb
+++ b/spec/ruby/core/complex/polar_spec.rb
@@ -1,14 +1,27 @@
-require File.expand_path('../../../shared/complex/polar', __FILE__)
+require_relative '../../spec_helper'
describe "Complex.polar" do
- it_behaves_like(:complex_polar_class, :polar)
+ it "returns a complex number in terms of radius and angle" do
+ Complex.polar(50, 60).should be_close(Complex(-47.6206490207578, -15.2405310551108), TOLERANCE)
+ Complex.polar(-10, -20).should be_close(Complex(-4.08082061813392, 9.12945250727628), TOLERANCE)
+ end
it "raises a TypeError when given non real arguments" do
- lambda{ Complex.polar(nil) }.should raise_error(TypeError)
- lambda{ Complex.polar(nil, nil) }.should raise_error(TypeError)
+ ->{ Complex.polar(nil) }.should raise_error(TypeError)
+ ->{ Complex.polar(nil, nil) }.should raise_error(TypeError)
end
end
describe "Complex#polar" do
- it_behaves_like(:complex_polar, :polar)
+ it "returns the absolute value and the argument" do
+ a = Complex(3, 4)
+ a.polar.size.should == 2
+ a.polar.first.should == 5.0
+ a.polar.last.should be_close(0.927295218001612, TOLERANCE)
+
+ b = Complex(-3.5, 4.7)
+ b.polar.size.should == 2
+ b.polar.first.should be_close(5.86003412959345, TOLERANCE)
+ b.polar.last.should be_close(2.21088447955664, TOLERANCE)
+ end
end
diff --git a/spec/ruby/core/complex/positive_spec.rb b/spec/ruby/core/complex/positive_spec.rb
index 88898d31cf..f1bad8608c 100644
--- a/spec/ruby/core/complex/positive_spec.rb
+++ b/spec/ruby/core/complex/positive_spec.rb
@@ -1,10 +1,12 @@
+require_relative '../../spec_helper'
+
describe "Complex#positive?" do
it "is undefined" do
c = Complex(1)
c.methods.should_not include(:positive?)
- lambda {
+ -> {
c.positive?
}.should raise_error(NoMethodError)
end
diff --git a/spec/ruby/core/complex/quo_spec.rb b/spec/ruby/core/complex/quo_spec.rb
index cb3f1203b4..ee6fd65c79 100644
--- a/spec/ruby/core/complex/quo_spec.rb
+++ b/spec/ruby/core/complex/quo_spec.rb
@@ -1,4 +1,5 @@
-require File.expand_path('../../../shared/complex/divide', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/divide'
describe "Complex#quo" do
it_behaves_like :complex_divide, :quo
diff --git a/spec/ruby/core/complex/rationalize_spec.rb b/spec/ruby/core/complex/rationalize_spec.rb
index 2dd1e9b122..043b8ddf2a 100644
--- a/spec/ruby/core/complex/rationalize_spec.rb
+++ b/spec/ruby/core/complex/rationalize_spec.rb
@@ -1,10 +1,12 @@
+require_relative '../../spec_helper'
+
describe "Complex#rationalize" do
it "raises RangeError if self has non-zero imaginary part" do
- lambda { Complex(1,5).rationalize }.should raise_error(RangeError)
+ -> { Complex(1,5).rationalize }.should raise_error(RangeError)
end
it "raises RangeError if self has 0.0 imaginary part" do
- lambda { Complex(1,0.0).rationalize }.should raise_error(RangeError)
+ -> { Complex(1,0.0).rationalize }.should raise_error(RangeError)
end
it "returns a Rational if self has zero imaginary part" do
@@ -23,7 +25,7 @@ describe "Complex#rationalize" do
end
it "raises ArgumentError when passed more than one argument" do
- lambda { Complex(1,0).rationalize(0.1, 0.1) }.should raise_error(ArgumentError)
- lambda { Complex(1,0).rationalize(0.1, 0.1, 2) }.should raise_error(ArgumentError)
+ -> { Complex(1,0).rationalize(0.1, 0.1) }.should raise_error(ArgumentError)
+ -> { Complex(1,0).rationalize(0.1, 0.1, 2) }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/complex/real_spec.rb b/spec/ruby/core/complex/real_spec.rb
index 1293e02d3c..2ea791c005 100644
--- a/spec/ruby/core/complex/real_spec.rb
+++ b/spec/ruby/core/complex/real_spec.rb
@@ -1,7 +1,12 @@
-require File.expand_path('../../../shared/complex/real', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#real" do
- it_behaves_like(:complex_real, :real)
+ it "returns the real part of self" do
+ Complex(1, 0).real.should == 1
+ Complex(2, 1).real.should == 2
+ Complex(6.7, 8.9).real.should == 6.7
+ Complex(bignum_value, 3).real.should == bignum_value
+ end
end
describe "Complex#real?" do
diff --git a/spec/ruby/core/complex/rect_spec.rb b/spec/ruby/core/complex/rect_spec.rb
index cf2ff9e83b..9e95f3efc2 100644
--- a/spec/ruby/core/complex/rect_spec.rb
+++ b/spec/ruby/core/complex/rect_spec.rb
@@ -1,9 +1,10 @@
-require File.expand_path('../../../shared/complex/rect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/rect'
describe "Complex#rect" do
- it_behaves_like(:complex_rect, :rect)
+ it_behaves_like :complex_rect, :rect
end
describe "Complex.rect" do
- it_behaves_like(:complex_rect_class, :rect)
+ it_behaves_like :complex_rect_class, :rect
end
diff --git a/spec/ruby/core/complex/rectangular_spec.rb b/spec/ruby/core/complex/rectangular_spec.rb
index 0eb29c3500..d4b8ad9782 100644
--- a/spec/ruby/core/complex/rectangular_spec.rb
+++ b/spec/ruby/core/complex/rectangular_spec.rb
@@ -1,9 +1,10 @@
-require File.expand_path('../../../shared/complex/rect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/rect'
describe "Complex#rectangular" do
- it_behaves_like(:complex_rect, :rectangular)
+ it_behaves_like :complex_rect, :rectangular
end
describe "Complex.rectangular" do
- it_behaves_like(:complex_rect_class, :rectangular)
+ it_behaves_like :complex_rect_class, :rectangular
end
diff --git a/spec/ruby/core/complex/shared/abs.rb b/spec/ruby/core/complex/shared/abs.rb
new file mode 100644
index 0000000000..2299479341
--- /dev/null
+++ b/spec/ruby/core/complex/shared/abs.rb
@@ -0,0 +1,10 @@
+describe :complex_abs, shared: true do
+ it "returns the modulus: |a + bi| = sqrt((a ^ 2) + (b ^ 2))" do
+ Complex(0, 0).send(@method).should == 0
+ Complex(3, 4).send(@method).should == 5 # well-known integer case
+ Complex(-3, 4).send(@method).should == 5
+ Complex(1, -1).send(@method).should be_close(Math.sqrt(2), TOLERANCE)
+ Complex(6.5, 0).send(@method).should be_close(6.5, TOLERANCE)
+ Complex(0, -7.2).send(@method).should be_close(7.2, TOLERANCE)
+ end
+end
diff --git a/spec/ruby/shared/complex/arg.rb b/spec/ruby/core/complex/shared/arg.rb
index c81f197433..c81f197433 100644
--- a/spec/ruby/shared/complex/arg.rb
+++ b/spec/ruby/core/complex/shared/arg.rb
diff --git a/spec/ruby/shared/complex/conjugate.rb b/spec/ruby/core/complex/shared/conjugate.rb
index d1ae47bcb6..d1ae47bcb6 100644
--- a/spec/ruby/shared/complex/conjugate.rb
+++ b/spec/ruby/core/complex/shared/conjugate.rb
diff --git a/spec/ruby/core/complex/shared/divide.rb b/spec/ruby/core/complex/shared/divide.rb
new file mode 100644
index 0000000000..dc1b870cff
--- /dev/null
+++ b/spec/ruby/core/complex/shared/divide.rb
@@ -0,0 +1,82 @@
+describe :complex_divide, shared: true do
+ describe "with Complex" do
+ it "divides according to the usual rule for complex numbers" do
+ a = Complex((1 * 10) - (2 * 20), (1 * 20) + (2 * 10))
+ b = Complex(1, 2)
+ a.send(@method, b).should == Complex(10, 20)
+
+ c = Complex((1.5 * 100.2) - (2.1 * -30.3), (1.5 * -30.3) + (2.1 * 100.2))
+ d = Complex(1.5, 2.1)
+ # remember the floating-point arithmetic
+ c.send(@method, d).should be_close(Complex(100.2, -30.3), TOLERANCE)
+ end
+ end
+
+ describe "with Integer" do
+ it "divides both parts of the Complex number" do
+ Complex(20, 40).send(@method, 2).should == Complex(10, 20)
+ Complex(30, 30).send(@method, 10).should == Complex(3, 3)
+ end
+
+ it "raises a ZeroDivisionError when given zero" do
+ -> { Complex(20, 40).send(@method, 0) }.should raise_error(ZeroDivisionError)
+ end
+
+ it "produces Rational parts" do
+ Complex(5, 9).send(@method, 2).should eql(Complex(Rational(5,2), Rational(9,2)))
+ end
+ end
+
+ describe "with Integer" do
+ it "divides both parts of the Complex number" do
+ Complex(20, 40).send(@method, 2).should == Complex(10, 20)
+ Complex(15, 16).send(@method, 2.0).should be_close(Complex(7.5, 8), TOLERANCE)
+ end
+ end
+
+ describe "with Float" do
+ it "divides both parts of the Complex number" do
+ Complex(3, 9).send(@method, 1.5).should == Complex(2, 6)
+ Complex(15, 16).send(@method, 2.0).should be_close(Complex(7.5, 8), TOLERANCE)
+ end
+
+ it "returns Complex(Infinity, Infinity) when given zero" do
+ Complex(20, 40).send(@method, 0.0).real.infinite?.should == 1
+ Complex(20, 40).send(@method, 0.0).imag.infinite?.should == 1
+ Complex(-20, 40).send(@method, 0.0).real.infinite?.should == -1
+ Complex(-20, 40).send(@method, 0.0).imag.infinite?.should == 1
+ end
+ end
+
+ describe "with Object" do
+ it "tries to coerce self into other" do
+ value = Complex(3, 9)
+
+ obj = mock("Object")
+ obj.should_receive(:coerce).with(value).and_return([4, 2])
+ value.send(@method, obj).should == 2
+ end
+ end
+
+ describe "with a Numeric which responds to #real? with true" do
+ it "returns Complex(real.quo(other), imag.quo(other))" do
+ other = mock_numeric('other')
+ real = mock_numeric('real')
+ imag = mock_numeric('imag')
+ other.should_receive(:real?).and_return(true)
+ real.should_receive(:quo).with(other).and_return(1)
+ imag.should_receive(:quo).with(other).and_return(2)
+ Complex(real, imag).send(@method, other).should == Complex(1, 2)
+ end
+ end
+
+ describe "with a Numeric which responds to #real? with false" do
+ it "coerces the passed argument to Complex and divides the resulting elements" do
+ complex = Complex(3, 0)
+ other = mock_numeric('other')
+ other.should_receive(:real?).any_number_of_times.and_return(false)
+ other.should_receive(:coerce).with(complex).and_return([5, 2])
+ complex.send(@method, other).should eql(Rational(5, 2))
+ end
+ end
+end
diff --git a/spec/ruby/core/complex/shared/image.rb b/spec/ruby/core/complex/shared/image.rb
new file mode 100644
index 0000000000..f839dbcaf9
--- /dev/null
+++ b/spec/ruby/core/complex/shared/image.rb
@@ -0,0 +1,8 @@
+describe :complex_image, shared: true do
+ it "returns the imaginary part of self" do
+ Complex(1, 0).send(@method).should == 0
+ Complex(2, 1).send(@method).should == 1
+ Complex(6.7, 8.9).send(@method).should == 8.9
+ Complex(1, bignum_value).send(@method).should == bignum_value
+ end
+end
diff --git a/spec/ruby/core/complex/shared/rect.rb b/spec/ruby/core/complex/shared/rect.rb
new file mode 100644
index 0000000000..9f5de1ffeb
--- /dev/null
+++ b/spec/ruby/core/complex/shared/rect.rb
@@ -0,0 +1,94 @@
+describe :complex_rect, shared: true do
+ before :each do
+ @numbers = [
+ Complex(1),
+ Complex(0, 20),
+ Complex(0, 0),
+ Complex(0.0),
+ Complex(9999999**99),
+ Complex(-20),
+ Complex.polar(76, 10)
+ ]
+ end
+
+ it "returns an Array" do
+ @numbers.each do |number|
+ number.send(@method).should be_an_instance_of(Array)
+ end
+ end
+
+ it "returns a two-element Array" do
+ @numbers.each do |number|
+ number.send(@method).size.should == 2
+ end
+ end
+
+ it "returns the real part of self as the first element" do
+ @numbers.each do |number|
+ number.send(@method).first.should == number.real
+ end
+ end
+
+ it "returns the imaginary part of self as the last element" do
+ @numbers.each do |number|
+ number.send(@method).last.should == number.imaginary
+ end
+ end
+
+ it "raises an ArgumentError if given any arguments" do
+ @numbers.each do |number|
+ -> { number.send(@method, number) }.should raise_error(ArgumentError)
+ end
+ end
+end
+
+describe :complex_rect_class, shared: true do
+ describe "passed a Numeric n which responds to #real? with true" do
+ it "returns a Complex with real part n and imaginary part 0" do
+ n = mock_numeric('n')
+ n.should_receive(:real?).any_number_of_times.and_return(true)
+ result = Complex.send(@method, n)
+ result.real.should == n
+ result.imag.should == 0
+ end
+ end
+
+ describe "passed a Numeric which responds to #real? with false" do
+ it "raises TypeError" do
+ n = mock_numeric('n')
+ n.should_receive(:real?).any_number_of_times.and_return(false)
+ -> { Complex.send(@method, n) }.should raise_error(TypeError)
+ end
+ end
+
+ describe "passed Numerics n1 and n2 and at least one responds to #real? with false" do
+ [[false, false], [false, true], [true, false]].each do |r1, r2|
+ it "raises TypeError" do
+ n1 = mock_numeric('n1')
+ n2 = mock_numeric('n2')
+ n1.should_receive(:real?).any_number_of_times.and_return(r1)
+ n2.should_receive(:real?).any_number_of_times.and_return(r2)
+ -> { Complex.send(@method, n1, n2) }.should raise_error(TypeError)
+ end
+ end
+ end
+
+ describe "passed Numerics n1 and n2 and both respond to #real? with true" do
+ it "returns a Complex with real part n1 and imaginary part n2" do
+ n1 = mock_numeric('n1')
+ n2 = mock_numeric('n2')
+ n1.should_receive(:real?).any_number_of_times.and_return(true)
+ n2.should_receive(:real?).any_number_of_times.and_return(true)
+ result = Complex.send(@method, n1, n2)
+ result.real.should == n1
+ result.imag.should == n2
+ end
+ end
+
+ describe "passed a non-Numeric" do
+ it "raises TypeError" do
+ -> { Complex.send(@method, :sym) }.should raise_error(TypeError)
+ -> { Complex.send(@method, 0, :sym) }.should raise_error(TypeError)
+ end
+ end
+end
diff --git a/spec/ruby/core/complex/to_c_spec.rb b/spec/ruby/core/complex/to_c_spec.rb
new file mode 100644
index 0000000000..5ce01d9d4e
--- /dev/null
+++ b/spec/ruby/core/complex/to_c_spec.rb
@@ -0,0 +1,12 @@
+require_relative '../../spec_helper'
+
+describe "Complex#to_c" do
+ it "returns self" do
+ value = Complex(1, 5)
+ value.to_c.should equal(value)
+ end
+
+ it 'returns the same value' do
+ Complex(1, 5).to_c.should == Complex(1, 5)
+ end
+end
diff --git a/spec/ruby/core/complex/to_f_spec.rb b/spec/ruby/core/complex/to_f_spec.rb
index 33342e61cc..b53471c1fc 100644
--- a/spec/ruby/core/complex/to_f_spec.rb
+++ b/spec/ruby/core/complex/to_f_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#to_f" do
- describe "when the imaginary part is Fixnum 0" do
+ describe "when the imaginary part is Integer 0" do
it "returns the result of sending #to_f to the real part" do
real = mock_numeric('real')
real.should_receive(:to_f).and_return(:f)
@@ -29,13 +29,13 @@ describe "Complex#to_f" do
describe "when the imaginary part is non-zero" do
it "raises RangeError" do
- lambda { Complex(0, 1).to_f }.should raise_error(RangeError)
+ -> { Complex(0, 1).to_f }.should raise_error(RangeError)
end
end
describe "when the imaginary part is Float 0.0" do
it "raises RangeError" do
- lambda { Complex(0, 0.0).to_f }.should raise_error(RangeError)
+ -> { Complex(0, 0.0).to_f }.should raise_error(RangeError)
end
end
end
diff --git a/spec/ruby/core/complex/to_i_spec.rb b/spec/ruby/core/complex/to_i_spec.rb
index ea8b199b2e..1e78f5ec0e 100644
--- a/spec/ruby/core/complex/to_i_spec.rb
+++ b/spec/ruby/core/complex/to_i_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#to_i" do
- describe "when the imaginary part is Fixnum 0" do
+ describe "when the imaginary part is Integer 0" do
it "returns the result of sending #to_i to the real part" do
real = mock_numeric('real')
real.should_receive(:to_i).and_return(:i)
@@ -29,13 +29,13 @@ describe "Complex#to_i" do
describe "when the imaginary part is non-zero" do
it "raises RangeError" do
- lambda { Complex(0, 1).to_i }.should raise_error(RangeError)
+ -> { Complex(0, 1).to_i }.should raise_error(RangeError)
end
end
describe "when the imaginary part is Float 0.0" do
it "raises RangeError" do
- lambda { Complex(0, 0.0).to_i }.should raise_error(RangeError)
+ -> { Complex(0, 0.0).to_i }.should raise_error(RangeError)
end
end
end
diff --git a/spec/ruby/core/complex/to_r_spec.rb b/spec/ruby/core/complex/to_r_spec.rb
index 92fcdd3862..4559921492 100644
--- a/spec/ruby/core/complex/to_r_spec.rb
+++ b/spec/ruby/core/complex/to_r_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#to_r" do
- describe "when the imaginary part is Fixnum 0" do
+ describe "when the imaginary part is Integer 0" do
it "returns the result of sending #to_r to the real part" do
real = mock_numeric('real')
real.should_receive(:to_r).and_return(:r)
@@ -29,13 +29,13 @@ describe "Complex#to_r" do
describe "when the imaginary part is non-zero" do
it "raises RangeError" do
- lambda { Complex(0, 1).to_r }.should raise_error(RangeError)
+ -> { Complex(0, 1).to_r }.should raise_error(RangeError)
end
end
describe "when the imaginary part is Float 0.0" do
it "raises RangeError" do
- lambda { Complex(0, 0.0).to_r }.should raise_error(RangeError)
+ -> { Complex(0, 0.0).to_r }.should raise_error(RangeError)
end
end
end
diff --git a/spec/ruby/core/complex/to_s_spec.rb b/spec/ruby/core/complex/to_s_spec.rb
index c398bb000e..989a7ae0b7 100644
--- a/spec/ruby/core/complex/to_s_spec.rb
+++ b/spec/ruby/core/complex/to_s_spec.rb
@@ -1,5 +1,44 @@
-require File.expand_path('../../../shared/complex/to_s', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#to_s" do
- it_behaves_like(:complex_to_s, :to_s)
+ describe "when self's real component is 0" do
+ it "returns both the real and imaginary component even when the real is 0" do
+ Complex(0, 5).to_s.should == "0+5i"
+ Complex(0, -3.2).to_s.should == "0-3.2i"
+ end
+ end
+
+ it "returns self as String" do
+ Complex(1, 5).to_s.should == "1+5i"
+ Complex(-2.5, 1.5).to_s.should == "-2.5+1.5i"
+
+ Complex(1, -5).to_s.should == "1-5i"
+ Complex(-2.5, -1.5).to_s.should == "-2.5-1.5i"
+
+ # Guard against the Mathn library
+ guard -> { !defined?(Math.rsqrt) } do
+ Complex(1, 0).to_s.should == "1+0i"
+ Complex(1, -0).to_s.should == "1+0i"
+ end
+ end
+
+ it "returns 1+0.0i for Complex(1, 0.0)" do
+ Complex(1, 0.0).to_s.should == "1+0.0i"
+ end
+
+ it "returns 1-0.0i for Complex(1, -0.0)" do
+ Complex(1, -0.0).to_s.should == "1-0.0i"
+ end
+
+ it "returns 1+Infinity*i for Complex(1, Infinity)" do
+ Complex(1, infinity_value).to_s.should == "1+Infinity*i"
+ end
+
+ it "returns 1-Infinity*i for Complex(1, -Infinity)" do
+ Complex(1, -infinity_value).to_s.should == "1-Infinity*i"
+ end
+
+ it "returns 1+NaN*i for Complex(1, NaN)" do
+ Complex(1, nan_value).to_s.should == "1+NaN*i"
+ end
end
diff --git a/spec/ruby/core/complex/uminus_spec.rb b/spec/ruby/core/complex/uminus_spec.rb
index 1bf56e770b..c0184e11de 100644
--- a/spec/ruby/core/complex/uminus_spec.rb
+++ b/spec/ruby/core/complex/uminus_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Complex#-@" do
it "sends #-@ to the real and imaginary parts and returns a Complex with the resulting respective parts" do
diff --git a/spec/ruby/core/data/constants_spec.rb b/spec/ruby/core/data/constants_spec.rb
new file mode 100644
index 0000000000..a037bf6816
--- /dev/null
+++ b/spec/ruby/core/data/constants_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ describe "Data" do
+ it "is a subclass of Object" do
+ suppress_warning do
+ Data.superclass.should == Object
+ end
+ end
+
+ it "is deprecated" do
+ -> { Data }.should complain(/constant ::Data is deprecated/)
+ end
+ end
+end
diff --git a/spec/ruby/core/dir/chdir_spec.rb b/spec/ruby/core/dir/chdir_spec.rb
index f5b0b80d1c..729ac403e3 100644
--- a/spec/ruby/core/dir/chdir_spec.rb
+++ b/spec/ruby/core/dir/chdir_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir.chdir" do
before :all do
@@ -88,19 +88,19 @@ describe "Dir.chdir" do
end
it "raises an Errno::ENOENT if the directory does not exist" do
- lambda { Dir.chdir DirSpecs.nonexistent }.should raise_error(Errno::ENOENT)
- lambda { Dir.chdir(DirSpecs.nonexistent) { } }.should raise_error(Errno::ENOENT)
+ -> { Dir.chdir DirSpecs.nonexistent }.should raise_error(Errno::ENOENT)
+ -> { Dir.chdir(DirSpecs.nonexistent) { } }.should raise_error(Errno::ENOENT)
end
it "raises an Errno::ENOENT if the original directory no longer exists" do
dir1 = tmp('/testdir1')
dir2 = tmp('/testdir2')
- File.exist?(dir1).should == false
- File.exist?(dir2).should == false
+ File.should_not.exist?(dir1)
+ File.should_not.exist?(dir2)
Dir.mkdir dir1
Dir.mkdir dir2
begin
- lambda {
+ -> {
Dir.chdir dir1 do
Dir.chdir(dir2) { Dir.unlink dir1 }
end
diff --git a/spec/ruby/core/dir/children_spec.rb b/spec/ruby/core/dir/children_spec.rb
new file mode 100644
index 0000000000..e0325a24b8
--- /dev/null
+++ b/spec/ruby/core/dir/children_spec.rb
@@ -0,0 +1,136 @@
+# encoding: utf-8
+
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+
+describe "Dir.children" do
+ before :all do
+ DirSpecs.create_mock_dirs
+ end
+
+ before :each do
+ @internal = Encoding.default_internal
+ end
+
+ after :all do
+ DirSpecs.delete_mock_dirs
+ end
+
+ after :each do
+ Encoding.default_internal = @internal
+ end
+
+ it "returns an Array of filenames in an existing directory including dotfiles" do
+ a = Dir.children(DirSpecs.mock_dir).sort
+
+ a.should == DirSpecs.expected_paths - %w[. ..]
+
+ a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested").sort
+ a.should == %w|.dotfile.ext directory|
+ end
+
+ it "calls #to_path on non-String arguments" do
+ p = mock('path')
+ p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
+ Dir.children(p)
+ end
+
+ it "accepts an options Hash" do
+ a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").sort
+ a.should == %w|.dotfile.ext directory|
+ end
+
+ it "returns children encoded with the filesystem encoding by default" do
+ # This spec depends on the locale not being US-ASCII because if it is, the
+ # children that are not ascii_only? will be BINARY encoded.
+ children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
+ encoding = Encoding.find("filesystem")
+ encoding = Encoding::BINARY if encoding == Encoding::US_ASCII
+ platform_is_not :windows do
+ children.should include("ã“ã‚“ã«ã¡ã¯.txt".force_encoding(encoding))
+ end
+ children.first.encoding.should equal(Encoding.find("filesystem"))
+ end
+
+ it "returns children encoded with the specified encoding" do
+ dir = File.join(DirSpecs.mock_dir, 'special')
+ children = Dir.children(dir, encoding: "euc-jp").sort
+ children.first.encoding.should equal(Encoding::EUC_JP)
+ end
+
+ it "returns children transcoded to the default internal encoding" do
+ Encoding.default_internal = Encoding::EUC_KR
+ children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
+ children.first.encoding.should equal(Encoding::EUC_KR)
+ end
+
+ it "raises a SystemCallError if called with a nonexistent directory" do
+ -> { Dir.children DirSpecs.nonexistent }.should raise_error(SystemCallError)
+ end
+end
+
+ruby_version_is "2.6" do
+ describe "Dir#children" do
+ before :all do
+ DirSpecs.create_mock_dirs
+ end
+
+ before :each do
+ @internal = Encoding.default_internal
+ end
+
+ after :all do
+ DirSpecs.delete_mock_dirs
+ end
+
+ after :each do
+ Encoding.default_internal = @internal
+ @dir.close if @dir
+ end
+
+ it "returns an Array of filenames in an existing directory including dotfiles" do
+ @dir = Dir.new(DirSpecs.mock_dir)
+ a = @dir.children.sort
+ @dir.close
+
+ a.should == DirSpecs.expected_paths - %w[. ..]
+
+ @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested")
+ a = @dir.children.sort
+ a.should == %w|.dotfile.ext directory|
+ end
+
+ it "accepts an options Hash" do
+ @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8")
+ a = @dir.children.sort
+ a.should == %w|.dotfile.ext directory|
+ end
+
+ it "returns children encoded with the filesystem encoding by default" do
+ # This spec depends on the locale not being US-ASCII because if it is, the
+ # children that are not ascii_only? will be BINARY encoded.
+ @dir = Dir.new(File.join(DirSpecs.mock_dir, 'special'))
+ children = @dir.children.sort
+ encoding = Encoding.find("filesystem")
+ encoding = Encoding::BINARY if encoding == Encoding::US_ASCII
+ platform_is_not :windows do
+ children.should include("ã“ã‚“ã«ã¡ã¯.txt".force_encoding(encoding))
+ end
+ children.first.encoding.should equal(Encoding.find("filesystem"))
+ end
+
+ it "returns children encoded with the specified encoding" do
+ path = File.join(DirSpecs.mock_dir, 'special')
+ @dir = Dir.new(path, encoding: "euc-jp")
+ children = @dir.children.sort
+ children.first.encoding.should equal(Encoding::EUC_JP)
+ end
+
+ it "returns children transcoded to the default internal encoding" do
+ Encoding.default_internal = Encoding::EUC_KR
+ @dir = Dir.new(File.join(DirSpecs.mock_dir, 'special'))
+ children = @dir.children.sort
+ children.first.encoding.should equal(Encoding::EUC_KR)
+ end
+ end
+end
diff --git a/spec/ruby/core/dir/chroot_spec.rb b/spec/ruby/core/dir/chroot_spec.rb
index 1afe254957..a5ca8943fc 100644
--- a/spec/ruby/core/dir/chroot_spec.rb
+++ b/spec/ruby/core/dir/chroot_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/chroot', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/chroot'
platform_is_not :windows do
as_superuser do
@@ -9,7 +9,7 @@ platform_is_not :windows do
end
end
- platform_is_not :cygwin do
+ platform_is_not :cygwin, :android do
as_user do
describe "Dir.chroot as regular user" do
before :all do
@@ -21,17 +21,17 @@ platform_is_not :windows do
end
it "raises an Errno::EPERM exception if the directory exists" do
- lambda { Dir.chroot('.') }.should raise_error(Errno::EPERM)
+ -> { Dir.chroot('.') }.should raise_error(Errno::EPERM)
end
it "raises a SystemCallError if the directory doesn't exist" do
- lambda { Dir.chroot('xgwhwhsjai2222jg') }.should raise_error(SystemCallError)
+ -> { Dir.chroot('xgwhwhsjai2222jg') }.should raise_error(SystemCallError)
end
it "calls #to_path on non-String argument" do
p = mock('path')
p.should_receive(:to_path).and_return('.')
- lambda { Dir.chroot(p) }.should raise_error
+ -> { Dir.chroot(p) }.should raise_error(Errno::EPERM)
end
end
end
diff --git a/spec/ruby/core/dir/close_spec.rb b/spec/ruby/core/dir/close_spec.rb
index 7b08ec5ee8..5fad5eecfb 100644
--- a/spec/ruby/core/dir/close_spec.rb
+++ b/spec/ruby/core/dir/close_spec.rb
@@ -1,9 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-ruby_version_is ''...'2.3' do
- require File.expand_path('../shared/closed', __FILE__)
-end
-
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir#close" do
before :all do
DirSpecs.create_mock_dirs
@@ -13,17 +9,11 @@ describe "Dir#close" do
DirSpecs.delete_mock_dirs
end
- ruby_version_is ''...'2.3' do
- it_behaves_like :dir_closed, :close
- end
-
- ruby_version_is '2.3' do
- it "does not raise an IOError even if the Dir instance is closed" do
- dir = Dir.open DirSpecs.mock_dir
+ it "does not raise an IOError even if the Dir instance is closed" do
+ dir = Dir.open DirSpecs.mock_dir
+ dir.close
+ -> {
dir.close
- lambda {
- dir.close
- }.should_not raise_error(IOError)
- end
+ }.should_not raise_error(IOError)
end
end
diff --git a/spec/ruby/core/dir/delete_spec.rb b/spec/ruby/core/dir/delete_spec.rb
index 5f36956839..a0020788ca 100644
--- a/spec/ruby/core/dir/delete_spec.rb
+++ b/spec/ruby/core/dir/delete_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/delete', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/delete'
describe "Dir.delete" do
before :all do
diff --git a/spec/ruby/core/dir/dir_spec.rb b/spec/ruby/core/dir/dir_spec.rb
index 4923445bed..7d55ea26d4 100644
--- a/spec/ruby/core/dir/dir_spec.rb
+++ b/spec/ruby/core/dir/dir_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Dir" do
it "includes Enumerable" do
diff --git a/spec/ruby/core/dir/each_child_spec.rb b/spec/ruby/core/dir/each_child_spec.rb
new file mode 100644
index 0000000000..93b4a1aec1
--- /dev/null
+++ b/spec/ruby/core/dir/each_child_spec.rb
@@ -0,0 +1,103 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+
+describe "Dir.each_child" do
+ before :all do
+ DirSpecs.create_mock_dirs
+ end
+
+ after :all do
+ DirSpecs.delete_mock_dirs
+ end
+
+ it "yields all names in an existing directory to the provided block" do
+ a, b = [], []
+
+ Dir.each_child(DirSpecs.mock_dir) {|f| a << f}
+ Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested") {|f| b << f}
+
+ a.sort.should == DirSpecs.expected_paths - %w[. ..]
+ b.sort.should == %w|.dotfile.ext directory|
+ end
+
+ it "returns nil when successful" do
+ Dir.each_child(DirSpecs.mock_dir) {|f| f}.should == nil
+ end
+
+ it "calls #to_path on non-String arguments" do
+ p = mock('path')
+ p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
+ Dir.each_child(p).to_a
+ end
+
+ it "raises a SystemCallError if passed a nonexistent directory" do
+ -> { Dir.each_child(DirSpecs.nonexistent) {} }.should raise_error(SystemCallError)
+ end
+
+ describe "when no block is given" do
+ it "returns an Enumerator" do
+ Dir.each_child(DirSpecs.mock_dir).should be_an_instance_of(Enumerator)
+ Dir.each_child(DirSpecs.mock_dir).to_a.sort.should == DirSpecs.expected_paths - %w[. ..]
+ end
+
+ describe "returned Enumerator" do
+ describe "size" do
+ it "should return nil" do
+ Dir.each_child(DirSpecs.mock_dir).size.should == nil
+ end
+ end
+ end
+ end
+end
+
+ruby_version_is "2.6" do
+ describe "Dir#each_child" do
+ before :all do
+ DirSpecs.create_mock_dirs
+ end
+
+ after :all do
+ DirSpecs.delete_mock_dirs
+ end
+
+ after :each do
+ @dir.close if @dir
+ end
+
+ it "yields all names in an existing directory to the provided block" do
+ a, b = [], []
+ @dir = Dir.new(DirSpecs.mock_dir)
+ @dir2 = Dir.new("#{DirSpecs.mock_dir}/deeply/nested")
+
+ @dir.each_child { |f| a << f }
+ @dir2.each_child { |f| b << f }
+ @dir2.close
+
+ a.sort.should == DirSpecs.expected_paths - %w|. ..|
+ b.sort.should == %w|.dotfile.ext directory|
+ end
+
+ it "returns self when successful" do
+ @dir = Dir.new(DirSpecs.mock_dir)
+ @dir.each_child { |f| f }.should == @dir
+ end
+
+ describe "when no block is given" do
+ it "returns an Enumerator" do
+ @dir = Dir.new(DirSpecs.mock_dir)
+
+ @dir.each_child.should be_an_instance_of(Enumerator)
+ @dir.each_child.to_a.sort.should == DirSpecs.expected_paths - %w|. ..|
+ end
+
+ describe "returned Enumerator" do
+ describe "size" do
+ it "should return nil" do
+ @dir = Dir.new(DirSpecs.mock_dir)
+ @dir.each_child.size.should == nil
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/dir/each_spec.rb b/spec/ruby/core/dir/each_spec.rb
index 534691ff58..8c69a7212b 100644
--- a/spec/ruby/core/dir/each_spec.rb
+++ b/spec/ruby/core/dir/each_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/closed', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/closed'
describe "Dir#each" do
before :all do
diff --git a/spec/ruby/core/dir/element_reference_spec.rb b/spec/ruby/core/dir/element_reference_spec.rb
index de379d75ac..092114bed4 100644
--- a/spec/ruby/core/dir/element_reference_spec.rb
+++ b/spec/ruby/core/dir/element_reference_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/glob', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/glob'
describe "Dir.[]" do
it_behaves_like :dir_glob, :[]
diff --git a/spec/ruby/core/dir/empty_spec.rb b/spec/ruby/core/dir/empty_spec.rb
new file mode 100644
index 0000000000..8cc8757798
--- /dev/null
+++ b/spec/ruby/core/dir/empty_spec.rb
@@ -0,0 +1,31 @@
+require_relative '../../spec_helper'
+
+describe "Dir.empty?" do
+ before :all do
+ @empty_dir = tmp("empty_dir")
+ mkdir_p @empty_dir
+ end
+
+ after :all do
+ rm_r @empty_dir
+ end
+
+ it "returns true for empty directories" do
+ result = Dir.empty? @empty_dir
+ result.should be_true
+ end
+
+ it "returns false for non-empty directories" do
+ result = Dir.empty? __dir__
+ result.should be_false
+ end
+
+ it "returns false for a non-directory" do
+ result = Dir.empty? __FILE__
+ result.should be_false
+ end
+
+ it "raises ENOENT for nonexistent directories" do
+ -> { Dir.empty? tmp("nonexistent") }.should raise_error(Errno::ENOENT)
+ end
+end
diff --git a/spec/ruby/core/dir/entries_spec.rb b/spec/ruby/core/dir/entries_spec.rb
index 8a31ab4b4a..33568b6fc4 100644
--- a/spec/ruby/core/dir/entries_spec.rb
+++ b/spec/ruby/core/dir/entries_spec.rb
@@ -1,7 +1,7 @@
# encoding: utf-8
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir.entries" do
before :all do
@@ -42,10 +42,10 @@ describe "Dir.entries" do
it "returns entries encoded with the filesystem encoding by default" do
# This spec depends on the locale not being US-ASCII because if it is, the
- # entries that are not ascii_only? will be ASCII-8BIT encoded.
+ # entries that are not ascii_only? will be BINARY encoded.
entries = Dir.entries(File.join(DirSpecs.mock_dir, 'special')).sort
encoding = Encoding.find("filesystem")
- encoding = Encoding::ASCII_8BIT if encoding == Encoding::US_ASCII
+ encoding = Encoding::BINARY if encoding == Encoding::US_ASCII
platform_is_not :windows do
entries.should include("ã“ã‚“ã«ã¡ã¯.txt".force_encoding(encoding))
end
@@ -64,7 +64,7 @@ describe "Dir.entries" do
entries.first.encoding.should equal(Encoding::EUC_KR)
end
- it "raises a SystemCallError if called with a nonexistent diretory" do
- lambda { Dir.entries DirSpecs.nonexistent }.should raise_error(SystemCallError)
+ it "raises a SystemCallError if called with a nonexistent directory" do
+ -> { Dir.entries DirSpecs.nonexistent }.should raise_error(SystemCallError)
end
end
diff --git a/spec/ruby/core/dir/exist_spec.rb b/spec/ruby/core/dir/exist_spec.rb
index 194284b5a0..43987b0f32 100644
--- a/spec/ruby/core/dir/exist_spec.rb
+++ b/spec/ruby/core/dir/exist_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/exist', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/exist'
describe "Dir.exist?" do
before :all do
@@ -11,5 +11,5 @@ describe "Dir.exist?" do
DirSpecs.delete_mock_dirs
end
- it_behaves_like(:dir_exist, :exist?)
+ it_behaves_like :dir_exist, :exist?
end
diff --git a/spec/ruby/core/dir/exists_spec.rb b/spec/ruby/core/dir/exists_spec.rb
deleted file mode 100644
index 002506a22f..0000000000
--- a/spec/ruby/core/dir/exists_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/exist', __FILE__)
-
-describe "Dir.exists?" do
- before :all do
- DirSpecs.create_mock_dirs
- end
-
- after :all do
- DirSpecs.delete_mock_dirs
- end
-
- it_behaves_like(:dir_exist, :exists?)
-end
diff --git a/spec/ruby/core/dir/fileno_spec.rb b/spec/ruby/core/dir/fileno_spec.rb
index cf8b811e3b..bb84ef5378 100644
--- a/spec/ruby/core/dir/fileno_spec.rb
+++ b/spec/ruby/core/dir/fileno_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
has_dir_fileno = begin
dir = Dir.new('.')
@@ -27,11 +27,11 @@ describe "Dir#fileno" do
if has_dir_fileno
it "returns the file descriptor of the dir" do
- @dir.fileno.should be_kind_of(Fixnum)
+ @dir.fileno.should be_kind_of(Integer)
end
else
it "raises an error when not implemented on the platform" do
- lambda { @dir.fileno }.should raise_error(NotImplementedError)
+ -> { @dir.fileno }.should raise_error(NotImplementedError)
end
end
end
diff --git a/spec/ruby/core/dir/fixtures/common.rb b/spec/ruby/core/dir/fixtures/common.rb
index f6708b04f7..71b1438b72 100644
--- a/spec/ruby/core/dir/fixtures/common.rb
+++ b/spec/ruby/core/dir/fixtures/common.rb
@@ -22,7 +22,7 @@ module DirSpecs
[0xe9].pack('U')
].each do |dir|
begin
- Dir.rmdir dir
+ Dir.rmdir mock_dir(dir)
rescue
end
end
@@ -36,6 +36,8 @@ module DirSpecs
.dotfile
.dotsubdir/.dotfile
.dotsubdir/nondotfile
+ nested/.dotsubir/.dotfile
+ nested/.dotsubir/nondotfile
deeply/.dotfile
deeply/nested/.dotfile.ext
@@ -160,6 +162,7 @@ module DirSpecs
dir_filename_ordering
file_one.ext
file_two.ext
+ nested
nondotfile
special
subdir_one
diff --git a/spec/ruby/core/dir/foreach_spec.rb b/spec/ruby/core/dir/foreach_spec.rb
index e606b4f65c..1560b85f8a 100644
--- a/spec/ruby/core/dir/foreach_spec.rb
+++ b/spec/ruby/core/dir/foreach_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir.foreach" do
before :all do
@@ -31,7 +31,7 @@ describe "Dir.foreach" do
end
it "raises a SystemCallError if passed a nonexistent directory" do
- lambda { Dir.foreach(DirSpecs.nonexistent) {} }.should raise_error(SystemCallError)
+ -> { Dir.foreach(DirSpecs.nonexistent) {} }.should raise_error(SystemCallError)
end
it "returns an Enumerator if no block given" do
diff --git a/spec/ruby/core/dir/getwd_spec.rb b/spec/ruby/core/dir/getwd_spec.rb
index 26659ddec7..132634347c 100644
--- a/spec/ruby/core/dir/getwd_spec.rb
+++ b/spec/ruby/core/dir/getwd_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/pwd', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/pwd'
describe "Dir.getwd" do
before :all do
diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb
index b65b738b61..9b6e2b2d3d 100644
--- a/spec/ruby/core/dir/glob_spec.rb
+++ b/spec/ruby/core/dir/glob_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/glob', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/glob'
describe "Dir.glob" do
it_behaves_like :dir_glob, :glob
@@ -59,6 +59,8 @@ describe "Dir.glob" do
deeply/nested/directory/
deeply/nested/directory/structure/
dir/
+ nested/
+ nested/.dotsubir/
special/
special/test{1}/
subdir_one/
@@ -68,7 +70,19 @@ describe "Dir.glob" do
Dir.glob('**/', File::FNM_DOTMATCH).sort.should == expected
end
- # This is a seperate case to check **/ coming after a constant
+ it "recursively matches files and directories in nested dot subdirectory with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do
+ expected = %w[
+ nested/.
+ nested/.dotsubir
+ nested/.dotsubir/.
+ nested/.dotsubir/.dotfile
+ nested/.dotsubir/nondotfile
+ ]
+
+ Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
+ end
+
+ # This is a separate case to check **/ coming after a constant
# directory as well.
it "recursively matches any subdirectories except './' or '../' with '**/' and option File::FNM_DOTMATCH" do
expected = %w[
@@ -80,6 +94,8 @@ describe "Dir.glob" do
./deeply/nested/directory/
./deeply/nested/directory/structure/
./dir/
+ ./nested/
+ ./nested/.dotsubir/
./special/
./special/test{1}/
./subdir_one/
@@ -119,7 +135,19 @@ describe "Dir.glob" do
end
it "handles infinite directory wildcards" do
- Dir.glob('**/**/**').empty?.should == false
+ Dir.glob('**/**/**').should_not.empty?
+ end
+
+ it "handles simple filename patterns" do
+ Dir.glob('.dotfile').should == ['.dotfile']
+ end
+
+ it "handles simple directory patterns" do
+ Dir.glob('.dotsubdir/').should == ['.dotsubdir/']
+ end
+
+ it "handles simple directory patterns applied to non-directories" do
+ Dir.glob('nondotfile/').should == []
end
platform_is_not(:windows) do
diff --git a/spec/ruby/core/dir/home_spec.rb b/spec/ruby/core/dir/home_spec.rb
index 6d99678034..713ba9db9a 100644
--- a/spec/ruby/core/dir/home_spec.rb
+++ b/spec/ruby/core/dir/home_spec.rb
@@ -1,26 +1,45 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir.home" do
- it "returns the current user's home directory as a string if called without arguments" do
- home_directory = ENV['HOME']
- platform_is :windows do
- unless home_directory
- home_directory = ENV['HOMEDRIVE'] + ENV['HOMEPATH']
- end
- home_directory = home_directory.tr('\\', '/').chomp('/')
+ before :each do
+ @home = ENV['HOME']
+ ENV['HOME'] = "/rubyspec_home"
+ end
+
+ after :each do
+ ENV['HOME'] = @home
+ end
+
+ describe "when called without arguments" do
+ it "returns the current user's home directory, reading $HOME first" do
+ Dir.home.should == "/rubyspec_home"
end
- Dir.home.should == home_directory
+ it "returns a non-frozen string" do
+ Dir.home.should_not.frozen?
+ end
end
- platform_is_not :windows do
- it "returns the named user's home directory as a string if called with an argument" do
- Dir.home(ENV['USER']).should == ENV['HOME']
+ describe "when called with the current user name" do
+ platform_is :solaris do
+ it "returns the named user's home directory from the user database" do
+ Dir.home(ENV['USER']).should == `getent passwd #{ENV['USER']}|cut -d: -f6`.chomp
+ end
+ end
+
+ platform_is_not :windows, :solaris, :android do
+ it "returns the named user's home directory, from the user database" do
+ Dir.home(ENV['USER']).should == `echo ~#{ENV['USER']}`.chomp
+ end
+ end
+
+ it "returns a non-frozen string" do
+ Dir.home(ENV['USER']).should_not.frozen?
end
end
it "raises an ArgumentError if the named user doesn't exist" do
- lambda { Dir.home('geuw2n288dh2k') }.should raise_error(ArgumentError)
+ -> { Dir.home('geuw2n288dh2k') }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/dir/initialize_spec.rb b/spec/ruby/core/dir/initialize_spec.rb
index b9420647d1..547b7dc18e 100644
--- a/spec/ruby/core/dir/initialize_spec.rb
+++ b/spec/ruby/core/dir/initialize_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir#initialize" do
before :each do
diff --git a/spec/ruby/core/dir/inspect_spec.rb b/spec/ruby/core/dir/inspect_spec.rb
index 01bde8a862..37338a97d4 100644
--- a/spec/ruby/core/dir/inspect_spec.rb
+++ b/spec/ruby/core/dir/inspect_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir#inspect" do
before :each do
diff --git a/spec/ruby/core/dir/mkdir_spec.rb b/spec/ruby/core/dir/mkdir_spec.rb
index 7eb8a8fe6c..0ed28f5a99 100644
--- a/spec/ruby/core/dir/mkdir_spec.rb
+++ b/spec/ruby/core/dir/mkdir_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Dir.mkdir" do
before :all do
@@ -13,29 +13,33 @@ describe "Dir.mkdir" do
it "creates the named directory with the given permissions" do
DirSpecs.clear_dirs
+ nonexisting = DirSpecs.mock_dir('nonexisting')
+ default_perms = DirSpecs.mock_dir('default_perms')
+ reduced = DirSpecs.mock_dir('reduced')
begin
- File.exist?('nonexisting').should == false
- Dir.mkdir 'nonexisting'
- File.exist?('nonexisting').should == true
+ File.should_not.exist?(nonexisting)
+ Dir.mkdir nonexisting
+ File.should.exist?(nonexisting)
platform_is_not :windows do
- Dir.mkdir 'default_perms'
- a = File.stat('default_perms').mode
- Dir.mkdir 'reduced', (a - 1)
- File.stat('reduced').mode.should_not == a
+ Dir.mkdir default_perms
+ a = File.stat(default_perms).mode
+ Dir.mkdir reduced, (a - 1)
+ File.stat(reduced).mode.should_not == a
end
platform_is :windows do
- Dir.mkdir 'default_perms', 0666
- a = File.stat('default_perms').mode
- Dir.mkdir 'reduced', 0444
- File.stat('reduced').mode.should_not == a
+ Dir.mkdir default_perms, 0666
+ a = File.stat(default_perms).mode
+ Dir.mkdir reduced, 0444
+ File.stat(reduced).mode.should_not == a
end
- Dir.mkdir('always_returns_0').should == 0
+ always_returns_0 = DirSpecs.mock_dir('always_returns_0')
+ Dir.mkdir(always_returns_0).should == 0
platform_is_not(:windows) do
- File.chmod(0777, "nonexisting","default_perms","reduced","always_returns_0")
+ File.chmod(0777, nonexisting, default_perms, reduced, always_returns_0)
end
platform_is_not(:windows) do
- File.chmod(0644, "nonexisting","default_perms","reduced","always_returns_0")
+ File.chmod(0644, nonexisting, default_perms, reduced, always_returns_0)
end
ensure
DirSpecs.clear_dirs
@@ -45,41 +49,43 @@ describe "Dir.mkdir" do
it "calls #to_path on non-String arguments" do
DirSpecs.clear_dirs
p = mock('path')
- p.should_receive(:to_path).and_return('nonexisting')
+ p.should_receive(:to_path).and_return(DirSpecs.mock_dir('nonexisting'))
Dir.mkdir(p)
DirSpecs.clear_dirs
end
it "raises a SystemCallError if any of the directories in the path before the last does not exist" do
- lambda { Dir.mkdir "#{DirSpecs.nonexistent}/subdir" }.should raise_error(SystemCallError)
+ -> { Dir.mkdir "#{DirSpecs.nonexistent}/subdir" }.should raise_error(SystemCallError)
end
it "raises Errno::EEXIST if the specified directory already exists" do
- lambda { Dir.mkdir("#{DirSpecs.mock_dir}/dir") }.should raise_error(Errno::EEXIST)
+ -> { Dir.mkdir("#{DirSpecs.mock_dir}/dir") }.should raise_error(Errno::EEXIST)
end
it "raises Errno::EEXIST if the argument points to the existing file" do
- lambda { Dir.mkdir("#{DirSpecs.mock_dir}/file_one.ext") }.should raise_error(Errno::EEXIST)
+ -> { Dir.mkdir("#{DirSpecs.mock_dir}/file_one.ext") }.should raise_error(Errno::EEXIST)
end
end
# The permissions flag are not supported on Windows as stated in documentation:
# The permissions may be modified by the value of File.umask, and are ignored on NT.
platform_is_not :windows do
- describe "Dir.mkdir" do
- before :each do
- @dir = tmp "noperms"
- end
+ as_user do
+ describe "Dir.mkdir" do
+ before :each do
+ @dir = tmp "noperms"
+ end
- after :each do
- File.chmod 0777, @dir
- rm_r @dir
- end
+ after :each do
+ File.chmod 0777, @dir
+ rm_r @dir
+ end
- it "raises a SystemCallError when lacking adequate permissions in the parent dir" do
- Dir.mkdir @dir, 0000
+ it "raises a SystemCallError when lacking adequate permissions in the parent dir" do
+ Dir.mkdir @dir, 0000
- lambda { Dir.mkdir "#{@dir}/subdir" }.should raise_error(SystemCallError)
+ -> { Dir.mkdir "#{@dir}/subdir" }.should raise_error(SystemCallError)
+ end
end
end
end
diff --git a/spec/ruby/core/dir/open_spec.rb b/spec/ruby/core/dir/open_spec.rb
index b3deed47b7..27f362320b 100644
--- a/spec/ruby/core/dir/open_spec.rb
+++ b/spec/ruby/core/dir/open_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/open', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/open'
describe "Dir.open" do
before :all do
diff --git a/spec/ruby/core/dir/path_spec.rb b/spec/ruby/core/dir/path_spec.rb
index 1601220636..b1c24c406b 100644
--- a/spec/ruby/core/dir/path_spec.rb
+++ b/spec/ruby/core/dir/path_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/path', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/path'
describe "Dir#path" do
before :all do
@@ -11,5 +11,5 @@ describe "Dir#path" do
DirSpecs.delete_mock_dirs
end
- it_behaves_like(:dir_path, :path)
+ it_behaves_like :dir_path, :path
end
diff --git a/spec/ruby/core/dir/pos_spec.rb b/spec/ruby/core/dir/pos_spec.rb
index 9f05fab250..b382bff81f 100644
--- a/spec/ruby/core/dir/pos_spec.rb
+++ b/spec/ruby/core/dir/pos_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/closed', __FILE__)
-require File.expand_path('../shared/pos', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/closed'
+require_relative 'shared/pos'
describe "Dir#pos" do
before :all do
diff --git a/spec/ruby/core/dir/pwd_spec.rb b/spec/ruby/core/dir/pwd_spec.rb
index 4fa86dd6b9..ad01286c90 100644
--- a/spec/ruby/core/dir/pwd_spec.rb
+++ b/spec/ruby/core/dir/pwd_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/pwd', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/pwd'
describe "Dir.pwd" do
before :all do
diff --git a/spec/ruby/core/dir/read_spec.rb b/spec/ruby/core/dir/read_spec.rb
index 79ed9b8058..59de2e81cf 100644
--- a/spec/ruby/core/dir/read_spec.rb
+++ b/spec/ruby/core/dir/read_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/closed', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/closed'
describe "Dir#read" do
before :all do
diff --git a/spec/ruby/core/dir/rewind_spec.rb b/spec/ruby/core/dir/rewind_spec.rb
index 65ffcdf1c3..220d7f5372 100644
--- a/spec/ruby/core/dir/rewind_spec.rb
+++ b/spec/ruby/core/dir/rewind_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/closed', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/closed'
describe "Dir#rewind" do
before :all do
diff --git a/spec/ruby/core/dir/rmdir_spec.rb b/spec/ruby/core/dir/rmdir_spec.rb
index 09499572c0..08cd1a5bc6 100644
--- a/spec/ruby/core/dir/rmdir_spec.rb
+++ b/spec/ruby/core/dir/rmdir_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/delete', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/delete'
describe "Dir.rmdir" do
before :all do
diff --git a/spec/ruby/core/dir/seek_spec.rb b/spec/ruby/core/dir/seek_spec.rb
index b51e554441..ed409897cd 100644
--- a/spec/ruby/core/dir/seek_spec.rb
+++ b/spec/ruby/core/dir/seek_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/pos', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/pos'
describe "Dir#seek" do
before :all do
diff --git a/spec/ruby/core/dir/shared/chroot.rb b/spec/ruby/core/dir/shared/chroot.rb
index 2ed033dfed..b14a433670 100644
--- a/spec/ruby/core/dir/shared/chroot.rb
+++ b/spec/ruby/core/dir/shared/chroot.rb
@@ -15,8 +15,8 @@ describe :dir_chroot_as_root, shared: true do
end
it "can be used to change the process' root directory" do
- lambda { Dir.send(@method, File.dirname(__FILE__)) }.should_not raise_error
- File.exist?("/#{File.basename(__FILE__)}").should be_true
+ -> { Dir.send(@method, File.dirname(__FILE__)) }.should_not raise_error
+ File.should.exist?("/#{File.basename(__FILE__)}")
end
it "returns 0 if successful" do
@@ -24,13 +24,13 @@ describe :dir_chroot_as_root, shared: true do
end
it "raises an Errno::ENOENT exception if the directory doesn't exist" do
- lambda { Dir.send(@method, 'xgwhwhsjai2222jg') }.should raise_error(Errno::ENOENT)
+ -> { Dir.send(@method, 'xgwhwhsjai2222jg') }.should raise_error(Errno::ENOENT)
end
it "can be escaped from with ../" do
Dir.send(@method, @real_root)
- File.exist?(@ref_dir).should be_true
- File.exist?("/#{File.basename(__FILE__)}").should be_false
+ File.should.exist?(@ref_dir)
+ File.should_not.exist?("/#{File.basename(__FILE__)}")
end
it "calls #to_path on non-String argument" do
diff --git a/spec/ruby/core/dir/shared/closed.rb b/spec/ruby/core/dir/shared/closed.rb
index a1bce06a08..17d8332c2a 100644
--- a/spec/ruby/core/dir/shared/closed.rb
+++ b/spec/ruby/core/dir/shared/closed.rb
@@ -1,6 +1,6 @@
describe :dir_closed, shared: true do
it "raises an IOError when called on a closed Dir instance" do
- lambda {
+ -> {
dir = Dir.open DirSpecs.mock_dir
dir.close
dir.send(@method) {}
diff --git a/spec/ruby/core/dir/shared/delete.rb b/spec/ruby/core/dir/shared/delete.rb
index 8db17d985f..49e88360e8 100644
--- a/spec/ruby/core/dir/shared/delete.rb
+++ b/spec/ruby/core/dir/shared/delete.rb
@@ -19,7 +19,7 @@ describe :dir_delete, shared: true do
platform_is_not :solaris do
it "raises an Errno::ENOTEMPTY when trying to remove a nonempty directory" do
- lambda do
+ -> do
Dir.send @method, DirSpecs.mock_rmdir("nonempty")
end.should raise_error(Errno::ENOTEMPTY)
end
@@ -27,14 +27,14 @@ describe :dir_delete, shared: true do
platform_is :solaris do
it "raises an Errno::EEXIST when trying to remove a nonempty directory" do
- lambda do
+ -> do
Dir.send @method, DirSpecs.mock_rmdir("nonempty")
end.should raise_error(Errno::EEXIST)
end
end
it "raises an Errno::ENOENT when trying to remove a non-existing directory" do
- lambda do
+ -> do
Dir.send @method, DirSpecs.nonexistent
end.should raise_error(Errno::ENOENT)
end
@@ -42,20 +42,22 @@ describe :dir_delete, shared: true do
it "raises an Errno::ENOTDIR when trying to remove a non-directory" do
file = DirSpecs.mock_rmdir("nonempty/regular")
touch(file)
- lambda do
+ -> do
Dir.send @method, file
end.should raise_error(Errno::ENOTDIR)
end
# this won't work on Windows, since chmod(0000) does not remove all permissions
platform_is_not :windows do
- it "raises an Errno::EACCES if lacking adequate permissions to remove the directory" do
- parent = DirSpecs.mock_rmdir("noperm")
- child = DirSpecs.mock_rmdir("noperm", "child")
- File.chmod(0000, parent)
- lambda do
- Dir.send @method, child
- end.should raise_error(Errno::EACCES)
+ as_user do
+ it "raises an Errno::EACCES if lacking adequate permissions to remove the directory" do
+ parent = DirSpecs.mock_rmdir("noperm")
+ child = DirSpecs.mock_rmdir("noperm", "child")
+ File.chmod(0000, parent)
+ -> do
+ Dir.send @method, child
+ end.should raise_error(Errno::EACCES)
+ end
end
end
end
diff --git a/spec/ruby/core/dir/shared/exist.rb b/spec/ruby/core/dir/shared/exist.rb
index fbd2c9862d..765d1b656c 100644
--- a/spec/ruby/core/dir/shared/exist.rb
+++ b/spec/ruby/core/dir/shared/exist.rb
@@ -39,7 +39,7 @@ describe :dir_exist, shared: true do
end
it "returns false if the argument exists but is a file" do
- File.exist?(__FILE__).should be_true
+ File.should.exist?(__FILE__)
Dir.send(@method, __FILE__).should be_false
end
diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb
index d2201cd6cd..f6d41ba209 100644
--- a/spec/ruby/core/dir/shared/glob.rb
+++ b/spec/ruby/core/dir/shared/glob.rb
@@ -11,11 +11,9 @@ describe :dir_glob, shared: true do
DirSpecs.delete_mock_dirs
end
- with_feature :encoding do
- it "raises an Encoding::CompatibilityError if the argument encoding is not compatible with US-ASCII" do
- pattern = "file*".force_encoding Encoding::UTF_16BE
- lambda { Dir.send(@method, pattern) }.should raise_error(Encoding::CompatibilityError)
- end
+ it "raises an Encoding::CompatibilityError if the argument encoding is not compatible with US-ASCII" do
+ pattern = "file*".force_encoding Encoding::UTF_16BE
+ -> { Dir.send(@method, pattern) }.should raise_error(Encoding::CompatibilityError)
end
it "calls #to_path to convert a pattern" do
@@ -25,9 +23,26 @@ describe :dir_glob, shared: true do
Dir.send(@method, obj).should == %w[file_one.ext]
end
- it "splits the string on \\0 if there is only one string given" do
- Dir.send(@method, "file_o*\0file_t*").should ==
- %w!file_one.ext file_two.ext!
+ ruby_version_is ""..."2.6" do
+ it "splits the string on \\0 if there is only one string given" do
+ Dir.send(@method, "file_o*\0file_t*").should ==
+ %w!file_one.ext file_two.ext!
+ end
+ end
+
+ ruby_version_is "2.6"..."2.7" do
+ it "splits the string on \\0 if there is only one string given and warns" do
+ -> {
+ Dir.send(@method, "file_o*\0file_t*").should ==
+ %w!file_one.ext file_two.ext!
+ }.should complain(/warning: use glob patterns list instead of nul-separated patterns/)
+ end
+ end
+
+ ruby_version_is "2.7" do
+ it "raises an ArgumentError if the string contains \\0" do
+ -> {Dir.send(@method, "file_o*\0file_t*")}.should raise_error ArgumentError, /nul-separated/
+ end
end
it "matches non-dotfiles with '*'" do
@@ -38,6 +53,7 @@ describe :dir_glob, shared: true do
dir_filename_ordering
file_one.ext
file_two.ext
+ nested
nondotfile
special
subdir_one
@@ -141,6 +157,7 @@ describe :dir_glob, shared: true do
dir_filename_ordering
file_one.ext
file_two.ext
+ nested
nondotfile
special
subdir_one
@@ -162,6 +179,7 @@ describe :dir_glob, shared: true do
deeply/nested/directory/
deeply/nested/directory/structure/
dir/
+ nested/
special/
special/test{1}/
subdir_one/
@@ -262,11 +280,11 @@ describe :dir_glob, shared: true do
subdir_two/nondotfile.ext]
end
- it "ignores matching through directories that doen't exist" do
+ it "ignores matching through directories that doesn't exist" do
Dir.send(@method, "deeply/notthere/blah*/whatever").should == []
end
- it "ignores matching only directories under an nonexistant path" do
+ it "ignores matching only directories under an nonexistent path" do
Dir.send(@method, "deeply/notthere/blah/").should == []
end
@@ -275,6 +293,76 @@ describe :dir_glob, shared: true do
Dir.send(@method, "special/ã“ã‚“ã«ã¡ã¯{,.txt}").should == ["special/ã“ã‚“ã«ã¡ã¯.txt"]
end
end
+
+ context ":base option passed" do
+ before :each do
+ @mock_dir = File.expand_path tmp('dir_glob_mock')
+
+ %w[
+ a/b/x
+ a/b/c/y
+ a/b/c/d/z
+ ].each do |path|
+ file = File.join @mock_dir, path
+ mkdir_p File.dirname(file)
+ touch file
+ end
+ end
+
+ after :each do
+ rm_r @mock_dir
+ end
+
+ it "matches entries only from within the specified directory" do
+ path = File.join(@mock_dir, "a/b/c")
+ Dir.send(@method, "*", base: path).sort.should == %w( d y )
+ end
+
+ it "accepts both relative and absolute paths" do
+ require 'pathname'
+
+ path_abs = File.join(@mock_dir, "a/b/c")
+ path_rel = Pathname.new(path_abs).relative_path_from(Pathname.new(Dir.pwd))
+
+ result_abs = Dir.send(@method, "*", base: path_abs).sort
+ result_rel = Dir.send(@method, "*", base: path_rel).sort
+
+ result_abs.should == %w( d y )
+ result_rel.should == %w( d y )
+ end
+
+ it "returns [] if specified path does not exist" do
+ path = File.join(@mock_dir, "fake-name")
+ File.should_not.exist?(path)
+
+ Dir.send(@method, "*", base: path).should == []
+ end
+
+ it "returns [] if specified path is a file" do
+ path = File.join(@mock_dir, "a/b/x")
+ File.should.exist?(path)
+
+ Dir.send(@method, "*", base: path).should == []
+ end
+
+ it "raises TypeError when cannot convert value to string" do
+ -> {
+ Dir.send(@method, "*", base: [])
+ }.should raise_error(TypeError)
+ end
+
+ it "handles '' as current directory path" do
+ Dir.chdir @mock_dir do
+ Dir.send(@method, "*", base: "").should == %w( a )
+ end
+ end
+
+ it "handles nil as current directory path" do
+ Dir.chdir @mock_dir do
+ Dir.send(@method, "*", base: nil).should == %w( a )
+ end
+ end
+ end
end
describe :dir_glob_recursive, shared: true do
diff --git a/spec/ruby/core/dir/shared/open.rb b/spec/ruby/core/dir/shared/open.rb
index 3c2b63b6fa..920845cba1 100644
--- a/spec/ruby/core/dir/shared/open.rb
+++ b/spec/ruby/core/dir/shared/open.rb
@@ -6,7 +6,7 @@ describe :dir_open, shared: true do
end
it "raises a SystemCallError if the directory does not exist" do
- lambda do
+ -> do
Dir.send @method, DirSpecs.nonexistent
end.should raise_error(SystemCallError)
end
@@ -21,20 +21,20 @@ describe :dir_open, shared: true do
it "closes the Dir instance when the block exits if given a block" do
closed_dir = Dir.send(@method, DirSpecs.mock_dir) { |dir| dir }
- lambda { closed_dir.read }.should raise_error(IOError)
+ -> { closed_dir.read }.should raise_error(IOError)
end
it "closes the Dir instance when the block exits the block even due to an exception" do
closed_dir = nil
- lambda do
+ -> do
Dir.send(@method, DirSpecs.mock_dir) do |dir|
closed_dir = dir
- raise
+ raise "dir specs"
end
- end.should raise_error
+ end.should raise_error(RuntimeError, "dir specs")
- lambda { closed_dir.read }.should raise_error(IOError)
+ -> { closed_dir.read }.should raise_error(IOError)
end
it "calls #to_path on non-String arguments" do
@@ -52,7 +52,7 @@ describe :dir_open, shared: true do
options = mock("dir_open")
options.should_receive(:to_hash).and_return({ encoding: Encoding::UTF_8 })
- dir = Dir.send(@method, DirSpecs.mock_dir, options) {|d| d }
+ dir = Dir.send(@method, DirSpecs.mock_dir, **options) {|d| d }
dir.should be_kind_of(Dir)
end
@@ -60,4 +60,14 @@ describe :dir_open, shared: true do
dir = Dir.send(@method, DirSpecs.mock_dir, encoding: nil) {|d| d }
dir.should be_kind_of(Dir)
end
+
+ platform_is_not :windows do
+ it 'sets the close-on-exec flag for the directory file descriptor' do
+ Dir.send(@method, DirSpecs.mock_dir) do |dir|
+ io = IO.for_fd(dir.fileno)
+ io.autoclose = false
+ io.should.close_on_exec?
+ end
+ end
+ end
end
diff --git a/spec/ruby/core/dir/shared/path.rb b/spec/ruby/core/dir/shared/path.rb
index 829eeb04c2..494dcca775 100644
--- a/spec/ruby/core/dir/shared/path.rb
+++ b/spec/ruby/core/dir/shared/path.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/common', __FILE__)
-require File.expand_path('../closed', __FILE__)
+require_relative '../../../spec_helper'
+require_relative '../fixtures/common'
+require_relative 'closed'
describe :dir_path, shared: true do
it "returns the path that was supplied to .new or .open" do
@@ -18,15 +18,13 @@ describe :dir_path, shared: true do
dir.send(@method).should == DirSpecs.mock_dir
end
- with_feature :encoding do
- it "returns a String with the same encoding as the argument to .open" do
- path = DirSpecs.mock_dir.force_encoding Encoding::IBM866
- dir = Dir.open path
- begin
- dir.send(@method).encoding.should equal(Encoding::IBM866)
- ensure
- dir.close
- end
+ it "returns a String with the same encoding as the argument to .open" do
+ path = DirSpecs.mock_dir.force_encoding Encoding::IBM866
+ dir = Dir.open path
+ begin
+ dir.send(@method).encoding.should equal(Encoding::IBM866)
+ ensure
+ dir.close
end
end
end
diff --git a/spec/ruby/core/dir/shared/pwd.rb b/spec/ruby/core/dir/shared/pwd.rb
index 5f041a9d41..2a8d7fe790 100644
--- a/spec/ruby/core/dir/shared/pwd.rb
+++ b/spec/ruby/core/dir/shared/pwd.rb
@@ -1,8 +1,6 @@
describe :dir_pwd, shared: true do
- with_feature :encoding do
- before :each do
- @fs_encoding = Encoding.find('filesystem')
- end
+ before :each do
+ @fs_encoding = Encoding.find('filesystem')
end
it "returns the current working directory" do
@@ -36,14 +34,12 @@ describe :dir_pwd, shared: true do
end
end
- with_feature :encoding do
- it "returns a String with the filesystem encoding" do
- enc = Dir.send(@method).encoding
- if @fs_encoding == Encoding::US_ASCII
- [Encoding::US_ASCII, Encoding::ASCII_8BIT].should include(enc)
- else
- enc.should equal(@fs_encoding)
- end
+ it "returns a String with the filesystem encoding" do
+ enc = Dir.send(@method).encoding
+ if @fs_encoding == Encoding::US_ASCII
+ [Encoding::US_ASCII, Encoding::BINARY].should include(enc)
+ else
+ enc.should equal(@fs_encoding)
end
end
end
diff --git a/spec/ruby/core/dir/tell_spec.rb b/spec/ruby/core/dir/tell_spec.rb
index fb9848153d..af86dc1598 100644
--- a/spec/ruby/core/dir/tell_spec.rb
+++ b/spec/ruby/core/dir/tell_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/closed', __FILE__)
-require File.expand_path('../shared/pos', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/closed'
+require_relative 'shared/pos'
describe "Dir#tell" do
before :all do
diff --git a/spec/ruby/core/dir/to_path_spec.rb b/spec/ruby/core/dir/to_path_spec.rb
index 85609fbfff..77404a3dc8 100644
--- a/spec/ruby/core/dir/to_path_spec.rb
+++ b/spec/ruby/core/dir/to_path_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/path', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/path'
describe "Dir#to_path" do
before :all do
@@ -11,5 +11,5 @@ describe "Dir#to_path" do
DirSpecs.delete_mock_dirs
end
- it_behaves_like(:dir_path, :to_path)
+ it_behaves_like :dir_path, :to_path
end
diff --git a/spec/ruby/core/dir/unlink_spec.rb b/spec/ruby/core/dir/unlink_spec.rb
index 4459bef56c..79027e020c 100644
--- a/spec/ruby/core/dir/unlink_spec.rb
+++ b/spec/ruby/core/dir/unlink_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/delete', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/delete'
describe "Dir.unlink" do
before :all do
diff --git a/spec/ruby/core/encoding/_dump_spec.rb b/spec/ruby/core/encoding/_dump_spec.rb
index 4e8305712e..623fe88ec9 100644
--- a/spec/ruby/core/encoding/_dump_spec.rb
+++ b/spec/ruby/core/encoding/_dump_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Encoding#_dump" do
it "needs to be reviewed for spec completeness"
diff --git a/spec/ruby/core/encoding/_load_spec.rb b/spec/ruby/core/encoding/_load_spec.rb
index b8cdbaa32b..608098d34b 100644
--- a/spec/ruby/core/encoding/_load_spec.rb
+++ b/spec/ruby/core/encoding/_load_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Encoding._load" do
it "needs to be reviewed for spec completeness"
diff --git a/spec/ruby/core/encoding/aliases_spec.rb b/spec/ruby/core/encoding/aliases_spec.rb
index 327c8fa641..786157981a 100644
--- a/spec/ruby/core/encoding/aliases_spec.rb
+++ b/spec/ruby/core/encoding/aliases_spec.rb
@@ -1,45 +1,43 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding.aliases" do
- it "returns a Hash" do
- Encoding.aliases.should be_an_instance_of(Hash)
- end
+describe "Encoding.aliases" do
+ it "returns a Hash" do
+ Encoding.aliases.should be_an_instance_of(Hash)
+ end
- it "has Strings as keys" do
- Encoding.aliases.keys.each do |key|
- key.should be_an_instance_of(String)
- end
+ it "has Strings as keys" do
+ Encoding.aliases.keys.each do |key|
+ key.should be_an_instance_of(String)
end
+ end
- it "has Strings as values" do
- Encoding.aliases.values.each do |value|
- value.should be_an_instance_of(String)
- end
+ it "has Strings as values" do
+ Encoding.aliases.values.each do |value|
+ value.should be_an_instance_of(String)
end
+ end
- it "has alias names as its keys" do
- Encoding.aliases.key?('BINARY').should be_true
- Encoding.aliases.key?('ASCII').should be_true
- end
+ it "has alias names as its keys" do
+ Encoding.aliases.key?('BINARY').should be_true
+ Encoding.aliases.key?('ASCII').should be_true
+ end
- it "has the names of the aliased encoding as its values" do
- Encoding.aliases['BINARY'].should == 'ASCII-8BIT'
- Encoding.aliases['ASCII'].should == 'US-ASCII'
- end
+ it "has the names of the aliased encoding as its values" do
+ Encoding.aliases['BINARY'].should == 'ASCII-8BIT'
+ Encoding.aliases['ASCII'].should == 'US-ASCII'
+ end
- it "has an 'external' key with the external default encoding as its value" do
- Encoding.aliases['external'].should == Encoding.default_external.name
- end
+ it "has an 'external' key with the external default encoding as its value" do
+ Encoding.aliases['external'].should == Encoding.default_external.name
+ end
- it "has a 'locale' key and its value equals to the name of the encoding finded by the locale charmap" do
- Encoding.aliases['locale'].should == Encoding.find(Encoding.locale_charmap).name
- end
+ it "has a 'locale' key and its value equals the name of the encoding found by the locale charmap" do
+ Encoding.aliases['locale'].should == Encoding.find(Encoding.locale_charmap).name
+ end
- it "only contains valid aliased encodings" do
- Encoding.aliases.each do |aliased, original|
- Encoding.find(aliased).should == Encoding.find(original)
- end
+ it "only contains valid aliased encodings" do
+ Encoding.aliases.each do |aliased, original|
+ Encoding.find(aliased).should == Encoding.find(original)
end
end
end
diff --git a/spec/ruby/core/encoding/ascii_compatible_spec.rb b/spec/ruby/core/encoding/ascii_compatible_spec.rb
index db3c31c9fb..4804300e85 100644
--- a/spec/ruby/core/encoding/ascii_compatible_spec.rb
+++ b/spec/ruby/core/encoding/ascii_compatible_spec.rb
@@ -1,13 +1,11 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding#ascii_compatible?" do
- it "returns true if self represents an ASCII-compatible encoding" do
- Encoding::UTF_8.ascii_compatible?.should be_true
- end
+describe "Encoding#ascii_compatible?" do
+ it "returns true if self represents an ASCII-compatible encoding" do
+ Encoding::UTF_8.ascii_compatible?.should be_true
+ end
- it "returns false if self does not represent an ASCII-compatible encoding" do
- Encoding::UTF_16LE.ascii_compatible?.should be_false
- end
+ it "returns false if self does not represent an ASCII-compatible encoding" do
+ Encoding::UTF_16LE.ascii_compatible?.should be_false
end
end
diff --git a/spec/ruby/core/encoding/compatible_spec.rb b/spec/ruby/core/encoding/compatible_spec.rb
index 55e3d0fb4d..dc47a6553a 100644
--- a/spec/ruby/core/encoding/compatible_spec.rb
+++ b/spec/ruby/core/encoding/compatible_spec.rb
@@ -1,381 +1,379 @@
-# -*- encoding: ascii-8bit -*-
+# -*- encoding: binary -*-
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- # TODO: add IO
+# TODO: add IO
- describe "Encoding.compatible? String, String" do
- describe "when the first's Encoding is valid US-ASCII" do
- before :each do
- @str = "abc".force_encoding Encoding::US_ASCII
- end
-
- it "returns US-ASCII when the second's is US-ASCII" do
- Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::US_ASCII
- end
-
- it "returns US-ASCII if the second String is ASCII-8BIT and ASCII only" do
- Encoding.compatible?(@str, "\x7f").should == Encoding::US_ASCII
- end
+describe "Encoding.compatible? String, String" do
+ describe "when the first's Encoding is valid US-ASCII" do
+ before :each do
+ @str = "abc".force_encoding Encoding::US_ASCII
+ end
- it "returns ASCII-8BIT if the second String is ASCII-8BIT but not ASCII only" do
- Encoding.compatible?(@str, "\xff").should == Encoding::ASCII_8BIT
- end
+ it "returns US-ASCII when the second's is US-ASCII" do
+ Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::US_ASCII
+ end
- it "returns US-ASCII if the second String is UTF-8 and ASCII only" do
- Encoding.compatible?(@str, "\x7f".encode("utf-8")).should == Encoding::US_ASCII
- end
+ it "returns US-ASCII if the second String is BINARY and ASCII only" do
+ Encoding.compatible?(@str, "\x7f").should == Encoding::US_ASCII
+ end
- it "returns UTF-8 if the second String is UTF-8 but not ASCII only" do
- Encoding.compatible?(@str, "\u3042".encode("utf-8")).should == Encoding::UTF_8
- end
+ it "returns BINARY if the second String is BINARY but not ASCII only" do
+ Encoding.compatible?(@str, "\xff").should == Encoding::BINARY
end
- describe "when the first's Encoding is ASCII compatible and ASCII only" do
- it "returns the first's Encoding if the second is ASCII compatible and ASCII only" do
- [ [Encoding, "abc".force_encoding("UTF-8"), "123".force_encoding("Shift_JIS"), Encoding::UTF_8],
- [Encoding, "123".force_encoding("Shift_JIS"), "abc".force_encoding("UTF-8"), Encoding::Shift_JIS]
- ].should be_computed_by(:compatible?)
- end
+ it "returns US-ASCII if the second String is UTF-8 and ASCII only" do
+ Encoding.compatible?(@str, "\x7f".encode("utf-8")).should == Encoding::US_ASCII
+ end
- it "returns the first's Encoding if the second is ASCII compatible and ASCII only" do
- [ [Encoding, "abc".force_encoding("ASCII-8BIT"), "123".force_encoding("US-ASCII"), Encoding::ASCII_8BIT],
- [Encoding, "123".force_encoding("US-ASCII"), "abc".force_encoding("ASCII-8BIT"), Encoding::US_ASCII]
- ].should be_computed_by(:compatible?)
- end
+ it "returns UTF-8 if the second String is UTF-8 but not ASCII only" do
+ Encoding.compatible?(@str, "\u3042".encode("utf-8")).should == Encoding::UTF_8
+ end
+ end
- it "returns the second's Encoding if the second is ASCII compatible but not ASCII only" do
- [ [Encoding, "abc".force_encoding("UTF-8"), "\xff".force_encoding("Shift_JIS"), Encoding::Shift_JIS],
- [Encoding, "123".force_encoding("Shift_JIS"), "\xff".force_encoding("UTF-8"), Encoding::UTF_8],
- [Encoding, "abc".force_encoding("ASCII-8BIT"), "\xff".force_encoding("US-ASCII"), Encoding::US_ASCII],
- [Encoding, "123".force_encoding("US-ASCII"), "\xff".force_encoding("ASCII-8BIT"), Encoding::ASCII_8BIT],
- ].should be_computed_by(:compatible?)
- end
+ describe "when the first's Encoding is ASCII compatible and ASCII only" do
+ it "returns the first's Encoding if the second is ASCII compatible and ASCII only" do
+ [ [Encoding, "abc".force_encoding("UTF-8"), "123".force_encoding("Shift_JIS"), Encoding::UTF_8],
+ [Encoding, "123".force_encoding("Shift_JIS"), "abc".force_encoding("UTF-8"), Encoding::Shift_JIS]
+ ].should be_computed_by(:compatible?)
+ end
- it "returns nil if the second's Encoding is not ASCII compatible" do
- a = "abc".force_encoding("UTF-8")
- b = "123".force_encoding("UTF-16LE")
- Encoding.compatible?(a, b).should be_nil
- end
+ it "returns the first's Encoding if the second is ASCII compatible and ASCII only" do
+ [ [Encoding, "abc".force_encoding("BINARY"), "123".force_encoding("US-ASCII"), Encoding::BINARY],
+ [Encoding, "123".force_encoding("US-ASCII"), "abc".force_encoding("BINARY"), Encoding::US_ASCII]
+ ].should be_computed_by(:compatible?)
end
- describe "when the first's Encoding is ASCII compatible but not ASCII only" do
- it "returns the first's Encoding if the second's is valid US-ASCII" do
- Encoding.compatible?("\xff", "def".encode("us-ascii")).should == Encoding::ASCII_8BIT
- end
+ it "returns the second's Encoding if the second is ASCII compatible but not ASCII only" do
+ [ [Encoding, "abc".force_encoding("UTF-8"), "\xff".force_encoding("Shift_JIS"), Encoding::Shift_JIS],
+ [Encoding, "123".force_encoding("Shift_JIS"), "\xff".force_encoding("UTF-8"), Encoding::UTF_8],
+ [Encoding, "abc".force_encoding("BINARY"), "\xff".force_encoding("US-ASCII"), Encoding::US_ASCII],
+ [Encoding, "123".force_encoding("US-ASCII"), "\xff".force_encoding("BINARY"), Encoding::BINARY],
+ ].should be_computed_by(:compatible?)
+ end
- it "returns the first's Encoding if the second's is UTF-8 and ASCII only" do
- Encoding.compatible?("\xff", "\u{7f}".encode("utf-8")).should == Encoding::ASCII_8BIT
- end
+ it "returns nil if the second's Encoding is not ASCII compatible" do
+ a = "abc".force_encoding("UTF-8")
+ b = "123".force_encoding("UTF-16LE")
+ Encoding.compatible?(a, b).should be_nil
+ end
+ end
- it "returns nil if the second encoding is ASCII compatible but neither String's encoding is ASCII only" do
- Encoding.compatible?("\xff", "\u3042".encode("utf-8")).should be_nil
- end
+ describe "when the first's Encoding is ASCII compatible but not ASCII only" do
+ it "returns the first's Encoding if the second's is valid US-ASCII" do
+ Encoding.compatible?("\xff", "def".encode("us-ascii")).should == Encoding::BINARY
end
- describe "when the first's Encoding is not ASCII compatible" do
- before :each do
- @str = "abc".force_encoding Encoding::UTF_7
- end
+ it "returns the first's Encoding if the second's is UTF-8 and ASCII only" do
+ Encoding.compatible?("\xff", "\u{7f}".encode("utf-8")).should == Encoding::BINARY
+ end
- it "returns nil when the second String is US-ASCII" do
- Encoding.compatible?(@str, "def".encode("us-ascii")).should be_nil
- end
+ it "returns nil if the second encoding is ASCII compatible but neither String's encoding is ASCII only" do
+ Encoding.compatible?("\xff", "\u3042".encode("utf-8")).should be_nil
+ end
+ end
- it "returns nil when the second String is ASCII-8BIT and ASCII only" do
- Encoding.compatible?(@str, "\x7f").should be_nil
- end
+ describe "when the first's Encoding is not ASCII compatible" do
+ before :each do
+ @str = "abc".force_encoding Encoding::UTF_7
+ end
- it "returns nil when the second String is ASCII-8BIT but not ASCII only" do
- Encoding.compatible?(@str, "\xff").should be_nil
- end
+ it "returns nil when the second String is US-ASCII" do
+ Encoding.compatible?(@str, "def".encode("us-ascii")).should be_nil
+ end
- it "returns the Encoding when the second's Encoding is not ASCII compatible but the same as the first's Encoding" do
- encoding = Encoding.compatible?(@str, "def".force_encoding("utf-7"))
- encoding.should == Encoding::UTF_7
- end
+ it "returns nil when the second String is BINARY and ASCII only" do
+ Encoding.compatible?(@str, "\x7f").should be_nil
end
- describe "when the first's Encoding is invalid" do
- before :each do
- @str = "\xff".force_encoding Encoding::UTF_8
- end
+ it "returns nil when the second String is BINARY but not ASCII only" do
+ Encoding.compatible?(@str, "\xff").should be_nil
+ end
- it "returns the first's Encoding when the second's Encoding is US-ASCII" do
- Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::UTF_8
- end
+ it "returns the Encoding when the second's Encoding is not ASCII compatible but the same as the first's Encoding" do
+ encoding = Encoding.compatible?(@str, "def".force_encoding("utf-7"))
+ encoding.should == Encoding::UTF_7
+ end
+ end
- it "returns the first's Encoding when the second String is ASCII only" do
- Encoding.compatible?(@str, "\x7f").should == Encoding::UTF_8
- end
+ describe "when the first's Encoding is invalid" do
+ before :each do
+ @str = "\xff".force_encoding Encoding::UTF_8
+ end
- it "returns nil when the second's Encoding is ASCII-8BIT but not ASCII only" do
- Encoding.compatible?(@str, "\xff").should be_nil
- end
+ it "returns the first's Encoding when the second's Encoding is US-ASCII" do
+ Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::UTF_8
+ end
- it "returns nil when the second's Encoding is invalid and ASCII only" do
- Encoding.compatible?(@str, "\x7f".force_encoding("utf-16be")).should be_nil
- end
+ it "returns the first's Encoding when the second String is ASCII only" do
+ Encoding.compatible?(@str, "\x7f").should == Encoding::UTF_8
+ end
- it "returns nil when the second's Encoding is invalid and not ASCII only" do
- Encoding.compatible?(@str, "\xff".force_encoding("utf-16be")).should be_nil
- end
+ it "returns nil when the second's Encoding is BINARY but not ASCII only" do
+ Encoding.compatible?(@str, "\xff").should be_nil
+ end
- it "returns the Encoding when the second's Encoding is invalid but the same as the first" do
- Encoding.compatible?(@str, @str).should == Encoding::UTF_8
- end
+ it "returns nil when the second's Encoding is invalid and ASCII only" do
+ Encoding.compatible?(@str, "\x7f".force_encoding("utf-16be")).should be_nil
end
- describe "when the first String is empty and the second is not" do
- describe "and the first's Encoding is ASCII compatible" do
- before :each do
- @str = "".force_encoding("utf-8")
- end
+ it "returns nil when the second's Encoding is invalid and not ASCII only" do
+ Encoding.compatible?(@str, "\xff".force_encoding("utf-16be")).should be_nil
+ end
- it "returns the first's encoding when the second String is ASCII only" do
- Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::UTF_8
- end
+ it "returns the Encoding when the second's Encoding is invalid but the same as the first" do
+ Encoding.compatible?(@str, @str).should == Encoding::UTF_8
+ end
+ end
- it "returns the second's encoding when the second String is not ASCII only" do
- Encoding.compatible?(@str, "def".encode("utf-32le")).should == Encoding::UTF_32LE
- end
+ describe "when the first String is empty and the second is not" do
+ describe "and the first's Encoding is ASCII compatible" do
+ before :each do
+ @str = "".force_encoding("utf-8")
end
- describe "when the first's Encoding is not ASCII compatible" do
- before :each do
- @str = "".force_encoding Encoding::UTF_7
- end
+ it "returns the first's encoding when the second String is ASCII only" do
+ Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::UTF_8
+ end
- it "returns the second string's encoding" do
- Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::US_ASCII
- end
+ it "returns the second's encoding when the second String is not ASCII only" do
+ Encoding.compatible?(@str, "def".encode("utf-32le")).should == Encoding::UTF_32LE
end
end
- describe "when the second String is empty" do
+ describe "when the first's Encoding is not ASCII compatible" do
before :each do
- @str = "abc".force_encoding("utf-7")
+ @str = "".force_encoding Encoding::UTF_7
end
- it "returns the first Encoding" do
- Encoding.compatible?(@str, "").should == Encoding::UTF_7
+ it "returns the second string's encoding" do
+ Encoding.compatible?(@str, "def".encode("us-ascii")).should == Encoding::US_ASCII
end
end
end
- describe "Encoding.compatible? String, Regexp" do
- it "returns US-ASCII if both are US-ASCII" do
- str = "abc".force_encoding("us-ascii")
- Encoding.compatible?(str, /abc/).should == Encoding::US_ASCII
+ describe "when the second String is empty" do
+ before :each do
+ @str = "abc".force_encoding("utf-7")
end
- it "returns the String's Encoding if it is not US-ASCII but both are ASCII only" do
- [ [Encoding, "abc", Encoding::ASCII_8BIT],
- [Encoding, "abc".encode("utf-8"), Encoding::UTF_8],
- [Encoding, "abc".encode("euc-jp"), Encoding::EUC_JP],
- [Encoding, "abc".encode("shift_jis"), Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, /abc/)
+ it "returns the first Encoding" do
+ Encoding.compatible?(@str, "").should == Encoding::UTF_7
end
+ end
+end
- it "returns the String's Encoding if the String is not ASCII only" do
- [ [Encoding, "\xff", Encoding::ASCII_8BIT],
- [Encoding, "\u3042".encode("utf-8"), Encoding::UTF_8],
- [Encoding, "\xa4\xa2".force_encoding("euc-jp"), Encoding::EUC_JP],
- [Encoding, "\x82\xa0".force_encoding("shift_jis"), Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, /abc/)
- end
+describe "Encoding.compatible? String, Regexp" do
+ it "returns US-ASCII if both are US-ASCII" do
+ str = "abc".force_encoding("us-ascii")
+ Encoding.compatible?(str, /abc/).should == Encoding::US_ASCII
end
- describe "Encoding.compatible? String, Symbol" do
- it "returns US-ASCII if both are ASCII only" do
- str = "abc".force_encoding("us-ascii")
- Encoding.compatible?(str, :abc).should == Encoding::US_ASCII
- end
+ it "returns the String's Encoding if it is not US-ASCII but both are ASCII only" do
+ [ [Encoding, "abc", Encoding::BINARY],
+ [Encoding, "abc".encode("utf-8"), Encoding::UTF_8],
+ [Encoding, "abc".encode("euc-jp"), Encoding::EUC_JP],
+ [Encoding, "abc".encode("shift_jis"), Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, /abc/)
+ end
- it "returns the String's Encoding if it is not US-ASCII but both are ASCII only" do
- [ [Encoding, "abc", Encoding::ASCII_8BIT],
- [Encoding, "abc".encode("utf-8"), Encoding::UTF_8],
- [Encoding, "abc".encode("euc-jp"), Encoding::EUC_JP],
- [Encoding, "abc".encode("shift_jis"), Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, :abc)
- end
+ it "returns the String's Encoding if the String is not ASCII only" do
+ [ [Encoding, "\xff", Encoding::BINARY],
+ [Encoding, "\u3042".encode("utf-8"), Encoding::UTF_8],
+ [Encoding, "\xa4\xa2".force_encoding("euc-jp"), Encoding::EUC_JP],
+ [Encoding, "\x82\xa0".force_encoding("shift_jis"), Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, /abc/)
+ end
+end
- it "returns the String's Encoding if the String is not ASCII only" do
- [ [Encoding, "\xff", Encoding::ASCII_8BIT],
- [Encoding, "\u3042".encode("utf-8"), Encoding::UTF_8],
- [Encoding, "\xa4\xa2".force_encoding("euc-jp"), Encoding::EUC_JP],
- [Encoding, "\x82\xa0".force_encoding("shift_jis"), Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, :abc)
- end
+describe "Encoding.compatible? String, Symbol" do
+ it "returns US-ASCII if both are ASCII only" do
+ str = "abc".force_encoding("us-ascii")
+ Encoding.compatible?(str, :abc).should == Encoding::US_ASCII
end
- describe "Encoding.compatible? String, Encoding" do
- it "returns nil if the String's encoding is not ASCII compatible" do
- Encoding.compatible?("abc".encode("utf-32le"), Encoding::US_ASCII).should be_nil
- end
+ it "returns the String's Encoding if it is not US-ASCII but both are ASCII only" do
+ [ [Encoding, "abc", Encoding::BINARY],
+ [Encoding, "abc".encode("utf-8"), Encoding::UTF_8],
+ [Encoding, "abc".encode("euc-jp"), Encoding::EUC_JP],
+ [Encoding, "abc".encode("shift_jis"), Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, :abc)
+ end
- it "returns nil if the Encoding is not ASCII compatible" do
- Encoding.compatible?("abc".encode("us-ascii"), Encoding::UTF_32LE).should be_nil
- end
+ it "returns the String's Encoding if the String is not ASCII only" do
+ [ [Encoding, "\xff", Encoding::BINARY],
+ [Encoding, "\u3042".encode("utf-8"), Encoding::UTF_8],
+ [Encoding, "\xa4\xa2".force_encoding("euc-jp"), Encoding::EUC_JP],
+ [Encoding, "\x82\xa0".force_encoding("shift_jis"), Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, :abc)
+ end
+end
- it "returns the String's encoding if the Encoding is US-ASCII" do
- [ [Encoding, "\xff", Encoding::ASCII_8BIT],
- [Encoding, "\u3042".encode("utf-8"), Encoding::UTF_8],
- [Encoding, "\xa4\xa2".force_encoding("euc-jp"), Encoding::EUC_JP],
- [Encoding, "\x82\xa0".force_encoding("shift_jis"), Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, Encoding::US_ASCII)
- end
+describe "Encoding.compatible? String, Encoding" do
+ it "returns nil if the String's encoding is not ASCII compatible" do
+ Encoding.compatible?("abc".encode("utf-32le"), Encoding::US_ASCII).should be_nil
+ end
- it "returns the Encoding if the String's encoding is ASCII compatible and the String is ASCII only" do
- str = "abc".encode("utf-8")
+ it "returns nil if the Encoding is not ASCII compatible" do
+ Encoding.compatible?("abc".encode("us-ascii"), Encoding::UTF_32LE).should be_nil
+ end
- Encoding.compatible?(str, Encoding::ASCII_8BIT).should == Encoding::ASCII_8BIT
- Encoding.compatible?(str, Encoding::UTF_8).should == Encoding::UTF_8
- Encoding.compatible?(str, Encoding::EUC_JP).should == Encoding::EUC_JP
- Encoding.compatible?(str, Encoding::Shift_JIS).should == Encoding::Shift_JIS
- end
+ it "returns the String's encoding if the Encoding is US-ASCII" do
+ [ [Encoding, "\xff", Encoding::BINARY],
+ [Encoding, "\u3042".encode("utf-8"), Encoding::UTF_8],
+ [Encoding, "\xa4\xa2".force_encoding("euc-jp"), Encoding::EUC_JP],
+ [Encoding, "\x82\xa0".force_encoding("shift_jis"), Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, Encoding::US_ASCII)
+ end
- it "returns nil if the String's encoding is ASCII compatible but the string is not ASCII only" do
- Encoding.compatible?("\u3042".encode("utf-8"), Encoding::ASCII_8BIT).should be_nil
- end
+ it "returns the Encoding if the String's encoding is ASCII compatible and the String is ASCII only" do
+ str = "abc".encode("utf-8")
+
+ Encoding.compatible?(str, Encoding::BINARY).should == Encoding::BINARY
+ Encoding.compatible?(str, Encoding::UTF_8).should == Encoding::UTF_8
+ Encoding.compatible?(str, Encoding::EUC_JP).should == Encoding::EUC_JP
+ Encoding.compatible?(str, Encoding::Shift_JIS).should == Encoding::Shift_JIS
end
- describe "Encoding.compatible? Regexp, String" do
- it "returns US-ASCII if both are US-ASCII" do
- str = "abc".force_encoding("us-ascii")
- Encoding.compatible?(/abc/, str).should == Encoding::US_ASCII
- end
+ it "returns nil if the String's encoding is ASCII compatible but the string is not ASCII only" do
+ Encoding.compatible?("\u3042".encode("utf-8"), Encoding::BINARY).should be_nil
+ end
+end
+describe "Encoding.compatible? Regexp, String" do
+ it "returns US-ASCII if both are US-ASCII" do
+ str = "abc".force_encoding("us-ascii")
+ Encoding.compatible?(/abc/, str).should == Encoding::US_ASCII
end
- describe "Encoding.compatible? Regexp, Regexp" do
- it "returns US-ASCII if both are US-ASCII" do
- Encoding.compatible?(/abc/, /def/).should == Encoding::US_ASCII
- end
+end
- it "returns the first's Encoding if it is not US-ASCII and not ASCII only" do
- [ [Encoding, Regexp.new("\xff"), Encoding::ASCII_8BIT],
- [Encoding, Regexp.new("\u3042".encode("utf-8")), Encoding::UTF_8],
- [Encoding, Regexp.new("\xa4\xa2".force_encoding("euc-jp")), Encoding::EUC_JP],
- [Encoding, Regexp.new("\x82\xa0".force_encoding("shift_jis")), Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, /abc/)
- end
+describe "Encoding.compatible? Regexp, Regexp" do
+ it "returns US-ASCII if both are US-ASCII" do
+ Encoding.compatible?(/abc/, /def/).should == Encoding::US_ASCII
end
- describe "Encoding.compatible? Regexp, Symbol" do
- it "returns US-ASCII if both are US-ASCII" do
- Encoding.compatible?(/abc/, :def).should == Encoding::US_ASCII
- end
+ it "returns the first's Encoding if it is not US-ASCII and not ASCII only" do
+ [ [Encoding, Regexp.new("\xff"), Encoding::BINARY],
+ [Encoding, Regexp.new("\u3042".encode("utf-8")), Encoding::UTF_8],
+ [Encoding, Regexp.new("\xa4\xa2".force_encoding("euc-jp")), Encoding::EUC_JP],
+ [Encoding, Regexp.new("\x82\xa0".force_encoding("shift_jis")), Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, /abc/)
+ end
+end
- it "returns the first's Encoding if it is not US-ASCII and not ASCII only" do
- [ [Encoding, Regexp.new("\xff"), Encoding::ASCII_8BIT],
- [Encoding, Regexp.new("\u3042".encode("utf-8")), Encoding::UTF_8],
- [Encoding, Regexp.new("\xa4\xa2".force_encoding("euc-jp")), Encoding::EUC_JP],
- [Encoding, Regexp.new("\x82\xa0".force_encoding("shift_jis")), Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, /abc/)
- end
+describe "Encoding.compatible? Regexp, Symbol" do
+ it "returns US-ASCII if both are US-ASCII" do
+ Encoding.compatible?(/abc/, :def).should == Encoding::US_ASCII
end
- describe "Encoding.compatible? Symbol, String" do
- it "returns US-ASCII if both are ASCII only" do
- str = "abc".force_encoding("us-ascii")
- Encoding.compatible?(str, :abc).should == Encoding::US_ASCII
- end
+ it "returns the first's Encoding if it is not US-ASCII and not ASCII only" do
+ [ [Encoding, Regexp.new("\xff"), Encoding::BINARY],
+ [Encoding, Regexp.new("\u3042".encode("utf-8")), Encoding::UTF_8],
+ [Encoding, Regexp.new("\xa4\xa2".force_encoding("euc-jp")), Encoding::EUC_JP],
+ [Encoding, Regexp.new("\x82\xa0".force_encoding("shift_jis")), Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, /abc/)
end
+end
- describe "Encoding.compatible? Symbol, Regexp" do
- it "returns US-ASCII if both are US-ASCII" do
- Encoding.compatible?(:abc, /def/).should == Encoding::US_ASCII
- end
+describe "Encoding.compatible? Symbol, String" do
+ it "returns US-ASCII if both are ASCII only" do
+ str = "abc".force_encoding("us-ascii")
+ Encoding.compatible?(str, :abc).should == Encoding::US_ASCII
+ end
+end
- it "returns the Regexp's Encoding if it is not US-ASCII and not ASCII only" do
- a = Regexp.new("\xff")
- b = Regexp.new("\u3042".encode("utf-8"))
- c = Regexp.new("\xa4\xa2".force_encoding("euc-jp"))
- d = Regexp.new("\x82\xa0".force_encoding("shift_jis"))
+describe "Encoding.compatible? Symbol, Regexp" do
+ it "returns US-ASCII if both are US-ASCII" do
+ Encoding.compatible?(:abc, /def/).should == Encoding::US_ASCII
+ end
- [ [Encoding, :abc, a, Encoding::ASCII_8BIT],
- [Encoding, :abc, b, Encoding::UTF_8],
- [Encoding, :abc, c, Encoding::EUC_JP],
- [Encoding, :abc, d, Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?)
- end
+ it "returns the Regexp's Encoding if it is not US-ASCII and not ASCII only" do
+ a = Regexp.new("\xff")
+ b = Regexp.new("\u3042".encode("utf-8"))
+ c = Regexp.new("\xa4\xa2".force_encoding("euc-jp"))
+ d = Regexp.new("\x82\xa0".force_encoding("shift_jis"))
+
+ [ [Encoding, :abc, a, Encoding::BINARY],
+ [Encoding, :abc, b, Encoding::UTF_8],
+ [Encoding, :abc, c, Encoding::EUC_JP],
+ [Encoding, :abc, d, Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?)
end
+end
- describe "Encoding.compatible? Symbol, Symbol" do
- it "returns US-ASCII if both are US-ASCII" do
- Encoding.compatible?(:abc, :def).should == Encoding::US_ASCII
- end
+describe "Encoding.compatible? Symbol, Symbol" do
+ it "returns US-ASCII if both are US-ASCII" do
+ Encoding.compatible?(:abc, :def).should == Encoding::US_ASCII
+ end
- it "returns the first's Encoding if it is not ASCII only" do
- [ [Encoding, "\xff".to_sym, Encoding::ASCII_8BIT],
- [Encoding, "\u3042".encode("utf-8").to_sym, Encoding::UTF_8],
- [Encoding, "\xa4\xa2".force_encoding("euc-jp").to_sym, Encoding::EUC_JP],
- [Encoding, "\x82\xa0".force_encoding("shift_jis").to_sym, Encoding::Shift_JIS],
- ].should be_computed_by(:compatible?, :abc)
- end
+ it "returns the first's Encoding if it is not ASCII only" do
+ [ [Encoding, "\xff".to_sym, Encoding::BINARY],
+ [Encoding, "\u3042".encode("utf-8").to_sym, Encoding::UTF_8],
+ [Encoding, "\xa4\xa2".force_encoding("euc-jp").to_sym, Encoding::EUC_JP],
+ [Encoding, "\x82\xa0".force_encoding("shift_jis").to_sym, Encoding::Shift_JIS],
+ ].should be_computed_by(:compatible?, :abc)
end
+end
- describe "Encoding.compatible? Encoding, Encoding" do
- it "returns nil if one of the encodings is a dummy encoding" do
- [ [Encoding, Encoding::UTF_7, Encoding::US_ASCII, nil],
- [Encoding, Encoding::US_ASCII, Encoding::UTF_7, nil],
- [Encoding, Encoding::EUC_JP, Encoding::UTF_7, nil],
- [Encoding, Encoding::UTF_7, Encoding::EUC_JP, nil],
- [Encoding, Encoding::UTF_7, Encoding::ASCII_8BIT, nil],
- [Encoding, Encoding::ASCII_8BIT, Encoding::UTF_7, nil],
- ].should be_computed_by(:compatible?)
- end
+describe "Encoding.compatible? Encoding, Encoding" do
+ it "returns nil if one of the encodings is a dummy encoding" do
+ [ [Encoding, Encoding::UTF_7, Encoding::US_ASCII, nil],
+ [Encoding, Encoding::US_ASCII, Encoding::UTF_7, nil],
+ [Encoding, Encoding::EUC_JP, Encoding::UTF_7, nil],
+ [Encoding, Encoding::UTF_7, Encoding::EUC_JP, nil],
+ [Encoding, Encoding::UTF_7, Encoding::BINARY, nil],
+ [Encoding, Encoding::BINARY, Encoding::UTF_7, nil],
+ ].should be_computed_by(:compatible?)
+ end
- it "returns nil if one of the encodings is not US-ASCII" do
- [ [Encoding, Encoding::UTF_8, Encoding::ASCII_8BIT, nil],
- [Encoding, Encoding::ASCII_8BIT, Encoding::UTF_8, nil],
- [Encoding, Encoding::ASCII_8BIT, Encoding::EUC_JP, nil],
- [Encoding, Encoding::Shift_JIS, Encoding::EUC_JP, nil],
- ].should be_computed_by(:compatible?)
- end
+ it "returns nil if one of the encodings is not US-ASCII" do
+ [ [Encoding, Encoding::UTF_8, Encoding::BINARY, nil],
+ [Encoding, Encoding::BINARY, Encoding::UTF_8, nil],
+ [Encoding, Encoding::BINARY, Encoding::EUC_JP, nil],
+ [Encoding, Encoding::Shift_JIS, Encoding::EUC_JP, nil],
+ ].should be_computed_by(:compatible?)
+ end
- it "returns the first if the second is US-ASCII" do
- [ [Encoding, Encoding::UTF_8, Encoding::US_ASCII, Encoding::UTF_8],
- [Encoding, Encoding::EUC_JP, Encoding::US_ASCII, Encoding::EUC_JP],
- [Encoding, Encoding::Shift_JIS, Encoding::US_ASCII, Encoding::Shift_JIS],
- [Encoding, Encoding::ASCII_8BIT, Encoding::US_ASCII, Encoding::ASCII_8BIT],
- ].should be_computed_by(:compatible?)
- end
+ it "returns the first if the second is US-ASCII" do
+ [ [Encoding, Encoding::UTF_8, Encoding::US_ASCII, Encoding::UTF_8],
+ [Encoding, Encoding::EUC_JP, Encoding::US_ASCII, Encoding::EUC_JP],
+ [Encoding, Encoding::Shift_JIS, Encoding::US_ASCII, Encoding::Shift_JIS],
+ [Encoding, Encoding::BINARY, Encoding::US_ASCII, Encoding::BINARY],
+ ].should be_computed_by(:compatible?)
+ end
- it "returns the Encoding if both are the same" do
- [ [Encoding, Encoding::UTF_8, Encoding::UTF_8, Encoding::UTF_8],
- [Encoding, Encoding::US_ASCII, Encoding::US_ASCII, Encoding::US_ASCII],
- [Encoding, Encoding::ASCII_8BIT, Encoding::ASCII_8BIT, Encoding::ASCII_8BIT],
- [Encoding, Encoding::UTF_7, Encoding::UTF_7, Encoding::UTF_7],
- ].should be_computed_by(:compatible?)
- end
+ it "returns the Encoding if both are the same" do
+ [ [Encoding, Encoding::UTF_8, Encoding::UTF_8, Encoding::UTF_8],
+ [Encoding, Encoding::US_ASCII, Encoding::US_ASCII, Encoding::US_ASCII],
+ [Encoding, Encoding::BINARY, Encoding::BINARY, Encoding::BINARY],
+ [Encoding, Encoding::UTF_7, Encoding::UTF_7, Encoding::UTF_7],
+ ].should be_computed_by(:compatible?)
end
+end
- describe "Encoding.compatible? Object, Object" do
- it "returns nil for Object, String" do
- Encoding.compatible?(Object.new, "abc").should be_nil
- end
+describe "Encoding.compatible? Object, Object" do
+ it "returns nil for Object, String" do
+ Encoding.compatible?(Object.new, "abc").should be_nil
+ end
- it "returns nil for Object, Regexp" do
- Encoding.compatible?(Object.new, /./).should be_nil
- end
+ it "returns nil for Object, Regexp" do
+ Encoding.compatible?(Object.new, /./).should be_nil
+ end
- it "returns nil for Object, Symbol" do
- Encoding.compatible?(Object.new, :sym).should be_nil
- end
+ it "returns nil for Object, Symbol" do
+ Encoding.compatible?(Object.new, :sym).should be_nil
+ end
- it "returns nil for String, Object" do
- Encoding.compatible?("abc", Object.new).should be_nil
- end
+ it "returns nil for String, Object" do
+ Encoding.compatible?("abc", Object.new).should be_nil
+ end
- it "returns nil for Regexp, Object" do
- Encoding.compatible?(/./, Object.new).should be_nil
- end
+ it "returns nil for Regexp, Object" do
+ Encoding.compatible?(/./, Object.new).should be_nil
+ end
- it "returns nil for Symbol, Object" do
- Encoding.compatible?(:sym, Object.new).should be_nil
- end
+ it "returns nil for Symbol, Object" do
+ Encoding.compatible?(:sym, Object.new).should be_nil
end
end
diff --git a/spec/ruby/core/encoding/converter/asciicompat_encoding_spec.rb b/spec/ruby/core/encoding/converter/asciicompat_encoding_spec.rb
index 329e09cade..1beb40af3f 100644
--- a/spec/ruby/core/encoding/converter/asciicompat_encoding_spec.rb
+++ b/spec/ruby/core/encoding/converter/asciicompat_encoding_spec.rb
@@ -1,39 +1,37 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter.asciicompat_encoding" do
- it "accepts an encoding name as a String argument" do
- lambda { Encoding::Converter.asciicompat_encoding('UTF-8') }.
- should_not raise_error
- end
+describe "Encoding::Converter.asciicompat_encoding" do
+ it "accepts an encoding name as a String argument" do
+ -> { Encoding::Converter.asciicompat_encoding('UTF-8') }.
+ should_not raise_error
+ end
- it "coerces non-String/Encoding objects with #to_str" do
- str = mock('string')
- str.should_receive(:to_str).at_least(1).times.and_return('string')
- Encoding::Converter.asciicompat_encoding(str)
- end
+ it "coerces non-String/Encoding objects with #to_str" do
+ str = mock('string')
+ str.should_receive(:to_str).at_least(1).times.and_return('string')
+ Encoding::Converter.asciicompat_encoding(str)
+ end
- it "accepts an Encoding object as an argument" do
- Encoding::Converter.
- asciicompat_encoding(Encoding.find("ISO-2022-JP")).
- should == Encoding::Converter.asciicompat_encoding("ISO-2022-JP")
- end
+ it "accepts an Encoding object as an argument" do
+ Encoding::Converter.
+ asciicompat_encoding(Encoding.find("ISO-2022-JP")).
+ should == Encoding::Converter.asciicompat_encoding("ISO-2022-JP")
+ end
- it "returns a corresponding ASCII compatible encoding for ASCII-incompatible encodings" do
- Encoding::Converter.asciicompat_encoding('UTF-16BE').should == Encoding::UTF_8
- Encoding::Converter.asciicompat_encoding("ISO-2022-JP").should == Encoding.find("stateless-ISO-2022-JP")
- end
+ it "returns a corresponding ASCII compatible encoding for ASCII-incompatible encodings" do
+ Encoding::Converter.asciicompat_encoding('UTF-16BE').should == Encoding::UTF_8
+ Encoding::Converter.asciicompat_encoding("ISO-2022-JP").should == Encoding.find("stateless-ISO-2022-JP")
+ end
- it "returns nil when the given encoding is ASCII compatible" do
- Encoding::Converter.asciicompat_encoding('ASCII').should be_nil
- Encoding::Converter.asciicompat_encoding('UTF-8').should be_nil
- end
+ it "returns nil when the given encoding is ASCII compatible" do
+ Encoding::Converter.asciicompat_encoding('ASCII').should be_nil
+ Encoding::Converter.asciicompat_encoding('UTF-8').should be_nil
+ end
- it "handles encoding names who resolve to nil encodings" do
- internal = Encoding.default_internal
- Encoding.default_internal = nil
- Encoding::Converter.asciicompat_encoding('internal').should be_nil
- Encoding.default_internal = internal
- end
+ it "handles encoding names who resolve to nil encodings" do
+ internal = Encoding.default_internal
+ Encoding.default_internal = nil
+ Encoding::Converter.asciicompat_encoding('internal').should be_nil
+ Encoding.default_internal = internal
end
end
diff --git a/spec/ruby/core/encoding/converter/constants_spec.rb b/spec/ruby/core/encoding/converter/constants_spec.rb
index 16eb60b4ab..7d29bdb278 100644
--- a/spec/ruby/core/encoding/converter/constants_spec.rb
+++ b/spec/ruby/core/encoding/converter/constants_spec.rb
@@ -1,133 +1,131 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter::INVALID_MASK" do
- it "exists" do
- Encoding::Converter.should have_constant(:INVALID_MASK)
- end
+describe "Encoding::Converter::INVALID_MASK" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:INVALID_MASK)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::INVALID_MASK.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::INVALID_MASK.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::INVALID_REPLACE" do
- it "exists" do
- Encoding::Converter.should have_constant(:INVALID_REPLACE)
- end
+describe "Encoding::Converter::INVALID_REPLACE" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:INVALID_REPLACE)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::INVALID_REPLACE.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::INVALID_REPLACE.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::UNDEF_MASK" do
- it "exists" do
- Encoding::Converter.should have_constant(:UNDEF_MASK)
- end
+describe "Encoding::Converter::UNDEF_MASK" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:UNDEF_MASK)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::UNDEF_MASK.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::UNDEF_MASK.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::UNDEF_REPLACE" do
- it "exists" do
- Encoding::Converter.should have_constant(:UNDEF_REPLACE)
- end
+describe "Encoding::Converter::UNDEF_REPLACE" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:UNDEF_REPLACE)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::UNDEF_REPLACE.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::UNDEF_REPLACE.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::UNDEF_HEX_CHARREF" do
- it "exists" do
- Encoding::Converter.should have_constant(:UNDEF_HEX_CHARREF)
- end
+describe "Encoding::Converter::UNDEF_HEX_CHARREF" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:UNDEF_HEX_CHARREF)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::UNDEF_HEX_CHARREF.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::UNDEF_HEX_CHARREF.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::PARTIAL_INPUT" do
- it "exists" do
- Encoding::Converter.should have_constant(:PARTIAL_INPUT)
- end
+describe "Encoding::Converter::PARTIAL_INPUT" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:PARTIAL_INPUT)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::PARTIAL_INPUT.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::PARTIAL_INPUT.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::AFTER_OUTPUT" do
- it "exists" do
- Encoding::Converter.should have_constant(:AFTER_OUTPUT)
- end
+describe "Encoding::Converter::AFTER_OUTPUT" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:AFTER_OUTPUT)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::AFTER_OUTPUT.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::AFTER_OUTPUT.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::UNIVERSAL_NEWLINE_DECORATOR" do
- it "exists" do
- Encoding::Converter.should have_constant(:UNIVERSAL_NEWLINE_DECORATOR)
- end
+describe "Encoding::Converter::UNIVERSAL_NEWLINE_DECORATOR" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:UNIVERSAL_NEWLINE_DECORATOR)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::UNIVERSAL_NEWLINE_DECORATOR.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::UNIVERSAL_NEWLINE_DECORATOR.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::CRLF_NEWLINE_DECORATOR" do
- it "exists" do
- Encoding::Converter.should have_constant(:CRLF_NEWLINE_DECORATOR)
- end
+describe "Encoding::Converter::CRLF_NEWLINE_DECORATOR" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:CRLF_NEWLINE_DECORATOR)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::CRLF_NEWLINE_DECORATOR.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::CRLF_NEWLINE_DECORATOR.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::CR_NEWLINE_DECORATOR" do
- it "exists" do
- Encoding::Converter.should have_constant(:CR_NEWLINE_DECORATOR)
- end
+describe "Encoding::Converter::CR_NEWLINE_DECORATOR" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:CR_NEWLINE_DECORATOR)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::CR_NEWLINE_DECORATOR.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::CR_NEWLINE_DECORATOR.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::XML_TEXT_DECORATOR" do
- it "exists" do
- Encoding::Converter.should have_constant(:XML_TEXT_DECORATOR)
- end
+describe "Encoding::Converter::XML_TEXT_DECORATOR" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:XML_TEXT_DECORATOR)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::XML_TEXT_DECORATOR.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::XML_TEXT_DECORATOR.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::XML_ATTR_CONTENT_DECORATOR" do
- it "exists" do
- Encoding::Converter.should have_constant(:XML_ATTR_CONTENT_DECORATOR)
- end
+describe "Encoding::Converter::XML_ATTR_CONTENT_DECORATOR" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:XML_ATTR_CONTENT_DECORATOR)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::XML_ATTR_CONTENT_DECORATOR.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::XML_ATTR_CONTENT_DECORATOR.should be_an_instance_of(Integer)
end
+end
- describe "Encoding::Converter::XML_ATTR_QUOTE_DECORATOR" do
- it "exists" do
- Encoding::Converter.should have_constant(:XML_ATTR_QUOTE_DECORATOR)
- end
+describe "Encoding::Converter::XML_ATTR_QUOTE_DECORATOR" do
+ it "exists" do
+ Encoding::Converter.should have_constant(:XML_ATTR_QUOTE_DECORATOR)
+ end
- it "has a Fixnum value" do
- Encoding::Converter::XML_ATTR_QUOTE_DECORATOR.should be_an_instance_of(Fixnum)
- end
+ it "has an Integer value" do
+ Encoding::Converter::XML_ATTR_QUOTE_DECORATOR.should be_an_instance_of(Integer)
end
end
diff --git a/spec/ruby/core/encoding/converter/convert_spec.rb b/spec/ruby/core/encoding/converter/convert_spec.rb
index 588d659ceb..95a9e0b758 100644
--- a/spec/ruby/core/encoding/converter/convert_spec.rb
+++ b/spec/ruby/core/encoding/converter/convert_spec.rb
@@ -1,47 +1,45 @@
# -*- encoding: binary -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#convert" do
- it "returns a String" do
- ec = Encoding::Converter.new('ascii', 'utf-8')
- ec.convert('glark').should be_an_instance_of(String)
- end
+describe "Encoding::Converter#convert" do
+ it "returns a String" do
+ ec = Encoding::Converter.new('ascii', 'utf-8')
+ ec.convert('glark').should be_an_instance_of(String)
+ end
- it "sets the encoding of the result to the target encoding" do
- ec = Encoding::Converter.new('ascii', 'utf-8')
- str = 'glark'.force_encoding('ascii')
- ec.convert(str).encoding.should == Encoding::UTF_8
- end
+ it "sets the encoding of the result to the target encoding" do
+ ec = Encoding::Converter.new('ascii', 'utf-8')
+ str = 'glark'.force_encoding('ascii')
+ ec.convert(str).encoding.should == Encoding::UTF_8
+ end
- it "transcodes the given String to the target encoding" do
- ec = Encoding::Converter.new("utf-8", "euc-jp")
- ec.convert("\u3042".force_encoding('UTF-8')).should == \
- "\xA4\xA2".force_encoding('EUC-JP')
- end
+ it "transcodes the given String to the target encoding" do
+ ec = Encoding::Converter.new("utf-8", "euc-jp")
+ ec.convert("\u3042".force_encoding('UTF-8')).should == \
+ "\xA4\xA2".force_encoding('EUC-JP')
+ end
- it "allows Strings of different encodings to the source encoding" do
- ec = Encoding::Converter.new('ascii', 'utf-8')
- str = 'glark'.force_encoding('SJIS')
- ec.convert(str).encoding.should == Encoding::UTF_8
- end
+ it "allows Strings of different encodings to the source encoding" do
+ ec = Encoding::Converter.new('ascii', 'utf-8')
+ str = 'glark'.force_encoding('SJIS')
+ ec.convert(str).encoding.should == Encoding::UTF_8
+ end
- it "reuses the given encoding pair if called multiple times" do
- ec = Encoding::Converter.new('ascii', 'SJIS')
- ec.convert('a'.force_encoding('ASCII')).should == 'a'.force_encoding('SJIS')
- ec.convert('b'.force_encoding('ASCII')).should == 'b'.force_encoding('SJIS')
- end
+ it "reuses the given encoding pair if called multiple times" do
+ ec = Encoding::Converter.new('ascii', 'SJIS')
+ ec.convert('a'.force_encoding('ASCII')).should == 'a'.force_encoding('SJIS')
+ ec.convert('b'.force_encoding('ASCII')).should == 'b'.force_encoding('SJIS')
+ end
- it "raises UndefinedConversionError if the String contains characters invalid for the target encoding" do
- ec = Encoding::Converter.new('UTF-8', Encoding.find('macCyrillic'))
- lambda { ec.convert("\u{6543}".force_encoding('UTF-8')) }.should \
- raise_error(Encoding::UndefinedConversionError)
- end
+ it "raises UndefinedConversionError if the String contains characters invalid for the target encoding" do
+ ec = Encoding::Converter.new('UTF-8', Encoding.find('macCyrillic'))
+ -> { ec.convert("\u{6543}".force_encoding('UTF-8')) }.should \
+ raise_error(Encoding::UndefinedConversionError)
+ end
- it "raises an ArgumentError if called on a finished stream" do
- ec = Encoding::Converter.new('UTF-8', Encoding.find('macCyrillic'))
- ec.finish
- lambda { ec.convert("\u{65}") }.should raise_error(ArgumentError)
- end
+ it "raises an ArgumentError if called on a finished stream" do
+ ec = Encoding::Converter.new('UTF-8', Encoding.find('macCyrillic'))
+ ec.finish
+ -> { ec.convert("\u{65}") }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/encoding/converter/convpath_spec.rb b/spec/ruby/core/encoding/converter/convpath_spec.rb
index 679b894f58..23f1e5dc33 100644
--- a/spec/ruby/core/encoding/converter/convpath_spec.rb
+++ b/spec/ruby/core/encoding/converter/convpath_spec.rb
@@ -1,65 +1,24 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#convpath" do
- before :all do
- @perms = Encoding.name_list.permutation(2).map do |pair|
- Encoding::Converter.new(pair.first, pair.last) rescue nil
- end.compact.map{|ec| ec.convpath}
- end
-
- it "returns an Array" do
- ec = Encoding::Converter.new('ASCII', 'EUC-JP')
- ec.convpath.should be_an_instance_of(Array)
- end
-
- it "returns each encoding pair as a sub-Array" do
- ec = Encoding::Converter.new('ASCII', 'EUC-JP')
- ec.convpath.first.should be_an_instance_of(Array)
- ec.convpath.first.size.should == 2
- end
-
- it "returns each encoding as an Encoding object" do
- ec = Encoding::Converter.new('ASCII', 'EUC-JP')
- ec.convpath.first.first.should be_an_instance_of(Encoding)
- ec.convpath.first.last.should be_an_instance_of(Encoding)
- end
-
- it "returns multiple encoding pairs when direct conversion is impossible" do
- ec = Encoding::Converter.new('ascii','Big5')
- ec.convpath.size.should == 2
- ec.convpath.first.first.should == Encoding::US_ASCII
- ec.convpath.first.last.should == ec.convpath.last.first
- ec.convpath.last.last.should == Encoding::Big5
- end
-
- it "sets the last element of each pair to the first element of the next" do
- @perms.each do |convpath|
- next if convpath.size == 1
- convpath.each_with_index do |pair, idx|
- break if idx == convpath.size - 1
- pair.last.should == convpath[idx+1].first
- end
- end
- end
+describe "Encoding::Converter#convpath" do
+ it "returns an Array with a single element if there is a direct converter" do
+ cp = Encoding::Converter.new('ASCII', 'UTF-8').convpath
+ cp.should == [[Encoding::US_ASCII, Encoding::UTF_8]]
+ end
- it "only lists a source encoding once" do
- @perms.each do |convpath|
- next if convpath.size < 2
- seen = Hash.new(false)
- convpath.each_with_index do |pair, idx|
- seen.key?(pair.first).should be_false if idx > 0
- seen[pair.first] = true
- end
- end
- end
+ it "returns multiple encoding pairs when direct conversion is impossible" do
+ cp = Encoding::Converter.new('ascii','Big5').convpath
+ cp.should == [
+ [Encoding::US_ASCII, Encoding::UTF_8],
+ [Encoding::UTF_8, Encoding::Big5]
+ ]
+ end
- it "indicates if crlf_newline conversion would occur" do
- ec = Encoding::Converter.new("ISo-8859-1", "EUC-JP", {crlf_newline: true})
- ec.convpath.last.should == "crlf_newline"
+ it "indicates if crlf_newline conversion would occur" do
+ ec = Encoding::Converter.new("ISo-8859-1", "EUC-JP", crlf_newline: true)
+ ec.convpath.last.should == "crlf_newline"
- ec = Encoding::Converter.new("ASCII", "UTF-8", {crlf_newline: false})
- ec.convpath.last.should_not == "crlf_newline"
- end
+ ec = Encoding::Converter.new("ASCII", "UTF-8", crlf_newline: false)
+ ec.convpath.last.should_not == "crlf_newline"
end
end
diff --git a/spec/ruby/core/encoding/converter/destination_encoding_spec.rb b/spec/ruby/core/encoding/converter/destination_encoding_spec.rb
index 830e6d2178..481a857909 100644
--- a/spec/ruby/core/encoding/converter/destination_encoding_spec.rb
+++ b/spec/ruby/core/encoding/converter/destination_encoding_spec.rb
@@ -1,13 +1,11 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#destination_encoding" do
- it "returns the destination encoding as an Encoding object" do
- ec = Encoding::Converter.new('ASCII','Big5')
- ec.destination_encoding.should == Encoding::BIG5
+describe "Encoding::Converter#destination_encoding" do
+ it "returns the destination encoding as an Encoding object" do
+ ec = Encoding::Converter.new('ASCII','Big5')
+ ec.destination_encoding.should == Encoding::BIG5
- ec = Encoding::Converter.new('SJIS','EUC-JP')
- ec.destination_encoding.should == Encoding::EUC_JP
- end
+ ec = Encoding::Converter.new('SJIS','EUC-JP')
+ ec.destination_encoding.should == Encoding::EUC_JP
end
end
diff --git a/spec/ruby/core/encoding/converter/finish_spec.rb b/spec/ruby/core/encoding/converter/finish_spec.rb
index 86097357f4..11ca7e8510 100644
--- a/spec/ruby/core/encoding/converter/finish_spec.rb
+++ b/spec/ruby/core/encoding/converter/finish_spec.rb
@@ -1,38 +1,36 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#finish" do
- before :each do
- @ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
- end
+describe "Encoding::Converter#finish" do
+ before :each do
+ @ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
+ end
- it "returns a String" do
- @ec.convert('foo')
- @ec.finish.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @ec.convert('foo')
+ @ec.finish.should be_an_instance_of(String)
+ end
- it "returns an empty String if there is nothing more to convert" do
- @ec.convert("glark")
- @ec.finish.should == ""
- end
+ it "returns an empty String if there is nothing more to convert" do
+ @ec.convert("glark")
+ @ec.finish.should == ""
+ end
- it "returns the last part of the converted String if it hasn't already" do
- @ec.convert("\u{9999}").should == "\e$B9a".force_encoding('iso-2022-jp')
- @ec.finish.should == "\e(B".force_encoding('iso-2022-jp')
- end
+ it "returns the last part of the converted String if it hasn't already" do
+ @ec.convert("\u{9999}").should == "\e$B9a".force_encoding('iso-2022-jp')
+ @ec.finish.should == "\e(B".force_encoding('iso-2022-jp')
+ end
- it "returns a String in the destination encoding" do
- @ec.convert("glark")
- @ec.finish.encoding.should == Encoding::ISO2022_JP
- end
+ it "returns a String in the destination encoding" do
+ @ec.convert("glark")
+ @ec.finish.encoding.should == Encoding::ISO2022_JP
+ end
- it "returns an empty String if self was not given anything to convert" do
- @ec.finish.should == ""
- end
+ it "returns an empty String if self was not given anything to convert" do
+ @ec.finish.should == ""
+ end
- it "returns an empty String on subsequent invocations" do
- @ec.finish.should == ""
- @ec.finish.should == ""
- end
+ it "returns an empty String on subsequent invocations" do
+ @ec.finish.should == ""
+ @ec.finish.should == ""
end
end
diff --git a/spec/ruby/core/encoding/converter/insert_output_spec.rb b/spec/ruby/core/encoding/converter/insert_output_spec.rb
index bc9a56ba45..1346adde1e 100644
--- a/spec/ruby/core/encoding/converter/insert_output_spec.rb
+++ b/spec/ruby/core/encoding/converter/insert_output_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Encoding::Converter#insert_output" do
it "needs to be reviewed for spec completeness"
diff --git a/spec/ruby/core/encoding/converter/inspect_spec.rb b/spec/ruby/core/encoding/converter/inspect_spec.rb
index b8216176cf..3170ee451f 100644
--- a/spec/ruby/core/encoding/converter/inspect_spec.rb
+++ b/spec/ruby/core/encoding/converter/inspect_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Encoding::Converter#inspect" do
it "includes the source and destination encodings in the return value" do
diff --git a/spec/ruby/core/encoding/converter/last_error_spec.rb b/spec/ruby/core/encoding/converter/last_error_spec.rb
index 8465935368..68567737b7 100644
--- a/spec/ruby/core/encoding/converter/last_error_spec.rb
+++ b/spec/ruby/core/encoding/converter/last_error_spec.rb
@@ -1,85 +1,91 @@
# -*- encoding: binary -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#last_error" do
- it "returns nil when the no conversion has been attempted" do
- ec = Encoding::Converter.new('ascii','utf-8')
- ec.last_error.should be_nil
- end
+describe "Encoding::Converter#last_error" do
+ it "returns nil when the no conversion has been attempted" do
+ ec = Encoding::Converter.new('ascii','utf-8')
+ ec.last_error.should be_nil
+ end
- it "returns nil when the last conversion did not produce an error" do
- ec = Encoding::Converter.new('ascii','utf-8')
- ec.convert('a'.force_encoding('ascii'))
- ec.last_error.should be_nil
- end
+ it "returns nil when the last conversion did not produce an error" do
+ ec = Encoding::Converter.new('ascii','utf-8')
+ ec.convert('a'.force_encoding('ascii'))
+ ec.last_error.should be_nil
+ end
- it "returns nil when #primitive_convert last returned :destination_buffer_full" do
- ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
- ec.primitive_convert("\u{9999}", "", 0, 0, partial_input: false) \
- .should == :destination_buffer_full
- ec.last_error.should be_nil
- end
+ it "returns nil when #primitive_convert last returned :destination_buffer_full" do
+ ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
+ ec.primitive_convert("\u{9999}", "", 0, 0, partial_input: false) \
+ .should == :destination_buffer_full
+ ec.last_error.should be_nil
+ end
- it "returns nil when #primitive_convert last returned :finished" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
- ec.last_error.should be_nil
- end
+ it "returns nil when #primitive_convert last returned :finished" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
+ ec.last_error.should be_nil
+ end
- it "returns nil if the last conversion succeeded but the penultimate failed" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
- ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
- ec.last_error.should be_nil
- end
+ it "returns nil if the last conversion succeeded but the penultimate failed" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
+ ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
+ ec.last_error.should be_nil
+ end
- it "returns an Encoding::InvalidByteSequenceError when #primitive_convert last returned :invalid_byte_sequence" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
- ec.last_error.should be_an_instance_of(Encoding::InvalidByteSequenceError)
- end
+ it "returns an Encoding::InvalidByteSequenceError when #primitive_convert last returned :invalid_byte_sequence" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
+ ec.last_error.should be_an_instance_of(Encoding::InvalidByteSequenceError)
+ end
- it "returns an Encoding::UndefinedConversionError when #primitive_convert last returned :undefined_conversion" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- ec.primitive_convert("\u{9876}","").should == :undefined_conversion
- ec.last_error.should be_an_instance_of(Encoding::UndefinedConversionError)
- end
+ it "returns an Encoding::UndefinedConversionError when #primitive_convert last returned :undefined_conversion" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ ec.primitive_convert("\u{9876}","").should == :undefined_conversion
+ ec.last_error.should be_an_instance_of(Encoding::UndefinedConversionError)
+ end
- it "returns an Encoding::InvalidByteSequenceError when #primitive_convert last returned :incomplete_input" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- ec.primitive_convert("\xa4", "", nil, 10).should == :incomplete_input
- ec.last_error.should be_an_instance_of(Encoding::InvalidByteSequenceError)
- end
+ it "returns an Encoding::InvalidByteSequenceError when #primitive_convert last returned :incomplete_input" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert("\xa4", "", nil, 10).should == :incomplete_input
+ ec.last_error.should be_an_instance_of(Encoding::InvalidByteSequenceError)
+ end
- it "returns an Encoding::InvalidByteSequenceError when the last call to #convert produced one" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- exception = nil
- lambda do
- begin
- ec.convert("\xf1abcd")
- rescue Encoding::InvalidByteSequenceError => e
- exception = e
- raise e
- end
- end.should raise_error(Encoding::InvalidByteSequenceError)
- ec.last_error.should be_an_instance_of(Encoding::InvalidByteSequenceError)
- ec.last_error.message.should == exception.message
- end
+ it "returns an Encoding::InvalidByteSequenceError when the last call to #convert produced one" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ exception = nil
+ -> {
+ ec.convert("\xf1abcd")
+ }.should raise_error(Encoding::InvalidByteSequenceError) { |e|
+ exception = e
+ }
+ ec.last_error.should be_an_instance_of(Encoding::InvalidByteSequenceError)
+ ec.last_error.message.should == exception.message
+ end
+
+ it "returns an Encoding::UndefinedConversionError when the last call to #convert produced one" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ exception = nil
+ -> {
+ ec.convert("\u{9899}")
+ }.should raise_error(Encoding::UndefinedConversionError) { |e|
+ exception = e
+ }
+ ec.last_error.should be_an_instance_of(Encoding::UndefinedConversionError)
+ ec.last_error.message.should == exception.message
+ ec.last_error.message.should include "from UTF-8 to ISO-8859-1"
+ end
- it "returns an Encoding::UndefinedConversionError when the last call to #convert produced one" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- exception = nil
- lambda do
- begin
- ec.convert("\u{9899}")
- rescue Encoding::UndefinedConversionError => e
- exception = e
- raise e
- end
- end.should raise_error(Encoding::UndefinedConversionError)
- ec.last_error.should be_an_instance_of(Encoding::UndefinedConversionError)
- ec.last_error.message.should == exception.message
- end
+ it "returns the last error of #convert with a message showing the transcoding path" do
+ ec = Encoding::Converter.new("iso-8859-1", "Big5")
+ exception = nil
+ -> {
+ ec.convert("\xE9") # é in ISO-8859-1
+ }.should raise_error(Encoding::UndefinedConversionError) { |e|
+ exception = e
+ }
+ ec.last_error.should be_an_instance_of(Encoding::UndefinedConversionError)
+ ec.last_error.message.should == exception.message
+ ec.last_error.message.should include "from ISO-8859-1 to UTF-8 to Big5"
end
end
diff --git a/spec/ruby/core/encoding/converter/new_spec.rb b/spec/ruby/core/encoding/converter/new_spec.rb
index d228c80a18..1f7affc72b 100644
--- a/spec/ruby/core/encoding/converter/new_spec.rb
+++ b/spec/ruby/core/encoding/converter/new_spec.rb
@@ -1,120 +1,118 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-
-with_feature :encoding do
- describe "Encoding::Converter.new" do
- it "accepts a String for the source encoding" do
- conv = Encoding::Converter.new("us-ascii", "utf-8")
- conv.source_encoding.should == Encoding::US_ASCII
- end
+# -*- encoding: binary -*-
+require_relative '../../../spec_helper'
- it "accepts a String for the destination encoding" do
- conv = Encoding::Converter.new("us-ascii", "utf-8")
- conv.destination_encoding.should == Encoding::UTF_8
- end
+describe "Encoding::Converter.new" do
+ it "accepts a String for the source encoding" do
+ conv = Encoding::Converter.new("us-ascii", "utf-8")
+ conv.source_encoding.should == Encoding::US_ASCII
+ end
- it "accepts an Encoding object for the source encoding" do
- conv = Encoding::Converter.new(Encoding::US_ASCII, "utf-8")
- conv.source_encoding.should == Encoding::US_ASCII
- end
+ it "accepts a String for the destination encoding" do
+ conv = Encoding::Converter.new("us-ascii", "utf-8")
+ conv.destination_encoding.should == Encoding::UTF_8
+ end
- it "accepts an Encoding object for the destination encoding" do
- conv = Encoding::Converter.new("us-ascii", Encoding::UTF_8)
- conv.destination_encoding.should == Encoding::UTF_8
- end
+ it "accepts an Encoding object for the source encoding" do
+ conv = Encoding::Converter.new(Encoding::US_ASCII, "utf-8")
+ conv.source_encoding.should == Encoding::US_ASCII
+ end
- it "raises an Encoding::ConverterNotFoundError if both encodings are the same" do
- lambda do
- Encoding::Converter.new "utf-8", "utf-8"
- end.should raise_error(Encoding::ConverterNotFoundError)
- end
+ it "accepts an Encoding object for the destination encoding" do
+ conv = Encoding::Converter.new("us-ascii", Encoding::UTF_8)
+ conv.destination_encoding.should == Encoding::UTF_8
+ end
- it "calls #to_str to convert the source encoding argument to an encoding name" do
- enc = mock("us-ascii")
- enc.should_receive(:to_str).and_return("us-ascii")
- conv = Encoding::Converter.new(enc, "utf-8")
- conv.source_encoding.should == Encoding::US_ASCII
- end
+ it "raises an Encoding::ConverterNotFoundError if both encodings are the same" do
+ -> do
+ Encoding::Converter.new "utf-8", "utf-8"
+ end.should raise_error(Encoding::ConverterNotFoundError)
+ end
- it "calls #to_str to convert the destination encoding argument to an encoding name" do
- enc = mock("utf-8")
- enc.should_receive(:to_str).and_return("utf-8")
- conv = Encoding::Converter.new("us-ascii", enc)
- conv.destination_encoding.should == Encoding::UTF_8
- end
+ it "calls #to_str to convert the source encoding argument to an encoding name" do
+ enc = mock("us-ascii")
+ enc.should_receive(:to_str).and_return("us-ascii")
+ conv = Encoding::Converter.new(enc, "utf-8")
+ conv.source_encoding.should == Encoding::US_ASCII
+ end
- it "sets replacement from the options Hash" do
- conv = Encoding::Converter.new("us-ascii", "utf-8", replace: "fubar")
- conv.replacement.should == "fubar"
- end
+ it "calls #to_str to convert the destination encoding argument to an encoding name" do
+ enc = mock("utf-8")
+ enc.should_receive(:to_str).and_return("utf-8")
+ conv = Encoding::Converter.new("us-ascii", enc)
+ conv.destination_encoding.should == Encoding::UTF_8
+ end
- it "calls #to_hash to convert the options argument to a Hash if not a Fixnum" do
- opts = mock("encoding converter options")
- opts.should_receive(:to_hash).and_return({ replace: "fubar" })
- conv = Encoding::Converter.new("us-ascii", "utf-8", opts)
- conv.replacement.should == "fubar"
- end
+ it "sets replacement from the options Hash" do
+ conv = Encoding::Converter.new("us-ascii", "utf-8", replace: "fubar")
+ conv.replacement.should == "fubar"
+ end
- it "calls #to_str to convert the replacement object to a String" do
- obj = mock("encoding converter replacement")
- obj.should_receive(:to_str).and_return("fubar")
- conv = Encoding::Converter.new("us-ascii", "utf-8", replace: obj)
- conv.replacement.should == "fubar"
- end
+ it "calls #to_hash to convert the options argument to a Hash if not an Integer" do
+ opts = mock("encoding converter options")
+ opts.should_receive(:to_hash).and_return({ replace: "fubar" })
+ conv = Encoding::Converter.new("us-ascii", "utf-8", **opts)
+ conv.replacement.should == "fubar"
+ end
- it "raises a TypeError if #to_str does not return a String" do
- obj = mock("encoding converter replacement")
- obj.should_receive(:to_str).and_return(1)
+ it "calls #to_str to convert the replacement object to a String" do
+ obj = mock("encoding converter replacement")
+ obj.should_receive(:to_str).and_return("fubar")
+ conv = Encoding::Converter.new("us-ascii", "utf-8", replace: obj)
+ conv.replacement.should == "fubar"
+ end
- lambda do
- Encoding::Converter.new("us-ascii", "utf-8", replace: obj)
- end.should raise_error(TypeError)
- end
+ it "raises a TypeError if #to_str does not return a String" do
+ obj = mock("encoding converter replacement")
+ obj.should_receive(:to_str).and_return(1)
- it "raises a TypeError if passed true for the replacement object" do
- lambda do
- Encoding::Converter.new("us-ascii", "utf-8", replace: true)
- end.should raise_error(TypeError)
- end
+ -> do
+ Encoding::Converter.new("us-ascii", "utf-8", replace: obj)
+ end.should raise_error(TypeError)
+ end
- it "raises a TypeError if passed false for the replacement object" do
- lambda do
- Encoding::Converter.new("us-ascii", "utf-8", replace: false)
- end.should raise_error(TypeError)
- end
+ it "raises a TypeError if passed true for the replacement object" do
+ -> do
+ Encoding::Converter.new("us-ascii", "utf-8", replace: true)
+ end.should raise_error(TypeError)
+ end
- it "raises a TypeError if passed a Fixnum for the replacement object" do
- lambda do
- Encoding::Converter.new("us-ascii", "utf-8", replace: 1)
- end.should raise_error(TypeError)
- end
+ it "raises a TypeError if passed false for the replacement object" do
+ -> do
+ Encoding::Converter.new("us-ascii", "utf-8", replace: false)
+ end.should raise_error(TypeError)
+ end
- it "accepts an empty String for the replacement object" do
- conv = Encoding::Converter.new("us-ascii", "utf-8", replace: "")
- conv.replacement.should == ""
- end
+ it "raises a TypeError if passed an Integer for the replacement object" do
+ -> do
+ Encoding::Converter.new("us-ascii", "utf-8", replace: 1)
+ end.should raise_error(TypeError)
+ end
+
+ it "accepts an empty String for the replacement object" do
+ conv = Encoding::Converter.new("us-ascii", "utf-8", replace: "")
+ conv.replacement.should == ""
+ end
+
+ describe "when passed nil for the replacement object" do
+ describe "when the destination encoding is not UTF-8" do
+ it "sets the replacement String to '?'" do
+ conv = Encoding::Converter.new("us-ascii", "binary", replace: nil)
+ conv.replacement.should == "?"
+ end
+
+ it "sets the replacement String encoding to US-ASCII" do
+ conv = Encoding::Converter.new("us-ascii", "binary", replace: nil)
+ conv.replacement.encoding.should == Encoding::US_ASCII
+ end
+
+ it "sets the replacement String to '\\uFFFD'" do
+ conv = Encoding::Converter.new("us-ascii", "utf-8", replace: nil)
+ conv.replacement.should == "\u{fffd}".force_encoding("utf-8")
+ end
- describe "when passed nil for the replacement object" do
- describe "when the destination encoding is not UTF-8" do
- it "sets the replacement String to '?'" do
- conv = Encoding::Converter.new("us-ascii", "ascii-8bit", replace: nil)
- conv.replacement.should == "?"
- end
-
- it "sets the replacement String encoding to US-ASCII" do
- conv = Encoding::Converter.new("us-ascii", "ascii-8bit", replace: nil)
- conv.replacement.encoding.should == Encoding::US_ASCII
- end
-
- it "sets the replacement String to '\\uFFFD'" do
- conv = Encoding::Converter.new("us-ascii", "utf-8", replace: nil)
- conv.replacement.should == "\u{fffd}".force_encoding("utf-8")
- end
-
- it "sets the replacement String encoding to UTF-8" do
- conv = Encoding::Converter.new("us-ascii", "utf-8", replace: nil)
- conv.replacement.encoding.should == Encoding::UTF_8
- end
+ it "sets the replacement String encoding to UTF-8" do
+ conv = Encoding::Converter.new("us-ascii", "utf-8", replace: nil)
+ conv.replacement.encoding.should == Encoding::UTF_8
end
end
end
diff --git a/spec/ruby/core/encoding/converter/primitive_convert_spec.rb b/spec/ruby/core/encoding/converter/primitive_convert_spec.rb
index b9d6288bb2..802d8e7cb1 100644
--- a/spec/ruby/core/encoding/converter/primitive_convert_spec.rb
+++ b/spec/ruby/core/encoding/converter/primitive_convert_spec.rb
@@ -1,213 +1,211 @@
# -*- encoding: binary -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-
-with_feature :encoding do
- describe "Encoding::Converter#primitive_convert" do
- before :each do
- @ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- end
-
- it "accepts a nil source buffer" do
- lambda { @ec.primitive_convert(nil,"") }.should_not raise_error
- end
-
- it "accepts a String as the source buffer" do
- lambda { @ec.primitive_convert("","") }.should_not raise_error
- end
-
- it "accepts nil for the destination byte offset" do
- lambda { @ec.primitive_convert("","", nil) }.should_not raise_error
- end
-
- it "accepts an integer for the destination byte offset" do
- lambda { @ec.primitive_convert("","a", 1) }.should_not raise_error
- end
-
- it "calls #to_int to convert the destination byte offset" do
- offset = mock("encoding primitive_convert destination byte offset")
- offset.should_receive(:to_int).and_return(2)
- @ec.primitive_convert("abc", result = " ", offset).should == :finished
- result.should == " abc"
- end
-
- it "raises an ArgumentError if the destination byte offset is greater than the bytesize of the destination buffer" do
- lambda { @ec.primitive_convert("","am", 0) }.should_not raise_error
- lambda { @ec.primitive_convert("","am", 1) }.should_not raise_error
- lambda { @ec.primitive_convert("","am", 2) }.should_not raise_error
- lambda { @ec.primitive_convert("","am", 3) }.should raise_error(ArgumentError)
- end
-
- it "uses the destination byte offset to determine where to write the result in the destination buffer" do
- dest = "aa"
- @ec.primitive_convert("b",dest, nil, 0)
- dest.should == "aa"
-
- @ec.primitive_convert("b",dest, nil, 1)
- dest.should == "aab"
-
- @ec.primitive_convert("b",dest, nil, 2)
- dest.should == "aabbb"
- end
-
- it "accepts nil for the destination bytesize" do
- lambda { @ec.primitive_convert("","", nil, nil) }.should_not raise_error
- end
-
- it "accepts an integer for the destination bytesize" do
- lambda { @ec.primitive_convert("","", nil, 0) }.should_not raise_error
- end
-
- it "allows a destination bytesize value greater than the bytesize of the source buffer" do
- lambda { @ec.primitive_convert("am","", nil, 3) }.should_not raise_error
- end
-
- it "allows a destination bytesize value less than the bytesize of the source buffer" do
- lambda { @ec.primitive_convert("am","", nil, 1) }.should_not raise_error
- end
-
- it "calls #to_int to convert the destination byte size" do
- size = mock("encoding primitive_convert destination byte size")
- size.should_receive(:to_int).and_return(2)
- @ec.primitive_convert("abc", result = " ", 0, size).should == :destination_buffer_full
- result.should == "ab"
- end
-
- it "uses destination bytesize as the maximum bytesize of the destination buffer" do
- dest = ""
- @ec.primitive_convert("glark", dest, nil, 1)
- dest.bytesize.should == 1
- end
-
- it "allows a destination buffer of unlimited size if destination bytesize is nil" do
- source = "glark".force_encoding('utf-8')
- dest = ""
- @ec.primitive_convert("glark", dest, nil, nil)
- dest.bytesize.should == source.bytesize
- end
-
- it "accepts an options hash" do
- @ec.primitive_convert("","",nil,nil, {after_output: true}).should == :finished
- end
-
- it "sets the destination buffer's encoding to the destination encoding if the conversion suceeded" do
- dest = "".force_encoding('utf-8')
- dest.encoding.should == Encoding::UTF_8
- @ec.primitive_convert("\u{98}",dest).should == :finished
- dest.encoding.should == Encoding::ISO_8859_1
- end
-
- it "sets the destination buffer's encoding to the destination encoding if the conversion failed" do
- dest = "".force_encoding('utf-8')
- dest.encoding.should == Encoding::UTF_8
- @ec.primitive_convert("\u{9878}",dest).should == :undefined_conversion
- dest.encoding.should == Encoding::ISO_8859_1
- end
-
- it "removes the undefined part from the source buffer when returning :undefined_conversion" do
- dest = "".force_encoding('utf-8')
- s = "\u{9878}abcd"
- @ec.primitive_convert(s, dest).should == :undefined_conversion
-
- s.should == "abcd"
- end
-
- it "returns :incomplete_input when source buffer ends unexpectedly and :partial_input isn't specified" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- ec.primitive_convert("\xa4", "", nil, nil, partial_input: false).should == :incomplete_input
- end
-
- it "clears the source buffer when returning :incomplete_input" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- s = "\xa4"
- ec.primitive_convert(s, "").should == :incomplete_input
-
- s.should == ""
- end
-
- it "returns :source_buffer_empty when source buffer ends unexpectedly and :partial_input is true" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- ec.primitive_convert("\xa4", "", nil, nil, partial_input: true).should == :source_buffer_empty
- end
-
- it "clears the source buffer when returning :source_buffer_empty" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- s = "\xa4"
- ec.primitive_convert(s, "", nil, nil, partial_input: true).should == :source_buffer_empty
-
- s.should == ""
- end
-
- it "returns :undefined_conversion when a character in the source buffer is not representable in the output encoding" do
- @ec.primitive_convert("\u{9876}","").should == :undefined_conversion
- end
-
- it "returns :invalid_byte_sequence when an invalid byte sequence was found in the source buffer" do
- @ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
- end
-
- it "removes consumed and erroneous bytes from the source buffer when returning :invalid_byte_sequence" do
- ec = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_8_MAC)
- s = "\xC3\xA1\x80\x80\xC3\xA1".force_encoding("utf-8")
- dest = "".force_encoding("utf-8")
- ec.primitive_convert(s, dest)
-
- s.should == "\x80\xC3\xA1".force_encoding("utf-8")
- end
-
- it "returns :finished when the conversion succeeded" do
- @ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
- end
-
- it "clears the source buffer when returning :finished" do
- s = "glark".force_encoding('utf-8')
- @ec.primitive_convert(s, "").should == :finished
-
- s.should == ""
- end
-
- it "returns :destination_buffer_full when the destination buffer is too small" do
- ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
- source = "\u{9999}"
- destination_bytesize = source.bytesize - 1
- ec.primitive_convert(source, "", 0, destination_bytesize) \
- .should == :destination_buffer_full
- source.should == ""
- end
-
- it "clears the source buffer when returning :destination_buffer_full" do
- ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
- s = "\u{9999}"
- destination_bytesize = s.bytesize - 1
- ec.primitive_convert(s, "", 0, destination_bytesize).should == :destination_buffer_full
-
- s.should == ""
- end
-
- it "keeps removing invalid bytes from the source buffer" do
- ec = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_8_MAC)
- s = "\x80\x80\x80"
- dest = "".force_encoding(Encoding::UTF_8_MAC)
-
- ec.primitive_convert(s, dest)
- s.should == "\x80\x80"
- ec.primitive_convert(s, dest)
- s.should == "\x80"
- ec.primitive_convert(s, dest)
- s.should == ""
- end
-
- it "reuses read-again bytes after the first error" do
- s = "\xf1abcd"
- dest = ""
-
- @ec.primitive_convert(s, dest).should == :invalid_byte_sequence
- s.should == "bcd"
- @ec.primitive_errinfo[4].should == "a"
-
- @ec.primitive_convert(s, dest).should == :finished
- s.should == ""
-
- dest.should == "abcd"
- end
+require_relative '../../../spec_helper'
+
+describe "Encoding::Converter#primitive_convert" do
+ before :each do
+ @ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ end
+
+ it "accepts a nil source buffer" do
+ -> { @ec.primitive_convert(nil,"") }.should_not raise_error
+ end
+
+ it "accepts a String as the source buffer" do
+ -> { @ec.primitive_convert("","") }.should_not raise_error
+ end
+
+ it "accepts nil for the destination byte offset" do
+ -> { @ec.primitive_convert("","", nil) }.should_not raise_error
+ end
+
+ it "accepts an integer for the destination byte offset" do
+ -> { @ec.primitive_convert("","a", 1) }.should_not raise_error
+ end
+
+ it "calls #to_int to convert the destination byte offset" do
+ offset = mock("encoding primitive_convert destination byte offset")
+ offset.should_receive(:to_int).and_return(2)
+ @ec.primitive_convert("abc", result = " ", offset).should == :finished
+ result.should == " abc"
+ end
+
+ it "raises an ArgumentError if the destination byte offset is greater than the bytesize of the destination buffer" do
+ -> { @ec.primitive_convert("","am", 0) }.should_not raise_error
+ -> { @ec.primitive_convert("","am", 1) }.should_not raise_error
+ -> { @ec.primitive_convert("","am", 2) }.should_not raise_error
+ -> { @ec.primitive_convert("","am", 3) }.should raise_error(ArgumentError)
+ end
+
+ it "uses the destination byte offset to determine where to write the result in the destination buffer" do
+ dest = "aa"
+ @ec.primitive_convert("b",dest, nil, 0)
+ dest.should == "aa"
+
+ @ec.primitive_convert("b",dest, nil, 1)
+ dest.should == "aab"
+
+ @ec.primitive_convert("b",dest, nil, 2)
+ dest.should == "aabbb"
+ end
+
+ it "accepts nil for the destination bytesize" do
+ -> { @ec.primitive_convert("","", nil, nil) }.should_not raise_error
+ end
+
+ it "accepts an integer for the destination bytesize" do
+ -> { @ec.primitive_convert("","", nil, 0) }.should_not raise_error
+ end
+
+ it "allows a destination bytesize value greater than the bytesize of the source buffer" do
+ -> { @ec.primitive_convert("am","", nil, 3) }.should_not raise_error
+ end
+
+ it "allows a destination bytesize value less than the bytesize of the source buffer" do
+ -> { @ec.primitive_convert("am","", nil, 1) }.should_not raise_error
+ end
+
+ it "calls #to_int to convert the destination byte size" do
+ size = mock("encoding primitive_convert destination byte size")
+ size.should_receive(:to_int).and_return(2)
+ @ec.primitive_convert("abc", result = " ", 0, size).should == :destination_buffer_full
+ result.should == "ab"
+ end
+
+ it "uses destination bytesize as the maximum bytesize of the destination buffer" do
+ dest = ""
+ @ec.primitive_convert("glark", dest, nil, 1)
+ dest.bytesize.should == 1
+ end
+
+ it "allows a destination buffer of unlimited size if destination bytesize is nil" do
+ source = "glark".force_encoding('utf-8')
+ dest = ""
+ @ec.primitive_convert("glark", dest, nil, nil)
+ dest.bytesize.should == source.bytesize
+ end
+
+ it "accepts an options hash" do
+ @ec.primitive_convert("","",nil,nil, after_output: true).should == :finished
+ end
+
+ it "sets the destination buffer's encoding to the destination encoding if the conversion succeeded" do
+ dest = "".force_encoding('utf-8')
+ dest.encoding.should == Encoding::UTF_8
+ @ec.primitive_convert("\u{98}",dest).should == :finished
+ dest.encoding.should == Encoding::ISO_8859_1
+ end
+
+ it "sets the destination buffer's encoding to the destination encoding if the conversion failed" do
+ dest = "".force_encoding('utf-8')
+ dest.encoding.should == Encoding::UTF_8
+ @ec.primitive_convert("\u{9878}",dest).should == :undefined_conversion
+ dest.encoding.should == Encoding::ISO_8859_1
+ end
+
+ it "removes the undefined part from the source buffer when returning :undefined_conversion" do
+ dest = "".force_encoding('utf-8')
+ s = "\u{9878}abcd"
+ @ec.primitive_convert(s, dest).should == :undefined_conversion
+
+ s.should == "abcd"
+ end
+
+ it "returns :incomplete_input when source buffer ends unexpectedly and :partial_input isn't specified" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert("\xa4", "", nil, nil, partial_input: false).should == :incomplete_input
+ end
+
+ it "clears the source buffer when returning :incomplete_input" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ s = "\xa4"
+ ec.primitive_convert(s, "").should == :incomplete_input
+
+ s.should == ""
+ end
+
+ it "returns :source_buffer_empty when source buffer ends unexpectedly and :partial_input is true" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert("\xa4", "", nil, nil, partial_input: true).should == :source_buffer_empty
+ end
+
+ it "clears the source buffer when returning :source_buffer_empty" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ s = "\xa4"
+ ec.primitive_convert(s, "", nil, nil, partial_input: true).should == :source_buffer_empty
+
+ s.should == ""
+ end
+
+ it "returns :undefined_conversion when a character in the source buffer is not representable in the output encoding" do
+ @ec.primitive_convert("\u{9876}","").should == :undefined_conversion
+ end
+
+ it "returns :invalid_byte_sequence when an invalid byte sequence was found in the source buffer" do
+ @ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
+ end
+
+ it "removes consumed and erroneous bytes from the source buffer when returning :invalid_byte_sequence" do
+ ec = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_8_MAC)
+ s = "\xC3\xA1\x80\x80\xC3\xA1".force_encoding("utf-8")
+ dest = "".force_encoding("utf-8")
+ ec.primitive_convert(s, dest)
+
+ s.should == "\x80\xC3\xA1".force_encoding("utf-8")
+ end
+
+ it "returns :finished when the conversion succeeded" do
+ @ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
+ end
+
+ it "clears the source buffer when returning :finished" do
+ s = "glark".force_encoding('utf-8')
+ @ec.primitive_convert(s, "").should == :finished
+
+ s.should == ""
+ end
+
+ it "returns :destination_buffer_full when the destination buffer is too small" do
+ ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
+ source = "\u{9999}"
+ destination_bytesize = source.bytesize - 1
+ ec.primitive_convert(source, "", 0, destination_bytesize) \
+ .should == :destination_buffer_full
+ source.should == ""
+ end
+
+ it "clears the source buffer when returning :destination_buffer_full" do
+ ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
+ s = "\u{9999}"
+ destination_bytesize = s.bytesize - 1
+ ec.primitive_convert(s, "", 0, destination_bytesize).should == :destination_buffer_full
+
+ s.should == ""
+ end
+
+ it "keeps removing invalid bytes from the source buffer" do
+ ec = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_8_MAC)
+ s = "\x80\x80\x80"
+ dest = "".force_encoding(Encoding::UTF_8_MAC)
+
+ ec.primitive_convert(s, dest)
+ s.should == "\x80\x80"
+ ec.primitive_convert(s, dest)
+ s.should == "\x80"
+ ec.primitive_convert(s, dest)
+ s.should == ""
+ end
+
+ it "reuses read-again bytes after the first error" do
+ s = "\xf1abcd"
+ dest = ""
+
+ @ec.primitive_convert(s, dest).should == :invalid_byte_sequence
+ s.should == "bcd"
+ @ec.primitive_errinfo[4].should == "a"
+
+ @ec.primitive_convert(s, dest).should == :finished
+ s.should == ""
+
+ dest.should == "abcd"
end
end
diff --git a/spec/ruby/core/encoding/converter/primitive_errinfo_spec.rb b/spec/ruby/core/encoding/converter/primitive_errinfo_spec.rb
index f92c95c6d5..1f836b259f 100644
--- a/spec/ruby/core/encoding/converter/primitive_errinfo_spec.rb
+++ b/spec/ruby/core/encoding/converter/primitive_errinfo_spec.rb
@@ -1,72 +1,68 @@
# -*- encoding: binary -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#primitive_errinfo" do
- it "returns [:source_buffer_empty,nil,nil,nil,nil] when no conversion has been attempted" do
- ec = Encoding::Converter.new('ascii','utf-8')
- ec.primitive_errinfo.should == [:source_buffer_empty, nil, nil, nil, nil]
- end
+describe "Encoding::Converter#primitive_errinfo" do
+ it "returns [:source_buffer_empty,nil,nil,nil,nil] when no conversion has been attempted" do
+ ec = Encoding::Converter.new('ascii','utf-8')
+ ec.primitive_errinfo.should == [:source_buffer_empty, nil, nil, nil, nil]
+ end
- it "returns [:finished,nil,nil,nil,nil] when #primitive_convert last returned :finished" do
- ec = Encoding::Converter.new('ascii','utf-8')
- ec.primitive_convert("a","").should == :finished
- ec.primitive_errinfo.should == [:finished, nil, nil, nil, nil]
- end
+ it "returns [:finished,nil,nil,nil,nil] when #primitive_convert last returned :finished" do
+ ec = Encoding::Converter.new('ascii','utf-8')
+ ec.primitive_convert("a","").should == :finished
+ ec.primitive_errinfo.should == [:finished, nil, nil, nil, nil]
+ end
- it "returns [:source_buffer_empty,nil,nil,nil, nil] when #convert last succeeded" do
- ec = Encoding::Converter.new('ascii','utf-8')
- ec.convert("a".force_encoding('ascii')).should == "a".\
- force_encoding('utf-8')
- ec.primitive_errinfo.should == [:source_buffer_empty, nil, nil, nil, nil]
- end
+ it "returns [:source_buffer_empty,nil,nil,nil, nil] when #convert last succeeded" do
+ ec = Encoding::Converter.new('ascii','utf-8')
+ ec.convert("a".force_encoding('ascii')).should == "a".force_encoding('utf-8')
+ ec.primitive_errinfo.should == [:source_buffer_empty, nil, nil, nil, nil]
+ end
- it "returns [:destination_buffer_full,nil,nil,nil,nil] when #primitive_convert last returned :destination_buffer_full" do
- ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
- ec.primitive_convert("\u{9999}", "", 0, 0, partial_input: false) \
- .should == :destination_buffer_full
- ec.primitive_errinfo.should == [:destination_buffer_full, nil, nil, nil, nil]
- end
+ it "returns [:destination_buffer_full,nil,nil,nil,nil] when #primitive_convert last returned :destination_buffer_full" do
+ ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
+ ec.primitive_convert("\u{9999}", "", 0, 0, partial_input: false).should == :destination_buffer_full
+ ec.primitive_errinfo.should == [:destination_buffer_full, nil, nil, nil, nil]
+ end
- it "returns the status of the last primitive conversion, even if it was successful and the previous one wasn't" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
- ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
- ec.primitive_errinfo.should == [:finished, nil, nil, nil, nil]
- end
+ it "returns the status of the last primitive conversion, even if it was successful and the previous one wasn't" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
+ ec.primitive_convert("glark".force_encoding('utf-8'),"").should == :finished
+ ec.primitive_errinfo.should == [:finished, nil, nil, nil, nil]
+ end
- it "returns the state, source encoding, target encoding, and the erroneous bytes when #primitive_convert last returned :undefined_conversion" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- ec.primitive_convert("\u{9876}","").should == :undefined_conversion
- ec.primitive_errinfo.should ==
- [:undefined_conversion, "UTF-8", "ISO-8859-1", "\xE9\xA1\xB6", ""]
- end
+ it "returns the state, source encoding, target encoding, and the erroneous bytes when #primitive_convert last returned :undefined_conversion" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ ec.primitive_convert("\u{9876}","").should == :undefined_conversion
+ ec.primitive_errinfo.should ==
+ [:undefined_conversion, "UTF-8", "ISO-8859-1", "\xE9\xA1\xB6", ""]
+ end
- it "returns the state, source encoding, target encoding, and erroneous bytes when #primitive_convert last returned :incomplete_input" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- ec.primitive_convert("\xa4", "", nil, 10).should == :incomplete_input
- ec.primitive_errinfo.should == [:incomplete_input, "EUC-JP", "UTF-8", "\xA4", ""]
- end
+ it "returns the state, source encoding, target encoding, and erroneous bytes when #primitive_convert last returned :incomplete_input" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert("\xa4", "", nil, 10).should == :incomplete_input
+ ec.primitive_errinfo.should == [:incomplete_input, "EUC-JP", "UTF-8", "\xA4", ""]
+ end
- it "returns the state, source encoding, target encoding, erroneous bytes, and the read-again bytes when #primitive_convert last returned :invalid_byte_sequence" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
- ec.primitive_errinfo.should ==
- [:invalid_byte_sequence, "UTF-8", "ISO-8859-1", "\xF1", "a"]
- end
+ it "returns the state, source encoding, target encoding, erroneous bytes, and the read-again bytes when #primitive_convert last returned :invalid_byte_sequence" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ ec.primitive_convert("\xf1abcd","").should == :invalid_byte_sequence
+ ec.primitive_errinfo.should ==
+ [:invalid_byte_sequence, "UTF-8", "ISO-8859-1", "\xF1", "a"]
+ end
- it "returns the state, source encoding, target encoding, erroneous bytes, and the read-again bytes when #convert last raised InvalidByteSequenceError" do
- ec = Encoding::Converter.new("utf-8", "iso-8859-1")
- lambda { ec.convert("\xf1abcd") }.should raise_error(Encoding::InvalidByteSequenceError)
- ec.primitive_errinfo.should ==
- [:invalid_byte_sequence, "UTF-8", "ISO-8859-1", "\xF1", "a"]
- end
+ it "returns the state, source encoding, target encoding, erroneous bytes, and the read-again bytes when #convert last raised InvalidByteSequenceError" do
+ ec = Encoding::Converter.new("utf-8", "iso-8859-1")
+ -> { ec.convert("\xf1abcd") }.should raise_error(Encoding::InvalidByteSequenceError)
+ ec.primitive_errinfo.should ==
+ [:invalid_byte_sequence, "UTF-8", "ISO-8859-1", "\xF1", "a"]
+ end
- it "returns the state, source encoding, target encoding, erroneous bytes, and the read-again bytes when #finish last raised InvalidByteSequenceError" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- ec.convert("\xa4")
- lambda { ec.finish }.should raise_error(Encoding::InvalidByteSequenceError)
- ec.primitive_errinfo.should == [:incomplete_input, "EUC-JP", "UTF-8", "\xA4", ""]
- end
+ it "returns the state, source encoding, target encoding, erroneous bytes, and the read-again bytes when #finish last raised InvalidByteSequenceError" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.convert("\xa4")
+ -> { ec.finish }.should raise_error(Encoding::InvalidByteSequenceError)
+ ec.primitive_errinfo.should == [:incomplete_input, "EUC-JP", "UTF-8", "\xA4", ""]
end
end
diff --git a/spec/ruby/core/encoding/converter/putback_spec.rb b/spec/ruby/core/encoding/converter/putback_spec.rb
index 69ce59e89b..87495eaf3f 100644
--- a/spec/ruby/core/encoding/converter/putback_spec.rb
+++ b/spec/ruby/core/encoding/converter/putback_spec.rb
@@ -1,50 +1,47 @@
# -*- encoding: binary -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#putback" do
- before :each do
- @ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- @ret = @ec.primitive_convert(@src="abc\xa1def", @dst="", nil, 10)
- end
+describe "Encoding::Converter#putback" do
+ before :each do
+ @ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ @ret = @ec.primitive_convert(@src="abc\xa1def", @dst="", nil, 10)
+ end
- it "returns a String" do
- @ec.putback.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @ec.putback.should be_an_instance_of(String)
+ end
- it "returns a String in the source encoding" do
- @ec.putback.encoding.should == Encoding::EUC_JP
- end
+ it "returns a String in the source encoding" do
+ @ec.putback.encoding.should == Encoding::EUC_JP
+ end
- it "returns the bytes buffered due to an :invalid_byte_sequence error" do
- @ret.should == :invalid_byte_sequence
- @ec.putback.should == 'd'
- @ec.primitive_errinfo.last.should == 'd'
- end
+ it "returns the bytes buffered due to an :invalid_byte_sequence error" do
+ @ret.should == :invalid_byte_sequence
+ @ec.putback.should == 'd'
+ @ec.primitive_errinfo.last.should == 'd'
+ end
- it "allows conversion to be resumed after an :invalid_byte_sequence" do
- @src = @ec.putback + @src
- @ret = @ec.primitive_convert(@src, @dst, nil, 10)
- @ret.should == :finished
- @dst.should == "abcdef"
- @src.should == ""
- end
+ it "allows conversion to be resumed after an :invalid_byte_sequence" do
+ @src = @ec.putback + @src
+ @ret = @ec.primitive_convert(@src, @dst, nil, 10)
+ @ret.should == :finished
+ @dst.should == "abcdef"
+ @src.should == ""
+ end
- it "returns an empty String when there are no more bytes to put back" do
- @ec.putback
- @ec.putback.should == ""
- end
+ it "returns an empty String when there are no more bytes to put back" do
+ @ec.putback
+ @ec.putback.should == ""
+ end
- it "accepts an integer argument corresponding to the number of bytes to be put back" do
- ec = Encoding::Converter.new("utf-16le", "iso-8859-1")
- src = "\x00\xd8\x61\x00"
- dst = ""
- ec.primitive_convert(src, dst).should == :invalid_byte_sequence
- ec.primitive_errinfo.should ==
- [:invalid_byte_sequence, "UTF-16LE", "UTF-8", "\x00\xD8", "a\x00"]
- ec.putback(1).should == "\x00".force_encoding("utf-16le")
- ec.putback.should == "a".force_encoding("utf-16le")
- ec.putback.should == ""
- end
+ it "accepts an integer argument corresponding to the number of bytes to be put back" do
+ ec = Encoding::Converter.new("utf-16le", "iso-8859-1")
+ src = "\x00\xd8\x61\x00"
+ dst = ""
+ ec.primitive_convert(src, dst).should == :invalid_byte_sequence
+ ec.primitive_errinfo.should == [:invalid_byte_sequence, "UTF-16LE", "UTF-8", "\x00\xD8", "a\x00"]
+ ec.putback(1).should == "\x00".force_encoding("utf-16le")
+ ec.putback.should == "a".force_encoding("utf-16le")
+ ec.putback.should == ""
end
end
diff --git a/spec/ruby/core/encoding/converter/replacement_spec.rb b/spec/ruby/core/encoding/converter/replacement_spec.rb
index 9c25887cd7..5ca42e7e5a 100644
--- a/spec/ruby/core/encoding/converter/replacement_spec.rb
+++ b/spec/ruby/core/encoding/converter/replacement_spec.rb
@@ -1,74 +1,72 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#replacement" do
- it "returns '?' in US-ASCII when the destination encoding is not UTF-8" do
- ec = Encoding::Converter.new("utf-8", "us-ascii")
- ec.replacement.should == "?"
- ec.replacement.encoding.should == Encoding::US_ASCII
+describe "Encoding::Converter#replacement" do
+ it "returns '?' in US-ASCII when the destination encoding is not UTF-8" do
+ ec = Encoding::Converter.new("utf-8", "us-ascii")
+ ec.replacement.should == "?"
+ ec.replacement.encoding.should == Encoding::US_ASCII
- ec = Encoding::Converter.new("utf-8", "sjis")
- ec.replacement.should == "?"
- ec.replacement.encoding.should == Encoding::US_ASCII
- end
+ ec = Encoding::Converter.new("utf-8", "sjis")
+ ec.replacement.should == "?"
+ ec.replacement.encoding.should == Encoding::US_ASCII
+ end
- it "returns \\uFFFD when the destination encoding is UTF-8" do
- ec = Encoding::Converter.new("us-ascii", "utf-8")
- ec.replacement.should == "\u{fffd}".force_encoding('utf-8')
- ec.replacement.encoding.should == Encoding::UTF_8
- end
+ it "returns \\uFFFD when the destination encoding is UTF-8" do
+ ec = Encoding::Converter.new("us-ascii", "utf-8")
+ ec.replacement.should == "\u{fffd}".force_encoding('utf-8')
+ ec.replacement.encoding.should == Encoding::UTF_8
end
+end
- describe "Encoding::Converter#replacement=" do
- it "accepts a String argument" do
- ec = Encoding::Converter.new("utf-8", "us-ascii")
- ec.replacement = "!"
- ec.replacement.should == "!"
- end
+describe "Encoding::Converter#replacement=" do
+ it "accepts a String argument" do
+ ec = Encoding::Converter.new("utf-8", "us-ascii")
+ ec.replacement = "!"
+ ec.replacement.should == "!"
+ end
- it "accepts a String argument of arbitrary length" do
- ec = Encoding::Converter.new("utf-8", "us-ascii")
- ec.replacement = "?!?" * 9999
- ec.replacement.should == "?!?" * 9999
- end
+ it "accepts a String argument of arbitrary length" do
+ ec = Encoding::Converter.new("utf-8", "us-ascii")
+ ec.replacement = "?!?" * 9999
+ ec.replacement.should == "?!?" * 9999
+ end
- it "raises a TypeError if assigned a non-String argument" do
- ec = Encoding::Converter.new("utf-8", "us-ascii")
- lambda { ec.replacement = nil }.should raise_error(TypeError)
- end
+ it "raises a TypeError if assigned a non-String argument" do
+ ec = Encoding::Converter.new("utf-8", "us-ascii")
+ -> { ec.replacement = nil }.should raise_error(TypeError)
+ end
- it "sets #replacement" do
- ec = Encoding::Converter.new("us-ascii", "utf-8")
- ec.replacement.should == "\u{fffd}".force_encoding('utf-8')
- ec.replacement = '?'.encode('utf-8')
- ec.replacement.should == '?'.force_encoding('utf-8')
- end
+ it "sets #replacement" do
+ ec = Encoding::Converter.new("us-ascii", "utf-8")
+ ec.replacement.should == "\u{fffd}".force_encoding('utf-8')
+ ec.replacement = '?'.encode('utf-8')
+ ec.replacement.should == '?'.force_encoding('utf-8')
+ end
- it "raises an UndefinedConversionError is the argument cannot be converted into the destination encoding" do
- ec = Encoding::Converter.new("sjis", "ascii")
- utf8_q = "\u{986}".force_encoding('utf-8')
- ec.primitive_convert(utf8_q.dup, "").should == :undefined_conversion
- lambda { ec.replacement = utf8_q }.should \
- raise_error(Encoding::UndefinedConversionError)
- end
+ it "raises an UndefinedConversionError is the argument cannot be converted into the destination encoding" do
+ ec = Encoding::Converter.new("sjis", "ascii")
+ utf8_q = "\u{986}".force_encoding('utf-8')
+ ec.primitive_convert(utf8_q.dup, "").should == :undefined_conversion
+ -> { ec.replacement = utf8_q }.should \
+ raise_error(Encoding::UndefinedConversionError)
+ end
- it "does not change the replacement character if the argument cannot be converted into the destination encoding" do
- ec = Encoding::Converter.new("sjis", "ascii")
- utf8_q = "\u{986}".force_encoding('utf-8')
- ec.primitive_convert(utf8_q.dup, "").should == :undefined_conversion
- lambda { ec.replacement = utf8_q }.should \
- raise_error(Encoding::UndefinedConversionError)
- ec.replacement.should == "?".force_encoding('us-ascii')
- end
+ it "does not change the replacement character if the argument cannot be converted into the destination encoding" do
+ ec = Encoding::Converter.new("sjis", "ascii")
+ utf8_q = "\u{986}".force_encoding('utf-8')
+ ec.primitive_convert(utf8_q.dup, "").should == :undefined_conversion
+ -> { ec.replacement = utf8_q }.should \
+ raise_error(Encoding::UndefinedConversionError)
+ ec.replacement.should == "?".force_encoding('us-ascii')
+ end
- it "uses the replacement character" do
- ec = Encoding::Converter.new("utf-8", "us-ascii", :invalid => :replace, :undef => :replace)
- ec.replacement = "!"
- dest = ""
- status = ec.primitive_convert "中文123", dest
+ it "uses the replacement character" do
+ ec = Encoding::Converter.new("utf-8", "us-ascii", :invalid => :replace, :undef => :replace)
+ ec.replacement = "!"
+ dest = ""
+ status = ec.primitive_convert "中文123", dest
- status.should == :finished
- dest.should == "!!123"
- end
+ status.should == :finished
+ dest.should == "!!123"
end
end
diff --git a/spec/ruby/core/encoding/converter/search_convpath_spec.rb b/spec/ruby/core/encoding/converter/search_convpath_spec.rb
index c04eeb98ad..0882af5539 100644
--- a/spec/ruby/core/encoding/converter/search_convpath_spec.rb
+++ b/spec/ruby/core/encoding/converter/search_convpath_spec.rb
@@ -1,73 +1,30 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter.search_convpath" do
- before :all do
- @perms = Encoding.name_list.permutation(2).map do |pair|
- Encoding::Converter.search_convpath(pair.first, pair.last) rescue []
- end
- end
-
- it "returns an Array" do
- Encoding::Converter.search_convpath('ASCII', 'EUC-JP').\
- should be_an_instance_of(Array)
- end
-
- it "returns each encoding pair as a sub-Array" do
- cp = Encoding::Converter.search_convpath('ASCII', 'EUC-JP')
- cp.first.should be_an_instance_of(Array)
- cp.first.size.should == 2
- end
-
- it "returns each encoding as an Encoding object" do
- cp = Encoding::Converter.search_convpath('ASCII', 'EUC-JP')
- cp.first.first.should be_an_instance_of(Encoding)
- cp.first.last.should be_an_instance_of(Encoding)
- end
-
- it "returns multiple encoding pairs when direct conversion is impossible" do
- cp = Encoding::Converter.search_convpath('ascii','Big5')
- cp.size.should == 2
- cp.first.should == [Encoding::US_ASCII, Encoding::UTF_8]
- cp.last.should == [Encoding::UTF_8, Encoding::Big5]
- end
-
- it "sets the last element of each pair to the first element of the next" do
- @perms.each do |convpath|
- next if convpath.size == 1
- convpath.each_with_index do |pair, idx|
- break if idx == convpath.size - 1
- pair.last.should == convpath[idx+1].first
- end
- end
- end
+describe "Encoding::Converter.search_convpath" do
+ it "returns an Array with a single element if there is a direct converter" do
+ cp = Encoding::Converter.search_convpath('ASCII', 'UTF-8')
+ cp.should == [[Encoding::US_ASCII, Encoding::UTF_8]]
+ end
- it "only lists a source encoding once" do
- @perms.each do |convpath|
- next if convpath.size < 2
- seen = Hash.new(false)
- convpath.each_with_index do |pair, idx|
- seen.key?(pair.first).should be_false if idx > 0
- seen[pair.first] = true
- end
- end
- end
+ it "returns multiple encoding pairs when direct conversion is impossible" do
+ cp = Encoding::Converter.search_convpath('ascii','Big5')
+ cp.should == [
+ [Encoding::US_ASCII, Encoding::UTF_8],
+ [Encoding::UTF_8, Encoding::Big5]
+ ]
+ end
- it "indicates if crlf_newline conversion would occur" do
- cp = Encoding::Converter.search_convpath(
- "ISo-8859-1", "EUC-JP", {crlf_newline: true})
- cp.last.should == "crlf_newline"
+ it "indicates if crlf_newline conversion would occur" do
+ cp = Encoding::Converter.search_convpath("ISO-8859-1", "EUC-JP", crlf_newline: true)
+ cp.last.should == "crlf_newline"
- cp = Encoding::Converter.search_convpath(
- "ASCII", "UTF-8", {crlf_newline: false})
- cp.last.should_not == "crlf_newline"
- end
+ cp = Encoding::Converter.search_convpath("ASCII", "UTF-8", crlf_newline: false)
+ cp.last.should_not == "crlf_newline"
+ end
- it "raises an Encoding::ConverterNotFoundError if no conversion path exists" do
- lambda do
- Encoding::Converter.search_convpath(
- Encoding::ASCII_8BIT, Encoding::Emacs_Mule)
- end.should raise_error(Encoding::ConverterNotFoundError)
- end
+ it "raises an Encoding::ConverterNotFoundError if no conversion path exists" do
+ -> do
+ Encoding::Converter.search_convpath(Encoding::BINARY, Encoding::Emacs_Mule)
+ end.should raise_error(Encoding::ConverterNotFoundError)
end
end
diff --git a/spec/ruby/core/encoding/converter/source_encoding_spec.rb b/spec/ruby/core/encoding/converter/source_encoding_spec.rb
index acec01502d..6196f717bd 100644
--- a/spec/ruby/core/encoding/converter/source_encoding_spec.rb
+++ b/spec/ruby/core/encoding/converter/source_encoding_spec.rb
@@ -1,13 +1,11 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::Converter#source_encoding" do
- it "returns the source encoding as an Encoding object" do
- ec = Encoding::Converter.new('ASCII','Big5')
- ec.source_encoding.should == Encoding::US_ASCII
+describe "Encoding::Converter#source_encoding" do
+ it "returns the source encoding as an Encoding object" do
+ ec = Encoding::Converter.new('ASCII','Big5')
+ ec.source_encoding.should == Encoding::US_ASCII
- ec = Encoding::Converter.new('Shift_JIS','EUC-JP')
- ec.source_encoding.should == Encoding::SHIFT_JIS
- end
+ ec = Encoding::Converter.new('Shift_JIS','EUC-JP')
+ ec.source_encoding.should == Encoding::SHIFT_JIS
end
end
diff --git a/spec/ruby/core/encoding/default_external_spec.rb b/spec/ruby/core/encoding/default_external_spec.rb
index 2b026c793f..e2cb9b02f4 100644
--- a/spec/ruby/core/encoding/default_external_spec.rb
+++ b/spec/ruby/core/encoding/default_external_spec.rb
@@ -1,74 +1,63 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding.default_external" do
- before :each do
- @original_encoding = Encoding.default_external
- end
-
- after :each do
- Encoding.default_external = @original_encoding
- end
-
- it "returns an Encoding object" do
- Encoding.default_external.should be_an_instance_of(Encoding)
- end
+describe "Encoding.default_external" do
+ before :each do
+ @original_encoding = Encoding.default_external
+ end
- it "returns the default external encoding" do
- Encoding.default_external = Encoding::UTF_8
- Encoding.default_external.should == Encoding::UTF_8
- end
+ after :each do
+ Encoding.default_external = @original_encoding
+ end
- describe "with command line options" do
- it "is not changed by the -U option" do
- result = ruby_exe("print Encoding.default_external", options: '-U')
- result.should == Encoding.default_external.name
- end
+ it "returns an Encoding object" do
+ Encoding.default_external.should be_an_instance_of(Encoding)
+ end
- it "returns the encoding specified by '-E external'" do
- result = ruby_exe("print Encoding.default_external", options: '-E euc-jp')
- result.should == "EUC-JP"
- end
+ it "returns the default external encoding" do
+ Encoding.default_external = Encoding::SHIFT_JIS
+ Encoding.default_external.should == Encoding::SHIFT_JIS
+ end
+end
- it "returns the encoding specified by '-E external:'" do
- result = ruby_exe("print Encoding.default_external", options: '-E Shift_JIS:')
- result.should == "Shift_JIS"
- end
- end
+describe "Encoding.default_external=" do
+ before :each do
+ @original_encoding = Encoding.default_external
end
- describe "Encoding.default_external=" do
- before :each do
- @original_encoding = Encoding.default_external
- end
+ after :each do
+ Encoding.default_external = @original_encoding
+ end
- after :each do
- Encoding.default_external = @original_encoding
- end
+ it "sets the default external encoding" do
+ Encoding.default_external = Encoding::SHIFT_JIS
+ Encoding.default_external.should == Encoding::SHIFT_JIS
+ Encoding.find('external').should == Encoding::SHIFT_JIS
+ end
- it "sets the default external encoding" do
- Encoding.default_external = Encoding::UTF_8
- Encoding.default_external.should == Encoding::UTF_8
+ platform_is_not :windows do
+ it "also sets the filesystem encoding" do
+ Encoding.default_external = Encoding::SHIFT_JIS
+ Encoding.find('filesystem').should == Encoding::SHIFT_JIS
end
+ end
- it "can accept a name of an encoding as a String" do
- Encoding.default_external = 'Shift_JIS'
- Encoding.default_external.should == Encoding::SHIFT_JIS
- end
+ it "can accept a name of an encoding as a String" do
+ Encoding.default_external = 'Shift_JIS'
+ Encoding.default_external.should == Encoding::SHIFT_JIS
+ end
- it "calls #to_s on arguments that are neither Strings nor Encodings" do
- string = mock('string')
- string.should_receive(:to_str).at_least(1).and_return('US-ASCII')
- Encoding.default_external = string
- Encoding.default_external.should == Encoding::ASCII
- end
+ it "calls #to_s on arguments that are neither Strings nor Encodings" do
+ string = mock('string')
+ string.should_receive(:to_str).at_least(1).and_return('US-ASCII')
+ Encoding.default_external = string
+ Encoding.default_external.should == Encoding::ASCII
+ end
- it "raises a TypeError unless the argument is an Encoding or convertible to a String" do
- lambda { Encoding.default_external = [] }.should raise_error(TypeError)
- end
+ it "raises a TypeError unless the argument is an Encoding or convertible to a String" do
+ -> { Encoding.default_external = [] }.should raise_error(TypeError)
+ end
- it "raises an ArgumentError if the argument is nil" do
- lambda { Encoding.default_external = nil }.should raise_error(ArgumentError)
- end
+ it "raises an ArgumentError if the argument is nil" do
+ -> { Encoding.default_external = nil }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/encoding/default_internal_spec.rb b/spec/ruby/core/encoding/default_internal_spec.rb
index 3234929eec..855f4e9f32 100644
--- a/spec/ruby/core/encoding/default_internal_spec.rb
+++ b/spec/ruby/core/encoding/default_internal_spec.rb
@@ -1,93 +1,74 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-with_feature :encoding do
- describe "Encoding.default_internal" do
- before :each do
- @original_encoding = Encoding.default_internal
- end
-
- after :each do
- Encoding.default_internal = @original_encoding
- end
-
- it "is nil by default" do
- Encoding.default_internal.should be_nil
- end
-
- it "returns an Encoding object if a default internal encoding is set" do
- Encoding.default_internal = Encoding::ASCII
- Encoding.default_internal.should be_an_instance_of(Encoding)
- end
-
- it "returns nil if no default internal encoding is set" do
- Encoding.default_internal = nil
- Encoding.default_internal.should be_nil
- end
-
- it "returns the default internal encoding" do
- Encoding.default_internal = Encoding::ASCII_8BIT
- Encoding.default_internal.should == Encoding::ASCII_8BIT
- end
-
- describe "with command line options" do
- it "returns Encoding::UTF_8 if ruby was invoked with -U" do
- ruby_exe("print Encoding.default_internal", options: '-U').
- should == 'UTF-8'
- end
-
- it "uses the encoding specified when ruby is invoked with an '-E :internal' argument" do
- ruby_exe("print Encoding.default_internal", options: '-E :SHIFT_JIS').
- should == 'Shift_JIS'
- end
-
- it "uses the encoding specified when ruby is invoked with an '-E external:internal' argument" do
- ruby_exe("print Encoding.default_internal", options: '-E UTF-8:SHIFT_JIS').
- should == 'Shift_JIS'
- end
- end
+require_relative '../../spec_helper'
+
+describe "Encoding.default_internal" do
+ before :each do
+ @original_encoding = Encoding.default_internal
end
- describe "Encoding.default_internal=" do
- before :each do
- @original_encoding = Encoding.default_internal
- end
+ after :each do
+ Encoding.default_internal = @original_encoding
+ end
- after :each do
- Encoding.default_internal = @original_encoding
- end
+ it "is nil by default" do
+ Encoding.default_internal.should be_nil
+ end
- it "sets the default internal encoding" do
- Encoding.default_internal = Encoding::SHIFT_JIS
- Encoding.default_internal.should == Encoding::SHIFT_JIS
- end
+ it "returns an Encoding object if a default internal encoding is set" do
+ Encoding.default_internal = Encoding::ASCII
+ Encoding.default_internal.should be_an_instance_of(Encoding)
+ end
- it "can accept a name of an encoding as a String" do
- Encoding.default_internal = 'Shift_JIS'
- Encoding.default_internal.should == Encoding::SHIFT_JIS
- end
+ it "returns nil if no default internal encoding is set" do
+ Encoding.default_internal = nil
+ Encoding.default_internal.should be_nil
+ end
- it "calls #to_str to convert an object to a String" do
- obj = mock('string')
- obj.should_receive(:to_str).at_least(1).times.and_return('ascii')
+ it "returns the default internal encoding" do
+ Encoding.default_internal = Encoding::BINARY
+ Encoding.default_internal.should == Encoding::BINARY
+ end
+end
- Encoding.default_internal = obj
- Encoding.default_internal.should == Encoding::ASCII
- end
+describe "Encoding.default_internal=" do
+ before :each do
+ @original_encoding = Encoding.default_internal
+ end
- it "raises a TypeError if #to_str does not return a String" do
- obj = mock('string')
- obj.should_receive(:to_str).at_least(1).times.and_return(1)
+ after :each do
+ Encoding.default_internal = @original_encoding
+ end
- lambda { Encoding.default_internal = obj }.should raise_error(TypeError)
- end
+ it "sets the default internal encoding" do
+ Encoding.default_internal = Encoding::SHIFT_JIS
+ Encoding.default_internal.should == Encoding::SHIFT_JIS
+ end
- it "raises a TypeError when passed an object not providing #to_str" do
- lambda { Encoding.default_internal = mock("encoding") }.should raise_error(TypeError)
- end
+ it "can accept a name of an encoding as a String" do
+ Encoding.default_internal = 'Shift_JIS'
+ Encoding.default_internal.should == Encoding::SHIFT_JIS
+ end
+
+ it "calls #to_str to convert an object to a String" do
+ obj = mock('string')
+ obj.should_receive(:to_str).at_least(1).times.and_return('ascii')
+
+ Encoding.default_internal = obj
+ Encoding.default_internal.should == Encoding::ASCII
+ end
+
+ it "raises a TypeError if #to_str does not return a String" do
+ obj = mock('string')
+ obj.should_receive(:to_str).at_least(1).times.and_return(1)
+
+ -> { Encoding.default_internal = obj }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError when passed an object not providing #to_str" do
+ -> { Encoding.default_internal = mock("encoding") }.should raise_error(TypeError)
+ end
- it "accepts an argument of nil to unset the default internal encoding" do
- Encoding.default_internal = nil
- Encoding.default_internal.should be_nil
- end
+ it "accepts an argument of nil to unset the default internal encoding" do
+ Encoding.default_internal = nil
+ Encoding.default_internal.should be_nil
end
end
diff --git a/spec/ruby/core/encoding/dummy_spec.rb b/spec/ruby/core/encoding/dummy_spec.rb
index 7917c71e47..75ffcd5a4e 100644
--- a/spec/ruby/core/encoding/dummy_spec.rb
+++ b/spec/ruby/core/encoding/dummy_spec.rb
@@ -1,16 +1,14 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding#dummy?" do
- it "returns false for proper encodings" do
- Encoding::UTF_8.dummy?.should be_false
- Encoding::ASCII.dummy?.should be_false
- end
+describe "Encoding#dummy?" do
+ it "returns false for proper encodings" do
+ Encoding::UTF_8.dummy?.should be_false
+ Encoding::ASCII.dummy?.should be_false
+ end
- it "returns true for dummy encodings" do
- Encoding::ISO_2022_JP.dummy?.should be_true
- Encoding::CP50221.dummy?.should be_true
- Encoding::UTF_7.dummy?.should be_true
- end
+ it "returns true for dummy encodings" do
+ Encoding::ISO_2022_JP.dummy?.should be_true
+ Encoding::CP50221.dummy?.should be_true
+ Encoding::UTF_7.dummy?.should be_true
end
end
diff --git a/spec/ruby/core/encoding/find_spec.rb b/spec/ruby/core/encoding/find_spec.rb
index bd195f6a1a..8a0873070f 100644
--- a/spec/ruby/core/encoding/find_spec.rb
+++ b/spec/ruby/core/encoding/find_spec.rb
@@ -1,84 +1,82 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding.find" do
- before :all do
- @encodings = Encoding.aliases.to_a.flatten.uniq
- end
+describe "Encoding.find" do
+ before :all do
+ @encodings = Encoding.aliases.to_a.flatten.uniq
+ end
- it "returns the corresponding Encoding object if given a valid encoding name" do
- @encodings.each do |enc|
- Encoding.find(enc).should be_an_instance_of(Encoding)
- end
+ it "returns the corresponding Encoding object if given a valid encoding name" do
+ @encodings.each do |enc|
+ Encoding.find(enc).should be_an_instance_of(Encoding)
end
+ end
- it "returns the corresponding Encoding object if given a valid alias name" do
- Encoding.aliases.keys.each do |enc_alias|
- Encoding.find(enc_alias).should be_an_instance_of(Encoding)
- end
+ it "returns the corresponding Encoding object if given a valid alias name" do
+ Encoding.aliases.keys.each do |enc_alias|
+ Encoding.find(enc_alias).should be_an_instance_of(Encoding)
end
+ end
- it "raises a TypeError if passed a Symbol" do
- lambda { Encoding.find(:"utf-8") }.should raise_error(TypeError)
- end
+ it "raises a TypeError if passed a Symbol" do
+ -> { Encoding.find(:"utf-8") }.should raise_error(TypeError)
+ end
- it "returns the passed Encoding object" do
- Encoding.find(Encoding::UTF_8).should == Encoding::UTF_8
- end
+ it "returns the passed Encoding object" do
+ Encoding.find(Encoding::UTF_8).should == Encoding::UTF_8
+ end
- it "accepts encoding names as Strings" do
- Encoding.list.each do |enc|
- Encoding.find(enc.name).should == enc
- end
+ it "accepts encoding names as Strings" do
+ Encoding.list.each do |enc|
+ Encoding.find(enc.name).should == enc
end
+ end
- it "accepts any object as encoding name, if it responds to #to_str" do
- obj = Class.new do
- attr_writer :encoding_name
- def to_str; @encoding_name; end
- end.new
+ it "accepts any object as encoding name, if it responds to #to_str" do
+ obj = Class.new do
+ attr_writer :encoding_name
+ def to_str; @encoding_name; end
+ end.new
- Encoding.list.each do |enc|
- obj.encoding_name = enc.name
- Encoding.find(obj).should == enc
- end
+ Encoding.list.each do |enc|
+ obj.encoding_name = enc.name
+ Encoding.find(obj).should == enc
end
+ end
- it "is case insensitive" do
- @encodings.each do |enc|
- Encoding.find(enc.upcase).should == Encoding.find(enc)
- end
+ it "is case insensitive" do
+ @encodings.each do |enc|
+ Encoding.find(enc.upcase).should == Encoding.find(enc)
end
+ end
- it "raises an ArgumentError if the given encoding does not exist" do
- lambda { Encoding.find('dh2dh278d') }.should raise_error(ArgumentError)
- end
+ it "raises an ArgumentError if the given encoding does not exist" do
+ -> { Encoding.find('dh2dh278d') }.should raise_error(ArgumentError)
+ end
- # Not sure how to do a better test, since locale depends on weird platform-specific stuff
- it "supports the 'locale' encoding alias" do
- enc = Encoding.find('locale')
- enc.should_not == nil
- end
+ # Not sure how to do a better test, since locale depends on weird platform-specific stuff
+ it "supports the 'locale' encoding alias" do
+ enc = Encoding.find('locale')
+ enc.should_not == nil
+ end
- it "returns default external encoding for the 'external' encoding alias" do
- enc = Encoding.find('external')
- enc.should == Encoding.default_external
- end
+ it "returns default external encoding for the 'external' encoding alias" do
+ enc = Encoding.find('external')
+ enc.should == Encoding.default_external
+ end
- it "returns default internal encoding for the 'internal' encoding alias" do
- enc = Encoding.find('internal')
- enc.should == Encoding.default_internal
- end
+ it "returns default internal encoding for the 'internal' encoding alias" do
+ enc = Encoding.find('internal')
+ enc.should == Encoding.default_internal
+ end
- platform_is_not :windows do
- it "uses default external encoding for the 'filesystem' encoding alias" do
- enc = Encoding.find('filesystem')
- enc.should == Encoding.default_external
- end
+ platform_is_not :windows do
+ it "uses default external encoding for the 'filesystem' encoding alias" do
+ enc = Encoding.find('filesystem')
+ enc.should == Encoding.default_external
end
+ end
- platform_is :windows do
- it "needs to be reviewed for spec completeness"
- end
+ platform_is :windows do
+ it "needs to be reviewed for spec completeness"
end
end
diff --git a/spec/ruby/core/encoding/inspect_spec.rb b/spec/ruby/core/encoding/inspect_spec.rb
index 771232e433..9a930b2a77 100644
--- a/spec/ruby/core/encoding/inspect_spec.rb
+++ b/spec/ruby/core/encoding/inspect_spec.rb
@@ -1,21 +1,19 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding#inspect" do
- it "returns a String" do
- Encoding::UTF_8.inspect.should be_an_instance_of(String)
- end
+describe "Encoding#inspect" do
+ it "returns a String" do
+ Encoding::UTF_8.inspect.should be_an_instance_of(String)
+ end
- it "returns #<Encoding:name> for a non-dummy encoding named 'name'" do
- Encoding.list.to_a.reject {|e| e.dummy? }.each do |enc|
- enc.inspect.should =~ /#<Encoding:#{enc.name}>/
- end
+ it "returns #<Encoding:name> for a non-dummy encoding named 'name'" do
+ Encoding.list.to_a.reject {|e| e.dummy? }.each do |enc|
+ enc.inspect.should =~ /#<Encoding:#{enc.name}>/
end
+ end
- it "returns #<Encoding:name (dummy)> for a dummy encoding named 'name'" do
- Encoding.list.to_a.select {|e| e.dummy? }.each do |enc|
- enc.inspect.should =~ /#<Encoding:#{enc.name} \(dummy\)>/
- end
+ it "returns #<Encoding:name (dummy)> for a dummy encoding named 'name'" do
+ Encoding.list.to_a.select {|e| e.dummy? }.each do |enc|
+ enc.inspect.should =~ /#<Encoding:#{enc.name} \(dummy\)>/
end
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb
index 790dd18655..f5fa6f55e3 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb
@@ -1,20 +1,18 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::InvalidByteSequenceError#destination_encoding_name" do
- before :each do
- @exception, = EncodingSpecs::InvalidByteSequenceError.exception
- @exception2, = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
- end
+describe "Encoding::InvalidByteSequenceError#destination_encoding_name" do
+ before :each do
+ @exception, = EncodingSpecs::InvalidByteSequenceError.exception
+ @exception2, = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
+ end
- it "returns a String" do
- @exception.destination_encoding_name.should be_an_instance_of(String)
- @exception2.destination_encoding_name.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @exception.destination_encoding_name.should be_an_instance_of(String)
+ @exception2.destination_encoding_name.should be_an_instance_of(String)
+ end
- it "is equal to the destination encoding name of the object that raised it" do
- @exception.destination_encoding_name.should == "ISO-8859-1"
- @exception2.destination_encoding_name.should == "UTF-8"
- end
+ it "is equal to the destination encoding name of the object that raised it" do
+ @exception.destination_encoding_name.should == "ISO-8859-1"
+ @exception2.destination_encoding_name.should == "UTF-8"
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb
index 981a62424e..43be3ddd71 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb
@@ -1,20 +1,18 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::InvalidByteSequenceError#destination_encoding" do
- before :each do
- @exception, = EncodingSpecs::InvalidByteSequenceError.exception
- @exception2, = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
- end
+describe "Encoding::InvalidByteSequenceError#destination_encoding" do
+ before :each do
+ @exception, = EncodingSpecs::InvalidByteSequenceError.exception
+ @exception2, = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
+ end
- it "returns an Encoding object" do
- @exception.destination_encoding.should be_an_instance_of(Encoding)
- @exception2.destination_encoding.should be_an_instance_of(Encoding)
- end
+ it "returns an Encoding object" do
+ @exception.destination_encoding.should be_an_instance_of(Encoding)
+ @exception2.destination_encoding.should be_an_instance_of(Encoding)
+ end
- it "is equal to the destination encoding of the object that raised it" do
- @exception.destination_encoding.should == Encoding::ISO_8859_1
- @exception2.destination_encoding.should == Encoding::UTF_8
- end
+ it "is equal to the destination encoding of the object that raised it" do
+ @exception.destination_encoding.should == Encoding::ISO_8859_1
+ @exception2.destination_encoding.should == Encoding::UTF_8
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
index 633ad2e1f7..a8f7354b16 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
@@ -1,32 +1,30 @@
# -*- encoding: binary -*-
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::InvalidByteSequenceError#error_bytes" do
- before :each do
- @exception, @errinfo = EncodingSpecs::InvalidByteSequenceError.exception
- @exception2, @errinfo2 = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
- end
+describe "Encoding::InvalidByteSequenceError#error_bytes" do
+ before :each do
+ @exception, @errinfo = EncodingSpecs::InvalidByteSequenceError.exception
+ @exception2, @errinfo2 = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
+ end
- it "returns a String" do
- @exception.error_bytes.should be_an_instance_of(String)
- @exception2.error_bytes.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @exception.error_bytes.should be_an_instance_of(String)
+ @exception2.error_bytes.should be_an_instance_of(String)
+ end
- it "returns the bytes that caused the exception" do
- @exception.error_bytes.size.should == 1
- @exception.error_bytes.should == "\xF1"
- @exception.error_bytes.should == @errinfo[-2]
+ it "returns the bytes that caused the exception" do
+ @exception.error_bytes.size.should == 1
+ @exception.error_bytes.should == "\xF1"
+ @exception.error_bytes.should == @errinfo[-2]
- @exception2.error_bytes.size.should == 1
- @exception2.error_bytes.should == "\xA1"
- @exception2.error_bytes.should == @errinfo2[-2]
- end
+ @exception2.error_bytes.size.should == 1
+ @exception2.error_bytes.should == "\xA1"
+ @exception2.error_bytes.should == @errinfo2[-2]
+ end
- it "uses ASCII-8BIT as the encoding" do
- @exception.error_bytes.encoding.should == Encoding::ASCII_8BIT
+ it "uses BINARY as the encoding" do
+ @exception.error_bytes.encoding.should == Encoding::BINARY
- @exception2.error_bytes.encoding.should == Encoding::ASCII_8BIT
- end
+ @exception2.error_bytes.encoding.should == Encoding::BINARY
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb
index c79a6663e2..94201a9b15 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb
@@ -1,31 +1,28 @@
# -*- encoding: binary -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
-with_feature :encoding do
- describe "Encoding::InvalidByteSequenceError#incomplete_input?" do
-
- it "returns nil by default" do
- Encoding::InvalidByteSequenceError.new.incomplete_input?.should be_nil
- end
+describe "Encoding::InvalidByteSequenceError#incomplete_input?" do
+ it "returns nil by default" do
+ Encoding::InvalidByteSequenceError.new.incomplete_input?.should be_nil
+ end
- it "returns true if #primitive_convert returned :incomplete_input for the same data" do
- ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
- ec.primitive_convert("\xA1",'').should == :incomplete_input
- begin
- ec.convert("\xA1")
- rescue Encoding::InvalidByteSequenceError => e
- e.incomplete_input?.should be_true
- end
+ it "returns true if #primitive_convert returned :incomplete_input for the same data" do
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert("\xA1",'').should == :incomplete_input
+ begin
+ ec.convert("\xA1")
+ rescue Encoding::InvalidByteSequenceError => e
+ e.incomplete_input?.should be_true
end
+ end
- it "returns false if #primitive_convert returned :invalid_byte_sequence for the same data" do
- ec = Encoding::Converter.new("ascii", "utf-8")
- ec.primitive_convert("\xfffffffff",'').should == :invalid_byte_sequence
- begin
- ec.convert("\xfffffffff")
- rescue Encoding::InvalidByteSequenceError => e
- e.incomplete_input?.should be_false
- end
+ it "returns false if #primitive_convert returned :invalid_byte_sequence for the same data" do
+ ec = Encoding::Converter.new("ascii", "utf-8")
+ ec.primitive_convert("\xfffffffff",'').should == :invalid_byte_sequence
+ begin
+ ec.convert("\xfffffffff")
+ rescue Encoding::InvalidByteSequenceError => e
+ e.incomplete_input?.should be_false
end
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
index 31408a4320..93823b5db4 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
@@ -1,32 +1,30 @@
# -*- encoding: binary -*-
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::InvalidByteSequenceError#readagain_bytes" do
- before :each do
- @exception, @errinfo = EncodingSpecs::InvalidByteSequenceError.exception
- @exception2, @errinfo2 = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
- end
+describe "Encoding::InvalidByteSequenceError#readagain_bytes" do
+ before :each do
+ @exception, @errinfo = EncodingSpecs::InvalidByteSequenceError.exception
+ @exception2, @errinfo2 = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
+ end
- it "returns a String" do
- @exception.readagain_bytes.should be_an_instance_of(String)
- @exception2.readagain_bytes.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @exception.readagain_bytes.should be_an_instance_of(String)
+ @exception2.readagain_bytes.should be_an_instance_of(String)
+ end
- it "returns the bytes to be read again" do
- @exception.readagain_bytes.size.should == 1
- @exception.readagain_bytes.should == "a".force_encoding('binary')
- @exception.readagain_bytes.should == @errinfo[-1]
+ it "returns the bytes to be read again" do
+ @exception.readagain_bytes.size.should == 1
+ @exception.readagain_bytes.should == "a".force_encoding('binary')
+ @exception.readagain_bytes.should == @errinfo[-1]
- @exception2.readagain_bytes.size.should == 1
- @exception2.readagain_bytes.should == "\xFF".force_encoding('binary')
- @exception2.readagain_bytes.should == @errinfo2[-1]
- end
+ @exception2.readagain_bytes.size.should == 1
+ @exception2.readagain_bytes.should == "\xFF".force_encoding('binary')
+ @exception2.readagain_bytes.should == @errinfo2[-1]
+ end
- it "uses ASCII-8BIT as the encoding" do
- @exception.readagain_bytes.encoding.should == Encoding::ASCII_8BIT
+ it "uses BINARY as the encoding" do
+ @exception.readagain_bytes.encoding.should == Encoding::BINARY
- @exception2.readagain_bytes.encoding.should == Encoding::ASCII_8BIT
- end
+ @exception2.readagain_bytes.encoding.should == Encoding::BINARY
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb
index 41320c5207..bd3a51cbc5 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb
@@ -1,30 +1,28 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::UndefinedConversionError#source_encoding_name" do
- before :each do
- @exception, = EncodingSpecs::UndefinedConversionError.exception
- @exception2, = EncodingSpecs::UndefinedConversionErrorIndirect.exception
- end
+describe "Encoding::UndefinedConversionError#source_encoding_name" do
+ before :each do
+ @exception, = EncodingSpecs::UndefinedConversionError.exception
+ @exception2, = EncodingSpecs::UndefinedConversionErrorIndirect.exception
+ end
- it "returns a String" do
- @exception.source_encoding_name.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @exception.source_encoding_name.should be_an_instance_of(String)
+ end
- it "is equal to the source encoding name of the object that raised it" do
- @exception.source_encoding_name.should == "UTF-8"
- end
+ it "is equal to the source encoding name of the object that raised it" do
+ @exception.source_encoding_name.should == "UTF-8"
+ end
- # The source encoding specified in the Encoding::Converter constructor may
- # differ from the source encoding returned here. What seems to happen is
- # that when transcoding along a path with multiple pairs of encodings, the
- # last one encountered when the error occurred is returned. So in this
- # case, the conversion path is ISO-8859-1 -> UTF-8 -> EUC-JP. The
- # conversion from ISO-8859-1 -> UTF-8 succeeded, but the conversion from
- # UTF-8 to EUC-JP failed. IOW, it failed when the source encoding was
- # UTF-8, so UTF-8 is regarded as the source encoding.
- it "is equal to the source encoding at the stage of the conversion path where the error occured" do
- @exception2.source_encoding_name.should == 'UTF-8'
- end
+ # The source encoding specified in the Encoding::Converter constructor may
+ # differ from the source encoding returned here. What seems to happen is
+ # that when transcoding along a path with multiple pairs of encodings, the
+ # last one encountered when the error occurred is returned. So in this
+ # case, the conversion path is ISO-8859-1 -> UTF-8 -> EUC-JP. The
+ # conversion from ISO-8859-1 -> UTF-8 succeeded, but the conversion from
+ # UTF-8 to EUC-JP failed. IOW, it failed when the source encoding was
+ # UTF-8, so UTF-8 is regarded as the source encoding.
+ it "is equal to the source encoding at the stage of the conversion path where the error occurred" do
+ @exception2.source_encoding_name.should == 'UTF-8'
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb
index 75514e5229..f43d6d5830 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb
@@ -1,35 +1,33 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::InvalidByteSequenceError#source_encoding" do
- before :each do
- @exception, = EncodingSpecs::InvalidByteSequenceError.exception
- @exception2, = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
- end
+describe "Encoding::InvalidByteSequenceError#source_encoding" do
+ before :each do
+ @exception, = EncodingSpecs::InvalidByteSequenceError.exception
+ @exception2, = EncodingSpecs::InvalidByteSequenceErrorIndirect.exception
+ end
- it "returns an Encoding object" do
- @exception.source_encoding.should be_an_instance_of(Encoding)
- @exception2.source_encoding.should be_an_instance_of(Encoding)
- end
+ it "returns an Encoding object" do
+ @exception.source_encoding.should be_an_instance_of(Encoding)
+ @exception2.source_encoding.should be_an_instance_of(Encoding)
+ end
- it "is equal to the source encoding of the object that raised it" do
- @exception.source_encoding.should == Encoding::UTF_8
- end
+ it "is equal to the source encoding of the object that raised it" do
+ @exception.source_encoding.should == Encoding::UTF_8
+ end
- # The source encoding specified in the Encoding::Converter constructor may
- # differ from the source encoding returned here. What seems to happen is
- # that when transcoding along a path with multiple pairs of encodings, the
- # last one encountered when the error occurred is returned. So in this
- # case, the conversion path is EUC-JP -> UTF-8 -> ISO-8859-1. The
- # conversions failed with the first pair of encodings (i.e. transcoding
- # from EUC-JP to UTF-8, so UTF-8 is regarded as the source encoding; if
- # the error had occurred when converting from UTF-8 to ISO-8859-1, UTF-8
- # would have been the source encoding.
+ # The source encoding specified in the Encoding::Converter constructor may
+ # differ from the source encoding returned here. What seems to happen is
+ # that when transcoding along a path with multiple pairs of encodings, the
+ # last one encountered when the error occurred is returned. So in this
+ # case, the conversion path is EUC-JP -> UTF-8 -> ISO-8859-1. The
+ # conversions failed with the first pair of encodings (i.e. transcoding
+ # from EUC-JP to UTF-8, so UTF-8 is regarded as the source encoding; if
+ # the error had occurred when converting from UTF-8 to ISO-8859-1, UTF-8
+ # would have been the source encoding.
- # FIXME: Derive example where the failure occurs at the UTF-8 ->
- # ISO-8859-1 case so as to better illustrate the issue
- it "is equal to the source encoding at the stage of the conversion path where the error occured" do
- @exception2.source_encoding.should == Encoding::EUC_JP
- end
+ # FIXME: Derive example where the failure occurs at the UTF-8 ->
+ # ISO-8859-1 case so as to better illustrate the issue
+ it "is equal to the source encoding at the stage of the conversion path where the error occurred" do
+ @exception2.source_encoding.should == Encoding::EUC_JP
end
end
diff --git a/spec/ruby/core/encoding/list_spec.rb b/spec/ruby/core/encoding/list_spec.rb
index 18488607e5..8efd94ab9c 100644
--- a/spec/ruby/core/encoding/list_spec.rb
+++ b/spec/ruby/core/encoding/list_spec.rb
@@ -1,43 +1,51 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding.list" do
- it "returns an Array" do
- Encoding.list.should be_an_instance_of(Array)
- end
+describe "Encoding.list" do
+ it "returns an Array" do
+ Encoding.list.should be_an_instance_of(Array)
+ end
- it "returns an Array of Encoding objects" do
- Encoding.list.each do |enc|
- enc.should be_an_instance_of(Encoding)
- end
+ it "returns an Array of Encoding objects" do
+ Encoding.list.each do |enc|
+ enc.should be_an_instance_of(Encoding)
end
+ end
- it "returns each encoding only once" do
- orig = Encoding.list.map {|e| e.name}
- orig.should == orig.uniq
- end
+ it "returns each encoding only once" do
+ orig = Encoding.list.map { |e| e.name }
+ orig.should == orig.uniq
+ end
- it "includes the default external encoding" do
- Encoding.list.include?(Encoding.default_external).should be_true
- end
+ it "includes the default external encoding" do
+ Encoding.list.include?(Encoding.default_external).should be_true
+ end
- it "does not include any alias names" do
- Encoding.aliases.keys.each do |enc_alias|
- Encoding.list.include?(enc_alias).should be_false
- end
+ it "does not include any alias names" do
+ Encoding.aliases.keys.each do |enc_alias|
+ Encoding.list.include?(enc_alias).should be_false
end
+ end
- it "includes all aliased encodings" do
- Encoding.aliases.values.each do |enc_alias|
- Encoding.list.include?(Encoding.find(enc_alias)).should be_true
- end
+ it "includes all aliased encodings" do
+ Encoding.aliases.values.each do |enc_alias|
+ Encoding.list.include?(Encoding.find(enc_alias)).should be_true
end
+ end
- it "includes dummy encodings" do
- Encoding.list.select {|e| e.dummy?}.should_not == []
- end
+ it "includes dummy encodings" do
+ Encoding.list.select { |e| e.dummy? }.should_not == []
+ end
- # TODO: Find example that illustrates this
- it "updates the list when #find is used to load a new encoding"
+ it 'includes UTF-8 encoding' do
+ Encoding.list.should.include?(Encoding::UTF_8)
end
+
+ ruby_version_is "2.7" do
+ it 'includes CESU-8 encoding' do
+ Encoding.list.should.include?(Encoding::CESU_8)
+ end
+ end
+
+ # TODO: Find example that illustrates this
+ it "updates the list when #find is used to load a new encoding"
end
diff --git a/spec/ruby/core/encoding/locale_charmap_spec.rb b/spec/ruby/core/encoding/locale_charmap_spec.rb
index 12b93c2562..8143b9083a 100644
--- a/spec/ruby/core/encoding/locale_charmap_spec.rb
+++ b/spec/ruby/core/encoding/locale_charmap_spec.rb
@@ -1,13 +1,13 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding.locale_charmap" do
- it "returns a String" do
- Encoding.locale_charmap.should be_an_instance_of(String)
- end
+describe "Encoding.locale_charmap" do
+ it "returns a String" do
+ Encoding.locale_charmap.should be_an_instance_of(String)
+ end
- # FIXME: Get this working on Windows
- platform_is :linux do
+ # FIXME: Get this working on Windows
+ platform_is :linux do
+ platform_is_not :android do
it "returns a value based on the LC_ALL environment variable" do
old_lc_all = ENV['LC_ALL']
ENV['LC_ALL'] = 'C'
@@ -15,33 +15,42 @@ with_feature :encoding do
ENV['LC_ALL'] = old_lc_all
end
end
+ end
- platform_is :freebsd, :darwin do
- it "returns a value based on the LC_ALL environment variable" do
- old_lc_all = ENV['LC_ALL']
- ENV['LC_ALL'] = 'C'
- ruby_exe("print Encoding.locale_charmap").should == 'US-ASCII'
- ENV['LC_ALL'] = old_lc_all
- end
+ platform_is :freebsd, :openbsd, :darwin do
+ it "returns a value based on the LC_ALL environment variable" do
+ old_lc_all = ENV['LC_ALL']
+ ENV['LC_ALL'] = 'C'
+ ruby_exe("print Encoding.locale_charmap").should == 'US-ASCII'
+ ENV['LC_ALL'] = old_lc_all
end
+ end
- platform_is :netbsd, :openbsd do
- it "returns a value based on the LC_ALL environment variable" do
- old_lc_all = ENV['LC_ALL']
- ENV['LC_ALL'] = 'C'
- ruby_exe("print Encoding.locale_charmap").should == '646'
- ENV['LC_ALL'] = old_lc_all
- end
+ platform_is :netbsd do
+ it "returns a value based on the LC_ALL environment variable" do
+ old_lc_all = ENV['LC_ALL']
+ ENV['LC_ALL'] = 'C'
+ ruby_exe("print Encoding.locale_charmap").should == '646'
+ ENV['LC_ALL'] = old_lc_all
end
+ end
- platform_is :bsd, :darwin, :linux do
- it "is unaffected by assigning to ENV['LC_ALL'] in the same process" do
- old_charmap = Encoding.locale_charmap
- old_lc_all = ENV['LC_ALL']
- ENV['LC_ALL'] = 'C'
- Encoding.locale_charmap.should == old_charmap
- ENV['LC_ALL'] = old_lc_all
- end
+ platform_is :android do
+ it "always returns UTF-8" do
+ old_lc_all = ENV['LC_ALL']
+ ENV['LC_ALL'] = 'C'
+ ruby_exe("print Encoding.locale_charmap").should == 'UTF-8'
+ ENV['LC_ALL'] = old_lc_all
+ end
+ end
+
+ platform_is :bsd, :darwin, :linux do
+ it "is unaffected by assigning to ENV['LC_ALL'] in the same process" do
+ old_charmap = Encoding.locale_charmap
+ old_lc_all = ENV['LC_ALL']
+ ENV['LC_ALL'] = 'C'
+ Encoding.locale_charmap.should == old_charmap
+ ENV['LC_ALL'] = old_lc_all
end
end
end
diff --git a/spec/ruby/core/encoding/name_list_spec.rb b/spec/ruby/core/encoding/name_list_spec.rb
index c06ec410ec..836381c4d8 100644
--- a/spec/ruby/core/encoding/name_list_spec.rb
+++ b/spec/ruby/core/encoding/name_list_spec.rb
@@ -1,25 +1,23 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding.name_list" do
- it "returns an Array" do
- Encoding.name_list.should be_an_instance_of(Array)
- end
+describe "Encoding.name_list" do
+ it "returns an Array" do
+ Encoding.name_list.should be_an_instance_of(Array)
+ end
- it "returns encoding names as Strings" do
- Encoding.name_list.each {|e| e.should be_an_instance_of(String) }
- end
+ it "returns encoding names as Strings" do
+ Encoding.name_list.each {|e| e.should be_an_instance_of(String) }
+ end
- it "includes all aliases" do
- Encoding.aliases.keys.each do |enc_alias|
- Encoding.name_list.include?(enc_alias).should be_true
- end
+ it "includes all aliases" do
+ Encoding.aliases.keys.each do |enc_alias|
+ Encoding.name_list.include?(enc_alias).should be_true
end
+ end
- it "includes all non-dummy encodings" do
- Encoding.list.each do |enc|
- Encoding.name_list.include?(enc.name).should be_true
- end
+ it "includes all non-dummy encodings" do
+ Encoding.list.each do |enc|
+ Encoding.name_list.include?(enc.name).should be_true
end
end
end
diff --git a/spec/ruby/core/encoding/name_spec.rb b/spec/ruby/core/encoding/name_spec.rb
index 4ea89a563a..5eadb1d2f5 100644
--- a/spec/ruby/core/encoding/name_spec.rb
+++ b/spec/ruby/core/encoding/name_spec.rb
@@ -1,7 +1,5 @@
-require File.expand_path('../shared/name', __FILE__)
+require_relative 'shared/name'
-with_feature :encoding do
- describe "Encoding#name" do
- it_behaves_like(:encoding_name, :name)
- end
+describe "Encoding#name" do
+ it_behaves_like :encoding_name, :name
end
diff --git a/spec/ruby/core/encoding/names_spec.rb b/spec/ruby/core/encoding/names_spec.rb
index 3cd741e513..9ded043bbb 100644
--- a/spec/ruby/core/encoding/names_spec.rb
+++ b/spec/ruby/core/encoding/names_spec.rb
@@ -1,37 +1,35 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding#names" do
- it "returns an Array" do
- Encoding.name_list.each do |name|
- e = Encoding.find(name) or next
- e.names.should be_an_instance_of(Array)
- end
+describe "Encoding#names" do
+ it "returns an Array" do
+ Encoding.name_list.each do |name|
+ e = Encoding.find(name) or next
+ e.names.should be_an_instance_of(Array)
end
+ end
- it "returns names as Strings" do
- Encoding.name_list.each do |name|
- e = Encoding.find(name) or next
- e.names.each do |this_name|
- this_name.should be_an_instance_of(String)
- end
+ it "returns names as Strings" do
+ Encoding.name_list.each do |name|
+ e = Encoding.find(name) or next
+ e.names.each do |this_name|
+ this_name.should be_an_instance_of(String)
end
end
+ end
- it "returns #name as the first value" do
- Encoding.name_list.each do |name|
- e = Encoding.find(name) or next
- e.names.first.should == e.name
- end
+ it "returns #name as the first value" do
+ Encoding.name_list.each do |name|
+ e = Encoding.find(name) or next
+ e.names.first.should == e.name
end
+ end
- it "includes any aliases the encoding has" do
- Encoding.name_list.each do |name|
- e = Encoding.find(name) or next
- aliases = Encoding.aliases.select{|a,n| n == name}.keys
- names = e.names
- aliases.each {|a| names.include?(a).should be_true}
- end
+ it "includes any aliases the encoding has" do
+ Encoding.name_list.each do |name|
+ e = Encoding.find(name) or next
+ aliases = Encoding.aliases.select{|a,n| n == name}.keys
+ names = e.names
+ aliases.each {|a| names.include?(a).should be_true}
end
end
end
diff --git a/spec/ruby/core/encoding/replicate_spec.rb b/spec/ruby/core/encoding/replicate_spec.rb
index 5d007dd827..717e9cea72 100644
--- a/spec/ruby/core/encoding/replicate_spec.rb
+++ b/spec/ruby/core/encoding/replicate_spec.rb
@@ -1,48 +1,46 @@
# -*- encoding: binary -*-
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :encoding do
- describe "Encoding#replicate" do
- before :all do
- @i = 0
- end
+describe "Encoding#replicate" do
+ before :all do
+ @i = 0
+ end
- before :each do
- @i += 1
- @prefix = "RS#{@i}"
- end
+ before :each do
+ @i += 1
+ @prefix = "RS#{@i}"
+ end
- it "returns a replica of ASCII" do
- name = @prefix + '-ASCII'
- e = Encoding::ASCII.replicate(name)
- e.name.should == name
- "a".force_encoding(e).valid_encoding?.should be_true
- "\x80".force_encoding(e).valid_encoding?.should be_false
- end
+ it "returns a replica of ASCII" do
+ name = @prefix + '-ASCII'
+ e = Encoding::ASCII.replicate(name)
+ e.name.should == name
+ "a".force_encoding(e).valid_encoding?.should be_true
+ "\x80".force_encoding(e).valid_encoding?.should be_false
+ end
- it "returns a replica of UTF-8" do
- name = @prefix + 'UTF-8'
- e = Encoding::UTF_8.replicate(name)
- e.name.should == name
- "a".force_encoding(e).valid_encoding?.should be_true
- "\u3042".force_encoding(e).valid_encoding?.should be_true
- "\x80".force_encoding(e).valid_encoding?.should be_false
- end
+ it "returns a replica of UTF-8" do
+ name = @prefix + 'UTF-8'
+ e = Encoding::UTF_8.replicate(name)
+ e.name.should == name
+ "a".force_encoding(e).valid_encoding?.should be_true
+ "\u3042".force_encoding(e).valid_encoding?.should be_true
+ "\x80".force_encoding(e).valid_encoding?.should be_false
+ end
- it "returns a replica of UTF-16BE" do
- name = @prefix + 'UTF-16-BE'
- e = Encoding::UTF_16BE.replicate(name)
- e.name.should == name
- "a".force_encoding(e).valid_encoding?.should be_false
- "\x30\x42".force_encoding(e).valid_encoding?.should be_true
- "\x80".force_encoding(e).valid_encoding?.should be_false
- end
+ it "returns a replica of UTF-16BE" do
+ name = @prefix + 'UTF-16-BE'
+ e = Encoding::UTF_16BE.replicate(name)
+ e.name.should == name
+ "a".force_encoding(e).valid_encoding?.should be_false
+ "\x30\x42".force_encoding(e).valid_encoding?.should be_true
+ "\x80".force_encoding(e).valid_encoding?.should be_false
+ end
- it "returns a replica of ISO-2022-JP" do
- name = @prefix + 'ISO-2022-JP'
- e = Encoding::ISO_2022_JP.replicate(name)
- e.name.should == name
- e.dummy?.should be_true
- end
+ it "returns a replica of ISO-2022-JP" do
+ name = @prefix + 'ISO-2022-JP'
+ e = Encoding::ISO_2022_JP.replicate(name)
+ e.name.should == name
+ e.dummy?.should be_true
end
end
diff --git a/spec/ruby/core/encoding/shared/name.rb b/spec/ruby/core/encoding/shared/name.rb
index 7f85c46764..cd37ea06db 100644
--- a/spec/ruby/core/encoding/shared/name.rb
+++ b/spec/ruby/core/encoding/shared/name.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe :encoding_name, shared: true do
it "returns a String" do
diff --git a/spec/ruby/core/encoding/to_s_spec.rb b/spec/ruby/core/encoding/to_s_spec.rb
index ddc57e321e..82d282386b 100644
--- a/spec/ruby/core/encoding/to_s_spec.rb
+++ b/spec/ruby/core/encoding/to_s_spec.rb
@@ -1,7 +1,5 @@
-require File.expand_path('../shared/name', __FILE__)
+require_relative 'shared/name'
-with_feature :encoding do
- describe "Encoding#to_s" do
- it_behaves_like(:encoding_name, :to_s)
- end
+describe "Encoding#to_s" do
+ it_behaves_like :encoding_name, :to_s
end
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb
index 2f7f33e45e..106fc7ecac 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb
@@ -1,17 +1,15 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::UndefinedConversionError#destination_encoding_name" do
- before :each do
- @exception = EncodingSpecs::UndefinedConversionError.exception
- end
+describe "Encoding::UndefinedConversionError#destination_encoding_name" do
+ before :each do
+ @exception = EncodingSpecs::UndefinedConversionError.exception
+ end
- it "returns a String" do
- @exception.destination_encoding_name.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @exception.destination_encoding_name.should be_an_instance_of(String)
+ end
- it "is equal to the destination encoding name of the object that raised it" do
- @exception.destination_encoding_name.should == "US-ASCII"
- end
+ it "is equal to the destination encoding name of the object that raised it" do
+ @exception.destination_encoding_name.should == "US-ASCII"
end
end
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb
index 6d4f42c0d8..c6e24732fd 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb
@@ -1,17 +1,15 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::UndefinedConversionError#destination_encoding" do
- before :each do
- @exception = EncodingSpecs::UndefinedConversionError.exception
- end
+describe "Encoding::UndefinedConversionError#destination_encoding" do
+ before :each do
+ @exception = EncodingSpecs::UndefinedConversionError.exception
+ end
- it "returns an Encoding object" do
- @exception.destination_encoding.should be_an_instance_of(Encoding)
- end
+ it "returns an Encoding object" do
+ @exception.destination_encoding.should be_an_instance_of(Encoding)
+ end
- it "is equal to the destination encoding of the object that raised it" do
- @exception.destination_encoding.should == Encoding::US_ASCII
- end
+ it "is equal to the destination encoding of the object that raised it" do
+ @exception.destination_encoding.should == Encoding::US_ASCII
end
end
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb
index 7f538a60d6..780d81c1ee 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb
@@ -1,29 +1,27 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::UndefinedConversionError#error_char" do
- before :each do
- @exception = EncodingSpecs::UndefinedConversionError.exception
- @exception2 = EncodingSpecs::UndefinedConversionErrorIndirect.exception
- end
+describe "Encoding::UndefinedConversionError#error_char" do
+ before :each do
+ @exception = EncodingSpecs::UndefinedConversionError.exception
+ @exception2 = EncodingSpecs::UndefinedConversionErrorIndirect.exception
+ end
- it "returns a String" do
- @exception.error_char.should be_an_instance_of(String)
- @exception2.error_char.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @exception.error_char.should be_an_instance_of(String)
+ @exception2.error_char.should be_an_instance_of(String)
+ end
- it "returns the one-character String that caused the exception" do
- @exception.error_char.size.should == 1
- @exception.error_char.should == "\u{8765}"
+ it "returns the one-character String that caused the exception" do
+ @exception.error_char.size.should == 1
+ @exception.error_char.should == "\u{8765}"
- @exception2.error_char.size.should == 1
- @exception2.error_char.should == "\u{A0}"
- end
+ @exception2.error_char.size.should == 1
+ @exception2.error_char.should == "\u{A0}"
+ end
- it "uses the source encoding" do
- @exception.error_char.encoding.should == @exception.source_encoding
+ it "uses the source encoding" do
+ @exception.error_char.encoding.should == @exception.source_encoding
- @exception2.error_char.encoding.should == @exception2.source_encoding
- end
+ @exception2.error_char.encoding.should == @exception2.source_encoding
end
end
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb
index 4a7aba2044..3b697cb82f 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb
@@ -1,30 +1,28 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::UndefinedConversionError#source_encoding_name" do
- before :each do
- @exception = EncodingSpecs::UndefinedConversionError.exception
- @exception2 = EncodingSpecs::UndefinedConversionErrorIndirect.exception
- end
+describe "Encoding::UndefinedConversionError#source_encoding_name" do
+ before :each do
+ @exception = EncodingSpecs::UndefinedConversionError.exception
+ @exception2 = EncodingSpecs::UndefinedConversionErrorIndirect.exception
+ end
- it "returns a String" do
- @exception.source_encoding_name.should be_an_instance_of(String)
- end
+ it "returns a String" do
+ @exception.source_encoding_name.should be_an_instance_of(String)
+ end
- it "is equal to the source encoding name of the object that raised it" do
- @exception.source_encoding_name.should == "UTF-8"
- end
+ it "is equal to the source encoding name of the object that raised it" do
+ @exception.source_encoding_name.should == "UTF-8"
+ end
- # The source encoding specified in the Encoding::Converter constructor may
- # differ from the source encoding returned here. What seems to happen is
- # that when transcoding along a path with multiple pairs of encodings, the
- # last one encountered when the error occurred is returned. So in this
- # case, the conversion path is ISO-8859-1 -> UTF-8 -> EUC-JP. The
- # conversion from ISO-8859-1 -> UTF-8 succeeded, but the conversion from
- # UTF-8 to EUC-JP failed. IOW, it failed when the source encoding was
- # UTF-8, so UTF-8 is regarded as the source encoding.
- it "is equal to the source encoding at the stage of the conversion path where the error occured" do
- @exception2.source_encoding_name.should == 'UTF-8'
- end
+ # The source encoding specified in the Encoding::Converter constructor may
+ # differ from the source encoding returned here. What seems to happen is
+ # that when transcoding along a path with multiple pairs of encodings, the
+ # last one encountered when the error occurred is returned. So in this
+ # case, the conversion path is ISO-8859-1 -> UTF-8 -> EUC-JP. The
+ # conversion from ISO-8859-1 -> UTF-8 succeeded, but the conversion from
+ # UTF-8 to EUC-JP failed. IOW, it failed when the source encoding was
+ # UTF-8, so UTF-8 is regarded as the source encoding.
+ it "is equal to the source encoding at the stage of the conversion path where the error occurred" do
+ @exception2.source_encoding_name.should == 'UTF-8'
end
end
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb
index 984862646c..9101d51e11 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb
@@ -1,31 +1,29 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
-with_feature :encoding do
- describe "Encoding::UndefinedConversionError#source_encoding" do
- before :each do
- @exception = EncodingSpecs::UndefinedConversionError.exception
- @exception2 = EncodingSpecs::UndefinedConversionErrorIndirect.exception
- end
+describe "Encoding::UndefinedConversionError#source_encoding" do
+ before :each do
+ @exception = EncodingSpecs::UndefinedConversionError.exception
+ @exception2 = EncodingSpecs::UndefinedConversionErrorIndirect.exception
+ end
- it "returns an Encoding object" do
- @exception.source_encoding.should be_an_instance_of(Encoding)
- @exception2.source_encoding.should be_an_instance_of(Encoding)
- end
+ it "returns an Encoding object" do
+ @exception.source_encoding.should be_an_instance_of(Encoding)
+ @exception2.source_encoding.should be_an_instance_of(Encoding)
+ end
- it "is equal to the source encoding of the object that raised it" do
- @exception.source_encoding.should == Encoding::UTF_8
- end
+ it "is equal to the source encoding of the object that raised it" do
+ @exception.source_encoding.should == Encoding::UTF_8
+ end
- # The source encoding specified in the Encoding::Converter constructor may
- # differ from the source encoding returned here. What seems to happen is
- # that when transcoding along a path with multiple pairs of encodings, the
- # last one encountered when the error occurred is returned. So in this
- # case, the conversion path is ISO-8859-1 -> UTF-8 -> EUC-JP. The
- # conversion from ISO-8859-1 -> UTF-8 succeeded, but the conversion from
- # UTF-8 to EUC-JP failed. IOW, it failed when the source encoding was
- # UTF-8, so UTF-8 is regarded as the source encoding.
- it "is equal to the source encoding at the stage of the conversion path where the error occured" do
- @exception2.source_encoding.should == Encoding::UTF_8
- end
+ # The source encoding specified in the Encoding::Converter constructor may
+ # differ from the source encoding returned here. What seems to happen is
+ # that when transcoding along a path with multiple pairs of encodings, the
+ # last one encountered when the error occurred is returned. So in this
+ # case, the conversion path is ISO-8859-1 -> UTF-8 -> EUC-JP. The
+ # conversion from ISO-8859-1 -> UTF-8 succeeded, but the conversion from
+ # UTF-8 to EUC-JP failed. IOW, it failed when the source encoding was
+ # UTF-8, so UTF-8 is regarded as the source encoding.
+ it "is equal to the source encoding at the stage of the conversion path where the error occurred" do
+ @exception2.source_encoding.should == Encoding::UTF_8
end
end
diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb
index bfde584260..7e9726fe87 100644
--- a/spec/ruby/core/enumerable/all_spec.rb
+++ b/spec/ruby/core/enumerable/all_spec.rb
@@ -1,63 +1,67 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#all?" do
-
before :each do
@enum = EnumerableSpecs::Numerous.new
@empty = EnumerableSpecs::Empty.new()
- @enum1 = [0, 1, 2, -1]
- @enum2 = [nil, false, true]
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
end
it "always returns true on empty enumeration" do
- @empty.all?.should == true
+ @empty.should.all?
@empty.all? { nil }.should == true
- [].all?.should == true
+ [].should.all?
[].all? { false }.should == true
- {}.all?.should == true
+ {}.should.all?
{}.all? { nil }.should == true
end
+ it "raises an ArgumentError when more than 1 argument is provided" do
+ -> { @enum.all?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { [].all?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { {}.all?(1, 2, 3) }.should raise_error(ArgumentError)
+ end
+
it "does not hide exceptions out of #each" do
- lambda {
+ -> {
EnumerableSpecs::ThrowingEach.new.all?
}.should raise_error(RuntimeError)
- lambda {
+ -> {
EnumerableSpecs::ThrowingEach.new.all? { false }
}.should raise_error(RuntimeError)
end
describe "with no block" do
it "returns true if no elements are false or nil" do
- @enum.all?.should == true
- @enum1.all?.should == true
- @enum2.all?.should == false
+ @enum.should.all?
+ @enum1.should.all?
+ @enum2.should_not.all?
- EnumerableSpecs::Numerous.new('a','b','c').all?.should == true
- EnumerableSpecs::Numerous.new(0, "x", true).all?.should == true
+ EnumerableSpecs::Numerous.new('a','b','c').should.all?
+ EnumerableSpecs::Numerous.new(0, "x", true).should.all?
end
it "returns false if there are false or nil elements" do
- EnumerableSpecs::Numerous.new(false).all?.should == false
- EnumerableSpecs::Numerous.new(false, false).all?.should == false
+ EnumerableSpecs::Numerous.new(false).should_not.all?
+ EnumerableSpecs::Numerous.new(false, false).should_not.all?
- EnumerableSpecs::Numerous.new(nil).all?.should == false
- EnumerableSpecs::Numerous.new(nil, nil).all?.should == false
+ EnumerableSpecs::Numerous.new(nil).should_not.all?
+ EnumerableSpecs::Numerous.new(nil, nil).should_not.all?
- EnumerableSpecs::Numerous.new(1, nil, 2).all?.should == false
- EnumerableSpecs::Numerous.new(0, "x", false, true).all?.should == false
- @enum2.all?.should == false
+ EnumerableSpecs::Numerous.new(1, nil, 2).should_not.all?
+ EnumerableSpecs::Numerous.new(0, "x", false, true).should_not.all?
+ @enum2.should_not.all?
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMultiWithFalse.new
multi.all?.should be_true
end
-
end
describe "with block" do
@@ -100,22 +104,87 @@ describe "Enumerable#all?" do
end
it "does not hide exceptions out of the block" do
- lambda {
+ -> {
@enum.all? { raise "from block" }
}.should raise_error(RuntimeError)
end
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
- multi.all? {|e| !(Array === e) }.should be_true
+ yielded = []
+ multi.all? { |e| yielded << e }.should == true
+ yielded.should == [1, 3, 6]
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
- multi.all? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2], [3, 4], [6, 7]]
+ multi.all? { |*args| yielded << args }.should == true
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
+ end
+ end
+
+ describe 'when given a pattern argument' do
+ it "calls `===` on the pattern the return value " do
+ pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
+ @enum1.all?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+ end
+
+ # may raise an exception in future versions
+ ruby_version_is ""..."2.6" do
+ it "ignores block" do
+ @enum2.all?(NilClass) { raise }.should == false
+ [1, 2, nil].all?(NilClass) { raise }.should == false
+ {a: 1}.all?(Array) { raise }.should == true
+ end
+ end
+
+ it "always returns true on empty enumeration" do
+ @empty.all?(Integer).should == true
+ [].all?(Integer).should == true
+ {}.all?(NilClass).should == true
+ end
+
+ it "does not hide exceptions out of #each" do
+ -> {
+ EnumerableSpecs::ThrowingEach.new.all?(Integer)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "returns true if the pattern never returns false or nil" do
+ pattern = EnumerableSpecs::Pattern.new { |x| 42 }
+ @enum.all?(pattern).should == true
+
+ [1, 42, 3].all?(pattern).should == true
+
+ pattern = EnumerableSpecs::Pattern.new { |x| Array === x }
+ {a: 1, b: 2}.all?(pattern).should == true
+ end
+
+ it "returns false if the pattern ever returns false or nil" do
+ pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
+ @enum1.all?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+
+ [1, 2, 3, -1].all?(pattern).should == false
+
+ pattern = EnumerableSpecs::Pattern.new { |x| x[1] >= 0 }
+ {a: 1, b: -1}.all?(pattern).should == false
end
+ it "does not hide exceptions out of pattern#===" do
+ pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
+ -> {
+ @enum.all?(pattern)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ pattern = EnumerableSpecs::Pattern.new { true }
+ multi.all?(pattern).should == true
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
+ end
end
end
diff --git a/spec/ruby/core/enumerable/any_spec.rb b/spec/ruby/core/enumerable/any_spec.rb
index 4f7af68b07..64e3159963 100644
--- a/spec/ruby/core/enumerable/any_spec.rb
+++ b/spec/ruby/core/enumerable/any_spec.rb
@@ -1,63 +1,61 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#any?" do
before :each do
@enum = EnumerableSpecs::Numerous.new
- @empty = EnumerableSpecs::Empty.new()
- @enum1 = [0, 1, 2, -1]
- @enum2 = [nil, false, true]
+ @empty = EnumerableSpecs::Empty.new
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
end
it "always returns false on empty enumeration" do
- @empty.any?.should == false
+ @empty.should_not.any?
@empty.any? { nil }.should == false
- [].any?.should == false
+ [].should_not.any?
[].any? { false }.should == false
- {}.any?.should == false
+ {}.should_not.any?
{}.any? { nil }.should == false
end
- it "raises an ArgumentError when any arguments provided" do
- lambda { @enum.any?(Proc.new {}) }.should raise_error(ArgumentError)
- lambda { @enum.any?(nil) }.should raise_error(ArgumentError)
- lambda { @empty.any?(1) }.should raise_error(ArgumentError)
- lambda { @enum1.any?(1) {} }.should raise_error(ArgumentError)
- lambda { @enum2.any?(1, 2, 3) {} }.should raise_error(ArgumentError)
+ it "raises an ArgumentError when more than 1 argument is provided" do
+ -> { @enum.any?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { [].any?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { {}.any?(1, 2, 3) }.should raise_error(ArgumentError)
end
it "does not hide exceptions out of #each" do
- lambda {
+ -> {
EnumerableSpecs::ThrowingEach.new.any?
}.should raise_error(RuntimeError)
- lambda {
+ -> {
EnumerableSpecs::ThrowingEach.new.any? { false }
}.should raise_error(RuntimeError)
end
describe "with no block" do
it "returns true if any element is not false or nil" do
- @enum.any?.should == true
- @enum1.any?.should == true
- @enum2.any?.should == true
- EnumerableSpecs::Numerous.new(true).any?.should == true
- EnumerableSpecs::Numerous.new('a','b','c').any?.should == true
- EnumerableSpecs::Numerous.new('a','b','c', nil).any?.should == true
- EnumerableSpecs::Numerous.new(1, nil, 2).any?.should == true
- EnumerableSpecs::Numerous.new(1, false).any?.should == true
- EnumerableSpecs::Numerous.new(false, nil, 1, false).any?.should == true
- EnumerableSpecs::Numerous.new(false, 0, nil).any?.should == true
+ @enum.should.any?
+ @enum1.should.any?
+ @enum2.should.any?
+ EnumerableSpecs::Numerous.new(true).should.any?
+ EnumerableSpecs::Numerous.new('a','b','c').should.any?
+ EnumerableSpecs::Numerous.new('a','b','c', nil).should.any?
+ EnumerableSpecs::Numerous.new(1, nil, 2).should.any?
+ EnumerableSpecs::Numerous.new(1, false).should.any?
+ EnumerableSpecs::Numerous.new(false, nil, 1, false).should.any?
+ EnumerableSpecs::Numerous.new(false, 0, nil).should.any?
end
it "returns false if all elements are false or nil" do
- EnumerableSpecs::Numerous.new(false).any?.should == false
- EnumerableSpecs::Numerous.new(false, false).any?.should == false
- EnumerableSpecs::Numerous.new(nil).any?.should == false
- EnumerableSpecs::Numerous.new(nil, nil).any?.should == false
- EnumerableSpecs::Numerous.new(nil, false, nil).any?.should == false
+ EnumerableSpecs::Numerous.new(false).should_not.any?
+ EnumerableSpecs::Numerous.new(false, false).should_not.any?
+ EnumerableSpecs::Numerous.new(nil).should_not.any?
+ EnumerableSpecs::Numerous.new(nil, nil).should_not.any?
+ EnumerableSpecs::Numerous.new(nil, false, nil).should_not.any?
end
it "gathers whole arrays as elements when each yields multiple" do
@@ -68,18 +66,18 @@ describe "Enumerable#any?" do
describe "with block" do
it "returns true if the block ever returns other than false or nil" do
- @enum.any? { true } == true
- @enum.any? { 0 } == true
- @enum.any? { 1 } == true
+ @enum.any? { true }.should == true
+ @enum.any? { 0 }.should == true
+ @enum.any? { 1 }.should == true
- @enum1.any? { Object.new } == true
+ @enum1.any? { Object.new }.should == true
@enum1.any?{ |o| o < 1 }.should == true
@enum1.any?{ |o| 5 }.should == true
@enum2.any? { |i| i == nil }.should == true
end
- it "any? should return false if the block never returns other than false or nil" do
+ it "returns false if the block never returns other than false or nil" do
@enum.any? { false }.should == false
@enum.any? { nil }.should == false
@@ -120,22 +118,86 @@ describe "Enumerable#any?" do
end
it "does not hide exceptions out of the block" do
- lambda {
+ -> {
@enum.any? { raise "from block" }
}.should raise_error(RuntimeError)
end
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
- multi.any? {|e| e == 1 }.should be_true
+ yielded = []
+ multi.any? { |e| yielded << e; false }.should == false
+ yielded.should == [1, 3, 6]
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
- multi.any? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2]]
+ multi.any? { |*args| yielded << args; false }.should == false
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
+ end
+ end
+
+ describe 'when given a pattern argument' do
+ it "calls `===` on the pattern the return value " do
+ pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
+ @enum1.any?(pattern).should == true
+ pattern.yielded.should == [[0], [1], [2]]
+ end
+
+ # may raise an exception in future versions
+ ruby_version_is ""..."2.6" do
+ it "ignores block" do
+ @enum2.any?(NilClass) { raise }.should == true
+ [1, 2, nil].any?(NilClass) { raise }.should == true
+ {a: 1}.any?(Array) { raise }.should == true
+ end
end
+ it "always returns false on empty enumeration" do
+ @empty.any?(Integer).should == false
+ [].any?(Integer).should == false
+ {}.any?(NilClass).should == false
+ end
+
+ it "does not hide exceptions out of #each" do
+ -> {
+ EnumerableSpecs::ThrowingEach.new.any?(Integer)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "returns true if the pattern ever returns a truthy value" do
+ @enum2.any?(NilClass).should == true
+ pattern = EnumerableSpecs::Pattern.new { |x| 42 }
+ @enum.any?(pattern).should == true
+
+ [1, 42, 3].any?(pattern).should == true
+
+ pattern = EnumerableSpecs::Pattern.new { |x| x == [:b, 2] }
+ {a: 1, b: 2}.any?(pattern).should == true
+ end
+
+ it "returns false if the block never returns other than false or nil" do
+ pattern = EnumerableSpecs::Pattern.new { |x| nil }
+ @enum1.any?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+
+ [1, 2, 3].any?(pattern).should == false
+ {a: 1}.any?(pattern).should == false
+ end
+
+ it "does not hide exceptions out of pattern#===" do
+ pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
+ -> {
+ @enum.any?(pattern)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ pattern = EnumerableSpecs::Pattern.new { false }
+ multi.any?(pattern).should == false
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
+ end
end
end
diff --git a/spec/ruby/core/enumerable/chain_spec.rb b/spec/ruby/core/enumerable/chain_spec.rb
new file mode 100644
index 0000000000..85c0c03603
--- /dev/null
+++ b/spec/ruby/core/enumerable/chain_spec.rb
@@ -0,0 +1,25 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "2.6" do
+ describe "Enumerable#chain" do
+ before :each do
+ ScratchPad.record []
+ end
+
+ it "returns a chain of self and provided enumerables" do
+ one = EnumerableSpecs::Numerous.new(1)
+ two = EnumerableSpecs::Numerous.new(2, 3)
+ three = EnumerableSpecs::Numerous.new(4, 5, 6)
+
+ chain = one.chain(two, three)
+
+ chain.each { |item| ScratchPad << item }
+ ScratchPad.recorded.should == [1, 2, 3, 4, 5, 6]
+ end
+
+ it "returns an Enumerator::Chain if given a block" do
+ EnumerableSpecs::Numerous.new.chain.should be_an_instance_of(Enumerator::Chain)
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerable/chunk_spec.rb b/spec/ruby/core/enumerable/chunk_spec.rb
index 9d658010e1..548544f4e8 100644
--- a/spec/ruby/core/enumerable/chunk_spec.rb
+++ b/spec/ruby/core/enumerable/chunk_spec.rb
@@ -1,26 +1,16 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#chunk" do
before do
ScratchPad.record []
end
- ruby_version_is ""..."2.4" do
- it "raises an ArgumentError if called without a block" do
- lambda do
- EnumerableSpecs::Numerous.new.chunk
- end.should raise_error(ArgumentError)
- end
- end
-
- ruby_version_is "2.4" do
- it "returns an Enumerator if called without a block" do
- chunk = EnumerableSpecs::Numerous.new(1, 2, 3, 1, 2).chunk
- chunk.should be_an_instance_of(Enumerator)
- result = chunk.with_index {|elt, i| elt - i }.to_a
- result.should == [[1, [1, 2, 3]], [-2, [1, 2]]]
- end
+ it "returns an Enumerator if called without a block" do
+ chunk = EnumerableSpecs::Numerous.new(1, 2, 3, 1, 2).chunk
+ chunk.should be_an_instance_of(Enumerator)
+ result = chunk.with_index {|elt, i| elt - i }.to_a
+ result.should == [[1, [1, 2, 3]], [-2, [1, 2]]]
end
it "returns an Enumerator if given a block" do
@@ -59,37 +49,14 @@ describe "Enumerable#chunk" do
it "raises a RuntimeError if the block returns a Symbol starting with an underscore other than :_alone or :_separator" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1)
- lambda { e.chunk { |x| :_arbitrary }.to_a }.should raise_error(RuntimeError)
+ -> { e.chunk { |x| :_arbitrary }.to_a }.should raise_error(RuntimeError)
end
- ruby_version_is ""..."2.3" do
- describe "with [initial_state]" do
- it "yields an element and an object value-equal but not identical to the object passed to #chunk" do
- e = EnumerableSpecs::Numerous.new(1)
- value = "value"
-
- e.chunk(value) do |x, v|
- x.should == 1
- v.should == value
- v.should_not equal(value)
- end.to_a
- end
-
- it "does not yield the object passed to #chunk if it is nil" do
- e = EnumerableSpecs::Numerous.new(1)
- e.chunk(nil) { |*x| ScratchPad << x }.to_a
- ScratchPad.recorded.should == [[1]]
- end
- end
- end
-
- ruby_version_is "2.3" do
- it "does not accept arguments" do
- e = EnumerableSpecs::Numerous.new(1, 2, 3)
- lambda {
- e.chunk(1) {}
- }.should raise_error(ArgumentError)
- end
+ it "does not accept arguments" do
+ e = EnumerableSpecs::Numerous.new(1, 2, 3)
+ -> {
+ e.chunk(1) {}
+ }.should raise_error(ArgumentError)
end
it 'returned Enumerator size returns nil' do
diff --git a/spec/ruby/core/enumerable/chunk_while_spec.rb b/spec/ruby/core/enumerable/chunk_while_spec.rb
index a5cbdc3348..26bcc983db 100644
--- a/spec/ruby/core/enumerable/chunk_while_spec.rb
+++ b/spec/ruby/core/enumerable/chunk_while_spec.rb
@@ -1,44 +1,42 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
-ruby_version_is "2.3" do
- describe "Enumerable#chunk_while" do
- before :each do
- ary = [10, 9, 7, 6, 4, 3, 2, 1]
- @enum = EnumerableSpecs::Numerous.new(*ary)
- @result = @enum.chunk_while { |i, j| i - 1 == j }
- @enum_length = ary.length
- end
+describe "Enumerable#chunk_while" do
+ before :each do
+ ary = [10, 9, 7, 6, 4, 3, 2, 1]
+ @enum = EnumerableSpecs::Numerous.new(*ary)
+ @result = @enum.chunk_while { |i, j| i - 1 == j }
+ @enum_length = ary.length
+ end
- context "when given a block" do
- it "returns an enumerator" do
- @result.should be_an_instance_of(Enumerator)
- end
+ context "when given a block" do
+ it "returns an enumerator" do
+ @result.should be_an_instance_of(Enumerator)
+ end
- it "splits chunks between adjacent elements i and j where the block returns false" do
- @result.to_a.should == [[10, 9], [7, 6], [4, 3, 2, 1]]
- end
+ it "splits chunks between adjacent elements i and j where the block returns false" do
+ @result.to_a.should == [[10, 9], [7, 6], [4, 3, 2, 1]]
+ end
- it "calls the block for length of the receiver enumerable minus one times" do
- times_called = 0
- @enum.chunk_while do |i, j|
- times_called += 1
- i - 1 == j
- end.to_a
- times_called.should == (@enum_length - 1)
- end
+ it "calls the block for length of the receiver enumerable minus one times" do
+ times_called = 0
+ @enum.chunk_while do |i, j|
+ times_called += 1
+ i - 1 == j
+ end.to_a
+ times_called.should == (@enum_length - 1)
end
+ end
- context "when not given a block" do
- it "raises an ArgumentError" do
- lambda { @enum.chunk_while }.should raise_error(ArgumentError)
- end
+ context "when not given a block" do
+ it "raises an ArgumentError" do
+ -> { @enum.chunk_while }.should raise_error(ArgumentError)
end
+ end
- context "on a single-element array" do
- it "ignores the block and returns an enumerator that yields [element]" do
- [1].chunk_while {|x| x.even?}.to_a.should == [[1]]
- end
+ context "on a single-element array" do
+ it "ignores the block and returns an enumerator that yields [element]" do
+ [1].chunk_while {|x| x.even?}.to_a.should == [[1]]
end
end
end
diff --git a/spec/ruby/core/enumerable/collect_concat_spec.rb b/spec/ruby/core/enumerable/collect_concat_spec.rb
index 6f21012060..6e34c9eb93 100644
--- a/spec/ruby/core/enumerable/collect_concat_spec.rb
+++ b/spec/ruby/core/enumerable/collect_concat_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/collect_concat', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/collect_concat'
describe "Enumerable#collect_concat" do
- it_behaves_like(:enumerable_collect_concat , :collect_concat)
+ it_behaves_like :enumerable_collect_concat , :collect_concat
end
diff --git a/spec/ruby/core/enumerable/collect_spec.rb b/spec/ruby/core/enumerable/collect_spec.rb
index a830eef9f7..1016b67798 100644
--- a/spec/ruby/core/enumerable/collect_spec.rb
+++ b/spec/ruby/core/enumerable/collect_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/collect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/collect'
describe "Enumerable#collect" do
- it_behaves_like(:enumerable_collect , :collect)
+ it_behaves_like :enumerable_collect , :collect
end
diff --git a/spec/ruby/core/enumerable/count_spec.rb b/spec/ruby/core/enumerable/count_spec.rb
index 9d1e08f3a9..50a1c8e1a4 100644
--- a/spec/ruby/core/enumerable/count_spec.rb
+++ b/spec/ruby/core/enumerable/count_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#count" do
before :each do
diff --git a/spec/ruby/core/enumerable/cycle_spec.rb b/spec/ruby/core/enumerable/cycle_spec.rb
index 2f5760992d..487086cba3 100644
--- a/spec/ruby/core/enumerable/cycle_spec.rb
+++ b/spec/ruby/core/enumerable/cycle_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorized'
describe "Enumerable#cycle" do
describe "passed no argument or nil" do
@@ -69,14 +69,14 @@ describe "Enumerable#cycle" do
enum.cycle(obj).to_a.should == [3, 2, 1, 3, 2, 1]
end
- it "raises a TypeError when the passed n can be coerced to Integer" do
+ it "raises a TypeError when the passed n cannot be coerced to Integer" do
enum = EnumerableSpecs::Numerous.new
- lambda{ enum.cycle("cat"){} }.should raise_error(TypeError)
+ ->{ enum.cycle("cat"){} }.should raise_error(TypeError)
end
it "raises an ArgumentError if more arguments are passed" do
enum = EnumerableSpecs::Numerous.new
- lambda{ enum.cycle(1, 2) {} }.should raise_error(ArgumentError)
+ ->{ enum.cycle(1, 2) {} }.should raise_error(ArgumentError)
end
it "gathers whole arrays as elements when each yields multiple" do
diff --git a/spec/ruby/core/enumerable/detect_spec.rb b/spec/ruby/core/enumerable/detect_spec.rb
index f69e456052..e912134fed 100644
--- a/spec/ruby/core/enumerable/detect_spec.rb
+++ b/spec/ruby/core/enumerable/detect_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/find', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/find'
describe "Enumerable#detect" do
- it_behaves_like(:enumerable_find , :detect)
+ it_behaves_like :enumerable_find , :detect
end
diff --git a/spec/ruby/core/enumerable/drop_spec.rb b/spec/ruby/core/enumerable/drop_spec.rb
index 1bcdc0ee9a..423cc0088b 100644
--- a/spec/ruby/core/enumerable/drop_spec.rb
+++ b/spec/ruby/core/enumerable/drop_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#drop" do
before :each do
@@ -7,13 +7,13 @@ describe "Enumerable#drop" do
end
it "requires exactly one argument" do
- lambda{ @enum.drop{} }.should raise_error(ArgumentError)
- lambda{ @enum.drop(1, 2){} }.should raise_error(ArgumentError)
+ ->{ @enum.drop{} }.should raise_error(ArgumentError)
+ ->{ @enum.drop(1, 2){} }.should raise_error(ArgumentError)
end
describe "passed a number n as an argument" do
it "raises ArgumentError if n < 0" do
- lambda{ @enum.drop(-1) }.should raise_error(ArgumentError)
+ ->{ @enum.drop(-1) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
@@ -34,9 +34,9 @@ describe "Enumerable#drop" do
EnumerableSpecs::Numerous.new(3, 2, 1, :go).drop(4).should == []
end
- it "raises a TypeError when the passed n can be coerced to Integer" do
- lambda{ @enum.drop("hat") }.should raise_error(TypeError)
- lambda{ @enum.drop(nil) }.should raise_error(TypeError)
+ it "raises a TypeError when the passed n cannot be coerced to Integer" do
+ ->{ @enum.drop("hat") }.should raise_error(TypeError)
+ ->{ @enum.drop(nil) }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/enumerable/drop_while_spec.rb b/spec/ruby/core/enumerable/drop_while_spec.rb
index 731b9588e4..636c3d284a 100644
--- a/spec/ruby/core/enumerable/drop_while_spec.rb
+++ b/spec/ruby/core/enumerable/drop_while_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#drop_while" do
before :each do
diff --git a/spec/ruby/core/enumerable/each_cons_spec.rb b/spec/ruby/core/enumerable/each_cons_spec.rb
index 6720199bc3..7d44f54f74 100644
--- a/spec/ruby/core/enumerable/each_cons_spec.rb
+++ b/spec/ruby/core/enumerable/each_cons_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorized'
describe "Enumerable#each_cons" do
before :each do
@@ -15,14 +15,14 @@ describe "Enumerable#each_cons" do
end
it "raises an ArgumentError if there is not a single parameter > 0" do
- lambda{ @enum.each_cons(0){} }.should raise_error(ArgumentError)
- lambda{ @enum.each_cons(-2){} }.should raise_error(ArgumentError)
- lambda{ @enum.each_cons{} }.should raise_error(ArgumentError)
- lambda{ @enum.each_cons(2,2){} }.should raise_error(ArgumentError)
- lambda{ @enum.each_cons(0) }.should raise_error(ArgumentError)
- lambda{ @enum.each_cons(-2) }.should raise_error(ArgumentError)
- lambda{ @enum.each_cons }.should raise_error(ArgumentError)
- lambda{ @enum.each_cons(2,2) }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons(0){} }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons(-2){} }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons{} }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons(2,2){} }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons(0) }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons(-2) }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons }.should raise_error(ArgumentError)
+ ->{ @enum.each_cons(2,2) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
diff --git a/spec/ruby/core/enumerable/each_entry_spec.rb b/spec/ruby/core/enumerable/each_entry_spec.rb
index 05d181a998..edf00f3137 100644
--- a/spec/ruby/core/enumerable/each_entry_spec.rb
+++ b/spec/ruby/core/enumerable/each_entry_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#each_entry" do
before :each do
@@ -27,8 +27,8 @@ describe "Enumerable#each_entry" do
end
it "raises an ArgumentError when extra arguments" do
- lambda { @enum.each_entry("one").to_a }.should raise_error(ArgumentError)
- lambda { @enum.each_entry("one"){}.to_a }.should raise_error(ArgumentError)
+ -> { @enum.each_entry("one").to_a }.should raise_error(ArgumentError)
+ -> { @enum.each_entry("one"){}.to_a }.should raise_error(ArgumentError)
end
it "passes extra arguments to #each" do
diff --git a/spec/ruby/core/enumerable/each_slice_spec.rb b/spec/ruby/core/enumerable/each_slice_spec.rb
index 62503fe206..ab3b79c344 100644
--- a/spec/ruby/core/enumerable/each_slice_spec.rb
+++ b/spec/ruby/core/enumerable/each_slice_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumeratorized'
describe "Enumerable#each_slice" do
before :each do
@@ -15,14 +15,14 @@ describe "Enumerable#each_slice" do
end
it "raises an ArgumentError if there is not a single parameter > 0" do
- lambda{ @enum.each_slice(0){} }.should raise_error(ArgumentError)
- lambda{ @enum.each_slice(-2){} }.should raise_error(ArgumentError)
- lambda{ @enum.each_slice{} }.should raise_error(ArgumentError)
- lambda{ @enum.each_slice(2,2){} }.should raise_error(ArgumentError)
- lambda{ @enum.each_slice(0) }.should raise_error(ArgumentError)
- lambda{ @enum.each_slice(-2) }.should raise_error(ArgumentError)
- lambda{ @enum.each_slice }.should raise_error(ArgumentError)
- lambda{ @enum.each_slice(2,2) }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice(0){} }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice(-2){} }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice{} }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice(2,2){} }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice(0) }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice(-2) }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice }.should raise_error(ArgumentError)
+ ->{ @enum.each_slice(2,2) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
diff --git a/spec/ruby/core/enumerable/each_with_index_spec.rb b/spec/ruby/core/enumerable/each_with_index_spec.rb
index 9884e71167..122e88eab7 100644
--- a/spec/ruby/core/enumerable/each_with_index_spec.rb
+++ b/spec/ruby/core/enumerable/each_with_index_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#each_with_index" do
diff --git a/spec/ruby/core/enumerable/each_with_object_spec.rb b/spec/ruby/core/enumerable/each_with_object_spec.rb
index 13a7c1c66d..35665e7019 100644
--- a/spec/ruby/core/enumerable/each_with_object_spec.rb
+++ b/spec/ruby/core/enumerable/each_with_object_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#each_with_object" do
before :each do
diff --git a/spec/ruby/core/enumerable/entries_spec.rb b/spec/ruby/core/enumerable/entries_spec.rb
index 94eceee713..83232cfa06 100644
--- a/spec/ruby/core/enumerable/entries_spec.rb
+++ b/spec/ruby/core/enumerable/entries_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/entries', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/entries'
describe "Enumerable#entries" do
- it_behaves_like(:enumerable_entries , :entries)
+ it_behaves_like :enumerable_entries , :entries
end
diff --git a/spec/ruby/core/enumerable/filter_map_spec.rb b/spec/ruby/core/enumerable/filter_map_spec.rb
new file mode 100644
index 0000000000..31acc277b4
--- /dev/null
+++ b/spec/ruby/core/enumerable/filter_map_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is '2.7' do
+ describe 'Enumerable#filter_map' do
+ before :each do
+ @numerous = EnumerableSpecs::Numerous.new(*(1..8).to_a)
+ end
+
+ it 'returns an empty array if there are no elements' do
+ EnumerableSpecs::Empty.new.filter_map { true }.should == []
+ end
+
+ it 'returns an array with truthy results of passing each element to block' do
+ @numerous.filter_map { |i| i * 2 if i.even? }.should == [4, 8, 12, 16]
+ @numerous.filter_map { |i| i * 2 }.should == [2, 4, 6, 8, 10, 12, 14, 16]
+ @numerous.filter_map { 0 }.should == [0, 0, 0, 0, 0, 0, 0, 0]
+ @numerous.filter_map { false }.should == []
+ @numerous.filter_map { nil }.should == []
+ end
+
+ it 'returns an enumerator when no block given' do
+ @numerous.filter_map.should be_an_instance_of(Enumerator)
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerable/filter_spec.rb b/spec/ruby/core/enumerable/filter_spec.rb
new file mode 100644
index 0000000000..f2dc7a7b71
--- /dev/null
+++ b/spec/ruby/core/enumerable/filter_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/find_all'
+
+ruby_version_is "2.6" do
+ describe "Enumerable#filter" do
+ it_behaves_like(:enumerable_find_all , :filter)
+ end
+end
diff --git a/spec/ruby/core/enumerable/find_all_spec.rb b/spec/ruby/core/enumerable/find_all_spec.rb
index 3d587d7709..ce9058fe77 100644
--- a/spec/ruby/core/enumerable/find_all_spec.rb
+++ b/spec/ruby/core/enumerable/find_all_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/find_all', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/find_all'
describe "Enumerable#find_all" do
- it_behaves_like(:enumerable_find_all , :find_all)
+ it_behaves_like :enumerable_find_all , :find_all
end
diff --git a/spec/ruby/core/enumerable/find_index_spec.rb b/spec/ruby/core/enumerable/find_index_spec.rb
index c118a61fcf..542660fe04 100644
--- a/spec/ruby/core/enumerable/find_index_spec.rb
+++ b/spec/ruby/core/enumerable/find_index_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#find_index" do
before :each do
diff --git a/spec/ruby/core/enumerable/find_spec.rb b/spec/ruby/core/enumerable/find_spec.rb
index 62e1194537..25aa3bf103 100644
--- a/spec/ruby/core/enumerable/find_spec.rb
+++ b/spec/ruby/core/enumerable/find_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/find', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/find'
describe "Enumerable#find" do
- it_behaves_like(:enumerable_find , :find)
+ it_behaves_like :enumerable_find , :find
end
diff --git a/spec/ruby/core/enumerable/first_spec.rb b/spec/ruby/core/enumerable/first_spec.rb
index a85550ee3b..1398807fa7 100644
--- a/spec/ruby/core/enumerable/first_spec.rb
+++ b/spec/ruby/core/enumerable/first_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/take', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/take'
describe "Enumerable#first" do
it "returns the first element" do
@@ -17,9 +17,9 @@ describe "Enumerable#first" do
EnumerableSpecs::YieldsMixed2.new.to_enum.first.should == nil
end
- it "raises a RangeError when passed a Bignum" do
+ it "raises a RangeError when passed an Integer" do
enum = EnumerableSpecs::Empty.new
- lambda { enum.first(bignum_value) }.should raise_error(RangeError)
+ -> { enum.first(bignum_value) }.should raise_error(RangeError)
end
describe "when passed an argument" do
diff --git a/spec/ruby/core/enumerable/fixtures/classes.rb b/spec/ruby/core/enumerable/fixtures/classes.rb
index 26a8aff8e2..fb4951c6e6 100644
--- a/spec/ruby/core/enumerable/fixtures/classes.rb
+++ b/spec/ruby/core/enumerable/fixtures/classes.rb
@@ -118,7 +118,7 @@ module EnumerableSpecs
end
end
- class ArrayConvertable
+ class ArrayConvertible
attr_accessor :called
def initialize(*values)
@values = values
@@ -135,7 +135,7 @@ module EnumerableSpecs
end
end
- class EnumConvertable
+ class EnumConvertible
attr_accessor :called
attr_accessor :sym
def initialize(delegate)
@@ -251,7 +251,7 @@ module EnumerableSpecs
end
end
- class ComparableWithFixnum
+ class ComparableWithInteger
include Comparable
def initialize(num)
@num = num
@@ -328,4 +328,18 @@ module EnumerableSpecs
EnumerableMapping.new(self, block)
end
end
+
+ class Pattern
+ attr_reader :yielded
+
+ def initialize(&block)
+ @block = block
+ @yielded = []
+ end
+
+ def ===(*args)
+ @yielded << args
+ @block.call(*args)
+ end
+ end
end # EnumerableSpecs utility classes
diff --git a/spec/ruby/core/enumerable/flat_map_spec.rb b/spec/ruby/core/enumerable/flat_map_spec.rb
index aaddeed05d..a294b9ddad 100644
--- a/spec/ruby/core/enumerable/flat_map_spec.rb
+++ b/spec/ruby/core/enumerable/flat_map_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/collect_concat', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/collect_concat'
describe "Enumerable#flat_map" do
- it_behaves_like(:enumerable_collect_concat , :flat_map)
+ it_behaves_like :enumerable_collect_concat , :flat_map
end
diff --git a/spec/ruby/core/enumerable/grep_spec.rb b/spec/ruby/core/enumerable/grep_spec.rb
index 777d5e538e..4e66bb85ea 100644
--- a/spec/ruby/core/enumerable/grep_spec.rb
+++ b/spec/ruby/core/enumerable/grep_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#grep" do
before :each do
@@ -29,6 +29,38 @@ describe "Enumerable#grep" do
ary.grep(/a(b)a/) { $1 }.should == ["b", "b"]
end
+ it "sets $~ in the block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep(/b/) { |e|
+ e.should == "abc"
+ $&.should == "b"
+ }
+
+ # Set by the failed match of "def"
+ $~.should == nil
+ end
+
+ ruby_version_is ""..."3.0.0" do
+ it "sets $~ to the last match when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep(/b/).should == ["abc"]
+
+ # Set by the failed match of "def"
+ $~.should == nil
+
+ ["abc", "def"].grep(/e/)
+ $&.should == "e"
+ end
+ end
+
+ ruby_version_is "3.0.0" do
+ it "does not set $~ when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep(/b/).should == ["abc"]
+ $&.should == "z"
+ end
+ end
+
describe "with a block" do
before :each do
@numerous = EnumerableSpecs::Numerous.new(*(0..9).to_a)
diff --git a/spec/ruby/core/enumerable/grep_v_spec.rb b/spec/ruby/core/enumerable/grep_v_spec.rb
index 05c43a43ef..8cae3ac618 100644
--- a/spec/ruby/core/enumerable/grep_v_spec.rb
+++ b/spec/ruby/core/enumerable/grep_v_spec.rb
@@ -1,43 +1,73 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-
-ruby_version_is "2.3" do
- describe "Enumerable#grep_v" do
- before :each do
- @numerous = EnumerableSpecs::Numerous.new(*(0..9).to_a)
- def (@odd_matcher = BasicObject.new).===(obj)
- obj.odd?
- end
- end
-
- describe "without block" do
- it "returns an Array of matched elements" do
- @numerous.grep_v(@odd_matcher).should == [0, 2, 4, 6, 8]
- end
-
- it "compares pattern with gathered array when yielded with multiple arguments" do
- (unmatcher = Object.new).stub!(:===).and_return(false)
- EnumerableSpecs::YieldsMixed2.new.grep_v(unmatcher).should == EnumerableSpecs::YieldsMixed2.gathered_yields
- end
-
- it "raises an ArgumentError when not given a pattern" do
- -> { @numerous.grep_v }.should raise_error(ArgumentError)
- end
- end
-
- describe "with block" do
- it "returns an Array of matched elements that mapped by the block" do
- @numerous.grep_v(@odd_matcher) { |n| n * 2 }.should == [0, 4, 8, 12, 16]
- end
-
- it "calls the block with gathered array when yielded with multiple arguments" do
- (unmatcher = Object.new).stub!(:===).and_return(false)
- EnumerableSpecs::YieldsMixed2.new.grep_v(unmatcher){ |e| e }.should == EnumerableSpecs::YieldsMixed2.gathered_yields
- end
-
- it "raises an ArgumentError when not given a pattern" do
- -> { @numerous.grep_v { |e| e } }.should raise_error(ArgumentError)
- end
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "Enumerable#grep_v" do
+ before :each do
+ @numerous = EnumerableSpecs::Numerous.new(*(0..9).to_a)
+ def (@odd_matcher = BasicObject.new).===(obj)
+ obj.odd?
+ end
+ end
+
+ it "sets $~ in the block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep_v(/e/) { |e|
+ e.should == "abc"
+ $~.should == nil
+ }
+
+ # Set by the match of "def"
+ $&.should == "e"
+ end
+
+ ruby_version_is ""..."3.0.0" do
+ it "sets $~ to the last match when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep_v(/e/).should == ["abc"]
+
+ # Set by the match of "def"
+ $&.should == "e"
+
+ ["abc", "def"].grep_v(/b/)
+ $&.should == nil
+ end
+ end
+
+ ruby_version_is "3.0.0" do
+ it "does not set $~ when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep_v(/e/).should == ["abc"]
+ $&.should == "z"
+ end
+ end
+
+ describe "without block" do
+ it "returns an Array of matched elements" do
+ @numerous.grep_v(@odd_matcher).should == [0, 2, 4, 6, 8]
+ end
+
+ it "compares pattern with gathered array when yielded with multiple arguments" do
+ (unmatcher = Object.new).stub!(:===).and_return(false)
+ EnumerableSpecs::YieldsMixed2.new.grep_v(unmatcher).should == EnumerableSpecs::YieldsMixed2.gathered_yields
+ end
+
+ it "raises an ArgumentError when not given a pattern" do
+ -> { @numerous.grep_v }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe "with block" do
+ it "returns an Array of matched elements that mapped by the block" do
+ @numerous.grep_v(@odd_matcher) { |n| n * 2 }.should == [0, 4, 8, 12, 16]
+ end
+
+ it "calls the block with gathered array when yielded with multiple arguments" do
+ (unmatcher = Object.new).stub!(:===).and_return(false)
+ EnumerableSpecs::YieldsMixed2.new.grep_v(unmatcher){ |e| e }.should == EnumerableSpecs::YieldsMixed2.gathered_yields
+ end
+
+ it "raises an ArgumentError when not given a pattern" do
+ -> { @numerous.grep_v { |e| e } }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/enumerable/group_by_spec.rb b/spec/ruby/core/enumerable/group_by_spec.rb
index 3513512ebf..52b5a68d64 100644
--- a/spec/ruby/core/enumerable/group_by_spec.rb
+++ b/spec/ruby/core/enumerable/group_by_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#group_by" do
it "returns a hash with values grouped according to the block" do
@@ -33,12 +33,14 @@ describe "Enumerable#group_by" do
[3, 4, 5] => [[3, 4, 5]] }
end
- it "returns a tainted hash if self is tainted" do
- EnumerableSpecs::Empty.new.taint.group_by {}.tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "returns a tainted hash if self is tainted" do
+ EnumerableSpecs::Empty.new.taint.group_by {}.tainted?.should be_true
+ end
- it "returns an untrusted hash if self is untrusted" do
- EnumerableSpecs::Empty.new.untrust.group_by {}.untrusted?.should be_true
+ it "returns an untrusted hash if self is untrusted" do
+ EnumerableSpecs::Empty.new.untrust.group_by {}.untrusted?.should be_true
+ end
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :group_by
diff --git a/spec/ruby/core/enumerable/include_spec.rb b/spec/ruby/core/enumerable/include_spec.rb
index 2cc0b6e83a..dab1b04451 100644
--- a/spec/ruby/core/enumerable/include_spec.rb
+++ b/spec/ruby/core/enumerable/include_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/include', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/include'
describe "Enumerable#include?" do
- it_behaves_like(:enumerable_include, :include?)
+ it_behaves_like :enumerable_include, :include?
end
diff --git a/spec/ruby/core/enumerable/inject_spec.rb b/spec/ruby/core/enumerable/inject_spec.rb
index 289a451552..e1fe216144 100644
--- a/spec/ruby/core/enumerable/inject_spec.rb
+++ b/spec/ruby/core/enumerable/inject_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/inject', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/inject'
describe "Enumerable#inject" do
it_behaves_like :enumerable_inject, :inject
diff --git a/spec/ruby/core/enumerable/lazy_spec.rb b/spec/ruby/core/enumerable/lazy_spec.rb
index f989fb947e..9a9ead81a0 100644
--- a/spec/ruby/core/enumerable/lazy_spec.rb
+++ b/spec/ruby/core/enumerable/lazy_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#lazy" do
it "returns an instance of Enumerator::Lazy" do
diff --git a/spec/ruby/core/enumerable/map_spec.rb b/spec/ruby/core/enumerable/map_spec.rb
index b2ddf1eb9d..d65aec238c 100644
--- a/spec/ruby/core/enumerable/map_spec.rb
+++ b/spec/ruby/core/enumerable/map_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/collect', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/collect'
describe "Enumerable#map" do
- it_behaves_like(:enumerable_collect , :map)
+ it_behaves_like :enumerable_collect , :map
end
diff --git a/spec/ruby/core/enumerable/max_by_spec.rb b/spec/ruby/core/enumerable/max_by_spec.rb
index 4058cf0a40..ec1738ea3b 100644
--- a/spec/ruby/core/enumerable/max_by_spec.rb
+++ b/spec/ruby/core/enumerable/max_by_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#max_by" do
it "returns an enumerator if no block" do
@@ -67,7 +67,7 @@ describe "Enumerable#max_by" do
context "when n is negative" do
it "raises an ArgumentError" do
- lambda { @enum.max_by(-1) { |i| i.to_s } }.should raise_error(ArgumentError)
+ -> { @enum.max_by(-1) { |i| i.to_s } }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/enumerable/max_spec.rb b/spec/ruby/core/enumerable/max_spec.rb
index e283a5d0e2..0c11ca0969 100644
--- a/spec/ruby/core/enumerable/max_spec.rb
+++ b/spec/ruby/core/enumerable/max_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#max" do
before :each do
@@ -36,16 +36,16 @@ describe "Enumerable#max" do
end
it "raises a NoMethodError for elements without #<=>" do
- lambda do
+ -> do
EnumerableSpecs::EachDefiner.new(BasicObject.new, BasicObject.new).max
end.should raise_error(NoMethodError)
end
it "raises an ArgumentError for incomparable elements" do
- lambda do
+ -> do
EnumerableSpecs::EachDefiner.new(11,"22").max
end.should raise_error(ArgumentError)
- lambda do
+ -> do
EnumerableSpecs::EachDefiner.new(11,12,22,33).max{|a, b| nil}
end.should raise_error(ArgumentError)
end
@@ -106,7 +106,7 @@ describe "Enumerable#max" do
context "that is negative" do
it "raises an ArgumentError" do
- lambda { @e_ints.max(-1) }.should raise_error(ArgumentError)
+ -> { @e_ints.max(-1) }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/enumerable/member_spec.rb b/spec/ruby/core/enumerable/member_spec.rb
index 862c949817..1fe3cebd28 100644
--- a/spec/ruby/core/enumerable/member_spec.rb
+++ b/spec/ruby/core/enumerable/member_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/include', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/include'
describe "Enumerable#member?" do
- it_behaves_like(:enumerable_include, :member?)
+ it_behaves_like :enumerable_include, :member?
end
diff --git a/spec/ruby/core/enumerable/min_by_spec.rb b/spec/ruby/core/enumerable/min_by_spec.rb
index 24fe995f09..3ff87e49d8 100644
--- a/spec/ruby/core/enumerable/min_by_spec.rb
+++ b/spec/ruby/core/enumerable/min_by_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#min_by" do
it "returns an enumerator if no block" do
@@ -67,7 +67,7 @@ describe "Enumerable#min_by" do
context "when n is negative" do
it "raises an ArgumentError" do
- lambda { @enum.min_by(-1) { |i| i.to_s } }.should raise_error(ArgumentError)
+ -> { @enum.min_by(-1) { |i| i.to_s } }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/enumerable/min_spec.rb b/spec/ruby/core/enumerable/min_spec.rb
index f56d0420c9..4b6ae248fa 100644
--- a/spec/ruby/core/enumerable/min_spec.rb
+++ b/spec/ruby/core/enumerable/min_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#min" do
before :each do
@@ -36,16 +36,16 @@ describe "Enumerable#min" do
end
it "raises a NoMethodError for elements without #<=>" do
- lambda do
+ -> do
EnumerableSpecs::EachDefiner.new(BasicObject.new, BasicObject.new).min
end.should raise_error(NoMethodError)
end
it "raises an ArgumentError for incomparable elements" do
- lambda do
+ -> do
EnumerableSpecs::EachDefiner.new(11,"22").min
end.should raise_error(ArgumentError)
- lambda do
+ -> do
EnumerableSpecs::EachDefiner.new(11,12,22,33).min{|a, b| nil}
end.should raise_error(ArgumentError)
end
@@ -110,7 +110,7 @@ describe "Enumerable#min" do
context "that is negative" do
it "raises an ArgumentError" do
- lambda { @e_ints.min(-1) }.should raise_error(ArgumentError)
+ -> { @e_ints.min(-1) }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/enumerable/minmax_by_spec.rb b/spec/ruby/core/enumerable/minmax_by_spec.rb
index c92eb381a4..a6a9249270 100644
--- a/spec/ruby/core/enumerable/minmax_by_spec.rb
+++ b/spec/ruby/core/enumerable/minmax_by_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#minmax_by" do
it "returns an enumerator if no block" do
diff --git a/spec/ruby/core/enumerable/minmax_spec.rb b/spec/ruby/core/enumerable/minmax_spec.rb
index 10bc9b68e4..f5f17ef079 100644
--- a/spec/ruby/core/enumerable/minmax_spec.rb
+++ b/spec/ruby/core/enumerable/minmax_spec.rb
@@ -1,41 +1,17 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative '../../shared/enumerable/minmax'
describe "Enumerable#minmax" do
before :each do
@enum = EnumerableSpecs::Numerous.new(6, 4, 5, 10, 8)
-
+ @empty_enum = EnumerableSpecs::Empty.new
+ @incomparable_enum = EnumerableSpecs::Numerous.new(BasicObject.new, BasicObject.new)
+ @incompatible_enum = EnumerableSpecs::Numerous.new(11,"22")
@strs = EnumerableSpecs::Numerous.new("333", "2", "60", "55555", "1010", "111")
end
- it "min should return the minimum element" do
- @enum.minmax.should == [4, 10]
- @strs.minmax.should == ["1010", "60" ]
- end
-
- it "returns [nil, nil] for an empty Enumerable" do
- EnumerableSpecs::Empty.new.minmax.should == [nil, nil]
- end
-
- it "raises an ArgumentError when elements are incomparable" do
- lambda do
- EnumerableSpecs::Numerous.new(11,"22").minmax
- end.should raise_error(ArgumentError)
- lambda do
- EnumerableSpecs::Numerous.new(11,12,22,33).minmax{|a, b| nil}
- end.should raise_error(ArgumentError)
- end
-
- it "raises a NoMethodError for elements without #<=>" do
- lambda do
- EnumerableSpecs::Numerous.new(BasicObject.new, BasicObject.new).minmax
- end.should raise_error(NoMethodError)
- end
-
- it "returns the minimum when using a block rule" do
- @enum.minmax {|a,b| b <=> a }.should == [10, 4]
- @strs.minmax {|a,b| a.length <=> b.length }.should == ["2", "55555"]
- end
+ it_behaves_like :enumerable_minmax, :minmax
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb
index 0646c13b34..ec48eaf0a7 100644
--- a/spec/ruby/core/enumerable/none_spec.rb
+++ b/spec/ruby/core/enumerable/none_spec.rb
@@ -1,57 +1,156 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#none?" do
- it "returns true if none of the elements in self are true" do
- e = EnumerableSpecs::Numerous.new(false, nil, false)
- e.none?.should be_true
+ before :each do
+ @empty = EnumerableSpecs::Empty.new
+ @enum = EnumerableSpecs::Numerous.new
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
end
- it "returns false if at least one of the elements in self are true" do
- e = EnumerableSpecs::Numerous.new(false, nil, true, false)
- e.none?.should be_false
+ it "always returns true on empty enumeration" do
+ @empty.should.none?
+ @empty.none? { true }.should == true
end
- it "gathers whole arrays as elements when each yields multiple" do
- multi = EnumerableSpecs::YieldsMultiWithFalse.new
- multi.none?.should be_false
+ it "raises an ArgumentError when more than 1 argument is provided" do
+ -> { @enum.none?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { [].none?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { {}.none?(1, 2, 3) }.should raise_error(ArgumentError)
end
-end
-describe "Enumerable#none? with a block" do
- before :each do
- @e = EnumerableSpecs::Numerous.new(1,1,2,3,4)
- end
+ it "does not hide exceptions out of #each" do
+ -> {
+ EnumerableSpecs::ThrowingEach.new.none?
+ }.should raise_error(RuntimeError)
- it "passes each element to the block in turn until it returns true" do
- acc = []
- @e.none? {|e| acc << e; false }
- acc.should == [1,1,2,3,4]
+ -> {
+ EnumerableSpecs::ThrowingEach.new.none? { false }
+ }.should raise_error(RuntimeError)
end
- it "stops passing elements to the block when it returns true" do
- acc = []
- @e.none? {|e| acc << e; e == 3 ? true : false }
- acc.should == [1,1,2,3]
- end
+ describe "with no block" do
+ it "returns true if none of the elements in self are true" do
+ e = EnumerableSpecs::Numerous.new(false, nil, false)
+ e.none?.should be_true
+ end
- it "returns true if the block never returns true" do
- @e.none? {|e| false }.should be_true
- end
+ it "returns false if at least one of the elements in self are true" do
+ e = EnumerableSpecs::Numerous.new(false, nil, true, false)
+ e.none?.should be_false
+ end
- it "returns false if the block ever returns true" do
- @e.none? {|e| e == 3 ? true : false }.should be_false
+ it "gathers whole arrays as elements when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMultiWithFalse.new
+ multi.none?.should be_false
+ end
end
- it "gathers initial args as elements when each yields multiple" do
- multi = EnumerableSpecs::YieldsMulti.new
- multi.none? {|e| e == [1, 2] }.should be_true
+ describe "with a block" do
+ before :each do
+ @e = EnumerableSpecs::Numerous.new(1,1,2,3,4)
+ end
+
+ it "passes each element to the block in turn until it returns true" do
+ acc = []
+ @e.none? {|e| acc << e; false }
+ acc.should == [1,1,2,3,4]
+ end
+
+ it "stops passing elements to the block when it returns true" do
+ acc = []
+ @e.none? {|e| acc << e; e == 3 ? true : false }
+ acc.should == [1,1,2,3]
+ end
+
+ it "returns true if the block never returns true" do
+ @e.none? {|e| false }.should be_true
+ end
+
+ it "returns false if the block ever returns true" do
+ @e.none? {|e| e == 3 ? true : false }.should be_false
+ end
+
+ it "does not hide exceptions out of the block" do
+ -> {
+ @enum.none? { raise "from block" }
+ }.should raise_error(RuntimeError)
+ end
+
+ it "gathers initial args as elements when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ yielded = []
+ multi.none? { |e| yielded << e; false }
+ yielded.should == [1, 3, 6]
+ end
+
+ it "yields multiple arguments when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ yielded = []
+ multi.none? { |*args| yielded << args; false }
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
+ end
end
- it "yields multiple arguments when each yields multiple" do
- multi = EnumerableSpecs::YieldsMulti.new
- yielded = []
- multi.none? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2]]
+ describe 'when given a pattern argument' do
+ it "calls `===` on the pattern the return value " do
+ pattern = EnumerableSpecs::Pattern.new { |x| x == 3 }
+ @enum1.none?(pattern).should == true
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+ end
+
+ # may raise an exception in future versions
+ ruby_version_is ""..."2.6" do
+ it "ignores block" do
+ @enum2.none?(Integer) { raise }.should == true
+ [1, 2, nil].none?(TrueClass) { raise }.should == true
+ {a: 1}.none?(Hash) { raise }.should == true
+ end
+ end
+
+ it "always returns true on empty enumeration" do
+ @empty.none?(Integer).should == true
+ [].none?(Integer).should == true
+ {}.none?(NilClass).should == true
+ end
+
+ it "does not hide exceptions out of #each" do
+ -> {
+ EnumerableSpecs::ThrowingEach.new.none?(Integer)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "returns true if the pattern never returns a truthy value" do
+ @enum2.none?(Integer).should == true
+ pattern = EnumerableSpecs::Pattern.new { |x| nil }
+ @enum.none?(pattern).should == true
+
+ [1, 42, 3].none?(pattern).should == true
+ {a: 1, b: 2}.none?(pattern).should == true
+ end
+
+ it "returns false if the pattern ever returns other than false or nil" do
+ pattern = EnumerableSpecs::Pattern.new { |x| x < 0 }
+ @enum1.none?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+
+ [1, 2, 3, -1].none?(pattern).should == false
+ {a: 1}.none?(Array).should == false
+ end
+
+ it "does not hide exceptions out of pattern#===" do
+ pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
+ -> {
+ @enum.none?(pattern)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ pattern = EnumerableSpecs::Pattern.new { false }
+ multi.none?(pattern).should == true
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
+ end
end
end
diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb
index 818d4663a4..6489c84742 100644
--- a/spec/ruby/core/enumerable/one_spec.rb
+++ b/spec/ruby/core/enumerable/one_spec.rb
@@ -1,8 +1,55 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#one?" do
- describe "when passed a block" do
+ before :each do
+ @empty = EnumerableSpecs::Empty.new
+ @enum = EnumerableSpecs::Numerous.new
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
+ end
+
+ it "always returns false on empty enumeration" do
+ @empty.should_not.one?
+ @empty.one? { true }.should == false
+ end
+
+ it "raises an ArgumentError when more than 1 argument is provided" do
+ -> { @enum.one?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { [].one?(1, 2, 3) }.should raise_error(ArgumentError)
+ -> { {}.one?(1, 2, 3) }.should raise_error(ArgumentError)
+ end
+
+ it "does not hide exceptions out of #each" do
+ -> {
+ EnumerableSpecs::ThrowingEach.new.one?
+ }.should raise_error(RuntimeError)
+
+ -> {
+ EnumerableSpecs::ThrowingEach.new.one? { false }
+ }.should raise_error(RuntimeError)
+ end
+
+ describe "with no block" do
+ it "returns true if only one element evaluates to true" do
+ [false, nil, true].one?.should be_true
+ end
+
+ it "returns false if two elements evaluate to true" do
+ [false, :value, nil, true].one?.should be_false
+ end
+
+ it "returns false if all elements evaluate to false" do
+ [false, nil, false].one?.should be_false
+ end
+
+ it "gathers whole arrays as elements when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMultiWithSingleTrue.new
+ multi.one?.should be_false
+ end
+ end
+
+ describe "with a block" do
it "returns true if block returns true once" do
[:a, :b, :c].one? { |s| s == :a }.should be_true
end
@@ -15,35 +62,97 @@ describe "Enumerable#one?" do
[:a, :b, :c].one? { |s| s == :d }.should be_false
end
+ it "does not hide exceptions out of the block" do
+ -> {
+ @enum.one? { raise "from block" }
+ }.should raise_error(RuntimeError)
+ end
+
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
- multi.one? {|e| e == 1 }.should be_true
+ yielded = []
+ multi.one? { |e| yielded << e; false }.should == false
+ yielded.should == [1, 3, 6]
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
- multi.one? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2], [3, 4]]
+ multi.one? { |*args| yielded << args; false }.should == false
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
end
- describe "when not passed a block" do
- it "returns true if only one element evaluates to true" do
- [false, nil, true].one?.should be_true
+
+ describe 'when given a pattern argument' do
+ it "calls `===` on the pattern the return value " do
+ pattern = EnumerableSpecs::Pattern.new { |x| x == 1 }
+ @enum1.one?(pattern).should == true
+ pattern.yielded.should == [[0], [1], [2], [-1]]
end
- it "returns false if two elements evaluate to true" do
- [false, :value, nil, true].one?.should be_false
+ # may raise an exception in future versions
+ ruby_version_is ""..."2.6" do
+ it "ignores block" do
+ @enum2.one?(NilClass) { raise }.should == true
+ [1, 2, nil].one?(NilClass) { raise }.should == true
+ {a: 1}.one?(Array) { raise }.should == true
+ end
end
- it "returns false if all elements evaluate to false" do
- [false, nil, false].one?.should be_false
+ it "always returns false on empty enumeration" do
+ @empty.one?(Integer).should == false
+ [].one?(Integer).should == false
+ {}.one?(NilClass).should == false
end
- it "gathers whole arrays as elements when each yields multiple" do
- multi = EnumerableSpecs::YieldsMultiWithSingleTrue.new
- multi.one?.should be_false
+ it "does not hide exceptions out of #each" do
+ -> {
+ EnumerableSpecs::ThrowingEach.new.one?(Integer)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "returns true if the pattern returns a truthy value only once" do
+ @enum2.one?(NilClass).should == true
+ pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
+ @enum1.one?(pattern).should == true
+
+ [1, 2, 42, 3].one?(pattern).should == true
+
+ pattern = EnumerableSpecs::Pattern.new { |x| x == [:b, 2] }
+ {a: 1, b: 2}.one?(pattern).should == true
+ end
+
+ it "returns false if the pattern returns a truthy value more than once" do
+ pattern = EnumerableSpecs::Pattern.new { |x| !x }
+ @enum2.one?(pattern).should == false
+ pattern.yielded.should == [[nil], [false]]
+
+ [1, 2, 3].one?(Integer).should == false
+ {a: 1, b: 2}.one?(Array).should == false
+ end
+
+ it "returns false if the pattern never returns a truthy value" do
+ pattern = EnumerableSpecs::Pattern.new { |x| nil }
+ @enum1.one?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+
+ [1, 2, 3].one?(pattern).should == false
+ {a: 1}.one?(pattern).should == false
+ end
+
+ it "does not hide exceptions out of pattern#===" do
+ pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
+ -> {
+ @enum.one?(pattern)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ pattern = EnumerableSpecs::Pattern.new { false }
+ multi.one?(pattern).should == false
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
end
end
diff --git a/spec/ruby/core/enumerable/partition_spec.rb b/spec/ruby/core/enumerable/partition_spec.rb
index 4319a9328f..d3d220b4b4 100644
--- a/spec/ruby/core/enumerable/partition_spec.rb
+++ b/spec/ruby/core/enumerable/partition_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#partition" do
it "returns two arrays, the first containing elements for which the block is true, the second containing the rest" do
diff --git a/spec/ruby/core/enumerable/reduce_spec.rb b/spec/ruby/core/enumerable/reduce_spec.rb
index 8afecb2a8e..bc8691c1b0 100644
--- a/spec/ruby/core/enumerable/reduce_spec.rb
+++ b/spec/ruby/core/enumerable/reduce_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/inject', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/inject'
describe "Enumerable#reduce" do
it_behaves_like :enumerable_inject, :reduce
diff --git a/spec/ruby/core/enumerable/reject_spec.rb b/spec/ruby/core/enumerable/reject_spec.rb
index 3dbfb07067..0d86b49ea2 100644
--- a/spec/ruby/core/enumerable/reject_spec.rb
+++ b/spec/ruby/core/enumerable/reject_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#reject" do
it "returns an array of the elements for which block is false" do
diff --git a/spec/ruby/core/enumerable/reverse_each_spec.rb b/spec/ruby/core/enumerable/reverse_each_spec.rb
index 62c3c0daef..2b1c233488 100644
--- a/spec/ruby/core/enumerable/reverse_each_spec.rb
+++ b/spec/ruby/core/enumerable/reverse_each_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#reverse_each" do
it "traverses enum in reverse order and pass each element to block" do
diff --git a/spec/ruby/core/enumerable/select_spec.rb b/spec/ruby/core/enumerable/select_spec.rb
index b4da35c754..11168eb42e 100644
--- a/spec/ruby/core/enumerable/select_spec.rb
+++ b/spec/ruby/core/enumerable/select_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/find_all', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/find_all'
describe "Enumerable#select" do
- it_behaves_like(:enumerable_find_all , :select)
+ it_behaves_like :enumerable_find_all , :select
end
diff --git a/spec/ruby/core/enumerable/shared/collect.rb b/spec/ruby/core/enumerable/shared/collect.rb
index f66c539904..71b8acd526 100644
--- a/spec/ruby/core/enumerable/shared/collect.rb
+++ b/spec/ruby/core/enumerable/shared/collect.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../enumerable_enumeratorized', __FILE__)
+require_relative 'enumerable_enumeratorized'
describe :enumerable_collect, shared: true do
before :each do
@@ -22,11 +22,47 @@ describe :enumerable_collect, shared: true do
multi.send(@method) {|e| e}.should == [1,3,6]
end
+ it "only yields increasing values for a Range" do
+ (1..0).send(@method) { |x| x }.should == []
+ (1..1).send(@method) { |x| x }.should == [1]
+ (1..2).send(@method) { |x| x }.should == [1, 2]
+ end
+
it "returns an enumerator when no block given" do
enum = EnumerableSpecs::Numerous.new.send(@method)
enum.should be_an_instance_of(Enumerator)
enum.each { |i| -i }.should == [-2, -5, -3, -6, -1, -4]
end
+ it "reports the same arity as the given block" do
+ entries = [0, 1, 3, 4, 5, 6]
+ numerous = EnumerableSpecs::Numerous.new(*entries)
+
+ def numerous.each(&block)
+ ScratchPad << block.arity
+ super
+ end
+
+ numerous.send(@method) { |a, b| a % 2 }.should == [0, 1, 1, 0, 1, 0]
+ ScratchPad.recorded.should == [2]
+ ScratchPad.clear
+ ScratchPad.record []
+ numerous.send(@method) { |i| i }.should == entries
+ ScratchPad.recorded.should == [1]
+ end
+
+ it "yields 2 arguments for a Hash" do
+ c = Class.new do
+ def register(a, b)
+ ScratchPad << [a, b]
+ end
+ end
+ m = c.new.method(:register)
+
+ ScratchPad.record []
+ { 1 => 'a', 2 => 'b' }.map(&m)
+ ScratchPad.recorded.should == [[1, 'a'], [2, 'b']]
+ end
+
it_should_behave_like :enumerable_enumeratorized_with_origin_size
end
diff --git a/spec/ruby/core/enumerable/shared/collect_concat.rb b/spec/ruby/core/enumerable/shared/collect_concat.rb
index 54e10692eb..ddd431baeb 100644
--- a/spec/ruby/core/enumerable/shared/collect_concat.rb
+++ b/spec/ruby/core/enumerable/shared/collect_concat.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../enumerable_enumeratorized', __FILE__)
+require_relative 'enumerable_enumeratorized'
describe :enumerable_collect_concat, shared: true do
it "yields elements to the block and flattens one level" do
@@ -41,7 +41,7 @@ describe :enumerable_collect_concat, shared: true do
obj = mock("to_ary defined")
obj.should_receive(:to_ary).and_return("array")
- lambda { [1, obj, 3].send(@method) { |i| i } }.should raise_error(TypeError)
+ -> { [1, obj, 3].send(@method) { |i| i } }.should raise_error(TypeError)
end
it "returns an enumerator when no block given" do
diff --git a/spec/ruby/core/enumerable/shared/entries.rb b/spec/ruby/core/enumerable/shared/entries.rb
index f52844cb45..590ce73bcf 100644
--- a/spec/ruby/core/enumerable/shared/entries.rb
+++ b/spec/ruby/core/enumerable/shared/entries.rb
@@ -14,11 +14,13 @@ describe :enumerable_entries, shared: true do
count.arguments_passed.should == [:hello, "world"]
end
- it "returns a tainted array if self is tainted" do
- EnumerableSpecs::Empty.new.taint.send(@method).tainted?.should be_true
- end
+ ruby_version_is ''...'2.7' do
+ it "returns a tainted array if self is tainted" do
+ EnumerableSpecs::Empty.new.taint.send(@method).tainted?.should be_true
+ end
- it "returns an untrusted array if self is untrusted" do
- EnumerableSpecs::Empty.new.untrust.send(@method).untrusted?.should be_true
+ it "returns an untrusted array if self is untrusted" do
+ EnumerableSpecs::Empty.new.untrust.send(@method).untrusted?.should be_true
+ end
end
end
diff --git a/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb b/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb
index b03ce9ed4e..e2bbe18eda 100644
--- a/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb
+++ b/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../enumeratorized', __FILE__)
+require_relative 'enumeratorized'
describe :enumerable_enumeratorized_with_unknown_size, shared: true do
describe "Enumerable with size" do
diff --git a/spec/ruby/core/enumerable/shared/find.rb b/spec/ruby/core/enumerable/shared/find.rb
index 4cbbf07be0..61d63ba3d5 100644
--- a/spec/ruby/core/enumerable/shared/find.rb
+++ b/spec/ruby/core/enumerable/shared/find.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../enumerable_enumeratorized', __FILE__)
+require_relative 'enumerable_enumeratorized'
describe :enumerable_find, shared: true do
# #detect and #find are aliases, so we only need one function
@@ -29,26 +29,30 @@ describe :enumerable_find, shared: true do
end
it "returns the value of the ifnone proc if the block is false" do
- fail_proc = lambda { "cheeseburgers" }
+ fail_proc = -> { "cheeseburgers" }
@numerous.send(@method, fail_proc) {|e| false }.should == "cheeseburgers"
end
it "doesn't call the ifnone proc if an element is found" do
- fail_proc = lambda { raise "This shouldn't have been called" }
+ fail_proc = -> { raise "This shouldn't have been called" }
@numerous.send(@method, fail_proc) {|e| e == @elements.first }.should == 2
end
it "calls the ifnone proc only once when the block is false" do
times = 0
- fail_proc = lambda { times += 1; raise if times > 1; "cheeseburgers" }
+ fail_proc = -> { times += 1; raise if times > 1; "cheeseburgers" }
@numerous.send(@method, fail_proc) {|e| false }.should == "cheeseburgers"
end
it "calls the ifnone proc when there are no elements" do
- fail_proc = lambda { "yay" }
+ fail_proc = -> { "yay" }
@empty.send(@method, fail_proc) {|e| true}.should == "yay"
end
+ it "ignores the ifnone argument when nil" do
+ @numerous.send(@method, nil) {|e| false }.should == nil
+ end
+
it "passes through the values yielded by #each_with_index" do
[:a, :b].each_with_index.send(@method) { |x, i| ScratchPad << [x, i]; nil }
ScratchPad.recorded.should == [[:a, 0], [:b, 1]]
@@ -60,7 +64,7 @@ describe :enumerable_find, shared: true do
it "passes the ifnone proc to the enumerator" do
times = 0
- fail_proc = lambda { times += 1; raise if times > 1; "cheeseburgers" }
+ fail_proc = -> { times += 1; raise if times > 1; "cheeseburgers" }
@numerous.send(@method, fail_proc).each {|e| false }.should == "cheeseburgers"
end
diff --git a/spec/ruby/core/enumerable/shared/find_all.rb b/spec/ruby/core/enumerable/shared/find_all.rb
index 3e15c68e9f..1bbe71f372 100644
--- a/spec/ruby/core/enumerable/shared/find_all.rb
+++ b/spec/ruby/core/enumerable/shared/find_all.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../enumerable_enumeratorized', __FILE__)
+require_relative 'enumerable_enumeratorized'
describe :enumerable_find_all, shared: true do
before :each do
diff --git a/spec/ruby/core/enumerable/shared/take.rb b/spec/ruby/core/enumerable/shared/take.rb
index bf2536acda..ce2ace20fa 100644
--- a/spec/ruby/core/enumerable/shared/take.rb
+++ b/spec/ruby/core/enumerable/shared/take.rb
@@ -25,7 +25,7 @@ describe :enumerable_take, shared: true do
end
it "raises an ArgumentError when count is negative" do
- lambda { @enum.send(@method, -1) }.should raise_error(ArgumentError)
+ -> { @enum.send(@method, -1) }.should raise_error(ArgumentError)
end
it "returns the entire array when count > length" do
@@ -40,11 +40,11 @@ describe :enumerable_take, shared: true do
end
it "raises a TypeError if the passed argument is not numeric" do
- lambda { @enum.send(@method, nil) }.should raise_error(TypeError)
- lambda { @enum.send(@method, "a") }.should raise_error(TypeError)
+ -> { @enum.send(@method, nil) }.should raise_error(TypeError)
+ -> { @enum.send(@method, "a") }.should raise_error(TypeError)
obj = mock("nonnumeric")
- lambda { @enum.send(@method, obj) }.should raise_error(TypeError)
+ -> { @enum.send(@method, obj) }.should raise_error(TypeError)
end
it "gathers whole arrays as elements when each yields multiple" do
diff --git a/spec/ruby/core/enumerable/slice_after_spec.rb b/spec/ruby/core/enumerable/slice_after_spec.rb
index a199b9f1ed..0e46688db1 100644
--- a/spec/ruby/core/enumerable/slice_after_spec.rb
+++ b/spec/ruby/core/enumerable/slice_after_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#slice_after" do
before :each do
@@ -41,14 +41,14 @@ describe "Enumerable#slice_after" do
describe "and an argument" do
it "raises an ArgumentError" do
- lambda { @enum.slice_after(42) { |i| i == 6 } }.should raise_error(ArgumentError)
+ -> { @enum.slice_after(42) { |i| i == 6 } }.should raise_error(ArgumentError)
end
end
end
it "raises an ArgumentError when given an incorrect number of arguments" do
- lambda { @enum.slice_after("one", "two") }.should raise_error(ArgumentError)
- lambda { @enum.slice_after }.should raise_error(ArgumentError)
+ -> { @enum.slice_after("one", "two") }.should raise_error(ArgumentError)
+ -> { @enum.slice_after }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/enumerable/slice_before_spec.rb b/spec/ruby/core/enumerable/slice_before_spec.rb
index 1594372d32..f9b33f7b28 100644
--- a/spec/ruby/core/enumerable/slice_before_spec.rb
+++ b/spec/ruby/core/enumerable/slice_before_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#slice_before" do
before :each do
@@ -40,39 +40,16 @@ describe "Enumerable#slice_before" do
end
end
- ruby_version_is ""..."2.3" do
- describe "and an argument" do
- it "calls the block with a copy of that argument" do
- arg = [:foo]
- first = nil
- e = @enum.slice_before(arg) do |i, init|
- init.should == arg
- init.should_not equal(arg)
- first = init
- i == 6 || i == 2
- end
- e.should be_an_instance_of(Enumerator)
- e.to_a.should == [[7], [6, 5, 4, 3], [2, 1]]
- e = @enum.slice_before(arg) do |i, init|
- init.should_not equal(first)
- end
- e.to_a
- end
- end
- end
-
- ruby_version_is "2.3" do
- it "does not accept arguments" do
- lambda {
- @enum.slice_before(1) {}
- }.should raise_error(ArgumentError)
- end
+ it "does not accept arguments" do
+ -> {
+ @enum.slice_before(1) {}
+ }.should raise_error(ArgumentError)
end
end
it "raises an ArgumentError when given an incorrect number of arguments" do
- lambda { @enum.slice_before("one", "two") }.should raise_error(ArgumentError)
- lambda { @enum.slice_before }.should raise_error(ArgumentError)
+ -> { @enum.slice_before("one", "two") }.should raise_error(ArgumentError)
+ -> { @enum.slice_before }.should raise_error(ArgumentError)
end
describe "when an iterator method yields more than one value" do
diff --git a/spec/ruby/core/enumerable/slice_when_spec.rb b/spec/ruby/core/enumerable/slice_when_spec.rb
index 593e623b1b..6b8ea0923e 100644
--- a/spec/ruby/core/enumerable/slice_when_spec.rb
+++ b/spec/ruby/core/enumerable/slice_when_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#slice_when" do
before :each do
@@ -39,7 +39,7 @@ describe "Enumerable#slice_when" do
context "when not given a block" do
it "raises an ArgumentError" do
- lambda { @enum.slice_when }.should raise_error(ArgumentError)
+ -> { @enum.slice_when }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/enumerable/sort_by_spec.rb b/spec/ruby/core/enumerable/sort_by_spec.rb
index f7df8659a8..8fdd923fb4 100644
--- a/spec/ruby/core/enumerable/sort_by_spec.rb
+++ b/spec/ruby/core/enumerable/sort_by_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#sort_by" do
it "returns an array of elements ordered by the result of block" do
@@ -32,5 +32,12 @@ describe "Enumerable#sort_by" do
b.sort_by{ |x| -x }.should == [3, 2, 1]
end
+ it "calls #each to iterate over the elements to be sorted" do
+ b = EnumerableSpecs::Numerous.new( 1, 2, 3 )
+ b.should_receive(:each).once.and_yield(1).and_yield(2).and_yield(3)
+ b.should_not_receive :map
+ b.sort_by { |x| -x }.should == [3, 2, 1]
+ end
+
it_behaves_like :enumerable_enumeratorized_with_origin_size, :sort_by
end
diff --git a/spec/ruby/core/enumerable/sort_spec.rb b/spec/ruby/core/enumerable/sort_spec.rb
index a39fa7ed34..6fc64f325e 100644
--- a/spec/ruby/core/enumerable/sort_spec.rb
+++ b/spec/ruby/core/enumerable/sort_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#sort" do
it "sorts by the natural order as defined by <=>" do
@@ -14,7 +14,7 @@ describe "Enumerable#sort" do
end
it "raises a NoMethodError if elements do not define <=>" do
- lambda do
+ -> do
EnumerableSpecs::Numerous.new(BasicObject.new, BasicObject.new, BasicObject.new).sort
end.should raise_error(NoMethodError)
end
@@ -31,16 +31,16 @@ describe "Enumerable#sort" do
it "compare values returned by block with 0" do
EnumerableSpecs::Numerous.new.sort { |n, m| -(n+m) * (n <=> m) }.should == [6, 5, 4, 3, 2, 1]
EnumerableSpecs::Numerous.new.sort { |n, m|
- EnumerableSpecs::ComparableWithFixnum.new(-(n+m) * (n <=> m))
+ EnumerableSpecs::ComparableWithInteger.new(-(n+m) * (n <=> m))
}.should == [6, 5, 4, 3, 2, 1]
- lambda {
+ -> {
EnumerableSpecs::Numerous.new.sort { |n, m| (n <=> m).to_s }
}.should raise_error(ArgumentError)
end
it "raises an error if objects can't be compared" do
a=EnumerableSpecs::Numerous.new(EnumerableSpecs::Uncomparable.new, EnumerableSpecs::Uncomparable.new)
- lambda {a.sort}.should raise_error(ArgumentError)
+ -> {a.sort}.should raise_error(ArgumentError)
end
it "gathers whole arrays as elements when each yields multiple" do
diff --git a/spec/ruby/core/enumerable/sum_spec.rb b/spec/ruby/core/enumerable/sum_spec.rb
index 4881039a8d..c9d7017b45 100644
--- a/spec/ruby/core/enumerable/sum_spec.rb
+++ b/spec/ruby/core/enumerable/sum_spec.rb
@@ -1,30 +1,28 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
-ruby_version_is '2.4' do
- describe 'Enumerable#sum' do
- before :each do
- @enum = Object.new.to_enum
- class << @enum
- def each
- yield 0
- yield(-1)
- yield 2
- yield 2/3r
- end
+describe 'Enumerable#sum' do
+ before :each do
+ @enum = Object.new.to_enum
+ class << @enum
+ def each
+ yield 0
+ yield(-1)
+ yield 2
+ yield 2/3r
end
end
+ end
- it 'returns amount of the elements with taking an argument as the initial value' do
- @enum.sum(10).should == 35/3r
- end
+ it 'returns amount of the elements with taking an argument as the initial value' do
+ @enum.sum(10).should == 35/3r
+ end
- it 'gives 0 as a default argument' do
- @enum.sum.should == 5/3r
- end
+ it 'gives 0 as a default argument' do
+ @enum.sum.should == 5/3r
+ end
- it 'takes a block to transform the elements' do
- @enum.sum { |element| element * 2 }.should == 10/3r
- end
+ it 'takes a block to transform the elements' do
+ @enum.sum { |element| element * 2 }.should == 10/3r
end
end
diff --git a/spec/ruby/core/enumerable/take_spec.rb b/spec/ruby/core/enumerable/take_spec.rb
index 71bf77050c..41a7438330 100644
--- a/spec/ruby/core/enumerable/take_spec.rb
+++ b/spec/ruby/core/enumerable/take_spec.rb
@@ -1,10 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/take', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/take'
describe "Enumerable#take" do
it "requires an argument" do
- lambda{ EnumerableSpecs::Numerous.new.take}.should raise_error(ArgumentError)
+ ->{ EnumerableSpecs::Numerous.new.take}.should raise_error(ArgumentError)
end
describe "when passed an argument" do
diff --git a/spec/ruby/core/enumerable/take_while_spec.rb b/spec/ruby/core/enumerable/take_while_spec.rb
index 990d16209a..26db39ac4b 100644
--- a/spec/ruby/core/enumerable/take_while_spec.rb
+++ b/spec/ruby/core/enumerable/take_while_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/enumerable_enumeratorized'
describe "Enumerable#take_while" do
before :each do
diff --git a/spec/ruby/core/enumerable/tally_spec.rb b/spec/ruby/core/enumerable/tally_spec.rb
new file mode 100644
index 0000000000..363b3def21
--- /dev/null
+++ b/spec/ruby/core/enumerable/tally_spec.rb
@@ -0,0 +1,35 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "2.7" do
+ describe "Enumerable#tally" do
+ before :each do
+ ScratchPad.record []
+ end
+
+ it "returns a hash with counts according to the value" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ enum.tally.should == { 'foo' => 2, 'bar' => 1, 'baz' => 1}
+ end
+
+ it "returns a hash without default" do
+ hash = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz').tally
+ hash.default_proc.should be_nil
+ hash.default.should be_nil
+ end
+
+ it "returns an empty hash for empty enumerables" do
+ EnumerableSpecs::Empty.new.tally.should == {}
+ end
+
+ it "counts values as gathered array when yielded with multiple arguments" do
+ EnumerableSpecs::YieldsMixed2.new.tally.should == EnumerableSpecs::YieldsMixed2.gathered_yields.group_by(&:itself).transform_values(&:size)
+ end
+
+ it "does not call given block" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ enum.tally { |v| ScratchPad << v }
+ ScratchPad.recorded.should == []
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerable/to_a_spec.rb b/spec/ruby/core/enumerable/to_a_spec.rb
index b14a3c7a1a..0f3060dc48 100644
--- a/spec/ruby/core/enumerable/to_a_spec.rb
+++ b/spec/ruby/core/enumerable/to_a_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/entries', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/entries'
describe "Enumerable#to_a" do
- it_behaves_like(:enumerable_entries , :to_a)
+ it_behaves_like :enumerable_entries , :to_a
end
diff --git a/spec/ruby/core/enumerable/to_h_spec.rb b/spec/ruby/core/enumerable/to_h_spec.rb
index b5b301b882..63bfdf19af 100644
--- a/spec/ruby/core/enumerable/to_h_spec.rb
+++ b/spec/ruby/core/enumerable/to_h_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#to_h" do
it "converts empty enumerable to empty hash" do
@@ -36,11 +36,55 @@ describe "Enumerable#to_h" do
it "raises TypeError if an element is not an array" do
enum = EnumerableSpecs::EachDefiner.new(:x)
- lambda { enum.to_h }.should raise_error(TypeError)
+ -> { enum.to_h }.should raise_error(TypeError)
end
it "raises ArgumentError if an element is not a [key, value] pair" do
enum = EnumerableSpecs::EachDefiner.new([:x])
- lambda { enum.to_h }.should raise_error(ArgumentError)
+ -> { enum.to_h }.should raise_error(ArgumentError)
+ end
+
+ ruby_version_is "2.6" do
+ context "with block" do
+ before do
+ @enum = EnumerableSpecs::EachDefiner.new(:a, :b)
+ end
+
+ it "converts [key, value] pairs returned by the block to a hash" do
+ @enum.to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' }
+ end
+
+ it "raises ArgumentError if block returns longer or shorter array" do
+ -> do
+ @enum.to_h { |k| [k, k.to_s, 1] }
+ end.should raise_error(ArgumentError, /element has wrong array length/)
+
+ -> do
+ @enum.to_h { |k| [k] }
+ end.should raise_error(ArgumentError, /element has wrong array length/)
+ end
+
+ it "raises TypeError if block returns something other than Array" do
+ -> do
+ @enum.to_h { |k| "not-array" }
+ end.should raise_error(TypeError, /wrong element type String/)
+ end
+
+ it "coerces returned pair to Array with #to_ary" do
+ x = mock('x')
+ x.stub!(:to_ary).and_return([:b, 'b'])
+
+ @enum.to_h { |k| x }.should == { :b => 'b' }
+ end
+
+ it "does not coerce returned pair to Array with #to_a" do
+ x = mock('x')
+ x.stub!(:to_a).and_return([:b, 'b'])
+
+ -> do
+ @enum.to_h { |k| x }
+ end.should raise_error(TypeError, /wrong element type MockObject/)
+ end
+ end
end
end
diff --git a/spec/ruby/core/enumerable/uniq_spec.rb b/spec/ruby/core/enumerable/uniq_spec.rb
index 0ede0170ce..e58dd36366 100644
--- a/spec/ruby/core/enumerable/uniq_spec.rb
+++ b/spec/ruby/core/enumerable/uniq_spec.rb
@@ -1,29 +1,122 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
-ruby_version_is '2.4' do
- describe 'Enumerable#uniq' do
- it 'returns an array that contains only unique elements' do
- [0, 1, 2, 3].to_enum.uniq { |n| n.even? }.should == [0, 1]
+describe 'Enumerable#uniq' do
+ it 'returns an array that contains only unique elements' do
+ [0, 1, 2, 3].to_enum.uniq { |n| n.even? }.should == [0, 1]
+ end
+
+ it "uses eql? semantics" do
+ [1.0, 1].to_enum.uniq.should == [1.0, 1]
+ end
+
+ it "compares elements first with hash" do
+ x = mock('0')
+ x.should_receive(:hash).at_least(1).and_return(0)
+ y = mock('0')
+ y.should_receive(:hash).at_least(1).and_return(0)
+
+ [x, y].to_enum.uniq.should == [x, y]
+ end
+
+ it "does not compare elements with different hash codes via eql?" do
+ x = mock('0')
+ x.should_not_receive(:eql?)
+ y = mock('1')
+ y.should_not_receive(:eql?)
+
+ x.should_receive(:hash).at_least(1).and_return(0)
+ y.should_receive(:hash).at_least(1).and_return(1)
+
+ [x, y].to_enum.uniq.should == [x, y]
+ end
+
+ ruby_version_is '2.7' do
+ it "compares elements with matching hash codes with #eql?" do
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
+
+ def obj.eql?(o)
+ false
+ end
+
+ obj
+ end
+
+ a.uniq.should == a
+
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
+
+ def obj.eql?(o)
+ true
+ end
+
+ obj
+ end
+
+ a.to_enum.uniq.size.should == 1
end
+ end
+
+ ruby_version_is ''...'2.7' do
+ it "compares elements with matching hash codes with #eql?" do
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
+
+ def obj.eql?(o)
+ # It's undefined whether the impl does a[0].eql?(a[1]) or
+ # a[1].eql?(a[0]) so we taint both.
+ taint
+ o.taint
+ false
+ end
+
+ obj
+ end
+
+ a.uniq.should == a
+ a[0].should.tainted?
+ a[1].should.tainted?
+
+ a = Array.new(2) do
+ obj = mock('0')
+ obj.should_receive(:hash).at_least(1).and_return(0)
- context 'when yielded with multiple arguments' do
- before :each do
- @enum = Object.new.to_enum
- class << @enum
- def each
- yield 0, 'foo'
- yield 1, 'FOO'
- yield 2, 'bar'
- end
+ def obj.eql?(o)
+ # It's undefined whether the impl does a[0].eql?(a[1]) or
+ # a[1].eql?(a[0]) so we taint both.
+ taint
+ o.taint
+ true
end
+
+ obj
end
- ruby_bug '#13669', ''...'2.5' do
- it 'returns all yield arguments as an array' do
- @enum.uniq { |_, label| label.downcase }.should == [[0, 'foo'], [2, 'bar']]
+ a.to_enum.uniq.size.should == 1
+ a[0].should.tainted?
+ a[1].should.tainted?
+ end
+ end
+
+ context 'when yielded with multiple arguments' do
+ before :each do
+ @enum = Object.new.to_enum
+ class << @enum
+ def each
+ yield 0, 'foo'
+ yield 1, 'FOO'
+ yield 2, 'bar'
end
end
end
+
+ it 'returns all yield arguments as an array' do
+ @enum.uniq { |_, label| label.downcase }.should == [[0, 'foo'], [2, 'bar']]
+ end
end
end
diff --git a/spec/ruby/core/enumerable/zip_spec.rb b/spec/ruby/core/enumerable/zip_spec.rb
index 2d090f335c..9ec15aa030 100644
--- a/spec/ruby/core/enumerable/zip_spec.rb
+++ b/spec/ruby/core/enumerable/zip_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerable#zip" do
@@ -21,16 +21,16 @@ describe "Enumerable#zip" do
end
it "converts arguments to arrays using #to_ary" do
- convertable = EnumerableSpecs::ArrayConvertable.new(4,5,6)
- EnumerableSpecs::Numerous.new(1,2,3).zip(convertable).should == [[1,4],[2,5],[3,6]]
- convertable.called.should == :to_ary
+ convertible = EnumerableSpecs::ArrayConvertible.new(4,5,6)
+ EnumerableSpecs::Numerous.new(1,2,3).zip(convertible).should == [[1,4],[2,5],[3,6]]
+ convertible.called.should == :to_ary
end
it "converts arguments to enums using #to_enum" do
- convertable = EnumerableSpecs::EnumConvertable.new(4..6)
- EnumerableSpecs::Numerous.new(1,2,3).zip(convertable).should == [[1,4],[2,5],[3,6]]
- convertable.called.should == :to_enum
- convertable.sym.should == :each
+ convertible = EnumerableSpecs::EnumConvertible.new(4..6)
+ EnumerableSpecs::Numerous.new(1,2,3).zip(convertible).should == [[1,4],[2,5],[3,6]]
+ convertible.called.should == :to_enum
+ convertible.sym.should == :each
end
it "gathers whole arrays as elements when each yields multiple" do
@@ -39,4 +39,3 @@ describe "Enumerable#zip" do
end
end
-
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb
new file mode 100644
index 0000000000..c8d91ebaec
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#begin" do
+ it "returns the begin of the sequence" do
+ 1.step(10).begin.should == 1
+ (1..10).step.begin.should == 1
+ (1...10).step.begin.should == 1
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb
new file mode 100644
index 0000000000..d7edf3a21f
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#each" do
+ before :each do
+ ScratchPad.record []
+ @seq = 1.step(10, 4)
+ end
+
+ it "calls given block on each item of the sequence" do
+ @seq.each { |item| ScratchPad << item }
+ ScratchPad.recorded.should == [1, 5, 9]
+ end
+
+ it "returns self" do
+ @seq.each { |item| }.should equal(@seq)
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb
new file mode 100644
index 0000000000..5a436e8167
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#end" do
+ it "returns the end of the sequence" do
+ 1.step(10).end.should == 10
+ (1..10).step.end.should == 10
+ (1...10).step(17).end.should == 10
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb
new file mode 100644
index 0000000000..7895f98047
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#==" do
+ it "returns true if begin, end, step and exclude_end? are equal" do
+ 1.step(10).should == 1.step(10)
+ 1.step(10, 5).should == 1.step(10, 5)
+
+ (1..10).step.should == (1..10).step
+ (1...10).step(8).should == (1...10).step(8)
+
+ # both have exclude_end? == false
+ (1..10).step(100).should == 1.step(10, 100)
+
+ ((1..10).step == (1..11).step).should == false
+ ((1..10).step == (1...10).step).should == false
+ ((1..10).step == (1..10).step(2)).should == false
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb
new file mode 100644
index 0000000000..5be189e993
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#exclude_end?" do
+ context "when created using Numeric#step" do
+ it "always returns false" do
+ 1.step(10).should_not.exclude_end?
+ 10.step(1).should_not.exclude_end?
+ end
+ end
+
+ context "when created using Range#step" do
+ it "mirrors range.exclude_end?" do
+ (1...10).step.should.exclude_end?
+ (1..10).step.should_not.exclude_end?
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb
new file mode 100644
index 0000000000..43c520d1f0
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#first" do
+ it "returns the first element of the sequence" do
+ 1.step(10).first.should == 1
+ (1..10).step.first.should == 1
+ (1...10).step.first.should == 1
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb
new file mode 100644
index 0000000000..236f845f41
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#hash" do
+ it "is based on begin, end, step and exclude_end?" do
+ 1.step(10).hash.should be_an_instance_of(Integer)
+
+ 1.step(10).hash.should == 1.step(10).hash
+ 1.step(10, 5).hash.should == 1.step(10, 5).hash
+
+ (1..10).step.hash.should == (1..10).step.hash
+ (1...10).step(8).hash.should == (1...10).step(8).hash
+
+ # both have exclude_end? == false
+ (1..10).step(100).hash.should == 1.step(10, 100).hash
+
+ ((1..10).step.hash == (1..11).step.hash).should == false
+ ((1..10).step.hash == (1...10).step.hash).should == false
+ ((1..10).step.hash == (1..10).step(2).hash).should == false
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb
new file mode 100644
index 0000000000..21e64a6b58
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#inspect" do
+ context 'when Numeric#step is used' do
+ it "returns '(begin.step(end{, step}))'" do
+ 1.step(10).inspect.should == "(1.step(10))"
+ 1.step(10, 3).inspect.should == "(1.step(10, 3))"
+ end
+ end
+
+ context 'when Range#step is used' do
+ it "returns '((range).step{(step)})'" do
+ (1..10).step.inspect.should == "((1..10).step)"
+ (1..10).step(3).inspect.should == "((1..10).step(3))"
+
+ (1...10).step.inspect.should == "((1...10).step)"
+ (1...10).step(3).inspect.should == "((1...10).step(3))"
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb
new file mode 100644
index 0000000000..ebb20090fc
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#last" do
+ it "returns the last element of the sequence" do
+ 1.step(10).last.should == 10
+ (1..10).step.last.should == 10
+ (1...10).step(4).last.should == 9
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb
new file mode 100644
index 0000000000..7227581fb9
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence.new" do
+ it "is not defined" do
+ -> {
+ Enumerator::ArithmeticSequence.new
+ }.should raise_error(NoMethodError)
+ end
+ end
+
+ describe "Enumerator::ArithmeticSequence.allocate" do
+ it "is not defined" do
+ -> {
+ Enumerator::ArithmeticSequence.allocate
+ }.should raise_error(TypeError, 'allocator undefined for Enumerator::ArithmeticSequence')
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb
new file mode 100644
index 0000000000..00403b0238
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#size" do
+ context "for finite sequence" do
+ it "returns the number of elements in this arithmetic sequence" do
+ 1.step(10).size.should == 10
+ (1...10).step.size.should == 9
+ end
+ end
+
+ context "for infinite sequence" do
+ it "returns Infinity" do
+ 1.step(Float::INFINITY).size.should == Float::INFINITY
+ (1..Float::INFINITY).step.size.should == Float::INFINITY
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb
new file mode 100644
index 0000000000..8b00fd4309
--- /dev/null
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::ArithmeticSequence#step" do
+ it "returns the original value given to step method" do
+ (1..10).step.step.should == 1
+ (1..10).step(3).step.should == 3
+
+ 1.step(10).step.should == 1
+ 1.step(10, 3).step.should == 3
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/chain/each_spec.rb b/spec/ruby/core/enumerator/chain/each_spec.rb
new file mode 100644
index 0000000000..ab4d355f22
--- /dev/null
+++ b/spec/ruby/core/enumerator/chain/each_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+require_relative '../../enumerable/fixtures/classes'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::Chain#each" do
+ it "calls each on its constituents as needed" do
+ a = EnumerableSpecs::EachCounter.new(:a, :b)
+ b = EnumerableSpecs::EachCounter.new(:c, :d)
+
+ ScratchPad.record []
+ Enumerator::Chain.new(a, b).each do |elem|
+ ScratchPad << elem << b.times_yielded
+ end
+ ScratchPad.recorded.should == [:a, 0, :b, 0, :c, 1, :d, 2]
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/chain/initialize_spec.rb b/spec/ruby/core/enumerator/chain/initialize_spec.rb
new file mode 100644
index 0000000000..e5aa32fd02
--- /dev/null
+++ b/spec/ruby/core/enumerator/chain/initialize_spec.rb
@@ -0,0 +1,33 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::Chain#initialize" do
+ before :each do
+ @uninitialized = Enumerator::Chain.allocate
+ end
+
+ it "is a private method" do
+ Enumerator::Chain.should have_private_instance_method(:initialize, false)
+ end
+
+ it "returns self" do
+ @uninitialized.send(:initialize).should equal(@uninitialized)
+ end
+
+ it "accepts many arguments" do
+ @uninitialized.send(:initialize, 0..1, 2..3, 4..5).should equal(@uninitialized)
+ end
+
+ it "accepts arguments that are not Enumerable nor responding to :each" do
+ @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+ end
+
+ describe "on frozen instance" do
+ it "raises a RuntimeError" do
+ -> {
+ @uninitialized.freeze.send(:initialize)
+ }.should raise_error(RuntimeError)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/chain/inspect_spec.rb b/spec/ruby/core/enumerator/chain/inspect_spec.rb
new file mode 100644
index 0000000000..a644d88c6f
--- /dev/null
+++ b/spec/ruby/core/enumerator/chain/inspect_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::Chain#inspect" do
+ it "shows a representation of the Enumerator" do
+ Enumerator::Chain.new.inspect.should == "#<Enumerator::Chain: []>"
+ Enumerator::Chain.new(1..2, 3..4).inspect.should == "#<Enumerator::Chain: [1..2, 3..4]>"
+ end
+
+ it "calls inspect on its chain elements" do
+ obj = mock('inspect')
+ obj.should_receive(:inspect).and_return('some desc')
+ Enumerator::Chain.new(obj).inspect.should == "#<Enumerator::Chain: [some desc]>"
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/chain/rewind_spec.rb b/spec/ruby/core/enumerator/chain/rewind_spec.rb
new file mode 100644
index 0000000000..951b364f07
--- /dev/null
+++ b/spec/ruby/core/enumerator/chain/rewind_spec.rb
@@ -0,0 +1,53 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::Chain#rewind" do
+ before(:each) do
+ @obj = mock('obj')
+ @obj.should_receive(:each).any_number_of_times.and_yield
+ @second = mock('obj')
+ @second.should_receive(:each).any_number_of_times.and_yield
+ @enum = Enumerator::Chain.new(@obj, @second)
+ end
+
+ it "returns self" do
+ @enum.rewind.should equal @enum
+ end
+
+ it "does nothing if receiver has not been iterated" do
+ @obj.should_not_receive(:rewind)
+ @obj.respond_to?(:rewind).should == true # sanity check
+ @enum.rewind
+ end
+
+ it "does nothing on objects that don't respond_to rewind" do
+ @obj.respond_to?(:rewind).should == false # sanity check
+ @enum.each {}
+ @enum.rewind
+ end
+
+ it "calls_rewind its objects" do
+ @obj.should_receive(:rewind)
+ @enum.each {}
+ @enum.rewind
+ end
+
+ it "calls_rewind in reverse order" do
+ @obj.should_not_receive(:rewind)
+ @second.should_receive(:rewind).and_raise(RuntimeError)
+ @enum.each {}
+ -> { @enum.rewind }.should raise_error(RuntimeError)
+ end
+
+ it "calls rewind only for objects that have actually been iterated on" do
+ @obj = mock('obj')
+ @obj.should_receive(:each).any_number_of_times.and_raise(RuntimeError)
+ @enum = Enumerator::Chain.new(@obj, @second)
+
+ @obj.should_receive(:rewind)
+ @second.should_not_receive(:rewind)
+ -> { @enum.each {} }.should raise_error(RuntimeError)
+ @enum.rewind
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/chain/size_spec.rb b/spec/ruby/core/enumerator/chain/size_spec.rb
new file mode 100644
index 0000000000..42c31ac10b
--- /dev/null
+++ b/spec/ruby/core/enumerator/chain/size_spec.rb
@@ -0,0 +1,24 @@
+require_relative '../../../spec_helper'
+require_relative '../../enumerable/fixtures/classes'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::Chain#size" do
+ it "returns the sum of the sizes of the elements" do
+ a = mock('size')
+ a.should_receive(:size).and_return(40)
+ Enumerator::Chain.new(a, [:a, :b]).size.should == 42
+ end
+
+ it "returns nil or Infinity for the first element of such a size" do
+ [nil, Float::INFINITY].each do |special|
+ a = mock('size')
+ a.should_receive(:size).and_return(40)
+ b = mock('special')
+ b.should_receive(:size).and_return(special)
+ c = mock('not called')
+ c.should_not_receive(:size)
+ Enumerator::Chain.new(a, b, c).size.should == special
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/each_spec.rb b/spec/ruby/core/enumerator/each_spec.rb
index a6ecf2af2d..99ac3120af 100644
--- a/spec/ruby/core/enumerator/each_spec.rb
+++ b/spec/ruby/core/enumerator/each_spec.rb
@@ -1,5 +1,89 @@
-require File.expand_path('../../../shared/enumerator/each', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#each" do
- it_behaves_like(:enum_each, :each)
+ before :each do
+ object_each_with_arguments = Object.new
+ def object_each_with_arguments.each_with_arguments(arg, *args)
+ yield arg, *args
+ :method_returned
+ end
+
+ @enum_with_arguments = object_each_with_arguments.to_enum(:each_with_arguments, :arg0, :arg1, :arg2)
+
+ @enum_with_yielder = Enumerator.new {|y| y.yield :ok}
+ end
+
+ it "yields each element of self to the given block" do
+ acc = []
+ [1,2,3].to_enum.each {|e| acc << e }
+ acc.should == [1,2,3]
+ end
+
+ it "calls #each on the object given in the constructor by default" do
+ each = mock('each')
+ each.should_receive(:each)
+ each.to_enum.each {|e| e }
+ end
+
+ it "calls #each on the underlying object until it's exhausted" do
+ each = mock('each')
+ each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
+ acc = []
+ each.to_enum.each {|e| acc << e }
+ acc.should == [1,2,3]
+ end
+
+ it "calls the method given in the constructor instead of #each" do
+ each = mock('peach')
+ each.should_receive(:peach)
+ each.to_enum(:peach).each {|e| e }
+ end
+
+ it "calls the method given in the constructor until it's exhausted" do
+ each = mock('peach')
+ each.should_receive(:peach).and_yield(1).and_yield(2).and_yield(3)
+ acc = []
+ each.to_enum(:peach).each {|e| acc << e }
+ acc.should == [1,2,3]
+ end
+
+ it "raises a NoMethodError if the object doesn't respond to #each" do
+ enum = Object.new.to_enum
+ -> do
+ enum.each { |e| e }
+ end.should raise_error(NoMethodError)
+ end
+
+ it "returns self if not given arguments and not given a block" do
+ @enum_with_arguments.each.should equal(@enum_with_arguments)
+
+ @enum_with_yielder.each.should equal(@enum_with_yielder)
+ end
+
+ it "returns the same value from receiver.each if block is given" do
+ @enum_with_arguments.each {}.should equal(:method_returned)
+ end
+
+ it "passes given arguments at initialized to receiver.each" do
+ @enum_with_arguments.each.to_a.should == [[:arg0, :arg1, :arg2]]
+ end
+
+ it "requires multiple arguments" do
+ Enumerator.instance_method(:each).arity.should < 0
+ end
+
+ it "appends given arguments to receiver.each" do
+ @enum_with_arguments.each(:each0, :each1).to_a.should == [[:arg0, :arg1, :arg2, :each0, :each1]]
+ @enum_with_arguments.each(:each2, :each3).to_a.should == [[:arg0, :arg1, :arg2, :each2, :each3]]
+ end
+
+ it "returns the same value from receiver.each if block and arguments are given" do
+ @enum_with_arguments.each(:each1, :each2) {}.should equal(:method_returned)
+ end
+
+ it "returns new Enumerator if given arguments but not given a block" do
+ ret = @enum_with_arguments.each 1
+ ret.should be_an_instance_of(Enumerator)
+ ret.should_not equal(@enum_with_arguments)
+ end
end
diff --git a/spec/ruby/core/enumerator/each_with_index_spec.rb b/spec/ruby/core/enumerator/each_with_index_spec.rb
index c8cb0bd496..96e53a2804 100644
--- a/spec/ruby/core/enumerator/each_with_index_spec.rb
+++ b/spec/ruby/core/enumerator/each_with_index_spec.rb
@@ -1,20 +1,20 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/with_index', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/enumerator/with_index'
+require_relative '../enumerable/shared/enumeratorized'
describe "Enumerator#each_with_index" do
- it_behaves_like(:enum_with_index, :each_with_index)
- it_behaves_like(:enumeratorized_with_origin_size, :each_with_index, [1,2,3].select)
+ it_behaves_like :enum_with_index, :each_with_index
+ it_behaves_like :enumeratorized_with_origin_size, :each_with_index, [1,2,3].select
it "returns a new Enumerator when no block is given" do
enum1 = [1,2,3].select
enum2 = enum1.each_with_index
enum2.should be_an_instance_of(Enumerator)
- enum1.should_not === enum2
+ enum1.should_not == enum2
end
it "raises an ArgumentError if passed extra arguments" do
- lambda do
+ -> do
[1].to_enum.each_with_index(:glark)
end.should raise_error(ArgumentError)
end
@@ -28,9 +28,7 @@ describe "Enumerator#each_with_index" do
it "returns the iterator's return value" do
[1,2,3].select.with_index { |a,b| false }.should == []
end
-end
-describe "Enumerator#each_with_index" do
it "returns the correct value if chained with itself" do
[:a].each_with_index.each_with_index.to_a.should == [[[:a,0],0]]
[:a].each.with_index.with_index.to_a.should == [[[:a,0],0]]
diff --git a/spec/ruby/core/enumerator/each_with_object_spec.rb b/spec/ruby/core/enumerator/each_with_object_spec.rb
index ec461e2425..68524dc74a 100644
--- a/spec/ruby/core/enumerator/each_with_object_spec.rb
+++ b/spec/ruby/core/enumerator/each_with_object_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/with_object', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/enumerator/with_object'
describe "Enumerator#each_with_object" do
it_behaves_like :enum_with_object, :each_with_object
diff --git a/spec/ruby/core/enumerator/enum_for_spec.rb b/spec/ruby/core/enumerator/enum_for_spec.rb
index 43c11e5a39..fd33f463bf 100644
--- a/spec/ruby/core/enumerator/enum_for_spec.rb
+++ b/spec/ruby/core/enumerator/enum_for_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/enum_for', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/enumerator/enum_for'
describe "Enumerator#enum_for" do
it_behaves_like :enum_for, :enum_for
diff --git a/spec/ruby/core/enumerator/enumerator_spec.rb b/spec/ruby/core/enumerator/enumerator_spec.rb
index 2d5213edd9..7a263336cb 100644
--- a/spec/ruby/core/enumerator/enumerator_spec.rb
+++ b/spec/ruby/core/enumerator/enumerator_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator" do
it "includes Enumerable" do
diff --git a/spec/ruby/core/enumerator/feed_spec.rb b/spec/ruby/core/enumerator/feed_spec.rb
index 32ea77a30d..e387c6cd39 100644
--- a/spec/ruby/core/enumerator/feed_spec.rb
+++ b/spec/ruby/core/enumerator/feed_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Enumerator#feed" do
before :each do
@@ -39,14 +39,14 @@ describe "Enumerator#feed" do
it "raises a TypeError if called more than once without advancing the enumerator" do
@enum.feed :a
@enum.next
- lambda { @enum.feed :b }.should raise_error(TypeError)
+ -> { @enum.feed :b }.should raise_error(TypeError)
end
it "sets the return value of Yielder#yield" do
enum = Enumerator.new { |y| ScratchPad << y.yield }
enum.next
enum.feed :a
- lambda { enum.next }.should raise_error(StopIteration)
+ -> { enum.next }.should raise_error(StopIteration)
ScratchPad.recorded.should == [:a]
end
end
diff --git a/spec/ruby/core/enumerator/first_spec.rb b/spec/ruby/core/enumerator/first_spec.rb
index ba3b0df492..458080bb31 100644
--- a/spec/ruby/core/enumerator/first_spec.rb
+++ b/spec/ruby/core/enumerator/first_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#first" do
it "returns arrays correctly when calling #first (2376)" do
diff --git a/spec/ruby/core/enumerator/generator/each_spec.rb b/spec/ruby/core/enumerator/generator/each_spec.rb
index 06395d0aa0..a43805dd16 100644
--- a/spec/ruby/core/enumerator/generator/each_spec.rb
+++ b/spec/ruby/core/enumerator/generator/each_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Enumerator::Generator#each" do
before :each do
@@ -21,7 +21,7 @@ describe "Enumerator::Generator#each" do
end
it "raises a LocalJumpError if no block given" do
- lambda { @generator.each }.should raise_error(LocalJumpError)
+ -> { @generator.each }.should raise_error(LocalJumpError)
end
it "returns the block returned value" do
diff --git a/spec/ruby/core/enumerator/generator/initialize_spec.rb b/spec/ruby/core/enumerator/generator/initialize_spec.rb
index 85b0e04354..f75c7d6f26 100644
--- a/spec/ruby/core/enumerator/generator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/generator/initialize_spec.rb
@@ -1,6 +1,6 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Enumerator::Generator#initialize" do
before :each do
@@ -18,7 +18,7 @@ describe "Enumerator::Generator#initialize" do
describe "on frozen instance" do
it "raises a RuntimeError" do
- lambda {
+ -> {
@uninitialized.freeze.send(:initialize) {}
}.should raise_error(RuntimeError)
end
diff --git a/spec/ruby/core/enumerator/initialize_spec.rb b/spec/ruby/core/enumerator/initialize_spec.rb
index 58f8a5e865..113bbf9957 100644
--- a/spec/ruby/core/enumerator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/initialize_spec.rb
@@ -1,6 +1,6 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#initialize" do
before :each do
@@ -11,8 +11,10 @@ describe "Enumerator#initialize" do
Enumerator.should have_private_instance_method(:initialize, false)
end
- it "returns self when given an object" do
- @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+ ruby_version_is ''...'3.0' do
+ it "returns self when given an object" do
+ @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+ end
end
it "returns self when given a block" do
@@ -43,17 +45,17 @@ describe "Enumerator#initialize" do
@uninitialized.send(:initialize, Float::INFINITY) {}.size.should equal(Float::INFINITY)
end
- it "sets size to the given size if the given size is a Fixnum" do
+ it "sets size to the given size if the given size is an Integer" do
@uninitialized.send(:initialize, 100) {}.size.should == 100
end
it "sets size to the given size if the given size is a Proc" do
- @uninitialized.send(:initialize, lambda { 200 }) {}.size.should == 200
+ @uninitialized.send(:initialize, -> { 200 }) {}.size.should == 200
end
describe "on frozen instance" do
it "raises a RuntimeError" do
- lambda {
+ -> {
@uninitialized.freeze.send(:initialize) {}
}.should raise_error(RuntimeError)
end
diff --git a/spec/ruby/core/enumerator/inject_spec.rb b/spec/ruby/core/enumerator/inject_spec.rb
deleted file mode 100644
index 64085a03c5..0000000000
--- a/spec/ruby/core/enumerator/inject_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require File.expand_path('../../../shared/enumerator/each', __FILE__)
-
-describe "Enumerator#inject" do
- it_behaves_like(:enum_each, :each)
-
- it "works when chained against each_with_index" do
- passed_values = []
- [:a].each_with_index.inject(0) do |accumulator,value|
- passed_values << value
- accumulator + 1
- end.should == 1
- passed_values.should == [[:a,0]]
- end
-
-end
diff --git a/spec/ruby/core/enumerator/inspect_spec.rb b/spec/ruby/core/enumerator/inspect_spec.rb
index b708256247..3bcf07e754 100644
--- a/spec/ruby/core/enumerator/inspect_spec.rb
+++ b/spec/ruby/core/enumerator/inspect_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#inspect" do
describe "shows a representation of the Enumerator" do
diff --git a/spec/ruby/core/enumerator/lazy/chunk_spec.rb b/spec/ruby/core/enumerator/lazy/chunk_spec.rb
new file mode 100644
index 0000000000..87d2b0c206
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/chunk_spec.rb
@@ -0,0 +1,67 @@
+# -*- encoding: us-ascii -*-
+
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "Enumerator::Lazy#chunk" do
+
+ before :each do
+ @yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy
+ @eventsmixed = EnumeratorLazySpecs::EventsMixed.new.to_enum.lazy
+ ScratchPad.record []
+ end
+
+ after :each do
+ ScratchPad.clear
+ end
+
+ it "returns a new instance of Enumerator::Lazy" do
+ ret = @yieldsmixed.chunk {}
+ ret.should be_an_instance_of(Enumerator::Lazy)
+ ret.should_not equal(@yieldsmixed)
+ end
+
+ it "sets #size to nil" do
+ Enumerator::Lazy.new(Object.new, 100) {}.chunk { |v| v }.size.should == nil
+ end
+
+ it "returns an Enumerator if called without a block" do
+ chunk = @yieldsmixed.chunk
+ chunk.should be_an_instance_of(Enumerator::Lazy)
+
+ res = chunk.each { |v| true }.force
+ res.should == [[true, EnumeratorLazySpecs::YieldsMixed.gathered_yields]]
+ end
+
+ describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
+ it "stops after specified times" do
+ first_two = (0..Float::INFINITY).lazy.chunk { |n| n.even? }.first(2)
+ first_two.should == [[true, [0]], [false, [1]]]
+ end
+ end
+
+ it "calls the block with gathered values when yield with multiple arguments" do
+ yields = []
+ @yieldsmixed.chunk { |v| yields << v; true }.force
+ yields.should == EnumeratorLazySpecs::YieldsMixed.gathered_yields
+ end
+
+ describe "on a nested Lazy" do
+ it "sets #size to nil" do
+ Enumerator::Lazy.new(Object.new, 100) {}.take(20).chunk { |v| v }.size.should == nil
+ end
+
+ describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
+ it "stops after specified times" do
+ remains_lazy = (0..Float::INFINITY).lazy.chunk { |n| n }
+ remains_lazy.chunk { |n| n }.first(2).size.should == 2
+ end
+ end
+ end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.chunk { |n| n.even? }.first(100).should ==
+ s.first(100).chunk { |n| n.even? }.to_a
+ end
+end
diff --git a/spec/ruby/core/enumerator/lazy/chunk_while_spec.rb b/spec/ruby/core/enumerator/lazy/chunk_while_spec.rb
new file mode 100644
index 0000000000..d555089872
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/chunk_while_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../../spec_helper'
+
+describe "Enumerator::Lazy#chunk_while" do
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.chunk_while { |a, b| false }.first(100).should ==
+ s.first(100).chunk_while { |a, b| false }.to_a
+ end
+end
diff --git a/spec/ruby/core/enumerator/lazy/collect_concat_spec.rb b/spec/ruby/core/enumerator/lazy/collect_concat_spec.rb
index 8c19dcbbf9..8765bb2190 100644
--- a/spec/ruby/core/enumerator/lazy/collect_concat_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/collect_concat_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/collect_concat', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/collect_concat'
describe "Enumerator::Lazy#collect_concat" do
it_behaves_like :enumerator_lazy_collect_concat, :collect_concat
diff --git a/spec/ruby/core/enumerator/lazy/collect_spec.rb b/spec/ruby/core/enumerator/lazy/collect_spec.rb
index 764b8af36d..14b79ce16d 100644
--- a/spec/ruby/core/enumerator/lazy/collect_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/collect_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/collect', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/collect'
describe "Enumerator::Lazy#collect" do
it_behaves_like :enumerator_lazy_collect, :collect
diff --git a/spec/ruby/core/enumerator/lazy/drop_spec.rb b/spec/ruby/core/enumerator/lazy/drop_spec.rb
index eb65bb246b..822b8034fb 100644
--- a/spec/ruby/core/enumerator/lazy/drop_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/drop_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#drop" do
before :each do
@@ -49,4 +49,10 @@ describe "Enumerator::Lazy#drop" do
end
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.drop(100).first(100).should ==
+ s.first(200).drop(100)
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/drop_while_spec.rb b/spec/ruby/core/enumerator/lazy/drop_while_spec.rb
index a08644a20c..4f6e366f88 100644
--- a/spec/ruby/core/enumerator/lazy/drop_while_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/drop_while_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#drop_while" do
before :each do
@@ -40,7 +40,7 @@ describe "Enumerator::Lazy#drop_while" do
end
it "raises an ArgumentError when not given a block" do
- lambda { @yieldsmixed.drop_while }.should raise_error(ArgumentError)
+ -> { @yieldsmixed.drop_while }.should raise_error(ArgumentError)
end
describe "on a nested Lazy" do
@@ -57,4 +57,10 @@ describe "Enumerator::Lazy#drop_while" do
end
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.drop_while { |n| n < 100 }.first(100).should ==
+ s.first(200).drop_while { |n| n < 100 }
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/eager_spec.rb b/spec/ruby/core/enumerator/lazy/eager_spec.rb
new file mode 100644
index 0000000000..30ba2dfe0e
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/eager_spec.rb
@@ -0,0 +1,29 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.7" do
+ describe "Enumerator::Lazy#eager" do
+ it "returns a non-lazy Enumerator converted from the lazy enumerator" do
+ enum = [1, 2, 3].lazy
+
+ enum.class.should == Enumerator::Lazy
+ enum.eager.class.should == Enumerator
+ end
+
+ it "does not enumerate an enumerator" do
+ ScratchPad.record []
+
+ sequence = [1, 2, 3]
+ enum_lazy = Enumerator::Lazy.new(sequence) do |yielder, value|
+ yielder << value
+ ScratchPad << value
+ end
+
+ ScratchPad.recorded.should == []
+ enum = enum_lazy.eager
+ ScratchPad.recorded.should == []
+
+ enum.map { |i| i }.should == [1, 2, 3]
+ ScratchPad.recorded.should == [1, 2, 3]
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/lazy/enum_for_spec.rb b/spec/ruby/core/enumerator/lazy/enum_for_spec.rb
index b2ef2c881e..7e7783f6f1 100644
--- a/spec/ruby/core/enumerator/lazy/enum_for_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/enum_for_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/to_enum', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/to_enum'
describe "Enumerator::Lazy#enum_for" do
it_behaves_like :enumerator_lazy_to_enum, :enum_for
diff --git a/spec/ruby/core/enumerator/lazy/filter_spec.rb b/spec/ruby/core/enumerator/lazy/filter_spec.rb
new file mode 100644
index 0000000000..2ababa69cc
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/filter_spec.rb
@@ -0,0 +1,8 @@
+require_relative '../../../spec_helper'
+require_relative 'shared/select'
+
+ruby_version_is "2.6" do
+ describe "Enumerator::Lazy#filter" do
+ it_behaves_like :enumerator_lazy_select, :filter
+ end
+end
diff --git a/spec/ruby/core/enumerator/lazy/find_all_spec.rb b/spec/ruby/core/enumerator/lazy/find_all_spec.rb
index ab2e69c857..8b05c53803 100644
--- a/spec/ruby/core/enumerator/lazy/find_all_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/find_all_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/select', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/select'
describe "Enumerator::Lazy#find_all" do
it_behaves_like :enumerator_lazy_select, :find_all
diff --git a/spec/ruby/core/enumerator/lazy/flat_map_spec.rb b/spec/ruby/core/enumerator/lazy/flat_map_spec.rb
index b7fba5e81c..5dcaa8bfa1 100644
--- a/spec/ruby/core/enumerator/lazy/flat_map_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/flat_map_spec.rb
@@ -1,8 +1,16 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/collect_concat', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/collect_concat'
describe "Enumerator::Lazy#flat_map" do
it_behaves_like :enumerator_lazy_collect_concat, :flat_map
+
+ it "properly unwraps nested yields" do
+ s = Enumerator.new do |y| loop do y << [1, 2] end end
+
+ expected = s.take(3).flat_map { |x| x }.to_a
+ actual = s.lazy.take(3).flat_map{ |x| x }.force
+ actual.should == expected
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/force_spec.rb b/spec/ruby/core/enumerator/lazy/force_spec.rb
index 03ff9a0fb6..a7fa029135 100644
--- a/spec/ruby/core/enumerator/lazy/force_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/force_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#force" do
before :each do
@@ -24,7 +24,13 @@ describe "Enumerator::Lazy#force" do
(0..Float::INFINITY).lazy.map(&:succ).take(2).force.should == [1, 2]
@eventsmixed.take(1).map(&:succ).force.should == [1]
- ScratchPad.recorded == [:after_yields]
+ ScratchPad.recorded.should == [:before_yield]
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.take(100).force.should ==
+ s.take(100)
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/grep_spec.rb b/spec/ruby/core/enumerator/lazy/grep_spec.rb
index 372be80d61..e67686c9a3 100644
--- a/spec/ruby/core/enumerator/lazy/grep_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/grep_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#grep" do
before :each do
@@ -33,6 +33,39 @@ describe "Enumerator::Lazy#grep" do
Enumerator::Lazy.new(Object.new, 100) {}.grep(Object).size.should == nil
end
+ it "sets $~ in the block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].lazy.grep(/b/) { |e|
+ e.should == "abc"
+ $&.should == "b"
+ }.force
+
+ # Set by the failed match of "def"
+ $~.should == nil
+ end
+
+ it "sets $~ in the next block with each" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].lazy.grep(/b/).each { |e|
+ e.should == "abc"
+ $&.should == "b"
+ }
+
+ # Set by the failed match of "def"
+ $~.should == nil
+ end
+
+ it "sets $~ in the next block with map" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].lazy.grep(/b/).map { |e|
+ e.should == "abc"
+ $&.should == "b"
+ }.force
+
+ # Set by the failed match of "def"
+ $~.should == nil
+ end
+
describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
it "stops after specified times when not given a block" do
(0..Float::INFINITY).lazy.grep(Integer).first(3).should == [0, 1, 2]
@@ -79,4 +112,10 @@ describe "Enumerator::Lazy#grep" do
end
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.grep(Numeric).first(100).should ==
+ s.first(100).grep(Numeric)
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/grep_v_spec.rb b/spec/ruby/core/enumerator/lazy/grep_v_spec.rb
index 123cbae58c..67173021bb 100644
--- a/spec/ruby/core/enumerator/lazy/grep_v_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/grep_v_spec.rb
@@ -1,86 +1,123 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-
-ruby_version_is "2.3" do
- describe "Enumerator::Lazy#grep_v" do
- before(:each) do
- @yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy
- @eventsmixed = EnumeratorLazySpecs::EventsMixed.new.to_enum.lazy
- ScratchPad.record []
- end
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "Enumerator::Lazy#grep_v" do
+ before(:each) do
+ @yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy
+ @eventsmixed = EnumeratorLazySpecs::EventsMixed.new.to_enum.lazy
+ ScratchPad.record []
+ end
- after(:each) do
- ScratchPad.clear
- end
+ after(:each) do
+ ScratchPad.clear
+ end
+
+ it "requires an argument" do
+ Enumerator::Lazy.instance_method(:grep_v).arity.should == 1
+ end
+
+ it "returns a new instance of Enumerator::Lazy" do
+ ret = @yieldsmixed.grep_v(Object) {}
+ ret.should be_an_instance_of(Enumerator::Lazy)
+ ret.should_not equal(@yieldsmixed)
+
+ ret = @yieldsmixed.grep_v(Object)
+ ret.should be_an_instance_of(Enumerator::Lazy)
+ ret.should_not equal(@yieldsmixed)
+ end
+
+ it "sets #size to nil" do
+ Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object) {}.size.should == nil
+ Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object).size.should == nil
+ end
+
+ it "sets $~ in the block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].lazy.grep_v(/e/) { |e|
+ e.should == "abc"
+ $~.should == nil
+ }.force
+
+ # Set by the match of "def"
+ $&.should == "e"
+ end
+
+ it "sets $~ in the next block with each" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].lazy.grep_v(/e/).each { |e|
+ e.should == "abc"
+ $~.should == nil
+ }
+
+ # Set by the match of "def"
+ $&.should == "e"
+ end
+
+ it "sets $~ in the next block with map" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].lazy.grep_v(/e/).map { |e|
+ e.should == "abc"
+ $~.should == nil
+ }.force
- it "requires an argument" do
- Enumerator::Lazy.instance_method(:grep_v).arity.should == 1
+ # Set by the match of "def"
+ $&.should == "e"
+ end
+
+ describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
+ it "stops after specified times when not given a block" do
+ (0..Float::INFINITY).lazy.grep_v(3..5).first(3).should == [0, 1, 2]
+
+ @eventsmixed.grep_v(Symbol).first(1)
+ ScratchPad.recorded.should == [:before_yield]
end
- it "returns a new instance of Enumerator::Lazy" do
- ret = @yieldsmixed.grep_v(Object) {}
- ret.should be_an_instance_of(Enumerator::Lazy)
- ret.should_not equal(@yieldsmixed)
+ it "stops after specified times when given a block" do
+ (0..Float::INFINITY).lazy.grep_v(4..8, &:succ).first(3).should == [1, 2, 3]
- ret = @yieldsmixed.grep_v(Object)
- ret.should be_an_instance_of(Enumerator::Lazy)
- ret.should_not equal(@yieldsmixed)
+ @eventsmixed.grep_v(Symbol) {}.first(1)
+ ScratchPad.recorded.should == [:before_yield]
end
+ end
+
+ it "calls the block with a gathered array when yield with multiple arguments" do
+ yields = []
+ @yieldsmixed.grep_v(Array) { |v| yields << v }.force
+ yields.should == EnumeratorLazySpecs::YieldsMixed.gathered_non_array_yields
+ @yieldsmixed.grep_v(Array).force.should == yields
+ end
+
+ describe "on a nested Lazy" do
it "sets #size to nil" do
- Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object) {}.size.should == nil
- Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object).size.should == nil
+ Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object).grep_v(Object) {}.size.should == nil
+ Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object).grep_v(Object).size.should == nil
end
describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
it "stops after specified times when not given a block" do
- (0..Float::INFINITY).lazy.grep_v(3..5).first(3).should == [0, 1, 2]
+ (0..Float::INFINITY).lazy.grep_v(3..5).grep_v(6..10).first(3).should == [0, 1, 2]
- @eventsmixed.grep_v(Symbol).first(1)
+ @eventsmixed.grep_v(Symbol).grep_v(String).first(1)
ScratchPad.recorded.should == [:before_yield]
end
it "stops after specified times when given a block" do
- (0..Float::INFINITY).lazy.grep_v(4..8, &:succ).first(3).should == [1, 2, 3]
+ (0..Float::INFINITY).lazy
+ .grep_v(1..2) { |n| n > 3 ? n : false }
+ .grep_v(false) { |n| n.even? ? n : false }
+ .first(3)
+ .should == [4, false, 6]
- @eventsmixed.grep_v(Symbol) {}.first(1)
+ @eventsmixed.grep_v(Symbol) {}.grep_v(String) {}.first(1)
ScratchPad.recorded.should == [:before_yield]
end
end
+ end
- it "calls the block with a gathered array when yield with multiple arguments" do
- yields = []
- @yieldsmixed.grep_v(Array) { |v| yields << v }.force
- yields.should == EnumeratorLazySpecs::YieldsMixed.gathered_non_array_yields
-
- @yieldsmixed.grep_v(Array).force.should == yields
- end
-
- describe "on a nested Lazy" do
- it "sets #size to nil" do
- Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object).grep_v(Object) {}.size.should == nil
- Enumerator::Lazy.new(Object.new, 100) {}.grep_v(Object).grep_v(Object).size.should == nil
- end
-
- describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
- it "stops after specified times when not given a block" do
- (0..Float::INFINITY).lazy.grep_v(3..5).grep_v(6..10).first(3).should == [0, 1, 2]
-
- @eventsmixed.grep_v(Symbol).grep_v(String).first(1)
- ScratchPad.recorded.should == [:before_yield]
- end
-
- it "stops after specified times when given a block" do
- (0..Float::INFINITY).lazy
- .grep_v(1..2) { |n| n > 3 ? n : false }
- .grep_v(false) { |n| n.even? ? n : false }
- .first(3)
- .should == [4, false, 6]
-
- @eventsmixed.grep_v(Symbol) {}.grep_v(String) {}.first(1)
- ScratchPad.recorded.should == [:before_yield]
- end
- end
- end
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.grep_v(String).first(100).should ==
+ s.first(100).grep_v(String)
end
end
diff --git a/spec/ruby/core/enumerator/lazy/initialize_spec.rb b/spec/ruby/core/enumerator/lazy/initialize_spec.rb
index 47eeafb5cf..f23018d010 100644
--- a/spec/ruby/core/enumerator/lazy/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/initialize_spec.rb
@@ -1,6 +1,6 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Enumerator::Lazy#initialize" do
before :each do
@@ -43,21 +43,21 @@ describe "Enumerator::Lazy#initialize" do
@uninitialized.send(:initialize, @receiver, Float::INFINITY) {}.size.should equal(Float::INFINITY)
end
- it "sets given size to own size if the given size is a Fixnum" do
+ it "sets given size to own size if the given size is an Integer" do
@uninitialized.send(:initialize, @receiver, 100) {}.size.should == 100
end
it "sets given size to own size if the given size is a Proc" do
- @uninitialized.send(:initialize, @receiver, lambda { 200 }) {}.size.should == 200
+ @uninitialized.send(:initialize, @receiver, -> { 200 }) {}.size.should == 200
end
it "raises an ArgumentError when block is not given" do
- lambda { @uninitialized.send :initialize, @receiver }.should raise_error(ArgumentError)
+ -> { @uninitialized.send :initialize, @receiver }.should raise_error(ArgumentError)
end
describe "on frozen instance" do
it "raises a RuntimeError" do
- lambda { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(RuntimeError)
+ -> { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(RuntimeError)
end
end
end
diff --git a/spec/ruby/core/enumerator/lazy/lazy_spec.rb b/spec/ruby/core/enumerator/lazy/lazy_spec.rb
index a82a1af271..cde9b31066 100644
--- a/spec/ruby/core/enumerator/lazy/lazy_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/lazy_spec.rb
@@ -1,11 +1,23 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Enumerator::Lazy" do
it "is a subclass of Enumerator" do
Enumerator::Lazy.superclass.should equal(Enumerator)
end
+
+ it "defines lazy versions of a whitelist of Enumerator methods" do
+ lazy_methods = [
+ :chunk, :collect, :collect_concat, :drop, :drop_while, :enum_for,
+ :find_all, :flat_map, :force, :grep, :grep_v, :lazy, :map, :reject,
+ :select, :slice_after, :slice_before, :slice_when, :take, :take_while,
+ :to_enum, :zip
+ ]
+ lazy_methods += [:chunk_while, :uniq]
+
+ Enumerator::Lazy.instance_methods(false).should include(*lazy_methods)
+ end
end
describe "Enumerator::Lazy#lazy" do
diff --git a/spec/ruby/core/enumerator/lazy/map_spec.rb b/spec/ruby/core/enumerator/lazy/map_spec.rb
index 8ff2573fe5..5cb998f5f7 100644
--- a/spec/ruby/core/enumerator/lazy/map_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/map_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/collect', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/collect'
describe "Enumerator::Lazy#map" do
it_behaves_like :enumerator_lazy_collect, :map
diff --git a/spec/ruby/core/enumerator/lazy/reject_spec.rb b/spec/ruby/core/enumerator/lazy/reject_spec.rb
index 317e927f02..0e1632d667 100644
--- a/spec/ruby/core/enumerator/lazy/reject_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/reject_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#reject" do
before :each do
@@ -33,6 +33,18 @@ describe "Enumerator::Lazy#reject" do
end
end
+ it "lets exceptions raised in the block go through" do
+ lazy = 10.times.lazy.map do |i|
+ raise "foo"
+ end
+
+ lazy = lazy.reject(&:nil?)
+
+ -> {
+ lazy.first
+ }.should raise_error(RuntimeError, "foo")
+ end
+
it "calls the block with a gathered array when yield with multiple arguments" do
yields = []
@yieldsmixed.reject { |v| yields << v }.force
@@ -40,7 +52,7 @@ describe "Enumerator::Lazy#reject" do
end
it "raises an ArgumentError when not given a block" do
- lambda { @yieldsmixed.reject }.should raise_error(ArgumentError)
+ -> { @yieldsmixed.reject }.should raise_error(ArgumentError)
end
describe "on a nested Lazy" do
@@ -57,4 +69,10 @@ describe "Enumerator::Lazy#reject" do
end
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.reject { |n| false }.first(100).should ==
+ s.first(100).reject { |n| false }
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/select_spec.rb b/spec/ruby/core/enumerator/lazy/select_spec.rb
index ba5823c7ad..3773d8f0a8 100644
--- a/spec/ruby/core/enumerator/lazy/select_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/select_spec.rb
@@ -1,8 +1,47 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/select', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/select'
describe "Enumerator::Lazy#select" do
it_behaves_like :enumerator_lazy_select, :select
+
+ it "doesn't pre-evaluate the next element" do
+ eval_count = 0
+ enum = %w[Text1 Text2 Text3].lazy.select do
+ eval_count += 1
+ true
+ end
+
+ eval_count.should == 0
+ enum.next
+ eval_count.should == 1
+ end
+
+ it "doesn't over-evaluate when peeked" do
+ eval_count = 0
+ enum = %w[Text1 Text2 Text3].lazy.select do
+ eval_count += 1
+ true
+ end
+
+ eval_count.should == 0
+ enum.peek
+ enum.peek
+ eval_count.should == 1
+ end
+
+ it "doesn't re-evaluate after peek" do
+ eval_count = 0
+ enum = %w[Text1 Text2 Text3].lazy.select do
+ eval_count += 1
+ true
+ end
+
+ eval_count.should == 0
+ enum.peek
+ eval_count.should == 1
+ enum.next
+ eval_count.should == 1
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/shared/collect.rb b/spec/ruby/core/enumerator/lazy/shared/collect.rb
index c892784bc2..5690255a0c 100644
--- a/spec/ruby/core/enumerator/lazy/shared/collect.rb
+++ b/spec/ruby/core/enumerator/lazy/shared/collect.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../../../../spec_helper'
+require_relative '../fixtures/classes'
describe :enumerator_lazy_collect, shared: true do
before :each do
@@ -53,4 +53,10 @@ describe :enumerator_lazy_collect, shared: true do
end
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.send(@method) { |n| n }.first(100).should ==
+ s.first(100).send(@method) { |n| n }.to_a
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/shared/collect_concat.rb b/spec/ruby/core/enumerator/lazy/shared/collect_concat.rb
index 69bc10c1a4..00d7941a61 100644
--- a/spec/ruby/core/enumerator/lazy/shared/collect_concat.rb
+++ b/spec/ruby/core/enumerator/lazy/shared/collect_concat.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../../../../spec_helper'
+require_relative '../fixtures/classes'
describe :enumerator_lazy_collect_concat, shared: true do
before :each do
@@ -46,7 +46,7 @@ describe :enumerator_lazy_collect_concat, shared: true do
end
it "raises an ArgumentError when not given a block" do
- lambda { @yieldsmixed.send(@method) }.should raise_error(ArgumentError)
+ -> { @yieldsmixed.send(@method) }.should raise_error(ArgumentError)
end
describe "on a nested Lazy" do
@@ -69,4 +69,10 @@ describe :enumerator_lazy_collect_concat, shared: true do
end
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.send(@method) { |n| [-n, +n] }.first(200).should ==
+ s.first(100).send(@method) { |n| [-n, +n] }.to_a
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/shared/select.rb b/spec/ruby/core/enumerator/lazy/shared/select.rb
index 546256360e..50a00bcbf4 100644
--- a/spec/ruby/core/enumerator/lazy/shared/select.rb
+++ b/spec/ruby/core/enumerator/lazy/shared/select.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../../spec_helper', __FILE__)
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../../../../spec_helper'
+require_relative '../fixtures/classes'
describe :enumerator_lazy_select, shared: true do
before :each do
@@ -40,7 +40,7 @@ describe :enumerator_lazy_select, shared: true do
end
it "raises an ArgumentError when not given a block" do
- lambda { @yieldsmixed.send(@method) }.should raise_error(ArgumentError)
+ -> { @yieldsmixed.send(@method) }.should raise_error(ArgumentError)
end
describe "on a nested Lazy" do
@@ -57,4 +57,10 @@ describe :enumerator_lazy_select, shared: true do
end
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.send(@method) { |n| true }.first(100).should ==
+ s.first(100).send(@method) { |n| true }
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/shared/to_enum.rb b/spec/ruby/core/enumerator/lazy/shared/to_enum.rb
index 5e6935b45a..0c91ea55b9 100644
--- a/spec/ruby/core/enumerator/lazy/shared/to_enum.rb
+++ b/spec/ruby/core/enumerator/lazy/shared/to_enum.rb
@@ -1,6 +1,6 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../../spec_helper', __FILE__)
+require_relative '../../../../spec_helper'
describe :enumerator_lazy_to_enum, shared: true do
before :each do
@@ -43,8 +43,13 @@ describe :enumerator_lazy_to_enum, shared: true do
each_entry: [],
each_cons: [2]
}.each_pair do |method, args|
- @infinite.method(method).owner.should_not equal(Enumerator::Lazy)
@infinite.send(method, *args).should be_an_instance_of(Enumerator::Lazy)
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.send(@method, :with_index).first(100).should ==
+ s.first(100).to_enum.send(@method, :with_index).to_a
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/slice_after_spec.rb b/spec/ruby/core/enumerator/lazy/slice_after_spec.rb
new file mode 100644
index 0000000000..438df8d550
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/slice_after_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../../spec_helper'
+
+describe "Enumerator::Lazy#slice_after" do
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.slice_after { |n| true }.first(100).should ==
+ s.first(100).slice_after { |n| true }.to_a
+ end
+end
diff --git a/spec/ruby/core/enumerator/lazy/slice_before_spec.rb b/spec/ruby/core/enumerator/lazy/slice_before_spec.rb
new file mode 100644
index 0000000000..6c8660c1a1
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/slice_before_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../../spec_helper'
+
+describe "Enumerator::Lazy#slice_before" do
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.slice_before { |n| true }.first(100).should ==
+ s.first(100).slice_before { |n| true }.to_a
+ end
+end
diff --git a/spec/ruby/core/enumerator/lazy/slice_when_spec.rb b/spec/ruby/core/enumerator/lazy/slice_when_spec.rb
new file mode 100644
index 0000000000..e7673def47
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/slice_when_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../../spec_helper'
+
+describe "Enumerator::Lazy#slice_when" do
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.slice_when { |a, b| true }.first(100).should ==
+ s.first(100).slice_when { |a, b| true }.to_a
+ end
+end
diff --git a/spec/ruby/core/enumerator/lazy/take_spec.rb b/spec/ruby/core/enumerator/lazy/take_spec.rb
index 5ef732237d..9fc17e969f 100644
--- a/spec/ruby/core/enumerator/lazy/take_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/take_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#take" do
before :each do
diff --git a/spec/ruby/core/enumerator/lazy/take_while_spec.rb b/spec/ruby/core/enumerator/lazy/take_while_spec.rb
index 8647dfcaf0..bcea0b1419 100644
--- a/spec/ruby/core/enumerator/lazy/take_while_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/take_while_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#take_while" do
before :each do
@@ -40,7 +40,7 @@ describe "Enumerator::Lazy#take_while" do
end
it "raises an ArgumentError when not given a block" do
- lambda { @yieldsmixed.take_while }.should raise_error(ArgumentError)
+ -> { @yieldsmixed.take_while }.should raise_error(ArgumentError)
end
describe "on a nested Lazy" do
diff --git a/spec/ruby/core/enumerator/lazy/to_enum_spec.rb b/spec/ruby/core/enumerator/lazy/to_enum_spec.rb
index e0966037ab..210e5294b7 100644
--- a/spec/ruby/core/enumerator/lazy/to_enum_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/to_enum_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../shared/to_enum', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'shared/to_enum'
describe "Enumerator::Lazy#to_enum" do
it_behaves_like :enumerator_lazy_to_enum, :to_enum
diff --git a/spec/ruby/core/enumerator/lazy/uniq_spec.rb b/spec/ruby/core/enumerator/lazy/uniq_spec.rb
index 6220c7ba34..ce67ace5ab 100644
--- a/spec/ruby/core/enumerator/lazy/uniq_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/uniq_spec.rb
@@ -1,39 +1,74 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-
-ruby_version_is '2.4' do
- describe 'Enumerator::Lazy#uniq' do
- context 'when yielded with an argument' do
- before :each do
- @lazy = [0, 1, 2, 3].to_enum.lazy.uniq(&:even?)
- end
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
- it 'returns a lazy enumerator' do
- @lazy.should be_an_instance_of(Enumerator::Lazy)
- @lazy.force.should == [0, 1]
- end
+describe 'Enumerator::Lazy#uniq' do
+ context 'without block' do
+ before :each do
+ @lazy = [0, 1, 0, 1].to_enum.lazy.uniq
+ end
- it 'sets the size to nil' do
- @lazy.size.should == nil
- end
+ it 'returns a lazy enumerator' do
+ @lazy.should be_an_instance_of(Enumerator::Lazy)
+ @lazy.force.should == [0, 1]
+ end
+
+ it 'return same value after rewind' do
+ @lazy.force.should == [0, 1]
+ @lazy.force.should == [0, 1]
+ end
+
+ it 'sets the size to nil' do
+ @lazy.size.should == nil
+ end
+ end
+
+ context 'when yielded with an argument' do
+ before :each do
+ @lazy = [0, 1, 2, 3].to_enum.lazy.uniq(&:even?)
+ end
+
+ it 'returns a lazy enumerator' do
+ @lazy.should be_an_instance_of(Enumerator::Lazy)
+ @lazy.force.should == [0, 1]
+ end
+
+ it 'return same value after rewind' do
+ @lazy.force.should == [0, 1]
+ @lazy.force.should == [0, 1]
end
- context 'when yielded with multiple arguments' do
- before :each do
- enum = Object.new.to_enum
- class << enum
- def each
- yield 0, 'foo'
- yield 1, 'FOO'
- yield 2, 'bar'
- end
+ it 'sets the size to nil' do
+ @lazy.size.should == nil
+ end
+ end
+
+ context 'when yielded with multiple arguments' do
+ before :each do
+ enum = Object.new.to_enum
+ class << enum
+ def each
+ yield 0, 'foo'
+ yield 1, 'FOO'
+ yield 2, 'bar'
end
- @lazy = enum.lazy
end
+ @lazy = enum.lazy
+ end
- it 'returns all yield arguments as an array' do
- @lazy.uniq { |_, label| label.downcase }.force.should == [[0, 'foo'], [2, 'bar']]
- end
+ it 'return same value after rewind' do
+ enum = @lazy.uniq { |_, label| label.downcase }
+ enum.force.should == [[0, 'foo'], [2, 'bar']]
+ enum.force.should == [[0, 'foo'], [2, 'bar']]
+ end
+
+ it 'returns all yield arguments as an array' do
+ @lazy.uniq { |_, label| label.downcase }.force.should == [[0, 'foo'], [2, 'bar']]
end
end
+
+ it "works with an infinite enumerable" do
+ s = 0..Float::INFINITY
+ s.lazy.uniq.first(100).should ==
+ s.first(100).uniq
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/zip_spec.rb b/spec/ruby/core/enumerator/lazy/zip_spec.rb
index 9c728364ce..5a828c1dcc 100644
--- a/spec/ruby/core/enumerator/lazy/zip_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/zip_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
describe "Enumerator::Lazy#zip" do
before :each do
@@ -44,7 +44,7 @@ describe "Enumerator::Lazy#zip" do
end
it "raises a TypeError if arguments contain non-list object" do
- lambda { @yieldsmixed.zip [], Object.new, [] }.should raise_error(TypeError)
+ -> { @yieldsmixed.zip [], Object.new, [] }.should raise_error(TypeError)
end
describe "on a nested Lazy" do
@@ -71,4 +71,16 @@ describe "Enumerator::Lazy#zip" do
end
end
end
+
+ it "works with an infinite enumerable and an array" do
+ s = 0..Float::INFINITY
+ s.lazy.zip(0..1000).first(100).should ==
+ s.first(100).zip(0..100)
+ end
+
+ it "works with two infinite enumerables" do
+ s = 0..Float::INFINITY
+ s.lazy.zip(s).first(100).should ==
+ s.first(100).zip(s)
+ end
end
diff --git a/spec/ruby/core/enumerator/new_spec.rb b/spec/ruby/core/enumerator/new_spec.rb
index e8e0572a40..9aea9fdd17 100644
--- a/spec/ruby/core/enumerator/new_spec.rb
+++ b/spec/ruby/core/enumerator/new_spec.rb
@@ -1,6 +1,120 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/new', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator.new" do
- it_behaves_like(:enum_new, :new)
+ context "no block given" do
+ ruby_version_is '3.0' do
+ it "raises" do
+ -> { Enumerator.new(1, :upto, 3) }.should raise_error(ArgumentError)
+ end
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "creates a new custom enumerator with the given object, iterator and arguments" do
+ enum = Enumerator.new(1, :upto, 3)
+ enum.should be_an_instance_of(Enumerator)
+ end
+
+ it "creates a new custom enumerator that responds to #each" do
+ enum = Enumerator.new(1, :upto, 3)
+ enum.respond_to?(:each).should == true
+ end
+
+ it "creates a new custom enumerator that runs correctly" do
+ Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
+ end
+
+ it "aliases the second argument to :each" do
+ Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
+ end
+
+ it "doesn't check for the presence of the iterator method" do
+ Enumerator.new(nil).should be_an_instance_of(Enumerator)
+ end
+
+ it "uses the latest define iterator method" do
+ class StrangeEach
+ def each
+ yield :foo
+ end
+ end
+ enum = Enumerator.new(StrangeEach.new)
+ enum.to_a.should == [:foo]
+ class StrangeEach
+ def each
+ yield :bar
+ end
+ end
+ enum.to_a.should == [:bar]
+ end
+ end
+ end
+
+ context "when passed a block" do
+ it "defines iteration with block, yielder argument and calling << method" do
+ enum = Enumerator.new do |yielder|
+ a = 1
+
+ loop do
+ yielder << a
+ a = a + 1
+ end
+ end
+
+ enum.take(3).should == [1, 2, 3]
+ end
+
+ it "defines iteration with block, yielder argument and calling yield method" do
+ enum = Enumerator.new do |yielder|
+ a = 1
+
+ loop do
+ yielder.yield(a)
+ a = a + 1
+ end
+ end
+
+ enum.take(3).should == [1, 2, 3]
+ end
+
+ ruby_version_is "2.7" do
+ it "defines iteration with block, yielder argument and treating it as a proc" do
+ enum = Enumerator.new do |yielder|
+ "a\nb\nc".each_line(&yielder)
+ end
+
+ enum.to_a.should == ["a\n", "b\n", "c"]
+ end
+ end
+
+ describe 'yielded values' do
+ it 'handles yield arguments properly' do
+ Enumerator.new { |y| y.yield(1) }.to_a.should == [1]
+ Enumerator.new { |y| y.yield(1) }.first.should == 1
+
+ Enumerator.new { |y| y.yield([1]) }.to_a.should == [[1]]
+ Enumerator.new { |y| y.yield([1]) }.first.should == [1]
+
+ Enumerator.new { |y| y.yield(1, 2) }.to_a.should == [[1, 2]]
+ Enumerator.new { |y| y.yield(1, 2) }.first.should == [1, 2]
+
+ Enumerator.new { |y| y.yield([1, 2]) }.to_a.should == [[1, 2]]
+ Enumerator.new { |y| y.yield([1, 2]) }.first.should == [1, 2]
+ end
+
+ it 'handles << arguments properly' do
+ Enumerator.new { |y| y.<<(1) }.to_a.should == [1]
+ Enumerator.new { |y| y.<<(1) }.first.should == 1
+
+ Enumerator.new { |y| y.<<([1]) }.to_a.should == [[1]]
+ Enumerator.new { |y| y.<<([1]) }.first.should == [1]
+
+ # << doesn't accept multiple arguments
+ # Enumerator.new { |y| y.<<(1, 2) }.to_a.should == [[1, 2]]
+ # Enumerator.new { |y| y.<<(1, 2) }.first.should == [1, 2]
+
+ Enumerator.new { |y| y.<<([1, 2]) }.to_a.should == [[1, 2]]
+ Enumerator.new { |y| y.<<([1, 2]) }.first.should == [1, 2]
+ end
+ end
+ end
end
diff --git a/spec/ruby/core/enumerator/next_spec.rb b/spec/ruby/core/enumerator/next_spec.rb
index 6b3309a2bc..a5e01a399d 100644
--- a/spec/ruby/core/enumerator/next_spec.rb
+++ b/spec/ruby/core/enumerator/next_spec.rb
@@ -1,6 +1,38 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/next', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#next" do
- it_behaves_like(:enum_next,:next)
+ before :each do
+ @enum = 1.upto(3)
+ end
+
+ it "returns the next element of the enumeration" do
+ @enum.next.should == 1
+ @enum.next.should == 2
+ @enum.next.should == 3
+ end
+
+ it "raises a StopIteration exception at the end of the stream" do
+ 3.times { @enum.next }
+ -> { @enum.next }.should raise_error(StopIteration)
+ end
+
+ it "cannot be called again until the enumerator is rewound" do
+ 3.times { @enum.next }
+ -> { @enum.next }.should raise_error(StopIteration)
+ -> { @enum.next }.should raise_error(StopIteration)
+ -> { @enum.next }.should raise_error(StopIteration)
+ @enum.rewind
+ @enum.next.should == 1
+ end
+
+ it "restarts the enumerator if an exception terminated a previous iteration" do
+ exception = StandardError.new
+ enum = Enumerator.new do
+ raise exception
+ end
+
+ result = 2.times.map { enum.next rescue $! }
+
+ result.should == [exception, exception]
+ end
end
diff --git a/spec/ruby/core/enumerator/next_values_spec.rb b/spec/ruby/core/enumerator/next_values_spec.rb
index 2c4b23dc8d..201b5d323f 100644
--- a/spec/ruby/core/enumerator/next_values_spec.rb
+++ b/spec/ruby/core/enumerator/next_values_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#next_values" do
before :each do
@@ -50,6 +50,6 @@ describe "Enumerator#next_values" do
it "raises StopIteration if called on a finished enumerator" do
7.times { @e.next }
- lambda { @e.next_values }.should raise_error(StopIteration)
+ -> { @e.next_values }.should raise_error(StopIteration)
end
end
diff --git a/spec/ruby/core/enumerator/peek_spec.rb b/spec/ruby/core/enumerator/peek_spec.rb
index 26ac85161b..2334385437 100644
--- a/spec/ruby/core/enumerator/peek_spec.rb
+++ b/spec/ruby/core/enumerator/peek_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#peek" do
before :each do
@@ -31,6 +31,6 @@ describe "Enumerator#peek" do
it "raises StopIteration if called on a finished enumerator" do
5.times { @e.next }
- lambda { @e.peek }.should raise_error(StopIteration)
+ -> { @e.peek }.should raise_error(StopIteration)
end
end
diff --git a/spec/ruby/core/enumerator/peek_values_spec.rb b/spec/ruby/core/enumerator/peek_values_spec.rb
index ecc4758854..7865546515 100644
--- a/spec/ruby/core/enumerator/peek_values_spec.rb
+++ b/spec/ruby/core/enumerator/peek_values_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#peek_values" do
before :each do
@@ -52,6 +52,6 @@ describe "Enumerator#peek_values" do
it "raises StopIteration if called on a finished enumerator" do
7.times { @e.next }
- lambda { @e.peek_values }.should raise_error(StopIteration)
+ -> { @e.peek_values }.should raise_error(StopIteration)
end
end
diff --git a/spec/ruby/core/enumerator/plus_spec.rb b/spec/ruby/core/enumerator/plus_spec.rb
new file mode 100644
index 0000000000..c9bae08b04
--- /dev/null
+++ b/spec/ruby/core/enumerator/plus_spec.rb
@@ -0,0 +1,35 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "Enumerator#+" do
+ before :each do
+ ScratchPad.record []
+ end
+
+ it "returns a chain of self and provided enumerators" do
+ one = Enumerator.new { |y| y << 1 }
+ two = Enumerator.new { |y| y << 2 }
+ three = Enumerator.new { |y| y << 3 }
+
+ chain = one + two + three
+
+ chain.should be_an_instance_of(Enumerator::Chain)
+ chain.each { |item| ScratchPad << item }
+ ScratchPad.recorded.should == [1, 2, 3]
+ end
+
+ it "calls #each on each argument" do
+ enum = Enumerator.new { |y| y << "one" }
+
+ obj1 = mock("obj1")
+ obj1.should_receive(:each).once.and_yield("two")
+
+ obj2 = mock("obj2")
+ obj2.should_receive(:each).once.and_yield("three")
+
+ chain = enum + obj1 + obj2
+ chain.each { |item| ScratchPad << item }
+ ScratchPad.recorded.should == ["one", "two", "three"]
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/produce_spec.rb b/spec/ruby/core/enumerator/produce_spec.rb
new file mode 100644
index 0000000000..f6f1dcd429
--- /dev/null
+++ b/spec/ruby/core/enumerator/produce_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "2.7" do
+ describe "Enumerator.produce" do
+ it "creates an infinite enumerator" do
+ enum = Enumerator.produce(0) { |prev| prev + 1 }
+ enum.take(5).should == [0, 1, 2, 3, 4]
+ end
+
+ it "terminates iteration when block raises StopIteration exception" do
+ enum = Enumerator.produce(0) do | prev|
+ raise StopIteration if prev >= 2
+ prev + 1
+ end
+
+ enum.to_a.should == [0, 1, 2]
+ end
+
+ context "when initial value skipped" do
+ it "uses nil instead" do
+ ScratchPad.record []
+ enum = Enumerator.produce { |prev| ScratchPad << prev; (prev || 0) + 1 }
+
+ enum.take(3).should == [1, 2, 3]
+ ScratchPad.recorded.should == [nil, 1, 2]
+ end
+
+ it "starts enumerable from result of first block call" do
+ array = "a\nb\nc\nd".lines
+ lines = Enumerator.produce { array.shift }.take_while { |s| s }
+
+ lines.should == ["a\n", "b\n", "c\n", "d"]
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/rewind_spec.rb b/spec/ruby/core/enumerator/rewind_spec.rb
index 666136d74a..a105f2c619 100644
--- a/spec/ruby/core/enumerator/rewind_spec.rb
+++ b/spec/ruby/core/enumerator/rewind_spec.rb
@@ -1,9 +1,41 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/rewind', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Enumerator#rewind" do
- it_behaves_like(:enum_rewind, :rewind)
+ before :each do
+ @enum = 1.upto(3)
+ end
+
+ it "resets the enumerator to its initial state" do
+ @enum.next.should == 1
+ @enum.next.should == 2
+ @enum.rewind
+ @enum.next.should == 1
+ end
+
+ it "returns self" do
+ @enum.rewind.should == @enum
+ end
+
+ it "has no effect on a new enumerator" do
+ @enum.rewind
+ @enum.next.should == 1
+ end
+
+ it "has no effect if called multiple, consecutive times" do
+ @enum.next.should == 1
+ @enum.rewind
+ @enum.rewind
+ @enum.next.should == 1
+ end
+
+ it "works with peek to reset the position" do
+ @enum.next
+ @enum.next
+ @enum.rewind
+ @enum.next
+ @enum.peek.should == 2
+ end
it "calls the enclosed object's rewind method if one exists" do
obj = mock('rewinder')
@@ -17,7 +49,7 @@ describe "Enumerator#rewind" do
obj = mock('rewinder')
enum = obj.to_enum
obj.should_receive(:each).at_most(1)
- lambda { enum.rewind.should == enum }.should_not raise_error
+ -> { enum.rewind.should == enum }.should_not raise_error
end
end
diff --git a/spec/ruby/core/enumerator/size_spec.rb b/spec/ruby/core/enumerator/size_spec.rb
index ef7940dc16..6accd26a4e 100644
--- a/spec/ruby/core/enumerator/size_spec.rb
+++ b/spec/ruby/core/enumerator/size_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Enumerator#size" do
it "returns same value if set size is an Integer" do
@@ -11,7 +11,7 @@ describe "Enumerator#size" do
it "returns returning value from size.call if set size is a Proc" do
base_size = 100
- enum = Enumerator.new(lambda { base_size + 1 }) {}
+ enum = Enumerator.new(-> { base_size + 1 }) {}
base_size = 200
enum.size.should == 201
base_size = 300
diff --git a/spec/ruby/core/enumerator/to_enum_spec.rb b/spec/ruby/core/enumerator/to_enum_spec.rb
index a719e62212..cadfcf6314 100644
--- a/spec/ruby/core/enumerator/to_enum_spec.rb
+++ b/spec/ruby/core/enumerator/to_enum_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/enum_for', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/enumerator/enum_for'
describe "Enumerator#to_enum" do
it_behaves_like :enum_for, :enum_for
diff --git a/spec/ruby/core/enumerator/with_index_spec.rb b/spec/ruby/core/enumerator/with_index_spec.rb
index 3d0ec0a298..ac37cee508 100644
--- a/spec/ruby/core/enumerator/with_index_spec.rb
+++ b/spec/ruby/core/enumerator/with_index_spec.rb
@@ -1,10 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/with_index', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/enumerator/with_index'
+require_relative '../enumerable/shared/enumeratorized'
describe "Enumerator#with_index" do
- it_behaves_like(:enum_with_index, :with_index)
- it_behaves_like(:enumeratorized_with_origin_size, :with_index, [1,2,3].select)
+ it_behaves_like :enum_with_index, :with_index
+ it_behaves_like :enumeratorized_with_origin_size, :with_index, [1,2,3].select
it "returns a new Enumerator when no block is given" do
enum1 = [1,2,3].select
@@ -14,13 +14,13 @@ describe "Enumerator#with_index" do
end
it "accepts an optional argument when given a block" do
- lambda do
+ -> do
@enum.with_index(1) { |f| f}
end.should_not raise_error(ArgumentError)
end
it "accepts an optional argument when not given a block" do
- lambda do
+ -> do
@enum.with_index(1)
end.should_not raise_error(ArgumentError)
end
@@ -36,7 +36,7 @@ describe "Enumerator#with_index" do
end
it "raises a TypeError when the argument cannot be converted to numeric" do
- lambda do
+ -> do
@enum.with_index('1') {|*i| i}
end.should raise_error(TypeError)
end
diff --git a/spec/ruby/core/enumerator/with_object_spec.rb b/spec/ruby/core/enumerator/with_object_spec.rb
index a7bd74220c..e7ba83fd9f 100644
--- a/spec/ruby/core/enumerator/with_object_spec.rb
+++ b/spec/ruby/core/enumerator/with_object_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/enumerator/with_object', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/enumerator/with_object'
describe "Enumerator#with_object" do
it_behaves_like :enum_with_object, :with_object
diff --git a/spec/ruby/core/enumerator/yielder/append_spec.rb b/spec/ruby/core/enumerator/yielder/append_spec.rb
index d2313b01f4..7f7059774d 100644
--- a/spec/ruby/core/enumerator/yielder/append_spec.rb
+++ b/spec/ruby/core/enumerator/yielder/append_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Enumerator::Yielder#<<" do
# TODO: There's some common behavior between yield and <<; move to a shared spec
@@ -22,14 +22,26 @@ describe "Enumerator::Yielder#<<" do
(y << 1).should equal(y)
end
- it "requires multiple arguments" do
- Enumerator::Yielder.instance_method(:<<).arity.should < 0
- end
+ context "when multiple arguments passed" do
+ ruby_version_is '' ... '2.6' do
+ it "yields the arguments list to the block" do
+ ary = []
+ y = Enumerator::Yielder.new { |*x| ary << x }
+ y.<<(1, 2)
- it "yields with passed arguments" do
- yields = []
- y = Enumerator::Yielder.new {|*args| yields << args }
- y.<<(1, 2)
- yields.should == [[1, 2]]
+ ary.should == [[1, 2]]
+ end
+ end
+
+ ruby_version_is '2.6' do
+ it "raises an ArgumentError" do
+ ary = []
+ y = Enumerator::Yielder.new { |*x| ary << x }
+
+ -> {
+ y.<<(1, 2)
+ }.should raise_error(ArgumentError, /wrong number of arguments/)
+ end
+ end
end
end
diff --git a/spec/ruby/core/enumerator/yielder/initialize_spec.rb b/spec/ruby/core/enumerator/yielder/initialize_spec.rb
index 095b6a64c6..5a6eee2d0f 100644
--- a/spec/ruby/core/enumerator/yielder/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/yielder/initialize_spec.rb
@@ -1,6 +1,6 @@
# -*- encoding: us-ascii -*-
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Enumerator::Yielder#initialize" do
before :each do
diff --git a/spec/ruby/core/enumerator/yielder/to_proc_spec.rb b/spec/ruby/core/enumerator/yielder/to_proc_spec.rb
new file mode 100644
index 0000000000..0ed1645853
--- /dev/null
+++ b/spec/ruby/core/enumerator/yielder/to_proc_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "2.7" do
+ describe "Enumerator::Yielder#to_proc" do
+ it "returns a Proc object that takes an argument and yields it to the block" do
+ ScratchPad.record []
+ y = Enumerator::Yielder.new { |*args| ScratchPad << args; "foobar" }
+
+ callable = y.to_proc
+ callable.class.should == Proc
+
+ result = callable.call(1, 2)
+ ScratchPad.recorded.should == [[1, 2]]
+
+ result.should == "foobar"
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/yielder/yield_spec.rb b/spec/ruby/core/enumerator/yielder/yield_spec.rb
index be904afef1..acfdf114b6 100644
--- a/spec/ruby/core/enumerator/yielder/yield_spec.rb
+++ b/spec/ruby/core/enumerator/yielder/yield_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
describe "Enumerator::Yielder#yield" do
it "yields the value to the block" do
@@ -9,8 +9,25 @@ describe "Enumerator::Yielder#yield" do
ary.should == [1]
end
+ it "yields with passed arguments" do
+ yields = []
+ y = Enumerator::Yielder.new {|*args| yields << args }
+ y.yield 1, 2
+ yields.should == [[1, 2]]
+ end
+
it "returns the result of the block for the given value" do
y = Enumerator::Yielder.new {|x| x + 1}
y.yield(1).should == 2
end
+
+ context "when multiple arguments passed" do
+ it "yields the arguments list to the block" do
+ ary = []
+ y = Enumerator::Yielder.new { |*x| ary << x }
+ y.yield(1, 2)
+
+ ary.should == [[1, 2]]
+ end
+ end
end
diff --git a/spec/ruby/core/env/assoc_spec.rb b/spec/ruby/core/env/assoc_spec.rb
index fb10a52b3c..c7a388db75 100644
--- a/spec/ruby/core/env/assoc_spec.rb
+++ b/spec/ruby/core/env/assoc_spec.rb
@@ -1,8 +1,12 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.assoc" do
+ before :each do
+ @foo = ENV["foo"]
+ end
+
after :each do
- ENV.delete("foo")
+ ENV["foo"] = @foo
end
it "returns an array of the key and value of the environment variable with the given key" do
@@ -20,4 +24,8 @@ describe "ENV.assoc" do
k.should_receive(:to_str).and_return("foo")
ENV.assoc(k).should == ["foo", "bar"]
end
+
+ it "raises TypeError if the argument is not a String and does not respond to #to_str" do
+ -> { ENV.assoc(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
end
diff --git a/spec/ruby/core/env/clear_spec.rb b/spec/ruby/core/env/clear_spec.rb
index c184926cc2..48b034ba1d 100644
--- a/spec/ruby/core/env/clear_spec.rb
+++ b/spec/ruby/core/env/clear_spec.rb
@@ -1,10 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.clear" do
it "deletes all environment variables" do
orig = ENV.to_hash
begin
- ENV.clear
+ ENV.clear.should equal(ENV)
# This used 'env' the helper before. That shells out to 'env' which
# itself sets up certain environment variables before it runs, because
diff --git a/spec/ruby/core/env/delete_if_spec.rb b/spec/ruby/core/env/delete_if_spec.rb
index 9a8220ae7d..d2de51c225 100644
--- a/spec/ruby/core/env/delete_if_spec.rb
+++ b/spec/ruby/core/env/delete_if_spec.rb
@@ -1,15 +1,32 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
describe "ENV.delete_if" do
+ before :each do
+ @foo = ENV["foo"]
+ @bar = ENV["bar"]
+
+ ENV["foo"] = "0"
+ ENV["bar"] = "1"
+ end
+
+ after :each do
+ ENV["foo"] = @foo
+ ENV["bar"] = @bar
+ end
+
it "deletes pairs if the block returns true" do
- ENV["foo"] = "bar"
- ENV.delete_if { |k, v| k == "foo" }
+ ENV.delete_if { |k, v| ["foo", "bar"].include?(k) }
ENV["foo"].should == nil
+ ENV["bar"].should == nil
+ end
+
+ it "returns ENV when block given" do
+ ENV.delete_if { |k, v| ["foo", "bar"].include?(k) }.should equal(ENV)
end
it "returns ENV even if nothing deleted" do
- ENV.delete_if { false }.should_not == nil
+ ENV.delete_if { false }.should equal(ENV)
end
it "returns an Enumerator if no block given" do
@@ -17,10 +34,20 @@ describe "ENV.delete_if" do
end
it "deletes pairs through enumerator" do
- ENV["foo"] = "bar"
enum = ENV.delete_if
- enum.each { |k, v| k == "foo" }
+ enum.each { |k, v| ["foo", "bar"].include?(k) }
ENV["foo"].should == nil
+ ENV["bar"].should == nil
+ end
+
+ it "returns ENV from enumerator" do
+ enum = ENV.delete_if
+ enum.each { |k, v| ["foo", "bar"].include?(k) }.should equal(ENV)
+ end
+
+ it "returns ENV from enumerator even if nothing deleted" do
+ enum = ENV.delete_if
+ enum.each { false }.should equal(ENV)
end
it_behaves_like :enumeratorized_with_origin_size, :delete_if, ENV
diff --git a/spec/ruby/core/env/delete_spec.rb b/spec/ruby/core/env/delete_spec.rb
index e02adf963f..5e7891f74d 100644
--- a/spec/ruby/core/env/delete_spec.rb
+++ b/spec/ruby/core/env/delete_spec.rb
@@ -1,8 +1,11 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.delete" do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
after :each do
- ENV.delete("foo")
+ ENV["foo"] = @saved_foo
end
it "removes the variable from the environment" do
@@ -16,9 +19,31 @@ describe "ENV.delete" do
ENV.delete("foo").should == "bar"
end
+ it "returns nil if the named environment variable does not exist and no block given" do
+ ENV.delete("foo")
+ ENV.delete("foo").should == nil
+ end
+
it "yields the name to the given block if the named environment variable does not exist" do
ENV.delete("foo")
ENV.delete("foo") { |name| ScratchPad.record name }
ScratchPad.recorded.should == "foo"
end
+
+ ruby_version_is "3.0" do
+ it "returns the result of given block if the named environment variable does not exist" do
+ ENV.delete("foo")
+ ENV.delete("foo") { |name| "bar" }.should == "bar"
+ end
+ end
+
+ it "does not evaluate the block if the environment variable exists" do
+ ENV["foo"] = "bar"
+ ENV.delete("foo") { |name| fail "Should not happen" }
+ ENV["foo"].should == nil
+ end
+
+ it "raises TypeError if the argument is not a String and does not respond to #to_str" do
+ -> { ENV.delete(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
end
diff --git a/spec/ruby/core/env/each_key_spec.rb b/spec/ruby/core/env/each_key_spec.rb
index 82721cdb96..0efcb09900 100644
--- a/spec/ruby/core/env/each_key_spec.rb
+++ b/spec/ruby/core/env/each_key_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
describe "ENV.each_key" do
@@ -10,7 +10,7 @@ describe "ENV.each_key" do
ENV.clear
ENV["1"] = "3"
ENV["2"] = "4"
- ENV.each_key { |k| e << k }
+ ENV.each_key { |k| e << k }.should equal(ENV)
e.should include("1")
e.should include("2")
ensure
@@ -19,7 +19,9 @@ describe "ENV.each_key" do
end
it "returns an Enumerator if called without a block" do
- ENV.each_key.should be_an_instance_of(Enumerator)
+ enum = ENV.each_key
+ enum.should be_an_instance_of(Enumerator)
+ enum.to_a.should == ENV.keys
end
it "returns keys in the locale encoding" do
diff --git a/spec/ruby/core/env/each_pair_spec.rb b/spec/ruby/core/env/each_pair_spec.rb
index 255ccd86c5..2d7ed5faa0 100644
--- a/spec/ruby/core/env/each_pair_spec.rb
+++ b/spec/ruby/core/env/each_pair_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each.rb', __FILE__)
+require_relative 'spec_helper'
+require_relative 'shared/each'
describe "ENV.each_pair" do
- it_behaves_like(:env_each, :each_pair)
+ it_behaves_like :env_each, :each_pair
end
diff --git a/spec/ruby/core/env/each_spec.rb b/spec/ruby/core/env/each_spec.rb
index 2424c5e4e0..d1e06f55b6 100644
--- a/spec/ruby/core/env/each_spec.rb
+++ b/spec/ruby/core/env/each_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/each.rb', __FILE__)
+require_relative 'spec_helper'
+require_relative 'shared/each'
describe "ENV.each" do
- it_behaves_like(:env_each, :each)
+ it_behaves_like :env_each, :each
end
diff --git a/spec/ruby/core/env/each_value_spec.rb b/spec/ruby/core/env/each_value_spec.rb
index 070a1d2cb9..cc3c9ebfb8 100644
--- a/spec/ruby/core/env/each_value_spec.rb
+++ b/spec/ruby/core/env/each_value_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative 'spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
describe "ENV.each_value" do
@@ -10,7 +10,7 @@ describe "ENV.each_value" do
ENV.clear
ENV["1"] = "3"
ENV["2"] = "4"
- ENV.each_value { |v| e << v }
+ ENV.each_value { |v| e << v }.should equal(ENV)
e.should include("3")
e.should include("4")
ensure
@@ -19,12 +19,14 @@ describe "ENV.each_value" do
end
it "returns an Enumerator if called without a block" do
- ENV.each_value.should be_an_instance_of(Enumerator)
+ enum = ENV.each_value
+ enum.should be_an_instance_of(Enumerator)
+ enum.to_a.should == ENV.values
end
it "uses the locale encoding" do
ENV.each_value do |value|
- value.encoding.should == Encoding.find('locale')
+ value.should.be_locale_env
end
end
diff --git a/spec/ruby/core/env/element_reference_spec.rb b/spec/ruby/core/env/element_reference_spec.rb
index 2e6402dd28..22633e7a08 100644
--- a/spec/ruby/core/env/element_reference_spec.rb
+++ b/spec/ruby/core/env/element_reference_spec.rb
@@ -1,5 +1,5 @@
-# -*- encoding: ascii-8bit -*-
-require File.expand_path('../../../spec_helper', __FILE__)
+# -*- encoding: binary -*-
+require_relative '../../spec_helper'
describe "ENV.[]" do
before :each do
@@ -16,7 +16,18 @@ describe "ENV.[]" do
it "returns only frozen values" do
ENV[@variable] = "a non-frozen string"
- ENV[@variable].frozen?.should == true
+ ENV[@variable].should.frozen?
+ end
+
+ it "coerces a non-string name with #to_str" do
+ ENV[@variable] = "bar"
+ k = mock('key')
+ k.should_receive(:to_str).and_return(@variable)
+ ENV[k].should == "bar"
+ end
+
+ it "raises TypeError if the argument is not a String and does not respond to #to_str" do
+ -> { ENV[Object.new] }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
platform_is :windows do
@@ -27,40 +38,39 @@ describe "ENV.[]" do
end
end
-with_feature :encoding do
- describe "ENV.[]" do
- before :each do
- @variable = "env_element_reference_encoding_specs"
+describe "ENV.[]" do
+ before :each do
+ @variable = "env_element_reference_encoding_specs"
- @external = Encoding.default_external
- @internal = Encoding.default_internal
+ @external = Encoding.default_external
+ @internal = Encoding.default_internal
- Encoding.default_external = Encoding::ASCII_8BIT
- end
+ Encoding.default_external = Encoding::BINARY
+ end
- after :each do
- Encoding.default_external = @external
- Encoding.default_internal = @internal
+ after :each do
+ Encoding.default_external = @external
+ Encoding.default_internal = @internal
- ENV.delete @variable
- end
+ ENV.delete @variable
+ end
- it "uses the locale encoding if Encoding.default_internal is nil" do
- Encoding.default_internal = nil
+ it "uses the locale encoding if Encoding.default_internal is nil" do
+ Encoding.default_internal = nil
- locale = Encoding.find('locale')
- locale = Encoding::ASCII_8BIT if locale == Encoding::US_ASCII
- ENV[@variable] = "\xC3\xB8"
- ENV[@variable].encoding.should == locale
- end
+ locale = Encoding.find('locale')
+ locale = Encoding::UTF_8 if platform_is :windows
+ locale = Encoding::BINARY if locale == Encoding::US_ASCII
+ ENV[@variable] = "\xC3\xB8"
+ ENV[@variable].encoding.should == locale
+ end
- it "transcodes from the locale encoding to Encoding.default_internal if set" do
- # We cannot reliably know the locale encoding, so we merely check that
- # the result string has the expected encoding.
- ENV[@variable] = ""
- Encoding.default_internal = Encoding::IBM437
+ it "transcodes from the locale encoding to Encoding.default_internal if set" do
+ # We cannot reliably know the locale encoding, so we merely check that
+ # the result string has the expected encoding.
+ ENV[@variable] = ""
+ Encoding.default_internal = Encoding::IBM437
- ENV[@variable].encoding.should equal(Encoding::IBM437)
- end
+ ENV[@variable].encoding.should equal(Encoding::IBM437)
end
end
diff --git a/spec/ruby/core/env/element_set_spec.rb b/spec/ruby/core/env/element_set_spec.rb
index a80cd0c51e..26dfee1ade 100644
--- a/spec/ruby/core/env/element_set_spec.rb
+++ b/spec/ruby/core/env/element_set_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/store.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/store'
describe "ENV.[]=" do
- it_behaves_like(:env_store, :[]=)
+ it_behaves_like :env_store, :[]=
end
diff --git a/spec/ruby/core/env/empty_spec.rb b/spec/ruby/core/env/empty_spec.rb
index fa02985a6e..afeb406a9e 100644
--- a/spec/ruby/core/env/empty_spec.rb
+++ b/spec/ruby/core/env/empty_spec.rb
@@ -1,15 +1,15 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.empty?" do
it "returns true if the Environment is empty" do
if ENV.keys.size > 0
- ENV.empty?.should == false
+ ENV.should_not.empty?
end
orig = ENV.to_hash
begin
ENV.clear
- ENV.empty?.should == true
+ ENV.should.empty?
ensure
ENV.replace orig
end
@@ -17,7 +17,7 @@ describe "ENV.empty?" do
it "returns false if not empty" do
if ENV.keys.size > 0
- ENV.empty?.should == false
+ ENV.should_not.empty?
end
end
end
diff --git a/spec/ruby/core/env/fetch_spec.rb b/spec/ruby/core/env/fetch_spec.rb
index 708ee91c39..f3af6f3dc2 100644
--- a/spec/ruby/core/env/fetch_spec.rb
+++ b/spec/ruby/core/env/fetch_spec.rb
@@ -1,35 +1,63 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/hash/key_error'
describe "ENV.fetch" do
+ before :each do
+ @foo_saved = ENV.delete("foo")
+ end
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
+
it "returns a value" do
ENV["foo"] = "bar"
ENV.fetch("foo").should == "bar"
- ENV.delete "foo"
end
it "raises a TypeError if the key is not a String" do
- lambda { ENV.fetch :should_never_be_set }.should raise_error(TypeError)
+ -> { ENV.fetch Object.new }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
- it "raises a KeyError if the key is not found" do
- lambda { ENV.fetch "should_never_be_set" }.should raise_error(KeyError)
+ context "when the key is not found" do
+ it_behaves_like :key_error, -> obj, key { obj.fetch(key) }, ENV
+
+ it "formats the object with #inspect in the KeyError message" do
+ -> {
+ ENV.fetch('foo')
+ }.should raise_error(KeyError, 'key not found: "foo"')
+ end
end
it "provides the given default parameter" do
- ENV.fetch("should_never_be_set", "default").should == "default"
+ ENV.fetch("foo", "default").should == "default"
+ end
+
+ it "does not insist that the default be a String" do
+ ENV.fetch("foo", :default).should == :default
end
it "provides a default value from a block" do
- ENV.fetch("should_never_be_set") { |k| "wanted #{k}" }.should == "wanted should_never_be_set"
+ ENV.fetch("foo") { |k| "wanted #{k}" }.should == "wanted foo"
+ end
+
+ it "does not insist that the block return a String" do
+ ENV.fetch("foo") { |k| k.to_sym }.should == :foo
end
it "warns on block and default parameter given" do
- lambda do
- ENV.fetch("should_never_be_set", "default") { 1 }.should == 1
+ -> do
+ ENV.fetch("foo", "default") { "bar" }.should == "bar"
end.should complain(/block supersedes default value argument/)
end
+ it "does not evaluate the block when key found" do
+ ENV["foo"] = "bar"
+ ENV.fetch("foo") { fail "should not get here"}.should == "bar"
+ end
+
it "uses the locale encoding" do
- ENV.fetch(ENV.keys.first).encoding.should == Encoding.find('locale')
+ encoding = platform_is(:windows) ? Encoding::UTF_8 : Encoding.find('locale')
+ ENV["foo"] = "bar"
+ ENV.fetch("foo").encoding.should == encoding
end
end
diff --git a/spec/ruby/core/env/filter_spec.rb b/spec/ruby/core/env/filter_spec.rb
new file mode 100644
index 0000000000..ba18a3b33b
--- /dev/null
+++ b/spec/ruby/core/env/filter_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
+require_relative 'shared/select'
+
+ruby_version_is "2.6" do
+ describe "ENV.filter!" do
+ it_behaves_like :env_select!, :filter!
+ it_behaves_like :enumeratorized_with_origin_size, :filter!, ENV
+ end
+
+ describe "ENV.filter" do
+ it_behaves_like :env_select, :filter
+ it_behaves_like :enumeratorized_with_origin_size, :filter, ENV
+ end
+end
diff --git a/spec/ruby/core/env/has_key_spec.rb b/spec/ruby/core/env/has_key_spec.rb
index 8da2d94265..798668105d 100644
--- a/spec/ruby/core/env/has_key_spec.rb
+++ b/spec/ruby/core/env/has_key_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/include.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/include'
describe "ENV.has_key?" do
- it_behaves_like(:env_include, :has_key?)
+ it_behaves_like :env_include, :has_key?
end
diff --git a/spec/ruby/core/env/has_value_spec.rb b/spec/ruby/core/env/has_value_spec.rb
index 76980a8df4..a2bf3eb877 100644
--- a/spec/ruby/core/env/has_value_spec.rb
+++ b/spec/ruby/core/env/has_value_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/value.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/value'
describe "ENV.has_value?" do
- it_behaves_like(:env_value, :has_value?)
+ it_behaves_like :env_value, :has_value?
end
diff --git a/spec/ruby/core/env/include_spec.rb b/spec/ruby/core/env/include_spec.rb
index 4a716fee85..3975f095ac 100644
--- a/spec/ruby/core/env/include_spec.rb
+++ b/spec/ruby/core/env/include_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/include.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/include'
describe "ENV.include?" do
- it_behaves_like(:env_include, :include?)
+ it_behaves_like :env_include, :include?
end
diff --git a/spec/ruby/core/env/index_spec.rb b/spec/ruby/core/env/index_spec.rb
index 95009b3558..301a66ab4e 100644
--- a/spec/ruby/core/env/index_spec.rb
+++ b/spec/ruby/core/env/index_spec.rb
@@ -1,6 +1,14 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/key.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/key'
-describe "ENV.index" do
- it_behaves_like(:env_key, :index)
+ruby_version_is ''...'3.0' do
+ describe "ENV.index" do
+ it_behaves_like :env_key, :index
+
+ it "warns about deprecation" do
+ -> do
+ ENV.index("foo")
+ end.should complain(/warning: ENV.index is deprecated; use ENV.key/)
+ end
+ end
end
diff --git a/spec/ruby/core/env/indexes_spec.rb b/spec/ruby/core/env/indexes_spec.rb
index 14fb93ef07..e724feaa39 100644
--- a/spec/ruby/core/env/indexes_spec.rb
+++ b/spec/ruby/core/env/indexes_spec.rb
@@ -1 +1 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
diff --git a/spec/ruby/core/env/indices_spec.rb b/spec/ruby/core/env/indices_spec.rb
index 14fb93ef07..e724feaa39 100644
--- a/spec/ruby/core/env/indices_spec.rb
+++ b/spec/ruby/core/env/indices_spec.rb
@@ -1 +1 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
diff --git a/spec/ruby/core/env/inspect_spec.rb b/spec/ruby/core/env/inspect_spec.rb
index 9c4273e188..3c611c24a1 100644
--- a/spec/ruby/core/env/inspect_spec.rb
+++ b/spec/ruby/core/env/inspect_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.inspect" do
diff --git a/spec/ruby/core/env/invert_spec.rb b/spec/ruby/core/env/invert_spec.rb
index 42170230db..c095374d95 100644
--- a/spec/ruby/core/env/invert_spec.rb
+++ b/spec/ruby/core/env/invert_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.invert" do
before :each do
diff --git a/spec/ruby/core/env/keep_if_spec.rb b/spec/ruby/core/env/keep_if_spec.rb
index c5bbc3dc05..64b6a207d0 100644
--- a/spec/ruby/core/env/keep_if_spec.rb
+++ b/spec/ruby/core/env/keep_if_spec.rb
@@ -1,22 +1,32 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
describe "ENV.keep_if" do
before :each do
- ENV["foo"] = "bar"
+ @foo = ENV["foo"]
+ @bar = ENV["bar"]
+
+ ENV["foo"] = "0"
+ ENV["bar"] = "1"
end
after :each do
- ENV.delete "foo"
+ ENV["foo"] = @foo
+ ENV["bar"] = @bar
end
it "deletes pairs if the block returns false" do
- ENV.keep_if { |k, v| k != "foo" }
+ ENV.keep_if { |k, v| !["foo", "bar"].include?(k) }
ENV["foo"].should == nil
+ ENV["bar"].should == nil
+ end
+
+ it "returns ENV when block given" do
+ ENV.keep_if { |k, v| !["foo", "bar"].include?(k) }.should equal(ENV)
end
it "returns ENV even if nothing deleted" do
- ENV.keep_if { true }.should_not == nil
+ ENV.keep_if { true }.should equal(ENV)
end
it "returns an Enumerator if no block given" do
@@ -25,8 +35,19 @@ describe "ENV.keep_if" do
it "deletes pairs through enumerator" do
enum = ENV.keep_if
- enum.each { |k, v| k != "foo" }
+ enum.each { |k, v| !["foo", "bar"].include?(k) }
ENV["foo"].should == nil
+ ENV["bar"].should == nil
+ end
+
+ it "returns ENV from enumerator" do
+ enum = ENV.keep_if
+ enum.each { |k, v| !["foo", "bar"].include?(k) }.should equal(ENV)
+ end
+
+ it "returns ENV from enumerator even if nothing deleted" do
+ enum = ENV.keep_if
+ enum.each { true }.should equal(ENV)
end
it_behaves_like :enumeratorized_with_origin_size, :keep_if, ENV
diff --git a/spec/ruby/core/env/key_spec.rb b/spec/ruby/core/env/key_spec.rb
index b653b1b1a5..82cfbefa39 100644
--- a/spec/ruby/core/env/key_spec.rb
+++ b/spec/ruby/core/env/key_spec.rb
@@ -1,11 +1,11 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/include.rb', __FILE__)
-require File.expand_path('../shared/key.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/include'
+require_relative 'shared/key'
describe "ENV.key?" do
- it_behaves_like(:env_include, :key?)
+ it_behaves_like :env_include, :key?
end
describe "ENV.key" do
- it_behaves_like(:env_key, :key)
+ it_behaves_like :env_key, :key
end
diff --git a/spec/ruby/core/env/keys_spec.rb b/spec/ruby/core/env/keys_spec.rb
index d79919b79d..b074a8f7c7 100644
--- a/spec/ruby/core/env/keys_spec.rb
+++ b/spec/ruby/core/env/keys_spec.rb
@@ -1,9 +1,9 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.keys" do
- it "returns all the keys" do
- ENV.keys.sort.should == ENV.to_hash.keys.sort
+ it "returns an array of the keys" do
+ ENV.keys.should == ENV.to_hash.keys
end
it "returns the keys in the locale encoding" do
diff --git a/spec/ruby/core/env/length_spec.rb b/spec/ruby/core/env/length_spec.rb
index 83d1b58c74..536af9edf5 100644
--- a/spec/ruby/core/env/length_spec.rb
+++ b/spec/ruby/core/env/length_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/length.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/length'
describe "ENV.length" do
- it_behaves_like(:env_length, :length)
+ it_behaves_like :env_length, :length
end
diff --git a/spec/ruby/core/env/member_spec.rb b/spec/ruby/core/env/member_spec.rb
index 25aa71e973..9119022ae5 100644
--- a/spec/ruby/core/env/member_spec.rb
+++ b/spec/ruby/core/env/member_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/include.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/include'
describe "ENV.member?" do
- it_behaves_like(:env_include, :member?)
+ it_behaves_like :env_include, :member?
end
diff --git a/spec/ruby/core/env/merge_spec.rb b/spec/ruby/core/env/merge_spec.rb
new file mode 100644
index 0000000000..b418cd11f4
--- /dev/null
+++ b/spec/ruby/core/env/merge_spec.rb
@@ -0,0 +1,8 @@
+require_relative '../../spec_helper'
+require_relative 'shared/update'
+
+ruby_version_is "2.7" do
+ describe "ENV.merge!" do
+ it_behaves_like :env_update, :merge!
+ end
+end
diff --git a/spec/ruby/core/env/rassoc_spec.rb b/spec/ruby/core/env/rassoc_spec.rb
index 3a86e7e158..ab9fe68088 100644
--- a/spec/ruby/core/env/rassoc_spec.rb
+++ b/spec/ruby/core/env/rassoc_spec.rb
@@ -1,8 +1,14 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.rassoc" do
+ before :each do
+ @foo = ENV["foo"]
+ @baz = ENV["baz"]
+ end
+
after :each do
- ENV.delete("foo")
+ ENV["foo"] = @foo
+ ENV["baz"] = @baz
end
it "returns an array of the key and value of the environment variable with the given value" do
@@ -10,6 +16,15 @@ describe "ENV.rassoc" do
ENV.rassoc("bar").should == ["foo", "bar"]
end
+ it "returns a single array even if there are multiple such environment variables" do
+ ENV["foo"] = "bar"
+ ENV["baz"] = "bar"
+ [
+ ["foo", "bar"],
+ ["baz", "bar"],
+ ].should include(ENV.rassoc("bar"))
+ end
+
it "returns nil if no environment variable with the given value exists" do
ENV.rassoc("bar").should == nil
end
@@ -20,4 +35,8 @@ describe "ENV.rassoc" do
v.should_receive(:to_str).and_return("bar")
ENV.rassoc(v).should == ["foo", "bar"]
end
+
+ it "returns nil if the argument is not a String and does not respond to #to_str" do
+ ENV.rassoc(Object.new).should == nil
+ end
end
diff --git a/spec/ruby/core/env/rehash_spec.rb b/spec/ruby/core/env/rehash_spec.rb
index 14fb93ef07..3782e4b727 100644
--- a/spec/ruby/core/env/rehash_spec.rb
+++ b/spec/ruby/core/env/rehash_spec.rb
@@ -1 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
+
+describe "ENV.rehash" do
+ it "returns nil" do
+ ENV.rehash.should == nil
+ end
+end
diff --git a/spec/ruby/core/env/reject_spec.rb b/spec/ruby/core/env/reject_spec.rb
index 0da84425b6..6a9794925d 100644
--- a/spec/ruby/core/env/reject_spec.rb
+++ b/spec/ruby/core/env/reject_spec.rb
@@ -1,7 +1,15 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
describe "ENV.reject!" do
+ before :each do
+ @foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @foo
+ end
+
it "rejects entries based on key" do
ENV["foo"] = "bar"
ENV.reject! { |k, v| k == "foo" }
@@ -17,19 +25,23 @@ describe "ENV.reject!" do
it "returns itself or nil" do
ENV.reject! { false }.should == nil
ENV["foo"] = "bar"
- ENV.reject! { |k, v| k == "foo" }.should == ENV
+ ENV.reject! { |k, v| k == "foo" }.should equal(ENV)
ENV["foo"].should == nil
end
it "returns an Enumerator if called without a block" do
- ENV.reject!.should be_an_instance_of(Enumerator)
+ ENV["foo"] = "bar"
+ enum = ENV.reject!
+ enum.should be_an_instance_of(Enumerator)
+ enum.each { |k, v| k == "foo" }.should equal(ENV)
+ ENV["foo"].should == nil
end
it "doesn't raise if empty" do
orig = ENV.to_hash
begin
ENV.clear
- lambda { ENV.reject! }.should_not raise_error(LocalJumpError)
+ -> { ENV.reject! }.should_not raise_error(LocalJumpError)
ensure
ENV.replace orig
end
@@ -39,6 +51,14 @@ describe "ENV.reject!" do
end
describe "ENV.reject" do
+ before :each do
+ @foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @foo
+ end
+
it "rejects entries based on key" do
ENV["foo"] = "bar"
e = ENV.reject { |k, v| k == "foo" }
@@ -60,14 +80,18 @@ describe "ENV.reject" do
end
it "returns an Enumerator if called without a block" do
- ENV.reject.should be_an_instance_of(Enumerator)
+ ENV["foo"] = "bar"
+ enum = ENV.reject
+ enum.should be_an_instance_of(Enumerator)
+ enum.each { |k, v| k == "foo"}
+ ENV["foo"] = nil
end
it "doesn't raise if empty" do
orig = ENV.to_hash
begin
ENV.clear
- lambda { ENV.reject }.should_not raise_error(LocalJumpError)
+ -> { ENV.reject }.should_not raise_error(LocalJumpError)
ensure
ENV.replace orig
end
diff --git a/spec/ruby/core/env/replace_spec.rb b/spec/ruby/core/env/replace_spec.rb
index 0c11e173ac..9fc67643d1 100644
--- a/spec/ruby/core/env/replace_spec.rb
+++ b/spec/ruby/core/env/replace_spec.rb
@@ -1,15 +1,51 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.replace" do
+ before :each do
+ @orig = ENV.to_hash
+ ENV.delete("foo")
+ end
+
+ after :each do
+ ENV.replace(@orig)
+ end
it "replaces ENV with a Hash" do
- ENV["foo"] = "bar"
- e = ENV.reject { |k, v| k == "foo" }
- e["baz"] = "bam"
- ENV.replace e
- ENV["foo"].should == nil
- ENV["baz"].should == "bam"
- ENV.delete "baz"
+ ENV.replace("foo" => "0", "bar" => "1").should equal(ENV)
+ ENV.size.should == 2
+ ENV["foo"].should == "0"
+ ENV["bar"].should == "1"
+ end
+
+ it "raises TypeError if the argument is not a Hash" do
+ -> { ENV.replace(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into Hash")
+ ENV.to_hash.should == @orig
+ end
+
+ it "raises TypeError if a key is not a String" do
+ -> { ENV.replace(Object.new => "0") }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ ENV.to_hash.should == @orig
+ end
+
+ it "raises TypeError if a value is not a String" do
+ -> { ENV.replace("foo" => Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ ENV.to_hash.should == @orig
+ end
+
+ it "raises Errno::EINVAL when the key contains the '=' character" do
+ -> { ENV.replace("foo=" =>"bar") }.should raise_error(Errno::EINVAL)
+ end
+
+ it "raises Errno::EINVAL when the key is an empty string" do
+ -> { ENV.replace("" => "bar") }.should raise_error(Errno::EINVAL)
+ end
+
+ it "does not accept good data preceding an error" do
+ -> { ENV.replace("foo" => "1", Object.new => Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
+ it "does not accept good data following an error" do
+ -> { ENV.replace(Object.new => Object.new, "foo" => "0") }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ ENV.to_hash.should == @orig
+ end
end
diff --git a/spec/ruby/core/env/select_spec.rb b/spec/ruby/core/env/select_spec.rb
index 8261ff593a..c3a76f4434 100644
--- a/spec/ruby/core/env/select_spec.rb
+++ b/spec/ruby/core/env/select_spec.rb
@@ -1,39 +1,13 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../enumerable/shared/enumeratorized'
+require_relative 'shared/select'
describe "ENV.select!" do
- it "removes environment variables for which the block returns true" do
- ENV["foo"] = "bar"
- ENV.select! { |k, v| k != "foo" }
- ENV["foo"].should == nil
- end
-
- it "returns self if any changes were made" do
- ENV["foo"] = "bar"
- ENV.select! { |k, v| k != "foo" }.should == ENV
- end
-
- it "returns nil if no changes were made" do
- ENV.select! { true }.should == nil
- end
-
- it "returns an Enumerator if called without a block" do
- ENV.select!.should be_an_instance_of(Enumerator)
- end
-
+ it_behaves_like :env_select!, :select!
it_behaves_like :enumeratorized_with_origin_size, :select!, ENV
end
describe "ENV.select" do
- it "returns a Hash of names and values for which block return true" do
- ENV["foo"] = "bar"
- ENV.select { |k, v| k == "foo" }.should == {"foo" => "bar"}
- ENV.delete "foo"
- end
-
- it "returns an Enumerator when no block is given" do
- ENV.select.should be_an_instance_of(Enumerator)
- end
-
+ it_behaves_like :env_select, :select
it_behaves_like :enumeratorized_with_origin_size, :select, ENV
end
diff --git a/spec/ruby/core/env/shared/each.rb b/spec/ruby/core/env/shared/each.rb
index 494fd5cee1..d901b854c4 100644
--- a/spec/ruby/core/env/shared/each.rb
+++ b/spec/ruby/core/env/shared/each.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../enumerable/shared/enumeratorized', __FILE__)
+require_relative '../../enumerable/shared/enumeratorized'
describe :env_each, shared: true do
it "returns each pair" do
@@ -8,7 +8,7 @@ describe :env_each, shared: true do
ENV.clear
ENV["foo"] = "bar"
ENV["baz"] = "boo"
- ENV.send(@method) { |k, v| e << [k, v] }
+ ENV.send(@method) { |k, v| e << [k, v] }.should equal(ENV)
e.should include(["foo", "bar"])
e.should include(["baz", "boo"])
ensure
@@ -17,7 +17,11 @@ describe :env_each, shared: true do
end
it "returns an Enumerator if called without a block" do
- ENV.send(@method).should be_an_instance_of(Enumerator)
+ enum = ENV.send(@method)
+ enum.should be_an_instance_of(Enumerator)
+ enum.each do |name, value|
+ ENV[name].should == value
+ end
end
before :all do
@@ -25,39 +29,35 @@ describe :env_each, shared: true do
end
it_should_behave_like :enumeratorized_with_origin_size
- with_feature :encoding do
- describe "with encoding" do
- before :each do
- @external = Encoding.default_external
- @internal = Encoding.default_internal
-
- Encoding.default_external = Encoding::ASCII_8BIT
+ describe "with encoding" do
+ before :each do
+ @external = Encoding.default_external
+ @internal = Encoding.default_internal
- @locale_encoding = Encoding.find "locale"
- end
+ Encoding.default_external = Encoding::BINARY
+ end
- after :each do
- Encoding.default_external = @external
- Encoding.default_internal = @internal
- end
+ after :each do
+ Encoding.default_external = @external
+ Encoding.default_internal = @internal
+ end
- it "uses the locale encoding when Encoding.default_internal is nil" do
- Encoding.default_internal = nil
+ it "uses the locale encoding when Encoding.default_internal is nil" do
+ Encoding.default_internal = nil
- ENV.send(@method) do |key, value|
- key.encoding.should equal(@locale_encoding)
- value.encoding.should equal(@locale_encoding)
- end
+ ENV.send(@method) do |key, value|
+ key.should.be_locale_env
+ value.should.be_locale_env
end
+ end
- it "transcodes from the locale encoding to Encoding.default_internal if set" do
- Encoding.default_internal = internal = Encoding::IBM437
+ it "transcodes from the locale encoding to Encoding.default_internal if set" do
+ Encoding.default_internal = internal = Encoding::IBM437
- ENV.send(@method) do |key, value|
- key.encoding.should equal(internal)
- if value.ascii_only?
- value.encoding.should equal(internal)
- end
+ ENV.send(@method) do |key, value|
+ key.encoding.should equal(internal)
+ if value.ascii_only?
+ value.encoding.should equal(internal)
end
end
end
diff --git a/spec/ruby/core/env/shared/include.rb b/spec/ruby/core/env/shared/include.rb
index 8d8311dcf2..3efcd523d6 100644
--- a/spec/ruby/core/env/shared/include.rb
+++ b/spec/ruby/core/env/shared/include.rb
@@ -1,11 +1,23 @@
describe :env_include, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
+
it "returns true if ENV has the key" do
ENV["foo"] = "bar"
ENV.send(@method, "foo").should == true
- ENV.delete "foo"
end
it "returns false if ENV doesn't include the key" do
- ENV.send(@method, "should_never_be_set").should == false
+ ENV.delete("foo")
+ ENV.send(@method, "foo").should == false
+ end
+
+ it "raises TypeError if the argument is not a String and does not respond to #to_str" do
+ -> { ENV.send(@method, Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
end
diff --git a/spec/ruby/core/env/shared/key.rb b/spec/ruby/core/env/shared/key.rb
index 5e6c21840f..93396d2aca 100644
--- a/spec/ruby/core/env/shared/key.rb
+++ b/spec/ruby/core/env/shared/key.rb
@@ -1,15 +1,31 @@
describe :env_key, shared: true do
- it "needs to be reviewed for completeness"
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
it "returns the index associated with the passed value" do
ENV["foo"] = "bar"
- ENV.send(@method, "bar").should == "foo"
- ENV.delete "foo"
+ suppress_warning {
+ ENV.send(@method, "bar").should == "foo"
+ }
end
it "returns nil if the passed value is not found" do
- ENV.send(@method, "should_never_be_set").should be_nil
+ ENV.delete("foo")
+ suppress_warning {
+ ENV.send(@method, "foo").should be_nil
+ }
end
-end
-
+ it "raises TypeError if the argument is not a String and does not respond to #to_str" do
+ -> {
+ suppress_warning {
+ ENV.send(@method, Object.new)
+ }
+ }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
+end
diff --git a/spec/ruby/core/env/shared/select.rb b/spec/ruby/core/env/shared/select.rb
new file mode 100644
index 0000000000..75ba112a32
--- /dev/null
+++ b/spec/ruby/core/env/shared/select.rb
@@ -0,0 +1,61 @@
+describe :env_select, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
+
+ it "returns a Hash of names and values for which block return true" do
+ ENV["foo"] = "bar"
+ (ENV.send(@method) { |k, v| k == "foo" }).should == { "foo" => "bar" }
+ end
+
+ it "returns an Enumerator when no block is given" do
+ enum = ENV.send(@method)
+ enum.should be_an_instance_of(Enumerator)
+ end
+
+ it "selects via the enumerator" do
+ enum = ENV.send(@method)
+ ENV["foo"] = "bar"
+ enum.each { |k, v| k == "foo" }.should == { "foo" => "bar"}
+ end
+end
+
+describe :env_select!, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
+
+ it "removes environment variables for which the block returns true" do
+ ENV["foo"] = "bar"
+ ENV.send(@method) { |k, v| k != "foo" }
+ ENV["foo"].should == nil
+ end
+
+ it "returns self if any changes were made" do
+ ENV["foo"] = "bar"
+ (ENV.send(@method) { |k, v| k != "foo" }).should == ENV
+ end
+
+ it "returns nil if no changes were made" do
+ (ENV.send(@method) { true }).should == nil
+ end
+
+ it "returns an Enumerator if called without a block" do
+ ENV.send(@method).should be_an_instance_of(Enumerator)
+ end
+
+ it "selects via the enumerator" do
+ enum = ENV.send(@method)
+ ENV["foo"] = "bar"
+ enum.each { |k, v| k != "foo" }
+ ENV["foo"].should == nil
+ end
+end
diff --git a/spec/ruby/core/env/shared/store.rb b/spec/ruby/core/env/shared/store.rb
index 4949ca8c73..d6265c66a5 100644
--- a/spec/ruby/core/env/shared/store.rb
+++ b/spec/ruby/core/env/shared/store.rb
@@ -1,6 +1,10 @@
describe :env_store, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
after :each do
- ENV.delete("foo")
+ ENV["foo"] = @saved_foo
end
it "sets the environment variable to the given value" do
@@ -34,19 +38,19 @@ describe :env_store, shared: true do
end
it "raises TypeError when the key is not coercible to String" do
- lambda { ENV.send(@method, Object.new, "bar") }.should raise_error(TypeError)
+ -> { ENV.send(@method, Object.new, "bar") }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
it "raises TypeError when the value is not coercible to String" do
- lambda { ENV.send(@method, "foo", Object.new) }.should raise_error(TypeError)
+ -> { ENV.send(@method, "foo", Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
it "raises Errno::EINVAL when the key contains the '=' character" do
- lambda { ENV.send(@method, "foo=", "bar") }.should raise_error(Errno::EINVAL)
+ -> { ENV.send(@method, "foo=", "bar") }.should raise_error(Errno::EINVAL)
end
it "raises Errno::EINVAL when the key is an empty string" do
- lambda { ENV.send(@method, "", "bar") }.should raise_error(Errno::EINVAL)
+ -> { ENV.send(@method, "", "bar") }.should raise_error(Errno::EINVAL)
end
it "does nothing when the key is not a valid environment variable key and the value is nil" do
diff --git a/spec/ruby/core/env/shared/to_hash.rb b/spec/ruby/core/env/shared/to_hash.rb
index 3bfbc415f7..a0d4d7ce69 100644
--- a/spec/ruby/core/env/shared/to_hash.rb
+++ b/spec/ruby/core/env/shared/to_hash.rb
@@ -1,22 +1,33 @@
describe :env_to_hash, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"]= @saved_foo
+ end
+
it "returns the ENV as a hash" do
ENV["foo"] = "bar"
h = ENV.send(@method)
h.should be_an_instance_of(Hash)
h["foo"].should == "bar"
- ENV.delete "foo"
end
it "uses the locale encoding for keys" do
- ENV.send(@method).keys.all? {|k| k.encoding == Encoding.find('locale') }.should be_true
+ ENV.send(@method).keys.each {|k| k.should.be_locale_env }
end
it "uses the locale encoding for values" do
- ENV.send(@method).values.all? {|v| v.encoding == Encoding.find('locale') }.should be_true
+ ENV.send(@method).values.each {|k| k.should.be_locale_env }
end
it "duplicates the ENV when converting to a Hash" do
h = ENV.send(@method)
- h.object_id.should_not == ENV.object_id
+ h.should_not equal ENV
+ h.size.should == ENV.size
+ h.each_pair do |k, v|
+ ENV[k].should == v
+ end
end
end
diff --git a/spec/ruby/core/env/shared/update.rb b/spec/ruby/core/env/shared/update.rb
new file mode 100644
index 0000000000..129a56544c
--- /dev/null
+++ b/spec/ruby/core/env/shared/update.rb
@@ -0,0 +1,100 @@
+describe :env_update, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ @saved_bar = ENV["bar"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ ENV["bar"] = @saved_bar
+ end
+
+ it "adds the parameter hash to ENV, returning ENV" do
+ ENV.send(@method, "foo" => "0", "bar" => "1").should equal(ENV)
+ ENV["foo"].should == "0"
+ ENV["bar"].should == "1"
+ end
+
+ it "returns ENV when no block given" do
+ ENV.send(@method, {"foo" => "0", "bar" => "1"}).should equal(ENV)
+ end
+
+ it "yields key, the old value and the new value when replacing an entry" do
+ ENV.send @method, {"foo" => "0", "bar" => "3"}
+ a = []
+ ENV.send @method, {"foo" => "1", "bar" => "4"} do |key, old, new|
+ a << [key, old, new]
+ new
+ end
+ a[0].should == ["foo", "0", "1"]
+ a[1].should == ["bar", "3", "4"]
+ end
+
+ it "yields key, the old value and the new value when replacing an entry" do
+ ENV.send @method, {"foo" => "0", "bar" => "3"}
+ ENV.send @method, {"foo" => "1", "bar" => "4"} do |key, old, new|
+ (new.to_i + 1).to_s
+ end
+ ENV["foo"].should == "2"
+ ENV["bar"].should == "5"
+ end
+
+ ruby_version_is "2.7" do
+ # BUG: https://bugs.ruby-lang.org/issues/16192
+ it "does not evaluate the block when the name is new" do
+ ENV.delete("bar")
+ ENV.send @method, {"foo" => "0"}
+ ENV.send(@method, "bar" => "1") { |key, old, new| fail "Should not get here" }
+ ENV["bar"].should == "1"
+ end
+
+ # BUG: https://bugs.ruby-lang.org/issues/16192
+ it "does not use the block's return value as the value when the name is new" do
+ ENV.delete("bar")
+ ENV.send @method, {"foo" => "0"}
+ ENV.send(@method, "bar" => "1") { |key, old, new| "Should not use this value" }
+ ENV["foo"].should == "0"
+ ENV["bar"].should == "1"
+ end
+ end
+
+ it "returns ENV when block given" do
+ ENV.send(@method, {"foo" => "0", "bar" => "1"}){}.should equal(ENV)
+ end
+
+ it "raises TypeError when a name is not coercible to String" do
+ -> { ENV.send @method, Object.new => "0" }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
+
+ it "raises TypeError when a value is not coercible to String" do
+ -> { ENV.send @method, "foo" => Object.new }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
+
+ it "raises Errno::EINVAL when a name contains the '=' character" do
+ -> { ENV.send(@method, "foo=" => "bar") }.should raise_error(Errno::EINVAL)
+ end
+
+ it "raises Errno::EINVAL when a name is an empty string" do
+ -> { ENV.send(@method, "" => "bar") }.should raise_error(Errno::EINVAL)
+ end
+
+ it "updates good data preceding an error" do
+ ENV["foo"] = "0"
+ begin
+ ENV.send @method, {"foo" => "2", Object.new => "1"}
+ rescue TypeError
+ ensure
+ ENV["foo"].should == "2"
+ end
+ end
+
+ it "does not update good data following an error" do
+ ENV["foo"] = "0"
+ begin
+ ENV.send @method, {Object.new => "1", "foo" => "2"}
+ rescue TypeError
+ ensure
+ ENV["foo"].should == "0"
+ end
+ end
+end
diff --git a/spec/ruby/core/env/shared/value.rb b/spec/ruby/core/env/shared/value.rb
index d9ee90f12d..bef96b5fef 100644
--- a/spec/ruby/core/env/shared/value.rb
+++ b/spec/ruby/core/env/shared/value.rb
@@ -1,11 +1,22 @@
describe :env_value, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
+
it "returns true if ENV has the value" do
ENV["foo"] = "bar"
ENV.send(@method, "bar").should == true
- ENV["foo"] = nil
end
it "returns false if ENV doesn't have the value" do
- ENV.send(@method, "this_value_should_never_exist").should == false
+ ENV.send(@method, "foo").should == false
+ end
+
+ it "returns nil if the argument is not a String and does not respond to #to_str" do
+ ENV.send(@method, Object.new).should == nil
end
end
diff --git a/spec/ruby/core/env/shift_spec.rb b/spec/ruby/core/env/shift_spec.rb
index bae6a17ba0..49d98c3729 100644
--- a/spec/ruby/core/env/shift_spec.rb
+++ b/spec/ruby/core/env/shift_spec.rb
@@ -1,8 +1,8 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.shift" do
it "returns a pair and deletes it" do
- ENV.empty?.should == false
+ ENV.should_not.empty?
orig = ENV.to_hash
begin
pair = ENV.shift
@@ -24,36 +24,35 @@ describe "ENV.shift" do
end
end
-with_feature :encoding do
- describe "ENV.shift" do
- before :each do
- @orig = ENV.to_hash
- @external = Encoding.default_external
- @internal = Encoding.default_internal
+describe "ENV.shift" do
+ before :each do
+ @orig = ENV.to_hash
+ @external = Encoding.default_external
+ @internal = Encoding.default_internal
- Encoding.default_external = Encoding::ASCII_8BIT
- end
+ Encoding.default_external = Encoding::BINARY
+ end
- after :each do
- Encoding.default_external = @external
- Encoding.default_internal = @internal
- ENV.replace @orig
- end
+ after :each do
+ Encoding.default_external = @external
+ Encoding.default_internal = @internal
+ ENV.replace @orig
+ end
- it "uses the locale encoding if Encoding.default_internal is nil" do
- Encoding.default_internal = nil
+ it "uses the locale encoding if Encoding.default_internal is nil" do
+ Encoding.default_internal = nil
- pair = ENV.shift
- pair.first.encoding.should equal(Encoding.find("locale"))
- pair.last.encoding.should equal(Encoding.find("locale"))
- end
+ encoding = platform_is(:windows) ? Encoding::UTF_8 : Encoding.find('locale')
+ pair = ENV.shift
+ pair.first.encoding.should equal(encoding)
+ pair.last.encoding.should equal(encoding)
+ end
- it "transcodes from the locale encoding to Encoding.default_internal if set" do
- Encoding.default_internal = Encoding::IBM437
+ it "transcodes from the locale encoding to Encoding.default_internal if set" do
+ Encoding.default_internal = Encoding::IBM437
- pair = ENV.shift
- pair.first.encoding.should equal(Encoding::IBM437)
- pair.last.encoding.should equal(Encoding::IBM437)
- end
+ pair = ENV.shift
+ pair.first.encoding.should equal(Encoding::IBM437)
+ pair.last.encoding.should equal(Encoding::IBM437)
end
end
diff --git a/spec/ruby/core/env/size_spec.rb b/spec/ruby/core/env/size_spec.rb
index 882ceac485..f050e9e5a9 100644
--- a/spec/ruby/core/env/size_spec.rb
+++ b/spec/ruby/core/env/size_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/length.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/length'
describe "ENV.size" do
- it_behaves_like(:env_length, :size)
+ it_behaves_like :env_length, :size
end
diff --git a/spec/ruby/core/env/slice_spec.rb b/spec/ruby/core/env/slice_spec.rb
new file mode 100644
index 0000000000..1ac8a303f8
--- /dev/null
+++ b/spec/ruby/core/env/slice_spec.rb
@@ -0,0 +1,29 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "2.6" do
+ describe "ENV.slice" do
+ before :each do
+ @saved_foo = ENV["foo"]
+ @saved_bar = ENV["bar"]
+ ENV["foo"] = "0"
+ ENV["bar"] = "1"
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ ENV["bar"] = @saved_bar
+ end
+
+ it "returns a hash of the given environment variable names and their values" do
+ ENV.slice("foo", "bar").should == {"foo" => "0", "bar" => "1"}
+ end
+
+ it "ignores each String that is not an environment variable name" do
+ ENV.slice("foo", "boo", "bar").should == {"foo" => "0", "bar" => "1"}
+ end
+
+ it "raises TypeError if any argument is not a String and does not respond to #to_str" do
+ -> { ENV.slice(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
+ end
+end
diff --git a/spec/ruby/core/env/spec_helper.rb b/spec/ruby/core/env/spec_helper.rb
new file mode 100644
index 0000000000..470ffa58bc
--- /dev/null
+++ b/spec/ruby/core/env/spec_helper.rb
@@ -0,0 +1,26 @@
+require_relative '../../spec_helper'
+
+locale_env_matcher = Class.new do
+ def initialize(name = 'locale')
+ encoding = Encoding.find(name)
+ @encodings = (encoding = Encoding::US_ASCII) ?
+ [encoding, Encoding::ASCII_8BIT] : [encoding]
+ end
+
+ def matches?(actual)
+ @actual = actual = actual.encoding
+ @encodings.include?(actual)
+ end
+
+ def failure_message
+ ["Expected #{@actual} to be #{@encodings.join(' or ')}"]
+ end
+
+ def negative_failure_message
+ ["Expected #{@actual} not to be #{@encodings.join(' or ')}"]
+ end
+end
+
+String.__send__(:define_method, :be_locale_env) do |expected = 'locale'|
+ locale_env_matcher.new(expected)
+end
diff --git a/spec/ruby/core/env/store_spec.rb b/spec/ruby/core/env/store_spec.rb
index 1ee5ce020e..b4700e0a96 100644
--- a/spec/ruby/core/env/store_spec.rb
+++ b/spec/ruby/core/env/store_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/store.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/store'
describe "ENV.store" do
- it_behaves_like(:env_store, :store)
+ it_behaves_like :env_store, :store
end
diff --git a/spec/ruby/core/env/to_a_spec.rb b/spec/ruby/core/env/to_a_spec.rb
index ffb66b8767..39e3877b48 100644
--- a/spec/ruby/core/env/to_a_spec.rb
+++ b/spec/ruby/core/env/to_a_spec.rb
@@ -1,19 +1,18 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative 'spec_helper'
describe "ENV.to_a" do
it "returns the ENV as an array" do
- ENV["foo"] = "bar"
a = ENV.to_a
a.is_a?(Array).should == true
- a.find { |e| e.first == "foo" }.should == ["foo", "bar"]
- ENV.delete "foo"
+ a.size.should == ENV.size
+ ENV.each_pair { |k, v| a.should include([k, v])}
end
it "returns the entries in the locale encoding" do
ENV.to_a.each do |key, value|
- key.encoding.should == Encoding.find('locale')
- value.encoding.should == Encoding.find('locale')
+ key.should.be_locale_env
+ value.should.be_locale_env
end
end
end
diff --git a/spec/ruby/core/env/to_h_spec.rb b/spec/ruby/core/env/to_h_spec.rb
index d0fef5382b..65cdb59951 100644
--- a/spec/ruby/core/env/to_h_spec.rb
+++ b/spec/ruby/core/env/to_h_spec.rb
@@ -1,6 +1,60 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/to_hash.rb', __FILE__)
+require_relative 'spec_helper'
+require_relative 'shared/to_hash'
-describe "ENV.to_hash" do
- it_behaves_like(:env_to_hash, :to_h)
+describe "ENV.to_h" do
+ it_behaves_like :env_to_hash, :to_h
+
+ ruby_version_is "2.6" do
+ context "with block" do
+ before do
+ @orig_hash = ENV.to_hash
+ end
+
+ after do
+ ENV.replace @orig_hash
+ end
+
+ it "converts [key, value] pairs returned by the block to a hash" do
+ ENV.replace("a" => "b", "c" => "d")
+ ENV.to_h { |k, v| [k, v.upcase] }.should == { 'a' => "B", 'c' => "D" }
+ end
+
+ it "does not require the array elements to be strings" do
+ ENV.replace("a" => "b", "c" => "d")
+ ENV.to_h { |k, v| [k.to_sym, v.to_sym] }.should == { :a => :b, :c => :d }
+ end
+
+ it "raises ArgumentError if block returns longer or shorter array" do
+ -> do
+ ENV.to_h { |k, v| [k, v.upcase, 1] }
+ end.should raise_error(ArgumentError, /element has wrong array length/)
+
+ -> do
+ ENV.to_h { |k, v| [k] }
+ end.should raise_error(ArgumentError, /element has wrong array length/)
+ end
+
+ it "raises TypeError if block returns something other than Array" do
+ -> do
+ ENV.to_h { |k, v| "not-array" }
+ end.should raise_error(TypeError, /wrong element type String/)
+ end
+
+ it "coerces returned pair to Array with #to_ary" do
+ x = mock('x')
+ x.stub!(:to_ary).and_return([:b, 'b'])
+
+ ENV.to_h { |k| x }.should == { :b => 'b' }
+ end
+
+ it "does not coerce returned pair to Array with #to_a" do
+ x = mock('x')
+ x.stub!(:to_a).and_return([:b, 'b'])
+
+ -> do
+ ENV.to_h { |k| x }
+ end.should raise_error(TypeError, /wrong element type MockObject/)
+ end
+ end
+ end
end
diff --git a/spec/ruby/core/env/to_hash_spec.rb b/spec/ruby/core/env/to_hash_spec.rb
index 3362fa9307..306572c353 100644
--- a/spec/ruby/core/env/to_hash_spec.rb
+++ b/spec/ruby/core/env/to_hash_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/to_hash.rb', __FILE__)
+require_relative 'spec_helper'
+require_relative 'shared/to_hash'
describe "ENV.to_hash" do
- it_behaves_like(:env_to_hash, :to_hash)
+ it_behaves_like :env_to_hash, :to_hash
end
diff --git a/spec/ruby/core/env/to_s_spec.rb b/spec/ruby/core/env/to_s_spec.rb
index 10aca09723..0bd92cf217 100644
--- a/spec/ruby/core/env/to_s_spec.rb
+++ b/spec/ruby/core/env/to_s_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.to_s" do
it "returns \"ENV\"" do
diff --git a/spec/ruby/core/env/update_spec.rb b/spec/ruby/core/env/update_spec.rb
index 7ebfbb313d..95a8a2eb49 100644
--- a/spec/ruby/core/env/update_spec.rb
+++ b/spec/ruby/core/env/update_spec.rb
@@ -1,25 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/update'
describe "ENV.update" do
-
- it "adds the parameter hash to ENV" do
- ENV["foo"].should == nil
- ENV.update "foo" => "bar"
- ENV["foo"].should == "bar"
- ENV.delete "foo"
- end
-
- it "yields key, the old value and the new value when replacing entries" do
- ENV.update "foo" => "bar"
- ENV["foo"].should == "bar"
- ENV.update("foo" => "boo") do |key, old, new|
- key.should == "foo"
- old.should == "bar"
- new.should == "boo"
- "rab"
- end
- ENV["foo"].should == "rab"
- ENV.delete "foo"
- end
-
+ it_behaves_like :env_update, :update
end
diff --git a/spec/ruby/core/env/value_spec.rb b/spec/ruby/core/env/value_spec.rb
index c7eb7c5376..906e86ab39 100644
--- a/spec/ruby/core/env/value_spec.rb
+++ b/spec/ruby/core/env/value_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/value.rb', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/value'
describe "ENV.value?" do
- it_behaves_like(:env_value, :value?)
+ it_behaves_like :env_value, :value?
end
diff --git a/spec/ruby/core/env/values_at_spec.rb b/spec/ruby/core/env/values_at_spec.rb
index efc7de2a05..87c8c7f663 100644
--- a/spec/ruby/core/env/values_at_spec.rb
+++ b/spec/ruby/core/env/values_at_spec.rb
@@ -1,17 +1,38 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "ENV.values_at" do
+ before :each do
+ @saved_foo = ENV["foo"]
+ @saved_bar = ENV["bar"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ ENV["bar"] = @saved_bar
+ end
- it "returns an array of the values referenced by the parameters as keys" do
+ it "returns an array of the values corresponding to the given keys" do
ENV["foo"] = "oof"
ENV["bar"] = "rab"
- ENV.values_at.should == []
ENV.values_at("bar", "foo").should == ["rab", "oof"]
- ENV.delete "foo"
- ENV.delete "bar"
+ end
+
+ it "returns an empty array if no keys specified" do
+ ENV.values_at.should == []
+ end
+
+ it "returns nil for each key that is not a name" do
+ ENV["foo"] = "oof"
+ ENV["bar"] = "rab"
+ ENV.values_at("x", "bar", "y", "foo", "z").should == [nil, "rab", nil, "oof", nil]
end
it "uses the locale encoding" do
- ENV.values_at(ENV.keys.first).first.encoding.should == Encoding.find('locale')
+ encoding = platform_is(:windows) ? Encoding::UTF_8 : Encoding.find('locale')
+ ENV.values_at(ENV.keys.first).first.encoding.should == encoding
+ end
+
+ it "raises TypeError when a key is not coercible to String" do
+ -> { ENV.values_at("foo", Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
end
diff --git a/spec/ruby/core/env/values_spec.rb b/spec/ruby/core/env/values_spec.rb
index 3a620bdb8b..71bc877d31 100644
--- a/spec/ruby/core/env/values_spec.rb
+++ b/spec/ruby/core/env/values_spec.rb
@@ -1,21 +1,14 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative 'spec_helper'
describe "ENV.values" do
it "returns an array of the values" do
- orig = ENV.to_hash
- begin
- ENV.replace "a" => "b", "c" => "d"
- a = ENV.values
- a.sort.should == ["b", "d"]
- ensure
- ENV.replace orig
- end
+ ENV.values.should == ENV.to_hash.values
end
it "uses the locale encoding" do
ENV.values.each do |value|
- value.encoding.should == Encoding.find('locale')
+ value.should.be_locale_env
end
end
end
diff --git a/spec/ruby/core/exception/args_spec.rb b/spec/ruby/core/exception/args_spec.rb
deleted file mode 100644
index 410e21edfb..0000000000
--- a/spec/ruby/core/exception/args_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "NoMethodError#args" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/arguments_spec.rb b/spec/ruby/core/exception/arguments_spec.rb
deleted file mode 100644
index 47c4339e2d..0000000000
--- a/spec/ruby/core/exception/arguments_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "ArgumentError" do
- it "is a subclass of StandardError" do
- StandardError.should be_ancestor_of(ArgumentError)
- end
-
- it "gives its own class name as message if it has no message" do
- ArgumentError.new.message.should == "ArgumentError"
- end
-end
diff --git a/spec/ruby/core/exception/backtrace_locations_spec.rb b/spec/ruby/core/exception/backtrace_locations_spec.rb
new file mode 100644
index 0000000000..86eb9d3413
--- /dev/null
+++ b/spec/ruby/core/exception/backtrace_locations_spec.rb
@@ -0,0 +1,39 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+
+describe "Exception#backtrace_locations" do
+ before :each do
+ @backtrace = ExceptionSpecs::Backtrace.backtrace_locations
+ end
+
+ it "returns nil if no backtrace was set" do
+ Exception.new.backtrace_locations.should be_nil
+ end
+
+ it "returns an Array" do
+ @backtrace.should be_an_instance_of(Array)
+ end
+
+ it "sets each element to a Thread::Backtrace::Location" do
+ @backtrace.each {|l| l.should be_an_instance_of(Thread::Backtrace::Location)}
+ end
+
+ it "produces a backtrace for an exception captured using $!" do
+ exception = begin
+ raise
+ rescue RuntimeError
+ $!
+ end
+
+ exception.backtrace_locations.first.path.should =~ /backtrace_locations_spec/
+ end
+
+ it "returns an Array that can be updated" do
+ begin
+ raise
+ rescue RuntimeError => e
+ e.backtrace_locations.unshift "backtrace first"
+ e.backtrace_locations[0].should == "backtrace first"
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/backtrace_spec.rb b/spec/ruby/core/exception/backtrace_spec.rb
index 2d115e9b2f..3f74c4cefe 100644
--- a/spec/ruby/core/exception/backtrace_spec.rb
+++ b/spec/ruby/core/exception/backtrace_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Exception#backtrace" do
before :each do
@@ -43,11 +43,11 @@ describe "Exception#backtrace" do
# This regexp is deliberately imprecise to account for the need to abstract out
# the paths of the included mspec files and the desire to avoid specifying in any
# detail what the in `...' portion looks like.
- line.should =~ /^[^ ]+\:\d+(:in `[^`]+')?$/
+ line.should =~ /^.+:\d+:in `[^`]+'$/
end
end
- it "produces a backtrace for an exception captured using $!" do
+ it "captures the backtrace for an exception into $!" do
exception = begin
raise
rescue RuntimeError
@@ -57,6 +57,16 @@ describe "Exception#backtrace" do
exception.backtrace.first.should =~ /backtrace_spec/
end
+ it "captures the backtrace for an exception into $@" do
+ backtrace = begin
+ raise
+ rescue RuntimeError
+ $@
+ end
+
+ backtrace.first.should =~ /backtrace_spec/
+ end
+
it "returns an Array that can be updated" do
begin
raise
@@ -65,4 +75,19 @@ describe "Exception#backtrace" do
e.backtrace[0].should == "backtrace first"
end
end
+
+ it "returns the same array after duping" do
+ begin
+ raise
+ rescue RuntimeError => err
+ bt = err.backtrace
+ err.dup.backtrace.should equal(bt)
+
+ new_bt = ['hi']
+ err.set_backtrace new_bt
+
+ err.backtrace.should == new_bt
+ err.dup.backtrace.should equal(new_bt)
+ end
+ end
end
diff --git a/spec/ruby/core/exception/case_compare_spec.rb b/spec/ruby/core/exception/case_compare_spec.rb
index 7592564855..87b9dee3ca 100644
--- a/spec/ruby/core/exception/case_compare_spec.rb
+++ b/spec/ruby/core/exception/case_compare_spec.rb
@@ -1,5 +1,39 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "SystemCallError.===" do
- it "needs to be reviewed for spec completeness"
+ before :all do
+ @example_errno_class = Errno::EINVAL
+ @example_errno = @example_errno_class::Errno
+ end
+
+ it "returns true for an instance of the same class" do
+ Errno::EINVAL.should === Errno::EINVAL.new
+ end
+
+ it "returns true if errnos same" do
+ e = SystemCallError.new('foo', @example_errno)
+ @example_errno_class.===(e).should == true
+ end
+
+ it "returns false if errnos different" do
+ e = SystemCallError.new('foo', @example_errno + 1)
+ @example_errno_class.===(e).should == false
+ end
+
+ it "returns false if arg is not kind of SystemCallError" do
+ e = Object.new
+ @example_errno_class.===(e).should == false
+ end
+
+ it "returns true if receiver is generic and arg is kind of SystemCallError" do
+ unknown_error_number = Errno.constants.size
+ e = SystemCallError.new('foo', @example_errno)
+ SystemCallError.===(e).should == true
+ end
+
+ it "returns false if receiver is generic and arg is not kind of SystemCallError" do
+ unknown_error_number = Errno.constants.size
+ e = Object.new
+ SystemCallError.===(e).should == false
+ end
end
diff --git a/spec/ruby/core/exception/cause_spec.rb b/spec/ruby/core/exception/cause_spec.rb
index a1aa39ae34..cf4aaeb188 100644
--- a/spec/ruby/core/exception/cause_spec.rb
+++ b/spec/ruby/core/exception/cause_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "Exception#cause" do
it "returns the active exception when an exception is raised" do
@@ -16,4 +16,41 @@ describe "Exception#cause" do
end
end
end
+
+ it "is set for user errors caused by internal errors" do
+ -> {
+ begin
+ 1 / 0
+ rescue
+ raise "foo"
+ end
+ }.should raise_error(RuntimeError) { |e|
+ e.cause.should be_kind_of(ZeroDivisionError)
+ }
+ end
+
+ it "is set for internal errors caused by user errors" do
+ cause = RuntimeError.new "cause"
+ -> {
+ begin
+ raise cause
+ rescue
+ 1 / 0
+ end
+ }.should raise_error(ZeroDivisionError) { |e|
+ e.cause.should equal(cause)
+ }
+ end
+
+ it "is not set to the exception itself when it is re-raised" do
+ -> {
+ begin
+ raise RuntimeError
+ rescue RuntimeError => e
+ raise e
+ end
+ }.should raise_error(RuntimeError) { |e|
+ e.cause.should == nil
+ }
+ end
end
diff --git a/spec/ruby/core/exception/destination_encoding_name_spec.rb b/spec/ruby/core/exception/destination_encoding_name_spec.rb
deleted file mode 100644
index d6a01c3220..0000000000
--- a/spec/ruby/core/exception/destination_encoding_name_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::UndefinedConversionError#destination_encoding_name" do
- it "needs to be reviewed for spec completeness"
-end
-
-describe "Encoding::InvalidByteSequenceError#destination_encoding_name" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/destination_encoding_spec.rb b/spec/ruby/core/exception/destination_encoding_spec.rb
deleted file mode 100644
index 09064a01f3..0000000000
--- a/spec/ruby/core/exception/destination_encoding_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::UndefinedConversionError#destination_encoding" do
- it "needs to be reviewed for spec completeness"
-end
-
-describe "Encoding::InvalidByteSequenceError#destination_encoding" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/dup_spec.rb b/spec/ruby/core/exception/dup_spec.rb
new file mode 100644
index 0000000000..edd54bfb37
--- /dev/null
+++ b/spec/ruby/core/exception/dup_spec.rb
@@ -0,0 +1,74 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+
+describe "Exception#dup" do
+ before :each do
+ @obj = ExceptionSpecs::InitializeException.new("my exception")
+ end
+
+ it "calls #initialize_copy on the new instance" do
+ dup = @obj.dup
+ ScratchPad.recorded.should_not == @obj.object_id
+ ScratchPad.recorded.should == dup.object_id
+ end
+
+ it "copies instance variables" do
+ dup = @obj.dup
+ dup.ivar.should == 1
+ end
+
+ it "does not copy singleton methods" do
+ def @obj.special() :the_one end
+ dup = @obj.dup
+ -> { dup.special }.should raise_error(NameError)
+ end
+
+ it "does not copy modules included in the singleton class" do
+ class << @obj
+ include ExceptionSpecs::ExceptionModule
+ end
+
+ dup = @obj.dup
+ -> { dup.repr }.should raise_error(NameError)
+ end
+
+ it "does not copy constants defined in the singleton class" do
+ class << @obj
+ CLONE = :clone
+ end
+
+ dup = @obj.dup
+ -> { class << dup; CLONE; end }.should raise_error(NameError)
+ end
+
+ it "does copy the message" do
+ @obj.dup.message.should == @obj.message
+ end
+
+ it "does copy the backtrace" do
+ begin
+ # Explicitly raise so a backtrace is associated with the exception.
+ # It's tempting to call `set_backtrace` instead, but that complicates
+ # the test because it might affect other state (e.g., instance variables)
+ # on some implementations.
+ raise ExceptionSpecs::InitializeException.new("my exception")
+ rescue => e
+ @obj = e
+ end
+
+ @obj.dup.backtrace.should == @obj.backtrace
+ end
+
+ it "does copy the cause" do
+ begin
+ raise StandardError, "the cause"
+ rescue StandardError => cause
+ begin
+ raise RuntimeError, "the consequence"
+ rescue RuntimeError => e
+ e.cause.should equal(cause)
+ e.dup.cause.should equal(cause)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/equal_value_spec.rb b/spec/ruby/core/exception/equal_value_spec.rb
index 3aad809377..7f2065511a 100644
--- a/spec/ruby/core/exception/equal_value_spec.rb
+++ b/spec/ruby/core/exception/equal_value_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Exception#==" do
it "returns true if both exceptions are the same object" do
diff --git a/spec/ruby/core/exception/errno_spec.rb b/spec/ruby/core/exception/errno_spec.rb
index f7f5b45d8a..095a926e09 100644
--- a/spec/ruby/core/exception/errno_spec.rb
+++ b/spec/ruby/core/exception/errno_spec.rb
@@ -1,9 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-
-describe "SystemCallError#errno" do
- it "needs to be reviewed for spec completeness"
-end
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Errno::EINVAL.new" do
it "can be called with no arguments" do
@@ -46,3 +42,17 @@ describe "Errno::EAGAIN" do
end
end
end
+
+describe "Errno::ENOTSUP" do
+ it "is defined" do
+ Errno.should have_constant(:ENOTSUP)
+ end
+
+ it "is the same class as Errno::EOPNOTSUPP if they represent the same errno value" do
+ if Errno::ENOTSUP::Errno == Errno::EOPNOTSUPP::Errno
+ Errno::ENOTSUP.should == Errno::EOPNOTSUPP
+ else
+ Errno::ENOTSUP.should_not == Errno::EOPNOTSUPP
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/error_bytes_spec.rb b/spec/ruby/core/exception/error_bytes_spec.rb
deleted file mode 100644
index e5027d0cf3..0000000000
--- a/spec/ruby/core/exception/error_bytes_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::InvalidByteSequenceError#error_bytes" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/error_char_spec.rb b/spec/ruby/core/exception/error_char_spec.rb
deleted file mode 100644
index 8842424e90..0000000000
--- a/spec/ruby/core/exception/error_char_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::UndefinedConversionError#error_char" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/exception_spec.rb b/spec/ruby/core/exception/exception_spec.rb
index afa482b9d7..d6f5283bd9 100644
--- a/spec/ruby/core/exception/exception_spec.rb
+++ b/spec/ruby/core/exception/exception_spec.rb
@@ -1,51 +1,9 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/new', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/new'
describe "Exception.exception" do
- it_behaves_like(:exception_new, :exception)
-end
-
-describe "Exception" do
- it "is a Class" do
- Exception.should be_kind_of(Class)
- end
-
- it "is a superclass of NoMemoryError" do
- Exception.should be_ancestor_of(NoMemoryError)
- end
-
- it "is a superclass of ScriptError" do
- Exception.should be_ancestor_of(ScriptError)
- end
-
- it "is a superclass of SignalException" do
- Exception.should be_ancestor_of(SignalException)
- end
-
- it "is a superclass of Interrupt" do
- SignalException.should be_ancestor_of(Interrupt)
- end
-
- it "is a superclass of StandardError" do
- Exception.should be_ancestor_of(StandardError)
- end
-
- it "is a superclass of SystemExit" do
- Exception.should be_ancestor_of(SystemExit)
- end
-
- it "is a superclass of SystemStackError" do
- Exception.should be_ancestor_of(SystemStackError)
- end
-
- it "is a superclass of SecurityError" do
- Exception.should be_ancestor_of(SecurityError)
- end
-
- it "is a superclass of EncodingError" do
- Exception.should be_ancestor_of(EncodingError)
- end
+ it_behaves_like :exception_new, :exception
end
describe "Exception#exception" do
@@ -66,6 +24,34 @@ describe "Exception#exception" do
e2.message.should == "message"
end
+ it "when raised will be rescued as the new exception" do
+ begin
+ begin
+ raised_first = StandardError.new('first')
+ raise raised_first
+ rescue => caught_first
+ raised_second = raised_first.exception('second')
+ raise raised_second
+ end
+ rescue => caught_second
+ end
+
+ raised_first.should == caught_first
+ raised_second.should == caught_second
+ end
+
+ it "captures an exception into $!" do
+ exception = begin
+ raise
+ rescue RuntimeError
+ $!
+ end
+
+ exception.class.should == RuntimeError
+ exception.message.should == ""
+ exception.backtrace.first.should =~ /exception_spec/
+ end
+
class CustomArgumentError < StandardError
attr_reader :val
def initialize(val)
diff --git a/spec/ruby/core/exception/exit_value_spec.rb b/spec/ruby/core/exception/exit_value_spec.rb
index daa5eb0b94..99987dd1bc 100644
--- a/spec/ruby/core/exception/exit_value_spec.rb
+++ b/spec/ruby/core/exception/exit_value_spec.rb
@@ -1,5 +1,13 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "LocalJumpError#exit_value" do
- it "needs to be reviewed for spec completeness"
+ def get_me_a_return
+ Proc.new { return 42 }
+ end
+
+ it "returns the value given to return" do
+ -> { get_me_a_return.call }.should raise_error(LocalJumpError) { |e|
+ e.exit_value.should == 42
+ }
+ end
end
diff --git a/spec/ruby/core/exception/fixtures/common.rb b/spec/ruby/core/exception/fixtures/common.rb
index 51dd0bf9ed..0ffb3ed855 100644
--- a/spec/ruby/core/exception/fixtures/common.rb
+++ b/spec/ruby/core/exception/fixtures/common.rb
@@ -4,11 +4,19 @@ module ExceptionSpecs
class Backtrace
def self.backtrace
begin
- raise # Do not move this line or update backtrace_spec.rb
+ raise # If you move this line, update backtrace_spec.rb
rescue RuntimeError => e
e.backtrace
end
end
+
+ def self.backtrace_locations
+ begin
+ raise
+ rescue RuntimeError => e
+ e.backtrace_locations
+ end
+ end
end
class UnExceptional < Exception
@@ -38,6 +46,26 @@ module ExceptionSpecs
""
end
end
+
+ class InitializeException < StandardError
+ attr_reader :ivar
+
+ def initialize(message = nil)
+ super
+ @ivar = 1
+ end
+
+ def initialize_copy(other)
+ super
+ ScratchPad.record object_id
+ end
+ end
+
+ module ExceptionModule
+ def repr
+ 1
+ end
+ end
end
module NoMethodErrorSpecs
@@ -53,6 +81,9 @@ module NoMethodErrorSpecs
end
class NoMethodErrorD; end
+
+ class InstanceException < Exception
+ end
end
class NameErrorSpecs
diff --git a/spec/ruby/core/exception/frozen_error_spec.rb b/spec/ruby/core/exception/frozen_error_spec.rb
new file mode 100644
index 0000000000..f27b33295c
--- /dev/null
+++ b/spec/ruby/core/exception/frozen_error_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../spec_helper'
+
+describe "FrozenError.new" do
+ ruby_version_is "2.7" do
+ it "should take optional receiver argument" do
+ o = Object.new
+ FrozenError.new("msg", receiver: o).receiver.should equal(o)
+ end
+ end
+end
+
+describe "FrozenError#receiver" do
+ ruby_version_is "2.7" do
+ it "should return frozen object that modification was attempted on" do
+ o = Object.new.freeze
+ begin
+ def o.x; end
+ rescue => e
+ e.should be_kind_of(FrozenError)
+ e.receiver.should equal(o)
+ else
+ raise
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/full_message_spec.rb b/spec/ruby/core/exception/full_message_spec.rb
new file mode 100644
index 0000000000..9cac9fb037
--- /dev/null
+++ b/spec/ruby/core/exception/full_message_spec.rb
@@ -0,0 +1,92 @@
+require_relative '../../spec_helper'
+
+describe "Exception#full_message" do
+ it "returns formatted string of exception using the same format that is used to print an uncaught exceptions to stderr" do
+ e = RuntimeError.new("Some runtime error")
+ e.set_backtrace(["a.rb:1", "b.rb:2"])
+
+ full_message = e.full_message
+ full_message.should include "RuntimeError"
+ full_message.should include "Some runtime error"
+ full_message.should include "a.rb:1"
+ full_message.should include "b.rb:2"
+ end
+
+ ruby_version_is "2.5.1" do
+ it "supports :highlight option and adds escape sequences to highlight some strings" do
+ e = RuntimeError.new("Some runtime error")
+
+ full_message = e.full_message(highlight: true, order: :bottom)
+ full_message.should include "\e[1mTraceback\e[m (most recent call last)"
+ full_message.should include "\e[1mSome runtime error (\e[1;4mRuntimeError\e[m\e[1m)"
+
+ full_message = e.full_message(highlight: false, order: :bottom)
+ full_message.should include "Traceback (most recent call last)"
+ full_message.should include "Some runtime error (RuntimeError)"
+ end
+
+ it "supports :order option and places the error message and the backtrace at the top or the bottom" do
+ e = RuntimeError.new("Some runtime error")
+ e.set_backtrace(["a.rb:1", "b.rb:2"])
+
+ e.full_message(order: :top, highlight: false).should =~ /a.rb:1.*b.rb:2/m
+ e.full_message(order: :bottom, highlight: false).should =~ /b.rb:2.*a.rb:1/m
+ end
+
+ it "shows the caller if the exception has no backtrace" do
+ e = RuntimeError.new("Some runtime error")
+ e.backtrace.should == nil
+ full_message = e.full_message(highlight: false, order: :top)
+ full_message.should include("#{__FILE__}:#{__LINE__-1}:in `")
+ full_message.should include("': Some runtime error (RuntimeError)\n")
+ end
+
+ it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do
+ begin
+ line = __LINE__; raise "first line\nsecond line"
+ rescue => e
+ full_message = e.full_message(highlight: false, order: :top).lines
+ full_message[0].should include("#{__FILE__}:#{line}:in `")
+ full_message[0].should include(": first line (RuntimeError)\n")
+ full_message[1].should == "second line\n"
+ end
+ end
+ end
+
+ ruby_version_is "2.6" do
+ it "contains cause of exception" do
+ begin
+ begin
+ raise 'the cause'
+ rescue
+ raise 'main exception'
+ end
+ rescue => e
+ exception = e
+ end
+
+ exception.full_message.should include "main exception"
+ exception.full_message.should include "the cause"
+ end
+
+ it 'contains all the chain of exceptions' do
+ begin
+ begin
+ begin
+ raise 'origin exception'
+ rescue
+ raise 'intermediate exception'
+ end
+ rescue
+ raise 'last exception'
+ end
+ rescue => e
+ exception = e
+ end
+
+ exception.full_message.should include "last exception"
+ exception.full_message.should include "intermediate exception"
+ exception.full_message.should include "origin exception"
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/hierarchy_spec.rb b/spec/ruby/core/exception/hierarchy_spec.rb
new file mode 100644
index 0000000000..6514eb1994
--- /dev/null
+++ b/spec/ruby/core/exception/hierarchy_spec.rb
@@ -0,0 +1,62 @@
+require_relative '../../spec_helper'
+
+describe "Exception" do
+ it "has the right class hierarchy" do
+ hierarchy = {
+ Exception => {
+ NoMemoryError => nil,
+ ScriptError => {
+ LoadError => nil,
+ NotImplementedError => nil,
+ SyntaxError => nil,
+ },
+ SecurityError => nil,
+ SignalException => {
+ Interrupt => nil,
+ },
+ StandardError => {
+ ArgumentError => {
+ UncaughtThrowError => nil,
+ },
+ EncodingError => nil,
+ FiberError => nil,
+ IOError => {
+ EOFError => nil,
+ },
+ IndexError => {
+ KeyError => nil,
+ StopIteration => {
+ ClosedQueueError => nil,
+ },
+ },
+ LocalJumpError => nil,
+ NameError => {
+ NoMethodError => nil,
+ },
+ RangeError => {
+ FloatDomainError => nil,
+ },
+ RegexpError => nil,
+ RuntimeError => {
+ FrozenError => nil,
+ },
+ SystemCallError => nil,
+ ThreadError => nil,
+ TypeError => nil,
+ ZeroDivisionError => nil,
+ },
+ SystemExit => nil,
+ SystemStackError => nil,
+ },
+ }
+
+ traverse = -> parent_class, parent_subclass_hash {
+ parent_subclass_hash.each do |child_class, child_subclass_hash|
+ child_class.class.should == Class
+ child_class.superclass.should == parent_class
+ traverse.call(child_class, child_subclass_hash) if child_subclass_hash
+ end
+ }
+ traverse.call(Object, hierarchy)
+ end
+end
diff --git a/spec/ruby/core/exception/incomplete_input_spec.rb b/spec/ruby/core/exception/incomplete_input_spec.rb
deleted file mode 100644
index a64d4be3f3..0000000000
--- a/spec/ruby/core/exception/incomplete_input_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::InvalidByteSequenceError#incomplete_input?" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/initialize_spec.rb b/spec/ruby/core/exception/initialize_spec.rb
deleted file mode 100644
index 14fb93ef07..0000000000
--- a/spec/ruby/core/exception/initialize_spec.rb
+++ /dev/null
@@ -1 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
diff --git a/spec/ruby/core/exception/inspect_spec.rb b/spec/ruby/core/exception/inspect_spec.rb
index 5b06ffee71..6f380a36c7 100644
--- a/spec/ruby/core/exception/inspect_spec.rb
+++ b/spec/ruby/core/exception/inspect_spec.rb
@@ -1,11 +1,15 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Exception#inspect" do
it "returns '#<Exception: Exception>' when no message given" do
Exception.new.inspect.should == "#<Exception: Exception>"
end
+ it "keeps message encoding" do
+ Exception.new('å').inspect.should == "#<Exception: å>"
+ end
+
it "includes #to_s when the result is non-empty" do
ExceptionSpecs::OverrideToS.new.inspect.should == "#<ExceptionSpecs::OverrideToS: this is from #to_s>"
end
diff --git a/spec/ruby/core/exception/interrupt_spec.rb b/spec/ruby/core/exception/interrupt_spec.rb
index ef24743936..14f294bec6 100644
--- a/spec/ruby/core/exception/interrupt_spec.rb
+++ b/spec/ruby/core/exception/interrupt_spec.rb
@@ -1,10 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Interrupt" do
- it "is a subclass of SignalException" do
- Interrupt.superclass.should == SignalException
- end
-end
+require_relative '../../spec_helper'
describe "Interrupt.new" do
it "returns an instance of interrupt with no message given" do
@@ -20,7 +14,7 @@ describe "Interrupt.new" do
end
end
-describe "rescueing Interrupt" do
+describe "rescuing Interrupt" do
before do
@original_sigint_proc = Signal.trap(:INT, :SIG_DFL)
end
diff --git a/spec/ruby/core/exception/io_error_spec.rb b/spec/ruby/core/exception/io_error_spec.rb
index 0971be332f..ab8a72518f 100644
--- a/spec/ruby/core/exception/io_error_spec.rb
+++ b/spec/ruby/core/exception/io_error_spec.rb
@@ -1,10 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "IOError" do
- it "is a superclass of EOFError" do
- IOError.should be_ancestor_of(EOFError)
- end
-end
+require_relative '../../spec_helper'
describe "IO::EAGAINWaitReadable" do
it "combines Errno::EAGAIN and IO::WaitReadable" do
diff --git a/spec/ruby/core/exception/key_error_spec.rb b/spec/ruby/core/exception/key_error_spec.rb
new file mode 100644
index 0000000000..71bf2b46ff
--- /dev/null
+++ b/spec/ruby/core/exception/key_error_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../spec_helper'
+
+describe "KeyError" do
+ ruby_version_is "2.6" do
+ it "accepts :receiver and :key options" do
+ receiver = mock("receiver")
+ key = mock("key")
+
+ error = KeyError.new(receiver: receiver, key: key)
+
+ error.receiver.should == receiver
+ error.key.should == key
+
+ error = KeyError.new("message", receiver: receiver, key: key)
+
+ error.message.should == "message"
+ error.receiver.should == receiver
+ error.key.should == key
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/load_error_spec.rb b/spec/ruby/core/exception/load_error_spec.rb
index 2999c66117..0056403e58 100644
--- a/spec/ruby/core/exception/load_error_spec.rb
+++ b/spec/ruby/core/exception/load_error_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "LoadError#path" do
before :each do
diff --git a/spec/ruby/core/exception/message_spec.rb b/spec/ruby/core/exception/message_spec.rb
index 7eee6d99de..8d7476126e 100644
--- a/spec/ruby/core/exception/message_spec.rb
+++ b/spec/ruby/core/exception/message_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Exception#message" do
it "returns the class name if there is no message" do
diff --git a/spec/ruby/core/exception/name_error_spec.rb b/spec/ruby/core/exception/name_error_spec.rb
index e5b19d6219..e901a80c42 100644
--- a/spec/ruby/core/exception/name_error_spec.rb
+++ b/spec/ruby/core/exception/name_error_spec.rb
@@ -1,13 +1,30 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "NameError" do
- it "is a superclass of NoMethodError" do
- NameError.should be_ancestor_of(NoMethodError)
- end
-end
+require_relative '../../spec_helper'
describe "NameError.new" do
it "should take optional name argument" do
NameError.new("msg","name").name.should == "name"
end
+
+ ruby_version_is "2.6" do
+ it "accepts a :receiver keyword argument" do
+ receiver = mock("receiver")
+
+ error = NameError.new("msg", :name, receiver: receiver)
+
+ error.receiver.should == receiver
+ error.name.should == :name
+ end
+ end
+end
+
+describe "NameError#dup" do
+ it "copies the name and receiver" do
+ begin
+ foo
+ rescue NameError => ne
+ name_error_dup = ne.dup
+ name_error_dup.name.should == :foo
+ name_error_dup.receiver.should == self
+ end
+ end
end
diff --git a/spec/ruby/core/exception/name_spec.rb b/spec/ruby/core/exception/name_spec.rb
index e8a3c011d2..c8a49b40e2 100644
--- a/spec/ruby/core/exception/name_spec.rb
+++ b/spec/ruby/core/exception/name_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "NameError#name" do
it "returns a method name as a symbol" do
@@ -21,41 +21,23 @@ describe "NameError#name" do
it "returns a class variable name as a symbol" do
-> {
- -> {
- @@doesnt_exist
- }.should complain(/class variable access from toplevel/)
+ eval("class singleton_class::A; @@doesnt_exist end", binding, __FILE__, __LINE__)
}.should raise_error(NameError) { |e| e.name.should == :@@doesnt_exist }
end
- ruby_version_is ""..."2.3" do
- it "always returns a symbol when a NameError is raised from #instance_variable_get" do
- -> {
- Object.new.instance_variable_get("invalid_ivar_name")
- }.should raise_error(NameError) { |e| e.name.should == :invalid_ivar_name }
- end
-
- it "always returns a symbol when a NameError is raised from #class_variable_get" do
- -> {
- Object.class_variable_get("invalid_cvar_name")
- }.should raise_error(NameError) { |e| e.name.should == :invalid_cvar_name }
- end
- end
-
- ruby_version_is "2.3" do
- it "returns the first argument passed to the method when a NameError is raised from #instance_variable_get" do
- invalid_ivar_name = "invalid_ivar_name"
+ it "returns the first argument passed to the method when a NameError is raised from #instance_variable_get" do
+ invalid_ivar_name = "invalid_ivar_name"
- -> {
- Object.new.instance_variable_get(invalid_ivar_name)
- }.should raise_error(NameError) {|e| e.name.should equal(invalid_ivar_name) }
- end
+ -> {
+ Object.new.instance_variable_get(invalid_ivar_name)
+ }.should raise_error(NameError) {|e| e.name.should equal(invalid_ivar_name) }
+ end
- it "returns the first argument passed to the method when a NameError is raised from #class_variable_get" do
- invalid_cvar_name = "invalid_cvar_name"
+ it "returns the first argument passed to the method when a NameError is raised from #class_variable_get" do
+ invalid_cvar_name = "invalid_cvar_name"
- -> {
- Object.class_variable_get(invalid_cvar_name)
- }.should raise_error(NameError) {|e| e.name.should equal(invalid_cvar_name) }
- end
+ -> {
+ Object.class_variable_get(invalid_cvar_name)
+ }.should raise_error(NameError) {|e| e.name.should equal(invalid_cvar_name) }
end
end
diff --git a/spec/ruby/core/exception/new_spec.rb b/spec/ruby/core/exception/new_spec.rb
index 61d35a1dfa..100dbb0a24 100644
--- a/spec/ruby/core/exception/new_spec.rb
+++ b/spec/ruby/core/exception/new_spec.rb
@@ -1,7 +1,7 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/new', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/new'
describe "Exception.new" do
- it_behaves_like(:exception_new, :new)
+ it_behaves_like :exception_new, :new
end
diff --git a/spec/ruby/core/exception/no_method_error_spec.rb b/spec/ruby/core/exception/no_method_error_spec.rb
index cf3fe58b1d..570ffc47b1 100644
--- a/spec/ruby/core/exception/no_method_error_spec.rb
+++ b/spec/ruby/core/exception/no_method_error_spec.rb
@@ -1,14 +1,25 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "NoMethodError.new" do
it "allows passing method args" do
- NoMethodError.new("msg","name","args").args.should == "args"
+ NoMethodError.new("msg", "name", ["args"]).args.should == ["args"]
end
it "does not require a name" do
NoMethodError.new("msg").message.should == "msg"
end
+
+ ruby_version_is "2.6" do
+ it "accepts a :receiver keyword argument" do
+ receiver = mock("receiver")
+
+ error = NoMethodError.new("msg", :name, receiver: receiver)
+
+ error.receiver.should == receiver
+ error.name.should == :name
+ end
+ end
end
describe "NoMethodError#args" do
@@ -26,7 +37,7 @@ describe "NoMethodError#args" do
NoMethodErrorSpecs::NoMethodErrorB.new.foo(1,a)
rescue Exception => e
e.args.should == [1,a]
- e.args[1].object_id.should == a.object_id
+ e.args[1].should equal a
end
end
end
@@ -53,7 +64,75 @@ describe "NoMethodError#message" do
NoMethodErrorSpecs::NoMethodErrorC.new.a_private_method
rescue Exception => e
e.should be_kind_of(NoMethodError)
- e.message.match(/private method/).should_not == nil
+ e.message.lines[0].should =~ /private method `a_private_method' called for #<NoMethodErrorSpecs::NoMethodErrorC:0x[\h]+>/
+ end
+ end
+
+ it "calls receiver.inspect only when calling Exception#message" do
+ ScratchPad.record []
+ test_class = Class.new do
+ def inspect
+ ScratchPad << :inspect_called
+ "<inspect>"
+ end
+ end
+ instance = test_class.new
+ begin
+ instance.bar
+ rescue Exception => e
+ e.name.should == :bar
+ ScratchPad.recorded.should == []
+ e.message.should =~ /undefined method.+\bbar\b/
+ ScratchPad.recorded.should == [:inspect_called]
+ end
+ end
+
+ it "fallbacks to a simpler representation of the receiver when receiver.inspect raises an exception" do
+ test_class = Class.new do
+ def inspect
+ raise NoMethodErrorSpecs::InstanceException
+ end
+ end
+ instance = test_class.new
+ begin
+ instance.bar
+ rescue Exception => e
+ e.name.should == :bar
+ message = e.message
+ message.should =~ /undefined method.+\bbar\b/
+ message.should include test_class.inspect
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "uses #name to display the receiver if it is a class or a module" do
+ klass = Class.new { def self.name; "MyClass"; end }
+ begin
+ klass.foo
+ rescue NoMethodError => error
+ error.message.lines.first.should == "undefined method `foo' for MyClass:Class"
+ end
+
+ mod = Module.new { def self.name; "MyModule"; end }
+ begin
+ mod.foo
+ rescue NoMethodError => error
+ error.message.lines.first.should == "undefined method `foo' for MyModule:Module"
+ end
+ end
+ end
+end
+
+describe "NoMethodError#dup" do
+ it "copies the name, arguments and receiver" do
+ begin
+ receiver = Object.new
+ receiver.foo(:one, :two)
+ rescue NoMethodError => nme
+ no_method_error_dup = nme.dup
+ no_method_error_dup.name.should == :foo
+ no_method_error_dup.receiver.should == receiver
+ no_method_error_dup.args.should == [:one, :two]
end
end
end
diff --git a/spec/ruby/core/exception/range_error_spec.rb b/spec/ruby/core/exception/range_error_spec.rb
deleted file mode 100644
index 9c0462bbf7..0000000000
--- a/spec/ruby/core/exception/range_error_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "RangeError" do
- it "is a superclass of FloatDomainError" do
- RangeError.should be_ancestor_of(FloatDomainError)
- end
-end
diff --git a/spec/ruby/core/exception/readagain_bytes_spec.rb b/spec/ruby/core/exception/readagain_bytes_spec.rb
deleted file mode 100644
index 30efb67686..0000000000
--- a/spec/ruby/core/exception/readagain_bytes_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::InvalidByteSequenceError#readagain_bytes" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/reason_spec.rb b/spec/ruby/core/exception/reason_spec.rb
index fad4d47c64..210bbc9725 100644
--- a/spec/ruby/core/exception/reason_spec.rb
+++ b/spec/ruby/core/exception/reason_spec.rb
@@ -1,5 +1,13 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "LocalJumpError#reason" do
- it "needs to be reviewed for spec completeness"
+ def get_me_a_return
+ Proc.new { return 42 }
+ end
+
+ it "returns 'return' for a return" do
+ -> { get_me_a_return.call }.should raise_error(LocalJumpError) { |e|
+ e.reason.should == :return
+ }
+ end
end
diff --git a/spec/ruby/core/exception/receiver_spec.rb b/spec/ruby/core/exception/receiver_spec.rb
index 83f8d5927c..d1c23b67be 100644
--- a/spec/ruby/core/exception/receiver_spec.rb
+++ b/spec/ruby/core/exception/receiver_spec.rb
@@ -1,62 +1,58 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-
-ruby_version_is "2.3" do
- describe "NameError#receiver" do
- class ::ReceiverClass
- def call_undefined_class_variable; @@doesnt_exist end
- end
-
- it "returns the object that raised the exception" do
- receiver = Object.new
-
- -> {
- receiver.doesnt_exist
- }.should raise_error(NameError) {|e| e.receiver.should equal(receiver) }
- end
-
- it "returns the Object class when an undefined constant is called without namespace" do
- -> {
- DoesntExist
- }.should raise_error(NameError) {|e| e.receiver.should equal(Object) }
- end
-
- it "returns a class when an undefined constant is called" do
- -> {
- NameErrorSpecs::ReceiverClass::DoesntExist
- }.should raise_error(NameError) {|e| e.receiver.should equal(NameErrorSpecs::ReceiverClass) }
- end
-
- it "returns the Object class when an undefined class variable is called" do
- -> {
- -> {
- @@doesnt_exist
- }.should complain(/class variable access from toplevel/)
- }.should raise_error(NameError) {|e| e.receiver.should equal(Object) }
- end
-
- it "returns a class when an undefined class variable is called in a subclass' namespace" do
- -> {
- NameErrorSpecs::ReceiverClass.new.call_undefined_class_variable
- }.should raise_error(NameError) {|e| e.receiver.should equal(NameErrorSpecs::ReceiverClass) }
- end
-
- it "returns the receiver when raised from #instance_variable_get" do
- receiver = Object.new
-
- -> {
- receiver.instance_variable_get("invalid_ivar_name")
- }.should raise_error(NameError) {|e| e.receiver.should equal(receiver) }
- end
-
- it "returns the receiver when raised from #class_variable_get" do
- -> {
- Object.class_variable_get("invalid_cvar_name")
- }.should raise_error(NameError) {|e| e.receiver.should equal(Object) }
- end
-
- it "raises an ArgumentError when the receiver is none" do
- -> { NameError.new.receiver }.should raise_error(ArgumentError)
- end
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+
+describe "NameError#receiver" do
+ class ::ReceiverClass
+ def call_undefined_class_variable; @@doesnt_exist end
+ end
+
+ it "returns the object that raised the exception" do
+ receiver = Object.new
+
+ -> {
+ receiver.doesnt_exist
+ }.should raise_error(NameError) {|e| e.receiver.should equal(receiver) }
+ end
+
+ it "returns the Object class when an undefined constant is called without namespace" do
+ -> {
+ DoesntExist
+ }.should raise_error(NameError) {|e| e.receiver.should equal(Object) }
+ end
+
+ it "returns a class when an undefined constant is called" do
+ -> {
+ NameErrorSpecs::ReceiverClass::DoesntExist
+ }.should raise_error(NameError) {|e| e.receiver.should equal(NameErrorSpecs::ReceiverClass) }
+ end
+
+ it "returns the Object class when an undefined class variable is called" do
+ -> {
+ eval("class singleton_class::A; @@doesnt_exist end", binding, __FILE__, __LINE__)
+ }.should raise_error(NameError) {|e| e.receiver.should equal(singleton_class::A) }
+ end
+
+ it "returns a class when an undefined class variable is called in a subclass' namespace" do
+ -> {
+ NameErrorSpecs::ReceiverClass.new.call_undefined_class_variable
+ }.should raise_error(NameError) {|e| e.receiver.should equal(NameErrorSpecs::ReceiverClass) }
+ end
+
+ it "returns the receiver when raised from #instance_variable_get" do
+ receiver = Object.new
+
+ -> {
+ receiver.instance_variable_get("invalid_ivar_name")
+ }.should raise_error(NameError) {|e| e.receiver.should equal(receiver) }
+ end
+
+ it "returns the receiver when raised from #class_variable_get" do
+ -> {
+ Object.class_variable_get("invalid_cvar_name")
+ }.should raise_error(NameError) {|e| e.receiver.should equal(Object) }
+ end
+
+ it "raises an ArgumentError when the receiver is none" do
+ -> { NameError.new.receiver }.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/exception/result_spec.rb b/spec/ruby/core/exception/result_spec.rb
index 350c071f60..2f12673295 100644
--- a/spec/ruby/core/exception/result_spec.rb
+++ b/spec/ruby/core/exception/result_spec.rb
@@ -1,10 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "StopIteration" do
- it "is a subclass of IndexError" do
- StopIteration.superclass.should equal(IndexError)
- end
-end
+require_relative '../../spec_helper'
describe "StopIteration#result" do
before :each do
@@ -20,7 +14,7 @@ describe "StopIteration#result" do
it "returns the method-returned-object from an Enumerator" do
@enum.next
@enum.next
- lambda { @enum.next }.should(
+ -> { @enum.next }.should(
raise_error(StopIteration) do |error|
error.result.should equal(:method_returned)
end
diff --git a/spec/ruby/core/exception/script_error_spec.rb b/spec/ruby/core/exception/script_error_spec.rb
deleted file mode 100644
index 5ca0333261..0000000000
--- a/spec/ruby/core/exception/script_error_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "ScriptError" do
- it "is a superclass of LoadError" do
- ScriptError.should be_ancestor_of(LoadError)
- end
-
- it "is a superclass of NotImplementedError" do
- ScriptError.should be_ancestor_of(NotImplementedError)
- end
-
- it "is a superclass of SyntaxError" do
- ScriptError.should be_ancestor_of(SyntaxError)
- end
-end
diff --git a/spec/ruby/core/exception/set_backtrace_spec.rb b/spec/ruby/core/exception/set_backtrace_spec.rb
index db58a193ef..ba2e1bf7aa 100644
--- a/spec/ruby/core/exception/set_backtrace_spec.rb
+++ b/spec/ruby/core/exception/set_backtrace_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Exception#set_backtrace" do
it "accepts an Array of Strings" do
@@ -36,21 +36,21 @@ describe "Exception#set_backtrace" do
it "raises a TypeError when passed a Symbol" do
err = RuntimeError.new
- lambda { err.set_backtrace :unhappy }.should raise_error(TypeError)
+ -> { err.set_backtrace :unhappy }.should raise_error(TypeError)
end
it "raises a TypeError when the Array contains a Symbol" do
err = RuntimeError.new
- lambda { err.set_backtrace ["String", :unhappy] }.should raise_error(TypeError)
+ -> { err.set_backtrace ["String", :unhappy] }.should raise_error(TypeError)
end
it "raises a TypeError when the array contains nil" do
err = Exception.new
- lambda { err.set_backtrace ["String", nil] }.should raise_error(TypeError)
+ -> { err.set_backtrace ["String", nil] }.should raise_error(TypeError)
end
it "raises a TypeError when the argument is a nested array" do
err = Exception.new
- lambda { err.set_backtrace ["String", ["String"]] }.should raise_error(TypeError)
+ -> { err.set_backtrace ["String", ["String"]] }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/exception/signal_exception_spec.rb b/spec/ruby/core/exception/signal_exception_spec.rb
index 3b2d1aad61..e494e18cde 100644
--- a/spec/ruby/core/exception/signal_exception_spec.rb
+++ b/spec/ruby/core/exception/signal_exception_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "SignalException.new" do
it "takes a signal number as the first argument" do
@@ -9,7 +9,7 @@ describe "SignalException.new" do
end
it "raises an exception with an invalid signal number" do
- lambda { SignalException.new(100000) }.should raise_error(ArgumentError)
+ -> { SignalException.new(100000) }.should raise_error(ArgumentError)
end
it "takes a signal name without SIG prefix as the first argument" do
@@ -27,7 +27,13 @@ describe "SignalException.new" do
end
it "raises an exception with an invalid signal name" do
- lambda { SignalException.new("NONEXISTANT") }.should raise_error(ArgumentError)
+ -> { SignalException.new("NONEXISTENT") }.should raise_error(ArgumentError)
+ end
+
+ ruby_version_is "2.6" do
+ it "raises an exception with an invalid first argument type" do
+ -> { SignalException.new(Object.new) }.should raise_error(ArgumentError)
+ end
end
it "takes a signal symbol without SIG prefix as the first argument" do
@@ -45,7 +51,7 @@ describe "SignalException.new" do
end
it "raises an exception with an invalid signal name" do
- lambda { SignalException.new(:NONEXISTANT) }.should raise_error(ArgumentError)
+ -> { SignalException.new(:NONEXISTENT) }.should raise_error(ArgumentError)
end
it "takes an optional message argument with a signal number" do
@@ -56,11 +62,11 @@ describe "SignalException.new" do
end
it "raises an exception for an optional argument with a signal name" do
- lambda { SignalException.new("INT","name") }.should raise_error(ArgumentError)
+ -> { SignalException.new("INT","name") }.should raise_error(ArgumentError)
end
end
-describe "rescueing SignalException" do
+describe "rescuing SignalException" do
it "raises a SignalException when sent a signal" do
begin
Process.kill :TERM, Process.pid
@@ -72,3 +78,48 @@ describe "rescueing SignalException" do
end
end
end
+
+describe "SignalException" do
+ it "can be rescued" do
+ ruby_exe(<<-RUBY)
+ begin
+ raise SignalException, 'SIGKILL'
+ rescue SignalException
+ exit(0)
+ end
+ exit(1)
+ RUBY
+
+ $?.exitstatus.should == 0
+ end
+
+ platform_is_not :windows do
+ it "runs after at_exit" do
+ output = ruby_exe(<<-RUBY)
+ at_exit do
+ puts "hello"
+ $stdout.flush
+ end
+
+ raise SignalException, 'SIGKILL'
+ RUBY
+
+ $?.termsig.should == Signal.list.fetch("KILL")
+ output.should == "hello\n"
+ end
+
+ it "cannot be trapped with Signal.trap" do
+ ruby_exe(<<-RUBY)
+ Signal.trap("PROF") {}
+ raise(SignalException, "PROF")
+ RUBY
+
+ $?.termsig.should == Signal.list.fetch("PROF")
+ end
+
+ it "self-signals for USR1" do
+ ruby_exe("raise(SignalException, 'USR1')")
+ $?.termsig.should == Signal.list.fetch('USR1')
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/signm_spec.rb b/spec/ruby/core/exception/signm_spec.rb
index e205b79e19..4adff3b5ee 100644
--- a/spec/ruby/core/exception/signm_spec.rb
+++ b/spec/ruby/core/exception/signm_spec.rb
@@ -1,5 +1,9 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "SignalException#signm" do
- it "needs to be reviewed for spec completeness"
+ it "returns the signal name" do
+ -> { Process.kill(:TERM, Process.pid) }.should raise_error(SignalException) { |e|
+ e.signm.should == 'SIGTERM'
+ }
+ end
end
diff --git a/spec/ruby/core/exception/signo_spec.rb b/spec/ruby/core/exception/signo_spec.rb
index 08c85274ca..62fc321516 100644
--- a/spec/ruby/core/exception/signo_spec.rb
+++ b/spec/ruby/core/exception/signo_spec.rb
@@ -1,5 +1,9 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "SignalException#signo" do
- it "needs to be reviewed for spec completeness"
+ it "returns the signal number" do
+ -> { Process.kill(:TERM, Process.pid) }.should raise_error(SignalException) { |e|
+ e.signo.should == Signal.list['TERM']
+ }
+ end
end
diff --git a/spec/ruby/core/exception/source_encoding_name_spec.rb b/spec/ruby/core/exception/source_encoding_name_spec.rb
deleted file mode 100644
index 5796072121..0000000000
--- a/spec/ruby/core/exception/source_encoding_name_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::UndefinedConversionError#source_encoding_name" do
- it "needs to be reviewed for spec completeness"
-end
-
-describe "Encoding::InvalidByteSequenceError#source_encoding_name" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/source_encoding_spec.rb b/spec/ruby/core/exception/source_encoding_spec.rb
deleted file mode 100644
index 796bec88f6..0000000000
--- a/spec/ruby/core/exception/source_encoding_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "Encoding::UndefinedConversionError#source_encoding" do
- it "needs to be reviewed for spec completeness"
-end
-
-describe "Encoding::InvalidByteSequenceError#source_encoding" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/exception/standard_error_spec.rb b/spec/ruby/core/exception/standard_error_spec.rb
index 9b3af4b322..17e98ce7f0 100644
--- a/spec/ruby/core/exception/standard_error_spec.rb
+++ b/spec/ruby/core/exception/standard_error_spec.rb
@@ -1,50 +1,23 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "StandardError" do
- it "is a superclass of ArgumentError" do
- StandardError.should be_ancestor_of(ArgumentError)
+ it "rescues StandardError" do
+ begin
+ raise StandardError
+ rescue => exception
+ exception.class.should == StandardError
+ end
end
- it "is a superclass of IOError" do
- StandardError.should be_ancestor_of(IOError)
+ it "rescues subclass of StandardError" do
+ begin
+ raise RuntimeError
+ rescue => exception
+ exception.class.should == RuntimeError
+ end
end
- it "is a superclass of IndexError" do
- StandardError.should be_ancestor_of(IndexError)
- end
-
- it "is a superclass of LocalJumpError" do
- StandardError.should be_ancestor_of(LocalJumpError)
- end
-
- it "is a superclass of NameError" do
- StandardError.should be_ancestor_of(NameError)
- end
-
- it "is a superclass of RangeError" do
- StandardError.should be_ancestor_of(RangeError)
- end
-
- it "is a superclass of RegexpError" do
- StandardError.should be_ancestor_of(RegexpError)
- end
-
- it "is a superclass of RuntimeError" do
- StandardError.should be_ancestor_of(RuntimeError)
- end
-
- it "is a superclass of SystemCallError" do
- StandardError.should be_ancestor_of(SystemCallError.new("").class)
- end
- it "is a superclass of ThreadError" do
- StandardError.should be_ancestor_of(ThreadError)
- end
-
- it "is a superclass of TypeError" do
- StandardError.should be_ancestor_of(TypeError)
- end
-
- it "is a superclass of ZeroDivisionError" do
- StandardError.should be_ancestor_of(ZeroDivisionError)
+ it "does not rescue superclass of StandardError" do
+ -> { begin; raise Exception; rescue; end }.should raise_error(Exception)
end
end
diff --git a/spec/ruby/core/exception/status_spec.rb b/spec/ruby/core/exception/status_spec.rb
index e648dc0adc..8ace00fe10 100644
--- a/spec/ruby/core/exception/status_spec.rb
+++ b/spec/ruby/core/exception/status_spec.rb
@@ -1,5 +1,9 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "SystemExit#status" do
- it "needs to be reviewed for spec completeness"
+ it "returns the exit status" do
+ -> { exit 42 }.should raise_error(SystemExit) { |e|
+ e.status.should == 42
+ }
+ end
end
diff --git a/spec/ruby/core/exception/success_spec.rb b/spec/ruby/core/exception/success_spec.rb
index d9b69b4f45..6f21743340 100644
--- a/spec/ruby/core/exception/success_spec.rb
+++ b/spec/ruby/core/exception/success_spec.rb
@@ -1,5 +1,15 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "SystemExit#success?" do
- it "needs to be reviewed for spec completeness"
+ it "returns true if the process exited successfully" do
+ -> { exit 0 }.should raise_error(SystemExit) { |e|
+ e.should.success?
+ }
+ end
+
+ it "returns false if the process exited unsuccessfully" do
+ -> { exit(-1) }.should raise_error(SystemExit) { |e|
+ e.should_not.success?
+ }
+ end
end
diff --git a/spec/ruby/core/exception/system_call_error_spec.rb b/spec/ruby/core/exception/system_call_error_spec.rb
index edcc8d3734..73167bc288 100644
--- a/spec/ruby/core/exception/system_call_error_spec.rb
+++ b/spec/ruby/core/exception/system_call_error_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "SystemCallError" do
before :each do
@@ -20,41 +20,82 @@ describe "SystemCallError" do
end
describe "SystemCallError.new" do
+ before :all do
+ @example_errno = Errno::EINVAL::Errno
+ @example_errno_class = Errno::EINVAL
+ @last_known_errno = Errno.constants.size - 1
+ @unknown_errno = Errno.constants.size
+ end
+
it "requires at least one argument" do
- lambda { SystemCallError.new }.should raise_error(ArgumentError)
+ -> { SystemCallError.new }.should raise_error(ArgumentError)
end
- it "accepts single Fixnum argument as errno" do
+ it "accepts single Integer argument as errno" do
SystemCallError.new(-2**24).errno.should == -2**24
- SystemCallError.new(42).errno.should == 42
+ SystemCallError.new(-1).errno.should == -1
+ SystemCallError.new(0).errno.should == 0
+ SystemCallError.new(@last_known_errno).errno.should == @last_known_errno
+ SystemCallError.new(@unknown_errno).errno.should == @unknown_errno
SystemCallError.new(2**24).errno.should == 2**24
end
+ it "constructs a SystemCallError for an unknown error number" do
+ SystemCallError.new(-2**24).should be_an_instance_of(SystemCallError)
+ SystemCallError.new(-1).should be_an_instance_of(SystemCallError)
+ SystemCallError.new(@unknown_errno).should be_an_instance_of(SystemCallError)
+ SystemCallError.new(2**24).should be_an_instance_of(SystemCallError)
+ end
+
it "constructs the appropriate Errno class" do
- # EINVAL should be more or less mortable across the platforms,
- # so let's use it then.
- SystemCallError.new(22).should be_kind_of(SystemCallError)
- SystemCallError.new(22).should be_an_instance_of(Errno::EINVAL)
- SystemCallError.new(2**28).should be_an_instance_of(SystemCallError)
+ e = SystemCallError.new(@example_errno)
+ e.should be_kind_of(SystemCallError)
+ e.should be_an_instance_of(@example_errno_class)
end
it "accepts an optional custom message preceding the errno" do
- exc = SystemCallError.new("custom message", 22)
- exc.should be_an_instance_of(Errno::EINVAL)
- exc.errno.should == 22
- exc.message.should == "Invalid argument - custom message"
+ exc = SystemCallError.new("custom message", @example_errno)
+ exc.should be_an_instance_of(@example_errno_class)
+ exc.errno.should == @example_errno
+ exc.message.should == 'Invalid argument - custom message'
end
it "accepts an optional third argument specifying the location" do
- exc = SystemCallError.new("custom message", 22, "location")
- exc.should be_an_instance_of(Errno::EINVAL)
- exc.errno.should == 22
- exc.message.should == "Invalid argument @ location - custom message"
+ exc = SystemCallError.new("custom message", @example_errno, "location")
+ exc.should be_an_instance_of(@example_errno_class)
+ exc.errno.should == @example_errno
+ exc.message.should == 'Invalid argument @ location - custom message'
+ end
+
+ it "coerces location if it is not a String" do
+ e = SystemCallError.new('foo', 1, :not_a_string)
+ e.message.should =~ /@ not_a_string - foo/
end
it "returns an arity of -1 for the initialize method" do
SystemCallError.instance_method(:initialize).arity.should == -1
end
+
+ it "converts to Integer if errno is a Float" do
+ SystemCallError.new('foo', 2.0).should == SystemCallError.new('foo', 2)
+ SystemCallError.new('foo', 2.9).should == SystemCallError.new('foo', 2)
+ end
+
+ it "converts to Integer if errno is a Complex convertible to Integer" do
+ SystemCallError.new('foo', Complex(2.9, 0)).should == SystemCallError.new('foo', 2)
+ end
+
+ it "raises TypeError if message is not a String" do
+ -> { SystemCallError.new(:foo, 1) }.should raise_error(TypeError, /no implicit conversion of Symbol into String/)
+ end
+
+ it "raises TypeError if errno is not an Integer" do
+ -> { SystemCallError.new('foo', 'bar') }.should raise_error(TypeError, /no implicit conversion of String into Integer/)
+ end
+
+ it "raises RangeError if errno is a Complex not convertible to Integer" do
+ -> { SystemCallError.new('foo', Complex(2.9, 1)) }.should raise_error(RangeError, /can't convert/)
+ end
end
describe "SystemCallError#errno" do
@@ -87,3 +128,16 @@ describe "SystemCallError#message" do
SystemCallError.new("XXX").message.should =~ /XXX/
end
end
+
+describe "SystemCallError#dup" do
+ it "copies the errno" do
+ dup_sce = SystemCallError.new("message", 42).dup
+ dup_sce.errno.should == 42
+ end
+end
+
+describe "SystemCallError#backtrace" do
+ it "is nil if not raised" do
+ SystemCallError.new("message", 42).backtrace.should == nil
+ end
+end
diff --git a/spec/ruby/core/exception/system_exit_spec.rb b/spec/ruby/core/exception/system_exit_spec.rb
new file mode 100644
index 0000000000..5c6116576b
--- /dev/null
+++ b/spec/ruby/core/exception/system_exit_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../spec_helper'
+
+describe "SystemExit" do
+ it "sets the exit status and exits silently when raised" do
+ code = 'raise SystemExit.new(7)'
+ result = ruby_exe(code, args: "2>&1")
+ result.should == ""
+ $?.exitstatus.should == 7
+ end
+
+ it "sets the exit status and exits silently when raised when subclassed" do
+ code = 'class CustomExit < SystemExit; end; raise CustomExit.new(8)'
+ result = ruby_exe(code, args: "2>&1")
+ result.should == ""
+ $?.exitstatus.should == 8
+ end
+end
diff --git a/spec/ruby/core/exception/system_stack_error_spec.rb b/spec/ruby/core/exception/system_stack_error_spec.rb
deleted file mode 100644
index acd56c0a0f..0000000000
--- a/spec/ruby/core/exception/system_stack_error_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "SystemStackError" do
- it "is a subclass of Exception" do
- SystemStackError.superclass.should == Exception
- end
-end
diff --git a/spec/ruby/core/exception/to_s_spec.rb b/spec/ruby/core/exception/to_s_spec.rb
index 83234bfe23..4c4c7ab432 100644
--- a/spec/ruby/core/exception/to_s_spec.rb
+++ b/spec/ruby/core/exception/to_s_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
describe "Exception#to_s" do
it "returns the self's name if no message is set" do
@@ -19,5 +19,19 @@ describe "Exception#to_s" do
end
describe "NameError#to_s" do
- it "needs to be reviewed for spec completeness"
+ it "raises its own message for an undefined variable" do
+ begin
+ puts not_defined
+ rescue => exception
+ exception.message.should =~ /undefined local variable or method `not_defined'/
+ end
+ end
+
+ it "raises its own message for an undefined constant" do
+ begin
+ puts NotDefined
+ rescue => exception
+ exception.message.should =~ /uninitialized constant NotDefined/
+ end
+ end
end
diff --git a/spec/ruby/core/exception/top_level_spec.rb b/spec/ruby/core/exception/top_level_spec.rb
new file mode 100644
index 0000000000..501c7253c3
--- /dev/null
+++ b/spec/ruby/core/exception/top_level_spec.rb
@@ -0,0 +1,47 @@
+require_relative '../../spec_helper'
+
+describe "An Exception reaching the top level" do
+ it "is printed on STDERR" do
+ ruby_exe('raise "foo"', args: "2>&1").should.include?("in `<main>': foo (RuntimeError)")
+ end
+
+ ruby_version_is "2.6" do
+ it "the Exception#cause is printed to STDERR with backtraces" do
+ code = <<-RUBY
+ def raise_cause
+ raise "the cause"
+ end
+ def raise_wrapped
+ raise "wrapped"
+ end
+ begin
+ raise_cause
+ rescue
+ raise_wrapped
+ end
+ RUBY
+ lines = ruby_exe(code, args: "2>&1").lines
+ lines.reject! { |l| l.include?('rescue in') }
+ lines.map! { |l| l.chomp[/:(in.+)/, 1] }
+ lines.should == ["in `raise_wrapped': wrapped (RuntimeError)",
+ "in `<main>'",
+ "in `raise_cause': the cause (RuntimeError)",
+ "in `<main>'"]
+ end
+ end
+
+ describe "with a custom backtrace" do
+ it "is printed on STDERR" do
+ code = <<-RUBY
+ raise RuntimeError, "foo", [
+ "/dir/foo.rb:10:in `raising'",
+ "/dir/bar.rb:20:in `caller'",
+ ]
+ RUBY
+ ruby_exe(code, args: "2>&1").should == <<-EOS
+/dir/foo.rb:10:in `raising': foo (RuntimeError)
+\tfrom /dir/bar.rb:20:in `caller'
+ EOS
+ end
+ end
+end
diff --git a/spec/ruby/core/exception/uncaught_throw_error_spec.rb b/spec/ruby/core/exception/uncaught_throw_error_spec.rb
index 3ed166af5b..9267df6670 100644
--- a/spec/ruby/core/exception/uncaught_throw_error_spec.rb
+++ b/spec/ruby/core/exception/uncaught_throw_error_spec.rb
@@ -1,10 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "UncaughtThrowError" do
- it "is a subclass of ArgumentError" do
- ArgumentError.should be_ancestor_of(UncaughtThrowError)
- end
-end
+require_relative '../../spec_helper'
describe "UncaughtThrowError#tag" do
it "returns the object thrown" do
@@ -16,4 +10,3 @@ describe "UncaughtThrowError#tag" do
end
end
end
-
diff --git a/spec/ruby/core/false/and_spec.rb b/spec/ruby/core/false/and_spec.rb
index a949c02503..0b02ae62c5 100644
--- a/spec/ruby/core/false/and_spec.rb
+++ b/spec/ruby/core/false/and_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "FalseClass#&" do
it "returns false" do
diff --git a/spec/ruby/core/false/dup_spec.rb b/spec/ruby/core/false/dup_spec.rb
new file mode 100644
index 0000000000..1a569a2f4f
--- /dev/null
+++ b/spec/ruby/core/false/dup_spec.rb
@@ -0,0 +1,7 @@
+require_relative '../../spec_helper'
+
+describe "FalseClass#dup" do
+ it "returns self" do
+ false.dup.should equal(false)
+ end
+end
diff --git a/spec/ruby/core/false/falseclass_spec.rb b/spec/ruby/core/false/falseclass_spec.rb
index e91682c94c..c018ef2421 100644
--- a/spec/ruby/core/false/falseclass_spec.rb
+++ b/spec/ruby/core/false/falseclass_spec.rb
@@ -1,14 +1,14 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "FalseClass" do
it ".allocate raises a TypeError" do
- lambda do
+ -> do
FalseClass.allocate
end.should raise_error(TypeError)
end
it ".new is undefined" do
- lambda do
+ -> do
FalseClass.new
end.should raise_error(NoMethodError)
end
diff --git a/spec/ruby/core/false/inspect_spec.rb b/spec/ruby/core/false/inspect_spec.rb
index f3bb6645bf..4cbb55d434 100644
--- a/spec/ruby/core/false/inspect_spec.rb
+++ b/spec/ruby/core/false/inspect_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "FalseClass#inspect" do
it "returns the string 'false'" do
diff --git a/spec/ruby/core/false/or_spec.rb b/spec/ruby/core/false/or_spec.rb
index e2f4dbd90b..f3ee1a3439 100644
--- a/spec/ruby/core/false/or_spec.rb
+++ b/spec/ruby/core/false/or_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "FalseClass#|" do
it "returns false if other is nil or false, otherwise true" do
diff --git a/spec/ruby/core/false/to_s_spec.rb b/spec/ruby/core/false/to_s_spec.rb
index bb2bdb65af..4cae278891 100644
--- a/spec/ruby/core/false/to_s_spec.rb
+++ b/spec/ruby/core/false/to_s_spec.rb
@@ -1,7 +1,17 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "FalseClass#to_s" do
it "returns the string 'false'" do
false.to_s.should == "false"
end
+
+ ruby_version_is "2.7" do
+ it "returns a frozen string" do
+ false.to_s.should.frozen?
+ end
+
+ it "always returns the same string" do
+ false.to_s.should equal(false.to_s)
+ end
+ end
end
diff --git a/spec/ruby/core/false/xor_spec.rb b/spec/ruby/core/false/xor_spec.rb
index 3e5c452f9b..1b87b9f412 100644
--- a/spec/ruby/core/false/xor_spec.rb
+++ b/spec/ruby/core/false/xor_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "FalseClass#^" do
it "returns false if other is nil or false, otherwise true" do
diff --git a/spec/ruby/core/fiber/fixtures/classes.rb b/spec/ruby/core/fiber/fixtures/classes.rb
new file mode 100644
index 0000000000..c00facd6e1
--- /dev/null
+++ b/spec/ruby/core/fiber/fixtures/classes.rb
@@ -0,0 +1,12 @@
+module FiberSpecs
+
+ class NewFiberToRaise
+ def self.raise(*args)
+ fiber = Fiber.new { Fiber.yield }
+ fiber.resume
+ fiber.raise(*args)
+ end
+ end
+
+ class CustomError < StandardError; end
+end
diff --git a/spec/ruby/core/fiber/new_spec.rb b/spec/ruby/core/fiber/new_spec.rb
index a3361acc65..b43c1386be 100644
--- a/spec/ruby/core/fiber/new_spec.rb
+++ b/spec/ruby/core/fiber/new_spec.rb
@@ -1,41 +1,39 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-with_feature :fiber do
- describe "Fiber.new" do
- it "creates a fiber from the given block" do
- fiber = Fiber.new {}
- fiber.resume
- fiber.should be_an_instance_of(Fiber)
- end
+describe "Fiber.new" do
+ it "creates a fiber from the given block" do
+ fiber = Fiber.new {}
+ fiber.resume
+ fiber.should be_an_instance_of(Fiber)
+ end
- it "creates a fiber from a subclass" do
- class MyFiber < Fiber
- end
- fiber = MyFiber.new {}
- fiber.resume
- fiber.should be_an_instance_of(MyFiber)
+ it "creates a fiber from a subclass" do
+ class MyFiber < Fiber
end
+ fiber = MyFiber.new {}
+ fiber.resume
+ fiber.should be_an_instance_of(MyFiber)
+ end
- it "raises an ArgumentError if called without a block" do
- lambda { Fiber.new }.should raise_error(ArgumentError)
- end
+ it "raises an ArgumentError if called without a block" do
+ -> { Fiber.new }.should raise_error(ArgumentError)
+ end
- it "does not invoke the block" do
- invoked = false
- fiber = Fiber.new { invoked = true }
- invoked.should be_false
- fiber.resume
- end
+ it "does not invoke the block" do
+ invoked = false
+ fiber = Fiber.new { invoked = true }
+ invoked.should be_false
+ fiber.resume
+ end
- it "closes over lexical environments" do
- o = Object.new
- def o.f
- a = 1
- f = Fiber.new { a = 2 }
- f.resume
- a
- end
- o.f.should == 2
+ it "closes over lexical environments" do
+ o = Object.new
+ def o.f
+ a = 1
+ f = Fiber.new { a = 2 }
+ f.resume
+ a
end
+ o.f.should == 2
end
end
diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb
new file mode 100644
index 0000000000..f56219e565
--- /dev/null
+++ b/spec/ruby/core/fiber/raise_spec.rb
@@ -0,0 +1,101 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative '../../shared/kernel/raise'
+
+ruby_version_is "2.7" do
+ describe "Fiber#raise" do
+ it_behaves_like :kernel_raise, :raise, FiberSpecs::NewFiberToRaise
+ end
+
+ describe "Fiber#raise" do
+ it 'raises RuntimeError by default' do
+ -> { FiberSpecs::NewFiberToRaise.raise }.should raise_error(RuntimeError)
+ end
+
+ it "raises FiberError if Fiber is not born" do
+ fiber = Fiber.new { true }
+ -> { fiber.raise }.should raise_error(FiberError, "cannot raise exception on unborn fiber")
+ end
+
+ it "raises FiberError if Fiber is dead" do
+ fiber = Fiber.new { true }
+ fiber.resume
+ -> { fiber.raise }.should raise_error(FiberError, /dead fiber called|attempt to resume a terminated fiber/)
+ end
+
+ it 'accepts error class' do
+ -> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError }.should raise_error(FiberSpecs::CustomError)
+ end
+
+ it 'accepts error message' do
+ -> { FiberSpecs::NewFiberToRaise.raise "error message" }.should raise_error(RuntimeError, "error message")
+ end
+
+ it 'does not accept array of backtrace information only' do
+ -> { FiberSpecs::NewFiberToRaise.raise ['foo'] }.should raise_error(TypeError)
+ end
+
+ it 'does not accept integer' do
+ -> { FiberSpecs::NewFiberToRaise.raise 100 }.should raise_error(TypeError)
+ end
+
+ it 'accepts error class with error message' do
+ -> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error' }.should raise_error(FiberSpecs::CustomError, 'test error')
+ end
+
+ it 'accepts error class with with error message and backtrace information' do
+ -> {
+ FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error', ['foo', 'boo']
+ }.should raise_error(FiberSpecs::CustomError) { |e|
+ e.message.should == 'test error'
+ e.backtrace.should == ['foo', 'boo']
+ }
+ end
+
+ it 'does not accept only error message and backtrace information' do
+ -> { FiberSpecs::NewFiberToRaise.raise 'test error', ['foo', 'boo'] }.should raise_error(TypeError)
+ end
+
+ it "raises a FiberError if invoked from a different Thread" do
+ fiber = Fiber.new { Fiber.yield }
+ fiber.resume
+ Thread.new do
+ -> {
+ fiber.raise
+ }.should raise_error(FiberError, "fiber called across threads")
+ end.join
+ end
+
+ it "kills Fiber" do
+ fiber = Fiber.new { Fiber.yield :first; :second }
+ fiber.resume
+ -> { fiber.raise }.should raise_error
+ -> { fiber.resume }.should raise_error(FiberError, /dead fiber called|attempt to resume a terminated fiber/)
+ end
+ end
+
+end
+
+ruby_version_is "2.7"..."3.0" do
+ describe "Fiber#raise" do
+ it "raises a FiberError if invoked on a transferring Fiber" do
+ require "fiber"
+ root = Fiber.current
+ fiber = Fiber.new { root.transfer }
+ fiber.transfer
+ -> { fiber.raise }.should raise_error(FiberError, "cannot resume transferred Fiber")
+ end
+ end
+end
+
+ruby_version_is "3.0" do
+ describe "Fiber#raise" do
+ it "transfers and raises on a transferring fiber" do
+ require "fiber"
+ root = Fiber.current
+ fiber = Fiber.new { root.transfer }
+ fiber.transfer
+ -> { fiber.raise "msg" }.should raise_error(RuntimeError, "msg")
+ end
+ end
+end
diff --git a/spec/ruby/core/fiber/resume_spec.rb b/spec/ruby/core/fiber/resume_spec.rb
index 3fd3aed8fa..273bc866af 100644
--- a/spec/ruby/core/fiber/resume_spec.rb
+++ b/spec/ruby/core/fiber/resume_spec.rb
@@ -1,54 +1,79 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/fiber/resume', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/fiber/resume'
-with_feature :fiber do
- describe "Fiber#resume" do
- it_behaves_like :fiber_resume, :resume
+describe "Fiber#resume" do
+ it_behaves_like :fiber_resume, :resume
+end
+
+describe "Fiber#resume" do
+ it "runs until Fiber.yield" do
+ obj = mock('obj')
+ obj.should_not_receive(:do)
+ fiber = Fiber.new { 1 + 2; Fiber.yield; obj.do }
+ fiber.resume
end
- describe "Fiber#resume" do
- it "returns control to the calling Fiber if called from one" do
- fiber1 = Fiber.new { :fiber1 }
- fiber2 = Fiber.new { fiber1.resume; :fiber2 }
- fiber2.resume.should == :fiber2
+ it "resumes from the last call to Fiber.yield on subsequent invocations" do
+ fiber = Fiber.new { Fiber.yield :first; :second }
+ fiber.resume.should == :first
+ fiber.resume.should == :second
+ end
+
+ it "sets the block parameters to its arguments on the first invocation" do
+ first = mock('first')
+ first.should_receive(:arg).with(:first).twice
+
+ fiber = Fiber.new { |arg| first.arg arg; Fiber.yield; first.arg arg; }
+ fiber.resume :first
+ fiber.resume :second
+ end
+
+ ruby_version_is '3.0' do
+ it "raises a FiberError if the Fiber tries to resume itself" do
+ fiber = Fiber.new { fiber.resume }
+ -> { fiber.resume }.should raise_error(FiberError, /current fiber/)
end
+ end
- with_feature :fork do
- # Redmine #595
- it "executes the ensure clause" do
- rd, wr = IO.pipe
-
- pid = Kernel::fork do
- rd.close
- f = Fiber.new do
- begin
- Fiber.yield
- ensure
- wr.write "executed"
- end
- end
-
- # The apparent issue is that when Fiber.yield executes, control
- # "leaves" the "ensure block" and so the ensure clause should run. But
- # control really does NOT leave the ensure block when Fiber.yield
- # executes. It merely pauses there. To require ensure to run when a
- # Fiber is suspended then makes ensure-in-a-Fiber-context different
- # than ensure-in-a-Thread-context and this would be very confusing.
- f.resume
-
- # When we execute the second #resume call, the ensure block DOES exit,
- # the ensure clause runs. This is Ruby behavior as of 2.3.1.
- f.resume
-
- exit 0
- end
+ ruby_version_is '' ... '3.0' do
+ it "raises a FiberError if the Fiber tries to resume itself" do
+ fiber = Fiber.new { fiber.resume }
+ -> { fiber.resume }.should raise_error(FiberError, /double resume/)
+ end
+ end
- wr.close
- Process.waitpid pid
+ it "returns control to the calling Fiber if called from one" do
+ fiber1 = Fiber.new { :fiber1 }
+ fiber2 = Fiber.new { fiber1.resume; :fiber2 }
+ fiber2.resume.should == :fiber2
+ end
- rd.read.should == "executed"
- rd.close
+ # Redmine #595
+ it "executes the ensure clause" do
+ code = <<-RUBY
+ f = Fiber.new do
+ begin
+ Fiber.yield
+ ensure
+ puts "ensure executed"
+ end
end
- end
+
+ # The apparent issue is that when Fiber.yield executes, control
+ # "leaves" the "ensure block" and so the ensure clause should run. But
+ # control really does NOT leave the ensure block when Fiber.yield
+ # executes. It merely pauses there. To require ensure to run when a
+ # Fiber is suspended then makes ensure-in-a-Fiber-context different
+ # than ensure-in-a-Thread-context and this would be very confusing.
+ f.resume
+
+ # When we execute the second #resume call, the ensure block DOES exit,
+ # the ensure clause runs.
+ f.resume
+
+ exit 0
+ RUBY
+
+ ruby_exe(code).should == "ensure executed\n"
end
end
diff --git a/spec/ruby/core/fiber/yield_spec.rb b/spec/ruby/core/fiber/yield_spec.rb
index e433da0aa9..b010912c87 100644
--- a/spec/ruby/core/fiber/yield_spec.rb
+++ b/spec/ruby/core/fiber/yield_spec.rb
@@ -1,51 +1,49 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-with_feature :fiber do
- describe "Fiber.yield" do
- it "passes control to the Fiber's caller" do
- step = 0
- fiber = Fiber.new { step = 1; Fiber.yield; step = 2; Fiber.yield; step = 3 }
- fiber.resume
- step.should == 1
- fiber.resume
- step.should == 2
- end
-
- it "returns its arguments to the caller" do
- fiber = Fiber.new { true; Fiber.yield :glark; true }
- fiber.resume.should == :glark
- fiber.resume
- end
+require_relative '../../spec_helper'
+
+describe "Fiber.yield" do
+ it "passes control to the Fiber's caller" do
+ step = 0
+ fiber = Fiber.new { step = 1; Fiber.yield; step = 2; Fiber.yield; step = 3 }
+ fiber.resume
+ step.should == 1
+ fiber.resume
+ step.should == 2
+ end
- it "returns nil to the caller if given no arguments" do
- fiber = Fiber.new { true; Fiber.yield; true }
- fiber.resume.should be_nil
- fiber.resume
- end
+ it "returns its arguments to the caller" do
+ fiber = Fiber.new { true; Fiber.yield :glark; true }
+ fiber.resume.should == :glark
+ fiber.resume
+ end
- it "returns to the Fiber the value of the #resume call that invoked it" do
- fiber = Fiber.new { Fiber.yield.should == :caller }
- fiber.resume
- fiber.resume :caller
- end
+ it "returns nil to the caller if given no arguments" do
+ fiber = Fiber.new { true; Fiber.yield; true }
+ fiber.resume.should be_nil
+ fiber.resume
+ end
- it "does not propagate or reraise a rescued exception" do
- fiber = Fiber.new do
- begin
- raise "an error in a Fiber"
- rescue
- Fiber.yield :first
- end
+ it "returns to the Fiber the value of the #resume call that invoked it" do
+ fiber = Fiber.new { Fiber.yield.should == :caller }
+ fiber.resume
+ fiber.resume :caller
+ end
- :second
+ it "does not propagate or reraise a rescued exception" do
+ fiber = Fiber.new do
+ begin
+ raise "an error in a Fiber"
+ rescue
+ Fiber.yield :first
end
- fiber.resume.should == :first
- fiber.resume.should == :second
+ :second
end
- it "raises a FiberError if called from the root Fiber" do
- lambda{ Fiber.yield }.should raise_error(FiberError)
- end
+ fiber.resume.should == :first
+ fiber.resume.should == :second
+ end
+
+ it "raises a FiberError if called from the root Fiber" do
+ ->{ Fiber.yield }.should raise_error(FiberError)
end
end
diff --git a/spec/ruby/core/file/absolute_path_spec.rb b/spec/ruby/core/file/absolute_path_spec.rb
index b1f4f05aee..9f39923472 100644
--- a/spec/ruby/core/file/absolute_path_spec.rb
+++ b/spec/ruby/core/file/absolute_path_spec.rb
@@ -1,4 +1,57 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
+
+ruby_version_is "2.7" do
+ describe "File.absolute_path?" do
+ before :each do
+ @abs = File.expand_path(__FILE__)
+ end
+
+ it "returns true if it's an absolute pathname" do
+ File.absolute_path?(@abs).should be_true
+ end
+
+ it "returns false if it's a relative path" do
+ File.absolute_path?(File.basename(__FILE__)).should be_false
+ end
+
+ it "returns false if it's a tricky relative path" do
+ File.absolute_path?("C:foo\\bar").should be_false
+ end
+
+ it "does not expand '~' to a home directory." do
+ File.absolute_path?('~').should be_false
+ end
+
+ it "does not expand '~user' to a home directory." do
+ path = File.dirname(@abs)
+ Dir.chdir(path) do
+ File.absolute_path?('~user').should be_false
+ end
+ end
+
+ it "calls #to_path on its argument" do
+ mock = mock_to_path(File.expand_path(__FILE__))
+
+ File.absolute_path?(mock).should be_true
+ end
+
+ platform_is_not :windows do
+ it "takes into consideration the platform's root" do
+ File.absolute_path?("C:\\foo\\bar").should be_false
+ File.absolute_path?("C:/foo/bar").should be_false
+ File.absolute_path?("/foo/bar\\baz").should be_true
+ end
+ end
+
+ platform_is :windows do
+ it "takes into consideration the platform path separator(s)" do
+ File.absolute_path?("C:\\foo\\bar").should be_true
+ File.absolute_path?("C:/foo/bar").should be_true
+ File.absolute_path?("/foo/bar\\baz").should be_false
+ end
+ end
+ end
+end
describe "File.absolute_path" do
before :each do
@@ -20,6 +73,12 @@ describe "File.absolute_path" do
File.absolute_path('~').should_not == File.expand_path('~')
end
+ platform_is_not :windows do
+ it "does not expand '~' when given dir argument" do
+ File.absolute_path('~', '/').should == '/~'
+ end
+ end
+
it "does not expand '~user' to a home directory." do
path = File.dirname(@abs)
Dir.chdir(path) do
diff --git a/spec/ruby/core/file/atime_spec.rb b/spec/ruby/core/file/atime_spec.rb
index 76e7fbd62a..5663e47266 100644
--- a/spec/ruby/core/file/atime_spec.rb
+++ b/spec/ruby/core/file/atime_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.atime" do
before :each do
@@ -15,7 +15,7 @@ describe "File.atime" do
File.atime(@file).should be_kind_of(Time)
end
- platform_is :linux do
+ platform_is :linux, :windows do
## NOTE also that some Linux systems disable atime (e.g. via mount params) for better filesystem speed.
it "returns the last access time for the named file with microseconds" do
supports_subseconds = Integer(`stat -c%x '#{__FILE__}'`[/\.(\d+)/, 1], 10)
@@ -30,7 +30,7 @@ describe "File.atime" do
end
it "raises an Errno::ENOENT exception if the file is not found" do
- lambda { File.atime('a_fake_file') }.should raise_error(Errno::ENOENT)
+ -> { File.atime('a_fake_file') }.should raise_error(Errno::ENOENT)
end
it "accepts an object that has a #to_path method" do
diff --git a/spec/ruby/core/file/basename_spec.rb b/spec/ruby/core/file/basename_spec.rb
index 4cf26062d3..6d7e432086 100644
--- a/spec/ruby/core/file/basename_spec.rb
+++ b/spec/ruby/core/file/basename_spec.rb
@@ -1,5 +1,5 @@
# -*- encoding: utf-8 -*-
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
# TODO: Fix these
describe "File.basename" do
@@ -105,10 +105,10 @@ describe "File.basename" do
end
it "raises a TypeError if the arguments are not String types" do
- lambda { File.basename(nil) }.should raise_error(TypeError)
- lambda { File.basename(1) }.should raise_error(TypeError)
- lambda { File.basename("bar.txt", 1) }.should raise_error(TypeError)
- lambda { File.basename(true) }.should raise_error(TypeError)
+ -> { File.basename(nil) }.should raise_error(TypeError)
+ -> { File.basename(1) }.should raise_error(TypeError)
+ -> { File.basename("bar.txt", 1) }.should raise_error(TypeError)
+ -> { File.basename(true) }.should raise_error(TypeError)
end
it "accepts an object that has a #to_path method" do
@@ -116,7 +116,7 @@ describe "File.basename" do
end
it "raises an ArgumentError if passed more than two arguments" do
- lambda { File.basename('bar.txt', '.txt', '.txt') }.should raise_error(ArgumentError)
+ -> { File.basename('bar.txt', '.txt', '.txt') }.should raise_error(ArgumentError)
end
# specific to MS Windows
@@ -153,18 +153,16 @@ describe "File.basename" do
end
end
- with_feature :encoding do
- it "returns the extension for a multibyte filename" do
- File.basename('/path/ОфиÑ.m4a').should == "ОфиÑ.m4a"
- end
-
- it "returns the basename with the same encoding as the original" do
- basename = File.basename('C:/Users/Scuby Pagrubý'.encode(Encoding::Windows_1250))
- basename.should == 'Scuby Pagrubý'.encode(Encoding::Windows_1250)
- basename.encoding.should == Encoding::Windows_1250
- end
+ it "returns the extension for a multibyte filename" do
+ File.basename('/path/ОфиÑ.m4a').should == "ОфиÑ.m4a"
+ end
+ it "returns the basename with the same encoding as the original" do
+ basename = File.basename('C:/Users/Scuby Pagrubý'.encode(Encoding::Windows_1250))
+ basename.should == 'Scuby Pagrubý'.encode(Encoding::Windows_1250)
+ basename.encoding.should == Encoding::Windows_1250
end
+
end
diff --git a/spec/ruby/core/file/birthtime_spec.rb b/spec/ruby/core/file/birthtime_spec.rb
index 9720ede834..755601df64 100644
--- a/spec/ruby/core/file/birthtime_spec.rb
+++ b/spec/ruby/core/file/birthtime_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.birthtime" do
before :each do
@@ -20,15 +20,17 @@ describe "File.birthtime" do
end
it "raises an Errno::ENOENT exception if the file is not found" do
- lambda { File.birthtime('bogus') }.should raise_error(Errno::ENOENT)
+ -> { File.birthtime('bogus') }.should raise_error(Errno::ENOENT)
end
end
- platform_is :linux, :openbsd do
+ platform_is :openbsd do
it "raises an NotImplementedError" do
- lambda { File.birthtime(@file) }.should raise_error(NotImplementedError)
+ -> { File.birthtime(@file) }.should raise_error(NotImplementedError)
end
end
+
+ # TODO: depends on Linux kernel version
end
describe "File#birthtime" do
@@ -48,9 +50,11 @@ describe "File#birthtime" do
end
end
- platform_is :linux, :openbsd do
+ platform_is :openbsd do
it "raises an NotImplementedError" do
- lambda { @file.birthtime }.should raise_error(NotImplementedError)
+ -> { @file.birthtime }.should raise_error(NotImplementedError)
end
end
+
+ # TODO: depends on Linux kernel version
end
diff --git a/spec/ruby/core/file/blockdev_spec.rb b/spec/ruby/core/file/blockdev_spec.rb
index f5e03d1ade..9ba9afc251 100644
--- a/spec/ruby/core/file/blockdev_spec.rb
+++ b/spec/ruby/core/file/blockdev_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/blockdev', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/blockdev'
describe "File.blockdev?" do
it_behaves_like :file_blockdev, :blockdev?, File
diff --git a/spec/ruby/core/file/chardev_spec.rb b/spec/ruby/core/file/chardev_spec.rb
index 963823a206..1fc932ee4e 100644
--- a/spec/ruby/core/file/chardev_spec.rb
+++ b/spec/ruby/core/file/chardev_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/chardev', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/chardev'
describe "File.chardev?" do
it_behaves_like :file_chardev, :chardev?, File
diff --git a/spec/ruby/core/file/chmod_spec.rb b/spec/ruby/core/file/chmod_spec.rb
index 8590f3008d..5ca15c9748 100644
--- a/spec/ruby/core/file/chmod_spec.rb
+++ b/spec/ruby/core/file/chmod_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File#chmod" do
before :each do
@@ -15,38 +15,11 @@ describe "File#chmod" do
@file.chmod(0755).should == 0
end
- platform_is_not :freebsd, :netbsd, :openbsd do
- it "always succeeds with any numeric values" do
- vals = [-2**30, -2**16, -2**8, -2, -1,
- -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
- vals.each { |v|
- lambda { @file.chmod(v) }.should_not raise_error
- }
- end
- end
-
- # -256, -2 and -1 raise Errno::E079 on FreeBSD
- # -256, -2 and -1 raise Errno::EFTYPE on NetBSD
- platform_is :freebsd, :netbsd do
- it "always succeeds with any numeric values" do
- vals = [-2**30, -2**16, #-2**8, -2, -1,
- -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
- vals.each { |v|
- lambda { @file.chmod(v) }.should_not raise_error
- }
- end
+ it "raises RangeError with too large values" do
+ -> { @file.chmod(2**64) }.should raise_error(RangeError)
+ -> { @file.chmod(-2**63 - 1) }.should raise_error(RangeError)
end
- # -256, -2 and -1 raise Errno::EINVAL on OpenBSD
- platform_is :openbsd do
- it "always succeeds with any numeric values" do
- vals = [#-2**30, -2**16, -2**8, -2, -1,
- -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8]#, 2**16, 2**30
- vals.each { |v|
- lambda { @file.chmod(v) }.should_not raise_error
- }
- end
- end
it "invokes to_int on non-integer argument" do
mode = File.stat(@filename).mode
(obj = mock('mode')).should_receive(:to_int).and_return(mode)
@@ -71,37 +44,39 @@ describe "File#chmod" do
end
platform_is_not :windows do
- it "with '0222' makes file writable but not readable or executable" do
- @file.chmod(0222)
- File.readable?(@filename).should == false
- File.writable?(@filename).should == true
- File.executable?(@filename).should == false
- end
-
- it "with '0444' makes file readable but not writable or executable" do
- @file.chmod(0444)
- File.readable?(@filename).should == true
- File.writable?(@filename).should == false
- File.executable?(@filename).should == false
- end
-
- it "with '0666' makes file readable and writable but not executable" do
- @file.chmod(0666)
- File.readable?(@filename).should == true
- File.writable?(@filename).should == true
- File.executable?(@filename).should == false
- end
-
- it "with '0111' makes file executable but not readable or writable" do
- @file.chmod(0111)
- File.readable?(@filename).should == false
- File.writable?(@filename).should == false
- File.executable?(@filename).should == true
- end
-
- it "modifies the permission bits of the files specified" do
- @file.chmod(0755)
- File.stat(@filename).mode.should == 33261
+ as_user do
+ it "with '0222' makes file writable but not readable or executable" do
+ @file.chmod(0222)
+ File.readable?(@filename).should == false
+ File.writable?(@filename).should == true
+ File.executable?(@filename).should == false
+ end
+
+ it "with '0444' makes file readable but not writable or executable" do
+ @file.chmod(0444)
+ File.readable?(@filename).should == true
+ File.writable?(@filename).should == false
+ File.executable?(@filename).should == false
+ end
+
+ it "with '0666' makes file readable and writable but not executable" do
+ @file.chmod(0666)
+ File.readable?(@filename).should == true
+ File.writable?(@filename).should == true
+ File.executable?(@filename).should == false
+ end
+
+ it "with '0111' makes file executable but not readable or writable" do
+ @file.chmod(0111)
+ File.readable?(@filename).should == false
+ File.writable?(@filename).should == false
+ File.executable?(@filename).should == true
+ end
+
+ it "modifies the permission bits of the files specified" do
+ @file.chmod(0755)
+ File.stat(@filename).mode.should == 33261
+ end
end
end
end
@@ -121,54 +96,21 @@ describe "File.chmod" do
@count.should == 1
end
- platform_is_not :freebsd, :netbsd, :openbsd do
- it "always succeeds with any numeric values" do
- vals = [-2**30, -2**16, -2**8, -2, -1,
- -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
- vals.each { |v|
- lambda { File.chmod(v, @file) }.should_not raise_error
- }
- end
- end
-
- # -256, -2 and -1 raise Errno::E079 on FreeBSD
- # -256, -2 and -1 raise Errno::EFTYPE on NetBSD
- platform_is :freebsd, :netbsd do
- it "always succeeds with any numeric values" do
- vals = [-2**30, -2**16, #-2**8, -2, -1,
- -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
- vals.each { |v|
- lambda { File.chmod(v, @file) }.should_not raise_error
- }
- end
- end
-
- platform_is :openbsd do
- it "succeeds with valid values" do
- vals = [-0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8]
- vals.each { |v|
- lambda { File.chmod(v, @file) }.should_not raise_error
- }
- end
-
- it "fails with invalid values" do
- vals = [-2**30, -2**16, -2**8, -2, -1, 2**16, 2**30]
- vals.each { |v|
- lambda { File.chmod(v, @file) }.should raise_error(Errno::EINVAL)
- }
- end
+ it "raises RangeError with too large values" do
+ -> { File.chmod(2**64, @file) }.should raise_error(RangeError)
+ -> { File.chmod(-2**63 - 1, @file) }.should raise_error(RangeError)
end
it "accepts an object that has a #to_path method" do
File.chmod(0, mock_to_path(@file))
end
- it "throws a TypeError if the given path is not coercable into a string" do
- lambda { File.chmod(0, []) }.should raise_error(TypeError)
+ it "throws a TypeError if the given path is not coercible into a string" do
+ -> { File.chmod(0, []) }.should raise_error(TypeError)
end
it "raises an error for a non existent path" do
- lambda {
+ -> {
File.chmod(0644, "#{@file}.not.existing")
}.should raise_error(Errno::ENOENT)
end
@@ -204,18 +146,20 @@ describe "File.chmod" do
end
platform_is_not :windows do
- it "with '0222' makes file writable but not readable or executable" do
- File.chmod(0222, @file)
- File.readable?(@file).should == false
- File.writable?(@file).should == true
- File.executable?(@file).should == false
- end
-
- it "with '0444' makes file readable but not writable or executable" do
- File.chmod(0444, @file)
- File.readable?(@file).should == true
- File.writable?(@file).should == false
- File.executable?(@file).should == false
+ as_user do
+ it "with '0222' makes file writable but not readable or executable" do
+ File.chmod(0222, @file)
+ File.readable?(@file).should == false
+ File.writable?(@file).should == true
+ File.executable?(@file).should == false
+ end
+
+ it "with '0444' makes file readable but not writable or executable" do
+ File.chmod(0444, @file)
+ File.readable?(@file).should == true
+ File.writable?(@file).should == false
+ File.executable?(@file).should == false
+ end
end
it "with '0666' makes file readable and writable but not executable" do
@@ -225,11 +169,13 @@ describe "File.chmod" do
File.executable?(@file).should == false
end
- it "with '0111' makes file executable but not readable or writable" do
- File.chmod(0111, @file)
- File.readable?(@file).should == false
- File.writable?(@file).should == false
- File.executable?(@file).should == true
+ as_user do
+ it "with '0111' makes file executable but not readable or writable" do
+ File.chmod(0111, @file)
+ File.readable?(@file).should == false
+ File.writable?(@file).should == false
+ File.executable?(@file).should == true
+ end
end
it "modifies the permission bits of the files specified" do
diff --git a/spec/ruby/core/file/chown_spec.rb b/spec/ruby/core/file/chown_spec.rb
index a0b46e9e39..8cc8f0d04b 100644
--- a/spec/ruby/core/file/chown_spec.rb
+++ b/spec/ruby/core/file/chown_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.chown" do
before :each do
@@ -66,7 +66,7 @@ describe "File.chown" do
platform_is_not :windows do
it "raises an error for a non existent path" do
- lambda {
+ -> {
File.chown(nil, nil, "#{@fname}_not_existing")
}.should raise_error(Errno::ENOENT)
end
@@ -91,17 +91,17 @@ describe "File#chown" do
as_superuser do
platform_is :windows do
it "does not modify the owner id of the file" do
- File.chown 0, nil, @fname
- File.stat(@fname).uid.should == 0
- File.chown 501, nil, @fname
- File.stat(@fname).uid.should == 0
+ @file.chown 0, nil
+ @file.stat.uid.should == 0
+ @file.chown 501, nil
+ @file.stat.uid.should == 0
end
it "does not modify the group id of the file" do
- File.chown nil, 0, @fname
- File.stat(@fname).gid.should == 0
- File.chown nil, 501, @fname
- File.stat(@fname).gid.should == 0
+ @file.chown nil, 0
+ @file.stat.gid.should == 0
+ @file.chown nil, 501
+ @file.stat.gid.should == 0
end
end
@@ -142,11 +142,3 @@ describe "File#chown" do
@file.chown(nil, nil).should == 0
end
end
-
-describe "File.chown" do
- it "needs to be reviewed for spec completeness"
-end
-
-describe "File#chown" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/file/constants/constants_spec.rb b/spec/ruby/core/file/constants/constants_spec.rb
index 3b2f67cc30..86946822c5 100644
--- a/spec/ruby/core/file/constants/constants_spec.rb
+++ b/spec/ruby/core/file/constants/constants_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../../spec_helper', __FILE__)
+require_relative '../../../spec_helper'
["APPEND", "CREAT", "EXCL", "FNM_CASEFOLD",
"FNM_DOTMATCH", "FNM_EXTGLOB", "FNM_NOESCAPE", "FNM_PATHNAME",
diff --git a/spec/ruby/core/file/constants_spec.rb b/spec/ruby/core/file/constants_spec.rb
index 0379149a18..5f058a7f40 100644
--- a/spec/ruby/core/file/constants_spec.rb
+++ b/spec/ruby/core/file/constants_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
# TODO: migrate these to constants/constants_spec.rb
diff --git a/spec/ruby/core/file/ctime_spec.rb b/spec/ruby/core/file/ctime_spec.rb
index c39775fcdd..b16eb13c1e 100644
--- a/spec/ruby/core/file/ctime_spec.rb
+++ b/spec/ruby/core/file/ctime_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.ctime" do
before :each do
@@ -14,7 +14,7 @@ describe "File.ctime" do
File.ctime(@file).should be_kind_of(Time)
end
- platform_is :linux do
+ platform_is :linux, :windows do
it "returns the change time for the named file (the time at which directory information about the file was changed, not the file itself) with microseconds." do
supports_subseconds = Integer(`stat -c%z '#{__FILE__}'`[/\.(\d+)/, 1], 10)
if supports_subseconds != 0
@@ -30,7 +30,7 @@ describe "File.ctime" do
end
it "raises an Errno::ENOENT exception if the file is not found" do
- lambda { File.ctime('bogus') }.should raise_error(Errno::ENOENT)
+ -> { File.ctime('bogus') }.should raise_error(Errno::ENOENT)
end
end
diff --git a/spec/ruby/core/file/delete_spec.rb b/spec/ruby/core/file/delete_spec.rb
index 2e903806d7..4098499942 100644
--- a/spec/ruby/core/file/delete_spec.rb
+++ b/spec/ruby/core/file/delete_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/unlink', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/unlink'
describe "File.delete" do
- it_behaves_like(:file_unlink, :delete)
+ it_behaves_like :file_unlink, :delete
end
diff --git a/spec/ruby/core/file/directory_spec.rb b/spec/ruby/core/file/directory_spec.rb
index d8e8b25121..8014a7a03d 100644
--- a/spec/ruby/core/file/directory_spec.rb
+++ b/spec/ruby/core/file/directory_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/directory', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/directory'
describe "File.directory?" do
it_behaves_like :file_directory, :directory?, File
diff --git a/spec/ruby/core/file/dirname_spec.rb b/spec/ruby/core/file/dirname_spec.rb
index f56f0806df..2ef04a7b64 100644
--- a/spec/ruby/core/file/dirname_spec.rb
+++ b/spec/ruby/core/file/dirname_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.dirname" do
it "returns all the components of filename except the last one" do
@@ -72,10 +72,10 @@ describe "File.dirname" do
end
it "raises a TypeError if not passed a String type" do
- lambda { File.dirname(nil) }.should raise_error(TypeError)
- lambda { File.dirname(0) }.should raise_error(TypeError)
- lambda { File.dirname(true) }.should raise_error(TypeError)
- lambda { File.dirname(false) }.should raise_error(TypeError)
+ -> { File.dirname(nil) }.should raise_error(TypeError)
+ -> { File.dirname(0) }.should raise_error(TypeError)
+ -> { File.dirname(true) }.should raise_error(TypeError)
+ -> { File.dirname(false) }.should raise_error(TypeError)
end
# Windows specific tests
diff --git a/spec/ruby/core/file/empty_spec.rb b/spec/ruby/core/file/empty_spec.rb
new file mode 100644
index 0000000000..77f132303e
--- /dev/null
+++ b/spec/ruby/core/file/empty_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../spec_helper'
+require_relative '../../shared/file/zero'
+
+describe "File.empty?" do
+ it_behaves_like :file_zero, :empty?, File
+ it_behaves_like :file_zero_missing, :empty?, File
+
+ platform_is :solaris do
+ it "returns false for /dev/null" do
+ File.empty?('/dev/null').should == true
+ end
+ end
+end
diff --git a/spec/ruby/core/file/executable_real_spec.rb b/spec/ruby/core/file/executable_real_spec.rb
index 24d6824169..0cb848b201 100644
--- a/spec/ruby/core/file/executable_real_spec.rb
+++ b/spec/ruby/core/file/executable_real_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/executable_real', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/executable_real'
describe "File.executable_real?" do
it_behaves_like :file_executable_real, :executable_real?, File
diff --git a/spec/ruby/core/file/executable_spec.rb b/spec/ruby/core/file/executable_spec.rb
index 82d6a81a0d..1dbb3b233d 100644
--- a/spec/ruby/core/file/executable_spec.rb
+++ b/spec/ruby/core/file/executable_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/executable', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/executable'
describe "File.executable?" do
it_behaves_like :file_executable, :executable?, File
diff --git a/spec/ruby/core/file/exist_spec.rb b/spec/ruby/core/file/exist_spec.rb
index 29a410c125..ddb5febcba 100644
--- a/spec/ruby/core/file/exist_spec.rb
+++ b/spec/ruby/core/file/exist_spec.rb
@@ -1,6 +1,6 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/exist', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/exist'
describe "File.exist?" do
- it_behaves_like(:file_exist, :exist?, File)
+ it_behaves_like :file_exist, :exist?, File
end
diff --git a/spec/ruby/core/file/exists_spec.rb b/spec/ruby/core/file/exists_spec.rb
deleted file mode 100644
index 70ebd12d86..0000000000
--- a/spec/ruby/core/file/exists_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/exist', __FILE__)
-
-describe "File.exists?" do
- it_behaves_like(:file_exist, :exists?, File)
-end
diff --git a/spec/ruby/core/file/expand_path_spec.rb b/spec/ruby/core/file/expand_path_spec.rb
index c57f323c4c..c31f885b92 100644
--- a/spec/ruby/core/file/expand_path_spec.rb
+++ b/spec/ruby/core/file/expand_path_spec.rb
@@ -1,7 +1,8 @@
# -*- encoding: utf-8 -*-
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require 'etc'
describe "File.expand_path" do
before :each do
@@ -18,14 +19,12 @@ describe "File.expand_path" do
end
end
- with_feature :encoding do
- before :each do
- @external = Encoding.default_external
- end
+ before :each do
+ @external = Encoding.default_external
+ end
- after :each do
- Encoding.default_external = @external
- end
+ after :each do
+ Encoding.default_external = @external
end
it "converts a pathname to an absolute pathname" do
@@ -56,39 +55,10 @@ describe "File.expand_path" do
File.expand_path(".", "#{@rootdir}").should == "#{@rootdir}"
end
- # FIXME: do not use conditionals like this around #it blocks
- unless not home = ENV['HOME']
- platform_is_not :windows do
- it "converts a pathname to an absolute pathname, using ~ (home) as base" do
- File.expand_path('~').should == home
- File.expand_path('~', '/tmp/gumby/ddd').should == home
- File.expand_path('~/a', '/tmp/gumby/ddd').should == File.join(home, 'a')
- end
-
- it "does not return a frozen string" do
- File.expand_path('~').frozen?.should == false
- File.expand_path('~', '/tmp/gumby/ddd').frozen?.should == false
- File.expand_path('~/a', '/tmp/gumby/ddd').frozen?.should == false
- end
- end
- platform_is :windows do
- it "converts a pathname to an absolute pathname, using ~ (home) as base" do
- File.expand_path('~').should == home.tr("\\", '/')
- File.expand_path('~', '/tmp/gumby/ddd').should == home.tr("\\", '/')
- File.expand_path('~/a', '/tmp/gumby/ddd').should == File.join(home.tr("\\", '/'), 'a')
- end
-
- it "does not return a frozen string" do
- File.expand_path('~').frozen?.should == false
- File.expand_path('~', '/tmp/gumby/ddd').frozen?.should == false
- File.expand_path('~/a', '/tmp/gumby/ddd').frozen?.should == false
- end
- end
- end
-
platform_is_not :windows do
before do
- @home = ENV['HOME'].chomp('/')
+ @var_home = ENV['HOME'].chomp('/')
+ @db_home = Dir.home(ENV['USER'])
end
# FIXME: these are insane!
@@ -100,17 +70,17 @@ describe "File.expand_path" do
File.expand_path("../bin", "x/../tmp").should == File.join(@base, 'bin')
end
- it "expand_path for commoms unix path give a full path" do
+ it "expand_path for common unix path gives a full path" do
File.expand_path('/tmp/').should =='/tmp'
File.expand_path('/tmp/../../../tmp').should == '/tmp'
File.expand_path('').should == Dir.pwd
File.expand_path('./////').should == Dir.pwd
File.expand_path('.').should == Dir.pwd
File.expand_path(Dir.pwd).should == Dir.pwd
- File.expand_path('~/').should == @home
- File.expand_path('~/..badfilename').should == "#{@home}/..badfilename"
- File.expand_path('..').should == Dir.pwd.split('/')[0...-1].join("/")
- File.expand_path('~/a','~/b').should == "#{@home}/a"
+ File.expand_path('~/').should == @var_home
+ File.expand_path('~/..badfilename').should == "#{@var_home}/..badfilename"
+ File.expand_path('~/a','~/b').should == "#{@var_home}/a"
+ File.expand_path('..').should == File.dirname(Dir.pwd)
end
it "does not replace multiple '/' at the beginning of the path" do
@@ -122,12 +92,15 @@ describe "File.expand_path" do
end
it "raises an ArgumentError if the path is not valid" do
- lambda { File.expand_path("~a_not_existing_user") }.should raise_error(ArgumentError)
+ -> { File.expand_path("~a_not_existing_user") }.should raise_error(ArgumentError)
end
it "expands ~ENV['USER'] to the user's home directory" do
- File.expand_path("~#{ENV['USER']}").should == @home
- File.expand_path("~#{ENV['USER']}/a").should == "#{@home}/a"
+ File.expand_path("~#{ENV['USER']}").should == @db_home
+ end
+
+ it "expands ~ENV['USER']/a to a in the user's home directory" do
+ File.expand_path("~#{ENV['USER']}/a").should == "#{@db_home}/a"
end
it "does not expand ~ENV['USER'] when it's not at the start" do
@@ -135,7 +108,7 @@ describe "File.expand_path" do
end
it "expands ../foo with ~/dir as base dir to /path/to/user/home/foo" do
- File.expand_path('../foo', '~/dir').should == "#{@home}/foo"
+ File.expand_path('../foo', '~/dir').should == "#{@var_home}/foo"
end
end
@@ -144,9 +117,9 @@ describe "File.expand_path" do
end
it "raises a TypeError if not passed a String type" do
- lambda { File.expand_path(1) }.should raise_error(TypeError)
- lambda { File.expand_path(nil) }.should raise_error(TypeError)
- lambda { File.expand_path(true) }.should raise_error(TypeError)
+ -> { File.expand_path(1) }.should raise_error(TypeError)
+ -> { File.expand_path(nil) }.should raise_error(TypeError)
+ -> { File.expand_path(true) }.should raise_error(TypeError)
end
platform_is_not :windows do
@@ -161,34 +134,32 @@ describe "File.expand_path" do
end
end
- with_feature :encoding do
- it "returns a String in the same encoding as the argument" do
- Encoding.default_external = Encoding::SHIFT_JIS
+ it "returns a String in the same encoding as the argument" do
+ Encoding.default_external = Encoding::SHIFT_JIS
- path = "./a".force_encoding Encoding::CP1251
- File.expand_path(path).encoding.should equal(Encoding::CP1251)
+ path = "./a".force_encoding Encoding::CP1251
+ File.expand_path(path).encoding.should equal(Encoding::CP1251)
- weird_path = [222, 173, 190, 175].pack('C*')
- File.expand_path(weird_path).encoding.should equal(Encoding::ASCII_8BIT)
- end
+ weird_path = [222, 173, 190, 175].pack('C*')
+ File.expand_path(weird_path).encoding.should equal(Encoding::BINARY)
+ end
- platform_is_not :windows do
- it "expands a path when the default external encoding is ASCII-8BIT" do
- Encoding.default_external = Encoding::ASCII_8BIT
- path_8bit = [222, 173, 190, 175].pack('C*')
- File.expand_path( path_8bit, @rootdir).should == "#{@rootdir}" + path_8bit
- end
+ platform_is_not :windows do
+ it "expands a path when the default external encoding is BINARY" do
+ Encoding.default_external = Encoding::BINARY
+ path_8bit = [222, 173, 190, 175].pack('C*')
+ File.expand_path( path_8bit, @rootdir).should == "#{@rootdir}" + path_8bit
end
+ end
- it "expands a path with multi-byte characters" do
- File.expand_path("Ångström").should == "#{@base}/Ångström"
- end
+ it "expands a path with multi-byte characters" do
+ File.expand_path("Ångström").should == "#{@base}/Ångström"
+ end
- platform_is_not :windows do
- it "raises an Encoding::CompatibilityError if the external encoding is not compatible" do
- Encoding.default_external = Encoding::UTF_16BE
- lambda { File.expand_path("./a") }.should raise_error(Encoding::CompatibilityError)
- end
+ platform_is_not :windows do
+ it "raises an Encoding::CompatibilityError if the external encoding is not compatible" do
+ Encoding.default_external = Encoding::UTF_16BE
+ -> { File.expand_path("./a") }.should raise_error(Encoding::CompatibilityError)
end
end
@@ -213,6 +184,32 @@ describe "File.expand_path" do
end
platform_is_not :windows do
+ describe "File.expand_path when HOME is set" do
+ before :each do
+ @home = ENV["HOME"]
+ ENV["HOME"] = "/rubyspec_home"
+ end
+
+ after :each do
+ ENV["HOME"] = @home
+ end
+
+ it "converts a pathname to an absolute pathname, using ~ (home) as base" do
+ home = "/rubyspec_home"
+ File.expand_path('~').should == home
+ File.expand_path('~', '/tmp/gumby/ddd').should == home
+ File.expand_path('~/a', '/tmp/gumby/ddd').should == File.join(home, 'a')
+ end
+
+ it "does not return a frozen string" do
+ home = "/rubyspec_home"
+ File.expand_path('~').should_not.frozen?
+ File.expand_path('~', '/tmp/gumby/ddd').should_not.frozen?
+ File.expand_path('~/a', '/tmp/gumby/ddd').should_not.frozen?
+ end
+ end
+
+
describe "File.expand_path when HOME is not set" do
before :each do
@home = ENV["HOME"]
@@ -222,21 +219,47 @@ platform_is_not :windows do
ENV["HOME"] = @home
end
- ruby_version_is ''...'2.4' do
- it "raises an ArgumentError when passed '~' if HOME is nil" do
+ guard -> {
+ # We need to check if getlogin(3) returns non-NULL,
+ # as MRI only checks getlogin(3) for expanding '~' if $HOME is not set.
+ user = ENV.delete("USER")
+ begin
+ Etc.getlogin != nil
+ rescue
+ false
+ ensure
+ ENV["USER"] = user
+ end
+ } do
+ it "uses the user database when passed '~' if HOME is nil" do
ENV.delete "HOME"
- lambda { File.expand_path("~") }.should raise_error(ArgumentError)
+ File.directory?(File.expand_path("~")).should == true
end
- it "raises an ArgumentError when passed '~/' if HOME is nil" do
+ it "uses the user database when passed '~/' if HOME is nil" do
ENV.delete "HOME"
- lambda { File.expand_path("~/") }.should raise_error(ArgumentError)
+ File.directory?(File.expand_path("~/")).should == true
end
end
it "raises an ArgumentError when passed '~' if HOME == ''" do
ENV["HOME"] = ""
- lambda { File.expand_path("~") }.should raise_error(ArgumentError)
+ -> { File.expand_path("~") }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe "File.expand_path with a non-absolute HOME" do
+ before :each do
+ @home = ENV["HOME"]
+ end
+
+ after :each do
+ ENV["HOME"] = @home
+ end
+
+ it "raises an ArgumentError" do
+ ENV["HOME"] = "non-absolute"
+ -> { File.expand_path("~") }.should raise_error(ArgumentError, 'non-absolute home')
end
end
end
diff --git a/spec/ruby/core/file/extname_spec.rb b/spec/ruby/core/file/extname_spec.rb
index fedd4fc89f..e182ed44f2 100644
--- a/spec/ruby/core/file/extname_spec.rb
+++ b/spec/ruby/core/file/extname_spec.rb
@@ -1,8 +1,8 @@
# -*- encoding: utf-8 -*-
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.extname" do
- it "returns the extension (the portion of file name in path after the period)." do
+ it "returns the extension (the portion of file name in path after the period)" do
File.extname("foo.rb").should == ".rb"
File.extname("/foo/bar.rb").should == ".rb"
File.extname("/foo.rb/bar.c").should == ".c"
@@ -12,7 +12,17 @@ describe "File.extname" do
File.extname(".app.conf").should == ".conf"
end
- it "returns the extension (the portion of file name in path after the period).(edge cases)" do
+ it "returns unfrozen strings" do
+ File.extname("foo.rb").frozen?.should == false
+ File.extname("/foo/bar.rb").frozen?.should == false
+ File.extname("/foo.rb/bar.c").frozen?.should == false
+ File.extname("bar").frozen?.should == false
+ File.extname(".bashrc").frozen?.should == false
+ File.extname("/foo.bar/baz").frozen?.should == false
+ File.extname(".app.conf").frozen?.should == false
+ end
+
+ it "returns the extension for edge cases" do
File.extname("").should == ""
File.extname(".").should == ""
File.extname("/").should == ""
@@ -20,8 +30,22 @@ describe "File.extname" do
File.extname("..").should == ""
File.extname("...").should == ""
File.extname("....").should == ""
- File.extname(".foo.").should == ""
- File.extname("foo.").should == ""
+ end
+
+ describe "for a filename ending with a dot" do
+ guard -> { platform_is :windows or ruby_version_is ""..."2.7" } do
+ it "returns ''" do
+ File.extname(".foo.").should == ""
+ File.extname("foo.").should == ""
+ end
+ end
+
+ guard -> { platform_is_not :windows and ruby_version_is "2.7" } do
+ it "returns '.'" do
+ File.extname(".foo.").should == "."
+ File.extname("foo.").should == "."
+ end
+ end
end
it "returns only the last extension of a file with several dots" do
@@ -33,22 +57,20 @@ describe "File.extname" do
end
it "raises a TypeError if not passed a String type" do
- lambda { File.extname(nil) }.should raise_error(TypeError)
- lambda { File.extname(0) }.should raise_error(TypeError)
- lambda { File.extname(true) }.should raise_error(TypeError)
- lambda { File.extname(false) }.should raise_error(TypeError)
+ -> { File.extname(nil) }.should raise_error(TypeError)
+ -> { File.extname(0) }.should raise_error(TypeError)
+ -> { File.extname(true) }.should raise_error(TypeError)
+ -> { File.extname(false) }.should raise_error(TypeError)
end
it "raises an ArgumentError if not passed one argument" do
- lambda { File.extname }.should raise_error(ArgumentError)
- lambda { File.extname("foo.bar", "foo.baz") }.should raise_error(ArgumentError)
+ -> { File.extname }.should raise_error(ArgumentError)
+ -> { File.extname("foo.bar", "foo.baz") }.should raise_error(ArgumentError)
end
- with_feature :encoding do
-
- it "returns the extension for a multibyte filename" do
- File.extname('ИмÑ.m4a').should == ".m4a"
- end
+ it "returns the extension for a multibyte filename" do
+ File.extname('ИмÑ.m4a').should == ".m4a"
end
+
end
diff --git a/spec/ruby/core/file/file_spec.rb b/spec/ruby/core/file/file_spec.rb
index 99eaacd086..8a9dfd5fe2 100644
--- a/spec/ruby/core/file/file_spec.rb
+++ b/spec/ruby/core/file/file_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/file', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/file'
describe "File" do
it "includes Enumerable" do
diff --git a/spec/ruby/core/file/fixtures/file_types.rb b/spec/ruby/core/file/fixtures/file_types.rb
index 36a5ff1a95..109bcfe42e 100644
--- a/spec/ruby/core/file/fixtures/file_types.rb
+++ b/spec/ruby/core/file/fixtures/file_types.rb
@@ -5,17 +5,11 @@ module FileSpecs
@file = tmp("test.txt")
@dir = Dir.pwd
@fifo = tmp("test_fifo")
+ @link = tmp("test_link")
platform_is_not :windows do
- @block = `find /dev /devices -type b 2> /dev/null`.split("\n").first
- @char = `find /dev /devices -type c 2> /dev/null`.split("\n").last
-
- %w[/dev /usr/bin /usr/local/bin].each do |dir|
- links = `find #{dir} -type l 2> /dev/null`.split("\n")
- next if links.empty?
- @link = links.first
- break
- end
+ @block = `find /dev /devices -type b 2>/dev/null`.split("\n").first
+ @char = `{ tty || find /dev /devices -type c; } 2>/dev/null`.split("\n").last
end
@configured = true
@@ -32,33 +26,41 @@ module FileSpecs
yield @dir
end
- # TODO: need a platform-independent helper here
def self.fifo
- system "mkfifo #{@fifo} 2> /dev/null"
+ File.mkfifo(@fifo)
yield @fifo
ensure
rm_r @fifo
end
def self.block_device
+ raise "Could not find a block device" unless @block
yield @block
end
def self.character_device
+ raise "Could not find a character device" unless @char
yield @char
end
def self.symlink
+ touch(@file)
+ File.symlink(@file, @link)
yield @link
+ ensure
+ rm_r @file, @link
end
def self.socket
- require 'socket'
- name = tmp("ftype_socket.socket")
- rm_r name
+ require_relative '../../../library/socket/fixtures/classes.rb'
+
+ name = SocketSpecs.socket_path
socket = UNIXServer.new name
- yield name
- socket.close
- rm_r name
+ begin
+ yield name
+ ensure
+ socket.close
+ rm_r name
+ end
end
end
diff --git a/spec/ruby/core/file/flock_spec.rb b/spec/ruby/core/file/flock_spec.rb
index e14d4252d4..751e99d994 100644
--- a/spec/ruby/core/file/flock_spec.rb
+++ b/spec/ruby/core/file/flock_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File#flock" do
before :each do
@@ -92,13 +92,13 @@ platform_is :solaris do
end
it "fails with EBADF acquiring exclusive lock on read-only File" do
- lambda do
+ -> do
@read_file.flock File::LOCK_EX
end.should raise_error(Errno::EBADF)
end
it "fails with EBADF acquiring shared lock on read-only File" do
- lambda do
+ -> do
@write_file.flock File::LOCK_SH
end.should raise_error(Errno::EBADF)
end
diff --git a/spec/ruby/core/file/fnmatch_spec.rb b/spec/ruby/core/file/fnmatch_spec.rb
index 8a4caacfb8..a1b7fa12b3 100644
--- a/spec/ruby/core/file/fnmatch_spec.rb
+++ b/spec/ruby/core/file/fnmatch_spec.rb
@@ -1,10 +1,10 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/fnmatch', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/fnmatch'
describe "File.fnmatch" do
- it_behaves_like(:file_fnmatch, :fnmatch)
+ it_behaves_like :file_fnmatch, :fnmatch
end
describe "File.fnmatch?" do
- it_behaves_like(:file_fnmatch, :fnmatch?)
+ it_behaves_like :file_fnmatch, :fnmatch?
end
diff --git a/spec/ruby/core/file/ftype_spec.rb b/spec/ruby/core/file/ftype_spec.rb
index 7c010b3e9c..cdddc404dc 100644
--- a/spec/ruby/core/file/ftype_spec.rb
+++ b/spec/ruby/core/file/ftype_spec.rb
@@ -1,5 +1,5 @@
-require "#{File.dirname(__FILE__)}/../../spec_helper"
-require "#{File.dirname(__FILE__)}/fixtures/file_types"
+require_relative '../../spec_helper'
+require_relative 'fixtures/file_types'
describe "File.ftype" do
before :all do
@@ -7,13 +7,14 @@ describe "File.ftype" do
end
it "raises ArgumentError if not given exactly one filename" do
- lambda { File.ftype }.should raise_error(ArgumentError)
- lambda { File.ftype('blah', 'bleh') }.should raise_error(ArgumentError)
+ -> { File.ftype }.should raise_error(ArgumentError)
+ -> { File.ftype('blah', 'bleh') }.should raise_error(ArgumentError)
end
it "raises Errno::ENOENT if the file is not valid" do
- l = lambda { File.ftype("/#{$$}#{Time.now.to_f}") }
- l.should raise_error(Errno::ENOENT)
+ -> {
+ File.ftype("/#{$$}#{Time.now.to_f}")
+ }.should raise_error(Errno::ENOENT)
end
it "returns a String" do
@@ -34,6 +35,14 @@ describe "File.ftype" do
end
end
+ it "uses to_path to convert arguments" do
+ FileSpecs.normal_file do |file|
+ obj = mock('path')
+ obj.should_receive(:to_path).and_return(file)
+ File.ftype(obj).should == 'file'
+ end
+ end
+
# Both FreeBSD and Windows does not have block devices
platform_is_not :freebsd, :windows do
with_block_device do
diff --git a/spec/ruby/core/file/grpowned_spec.rb b/spec/ruby/core/file/grpowned_spec.rb
index 0b5514d7ca..8ddac5237c 100644
--- a/spec/ruby/core/file/grpowned_spec.rb
+++ b/spec/ruby/core/file/grpowned_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/grpowned', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/grpowned'
describe "File.grpowned?" do
it_behaves_like :file_grpowned, :grpowned?, File
diff --git a/spec/ruby/core/file/identical_spec.rb b/spec/ruby/core/file/identical_spec.rb
index 303337b62d..bbeaef24d2 100644
--- a/spec/ruby/core/file/identical_spec.rb
+++ b/spec/ruby/core/file/identical_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/identical', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/identical'
describe "File.identical?" do
it_behaves_like :file_identical, :identical?, File
diff --git a/spec/ruby/core/file/initialize_spec.rb b/spec/ruby/core/file/initialize_spec.rb
index 269e13b3ca..9a76a95260 100644
--- a/spec/ruby/core/file/initialize_spec.rb
+++ b/spec/ruby/core/file/initialize_spec.rb
@@ -1,8 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-
-describe "File#initialize" do
- it "needs to be reviewed for spec completeness"
-end
+require_relative '../../spec_helper'
describe "File#initialize" do
after :each do
diff --git a/spec/ruby/core/file/inspect_spec.rb b/spec/ruby/core/file/inspect_spec.rb
index a059fa2c48..148e789c62 100644
--- a/spec/ruby/core/file/inspect_spec.rb
+++ b/spec/ruby/core/file/inspect_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File#inspect" do
before :each do
diff --git a/spec/ruby/core/file/join_spec.rb b/spec/ruby/core/file/join_spec.rb
index 7c5955d03b..0feedbae93 100644
--- a/spec/ruby/core/file/join_spec.rb
+++ b/spec/ruby/core/file/join_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.join" do
# see [ruby-core:46804] for the 4 following rules
@@ -104,15 +104,15 @@ describe "File.join" do
it "raises an ArgumentError if passed a recursive array" do
a = ["a"]
a << a
- lambda { File.join a }.should raise_error(ArgumentError)
+ -> { File.join a }.should raise_error(ArgumentError)
end
it "raises a TypeError exception when args are nil" do
- lambda { File.join nil }.should raise_error(TypeError)
+ -> { File.join nil }.should raise_error(TypeError)
end
it "calls #to_str" do
- lambda { File.join(mock('x')) }.should raise_error(TypeError)
+ -> { File.join(mock('x')) }.should raise_error(TypeError)
bin = mock("bin")
bin.should_receive(:to_str).exactly(:twice).and_return("bin")
@@ -129,11 +129,20 @@ describe "File.join" do
end
it "calls #to_path" do
- lambda { File.join(mock('x')) }.should raise_error(TypeError)
+ -> { File.join(mock('x')) }.should raise_error(TypeError)
bin = mock("bin")
bin.should_receive(:to_path).exactly(:twice).and_return("bin")
File.join(bin).should == "bin"
File.join("usr", bin).should == "usr/bin"
end
+
+ it "raises errors for null bytes" do
+ -> { File.join("\x00x", "metadata.gz") }.should raise_error(ArgumentError) { |e|
+ e.message.should == 'string contains null byte'
+ }
+ -> { File.join("metadata.gz", "\x00x") }.should raise_error(ArgumentError) { |e|
+ e.message.should == 'string contains null byte'
+ }
+ end
end
diff --git a/spec/ruby/core/file/lchmod_spec.rb b/spec/ruby/core/file/lchmod_spec.rb
index 2ce265841e..7420b95e4a 100644
--- a/spec/ruby/core/file/lchmod_spec.rb
+++ b/spec/ruby/core/file/lchmod_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.lchmod" do
platform_is_not :linux, :windows, :openbsd, :solaris, :aix do
@@ -20,23 +20,13 @@ describe "File.lchmod" do
File.chmod(0222, @lname).should == 1
File.lchmod(0755, @lname).should == 1
- File.lstat(@lname).executable?.should == true
- File.lstat(@lname).readable?.should == true
- File.lstat(@lname).writable?.should == true
+ File.lstat(@lname).should.executable?
+ File.lstat(@lname).should.readable?
+ File.lstat(@lname).should.writable?
- File.stat(@lname).executable?.should == false
- File.stat(@lname).readable?.should == false
- File.stat(@lname).writable?.should == true
- end
- end
-
- platform_is :linux, :openbsd, :aix do
- it "returns false from #respond_to?" do
- File.respond_to?(:lchmod).should be_false
- end
-
- it "raises a NotImplementedError when called" do
- lambda { File.lchmod 0 }.should raise_error(NotImplementedError)
+ File.stat(@lname).should_not.executable?
+ File.stat(@lname).should_not.readable?
+ File.stat(@lname).should.writable?
end
end
end
diff --git a/spec/ruby/core/file/lchown_spec.rb b/spec/ruby/core/file/lchown_spec.rb
index 814b0bf534..8d95d287ba 100644
--- a/spec/ruby/core/file/lchown_spec.rb
+++ b/spec/ruby/core/file/lchown_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
as_superuser do
describe "File.lchown" do
@@ -57,7 +57,3 @@ as_superuser do
end
end
end
-
-describe "File.lchown" do
- it "needs to be reviewed for spec completeness"
-end
diff --git a/spec/ruby/core/file/link_spec.rb b/spec/ruby/core/file/link_spec.rb
index 69d1459672..a5d5b4815f 100644
--- a/spec/ruby/core/file/link_spec.rb
+++ b/spec/ruby/core/file/link_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.link" do
before :each do
@@ -13,27 +13,27 @@ describe "File.link" do
rm_r @link, @file
end
- platform_is_not :windows do
+ platform_is_not :windows, :android do
it "link a file with another" do
File.link(@file, @link).should == 0
- File.exist?(@link).should == true
+ File.should.exist?(@link)
File.identical?(@file, @link).should == true
end
it "raises an Errno::EEXIST if the target already exists" do
File.link(@file, @link)
- lambda { File.link(@file, @link) }.should raise_error(Errno::EEXIST)
+ -> { File.link(@file, @link) }.should raise_error(Errno::EEXIST)
end
it "raises an ArgumentError if not passed two arguments" do
- lambda { File.link }.should raise_error(ArgumentError)
- lambda { File.link(@file) }.should raise_error(ArgumentError)
- lambda { File.link(@file, @link, @file) }.should raise_error(ArgumentError)
+ -> { File.link }.should raise_error(ArgumentError)
+ -> { File.link(@file) }.should raise_error(ArgumentError)
+ -> { File.link(@file, @link, @file) }.should raise_error(ArgumentError)
end
it "raises a TypeError if not passed String types" do
- lambda { File.link(@file, nil) }.should raise_error(TypeError)
- lambda { File.link(@file, 1) }.should raise_error(TypeError)
+ -> { File.link(@file, nil) }.should raise_error(TypeError)
+ -> { File.link(@file, 1) }.should raise_error(TypeError)
end
end
end
diff --git a/spec/ruby/core/file/lstat_spec.rb b/spec/ruby/core/file/lstat_spec.rb
index 6657bfa00e..a5ea9d15a5 100644
--- a/spec/ruby/core/file/lstat_spec.rb
+++ b/spec/ruby/core/file/lstat_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/stat', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/stat'
describe "File.lstat" do
it_behaves_like :file_stat, :lstat
@@ -22,8 +22,8 @@ describe "File.lstat" do
it "returns a File::Stat object with symlink properties for a symlink" do
st = File.lstat(@link)
- st.symlink?.should == true
- st.file?.should == false
+ st.should.symlink?
+ st.should_not.file?
end
end
end
diff --git a/spec/ruby/core/file/lutime_spec.rb b/spec/ruby/core/file/lutime_spec.rb
new file mode 100644
index 0000000000..1f0625f61e
--- /dev/null
+++ b/spec/ruby/core/file/lutime_spec.rb
@@ -0,0 +1,38 @@
+require_relative '../../spec_helper'
+
+describe "File.lutime" do
+ platform_is_not :windows do
+ before :each do
+ @atime = Time.utc(2000)
+ @mtime = Time.utc(2001)
+ @file = tmp("specs_lutime_file")
+ @symlink = tmp("specs_lutime_symlink")
+ touch @file
+ File.symlink(@file, @symlink)
+ end
+
+ after :each do
+ rm_r @file, @symlink
+ end
+
+ it "sets the access and modification time for a regular file" do
+ File.lutime(@atime, @mtime, @file)
+ stat = File.stat(@file)
+ stat.atime.should == @atime
+ stat.mtime.should === @mtime
+ end
+
+ it "sets the access and modification time for a symlink" do
+ original = File.stat(@file)
+
+ File.lutime(@atime, @mtime, @symlink)
+ stat = File.lstat(@symlink)
+ stat.atime.should == @atime
+ stat.mtime.should === @mtime
+
+ file = File.stat(@file)
+ file.atime.should == original.atime
+ file.mtime.should == original.mtime
+ end
+ end
+end
diff --git a/spec/ruby/core/file/mkfifo_spec.rb b/spec/ruby/core/file/mkfifo_spec.rb
index ad6e804b99..19298c967c 100644
--- a/spec/ruby/core/file/mkfifo_spec.rb
+++ b/spec/ruby/core/file/mkfifo_spec.rb
@@ -1,53 +1,51 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
-ruby_version_is "2.3" do
- describe "File.mkfifo" do
- platform_is_not :windows do
- before do
- @path = tmp('fifo')
- end
+describe "File.mkfifo" do
+ platform_is_not :windows do
+ before do
+ @path = tmp('fifo')
+ end
- after do
- rm_r(@path)
- end
+ after do
+ rm_r(@path)
+ end
- context "when path passed responds to :to_path" do
- it "creates a FIFO file at the path specified" do
- File.mkfifo(@path)
- File.ftype(@path).should == "fifo"
- end
+ context "when path passed responds to :to_path" do
+ it "creates a FIFO file at the path specified" do
+ File.mkfifo(@path)
+ File.ftype(@path).should == "fifo"
end
+ end
- context "when path passed is not a String value" do
- it "raises a TypeError" do
- lambda { File.mkfifo(:"/tmp/fifo") }.should raise_error(TypeError)
- end
+ context "when path passed is not a String value" do
+ it "raises a TypeError" do
+ -> { File.mkfifo(:"/tmp/fifo") }.should raise_error(TypeError)
end
+ end
- context "when path does not exist" do
- it "raises an Errno::ENOENT exception" do
- lambda { File.mkfifo("/bogus/path") }.should raise_error(Errno::ENOENT)
- end
+ context "when path does not exist" do
+ it "raises an Errno::ENOENT exception" do
+ -> { File.mkfifo("/bogus/path") }.should raise_error(Errno::ENOENT)
end
+ end
- it "creates a FIFO file at the passed path" do
- File.mkfifo(@path.to_s)
- File.ftype(@path).should == "fifo"
- end
+ it "creates a FIFO file at the passed path" do
+ File.mkfifo(@path.to_s)
+ File.ftype(@path).should == "fifo"
+ end
- it "creates a FIFO file with passed mode & ~umask" do
- File.mkfifo(@path, 0755)
- File.stat(@path).mode.should == 010755 & ~File.umask
- end
+ it "creates a FIFO file with passed mode & ~umask" do
+ File.mkfifo(@path, 0755)
+ File.stat(@path).mode.should == 010755 & ~File.umask
+ end
- it "creates a FIFO file with a default mode of 0666 & ~umask" do
- File.mkfifo(@path)
- File.stat(@path).mode.should == 010666 & ~File.umask
- end
+ it "creates a FIFO file with a default mode of 0666 & ~umask" do
+ File.mkfifo(@path)
+ File.stat(@path).mode.should == 010666 & ~File.umask
+ end
- it "returns 0 after creating the FIFO file" do
- File.mkfifo(@path).should == 0
- end
+ it "returns 0 after creating the FIFO file" do
+ File.mkfifo(@path).should == 0
end
end
end
diff --git a/spec/ruby/core/file/mtime_spec.rb b/spec/ruby/core/file/mtime_spec.rb
index 56b7e4464e..8d47d3021a 100644
--- a/spec/ruby/core/file/mtime_spec.rb
+++ b/spec/ruby/core/file/mtime_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File.mtime" do
before :each do
@@ -12,10 +12,10 @@ describe "File.mtime" do
it "returns the modification Time of the file" do
File.mtime(@filename).should be_kind_of(Time)
- File.mtime(@filename).should be_close(@mtime, 2.0)
+ File.mtime(@filename).should be_close(@mtime, TIME_TOLERANCE)
end
- platform_is :linux do
+ platform_is :linux, :windows do
it "returns the modification Time of the file with microseconds" do
supports_subseconds = Integer(`stat -c%y '#{__FILE__}'`[/\.(\d+)/, 1], 10)
if supports_subseconds != 0
@@ -29,7 +29,7 @@ describe "File.mtime" do
end
it "raises an Errno::ENOENT exception if the file is not found" do
- lambda { File.mtime('bogus') }.should raise_error(Errno::ENOENT)
+ -> { File.mtime('bogus') }.should raise_error(Errno::ENOENT)
end
end
diff --git a/spec/ruby/core/file/new_spec.rb b/spec/ruby/core/file/new_spec.rb
index 3c72ac48e5..004f78503a 100644
--- a/spec/ruby/core/file/new_spec.rb
+++ b/spec/ruby/core/file/new_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/open', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/open'
describe "File.new" do
before :each do
@@ -17,13 +17,13 @@ describe "File.new" do
it "returns a new File with mode string" do
@fh = File.new(@file, 'w')
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "returns a new File with mode num" do
@fh = File.new(@file, @flags)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "returns a new File with modus num and permissions" do
@@ -34,21 +34,21 @@ describe "File.new" do
platform_is_not :windows do
File.stat(@file).mode.to_s(8).should == "100744"
end
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "creates the file and returns writable descriptor when called with 'w' mode and r-o permissions" do
- # it should be possible to write to such a file via returned descriptior,
+ # it should be possible to write to such a file via returned descriptor,
# even though the file permissions are r-r-r.
rm_r @file
begin
f = File.new(@file, "w", 0444)
- lambda { f.puts("test") }.should_not raise_error(IOError)
+ -> { f.puts("test") }.should_not raise_error(IOError)
ensure
f.close
end
- File.exist?(@file).should == true
+ File.should.exist?(@file)
File.read(@file).should == "test\n"
end
@@ -75,81 +75,81 @@ describe "File.new" do
fh_copy = File.new(@fh.fileno)
fh_copy.autoclose = false
fh_copy.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "creates a new file when use File::EXCL mode" do
@fh = File.new(@file, File::EXCL)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "raises an Errorno::EEXIST if the file exists when create a new file with File::CREAT|File::EXCL" do
- lambda { @fh = File.new(@file, File::CREAT|File::EXCL) }.should raise_error(Errno::EEXIST)
+ -> { @fh = File.new(@file, File::CREAT|File::EXCL) }.should raise_error(Errno::EEXIST)
end
it "creates a new file when use File::WRONLY|File::APPEND mode" do
@fh = File.new(@file, File::WRONLY|File::APPEND)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "returns a new File when use File::APPEND mode" do
@fh = File.new(@file, File::APPEND)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "returns a new File when use File::RDONLY|File::APPEND mode" do
@fh = File.new(@file, File::RDONLY|File::APPEND)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "returns a new File when use File::RDONLY|File::WRONLY mode" do
@fh = File.new(@file, File::RDONLY|File::WRONLY)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "creates a new file when use File::WRONLY|File::TRUNC mode" do
@fh = File.new(@file, File::WRONLY|File::TRUNC)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "coerces filename using to_str" do
name = mock("file")
name.should_receive(:to_str).and_return(@file)
@fh = File.new(name, "w")
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "coerces filename using #to_path" do
name = mock("file")
name.should_receive(:to_path).and_return(@file)
@fh = File.new(name, "w")
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "raises a TypeError if the first parameter can't be coerced to a string" do
- lambda { File.new(true) }.should raise_error(TypeError)
- lambda { File.new(false) }.should raise_error(TypeError)
+ -> { File.new(true) }.should raise_error(TypeError)
+ -> { File.new(false) }.should raise_error(TypeError)
end
it "raises a TypeError if the first parameter is nil" do
- lambda { File.new(nil) }.should raise_error(TypeError)
+ -> { File.new(nil) }.should raise_error(TypeError)
end
it "raises an Errno::EBADF if the first parameter is an invalid file descriptor" do
- lambda { File.new(-1) }.should raise_error(Errno::EBADF)
+ -> { File.new(-1) }.should raise_error(Errno::EBADF)
end
platform_is_not :windows do
it "can't alter mode or permissions when opening a file" do
@fh = File.new(@file)
- lambda {
+ -> {
f = File.new(@fh.fileno, @flags)
f.autoclose = false
}.should raise_error(Errno::EINVAL)
diff --git a/spec/ruby/core/file/null_spec.rb b/spec/ruby/core/file/null_spec.rb
index b9dd6b658b..355b72b799 100644
--- a/spec/ruby/core/file/null_spec.rb
+++ b/spec/ruby/core/file/null_spec.rb
@@ -1,4 +1,4 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
describe "File::NULL" do
platform_is :windows do
diff --git a/spec/ruby/core/file/open_spec.rb b/spec/ruby/core/file/open_spec.rb
index 440921a796..8faa31173e 100644
--- a/spec/ruby/core/file/open_spec.rb
+++ b/spec/ruby/core/file/open_spec.rb
@@ -1,8 +1,8 @@
# encoding: utf-8
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/common', __FILE__)
-require File.expand_path('../shared/open', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/common'
+require_relative 'shared/open'
describe "File.open" do
before :all do
@@ -28,7 +28,7 @@ describe "File.open" do
describe "with a block" do
it "does not raise error when file is closed inside the block" do
@fh = File.open(@file) { |fh| fh.close; fh }
- @fh.closed?.should == true
+ @fh.should.closed?
end
it "invokes close on an opened file when exiting the block" do
@@ -38,7 +38,7 @@ describe "File.open" do
end
it "propagates non-StandardErrors produced by close" do
- lambda {
+ -> {
File.open(@file, 'r') { |f| FileSpecs.make_closer f, Exception }
}.should raise_error(Exception)
@@ -46,7 +46,7 @@ describe "File.open" do
end
it "propagates StandardErrors produced by close" do
- lambda {
+ -> {
File.open(@file, 'r') { |f| FileSpecs.make_closer f, StandardError }
}.should raise_error(StandardError)
@@ -63,40 +63,40 @@ describe "File.open" do
it "opens the file (basic case)" do
@fh = File.open(@file)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens the file with unicode characters" do
@fh = File.open(@unicode_path, "w")
@fh.should be_kind_of(File)
- File.exist?(@unicode_path).should == true
+ File.should.exist?(@unicode_path)
end
it "opens a file when called with a block" do
File.open(@file) { |fh| }
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens with mode string" do
@fh = File.open(@file, 'w')
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file with mode string and block" do
File.open(@file, 'w') { |fh| }
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file with mode num" do
@fh = File.open(@file, @flags)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file with mode num and block" do
File.open(@file, 'w') { |fh| }
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file with mode and permission as nil" do
@@ -113,7 +113,7 @@ describe "File.open" do
platform_is_not :windows do
@fh.lstat.mode.to_s(8).should == "100744"
end
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
# For this test we delete the file first to reset the perms
@@ -124,11 +124,11 @@ describe "File.open" do
platform_is_not :windows do
File.stat(@file).mode.to_s(8).should == "100755"
end
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "creates the file and returns writable descriptor when called with 'w' mode and r-o permissions" do
- # it should be possible to write to such a file via returned descriptior,
+ # it should be possible to write to such a file via returned descriptor,
# even though the file permissions are r-r-r.
File.open(@file, "w", 0444) { |f| f.write("test") }
@@ -147,11 +147,13 @@ describe "File.open" do
end
platform_is_not :windows do
- it "creates a new write-only file when invoked with 'w' and '0222'" do
- rm_r @file
- File.open(@file, 'w', 0222) {}
- File.readable?(@file).should == false
- File.writable?(@file).should == true
+ as_user do
+ it "creates a new write-only file when invoked with 'w' and '0222'" do
+ rm_r @file
+ File.open(@file, 'w', 0222) {}
+ File.readable?(@file).should == false
+ File.writable?(@file).should == true
+ end
end
end
@@ -160,83 +162,68 @@ describe "File.open" do
fh_copy = File.open(@fh.fileno)
fh_copy.autoclose = false
fh_copy.should be_kind_of(File)
- File.exist?(@file).should == true
- end
-
- it "opens a file with a file descriptor d and a block" do
- @fh = File.open(@file)
- @fh.should be_kind_of(File)
-
- lambda {
- File.open(@fh.fileno) do |fh|
- @fd = fh.fileno
- @fh.close
- end
- }.should raise_error(Errno::EBADF)
- lambda { File.open(@fd) }.should raise_error(Errno::EBADF)
-
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file that no exists when use File::WRONLY mode" do
- lambda { File.open(@nonexistent, File::WRONLY) }.should raise_error(Errno::ENOENT)
+ -> { File.open(@nonexistent, File::WRONLY) }.should raise_error(Errno::ENOENT)
end
it "opens a file that no exists when use File::RDONLY mode" do
- lambda { File.open(@nonexistent, File::RDONLY) }.should raise_error(Errno::ENOENT)
+ -> { File.open(@nonexistent, File::RDONLY) }.should raise_error(Errno::ENOENT)
end
it "opens a file that no exists when use 'r' mode" do
- lambda { File.open(@nonexistent, 'r') }.should raise_error(Errno::ENOENT)
+ -> { File.open(@nonexistent, 'r') }.should raise_error(Errno::ENOENT)
end
it "opens a file that no exists when use File::EXCL mode" do
- lambda { File.open(@nonexistent, File::EXCL) }.should raise_error(Errno::ENOENT)
+ -> { File.open(@nonexistent, File::EXCL) }.should raise_error(Errno::ENOENT)
end
it "opens a file that no exists when use File::NONBLOCK mode" do
- lambda { File.open(@nonexistent, File::NONBLOCK) }.should raise_error(Errno::ENOENT)
+ -> { File.open(@nonexistent, File::NONBLOCK) }.should raise_error(Errno::ENOENT)
end
platform_is_not :openbsd, :windows do
it "opens a file that no exists when use File::TRUNC mode" do
- lambda { File.open(@nonexistent, File::TRUNC) }.should raise_error(Errno::ENOENT)
+ -> { File.open(@nonexistent, File::TRUNC) }.should raise_error(Errno::ENOENT)
end
end
platform_is :openbsd, :windows do
it "does not open a file that does no exists when using File::TRUNC mode" do
- lambda { File.open(@nonexistent, File::TRUNC) }.should raise_error(Errno::EINVAL)
+ -> { File.open(@nonexistent, File::TRUNC) }.should raise_error(Errno::EINVAL)
end
end
platform_is_not :windows do
it "opens a file that no exists when use File::NOCTTY mode" do
- lambda { File.open(@nonexistent, File::NOCTTY) }.should raise_error(Errno::ENOENT)
+ -> { File.open(@nonexistent, File::NOCTTY) }.should raise_error(Errno::ENOENT)
end
end
it "opens a file that no exists when use File::CREAT mode" do
@fh = File.open(@nonexistent, File::CREAT) { |f| f }
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file that no exists when use 'a' mode" do
@fh = File.open(@nonexistent, 'a') { |f| f }
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file that no exists when use 'w' mode" do
@fh = File.open(@nonexistent, 'w') { |f| f }
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
- # Check the grants associated to the differents open modes combinations.
+ # Check the grants associated to the different open modes combinations.
it "raises an ArgumentError exception when call with an unknown mode" do
- lambda { File.open(@file, "q") }.should raise_error(ArgumentError)
+ -> { File.open(@file, "q") }.should raise_error(ArgumentError)
end
it "can read in a block when call open with RDONLY mode" do
@@ -253,13 +240,13 @@ describe "File.open" do
it "raises an IO exception when write in a block opened with RDONLY mode" do
File.open(@file, File::RDONLY) do |f|
- lambda { f.puts "writing ..." }.should raise_error(IOError)
+ -> { f.puts "writing ..." }.should raise_error(IOError)
end
end
it "raises an IO exception when write in a block opened with 'r' mode" do
File.open(@file, "r") do |f|
- lambda { f.puts "writing ..." }.should raise_error(IOError)
+ -> { f.puts "writing ..." }.should raise_error(IOError)
end
end
@@ -270,7 +257,7 @@ describe "File.open" do
end
it "can't read in a block when call open with File::WRONLY||File::RDONLY mode" do
- lambda {
+ -> {
File.open(@file, File::WRONLY|File::RDONLY ) do |f|
f.gets.should == nil
end
@@ -291,44 +278,44 @@ describe "File.open" do
it "raises an IOError when read in a block opened with WRONLY mode" do
File.open(@file, File::WRONLY) do |f|
- lambda { f.gets }.should raise_error(IOError)
+ -> { f.gets }.should raise_error(IOError)
end
end
it "raises an IOError when read in a block opened with 'w' mode" do
File.open(@file, "w") do |f|
- lambda { f.gets }.should raise_error(IOError)
+ -> { f.gets }.should raise_error(IOError)
end
end
it "raises an IOError when read in a block opened with 'a' mode" do
File.open(@file, "a") do |f|
- lambda { f.gets }.should raise_error(IOError)
+ -> { f.gets }.should raise_error(IOError)
end
end
it "raises an IOError when read in a block opened with 'a' mode" do
File.open(@file, "a") do |f|
f.puts("writing").should == nil
- lambda { f.gets }.should raise_error(IOError)
+ -> { f.gets }.should raise_error(IOError)
end
end
it "raises an IOError when read in a block opened with 'a' mode" do
File.open(@file, File::WRONLY|File::APPEND ) do |f|
- lambda { f.gets }.should raise_error(IOError)
+ -> { f.gets }.should raise_error(IOError)
end
end
it "raises an IOError when read in a block opened with File::WRONLY|File::APPEND mode" do
File.open(@file, File::WRONLY|File::APPEND ) do |f|
f.puts("writing").should == nil
- lambda { f.gets }.should raise_error(IOError)
+ -> { f.gets }.should raise_error(IOError)
end
end
it "raises an IOError when read in a block opened with File::RDONLY|File::APPEND mode" do
- lambda {
+ -> {
File.open(@file, File::RDONLY|File::APPEND ) do |f|
f.puts("writing")
end
@@ -345,7 +332,7 @@ describe "File.open" do
end
it "can't read in a block when call open with File::EXCL mode" do
- lambda {
+ -> {
File.open(@file, File::EXCL) do |f|
f.puts("writing").should == nil
end
@@ -368,7 +355,7 @@ describe "File.open" do
end
it "raises an Errorno::EEXIST if the file exists when open with File::CREAT|File::EXCL" do
- lambda {
+ -> {
File.open(@file, File::CREAT|File::EXCL) do |f|
f.puts("writing")
end
@@ -378,7 +365,7 @@ describe "File.open" do
it "creates a new file when use File::WRONLY|File::APPEND mode" do
@fh = File.open(@file, File::WRONLY|File::APPEND)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file when use File::WRONLY|File::APPEND mode" do
@@ -395,7 +382,7 @@ describe "File.open" do
end
it "raises an IOError if the file exists when open with File::RDONLY|File::APPEND" do
- lambda {
+ -> {
File.open(@file, File::RDONLY|File::APPEND) do |f|
f.puts("writing").should == nil
end
@@ -421,7 +408,7 @@ describe "File.open" do
begin
@fh = File.open(@file, File::WRONLY|File::TRUNC)
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
ensure
fh1.close
end
@@ -429,7 +416,7 @@ describe "File.open" do
platform_is_not :openbsd, :windows do
it "can't write in a block when call open with File::TRUNC mode" do
- lambda {
+ -> {
File.open(@file, File::TRUNC) do |f|
f.puts("writing")
end
@@ -437,7 +424,7 @@ describe "File.open" do
end
it "raises an Errorno::EEXIST if the file exists when open with File::RDONLY|File::TRUNC" do
- lambda {
+ -> {
File.open(@file, File::RDONLY|File::TRUNC) do |f|
f.puts("writing").should == nil
end
@@ -447,7 +434,7 @@ describe "File.open" do
platform_is :openbsd, :windows do
it "can't write in a block when call open with File::TRUNC mode" do
- lambda {
+ -> {
File.open(@file, File::TRUNC) do |f|
f.puts("writing")
end
@@ -455,7 +442,7 @@ describe "File.open" do
end
it "raises an Errorno::EEXIST if the file exists when open with File::RDONLY|File::TRUNC" do
- lambda {
+ -> {
File.open(@file, File::RDONLY|File::TRUNC) do |f|
f.puts("writing").should == nil
end
@@ -464,29 +451,33 @@ describe "File.open" do
end
platform_is_not :windows do
- it "raises an Errno::EACCES when opening non-permitted file" do
- @fh = File.open(@file, "w")
- @fh.chmod(000)
- lambda { fh1 = File.open(@file); fh1.close }.should raise_error(Errno::EACCES)
+ as_user do
+ it "raises an Errno::EACCES when opening non-permitted file" do
+ @fh = File.open(@file, "w")
+ @fh.chmod(000)
+ -> { fh1 = File.open(@file); fh1.close }.should raise_error(Errno::EACCES)
+ end
end
end
- it "raises an Errno::EACCES when opening read-only file" do
- @fh = File.open(@file, "w")
- @fh.chmod(0444)
- lambda { File.open(@file, "w") }.should raise_error(Errno::EACCES)
+ as_user do
+ it "raises an Errno::EACCES when opening read-only file" do
+ @fh = File.open(@file, "w")
+ @fh.chmod(0444)
+ -> { File.open(@file, "w") }.should raise_error(Errno::EACCES)
+ end
end
it "opens a file for binary read" do
@fh = File.open(@file, "rb")
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file for binary write" do
@fh = File.open(@file, "wb")
@fh.should be_kind_of(File)
- File.exist?(@file).should == true
+ File.should.exist?(@file)
end
it "opens a file for read-write and truncate the file" do
@@ -494,7 +485,7 @@ describe "File.open" do
File.size(@file).should > 0
File.open(@file, "w+") do |f|
f.pos.should == 0
- f.eof?.should == true
+ f.should.eof?
end
File.size(@file).should == 0
end
@@ -504,7 +495,7 @@ describe "File.open" do
File.size(@file).should > 0
File.open(@file, "rb+") do |f|
f.pos.should == 0
- f.eof?.should == false
+ f.should_not.eof?
end
end
@@ -513,59 +504,57 @@ describe "File.open" do
File.size(@file).should > 0
File.open(@file, "wb+") do |f|
f.pos.should == 0
- f.eof?.should == true
+ f.should.eof?
end
File.size(@file).should == 0
end
- ruby_version_is "2.3" do
- platform_is :linux do
- if defined?(File::TMPFILE)
- it "creates an unnamed temporary file with File::TMPFILE" do
- dir = tmp("tmpfilespec")
- mkdir_p dir
- begin
+ platform_is :linux do
+ guard -> { defined?(File::TMPFILE) } do
+ it "creates an unnamed temporary file with File::TMPFILE" do
+ dir = tmp("tmpfilespec")
+ mkdir_p dir
+ begin
+ Dir["#{dir}/*"].should == []
+ File.open(dir, "r+", flags: File::TMPFILE) do |io|
+ io.write("ruby")
+ io.flush
+ io.rewind
+ io.read.should == "ruby"
Dir["#{dir}/*"].should == []
- File.open(dir, "r+", flags: File::TMPFILE) do |io|
- io.write("ruby")
- io.flush
- io.rewind
- io.read.should == "ruby"
- Dir["#{dir}/*"].should == []
- end
- rescue Errno::EOPNOTSUPP, Errno::EINVAL
- # EOPNOTSUPP: no support from the filesystem
- # EINVAL: presumably bug in glibc
- 1.should == 1
- ensure
- rm_r dir
end
+ rescue Errno::EOPNOTSUPP
+ skip "no support from the filesystem"
+ rescue Errno::EINVAL, Errno::EISDIR
+ skip "presumably bug in glibc"
+ ensure
+ rm_r dir
end
end
end
end
it "raises a TypeError if passed a filename that is not a String or Integer type" do
- lambda { File.open(true) }.should raise_error(TypeError)
- lambda { File.open(false) }.should raise_error(TypeError)
- lambda { File.open(nil) }.should raise_error(TypeError)
+ -> { File.open(true) }.should raise_error(TypeError)
+ -> { File.open(false) }.should raise_error(TypeError)
+ -> { File.open(nil) }.should raise_error(TypeError)
end
it "raises a SystemCallError if passed an invalid Integer type" do
- lambda { File.open(-1) }.should raise_error(SystemCallError)
+ -> { File.open(-1) }.should raise_error(SystemCallError)
end
it "raises an ArgumentError if passed the wrong number of arguments" do
- lambda { File.open(@file, File::CREAT, 0755, 'test') }.should raise_error(ArgumentError)
+ -> { File.open(@file, File::CREAT, 0755, 'test') }.should raise_error(ArgumentError)
end
it "raises an ArgumentError if passed an invalid string for mode" do
- lambda { File.open(@file, 'fake') }.should raise_error(ArgumentError)
+ -> { File.open(@file, 'fake') }.should raise_error(ArgumentError)
end
- it "defaults external_encoding to ASCII-8BIT for binary modes" do
- File.open(@file, 'rb') {|f| f.external_encoding.should == Encoding::ASCII_8BIT}
- File.open(@file, 'wb+') {|f| f.external_encoding.should == Encoding::ASCII_8BIT}
+ it "defaults external_encoding to BINARY for binary modes" do
+ File.open(@file, 'rb') {|f| f.external_encoding.should == Encoding::BINARY}
+ File.open(@file, 'wb+') {|f| f.external_encoding.should == Encoding::BINARY}
end
it "uses the second argument as an options Hash" do
@@ -577,32 +566,30 @@ describe "File.open" do
options = mock("file open options")
options.should_receive(:to_hash).and_return({ mode: "r" })
- @fh = File.open(@file, options)
+ @fh = File.open(@file, **options)
end
- ruby_version_is "2.3" do
- it "accepts extra flags as a keyword argument and combine with a string mode" do
- lambda {
- File.open(@file, "w", flags: File::EXCL) { }
- }.should raise_error(Errno::EEXIST)
+ it "accepts extra flags as a keyword argument and combine with a string mode" do
+ -> {
+ File.open(@file, "w", flags: File::EXCL) { }
+ }.should raise_error(Errno::EEXIST)
- lambda {
- File.open(@file, mode: "w", flags: File::EXCL) { }
- }.should raise_error(Errno::EEXIST)
- end
+ -> {
+ File.open(@file, mode: "w", flags: File::EXCL) { }
+ }.should raise_error(Errno::EEXIST)
+ end
- it "accepts extra flags as a keyword argument and combine with an integer mode" do
- lambda {
- File.open(@file, File::WRONLY | File::CREAT, flags: File::EXCL) { }
- }.should raise_error(Errno::EEXIST)
- end
+ it "accepts extra flags as a keyword argument and combine with an integer mode" do
+ -> {
+ File.open(@file, File::WRONLY | File::CREAT, flags: File::EXCL) { }
+ }.should raise_error(Errno::EEXIST)
end
platform_is_not :windows do
describe "on a FIFO" do
before :each do
@fifo = tmp("File_open_fifo")
- system "mkfifo #{@fifo}"
+ File.mkfifo(@fifo)
end
after :each do
@@ -636,13 +623,46 @@ describe "File.open" do
end
end
+ it "raises ArgumentError if mixing :newline and binary mode" do
+ -> {
+ File.open(@file, "rb", newline: :universal) {}
+ }.should raise_error(ArgumentError, "newline decorator with binary mode")
+ end
+
+ ruby_version_is "2.6" do
+ context "'x' flag" do
+ before :each do
+ @xfile = tmp("x-flag")
+ rm_r @xfile
+ end
+
+ after :each do
+ rm_r @xfile
+ end
+
+ it "does nothing if the file doesn't exist" do
+ File.open(@xfile, "wx") { |f| f.write("content") }
+ File.read(@xfile).should == "content"
+ end
+
+ it "throws a Errno::EEXIST error if the file exists" do
+ touch @xfile
+ -> { File.open(@xfile, "wx") }.should raise_error(Errno::EEXIST)
+ end
+
+ it "can't be used with 'r' and 'a' flags" do
+ -> { File.open(@xfile, "rx") }.should raise_error(ArgumentError, 'invalid access mode rx')
+ -> { File.open(@xfile, "ax") }.should raise_error(ArgumentError, 'invalid access mode ax')
+ end
+ end
+ end
end
describe "File.open when passed a file descriptor" do
before do
@content = "File#open when passed a file descriptor"
@name = tmp("file_open_with_fd.txt")
- @fd = new_fd @name, fmode("w:utf-8")
+ @fd = new_fd @name, "w:utf-8"
@file = nil
end
diff --git a/spec/ruby/core/file/owned_spec.rb b/spec/ruby/core/file/owned_spec.rb
index d19e9cb278..06d6796da9 100644
--- a/spec/ruby/core/file/owned_spec.rb
+++ b/spec/ruby/core/file/owned_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/owned', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/owned'
describe "File.owned?" do
it_behaves_like :file_owned, :owned?, File
@@ -24,9 +24,11 @@ describe "File.owned?" do
end
platform_is_not :windows do
- it "returns false when the file is not owned by the user" do
- system_file = '/etc/passwd'
- File.owned?(system_file).should == false
+ as_user do
+ it "returns false when the file is not owned by the user" do
+ system_file = '/etc/passwd'
+ File.owned?(system_file).should == false
+ end
end
end
diff --git a/spec/ruby/core/file/path_spec.rb b/spec/ruby/core/file/path_spec.rb
index 5004e128cd..dfa0c4ec02 100644
--- a/spec/ruby/core/file/path_spec.rb
+++ b/spec/ruby/core/file/path_spec.rb
@@ -1,6 +1,11 @@
-require File.expand_path('../../../spec_helper', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/path'
describe "File#path" do
+ it_behaves_like :file_path, :path
+end
+
+describe "File.path" do
before :each do
@name = tmp("file_path")
end
@@ -9,21 +14,27 @@ describe "File#path" do
rm_r @name
end
- it "returns the pathname used to create file as a string" do
- File.open(@name,'w') { |file| file.path.should == @name }
+ it "returns the string argument without any change" do
+ File.path("abc").should == "abc"
+ File.path("./abc").should == "./abc"
+ File.path("../abc").should == "../abc"
+ File.path("/./a/../bc").should == "/./a/../bc"
end
-end
-describe "File.path" do
- before :each do
- @name = tmp("file_path")
+ it "returns path for File argument" do
+ File.open(@name, "w") do |f|
+ File.path(f).should == @name
+ end
end
- after :each do
- rm_r @name
+ it "returns path for Pathname argument" do
+ require "pathname"
+ File.path(Pathname.new(@name)).should == @name
end
- it "returns the full path for the given file" do
- File.path(@name).should == @name
+ it "calls #to_path for non-string argument and returns result" do
+ path = mock("path")
+ path.should_receive(:to_path).and_return("abc")
+ File.path(path).should == "abc"
end
end
diff --git a/spec/ruby/core/file/pipe_spec.rb b/spec/ruby/core/file/pipe_spec.rb
index ca7392b8ee..01d72dbe85 100644
--- a/spec/ruby/core/file/pipe_spec.rb
+++ b/spec/ruby/core/file/pipe_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../../../shared/file/pipe', __FILE__)
+require_relative '../../spec_helper'
+require_relative '../../shared/file/pipe'
describe "File.pipe?" do
it_behaves_like :file_pipe, :pipe?, File
@@ -22,7 +22,7 @@ describe "File.pipe?" do
platform_is_not :windows do
it "returns true if the file is a pipe" do
filename = tmp("i_am_a_pipe")
- system "mkfifo #{filename}"
+ File.mkfifo(filename)
File.pipe?(filename).should == true
diff --git a/spec/ruby/core/file/printf_spec.rb b/spec/ruby/core/file/printf_spec.rb
new file mode 100644
index 0000000000..2530419fc7
--- /dev/null
+++ b/spec/ruby/core/file/printf_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../spec_helper'
+require_relative '../kernel/shared/sprintf'
+
+describe "File#printf" do
+ it_behaves_like :kernel_sprintf, -> format, *args {
+ begin
+ @filename = tmp("printf.txt")
+
+ File.open(@filename, "w", encoding: "utf-8") do |f|
+ f.printf(format, *args)
+ end
+
+ File.read(@filename, encoding: "utf-8")
+ ensure
+ rm_r @filename
+ end
+ }
+end
diff --git a/spec/ruby/core/file/read_spec.rb b/spec/ruby/core/file/read_spec.rb
index fdbbf58a1c..67a3325cbd 100644
--- a/spec/ruby/core/file/read_spec.rb
+++ b/spec/ruby/core/file/read_spec.rb
@@ -1,5 +1,5 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../shared/read', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'shared/read'
describe "File.read" do
it_behaves_like :file_read_directory, :read, File
diff --git a/spec/ruby/core/file/readable_real_spec.rb b/spec/ruby/core/file/readable_real_spec.rb
index 5fca968611..524466cd96 100644
--- a/